-- cgit v1.2.3 -- cgit v1.2.3 From a5ede4332043284255c2020d7b75c0c00f58db5d Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 10 May 2009 21:02:58 +0000 Subject: *new generic raytrace API *Adapted octree to a more generic raytrace API *ray shadow works (other untested stuff disabled atm) On the scene tested the user-cpu time got from 1:24 to 1:19/20 probably because of removed callbacks or sligtly diferente memory usage --- source/blender/editors/armature/meshlaplacian.c | 105 +- source/blender/render/extern/include/RE_raytrace.h | 108 +- source/blender/render/intern/include/rayobject.h | 122 ++ .../blender/render/intern/include/render_types.h | 7 +- source/blender/render/intern/source/rayobject.c | 276 ++++ .../blender/render/intern/source/rayobject_mesh.c | 128 ++ .../render/intern/source/rayobject_octree.c | 1092 +++++++++++++++ source/blender/render/intern/source/rayshade.c | 275 ++-- source/blender/render/intern/source/raytrace.c | 1442 -------------------- source/blender/render/intern/source/rendercore.c | 33 +- 10 files changed, 1868 insertions(+), 1720 deletions(-) create mode 100644 source/blender/render/intern/include/rayobject.h create mode 100644 source/blender/render/intern/source/rayobject.c create mode 100644 source/blender/render/intern/source/rayobject_mesh.c create mode 100644 source/blender/render/intern/source/rayobject_octree.c delete mode 100644 source/blender/render/intern/source/raytrace.c diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 8807b21e653..c3ab60ffda6 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -30,6 +30,7 @@ #include #include +#include #include "MEM_guardedalloc.h" @@ -105,7 +106,7 @@ struct LaplacianSystem { float *p; /* values from all p vectors */ float *mindist; /* minimum distance to a bone for all vertices */ - RayTree *raytree; /* ray tracing acceleration structure */ + RayObject *raytree; /* ray tracing acceleration structure */ MFace **vface; /* a face that the vertex belongs to */ } heat; @@ -394,77 +395,31 @@ float laplacian_system_get_solution(int v) #define DISTANCE_EPSILON 1e-4f /* Raytracing for vertex to bone visibility */ - -static LaplacianSystem *HeatSys = NULL; - -static void heat_ray_coords_func(RayFace *face, float **v1, float **v2, float **v3, float **v4) -{ - MFace *mface= (MFace*)face; - float (*verts)[3]= HeatSys->heat.verts; - - *v1= verts[mface->v1]; - *v2= verts[mface->v2]; - *v3= verts[mface->v3]; - *v4= (mface->v4)? verts[mface->v4]: NULL; -} - -static int heat_ray_check_func(Isect *is, int ob, RayFace *face) -{ - float *v1, *v2, *v3, *v4, nor[3]; - - /* don't intersect if the ray faces along the face normal */ - heat_ray_coords_func(face, &v1, &v2, &v3, &v4); - - if(v4) CalcNormFloat4(v1, v2, v3, v4, nor); - else CalcNormFloat(v1, v2, v3, nor); - - return (INPR(nor, is->vec) < 0); -} - static void heat_ray_tree_create(LaplacianSystem *sys) { Mesh *me = sys->heat.mesh; - RayTree *tree; MFace *mface; - float min[3], max[3]; int a; - /* create a raytrace tree from the mesh */ - INIT_MINMAX(min, max); - - for(a=0; atotvert; a++) - DO_MINMAX(sys->heat.verts[a], min, max); - - tree= RE_ray_tree_create(64, me->totface, min, max, - heat_ray_coords_func, heat_ray_check_func, NULL, NULL); - - sys->heat.vface= MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces"); - - HeatSys= sys; + sys->heat.raytree = RayObject_mesh_create(me, me); + sys->heat.vface = MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces"); for(a=0, mface=me->mface; atotface; a++, mface++) { - RE_ray_tree_add_face(tree, 0, mface); - sys->heat.vface[mface->v1]= mface; sys->heat.vface[mface->v2]= mface; sys->heat.vface[mface->v3]= mface; if(mface->v4) sys->heat.vface[mface->v4]= mface; } - - HeatSys= NULL; - - RE_ray_tree_done(tree); - - sys->heat.raytree= tree; } static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone) { Isect isec; MFace *mface; - float dir[3]; + float end[3]; int visible; + assert( 0 ); mface= sys->heat.vface[vertex]; if(!mface) return 1; @@ -473,22 +428,24 @@ static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone) memset(&isec, 0, sizeof(isec)); isec.mode= RE_RAY_SHADOW; isec.lay= -1; - isec.face_last= NULL; - isec.faceorig= mface; + isec.orig.face = mface; + isec.skip = RE_SKIP_CULLFACE; VECCOPY(isec.start, sys->heat.verts[vertex]); - PclosestVL3Dfl(isec.end, isec.start, - sys->heat.root[bone], sys->heat.tip[bone]); + PclosestVL3Dfl(end, isec.start, sys->heat.root[bone], sys->heat.tip[bone]); + + VECSUB(isec.vec, end, isec.start); + isec.labda = 1.0f; +#if 0 + TODO /* add an extra offset to the start position to avoid self intersection */ - VECSUB(dir, isec.end, isec.start); + VECCOPY(dir, isec.vec); Normalize(dir); VecMulf(dir, 1e-5); VecAddf(isec.start, isec.start, dir); - - HeatSys= sys; - visible= !RE_ray_tree_intersect(sys->heat.raytree, &isec); - HeatSys= NULL; +#endif + visible= !RayObject_raycast(sys->heat.raytree, &isec); return visible; } @@ -752,7 +709,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, /* free */ if(vertsflipped) MEM_freeN(vertsflipped); - RE_ray_tree_free(sys->heat.raytree); + RayObject_free(sys->heat.raytree); MEM_freeN(sys->heat.vface); MEM_freeN(sys->heat.mindist); @@ -1049,7 +1006,7 @@ typedef struct MeshDeformBind { int *varidx; /* raytrace */ - RayTree *raytree; + RayObject *raytree; } MeshDeformBind; /* ray intersection */ @@ -1173,7 +1130,7 @@ static void meshdeform_ray_tree_free(MeshDeformBind *mdb) static int meshdeform_intersect(MeshDeformBind *mdb, Isect *isec) { MFace *mface; - float face[4][3], co[3], uvw[3], len, nor[3]; + float face[4][3], co[3], uvw[3], len, nor[3], end[3]; int f, hit, is= 0, totface; isec->labda= 1e10; @@ -1181,6 +1138,8 @@ static int meshdeform_intersect(MeshDeformBind *mdb, Isect *isec) mface= mdb->cagedm->getFaceArray(mdb->cagedm); totface= mdb->cagedm->getNumFaces(mdb->cagedm); + VECADDFAC( end, isec->start, isec->vec, isec->labda ); + for(f=0; fcagecos[mface->v1]); VECCOPY(face[1], mdb->cagecos[mface->v2]); @@ -1188,26 +1147,26 @@ static int meshdeform_intersect(MeshDeformBind *mdb, Isect *isec) if(mface->v4) { VECCOPY(face[3], mdb->cagecos[mface->v4]); - hit= meshdeform_tri_intersect(isec->start, isec->end, face[0], face[1], face[2], co, uvw); + hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); if(hit) { CalcNormFloat(face[0], face[1], face[2], nor); } else { - hit= meshdeform_tri_intersect(isec->start, isec->end, face[0], face[2], face[3], co, uvw); + hit= meshdeform_tri_intersect(isec->start, end, face[0], face[2], face[3], co, uvw); CalcNormFloat(face[0], face[2], face[3], nor); } } else { - hit= meshdeform_tri_intersect(isec->start, isec->end, face[0], face[1], face[2], co, uvw); + hit= meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); CalcNormFloat(face[0], face[1], face[2], nor); } if(hit) { - len= VecLenf(isec->start, co)/VecLenf(isec->start, isec->end); + len= VecLenf(isec->start, co)/VecLenf(isec->start, end); if(len < isec->labda) { isec->labda= len; - isec->face= mface; + isec->hit.face = mface; isec->isect= (INPR(isec->vec, nor) <= 0.0f); is= 1; } @@ -1223,20 +1182,18 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float Isect isec; float (*cagecos)[3]; MFace *mface; - float vert[4][3], len; + float vert[4][3], len, end[3]; static float epsilon[3]= {0, 0, 0}; //1e-4, 1e-4, 1e-4}; /* setup isec */ memset(&isec, 0, sizeof(isec)); isec.mode= RE_RAY_MIRROR; /* we want the closest intersection */ isec.lay= -1; - isec.face_last= NULL; - isec.faceorig= NULL; isec.labda= 1e10f; VECADD(isec.start, co1, epsilon); - VECADD(isec.end, co2, epsilon); - VECSUB(isec.vec, isec.end, isec.start); + VECADD(end, co2, epsilon); + VECSUB(isec.vec, end, isec.start); #if 0 /*if(RE_ray_tree_intersect(mdb->raytree, &isec)) {*/ @@ -1244,7 +1201,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float if(meshdeform_intersect(mdb, &isec)) { len= isec.labda; - mface= isec.face; + mface=(MFace*)isec.hit.face; /* create MDefBoundIsect */ isect= BLI_memarena_alloc(mdb->memarena, sizeof(*isect)); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 8f429f7dd90..b274fe681b3 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): André Pinto. * * ***** END GPL LICENSE BLOCK ***** * RE_raytrace.h: ray tracing api, can be used independently from the renderer. @@ -31,84 +31,64 @@ #ifndef RE_RAYTRACE_H #define RE_RAYTRACE_H -/* ray types */ -#define RE_RAY_SHADOW 0 -#define RE_RAY_MIRROR 1 -#define RE_RAY_SHADOW_TRA 2 -/* spatial tree for raytracing acceleration */ -typedef void RayTree; -/* abstraction of face type */ -typedef void RayFace; +/* Internals about raycasting structures can be found on intern/raytree.h */ +typedef struct RayObject RayObject; +typedef struct Isect Isect; +struct DerivedMesh; +struct Mesh; -/* object numbers above this are transformed */ -#define RE_RAY_TRANSFORM_OFFS 0x8000000 +int RayObject_raycast(RayObject *r, Isect *i); +void RayObject_add (RayObject *r, RayObject *); +void RayObject_done(RayObject *r); +void RayObject_free(RayObject *r); -/* convert from pointer to index in array and back, with offset if the - * instance is transformed */ -#define RAY_OBJECT_SET(re, obi) \ - ((obi == NULL)? 0: \ - ((obi - (re)->objectinstance) + ((obi->flag & R_TRANSFORMED)? RE_RAY_TRANSFORM_OFFS: 0))) +/* RayObject constructors */ +RayObject* RayObject_octree_create(int ocres, int size); -#define RAY_OBJECT_GET(re, i) \ - ((re)->objectinstance + ((i >= RE_RAY_TRANSFORM_OFFS)? i-RE_RAY_TRANSFORM_OFFS: i)) +//RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); +RayObject* RayObject_mesh_create(struct Mesh*, void *ob); - -/* struct for intersection data */ -typedef struct Isect { - float start[3]; /* start+vec = end, in ray_tree_intersect */ +/* Ray Intersection */ +struct Isect +{ + float start[3]; float vec[3]; - float end[3]; - - float labda, u, v; /* distance to hitpoint, uv weights */ - - RayFace *face; /* face is where to intersect with */ - int ob; - RayFace *faceorig; /* start face */ - int oborig; - RayFace *face_last; /* for shadow optimize, last intersected face */ - int ob_last; - +/* float end[3]; - not used */ + + float labda, u, v; + + struct + { + void *ob; + void *face; +/* RayObject *obj; */ + } + hit, orig; + + RayObject *last_hit; /* last hit optimization */ + short isect; /* which half of quad */ short mode; /* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */ int lay; /* -1 default, set for layer lamps */ + + int skip; /* RE_SKIP_CULLFACE */ - /* only used externally */ float col[4]; /* RGBA for shadow_tra */ - - /* octree only */ - RayFace *facecontr; - int obcontr; - float ddalabda; - short faceisect; /* flag if facecontr was done or not */ - - /* custom pointer to be used in the RayCheckFunc */ + void *userdata; -} Isect; +}; -/* function callbacks for face type abstraction */ -typedef void (*RayCoordsFunc)(RayFace *face, - float **v1, float **v2, float **v3, float **v4); -typedef int (*RayCheckFunc)(Isect *is, int ob, RayFace *face); -typedef float *(*RayObjectTransformFunc)(void *userdata, int ob); +/* ray types */ +#define RE_RAY_SHADOW 0 +#define RE_RAY_MIRROR 1 +#define RE_RAY_SHADOW_TRA 2 -/* tree building and freeing */ -RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, - RayCoordsFunc coordfunc, RayCheckFunc checkfunc, - RayObjectTransformFunc transformfunc, void *userdata); -void RE_ray_tree_add_face(RayTree *tree, int ob, RayFace *face); -void RE_ray_tree_done(RayTree *tree); -void RE_ray_tree_free(RayTree *tree); +/* skip options */ +#define RE_SKIP_CULLFACE 1 -/* intersection with full tree and single face */ -int RE_ray_tree_intersect(RayTree *tree, Isect *is); -int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc check); -int RE_ray_face_intersection(Isect *is, RayObjectTransformFunc transformfunc, - RayCoordsFunc coordsfunc); +/* TODO use: FLT_MAX? */ +#define RE_RAYTRACE_MAXDIST 1e33 -/* retrieve the diameter of the tree structure, for setting intersection - end distance */ -float RE_ray_tree_max_size(RayTree *tree); #endif /*__RE_RAYTRACE_H__*/ - diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h new file mode 100644 index 00000000000..a1b35ac0465 --- /dev/null +++ b/source/blender/render/intern/include/rayobject.h @@ -0,0 +1,122 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYOBJECT_H +#define RE_RAYOBJECT_H + +#include "RE_raytrace.h" +#include + +/* RayObject + + A ray object is everything where we can cast rays like: + * a face/triangle + * an octree + * a bvh tree + * an octree of bvh's + * a bvh of bvh's + + + All types of RayObjects can be created by implementing the + callbacks of the RayObject. + + Due to high computing time evolved with casting on faces + there is a special type of RayObject (named RayFace) + which won't use callbacks like other generic nodes. + + In order to allow a mixture of RayFace+RayObjects, + all RayObjects must be 4byte aligned, allowing us to use the + 2 least significant bits (with the mask 0x02) to define the + type of RayObject. + + This leads to 4 possible types of RayObject, but at the moment + only 2 are used: + + addr&2 - type of object + 0 RayFace + 1 RayObject (generic with API callbacks) + 2 unused + 3 unused + + 0 was choosed to RayFace because thats the one where speed will be needed. + + You actually don't need to care about this if you are only using the API + described on RE_raytrace.h + */ + +typedef struct RayFace +{ + float *v1, *v2, *v3, *v4; + + void *ob; + void *face; + +} RayFace; + +struct RayObject +{ + struct RayObjectAPI *api; + +}; + +typedef int (*RayObject_raycast_callback)(RayObject *, Isect *); +typedef void (*RayObject_add_callback)(RayObject *, RayObject *); +typedef void (*RayObject_done_callback)(RayObject *); +typedef void (*RayObject_free_callback)(RayObject *); +typedef void (*RayObject_bb_callback)(RayObject *, float *min, float *max); + +typedef struct RayObjectAPI +{ + RayObject_raycast_callback raycast; + RayObject_add_callback add; + RayObject_done_callback done; + RayObject_free_callback free; + RayObject_bb_callback bb; + +} RayObjectAPI; + +//TODO use intptr_t +#define RayObject_align(o) ((RayObject*)(((int)o)&(~3))) +#define RayObject_unalign(o) ((RayObject*)(((int)o)|1)) +#define RayObject_isFace(o) ((((int)o)&3) == 0) + +/* + * Extend min/max coords so that the rayobject is inside them + */ +void RayObject_merge_bb(RayObject *ob, float *min, float *max); + +/* + * This function differs from RayObject_raycast + * RayObject_intersect does NOT perform last-hit optimization + * So this is probably a function to call inside raytrace structures + */ +int RayObject_intersect(RayObject *r, Isect *i); + +#define ISECT_EPSILON ((float)FLT_EPSILON) + +#endif diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index ab3758781ce..4846fe8d0e4 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -53,6 +53,7 @@ struct VlakTableNode; struct GHash; struct RenderBuckets; struct ObjectInstanceRen; +struct RayObject; #define TABLEINITSIZE 1024 #define LAMPINITSIZE 256 @@ -168,7 +169,8 @@ struct Render ListBase parts; /* octree tables and variables for raytrace */ - void *raytree; + struct RayObject *raytree; + struct RayObject *rayfaces; /* TODO Temporary */ /* occlusion tree */ void *occlusiontree; @@ -491,8 +493,7 @@ typedef struct LampRen { short YF_glowtype; /* ray optim */ - VlakRen *vlr_last[BLENDER_MAX_THREADS]; - ObjectInstanceRen *obi_last[BLENDER_MAX_THREADS]; + struct RayObject *last_hit[BLENDER_MAX_THREADS]; struct MTex *mtex[MAX_MTEX]; diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c new file mode 100644 index 00000000000..ee364d3586c --- /dev/null +++ b/source/blender/render/intern/source/rayobject.c @@ -0,0 +1,276 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include "assert.h" + +#include "BKE_utildefines.h" + +#include "RE_raytrace.h" +#include "rayobject.h" + +/* ray - triangle or quad intersection */ +static int intersect_rayface(RayFace *face, Isect *is) +{ + float co1[3],co2[3],co3[3],co4[3]; + float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2; + float m0, m1, m2, divdet, det1; + short ok=0; + + if(is->orig.ob == face->ob && is->orig.face == face->face) + return 0; + + /* disabled until i got real & fast cylinder checking, this code doesnt work proper for faster strands */ + // if(is->mode==RE_RAY_SHADOW && is->vlr->flag & R_STRAND) + // return intersection_strand(is); + + + VECCOPY(co1, face->v1); + VECCOPY(co2, face->v2); + + //TODO if(v4) { SWAP(float*, v3, v4); } + if(face->v4) + { + VECCOPY(co3, face->v4); + VECCOPY(co4, face->v3); + } + else + { + VECCOPY(co3, face->v3); + } + + t00= co3[0]-co1[0]; + t01= co3[1]-co1[1]; + t02= co3[2]-co1[2]; + t10= co3[0]-co2[0]; + t11= co3[1]-co2[1]; + t12= co3[2]-co2[2]; + + r0= is->vec[0]; + r1= is->vec[1]; + r2= is->vec[2]; + + x0= t12*r1-t11*r2; + x1= t10*r2-t12*r0; + x2= t11*r0-t10*r1; + + divdet= t00*x0+t01*x1+t02*x2; + + m0= is->start[0]-co3[0]; + m1= is->start[1]-co3[1]; + m2= is->start[2]-co3[2]; + det1= m0*x0+m1*x1+m2*x2; + + if(divdet!=0.0f) { + float u; + + divdet= 1.0f/divdet; + u= det1*divdet; + if(u-(1.0f+ISECT_EPSILON)) { + float v, cros0, cros1, cros2; + + cros0= m1*t02-m2*t01; + cros1= m2*t00-m0*t02; + cros2= m0*t01-m1*t00; + v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); + + if(v -(1.0f+ISECT_EPSILON)) { + float labda; + labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); + + if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { + is->labda= labda; + is->u= u; is->v= v; + ok= 1; + } + } + } + } + + if(ok==0 && face->v4) { + + t20= co3[0]-co4[0]; + t21= co3[1]-co4[1]; + t22= co3[2]-co4[2]; + + divdet= t20*x0+t21*x1+t22*x2; + if(divdet!=0.0f) { + float u; + divdet= 1.0f/divdet; + u = det1*divdet; + + if(u-(1.0f+ISECT_EPSILON)) { + float v, cros0, cros1, cros2; + cros0= m1*t22-m2*t21; + cros1= m2*t20-m0*t22; + cros2= m0*t21-m1*t20; + v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); + + if(v-(1.0f+ISECT_EPSILON)) { + float labda; + labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); + + if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { + ok= 2; + is->labda= labda; + is->u= u; is->v= v; + } + } + } + } + } + + if(ok) { + is->isect= ok; // wich half of the quad + +/* + TODO + if(is->mode!=RE_RAY_SHADOW) { + / * for mirror & tra-shadow: large faces can be filled in too often, this prevents + a face being detected too soon... * / + if(is->labda > is->ddalabda) { + return 0; + } + } +*/ + +#if 0 + TODO + /* when a shadow ray leaves a face, it can be little outside the edges of it, causing + intersection to be detected in its neighbour face */ + if(is->facecontr && is->faceisect); // optimizing, the tests below are not needed + else if(is->labda< .1) { + RayFace *face= is->orig.face; + float *origv1, *origv2, *origv3, *origv4; + short de= 0; + + coordsfunc(face, &origv1, &origv2, &origv3, &origv4); + + if(ob == is->orig.ob) { + if(v1==origv1 || v2==origv1 || v3==origv1 || v4==origv1) de++; + if(v1==origv2 || v2==origv2 || v3==origv2 || v4==origv2) de++; + if(v1==origv3 || v2==origv3 || v3==origv3 || v4==origv3) de++; + if(origv4) { + if(v1==origv4 || v2==origv4 || v3==origv4 || v4==origv4) de++; + } + } + if(de) { + /* so there's a shared edge or vertex, let's intersect ray with face + itself, if that's true we can safely return 1, otherwise we assume + the intersection is invalid, 0 */ + + if(is->facecontr==NULL) { + is->obcontr= is->orig.ob; + is->facecontr= face; + is->faceisect= intersection2(face, is->orig.ob, transformfunc, coordsfunc, is->userdata, + -r0, -r1, -r2, + is->start[0], is->start[1], is->start[2]); + } + + if(is->faceisect) return 1; + return 0; + } + } +#endif + + is->hit.ob = face->ob; + is->hit.face = face->face; + return 1; + } + + return 0; +} + +int RayObject_raycast(RayObject *r, Isect *i) +{ + if(i->mode==RE_RAY_SHADOW && i->last_hit && RayObject_intersect(i->last_hit, i)) + return 1; + + return RayObject_intersect(r, i); +} + +int RayObject_intersect(RayObject *r, Isect *i) +{ + assert(i->mode==RE_RAY_SHADOW); + if(RayObject_isFace(r)) + { + return intersect_rayface( (RayFace*) r, i); + } + else + { + //TODO should be done somewhere else +// float len = Normalize( i->vec ); + int hit; + i->vec[0] *= i->labda; + i->vec[1] *= i->labda; + i->vec[2] *= i->labda; + i->labda = 1.0f; //RE_RAYTRACE_MAXDIST; //len; + + r = RayObject_align( r ); + + hit = r->api->raycast( r, i ); +// i->labda /= len; + + return hit; + } +} + +void RayObject_add(RayObject *r, RayObject *o) +{ + r = RayObject_align( r ); + return r->api->add( r, o ); +} + +void RayObject_done(RayObject *r) +{ + r = RayObject_align( r ); + r->api->done( r ); +} + +void RayObject_free(RayObject *r) +{ + r = RayObject_align( r ); + r->api->free( r ); +} + +void RayObject_merge_bb(RayObject *r, float *min, float *max) +{ + if(RayObject_isFace(r)) + { + RayFace *face = (RayFace*)r; + DO_MINMAX( face->v1, min, max ); + DO_MINMAX( face->v2, min, max ); + DO_MINMAX( face->v3, min, max ); + if(face->v4) DO_MINMAX( face->v4, min, max ); + } + else + { + r = RayObject_align( r ); + r->api->bb( r, min, max ); + } +} + diff --git a/source/blender/render/intern/source/rayobject_mesh.c b/source/blender/render/intern/source/rayobject_mesh.c new file mode 100644 index 00000000000..7b8bca38172 --- /dev/null +++ b/source/blender/render/intern/source/rayobject_mesh.c @@ -0,0 +1,128 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include "rayobject.h" + +#include "MEM_guardedalloc.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "BKE_utildefines.h" + +typedef struct RayMesh +{ + RayObject rayobj; + + Mesh *mesh; + void *ob; + + RayFace *faces; + int num_faces; + +} RayMesh; + +static int RayObject_mesh_intersect(RayObject *o, Isect *isec); +static void RayObject_mesh_add(RayObject *o, RayObject *ob); +static void RayObject_mesh_done(RayObject *o); +static void RayObject_mesh_free(RayObject *o); +static void RayObject_mesh_bb(RayObject *o, float *min, float *max); + +static RayObjectAPI mesh_api = +{ + RayObject_mesh_intersect, + RayObject_mesh_add, + RayObject_mesh_done, + RayObject_mesh_free, + RayObject_mesh_bb +}; + + +static int RayObject_mesh_intersect(RayObject *o, Isect *isec) +{ + RayMesh *rm= (RayMesh*)o; + int i, hit = 0; + for(i = 0; inum_faces; i++) + if(RayObject_raycast( (RayObject*)rm->faces+i, isec )) + { + hit = 1; + if(isec->mode == RE_RAY_SHADOW) + break; + } + + return hit; +} + +static void RayObject_mesh_add(RayObject *o, RayObject *ob) +{ +} + +static void RayObject_mesh_done(RayObject *o) +{ +} + +static void RayObject_mesh_free(RayObject *o) +{ + RayMesh *rm= (RayMesh*)o; + MEM_freeN( rm->faces ); + MEM_freeN( rm ); +} + +static void RayObject_mesh_bb(RayObject *o, float *min, float *max) +{ + RayMesh *rm= (RayMesh*)o; + int i; + for(i = 0; imesh->totvert; i++) + DO_MINMAX( rm->mesh->mvert[i].co, min, max); +} + +RayObject* RayObject_mesh_create(Mesh *mesh, void *ob) +{ + RayMesh *rm= MEM_callocN(sizeof(RayMesh), "Octree"); + int i; + RayFace *face; + MFace *mface; + + rm->rayobj.api = &mesh_api; + rm->mesh = mesh; + rm->faces = MEM_callocN(sizeof(RayFace)*mesh->totface, "octree rayobject nodes"); + rm->num_faces = mesh->totface; + + face = rm->faces; + mface = mesh->mface; + for(i=0; itotface; i++, face++, mface++) + { + face->v1 = mesh->mvert[mface->v1].co; + face->v2 = mesh->mvert[mface->v2].co; + face->v3 = mesh->mvert[mface->v3].co; + face->v4 = mface->v4 ? mesh->mvert[mface->v4].co : NULL; + + face->ob = ob; + face->face = (void*)i; + } + + return RayObject_unalign((RayObject*) rm); +} diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c new file mode 100644 index 00000000000..a738898871b --- /dev/null +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -0,0 +1,1092 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 1990-1998 NeoGeo BV. + * All rights reserved. + * + * Contributors: 2004/2005 Blender Foundation, full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* IMPORTANT NOTE: this code must be independent of any other render code + to use it outside the renderer! */ + +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_material_types.h" + +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" + +#include "rayobject.h" + +/* ********** structs *************** */ +#define BRANCH_ARRAY 1024 +#define NODE_ARRAY 4096 + +typedef struct Branch +{ + struct Branch *b[8]; +} Branch; + +typedef struct OcVal +{ + short ocx, ocy, ocz; +} OcVal; + +typedef struct Node +{ + struct RayObject *v[8]; + struct OcVal ov[8]; + struct Node *next; +} Node; + +typedef struct Octree { + RayObject rayobj; + + struct Branch **adrbranch; + struct Node **adrnode; + float ocsize; /* ocsize: mult factor, max size octree */ + float ocfacx,ocfacy,ocfacz; + float min[3], max[3]; + int ocres; + int branchcount, nodecount; + + /* during building only */ + char *ocface; + + RayObject **ro_nodes; + int ro_nodes_size, ro_nodes_used; + +} Octree; + +static int RayObject_octree_intersect(RayObject *o, Isect *isec); +static void RayObject_octree_add(RayObject *o, RayObject *ob); +static void RayObject_octree_done(RayObject *o); +static void RayObject_octree_free(RayObject *o); +static void RayObject_octree_bb(RayObject *o, float *min, float *max); + +static RayObjectAPI octree_api = +{ + RayObject_octree_intersect, + RayObject_octree_add, + RayObject_octree_done, + RayObject_octree_free, + RayObject_octree_bb +}; + +/* **************** ocval method ******************* */ +/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */ + +#define OCVALRES 15 +#define BROW16(min, max) (((max)>=OCVALRES? 0xFFFF: (1<<(max+1))-1) - ((min>0)? ((1<<(min))-1):0) ) + +static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov) +{ + float min[3], max[3]; + int ocmin, ocmax; + + VECCOPY(min, v1); + VECCOPY(max, v1); + DO_MINMAX(v2, min, max); + DO_MINMAX(v3, min, max); + if(v4) { + DO_MINMAX(v4, min, max); + } + + ocmin= OCVALRES*(min[0]-x); + ocmax= OCVALRES*(max[0]-x); + ov->ocx= BROW16(ocmin, ocmax); + + ocmin= OCVALRES*(min[1]-y); + ocmax= OCVALRES*(max[1]-y); + ov->ocy= BROW16(ocmin, ocmax); + + ocmin= OCVALRES*(min[2]-z); + ocmax= OCVALRES*(max[2]-z); + ov->ocz= BROW16(ocmin, ocmax); + +} + +static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2) +{ + int ocmin, ocmax; + + if(vec1[0]ocx= BROW16(ocmin, ocmax); + + if(vec1[1]ocy= BROW16(ocmin, ocmax); + + if(vec1[2]ocz= BROW16(ocmin, ocmax); +} + +/* ************* octree ************** */ + +static Branch *addbranch(Octree *oc, Branch *br, short ocb) +{ + int index; + + if(br->b[ocb]) return br->b[ocb]; + + oc->branchcount++; + index= oc->branchcount>>12; + + if(oc->adrbranch[index]==NULL) + oc->adrbranch[index]= MEM_callocN(4096*sizeof(Branch), "new oc branch"); + + if(oc->branchcount>= BRANCH_ARRAY*4096) { + printf("error; octree branches full\n"); + oc->branchcount=0; + } + + return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095); +} + +static Node *addnode(Octree *oc) +{ + int index; + + oc->nodecount++; + index= oc->nodecount>>12; + + if(oc->adrnode[index]==NULL) + oc->adrnode[index]= MEM_callocN(4096*sizeof(Node),"addnode"); + + if(oc->nodecount> NODE_ARRAY*NODE_ARRAY) { + printf("error; octree nodes full\n"); + oc->nodecount=0; + } + + return oc->adrnode[index]+(oc->nodecount & 4095); +} + +static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]) +{ + static float nor[3], d; + float fx, fy, fz; + + // init static vars + if(face) { + CalcNormFloat(rtf[0], rtf[1], rtf[2], nor); + d= -nor[0]*rtf[0][0] - nor[1]*rtf[0][1] - nor[2]*rtf[0][2]; + return 0; + } + + fx= x; + fy= y; + fz= z; + + if((fx)*nor[0] + (fy)*nor[1] + (fz)*nor[2] + d > 0.0f) { + if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; + if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; + if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; + + if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; + if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; + if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; + if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; + } + else { + if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; + if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; + if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; + + if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; + if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; + if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; + if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; + } + + return 0; +} + +static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short z, float rtf[][3]) +{ + Branch *br; + Node *no; + short a, oc0, oc1, oc2, oc3, oc4, oc5; + + x<<=2; + y<<=1; + + br= oc->adrbranch[0]; + + if(oc->ocres==512) { + oc0= ((x & 1024)+(y & 512)+(z & 256))>>8; + br= addbranch(oc, br, oc0); + } + if(oc->ocres>=256) { + oc0= ((x & 512)+(y & 256)+(z & 128))>>7; + br= addbranch(oc, br, oc0); + } + if(oc->ocres>=128) { + oc0= ((x & 256)+(y & 128)+(z & 64))>>6; + br= addbranch(oc, br, oc0); + } + + oc0= ((x & 128)+(y & 64)+(z & 32))>>5; + oc1= ((x & 64)+(y & 32)+(z & 16))>>4; + oc2= ((x & 32)+(y & 16)+(z & 8))>>3; + oc3= ((x & 16)+(y & 8)+(z & 4))>>2; + oc4= ((x & 8)+(y & 4)+(z & 2))>>1; + oc5= ((x & 4)+(y & 2)+(z & 1)); + + br= addbranch(oc, br,oc0); + br= addbranch(oc, br,oc1); + br= addbranch(oc, br,oc2); + br= addbranch(oc, br,oc3); + br= addbranch(oc, br,oc4); + no= (Node *)br->b[oc5]; + if(no==NULL) br->b[oc5]= (Branch *)(no= addnode(oc)); + + while(no->next) no= no->next; + + a= 0; + if(no->v[7]) { /* node full */ + no->next= addnode(oc); + no= no->next; + } + else { + while(no->v[a]!=NULL) a++; + } + + no->v[a]= (RayObject*)face; + + if(quad) + calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]); + else + calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x>>2, y>>1, z, &no->ov[a]); +} + +static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3]) +{ + int ocx1,ocx2,ocy1,ocy2; + int x,y,dx=0,dy=0; + float ox1,ox2,oy1,oy2; + float labda,labdao,labdax,labday,ldx,ldy; + + ocx1= rts[b1][c1]; + ocy1= rts[b1][c2]; + ocx2= rts[b2][c1]; + ocy2= rts[b2][c2]; + + if(ocx1==ocx2 && ocy1==ocy2) { + ocface[oc->ocres*ocx1+ocy1]= 1; + return; + } + + ox1= rtf[b1][c1]; + oy1= rtf[b1][c2]; + ox2= rtf[b2][c1]; + oy2= rtf[b2][c2]; + + if(ox1!=ox2) { + if(ox2-ox1>0.0f) { + labdax= (ox1-ocx1-1.0f)/(ox1-ox2); + ldx= -1.0f/(ox1-ox2); + dx= 1; + } else { + labdax= (ox1-ocx1)/(ox1-ox2); + ldx= 1.0f/(ox1-ox2); + dx= -1; + } + } else { + labdax=1.0f; + ldx=0; + } + + if(oy1!=oy2) { + if(oy2-oy1>0.0f) { + labday= (oy1-ocy1-1.0f)/(oy1-oy2); + ldy= -1.0f/(oy1-oy2); + dy= 1; + } else { + labday= (oy1-ocy1)/(oy1-oy2); + ldy= 1.0f/(oy1-oy2); + dy= -1; + } + } else { + labday=1.0f; + ldy=0; + } + + x=ocx1; y=ocy1; + labda= MIN2(labdax, labday); + + while(TRUE) { + + if(x<0 || y<0 || x>=oc->ocres || y>=oc->ocres); + else ocface[oc->ocres*x+y]= 1; + + labdao=labda; + if(labdax==labday) { + labdax+=ldx; + x+=dx; + labday+=ldy; + y+=dy; + } else { + if(labdax=1.0f) break; + } + ocface[oc->ocres*ocx2+ocy2]=1; +} + +static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin, short *ocmax) +{ + int a, x, y, y1, y2; + + for(x=ocmin[c1];x<=ocmax[c1];x++) { + a= oc->ocres*x; + for(y=ocmin[c2];y<=ocmax[c2];y++) { + if(ocface[a+y]) { + y++; + while(ocface[a+y] && y!=ocmax[c2]) y++; + for(y1=ocmax[c2];y1>y;y1--) { + if(ocface[a+y1]) { + for(y2=y;y2<=y1;y2++) ocface[a+y2]=1; + y1=0; + } + } + y=ocmax[c2]; + } + } + } +} + +static void RayObject_octree_free(RayObject *tree) +{ + Octree *oc= (Octree*)tree; + +#if 0 + printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount); + printf("raycount %d \n", raycount); + printf("ray coherent %d \n", coherent_ray); + printf("accepted %d rejected %d\n", accepted, rejected); +#endif + if(oc->ocface) + MEM_freeN(oc->ocface); + + if(oc->adrbranch) { + int a= 0; + while(oc->adrbranch[a]) { + MEM_freeN(oc->adrbranch[a]); + oc->adrbranch[a]= NULL; + a++; + } + MEM_freeN(oc->adrbranch); + oc->adrbranch= NULL; + } + oc->branchcount= 0; + + if(oc->adrnode) { + int a= 0; + while(oc->adrnode[a]) { + MEM_freeN(oc->adrnode[a]); + oc->adrnode[a]= NULL; + a++; + } + MEM_freeN(oc->adrnode); + oc->adrnode= NULL; + } + oc->nodecount= 0; + + MEM_freeN(oc); +} + + +RayObject *RayObject_octree_create(int ocres, int size) +{ + Octree *oc= MEM_callocN(sizeof(Octree), "Octree"); + + oc->rayobj.api = &octree_api; + + oc->ocres = ocres; + + oc->ro_nodes = MEM_callocN(sizeof(RayObject*)*size, "octree rayobject nodes"); + oc->ro_nodes_size = size; + oc->ro_nodes_used = 0; + + + return RayObject_unalign((RayObject*) oc); +} + + +static void RayObject_octree_add(RayObject *tree, RayObject *node) +{ + Octree *oc = (Octree*)tree; + + assert( oc->ro_nodes_used < oc->ro_nodes_size ); + oc->ro_nodes[ oc->ro_nodes_used++ ] = node; +} + +static void octree_fill_rayface(Octree *oc, RayFace *face) +{ + float ocfac[3], rtf[4][3]; + float co1[3], co2[3], co3[3], co4[3]; + short rts[4][3]; + short ocmin[3], ocmax[3]; + char *ocface= oc->ocface; // front, top, size view of face, to fill in + int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2; + + ocfac[0]= oc->ocfacx; + ocfac[1]= oc->ocfacy; + ocfac[2]= oc->ocfacz; + + ocres2= oc->ocres*oc->ocres; + + VECCOPY(co1, face->v1); + VECCOPY(co2, face->v2); + VECCOPY(co3, face->v3); + if(face->v4) + VECCOPY(co4, face->v4); + + for(c=0;c<3;c++) { + rtf[0][c]= (co1[c]-oc->min[c])*ocfac[c] ; + rts[0][c]= (short)rtf[0][c]; + rtf[1][c]= (co2[c]-oc->min[c])*ocfac[c] ; + rts[1][c]= (short)rtf[1][c]; + rtf[2][c]= (co3[c]-oc->min[c])*ocfac[c] ; + rts[2][c]= (short)rtf[2][c]; + if(face->v4) { + rtf[3][c]= (co4[c]-oc->min[c])*ocfac[c] ; + rts[3][c]= (short)rtf[3][c]; + } + } + + for(c=0;c<3;c++) { + oc1= rts[0][c]; + oc2= rts[1][c]; + oc3= rts[2][c]; + if(face->v4==NULL) { + ocmin[c]= MIN3(oc1,oc2,oc3); + ocmax[c]= MAX3(oc1,oc2,oc3); + } + else { + oc4= rts[3][c]; + ocmin[c]= MIN4(oc1,oc2,oc3,oc4); + ocmax[c]= MAX4(oc1,oc2,oc3,oc4); + } + if(ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1; + if(ocmin[c]<0) ocmin[c]=0; + } + + if(ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) { + ocwrite(oc, face, (face->v4 != NULL), ocmin[0], ocmin[1], ocmin[2], rtf); + } + else { + + d2dda(oc, 0,1,0,1,ocface+ocres2,rts,rtf); + d2dda(oc, 0,1,0,2,ocface,rts,rtf); + d2dda(oc, 0,1,1,2,ocface+2*ocres2,rts,rtf); + d2dda(oc, 1,2,0,1,ocface+ocres2,rts,rtf); + d2dda(oc, 1,2,0,2,ocface,rts,rtf); + d2dda(oc, 1,2,1,2,ocface+2*ocres2,rts,rtf); + if(face->v4==NULL) { + d2dda(oc, 2,0,0,1,ocface+ocres2,rts,rtf); + d2dda(oc, 2,0,0,2,ocface,rts,rtf); + d2dda(oc, 2,0,1,2,ocface+2*ocres2,rts,rtf); + } + else { + d2dda(oc, 2,3,0,1,ocface+ocres2,rts,rtf); + d2dda(oc, 2,3,0,2,ocface,rts,rtf); + d2dda(oc, 2,3,1,2,ocface+2*ocres2,rts,rtf); + d2dda(oc, 3,0,0,1,ocface+ocres2,rts,rtf); + d2dda(oc, 3,0,0,2,ocface,rts,rtf); + d2dda(oc, 3,0,1,2,ocface+2*ocres2,rts,rtf); + } + /* nothing todo with triangle..., just fills :) */ + filltriangle(oc, 0,1,ocface+ocres2,ocmin,ocmax); + filltriangle(oc, 0,2,ocface,ocmin,ocmax); + filltriangle(oc, 1,2,ocface+2*ocres2,ocmin,ocmax); + + /* init static vars here */ + face_in_node(face, 0,0,0, rtf); + + for(x=ocmin[0];x<=ocmax[0];x++) { + a= oc->ocres*x; + for(y=ocmin[1];y<=ocmax[1];y++) { + if(ocface[a+y+ocres2]) { + b= oc->ocres*y+2*ocres2; + for(z=ocmin[2];z<=ocmax[2];z++) { + if(ocface[b+z] && ocface[a+z]) { + if(face_in_node(NULL, x, y, z, rtf)) + ocwrite(oc, face, (face->v4 != NULL), x,y,z, rtf); + } + } + } + } + } + + /* same loops to clear octree, doubt it can be done smarter */ + for(x=ocmin[0];x<=ocmax[0];x++) { + a= oc->ocres*x; + for(y=ocmin[1];y<=ocmax[1];y++) { + /* x-y */ + ocface[a+y+ocres2]= 0; + + b= oc->ocres*y + 2*ocres2; + for(z=ocmin[2];z<=ocmax[2];z++) { + /* y-z */ + ocface[b+z]= 0; + /* x-z */ + ocface[a+z]= 0; + } + } + } + } +} + +static void RayObject_octree_done(RayObject *tree) +{ + Octree *oc = (Octree*)tree; + int c; + float t00, t01, t02; + int ocres2 = oc->ocres*oc->ocres; + + INIT_MINMAX(oc->min, oc->max); + + /* Calculate Bounding Box */ + for(c=0; cro_nodes_used; c++) + RayObject_merge_bb(oc->ro_nodes[c], oc->min, oc->max); + + /* Alloc memory */ + oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); + oc->adrnode= MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes"); + + oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree"); + + /* the lookup table, per face, for which nodes to fill in */ + oc->ocface= MEM_callocN( 3*ocres2 + 8, "ocface"); + memset(oc->ocface, 0, 3*ocres2); + + for(c=0;c<3;c++) { /* octree enlarge, still needed? */ + oc->min[c]-= 0.01f; + oc->max[c]+= 0.01f; + } + + t00= oc->max[0]-oc->min[0]; + t01= oc->max[1]-oc->min[1]; + t02= oc->max[2]-oc->min[2]; + + /* this minus 0.1 is old safety... seems to be needed? */ + oc->ocfacx= (oc->ocres-0.1)/t00; + oc->ocfacy= (oc->ocres-0.1)/t01; + oc->ocfacz= (oc->ocres-0.1)/t02; + + oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */ + + for(c=0; cro_nodes_used; c++) + { + assert( RayObject_isFace(oc->ro_nodes[c]) ); + octree_fill_rayface(oc, (RayFace*)oc->ro_nodes[c]); + } + + MEM_freeN(oc->ocface); + MEM_freeN(oc->ro_nodes); + + printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx ); + printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy ); + printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz ); +} + +static void RayObject_octree_bb(RayObject *tree, float *min, float *max) +{ + Octree *oc = (Octree*)tree; + DO_MINMAX(oc->min, min, max); + DO_MINMAX(oc->max, min, max); +} + +/* check all faces in this node */ +static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) +{ + short nr=0; + + /* return on any first hit */ + if(is->mode==RE_RAY_SHADOW) { + + for(; no; no = no->next) + for(nr=0; nr<8; nr++) + { + RayObject *face = no->v[nr]; + OcVal *ov = no->ov+nr; + + if(!face) break; //TODO? return 0; + + if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) + { + if( RayObject_intersect(face,is) ) + return 1; + } + } + } + else + { /* else mirror or glass or shadowtra, return closest face */ + Isect isect; + int found= 0; + + assert(0); + + is->labda= 1.0f; /* needed? */ + isect= *is; /* copy for sorting */ + + for(; no; no = no->next) + for(nr=0; nr<8; nr++) + { + RayObject *face = no->v[nr]; + OcVal *ov = no->ov+nr; + + if(!face) return 0; + + if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) + { + + if( RayObject_raycast(face,is) ) + if(isect.labdalabda) { + *is= isect; + found= 1; + } + } + } + + return found; + } + + return 0; +} + +/* find the Node for the octree coord x y z */ +static Node *ocread(Octree *oc, int x, int y, int z) +{ + Branch *br; + int oc1; + + x<<=2; + y<<=1; + + br= oc->adrbranch[0]; + + if(oc->ocres==512) { + oc1= ((x & 1024)+(y & 512)+(z & 256))>>8; + br= br->b[oc1]; + if(br==NULL) { + return NULL; + } + } + if(oc->ocres>=256) { + oc1= ((x & 512)+(y & 256)+(z & 128))>>7; + br= br->b[oc1]; + if(br==NULL) { + return NULL; + } + } + if(oc->ocres>=128) { + oc1= ((x & 256)+(y & 128)+(z & 64))>>6; + br= br->b[oc1]; + if(br==NULL) { + return NULL; + } + } + + oc1= ((x & 128)+(y & 64)+(z & 32))>>5; + br= br->b[oc1]; + if(br) { + oc1= ((x & 64)+(y & 32)+(z & 16))>>4; + br= br->b[oc1]; + if(br) { + oc1= ((x & 32)+(y & 16)+(z & 8))>>3; + br= br->b[oc1]; + if(br) { + oc1= ((x & 16)+(y & 8)+(z & 4))>>2; + br= br->b[oc1]; + if(br) { + oc1= ((x & 8)+(y & 4)+(z & 2))>>1; + br= br->b[oc1]; + if(br) { + oc1= ((x & 4)+(y & 2)+(z & 1)); + return (Node *)br->b[oc1]; + } + } + } + } + } + + return NULL; +} + +static int cliptest(float p, float q, float *u1, float *u2) +{ + float r; + + if(p<0.0f) { + if(q*u2) return 0; + else if(r>*u1) *u1=r; + } + } + else { + if(p>0.0f) { + if(q<0.0f) return 0; + else if(qorig.face */ +static int RayObject_octree_intersect(RayObject *tree, Isect *is) +{ + Octree *oc= (Octree*)tree; + Node *no; + OcVal ocval; + float vec1[3], vec2[3], end[3]; + float u1,u2,ox1,ox2,oy1,oy2,oz1,oz2; + float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda; + int dx,dy,dz; + int xo,yo,zo,c1=0; + int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2; + + /* clip with octree */ + if(oc->branchcount==0) return 0; + + /* do this before intersect calls */ +#if 0 + is->facecontr= NULL; /* to check shared edge */ + is->obcontr= 0; + is->faceisect= is->isect= 0; /* shared edge, quad half flag */ + is->userdata= oc->userdata; +#endif + +#if 0 + /* only for shadow! */ + if(is->mode==RE_RAY_SHADOW) { + + /* TODO check with last intersected shadow face */ + if(is->last.face!=NULL && !(is->last.face==is->orig.face && is->last.ob==is->orig.ob)) { + if(checkfunc(is, is->last.ob, is->last.face)) { + is->ob= is->last.ob; + is->face= is->last.face; + VECSUB(is->vec, is->end, is->start); + if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) return 1; + } + } + } +#endif + + VECADDFAC( end, is->start, is->vec, is->labda ); + ldx= end[0] - is->start[0]; + u1= 0.0f; + u2= 1.0f; + + /* clip with octree cube */ + if(cliptest(-ldx, is->start[0]-oc->min[0], &u1,&u2)) { + if(cliptest(ldx, oc->max[0]-is->start[0], &u1,&u2)) { + ldy= end[1] - is->start[1]; + if(cliptest(-ldy, is->start[1]-oc->min[1], &u1,&u2)) { + if(cliptest(ldy, oc->max[1]-is->start[1], &u1,&u2)) { + ldz = end[2] - is->start[2]; + if(cliptest(-ldz, is->start[2]-oc->min[2], &u1,&u2)) { + if(cliptest(ldz, oc->max[2]-is->start[2], &u1,&u2)) { + c1=1; + if(u2<1.0f) { + end[0]= is->start[0]+u2*ldx; + end[1]= is->start[1]+u2*ldy; + end[2]= is->start[2]+u2*ldz; + } + if(u1>0.0f) { + assert( 0 ); + is->start[0]+=u1*ldx; + is->start[1]+=u1*ldy; + is->start[2]+=u1*ldz; + } + } + } + } + } + } + } + + if(c1==0) return 0; + + /* reset static variables in ocread */ + //ocread(oc, oc->ocres, 0, 0); + + /* setup 3dda to traverse octree */ + ox1= (is->start[0]-oc->min[0])*oc->ocfacx; + oy1= (is->start[1]-oc->min[1])*oc->ocfacy; + oz1= (is->start[2]-oc->min[2])*oc->ocfacz; + ox2= (end[0]-oc->min[0])*oc->ocfacx; + oy2= (end[1]-oc->min[1])*oc->ocfacy; + oz2= (end[2]-oc->min[2])*oc->ocfacz; + + ocx1= (int)ox1; + ocy1= (int)oy1; + ocz1= (int)oz1; + ocx2= (int)ox2; + ocy2= (int)oy2; + ocz2= (int)oz2; + +// for(ocx1=0; ocx1ocres; ocx1++) +// for(ocy1=0; ocy1ocres; ocy1++) +// for(ocz1=0; ocz1ocres; ocz1++) +// { +// no= ocread(oc, ocx1, ocy1, ocz1); +// if( testnode(oc, is, no, ocval) ) return 1; +// } + +// return 0; + + if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) { + no= ocread(oc, ocx1, ocy1, ocz1); + if(no) { + /* exact intersection with node */ + vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1; + vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2; + calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); +// is->ddalabda= 1.0f; + if( testnode(oc, is, no, ocval) ) return 1; + } + } + else { + //static int coh_ocx1,coh_ocx2,coh_ocy1, coh_ocy2,coh_ocz1,coh_ocz2; + float dox, doy, doz; + int eqval; + + /* calc labda en ld */ + dox= ox1-ox2; + doy= oy1-oy2; + doz= oz1-oz2; + + if(dox<-FLT_EPSILON) { + ldx= -1.0f/dox; + labdax= (ocx1-ox1+1.0f)*ldx; + dx= 1; + } else if(dox>FLT_EPSILON) { + ldx= 1.0f/dox; + labdax= (ox1-ocx1)*ldx; + dx= -1; + } else { + labdax=1.0f; + ldx=0; + dx= 0; + } + + if(doy<-FLT_EPSILON) { + ldy= -1.0f/doy; + labday= (ocy1-oy1+1.0f)*ldy; + dy= 1; + } else if(doy>FLT_EPSILON) { + ldy= 1.0f/doy; + labday= (oy1-ocy1)*ldy; + dy= -1; + } else { + labday=1.0f; + ldy=0; + dy= 0; + } + + if(doz<-FLT_EPSILON) { + ldz= -1.0f/doz; + labdaz= (ocz1-oz1+1.0f)*ldz; + dz= 1; + } else if(doz>FLT_EPSILON) { + ldz= 1.0f/doz; + labdaz= (oz1-ocz1)*ldz; + dz= -1; + } else { + labdaz=1.0f; + ldz=0; + dz= 0; + } + + xo=ocx1; yo=ocy1; zo=ocz1; + labdao= ddalabda= MIN3(labdax,labday,labdaz); + + vec2[0]= ox1; + vec2[1]= oy1; + vec2[2]= oz1; + + /* this loop has been constructed to make sure the first and last node of ray + are always included, even when ddalabda==1.0f or larger */ + + while(TRUE) { + + no= ocread(oc, xo, yo, zo); + if(no) { + + /* calculate ray intersection with octree node */ + VECCOPY(vec1, vec2); + // dox,y,z is negative + vec2[0]= ox1-ddalabda*dox; + vec2[1]= oy1-ddalabda*doy; + vec2[2]= oz1-ddalabda*doz; + calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); + +// is->ddalabda= ddalabda; + if( testnode(oc, is, no, ocval) ) return 1; + } + + labdao= ddalabda; + + /* traversing ocree nodes need careful detection of smallest values, with proper + exceptions for equal labdas */ + eqval= (labdax==labday); + if(labday==labdaz) eqval += 2; + if(labdax==labdaz) eqval += 4; + + if(eqval) { // only 4 cases exist! + if(eqval==7) { // x=y=z + xo+=dx; labdax+=ldx; + yo+=dy; labday+=ldy; + zo+=dz; labdaz+=ldz; + } + else if(eqval==1) { // x=y + if(labday < labdaz) { + xo+=dx; labdax+=ldx; + yo+=dy; labday+=ldy; + } + else { + zo+=dz; labdaz+=ldz; + } + } + else if(eqval==2) { // y=z + if(labdax < labday) { + xo+=dx; labdax+=ldx; + } + else { + yo+=dy; labday+=ldy; + zo+=dz; labdaz+=ldz; + } + } + else { // x=z + if(labday < labdax) { + yo+=dy; labday+=ldy; + } + else { + xo+=dx; labdax+=ldx; + zo+=dz; labdaz+=ldz; + } + } + } + else { // all three different, just three cases exist + eqval= (labdax=1.0f) break; + } + } + + /* reached end, no intersections found */ + is->hit.ob = 0; + is->hit.face = NULL; + return 0; +} + + + diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index e89cf20e4b1..83165bb6b52 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -56,6 +57,7 @@ #include "texture.h" #include "RE_raytrace.h" +#include "rayobject.h" #define RAY_TRA 1 #define RAY_TRAFLIP 2 @@ -68,6 +70,7 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#if 0 static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, float **v4) { VlakRen *vlr= (VlakRen*)face; @@ -101,27 +104,28 @@ static float *vlr_get_transform(void *userdata, int i) return (obi->flag & R_TRANSFORMED)? (float*)obi->mat: NULL; } +#endif void freeraytree(Render *re) { if(re->raytree) { - RE_ray_tree_free(re->raytree); + RayObject_free(re->raytree); re->raytree= NULL; + MEM_freeN( re->rayfaces ); } } - void makeraytree(Render *re) { ObjectInstanceRen *obi; ObjectRen *obr; VlakRen *vlr= NULL; - float min[3], max[3], co1[3], co2[3], co3[3], co4[3]; double lasttime= PIL_check_seconds_timer(); int v, totv = 0, totface = 0; + RayFace *faces, *cur_face; - INIT_MINMAX(min, max); - - /* first min max raytree space */ + //TODO (for now octree only supports RayFaces so we need to create them) + // + //count faces for(obi=re->instancetable.first; obi; obi=obi->next) { obr= obi->obr; @@ -134,51 +138,31 @@ void makeraytree(Render *re) /* baking selected to active needs non-traceable too */ if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) { if((vlr->mat->mode & MA_WIRE)==0) { - VECCOPY(co1, vlr->v1->co); - VECCOPY(co2, vlr->v2->co); - VECCOPY(co3, vlr->v3->co); - - if(obi->flag & R_TRANSFORMED) { - Mat4MulVecfl(obi->mat, co1); - Mat4MulVecfl(obi->mat, co2); - Mat4MulVecfl(obi->mat, co3); - } - - DO_MINMAX(co1, min, max); - DO_MINMAX(co2, min, max); - DO_MINMAX(co3, min, max); - - if(vlr->v4) { - VECCOPY(co4, vlr->v4->co); - if(obi->flag & R_TRANSFORMED) - Mat4MulVecfl(obi->mat, co4); - DO_MINMAX(co4, min, max); - } - totface++; } } } } - - re->raytree= RE_ray_tree_create(re->r.ocres, totface, min, max, - vlr_face_coords, vlr_check_intersect, vlr_get_transform, re); - - if(min[0] > max[0]) { /* empty raytree */ - RE_ray_tree_done(re->raytree); - return; - } - + + re->raytree = RayObject_octree_create( re->r.ocres, totface ); + + //Fill rayfaces + re->rayfaces = (RayObject*)MEM_callocN(totface*sizeof(RayFace), "render faces"); + cur_face = faces = (RayFace*)re->rayfaces; + for(obi=re->instancetable.first; obi; obi=obi->next) { obr= obi->obr; if(re->excludeob && obr->ob == re->excludeob) continue; - for(v=0; vtotvlak; v++, totv++) { - if((v & 255)==0) { + for(v=0;vtotvlak;v++) { + if((v & 255)==0) + { double time= PIL_check_seconds_timer(); + vlr= obr->vlaknodes[v>>8].vlak; + vlr= obr->vlaknodes[v>>8].vlak; if(re->test_break(re->tbh)) break; @@ -192,23 +176,35 @@ void makeraytree(Render *re) } } else vlr++; - - if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) - if((vlr->mat->mode & MA_WIRE)==0) - RE_ray_tree_add_face(re->raytree, RAY_OBJECT_SET(re, obi), vlr); + /* baking selected to active needs non-traceable too */ + if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) { + if((vlr->mat->mode & MA_WIRE)==0) { + cur_face->v1 = vlr->v1->co; + cur_face->v2 = vlr->v2->co; + cur_face->v3 = vlr->v3->co; + cur_face->v4 = vlr->v4 ? vlr->v4->co : NULL; + + cur_face->ob = (void*)obi; + cur_face->face = vlr; + + RayObject_add( re->raytree, (RayObject*) cur_face ); + cur_face++; + } + } } } - RE_ray_tree_done(re->raytree); - + RayObject_done( re->raytree ); +//TODO vlr_face_coords, vlr_check_intersect, vlr_get_transform, re); + re->i.infostr= NULL; re->stats_draw(re->sdh, &re->i); } static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) { - VlakRen *vlr= (VlakRen*)is->face; - ObjectInstanceRen *obi= RAY_OBJECT_GET(&R, is->ob); + ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob; + VlakRen *vlr= (VlakRen*)is->hit.face; int osatex= 0; /* set up view vector */ @@ -420,29 +416,25 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo ShadeResult shr; Isect isec; float f, f1, fr, fg, fb; - float ref[3], maxsize=RE_ray_tree_max_size(R.raytree); + float ref[3]; float dist_mir = origshi->mat->dist_mir; + assert(0); + /* Warning, This is not that nice, and possibly a bit slow for every ray, however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */ memset(&shi, 0, sizeof(ShadeInput)); /* end warning! - Campbell */ VECCOPY(isec.start, start); - if (dist_mir > 0.0) { - isec.end[0]= start[0]+dist_mir*vec[0]; - isec.end[1]= start[1]+dist_mir*vec[1]; - isec.end[2]= start[2]+dist_mir*vec[2]; - } else { - isec.end[0]= start[0]+maxsize*vec[0]; - isec.end[1]= start[1]+maxsize*vec[1]; - isec.end[2]= start[2]+maxsize*vec[2]; - } + VECCOPY(isec.vec, vec ); + isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; isec.mode= RE_RAY_MIRROR; - isec.faceorig= (RayFace*)vlr; - isec.oborig= RAY_OBJECT_SET(&R, obi); - if(RE_ray_tree_intersect(R.raytree, &isec)) { + isec.orig.ob = obi; + isec.orig.face = vlr; + + if(RayObject_raycast(R.raytree, &isec)) { float d= 1.0f; shi.mask= origshi->mask; @@ -1279,8 +1271,10 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) if it has col[3]>0.0f continue. so exit when alpha is full */ ShadeInput shi; ShadeResult shr; + + assert(0); - if(RE_ray_tree_intersect(R.raytree, is)) { + if(RayObject_raycast(R.raytree, is)) { float d= 1.0f; /* we got a face */ @@ -1312,8 +1306,9 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) /* adapt isect struct */ VECCOPY(is->start, shi.co); - is->oborig= RAY_OBJECT_SET(&R, shi.obi); - is->faceorig= (RayFace*)shi.vlr; + + is->orig.ob = shi.obi; + is->orig.face = shi.vlr; ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA); } @@ -1329,9 +1324,11 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) Isect isec; ShadeInput shi; ShadeResult shr_t; - float vec[3], accum[3], div= 0.0f, maxsize= RE_ray_tree_max_size(R.raytree); + float vec[3], accum[3], div= 0.0f; int a; + assert(0); + if(only_one) { return 0; } @@ -1339,8 +1336,8 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) accum[0]= accum[1]= accum[2]= 0.0f; isec.mode= RE_RAY_MIRROR; - isec.faceorig= (RayFace*)ship->vlr; - isec.oborig= RAY_OBJECT_SET(&R, ship->obi); + isec.orig.ob = ship->obi; + isec.orig.face = ship->vlr; for(a=0; a<8*8; a++) { @@ -1352,12 +1349,12 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) vec[1]-= vec[1]; vec[2]-= vec[2]; } + VECCOPY(isec.start, ship->co); - isec.end[0]= isec.start[0] + maxsize*vec[0]; - isec.end[1]= isec.start[1] + maxsize*vec[1]; - isec.end[2]= isec.start[2] + maxsize*vec[2]; - - if(RE_ray_tree_intersect(R.raytree, &isec)) { + VECCOPY(isec.vec, vec ); + isec.labda = RE_RAYTRACE_MAXDIST; + + if(RayObject_raycast(R.raytree, &isec)) { float fac; /* Warning, This is not that nice, and possibly a bit slow for every ray, @@ -1545,10 +1542,16 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) float dxyview[3], skyadded=0, div; int aocolor; - isec.faceorig= (RayFace*)shi->vlr; - isec.oborig= RAY_OBJECT_SET(&R, shi->obi); - isec.face_last= NULL; - isec.ob_last= 0; + assert(0); + + isec.orig.ob = shi->obi; + isec.orig.face = shi->vlr; + + isec.hit.ob = 0; + isec.hit.face = 0; + + isec.last_hit = NULL; + isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW; isec.lay= -1; @@ -1601,13 +1604,14 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) Normalize(dir); VECCOPY(isec.start, shi->co); - isec.end[0] = shi->co[0] - maxdist*dir[0]; - isec.end[1] = shi->co[1] - maxdist*dir[1]; - isec.end[2] = shi->co[2] - maxdist*dir[2]; + isec.vec[0] = -dir[0]; + isec.vec[1] = -dir[1]; + isec.vec[2] = -dir[2]; + isec.labda = maxdist; prev = fac; - if(RE_ray_tree_intersect(R.raytree, &isec)) { + if(RayObject_raycast(R.raytree, &isec)) { if (R.wrld.aomode & WO_AODIST) fac+= exp(-isec.labda*R.wrld.aodistfac); else fac+= 1.0f; } @@ -1672,10 +1676,16 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) float dxyview[3]; int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp; - isec.faceorig= (RayFace*)shi->vlr; - isec.oborig= RAY_OBJECT_SET(&R, shi->obi); - isec.face_last= NULL; - isec.ob_last= 0; + assert(0); + + isec.orig.ob = shi->obi; + isec.orig.face = shi->vlr; + + isec.hit.ob = 0; + isec.hit.face = 0; + + isec.last_hit = NULL; + isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW; isec.lay= -1; @@ -1725,14 +1735,15 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) actual++; - /* always set start/end, RE_ray_tree_intersect clips it */ + /* always set start/vec/labda */ VECCOPY(isec.start, shi->co); - isec.end[0] = shi->co[0] - maxdist*vec[0]; - isec.end[1] = shi->co[1] - maxdist*vec[1]; - isec.end[2] = shi->co[2] - maxdist*vec[2]; + isec.vec[0] = -vec[0]; + isec.vec[1] = -vec[1]; + isec.vec[2] = -vec[2]; + isec.labda = maxdist; /* do the trace */ - if(RE_ray_tree_intersect(R.raytree, &isec)) { + if(RayObject_raycast(R.raytree, &isec)) { if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac); else sh+= 1.0f; } @@ -1838,7 +1849,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * int samples=0; float samp3d[3]; - float fac=0.0f, vec[3]; + float fac=0.0f, vec[3], end[3]; float colsq[4]; float adapt_thresh = lar->adapt_thresh; int min_adapt_samples=4, max_samples = lar->ray_totsamp; @@ -1848,6 +1859,8 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * float jitco[RE_MAX_OSA][3]; int totjitco; +// assert(0); + colsq[0] = colsq[1] = colsq[2] = 0.0; if(isec->mode==RE_RAY_SHADOW_TRA) { shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; @@ -1879,8 +1892,9 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * while (samples < max_samples) { - isec->faceorig= (RayFace*)shi->vlr; - isec->oborig= RAY_OBJECT_SET(&R, shi->obi); + + isec->orig.ob = shi->obi; + isec->orig.face = shi->vlr; /* manually jitter the start shading co-ord per sample * based on the pre-generated OSA texture sampling offsets, @@ -1916,11 +1930,11 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * /* align samples to lamp vector */ Mat3MulVecfl(lar->mat, samp3d); } - isec->end[0]= vec[0]+samp3d[0]; - isec->end[1]= vec[1]+samp3d[1]; - isec->end[2]= vec[2]+samp3d[2]; + end[0] = vec[0]+samp3d[0]; + end[1] = vec[1]+samp3d[1]; + end[2] = vec[2]+samp3d[2]; } else { - VECCOPY(isec->end, vec); + VECCOPY(end, vec); } if(shi->strand) { @@ -1928,7 +1942,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * float jitbias= 0.5f*(VecLength(shi->dxco) + VecLength(shi->dyco)); float v[3]; - VECSUB(v, co, isec->end); + VECSUB(v, co, end); Normalize(v); co[0] -= jitbias*v[0]; @@ -1937,6 +1951,11 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * } VECCOPY(isec->start, co); +// VECSUB(isec->vec, end, isec->start); + isec->vec[0] = end[0]-isec->start[0]; + isec->vec[1] = end[1]-isec->start[1]; + isec->vec[2] = end[2]-isec->start[2]; + isec->labda = 1.0f; // * Normalize(isec->vec); /* trace the ray */ if(isec->mode==RE_RAY_SHADOW_TRA) { @@ -1955,7 +1974,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * colsq[2] += isec->col[2]*isec->col[2]; } else { - if( RE_ray_tree_intersect(R.raytree, isec) ) fac+= 1.0f; + if( RayObject_raycast(R.raytree, isec) ) fac+= 1.0f; } samples++; @@ -1996,6 +2015,8 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa float fac=0.0f, div=0.0f, vec[3]; int a, j= -1, mask; + assert(0); + if(isec->mode==RE_RAY_SHADOW_TRA) { shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; } @@ -2022,19 +2043,18 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa } } - isec->faceorig= (RayFace*)shi->vlr; - isec->oborig= RAY_OBJECT_SET(&R, shi->obi); + isec->orig.ob = shi->obi; + isec->orig.face = shi->vlr; vec[0]= jitlamp[0]; vec[1]= jitlamp[1]; vec[2]= 0.0f; Mat3MulVecfl(lar->mat, vec); - /* set start and end, RE_ray_tree_intersect clips it */ + /* set start and vec */ VECCOPY(isec->start, shi->co); - isec->end[0]= lampco[0]+vec[0]; - isec->end[1]= lampco[1]+vec[1]; - isec->end[2]= lampco[2]+vec[2]; + VECCOPY(isec->vec, vec); + isec->labda = 1.0f; if(isec->mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ @@ -2047,7 +2067,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa shadfac[2] += isec->col[2]; shadfac[3] += isec->col[3]; } - else if( RE_ray_tree_intersect(R.raytree, isec) ) fac+= 1.0f; + else if( RayObject_raycast(R.raytree, isec) ) fac+= 1.0f; div+= 1.0f; jitlamp+= 2; @@ -2071,7 +2091,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) { Isect isec; - float lampco[3], maxsize; + float lampco[3]; /* setup isec */ if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; @@ -2084,19 +2104,16 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) /* only when not mir tracing, first hit optimm */ if(shi->depth==0) { - isec.face_last= (RayFace*)lar->vlr_last[shi->thread]; - isec.ob_last= RAY_OBJECT_SET(&R, lar->obi_last[shi->thread]); + isec.last_hit = lar->last_hit[shi->thread]; } else { - isec.face_last= NULL; - isec.ob_last= 0; + isec.last_hit = NULL; } if(lar->type==LA_SUN || lar->type==LA_HEMI) { - maxsize= RE_ray_tree_max_size(R.raytree); - lampco[0]= shi->co[0] - maxsize*lar->vec[0]; - lampco[1]= shi->co[1] - maxsize*lar->vec[1]; - lampco[2]= shi->co[2] - maxsize*lar->vec[2]; + lampco[0]= shi->co[0] - RE_RAYTRACE_MAXDIST*lar->vec[0]; + lampco[1]= shi->co[1] - RE_RAYTRACE_MAXDIST*lar->vec[1]; + lampco[2]= shi->co[2] - RE_RAYTRACE_MAXDIST*lar->vec[2]; } else { VECCOPY(lampco, lar->co); @@ -2109,13 +2126,15 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) } else { if(lar->ray_totsamp<2) { - isec.faceorig= (RayFace*)shi->vlr; - isec.oborig= RAY_OBJECT_SET(&R, shi->obi); + isec.orig.ob = shi->obi; + isec.orig.face = shi->vlr; + shadfac[3]= 1.0f; // 1.0=full light /* set up isec vec */ VECCOPY(isec.start, shi->co); - VECCOPY(isec.end, lampco); + VECSUB(isec.vec, lampco, isec.start); + isec.labda = 1.0f; if(isec.mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ @@ -2125,7 +2144,11 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0); QUATCOPY(shadfac, isec.col); } - else if(RE_ray_tree_intersect(R.raytree, &isec)) shadfac[3]= 0.0f; + else + { + assert(0); + if(RayObject_raycast(R.raytree, &isec)) shadfac[3]= 0.0f; + } } else { ray_shadow_jitter(shi, lar, lampco, shadfac, &isec); @@ -2134,8 +2157,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) /* for first hit optim, set last interesected shadow face */ if(shi->depth==0) { - lar->vlr_last[shi->thread]= (VlakRen*)isec.face_last; - lar->obi_last[shi->thread]= RAY_OBJECT_GET(&R, isec.ob_last); + lar->last_hit[shi->thread] = isec.last_hit; } } @@ -2145,7 +2167,9 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co) { Isect isec; - float lampco[3], maxsize; + float lampco[3]; + + assert(0); /* setup isec */ isec.mode= RE_RAY_SHADOW_TRA; @@ -2153,23 +2177,22 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; if(lar->type==LA_SUN || lar->type==LA_HEMI) { - maxsize= RE_ray_tree_max_size(R.raytree); - lampco[0]= shi->co[0] - maxsize*lar->vec[0]; - lampco[1]= shi->co[1] - maxsize*lar->vec[1]; - lampco[2]= shi->co[2] - maxsize*lar->vec[2]; + lampco[0]= shi->co[0] - RE_RAYTRACE_MAXDIST*lar->vec[0]; + lampco[1]= shi->co[1] - RE_RAYTRACE_MAXDIST*lar->vec[1]; + lampco[2]= shi->co[2] - RE_RAYTRACE_MAXDIST*lar->vec[2]; } else { VECCOPY(lampco, lar->co); } - isec.faceorig= (RayFace*)shi->vlr; - isec.oborig= RAY_OBJECT_SET(&R, shi->obi); + isec.orig.ob = shi->obi; + isec.orig.face = shi->vlr; /* set up isec vec */ VECCOPY(isec.start, shi->co); VECCOPY(isec.end, lampco); - if(RE_ray_tree_intersect(R.raytree, &isec)) { + if(RayObject_raycast(R.raytree, &isec)) { /* we got a face */ /* render co */ diff --git a/source/blender/render/intern/source/raytrace.c b/source/blender/render/intern/source/raytrace.c deleted file mode 100644 index 09d3711885a..00000000000 --- a/source/blender/render/intern/source/raytrace.c +++ /dev/null @@ -1,1442 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 1990-1998 NeoGeo BV. - * All rights reserved. - * - * Contributors: 2004/2005 Blender Foundation, full recode - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* IMPORTANT NOTE: this code must be independent of any other render code - to use it outside the renderer! */ - -#include -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "DNA_material_types.h" - -#include "BKE_utildefines.h" - -#include "BLI_arithb.h" - -#include "RE_raytrace.h" - -/* ********** structs *************** */ - -#define BRANCH_ARRAY 1024 -#define NODE_ARRAY 4096 - -typedef struct Branch -{ - struct Branch *b[8]; -} Branch; - -typedef struct OcVal -{ - short ocx, ocy, ocz; -} OcVal; - -typedef struct Node -{ - struct RayFace *v[8]; - int ob[8]; - struct OcVal ov[8]; - struct Node *next; -} Node; - -typedef struct Octree { - struct Branch **adrbranch; - struct Node **adrnode; - float ocsize; /* ocsize: mult factor, max size octree */ - float ocfacx,ocfacy,ocfacz; - float min[3], max[3]; - int ocres; - int branchcount, nodecount; - char *ocface; /* during building only */ - RayCoordsFunc coordsfunc; - RayCheckFunc checkfunc; - RayObjectTransformFunc transformfunc; - void *userdata; -} Octree; - -/* ******** globals ***************** */ - -/* just for statistics */ -static int raycount; -static int accepted, rejected, coherent_ray; - - -/* **************** ocval method ******************* */ -/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */ - -#define OCVALRES 15 -#define BROW16(min, max) (((max)>=OCVALRES? 0xFFFF: (1<<(max+1))-1) - ((min>0)? ((1<<(min))-1):0) ) - -static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov) -{ - float min[3], max[3]; - int ocmin, ocmax; - - VECCOPY(min, v1); - VECCOPY(max, v1); - DO_MINMAX(v2, min, max); - DO_MINMAX(v3, min, max); - if(v4) { - DO_MINMAX(v4, min, max); - } - - ocmin= OCVALRES*(min[0]-x); - ocmax= OCVALRES*(max[0]-x); - ov->ocx= BROW16(ocmin, ocmax); - - ocmin= OCVALRES*(min[1]-y); - ocmax= OCVALRES*(max[1]-y); - ov->ocy= BROW16(ocmin, ocmax); - - ocmin= OCVALRES*(min[2]-z); - ocmax= OCVALRES*(max[2]-z); - ov->ocz= BROW16(ocmin, ocmax); - -} - -static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2) -{ - int ocmin, ocmax; - - if(vec1[0]ocx= BROW16(ocmin, ocmax); - - if(vec1[1]ocy= BROW16(ocmin, ocmax); - - if(vec1[2]ocz= BROW16(ocmin, ocmax); -} - -/* ************* octree ************** */ - -static Branch *addbranch(Octree *oc, Branch *br, short ocb) -{ - int index; - - if(br->b[ocb]) return br->b[ocb]; - - oc->branchcount++; - index= oc->branchcount>>12; - - if(oc->adrbranch[index]==NULL) - oc->adrbranch[index]= MEM_callocN(4096*sizeof(Branch), "new oc branch"); - - if(oc->branchcount>= BRANCH_ARRAY*4096) { - printf("error; octree branches full\n"); - oc->branchcount=0; - } - - return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095); -} - -static Node *addnode(Octree *oc) -{ - int index; - - oc->nodecount++; - index= oc->nodecount>>12; - - if(oc->adrnode[index]==NULL) - oc->adrnode[index]= MEM_callocN(4096*sizeof(Node),"addnode"); - - if(oc->nodecount> NODE_ARRAY*NODE_ARRAY) { - printf("error; octree nodes full\n"); - oc->nodecount=0; - } - - return oc->adrnode[index]+(oc->nodecount & 4095); -} - -static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]) -{ - static float nor[3], d; - float fx, fy, fz; - - // init static vars - if(face) { - CalcNormFloat(rtf[0], rtf[1], rtf[2], nor); - d= -nor[0]*rtf[0][0] - nor[1]*rtf[0][1] - nor[2]*rtf[0][2]; - return 0; - } - - fx= x; - fy= y; - fz= z; - - if((fx)*nor[0] + (fy)*nor[1] + (fz)*nor[2] + d > 0.0f) { - if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; - if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; - if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1; - - if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1; - } - else { - if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; - if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; - if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1; - - if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1; - } - - return 0; -} - -static void ocwrite(Octree *oc, int ob, RayFace *face, int quad, short x, short y, short z, float rtf[][3]) -{ - Branch *br; - Node *no; - short a, oc0, oc1, oc2, oc3, oc4, oc5; - - x<<=2; - y<<=1; - - br= oc->adrbranch[0]; - - if(oc->ocres==512) { - oc0= ((x & 1024)+(y & 512)+(z & 256))>>8; - br= addbranch(oc, br, oc0); - } - if(oc->ocres>=256) { - oc0= ((x & 512)+(y & 256)+(z & 128))>>7; - br= addbranch(oc, br, oc0); - } - if(oc->ocres>=128) { - oc0= ((x & 256)+(y & 128)+(z & 64))>>6; - br= addbranch(oc, br, oc0); - } - - oc0= ((x & 128)+(y & 64)+(z & 32))>>5; - oc1= ((x & 64)+(y & 32)+(z & 16))>>4; - oc2= ((x & 32)+(y & 16)+(z & 8))>>3; - oc3= ((x & 16)+(y & 8)+(z & 4))>>2; - oc4= ((x & 8)+(y & 4)+(z & 2))>>1; - oc5= ((x & 4)+(y & 2)+(z & 1)); - - br= addbranch(oc, br,oc0); - br= addbranch(oc, br,oc1); - br= addbranch(oc, br,oc2); - br= addbranch(oc, br,oc3); - br= addbranch(oc, br,oc4); - no= (Node *)br->b[oc5]; - if(no==NULL) br->b[oc5]= (Branch *)(no= addnode(oc)); - - while(no->next) no= no->next; - - a= 0; - if(no->v[7]) { /* node full */ - no->next= addnode(oc); - no= no->next; - } - else { - while(no->v[a]!=NULL) a++; - } - - no->v[a]= face; - no->ob[a]= ob; - - if(quad) - calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]); - else - calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x>>2, y>>1, z, &no->ov[a]); -} - -static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3]) -{ - int ocx1,ocx2,ocy1,ocy2; - int x,y,dx=0,dy=0; - float ox1,ox2,oy1,oy2; - float labda,labdao,labdax,labday,ldx,ldy; - - ocx1= rts[b1][c1]; - ocy1= rts[b1][c2]; - ocx2= rts[b2][c1]; - ocy2= rts[b2][c2]; - - if(ocx1==ocx2 && ocy1==ocy2) { - ocface[oc->ocres*ocx1+ocy1]= 1; - return; - } - - ox1= rtf[b1][c1]; - oy1= rtf[b1][c2]; - ox2= rtf[b2][c1]; - oy2= rtf[b2][c2]; - - if(ox1!=ox2) { - if(ox2-ox1>0.0f) { - labdax= (ox1-ocx1-1.0f)/(ox1-ox2); - ldx= -1.0f/(ox1-ox2); - dx= 1; - } else { - labdax= (ox1-ocx1)/(ox1-ox2); - ldx= 1.0f/(ox1-ox2); - dx= -1; - } - } else { - labdax=1.0f; - ldx=0; - } - - if(oy1!=oy2) { - if(oy2-oy1>0.0f) { - labday= (oy1-ocy1-1.0f)/(oy1-oy2); - ldy= -1.0f/(oy1-oy2); - dy= 1; - } else { - labday= (oy1-ocy1)/(oy1-oy2); - ldy= 1.0f/(oy1-oy2); - dy= -1; - } - } else { - labday=1.0f; - ldy=0; - } - - x=ocx1; y=ocy1; - labda= MIN2(labdax, labday); - - while(TRUE) { - - if(x<0 || y<0 || x>=oc->ocres || y>=oc->ocres); - else ocface[oc->ocres*x+y]= 1; - - labdao=labda; - if(labdax==labday) { - labdax+=ldx; - x+=dx; - labday+=ldy; - y+=dy; - } else { - if(labdax=1.0f) break; - } - ocface[oc->ocres*ocx2+ocy2]=1; -} - -static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin) -{ - short *ocmax; - int a, x, y, y1, y2; - - ocmax=ocmin+3; - - for(x=ocmin[c1];x<=ocmax[c1];x++) { - a= oc->ocres*x; - for(y=ocmin[c2];y<=ocmax[c2];y++) { - if(ocface[a+y]) { - y++; - while(ocface[a+y] && y!=ocmax[c2]) y++; - for(y1=ocmax[c2];y1>y;y1--) { - if(ocface[a+y1]) { - for(y2=y;y2<=y1;y2++) ocface[a+y2]=1; - y1=0; - } - } - y=ocmax[c2]; - } - } - } -} - -void RE_ray_tree_free(RayTree *tree) -{ - Octree *oc= (Octree*)tree; - -#if 0 - printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount); - printf("raycount %d \n", raycount); - printf("ray coherent %d \n", coherent_ray); - printf("accepted %d rejected %d\n", accepted, rejected); -#endif - if(oc->ocface) - MEM_freeN(oc->ocface); - - if(oc->adrbranch) { - int a= 0; - while(oc->adrbranch[a]) { - MEM_freeN(oc->adrbranch[a]); - oc->adrbranch[a]= NULL; - a++; - } - MEM_freeN(oc->adrbranch); - oc->adrbranch= NULL; - } - oc->branchcount= 0; - - if(oc->adrnode) { - int a= 0; - while(oc->adrnode[a]) { - MEM_freeN(oc->adrnode[a]); - oc->adrnode[a]= NULL; - a++; - } - MEM_freeN(oc->adrnode); - oc->adrnode= NULL; - } - oc->nodecount= 0; - - MEM_freeN(oc); -} - -RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, RayCoordsFunc coordsfunc, RayCheckFunc checkfunc, RayObjectTransformFunc transformfunc, void *userdata) -{ - Octree *oc; - float t00, t01, t02; - int c, ocres2; - - oc= MEM_callocN(sizeof(Octree), "Octree"); - oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); - oc->adrnode= MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes"); - - oc->coordsfunc= coordsfunc; - oc->checkfunc= checkfunc; - oc->transformfunc= transformfunc; - oc->userdata= userdata; - - /* only for debug info */ - raycount=0; - accepted= 0; - rejected= 0; - coherent_ray= 0; - - /* fill main octree struct */ - oc->ocres= ocres; - ocres2= oc->ocres*oc->ocres; - - VECCOPY(oc->min, min); - VECCOPY(oc->max, max); - - oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree"); - - /* the lookup table, per face, for which nodes to fill in */ - oc->ocface= MEM_callocN( 3*ocres2 + 8, "ocface"); - memset(oc->ocface, 0, 3*ocres2); - - for(c=0;c<3;c++) { /* octree enlarge, still needed? */ - oc->min[c]-= 0.01f; - oc->max[c]+= 0.01f; - } - - t00= oc->max[0]-oc->min[0]; - t01= oc->max[1]-oc->min[1]; - t02= oc->max[2]-oc->min[2]; - - /* this minus 0.1 is old safety... seems to be needed? */ - oc->ocfacx= (oc->ocres-0.1)/t00; - oc->ocfacy= (oc->ocres-0.1)/t01; - oc->ocfacz= (oc->ocres-0.1)/t02; - - oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */ - - return (RayTree*)oc; -} - -void RE_ray_tree_add_face(RayTree *tree, int ob, RayFace *face) -{ - Octree *oc = (Octree*)tree; - float *v1, *v2, *v3, *v4, ocfac[3], rtf[4][3]; - float co1[3], co2[3], co3[3], co4[3]; - short rts[4][3], ocmin[6], *ocmax; - char *ocface= oc->ocface; // front, top, size view of face, to fill in - int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2; - - ocfac[0]= oc->ocfacx; - ocfac[1]= oc->ocfacy; - ocfac[2]= oc->ocfacz; - - ocres2= oc->ocres*oc->ocres; - - ocmax= ocmin+3; - - oc->coordsfunc(face, &v1, &v2, &v3, &v4); - - VECCOPY(co1, v1); - VECCOPY(co2, v2); - VECCOPY(co3, v3); - if(v4) - VECCOPY(co4, v4); - - if(ob >= RE_RAY_TRANSFORM_OFFS) { - float (*mat)[4]= (float(*)[4])oc->transformfunc(oc->userdata, ob); - - if(mat) { - Mat4MulVecfl(mat, co1); - Mat4MulVecfl(mat, co2); - Mat4MulVecfl(mat, co3); - if(v4) - Mat4MulVecfl(mat, co4); - } - } - - for(c=0;c<3;c++) { - rtf[0][c]= (co1[c]-oc->min[c])*ocfac[c] ; - rts[0][c]= (short)rtf[0][c]; - rtf[1][c]= (co2[c]-oc->min[c])*ocfac[c] ; - rts[1][c]= (short)rtf[1][c]; - rtf[2][c]= (co3[c]-oc->min[c])*ocfac[c] ; - rts[2][c]= (short)rtf[2][c]; - if(v4) { - rtf[3][c]= (co4[c]-oc->min[c])*ocfac[c] ; - rts[3][c]= (short)rtf[3][c]; - } - } - - for(c=0;c<3;c++) { - oc1= rts[0][c]; - oc2= rts[1][c]; - oc3= rts[2][c]; - if(v4==NULL) { - ocmin[c]= MIN3(oc1,oc2,oc3); - ocmax[c]= MAX3(oc1,oc2,oc3); - } - else { - oc4= rts[3][c]; - ocmin[c]= MIN4(oc1,oc2,oc3,oc4); - ocmax[c]= MAX4(oc1,oc2,oc3,oc4); - } - if(ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1; - if(ocmin[c]<0) ocmin[c]=0; - } - - if(ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) { - ocwrite(oc, ob, face, (v4 != NULL), ocmin[0], ocmin[1], ocmin[2], rtf); - } - else { - - d2dda(oc, 0,1,0,1,ocface+ocres2,rts,rtf); - d2dda(oc, 0,1,0,2,ocface,rts,rtf); - d2dda(oc, 0,1,1,2,ocface+2*ocres2,rts,rtf); - d2dda(oc, 1,2,0,1,ocface+ocres2,rts,rtf); - d2dda(oc, 1,2,0,2,ocface,rts,rtf); - d2dda(oc, 1,2,1,2,ocface+2*ocres2,rts,rtf); - if(v4==NULL) { - d2dda(oc, 2,0,0,1,ocface+ocres2,rts,rtf); - d2dda(oc, 2,0,0,2,ocface,rts,rtf); - d2dda(oc, 2,0,1,2,ocface+2*ocres2,rts,rtf); - } - else { - d2dda(oc, 2,3,0,1,ocface+ocres2,rts,rtf); - d2dda(oc, 2,3,0,2,ocface,rts,rtf); - d2dda(oc, 2,3,1,2,ocface+2*ocres2,rts,rtf); - d2dda(oc, 3,0,0,1,ocface+ocres2,rts,rtf); - d2dda(oc, 3,0,0,2,ocface,rts,rtf); - d2dda(oc, 3,0,1,2,ocface+2*ocres2,rts,rtf); - } - /* nothing todo with triangle..., just fills :) */ - filltriangle(oc, 0,1,ocface+ocres2,ocmin); - filltriangle(oc, 0,2,ocface,ocmin); - filltriangle(oc, 1,2,ocface+2*ocres2,ocmin); - - /* init static vars here */ - face_in_node(face, 0,0,0, rtf); - - for(x=ocmin[0];x<=ocmax[0];x++) { - a= oc->ocres*x; - for(y=ocmin[1];y<=ocmax[1];y++) { - if(ocface[a+y+ocres2]) { - b= oc->ocres*y+2*ocres2; - for(z=ocmin[2];z<=ocmax[2];z++) { - if(ocface[b+z] && ocface[a+z]) { - if(face_in_node(NULL, x, y, z, rtf)) - ocwrite(oc, ob, face, (v4 != NULL), x,y,z, rtf); - } - } - } - } - } - - /* same loops to clear octree, doubt it can be done smarter */ - for(x=ocmin[0];x<=ocmax[0];x++) { - a= oc->ocres*x; - for(y=ocmin[1];y<=ocmax[1];y++) { - /* x-y */ - ocface[a+y+ocres2]= 0; - - b= oc->ocres*y + 2*ocres2; - for(z=ocmin[2];z<=ocmax[2];z++) { - /* y-z */ - ocface[b+z]= 0; - /* x-z */ - ocface[a+z]= 0; - } - } - } - } -} - -void RE_ray_tree_done(RayTree *tree) -{ - Octree *oc= (Octree*)tree; - - MEM_freeN(oc->ocface); - oc->ocface= NULL; -} - -/* ************ raytracer **************** */ - -#define ISECT_EPSILON ((float)FLT_EPSILON) - -/* only for self-intersecting test with current render face (where ray left) */ -static int intersection2(RayFace *face, int ob, RayObjectTransformFunc transformfunc, RayCoordsFunc coordsfunc, void *userdata, float r0, float r1, float r2, float rx1, float ry1, float rz1) -{ - float *v1, *v2, *v3, *v4, co1[3], co2[3], co3[3], co4[3]; - float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; - float m0, m1, m2, divdet, det, det1; - float u1, v, u2; - - coordsfunc(face, &v1, &v2, &v3, &v4); - - /* happens for baking with non existing face */ - if(v1==NULL) - return 1; - - if(v4) { - SWAP(float*, v3, v4); - } - - VECCOPY(co1, v1); - VECCOPY(co2, v2); - VECCOPY(co3, v3); - if(v4) - VECCOPY(co4, v4); - - if(ob >= RE_RAY_TRANSFORM_OFFS) { - float (*mat)[4]= (float(*)[4])transformfunc(userdata, ob); - - if(mat) { - Mat4MulVecfl(mat, co1); - Mat4MulVecfl(mat, co2); - Mat4MulVecfl(mat, co3); - if(v4) - Mat4MulVecfl(mat, co4); - } - } - - t00= co3[0]-co1[0]; - t01= co3[1]-co1[1]; - t02= co3[2]-co1[2]; - t10= co3[0]-co2[0]; - t11= co3[1]-co2[1]; - t12= co3[2]-co2[2]; - - x0= t11*r2-t12*r1; - x1= t12*r0-t10*r2; - x2= t10*r1-t11*r0; - - divdet= t00*x0+t01*x1+t02*x2; - - m0= rx1-co3[0]; - m1= ry1-co3[1]; - m2= rz1-co3[2]; - det1= m0*x0+m1*x1+m2*x2; - - if(divdet!=0.0f) { - u1= det1/divdet; - - if(u1 -(1.0f+ISECT_EPSILON)) { - return 1; - } - } - } - - if(v4) { - - t20= co3[0]-co4[0]; - t21= co3[1]-co4[1]; - t22= co3[2]-co4[2]; - - divdet= t20*x0+t21*x1+t22*x2; - if(divdet!=0.0f) { - u2= det1/divdet; - - if(u2= -(1.0f+ISECT_EPSILON)) { - return 2; - } - } - } - } - return 0; -} - -#if 0 -/* ray - line intersection */ -/* disabled until i got real & fast cylinder checking, this code doesnt work proper -for faster strands */ - -static int intersection_strand(Isect *is) -{ - float v1[3], v2[3]; /* length of strand */ - float axis[3], rc[3], nor[3], radline, dist, len; - - /* radius strand */ - radline= 0.5f*VecLenf(is->vlr->v1->co, is->vlr->v2->co); - - VecMidf(v1, is->vlr->v1->co, is->vlr->v2->co); - VecMidf(v2, is->vlr->v3->co, is->vlr->v4->co); - - VECSUB(rc, v1, is->start); /* vector from base ray to base cylinder */ - VECSUB(axis, v2, v1); /* cylinder axis */ - - CROSS(nor, is->vec, axis); - len= VecLength(nor); - - if(len-radline) { - float dot1, dot2, dot3, rlen, alen, div; - float labda; - - /* calculating the intersection point of shortest distance */ - dot1 = INPR(rc, is->vec); - dot2 = INPR(is->vec, axis); - dot3 = INPR(rc, axis); - rlen = INPR(is->vec, is->vec); - alen = INPR(axis, axis); - - div = alen * rlen - dot2 * dot2; - if (ABS(div) < FLT_EPSILON) - return 0; - - labda = (dot1*dot2 - dot3*rlen)/div; - - radline/= sqrt(alen); - - /* labda: where on axis do we have closest intersection? */ - if(labda >= -radline && labda <= 1.0f+radline) { - VlakRen *vlr= is->faceorig; - VertRen *v1= is->vlr->v1, *v2= is->vlr->v2, *v3= is->vlr->v3, *v4= is->vlr->v4; - /* but we dont do shadows from faces sharing edge */ - - if(v1==vlr->v1 || v2==vlr->v1 || v3==vlr->v1 || v4==vlr->v1) return 0; - if(v1==vlr->v2 || v2==vlr->v2 || v3==vlr->v2 || v4==vlr->v2) return 0; - if(v1==vlr->v3 || v2==vlr->v3 || v3==vlr->v3 || v4==vlr->v3) return 0; - if(vlr->v4) { - if(v1==vlr->v4 || v2==vlr->v4 || v3==vlr->v4 || v4==vlr->v4) return 0; - } - return 1; - } - } - return 0; -} -#endif - -/* ray - triangle or quad intersection */ -int RE_ray_face_intersection(Isect *is, RayObjectTransformFunc transformfunc, RayCoordsFunc coordsfunc) -{ - RayFace *face= is->face; - int ob= is->ob; - float *v1,*v2,*v3,*v4,co1[3],co2[3],co3[3],co4[3]; - float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2; - float m0, m1, m2, divdet, det1; - short ok=0; - - /* disabled until i got real & fast cylinder checking, this code doesnt work proper - for faster strands */ -// if(is->mode==RE_RAY_SHADOW && is->vlr->flag & R_STRAND) -// return intersection_strand(is); - - coordsfunc(face, &v1, &v2, &v3, &v4); - - if(v4) { - SWAP(float*, v3, v4); - } - - VECCOPY(co1, v1); - VECCOPY(co2, v2); - VECCOPY(co3, v3); - if(v4) - VECCOPY(co4, v4); - - if(ob) { - float (*mat)[4]= (float(*)[4])transformfunc(is->userdata, ob); - - if(mat) { - Mat4MulVecfl(mat, co1); - Mat4MulVecfl(mat, co2); - Mat4MulVecfl(mat, co3); - if(v4) - Mat4MulVecfl(mat, co4); - } - } - - t00= co3[0]-co1[0]; - t01= co3[1]-co1[1]; - t02= co3[2]-co1[2]; - t10= co3[0]-co2[0]; - t11= co3[1]-co2[1]; - t12= co3[2]-co2[2]; - - r0= is->vec[0]; - r1= is->vec[1]; - r2= is->vec[2]; - - x0= t12*r1-t11*r2; - x1= t10*r2-t12*r0; - x2= t11*r0-t10*r1; - - divdet= t00*x0+t01*x1+t02*x2; - - m0= is->start[0]-co3[0]; - m1= is->start[1]-co3[1]; - m2= is->start[2]-co3[2]; - det1= m0*x0+m1*x1+m2*x2; - - if(divdet!=0.0f) { - float u; - - divdet= 1.0f/divdet; - u= det1*divdet; - if(u-(1.0f+ISECT_EPSILON)) { - float v, cros0, cros1, cros2; - - cros0= m1*t02-m2*t01; - cros1= m2*t00-m0*t02; - cros2= m0*t01-m1*t00; - v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); - - if(v -(1.0f+ISECT_EPSILON)) { - float labda; - labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); - - if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { - is->labda= labda; - is->u= u; is->v= v; - ok= 1; - } - } - } - } - - if(ok==0 && v4) { - - t20= co3[0]-co4[0]; - t21= co3[1]-co4[1]; - t22= co3[2]-co4[2]; - - divdet= t20*x0+t21*x1+t22*x2; - if(divdet!=0.0f) { - float u; - divdet= 1.0f/divdet; - u = det1*divdet; - - if(u-(1.0f+ISECT_EPSILON)) { - float v, cros0, cros1, cros2; - cros0= m1*t22-m2*t21; - cros1= m2*t20-m0*t22; - cros2= m0*t21-m1*t20; - v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); - - if(v-(1.0f+ISECT_EPSILON)) { - float labda; - labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); - - if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { - ok= 2; - is->labda= labda; - is->u= u; is->v= v; - } - } - } - } - } - - if(ok) { - is->isect= ok; // wich half of the quad - - if(is->mode!=RE_RAY_SHADOW) { - /* for mirror & tra-shadow: large faces can be filled in too often, this prevents - a face being detected too soon... */ - if(is->labda > is->ddalabda) { - return 0; - } - } - - /* when a shadow ray leaves a face, it can be little outside the edges of it, causing - intersection to be detected in its neighbour face */ - - if(is->facecontr && is->faceisect); // optimizing, the tests below are not needed - else if(is->labda< .1) { - RayFace *face= is->faceorig; - float *origv1, *origv2, *origv3, *origv4; - short de= 0; - - coordsfunc(face, &origv1, &origv2, &origv3, &origv4); - - if(ob == is->oborig) { - if(v1==origv1 || v2==origv1 || v3==origv1 || v4==origv1) de++; - if(v1==origv2 || v2==origv2 || v3==origv2 || v4==origv2) de++; - if(v1==origv3 || v2==origv3 || v3==origv3 || v4==origv3) de++; - if(origv4) { - if(v1==origv4 || v2==origv4 || v3==origv4 || v4==origv4) de++; - } - } - if(de) { - /* so there's a shared edge or vertex, let's intersect ray with face - itself, if that's true we can safely return 1, otherwise we assume - the intersection is invalid, 0 */ - - if(is->facecontr==NULL) { - is->obcontr= is->oborig; - is->facecontr= face; - is->faceisect= intersection2(face, is->oborig, transformfunc, coordsfunc, is->userdata, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]); - } - - if(is->faceisect) return 1; - return 0; - } - } - - return 1; - } - - return 0; -} - -/* check all faces in this node */ -static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc checkfunc) -{ - RayFace *face; - int ob; - short nr=0; - OcVal *ov; - - /* return on any first hit */ - if(is->mode==RE_RAY_SHADOW) { - - face= no->v[0]; - ob= no->ob[0]; - while(face) { - - if(!(is->faceorig == face && is->oborig == ob)) { - - if(checkfunc(is, ob, face)) { - - ov= no->ov+nr; - if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - //accepted++; - is->ob= ob; - is->face= face; - - if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) { - is->ob_last= ob; - is->face_last= face; - return 1; - } - } - //else rejected++; - } - } - - nr++; - if(nr==8) { - no= no->next; - if(no==0) return 0; - nr=0; - } - face= no->v[nr]; - ob= no->ob[nr]; - } - } - else { /* else mirror or glass or shadowtra, return closest face */ - Isect isect; - int found= 0; - - is->labda= 1.0f; /* needed? */ - isect= *is; /* copy for sorting */ - - face= no->v[0]; - ob= no->ob[0]; - while(face) { - - if(!(is->faceorig == face && is->oborig == ob)) { - if(checkfunc(is, ob, face)) { - ov= no->ov+nr; - if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - //accepted++; - - isect.ob= ob; - isect.face= face; - if(RE_ray_face_intersection(&isect, oc->transformfunc, oc->coordsfunc)) { - if(isect.labdalabda) { - *is= isect; - found= 1; - } - - } - } - //else rejected++; - } - } - - nr++; - if(nr==8) { - no= no->next; - if(no==NULL) break; - nr=0; - } - face= no->v[nr]; - ob= no->ob[nr]; - } - - return found; - } - - return 0; -} - -/* find the Node for the octree coord x y z */ -static Node *ocread(Octree *oc, int x, int y, int z) -{ - Branch *br; - int oc1; - - x<<=2; - y<<=1; - - br= oc->adrbranch[0]; - - if(oc->ocres==512) { - oc1= ((x & 1024)+(y & 512)+(z & 256))>>8; - br= br->b[oc1]; - if(br==NULL) { - return NULL; - } - } - if(oc->ocres>=256) { - oc1= ((x & 512)+(y & 256)+(z & 128))>>7; - br= br->b[oc1]; - if(br==NULL) { - return NULL; - } - } - if(oc->ocres>=128) { - oc1= ((x & 256)+(y & 128)+(z & 64))>>6; - br= br->b[oc1]; - if(br==NULL) { - return NULL; - } - } - - oc1= ((x & 128)+(y & 64)+(z & 32))>>5; - br= br->b[oc1]; - if(br) { - oc1= ((x & 64)+(y & 32)+(z & 16))>>4; - br= br->b[oc1]; - if(br) { - oc1= ((x & 32)+(y & 16)+(z & 8))>>3; - br= br->b[oc1]; - if(br) { - oc1= ((x & 16)+(y & 8)+(z & 4))>>2; - br= br->b[oc1]; - if(br) { - oc1= ((x & 8)+(y & 4)+(z & 2))>>1; - br= br->b[oc1]; - if(br) { - oc1= ((x & 4)+(y & 2)+(z & 1)); - return (Node *)br->b[oc1]; - } - } - } - } - } - - return NULL; -} - -static int cliptest(float p, float q, float *u1, float *u2) -{ - float r; - - if(p<0.0f) { - if(q*u2) return 0; - else if(r>*u1) *u1=r; - } - } - else { - if(p>0.0f) { - if(q<0.0f) return 0; - else if(qcheckfunc); -} - -/* return 1: found valid intersection */ -/* starts with is->faceorig */ -int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc checkfunc) -{ - Octree *oc= (Octree*)tree; - Node *no; - OcVal ocval; - float vec1[3], vec2[3]; - float u1,u2,ox1,ox2,oy1,oy2,oz1,oz2; - float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda; - int dx,dy,dz; - int xo,yo,zo,c1=0; - int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2; - - /* clip with octree */ - if(oc->branchcount==0) return 0; - - /* do this before intersect calls */ - is->facecontr= NULL; /* to check shared edge */ - is->obcontr= 0; - is->faceisect= is->isect= 0; /* shared edge, quad half flag */ - is->userdata= oc->userdata; - - /* only for shadow! */ - if(is->mode==RE_RAY_SHADOW) { - - /* check with last intersected shadow face */ - if(is->face_last!=NULL && !(is->face_last==is->faceorig && is->ob_last==is->oborig)) { - if(checkfunc(is, is->ob_last, is->face_last)) { - is->ob= is->ob_last; - is->face= is->face_last; - VECSUB(is->vec, is->end, is->start); - if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) return 1; - } - } - } - - ldx= is->end[0] - is->start[0]; - u1= 0.0f; - u2= 1.0f; - - /* clip with octree cube */ - if(cliptest(-ldx, is->start[0]-oc->min[0], &u1,&u2)) { - if(cliptest(ldx, oc->max[0]-is->start[0], &u1,&u2)) { - ldy= is->end[1] - is->start[1]; - if(cliptest(-ldy, is->start[1]-oc->min[1], &u1,&u2)) { - if(cliptest(ldy, oc->max[1]-is->start[1], &u1,&u2)) { - ldz= is->end[2] - is->start[2]; - if(cliptest(-ldz, is->start[2]-oc->min[2], &u1,&u2)) { - if(cliptest(ldz, oc->max[2]-is->start[2], &u1,&u2)) { - c1=1; - if(u2<1.0f) { - is->end[0]= is->start[0]+u2*ldx; - is->end[1]= is->start[1]+u2*ldy; - is->end[2]= is->start[2]+u2*ldz; - } - if(u1>0.0f) { - is->start[0]+=u1*ldx; - is->start[1]+=u1*ldy; - is->start[2]+=u1*ldz; - } - } - } - } - } - } - } - - if(c1==0) return 0; - - /* reset static variables in ocread */ - //ocread(oc, oc->ocres, 0, 0); - - /* setup 3dda to traverse octree */ - ox1= (is->start[0]-oc->min[0])*oc->ocfacx; - oy1= (is->start[1]-oc->min[1])*oc->ocfacy; - oz1= (is->start[2]-oc->min[2])*oc->ocfacz; - ox2= (is->end[0]-oc->min[0])*oc->ocfacx; - oy2= (is->end[1]-oc->min[1])*oc->ocfacy; - oz2= (is->end[2]-oc->min[2])*oc->ocfacz; - - ocx1= (int)ox1; - ocy1= (int)oy1; - ocz1= (int)oz1; - ocx2= (int)ox2; - ocy2= (int)oy2; - ocz2= (int)oz2; - - /* for intersection */ - VECSUB(is->vec, is->end, is->start); - - if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) { - no= ocread(oc, ocx1, ocy1, ocz1); - if(no) { - /* exact intersection with node */ - vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1; - vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2; - calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); - is->ddalabda= 1.0f; - if( testnode(oc, is, no, ocval, checkfunc) ) return 1; - } - } - else { - //static int coh_ocx1,coh_ocx2,coh_ocy1, coh_ocy2,coh_ocz1,coh_ocz2; - float dox, doy, doz; - int eqval; - - /* calc labda en ld */ - dox= ox1-ox2; - doy= oy1-oy2; - doz= oz1-oz2; - - if(dox<-FLT_EPSILON) { - ldx= -1.0f/dox; - labdax= (ocx1-ox1+1.0f)*ldx; - dx= 1; - } else if(dox>FLT_EPSILON) { - ldx= 1.0f/dox; - labdax= (ox1-ocx1)*ldx; - dx= -1; - } else { - labdax=1.0f; - ldx=0; - dx= 0; - } - - if(doy<-FLT_EPSILON) { - ldy= -1.0f/doy; - labday= (ocy1-oy1+1.0f)*ldy; - dy= 1; - } else if(doy>FLT_EPSILON) { - ldy= 1.0f/doy; - labday= (oy1-ocy1)*ldy; - dy= -1; - } else { - labday=1.0f; - ldy=0; - dy= 0; - } - - if(doz<-FLT_EPSILON) { - ldz= -1.0f/doz; - labdaz= (ocz1-oz1+1.0f)*ldz; - dz= 1; - } else if(doz>FLT_EPSILON) { - ldz= 1.0f/doz; - labdaz= (oz1-ocz1)*ldz; - dz= -1; - } else { - labdaz=1.0f; - ldz=0; - dz= 0; - } - - xo=ocx1; yo=ocy1; zo=ocz1; - labdao= ddalabda= MIN3(labdax,labday,labdaz); - - vec2[0]= ox1; - vec2[1]= oy1; - vec2[2]= oz1; - - /* this loop has been constructed to make sure the first and last node of ray - are always included, even when ddalabda==1.0f or larger */ - - while(TRUE) { - - no= ocread(oc, xo, yo, zo); - if(no) { - - /* calculate ray intersection with octree node */ - VECCOPY(vec1, vec2); - // dox,y,z is negative - vec2[0]= ox1-ddalabda*dox; - vec2[1]= oy1-ddalabda*doy; - vec2[2]= oz1-ddalabda*doz; - calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - - is->ddalabda= ddalabda; - if( testnode(oc, is, no, ocval, checkfunc) ) return 1; - } - - labdao= ddalabda; - - /* traversing ocree nodes need careful detection of smallest values, with proper - exceptions for equal labdas */ - eqval= (labdax==labday); - if(labday==labdaz) eqval += 2; - if(labdax==labdaz) eqval += 4; - - if(eqval) { // only 4 cases exist! - if(eqval==7) { // x=y=z - xo+=dx; labdax+=ldx; - yo+=dy; labday+=ldy; - zo+=dz; labdaz+=ldz; - } - else if(eqval==1) { // x=y - if(labday < labdaz) { - xo+=dx; labdax+=ldx; - yo+=dy; labday+=ldy; - } - else { - zo+=dz; labdaz+=ldz; - } - } - else if(eqval==2) { // y=z - if(labdax < labday) { - xo+=dx; labdax+=ldx; - } - else { - yo+=dy; labday+=ldy; - zo+=dz; labdaz+=ldz; - } - } - else { // x=z - if(labday < labdax) { - yo+=dy; labday+=ldy; - } - else { - xo+=dx; labdax+=ldx; - zo+=dz; labdaz+=ldz; - } - } - } - else { // all three different, just three cases exist - eqval= (labdax=1.0f) break; - } - } - - /* reached end, no intersections found */ - is->ob_last= 0; - is->face_last= NULL; - return 0; -} - -float RE_ray_tree_max_size(RayTree *tree) -{ - return ((Octree*)tree)->ocsize; -} - diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index deb6f0db743..fe1ab21a4a4 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -31,6 +31,7 @@ #include #include #include +#include /* External modules: */ #include "MEM_guardedalloc.h" @@ -2234,6 +2235,7 @@ static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, } } +#if 0 static int bake_check_intersect(Isect *is, int ob, RayFace *face) { BakeShade *bs = (BakeShade*)is->userdata; @@ -2243,9 +2245,13 @@ static int bake_check_intersect(Isect *is, int ob, RayFace *face) return (R.objectinstance[ob].obr->ob != bs->actob); } +#endif -static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist) +static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist) { + //TODO + assert( 0 ); +#if 0 float maxdist; int hit; @@ -2253,15 +2259,17 @@ static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, flo if(R.r.bake_maxdist > 0.0f) maxdist= R.r.bake_maxdist; else - maxdist= RE_ray_tree_max_size(R.raytree) + R.r.bake_biasdist; + maxdist= FLT_MAX + R.r.bake_biasdist; + //TODO normalized direction? VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist); + isect->dir[0] = dir[0]*sign; + isect->dir[1] = dir[1]*sign; + isect->dir[2] = dir[2]*sign; + isect->labda = maxdist; - isect->end[0] = isect->start[0] + dir[0]*maxdist*sign; - isect->end[1] = isect->start[1] + dir[1]*maxdist*sign; - isect->end[2] = isect->start[2] + dir[2]*maxdist*sign; - - hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect); + hit = RayObject_raycast(raytree, isect); + //TODO bake_check_intersect if(hit) { hitco[0] = isect->start[0] + isect->labda*isect->vec[0]; hitco[1] = isect->start[1] + isect->labda*isect->vec[1]; @@ -2271,6 +2279,8 @@ static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, flo } return hit; +#endif + return 0; } static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3) @@ -2387,8 +2397,9 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) for(sign=-1; sign<=1; sign+=2) { memset(&isec, 0, sizeof(isec)); isec.mode= RE_RAY_MIRROR; - isec.faceorig= (RayFace*)vlr; - isec.oborig= RAY_OBJECT_SET(&R, obi); + + isec.orig.ob = obi; + isec.orig.face = vlr; isec.userdata= bs; if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) { @@ -2412,8 +2423,8 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) /* if hit, we shade from the new point, otherwise from point one starting face */ if(hit) { - vlr= (VlakRen*)minisec.face; - obi= RAY_OBJECT_GET(&R, minisec.ob); + obi= (ObjectInstanceRen*)minisec.hit.ob; + vlr= (VlakRen*)minisec.hit.face; quad= (minisec.isect == 2); VECCOPY(shi->co, minco); -- cgit v1.2.3 From f5566daa89a43a4b248f36b5335772ebd35960b8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 11 May 2009 13:56:45 +0000 Subject: Added neighbour test on detected ray hit --- source/blender/render/extern/include/RE_raytrace.h | 5 +- source/blender/render/intern/source/rayobject.c | 171 ++++++++++++++------- source/blender/render/intern/source/rayshade.c | 1 + 3 files changed, 123 insertions(+), 54 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index b274fe681b3..b5ff3d9cae0 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -85,7 +85,10 @@ struct Isect #define RE_RAY_SHADOW_TRA 2 /* skip options */ -#define RE_SKIP_CULLFACE 1 +#define RE_SKIP_CULLFACE (1 << 0) + +/* if using this flag then *face should be a pointer to a VlakRen */ +#define RE_SKIP_VLR_NEIGHBOUR (1 << 1) /* TODO use: FLT_MAX? */ #define RE_RAYTRACE_MAXDIST 1e33 diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index ee364d3586c..c816bcb2333 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -31,14 +31,96 @@ #include "BKE_utildefines.h" #include "RE_raytrace.h" +#include "render_types.h" #include "rayobject.h" +/* only for self-intersecting test with current render face (where ray left) */ +static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, float ry1, float rz1) +{ + float co1[3], co2[3], co3[3], co4[3]; + float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; + float m0, m1, m2, divdet, det, det1; + float u1, v, u2; + + VECCOPY(co1, face->v1->co); + VECCOPY(co2, face->v2->co); + if(face->v4) + { + VECCOPY(co3, face->v4->co); + VECCOPY(co4, face->v3->co); + } + else + { + VECCOPY(co3, face->v3->co); + } + + t00= co3[0]-co1[0]; + t01= co3[1]-co1[1]; + t02= co3[2]-co1[2]; + t10= co3[0]-co2[0]; + t11= co3[1]-co2[1]; + t12= co3[2]-co2[2]; + + x0= t11*r2-t12*r1; + x1= t12*r0-t10*r2; + x2= t10*r1-t11*r0; + + divdet= t00*x0+t01*x1+t02*x2; + + m0= rx1-co3[0]; + m1= ry1-co3[1]; + m2= rz1-co3[2]; + det1= m0*x0+m1*x1+m2*x2; + + if(divdet!=0.0f) { + u1= det1/divdet; + + if(u1 -(1.0f+ISECT_EPSILON)) { + return 1; + } + } + } + + if(face->v4) { + + t20= co3[0]-co4[0]; + t21= co3[1]-co4[1]; + t22= co3[2]-co4[2]; + + divdet= t20*x0+t21*x1+t22*x2; + if(divdet!=0.0f) { + u2= det1/divdet; + + if(u2= -(1.0f+ISECT_EPSILON)) { + return 2; + } + } + } + } + return 0; +} + + /* ray - triangle or quad intersection */ +/* this function shall only modify Isect if it detects an hit */ static int intersect_rayface(RayFace *face, Isect *is) { float co1[3],co2[3],co3[3],co4[3]; float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2; float m0, m1, m2, divdet, det1; + float labda, u, v; short ok=0; if(is->orig.ob == face->ob && is->orig.face == face->face) @@ -51,8 +133,6 @@ static int intersect_rayface(RayFace *face, Isect *is) VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); - - //TODO if(v4) { SWAP(float*, v3, v4); } if(face->v4) { VECCOPY(co3, face->v4); @@ -86,12 +166,11 @@ static int intersect_rayface(RayFace *face, Isect *is) det1= m0*x0+m1*x1+m2*x2; if(divdet!=0.0f) { - float u; divdet= 1.0f/divdet; u= det1*divdet; if(u-(1.0f+ISECT_EPSILON)) { - float v, cros0, cros1, cros2; + float cros0, cros1, cros2; cros0= m1*t02-m2*t01; cros1= m2*t00-m0*t02; @@ -99,12 +178,9 @@ static int intersect_rayface(RayFace *face, Isect *is) v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); if(v -(1.0f+ISECT_EPSILON)) { - float labda; labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { - is->labda= labda; - is->u= u; is->v= v; ok= 1; } } @@ -119,25 +195,21 @@ static int intersect_rayface(RayFace *face, Isect *is) divdet= t20*x0+t21*x1+t22*x2; if(divdet!=0.0f) { - float u; divdet= 1.0f/divdet; u = det1*divdet; if(u-(1.0f+ISECT_EPSILON)) { - float v, cros0, cros1, cros2; + float cros0, cros1, cros2; cros0= m1*t22-m2*t21; cros1= m2*t20-m0*t22; cros2= m0*t21-m1*t20; v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); if(v-(1.0f+ISECT_EPSILON)) { - float labda; labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { ok= 2; - is->labda= labda; - is->u= u; is->v= v; } } } @@ -145,58 +217,51 @@ static int intersect_rayface(RayFace *face, Isect *is) } if(ok) { - is->isect= ok; // wich half of the quad - -/* - TODO - if(is->mode!=RE_RAY_SHADOW) { - / * for mirror & tra-shadow: large faces can be filled in too often, this prevents - a face being detected too soon... * / - if(is->labda > is->ddalabda) { - return 0; - } - } -*/ - -#if 0 - TODO + /* when a shadow ray leaves a face, it can be little outside the edges of it, causing intersection to be detected in its neighbour face */ - if(is->facecontr && is->faceisect); // optimizing, the tests below are not needed - else if(is->labda< .1) { - RayFace *face= is->orig.face; - float *origv1, *origv2, *origv3, *origv4; - short de= 0; + if(is->skip & RE_SKIP_VLR_NEIGHBOUR) + { + if(labda < 0.1f && is->orig.ob == face->ob) + { + VlakRen * a = is->orig.face; + VlakRen * b = face->face; - coordsfunc(face, &origv1, &origv2, &origv3, &origv4); - - if(ob == is->orig.ob) { - if(v1==origv1 || v2==origv1 || v3==origv1 || v4==origv1) de++; - if(v1==origv2 || v2==origv2 || v3==origv2 || v4==origv2) de++; - if(v1==origv3 || v2==origv3 || v3==origv3 || v4==origv3) de++; - if(origv4) { - if(v1==origv4 || v2==origv4 || v3==origv4 || v4==origv4) de++; - } - } - if(de) { /* so there's a shared edge or vertex, let's intersect ray with face itself, if that's true we can safely return 1, otherwise we assume the intersection is invalid, 0 */ - - if(is->facecontr==NULL) { - is->obcontr= is->orig.ob; - is->facecontr= face; - is->faceisect= intersection2(face, is->orig.ob, transformfunc, coordsfunc, is->userdata, - -r0, -r1, -r2, - is->start[0], is->start[1], is->start[2]); + if(a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1 + || a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2 + || a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3 + || a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || (a->v4 && a->v4==b->v4)) + if(!intersection2((VlakRen*)b, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) + { + return 0; } + } + } +#if 0 + else if(labda < ISECT_EPSILON) + { + /* too close to origin */ + return 0; + } +#endif - if(is->faceisect) return 1; +/* + TODO + if(is->mode!=RE_RAY_SHADOW) { + / * for mirror & tra-shadow: large faces can be filled in too often, this prevents + a face being detected too soon... * / + if(is->labda > is->ddalabda) { return 0; } } -#endif - +*/ + is->isect= ok; // wich half of the quad + is->labda= labda; + is->u= u; is->v= v; + is->hit.ob = face->ob; is->hit.face = face->face; return 1; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 83165bb6b52..2d617163e29 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -2055,6 +2055,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa VECCOPY(isec->start, shi->co); VECCOPY(isec->vec, vec); isec->labda = 1.0f; + isec->skip = RE_SKIP_VLR_NEIGHBOUR; if(isec->mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ -- cgit v1.2.3 From da0c45e7eb5a25ee8ed01a3bd38168045fa3dc04 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 13 May 2009 01:56:03 +0000 Subject: Renamed exported functions from render to have the RE_ prefix RayObject_* => RE_rayobject_* --- source/blender/editors/armature/meshlaplacian.c | 6 ++--- source/blender/render/extern/include/RE_raytrace.h | 12 ++++----- source/blender/render/intern/include/rayobject.h | 29 +++++++++++----------- source/blender/render/intern/source/rayobject.c | 18 +++++++------- .../blender/render/intern/source/rayobject_mesh.c | 8 ++++-- .../render/intern/source/rayobject_octree.c | 9 ++++--- source/blender/render/intern/source/rayshade.c | 26 +++++++++---------- source/blender/render/intern/source/rendercore.c | 2 +- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index c3ab60ffda6..d74c8dbd0e1 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -401,7 +401,7 @@ static void heat_ray_tree_create(LaplacianSystem *sys) MFace *mface; int a; - sys->heat.raytree = RayObject_mesh_create(me, me); + sys->heat.raytree = RE_rayobject_mesh_create(me, me); sys->heat.vface = MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces"); for(a=0, mface=me->mface; atotface; a++, mface++) { @@ -445,7 +445,7 @@ static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone) VecMulf(dir, 1e-5); VecAddf(isec.start, isec.start, dir); #endif - visible= !RayObject_raycast(sys->heat.raytree, &isec); + visible= !RE_rayobject_raycast(sys->heat.raytree, &isec); return visible; } @@ -709,7 +709,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, /* free */ if(vertsflipped) MEM_freeN(vertsflipped); - RayObject_free(sys->heat.raytree); + RE_rayobject_free(sys->heat.raytree); MEM_freeN(sys->heat.vface); MEM_freeN(sys->heat.mindist); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index b5ff3d9cae0..d661e355249 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -38,16 +38,16 @@ typedef struct Isect Isect; struct DerivedMesh; struct Mesh; -int RayObject_raycast(RayObject *r, Isect *i); -void RayObject_add (RayObject *r, RayObject *); -void RayObject_done(RayObject *r); -void RayObject_free(RayObject *r); +int RE_rayobject_raycast(RayObject *r, Isect *i); +void RE_rayobject_add (RayObject *r, RayObject *); +void RE_rayobject_done(RayObject *r); +void RE_rayobject_free(RayObject *r); /* RayObject constructors */ -RayObject* RayObject_octree_create(int ocres, int size); +RayObject* RE_rayobject_octree_create(int ocres, int size); //RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); -RayObject* RayObject_mesh_create(struct Mesh*, void *ob); +RayObject* RE_rayobject_mesh_create(struct Mesh*, void *ob); /* Ray Intersection */ struct Isect diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index a1b35ac0465..064341ae18b 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -84,19 +84,19 @@ struct RayObject }; -typedef int (*RayObject_raycast_callback)(RayObject *, Isect *); -typedef void (*RayObject_add_callback)(RayObject *, RayObject *); -typedef void (*RayObject_done_callback)(RayObject *); -typedef void (*RayObject_free_callback)(RayObject *); -typedef void (*RayObject_bb_callback)(RayObject *, float *min, float *max); +typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *); +typedef void (*RE_rayobject_add_callback)(RayObject *, RayObject *); +typedef void (*RE_rayobject_done_callback)(RayObject *); +typedef void (*RE_rayobject_free_callback)(RayObject *); +typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); typedef struct RayObjectAPI { - RayObject_raycast_callback raycast; - RayObject_add_callback add; - RayObject_done_callback done; - RayObject_free_callback free; - RayObject_bb_callback bb; + RE_rayobject_raycast_callback raycast; + RE_rayobject_add_callback add; + RE_rayobject_done_callback done; + RE_rayobject_free_callback free; + RE_rayobject_merge_bb_callback bb; } RayObjectAPI; @@ -104,18 +104,19 @@ typedef struct RayObjectAPI #define RayObject_align(o) ((RayObject*)(((int)o)&(~3))) #define RayObject_unalign(o) ((RayObject*)(((int)o)|1)) #define RayObject_isFace(o) ((((int)o)&3) == 0) +#define RayObject_isAligned(o) ((((int)o)&3) == 0) /* * Extend min/max coords so that the rayobject is inside them */ -void RayObject_merge_bb(RayObject *ob, float *min, float *max); +void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max); /* - * This function differs from RayObject_raycast - * RayObject_intersect does NOT perform last-hit optimization + * This function differs from RE_rayobject_raycast + * RE_rayobject_intersect does NOT perform last-hit optimization * So this is probably a function to call inside raytrace structures */ -int RayObject_intersect(RayObject *r, Isect *i); +int RE_rayobject_intersect(RayObject *r, Isect *i); #define ISECT_EPSILON ((float)FLT_EPSILON) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index c816bcb2333..9537a0e6424 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -26,7 +26,7 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#include "assert.h" +#include #include "BKE_utildefines.h" @@ -270,15 +270,15 @@ static int intersect_rayface(RayFace *face, Isect *is) return 0; } -int RayObject_raycast(RayObject *r, Isect *i) +int RE_rayobject_raycast(RayObject *r, Isect *i) { - if(i->mode==RE_RAY_SHADOW && i->last_hit && RayObject_intersect(i->last_hit, i)) + if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) return 1; - return RayObject_intersect(r, i); + return RE_rayobject_intersect(r, i); } -int RayObject_intersect(RayObject *r, Isect *i) +int RE_rayobject_intersect(RayObject *r, Isect *i) { assert(i->mode==RE_RAY_SHADOW); if(RayObject_isFace(r)) @@ -304,25 +304,25 @@ int RayObject_intersect(RayObject *r, Isect *i) } } -void RayObject_add(RayObject *r, RayObject *o) +void RE_rayobject_add(RayObject *r, RayObject *o) { r = RayObject_align( r ); return r->api->add( r, o ); } -void RayObject_done(RayObject *r) +void RE_rayobject_done(RayObject *r) { r = RayObject_align( r ); r->api->done( r ); } -void RayObject_free(RayObject *r) +void RE_rayobject_free(RayObject *r) { r = RayObject_align( r ); r->api->free( r ); } -void RayObject_merge_bb(RayObject *r, float *min, float *max) +void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) { if(RayObject_isFace(r)) { diff --git a/source/blender/render/intern/source/rayobject_mesh.c b/source/blender/render/intern/source/rayobject_mesh.c index 7b8bca38172..eee7231aef4 100644 --- a/source/blender/render/intern/source/rayobject_mesh.c +++ b/source/blender/render/intern/source/rayobject_mesh.c @@ -26,6 +26,8 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#include + #include "rayobject.h" #include "MEM_guardedalloc.h" @@ -66,7 +68,7 @@ static int RayObject_mesh_intersect(RayObject *o, Isect *isec) RayMesh *rm= (RayMesh*)o; int i, hit = 0; for(i = 0; inum_faces; i++) - if(RayObject_raycast( (RayObject*)rm->faces+i, isec )) + if(RE_rayobject_raycast( (RayObject*)rm->faces+i, isec )) { hit = 1; if(isec->mode == RE_RAY_SHADOW) @@ -99,13 +101,15 @@ static void RayObject_mesh_bb(RayObject *o, float *min, float *max) DO_MINMAX( rm->mesh->mvert[i].co, min, max); } -RayObject* RayObject_mesh_create(Mesh *mesh, void *ob) +RayObject* RE_rayobject_mesh_create(Mesh *mesh, void *ob) { RayMesh *rm= MEM_callocN(sizeof(RayMesh), "Octree"); int i; RayFace *face; MFace *mface; + assert( RayObject_isAligned(rm) ); /* RayObject API assumes real data to be 4-byte aligned */ + rm->rayobj.api = &mesh_api; rm->mesh = mesh; rm->faces = MEM_callocN(sizeof(RayFace)*mesh->totface, "octree rayobject nodes"); diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index a738898871b..f9d621b8920 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -447,9 +447,10 @@ static void RayObject_octree_free(RayObject *tree) } -RayObject *RayObject_octree_create(int ocres, int size) +RayObject *RE_rayobject_octree_create(int ocres, int size) { Octree *oc= MEM_callocN(sizeof(Octree), "Octree"); + assert( RayObject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */ oc->rayobj.api = &octree_api; @@ -600,7 +601,7 @@ static void RayObject_octree_done(RayObject *tree) /* Calculate Bounding Box */ for(c=0; cro_nodes_used; c++) - RayObject_merge_bb(oc->ro_nodes[c], oc->min, oc->max); + RE_rayobject_merge_bb(oc->ro_nodes[c], oc->min, oc->max); /* Alloc memory */ oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); @@ -667,7 +668,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RayObject_intersect(face,is) ) + if( RE_rayobject_intersect(face,is) ) return 1; } } @@ -693,7 +694,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RayObject_raycast(face,is) ) + if( RE_rayobject_raycast(face,is) ) if(isect.labdalabda) { *is= isect; found= 1; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 2d617163e29..7f9bdbc9f9d 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -109,7 +109,7 @@ static float *vlr_get_transform(void *userdata, int i) void freeraytree(Render *re) { if(re->raytree) { - RayObject_free(re->raytree); + RE_rayobject_free(re->raytree); re->raytree= NULL; MEM_freeN( re->rayfaces ); } @@ -144,7 +144,7 @@ void makeraytree(Render *re) } } - re->raytree = RayObject_octree_create( re->r.ocres, totface ); + re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); //Fill rayfaces re->rayfaces = (RayObject*)MEM_callocN(totface*sizeof(RayFace), "render faces"); @@ -187,14 +187,14 @@ void makeraytree(Render *re) cur_face->ob = (void*)obi; cur_face->face = vlr; - RayObject_add( re->raytree, (RayObject*) cur_face ); + RE_rayobject_add( re->raytree, (RayObject*) cur_face ); cur_face++; } } } } - RayObject_done( re->raytree ); + RE_rayobject_done( re->raytree ); //TODO vlr_face_coords, vlr_check_intersect, vlr_get_transform, re); re->i.infostr= NULL; @@ -434,7 +434,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo isec.orig.ob = obi; isec.orig.face = vlr; - if(RayObject_raycast(R.raytree, &isec)) { + if(RE_rayobject_raycast(R.raytree, &isec)) { float d= 1.0f; shi.mask= origshi->mask; @@ -1274,7 +1274,7 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag) assert(0); - if(RayObject_raycast(R.raytree, is)) { + if(RE_rayobject_raycast(R.raytree, is)) { float d= 1.0f; /* we got a face */ @@ -1354,7 +1354,7 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) VECCOPY(isec.vec, vec ); isec.labda = RE_RAYTRACE_MAXDIST; - if(RayObject_raycast(R.raytree, &isec)) { + if(RE_rayobject_raycast(R.raytree, &isec)) { float fac; /* Warning, This is not that nice, and possibly a bit slow for every ray, @@ -1611,7 +1611,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) prev = fac; - if(RayObject_raycast(R.raytree, &isec)) { + if(RE_rayobject_raycast(R.raytree, &isec)) { if (R.wrld.aomode & WO_AODIST) fac+= exp(-isec.labda*R.wrld.aodistfac); else fac+= 1.0f; } @@ -1743,7 +1743,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) isec.labda = maxdist; /* do the trace */ - if(RayObject_raycast(R.raytree, &isec)) { + if(RE_rayobject_raycast(R.raytree, &isec)) { if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac); else sh+= 1.0f; } @@ -1974,7 +1974,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * colsq[2] += isec->col[2]*isec->col[2]; } else { - if( RayObject_raycast(R.raytree, isec) ) fac+= 1.0f; + if( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f; } samples++; @@ -2068,7 +2068,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa shadfac[2] += isec->col[2]; shadfac[3] += isec->col[3]; } - else if( RayObject_raycast(R.raytree, isec) ) fac+= 1.0f; + else if( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f; div+= 1.0f; jitlamp+= 2; @@ -2148,7 +2148,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) else { assert(0); - if(RayObject_raycast(R.raytree, &isec)) shadfac[3]= 0.0f; + if(RE_rayobject_raycast(R.raytree, &isec)) shadfac[3]= 0.0f; } } else { @@ -2193,7 +2193,7 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float VECCOPY(isec.start, shi->co); VECCOPY(isec.end, lampco); - if(RayObject_raycast(R.raytree, &isec)) { + if(RE_rayobject_raycast(R.raytree, &isec)) { /* we got a face */ /* render co */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index fe1ab21a4a4..9fbb585fd02 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2268,7 +2268,7 @@ static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, f isect->dir[2] = dir[2]*sign; isect->labda = maxdist; - hit = RayObject_raycast(raytree, isect); + hit = RE_rayobject_raycast(raytree, isect); //TODO bake_check_intersect if(hit) { hitco[0] = isect->start[0] + isect->labda*isect->vec[0]; -- cgit v1.2.3 From 02ca0c6f7549b9405e2956598c100cfe09d95396 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 13 May 2009 02:01:04 +0000 Subject: I think this fix the black dots problem (ZanQdo machine is just faster than mine.. so he will test :) ) --- source/blender/render/intern/source/rayshade.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 7f9bdbc9f9d..55f54de8f15 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1890,7 +1890,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * VECCOPY(vec, lampco); - + isec->skip = RE_SKIP_VLR_NEIGHBOUR; while (samples < max_samples) { isec->orig.ob = shi->obi; -- cgit v1.2.3 From a5a2d8c871ac7eb104174467b5e8c074e267974d Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 26 May 2009 16:22:00 +0000 Subject: Start OBJ exporter conversion. Just copied export_obj.py to export_obj-2.5.py leaving old one for reference. Once conversion is done, the new one will replace it. --- release/scripts/export_obj-2.5.py | 791 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 791 insertions(+) create mode 100644 release/scripts/export_obj-2.5.py diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py new file mode 100644 index 00000000000..1eb34a62af0 --- /dev/null +++ b/release/scripts/export_obj-2.5.py @@ -0,0 +1,791 @@ +#!BPY + +""" +Name: 'Wavefront (.obj)...' +Blender: 248 +Group: 'Export' +Tooltip: 'Save a Wavefront OBJ File' +""" + +__author__ = "Campbell Barton, Jiri Hnidek" +__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] +__version__ = "1.2" + +__bpydoc__ = """\ +This script is an exporter to OBJ file format. + +Usage: + +Select the objects you wish to export and run this script from "File->Export" menu. +Selecting the default options from the popup box will be good in most cases. +All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) +will be exported as mesh data. +""" + + +# -------------------------------------------------------------------------- +# OBJ Export v1.1 by Campbell Barton (AKA Ideasman) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + +import bpy + +# import Blender +# from Blender import Mesh, Scene, Window, sys, Image, Draw +# import BPyMesh +# import BPyObject +# import BPySys +# import BPyMessages + +# Returns a tuple - path,extension. +# 'hello.obj' > ('hello', '.obj') +def splitExt(path): + dotidx = path.rfind('.') + if dotidx == -1: + return path, '' + else: + return path[:dotidx], path[dotidx:] + +def fixName(name): + if name == None: + return 'None' + else: + return name.replace(' ', '_') + +# A Dict of Materials +# (material.name, image.name):matname_imagename # matname_imagename has gaps removed. +MTL_DICT = {} + +def write_mtl(filename): + + world = Blender.World.GetCurrent() + if world: + worldAmb = world.getAmb() + else: + worldAmb = (0,0,0) # Default value + + file = open(filename, "w") + file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) + file.write('# Material Count: %i\n' % len(MTL_DICT)) + # Write material/image combinations we have used. + for key, (mtl_mat_name, mat, img) in MTL_DICT.iteritems(): + + # Get the Blender data for the material and the image. + # Having an image named None will make a bug, dont do it :) + + file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname + + if mat: + file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's + file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse + file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular + file.write('Ni %.6f\n' % mat.IOR) # Refraction index + file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) + + # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. + if mat.getMode() & Blender.Material.Modes['SHADELESS']: + file.write('illum 0\n') # ignore lighting + elif mat.getSpec() == 0: + file.write('illum 1\n') # no specular. + else: + file.write('illum 2\n') # light normaly + + else: + #write a dummy material here? + file.write('Ns 0\n') + file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Kd 0.8 0.8 0.8\n') + file.write('Ks 0.8 0.8 0.8\n') + file.write('d 1\n') # No alpha + file.write('illum 2\n') # light normaly + + # Write images! + if img: # We have an image on the face! + file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image + + elif mat: # No face image. if we havea material search for MTex image. + for mtex in mat.getTextures(): + if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: + try: + filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1] + file.write('map_Kd %s\n' % filename) # Diffuse mapping image + break + except: + # Texture has no image though its an image type, best ignore. + pass + + file.write('\n\n') + + file.close() + +def copy_file(source, dest): + file = open(source, 'rb') + data = file.read() + file.close() + + file = open(dest, 'wb') + file.write(data) + file.close() + + +def copy_images(dest_dir): + if dest_dir[-1] != sys.sep: + dest_dir += sys.sep + + # Get unique image names + uniqueImages = {} + for matname, mat, image in MTL_DICT.itervalues(): # Only use image name + # Get Texface images + if image: + uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default. + + # Get MTex images + if mat: + for mtex in mat.getTextures(): + if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: + image_tex = mtex.tex.image + if image_tex: + try: + uniqueImages[image_tex] = image_tex + except: + pass + + # Now copy images + copyCount = 0 + + for bImage in uniqueImages.itervalues(): + image_path = sys.expandpath(bImage.filename) + if sys.exists(image_path): + # Make a name for the target path. + dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] + if not sys.exists(dest_image_path): # Image isnt alredy there + print '\tCopying "%s" > "%s"' % (image_path, dest_image_path) + copy_file(image_path, dest_image_path) + copyCount+=1 + print '\tCopied %d images' % copyCount + +def write(filename, objects,\ +EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ +EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ +EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ +EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False): + ''' + Basic write function. The context and options must be alredy set + This can be accessed externaly + eg. + write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. + ''' + + def veckey3d(v): + return round(v.x, 6), round(v.y, 6), round(v.z, 6) + + def veckey2d(v): + return round(v.x, 6), round(v.y, 6) + + print 'OBJ Export path: "%s"' % filename + temp_mesh_name = '~tmp-mesh' + + time1 = sys.time() + scn = Scene.GetCurrent() + + file = open(filename, "w") + + # Write Header + file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) + file.write('# www.blender3d.org\n') + + # Tell the obj file what material file to use. + if EXPORT_MTL: + mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) + file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) + + # Get the container mesh. - used for applying modifiers and non mesh objects. + containerMesh = meshName = tempMesh = None + for meshName in Blender.NMesh.GetNames(): + if meshName.startswith(temp_mesh_name): + tempMesh = Mesh.Get(meshName) + if not tempMesh.users: + containerMesh = tempMesh + if not containerMesh: + containerMesh = Mesh.New(temp_mesh_name) + + if EXPORT_ROTX90: + mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x') + + del meshName + del tempMesh + + # Initialize totals, these are updated each object + totverts = totuvco = totno = 1 + + face_vert_index = 1 + + globalNormals = {} + + # Get all meshs + for ob_main in objects: + for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): + # Will work for non meshes now! :) + # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) + me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scn) + if not me: + continue + + if EXPORT_UV: + faceuv= me.faceUV + else: + faceuv = False + + # We have a valid mesh + if EXPORT_TRI and me.faces: + # Add a dummy object to it. + has_quads = False + for f in me.faces: + if len(f) == 4: + has_quads = True + break + + if has_quads: + oldmode = Mesh.Mode() + Mesh.Mode(Mesh.SelectModes['FACE']) + + me.sel = True + tempob = scn.objects.new(me) + me.quadToTriangle(0) # more=0 shortest length + oldmode = Mesh.Mode(oldmode) + scn.objects.unlink(tempob) + + Mesh.Mode(oldmode) + + # Make our own list so it can be sorted to reduce context switching + faces = [ f for f in me.faces ] + + if EXPORT_EDGES: + edges = me.edges + else: + edges = [] + + if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write + continue # dont bother with this mesh. + + if EXPORT_ROTX90: + me.transform(ob_mat*mat_xrot90) + else: + me.transform(ob_mat) + + # High Quality Normals + if EXPORT_NORMALS and faces: + if EXPORT_NORMALS_HQ: + BPyMesh.meshCalcNormals(me) + else: + # transforming normals is incorrect + # when the matrix is scaled, + # better to recalculate them + me.calcNormals() + + # # Crash Blender + #materials = me.getMaterials(1) # 1 == will return None in the list. + materials = me.materials + + materialNames = [] + materialItems = materials[:] + if materials: + for mat in materials: + if mat: # !=None + materialNames.append(mat.name) + else: + materialNames.append(None) + # Cant use LC because some materials are None. + # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. + + # Possible there null materials, will mess up indicies + # but at least it will export, wait until Blender gets fixed. + materialNames.extend((16-len(materialNames)) * [None]) + materialItems.extend((16-len(materialItems)) * [None]) + + # Sort by Material, then images + # so we dont over context switch in the obj file. + if EXPORT_KEEP_VERT_ORDER: + pass + elif faceuv: + try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) + except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) + elif len(materials) > 1: + try: faces.sort(key = lambda a: (a.mat, a.smooth)) + except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) + else: + # no materials + try: faces.sort(key = lambda a: a.smooth) + except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) + + # Set the default mat to no material and no image. + contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. + contextSmooth = None # Will either be true or false, set bad to force initialization switch. + + if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: + name1 = ob.name + name2 = ob.getData(1) + if name1 == name2: + obnamestring = fixName(name1) + else: + obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) + + if EXPORT_BLEN_OBS: + file.write('o %s\n' % obnamestring) # Write Object name + else: # if EXPORT_GROUP_BY_OB: + file.write('g %s\n' % obnamestring) + + + # Vert + for v in me.verts: + file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) + + # UV + if faceuv: + uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ + + uv_dict = {} # could use a set() here + for f_index, f in enumerate(faces): + + for uv_index, uv in enumerate(f.uv): + uvkey = veckey2d(uv) + try: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] + except: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) + file.write('vt %.6f %.6f\n' % tuple(uv)) + + uv_unique_count = len(uv_dict) + del uv, uvkey, uv_dict, f_index, uv_index + # Only need uv_unique_count and uv_face_mapping + + # NORMAL, Smooth/Non smoothed. + if EXPORT_NORMALS: + for f in faces: + if f.smooth: + for v in f: + noKey = veckey3d(v.no) + if not globalNormals.has_key( noKey ): + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + else: + # Hard, 1 normal from the face. + noKey = veckey3d(f.no) + if not globalNormals.has_key( noKey ): + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + + if not faceuv: + f_image = None + + for f_index, f in enumerate(faces): + f_v= f.v + f_smooth= f.smooth + f_mat = min(f.mat, len(materialNames)-1) + if faceuv: + f_image = f.image + f_uv= f.uv + + # MAKE KEY + if faceuv and f_image: # Object is always true. + key = materialNames[f_mat], f_image.name + else: + key = materialNames[f_mat], None # No image, use None instead. + + # CHECK FOR CONTEXT SWITCH + if key == contextMat: + pass # Context alredy switched, dont do anythoing + else: + if key[0] == None and key[1] == None: + # Write a null material, since we know the context has changed. + if EXPORT_GROUP_BY_MAT: + file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) + file.write('usemtl (null)\n') # mat, image + + else: + mat_data= MTL_DICT.get(key) + if not mat_data: + # First add to global dict so we can export to mtl + # Then write mtl + + # Make a new names from the mat and image name, + # converting any spaces to underscores with fixName. + + # If none image dont bother adding it to the name + if key[1] == None: + mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image + else: + mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image + + if EXPORT_GROUP_BY_MAT: + file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) + file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) + + contextMat = key + if f_smooth != contextSmooth: + if f_smooth: # on now off + file.write('s 1\n') + contextSmooth = f_smooth + else: # was off now on + file.write('s off\n') + contextSmooth = f_smooth + + file.write('f') + if faceuv: + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % (\ + v.index+totverts,\ + totuvco + uv_face_mapping[f_index][vi],\ + globalNormals[ veckey3d(v.no) ])) # vert, uv, normal + + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.no) ] + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % (\ + v.index+totverts,\ + totuvco + uv_face_mapping[f_index][vi],\ + no)) # vert, uv, normal + + else: # No Normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d' % (\ + v.index+totverts,\ + totuvco + uv_face_mapping[f_index][vi])) # vert, uv + + face_vert_index += len(f_v) + + else: # No UV's + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for v in f_v: + file.write( ' %d//%d' % (\ + v.index+totverts,\ + globalNormals[ veckey3d(v.no) ])) + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.no) ] + for v in f_v: + file.write( ' %d//%d' % (\ + v.index+totverts,\ + no)) + else: # No Normals + for v in f_v: + file.write( ' %d' % (\ + v.index+totverts)) + + file.write('\n') + + # Write edges. + if EXPORT_EDGES: + LOOSE= Mesh.EdgeFlags.LOOSE + for ed in edges: + if ed.flag & LOOSE: + file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) + + # Make the indicies global rather then per mesh + totverts += len(me.verts) + if faceuv: + totuvco += uv_unique_count + me.verts= None + file.close() + + + # Now we have all our materials, save them + if EXPORT_MTL: + write_mtl(mtlfilename) + if EXPORT_COPY_IMAGES: + dest_dir = filename + # Remove chars until we are just the path. + while dest_dir and dest_dir[-1] not in '\\/': + dest_dir = dest_dir[:-1] + if dest_dir: + copy_images(dest_dir) + else: + print '\tError: "%s" could not be used as a base for an image path.' % filename + + print "OBJ Export time: %.2f" % (sys.time() - time1) + + +# converted: 0% +def write_ui(filename): + + if not filename.lower().endswith('.obj'): + filename += '.obj' + + if not BPyMessages.Warning_SaveOver(filename): + return + + global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ + EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ + EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ + EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER + + EXPORT_APPLY_MODIFIERS = Draw.Create(0) + EXPORT_ROTX90 = Draw.Create(1) + EXPORT_TRI = Draw.Create(0) + EXPORT_EDGES = Draw.Create(1) + EXPORT_NORMALS = Draw.Create(0) + EXPORT_NORMALS_HQ = Draw.Create(0) + EXPORT_UV = Draw.Create(1) + EXPORT_MTL = Draw.Create(1) + EXPORT_SEL_ONLY = Draw.Create(1) + EXPORT_ALL_SCENES = Draw.Create(0) + EXPORT_ANIMATION = Draw.Create(0) + EXPORT_COPY_IMAGES = Draw.Create(0) + EXPORT_BLEN_OBS = Draw.Create(0) + EXPORT_GROUP_BY_OB = Draw.Create(0) + EXPORT_GROUP_BY_MAT = Draw.Create(0) + EXPORT_KEEP_VERT_ORDER = Draw.Create(1) + + # Old UI + ''' + # removed too many options are bad! + + # Get USER Options + pup_block = [\ + ('Context...'),\ + ('Selection Only', EXPORT_SEL_ONLY, 'Only export objects in visible selection. Else export whole scene.'),\ + ('All Scenes', EXPORT_ALL_SCENES, 'Each scene as a separate OBJ file.'),\ + ('Animation', EXPORT_ANIMATION, 'Each frame as a numbered OBJ file.'),\ + ('Object Prefs...'),\ + ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object. May break vert order for morph targets.'),\ + ('Rotate X90', EXPORT_ROTX90 , 'Rotate on export so Blenders UP is translated into OBJs UP'),\ + ('Keep Vert Order', EXPORT_KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ + ('Extra Data...'),\ + ('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\ + ('Normals', EXPORT_NORMALS, 'Export vertex normal data (Ignored on import).'),\ + ('High Quality Normals', EXPORT_NORMALS_HQ, 'Calculate high quality normals for rendering.'),\ + ('UVs', EXPORT_UV, 'Export texface UV coords.'),\ + ('Materials', EXPORT_MTL, 'Write a separate MTL file with the OBJ.'),\ + ('Copy Images', EXPORT_COPY_IMAGES, 'Copy image files to the export directory, never overwrite.'),\ + ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\ + ('Grouping...'),\ + ('Objects', EXPORT_BLEN_OBS, 'Export blender objects as "OBJ objects".'),\ + ('Object Groups', EXPORT_GROUP_BY_OB, 'Export blender objects as "OBJ Groups".'),\ + ('Material Groups', EXPORT_GROUP_BY_MAT, 'Group by materials.'),\ + ] + + if not Draw.PupBlock('Export...', pup_block): + return + ''' + + # BEGIN ALTERNATIVE UI ******************* + if True: + + EVENT_NONE = 0 + EVENT_EXIT = 1 + EVENT_REDRAW = 2 + EVENT_EXPORT = 3 + + GLOBALS = {} + GLOBALS['EVENT'] = EVENT_REDRAW + #GLOBALS['MOUSE'] = Window.GetMouseCoords() + GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] + + def obj_ui_set_event(e,v): + GLOBALS['EVENT'] = e + + def do_split(e,v): + global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER + if EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val: + EXPORT_KEEP_VERT_ORDER.val = 0 + else: + EXPORT_KEEP_VERT_ORDER.val = 1 + + def do_vertorder(e,v): + global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER + if EXPORT_KEEP_VERT_ORDER.val: + EXPORT_BLEN_OBS.val = EXPORT_GROUP_BY_OB.val = EXPORT_GROUP_BY_MAT.val = EXPORT_APPLY_MODIFIERS.val = 0 + else: + if not (EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val): + EXPORT_KEEP_VERT_ORDER.val = 1 + + def do_help(e,v): + url = __url__[0] + print 'Trying to open web browser with documentation at this address...' + print '\t' + url + + try: + import webbrowser + webbrowser.open(url) + except: + print '...could not open a browser window.' + + def obj_ui(): + ui_x, ui_y = GLOBALS['MOUSE'] + + # Center based on overall pup size + ui_x -= 165 + ui_y -= 110 + + global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ + EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ + EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ + EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER + + Draw.Label('Context...', ui_x+9, ui_y+209, 220, 20) + Draw.BeginAlign() + EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+189, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.') + EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+189, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.') + EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+189, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.') + Draw.EndAlign() + + + Draw.Label('Output Options...', ui_x+9, ui_y+159, 220, 20) + Draw.BeginAlign() + EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+140, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split) + EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+140, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP') + EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+140, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.') + Draw.EndAlign() + + + Draw.Label('Export...', ui_x+9, ui_y+109, 220, 20) + Draw.BeginAlign() + EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+90, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.') + EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+90, 70, 20, EXPORT_TRI.val, 'Triangulate quads.') + Draw.EndAlign() + Draw.BeginAlign() + EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+90, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.') + EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+90, 31, 20, EXPORT_UV.val, 'Export texface UV coords.') + Draw.EndAlign() + Draw.BeginAlign() + EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+90, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).') + EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+90, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.') + Draw.EndAlign() + + + Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20) + Draw.BeginAlign() + EXPORT_BLEN_OBS = Draw.Toggle('Objects', EVENT_REDRAW, ui_x+9, ui_y+39, 60, 20, EXPORT_BLEN_OBS.val, 'Export blender objects as "OBJ objects".', do_split) + EXPORT_GROUP_BY_OB = Draw.Toggle('Groups', EVENT_REDRAW, ui_x+69, ui_y+39, 60, 20, EXPORT_GROUP_BY_OB.val, 'Export blender objects as "OBJ Groups".', do_split) + EXPORT_GROUP_BY_MAT = Draw.Toggle('Material Groups', EVENT_REDRAW, ui_x+129, ui_y+39, 100, 20, EXPORT_GROUP_BY_MAT.val, 'Group by materials.', do_split) + Draw.EndAlign() + + EXPORT_KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+239, ui_y+39, 100, 20, EXPORT_KEEP_VERT_ORDER.val, 'Keep vert and face order, disables some other options. Use for morph targets.', do_vertorder) + + Draw.BeginAlign() + Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 20, 'Load the wiki page for this script', do_help) + Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 20, '', obj_ui_set_event) + Draw.PushButton('Export', EVENT_EXPORT, ui_x+229, ui_y+9, 110, 20, 'Export with these settings', obj_ui_set_event) + Draw.EndAlign() + + + # hack so the toggle buttons redraw. this is not nice at all + while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_EXPORT): + Draw.UIBlock(obj_ui, 0) + + if GLOBALS['EVENT'] != EVENT_EXPORT: + return + + # END ALTERNATIVE UI ********************* + + + if EXPORT_KEEP_VERT_ORDER.val: + EXPORT_BLEN_OBS.val = False + EXPORT_GROUP_BY_OB.val = False + EXPORT_GROUP_BY_MAT.val = False + EXPORT_APPLY_MODIFIERS.val = False + + Window.EditMode(0) + Window.WaitCursor(1) + + EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val + EXPORT_ROTX90 = EXPORT_ROTX90.val + EXPORT_TRI = EXPORT_TRI.val + EXPORT_EDGES = EXPORT_EDGES.val + EXPORT_NORMALS = EXPORT_NORMALS.val + EXPORT_NORMALS_HQ = EXPORT_NORMALS_HQ.val + EXPORT_UV = EXPORT_UV.val + EXPORT_MTL = EXPORT_MTL.val + EXPORT_SEL_ONLY = EXPORT_SEL_ONLY.val + EXPORT_ALL_SCENES = EXPORT_ALL_SCENES.val + EXPORT_ANIMATION = EXPORT_ANIMATION.val + EXPORT_COPY_IMAGES = EXPORT_COPY_IMAGES.val + EXPORT_BLEN_OBS = EXPORT_BLEN_OBS.val + EXPORT_GROUP_BY_OB = EXPORT_GROUP_BY_OB.val + EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val + EXPORT_KEEP_VERT_ORDER = EXPORT_KEEP_VERT_ORDER.val + + + + base_name, ext = splitExt(filename) + context_name = [base_name, '', '', ext] # basename, scene_name, framenumber, extension + + # Use the options to export the data using write() + # def write(filename, objects, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, EXPORT_APPLY_MODIFIERS=True): + orig_scene = Scene.GetCurrent() + if EXPORT_ALL_SCENES: + export_scenes = Scene.Get() + else: + export_scenes = [orig_scene] + + # Export all scenes. + for scn in export_scenes: + scn.makeCurrent() # If alredy current, this is not slow. + context = scn.getRenderingContext() + orig_frame = Blender.Get('curframe') + + if EXPORT_ALL_SCENES: # Add scene name into the context_name + context_name[1] = '_%s' % BPySys.cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. + + # Export an animation? + if EXPORT_ANIMATION: + scene_frames = xrange(context.startFrame(), context.endFrame()+1) # up to and including the end frame. + else: + scene_frames = [orig_frame] # Dont export an animation. + + # Loop through all frames in the scene and export. + for frame in scene_frames: + if EXPORT_ANIMATION: # Add frame to the filename. + context_name[2] = '_%.6d' % frame + + Blender.Set('curframe', frame) + if EXPORT_SEL_ONLY: + export_objects = scn.objects.context + else: + export_objects = scn.objects + + full_path= ''.join(context_name) + + # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. + # EXPORT THE FILE. + write(full_path, export_objects,\ + EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ + EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ + EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ + EXPORT_ROTX90, EXPORT_BLEN_OBS,\ + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER) + + Blender.Set('curframe', orig_frame) + + # Restore old active scene. + orig_scene.makeCurrent() + Window.WaitCursor(0) + + +if __name__ == '__main__': + Window.FileSelector(write_ui, 'Export Wavefront OBJ', sys.makename(ext='.obj')) -- cgit v1.2.3 From ab6ec6be7bc8bbd0f22d5b5d8e37527c13aef308 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 26 May 2009 17:08:10 +0000 Subject: In bpy, renamed "exec" operator method to "execu" for compatibility with py 2.x ("exec" is a keyword in py 2.x). --- source/blender/python/intern/bpy_operator_wrap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 43d62b3005f..ab4d5c6169d 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -232,7 +232,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event)); } else if (mode==PYOP_EXEC) { - item= PyObject_GetAttrString(py_class, "exec"); + item= PyObject_GetAttrString(py_class, "execu"); args = PyTuple_New(1); } else if (mode==PYOP_POLL) { @@ -328,7 +328,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) /* api callbacks, detailed checks dont on adding */ if (PyObject_HasAttrString(py_class, "invoke")) ot->invoke= PYTHON_OT_invoke; - if (PyObject_HasAttrString(py_class, "exec")) + if (PyObject_HasAttrString(py_class, "execu")) ot->exec= PYTHON_OT_exec; if (PyObject_HasAttrString(py_class, "poll")) ot->poll= PYTHON_OT_poll; @@ -391,7 +391,7 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) {PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK}, - {"exec", 'f', 1, BPY_CLASS_ATTR_OPTIONAL}, + {"execu", 'f', 1, BPY_CLASS_ATTR_OPTIONAL}, {"invoke", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {NULL, 0, 0, 0} -- cgit v1.2.3 From aab6dfd724131fe58e492cc0cbac81e76c59a0dd Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 29 May 2009 21:32:52 +0000 Subject: Fixed black dot bug! (it does work for the test case I had) But I still wonder about its correction because it looks the oposite of whats documented and of what was used before :S I also took a long time to find it because I tought blender was feeding the raytrace structure with quads and triangles but it looks the quads get triangulated before reaching makeraytree (on rayshade.c). --- source/blender/render/intern/source/rayobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 9537a0e6424..d7d02f07328 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -233,8 +233,8 @@ static int intersect_rayface(RayFace *face, Isect *is) if(a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1 || a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2 || a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3 - || a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || (a->v4 && a->v4==b->v4)) - if(!intersection2((VlakRen*)b, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) + || (b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4))) + if(intersection2((VlakRen*)b, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) { return 0; } -- cgit v1.2.3 From 92811f0f6733eda0d5b8565cc6f7a0bad3259ef8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 29 May 2009 22:55:06 +0000 Subject: Linked bvhkdop with raytrace api --- .../blender/render/intern/source/rayobject_bvh.c | 124 +++++++++++++++++++++ .../render/intern/source/rayobject_octree.c | 2 +- 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 source/blender/render/intern/source/rayobject_bvh.c diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c new file mode 100644 index 00000000000..972bbe81b73 --- /dev/null +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -0,0 +1,124 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include + +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_kdopbvh.h" +#include "BLI_arithb.h" +#include "RE_raytrace.h" +#include "render_types.h" +#include "rayobject.h" + +static int RayObject_bvh_intersect(RayObject *o, Isect *isec); +static void RayObject_bvh_add(RayObject *o, RayObject *ob); +static void RayObject_bvh_done(RayObject *o); +static void RayObject_bvh_free(RayObject *o); +static void RayObject_bvh_bb(RayObject *o, float *min, float *max); + +static RayObjectAPI bvh_api = +{ + RayObject_bvh_intersect, + RayObject_bvh_add, + RayObject_bvh_done, + RayObject_bvh_free, + RayObject_bvh_bb +}; + +typedef struct BVHObject +{ + RayObject rayobj; + BVHTree *bvh; + +} BVHObject; + + +RayObject *RE_rayobject_bvh_create(int size) +{ + BVHObject *obj= (BVHObject*)MEM_callocN(sizeof(BVHObject), "BVHObject"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bvh_api; + obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6); + + return RayObject_unalign((RayObject*) obj); +} + +static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +{ + Isect *isect = (Isect*)userdata; + RayObject *face = (RayObject*)index; + + if(RE_rayobject_intersect(face,isect)) + { + hit->index = index; +// hit.distance = TODO + } +} + +static int RayObject_bvh_intersect(RayObject *o, Isect *isec) +{ + BVHObject *obj = (BVHObject*)o; + float dir[3]; + VECCOPY( dir, isec->vec ); + Normalize( dir ); + + //BLI_bvhtree_ray_cast returns -1 on non hit (in case we dont give a Hit structure + return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, NULL, bvh_callback, isec) != -1; +} + +static void RayObject_bvh_add(RayObject *o, RayObject *ob) +{ + BVHObject *obj = (BVHObject*)o; + float min_max[6]; + INIT_MINMAX(min_max, min_max+3); + RE_rayobject_merge_bb(ob, min_max, min_max+3); + BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); +} + +static void RayObject_bvh_done(RayObject *o) +{ + BVHObject *obj = (BVHObject*)o; + BLI_bvhtree_balance(obj->bvh); +} + +static void RayObject_bvh_free(RayObject *o) +{ + BVHObject *obj = (BVHObject*)o; + + if(obj->bvh) + BLI_bvhtree_free(obj->bvh); + + MEM_freeN(obj); +} + +static void RayObject_bvh_bb(RayObject *o, float *min, float *max) +{ + assert(0); +} diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index f9d621b8920..dc4669fa084 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -694,7 +694,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RE_rayobject_raycast(face,is) ) + if( RE_rayobject_intersect(face,is) ) if(isect.labdalabda) { *is= isect; found= 1; -- cgit v1.2.3 From 4b5059094578021c6350529b98ee194501cc4188 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 31 May 2009 02:35:58 +0000 Subject: *Some debug *Some more integration with bli bvh (just testing stuff) --- source/blender/render/extern/include/RE_raytrace.h | 6 ++++- source/blender/render/intern/source/rayobject.c | 31 ++++++++++++---------- .../blender/render/intern/source/rayobject_bvh.c | 18 ++++++++----- source/blender/render/intern/source/rayshade.c | 9 +++++-- 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index d661e355249..07c1cc045fe 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -45,6 +45,7 @@ void RE_rayobject_free(RayObject *r); /* RayObject constructors */ RayObject* RE_rayobject_octree_create(int ocres, int size); +RayObject* RE_rayobject_bvh_create(int size); //RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); RayObject* RE_rayobject_mesh_create(struct Mesh*, void *ob); @@ -54,9 +55,12 @@ struct Isect { float start[3]; float vec[3]; + float labda; + + float dist; /* length of vec, configured by RE_rayobject_raycast */ /* float end[3]; - not used */ - float labda, u, v; + float u, v; struct { diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index d7d02f07328..be247d0d86b 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -27,8 +27,10 @@ * ***** END GPL LICENSE BLOCK ***** */ #include +#include #include "BKE_utildefines.h" +#include "BLI_arithb.h" #include "RE_raytrace.h" #include "render_types.h" @@ -264,6 +266,7 @@ static int intersect_rayface(RayFace *face, Isect *is) is->hit.ob = face->ob; is->hit.face = face->face; + is->last_hit = (RayObject*)face; return 1; } @@ -272,6 +275,19 @@ static int intersect_rayface(RayFace *face, Isect *is) int RE_rayobject_raycast(RayObject *r, Isect *i) { + static int casted_rays = 0; + + if(casted_rays++ % (1<<20) == 0) + printf("Casting %d rays\n", casted_rays); + + i->vec[0] *= i->labda; + i->vec[1] *= i->labda; + i->vec[2] *= i->labda; + i->labda = 1.0f; //RE_RAYTRACE_MAXDIST; //len; + i->dist = VecLength(i->vec); + + + assert(i->mode==RE_RAY_SHADOW); if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) return 1; @@ -280,27 +296,14 @@ int RE_rayobject_raycast(RayObject *r, Isect *i) int RE_rayobject_intersect(RayObject *r, Isect *i) { - assert(i->mode==RE_RAY_SHADOW); if(RayObject_isFace(r)) { return intersect_rayface( (RayFace*) r, i); } else { - //TODO should be done somewhere else -// float len = Normalize( i->vec ); - int hit; - i->vec[0] *= i->labda; - i->vec[1] *= i->labda; - i->vec[2] *= i->labda; - i->labda = 1.0f; //RE_RAYTRACE_MAXDIST; //len; - r = RayObject_align( r ); - - hit = r->api->raycast( r, i ); -// i->labda /= len; - - return hit; + return r->api->raycast( r, i ); } } diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 972bbe81b73..aa36bc44010 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -65,7 +65,7 @@ RayObject *RE_rayobject_bvh_create(int size) assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; - obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6); + obj->bvh = BLI_bvhtree_new(size, 0.0, 2, 6); return RayObject_unalign((RayObject*) obj); } @@ -78,19 +78,23 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr if(RE_rayobject_intersect(face,isect)) { hit->index = index; -// hit.distance = TODO + + if(isect->mode == RE_RAY_SHADOW) + hit->dist = 0; } } static int RayObject_bvh_intersect(RayObject *o, Isect *isec) { BVHObject *obj = (BVHObject*)o; - float dir[3]; - VECCOPY( dir, isec->vec ); - Normalize( dir ); +// float dir[3]; +// VECCOPY( dir, isec->vec ); +// Normalize( dir ); + BVHTreeRayHit hit; + hit.index = 0; + hit.dist = isec->labda*isec->dist; - //BLI_bvhtree_ray_cast returns -1 on non hit (in case we dont give a Hit structure - return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, NULL, bvh_callback, isec) != -1; + return BLI_bvhtree_ray_cast(obj->bvh, isec->start, isec->vec, 0.0, &hit, bvh_callback, isec) != 0; } static void RayObject_bvh_add(RayObject *o, RayObject *ob) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 55f54de8f15..9bc1d5e75ce 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -122,6 +122,7 @@ void makeraytree(Render *re) double lasttime= PIL_check_seconds_timer(); int v, totv = 0, totface = 0; RayFace *faces, *cur_face; + int tot_quads = 0; //TODO (for now octree only supports RayFaces so we need to create them) // @@ -144,7 +145,9 @@ void makeraytree(Render *re) } } - re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); + printf("RE_rayobject_*_create( %d )\n", totface); +// re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); + re->raytree = RE_rayobject_bvh_create( totface ); //Fill rayfaces re->rayfaces = (RayObject*)MEM_callocN(totface*sizeof(RayFace), "render faces"); @@ -182,7 +185,7 @@ void makeraytree(Render *re) cur_face->v1 = vlr->v1->co; cur_face->v2 = vlr->v2->co; cur_face->v3 = vlr->v3->co; - cur_face->v4 = vlr->v4 ? vlr->v4->co : NULL; + cur_face->v4 = vlr->v4 ? tot_quads++, vlr->v4->co : NULL; cur_face->ob = (void*)obi; cur_face->face = vlr; @@ -194,7 +197,9 @@ void makeraytree(Render *re) } } + printf("call RE_rayobject_done( %dtri, %dquads )\n", totface-tot_quads, tot_quads); RE_rayobject_done( re->raytree ); + printf("return RE_rayobject_done( )\n"); //TODO vlr_face_coords, vlr_check_intersect, vlr_get_transform, re); re->i.infostr= NULL; -- cgit v1.2.3 From 628b06e9c551036d2e4f03610ce52c1b7aa3254e Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 1 Jun 2009 19:44:22 +0000 Subject: Woohoo! Context is now passed to operator's exec. Thanks Brecht and Campbell! --- source/blender/python/intern/bpy_operator_wrap.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index ab4d5c6169d..215e42dd95d 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -189,6 +189,8 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyObject *args; PyObject *ret= NULL, *py_class_instance, *item= NULL; int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); + PointerRNA ptr_context; + PyObject *py_context; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -233,7 +235,11 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve } else if (mode==PYOP_EXEC) { item= PyObject_GetAttrString(py_class, "execu"); - args = PyTuple_New(1); + args = PyTuple_New(2); + + RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); + py_context = pyrna_struct_CreatePyObject(&ptr_context); + PyTuple_SET_ITEM(args, 1, py_context); } else if (mode==PYOP_POLL) { item= PyObject_GetAttrString(py_class, "poll"); @@ -391,7 +397,7 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) {PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK}, - {"execu", 'f', 1, BPY_CLASS_ATTR_OPTIONAL}, + {"execu", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {"invoke", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {NULL, 0, 0, 0} -- cgit v1.2.3 From c09cbacf975f429c7b3f535e5e0ae897499f2e15 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 2 Jun 2009 20:16:33 +0000 Subject: Continuing OBJ exporter conversion. - export is initiated by an operator, output filepath is hardcoded for now. - added code in bpy_interface.c to put 'scripts/bpymodules' in sys.path. - no UI atm, using default option values, don't know how to do it yet --- release/scripts/export_obj-2.5.py | 151 ++++++++++++++++++++++++--- source/blender/python/intern/bpy_interface.c | 56 +++++++++- 2 files changed, 189 insertions(+), 18 deletions(-) diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py index 1eb34a62af0..2effe7556bc 100644 --- a/release/scripts/export_obj-2.5.py +++ b/release/scripts/export_obj-2.5.py @@ -35,18 +35,19 @@ will be exported as mesh data. # # 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- import bpy +import BPySys # import Blender # from Blender import Mesh, Scene, Window, sys, Image, Draw @@ -56,7 +57,7 @@ import bpy # import BPyMessages # Returns a tuple - path,extension. -# 'hello.obj' > ('hello', '.obj') +# 'hello.obj' > ('hello', '.obj') def splitExt(path): dotidx = path.rfind('.') if dotidx == -1: @@ -95,7 +96,7 @@ def write_mtl(filename): if mat: file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's - file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour, file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular file.write('Ni %.6f\n' % mat.IOR) # Refraction index @@ -112,14 +113,14 @@ def write_mtl(filename): else: #write a dummy material here? file.write('Ns 0\n') - file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, file.write('Kd 0.8 0.8 0.8\n') file.write('Ks 0.8 0.8 0.8\n') file.write('d 1\n') # No alpha file.write('illum 2\n') # light normaly # Write images! - if img: # We have an image on the face! + if img: # We have an image on the face! file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image elif mat: # No face image. if we havea material search for MTex image. @@ -183,11 +184,12 @@ def copy_images(dest_dir): copyCount+=1 print '\tCopied %d images' % copyCount -def write(filename, objects,\ -EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ -EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ -EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ -EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False): +def write(filename, objects, + EXPORT_TRI=False, EXPORT_EDGES=False, + EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False, + EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, + EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True, + EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False): ''' Basic write function. The context and options must be alredy set This can be accessed externaly @@ -409,9 +411,9 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal # MAKE KEY if faceuv and f_image: # Object is always true. - key = materialNames[f_mat], f_image.name + key = materialNames[f_mat], f_image.name else: - key = materialNames[f_mat], None # No image, use None instead. + key = materialNames[f_mat], None # No image, use None instead. # CHECK FOR CONTEXT SWITCH if key == contextMat: @@ -528,7 +530,7 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=Fal print "OBJ Export time: %.2f" % (sys.time() - time1) -# converted: 0% +# replaced by do_export def write_ui(filename): if not filename.lower().endswith('.obj'): @@ -787,5 +789,122 @@ def write_ui(filename): Window.WaitCursor(0) -if __name__ == '__main__': - Window.FileSelector(write_ui, 'Export Wavefront OBJ', sys.makename(ext='.obj')) +def do_export(filename, context): +# Window.EditMode(0) +# Window.WaitCursor(1) + + EXPORT_APPLY_MODIFIERS = True + EXPORT_ROTX90 = True + EXPORT_TRI = False + EXPORT_EDGES = False + EXPORT_NORMALS = False + EXPORT_NORMALS_HQ = False + EXPORT_UV = True + EXPORT_MTL = True + EXPORT_SEL_ONLY = True + EXPORT_ALL_SCENES = False # XXX not working atm + EXPORT_ANIMATION = False + EXPORT_COPY_IMAGES = False + EXPORT_BLEN_OBS = True + EXPORT_GROUP_BY_OB = False + EXPORT_GROUP_BY_MAT = False + EXPORT_KEEP_VERT_ORDER = False + + base_name, ext = splitExt(filename) + context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension + + orig_scene = context.scene + +# if EXPORT_ALL_SCENES: +# export_scenes = bpy.data.scenes +# else: +# export_scenes = [orig_scene] + + # XXX only exporting one scene atm since changing + # current scene is not possible. + # Brecht says that ideally in 2.5 we won't need such a function, + # allowing multiple scenes open at once. + export_scenes = [orig_scene] + + # Export all scenes. + for scn in export_scenes: +# scn.makeCurrent() # If already current, this is not slow. +# context = scn.getRenderingContext() + orig_frame = scn.current_frame + + if EXPORT_ALL_SCENES: # Add scene name into the context_name + context_name[1] = '_%s' % BPySys.cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. + + # Export an animation? + if EXPORT_ANIMATION: + scene_frames = xrange(scn.start_frame, context.end_frame+1) # Up to and including the end frame. + else: + scene_frames = [orig_frame] # Dont export an animation. + + # Loop through all frames in the scene and export. + for frame in scene_frames: + if EXPORT_ANIMATION: # Add frame to the filename. + context_name[2] = '_%.6d' % frame + + scn.current_frame = frame + if EXPORT_SEL_ONLY: + export_objects = context.selected_objects + else: + export_objects = scn.objects + + full_path= ''.join(context_name) + + # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. + # EXPORT THE FILE. +# write(full_path, export_objects, +# EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, +# EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, +# EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, +# EXPORT_ROTX90, EXPORT_BLEN_OBS, +# EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER) + + scn.current_frame = orig_frame + + # Restore old active scene. +# orig_scene.makeCurrent() +# Window.WaitCursor(0) + + +class SCRIPT_OT_export_obj(bpy.types.Operator): + ''' + Operator documentatuon text, will be used for the operator tooltip and python docs. + ''' + __label__ = 'My Operator' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + __props__ = [ + # bpy.types.FloatProperty(attr="setting_1", name="Example 1", + # default=10.0, min=0, max=10, description="Add info here"), + # bpy.types.IntProperty(attr="setting_2", default=2), + # bpy.types.BoolProperty(attr="toggle", default=True) + ] + + def execu(self, context): + print("Selected: " + context.active_object.name) + + do_export("/tmp/test.obj", context) + + return 'FINISHED' + + def invoke(self, event): + print("Invoke") + return 'FINISHED' + + def poll(self, context): # Poll isnt working yet + print("Poll") + return True + +if (hasattr(bpy.ops, "SCRIPT_OT_export_obj")): + bpy.ops.remove(bpy.ops.SCRIPT_OT_export_obj) + +bpy.ops.add(SCRIPT_OT_export_obj) + +bpy.ops.SCRIPT_OT_export_obj() + +bpy.ops.remove(bpy.ops.SCRIPT_OT_export_obj) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 999f6d8e9cb..d6e3b0c3dd5 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -35,6 +35,8 @@ #include "BPY_extern.h" +static void bpy_init_syspath(); + void BPY_free_compiled_text( struct Text *text ) { if( text->compiled ) { @@ -126,14 +128,14 @@ void BPY_start_python( int argc, char **argv ) /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); - /* bpy.* and lets us import it */ bpy_init_modules(); + /* init sys.path */ + bpy_init_syspath(); py_tstate = PyGILState_GetThisThreadState(); PyEval_ReleaseThread(py_tstate); - } void BPY_end_python( void ) @@ -148,6 +150,56 @@ void BPY_end_python( void ) return; } +void syspath_append(char *dirname) +{ + PyObject *mod_sys= NULL, *dict= NULL, *path= NULL, *dir= NULL; + short ok=1; + + mod_sys = PyImport_ImportModule( "sys" ); /* new ref */ + + if (mod_sys) { + dict = PyModule_GetDict( mod_sys ); /* borrowed ref */ + path = PyDict_GetItemString( dict, "path" ); /* borrowed ref */ + if ( !PyList_Check( path ) ) { + ok = 0; + } + } else { + /* cant get the sys module */ + /* PyErr_Clear(); is called below */ + ok = 0; + } + + dir = PyString_FromString( dirname ); + + if (ok && PySequence_Contains(path, dir)==0) { /* Only add if we need to */ + if (PyList_Append( path, dir ) != 0) /* decref below */ + ok = 0; /* append failed */ + } + + if( (ok==0) || PyErr_Occurred( ) ) + fprintf(stderr, "Warning: could import or build sys.path\n" ); + + PyErr_Clear(); + Py_DECREF( dir ); + Py_XDECREF( mod_sys ); +} + +/* Adds bpymodules to sys.path */ +static void bpy_init_syspath() +{ + char *dir; + char mod_dir[FILE_MAX]; + + // make path to [home]/scripts/bpymodules + dir = BLI_gethome_folder("scripts"); + BLI_make_file_string("/", mod_dir, dir, "bpymodules"); + + if (BLI_exists(mod_dir)) { + syspath_append(mod_dir); + fprintf(stderr, "'%s' has been added to sys.path\n", mod_dir); + } +} + /* Can run a file or text block */ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text ) { -- cgit v1.2.3 From 2e8979643871ed66ba3accddc7ec61465b6052b7 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 3 Jun 2009 14:42:28 +0000 Subject: RayObject to support instances.. its not still plugged in the renderer, as so, it hasn't been tested yet --- source/blender/render/extern/include/RE_raytrace.h | 1 + .../render/intern/source/rayobject_instance.c | 139 +++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 source/blender/render/intern/source/rayobject_instance.c diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 07c1cc045fe..b0e26940ffc 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -46,6 +46,7 @@ void RE_rayobject_free(RayObject *r); /* RayObject constructors */ RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_bvh_create(int size); +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4]); //RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); RayObject* RE_rayobject_mesh_create(struct Mesh*, void *ob); diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c new file mode 100644 index 00000000000..ba675dcb1e7 --- /dev/null +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -0,0 +1,139 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include + +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "RE_raytrace.h" +#include "rayobject.h" + +static int RayObject_instance_intersect(RayObject *o, Isect *isec); +static void RayObject_instance_free(RayObject *o); +static void RayObject_instance_bb(RayObject *o, float *min, float *max); + +static RayObjectAPI instance_api = +{ + RayObject_instance_intersect, + NULL, //static void RayObject_instance_add(RayObject *o, RayObject *ob); + NULL, //static void RayObject_instance_done(RayObject *o); + RayObject_instance_free, + RayObject_instance_bb +}; + +typedef struct InstanceRayObject +{ + RayObject rayobj; + RayObject *target; + float global2target[4][4]; + float target2global[4][4]; + +} InstanceRayObject; + + +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4]) +{ + InstanceRayObject *obj= (InstanceRayObject*)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &instance_api; + obj->target = target; + + Mat4CpyMat4(obj->global2target, transform); + Mat4Invert(obj->target2global, obj->global2target); + + return RayObject_unalign((RayObject*) obj); +} + +static int RayObject_instance_intersect(RayObject *o, Isect *isec) +{ + //TODO + // *there is probably a faster way to convert between coordinates + + InstanceRayObject *obj = (InstanceRayObject*)o; + int res; + float start[3], vec[3], labda_point[3], labda; + + + VECCOPY( start, isec->start ); + VECCOPY( vec , isec->vec ); + labda = isec->labda; + VECADDFAC( labda_point, start, vec, labda ); + + + //Transform to target coordinates system + VECADD( isec->vec, isec->vec, isec->start ); + VecMat4MulVecfl(isec->start, obj->target2global, isec->start); + VecMat4MulVecfl(isec->vec , obj->target2global, isec->vec); + VecMat4MulVecfl(labda_point, obj->target2global, labda_point); + isec->labda = VecLenf( isec->start, labda_point ); + VECSUB( isec->vec, isec->vec, isec->start ); + + //Raycast + res = RE_rayobject_intersect(obj->target, isec); + + //Restore coordinate space coords + if(res == 0) + isec->labda = labda; + else + { + VECADDFAC( labda_point, isec->start, isec->vec, isec->labda ); + VecMat4MulVecfl(labda_point, obj->global2target, labda_point); + isec->labda = VecLenf( start, labda_point ); + + } + VECCOPY( isec->start, start ); + VECCOPY( isec->vec, vec ); + + return res; +} + +static void RayObject_instance_free(RayObject *o) +{ + InstanceRayObject *obj = (InstanceRayObject*)o; + MEM_freeN(obj); +} + +static void RayObject_instance_bb(RayObject *o, float *min, float *max) +{ + //TODO: + // *better bb.. calculated witouth rotations of bb + // *maybe cache that better fitted BB at the InstanceRayObject + InstanceRayObject *obj = (InstanceRayObject*)o; + + float m[3], M[3]; + INIT_MINMAX(m, M); + RE_rayobject_merge_bb(obj->target, m, M); + + VecMat4MulVecfl(m, obj->target2global, m); + VecMat4MulVecfl(M, obj->target2global, M); + + DO_MINMAX(m, min, max); + DO_MINMAX(M, min, max); +} -- cgit v1.2.3 From 2fad9229242d3af5f7c2ff8c385c41b353ffd017 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 3 Jun 2009 23:56:04 +0000 Subject: *enabled mirror rays again *octree is fine *bvh tree gives bad results --- source/blender/render/intern/source/rayobject.c | 22 +++------ .../render/intern/source/rayobject_octree.c | 52 +++++----------------- source/blender/render/intern/source/rayshade.c | 6 +-- 3 files changed, 19 insertions(+), 61 deletions(-) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index be247d0d86b..ecc74f9c11c 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -250,16 +250,9 @@ static int intersect_rayface(RayFace *face, Isect *is) } #endif -/* - TODO - if(is->mode!=RE_RAY_SHADOW) { - / * for mirror & tra-shadow: large faces can be filled in too often, this prevents - a face being detected too soon... * / - if(is->labda > is->ddalabda) { - return 0; - } - } -*/ + if(is->mode!=RE_RAY_SHADOW && labda > is->labda) + return 0; + is->isect= ok; // wich half of the quad is->labda= labda; is->u= u; is->v= v; @@ -280,14 +273,13 @@ int RE_rayobject_raycast(RayObject *r, Isect *i) if(casted_rays++ % (1<<20) == 0) printf("Casting %d rays\n", casted_rays); - i->vec[0] *= i->labda; +/* i->vec[0] *= i->labda; i->vec[1] *= i->labda; i->vec[2] *= i->labda; - i->labda = 1.0f; //RE_RAYTRACE_MAXDIST; //len; - i->dist = VecLength(i->vec); + i->labda = 1.0f; +*/ +// i->dist = VecLength(i->vec); - - assert(i->mode==RE_RAY_SHADOW); if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) return 1; diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index dc4669fa084..018c7735284 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -664,7 +664,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) RayObject *face = no->v[nr]; OcVal *ov = no->ov+nr; - if(!face) break; //TODO? return 0; + if(!face) break; if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { @@ -675,30 +675,20 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) } else { /* else mirror or glass or shadowtra, return closest face */ - Isect isect; int found= 0; - assert(0); - - is->labda= 1.0f; /* needed? */ - isect= *is; /* copy for sorting */ - for(; no; no = no->next) for(nr=0; nr<8; nr++) { RayObject *face = no->v[nr]; OcVal *ov = no->ov+nr; - if(!face) return 0; + if(!face) break; if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RE_rayobject_intersect(face,is) ) - if(isect.labdalabda) { - *is= isect; - found= 1; - } + found= 1; } } @@ -848,22 +838,6 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) is->userdata= oc->userdata; #endif -#if 0 - /* only for shadow! */ - if(is->mode==RE_RAY_SHADOW) { - - /* TODO check with last intersected shadow face */ - if(is->last.face!=NULL && !(is->last.face==is->orig.face && is->last.ob==is->orig.ob)) { - if(checkfunc(is, is->last.ob, is->last.face)) { - is->ob= is->last.ob; - is->face= is->last.face; - VECSUB(is->vec, is->end, is->start); - if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) return 1; - } - } - } -#endif - VECADDFAC( end, is->start, is->vec, is->labda ); ldx= end[0] - is->start[0]; u1= 0.0f; @@ -880,6 +854,10 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) if(cliptest(ldz, oc->max[2]-is->start[2], &u1,&u2)) { c1=1; if(u2<1.0f) { + is->vec[0] = u2*ldx; + is->vec[1] = u2*ldy; + is->vec[2] = u2*ldz; + end[0]= is->start[0]+u2*ldx; end[1]= is->start[1]+u2*ldy; end[2]= is->start[2]+u2*ldz; @@ -917,16 +895,6 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) ocy2= (int)oy2; ocz2= (int)oz2; -// for(ocx1=0; ocx1ocres; ocx1++) -// for(ocy1=0; ocy1ocres; ocy1++) -// for(ocz1=0; ocz1ocres; ocz1++) -// { -// no= ocread(oc, ocx1, ocy1, ocz1); -// if( testnode(oc, is, no, ocval) ) return 1; -// } - -// return 0; - if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) { no= ocread(oc, ocx1, ocy1, ocz1); if(no) { @@ -934,7 +902,7 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1; vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2; calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); -// is->ddalabda= 1.0f; + is->labda = 1.0f; if( testnode(oc, is, no, ocval) ) return 1; } } @@ -1012,8 +980,8 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) vec2[1]= oy1-ddalabda*doy; vec2[2]= oz1-ddalabda*doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - -// is->ddalabda= ddalabda; + + is->labda= ddalabda; if( testnode(oc, is, no, ocval) ) return 1; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 9bc1d5e75ce..b0515e17424 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -146,8 +146,8 @@ void makeraytree(Render *re) } printf("RE_rayobject_*_create( %d )\n", totface); -// re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); - re->raytree = RE_rayobject_bvh_create( totface ); + re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); +// re->raytree = RE_rayobject_bvh_create( totface ); //Fill rayfaces re->rayfaces = (RayObject*)MEM_callocN(totface*sizeof(RayFace), "render faces"); @@ -424,8 +424,6 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo float ref[3]; float dist_mir = origshi->mat->dist_mir; - assert(0); - /* Warning, This is not that nice, and possibly a bit slow for every ray, however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */ memset(&shi, 0, sizeof(ShadeInput)); -- cgit v1.2.3 From 1dcab2c87560272112c39b48f28ef1d884ba563a Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 5 Jun 2009 14:44:54 +0000 Subject: Fixed reflections on bvh tree (its kinda of a hackish-fix.. must be improved later) --- source/blender/render/intern/source/rayobject.c | 6 ++-- .../blender/render/intern/source/rayobject_bvh.c | 37 +++++++++++++++------- source/blender/render/intern/source/rayshade.c | 5 +-- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index ecc74f9c11c..e622dd971ee 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -273,12 +273,12 @@ int RE_rayobject_raycast(RayObject *r, Isect *i) if(casted_rays++ % (1<<20) == 0) printf("Casting %d rays\n", casted_rays); -/* i->vec[0] *= i->labda; + i->labda = 10000.0; + i->vec[0] *= i->labda; i->vec[1] *= i->labda; i->vec[2] *= i->labda; i->labda = 1.0f; -*/ -// i->dist = VecLength(i->vec); + i->dist = VecLength(i->vec); if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) return 1; diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index aa36bc44010..232b221fbdb 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -55,6 +55,7 @@ typedef struct BVHObject { RayObject rayobj; BVHTree *bvh; + float bb[2][3]; } BVHObject; @@ -65,36 +66,42 @@ RayObject *RE_rayobject_bvh_create(int size) assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; - obj->bvh = BLI_bvhtree_new(size, 0.0, 2, 6); + obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 2, 6); + INIT_MINMAX(obj->bb[0], obj->bb[1]); return RayObject_unalign((RayObject*) obj); } static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - Isect *isect = (Isect*)userdata; + Isect *isec = (Isect*)userdata; RayObject *face = (RayObject*)index; - if(RE_rayobject_intersect(face,isect)) + if(RE_rayobject_intersect(face,isec)) { hit->index = index; - if(isect->mode == RE_RAY_SHADOW) + if(isec->mode == RE_RAY_SHADOW) hit->dist = 0; +// TODO +// else +// hit->dist = isec->labda; } } static int RayObject_bvh_intersect(RayObject *o, Isect *isec) { BVHObject *obj = (BVHObject*)o; -// float dir[3]; -// VECCOPY( dir, isec->vec ); -// Normalize( dir ); BVHTreeRayHit hit; + float dir[3]; + + VECCOPY(dir, isec->vec); + Normalize(dir); + hit.index = 0; - hit.dist = isec->labda*isec->dist; + hit.dist = FLT_MAX; //TODO isec->labda; - return BLI_bvhtree_ray_cast(obj->bvh, isec->start, isec->vec, 0.0, &hit, bvh_callback, isec) != 0; + return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, isec); } static void RayObject_bvh_add(RayObject *o, RayObject *ob) @@ -102,8 +109,12 @@ static void RayObject_bvh_add(RayObject *o, RayObject *ob) BVHObject *obj = (BVHObject*)o; float min_max[6]; INIT_MINMAX(min_max, min_max+3); - RE_rayobject_merge_bb(ob, min_max, min_max+3); - BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); + RE_rayobject_merge_bb(ob, min_max, min_max+3); + + DO_MINMAX(min_max , obj->bb[0], obj->bb[1]); + DO_MINMAX(min_max+3, obj->bb[0], obj->bb[1]); + + BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); } static void RayObject_bvh_done(RayObject *o) @@ -124,5 +135,7 @@ static void RayObject_bvh_free(RayObject *o) static void RayObject_bvh_bb(RayObject *o, float *min, float *max) { - assert(0); + BVHObject *obj = (BVHObject*)o; + DO_MINMAX( obj->bb[0], min, max ); + DO_MINMAX( obj->bb[1], min, max ); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index b0515e17424..2eb545f7364 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -146,8 +146,8 @@ void makeraytree(Render *re) } printf("RE_rayobject_*_create( %d )\n", totface); - re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); -// re->raytree = RE_rayobject_bvh_create( totface ); +// re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); + re->raytree = RE_rayobject_bvh_create( totface ); //Fill rayfaces re->rayfaces = (RayObject*)MEM_callocN(totface*sizeof(RayFace), "render faces"); @@ -433,6 +433,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo VECCOPY(isec.vec, vec ); isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; isec.mode= RE_RAY_MIRROR; + isec.skip = RE_SKIP_VLR_NEIGHBOUR; isec.orig.ob = obi; isec.orig.face = vlr; -- cgit v1.2.3 From 0474acc4cb21ca5603579d8b5d835b7467dc6e5e Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 6 Jun 2009 16:22:54 +0000 Subject: Small fix: use PyUnicode_FromString instead of PyString_FromString in Python 3.x builds. PyString_FromString no longer exists in Python 3.x. --- source/blender/python/intern/bpy_interface.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index d6e3b0c3dd5..147358776bc 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -168,8 +168,12 @@ void syspath_append(char *dirname) /* PyErr_Clear(); is called below */ ok = 0; } - + +#if PY_MAJOR_VERSION >= 3 + dir = PyUnicode_FromString( dirname ); +#else dir = PyString_FromString( dirname ); +#endif if (ok && PySequence_Contains(path, dir)==0) { /* Only add if we need to */ if (PyList_Append( path, dir ) != 0) /* decref below */ -- cgit v1.2.3 From cb82ef0d5288aed62fcab2271b4b15ef15a71aaf Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 6 Jun 2009 17:23:06 +0000 Subject: Renamed "execu" python operator method back to "exec" - switched to Python 3.0... --- source/blender/python/intern/bpy_operator_wrap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 215e42dd95d..9c530bd63e1 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -234,7 +234,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event)); } else if (mode==PYOP_EXEC) { - item= PyObject_GetAttrString(py_class, "execu"); + item= PyObject_GetAttrString(py_class, "exec"); args = PyTuple_New(2); RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); @@ -334,7 +334,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) /* api callbacks, detailed checks dont on adding */ if (PyObject_HasAttrString(py_class, "invoke")) ot->invoke= PYTHON_OT_invoke; - if (PyObject_HasAttrString(py_class, "execu")) + if (PyObject_HasAttrString(py_class, "exec")) ot->exec= PYTHON_OT_exec; if (PyObject_HasAttrString(py_class, "poll")) ot->poll= PYTHON_OT_poll; @@ -397,7 +397,7 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) {PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK}, - {"execu", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, + {"exec", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {"invoke", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {NULL, 0, 0, 0} -- cgit v1.2.3 From b429a65ed6f1d53e74bd6cc913a32092a1d191a9 Mon Sep 17 00:00:00 2001 From: Chingiz Dyussenov Date: Tue, 9 Jun 2009 14:53:19 +0000 Subject: Added two RNA struct functions - merely wrappers around the C api. - add_mesh to Main - calls C add_mesh and returns a new mesh - copy to Mesh - calls C copy_mesh and returns a new copy Not sure about function placement and naming though. Put both functions in editmesh.c, mesh editor module. Added prototypes to rna_internal.h. Prefixed both with "RNA_api_". Wanted to code Mesh.copy so that it copies Mesh data from another object instead of creating a new Mesh, but this needs CustomData manipulations which I should study later. Maybe we need a separate file for API functions? e.g. mesh_api.c? --- source/blender/editors/mesh/editmesh.c | 48 +++++++++++++++++++++++++++ source/blender/makesrna/intern/rna_internal.h | 2 ++ source/blender/makesrna/intern/rna_main.c | 9 +++++ source/blender/makesrna/intern/rna_mesh.c | 6 ++++ 4 files changed, 65 insertions(+) diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 40373c9f327..96348972f4f 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -2027,3 +2027,51 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc) vc->em= me->edit_mesh; } } + +/* Python API */ +Mesh *RNA_api_add_mesh(Main *main, char *name) +{ + return add_mesh(name); +} + +Mesh *RNA_api_mesh_copy(Mesh *me) +{ + return copy_mesh(me); +} + +/* +void RNA_api_mesh_copy_(Mesh *me, Object *ob, int apply_transform) +{ + if (ob->type != OB_MESH) { + return; + } + + Mesh *src= (Mesh*)ob->data; + + CustomData_free(&me->vdata, me->totvert); + CustomData_free(&me->edata, me->totedge); + CustomData_free(&me->fdata, me->totface); + + CustomData_copy(&src->vdata, &me->vdata, CD_MASK_MESH, CD_DUPLICATE, me->totvert); + CustomData_copy(&src->edata, &me->edata, CD_MASK_MESH, CD_DUPLICATE, me->totedge); + CustomData_copy(&src->fdata, &me->fdata, CD_MASK_MESH, CD_DUPLICATE, me->totface); + mesh_update_customdata_pointers(me); + + // ensure indirect linked data becomes lib-extern + for(i=0; ifdata.totlayer; i++) { + if(src->fdata.layers[i].type == CD_MTFACE) { + tface= (MTFace*)src->fdata.layers[i].data; + + for(a=0; atotface; a++, tface++) + if(tface->tpage) + id_lib_extern((ID*)tface->tpage); + } + } + + me->mselect= NULL; + me->bb= src->bb; + + //men->key= copy_key(me->key); + //if(men->key) men->key->from= (ID *)men; +} +*/ diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 9071efe71f7..ee08465f544 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -189,6 +189,8 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch /* API functions */ void RNA_api_ui_layout(struct StructRNA *srna); +struct Mesh *RNA_api_add_mesh(struct Main *main, char *name); +struct Mesh *RNA_api_mesh_copy(struct Mesh *me); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index fdd0349b25e..347aef69a76 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -218,6 +218,8 @@ void RNA_def_main(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; + const char *lists[][5]= { {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks."}, {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks."}, @@ -265,6 +267,13 @@ void RNA_def_main(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]); } + + func= RNA_def_function(srna, "add_mesh", "RNA_api_add_mesh"); + RNA_def_function_ui_description(func, "Add a new mesh."); + prop= RNA_def_string(func, "name", "", 0, "", "New name for the datablock."); + RNA_def_property_flag(prop, PROP_REQUIRED); + prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A new mesh."); + RNA_def_function_return(func, prop); } #endif diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 92e53cf7606..a15e36f947f 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1044,6 +1044,7 @@ static void rna_def_mesh(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; srna= RNA_def_struct(brna, "Mesh", "ID"); RNA_def_struct_ui_text(srna, "Mesh", "Mesh datablock to define geometric surfaces."); @@ -1126,6 +1127,11 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Shape Keys", ""); rna_def_texmat_common(srna, "rna_Mesh_texspace_editable"); + + func= RNA_def_function(srna, "copy", "RNA_api_mesh_copy"); + RNA_def_function_ui_description(func, "Create a copy of this mesh."); + prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A new mesh."); + RNA_def_function_return(func, prop); } void RNA_def_mesh(BlenderRNA *brna) -- cgit v1.2.3 From ad503a32d60459d627b74479064b0536e0a73ef2 Mon Sep 17 00:00:00 2001 From: Chingiz Dyussenov Date: Wed, 10 Jun 2009 09:56:22 +0000 Subject: - added copy_mesh_data C function which, unlike copy_mesh, copies data between two existing meshes. - API's Mesh.copy reflects copy_mesh_data. --- source/blender/editors/mesh/editmesh.c | 51 +++++++++++++++++++++++++-- source/blender/makesrna/intern/rna_internal.h | 2 +- source/blender/makesrna/intern/rna_mesh.c | 6 +++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 96348972f4f..a1b6bc56742 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -2029,15 +2029,62 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc) } /* Python API */ +void copy_mesh_data(Mesh *dest, Mesh *src); + Mesh *RNA_api_add_mesh(Main *main, char *name) { return add_mesh(name); } -Mesh *RNA_api_mesh_copy(Mesh *me) +void RNA_api_mesh_copy(Mesh *me, Mesh *from) +{ + copy_mesh_data(me, from); +} + +void RNA_api_mesh_copy_transformed() +{ +} + +/* + * This version of copy_mesh doesn't allocate a new mesh, + * instead it copies data between two existing meshes. + */ +void copy_mesh_data(Mesh *dest, Mesh *src) +{ + int totvert, totedge, totface; + int has_layer; + + CustomData_free(&dest->vdata, dest->totvert); + CustomData_free(&dest->edata, dest->totedge); + CustomData_free(&dest->fdata, dest->totface); + + memset(&dest->vdata, 0, sizeof(dest->vdata)); + memset(&dest->edata, 0, sizeof(dest->edata)); + memset(&dest->fdata, 0, sizeof(dest->fdata)); + + totvert = dest->totvert = src->totvert; + totedge = dest->totedge = src->totedge; + totface = dest->totface = src->totface; + + CustomData_copy(&src->vdata, &dest->vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); + CustomData_copy(&src->edata, &dest->edata, CD_MASK_MESH, CD_DUPLICATE, totedge); + CustomData_copy(&src->fdata, &dest->fdata, CD_MASK_MESH, CD_DUPLICATE, totface); + + CustomData_has_layer(&dest->vdata, CD_MVERT); + + CustomData_add_layer(&dest->vdata, CD_MVERT, CD_ASSIGN, src->mvert, totvert); + CustomData_add_layer(&dest->edata, CD_MEDGE, CD_ASSIGN, src->medge, totedge); + CustomData_add_layer(&dest->fdata, CD_MFACE, CD_ASSIGN, src->mface, totface); + + mesh_update_customdata_pointers(dest); +} + +/* +void RNA_api_mesh_apply_transform(Mesh *me) { - return copy_mesh(me); + } +*/ /* void RNA_api_mesh_copy_(Mesh *me, Object *ob, int apply_transform) diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index ee08465f544..d93c296ca93 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -190,7 +190,7 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch void RNA_api_ui_layout(struct StructRNA *srna); struct Mesh *RNA_api_add_mesh(struct Main *main, char *name); -struct Mesh *RNA_api_mesh_copy(struct Mesh *me); +void RNA_api_mesh_copy(struct Mesh *me, struct Mesh *from); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index a15e36f947f..b330bf277d1 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1129,9 +1129,13 @@ static void rna_def_mesh(BlenderRNA *brna) rna_def_texmat_common(srna, "rna_Mesh_texspace_editable"); func= RNA_def_function(srna, "copy", "RNA_api_mesh_copy"); - RNA_def_function_ui_description(func, "Create a copy of this mesh."); + RNA_def_function_ui_description(func, "Copy mesh data."); + prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from."); + RNA_def_property_flag(prop, PROP_REQUIRED); + /* prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A new mesh."); RNA_def_function_return(func, prop); + */ } void RNA_def_mesh(BlenderRNA *brna) -- cgit v1.2.3 From aaa17a285dc46adf354678bf14e9c7043a9f645a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 11 Jun 2009 11:46:12 +0000 Subject: Allow defining string property on py operator - a first step towards interfacing the file selector :) --- source/blender/editors/mesh/editmesh.c | 2 +- source/blender/makesrna/intern/rna_object.c | 6 ++++++ source/blender/python/intern/bpy_interface.c | 1 + source/blender/python/intern/bpy_rna.c | 28 ++++++++++++++++++++++++++++ source/blender/python/intern/bpy_rna.h | 1 + 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index a1b6bc56742..bce5c202366 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -2041,7 +2041,7 @@ void RNA_api_mesh_copy(Mesh *me, Mesh *from) copy_mesh_data(me, from); } -void RNA_api_mesh_copy_transformed() +void RNA_api_mesh_transform(Mesh *me, float **mat) { } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 08eca7b0528..86cf501295c 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -799,6 +799,12 @@ static StructRNA *rna_def_object(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Scale", "Lock editing of scale in the interface."); + /* + // error on compile + prop= RNA_def_float_matrix(srna, "mat", 16, NULL, 0.0f, 0.0f, "Matrix", "Transform matrix of the object.", 0.0f, 0.0f); + RNA_def_property_float_sdna(prop, NULL, "obmat"); + */ + /* collections */ prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Constraint"); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 49cc4d678e5..4903af475ed 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -102,6 +102,7 @@ static PyObject *CreateGlobalDictionary( bContext *C ) {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 12c19bd3471..3ef3c878826 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -38,6 +38,7 @@ #include "BKE_context.h" #include "BKE_global.h" /* evil G.* */ #include "BKE_report.h" +#include "BKE_utildefines.h" /* FILE_MAX */ static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b ) { @@ -1803,6 +1804,33 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) } } +PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + static char *kwlist[] = {"attr", "name", "description", "maxlen", "default", NULL}; + char *id, *name="", *description="", *def=""; + int maxlen=FILE_MAX; // XXX need greater? + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssis:StringProperty", kwlist, &id, &name, &description, &maxlen, &def)) + return NULL; + + if (PyTuple_Size(args) > 0) { + PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this. + return NULL; + } + + if (self) { + StructRNA *srna = PyCObject_AsVoidPtr(self); + RNA_def_string(srna, id, def, maxlen, name, description); + Py_RETURN_NONE; + } else { + PyObject *ret = PyTuple_New(2); + PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_StringProperty, NULL)); + PyTuple_SET_ITEM(ret, 1, kw); + Py_INCREF(kw); + return ret; + } +} + /*-------------------- Type Registration ------------------------*/ static int rna_function_arg_count(FunctionRNA *func) diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index a2a3015912b..7789e083a4e 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -76,6 +76,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw); PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw); PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw); +PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw); /* function for registering types */ PyObject *pyrna_basetype_register(PyObject *self, PyObject *args); -- cgit v1.2.3 From a892799db7a9019b592d742b1782c35fa53be01f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 11 Jun 2009 15:10:23 +0000 Subject: Pass context to the "invoke" operator method. "invoke" should have three args now: self, context and event respectively. --- source/blender/python/intern/bpy_operator_wrap.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 6ab990acdf5..a8f993f512b 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -190,7 +190,6 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyObject *ret= NULL, *py_class_instance, *item= NULL; int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); PointerRNA ptr_context; - PyObject *py_context; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -226,20 +225,23 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve RNA_property_collection_end(&iter); } - + + RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); if (mode==PYOP_INVOKE) { item= PyObject_GetAttrString(py_class, "invoke"); - args = PyTuple_New(2); - PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event)); + args = PyTuple_New(3); + + // PyTuple_SET_ITEM "steals" object reference, it is + // an object passed shouldn't be DECREF'ed + PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context)); + PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event)); } else if (mode==PYOP_EXEC) { item= PyObject_GetAttrString(py_class, "exec"); args = PyTuple_New(2); - RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); - py_context = pyrna_struct_CreatePyObject(&ptr_context); - PyTuple_SET_ITEM(args, 1, py_context); + PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context)); } else if (mode==PYOP_POLL) { item= PyObject_GetAttrString(py_class, "poll"); @@ -398,7 +400,7 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) {PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK}, {"exec", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, - {"invoke", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, + {"invoke", 'f', 3, BPY_CLASS_ATTR_OPTIONAL}, {"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {NULL, 0, 0, 0} }; -- cgit v1.2.3 From 49479ef91044965077cb0053623e51967dd662c6 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 11 Jun 2009 16:44:01 +0000 Subject: *Instance support at dupliverts/faces *Octree works nicely on hierarchic trees *the old code was quite destructive at the Isect variable changing isec->start, end, vec..now it only changes isec->labda (and hit results) Currently rendering a BVH of all objects, where each object has it own octree. --- source/blender/render/extern/include/RE_raytrace.h | 2 +- .../blender/render/intern/include/render_types.h | 13 +- source/blender/render/intern/source/rayobject.c | 13 +- .../blender/render/intern/source/rayobject_bvh.c | 9 +- .../render/intern/source/rayobject_instance.c | 72 +++-- .../render/intern/source/rayobject_octree.c | 62 +++-- source/blender/render/intern/source/rayshade.c | 304 ++++++++++++++------- .../blender/render/intern/source/renderdatabase.c | 17 ++ 8 files changed, 328 insertions(+), 164 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index b0e26940ffc..db3dc50c843 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -46,7 +46,7 @@ void RE_rayobject_free(RayObject *r); /* RayObject constructors */ RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_bvh_create(int size); -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4]); +RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); //RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); RayObject* RE_rayobject_mesh_create(struct Mesh*, void *ob); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 4846fe8d0e4..88bf30bd9ef 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -54,6 +54,7 @@ struct GHash; struct RenderBuckets; struct ObjectInstanceRen; struct RayObject; +struct RayFace; #define TABLEINITSIZE 1024 #define LAMPINITSIZE 256 @@ -170,7 +171,7 @@ struct Render /* octree tables and variables for raytrace */ struct RayObject *raytree; - struct RayObject *rayfaces; /* TODO Temporary */ + struct RayFace *rayfaces; /* occlusion tree */ void *occlusiontree; @@ -280,6 +281,12 @@ typedef struct ObjectRen { int actmtface, actmcol, bakemtface; float obmat[4][4]; /* only used in convertblender.c, for instancing */ + + /* used on makeraytree */ + struct RayObject *raytree; + struct RayFace *rayfaces; + struct ObjectInstanceRen *rayobi; + } ObjectRen; typedef struct ObjectInstanceRen { @@ -297,6 +304,10 @@ typedef struct ObjectInstanceRen { float *vectors; int totvector; + + /* used on makeraytree */ + struct RayObject *raytree; + } ObjectInstanceRen; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index e622dd971ee..5fc70deaee7 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -128,10 +128,6 @@ static int intersect_rayface(RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; - /* disabled until i got real & fast cylinder checking, this code doesnt work proper for faster strands */ - // if(is->mode==RE_RAY_SHADOW && is->vlr->flag & R_STRAND) - // return intersection_strand(is); - VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); @@ -182,7 +178,7 @@ static int intersect_rayface(RayFace *face, Isect *is) if(v -(1.0f+ISECT_EPSILON)) { labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); - if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { + if(labda>-ISECT_EPSILON && labdalabda) { ok= 1; } } @@ -210,7 +206,7 @@ static int intersect_rayface(RayFace *face, Isect *is) if(v-(1.0f+ISECT_EPSILON)) { labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); - if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) { + if(labda>-ISECT_EPSILON && labdalabda) { ok= 2; } } @@ -250,9 +246,6 @@ static int intersect_rayface(RayFace *face, Isect *is) } #endif - if(is->mode!=RE_RAY_SHADOW && labda > is->labda) - return 0; - is->isect= ok; // wich half of the quad is->labda= labda; is->u= u; is->v= v; @@ -274,10 +267,12 @@ int RE_rayobject_raycast(RayObject *r, Isect *i) printf("Casting %d rays\n", casted_rays); i->labda = 10000.0; +/* i->vec[0] *= i->labda; i->vec[1] *= i->labda; i->vec[2] *= i->labda; i->labda = 1.0f; +*/ i->dist = VecLength(i->vec); if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 232b221fbdb..c5e0cca808c 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -66,7 +66,7 @@ RayObject *RE_rayobject_bvh_create(int size) assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; - obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 2, 6); + obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 4, 6); INIT_MINMAX(obj->bb[0], obj->bb[1]); return RayObject_unalign((RayObject*) obj); @@ -83,9 +83,8 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr if(isec->mode == RE_RAY_SHADOW) hit->dist = 0; -// TODO -// else -// hit->dist = isec->labda; + else + hit->dist = isec->labda*isec->dist; } } @@ -99,7 +98,7 @@ static int RayObject_bvh_intersect(RayObject *o, Isect *isec) Normalize(dir); hit.index = 0; - hit.dist = FLT_MAX; //TODO isec->labda; + hit.dist = isec->labda*isec->dist; return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, isec); } diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c index ba675dcb1e7..a5024e97450 100644 --- a/source/blender/render/intern/source/rayobject_instance.c +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -51,22 +51,28 @@ typedef struct InstanceRayObject { RayObject rayobj; RayObject *target; + + void *ob; //Object represented by this instance + void *target_ob; //Object represented by the inner RayObject, needed to handle self-intersection + float global2target[4][4]; float target2global[4][4]; } InstanceRayObject; -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4]) +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob) { InstanceRayObject *obj= (InstanceRayObject*)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &instance_api; obj->target = target; + obj->ob = ob; + obj->target_ob = target_ob; - Mat4CpyMat4(obj->global2target, transform); - Mat4Invert(obj->target2global, obj->global2target); + Mat4CpyMat4(obj->target2global, transform); + Mat4Invert(obj->global2target, obj->target2global); return RayObject_unalign((RayObject*) obj); } @@ -78,39 +84,54 @@ static int RayObject_instance_intersect(RayObject *o, Isect *isec) InstanceRayObject *obj = (InstanceRayObject*)o; int res; - float start[3], vec[3], labda_point[3], labda; + float start[3], vec[3], labda, dist; + int changed = 0; + + //TODO - this is disabling self intersection on instances + if(isec->orig.ob == obj->ob && obj->ob) + { + changed = 1; + isec->orig.ob = obj->target_ob; + } VECCOPY( start, isec->start ); VECCOPY( vec , isec->vec ); labda = isec->labda; - VECADDFAC( labda_point, start, vec, labda ); - - + dist = isec->dist; + //Transform to target coordinates system VECADD( isec->vec, isec->vec, isec->start ); - VecMat4MulVecfl(isec->start, obj->target2global, isec->start); - VecMat4MulVecfl(isec->vec , obj->target2global, isec->vec); - VecMat4MulVecfl(labda_point, obj->target2global, labda_point); - isec->labda = VecLenf( isec->start, labda_point ); + + Mat4MulVecfl(obj->global2target, isec->start); + Mat4MulVecfl(obj->global2target, isec->vec ); + + isec->dist = VecLenf( isec->start, isec->vec ); VECSUB( isec->vec, isec->vec, isec->start ); + isec->labda *= isec->dist / dist; + //Raycast res = RE_rayobject_intersect(obj->target, isec); //Restore coordinate space coords if(res == 0) + { isec->labda = labda; + + } else { - VECADDFAC( labda_point, isec->start, isec->vec, isec->labda ); - VecMat4MulVecfl(labda_point, obj->global2target, labda_point); - isec->labda = VecLenf( start, labda_point ); - + isec->labda *= dist / isec->dist; + isec->hit.ob = obj->ob; } + isec->dist = dist; VECCOPY( isec->start, start ); - VECCOPY( isec->vec, vec ); + VECCOPY( isec->vec, vec ); + if(changed) + isec->orig.ob = obj->ob; + return res; } @@ -123,17 +144,20 @@ static void RayObject_instance_free(RayObject *o) static void RayObject_instance_bb(RayObject *o, float *min, float *max) { //TODO: - // *better bb.. calculated witouth rotations of bb - // *maybe cache that better fitted BB at the InstanceRayObject + // *better bb.. calculated without rotations of bb + // *maybe cache that better-fitted-BB at the InstanceRayObject InstanceRayObject *obj = (InstanceRayObject*)o; - float m[3], M[3]; + float m[3], M[3], t[3]; + int i, j; INIT_MINMAX(m, M); RE_rayobject_merge_bb(obj->target, m, M); - VecMat4MulVecfl(m, obj->target2global, m); - VecMat4MulVecfl(M, obj->target2global, M); - - DO_MINMAX(m, min, max); - DO_MINMAX(M, min, max); + //There must be a faster way than rotating all the 8 vertexs of the BB + for(i=0; i<8; i++) + { + for(j=0; j<3; j++) t[j] = i&(1<target2global, t); + DO_MINMAX(t, min, max); + } } diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index 018c7735284..b715695dc10 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -636,7 +636,9 @@ static void RayObject_octree_done(RayObject *tree) } MEM_freeN(oc->ocface); + oc->ocface = NULL; MEM_freeN(oc->ro_nodes); + oc->ro_nodes = NULL; printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx ); printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy ); @@ -820,9 +822,10 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) Octree *oc= (Octree*)tree; Node *no; OcVal ocval; - float vec1[3], vec2[3], end[3]; + float vec1[3], vec2[3], start[3], end[3]; float u1,u2,ox1,ox2,oy1,oy2,oz1,oz2; float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda; + float olabda = 0; int dx,dy,dz; int xo,yo,zo,c1=0; int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2; @@ -838,35 +841,33 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) is->userdata= oc->userdata; #endif + VECCOPY( start, is->start ); VECADDFAC( end, is->start, is->vec, is->labda ); - ldx= end[0] - is->start[0]; + ldx= is->vec[0]*is->labda; + olabda = is->labda; u1= 0.0f; u2= 1.0f; /* clip with octree cube */ - if(cliptest(-ldx, is->start[0]-oc->min[0], &u1,&u2)) { - if(cliptest(ldx, oc->max[0]-is->start[0], &u1,&u2)) { - ldy= end[1] - is->start[1]; - if(cliptest(-ldy, is->start[1]-oc->min[1], &u1,&u2)) { - if(cliptest(ldy, oc->max[1]-is->start[1], &u1,&u2)) { - ldz = end[2] - is->start[2]; - if(cliptest(-ldz, is->start[2]-oc->min[2], &u1,&u2)) { - if(cliptest(ldz, oc->max[2]-is->start[2], &u1,&u2)) { + if(cliptest(-ldx, start[0]-oc->min[0], &u1,&u2)) { + if(cliptest(ldx, oc->max[0]-start[0], &u1,&u2)) { + ldy= is->vec[1]*is->labda; + if(cliptest(-ldy, start[1]-oc->min[1], &u1,&u2)) { + if(cliptest(ldy, oc->max[1]-start[1], &u1,&u2)) { + ldz = is->vec[2]*is->labda; + if(cliptest(-ldz, start[2]-oc->min[2], &u1,&u2)) { + if(cliptest(ldz, oc->max[2]-start[2], &u1,&u2)) { c1=1; if(u2<1.0f) { - is->vec[0] = u2*ldx; - is->vec[1] = u2*ldy; - is->vec[2] = u2*ldz; - - end[0]= is->start[0]+u2*ldx; - end[1]= is->start[1]+u2*ldy; - end[2]= is->start[2]+u2*ldz; + end[0] = start[0]+u2*ldx; + end[1] = start[1]+u2*ldy; + end[2] = start[2]+u2*ldz; } + if(u1>0.0f) { - assert( 0 ); - is->start[0]+=u1*ldx; - is->start[1]+=u1*ldy; - is->start[2]+=u1*ldz; + start[0] += u1*ldx; + start[1] += u1*ldy; + start[2] += u1*ldz; } } } @@ -881,9 +882,9 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) //ocread(oc, oc->ocres, 0, 0); /* setup 3dda to traverse octree */ - ox1= (is->start[0]-oc->min[0])*oc->ocfacx; - oy1= (is->start[1]-oc->min[1])*oc->ocfacy; - oz1= (is->start[2]-oc->min[2])*oc->ocfacz; + ox1= (start[0]-oc->min[0])*oc->ocfacx; + oy1= (start[1]-oc->min[1])*oc->ocfacy; + oz1= (start[2]-oc->min[2])*oc->ocfacz; ox2= (end[0]-oc->min[0])*oc->ocfacx; oy2= (end[1]-oc->min[1])*oc->ocfacy; oz2= (end[2]-oc->min[2])*oc->ocfacz; @@ -902,11 +903,11 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1; vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2; calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); - is->labda = 1.0f; if( testnode(oc, is, no, ocval) ) return 1; } } else { + int found = 0; //static int coh_ocx1,coh_ocx2,coh_ocy1, coh_ocy2,coh_ocz1,coh_ocz2; float dox, doy, doz; int eqval; @@ -981,10 +982,15 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) vec2[2]= oz1-ddalabda*doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - is->labda= ddalabda; - if( testnode(oc, is, no, ocval) ) return 1; + //is->labda = (u1+ddalabda*(u2-u1))*olabda; + if( testnode(oc, is, no, ocval) ) + found = 1; + + if(is->labda < (u1+ddalabda*(u2-u1))*olabda) + return found; } + labdao= ddalabda; /* traversing ocree nodes need careful detection of smallest values, with proper @@ -1052,8 +1058,6 @@ static int RayObject_octree_intersect(RayObject *tree, Isect *is) } /* reached end, no intersections found */ - is->hit.ob = 0; - is->hit.face = NULL; return 0; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 2eb545f7364..707af95aaef 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -71,16 +71,6 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #if 0 -static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, float **v4) -{ - VlakRen *vlr= (VlakRen*)face; - - *v1 = (vlr->v1)? vlr->v1->co: NULL; - *v2 = (vlr->v2)? vlr->v2->co: NULL; - *v3 = (vlr->v3)? vlr->v3->co: NULL; - *v4 = (vlr->v4)? vlr->v4->co: NULL; -} - static int vlr_check_intersect(Isect *is, int ob, RayFace *face) { ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob); @@ -97,115 +87,239 @@ static int vlr_check_intersect(Isect *is, int ob, RayFace *face) else return (is->lay & obi->lay); } +#endif -static float *vlr_get_transform(void *userdata, int i) +void freeraytree(Render *re) { - ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)userdata, i); + ObjectInstanceRen *obi; + + if(re->raytree) + { + RE_rayobject_free(re->raytree); + re->raytree = NULL; + } + if(re->rayfaces) + { + MEM_freeN(re->rayfaces); + re->rayfaces = NULL; + } - return (obi->flag & R_TRANSFORMED)? (float*)obi->mat: NULL; + for(obi=re->instancetable.first; obi; obi=obi->next) + { + ObjectRen *obr = obi->obr; + if(obr->raytree) + { + RE_rayobject_free(obr->raytree); + obr->raytree = NULL; + } + if(obr->rayfaces) + { + MEM_freeN(obr->rayfaces); + obr->rayfaces = NULL; + } + if(obi->raytree) + { + RE_rayobject_free(obi->raytree); + obi->raytree = NULL; + } + } } -#endif -void freeraytree(Render *re) +static int is_raytraceable_vlr(Render *re, VlakRen *vlr) { - if(re->raytree) { - RE_rayobject_free(re->raytree); - re->raytree= NULL; - MEM_freeN( re->rayfaces ); + if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) + if((vlr->mat->mode & MA_WIRE)==0) + return 1; + return 0; +} + +static int is_raytraceable(Render *re, ObjectInstanceRen *obi) +{ + int v; + ObjectRen *obr = obi->obr; + + if(re->excludeob && obr->ob == re->excludeob) + return 0; + + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + if(is_raytraceable_vlr(re, vlr)) + return 1; } + return 0; } -void makeraytree(Render *re) + +RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) { - ObjectInstanceRen *obi; - ObjectRen *obr; - VlakRen *vlr= NULL; - double lasttime= PIL_check_seconds_timer(); - int v, totv = 0, totface = 0; - RayFace *faces, *cur_face; - int tot_quads = 0; - - //TODO (for now octree only supports RayFaces so we need to create them) - // - //count faces - for(obi=re->instancetable.first; obi; obi=obi->next) { - obr= obi->obr; - - if(re->excludeob && obr->ob == re->excludeob) - continue; - - for(v=0;vtotvlak;v++) { - if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak; - else vlr++; - /* baking selected to active needs non-traceable too */ - if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) { - if((vlr->mat->mode & MA_WIRE)==0) { - totface++; - } + //TODO + // out-of-memory safeproof + // break render + // update render stats + ObjectRen *obr = obi->obr; + + if(obr->raytree == NULL) + { + RayObject *raytree; + RayFace *face; + int v; + + //Count faces + int faces = 0; + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + if(is_raytraceable_vlr(re, vlr)) + faces++; + } + assert( faces > 0 ); + + //Create Ray cast accelaration structure + + //TODO dynamic ocres + raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); +// raytree = obr->raytree = RE_rayobject_bvh_create( faces ); + face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); + obr->rayobi = obi; + + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + if(is_raytraceable_vlr(re, vlr)) + { + face->v1 = vlr->v1->co; + face->v2 = vlr->v2->co; + face->v3 = vlr->v3->co; + face->v4 = vlr->v4 ? vlr->v4->co : NULL; + + face->ob = obi; + face->face = vlr; + + RE_rayobject_add( raytree, (RayObject*)face++ ); } } + RE_rayobject_done( raytree ); + } + + + if(obi->flag & R_TRANSFORMED) + { + obi->raytree = RE_rayobject_instance_create( obr->raytree, obi->mat, obi, obi->obr->rayobi ); } - printf("RE_rayobject_*_create( %d )\n", totface); -// re->raytree = RE_rayobject_octree_create( re->r.ocres, totface ); - re->raytree = RE_rayobject_bvh_create( totface ); - - //Fill rayfaces - re->rayfaces = (RayObject*)MEM_callocN(totface*sizeof(RayFace), "render faces"); - cur_face = faces = (RayFace*)re->rayfaces; - - for(obi=re->instancetable.first; obi; obi=obi->next) { - obr= obi->obr; + if(obi->raytree) return obi->raytree; + return obi->obr->raytree; +} - if(re->excludeob && obr->ob == re->excludeob) - continue; +/* + * create an hierarchic raytrace structure with all objects + * + * R_TRANSFORMED objects instances reuse the same tree by using the rayobject_instance + */ +static void makeraytree_hier(Render *re) +{ + //TODO + // out-of-memory safeproof + // break render + // update render stats - for(v=0;vtotvlak;v++) { - if((v & 255)==0) - { - double time= PIL_check_seconds_timer(); + ObjectInstanceRen *obi; + int num_objects = 0; - vlr= obr->vlaknodes[v>>8].vlak; + re->i.infostr="Creating raytrace structure"; + re->stats_draw(re->sdh, &re->i); - vlr= obr->vlaknodes[v>>8].vlak; - if(re->test_break(re->tbh)) - break; - if(time-lasttime>1.0f) { - char str[32]; - sprintf(str, "Filling Octree: %d", totv); - re->i.infostr= str; - re->stats_draw(re->sdh, &re->i); - re->i.infostr= NULL; - lasttime= time; - } - } - else vlr++; - /* baking selected to active needs non-traceable too */ - if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE)) { - if((vlr->mat->mode & MA_WIRE)==0) { - cur_face->v1 = vlr->v1->co; - cur_face->v2 = vlr->v2->co; - cur_face->v3 = vlr->v3->co; - cur_face->v4 = vlr->v4 ? tot_quads++, vlr->v4->co : NULL; - - cur_face->ob = (void*)obi; - cur_face->face = vlr; - - RE_rayobject_add( re->raytree, (RayObject*) cur_face ); - cur_face++; - } - } - } + //Count number of objects + for(obi=re->instancetable.first; obi; obi=obi->next) + if(is_raytraceable(re, obi)) + num_objects++; + + //Create raytree + re->raytree = RE_rayobject_bvh_create( num_objects ); + + for(obi=re->instancetable.first; obi; obi=obi->next) + if(is_raytraceable(re, obi)) + { + RayObject *obj = makeraytree_object(re, obi); + RE_rayobject_add( re->raytree, obj ); + + if(re->test_break(re->tbh)) + break; } - printf("call RE_rayobject_done( %dtri, %dquads )\n", totface-tot_quads, tot_quads); - RE_rayobject_done( re->raytree ); - printf("return RE_rayobject_done( )\n"); -//TODO vlr_face_coords, vlr_check_intersect, vlr_get_transform, re); + if(!re->test_break(re->tbh)) + { + RE_rayobject_done( re->raytree ); + } re->i.infostr= NULL; re->stats_draw(re->sdh, &re->i); } +/* + * create a single raytrace structure with all faces + */ +static void makeraytree_single(Render *re) +{ + ObjectInstanceRen *obi; + RayObject *raytree; + RayFace *face; + int faces = 0, obs = 0; + + for(obi=re->instancetable.first; obi; obi=obi->next) + if(is_raytraceable(re, obi)) + { + int v; + ObjectRen *obr = obi->obr; + obs++; + + assert((obi->flag & R_TRANSFORMED) == 0); //Not suported + + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + if(is_raytraceable_vlr(re, vlr)) + faces++; + } + } + + //Create raytree + raytree = re->raytree = RE_rayobject_octree_create(re->r.ocres, faces); + face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); + + for(obi=re->instancetable.first; obi; obi=obi->next) + if(is_raytraceable(re, obi)) + { + int v; + ObjectRen *obr = obi->obr; + + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + face->v1 = vlr->v1->co; + face->v2 = vlr->v2->co; + face->v3 = vlr->v3->co; + face->v4 = vlr->v4 ? vlr->v4->co : NULL; + + face->ob = obi; + face->face = vlr; + + RE_rayobject_add( raytree, (RayObject*)face++ ); + } + } + RE_rayobject_done( raytree ); +} + +void makeraytree(Render *re) +{ + if(1) + makeraytree_hier(re); + else + makeraytree_single(re); +} + + + static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) { ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 621831fb341..5f21a0e2e1a 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -75,6 +75,7 @@ #include "BKE_DerivedMesh.h" #include "RE_render_ext.h" /* externtex */ +#include "RE_raytrace.h" #include "renderpipeline.h" #include "render_types.h" @@ -872,13 +873,29 @@ void free_renderdata_tables(Render *re) MEM_freeN(obr->mtface); if(obr->mcol) MEM_freeN(obr->mcol); + + if(obr->rayfaces) + { + MEM_freeN(obr->rayfaces); + obr->rayfaces = NULL; + } + if(obr->raytree) + { + RE_rayobject_free(obr->raytree); + obr->raytree = NULL; + } } if(re->objectinstance) { for(obi=re->instancetable.first; obi; obi=obi->next) + { if(obi->vectors) MEM_freeN(obi->vectors); + if(obi->raytree) + RE_rayobject_free(obi->raytree); + } + MEM_freeN(re->objectinstance); re->objectinstance= NULL; re->totinstance= 0; -- cgit v1.2.3 From 6563e9ff8a6acd7f63038d8a9bbe727d312a2b29 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 11 Jun 2009 18:15:04 +0000 Subject: Started operator registration with python. This is a piece of cake! Made space_script header area customizable with python - need Brecht to check this. Added a base for operator registration: a menu in Scripts Window with two items "Reload Scripts" and "Export". The former will do guess what? The latter will be populated with submenu items each corresponding to an exporter :) --- release/ui/space_script.py | 73 ++++++++++++++++++++++ source/blender/editors/space_script/space_script.c | 31 ++++----- 2 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 release/ui/space_script.py diff --git a/release/ui/space_script.py b/release/ui/space_script.py new file mode 100644 index 00000000000..ea6f4be311c --- /dev/null +++ b/release/ui/space_script.py @@ -0,0 +1,73 @@ +import bpy + +class SCRIPT_HT_header(bpy.types.Header): + __space_type__ = "SCRIPTS_WINDOW" + __idname__ = "SCRIPT_HT_header" + + def draw(self, context): + st = context.space_data + layout = self.layout + + layout.template_header(context) + + if context.area.show_menus: + row = layout.row(align=True) + row.itemM(context, "SCRIPT_MT_scripts") + + # draw menu item to reload scripts from + # release/io + # + # it should call operator or + # a func that will: + # for each .py file in the dir, + # import/reload module, in the module: + # find subclasses of bpy.types.Operator, + # for each subclass create menus under "Export" + # with (row.)itemO + # + # for interface api documentation, see + # see source/blender/editors/interface/interface_api.c + # + # hint: reloading ui scripts in scripts window is Shift+P + + +class SCRIPT_MT_scripts(bpy.types.Menu): + __space_type__ = "SCRIPTS_WINDOW" + __label__ = "Scripts" + + def draw(self, context): + layout = self.layout + layout.column() + layout.itemM(context, "SCRIPT_MT_export") + layout.itemO("SCRIPT_OT_reload_scripts") + +class SCRIPT_MT_export(bpy.types.Menu): + __space_type__ = "SCRIPTS_WINDOW" + __label__ = "Export" + + def draw(self, context): + pass + +class SCRIPT_OT_reload_scripts(bpy.types.Operator): + __label__ = 'Reload Scripts' + + def exec(self, context): + print("SCRIPT_OT_reload_scripts: exec") + return 'FINISHED' + + def invoke(self, context, event): + print("SCRIPT_OT_reload_scripts: invoke") + return self.exec(context) + + def poll(self, context): + pass + + +bpy.types.register(SCRIPT_HT_header) +bpy.types.register(SCRIPT_MT_scripts) +bpy.types.register(SCRIPT_MT_export) + +if (hasattr(bpy.ops, "SCRIPT_OT_reload_scripts")): + bpy.ops.remove(bpy.ops.SCRIPT_OT_reload_scripts) + +bpy.ops.add(SCRIPT_OT_reload_scripts) diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index 4c17ed16475..01f19b3a0ab 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -175,29 +175,32 @@ static void script_main_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void script_header_area_init(wmWindowManager *wm, ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + /* UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); */ + ED_region_header_init(ar); } static void script_header_area_draw(const bContext *C, ARegion *ar) { - float col[3]; + /* float col[3]; */ - /* clear */ - if(ED_screen_area_active(C)) - UI_GetThemeColor3fv(TH_HEADER, col); - else - UI_GetThemeColor3fv(TH_HEADERDESEL, col); + /* /\* clear *\/ */ + /* if(ED_screen_area_active(C)) */ + /* UI_GetThemeColor3fv(TH_HEADER, col); */ + /* else */ + /* UI_GetThemeColor3fv(TH_HEADERDESEL, col); */ - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); + /* glClearColor(col[0], col[1], col[2], 0.0); */ + /* glClear(GL_COLOR_BUFFER_BIT); */ - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); + /* /\* set view2d view matrix for scrolling (without scrollers) *\/ */ + /* UI_view2d_view_ortho(C, &ar->v2d); */ - script_header_buttons(C, ar); + /* script_header_buttons(C, ar); */ - /* restore view matrix? */ - UI_view2d_view_restore(C); + /* /\* restore view matrix? *\/ */ + /* UI_view2d_view_restore(C); */ + + ED_region_header(C, ar); } static void script_main_area_listener(ARegion *ar, wmNotifier *wmn) -- cgit v1.2.3 From d198480db81f7efea85ee67c9ecedff9aaf5e2f5 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 11 Jun 2009 18:25:29 +0000 Subject: *ray<->bb hit optimization... just to make it "slightly" faster :P Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] *for now it breaks shrinkwrap or other stuff that relies on sphere-raycast of BLI_kdopbvh. --- source/blender/blenlib/intern/BLI_kdopbvh.c | 39 +++++++++++++++++++++++++- source/blender/render/intern/source/rayshade.c | 7 +++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 0f8194362c9..51b51e5ecca 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -101,6 +101,8 @@ typedef struct BVHRayCastData BVHTreeRay ray; float ray_dot_axis[13]; + float idot_axis[13]; + int index[6]; BVHTreeRayHit hit; } BVHRayCastData; @@ -1404,6 +1406,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nea * raycast is done by performing a DFS on the BVHTree and saving the closest hit */ + //Determines the distance that the ray must travel to hit the bounding volume of the given node static float ray_nearest_hit(BVHRayCastData *data, BVHNode *node) { @@ -1443,13 +1446,40 @@ static float ray_nearest_hit(BVHRayCastData *data, BVHNode *node) return low; } +//Determines the distance that the ray must travel to hit the bounding volume of the given node +//Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe +//[http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] +// +//TODO this doens't has data->ray.radius in consideration +static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *node) +{ + const float *bv = node->bv; + float dist; + + float t1x = (bv[data->index[0]] - data->ray.origin[0]) * data->idot_axis[0]; + float t2x = (bv[data->index[1]] - data->ray.origin[0]) * data->idot_axis[0]; + float t1y = (bv[data->index[2]] - data->ray.origin[1]) * data->idot_axis[1]; + float t2y = (bv[data->index[3]] - data->ray.origin[1]) * data->idot_axis[1]; + float t1z = (bv[data->index[4]] - data->ray.origin[2]) * data->idot_axis[2]; + float t2z = (bv[data->index[5]] - data->ray.origin[2]) * data->idot_axis[2]; + + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return FLT_MAX; + if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return FLT_MAX; + if(t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist) return FLT_MAX; + + dist = t1x; + if (t1y > dist) dist = t1y; + if (t1z > dist) dist = t1z; + return dist; +} + static void dfs_raycast(BVHRayCastData *data, BVHNode *node) { int i; //ray-bv is really fast.. and simple tests revealed its worth to test it //before calling the ray-primitive functions - float dist = ray_nearest_hit(data, node); + float dist = fast_ray_nearest_hit(data, node); if(dist >= data->hit.dist) return; if(node->totnode == 0) @@ -1503,9 +1533,16 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float for(i=0; i<3; i++) { data.ray_dot_axis[i] = INPR( data.ray.direction, KDOP_AXES[i]); + data.idot_axis[i] = 1.0f / data.ray_dot_axis[i]; if(fabs(data.ray_dot_axis[i]) < FLT_EPSILON) + { data.ray_dot_axis[i] = 0.0; + } + data.index[2*i] = data.idot_axis[i] < 0.0 ? 1 : 0; + data.index[2*i+1] = 1 - data.index[2*i]; + data.index[2*i] += 2*i; + data.index[2*i+1] += 2*i; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 707af95aaef..8a5a0dbf06d 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -177,8 +177,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) //Create Ray cast accelaration structure //TODO dynamic ocres - raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); -// raytree = obr->raytree = RE_rayobject_bvh_create( faces ); +// raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); + raytree = obr->raytree = RE_rayobject_bvh_create( faces ); face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); obr->rayobi = obi; @@ -284,7 +284,8 @@ static void makeraytree_single(Render *re) } //Create raytree - raytree = re->raytree = RE_rayobject_octree_create(re->r.ocres, faces); +// raytree = re->raytree = RE_rayobject_octree_create(re->r.ocres, faces); + raytree = re->raytree = RE_rayobject_bvh_create(faces); face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); for(obi=re->instancetable.first; obi; obi=obi->next) -- cgit v1.2.3 From 23eecb1e6e1824b8f6b13448a7eb164e6c73bc0f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 12 Jun 2009 09:54:28 +0000 Subject: Import/export operator registration working. Written in python, it traverses scripts in .blender/io extracting and registering Operator subclasses, and binding to menu items under Scripts->Export in Scripts Window. release/io dir has to be copied to .blender manually for now. --- release/io/export_obj.py | 28 ++++++++++++++ release/ui/space_script.py | 96 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 19 deletions(-) create mode 100644 release/io/export_obj.py diff --git a/release/io/export_obj.py b/release/io/export_obj.py new file mode 100644 index 00000000000..37039bb11cb --- /dev/null +++ b/release/io/export_obj.py @@ -0,0 +1,28 @@ +import bpy + +class SCRIPT_OT_export_obj(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __label__ = 'Export OBJ' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + __props__ = [ +# FloatProperty(attr="setting_1", name="Example 1", default=10.0, min=0, max=10, description="Add info here"), +# StringProperty(attr="filename") + ] + + def debug(self, message): + print("{0}: {1}".format(self.__class__.__name__, message)) + + def exec(self, context): +# print(self.setting_1) + self.debug("exec") + return 'FINISHED' + + def invoke(self, context, event): + self.debug("invoke") + return self.exec(context) + + def poll(self, context): # poll isnt working yet + self.debug("poll") + return True diff --git a/release/ui/space_script.py b/release/ui/space_script.py index ea6f4be311c..0ab091e8fd5 100644 --- a/release/ui/space_script.py +++ b/release/ui/space_script.py @@ -1,5 +1,25 @@ +import sys +import os +import imp +# import glob import bpy +operators = [] + +def register_op(opclass): + if (hasattr(bpy.ops, opclass.__name__)): + bpy.ops.remove(getattr(bpy.ops, opclass.__name__)) + + bpy.ops.add(opclass) + + global operators + if opclass.__name__ not in operators: + operators.append(opclass.__name__) + + +# hint for myself: for interface api documentation, see source/blender/editors/interface/interface_api.c +# another hint: reloading ui scripts in scripts window is Shift + P + class SCRIPT_HT_header(bpy.types.Header): __space_type__ = "SCRIPTS_WINDOW" __idname__ = "SCRIPT_HT_header" @@ -14,23 +34,6 @@ class SCRIPT_HT_header(bpy.types.Header): row = layout.row(align=True) row.itemM(context, "SCRIPT_MT_scripts") - # draw menu item to reload scripts from - # release/io - # - # it should call operator or - # a func that will: - # for each .py file in the dir, - # import/reload module, in the module: - # find subclasses of bpy.types.Operator, - # for each subclass create menus under "Export" - # with (row.)itemO - # - # for interface api documentation, see - # see source/blender/editors/interface/interface_api.c - # - # hint: reloading ui scripts in scripts window is Shift+P - - class SCRIPT_MT_scripts(bpy.types.Menu): __space_type__ = "SCRIPTS_WINDOW" __label__ = "Scripts" @@ -46,13 +49,69 @@ class SCRIPT_MT_export(bpy.types.Menu): __label__ = "Export" def draw(self, context): - pass + global operators + + print("drawing {0} operators: {1}".format(len(operators), operators)) + + layout = self.layout + layout.column() + for opname in operators: + layout.itemO(opname) class SCRIPT_OT_reload_scripts(bpy.types.Operator): __label__ = 'Reload Scripts' def exec(self, context): print("SCRIPT_OT_reload_scripts: exec") + + # add ../io to sys.path + + # this module's absolute path + abspath = os.path.abspath(sys.modules[__name__].__file__) + print("Current abspath: {0}".format(abspath)) + + # ../io + io = os.path.normpath(os.path.dirname(abspath) + "/../io") + print("abspath = " + io) + + if io not in sys.path: + sys.path.append(io) + + # for each .py file in release/io, + # import/reload module, in the module: + # find subclasses of bpy.types.Operator, + # for each subclass create menus under "Export" + # with (row.)itemO + + global operators + operators = [] + + # glob unavailable :( +# for path in glob.glob("../io/*.py"): + for path in os.listdir(io): + modname, ext = os.path.splitext(os.path.basename(path)) + + if ext != ".py": + continue + + print("Found module {0}.".format(modname)) + + if modname in sys.modules: + mod = imp.reload(sys.modules[modname]) + print("Reloaded it.") + else: + mod = __import__(modname) + print("Imported it.") + + for attr in dir(mod): + cls = getattr(mod, attr) + + # XXX is there a better way to check that cls is a class? + if type(cls) == bpy.types.Operator.__class__ and issubclass(cls, bpy.types.Operator): + print("Found class {0}.".format(cls.__name__)) + register_op(cls) + print("Registered it.") + return 'FINISHED' def invoke(self, context, event): @@ -62,7 +121,6 @@ class SCRIPT_OT_reload_scripts(bpy.types.Operator): def poll(self, context): pass - bpy.types.register(SCRIPT_HT_header) bpy.types.register(SCRIPT_MT_scripts) bpy.types.register(SCRIPT_MT_export) -- cgit v1.2.3 From 590f3a43bf2e5e4826e943aa6b5cdf0ebc76aa6d Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 14 Jun 2009 10:56:29 +0000 Subject: Enabled the missing features (not tested) bug-reports are welcome --- source/blender/render/intern/source/rayobject.c | 2 +- source/blender/render/intern/source/rayshade.c | 18 ++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 5fc70deaee7..4d0606e2067 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -266,8 +266,8 @@ int RE_rayobject_raycast(RayObject *r, Isect *i) if(casted_rays++ % (1<<20) == 0) printf("Casting %d rays\n", casted_rays); - i->labda = 10000.0; /* + i->labda = 10000.0; i->vec[0] *= i->labda; i->vec[1] *= i->labda; i->vec[2] *= i->labda; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index d9ba89d15e8..10115dc97e9 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1393,8 +1393,6 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int ShadeInput shi; ShadeResult shr; - assert(0); - if(RE_rayobject_raycast(R.raytree, is)) { float d= 1.0f; /* we got a face */ @@ -1662,8 +1660,6 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) float dxyview[3], skyadded=0, div; int aocolor; - assert(0); - isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; @@ -1796,8 +1792,6 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) float dxyview[3]; int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp; - assert(0); - isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; @@ -1979,8 +1973,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * float jitco[RE_MAX_OSA][3]; int totjitco; -// assert(0); - colsq[0] = colsq[1] = colsq[2] = 0.0; if(isec->mode==RE_RAY_SHADOW_TRA) { shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; @@ -2071,7 +2063,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * } VECCOPY(isec->start, co); -// VECSUB(isec->vec, end, isec->start); isec->vec[0] = end[0]-isec->start[0]; isec->vec[1] = end[1]-isec->start[1]; isec->vec[2] = end[2]-isec->start[2]; @@ -2135,8 +2126,6 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa float fac=0.0f, div=0.0f, vec[3]; int a, j= -1, mask; - assert(0); - if(isec->mode==RE_RAY_SHADOW_TRA) { shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; } @@ -2265,11 +2254,8 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) ray_trace_shadow_tra(&isec, shi, DEPTH_SHADOW_TRA, 0); QUATCOPY(shadfac, isec.col); } - else - { - assert(0); - if(RE_rayobject_raycast(R.raytree, &isec)) shadfac[3]= 0.0f; - } + else if(RE_rayobject_raycast(R.raytree, &isec)) + shadfac[3]= 0.0f; } else { ray_shadow_jitter(shi, lar, lampco, shadfac, &isec); -- cgit v1.2.3 From 93d21f36b3450803958ab0a5686ad0a16fa367cd Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sun, 14 Jun 2009 16:48:19 +0000 Subject: Make release/io dir installable on scons build. --- SConstruct | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/SConstruct b/SConstruct index dcea0f511eb..808fa09bea0 100644 --- a/SConstruct +++ b/SConstruct @@ -468,27 +468,17 @@ if env['OURPLATFORM']!='darwin': dotblenderinstall.append(env.Install(dir=td, source=srcfile)) if env['WITH_BF_PYTHON']: - #-- .blender/scripts - scriptpath='release/scripts' - for dp, dn, df in os.walk(scriptpath): - if 'CVS' in dn: - dn.remove('CVS') - if '.svn' in dn: - dn.remove('.svn') - dir=env['BF_INSTALLDIR']+'/.blender/scripts'+dp[len(scriptpath):] - source=[dp+os.sep+f for f in df] - scriptinstall.append(env.Install(dir=dir,source=source)) - - #-- .blender/ui - scriptpath='release/ui' - for dp, dn, df in os.walk(scriptpath): - if 'CVS' in dn: - dn.remove('CVS') - if '.svn' in dn: - dn.remove('.svn') - dir=env['BF_INSTALLDIR']+'/.blender/ui'+dp[len(scriptpath):] - source=[dp+os.sep+f for f in df] - scriptinstall.append(env.Install(dir=dir,source=source)) + #-- .blender/scripts, .blender/ui, .blender/io + scriptpaths=['release/scripts', 'release/ui', 'release/io'] + for scriptpath in scriptpaths: + for dp, dn, df in os.walk(scriptpath): + if 'CVS' in dn: + dn.remove('CVS') + if '.svn' in dn: + dn.remove('.svn') + dir=env['BF_INSTALLDIR']+'/.blender/'+os.path.basename(scriptpath)+dp[len(scriptpath):] + source=[dp+os.sep+f for f in df] + scriptinstall.append(env.Install(dir=dir,source=source)) #-- icons if env['OURPLATFORM']=='linux2': -- cgit v1.2.3 From fd893819bcc3d4952e785fcf903ed9bc10d7830e Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 15 Jun 2009 07:47:09 +0000 Subject: Fix bug in BPY_flag_from_seq: reset the flag before adjusting it. Otherwise py operators ended up returning something like OPERATOR_CANCELLED | OPERATOR_FINISHED. --- source/blender/python/intern/bpy_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index c447e7de982..8dd81834213 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -81,6 +81,7 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag) char *cstring; PyObject *item; BPY_flag_def *fd; + *flag = 0; if (PySequence_Check(seq)) { i= PySequence_Length(seq); -- cgit v1.2.3 From c7cdb9cc38aa1cbe0772041a21f0bb1640b06220 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 15 Jun 2009 08:12:28 +0000 Subject: File selector working. For now it is accessed as context.add_fileselect(self.__operator__). To allow file selector, I made the following changes: - moved property definition funcs (FloatProperty, etc.) to "bpy.props" to make them accessible from io scripts. Previously they were only accessible in scripts running from Text Editor. - added the "__operator__" instance attribute to py operators. The value is RNA operator pointer. Note that "context.add_fileselect" changes were mistakenly committed with my last merge. --- release/io/export_obj.py | 8 ++++++-- source/blender/python/intern/bpy_interface.c | 17 +---------------- source/blender/python/intern/bpy_operator_wrap.c | 8 ++++++++ source/blender/python/intern/bpy_rna.c | 17 +++++++++++++++++ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 37039bb11cb..663ec6c0478 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -1,3 +1,4 @@ + import bpy class SCRIPT_OT_export_obj(bpy.types.Operator): @@ -7,6 +8,7 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. __props__ = [ + bpy.props["StringProperty"](attr="filename", name="filename", default="/tmp") # FloatProperty(attr="setting_1", name="Example 1", default=10.0, min=0, max=10, description="Add info here"), # StringProperty(attr="filename") ] @@ -17,11 +19,13 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): def exec(self, context): # print(self.setting_1) self.debug("exec") - return 'FINISHED' + self.debug("filename = " + self.filename) + return ('FINISHED',) def invoke(self, context, event): self.debug("invoke") - return self.exec(context) + context.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) #self.exec(context) def poll(self, context): # poll isnt working yet self.debug("poll") diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 4903af475ed..5c33c63028a 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -60,6 +60,7 @@ static void bpy_init_modules( void ) PyModule_AddObject( mod, "types", BPY_rna_types() ); PyModule_AddObject( mod, "ops", BPY_operator_module() ); PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant + PyModule_AddObject( mod, "props", BPY_rna_props() ); /* add the module so we can import it */ PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod); @@ -95,22 +96,6 @@ static PyObject *CreateGlobalDictionary( bContext *C ) // XXX - evil, need to access context BPy_SetContext(C); - // XXX - put somewhere more logical - { - PyMethodDef *ml; - static PyMethodDef bpy_prop_meths[] = { - {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {NULL, NULL, 0, NULL} - }; - - for(ml = bpy_prop_meths; ml->ml_name; ml++) { - PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL)); - } - } - /* add bpy to global namespace */ mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyDict_SetItemString( dict, "bpy", mod ); diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index d951d40b9db..33715a97a43 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -225,6 +225,8 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyObject *ret= NULL, *py_class_instance, *item= NULL; int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); PointerRNA ptr_context; + PyObject ptr_operator; + PyObject *py_operator; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -261,6 +263,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve RNA_property_collection_end(&iter); } + /* set operator pointer RNA as instance "__operator__" attribute */ + RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); + py_operator= pyrna_struct_CreatePyObject(&ptr_operator); + PyObject_SetAttrString(py_class_instance, "__operator__", py_operator); + Py_DECREF(py_operator); + RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); if (mode==PYOP_INVOKE) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 09e2ab15c56..d1c06802f0a 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1750,7 +1750,24 @@ PyObject *BPY_rna_types(void) return (PyObject *)self; } +PyObject *BPY_rna_props( void ) +{ + PyObject *dict = PyDict_New( ); + PyMethodDef *ml; + static PyMethodDef bpy_prop_meths[] = { + {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {NULL, NULL, 0, NULL} + }; + + for(ml = bpy_prop_meths; ml->ml_name; ml++) { + PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL)); + } + return dict; +} /* Orphan functions, not sure where they should go */ -- cgit v1.2.3 From 07e1b84ca8f2ad83b148df03b697a0bcfdb04e3a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 15 Jun 2009 09:26:31 +0000 Subject: Another fix in BPY_flag_from_seq: unrecognized flag is also an error. Print operator return value for debugging. --- release/ui/space_script.py | 2 +- source/blender/python/intern/bpy_operator_wrap.c | 26 +++++++++++++++++++++++- source/blender/python/intern/bpy_util.c | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/release/ui/space_script.py b/release/ui/space_script.py index 0ab091e8fd5..d2c73adb00f 100644 --- a/release/ui/space_script.py +++ b/release/ui/space_script.py @@ -112,7 +112,7 @@ class SCRIPT_OT_reload_scripts(bpy.types.Operator): register_op(cls) print("Registered it.") - return 'FINISHED' + return ('FINISHED',) def invoke(self, context, event): print("SCRIPT_OT_reload_scripts: invoke") diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 33715a97a43..4624fe764b3 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -316,7 +316,8 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) { /* the returned value could not be converted into a flag */ pyop_error_report(op->reports); - + + ret_flag = OPERATOR_CANCELLED; } /* there is no need to copy the py keyword dict modified by * pyot->py_invoke(), back to the operator props since they are just @@ -329,6 +330,29 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve Py_DECREF(ret); } + /* print operator return value */ + if (mode != PYOP_POLL) { + char flag_str[100]; + char class_name[100]; + BPY_flag_def *flag_def = pyop_ret_flags; + + strcpy(flag_str, ""); + + while(flag_def->name) { + if (ret_flag & flag_def->flag) { + flag_str[1] ? sprintf(flag_str, "%s | %s", flag_str, flag_def->name) : strcpy(flag_str, flag_def->name); + } + flag_def++; + } + + /* get class name */ + item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME); + Py_DECREF(item); + strcpy(class_name, _PyUnicode_AsString(item)); + + fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "exec" : "invoke", flag_str); + } + PyGILState_Release(gilstate); return ret_flag; diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 8dd81834213..2c7626fea7f 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -109,6 +109,9 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag) error_val= 1; } + if (*flag == 0) + error_val = 1; + if (error_val) { char *buf = bpy_flag_error_str(flagdef); PyErr_SetString(PyExc_AttributeError, buf); -- cgit v1.2.3 From 678417b76c228d30417889aa91ad9c2b14cbe4fe Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 15 Jun 2009 13:49:02 +0000 Subject: Added copy_applied method on Mesh objects. Uses DerivedMesh funcs to get a mesh with all modifiers applied. --- release/io/export_obj.py | 29 ++++++++++---- source/blender/editors/mesh/editmesh.c | 56 ++++++--------------------- source/blender/makesrna/intern/rna_internal.h | 6 +++ source/blender/makesrna/intern/rna_mesh.c | 12 ++++-- 4 files changed, 48 insertions(+), 55 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 663ec6c0478..c5b8038a3d7 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -1,4 +1,3 @@ - import bpy class SCRIPT_OT_export_obj(bpy.types.Operator): @@ -8,24 +7,40 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. __props__ = [ - bpy.props["StringProperty"](attr="filename", name="filename", default="/tmp") -# FloatProperty(attr="setting_1", name="Example 1", default=10.0, min=0, max=10, description="Add info here"), -# StringProperty(attr="filename") + bpy.props["StringProperty"](attr="filename", name="filename") ] def debug(self, message): print("{0}: {1}".format(self.__class__.__name__, message)) def exec(self, context): -# print(self.setting_1) self.debug("exec") self.debug("filename = " + self.filename) + + self.debug("num selected objects: {0}".format(len(context.selected_objects))) + + ob = bpy.data.objects["Cube"] + o = ob.data + + m = bpy.data.add_mesh("tmpmesh") + m.copy_applied(context.scene, ob, True) + + def vert(co): + return "{0}, {1}, {2}".format(co[0], co[1], co[2]) + + print(" orig: {0} with totverts={1}".format(vert(o.verts[0].co), len(o.verts))) + print("applied: {0} with totverts={1}".format(vert(m.verts[0].co), len(m.verts))) + + # XXX errors are silenced for some reason +# raise Exception("oops!") + return ('FINISHED',) def invoke(self, context, event): self.debug("invoke") - context.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) #self.exec(context) +# context.add_fileselect(self.__operator__) +# return ('RUNNING_MODAL',) + return self.exec(context) def poll(self, context): # poll isnt working yet self.debug("poll") diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index bce5c202366..de4bab57a72 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -2041,6 +2041,16 @@ void RNA_api_mesh_copy(Mesh *me, Mesh *from) copy_mesh_data(me, from); } +void RNA_api_mesh_copy_applied(Mesh *me, Scene *sce, Object *ob, int apply_obmat) +{ + DerivedMesh *dm= mesh_create_derived_view(sce, ob, CD_MASK_MESH); + DM_to_mesh(dm, me); + dm->release(dm); + + if (apply_obmat) { + } +} + void RNA_api_mesh_transform(Mesh *me, float **mat) { } @@ -2048,6 +2058,8 @@ void RNA_api_mesh_transform(Mesh *me, float **mat) /* * This version of copy_mesh doesn't allocate a new mesh, * instead it copies data between two existing meshes. + * + * XXX is this already possible with DerivedMesh? */ void copy_mesh_data(Mesh *dest, Mesh *src) { @@ -2078,47 +2090,3 @@ void copy_mesh_data(Mesh *dest, Mesh *src) mesh_update_customdata_pointers(dest); } - -/* -void RNA_api_mesh_apply_transform(Mesh *me) -{ - -} -*/ - -/* -void RNA_api_mesh_copy_(Mesh *me, Object *ob, int apply_transform) -{ - if (ob->type != OB_MESH) { - return; - } - - Mesh *src= (Mesh*)ob->data; - - CustomData_free(&me->vdata, me->totvert); - CustomData_free(&me->edata, me->totedge); - CustomData_free(&me->fdata, me->totface); - - CustomData_copy(&src->vdata, &me->vdata, CD_MASK_MESH, CD_DUPLICATE, me->totvert); - CustomData_copy(&src->edata, &me->edata, CD_MASK_MESH, CD_DUPLICATE, me->totedge); - CustomData_copy(&src->fdata, &me->fdata, CD_MASK_MESH, CD_DUPLICATE, me->totface); - mesh_update_customdata_pointers(me); - - // ensure indirect linked data becomes lib-extern - for(i=0; ifdata.totlayer; i++) { - if(src->fdata.layers[i].type == CD_MTFACE) { - tface= (MTFace*)src->fdata.layers[i].data; - - for(a=0; atotface; a++, tface++) - if(tface->tpage) - id_lib_extern((ID*)tface->tpage); - } - } - - me->mselect= NULL; - me->bb= src->bb; - - //men->key= copy_key(me->key); - //if(men->key) men->key->from= (ID *)men; -} -*/ diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index d93c296ca93..4d3b9dfa327 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -188,9 +188,15 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch /* API functions */ +struct Main; +struct Scene; +struct Object; +struct Mesh; + void RNA_api_ui_layout(struct StructRNA *srna); struct Mesh *RNA_api_add_mesh(struct Main *main, char *name); void RNA_api_mesh_copy(struct Mesh *me, struct Mesh *from); +void RNA_api_mesh_copy_applied(struct Mesh *me, struct Scene *sce, struct Object *ob, int apply_obmat); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index a071a79230e..35b8164fae3 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1132,10 +1132,14 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_function_ui_description(func, "Copy mesh data."); prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from."); RNA_def_property_flag(prop, PROP_REQUIRED); - /* - prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A new mesh."); - RNA_def_function_return(func, prop); - */ + + func= RNA_def_function(srna, "copy_applied", "RNA_api_mesh_copy_applied"); + RNA_def_function_ui_description(func, "Copy mesh data from object with all modifiers and transformations applied."); + prop= RNA_def_pointer(func, "sce", "Scene", "", "Scene."); + RNA_def_property_flag(prop, PROP_REQUIRED); + prop= RNA_def_pointer(func, "ob", "Object", "", "Object to copy data from."); + RNA_def_property_flag(prop, PROP_REQUIRED); + RNA_def_boolean(func, "apply_obmat", 1, "", "Apply object matrix."); } void RNA_def_mesh(BlenderRNA *brna) -- cgit v1.2.3 From 556369fe2fcb33ec4a028cc1a9c1ae1d0701e6ba Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 16 Jun 2009 08:54:38 +0000 Subject: The basic OBJ exporter working. The code is release/io/export_obj.py. To run it, switch to Scripts Window, click Scripts->Reload Scripts menu, it appears under Scripts->Export. --- release/io/export_obj.py | 54 +++++++++++++++++++-------- source/blender/editors/mesh/editmesh.c | 5 +-- source/blender/makesrna/intern/rna_internal.h | 2 +- source/blender/makesrna/intern/rna_mesh.c | 3 +- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index c5b8038a3d7..df10c3e9089 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -1,7 +1,37 @@ import bpy +def write_obj(filepath, scene, ob): + out = open(filepath, 'w') + + # create a temporary mesh + mesh = bpy.data.add_mesh("tmpmesh") + + # copy data with modifiers applied + mesh.copy_applied(scene, ob) + + # for vert in mesh.verts: + # ^ iterating that way doesn't work atm for some reason + + for i in range(len(mesh.verts)): + vert = mesh.verts[i] + out.write('v {0} {1} {2}\n'.format(vert.co[0], vert.co[1], vert.co[2])) + + for i in range(len(mesh.faces)): + face = mesh.faces[i] + out.write('f') + + # but this works + for index in face.verts: + out.write(' {0}'.format(index + 1)) + out.write('\n') + + # TODO: delete mesh here + + out.close() + class SCRIPT_OT_export_obj(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''A very basic OBJ exporter, writes only active object's mesh.''' + __label__ = 'Export OBJ' # List of operator properties, the attributes will be assigned @@ -17,19 +47,12 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): self.debug("exec") self.debug("filename = " + self.filename) - self.debug("num selected objects: {0}".format(len(context.selected_objects))) - - ob = bpy.data.objects["Cube"] - o = ob.data - - m = bpy.data.add_mesh("tmpmesh") - m.copy_applied(context.scene, ob, True) - - def vert(co): - return "{0}, {1}, {2}".format(co[0], co[1], co[2]) + act = context.active_object - print(" orig: {0} with totverts={1}".format(vert(o.verts[0].co), len(o.verts))) - print("applied: {0} with totverts={1}".format(vert(m.verts[0].co), len(m.verts))) + if act.type == 'MESH': + write_obj(self.filename, context.scene, act) + else: + self.debug("Active object is not a MESH.") # XXX errors are silenced for some reason # raise Exception("oops!") @@ -38,9 +61,8 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): def invoke(self, context, event): self.debug("invoke") -# context.add_fileselect(self.__operator__) -# return ('RUNNING_MODAL',) - return self.exec(context) + context.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) def poll(self, context): # poll isnt working yet self.debug("poll") diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index de4bab57a72..33174e31df5 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -2041,14 +2041,11 @@ void RNA_api_mesh_copy(Mesh *me, Mesh *from) copy_mesh_data(me, from); } -void RNA_api_mesh_copy_applied(Mesh *me, Scene *sce, Object *ob, int apply_obmat) +void RNA_api_mesh_copy_applied(Mesh *me, Scene *sce, Object *ob) { DerivedMesh *dm= mesh_create_derived_view(sce, ob, CD_MASK_MESH); DM_to_mesh(dm, me); dm->release(dm); - - if (apply_obmat) { - } } void RNA_api_mesh_transform(Mesh *me, float **mat) diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 4d3b9dfa327..aad70ec57b0 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -196,7 +196,7 @@ struct Mesh; void RNA_api_ui_layout(struct StructRNA *srna); struct Mesh *RNA_api_add_mesh(struct Main *main, char *name); void RNA_api_mesh_copy(struct Mesh *me, struct Mesh *from); -void RNA_api_mesh_copy_applied(struct Mesh *me, struct Scene *sce, struct Object *ob, int apply_obmat); +void RNA_api_mesh_copy_applied(struct Mesh *me, struct Scene *sce, struct Object *ob); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 35b8164fae3..574bfee49f6 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1134,12 +1134,11 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REQUIRED); func= RNA_def_function(srna, "copy_applied", "RNA_api_mesh_copy_applied"); - RNA_def_function_ui_description(func, "Copy mesh data from object with all modifiers and transformations applied."); + RNA_def_function_ui_description(func, "Copy mesh data from object with all modifiers applied."); prop= RNA_def_pointer(func, "sce", "Scene", "", "Scene."); RNA_def_property_flag(prop, PROP_REQUIRED); prop= RNA_def_pointer(func, "ob", "Object", "", "Object to copy data from."); RNA_def_property_flag(prop, PROP_REQUIRED); - RNA_def_boolean(func, "apply_obmat", 1, "", "Apply object matrix."); } void RNA_def_mesh(BlenderRNA *brna) -- cgit v1.2.3 From 16d8cc633db5e1e3168d9ce9bbea62957d973024 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 16 Jun 2009 12:42:14 +0000 Subject: WARNING: I'm starting generic RNA collection add ;) --- source/blender/makesrna/intern/rna_access.c | 24 ++++++++++++++++++++++++ source/blender/makesrna/intern/rna_internal.h | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 870fa4d9aa3..71044cbfe13 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1342,6 +1342,8 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA else printf("RNA_property_collection_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier); + /* TODO: call cprop->add on non-ID props here */ + if(r_ptr) { if(idprop) { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; @@ -1510,6 +1512,13 @@ void rna_iterator_listbase_end(CollectionPropertyIterator *iter) iter->internal= NULL; } +void *rna_iterator_listbase_add(ListBase *lb, void *item) +{ + BLI_addtail(lb, item); + + return item; +} + void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, IteratorSkipFunc skip) { ArrayIterator *internal; @@ -1567,6 +1576,21 @@ void rna_iterator_array_end(CollectionPropertyIterator *iter) iter->internal= NULL; } +void *rna_iterator_array_add(void *ptr, int itemsize, int length, void *item) +{ + // alloc new block, copy old data + void *newptr= MEM_callocN(length * itemsize + itemsize, "RNA collection add"); + memcpy(newptr, ptr, length * itemsize); + + // copy new item + memcpy(((char*)newptr) + length * itemsize, item, itemsize); + + // free old block + MEM_freeN(ptr); + + return newptr; +} + /* RNA Path - Experiment */ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket) diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index aad70ec57b0..531268768d3 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -237,6 +237,9 @@ void rna_iterator_listbase_next(struct CollectionPropertyIterator *iter); void *rna_iterator_listbase_get(struct CollectionPropertyIterator *iter); void rna_iterator_listbase_end(struct CollectionPropertyIterator *iter); +/* experimental */ +void *rna_iterator_listbase_add(ListBase *lb, void *item); + typedef struct ArrayIterator { char *ptr; char *endptr; @@ -250,6 +253,9 @@ void *rna_iterator_array_get(struct CollectionPropertyIterator *iter); void *rna_iterator_array_dereference_get(struct CollectionPropertyIterator *iter); void rna_iterator_array_end(struct CollectionPropertyIterator *iter); +/* experimental */ +void *rna_iterator_array_add(void *ptr, void *data); + /* Duplicated code since we can't link in blenlib */ void rna_addtail(struct ListBase *listbase, void *vlink); -- cgit v1.2.3 From 7a54e45ccdaed5d7fa802fa20a31fda205b04294 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 16 Jun 2009 13:57:28 +0000 Subject: Just added another param to RNA_def_property_collection_funcs and zeroed it in each call. --- source/blender/makesrna/RNA_define.h | 2 +- source/blender/makesrna/intern/rna_color.c | 2 +- source/blender/makesrna/intern/rna_curve.c | 2 +- source/blender/makesrna/intern/rna_define.c | 5 +++-- source/blender/makesrna/intern/rna_group.c | 2 +- source/blender/makesrna/intern/rna_internal.h | 2 +- .../blender/makesrna/intern/rna_internal_types.h | 2 ++ source/blender/makesrna/intern/rna_key.c | 2 +- source/blender/makesrna/intern/rna_lattice.c | 4 ++-- source/blender/makesrna/intern/rna_main.c | 2 +- source/blender/makesrna/intern/rna_material.c | 2 +- source/blender/makesrna/intern/rna_mesh.c | 22 +++++++++++----------- source/blender/makesrna/intern/rna_modifier.c | 2 +- source/blender/makesrna/intern/rna_object.c | 2 +- source/blender/makesrna/intern/rna_rna.c | 10 +++++----- source/blender/makesrna/intern/rna_scene.c | 2 +- source/blender/makesrna/intern/rna_sequence.c | 2 +- 17 files changed, 35 insertions(+), 32 deletions(-) diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index c40f50c34fc..553d0ecf028 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -146,7 +146,7 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item); void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set); void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef); -void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring); +void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *add); /* Function */ diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index dcd5a494e5d..ef9bd86c2d9 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -212,7 +212,7 @@ static void rna_def_curvemapping(BlenderRNA *brna) RNA_def_property_float_funcs(prop, NULL, NULL, "rna_CurveMapping_clipmaxy_range"); prop= RNA_def_property(srna, "curves", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_CurveMapping_curves_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_CurveMapping_curves_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_CurveMapping_curves_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_CurveMapping_curves_length", 0, 0, 0); RNA_def_property_struct_type(prop, "CurveMap"); RNA_def_property_ui_text(prop, "Curves", ""); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index aac9d75c6a6..6b3c9767e2e 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -605,7 +605,7 @@ static void rna_def_curve_nurb(BlenderRNA *brna) prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "bp", NULL); RNA_def_property_struct_type(prop, "CurvePoint"); - RNA_def_property_collection_funcs(prop, "rna_BPoint_array_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_Nurb_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_BPoint_array_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_Nurb_length", 0, 0, 0); RNA_def_property_ui_text(prop, "Points", "Collection of points for Poly and Nurbs curves."); prop= RNA_def_property(srna, "bezier_points", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 33d94e800d1..6b72646da4a 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -604,7 +604,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * if(DefRNA.preprocess) { RNA_def_property_struct_type(prop, "Property"); - RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, 0, 0); } else { #ifdef RNA_RUNTIME @@ -1769,7 +1769,7 @@ void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const ch } } -void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring) +void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *add) { StructRNA *srna= DefRNA.laststruct; @@ -1789,6 +1789,7 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con if(length) cprop->length= (PropCollectionLengthFunc)length; if(lookupint) cprop->lookupint= (PropCollectionLookupIntFunc)lookupint; if(lookupstring) cprop->lookupstring= (PropCollectionLookupStringFunc)lookupstring; + if(add) cprop->add= (PropCollectionAddFunc)add; break; } default: diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index 059b2ce78f7..f284423ef7f 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -61,7 +61,7 @@ void RNA_def_group(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "gobject", NULL); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Objects", "A collection of this groups objects."); - RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Group_objects_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Group_objects_get", 0, 0, 0, 0); prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "layer", 1); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 531268768d3..467e0dabb24 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -254,7 +254,7 @@ void *rna_iterator_array_dereference_get(struct CollectionPropertyIterator *iter void rna_iterator_array_end(struct CollectionPropertyIterator *iter); /* experimental */ -void *rna_iterator_array_add(void *ptr, void *data); +void *rna_iterator_array_add(void *ptr, int itemsize, int length, void *item); /* Duplicated code since we can't link in blenlib */ diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index d690251f503..1a3668813c8 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -78,6 +78,7 @@ typedef PointerRNA (*PropCollectionGetFunc)(struct CollectionPropertyIterator *i typedef int (*PropCollectionLengthFunc)(struct PointerRNA *ptr); typedef PointerRNA (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key); typedef PointerRNA (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key); +typedef void (*PropCollectionAddFunc)(PointerRNA *ptr, PointerRNA *item); /* Container - generic abstracted container of RNA properties */ typedef struct ContainerRNA { @@ -243,6 +244,7 @@ typedef struct CollectionPropertyRNA { PropCollectionLengthFunc length; /* optional */ PropCollectionLookupIntFunc lookupint; /* optional */ PropCollectionLookupStringFunc lookupstring; /* optional */ + PropCollectionAddFunc add; struct StructRNA *type; } CollectionPropertyRNA; diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index ae03cca74c2..3070e0a9076 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -335,7 +335,7 @@ static void rna_def_keyblock(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "data", "totelem"); RNA_def_property_struct_type(prop, "UnknownType"); RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_collection_funcs(prop, "rna_ShapeKey_data_begin", 0, 0, "rna_ShapeKey_data_get", "rna_ShapeKey_data_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_ShapeKey_data_begin", 0, 0, "rna_ShapeKey_data_get", "rna_ShapeKey_data_length", 0, 0, 0); } static void rna_def_key(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c index 26c4ebb7b23..de547eab617 100644 --- a/source/blender/makesrna/intern/rna_lattice.c +++ b/source/blender/makesrna/intern/rna_lattice.c @@ -99,7 +99,7 @@ static void rna_def_latticepoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Deformed Location", ""); prop= RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_LatticePoint_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_LatticePoint_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0, 0); RNA_def_property_struct_type(prop, "VertexGroupElement"); RNA_def_property_ui_text(prop, "Groups", "Weights for the vertex groups this point is member of."); } @@ -159,7 +159,7 @@ static void rna_def_lattice(BlenderRNA *brna) prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "LatticePoint"); - RNA_def_property_collection_funcs(prop, "rna_Lattice_points_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Lattice_points_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Points", "Points of the lattice."); } diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 347aef69a76..22f19d725cb 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -264,7 +264,7 @@ void RNA_def_main(BlenderRNA *brna) { prop= RNA_def_property(srna, lists[i][0], PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, lists[i][1]); - RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]); } diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index a5dbb63adf2..1ab70154442 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1048,7 +1048,7 @@ void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeg /* mtex */ prop= RNA_def_property(srna, "textures", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, structname); - RNA_def_property_collection_funcs(prop, begin, "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_dereference_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, begin, "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_dereference_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Textures", "Texture slots defining the mapping and influence of textures."); prop= RNA_def_property(srna, "active_texture", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 574bfee49f6..18a94d97296 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -646,7 +646,7 @@ static void rna_def_mvert(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bevel Weight", "Weight used by the Bevel modifier 'Only Vertices' option"); prop= RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_funcs(prop, "rna_MeshVertex_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MeshVertex_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0, 0); RNA_def_property_struct_type(prop, "VertexGroupElement"); RNA_def_property_ui_text(prop, "Groups", "Weights for the vertex groups this vertex is member of."); } @@ -761,7 +761,7 @@ static void rna_def_mtface(BlenderRNA *brna) prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTextureFace"); RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_collection_funcs(prop, "rna_MeshTextureFaceLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshTextureFaceLayer_data_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MeshTextureFaceLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshTextureFaceLayer_data_length", 0, 0, 0); srna= RNA_def_struct(brna, "MeshTextureFace", NULL); RNA_def_struct_sdna(srna, "MTFace"); @@ -902,7 +902,7 @@ static void rna_def_mcol(BlenderRNA *brna) prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshColor"); RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_collection_funcs(prop, "rna_MeshColorLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshColorLayer_data_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MeshColorLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshColorLayer_data_length", 0, 0, 0); srna= RNA_def_struct(brna, "MeshColor", NULL); RNA_def_struct_sdna(srna, "MCol"); @@ -948,7 +948,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshFloatProperty"); RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_collection_funcs(prop, "rna_MeshFloatPropertyLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshFloatPropertyLayer_data_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MeshFloatPropertyLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshFloatPropertyLayer_data_length", 0, 0, 0); srna= RNA_def_struct(brna, "MeshFloatProperty", NULL); RNA_def_struct_sdna(srna, "MFloatProperty"); @@ -972,7 +972,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshIntProperty"); RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_collection_funcs(prop, "rna_MeshIntPropertyLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshIntPropertyLayer_data_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MeshIntPropertyLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshIntPropertyLayer_data_length", 0, 0, 0); srna= RNA_def_struct(brna, "MeshIntProperty", NULL); RNA_def_struct_sdna(srna, "MIntProperty"); @@ -996,7 +996,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshStringProperty"); RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_collection_funcs(prop, "rna_MeshStringPropertyLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshStringPropertyLayer_data_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_MeshStringPropertyLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshStringPropertyLayer_data_length", 0, 0, 0); srna= RNA_def_struct(brna, "MeshStringProperty", NULL); RNA_def_struct_sdna(srna, "MStringProperty"); @@ -1072,31 +1072,31 @@ static void rna_def_mesh(BlenderRNA *brna) prop= RNA_def_property(srna, "uv_layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); - RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_layers_begin", 0, 0, 0, "rna_Mesh_uv_layers_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_layers_begin", 0, 0, 0, "rna_Mesh_uv_layers_length", 0, 0, 0); RNA_def_property_struct_type(prop, "MeshTextureFaceLayer"); RNA_def_property_ui_text(prop, "UV Layers", ""); prop= RNA_def_property(srna, "vcol_layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); - RNA_def_property_collection_funcs(prop, "rna_Mesh_vcol_layers_begin", 0, 0, 0, "rna_Mesh_vcol_layers_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Mesh_vcol_layers_begin", 0, 0, 0, "rna_Mesh_vcol_layers_length", 0, 0, 0); RNA_def_property_struct_type(prop, "MeshColorLayer"); RNA_def_property_ui_text(prop, "Vertex Color Layers", ""); prop= RNA_def_property(srna, "float_layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); - RNA_def_property_collection_funcs(prop, "rna_Mesh_float_layers_begin", 0, 0, 0, "rna_Mesh_float_layers_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Mesh_float_layers_begin", 0, 0, 0, "rna_Mesh_float_layers_length", 0, 0, 0); RNA_def_property_struct_type(prop, "MeshFloatPropertyLayer"); RNA_def_property_ui_text(prop, "Float Property Layers", ""); prop= RNA_def_property(srna, "int_layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); - RNA_def_property_collection_funcs(prop, "rna_Mesh_int_layers_begin", 0, 0, 0, "rna_Mesh_int_layers_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Mesh_int_layers_begin", 0, 0, 0, "rna_Mesh_int_layers_length", 0, 0, 0); RNA_def_property_struct_type(prop, "MeshIntPropertyLayer"); RNA_def_property_ui_text(prop, "Int Property Layers", ""); prop= RNA_def_property(srna, "string_layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); - RNA_def_property_collection_funcs(prop, "rna_Mesh_string_layers_begin", 0, 0, 0, "rna_Mesh_string_layers_length", 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Mesh_string_layers_begin", 0, 0, 0, "rna_Mesh_string_layers_length", 0, 0, 0); RNA_def_property_struct_type(prop, "MeshStringPropertyLayer"); RNA_def_property_ui_text(prop, "String Property Layers", ""); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index fe5bd6ad727..56e16a8f21e 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1089,7 +1089,7 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna) prop= RNA_def_property(srna, "projectors", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_collection_funcs(prop, "rna_UVProject_projectors_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_dereference_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_UVProject_projectors_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_dereference_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Projectors", ""); prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 86cf501295c..4d5cef123dc 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -739,7 +739,7 @@ static StructRNA *rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol"); RNA_def_property_struct_type(prop, "MaterialSlot"); - RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_iterator_array_get", 0, 0, 0); /* don't dereference pointer! */ + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_iterator_array_get", 0, 0, 0, 0); /* don't dereference pointer! */ RNA_def_property_ui_text(prop, "Materials", "Material slots in the object."); prop= RNA_def_property(srna, "active_material", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 8ea8844c65f..e0f670e8ded 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -611,13 +611,13 @@ static void rna_def_struct(BlenderRNA *brna) prop= RNA_def_property(srna, "properties", PROP_COLLECTION, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Property"); - RNA_def_property_collection_funcs(prop, "rna_Struct_properties_begin", "rna_Struct_properties_next", "rna_iterator_listbase_end", "rna_Struct_properties_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Struct_properties_begin", "rna_Struct_properties_next", "rna_iterator_listbase_end", "rna_Struct_properties_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Properties", "Properties in the struct."); prop= RNA_def_property(srna, "functions", PROP_COLLECTION, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Function"); - RNA_def_property_collection_funcs(prop, "rna_Struct_functions_begin", "rna_Struct_functions_next", "rna_iterator_listbase_end", "rna_Struct_functions_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Struct_functions_begin", "rna_Struct_functions_next", "rna_iterator_listbase_end", "rna_Struct_functions_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Functions", ""); } @@ -719,7 +719,7 @@ static void rna_def_function(BlenderRNA *brna) prop= RNA_def_property(srna, "parameters", PROP_COLLECTION, PROP_NONE); /*RNA_def_property_clear_flag(prop, PROP_EDITABLE);*/ RNA_def_property_struct_type(prop, "Property"); - RNA_def_property_collection_funcs(prop, "rna_Function_parameters_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_Function_parameters_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Parameters", "Parameters for the function."); prop= RNA_def_property(srna, "registered", PROP_BOOLEAN, PROP_NONE); @@ -800,7 +800,7 @@ static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna) prop= RNA_def_property(srna, "items", PROP_COLLECTION, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "EnumPropertyItem"); - RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Items", "Possible values for the property."); srna= RNA_def_struct(brna, "EnumPropertyItem", NULL); @@ -895,7 +895,7 @@ void RNA_def_rna(BlenderRNA *brna) prop= RNA_def_property(srna, "structs", PROP_COLLECTION, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Struct"); - RNA_def_property_collection_funcs(prop, "rna_BlenderRNA_structs_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, "rna_BlenderRNA_structs_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); RNA_def_property_ui_text(prop, "Structs", ""); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 3907a633e3d..83b6df502a6 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -866,7 +866,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "base", NULL); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Objects", ""); - RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Scene_objects_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Scene_objects_get", 0, 0, 0, 0); prop= RNA_def_property(srna, "visible_layers", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "lay", 1); diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index b21e08fcd1a..b3975e2469e 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -519,7 +519,7 @@ void rna_def_editor(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "metastack", NULL); RNA_def_property_struct_type(prop, "Sequence"); RNA_def_property_ui_text(prop, "Meta Stack", "Meta strip stack, last is currently edited meta strip."); - RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_SequenceEdtior_meta_stack_get", 0, 0, 0); + RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_SequenceEdtior_meta_stack_get", 0, 0, 0, 0); prop= RNA_def_property(srna, "active_strip", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "act_seq"); -- cgit v1.2.3 From bbec5c03c989fca91ba8be9f3c002c6cb2980415 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 16 Jun 2009 16:15:19 +0000 Subject: Updated makesrna to generate correct CollectionPropertyRNAs. --- source/blender/makesrna/intern/makesrna.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index ea587174f54..304a008229a 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1628,7 +1628,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr } case PROP_COLLECTION: { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; - fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring)); + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring), rna_function_string(cprop->add)); if(cprop->type) fprintf(f, "&RNA_%s\n", (char*)cprop->type); else fprintf(f, "NULL\n"); break; -- cgit v1.2.3 From 449555315a45fe4e58cc20d5685c60063444543f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 16 Jun 2009 18:02:38 +0000 Subject: RNA_property_collection_add should work now for non-ID properties. Since it's very limited, and has a doubtful interface, I need help on how improve and use it. I'll ask on ML. --- source/blender/makesrna/intern/rna_access.c | 8 ++++--- .../blender/makesrna/intern/rna_internal_types.h | 2 +- source/blender/makesrna/intern/rna_mesh.c | 28 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 71044cbfe13..f114e72e990 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1314,6 +1314,7 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop) void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr) { IDProperty *idprop; + CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; if((idprop=rna_idproperty_check(&prop, ptr))) { IDPropertyTemplate val = {0}; @@ -1339,10 +1340,11 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA MEM_freeN(item); } } + else if(cprop->add){ + cprop->add(ptr, r_ptr); + } else - printf("RNA_property_collection_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier); - - /* TODO: call cprop->add on non-ID props here */ + printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier); if(r_ptr) { if(idprop) { diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index 1a3668813c8..840b5745681 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -78,7 +78,7 @@ typedef PointerRNA (*PropCollectionGetFunc)(struct CollectionPropertyIterator *i typedef int (*PropCollectionLengthFunc)(struct PointerRNA *ptr); typedef PointerRNA (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key); typedef PointerRNA (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key); -typedef void (*PropCollectionAddFunc)(PointerRNA *ptr, PointerRNA *item); +typedef void (*PropCollectionAddFunc)(PointerRNA *ptr, PointerRNA *ptr_item); /* Container - generic abstracted container of RNA properties */ typedef struct ContainerRNA { diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 18a94d97296..ec58d695105 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -484,6 +484,33 @@ static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value) tf->tpage= (struct Image*)id; } +static void rna_Mesh_verts_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *me= (Mesh*)ptr->data; + rna_iterator_array_begin(iter, me->mvert, sizeof(MVert), me->totvert, NULL); +} + +/* extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); */ + +static void rna_Mesh_verts_add(PointerRNA *ptr, PointerRNA *ptr_item) +{ + Mesh *me= (Mesh*)ptr->data; + + /* + // XXX if item is not MVert we fail silently + if (item->type == RNA_MeshVertex) + return; + + // XXX this must be slow... + EditMesh *em= BKE_mesh_get_editmesh(me); + + MVert *v = (MVert*)ptr_item->ptr->data; + addvertlist(em, v->co, NULL); + + BKE_mesh_end_editmesh(me, em); + */ +} + /* path construction */ static char *rna_VertexGroupElement_path(PointerRNA *ptr) @@ -1054,6 +1081,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "mvert", "totvert"); RNA_def_property_struct_type(prop, "MeshVertex"); RNA_def_property_ui_text(prop, "Vertices", "Vertices of the mesh."); + RNA_def_property_collection_funcs(prop, "rna_Mesh_verts_begin", 0, 0, 0, 0, 0, 0, "rna_Mesh_verts_add"); prop= RNA_def_property(srna, "edges", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "medge", "totedge"); -- cgit v1.2.3 From 419dde702146fa9d49b309e746b03782baae8baf Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 17 Jun 2009 00:01:27 +0000 Subject: Non recursive tree transverse on raycast *for now proximity-heuristic on tree transverse is disabled --- source/blender/blenlib/intern/BLI_kdopbvh.c | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 51b51e5ecca..3a5da8dd8aa 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -52,6 +52,7 @@ typedef struct BVHNode { struct BVHNode **children; struct BVHNode *parent; // some user defined traversed need that + struct BVHNode *skip[2]; float *bv; // Bounding volume of all nodes, max 13 axis int index; // face, edge, vertex index char totnode; // how many nodes are used, used for speedup @@ -355,6 +356,23 @@ int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ } ////////////////////////////////////////////////////////////////////////////////////////////////////// +static void build_skip_links(BVHTree *tree, BVHNode *node, BVHNode *left, BVHNode *right) +{ + int i; + + node->skip[0] = left; + node->skip[1] = right; + + for (i = 0; i < node->totnode; i++) + { + if(i+1 < node->totnode) + build_skip_links(tree, node->children[i], left, node->children[i+1] ); + else + build_skip_links(tree, node->children[i], left, right ); + + left = node->children[i]; + } +} /* * BVHTree bounding volumes functions @@ -941,6 +959,7 @@ void BLI_bvhtree_balance(BVHTree *tree) for(i = 0; i < tree->totbranch; i++) tree->nodes[tree->totleaf + i] = branches_array + i; + build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL); //bvhtree_info(tree); } @@ -1513,6 +1532,37 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node) } } +static void iterative_raycast(BVHRayCastData *data, BVHNode *node) +{ + while(node) + { + float dist = fast_ray_nearest_hit(data, node); + if(dist >= data->hit.dist) + { + node = node->skip[1]; + continue; + } + + if(node->totnode == 0) + { + if(data->callback) + data->callback(data->userdata, node->index, &data->ray, &data->hit); + else + { + data->hit.index = node->index; + data->hit.dist = dist; + VECADDFAC(data->hit.co, data->ray.origin, data->ray.direction, dist); + } + + node = node->skip[1]; + } + else + { + node = node->children[0]; + } + } +} + int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata) { int i; @@ -1555,7 +1605,10 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float } if(root) + { dfs_raycast(&data, root); +// iterative_raycast(&data, root); + } if(hit) -- cgit v1.2.3 From 29f5694ab8d2021bb0b9c197f95b228809b40897 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 18 Jun 2009 09:50:34 +0000 Subject: API structuring improvements according to design guidelines by Brecht, for more info see http://lists.blender.org/pipermail/bf-taskforce25/2009-June/000954.html. Created *_api.c files in makesrna/intern. Among these only rna_api.c is compiled on preprocesssing step. It contains code declaring RNA struct functions, for example RNA_api_mesh declares all functions on Mesh. The rest *_api.c files contain functions themselves. Removed interface_api.c and moved its contents to rna_api.c. Added remove_mesh function on Main. Replaced copy and copy_mesh on Mesh with make_rendermesh which currently does the same as copy_applied did (grasping mesh-related stuff needs time). SConscript tweaking so it builds ok. --- source/blender/editors/interface/SConscript | 4 +- source/blender/editors/interface/interface_api.c | 240 ------------------ source/blender/editors/mesh/editmesh.c | 26 +- source/blender/makesrna/intern/SConscript | 10 +- source/blender/makesrna/intern/main_api.c | 26 ++ source/blender/makesrna/intern/mesh_api.c | 42 ++++ source/blender/makesrna/intern/rna_api.c | 299 +++++++++++++++++++++++ source/blender/makesrna/intern/rna_context.c | 5 - source/blender/makesrna/intern/rna_internal.h | 24 +- source/blender/makesrna/intern/rna_main.c | 8 +- source/blender/makesrna/intern/rna_mesh.c | 13 +- source/blender/makesrna/intern/rna_wm.c | 2 + source/blender/makesrna/intern/wm_api.c | 9 + source/blender/python/intern/bpy_operator_wrap.c | 2 +- 14 files changed, 412 insertions(+), 298 deletions(-) delete mode 100644 source/blender/editors/interface/interface_api.c create mode 100644 source/blender/makesrna/intern/main_api.c create mode 100644 source/blender/makesrna/intern/mesh_api.c create mode 100644 source/blender/makesrna/intern/rna_api.c create mode 100644 source/blender/makesrna/intern/wm_api.c diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript index bac3742c12f..a05756ed9c6 100644 --- a/source/blender/editors/interface/SConscript +++ b/source/blender/editors/interface/SConscript @@ -3,8 +3,8 @@ Import ('env') sources = env.Glob('*.c') -for source in env.Glob('*_api.c'): - sources.remove(source) +# for source in env.Glob('*_api.c'): +# sources.remove(source) incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc' diff --git a/source/blender/editors/interface/interface_api.c b/source/blender/editors/interface/interface_api.c deleted file mode 100644 index b4e7dc03506..00000000000 --- a/source/blender/editors/interface/interface_api.c +++ /dev/null @@ -1,240 +0,0 @@ -/** - * $Id: - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include - -#include "RNA_define.h" -#include "RNA_types.h" - -#include "UI_interface.h" - -static void api_ui_item_common(FunctionRNA *func) -{ - RNA_def_string(func, "text", "", 0, "", "Override automatic text of the item."); - RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Override automatic icon of the item.", 0, INT_MAX); -} - -static void api_ui_item_op_common(FunctionRNA *func) -{ - PropertyRNA *parm; - - api_ui_item_common(func); - parm= RNA_def_string(func, "operator", "", 0, "", "Identifier of the operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); -} - -void RNA_api_ui_layout(StructRNA *srna) -{ - FunctionRNA *func; - PropertyRNA *parm; - - static EnumPropertyItem curve_type_items[] = { - {0, "NONE", "None", ""}, - {'v', "VECTOR", "Vector", ""}, - {'c', "COLOR", "Color", ""}, - {0, NULL, NULL, NULL}}; - - /* simple layout specifiers */ - func= RNA_def_function(srna, "row", "uiLayoutRow"); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); - - func= RNA_def_function(srna, "column", "uiLayoutColumn"); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); - - func= RNA_def_function(srna, "column_flow", "uiLayoutColumnFlow"); - parm= RNA_def_int(func, "columns", 0, 0, INT_MAX, "", "Number of columns, 0 is automatic.", 0, INT_MAX); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); - - /* box layout */ - func= RNA_def_function(srna, "box", "uiLayoutBox"); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - - /* split layout */ - func= RNA_def_function(srna, "split", "uiLayoutSplit"); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - RNA_def_float(func, "percentage", 0.5f, 0.0f, 1.0f, "Percentage", "Percentage of width to split at.", 0.0f, 1.0f); - - /* items */ - func= RNA_def_function(srna, "itemR", "uiItemR"); - api_ui_item_common(func); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); - RNA_def_boolean(func, "slider", 0, "", "Use slider widget for numeric values."); - RNA_def_boolean(func, "toggle", 0, "", "Use toggle widget for boolean values."); - - func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "item_menu_enumR", "uiItemMenuEnumR"); - api_ui_item_common(func); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - /*func= RNA_def_function(srna, "item_enumR", "uiItemEnumR"); - api_ui_item_common(func); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "value", "", 0, "", "Enum property value."); - RNA_def_property_flag(parm, PROP_REQUIRED);*/ - - func= RNA_def_function(srna, "itemO", "uiItemO"); - api_ui_item_op_common(func); - - func= RNA_def_function(srna, "item_enumO", "uiItemEnumO_string"); - api_ui_item_op_common(func); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "value", "", 0, "", "Enum property value."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "items_enumO", "uiItemsEnumO"); - parm= RNA_def_string(func, "operator", "", 0, "", "Identifier of the operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "item_menu_enumO", "uiItemMenuEnumO"); - api_ui_item_op_common(func); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "item_booleanO", "uiItemBooleanO"); - api_ui_item_op_common(func); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_boolean(func, "value", 0, "", "Value of the property to call the operator with."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "item_intO", "uiItemIntO"); - api_ui_item_op_common(func); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_int(func, "value", 0, INT_MIN, INT_MAX, "", "Value of the property to call the operator with.", INT_MIN, INT_MAX); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "item_floatO", "uiItemFloatO"); - api_ui_item_op_common(func); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_float(func, "value", 0, -FLT_MAX, FLT_MAX, "", "Value of the property to call the operator with.", -FLT_MAX, FLT_MAX); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "item_stringO", "uiItemStringO"); - api_ui_item_op_common(func); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "value", "", 0, "", "Value of the property to call the operator with."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "itemL", "uiItemL"); - api_ui_item_common(func); - - func= RNA_def_function(srna, "itemM", "uiItemM"); - parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); - RNA_def_property_flag(parm, PROP_REQUIRED); - api_ui_item_common(func); - parm= RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "itemS", "uiItemS"); - - /* context */ - func= RNA_def_function(srna, "set_context_pointer", "uiLayoutSetContextPointer"); - parm= RNA_def_string(func, "name", "", 0, "Name", "Name of entry in the context."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Pointer to put in context."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - /* templates */ - func= RNA_def_function(srna, "template_header", "uiTemplateHeader"); - parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "template_ID", "uiTemplateID"); - parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of pointer property in data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block."); - RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a new ID block."); - RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block."); - - func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Modifier data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "template_constraint", "uiTemplateConstraint"); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Constraint data."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "template_preview", "uiTemplatePreview"); - parm= RNA_def_pointer(func, "id", "ID", "", "ID datablock."); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping"); - parm= RNA_def_pointer(func, "curvemap", "CurveMapping", "", "Curve mapping pointer."); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_enum(func, "type", curve_type_items, 0, "Type", "Type of curves to display."); - - func= RNA_def_function(srna, "template_color_ramp", "uiTemplateColorRamp"); - parm= RNA_def_pointer(func, "ramp", "ColorRamp", "", "Color ramp pointer."); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); - - func= RNA_def_function(srna, "template_layers", "uiTemplateLayers"); - parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "property", "", 0, "", "Identifier of pointer property in data."); - RNA_def_property_flag(parm, PROP_REQUIRED); -} - diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 33174e31df5..b6cc57990a3 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -2028,35 +2028,11 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc) } } -/* Python API */ -void copy_mesh_data(Mesh *dest, Mesh *src); - -Mesh *RNA_api_add_mesh(Main *main, char *name) -{ - return add_mesh(name); -} - -void RNA_api_mesh_copy(Mesh *me, Mesh *from) -{ - copy_mesh_data(me, from); -} - -void RNA_api_mesh_copy_applied(Mesh *me, Scene *sce, Object *ob) -{ - DerivedMesh *dm= mesh_create_derived_view(sce, ob, CD_MASK_MESH); - DM_to_mesh(dm, me); - dm->release(dm); -} - -void RNA_api_mesh_transform(Mesh *me, float **mat) -{ -} - /* * This version of copy_mesh doesn't allocate a new mesh, * instead it copies data between two existing meshes. * - * XXX is this already possible with DerivedMesh? + * XXX not used anywhere... */ void copy_mesh_data(Mesh *dest, Mesh *src) { diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 9c8e00da16d..0ad14553bfb 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -13,12 +13,17 @@ root_build_dir=normpath(env['BF_BUILDDIR']) source_files = env.Glob('*.c') source_files.remove('rna_access.c') +api_runtime_files = env.Glob('*_api.c') +for api_file in api_runtime_files: + source_files.remove(api_file) + generated_files = source_files[:] generated_files.remove('rna_define.c') generated_files.remove('makesrna.c') generated_files = [filename[:-2] + '_gen.c' for filename in generated_files] -source_files.extend(env.Glob('../../editors/*/*_api.c')) +# source_files.extend(env.Glob('../../editors/*/*_api.c')) +source_files.extend(env.Glob('rna_api.c')) makesrna_tool = env.Clone() rna = env.Clone() @@ -110,8 +115,9 @@ else: rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna.exe " + build_dir) +api_runtime_files.remove('rna_api.c') obj = ['intern/rna_access.c'] -for generated_file in generated_files: +for generated_file in generated_files + api_runtime_files: obj += ['intern/' + generated_file] Return ('obj') diff --git a/source/blender/makesrna/intern/main_api.c b/source/blender/makesrna/intern/main_api.c new file mode 100644 index 00000000000..5d9e1f5e580 --- /dev/null +++ b/source/blender/makesrna/intern/main_api.c @@ -0,0 +1,26 @@ +#include + +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_library.h" + +#include "BLI_listbase.h" + +#include "DNA_mesh_types.h" + +Mesh *RNA_api_main_add_mesh(Main *main, char *name) +{ + return add_mesh(name); +} + +void RNA_api_main_remove_mesh(Main *main, Mesh *me) +{ + if (BLI_findindex(&main->mesh, me) == -1) { + /* XXX report error */ + return; + } + + /* XXX correct ? */ + if (me->id.us == 1) + free_libblock(&main->mesh, me); +} diff --git a/source/blender/makesrna/intern/mesh_api.c b/source/blender/makesrna/intern/mesh_api.c new file mode 100644 index 00000000000..e9437e29f81 --- /dev/null +++ b/source/blender/makesrna/intern/mesh_api.c @@ -0,0 +1,42 @@ +#include + +#include "DNA_mesh_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" + +#include "BKE_DerivedMesh.h" +#include "BKE_mesh.h" + + +/* +void RNA_api_mesh_copy(Mesh *me, Mesh *from) +{ + copy_mesh_data(me, from); +} + +void RNA_api_mesh_copy_applied(Mesh *me, Scene *sce, Object *ob) +{ + DerivedMesh *dm= mesh_create_derived_view(sce, ob, CD_MASK_MESH); + DM_to_mesh(dm, me); + dm->release(dm); +} +*/ + +/* copied from init_render_mesh (render code) */ +void RNA_api_mesh_make_rendermesh(Mesh *me, Scene *sce, Object *ob) +{ + CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; + DerivedMesh *dm= mesh_create_derived_render(sce, ob, mask); + + /* XXX report reason */ + if(dm==NULL) return; + + DM_to_mesh(dm, me); + dm->release(dm); +} + +void RNA_api_mesh_transform(Mesh *me, float **mat) +{ +} diff --git a/source/blender/makesrna/intern/rna_api.c b/source/blender/makesrna/intern/rna_api.c new file mode 100644 index 00000000000..fa594c5929e --- /dev/null +++ b/source/blender/makesrna/intern/rna_api.c @@ -0,0 +1,299 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "UI_interface.h" + + +void RNA_api_main(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *prop; + + func= RNA_def_function(srna, "add_mesh", "RNA_api_main_add_mesh"); + RNA_def_function_ui_description(func, "Add a new mesh."); + prop= RNA_def_string(func, "name", "", 0, "", "New name for the datablock."); + RNA_def_property_flag(prop, PROP_REQUIRED); + prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A new mesh."); + RNA_def_function_return(func, prop); + + func= RNA_def_function(srna, "remove_mesh", "RNA_api_main_remove_mesh"); + RNA_def_function_ui_description(func, "Remove a mesh if it has only one user."); + prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A mesh to remove."); + RNA_def_property_flag(prop, PROP_REQUIRED); +} + +void RNA_api_mesh(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *prop; + + /* + func= RNA_def_function(srna, "copy", "RNA_api_mesh_copy"); + RNA_def_function_ui_description(func, "Copy mesh data."); + prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from."); + RNA_def_property_flag(prop, PROP_REQUIRED);*/ + + func= RNA_def_function(srna, "make_rendermesh", "RNA_api_mesh_make_rendermesh"); + RNA_def_function_ui_description(func, "Copy mesh data from object with all modifiers applied."); + prop= RNA_def_pointer(func, "sce", "Scene", "", "Scene."); + RNA_def_property_flag(prop, PROP_REQUIRED); + prop= RNA_def_pointer(func, "ob", "Object", "", "Object to copy data from."); + RNA_def_property_flag(prop, PROP_REQUIRED); + + /* + func= RNA_def_function(srna, "add_geom", "RNA_api_mesh_add_geom"); + RNA_def_function_ui_description(func, "Add geometry data to mesh."); + prop= RNA_def_collection(func, "verts", "?", "", "Vertices."); + RNA_def_property_flag(prop, PROP_REQUIRED); + prop= RNA_def_collection(func, "faces", "?", "", "Faces."); + RNA_def_property_flag(prop, PROP_REQUIRED); + */ +} + +void RNA_api_wm(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *prop; + + func= RNA_def_function(srna, "add_fileselect", "RNA_api_wm_add_fileselect"); + RNA_def_function_ui_description(func, "Show up the file selector."); + prop= RNA_def_pointer(func, "context", "Context", "", "Context."); + RNA_def_property_flag(prop, PROP_REQUIRED); + prop= RNA_def_pointer(func, "op", "Operator", "", "Operator to call."); + RNA_def_property_flag(prop, PROP_REQUIRED); +} + +static void api_ui_item_common(FunctionRNA *func) +{ + RNA_def_string(func, "text", "", 0, "", "Override automatic text of the item."); + RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Override automatic icon of the item.", 0, INT_MAX); +} + +static void api_ui_item_op_common(FunctionRNA *func) +{ + PropertyRNA *parm; + + api_ui_item_common(func); + parm= RNA_def_string(func, "operator", "", 0, "", "Identifier of the operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); +} + +void RNA_api_ui_layout(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + static EnumPropertyItem curve_type_items[] = { + {0, "NONE", "None", ""}, + {'v', "VECTOR", "Vector", ""}, + {'c', "COLOR", "Color", ""}, + {0, NULL, NULL, NULL}}; + + /* simple layout specifiers */ + func= RNA_def_function(srna, "row", "uiLayoutRow"); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); + + func= RNA_def_function(srna, "column", "uiLayoutColumn"); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); + + func= RNA_def_function(srna, "column_flow", "uiLayoutColumnFlow"); + parm= RNA_def_int(func, "columns", 0, 0, INT_MAX, "", "Number of columns, 0 is automatic.", 0, INT_MAX); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_boolean(func, "align", 0, "", "Align buttons to each other."); + + /* box layout */ + func= RNA_def_function(srna, "box", "uiLayoutBox"); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + + /* split layout */ + func= RNA_def_function(srna, "split", "uiLayoutSplit"); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + RNA_def_float(func, "percentage", 0.5f, 0.0f, 1.0f, "Percentage", "Percentage of width to split at.", 0.0f, 1.0f); + + /* items */ + func= RNA_def_function(srna, "itemR", "uiItemR"); + api_ui_item_common(func); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); + RNA_def_boolean(func, "slider", 0, "", "Use slider widget for numeric values."); + RNA_def_boolean(func, "toggle", 0, "", "Use toggle widget for boolean values."); + + func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_menu_enumR", "uiItemMenuEnumR"); + api_ui_item_common(func); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /*func= RNA_def_function(srna, "item_enumR", "uiItemEnumR"); + api_ui_item_common(func); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "value", "", 0, "", "Enum property value."); + RNA_def_property_flag(parm, PROP_REQUIRED);*/ + + func= RNA_def_function(srna, "itemO", "uiItemO"); + api_ui_item_op_common(func); + + func= RNA_def_function(srna, "item_enumO", "uiItemEnumO_string"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "value", "", 0, "", "Enum property value."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "items_enumO", "uiItemsEnumO"); + parm= RNA_def_string(func, "operator", "", 0, "", "Identifier of the operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_menu_enumO", "uiItemMenuEnumO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_booleanO", "uiItemBooleanO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_boolean(func, "value", 0, "", "Value of the property to call the operator with."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_intO", "uiItemIntO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_int(func, "value", 0, INT_MIN, INT_MAX, "", "Value of the property to call the operator with.", INT_MIN, INT_MAX); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_floatO", "uiItemFloatO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_float(func, "value", 0, -FLT_MAX, FLT_MAX, "", "Value of the property to call the operator with.", -FLT_MAX, FLT_MAX); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "item_stringO", "uiItemStringO"); + api_ui_item_op_common(func); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "value", "", 0, "", "Value of the property to call the operator with."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "itemL", "uiItemL"); + api_ui_item_common(func); + + func= RNA_def_function(srna, "itemM", "uiItemM"); + parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); + RNA_def_property_flag(parm, PROP_REQUIRED); + api_ui_item_common(func); + parm= RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "itemS", "uiItemS"); + + /* context */ + func= RNA_def_function(srna, "set_context_pointer", "uiLayoutSetContextPointer"); + parm= RNA_def_string(func, "name", "", 0, "Name", "Name of entry in the context."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Pointer to put in context."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /* templates */ + func= RNA_def_function(srna, "template_header", "uiTemplateHeader"); + parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "template_ID", "uiTemplateID"); + parm= RNA_def_pointer(func, "context", "Context", "", "Current context."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of pointer property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block."); + RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a new ID block."); + RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block."); + + func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Modifier data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "template_constraint", "uiTemplateConstraint"); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Constraint data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "template_preview", "uiTemplatePreview"); + parm= RNA_def_pointer(func, "id", "ID", "", "ID datablock."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping"); + parm= RNA_def_pointer(func, "curvemap", "CurveMapping", "", "Curve mapping pointer."); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_enum(func, "type", curve_type_items, 0, "Type", "Type of curves to display."); + + func= RNA_def_function(srna, "template_color_ramp", "uiTemplateColorRamp"); + parm= RNA_def_pointer(func, "ramp", "ColorRamp", "", "Color ramp pointer."); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); + + func= RNA_def_function(srna, "template_layers", "uiTemplateLayers"); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of pointer property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); +} diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index b1ecf2c3a86..6bab4206dc6 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -146,11 +146,6 @@ void RNA_def_context(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Scene"); RNA_def_property_pointer_funcs(prop, "rna_Context_scene_get", NULL, NULL); - - func= RNA_def_function(srna, "add_fileselect", "WM_event_add_fileselect"); - RNA_def_function_ui_description(func, "Show up the file selector."); - prop= RNA_def_pointer(func, "op", "Operator", "", "Operator to call."); - RNA_def_property_flag(prop, PROP_REQUIRED); } #endif diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 467e0dabb24..f38c3aac71d 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -188,15 +188,29 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch /* API functions */ +void RNA_api_ui_layout(struct StructRNA *srna); +void RNA_api_mesh(struct StructRNA *srna); +void RNA_api_wm(struct StructRNA *srna); +void RNA_api_main(StructRNA *srna); + +#ifdef RNA_RUNTIME + +struct wmWindowManager; +struct bContext; +struct wmOperator; struct Main; +struct Mesh; struct Scene; struct Object; -struct Mesh; -void RNA_api_ui_layout(struct StructRNA *srna); -struct Mesh *RNA_api_add_mesh(struct Main *main, char *name); -void RNA_api_mesh_copy(struct Mesh *me, struct Mesh *from); -void RNA_api_mesh_copy_applied(struct Mesh *me, struct Scene *sce, struct Object *ob); +void RNA_api_wm_add_fileselect(struct wmWindowManager *self, struct bContext *C, struct wmOperator *op); + +struct Mesh *RNA_api_main_add_mesh(struct Main *main, char *name); +void RNA_api_main_remove_mesh(struct Main *main, struct Mesh *me); + +void RNA_api_mesh_make_rendermesh(struct Mesh *me, struct Scene *sce, struct Object *ob); + +#endif /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 22f19d725cb..78e1c7fb435 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -33,6 +33,7 @@ #ifdef RNA_RUNTIME #include "BKE_main.h" +#include "BKE_mesh.h" /* all the list begin functions are added manually here, Main is not in SDNA */ @@ -268,12 +269,7 @@ void RNA_def_main(BlenderRNA *brna) RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]); } - func= RNA_def_function(srna, "add_mesh", "RNA_api_add_mesh"); - RNA_def_function_ui_description(func, "Add a new mesh."); - prop= RNA_def_string(func, "name", "", 0, "", "New name for the datablock."); - RNA_def_property_flag(prop, PROP_REQUIRED); - prop= RNA_def_pointer(func, "mesh", "Mesh", "", "A new mesh."); - RNA_def_function_return(func, prop); + RNA_api_main(srna); } #endif diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index ec58d695105..d7b17490826 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1071,7 +1071,6 @@ static void rna_def_mesh(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - FunctionRNA *func; srna= RNA_def_struct(brna, "Mesh", "ID"); RNA_def_struct_ui_text(srna, "Mesh", "Mesh datablock to define geometric surfaces."); @@ -1156,17 +1155,7 @@ static void rna_def_mesh(BlenderRNA *brna) rna_def_texmat_common(srna, "rna_Mesh_texspace_editable"); - func= RNA_def_function(srna, "copy", "RNA_api_mesh_copy"); - RNA_def_function_ui_description(func, "Copy mesh data."); - prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from."); - RNA_def_property_flag(prop, PROP_REQUIRED); - - func= RNA_def_function(srna, "copy_applied", "RNA_api_mesh_copy_applied"); - RNA_def_function_ui_description(func, "Copy mesh data from object with all modifiers applied."); - prop= RNA_def_pointer(func, "sce", "Scene", "", "Scene."); - RNA_def_property_flag(prop, PROP_REQUIRED); - prop= RNA_def_pointer(func, "ob", "Object", "", "Object to copy data from."); - RNA_def_property_flag(prop, PROP_REQUIRED); + RNA_api_mesh(srna); } void RNA_def_mesh(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 22ce207c6a9..df07e03850a 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -160,6 +160,8 @@ static void rna_def_windowmanager(BlenderRNA *brna) prop= RNA_def_property(srna, "operators", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Operator"); RNA_def_property_ui_text(prop, "Operators", "Operator registry."); + + RNA_api_wm(srna); } void RNA_def_wm(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/wm_api.c b/source/blender/makesrna/intern/wm_api.c new file mode 100644 index 00000000000..a00c401b683 --- /dev/null +++ b/source/blender/makesrna/intern/wm_api.c @@ -0,0 +1,9 @@ +#include "WM_api.h" + +#include "BKE_context.h" + +void RNA_api_wm_add_fileselect(wmWindowManager *self, bContext *C, wmOperator *op) +{ + WM_event_add_fileselect(C, op); +} + diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 4624fe764b3..c0fac17dd97 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -225,7 +225,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyObject *ret= NULL, *py_class_instance, *item= NULL; int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); PointerRNA ptr_context; - PyObject ptr_operator; + PointerRNA ptr_operator; PyObject *py_operator; PyGILState_STATE gilstate = PyGILState_Ensure(); -- cgit v1.2.3 From 5d78f56c1fb1208329ba9c40eaff6ee4a8cd59bb Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 19 Jun 2009 10:40:18 +0000 Subject: - added Object.create_dupli_list, Object.free_dupli_list - attempted to RNA-wrap DupliObject, Object.create_dupli_list returns a collection of these. Build fails probably because DupliObject is not defined in one of DNA_*.h headers. --- source/blender/makesrna/intern/rna_object.c | 30 ++++++++ source/blender/makesrna/intern/rna_object_api.c | 96 +++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index ff9777d283e..36e2ba2d8aa 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1113,12 +1113,42 @@ static void rna_def_object(BlenderRNA *brna) RNA_api_object(srna); } +static void rna_def_dupli_object(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "DupliObject", NULL); + RNA_def_struct_sdna(srna, "DupliObject"); + RNA_def_struct_ui_text(srna, "Dupli Object", "Dupli Object data."); + /* RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA); */ + + prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "ob"); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Object", "Object this DupliObject represents."); + + prop= RNA_def_property(srna, "ob_matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "omat"); + RNA_def_property_array(prop, 16); + RNA_def_property_ui_text(prop, "Object Matrix", "Object transformation matrix."); + + prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "mat"); + RNA_def_property_array(prop, 16); + RNA_def_property_ui_text(prop, "DupliObject Matrix", "DupliObject transformation matrix."); + + /* TODO: DupliObject has more properties that can be wrapped */ +} + void RNA_def_object(BlenderRNA *brna) { rna_def_object(brna); rna_def_object_game_settings(brna); rna_def_vertex_group(brna); rna_def_material_slot(brna); + rna_def_dupli_object(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 053ab115b3b..e54c8c712c1 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -32,13 +32,18 @@ #include "RNA_define.h" #include "RNA_types.h" +#define OBJECT_API_PROP_DUPLILIST "dupli_list" + #ifdef RNA_RUNTIME #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" +#include "BKE_anim.h" +#include "BKE_report.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" +#include "DNA_object_types.h" /* copied from init_render_mesh (render code) */ Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene) @@ -64,19 +69,100 @@ Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene) return me; } +/* When no longer needed, duplilist should be freed with Object.free_duplilist */ +void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) +{ + PointerRNA obptr; + PointerRNA dobptr; + Scene *sce; + ListBase *lb; + DupliObject *dob; + PropertyRNA *prop; + + if (!(ob->transflag & OB_DUPLI)) { + BKE_report(reports, RPT_ERROR, "Object does not have duplis."); + return; + } + + sce= CTX_data_scene(C); + + RNA_id_pointer_create(&ob->id, &obptr); + + if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { + // hint: all Objects will now have this property defined + prop= RNA_def_collection_runtime(obptr->type, OBJECT_API_PROP_DUPLILIST, "DupliObject", "Dupli list", "List of object's duplis"); + } + + RNA_property_collection_clear(&obptr, prop); + lb= object_duplilist(sce, ob); + + for(dob= (DupliObject*)lb->first; dob; dob= dob->next) { + RNA_pointer_create(NULL, &RNA_Object, dob, &dobptr); + RNA_property_collection_add(&obptr, prop, &dobptr); + dob = dob->next; + } + + /* + Now we need to free duplilist with + + free_object_duplilist(lb); + + We can't to it here since DupliObjects are in use, + but we also can't do it in another function since lb + isn't stored... + + So we free lb, but not DupliObjects - these will have to be freed with Object.free_duplilist + */ + + MEM_freeN(lb); +} + +void rna_Object_free_duplilist(Object *ob, ReportList *reports) +{ + PointerRNA obptr; + PropertyRNA *prop; + CollectionPropertyIterator iter; + + RNA_id_pointer_create(&ob->id, &obptr); + + if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { + BKE_report(reports, RPT_ERROR, "Object has no duplilist property."); + return; + } + + /* free each allocated DupliObject */ + RNA_property_collection_begin(&obptr, prop, &iter); + for(; iter.valid; RNA_property_collection_next(&iter)) { + MEM_freeN(iter.ptr.data); + } + RNA_property_collection_end(&iter); + + RNA_property_collection_clear(&obptr, prop); +} + #else void RNA_api_object(StructRNA *srna) { FunctionRNA *func; - PropertyRNA *prop; + PropertyRNA *parm; func= RNA_def_function(srna, "create_render_mesh", "rna_Object_create_render_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); - prop= RNA_def_pointer(func, "scene", "Scene", "", ""); - RNA_def_property_flag(prop, PROP_REQUIRED); - prop= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); - RNA_def_function_return(func, prop); + parm= RNA_def_pointer(func, "scene", "Scene", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist"); + RNA_def_function_ui_description(func, "Create a list of dupli objects for this object. When no longer needed, it should be freed with free_dupli_list."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); + parm= RNA_def_collection(func, OBJECT_API_PROP_DUPLILIST, "DupliObject", "Dupli list", "List of objects's duplis."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "free_dupli_list", "rna_Object_free_duplilist"); + RNA_def_function_ui_description(func, "Free the list of dupli objects."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); } #endif -- cgit v1.2.3 From f6267e2a26cac8c7b30c7b165df1df54e9cec474 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 19 Jun 2009 12:46:51 +0000 Subject: Moved struct DupliObject to DNA_object_types.h. Object.create_dupli_list now works ok. --- release/io/export_obj.py | 14 ++++++++- source/blender/blenkernel/BKE_anim.h | 9 +----- source/blender/makesdna/DNA_object_types.h | 9 ++++++ source/blender/makesrna/intern/rna_object_api.c | 38 +++++++------------------ 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 4354f9f9bb9..8b3bcfb26b3 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -41,7 +41,7 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): def debug(self, message): print("{0}: {1}".format(self.__class__.__name__, message)) - def execute(self, context): + def execute_(self, context): self.debug("exec") self.debug("filename = " + self.filename) @@ -56,6 +56,18 @@ class SCRIPT_OT_export_obj(bpy.types.Operator): # raise Exception("oops!") return ('FINISHED',) + + def execute(self, context): + self.debug("exec") + + act = context.active_object + + act.create_dupli_list() + print("{0} has {1} dupli objects".format(act.name, len(act.dupli_list))) + + act.free_dupli_list() + + return ('FINISHED',) def invoke(self, context, event): self.debug("invoke") diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 5ea511738ad..091887a4eb7 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -39,14 +39,7 @@ struct PartEff; struct Scene; struct ListBase; -typedef struct DupliObject { - struct DupliObject *next, *prev; - struct Object *ob; - unsigned int origlay; - int index, no_draw, type, animated; - float mat[4][4], omat[4][4]; - float orco[3], uv[2]; -} DupliObject; +#include "DNA_object_types.h" void free_path(struct Path *path); void calc_curvepath(struct Object *ob); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index febf2fe59cd..445a948c5cb 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -230,6 +230,7 @@ typedef struct Object { int pad2; ListBase gpulamp; /* runtime, for lamps only */ + ListBase *duplilist; /* only for internal use by RNA API functions. To get dupli list, use object_duplilist instead */ } Object; /* Warning, this is not used anymore because hooks are now modifiers */ @@ -250,6 +251,14 @@ typedef struct ObHook { float force; } ObHook; +typedef struct DupliObject { + struct DupliObject *next, *prev; + struct Object *ob; + unsigned int origlay; + int index, no_draw, type, animated; + float mat[4][4], omat[4][4]; + float orco[3], uv[2]; +} DupliObject; /* this work object is defined in object.c */ extern Object workob; diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index e54c8c712c1..3944dd72cec 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -32,8 +32,6 @@ #include "RNA_define.h" #include "RNA_types.h" -#define OBJECT_API_PROP_DUPLILIST "dupli_list" - #ifdef RNA_RUNTIME #include "BKE_customdata.h" @@ -45,6 +43,8 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" +#define OBJECT_API_PROP_DUPLILIST "dupli_list" + /* copied from init_render_mesh (render code) */ Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene) { @@ -75,7 +75,6 @@ void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) PointerRNA obptr; PointerRNA dobptr; Scene *sce; - ListBase *lb; DupliObject *dob; PropertyRNA *prop; @@ -90,38 +89,27 @@ void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { // hint: all Objects will now have this property defined - prop= RNA_def_collection_runtime(obptr->type, OBJECT_API_PROP_DUPLILIST, "DupliObject", "Dupli list", "List of object's duplis"); + prop= RNA_def_collection_runtime(obptr.type, OBJECT_API_PROP_DUPLILIST, "DupliObject", "Dupli list", "List of object's duplis"); } RNA_property_collection_clear(&obptr, prop); - lb= object_duplilist(sce, ob); + ob->duplilist= object_duplilist(sce, ob); - for(dob= (DupliObject*)lb->first; dob; dob= dob->next) { + for(dob= (DupliObject*)ob->duplilist->first; dob; dob= dob->next) { RNA_pointer_create(NULL, &RNA_Object, dob, &dobptr); RNA_property_collection_add(&obptr, prop, &dobptr); dob = dob->next; } - /* - Now we need to free duplilist with - - free_object_duplilist(lb); - - We can't to it here since DupliObjects are in use, - but we also can't do it in another function since lb - isn't stored... + /* ob->duplilist should now be freed with Object.free_duplilist */ - So we free lb, but not DupliObjects - these will have to be freed with Object.free_duplilist - */ - - MEM_freeN(lb); + return *((CollectionPropertyRNA*)prop); } void rna_Object_free_duplilist(Object *ob, ReportList *reports) { PointerRNA obptr; PropertyRNA *prop; - CollectionPropertyIterator iter; RNA_id_pointer_create(&ob->id, &obptr); @@ -130,14 +118,10 @@ void rna_Object_free_duplilist(Object *ob, ReportList *reports) return; } - /* free each allocated DupliObject */ - RNA_property_collection_begin(&obptr, prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - MEM_freeN(iter.ptr.data); - } - RNA_property_collection_end(&iter); - RNA_property_collection_clear(&obptr, prop); + + free_object_duplilist(ob->duplilist); + ob->duplilist= NULL; } #else @@ -157,8 +141,6 @@ void RNA_api_object(StructRNA *srna) func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist"); RNA_def_function_ui_description(func, "Create a list of dupli objects for this object. When no longer needed, it should be freed with free_dupli_list."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_collection(func, OBJECT_API_PROP_DUPLILIST, "DupliObject", "Dupli list", "List of objects's duplis."); - RNA_def_function_return(func, parm); func= RNA_def_function(srna, "free_dupli_list", "rna_Object_free_duplilist"); RNA_def_function_ui_description(func, "Free the list of dupli objects."); -- cgit v1.2.3 From 705fbec7688c88a801c41bb3c8889cd0527adc30 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 20 Jun 2009 16:32:52 +0000 Subject: * Added Main.add_object(type, name) * Added optional params to Object.create_render_mesh(apply_matrix, custom_matrix) apply_matrix is a boolean, True to transform mesh by ob->obmat or custom_matrix if given * Fix subtle error in Object.create_dupli_list * Make RNA struct funcs static, hopefully didn't miss any Ignore export_obj-2.5.py changes for now ;) --- release/scripts/export_obj-2.5.py | 11 ++++++ source/blender/makesrna/intern/rna_main_api.c | 50 +++++++++++++++++++++---- source/blender/makesrna/intern/rna_object_api.c | 49 ++++++++++++++++++++---- 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py index e0b417d4ce5..a9abba22944 100644 --- a/release/scripts/export_obj-2.5.py +++ b/release/scripts/export_obj-2.5.py @@ -347,6 +347,17 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): face_vert_index = 1 globalNormals = {} + + for ob_main in objects: + + if ob_main.dupli_type != 'NONE': + ob_main.create_dupli_list() + + if ob_main.parent: + pass + + if ob_main.dupli_type != 'NONE': + ob_main.free_dupli_list() # Get all meshes for ob_main in objects: diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 6d56b2b00f9..2c78884a027 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -32,22 +32,25 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "DNA_object_types.h" + #ifdef RNA_RUNTIME #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_library.h" +#include "BKE_object.h" #include "DNA_mesh_types.h" -Mesh *rna_Main_add_mesh(Main *main, char *name) +static Mesh *rna_Main_add_mesh(Main *main, char *name) { Mesh *me= add_mesh(name); me->id.us--; return me; } -void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) +static void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) { if(me->id.us == 0) free_libblock(&main->mesh, me); @@ -57,24 +60,55 @@ void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) /* XXX python now has invalid pointer? */ } +static Object* rna_Main_add_object(Main *main, int type, char *name) +{ + return add_only_object(type, name); +} + #else void RNA_api_main(StructRNA *srna) { FunctionRNA *func; - PropertyRNA *prop; + PropertyRNA *parm; + + /* copied from rna_def_object */ + static EnumPropertyItem object_type_items[] = { + {OB_EMPTY, "EMPTY", 0, "Empty", ""}, + {OB_MESH, "MESH", 0, "Mesh", ""}, + {OB_CURVE, "CURVE", 0, "Curve", ""}, + {OB_SURF, "SURFACE", 0, "Surface", ""}, + {OB_FONT, "TEXT", 0, "Text", ""}, + {OB_MBALL, "META", 0, "Meta", ""}, + {OB_LAMP, "LAMP", 0, "Lamp", ""}, + {OB_CAMERA, "CAMERA", 0, "Camera", ""}, + {OB_WAVE, "WAVE", 0, "Wave", ""}, + {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, + {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, + {0, NULL, 0, NULL, NULL}}; + + func= RNA_def_function(srna, "add_object", "rna_Main_add_object"); + RNA_def_function_ui_description(func, "Add a new object."); + parm= RNA_def_enum(func, "type", object_type_items, 0, "Type", "Type of Object."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "name", "Object", 0, "", "New name for the datablock."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "object", "Object", "", "New object."); + RNA_def_function_return(func, parm); func= RNA_def_function(srna, "add_mesh", "rna_Main_add_mesh"); RNA_def_function_ui_description(func, "Add a new mesh."); - prop= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock."); - prop= RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh."); - RNA_def_function_return(func, prop); + parm= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "mesh", "Mesh", "", "New mesh."); + RNA_def_function_return(func, parm); func= RNA_def_function(srna, "remove_mesh", "rna_Main_remove_mesh"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a mesh if it has zero users."); - prop= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove."); - RNA_def_property_flag(prop, PROP_REQUIRED); + parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove."); + RNA_def_property_flag(parm, PROP_REQUIRED); + } #endif diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index d7f6f85eff4..61f074c00ab 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -32,6 +32,8 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "DNA_object_types.h" + #ifdef RNA_RUNTIME #include "BKE_customdata.h" @@ -41,17 +43,19 @@ #include "DNA_mesh_types.h" #include "DNA_scene_types.h" -#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" #define OBJECT_API_PROP_DUPLILIST "dupli_list" /* copied from init_render_mesh (render code) */ -Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports) +static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports, int apply_matrix, float *matrix) { CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; DerivedMesh *dm; Mesh *me; Scene *sce; + int a; + MVert *mvert; sce= CTX_data_scene(C); @@ -73,11 +77,25 @@ Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports DM_to_mesh(dm, me); dm->release(dm); + if (apply_matrix) { + float *mat = ob->obmat; + + if (matrix) { + /* apply custom matrix */ + mat = matrix; + } + + /* is this really that simple? :) */ + for(a= 0, mvert= me->mvert; a < me->totvert; a++, mvert++) { + Mat4MulVecfl(ob->obmat, mvert->co); + } + } + return me; } /* When no longer needed, duplilist should be freed with Object.free_duplilist */ -void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) +static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) { PointerRNA obptr; PointerRNA dobptr; @@ -96,7 +114,7 @@ void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { // hint: all Objects will now have this property defined - prop= RNA_def_collection_runtime(obptr.type, OBJECT_API_PROP_DUPLILIST, "DupliObject", "Dupli list", "List of object's duplis"); + prop= RNA_def_collection_runtime(obptr.type, OBJECT_API_PROP_DUPLILIST, &RNA_DupliObject, "Dupli list", "List of object's duplis"); } RNA_property_collection_clear(&obptr, prop); @@ -109,11 +127,9 @@ void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) } /* ob->duplilist should now be freed with Object.free_duplilist */ - - return *((CollectionPropertyRNA*)prop); } -void rna_Object_free_duplilist(Object *ob, ReportList *reports) +static void rna_Object_free_duplilist(Object *ob, ReportList *reports) { PointerRNA obptr; PropertyRNA *prop; @@ -138,9 +154,28 @@ void RNA_api_object(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; + /* copied from rna_def_object */ + static EnumPropertyItem object_type_items[] = { + {OB_EMPTY, "EMPTY", 0, "Empty", ""}, + {OB_MESH, "MESH", 0, "Mesh", ""}, + {OB_CURVE, "CURVE", 0, "Curve", ""}, + {OB_SURF, "SURFACE", 0, "Surface", ""}, + {OB_FONT, "TEXT", 0, "Text", ""}, + {OB_MBALL, "META", 0, "Meta", ""}, + {OB_LAMP, "LAMP", 0, "Lamp", ""}, + {OB_CAMERA, "CAMERA", 0, "Camera", ""}, + {OB_WAVE, "WAVE", 0, "Wave", ""}, + {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, + {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, + {0, NULL, 0, NULL, NULL}}; + func= RNA_def_function(srna, "create_render_mesh", "rna_Object_create_render_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); + parm= RNA_def_boolean(func, "apply_matrix", 0, "", "True if object matrix or custom matrix should be applied to geometry."); + RNA_def_property_clear_flag(parm, PROP_REQUIRED); + parm= RNA_def_float_matrix(func, "custom_matrix", 16, NULL, 0.0f, 0.0f, "", "Optional custom matrix to apply.", 0.0f, 0.0f); + RNA_def_property_clear_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); -- cgit v1.2.3 From 01da493a0af3130652151640f867cfe6b4bc376a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 20 Jun 2009 20:08:11 +0000 Subject: * Object.create_dupli_list, Object.free_dupli_list tweaking * Defined custom "get" function for DupliObject.object Accessing Object.dupli_list[N].object produces a crash. --- source/blender/makesrna/intern/rna_object.c | 11 ++++++++++- source/blender/makesrna/intern/rna_object_api.c | 13 +++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 159362ef7e7..d566af1954c 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -364,6 +364,14 @@ static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values) } } +static PointerRNA rna_DupliObject_object_get(PointerRNA *ptr) +{ + DupliObject *dob= (DupliObject*)ptr->data; + PointerRNA newptr; + RNA_pointer_create(&dob->ob->id, &RNA_Object, dob->ob, &newptr); + return newptr; +} + #else static void rna_def_vertex_group(BlenderRNA *brna) @@ -1167,8 +1175,9 @@ static void rna_def_dupli_object(BlenderRNA *brna) /* RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA); */ prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "ob"); RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_pointer_sdna(prop, NULL, "ob"); + RNA_def_property_pointer_funcs(prop, "rna_DupliObject_object_get", NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Object", "Object this DupliObject represents."); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 61f074c00ab..c3740921f0f 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -108,20 +108,19 @@ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *rep return; } - sce= CTX_data_scene(C); - RNA_id_pointer_create(&ob->id, &obptr); if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { // hint: all Objects will now have this property defined - prop= RNA_def_collection_runtime(obptr.type, OBJECT_API_PROP_DUPLILIST, &RNA_DupliObject, "Dupli list", "List of object's duplis"); + prop= RNA_def_collection_runtime(obptr.type, OBJECT_API_PROP_DUPLILIST, &RNA_DupliObject, "Dupli list", ""); } RNA_property_collection_clear(&obptr, prop); + sce= CTX_data_scene(C); ob->duplilist= object_duplilist(sce, ob); for(dob= (DupliObject*)ob->duplilist->first; dob; dob= dob->next) { - RNA_pointer_create(NULL, &RNA_Object, dob, &dobptr); + RNA_pointer_create(NULL, &RNA_DupliObject, dob, &dobptr); RNA_property_collection_add(&obptr, prop, &dobptr); dob = dob->next; } @@ -143,8 +142,10 @@ static void rna_Object_free_duplilist(Object *ob, ReportList *reports) RNA_property_collection_clear(&obptr, prop); - free_object_duplilist(ob->duplilist); - ob->duplilist= NULL; + if (ob->duplilist) { + free_object_duplilist(ob->duplilist); + ob->duplilist= NULL; + } } #else -- cgit v1.2.3 From 10a4338936db1a196703ad0ad8f983c3ba503ac8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 21 Jun 2009 11:08:30 +0000 Subject: *fixs ray_shadow_jitter (area soft shadow) (detected with test249/render/arealight.blend) --- source/blender/render/intern/source/rayshade.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 10115dc97e9..4c72f80224a 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -2162,7 +2162,9 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa /* set start and vec */ VECCOPY(isec->start, shi->co); - VECCOPY(isec->vec, vec); + isec->vec[0] = vec[0]+lampco[0]-shi->co[0]; + isec->vec[1] = vec[1]+lampco[1]-shi->co[1]; + isec->vec[2] = vec[2]+lampco[2]-shi->co[2]; isec->labda = 1.0f; isec->skip = RE_SKIP_VLR_NEIGHBOUR; -- cgit v1.2.3 From 3fce2f282644a632fe2768ae516a50e394c1179f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 23 Jun 2009 17:52:58 +0000 Subject: - added Mesh.transform - fixed Object.create_dupli_list - continuing OBJ exporter conversion --- release/scripts/export_obj-2.5.py | 326 +++++++++++++++++++++++- source/blender/makesrna/intern/rna_mesh_api.c | 22 +- source/blender/makesrna/intern/rna_object.c | 6 + source/blender/makesrna/intern/rna_object_api.c | 38 +-- 4 files changed, 351 insertions(+), 41 deletions(-) diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py index a9abba22944..4fa02ce2efe 100644 --- a/release/scripts/export_obj-2.5.py +++ b/release/scripts/export_obj-2.5.py @@ -186,7 +186,7 @@ def copy_images(dest_dir): def test_nurbs_compat(ob): - if ob.type != 'Curve': + if ob.type != 'CURVE': return False for nu in ob.data: @@ -353,8 +353,328 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if ob_main.dupli_type != 'NONE': ob_main.create_dupli_list() - if ob_main.parent: - pass + # ignore dupli children + if ob_main.parent.dupli_type != 'NONE': + continue + + obs = [] + if ob_main.dupli_type != 'NONE': + obs = [(dob.matrix, dob.object) for dob in ob_main.dupli_list] + else: + obs = [ob.matrix, ob] + + for ob, ob_mat in obs: + # XXX postponed +# # Nurbs curve support +# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): +# if EXPORT_ROTX90: +# ob_mat = ob_mat * mat_xrot90 + +# totverts += write_nurb(file, ob, ob_mat) + +# continue +# end nurbs + +# # Will work for non meshes now! :) +# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) +# if not me: +# continue + + if ob.type != 'MESH': + continue + + me = ob.data + + # XXX +# if EXPORT_UV: +# faceuv= me.faceUV +# else: +# faceuv = False + + convert_to_tri = False + + # We have a valid mesh + if EXPORT_TRI and me.faces: + # Add a dummy object to it. + has_quads = False + for f in me.faces: +# if len(f) == 4: + if len(f.verts) == 4: + has_quads = True + break + + convert_to_tri = has_quads +# oldmode = Mesh.Mode() +# Mesh.Mode(Mesh.SelectModes['FACE']) + +# me.sel = True +# tempob = scn.objects.new(me) +# me.quadToTriangle(0) # more=0 shortest length +# oldmode = Mesh.Mode(oldmode) +# scn.objects.unlink(tempob) + +# Mesh.Mode(oldmode) + + if EXPORT_ROTX90: + ob_mat *= mat_xrot90 + + me = ob.create_render_mesh(True, ob_mat, convert_to_tri) + + # Make our own list so it can be sorted to reduce context switching + faces = [ f for f in me.faces ] + + if EXPORT_EDGES: + edges = me.edges + else: + edges = [] + + if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write + continue # dont bother with this mesh. + + # done above ^ +# if EXPORT_ROTX90: +# me.transform(ob_mat*mat_xrot90) +# else: +# me.transform(ob_mat) + + # High Quality Normals + if EXPORT_NORMALS and faces: + if EXPORT_NORMALS_HQ: + BPyMesh.meshCalcNormals(me) + else: + # transforming normals is incorrect + # when the matrix is scaled, + # better to recalculate them + me.calcNormals() + + # # Crash Blender + #materials = me.getMaterials(1) # 1 == will return None in the list. + materials = me.materials + + materialNames = [] + materialItems = materials[:] + if materials: + for mat in materials: + if mat: # !=None + materialNames.append(mat.name) + else: + materialNames.append(None) + # Cant use LC because some materials are None. + # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. + + # Possible there null materials, will mess up indicies + # but at least it will export, wait until Blender gets fixed. + materialNames.extend((16-len(materialNames)) * [None]) + materialItems.extend((16-len(materialItems)) * [None]) + + # Sort by Material, then images + # so we dont over context switch in the obj file. + if EXPORT_KEEP_VERT_ORDER: + pass + elif faceuv: + try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) + except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) + elif len(materials) > 1: + try: faces.sort(key = lambda a: (a.mat, a.smooth)) + except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) + else: + # no materials + try: faces.sort(key = lambda a: a.smooth) + except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) + + # Set the default mat to no material and no image. + contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. + contextSmooth = None # Will either be true or false, set bad to force initialization switch. + + if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: + name1 = ob.name + name2 = ob.getData(1) + if name1 == name2: + obnamestring = fixName(name1) + else: + obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) + + if EXPORT_BLEN_OBS: + file.write('o %s\n' % obnamestring) # Write Object name + else: # if EXPORT_GROUP_BY_OB: + file.write('g %s\n' % obnamestring) + + + # Vert + for v in me.verts: + file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) + + # UV + if faceuv: + uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ + + uv_dict = {} # could use a set() here + for f_index, f in enumerate(faces): + + for uv_index, uv in enumerate(f.uv): + uvkey = veckey2d(uv) + try: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] + except: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) + file.write('vt %.6f %.6f\n' % tuple(uv)) + + uv_unique_count = len(uv_dict) + del uv, uvkey, uv_dict, f_index, uv_index + # Only need uv_unique_count and uv_face_mapping + + # NORMAL, Smooth/Non smoothed. + if EXPORT_NORMALS: + for f in faces: + if f.smooth: + for v in f: + noKey = veckey3d(v.no) + if not globalNormals.has_key( noKey ): + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + else: + # Hard, 1 normal from the face. + noKey = veckey3d(f.no) + if not globalNormals.has_key( noKey ): + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + + if not faceuv: + f_image = None + + if EXPORT_POLYGROUPS: + # Retrieve the list of vertex groups + vertGroupNames = me.getVertGroupNames() + + currentVGroup = '' + # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to + vgroupsMap = [[] for _i in xrange(len(me.verts))] + for vertexGroupName in vertGroupNames: + for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): + vgroupsMap[vIdx].append((vertexGroupName, vWeight)) + + for f_index, f in enumerate(faces): + f_v= f.v + f_smooth= f.smooth + f_mat = min(f.mat, len(materialNames)-1) + if faceuv: + f_image = f.image + f_uv= f.uv + + # MAKE KEY + if faceuv and f_image: # Object is always true. + key = materialNames[f_mat], f_image.name + else: + key = materialNames[f_mat], None # No image, use None instead. + + # Write the vertex group + if EXPORT_POLYGROUPS: + if vertGroupNames: + # find what vertext group the face belongs to + theVGroup = findVertexGroupName(f,vgroupsMap) + if theVGroup != currentVGroup: + currentVGroup = theVGroup + file.write('g %s\n' % theVGroup) + + # CHECK FOR CONTEXT SWITCH + if key == contextMat: + pass # Context alredy switched, dont do anything + else: + if key[0] == None and key[1] == None: + # Write a null material, since we know the context has changed. + if EXPORT_GROUP_BY_MAT: + file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) + file.write('usemtl (null)\n') # mat, image + + else: + mat_data= MTL_DICT.get(key) + if not mat_data: + # First add to global dict so we can export to mtl + # Then write mtl + + # Make a new names from the mat and image name, + # converting any spaces to underscores with fixName. + + # If none image dont bother adding it to the name + if key[1] == None: + mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image + else: + mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image + + if EXPORT_GROUP_BY_MAT: + file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) + + file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) + + contextMat = key + if f_smooth != contextSmooth: + if f_smooth: # on now off + file.write('s 1\n') + contextSmooth = f_smooth + else: # was off now on + file.write('s off\n') + contextSmooth = f_smooth + + file.write('f') + if faceuv: + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % (\ + v.index+totverts,\ + totuvco + uv_face_mapping[f_index][vi],\ + globalNormals[ veckey3d(v.no) ])) # vert, uv, normal + + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.no) ] + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % (\ + v.index+totverts,\ + totuvco + uv_face_mapping[f_index][vi],\ + no)) # vert, uv, normal + + else: # No Normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d' % (\ + v.index+totverts,\ + totuvco + uv_face_mapping[f_index][vi])) # vert, uv + + face_vert_index += len(f_v) + + else: # No UV's + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for v in f_v: + file.write( ' %d//%d' % (\ + v.index+totverts,\ + globalNormals[ veckey3d(v.no) ])) + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.no) ] + for v in f_v: + file.write( ' %d//%d' % (\ + v.index+totverts,\ + no)) + else: # No Normals + for v in f_v: + file.write( ' %d' % (\ + v.index+totverts)) + + file.write('\n') + + # Write edges. + if EXPORT_EDGES: + LOOSE= Mesh.EdgeFlags.LOOSE + for ed in edges: + if ed.flag & LOOSE: + file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) + + # Make the indicies global rather then per mesh + totverts += len(me.verts) + if faceuv: + totuvco += uv_unique_count + me.verts= None if ob_main.dupli_type != 'NONE': ob_main.free_dupli_list() diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 26fb77777d7..0aa4faeddd8 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -54,8 +54,15 @@ void rna_Mesh_copy_applied(Mesh *me, Scene *sce, Object *ob) } */ -void rna_Mesh_transform(Mesh *me, float **mat) +void rna_Mesh_transform(Mesh *me, float *mat) { + /* TODO: old API transform had recalc_normals option */ + int i; + MVert *mvert= me->mvert; + + for(i= 0; i < mesh->totvert; i++, mvert++) { + Mat4MulVecfl(mat, mvert->co); + } } #if 0 @@ -85,14 +92,13 @@ static void rna_Mesh_verts_add(PointerRNA *ptr, PointerRNA *ptr_item) void RNA_api_mesh(StructRNA *srna) { - /*FunctionRNA *func; - PropertyRNA *prop;*/ + FunctionRNA *func; + PropertyRNA *parm; - /* - func= RNA_def_function(srna, "copy", "rna_Mesh_copy"); - RNA_def_function_ui_description(func, "Copy mesh data."); - prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from."); - RNA_def_property_flag(prop, PROP_REQUIRED);*/ + func= RNA_def_function(srna, "transform", "rna_Mesh_transform"); + RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix."); + parm= RNA_def_float_matrix(func, "matrix", 16, NULL, 0.0f, 0.0f, "", "Matrix.", 0.0f, 0.0f); + RNA_def_property_flag(parm, PROP_REQUIRED); /* func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index d566af1954c..14ce5954cb7 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1028,6 +1028,12 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Dupli Frames Off", "Recurring frames to exclude from the Dupliframes."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); + prop= RNA_def_property(srna, "dupli_list", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "duplilist", NULL); + RNA_def_property_struct_type(prop, "DupliObject"); + RNA_def_property_ui_text(prop, "Dupli list", "Object duplis."); + + /* time offset */ prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index c3740921f0f..69d3f48761c 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -45,7 +45,7 @@ #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" -#define OBJECT_API_PROP_DUPLILIST "dupli_list" +#include "BLI_arithb.h" /* copied from init_render_mesh (render code) */ static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports, int apply_matrix, float *matrix) @@ -78,7 +78,7 @@ static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList * dm->release(dm); if (apply_matrix) { - float *mat = ob->obmat; + float *mat = (float*)ob->obmat; if (matrix) { /* apply custom matrix */ @@ -97,33 +97,20 @@ static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList * /* When no longer needed, duplilist should be freed with Object.free_duplilist */ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) { - PointerRNA obptr; - PointerRNA dobptr; - Scene *sce; - DupliObject *dob; - PropertyRNA *prop; - if (!(ob->transflag & OB_DUPLI)) { BKE_report(reports, RPT_ERROR, "Object does not have duplis."); return; } - RNA_id_pointer_create(&ob->id, &obptr); + /* free duplilist if a user forget to */ + if (ob->duplilist) { + BKE_report(reports, RPT_WARNING, "%s.dupli_list has not been freed.", RNA_struct_identifier(&RNA_Object)); - if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { - // hint: all Objects will now have this property defined - prop= RNA_def_collection_runtime(obptr.type, OBJECT_API_PROP_DUPLILIST, &RNA_DupliObject, "Dupli list", ""); + free_object_duplilist(ob->duplilist); + ob->duplilist= NULL; } - RNA_property_collection_clear(&obptr, prop); - sce= CTX_data_scene(C); - ob->duplilist= object_duplilist(sce, ob); - - for(dob= (DupliObject*)ob->duplilist->first; dob; dob= dob->next) { - RNA_pointer_create(NULL, &RNA_DupliObject, dob, &dobptr); - RNA_property_collection_add(&obptr, prop, &dobptr); - dob = dob->next; - } + ob->duplilist= object_duplilist(CTX_data_scene(C), ob); /* ob->duplilist should now be freed with Object.free_duplilist */ } @@ -133,15 +120,6 @@ static void rna_Object_free_duplilist(Object *ob, ReportList *reports) PointerRNA obptr; PropertyRNA *prop; - RNA_id_pointer_create(&ob->id, &obptr); - - if (!(prop= RNA_struct_find_property(&obptr, OBJECT_API_PROP_DUPLILIST))) { - BKE_report(reports, RPT_ERROR, "Object has no duplilist property."); - return; - } - - RNA_property_collection_clear(&obptr, prop); - if (ob->duplilist) { free_object_duplilist(ob->duplilist); ob->duplilist= NULL; -- cgit v1.2.3 From 3f2fef55c2bbeb1f837b48c76263e3e035d56792 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 24 Jun 2009 19:23:34 +0000 Subject: - added API functions: * Main.remove_object * Scene.add_object * Scene.remove_object * Object.convert_to_triface * Object.create_preview_mesh - a small tweak in set_mesh (blenkernel/inter/mesh.c) to make it work on objects having data == NULL --- release/scripts/export_obj-2.5.py | 20 ++++-- source/blender/blenkernel/intern/mesh.c | 3 +- source/blender/makesrna/intern/makesrna.c | 2 +- source/blender/makesrna/intern/rna_main_api.c | 33 ++++++++- source/blender/makesrna/intern/rna_mesh_api.c | 3 +- source/blender/makesrna/intern/rna_object_api.c | 91 +++++++++++++++++-------- source/blender/makesrna/intern/rna_scene.c | 2 + source/blender/makesrna/intern/rna_scene_api.c | 91 +++++++++++++++++++++++++ 8 files changed, 204 insertions(+), 41 deletions(-) create mode 100644 source/blender/makesrna/intern/rna_scene_api.c diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py index 4fa02ce2efe..c0468f744b8 100644 --- a/release/scripts/export_obj-2.5.py +++ b/release/scripts/export_obj-2.5.py @@ -307,7 +307,8 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): temp_mesh_name = '~tmp-mesh' time1 = sys.time() - scn = Scene.GetCurrent() +# scn = Scene.GetCurrent() + scene = context.scene file = open(filename, "w") @@ -383,15 +384,15 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if ob.type != 'MESH': continue - me = ob.data - # XXX # if EXPORT_UV: # faceuv= me.faceUV # else: # faceuv = False - convert_to_tri = False + me = ob.create_render_mesh() + + newob = ob # We have a valid mesh if EXPORT_TRI and me.faces: @@ -403,7 +404,10 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): has_quads = True break - convert_to_tri = has_quads + if has_quads: + newob = bpy.data.add_object('MESH', 'temp_object') + scene.add_object(newob) + newob.convert_to_triface(scene) # oldmode = Mesh.Mode() # Mesh.Mode(Mesh.SelectModes['FACE']) @@ -418,8 +422,6 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if EXPORT_ROTX90: ob_mat *= mat_xrot90 - me = ob.create_render_mesh(True, ob_mat, convert_to_tri) - # Make our own list so it can be sorted to reduce context switching faces = [ f for f in me.faces ] @@ -429,6 +431,10 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): edges = [] if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write + + if newob != ob: + scene.remove_object(newob) + continue # dont bother with this mesh. # done above ^ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 3facf975992..9fc8d0ed609 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -542,7 +542,8 @@ void set_mesh(Object *ob, Mesh *me) if(ob->type==OB_MESH) { old= ob->data; - old->id.us--; + if (old) /* to make set_mesh work on objects created with add_only_object, i.e. having ob->data == NULL */ + old->id.us--; ob->data= me; id_us_plus((ID *)me); } diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index e7ca3fc5932..f7bf176a325 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1853,7 +1853,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_particle.c", NULL, RNA_def_particle}, {"rna_pose.c", NULL, RNA_def_pose}, {"rna_property.c", NULL, RNA_def_gameproperty}, - {"rna_scene.c", NULL, RNA_def_scene}, + {"rna_scene.c", "rna_scene_api.c", RNA_def_scene}, {"rna_screen.c", NULL, RNA_def_screen}, {"rna_scriptlink.c", NULL, RNA_def_scriptlink}, {"rna_sensor.c", NULL, RNA_def_sensor}, diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 2c78884a027..08a3b7cee25 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -62,7 +62,29 @@ static void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) static Object* rna_Main_add_object(Main *main, int type, char *name) { - return add_only_object(type, name); + Object *ob= add_only_object(type, name); + ob->id.us--; + return ob; +} + +/* + WARNING: the following example shows when this function should not be called + + ob = bpy.data.add_object() + scene.add_object(ob) + + # ob is freed here + scene.remove_object(ob) + + # don't do this since ob is already freed! + bpy.data.remove_object(ob) +*/ +static void rna_Main_remove_object(Main *main, ReportList *reports, Object *ob) +{ + if(ob->id.us == 0) + free_libblock(&main->object, ob); + else + BKE_report(reports, RPT_ERROR, "Object must have zero users to be removed."); } #else @@ -89,13 +111,19 @@ void RNA_api_main(StructRNA *srna) func= RNA_def_function(srna, "add_object", "rna_Main_add_object"); RNA_def_function_ui_description(func, "Add a new object."); - parm= RNA_def_enum(func, "type", object_type_items, 0, "Type", "Type of Object."); + parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_string(func, "name", "Object", 0, "", "New name for the datablock."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "object", "Object", "", "New object."); RNA_def_function_return(func, parm); + func= RNA_def_function(srna, "remove_object", "rna_Main_remove_object"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove an object if it has zero users."); + parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove."); + RNA_def_property_flag(parm, PROP_REQUIRED); + func= RNA_def_function(srna, "add_mesh", "rna_Main_add_mesh"); RNA_def_function_ui_description(func, "Add a new mesh."); parm= RNA_def_string(func, "name", "Mesh", 0, "", "New name for the datablock."); @@ -108,7 +136,6 @@ void RNA_api_main(StructRNA *srna) RNA_def_function_ui_description(func, "Remove a mesh if it has zero users."); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove."); RNA_def_property_flag(parm, PROP_REQUIRED); - } #endif diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 0aa4faeddd8..984e6a5d30f 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -36,6 +36,7 @@ #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" +#include "BLI_arithb.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" @@ -60,7 +61,7 @@ void rna_Mesh_transform(Mesh *me, float *mat) int i; MVert *mvert= me->mvert; - for(i= 0; i < mesh->totvert; i++, mvert++) { + for(i= 0; i < me->totvert; i++, mvert++) { Mat4MulVecfl(mat, mvert->co); } } diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 69d3f48761c..5af12b696c4 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "RNA_define.h" #include "RNA_types.h" @@ -40,6 +42,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_anim.h" #include "BKE_report.h" +#include "BKE_depsgraph.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" @@ -47,15 +50,17 @@ #include "BLI_arithb.h" +#include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */ + +#include "ED_mesh.h" + /* copied from init_render_mesh (render code) */ -static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports, int apply_matrix, float *matrix) +static Mesh *create_mesh(Object *ob, bContext *C, ReportList *reports, int render_mesh) { CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; DerivedMesh *dm; Mesh *me; Scene *sce; - int a; - MVert *mvert; sce= CTX_data_scene(C); @@ -65,7 +70,7 @@ static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList * return NULL; } - dm= mesh_create_derived_render(sce, ob, mask); + dm= render_mesh ? mesh_create_derived_render(sce, ob, mask) : mesh_create_derived_view(sce, ob, mask); if(!dm) { /* TODO: report */ @@ -77,21 +82,17 @@ static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList * DM_to_mesh(dm, me); dm->release(dm); - if (apply_matrix) { - float *mat = (float*)ob->obmat; - - if (matrix) { - /* apply custom matrix */ - mat = matrix; - } + return me; +} - /* is this really that simple? :) */ - for(a= 0, mvert= me->mvert; a < me->totvert; a++, mvert++) { - Mat4MulVecfl(ob->obmat, mvert->co); - } - } +static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports) +{ + return create_mesh(ob, C, reports, 1); +} - return me; +static Mesh *rna_Object_create_preview_mesh(Object *ob, bContext *C, ReportList *reports) +{ + return create_mesh(ob, C, reports, 0); } /* When no longer needed, duplilist should be freed with Object.free_duplilist */ @@ -102,9 +103,9 @@ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *rep return; } - /* free duplilist if a user forget to */ + /* free duplilist if a user forgets to */ if (ob->duplilist) { - BKE_report(reports, RPT_WARNING, "%s.dupli_list has not been freed.", RNA_struct_identifier(&RNA_Object)); + BKE_reportf(reports, RPT_WARNING, "%s.dupli_list has not been freed.", RNA_struct_identifier(&RNA_Object)); free_object_duplilist(ob->duplilist); ob->duplilist= NULL; @@ -117,15 +118,41 @@ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *rep static void rna_Object_free_duplilist(Object *ob, ReportList *reports) { - PointerRNA obptr; - PropertyRNA *prop; - if (ob->duplilist) { free_object_duplilist(ob->duplilist); ob->duplilist= NULL; } } +static void rna_Object_convert_to_triface(Object *ob, bContext *C, ReportList *reports, Scene *sce) +{ + Mesh *me; + int ob_editing = CTX_data_edit_object(C) == ob; + + if (ob->type != OB_MESH) { + BKE_report(reports, RPT_ERROR, "Object should be of type MESH."); + return; + } + + me= (Mesh*)ob->data; + + if (!ob_editing) + make_editMesh(sce, ob); + + /* select all */ + EM_set_flag_all(me->edit_mesh, SELECT); + + convert_to_triface(me->edit_mesh, 0); + + load_editMesh(sce, ob); + + if (!ob_editing) + free_editMesh(me->edit_mesh); + + DAG_object_flush_update(sce, ob, OB_RECALC_DATA); +} + + #else void RNA_api_object(StructRNA *srna) @@ -149,22 +176,30 @@ void RNA_api_object(StructRNA *srna) {0, NULL, 0, NULL, NULL}}; func= RNA_def_function(srna, "create_render_mesh", "rna_Object_create_render_mesh"); - RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); + RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied for rendering."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); + parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "create_preview_mesh", "rna_Object_create_preview_mesh"); + RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied for preview."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_boolean(func, "apply_matrix", 0, "", "True if object matrix or custom matrix should be applied to geometry."); - RNA_def_property_clear_flag(parm, PROP_REQUIRED); - parm= RNA_def_float_matrix(func, "custom_matrix", 16, NULL, 0.0f, 0.0f, "", "Optional custom matrix to apply.", 0.0f, 0.0f); - RNA_def_property_clear_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist"); - RNA_def_function_ui_description(func, "Create a list of dupli objects for this object. When no longer needed, it should be freed with free_dupli_list."); + RNA_def_function_ui_description(func, "Create a list of dupli objects for this object, needs to be freed manually with free_dupli_list."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); func= RNA_def_function(srna, "free_dupli_list", "rna_Object_free_duplilist"); RNA_def_function_ui_description(func, "Free the list of dupli objects."); RNA_def_function_flag(func, FUNC_USE_REPORTS); + + func= RNA_def_function(srna, "convert_to_triface", "rna_Object_convert_to_triface"); + RNA_def_function_ui_description(func, "Convert all mesh faces to triangles."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); + parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object is."); + RNA_def_property_flag(parm, PROP_REQUIRED); } #endif diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 47c9025149a..1017703c56b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1018,6 +1018,8 @@ void RNA_def_scene(BlenderRNA *brna) rna_def_tool_settings(brna); rna_def_scene_render_data(brna); + + RNA_api_scene(srna); } #endif diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c new file mode 100644 index 00000000000..a38622b48ae --- /dev/null +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -0,0 +1,91 @@ +/** + * $Id: rna_object_api.c 21115 2009-06-23 19:17:59Z kazanbas $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "DNA_object_types.h" + +#ifdef RNA_RUNTIME + +#include "BKE_scene.h" +#include "ED_object.h" + +static void rna_Scene_add_object(Scene *sce, ReportList *reports, Object *ob) +{ + Base *base= object_in_scene(ob, sce); + if (base) { + BKE_report(reports, RPT_ERROR, "Object is already in this scene."); + return; + } + base= scene_add_base(sce, ob); + ob->id.us++; + + /* this is similar to what object_add_type and add_object do */ + ob->lay= base->lay= sce->lay; + ob->recalc |= OB_RECALC; + + DAG_scene_sort(sce); +} + +static void rna_Scene_remove_object(Scene *sce, ReportList *reports, Object *ob) +{ + Base *base= object_in_scene(ob, sce); + if (!base) { + BKE_report(reports, RPT_ERROR, "Object is not in this scene."); + return; + } + /* as long as ED_base_object_free_and_unlink calls free_libblock_us, we don't have to decrement ob->id.us */ + ED_base_object_free_and_unlink(sce, base); +} + +#else + +void RNA_api_scene(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "add_object", "rna_Scene_add_object"); + RNA_def_function_ui_description(func, "Add object to scene."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm= RNA_def_pointer(func, "object", "Object", "", "Object to add to scene."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "remove_object", "rna_Scene_remove_object"); + RNA_def_function_ui_description(func, "Remove object from scene."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove from scene."); + RNA_def_property_flag(parm, PROP_REQUIRED); +} + +#endif + -- cgit v1.2.3 From edfb507088165db835c184f55829832af0776f33 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 24 Jun 2009 19:29:48 +0000 Subject: *Fixed handling of HEMI and SUN lights shadows --- source/blender/render/intern/source/rayshade.c | 68 +++++++++++++++++++------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 4c72f80224a..be7b2665bdb 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1957,7 +1957,7 @@ static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_ } } -static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec) +static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lampvec, float *shadfac, Isect *isec) { QMCSampler *qsa=NULL; int samples=0; @@ -2018,6 +2018,8 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * if (lar->type == LA_LOCAL) { float ru[3], rv[3], v[3], s[3]; + assert(lampvec == 0); + /* calc tangent plane vectors */ v[0] = co[0] - lampco[0]; v[1] = co[1] - lampco[1]; @@ -2036,6 +2038,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * VECCOPY(samp3d, s); } else { + assert(lampvec); /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */ QMC_sampleRect(samp3d, qsa, shi->thread, samples, lar->area_size, lar->area_sizey); @@ -2063,10 +2066,20 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * } VECCOPY(isec->start, co); - isec->vec[0] = end[0]-isec->start[0]; - isec->vec[1] = end[1]-isec->start[1]; - isec->vec[2] = end[2]-isec->start[2]; - isec->labda = 1.0f; // * Normalize(isec->vec); + if(lampvec) + { + isec->vec[0] = end[0]; + isec->vec[1] = end[1]; + isec->vec[2] = end[2]; + isec->labda = RE_RAYTRACE_MAXDIST; + } + else + { + isec->vec[0] = end[0]-isec->start[0]; + isec->vec[1] = end[1]-isec->start[1]; + isec->vec[2] = end[2]-isec->start[2]; + isec->labda = 1.0f; // * Normalize(isec->vec); + } /* trace the ray */ if(isec->mode==RE_RAY_SHADOW_TRA) { @@ -2119,7 +2132,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * release_thread_qmcsampler(&R, shi->thread, qsa); } -static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec) +static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, int lampvec, float *shadfac, Isect *isec) { /* area soft shadow */ float *jitlamp; @@ -2162,10 +2175,20 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa /* set start and vec */ VECCOPY(isec->start, shi->co); - isec->vec[0] = vec[0]+lampco[0]-shi->co[0]; - isec->vec[1] = vec[1]+lampco[1]-shi->co[1]; - isec->vec[2] = vec[2]+lampco[2]-shi->co[2]; - isec->labda = 1.0f; + if(lampvec) + { + isec->vec[0] = vec[0]+lampco[0]; + isec->vec[1] = vec[1]+lampco[1]; + isec->vec[2] = vec[2]+lampco[2]; + isec->labda = RE_RAYTRACE_MAXDIST; + } + else + { + isec->vec[0] = vec[0]+lampco[0]-shi->co[0]; + isec->vec[1] = vec[1]+lampco[1]-shi->co[1]; + isec->vec[2] = vec[2]+lampco[2]-shi->co[2]; + isec->labda = 1.0f; + } isec->skip = RE_SKIP_VLR_NEIGHBOUR; if(isec->mode==RE_RAY_SHADOW_TRA) { @@ -2204,6 +2227,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) { Isect isec; float lampco[3]; + int lampvec; /* indicates if lampco is a vector lamp */ /* setup isec */ if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; @@ -2223,17 +2247,19 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) } if(lar->type==LA_SUN || lar->type==LA_HEMI) { - lampco[0]= shi->co[0] - RE_RAYTRACE_MAXDIST*lar->vec[0]; - lampco[1]= shi->co[1] - RE_RAYTRACE_MAXDIST*lar->vec[1]; - lampco[2]= shi->co[2] - RE_RAYTRACE_MAXDIST*lar->vec[2]; + lampco[0]= -lar->vec[0]; + lampco[1]= -lar->vec[1]; + lampco[2]= -lar->vec[2]; + lampvec = 1; } else { VECCOPY(lampco, lar->co); + lampvec = 0; } if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) { - ray_shadow_qmc(shi, lar, lampco, shadfac, &isec); + ray_shadow_qmc(shi, lar, lampco, lampvec, shadfac, &isec); } else { if(lar->ray_totsamp<2) { @@ -2245,8 +2271,16 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) /* set up isec vec */ VECCOPY(isec.start, shi->co); - VECSUB(isec.vec, lampco, isec.start); - isec.labda = 1.0f; + if(lampvec) + { + VECCOPY(isec.vec, lampco); + isec.labda = RE_RAYTRACE_MAXDIST; + } + else + { + VECSUB(isec.vec, lampco, isec.start); + isec.labda = 1.0f; + } if(isec.mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ @@ -2260,7 +2294,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) shadfac[3]= 0.0f; } else { - ray_shadow_jitter(shi, lar, lampco, shadfac, &isec); + ray_shadow_jitter(shi, lar, lampco, lampvec, shadfac, &isec); } } -- cgit v1.2.3 From e2e139c0ba91f6218af04748ab08fcb8dd1a9425 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 25 Jun 2009 13:33:21 +0000 Subject: Added Mesh.active_uv_layer read-only property. --- source/blender/makesrna/intern/rna_mesh.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index da90b9f4c76..00af79890be 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -234,6 +234,23 @@ static int rna_Mesh_uv_layers_length(PointerRNA *ptr) return rna_CustomDataLayer_length(ptr, CD_MTFACE); } +static PointerRNA rna_Mesh_active_uv_layer_get(PointerRNA *ptr) +{ + CustomDataLayer *active_layer; + Mesh *me; + int layer_index; + + active_layer= NULL; + me= (Mesh*)ptr->data; + + if (CustomData_has_layer(&me->fdata, CD_MTFACE)) { + layer_index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); + active_layer= &me->fdata.layers[layer_index]; + } + + return rna_pointer_inherit_refine(ptr, &RNA_MeshTextureFaceLayer, active_layer); +} + static void rna_MeshTextureFace_uv1_get(PointerRNA *ptr, float *values) { MTFace *mtface= (MTFace*)ptr->data; @@ -1081,6 +1098,11 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_struct_type(prop, "MeshTextureFaceLayer"); RNA_def_property_ui_text(prop, "UV Layers", ""); + prop= RNA_def_property(srna, "active_uv_layer", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MeshTextureFaceLayer"); + RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_uv_layer_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Active UV layer", "Active UV layer."); + prop= RNA_def_property(srna, "vcol_layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); RNA_def_property_collection_funcs(prop, "rna_Mesh_vcol_layers_begin", 0, 0, 0, "rna_Mesh_vcol_layers_length", 0, 0, 0, 0); -- cgit v1.2.3 From 18e7ec8463930947cfa9d76e7385be0b81482627 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 25 Jun 2009 18:04:32 +0000 Subject: - added MeshFace.normal property - continuing OBJ exporter conversion --- release/scripts/export_obj-2.5.py | 163 ++++++++++++++++-------- source/blender/makesrna/intern/rna_mesh.c | 29 +++++ source/blender/makesrna/intern/rna_object_api.c | 2 +- 3 files changed, 140 insertions(+), 54 deletions(-) diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py index c0468f744b8..de1657402b3 100644 --- a/release/scripts/export_obj-2.5.py +++ b/release/scripts/export_obj-2.5.py @@ -384,16 +384,13 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if ob.type != 'MESH': continue - # XXX -# if EXPORT_UV: -# faceuv= me.faceUV -# else: -# faceuv = False + if EXPORT_UV: + faceuv = len(me.uv_layers) > 0 + else: + faceuv = False me = ob.create_render_mesh() - newob = ob - # We have a valid mesh if EXPORT_TRI and me.faces: # Add a dummy object to it. @@ -408,6 +405,8 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): newob = bpy.data.add_object('MESH', 'temp_object') scene.add_object(newob) newob.convert_to_triface(scene) + # me will still be there + scene.remove_object(newob) # oldmode = Mesh.Mode() # Mesh.Mode(Mesh.SelectModes['FACE']) @@ -423,35 +422,38 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): ob_mat *= mat_xrot90 # Make our own list so it can be sorted to reduce context switching - faces = [ f for f in me.faces ] + face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)] + # faces = [ f for f in me.faces ] if EXPORT_EDGES: edges = me.edges else: edges = [] - - if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write - if newob != ob: - scene.remove_object(newob) + if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write +# if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write + + bpy.data.remove_mesh(me) continue # dont bother with this mesh. - # done above ^ -# if EXPORT_ROTX90: -# me.transform(ob_mat*mat_xrot90) -# else: -# me.transform(ob_mat) + if EXPORT_ROTX90: + me.transform(ob_mat*mat_xrot90) + else: + me.transform(ob_mat) # High Quality Normals - if EXPORT_NORMALS and faces: - if EXPORT_NORMALS_HQ: - BPyMesh.meshCalcNormals(me) - else: - # transforming normals is incorrect - # when the matrix is scaled, - # better to recalculate them - me.calcNormals() + if EXPORT_NORMALS and face_index_pairs: +# if EXPORT_NORMALS and faces: + # XXX + pass +# if EXPORT_NORMALS_HQ: +# BPyMesh.meshCalcNormals(me) +# else: +# # transforming normals is incorrect +# # when the matrix is scaled, +# # better to recalculate them +# me.calcNormals() # # Crash Blender #materials = me.getMaterials(1) # 1 == will return None in the list. @@ -478,15 +480,35 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if EXPORT_KEEP_VERT_ORDER: pass elif faceuv: - try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) - except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) + # XXX update + tface = me.active_uv_layer.data + + # exception only raised if Python 2.3 or lower... + try: face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth)) + except: face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth), + (b[0].material_index, tface[b[1]].image, b[0].smooth))) elif len(materials) > 1: - try: faces.sort(key = lambda a: (a.mat, a.smooth)) - except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) + try: face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth)) + except: face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth), + (b[0].material_index, b[0].smooth))) else: # no materials - try: faces.sort(key = lambda a: a.smooth) - except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) + try: face_index_pairs.sort(key = lambda a: a[0].smooth) + except: face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth)) +# if EXPORT_KEEP_VERT_ORDER: +# pass +# elif faceuv: +# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) +# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) +# elif len(materials) > 1: +# try: faces.sort(key = lambda a: (a.mat, a.smooth)) +# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) +# else: +# # no materials +# try: faces.sort(key = lambda a: a.smooth) +# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) + + faces = [pair[0] for pair in face_index_pairs] # Set the default mat to no material and no image. contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. @@ -494,7 +516,8 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: name1 = ob.name - name2 = ob.getData(1) + name2 = ob.data.name + # name2 = ob.getData(1) if name1 == name2: obnamestring = fixName(name1) else: @@ -513,17 +536,37 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): # UV if faceuv: uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ - + uv_dict = {} # could use a set() here - for f_index, f in enumerate(faces): - - for uv_index, uv in enumerate(f.uv): + uv_layer = me.active_uv_layer + for f, f_index in face_index_pairs: + + tface = uv_layer.data[f_index] + + uvs = [tface.uv1, tface.uv2, tface.uv3] + + # add another UV if it's a quad + if tface.verts[3] != 0: + uvs.append(tface.uv4) + + for uv_index, uv in enumerate(uvs): uvkey = veckey2d(uv) try: uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] except: uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) file.write('vt %.6f %.6f\n' % tuple(uv)) + +# uv_dict = {} # could use a set() here +# for f_index, f in enumerate(faces): + +# for uv_index, uv in enumerate(f.uv): +# uvkey = veckey2d(uv) +# try: +# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] +# except: +# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) +# file.write('vt %.6f %.6f\n' % tuple(uv)) uv_unique_count = len(uv_dict) del uv, uvkey, uv_dict, f_index, uv_index @@ -534,14 +577,16 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): for f in faces: if f.smooth: for v in f: - noKey = veckey3d(v.no) + noKey = veckey3d(v.normal) +# noKey = veckey3d(v.no) if not globalNormals.has_key( noKey ): globalNormals[noKey] = totno totno +=1 file.write('vn %.6f %.6f %.6f\n' % noKey) else: # Hard, 1 normal from the face. - noKey = veckey3d(f.no) + noKey = veckey3d(f.normal) +# noKey = veckey3d(f.no) if not globalNormals.has_key( noKey ): globalNormals[noKey] = totno totno +=1 @@ -549,14 +594,17 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if not faceuv: f_image = None - + + # XXX if EXPORT_POLYGROUPS: # Retrieve the list of vertex groups - vertGroupNames = me.getVertGroupNames() + vertGroupNames = [g.name for g in ob.vertex_groups] +# vertGroupNames = me.getVertGroupNames() currentVGroup = '' # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to - vgroupsMap = [[] for _i in xrange(len(me.verts))] + vgroupsMap = [[] for _i in range(len(me.verts))] +# vgroupsMap = [[] for _i in xrange(len(me.verts))] for vertexGroupName in vertGroupNames: for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): vgroupsMap[vIdx].append((vertexGroupName, vWeight)) @@ -564,25 +612,34 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): for f_index, f in enumerate(faces): f_v= f.v f_smooth= f.smooth - f_mat = min(f.mat, len(materialNames)-1) + f_mat = min(f.material_index, len(materialNames)-1) +# f_mat = min(f.mat, len(materialNames)-1) if faceuv: - f_image = f.image - f_uv= f.uv + + tface = me.active_uv_layer.data[face_index_pairs[f_index][1]] + + f_image = tface.image + f_uv= [tface.uv1, tface.uv2, tface.uv3] + if f.verts[4] != 0: + f_uv.append(tface.uv4) +# f_image = f.image +# f_uv= f.uv # MAKE KEY if faceuv and f_image: # Object is always true. key = materialNames[f_mat], f_image.name else: key = materialNames[f_mat], None # No image, use None instead. - - # Write the vertex group - if EXPORT_POLYGROUPS: - if vertGroupNames: - # find what vertext group the face belongs to - theVGroup = findVertexGroupName(f,vgroupsMap) - if theVGroup != currentVGroup: - currentVGroup = theVGroup - file.write('g %s\n' % theVGroup) + + # XXX +# # Write the vertex group +# if EXPORT_POLYGROUPS: +# if vertGroupNames: +# # find what vertext group the face belongs to +# theVGroup = findVertexGroupName(f,vgroupsMap) +# if theVGroup != currentVGroup: +# currentVGroup = theVGroup +# file.write('g %s\n' % theVGroup) # CHECK FOR CONTEXT SWITCH if key == contextMat: diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 00af79890be..3127c352f60 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -38,6 +38,9 @@ #ifdef RNA_RUNTIME +#include "BLI_arithb.h" /* CalcNormFloat */ + + static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value) { MVert *mvert= (MVert*)ptr->data; @@ -183,6 +186,26 @@ static void rna_MeshFace_material_index_range(PointerRNA *ptr, int *min, int *ma *max= me->totcol-1; } +static void rna_MeshFace_normal_get(PointerRNA *ptr, float *value) +{ + float *vert[4]; + MFace *face = (MFace*)ptr->data; + Mesh *me= (Mesh*)ptr->id.data; + + vert[0] = me->mvert[face->v1].co; + vert[1] = me->mvert[face->v2].co; + vert[2] = me->mvert[face->v3].co; + + /* copied from MFace_getNormal (old python API) */ + if (face->v4) { + vert[3] = me->mvert[face->v4].co; + CalcNormFloat4(vert[0], vert[1], vert[2], vert[3], value); + } + else { + CalcNormFloat(vert[0], vert[1], vert[2], value); + } +} + static int rna_CustomDataLayer_length(PointerRNA *ptr, int type) { Mesh *me= (Mesh*)ptr->id.data; @@ -749,6 +772,12 @@ static void rna_def_mface(BlenderRNA *brna) prop= RNA_def_property(srna, "smooth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SMOOTH); RNA_def_property_ui_text(prop, "Smooth", ""); + + prop= RNA_def_property(srna, "normal", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_array(prop, 3); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_MeshFace_normal_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Normal", "Face normal"); } static void rna_def_mtface(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 5af12b696c4..40f29360e9c 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -198,7 +198,7 @@ void RNA_api_object(StructRNA *srna) func= RNA_def_function(srna, "convert_to_triface", "rna_Object_convert_to_triface"); RNA_def_function_ui_description(func, "Convert all mesh faces to triangles."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object is."); + parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object belongs."); RNA_def_property_flag(parm, PROP_REQUIRED); } -- cgit v1.2.3 From 165593931ff325fa1fbdbad61537b42b5532b3cd Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 26 Jun 2009 02:11:08 +0000 Subject: *another blackdots fixed - had forgoted to enable skip-neighbour faces on ao. --- source/blender/render/intern/source/rayshade.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index be7b2665bdb..320b4cb601b 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1662,6 +1662,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; + isec.skip = RE_SKIP_VLR_NEIGHBOUR; isec.hit.ob = 0; isec.hit.face = 0; @@ -1794,6 +1795,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; + isec.skip = RE_SKIP_VLR_NEIGHBOUR; isec.hit.ob = 0; isec.hit.face = 0; @@ -2018,8 +2020,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam if (lar->type == LA_LOCAL) { float ru[3], rv[3], v[3], s[3]; - assert(lampvec == 0); - /* calc tangent plane vectors */ v[0] = co[0] - lampco[0]; v[1] = co[1] - lampco[1]; @@ -2038,7 +2038,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam VECCOPY(samp3d, s); } else { - assert(lampvec); /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */ QMC_sampleRect(samp3d, qsa, shi->thread, samples, lar->area_size, lar->area_sizey); -- cgit v1.2.3 From acb590e4b065505117a78786e2627c43e65c499a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 26 Jun 2009 12:33:07 +0000 Subject: * OBJ exporter almost converted * added MeshEdge.loose property * changed mask used in Object.create_*_mesh to CD_MASK_MESH. --- release/scripts/export_obj-2.5.py | 489 ++++++------------------ source/blender/makesrna/intern/rna_mesh.c | 5 + source/blender/makesrna/intern/rna_object_api.c | 4 +- 3 files changed, 135 insertions(+), 363 deletions(-) diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py index de1657402b3..cd8e423ed07 100644 --- a/release/scripts/export_obj-2.5.py +++ b/release/scripts/export_obj-2.5.py @@ -47,7 +47,7 @@ will be exported as mesh data. import bpy -import BPySys +# import BPySys # import Blender # from Blender import Mesh, Scene, Window, sys, Image, Draw @@ -75,16 +75,20 @@ def fixName(name): # (material.name, image.name):matname_imagename # matname_imagename has gaps removed. MTL_DICT = {} -def write_mtl(filename): - - world = Blender.World.GetCurrent() - if world: - worldAmb = world.getAmb() - else: - worldAmb = (0,0,0) # Default value +def write_mtl(scene, filename): + + world = bpy.data.worlds[0] + worldAmb = world.ambient_color + +# world = Blender.World.GetCurrent() +# if world: +# worldAmb = world.getAmb() +# else: +# worldAmb = (0,0,0) # Default value file = open(filename, "w") - file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) + # XXX +# file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) file.write('# Material Count: %i\n' % len(MTL_DICT)) # Write material/image combinations we have used. for key, (mtl_mat_name, mat, img) in MTL_DICT.iteritems(): @@ -261,7 +265,7 @@ def write_nurb(file, ob, ob_mat): return tot_verts -def write(filename, objects,\ +def write(filename, objects, scene, \ EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ @@ -290,8 +294,10 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): of vertices is the face's group """ weightDict = {} - for vert in face: - vWeights = vWeightMap[vert.index] + for vert_index in face.verts: +# for vert in face: + vWeights = vWeightMap[vert_index] +# vWeights = vWeightMap[vert] for vGroupName, weight in vWeights: weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight @@ -302,6 +308,17 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): else: return '(null)' + # TODO: implement this in C? dunno how it should be called... + def getVertsFromGroup(me, group_index): + ret = [] + + for i, v in enumerate(me.verts): + for g in v.groups: + if g.group == group.index: + ret.append((i, g.weight)) + + return ret + print 'OBJ Export path: "%s"' % filename temp_mesh_name = '~tmp-mesh' @@ -349,6 +366,7 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): globalNormals = {} + # Get all meshes for ob_main in objects: if ob_main.dupli_type != 'NONE': @@ -375,22 +393,25 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): # continue # end nurbs - + + if ob.type != 'MESH': + continue + + # XXX EXPORT_APPLY_MODIFIERS is not used (always true) + # we also need influences to be copied... for EXPORT_POLYGROUPS to work + # which create_preview_mesh presumably does (CD_MASK_MDEFORMVERT flag) + me = ob.create_preview_mesh() + # # Will work for non meshes now! :) # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) # if not me: # continue - if ob.type != 'MESH': - continue - if EXPORT_UV: faceuv = len(me.uv_layers) > 0 else: faceuv = False - me = ob.create_render_mesh() - # We have a valid mesh if EXPORT_TRI and me.faces: # Add a dummy object to it. @@ -598,19 +619,21 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): # XXX if EXPORT_POLYGROUPS: # Retrieve the list of vertex groups - vertGroupNames = [g.name for g in ob.vertex_groups] # vertGroupNames = me.getVertGroupNames() currentVGroup = '' # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to vgroupsMap = [[] for _i in range(len(me.verts))] # vgroupsMap = [[] for _i in xrange(len(me.verts))] - for vertexGroupName in vertGroupNames: - for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): - vgroupsMap[vIdx].append((vertexGroupName, vWeight)) + for g in ob.vertex_groups: +# for vertexGroupName in vertGroupNames: + for vIdx, vWeight in getVertsFromGroup(me, g.index) +# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): + vgroupsMap[vIdx].append((g.name, vWeight)) for f_index, f in enumerate(faces): - f_v= f.v + f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts] +# f_v= f.v f_smooth= f.smooth f_mat = min(f.material_index, len(materialNames)-1) # f_mat = min(f.mat, len(materialNames)-1) @@ -632,6 +655,14 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): key = materialNames[f_mat], None # No image, use None instead. # XXX + # Write the vertex group + if EXPORT_POLYGROUPS: + if len(ob.vertex_groups): + # find what vertext group the face belongs to + theVGroup = findVertexGroupName(f,vgroupsMap) + if theVGroup != currentVGroup: + currentVGroup = theVGroup + file.write('g %s\n' % theVGroup) # # Write the vertex group # if EXPORT_POLYGROUPS: # if vertGroupNames: @@ -648,7 +679,9 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if key[0] == None and key[1] == None: # Write a null material, since we know the context has changed. if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) + # can be mat_image or (null) + file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.data.name)) ) +# file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) file.write('usemtl (null)\n') # mat, image else: @@ -667,7 +700,8 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) + file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.data.name), mat_data[0]) ) # can be mat_image or (null) +# file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) @@ -685,24 +719,36 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if EXPORT_NORMALS: if f_smooth: # Smoothed, use vertex normals for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi],\ - globalNormals[ veckey3d(v.no) ])) # vert, uv, normal + file.write( ' %d/%d/%d' % \ + (v["index"] + totverts, + totuvco + uv_face_mapping[f_index][vi], + globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal +# file.write( ' %d/%d/%d' % (\ +# v.index+totverts,\ +# totuvco + uv_face_mapping[f_index][vi],\ +# globalNormals[ veckey3d(v.no) ])) # vert, uv, normal else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.no) ] + no = globalNormals[ veckey3d(f.normal) ] +# no = globalNormals[ veckey3d(f.no) ] for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi],\ - no)) # vert, uv, normal + file.write( ' %d/%d/%d' % \ + (v["index"] + totverts, + totuvco + uv_face_mapping[f_index][vi], + no) ) # vert, uv, normal +# file.write( ' %d/%d/%d' % (\ +# v.index+totverts,\ +# totuvco + uv_face_mapping[f_index][vi],\ +# no)) # vert, uv, normal else: # No Normals for vi, v in enumerate(f_v): file.write( ' %d/%d' % (\ - v.index+totverts,\ + v["index"] + totverts,\ totuvco + uv_face_mapping[f_index][vi])) # vert, uv +# file.write( ' %d/%d' % (\ +# v.index+totverts,\ +# totuvco + uv_face_mapping[f_index][vi])) # vert, uv face_vert_index += len(f_v) @@ -710,344 +756,56 @@ EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): if EXPORT_NORMALS: if f_smooth: # Smoothed, use vertex normals for v in f_v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - globalNormals[ veckey3d(v.no) ])) + file.write( ' %d//%d' % + (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) ) + +# file.write( ' %d//%d' % (\ +# v.index+totverts,\ +# globalNormals[ veckey3d(v.no) ])) else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.no) ] + no = globalNormals[ veckey3d(f.normal) ] +# no = globalNormals[ veckey3d(f.no) ] for v in f_v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - no)) + file.write( ' %d//%d' % (v["index"] + totverts, no) ) +# file.write( ' %d//%d' % (\ +# v.index+totverts,\ +# no)) else: # No Normals for v in f_v: - file.write( ' %d' % (\ - v.index+totverts)) + file.write( ' %d' % (v["index"] + totverts) ) +# file.write( ' %d' % (\ +# v.index+totverts)) file.write('\n') # Write edges. if EXPORT_EDGES: - LOOSE= Mesh.EdgeFlags.LOOSE for ed in edges: - if ed.flag & LOOSE: - file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) + if ed.loose: + file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts)) +# LOOSE= Mesh.EdgeFlags.LOOSE +# for ed in edges: +# if ed.flag & LOOSE: +# file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) # Make the indicies global rather then per mesh totverts += len(me.verts) if faceuv: totuvco += uv_unique_count - me.verts= None + + # clean up + bpy.data.remove_mesh(me) +# me.verts= None if ob_main.dupli_type != 'NONE': ob_main.free_dupli_list() - - # Get all meshes - for ob_main in objects: - for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): - - # Nurbs curve support - if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): - if EXPORT_ROTX90: - ob_mat = ob_mat * mat_xrot90 - - totverts += write_nurb(file, ob, ob_mat) - - continue - # end nurbs - - # Will work for non meshes now! :) - # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) - me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) - if not me: - continue - - if EXPORT_UV: - faceuv= me.faceUV - else: - faceuv = False - - # We have a valid mesh - if EXPORT_TRI and me.faces: - # Add a dummy object to it. - has_quads = False - for f in me.faces: - if len(f) == 4: - has_quads = True - break - - if has_quads: - oldmode = Mesh.Mode() - Mesh.Mode(Mesh.SelectModes['FACE']) - - me.sel = True - tempob = scn.objects.new(me) - me.quadToTriangle(0) # more=0 shortest length - oldmode = Mesh.Mode(oldmode) - scn.objects.unlink(tempob) - - Mesh.Mode(oldmode) - - # Make our own list so it can be sorted to reduce context switching - faces = [ f for f in me.faces ] - - if EXPORT_EDGES: - edges = me.edges - else: - edges = [] - - if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write - continue # dont bother with this mesh. - - if EXPORT_ROTX90: - me.transform(ob_mat*mat_xrot90) - else: - me.transform(ob_mat) - - # High Quality Normals - if EXPORT_NORMALS and faces: - if EXPORT_NORMALS_HQ: - BPyMesh.meshCalcNormals(me) - else: - # transforming normals is incorrect - # when the matrix is scaled, - # better to recalculate them - me.calcNormals() - - # # Crash Blender - #materials = me.getMaterials(1) # 1 == will return None in the list. - materials = me.materials - - materialNames = [] - materialItems = materials[:] - if materials: - for mat in materials: - if mat: # !=None - materialNames.append(mat.name) - else: - materialNames.append(None) - # Cant use LC because some materials are None. - # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. - - # Possible there null materials, will mess up indicies - # but at least it will export, wait until Blender gets fixed. - materialNames.extend((16-len(materialNames)) * [None]) - materialItems.extend((16-len(materialItems)) * [None]) - - # Sort by Material, then images - # so we dont over context switch in the obj file. - if EXPORT_KEEP_VERT_ORDER: - pass - elif faceuv: - try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) - except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) - elif len(materials) > 1: - try: faces.sort(key = lambda a: (a.mat, a.smooth)) - except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) - else: - # no materials - try: faces.sort(key = lambda a: a.smooth) - except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) - - # Set the default mat to no material and no image. - contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. - contextSmooth = None # Will either be true or false, set bad to force initialization switch. - - if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: - name1 = ob.name - name2 = ob.getData(1) - if name1 == name2: - obnamestring = fixName(name1) - else: - obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) - - if EXPORT_BLEN_OBS: - file.write('o %s\n' % obnamestring) # Write Object name - else: # if EXPORT_GROUP_BY_OB: - file.write('g %s\n' % obnamestring) - - - # Vert - for v in me.verts: - file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) - - # UV - if faceuv: - uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ - - uv_dict = {} # could use a set() here - for f_index, f in enumerate(faces): - - for uv_index, uv in enumerate(f.uv): - uvkey = veckey2d(uv) - try: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] - except: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) - file.write('vt %.6f %.6f\n' % tuple(uv)) - - uv_unique_count = len(uv_dict) - del uv, uvkey, uv_dict, f_index, uv_index - # Only need uv_unique_count and uv_face_mapping - - # NORMAL, Smooth/Non smoothed. - if EXPORT_NORMALS: - for f in faces: - if f.smooth: - for v in f: - noKey = veckey3d(v.no) - if not globalNormals.has_key( noKey ): - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - else: - # Hard, 1 normal from the face. - noKey = veckey3d(f.no) - if not globalNormals.has_key( noKey ): - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - - if not faceuv: - f_image = None - - if EXPORT_POLYGROUPS: - # Retrieve the list of vertex groups - vertGroupNames = me.getVertGroupNames() - - currentVGroup = '' - # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to - vgroupsMap = [[] for _i in xrange(len(me.verts))] - for vertexGroupName in vertGroupNames: - for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): - vgroupsMap[vIdx].append((vertexGroupName, vWeight)) - - for f_index, f in enumerate(faces): - f_v= f.v - f_smooth= f.smooth - f_mat = min(f.mat, len(materialNames)-1) - if faceuv: - f_image = f.image - f_uv= f.uv - - # MAKE KEY - if faceuv and f_image: # Object is always true. - key = materialNames[f_mat], f_image.name - else: - key = materialNames[f_mat], None # No image, use None instead. - - # Write the vertex group - if EXPORT_POLYGROUPS: - if vertGroupNames: - # find what vertext group the face belongs to - theVGroup = findVertexGroupName(f,vgroupsMap) - if theVGroup != currentVGroup: - currentVGroup = theVGroup - file.write('g %s\n' % theVGroup) - - # CHECK FOR CONTEXT SWITCH - if key == contextMat: - pass # Context alredy switched, dont do anything - else: - if key[0] == None and key[1] == None: - # Write a null material, since we know the context has changed. - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) - file.write('usemtl (null)\n') # mat, image - - else: - mat_data= MTL_DICT.get(key) - if not mat_data: - # First add to global dict so we can export to mtl - # Then write mtl - - # Make a new names from the mat and image name, - # converting any spaces to underscores with fixName. - - # If none image dont bother adding it to the name - if key[1] == None: - mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image - else: - mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image - - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) - file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) - - contextMat = key - if f_smooth != contextSmooth: - if f_smooth: # on now off - file.write('s 1\n') - contextSmooth = f_smooth - else: # was off now on - file.write('s off\n') - contextSmooth = f_smooth - - file.write('f') - if faceuv: - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi],\ - globalNormals[ veckey3d(v.no) ])) # vert, uv, normal - - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.no) ] - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi],\ - no)) # vert, uv, normal - - else: # No Normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi])) # vert, uv - - face_vert_index += len(f_v) - - else: # No UV's - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for v in f_v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - globalNormals[ veckey3d(v.no) ])) - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.no) ] - for v in f_v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - no)) - else: # No Normals - for v in f_v: - file.write( ' %d' % (\ - v.index+totverts)) - - file.write('\n') - - # Write edges. - if EXPORT_EDGES: - LOOSE= Mesh.EdgeFlags.LOOSE - for ed in edges: - if ed.flag & LOOSE: - file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) - - # Make the indicies global rather then per mesh - totverts += len(me.verts) - if faceuv: - totuvco += uv_unique_count - me.verts= None file.close() # Now we have all our materials, save them if EXPORT_MTL: - write_mtl(mtlfilename) + write_mtl(scene, mtlfilename) if EXPORT_COPY_IMAGES: dest_dir = filename # Remove chars until we are just the path. @@ -1332,8 +1090,8 @@ def write_ui(filename): def do_export(filename, context): -# Window.EditMode(0) -# Window.WaitCursor(1) + # Window.EditMode(0) + # Window.WaitCursor(1) EXPORT_APPLY_MODIFIERS = True EXPORT_ROTX90 = True @@ -1351,6 +1109,8 @@ def do_export(filename, context): EXPORT_GROUP_BY_OB = False EXPORT_GROUP_BY_MAT = False EXPORT_KEEP_VERT_ORDER = False + EXPORT_POLYGROUPS = False + EXPORT_CURVE_AS_NURBS = True base_name, ext = splitExt(filename) context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension @@ -1370,8 +1130,8 @@ def do_export(filename, context): # Export all scenes. for scn in export_scenes: -# scn.makeCurrent() # If already current, this is not slow. -# context = scn.getRenderingContext() + # scn.makeCurrent() # If already current, this is not slow. + # context = scn.getRenderingContext() orig_frame = scn.current_frame if EXPORT_ALL_SCENES: # Add scene name into the context_name @@ -1398,12 +1158,14 @@ def do_export(filename, context): # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. # EXPORT THE FILE. -# write(full_path, export_objects, -# EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, -# EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, -# EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, -# EXPORT_ROTX90, EXPORT_BLEN_OBS, -# EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER) + write(full_path, export_objects, scn, + EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, + EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, + EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, + EXPORT_ROTX90, EXPORT_BLEN_OBS, + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER, + EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) + scn.current_frame = orig_frame @@ -1412,11 +1174,14 @@ def do_export(filename, context): # Window.WaitCursor(0) -class SCRIPT_OT_export_obj(bpy.types.Operator): +class EXPORT_OT_obj(bpy.types.Operator): ''' - Operator documentatuon text, will be used for the operator tooltip and python docs. + Currently the exporter lacks these features: + * nurbs + * multiple scene export (only active scene is written) + * particles ''' - __label__ = 'My Operator' + __label__ = 'Export OBJ' # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 3127c352f60..4b4c9b97871 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -736,6 +736,11 @@ static void rna_def_medge(BlenderRNA *brna) prop= RNA_def_property(srna, "sharp", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SHARP); RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier"); + + prop= RNA_def_property(srna, "loose", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_LOOSEEDGE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Loose", "Loose edge"); } static void rna_def_mface(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 40f29360e9c..1b6c298eba4 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -57,7 +57,9 @@ /* copied from init_render_mesh (render code) */ static Mesh *create_mesh(Object *ob, bContext *C, ReportList *reports, int render_mesh) { - CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; + /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */ + CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter, + for example, needs CD_MASK_MDEFORMVERT */ DerivedMesh *dm; Mesh *me; Scene *sce; -- cgit v1.2.3 From 1557736756b41dfa8fff4d7c887a7d6da2b1f468 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sun, 28 Jun 2009 13:29:03 +0000 Subject: OBJ exporter working (Python 3.0), but needs testing and fixing. Current issues: - NURBS - needs API additions - "all scenes" export - cannot switch scene in bpy - normal calculation, disabled - duplis - need testing, only dupliverts tested - matrix problem - UI, 18 options currently don't fit into filesel panel, will do manual lay out once it's available - probably others... BPY: - made operator "execute" method required to avoid crash - added bpy.sys module which replicates old "sys" module API: - replaced create_*_mesh with a single create_mesh accepting type parameter - added Mesh.create_copy to create a copy of a mesh with 0 users Ran `dos2unix` on source/blender/python/SConscript --- release/io/export_obj.py | 978 ++++++++++++++++- release/io/export_ply.py | 6 +- release/scripts/3ds_export.py | 24 +- release/scripts/export_obj-2.5.py | 1217 ---------------------- release/ui/space_script.py | 4 +- source/blender/makesrna/intern/rna_mesh_api.c | 15 + source/blender/makesrna/intern/rna_object_api.c | 60 +- source/blender/python/intern/bpy_interface.c | 2 + source/blender/python/intern/bpy_operator_wrap.c | 2 +- source/blender/python/intern/bpy_rna.c | 8 +- source/blender/python/intern/bpy_sys.c | 460 ++++++++ source/blender/python/intern/bpy_sys.h | 41 + 12 files changed, 1497 insertions(+), 1320 deletions(-) delete mode 100644 release/scripts/export_obj-2.5.py create mode 100644 source/blender/python/intern/bpy_sys.c create mode 100644 source/blender/python/intern/bpy_sys.h diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 8b3bcfb26b3..d139e872251 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -1,83 +1,961 @@ +#!BPY + +""" +Name: 'Wavefront (.obj)...' +Blender: 248 +Group: 'Export' +Tooltip: 'Save a Wavefront OBJ File' +""" + +__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone" +__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] +__version__ = "1.21" + +__bpydoc__ = """\ +This script is an exporter to OBJ file format. + +Usage: + +Select the objects you wish to export and run this script from "File->Export" menu. +Selecting the default options from the popup box will be good in most cases. +All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) +will be exported as mesh data. +""" + + +# -------------------------------------------------------------------------- +# OBJ Export v1.1 by Campbell Barton (AKA Ideasman) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + import bpy +import os # os.sep +import Mathutils + +# Returns a tuple - path,extension. +# 'hello.obj' > ('hello', '.obj') +def splitExt(path): + dotidx = path.rfind('.') + if dotidx == -1: + return path, '' + else: + return path[:dotidx], path[dotidx:] + +def fixName(name): + if name == None: + return 'None' + else: + return name.replace(' ', '_') + + +# this used to be in BPySys module +# frankly, I don't understand how it works +def BPySys_cleanName(name): + + v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] + + invalid = ''.join([chr(i) for i in v]) + + for ch in invalid: + name = name.replace(ch, '_') + return name + +# A Dict of Materials +# (material.name, image.name):matname_imagename # matname_imagename has gaps removed. +MTL_DICT = {} -def write_obj(filepath, scene, ob): - out = open(filepath, 'w') +def write_mtl(scene, filename): - # create a temporary mesh - mesh = ob.create_render_mesh(scene) + world = scene.world + worldAmb = world.ambient_color - # for vert in mesh.verts: - # ^ iterating that way doesn't work atm for some reason + file = open(filename, "w") + # XXX +# file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) + file.write('# Material Count: %i\n' % len(MTL_DICT)) + # Write material/image combinations we have used. + for key, (mtl_mat_name, mat, img) in MTL_DICT.items(): + + # Get the Blender data for the material and the image. + # Having an image named None will make a bug, dont do it :) + + file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname + + if mat: + file.write('Ns %.6f\n' % ((mat.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's + file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_reflection for c in mat.diffuse_color]) ) # Diffuse + file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_reflection for c in mat.specular_color]) ) # Specular + file.write('Ni %.6f\n' % mat.ior) # Refraction index + file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) - for i in range(len(mesh.verts)): - vert = mesh.verts[i] - out.write('v {0} {1} {2}\n'.format(vert.co[0], vert.co[1], vert.co[2])) + # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. + if mat.shadeless: + file.write('illum 0\n') # ignore lighting + elif mat.specular_reflection == 0: + file.write('illum 1\n') # no specular. + else: + file.write('illum 2\n') # light normaly + + else: + #write a dummy material here? + file.write('Ns 0\n') + file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Kd 0.8 0.8 0.8\n') + file.write('Ks 0.8 0.8 0.8\n') + file.write('d 1\n') # No alpha + file.write('illum 2\n') # light normaly + + # Write images! + if img: # We have an image on the face! + file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image + + elif mat: # No face image. if we havea material search for MTex image. + for mtex in mat.textures: + if mtex and mtex.texure.type == 'IMAGE': + try: + filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1] + file.write('map_Kd %s\n' % filename) # Diffuse mapping image + break + except: + # Texture has no image though its an image type, best ignore. + pass + + file.write('\n\n') - for i in range(len(mesh.faces)): - face = mesh.faces[i] - out.write('f') + file.close() - # but this works - for index in face.verts: - out.write(' {0}'.format(index + 1)) - out.write('\n') +def copy_file(source, dest): + file = open(source, 'rb') + data = file.read() + file.close() + + file = open(dest, 'wb') + file.write(data) + file.close() - # delete mesh gain - bpy.data.remove_mesh(mesh) - out.close() +def copy_images(dest_dir): + if dest_dir[-1] != os.sep: + dest_dir += os.sep +# if dest_dir[-1] != sys.sep: +# dest_dir += sys.sep -class SCRIPT_OT_export_obj(bpy.types.Operator): - '''A very basic OBJ exporter, writes only active object's mesh.''' + # Get unique image names + uniqueImages = {} + for matname, mat, image in MTL_DICT.values(): # Only use image name + # Get Texface images + if image: + uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default. + + # Get MTex images + if mat: + for mtex in mat.textures: + if mtex and mtex.texture.type == 'IMAGE': + image_tex = mtex.texture.image + if image_tex: + try: + uniqueImages[image_tex] = image_tex + except: + pass + + # Now copy images + copyCount = 0 + + for bImage in uniqueImages.values(): + image_path = bpy.sys.expandpath(bImage.filename) + if bpy.sys.exists(image_path): + # Make a name for the target path. + dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] + if not bpy.sys.exists(dest_image_path): # Image isnt alredy there + print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) + copy_file(image_path, dest_image_path) + copyCount+=1 - __label__ = 'Export OBJ' + print('\tCopied %d images' % copyCount) + +# XXX not converted +def test_nurbs_compat(ob): + if ob.type != 'CURVE': + return False - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - __props__ = [ - bpy.props.StringProperty(attr="filename", name="filename") - ] + for nu in ob.data.curves: + if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier + return True - def debug(self, message): - print("{0}: {1}".format(self.__class__.__name__, message)) +# for nu in ob.data: +# if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier +# return True + + return False - def execute_(self, context): - self.debug("exec") - self.debug("filename = " + self.filename) +# XXX not converted +def write_nurb(file, ob, ob_mat): + tot_verts = 0 + cu = ob.data + + # use negative indices + Vector = Blender.Mathutils.Vector + for nu in cu: + + if nu.type==0: DEG_ORDER_U = 1 + else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct + + if nu.type==1: + print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported") + continue + + if nu.knotsV: + print("\tWarning, surface:", ob.name, "only poly and nurbs curves supported") + continue + + if len(nu) <= DEG_ORDER_U: + print("\tWarning, orderU is lower then vert count, skipping:", ob.name) + continue + + pt_num = 0 + do_closed = (nu.flagU & 1) + do_endpoints = (do_closed==0) and (nu.flagU & 2) + + for pt in nu: + pt = Vector(pt[0], pt[1], pt[2]) * ob_mat + file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2])) + pt_num += 1 + tot_verts += pt_num + + file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too + file.write('cstype bspline\n') # not ideal, hard coded + file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still + + curve_ls = [-(i+1) for i in range(pt_num)] + + # 'curv' keyword + if do_closed: + if DEG_ORDER_U == 1: + pt_num += 1 + curve_ls.append(-1) + else: + pt_num += DEG_ORDER_U + curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U] + + file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve + + # 'parm' keyword + tot_parm = (DEG_ORDER_U + 1) + pt_num + tot_parm_div = float(tot_parm-1) + parm_ls = [(i/tot_parm_div) for i in range(tot_parm)] + + if do_endpoints: # end points, force param + for i in range(DEG_ORDER_U+1): + parm_ls[i] = 0.0 + parm_ls[-(1+i)] = 1.0 + + file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] )) - act = context.active_object + file.write('end\n') + + return tot_verts - if act.type == 'MESH': - write_obj(self.filename, context.scene, act) +def write(filename, objects, scene, + EXPORT_TRI=False, + EXPORT_EDGES=False, + EXPORT_NORMALS=False, + EXPORT_NORMALS_HQ=False, + EXPORT_UV=True, + EXPORT_MTL=True, + EXPORT_COPY_IMAGES=False, + EXPORT_APPLY_MODIFIERS=True, + EXPORT_ROTX90=True, + EXPORT_BLEN_OBS=True, + EXPORT_GROUP_BY_OB=False, + EXPORT_GROUP_BY_MAT=False, + EXPORT_KEEP_VERT_ORDER=False, + EXPORT_POLYGROUPS=False, + EXPORT_CURVE_AS_NURBS=True): + ''' + Basic write function. The context and options must be alredy set + This can be accessed externaly + eg. + write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. + ''' + + def veckey3d(v): + return round(v.x, 6), round(v.y, 6), round(v.z, 6) + + def veckey2d(v): + return round(v.x, 6), round(v.y, 6) + + def findVertexGroupName(face, vWeightMap): + """ + Searches the vertexDict to see what groups is assigned to a given face. + We use a frequency system in order to sort out the name because a given vetex can + belong to two or more groups at the same time. To find the right name for the face + we list all the possible vertex group names with their frequency and then sort by + frequency in descend order. The top element is the one shared by the highest number + of vertices is the face's group + """ + weightDict = {} + for vert_index in face.verts: +# for vert in face: + vWeights = vWeightMap[vert_index] +# vWeights = vWeightMap[vert] + for vGroupName, weight in vWeights: + weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight + + if weightDict: + alist = [(weight,vGroupName) for vGroupName, weight in weightDict.items()] # sort least to greatest amount of weight + alist.sort() + return(alist[-1][1]) # highest value last else: - self.debug("Active object is not a MESH.") + return '(null)' - # XXX errors are silenced for some reason -# raise Exception("oops!") + # TODO: implement this in C? dunno how it should be called... + def getVertsFromGroup(me, group_index): + ret = [] - return ('FINISHED',) + for i, v in enumerate(me.verts): + for g in v.groups: + if g.group == group_index: + ret.append((i, g.weight)) - def execute(self, context): - self.debug("exec") + return ret + + + print('OBJ Export path: "%s"' % filename) + temp_mesh_name = '~tmp-mesh' + + time1 = bpy.sys.time() +# time1 = sys.time() +# scn = Scene.GetCurrent() + + file = open(filename, "w") + + # Write Header + version = "2.5" + file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] )) + file.write('# www.blender3d.org\n') + + # Tell the obj file what material file to use. + if EXPORT_MTL: + mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) + file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) + + if EXPORT_ROTX90: + mat_xrot90= Mathutils.RotationMatrix(-90, 4, 'x') + + # Initialize totals, these are updated each object + totverts = totuvco = totno = 1 + + face_vert_index = 1 + + globalNormals = {} + + # Get all meshes + for ob_main in objects: + + if ob_main.dupli_type != 'NONE': + # XXX + print('creating dupli_list on', ob_main.name) + ob_main.create_dupli_list() + + # ignore dupli children + if ob_main.parent and ob_main.parent.dupli_type != 'NONE': + # XXX + print(ob_main.name, 'is a dupli child - ignoring') + continue + + obs = [] + if ob_main.dupli_type != 'NONE': + obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list] + + # XXX + print(ob_main.name, 'has', len(obs), 'dupli children') + else: + obs = [(ob_main, ob_main.matrix)] + + for ob, ob_mat in obs: + + if EXPORT_ROTX90: + ob_mat = ob_mat * mat_xrot90 + + # XXX postponed +# # Nurbs curve support +# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): +# if EXPORT_ROTX90: +# ob_mat = ob_mat * mat_xrot90 + +# totverts += write_nurb(file, ob, ob_mat) + +# continue +# end nurbs + + if ob.type != 'MESH': + continue + + if EXPORT_APPLY_MODIFIERS: + me = ob.create_mesh('PREVIEW') + else: + me = ob.data.create_copy() + + me.transform(ob_mat) + +# # Will work for non meshes now! :) +# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) +# if not me: +# continue + + if EXPORT_UV: + faceuv = len(me.uv_layers) > 0 + else: + faceuv = False + + # We have a valid mesh + if EXPORT_TRI and me.faces: + # Add a dummy object to it. + has_quads = False + for f in me.faces: + if f.verts[3] != 0: + has_quads = True + break + + if has_quads: + newob = bpy.data.add_object('MESH', 'temp_object') + newob.data = me + # if we forget to set Object.data - crash + scene.add_object(newob) + newob.convert_to_triface(scene) + # mesh will still be there + scene.remove_object(newob) + + # Make our own list so it can be sorted to reduce context switching + face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)] + # faces = [ f for f in me.faces ] + + if EXPORT_EDGES: + edges = me.edges + else: + edges = [] + + if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write + + # clean up + bpy.data.remove_mesh(me) + + continue # dont bother with this mesh. + + # XXX + # High Quality Normals + if EXPORT_NORMALS and face_index_pairs: + pass +# if EXPORT_NORMALS_HQ: +# BPyMesh.meshCalcNormals(me) +# else: +# # transforming normals is incorrect +# # when the matrix is scaled, +# # better to recalculate them +# me.calcNormals() + + materials = me.materials + + materialNames = [] + materialItems = [m for m in materials] + if materials: + for mat in materials: + if mat: # !=None + materialNames.append(mat.name) + else: + materialNames.append(None) + # Cant use LC because some materials are None. + # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. + + # Possible there null materials, will mess up indicies + # but at least it will export, wait until Blender gets fixed. + materialNames.extend((16-len(materialNames)) * [None]) + materialItems.extend((16-len(materialItems)) * [None]) + + # Sort by Material, then images + # so we dont over context switch in the obj file. + if EXPORT_KEEP_VERT_ORDER: + pass + elif faceuv: + # XXX update + tface = me.active_uv_layer.data + + # exception only raised if Python 2.3 or lower... + try: + face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth)) + except: + face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth), + (b[0].material_index, tface[b[1]].image, b[0].smooth))) + elif len(materials) > 1: + try: + face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth)) + except: + face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth), + (b[0].material_index, b[0].smooth))) + else: + # no materials + try: + face_index_pairs.sort(key = lambda a: a[0].smooth) + except: + face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth)) +# if EXPORT_KEEP_VERT_ORDER: +# pass +# elif faceuv: +# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) +# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) +# elif len(materials) > 1: +# try: faces.sort(key = lambda a: (a.mat, a.smooth)) +# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) +# else: +# # no materials +# try: faces.sort(key = lambda a: a.smooth) +# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) + + faces = [pair[0] for pair in face_index_pairs] + + # Set the default mat to no material and no image. + contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. + contextSmooth = None # Will either be true or false, set bad to force initialization switch. + + if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: + name1 = ob.name + name2 = ob.data.name + if name1 == name2: + obnamestring = fixName(name1) + else: + obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) + + if EXPORT_BLEN_OBS: + file.write('o %s\n' % obnamestring) # Write Object name + else: # if EXPORT_GROUP_BY_OB: + file.write('g %s\n' % obnamestring) + + + # Vert + for v in me.verts: + file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) + + # UV + if faceuv: + uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ + + uv_dict = {} # could use a set() here + uv_layer = me.active_uv_layer + for f, f_index in face_index_pairs: + + tface = uv_layer.data[f_index] + + uvs = [tface.uv1, tface.uv2, tface.uv3] + + # add another UV if it's a quad + if f.verts[3] != 0: + uvs.append(tface.uv4) + + for uv_index, uv in enumerate(uvs): + uvkey = veckey2d(uv) + try: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] + except: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) + file.write('vt %.6f %.6f\n' % tuple(uv)) + +# uv_dict = {} # could use a set() here +# for f_index, f in enumerate(faces): + +# for uv_index, uv in enumerate(f.uv): +# uvkey = veckey2d(uv) +# try: +# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] +# except: +# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) +# file.write('vt %.6f %.6f\n' % tuple(uv)) + + uv_unique_count = len(uv_dict) + del uv, uvkey, uv_dict, f_index, uv_index + # Only need uv_unique_count and uv_face_mapping + + # NORMAL, Smooth/Non smoothed. + if EXPORT_NORMALS: + for f in faces: + if f.smooth: + for v in f: + noKey = veckey3d(v.normal) + if noKey not in globalNormals: + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + else: + # Hard, 1 normal from the face. + noKey = veckey3d(f.normal) + if noKey not in globalNormals: + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + + if not faceuv: + f_image = None + + # XXX + if EXPORT_POLYGROUPS: + # Retrieve the list of vertex groups +# vertGroupNames = me.getVertGroupNames() + + currentVGroup = '' + # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to + vgroupsMap = [[] for _i in range(len(me.verts))] +# vgroupsMap = [[] for _i in xrange(len(me.verts))] + for g in ob.vertex_groups: +# for vertexGroupName in vertGroupNames: + for vIdx, vWeight in getVertsFromGroup(me, g.index): +# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): + vgroupsMap[vIdx].append((g.name, vWeight)) + + for f_index, f in enumerate(faces): + f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts] + + if f.verts[3] == 0: + f_v.pop() + +# f_v= f.v + f_smooth= f.smooth + f_mat = min(f.material_index, len(materialNames)-1) +# f_mat = min(f.mat, len(materialNames)-1) + if faceuv: + + tface = me.active_uv_layer.data[face_index_pairs[f_index][1]] + + f_image = tface.image + f_uv= [tface.uv1, tface.uv2, tface.uv3] + if f.verts[3] != 0: + f_uv.append(tface.uv4) +# f_image = f.image +# f_uv= f.uv + + # MAKE KEY + if faceuv and f_image: # Object is always true. + key = materialNames[f_mat], f_image.name + else: + key = materialNames[f_mat], None # No image, use None instead. + + # Write the vertex group + if EXPORT_POLYGROUPS: + if len(ob.vertex_groups): + # find what vertext group the face belongs to + theVGroup = findVertexGroupName(f,vgroupsMap) + if theVGroup != currentVGroup: + currentVGroup = theVGroup + file.write('g %s\n' % theVGroup) +# # Write the vertex group +# if EXPORT_POLYGROUPS: +# if vertGroupNames: +# # find what vertext group the face belongs to +# theVGroup = findVertexGroupName(f,vgroupsMap) +# if theVGroup != currentVGroup: +# currentVGroup = theVGroup +# file.write('g %s\n' % theVGroup) + + # CHECK FOR CONTEXT SWITCH + if key == contextMat: + pass # Context alredy switched, dont do anything + else: + if key[0] == None and key[1] == None: + # Write a null material, since we know the context has changed. + if EXPORT_GROUP_BY_MAT: + # can be mat_image or (null) + file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.data.name)) ) # can be mat_image or (null) + file.write('usemtl (null)\n') # mat, image + + else: + mat_data= MTL_DICT.get(key) + if not mat_data: + # First add to global dict so we can export to mtl + # Then write mtl + + # Make a new names from the mat and image name, + # converting any spaces to underscores with fixName. + + # If none image dont bother adding it to the name + if key[1] == None: + mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image + else: + mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image + + if EXPORT_GROUP_BY_MAT: + file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.data.name), mat_data[0]) ) # can be mat_image or (null) + + file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) + + contextMat = key + if f_smooth != contextSmooth: + if f_smooth: # on now off + file.write('s 1\n') + contextSmooth = f_smooth + else: # was off now on + file.write('s off\n') + contextSmooth = f_smooth + + file.write('f') + if faceuv: + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % \ + (v["index"] + totverts, + totuvco + uv_face_mapping[f_index][vi], + globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal + + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.normal) ] + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % \ + (v["index"] + totverts, + totuvco + uv_face_mapping[f_index][vi], + no) ) # vert, uv, normal + else: # No Normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d' % (\ + v["index"] + totverts,\ + totuvco + uv_face_mapping[f_index][vi])) # vert, uv + + face_vert_index += len(f_v) + + else: # No UV's + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for v in f_v: + file.write( ' %d//%d' % + (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) ) + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.normal) ] + for v in f_v: + file.write( ' %d//%d' % (v["index"] + totverts, no) ) + else: # No Normals + for v in f_v: + file.write( ' %d' % (v["index"] + totverts) ) + + file.write('\n') + + # Write edges. + if EXPORT_EDGES: + for ed in edges: + if ed.loose: + file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts)) + + # Make the indicies global rather then per mesh + totverts += len(me.verts) + if faceuv: + totuvco += uv_unique_count + + # clean up + bpy.data.remove_mesh(me) + + if ob_main.dupli_type != 'NONE': + ob_main.free_dupli_list() + + file.close() + + + # Now we have all our materials, save them + if EXPORT_MTL: + write_mtl(scene, mtlfilename) + if EXPORT_COPY_IMAGES: + dest_dir = filename + # Remove chars until we are just the path. + while dest_dir and dest_dir[-1] not in '\\/': + dest_dir = dest_dir[:-1] + if dest_dir: + copy_images(dest_dir) + else: + print('\tError: "%s" could not be used as a base for an image path.' % filename) + + print("OBJ Export time: %.2f" % (bpy.sys.time() - time1)) +# print "OBJ Export time: %.2f" % (sys.time() - time1) + +def do_export(filename, context, + EXPORT_APPLY_MODIFIERS = True, # not used + EXPORT_ROTX90 = True, # wrong + EXPORT_TRI = False, # ok + EXPORT_EDGES = False, + EXPORT_NORMALS = False, # not yet + EXPORT_NORMALS_HQ = False, # not yet + EXPORT_UV = True, # ok + EXPORT_MTL = True, + EXPORT_SEL_ONLY = True, # ok + EXPORT_ALL_SCENES = False, # XXX not working atm + EXPORT_ANIMATION = False, + EXPORT_COPY_IMAGES = False, + EXPORT_BLEN_OBS = True, + EXPORT_GROUP_BY_OB = False, + EXPORT_GROUP_BY_MAT = False, + EXPORT_KEEP_VERT_ORDER = False, + EXPORT_POLYGROUPS = False, + EXPORT_CURVE_AS_NURBS = True): + # Window.EditMode(0) + # Window.WaitCursor(1) + + base_name, ext = splitExt(filename) + context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension + + orig_scene = context.scene + +# if EXPORT_ALL_SCENES: +# export_scenes = bpy.data.scenes +# else: +# export_scenes = [orig_scene] + + # XXX only exporting one scene atm since changing + # current scene is not possible. + # Brecht says that ideally in 2.5 we won't need such a function, + # allowing multiple scenes open at once. + export_scenes = [orig_scene] + + # Export all scenes. + for scn in export_scenes: + # scn.makeCurrent() # If already current, this is not slow. + # context = scn.getRenderingContext() + orig_frame = scn.current_frame + + if EXPORT_ALL_SCENES: # Add scene name into the context_name + context_name[1] = '_%s' % BPySys_cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. + + # Export an animation? + if EXPORT_ANIMATION: + scene_frames = range(scn.start_frame, context.end_frame+1) # Up to and including the end frame. + else: + scene_frames = [orig_frame] # Dont export an animation. - act = context.active_object + # Loop through all frames in the scene and export. + for frame in scene_frames: + if EXPORT_ANIMATION: # Add frame to the filename. + context_name[2] = '_%.6d' % frame + + scn.current_frame = frame + if EXPORT_SEL_ONLY: + export_objects = context.selected_objects + else: + export_objects = scn.objects + + full_path= ''.join(context_name) + + # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. + # EXPORT THE FILE. + write(full_path, export_objects, scn, + EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, + EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, + EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, + EXPORT_ROTX90, EXPORT_BLEN_OBS, + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER, + EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) + + + scn.current_frame = orig_frame + + # Restore old active scene. +# orig_scene.makeCurrent() +# Window.WaitCursor(0) - act.create_dupli_list() - print("{0} has {1} dupli objects".format(act.name, len(act.dupli_list))) - act.free_dupli_list() +class EXPORT_OT_obj(bpy.types.Operator): + ''' + Currently the exporter lacks these features: + * nurbs + * multiple scene export (only active scene is written) + * particles + ''' + __label__ = 'Export OBJ' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), + + # context group + bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= True), + bpy.props.BoolProperty(attr="use_all_scenes", name="All Scenes", description="", default= False), + bpy.props.BoolProperty(attr="use_animation", name="All Animation", description="", default= False), + + # object group + bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="", default= True), + bpy.props.BoolProperty(attr="use_rotate90", name="Rotate X90", description="", default= True), + + # extra data group + bpy.props.BoolProperty(attr="use_edges", name="Edges", description="", default= True), + bpy.props.BoolProperty(attr="use_normals", name="Normals", description="", default= False), + bpy.props.BoolProperty(attr="use_hq_normals", name="High Quality Normals", description="", default= True), + bpy.props.BoolProperty(attr="use_uvs", name="UVs", description="", default= True), + bpy.props.BoolProperty(attr="use_materials", name="Materials", description="", default= True), + bpy.props.BoolProperty(attr="copy_images", name="Copy Images", description="", default= False), + bpy.props.BoolProperty(attr="use_triangles", name="Triangulate", description="", default= False), + bpy.props.BoolProperty(attr="use_vertex_groups", name="Polygroups", description="", default= False), + bpy.props.BoolProperty(attr="use_nurbs", name="Nurbs", description="", default= False), + + # grouping group + bpy.props.BoolProperty(attr="use_blen_objects", name="Objects as OBJ Objects", description="", default= True), + bpy.props.BoolProperty(attr="group_by_object", name="Objects as OBJ Groups ", description="", default= False), + bpy.props.BoolProperty(attr="group_by_material", name="Material Groups", description="", default= False), + bpy.props.BoolProperty(attr="keep_vertex_order", name="Keep Vertex Order", description="", default= False) + ] + + def execute(self, context): + + do_export(self.filename, context, + EXPORT_TRI=self.use_triangles, + EXPORT_EDGES=self.use_edges, + EXPORT_NORMALS=self.use_normals, + EXPORT_NORMALS_HQ=self.use_hq_normals, + EXPORT_UV=self.use_uvs, + EXPORT_MTL=self.use_materials, + EXPORT_COPY_IMAGES=self.copy_images, + EXPORT_APPLY_MODIFIERS=self.use_modifiers, + EXPORT_ROTX90=self.use_rotate90, + EXPORT_BLEN_OBS=self.use_blen_objects, + EXPORT_GROUP_BY_OB=self.group_by_object, + EXPORT_GROUP_BY_MAT=self.group_by_material, + EXPORT_KEEP_VERT_ORDER=self.keep_vertex_order, + EXPORT_POLYGROUPS=self.use_vertex_groups, + EXPORT_CURVE_AS_NURBS=self.use_nurbs, + EXPORT_SEL_ONLY=self.use_selection, + EXPORT_ALL_SCENES=self.use_all_scenes) return ('FINISHED',) def invoke(self, context, event): - self.debug("invoke") wm = context.manager wm.add_fileselect(self.__operator__) return ('RUNNING_MODAL',) - def poll(self, context): # poll isnt working yet - self.debug("poll") - return True + def poll(self, context): # Poll isnt working yet + print("Poll") + return context.active_object != None + +bpy.ops.add(EXPORT_OT_obj) -bpy.ops.add(SCRIPT_OT_export_obj) +if __name__ == "__main__": + bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj") +# CONVERSION ISSUES +# - matrix problem +# - duplis - only tested dupliverts +# - NURBS - needs API additions +# - all scenes export +# - normals calculation diff --git a/release/io/export_ply.py b/release/io/export_ply.py index ed983c2b169..ce1cdc55d09 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -64,7 +64,7 @@ def write(filename, scene, ob, \ raise Exception("Error, Select 1 active object") return - file = open(filename, 'wb') + file = open(filename, 'w') #EXPORT_EDGES = Draw.Create(0) @@ -123,8 +123,8 @@ def write(filename, scene, ob, \ mesh_verts = mesh.verts # save a lookup ply_verts = [] # list of dictionaries # vdict = {} # (index, normal, uv) -> new index - vdict = [{} for i in xrange(len(mesh_verts))] - ply_faces = [[] for f in xrange(len(mesh.faces))] + vdict = [{} for i in range(len(mesh_verts))] + ply_faces = [[] for f in range(len(mesh.faces))] vert_count = 0 for i, f in enumerate(mesh.faces): diff --git a/release/scripts/3ds_export.py b/release/scripts/3ds_export.py index 87680bce1b0..69b4d00b4d8 100644 --- a/release/scripts/3ds_export.py +++ b/release/scripts/3ds_export.py @@ -863,19 +863,24 @@ def make_kf_obj_node(obj, name_to_id): """ import BPyMessages -def save_3ds(filename): +def save_3ds(filename, context): '''Save the Blender scene to a 3ds file.''' # Time the export if not filename.lower().endswith('.3ds'): filename += '.3ds' - - if not BPyMessages.Warning_SaveOver(filename): - return - - time1= Blender.sys.time() - Blender.Window.WaitCursor(1) - sce= bpy.data.scenes.active + + # XXX +# if not BPyMessages.Warning_SaveOver(filename): +# return + + # XXX + time1 = bpy.sys.time() +# time1= Blender.sys.time() +# Blender.Window.WaitCursor(1) + + sce = context.scene +# sce= bpy.data.scenes.active # Initialize the main chunk (primary): primary = _3ds_chunk(PRIMARY) @@ -901,7 +906,8 @@ def save_3ds(filename): # each material is added once): materialDict = {} mesh_objects = [] - for ob in sce.objects.context: + for ob in context.selected_objects: +# for ob in sce.objects.context: for ob_derived, mat in getDerivedObjects(ob, False): data = getMeshFromObject(ob_derived, None, True, False, sce) if data: diff --git a/release/scripts/export_obj-2.5.py b/release/scripts/export_obj-2.5.py deleted file mode 100644 index cd8e423ed07..00000000000 --- a/release/scripts/export_obj-2.5.py +++ /dev/null @@ -1,1217 +0,0 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 248 -Group: 'Export' -Tooltip: 'Save a Wavefront OBJ File' -""" - -__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone" -__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] -__version__ = "1.21" - -__bpydoc__ = """\ -This script is an exporter to OBJ file format. - -Usage: - -Select the objects you wish to export and run this script from "File->Export" menu. -Selecting the default options from the popup box will be good in most cases. -All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) -will be exported as mesh data. -""" - - -# -------------------------------------------------------------------------- -# OBJ Export v1.1 by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -import bpy -# import BPySys - -# import Blender -# from Blender import Mesh, Scene, Window, sys, Image, Draw -# import BPyMesh -# import BPyObject -# import BPySys -# import BPyMessages - -# Returns a tuple - path,extension. -# 'hello.obj' > ('hello', '.obj') -def splitExt(path): - dotidx = path.rfind('.') - if dotidx == -1: - return path, '' - else: - return path[:dotidx], path[dotidx:] - -def fixName(name): - if name == None: - return 'None' - else: - return name.replace(' ', '_') - -# A Dict of Materials -# (material.name, image.name):matname_imagename # matname_imagename has gaps removed. -MTL_DICT = {} - -def write_mtl(scene, filename): - - world = bpy.data.worlds[0] - worldAmb = world.ambient_color - -# world = Blender.World.GetCurrent() -# if world: -# worldAmb = world.getAmb() -# else: -# worldAmb = (0,0,0) # Default value - - file = open(filename, "w") - # XXX -# file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) - file.write('# Material Count: %i\n' % len(MTL_DICT)) - # Write material/image combinations we have used. - for key, (mtl_mat_name, mat, img) in MTL_DICT.iteritems(): - - # Get the Blender data for the material and the image. - # Having an image named None will make a bug, dont do it :) - - file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname - - if mat: - file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's - file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse - file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular - file.write('Ni %.6f\n' % mat.IOR) # Refraction index - file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) - - # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. - if mat.getMode() & Blender.Material.Modes['SHADELESS']: - file.write('illum 0\n') # ignore lighting - elif mat.getSpec() == 0: - file.write('illum 1\n') # no specular. - else: - file.write('illum 2\n') # light normaly - - else: - #write a dummy material here? - file.write('Ns 0\n') - file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd 0.8 0.8 0.8\n') - file.write('Ks 0.8 0.8 0.8\n') - file.write('d 1\n') # No alpha - file.write('illum 2\n') # light normaly - - # Write images! - if img: # We have an image on the face! - file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image - - elif mat: # No face image. if we havea material search for MTex image. - for mtex in mat.getTextures(): - if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: - try: - filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1] - file.write('map_Kd %s\n' % filename) # Diffuse mapping image - break - except: - # Texture has no image though its an image type, best ignore. - pass - - file.write('\n\n') - - file.close() - -def copy_file(source, dest): - file = open(source, 'rb') - data = file.read() - file.close() - - file = open(dest, 'wb') - file.write(data) - file.close() - - -def copy_images(dest_dir): - if dest_dir[-1] != sys.sep: - dest_dir += sys.sep - - # Get unique image names - uniqueImages = {} - for matname, mat, image in MTL_DICT.itervalues(): # Only use image name - # Get Texface images - if image: - uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default. - - # Get MTex images - if mat: - for mtex in mat.getTextures(): - if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: - image_tex = mtex.tex.image - if image_tex: - try: - uniqueImages[image_tex] = image_tex - except: - pass - - # Now copy images - copyCount = 0 - - for bImage in uniqueImages.itervalues(): - image_path = sys.expandpath(bImage.filename) - if sys.exists(image_path): - # Make a name for the target path. - dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] - if not sys.exists(dest_image_path): # Image isnt alredy there - print '\tCopying "%s" > "%s"' % (image_path, dest_image_path) - copy_file(image_path, dest_image_path) - copyCount+=1 - print '\tCopied %d images' % copyCount - - -def test_nurbs_compat(ob): - if ob.type != 'CURVE': - return False - - for nu in ob.data: - if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier - return True - - return False - -def write_nurb(file, ob, ob_mat): - tot_verts = 0 - cu = ob.data - - # use negative indices - Vector = Blender.Mathutils.Vector - for nu in cu: - - if nu.type==0: DEG_ORDER_U = 1 - else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct - - if nu.type==1: - print "\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported" - continue - - if nu.knotsV: - print "\tWarning, surface:", ob.name, "only poly and nurbs curves supported" - continue - - if len(nu) <= DEG_ORDER_U: - print "\tWarning, orderU is lower then vert count, skipping:", ob.name - continue - - pt_num = 0 - do_closed = (nu.flagU & 1) - do_endpoints = (do_closed==0) and (nu.flagU & 2) - - for pt in nu: - pt = Vector(pt[0], pt[1], pt[2]) * ob_mat - file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2])) - pt_num += 1 - tot_verts += pt_num - - file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too - file.write('cstype bspline\n') # not ideal, hard coded - file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still - - curve_ls = [-(i+1) for i in xrange(pt_num)] - - # 'curv' keyword - if do_closed: - if DEG_ORDER_U == 1: - pt_num += 1 - curve_ls.append(-1) - else: - pt_num += DEG_ORDER_U - curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U] - - file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve - - # 'parm' keyword - tot_parm = (DEG_ORDER_U + 1) + pt_num - tot_parm_div = float(tot_parm-1) - parm_ls = [(i/tot_parm_div) for i in xrange(tot_parm)] - - if do_endpoints: # end points, force param - for i in xrange(DEG_ORDER_U+1): - parm_ls[i] = 0.0 - parm_ls[-(1+i)] = 1.0 - - file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] )) - - file.write('end\n') - - return tot_verts - -def write(filename, objects, scene, \ -EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ -EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ -EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ -EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False,\ -EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): - ''' - Basic write function. The context and options must be alredy set - This can be accessed externaly - eg. - write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. - ''' - - def veckey3d(v): - return round(v.x, 6), round(v.y, 6), round(v.z, 6) - - def veckey2d(v): - return round(v.x, 6), round(v.y, 6) - - def findVertexGroupName(face, vWeightMap): - """ - Searches the vertexDict to see what groups is assigned to a given face. - We use a frequency system in order to sort out the name because a given vetex can - belong to two or more groups at the same time. To find the right name for the face - we list all the possible vertex group names with their frequency and then sort by - frequency in descend order. The top element is the one shared by the highest number - of vertices is the face's group - """ - weightDict = {} - for vert_index in face.verts: -# for vert in face: - vWeights = vWeightMap[vert_index] -# vWeights = vWeightMap[vert] - for vGroupName, weight in vWeights: - weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight - - if weightDict: - alist = [(weight,vGroupName) for vGroupName, weight in weightDict.iteritems()] # sort least to greatest amount of weight - alist.sort() - return(alist[-1][1]) # highest value last - else: - return '(null)' - - # TODO: implement this in C? dunno how it should be called... - def getVertsFromGroup(me, group_index): - ret = [] - - for i, v in enumerate(me.verts): - for g in v.groups: - if g.group == group.index: - ret.append((i, g.weight)) - - return ret - - - print 'OBJ Export path: "%s"' % filename - temp_mesh_name = '~tmp-mesh' - - time1 = sys.time() -# scn = Scene.GetCurrent() - scene = context.scene - - file = open(filename, "w") - - # Write Header - file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) - file.write('# www.blender3d.org\n') - - # Tell the obj file what material file to use. - if EXPORT_MTL: - mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) - file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) - - # Get the container mesh. - used for applying modifiers and non mesh objects. - -# containerMesh = meshName = tempMesh = None -# for meshName in Blender.NMesh.GetNames(): -# if meshName.startswith(temp_mesh_name): -# tempMesh = Mesh.Get(meshName) -# if not tempMesh.users: -# containerMesh = tempMesh -# if not containerMesh: -# containerMesh = Mesh.New(temp_mesh_name) - - # XXX this mesh is not removed - # XXX this mesh should not be in database - containerMesh = bpy.data.add_mesh(temp_mesh_name) - - if EXPORT_ROTX90: - mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x') - -# del meshName -# del tempMesh - - # Initialize totals, these are updated each object - totverts = totuvco = totno = 1 - - face_vert_index = 1 - - globalNormals = {} - - # Get all meshes - for ob_main in objects: - - if ob_main.dupli_type != 'NONE': - ob_main.create_dupli_list() - - # ignore dupli children - if ob_main.parent.dupli_type != 'NONE': - continue - - obs = [] - if ob_main.dupli_type != 'NONE': - obs = [(dob.matrix, dob.object) for dob in ob_main.dupli_list] - else: - obs = [ob.matrix, ob] - - for ob, ob_mat in obs: - # XXX postponed -# # Nurbs curve support -# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): -# if EXPORT_ROTX90: -# ob_mat = ob_mat * mat_xrot90 - -# totverts += write_nurb(file, ob, ob_mat) - -# continue -# end nurbs - - if ob.type != 'MESH': - continue - - # XXX EXPORT_APPLY_MODIFIERS is not used (always true) - # we also need influences to be copied... for EXPORT_POLYGROUPS to work - # which create_preview_mesh presumably does (CD_MASK_MDEFORMVERT flag) - me = ob.create_preview_mesh() - -# # Will work for non meshes now! :) -# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) -# if not me: -# continue - - if EXPORT_UV: - faceuv = len(me.uv_layers) > 0 - else: - faceuv = False - - # We have a valid mesh - if EXPORT_TRI and me.faces: - # Add a dummy object to it. - has_quads = False - for f in me.faces: -# if len(f) == 4: - if len(f.verts) == 4: - has_quads = True - break - - if has_quads: - newob = bpy.data.add_object('MESH', 'temp_object') - scene.add_object(newob) - newob.convert_to_triface(scene) - # me will still be there - scene.remove_object(newob) -# oldmode = Mesh.Mode() -# Mesh.Mode(Mesh.SelectModes['FACE']) - -# me.sel = True -# tempob = scn.objects.new(me) -# me.quadToTriangle(0) # more=0 shortest length -# oldmode = Mesh.Mode(oldmode) -# scn.objects.unlink(tempob) - -# Mesh.Mode(oldmode) - - if EXPORT_ROTX90: - ob_mat *= mat_xrot90 - - # Make our own list so it can be sorted to reduce context switching - face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)] - # faces = [ f for f in me.faces ] - - if EXPORT_EDGES: - edges = me.edges - else: - edges = [] - - if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write -# if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write - - bpy.data.remove_mesh(me) - - continue # dont bother with this mesh. - - if EXPORT_ROTX90: - me.transform(ob_mat*mat_xrot90) - else: - me.transform(ob_mat) - - # High Quality Normals - if EXPORT_NORMALS and face_index_pairs: -# if EXPORT_NORMALS and faces: - # XXX - pass -# if EXPORT_NORMALS_HQ: -# BPyMesh.meshCalcNormals(me) -# else: -# # transforming normals is incorrect -# # when the matrix is scaled, -# # better to recalculate them -# me.calcNormals() - - # # Crash Blender - #materials = me.getMaterials(1) # 1 == will return None in the list. - materials = me.materials - - materialNames = [] - materialItems = materials[:] - if materials: - for mat in materials: - if mat: # !=None - materialNames.append(mat.name) - else: - materialNames.append(None) - # Cant use LC because some materials are None. - # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. - - # Possible there null materials, will mess up indicies - # but at least it will export, wait until Blender gets fixed. - materialNames.extend((16-len(materialNames)) * [None]) - materialItems.extend((16-len(materialItems)) * [None]) - - # Sort by Material, then images - # so we dont over context switch in the obj file. - if EXPORT_KEEP_VERT_ORDER: - pass - elif faceuv: - # XXX update - tface = me.active_uv_layer.data - - # exception only raised if Python 2.3 or lower... - try: face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth)) - except: face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth), - (b[0].material_index, tface[b[1]].image, b[0].smooth))) - elif len(materials) > 1: - try: face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth)) - except: face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth), - (b[0].material_index, b[0].smooth))) - else: - # no materials - try: face_index_pairs.sort(key = lambda a: a[0].smooth) - except: face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth)) -# if EXPORT_KEEP_VERT_ORDER: -# pass -# elif faceuv: -# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) -# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) -# elif len(materials) > 1: -# try: faces.sort(key = lambda a: (a.mat, a.smooth)) -# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) -# else: -# # no materials -# try: faces.sort(key = lambda a: a.smooth) -# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) - - faces = [pair[0] for pair in face_index_pairs] - - # Set the default mat to no material and no image. - contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. - contextSmooth = None # Will either be true or false, set bad to force initialization switch. - - if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: - name1 = ob.name - name2 = ob.data.name - # name2 = ob.getData(1) - if name1 == name2: - obnamestring = fixName(name1) - else: - obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) - - if EXPORT_BLEN_OBS: - file.write('o %s\n' % obnamestring) # Write Object name - else: # if EXPORT_GROUP_BY_OB: - file.write('g %s\n' % obnamestring) - - - # Vert - for v in me.verts: - file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) - - # UV - if faceuv: - uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ - - uv_dict = {} # could use a set() here - uv_layer = me.active_uv_layer - for f, f_index in face_index_pairs: - - tface = uv_layer.data[f_index] - - uvs = [tface.uv1, tface.uv2, tface.uv3] - - # add another UV if it's a quad - if tface.verts[3] != 0: - uvs.append(tface.uv4) - - for uv_index, uv in enumerate(uvs): - uvkey = veckey2d(uv) - try: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] - except: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) - file.write('vt %.6f %.6f\n' % tuple(uv)) - -# uv_dict = {} # could use a set() here -# for f_index, f in enumerate(faces): - -# for uv_index, uv in enumerate(f.uv): -# uvkey = veckey2d(uv) -# try: -# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] -# except: -# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) -# file.write('vt %.6f %.6f\n' % tuple(uv)) - - uv_unique_count = len(uv_dict) - del uv, uvkey, uv_dict, f_index, uv_index - # Only need uv_unique_count and uv_face_mapping - - # NORMAL, Smooth/Non smoothed. - if EXPORT_NORMALS: - for f in faces: - if f.smooth: - for v in f: - noKey = veckey3d(v.normal) -# noKey = veckey3d(v.no) - if not globalNormals.has_key( noKey ): - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - else: - # Hard, 1 normal from the face. - noKey = veckey3d(f.normal) -# noKey = veckey3d(f.no) - if not globalNormals.has_key( noKey ): - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - - if not faceuv: - f_image = None - - # XXX - if EXPORT_POLYGROUPS: - # Retrieve the list of vertex groups -# vertGroupNames = me.getVertGroupNames() - - currentVGroup = '' - # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to - vgroupsMap = [[] for _i in range(len(me.verts))] -# vgroupsMap = [[] for _i in xrange(len(me.verts))] - for g in ob.vertex_groups: -# for vertexGroupName in vertGroupNames: - for vIdx, vWeight in getVertsFromGroup(me, g.index) -# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): - vgroupsMap[vIdx].append((g.name, vWeight)) - - for f_index, f in enumerate(faces): - f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts] -# f_v= f.v - f_smooth= f.smooth - f_mat = min(f.material_index, len(materialNames)-1) -# f_mat = min(f.mat, len(materialNames)-1) - if faceuv: - - tface = me.active_uv_layer.data[face_index_pairs[f_index][1]] - - f_image = tface.image - f_uv= [tface.uv1, tface.uv2, tface.uv3] - if f.verts[4] != 0: - f_uv.append(tface.uv4) -# f_image = f.image -# f_uv= f.uv - - # MAKE KEY - if faceuv and f_image: # Object is always true. - key = materialNames[f_mat], f_image.name - else: - key = materialNames[f_mat], None # No image, use None instead. - - # XXX - # Write the vertex group - if EXPORT_POLYGROUPS: - if len(ob.vertex_groups): - # find what vertext group the face belongs to - theVGroup = findVertexGroupName(f,vgroupsMap) - if theVGroup != currentVGroup: - currentVGroup = theVGroup - file.write('g %s\n' % theVGroup) -# # Write the vertex group -# if EXPORT_POLYGROUPS: -# if vertGroupNames: -# # find what vertext group the face belongs to -# theVGroup = findVertexGroupName(f,vgroupsMap) -# if theVGroup != currentVGroup: -# currentVGroup = theVGroup -# file.write('g %s\n' % theVGroup) - - # CHECK FOR CONTEXT SWITCH - if key == contextMat: - pass # Context alredy switched, dont do anything - else: - if key[0] == None and key[1] == None: - # Write a null material, since we know the context has changed. - if EXPORT_GROUP_BY_MAT: - # can be mat_image or (null) - file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.data.name)) ) -# file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) - file.write('usemtl (null)\n') # mat, image - - else: - mat_data= MTL_DICT.get(key) - if not mat_data: - # First add to global dict so we can export to mtl - # Then write mtl - - # Make a new names from the mat and image name, - # converting any spaces to underscores with fixName. - - # If none image dont bother adding it to the name - if key[1] == None: - mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image - else: - mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image - - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.data.name), mat_data[0]) ) # can be mat_image or (null) -# file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) - - file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) - - contextMat = key - if f_smooth != contextSmooth: - if f_smooth: # on now off - file.write('s 1\n') - contextSmooth = f_smooth - else: # was off now on - file.write('s off\n') - contextSmooth = f_smooth - - file.write('f') - if faceuv: - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % \ - (v["index"] + totverts, - totuvco + uv_face_mapping[f_index][vi], - globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal -# file.write( ' %d/%d/%d' % (\ -# v.index+totverts,\ -# totuvco + uv_face_mapping[f_index][vi],\ -# globalNormals[ veckey3d(v.no) ])) # vert, uv, normal - - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.normal) ] -# no = globalNormals[ veckey3d(f.no) ] - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % \ - (v["index"] + totverts, - totuvco + uv_face_mapping[f_index][vi], - no) ) # vert, uv, normal -# file.write( ' %d/%d/%d' % (\ -# v.index+totverts,\ -# totuvco + uv_face_mapping[f_index][vi],\ -# no)) # vert, uv, normal - - else: # No Normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d' % (\ - v["index"] + totverts,\ - totuvco + uv_face_mapping[f_index][vi])) # vert, uv -# file.write( ' %d/%d' % (\ -# v.index+totverts,\ -# totuvco + uv_face_mapping[f_index][vi])) # vert, uv - - face_vert_index += len(f_v) - - else: # No UV's - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for v in f_v: - file.write( ' %d//%d' % - (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) ) - -# file.write( ' %d//%d' % (\ -# v.index+totverts,\ -# globalNormals[ veckey3d(v.no) ])) - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.normal) ] -# no = globalNormals[ veckey3d(f.no) ] - for v in f_v: - file.write( ' %d//%d' % (v["index"] + totverts, no) ) -# file.write( ' %d//%d' % (\ -# v.index+totverts,\ -# no)) - else: # No Normals - for v in f_v: - file.write( ' %d' % (v["index"] + totverts) ) -# file.write( ' %d' % (\ -# v.index+totverts)) - - file.write('\n') - - # Write edges. - if EXPORT_EDGES: - for ed in edges: - if ed.loose: - file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts)) -# LOOSE= Mesh.EdgeFlags.LOOSE -# for ed in edges: -# if ed.flag & LOOSE: -# file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) - - # Make the indicies global rather then per mesh - totverts += len(me.verts) - if faceuv: - totuvco += uv_unique_count - - # clean up - bpy.data.remove_mesh(me) -# me.verts= None - - if ob_main.dupli_type != 'NONE': - ob_main.free_dupli_list() - - file.close() - - - # Now we have all our materials, save them - if EXPORT_MTL: - write_mtl(scene, mtlfilename) - if EXPORT_COPY_IMAGES: - dest_dir = filename - # Remove chars until we are just the path. - while dest_dir and dest_dir[-1] not in '\\/': - dest_dir = dest_dir[:-1] - if dest_dir: - copy_images(dest_dir) - else: - print '\tError: "%s" could not be used as a base for an image path.' % filename - - print "OBJ Export time: %.2f" % (sys.time() - time1) - - -# replaced by do_export -def write_ui(filename): - - if not filename.lower().endswith('.obj'): - filename += '.obj' - - if not BPyMessages.Warning_SaveOver(filename): - return - - global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ - EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ - EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ - EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS - - EXPORT_APPLY_MODIFIERS = Draw.Create(0) - EXPORT_ROTX90 = Draw.Create(1) - EXPORT_TRI = Draw.Create(0) - EXPORT_EDGES = Draw.Create(1) - EXPORT_NORMALS = Draw.Create(0) - EXPORT_NORMALS_HQ = Draw.Create(0) - EXPORT_UV = Draw.Create(1) - EXPORT_MTL = Draw.Create(1) - EXPORT_SEL_ONLY = Draw.Create(1) - EXPORT_ALL_SCENES = Draw.Create(0) - EXPORT_ANIMATION = Draw.Create(0) - EXPORT_COPY_IMAGES = Draw.Create(0) - EXPORT_BLEN_OBS = Draw.Create(0) - EXPORT_GROUP_BY_OB = Draw.Create(0) - EXPORT_GROUP_BY_MAT = Draw.Create(0) - EXPORT_KEEP_VERT_ORDER = Draw.Create(1) - EXPORT_POLYGROUPS = Draw.Create(0) - EXPORT_CURVE_AS_NURBS = Draw.Create(1) - - - # Old UI - ''' - # removed too many options are bad! - - # Get USER Options - pup_block = [\ - ('Context...'),\ - ('Selection Only', EXPORT_SEL_ONLY, 'Only export objects in visible selection. Else export whole scene.'),\ - ('All Scenes', EXPORT_ALL_SCENES, 'Each scene as a separate OBJ file.'),\ - ('Animation', EXPORT_ANIMATION, 'Each frame as a numbered OBJ file.'),\ - ('Object Prefs...'),\ - ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object. May break vert order for morph targets.'),\ - ('Rotate X90', EXPORT_ROTX90 , 'Rotate on export so Blenders UP is translated into OBJs UP'),\ - ('Keep Vert Order', EXPORT_KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ - ('Extra Data...'),\ - ('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\ - ('Normals', EXPORT_NORMALS, 'Export vertex normal data (Ignored on import).'),\ - ('High Quality Normals', EXPORT_NORMALS_HQ, 'Calculate high quality normals for rendering.'),\ - ('UVs', EXPORT_UV, 'Export texface UV coords.'),\ - ('Materials', EXPORT_MTL, 'Write a separate MTL file with the OBJ.'),\ - ('Copy Images', EXPORT_COPY_IMAGES, 'Copy image files to the export directory, never overwrite.'),\ - ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\ - ('Grouping...'),\ - ('Objects', EXPORT_BLEN_OBS, 'Export blender objects as "OBJ objects".'),\ - ('Object Groups', EXPORT_GROUP_BY_OB, 'Export blender objects as "OBJ Groups".'),\ - ('Material Groups', EXPORT_GROUP_BY_MAT, 'Group by materials.'),\ - ] - - if not Draw.PupBlock('Export...', pup_block): - return - ''' - - # BEGIN ALTERNATIVE UI ******************* - if True: - - EVENT_NONE = 0 - EVENT_EXIT = 1 - EVENT_REDRAW = 2 - EVENT_EXPORT = 3 - - GLOBALS = {} - GLOBALS['EVENT'] = EVENT_REDRAW - #GLOBALS['MOUSE'] = Window.GetMouseCoords() - GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] - - def obj_ui_set_event(e,v): - GLOBALS['EVENT'] = e - - def do_split(e,v): - global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER, EXPORT_POLYGROUPS - if EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val: - EXPORT_KEEP_VERT_ORDER.val = 0 - else: - EXPORT_KEEP_VERT_ORDER.val = 1 - - def do_vertorder(e,v): - global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER - if EXPORT_KEEP_VERT_ORDER.val: - EXPORT_BLEN_OBS.val = EXPORT_GROUP_BY_OB.val = EXPORT_GROUP_BY_MAT.val = EXPORT_APPLY_MODIFIERS.val = 0 - else: - if not (EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val): - EXPORT_KEEP_VERT_ORDER.val = 1 - - - def do_help(e,v): - url = __url__[0] - print 'Trying to open web browser with documentation at this address...' - print '\t' + url - - try: - import webbrowser - webbrowser.open(url) - except: - print '...could not open a browser window.' - - def obj_ui(): - ui_x, ui_y = GLOBALS['MOUSE'] - - # Center based on overall pup size - ui_x -= 165 - ui_y -= 140 - - global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ - EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ - EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ - EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS - - Draw.Label('Context...', ui_x+9, ui_y+239, 220, 20) - Draw.BeginAlign() - EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+219, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.') - EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+219, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.') - EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+219, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.') - Draw.EndAlign() - - - Draw.Label('Output Options...', ui_x+9, ui_y+189, 220, 20) - Draw.BeginAlign() - EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+170, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split) - EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+170, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP') - EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+170, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.') - Draw.EndAlign() - - - Draw.Label('Export...', ui_x+9, ui_y+139, 220, 20) - Draw.BeginAlign() - EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+120, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.') - EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+120, 70, 20, EXPORT_TRI.val, 'Triangulate quads.') - Draw.EndAlign() - Draw.BeginAlign() - EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+120, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.') - EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+120, 31, 20, EXPORT_UV.val, 'Export texface UV coords.') - Draw.EndAlign() - Draw.BeginAlign() - EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+120, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).') - EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+120, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.') - Draw.EndAlign() - EXPORT_POLYGROUPS = Draw.Toggle('Polygroups', EVENT_REDRAW, ui_x+9, ui_y+95, 120, 20, EXPORT_POLYGROUPS.val, 'Export vertex groups as OBJ groups (one group per face approximation).') - - EXPORT_CURVE_AS_NURBS = Draw.Toggle('Nurbs', EVENT_NONE, ui_x+139, ui_y+95, 100, 20, EXPORT_CURVE_AS_NURBS.val, 'Export 3D nurbs curves and polylines as OBJ curves, (bezier not supported).') - - - Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20) - Draw.BeginAlign() - EXPORT_BLEN_OBS = Draw.Toggle('Objects', EVENT_REDRAW, ui_x+9, ui_y+39, 60, 20, EXPORT_BLEN_OBS.val, 'Export blender objects as "OBJ objects".', do_split) - EXPORT_GROUP_BY_OB = Draw.Toggle('Groups', EVENT_REDRAW, ui_x+69, ui_y+39, 60, 20, EXPORT_GROUP_BY_OB.val, 'Export blender objects as "OBJ Groups".', do_split) - EXPORT_GROUP_BY_MAT = Draw.Toggle('Material Groups', EVENT_REDRAW, ui_x+129, ui_y+39, 100, 20, EXPORT_GROUP_BY_MAT.val, 'Group by materials.', do_split) - Draw.EndAlign() - - EXPORT_KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+239, ui_y+39, 100, 20, EXPORT_KEEP_VERT_ORDER.val, 'Keep vert and face order, disables some other options. Use for morph targets.', do_vertorder) - - Draw.BeginAlign() - Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 20, 'Load the wiki page for this script', do_help) - Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 20, '', obj_ui_set_event) - Draw.PushButton('Export', EVENT_EXPORT, ui_x+229, ui_y+9, 110, 20, 'Export with these settings', obj_ui_set_event) - Draw.EndAlign() - - - # hack so the toggle buttons redraw. this is not nice at all - while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_EXPORT): - Draw.UIBlock(obj_ui, 0) - - if GLOBALS['EVENT'] != EVENT_EXPORT: - return - - # END ALTERNATIVE UI ********************* - - - if EXPORT_KEEP_VERT_ORDER.val: - EXPORT_BLEN_OBS.val = False - EXPORT_GROUP_BY_OB.val = False - EXPORT_GROUP_BY_MAT.val = False - EXPORT_APPLY_MODIFIERS.val = False - - Window.EditMode(0) - Window.WaitCursor(1) - - EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val - EXPORT_ROTX90 = EXPORT_ROTX90.val - EXPORT_TRI = EXPORT_TRI.val - EXPORT_EDGES = EXPORT_EDGES.val - EXPORT_NORMALS = EXPORT_NORMALS.val - EXPORT_NORMALS_HQ = EXPORT_NORMALS_HQ.val - EXPORT_UV = EXPORT_UV.val - EXPORT_MTL = EXPORT_MTL.val - EXPORT_SEL_ONLY = EXPORT_SEL_ONLY.val - EXPORT_ALL_SCENES = EXPORT_ALL_SCENES.val - EXPORT_ANIMATION = EXPORT_ANIMATION.val - EXPORT_COPY_IMAGES = EXPORT_COPY_IMAGES.val - EXPORT_BLEN_OBS = EXPORT_BLEN_OBS.val - EXPORT_GROUP_BY_OB = EXPORT_GROUP_BY_OB.val - EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val - EXPORT_KEEP_VERT_ORDER = EXPORT_KEEP_VERT_ORDER.val - EXPORT_POLYGROUPS = EXPORT_POLYGROUPS.val - EXPORT_CURVE_AS_NURBS = EXPORT_CURVE_AS_NURBS.val - - - base_name, ext = splitExt(filename) - context_name = [base_name, '', '', ext] # basename, scene_name, framenumber, extension - - # Use the options to export the data using write() - # def write(filename, objects, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, EXPORT_APPLY_MODIFIERS=True): - orig_scene = Scene.GetCurrent() - if EXPORT_ALL_SCENES: - export_scenes = Scene.Get() - else: - export_scenes = [orig_scene] - - # Export all scenes. - for scn in export_scenes: - scn.makeCurrent() # If alredy current, this is not slow. - context = scn.getRenderingContext() - orig_frame = Blender.Get('curframe') - - if EXPORT_ALL_SCENES: # Add scene name into the context_name - context_name[1] = '_%s' % BPySys.cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. - - # Export an animation? - if EXPORT_ANIMATION: - scene_frames = xrange(context.startFrame(), context.endFrame()+1) # up to and including the end frame. - else: - scene_frames = [orig_frame] # Dont export an animation. - - # Loop through all frames in the scene and export. - for frame in scene_frames: - if EXPORT_ANIMATION: # Add frame to the filename. - context_name[2] = '_%.6d' % frame - - Blender.Set('curframe', frame) - if EXPORT_SEL_ONLY: - export_objects = scn.objects.context - else: - export_objects = scn.objects - - full_path= ''.join(context_name) - - # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. - # EXPORT THE FILE. - write(full_path, export_objects,\ - EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ - EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ - EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ - EXPORT_ROTX90, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) - - Blender.Set('curframe', orig_frame) - - # Restore old active scene. - orig_scene.makeCurrent() - Window.WaitCursor(0) - - -def do_export(filename, context): - # Window.EditMode(0) - # Window.WaitCursor(1) - - EXPORT_APPLY_MODIFIERS = True - EXPORT_ROTX90 = True - EXPORT_TRI = False - EXPORT_EDGES = False - EXPORT_NORMALS = False - EXPORT_NORMALS_HQ = False - EXPORT_UV = True - EXPORT_MTL = True - EXPORT_SEL_ONLY = True - EXPORT_ALL_SCENES = False # XXX not working atm - EXPORT_ANIMATION = False - EXPORT_COPY_IMAGES = False - EXPORT_BLEN_OBS = True - EXPORT_GROUP_BY_OB = False - EXPORT_GROUP_BY_MAT = False - EXPORT_KEEP_VERT_ORDER = False - EXPORT_POLYGROUPS = False - EXPORT_CURVE_AS_NURBS = True - - base_name, ext = splitExt(filename) - context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension - - orig_scene = context.scene - -# if EXPORT_ALL_SCENES: -# export_scenes = bpy.data.scenes -# else: -# export_scenes = [orig_scene] - - # XXX only exporting one scene atm since changing - # current scene is not possible. - # Brecht says that ideally in 2.5 we won't need such a function, - # allowing multiple scenes open at once. - export_scenes = [orig_scene] - - # Export all scenes. - for scn in export_scenes: - # scn.makeCurrent() # If already current, this is not slow. - # context = scn.getRenderingContext() - orig_frame = scn.current_frame - - if EXPORT_ALL_SCENES: # Add scene name into the context_name - context_name[1] = '_%s' % BPySys.cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. - - # Export an animation? - if EXPORT_ANIMATION: - scene_frames = xrange(scn.start_frame, context.end_frame+1) # Up to and including the end frame. - else: - scene_frames = [orig_frame] # Dont export an animation. - - # Loop through all frames in the scene and export. - for frame in scene_frames: - if EXPORT_ANIMATION: # Add frame to the filename. - context_name[2] = '_%.6d' % frame - - scn.current_frame = frame - if EXPORT_SEL_ONLY: - export_objects = context.selected_objects - else: - export_objects = scn.objects - - full_path= ''.join(context_name) - - # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. - # EXPORT THE FILE. - write(full_path, export_objects, scn, - EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, - EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, - EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, - EXPORT_ROTX90, EXPORT_BLEN_OBS, - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER, - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) - - - scn.current_frame = orig_frame - - # Restore old active scene. -# orig_scene.makeCurrent() -# Window.WaitCursor(0) - - -class EXPORT_OT_obj(bpy.types.Operator): - ''' - Currently the exporter lacks these features: - * nurbs - * multiple scene export (only active scene is written) - * particles - ''' - __label__ = 'Export OBJ' - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - __props__ = [ - # bpy.types.FloatProperty(attr="setting_1", name="Example 1", - # default=10.0, min=0, max=10, description="Add info here"), - # bpy.types.IntProperty(attr="setting_2", default=2), - # bpy.types.BoolProperty(attr="toggle", default=True) - ] - - def execu(self, context): - print("Selected: " + context.active_object.name) - - do_export("/tmp/test.obj", context) - - return 'FINISHED' - - def invoke(self, event): - print("Invoke") - return 'FINISHED' - - def poll(self, context): # Poll isnt working yet - print("Poll") - return True - -if (hasattr(bpy.ops, "SCRIPT_OT_export_obj")): - bpy.ops.remove(bpy.ops.SCRIPT_OT_export_obj) - -bpy.ops.add(SCRIPT_OT_export_obj) - -bpy.ops.SCRIPT_OT_export_obj() - -bpy.ops.remove(bpy.ops.SCRIPT_OT_export_obj) diff --git a/release/ui/space_script.py b/release/ui/space_script.py index d35f2d389c8..9b0809ffc75 100644 --- a/release/ui/space_script.py +++ b/release/ui/space_script.py @@ -32,7 +32,7 @@ class SCRIPT_HT_header(bpy.types.Header): if context.area.show_menus: row = layout.row(align=True) - row.itemM(context, "SCRIPT_MT_scripts") + row.itemM("SCRIPT_MT_scripts") class SCRIPT_MT_scripts(bpy.types.Menu): __space_type__ = "SCRIPTS_WINDOW" @@ -41,7 +41,7 @@ class SCRIPT_MT_scripts(bpy.types.Menu): def draw(self, context): layout = self.layout layout.column() - layout.itemM(context, "SCRIPT_MT_export") + layout.itemM("SCRIPT_MT_export") layout.itemO("SCRIPT_OT_reload_scripts") class SCRIPT_MT_export(bpy.types.Menu): diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 984e6a5d30f..f4bc52bc517 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -36,6 +36,8 @@ #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" +#include "BKE_mesh.h" + #include "BLI_arithb.h" #include "DNA_mesh_types.h" @@ -66,6 +68,14 @@ void rna_Mesh_transform(Mesh *me, float *mat) } } +Mesh *rna_Mesh_create_copy(Mesh *me) +{ + Mesh *ret= copy_mesh(me); + ret->id.us--; + + return ret; +} + #if 0 /* extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); */ @@ -101,6 +111,11 @@ void RNA_api_mesh(StructRNA *srna) parm= RNA_def_float_matrix(func, "matrix", 16, NULL, 0.0f, 0.0f, "", "Matrix.", 0.0f, 0.0f); RNA_def_property_flag(parm, PROP_REQUIRED); + func= RNA_def_function(srna, "create_copy", "rna_Mesh_create_copy"); + RNA_def_function_ui_description(func, "Create a copy of this Mesh datablock."); + parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh, remove it if it is only used for export."); + RNA_def_function_return(func, parm); + /* func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom"); RNA_def_function_ui_description(func, "Add geometry data to mesh."); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 1b6c298eba4..b09acb51084 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -36,6 +36,12 @@ #include "DNA_object_types.h" +/* parameter to rna_Object_create_mesh */ +typedef enum CreateMeshType { + CREATE_MESH_PREVIEW = 0, + CREATE_MESH_RENDER = 1 +} CreateMeshType; + #ifdef RNA_RUNTIME #include "BKE_customdata.h" @@ -55,7 +61,7 @@ #include "ED_mesh.h" /* copied from init_render_mesh (render code) */ -static Mesh *create_mesh(Object *ob, bContext *C, ReportList *reports, int render_mesh) +static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports, int type) { /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */ CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter, @@ -71,8 +77,13 @@ static Mesh *create_mesh(Object *ob, bContext *C, ReportList *reports, int rende BKE_report(reports, RPT_ERROR, "Object should be of type MESH."); return NULL; } - - dm= render_mesh ? mesh_create_derived_render(sce, ob, mask) : mesh_create_derived_view(sce, ob, mask); + + if (type == CREATE_MESH_PREVIEW) { + dm= mesh_create_derived_view(sce, ob, mask); + } + else { + dm= mesh_create_derived_render(sce, ob, mask); + } if(!dm) { /* TODO: report */ @@ -87,16 +98,6 @@ static Mesh *create_mesh(Object *ob, bContext *C, ReportList *reports, int rende return me; } -static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, ReportList *reports) -{ - return create_mesh(ob, C, reports, 1); -} - -static Mesh *rna_Object_create_preview_mesh(Object *ob, bContext *C, ReportList *reports) -{ - return create_mesh(ob, C, reports, 0); -} - /* When no longer needed, duplilist should be freed with Object.free_duplilist */ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports) { @@ -162,33 +163,20 @@ void RNA_api_object(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; - /* copied from rna_def_object */ - static EnumPropertyItem object_type_items[] = { - {OB_EMPTY, "EMPTY", 0, "Empty", ""}, - {OB_MESH, "MESH", 0, "Mesh", ""}, - {OB_CURVE, "CURVE", 0, "Curve", ""}, - {OB_SURF, "SURFACE", 0, "Surface", ""}, - {OB_FONT, "TEXT", 0, "Text", ""}, - {OB_MBALL, "META", 0, "Meta", ""}, - {OB_LAMP, "LAMP", 0, "Lamp", ""}, - {OB_CAMERA, "CAMERA", 0, "Camera", ""}, - {OB_WAVE, "WAVE", 0, "Wave", ""}, - {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, - {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, - {0, NULL, 0, NULL, NULL}}; - - func= RNA_def_function(srna, "create_render_mesh", "rna_Object_create_render_mesh"); - RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied for rendering."); - RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); - RNA_def_function_return(func, parm); + static EnumPropertyItem mesh_type_items[] = { + {CREATE_MESH_PREVIEW, "PREVIEW", 0, "Preview", "Apply preview settings."}, + {CREATE_MESH_RENDER, "RENDER", 0, "Render", "Apply render settings."}, + {0, NULL, 0, NULL, NULL} + }; - func= RNA_def_function(srna, "create_preview_mesh", "rna_Object_create_preview_mesh"); - RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied for preview."); + func= RNA_def_function(srna, "create_mesh", "rna_Object_create_mesh"); + RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); + parm= RNA_def_enum(func, "type", mesh_type_items, 0, "", "Type of mesh settings to apply."); + RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); - + func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist"); RNA_def_function_ui_description(func, "Create a list of dupli objects for this object, needs to be freed manually with free_dupli_list."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 8b5ad36f349..96ef796839b 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -19,6 +19,7 @@ #include "bpy_rna.h" #include "bpy_operator.h" #include "bpy_ui.h" +#include "bpy_sys.h" #include "bpy_util.h" #include "DNA_anim_types.h" @@ -91,6 +92,7 @@ void BPY_update_modules( void ) PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject( mod, "data", BPY_rna_module() ); PyModule_AddObject( mod, "types", BPY_rna_types() ); + PyModule_AddObject( mod, "sys", BPY_sys_module() ); } /***************************************************************************** diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index b7e3c86dd91..4e5536c8552 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -331,7 +331,7 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) {PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK}, - {"execute", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, + {"execute", 'f', 2, 0}, {"invoke", 'f', 3, BPY_CLASS_ATTR_OPTIONAL}, {"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL}, {NULL, 0, 0, 0} diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 0b8a7df1ae1..90876b36ee0 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1367,8 +1367,12 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) newptr= *(PointerRNA*)data; } else { - /* XXX this is missing the ID part! */ - RNA_pointer_create(NULL, type, *(void**)data, &newptr); + if (RNA_struct_is_ID(type)) { + RNA_id_pointer_create(*(void**)data, &newptr); + } + else { + RNA_pointer_create(NULL, type, *(void**)data, &newptr); + } } if (newptr.data) { diff --git a/source/blender/python/intern/bpy_sys.c b/source/blender/python/intern/bpy_sys.c new file mode 100644 index 00000000000..4d80d3bff93 --- /dev/null +++ b/source/blender/python/intern/bpy_sys.c @@ -0,0 +1,460 @@ +/* + * $Id: Sys.c 17889 2008-12-16 11:26:55Z campbellbarton $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** +*/ + +#include "bpy_sys.h" /*This must come first*/ +#include "bpy_util.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_context.h" + +#include "BLI_blenlib.h" + +#include "DNA_scene_types.h" /* G.scene-"r.cfra */ + +#include "PIL_time.h" +/* #include "gen_utils.h" */ + +#ifdef WIN32 +#define DIRSEP '\\' +#define DIRSEP_STR "\\" +#else +#define DIRSEP '/' +#define DIRSEP_STR "/" +#endif + + +/*****************************************************************************/ +/* Python API function prototypes for the sys module. */ +/*****************************************************************************/ +static PyObject *M_sys_basename( PyObject * self, PyObject * value ); +static PyObject *M_sys_dirname( PyObject * self, PyObject * value ); +static PyObject *M_sys_join( PyObject * self, PyObject * args ); +static PyObject *M_sys_splitext( PyObject * self, PyObject * value ); +static PyObject *M_sys_makename( PyObject * self, PyObject * args, + PyObject * kw ); +static PyObject *M_sys_exists( PyObject * self, PyObject * value ); +static PyObject *M_sys_time( PyObject * self ); +static PyObject *M_sys_sleep( PyObject * self, PyObject * args ); +static PyObject *M_sys_expandpath( PyObject *self, PyObject *value); +static PyObject *M_sys_cleanpath( PyObject *self, PyObject *value); +static PyObject *M_sys_relpath( PyObject *self, PyObject *args); + +/*****************************************************************************/ +/* The following string definitions are used for documentation strings. */ +/* In Python these will be written to the console when doing a */ +/* Blender.sys.__doc__ */ +/*****************************************************************************/ +static char M_sys_doc[] = "The Blender.sys submodule\n\ +\n\ +This is a minimal system module to supply simple functionality available\n\ +in the default Python module os."; + +static char M_sys_basename_doc[] = + "(path) - Split 'path' in dir and filename.\n\ +Return the filename."; + +static char M_sys_dirname_doc[] = + "(path) - Split 'path' in dir and filename.\n\ +Return the dir."; + +static char M_sys_join_doc[] = + "(dir, file) - Join dir and file to form a full filename.\n\ +Return the filename."; + +static char M_sys_splitext_doc[] = + "(path) - Split 'path' in root and extension:\n\ +/this/that/file.ext -> ('/this/that/file','.ext').\n\ +Return the pair (root, extension)."; + +static char M_sys_makename_doc[] = + "(path = Blender.Get('filename'), ext = \"\", strip = 0) -\n\ +Strip dir and extension from path, leaving only a name, then append 'ext'\n\ +to it (if given) and return the resulting string.\n\n\ +(path) - string: a pathname -- Blender.Get('filename') if 'path' isn't given;\n\ +(ext = \"\") - string: the extension to append.\n\ +(strip = 0) - int: strip dirname from 'path' if given and non-zero.\n\ +Ex: makename('/path/to/file/myfile.foo','-01.abc') returns 'myfile-01.abc'\n\ +Ex: makename(ext='.txt') returns 'untitled.txt' if Blender.Get('filename')\n\ +returns a path to the file 'untitled.blend'"; + +static char M_sys_time_doc[] = + "() - Return a float representing time elapsed in seconds.\n\ +Each successive call is garanteed to return values greater than or\n\ +equal to the previous call."; + +static char M_sys_sleep_doc[] = + "(milliseconds = 10) - Sleep for the specified time.\n\ +(milliseconds = 10) - the amount of time in milliseconds to sleep.\n\ +This function can be necessary in tight 'get event' loops."; + +static char M_sys_exists_doc[] = + "(path) - Check if the given pathname exists.\n\ +The return value is as follows:\n\ +\t 0: path doesn't exist;\n\ +\t 1: path is an existing filename;\n\ +\t 2: path is an existing dirname;\n\ +\t-1: path exists but is neither a regular file nor a dir."; + +static char M_sys_expandpath_doc[] = +"(path) - Expand this Blender internal path to a proper file system path.\n\ +(path) - the string path to convert.\n\n\ +Note: internally Blender paths can contain two special character sequences:\n\ +- '//' (at start) for base path directory (the current .blend's dir path);\n\ +- '#' characters in the filename will be replaced by the frame number.\n\n\ +This function expands these to their actual content, returning a valid path.\n\ +If the special chars are not found in the given path, it is simply returned."; + +static char M_sys_cleanpath_doc[] = +"(path) - Removes parts of a path that are not needed paths such as '../foo/../bar/' and '//./././'"; + +static char M_sys_relpath_doc[] = +"(path, start=\"//\") - Returns the path relative to the current blend file or start if spesified"; + +/*****************************************************************************/ +/* Python method structure definition for Blender.sys module: */ +/*****************************************************************************/ +struct PyMethodDef M_sys_methods[] = { + {"basename", M_sys_basename, METH_O, M_sys_basename_doc}, + {"dirname", M_sys_dirname, METH_O, M_sys_dirname_doc}, + {"join", M_sys_join, METH_VARARGS, M_sys_join_doc}, + {"splitext", M_sys_splitext, METH_O, M_sys_splitext_doc}, + {"makename", ( PyCFunction ) M_sys_makename, + METH_VARARGS | METH_KEYWORDS, + M_sys_makename_doc}, + {"exists", M_sys_exists, METH_O, M_sys_exists_doc}, + {"sleep", M_sys_sleep, METH_VARARGS, M_sys_sleep_doc}, + {"time", ( PyCFunction ) M_sys_time, METH_NOARGS, M_sys_time_doc}, + {"expandpath", M_sys_expandpath, METH_O, M_sys_expandpath_doc}, + {"cleanpath", M_sys_cleanpath, METH_O, M_sys_cleanpath_doc}, + {"relpath", M_sys_relpath, METH_VARARGS, M_sys_relpath_doc}, + {NULL, NULL, 0, NULL} +}; + +#if PY_VERSION_HEX >= 0x03000000 +static struct PyModuleDef sys_module = { + PyModuleDef_HEAD_INIT, + "bpysys", + M_sys_doc, + -1,/* multiple "initialization" just copies the module dict. */ + M_sys_methods, + NULL, NULL, NULL, NULL +}; +#endif + +/* Module Functions */ + +PyObject *BPY_sys_module( void ) +{ + PyObject *submodule, *dict; + +#if PY_VERSION_HEX >= 0x03000000 + submodule= PyModule_Create(&sys_module); +#else /* Py2.x */ + submodule= Py_InitModule3( "bpysys", M_sys_methods, M_sys_doc ); +#endif + + dict = PyModule_GetDict( submodule ); + + /* EXPP_dict_set_item_str( dict, "dirsep", PyString_FromString(DIRSEP_STR) ); */ + /* EXPP_dict_set_item_str( dict, "sep", PyString_FromString(DIRSEP_STR) ); */ + + return submodule; +} + +static PyObject *M_sys_basename( PyObject * self, PyObject * value ) +{ + char *name = _PyUnicode_AsString(value); + char *p, basename[FILE_MAXDIR + FILE_MAXFILE]; + int n, len; + + if( !name ) { + return PyErr_Format( PyExc_TypeError, "expected string argument" ); + } + + len = strlen( name ); + +#ifdef WIN32 + p = MAX2(strrchr( name, '/' ), strrchr( name, '\\' )); +#else + p = strrchr( name, DIRSEP ); +#endif + + if( p ) { + n = name + len - p - 1; /* - 1 because we don't want the sep */ + + if( n > FILE_MAXDIR + FILE_MAXFILE ) { + return PyErr_Format( PyExc_RuntimeError, "path too long" ); + } + + BLI_strncpy( basename, p + 1, n + 1 ); + return PyUnicode_FromString( basename ); + } + + return PyUnicode_FromString( name ); +} + +static PyObject *M_sys_dirname( PyObject * self, PyObject * value ) +{ + char *name = _PyUnicode_AsString(value); + char *p, dirname[FILE_MAXDIR + FILE_MAXFILE]; + int n; + + if( !name ) + return PyErr_Format( PyExc_TypeError, "expected string argument" ); + +#ifdef WIN32 + p = MAX2(strrchr( name, '/' ), strrchr( name, '\\' )); +#else + p = strrchr( name, DIRSEP ); +#endif + + if( p ) { + n = p - name; + + if( n > FILE_MAXDIR + FILE_MAXFILE ) + return PyErr_Format( PyExc_RuntimeError, "path too long" ); + + BLI_strncpy( dirname, name, n + 1 ); + return PyUnicode_FromString( dirname ); + } + + return PyUnicode_FromString( "." ); +} + +static PyObject *M_sys_join( PyObject * self, PyObject * args ) +{ + char *name = NULL, *path = NULL; + char filename[FILE_MAXDIR + FILE_MAXFILE]; + int pathlen = 0, namelen = 0; + + if( !PyArg_ParseTuple( args, "ss:Blender.sys.join", &path, &name ) ) + return NULL; + + pathlen = strlen( path ) + 1; + namelen = strlen( name ) + 1; /* + 1 to account for '\0' for BLI_strncpy */ + + if( pathlen + namelen > FILE_MAXDIR + FILE_MAXFILE - 1 ) + return PyErr_Format( PyExc_RuntimeError, "filename is too long." ); + + BLI_strncpy( filename, path, pathlen ); + + if( filename[pathlen - 2] != DIRSEP ) { + filename[pathlen - 1] = DIRSEP; + pathlen += 1; + } + + BLI_strncpy( filename + pathlen - 1, name, namelen ); + + return PyUnicode_FromString( filename ); +} + +static PyObject *M_sys_splitext( PyObject * self, PyObject * value ) +{ + char *name = _PyUnicode_AsString(value); + char *dot, *p, path[FILE_MAXDIR + FILE_MAXFILE], ext[FILE_MAXDIR + FILE_MAXFILE]; + int n, len; + + if( !name ) + return PyErr_Format( PyExc_TypeError, "expected string argument" ); + + len = strlen( name ); + dot = strrchr( name, '.' ); + + if( !dot ) + return Py_BuildValue( "ss", name, "" ); + + p = strrchr( name, DIRSEP ); + + if( p ) { + if( p > dot ) + return Py_BuildValue( "ss", name, "" ); + } + + n = name + len - dot; + + /* loong extensions are supported -- foolish, but Python's os.path.splitext + * supports them, so ... */ + + if( n >= FILE_MAXDIR + FILE_MAXFILE || ( len - n ) >= FILE_MAXDIR + FILE_MAXFILE ) + return PyErr_Format( PyExc_RuntimeError, "path too long" ); + + BLI_strncpy( ext, dot, n + 1 ); + BLI_strncpy( path, name, dot - name + 1 ); + + return Py_BuildValue( "ss", path, ext ); +} + +static PyObject *M_sys_makename( PyObject * self, PyObject * args, + PyObject * kw ) +{ + char *path = G.sce, *ext = NULL; + int strip = 0; + static char *kwlist[] = { "path", "ext", "strip", NULL }; + char *dot = NULL, *p = NULL, basename[FILE_MAXDIR + FILE_MAXFILE]; + int n, len, lenext = 0; + + if( !PyArg_ParseTupleAndKeywords( args, kw, "|ssi:Blender.sys.makename", kwlist, &path, &ext, &strip ) ) + return NULL; + + len = strlen( path ) + 1; /* + 1 to consider ending '\0' */ + if( ext ) + lenext = strlen( ext ) + 1; + + if( ( len + lenext ) > FILE_MAXDIR + FILE_MAXFILE ) + return PyErr_Format( PyExc_RuntimeError, "path too long" ); + + p = strrchr( path, DIRSEP ); + + if( p && strip ) { + n = path + len - p; + BLI_strncpy( basename, p + 1, n ); /* + 1 to skip the sep */ + } else + BLI_strncpy( basename, path, len ); + + dot = strrchr( basename, '.' ); + + /* now the extension: always remove the one in basename */ + if( dot || ext ) { + if( !ext ) + basename[dot - basename] = '\0'; + else { /* if user gave an ext, append it */ + + if( dot ) + n = dot - basename; + else + n = strlen( basename ); + + BLI_strncpy( basename + n, ext, lenext ); + } + } + + return PyUnicode_FromString( basename ); +} + +static PyObject *M_sys_time( PyObject * self ) +{ + return PyFloat_FromDouble( PIL_check_seconds_timer( ) ); +} + +static PyObject *M_sys_sleep( PyObject * self, PyObject * args ) +{ + int millisecs = 10; + + if( !PyArg_ParseTuple( args, "|i:Blender.sys.sleep", &millisecs ) ) + return NULL; + + PIL_sleep_ms( millisecs ); + + Py_RETURN_NONE; +} + +static PyObject *M_sys_exists( PyObject * self, PyObject * value ) +{ + char *fname = _PyUnicode_AsString(value); + + int mode = 0, i = -1; + + if( !fname ) + return PyErr_Format( PyExc_TypeError, "expected string (pathname) argument" ); + + mode = BLI_exist(fname); + + if( mode == 0 ) + i = 0; + else if( S_ISREG( mode ) ) + i = 1; + else if( S_ISDIR( mode ) ) + i = 2; + /* i stays as -1 if path exists but is neither a regular file nor a dir */ + + return PyLong_FromLong(i); +} + +static PyObject *M_sys_expandpath( PyObject * self, PyObject * value ) +{ + char *path = _PyUnicode_AsString(value); + char expanded[FILE_MAXDIR + FILE_MAXFILE]; + bContext *C = BPy_GetContext(); + Scene *scene = CTX_data_scene(C); + + if (!path) + return PyErr_Format( PyExc_TypeError, "expected string argument" ); + + BLI_strncpy(expanded, path, FILE_MAXDIR + FILE_MAXFILE); + BLI_convertstringcode(expanded, G.sce); + BLI_convertstringframe(expanded, scene->r.cfra); + + return PyUnicode_FromString(expanded); +} + +static PyObject *M_sys_cleanpath( PyObject * self, PyObject * value ) +{ + char *path = _PyUnicode_AsString(value); + char cleaned[FILE_MAXDIR + FILE_MAXFILE]; + int trailing_slash = 0, last; + if (!path) + return PyErr_Format( PyExc_TypeError, "expected string argument" ); + last = strlen(path)-1; + if ((last >= 0) && ((path[last]=='/') || (path[last]=='\\'))) { + trailing_slash = 1; + } + BLI_strncpy(cleaned, path, FILE_MAXDIR + FILE_MAXFILE); + BLI_cleanup_file(NULL, cleaned); + + if (trailing_slash) { + BLI_add_slash(cleaned); + } + + return PyUnicode_FromString(cleaned); +} + +static PyObject *M_sys_relpath( PyObject * self, PyObject * args ) +{ + char *base = G.sce; + char *path; + char relpath[FILE_MAXDIR + FILE_MAXFILE]; + + if( !PyArg_ParseTuple( args, "s|s:Blender.sys.relpath", &path, &base ) ) + return NULL; + + strncpy(relpath, path, sizeof(relpath)); + BLI_makestringcode(base, relpath); + + return PyUnicode_FromString(relpath); +} + +#if 0 + +static PyObject *bpy_sys_get_blender_version() +{ + return PyUnicode_FromString(G.version); +} + +#endif diff --git a/source/blender/python/intern/bpy_sys.h b/source/blender/python/intern/bpy_sys.h new file mode 100644 index 00000000000..a045ed0d537 --- /dev/null +++ b/source/blender/python/intern/bpy_sys.h @@ -0,0 +1,41 @@ +/* + * $Id: Sys.h 14444 2008-04-16 22:40:48Z hos $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL LICENSE BLOCK ***** +*/ + +#ifndef BPY_SYS_H + +/* #include */ + +/* PyObject *sys_Init( void ); */ + +#include + +PyObject *BPY_sys_module( void ); + + +#endif /* BPY_SYS_H */ -- cgit v1.2.3 From f5f6850f23d594582c6438d04296ab84ef973521 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 29 Jun 2009 19:48:11 +0000 Subject: *make type of acceleration structure changeable at runtime *added some counter code (test/hits) for primitives and raycasts --- release/ui/buttons_scene.py | 1 + source/blender/makesrna/intern/rna_scene.c | 13 +++++++ source/blender/render/extern/include/RE_raytrace.h | 36 +++++++++++++++++- source/blender/render/intern/source/rayobject.c | 44 ++++++++++++++++------ source/blender/render/intern/source/rayshade.c | 22 +++++++---- 5 files changed, 95 insertions(+), 21 deletions(-) diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index df172ea8298..25ff12de306 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -25,6 +25,7 @@ class RENDER_PT_shading(RenderButtonsPanel): col.itemR(rd, "render_raytracing", text="Ray Tracing") colsub = col.column() colsub.active = rd.render_raytracing + colsub.itemR(rd, "raytrace_structure", text="Structure") colsub.itemR(rd, "octree_resolution", text="Octree") col.itemR(rd, "dither_intensity", text="Dither", slider=True) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 1365ab75fc7..662327439b9 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -199,6 +199,13 @@ void rna_def_scene_render_data(BlenderRNA *brna) {256, "OCTREE_RES_256", 0, "256", ""}, {512, "OCTREE_RES_512", 0, "512", ""}, {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem raytrace_structure_items[] = { + {R_RAYSTRUCTURE_HIER_BVH_BVH, "{R_RAYSTRUCTURE_HIER_BVH_BVH", 0, "BVH of BVH's", "Create a BVH of objects (each object has it own BVH)"}, + {R_RAYSTRUCTURE_HIER_BVH_OCTREE, "{R_RAYSTRUCTURE_HIER_BVH_OCTREE", 0, "BVH of octree", "Create a BVH of objects (each object has it own octree)"}, + {R_RAYSTRUCTURE_SINGLE_BVH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "Single BVH", "BVH of all primitives (no instance support)"}, + {R_RAYSTRUCTURE_SINGLE_OCTREE, "{R_RAYSTRUCTURE_SINGLE_OCTREE", 0, "Octree", "Octree of all primitives (no instance support)"}, + {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem fixed_oversample_items[] = { {5, "OVERSAMPLE_5", 0, "5", ""}, @@ -594,6 +601,12 @@ void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_items(prop, octree_resolution_items); RNA_def_property_ui_text(prop, "Octree Resolution", "Resolution of raytrace accelerator. Use higher resolutions for larger scenes."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "raytrace_structure", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "raystructure"); + RNA_def_property_enum_items(prop, raytrace_structure_items); + RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index db3dc50c843..b1d8abef766 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -31,10 +31,12 @@ #ifndef RE_RAYTRACE_H #define RE_RAYTRACE_H +#define RE_RAY_COUNTER /* Internals about raycasting structures can be found on intern/raytree.h */ typedef struct RayObject RayObject; typedef struct Isect Isect; +typedef struct RayCounter RayCounter; struct DerivedMesh; struct Mesh; @@ -80,10 +82,42 @@ struct Isect int skip; /* RE_SKIP_CULLFACE */ float col[4]; /* RGBA for shadow_tra */ - + void *userdata; + +#ifdef RE_RAY_COUNTER + RayCounter *count; +#endif + }; +#ifdef RE_RAYCOUNTER + +struct RayCounter +{ + + struct + { + unsigned long long test, hit; + + } intersect_rayface, raycast; + + unsigned long long rayshadow_last_hit_optimization; +}; + +void RE_RC_INIT (RayCounter *rc); +void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); +#define RE_RC_COUNT(var) (var)++ + +#else + +#define RE_RC_INIT(rc) +#define RE_RC_MERGE(dest,src) +#define RE_RC_COUNT(var) + +#endif + + /* ray types */ #define RE_RAY_SHADOW 0 #define RE_RAY_MIRROR 1 diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 4d0606e2067..ef224dc7d21 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -128,6 +128,7 @@ static int intersect_rayface(RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; + RE_RC_COUNT(is->count->intersect_rayface.test); VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); @@ -246,6 +247,8 @@ static int intersect_rayface(RayFace *face, Isect *is) } #endif + RE_RC_COUNT(is->count->intersect_rayface.hit); + is->isect= ok; // wich half of the quad is->labda= labda; is->u= u; is->v= v; @@ -261,24 +264,27 @@ static int intersect_rayface(RayFace *face, Isect *is) int RE_rayobject_raycast(RayObject *r, Isect *i) { - static int casted_rays = 0; - - if(casted_rays++ % (1<<20) == 0) - printf("Casting %d rays\n", casted_rays); - -/* - i->labda = 10000.0; - i->vec[0] *= i->labda; - i->vec[1] *= i->labda; - i->vec[2] *= i->labda; - i->labda = 1.0f; -*/ + RE_RC_COUNT(i->count->raycast.test); + i->dist = VecLength(i->vec); if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) + { + RE_RC_COUNT(i->count->raycast.hit); + RE_RC_COUNT(i->count->rayshadow_last_hit_optimization ); return 1; + } +#ifdef RE_RAYCOUNTER + if(RE_rayobject_intersect(r, i)) + { + RE_RC_COUNT(i->count->raycast.hit); + return 1; + } + return 0; +#else return RE_rayobject_intersect(r, i); +#endif } int RE_rayobject_intersect(RayObject *r, Isect *i) @@ -329,3 +335,17 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) } } +#ifdef RE_RAYCOUNTER +void RE_merge_raycounter(RayCounter *dest, RayCounter *tmp) +{ + int i; + for(i=0; i<3; i++) dest->casted[i] += tmp->casted[i]; + for(i=0; i<3; i++) dest->hit [i] += tmp->hit [i]; + + dest->test_primitives += tmp->test_primitives; + dest->hit_primitives += tmp->hit_primitives; + + dest->test_bb += tmp->test_bb; + dest->hit_bb += tmp->hit_bb; +} +#endif \ No newline at end of file diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 320b4cb601b..66afb7510a4 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -175,10 +175,13 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) assert( faces > 0 ); //Create Ray cast accelaration structure - + //TODO dynamic ocres -// raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); - raytree = obr->raytree = RE_rayobject_bvh_create( faces ); + if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) + raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); + else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH) + raytree = obr->raytree = RE_rayobject_bvh_create( faces ); + face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); obr->rayobi = obi; @@ -284,8 +287,11 @@ static void makeraytree_single(Render *re) } //Create raytree -// raytree = re->raytree = RE_rayobject_octree_create(re->r.ocres, faces); - raytree = re->raytree = RE_rayobject_bvh_create(faces); + if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) + raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); + else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) + raytree = re->raytree = RE_rayobject_bvh_create( faces ); + face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); for(obi=re->instancetable.first; obi; obi=obi->next) @@ -313,10 +319,10 @@ static void makeraytree_single(Render *re) void makeraytree(Render *re) { - if(1) - makeraytree_hier(re); - else + if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE)) makeraytree_single(re); + else + makeraytree_hier(re); } -- cgit v1.2.3 From 1136656bbadc92936fa497e2ddd99bae1b982982 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 29 Jun 2009 20:15:59 +0000 Subject: *forgot this file --- source/blender/makesdna/DNA_scene_types.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 7391201776e..e8279604100 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -232,6 +232,8 @@ typedef struct RenderData { /* render engine, octree resolution */ short renderer, ocres; + short raystructure; + short pad4[3]; /** * What to do with the sky/background. Picks sky/premul/key @@ -660,6 +662,12 @@ typedef struct Scene { #define R_INTERN 0 #define R_YAFRAY 1 +/* raytrace structure */ +#define R_RAYSTRUCTURE_HIER_BVH_BVH 0 +#define R_RAYSTRUCTURE_HIER_BVH_OCTREE 1 +#define R_RAYSTRUCTURE_SINGLE_OCTREE 2 +#define R_RAYSTRUCTURE_SINGLE_BVH 3 + /* scemode (int now) */ #define R_DOSEQ 0x0001 #define R_BG_RENDER 0x0002 -- cgit v1.2.3 From e0cfafa6292cbcec5d49817583204a418308aac7 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 30 Jun 2009 01:17:50 +0000 Subject: Measure build time... *as expected it's a lot faster on BVH --- source/blender/render/intern/include/rayobject.h | 27 ++++++++++++++++++++++++ source/blender/render/intern/source/rayshade.c | 4 ++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 064341ae18b..53d96d6331f 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -120,4 +120,31 @@ int RE_rayobject_intersect(RayObject *r, Isect *i); #define ISECT_EPSILON ((float)FLT_EPSILON) + + +#if !defined(_WIN32) + +#include +#include +#include + +#define BENCH(a,name) \ + do { \ + double _t1, _t2; \ + struct timeval _tstart, _tend; \ + clock_t _clock_init = clock(); \ + gettimeofday ( &_tstart, NULL); \ + (a); \ + gettimeofday ( &_tend, NULL); \ + _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); \ + _t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); \ + printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\ + } while(0) +#else + +#define BENCH(a) (a) + +#endif + + #endif diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 66afb7510a4..3fe3ac8690b 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -320,9 +320,9 @@ static void makeraytree_single(Render *re) void makeraytree(Render *re) { if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE)) - makeraytree_single(re); + BENCH(makeraytree_single(re), tree_build); else - makeraytree_hier(re); + BENCH(makeraytree_hier(re), tree_build); } -- cgit v1.2.3 From 021e0cc53f5169a92e06eafa321bc53b305f002f Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 30 Jun 2009 14:05:33 +0000 Subject: *reserved RayObject align offset 0 for private usage inside each structure point is that other structures like trees can then distiguish between other nodes or rayobject primitives withouth needing any other variable. (Note yet used but will reduce memory by a nice factor (linear to the number of primitives)) --- source/blender/render/intern/include/rayobject.h | 21 +++++++++++++-------- source/blender/render/intern/source/rayobject.c | 16 +++++++++------- source/blender/render/intern/source/rayobject_bvh.c | 2 +- .../render/intern/source/rayobject_instance.c | 2 +- .../blender/render/intern/source/rayobject_mesh.c | 2 +- .../blender/render/intern/source/rayobject_octree.c | 4 ++-- source/blender/render/intern/source/rayshade.c | 7 +++++-- 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 53d96d6331f..d516c122bcc 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -58,13 +58,15 @@ only 2 are used: addr&2 - type of object - 0 RayFace - 1 RayObject (generic with API callbacks) - 2 unused + 0 Self (reserved for each structure) + 1 RayFace + 2 RayObject (generic with API callbacks) 3 unused - 0 was choosed to RayFace because thats the one where speed will be needed. - + 0 means it's reserved and has it own meaning inside each ray acceleration structure + (this way each structure can use the allign offset to determine if a node represents a + RayObject primitive, which can be used to save memory) + You actually don't need to care about this if you are only using the API described on RE_raytrace.h */ @@ -101,10 +103,13 @@ typedef struct RayObjectAPI } RayObjectAPI; //TODO use intptr_t -#define RayObject_align(o) ((RayObject*)(((int)o)&(~3))) -#define RayObject_unalign(o) ((RayObject*)(((int)o)|1)) -#define RayObject_isFace(o) ((((int)o)&3) == 0) +#define RayObject_align(o) ((RayObject*)(((int)o)&(~3))) +#define RayObject_unalignRayFace(o) ((RayObject*)(((int)o)|1)) +#define RayObject_unalignRayAPI(o) ((RayObject*)(((int)o)|2)) + #define RayObject_isAligned(o) ((((int)o)&3) == 0) +#define RayObject_isRayFace(o) ((((int)o)&3) == 1) +#define RayObject_isRayAPI(o) ((((int)o)&3) == 2) /* * Extend min/max coords so that the rayobject is inside them diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index ef224dc7d21..3af2969b67e 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -255,7 +255,7 @@ static int intersect_rayface(RayFace *face, Isect *is) is->hit.ob = face->ob; is->hit.face = face->face; - is->last_hit = (RayObject*)face; + is->last_hit = (RayObject*) RayObject_unalignRayFace(face); return 1; } @@ -289,15 +289,16 @@ int RE_rayobject_raycast(RayObject *r, Isect *i) int RE_rayobject_intersect(RayObject *r, Isect *i) { - if(RayObject_isFace(r)) + if(RayObject_isRayFace(r)) { - return intersect_rayface( (RayFace*) r, i); + return intersect_rayface( (RayFace*) RayObject_align(r), i); } - else + else if(RayObject_isRayAPI(r)) { r = RayObject_align( r ); return r->api->raycast( r, i ); } + else assert(0); } void RE_rayobject_add(RayObject *r, RayObject *o) @@ -320,19 +321,20 @@ void RE_rayobject_free(RayObject *r) void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) { - if(RayObject_isFace(r)) + if(RayObject_isRayFace(r)) { - RayFace *face = (RayFace*)r; + RayFace *face = (RayFace*) RayObject_align(r); DO_MINMAX( face->v1, min, max ); DO_MINMAX( face->v2, min, max ); DO_MINMAX( face->v3, min, max ); if(face->v4) DO_MINMAX( face->v4, min, max ); } - else + else if(RayObject_isRayAPI(r)) { r = RayObject_align( r ); r->api->bb( r, min, max ); } + else assert(0); } #ifdef RE_RAYCOUNTER diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index c5e0cca808c..54fbc5ba0be 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -69,7 +69,7 @@ RayObject *RE_rayobject_bvh_create(int size) obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 4, 6); INIT_MINMAX(obj->bb[0], obj->bb[1]); - return RayObject_unalign((RayObject*) obj); + return RayObject_unalignRayAPI((RayObject*) obj); } static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c index a5024e97450..4a67e8108cb 100644 --- a/source/blender/render/intern/source/rayobject_instance.c +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -74,7 +74,7 @@ RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], Mat4CpyMat4(obj->target2global, transform); Mat4Invert(obj->global2target, obj->target2global); - return RayObject_unalign((RayObject*) obj); + return RayObject_unalignRayAPI((RayObject*) obj); } static int RayObject_instance_intersect(RayObject *o, Isect *isec) diff --git a/source/blender/render/intern/source/rayobject_mesh.c b/source/blender/render/intern/source/rayobject_mesh.c index eee7231aef4..538c245988d 100644 --- a/source/blender/render/intern/source/rayobject_mesh.c +++ b/source/blender/render/intern/source/rayobject_mesh.c @@ -128,5 +128,5 @@ RayObject* RE_rayobject_mesh_create(Mesh *mesh, void *ob) face->face = (void*)i; } - return RayObject_unalign((RayObject*) rm); + return RayObject_unalignRayAPI((RayObject*) rm); } diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index b715695dc10..b7850c05104 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -461,7 +461,7 @@ RayObject *RE_rayobject_octree_create(int ocres, int size) oc->ro_nodes_used = 0; - return RayObject_unalign((RayObject*) oc); + return RayObject_unalignRayAPI((RayObject*) oc); } @@ -631,7 +631,7 @@ static void RayObject_octree_done(RayObject *tree) for(c=0; cro_nodes_used; c++) { - assert( RayObject_isFace(oc->ro_nodes[c]) ); + assert( RayObject_isRayFace(oc->ro_nodes[c]) ); octree_fill_rayface(oc, (RayFace*)oc->ro_nodes[c]); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 3fe3ac8690b..975de3a5da3 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -198,7 +198,9 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) face->ob = obi; face->face = vlr; - RE_rayobject_add( raytree, (RayObject*)face++ ); + RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); + + face++; } } RE_rayobject_done( raytree ); @@ -311,7 +313,8 @@ static void makeraytree_single(Render *re) face->ob = obi; face->face = vlr; - RE_rayobject_add( raytree, (RayObject*)face++ ); + RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); + face++; } } RE_rayobject_done( raytree ); -- cgit v1.2.3 From 1deba75110aebda447beb79a8f07dae35f5bcc65 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 30 Jun 2009 22:07:42 +0000 Subject: *Added initial code of rayobject_rtbuild An helper class to build trees --- source/blender/render/extern/include/RE_raytrace.h | 9 +- .../render/intern/include/rayobject_rtbuild.h | 84 ++++++++ .../render/intern/source/rayobject_blibvh.c | 140 +++++++++++++ .../blender/render/intern/source/rayobject_bvh.c | 140 ------------- .../render/intern/source/rayobject_rtbuild.c | 222 +++++++++++++++++++++ source/blender/render/intern/source/rayshade.c | 6 +- 6 files changed, 456 insertions(+), 145 deletions(-) create mode 100644 source/blender/render/intern/include/rayobject_rtbuild.h create mode 100644 source/blender/render/intern/source/rayobject_blibvh.c delete mode 100644 source/blender/render/intern/source/rayobject_bvh.c create mode 100644 source/blender/render/intern/source/rayobject_rtbuild.c diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index b1d8abef766..0f92f54b396 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -47,7 +47,7 @@ void RE_rayobject_free(RayObject *r); /* RayObject constructors */ RayObject* RE_rayobject_octree_create(int ocres, int size); -RayObject* RE_rayobject_bvh_create(int size); +RayObject* RE_rayobject_blibvh_create(int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); //RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); @@ -59,8 +59,13 @@ struct Isect float start[3]; float vec[3]; float labda; + + /* length of vec, configured by RE_rayobject_raycast */ + int bv_index[6]; + float idot_axis[3]; + float dist; - float dist; /* length of vec, configured by RE_rayobject_raycast */ + /* float end[3]; - not used */ float u, v; diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h new file mode 100644 index 00000000000..b1458a571dd --- /dev/null +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -0,0 +1,84 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYOBJECT_RTBUILD_H +#define RE_RAYOBJECT_RTBUILD_H + +#include "rayobject.h" + +/* + * Ray Tree Builder + * this structs helps building any type of tree + * it contains several methods to organiza/split nodes + * allowing to create a given tree on the fly. + * + * Idea is that other trees BVH, BIH can use this code to + * generate with simple calls, and then convert to the theirs + * specific structure on the fly. + */ +#define MAX_CHILDS 32 +typedef struct RTBuilder +{ + /* list to all primitives in this tree */ + RayObject **begin, **end; + + /* axis used (if any) on the split method */ + int split_axis; + + /* links to child partitions calculated during splitting */ + RayObject **child[MAX_CHILDS+1]; + +} RTBuilder; + +/* used during creation */ +RTBuilder* rtbuild_create(int size); +void rtbuild_free(RTBuilder *b); +void rtbuild_add(RTBuilder *b, RayObject *o); +int rtbuild_size(RTBuilder *b); + +/* used during tree reorganization */ +RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); +void rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); +void rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); + +/* +static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *b) +{ + int i; + int nc = rtbuild_mean_split_largest_axis(b, BVH_NCHILDS); + RTBuilder tmp; + + BVHNode *bvh = tree->next_node++; + + bvh->split_axis = tmp->split_axis; + for(i=0; ichild[i] = bvh_rearrange( rtbuild_get_child(b, i, &tmp) ); +} + */ + +#endif diff --git a/source/blender/render/intern/source/rayobject_blibvh.c b/source/blender/render/intern/source/rayobject_blibvh.c new file mode 100644 index 00000000000..41da4679b6a --- /dev/null +++ b/source/blender/render/intern/source/rayobject_blibvh.c @@ -0,0 +1,140 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include + +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_kdopbvh.h" +#include "BLI_arithb.h" +#include "RE_raytrace.h" +#include "render_types.h" +#include "rayobject.h" + +static int RayObject_blibvh_intersect(RayObject *o, Isect *isec); +static void RayObject_blibvh_add(RayObject *o, RayObject *ob); +static void RayObject_blibvh_done(RayObject *o); +static void RayObject_blibvh_free(RayObject *o); +static void RayObject_blibvh_bb(RayObject *o, float *min, float *max); + +static RayObjectAPI bvh_api = +{ + RayObject_blibvh_intersect, + RayObject_blibvh_add, + RayObject_blibvh_done, + RayObject_blibvh_free, + RayObject_blibvh_bb +}; + +typedef struct BVHObject +{ + RayObject rayobj; + BVHTree *bvh; + float bb[2][3]; + +} BVHObject; + + +RayObject *RE_rayobject_blibvh_create(int size) +{ + BVHObject *obj= (BVHObject*)MEM_callocN(sizeof(BVHObject), "BVHObject"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bvh_api; + obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 4, 6); + + INIT_MINMAX(obj->bb[0], obj->bb[1]); + return RayObject_unalignRayAPI((RayObject*) obj); +} + +static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) +{ + Isect *isec = (Isect*)userdata; + RayObject *face = (RayObject*)index; + + if(RE_rayobject_intersect(face,isec)) + { + hit->index = index; + + if(isec->mode == RE_RAY_SHADOW) + hit->dist = 0; + else + hit->dist = isec->labda*isec->dist; + } +} + +static int RayObject_blibvh_intersect(RayObject *o, Isect *isec) +{ + BVHObject *obj = (BVHObject*)o; + BVHTreeRayHit hit; + float dir[3]; + + VECCOPY(dir, isec->vec); + Normalize(dir); + + hit.index = 0; + hit.dist = isec->labda*isec->dist; + + return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, isec); +} + +static void RayObject_blibvh_add(RayObject *o, RayObject *ob) +{ + BVHObject *obj = (BVHObject*)o; + float min_max[6]; + INIT_MINMAX(min_max, min_max+3); + RE_rayobject_merge_bb(ob, min_max, min_max+3); + + DO_MINMAX(min_max , obj->bb[0], obj->bb[1]); + DO_MINMAX(min_max+3, obj->bb[0], obj->bb[1]); + + BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); +} + +static void RayObject_blibvh_done(RayObject *o) +{ + BVHObject *obj = (BVHObject*)o; + BLI_bvhtree_balance(obj->bvh); +} + +static void RayObject_blibvh_free(RayObject *o) +{ + BVHObject *obj = (BVHObject*)o; + + if(obj->bvh) + BLI_bvhtree_free(obj->bvh); + + MEM_freeN(obj); +} + +static void RayObject_blibvh_bb(RayObject *o, float *min, float *max) +{ + BVHObject *obj = (BVHObject*)o; + DO_MINMAX( obj->bb[0], min, max ); + DO_MINMAX( obj->bb[1], min, max ); +} diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c deleted file mode 100644 index 54fbc5ba0be..00000000000 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include - -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_kdopbvh.h" -#include "BLI_arithb.h" -#include "RE_raytrace.h" -#include "render_types.h" -#include "rayobject.h" - -static int RayObject_bvh_intersect(RayObject *o, Isect *isec); -static void RayObject_bvh_add(RayObject *o, RayObject *ob); -static void RayObject_bvh_done(RayObject *o); -static void RayObject_bvh_free(RayObject *o); -static void RayObject_bvh_bb(RayObject *o, float *min, float *max); - -static RayObjectAPI bvh_api = -{ - RayObject_bvh_intersect, - RayObject_bvh_add, - RayObject_bvh_done, - RayObject_bvh_free, - RayObject_bvh_bb -}; - -typedef struct BVHObject -{ - RayObject rayobj; - BVHTree *bvh; - float bb[2][3]; - -} BVHObject; - - -RayObject *RE_rayobject_bvh_create(int size) -{ - BVHObject *obj= (BVHObject*)MEM_callocN(sizeof(BVHObject), "BVHObject"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bvh_api; - obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 4, 6); - - INIT_MINMAX(obj->bb[0], obj->bb[1]); - return RayObject_unalignRayAPI((RayObject*) obj); -} - -static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) -{ - Isect *isec = (Isect*)userdata; - RayObject *face = (RayObject*)index; - - if(RE_rayobject_intersect(face,isec)) - { - hit->index = index; - - if(isec->mode == RE_RAY_SHADOW) - hit->dist = 0; - else - hit->dist = isec->labda*isec->dist; - } -} - -static int RayObject_bvh_intersect(RayObject *o, Isect *isec) -{ - BVHObject *obj = (BVHObject*)o; - BVHTreeRayHit hit; - float dir[3]; - - VECCOPY(dir, isec->vec); - Normalize(dir); - - hit.index = 0; - hit.dist = isec->labda*isec->dist; - - return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, isec); -} - -static void RayObject_bvh_add(RayObject *o, RayObject *ob) -{ - BVHObject *obj = (BVHObject*)o; - float min_max[6]; - INIT_MINMAX(min_max, min_max+3); - RE_rayobject_merge_bb(ob, min_max, min_max+3); - - DO_MINMAX(min_max , obj->bb[0], obj->bb[1]); - DO_MINMAX(min_max+3, obj->bb[0], obj->bb[1]); - - BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); -} - -static void RayObject_bvh_done(RayObject *o) -{ - BVHObject *obj = (BVHObject*)o; - BLI_bvhtree_balance(obj->bvh); -} - -static void RayObject_bvh_free(RayObject *o) -{ - BVHObject *obj = (BVHObject*)o; - - if(obj->bvh) - BLI_bvhtree_free(obj->bvh); - - MEM_freeN(obj); -} - -static void RayObject_bvh_bb(RayObject *o, float *min, float *max) -{ - BVHObject *obj = (BVHObject*)o; - DO_MINMAX( obj->bb[0], min, max ); - DO_MINMAX( obj->bb[1], min, max ); -} diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c new file mode 100644 index 00000000000..b89729e2b45 --- /dev/null +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -0,0 +1,222 @@ +#include "rayobject_rtbuild.h" +#include "MEM_guardedalloc.h" +#include "BLI_arithb.h" +#include "BKE_utildefines.h" + +static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); +static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); + + +static void RayObject_rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) +{ + int i; + + b->begin = begin; + b->end = end; + b->split_axis = 0; + + for(i=0; ichild[i] = 0; +} + +RTBuilder* RayObject_rtbuild_create(int size) +{ + RTBuilder *builder = (RTBuilder*) MEM_mallocN( sizeof(RTBuilder), "RTBuilder" ); + RayObject **memblock= (RayObject**)MEM_mallocN( sizeof(RayObject*),"RTBuilder.objects"); + RayObject_rtbuild_init(builder, memblock, memblock); + return builder; +} + +void RayObject_rtbuild_free(RTBuilder *b) +{ + MEM_freeN(b->begin); + MEM_freeN(b); +} + +void RayObject_rtbuild_add(RTBuilder *b, RayObject *o) +{ + *(b->end++) = o; +} + +RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) +{ + RayObject_rtbuild_init( tmp, b->child[child], b->child[child+1] ); + return tmp; +} + +int RayObject_rtbuild_size(RTBuilder *b) +{ + return b->end - b->begin; +} + +/* Split methods */ +static void merge_bb(RTBuilder *b, float *min, float *max) +{ + RayObject **index = b->begin; + + for(; index != b->end; index++) + RE_rayobject_merge_bb(*index, min, max); +} + +static int calc_largest_axis(RTBuilder *b) +{ + float min[3], max[3], sub[3]; + + INIT_MINMAX(min, max); + merge_bb( b, min, max); + + VECSUB(sub, max, min); + if(sub[0] > sub[1]) + { + if(sub[0] > sub[2]) + return 0; + else + return 2; + } + else + { + if(sub[1] > sub[2]) + return 1; + else + return 2; + } +} + + +//Unballanced mean +//TODO better balance nodes +//TODO suport for variable number of partitions (its hardcoded in 2) +void rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) +{ + int nth[3] = {0, (b->end - b->begin)/2, b->end-b->begin}; + split_leafs(b, nth, 2, axis); +} + + +void rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) +{ + int axis = calc_largest_axis(b); + rtbuild_mean_split(b, nchilds, axis); +} + + +/* + * Helper code + * PARTITION code / used on mean-split + * basicly this a std::nth_element (like on C++ STL algorithm) + */ +static void sort_swap(RTBuilder *b, int i, int j) +{ + SWAP(RayObject*, b->begin[i], b->begin[j]); +} + +static int sort_get_value(RTBuilder *b, int i) +{ + float min[3], max[3]; + RE_rayobject_merge_bb(b->begin[i], min, max); + return max[i]; +} + +static int medianof3(RTBuilder *d, int a, int b, int c) +{ + float fa = sort_get_value( d, a ); + float fb = sort_get_value( d, b ); + float fc = sort_get_value( d, c ); + + if(fb < fa) + { + if(fc < fb) + return b; + else + { + if(fc < fa) + return c; + else + return a; + } + } + else + { + if(fc > fb) + return b; + else + { + if(fc > fa) + return c; + else + return a; + } + } +} + +static void insertionsort(RTBuilder *b, int lo, int hi) +{ + int i; + for(i=lo; ibegin[i]; + float tv= sort_get_value(b, i); + int j=i; + + while( j != lo && tv < sort_get_value(b, j-1)) + { + b->begin[j] = b->begin[j-1]; + j--; + } + b->begin[j] = t; + } +} + +static int partition(RTBuilder *b, int lo, int mid, int hi) +{ + float x = sort_get_value( b, mid ); + + int i=lo, j=hi; + while (1) + { + while (sort_get_value(b,i) < x) i++; + j--; + while (x < sort_get_value(b,j)) j--; + if(!(i < j)) + return i; + + sort_swap(b, i, j); + i++; + } +} + +// +// PARTITION code / used on mean-split +// basicly this is an adapted std::nth_element (C++ STL ) +// +// after a call to this function you can expect one of: +// every node to left of a[n] are smaller or equal to it +// every node to the right of a[n] are greater or equal to it +static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n) +{ + int begin = _begin, end = _end, cut; + while(end-begin > 3) + { + cut = partition(b, begin, medianof3(b, begin, begin+(end-begin)/2, end-1), end); + if(cut <= n) + begin = cut; + else + end = cut; + } + insertionsort(b, begin, end); + + return n; +} + +static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) +{ + int i; + b->split_axis = split_axis; + for(i=0; i < partitions-1; i++) + { + if(nth[i] >= nth[partitions]) + break; + + partition_nth_element(b, nth[i], nth[i+1], nth[partitions] ); + } +} diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 975de3a5da3..75c93fc1c80 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -180,7 +180,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH) - raytree = obr->raytree = RE_rayobject_bvh_create( faces ); + raytree = obr->raytree = RE_rayobject_blibvh_create( faces ); face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); obr->rayobi = obi; @@ -240,7 +240,7 @@ static void makeraytree_hier(Render *re) num_objects++; //Create raytree - re->raytree = RE_rayobject_bvh_create( num_objects ); + re->raytree = RE_rayobject_blibvh_create( num_objects ); for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) @@ -292,7 +292,7 @@ static void makeraytree_single(Render *re) if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) - raytree = re->raytree = RE_rayobject_bvh_create( faces ); + raytree = re->raytree = RE_rayobject_blibvh_create( faces ); face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); -- cgit v1.2.3 From 91226e6807435c6e0163865fea4cb45e22b14e16 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 1 Jul 2009 11:27:43 +0000 Subject: *Added rayobject_bvh A bvh structure to use on the raytracer --- source/blender/render/extern/include/RE_raytrace.h | 8 +- source/blender/render/intern/include/rayobject.h | 6 + .../render/intern/include/rayobject_rtbuild.h | 23 +-- source/blender/render/intern/source/rayobject.c | 61 ++++++- .../blender/render/intern/source/rayobject_bvh.c | 200 +++++++++++++++++++++ .../render/intern/source/rayobject_rtbuild.c | 49 +++-- source/blender/render/intern/source/rayshade.c | 6 +- 7 files changed, 302 insertions(+), 51 deletions(-) create mode 100644 source/blender/render/intern/source/rayobject_bvh.c diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 0f92f54b396..e1d03c996a4 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -46,12 +46,14 @@ void RE_rayobject_done(RayObject *r); void RE_rayobject_free(RayObject *r); /* RayObject constructors */ + RayObject* RE_rayobject_octree_create(int ocres, int size); -RayObject* RE_rayobject_blibvh_create(int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); -//RayObject* RayObject_derivedmesh_create(struct DerivedMesh*, void *ob); -RayObject* RE_rayobject_mesh_create(struct Mesh*, void *ob); +#define RE_rayobject_tree_create RE_rayobject_bvh_create +RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ +RayObject* RE_rayobject_bvh_create(int size); /* rayobject_bvh.c */ + /* Ray Intersection */ struct Isect diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index d516c122bcc..3b77341f229 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -123,6 +123,12 @@ void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max); */ int RE_rayobject_intersect(RayObject *r, Isect *i); +/* + * Returns distance ray must travel to hit the given bounding box + * BB should be in format [2][3] + */ +float RE_rayobject_bb_intersect(const Isect *i, const float *bb); + #define ISECT_EPSILON ((float)FLT_EPSILON) diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index b1458a571dd..fbe3930149c 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -50,8 +50,8 @@ typedef struct RTBuilder /* axis used (if any) on the split method */ int split_axis; - /* links to child partitions calculated during splitting */ - RayObject **child[MAX_CHILDS+1]; + /* child partitions calculated during splitting */ + int child_offset[MAX_CHILDS+1]; } RTBuilder; @@ -63,22 +63,9 @@ int rtbuild_size(RTBuilder *b); /* used during tree reorganization */ RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); -void rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); -void rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); -/* -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *b) -{ - int i; - int nc = rtbuild_mean_split_largest_axis(b, BVH_NCHILDS); - RTBuilder tmp; - - BVHNode *bvh = tree->next_node++; - - bvh->split_axis = tmp->split_axis; - for(i=0; ichild[i] = bvh_rearrange( rtbuild_get_child(b, i, &tmp) ); -} - */ +/* Calculates child partitions and returns number of efectively needed partitions */ +int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); +int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); #endif diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 3af2969b67e..7779c2aee82 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -36,6 +36,34 @@ #include "render_types.h" #include "rayobject.h" + +/* + * Determines the distance that the ray must travel to hit the bounding volume of the given node + * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe + * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] + */ +float RE_rayobject_bb_intersect(const Isect *isec, const float *bb) +{ + float dist; + + float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; + float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; + float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; + float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; + float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; + float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; + + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return FLT_MAX; + if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return FLT_MAX; + if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return FLT_MAX; + + dist = t1x; + if (t1y > dist) dist = t1y; + if (t1z > dist) dist = t1z; + return dist; +} + + /* only for self-intersecting test with current render face (where ray left) */ static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, float ry1, float rz1) { @@ -262,28 +290,43 @@ static int intersect_rayface(RayFace *face, Isect *is) return 0; } -int RE_rayobject_raycast(RayObject *r, Isect *i) +int RE_rayobject_raycast(RayObject *r, Isect *isec) { - RE_RC_COUNT(i->count->raycast.test); + int i; + RE_RC_COUNT(isec->count->raycast.test); + + /* Setup vars used on raycast */ + isec->dist = VecLength(isec->vec); + + for(i=0; i<3; i++) + { + isec->idot_axis[i] = 1.0f / isec->vec[i]; + + isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i]; + + isec->bv_index[2*i] = i+3*isec->bv_index[2*i]; + isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; + } - i->dist = VecLength(i->vec); - if(i->mode==RE_RAY_SHADOW && i->last_hit && RE_rayobject_intersect(i->last_hit, i)) + /* Last hit heuristic */ + if(isec->mode==RE_RAY_SHADOW && isec->last_hit && RE_rayobject_intersect(isec->last_hit, isec)) { - RE_RC_COUNT(i->count->raycast.hit); - RE_RC_COUNT(i->count->rayshadow_last_hit_optimization ); + RE_RC_COUNT(isec->count->raycast.hit); + RE_RC_COUNT(isec->count->rayshadow_last_hit_optimization ); return 1; } #ifdef RE_RAYCOUNTER - if(RE_rayobject_intersect(r, i)) + if(RE_rayobject_intersect(r, isec)) { - RE_RC_COUNT(i->count->raycast.hit); + RE_RC_COUNT(isec->count->raycast.hit); return 1; } return 0; #else - return RE_rayobject_intersect(r, i); + return RE_rayobject_intersect(r, isec); #endif } diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c new file mode 100644 index 00000000000..ea590ef83fd --- /dev/null +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -0,0 +1,200 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include + +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" + +#define BVH_NCHILDS 2 +typedef struct BVHTree BVHTree; + +static int bvh_intersect(BVHTree *obj, Isect *isec); +static void bvh_add(BVHTree *o, RayObject *ob); +static void bvh_done(BVHTree *o); +static void bvh_free(BVHTree *o); +static void bvh_bb(BVHTree *o, float *min, float *max); + +static RayObjectAPI bvh_api = +{ + (RE_rayobject_raycast_callback) bvh_intersect, + (RE_rayobject_add_callback) bvh_add, + (RE_rayobject_done_callback) bvh_done, + (RE_rayobject_free_callback) bvh_free, + (RE_rayobject_merge_bb_callback)bvh_bb +}; + +typedef struct BVHNode BVHNode; +struct BVHNode +{ + BVHNode *child[BVH_NCHILDS]; + float bb[2][3]; +}; + +struct BVHTree +{ + RayObject rayobj; + + BVHNode *alloc, *next_node, *root; + RTBuilder *builder; + +}; + + +RayObject *RE_rayobject_bvh_create(int size) +{ + BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bvh_api; + obj->builder = rtbuild_create( size ); + obj->root = NULL; + + return RayObject_unalignRayAPI((RayObject*) obj); +} + +static void bvh_free(BVHTree *obj) +{ + if(obj->builder) + rtbuild_free(obj->builder); + + if(obj->alloc) + MEM_freeN(obj->alloc); + + MEM_freeN(obj); +} + + +static void bvh_merge_bb(BVHNode *node, float *min, float *max) +{ + if(RayObject_isAligned(node)) + { + //TODO only half operations needed + DO_MINMAX(node->bb[0], min, max); + DO_MINMAX(node->bb[1], min, max); + } + else + { + RE_rayobject_merge_bb( (RayObject*)node, min, max); + } +} + +static void bvh_bb(BVHTree *obj, float *min, float *max) +{ + bvh_merge_bb(obj->root, min, max); +} + +/* + * Tree transverse + */ +static int dfs_raycast(BVHNode *node, Isect *isec) +{ + int hit = 0; + if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) + { + int i; + for(i=0; ichild[i])) + { + hit = dfs_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit = RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + return hit; +} + +static int bvh_intersect(BVHTree *obj, Isect *isec) +{ + if(RayObject_isAligned(obj->root)) + return dfs_raycast(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*)obj->root, isec); +} + + +/* + * Builds a BVH tree from builder object + */ +static void bvh_add(BVHTree *obj, RayObject *ob) +{ + rtbuild_add( obj->builder, ob ); +} + +static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder) +{ + if(rtbuild_size(builder) == 1) + { + return (BVHNode*)builder->begin[0]; + } + else + { + int i; + int nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); + RTBuilder tmp; + + BVHNode *parent = tree->next_node++; + + INIT_MINMAX(parent->bb[0], parent->bb[1]); +// bvh->split_axis = tmp->split_axis; + for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp) ); + bvh_merge_bb(parent->child[i], parent->bb[0], parent->bb[1]); + } + + return parent; + } +} + +static void bvh_done(BVHTree *obj) +{ + int needed_nodes; + assert(obj->root == NULL && obj->next_node == NULL && obj->builder); + + needed_nodes = (rtbuild_size(obj->builder)+1)*2; + assert(needed_nodes > 0); + obj->alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); + obj->next_node = obj->alloc; + obj->root = bvh_rearrange( obj, obj->builder ); + + assert(obj->alloc+needed_nodes >= obj->next_node); + + + rtbuild_free( obj->builder ); + obj->builder = NULL; +} + diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index b89729e2b45..46833b8c15d 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -2,12 +2,13 @@ #include "MEM_guardedalloc.h" #include "BLI_arithb.h" #include "BKE_utildefines.h" +#include static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); -static void RayObject_rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) +static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) { int i; @@ -16,35 +17,35 @@ static void RayObject_rtbuild_init(RTBuilder *b, RayObject **begin, RayObject ** b->split_axis = 0; for(i=0; ichild[i] = 0; + b->child_offset[i] = 0; } -RTBuilder* RayObject_rtbuild_create(int size) +RTBuilder* rtbuild_create(int size) { RTBuilder *builder = (RTBuilder*) MEM_mallocN( sizeof(RTBuilder), "RTBuilder" ); - RayObject **memblock= (RayObject**)MEM_mallocN( sizeof(RayObject*),"RTBuilder.objects"); - RayObject_rtbuild_init(builder, memblock, memblock); + RayObject **memblock= (RayObject**)MEM_mallocN( sizeof(RayObject*)*size,"RTBuilder.objects"); + rtbuild_init(builder, memblock, memblock); return builder; } -void RayObject_rtbuild_free(RTBuilder *b) +void rtbuild_free(RTBuilder *b) { MEM_freeN(b->begin); MEM_freeN(b); } -void RayObject_rtbuild_add(RTBuilder *b, RayObject *o) +void rtbuild_add(RTBuilder *b, RayObject *o) { *(b->end++) = o; } RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) { - RayObject_rtbuild_init( tmp, b->child[child], b->child[child+1] ); + rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); return tmp; } -int RayObject_rtbuild_size(RTBuilder *b) +int rtbuild_size(RTBuilder *b) { return b->end - b->begin; } @@ -86,17 +87,23 @@ static int calc_largest_axis(RTBuilder *b) //Unballanced mean //TODO better balance nodes //TODO suport for variable number of partitions (its hardcoded in 2) -void rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) +int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) { - int nth[3] = {0, (b->end - b->begin)/2, b->end-b->begin}; - split_leafs(b, nth, 2, axis); + b->child_offset[0] = 0; + b->child_offset[1] = (b->end - b->begin) / 2; + b->child_offset[2] = (b->end - b->begin); + + assert( b->child_offset[0] != b->child_offset[1] && b->child_offset[1] != b->child_offset[2]); + + split_leafs(b, b->child_offset, 2, axis); + return 2; } -void rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) +int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) { int axis = calc_largest_axis(b); - rtbuild_mean_split(b, nchilds, axis); + return rtbuild_mean_split(b, nchilds, axis); } @@ -110,11 +117,12 @@ static void sort_swap(RTBuilder *b, int i, int j) SWAP(RayObject*, b->begin[i], b->begin[j]); } -static int sort_get_value(RTBuilder *b, int i) +static float sort_get_value(RTBuilder *b, int i) { float min[3], max[3]; + INIT_MINMAX(min, max); RE_rayobject_merge_bb(b->begin[i], min, max); - return max[i]; + return max[b->split_axis]; } static int medianof3(RTBuilder *d, int a, int b, int c) @@ -174,9 +182,14 @@ static int partition(RTBuilder *b, int lo, int mid, int hi) int i=lo, j=hi; while (1) { - while (sort_get_value(b,i) < x) i++; + while(sort_get_value(b,i) < x) + i++; + j--; - while (x < sort_get_value(b,j)) j--; + + while(x < sort_get_value(b,j)) + j--; + if(!(i < j)) return i; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 75c93fc1c80..4c16ac05ec2 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -180,7 +180,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH) - raytree = obr->raytree = RE_rayobject_blibvh_create( faces ); + raytree = obr->raytree = RE_rayobject_tree_create( faces ); face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); obr->rayobi = obi; @@ -240,7 +240,7 @@ static void makeraytree_hier(Render *re) num_objects++; //Create raytree - re->raytree = RE_rayobject_blibvh_create( num_objects ); + re->raytree = RE_rayobject_tree_create( num_objects ); for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) @@ -292,7 +292,7 @@ static void makeraytree_single(Render *re) if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) - raytree = re->raytree = RE_rayobject_blibvh_create( faces ); + raytree = re->raytree = RE_rayobject_tree_create( faces ); face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); -- cgit v1.2.3 From 1b557a61a53235f978262c52ac79fa16464bdd91 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 1 Jul 2009 12:36:05 +0000 Subject: fixed ray mirror/trans shadow on rayobject_bvh --- source/blender/render/intern/source/rayobject_bvh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index ea590ef83fd..4be57543a77 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -125,12 +125,12 @@ static int dfs_raycast(BVHNode *node, Isect *isec) for(i=0; ichild[i])) { - hit = dfs_raycast(node->child[i], isec); + hit |= dfs_raycast(node->child[i], isec); if(hit && isec->mode == RE_RAY_SHADOW) return hit; } else { - hit = RE_rayobject_intersect( (RayObject*)node->child[i], isec); + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); if(hit && isec->mode == RE_RAY_SHADOW) return hit; } } -- cgit v1.2.3 From 6ede28a05ae7cfbf8159277f3618b763d1fbb2c2 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 1 Jul 2009 18:23:11 +0000 Subject: - started OBJ importer conversion - added Mesh.add_uv_layer, Object.add_vertex_group --- release/io/import_obj.py | 1280 +++++++++++++++++++++++ source/blender/makesrna/intern/rna_mesh_api.c | 14 + source/blender/makesrna/intern/rna_object.c | 6 +- source/blender/makesrna/intern/rna_object_api.c | 57 +- 4 files changed, 1350 insertions(+), 7 deletions(-) create mode 100644 release/io/import_obj.py diff --git a/release/io/import_obj.py b/release/io/import_obj.py new file mode 100644 index 00000000000..b81ada15f89 --- /dev/null +++ b/release/io/import_obj.py @@ -0,0 +1,1280 @@ +#!BPY + +""" +Name: 'Wavefront (.obj)...' +Blender: 249 +Group: 'Import' +Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' +""" + +__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" +__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] +__version__= "2.11" + +__bpydoc__= """\ +This script imports a Wavefront OBJ files to Blender. + +Usage: +Run this script from "File->Import" menu and then load the desired OBJ file. +Note, This loads mesh objects and materials only, nurbs and curves are not supported. +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Campbell J Barton 2007 +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +from Blender import Mesh, Draw, Window, Texture, Material, sys +import bpy +import BPyMesh +import BPyImage +import BPyMessages + +try: import os +except: os= False + +# Generic path functions +def stripFile(path): + '''Return directory, where the file is''' + lastSlash= max(path.rfind('\\'), path.rfind('/')) + if lastSlash != -1: + path= path[:lastSlash] + return '%s%s' % (path, sys.sep) + +def stripPath(path): + '''Strips the slashes from the back of a string''' + return path.split('/')[-1].split('\\')[-1] + +def stripExt(name): # name is a string + '''Strips the prefix off the name before writing''' + index= name.rfind('.') + if index != -1: + return name[ : index ] + else: + return name +# end path funcs + +def unpack_list(list_of_tuples): + l = [] + for t in list_of_tuples: + l.extend(t) + return l + +# same as above except that it adds 0 for triangle faces +def unpack_face_list(list_of_tuples): + l = [] + for t in list_of_tuples: + if len(t) == 3: + t += [0] + l.extend(t) + return l + + +def line_value(line_split): + ''' + Returns 1 string represneting the value for this line + None will be returned if theres only 1 word + ''' + length= len(line_split) + if length == 1: + return None + + elif length == 2: + return line_split[1] + + elif length > 2: + return ' '.join( line_split[1:] ) + +def obj_image_load(imagepath, DIR, IMAGE_SEARCH): + ''' + Mainly uses comprehensiveImageLoad + but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores. + ''' + + if '_' in imagepath: + image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) + if image: return image + # Did the exporter rename the image? + image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) + if image: return image + + # Return an image, placeholder if it dosnt exist + image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH) + return image + + +def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH): + ''' + Create all the used materials in this obj, + assign colors and images to the materials from all referenced material libs + ''' + DIR= stripFile(filepath) + + #==================================================================================# + # This function sets textures defined in .mtl file # + #==================================================================================# + def load_material_image(blender_material, context_material_name, imagepath, type): + + texture= bpy.data.textures.new(type) + texture.setType('Image') + + # Absolute path - c:\.. etc would work here + image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) + has_data = image.has_data + texture.image = image + + # Adds textures for materials (rendering) + if type == 'Kd': + if has_data and image.depth == 32: + # Image has alpha + blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) + texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') + blender_material.mode |= Material.Modes.ZTRANSP + blender_material.alpha = 0.0 + else: + blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) + + # adds textures to faces (Textured/Alt-Z mode) + # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func. + unique_material_images[context_material_name]= image, has_data # set the texface image + + elif type == 'Ka': + blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API + + elif type == 'Ks': + blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) + + elif type == 'Bump': + blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR) + elif type == 'D': + blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA) + blender_material.mode |= Material.Modes.ZTRANSP + blender_material.alpha = 0.0 + # Todo, unset deffuse material alpha if it has an alpha channel + + elif type == 'refl': + blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF) + + + # Add an MTL with the same name as the obj if no MTLs are spesified. + temp_mtl= stripExt(stripPath(filepath))+ '.mtl' + + if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: + material_libs.append( temp_mtl ) + del temp_mtl + + #Create new materials + for name in unique_materials: # .keys() + if name != None: + unique_materials[name]= bpy.data.materials.new(name) + unique_material_images[name]= None, False # assign None to all material images to start with, add to later. + + unique_materials[None]= None + unique_material_images[None]= None, False + + for libname in material_libs: + mtlpath= DIR + libname + if not sys.exists(mtlpath): + #print '\tError Missing MTL: "%s"' % mtlpath + pass + else: + #print '\t\tloading mtl: "%s"' % mtlpath + context_material= None + mtl= open(mtlpath, 'rU') + for line in mtl: #.xreadlines(): + if line.startswith('newmtl'): + context_material_name= line_value(line.split()) + if unique_materials.has_key(context_material_name): + context_material = unique_materials[ context_material_name ] + else: + context_material = None + + elif context_material: + # we need to make a material to assign properties to it. + line_split= line.split() + line_lower= line.lower().lstrip() + if line_lower.startswith('ka'): + context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + elif line_lower.startswith('kd'): + context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + elif line_lower.startswith('ks'): + context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + elif line_lower.startswith('ns'): + context_material.setHardness( int((float(line_split[1])*0.51)) ) + elif line_lower.startswith('ni'): # Refraction index + context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3 + elif line_lower.startswith('d') or line_lower.startswith('tr'): + context_material.setAlpha(float(line_split[1])) + elif line_lower.startswith('map_ka'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Ka') + elif line_lower.startswith('map_ks'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Ks') + elif line_lower.startswith('map_kd'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Kd') + elif line_lower.startswith('map_bump'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Bump') + elif line_lower.startswith('map_d') or line_lower.startswith('map_tr'): # Alpha map - Dissolve + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'D') + + elif line_lower.startswith('refl'): # Reflectionmap + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'refl') + mtl.close() + + + + +def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): + ''' + Takes vert_loc and faces, and seperates into multiple sets of + (verts_loc, faces, unique_materials, dataname) + This is done so objects do not overload the 16 material limit. + ''' + + filename = stripExt(stripPath(filepath)) + + if not SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: + # use the filename for the object name since we arnt chopping up the mesh. + return [(verts_loc, faces, unique_materials, filename)] + + + def key_to_name(key): + # if the key is a tuple, join it to make a string + if type(key) == tuple: + return '%s_%s' % key + elif not key: + return filename # assume its a string. make sure this is true if the splitting code is changed + else: + return key + + # Return a key that makes the faces unique. + if SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: + def face_key(face): + return face[4] # object + + elif not SPLIT_OB_OR_GROUP and SPLIT_MATERIALS: + def face_key(face): + return face[2] # material + + else: # Both + def face_key(face): + return face[4], face[2] # object,material + + + face_split_dict= {} + + oldkey= -1 # initialize to a value that will never match the key + + for face in faces: + + key= face_key(face) + + if oldkey != key: + # Check the key has changed. + try: + verts_split, faces_split, unique_materials_split, vert_remap= face_split_dict[key] + except KeyError: + faces_split= [] + verts_split= [] + unique_materials_split= {} + vert_remap= [-1]*len(verts_loc) + + face_split_dict[key]= (verts_split, faces_split, unique_materials_split, vert_remap) + + oldkey= key + + face_vert_loc_indicies= face[0] + + # Remap verts to new vert list and add where needed + for enum, i in enumerate(face_vert_loc_indicies): + if vert_remap[i] == -1: + new_index= len(verts_split) + vert_remap[i]= new_index # set the new remapped index so we only add once and can reference next time. + face_vert_loc_indicies[enum] = new_index # remap to the local index + verts_split.append( verts_loc[i] ) # add the vert to the local verts + + else: + face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index + + matname= face[2] + if matname and not unique_materials_split.has_key(matname): + unique_materials_split[matname] = unique_materials[matname] + + faces_split.append(face) + + + # remove one of the itemas and reorder + return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.iteritems()] + + +def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): + ''' + Takes all the data gathered and generates a mesh, adding the new object to new_objects + deals with fgons, sharp edges and assigning materials + ''' + if not has_ngons: + CREATE_FGONS= False + + if unique_smooth_groups: + sharp_edges= {} + smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.iterkeys() ]) + context_smooth_group_old= -1 + + # Split fgons into tri's + fgon_edges= {} # Used for storing fgon keys + if CREATE_EDGES: + edges= [] + + context_object= None + + # reverse loop through face indicies + for f_idx in xrange(len(faces)-1, -1, -1): + + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object= faces[f_idx] + + len_face_vert_loc_indicies = len(face_vert_loc_indicies) + + if len_face_vert_loc_indicies==1: + faces.pop(f_idx)# cant add single vert faces + + elif not face_vert_tex_indicies or len_face_vert_loc_indicies == 2: # faces that have no texture coords are lines + if CREATE_EDGES: + # generators are better in python 2.4+ but can't be used in 2.3 + # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) ) + edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] ) + + faces.pop(f_idx) + else: + + # Smooth Group + if unique_smooth_groups and context_smooth_group: + # Is a part of of a smooth group and is a face + if context_smooth_group_old is not context_smooth_group: + edge_dict= smooth_group_users[context_smooth_group] + context_smooth_group_old= context_smooth_group + + for i in xrange(len_face_vert_loc_indicies): + i1= face_vert_loc_indicies[i] + i2= face_vert_loc_indicies[i-1] + if i1>i2: i1,i2= i2,i1 + + try: + edge_dict[i1,i2]+= 1 + except KeyError: + edge_dict[i1,i2]= 1 + + # FGons into triangles + if has_ngons and len_face_vert_loc_indicies > 4: + + ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies) + faces.extend(\ + [(\ + [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ + [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ + context_material,\ + context_smooth_group,\ + context_object)\ + for ngon in ngon_face_indices]\ + ) + + # edges to make fgons + if CREATE_FGONS: + edge_users= {} + for ngon in ngon_face_indices: + for i in (0,1,2): + i1= face_vert_loc_indicies[ngon[i ]] + i2= face_vert_loc_indicies[ngon[i-1]] + if i1>i2: i1,i2= i2,i1 + + try: + edge_users[i1,i2]+=1 + except KeyError: + edge_users[i1,i2]= 1 + + for key, users in edge_users.iteritems(): + if users>1: + fgon_edges[key]= None + + # remove all after 3, means we dont have to pop this one. + faces.pop(f_idx) + + + # Build sharp edges + if unique_smooth_groups: + for edge_dict in smooth_group_users.itervalues(): + for key, users in edge_dict.iteritems(): + if users==1: # This edge is on the boundry of a group + sharp_edges[key]= None + + + # map the material names to an index + material_mapping= dict([(name, i) for i, name in enumerate(unique_materials)]) # enumerate over unique_materials keys() + + materials= [None] * len(unique_materials) + + for name, index in material_mapping.iteritems(): + materials[index]= unique_materials[name] + + me= bpy.data.add_mesh(dataname) +# me= bpy.data.meshes.new(dataname) + + me.materials= materials[0:16] # make sure the list isnt too big. + #me.verts.extend([(0,0,0)]) # dummy vert + + me.add_geometry(len(verts_loc), 0, len(faces)) + + # verts_loc is a list of (x, y, z) tuples + me.verts.foreach_set("co", unpack_list(verts_loc)) +# me.verts.extend(verts_loc) + + # faces is a list of (vert_indices, texco_indices, ...) tuples + # XXX faces should not contain edges + # XXX no check for valid face indices + me.faces.foreach_set("verts", unpack_face_list([f[0] for f in faces])) +# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True) + + if verts_tex and me.faces: + me.add_uv_layer() +# me.faceUV= 1 + # TEXMODE= Mesh.FaceModes['TEX'] + + context_material_old= -1 # avoid a dict lookup + mat= 0 # rare case it may be un-initialized. + me_faces= me.faces +# ALPHA= Mesh.FaceTranspModes.ALPHA + + for i, face in enumerate(faces): + if len(face[0]) < 2: + pass #raise "bad face" + elif len(face[0])==2: + if CREATE_EDGES: + edges.append(face[0]) + else: +# face_index_map= face_mapping[i] + + # since we use foreach_set to add faces, all of them are added + if 1: +# if face_index_map!=None: # None means the face wasnt added + + blender_face = me.faces[i] +# blender_face= me_faces[face_index_map] + + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object= face + + + + if context_smooth_group: + blender_face.smooth= True + + if context_material: + if context_material_old is not context_material: + mat= material_mapping[context_material] + if mat>15: + mat= 15 + context_material_old= context_material + + blender_face.material_index= mat +# blender_face.mat= mat + + + if verts_tex: + + blender_tface= me.uv_layers[0].data[i] + + if context_material: + image, has_data= unique_material_images[context_material] + if image: # Can be none if the material dosnt have an image. + blender_tface.image= image +# blender_face.image= image + if has_data: +# if has_data and image.depth == 32: + blender_tface.transp = 'ALPHA' +# blender_face.transp |= ALPHA + + # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled. + if len(face_vert_loc_indicies)==4: + if face_vert_loc_indicies[2]==0 or face_vert_loc_indicies[3]==0: + face_vert_tex_indicies= face_vert_tex_indicies[2], face_vert_tex_indicies[3], face_vert_tex_indicies[0], face_vert_tex_indicies[1] + else: # length of 3 + if face_vert_loc_indicies[2]==0: + face_vert_tex_indicies= face_vert_tex_indicies[1], face_vert_tex_indicies[2], face_vert_tex_indicies[0] + # END EEEKADOODLE FIX + + # assign material, uv's and image + blender_tface.uv1= verts_tex[face_vert_tex_indicies[0]] + blender_tface.uv2= verts_tex[face_vert_tex_indicies[1]] + blender_tface.uv3= verts_tex[face_vert_tex_indicies[2]] + + if blender_face.verts[3] != 0: + blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]] + +# for ii, uv in enumerate(blender_face.uv): +# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]] + del me_faces +# del ALPHA + + # Add edge faces. + me_edges= me.edges +# if CREATE_FGONS and fgon_edges: +# FGON= Mesh.EdgeFlags.FGON +# for ed in me.findEdges( fgon_edges.keys() ): +# if ed!=None: +# me_edges[ed].flag |= FGON +# del FGON + +# if unique_smooth_groups and sharp_edges: +# SHARP= Mesh.EdgeFlags.SHARP +# for ed in me.findEdges( sharp_edges.keys() ): +# if ed!=None: +# me_edges[ed].flag |= SHARP +# del SHARP + +# if CREATE_EDGES: +# me_edges.extend( edges ) + +# del me_edges + +# me.calcNormals() + + ob= bpy.data.add_object("MESH", "Mesh") + ob.data= me +# ob= scn.objects.new(me) + new_objects.append(ob) + +# # Create the vertex groups. No need to have the flag passed here since we test for the +# # content of the vertex_groups. If the user selects to NOT have vertex groups saved then +# # the following test will never run +# for group_name, group_indicies in vertex_groups.iteritems(): +# i= ob.add_vertex_group(group_name) +# # me.addVertGroup(group_name) +# me.assign_verts_to_group(group_index, group_indicies, len(group_indicies), 1.0, 'REPLACE') +# # me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE) + + +class Mesh(bpy.types.Mesh): + + def assign_verts_to_group(self, group_index, vert_indices, weight): + + +def create_nurbs(scn, context_nurbs, vert_loc, new_objects): + ''' + Add nurbs object to blender, only support one type at the moment + ''' + deg = context_nurbs.get('deg', (3,)) + curv_range = context_nurbs.get('curv_range', None) + curv_idx = context_nurbs.get('curv_idx', []) + parm_u = context_nurbs.get('parm_u', []) + parm_v = context_nurbs.get('parm_v', []) + name = context_nurbs.get('name', 'ObjNurb') + cstype = context_nurbs.get('cstype', None) + + if cstype == None: + print '\tWarning, cstype not found' + return + if cstype != 'bspline': + print '\tWarning, cstype is not supported (only bspline)' + return + if not curv_idx: + print '\tWarning, curv argument empty or not set' + return + if len(deg) > 1 or parm_v: + print '\tWarning, surfaces not supported' + return + + cu = bpy.data.curves.new(name, 'Curve') + cu.flag |= 1 # 3D curve + + nu = None + for pt in curv_idx: + + pt = vert_loc[pt] + pt = (pt[0], pt[1], pt[2], 1.0) + + if nu == None: + nu = cu.appendNurb(pt) + else: + nu.append(pt) + + nu.orderU = deg[0]+1 + + # get for endpoint flag from the weighting + if curv_range and len(parm_u) > deg[0]+1: + do_endpoints = True + for i in xrange(deg[0]+1): + + if abs(parm_u[i]-curv_range[0]) > 0.0001: + do_endpoints = False + break + + if abs(parm_u[-(i+1)]-curv_range[1]) > 0.0001: + do_endpoints = False + break + + else: + do_endpoints = False + + if do_endpoints: + nu.flagU |= 2 + + + # close + ''' + do_closed = False + if len(parm_u) > deg[0]+1: + for i in xrange(deg[0]+1): + #print curv_idx[i], curv_idx[-(i+1)] + + if curv_idx[i]==curv_idx[-(i+1)]: + do_closed = True + break + + if do_closed: + nu.flagU |= 1 + ''' + + ob = scn.objects.new(cu) + new_objects.append(ob) + + +def strip_slash(line_split): + if line_split[-1][-1]== '\\': + if len(line_split[-1])==1: + line_split.pop() # remove the \ item + else: + line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number + return True + return False + + + +def get_float_func(filepath): + ''' + find the float function for this obj file + - weather to replace commas or not + ''' + file= open(filepath, 'rU') + for line in file: #.xreadlines(): + line = line.lstrip() + if line.startswith('v'): # vn vt v + if ',' in line: + return lambda f: float(f.replace(',', '.')) + elif '.' in line: + return float + + # incase all vert values were ints + return float + +def load_obj(filepath, + CLAMP_SIZE= 0.0, + CREATE_FGONS= True, + CREATE_SMOOTH_GROUPS= True, + CREATE_EDGES= True, + SPLIT_OBJECTS= True, + SPLIT_GROUPS= True, + SPLIT_MATERIALS= True, + ROTATE_X90= True, + IMAGE_SEARCH=True, + POLYGROUPS=False): + ''' + Called by the user interface or another script. + load_obj(path) - should give acceptable results. + This function passes the file and sends the data off + to be split into objects and then converted into mesh objects + ''' + print '\nimporting obj "%s"' % filepath + + if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: + POLYGROUPS = False + + time_main= sys.time() + + verts_loc= [] + verts_tex= [] + faces= [] # tuples of the faces + material_libs= [] # filanems to material libs this uses + vertex_groups = {} # when POLYGROUPS is true + + # Get the string to float conversion func for this file- is 'float' for almost all files. + float_func= get_float_func(filepath) + + # Context variables + context_material= None + context_smooth_group= None + context_object= None + context_vgroup = None + + # Nurbs + context_nurbs = {} + nurbs = [] + context_parm = '' # used by nurbs too but could be used elsewhere + + has_ngons= False + # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0 + + # Until we can use sets + unique_materials= {} + unique_material_images= {} + unique_smooth_groups= {} + # unique_obects= {} - no use for this variable since the objects are stored in the face. + + # when there are faces that end with \ + # it means they are multiline- + # since we use xreadline we cant skip to the next line + # so we need to know weather + context_multi_line= '' + + print '\tparsing obj file "%s"...' % filepath, + time_sub= sys.time() + + file= open(filepath, 'rU') + for line in file: #.xreadlines(): + line = line.lstrip() # rare cases there is white space at the start of the line + + if line.startswith('v '): + line_split= line.split() + # rotate X90: (x,-z,y) + verts_loc.append( (float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])) ) + + elif line.startswith('vn '): + pass + + elif line.startswith('vt '): + line_split= line.split() + verts_tex.append( (float_func(line_split[1]), float_func(line_split[2])) ) + + # Handel faces lines (as faces) and the second+ lines of fa multiline face here + # use 'f' not 'f ' because some objs (very rare have 'fo ' for faces) + elif line.startswith('f') or context_multi_line == 'f': + + if context_multi_line: + # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face + line_split= line.split() + + else: + line_split= line[2:].split() + face_vert_loc_indicies= [] + face_vert_tex_indicies= [] + + # Instance a face + faces.append((\ + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object\ + )) + + if strip_slash(line_split): + context_multi_line = 'f' + else: + context_multi_line = '' + + for v in line_split: + obj_vert= v.split('/') + + vert_loc_index= int(obj_vert[0])-1 + # Add the vertex to the current group + # *warning*, this wont work for files that have groups defined around verts + if POLYGROUPS and context_vgroup: + vertex_groups[context_vgroup].append(vert_loc_index) + + # Make relative negative vert indicies absolute + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + face_vert_loc_indicies.append(vert_loc_index) + + if len(obj_vert)>1 and obj_vert[1]: + # formatting for faces with normals and textures us + # loc_index/tex_index/nor_index + + vert_tex_index= int(obj_vert[1])-1 + # Make relative negative vert indicies absolute + if vert_tex_index < 0: + vert_tex_index= len(verts_tex) + vert_tex_index + 1 + + face_vert_tex_indicies.append(vert_tex_index) + else: + # dummy + face_vert_tex_indicies.append(0) + + if len(face_vert_loc_indicies) > 4: + has_ngons= True + + elif CREATE_EDGES and (line.startswith('l ') or context_multi_line == 'l'): + # very similar to the face load function above with some parts removed + + if context_multi_line: + # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face + line_split= line.split() + + else: + line_split= line[2:].split() + face_vert_loc_indicies= [] + face_vert_tex_indicies= [] + + # Instance a face + faces.append((\ + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object\ + )) + + if strip_slash(line_split): + context_multi_line = 'l' + else: + context_multi_line = '' + + isline= line.startswith('l') + + for v in line_split: + vert_loc_index= int(v)-1 + + # Make relative negative vert indicies absolute + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + face_vert_loc_indicies.append(vert_loc_index) + + elif line.startswith('s'): + if CREATE_SMOOTH_GROUPS: + context_smooth_group= line_value(line.split()) + if context_smooth_group=='off': + context_smooth_group= None + elif context_smooth_group: # is not None + unique_smooth_groups[context_smooth_group]= None + + elif line.startswith('o'): + if SPLIT_OBJECTS: + context_object= line_value(line.split()) + # unique_obects[context_object]= None + + elif line.startswith('g'): + if SPLIT_GROUPS: + context_object= line_value(line.split()) + # print 'context_object', context_object + # unique_obects[context_object]= None + elif POLYGROUPS: + context_vgroup = line_value(line.split()) + if context_vgroup and context_vgroup != '(null)': + vertex_groups.setdefault(context_vgroup, []) + else: + context_vgroup = None # dont assign a vgroup + + elif line.startswith('usemtl'): + context_material= line_value(line.split()) + unique_materials[context_material]= None + elif line.startswith('mtllib'): # usemap or usemat + material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line + + + # Nurbs support + elif line.startswith('cstype '): + context_nurbs['cstype']= line_value(line.split()) # 'rat bspline' / 'bspline' + elif line.startswith('curv ') or context_multi_line == 'curv': + line_split= line.split() + + curv_idx = context_nurbs['curv_idx'] = context_nurbs.get('curv_idx', []) # incase were multiline + + if not context_multi_line: + context_nurbs['curv_range'] = float_func(line_split[1]), float_func(line_split[2]) + line_split[0:3] = [] # remove first 3 items + + if strip_slash(line_split): + context_multi_line = 'curv' + else: + context_multi_line = '' + + + for i in line_split: + vert_loc_index = int(i)-1 + + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + curv_idx.append(vert_loc_index) + + elif line.startswith('parm') or context_multi_line == 'parm': + line_split= line.split() + + if context_multi_line: + context_multi_line = '' + else: + context_parm = line_split[1] + line_split[0:2] = [] # remove first 2 + + if strip_slash(line_split): + context_multi_line = 'parm' + else: + context_multi_line = '' + + if context_parm.lower() == 'u': + context_nurbs.setdefault('parm_u', []).extend( [float_func(f) for f in line_split] ) + elif context_parm.lower() == 'v': # surfaces not suported yet + context_nurbs.setdefault('parm_v', []).extend( [float_func(f) for f in line_split] ) + # else: # may want to support other parm's ? + + elif line.startswith('deg '): + context_nurbs['deg']= [int(i) for i in line.split()[1:]] + elif line.startswith('end'): + # Add the nurbs curve + if context_object: + context_nurbs['name'] = context_object + nurbs.append(context_nurbs) + context_nurbs = {} + context_parm = '' + + ''' # How to use usemap? depricated? + elif line.startswith('usema'): # usemap or usemat + context_image= line_value(line.split()) + ''' + + file.close() + time_new= sys.time() + print '%.4f sec' % (time_new-time_sub) + time_sub= time_new + + + print '\tloading materials and images...', + create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) + + time_new= sys.time() + print '%.4f sec' % (time_new-time_sub) + time_sub= time_new + + if not ROTATE_X90: + verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] + + # deselect all + scn = bpy.data.scenes.active + scn.objects.selected = [] + new_objects= [] # put new objects here + + print '\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), + # Split the mesh by objects/materials, may + if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True + else: SPLIT_OB_OR_GROUP = False + + for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): + # Create meshes from the data, warning 'vertex_groups' wont support splitting + create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) + + # nurbs support + for context_nurbs in nurbs: + create_nurbs(scn, context_nurbs, verts_loc, new_objects) + + + axis_min= [ 1000000000]*3 + axis_max= [-1000000000]*3 + + if CLAMP_SIZE: + # Get all object bounds + for ob in new_objects: + for v in ob.getBoundBox(): + for axis, value in enumerate(v): + if axis_min[axis] > value: axis_min[axis]= value + if axis_max[axis] < value: axis_max[axis]= value + + # Scale objects + max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2]) + scale= 1.0 + + while CLAMP_SIZE < max_axis * scale: + scale= scale/10.0 + + for ob in new_objects: + ob.setSize(scale, scale, scale) + + # Better rotate the vert locations + #if not ROTATE_X90: + # for ob in new_objects: + # ob.RotX = -1.570796326794896558 + + time_new= sys.time() + + print '%.4f sec' % (time_new-time_sub) + print 'finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)) + + +DEBUG= True + + +def load_obj_ui(filepath, BATCH_LOAD= False): + if BPyMessages.Error_NoFile(filepath): + return + + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 + + CREATE_SMOOTH_GROUPS= Draw.Create(0) + CREATE_FGONS= Draw.Create(1) + CREATE_EDGES= Draw.Create(1) + SPLIT_OBJECTS= Draw.Create(0) + SPLIT_GROUPS= Draw.Create(0) + SPLIT_MATERIALS= Draw.Create(0) + CLAMP_SIZE= Draw.Create(10.0) + IMAGE_SEARCH= Draw.Create(1) + POLYGROUPS= Draw.Create(0) + KEEP_VERT_ORDER= Draw.Create(1) + ROTATE_X90= Draw.Create(1) + + + # Get USER Options + # Note, Works but not pretty, instead use a more complicated GUI + ''' + pup_block= [\ + 'Import...',\ + ('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\ + ('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\ + ('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\ + 'Separate objects from obj...',\ + ('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\ + ('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\ + ('Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)'),\ + 'Options...',\ + ('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ + ('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\ + ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\ + ] + + if not Draw.PupBlock('Import OBJ...', pup_block): + return + + if KEEP_VERT_ORDER.val: + SPLIT_OBJECTS.val = False + SPLIT_GROUPS.val = False + SPLIT_MATERIALS.val = False + ''' + + + + # BEGIN ALTERNATIVE UI ******************* + if True: + + EVENT_NONE = 0 + EVENT_EXIT = 1 + EVENT_REDRAW = 2 + EVENT_IMPORT = 3 + + GLOBALS = {} + GLOBALS['EVENT'] = EVENT_REDRAW + #GLOBALS['MOUSE'] = Window.GetMouseCoords() + GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] + + def obj_ui_set_event(e,v): + GLOBALS['EVENT'] = e + + def do_split(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS + if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val: + KEEP_VERT_ORDER.val = 0 + POLYGROUPS.val = 0 + else: + KEEP_VERT_ORDER.val = 1 + + def do_vertorder(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER + if KEEP_VERT_ORDER.val: + SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 + else: + if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val): + KEEP_VERT_ORDER.val = 1 + + def do_polygroups(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS + if POLYGROUPS.val: + SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 + + def do_help(e,v): + url = __url__[0] + print 'Trying to open web browser with documentation at this address...' + print '\t' + url + + try: + import webbrowser + webbrowser.open(url) + except: + print '...could not open a browser window.' + + def obj_ui(): + ui_x, ui_y = GLOBALS['MOUSE'] + + # Center based on overall pup size + ui_x -= 165 + ui_y -= 90 + + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 + + Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21) + Draw.BeginAlign() + CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges') + CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons') + CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges') + Draw.EndAlign() + + Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20) + Draw.BeginAlign() + SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split) + SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split) + SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+119, ui_y+89, 60, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split) + Draw.EndAlign() + + # Only used for user feedback + KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) + + ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.') + + Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20) + CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') + POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups) + IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)') + Draw.BeginAlign() + Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help) + Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event) + Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event) + Draw.EndAlign() + + + # hack so the toggle buttons redraw. this is not nice at all + while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT): + Draw.UIBlock(obj_ui, 0) + + if GLOBALS['EVENT'] != EVENT_IMPORT: + return + + # END ALTERNATIVE UI ********************* + + + + + + + + Window.WaitCursor(1) + + if BATCH_LOAD: # load the dir + try: + files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ] + except: + Window.WaitCursor(0) + Draw.PupMenu('Error%t|Could not open path ' + filepath) + return + + if not files: + Window.WaitCursor(0) + Draw.PupMenu('Error%t|No files at path ' + filepath) + return + + for f in files: + scn= bpy.data.scenes.new( stripExt(f) ) + scn.makeCurrent() + + load_obj(sys.join(filepath, f),\ + CLAMP_SIZE.val,\ + CREATE_FGONS.val,\ + CREATE_SMOOTH_GROUPS.val,\ + CREATE_EDGES.val,\ + SPLIT_OBJECTS.val,\ + SPLIT_GROUPS.val,\ + SPLIT_MATERIALS.val,\ + ROTATE_X90.val,\ + IMAGE_SEARCH.val,\ + POLYGROUPS.val + ) + + else: # Normal load + load_obj(filepath,\ + CLAMP_SIZE.val,\ + CREATE_FGONS.val,\ + CREATE_SMOOTH_GROUPS.val,\ + CREATE_EDGES.val,\ + SPLIT_OBJECTS.val,\ + SPLIT_GROUPS.val,\ + SPLIT_MATERIALS.val,\ + ROTATE_X90.val,\ + IMAGE_SEARCH.val,\ + POLYGROUPS.val + ) + + Window.WaitCursor(0) + + +def load_obj_ui_batch(file): + load_obj_ui(file, True) + +DEBUG= False + +if __name__=='__main__' and not DEBUG: + if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT: + Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '') + else: + Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') + + # For testing compatibility +''' +else: + # DEBUG ONLY + TIME= sys.time() + DIR = '/fe/obj' + import os + print 'Searching for files' + def fileList(path): + for dirpath, dirnames, filenames in os.walk(path): + for filename in filenames: + yield os.path.join(dirpath, filename) + + files = [f for f in fileList(DIR) if f.lower().endswith('.obj')] + files.sort() + + for i, obj_file in enumerate(files): + if 0 < i < 20: + print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files) + newScn= bpy.data.scenes.new(os.path.basename(obj_file)) + newScn.makeCurrent() + load_obj(obj_file, False, IMAGE_SEARCH=0) + + print 'TOTAL TIME: %.6f' % (sys.time() - TIME) +''' +#load_obj('/test.obj') +#load_obj('/fe/obj/mba1.obj') + +# NOTES (all line numbers refer to 2.4x import_obj.py, not this file) +# check later: line 489 +# edge flags, edges, normals: lines 508-528 +# vertex groups: line 533 - cannot assign vertex groups diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 00d5bacfef0..ecc32b23249 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -232,6 +232,12 @@ static void rna_Mesh_add_faces(Mesh *mesh, int len) mesh->totface= totface; } +/* +static void rna_Mesh_add_faces(Mesh *mesh) +{ +} +*/ + static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces) { if(verts) @@ -242,6 +248,11 @@ static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces) rna_Mesh_add_faces(mesh, faces); } +static void rna_Mesh_add_uv_layer(Mesh *me) +{ + me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface); +} + #else void RNA_api_mesh(StructRNA *srna) @@ -267,6 +278,9 @@ void RNA_api_mesh(StructRNA *srna) parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh, remove it if it is only used for export."); RNA_def_function_return(func, parm); + func= RNA_def_function(srna, "add_uv_layer", "rna_Mesh_add_uv_layer"); + RNA_def_function_ui_description(func, "Add new UV layer to Mesh."); + /* func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom"); RNA_def_function_ui_description(func, "Add geometry data to mesh."); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 4166eb9bc2c..e046f2ff73d 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -384,6 +384,7 @@ static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values) } } +/* static PointerRNA rna_DupliObject_object_get(PointerRNA *ptr) { DupliObject *dob= (DupliObject*)ptr->data; @@ -391,6 +392,7 @@ static PointerRNA rna_DupliObject_object_get(PointerRNA *ptr) RNA_pointer_create(&dob->ob->id, &RNA_Object, dob->ob, &newptr); return newptr; } +*/ #else @@ -1207,9 +1209,9 @@ static void rna_def_dupli_object(BlenderRNA *brna) /* RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA); */ prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "Object"); + /* RNA_def_property_struct_type(prop, "Object"); */ RNA_def_property_pointer_sdna(prop, NULL, "ob"); - RNA_def_property_pointer_funcs(prop, "rna_DupliObject_object_get", NULL, NULL); + /* RNA_def_property_pointer_funcs(prop, "rna_DupliObject_object_get", NULL, NULL); */ RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Object", "Object this DupliObject represents."); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index b09acb51084..9d1a6a39d51 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -36,6 +36,10 @@ #include "DNA_object_types.h" +#include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */ + +#include "ED_mesh.h" + /* parameter to rna_Object_create_mesh */ typedef enum CreateMeshType { CREATE_MESH_PREVIEW = 0, @@ -56,10 +60,6 @@ typedef enum CreateMeshType { #include "BLI_arithb.h" -#include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */ - -#include "ED_mesh.h" - /* copied from init_render_mesh (render code) */ static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports, int type) { @@ -108,7 +108,7 @@ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *rep /* free duplilist if a user forgets to */ if (ob->duplilist) { - BKE_reportf(reports, RPT_WARNING, "%s.dupli_list has not been freed.", RNA_struct_identifier(&RNA_Object)); + BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed."); free_object_duplilist(ob->duplilist); ob->duplilist= NULL; @@ -155,6 +155,47 @@ static void rna_Object_convert_to_triface(Object *ob, bContext *C, ReportList *r DAG_object_flush_update(sce, ob, OB_RECALC_DATA); } +static int rna_Object_add_vertex_group(Object *ob, char *group_name) +{ + bDeformGroup *defgroup= add_defgroup_name(ob, group_name); + return BLI_findindex(&ob->defbase, defgroup); +} + +/* +static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int *indices, int totindex, float weight, int assignmode) +{ + if (ob->type != OB_MESH) { + BKE_report(reports, RPT_ERROR, "Object should be of MESH type."); + return; + } + + Mesh *me = (Mesh*)ob->data; + int group_index = get_defgroup_num(ob, group); + if (group_index == -1) { + BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh."); + return; + } + + if (assignmode != WEIGHT_REPLACE && assignmode != WEIGHT_ADD && assignmode != WEIGHT_SUBTRACT) { + BKE_report(reports, RPT_ERROR, "Bad assignment mode." ); + return; + } + + // makes a set of dVerts corresponding to the mVerts + if (!me->dvert) + create_dverts(&me->id); + + // loop list adding verts to group + for (i= 0; i < totindex; i++) { + if(i < 0 || i >= me->totvert) { + BKE_report(reports, RPT_ERROR, "Bad vertex index in list."); + return; + } + + add_vert_defnr(ob, group_index, i, weight, assignmode); + } +} +*/ #else @@ -190,6 +231,12 @@ void RNA_api_object(StructRNA *srna) RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object belongs."); RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "add_vertex_group", "rna_Object_add_vertex_group"); + RNA_def_function_ui_description(func, "Add vertex group to object."); + parm= RNA_def_string(func, "name", "Group", 0, "", "Vertex group name."); + parm= RNA_def_int(func, "group_index", 0, 0, 0, "", "Index of the created vertex group.", 0, 0); + RNA_def_function_return(func, parm); } #endif -- cgit v1.2.3 From b14298f959180762c3bbf31d42a747e55ca48494 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 2 Jul 2009 11:28:42 +0000 Subject: svn merge -r 21041:21301 https://svn.blender.org/svnroot/bf-blender/branches/blender2.5/blender --- CMake/macros.cmake | 2 +- CMakeLists.txt | 51 +- SConstruct | 2 - config/darwin-config.py | 9 - config/irix6-config.py | 9 - config/linux2-config.py | 9 - config/linuxcross-config.py | 9 - config/openbsd3-config.py | 9 - config/sunos5-config.py | 9 - config/win32-mingw-config.py | 9 - config/win32-vc-config.py | 9 - config/win64-vc-config.py | 9 - extern/CMakeLists.txt | 5 - extern/Makefile | 2 +- extern/SConscript | 4 - extern/qhull/CMakeLists.txt | 45 - extern/qhull/COPYING.txt | 37 - extern/qhull/README.txt | 318 -- extern/qhull/REGISTER.txt | 37 - extern/qhull/SConscript | 35 - extern/qhull/VisualC6/qhull.dsw | 29 - extern/qhull/VisualC6/qhull/qhull.dsp | 192 - extern/qhull/include/qhull/geom.h | 177 - extern/qhull/include/qhull/io.h | 149 - extern/qhull/include/qhull/mem.h | 174 - extern/qhull/include/qhull/merge.h | 171 - extern/qhull/include/qhull/poly.h | 290 -- extern/qhull/include/qhull/qhull.h | 1048 ----- extern/qhull/include/qhull/qhull_a.h | 127 - extern/qhull/include/qhull/qset.h | 468 --- extern/qhull/include/qhull/stat.h | 520 --- extern/qhull/include/qhull/user.h | 762 ---- extern/qhull/make/msvc_7_0/qhull.vcproj | 677 ---- extern/qhull/make/msvc_9_0/qhull.vcproj | 877 ----- extern/qhull/src/Make-config.sh | 285 -- extern/qhull/src/Makefile | 55 - extern/qhull/src/Makefile.txt | 190 - extern/qhull/src/geom.c | 1230 ------ extern/qhull/src/geom.h | 177 - extern/qhull/src/geom2.c | 2160 ----------- extern/qhull/src/global.c | 2018 ---------- extern/qhull/src/io.c | 4089 -------------------- extern/qhull/src/io.h | 149 - extern/qhull/src/mem.c | 447 --- extern/qhull/src/mem.h | 174 - extern/qhull/src/merge.c | 3626 ----------------- extern/qhull/src/merge.h | 171 - extern/qhull/src/poly.c | 1180 ------ extern/qhull/src/poly.h | 290 -- extern/qhull/src/poly2.c | 3070 --------------- extern/qhull/src/qconvex.c | 334 -- extern/qhull/src/qdelaun.c | 323 -- extern/qhull/src/qhalf.c | 324 -- extern/qhull/src/qhull.c | 1395 ------- extern/qhull/src/qhull.h | 1048 ----- extern/qhull/src/qhull_a.h | 127 - extern/qhull/src/qhull_interface.cpp | 96 - extern/qhull/src/qset.c | 1301 ------- extern/qhull/src/qset.h | 468 --- extern/qhull/src/qvoronoi.c | 318 -- extern/qhull/src/rbox.c | 788 ---- extern/qhull/src/stat.c | 700 ---- extern/qhull/src/stat.h | 520 --- extern/qhull/src/unix.c | 376 -- extern/qhull/src/user.c | 324 -- extern/qhull/src/user.h | 762 ---- extern/qhull/src/user_eg.c | 310 -- extern/qhull/src/user_eg2.c | 532 --- extern/solid/CMakeLists.txt | 34 - extern/solid/LICENSE_GPL.txt | 349 -- extern/solid/LICENSE_QPL.txt | 110 - extern/solid/Makefile | 56 - extern/solid/README.txt | 55 - extern/solid/SConscript | 34 - extern/solid/SOLID/SOLID.h | 279 -- extern/solid/SOLID/SOLID_broad.h | 75 - extern/solid/SOLID/SOLID_types.h | 53 - extern/solid/VisualC6/broad/broad.dsp | 132 - extern/solid/VisualC6/complex/complex.dsp | 116 - extern/solid/VisualC6/convex/convex.dsp | 232 -- extern/solid/VisualC6/dynamics/dynamics.dsp | 120 - extern/solid/VisualC6/gldemo/gldemo.dsp | 102 - extern/solid/VisualC6/mnm/mnm.dsp | 100 - extern/solid/VisualC6/physics/physics.dsp | 100 - extern/solid/VisualC6/sample/sample.dsp | 102 - extern/solid/VisualC6/solid.dsw | 89 - extern/solid/VisualC6/solid/solid.dsp | 148 - extern/solid/VisualC6/solid_dll/solid_dll.dsp | 147 - extern/solid/include/GEN_MinMax.h | 76 - extern/solid/include/GEN_random.h | 49 - extern/solid/include/MT/Interval.h | 180 - extern/solid/include/MT/Matrix3x3.h | 380 -- extern/solid/include/MT/Quaternion.h | 316 -- extern/solid/include/MT/Transform.h | 189 - extern/solid/include/MT/Tuple3.h | 120 - extern/solid/include/MT/Tuple4.h | 112 - extern/solid/include/MT/Vector3.h | 283 -- extern/solid/include/MT_BBox.h | 119 - extern/solid/include/MT_Interval.h | 33 - extern/solid/include/MT_Matrix3x3.h | 34 - extern/solid/include/MT_Point3.h | 31 - extern/solid/include/MT_Quaternion.h | 35 - extern/solid/include/MT_Scalar.h | 158 - extern/solid/include/MT_Transform.h | 38 - extern/solid/include/MT_Vector3.h | 50 - extern/solid/include/SOLID.h | 279 -- extern/solid/include/SOLID_broad.h | 75 - extern/solid/include/SOLID_types.h | 53 - extern/solid/make/msvc_7_0/broad/broad.vcproj | 262 -- extern/solid/make/msvc_7_0/complex/complex.vcproj | 252 -- extern/solid/make/msvc_7_0/convex/convex.vcproj | 337 -- extern/solid/make/msvc_7_0/solid.vcproj | 462 --- extern/solid/make/msvc_9_0/broad/broad.vcproj | 369 -- extern/solid/make/msvc_9_0/complex/complex.vcproj | 355 -- extern/solid/make/msvc_9_0/convex/convex.vcproj | 469 --- extern/solid/make/msvc_9_0/solid.vcproj | 595 --- extern/solid/src/DT_AlgoTable.h | 47 - extern/solid/src/DT_C-api.cpp | 581 --- extern/solid/src/DT_Encounter.cpp | 111 - extern/solid/src/DT_Encounter.h | 84 - extern/solid/src/DT_Object.cpp | 276 -- extern/solid/src/DT_Object.h | 157 - extern/solid/src/DT_RespTable.cpp | 184 - extern/solid/src/DT_RespTable.h | 139 - extern/solid/src/DT_Response.h | 63 - extern/solid/src/DT_Scene.cpp | 183 - extern/solid/src/DT_Scene.h | 57 - extern/solid/src/Makefile | 45 - extern/solid/src/broad/BP_C-api.cpp | 77 - extern/solid/src/broad/BP_Endpoint.h | 108 - extern/solid/src/broad/BP_EndpointList.cpp | 237 -- extern/solid/src/broad/BP_EndpointList.h | 109 - extern/solid/src/broad/BP_Proxy.cpp | 120 - extern/solid/src/broad/BP_Proxy.h | 78 - extern/solid/src/broad/BP_ProxyList.h | 69 - extern/solid/src/broad/BP_Scene.cpp | 151 - extern/solid/src/broad/BP_Scene.h | 79 - extern/solid/src/broad/Makefile | 41 - extern/solid/src/complex/DT_BBoxTree.cpp | 90 - extern/solid/src/complex/DT_BBoxTree.h | 540 --- extern/solid/src/complex/DT_CBox.h | 134 - extern/solid/src/complex/DT_Complex.cpp | 327 -- extern/solid/src/complex/DT_Complex.h | 94 - extern/solid/src/complex/Makefile | 42 - extern/solid/src/convex/DT_Accuracy.cpp | 30 - extern/solid/src/convex/DT_Accuracy.h | 47 - extern/solid/src/convex/DT_Array.h | 75 - extern/solid/src/convex/DT_Box.cpp | 112 - extern/solid/src/convex/DT_Box.h | 62 - extern/solid/src/convex/DT_Cone.cpp | 48 - extern/solid/src/convex/DT_Cone.h | 45 - extern/solid/src/convex/DT_Convex.cpp | 426 -- extern/solid/src/convex/DT_Convex.h | 64 - extern/solid/src/convex/DT_Cylinder.cpp | 39 - extern/solid/src/convex/DT_Cylinder.h | 42 - extern/solid/src/convex/DT_Facet.cpp | 80 - extern/solid/src/convex/DT_Facet.h | 134 - extern/solid/src/convex/DT_GJK.h | 438 --- extern/solid/src/convex/DT_Hull.h | 53 - extern/solid/src/convex/DT_IndexArray.h | 33 - extern/solid/src/convex/DT_LineSegment.cpp | 36 - extern/solid/src/convex/DT_LineSegment.h | 52 - extern/solid/src/convex/DT_Minkowski.h | 51 - extern/solid/src/convex/DT_PenDepth.cpp | 376 -- extern/solid/src/convex/DT_PenDepth.h | 36 - extern/solid/src/convex/DT_Point.cpp | 36 - extern/solid/src/convex/DT_Point.h | 46 - extern/solid/src/convex/DT_Polyhedron.cpp | 415 -- extern/solid/src/convex/DT_Polyhedron.h | 76 - extern/solid/src/convex/DT_Polytope.cpp | 69 - extern/solid/src/convex/DT_Polytope.h | 51 - extern/solid/src/convex/DT_Shape.h | 72 - extern/solid/src/convex/DT_Sphere.cpp | 90 - extern/solid/src/convex/DT_Sphere.h | 43 - extern/solid/src/convex/DT_Transform.h | 53 - extern/solid/src/convex/DT_Triangle.cpp | 96 - extern/solid/src/convex/DT_Triangle.h | 63 - extern/solid/src/convex/DT_VertexBase.h | 84 - extern/solid/src/convex/Makefile | 41 - intern/bsp/test/Makefile | 2 +- intern/guardedalloc/intern/mallocn.c | 12 +- intern/iksolver/test/Makefile | 2 +- intern/moto/include/MT_Matrix3x3.h | 24 + intern/string/intern/STR_String.cpp | 6 +- .../blender/BPY_python/BPY_python.vcproj | 44 +- projectfiles_vc9/blender/blender.sln | 146 - projectfiles_vc9/blender/blender.vcproj | 12 +- .../blender/blenkernel/BKE_blenkernel.vcproj | 12 +- .../blender/blenlib/BLI_blenlib.vcproj | 2 +- projectfiles_vc9/blender/editors/ED_editors.vcproj | 44 +- .../blender/makesrna/RNA_makesrna.vcproj | 30 +- projectfiles_vc9/blender/makesrna/RNA_rna.vcproj | 10 +- projectfiles_vc9/blender/nodes/nodes.vcproj | 8 +- .../gameengine/blenderhook/KX_blenderhook.vcproj | 4 +- .../gameengine/converter/KX_converter.vcproj | 12 +- .../gameengine/expression/EXP_expressions.vcproj | 12 +- .../gameengine/gamelogic/SCA_GameLogic.vcproj | 12 +- .../gameengine/gameplayer/axctl/GP_axctl.vcproj | 4 +- .../gameengine/gameplayer/common/GP_common.vcproj | 8 +- .../gameengine/gameplayer/ghost/GP_ghost.vcproj | 4 +- .../gameengine/ketsji/KX_ketsji.vcproj | 20 +- .../gameengine/ketsji/network/KX_network.vcproj | 12 +- .../PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj | 12 +- .../gameengine/rasterizer/RAS_rasterizer.vcproj | 12 +- .../gameengine/videotexture/TEX_Video.vcproj | 4 +- projectfiles_vc9/kernel/system/SYS_system.vcproj | 4 +- release/ui/buttons_data_armature.py | 4 +- release/ui/buttons_data_camera.py | 4 +- release/ui/buttons_data_curve.py | 4 +- release/ui/buttons_data_lamp.py | 4 +- release/ui/buttons_data_lattice.py | 4 +- release/ui/buttons_data_mesh.py | 143 +- release/ui/buttons_data_modifier.py | 169 +- release/ui/buttons_data_text.py | 4 +- release/ui/buttons_material.py | 4 +- release/ui/buttons_object_constraint.py | 27 +- release/ui/buttons_particle.py | 174 +- release/ui/buttons_physic_cloth.py | 48 + release/ui/buttons_texture.py | 4 +- release/ui/buttons_world.py | 4 +- release/ui/space_buttons.py | 36 + release/ui/space_filebrowser.py | 65 + release/ui/space_image.py | 619 +-- release/ui/space_info.py | 119 + release/ui/space_logic.py | 8 + release/ui/space_outliner.py | 4 +- release/ui/space_sequencer.py | 14 +- release/ui/space_text.py | 22 +- source/Makefile | 11 - source/blender/CMakeLists.txt | 1 - source/blender/Makefile | 2 +- source/blender/SConscript | 1 - source/blender/blenfont/BLF_api.h | 17 + source/blender/blenfont/intern/blf.c | 25 + source/blender/blenfont/intern/blf_dir.c | 2 +- source/blender/blenfont/intern/blf_font.c | 36 +- source/blender/blenfont/intern/blf_glyph.c | 33 + source/blender/blenfont/intern/blf_internal.h | 2 +- .../blender/blenfont/intern/blf_internal_types.h | 12 +- source/blender/blenfont/intern/blf_lang.c | 2 +- source/blender/blenkernel/BKE_cloth.h | 5 +- source/blender/blenkernel/BKE_context.h | 3 +- source/blender/blenkernel/BKE_exotic.h | 1 - source/blender/blenkernel/BKE_gpencil.h | 2 +- source/blender/blenkernel/BKE_material.h | 15 +- source/blender/blenkernel/BKE_packedFile.h | 54 +- source/blender/blenkernel/BKE_particle.h | 7 + source/blender/blenkernel/BKE_pointcache.h | 57 +- source/blender/blenkernel/BKE_report.h | 7 +- source/blender/blenkernel/BKE_sequence.h | 2 +- source/blender/blenkernel/BKE_utildefines.h | 8 +- source/blender/blenkernel/intern/anim_sys.c | 4 + source/blender/blenkernel/intern/blender.c | 1 - source/blender/blenkernel/intern/cdderivedmesh.c | 2 +- source/blender/blenkernel/intern/cloth.c | 164 +- source/blender/blenkernel/intern/constraint.c | 8 +- source/blender/blenkernel/intern/context.c | 24 +- source/blender/blenkernel/intern/depsgraph.c | 20 +- source/blender/blenkernel/intern/displist.c | 36 +- source/blender/blenkernel/intern/effect.c | 2 + source/blender/blenkernel/intern/exotic.c | 594 +-- source/blender/blenkernel/intern/fluidsim.c | 2 + source/blender/blenkernel/intern/font.c | 8 +- source/blender/blenkernel/intern/gpencil.c | 2 +- source/blender/blenkernel/intern/idprop.c | 8 +- source/blender/blenkernel/intern/image.c | 6 +- source/blender/blenkernel/intern/implicit.c | 10 +- source/blender/blenkernel/intern/material.c | 4 +- source/blender/blenkernel/intern/modifier.c | 29 +- source/blender/blenkernel/intern/multires.c | 6 +- source/blender/blenkernel/intern/packedFile.c | 227 +- source/blender/blenkernel/intern/particle.c | 99 +- source/blender/blenkernel/intern/particle_system.c | 200 +- source/blender/blenkernel/intern/pointcache.c | 896 ++++- source/blender/blenkernel/intern/report.c | 6 +- source/blender/blenkernel/intern/scene.c | 9 +- source/blender/blenkernel/intern/sequence.c | 2 +- source/blender/blenlib/BLI_listbase.h | 4 +- source/blender/blenlib/BLI_noise.h | 2 +- source/blender/blenlib/BLI_rect.h | 2 +- source/blender/blenlib/BLI_storage.h | 7 +- source/blender/blenlib/BLI_string.h | 4 +- source/blender/blenlib/BLI_util.h | 1 + source/blender/blenlib/intern/dynamiclist.c | 2 +- source/blender/blenlib/intern/dynamiclist.h | 2 +- source/blender/blenlib/intern/listbase.c | 2 +- source/blender/blenlib/intern/psfont.c | 4 +- source/blender/blenlib/intern/storage.c | 54 +- source/blender/blenlib/intern/string.c | 2 +- source/blender/blenlib/intern/util.c | 24 +- source/blender/blenloader/intern/readblenentry.c | 2 + source/blender/blenloader/intern/readfile.c | 148 +- source/blender/blenloader/intern/writefile.c | 28 +- source/blender/blenpluginapi/intern/Makefile | 4 - source/blender/editors/animation/Makefile | 2 +- source/blender/editors/animation/anim_channels.c | 2 +- source/blender/editors/animation/keyframes_draw.c | 2 +- source/blender/editors/armature/BIF_generate.h | 2 +- source/blender/editors/armature/BIF_retarget.h | 2 +- source/blender/editors/armature/Makefile | 2 +- .../editors/armature/editarmature_generate.c | 2 +- .../blender/editors/armature/editarmature_sketch.c | 107 +- source/blender/editors/armature/meshlaplacian.c | 2 +- source/blender/editors/armature/meshlaplacian.h | 2 +- source/blender/editors/curve/Makefile | 2 +- source/blender/editors/curve/curve_intern.h | 1 - source/blender/editors/curve/curve_ops.c | 1 - source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/curve/editfont.c | 44 - source/blender/editors/datafiles/Bfont.c | 2 +- source/blender/editors/datafiles/Makefile | 2 +- source/blender/editors/gpencil/Makefile | 2 +- source/blender/editors/gpencil/gpencil_edit.c | 2 +- source/blender/editors/include/BIF_gl.h | 2 +- source/blender/editors/include/ED_curve.h | 3 + source/blender/editors/include/ED_datafiles.h | 2 +- source/blender/editors/include/ED_fileselect.h | 32 +- source/blender/editors/include/ED_fluidsim.h | 2 +- source/blender/editors/include/ED_keyframes_draw.h | 2 +- source/blender/editors/include/ED_keyframing.h | 6 +- source/blender/editors/include/ED_mesh.h | 7 +- source/blender/editors/include/ED_object.h | 1 + source/blender/editors/include/ED_particle.h | 2 +- source/blender/editors/include/ED_pointcache.h | 38 + source/blender/editors/include/ED_previewrender.h | 6 +- source/blender/editors/include/ED_view3d.h | 2 + source/blender/editors/include/UI_icons.h | 4 +- source/blender/editors/include/UI_interface.h | 17 +- source/blender/editors/include/UI_resources.h | 2 +- source/blender/editors/interface/Makefile | 2 +- source/blender/editors/interface/interface.c | 137 +- source/blender/editors/interface/interface_draw.c | 2 +- .../blender/editors/interface/interface_handlers.c | 141 +- source/blender/editors/interface/interface_icons.c | 101 +- .../blender/editors/interface/interface_intern.h | 25 +- .../blender/editors/interface/interface_layout.c | 180 +- source/blender/editors/interface/interface_panel.c | 9 +- .../blender/editors/interface/interface_regions.c | 213 +- source/blender/editors/interface/interface_style.c | 38 +- .../editors/interface/interface_templates.c | 505 ++- source/blender/editors/interface/interface_utils.c | 88 +- .../blender/editors/interface/interface_widgets.c | 136 +- source/blender/editors/interface/resources.c | 2 +- source/blender/editors/interface/view2d.c | 8 +- source/blender/editors/mesh/Makefile | 2 +- source/blender/editors/mesh/editdeform.c | 1110 ------ source/blender/editors/mesh/editmesh.c | 4 +- source/blender/editors/mesh/editmesh_add.c | 4 +- source/blender/editors/mesh/editmesh_mods.c | 8 +- source/blender/editors/mesh/editmesh_tools.c | 6 +- source/blender/editors/mesh/mesh_intern.h | 9 + source/blender/editors/mesh/mesh_layers.c | 424 ++ source/blender/editors/mesh/mesh_ops.c | 6 + source/blender/editors/object/Makefile | 2 +- source/blender/editors/object/editkey.c | 144 +- source/blender/editors/object/object_edit.c | 27 +- source/blender/editors/object/object_intern.h | 14 + source/blender/editors/object/object_modifier.c | 2 +- source/blender/editors/object/object_ops.c | 12 + source/blender/editors/object/object_vgroup.c | 1344 +++++++ source/blender/editors/physics/Makefile | 2 +- source/blender/editors/physics/ed_pointcache.c | 382 ++ source/blender/editors/physics/editparticle.c | 34 +- source/blender/editors/physics/physics_intern.h | 2 +- source/blender/editors/preview/Makefile | 2 +- source/blender/editors/preview/previewrender.c | 256 +- source/blender/editors/screen/Makefile | 2 +- source/blender/editors/screen/area.c | 16 +- source/blender/editors/screen/glutil.c | 2 +- source/blender/editors/screen/screen_ops.c | 5 +- source/blender/editors/sculpt_paint/Makefile | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 899 +---- .../blender/editors/sculpt_paint/sculpt_intern.h | 2 +- .../blender/editors/sculpt_paint/sculpt_stroke.c | 2 +- source/blender/editors/space_action/Makefile | 2 +- source/blender/editors/space_action/action_draw.c | 2 +- source/blender/editors/space_action/action_edit.c | 2 +- .../blender/editors/space_action/action_select.c | 2 +- source/blender/editors/space_api/Makefile | 2 +- source/blender/editors/space_api/spacetypes.c | 2 + source/blender/editors/space_buttons/Makefile | 2 +- source/blender/editors/space_buttons/SConscript | 3 - .../editors/space_buttons/buttons_context.c | 9 +- .../blender/editors/space_buttons/buttons_header.c | 6 +- .../blender/editors/space_buttons/buttons_intern.h | 11 + source/blender/editors/space_buttons/buttons_ops.c | 368 +- .../blender/editors/space_buttons/space_buttons.c | 30 +- source/blender/editors/space_file/Makefile | 2 +- source/blender/editors/space_file/file_draw.c | 77 - source/blender/editors/space_file/file_header.c | 2 +- source/blender/editors/space_file/file_intern.h | 12 +- source/blender/editors/space_file/file_ops.c | 212 +- source/blender/editors/space_file/file_panels.c | 165 + source/blender/editors/space_file/filelist.c | 8 +- source/blender/editors/space_file/filelist.h | 1 - source/blender/editors/space_file/filesel.c | 4 +- source/blender/editors/space_file/fsmenu.c | 39 +- source/blender/editors/space_file/fsmenu.h | 13 +- source/blender/editors/space_file/space_file.c | 126 +- source/blender/editors/space_graph/Makefile | 2 +- source/blender/editors/space_graph/graph_draw.c | 2 +- source/blender/editors/space_graph/graph_edit.c | 2 +- source/blender/editors/space_graph/graph_select.c | 2 +- source/blender/editors/space_image/Makefile | 2 +- source/blender/editors/space_image/image_buttons.c | 48 +- source/blender/editors/space_image/image_draw.c | 28 +- source/blender/editors/space_image/image_header.c | 14 +- source/blender/editors/space_image/image_ops.c | 148 +- source/blender/editors/space_image/space_image.c | 8 +- source/blender/editors/space_info/Makefile | 2 +- source/blender/editors/space_info/SConscript | 3 - source/blender/editors/space_info/info_header.c | 507 --- source/blender/editors/space_info/info_intern.h | 7 + source/blender/editors/space_info/info_ops.c | 397 ++ source/blender/editors/space_info/space_info.c | 28 +- source/blender/editors/space_logic/Makefile | 2 +- source/blender/editors/space_logic/SConscript | 3 - source/blender/editors/space_logic/logic_buttons.c | 2 +- source/blender/editors/space_logic/logic_header.c | 2 +- source/blender/editors/space_logic/logic_window.c | 102 +- source/blender/editors/space_nla/Makefile | 2 +- source/blender/editors/space_nla/nla_header.c | 2 +- source/blender/editors/space_node/Makefile | 2 +- source/blender/editors/space_node/node_draw.c | 2 +- source/blender/editors/space_node/node_header.c | 2 +- source/blender/editors/space_outliner/Makefile | 2 +- source/blender/editors/space_outliner/outliner.c | 19 +- .../editors/space_outliner/outliner_header.c | 2 +- .../editors/space_outliner/space_outliner.c | 2 +- source/blender/editors/space_script/Makefile | 2 +- .../blender/editors/space_script/script_header.c | 2 +- source/blender/editors/space_sequencer/Makefile | 2 +- .../editors/space_sequencer/sequencer_buttons.c | 2 +- source/blender/editors/space_sound/Makefile | 2 +- source/blender/editors/space_sound/sound_header.c | 2 +- source/blender/editors/space_text/Makefile | 2 +- source/blender/editors/space_text/text_header.c | 4 +- source/blender/editors/space_text/text_python.c | 2 +- source/blender/editors/space_time/Makefile | 2 +- source/blender/editors/space_time/space_time.c | 2 +- source/blender/editors/space_time/time_header.c | 6 +- source/blender/editors/space_view3d/Makefile | 2 +- source/blender/editors/space_view3d/drawobject.c | 58 +- source/blender/editors/space_view3d/space_view3d.c | 18 + .../blender/editors/space_view3d/view3d_buttons.c | 4 +- .../blender/editors/space_view3d/view3d_header.c | 127 +- .../blender/editors/space_view3d/view3d_select.c | 21 +- .../blender/editors/space_view3d/view3d_toolbar.c | 125 +- source/blender/editors/space_view3d/view3d_view.c | 6 +- source/blender/editors/transform/Makefile | 2 +- source/blender/editors/transform/transform.c | 14 +- source/blender/editors/transform/transform.h | 1 + .../editors/transform/transform_conversions.c | 18 +- .../blender/editors/transform/transform_generics.c | 15 +- source/blender/editors/transform/transform_input.c | 3 +- .../editors/transform/transform_ndofinput.c | 1 + .../blender/editors/transform/transform_numinput.c | 1 + source/blender/editors/transform/transform_ops.c | 2 +- source/blender/editors/transform/transform_snap.c | 19 +- source/blender/editors/util/Makefile | 2 +- source/blender/editors/util/undo.c | 2 + source/blender/editors/uvedit/Makefile | 2 +- source/blender/editors/uvedit/uvedit_draw.c | 22 +- source/blender/editors/uvedit/uvedit_ops.c | 112 +- source/blender/gpu/intern/Makefile | 2 +- source/blender/imbuf/intern/imbuf.h | 2 +- source/blender/imbuf/intern/readimage.c | 21 - source/blender/makesdna/DNA_brush_types.h | 1 + source/blender/makesdna/DNA_object_force.h | 22 + source/blender/makesdna/DNA_particle_types.h | 6 +- source/blender/makesdna/DNA_radio_types.h | 62 - source/blender/makesdna/DNA_scene_types.h | 69 +- source/blender/makesdna/DNA_screen_types.h | 4 + source/blender/makesdna/DNA_space_types.h | 50 +- source/blender/makesdna/DNA_userdef_types.h | 10 +- source/blender/makesdna/DNA_windowmanager_types.h | 34 +- source/blender/makesdna/intern/makesdna.c | 2 - source/blender/makesrna/Makefile | 2 +- source/blender/makesrna/RNA_access.h | 40 +- source/blender/makesrna/RNA_define.h | 4 +- source/blender/makesrna/RNA_enum_types.h | 5 +- source/blender/makesrna/RNA_types.h | 21 +- source/blender/makesrna/intern/Makefile | 2 +- source/blender/makesrna/intern/makesrna.c | 105 +- source/blender/makesrna/intern/rna_ID.c | 2 +- source/blender/makesrna/intern/rna_access.c | 500 ++- source/blender/makesrna/intern/rna_action.c | 2 +- source/blender/makesrna/intern/rna_actuator.c | 2 +- source/blender/makesrna/intern/rna_animation.c | 2 +- source/blender/makesrna/intern/rna_armature.c | 27 +- source/blender/makesrna/intern/rna_brush.c | 6 +- source/blender/makesrna/intern/rna_camera.c | 2 +- source/blender/makesrna/intern/rna_cloth.c | 45 +- source/blender/makesrna/intern/rna_color.c | 2 +- source/blender/makesrna/intern/rna_constraint.c | 15 +- source/blender/makesrna/intern/rna_context.c | 22 +- source/blender/makesrna/intern/rna_controller.c | 2 +- source/blender/makesrna/intern/rna_curve.c | 2 +- source/blender/makesrna/intern/rna_define.c | 17 +- source/blender/makesrna/intern/rna_fcurve.c | 2 +- source/blender/makesrna/intern/rna_fluidsim.c | 2 +- source/blender/makesrna/intern/rna_group.c | 2 +- source/blender/makesrna/intern/rna_image.c | 47 +- source/blender/makesrna/intern/rna_internal.h | 4 +- .../blender/makesrna/intern/rna_internal_types.h | 6 +- source/blender/makesrna/intern/rna_key.c | 2 +- source/blender/makesrna/intern/rna_lamp.c | 12 +- source/blender/makesrna/intern/rna_lattice.c | 2 +- source/blender/makesrna/intern/rna_main.c | 4 +- source/blender/makesrna/intern/rna_main_api.c | 2 +- source/blender/makesrna/intern/rna_material.c | 2 +- source/blender/makesrna/intern/rna_mesh.c | 261 +- source/blender/makesrna/intern/rna_mesh_api.c | 219 +- source/blender/makesrna/intern/rna_meta.c | 2 +- source/blender/makesrna/intern/rna_modifier.c | 60 +- source/blender/makesrna/intern/rna_nodetree.c | 2 +- .../blender/makesrna/intern/rna_nodetree_types.h | 2 +- source/blender/makesrna/intern/rna_object.c | 125 +- source/blender/makesrna/intern/rna_object_api.c | 2 +- source/blender/makesrna/intern/rna_object_force.c | 450 ++- source/blender/makesrna/intern/rna_packedfile.c | 2 +- source/blender/makesrna/intern/rna_particle.c | 132 +- source/blender/makesrna/intern/rna_pose.c | 2 +- source/blender/makesrna/intern/rna_property.c | 2 +- source/blender/makesrna/intern/rna_radio.c | 140 - source/blender/makesrna/intern/rna_rna.c | 18 +- source/blender/makesrna/intern/rna_scene.c | 109 +- source/blender/makesrna/intern/rna_screen.c | 30 +- source/blender/makesrna/intern/rna_scriptlink.c | 2 +- source/blender/makesrna/intern/rna_sensor.c | 2 +- source/blender/makesrna/intern/rna_sequence.c | 2 +- source/blender/makesrna/intern/rna_sound.c | 2 +- source/blender/makesrna/intern/rna_space.c | 203 +- source/blender/makesrna/intern/rna_text.c | 2 +- source/blender/makesrna/intern/rna_texture.c | 2 +- source/blender/makesrna/intern/rna_timeline.c | 2 +- source/blender/makesrna/intern/rna_ui.c | 18 +- source/blender/makesrna/intern/rna_ui_api.c | 42 +- source/blender/makesrna/intern/rna_userdef.c | 24 +- source/blender/makesrna/intern/rna_vfont.c | 2 +- source/blender/makesrna/intern/rna_vpaint.c | 2 +- source/blender/makesrna/intern/rna_wm.c | 250 +- source/blender/makesrna/intern/rna_wm_api.c | 2 +- source/blender/makesrna/intern/rna_world.c | 4 +- source/blender/python/BPY_extern.h | 4 +- source/blender/python/BPY_menus.c | 1118 ------ source/blender/python/BPY_menus.h | 128 - source/blender/python/Makefile | 2 +- source/blender/python/generic/BGL.c | 13 +- source/blender/python/generic/BGL.h | 2 +- source/blender/python/generic/Geometry.c | 36 +- source/blender/python/generic/Geometry.h | 2 +- source/blender/python/generic/Makefile | 2 +- source/blender/python/generic/Mathutils.c | 279 +- source/blender/python/generic/Mathutils.h | 51 +- .../blender/python/generic/bpy_internal_import.c | 2 +- .../blender/python/generic/bpy_internal_import.h | 2 +- source/blender/python/generic/euler.c | 294 +- source/blender/python/generic/euler.h | 21 +- source/blender/python/generic/matrix.c | 494 ++- source/blender/python/generic/matrix.h | 35 +- source/blender/python/generic/quat.c | 466 +-- source/blender/python/generic/quat.h | 23 +- source/blender/python/generic/vector.c | 1236 +++--- source/blender/python/generic/vector.h | 21 +- source/blender/python/intern/Makefile | 2 +- source/blender/python/intern/bpy_compat.h | 2 +- source/blender/python/intern/bpy_interface.c | 13 +- source/blender/python/intern/bpy_operator.c | 2 +- source/blender/python/intern/bpy_operator.h | 2 +- source/blender/python/intern/bpy_operator_wrap.c | 113 +- source/blender/python/intern/bpy_operator_wrap.h | 2 +- source/blender/python/intern/bpy_rna.c | 882 ++++- source/blender/python/intern/bpy_rna.h | 2 +- source/blender/python/intern/bpy_ui.c | 2 +- source/blender/python/intern/bpy_ui.h | 2 +- source/blender/python/intern/bpy_util.c | 4 +- source/blender/python/intern/bpy_util.h | 2 +- source/blender/radiosity/CMakeLists.txt | 36 - source/blender/radiosity/Makefile | 34 - source/blender/radiosity/SConscript | 12 - source/blender/radiosity/extern/include/radio.h | 173 - .../blender/radiosity/extern/include/radio_types.h | 168 - source/blender/radiosity/intern/Makefile | 34 - source/blender/radiosity/intern/source/Makefile | 55 - .../blender/radiosity/intern/source/raddisplay.c | 477 --- .../blender/radiosity/intern/source/radfactors.c | 939 ----- source/blender/radiosity/intern/source/radio.c | 390 -- source/blender/radiosity/intern/source/radnode.c | 1103 ------ .../radiosity/intern/source/radpostprocess.c | 824 ---- .../radiosity/intern/source/radpreprocess.c | 828 ---- source/blender/radiosity/intern/source/radrender.c | 530 --- .../blender/render/extern/include/RE_render_ext.h | 3 +- .../blender/render/intern/source/convertblender.c | 10 +- source/blender/render/intern/source/pipeline.c | 20 +- source/blender/render/intern/source/zbuf.c | 108 +- source/blender/windowmanager/WM_api.h | 8 +- source/blender/windowmanager/WM_types.h | 36 +- source/blender/windowmanager/intern/Makefile | 2 +- source/blender/windowmanager/intern/wm.c | 12 + .../blender/windowmanager/intern/wm_event_system.c | 17 +- source/blender/windowmanager/intern/wm_files.c | 4 +- source/blender/windowmanager/intern/wm_init_exit.c | 5 - source/blender/windowmanager/intern/wm_keymap.c | 313 +- source/blender/windowmanager/intern/wm_operators.c | 21 +- source/blender/windowmanager/intern/wm_subwindow.c | 2 +- source/blender/windowmanager/wm_cursors.h | 2 +- source/blender/windowmanager/wm_subwindow.h | 2 +- source/creator/CMakeLists.txt | 12 +- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 41 +- source/gameengine/BlenderRoutines/CMakeLists.txt | 3 +- .../BlenderRoutines/KX_BlenderCanvas.cpp | 2 + source/gameengine/BlenderRoutines/Makefile | 4 +- source/gameengine/BlenderRoutines/SConscript | 8 +- source/gameengine/CMakeLists.txt | 1 - source/gameengine/Converter/BL_ActionActuator.cpp | 49 +- source/gameengine/Converter/BL_ActionActuator.h | 9 +- .../Converter/BL_BlenderDataConversion.cpp | 13 - .../Converter/BL_ShapeActionActuator.cpp | 40 +- .../gameengine/Converter/BL_ShapeActionActuator.h | 9 +- .../Converter/KX_BlenderSceneConverter.cpp | 28 +- source/gameengine/Converter/Makefile | 3 +- source/gameengine/Converter/SConscript | 5 - source/gameengine/Expressions/BoolValue.cpp | 3 +- source/gameengine/Expressions/CMakeLists.txt | 1 + source/gameengine/Expressions/IntValue.cpp | 2 +- source/gameengine/Expressions/KX_Python.h | 2 + source/gameengine/Expressions/ListValue.cpp | 59 +- source/gameengine/Expressions/ListValue.h | 4 +- source/gameengine/Expressions/Makefile | 1 + source/gameengine/Expressions/PyObjectPlus.cpp | 338 +- source/gameengine/Expressions/PyObjectPlus.h | 99 +- source/gameengine/Expressions/StringValue.h | 2 +- source/gameengine/Expressions/Value.cpp | 124 +- source/gameengine/Expressions/Value.h | 16 +- .../gameengine/GameLogic/SCA_2DFilterActuator.cpp | 42 +- source/gameengine/GameLogic/SCA_2DFilterActuator.h | 13 +- source/gameengine/GameLogic/SCA_ANDController.cpp | 31 +- source/gameengine/GameLogic/SCA_ANDController.h | 10 +- source/gameengine/GameLogic/SCA_ActuatorSensor.cpp | 37 +- source/gameengine/GameLogic/SCA_ActuatorSensor.h | 7 +- source/gameengine/GameLogic/SCA_AlwaysSensor.cpp | 31 +- source/gameengine/GameLogic/SCA_AlwaysSensor.h | 12 +- source/gameengine/GameLogic/SCA_DelaySensor.cpp | 40 +- source/gameengine/GameLogic/SCA_DelaySensor.h | 7 +- .../GameLogic/SCA_ExpressionController.cpp | 5 +- .../GameLogic/SCA_ExpressionController.h | 11 +- source/gameengine/GameLogic/SCA_IActuator.cpp | 5 +- source/gameengine/GameLogic/SCA_IActuator.h | 3 +- source/gameengine/GameLogic/SCA_IController.cpp | 47 +- source/gameengine/GameLogic/SCA_IController.h | 6 +- source/gameengine/GameLogic/SCA_ILogicBrick.cpp | 44 +- source/gameengine/GameLogic/SCA_ILogicBrick.h | 6 +- source/gameengine/GameLogic/SCA_IObject.cpp | 81 +- source/gameengine/GameLogic/SCA_IObject.h | 7 +- source/gameengine/GameLogic/SCA_ISensor.cpp | 46 +- source/gameengine/GameLogic/SCA_ISensor.h | 7 +- source/gameengine/GameLogic/SCA_JoystickSensor.cpp | 73 +- source/gameengine/GameLogic/SCA_JoystickSensor.h | 7 +- source/gameengine/GameLogic/SCA_KeyboardSensor.cpp | 61 +- source/gameengine/GameLogic/SCA_KeyboardSensor.h | 7 +- source/gameengine/GameLogic/SCA_LogicManager.cpp | 1 + source/gameengine/GameLogic/SCA_MouseSensor.cpp | 47 +- source/gameengine/GameLogic/SCA_MouseSensor.h | 7 +- source/gameengine/GameLogic/SCA_NANDController.cpp | 31 +- source/gameengine/GameLogic/SCA_NANDController.h | 6 +- source/gameengine/GameLogic/SCA_NORController.cpp | 31 +- source/gameengine/GameLogic/SCA_NORController.h | 10 +- source/gameengine/GameLogic/SCA_ORController.cpp | 32 +- source/gameengine/GameLogic/SCA_ORController.h | 9 +- .../gameengine/GameLogic/SCA_PropertyActuator.cpp | 38 +- source/gameengine/GameLogic/SCA_PropertyActuator.h | 8 +- source/gameengine/GameLogic/SCA_PropertySensor.cpp | 42 +- source/gameengine/GameLogic/SCA_PropertySensor.h | 7 +- .../gameengine/GameLogic/SCA_PythonController.cpp | 63 +- source/gameengine/GameLogic/SCA_PythonController.h | 6 +- source/gameengine/GameLogic/SCA_RandomActuator.cpp | 48 +- source/gameengine/GameLogic/SCA_RandomActuator.h | 7 +- source/gameengine/GameLogic/SCA_RandomSensor.cpp | 46 +- source/gameengine/GameLogic/SCA_RandomSensor.h | 7 +- source/gameengine/GameLogic/SCA_XNORController.cpp | 31 +- source/gameengine/GameLogic/SCA_XNORController.h | 5 +- source/gameengine/GameLogic/SCA_XORController.cpp | 31 +- source/gameengine/GameLogic/SCA_XORController.h | 10 +- source/gameengine/GamePlayer/common/Makefile | 3 - source/gameengine/GamePlayer/common/SConscript | 5 - .../GamePlayer/common/unix/GPU_Engine.cpp | 3 - source/gameengine/GamePlayer/common/unix/Makefile | 2 - source/gameengine/GamePlayer/ghost/SConscript | 4 - source/gameengine/Ketsji/BL_Shader.cpp | 43 +- source/gameengine/Ketsji/BL_Shader.h | 6 +- .../Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp | 37 +- .../Ketsji/KXNetwork/KX_NetworkMessageActuator.h | 7 +- .../Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp | 43 +- .../Ketsji/KXNetwork/KX_NetworkMessageSensor.h | 7 +- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 43 +- source/gameengine/Ketsji/KX_BlenderMaterial.h | 9 +- source/gameengine/Ketsji/KX_CDActuator.cpp | 47 +- source/gameengine/Ketsji/KX_CDActuator.h | 7 +- source/gameengine/Ketsji/KX_Camera.cpp | 65 +- source/gameengine/Ketsji/KX_Camera.h | 7 +- source/gameengine/Ketsji/KX_CameraActuator.cpp | 39 +- source/gameengine/Ketsji/KX_CameraActuator.h | 8 +- source/gameengine/Ketsji/KX_ClientObjectInfo.h | 12 - source/gameengine/Ketsji/KX_ConstraintActuator.cpp | 50 +- source/gameengine/Ketsji/KX_ConstraintActuator.h | 7 +- source/gameengine/Ketsji/KX_ConstraintWrapper.cpp | 42 +- source/gameengine/Ketsji/KX_ConstraintWrapper.h | 5 +- source/gameengine/Ketsji/KX_ConvertPhysicsObject.h | 30 - .../gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp | 592 --- source/gameengine/Ketsji/KX_GameActuator.cpp | 45 +- source/gameengine/Ketsji/KX_GameActuator.h | 7 +- source/gameengine/Ketsji/KX_GameObject.cpp | 445 ++- source/gameengine/Ketsji/KX_GameObject.h | 42 +- source/gameengine/Ketsji/KX_IpoActuator.cpp | 37 +- source/gameengine/Ketsji/KX_IpoActuator.h | 7 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 10 +- source/gameengine/Ketsji/KX_Light.cpp | 56 +- source/gameengine/Ketsji/KX_Light.h | 6 +- source/gameengine/Ketsji/KX_MeshProxy.cpp | 55 +- source/gameengine/Ketsji/KX_MeshProxy.h | 3 - source/gameengine/Ketsji/KX_MouseFocusSensor.cpp | 33 +- source/gameengine/Ketsji/KX_MouseFocusSensor.h | 5 +- source/gameengine/Ketsji/KX_NearSensor.cpp | 46 +- source/gameengine/Ketsji/KX_NearSensor.h | 9 +- source/gameengine/Ketsji/KX_ObjectActuator.cpp | 159 +- source/gameengine/Ketsji/KX_ObjectActuator.h | 18 +- .../gameengine/Ketsji/KX_OdePhysicsController.cpp | 257 -- source/gameengine/Ketsji/KX_OdePhysicsController.h | 109 - source/gameengine/Ketsji/KX_ParentActuator.cpp | 37 +- source/gameengine/Ketsji/KX_ParentActuator.h | 7 +- .../gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp | 49 +- source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h | 6 +- source/gameengine/Ketsji/KX_PolyProxy.cpp | 61 +- source/gameengine/Ketsji/KX_PolyProxy.h | 2 - source/gameengine/Ketsji/KX_PolygonMaterial.cpp | 44 +- source/gameengine/Ketsji/KX_PolygonMaterial.h | 7 +- .../gameengine/Ketsji/KX_PyConstraintBinding.cpp | 2 +- source/gameengine/Ketsji/KX_PyMath.cpp | 92 +- source/gameengine/Ketsji/KX_PyMath.h | 55 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 38 +- source/gameengine/Ketsji/KX_PythonInitTypes.cpp | 213 +- source/gameengine/Ketsji/KX_PythonSeq.cpp | 12 +- source/gameengine/Ketsji/KX_RadarSensor.cpp | 40 +- source/gameengine/Ketsji/KX_RadarSensor.h | 7 +- source/gameengine/Ketsji/KX_RaySensor.cpp | 39 +- source/gameengine/Ketsji/KX_RaySensor.h | 8 +- .../gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp | 45 +- .../gameengine/Ketsji/KX_SCA_AddObjectActuator.h | 7 +- .../gameengine/Ketsji/KX_SCA_DynamicActuator.cpp | 45 +- source/gameengine/Ketsji/KX_SCA_DynamicActuator.h | 8 +- .../gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp | 35 +- .../gameengine/Ketsji/KX_SCA_EndObjectActuator.h | 6 +- .../Ketsji/KX_SCA_ReplaceMeshActuator.cpp | 45 +- .../gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h | 9 +- source/gameengine/Ketsji/KX_Scene.cpp | 88 +- source/gameengine/Ketsji/KX_Scene.h | 10 +- source/gameengine/Ketsji/KX_SceneActuator.cpp | 50 +- source/gameengine/Ketsji/KX_SceneActuator.h | 7 +- source/gameengine/Ketsji/KX_SoundActuator.cpp | 53 +- source/gameengine/Ketsji/KX_SoundActuator.h | 7 +- source/gameengine/Ketsji/KX_StateActuator.cpp | 41 +- source/gameengine/Ketsji/KX_StateActuator.h | 9 +- .../gameengine/Ketsji/KX_SumoPhysicsController.cpp | 244 -- .../gameengine/Ketsji/KX_SumoPhysicsController.h | 122 - source/gameengine/Ketsji/KX_TouchSensor.cpp | 44 +- source/gameengine/Ketsji/KX_TouchSensor.h | 7 +- source/gameengine/Ketsji/KX_TrackToActuator.cpp | 51 +- source/gameengine/Ketsji/KX_TrackToActuator.h | 5 +- source/gameengine/Ketsji/KX_VehicleWrapper.cpp | 44 +- source/gameengine/Ketsji/KX_VehicleWrapper.h | 5 +- source/gameengine/Ketsji/KX_VertexProxy.cpp | 96 +- source/gameengine/Ketsji/KX_VertexProxy.h | 3 - source/gameengine/Ketsji/KX_VisibilityActuator.cpp | 43 +- source/gameengine/Ketsji/KX_VisibilityActuator.h | 8 +- source/gameengine/Ketsji/Makefile | 5 +- source/gameengine/Ketsji/SConscript | 9 +- source/gameengine/Physics/BlOde/Makefile | 48 - .../Physics/BlOde/OdePhysicsController.cpp | 625 --- .../Physics/BlOde/OdePhysicsController.h | 164 - .../Physics/BlOde/OdePhysicsEnvironment.cpp | 277 -- .../Physics/BlOde/OdePhysicsEnvironment.h | 94 - source/gameengine/Physics/BlOde/SConscript | 15 - source/gameengine/Physics/Dummy/Makefile | 2 +- source/gameengine/Physics/Makefile | 3 +- source/gameengine/Physics/Sumo/CMakeLists.txt | 46 - source/gameengine/Physics/Sumo/Fuzzics/Makefile | 34 - .../Physics/Sumo/Fuzzics/include/SM_Callback.h | 11 - .../Sumo/Fuzzics/include/SM_ClientObjectInfo.h | 16 - .../Physics/Sumo/Fuzzics/include/SM_Debug.h | 26 - .../Physics/Sumo/Fuzzics/include/SM_FhObject.h | 56 - .../Physics/Sumo/Fuzzics/include/SM_MotionState.h | 77 - .../Physics/Sumo/Fuzzics/include/SM_Object.h | 393 -- .../Physics/Sumo/Fuzzics/include/SM_Props.h | 58 - .../Physics/Sumo/Fuzzics/include/SM_Scene.h | 172 - .../Physics/Sumo/Fuzzics/sample/Makefile | 25 - .../Physics/Sumo/Fuzzics/sample/particle.cpp | 709 ---- .../Physics/Sumo/Fuzzics/sample/particle0.cpp | 695 ---- .../gameengine/Physics/Sumo/Fuzzics/src/Makefile | 14 - .../Physics/Sumo/Fuzzics/src/SM_FhObject.cpp | 180 - .../Physics/Sumo/Fuzzics/src/SM_MotionState.cpp | 100 - .../Physics/Sumo/Fuzzics/src/SM_Object.cpp | 1298 ------- .../Physics/Sumo/Fuzzics/src/SM_Scene.cpp | 378 -- source/gameengine/Physics/Sumo/Makefile | 50 - source/gameengine/Physics/Sumo/SConscript | 25 - .../Physics/Sumo/SumoPHYCallbackBridge.cpp | 66 - .../Physics/Sumo/SumoPHYCallbackBridge.h | 28 - .../Physics/Sumo/SumoPhysicsController.cpp | 495 --- .../Physics/Sumo/SumoPhysicsController.h | 192 - .../Physics/Sumo/SumoPhysicsEnvironment.cpp | 264 -- .../Physics/Sumo/SumoPhysicsEnvironment.h | 110 - source/gameengine/Physics/Sumo/convert.txt | 35 - .../gameengine/Physics/Sumo/include/interpolator.h | 27 - source/gameengine/Physics/common/Makefile | 2 +- source/gameengine/SConscript | 8 - .../gameengine/VideoTexture/FilterBlueScreen.cpp | 20 +- source/gameengine/VideoTexture/FilterColor.cpp | 8 +- source/gameengine/VideoTexture/FilterNormal.cpp | 4 +- source/gameengine/VideoTexture/ImageRender.cpp | 16 +- source/gameengine/VideoTexture/ImageViewport.cpp | 16 +- source/gameengine/VideoTexture/VideoBase.cpp | 4 +- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 4 +- source/gameengine/VideoTexture/blendVideoTex.cpp | 2 +- source/nan_compile.mk | 15 - source/nan_definitions.mk | 41 - source/nan_link.mk | 4 - tools/btools.py | 13 +- 827 files changed, 15576 insertions(+), 78646 deletions(-) delete mode 100644 extern/qhull/CMakeLists.txt delete mode 100644 extern/qhull/COPYING.txt delete mode 100644 extern/qhull/README.txt delete mode 100644 extern/qhull/REGISTER.txt delete mode 100644 extern/qhull/SConscript delete mode 100644 extern/qhull/VisualC6/qhull.dsw delete mode 100644 extern/qhull/VisualC6/qhull/qhull.dsp delete mode 100644 extern/qhull/include/qhull/geom.h delete mode 100644 extern/qhull/include/qhull/io.h delete mode 100644 extern/qhull/include/qhull/mem.h delete mode 100644 extern/qhull/include/qhull/merge.h delete mode 100644 extern/qhull/include/qhull/poly.h delete mode 100644 extern/qhull/include/qhull/qhull.h delete mode 100644 extern/qhull/include/qhull/qhull_a.h delete mode 100644 extern/qhull/include/qhull/qset.h delete mode 100644 extern/qhull/include/qhull/stat.h delete mode 100644 extern/qhull/include/qhull/user.h delete mode 100644 extern/qhull/make/msvc_7_0/qhull.vcproj delete mode 100644 extern/qhull/make/msvc_9_0/qhull.vcproj delete mode 100755 extern/qhull/src/Make-config.sh delete mode 100644 extern/qhull/src/Makefile delete mode 100644 extern/qhull/src/Makefile.txt delete mode 100644 extern/qhull/src/geom.c delete mode 100644 extern/qhull/src/geom.h delete mode 100644 extern/qhull/src/geom2.c delete mode 100644 extern/qhull/src/global.c delete mode 100644 extern/qhull/src/io.c delete mode 100644 extern/qhull/src/io.h delete mode 100644 extern/qhull/src/mem.c delete mode 100644 extern/qhull/src/mem.h delete mode 100644 extern/qhull/src/merge.c delete mode 100644 extern/qhull/src/merge.h delete mode 100644 extern/qhull/src/poly.c delete mode 100644 extern/qhull/src/poly.h delete mode 100644 extern/qhull/src/poly2.c delete mode 100644 extern/qhull/src/qconvex.c delete mode 100644 extern/qhull/src/qdelaun.c delete mode 100644 extern/qhull/src/qhalf.c delete mode 100644 extern/qhull/src/qhull.c delete mode 100644 extern/qhull/src/qhull.h delete mode 100644 extern/qhull/src/qhull_a.h delete mode 100644 extern/qhull/src/qhull_interface.cpp delete mode 100644 extern/qhull/src/qset.c delete mode 100644 extern/qhull/src/qset.h delete mode 100644 extern/qhull/src/qvoronoi.c delete mode 100644 extern/qhull/src/rbox.c delete mode 100644 extern/qhull/src/stat.c delete mode 100644 extern/qhull/src/stat.h delete mode 100644 extern/qhull/src/unix.c delete mode 100644 extern/qhull/src/user.c delete mode 100644 extern/qhull/src/user.h delete mode 100644 extern/qhull/src/user_eg.c delete mode 100644 extern/qhull/src/user_eg2.c delete mode 100644 extern/solid/CMakeLists.txt delete mode 100644 extern/solid/LICENSE_GPL.txt delete mode 100644 extern/solid/LICENSE_QPL.txt delete mode 100644 extern/solid/Makefile delete mode 100644 extern/solid/README.txt delete mode 100644 extern/solid/SConscript delete mode 100644 extern/solid/SOLID/SOLID.h delete mode 100644 extern/solid/SOLID/SOLID_broad.h delete mode 100644 extern/solid/SOLID/SOLID_types.h delete mode 100644 extern/solid/VisualC6/broad/broad.dsp delete mode 100644 extern/solid/VisualC6/complex/complex.dsp delete mode 100644 extern/solid/VisualC6/convex/convex.dsp delete mode 100644 extern/solid/VisualC6/dynamics/dynamics.dsp delete mode 100644 extern/solid/VisualC6/gldemo/gldemo.dsp delete mode 100644 extern/solid/VisualC6/mnm/mnm.dsp delete mode 100644 extern/solid/VisualC6/physics/physics.dsp delete mode 100644 extern/solid/VisualC6/sample/sample.dsp delete mode 100644 extern/solid/VisualC6/solid.dsw delete mode 100644 extern/solid/VisualC6/solid/solid.dsp delete mode 100644 extern/solid/VisualC6/solid_dll/solid_dll.dsp delete mode 100644 extern/solid/include/GEN_MinMax.h delete mode 100644 extern/solid/include/GEN_random.h delete mode 100644 extern/solid/include/MT/Interval.h delete mode 100644 extern/solid/include/MT/Matrix3x3.h delete mode 100644 extern/solid/include/MT/Quaternion.h delete mode 100644 extern/solid/include/MT/Transform.h delete mode 100644 extern/solid/include/MT/Tuple3.h delete mode 100644 extern/solid/include/MT/Tuple4.h delete mode 100644 extern/solid/include/MT/Vector3.h delete mode 100644 extern/solid/include/MT_BBox.h delete mode 100644 extern/solid/include/MT_Interval.h delete mode 100644 extern/solid/include/MT_Matrix3x3.h delete mode 100644 extern/solid/include/MT_Point3.h delete mode 100644 extern/solid/include/MT_Quaternion.h delete mode 100644 extern/solid/include/MT_Scalar.h delete mode 100644 extern/solid/include/MT_Transform.h delete mode 100644 extern/solid/include/MT_Vector3.h delete mode 100644 extern/solid/include/SOLID.h delete mode 100644 extern/solid/include/SOLID_broad.h delete mode 100644 extern/solid/include/SOLID_types.h delete mode 100644 extern/solid/make/msvc_7_0/broad/broad.vcproj delete mode 100644 extern/solid/make/msvc_7_0/complex/complex.vcproj delete mode 100644 extern/solid/make/msvc_7_0/convex/convex.vcproj delete mode 100644 extern/solid/make/msvc_7_0/solid.vcproj delete mode 100644 extern/solid/make/msvc_9_0/broad/broad.vcproj delete mode 100644 extern/solid/make/msvc_9_0/complex/complex.vcproj delete mode 100644 extern/solid/make/msvc_9_0/convex/convex.vcproj delete mode 100644 extern/solid/make/msvc_9_0/solid.vcproj delete mode 100644 extern/solid/src/DT_AlgoTable.h delete mode 100644 extern/solid/src/DT_C-api.cpp delete mode 100644 extern/solid/src/DT_Encounter.cpp delete mode 100644 extern/solid/src/DT_Encounter.h delete mode 100644 extern/solid/src/DT_Object.cpp delete mode 100644 extern/solid/src/DT_Object.h delete mode 100644 extern/solid/src/DT_RespTable.cpp delete mode 100644 extern/solid/src/DT_RespTable.h delete mode 100644 extern/solid/src/DT_Response.h delete mode 100644 extern/solid/src/DT_Scene.cpp delete mode 100644 extern/solid/src/DT_Scene.h delete mode 100644 extern/solid/src/Makefile delete mode 100644 extern/solid/src/broad/BP_C-api.cpp delete mode 100644 extern/solid/src/broad/BP_Endpoint.h delete mode 100644 extern/solid/src/broad/BP_EndpointList.cpp delete mode 100644 extern/solid/src/broad/BP_EndpointList.h delete mode 100644 extern/solid/src/broad/BP_Proxy.cpp delete mode 100644 extern/solid/src/broad/BP_Proxy.h delete mode 100644 extern/solid/src/broad/BP_ProxyList.h delete mode 100644 extern/solid/src/broad/BP_Scene.cpp delete mode 100644 extern/solid/src/broad/BP_Scene.h delete mode 100644 extern/solid/src/broad/Makefile delete mode 100644 extern/solid/src/complex/DT_BBoxTree.cpp delete mode 100644 extern/solid/src/complex/DT_BBoxTree.h delete mode 100644 extern/solid/src/complex/DT_CBox.h delete mode 100644 extern/solid/src/complex/DT_Complex.cpp delete mode 100644 extern/solid/src/complex/DT_Complex.h delete mode 100644 extern/solid/src/complex/Makefile delete mode 100644 extern/solid/src/convex/DT_Accuracy.cpp delete mode 100644 extern/solid/src/convex/DT_Accuracy.h delete mode 100644 extern/solid/src/convex/DT_Array.h delete mode 100644 extern/solid/src/convex/DT_Box.cpp delete mode 100644 extern/solid/src/convex/DT_Box.h delete mode 100644 extern/solid/src/convex/DT_Cone.cpp delete mode 100644 extern/solid/src/convex/DT_Cone.h delete mode 100644 extern/solid/src/convex/DT_Convex.cpp delete mode 100644 extern/solid/src/convex/DT_Convex.h delete mode 100644 extern/solid/src/convex/DT_Cylinder.cpp delete mode 100644 extern/solid/src/convex/DT_Cylinder.h delete mode 100644 extern/solid/src/convex/DT_Facet.cpp delete mode 100644 extern/solid/src/convex/DT_Facet.h delete mode 100644 extern/solid/src/convex/DT_GJK.h delete mode 100644 extern/solid/src/convex/DT_Hull.h delete mode 100644 extern/solid/src/convex/DT_IndexArray.h delete mode 100644 extern/solid/src/convex/DT_LineSegment.cpp delete mode 100644 extern/solid/src/convex/DT_LineSegment.h delete mode 100644 extern/solid/src/convex/DT_Minkowski.h delete mode 100644 extern/solid/src/convex/DT_PenDepth.cpp delete mode 100644 extern/solid/src/convex/DT_PenDepth.h delete mode 100644 extern/solid/src/convex/DT_Point.cpp delete mode 100644 extern/solid/src/convex/DT_Point.h delete mode 100644 extern/solid/src/convex/DT_Polyhedron.cpp delete mode 100644 extern/solid/src/convex/DT_Polyhedron.h delete mode 100644 extern/solid/src/convex/DT_Polytope.cpp delete mode 100644 extern/solid/src/convex/DT_Polytope.h delete mode 100644 extern/solid/src/convex/DT_Shape.h delete mode 100644 extern/solid/src/convex/DT_Sphere.cpp delete mode 100644 extern/solid/src/convex/DT_Sphere.h delete mode 100644 extern/solid/src/convex/DT_Transform.h delete mode 100644 extern/solid/src/convex/DT_Triangle.cpp delete mode 100644 extern/solid/src/convex/DT_Triangle.h delete mode 100644 extern/solid/src/convex/DT_VertexBase.h delete mode 100644 extern/solid/src/convex/Makefile create mode 100644 release/ui/space_buttons.py create mode 100644 release/ui/space_filebrowser.py create mode 100644 release/ui/space_info.py create mode 100644 source/blender/editors/include/ED_pointcache.h delete mode 100644 source/blender/editors/mesh/editdeform.c create mode 100644 source/blender/editors/mesh/mesh_layers.c create mode 100644 source/blender/editors/object/object_vgroup.c create mode 100644 source/blender/editors/physics/ed_pointcache.c create mode 100644 source/blender/editors/space_file/file_panels.c delete mode 100644 source/blender/editors/space_info/info_header.c create mode 100644 source/blender/editors/space_info/info_ops.c delete mode 100644 source/blender/makesdna/DNA_radio_types.h delete mode 100644 source/blender/makesrna/intern/rna_radio.c delete mode 100644 source/blender/python/BPY_menus.c delete mode 100644 source/blender/python/BPY_menus.h delete mode 100644 source/blender/radiosity/CMakeLists.txt delete mode 100644 source/blender/radiosity/Makefile delete mode 100644 source/blender/radiosity/SConscript delete mode 100644 source/blender/radiosity/extern/include/radio.h delete mode 100644 source/blender/radiosity/extern/include/radio_types.h delete mode 100644 source/blender/radiosity/intern/Makefile delete mode 100644 source/blender/radiosity/intern/source/Makefile delete mode 100644 source/blender/radiosity/intern/source/raddisplay.c delete mode 100644 source/blender/radiosity/intern/source/radfactors.c delete mode 100644 source/blender/radiosity/intern/source/radio.c delete mode 100644 source/blender/radiosity/intern/source/radnode.c delete mode 100644 source/blender/radiosity/intern/source/radpostprocess.c delete mode 100644 source/blender/radiosity/intern/source/radpreprocess.c delete mode 100644 source/blender/radiosity/intern/source/radrender.c delete mode 100644 source/gameengine/Ketsji/KX_OdePhysicsController.cpp delete mode 100644 source/gameengine/Ketsji/KX_OdePhysicsController.h delete mode 100644 source/gameengine/Ketsji/KX_SumoPhysicsController.cpp delete mode 100644 source/gameengine/Ketsji/KX_SumoPhysicsController.h delete mode 100644 source/gameengine/Physics/BlOde/Makefile delete mode 100644 source/gameengine/Physics/BlOde/OdePhysicsController.cpp delete mode 100644 source/gameengine/Physics/BlOde/OdePhysicsController.h delete mode 100644 source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp delete mode 100644 source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h delete mode 100644 source/gameengine/Physics/BlOde/SConscript delete mode 100644 source/gameengine/Physics/Sumo/CMakeLists.txt delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/Makefile delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/src/Makefile delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp delete mode 100644 source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp delete mode 100644 source/gameengine/Physics/Sumo/Makefile delete mode 100644 source/gameengine/Physics/Sumo/SConscript delete mode 100644 source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp delete mode 100644 source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h delete mode 100644 source/gameengine/Physics/Sumo/SumoPhysicsController.cpp delete mode 100644 source/gameengine/Physics/Sumo/SumoPhysicsController.h delete mode 100644 source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp delete mode 100644 source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h delete mode 100644 source/gameengine/Physics/Sumo/convert.txt delete mode 100644 source/gameengine/Physics/Sumo/include/interpolator.h diff --git a/CMake/macros.cmake b/CMake/macros.cmake index bc8892e4b99..44fc2903875 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -61,7 +61,7 @@ MACRO(SETUP_LIBLINKS SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ") #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) - TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${SDL_LIB} ${LLIBS}) # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c7ee34cc14..714ec4095af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ INCLUDE(CMake/macros.cmake) IF(UNIX) IF(WITH_OPENAL) - INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + FIND_PACKAGE(OpenAL) IF(OPENAL_FOUND) SET(WITH_OPENAL ON) SET(OPENAL_LIB ${OPENAL_LIBRARY}) @@ -102,22 +102,12 @@ IF(UNIX) FIND_LIBRARY(INTL_LIBRARY NAMES intl PATHS - /usr/local/lib - /usr/lib /sw/lib - /opt/local/lib - /opt/csw/lib - /opt/lib ) FIND_LIBRARY(ICONV_LIBRARY NAMES iconv PATHS - /usr/local/lib - /usr/lib /sw/lib - /opt/local/lib - /opt/csw/lib - /opt/lib ) IF(INTL_LIBRARY AND ICONV_LIBRARY) SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY}) @@ -136,14 +126,14 @@ IF(UNIX) ) SET(FREETYPE_LIB freetype) - INCLUDE(${CMAKE_ROOT}/Modules/FindPythonLibs.cmake) + FIND_PACKAGE(PythonLibs) SET(PYTHON_INC "${PYTHON_INCLUDE_PATH}" CACHE STRING "") SET(PYTHON_LIB "${PYTHON_LIBRARIES}" CACHE STRING "") - INCLUDE(${CMAKE_ROOT}/Modules/FindPythonInterp.cmake) + FIND_PACKAGE(PythonInterp) SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "") SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic") - INCLUDE(${CMAKE_ROOT}/Modules/FindSDL.cmake) + FIND_PACKAGE(SDL) SET(SDL_INC ${SDL_INCLUDE_DIR}) SET(SDL_LIB ${SDL_LIBRARY}) @@ -164,11 +154,11 @@ IF(UNIX) SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale) SET(FFMPEG_LIBPATH ${FFMPEG}/lib) - SET(JPEG_LIB jpeg) + FIND_PACKAGE(JPEG REQUIRED) - SET(PNG_LIB png) + FIND_PACKAGE(PNG REQUIRED) - SET(ZLIB_LIB z) + FIND_PACKAGE(ZLIB REQUIRED) SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11 -ldl") @@ -186,12 +176,13 @@ IF(UNIX) # Better warnings SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wnested-externs -Wdeclaration-after-statement") - INCLUDE_DIRECTORIES(/usr/include /usr/local/include) + INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) ENDIF(UNIX) IF(WIN32) - INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) + # this file is included anyway when building under Windows with cl.exe + # INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows) @@ -202,10 +193,10 @@ IF(WIN32) ENDIF(CMAKE_CL_64) SET(PYTHON ${LIBDIR}/python) - SET(PYTHON_VERSION 2.5) + SET(PYTHON_VERSION 2.6) SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}") SET(PYTHON_BINARY python) - SET(PYTHON_LIB python25) + SET(PYTHON_LIB python26) SET(PYTHON_LIBPATH ${PYTHON}/lib) IF(CMAKE_CL_64) @@ -219,15 +210,15 @@ IF(WIN32) ENDIF(CMAKE_CL_64) IF(CMAKE_CL_64) - SET(PNG_LIB libpng) + SET(PNG_LIBRARIES libpng) ELSE(CMAKE_CL_64) - SET(PNG_LIB libpng_st) + SET(PNG_LIBRARIES libpng_st) ENDIF(CMAKE_CL_64) - SET(JPEG_LIB libjpeg) + SET(JPEG_LIBRARY libjpeg) SET(ZLIB ${LIBDIR}/zlib) SET(ZLIB_INC ${ZLIB}/include) - SET(ZLIB_LIB libz) + SET(ZLIB_LIBRARIES zlib) SET(ZLIB_LIBPATH ${ZLIB}/lib) SET(PTHREADS ${LIBDIR}/pthreads) @@ -335,7 +326,7 @@ IF(APPLE) ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) IF(WITH_OPENAL) - INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + FIND_PACKAGE(OpenAL) IF(OPENAL_FOUND) SET(WITH_OPENAL ON) SET(OPENAL_LIB ${OPENAL_LIBRARY}) @@ -362,12 +353,12 @@ IF(APPLE) SET(GETTEXT_LIB intl iconv) SET(GETTEXT_LIBPATH ${GETTEXT}/lib) - SET(PNG_LIB png) - SET(JPEG_LIB jpeg) + SET(PNG_LIBRARIES png) + SET(JPEG_LIBRARY jpeg) SET(ZLIB /usr) SET(ZLIB_INC "${ZLIB}/include") - SET(ZLIB_LIB z) + SET(ZLIB_LIBRARIES z) SET(FREETYPE ${LIBDIR}/freetype) SET(FREETYPE_INC ${FREETYPE}/include ${FREETYPE}/include/freetype2) @@ -438,7 +429,7 @@ ENDIF(WITH_WEBPLUGIN) #----------------------------------------------------------------------------- # Configure OpenGL. -INCLUDE(${CMAKE_ROOT}/Modules/FindOpenGL.cmake) +FIND_PACKAGE(OpenGL) INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) #----------------------------------------------------------------------------- # Extra compile flags diff --git a/SConstruct b/SConstruct index 808fa09bea0..b85bc799ea5 100644 --- a/SConstruct +++ b/SConstruct @@ -285,9 +285,7 @@ if 'blenderlite' in B.targets: target_env_defs['WITH_BF_SDL'] = False target_env_defs['WITH_BF_JPEG'] = False target_env_defs['WITH_BF_PNG'] = False - target_env_defs['WITH_BF_ODE'] = False target_env_defs['WITH_BF_BULLET'] = False - target_env_defs['WITH_BF_SOLID'] = False target_env_defs['WITH_BF_BINRELOC'] = False target_env_defs['BF_BUILDINFO'] = False target_env_defs['BF_NO_ELBEEM'] = True diff --git a/config/darwin-config.py b/config/darwin-config.py index 080820f885a..785f1cb42a2 100644 --- a/config/darwin-config.py +++ b/config/darwin-config.py @@ -141,20 +141,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE=True WITH_BF_PLAYER=True -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = '${BF_ODE}/include' -BF_ODE_LIB = '${BF_ODE}/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/irix6-config.py b/config/irix6-config.py index 3c8fd0dece4..87af6b29eb1 100644 --- a/config/irix6-config.py +++ b/config/irix6-config.py @@ -74,20 +74,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE='false' -WITH_BF_ODE = 'false' -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = 'true' BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = 'true' #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/linux2-config.py b/config/linux2-config.py index 4cea4bb8e05..86de10c8fb3 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -77,20 +77,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = True WITH_BF_PLAYER = True -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index 2f15ef67e6c..5e5c44ecd69 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -74,20 +74,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = False -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py index f27066b43f7..2b0621e2ed3 100644 --- a/config/openbsd3-config.py +++ b/config/openbsd3-config.py @@ -61,20 +61,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE=False -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = '${BF_ODE}/include' -BF_ODE_LIB = '${BF_ODE}/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/sunos5-config.py b/config/sunos5-config.py index e050a5950aa..dc067b6f568 100644 --- a/config/sunos5-config.py +++ b/config/sunos5-config.py @@ -69,20 +69,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE=False -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 5b9b2f9b9dc..42e56417f54 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -77,20 +77,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = False -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 04e87a23ed1..82babeb1a3a 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -90,20 +90,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = True WITH_BF_PLAYER = True -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index fcc6f1ab846..83e27a85574 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -93,20 +93,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = True WITH_BF_PLAYER = False -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 8dcace11e7d..b6cfe3b113e 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -24,11 +24,6 @@ # # ***** END GPL LICENSE BLOCK ***** -IF(WITH_GAMEENGINE) - ADD_SUBDIRECTORY(qhull) - ADD_SUBDIRECTORY(solid) -ENDIF(WITH_GAMEENGINE) - IF(WITH_BULLET) ADD_SUBDIRECTORY(bullet2) ENDIF(WITH_BULLET) diff --git a/extern/Makefile b/extern/Makefile index 8311006444f..61499da8743 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -30,7 +30,7 @@ include nan_definitions.mk SOURCEDIR = extern DIR = $(OCGDIR)/extern -DIRS = qhull/src solid glew/src +DIRS = glew/src ifeq ($(WITH_FFMPEG), true) ifeq ($(NAN_FFMPEG), $(LCGDIR)/ffmpeg) diff --git a/extern/SConscript b/extern/SConscript index 126f40b00b3..175613c3d2b 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -4,10 +4,6 @@ Import('env') SConscript(['glew/SConscript']) -if env['WITH_BF_GAMEENGINE']: - if env['WITH_BF_SOLID']: - SConscript(['qhull/SConscript', 'solid/SConscript']) - if env['WITH_BF_BULLET']: SConscript(['bullet2/src/SConscript']) diff --git a/extern/qhull/CMakeLists.txt b/extern/qhull/CMakeLists.txt deleted file mode 100644 index f2ac24afff3..00000000000 --- a/extern/qhull/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# $Id$ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -SET(INC include src) - -SET(SRC - src/geom.c - src/geom2.c - src/global.c - src/io.c - src/mem.c - src/merge.c - src/poly.c - src/poly2.c - src/qhull.c - src/qset.c - src/stat.c - src/user.c -) - -BLENDERLIB(extern_qhull "${SRC}" "${INC}") -#, libtype=['game2','player'], priority=[50, 85] diff --git a/extern/qhull/COPYING.txt b/extern/qhull/COPYING.txt deleted file mode 100644 index 1334eba6d0b..00000000000 --- a/extern/qhull/COPYING.txt +++ /dev/null @@ -1,37 +0,0 @@ - Qhull, Copyright (c) 1993-2002 - - The National Science and Technology Research Center for - Computation and Visualization of Geometric Structures - (The Geometry Center) - University of Minnesota - 400 Lind Hall - 207 Church Street S.E. - Minneapolis, MN 55455 USA - - email: qhull@geom.umn.edu - -This software includes Qhull from The Geometry Center. Qhull is -copyrighted as noted above. Qhull is free software and may be obtained -via http from www.geom.umn.edu. It may be freely copied, modified, -and redistributed under the following conditions: - -1. All copyright notices must remain intact in all files. - -2. A copy of this text file must be distributed along with any copies - of Qhull that you redistribute; this includes copies that you have - modified, or copies of programs or other software products that - include Qhull. - -3. If you modify Qhull, you must include a notice giving the - name of the person performing the modification, the date of - modification, and the reason for such modification. - -4. When distributing modified versions of Qhull, or other software - products that include Qhull, you must provide notice that the original - source code may be obtained as noted above. - -5. There is no warranty or other guarantee of fitness for Qhull, it is - provided solely "as is". Bug reports or fixes may be sent to - qhull_bug@geom.umn.edu; the authors may or may not act on them as - they desire. - diff --git a/extern/qhull/README.txt b/extern/qhull/README.txt deleted file mode 100644 index 9ef958a1f47..00000000000 --- a/extern/qhull/README.txt +++ /dev/null @@ -1,318 +0,0 @@ -Name - - qhull, rbox 2002.1 August 20, 2002 - -Convex hull, Delaunay triangulation, Voronoi diagrams, Halfspace intersection - - Documentation: - html/index.htm - - Available from: - - - - - Version 1 (simplicial only): - - - - News and a paper: - - - -Purpose - - Qhull is a general dimension convex hull program that reads a set - of points from stdin, and outputs the smallest convex set that contains - the points to stdout. It also generates Delaunay triangulations, Voronoi - diagrams, furthest-site Voronoi diagrams, and halfspace intersections - about a point. - - Rbox is a useful tool in generating input for Qhull; it generates - hypercubes, diamonds, cones, circles, simplices, spirals, - lattices, and random points. - - Qhull produces graphical output for Geomview. This helps with - understanding the output. - - -Environment requirements - - Qhull and rbox should run on all 32-bit and 64-bit computers. Use - an ANSI C or C++ compiler to compile the program. The software is - self-contained. - - Qhull is copyrighted software. Please read COPYING.txt and REGISTER.txt - before using or distributing Qhull. - -To contribute to Qhull - - Qhull is on Savannah, http://savannah.gnu.org/projects/qhull/ - -Qhull on Windows 95, 98, ME, NT, 2000, XP - - The zip file contains rbox.exe, qhull.exe, qconvex.exe, qdelaunay.exe, - qhalf.exe, qvoronoi.exe, documentation files, and source files. - - To install Qhull: - - Unzip the files into a directory. You may use WinZip32 - - Open a DOS window for the directory. - - In Windows 95, the DOS window needs improvement. - - Double-click on qhull\eg\qhull-go.bat to call doskey (arrow keys). - - Increase the size of the screen font to 8x12. - - If the text is too dim, fix the screen colors with shareware (e.g., crt.exe) - - If you use qhull a lot, consider using the Cygwin Unix shell, - Cygwin tools (http://sources.redhat.com/cygwin/) - - Execute 'qconvex' for a synopsis and examples. - - Execute 'rbox 10 | qconvex' to compute the convex hull of 10 random points. - - Execute 'rbox 10 | qconvex i TO file' to write results to 'file'. - - If an error occurs, Windows 95 sends the error to stdout instead of stderr - - use 'TO xxx' to send normal output to xxx and error output to stdout - - Browse the documentation: qhull\html\index.htm - -Compiling for Unix - - The gzip file, qhull.tgz, contains documentation and source files for - qhull and rbox. - - To unpack the gzip file - - tar zxf qhull.tgz - - cd qhull - - Compiling with the Debian Make:[R. Laboissiere] - - cd src - - ./Make-config.sh - - cd .. - - configure - - make - - Compiling with Makefile (i.e., Makefile.txt) - - cd src - - in Makefile, check the CC, CCOPTS1, PRINTMAN, and PRINTC defines - - the defaults are gcc and enscript - - CCOPTS1 should include the ANSI flag. It defines __STDC__ - - in user.h, check the definitions of qh_SECticks and qh_CPUclock. - - use '#define qh_CLOCKtype 2' for timing runs longer than 1 hour - - type: make - - this builds: qhull qconvex qdelaunay qhalf qvoronoi rbox libqhull.a - - type: make doc - - this prints the man page - - See also qhull/html/index.htm - - if your compiler reports many errors, it is probably not a ANSI C compiler - - you will need to set the -ansi switch or find another compiler - - if your compiler warns about missing prototypes for fprintf() etc. - - this is ok, your compiler should have these in stdio.h - - if your compiler warns about missing prototypes for memset() etc. - - include memory.h in qhull_a.h - - if your compiler is gcc-2.95.1, you need to set flag -fno-strict-aliasing. - - This flag is set by default for other versions [Karas, Krishnaswami] - - if your compiler reports "global.c: storage size of 'qh_qh' isn't known" - - delete the initializer "={0}" in global.c, stat.c and mem.c - - if your compiler warns about "stat.c: improper initializer" - - this is ok, the initializer is not used - - if you have trouble building libqhull.a with 'ar' - - try 'make -f Makefile.txt qhullx' - - if the code compiles, the qhull test case will automatically execute - - if an error occurs, there's an incompatibility between machines - - For gcc-2.95.1, you need to set flag -fno-strict-aliasing. - It is set by default for other versions of gcc [Karas, Krishnaswami] - - If you can, try a different compiler - - You can turn off the Qhull memory manager with qh_NOmem in mem.h - - You can turn off compiler optimization (-O2 in Makefile) - - If you find the source of the problem, please let us know - - if you have Geomview (www.geomview.org) - - try 'rbox 100 | qconvex G >a' and load 'a' into Geomview - - run 'q_eg' for Geomview examples of Qhull output (see qh-eg.htm) - - to install the programs and their man pages: - - define MANDIR and BINDIR - - type 'make install' - -Compiling for Windows NT, 2000, XP with cygwin (www.cygwin.com) - - - install cygwin with gcc, make, ar, and ln - - cd qhull/src - - make -f Makefile.txt - -Compiling for Windows 95, 98, NT, 2000, XP - - Qhull compiles as a console application in Visual C++ 5.0 at warning - level 3. - - Visual C++ quickstart for qhull.exe: - - create a "Win32 console application" called "qhull" - - add the following files: - geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhull.c - qset.c stat.c unix.c user.c - - create a "Win32 console application" called "rbox" - - add rbox.c - - Visual C++ quickstart for qhull library, qconvex.exe, etc. - - To simplify setting up lots of projects, - - create a temporary "Win32 console application" called "source" - - add all .c files from .../src/... - - In Tools::Options::Tab - Set tab size to 8 and indent size to 2 - - - create a "Win32 console application" called "rbox" - - move rbox.c from "qhull source" - - for Project:Settings..., Link - you only need the default libraries - - build the project - - - create a "Win32 static library" called "library" - - move these files from "qhull source" - geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhull.c - qset.c stat.c user.c - - set the library file (use the same for debug and release) - - build the project - - - create a "Win32 console application" called "qhull" - - move unix.c from "qhull source" - - Set the library file in Project:Settings..., Link - - Qhull does not use other libraries - - - create a "Win32 console application" called "qconvex" - - move qconvex.c from "qhull source" - - Set the library file in Project:Settings..., Link - - - do the same for qdelaun.c, qhalf, qvoronoi.c, user_eg.c, user_eg2.c - - delete "qhull sources" since it is no longer needed - - Set the library file in Project:Settings..., Link - - use Project:Settings to make any changes - - use batch build to rebuild everything - - Qhull compiles with Borland C++ 5.0 bcc32. A Makefile is included. - Execute 'make -f MBorland'. If you use the Borland IDE, set the ANSI - option in Options:Project:Compiler:Source:Language-compliance. - - Qhull compiles with Borland C++ 4.02 for Win32 and DOS Power Pack. - Use 'make -f MBorland -D_DPMI'. Qhull 1.0 compiles with Borland - C++ 4.02. For rbox 1.0, use "bcc32 -WX -w- -O2-e -erbox -lc rbox.c". - Use the same options for Qhull 1.0. [D. Zwick] - - Qhull compiles with Metrowerks C++ 1.7 with the ANSI option. - - If you turn on full warnings, the compiler will report a number of - unused variables, variables set but not used, and dead code. These are - intentional. For example, variables may be initialized (unnecessarily) - to prevent warnings about possible use of uninitialized variables. - -Compiling for the Power Macintosh - - Qhull compiles for the Power Macintosh with Metrowerk's C compiler. - It uses the SIOUX interface to read point coordinates and return output. - There is no graphical output. For project files, see 'Compiling for - Windows 95'. Instead of using SIOUX, Qhull may be embedded within an - application. - - Version 1 is available for Macintosh computers by download of qhull.sit.hqx - It reads point coordinates from a standard file and returns output - to a standard file. There is no graphical output. - - -Compiling for other machines - - Some users have reported problems with compiling Qhull under Irix 5.1. It - compiles under other versions of Irix. - - If you have troubles with the memory manager, you can turn it off by - defining qh_NOmem in mem.h. - - You may compile Qhull with a C++ compiler. - - -Distributed files - - README.txt // instructions for installing Qhull - REGISTER.txt // Qhull registration - COPYING.txt // copyright notice - Announce.txt // announcement - Changes.txt // change history for Qhull and rbox - qh-faq.htm // Frequently asked questions - qh-home.htm // Home page - qh-get.htm // Download page - html/index.htm // Manual - Makefile.txt // Makefile for Unix or cygwin 'make' - MBorland // Makefile for Borland C++/Win32 - Make-config.sh // Create Debian configure and automake - -src/ - rbox consists of: - rbox.exe // Win32 executable (.zip only) - rbox.htm // html manual - rbox.man // Unix man page - rbox.txt - rbox.c // source program - - qhull consists of: - qhull.exe // Win32 executables (.zip only) - qconvex.exe - qdelaunay.exe - qhalf.exe - qvoronoi.exe - qhull-go.bat // DOS window - qconvex.htm // html manuals - qdelaun.htm - qdelau_f.htm - qhalf.htm - qvoronoi.htm - qvoron_f.htm - qh-eg.htm - qh-impre.htm - qh-in.htm - index.htm - qh-opt*.htm - qh-quick.htm - qh--4d.gif,etc. // images for manual - qhull.man // Unix man page - qhull.txt - q_eg // shell script for Geomview examples - q_egtest // shell script for Geomview test examples - q_test // shell script to test qhull - - top-level source files: - src/index.htm // index to source files - qh-...htm // specific files - user.h // header file of user definable constants - qhull.h // header file for qhull - unix.c // Unix front end to qhull - qhull.c // Quickhull algorithm with partitioning - user.c // user re-definable functions - user_eg.c // example of incorporating qhull into a user program - user_eg2.c // more complex example - qhull_interface.cpp // call Qhull from C++ - - other source files: - qhull_a.h // include file for *.c - geom.c // geometric routines - geom2.c - geom.h - global.c // global variables - io.c // input-output routines - io.h - mem.c // memory routines, this is stand-alone code - mem.h - merge.c // merging of non-convex facets - merge.h - poly.c // polyhedron routines - poly2.c - poly.h - qset.c // set routines, this only depends on mem.c - qset.h - stat.c // statistics - stat.h - -Authors: - - C. Bradford Barber Hannu Huhdanpaa - bradb@geom.umn.edu hannu@geom.umn.edu - - c/o The Geometry Center - University of Minnesota - 400 Lind Hall - 207 Church Street S.E. - Minneapolis, MN 55455 - - This software was developed under NSF grants NSF/DMS-8920161 and - NSF-CCR-91-15793 750-7504 at the Geometry Center and Harvard - University. If you find Qhull useful, please let us know. diff --git a/extern/qhull/REGISTER.txt b/extern/qhull/REGISTER.txt deleted file mode 100644 index 767eb1c0cda..00000000000 --- a/extern/qhull/REGISTER.txt +++ /dev/null @@ -1,37 +0,0 @@ -Dear User of Geometry Center Software: - -We would like to find out how you are using our software. Think of -Geometry Center software as a new kind of shareware: you share your -science and successes with us, and we share our software and support -with you. - -If you use Geometry Center software, please send us a note telling -us what you are doing with it. - -We need to know: - - (1) What you are working on - an abstract of your work would be - fine. - - (2) What Geometry Center software you use. - - (3) How that software has helped you, for example, by increasing - your productivity or allowing you to do things you could not do - before. In particular, if you feel that Geometry Center - software has had a direct bearing on your work, please tell us - about this. - -We encourage you to cite the use of any Geometry Center software you -have used in your publications. - -To cite Qhull, use - - Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull - algorithm for convex hulls," ACM Trans. on Mathematical Software, - Dec 1996. http://www.geom.umn.edu/software/qhull - -Please send e-mail to - - qhull@geom.umn.edu - -Thank you! diff --git a/extern/qhull/SConscript b/extern/qhull/SConscript deleted file mode 100644 index d3db67cddc0..00000000000 --- a/extern/qhull/SConscript +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python -import sys -import os - -Import('env') -defs = '' -cflags = [] -if sys.platform=='linux2' or sys.platform=='linux-i386': - cflags += ['-O2','-ansi'] -elif env['OURPLATFORM']=='win32-vc': - cflags += ['/O2'] -elif env['OURPLATFORM']=='win32-mingw': - cflags += ['-O2'] -elif sys.platform=='sunos5': - cflags += ['-O2', '-ansi'] -elif sys.platform=='darwin': - cflags += ['-O2', '-pipe', '-fPIC', '-funsigned-char', '-ffast-math'] - -sources = ['src/geom.c', - 'src/geom2.c', - 'src/global.c', - 'src/io.c', - 'src/mem.c', - 'src/merge.c', - 'src/poly.c', - 'src/poly2.c', - 'src/qhull.c', - 'src/qset.c', - 'src/stat.c', - 'src/user.c'] - - -incs = 'include src' - -env.BlenderLib ( 'extern_qhull', sources, Split(incs), Split(defs), libtype=['extern'], priority=[50], compileflags = cflags) diff --git a/extern/qhull/VisualC6/qhull.dsw b/extern/qhull/VisualC6/qhull.dsw deleted file mode 100644 index 96c68d8e34c..00000000000 --- a/extern/qhull/VisualC6/qhull.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "qhull"=".\qhull\qhull.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/extern/qhull/VisualC6/qhull/qhull.dsp b/extern/qhull/VisualC6/qhull/qhull.dsp deleted file mode 100644 index 6e059b0994c..00000000000 --- a/extern/qhull/VisualC6/qhull/qhull.dsp +++ /dev/null @@ -1,192 +0,0 @@ -# Microsoft Developer Studio Project File - Name="qhull" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=qhull - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "qhull.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "qhull.mak" CFG="qhull - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "qhull - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "qhull - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "qhull - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -LINK32=cwlink.exe -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=XCOPY /Y ..\..\include\qhull\*.h ..\..\..\..\..\lib\windows\qhull\include\qhull\ XCOPY /Y Release\*.lib ..\..\..\..\..\lib\windows\qhull\lib\ -# End Special Build Tool - -!ELSEIF "$(CFG)" == "qhull - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -LINK32=cwlink.exe -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MT /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=XCOPY /Y ..\..\include\qhull\*.h ..\..\..\..\..\lib\windows\qhull\include\qhull\ XCOPY /Y Debug\*.lib ..\..\..\..\..\lib\windows\qhull\lib\Debug\ -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "qhull - Win32 Release" -# Name "qhull - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\geom.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\geom2.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\global.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\io.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mem.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\merge.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\poly.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\poly2.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\qhull.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\qset.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\stat.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\user.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\src\geom.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\io.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\mem.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\merge.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\poly.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\qhull.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\qhull_a.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\qset.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\stat.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\user.h -# End Source File -# End Group -# End Target -# End Project diff --git a/extern/qhull/include/qhull/geom.h b/extern/qhull/include/qhull/geom.h deleted file mode 100644 index 32440cff56f..00000000000 --- a/extern/qhull/include/qhull/geom.h +++ /dev/null @@ -1,177 +0,0 @@ -/*
  ---------------------------------
-
-  geom.h 
-    header file for geometric routines
-
-   see qh-geom.htm and geom.c
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#ifndef qhDEFgeom
-#define qhDEFgeom 1
-
-/* ============ -macros- ======================== */
-
-/*----------------------------------
-   
-  fabs_(a)
-    returns the absolute value of a
-*/
-#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
-               
-/*----------------------------------
-  
-  fmax_(a,b)
-    returns the maximum value of a and b
-*/
-#define fmax_( a,b )  ( ( a ) < ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  fmin_(a,b)
-    returns the minimum value of a and b
-*/
-#define fmin_( a,b )  ( ( a ) > ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  maximize_(maxval, val)
-    set maxval to val if val is greater than maxval
-*/
-#define maximize_( maxval, val ) {if (( maxval ) < ( val )) ( maxval )= ( val );}
-
-/*----------------------------------
-
-  minimize_(minval, val)
-    set minval to val if val is less than minval
-*/
-#define minimize_( minval, val ) {if (( minval ) > ( val )) ( minval )= ( val );}
-
-/*----------------------------------
-
-  det2_(a1, a2,     
-        b1, b2)
-  
-    compute a 2-d determinate
-*/
-#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
-
-/*----------------------------------
-  
-  det3_(a1, a2, a3,    
-       b1, b2, b3,
-       c1, c2, c3)
-  
-    compute a 3-d determinate
-*/
-#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
-                - ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
-
-/*----------------------------------
-  
-  dX( p1, p2 )
-  dY( p1, p2 )
-  dZ( p1, p2 )
-  
-    given two indices into rows[],
-
-    compute the difference between X, Y, or Z coordinates
-*/
-#define dX( p1,p2 )  ( *( rows[p1] ) - *( rows[p2] ))
-#define dY( p1,p2 )  ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
-#define dZ( p1,p2 )  ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
-#define dW( p1,p2 )  ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
-
-/*============= prototypes in alphabetical order, infrequent at end ======= */
-
-void    qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
-void	qh_distplane (pointT *point, facetT *facet, realT *dist);
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT isnewfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbesthorizon (boolT ischeckmax, pointT *point, 
-	             facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet, realT *dist, 
-		     boolT bestoutside, boolT *isoutside, int *numpart);
-void 	qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
-realT   qh_getangle(pointT *vect1, pointT *vect2);
-pointT *qh_getcenter(setT *vertices);
-pointT *qh_getcentrum(facetT *facet);
-realT   qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
-void    qh_normalize (coordT *normal, int dim, boolT toporient);
-void    qh_normalize2 (coordT *normal, int dim, boolT toporient, 
-            realT *minnorm, boolT *ismin);
-pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist);
-
-void    qh_setfacetplane(facetT *newfacets);
-void 	qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 
-              boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
-void 	qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, 
-	     boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
-boolT   qh_sharpnewfacets (void);
-
-/*========= infrequently used code in geom2.c =============*/
-
-
-coordT *qh_copypoints (coordT *points, int numpoints, int dimension);
-void    qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
-realT 	qh_determinant (realT **rows, int dim, boolT *nearzero);
-realT   qh_detjoggle (pointT *points, int numpoints, int dimension);
-void    qh_detroundoff (void);
-realT   qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero);
-realT   qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp);
-realT   qh_distround (int dimension, realT maxabs, realT maxsumabs);
-realT   qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
-realT   qh_facetarea (facetT *facet);
-realT   qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, 
-          vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset);
-pointT *qh_facetcenter (setT *vertices);
-facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
-void    qh_getarea (facetT *facetlist);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-boolT   qh_inthresholds (coordT *normal, realT *angle);
-void    qh_joggleinput (void);
-realT  *qh_maxabsval (realT *normal, int dim);
-setT   *qh_maxmin(pointT *points, int numpoints, int dimension);
-realT   qh_maxouter (void);
-void    qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
-realT   qh_minabsval (realT *normal, int dim);
-int     qh_mindiff (realT *vecA, realT *vecB, int dim);
-boolT   qh_orientoutside (facetT *facet);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-coordT  qh_pointdist(pointT *point1, pointT *point2, int dim);
-void    qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol);
-void    qh_printpoints (FILE *fp, char *string, setT *points);
-void    qh_projectinput (void);
-void 	qh_projectpoints (signed char *project, int n, realT *points, 
-             int numpoints, int dim, realT *newpoints, int newdim);
-int     qh_rand( void);
-void    qh_srand( int seed);
-realT   qh_randomfactor (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_rotatepoints (realT *points, int numpoints, int dim, realT **rows);
-void    qh_scaleinput (void);
-void    qh_scalelast (coordT *points, int numpoints, int dim, coordT low,
-		   coordT high, coordT newhigh);
-void 	qh_scalepoints (pointT *points, int numpoints, int dim,
-  		realT *newlows, realT *newhighs);
-boolT   qh_sethalfspace (int dim, coordT *coords, coordT **nextp, 
-              coordT *normal, coordT *offset, coordT *feasible);
-coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-pointT *qh_voronoi_center (int dim, setT *points);
-
-#endif /* qhDEFgeom */
-
-
-
diff --git a/extern/qhull/include/qhull/io.h b/extern/qhull/include/qhull/io.h
deleted file mode 100644
index 351d56b3708..00000000000
--- a/extern/qhull/include/qhull/io.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
  ---------------------------------
-
-   io.h 
-   declarations of Input/Output functions
-
-   see README, qhull.h and io.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFio
-#define qhDEFio 1
-
-/*============ constants and flags ==================*/
-
-/*----------------------------------
-  
-  qh_MAXfirst
-    maximum length of first two lines of stdin
-*/
-#define qh_MAXfirst  200
-
-/*----------------------------------
-  
-  qh_MINradius
-    min radius for Gp and Gv, fraction of maxcoord
-*/
-#define qh_MINradius 0.02
-
-/*----------------------------------
-  
-  qh_GEOMepsilon
-    adjust outer planes for 'lines closer' and geomview roundoff.  
-    This prevents bleed through.
-*/
-#define qh_GEOMepsilon 2e-3
-
-/*----------------------------------
-  
-  qh_WHITESPACE
-    possible values of white space
-*/
-#define qh_WHITESPACE " \n\t\v\r\f"
-
-
-/*----------------------------------
-  
-  qh_RIDGE
-    to select which ridges to print in qh_eachvoronoi
-*/
-typedef enum
-{
-    qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
-}
-qh_RIDGE;
-
-/*----------------------------------
-  
-  printvridgeT
-    prints results of qh_printvdiagram
-
-  see:
-    qh_printvridge for an example
-*/
-typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-
-/*============== -prototypes in alphabetical order =========*/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void    qh_countfacets (facetT *facetlist, setT *facets, boolT printall, 
-              int *numfacetsp, int *numsimplicialp, int *totneighborsp, 
-              int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
-pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
-setT   *qh_detvridge (vertexT *vertex);
-setT   *qh_detvridge3 (vertexT *atvertex, vertexT *vertex);
-int     qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
-int     qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder);
-void	qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-void    qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane);
-void    qh_markkeep (facetT *facetlist);
-setT   *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp);
-void    qh_order_vertexneighbors(vertexT *vertex);
-void	qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall);
-void    qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void 	qh_printcenter (FILE *fp, int format, char *string, facetT *facet);
-void    qh_printcentrum (FILE *fp, facetT *facet, realT radius);
-void    qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printend4geom (FILE *fp, facetT *facet, int *num, boolT printall);
-void    qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void	qh_printfacet(FILE *fp, facetT *facet);
-void	qh_printfacet2math(FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]);
-void    qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
-			       facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3math (FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3vertex(FILE *fp, facetT *facet, int format);
-void	qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int format);
-void	qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format);
-void    qh_printfacetheader(FILE *fp, facetT *facet);
-void    qh_printfacetridges(FILE *fp, facetT *facet);
-void	qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void	qh_printhelp_degenerate(FILE *fp);
-void	qh_printhelp_singular(FILE *fp);
-void	qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
-  		   setT *vertices, realT color[3]);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void    qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
-void	qh_printpoint(FILE *fp, char *string, pointT *point);
-void	qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id);
-void    qh_printpoint3 (FILE *fp, pointT *point);
-void    qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
-void    qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
-void	qh_printridge(FILE *fp, ridgeT *ridge);
-void    qh_printspheres(FILE *fp, setT *vertices, realT radius);
-void    qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-int     qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
-void	qh_printvertex(FILE *fp, vertexT *vertex);
-void	qh_printvertexlist (FILE *fp, char* string, facetT *facetlist,
-                         setT *facets, boolT printall);
-void	qh_printvertices (FILE *fp, char* string, setT *vertices);
-void    qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall);
-void    qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void    qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void	qh_produce_output(void);
-void    qh_projectdim3 (pointT *source, pointT *destination);
-int     qh_readfeasible (int dim, char *remainder);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-void    qh_setfeasible (int dim);
-boolT	qh_skipfacet(facetT *facet);
-
-#endif /* qhDEFio */
diff --git a/extern/qhull/include/qhull/mem.h b/extern/qhull/include/qhull/mem.h
deleted file mode 100644
index e9ebd1bb9bc..00000000000
--- a/extern/qhull/include/qhull/mem.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
  ---------------------------------
-
-   mem.h 
-     prototypes for memory management functions
-
-   see qh-mem.htm, mem.c and qset.h
-
-   for error handling, writes message and calls
-     qh_errexit (qhmem_ERRmem, NULL, NULL) if insufficient memory
-       and
-     qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmem
-#define qhDEFmem
-
-/*---------------------------------
-  
-  qh_NOmem
-    turn off quick-fit memory allocation
-
-  notes:
-    mem.c implements Quickfit memory allocation for about 20% time
-    savings.  If it fails on your machine, try to locate the
-    problem, and send the answer to qhull@geom.umn.edu.  If this can
-    not be done, define qh_NOmem to use malloc/free instead.
-
-   #define qh_NOmem
-*/
-
-/*-------------------------------------------
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers.  If gcc is available, 
-    use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
-
-   see qh_MEMalign in user.h for qhull's alignment
-*/
-
-#define qhmem_ERRmem 4    /* matches qh_ERRmem in qhull.h */
-#define qhmem_ERRqhull 5  /* matches qh_ERRqhull in qhull.h */
-
-/*----------------------------------
-  
-  ptr_intT
-    for casting a void* to an integer-type
-  
-  notes:
-    On 64-bit machines, a pointer may be larger than an 'int'.  
-    qh_meminit() checks that 'long' holds a 'void*'
-*/
-typedef unsigned long ptr_intT;
-
-/*----------------------------------
- 
-  qhmemT
-    global memory structure for mem.c
- 
- notes:
-   users should ignore qhmem except for writing extensions
-   qhmem is allocated in mem.c 
-   
-   qhmem could be swapable like qh and qhstat, but then
-   multiple qh's and qhmem's would need to keep in synch.  
-   A swapable qhmem would also waste memory buffers.  As long
-   as memory operations are atomic, there is no problem with
-   multiple qh structures being active at the same time.
-   If you need separate address spaces, you can swap the
-   contents of qhmem.
-*/
-typedef struct qhmemT qhmemT;
-extern qhmemT qhmem; 
-
-struct qhmemT {               /* global memory management variables */
-  int      BUFsize;	      /* size of memory allocation buffer */
-  int      BUFinit;	      /* initial size of memory allocation buffer */
-  int      TABLEsize;         /* actual number of sizes in free list table */
-  int      NUMsizes;          /* maximum number of sizes in free list table */
-  int      LASTsize;          /* last size in free list table */
-  int      ALIGNmask;         /* worst-case alignment, must be 2^n-1 */
-  void	 **freelists;          /* free list table, linked by offset 0 */
-  int     *sizetable;         /* size of each freelist */
-  int     *indextable;        /* size->index table */
-  void    *curbuffer;         /* current buffer, linked by offset 0 */
-  void    *freemem;           /*   free memory in curbuffer */
-  int 	   freesize;          /*   size of free memory in bytes */
-  void 	  *tempstack;         /* stack of temporary memory, managed by users */
-  FILE    *ferr;              /* file for reporting errors */
-  int      IStracing;         /* =5 if tracing memory allocations */
-  int      cntquick;          /* count of quick allocations */
-                              /* remove statistics doesn't effect speed */
-  int      cntshort;          /* count of short allocations */
-  int      cntlong;           /* count of long allocations */
-  int      curlong;           /* current count of inuse, long allocations */
-  int      freeshort;	      /* count of short memfrees */
-  int      freelong;	      /* count of long memfrees */
-  int      totshort;          /* total size of short allocations */
-  int      totlong;           /* total size of long allocations */
-  int      maxlong;           /* maximum totlong */
-  int      cntlarger;         /* count of setlarger's */
-  int      totlarger;         /* total copied by setlarger */
-};
-
-
-/*==================== -macros ====================*/
-
-/*----------------------------------
-   
-  qh_memalloc_(size, object, type)  
-    returns object of size bytes 
-	assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-
-#ifdef qh_NOmem
-#define qh_memalloc_(size, freelistp, object, type) {\
-  object= (type*)qh_memalloc (size); }
-#else /* !qh_NOmem */
-
-#define qh_memalloc_(size, freelistp, object, type) {\
-  freelistp= qhmem.freelists + qhmem.indextable[size];\
-  if ((object= (type*)*freelistp)) {\
-    qhmem.cntquick++;  \
-    *freelistp= *((void **)*freelistp);\
-  }else object= (type*)qh_memalloc (size);}
-#endif
-
-/*----------------------------------
-   
-  qh_memfree_(object, size) 
-    free up an object
-
-  notes:
-    object may be NULL
-    assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-#ifdef qh_NOmem
-#define qh_memfree_(object, size, freelistp) {\
-  qh_memfree (object, size); }
-#else /* !qh_NOmem */
-
-#define qh_memfree_(object, size, freelistp) {\
-  if (object) { \
-    qhmem .freeshort++;\
-    freelistp= qhmem.freelists + qhmem.indextable[size];\
-    *((void **)object)= *freelistp;\
-    *freelistp= object;}}
-#endif
-
-/*=============== prototypes in alphabetical order ============*/
-
-void *qh_memalloc(int insize);
-void qh_memfree (void *object, int size);
-void qh_memfreeshort (int *curlong, int *totlong);
-void qh_meminit (FILE *ferr);
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes,
-			int bufsize, int bufinit);
-void qh_memsetup (void);
-void qh_memsize(int size);
-void qh_memstatistics (FILE *fp);
-
-#endif /* qhDEFmem */
diff --git a/extern/qhull/include/qhull/merge.h b/extern/qhull/include/qhull/merge.h
deleted file mode 100644
index 7fc2afa5967..00000000000
--- a/extern/qhull/include/qhull/merge.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
  ---------------------------------
-
-   merge.h 
-   header file for merge.c
-
-   see qh-merge.htm and merge.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmerge
-#define qhDEFmerge 1
-
-
-/*============ -constants- ==============*/
-
-/*----------------------------------
-
-  qh_ANGLEredundant
-    indicates redundant merge in mergeT->angle
-*/
-#define qh_ANGLEredundant 6.0
-
-/*----------------------------------
-  
-  qh_ANGLEdegen
-    indicates degenerate facet in mergeT->angle
-*/
-#define qh_ANGLEdegen     5.0
-
-/*----------------------------------
-  
-  qh_ANGLEconcave
-    offset to indicate concave facets in mergeT->angle
-  
-  notes:
-    concave facets are assigned the range of [2,4] in mergeT->angle
-    roundoff error may make the angle less than 2
-*/
-#define qh_ANGLEconcave  1.5
-
-/*----------------------------------
-  
-  MRG... (mergeType)
-    indicates the type of a merge (mergeT->type)
-*/
-typedef enum {	/* in sort order for facet_mergeset */
-  MRGnone= 0,
-  MRGcoplanar,		/* centrum coplanar */
-  MRGanglecoplanar,	/* angle coplanar */
-  			/* could detect half concave ridges */
-  MRGconcave,		/* concave ridge */
-  MRGflip,		/* flipped facet. facet1 == facet2 */
-  MRGridge,		/* duplicate ridge (qh_MERGEridge) */
-                        /* degen and redundant go onto degen_mergeset */
-  MRGdegen,		/* degenerate facet (not enough neighbors) facet1 == facet2 */
-  MRGredundant,		/* redundant facet (vertex subset) */
-  			/* merge_degenredundant assumes degen < redundant */
-  MRGmirror,	        /* mirror facet from qh_triangulate */
-  ENDmrg
-} mergeType;
-
-/*----------------------------------
-  
-  qh_MERGEapex
-    flag for qh_mergefacet() to indicate an apex merge  
-*/
-#define qh_MERGEapex     True
-
-/*============ -structures- ====================*/
-
-/*----------------------------------
-     
-  mergeT
-    structure used to merge facets
-*/
-
-typedef struct mergeT mergeT;
-struct mergeT {		/* initialize in qh_appendmergeset */
-  realT   angle;        /* angle between normals of facet1 and facet2 */
-  facetT *facet1; 	/* will merge facet1 into facet2 */
-  facetT *facet2;
-  mergeType type;
-};
-
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-     
-  FOREACHmerge_( merges ) {...}
-    assign 'merge' to each merge in merges
-       
-  notes:
-    uses 'mergeT *merge, **mergep;'
-    if qh_mergefacet(),
-      restart since qh.facet_mergeset may change
-    see FOREACHsetelement_
-*/
-#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
-
-/*============ prototypes in alphabetical order after pre/postmerge =======*/
-
-void    qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle);
-void    qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-             boolT vneighbors);
-void    qh_all_merges (boolT othermerge, boolT vneighbors);
-void    qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
-setT   *qh_basevertices( facetT *samecycle);
-void    qh_checkconnect (void /* qh new_facets */);
-boolT   qh_checkzero (boolT testall);
-void    qh_copynonconvex (ridgeT *atridge);
-void    qh_degen_redundant_facet (facetT *facet);
-void   	qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet);
-vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges);
-void    qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor,
-           facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
-facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
-void 	qh_flippedmerges(facetT *facetlist, boolT *wasmerge);
-void 	qh_forcedmerges( boolT *wasmerge);
-void	qh_getmergeset(facetT *facetlist);
-void 	qh_getmergeset_initial (facetT *facetlist);
-void    qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
-ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, 
-              vertexT *vertex, vertexT *oldvertex, int *hashslot);
-void 	qh_makeridges(facetT *facet);
-void    qh_mark_dupridges(facetT *facetlist);
-void    qh_maydropneighbor (facetT *facet);
-int     qh_merge_degenredundant (void);
-void    qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype);
-void    qh_mergecycle (facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_all (facetT *facetlist, boolT *wasmerge);
-void    qh_mergecycle_facets( facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet);
-void 	qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
-void    qh_mergefacet2d (facetT *facet1, facetT *facet2);
-void 	qh_mergeneighbors(facetT *facet1, facetT *facet2);
-void 	qh_mergeridges(facetT *facet1, facetT *facet2);
-void    qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex);
-void    qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2);
-void    qh_mergevertex_neighbors(facetT *facet1, facetT *facet2);
-void	qh_mergevertices(setT *vertices1, setT **vertices);
-setT   *qh_neighbor_intersections (vertexT *vertex);
-void    qh_newvertices (setT *vertices);
-boolT   qh_reducevertices (void);
-vertexT *qh_redundant_vertex (vertexT *vertex);
-boolT   qh_remove_extravertices (facetT *facet);
-vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet);
-void	qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
-void    qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges,
-			facetT *oldfacet, facetT *neighborA);
-boolT 	qh_test_appendmerge (facetT *facet, facetT *neighbor);
-boolT   qh_test_vneighbors (void /* qh newfacet_list */);
-void    qh_tracemerge (facetT *facet1, facetT *facet2);
-void    qh_tracemerging (void);
-void    qh_updatetested( facetT *facet1, facetT *facet2);
-setT   *qh_vertexridges (vertexT *vertex);
-void    qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges);
-void    qh_willdelete (facetT *facet, facetT *replace);
-
-#endif /* qhDEFmerge */
diff --git a/extern/qhull/include/qhull/poly.h b/extern/qhull/include/qhull/poly.h
deleted file mode 100644
index 294ec9527fc..00000000000
--- a/extern/qhull/include/qhull/poly.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
  ---------------------------------
-
-   poly.h 
-   header file for poly.c and poly2.c
-
-   see qh-poly.htm, qhull.h and poly.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFpoly
-#define qhDEFpoly 1
-
-/*===============   constants ========================== */
-
-/*----------------------------------
-  
-  ALGORITHMfault   
-    use as argument to checkconvex() to report errors during buildhull
-*/
-#define qh_ALGORITHMfault 0
-
-/*----------------------------------
-  
-  DATAfault        
-    use as argument to checkconvex() to report errors during initialhull
-*/
-#define qh_DATAfault 1
-
-/*----------------------------------
-  
-  DUPLICATEridge
-    special value for facet->neighbor to indicate a duplicate ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_DUPLICATEridge ( facetT * ) 1L
-
-/*----------------------------------
-  
-  MERGEridge       flag in facet
-    special value for facet->neighbor to indicate a merged ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_MERGEridge ( facetT * ) 2L
-
-
-/*============ -structures- ====================*/
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-  
-  FORALLfacet_( facetlist ) { ... }
-    assign 'facet' to each facet in facetlist
-    
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-    
-  see:
-    FORALLfacets
-*/
-#define FORALLfacet_( facetlist ) if ( facetlist ) for( facet=( facetlist );facet && facet->next;facet=facet->next )
-
-/*----------------------------------
-  
-  FORALLnew_facets { ... } 
-    assign 'newfacet' to each facet in qh.newfacet_list
-    
-  notes:
-    uses 'facetT *newfacet;'
-    at exit, newfacet==NULL
-*/
-#define FORALLnew_facets for( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
-
-/*----------------------------------
-  
-  FORALLvertex_( vertexlist ) { ... }
-    assign 'vertex' to each vertex in vertexlist
-    
-  notes:
-    uses 'vertexT *vertex;'
-    at exit, vertex==NULL
-*/
-#define FORALLvertex_( vertexlist ) for ( vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
-
-/*----------------------------------
-  
-  FORALLvisible_facets { ... }
-    assign 'visible' to each visible facet in qh.visible_list
-    
-  notes:
-    uses 'vacetT *visible;'
-    at exit, visible==NULL
-*/
-#define FORALLvisible_facets for (visible=qh visible_list; visible && visible->visible; visible= visible->next)
-
-/*----------------------------------
-  
-  FORALLsame_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    stops when it returns to newfacet
-*/
-#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
-
-/*----------------------------------
-  
-  FORALLsame_cycle_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    at exit, same == NULL
-*/
-#define FORALLsame_cycle_(newfacet) \
-     for (same= newfacet->f.samecycle; \
-         same; same= (same == newfacet ?  NULL : same->f.samecycle))
-
-/*----------------------------------
-  
-  FOREACHneighborA_( facet ) { ... }
-    assign 'neighborA' to each neighbor in facet->neighbors
-  
-  FOREACHneighborA_( vertex ) { ... }
-    assign 'neighborA' to each neighbor in vertex->neighbors
-  
-  declare:
-    facetT *neighborA, **neighborAp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighborA_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighborA)
-
-/*----------------------------------
-  
-  FOREACHvisible_( facets ) { ... } 
-    assign 'visible' to each facet in facets
-    
-  notes:
-    uses 'facetT *facet, *facetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
-
-/*----------------------------------
-  
-  FOREACHnewfacet_( facets ) { ... } 
-    assign 'newfacet' to each facet in facets
-    
-  notes:
-    uses 'facetT *newfacet, *newfacetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
-
-/*----------------------------------
-  
-  FOREACHvertexA_( vertices ) { ... } 
-    assign 'vertexA' to each vertex in vertices
-    
-  notes:
-    uses 'vertexT *vertexA, *vertexAp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
-
-/*----------------------------------
-  
-  FOREACHvertexreverse12_( vertices ) { ... } 
-    assign 'vertex' to each vertex in vertices
-    reverse order of first two vertices
-    
-  notes:
-    uses 'vertexT *vertex, *vertexp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
-
-
-/*=============== prototypes poly.c in alphabetical order ================*/
-
-void    qh_appendfacet(facetT *facet);
-void    qh_appendvertex(vertexT *vertex);
-void 	qh_attachnewfacets (void);
-boolT   qh_checkflipped (facetT *facet, realT *dist, boolT allerror);
-void	qh_delfacet(facetT *facet);
-void 	qh_deletevisible(void /*qh visible_list, qh horizon_list*/);
-setT   *qh_facetintersect (facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
-unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem);
-facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet);
-void    qh_makenewplanes ( void /* newfacet_list */);
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew);
-facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew);
-void    qh_matchneighbor (facetT *newfacet, int newskip, int hashsize,
-			  int *hashcount);
-void	qh_matchnewfacets (void);
-boolT   qh_matchvertices (int firstindex, setT *verticesA, int skipA, 
-			  setT *verticesB, int *skipB, boolT *same);
-facetT *qh_newfacet(void);
-ridgeT *qh_newridge(void);
-int     qh_pointid (pointT *point);
-void 	qh_removefacet(facetT *facet);
-void 	qh_removevertex(vertexT *vertex);
-void    qh_updatevertices (void);
-
-
-/*========== -prototypes poly2.c in alphabetical order ===========*/
-
-void    qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash);
-void 	qh_check_bestdist (void);
-void    qh_check_maxout (void);
-void    qh_check_output (void);
-void    qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
-void   	qh_check_points(void);
-void 	qh_checkconvex(facetT *facetlist, int fault);
-void    qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp);
-void 	qh_checkflipped_all (facetT *facetlist);
-void 	qh_checkpolygon(facetT *facetlist);
-void    qh_checkvertex (vertexT *vertex);
-void 	qh_clearcenters (qh_CENTER type);
-void 	qh_createsimplex(setT *vertices);
-void 	qh_delridge(ridgeT *ridge);
-void    qh_delvertex (vertexT *vertex);
-setT   *qh_facet3vertex (facetT *facet);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside,
-			  int *numpart);
-int 	qh_findgood (facetT *facetlist, int goodhorizon);
-void 	qh_findgood_all (facetT *facetlist);
-void    qh_furthestnext (void /* qh facet_list */);
-void    qh_furthestout (facetT *facet);
-void    qh_infiniteloop (facetT *facet);
-void 	qh_initbuild(void);
-void 	qh_initialhull(setT *vertices);
-setT   *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints);
-vertexT *qh_isvertex (pointT *point, setT *vertices);
-vertexT *qh_makenewfacets (pointT *point /*horizon_list, visible_list*/);
-void    qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount);
-void    qh_nearcoplanar ( void /* qh.facet_list */);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-int 	qh_newhashtable(int newsize);
-vertexT *qh_newvertex(pointT *point);
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp);
-void    qh_outcoplanar (void /* facet_list */);
-pointT *qh_point (int id);
-void 	qh_point_add (setT *set, pointT *point, void *elem);
-setT   *qh_pointfacet (void /*qh facet_list*/);
-setT   *qh_pointvertex (void /*qh facet_list*/);
-void 	qh_prependfacet(facetT *facet, facetT **facetlist);
-void	qh_printhashtable(FILE *fp);
-void    qh_printlists (void);
-void    qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-void    qh_triangulate_facet (facetT *facetA, vertexT **first_vertex);
-void    qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
-void	qh_triangulate_mirror (facetT *facetA, facetT *facetB);
-void    qh_triangulate_null (facetT *facetA);
-void    qh_vertexintersect(setT **vertexsetA,setT *vertexsetB);
-setT   *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB);
-void    qh_vertexneighbors (void /*qh facet_list*/);
-boolT 	qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
-
-
-#endif /* qhDEFpoly */
diff --git a/extern/qhull/include/qhull/qhull.h b/extern/qhull/include/qhull/qhull.h
deleted file mode 100644
index 896ec1e9c18..00000000000
--- a/extern/qhull/include/qhull/qhull.h
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
  ---------------------------------
-
-   qhull.h
-   user-level header file for using qhull.a library
-
-   see qh-qhull.htm, qhull_a.h
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   NOTE: access to qh_qh is via the 'qh' macro.  This allows
-   qh_qh to be either a pointer or a structure.  An example
-   of using qh is "qh DROPdim" which accesses the DROPdim
-   field of qh_qh.  Similarly, access to qh_qhstat is via
-   the 'qhstat' macro.
-
-   includes function prototypes for qhull.c, geom.c, global.c, io.c, user.c
-
-   use mem.h for mem.c
-   use qset.h for qset.c
-
-   see unix.c for an example of using qhull.h
-
-   recompile qhull if you change this file
-*/
-
-#ifndef qhDEFqhull
-#define qhDEFqhull 1
-
-/*=========================== -included files ==============*/
-
-#include 
-#include 
-#include 
-
-#if __MWERKS__ && __POWERPC__
-#include  
-#include  
-#include	
-#endif
-
-#ifndef __STDC__
-#ifndef __cplusplus
-#if     !_MSC_VER
-#error  Neither __STDC__ nor __cplusplus is defined.  Please use strict ANSI C or C++ to compile
-#error  Qhull.  You may need to turn off compiler extensions in your project configuration.  If
-#error  your compiler is a standard C compiler, you can delete this warning from qhull.h
-#endif
-#endif
-#endif
-
-#include "user.h"      /* user defineable constants */
-
-/*============ constants and basic types ====================*/
-
-/*----------------------------------
-
-  qh_VERSION
-    version string by year and date
-
-    the revision increases on code changes only
-
-  notes:
-    change date:    Changes.txt, Announce.txt, README.txt, qhull.man
-                    qhull-news.html, Eudora signatures, 
-    change version: README.txt, qhull.html, file_id.diz, Makefile
-    change year:    Copying.txt
-    check download size
-    recompile user_eg.c, rbox.c, qhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c
-    make copy of qhull-news.html as qh-news.htm
-*/
-
-#define qh_VERSION "2002.1 2002/8/20"
-
-/*----------------------------------
-
-  coordT
-    coordinates and coefficients are stored as realT (i.e., double)
-
-  notes:
-    could use 'float' for data and 'double' for calculations (realT vs. coordT)
-      This requires many type casts, and adjusted error bounds.
-      Also C compilers may do expressions in double anyway.
-*/
-#define coordT realT
-
-/*----------------------------------
-
-  pointT
-    a point is an array of DIM3 coordinates
-*/
-#define pointT coordT
-
-/*----------------------------------
-
-  flagT
-    Boolean flag as a bit
-*/
-#define flagT unsigned int
-
-/*----------------------------------
-
-  boolT
-    boolean value, either True or False
-
-  notes:
-    needed for portability
-*/
-#define boolT unsigned int
-#ifdef False
-#undef False
-#endif
-#ifdef True
-#undef True
-#endif
-#define False 0
-#define True 1
-
-/*----------------------------------
-
-  qh_CENTER
-    to distinguish facet->center
-*/
-typedef enum
-{
-    qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum
-}
-qh_CENTER;
-
-/*----------------------------------
-
-  qh_PRINT
-    output formats for printing (qh.PRINTout).
-    'Fa' 'FV' 'Fc' 'FC' 
-       
-
-   notes:
-   some of these names are similar to qh names.  The similar names are only
-   used in switch statements in qh_printbegin() etc.
-*/
-typedef enum {qh_PRINTnone= 0, 
-  qh_PRINTarea, qh_PRINTaverage,           /* 'Fa' 'FV' 'Fc' 'FC' */
-  qh_PRINTcoplanars, qh_PRINTcentrums, 
-  qh_PRINTfacets, qh_PRINTfacets_xridge,   /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */
-  qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, 
-  qh_PRINTnormals, qh_PRINTouter,          /* 'n' 'Fo' 'i' 'm' 'Fm' 'o' */
-  qh_PRINTincidences, qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff, 
-  qh_PRINToptions, qh_PRINTpointintersect, /* 'FO' 'Fp' 'FP' 'p' 'FQ' 'FS' */
-  qh_PRINTpointnearest, qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize, 
-  qh_PRINTsummary, qh_PRINTtriangles,      /* 'Fs' 'Ft' 'Fv' 'FN' 'Fx' */
-  qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes,
-  qh_PRINTEND} qh_PRINT;
-
-/*----------------------------------
-
-  qh_ALL
-    argument flag for selecting everything
-*/
-#define qh_ALL      True
-#define qh_NOupper  True     /* argument for qh_findbest */
-#define qh_IScheckmax  True     /* argument for qh_findbesthorizon */
-#define qh_ISnewfacets  True     /* argument for qh_findbest */
-#define qh_RESETvisible  True     /* argument for qh_resetlists */
-
-/*----------------------------------
-
-  qh_ERR
-    Qhull exit codes, for indicating errors
-*/
-#define qh_ERRnone  0    /* no error occurred during qhull */
-#define qh_ERRinput 1    /* input inconsistency */
-#define qh_ERRsingular 2 /* singular input data */
-#define qh_ERRprec  3    /* precision error */
-#define qh_ERRmem   4    /* insufficient memory, matches mem.h */
-#define qh_ERRqhull 5    /* internal error detected, matches mem.h */
-
-/* ============ -structures- ====================
-   each of the following structures is defined by a typedef
-   all realT and coordT fields occur at the beginning of a structure
-        (otherwise space may be wasted due to alignment)
-   define all flags together and pack into 32-bit number
-*/
-
-typedef struct vertexT vertexT;
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;          /* defined in qset.h */
-#endif
-
-/*----------------------------------
-
-  facetT
-    defines a facet
-
-  notes:
-   qhull() generates the hull as a list of facets.
-
-  topological information:
-    f.previous,next     doubly-linked list of facets
-    f.vertices          set of vertices
-    f.ridges            set of ridges
-    f.neighbors         set of neighbors
-    f.toporient         True if facet has top-orientation (else bottom)
-
-  geometric information:
-    f.offset,normal     hyperplane equation
-    f.maxoutside        offset to outer plane -- all points inside
-    f.center            centrum for testing convexity
-    f.simplicial        True if facet is simplicial
-    f.flipped           True if facet does not include qh.interior_point
-
-  for constructing hull:
-    f.visible           True if facet on list of visible facets (will be deleted)
-    f.newfacet          True if facet on list of newly created facets
-    f.coplanarset       set of points coplanar with this facet
-                        (includes near-inside points for later testing)
-    f.outsideset        set of points outside of this facet
-    f.furthestdist      distance to furthest point of outside set
-    f.visitid           marks visited facets during a loop
-    f.replace           replacement facet for to-be-deleted, visible facets
-    f.samecycle,newcycle cycle of facets for merging into horizon facet
-
-  see below for other flags and fields
-*/
-struct facetT {
-#if !qh_COMPUTEfurthest
-  coordT   furthestdist;/* distance to furthest point of outsideset */
-#endif
-#if qh_MAXoutside
-  coordT   maxoutside;  /* max computed distance of point to facet
-  			Before QHULLfinished this is an approximation
-  			since maxdist not always set for mergefacet
-			Actual outer plane is +DISTround and
-			computed outer plane is +2*DISTround */
-#endif
-  coordT   offset;      /* exact offset of hyperplane from origin */
-  coordT  *normal;      /* normal of hyperplane, hull_dim coefficients */
-			/*   if tricoplanar, shared with a neighbor */
-  union {               /* in order of testing */
-   realT   area;        /* area of facet, only in io.c if  ->isarea */
-   facetT *replace;	/*  replacement facet if ->visible and NEWfacets
-  			     is NULL only if qh_mergedegen_redundant or interior */
-   facetT *samecycle;   /*  cycle of facets from the same visible/horizon intersection,
-   			     if ->newfacet */
-   facetT *newcycle;    /*  in horizon facet, current samecycle of new facets */ 
-   facetT *trivisible;  /* visible facet for ->tricoplanar facets during qh_triangulate() */
-   facetT *triowner;    /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
-  }f;
-  coordT  *center;      /*  centrum for convexity, qh CENTERtype == qh_AScentrum */
-      			/*  Voronoi center, qh CENTERtype == qh_ASvoronoi */
-			/*   if tricoplanar, shared with a neighbor */
-  facetT  *previous;    /* previous facet in the facet_list */
-  facetT  *next;        /* next facet in the facet_list */
-  setT    *vertices;    /* vertices for this facet, inverse sorted by ID 
-                           if simplicial, 1st vertex was apex/furthest */
-  setT    *ridges;      /* explicit ridges for nonsimplicial facets.
-  			   for simplicial facets, neighbors defines ridge */
-  setT    *neighbors;   /* neighbors of the facet.  If simplicial, the kth
-			   neighbor is opposite the kth vertex, and the first
-			   neighbor is the horizon facet for the first vertex*/
-  setT    *outsideset;  /* set of points outside this facet
-		           if non-empty, last point is furthest
-			   if NARROWhull, includes coplanars for partitioning*/
-  setT    *coplanarset; /* set of points coplanar with this facet
-  			   > qh.min_vertex and <= facet->max_outside
-                           a point is assigned to the furthest facet
-		           if non-empty, last point is furthest away */
-  unsigned visitid;     /* visit_id, for visiting all neighbors,
-			   all uses are independent */
-  unsigned id;	        /* unique identifier from qh facet_id */
-  unsigned nummerge:9;  /* number of merges */
-#define qh_MAXnummerge 511 /*     2^9-1, 32 flags total, see "flags:" in io.c */
-  flagT    tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
-			  /*   all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
-			  /*   all tricoplanars share the same apex */
-                          /*   if ->degenerate, does not span facet (one logical ridge) */
-                          /*   one tricoplanar has ->keepcentrum and ->coplanarset */
-                          /*   during qh_triangulate, f.trivisible points to original facet */
-  flagT	   newfacet:1;  /* True if facet on qh newfacet_list (new or merged) */
-  flagT	   visible:1;   /* True if visible facet (will be deleted) */
-  flagT    toporient:1; /* True if created with top orientation
-			   after merging, use ridge orientation */
-  flagT    simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
-  flagT    seen:1;      /* used to perform operations only once, like visitid */
-  flagT    seen2:1;     /* used to perform operations only once, like visitid */
-  flagT	   flipped:1;   /* True if facet is flipped */
-  flagT    upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
-  flagT    notfurthest:1; /* True if last point of outsideset is not furthest*/
-
-/*-------- flags primarily for output ---------*/
-  flagT	   good:1;      /* True if a facet marked good for output */
-  flagT    isarea:1;    /* True if facet->f.area is defined */
-
-/*-------- flags for merging ------------------*/
-  flagT    dupridge:1;  /* True if duplicate ridge in facet */
-  flagT    mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
-                            ->normal defined (also defined for mergeridge2) */
-  flagT    mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */
-  flagT    coplanar:1;  /* True if horizon facet is coplanar at last use */
-  flagT     mergehorizon:1; /* True if will merge into horizon (->coplanar) */
-  flagT	    cycledone:1;/* True if mergecycle_all already done */
-  flagT    tested:1;    /* True if facet convexity has been tested (false after merge */
-  flagT    keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
-  flagT	   newmerge:1;  /* True if facet is newly merged for reducevertices */
-  flagT	   degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
-  flagT	   redundant:1;  /* True if facet is redundant (degen_mergeset) */
-};
-
-
-/*----------------------------------
-
-  ridgeT
-    defines a ridge
-
-  notes:
-  a ridge is DIM3-1 simplex between two neighboring facets.  If the
-  facets are non-simplicial, there may be more than one ridge between
-  two facets.  E.G. a 4-d hypercube has two triangles between each pair
-  of neighboring facets.
-
-  topological information:
-    vertices            a set of vertices
-    top,bottom          neighboring facets with orientation
-
-  geometric information:
-    tested              True if ridge is clearly convex
-    nonconvex           True if ridge is non-convex
-*/
-struct ridgeT {
-  setT    *vertices;    /* vertices belonging to this ridge, inverse sorted by ID 
-                           NULL if a degen ridge (matchsame) */
-  facetT  *top;         /* top facet this ridge is part of */
-  facetT  *bottom;      /* bottom facet this ridge is part of */
-  unsigned id:24;       /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    tested:1;    /* True when ridge is tested for convexity */
-  flagT    nonconvex:1; /* True if getmergeset detected a non-convex neighbor
-			   only one ridge between neighbors may have nonconvex */
-};
-
-/*----------------------------------
-
-  vertexT
-     defines a vertex
-
-  topological information:
-    next,previous       doubly-linked list of all vertices
-    neighbors           set of adjacent facets (only if qh.VERTEXneighbors)
-
-  geometric information:
-    point               array of DIM3 coordinates
-*/
-struct vertexT {
-  vertexT *next;        /* next vertex in vertex_list */
-  vertexT *previous;    /* previous vertex in vertex_list */
-  pointT  *point;       /* hull_dim coordinates (coordT) */
-  setT    *neighbors;   /* neighboring facets of vertex, qh_vertexneighbors()
-			   inits in io.c or after first merge */
-  unsigned visitid; /* for use with qh vertex_visit */
-  unsigned id:24;   /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    seen2:1;     /* another seen flag */
-  flagT    delridge:1;  /* vertex was part of a deleted ridge */
-  flagT	   deleted:1;   /* true if vertex on qh del_vertices */
-  flagT    newlist:1;   /* true if vertex on qh newvertex_list */
-};
-
-/*======= -global variables -qh ============================*/
-
-/*----------------------------------
-
-  qh
-   all global variables for qhull are in qh, qhmem, and qhstat
-
-  notes:
-   qhmem is defined in mem.h and qhstat is defined in stat.h
-   access to qh_qh is via the "qh" macro.  See qh_QHpointer in user.h
-*/
-typedef struct qhT qhT;
-#if qh_QHpointer
-#define qh qh_qh->
-extern qhT *qh_qh;     /* allocated in global.c */
-#else
-#define qh qh_qh.
-extern qhT qh_qh;
-#endif
-
-struct qhT {
-
-/*----------------------------------
-
-  qh constants
-    configuration flags and constants for Qhull
-
-  notes:
-    The user configures Qhull by defining flags.  They are
-    copied into qh by qh_setflags().  qh-quick.htm#options defines the flags.
-*/
-  boolT ALLpoints;        /* true 'Qs' if search all points for initial simplex */
-  boolT ANGLEmerge;	  /* true 'Qa' if sort potential merges by angle */
-  boolT APPROXhull;       /* true 'Wn' if MINoutside set */
-  realT MINoutside;       /*   'Wn' min. distance for an outside point */
-  boolT ATinfinity;       /* true 'Qz' if point num_points-1 is "at-infinity"
-                             for improving precision in Delaunay triangulations */
-  boolT AVOIDold;         /* true 'Q4' if avoid old->new merges */
-  boolT BESToutside;      /* true 'Qf' if partition points into best outsideset */
-  boolT CDDinput;         /* true 'Pc' if input uses CDD format (1.0/offset first) */
-  boolT CDDoutput;        /* true 'PC' if print normals in CDD format (offset first) */
-  boolT CHECKfrequently;  /* true 'Tc' if checking frequently */
-  realT premerge_cos;     /*   'A-n'   cos_max when pre merging */
-  realT postmerge_cos;    /*   'An'    cos_max when post merging */
-  boolT DELAUNAY;         /* true 'd' if computing DELAUNAY triangulation */
-  boolT DOintersections;  /* true 'Gh' if print hyperplane intersections */
-  int   DROPdim;          /* drops dim 'GDn' for 4-d -> 3-d output */
-  boolT FORCEoutput;      /* true 'Po' if forcing output despite degeneracies */
-  int   GOODpoint;        /* 1+n for 'QGn', good facet if visible/not(-) from point n*/
-  pointT *GOODpointp;     /*   the actual point */
-  boolT GOODthreshold;    /* true if qh lower_threshold/upper_threshold defined
-  			     false if qh SPLITthreshold */
-  int   GOODvertex;       /* 1+n, good facet if vertex for point n */
-  pointT *GOODvertexp;     /*   the actual point */
-  boolT HALFspace;        /* true 'Hn,n,n' if halfspace intersection */
-  int   IStracing;        /* trace execution, 0=none, 1=least, 4=most, -1=events */
-  int   KEEParea;         /* 'PAn' number of largest facets to keep */
-  boolT KEEPcoplanar;     /* true 'Qc' if keeping nearest facet for coplanar points */
-  boolT KEEPinside;       /* true 'Qi' if keeping nearest facet for inside points
-			      set automatically if 'd Qc' */
-  int   KEEPmerge;        /* 'PMn' number of facets to keep with most merges */
-  realT KEEPminArea;      /* 'PFn' minimum facet area to keep */
-  realT MAXcoplanar;      /* 'Un' max distance below a facet to be coplanar*/
-  boolT MERGEexact;	  /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */
-  boolT MERGEindependent; /* true 'Q2' if merging independent sets */
-  boolT MERGING;          /* true if exact-, pre- or post-merging, with angle and centrum tests */
-  realT   premerge_centrum;  /*   'C-n' centrum_radius when pre merging.  Default is round-off */
-  realT   postmerge_centrum; /*   'Cn' centrum_radius when post merging.  Default is round-off */
-  boolT MERGEvertices;	  /* true 'Q3' if merging redundant vertices */
-  realT MINvisible;       /* 'Vn' min. distance for a facet to be visible */
-  boolT NOnarrow;         /* true 'Q10' if no special processing for narrow distributions */
-  boolT NOnearinside;     /* true 'Q8' if ignore near-inside points when partitioning */
-  boolT NOpremerge;       /* true 'Q0' if no defaults for C-0 or Qx */
-  boolT ONLYgood; 	  /* true 'Qg' if process points with good visible or horizon facets */
-  boolT ONLYmax; 	  /* true 'Qm' if only process points that increase max_outside */
-  boolT PICKfurthest;     /* true 'Q9' if process furthest of furthest points*/
-  boolT POSTmerge;        /* true if merging after buildhull (Cn or An) */
-  boolT PREmerge;         /* true if merging during buildhull (C-n or A-n) */
-  			/* NOTE: some of these names are similar to qh_PRINT names */
-  boolT PRINTcentrums;	  /* true 'Gc' if printing centrums */
-  boolT PRINTcoplanar;    /* true 'Gp' if printing coplanar points */
-  int	PRINTdim;      	  /* print dimension for Geomview output */
-  boolT PRINTdots;        /* true 'Ga' if printing all points as dots */
-  boolT PRINTgood;        /* true 'Pg' if printing good facets */
-  boolT PRINTinner;	  /* true 'Gi' if printing inner planes */
-  boolT PRINTneighbors;	  /* true 'PG' if printing neighbors of good facets */
-  boolT PRINTnoplanes;	  /* true 'Gn' if printing no planes */
-  boolT PRINToptions1st;  /* true 'FO' if printing options to stderr */
-  boolT PRINTouter;	  /* true 'Go' if printing outer planes */
-  boolT PRINTprecision;   /* false 'Pp' if not reporting precision problems */
-  qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */
-  boolT PRINTridges;      /* true 'Gr' if print ridges */
-  boolT PRINTspheres;     /* true 'Gv' if print vertices as spheres */
-  boolT PRINTstatistics;  /* true 'Ts' if printing statistics to stderr */
-  boolT PRINTsummary;     /* true 's' if printing summary to stderr */
-  boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */
-  boolT PROJECTdelaunay;  /* true if DELAUNAY, no readpoints() and
-			     need projectinput() for Delaunay in qh_init_B */
-  int   PROJECTinput;     /* number of projected dimensions 'bn:0Bn:0' */
-  boolT QUICKhelp;	  /* true if quick help message for degen input */
-  boolT RANDOMdist;       /* true if randomly change distplane and setfacetplane */
-  realT RANDOMfactor;     /*    maximum random perturbation */
-  realT RANDOMa;         /*  qh_randomfactor is randr * RANDOMa + RANDOMb */
-  realT RANDOMb;
-  boolT RANDOMoutside;    /* true if select a random outside point */
-  int	REPORTfreq;       /* buildtracing reports every n facets */
-  int   REPORTfreq2;	  /* tracemerging reports every REPORTfreq/2 facets */
-  int	RERUN;            /* 'TRn' rerun qhull n times (qh.build_cnt) */
-  int	ROTATErandom;	  /* 'QRn' seed, 0 time, >= rotate input */
-  boolT SCALEinput;       /* true 'Qbk' if scaling input */
-  boolT SCALElast;        /* true 'Qbb' if scale last coord to max prev coord */
-  boolT SETroundoff;      /* true 'E' if qh DISTround is predefined */
-  boolT SKIPcheckmax;	  /* true 'Q5' if skip qh_check_maxout */
-  boolT SKIPconvex;       /* true 'Q6' if skip convexity testing during pre-merge */
-  boolT SPLITthresholds;  /* true if upper_/lower_threshold defines a region
-                               used only for printing (not for qh ONLYgood) */
-  int	STOPcone;         /* 'TCn' 1+n for stopping after cone for point n*/
-			  /*       also used by qh_build_withresart for err exit*/
-  int	STOPpoint;        /* 'TVn' 'TV-n' 1+n for stopping after/before(-)
-			                adding point n */
-  int	TESTpoints;	  /* 'QTn' num of test points after qh.num_points.  Test points always coplanar. */
-  boolT TESTvneighbors;   /*  true 'Qv' if test vertex neighbors at end */
-  int   TRACElevel;       /* 'Tn' conditional IStracing level */
-  int	TRACElastrun;	  /*  qh.TRACElevel applies to last qh.RERUN */
-  int   TRACEpoint;       /* 'TPn' start tracing when point n is a vertex */
-  realT TRACEdist;        /* 'TWn' start tracing when merge distance too big */
-  int   TRACEmerge;       /* 'TMn' start tracing before this merge */
-  boolT TRIangulate;	  /* true 'Qt' if triangulate non-simplicial facets */
-  boolT TRInormals;	  /* true 'Q11' if triangulate duplicates normals (sets Qt) */
-  boolT UPPERdelaunay;    /* true 'Qu' if computing furthest-site Delaunay */
-  boolT VERIFYoutput;     /* true 'Tv' if verify output at end of qhull */
-  boolT VIRTUALmemory;    /* true 'Q7' if depth-first processing in buildhull */
-  boolT VORONOI;	  /* true 'v' if computing Voronoi diagram */
-
-  /*--------input constants ---------*/
-  realT AREAfactor;       /* 1/(hull_dim-1)! for converting det's to area */
-  boolT DOcheckmax;       /* true if calling qh_check_maxout (qh_initqhull_globals) */
-  char	*feasible_string;  /* feasible point 'Hn,n,n' for halfspace intersection */
-  coordT *feasible_point;  /*    as coordinates, both malloc'd */
-  boolT GETarea;          /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io.c */
-  boolT KEEPnearinside;   /* true if near-inside points in coplanarset */
-  int 	hull_dim;         /* dimension of hull, set by initbuffers */
-  int 	input_dim;	  /* dimension of input, set by initbuffers */
-  int 	num_points;       /* number of input points */
-  pointT *first_point;    /* array of input points, see POINTSmalloc */
-  boolT POINTSmalloc;     /*   true if qh first_point/num_points allocated */
-  pointT *input_points;   /* copy of original qh.first_point for input points for qh_joggleinput */
-  boolT input_malloc;     /* true if qh input_points malloc'd */
-  char 	qhull_command[256];/* command line that invoked this program */
-  char 	rbox_command[256]; /* command line that produced the input points */
-  char  qhull_options[512];/* descriptive list of options */
-  int   qhull_optionlen;  /*    length of last line */
-  int   qhull_optionsiz;  /*     size of qhull_options before qh_initbuild */
-  boolT VERTEXneighbors;  /* true if maintaining vertex neighbors */
-  boolT ZEROcentrum;      /* true if 'C-0' or 'C-0 Qx'.  sets ZEROall_ok */
-  realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k]
-                             must set either GOODthreshold or SPLITthreshold
-  			     if Delaunay, default is 0.0 for upper envelope */
-  realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */
-  realT *upper_bound;     /* scale point[k] to new upper bound */
-  realT *lower_bound;     /* scale point[k] to new lower bound
-  			     project if both upper_ and lower_bound == 0 */
-
-/*----------------------------------
-
-  qh precision constants
-    precision constants for Qhull
-
-  notes:
-    qh_detroundoff() computes the maximum roundoff error for distance
-    and other computations.  It also sets default values for the
-    qh constants above.
-*/
-  realT ANGLEround;       /* max round off error for angles */
-  realT centrum_radius;   /* max centrum radius for convexity (roundoff added) */
-  realT cos_max;	  /* max cosine for convexity (roundoff added) */
-  realT DISTround;        /* max round off error for distances, 'E' overrides */
-  realT MAXabs_coord;     /* max absolute coordinate */
-  realT MAXlastcoord;     /* max last coordinate for qh_scalelast */
-  realT MAXsumcoord;      /* max sum of coordinates */
-  realT MAXwidth;         /* max rectilinear width of point coordinates */
-  realT MINdenom_1;       /* min. abs. value for 1/x */
-  realT MINdenom;         /*    use divzero if denominator < MINdenom */
-  realT MINdenom_1_2;     /* min. abs. val for 1/x that allows normalization */
-  realT MINdenom_2;       /*    use divzero if denominator < MINdenom_2 */
-  realT MINlastcoord;     /* min. last coordinate for qh_scalelast */
-  boolT NARROWhull;       /* set in qh_initialhull if angle < qh_MAXnarrow */
-  realT *NEARzero;        /* hull_dim array for near zero in gausselim */
-  realT NEARinside;       /* keep points for qh_check_maxout if close to facet */
-  realT ONEmerge;         /* max distance for merging simplicial facets */
-  realT outside_err;      /* application's epsilon for coplanar points
-                             qh_check_bestdist() qh_check_points() reports error if point outside */
-  realT WIDEfacet;        /* size of wide facet for skipping ridge in
-			     area computation and locking centrum */
-  
-/*----------------------------------
-
-  qh internal constants
-    internal constants for Qhull
-*/
-  char qhull[sizeof("qhull")]; /* for checking ownership */
-  void *old_stat;         /* pointer to saved qh_qhstat, qh_save_qhull */
-  jmp_buf errexit;        /* exit label for qh_errexit, defined by setjmp() */
-  char jmpXtra[40];       /* extra bytes in case jmp_buf is defined wrong by compiler */
-  jmp_buf restartexit;    /* restart label for qh_errexit, defined by setjmp() */
-  char jmpXtra2[40];      /* extra bytes in case jmp_buf is defined wrong by compiler*/
-  FILE *fin;              /* pointer to input file, init by qh_meminit */
-  FILE *fout;             /* pointer to output file */
-  FILE *ferr;             /* pointer to error file */
-  pointT *interior_point; /* center point of the initial simplex*/
-  int   normal_size;      /* size in bytes for facet normals and point coords*/
-  int   center_size;      /* size in bytes for Voronoi centers */
-  int   TEMPsize;         /* size for small, temporary sets (in quick mem) */
-
-/*----------------------------------
-
-  qh facet and vertex lists
-    defines lists of facets, new facets, visible facets, vertices, and
-    new vertices.  Includes counts, next ids, and trace ids.
-  see:
-    qh_resetlists()
-*/
-  facetT *facet_list;     /* first facet */
-  facetT  *facet_tail;     /* end of facet_list (dummy facet) */
-  facetT *facet_next;     /* next facet for buildhull()
-    			     previous facets do not have outside sets
-                             NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
-  facetT *newfacet_list;  /* list of new facets to end of facet_list */
-  facetT *visible_list;   /* list of visible facets preceeding newfacet_list,
-                             facet->visible set */
-  int       num_visible;  /* current number of visible facets */
-  unsigned tracefacet_id;  /* set at init, then can print whenever */
-  facetT *tracefacet;     /*   set in newfacet/mergefacet, undone in delfacet*/
-  unsigned tracevertex_id;  /* set at buildtracing, can print whenever */
-  vertexT *tracevertex;     /*   set in newvertex, undone in delvertex*/
-  vertexT *vertex_list;     /* list of all vertices, to vertex_tail */
-  vertexT  *vertex_tail;    /*      end of vertex_list (dummy vertex) */
-  vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
-                             all vertices have 'newlist' set */
-  int 	num_facets;	  /* number of facets in facet_list
-			     includes visble faces (num_visible) */
-  int 	num_vertices;     /* number of vertices in facet_list */
-  int   num_outside;      /* number of points in outsidesets (for tracing and RANDOMoutside)
-                               includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
-  int   num_good;         /* number of good facets (after findgood_all) */
-  unsigned facet_id;      /* ID of next, new facet from newfacet() */
-  unsigned ridge_id;      /* ID of next, new ridge from newridge() */
-  unsigned vertex_id;     /* ID of next, new vertex from newvertex() */
-
-/*----------------------------------
-
-  qh global variables
-    defines minimum and maximum distances, next visit ids, several flags,
-    and other global variables.
-    initialize in qh_initbuild or qh_maxmin if used in qh_buildhull
-*/
-  unsigned long hulltime; /* ignore time to set up input and randomize */
-                          /*   use unsigned to avoid wrap-around errors */
-  boolT ALLOWrestart;     /* true if qh_precision can use qh.restartexit */
-  int   build_cnt;        /* number of calls to qh_initbuild */
-  qh_CENTER CENTERtype;   /* current type of facet->center, qh_CENTER */
-  int 	furthest_id;      /* pointid of furthest point, for tracing */
-  facetT *GOODclosest;    /* closest facet to GOODthreshold in qh_findgood */
-  realT JOGGLEmax;        /* set 'QJn' if randomly joggle input */
-  boolT maxoutdone;       /* set qh_check_maxout(), cleared by qh_addpoint() */
-  realT max_outside;      /* maximum distance from a point to a facet,
-			       before roundoff, not simplicial vertices
-			       actual outer plane is +DISTround and
-			       computed outer plane is +2*DISTround */
-  realT max_vertex;       /* maximum distance (>0) from vertex to a facet,
-			       before roundoff, due to a merge */
-  realT min_vertex;       /* minimum distance (<0) from vertex to a facet,
-			       before roundoff, due to a merge
-			       if qh.JOGGLEmax, qh_makenewplanes sets it
-  			       recomputed if qh.DOcheckmax, default -qh.DISTround */
-  boolT NEWfacets;        /* true while visible facets invalid due to new or merge
-			      from makecone/attachnewfacets to deletevisible */
-  boolT findbestnew;	  /* true if partitioning calls qh_findbestnew */
-  boolT findbest_notsharp; /* true if new facets are at least 90 degrees */
-  boolT NOerrexit;        /* true if qh.errexit is not available */
-  realT PRINTcradius;     /* radius for printing centrums */
-  realT PRINTradius;      /* radius for printing vertex spheres and points */
-  boolT POSTmerging;      /* true when post merging */
-  int 	printoutvar;	  /* temporary variable for qh_printbegin, etc. */
-  int 	printoutnum;	  /* number of facets printed */
-  boolT QHULLfinished;    /* True after qhull() is finished */
-  realT totarea;          /* 'FA': total facet area computed by qh_getarea */
-  realT totvol;           /* 'FA': total volume computed by qh_getarea */
-  unsigned int visit_id;  /* unique ID for searching neighborhoods, */
-  unsigned int vertex_visit; /* unique ID for searching vertices */
-  boolT ZEROall_ok;       /* True if qh_checkzero always succeeds */
-  boolT WAScoplanar;      /* True if qh_partitioncoplanar (qh_check_maxout) */
-  
-/*----------------------------------
-
-  qh global sets
-    defines sets for merging, initial simplex, hashing, extra input points,
-    and deleted vertices
-*/
-  setT *facet_mergeset;   /* temporary set of merges to be done */
-  setT *degen_mergeset;   /* temporary set of degenerate and redundant merges */
-  setT *hash_table;	  /* hash table for matching ridges in qh_matchfacets
-                             size is setsize() */
-  setT *other_points;     /* additional points (first is qh interior_point) */
-  setT *del_vertices;     /* vertices to partition and delete with visible
-                             facets.  Have deleted set for checkfacet */
-
-/*----------------------------------
-
-  qh global buffers
-    defines buffers for maxtrix operations, input, and error messages
-*/
-  coordT *gm_matrix;      /* (dim+1)Xdim matrix for geom.c */
-  coordT **gm_row;        /* array of gm_matrix rows */
-  char* line;             /* malloc'd input line of maxline+1 chars */
-  int maxline;
-  coordT *half_space;     /* malloc'd input array for halfspace (qh normal_size+coordT) */
-  coordT *temp_malloc;    /* malloc'd input array for points */
-  
-/*----------------------------------
-
-  qh static variables
-    defines static variables for individual functions
-
-  notes:
-    do not use 'static' within a function.  Multiple instances of qhull
-    may exist.
-
-    do not assume zero initialization, 'QPn' may cause a restart
-*/
-  boolT ERREXITcalled;    /* true during errexit (prevents duplicate calls */
-  boolT firstcentrum; 	  /* for qh_printcentrum */
-  realT last_low;         /* qh_scalelast parameters for qh_setdelaunay */
-  realT last_high;
-  realT last_newhigh;
-  unsigned lastreport;    /* for qh_buildtracing */
-  int mergereport;        /* for qh_tracemerging */
-  boolT old_randomdist;   /* save RANDOMdist when io, tracing, or statistics */
-  int   ridgeoutnum;      /* number of ridges in 4OFF output */
-  void *old_qhstat;       /* for saving qh_qhstat in save_qhull() */
-  setT *old_tempstack;     /* for saving qhmem.tempstack in save_qhull */
-  setT *coplanarset;      /* set of coplanar facets for searching qh_findbesthorizon() */
-};
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-
-  otherfacet_(ridge, facet)
-    return neighboring facet for a ridge in facet
-*/
-#define otherfacet_(ridge, facet) \
-                        (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
-
-/*----------------------------------
-
-  getid_(p)
-    return ID for facet, ridge, or vertex
-    return MAXINT if NULL (-1 causes type conversion error )
-*/
-#define getid_(p)       ((p) ? (p)->id : -1)
-
-/*============== FORALL macros ===================*/
-
-/*----------------------------------
-
-  FORALLfacets { ... }
-    assign 'facet' to each facet in qh.facet_list
-
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-
-  see:
-    FORALLfacet_( facetlist )
-*/
-#define FORALLfacets for (facet=qh facet_list;facet && facet->next;facet=facet->next)
-
-/*----------------------------------
-
-  FORALLpoints { ... }
-    assign 'point' to each point in qh.first_point, qh.num_points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoints FORALLpoint_(qh first_point, qh num_points)
-
-/*----------------------------------
-
-  FORALLpoint_( points, num) { ... }
-    assign 'point' to each point in points array of num points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoint_(points, num) for(point= (points), \
-      pointtemp= (points)+qh hull_dim*(num); point < pointtemp; point += qh hull_dim)
-
-/*----------------------------------
-
-  FORALLvertices { ... }
-    assign 'vertex' to each vertex in qh.vertex_list
-
-  declare:
-    vertexT *vertex;
-
-  notes:
-    assumes qh.vertex_list terminated with a sentinel
-*/
-#define FORALLvertices for (vertex=qh vertex_list;vertex && vertex->next;vertex= vertex->next)
-
-/*----------------------------------
-
-  FOREACHfacet_( facets ) { ... }
-    assign 'facet' to each facet in facets
-
-  declare:
-    facetT *facet, **facetp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHfacet_(facets)    FOREACHsetelement_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_( facet ) { ... }
-    assign 'neighbor' to each neighbor in facet->neighbors
-
-  FOREACHneighbor_( vertex ) { ... }
-    assign 'neighbor' to each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor, **neighborp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighbor_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_( points ) { ... }
-    assign 'point' to each point in points set
-
-  declare:
-    pointT *point, **pointp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHpoint_(points)    FOREACHsetelement_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_( ridges ) { ... }
-    assign 'ridge' to each ridge in ridges set
-
-  declare:
-    ridgeT *ridge, **ridgep;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHridge_(ridges)    FOREACHsetelement_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_( vertices ) { ... }
-    assign 'vertex' to each vertex in vertices set
-
-  declare:
-    vertexT *vertex, **vertexp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
-
-/*----------------------------------
-
-  FOREACHfacet_i_( facets ) { ... }
-    assign 'facet' and 'facet_i' for each facet in facets set
-
-  declare:
-    facetT *facet;
-    int     facet_n, facet_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHfacet_i_(facets)    FOREACHsetelement_i_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_i_( facet ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
-
-  FOREACHneighbor_i_( vertex ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor;
-    int     neighbor_n, neighbor_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHneighbor_i_(facet)  FOREACHsetelement_i_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_i_( points ) { ... }
-    assign 'point' and 'point_i' for each point in points set
-
-  declare:
-    pointT *point;
-    int     point_n, point_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHpoint_i_(points)    FOREACHsetelement_i_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_i_( ridges ) { ... }
-    assign 'ridge' and 'ridge_i' for each ridge in ridges set
-
-  declare:
-    ridgeT *ridge;
-    int     ridge_n, ridge_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHridge_i_(ridges)    FOREACHsetelement_i_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_i_( vertices ) { ... }
-    assign 'vertex' and 'vertex_i' for each vertex in vertices set
-
-  declare:
-    vertexT *vertex;
-    int     vertex_n, vertex_i;
-
-  see:
-    FOREACHsetelement_i_
- */
-#define FOREACHvertex_i_(vertices) FOREACHsetelement_i_(vertexT, vertices,vertex)
-
-/********* -qhull.c prototypes (duplicated from qhull_a.h) **********************/
-
-void    qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void	qh_printsummary(FILE *fp);
-
-/********* -user.c prototypes (alphabetical) **********************/
-
-void 	qh_errexit(int exitcode, facetT *facet, ridgeT *ridge);
-void 	qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
-int     qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc,
-		char *qhull_cmd, FILE *outfile, FILE *errfile);
-void    qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall);
-void 	qh_user_memsizes (void);
-
-/***** -geom.c/geom2.c prototypes (duplicated from geom.h) ****************/
-
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT newfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet,
-                     realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-void	qh_printsummary(FILE *fp);
-void    qh_projectinput (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_scaleinput (void);
-void    qh_setdelaunay (int dim, int count, pointT *points);
-coordT  *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-
-/***** -global.c prototypes (alphabetical) ***********************/
-
-unsigned long qh_clock (void);
-void 	qh_checkflags (char *command, char *hiddenflags);
-void 	qh_freebuffers (void);
-void    qh_freeqhull (boolT allmem);
-void    qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
-void    qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_init_qhull_command (int argc, char *argv[]);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_initflags (char *command);
-void 	qh_initqhull_buffers (void);
-void 	qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc);
-void    qh_initqhull_mem (void);
-void 	qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile);
-void 	qh_initthresholds (char *command);
-void    qh_option (char *option, int *i, realT *r);
-#if qh_QHpointer
-void 	qh_restore_qhull (qhT **oldqh);
-qhT    *qh_save_qhull (void);
-#endif
-
-/***** -io.c prototypes (duplicated from io.h) ***********************/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void	qh_produce_output(void);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-
-
-/********* -mem.c prototypes (duplicated from mem.h) **********************/
-
-void qh_meminit (FILE *ferr);
-void qh_memfreeshort (int *curlong, int *totlong);
-
-/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/
-
-void    qh_check_output (void);
-void    qh_check_points (void);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-pointT *qh_point (int id);
-setT   *qh_pointfacet (void /*qh.facet_list*/);
-int     qh_pointid (pointT *point);
-setT   *qh_pointvertex (void /*qh.facet_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-
-/********* -stat.c prototypes (duplicated from stat.h) **********************/
-
-void    qh_collectstatistics (void);
-void    qh_printallstatistics (FILE *fp, char *string);
-
-#endif /* qhDEFqhull */
diff --git a/extern/qhull/include/qhull/qhull_a.h b/extern/qhull/include/qhull/qhull_a.h
deleted file mode 100644
index d4e69b071be..00000000000
--- a/extern/qhull/include/qhull/qhull_a.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
  ---------------------------------
-
-   qhull_a.h 
-   all header files for compiling qhull
-
-   see qh-qhull.htm
-
-   see qhull.h for user-level definitions
-   
-   see user.h for user-defineable constants
-   
-   defines internal functions for qhull.c global.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   Notes:  grep for ((" and (" to catch fprintf("lkasdjf");
-           full parens around (x?y:z)
-	   use '#include qhull/qhull_a.h' to avoid name clashes
-*/
-
-#ifndef qhDEFqhulla
-#define qhDEFqhulla
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include     /* some compilers will not need float.h */
-#include 
-#include 
-#include 
-/*** uncomment here and qset.c
-     if string.h does not define memcpy()
-#include 
-*/
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-#include "geom.h"
-#include "merge.h"
-#include "poly.h"
-#include "io.h"
-#include "stat.h"
-
-#if qh_CLOCKtype == 2  /* defined in user.h from qhull.h */
-#include 
-#include 
-#include 
-#endif
-
-#ifdef _MSC_VER  /* Microsoft Visual C++ */
-#pragma warning( disable : 4056)  /* float constant expression.  Looks like a compiler bug */
-#pragma warning( disable : 4146)  /* unary minus applied to unsigned type */
-#pragma warning( disable : 4244)  /* conversion from 'unsigned long' to 'real' */
-#pragma warning( disable : 4305)  /* conversion from 'const double' to 'float' */
-#endif
-
-/* ======= -macros- =========== */
-
-/*----------------------------------
-  
-  traceN((fp.ferr, "format\n", vars));  
-    calls fprintf if qh.IStracing >= N
-  
-  notes:
-    removing tracing reduces code size but doesn't change execution speed
-*/
-#ifndef qh_NOtrace
-#define trace0(args) {if (qh IStracing) fprintf args;}
-#define trace1(args) {if (qh IStracing >= 1) fprintf args;}
-#define trace2(args) {if (qh IStracing >= 2) fprintf args;}
-#define trace3(args) {if (qh IStracing >= 3) fprintf args;}
-#define trace4(args) {if (qh IStracing >= 4) fprintf args;}
-#define trace5(args) {if (qh IStracing >= 5) fprintf args;}
-#else /* qh_NOtrace */
-#define trace0(args) {}
-#define trace1(args) {}
-#define trace2(args) {}
-#define trace3(args) {}
-#define trace4(args) {}
-#define trace5(args) {}
-#endif /* qh_NOtrace */
-
-/***** -qhull.c prototypes (alphabetical after qhull) ********************/
-
-void 	qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void 	qh_buildhull(void);
-void    qh_buildtracing (pointT *furthest, facetT *facet);
-void    qh_build_withrestart (void);
-void 	qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet);
-void    qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
-pointT *qh_nextfurthest (facetT **visible);
-void 	qh_partitionall(setT *vertices, pointT *points,int npoints);
-void    qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist);
-void    qh_partitionpoint (pointT *point, facetT *facet);
-void 	qh_partitionvisible(boolT allpoints, int *numpoints);
-void    qh_precision (char *reason);
-void	qh_printsummary(FILE *fp);
-
-/***** -global.c internal prototypes (alphabetical) ***********************/
-
-void    qh_appendprint (qh_PRINT format);
-void 	qh_freebuild (boolT allmem);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-int     qh_strtol (const char *s, char **endp);
-double  qh_strtod (const char *s, char **endp);
-
-/***** -stat.c internal prototypes (alphabetical) ***********************/
-
-void	qh_allstatA (void);
-void	qh_allstatB (void);
-void	qh_allstatC (void);
-void	qh_allstatD (void);
-void	qh_allstatE (void);
-void	qh_allstatE2 (void);
-void	qh_allstatF (void);
-void	qh_allstatG (void);
-void	qh_allstatH (void);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-
-#endif /* qhDEFqhulla */
diff --git a/extern/qhull/include/qhull/qset.h b/extern/qhull/include/qhull/qset.h
deleted file mode 100644
index 6c0ff758de4..00000000000
--- a/extern/qhull/include/qhull/qset.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
  ---------------------------------
-
-   qset.h
-     header file for qset.c that implements set
-
-   see qh-set.htm and qset.c
-   
-   only uses mem.c, malloc/free
-
-   for error handling, writes message and calls
-      qh_errexit (qhmem_ERRqhull, NULL, NULL);
-   
-   set operations satisfy the following properties:
-    - sets have a max size, the actual size (if different) is stored at the end
-    - every set is NULL terminated
-    - sets may be sorted or unsorted, the caller must distinguish this
-   
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFset
-#define qhDEFset 1
-
-/*================= -structures- ===============*/
-
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;   /* a set is a sorted or unsorted array of pointers */
-#endif
-
-/*------------------------------------------
-   
-setT
-  a set or list of pointers with maximum size and actual size.
-
-variations:
-  unsorted, unique   -- a list of unique pointers with NULL terminator
-  			   user guarantees uniqueness
-  sorted	     -- a sorted list of unique pointers with NULL terminator
-  			   qset.c guarantees uniqueness
-  unsorted           -- a list of pointers terminated with NULL
-  indexed  	     -- an array of pointers with NULL elements 
-
-structure for set of n elements:
-
-	--------------
-	|  maxsize 
-	--------------
-	|  e[0] - a pointer, may be NULL for indexed sets
-	--------------
-	|  e[1]
-	
-	--------------
-	|  ...
-	--------------
-	|  e[n-1]
-	--------------
-	|  e[n] = NULL
-	--------------
-	|  ...
-	--------------
-	|  e[maxsize] - n+1 or NULL (determines actual size of set)
-	--------------
-
-*/
-
-/*-- setelemT -- internal type to allow both pointers and indices
-*/
-typedef union setelemT setelemT;
-union setelemT {
-  void    *p;
-  int      i;         /* integer used for e[maxSize] */
-};
-
-struct setT {
-  int maxsize;          /* maximum number of elements (except NULL) */
-  setelemT e[1];        /* array of pointers, tail is NULL */
-                        /* last slot (unless NULL) is actual size+1 
-                           e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
-                        /* this may generate a warning since e[] contains
-			   maxsize elements */
-};
-
-/*=========== -constants- =========================*/
-
-/*-------------------------------------
-   
-  SETelemsize
-    size of a set element in bytes
-*/
-#define SETelemsize sizeof(setelemT) 
-
-
-/*=========== -macros- =========================*/
-
-/*-------------------------------------
-   
-   FOREACHsetelement_(type, set, variable)
-     define FOREACH iterator
-
-   declare:  
-     assumes *variable and **variablep are declared
-     no space in "variable)" [DEC Alpha cc compiler]
-
-   each iteration:
-     variable is set element
-     variablep is one beyond variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-
-   example:  
-     #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
-
-   notes:
-     use FOREACHsetelement_i_() if need index or include NULLs
-
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[0].p); \
-	  (variable= *variable##p++);)
-
-/*------------------------------------------
-
-   FOREACHsetelement_i_(type, set, variable)
-     define indexed FOREACH iterator
-
-   declare:  
-     type *variable, variable_n, variable_i;
-
-   each iteration:
-     variable is set element, may be NULL
-     variable_i is index, variable_n is qh_setsize()
-
-   to repeat an element:
-     variable_i--; variable_n-- repeats for deleted element
-
-   at exit:
-     variable==NULL and variable_i==variable_n
-
-   example:
-     #define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet )
-   
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_i_(type, set, variable) \
-        if (((variable= NULL), set)) for (\
-          variable##_i= 0, variable= (type *)((set)->e[0].p), \
-                   variable##_n= qh_setsize(set);\
-          variable##_i < variable##_n;\
-          variable= (type *)((set)->e[++variable##_i].p) )
-
-/*----------------------------------------
-
-   FOREACHsetelementreverse_(type, set, variable)- 
-     define FOREACH iterator in reverse order
-
-   declare:  
-     assumes *variable and **variablep are declared
-     also declare 'int variabletemp'
-
-   each iteration:
-     variable is set element
-
-   to repeat an element:
-     variabletemp++; / *repeat* /
-
-   at exit:
-     variable is NULL
-
-   example:
-     #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
-  
-   notes:
-     use FOREACHsetelementreverse12_() to reverse first two elements
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-	   variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\
-	   variable; variable= \
-	   ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
-
-/*-------------------------------------
-
-   FOREACHsetelementreverse12_(type, set, variable)- 
-     define FOREACH iterator with e[1] and e[0] reversed
-
-   declare:  
-     assumes *variable and **variablep are declared
-
-   each iteration:
-     variable is set element
-     variablep is one after variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-  
-   example
-     #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
-
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse12_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[1].p); \
-	  (variable= *variable##p); \
-          variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
-	      (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
-
-/*-------------------------------------
-
-   FOREACHelem_( set )- 
-     iterate elements in a set
-
-   declare:  
-     void *elem, *elemp;
-
-   each iteration:
-     elem is set element
-     elemp is one beyond
-
-   to repeat an element:
-     elemp--; / *repeat* /
-
-   at exit:
-     elem == NULL at end of loop
-  
-   example:
-     FOREACHelem_(set) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
-
-/*-------------------------------------
-
-   FOREACHset_( set )- 
-     iterate a set of sets
-
-   declare:  
-     setT *set, **setp;
-
-   each iteration:
-     set is set element
-     setp is one beyond
-
-   to repeat an element:
-     setp--; / *repeat* /
-
-   at exit:
-     set == NULL at end of loop
-  
-   example
-     FOREACHset_(sets) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
-
-/*-------------------------------------------
-
-   SETindex_( set, elem )
-     return index of elem in set
-
-   notes:   
-     for use with FOREACH iteration
-
-   example:
-     i= SETindex_(ridges, ridge)
-*/
-#define SETindex_(set, elem) ((void **)elem##p - (void **)&(set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETref_( elem )
-     l.h.s. for modifying the current element in a FOREACH iteration
-
-   example:
-     SETref_(ridge)= anotherridge;
-*/
-#define SETref_(elem) (elem##p[-1])
-
-/*-----------------------------------------
-
-   SETelem_(set, n)
-     return the n'th element of set
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-      use SETelemt_() for type cast
-*/
-#define SETelem_(set, n)           ((set)->e[n].p)
-
-/*-----------------------------------------
-
-   SETelemt_(set, n, type)
-     return the n'th element of set as a type
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-*/
-#define SETelemt_(set, n, type)    ((type*)((set)->e[n].p))
-
-/*-----------------------------------------
-
-   SETelemaddr_(set, n, type)
-     return address of the n'th element of a set
-   
-   notes:
-      assumes that n is valid [0..size] and set is defined 
-*/
-#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
-
-/*-----------------------------------------
-
-   SETfirst_(set)
-     return first element of set
-   
-*/
-#define SETfirst_(set)             ((set)->e[0].p)
-
-/*-----------------------------------------
-
-   SETfirstt_(set, type)
-     return first element of set as a type
-   
-*/
-#define SETfirstt_(set, type)      ((type*)((set)->e[0].p))
-
-/*-----------------------------------------
-
-   SETsecond_(set)
-     return second element of set
-   
-*/
-#define SETsecond_(set)            ((set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETsecondt_(set, type)
-     return second element of set as a type
-*/
-#define SETsecondt_(set, type)     ((type*)((set)->e[1].p))
-
-/*-----------------------------------------
-
-   SETaddr_(set, type)
-       return address of set's elements
-*/
-#define SETaddr_(set,type)	   ((type **)(&((set)->e[0].p)))
-
-/*-----------------------------------------
-
-   SETreturnsize_(set, size) 
-     return size of a set
-   
-   notes:
-      set must be defined
-      use qh_setsize(set) unless speed is critical
-*/
-#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
-
-/*-----------------------------------------
-
-   SETempty_(set) 
-     return true (1) if set is empty
-   
-   notes:
-      set may be NULL
-*/
-#define SETempty_(set) 	          (!set || (SETfirst_(set) ? 0:1))
-
-/*-----------------------------------------
-
-   SETtruncate_(set)
-     return first element of set
-
-   see:
-     qh_settruncate()
-   
-*/
-#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
-      set->e[size].p= NULL;}
-
-/*======= prototypes in alphabetical order ============*/
-
-void  qh_setaddsorted(setT **setp, void *elem);
-void  qh_setaddnth(setT **setp, int nth, void *newelem);
-void  qh_setappend(setT **setp, void *elem);
-void  qh_setappend_set(setT **setp, setT *setA);
-void  qh_setappend2ndlast(setT **setp, void *elem);
-void  qh_setcheck(setT *set, char *tname, int id);
-void  qh_setcompact(setT *set);
-setT *qh_setcopy(setT *set, int extra);
-void *qh_setdel(setT *set, void *elem);
-void *qh_setdellast(setT *set);
-void *qh_setdelnth(setT *set, int nth);
-void *qh_setdelnthsorted(setT *set, int nth);
-void *qh_setdelsorted(setT *set, void *newelem);
-setT *qh_setduplicate( setT *set, int elemsize);
-int   qh_setequal(setT *setA, setT *setB);
-int   qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB);
-int   qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB);
-void  qh_setfree(setT **set);
-void  qh_setfree2( setT **setp, int elemsize);
-void  qh_setfreelong(setT **set);
-int   qh_setin(setT *set, void *setelem);
-int   qh_setindex(setT *set, void *setelem);
-void  qh_setlarger(setT **setp);
-void *qh_setlast(setT *set);
-setT *qh_setnew(int size);
-setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend);
-void  qh_setprint(FILE *fp, char* string, setT *set);
-void  qh_setreplace(setT *set, void *oldelem, void *newelem);
-int   qh_setsize(setT *set);
-setT *qh_settemp(int setsize);
-void  qh_settempfree(setT **set);
-void  qh_settempfree_all(void);
-setT *qh_settemppop(void);
-void  qh_settemppush(setT *set);
-void  qh_settruncate (setT *set, int size);
-int   qh_setunique (setT **set, void *elem);
-void  qh_setzero (setT *set, int index, int size);
-
-
-#endif /* qhDEFset */
diff --git a/extern/qhull/include/qhull/stat.h b/extern/qhull/include/qhull/stat.h
deleted file mode 100644
index 1dae54ed21d..00000000000
--- a/extern/qhull/include/qhull/stat.h
+++ /dev/null
@@ -1,520 +0,0 @@
-  /*
  ---------------------------------
-
-   stat.h 
-     contains all statistics that are collected for qhull
-
-   see qh-stat.htm and stat.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   recompile qhull if you change this file
-
-   Integer statistics are Z* while real statistics are W*.  
-
-   define maydebugx to call a routine at every statistic event
-
-*/
-
-#ifndef qhDEFstat
-#define qhDEFstat 1
-
-
-/*---------------------------------
-
-  qh_KEEPstatistics
-    0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
-*/
-#ifndef qh_KEEPstatistics
-#define qh_KEEPstatistics 1
-#endif
-
-/*---------------------------------
-
-  Zxxx for integers, Wxxx for reals
-
-  notes:
-    be sure that all statistics are defined in stat.c
-      otherwise initialization may core dump
-    can pick up all statistics by:
-      grep '[zw].*_[(][ZW]' *.c >z.x
-    remove trailers with query">-
-    remove leaders with  query-replace-regexp [ ^I]+  (
-*/
-#if qh_KEEPstatistics
-enum statistics {     /* alphabetical after Z/W */
-    Zacoplanar,
-    Wacoplanarmax,
-    Wacoplanartot,
-    Zangle,
-    Wangle,
-    Wanglemax,
-    Wanglemin,
-    Zangletests,
-    Wareatot,
-    Wareamax,
-    Wareamin,
-    Zavoidold,
-    Wavoidoldmax,
-    Wavoidoldtot,
-    Zback0,
-    Zbestcentrum,
-    Zbestdist,
-    Zcentrumtests,
-    Zcheckpart,
-    Zcomputefurthest,
-    Zconcave,
-    Wconcavemax,
-    Wconcavetot,
-    Zconcaveridges,
-    Zconcaveridge,
-    Zcoplanar,
-    Wcoplanarmax,
-    Wcoplanartot,
-    Zcoplanarangle,
-    Zcoplanarcentrum,
-    Zcoplanarhorizon,
-    Zcoplanarinside,
-    Zcoplanarpart,
-    Zcoplanarridges,
-    Wcpu,
-    Zcyclefacetmax,
-    Zcyclefacettot,
-    Zcyclehorizon,
-    Zcyclevertex,
-    Zdegen,
-    Wdegenmax,
-    Wdegentot,
-    Zdegenvertex,
-    Zdelfacetdup, 
-    Zdelridge,
-    Zdelvertextot,
-    Zdelvertexmax,
-    Zdetsimplex,
-    Zdistcheck,
-    Zdistconvex,
-    Zdistgood,
-    Zdistio,
-    Zdistplane,
-    Zdiststat,
-    Zdistvertex,
-    Zdistzero,
-    Zdoc1,
-    Zdoc2,
-    Zdoc3,
-    Zdoc4,
-    Zdoc5,
-    Zdoc6,
-    Zdoc7,
-    Zdoc8,
-    Zdoc9,
-    Zdoc10,
-    Zdoc11,
-    Zdoc12,
-    Zdropdegen,
-    Zdropneighbor,
-    Zdupflip,
-    Zduplicate,
-    Wduplicatemax,
-    Wduplicatetot,
-    Zdupridge,
-    Zdupsame,
-    Zflipped, 
-    Wflippedmax, 
-    Wflippedtot, 
-    Zflippedfacets,
-    Zfindbest,
-    Zfindbestmax,
-    Zfindbesttot,
-    Zfindcoplanar,
-    Zfindfail,
-    Zfindhorizon,
-    Zfindhorizonmax,
-    Zfindhorizontot,
-    Zfindjump,
-    Zfindnew,
-    Zfindnewmax,
-    Zfindnewtot,
-    Zfindnewjump,
-    Zfindnewsharp,
-    Zgauss0,
-    Zgoodfacet,
-    Zhashlookup,
-    Zhashridge,
-    Zhashridgetest,
-    Zhashtests,
-    Zinsidevisible,
-    Zintersect,
-    Zintersectfail,
-    Zintersectmax,
-    Zintersectnum,
-    Zintersecttot,
-    Zmaxneighbors,
-    Wmaxout,
-    Wmaxoutside,
-    Zmaxridges,
-    Zmaxvertex,
-    Zmaxvertices,
-    Zmaxvneighbors,
-    Zmemfacets,
-    Zmempoints,
-    Zmemridges,
-    Zmemvertices,
-    Zmergeflipdup,
-    Zmergehorizon,
-    Zmergeinittot,
-    Zmergeinitmax,
-    Zmergeinittot2,
-    Zmergeintohorizon,
-    Zmergenew,
-    Zmergesettot,
-    Zmergesetmax,
-    Zmergesettot2,
-    Zmergesimplex,
-    Zmergevertex,
-    Wmindenom,
-    Wminvertex,
-    Zminnorm,
-    Zmultiridge,
-    Znearlysingular,
-    Zneighbor,
-    Wnewbalance,
-    Wnewbalance2,
-    Znewfacettot,
-    Znewfacetmax,
-    Znewvertex,
-    Wnewvertex,
-    Wnewvertexmax,
-    Znoarea,
-    Znonsimplicial,
-    Znowsimplicial,
-    Znotgood,
-    Znotgoodnew,
-    Znotmax,
-    Znumfacets,
-    Znummergemax,
-    Znummergetot,
-    Znumneighbors,
-    Znumridges,
-    Znumvertices,
-    Znumvisibility,
-    Znumvneighbors,
-    Zonehorizon,
-    Zpartangle,
-    Zpartcoplanar,
-    Zpartflip,
-    Zparthorizon,
-    Zpartinside,
-    Zpartition, 
-    Zpartitionall,
-    Zpartnear,
-    Zpbalance,
-    Wpbalance,
-    Wpbalance2, 
-    Zpostfacets, 
-    Zpremergetot,
-    Zprocessed,
-    Zremvertex,
-    Zremvertexdel,
-    Zrenameall,
-    Zrenamepinch,
-    Zrenameshare,
-    Zretry,
-    Wretrymax,
-    Zridge,
-    Wridge,
-    Wridgemax,
-    Zridge0,
-    Wridge0,
-    Wridge0max,
-    Zridgemid,
-    Wridgemid,
-    Wridgemidmax,
-    Zridgeok,
-    Wridgeok,
-    Wridgeokmax,
-    Zsearchpoints,
-    Zsetplane,
-    Ztestvneighbor,
-    Ztotcheck,
-    Ztothorizon,
-    Ztotmerge,
-    Ztotpartcoplanar,
-    Ztotpartition,
-    Ztotridges,
-    Ztotvertices,
-    Ztotvisible,
-    Ztricoplanar,
-    Ztricoplanarmax,
-    Ztricoplanartot,
-    Ztridegen,
-    Ztrimirror,
-    Ztrinull,
-    Wvertexmax,
-    Wvertexmin,
-    Zvertexridge,
-    Zvertexridgetot,
-    Zvertexridgemax,
-    Zvertices,
-    Zvisfacettot,
-    Zvisfacetmax,
-    Zvisvertextot,
-    Zvisvertexmax,
-    Zwidefacet,
-    Zwidevertices,
-    ZEND};
-
-/*---------------------------------
-
-  Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
-
-  notes:
-    be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
-*/
-#else
-enum statistics {     /* for zzdef etc. macros */
-  Zback0,
-  Zbestdist,
-  Zcentrumtests,
-  Zcheckpart,
-  Zconcaveridges,
-  Zcoplanarhorizon,
-  Zcoplanarpart,
-  Zcoplanarridges,
-  Zcyclefacettot,
-  Zcyclehorizon,
-  Zdelvertextot,
-  Zdistcheck,
-  Zdistconvex,
-  Zdistzero,
-  Zdoc1,
-  Zdoc2,
-  Zdoc3,
-  Zdoc11,
-  Zflippedfacets,
-  Zgauss0,
-  Zminnorm,
-  Zmultiridge,
-  Znearlysingular,
-  Wnewvertexmax,
-  Znumvisibility,
-  Zpartcoplanar,
-  Zpartition,
-  Zpartitionall,
-  Zprocessed,
-  Zretry,
-  Zridge,
-  Wridge,
-  Wridgemax,
-  Zridge0,
-  Wridge0,
-  Wridge0max,
-  Zridgemid,
-  Wridgemid,
-  Wridgemidmax,
-  Zridgeok,
-  Wridgeok,
-  Wridgeokmax,
-  Zsetplane,
-  Ztotmerge,
-    ZEND};
-#endif
-
-/*---------------------------------
-  
-  ztype
-    the type of a statistic sets its initial value.  
-
-  notes:
-    The type should be the same as the macro for collecting the statistic
-*/
-enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
-
-/*========== macros and constants =============*/
-
-/*----------------------------------
-  
-  MAYdebugx
-    define as maydebug() to be called frequently for error trapping
-*/
-#define MAYdebugx 
-
-/*----------------------------------
-  
-  zzdef_, zdef_( type, name, doc, -1)
-    define a statistic (assumes 'qhstat.next= 0;')
-
-  zdef_( type, name, doc, count)
-    define an averaged statistic
-    printed as name/count
-*/
-#define zzdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#if qh_KEEPstatistics
-#define zdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#else
-#define zdef_(type,name,doc,count)
-#endif
-
-/*----------------------------------
-  
-  zzinc_( name ), zinc_( name)
-    increment an integer statistic
-*/
-#define zzinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#if qh_KEEPstatistics
-#define zinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#else
-#define zinc_(id) {}
-#endif
-
-/*----------------------------------
-  
-  zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
-    add value to an integer or real statistic
-*/
-#define zzadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wwadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#if qh_KEEPstatistics
-#define zadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#else
-#define zadd_(id, val) {}
-#define wadd_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zzval_( name ), zval_( name ), wwval_( name )
-    set or return value of a statistic
-*/
-#define zzval_(id) ((qhstat stats[id]).i)
-#define wwval_(id) ((qhstat stats[id]).r)
-#if qh_KEEPstatistics
-#define zval_(id) ((qhstat stats[id]).i)
-#define wval_(id) ((qhstat stats[id]).r)
-#else
-#define zval_(id) qhstat tempi
-#define wval_(id) qhstat tempr
-#endif
-
-/*----------------------------------
-
-  zmax_( id, val ), wmax_( id, value )
-    maximize id with val
-*/
-#define wwmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#if qh_KEEPstatistics
-#define zmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].i,(val));}
-#define wmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#else
-#define zmax_(id, val) {}
-#define wmax_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zmin_( id, val ), wmin_( id, value )
-    minimize id with val
-*/
-#if qh_KEEPstatistics
-#define zmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].i,(val));}
-#define wmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].r,(val));}
-#else
-#define zmin_(id, val) {}
-#define wmin_(id, val) {}
-#endif
-
-/*================== stat.h types ==============*/
-
-
-/*----------------------------------
- 
-  intrealT
-    union of integer and real, used for statistics
-*/
-typedef union intrealT intrealT;    /* union of int and realT */
-union intrealT {
-    int i;
-    realT r;
-};
-
-/*----------------------------------
-  
-  qhstat
-    global data structure for statistics
-  
-  notes:
-   access to qh_qhstat is via the "qhstat" macro.  There are two choices
-   qh_QHpointer = 1     access globals via a pointer
-                        enables qh_saveqhull() and qh_restoreqhull()
-		= 0     qh_qhstat is a static data structure
-		        only one instance of qhull() can be active at a time
-			default value
-   qh_QHpointer is defined in qhull.h
-
-   allocated in stat.c
-*/
-typedef struct qhstatT qhstatT; 
-#if qh_QHpointer
-#define qhstat qh_qhstat->
-extern qhstatT *qh_qhstat;
-#else
-#define qhstat qh_qhstat.
-extern qhstatT qh_qhstat; 
-#endif
-struct qhstatT {  
-  intrealT   stats[ZEND];     /* integer and real statistics */
-  unsigned   char id[ZEND+10]; /* id's in print order */
-  char      *doc[ZEND];       /* array of documentation strings */
-  short int  count[ZEND];     /* -1 if none, else index of count to use */
-  char       type[ZEND];      /* type, see ztypes above */
-  char       printed[ZEND];   /* true, if statistic has been printed */
-  intrealT   init[ZTYPEend];  /* initial values by types, set initstatistics */
-
-  int        next;            /* next index for zdef_ */
-  int        precision;       /* index for precision problems */
-  int        vridges;         /* index for Voronoi ridges */
-  int        tempi;
-  realT      tempr;
-};
-
-/*========== function prototypes ===========*/
-
-void    qh_allstatA(void);
-void    qh_allstatB(void);
-void    qh_allstatC(void);
-void    qh_allstatD(void);
-void    qh_allstatE(void);
-void    qh_allstatE2(void);
-void    qh_allstatF(void);
-void    qh_allstatG(void);
-void    qh_allstatH(void);
-void    qh_allstatI(void);
-void    qh_allstatistics (void);
-void    qh_collectstatistics (void);
-void	qh_freestatistics (void);
-void    qh_initstatistics (void);
-boolT 	qh_newstats (int index, int *nextindex);
-boolT 	qh_nostatistic (int i);
-void    qh_printallstatistics (FILE *fp, char *string);
-void    qh_printstatistics (FILE *fp, char *string);
-void  	qh_printstatlevel (FILE *fp, int id, int start);
-void  	qh_printstats (FILE *fp, int index, int *nextindex);
-realT   qh_stddev (int num, realT tot, realT tot2, realT *ave);
-
-#endif   /* qhDEFstat */
diff --git a/extern/qhull/include/qhull/user.h b/extern/qhull/include/qhull/user.h
deleted file mode 100644
index 79558967a52..00000000000
--- a/extern/qhull/include/qhull/user.h
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
  ---------------------------------
-
-   user.h
-   user redefinable constants
-
-   see qh-user.htm.  see COPYING for copyright information.
-
-   before reading any code, review qhull.h for data structure definitions and 
-   the "qh" macro.
-*/
-
-#ifndef qhDEFuser
-#define qhDEFuser 1
-
-/*============= data types and configuration macros ==========*/
-
-/*----------------------------------
-  
-  realT
-    set the size of floating point numbers
-  
-  qh_REALdigits 
-    maximimum number of significant digits
-  
-  qh_REAL_1, qh_REAL_2n, qh_REAL_3n
-    format strings for printf
-  
-  qh_REALmax, qh_REALmin
-    maximum and minimum (near zero) values  
-  
-  qh_REALepsilon
-    machine roundoff.  Maximum roundoff error for addition and multiplication.
-    
-  notes:
-   Select whether to store floating point numbers in single precision (float)
-   or double precision (double).
-   
-   Use 'float' to save about 8% in time and 25% in space.  This is particularly
-   help if high-d where convex hulls are space limited.  Using 'float' also
-   reduces the printed size of Qhull's output since numbers have 8 digits of 
-   precision.
-   
-   Use 'double' when greater arithmetic precision is needed.  This is needed
-   for Delaunay triangulations and Voronoi diagrams when you are not merging 
-   facets.
-
-   If 'double' gives insufficient precision, your data probably includes
-   degeneracies.  If so you should use facet merging (done by default)
-   or exact arithmetic (see imprecision section of manual, qh-impre.htm).  
-   You may also use option 'Po' to force output despite precision errors.
-
-   You may use 'long double', but many format statements need to be changed
-   and you may need a 'long double' square root routine.  S. Grundmann
-   (sg@eeiwzb.et.tu-dresden.de) has done this.  He reports that the code runs 
-   much slower with little gain in precision.    
-
-   WARNING: on some machines,    int f(){realT a= REALmax;return (a == REALmax);}
-      returns False.  Use (a > REALmax/2) instead of (a == REALmax).
-
-   REALfloat =   1      all numbers are 'float' type
-             =   0      all numbers are 'double' type
-*/
-#define REALfloat 0
-
-#if (REALfloat == 1)
-#define realT float
-#define REALmax FLT_MAX
-#define REALmin FLT_MIN
-#define REALepsilon FLT_EPSILON
-#define qh_REALdigits 8   /* maximum number of significant digits */
-#define qh_REAL_1 "%6.8g "
-#define qh_REAL_2n "%6.8g %6.8g\n"
-#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
-
-#elif (REALfloat == 0)
-#define realT double
-#define REALmax DBL_MAX
-#define REALmin DBL_MIN
-#define REALepsilon DBL_EPSILON
-#define qh_REALdigits 16    /* maximum number of significant digits */
-#define qh_REAL_1 "%6.16g "
-#define qh_REAL_2n "%6.16g %6.16g\n"
-#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
-
-#else
-#error unknown float option
-#endif
-
-/*----------------------------------
-  
-  qh_CPUclock
-    define the clock() function for reporting the total time spent by Qhull
-    returns CPU ticks as a 'long int'
-    qh_CPUclock is only used for reporting the total time spent by Qhull
-
-  qh_SECticks 
-    the number of clock ticks per second
-
-  notes:
-    looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
-    to define a custom clock, set qh_CLOCKtype to 0
-
-    if your system does not use clock() to return CPU ticks, replace
-    qh_CPUclock with the corresponding function.  It is converted
-    to unsigned long to prevent wrap-around during long runs.
-   
-
-   Set qh_CLOCKtype to
-   
-     1	   	for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
-                Note:  may fail if more than 1 hour elapsed time
-
-     2	   	use qh_clock() with POSIX times() (see global.c)
-*/
-#define qh_CLOCKtype 1  /* change to the desired number */
-
-#if (qh_CLOCKtype == 1)
-
-#if defined (CLOCKS_PER_SECOND)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SECOND
-
-#elif defined (CLOCKS_PER_SEC)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SEC
-
-#elif defined (CLK_TCK)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLK_TCK
-
-#else
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks 1E6
-#endif
-
-#elif (qh_CLOCKtype == 2)
-#define qh_CPUclock    qh_clock()  /* return CPU clock */
-#define qh_SECticks 100
-
-#else /* qh_CLOCKtype == ? */
-#error unknown clock option
-#endif
-
-/*----------------------------------
-  
-  qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
-    define random number generator
-
-    qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.  
-    qh_RANDOMseed sets the random number seed for qh_RANDOMint
-
-  Set qh_RANDOMtype (default 5) to:
-    1       for random() with 31 bits (UCB)
-    2       for rand() with RAND_MAX or 15 bits (system 5)
-    3       for rand() with 31 bits (Sun)
-    4       for lrand48() with 31 bits (Solaris)
-    5       for qh_rand() with 31 bits (included with Qhull)
-  
-  notes:
-    Random numbers are used by rbox to generate point sets.  Random
-    numbers are used by Qhull to rotate the input ('QRn' option),
-    simulate a randomized algorithm ('Qr' option), and to simulate
-    roundoff errors ('Rn' option).
-
-    Random number generators differ between systems.  Most systems provide
-    rand() but the period varies.  The period of rand() is not critical
-    since qhull does not normally use random numbers.  
-
-    The default generator is Park & Miller's minimal standard random
-    number generator [CACM 31:1195 '88].  It is included with Qhull.
-
-    If qh_RANDOMmax is wrong, qhull will report a warning and Geomview 
-    output will likely be invisible.
-*/
-#define qh_RANDOMtype 5   /* *** change to the desired number *** */
-
-#if (qh_RANDOMtype == 1)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, random()/MAX */
-#define qh_RANDOMint random()
-#define qh_RANDOMseed_(seed) srandom(seed);
-
-#elif (qh_RANDOMtype == 2)
-#ifdef RAND_MAX
-#define qh_RANDOMmax ((realT)RAND_MAX)
-#else
-#define qh_RANDOMmax ((realT)32767)   /* 15 bits (System 5) */
-#endif
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-  
-#elif (qh_RANDOMtype == 3)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, Sun */
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-
-#elif (qh_RANDOMtype == 4)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, lrand38()/MAX */
-#define qh_RANDOMint lrand48()
-#define qh_RANDOMseed_(seed) srand48(seed);
-
-#elif (qh_RANDOMtype == 5)
-#define qh_RANDOMmax ((realT)2147483646UL)  /* 31 bits, qh_rand/MAX */
-#define qh_RANDOMint qh_rand()
-#define qh_RANDOMseed_(seed) qh_srand(seed);
-/* unlike rand(), never returns 0 */
-
-#else
-#error: unknown random option
-#endif
-
-/*----------------------------------
-  
-  qh_ORIENTclock
-    0 for inward pointing normals by Geomview convention
-*/
-#define qh_ORIENTclock 0 
-
-
-/*========= performance related constants =========*/
-
-/*----------------------------------
-  
-  qh_HASHfactor
-    total hash slots / used hash slots.  Must be at least 1.1.
-      
-  notes:
-    =2 for at worst 50% occupancy for qh hash_table and normally 25% occupancy
-*/
-#define qh_HASHfactor 2
-
-/*----------------------------------
-  
-  qh_VERIFYdirect
-    with 'Tv' verify all points against all facets if op count is smaller
-
-  notes:
-    if greater, calls qh_check_bestdist() instead
-*/
-#define qh_VERIFYdirect 1000000 
-
-/*----------------------------------
-  
-  qh_INITIALsearch
-     if qh_INITIALmax, search points up to this dimension
-*/
-#define qh_INITIALsearch 6
-
-/*----------------------------------
-  
-  qh_INITIALmax
-    if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
-      
-  notes:
-    from points with non-zero determinants
-    use option 'Qs' to override (much slower)
-*/
-#define qh_INITIALmax 8
-
-/*----------------------------------
-  
-  qh_JOGGLEdefault
-    default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
-
-  notes:
-    rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
-    rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
-    rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
-    rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
-    rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
-    rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
-    rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
-    rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
-    rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
-    the later have about 20 points per facet, each of which may interfere
-
-    pick a value large enough to avoid retries on most inputs
-*/
-#define qh_JOGGLEdefault 30000.0
-
-/*----------------------------------
-  
-  qh_JOGGLEincrease
-    factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
-*/
-#define qh_JOGGLEincrease 10.0
-
-/*----------------------------------
-  
-  qh_JOGGLEretry
-    if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
-
-  notes:
-    try twice at the original value in case of bad luck the first time
-*/
-#define qh_JOGGLEretry 2
-
-/*----------------------------------
-  
-  qh_JOGGLEagain
-    every following qh_JOGGLEagain, increase qh.JOGGLEmax
-
-  notes:
-    1 is OK since it's already failed qh_JOGGLEretry times
-*/
-#define qh_JOGGLEagain 1
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxincrease
-    maximum qh.JOGGLEmax due to qh_JOGGLEincrease
-    relative to qh.MAXwidth
-
-  notes:
-    qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
-*/
-#define qh_JOGGLEmaxincrease 1e-2
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxretry
-    stop after qh_JOGGLEmaxretry attempts
-*/
-#define qh_JOGGLEmaxretry 100
-
-/*========= memory constants =========*/
-
-/*----------------------------------
-  
-  qh_MEMalign
-    memory alignment for qh_meminitbuffers() in global.c
-    
-  notes:
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers. 
-
-    If using gcc, best alignment is
-              #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
-*/
-#define qh_MEMalign fmax_(sizeof(realT), sizeof(void *))
-
-/*----------------------------------
-  
-  qh_MEMbufsize
-    size of additional memory buffers
-    
-  notes:
-    used for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
-
-/*----------------------------------
-  
-  qh_MEMinitbuf
-    size of initial memory buffer
-    
-  notes:
-    use for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMinitbuf 0x20000      /* initially allocate 128K buffer */
-
-/*----------------------------------
-  
-  qh_INFINITE
-    on output, indicates Voronoi center at infinity
-*/
-#define qh_INFINITE  -10.101
-
-/*----------------------------------
-  
-  qh_DEFAULTbox
-    default box size (Geomview expects 0.5)
-*/
-#define qh_DEFAULTbox 0.5 
-
-/*======= conditional compilation ============================*/
-
-/*----------------------------------
-
-  __cplusplus
-    defined by C++ compilers
-
-  __MSC_VER
-    defined by Microsoft Visual C++
-  
-  __MWERKS__ && __POWERPC__
-    defined by Metrowerks when compiling for the Power Macintosh
-
-  __STDC__
-    defined for strict ANSI C 
-*/
-
-/*----------------------------------
- 
-  qh_COMPUTEfurthest 
-    compute furthest distance to an outside point instead of storing it with the facet
-    =1 to compute furthest
-  
-  notes:
-    computing furthest saves memory but costs time
-      about 40% more distance tests for partitioning
-      removes facet->furthestdist 
-*/
-#define qh_COMPUTEfurthest 0
-                         
-/*----------------------------------
- 
-  qh_KEEPstatistics   
-    =0 removes most of statistic gathering and reporting
-
-  notes:
-    if 0, code size is reduced by about 4%.
-*/
-#define qh_KEEPstatistics 1
-                       
-/*----------------------------------
- 
-  qh_MAXoutside 
-    record outer plane for each facet
-    =1 to record facet->maxoutside
-  
-  notes:
-    this takes a realT per facet and slightly slows down qhull
-    it produces better outer planes for geomview output 
-*/
-#define qh_MAXoutside 1
-
-/*----------------------------------
- 
-  qh_NOmerge
-    disables facet merging if defined
-    
-  notes:
-    This saves about 10% space.
-    
-    Unless 'Q0'
-      qh_NOmerge sets 'QJ' to avoid precision errors
-
-    #define qh_NOmerge    
-
-  see:
-    qh_NOmem in mem.c
-    
-    see user.c/user_eg.c for removing io.o
-*/  
-    
-/*----------------------------------
- 
-  qh_NOtrace
-    no tracing if defined 
-  
-  notes:
-    This saves about 5% space.
-
-    #define qh_NOtrace
-*/    
-
-/*----------------------------------
-  
-  qh_QHpointer
-    access global data with pointer or static structure
-
-  qh_QHpointer  = 1     access globals via a pointer to allocated memory
-                        enables qh_saveqhull() and qh_restoreqhull()
-			costs about 8% in time and 2% in space
-
-		= 0     qh_qh and qh_qhstat are static data structures
-		        only one instance of qhull() can be active at a time
-			default value
-
-  notes:
-    all global variables for qhull are in qh, qhmem, and qhstat
-    qh is defined in qhull.h
-    qhmem is defined in mem.h
-    qhstat is defined in stat.h
-
-  see:
-    user_eg.c for an example
-*/
-#define qh_QHpointer 0
-#if 0  /* sample code */
-    qhT *oldqhA, *oldqhB;
-
-    exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from first call to qh_new_qhull */
-    oldqhA= qh_save_qhull();
-    exitcode= qh_new_qhull (dimB, numpointsB, pointsB, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from second call to qh_new_qhull */
-    oldqhB= qh_save_qhull();
-    qh_restore_qhull (&oldqhA);
-    /* use results from first call to qh_new_qhull */
-    qh_freeqhull (qh_ALL);  /* frees all memory used by first call */
-    qh_restore_qhull (&oldqhB);
-    /* use results from second call to qh_new_qhull */
-    qh_freeqhull (!qh_ALL); /* frees long memory used by second call */
-    qh_memfreeshort (&curlong, &totlong);  /* frees short memory and memory allocator */
-#endif
-
-/*----------------------------------
- 
-  qh_QUICKhelp        
-    =1 to use abbreviated help messages, e.g., for degenerate inputs
-*/
-#define qh_QUICKhelp    0  
-
-/* ============ -merge constants- ====================
-
-   These constants effect facet merging.  You probably will not need
-   to modify these.  They effect the performance of facet merging.
-*/
-
-/*----------------------------------
-  
-  qh_DIMmergeVertex
-    max dimension for vertex merging (it is not effective in high-d)
-*/
-#define qh_DIMmergeVertex 6
-
-/*----------------------------------
-  
-  qh_DIMreduceBuild
-     max dimension for vertex reduction during build (slow in high-d)
-*/
-#define qh_DIMreduceBuild 5
-
-/*----------------------------------
-     
-  qh_BESTcentrum
-     if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
-     else, qh_findbestneighbor() tests all vertices (much better merges)
-
-  qh_BESTcentrum2
-     if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
-*/
-#define qh_BESTcentrum 20
-#define qh_BESTcentrum2 2
-
-/*----------------------------------
-  
-  qh_BESTnonconvex
-    if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
-    
-  notes:
-    It is needed because qh_findbestneighbor is slow for large facets
-*/
-#define qh_BESTnonconvex 15 
-
-/*----------------------------------
-  
-  qh_MAXnewmerges
-    if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
-     
-  notes:
-    It is needed because postmerge can merge many facets at once
-*/
-#define qh_MAXnewmerges 2
-
-/*----------------------------------
-  
-  qh_MAXnewcentrum
-    if <= dim+n vertices (n approximates the number of merges),
-      reset the centrum in qh_updatetested() and qh_mergecycle_facets()
-    
-  notes:
-    needed to reduce cost and because centrums may move too much if 
-    many vertices in high-d
-*/
-#define qh_MAXnewcentrum 5
-
-/*----------------------------------
-  
-  qh_COPLANARratio
-    for 3-d+ merging, qh.MINvisible is n*premerge_centrum
-
-  notes:
-    for non-merging, it's DISTround
-*/
-#define qh_COPLANARratio 3
-
-/*----------------------------------
-  
-  qh_DISToutside
-    When is a point clearly outside of a facet?  
-    Stops search in qh_findbestnew or qh_partitionall
-    qh_findbest uses qh.MINoutside since since it is only called if no merges.
-     
-  notes:
-    'Qf' always searches for best facet
-    if !qh.MERGING, same as qh.MINoutside. 
-    if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
-      [Note: Zdelvertextot occurs normally with interior points]
-            RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
-    When there is a sharp edge, need to move points to a
-    clearly good facet; otherwise may be lost in another partitioning.
-    if too big then O(n^2) behavior for partitioning in cone
-    if very small then important points not processed
-    Needed in qh_partitionall for
-      RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
-    Needed in qh_findbestnew for many instances of
-      RBOX 1000 s Z1 G1e-13 t | QHULL Tv
-
-  See:  
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
-     fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside))
-
-/*----------------------------------
-  
-  qh_RATIOnearinside
-    ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
-    qh_check_maxout().  
-  
-  notes:
-    This is overkill since do not know the correct value.
-    It effects whether 'Qc' reports all coplanar points
-    Not used for 'd' since non-extreme points are coplanar
-*/
-#define qh_RATIOnearinside 5
-
-/*----------------------------------
-  
-  qh_SEARCHdist
-    When is a facet coplanar with the best facet?  
-    qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
-
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
-      (qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar)));
-
-/*----------------------------------
-  
-  qh_USEfindbestnew
-     Always use qh_findbestnew for qh_partitionpoint, otherwise use
-     qh_findbestnew if merged new facet or sharpnewfacets.
-  
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
-
-/*----------------------------------
-  
-  qh_WIDEcoplanar
-    n*MAXcoplanar or n*MINvisible for a WIDEfacet 
-    
-    if vertex is further than qh.WIDEfacet from the hyperplane
-    then its ridges are not counted in computing the area, and
-    the facet's centrum is frozen. 
-    
-  notes:
-   qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
-      qh_WIDEcoplanar * qh.MINvisible);
-*/
-#define qh_WIDEcoplanar 6
-
-/*----------------------------------
-  
-  qh_MAXnarrow
-    max. cosine in initial hull that sets qh.NARROWhull
-       
-  notes:
-    If qh.NARROWhull, the initial partition does not make 
-    coplanar points.  If narrow, a coplanar point can be 
-    coplanar to two facets of opposite orientations and
-    distant from the exact convex hull.
-
-    Conservative estimate.  Don't actually see problems until it is -1.0
-*/
-#define qh_MAXnarrow -0.99999999
-
-/*----------------------------------
-  
-  qh_WARNnarrow
-    max. cosine in initial hull to warn about qh.NARROWhull
-      
-  notes:
-    this is a conservative estimate.  
-    Don't actually see problems until it is -1.0.  See qh-impre.htm
-*/
-#define qh_WARNnarrow -0.999999999999999
-
-/*----------------------------------
-  
-  qh_ZEROdelaunay
-    a zero Delaunay facet occurs for input sites coplanar with their convex hull
-    the last normal coefficient of a zero Delaunay facet is within
-        qh_ZEROdelaunay * qh.ANGLEround of 0
-      
-  notes:
-    qh_ZEROdelaunay does not allow for joggled input ('QJ').
-
-    You can avoid zero Delaunay facets by surrounding the input with a box.
-
-    Use option 'PDk:-n' to explicitly define zero Delaunay facets
-      k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
-      n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
-*/
-#define qh_ZEROdelaunay 2
-
-#endif /* qh_DEFuser */
-
-
-
diff --git a/extern/qhull/make/msvc_7_0/qhull.vcproj b/extern/qhull/make/msvc_7_0/qhull.vcproj
deleted file mode 100644
index 1b754d8e076..00000000000
--- a/extern/qhull/make/msvc_7_0/qhull.vcproj
+++ /dev/null
@@ -1,677 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/qhull/make/msvc_9_0/qhull.vcproj b/extern/qhull/make/msvc_9_0/qhull.vcproj
deleted file mode 100644
index fe5b3e806b6..00000000000
--- a/extern/qhull/make/msvc_9_0/qhull.vcproj
+++ /dev/null
@@ -1,877 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/qhull/src/Make-config.sh b/extern/qhull/src/Make-config.sh
deleted file mode 100755
index 90bbb958599..00000000000
--- a/extern/qhull/src/Make-config.sh
+++ /dev/null
@@ -1,285 +0,0 @@
-#!/bin/sh -e
-#
-# Make-config.sh
-#
-#     Setup for Debian build
-#
-#     Writes configure.in and Makefile.am files
-#     and runs automake and autoconfig
-#
-#     Use 'make dist' to build Unix distribution.
-#     Use 'configure; make' to build Qhull
-#
-#note:
-#     'configure; make' does not work under cygwin.
-#	src/unix.c:354: variable 'qh_qh' can't be auto-imported.
-#	Please read the documentation for ld's --enable-auto-import for details.
-
-###################################################
-###########  ../configure.in ######################
-###################################################
-
-echo Create ../configure.in
-cat >../configure.in <<\HERE-CONFIGURE
-dnl configure.in for the qhull package
-dnl Author: Rafael Laboissiere 
-dnl Created: Mon Dec  3 21:36:21 CET 2001
-
-AC_INIT(src/qhull.c)
-AM_INIT_AUTOMAKE(qhull, 2002.1)
-
-AC_PROG_CC
-AC_PROG_LIBTOOL
-
-AC_OUTPUT([Makefile src/Makefile html/Makefile eg/Makefile])
-
-HERE-CONFIGURE
-
-###################################################
-###########  ../Makefile.am #######################
-###################################################
-
-echo Create ../Makefile.am
-cat >../Makefile.am <<\HERE-TOP
-### Makefile.am for the qhull package (main)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-
-# which:
-doc_DATA = \
-  Announce.txt \
-  COPYING.txt \
-  README.txt \
-  REGISTER.txt
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
-  $(doc_DATA) \
-  File_id.diz \
-  QHULL-GO.pif
-
-### Subdirectories for Automaking
-
-SUBDIRS = src html eg
-
-HERE-TOP
-
-###################################################
-###########  ../eg/Makefile.am ####################
-###################################################
-
-echo Create ../eg/Makefile.am
-cat >../eg/Makefile.am <<\HERE-AM
-### Makefile.am for the qhull package (eg)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-examplesdir = $(docdir)/examples
-
-# which:
-examples_DATA = \
-  q_eg \
-  q_egtest \
-  q_test \
-  Qhull-go.bat \
-  q_test.bat
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = $(examples_DATA)
-
-HERE-AM
-
-###################################################
-###########  ../html/Makefile.am ##################
-###################################################
-
-echo Create ../html/Makefile.am
-cat >../html/Makefile.am <<\HERE-HTML
-### Makefile.am for the qhull package (html)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Man pages (trick to get around .man extension)
-
-%.1: %.man
-	cp $< $@
-CLEANFILES = *.1
-man_MANS = rbox.1 qhull.1
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-htmldir = $(docdir)/html
-
-# which:
-html_DATA = \
-  index.htm \
-  qconvex.htm \
-  qdelau_f.htm \
-  qdelaun.htm \
-  qh--4d.gif \
-  qh--cone.gif \
-  qh--dt.gif \
-  qh--geom.gif \
-  qh--half.gif \
-  qh--rand.gif \
-  qh-eg.htm \
-  qh-faq.htm \
-  qh-get.htm \
-  qh-home.htm \
-  qh-impre.htm \
-  qh-in.htm \
-  qh-optc.htm \
-  qh-optf.htm \
-  qh-optg.htm \
-  qh-opto.htm \
-  qh-optp.htm \
-  qh-optq.htm \
-  qh-optt.htm \
-  qh-quick.htm \
-  qhalf.htm \
-  qhull.htm \
-  qvoron_f.htm \
-  qvoronoi.htm \
-  rbox.htm
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
-  $(html_DATA) \
-  qhull.man \
-  qhull.txt \
-  rbox.man \
-  rbox.txt
-
-HERE-HTML
-
-###################################################
-###########  ../src/Makefile.am ###################
-###################################################
-
-echo Create ../src/Makefile.am
-cat >../src/Makefile.am <<\HERE-SRC
-### Makefile.am for the qhull package (src)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Shared Library
-
-# to:
-lib_LTLIBRARIES = libqhull.la
-
-# from:
-libqhull_la_SOURCES = \
-  user.c \
-  global.c \
-  stat.c \
-  io.c \
-  geom2.c \
-  poly2.c \
-  merge.c \
-  qhull.c \
-  geom.c \
-  poly.c \
-  qset.c \
-  mem.c
-
-# how:
-libqhull_la_LDFLAGS = -version-info 0:0:0 -lm
-
-### Utility programs
-
-# to:
-bin_PROGRAMS = qhull rbox qconvex qdelaunay qvoronoi qhalf
-
-# from:
-qhull_SOURCES = unix.c
-rbox_SOURCES = rbox.c
-qconvex_SOURCES = qconvex.c
-qdelaunay_SOURCES = qdelaun.c
-qvoronoi_SOURCES = qvoronoi.c
-qhalf_SOURCES = qhalf.c
-
-# how:
-qhull_LDADD = libqhull.la
-rbox_LDADD = libqhull.la
-qconvex_LDADD = libqhull.la
-qdelaunay_LDADD = libqhull.la
-qvoronoi_LDADD = libqhull.la
-qhalf_LDADD = libqhull.la
-
-### Include files
-
-pkginclude_HEADERS = \
-  geom.h \
-  mem.h \
-  poly.h \
-  qhull_a.h \
-  stat.h \
-  io.h \
-  merge.h \
-  qhull.h  \
-  qset.h \
-  user.h
-
-
-### Example programs
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-examplesdir = $(docdir)/examples
-
-# which:
-examples_DATA = \
-  user_eg.c \
-  user_eg2.c \
-  qhull_interface.cpp \
-  Makefile.txt \
-  Make-config.sh \
-  MBorland
-
-doc_DATA = Changes.txt \
-    index.htm \
-    qh-geom.htm \
-    qh-globa.htm \
-    qh-io.htm \
-    qh-mem.htm \
-    qh-merge.htm \
-    qh-poly.htm \
-    qh-qhull.htm \
-    qh-set.htm \
-    qh-stat.htm \
-    qh-user.htm
-
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
-  $(doc_DATA) \
-  $(examples_DATA)
-
-HERE-SRC
-
-###################################################
-###########  run automake autoconf ################
-###################################################
-
-
-echo Run automake, libtoolize, and autoconf
-cd ..; aclocal &&\
-  automake --foreign --add-missing --force-missing && \
-  libtoolize --force && \
-  autoconf
-
diff --git a/extern/qhull/src/Makefile b/extern/qhull/src/Makefile
deleted file mode 100644
index 81c06758cbb..00000000000
--- a/extern/qhull/src/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
-# vim: tabstop=8
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): GSR
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = qhull
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../include
-
-CSRCS = user.c global.c stat.c io.c geom2.c poly2.c \
-       merge.c qhull.c geom.c poly.c qset.c mem.c
-CCSRCS = 
-include nan_compile.mk 
-
-install: $(ALL_OR_DEBUG)
-	@[ -d $(NAN_QHULL) ] || mkdir -p $(NAN_QHULL)
-	@[ -d $(NAN_QHULL)/include/qhull ] || mkdir -p $(NAN_QHULL)/include/qhull
-	@[ -d $(NAN_QHULL)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_QHULL)/lib/$(DEBUG_DIR)
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_QHULL)/lib/$(DEBUG_DIR)
-ifeq ($(OS),darwin)
-	ranlib $(NAN_QHULL)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
-endif
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/qhull/*.h $(NAN_QHULL)/include/qhull
-
-
diff --git a/extern/qhull/src/Makefile.txt b/extern/qhull/src/Makefile.txt
deleted file mode 100644
index e87b66b49bc..00000000000
--- a/extern/qhull/src/Makefile.txt
+++ /dev/null
@@ -1,190 +0,0 @@
-# Unix Makefile for qhull and rbox
-#
-#       see README.txt
-#
-#       make           to produce qhull qconvex qdelaunay qhalf qvoronoi rbox
-#       make qvoronoi  to produce qvoronoi (etc.)
-#       make qhullx    to produce qhull qconvex etc.  w/o using libqhull.a
-#       make doc       to print documentation
-#       make install   to copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
-#       make new       to rebuild qhull and rbox from source
-#
-#       make printall  to print all files
-#       make user_eg   to produce user_eg
-#       make user_eg2  to produce user_eg2
-#       make clean     to remove object files and core
-#       make cleanall  to remove all generated files
-#
-#       PRINTMAN --  command for printing manual pages
-#       PRINTC --  command for printing C files
-#       BINDIR -- directory where to copy executables
-#       MANDIR -- directory where to copy manual pages
-#       CC --     ANSI C or C++ compiler
-#       CCOPTS1 - options used to compile .c files
-#       CCOPTS2 -- options used to link .o files
-#
-#       CFILES -- .c files for printing
-#       HFILES -- .h files for printing
-#       DFILES -- documentation files
-#       MFILES -- man pages and html files
-#       TFILES -- .txt versions of html html files
-#       FILES -- all other files
-#       OBJS -- specifies the object files of libqhull.a
-#
-BINDIR  = /usr/local/bin
-MANDIR  = /usr/local/man/man1
-
-# if you do not have enscript, try a2ps or just use lpr.  The files are text.
-PRINTMAN = enscript -2rl
-PRINTC = enscript -2r
-# PRINTMAN = lpr
-# PRINTC = lpr
-
-#for Gnu's gcc compiler -O2 for optimization, -g for debugging, -Wall for check
-#
-CC     = gcc
-CCOPTS1 = -O2 -ansi 
-
-# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
-#CC = cc
-#CCOPTS1 = -Xc -v -fast
-
-# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
-#CC = cc
-#CCOPTS1 = -ansi -O2
-
-# for Next cc compiler with fat executable
-#CC = cc
-#CCOPTS1 = -ansi -O2 -arch m68k -arch i386 -arch hppa
-
-# for loader, ld
-CCOPTS2 = $(CCOPTS1)
-
-# OBJS in execution frequency order.  CFILES after qhull.c are alphabetical
-OBJS = user.o global.o stat.o io.o geom2.o poly2.o \
-       merge.o qhull.o geom.o poly.o qset.o mem.o
-
-CFILES= unix.c qhull.c geom.c geom2.c global.c io.c mem.c merge.c poly.c \
-        poly2.c qset.c stat.c user.c qconvex.c qdelaun.c qhalf.c qvoronoi.c
-HFILES= user.h qhull.h qhull_a.h geom.h io.h mem.h merge.h poly.h qset.h stat.h
-TXTFILES= ../Announce.txt ../REGISTER.txt ../COPYING.txt ../README.txt Changes.txt
-DOCFILES= ../html/rbox.txt ../html/qhull.txt
-FILES=  Makefile rbox.c user_eg.c ../eg/q_test ../eg/q_egtest ../eg/q_eg
-HTMFILES= qhull.man rbox.man qh-in.htm qh-optg.htm qh-optt.htm qh-optp.htm \
-        index.htm qh-quick.htm qh-impre.htm qh-eg.htm \
-        qh-optc.htm qh-opto.htm qh-optf.htm qh-optq.htm \
-	    qh-c.htm qh-faq.htm qhull.htm qconvex.htm qdelaun.htm \
-		qh-geom.htm qh-globa.htm qh-io.htm qh-mem.htm qh-merge.htm \
-		qh-poly.htm qh-qhull.htm qh-set.htm qh-stat.htm qh-user.htm \
-		qdelau_f.htm qhalf.htm qvoronoi.htm qvoron_f.htm rbox.htm 
-
-all: rbox qconvex qdelaunay qhalf qvoronoi qhull
-
-unix.o:   qhull.h user.h mem.h
-qconvex.o:   qhull.h user.h mem.h
-qdelaun.o:   qhull.h user.h mem.h
-qhalf.o:   qhull.h user.h mem.h
-qvoronoi.o:   qhull.h user.h mem.h
-qhull.o:  $(HFILES)
-geom.o:   $(HFILES)
-geom2.o:  $(HFILES)
-global.o: $(HFILES)
-io.o:     $(HFILES)
-mem.o:    mem.h 
-merge.o:  $(HFILES)
-poly.o:   $(HFILES)
-poly2.o:  $(HFILES)
-qset.o:   qset.h mem.h 
-stat.o:   $(HFILES)
-user.o:   $(HFILES)
-
-.c.o:
-	$(CC) -c $(CCOPTS1) $<
-
-clean:
-	rm -f *.o ../core qconvex qdelaunay qhalf qvoronoi qhull libqhull.a \
-	    *.exe
-
-cleanall: clean
-	rm -f *~ ../rbox ../qhull ../qhalf ../qconvex ../qdelaunay ../qhalf\
-	   ../qvoronoi ../user_eg ../user_eg2 ../*.exe >/dev/null
-
-doc: 
-	$(PRINTMAN) $(TXTFILES) $(DOCFILES)
-
-install: all 
-	cp ../qconvex $(BINDIR)/qconvex
-	cp ../qdelaunay $(BINDIR)/qdelaunay
-	cp ../qhalf $(BINDIR)/qhalf
-	cp ../qhull $(BINDIR)/qhull
-	cp ../qvoronoi $(BINDIR)/qvoronoi
-	cp ../rbox $(BINDIR)/rbox
-	cp ../html/qhull.man $(MANDIR)/qhull.1
-	cp ../html/rbox.man $(MANDIR)/rbox.1
-
-new:    cleanall all
-
-printall: doc printh printc printf
-
-printh:
-	$(PRINTC) $(HFILES)
-
-printc:
-	$(PRINTC) $(CFILES)
-
-printf:
-	$(PRINTC) $(FILES) 
-
-libqhull.a: $(OBJS)
-	@echo if 'ar' or 'ranlib' fails, try 'make qhullx'
-	ar r libqhull.a $(OBJS)
-	@echo the next line may need to be removed.
-	-test -x /bin/ranlib -o -x /usr/bin/ranlib && ranlib libqhull.a
-
-# don't use ../qconvex.  Does not work on Red Hat Linux
-qconvex: qconvex.o libqhull.a
-	$(CC) -o qconvex $(CCOPTS2) qconvex.o -L. -lqhull -lm 
-	cp qconvex ..
-
-qdelaunay: qdelaun.o libqhull.a
-	$(CC) -o qdelaunay $(CCOPTS2) qdelaun.o -L. -lqhull -lm 
-	cp qdelaunay ..
-
-qhalf: qhalf.o libqhull.a
-	$(CC) -o qhalf $(CCOPTS2) qhalf.o -L. -lqhull -lm 
-	cp qhalf ..
-
-qvoronoi: qvoronoi.o libqhull.a
-	$(CC) -o qvoronoi $(CCOPTS2) qvoronoi.o -L. -lqhull -lm 
-	cp qvoronoi ..
-
-qhull: unix.o libqhull.a
-	$(CC) -o qhull $(CCOPTS2) unix.o -L. -lqhull -lm 
-	cp qhull ..
-	-chmod +x ../eg/q_test ../eg/q_eg ../eg/q_egtest
-	-cd ..; ./rbox D4 | ./qhull
-
-# compile qhull without using libqhull.a
-qhullx: qconvex.o qdelaun.o qhalf.o qvoronoi.o unix.o $(OBJS)
-	$(CC) -o qconvex $(CCOPTS2) qconvex.o $(OBJS) -lm 
-	$(CC) -o qdelaunay $(CCOPTS2) qdelaun.o $(OBJS) -lm 
-	$(CC) -o qhalf $(CCOPTS2) qhalf.o $(OBJS) -lm 
-	$(CC) -o qvoronoi $(CCOPTS2) qvoronoi.o $(OBJS) -lm 
-	$(CC) -o qhull $(CCOPTS2) unix.o $(OBJS) -lm 
-	cp qconvex qdelaunay qhalf qvoronoi qhull ..
-	-chmod +x ../eg/q_test ../eg/q_eg ../eg/q_egtest
-	-cd ..; ./rbox D4 | ./qhull
-
-rbox: rbox.o
-	$(CC) -o rbox rbox.o $(CCOPTS2) -lm
-	cp rbox ..
-
-user_eg: user_eg.o libqhull.a 
-	$(CC)  -o user_eg $(CCOPTS2) user_eg.o  -L. -lqhull -lm 
-	cp user_eg ..
-
-user_eg2: user_eg2.o libqhull.a 
-	$(CC)  -o user_eg2 $(CCOPTS2) user_eg2.o  -L. -lqhull -lm 
-	cp user_eg2 ..
-
-# end of Makefile
diff --git a/extern/qhull/src/geom.c b/extern/qhull/src/geom.c
deleted file mode 100644
index ca4bcaf2541..00000000000
--- a/extern/qhull/src/geom.c
+++ /dev/null
@@ -1,1230 +0,0 @@
-/*
  ---------------------------------
-
-   geom.c 
-   geometric routines of qhull
-
-   see qh-geom.htm and geom.h
-
-   copyright (c) 1993-2002 The Geometry Center        
-
-   infrequent code goes into geom2.c
-*/
-   
-#include "qhull_a.h"
-   
-/*---------------------------------
-  
-  qh_distplane( point, facet, dist )
-    return distance from point to facet
-
-  returns:
-    dist
-    if qh.RANDOMdist, joggles result
-  
-  notes:  
-    dist > 0 if point is above facet (i.e., outside)
-    does not error (for sortfacets)
-    
-  see:
-    qh_distnorm in geom2.c
-*/
-void qh_distplane (pointT *point, facetT *facet, realT *dist) {
-  coordT *normal= facet->normal, *coordp, randr;
-  int k;
-  
-  switch(qh hull_dim){
-  case 2:
-    *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1];
-    break;
-  case 3:
-    *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
-    break;
-  case 4:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
-    break;
-  case 5:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
-    break;
-  case 6:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
-    break;
-  case 7:  
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
-    break;
-  case 8:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
-    break;
-  default:
-    *dist= facet->offset;
-    coordp= point;
-    for (k= qh hull_dim; k--; )
-      *dist += *coordp++ * *normal++;
-    break;
-  }
-  zinc_(Zdistplane);
-  if (!qh RANDOMdist && qh IStracing < 4)
-    return;
-  if (qh RANDOMdist) {
-    randr= qh_RANDOMint;
-    *dist += (2.0 * randr / qh_RANDOMmax - 1.0) *
-      qh RANDOMfactor * qh MAXabs_coord;
-  }
-  if (qh IStracing >= 4) {
-    fprintf (qh ferr, "qh_distplane: ");
-    fprintf (qh ferr, qh_REAL_1, *dist);
-    fprintf (qh ferr, "from p%d to f%d\n", qh_pointid(point), facet->id);
-  }
-  return;
-} /* distplane */
-
-
-/*---------------------------------
-  
-  qh_findbest( point, startfacet, bestoutside, qh_ISnewfacets, qh_NOupper, dist, isoutside, numpart )
-    find facet that is furthest below a point 
-    for upperDelaunay facets
-      returns facet only if !qh_NOupper and clearly above
-
-  input:
-    starts search at 'startfacet' (can not be flipped)
-    if !bestoutside (qh_ALL), stops at qh.MINoutside
-
-  returns:
-    best facet (reports error if NULL)
-    early out if isoutside defined and bestdist > qh.MINoutside
-    dist is distance to facet
-    isoutside is true if point is outside of facet
-    numpart counts the number of distance tests
-
-  see also:
-    qh_findbestnew()
-    
-  notes:
-    If merging (testhorizon), searches horizon facets of coplanar best facets because
-    after qh_distplane, this and qh_partitionpoint are the most expensive in 3-d
-      avoid calls to distplane, function calls, and real number operations.
-    caller traces result
-    Optimized for outside points.   Tried recording a search set for qh_findhorizon.
-    Made code more complicated.
-
-  when called by qh_partitionvisible():
-    indicated by qh_ISnewfacets
-    qh.newfacet_list is list of simplicial, new facets
-    qh_findbestnew set if qh_sharpnewfacets returns True (to use qh_findbestnew)
-    qh.bestfacet_notsharp set if qh_sharpnewfacets returns False
-
-  when called by qh_findfacet(), qh_partitionpoint(), qh_partitioncoplanar(), 
-                 qh_check_bestdist(), qh_addpoint()
-    indicated by !qh_ISnewfacets
-    returns best facet in neighborhood of given facet
-      this is best facet overall if dist > -   qh.MAXcoplanar 
-        or hull has at least a "spherical" curvature
-
-  design:
-    initialize and test for early exit
-    repeat while there are better facets
-      for each neighbor of facet
-        exit if outside facet found
-	test for better facet
-    if point is inside and partitioning
-      test for new facets with a "sharp" intersection
-      if so, future calls go to qh_findbestnew()
-    test horizon facets
-*/
-facetT *qh_findbest (pointT *point, facetT *startfacet, 
-		     boolT bestoutside, boolT isnewfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart) {
-  realT bestdist= -REALmax/2 /* avoid underflow */;
-  facetT *facet, *neighbor, **neighborp, *bestfacet= NULL;
- /* facetT *bestfacet_all= startfacet; */
-  int oldtrace= qh IStracing;
-  unsigned int visitid= ++qh visit_id;
-  int numpartnew=0;
-  boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
-
-  zinc_(Zfindbest);
-  if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid (point))) {
-    if (qh TRACElevel > qh IStracing)
-      qh IStracing= qh TRACElevel;
-    fprintf (qh ferr, "qh_findbest: point p%d starting at f%d isnewfacets? %d, unless %d exit if > %2.2g\n",
-	     qh_pointid(point), startfacet->id, isnewfacets, bestoutside, qh MINoutside);
-    fprintf(qh ferr, "  testhorizon? %d noupper? %d", testhorizon, noupper);
-    fprintf (qh ferr, "  Last point added was p%d.", qh furthest_id);
-    fprintf(qh ferr, "  Last merge was #%d.  max_outside %2.2g\n", zzval_(Ztotmerge), qh max_outside);
-  }
-  if (isoutside)
-    *isoutside= True;
-  if (!startfacet->flipped) {  /* test startfacet */
-    *numpart= 1;
-    qh_distplane (point, startfacet, dist);  /* this code is duplicated below */
-    if (!bestoutside && *dist >= qh MINoutside 
-    && (!startfacet->upperdelaunay || !noupper)) {
-      bestfacet= startfacet;
-      goto LABELreturn_best;
-    }
-    bestdist= *dist;
-    if (!startfacet->upperdelaunay) {
-      bestfacet= startfacet;
-    } 
-  }else 
-    *numpart= 0;
-  startfacet->visitid= visitid;
-  facet= startfacet;
-  while (facet) {
-    trace4((qh ferr, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n", 
-                facet->id, bestdist, getid_(bestfacet)));
-    FOREACHneighbor_(facet) {
-      if (!neighbor->newfacet && isnewfacets)
-        continue;
-      if (neighbor->visitid == visitid)
-	continue;
-      neighbor->visitid= visitid;
-      if (!neighbor->flipped) {  /* code duplicated above */
-	(*numpart)++;
-	qh_distplane (point, neighbor, dist);
-	if (*dist > bestdist) {
-	  if (!bestoutside && *dist >= qh MINoutside 
-	  && (!neighbor->upperdelaunay || !noupper)) {
-	    bestfacet= neighbor;
-	    goto LABELreturn_best;
-	  }
-	  if (!neighbor->upperdelaunay) {
-	    bestfacet= neighbor;
-	    bestdist= *dist;
-	  }
-	  break; /* switch to neighor */
-	} /* end of *dist>bestdist */
-      } /* end of !flipped */
-    } /* end of FOREACHneighbor */
-    facet= neighbor;  /* non-NULL only if *dist>bestdist */
-  } /* end of while facet (directed search) */
-  if (isnewfacets) { 
-    if (!bestfacet) {
-      bestdist= -REALmax/2; 
-      bestfacet= qh_findbestnew (point, startfacet->next, &bestdist, bestoutside, isoutside, &numpartnew);
-      testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
-    }else if (!qh findbest_notsharp && bestdist < - qh DISTround) {
-      if (qh_sharpnewfacets()) { 
-	/* seldom used, qh_findbestnew will retest all facets */
-	zinc_(Zfindnewsharp);
-	bestfacet= qh_findbestnew (point, bestfacet, &bestdist, bestoutside, isoutside, &numpartnew);
-	testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
-	qh findbestnew= True;
-      }else
-	qh findbest_notsharp= True;
-    }
-  }
-  if (!bestfacet) {
-    fprintf(qh ferr, "\n\
-qh_findbest: all neighbors of facet %d are flipped or upper Delaunay.\n\
-Please report this error to qhull_bug@geom.umn.edu with the input and all of the output.\n",
-       startfacet->id);
-    qh_errexit (qh_ERRqhull, startfacet, NULL);
-  }
-  if (testhorizon) 
-    bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, bestfacet, noupper, &bestdist, &numpartnew);
-  *dist= bestdist;
-  if (isoutside && bestdist < qh MINoutside)
-    *isoutside= False;
-LABELreturn_best:
-  zadd_(Zfindbesttot, *numpart);
-  zmax_(Zfindbestmax, *numpart);
-  (*numpart) += numpartnew;
-  qh IStracing= oldtrace;
-  return bestfacet;
-}  /* findbest */
-
-
-/*---------------------------------
-  
-  qh_findbesthorizon( qh_IScheckmax, point, startfacet, qh_NOupper, &bestdist, &numpart )
-    search coplanar and better horizon facets from startfacet/bestdist
-    ischeckmax turns off statistics and minsearch update
-    all arguments must be initialized
-  returns (ischeckmax):
-    best facet
-  returns (!ischeckmax):
-    best facet that is not upperdelaunay
-    allows upperdelaunay that is clearly outside
-  returns:
-    bestdist is distance to bestfacet
-    numpart -- updates number of distance tests
-
-  notes:
-    no early out -- use qh_findbest() or qh_findbestnew()
-    Searches coplanar or better horizon facets
-
-  when called by qh_check_maxout() (qh_IScheckmax)
-    startfacet must be closest to the point
-      Otherwise, if point is beyond and below startfacet, startfacet may be a local minimum
-      even though other facets are below the point.
-    updates facet->maxoutside for good, visited facets
-    may return NULL
-
-    searchdist is qh.max_outside + 2 * DISTround
-      + max( MINvisible('Vn'), MAXcoplanar('Un'));
-    This setting is a guess.  It must be at least max_outside + 2*DISTround 
-    because a facet may have a geometric neighbor across a vertex
-
-  design:
-    for each horizon facet of coplanar best facets
-      continue if clearly inside
-      unless upperdelaunay or clearly outside
-         update best facet
-*/
-facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart) {
-  facetT *bestfacet= startfacet;
-  realT dist;
-  facetT *neighbor, **neighborp, *facet;
-  facetT *nextfacet= NULL; /* optimize last facet of coplanarset */
-  int numpartinit= *numpart, coplanarset_size;
-  unsigned int visitid= ++qh visit_id;
-  boolT newbest= False; /* for tracing */
-  realT minsearch, searchdist;  /* skip facets that are too far from point */
-
-  if (!ischeckmax) {
-    zinc_(Zfindhorizon);
-  }else {
-#if qh_MAXoutside
-    if ((!qh ONLYgood || startfacet->good) && *bestdist > startfacet->maxoutside)
-      startfacet->maxoutside= *bestdist;
-#endif
-  }
-  searchdist= qh_SEARCHdist; /* multiple of qh.max_outside and precision constants */
-  minsearch= *bestdist - searchdist;
-  if (ischeckmax) {
-    /* Always check coplanar facets.  Needed for RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv */
-    minimize_(minsearch, -searchdist);
-  }
-  coplanarset_size= 0;
-  facet= startfacet;
-  while (True) {
-    trace4((qh ferr, "qh_findbesthorizon: neighbors of f%d bestdist %2.2g f%d ischeckmax? %d noupper? %d minsearch %2.2g searchdist %2.2g\n", 
-		facet->id, *bestdist, getid_(bestfacet), ischeckmax, noupper,
-		minsearch, searchdist));
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid == visitid) 
-	continue;
-      neighbor->visitid= visitid;
-      if (!neighbor->flipped) { 
-	qh_distplane (point, neighbor, &dist);
-	(*numpart)++;
-	if (dist > *bestdist) {
-	  if (!neighbor->upperdelaunay || ischeckmax || (!noupper && dist >= qh MINoutside)) {
-	    bestfacet= neighbor;
-	    *bestdist= dist;
-	    newbest= True;
-	    if (!ischeckmax) {
-	      minsearch= dist - searchdist;
-	      if (dist > *bestdist + searchdist) {
-		zinc_(Zfindjump);  /* everything in qh.coplanarset at least searchdist below */
-		coplanarset_size= 0;
-	      }
-	    }
-	  }
-	}else if (dist < minsearch) 
-	  continue;  /* if ischeckmax, dist can't be positive */
-#if qh_MAXoutside
-	if (ischeckmax && dist > neighbor->maxoutside)
-	  neighbor->maxoutside= dist;
-#endif      
-      } /* end of !flipped */
-      if (nextfacet) {
-	if (!coplanarset_size++) {
-	  SETfirst_(qh coplanarset)= nextfacet;
-	  SETtruncate_(qh coplanarset, 1);
-	}else
-  	  qh_setappend (&qh coplanarset, nextfacet); /* Was needed for RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv
-						 and RBOX 1000 s Z1 G1e-13 t996564279 | qhull Tv  */
-      }
-      nextfacet= neighbor;
-    } /* end of EACHneighbor */
-    facet= nextfacet;
-    if (facet) 
-      nextfacet= NULL;
-    else if (!coplanarset_size)
-      break; 
-    else if (!--coplanarset_size) {
-      facet= SETfirst_(qh coplanarset);
-      SETtruncate_(qh coplanarset, 0);
-    }else
-      facet= (facetT*)qh_setdellast (qh coplanarset);
-  } /* while True, for each facet in qh.coplanarset */
-  if (!ischeckmax) {
-    zadd_(Zfindhorizontot, *numpart - numpartinit);
-    zmax_(Zfindhorizonmax, *numpart - numpartinit);
-    if (newbest)
-      zinc_(Zparthorizon);
-  }
-  trace4((qh ferr, "qh_findbesthorizon: newbest? %d bestfacet f%d bestdist %2.2g\n", newbest, getid_(bestfacet), *bestdist));
-  return bestfacet;
-}  /* findbesthorizon */
-
-/*---------------------------------
-  
-  qh_findbestnew( point, startfacet, dist, isoutside, numpart )
-    find best newfacet for point
-    searches all of qh.newfacet_list starting at startfacet
-    searches horizon facets of coplanar best newfacets
-    searches all facets if startfacet == qh.facet_list
-  returns:
-    best new or horizon facet that is not upperdelaunay
-    early out if isoutside and not 'Qf'
-    dist is distance to facet
-    isoutside is true if point is outside of facet
-    numpart is number of distance tests
-
-  notes:
-    Always used for merged new facets (see qh_USEfindbestnew)
-    Avoids upperdelaunay facet unless (isoutside and outside)
-
-    Uses qh.visit_id, qh.coplanarset.  
-    If share visit_id with qh_findbest, coplanarset is incorrect.
-
-    If merging (testhorizon), searches horizon facets of coplanar best facets because
-    a point maybe coplanar to the bestfacet, below its horizon facet,
-    and above a horizon facet of a coplanar newfacet.  For example,
-      rbox 1000 s Z1 G1e-13 | qhull
-      rbox 1000 s W1e-13 P0 t992110337 | QHULL d Qbb Qc
-
-    qh_findbestnew() used if
-       qh_sharpnewfacets -- newfacets contains a sharp angle
-       if many merges, qh_premerge found a merge, or 'Qf' (qh.findbestnew)
-
-  see also:
-    qh_partitionall() and qh_findbest()
-
-  design:
-    for each new facet starting from startfacet
-      test distance from point to facet
-      return facet if clearly outside
-      unless upperdelaunay and a lowerdelaunay exists
-         update best facet
-    test horizon facets
-*/
-facetT *qh_findbestnew (pointT *point, facetT *startfacet,
-	   realT *dist, boolT bestoutside, boolT *isoutside, int *numpart) {
-  realT bestdist= -REALmax/2; /*, minsearch= -REALmax/2;*/
-  facetT *bestfacet= NULL, *facet;
-  int oldtrace= qh IStracing, i;
-  unsigned int visitid= ++qh visit_id;
-  realT distoutside= 0.0;
-  boolT isdistoutside; /* True if distoutside is defined */
-  boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
-
-  if (!startfacet) {
-    if (qh MERGING)
-      fprintf(qh ferr, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets.  Can not continue.\n");
-    else
-      fprintf(qh ferr, "qhull internal error (qh_findbestnew): no new facets for point p%d\n",
-      	      qh furthest_id);      
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  zinc_(Zfindnew);
-  if (qh BESToutside || bestoutside)
-    isdistoutside= False;
-  else {
-    isdistoutside= True;
-    distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
-  }
-  if (isoutside)
-    *isoutside= True;
-  *numpart= 0;
-  if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid (point))) {
-    if (qh TRACElevel > qh IStracing)
-      qh IStracing= qh TRACElevel;
-    fprintf(qh ferr, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n",
-	     qh_pointid(point), startfacet->id, isdistoutside, distoutside);
-    fprintf(qh ferr, "  Last point added p%d visitid %d.",  qh furthest_id, visitid);
-    fprintf(qh ferr, "  Last merge was #%d.\n", zzval_(Ztotmerge));
-  }
-  /* visit all new facets starting with startfacet, maybe qh facet_list */
-  for (i= 0, facet= startfacet; i < 2; i++, facet= qh newfacet_list) {
-    FORALLfacet_(facet) {
-      if (facet == startfacet && i)
-	break;
-      facet->visitid= visitid;
-      if (!facet->flipped) {
-	qh_distplane (point, facet, dist);
-	(*numpart)++;
-	if (*dist > bestdist) {
-	  if (!facet->upperdelaunay || *dist >= qh MINoutside) {
-	    bestfacet= facet;
-	    if (isdistoutside && *dist >= distoutside)
-	      goto LABELreturn_bestnew;
-	    bestdist= *dist;
-  	  }
-	}
-      } /* end of !flipped */
-    } /* FORALLfacet from startfacet or qh newfacet_list */
-  }
-  if (testhorizon || !bestfacet)
-    bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, bestfacet ? bestfacet : startfacet, 
-	                                !qh_NOupper, &bestdist, numpart);  
-  *dist= bestdist;
-  if (isoutside && *dist < qh MINoutside)
-    *isoutside= False;
-LABELreturn_bestnew:
-  zadd_(Zfindnewtot, *numpart);
-  zmax_(Zfindnewmax, *numpart);
-  trace4((qh ferr, "qh_findbestnew: bestfacet f%d bestdist %2.2g\n", getid_(bestfacet), *dist));
-  qh IStracing= oldtrace;
-  return bestfacet;
-}  /* findbestnew */
-
-/* ============ hyperplane functions -- keep code together [?] ============ */
-
-/*---------------------------------
-  
-  qh_backnormal( rows, numrow, numcol, sign, normal, nearzero )
-    given an upper-triangular rows array and a sign,
-    solve for normal equation x using back substitution over rows U
-
-  returns:
-     normal= x
-      
-     if will not be able to divzero() when normalized (qh.MINdenom_2 and qh.MINdenom_1_2),
-       if fails on last row
-         this means that the hyperplane intersects [0,..,1]
-         sets last coordinate of normal to sign
-       otherwise
-         sets tail of normal to [...,sign,0,...], i.e., solves for b= [0...0]
-         sets nearzero
-
-  notes:
-     assumes numrow == numcol-1
-
-     see Golub & van Loan 4.4-9 for back substitution
-
-     solves Ux=b where Ax=b and PA=LU
-     b= [0,...,0,sign or 0]  (sign is either -1 or +1)
-     last row of A= [0,...,0,1]
-
-     1) Ly=Pb == y=b since P only permutes the 0's of   b
-     
-  design:
-    for each row from end
-      perform back substitution
-      if near zero
-        use qh_divzero for division
-        if zero divide and not last row
-          set tail of normal to 0
-*/
-void qh_backnormal (realT **rows, int numrow, int numcol, boolT sign,
-  	coordT *normal, boolT *nearzero) {
-  int i, j;
-  coordT *normalp, *normal_tail, *ai, *ak;
-  realT diagonal;
-  boolT waszero;
-  int zerocol= -1;
-  
-  normalp= normal + numcol - 1;
-  *normalp--= (sign ? -1.0 : 1.0);
-  for(i= numrow; i--; ) {
-    *normalp= 0.0;
-    ai= rows[i] + i + 1;
-    ak= normalp+1;
-    for(j= i+1; j < numcol; j++)
-      *normalp -= *ai++ * *ak++;
-    diagonal= (rows[i])[i];
-    if (fabs_(diagonal) > qh MINdenom_2)
-      *(normalp--) /= diagonal;
-    else {
-      waszero= False;
-      *normalp= qh_divzero (*normalp, diagonal, qh MINdenom_1_2, &waszero);
-      if (waszero) {
-        zerocol= i;
-	*(normalp--)= (sign ? -1.0 : 1.0);
-	for (normal_tail= normalp+2; normal_tail < normal + numcol; normal_tail++)
-	  *normal_tail= 0.0;
-      }else
-	normalp--;
-    }
-  }
-  if (zerocol != -1) {
-    zzinc_(Zback0);
-    *nearzero= True;
-    trace4((qh ferr, "qh_backnormal: zero diagonal at column %d.\n", i));
-    qh_precision ("zero diagonal on back substitution");
-  }
-} /* backnormal */
-
-/*---------------------------------
-  
-  qh_gausselim( rows, numrow, numcol, sign )
-    Gaussian elimination with partial pivoting
-
-  returns:
-    rows is upper triangular (includes row exchanges)
-    flips sign for each row exchange
-    sets nearzero if pivot[k] < qh.NEARzero[k], else clears it
-
-  notes:
-    if nearzero, the determinant's sign may be incorrect.
-    assumes numrow <= numcol
-
-  design:
-    for each row
-      determine pivot and exchange rows if necessary
-      test for near zero
-      perform gaussian elimination step
-*/
-void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero) {
-  realT *ai, *ak, *rowp, *pivotrow;
-  realT n, pivot, pivot_abs= 0.0, temp;
-  int i, j, k, pivoti, flip=0;
-  
-  *nearzero= False;
-  for(k= 0; k < numrow; k++) {
-    pivot_abs= fabs_((rows[k])[k]);
-    pivoti= k;
-    for(i= k+1; i < numrow; i++) {
-      if ((temp= fabs_((rows[i])[k])) > pivot_abs) {
-	pivot_abs= temp;
-	pivoti= i;
-      }
-    }
-    if (pivoti != k) {
-      rowp= rows[pivoti]; 
-      rows[pivoti]= rows[k]; 
-      rows[k]= rowp; 
-      *sign ^= 1;
-      flip ^= 1;
-    }
-    if (pivot_abs <= qh NEARzero[k]) {
-      *nearzero= True;
-      if (pivot_abs == 0.0) {   /* remainder of column == 0 */
-	if (qh IStracing >= 4) {
-	  fprintf (qh ferr, "qh_gausselim: 0 pivot at column %d. (%2.2g < %2.2g)\n", k, pivot_abs, qh DISTround);
-	  qh_printmatrix (qh ferr, "Matrix:", rows, numrow, numcol);
-	}
-	zzinc_(Zgauss0);
-        qh_precision ("zero pivot for Gaussian elimination");
-	goto LABELnextcol;
-      }
-    }
-    pivotrow= rows[k] + k;
-    pivot= *pivotrow++;  /* signed value of pivot, and remainder of row */
-    for(i= k+1; i < numrow; i++) {
-      ai= rows[i] + k;
-      ak= pivotrow;
-      n= (*ai++)/pivot;   /* divzero() not needed since |pivot| >= |*ai| */
-      for(j= numcol - (k+1); j--; )
-	*ai++ -= n * *ak++;
-    }
-  LABELnextcol:
-    ;
-  }
-  wmin_(Wmindenom, pivot_abs);  /* last pivot element */
-  if (qh IStracing >= 5)
-    qh_printmatrix (qh ferr, "qh_gausselem: result", rows, numrow, numcol);
-} /* gausselim */
-
-
-/*---------------------------------
-  
-  qh_getangle( vect1, vect2 )
-    returns the dot product of two vectors
-    if qh.RANDOMdist, joggles result
-
-  notes:
-    the angle may be > 1.0 or < -1.0 because of roundoff errors
-
-*/
-realT qh_getangle(pointT *vect1, pointT *vect2) {
-  realT angle= 0, randr;
-  int k;
-
-  for(k= qh hull_dim; k--; )
-    angle += *vect1++ * *vect2++;
-  if (qh RANDOMdist) {
-    randr= qh_RANDOMint;
-    angle += (2.0 * randr / qh_RANDOMmax - 1.0) *
-      qh RANDOMfactor;
-  }
-  trace4((qh ferr, "qh_getangle: %2.2g\n", angle));
-  return(angle);
-} /* getangle */
-
-
-/*---------------------------------
-  
-  qh_getcenter( vertices )
-    returns arithmetic center of a set of vertices as a new point
-
-  notes:
-    allocates point array for center
-*/
-pointT *qh_getcenter(setT *vertices) {
-  int k;
-  pointT *center, *coord;
-  vertexT *vertex, **vertexp;
-  int count= qh_setsize(vertices);
-
-  if (count < 2) {
-    fprintf (qh ferr, "qhull internal error (qh_getcenter): not defined for %d points\n", count);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  center= (pointT *)qh_memalloc(qh normal_size);
-  for (k=0; k < qh hull_dim; k++) {
-    coord= center+k;
-    *coord= 0.0;
-    FOREACHvertex_(vertices)
-      *coord += vertex->point[k];
-    *coord /= count;
-  }
-  return(center);
-} /* getcenter */
-
-
-/*---------------------------------
-  
-  qh_getcentrum( facet )
-    returns the centrum for a facet as a new point
-
-  notes:
-    allocates the centrum
-*/
-pointT *qh_getcentrum(facetT *facet) {
-  realT dist;
-  pointT *centrum, *point;
-
-  point= qh_getcenter(facet->vertices);
-  zzinc_(Zcentrumtests);
-  qh_distplane (point, facet, &dist);
-  centrum= qh_projectpoint(point, facet, dist);
-  qh_memfree(point, qh normal_size);
-  trace4((qh ferr, "qh_getcentrum: for f%d, %d vertices dist= %2.2g\n",
-	  facet->id, qh_setsize(facet->vertices), dist));
-  return centrum;
-} /* getcentrum */
-
-
-/*---------------------------------
-  
-  qh_getdistance( facet, neighbor, mindist, maxdist )
-    returns the maxdist and mindist distance of any vertex from neighbor
-
-  returns:
-    the max absolute value
-
-  design:
-    for each vertex of facet that is not in neighbor
-      test the distance from vertex to neighbor
-*/
-realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist) {
-  vertexT *vertex, **vertexp;
-  realT dist, maxd, mind;
-  
-  FOREACHvertex_(facet->vertices)
-    vertex->seen= False;
-  FOREACHvertex_(neighbor->vertices)
-    vertex->seen= True;
-  mind= 0.0;
-  maxd= 0.0;
-  FOREACHvertex_(facet->vertices) {
-    if (!vertex->seen) {
-      zzinc_(Zbestdist);
-      qh_distplane(vertex->point, neighbor, &dist);
-      if (dist < mind)
-	mind= dist;
-      else if (dist > maxd)
-	maxd= dist;
-    }
-  }
-  *mindist= mind;
-  *maxdist= maxd;
-  mind= -mind;
-  if (maxd > mind)
-    return maxd;
-  else
-    return mind;
-} /* getdistance */
-
-
-/*---------------------------------
-
-  qh_normalize( normal, dim, toporient )
-    normalize a vector and report if too small
-    does not use min norm
-  
-  see:
-    qh_normalize2
-*/
-void qh_normalize (coordT *normal, int dim, boolT toporient) {
-  qh_normalize2( normal, dim, toporient, NULL, NULL);
-} /* normalize */
-
-/*---------------------------------
-  
-  qh_normalize2( normal, dim, toporient, minnorm, ismin )
-    normalize a vector and report if too small
-    qh.MINdenom/MINdenom1 are the upper limits for divide overflow
-
-  returns:
-    normalized vector
-    flips sign if !toporient
-    if minnorm non-NULL, 
-      sets ismin if normal < minnorm
-
-  notes:
-    if zero norm
-       sets all elements to sqrt(1.0/dim)
-    if divide by zero (divzero ())
-       sets largest element to   +/-1
-       bumps Znearlysingular
-      
-  design:
-    computes norm
-    test for minnorm
-    if not near zero
-      normalizes normal
-    else if zero norm
-      sets normal to standard value
-    else
-      uses qh_divzero to normalize
-      if nearzero
-        sets norm to direction of maximum value
-*/
-void qh_normalize2 (coordT *normal, int dim, boolT toporient, 
-            realT *minnorm, boolT *ismin) {
-  int k;
-  realT *colp, *maxp, norm= 0, temp, *norm1, *norm2, *norm3;
-  boolT zerodiv;
-
-  norm1= normal+1;
-  norm2= normal+2;
-  norm3= normal+3;
-  if (dim == 2)
-    norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1));
-  else if (dim == 3)
-    norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2));
-  else if (dim == 4) {
-    norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) 
-               + (*norm3)*(*norm3));
-  }else if (dim > 4) {
-    norm= (*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) 
-               + (*norm3)*(*norm3);
-    for (k= dim-4, colp= normal+4; k--; colp++)
-      norm += (*colp) * (*colp);
-    norm= sqrt(norm);
-  }
-  if (minnorm) {
-    if (norm < *minnorm) 
-      *ismin= True;
-    else
-      *ismin= False;
-  }
-  wmin_(Wmindenom, norm);
-  if (norm > qh MINdenom) {
-    if (!toporient)
-      norm= -norm;
-    *normal /= norm;
-    *norm1 /= norm;
-    if (dim == 2)
-      ; /* all done */
-    else if (dim == 3)
-      *norm2 /= norm;
-    else if (dim == 4) {
-      *norm2 /= norm;
-      *norm3 /= norm;
-    }else if (dim >4) {
-      *norm2 /= norm;
-      *norm3 /= norm;
-      for (k= dim-4, colp= normal+4; k--; )
-        *colp++ /= norm;
-    }
-  }else if (norm == 0.0) {
-    temp= sqrt (1.0/dim);
-    for (k= dim, colp= normal; k--; )
-      *colp++ = temp;
-  }else {
-    if (!toporient)
-      norm= -norm;
-    for (k= dim, colp= normal; k--; colp++) { /* k used below */
-      temp= qh_divzero (*colp, norm, qh MINdenom_1, &zerodiv);
-      if (!zerodiv)
-	*colp= temp;
-      else {
-	maxp= qh_maxabsval(normal, dim);
-	temp= ((*maxp * norm >= 0.0) ? 1.0 : -1.0);
-	for (k= dim, colp= normal; k--; colp++)
-	  *colp= 0.0;
-	*maxp= temp;
-	zzinc_(Znearlysingular);
-	trace0((qh ferr, "qh_normalize: norm=%2.2g too small during p%d\n", 
-	       norm, qh furthest_id));
-	return;
-      }
-    }
-  }
-} /* normalize */
-
-
-/*---------------------------------
-  
-  qh_projectpoint( point, facet, dist )
-    project point onto a facet by dist
-
-  returns:
-    returns a new point
-    
-  notes:
-    if dist= distplane(point,facet)
-      this projects point to hyperplane
-    assumes qh_memfree_() is valid for normal_size
-*/
-pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist) {
-  pointT *newpoint, *np, *normal;
-  int normsize= qh normal_size,k;
-  void **freelistp; /* used !qh_NOmem */
-  
-  qh_memalloc_(normsize, freelistp, newpoint, pointT);
-  np= newpoint;
-  normal= facet->normal;
-  for(k= qh hull_dim; k--; )
-    *(np++)= *point++ - dist * *normal++;
-  return(newpoint);
-} /* projectpoint */
-
-  
-/*---------------------------------
-  
-  qh_setfacetplane( facet )
-    sets the hyperplane for a facet
-    if qh.RANDOMdist, joggles hyperplane
-
-  notes:
-    uses global buffers qh.gm_matrix and qh.gm_row
-    overwrites facet->normal if already defined
-    updates Wnewvertex if PRINTstatistics
-    sets facet->upperdelaunay if upper envelope of Delaunay triangulation
-
-  design:
-    copy vertex coordinates to qh.gm_matrix/gm_row
-    compute determinate
-    if nearzero
-      recompute determinate with gaussian elimination
-      if nearzero
-        force outside orientation by testing interior point
-*/
-void qh_setfacetplane(facetT *facet) {
-  pointT *point;
-  vertexT *vertex, **vertexp;
-  int k,i, normsize= qh normal_size, oldtrace= 0;
-  realT dist;
-  void **freelistp; /* used !qh_NOmem */
-  coordT *coord, *gmcoord;
-  pointT *point0= SETfirstt_(facet->vertices, vertexT)->point;
-  boolT nearzero= False;
-
-  zzinc_(Zsetplane);
-  if (!facet->normal)
-    qh_memalloc_(normsize, freelistp, facet->normal, coordT);
-  if (facet == qh tracefacet) {
-    oldtrace= qh IStracing;
-    qh IStracing= 5;
-    fprintf (qh ferr, "qh_setfacetplane: facet f%d created.\n", facet->id);
-    fprintf (qh ferr, "  Last point added to hull was p%d.", qh furthest_id);
-    if (zzval_(Ztotmerge))
-      fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
-    fprintf (qh ferr, "\n\nCurrent summary is:\n");
-      qh_printsummary (qh ferr);
-  }
-  if (qh hull_dim <= 4) {
-    i= 0;
-    if (qh RANDOMdist) {
-      gmcoord= qh gm_matrix;
-      FOREACHvertex_(facet->vertices) {
-        qh gm_row[i++]= gmcoord;
-	coord= vertex->point;
-	for (k= qh hull_dim; k--; )
-	  *(gmcoord++)= *coord++ * qh_randomfactor();
-      }	  
-    }else {
-      FOREACHvertex_(facet->vertices)
-       qh gm_row[i++]= vertex->point;
-    }
-    qh_sethyperplane_det(qh hull_dim, qh gm_row, point0, facet->toporient,
-                facet->normal, &facet->offset, &nearzero);
-  }
-  if (qh hull_dim > 4 || nearzero) {
-    i= 0;
-    gmcoord= qh gm_matrix;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->point != point0) {
-	qh gm_row[i++]= gmcoord;
-	coord= vertex->point;
-	point= point0;
-	for(k= qh hull_dim; k--; )
-	  *(gmcoord++)= *coord++ - *point++;
-      }
-    }
-    qh gm_row[i]= gmcoord;  /* for areasimplex */
-    if (qh RANDOMdist) {
-      gmcoord= qh gm_matrix;
-      for (i= qh hull_dim-1; i--; ) {
-	for (k= qh hull_dim; k--; )
-	  *(gmcoord++) *= qh_randomfactor();
-      }
-    }
-    qh_sethyperplane_gauss(qh hull_dim, qh gm_row, point0, facet->toporient,
-           	facet->normal, &facet->offset, &nearzero);
-    if (nearzero) { 
-      if (qh_orientoutside (facet)) {
-	trace0((qh ferr, "qh_setfacetplane: flipped orientation after testing interior_point during p%d\n", qh furthest_id));
-      /* this is part of using Gaussian Elimination.  For example in 5-d
-	   1 1 1 1 0
-	   1 1 1 1 1
-	   0 0 0 1 0
-	   0 1 0 0 0
-	   1 0 0 0 0
-	   norm= 0.38 0.38 -0.76 0.38 0
-	 has a determinate of 1, but g.e. after subtracting pt. 0 has
-	 0's in the diagonal, even with full pivoting.  It does work
-	 if you subtract pt. 4 instead. */
-      }
-    }
-  }
-  facet->upperdelaunay= False;
-  if (qh DELAUNAY) {
-    if (qh UPPERdelaunay) {     /* matches qh_triangulate_facet and qh.lower_threshold in qh_initbuild */
-      if (facet->normal[qh hull_dim -1] >= qh ANGLEround * qh_ZEROdelaunay)
-        facet->upperdelaunay= True;
-    }else {
-      if (facet->normal[qh hull_dim -1] > -qh ANGLEround * qh_ZEROdelaunay)
-        facet->upperdelaunay= True;
-    }
-  }
-  if (qh PRINTstatistics || qh IStracing || qh TRACElevel || qh JOGGLEmax < REALmax) {
-    qh old_randomdist= qh RANDOMdist;
-    qh RANDOMdist= False;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->point != point0) {
-	boolT istrace= False;
-	zinc_(Zdiststat);
-        qh_distplane(vertex->point, facet, &dist);
-        dist= fabs_(dist);
-        zinc_(Znewvertex);
-        wadd_(Wnewvertex, dist);
-        if (dist > wwval_(Wnewvertexmax)) {
-          wwval_(Wnewvertexmax)= dist;
-	  if (dist > qh max_outside) {
-	    qh max_outside= dist;  /* used by qh_maxouter() */
-	    if (dist > qh TRACEdist) 
-	      istrace= True;
-	  }
-	}else if (-dist > qh TRACEdist)
-	  istrace= True;
-	if (istrace) {
-	  fprintf (qh ferr, "qh_setfacetplane: ====== vertex p%d (v%d) increases max_outside to %2.2g for new facet f%d last p%d\n",
-	        qh_pointid(vertex->point), vertex->id, dist, facet->id, qh furthest_id);
-	  qh_errprint ("DISTANT", facet, NULL, NULL, NULL);
-	}
-      }
-    }
-    qh RANDOMdist= qh old_randomdist;
-  }
-  if (qh IStracing >= 3) {
-    fprintf (qh ferr, "qh_setfacetplane: f%d offset %2.2g normal: ",
-	     facet->id, facet->offset);
-    for (k=0; k < qh hull_dim; k++)
-      fprintf (qh ferr, "%2.2g ", facet->normal[k]);
-    fprintf (qh ferr, "\n");
-  }
-  if (facet == qh tracefacet)
-    qh IStracing= oldtrace;
-} /* setfacetplane */
-
-
-/*---------------------------------
-  
-  qh_sethyperplane_det( dim, rows, point0, toporient, normal, offset, nearzero )
-    given dim X dim array indexed by rows[], one row per point, 
-        toporient (flips all signs),
-        and point0 (any row)
-    set normalized hyperplane equation from oriented simplex
-
-  returns:
-    normal (normalized)
-    offset (places point0 on the hyperplane)
-    sets nearzero if hyperplane not through points
-
-  notes:
-    only defined for dim == 2..4
-    rows[] is not modified
-    solves det(P-V_0, V_n-V_0, ..., V_1-V_0)=0, i.e. every point is on hyperplane
-    see Bower & Woodworth, A programmer's geometry, Butterworths 1983.
-
-  derivation of 3-d minnorm
-    Goal: all vertices V_i within qh.one_merge of hyperplane
-    Plan: exactly translate the facet so that V_0 is the origin
-          exactly rotate the facet so that V_1 is on the x-axis and y_2=0.
-          exactly rotate the effective perturbation to only effect n_0
-	     this introduces a factor of sqrt(3)
-    n_0 = ((y_2-y_0)*(z_1-z_0) - (z_2-z_0)*(y_1-y_0)) / norm
-    Let M_d be the max coordinate difference
-    Let M_a be the greater of M_d and the max abs. coordinate
-    Let u be machine roundoff and distround be max error for distance computation
-    The max error for n_0 is sqrt(3) u M_a M_d / norm.  n_1 is approx. 1 and n_2 is approx. 0
-    The max error for distance of V_1 is sqrt(3) u M_a M_d M_d / norm.  Offset=0 at origin
-    Then minnorm = 1.8 u M_a M_d M_d / qh.ONEmerge
-    Note that qh.one_merge is approx. 45.5 u M_a and norm is usually about M_d M_d
-
-  derivation of 4-d minnorm
-    same as above except rotate the facet so that V_1 on x-axis and w_2, y_3, w_3=0
-     [if two vertices fixed on x-axis, can rotate the other two in yzw.]
-    n_0 = det3_(...) = y_2 det2_(z_1, w_1, z_3, w_3) = - y_2 w_1 z_3
-     [all other terms contain at least two factors nearly zero.]
-    The max error for n_0 is sqrt(4) u M_a M_d M_d / norm
-    Then minnorm = 2 u M_a M_d M_d M_d / qh.ONEmerge
-    Note that qh.one_merge is approx. 82 u M_a and norm is usually about M_d M_d M_d
-*/
-void qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 
-          boolT toporient, coordT *normal, realT *offset, boolT *nearzero) {
-  realT maxround, dist;
-  int i;
-  pointT *point;
-
-
-  if (dim == 2) {
-    normal[0]= dY(1,0);
-    normal[1]= dX(0,1);
-    qh_normalize2 (normal, dim, toporient, NULL, NULL);
-    *offset= -(point0[0]*normal[0]+point0[1]*normal[1]);
-    *nearzero= False;  /* since nearzero norm => incident points */
-  }else if (dim == 3) {
-    normal[0]= det2_(dY(2,0), dZ(2,0),
-		     dY(1,0), dZ(1,0));
-    normal[1]= det2_(dX(1,0), dZ(1,0),
-		     dX(2,0), dZ(2,0));
-    normal[2]= det2_(dX(2,0), dY(2,0),
-		     dX(1,0), dY(1,0));
-    qh_normalize2 (normal, dim, toporient, NULL, NULL);
-    *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
-	       + point0[2]*normal[2]);
-    maxround= qh DISTround;
-    for (i=dim; i--; ) {
-      point= rows[i];
-      if (point != point0) {
-        dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
-	       + point[2]*normal[2]);
-        if (dist > maxround || dist < -maxround) {
-  	  *nearzero= True;
-	  break;
-	}
-      }
-    }
-  }else if (dim == 4) {
-    normal[0]= - det3_(dY(2,0), dZ(2,0), dW(2,0),
-			dY(1,0), dZ(1,0), dW(1,0),
-			dY(3,0), dZ(3,0), dW(3,0));
-    normal[1]=   det3_(dX(2,0), dZ(2,0), dW(2,0),
-		        dX(1,0), dZ(1,0), dW(1,0),
-		        dX(3,0), dZ(3,0), dW(3,0));
-    normal[2]= - det3_(dX(2,0), dY(2,0), dW(2,0),
-			dX(1,0), dY(1,0), dW(1,0),
-			dX(3,0), dY(3,0), dW(3,0));
-    normal[3]=   det3_(dX(2,0), dY(2,0), dZ(2,0),
-		        dX(1,0), dY(1,0), dZ(1,0),
-		        dX(3,0), dY(3,0), dZ(3,0));
-    qh_normalize2 (normal, dim, toporient, NULL, NULL);
-    *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
-	       + point0[2]*normal[2] + point0[3]*normal[3]);
-    maxround= qh DISTround;
-    for (i=dim; i--; ) {
-      point= rows[i];
-      if (point != point0) {
-        dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
-	       + point[2]*normal[2] + point[3]*normal[3]);
-        if (dist > maxround || dist < -maxround) {
-  	  *nearzero= True;
-	  break;
-	}
-      }
-    }
-  }
-  if (*nearzero) {
-    zzinc_(Zminnorm);
-    trace0((qh ferr, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh furthest_id));
-    zzinc_(Znearlysingular);
-  }
-} /* sethyperplane_det */
-
-
-/*---------------------------------
-  
-  qh_sethyperplane_gauss( dim, rows, point0, toporient, normal, offset, nearzero )
-    given (dim-1) X dim array of rows[i]= V_{i+1} - V_0 (point0)
-    set normalized hyperplane equation from oriented simplex
-
-  returns:
-    normal (normalized)
-    offset (places point0 on the hyperplane)
-
-  notes:
-    if nearzero
-      orientation may be incorrect because of incorrect sign flips in gausselim
-    solves [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0 .. 0 1] 
-        or [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0] 
-    i.e., N is normal to the hyperplane, and the unnormalized
-        distance to [0 .. 1] is either 1 or   0
-
-  design:
-    perform gaussian elimination
-    flip sign for negative values
-    perform back substitution 
-    normalize result
-    compute offset
-*/
-void qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, 
-		boolT toporient, coordT *normal, coordT *offset, boolT *nearzero) {
-  coordT *pointcoord, *normalcoef;
-  int k;
-  boolT sign= toporient, nearzero2= False;
-  
-  qh_gausselim(rows, dim-1, dim, &sign, nearzero);
-  for(k= dim-1; k--; ) {
-    if ((rows[k])[k] < 0)
-      sign ^= 1;
-  }
-  if (*nearzero) {
-    zzinc_(Znearlysingular);
-    trace0((qh ferr, "qh_sethyperplane_gauss: nearly singular or axis parallel hyperplane during p%d.\n", qh furthest_id));
-    qh_backnormal(rows, dim-1, dim, sign, normal, &nearzero2);
-  }else {
-    qh_backnormal(rows, dim-1, dim, sign, normal, &nearzero2);
-    if (nearzero2) {
-      zzinc_(Znearlysingular);
-      trace0((qh ferr, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh furthest_id));
-    }
-  }
-  if (nearzero2)
-    *nearzero= True;
-  qh_normalize2(normal, dim, True, NULL, NULL);
-  pointcoord= point0;
-  normalcoef= normal;
-  *offset= -(*pointcoord++ * *normalcoef++);
-  for(k= dim-1; k--; )
-    *offset -= *pointcoord++ * *normalcoef++;
-} /* sethyperplane_gauss */
-
-  
-
diff --git a/extern/qhull/src/geom.h b/extern/qhull/src/geom.h
deleted file mode 100644
index 32440cff56f..00000000000
--- a/extern/qhull/src/geom.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
  ---------------------------------
-
-  geom.h 
-    header file for geometric routines
-
-   see qh-geom.htm and geom.c
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#ifndef qhDEFgeom
-#define qhDEFgeom 1
-
-/* ============ -macros- ======================== */
-
-/*----------------------------------
-   
-  fabs_(a)
-    returns the absolute value of a
-*/
-#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
-               
-/*----------------------------------
-  
-  fmax_(a,b)
-    returns the maximum value of a and b
-*/
-#define fmax_( a,b )  ( ( a ) < ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  fmin_(a,b)
-    returns the minimum value of a and b
-*/
-#define fmin_( a,b )  ( ( a ) > ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  maximize_(maxval, val)
-    set maxval to val if val is greater than maxval
-*/
-#define maximize_( maxval, val ) {if (( maxval ) < ( val )) ( maxval )= ( val );}
-
-/*----------------------------------
-
-  minimize_(minval, val)
-    set minval to val if val is less than minval
-*/
-#define minimize_( minval, val ) {if (( minval ) > ( val )) ( minval )= ( val );}
-
-/*----------------------------------
-
-  det2_(a1, a2,     
-        b1, b2)
-  
-    compute a 2-d determinate
-*/
-#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
-
-/*----------------------------------
-  
-  det3_(a1, a2, a3,    
-       b1, b2, b3,
-       c1, c2, c3)
-  
-    compute a 3-d determinate
-*/
-#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
-                - ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
-
-/*----------------------------------
-  
-  dX( p1, p2 )
-  dY( p1, p2 )
-  dZ( p1, p2 )
-  
-    given two indices into rows[],
-
-    compute the difference between X, Y, or Z coordinates
-*/
-#define dX( p1,p2 )  ( *( rows[p1] ) - *( rows[p2] ))
-#define dY( p1,p2 )  ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
-#define dZ( p1,p2 )  ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
-#define dW( p1,p2 )  ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
-
-/*============= prototypes in alphabetical order, infrequent at end ======= */
-
-void    qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
-void	qh_distplane (pointT *point, facetT *facet, realT *dist);
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT isnewfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbesthorizon (boolT ischeckmax, pointT *point, 
-	             facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet, realT *dist, 
-		     boolT bestoutside, boolT *isoutside, int *numpart);
-void 	qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
-realT   qh_getangle(pointT *vect1, pointT *vect2);
-pointT *qh_getcenter(setT *vertices);
-pointT *qh_getcentrum(facetT *facet);
-realT   qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
-void    qh_normalize (coordT *normal, int dim, boolT toporient);
-void    qh_normalize2 (coordT *normal, int dim, boolT toporient, 
-            realT *minnorm, boolT *ismin);
-pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist);
-
-void    qh_setfacetplane(facetT *newfacets);
-void 	qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 
-              boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
-void 	qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, 
-	     boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
-boolT   qh_sharpnewfacets (void);
-
-/*========= infrequently used code in geom2.c =============*/
-
-
-coordT *qh_copypoints (coordT *points, int numpoints, int dimension);
-void    qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
-realT 	qh_determinant (realT **rows, int dim, boolT *nearzero);
-realT   qh_detjoggle (pointT *points, int numpoints, int dimension);
-void    qh_detroundoff (void);
-realT   qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero);
-realT   qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp);
-realT   qh_distround (int dimension, realT maxabs, realT maxsumabs);
-realT   qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
-realT   qh_facetarea (facetT *facet);
-realT   qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, 
-          vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset);
-pointT *qh_facetcenter (setT *vertices);
-facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
-void    qh_getarea (facetT *facetlist);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-boolT   qh_inthresholds (coordT *normal, realT *angle);
-void    qh_joggleinput (void);
-realT  *qh_maxabsval (realT *normal, int dim);
-setT   *qh_maxmin(pointT *points, int numpoints, int dimension);
-realT   qh_maxouter (void);
-void    qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
-realT   qh_minabsval (realT *normal, int dim);
-int     qh_mindiff (realT *vecA, realT *vecB, int dim);
-boolT   qh_orientoutside (facetT *facet);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-coordT  qh_pointdist(pointT *point1, pointT *point2, int dim);
-void    qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol);
-void    qh_printpoints (FILE *fp, char *string, setT *points);
-void    qh_projectinput (void);
-void 	qh_projectpoints (signed char *project, int n, realT *points, 
-             int numpoints, int dim, realT *newpoints, int newdim);
-int     qh_rand( void);
-void    qh_srand( int seed);
-realT   qh_randomfactor (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_rotatepoints (realT *points, int numpoints, int dim, realT **rows);
-void    qh_scaleinput (void);
-void    qh_scalelast (coordT *points, int numpoints, int dim, coordT low,
-		   coordT high, coordT newhigh);
-void 	qh_scalepoints (pointT *points, int numpoints, int dim,
-  		realT *newlows, realT *newhighs);
-boolT   qh_sethalfspace (int dim, coordT *coords, coordT **nextp, 
-              coordT *normal, coordT *offset, coordT *feasible);
-coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-pointT *qh_voronoi_center (int dim, setT *points);
-
-#endif /* qhDEFgeom */
-
-
-
diff --git a/extern/qhull/src/geom2.c b/extern/qhull/src/geom2.c
deleted file mode 100644
index bd58ce1282b..00000000000
--- a/extern/qhull/src/geom2.c
+++ /dev/null
@@ -1,2160 +0,0 @@
-/*
  ---------------------------------
-
-
-   geom2.c 
-   infrequently used geometric routines of qhull
-
-   see qh-geom.htm and geom.h
-
-   copyright (c) 1993-2002 The Geometry Center        
-
-   frequently used code goes into geom.c
-*/
-   
-#include "qhull_a.h"
-   
-/*================== functions in alphabetic order ============*/
-
-/*---------------------------------
-
-  qh_copypoints( points, numpoints, dimension)
-    return malloc'd copy of points
-*/
-coordT *qh_copypoints (coordT *points, int numpoints, int dimension) {
-  int size;
-  coordT *newpoints;
-
-  size= numpoints * dimension * sizeof(coordT);
-  if (!(newpoints=(coordT*)malloc(size))) {
-    fprintf(qh ferr, "qhull error: insufficient memory to copy %d points\n",
-        numpoints);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  memcpy ((char *)newpoints, (char *)points, size);
-  return newpoints;
-} /* copypoints */
-
-/*---------------------------------
-  
-  qh_crossproduct( dim, vecA, vecB, vecC )
-    crossproduct of 2 dim vectors
-    C= A x B
-  
-  notes:
-    from Glasner, Graphics Gems I, p. 639
-    only defined for dim==3
-*/
-void qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]){
-
-  if (dim == 3) {
-    vecC[0]=   det2_(vecA[1], vecA[2],
-		     vecB[1], vecB[2]);
-    vecC[1]= - det2_(vecA[0], vecA[2],
-		     vecB[0], vecB[2]);
-    vecC[2]=   det2_(vecA[0], vecA[1],
-		     vecB[0], vecB[1]);
-  }
-} /* vcross */
-
-/*---------------------------------
-  
-  qh_determinant( rows, dim, nearzero )
-    compute signed determinant of a square matrix
-    uses qh.NEARzero to test for degenerate matrices
-
-  returns:
-    determinant
-    overwrites rows and the matrix
-    if dim == 2 or 3
-      nearzero iff determinant < qh NEARzero[dim-1]
-      (not quite correct, not critical)
-    if dim >= 4
-      nearzero iff diagonal[k] < qh NEARzero[k]
-*/
-realT qh_determinant (realT **rows, int dim, boolT *nearzero) {
-  realT det=0;
-  int i;
-  boolT sign= False;
-
-  *nearzero= False;
-  if (dim < 2) {
-    fprintf (qh ferr, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }else if (dim == 2) {
-    det= det2_(rows[0][0], rows[0][1],
-		 rows[1][0], rows[1][1]);
-    if (fabs_(det) < qh NEARzero[1])  /* not really correct, what should this be? */
-      *nearzero= True;
-  }else if (dim == 3) {
-    det= det3_(rows[0][0], rows[0][1], rows[0][2],
-		 rows[1][0], rows[1][1], rows[1][2],
-		 rows[2][0], rows[2][1], rows[2][2]);
-    if (fabs_(det) < qh NEARzero[2])  /* not really correct, what should this be? */
-      *nearzero= True;
-  }else {	
-    qh_gausselim(rows, dim, dim, &sign, nearzero);  /* if nearzero, diagonal still ok*/
-    det= 1.0;
-    for (i= dim; i--; )
-      det *= (rows[i])[i];
-    if (sign)
-      det= -det;
-  }
-  return det;
-} /* determinant */
-
-/*---------------------------------
-  
-  qh_detjoggle( points, numpoints, dimension )
-    determine default max joggle for point array
-      as qh_distround * qh_JOGGLEdefault
-
-  returns:
-    initial value for JOGGLEmax from points and REALepsilon
-
-  notes:
-    computes DISTround since qh_maxmin not called yet
-    if qh SCALElast, last dimension will be scaled later to MAXwidth
-
-    loop duplicated from qh_maxmin
-*/
-realT qh_detjoggle (pointT *points, int numpoints, int dimension) {
-  realT abscoord, distround, joggle, maxcoord, mincoord;
-  pointT *point, *pointtemp;
-  realT maxabs= -REALmax;
-  realT sumabs= 0;
-  realT maxwidth= 0;
-  int k;
-
-  for (k= 0; k < dimension; k++) {
-    if (qh SCALElast && k == dimension-1)
-      abscoord= maxwidth;
-    else if (qh DELAUNAY && k == dimension-1) /* will qh_setdelaunay() */
-      abscoord= 2 * maxabs * maxabs;  /* may be low by qh hull_dim/2 */
-    else {
-      maxcoord= -REALmax;
-      mincoord= REALmax;
-      FORALLpoint_(points, numpoints) {
-	maximize_(maxcoord, point[k]);
-        minimize_(mincoord, point[k]);
-      }
-      maximize_(maxwidth, maxcoord-mincoord);
-      abscoord= fmax_(maxcoord, -mincoord);
-    }
-    sumabs += abscoord;
-    maximize_(maxabs, abscoord);
-  } /* for k */
-  distround= qh_distround (qh hull_dim, maxabs, sumabs);
-  joggle= distround * qh_JOGGLEdefault;
-  maximize_(joggle, REALepsilon * qh_JOGGLEdefault);
-  trace2((qh ferr, "qh_detjoggle: joggle=%2.2g maxwidth=%2.2g\n", joggle, maxwidth));
-  return joggle;
-} /* detjoggle */
-
-/*---------------------------------
-  
-  qh_detroundoff()
-    determine maximum roundoff errors from
-      REALepsilon, REALmax, REALmin, qh.hull_dim, qh.MAXabs_coord, 
-      qh.MAXsumcoord, qh.MAXwidth, qh.MINdenom_1
-
-    accounts for qh.SETroundoff, qh.RANDOMdist, qh MERGEexact
-      qh.premerge_cos, qh.postmerge_cos, qh.premerge_centrum,
-      qh.postmerge_centrum, qh.MINoutside,
-      qh_RATIOnearinside, qh_COPLANARratio, qh_WIDEcoplanar
-
-  returns:
-    sets qh.DISTround, etc. (see below)
-    appends precision constants to qh.qhull_options
-
-  see:
-    qh_maxmin() for qh.NEARzero
-
-  design:
-    determine qh.DISTround for distance computations
-    determine minimum denominators for qh_divzero
-    determine qh.ANGLEround for angle computations
-    adjust qh.premerge_cos,... for roundoff error
-    determine qh.ONEmerge for maximum error due to a single merge
-    determine qh.NEARinside, qh.MAXcoplanar, qh.MINvisible,
-      qh.MINoutside, qh.WIDEfacet
-    initialize qh.max_vertex and qh.minvertex
-*/
-void qh_detroundoff (void) {
-
-  qh_option ("_max-width", NULL, &qh MAXwidth);
-  if (!qh SETroundoff) {
-    qh DISTround= qh_distround (qh hull_dim, qh MAXabs_coord, qh MAXsumcoord);
-    if (qh RANDOMdist)
-      qh DISTround += qh RANDOMfactor * qh MAXabs_coord;
-    qh_option ("Error-roundoff", NULL, &qh DISTround);
-  }
-  qh MINdenom= qh MINdenom_1 * qh MAXabs_coord;
-  qh MINdenom_1_2= sqrt (qh MINdenom_1 * qh hull_dim) ;  /* if will be normalized */
-  qh MINdenom_2= qh MINdenom_1_2 * qh MAXabs_coord;
-                                              /* for inner product */
-  qh ANGLEround= 1.01 * qh hull_dim * REALepsilon;
-  if (qh RANDOMdist)
-    qh ANGLEround += qh RANDOMfactor;
-  if (qh premerge_cos < REALmax/2) {
-    qh premerge_cos -= qh ANGLEround;
-    if (qh RANDOMdist) 
-      qh_option ("Angle-premerge-with-random", NULL, &qh premerge_cos);
-  }
-  if (qh postmerge_cos < REALmax/2) {
-    qh postmerge_cos -= qh ANGLEround;
-    if (qh RANDOMdist)
-      qh_option ("Angle-postmerge-with-random", NULL, &qh postmerge_cos);
-  }
-  qh premerge_centrum += 2 * qh DISTround;    /*2 for centrum and distplane()*/
-  qh postmerge_centrum += 2 * qh DISTround;
-  if (qh RANDOMdist && (qh MERGEexact || qh PREmerge))
-    qh_option ("Centrum-premerge-with-random", NULL, &qh premerge_centrum);
-  if (qh RANDOMdist && qh POSTmerge)
-    qh_option ("Centrum-postmerge-with-random", NULL, &qh postmerge_centrum);
-  { /* compute ONEmerge, max vertex offset for merging simplicial facets */
-    realT maxangle= 1.0, maxrho;
-    
-    minimize_(maxangle, qh premerge_cos);
-    minimize_(maxangle, qh postmerge_cos);
-    /* max diameter * sin theta + DISTround for vertex to its hyperplane */
-    qh ONEmerge= sqrt (qh hull_dim) * qh MAXwidth *
-      sqrt (1.0 - maxangle * maxangle) + qh DISTround;  
-    maxrho= qh hull_dim * qh premerge_centrum + qh DISTround;
-    maximize_(qh ONEmerge, maxrho);
-    maxrho= qh hull_dim * qh postmerge_centrum + qh DISTround;
-    maximize_(qh ONEmerge, maxrho);
-    if (qh MERGING)
-      qh_option ("_one-merge", NULL, &qh ONEmerge);
-  }
-  qh NEARinside= qh ONEmerge * qh_RATIOnearinside; /* only used if qh KEEPnearinside */
-  if (qh JOGGLEmax < REALmax/2 && (qh KEEPcoplanar || qh KEEPinside)) {
-    realT maxdist;	       /* adjust qh.NEARinside for joggle */
-    qh KEEPnearinside= True;   
-    maxdist= sqrt (qh hull_dim) * qh JOGGLEmax + qh DISTround;
-    maxdist= 2*maxdist;        /* vertex and coplanar point can joggle in opposite directions */
-    maximize_(qh NEARinside, maxdist);  /* must agree with qh_nearcoplanar() */
-  }
-  if (qh KEEPnearinside)
-    qh_option ("_near-inside", NULL, &qh NEARinside);
-  if (qh JOGGLEmax < qh DISTround) {
-    fprintf (qh ferr, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n",
-         qh JOGGLEmax, qh DISTround);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (qh MINvisible > REALmax/2) {
-    if (!qh MERGING)
-      qh MINvisible= qh DISTround;
-    else if (qh hull_dim <= 3)
-      qh MINvisible= qh premerge_centrum;
-    else
-      qh MINvisible= qh_COPLANARratio * qh premerge_centrum;
-    if (qh APPROXhull && qh MINvisible > qh MINoutside)
-      qh MINvisible= qh MINoutside;
-    qh_option ("Visible-distance", NULL, &qh MINvisible);
-  }
-  if (qh MAXcoplanar > REALmax/2) {
-    qh MAXcoplanar= qh MINvisible;
-    qh_option ("U-coplanar-distance", NULL, &qh MAXcoplanar);
-  }
-  if (!qh APPROXhull) {             /* user may specify qh MINoutside */
-    qh MINoutside= 2 * qh MINvisible;
-    if (qh premerge_cos < REALmax/2) 
-      maximize_(qh MINoutside, (1- qh premerge_cos) * qh MAXabs_coord);
-    qh_option ("Width-outside", NULL, &qh MINoutside);
-  }
-  qh WIDEfacet= qh MINoutside;
-  maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MAXcoplanar); 
-  maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MINvisible); 
-  qh_option ("_wide-facet", NULL, &qh WIDEfacet);
-  if (qh MINvisible > qh MINoutside + 3 * REALepsilon 
-  && !qh BESToutside && !qh FORCEoutput)
-    fprintf (qh ferr, "qhull input warning: minimum visibility V%.2g is greater than \nminimum outside W%.2g.  Flipped facets are likely.\n",
-	     qh MINvisible, qh MINoutside);
-  qh max_vertex= qh DISTround;
-  qh min_vertex= -qh DISTround;
-  /* numeric constants reported in printsummary */
-} /* detroundoff */
-
-/*---------------------------------
-  
-  qh_detsimplex( apex, points, dim, nearzero )
-    compute determinant of a simplex with point apex and base points
-
-  returns:
-     signed determinant and nearzero from qh_determinant
-
-  notes:
-     uses qh.gm_matrix/qh.gm_row (assumes they're big enough)
-
-  design:
-    construct qm_matrix by subtracting apex from points
-    compute determinate
-*/
-realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero) {
-  pointT *coorda, *coordp, *gmcoord, *point, **pointp;
-  coordT **rows;
-  int k,  i=0;
-  realT det;
-
-  zinc_(Zdetsimplex);
-  gmcoord= qh gm_matrix;
-  rows= qh gm_row;
-  FOREACHpoint_(points) {
-    if (i == dim)
-      break;
-    rows[i++]= gmcoord;
-    coordp= point;
-    coorda= apex;
-    for (k= dim; k--; )
-      *(gmcoord++)= *coordp++ - *coorda++;
-  }
-  if (i < dim) {
-    fprintf (qh ferr, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n", 
-               i, dim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  det= qh_determinant (rows, dim, nearzero);
-  trace2((qh ferr, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n",
-	  det, qh_pointid(apex), dim, *nearzero)); 
-  return det;
-} /* detsimplex */
-
-/*---------------------------------
-  
-  qh_distnorm( dim, point, normal, offset )
-    return distance from point to hyperplane at normal/offset
-
-  returns:
-    dist
-  
-  notes:  
-    dist > 0 if point is outside of hyperplane
-  
-  see:
-    qh_distplane in geom.c
-*/
-realT qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp) {
-  coordT *normalp= normal, *coordp= point;
-  realT dist;
-  int k;
-
-  dist= *offsetp;
-  for (k= dim; k--; )
-    dist += *(coordp++) * *(normalp++);
-  return dist;
-} /* distnorm */
-
-/*---------------------------------
-
-  qh_distround ( dimension, maxabs, maxsumabs )
-    compute maximum round-off error for a distance computation
-      to a normalized hyperplane
-    maxabs is the maximum absolute value of a coordinate
-    maxsumabs is the maximum possible sum of absolute coordinate values
-
-  returns:
-    max dist round for REALepsilon
-
-  notes:
-    calculate roundoff error according to
-    Lemma 3.2-1 of Golub and van Loan "Matrix Computation"
-    use sqrt(dim) since one vector is normalized
-      or use maxsumabs since one vector is < 1
-*/
-realT qh_distround (int dimension, realT maxabs, realT maxsumabs) {
-  realT maxdistsum, maxround;
-
-  maxdistsum= sqrt (dimension) * maxabs;
-  minimize_( maxdistsum, maxsumabs);
-  maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs);
-              /* adds maxabs for offset */
-  trace4((qh ferr, "qh_distround: %2.2g maxabs %2.2g maxsumabs %2.2g maxdistsum %2.2g\n",
-	         maxround, maxabs, maxsumabs, maxdistsum));
-  return maxround;
-} /* distround */
-
-/*---------------------------------
-  
-  qh_divzero( numer, denom, mindenom1, zerodiv )
-    divide by a number that's nearly zero
-    mindenom1= minimum denominator for dividing into 1.0
-
-  returns:
-    quotient
-    sets zerodiv and returns 0.0 if it would overflow
-  
-  design:
-    if numer is nearly zero and abs(numer) < abs(denom)
-      return numer/denom
-    else if numer is nearly zero
-      return 0 and zerodiv
-    else if denom/numer non-zero
-      return numer/denom
-    else
-      return 0 and zerodiv
-*/
-realT qh_divzero (realT numer, realT denom, realT mindenom1, boolT *zerodiv) {
-  realT temp, numerx, denomx;
-  
-
-  if (numer < mindenom1 && numer > -mindenom1) {
-    numerx= fabs_(numer);
-    denomx= fabs_(denom);
-    if (numerx < denomx) {
-      *zerodiv= False;
-      return numer/denom;
-    }else {
-      *zerodiv= True;
-      return 0.0;
-    }
-  }
-  temp= denom/numer;
-  if (temp > mindenom1 || temp < -mindenom1) {
-    *zerodiv= False;
-    return numer/denom;
-  }else {
-    *zerodiv= True;
-    return 0.0;
-  }
-} /* divzero */
-  
-
-/*---------------------------------
-
-  qh_facetarea( facet )
-    return area for a facet
-  
-  notes:
-    if non-simplicial, 
-      uses centrum to triangulate facet and sums the projected areas.
-    if (qh DELAUNAY),
-      computes projected area instead for last coordinate
-    assumes facet->normal exists
-    projecting tricoplanar facets to the hyperplane does not appear to make a difference
-  
-  design:
-    if simplicial
-      compute area
-    else
-      for each ridge
-        compute area from centrum to ridge
-    negate area if upper Delaunay facet
-*/
-realT qh_facetarea (facetT *facet) {
-  vertexT *apex;
-  pointT *centrum;
-  realT area= 0.0;
-  ridgeT *ridge, **ridgep;
-
-  if (facet->simplicial) {
-    apex= SETfirstt_(facet->vertices, vertexT);
-    area= qh_facetarea_simplex (qh hull_dim, apex->point, facet->vertices, 
-                    apex, facet->toporient, facet->normal, &facet->offset);
-  }else {
-    if (qh CENTERtype == qh_AScentrum)
-      centrum= facet->center;
-    else
-      centrum= qh_getcentrum (facet);
-    FOREACHridge_(facet->ridges) 
-      area += qh_facetarea_simplex (qh hull_dim, centrum, ridge->vertices, 
-                 NULL, (ridge->top == facet),  facet->normal, &facet->offset);
-    if (qh CENTERtype != qh_AScentrum)
-      qh_memfree (centrum, qh normal_size);
-  }
-  if (facet->upperdelaunay && qh DELAUNAY)
-    area= -area;  /* the normal should be [0,...,1] */
-  trace4((qh ferr, "qh_facetarea: f%d area %2.2g\n", facet->id, area)); 
-  return area;
-} /* facetarea */
-
-/*---------------------------------
-
-  qh_facetarea_simplex( dim, apex, vertices, notvertex, toporient, normal, offset )
-    return area for a simplex defined by 
-      an apex, a base of vertices, an orientation, and a unit normal
-    if simplicial or tricoplanar facet, 
-      notvertex is defined and it is skipped in vertices
-  
-  returns:
-    computes area of simplex projected to plane [normal,offset]
-    returns 0 if vertex too far below plane (qh WIDEfacet)
-      vertex can't be apex of tricoplanar facet
-  
-  notes:
-    if (qh DELAUNAY),
-      computes projected area instead for last coordinate
-    uses qh gm_matrix/gm_row and qh hull_dim
-    helper function for qh_facetarea
-  
-  design:
-    if Notvertex
-      translate simplex to apex
-    else
-      project simplex to normal/offset
-      translate simplex to apex
-    if Delaunay
-      set last row/column to 0 with -1 on diagonal 
-    else
-      set last row to Normal
-    compute determinate
-    scale and flip sign for area
-*/
-realT qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, 
-        vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset) {
-  pointT *coorda, *coordp, *gmcoord;
-  coordT **rows, *normalp;
-  int k,  i=0;
-  realT area, dist;
-  vertexT *vertex, **vertexp;
-  boolT nearzero;
-
-  gmcoord= qh gm_matrix;
-  rows= qh gm_row;
-  FOREACHvertex_(vertices) {
-    if (vertex == notvertex)
-      continue;
-    rows[i++]= gmcoord;
-    coorda= apex;
-    coordp= vertex->point;
-    normalp= normal;
-    if (notvertex) {
-      for (k= dim; k--; )
-	*(gmcoord++)= *coordp++ - *coorda++;
-    }else {
-      dist= *offset;
-      for (k= dim; k--; )
-	dist += *coordp++ * *normalp++;
-      if (dist < -qh WIDEfacet) {
-	zinc_(Znoarea);
-	return 0.0;
-      }
-      coordp= vertex->point;
-      normalp= normal;
-      for (k= dim; k--; )
-	*(gmcoord++)= (*coordp++ - dist * *normalp++) - *coorda++;
-    }
-  }
-  if (i != dim-1) {
-    fprintf (qh ferr, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n", 
-               i, dim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  rows[i]= gmcoord;
-  if (qh DELAUNAY) {
-    for (i= 0; i < dim-1; i++)
-      rows[i][dim-1]= 0.0;
-    for (k= dim; k--; )
-      *(gmcoord++)= 0.0;
-    rows[dim-1][dim-1]= -1.0;
-  }else {
-    normalp= normal;
-    for (k= dim; k--; )
-      *(gmcoord++)= *normalp++;
-  }
-  zinc_(Zdetsimplex);
-  area= qh_determinant (rows, dim, &nearzero);
-  if (toporient)
-    area= -area;
-  area *= qh AREAfactor;
-  trace4((qh ferr, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n",
-	  area, qh_pointid(apex), toporient, nearzero)); 
-  return area;
-} /* facetarea_simplex */
-
-/*---------------------------------
-  
-  qh_facetcenter( vertices )
-    return Voronoi center (Voronoi vertex) for a facet's vertices
-
-  returns:
-    return temporary point equal to the center
-    
-  see:
-    qh_voronoi_center()
-*/
-pointT *qh_facetcenter (setT *vertices) {
-  setT *points= qh_settemp (qh_setsize (vertices));
-  vertexT *vertex, **vertexp;
-  pointT *center;
-  
-  FOREACHvertex_(vertices) 
-    qh_setappend (&points, vertex->point);
-  center= qh_voronoi_center (qh hull_dim-1, points);
-  qh_settempfree (&points);
-  return center;
-} /* facetcenter */
-
-/*---------------------------------
-  
-  qh_findgooddist( point, facetA, dist, facetlist )
-    find best good facet visible for point from facetA
-    assumes facetA is visible from point
-
-  returns:
-    best facet, i.e., good facet that is furthest from point
-      distance to best facet
-      NULL if none
-      
-    moves good, visible facets (and some other visible facets)
-      to end of qh facet_list
-
-  notes:
-    uses qh visit_id
-
-  design:
-    initialize bestfacet if facetA is good
-    move facetA to end of facetlist
-    for each facet on facetlist
-      for each unvisited neighbor of facet
-        move visible neighbors to end of facetlist
-        update best good neighbor
-        if no good neighbors, update best facet
-*/
-facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, 
-               facetT **facetlist) {
-  realT bestdist= -REALmax, dist;
-  facetT *neighbor, **neighborp, *bestfacet=NULL, *facet;
-  boolT goodseen= False;  
-
-  if (facetA->good) {
-    zinc_(Zcheckpart);  /* calls from check_bestdist occur after print stats */
-    qh_distplane (point, facetA, &bestdist);
-    bestfacet= facetA;
-    goodseen= True;
-  }
-  qh_removefacet (facetA);
-  qh_appendfacet (facetA);
-  *facetlist= facetA;
-  facetA->visitid= ++qh visit_id;
-  FORALLfacet_(*facetlist) {
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid == qh visit_id)
-        continue;
-      neighbor->visitid= qh visit_id;
-      if (goodseen && !neighbor->good)
-        continue;
-      zinc_(Zcheckpart); 
-      qh_distplane (point, neighbor, &dist);
-      if (dist > 0) {
-        qh_removefacet (neighbor);
-        qh_appendfacet (neighbor);
-        if (neighbor->good) {
-          goodseen= True;
-          if (dist > bestdist) {
-            bestdist= dist;
-            bestfacet= neighbor;
-          }
-        }
-      }
-    }
-  }
-  if (bestfacet) {
-    *distp= bestdist;
-    trace2((qh ferr, "qh_findgooddist: p%d is %2.2g above good facet f%d\n",
-      qh_pointid(point), bestdist, bestfacet->id));
-    return bestfacet;
-  }
-  trace4((qh ferr, "qh_findgooddist: no good facet for p%d above f%d\n", 
-      qh_pointid(point), facetA->id));
-  return NULL;
-}  /* findgooddist */
-    
-/*---------------------------------
-  
-  qh_getarea( facetlist )
-    set area of all facets in facetlist
-    collect statistics
-
-  returns:
-    sets qh totarea/totvol to total area and volume of convex hull
-    for Delaunay triangulation, computes projected area of the lower or upper hull
-      ignores upper hull if qh ATinfinity
-  
-  notes:
-    could compute outer volume by expanding facet area by rays from interior
-    the following attempt at perpendicular projection underestimated badly:
-      qh.totoutvol += (-dist + facet->maxoutside + qh DISTround) 
-                            * area/ qh hull_dim;
-  design:
-    for each facet on facetlist
-      compute facet->area
-      update qh.totarea and qh.totvol
-*/
-void qh_getarea (facetT *facetlist) {
-  realT area;
-  realT dist;
-  facetT *facet;
-
-  if (qh REPORTfreq)
-    fprintf (qh ferr, "computing area of each facet and volume of the convex hull\n");
-  else 
-    trace1((qh ferr, "qh_getarea: computing volume and area for each facet\n"));
-  qh totarea= qh totvol= 0.0;
-  FORALLfacet_(facetlist) {
-    if (!facet->normal)
-      continue;
-    if (facet->upperdelaunay && qh ATinfinity)
-      continue;
-    facet->f.area= area= qh_facetarea (facet);
-    facet->isarea= True;
-    if (qh DELAUNAY) {
-      if (facet->upperdelaunay == qh UPPERdelaunay)
-	qh totarea += area;
-    }else {
-      qh totarea += area;
-      qh_distplane (qh interior_point, facet, &dist);
-      qh totvol += -dist * area/ qh hull_dim;
-    }
-    if (qh PRINTstatistics) {
-      wadd_(Wareatot, area);
-      wmax_(Wareamax, area);
-      wmin_(Wareamin, area);
-    }
-  }
-} /* getarea */
-
-/*---------------------------------
-  
-  qh_gram_schmidt( dim, row )
-    implements Gram-Schmidt orthogonalization by rows
-
-  returns:
-    false if zero norm
-    overwrites rows[dim][dim]
-
-  notes:
-    see Golub & van Loan Algorithm 6.2-2
-    overflow due to small divisors not handled
-
-  design:
-    for each row
-      compute norm for row
-      if non-zero, normalize row
-      for each remaining rowA
-        compute inner product of row and rowA
-        reduce rowA by row * inner product
-*/
-boolT qh_gram_schmidt(int dim, realT **row) {
-  realT *rowi, *rowj, norm;
-  int i, j, k;
-  
-  for(i=0; i < dim; i++) {
-    rowi= row[i];
-    for (norm= 0.0, k= dim; k--; rowi++)
-      norm += *rowi * *rowi;
-    norm= sqrt(norm);
-    wmin_(Wmindenom, norm);
-    if (norm == 0.0)  /* either 0 or overflow due to sqrt */
-      return False;
-    for(k= dim; k--; )
-      *(--rowi) /= norm;  
-    for(j= i+1; j < dim; j++) {
-      rowj= row[j];
-      for(norm= 0.0, k=dim; k--; )
-	norm += *rowi++ * *rowj++;
-      for(k=dim; k--; )
-	*(--rowj) -= *(--rowi) * norm;
-    }
-  }
-  return True;
-} /* gram_schmidt */
-
-
-/*---------------------------------
-  
-  qh_inthresholds( normal, angle )
-    return True if normal within qh.lower_/upper_threshold
-
-  returns:
-    estimate of angle by summing of threshold diffs
-      angle may be NULL
-      smaller "angle" is better
-  
-  notes:
-    invalid if qh.SPLITthresholds
-
-  see:
-    qh.lower_threshold in qh_initbuild()
-    qh_initthresholds()
-
-  design:
-    for each dimension
-      test threshold
-*/
-boolT qh_inthresholds (coordT *normal, realT *angle) {
-  boolT within= True;
-  int k;
-  realT threshold;
-
-  if (angle)
-    *angle= 0.0;
-  for(k= 0; k < qh hull_dim; k++) {
-    threshold= qh lower_threshold[k];
-    if (threshold > -REALmax/2) {
-      if (normal[k] < threshold)
-        within= False;
-      if (angle) {
-	threshold -= normal[k];
-	*angle += fabs_(threshold);
-      }
-    }
-    if (qh upper_threshold[k] < REALmax/2) {
-      threshold= qh upper_threshold[k];
-      if (normal[k] > threshold)
-        within= False;
-      if (angle) {
-	threshold -= normal[k];
-	*angle += fabs_(threshold);
-      }
-    }
-  }
-  return within;
-} /* inthresholds */
-    
-
-/*---------------------------------
-  
-  qh_joggleinput()
-    randomly joggle input to Qhull by qh.JOGGLEmax
-    initial input is qh.first_point/qh.num_points of qh.hull_dim
-      repeated calls use qh.input_points/qh.num_points
- 
-  returns:
-    joggles points at qh.first_point/qh.num_points
-    copies data to qh.input_points/qh.input_malloc if first time
-    determines qh.JOGGLEmax if it was zero
-    if qh.DELAUNAY
-      computes the Delaunay projection of the joggled points
-
-  notes:
-    if qh.DELAUNAY, unnecessarily joggles the last coordinate
-    the initial 'QJn' may be set larger than qh_JOGGLEmaxincrease
-
-  design:
-    if qh.DELAUNAY
-      set qh.SCALElast for reduced precision errors
-    if first call
-      initialize qh.input_points to the original input points
-      if qh.JOGGLEmax == 0
-        determine default qh.JOGGLEmax
-    else
-      increase qh.JOGGLEmax according to qh.build_cnt
-    joggle the input by adding a random number in [-qh.JOGGLEmax,qh.JOGGLEmax]
-    if qh.DELAUNAY
-      sets the Delaunay projection
-*/
-void qh_joggleinput (void) {
-  int size, i, seed;
-  coordT *coordp, *inputp;
-  realT randr, randa, randb;
-
-  if (!qh input_points) { /* first call */
-    qh input_points= qh first_point;
-    qh input_malloc= qh POINTSmalloc;
-    size= qh num_points * qh hull_dim * sizeof(coordT);
-    if (!(qh first_point=(coordT*)malloc(size))) {
-      fprintf(qh ferr, "qhull error: insufficient memory to joggle %d points\n",
-          qh num_points);
-      qh_errexit(qh_ERRmem, NULL, NULL);
-    }
-    qh POINTSmalloc= True;
-    if (qh JOGGLEmax == 0.0) {
-      qh JOGGLEmax= qh_detjoggle (qh input_points, qh num_points, qh hull_dim);
-      qh_option ("QJoggle", NULL, &qh JOGGLEmax);
-    }
-  }else {                 /* repeated call */
-    if (!qh RERUN && qh build_cnt > qh_JOGGLEretry) {
-      if (((qh build_cnt-qh_JOGGLEretry-1) % qh_JOGGLEagain) == 0) {
-	realT maxjoggle= qh MAXwidth * qh_JOGGLEmaxincrease;
-	if (qh JOGGLEmax < maxjoggle) {
-	  qh JOGGLEmax *= qh_JOGGLEincrease;
-	  minimize_(qh JOGGLEmax, maxjoggle); 
-	}
-      }
-    }
-    qh_option ("QJoggle", NULL, &qh JOGGLEmax);
-  }
-  if (qh build_cnt > 1 && qh JOGGLEmax > fmax_(qh MAXwidth/4, 0.1)) {
-      fprintf (qh ferr, "qhull error: the current joggle for 'QJn', %.2g, is too large for the width\nof the input.  If possible, recompile Qhull with higher-precision reals.\n",
-	        qh JOGGLEmax);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  /* for some reason, using qh ROTATErandom and qh_RANDOMseed does not repeat the run. Use 'TRn' instead */
-  seed= qh_RANDOMint;
-  qh_option ("_joggle-seed", &seed, NULL);
-  trace0((qh ferr, "qh_joggleinput: joggle input by %2.2g with seed %d\n", 
-    qh JOGGLEmax, seed));
-  inputp= qh input_points;
-  coordp= qh first_point;
-  randa= 2.0 * qh JOGGLEmax/qh_RANDOMmax;
-  randb= -qh JOGGLEmax;
-  size= qh num_points * qh hull_dim;
-  for (i= size; i--; ) {
-    randr= qh_RANDOMint;
-    *(coordp++)= *(inputp++) + (randr * randa + randb);
-  }
-  if (qh DELAUNAY) {
-    qh last_low= qh last_high= qh last_newhigh= REALmax;
-    qh_setdelaunay (qh hull_dim, qh num_points, qh first_point);
-  }
-} /* joggleinput */
-
-/*---------------------------------
-  
-  qh_maxabsval( normal, dim )
-    return pointer to maximum absolute value of a dim vector
-    returns NULL if dim=0
-*/
-realT *qh_maxabsval (realT *normal, int dim) {
-  realT maxval= -REALmax;
-  realT *maxp= NULL, *colp, absval;
-  int k;
-
-  for (k= dim, colp= normal; k--; colp++) {
-    absval= fabs_(*colp);
-    if (absval > maxval) {
-      maxval= absval;
-      maxp= colp;
-    }
-  }
-  return maxp;
-} /* maxabsval */
-
-
-/*---------------------------------
-  
-  qh_maxmin( points, numpoints, dimension )
-    return max/min points for each dimension      
-    determine max and min coordinates
-
-  returns:
-    returns a temporary set of max and min points
-      may include duplicate points. Does not include qh.GOODpoint
-    sets qh.NEARzero, qh.MAXabs_coord, qh.MAXsumcoord, qh.MAXwidth
-         qh.MAXlastcoord, qh.MINlastcoord
-    initializes qh.max_outside, qh.min_vertex, qh.WAScoplanar, qh.ZEROall_ok
-
-  notes:
-    loop duplicated in qh_detjoggle()
-
-  design:
-    initialize global precision variables
-    checks definition of REAL...
-    for each dimension
-      for each point
-        collect maximum and minimum point
-      collect maximum of maximums and minimum of minimums
-      determine qh.NEARzero for Gaussian Elimination
-*/
-setT *qh_maxmin(pointT *points, int numpoints, int dimension) {
-  int k;
-  realT maxcoord, temp;
-  pointT *minimum, *maximum, *point, *pointtemp;
-  setT *set;
-
-  qh max_outside= 0.0;
-  qh MAXabs_coord= 0.0;
-  qh MAXwidth= -REALmax;
-  qh MAXsumcoord= 0.0;
-  qh min_vertex= 0.0;
-  qh WAScoplanar= False;
-  if (qh ZEROcentrum)
-    qh ZEROall_ok= True;
-  if (REALmin < REALepsilon && REALmin < REALmax && REALmin > -REALmax
-  && REALmax > 0.0 && -REALmax < 0.0)
-    ; /* all ok */
-  else {
-    fprintf (qh ferr, "qhull error: floating point constants in user.h are wrong\n\
-REALepsilon %g REALmin %g REALmax %g -REALmax %g\n",
-	     REALepsilon, REALmin, REALmax, -REALmax);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  set= qh_settemp(2*dimension);
-  for(k= 0; k < dimension; k++) {
-    if (points == qh GOODpointp)
-      minimum= maximum= points + dimension;
-    else
-      minimum= maximum= points;
-    FORALLpoint_(points, numpoints) {
-      if (point == qh GOODpointp)
-	continue;
-      if (maximum[k] < point[k])
-	maximum= point;
-      else if (minimum[k] > point[k])
-	minimum= point;
-    }
-    if (k == dimension-1) {
-      qh MINlastcoord= minimum[k];
-      qh MAXlastcoord= maximum[k];
-    }
-    if (qh SCALElast && k == dimension-1)
-      maxcoord= qh MAXwidth;
-    else {
-      maxcoord= fmax_(maximum[k], -minimum[k]);
-      if (qh GOODpointp) {
-        temp= fmax_(qh GOODpointp[k], -qh GOODpointp[k]);
-        maximize_(maxcoord, temp);
-      }
-      temp= maximum[k] - minimum[k];
-      maximize_(qh MAXwidth, temp);
-    }
-    maximize_(qh MAXabs_coord, maxcoord);
-    qh MAXsumcoord += maxcoord;
-    qh_setappend (&set, maximum);
-    qh_setappend (&set, minimum);
-    /* calculation of qh NEARzero is based on error formula 4.4-13 of
-       Golub & van Loan, authors say n^3 can be ignored and 10 be used in
-       place of rho */
-    qh NEARzero[k]= 80 * qh MAXsumcoord * REALepsilon;
-  }
-  if (qh IStracing >=1)
-    qh_printpoints (qh ferr, "qh_maxmin: found the max and min points (by dim):", set);
-  return(set);
-} /* maxmin */
-
-/*---------------------------------
-
-  qh_maxouter()
-    return maximum distance from facet to outer plane
-    normally this is qh.max_outside+qh.DISTround
-    does not include qh.JOGGLEmax
-
-  see:
-    qh_outerinner()
-    
-  notes:
-    need to add another qh.DISTround if testing actual point with computation
-
-  for joggle:
-    qh_setfacetplane() updated qh.max_outer for Wnewvertexmax (max distance to vertex)
-    need to use Wnewvertexmax since could have a coplanar point for a high 
-      facet that is replaced by a low facet
-    need to add qh.JOGGLEmax if testing input points
-*/
-realT qh_maxouter (void) {
-  realT dist;
-
-  dist= fmax_(qh max_outside, qh DISTround);
-  dist += qh DISTround;
-  trace4((qh ferr, "qh_maxouter: max distance from facet to outer plane is %2.2g max_outside is %2.2g\n", dist, qh max_outside));
-  return dist;
-} /* maxouter */
-
-/*---------------------------------
-  
-  qh_maxsimplex( dim, maxpoints, points, numpoints, simplex )
-    determines maximum simplex for a set of points 
-    starts from points already in simplex
-    skips qh.GOODpointp (assumes that it isn't in maxpoints)
-  
-  returns:
-    simplex with dim+1 points
-
-  notes:
-    assumes at least pointsneeded points in points
-    maximizes determinate for x,y,z,w, etc.
-    uses maxpoints as long as determinate is clearly non-zero
-
-  design:
-    initialize simplex with at least two points
-      (find points with max or min x coordinate)
-    for each remaining dimension
-      add point that maximizes the determinate
-        (use points from maxpoints first)    
-*/
-void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex) {
-  pointT *point, **pointp, *pointtemp, *maxpoint, *minx=NULL, *maxx=NULL;
-  boolT nearzero, maxnearzero= False;
-  int k, sizinit;
-  realT maxdet= -REALmax, det, mincoord= REALmax, maxcoord= -REALmax;
-
-  sizinit= qh_setsize (*simplex);
-  if (sizinit < 2) {
-    if (qh_setsize (maxpoints) >= 2) {
-      FOREACHpoint_(maxpoints) {
-        if (maxcoord < point[0]) {
-          maxcoord= point[0];
-          maxx= point;
-        }
-	if (mincoord > point[0]) {
-          mincoord= point[0];
-          minx= point;
-        }
-      }
-    }else {
-      FORALLpoint_(points, numpoints) {
-	if (point == qh GOODpointp)
-	  continue;
-        if (maxcoord < point[0]) {
-	  maxcoord= point[0];
-          maxx= point;
-        }
-	if (mincoord > point[0]) {
-          mincoord= point[0];
-          minx= point;
-	}
-      }
-    }
-    qh_setunique (simplex, minx);
-    if (qh_setsize (*simplex) < 2)
-      qh_setunique (simplex, maxx);
-    sizinit= qh_setsize (*simplex);
-    if (sizinit < 2) {
-      qh_precision ("input has same x coordinate");
-      if (zzval_(Zsetplane) > qh hull_dim+1) {
-	fprintf (qh ferr, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n",
-		 qh_setsize(maxpoints)+numpoints);
-	qh_errexit (qh_ERRprec, NULL, NULL);
-      }else {
-	fprintf (qh ferr, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh hull_dim);
-	qh_errexit (qh_ERRinput, NULL, NULL);
-      }
-    }
-  }
-  for(k= sizinit; k < dim+1; k++) {
-    maxpoint= NULL;
-    maxdet= -REALmax;
-    FOREACHpoint_(maxpoints) {
-      if (!qh_setin (*simplex, point)) {
-        det= qh_detsimplex(point, *simplex, k, &nearzero);
-        if ((det= fabs_(det)) > maxdet) {
-	  maxdet= det;
-          maxpoint= point;
-	  maxnearzero= nearzero;
-        }
-      }
-    }
-    if (!maxpoint || maxnearzero) {
-      zinc_(Zsearchpoints);
-      if (!maxpoint) {
-        trace0((qh ferr, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1));
-      }else {
-        trace0((qh ferr, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n",
-		k+1, qh_pointid(maxpoint), maxdet));
-      }
-      FORALLpoint_(points, numpoints) {
-	if (point == qh GOODpointp)
-	  continue;
-        if (!qh_setin (*simplex, point)) {
-          det= qh_detsimplex(point, *simplex, k, &nearzero);
-          if ((det= fabs_(det)) > maxdet) {
-	    maxdet= det;
-            maxpoint= point;
-	    maxnearzero= nearzero;
-	  }
-        }
-      }
-    } /* !maxpoint */
-    if (!maxpoint) {
-      fprintf (qh ferr, "qhull internal error (qh_maxsimplex): not enough points available\n");
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-    qh_setappend(simplex, maxpoint);
-    trace1((qh ferr, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n",
-	    qh_pointid(maxpoint), k+1, maxdet));
-  } /* k */ 
-} /* maxsimplex */
-
-/*---------------------------------
-  
-  qh_minabsval( normal, dim )
-    return minimum absolute value of a dim vector
-*/
-realT qh_minabsval (realT *normal, int dim) {
-  realT minval= 0;
-  realT maxval= 0;
-  realT *colp;
-  int k;
-
-  for (k= dim, colp= normal; k--; colp++) {
-    maximize_(maxval, *colp);
-    minimize_(minval, *colp);
-  }
-  return fmax_(maxval, -minval);
-} /* minabsval */
-
-
-/*---------------------------------
-  
-  qh_mindif( vecA, vecB, dim )
-    return index of min abs. difference of two vectors
-*/
-int qh_mindiff (realT *vecA, realT *vecB, int dim) {
-  realT mindiff= REALmax, diff;
-  realT *vecAp= vecA, *vecBp= vecB;
-  int k, mink= 0;
-
-  for (k= 0; k < dim; k++) {
-    diff= *vecAp++ - *vecBp++;
-    diff= fabs_(diff);
-    if (diff < mindiff) {
-      mindiff= diff;
-      mink= k;
-    }
-  }
-  return mink;
-} /* mindiff */
-
-
-
-/*---------------------------------
-  
-  qh_orientoutside( facet  )
-    make facet outside oriented via qh.interior_point
-
-  returns:
-    True if facet reversed orientation.
-*/
-boolT qh_orientoutside (facetT *facet) {
-  int k;
-  realT dist;
-
-  qh_distplane (qh interior_point, facet, &dist);
-  if (dist > 0) {
-    for (k= qh hull_dim; k--; )
-      facet->normal[k]= -facet->normal[k];
-    facet->offset= -facet->offset;
-    return True;
-  }
-  return False;
-} /* orientoutside */
-
-/*---------------------------------
-  
-  qh_outerinner( facet, outerplane, innerplane  )
-    if facet and qh.maxoutdone (i.e., qh_check_maxout)
-      returns outer and inner plane for facet
-    else
-      returns maximum outer and inner plane
-    accounts for qh.JOGGLEmax
-
-  see:
-    qh_maxouter(), qh_check_bestdist(), qh_check_points()
-
-  notes:
-    outerplaner or innerplane may be NULL
-    
-    includes qh.DISTround for actual points
-    adds another qh.DISTround if testing with floating point arithmetic
-*/
-void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane) {
-  realT dist, mindist;
-  vertexT *vertex, **vertexp;
-
-  if (outerplane) {
-    if (!qh_MAXoutside || !facet || !qh maxoutdone) {
-      *outerplane= qh_maxouter();       /* includes qh.DISTround */
-    }else { /* qh_MAXoutside ... */
-#if qh_MAXoutside 
-      *outerplane= facet->maxoutside + qh DISTround;
-#endif
-      
-    }
-    if (qh JOGGLEmax < REALmax/2)
-      *outerplane += qh JOGGLEmax * sqrt (qh hull_dim);
-  }
-  if (innerplane) {
-    if (facet) {
-      mindist= REALmax;
-      FOREACHvertex_(facet->vertices) {
-        zinc_(Zdistio);
-        qh_distplane (vertex->point, facet, &dist);
-        minimize_(mindist, dist);
-      }
-      *innerplane= mindist - qh DISTround;
-    }else 
-      *innerplane= qh min_vertex - qh DISTround;
-    if (qh JOGGLEmax < REALmax/2)
-      *innerplane -= qh JOGGLEmax * sqrt (qh hull_dim);
-  }
-} /* outerinner */
-
-/*---------------------------------
-  
-  qh_pointdist( point1, point2, dim )
-    return distance between two points
-
-  notes:
-    returns distance squared if 'dim' is negative
-*/
-coordT qh_pointdist(pointT *point1, pointT *point2, int dim) {
-  coordT dist, diff;
-  int k;
-  
-  dist= 0.0;
-  for (k= (dim > 0 ? dim : -dim); k--; ) {
-    diff= *point1++ - *point2++;
-    dist += diff * diff;
-  }
-  if (dim > 0)
-    return(sqrt(dist));
-  return dist;
-} /* pointdist */
-
-
-/*---------------------------------
-  
-  qh_printmatrix( fp, string, rows, numrow, numcol )
-    print matrix to fp given by row vectors
-    print string as header
-
-  notes:
-    print a vector by qh_printmatrix(fp, "", &vect, 1, len)
-*/
-void qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol) {
-  realT *rowp;
-  realT r; /*bug fix*/
-  int i,k;
-
-  fprintf (fp, "%s\n", string);
-  for (i= 0; i < numrow; i++) {
-    rowp= rows[i];
-    for (k= 0; k < numcol; k++) {
-      r= *rowp++;
-      fprintf (fp, "%6.3g ", r);
-    }
-    fprintf (fp, "\n");
-  }
-} /* printmatrix */
-
-  
-/*---------------------------------
-  
-  qh_printpoints( fp, string, points )
-    print pointids to fp for a set of points
-    if string, prints string and 'p' point ids
-*/
-void qh_printpoints (FILE *fp, char *string, setT *points) {
-  pointT *point, **pointp;
-
-  if (string) {
-    fprintf (fp, "%s", string);
-    FOREACHpoint_(points) 
-      fprintf (fp, " p%d", qh_pointid(point));
-    fprintf (fp, "\n");
-  }else {
-    FOREACHpoint_(points) 
-      fprintf (fp, " %d", qh_pointid(point));
-    fprintf (fp, "\n");
-  }
-} /* printpoints */
-
-  
-/*---------------------------------
-  
-  qh_projectinput()
-    project input points using qh.lower_bound/upper_bound and qh DELAUNAY
-    if qh.lower_bound[k]=qh.upper_bound[k]= 0, 
-      removes dimension k 
-    if halfspace intersection
-      removes dimension k from qh.feasible_point
-    input points in qh first_point, num_points, input_dim
-
-  returns:
-    new point array in qh first_point of qh hull_dim coordinates
-    sets qh POINTSmalloc
-    if qh DELAUNAY 
-      projects points to paraboloid
-      lowbound/highbound is also projected
-    if qh ATinfinity
-      adds point "at-infinity"
-    if qh POINTSmalloc 
-      frees old point array
-
-  notes:
-    checks that qh.hull_dim agrees with qh.input_dim, PROJECTinput, and DELAUNAY
-
-
-  design:
-    sets project[k] to -1 (delete), 0 (keep), 1 (add for Delaunay)
-    determines newdim and newnum for qh hull_dim and qh num_points
-    projects points to newpoints
-    projects qh.lower_bound to itself
-    projects qh.upper_bound to itself
-    if qh DELAUNAY
-      if qh ATINFINITY
-        projects points to paraboloid
-        computes "infinity" point as vertex average and 10% above all points 
-      else
-        uses qh_setdelaunay to project points to paraboloid
-*/
-void qh_projectinput (void) {
-  int k,i;
-  int newdim= qh input_dim, newnum= qh num_points;
-  signed char *project;
-  int size= (qh input_dim+1)*sizeof(*project);
-  pointT *newpoints, *coord, *infinity;
-  realT paraboloid, maxboloid= 0;
-  
-  project= (signed char*)qh_memalloc (size);
-  memset ((char*)project, 0, size);
-  for (k= 0; k < qh input_dim; k++) {   /* skip Delaunay bound */
-    if (qh lower_bound[k] == 0 && qh upper_bound[k] == 0) {
-      project[k]= -1;
-      newdim--;
-    }
-  }
-  if (qh DELAUNAY) {
-    project[k]= 1;
-    newdim++;
-    if (qh ATinfinity)
-      newnum++;
-  }
-  if (newdim != qh hull_dim) {
-    fprintf(qh ferr, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh hull_dim);
-    qh_errexit(qh_ERRqhull, NULL, NULL);
-  }
-  if (!(newpoints=(coordT*)malloc(newnum*newdim*sizeof(coordT)))){
-    fprintf(qh ferr, "qhull error: insufficient memory to project %d points\n",
-           qh num_points);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  qh_projectpoints (project, qh input_dim+1, qh first_point,
-                    qh num_points, qh input_dim, newpoints, newdim);
-  trace1((qh ferr, "qh_projectinput: updating lower and upper_bound\n"));
-  qh_projectpoints (project, qh input_dim+1, qh lower_bound,
-                    1, qh input_dim+1, qh lower_bound, newdim+1);
-  qh_projectpoints (project, qh input_dim+1, qh upper_bound,
-                    1, qh input_dim+1, qh upper_bound, newdim+1);
-  if (qh HALFspace) {
-    if (!qh feasible_point) {
-      fprintf(qh ferr, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n");
-      qh_errexit(qh_ERRqhull, NULL, NULL);
-    }
-    qh_projectpoints (project, qh input_dim, qh feasible_point,
-		      1, qh input_dim, qh feasible_point, newdim);
-  }
-  qh_memfree(project, ((qh input_dim+1)*sizeof(*project)));
-  if (qh POINTSmalloc)
-    free (qh first_point);
-  qh first_point= newpoints;
-  qh POINTSmalloc= True;
-  if (qh DELAUNAY && qh ATinfinity) {
-    coord= qh first_point;
-    infinity= qh first_point + qh hull_dim * qh num_points;
-    for (k=qh hull_dim-1; k--; )
-      infinity[k]= 0.0;
-    for (i=qh num_points; i--; ) {
-      paraboloid= 0.0;
-      for (k=qh hull_dim-1; k--; ) {
-        paraboloid += *coord * *coord;
-	infinity[k] += *coord;
-        coord++;
-      }
-      *(coord++)= paraboloid;
-      maximize_(maxboloid, paraboloid);
-    }
-    /* coord == infinity */
-    for (k=qh hull_dim-1; k--; )
-      *(coord++) /= qh num_points;
-    *(coord++)= maxboloid * 1.1;
-    qh num_points++;
-    trace0((qh ferr, "qh_projectinput: projected points to paraboloid for Delaunay\n"));
-  }else if (qh DELAUNAY)  /* !qh ATinfinity */
-    qh_setdelaunay( qh hull_dim, qh num_points, qh first_point);
-} /* projectinput */
-
-  
-/*---------------------------------
-  
-  qh_projectpoints( project, n, points, numpoints, dim, newpoints, newdim )
-    project points/numpoints/dim to newpoints/newdim
-    if project[k] == -1
-      delete dimension k 
-    if project[k] == 1 
-      add dimension k by duplicating previous column
-    n is size of project
-
-  notes:
-    newpoints may be points if only adding dimension at end
-
-  design:
-    check that 'project' and 'newdim' agree
-    for each dimension
-      if project == -1
-        skip dimension
-      else
-        determine start of column in newpoints
-        determine start of column in points 
-          if project == +1, duplicate previous column
-        copy dimension (column) from points to newpoints
-*/
-void qh_projectpoints (signed char *project, int n, realT *points, 
-        int numpoints, int dim, realT *newpoints, int newdim) {
-  int testdim= dim, oldk=0, newk=0, i,j=0,k;
-  realT *newp, *oldp;
-  
-  for (k= 0; k < n; k++)
-    testdim += project[k];
-  if (testdim != newdim) {
-    fprintf (qh ferr, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n",
-      newdim, testdim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  for (j= 0; j= dim)
-	  continue;
-	oldp= points+oldk;
-      }else 
-	oldp= points+oldk++;
-      for (i=numpoints; i--; ) {
-        *newp= *oldp;
-        newp += newdim;
-        oldp += dim;
-      }
-    }
-    if (oldk >= dim)
-      break;
-  }
-  trace1((qh ferr, "qh_projectpoints: projected %d points from dim %d to dim %d\n", 
-    numpoints, dim, newdim));
-} /* projectpoints */
-        
-
-/*---------------------------------
-  
-  qh_rand() 
-  qh_srand( seed )
-    generate pseudo-random number between 1 and 2^31 -2
-
-  notes:
-    from Park & Miller's minimimal standard random number generator
-       Communications of the ACM, 31:1192-1201, 1988.
-    does not use 0 or 2^31 -1
-       this is silently enforced by qh_srand()
-    can make 'Rn' much faster by moving qh_rand to qh_distplane
-*/
-int qh_rand_seed= 1;  /* define as global variable instead of using qh */
-
-int qh_rand( void) {
-#define qh_rand_a 16807
-#define qh_rand_m 2147483647
-#define qh_rand_q 127773  /* m div a */
-#define qh_rand_r 2836    /* m mod a */
-  int lo, hi, test;
-  int seed = qh_rand_seed;
-
-  hi = seed / qh_rand_q;  /* seed div q */
-  lo = seed % qh_rand_q;  /* seed mod q */
-  test = qh_rand_a * lo - qh_rand_r * hi;
-  if (test > 0)
-    seed= test;
-  else
-    seed= test + qh_rand_m;
-  qh_rand_seed= seed;
-  /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax;  for testing */
-  /* seed = qh_RANDOMmax;  for testing */
-  return seed;
-} /* rand */
-
-void qh_srand( int seed) {
-  if (seed < 1)
-    qh_rand_seed= 1;
-  else if (seed >= qh_rand_m)
-    qh_rand_seed= qh_rand_m - 1;
-  else
-    qh_rand_seed= seed;
-} /* qh_srand */
-
-/*---------------------------------
-  
-  qh_randomfactor()
-    return a random factor within qh.RANDOMmax of 1.0
-
-  notes:
-    qh.RANDOMa/b are defined in global.c
-*/
-realT qh_randomfactor (void) {
-  realT randr;
-
-  randr= qh_RANDOMint;
-  return randr * qh RANDOMa + qh RANDOMb;
-} /* randomfactor */
-
-/*---------------------------------
-  
-  qh_randommatrix( buffer, dim, rows )
-    generate a random dim X dim matrix in range [-1,1]
-    assumes buffer is [dim+1, dim]
-
-  returns:
-    sets buffer to random numbers
-    sets rows to rows of buffer
-      sets row[dim] as scratch row
-*/
-void qh_randommatrix (realT *buffer, int dim, realT **rows) {
-  int i, k;
-  realT **rowi, *coord, realr;
-
-  coord= buffer;
-  rowi= rows;
-  for (i=0; i < dim; i++) {
-    *(rowi++)= coord;
-    for (k=0; k < dim; k++) {
-      realr= qh_RANDOMint;
-      *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
-    }
-  }
-  *rowi= coord;
-} /* randommatrix */
-
-        
-/*---------------------------------
-  
-  qh_rotateinput( rows )
-    rotate input using row matrix
-    input points given by qh first_point, num_points, hull_dim
-    assumes rows[dim] is a scratch buffer
-    if qh POINTSmalloc, overwrites input points, else mallocs a new array
-
-  returns:
-    rotated input
-    sets qh POINTSmalloc
-
-  design:
-    see qh_rotatepoints
-*/
-void qh_rotateinput (realT **rows) {
-
-  if (!qh POINTSmalloc) {
-    qh first_point= qh_copypoints (qh first_point, qh num_points, qh hull_dim);
-    qh POINTSmalloc= True;
-  }
-  qh_rotatepoints (qh first_point, qh num_points, qh hull_dim, rows);
-}  /* rotateinput */
-
-/*---------------------------------
-  
-  qh_rotatepoints( points, numpoints, dim, row )
-    rotate numpoints points by a d-dim row matrix
-    assumes rows[dim] is a scratch buffer
-
-  returns:
-    rotated points in place
-
-  design:
-    for each point
-      for each coordinate
-        use row[dim] to compute partial inner product
-      for each coordinate
-        rotate by partial inner product
-*/
-void qh_rotatepoints (realT *points, int numpoints, int dim, realT **row) {
-  realT *point, *rowi, *coord= NULL, sum, *newval;
-  int i,j,k;
-
-  if (qh IStracing >= 1)
-    qh_printmatrix (qh ferr, "qh_rotatepoints: rotate points by", row, dim, dim);
-  for (point= points, j= numpoints; j--; point += dim) {
-    newval= row[dim];
-    for (i= 0; i < dim; i++) {
-      rowi= row[i];
-      coord= point;
-      for (sum= 0.0, k= dim; k--; )
-        sum += *rowi++ * *coord++;
-      *(newval++)= sum;
-    }
-    for (k= dim; k--; )
-      *(--coord)= *(--newval);
-  }
-} /* rotatepoints */  
-  
-
-/*---------------------------------
-  
-  qh_scaleinput()
-    scale input points using qh low_bound/high_bound
-    input points given by qh first_point, num_points, hull_dim
-    if qh POINTSmalloc, overwrites input points, else mallocs a new array
-
-  returns:
-    scales coordinates of points to low_bound[k], high_bound[k]
-    sets qh POINTSmalloc
-
-  design:
-    see qh_scalepoints
-*/
-void qh_scaleinput (void) {
-
-  if (!qh POINTSmalloc) {
-    qh first_point= qh_copypoints (qh first_point, qh num_points, qh hull_dim);
-    qh POINTSmalloc= True;
-  }
-  qh_scalepoints (qh first_point, qh num_points, qh hull_dim,
-       qh lower_bound, qh upper_bound);
-}  /* scaleinput */
-  
-/*---------------------------------
-  
-  qh_scalelast( points, numpoints, dim, low, high, newhigh )
-    scale last coordinate to [0,m] for Delaunay triangulations
-    input points given by points, numpoints, dim
-
-  returns:
-    changes scale of last coordinate from [low, high] to [0, newhigh]
-    overwrites last coordinate of each point
-    saves low/high/newhigh in qh.last_low, etc. for qh_setdelaunay()
-
-  notes:
-    when called by qh_setdelaunay, low/high may not match actual data
-    
-  design:
-    compute scale and shift factors
-    apply to last coordinate of each point
-*/
-void qh_scalelast (coordT *points, int numpoints, int dim, coordT low,
-		   coordT high, coordT newhigh) {
-  realT scale, shift;
-  coordT *coord;
-  int i;
-  boolT nearzero= False;
-
-  trace4((qh ferr, "qh_scalelast: scale last coordinate from [%2.2g, %2.2g] to [0,%2.2g]\n",
-    low, high, newhigh));
-  qh last_low= low;
-  qh last_high= high;
-  qh last_newhigh= newhigh;
-  scale= qh_divzero (newhigh, high - low,
-                  qh MINdenom_1, &nearzero);
-  if (nearzero) {
-    if (qh DELAUNAY)
-      fprintf (qh ferr, "qhull input error: can not scale last coordinate.  Input is cocircular\n   or cospherical.   Use option 'Qz' to add a point at infinity.\n");
-    else
-      fprintf (qh ferr, "qhull input error: can not scale last coordinate.  New bounds [0, %2.2g] are too wide for\nexisting bounds [%2.2g, %2.2g] (width %2.2g)\n",
-		newhigh, low, high, high-low);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  shift= - low * newhigh / (high-low);
-  coord= points + dim - 1;
-  for (i= numpoints; i--; coord += dim)
-    *coord= *coord * scale + shift;
-} /* scalelast */
-
-/*---------------------------------
-  
-  qh_scalepoints( points, numpoints, dim, newlows, newhighs )
-    scale points to new lowbound and highbound
-    retains old bound when newlow= -REALmax or newhigh= +REALmax
-
-  returns:
-    scaled points
-    overwrites old points
-
-  design:
-    for each coordinate
-      compute current low and high bound
-      compute scale and shift factors
-      scale all points
-      enforce new low and high bound for all points
-*/
-void qh_scalepoints (pointT *points, int numpoints, int dim,
-	realT *newlows, realT *newhighs) {
-  int i,k;
-  realT shift, scale, *coord, low, high, newlow, newhigh, mincoord, maxcoord;
-  boolT nearzero= False;
-     
-  for (k= 0; k < dim; k++) {
-    newhigh= newhighs[k];
-    newlow= newlows[k];
-    if (newhigh > REALmax/2 && newlow < -REALmax/2)
-      continue;
-    low= REALmax;
-    high= -REALmax;
-    for (i= numpoints, coord= points+k; i--; coord += dim) {
-      minimize_(low, *coord);
-      maximize_(high, *coord);
-    }
-    if (newhigh > REALmax/2)
-      newhigh= high;
-    if (newlow < -REALmax/2)
-      newlow= low;
-    if (qh DELAUNAY && k == dim-1 && newhigh < newlow) {
-      fprintf (qh ferr, "qhull input error: 'Qb%d' or 'QB%d' inverts paraboloid since high bound %.2g < low bound %.2g\n",
-	       k, k, newhigh, newlow);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    scale= qh_divzero (newhigh - newlow, high - low,
-                  qh MINdenom_1, &nearzero);
-    if (nearzero) {
-      fprintf (qh ferr, "qhull input error: %d'th dimension's new bounds [%2.2g, %2.2g] too wide for\nexisting bounds [%2.2g, %2.2g]\n",
-              k, newlow, newhigh, low, high);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    shift= (newlow * high - low * newhigh)/(high-low);
-    coord= points+k;
-    for (i= numpoints; i--; coord += dim)
-      *coord= *coord * scale + shift;
-    coord= points+k;
-    if (newlow < newhigh) {
-      mincoord= newlow;
-      maxcoord= newhigh;
-    }else {
-      mincoord= newhigh;
-      maxcoord= newlow;
-    }
-    for (i= numpoints; i--; coord += dim) {
-      minimize_(*coord, maxcoord);  /* because of roundoff error */
-      maximize_(*coord, mincoord);
-    }
-    trace0((qh ferr, "qh_scalepoints: scaled %d'th coordinate [%2.2g, %2.2g] to [%.2g, %.2g] for %d points by %2.2g and shifted %2.2g\n",
-      k, low, high, newlow, newhigh, numpoints, scale, shift));
-  }
-} /* scalepoints */    
-
-       
-/*---------------------------------
-  
-  qh_setdelaunay( dim, count, points )
-    project count points to dim-d paraboloid for Delaunay triangulation
-    
-    dim is one more than the dimension of the input set
-    assumes dim is at least 3 (i.e., at least a 2-d Delaunay triangulation)
-
-    points is a dim*count realT array.  The first dim-1 coordinates
-    are the coordinates of the first input point.  array[dim] is
-    the first coordinate of the second input point.  array[2*dim] is
-    the first coordinate of the third input point.
-
-    if qh.last_low defined (i.e., 'Qbb' called qh_scalelast)
-      calls qh_scalelast to scale the last coordinate the same as the other points
-
-  returns:
-    for each point
-      sets point[dim-1] to sum of squares of coordinates
-    scale points to 'Qbb' if needed
-      
-  notes:
-    to project one point, use
-      qh_setdelaunay (qh hull_dim, 1, point)
-      
-    Do not use options 'Qbk', 'QBk', or 'QbB' since they scale 
-    the coordinates after the original projection.
-
-*/
-void qh_setdelaunay (int dim, int count, pointT *points) {
-  int i, k;
-  coordT *coordp, coord;
-  realT paraboloid;
-
-  trace0((qh ferr, "qh_setdelaunay: project %d points to paraboloid for Delaunay triangulation\n", count));
-  coordp= points;
-  for (i= 0; i < count; i++) {
-    coord= *coordp++;
-    paraboloid= coord*coord;
-    for (k= dim-2; k--; ) {
-      coord= *coordp++;
-      paraboloid += coord*coord;
-    }
-    *coordp++ = paraboloid;
-  }
-  if (qh last_low < REALmax/2) 
-    qh_scalelast (points, count, dim, qh last_low, qh last_high, qh last_newhigh);
-} /* setdelaunay */
-
-  
-/*---------------------------------
-  
-  qh_sethalfspace( dim, coords, nextp, normal, offset, feasible )
-    set point to dual of halfspace relative to feasible point
-    halfspace is normal coefficients and offset.
-
-  returns:
-    false if feasible point is outside of hull (error message already reported)
-    overwrites coordinates for point at dim coords
-    nextp= next point (coords)
-
-  design:
-    compute distance from feasible point to halfspace
-    divide each normal coefficient by -dist
-*/
-boolT qh_sethalfspace (int dim, coordT *coords, coordT **nextp, 
-         coordT *normal, coordT *offset, coordT *feasible) {
-  coordT *normp= normal, *feasiblep= feasible, *coordp= coords;
-  realT dist;
-  realT r; /*bug fix*/
-  int k;
-  boolT zerodiv;
-
-  dist= *offset;
-  for (k= dim; k--; )
-    dist += *(normp++) * *(feasiblep++);
-  if (dist > 0)
-    goto LABELerroroutside;
-  normp= normal;
-  if (dist < -qh MINdenom) {
-    for (k= dim; k--; )
-      *(coordp++)= *(normp++) / -dist;
-  }else {
-    for (k= dim; k--; ) {
-      *(coordp++)= qh_divzero (*(normp++), -dist, qh MINdenom_1, &zerodiv);
-      if (zerodiv) 
-        goto LABELerroroutside;
-    }
-  }
-  *nextp= coordp;
-  if (qh IStracing >= 4) {
-    fprintf (qh ferr, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset);
-    for (k= dim, coordp= coords; k--; ) {
-      r= *coordp++;
-      fprintf (qh ferr, " %6.2g", r);
-    }
-    fprintf (qh ferr, "\n");
-  }
-  return True;
-LABELerroroutside:
-  feasiblep= feasible;
-  normp= normal;
-  fprintf(qh ferr, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: ");
-  for (k= dim; k--; )
-    fprintf (qh ferr, qh_REAL_1, r=*(feasiblep++));
-  fprintf (qh ferr, "\n     halfspace: "); 
-  for (k= dim; k--; )
-    fprintf (qh ferr, qh_REAL_1, r=*(normp++));
-  fprintf (qh ferr, "\n     at offset: ");
-  fprintf (qh ferr, qh_REAL_1, *offset);
-  fprintf (qh ferr, " and distance: ");
-  fprintf (qh ferr, qh_REAL_1, dist);
-  fprintf (qh ferr, "\n");
-  return False;
-} /* sethalfspace */
-
-/*---------------------------------
-  
-  qh_sethalfspace_all( dim, count, halfspaces, feasible )
-    generate dual for halfspace intersection with feasible point
-    array of count halfspaces
-      each halfspace is normal coefficients followed by offset 
-      the origin is inside the halfspace if the offset is negative
-
-  returns:
-    malloc'd array of count X dim-1 points
-
-  notes:
-    call before qh_init_B or qh_initqhull_globals 
-    unused/untested code: please email bradb@shore.net if this works ok for you
-    If using option 'Fp', also set qh feasible_point. It is a malloc'd array 
-      that is freed by qh_freebuffers.
-
-  design:
-    see qh_sethalfspace
-*/
-coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible) {
-  int i, newdim;
-  pointT *newpoints;
-  coordT *coordp, *normalp, *offsetp;
-
-  trace0((qh ferr, "qh_sethalfspace_all: compute dual for halfspace intersection\n"));
-  newdim= dim - 1;
-  if (!(newpoints=(coordT*)malloc(count*newdim*sizeof(coordT)))){
-    fprintf(qh ferr, "qhull error: insufficient memory to compute dual of %d halfspaces\n",
-          count);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  coordp= newpoints;
-  normalp= halfspaces;
-  for (i= 0; i < count; i++) {
-    offsetp= normalp + newdim;
-    if (!qh_sethalfspace (newdim, coordp, &coordp, normalp, offsetp, feasible)) {
-      fprintf (qh ferr, "The halfspace was at index %d\n", i);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    normalp= offsetp + 1;
-  }
-  return newpoints;
-} /* sethalfspace_all */
-
-  
-/*---------------------------------
-  
-  qh_sharpnewfacets()
-
-  returns:
-    true if could be an acute angle (facets in different quadrants)
- 
-  notes:
-    for qh_findbest
-
-  design:
-    for all facets on qh.newfacet_list
-      if two facets are in different quadrants
-        set issharp
-*/
-boolT qh_sharpnewfacets () {
-  facetT *facet;
-  boolT issharp = False;
-  int *quadrant, k;
-  
-  quadrant= (int*)qh_memalloc (qh hull_dim * sizeof(int));
-  FORALLfacet_(qh newfacet_list) {
-    if (facet == qh newfacet_list) {
-      for (k= qh hull_dim; k--; )
-      	quadrant[ k]= (facet->normal[ k] > 0);
-    }else {
-      for (k= qh hull_dim; k--; ) {
-        if (quadrant[ k] != (facet->normal[ k] > 0)) {
-          issharp= True;
-          break;
-        }
-      }
-    }
-    if (issharp)
-      break;
-  }
-  qh_memfree( quadrant, qh hull_dim * sizeof(int));
-  trace3((qh ferr, "qh_sharpnewfacets: %d\n", issharp));
-  return issharp;
-} /* sharpnewfacets */
-
-/*---------------------------------
-  
-  qh_voronoi_center( dim, points )
-    return Voronoi center for a set of points
-    dim is the orginal dimension of the points
-    gh.gm_matrix/qh.gm_row are scratch buffers
-
-  returns:
-    center as a temporary point
-    if non-simplicial, 
-      returns center for max simplex of points
-
-  notes:
-    from Bowyer & Woodwark, A Programmer's Geometry, 1983, p. 65
-
-  design:
-    if non-simplicial
-      determine max simplex for points
-    translate point0 of simplex to origin
-    compute sum of squares of diagonal
-    compute determinate
-    compute Voronoi center (see Bowyer & Woodwark)
-*/
-pointT *qh_voronoi_center (int dim, setT *points) {
-  pointT *point, **pointp, *point0;
-  pointT *center= (pointT*)qh_memalloc (qh center_size);
-  setT *simplex;
-  int i, j, k, size= qh_setsize(points);
-  coordT *gmcoord;
-  realT *diffp, sum2, *sum2row, *sum2p, det, factor;
-  boolT nearzero, infinite;
-
-  if (size == dim+1)
-    simplex= points;
-  else if (size < dim+1) {
-    fprintf (qh ferr, "qhull internal error (qh_voronoi_center):\n  need at least %d points to construct a Voronoi center\n",
-	     dim+1);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }else {
-    simplex= qh_settemp (dim+1);
-    qh_maxsimplex (dim, points, NULL, 0, &simplex);
-  }
-  point0= SETfirstt_(simplex, pointT);
-  gmcoord= qh gm_matrix;
-  for (k=0; k < dim; k++) {
-    qh gm_row[k]= gmcoord;
-    FOREACHpoint_(simplex) {
-      if (point != point0)
-        *(gmcoord++)= point[k] - point0[k];
-    }
-  }
-  sum2row= gmcoord;
-  for (i=0; i < dim; i++) {
-    sum2= 0.0;
-    for (k= 0; k < dim; k++) {
-      diffp= qh gm_row[k] + i;
-      sum2 += *diffp * *diffp;
-    }
-    *(gmcoord++)= sum2;
-  }
-  det= qh_determinant (qh gm_row, dim, &nearzero);
-  factor= qh_divzero (0.5, det, qh MINdenom, &infinite);
-  if (infinite) {
-    for (k=dim; k--; )
-      center[k]= qh_INFINITE;
-    if (qh IStracing)
-      qh_printpoints (qh ferr, "qh_voronoi_center: at infinity for ", simplex);
-  }else {
-    for (i=0; i < dim; i++) {
-      gmcoord= qh gm_matrix;
-      sum2p= sum2row;
-      for (k=0; k < dim; k++) {
-	qh gm_row[k]= gmcoord;
-	if (k == i) {
-	  for (j= dim; j--; )
-	    *(gmcoord++)= *sum2p++;
-	}else {
-	  FOREACHpoint_(simplex) {
-	    if (point != point0)
-	      *(gmcoord++)= point[k] - point0[k];
-	  }
-	}
-      }
-      center[i]= qh_determinant (qh gm_row, dim, &nearzero)*factor + point0[i];
-    }
-#ifndef qh_NOtrace
-    if (qh IStracing >= 3) {
-      fprintf (qh ferr, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor);
-      qh_printmatrix (qh ferr, "center:", ¢er, 1, dim);
-      if (qh IStracing >= 5) {
-	qh_printpoints (qh ferr, "points", simplex);
-	FOREACHpoint_(simplex)
-	  fprintf (qh ferr, "p%d dist %.2g, ", qh_pointid (point),
-		   qh_pointdist (point, center, dim));
-	fprintf (qh ferr, "\n");
-      }
-    }
-#endif
-  }
-  if (simplex != points)
-    qh_settempfree (&simplex);
-  return center;
-} /* voronoi_center */
-
diff --git a/extern/qhull/src/global.c b/extern/qhull/src/global.c
deleted file mode 100644
index d3e141aa985..00000000000
--- a/extern/qhull/src/global.c
+++ /dev/null
@@ -1,2018 +0,0 @@
-/*
  ---------------------------------
-
-   global.c
-   initializes all the globals of the qhull application
-
-   see README
-
-   see qhull.h for qh.globals and function prototypes
-
-   see qhull_a.h for internal functions
-
-   copyright (c) 1993-2002, The Geometry Center
- */
-
-#include "qhull_a.h"
-
-/*========= qh definition =======================*/
-
-#if qh_QHpointer
-qhT *qh_qh= NULL;	/* pointer to all global variables */
-#else
-qhT qh_qh;     		/* all global variables.
-			   Add "= {0}" if this causes a compiler error.
-			   Also qh_qhstat in stat.c and qhmem in mem.c.  */
-#endif
-
-/*---------------------------------
-
-  qh_appendprint( printFormat )
-    append printFormat to qh.PRINTout unless already defined
-*/
-void qh_appendprint (qh_PRINT format) {
-  int i;
-
-  for (i=0; i < qh_PRINTEND; i++) {
-    if (qh PRINTout[i] == format && format != qh_PRINTqhull)
-      break;
-    if (!qh PRINTout[i]) {
-      qh PRINTout[i]= format;
-      break;
-    }
-  }
-} /* appendprint */
-     
-/*---------------------------------
-  
-  qh_checkflags( commandStr, hiddenFlags )
-    errors if commandStr contains hiddenFlags
-    hiddenFlags starts and ends with a space and is space deliminated (checked)
-
-  notes:
-    ignores first word (e.g., "qconvex i")
-    use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
-  
-  see:
-    qh_initflags() initializes Qhull according to commandStr
-*/
-void qh_checkflags(char *command, char *hiddenflags) {
-  char *s= command, *t, *chkerr, key, opt, prevopt;
-  char chkkey[]= "   ";
-  char chkopt[]=  "    ";
-  char chkopt2[]= "     ";
-
-  if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
-    fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (strpbrk(hiddenflags, ",\n\r\t")) { 
-    fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  while (*s && !isspace(*s))  /* skip program name */
-    s++;
-  while (*s) {
-    while (*s && isspace(*s))
-      s++;
-    if (*s == '-')
-      s++;
-    if (!*s)
-      break;
-    key = *s++;
-    chkerr = NULL;
-    if (key == '\'') {         /* TO 'file name' */
-      t= strchr(s, '\'');
-      if (!t) {
-	fprintf(qh ferr, "qhull error (qh_checkflags): missing the 2nd single-quote for:\n%s\n", s-1);
-	qh_errexit(qh_ERRinput, NULL, NULL);
-      }
-      s= t+1;
-      continue;
-    }
-    chkkey[1]= key;
-    if (strstr(hiddenflags, chkkey)) {
-      chkerr= chkkey;
-    }else if (isupper(key)) {
-      opt= ' ';
-      prevopt= ' ';
-      chkopt[1]= key;
-      chkopt2[1]= key;
-      while (!chkerr && *s && !isspace(*s)) {
-	opt= *s++;
-	if (isalpha(opt)) {
-	  chkopt[2]= opt;
-	  if (strstr(hiddenflags, chkopt))
-	    chkerr= chkopt;
-	  if (prevopt != ' ') {
- 	    chkopt2[2]= prevopt;
- 	    chkopt2[3]= opt;
-	    if (strstr(hiddenflags, chkopt2))
-	      chkerr= chkopt2;
-	  }
-	}else if (key == 'Q' && isdigit(opt) && prevopt != 'b' 
-	      && (prevopt == ' ' || islower(prevopt))) {
-  	    chkopt[2]= opt;
-	    if (strstr(hiddenflags, chkopt))
-	      chkerr= chkopt;
-	}else {
-	  qh_strtod (s-1, &t);
-	  if (s < t)
-	    s= t;
-	}
-        prevopt= opt;
-      }
-    }
-    if (chkerr) {
-      *chkerr= '\'';
-      chkerr[strlen(chkerr)-1]=  '\'';
-      fprintf(qh ferr, "qhull error: option %s is not used with this program.\n             It may be used with qhull.\n", chkerr);
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-  }
-} /* checkflags */
-    
-/*---------------------------------
-  
-  qh_clock()
-    return user CPU time in 100ths (qh_SECtick)
-    only defined for qh_CLOCKtype == 2
-
-  notes:
-    use first value to determine time 0
-    from Stevens '92 8.15
-*/
-unsigned long qh_clock (void) {
-
-#if (qh_CLOCKtype == 2)
-  struct tms time;
-  static long clktck;  /* initialized first call */
-  double ratio, cpu;
-  unsigned long ticks;
-
-  if (!clktck) {
-    if ((clktck= sysconf (_SC_CLK_TCK)) < 0) {
-      fprintf (qh ferr, "qhull internal error (qh_clock): sysconf() failed.  Use qh_CLOCKtype 1 in user.h\n");
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-  }
-  if (times (&time) == -1) {
-    fprintf (qh ferr, "qhull internal error (qh_clock): times() failed.  Use qh_CLOCKtype 1 in user.h\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  ratio= qh_SECticks / (double)clktck;
-  ticks= time.tms_utime * ratio;
-  return ticks;
-#else
-  fprintf (qh ferr, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
-  qh_errexit (qh_ERRqhull, NULL, NULL); /* never returns */
-  return 0;
-#endif
-} /* clock */
-
-/*---------------------------------
-
-  qh_freebuffers()
-    free up global memory buffers
-
-  notes:
-    must match qh_initbuffers()
-*/
-void qh_freebuffers (void) {
-
-  trace5((qh ferr, "qh_freebuffers: freeing up global memory buffers\n"));
-  /* allocated by qh_initqhull_buffers */
-  qh_memfree (qh NEARzero, qh hull_dim * sizeof(realT));
-  qh_memfree (qh lower_threshold, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh upper_threshold, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh lower_bound, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh upper_bound, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh gm_matrix, (qh hull_dim+1) * qh hull_dim * sizeof(coordT));
-  qh_memfree (qh gm_row, (qh hull_dim+1) * sizeof(coordT *));
-  qh NEARzero= qh lower_threshold= qh upper_threshold= NULL;
-  qh lower_bound= qh upper_bound= NULL;
-  qh gm_matrix= NULL;
-  qh gm_row= NULL;
-  qh_setfree (&qh other_points);
-  qh_setfree (&qh del_vertices);
-  qh_setfree (&qh coplanarset);
-  if (qh line)                /* allocated by qh_readinput, freed if no error */
-    free (qh line);
-  if (qh half_space)
-    free (qh half_space);
-  if (qh temp_malloc)
-    free (qh temp_malloc);
-  if (qh feasible_point)      /* allocated by qh_readfeasible */
-    free (qh feasible_point);
-  if (qh feasible_string)     /* allocated by qh_initflags */
-    free (qh feasible_string);
-  qh line= qh feasible_string= NULL;
-  qh half_space= qh feasible_point= qh temp_malloc= NULL;
-  /* usually allocated by qh_readinput */
-  if (qh first_point && qh POINTSmalloc) {
-    free(qh first_point);
-    qh first_point= NULL;
-  }
-  if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
-    free (qh input_points);
-    qh input_points= NULL;
-  }
-  trace5((qh ferr, "qh_freebuffers: finished\n"));
-} /* freebuffers */
-
-
-/*---------------------------------
-
-  qh_freebuild( allmem )
-    free global memory used by qh_initbuild and qh_buildhull
-    if !allmem,
-      does not free short memory (freed by qh_memfreeshort)
-
-  design:
-    free centrums
-    free each vertex
-    mark unattached ridges
-    for each facet
-      free ridges
-      free outside set, coplanar set, neighbor set, ridge set, vertex set
-      free facet
-    free hash table
-    free interior point
-    free merge set
-    free temporary sets
-*/
-void qh_freebuild (boolT allmem) {
-  facetT *facet;
-  vertexT *vertex;
-  ridgeT *ridge, **ridgep;
-  mergeT *merge, **mergep;
-
-  trace1((qh ferr, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
-  if (qh del_vertices)
-    qh_settruncate (qh del_vertices, 0);
-  if (allmem) {
-    qh_clearcenters (qh_ASnone);
-    while ((vertex= qh vertex_list)) {
-      if (vertex->next)
-        qh_delvertex (vertex);
-      else {
-        qh_memfree (vertex, sizeof(vertexT));
-        qh newvertex_list= qh vertex_list= NULL;
-      }
-    }
-  }else if (qh VERTEXneighbors) {
-    FORALLvertices
-      qh_setfreelong (&(vertex->neighbors));
-  }
-  qh VERTEXneighbors= False;
-  qh GOODclosest= NULL;
-  if (allmem) {
-    FORALLfacets {
-      FOREACHridge_(facet->ridges)
-        ridge->seen= False;
-    }
-    FORALLfacets {
-      if (facet->visible) {
-	FOREACHridge_(facet->ridges) {
-	  if (!otherfacet_(ridge, facet)->visible)
-	    ridge->seen= True;  /* an unattached ridge */
-	}
-      }
-    }
-    while ((facet= qh facet_list)) {
-      FOREACHridge_(facet->ridges) {
-        if (ridge->seen) {
-          qh_setfree(&(ridge->vertices));
-          qh_memfree(ridge, sizeof(ridgeT));
-        }else
-          ridge->seen= True;
-      }
-      qh_setfree (&(facet->outsideset));
-      qh_setfree (&(facet->coplanarset));
-      qh_setfree (&(facet->neighbors));
-      qh_setfree (&(facet->ridges));
-      qh_setfree (&(facet->vertices));
-      if (facet->next)
-        qh_delfacet (facet);
-      else {
-        qh_memfree (facet, sizeof(facetT));
-        qh visible_list= qh newfacet_list= qh facet_list= NULL;
-      }
-    }
-  }else {
-    FORALLfacets {
-      qh_setfreelong (&(facet->outsideset));
-      qh_setfreelong (&(facet->coplanarset));
-      if (!facet->simplicial) {
-        qh_setfreelong (&(facet->neighbors));
-        qh_setfreelong (&(facet->ridges));
-        qh_setfreelong (&(facet->vertices));
-      }
-    }
-  }
-  qh_setfree (&(qh hash_table));
-  qh_memfree (qh interior_point, qh normal_size);
-  qh interior_point= NULL;
-  FOREACHmerge_(qh facet_mergeset)  /* usually empty */
-    qh_memfree (merge, sizeof(mergeT));
-  qh facet_mergeset= NULL;  /* temp set */
-  qh degen_mergeset= NULL;  /* temp set */
-  qh_settempfree_all();
-} /* freebuild */
-
-/*---------------------------------
-
-  qh_freeqhull( allmem )
-    free global memory
-    if !allmem,
-      does not free short memory (freed by qh_memfreeshort)
-
-  notes:
-    sets qh.NOerrexit in case caller forgets to
-
-  design:
-    free global and temporary memory from qh_initbuild and qh_buildhull
-    free buffers
-    free statistics
-*/
-void qh_freeqhull (boolT allmem) {
-
-  trace1((qh ferr, "qh_freeqhull: free global memory\n"));
-  qh NOerrexit= True;  /* no more setjmp since called at exit */
-  qh_freebuild (allmem);
-  qh_freebuffers();
-  qh_freestatistics();
-#if qh_QHpointer
-  free (qh_qh);
-  qh_qh= NULL;
-#else
-  memset((char *)&qh_qh, 0, sizeof(qhT));
-  qh NOerrexit= True;
-#endif
-} /* freeqhull */
-
-/*---------------------------------
-
-  qh_init_A( infile, outfile, errfile, argc, argv )
-    initialize memory and stdio files
-    convert input options to option string (qh.qhull_command)
-
-  notes:
-    infile may be NULL if qh_readpoints() is not called
-
-    errfile should always be defined.  It is used for reporting
-    errors.  outfile is used for output and format options.
-
-    argc/argv may be 0/NULL
-
-    called before error handling initialized
-    qh_errexit() may not be used
-*/
-void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
-  qh_meminit (errfile);
-  qh_initqhull_start (infile, outfile, errfile);
-  qh_init_qhull_command (argc, argv);
-} /* init_A */
-
-/*---------------------------------
-
-  qh_init_B( points, numpoints, dim, ismalloc )
-    initialize globals for points array
-
-    points has numpoints dim-dimensional points
-      points[0] is the first coordinate of the first point
-      points[1] is the second coordinate of the first point
-      points[dim] is the first coordinate of the second point
-
-    ismalloc=True
-      Qhull will call free(points) on exit or input transformation
-    ismalloc=False
-      Qhull will allocate a new point array if needed for input transformation
-
-    qh.qhull_command
-      is the option string.
-      It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
-
-  returns:
-    if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
-      projects the input to a new point array
-
-        if qh.DELAUNAY,
-          qh.hull_dim is increased by one
-        if qh.ATinfinity,
-          qh_projectinput adds point-at-infinity for Delaunay tri.
-
-    if qh.SCALEinput
-      changes the upper and lower bounds of the input, see qh_scaleinput()
-
-    if qh.ROTATEinput
-      rotates the input by a random rotation, see qh_rotateinput()
-      if qh.DELAUNAY
-        rotates about the last coordinate
-
-  notes:
-    called after points are defined
-    qh_errexit() may be used
-*/
-void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc) {
-  qh_initqhull_globals (points, numpoints, dim, ismalloc);
-  if (qhmem.LASTsize == 0)
-    qh_initqhull_mem();
-  /* mem.c and qset.c are initialized */
-  qh_initqhull_buffers();
-  qh_initthresholds (qh qhull_command);
-  if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay))
-    qh_projectinput();
-  if (qh SCALEinput)
-    qh_scaleinput();
-  if (qh ROTATErandom >= 0) {
-    qh_randommatrix (qh gm_matrix, qh hull_dim, qh gm_row);
-    if (qh DELAUNAY) {
-      int k, lastk= qh hull_dim-1;
-      for (k= 0; k < lastk; k++) {
-        qh gm_row[k][lastk]= 0.0;
-        qh gm_row[lastk][k]= 0.0;
-      }
-      qh gm_row[lastk][lastk]= 1.0;
-    }
-    qh_gram_schmidt (qh hull_dim, qh gm_row);
-    qh_rotateinput (qh gm_row);
-  }
-} /* init_B */
-
-/*---------------------------------
-
-  qh_init_qhull_command( argc, argv )
-    build qh.qhull_command from argc/argv
-
-  returns:
-    a space-deliminated string of options (just as typed)
-
-  notes:
-    makes option string easy to input and output
-
-    argc/argv may be 0/NULL
-*/
-void qh_init_qhull_command(int argc, char *argv[]) {
-  int i;
-  char *s;
-
-  if (argc) {
-    if ((s= strrchr( argv[0], '\\'))) /* Borland gives full path */
-      strcpy (qh qhull_command, s+1);
-    else
-      strcpy (qh qhull_command, argv[0]);
-    if ((s= strstr (qh qhull_command, ".EXE"))
-    ||  (s= strstr (qh qhull_command, ".exe")))
-      *s= '\0';
-  }
-  for (i=1; i < argc; i++) {
-    if (strlen (qh qhull_command) + strlen(argv[i]) + 1 < sizeof(qh qhull_command)) {
-      strcat (qh qhull_command, " ");
-      strcat (qh qhull_command, argv[i]);
-    }else {
-      fprintf (qh ferr, "qhull input error: more than %d characters in command line\n",
-        (int)sizeof(qh qhull_command));
-      exit (1);  /* can not use qh_errexit */
-    }
-  }
-} /* init_qhull_command */
-
-/*---------------------------------
-
-  qh_initflags( commandStr )
-    set flags and initialized constants from commandStr
-
-  returns:
-    sets qh.qhull_command to command if needed
-
-  notes:
-    ignores first word (e.g., "qhull d")
-    use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
-
-  see:
-    qh_initthresholds() continues processing of 'Pdn' and 'PDn'
-    'prompt' in unix.c for documentation
-
-  design:
-    for each space-deliminated option group
-      if top-level option
-        check syntax
-        append approriate option to option string
-        set appropriate global variable or append printFormat to print options
-      else
-        for each sub-option
-          check syntax
-          append approriate option to option string
-          set appropriate global variable or append printFormat to print options
-
-
-*/
-void qh_initflags(char *command) {
-  int k, i, lastproject;
-  char *s= command, *t, *prev_s, *start, key;
-  boolT isgeom= False, wasproject;
-  realT r;
-
-  if (command != &qh qhull_command[0]) {
-    *qh qhull_command= '\0';
-    strncat( qh qhull_command, command, sizeof( qh qhull_command));
-  }
-  while (*s && !isspace(*s))  /* skip program name */
-    s++;
-  while (*s) {
-    while (*s && isspace(*s))
-      s++;
-    if (*s == '-')
-      s++;
-    if (!*s)
-      break;
-    prev_s= s;
-    switch (*s++) {
-    case 'd':
-      qh_option ("delaunay", NULL, NULL);
-      qh DELAUNAY= True;
-      break;
-    case 'f':
-      qh_option ("facets", NULL, NULL);
-      qh_appendprint (qh_PRINTfacets);
-      break;
-    case 'i':
-      qh_option ("incidence", NULL, NULL);
-      qh_appendprint (qh_PRINTincidences);
-      break;
-    case 'm':
-      qh_option ("mathematica", NULL, NULL);
-      qh_appendprint (qh_PRINTmathematica);
-      break;
-    case 'n':
-      qh_option ("normals", NULL, NULL);
-      qh_appendprint (qh_PRINTnormals);
-      break;
-    case 'o':
-      qh_option ("offFile", NULL, NULL);
-      qh_appendprint (qh_PRINToff);
-      break;
-    case 'p':
-      qh_option ("points", NULL, NULL);
-      qh_appendprint (qh_PRINTpoints);
-      break;
-    case 's':
-      qh_option ("summary", NULL, NULL);
-      qh PRINTsummary= True;
-      break;
-    case 'v':
-      qh_option ("voronoi", NULL, NULL);
-      qh VORONOI= True;
-      qh DELAUNAY= True;
-      break;
-    case 'A':
-      if (!isdigit(*s) && *s != '.' && *s != '-')
-	fprintf(qh ferr, "qhull warning: no maximum cosine angle given for option 'An'.  Ignored.\n");
-      else {
-	if (*s == '-') {
-	  qh premerge_cos= -qh_strtod (s, &s);
-          qh_option ("Angle-premerge-", NULL, &qh premerge_cos);
-	  qh PREmerge= True;
-	}else {
-	  qh postmerge_cos= qh_strtod (s, &s);
-          qh_option ("Angle-postmerge", NULL, &qh postmerge_cos);
-	  qh POSTmerge= True;
-	}
-	qh MERGING= True;
-      }
-      break;
-    case 'C':
-      if (!isdigit(*s) && *s != '.' && *s != '-')
-	fprintf(qh ferr, "qhull warning: no centrum radius given for option 'Cn'.  Ignored.\n");
-      else {
-	if (*s == '-') {
-	  qh premerge_centrum= -qh_strtod (s, &s);
-          qh_option ("Centrum-premerge-", NULL, &qh premerge_centrum);
-	  qh PREmerge= True;
-	}else {
-	  qh postmerge_centrum= qh_strtod (s, &s);
-          qh_option ("Centrum-postmerge", NULL, &qh postmerge_centrum);
-	  qh POSTmerge= True;
-	}
-	qh MERGING= True;
-      }
-      break;
-    case 'E':
-      if (*s == '-')
-	fprintf(qh ferr, "qhull warning: negative maximum roundoff given for option 'An'.  Ignored.\n");
-      else if (!isdigit(*s))
-	fprintf(qh ferr, "qhull warning: no maximum roundoff given for option 'En'.  Ignored.\n");
-      else {
-	qh DISTround= qh_strtod (s, &s);
-        qh_option ("Distance-roundoff", NULL, &qh DISTround);
-	qh SETroundoff= True;
-      }
-      break;
-    case 'H':
-      start= s;
-      qh HALFspace= True;
-      qh_strtod (s, &t);
-      while (t > s)  {
-        if (*t && !isspace (*t)) {
-	  if (*t == ',')
-	    t++;
-	  else
-	    fprintf (qh ferr, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n");
-	}
-        s= t;
-	qh_strtod (s, &t);
-      }
-      if (start < t) {
-        if (!(qh feasible_string= (char*)calloc (t-start+1, 1))) {
-          fprintf(qh ferr, "qhull error: insufficient memory for 'Hn,n,n'\n");
-          qh_errexit(qh_ERRmem, NULL, NULL);
-        }
-        strncpy (qh feasible_string, start, t-start);
-        qh_option ("Halfspace-about", NULL, NULL);
-        qh_option (qh feasible_string, NULL, NULL);
-      }else
-        qh_option ("Halfspace", NULL, NULL);
-      break;
-    case 'R':
-      if (!isdigit(*s))
-	fprintf(qh ferr, "qhull warning: missing random perturbation for option 'Rn'.  Ignored\n");
-      else {
-	qh RANDOMfactor= qh_strtod (s, &s);
-        qh_option ("Random_perturb", NULL, &qh RANDOMfactor);
-        qh RANDOMdist= True;
-      }
-      break;
-    case 'V':
-      if (!isdigit(*s) && *s != '-')
-	fprintf(qh ferr, "qhull warning: missing visible distance for option 'Vn'.  Ignored\n");
-      else {
-	qh MINvisible= qh_strtod (s, &s);
-        qh_option ("Visible", NULL, &qh MINvisible);
-      }
-      break;
-    case 'U':
-      if (!isdigit(*s) && *s != '-')
-	fprintf(qh ferr, "qhull warning: missing coplanar distance for option 'Un'.  Ignored\n");
-      else {
-	qh MAXcoplanar= qh_strtod (s, &s);
-        qh_option ("U-coplanar", NULL, &qh MAXcoplanar);
-      }
-      break;
-    case 'W':
-      if (*s == '-')
-	fprintf(qh ferr, "qhull warning: negative outside width for option 'Wn'.  Ignored.\n");
-      else if (!isdigit(*s))
-	fprintf(qh ferr, "qhull warning: missing outside width for option 'Wn'.  Ignored\n");
-      else {
-	qh MINoutside= qh_strtod (s, &s);
-        qh_option ("W-outside", NULL, &qh MINoutside);
-        qh APPROXhull= True;
-      }
-      break;
-    /************  sub menus ***************/
-    case 'F':
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-	case 'a':
-	  qh_option ("Farea", NULL, NULL);
-	  qh_appendprint (qh_PRINTarea);
-	  qh GETarea= True;
-	  break;
-	case 'A':
-	  qh_option ("FArea-total", NULL, NULL);
-	  qh GETarea= True;
-	  break;
-        case 'c':
-          qh_option ("Fcoplanars", NULL, NULL);
-          qh_appendprint (qh_PRINTcoplanars);
-          break;
-        case 'C':
-          qh_option ("FCentrums", NULL, NULL);
-          qh_appendprint (qh_PRINTcentrums);
-          break;
-	case 'd':
-          qh_option ("Fd-cdd-in", NULL, NULL);
-	  qh CDDinput= True;
-	  break;
-	case 'D':
-          qh_option ("FD-cdd-out", NULL, NULL);
-	  qh CDDoutput= True;
-	  break;
-	case 'F':
-	  qh_option ("FFacets-xridge", NULL, NULL);
-          qh_appendprint (qh_PRINTfacets_xridge);
-	  break;
-        case 'i':
-          qh_option ("Finner", NULL, NULL);
-          qh_appendprint (qh_PRINTinner);
-          break;
-        case 'I':
-          qh_option ("FIDs", NULL, NULL);
-          qh_appendprint (qh_PRINTids);
-          break;
-        case 'm':
-          qh_option ("Fmerges", NULL, NULL);
-          qh_appendprint (qh_PRINTmerges);
-          break;
-        case 'n':
-          qh_option ("Fneighbors", NULL, NULL);
-          qh_appendprint (qh_PRINTneighbors);
-          break;
-        case 'N':
-          qh_option ("FNeighbors-vertex", NULL, NULL);
-          qh_appendprint (qh_PRINTvneighbors);
-          break;
-        case 'o':
-          qh_option ("Fouter", NULL, NULL);
-          qh_appendprint (qh_PRINTouter);
-          break;
-	case 'O':
-	  if (qh PRINToptions1st) {
-	    qh_option ("FOptions", NULL, NULL);
-	    qh_appendprint (qh_PRINToptions);
-	  }else
-	    qh PRINToptions1st= True;
-	  break;
-	case 'p':
-	  qh_option ("Fpoint-intersect", NULL, NULL);
-	  qh_appendprint (qh_PRINTpointintersect);
-	  break;
-	case 'P':
-	  qh_option ("FPoint-nearest", NULL, NULL);
-	  qh_appendprint (qh_PRINTpointnearest);
-	  break;
-	case 'Q':
-	  qh_option ("FQhull", NULL, NULL);
-	  qh_appendprint (qh_PRINTqhull);
-	  break;
-        case 's':
-          qh_option ("Fsummary", NULL, NULL);
-          qh_appendprint (qh_PRINTsummary);
-          break;
-        case 'S':
-          qh_option ("FSize", NULL, NULL);
-          qh_appendprint (qh_PRINTsize);
-          qh GETarea= True;
-          break;
-        case 't':
-          qh_option ("Ftriangles", NULL, NULL);
-          qh_appendprint (qh_PRINTtriangles);
-          break;
-        case 'v':
-          /* option set in qh_initqhull_globals */
-          qh_appendprint (qh_PRINTvertices);
-          break;
-        case 'V':
-          qh_option ("FVertex-average", NULL, NULL);
-          qh_appendprint (qh_PRINTaverage);
-          break;
-	case 'x':
-	  qh_option ("Fxtremes", NULL, NULL);
-	  qh_appendprint (qh_PRINTextremes);
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'G':
-      isgeom= True;
-      qh_appendprint (qh_PRINTgeom);
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-        case 'a':
-          qh_option ("Gall-points", NULL, NULL);
-          qh PRINTdots= True;
-          break;
-        case 'c':
-          qh_option ("Gcentrums", NULL, NULL);
-          qh PRINTcentrums= True;
-          break;
-	case 'h':
-          qh_option ("Gintersections", NULL, NULL);
-	  qh DOintersections= True;
-	  break;
-	case 'i':
-          qh_option ("Ginner", NULL, NULL);
-	  qh PRINTinner= True;
-	  break;
-	case 'n':
-          qh_option ("Gno-planes", NULL, NULL);
-	  qh PRINTnoplanes= True;
-	  break;
-	case 'o':
-          qh_option ("Gouter", NULL, NULL);
-	  qh PRINTouter= True;
-	  break;
-	case 'p':
-          qh_option ("Gpoints", NULL, NULL);
-	  qh PRINTcoplanar= True;
-	  break;
-	case 'r':
-          qh_option ("Gridges", NULL, NULL);
-	  qh PRINTridges= True;
-	  break;
-	case 't':
-          qh_option ("Gtransparent", NULL, NULL);
-	  qh PRINTtransparent= True;
-	  break;
-	case 'v':
-          qh_option ("Gvertices", NULL, NULL);
-	  qh PRINTspheres= True;
-	  break;
-	case 'D':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing dimension for option 'GDn'\n");
-	  else {
-	    if (qh DROPdim >= 0)
-	      fprintf (qh ferr, "qhull warning: can only drop one dimension.  Previous 'GD%d' ignored\n",
-	           qh DROPdim);
-  	    qh DROPdim= qh_strtol (s, &s);
-            qh_option ("GDrop-dim", &qh DROPdim, NULL);
-          }
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'P':
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-	case 'd': case 'D':  /* see qh_initthresholds() */
-	  key= s[-1];
-	  i= qh_strtol (s, &s);
-	  r= 0;
-	  if (*s == ':') {
-	    s++;
-	    r= qh_strtod (s, &s);
-	  }
-	  if (key == 'd')
-  	    qh_option ("Pdrop-facets-dim-less", &i, &r);
-  	  else
-  	    qh_option ("PDrop-facets-dim-more", &i, &r);
-	  break;
-        case 'g':
-          qh_option ("Pgood-facets", NULL, NULL);
-          qh PRINTgood= True;
-          break;
-        case 'G':
-          qh_option ("PGood-facet-neighbors", NULL, NULL);
-          qh PRINTneighbors= True;
-          break;
-        case 'o':
-          qh_option ("Poutput-forced", NULL, NULL);
-          qh FORCEoutput= True;
-          break;
-        case 'p':
-          qh_option ("Pprecision-ignore", NULL, NULL);
-          qh PRINTprecision= False;
-          break;
-	case 'A':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing facet count for keep area option 'PAn'\n");
-	  else {
-  	    qh KEEParea= qh_strtol (s, &s);
-            qh_option ("PArea-keep", &qh KEEParea, NULL);
-            qh GETarea= True;
-          }
-	  break;
-	case 'F':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing facet area for option 'PFn'\n");
-	  else {
-  	    qh KEEPminArea= qh_strtod (s, &s);
-            qh_option ("PFacet-area-keep", NULL, &qh KEEPminArea);
-            qh GETarea= True;
-          }
-	  break;
-	case 'M':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing merge count for option 'PMn'\n");
-	  else {
-  	    qh KEEPmerge= qh_strtol (s, &s);
-            qh_option ("PMerge-keep", &qh KEEPmerge, NULL);
-          }
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'Q':
-      lastproject= -1;
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-	case 'b': case 'B':  /* handled by qh_initthresholds */
-	  key= s[-1];
-	  if (key == 'b' && *s == 'B') {
-	    s++;
-	    r= qh_DEFAULTbox;
-	    qh SCALEinput= True;
-	    qh_option ("QbBound-unit-box", NULL, &r);
-	    break;
-	  }
-	  if (key == 'b' && *s == 'b') {
-	    s++;
-	    qh SCALElast= True;
-	    qh_option ("Qbbound-last", NULL, NULL);
-	    break;
-	  }
-	  k= qh_strtol (s, &s);
-	  r= 0.0;
-	  wasproject= False;
-	  if (*s == ':') {
-	    s++;
-	    if ((r= qh_strtod(s, &s)) == 0.0) {
- 	      t= s;            /* need true dimension for memory allocation */
-	      while (*t && !isspace(*t)) {
-	        if (toupper(*t++) == 'B'
-	         && k == qh_strtol (t, &t)
-	         && *t++ == ':'
-	         && qh_strtod(t, &t) == 0.0) {
-	          qh PROJECTinput++;
-	          trace2((qh ferr, "qh_initflags: project dimension %d\n", k));
-	          qh_option ("Qb-project-dim", &k, NULL);
-		  wasproject= True;
-	          lastproject= k;
-	          break;
-		}
-	      }
-	    }
-  	  }
-	  if (!wasproject) {
-	    if (lastproject == k && r == 0.0)
-	      lastproject= -1;  /* doesn't catch all possible sequences */
-	    else if (key == 'b') {
-	      qh SCALEinput= True;
-	      if (r == 0.0)
-		r= -qh_DEFAULTbox;
-	      qh_option ("Qbound-dim-low", &k, &r);
-	    }else {
-	      qh SCALEinput= True;
-	      if (r == 0.0)
-		r= qh_DEFAULTbox;
-	      qh_option ("QBound-dim-high", &k, &r);
-	    }
-	  }
-	  break;
-	case 'c':
-	  qh_option ("Qcoplanar-keep", NULL, NULL);
-	  qh KEEPcoplanar= True;
-	  break;
-	case 'f':
-	  qh_option ("Qfurthest-outside", NULL, NULL);
-	  qh BESToutside= True;
-	  break;
-	case 'g':
-	  qh_option ("Qgood-facets-only", NULL, NULL);
-	  qh ONLYgood= True;
-	  break;
-	case 'i':
-	  qh_option ("Qinterior-keep", NULL, NULL);
-	  qh KEEPinside= True;
-	  break;
-	case 'm':
-	  qh_option ("Qmax-outside-only", NULL, NULL);
-	  qh ONLYmax= True;
-	  break;
-	case 'r':
-	  qh_option ("Qrandom-outside", NULL, NULL);
-	  qh RANDOMoutside= True;
-	  break;
-	case 's':
-	  qh_option ("Qsearch-initial-simplex", NULL, NULL);
-	  qh ALLpoints= True;
-	  break;
-	case 't':
-	  qh_option ("Qtriangulate", NULL, NULL);
-	  qh TRIangulate= True;
-	  break;
-	case 'T':
-	  qh_option ("QTestPoints", NULL, NULL);
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing number of test points for option 'QTn'\n");
-	  else {
-  	    qh TESTpoints= qh_strtol (s, &s);
-            qh_option ("QTestPoints", &qh TESTpoints, NULL);
-          }
-	  break;
-	case 'u':
-	  qh_option ("QupperDelaunay", NULL, NULL);
-	  qh UPPERdelaunay= True;
-	  break;
-	case 'v':
-	  qh_option ("Qvertex-neighbors-convex", NULL, NULL);
-	  qh TESTvneighbors= True;
-	  break;
-	case 'x':
-	  qh_option ("Qxact-merge", NULL, NULL);
-	  qh MERGEexact= True;
-	  break;
-	case 'z':
-	  qh_option ("Qz-infinity-point", NULL, NULL);
-	  qh ATinfinity= True;
-	  break;
-	case '0':
-	  qh_option ("Q0-no-premerge", NULL, NULL);
-	  qh NOpremerge= True;
-	  break;
-	case '1':
-	  if (!isdigit(*s)) {
-	    qh_option ("Q1-no-angle-sort", NULL, NULL);
-	    qh ANGLEmerge= False;
-	    break; 
-	  }
-	  switch(*s++) {
-  	  case '0':
-	    qh_option ("Q10-no-narrow", NULL, NULL);
-	    qh NOnarrow= True;
-	    break; 
-  	  case '1':
-	    qh_option ("Q11-trinormals Qtriangulate", NULL, NULL);
-	    qh TRInormals= True;
-	    qh TRIangulate= True;
-	    break; 
-	  default:
-	    s--;
-	    fprintf (qh ferr, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]);
-	    while (*++s && !isspace(*s));
-	    break;
-	  }
-	  break;
-	case '2':
-	  qh_option ("Q2-no-merge-independent", NULL, NULL);
-	  qh MERGEindependent= False;
-	  goto LABELcheckdigit;
-	  break; /* no warnings */
-	case '3':
-	  qh_option ("Q3-no-merge-vertices", NULL, NULL);
-	  qh MERGEvertices= False;
-	LABELcheckdigit:
-	  if (isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: can not follow '1', '2', or '3' with a digit.  '%c' skipped.\n",
-	             *s++);
-	  break;
-	case '4':
-	  qh_option ("Q4-avoid-old-into-new", NULL, NULL);
-	  qh AVOIDold= True;
-	  break;
-	case '5':
-	  qh_option ("Q5-no-check-outer", NULL, NULL);
-	  qh SKIPcheckmax= True;
-	  break;
-	case '6':
-	  qh_option ("Q6-no-concave-merge", NULL, NULL);
-	  qh SKIPconvex= True;
-	  break;
-	case '7':
-	  qh_option ("Q7-no-breadth-first", NULL, NULL);
-	  qh VIRTUALmemory= True;
-	  break;
-	case '8':
-	  qh_option ("Q8-no-near-inside", NULL, NULL);
-	  qh NOnearinside= True;
-	  break;
-	case '9':
-	  qh_option ("Q9-pick-furthest", NULL, NULL);
-	  qh PICKfurthest= True;
-	  break;
-	case 'G':
-	  i= qh_strtol (s, &t);
-	  if (qh GOODpoint)
-	    fprintf (qh ferr, "qhull warning: good point already defined for option 'QGn'.  Ignored\n");
-          else if (s == t)
-	    fprintf (qh ferr, "qhull warning: missing good point id for option 'QGn'.  Ignored\n");
-	  else if (i < 0 || *s == '-') {
- 	    qh GOODpoint= i-1;
-  	    qh_option ("QGood-if-dont-see-point", &i, NULL);
-	  }else {
- 	    qh GOODpoint= i+1;
-  	    qh_option ("QGood-if-see-point", &i, NULL);
-  	  }
- 	  s= t;
-	  break;
-	case 'J':
-          if (!isdigit(*s) && *s != '-')
-   	    qh JOGGLEmax= 0.0;
-	  else {
- 	    qh JOGGLEmax= (realT) qh_strtod (s, &s);
-            qh_option ("QJoggle", NULL, &qh JOGGLEmax);
-	  }
-	  break;
-	case 'R':
-          if (!isdigit(*s) && *s != '-')
-	    fprintf (qh ferr, "qhull warning: missing random seed for option 'QRn'.  Ignored\n");
-	  else {
- 	    qh ROTATErandom= i= qh_strtol(s, &s);
-   	    if (i > 0)
-   	      qh_option ("QRotate-id", &i, NULL );
-	    else if (i < -1)
-   	      qh_option ("QRandom-seed", &i, NULL );
-          }
-	  break;
-	case 'V':
-	  i= qh_strtol (s, &t);
-	  if (qh GOODvertex)
-	    fprintf (qh ferr, "qhull warning: good vertex already defined for option 'QVn'.  Ignored\n");
-          else if (s == t)
-	    fprintf (qh ferr, "qhull warning: no good point id given for option 'QVn'.  Ignored\n");
-	  else if (i < 0) {
- 	    qh GOODvertex= i - 1;
- 	    qh_option ("QV-good-facets-not-point", &i, NULL);
-	  }else {
-  	    qh_option ("QV-good-facets-point", &i, NULL);
-	    qh GOODvertex= i + 1;
-          }
- 	  s= t;
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'T':
-      while (*s && !isspace(*s)) {
-	if (isdigit(*s) || *s == '-')
-	  qh IStracing= qh_strtol(s, &s);
-	else switch(*s++) {
-	case 'c':
-          qh_option ("Tcheck-frequently", NULL, NULL);
-	  qh CHECKfrequently= True;
-	  break;
-	case 's':
-          qh_option ("Tstatistics", NULL, NULL);
-	  qh PRINTstatistics= True;
-	  break;
-	case 'v':
-          qh_option ("Tverify", NULL, NULL);
-	  qh VERIFYoutput= True;
-	  break;
-	case 'z':
-	  if (!qh fout)
-	    fprintf (qh ferr, "qhull warning: output file undefined (stdout).  Option 'Tz' ignored.\n");
-	  else {
-	    qh_option ("Tz-stdout", NULL, NULL);
-  	    qh ferr= qh fout;
-  	    qhmem.ferr= qh fout;
-	  }
-	  break;
-	case 'C':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing point id for cone for trace option 'TCn'.  Ignored\n");
-	  else {
-	    i= qh_strtol (s, &s);
-	    qh_option ("TCone-stop", &i, NULL);
-	    qh STOPcone= i + 1;
-          }
-	  break;
-	case 'F':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing frequency count for trace option 'TFn'.  Ignored\n");
-	  else {
-	    qh REPORTfreq= qh_strtol (s, &s);
-            qh_option ("TFacet-log", &qh REPORTfreq, NULL);
-	    qh REPORTfreq2= qh REPORTfreq/2;  /* for tracemerging() */
-	  }
-	  break;
-	case 'I':
-	  if (s[0] != ' ' || s[1] == '\"' || s[1] == '\'' ||isspace (s[1])) {
-	    s++;
-	    fprintf (qh ferr, "qhull warning: option 'TI' mistyped.\nUse 'TI', one space, file name, and space or end-of-line.\nDo not use quotes.  Option 'FI' ignored.\n");
-	  }else {  /* not a procedure because of qh_option (filename, NULL, NULL); */
-	    char filename[500], *t= filename;
-
-	    s++;
-	    while (*s) {
-	      if (t - filename >= sizeof (filename)-2) {
-		fprintf (qh ferr, "qhull error: filename for 'TI' too long.\n");
-		qh_errexit (qh_ERRinput, NULL, NULL);
-	      }
-	      if (isspace (*s))
-		break;
-	      *(t++)= *s++;
-	    }
-	    *t= '\0';
-	    if (!freopen (filename, "r", stdin)) {
-	      fprintf (qh ferr, "qhull error: could not open file \"%s\".", filename);
-	      qh_errexit (qh_ERRinput, NULL, NULL);
-	    }else {
-	      qh_option ("TInput-file", NULL, NULL);
-	      qh_option (filename, NULL, NULL);
-	    }
-	  }
-	  break;
-	case 'O':
-	  if (s[0] != ' ' || s[1] == '\"' || isspace (s[1])) {
-	    s++;
-	    fprintf (qh ferr, "qhull warning: option 'TO' mistyped.\nUse 'TO', one space, file name, and space or end-of-line.\nThe file name may be enclosed in single quotes.\nDo not use double quotes.  Option 'FO' ignored.\n");
-	  }else {  /* not a procedure because of qh_option (filename, NULL, NULL); */
-	    char filename[500], *t= filename;
-	    boolT isquote= False;
-
-	    s++;
-	    if (*s == '\'') {
-	      isquote= True;
-	      s++;
-	    }
-	    while (*s) {
-	      if (t - filename >= sizeof (filename)-2) {
-		fprintf (qh ferr, "qhull error: filename for 'TO' too long.\n");
-		qh_errexit (qh_ERRinput, NULL, NULL);
-	      }
-	      if (isquote) {
-		if (*s == '\'') {
-		  s++;
-		  isquote= False;
-		  break;
-		}
-	      }else if (isspace (*s))
-		break;
-	      *(t++)= *s++;
-	    }
-	    *t= '\0';
-	    if (isquote)
-	      fprintf (qh ferr, "qhull error: missing end quote for option 'TO'.  Rest of line ignored.\n");
-	    else if (!freopen (filename, "w", stdout)) {
-	      fprintf (qh ferr, "qhull error: could not open file \"%s\".", filename);
-	      qh_errexit (qh_ERRinput, NULL, NULL);
-	    }else {
-	      qh_option ("TOutput-file", NULL, NULL);
-	      qh_option (filename, NULL, NULL);
-	    }
-	  }
-	  break;
-	case 'P':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing point id for trace option 'TPn'.  Ignored\n");
-	  else {
-	    qh TRACEpoint= qh_strtol (s, &s);
-            qh_option ("Trace-point", &qh TRACEpoint, NULL);
-          }
-	  break;
-	case 'M':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing merge id for trace option 'TMn'.  Ignored\n");
-	  else {
-	    qh TRACEmerge= qh_strtol (s, &s);
-            qh_option ("Trace-merge", &qh TRACEmerge, NULL);
-          }
-	  break;
-	case 'R':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing rerun count for trace option 'TRn'.  Ignored\n");
-	  else {
-	    qh RERUN= qh_strtol (s, &s);
-            qh_option ("TRerun", &qh RERUN, NULL);
-          }
-	  break;
-	case 'V':
-	  i= qh_strtol (s, &t);
-	  if (s == t)
-	    fprintf (qh ferr, "qhull warning: missing furthest point id for trace option 'TVn'.  Ignored\n");
-	  else if (i < 0) {
-	    qh STOPpoint= i - 1;
-            qh_option ("TV-stop-before-point", &i, NULL);
-	  }else {
-	    qh STOPpoint= i + 1;
-            qh_option ("TV-stop-after-point", &i, NULL);
-          }
-          s= t;
-	  break;
-	case 'W':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing max width for trace option 'TWn'.  Ignored\n");
-	  else {
- 	    qh TRACEdist= (realT) qh_strtod (s, &s);
-            qh_option ("TWide-trace", NULL, &qh TRACEdist);
-          }
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    default:
-      fprintf (qh ferr, "qhull warning: unknown flag %c (%x)\n", (int)s[-1],
-	       (int)s[-1]);
-      break;
-    }
-    if (s-1 == prev_s && *s && !isspace(*s)) {
-      fprintf (qh ferr, "qhull warning: missing space after flag %c (%x); reserved for menu. Skipped.\n",
-	       (int)*prev_s, (int)*prev_s);
-      while (*s && !isspace(*s))
-	s++;
-    }
-  }
-  if (isgeom && !qh FORCEoutput && qh PRINTout[1])
-    fprintf (qh ferr, "qhull warning: additional output formats are not compatible with Geomview\n");
-  /* set derived values in qh_initqhull_globals */
-} /* initflags */
-
-
-/*---------------------------------
-
-  qh_initqhull_buffers()
-    initialize global memory buffers
-
-  notes:
-    must match qh_freebuffers()
-*/
-void qh_initqhull_buffers (void) {
-  int k;
-
-  qh TEMPsize= (qhmem.LASTsize - sizeof (setT))/SETelemsize;
-  if (qh TEMPsize <= 0 || qh TEMPsize > qhmem.LASTsize)
-    qh TEMPsize= 8;  /* e.g., if qh_NOmem */
-  qh other_points= qh_setnew (qh TEMPsize);
-  qh del_vertices= qh_setnew (qh TEMPsize);
-  qh coplanarset= qh_setnew (qh TEMPsize);
-  qh NEARzero= (realT *)qh_memalloc(qh hull_dim * sizeof(realT));
-  qh lower_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  qh upper_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  qh lower_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  qh upper_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  for(k= qh input_dim+1; k--; ) {
-    qh lower_threshold[k]= -REALmax;
-    qh upper_threshold[k]= REALmax;
-    qh lower_bound[k]= -REALmax;
-    qh upper_bound[k]= REALmax;
-  }
-  qh gm_matrix= (coordT *)qh_memalloc((qh hull_dim+1) * qh hull_dim * sizeof(coordT));
-  qh gm_row= (coordT **)qh_memalloc((qh hull_dim+1) * sizeof(coordT *));
-} /* initqhull_buffers */
-
-/*---------------------------------
-
-  qh_initqhull_globals( points, numpoints, dim, ismalloc )
-    initialize globals
-    if ismalloc
-      points were malloc'd and qhull should free at end
-
-  returns:
-    sets qh.first_point, num_points, input_dim, hull_dim and others
-    seeds random number generator (seed=1 if tracing)
-    modifies qh.hull_dim if ((qh.DELAUNAY and qh.PROJECTdelaunay) or qh.PROJECTinput)
-    adjust user flags as needed
-    also checks DIM3 dependencies and constants
-
-  notes:
-    do not use qh_point() since an input transformation may move them elsewhere
-
-  see:
-    qh_initqhull_start() sets default values for non-zero globals
-
-  design:
-    initialize points array from input arguments
-    test for qh.ZEROcentrum
-      (i.e., use opposite vertex instead of cetrum for convexity testing)
-    test for qh.PRINTgood (i.e., only print 'good' facets)
-    initialize qh.CENTERtype, qh.normal_size,
-      qh.center_size, qh.TRACEpoint/level,
-    initialize and test random numbers
-    check for conflicting print output options
-*/
-void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc) {
-  int seed, pointsneeded, extra= 0, i, randi, k;
-  boolT printgeom= False, printmath= False, printcoplanar= False;
-  realT randr;
-  realT factorial;
-
-  time_t timedata;
-
-  trace0((qh ferr, "qh_initqhull_globals: for %s | %s\n", qh rbox_command,
-      qh qhull_command));
-  qh POINTSmalloc= ismalloc;
-  qh first_point= points;
-  qh num_points= numpoints;
-  qh hull_dim= qh input_dim= dim;
-  if (!qh NOpremerge && !qh MERGEexact && !qh PREmerge && qh JOGGLEmax > REALmax/2) {
-    qh MERGING= True;
-    if (qh hull_dim <= 4) {
-      qh PREmerge= True;
-      qh_option ("_pre-merge", NULL, NULL);
-    }else {
-      qh MERGEexact= True;
-      qh_option ("Qxact_merge", NULL, NULL);
-    }
-  }else if (qh MERGEexact) 
-    qh MERGING= True;
-  if (!qh NOpremerge && qh JOGGLEmax > REALmax/2) {
-#ifdef qh_NOmerge
-    qh JOGGLEmax= 0.0;
-#endif
-  }
-  if (qh TRIangulate && qh JOGGLEmax < REALmax/2 && qh PRINTprecision)
-    fprintf(qh ferr, "qhull warning: joggle ('QJ') always produces simplicial output.  Triangulated output ('Qt') does nothing.\n");
-  if (qh JOGGLEmax < REALmax/2 && qh DELAUNAY && !qh SCALEinput && !qh SCALElast) {
-    qh SCALElast= True;
-    qh_option ("Qbbound-last-qj", NULL, NULL);
-  }
-  if (qh MERGING && !qh POSTmerge && qh premerge_cos > REALmax/2
-  && qh premerge_centrum == 0) {
-    qh ZEROcentrum= True;
-    qh ZEROall_ok= True;
-    qh_option ("_zero-centrum", NULL, NULL);
-  }
-  if (qh JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh PRINTprecision)
-    fprintf(qh ferr, "qhull warning: real epsilon, %2.2g, is probably too large for joggle ('QJn')\nRecompile with double precision reals (see user.h).\n",
-          REALepsilon);
-#ifdef qh_NOmerge
-  if (qh MERGING) {
-    fprintf (qh ferr, "qhull input error: merging not installed (qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-#endif
-  if (!(qh PRINTgood || qh PRINTneighbors)) {
-    if (qh KEEParea || qh KEEPminArea < REALmax/2 || qh KEEPmerge || qh DELAUNAY
-	|| (!qh ONLYgood && (qh GOODvertex || qh GOODpoint))) {
-      qh PRINTgood= True;
-      qh_option ("Pgood", NULL, NULL);
-    }
-  }
-  if (qh DELAUNAY && qh KEEPcoplanar && !qh KEEPinside) {
-    qh KEEPinside= True;
-    qh_option ("Qinterior-keep", NULL, NULL);
-  }
-  if (qh DELAUNAY && qh HALFspace) {
-    fprintf (qh ferr, "qhull input error: can not use Delaunay ('d') or Voronoi ('v') with halfspace intersection ('H')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (!qh DELAUNAY && (qh UPPERdelaunay || qh ATinfinity)) {
-    fprintf (qh ferr, "qhull input error: use upper-Delaunay ('Qu') or infinity-point ('Qz') with Delaunay ('d') or Voronoi ('v')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (qh UPPERdelaunay && qh ATinfinity) {
-    fprintf (qh ferr, "qhull input error: can not use infinity-point ('Qz') with upper-Delaunay ('Qu')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (qh SCALElast && !qh DELAUNAY && qh PRINTprecision)
-    fprintf (qh ferr, "qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n");
-  qh DOcheckmax= (!qh SKIPcheckmax && qh MERGING );
-  qh KEEPnearinside= (qh DOcheckmax && !(qh KEEPinside && qh KEEPcoplanar) 
-                          && !qh NOnearinside);
-  if (qh MERGING)
-    qh CENTERtype= qh_AScentrum;
-  else if (qh VORONOI)
-    qh CENTERtype= qh_ASvoronoi;
-  if (qh TESTvneighbors && !qh MERGING) {
-    fprintf(qh ferr, "qhull input error: test vertex neighbors ('Qv') needs a merge option\n");
-    qh_errexit (qh_ERRinput, NULL ,NULL);
-  }
-  if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay)) {
-    qh hull_dim -= qh PROJECTinput;
-    if (qh DELAUNAY) {
-      qh hull_dim++;
-      extra= 1;
-    }
-  }
-  if (qh hull_dim <= 1) {
-    fprintf(qh ferr, "qhull error: dimension %d must be > 1\n", qh hull_dim);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  for (k= 2, factorial=1.0; k < qh hull_dim; k++)
-    factorial *= k;
-  qh AREAfactor= 1.0 / factorial;
-  trace2((qh ferr, "qh_initqhull_globals: initialize globals.  dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n",
-	dim, numpoints, ismalloc, qh PROJECTinput, qh hull_dim));
-  qh normal_size= qh hull_dim * sizeof(coordT);
-  qh center_size= qh normal_size - sizeof(coordT);
-  pointsneeded= qh hull_dim+1;
-  if (qh hull_dim > qh_DIMmergeVertex) {
-    qh MERGEvertices= False;
-    qh_option ("Q3-no-merge-vertices-dim-high", NULL, NULL);
-  }
-  if (qh GOODpoint)
-    pointsneeded++;
-#ifdef qh_NOtrace
-  if (qh IStracing) {
-    fprintf (qh ferr, "qhull input error: tracing is not installed (qh_NOtrace in user.h)");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-#endif
-  if (qh RERUN > 1) {
-    qh TRACElastrun= qh IStracing; /* qh_build_withrestart duplicates next conditional */
-    if (qh IStracing != -1)
-      qh IStracing= 0;
-  }else if (qh TRACEpoint != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
-    qh TRACElevel= (qh IStracing? qh IStracing : 3);
-    qh IStracing= 0;
-  }
-  if (qh ROTATErandom == 0 || qh ROTATErandom == -1) {
-    seed= time (&timedata);
-    if (qh ROTATErandom  == -1) {
-      seed= -seed;
-      qh_option ("QRandom-seed", &seed, NULL );
-    }else
-      qh_option ("QRotate-random", &seed, NULL);
-    qh ROTATErandom= seed;
-  }
-  seed= qh ROTATErandom;
-  if (seed == INT_MIN)    /* default value */
-    seed= 1;
-  else if (seed < 0)
-    seed= -seed;
-  qh_RANDOMseed_(seed);
-  randr= 0.0;
-  for (i= 1000; i--; ) {
-    randi= qh_RANDOMint;
-    randr += randi;
-    if (randi > qh_RANDOMmax) {
-      fprintf (qh ferr, "\
-qhull configuration error (qh_RANDOMmax in user.h):\n\
-   random integer %d > qh_RANDOMmax (%.8g)\n",
-	       randi, qh_RANDOMmax);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-  }
-  qh_RANDOMseed_(seed);
-  randr = randr/1000;
-  if (randr < qh_RANDOMmax/10
-  || randr > qh_RANDOMmax * 5)
-    fprintf (qh ferr, "\
-qhull configuration warning (qh_RANDOMmax in user.h):\n\
-   average of 1000 random integers (%.2g) is much different than expected (%.2g).\n\
-   Is qh_RANDOMmax (%.2g) wrong?\n",
-	     randr, qh_RANDOMmax/2.0, qh_RANDOMmax);
-  qh RANDOMa= 2.0 * qh RANDOMfactor/qh_RANDOMmax;
-  qh RANDOMb= 1.0 - qh RANDOMfactor;
-  if (qh_HASHfactor < 1.1) {
-    fprintf(qh ferr, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1.  Qhull uses linear hash probing\n",
-      qh_HASHfactor);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (numpoints+extra < pointsneeded) {
-    fprintf(qh ferr,"qhull input error: not enough points (%d) to construct initial simplex (need %d)\n",
-	    numpoints, pointsneeded);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (qh PRINTtransparent) {
-    if (qh hull_dim != 4 || !qh DELAUNAY || qh VORONOI || qh DROPdim >= 0) {
-      fprintf(qh ferr,"qhull input error: transparent Delaunay ('Gt') needs 3-d Delaunay ('d') w/o 'GDn'\n");
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    qh DROPdim = 3;
-    qh PRINTridges = True;
-  }
-  for (i= qh_PRINTEND; i--; ) {
-    if (qh PRINTout[i] == qh_PRINTgeom)
-      printgeom= True;
-    else if (qh PRINTout[i] == qh_PRINTmathematica)
-      printmath= True;
-    else if (qh PRINTout[i] == qh_PRINTcoplanars)
-      printcoplanar= True;
-    else if (qh PRINTout[i] == qh_PRINTpointnearest)
-      printcoplanar= True;
-    else if (qh PRINTout[i] == qh_PRINTpointintersect && !qh HALFspace) {
-      fprintf (qh ferr, "qhull input error: option 'Fp' is only used for \nhalfspace intersection ('Hn,n,n').\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }else if (qh PRINTout[i] == qh_PRINTtriangles && (qh HALFspace || qh VORONOI)) {
-      fprintf (qh ferr, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }else if (qh PRINTout[i] == qh_PRINTcentrums && qh VORONOI) {
-      fprintf (qh ferr, "qhull input error: option 'FC' is not available for Voronoi vertices ('v')\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }else if (qh PRINTout[i] == qh_PRINTvertices) {
-      if (qh VORONOI)
-        qh_option ("Fvoronoi", NULL, NULL);
-      else 
-        qh_option ("Fvertices", NULL, NULL);
-    }
-  }
-  if (printcoplanar && qh DELAUNAY && qh JOGGLEmax < REALmax/2) {
-    if (qh PRINTprecision) 
-      fprintf (qh ferr, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
-  }
-  if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood) {
-    if ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar) {
-      qh KEEPcoplanar = True;
-      qh_option ("Qcoplanar", NULL, NULL);
-    }
-  }
-  if (printmath && (qh hull_dim > 3 || qh VORONOI)) {
-    fprintf (qh ferr, "qhull input error: Mathematica output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (printgeom) {
-    if (qh hull_dim > 4) {
-      fprintf (qh ferr, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (qh PRINTnoplanes && !(qh PRINTcoplanar + qh PRINTcentrums
-     + qh PRINTdots + qh PRINTspheres + qh DOintersections + qh PRINTridges)) {
-      fprintf (qh ferr, "qhull input error: no output specified for Geomview\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (qh VORONOI && (qh hull_dim > 3 || qh DROPdim >= 0)) {
-      fprintf (qh ferr, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    /* can not warn about furthest-site Geomview output: no lower_threshold */
-    if (qh hull_dim == 4 && qh DROPdim == -1 &&
-	(qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
-      fprintf (qh ferr, "qhull input warning: coplanars, vertices, and centrums output not\n\
-available for 4-d output (ignored).  Could use 'GDn' instead.\n");
-      qh PRINTcoplanar= qh PRINTspheres= qh PRINTcentrums= False;
-    }
-  }
-  qh PRINTdim= qh hull_dim;
-  if (qh DROPdim >=0) {    /* after Geomview checks */
-    if (qh DROPdim < qh hull_dim) {
-      qh PRINTdim--;
-      if (!printgeom || qh hull_dim < 3)
-        fprintf (qh ferr, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh DROPdim);
-    }else
-      qh DROPdim= -1;
-  }else if (qh VORONOI) {
-    qh DROPdim= qh hull_dim-1;
-    qh PRINTdim= qh hull_dim-1;
-  }
-} /* initqhull_globals */
- 
-/*---------------------------------
-
-  qh_initqhull_mem(  )
-    initialize mem.c for qhull
-    qh.hull_dim and qh.normal_size determine some of the allocation sizes
-    if qh.MERGING,
-      includes ridgeT
-    calls qh_user_memsizes() to add up to 10 additional sizes for quick allocation
-      (see numsizes below)
-
-  returns:
-    mem.c already for qh_memalloc/qh_memfree (errors if called beforehand)
-
-  notes:
-    qh_produceoutput() prints memsizes
-
-*/
-void qh_initqhull_mem (void) {
-  int numsizes;
-  int i;
-
-  numsizes= 8+10;
-  qh_meminitbuffers (qh IStracing, qh_MEMalign, numsizes,
-                     qh_MEMbufsize,qh_MEMinitbuf);
-  qh_memsize(sizeof(vertexT));
-  if (qh MERGING) {
-    qh_memsize(sizeof(ridgeT));
-    qh_memsize(sizeof(mergeT));
-  }
-  qh_memsize(sizeof(facetT));
-  i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;  /* ridge.vertices */
-  qh_memsize(i);
-  qh_memsize(qh normal_size);        /* normal */
-  i += SETelemsize;                 /* facet.vertices, .ridges, .neighbors */
-  qh_memsize(i);
-  qh_user_memsizes();
-  qh_memsetup();
-} /* initqhull_mem */
-
-/*---------------------------------
-
-  qh_initqhull_start( infile, outfile, errfile )
-    start initialization of qhull
-    initialize statistics, stdio, default values for global variables
-
-  see:
-    qh_maxmin() determines the precision constants
-*/
-void qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile) {
-
-  qh_CPUclock; /* start the clock */
-#if qh_QHpointer
-  if (!(qh_qh= (qhT *)malloc (sizeof(qhT)))) {
-    fprintf (errfile, "qhull error (qh_initqhull_globals): insufficient memory\n");
-    exit (qh_ERRmem);  /* no error handler */
-  }
-  memset((char *)qh_qh, 0, sizeof(qhT));   /* every field is 0, FALSE, NULL */
-#else
-  memset((char *)&qh_qh, 0, sizeof(qhT));
-#endif
-  strcat (qh qhull, "qhull");
-  qh_initstatistics();
-  qh ANGLEmerge= True;
-  qh DROPdim= -1;
-  qh ferr= errfile;
-  qh fin= infile;
-  qh fout= outfile;
-  qh furthest_id= -1;
-  qh JOGGLEmax= REALmax;
-  qh KEEPminArea = REALmax;
-  qh last_low= REALmax;
-  qh last_high= REALmax;
-  qh last_newhigh= REALmax;
-  qh max_outside= 0.0;
-  qh max_vertex= 0.0;
-  qh MAXabs_coord= 0.0;
-  qh MAXsumcoord= 0.0;
-  qh MAXwidth= -REALmax;
-  qh MERGEindependent= True;
-  qh MINdenom_1= fmax_(1.0/REALmax, REALmin); /* used by qh_scalepoints */
-  qh MINoutside= 0.0;
-  qh MINvisible= REALmax;
-  qh MAXcoplanar= REALmax;
-  qh outside_err= REALmax;
-  qh premerge_centrum= 0.0;
-  qh premerge_cos= REALmax;
-  qh PRINTprecision= True;
-  qh PRINTradius= 0.0;
-  qh postmerge_cos= REALmax;
-  qh postmerge_centrum= 0.0;
-  qh ROTATErandom= INT_MIN;
-  qh MERGEvertices= True;
-  qh totarea= 0.0;
-  qh totvol= 0.0;
-  qh TRACEdist= REALmax;
-  qh TRACEpoint= -1; /* recompile or use 'TPn' */
-  qh tracefacet_id= UINT_MAX;  /* recompile to trace a facet */
-  qh tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
-  qh_RANDOMseed_(1);
-} /* initqhull_start */
-
-/*---------------------------------
-
-  qh_initthresholds( commandString )
-    set thresholds for printing and scaling from commandString
-
-  returns:
-    sets qh.GOODthreshold or qh.SPLITthreshold if 'Pd0D1' used
-
-  see:
-    qh_initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk'
-    qh_inthresholds()
-
-  design:
-    for each 'Pdn' or 'PDn' option
-      check syntax
-      set qh.lower_threshold or qh.upper_threshold
-    set qh.GOODthreshold if an unbounded threshold is used
-    set qh.SPLITthreshold if a bounded threshold is used
-*/
-void qh_initthresholds(char *command) {
-  realT value;
-  int index, maxdim, k;
-  char *s= command;
-  char key;
-
-  maxdim= qh input_dim;
-  if (qh DELAUNAY && (qh PROJECTdelaunay || qh PROJECTinput))
-    maxdim++;
-  while (*s) {
-    if (*s == '-')
-      s++;
-    if (*s == 'P') {
-      s++;
-      while (*s && !isspace(key= *s++)) {
-	if (key == 'd' || key == 'D') {
-	  if (!isdigit(*s)) {
-	    fprintf(qh ferr, "qhull warning: no dimension given for Print option '%c' at: %s.  Ignored\n",
-		    key, s-1);
-	    continue;
-	  }
-	  index= qh_strtol (s, &s);
-	  if (index >= qh hull_dim) {
-	    fprintf(qh ferr, "qhull warning: dimension %d for Print option '%c' is >= %d.  Ignored\n",
-	        index, key, qh hull_dim);
-	    continue;
-	  }
-	  if (*s == ':') {
-	    s++;
-	    value= qh_strtod(s, &s);
-	    if (fabs((double)value) > 1.0) {
-	      fprintf(qh ferr, "qhull warning: value %2.4g for Print option %c is > +1 or < -1.  Ignored\n",
-	              value, key);
-	      continue;
-	    }
-	  }else
-	    value= 0.0;
-	  if (key == 'd')
-	    qh lower_threshold[index]= value;
-	  else
-	    qh upper_threshold[index]= value;
-	}
-      }
-    }else if (*s == 'Q') {
-      s++;
-      while (*s && !isspace(key= *s++)) {
-	if (key == 'b' && *s == 'B') {
-	  s++;
-	  for (k=maxdim; k--; ) {
-	    qh lower_bound[k]= -qh_DEFAULTbox;
-	    qh upper_bound[k]= qh_DEFAULTbox;
-	  }
-	}else if (key == 'b' && *s == 'b')
-	  s++;
-	else if (key == 'b' || key == 'B') {
-	  if (!isdigit(*s)) {
-	    fprintf(qh ferr, "qhull warning: no dimension given for Qhull option %c.  Ignored\n",
-		    key);
-	    continue;
-	  }
-	  index= qh_strtol (s, &s);
-	  if (index >= maxdim) {
-	    fprintf(qh ferr, "qhull warning: dimension %d for Qhull option %c is >= %d.  Ignored\n",
-	        index, key, maxdim);
-	    continue;
-	  }
-	  if (*s == ':') {
-	    s++;
-	    value= qh_strtod(s, &s);
-	  }else if (key == 'b')
-	    value= -qh_DEFAULTbox;
-	  else
-	    value= qh_DEFAULTbox;
-	  if (key == 'b')
-	    qh lower_bound[index]= value;
-	  else
-	    qh upper_bound[index]= value;
-	}
-      }
-    }else {
-      while (*s && !isspace (*s))
-        s++;
-    }
-    while (isspace (*s))
-      s++;
-  }
-  for (k= qh hull_dim; k--; ) {
-    if (qh lower_threshold[k] > -REALmax/2) {
-      qh GOODthreshold= True;
-      if (qh upper_threshold[k] < REALmax/2) {
-        qh SPLITthresholds= True;
-        qh GOODthreshold= False;
-        break;
-      }
-    }else if (qh upper_threshold[k] < REALmax/2)
-      qh GOODthreshold= True;
-  }
-} /* initthresholds */
-
-/*---------------------------------
-
-  qh_option( option, intVal, realVal )
-    add an option description to qh.qhull_options
-
-  notes:
-    will be printed with statistics ('Ts') and errors
-    strlen(option) < 40
-*/
-void qh_option (char *option, int *i, realT *r) {
-  char buf[200];
-  int len, maxlen;
-
-  sprintf (buf, "  %s", option);
-  if (i)
-    sprintf (buf+strlen(buf), " %d", *i);
-  if (r)
-    sprintf (buf+strlen(buf), " %2.2g", *r);
-  len= strlen(buf);
-  qh qhull_optionlen += len;
-  maxlen= sizeof (qh qhull_options) - len -1;
-  maximize_(maxlen, 0);
-  if (qh qhull_optionlen >= 80 && maxlen > 0) {
-    qh qhull_optionlen= len;
-    strncat (qh qhull_options, "\n", maxlen--);
-  }
-  strncat (qh qhull_options, buf, maxlen);
-} /* option */
-
-#if qh_QHpointer
-/*---------------------------------
-
-  qh_restore_qhull( oldqh )
-    restores a previously saved qhull
-    also restores qh_qhstat and qhmem.tempstack
-
-  notes:
-    errors if current qhull hasn't been saved or freed
-    uses qhmem for error reporting
-
-  NOTE 1998/5/11:
-    Freeing memory after qh_save_qhull and qh_restore_qhull
-    is complicated.  The procedures will be redesigned.
-
-  see:
-    qh_save_qhull()
-*/
-void qh_restore_qhull (qhT **oldqh) {
-
-  if (*oldqh && strcmp ((*oldqh)->qhull, "qhull")) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n",
-                  *oldqh);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (qh_qh) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not save or free existing qhull\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (!*oldqh || !(*oldqh)->old_qhstat) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not previously save qhull %p\n",
-                  *oldqh);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh_qh= *oldqh;
-  *oldqh= NULL;
-  qh_qhstat= qh old_qhstat;
-  qhmem.tempstack= qh old_tempstack;
-  trace1((qh ferr, "qh_restore_qhull: restored qhull from %p\n", *oldqh));
-} /* restore_qhull */
-
-/*---------------------------------
-
-  qh_save_qhull(  )
-    saves qhull for a later qh_restore_qhull
-    also saves qh_qhstat and qhmem.tempstack
-
-  returns:
-    qh_qh=NULL
-
-  notes:
-    need to initialize qhull or call qh_restore_qhull before continuing
-
-  NOTE 1998/5/11:
-    Freeing memory after qh_save_qhull and qh_restore_qhull
-    is complicated.  The procedures will be redesigned.
-
-  see:
-    qh_restore_qhull()
-*/
-qhT *qh_save_qhull (void) {
-  qhT *oldqh;
-
-  trace1((qhmem.ferr, "qh_save_qhull: save qhull %p\n", qh_qh));
-  if (!qh_qh) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_save_qhull): qhull not initialized\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh old_qhstat= qh_qhstat;
-  qh_qhstat= NULL;
-  qh old_tempstack= qhmem.tempstack;
-  qhmem.tempstack= NULL;
-  oldqh= qh_qh;
-  qh_qh= NULL;
-  return oldqh;
-} /* save_qhull */
-
-#endif
-
-/*---------------------------------
-
-  qh_strtol( s, endp) qh_strtod( s, endp)
-    internal versions of strtol() and strtod()
-    does not skip trailing spaces
-  notes:
-    some implementations of strtol()/strtod() skip trailing spaces
-*/
-double qh_strtod (const char *s, char **endp) {
-  double result;
-
-  result= strtod (s, endp);
-  if (s < (*endp) && (*endp)[-1] == ' ')
-    (*endp)--;
-  return result;
-} /* strtod */
-
-int qh_strtol (const char *s, char **endp) {
-  int result;
-
-  result= (int) strtol (s, endp, 10);
-  if (s< (*endp) && (*endp)[-1] == ' ')
-    (*endp)--;
-  return result;
-} /* strtol */
diff --git a/extern/qhull/src/io.c b/extern/qhull/src/io.c
deleted file mode 100644
index 9b0ccdd0b24..00000000000
--- a/extern/qhull/src/io.c
+++ /dev/null
@@ -1,4089 +0,0 @@
-/*
  ---------------------------------
-
-   io.c 
-   Input/Output routines of qhull application
-
-   see qh-io.htm and io.h
-
-   see user.c for qh_errprint and qh_printfacetlist
-
-   unix.c calls qh_readpoints and qh_produce_output
-
-   unix.c and user.c are the only callers of io.c functions
-   This allows the user to avoid loading io.o from qhull.a
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include "qhull_a.h"
-
-/*========= -prototypes for internal functions ========= */
-
-static int qh_compare_facetarea(const void *p1, const void *p2);
-static int qh_compare_facetmerge(const void *p1, const void *p2);
-static int qh_compare_facetvisit(const void *p1, const void *p2);
-int qh_compare_vertexpoint(const void *p1, const void *p2); /* not used */
-
-/*========= -functions in alphabetical order after qh_produce_output()  =====*/
-
-/*---------------------------------
-  
-  qh_produce_output()
-    prints out the result of qhull in desired format
-    if qh.GETarea
-      computes and prints area and volume
-    qh.PRINTout[] is an array of output formats
-
-  notes:
-    prints output in qh.PRINTout order
-*/
-void qh_produce_output(void) {
-  int i, tempsize= qh_setsize ((setT*)qhmem.tempstack), d_1;
-
-  if (qh VORONOI) {
-    qh_clearcenters (qh_ASvoronoi);
-    qh_vertexneighbors();
-  }
-  if (qh TRIangulate) {
-    qh_triangulate(); 
-    if (qh VERIFYoutput && !qh CHECKfrequently) 
-      qh_checkpolygon (qh facet_list);
-  }
-  qh_findgood_all (qh facet_list); 
-  if (qh GETarea)
-    qh_getarea(qh facet_list);
-  if (qh KEEParea || qh KEEPmerge || qh KEEPminArea < REALmax/2)
-    qh_markkeep (qh facet_list);
-  if (qh PRINTsummary)
-    qh_printsummary(qh ferr);
-  else if (qh PRINTout[0] == qh_PRINTnone)
-    qh_printsummary(qh fout);
-  for (i= 0; i < qh_PRINTEND; i++)
-    qh_printfacets (qh fout, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
-  qh_allstatistics();
-  if (qh PRINTprecision && !qh MERGING && (qh JOGGLEmax > REALmax/2 || qh RERUN))
-    qh_printstats (qh ferr, qhstat precision, NULL);
-  if (qh VERIFYoutput && (zzval_(Zridge) > 0 || zzval_(Zridgemid) > 0)) 
-    qh_printstats (qh ferr, qhstat vridges, NULL);
-  if (qh PRINTstatistics) {
-    qh_collectstatistics();
-    qh_printstatistics(qh ferr, "");
-    qh_memstatistics (qh ferr);
-    d_1= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;
-    fprintf(qh ferr, "\
-    size in bytes: merge %ld ridge %ld vertex %ld facet %ld\n\
-         normal %d ridge vertices %d facet vertices or neighbors %ld\n",
-	    sizeof(mergeT), sizeof(ridgeT),
-	    sizeof(vertexT), sizeof(facetT),
-	    qh normal_size, d_1, d_1 + SETelemsize);
-  }
-  if (qh_setsize ((setT*)qhmem.tempstack) != tempsize) {
-    fprintf (qh ferr, "qhull internal error (qh_produce_output): temporary sets not empty (%d)\n",
-	     qh_setsize ((setT*)qhmem.tempstack));
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-} /* produce_output */
-
-
-/*---------------------------------
-  
-  dfacet( id )
-    print facet by id, for debugging
-
-*/
-void dfacet (unsigned id) {
-  facetT *facet;
-
-  FORALLfacets {
-    if (facet->id == id) {
-      qh_printfacet (qh fout, facet);
-      break;
-    }
-  }
-} /* dfacet */
-
-
-/*---------------------------------
-  
-  dvertex( id )
-    print vertex by id, for debugging
-*/
-void dvertex (unsigned id) {
-  vertexT *vertex;
-
-  FORALLvertices {
-    if (vertex->id == id) {
-      qh_printvertex (qh fout, vertex);
-      break;
-    }
-  }
-} /* dvertex */
-
-
-/*---------------------------------
-  
-  qh_compare_vertexpoint( p1, p2 )
-    used by qsort() to order vertices by point id 
-*/
-int qh_compare_vertexpoint(const void *p1, const void *p2) {
-  vertexT *a= *((vertexT **)p1), *b= *((vertexT **)p2);
- 
-  return ((qh_pointid(a->point) > qh_pointid(b->point)?1:-1));
-} /* compare_vertexpoint */
-
-/*---------------------------------
-  
-  qh_compare_facetarea( p1, p2 )
-    used by qsort() to order facets by area
-*/
-static int qh_compare_facetarea(const void *p1, const void *p2) {
-  facetT *a= *((facetT **)p1), *b= *((facetT **)p2);
-
-  if (!a->isarea)
-    return -1;
-  if (!b->isarea)
-    return 1; 
-  if (a->f.area > b->f.area)
-    return 1;
-  else if (a->f.area == b->f.area)
-    return 0;
-  return -1;
-} /* compare_facetarea */
-
-/*---------------------------------
-  
-  qh_compare_facetmerge( p1, p2 )
-    used by qsort() to order facets by number of merges
-*/
-static int qh_compare_facetmerge(const void *p1, const void *p2) {
-  facetT *a= *((facetT **)p1), *b= *((facetT **)p2);
- 
-  return (a->nummerge - b->nummerge);
-} /* compare_facetvisit */
-
-/*---------------------------------
-  
-  qh_compare_facetvisit( p1, p2 )
-    used by qsort() to order facets by visit id or id
-*/
-static int qh_compare_facetvisit(const void *p1, const void *p2) {
-  facetT *a= *((facetT **)p1), *b= *((facetT **)p2);
-  int i,j;
-
-  if (!(i= a->visitid))
-    i= - a->id; /* do not convert to int */
-  if (!(j= b->visitid))
-    j= - b->id;
-  return (i - j);
-} /* compare_facetvisit */
-
-/*---------------------------------
-  
-  qh_countfacets( facetlist, facets, printall, 
-          numfacets, numsimplicial, totneighbors, numridges, numcoplanar, numtricoplanars  )
-    count good facets for printing and set visitid
-    if allfacets, ignores qh_skipfacet()
-
-  notes:
-    qh_printsummary and qh_countfacets must match counts
-
-  returns:
-    numfacets, numsimplicial, total neighbors, numridges, coplanars
-    each facet with ->visitid indicating 1-relative position
-      ->visitid==0 indicates not good
-  
-  notes
-    numfacets >= numsimplicial
-    if qh.NEWfacets, 
-      does not count visible facets (matches qh_printafacet)
-
-  design:
-    for all facets on facetlist and in facets set
-      unless facet is skipped or visible (i.e., will be deleted)
-        mark facet->visitid
-        update counts
-*/
-void qh_countfacets (facetT *facetlist, setT *facets, boolT printall,
-    int *numfacetsp, int *numsimplicialp, int *totneighborsp, int *numridgesp, int *numcoplanarsp, int *numtricoplanarsp) {
-  facetT *facet, **facetp;
-  int numfacets= 0, numsimplicial= 0, numridges= 0, totneighbors= 0, numcoplanars= 0, numtricoplanars= 0;
-
-  FORALLfacet_(facetlist) {
-    if ((facet->visible && qh NEWfacets)
-    || (!printall && qh_skipfacet(facet)))
-      facet->visitid= 0;
-    else {
-      facet->visitid= ++numfacets;
-      totneighbors += qh_setsize (facet->neighbors);
-      if (facet->simplicial) {
-        numsimplicial++;
-	if (facet->keepcentrum && facet->tricoplanar)
-	  numtricoplanars++;
-      }else
-        numridges += qh_setsize (facet->ridges);
-      if (facet->coplanarset)
-        numcoplanars += qh_setsize (facet->coplanarset);
-    }
-  }
-  FOREACHfacet_(facets) {
-    if ((facet->visible && qh NEWfacets)
-    || (!printall && qh_skipfacet(facet)))
-      facet->visitid= 0;
-    else {
-      facet->visitid= ++numfacets;
-      totneighbors += qh_setsize (facet->neighbors);
-      if (facet->simplicial){
-        numsimplicial++;
-	if (facet->keepcentrum && facet->tricoplanar)
-	  numtricoplanars++;
-      }else
-        numridges += qh_setsize (facet->ridges);
-      if (facet->coplanarset)
-        numcoplanars += qh_setsize (facet->coplanarset);
-    }
-  }
-  qh visit_id += numfacets+1;
-  *numfacetsp= numfacets;
-  *numsimplicialp= numsimplicial;
-  *totneighborsp= totneighbors;
-  *numridgesp= numridges;
-  *numcoplanarsp= numcoplanars;
-  *numtricoplanarsp= numtricoplanars;
-} /* countfacets */
-
-/*---------------------------------
-  
-  qh_detvnorm( vertex, vertexA, centers, offset )
-    compute separating plane of the Voronoi diagram for a pair of input sites
-    centers= set of facets (i.e., Voronoi vertices)
-      facet->visitid= 0 iff vertex-at-infinity (i.e., unbounded)
-        
-  assumes:
-    qh_ASvoronoi and qh_vertexneighbors() already set
-  
-  returns:
-    norm
-      a pointer into qh.gm_matrix to qh.hull_dim-1 reals
-      copy the data before reusing qh.gm_matrix
-    offset
-      if 'QVn'
-        sign adjusted so that qh.GOODvertexp is inside
-      else
-        sign adjusted so that vertex is inside
-      
-    qh.gm_matrix= simplex of points from centers relative to first center
-    
-  notes:
-    in io.c so that code for 'v Tv' can be removed by removing io.c
-    returns pointer into qh.gm_matrix to avoid tracking of temporary memory
-  
-  design:
-    determine midpoint of input sites
-    build points as the set of Voronoi vertices
-    select a simplex from points (if necessary)
-      include midpoint if the Voronoi region is unbounded
-    relocate the first vertex of the simplex to the origin
-    compute the normalized hyperplane through the simplex
-    orient the hyperplane toward 'QVn' or 'vertex'
-    if 'Tv' or 'Ts'
-      if bounded
-        test that hyperplane is the perpendicular bisector of the input sites
-      test that Voronoi vertices not in the simplex are still on the hyperplane
-    free up temporary memory
-*/
-pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp) {
-  facetT *facet, **facetp;
-  int  i, k, pointid, pointidA, point_i, point_n;
-  setT *simplex= NULL;
-  pointT *point, **pointp, *point0, *midpoint, *normal, *inpoint;
-  coordT *coord, *gmcoord, *normalp;
-  setT *points= qh_settemp (qh TEMPsize);
-  boolT nearzero= False;
-  boolT unbounded= False;
-  int numcenters= 0;
-  int dim= qh hull_dim - 1;
-  realT dist, offset, angle, zero= 0.0;
-
-  midpoint= qh gm_matrix + qh hull_dim * qh hull_dim;  /* last row */
-  for (k= 0; k < dim; k++)
-    midpoint[k]= (vertex->point[k] + vertexA->point[k])/2;
-  FOREACHfacet_(centers) {
-    numcenters++;
-    if (!facet->visitid)
-      unbounded= True;
-    else {
-      if (!facet->center)
-        facet->center= qh_facetcenter (facet->vertices);
-      qh_setappend (&points, facet->center);
-    }
-  }
-  if (numcenters > dim) {
-    simplex= qh_settemp (qh TEMPsize);
-    qh_setappend (&simplex, vertex->point);
-    if (unbounded)
-      qh_setappend (&simplex, midpoint);
-    qh_maxsimplex (dim, points, NULL, 0, &simplex);
-    qh_setdelnth (simplex, 0);
-  }else if (numcenters == dim) {
-    if (unbounded)
-      qh_setappend (&points, midpoint);
-    simplex= points; 
-  }else {
-    fprintf(qh ferr, "qh_detvnorm: too few points (%d) to compute separating plane\n", numcenters);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  i= 0;
-  gmcoord= qh gm_matrix;
-  point0= SETfirstt_(simplex, pointT);
-  FOREACHpoint_(simplex) {
-    if (qh IStracing >= 4)
-      qh_printmatrix(qh ferr, "qh_detvnorm: Voronoi vertex or midpoint", 
-                              &point, 1, dim);
-    if (point != point0) {
-      qh gm_row[i++]= gmcoord;
-      coord= point0;
-      for (k= dim; k--; )
-        *(gmcoord++)= *point++ - *coord++;
-    }
-  }
-  qh gm_row[i]= gmcoord;  /* does not overlap midpoint, may be used later for qh_areasimplex */
-  normal= gmcoord;
-  qh_sethyperplane_gauss (dim, qh gm_row, point0, True,
-           	normal, &offset, &nearzero);
-  if (qh GOODvertexp == vertexA->point)
-    inpoint= vertexA->point;
-  else
-    inpoint= vertex->point;
-  zinc_(Zdistio);
-  dist= qh_distnorm (dim, inpoint, normal, &offset);
-  if (dist > 0) {
-    offset= -offset;
-    normalp= normal;
-    for (k= dim; k--; ) {
-      *normalp= -(*normalp);
-      normalp++;
-    }
-  }
-  if (qh VERIFYoutput || qh PRINTstatistics) {
-    pointid= qh_pointid (vertex->point);
-    pointidA= qh_pointid (vertexA->point);
-    if (!unbounded) {
-      zinc_(Zdiststat);
-      dist= qh_distnorm (dim, midpoint, normal, &offset);
-      if (dist < 0)
-        dist= -dist;
-      zzinc_(Zridgemid);
-      wwmax_(Wridgemidmax, dist);
-      wwadd_(Wridgemid, dist);
-      trace4((qh ferr, "qh_detvnorm: points %d %d midpoint dist %2.2g\n",
-                 pointid, pointidA, dist));
-      for (k= 0; k < dim; k++) 
-        midpoint[k]= vertexA->point[k] - vertex->point[k];  /* overwrites midpoint! */
-      qh_normalize (midpoint, dim, False);
-      angle= qh_distnorm (dim, midpoint, normal, &zero); /* qh_detangle uses dim+1 */
-      if (angle < 0.0)
-	angle= angle + 1.0;
-      else
-	angle= angle - 1.0;
-      if (angle < 0.0)
-	angle -= angle;
-      trace4((qh ferr, "qh_detvnorm: points %d %d angle %2.2g nearzero %d\n",
-                 pointid, pointidA, angle, nearzero));
-      if (nearzero) {
-        zzinc_(Zridge0);
-        wwmax_(Wridge0max, angle);
-        wwadd_(Wridge0, angle);
-      }else {
-        zzinc_(Zridgeok)
-        wwmax_(Wridgeokmax, angle);
-        wwadd_(Wridgeok, angle);
-      }
-    }
-    if (simplex != points) {
-      FOREACHpoint_i_(points) {
-        if (!qh_setin (simplex, point)) {
-          facet= SETelemt_(centers, point_i, facetT);
-	  zinc_(Zdiststat);
-  	  dist= qh_distnorm (dim, point, normal, &offset);
-          if (dist < 0)
-            dist= -dist;
-	  zzinc_(Zridge);
-          wwmax_(Wridgemax, dist);
-          wwadd_(Wridge, dist);
-          trace4((qh ferr, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n",
-                             pointid, pointidA, facet->visitid, dist));
-        }
-      }
-    }
-  }
-  *offsetp= offset;
-  if (simplex != points)
-    qh_settempfree (&simplex);
-  qh_settempfree (&points);
-  return normal;
-} /* detvnorm */
-
-/*---------------------------------
-
-  qh_detvridge( vertexA )
-    determine Voronoi ridge from 'seen' neighbors of vertexA
-    include one vertex-at-infinite if an !neighbor->visitid
-
-  returns:
-    temporary set of centers (facets, i.e., Voronoi vertices)
-    sorted by center id
-*/
-setT *qh_detvridge (vertexT *vertex) {
-  setT *centers= qh_settemp (qh TEMPsize);
-  setT *tricenters= qh_settemp (qh TEMPsize);
-  facetT *neighbor, **neighborp;
-  boolT firstinf= True;
-  
-  FOREACHneighbor_(vertex) {
-    if (neighbor->seen) {
-      if (neighbor->visitid) {
-	if (!neighbor->tricoplanar || qh_setunique (&tricenters, neighbor->center)) 
-	  qh_setappend (¢ers, neighbor);
-      }else if (firstinf) {
-        firstinf= False;
-        qh_setappend (¢ers, neighbor);
-      }
-    }
-  }
-  qsort (SETaddr_(centers, facetT), qh_setsize (centers),
-             sizeof (facetT *), qh_compare_facetvisit);
-  qh_settempfree (&tricenters);
-  return centers;
-} /* detvridge */      
-
-/*---------------------------------
-
-  qh_detvridge3( atvertex, vertex )
-    determine 3-d Voronoi ridge from 'seen' neighbors of atvertex and vertex
-    include one vertex-at-infinite for !neighbor->visitid
-    assumes all facet->seen2= True
-
-  returns:
-    temporary set of centers (facets, i.e., Voronoi vertices)
-    listed in adjacency order (not oriented)
-    all facet->seen2= True
-
-  design:
-    mark all neighbors of atvertex
-    for each adjacent neighbor of both atvertex and vertex
-      if neighbor selected
-        add neighbor to set of Voronoi vertices
-*/
-setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex) {
-  setT *centers= qh_settemp (qh TEMPsize);
-  setT *tricenters= qh_settemp (qh TEMPsize);
-  facetT *neighbor, **neighborp, *facet= NULL;
-  boolT firstinf= True;
-  
-  FOREACHneighbor_(atvertex)
-    neighbor->seen2= False;
-  FOREACHneighbor_(vertex) {
-    if (!neighbor->seen2) {
-      facet= neighbor;
-      break;
-    }
-  }
-  while (facet) { 
-    facet->seen2= True;
-    if (neighbor->seen) {
-      if (facet->visitid) {
-	if (!facet->tricoplanar || qh_setunique (&tricenters, facet->center)) 
-	  qh_setappend (¢ers, facet);
-      }else if (firstinf) {
-        firstinf= False;
-        qh_setappend (¢ers, facet);
-      }
-    }
-    FOREACHneighbor_(facet) {
-      if (!neighbor->seen2) {
-	if (qh_setin (vertex->neighbors, neighbor))
-          break;
-	else
-	  neighbor->seen2= True;
-      }
-    }
-    facet= neighbor;
-  }
-  if (qh CHECKfrequently) {
-    FOREACHneighbor_(vertex) {
-      if (!neighbor->seen2) {
-	fprintf (stderr, "qh_detvridge3: neigbors of vertex p%d are not connected at facet %d\n",
-	         qh_pointid (vertex->point), neighbor->id);
-	qh_errexit (qh_ERRqhull, neighbor, NULL);
-      }
-    }
-  }
-  FOREACHneighbor_(atvertex) 
-    neighbor->seen2= True;
-  qh_settempfree (&tricenters);
-  return centers;
-} /* detvridge3 */      
-
-/*---------------------------------
-  
-  qh_eachvoronoi( fp, printvridge, vertex, visitall, innerouter, inorder )
-    if visitall,
-      visit all Voronoi ridges for vertex (i.e., an input site)
-    else
-      visit all unvisited Voronoi ridges for vertex
-      all vertex->seen= False if unvisited
-    assumes
-      all facet->seen= False
-      all facet->seen2= True (for qh_detvridge3)
-      all facet->visitid == 0 if vertex_at_infinity
-                         == index of Voronoi vertex 
-                         >= qh.num_facets if ignored
-    innerouter:
-      qh_RIDGEall--  both inner (bounded) and outer (unbounded) ridges
-      qh_RIDGEinner- only inner
-      qh_RIDGEouter- only outer
-      
-    if inorder
-      orders vertices for 3-d Voronoi diagrams
-  
-  returns:
-    number of visited ridges (does not include previously visited ridges)
-    
-    if printvridge,
-      calls printvridge( fp, vertex, vertexA, centers)
-        fp== any pointer (assumes FILE*)
-        vertex,vertexA= pair of input sites that define a Voronoi ridge
-        centers= set of facets (i.e., Voronoi vertices)
-                 ->visitid == index or 0 if vertex_at_infinity
-                 ordered for 3-d Voronoi diagram
-  notes:
-    uses qh.vertex_visit
-  
-  see:
-    qh_eachvoronoi_all()
-  
-  design:
-    mark selected neighbors of atvertex
-    for each selected neighbor (either Voronoi vertex or vertex-at-infinity)
-      for each unvisited vertex 
-        if atvertex and vertex share more than d-1 neighbors
-          bump totalcount
-          if printvridge defined
-            build the set of shared neighbors (i.e., Voronoi vertices)
-            call printvridge
-*/
-int qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder) {
-  boolT unbounded;
-  int count;
-  facetT *neighbor, **neighborp, *neighborA, **neighborAp;
-  setT *centers;
-  setT *tricenters= qh_settemp (qh TEMPsize);
-
-  vertexT *vertex, **vertexp;
-  boolT firstinf;
-  unsigned int numfacets= (unsigned int)qh num_facets;
-  int totridges= 0;
-
-  qh vertex_visit++;
-  atvertex->seen= True;
-  if (visitall) {
-    FORALLvertices 
-      vertex->seen= False;
-  }
-  FOREACHneighbor_(atvertex) {
-    if (neighbor->visitid < numfacets) 
-      neighbor->seen= True;
-  }
-  FOREACHneighbor_(atvertex) {
-    if (neighbor->seen) {
-      FOREACHvertex_(neighbor->vertices) {
-        if (vertex->visitid != qh vertex_visit && !vertex->seen) {
-	  vertex->visitid= qh vertex_visit;
-          count= 0;
-          firstinf= True;
-	  qh_settruncate (tricenters, 0);
-          FOREACHneighborA_(vertex) {
-            if (neighborA->seen) {
-	      if (neighborA->visitid) {
-		if (!neighborA->tricoplanar || qh_setunique (&tricenters, neighborA->center))
-		  count++;
-              }else if (firstinf) {
-                count++;
-                firstinf= False;
-	      }
-	    }
-          }
-          if (count >= qh hull_dim - 1) {  /* e.g., 3 for 3-d Voronoi */
-            if (firstinf) {
-              if (innerouter == qh_RIDGEouter)
-                continue;
-              unbounded= False;
-            }else {
-              if (innerouter == qh_RIDGEinner)
-                continue;
-              unbounded= True;
-            }
-            totridges++;
-            trace4((qh ferr, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n",
-                  count, qh_pointid (atvertex->point), qh_pointid (vertex->point)));
-            if (printvridge) { 
-	      if (inorder && qh hull_dim == 3+1) /* 3-d Voronoi diagram */
-                centers= qh_detvridge3 (atvertex, vertex);
-	      else
-                centers= qh_detvridge (vertex);
-              (*printvridge) (fp, atvertex, vertex, centers, unbounded);
-              qh_settempfree (¢ers);
-            }
-          }
-        }
-      }
-    }
-  }
-  FOREACHneighbor_(atvertex) 
-    neighbor->seen= False;
-  qh_settempfree (&tricenters);
-  return totridges;
-} /* eachvoronoi */
-  
-
-/*---------------------------------
-  
-  qh_eachvoronoi_all( fp, printvridge, isupper, innerouter, inorder )
-    visit all Voronoi ridges
-    
-    innerouter:
-      see qh_eachvoronoi()
-      
-    if inorder
-      orders vertices for 3-d Voronoi diagrams
-    
-  returns
-    total number of ridges 
-
-    if isupper == facet->upperdelaunay  (i.e., a Vornoi vertex)
-      facet->visitid= Voronoi vertex index (same as 'o' format)
-    else 
-      facet->visitid= 0
-
-    if printvridge,
-      calls printvridge( fp, vertex, vertexA, centers)
-      [see qh_eachvoronoi]
-      
-  notes:
-    Not used for qhull.exe
-    same effect as qh_printvdiagram but ridges not sorted by point id
-*/
-int qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder) {
-  facetT *facet;
-  vertexT *vertex;
-  int numcenters= 1;  /* vertex 0 is vertex-at-infinity */
-  int totridges= 0;
-
-  qh_clearcenters (qh_ASvoronoi);
-  qh_vertexneighbors();
-  maximize_(qh visit_id, (unsigned) qh num_facets);
-  FORALLfacets {
-    facet->visitid= 0;
-    facet->seen= False;
-    facet->seen2= True;
-  }
-  FORALLfacets {
-    if (facet->upperdelaunay == isupper)
-      facet->visitid= numcenters++;
-  }
-  FORALLvertices 
-    vertex->seen= False;
-  FORALLvertices {
-    if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex)
-      continue;
-    totridges += qh_eachvoronoi (fp, printvridge, vertex, 
-                   !qh_ALL, innerouter, inorder);
-  }
-  return totridges;
-} /* eachvoronoi_all */
-      
-/*---------------------------------
-  
-  qh_facet2point( facet, point0, point1, mindist )
-    return two projected temporary vertices for a 2-d facet
-    may be non-simplicial
-
-  returns:
-    point0 and point1 oriented and projected to the facet
-    returns mindist (maximum distance below plane)
-*/
-void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist) {
-  vertexT *vertex0, *vertex1;
-  realT dist;
-  
-  if (facet->toporient ^ qh_ORIENTclock) {
-    vertex0= SETfirstt_(facet->vertices, vertexT);
-    vertex1= SETsecondt_(facet->vertices, vertexT);
-  }else {
-    vertex1= SETfirstt_(facet->vertices, vertexT);
-    vertex0= SETsecondt_(facet->vertices, vertexT);
-  }
-  zadd_(Zdistio, 2);
-  qh_distplane(vertex0->point, facet, &dist);
-  *mindist= dist;
-  *point0= qh_projectpoint(vertex0->point, facet, dist);
-  qh_distplane(vertex1->point, facet, &dist);
-  minimize_(*mindist, dist);		
-  *point1= qh_projectpoint(vertex1->point, facet, dist);
-} /* facet2point */
-
-
-/*---------------------------------
-  
-  qh_facetvertices( facetlist, facets, allfacets )
-    returns temporary set of vertices in a set and/or list of facets
-    if allfacets, ignores qh_skipfacet()
-
-  returns:
-    vertices with qh.vertex_visit
-    
-  notes:
-    optimized for allfacets of facet_list
-
-  design:
-    if allfacets of facet_list
-      create vertex set from vertex_list
-    else
-      for each selected facet in facets or facetlist
-        append unvisited vertices to vertex set
-*/
-setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets) {
-  setT *vertices;
-  facetT *facet, **facetp;
-  vertexT *vertex, **vertexp;
-
-  qh vertex_visit++;
-  if (facetlist == qh facet_list && allfacets && !facets) {
-    vertices= qh_settemp (qh num_vertices);
-    FORALLvertices {
-      vertex->visitid= qh vertex_visit; 
-      qh_setappend (&vertices, vertex);
-    }
-  }else {
-    vertices= qh_settemp (qh TEMPsize);
-    FORALLfacet_(facetlist) {
-      if (!allfacets && qh_skipfacet (facet))
-        continue;
-      FOREACHvertex_(facet->vertices) {
-        if (vertex->visitid != qh vertex_visit) {
-          vertex->visitid= qh vertex_visit;
-          qh_setappend (&vertices, vertex);
-        }
-      }
-    }
-  }
-  FOREACHfacet_(facets) {
-    if (!allfacets && qh_skipfacet (facet))
-      continue;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        vertex->visitid= qh vertex_visit;
-        qh_setappend (&vertices, vertex);
-      }
-    }
-  }
-  return vertices;
-} /* facetvertices */
-
-/*---------------------------------
-  
-  qh_geomplanes( facet, outerplane, innerplane )
-    return outer and inner planes for Geomview 
-    qh.PRINTradius is size of vertices and points (includes qh.JOGGLEmax)
-
-  notes:
-    assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
-*/
-void qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane) {
-  realT radius;
-
-  if (qh MERGING || qh JOGGLEmax < REALmax/2) {
-    qh_outerinner (facet, outerplane, innerplane);
-    radius= qh PRINTradius;
-    if (qh JOGGLEmax < REALmax/2)
-      radius -= qh JOGGLEmax * sqrt (qh hull_dim);  /* already accounted for in qh_outerinner() */
-    *outerplane += radius;
-    *innerplane -= radius;
-    if (qh PRINTcoplanar || qh PRINTspheres) {
-      *outerplane += qh MAXabs_coord * qh_GEOMepsilon;
-      *innerplane -= qh MAXabs_coord * qh_GEOMepsilon;
-    }
-  }else 
-    *innerplane= *outerplane= 0;
-} /* geomplanes */
-
-
-/*---------------------------------
-  
-  qh_markkeep( facetlist )
-    mark good facets that meet qh.KEEParea, qh.KEEPmerge, and qh.KEEPminArea
-    ignores visible facets (not part of convex hull)
-
-  returns:
-    may clear facet->good
-    recomputes qh.num_good
-
-  design:
-    get set of good facets
-    if qh.KEEParea
-      sort facets by area
-      clear facet->good for all but n largest facets
-    if qh.KEEPmerge
-      sort facets by merge count
-      clear facet->good for all but n most merged facets
-    if qh.KEEPminarea
-      clear facet->good if area too small
-    update qh.num_good    
-*/
-void qh_markkeep (facetT *facetlist) {
-  facetT *facet, **facetp;
-  setT *facets= qh_settemp (qh num_facets);
-  int size, count;
-
-  trace2((qh ferr, "qh_markkeep: only keep %d largest and/or %d most merged facets and/or min area %.2g\n",
-          qh KEEParea, qh KEEPmerge, qh KEEPminArea));
-  FORALLfacet_(facetlist) {
-    if (!facet->visible && facet->good)
-      qh_setappend (&facets, facet);
-  }
-  size= qh_setsize (facets);
-  if (qh KEEParea) {
-    qsort (SETaddr_(facets, facetT), size,
-             sizeof (facetT *), qh_compare_facetarea);
-    if ((count= size - qh KEEParea) > 0) {
-      FOREACHfacet_(facets) {
-        facet->good= False;
-        if (--count == 0)
-          break;
-      }
-    }
-  }
-  if (qh KEEPmerge) {
-    qsort (SETaddr_(facets, facetT), size,
-             sizeof (facetT *), qh_compare_facetmerge);
-    if ((count= size - qh KEEPmerge) > 0) {
-      FOREACHfacet_(facets) {
-        facet->good= False;
-        if (--count == 0)
-          break;
-      }
-    }
-  }
-  if (qh KEEPminArea < REALmax/2) {
-    FOREACHfacet_(facets) {
-      if (!facet->isarea || facet->f.area < qh KEEPminArea)
-	facet->good= False;
-    }
-  }
-  qh_settempfree (&facets);
-  count= 0;
-  FORALLfacet_(facetlist) {
-    if (facet->good)
-      count++;
-  }
-  qh num_good= count;
-} /* markkeep */
-
-
-/*---------------------------------
-  
-  qh_markvoronoi( facetlist, facets, printall, islower, numcenters )
-    mark voronoi vertices for printing by site pairs
-  
-  returns:
-    temporary set of vertices indexed by pointid
-    islower set if printing lower hull (i.e., at least one facet is lower hull)
-    numcenters= total number of Voronoi vertices
-    bumps qh.printoutnum for vertex-at-infinity
-    clears all facet->seen and sets facet->seen2
-    
-    if selected
-      facet->visitid= Voronoi vertex id
-    else if upper hull (or 'Qu' and lower hull)
-      facet->visitid= 0
-    else
-      facet->visitid >= qh num_facets
-  
-  notes:
-    ignores qh.ATinfinity, if defined
-*/
-setT *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp) {
-  int numcenters=0;
-  facetT *facet, **facetp;
-  setT *vertices;
-  boolT islower= False;
-
-  qh printoutnum++;
-  qh_clearcenters (qh_ASvoronoi);  /* in case, qh_printvdiagram2 called by user */
-  qh_vertexneighbors();
-  vertices= qh_pointvertex();
-  if (qh ATinfinity) 
-    SETelem_(vertices, qh num_points-1)= NULL;
-  qh visit_id++;
-  maximize_(qh visit_id, (unsigned) qh num_facets);
-  FORALLfacet_(facetlist) { 
-    if (printall || !qh_skipfacet (facet)) {
-      if (!facet->upperdelaunay) {
-        islower= True;
-	break;
-      }
-    }
-  }
-  FOREACHfacet_(facets) {
-    if (printall || !qh_skipfacet (facet)) {
-      if (!facet->upperdelaunay) {
-        islower= True;
-	break;
-      }
-    }
-  }
-  FORALLfacets {
-    if (facet->normal && (facet->upperdelaunay == islower))
-      facet->visitid= 0;  /* facetlist or facets may overwrite */
-    else
-      facet->visitid= qh visit_id;
-    facet->seen= False;
-    facet->seen2= True;
-  }
-  numcenters++;  /* qh_INFINITE */
-  FORALLfacet_(facetlist) {
-    if (printall || !qh_skipfacet (facet))
-      facet->visitid= numcenters++;
-  }
-  FOREACHfacet_(facets) {
-    if (printall || !qh_skipfacet (facet))
-      facet->visitid= numcenters++;  
-  }
-  *islowerp= islower;
-  *numcentersp= numcenters;
-  trace2((qh ferr, "qh_markvoronoi: islower %d numcenters %d\n", islower, numcenters));
-  return vertices;
-} /* markvoronoi */
-
-/*---------------------------------
-  
-  qh_order_vertexneighbors( vertex )
-    order facet neighbors of a 2-d or 3-d vertex by adjacency
-
-  notes:
-    does not orient the neighbors
-
-  design:
-    initialize a new neighbor set with the first facet in vertex->neighbors
-    while vertex->neighbors non-empty
-      select next neighbor in the previous facet's neighbor set
-    set vertex->neighbors to the new neighbor set
-*/
-void qh_order_vertexneighbors(vertexT *vertex) {
-  setT *newset;
-  facetT *facet, *neighbor, **neighborp;
-
-  trace4((qh ferr, "qh_order_vertexneighbors: order neighbors of v%d for 3-d\n", vertex->id));
-  newset= qh_settemp (qh_setsize (vertex->neighbors));
-  facet= (facetT*)qh_setdellast (vertex->neighbors);
-  qh_setappend (&newset, facet);
-  while (qh_setsize (vertex->neighbors)) {
-    FOREACHneighbor_(vertex) {
-      if (qh_setin (facet->neighbors, neighbor)) {
-        qh_setdel(vertex->neighbors, neighbor);
-        qh_setappend (&newset, neighbor);
-        facet= neighbor;
-        break;
-      }
-    }
-    if (!neighbor) {
-      fprintf (qh ferr, "qhull internal error (qh_order_vertexneighbors): no neighbor of v%d for f%d\n",
-        vertex->id, facet->id);
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-  }
-  qh_setfree (&vertex->neighbors);
-  qh_settemppop ();
-  vertex->neighbors= newset;
-} /* order_vertexneighbors */
-
-/*---------------------------------
-  
-  qh_printafacet( fp, format, facet, printall )
-    print facet to fp in given output format (see qh.PRINTout)
-
-  returns:
-    nop if !printall and qh_skipfacet()
-    nop if visible facet and NEWfacets and format != PRINTfacets
-    must match qh_countfacets
-
-  notes
-    preserves qh.visit_id
-    facet->normal may be null if PREmerge/MERGEexact and STOPcone before merge
-
-  see
-    qh_printbegin() and qh_printend()
-
-  design:
-    test for printing facet
-    call appropriate routine for format
-    or output results directly
-*/
-void qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall) {
-  realT color[4], offset, dist, outerplane, innerplane;
-  boolT zerodiv;
-  coordT *point, *normp, *coordp, **pointp, *feasiblep;
-  int k;
-  vertexT *vertex, **vertexp;
-  facetT *neighbor, **neighborp;
-
-  if (!printall && qh_skipfacet (facet))
-    return;
-  if (facet->visible && qh NEWfacets && format != qh_PRINTfacets)
-    return;
-  qh printoutnum++;
-  switch (format) {
-  case qh_PRINTarea:
-    if (facet->isarea) {
-      fprintf (fp, qh_REAL_1, facet->f.area);
-      fprintf (fp, "\n");
-    }else
-      fprintf (fp, "0\n");
-    break;
-  case qh_PRINTcoplanars:
-    fprintf (fp, "%d", qh_setsize (facet->coplanarset));
-    FOREACHpoint_(facet->coplanarset)
-      fprintf (fp, " %d", qh_pointid (point));
-    fprintf (fp, "\n");
-    break;
-  case qh_PRINTcentrums:
-    qh_printcenter (fp, format, NULL, facet);
-    break;
-  case qh_PRINTfacets:
-    qh_printfacet (fp, facet);
-    break;
-  case qh_PRINTfacets_xridge:
-    qh_printfacetheader (fp, facet);
-    break;
-  case qh_PRINTgeom:  /* either 2 , 3, or 4-d by qh_printbegin */
-    if (!facet->normal)
-      break;
-    for (k= qh hull_dim; k--; ) {
-      color[k]= (facet->normal[k]+1.0)/2.0;
-      maximize_(color[k], -1.0);
-      minimize_(color[k], +1.0);
-    }
-    qh_projectdim3 (color, color);
-    if (qh PRINTdim != qh hull_dim)
-      qh_normalize2 (color, 3, True, NULL, NULL);
-    if (qh hull_dim <= 2)
-      qh_printfacet2geom (fp, facet, color);
-    else if (qh hull_dim == 3) {
-      if (facet->simplicial)
-        qh_printfacet3geom_simplicial (fp, facet, color);
-      else
-        qh_printfacet3geom_nonsimplicial (fp, facet, color);
-    }else {
-      if (facet->simplicial)
-        qh_printfacet4geom_simplicial (fp, facet, color);
-      else
-        qh_printfacet4geom_nonsimplicial (fp, facet, color);
-    }
-    break;
-  case qh_PRINTids:
-    fprintf (fp, "%d\n", facet->id);
-    break;
-  case qh_PRINTincidences:
-  case qh_PRINToff:
-  case qh_PRINTtriangles:
-    if (qh hull_dim == 3 && format != qh_PRINTtriangles) 
-      qh_printfacet3vertex (fp, facet, format);
-    else if (facet->simplicial || qh hull_dim == 2 || format == qh_PRINToff)
-      qh_printfacetNvertex_simplicial (fp, facet, format);
-    else
-      qh_printfacetNvertex_nonsimplicial (fp, facet, qh printoutvar++, format);
-    break;
-  case qh_PRINTinner:
-    qh_outerinner (facet, NULL, &innerplane);
-    offset= facet->offset - innerplane;
-    goto LABELprintnorm;
-    break; /* prevent warning */
-  case qh_PRINTmerges:
-    fprintf (fp, "%d\n", facet->nummerge);
-    break;
-  case qh_PRINTnormals:
-    offset= facet->offset;
-    goto LABELprintnorm;
-    break; /* prevent warning */
-  case qh_PRINTouter:
-    qh_outerinner (facet, &outerplane, NULL);
-    offset= facet->offset - outerplane;
-  LABELprintnorm:
-    if (!facet->normal) {
-      fprintf (fp, "no normal for facet f%d\n", facet->id);
-      break;
-    }
-    if (qh CDDoutput) {
-      fprintf (fp, qh_REAL_1, -offset);
-      for (k=0; k < qh hull_dim; k++) 
-	fprintf (fp, qh_REAL_1, -facet->normal[k]);
-    }else {
-      for (k=0; k < qh hull_dim; k++) 
-	fprintf (fp, qh_REAL_1, facet->normal[k]);
-      fprintf (fp, qh_REAL_1, offset);
-    }
-    fprintf (fp, "\n");
-    break;
-  case qh_PRINTmathematica:  /* either 2 or 3-d by qh_printbegin */
-    if (qh hull_dim == 2)
-      qh_printfacet2math (fp, facet, qh printoutvar++);
-    else 
-      qh_printfacet3math (fp, facet, qh printoutvar++);
-    break;
-  case qh_PRINTneighbors:
-    fprintf (fp, "%d", qh_setsize (facet->neighbors));
-    FOREACHneighbor_(facet)
-      fprintf (fp, " %d", 
-	       neighbor->visitid ? neighbor->visitid - 1: - neighbor->id);
-    fprintf (fp, "\n");
-    break;
-  case qh_PRINTpointintersect:
-    if (!qh feasible_point) {
-      fprintf (fp, "qhull input error (qh_printafacet): option 'Fp' needs qh feasible_point\n");
-      qh_errexit( qh_ERRinput, NULL, NULL);
-    }
-    if (facet->offset > 0)
-      goto LABELprintinfinite;
-    point= coordp= (coordT*)qh_memalloc (qh normal_size);
-    normp= facet->normal;
-    feasiblep= qh feasible_point;
-    if (facet->offset < -qh MINdenom) {
-      for (k= qh hull_dim; k--; )
-        *(coordp++)= (*(normp++) / - facet->offset) + *(feasiblep++);
-    }else {
-      for (k= qh hull_dim; k--; ) {
-        *(coordp++)= qh_divzero (*(normp++), facet->offset, qh MINdenom_1,
-				 &zerodiv) + *(feasiblep++);
-        if (zerodiv) {
-          qh_memfree (point, qh normal_size);
-          goto LABELprintinfinite;
-        }
-      }
-    }
-    qh_printpoint (fp, NULL, point);
-    qh_memfree (point, qh normal_size);
-    break;
-  LABELprintinfinite:
-    for (k= qh hull_dim; k--; )
-      fprintf (fp, qh_REAL_1, qh_INFINITE);
-    fprintf (fp, "\n");   
-    break;
-  case qh_PRINTpointnearest:
-    FOREACHpoint_(facet->coplanarset) {
-      int id, id2;
-      vertex= qh_nearvertex (facet, point, &dist);
-      id= qh_pointid (vertex->point);
-      id2= qh_pointid (point);
-      fprintf (fp, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist);
-    }
-    break;
-  case qh_PRINTpoints:  /* VORONOI only by qh_printbegin */
-    if (qh CDDoutput)
-      fprintf (fp, "1 ");
-    qh_printcenter (fp, format, NULL, facet);
-    break;
-  case qh_PRINTvertices:
-    fprintf (fp, "%d", qh_setsize (facet->vertices));
-    FOREACHvertex_(facet->vertices)
-      fprintf (fp, " %d", qh_pointid (vertex->point));
-    fprintf (fp, "\n");
-    break;
-  }
-} /* printafacet */
-
-/*---------------------------------
-  
-  qh_printbegin(  )
-    prints header for all output formats
-
-  returns:
-    checks for valid format
-  
-  notes:
-    uses qh.visit_id for 3/4off
-    changes qh.interior_point if printing centrums
-    qh_countfacets clears facet->visitid for non-good facets
-    
-  see
-    qh_printend() and qh_printafacet()
-    
-  design:
-    count facets and related statistics
-    print header for format
-*/
-void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
-  int i, num;
-  facetT *facet, **facetp;
-  vertexT *vertex, **vertexp;
-  setT *vertices;
-  pointT *point, **pointp, *pointtemp;
-
-  qh printoutnum= 0;
-  qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
-  switch (format) {
-  case qh_PRINTnone:
-    break;
-  case qh_PRINTarea:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTcoplanars:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTcentrums:
-    if (qh CENTERtype == qh_ASnone)
-      qh_clearcenters (qh_AScentrum);
-    fprintf (fp, "%d\n%d\n", qh hull_dim, numfacets);
-    break;
-  case qh_PRINTfacets:
-  case qh_PRINTfacets_xridge:
-    if (facetlist)
-      qh_printvertexlist (fp, "Vertices and facets:\n", facetlist, facets, printall);
-    break;
-  case qh_PRINTgeom: 
-    if (qh hull_dim > 4)  /* qh_initqhull_globals also checks */
-      goto LABELnoformat;
-    if (qh VORONOI && qh hull_dim > 3)  /* PRINTdim == DROPdim == hull_dim-1 */
-      goto LABELnoformat;
-    if (qh hull_dim == 2 && (qh PRINTridges || qh DOintersections))
-      fprintf (qh ferr, "qhull warning: output for ridges and intersections not implemented in 2-d\n");
-    if (qh hull_dim == 4 && (qh PRINTinner || qh PRINTouter ||
-			     (qh PRINTdim == 4 && qh PRINTcentrums)))
-      fprintf (qh ferr, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n");
-    if (qh PRINTdim == 4 && (qh PRINTspheres))
-      fprintf (qh ferr, "qhull warning: output for vertices not implemented in 4-d\n");
-    if (qh PRINTdim == 4 && qh DOintersections && qh PRINTnoplanes)
-      fprintf (qh ferr, "qhull warning: 'Gnh' generates no output in 4-d\n");
-    if (qh PRINTdim == 2) {
-      fprintf(fp, "{appearance {linewidth 3} LIST # %s | %s\n",
-	      qh rbox_command, qh qhull_command);
-    }else if (qh PRINTdim == 3) {
-      fprintf(fp, "{appearance {+edge -evert linewidth 2} LIST # %s | %s\n",
-	      qh rbox_command, qh qhull_command);
-    }else if (qh PRINTdim == 4) {
-      qh visit_id++;
-      num= 0;
-      FORALLfacet_(facetlist)    /* get number of ridges to be printed */
-        qh_printend4geom (NULL, facet, &num, printall);
-      FOREACHfacet_(facets)
-        qh_printend4geom (NULL, facet, &num, printall);
-      qh ridgeoutnum= num;
-      qh printoutvar= 0;  /* counts number of ridges in output */
-      fprintf (fp, "LIST # %s | %s\n", qh rbox_command, qh qhull_command);
-    }
-    if (qh PRINTdots) {
-      qh printoutnum++;
-      num= qh num_points + qh_setsize (qh other_points);
-      if (qh DELAUNAY && qh ATinfinity)
-	num--;
-      if (qh PRINTdim == 4)
-        fprintf (fp, "4VECT %d %d 1\n", num, num);
-      else
-	fprintf (fp, "VECT %d %d 1\n", num, num);
-      for (i= num; i--; ) {
-        if (i % 20 == 0)
-          fprintf (fp, "\n");
-	fprintf (fp, "1 ");
-      }
-      fprintf (fp, "# 1 point per line\n1 ");
-      for (i= num-1; i--; ) {
-        if (i % 20 == 0)
-          fprintf (fp, "\n");
-	fprintf (fp, "0 ");
-      }
-      fprintf (fp, "# 1 color for all\n");
-      FORALLpoints {
-        if (!qh DELAUNAY || !qh ATinfinity || qh_pointid(point) != qh num_points-1) {
-	  if (qh PRINTdim == 4)
-	    qh_printpoint (fp, NULL, point);
-	  else
-	    qh_printpoint3 (fp, point);
-	}
-      }
-      FOREACHpoint_(qh other_points) {
-	if (qh PRINTdim == 4)
-	  qh_printpoint (fp, NULL, point);
-	else
-	  qh_printpoint3 (fp, point);
-      }
-      fprintf (fp, "0 1 1 1  # color of points\n");
-    }
-    if (qh PRINTdim == 4  && !qh PRINTnoplanes)
-      /* 4dview loads up multiple 4OFF objects slowly */
-      fprintf(fp, "4OFF %d %d 1\n", 3*qh ridgeoutnum, qh ridgeoutnum);
-    qh PRINTcradius= 2 * qh DISTround;  /* include test DISTround */
-    if (qh PREmerge) {
-      maximize_(qh PRINTcradius, qh premerge_centrum + qh DISTround);
-    }else if (qh POSTmerge)
-      maximize_(qh PRINTcradius, qh postmerge_centrum + qh DISTround);
-    qh PRINTradius= qh PRINTcradius;
-    if (qh PRINTspheres + qh PRINTcoplanar)
-      maximize_(qh PRINTradius, qh MAXabs_coord * qh_MINradius);
-    if (qh premerge_cos < REALmax/2) {
-      maximize_(qh PRINTradius, (1- qh premerge_cos) * qh MAXabs_coord);
-    }else if (!qh PREmerge && qh POSTmerge && qh postmerge_cos < REALmax/2) {
-      maximize_(qh PRINTradius, (1- qh postmerge_cos) * qh MAXabs_coord);
-    }
-    maximize_(qh PRINTradius, qh MINvisible); 
-    if (qh JOGGLEmax < REALmax/2)
-      qh PRINTradius += qh JOGGLEmax * sqrt (qh hull_dim);
-    if (qh PRINTdim != 4 &&
-	(qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
-      vertices= qh_facetvertices (facetlist, facets, printall);
-      if (qh PRINTspheres && qh PRINTdim <= 3)
-         qh_printspheres (fp, vertices, qh PRINTradius);
-      if (qh PRINTcoplanar || qh PRINTcentrums) {
-        qh firstcentrum= True;
-        if (qh PRINTcoplanar&& !qh PRINTspheres) {
-          FOREACHvertex_(vertices) 
-            qh_printpointvect2 (fp, vertex->point, NULL,
-				qh interior_point, qh PRINTradius);
-	}
-        FORALLfacet_(facetlist) {
-	  if (!printall && qh_skipfacet(facet))
-	    continue;
-	  if (!facet->normal)
-	    continue;
-          if (qh PRINTcentrums && qh PRINTdim <= 3)
-            qh_printcentrum (fp, facet, qh PRINTcradius);
-	  if (!qh PRINTcoplanar)
-	    continue;
-          FOREACHpoint_(facet->coplanarset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-          FOREACHpoint_(facet->outsideset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-        }
-        FOREACHfacet_(facets) {
-	  if (!printall && qh_skipfacet(facet))
-	    continue;
-	  if (!facet->normal)
-	    continue;
-          if (qh PRINTcentrums && qh PRINTdim <= 3)
-            qh_printcentrum (fp, facet, qh PRINTcradius);
-	  if (!qh PRINTcoplanar)
-	    continue;
-          FOREACHpoint_(facet->coplanarset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-          FOREACHpoint_(facet->outsideset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-        }
-      }
-      qh_settempfree (&vertices);
-    }
-    qh visit_id++; /* for printing hyperplane intersections */
-    break;
-  case qh_PRINTids:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTincidences:
-    if (qh VORONOI && qh PRINTprecision)
-      fprintf (qh ferr, "qhull warning: writing Delaunay.  Use 'p' or 'o' for Voronoi centers\n");
-    qh printoutvar= qh vertex_id;  /* centrum id for non-simplicial facets */
-    if (qh hull_dim <= 3)
-      fprintf(fp, "%d\n", numfacets);
-    else
-      fprintf(fp, "%d\n", numsimplicial+numridges);
-    break;
-  case qh_PRINTinner:
-  case qh_PRINTnormals:
-  case qh_PRINTouter:
-    if (qh CDDoutput)
-      fprintf (fp, "%s | %s\nbegin\n    %d %d real\n", qh rbox_command, 
-              qh qhull_command, numfacets, qh hull_dim+1);
-    else
-      fprintf (fp, "%d\n%d\n", qh hull_dim+1, numfacets);
-    break;
-  case qh_PRINTmathematica:  
-    if (qh hull_dim > 3)  /* qh_initbuffers also checks */
-      goto LABELnoformat;
-    if (qh VORONOI)
-      fprintf (qh ferr, "qhull warning: output is the Delaunay triangulation\n");
-    fprintf(fp, "{\n");
-    qh printoutvar= 0;   /* counts number of facets for notfirst */
-    break;
-  case qh_PRINTmerges:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTpointintersect:
-    fprintf (fp, "%d\n%d\n", qh hull_dim, numfacets);
-    break;
-  case qh_PRINTneighbors:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINToff:
-  case qh_PRINTtriangles:
-    if (qh VORONOI)
-      goto LABELnoformat;
-    num = qh hull_dim;
-    if (format == qh_PRINToff || qh hull_dim == 2)
-      fprintf (fp, "%d\n%d %d %d\n", num, 
-        qh num_points+qh_setsize (qh other_points), numfacets, totneighbors/2);
-    else { /* qh_PRINTtriangles */
-      qh printoutvar= qh num_points+qh_setsize (qh other_points); /* first centrum */
-      if (qh DELAUNAY)
-        num--;  /* drop last dimension */
-      fprintf (fp, "%d\n%d %d %d\n", num, qh printoutvar 
-	+ numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2);
-    }
-    FORALLpoints
-      qh_printpointid (qh fout, NULL, num, point, -1);
-    FOREACHpoint_(qh other_points)
-      qh_printpointid (qh fout, NULL, num, point, -1);
-    if (format == qh_PRINTtriangles && qh hull_dim > 2) {
-      FORALLfacets {
-	if (!facet->simplicial && facet->visitid)
-          qh_printcenter (qh fout, format, NULL, facet);
-      }
-    }
-    break;
-  case qh_PRINTpointnearest:
-    fprintf (fp, "%d\n", numcoplanars);
-    break;
-  case qh_PRINTpoints:
-    if (!qh VORONOI)
-      goto LABELnoformat;
-    if (qh CDDoutput)
-      fprintf (fp, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
-             qh qhull_command, numfacets, qh hull_dim);
-    else
-      fprintf (fp, "%d\n%d\n", qh hull_dim-1, numfacets);
-    break;
-  case qh_PRINTvertices:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTsummary:
-  default:
-  LABELnoformat:
-    fprintf (qh ferr, "qhull internal error (qh_printbegin): can not use this format for dimension %d\n",
-         qh hull_dim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-} /* printbegin */
-
-/*---------------------------------
-  
-  qh_printcenter( fp, string, facet )
-    print facet->center as centrum or Voronoi center
-    string may be NULL.  Don't include '%' codes.
-    nop if qh CENTERtype neither CENTERvoronoi nor CENTERcentrum
-    if upper envelope of Delaunay triangulation and point at-infinity
-      prints qh_INFINITE instead;
-
-  notes:
-    defines facet->center if needed
-    if format=PRINTgeom, adds a 0 if would otherwise be 2-d
-*/
-void qh_printcenter (FILE *fp, int format, char *string, facetT *facet) {
-  int k, num;
-
-  if (qh CENTERtype != qh_ASvoronoi && qh CENTERtype != qh_AScentrum)
-    return;
-  if (string)
-    fprintf (fp, string, facet->id);
-  if (qh CENTERtype == qh_ASvoronoi) {
-    num= qh hull_dim-1;
-    if (!facet->normal || !facet->upperdelaunay || !qh ATinfinity) {
-      if (!facet->center)
-        facet->center= qh_facetcenter (facet->vertices);
-      for (k=0; k < num; k++)
-        fprintf (fp, qh_REAL_1, facet->center[k]);
-    }else {
-      for (k=0; k < num; k++)
-        fprintf (fp, qh_REAL_1, qh_INFINITE);
-    }
-  }else /* qh CENTERtype == qh_AScentrum */ {
-    num= qh hull_dim;
-    if (format == qh_PRINTtriangles && qh DELAUNAY) 
-      num--;
-    if (!facet->center) 
-      facet->center= qh_getcentrum (facet);
-    for (k=0; k < num; k++)
-      fprintf (fp, qh_REAL_1, facet->center[k]);
-  }
-  if (format == qh_PRINTgeom && num == 2)
-    fprintf (fp, " 0\n");
-  else
-    fprintf (fp, "\n");
-} /* printcenter */
-
-/*---------------------------------
-  
-  qh_printcentrum( fp, facet, radius )
-    print centrum for a facet in OOGL format
-    radius defines size of centrum
-    2-d or 3-d only
-
-  returns:
-    defines facet->center if needed
-*/
-void qh_printcentrum (FILE *fp, facetT *facet, realT radius) {
-  pointT *centrum, *projpt;
-  boolT tempcentrum= False;
-  realT xaxis[4], yaxis[4], normal[4], dist;
-  realT green[3]={0, 1, 0};
-  vertexT *apex;
-  int k;
-  
-  if (qh CENTERtype == qh_AScentrum) {
-    if (!facet->center)
-      facet->center= qh_getcentrum (facet);
-    centrum= facet->center;
-  }else {
-    centrum= qh_getcentrum (facet);
-    tempcentrum= True;
-  }
-  fprintf (fp, "{appearance {-normal -edge normscale 0} ");
-  if (qh firstcentrum) {
-    qh firstcentrum= False;
-    fprintf (fp, "{INST geom { define centrum CQUAD  # f%d\n\
--0.3 -0.3 0.0001     0 0 1 1\n\
- 0.3 -0.3 0.0001     0 0 1 1\n\
- 0.3  0.3 0.0001     0 0 1 1\n\
--0.3  0.3 0.0001     0 0 1 1 } transform { \n", facet->id);
-  }else
-    fprintf (fp, "{INST geom { : centrum } transform { # f%d\n", facet->id);
-  apex= SETfirstt_(facet->vertices, vertexT);
-  qh_distplane(apex->point, facet, &dist);
-  projpt= qh_projectpoint(apex->point, facet, dist);
-  for (k= qh hull_dim; k--; ) {
-    xaxis[k]= projpt[k] - centrum[k];
-    normal[k]= facet->normal[k];
-  }
-  if (qh hull_dim == 2) {
-    xaxis[2]= 0;
-    normal[2]= 0;
-  }else if (qh hull_dim == 4) {
-    qh_projectdim3 (xaxis, xaxis);
-    qh_projectdim3 (normal, normal);
-    qh_normalize2 (normal, qh PRINTdim, True, NULL, NULL);
-  }
-  qh_crossproduct (3, xaxis, normal, yaxis);
-  fprintf (fp, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]);
-  fprintf (fp, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]);
-  fprintf (fp, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]);
-  qh_printpoint3 (fp, centrum);
-  fprintf (fp, "1 }}}\n"); 
-  qh_memfree (projpt, qh normal_size);
-  qh_printpointvect (fp, centrum, facet->normal, NULL, radius, green);
-  if (tempcentrum)
-    qh_memfree (centrum, qh normal_size);
-} /* printcentrum */
-  
-/*---------------------------------
-  
-  qh_printend( fp, format )
-    prints trailer for all output formats
-
-  see:
-    qh_printbegin() and qh_printafacet()
-      
-*/
-void qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int num;
-  facetT *facet, **facetp;
-
-  if (!qh printoutnum)
-    fprintf (qh ferr, "qhull warning: no facets printed\n");
-  switch (format) {
-  case qh_PRINTgeom:
-    if (qh hull_dim == 4 && qh DROPdim < 0  && !qh PRINTnoplanes) {
-      qh visit_id++;
-      num= 0;
-      FORALLfacet_(facetlist)
-        qh_printend4geom (fp, facet,&num, printall);
-      FOREACHfacet_(facets) 
-        qh_printend4geom (fp, facet, &num, printall);
-      if (num != qh ridgeoutnum || qh printoutvar != qh ridgeoutnum) {
-	fprintf (qh ferr, "qhull internal error (qh_printend): number of ridges %d != number printed %d and at end %d\n", qh ridgeoutnum, qh printoutvar, num);
-	qh_errexit (qh_ERRqhull, NULL, NULL);
-      }
-    }else
-      fprintf(fp, "}\n");
-    break;
-  case qh_PRINTinner:
-  case qh_PRINTnormals:
-  case qh_PRINTouter:
-    if (qh CDDoutput) 
-      fprintf (fp, "end\n");
-    break;
-  case qh_PRINTmathematica:
-    fprintf(fp, "}\n");
-    break;
-  case qh_PRINTpoints:
-    if (qh CDDoutput)
-      fprintf (fp, "end\n");
-    break;
-  }
-} /* printend */
-
-/*---------------------------------
-  
-  qh_printend4geom( fp, facet, numridges, printall )
-    helper function for qh_printbegin/printend
-
-  returns:
-    number of printed ridges
-  
-  notes:
-    just counts printed ridges if fp=NULL
-    uses facet->visitid
-    must agree with qh_printfacet4geom...
-
-  design:
-    computes color for facet from its normal
-    prints each ridge of facet 
-*/
-void qh_printend4geom (FILE *fp, facetT *facet, int *nump, boolT printall) {
-  realT color[3];
-  int i, num= *nump;
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  
-  if (!printall && qh_skipfacet(facet))
-    return;
-  if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
-    return;
-  if (!facet->normal)
-    return;
-  if (fp) {
-    for (i=0; i < 3; i++) {
-      color[i]= (facet->normal[i]+1.0)/2.0;
-      maximize_(color[i], -1.0);
-      minimize_(color[i], +1.0);
-    }
-  }
-  facet->visitid= qh visit_id;
-  if (facet->simplicial) {
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-	if (fp)
-          fprintf (fp, "3 %d %d %d %8.4g %8.4g %8.4g 1 # f%d f%d\n",
-		 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
-		 facet->id, neighbor->id);
-	num++;
-      }
-    }
-  }else {
-    FOREACHridge_(facet->ridges) {
-      neighbor= otherfacet_(ridge, facet);
-      if (neighbor->visitid != qh visit_id) {
-	if (fp)
-          fprintf (fp, "3 %d %d %d %8.4g %8.4g %8.4g 1 #r%d f%d f%d\n",
-		 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
-		 ridge->id, facet->id, neighbor->id);
-	num++;
-      }
-    }
-  }
-  *nump= num;
-} /* printend4geom */
-
-/*---------------------------------
-  
-  qh_printextremes( fp, facetlist, facets, printall )
-    print extreme points for convex hulls or halfspace intersections
-
-  notes:
-    #points, followed by ids, one per line
-    
-    sorted by id
-    same order as qh_printpoints_out if no coplanar/interior points
-*/
-void qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  setT *vertices, *points;
-  pointT *point;
-  vertexT *vertex, **vertexp;
-  int id;
-  int numpoints=0, point_i, point_n;
-  int allpoints= qh num_points + qh_setsize (qh other_points);
-
-  points= qh_settemp (allpoints);
-  qh_setzero (points, 0, allpoints);
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  FOREACHvertex_(vertices) {
-    id= qh_pointid (vertex->point);
-    if (id >= 0) {
-      SETelem_(points, id)= vertex->point;
-      numpoints++;
-    }
-  }
-  qh_settempfree (&vertices);
-  fprintf (fp, "%d\n", numpoints);
-  FOREACHpoint_i_(points) {
-    if (point) 
-      fprintf (fp, "%d\n", point_i);
-  }
-  qh_settempfree (&points);
-} /* printextremes */
-
-/*---------------------------------
-  
-  qh_printextremes_2d( fp, facetlist, facets, printall )
-    prints point ids for facets in qh_ORIENTclock order
-
-  notes:
-    #points, followed by ids, one per line
-    if facetlist/facets are disjoint than the output includes skips
-    errors if facets form a loop
-    does not print coplanar points
-*/
-void qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  int numfacets, numridges, totneighbors, numcoplanars, numsimplicial, numtricoplanars;
-  setT *vertices;
-  facetT *facet, *startfacet, *nextfacet;
-  vertexT *vertexA, *vertexB;
-
-  qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* marks qh visit_id */
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  fprintf(fp, "%d\n", qh_setsize (vertices));
-  qh_settempfree (&vertices);
-  if (!numfacets)
-    return;
-  facet= startfacet= facetlist ? facetlist : SETfirstt_(facets, facetT);
-  qh vertex_visit++;
-  qh visit_id++;
-  do {
-    if (facet->toporient ^ qh_ORIENTclock) {
-      vertexA= SETfirstt_(facet->vertices, vertexT);
-      vertexB= SETsecondt_(facet->vertices, vertexT);
-      nextfacet= SETfirstt_(facet->neighbors, facetT);
-    }else {
-      vertexA= SETsecondt_(facet->vertices, vertexT);
-      vertexB= SETfirstt_(facet->vertices, vertexT);
-      nextfacet= SETsecondt_(facet->neighbors, facetT);
-    }
-    if (facet->visitid == qh visit_id) {
-      fprintf(qh ferr, "qh_printextremes_2d: loop in facet list.  facet %d nextfacet %d\n",
-                 facet->id, nextfacet->id);
-      qh_errexit2 (qh_ERRqhull, facet, nextfacet);
-    }
-    if (facet->visitid) {
-      if (vertexA->visitid != qh vertex_visit) {
-	vertexA->visitid= qh vertex_visit;
-	fprintf(fp, "%d\n", qh_pointid (vertexA->point));
-      }
-      if (vertexB->visitid != qh vertex_visit) {
-	vertexB->visitid= qh vertex_visit;
-	fprintf(fp, "%d\n", qh_pointid (vertexB->point));
-      }
-    }
-    facet->visitid= qh visit_id;
-    facet= nextfacet;
-  }while (facet && facet != startfacet);
-} /* printextremes_2d */
-
-/*---------------------------------
-  
-  qh_printextremes_d( fp, facetlist, facets, printall )
-    print extreme points of input sites for Delaunay triangulations
-
-  notes:
-    #points, followed by ids, one per line
-    
-    unordered
-*/
-void qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  setT *vertices;
-  vertexT *vertex, **vertexp;
-  boolT upperseen, lowerseen;
-  facetT *neighbor, **neighborp;
-  int numpoints=0;
-
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  qh_vertexneighbors();
-  FOREACHvertex_(vertices) {
-    upperseen= lowerseen= False;
-    FOREACHneighbor_(vertex) {
-      if (neighbor->upperdelaunay)
-        upperseen= True;
-      else
-        lowerseen= True;
-    }
-    if (upperseen && lowerseen) {
-      vertex->seen= True;
-      numpoints++;
-    }else
-      vertex->seen= False;
-  }
-  fprintf (fp, "%d\n", numpoints);
-  FOREACHvertex_(vertices) {
-    if (vertex->seen)
-      fprintf (fp, "%d\n", qh_pointid (vertex->point));
-  }
-  qh_settempfree (&vertices);
-} /* printextremes_d */
-
-/*---------------------------------
-  
-  qh_printfacet( fp, facet )
-    prints all fields of a facet to fp
-
-  notes:
-    ridges printed in neighbor order
-*/
-void qh_printfacet(FILE *fp, facetT *facet) {
-
-  qh_printfacetheader (fp, facet);
-  if (facet->ridges)
-    qh_printfacetridges (fp, facet);
-} /* printfacet */
-
-
-/*---------------------------------
-  
-  qh_printfacet2geom( fp, facet, color )
-    print facet as part of a 2-d VECT for Geomview
-  
-    notes:
-      assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
-      mindist is calculated within io.c.  maxoutside is calculated elsewhere
-      so a DISTround error may have occured.
-*/
-void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]) {
-  pointT *point0, *point1;
-  realT mindist, innerplane, outerplane;
-  int k;
-
-  qh_facet2point (facet, &point0, &point1, &mindist);
-  qh_geomplanes (facet, &outerplane, &innerplane);
-  if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
-    qh_printfacet2geom_points(fp, point0, point1, facet, outerplane, color);
-  if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
-                outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
-    for(k= 3; k--; )
-      color[k]= 1.0 - color[k];
-    qh_printfacet2geom_points(fp, point0, point1, facet, innerplane, color);
-  }
-  qh_memfree (point1, qh normal_size);
-  qh_memfree (point0, qh normal_size); 
-} /* printfacet2geom */
-
-/*---------------------------------
-  
-  qh_printfacet2geom_points( fp, point1, point2, facet, offset, color )
-    prints a 2-d facet as a VECT with 2 points at some offset.   
-    The points are on the facet's plane.
-*/
-void qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
-			       facetT *facet, realT offset, realT color[3]) {
-  pointT *p1= point1, *p2= point2;
-
-  fprintf(fp, "VECT 1 2 1 2 1 # f%d\n", facet->id);
-  if (offset != 0.0) {
-    p1= qh_projectpoint (p1, facet, -offset);
-    p2= qh_projectpoint (p2, facet, -offset);
-  }
-  fprintf(fp, "%8.4g %8.4g %8.4g\n%8.4g %8.4g %8.4g\n",
-           p1[0], p1[1], 0.0, p2[0], p2[1], 0.0);
-  if (offset != 0.0) {
-    qh_memfree (p1, qh normal_size);
-    qh_memfree (p2, qh normal_size);
-  }
-  fprintf(fp, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
-} /* printfacet2geom_points */
-
-
-/*---------------------------------
-  
-  qh_printfacet2math( fp, facet, notfirst )
-    print 2-d Mathematica output for a facet
-    may be non-simplicial
-
-  notes:
-    use %16.8f since Mathematica 2.2 does not handle exponential format
-*/
-void qh_printfacet2math(FILE *fp, facetT *facet, int notfirst) {
-  pointT *point0, *point1;
-  realT mindist;
-  
-  qh_facet2point (facet, &point0, &point1, &mindist);
-  if (notfirst)
-    fprintf(fp, ",");
-  fprintf(fp, "Line[{{%16.8f, %16.8f}, {%16.8f, %16.8f}}]\n",
-	  point0[0], point0[1], point1[0], point1[1]);
-  qh_memfree (point1, qh normal_size);
-  qh_memfree (point0, qh normal_size);
-} /* printfacet2math */
-
-
-/*---------------------------------
-  
-  qh_printfacet3geom_nonsimplicial( fp, facet, color )
-    print Geomview OFF for a 3-d nonsimplicial facet.
-    if DOintersections, prints ridges to unvisited neighbors (qh visit_id) 
-
-  notes
-    uses facet->visitid for intersections and ridges
-*/
-void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) {
-  ridgeT *ridge, **ridgep;
-  setT *projectedpoints, *vertices;
-  vertexT *vertex, **vertexp, *vertexA, *vertexB;
-  pointT *projpt, *point, **pointp;
-  facetT *neighbor;
-  realT dist, outerplane, innerplane;
-  int cntvertices, k;
-  realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
-
-  qh_geomplanes (facet, &outerplane, &innerplane); 
-  vertices= qh_facet3vertex (facet); /* oriented */
-  cntvertices= qh_setsize(vertices);
-  projectedpoints= qh_settemp(cntvertices);
-  FOREACHvertex_(vertices) {
-    zinc_(Zdistio);
-    qh_distplane(vertex->point, facet, &dist);
-    projpt= qh_projectpoint(vertex->point, facet, dist);
-    qh_setappend (&projectedpoints, projpt);
-  }
-  if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
-    qh_printfacet3geom_points(fp, projectedpoints, facet, outerplane, color);
-  if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
-                outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
-    for (k=3; k--; )
-      color[k]= 1.0 - color[k];
-    qh_printfacet3geom_points(fp, projectedpoints, facet, innerplane, color);
-  }
-  FOREACHpoint_(projectedpoints)
-    qh_memfree (point, qh normal_size);
-  qh_settempfree(&projectedpoints);
-  qh_settempfree(&vertices);
-  if ((qh DOintersections || qh PRINTridges)
-  && (!facet->visible || !qh NEWfacets)) {
-    facet->visitid= qh visit_id;
-    FOREACHridge_(facet->ridges) {
-      neighbor= otherfacet_(ridge, facet);
-      if (neighbor->visitid != qh visit_id) {
-        if (qh DOintersections)
-          qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, black);
-        if (qh PRINTridges) {
-          vertexA= SETfirstt_(ridge->vertices, vertexT);
-          vertexB= SETsecondt_(ridge->vertices, vertexT);
-          qh_printline3geom (fp, vertexA->point, vertexB->point, green);
-        }
-      }
-    }
-  }
-} /* printfacet3geom_nonsimplicial */
-
-/*---------------------------------
-  
-  qh_printfacet3geom_points( fp, points, facet, offset )
-    prints a 3-d facet as OFF Geomview object. 
-    offset is relative to the facet's hyperplane
-    Facet is determined as a list of points
-*/
-void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]) {
-  int k, n= qh_setsize(points), i;
-  pointT *point, **pointp;
-  setT *printpoints;
-
-  fprintf(fp, "{ OFF %d 1 1 # f%d\n", n, facet->id);
-  if (offset != 0.0) {
-    printpoints= qh_settemp (n);
-    FOREACHpoint_(points) 
-      qh_setappend (&printpoints, qh_projectpoint(point, facet, -offset));
-  }else
-    printpoints= points;
-  FOREACHpoint_(printpoints) {
-    for (k=0; k < qh hull_dim; k++) {
-      if (k == qh DROPdim)
-        fprintf(fp, "0 ");
-      else
-        fprintf(fp, "%8.4g ", point[k]);
-    }
-    if (printpoints != points)
-      qh_memfree (point, qh normal_size);
-    fprintf (fp, "\n");
-  }
-  if (printpoints != points)
-    qh_settempfree (&printpoints);
-  fprintf(fp, "%d ", n);
-  for(i= 0; i < n; i++)
-    fprintf(fp, "%d ", i);
-  fprintf(fp, "%8.4g %8.4g %8.4g 1.0 }\n", color[0], color[1], color[2]);
-} /* printfacet3geom_points */
-
-
-/*---------------------------------
-  
-  qh_printfacet3geom_simplicial(  )
-    print Geomview OFF for a 3-d simplicial facet.
-
-  notes:
-    may flip color
-    uses facet->visitid for intersections and ridges
-
-    assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
-    innerplane may be off by qh DISTround.  Maxoutside is calculated elsewhere
-    so a DISTround error may have occured.
-*/
-void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
-  setT *points, *vertices;
-  vertexT *vertex, **vertexp, *vertexA, *vertexB;
-  facetT *neighbor, **neighborp;
-  realT outerplane, innerplane;
-  realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
-  int k;
-
-  qh_geomplanes (facet, &outerplane, &innerplane); 
-  vertices= qh_facet3vertex (facet);
-  points= qh_settemp (qh TEMPsize);
-  FOREACHvertex_(vertices)
-    qh_setappend(&points, vertex->point);
-  if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
-    qh_printfacet3geom_points(fp, points, facet, outerplane, color);
-  if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
-              outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
-    for (k= 3; k--; )
-      color[k]= 1.0 - color[k];
-    qh_printfacet3geom_points(fp, points, facet, innerplane, color);
-  }
-  qh_settempfree(&points);
-  qh_settempfree(&vertices);
-  if ((qh DOintersections || qh PRINTridges)
-  && (!facet->visible || !qh NEWfacets)) {
-    facet->visitid= qh visit_id;
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-	vertices= qh_setnew_delnthsorted (facet->vertices, qh hull_dim,
-	                  SETindex_(facet->neighbors, neighbor), 0);
-        if (qh DOintersections)
-	   qh_printhyperplaneintersection(fp, facet, neighbor, vertices, black); 
-        if (qh PRINTridges) {
-          vertexA= SETfirstt_(vertices, vertexT);
-          vertexB= SETsecondt_(vertices, vertexT);
-          qh_printline3geom (fp, vertexA->point, vertexB->point, green);
-        }
-	qh_setfree(&vertices);
-      }
-    }
-  }
-} /* printfacet3geom_simplicial */
-
-/*---------------------------------
-  
-  qh_printfacet3math( fp, facet, notfirst )
-    print 3-d Mathematica output for a facet
-
-  notes:
-    may be non-simplicial
-    use %16.8f since Mathematica 2.2 does not handle exponential format
-*/
-void qh_printfacet3math (FILE *fp, facetT *facet, int notfirst) {
-  vertexT *vertex, **vertexp;
-  setT *points, *vertices;
-  pointT *point, **pointp;
-  boolT firstpoint= True;
-  realT dist;
-  
-  if (notfirst)
-    fprintf(fp, ",\n");
-  vertices= qh_facet3vertex (facet);
-  points= qh_settemp (qh_setsize (vertices));
-  FOREACHvertex_(vertices) {
-    zinc_(Zdistio);
-    qh_distplane(vertex->point, facet, &dist);
-    point= qh_projectpoint(vertex->point, facet, dist);
-    qh_setappend (&points, point);
-  }
-  fprintf(fp, "Polygon[{");
-  FOREACHpoint_(points) {
-    if (firstpoint)
-      firstpoint= False;
-    else
-      fprintf(fp, ",\n");
-    fprintf(fp, "{%16.8f, %16.8f, %16.8f}", point[0], point[1], point[2]);
-  }
-  FOREACHpoint_(points)
-    qh_memfree (point, qh normal_size);
-  qh_settempfree(&points);
-  qh_settempfree(&vertices);
-  fprintf(fp, "}]");
-} /* printfacet3math */
-
-
-/*---------------------------------
-  
-  qh_printfacet3vertex( fp, facet, format )
-    print vertices in a 3-d facet as point ids
-
-  notes:
-    prints number of vertices first if format == qh_PRINToff
-    the facet may be non-simplicial
-*/
-void qh_printfacet3vertex(FILE *fp, facetT *facet, int format) {
-  vertexT *vertex, **vertexp;
-  setT *vertices;
-
-  vertices= qh_facet3vertex (facet);
-  if (format == qh_PRINToff)
-    fprintf (fp, "%d ", qh_setsize (vertices));
-  FOREACHvertex_(vertices) 
-    fprintf (fp, "%d ", qh_pointid(vertex->point));
-  fprintf (fp, "\n");
-  qh_settempfree(&vertices);
-} /* printfacet3vertex */
-
-
-/*---------------------------------
-  
-  qh_printfacet4geom_nonsimplicial(  )
-    print Geomview 4OFF file for a 4d nonsimplicial facet
-    prints all ridges to unvisited neighbors (qh.visit_id)
-    if qh.DROPdim
-      prints in OFF format
-  
-  notes:
-    must agree with printend4geom()
-*/
-void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) {
-  facetT *neighbor;
-  ridgeT *ridge, **ridgep;
-  vertexT *vertex, **vertexp;
-  pointT *point;
-  int k;
-  realT dist;
-  
-  facet->visitid= qh visit_id;
-  if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
-    return;
-  FOREACHridge_(facet->ridges) {
-    neighbor= otherfacet_(ridge, facet);
-    if (neighbor->visitid == qh visit_id) 
-      continue;
-    if (qh PRINTtransparent && !neighbor->good)
-      continue;  
-    if (qh DOintersections)
-      qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, color);
-    else {
-      if (qh DROPdim >= 0) 
-	fprintf(fp, "OFF 3 1 1 # f%d\n", facet->id);
-      else {
-	qh printoutvar++;
-	fprintf (fp, "# r%d between f%d f%d\n", ridge->id, facet->id, neighbor->id);
-      }
-      FOREACHvertex_(ridge->vertices) {
-	zinc_(Zdistio);
-	qh_distplane(vertex->point,facet, &dist);
-	point=qh_projectpoint(vertex->point,facet, dist);
-	for(k= 0; k < qh hull_dim; k++) {
-	  if (k != qh DROPdim)
-  	    fprintf(fp, "%8.4g ", point[k]);
-  	}
-	fprintf (fp, "\n");
-	qh_memfree (point, qh normal_size);
-      }
-      if (qh DROPdim >= 0)
-        fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
-    }
-  }
-} /* printfacet4geom_nonsimplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacet4geom_simplicial( fp, facet, color )
-    print Geomview 4OFF file for a 4d simplicial facet
-    prints triangles for unvisited neighbors (qh.visit_id)
-
-  notes:
-    must agree with printend4geom()
-*/
-void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
-  setT *vertices;
-  facetT *neighbor, **neighborp;
-  vertexT *vertex, **vertexp;
-  int k;
-  
-  facet->visitid= qh visit_id;
-  if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
-    return;
-  FOREACHneighbor_(facet) {
-    if (neighbor->visitid == qh visit_id)
-      continue;
-    if (qh PRINTtransparent && !neighbor->good)
-      continue;  
-    vertices= qh_setnew_delnthsorted (facet->vertices, qh hull_dim,
-	                  SETindex_(facet->neighbors, neighbor), 0);
-    if (qh DOintersections)
-      qh_printhyperplaneintersection(fp, facet, neighbor, vertices, color);
-    else {
-      if (qh DROPdim >= 0) 
-	fprintf(fp, "OFF 3 1 1 # ridge between f%d f%d\n",
-		facet->id, neighbor->id);
-      else {
-	qh printoutvar++;
-	fprintf (fp, "# ridge between f%d f%d\n", facet->id, neighbor->id);
-      }
-      FOREACHvertex_(vertices) {
-	for(k= 0; k < qh hull_dim; k++) {
-	  if (k != qh DROPdim)
-  	    fprintf(fp, "%8.4g ", vertex->point[k]);
-  	}
-	fprintf (fp, "\n");
-      }
-      if (qh DROPdim >= 0) 
-        fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
-    }
-    qh_setfree(&vertices);
-  }
-} /* printfacet4geom_simplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacetNvertex_nonsimplicial( fp, facet, id, format )
-    print vertices for an N-d non-simplicial facet
-    triangulates each ridge to the id
-*/
-void qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int format) {
-  vertexT *vertex, **vertexp;
-  ridgeT *ridge, **ridgep;
-
-  if (facet->visible && qh NEWfacets)
-    return;
-  FOREACHridge_(facet->ridges) {
-    if (format == qh_PRINTtriangles)
-      fprintf(fp, "%d ", qh hull_dim);
-    fprintf(fp, "%d ", id);
-    if ((ridge->top == facet) ^ qh_ORIENTclock) {
-      FOREACHvertex_(ridge->vertices)
-        fprintf(fp, "%d ", qh_pointid(vertex->point));
-    }else {
-      FOREACHvertexreverse12_(ridge->vertices)
-        fprintf(fp, "%d ", qh_pointid(vertex->point));
-    }
-    fprintf(fp, "\n");
-  }
-} /* printfacetNvertex_nonsimplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacetNvertex_simplicial( fp, facet, format )
-    print vertices for an N-d simplicial facet
-    prints vertices for non-simplicial facets
-      2-d facets (orientation preserved by qh_mergefacet2d)
-      PRINToff ('o') for 4-d and higher
-*/
-void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format) {
-  vertexT *vertex, **vertexp;
-
-  if (format == qh_PRINToff || format == qh_PRINTtriangles)
-    fprintf (fp, "%d ", qh_setsize (facet->vertices));
-  if ((facet->toporient ^ qh_ORIENTclock) 
-  || (qh hull_dim > 2 && !facet->simplicial)) {
-    FOREACHvertex_(facet->vertices)
-      fprintf(fp, "%d ", qh_pointid(vertex->point));
-  }else {
-    FOREACHvertexreverse12_(facet->vertices)
-      fprintf(fp, "%d ", qh_pointid(vertex->point));
-  }
-  fprintf(fp, "\n");
-} /* printfacetNvertex_simplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacetheader( fp, facet )
-    prints header fields of a facet to fp
-    
-  notes:
-    for 'f' output and debugging
-*/
-void qh_printfacetheader(FILE *fp, facetT *facet) {
-  pointT *point, **pointp, *furthest;
-  facetT *neighbor, **neighborp;
-  realT dist;
-
-  if (facet == qh_MERGEridge) {
-    fprintf (fp, " MERGEridge\n");
-    return;
-  }else if (facet == qh_DUPLICATEridge) {
-    fprintf (fp, " DUPLICATEridge\n");
-    return;
-  }else if (!facet) {
-    fprintf (fp, " NULLfacet\n");
-    return;
-  }
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  fprintf(fp, "- f%d\n", facet->id);
-  fprintf(fp, "    - flags:");
-  if (facet->toporient) 
-    fprintf(fp, " top");
-  else
-    fprintf(fp, " bottom");
-  if (facet->simplicial)
-    fprintf(fp, " simplicial");
-  if (facet->tricoplanar)
-    fprintf(fp, " tricoplanar");
-  if (facet->upperdelaunay)
-    fprintf(fp, " upperDelaunay");
-  if (facet->visible)
-    fprintf(fp, " visible");
-  if (facet->newfacet)
-    fprintf(fp, " new");
-  if (facet->tested)
-    fprintf(fp, " tested");
-  if (!facet->good)
-    fprintf(fp, " notG");
-  if (facet->seen)
-    fprintf(fp, " seen");
-  if (facet->coplanar)
-    fprintf(fp, " coplanar");
-  if (facet->mergehorizon)
-    fprintf(fp, " mergehorizon");
-  if (facet->keepcentrum)
-    fprintf(fp, " keepcentrum");
-  if (facet->dupridge)
-    fprintf(fp, " dupridge");
-  if (facet->mergeridge && !facet->mergeridge2)
-    fprintf(fp, " mergeridge1");
-  if (facet->mergeridge2)
-    fprintf(fp, " mergeridge2");
-  if (facet->newmerge)
-    fprintf(fp, " newmerge");
-  if (facet->flipped) 
-    fprintf(fp, " flipped");
-  if (facet->notfurthest) 
-    fprintf(fp, " notfurthest");
-  if (facet->degenerate)
-    fprintf(fp, " degenerate");
-  if (facet->redundant)
-    fprintf(fp, " redundant");
-  fprintf(fp, "\n");
-  if (facet->isarea)
-    fprintf(fp, "    - area: %2.2g\n", facet->f.area);
-  else if (qh NEWfacets && facet->visible && facet->f.replace)
-    fprintf(fp, "    - replacement: f%d\n", facet->f.replace->id);
-  else if (facet->newfacet) {
-    if (facet->f.samecycle && facet->f.samecycle != facet)
-      fprintf(fp, "    - shares same visible/horizon as f%d\n", facet->f.samecycle->id);
-  }else if (facet->tricoplanar /* !isarea */) {
-    if (facet->f.triowner)
-      fprintf(fp, "    - owner of normal & centrum is facet f%d\n", facet->f.triowner->id);
-  }else if (facet->f.newcycle)
-    fprintf(fp, "    - was horizon to f%d\n", facet->f.newcycle->id);
-  if (facet->nummerge)
-    fprintf(fp, "    - merges: %d\n", facet->nummerge);
-  qh_printpointid(fp, "    - normal: ", qh hull_dim, facet->normal, -1);
-  fprintf(fp, "    - offset: %10.7g\n", facet->offset);
-  if (qh CENTERtype == qh_ASvoronoi || facet->center)
-    qh_printcenter (fp, qh_PRINTfacets, "    - center: ", facet);
-#if qh_MAXoutside
-  if (facet->maxoutside > qh DISTround)
-    fprintf(fp, "    - maxoutside: %10.7g\n", facet->maxoutside);
-#endif
-  if (!SETempty_(facet->outsideset)) {
-    furthest= (pointT*)qh_setlast(facet->outsideset);
-    if (qh_setsize (facet->outsideset) < 6) {
-      fprintf(fp, "    - outside set (furthest p%d):\n", qh_pointid(furthest));
-      FOREACHpoint_(facet->outsideset)
-	qh_printpoint(fp, "     ", point);
-    }else if (qh_setsize (facet->outsideset) < 21) {
-      qh_printpoints(fp, "    - outside set:", facet->outsideset);
-    }else {
-      fprintf(fp, "    - outside set:  %d points.", qh_setsize(facet->outsideset));
-      qh_printpoint(fp, "  Furthest", furthest);
-    }
-#if !qh_COMPUTEfurthest
-    fprintf(fp, "    - furthest distance= %2.2g\n", facet->furthestdist);
-#endif
-  }
-  if (!SETempty_(facet->coplanarset)) {
-    furthest= (pointT*)qh_setlast(facet->coplanarset);
-    if (qh_setsize (facet->coplanarset) < 6) {
-      fprintf(fp, "    - coplanar set (furthest p%d):\n", qh_pointid(furthest));
-      FOREACHpoint_(facet->coplanarset)
-	qh_printpoint(fp, "     ", point);
-    }else if (qh_setsize (facet->coplanarset) < 21) {
-      qh_printpoints(fp, "    - coplanar set:", facet->coplanarset);
-    }else {
-      fprintf(fp, "    - coplanar set:  %d points.", qh_setsize(facet->coplanarset));
-      qh_printpoint(fp, "  Furthest", furthest);
-    }
-    zinc_(Zdistio);
-    qh_distplane (furthest, facet, &dist);
-    fprintf(fp, "      furthest distance= %2.2g\n", dist);
-  }
-  qh_printvertices (fp, "    - vertices:", facet->vertices);
-  fprintf(fp, "    - neighboring facets: ");
-  FOREACHneighbor_(facet) {
-    if (neighbor == qh_MERGEridge)
-      fprintf(fp, " MERGE");
-    else if (neighbor == qh_DUPLICATEridge)
-      fprintf(fp, " DUP");
-    else
-      fprintf(fp, " f%d", neighbor->id);
-  }
-  fprintf(fp, "\n");
-  qh RANDOMdist= qh old_randomdist;
-} /* printfacetheader */
-
-
-/*---------------------------------
-  
-  qh_printfacetridges( fp, facet )
-    prints ridges of a facet to fp
-
-  notes:
-    ridges printed in neighbor order
-    assumes the ridges exist
-    for 'f' output
-*/
-void qh_printfacetridges(FILE *fp, facetT *facet) {
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int numridges= 0;
-
-
-  if (facet->visible && qh NEWfacets) {
-    fprintf(fp, "    - ridges (ids may be garbage):");
-    FOREACHridge_(facet->ridges)
-      fprintf(fp, " r%d", ridge->id);
-    fprintf(fp, "\n");
-  }else {
-    fprintf(fp, "    - ridges:\n");
-    FOREACHridge_(facet->ridges)
-      ridge->seen= False;
-    if (qh hull_dim == 3) {
-      ridge= SETfirstt_(facet->ridges, ridgeT);
-      while (ridge && !ridge->seen) {
-	ridge->seen= True;
-	qh_printridge(fp, ridge);
-	numridges++;
-	ridge= qh_nextridge3d (ridge, facet, NULL);
-	}
-    }else {
-      FOREACHneighbor_(facet) {
-	FOREACHridge_(facet->ridges) {
-	  if (otherfacet_(ridge,facet) == neighbor) {
-	    ridge->seen= True;
-	    qh_printridge(fp, ridge);
-	    numridges++;
-	  }
-	}
-      }
-    }
-    if (numridges != qh_setsize (facet->ridges)) {
-      fprintf (fp, "     - all ridges:");
-      FOREACHridge_(facet->ridges) 
-	fprintf (fp, " r%d", ridge->id);
-        fprintf (fp, "\n");
-    }
-    FOREACHridge_(facet->ridges) {
-      if (!ridge->seen) 
-	qh_printridge(fp, ridge);
-    }
-  }
-} /* printfacetridges */
-
-/*---------------------------------
-  
-  qh_printfacets( fp, format, facetlist, facets, printall )
-    prints facetlist and/or facet set in output format
-  
-  notes:
-    also used for specialized formats ('FO' and summary)
-    turns off 'Rn' option since want actual numbers
-*/
-void qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
-  facetT *facet, **facetp;
-  setT *vertices;
-  coordT *center;
-  realT outerplane, innerplane;
-
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  if (qh CDDoutput && (format == qh_PRINTcentrums || format == qh_PRINTpointintersect || format == qh_PRINToff))
-    fprintf (qh ferr, "qhull warning: CDD format is not available for centrums, halfspace\nintersections, and OFF file format.\n");
-  if (format == qh_PRINTnone)
-    ; /* print nothing */
-  else if (format == qh_PRINTaverage) {
-    vertices= qh_facetvertices (facetlist, facets, printall);
-    center= qh_getcenter (vertices);
-    fprintf (fp, "%d 1\n", qh hull_dim);
-    qh_printpointid (fp, NULL, qh hull_dim, center, -1);
-    qh_memfree (center, qh normal_size);
-    qh_settempfree (&vertices);
-  }else if (format == qh_PRINTextremes) {
-    if (qh DELAUNAY)
-      qh_printextremes_d (fp, facetlist, facets, printall);
-    else if (qh hull_dim == 2)
-      qh_printextremes_2d (fp, facetlist, facets, printall);
-    else 
-      qh_printextremes (fp, facetlist, facets, printall);
-  }else if (format == qh_PRINToptions)
-    fprintf(fp, "Options selected for Qhull %s:\n%s\n", qh_VERSION, qh qhull_options);
-  else if (format == qh_PRINTpoints && !qh VORONOI)
-    qh_printpoints_out (fp, facetlist, facets, printall);
-  else if (format == qh_PRINTqhull)
-    fprintf (fp, "%s | %s\n", qh rbox_command, qh qhull_command);
-  else if (format == qh_PRINTsize) {
-    fprintf (fp, "0\n2 ");
-    fprintf (fp, qh_REAL_1, qh totarea);
-    fprintf (fp, qh_REAL_1, qh totvol);
-    fprintf (fp, "\n");
-  }else if (format == qh_PRINTsummary) {
-    qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
-    vertices= qh_facetvertices (facetlist, facets, printall); 
-    fprintf (fp, "10 %d %d %d %d %d %d %d %d %d %d\n2 ", qh hull_dim, 
-                qh num_points + qh_setsize (qh other_points),
-                qh num_vertices, qh num_facets - qh num_visible,
-                qh_setsize (vertices), numfacets, numcoplanars, 
-		numfacets - numsimplicial, zzval_(Zdelvertextot), 
-		numtricoplanars);
-    qh_settempfree (&vertices);
-    qh_outerinner (NULL, &outerplane, &innerplane);
-    fprintf (fp, qh_REAL_2n, outerplane, innerplane);
-  }else if (format == qh_PRINTvneighbors)
-    qh_printvneighbors (fp, facetlist, facets, printall);
-  else if (qh VORONOI && format == qh_PRINToff)
-    qh_printvoronoi (fp, format, facetlist, facets, printall);
-  else if (qh VORONOI && format == qh_PRINTgeom) {
-    qh_printbegin (fp, format, facetlist, facets, printall);
-    qh_printvoronoi (fp, format, facetlist, facets, printall);
-    qh_printend (fp, format, facetlist, facets, printall);
-  }else if (qh VORONOI 
-  && (format == qh_PRINTvertices || format == qh_PRINTinner || format == qh_PRINTouter))
-    qh_printvdiagram (fp, format, facetlist, facets, printall);
-  else {
-    qh_printbegin (fp, format, facetlist, facets, printall);
-    FORALLfacet_(facetlist)
-      qh_printafacet (fp, format, facet, printall);
-    FOREACHfacet_(facets) 
-      qh_printafacet (fp, format, facet, printall);
-    qh_printend (fp, format, facetlist, facets, printall);
-  }
-  qh RANDOMdist= qh old_randomdist;
-} /* printfacets */
-
-
-/*---------------------------------
-  
-  qh_printhelp_degenerate( fp )
-    prints descriptive message for precision error
-
-  notes:
-    no message if qh_QUICKhelp
-*/
-void qh_printhelp_degenerate(FILE *fp) {
-  
-  if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2) 
-    fprintf(fp, "\n\
-A Qhull error has occurred.  Qhull should have corrected the above\n\
-precision error.  Please send the input and all of the output to\n\
-qhull_bug@geom.umn.edu\n");
-  else if (!qh_QUICKhelp) {
-    fprintf(fp, "\n\
-Precision problems were detected during construction of the convex hull.\n\
-This occurs because convex hull algorithms assume that calculations are\n\
-exact, but floating-point arithmetic has roundoff errors.\n\
-\n\
-To correct for precision problems, do not use 'Q0'.  By default, Qhull\n\
-selects 'C-0' or 'Qx' and merges non-convex facets.  With option 'QJ',\n\
-Qhull joggles the input to prevent precision problems.  See \"Imprecision\n\
-in Qhull\" (qh-impre.htm).\n\
-\n\
-If you use 'Q0', the output may include\n\
-coplanar ridges, concave ridges, and flipped facets.  In 4-d and higher,\n\
-Qhull may produce a ridge with four neighbors or two facets with the same \n\
-vertices.  Qhull reports these events when they occur.  It stops when a\n\
-concave ridge, flipped facet, or duplicate facet occurs.\n");
-#if REALfloat
-    fprintf (fp, "\
-\n\
-Qhull is currently using single precision arithmetic.  The following\n\
-will probably remove the precision problems:\n\
-  - recompile qhull for double precision (#define REALfloat 0 in user.h).\n");
-#endif
-    if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
-      fprintf( fp, "\
-\n\
-When computing the Delaunay triangulation of coordinates > 1.0,\n\
-  - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
-    if (qh DELAUNAY && !qh ATinfinity) 
-      fprintf( fp, "\
-When computing the Delaunay triangulation:\n\
-  - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
- 
-    fprintf(fp, "\
-\n\
-If you need triangular output:\n\
-  - use option 'Qt' to triangulate the output\n\
-  - use option 'QJ' to joggle the input points and remove precision errors\n\
-  - use option 'Ft'.  It triangulates non-simplicial facets with added points.\n\
-\n\
-If you must use 'Q0',\n\
-try one or more of the following options.  They can not guarantee an output.\n\
-  - use 'QbB' to scale the input to a cube.\n\
-  - use 'Po' to produce output and prevent partitioning for flipped facets\n\
-  - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
-  - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
-  - options 'Qf', 'Qbb', and 'QR0' may also help\n",
-               qh DISTround);
-    fprintf(fp, "\
-\n\
-To guarantee simplicial output:\n\
-  - use option 'Qt' to triangulate the output\n\
-  - use option 'QJ' to joggle the input points and remove precision errors\n\
-  - use option 'Ft' to triangulate the output by adding points\n\
-  - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
-");
-  }
-} /* printhelp_degenerate */
-
-
-/*---------------------------------
-  
-  qh_printhelp_singular( fp )
-    prints descriptive message for singular input
-*/
-void qh_printhelp_singular(FILE *fp) {
-  facetT *facet;
-  vertexT *vertex, **vertexp;
-  realT min, max, *coord, dist;
-  int i,k;
-  
-  fprintf(fp, "\n\
-The input to qhull appears to be less than %d dimensional, or a\n\
-computation has overflowed.\n\n\
-Qhull could not construct a clearly convex simplex from points:\n",
-           qh hull_dim);
-  qh_printvertexlist (fp, "", qh facet_list, NULL, qh_ALL);
-  if (!qh_QUICKhelp)
-    fprintf(fp, "\n\
-The center point is coplanar with a facet, or a vertex is coplanar\n\
-with a neighboring facet.  The maximum round off error for\n\
-computing distances is %2.2g.  The center point, facets and distances\n\
-to the center point are as follows:\n\n", qh DISTround);
-  qh_printpointid (fp, "center point", qh hull_dim, qh interior_point, -1);
-  fprintf (fp, "\n");
-  FORALLfacets {
-    fprintf (fp, "facet");
-    FOREACHvertex_(facet->vertices)
-      fprintf (fp, " p%d", qh_pointid(vertex->point));
-    zinc_(Zdistio);
-    qh_distplane(qh interior_point, facet, &dist);
-    fprintf (fp, " distance= %4.2g\n", dist);
-  }
-  if (!qh_QUICKhelp) {
-    if (qh HALFspace) 
-      fprintf (fp, "\n\
-These points are the dual of the given halfspaces.  They indicate that\n\
-the intersection is degenerate.\n");
-    fprintf (fp,"\n\
-These points either have a maximum or minimum x-coordinate, or\n\
-they maximize the determinant for k coordinates.  Trial points\n\
-are first selected from points that maximize a coordinate.\n");
-    if (qh hull_dim >= qh_INITIALmax)
-      fprintf (fp, "\n\
-Because of the high dimension, the min x-coordinate and max-coordinate\n\
-points are used if the determinant is non-zero.  Option 'Qs' will\n\
-do a better, though much slower, job.  Instead of 'Qs', you can change\n\
-the points by randomly rotating the input with 'QR0'.\n");
-  }
-  fprintf (fp, "\nThe min and max coordinates for each dimension are:\n");
-  for (k=0; k < qh hull_dim; k++) {
-    min= REALmax;
-    max= -REALmin;
-    for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
-      maximize_(max, *coord);
-      minimize_(min, *coord);
-    }
-    fprintf (fp, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
-  }
-  if (!qh_QUICKhelp) {
-    fprintf (fp, "\n\
-If the input should be full dimensional, you have several options that\n\
-may determine an initial simplex:\n\
-  - use 'QJ'  to joggle the input and make it full dimensional\n\
-  - use 'QbB' to scale the points to the unit cube\n\
-  - use 'QR0' to randomly rotate the input for different maximum points\n\
-  - use 'Qs'  to search all points for the initial simplex\n\
-  - use 'En'  to specify a maximum roundoff error less than %2.2g.\n\
-  - trace execution with 'T3' to see the determinant for each point.\n",
-                     qh DISTround);
-#if REALfloat
-    fprintf (fp, "\
-  - recompile qhull for double precision (#define REALfloat 0 in qhull.h).\n");
-#endif
-    fprintf (fp, "\n\
-If the input is lower dimensional:\n\
-  - use 'QJ' to joggle the input and make it full dimensional\n\
-  - use 'Qbk:0Bk:0' to delete coordinate k from the input.  You should\n\
-    pick the coordinate with the least range.  The hull will have the\n\
-    correct topology.\n\
-  - determine the flat containing the points, rotate the points\n\
-    into a coordinate plane, and delete the other coordinates.\n\
-  - add one or more points to make the input full dimensional.\n\
-");
-    if (qh DELAUNAY && !qh ATinfinity)
-      fprintf (fp, "\n\n\
-This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\
-  - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\
-  - or use 'QJ' to joggle the input and avoid co-circular data\n");
-  }
-} /* printhelp_singular */
-
-/*---------------------------------
-  
-  qh_printhyperplaneintersection( fp, facet1, facet2, vertices, color )
-    print Geomview OFF or 4OFF for the intersection of two hyperplanes in 3-d or 4-d
-*/
-void qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
-		   setT *vertices, realT color[3]) {
-  realT costheta, denominator, dist1, dist2, s, t, mindenom, p[4];
-  vertexT *vertex, **vertexp;
-  int i, k;
-  boolT nearzero1, nearzero2;
-  
-  costheta= qh_getangle(facet1->normal, facet2->normal);
-  denominator= 1 - costheta * costheta;
-  i= qh_setsize(vertices);
-  if (qh hull_dim == 3)
-    fprintf(fp, "VECT 1 %d 1 %d 1 ", i, i);
-  else if (qh hull_dim == 4 && qh DROPdim >= 0)
-    fprintf(fp, "OFF 3 1 1 ");
-  else
-    qh printoutvar++;
-  fprintf (fp, "# intersect f%d f%d\n", facet1->id, facet2->id);
-  mindenom= 1 / (10.0 * qh MAXabs_coord);
-  FOREACHvertex_(vertices) {
-    zadd_(Zdistio, 2);
-    qh_distplane(vertex->point, facet1, &dist1);
-    qh_distplane(vertex->point, facet2, &dist2);
-    s= qh_divzero (-dist1 + costheta * dist2, denominator,mindenom,&nearzero1);
-    t= qh_divzero (-dist2 + costheta * dist1, denominator,mindenom,&nearzero2);
-    if (nearzero1 || nearzero2)
-      s= t= 0.0;
-    for(k= qh hull_dim; k--; )
-      p[k]= vertex->point[k] + facet1->normal[k] * s + facet2->normal[k] * t;
-    if (qh PRINTdim <= 3) {
-      qh_projectdim3 (p, p);
-      fprintf(fp, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]);
-    }else 
-      fprintf(fp, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]);
-    if (nearzero1+nearzero2)
-      fprintf (fp, "p%d (coplanar facets)\n", qh_pointid (vertex->point));
-    else
-      fprintf (fp, "projected p%d\n", qh_pointid (vertex->point));
-  }
-  if (qh hull_dim == 3)
-    fprintf(fp, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]); 
-  else if (qh hull_dim == 4 && qh DROPdim >= 0)  
-    fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
-} /* printhyperplaneintersection */
-
-/*---------------------------------
-  
-  qh_printline3geom( fp, pointA, pointB, color )
-    prints a line as a VECT
-    prints 0's for qh.DROPdim
-  
-  notes:
-    if pointA == pointB, 
-      it's a 1 point VECT
-*/
-void qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]) {
-  int k;
-  realT pA[4], pB[4];
-
-  qh_projectdim3(pointA, pA);
-  qh_projectdim3(pointB, pB);
-  if ((fabs(pA[0] - pB[0]) > 1e-3) || 
-      (fabs(pA[1] - pB[1]) > 1e-3) || 
-      (fabs(pA[2] - pB[2]) > 1e-3)) {
-    fprintf (fp, "VECT 1 2 1 2 1\n");
-    for (k= 0; k < 3; k++)
-       fprintf (fp, "%8.4g ", pB[k]);
-    fprintf (fp, " # p%d\n", qh_pointid (pointB));
-  }else
-    fprintf (fp, "VECT 1 1 1 1 1\n");
-  for (k=0; k < 3; k++)
-    fprintf (fp, "%8.4g ", pA[k]);
-  fprintf (fp, " # p%d\n", qh_pointid (pointA));
-  fprintf (fp, "%8.4g %8.4g %8.4g 1\n", color[0], color[1], color[2]);
-}
-
-/*---------------------------------
-  
-  qh_printneighborhood( fp, format, facetA, facetB, printall )
-    print neighborhood of one or two facets
-
-  notes:
-    calls qh_findgood_all() 
-    bumps qh.visit_id
-*/
-void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall) {
-  facetT *neighbor, **neighborp, *facet;
-  setT *facets;
-
-  if (format == qh_PRINTnone)
-    return;
-  qh_findgood_all (qh facet_list);
-  if (facetA == facetB)
-    facetB= NULL;
-  facets= qh_settemp (2*(qh_setsize (facetA->neighbors)+1));
-  qh visit_id++;
-  for (facet= facetA; facet; facet= ((facet == facetA) ? facetB : NULL)) {
-    if (facet->visitid != qh visit_id) {
-      facet->visitid= qh visit_id;
-      qh_setappend (&facets, facet);
-    }
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid == qh visit_id)
-        continue;
-      neighbor->visitid= qh visit_id;
-      if (printall || !qh_skipfacet (neighbor))
-        qh_setappend (&facets, neighbor);
-    }
-  }
-  qh_printfacets (fp, format, NULL, facets, printall);
-  qh_settempfree (&facets);
-} /* printneighborhood */
-
-/*---------------------------------
-  
-  qh_printpoint( fp, string, point )
-  qh_printpointid( fp, string, dim, point, id )
-    prints the coordinates of a point
-
-  returns:
-    if string is defined
-      prints 'string p%d' (skips p%d if id=-1)
-
-  notes:
-    nop if point is NULL
-    prints id unless it is undefined (-1)
-*/
-void qh_printpoint(FILE *fp, char *string, pointT *point) {
-  int id= qh_pointid( point);
-
-  qh_printpointid( fp, string, qh hull_dim, point, id);
-} /* printpoint */
-
-void qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id) {
-  int k;
-  realT r; /*bug fix*/
-  
-  if (!point)
-    return;
-  if (string) {
-    fputs (string, fp);
-   if (id != -1)
-      fprintf(fp, " p%d: ", id);
-  }
-  for(k= dim; k--; ) {
-    r= *point++;
-    if (string)
-      fprintf(fp, " %8.4g", r);
-    else
-      fprintf(fp, qh_REAL_1, r);
-  }
-  fprintf(fp, "\n");
-} /* printpointid */
-
-/*---------------------------------
-  
-  qh_printpoint3( fp, point )
-    prints 2-d, 3-d, or 4-d point as Geomview 3-d coordinates
-*/
-void qh_printpoint3 (FILE *fp, pointT *point) {
-  int k;
-  realT p[4];
-  
-  qh_projectdim3 (point, p);
-  for (k=0; k < 3; k++)
-    fprintf (fp, "%8.4g ", p[k]);
-  fprintf (fp, " # p%d\n", qh_pointid (point));
-} /* printpoint3 */
-
-/*----------------------------------------
--printpoints- print pointids for a set of points starting at index 
-   see geom.c
-*/
-
-/*---------------------------------
-  
-  qh_printpoints_out( fp, facetlist, facets, printall )
-    prints vertices, coplanar/inside points, for facets by their point coordinates
-    allows qh.CDDoutput
-
-  notes:
-    same format as qhull input
-    if no coplanar/interior points,
-      same order as qh_printextremes
-*/
-void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  int allpoints= qh num_points + qh_setsize (qh other_points);
-  int numpoints=0, point_i, point_n;
-  setT *vertices, *points;
-  facetT *facet, **facetp;
-  pointT *point, **pointp;
-  vertexT *vertex, **vertexp;
-  int id;
-
-  points= qh_settemp (allpoints);
-  qh_setzero (points, 0, allpoints);
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  FOREACHvertex_(vertices) {
-    id= qh_pointid (vertex->point);
-    if (id >= 0)
-      SETelem_(points, id)= vertex->point;
-  }
-  if (qh KEEPinside || qh KEEPcoplanar || qh KEEPnearinside) {
-    FORALLfacet_(facetlist) {
-      if (!printall && qh_skipfacet(facet))
-        continue;
-      FOREACHpoint_(facet->coplanarset) {
-        id= qh_pointid (point);
-        if (id >= 0)
-          SETelem_(points, id)= point;
-      }
-    }
-    FOREACHfacet_(facets) {
-      if (!printall && qh_skipfacet(facet))
-        continue;
-      FOREACHpoint_(facet->coplanarset) {
-        id= qh_pointid (point);
-        if (id >= 0)
-          SETelem_(points, id)= point;
-      }
-    }
-  }
-  qh_settempfree (&vertices);
-  FOREACHpoint_i_(points) {
-    if (point)
-      numpoints++;
-  }
-  if (qh CDDoutput)
-    fprintf (fp, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
-             qh qhull_command, numpoints, qh hull_dim + 1);
-  else
-    fprintf (fp, "%d\n%d\n", qh hull_dim, numpoints);
-  FOREACHpoint_i_(points) {
-    if (point) {
-      if (qh CDDoutput)
-	fprintf (fp, "1 ");
-      qh_printpoint (fp, NULL, point);
-    }
-  }
-  if (qh CDDoutput)
-    fprintf (fp, "end\n");
-  qh_settempfree (&points);
-} /* printpoints_out */
-  
-
-/*---------------------------------
-  
-  qh_printpointvect( fp, point, normal, center, radius, color )
-    prints a 2-d, 3-d, or 4-d point as 3-d VECT's relative to normal or to center point
-*/
-void qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]) {
-  realT diff[4], pointA[4];
-  int k;
-  
-  for (k= qh hull_dim; k--; ) {
-    if (center)
-      diff[k]= point[k]-center[k];
-    else if (normal) 
-      diff[k]= normal[k];
-    else
-      diff[k]= 0;
-  }
-  if (center)
-    qh_normalize2 (diff, qh hull_dim, True, NULL, NULL);
-  for (k= qh hull_dim; k--; ) 
-    pointA[k]= point[k]+diff[k] * radius;
-  qh_printline3geom (fp, point, pointA, color);
-} /* printpointvect */  
-
-/*---------------------------------
-  
-  qh_printpointvect2( fp, point, normal, center, radius )
-    prints a 2-d, 3-d, or 4-d point as 2 3-d VECT's for an imprecise point
-*/
-void qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius) {
-  realT red[3]={1, 0, 0}, yellow[3]={1, 1, 0};
-
-  qh_printpointvect (fp, point, normal, center, radius, red);
-  qh_printpointvect (fp, point, normal, center, -radius, yellow);
-} /* printpointvect2 */
-
-/*---------------------------------
-  
-  qh_printridge( fp, ridge )
-    prints the information in a ridge
-
-  notes:
-    for qh_printfacetridges()
-*/
-void qh_printridge(FILE *fp, ridgeT *ridge) {
-  
-  fprintf(fp, "     - r%d", ridge->id);
-  if (ridge->tested)
-    fprintf (fp, " tested");
-  if (ridge->nonconvex)
-    fprintf (fp, " nonconvex");
-  fprintf (fp, "\n");
-  qh_printvertices (fp, "           vertices:", ridge->vertices);
-  if (ridge->top && ridge->bottom)
-    fprintf(fp, "           between f%d and f%d\n",
-	    ridge->top->id, ridge->bottom->id);
-} /* printridge */
-
-/*---------------------------------
-  
-  qh_printspheres( fp, vertices, radius )
-    prints 3-d vertices as OFF spheres
-
-  notes:
-    inflated octahedron from Stuart Levy earth/mksphere2
-*/
-void qh_printspheres(FILE *fp, setT *vertices, realT radius) {
-  vertexT *vertex, **vertexp;
-
-  qh printoutnum++;
-  fprintf (fp, "{appearance {-edge -normal normscale 0} {\n\
-INST geom {define vsphere OFF\n\
-18 32 48\n\
-\n\
-0 0 1\n\
-1 0 0\n\
-0 1 0\n\
--1 0 0\n\
-0 -1 0\n\
-0 0 -1\n\
-0.707107 0 0.707107\n\
-0 -0.707107 0.707107\n\
-0.707107 -0.707107 0\n\
--0.707107 0 0.707107\n\
--0.707107 -0.707107 0\n\
-0 0.707107 0.707107\n\
--0.707107 0.707107 0\n\
-0.707107 0.707107 0\n\
-0.707107 0 -0.707107\n\
-0 0.707107 -0.707107\n\
--0.707107 0 -0.707107\n\
-0 -0.707107 -0.707107\n\
-\n\
-3 0 6 11\n\
-3 0 7 6	\n\
-3 0 9 7	\n\
-3 0 11 9\n\
-3 1 6 8	\n\
-3 1 8 14\n\
-3 1 13 6\n\
-3 1 14 13\n\
-3 2 11 13\n\
-3 2 12 11\n\
-3 2 13 15\n\
-3 2 15 12\n\
-3 3 9 12\n\
-3 3 10 9\n\
-3 3 12 16\n\
-3 3 16 10\n\
-3 4 7 10\n\
-3 4 8 7\n\
-3 4 10 17\n\
-3 4 17 8\n\
-3 5 14 17\n\
-3 5 15 14\n\
-3 5 16 15\n\
-3 5 17 16\n\
-3 6 13 11\n\
-3 7 8 6\n\
-3 9 10 7\n\
-3 11 12 9\n\
-3 14 8 17\n\
-3 15 13 14\n\
-3 16 12 15\n\
-3 17 10 16\n} transforms { TLIST\n");
-  FOREACHvertex_(vertices) {
-    fprintf(fp, "%8.4g 0 0 0 # v%d\n 0 %8.4g 0 0\n0 0 %8.4g 0\n",
-      radius, vertex->id, radius, radius);
-    qh_printpoint3 (fp, vertex->point);
-    fprintf (fp, "1\n");
-  }
-  fprintf (fp, "}}}\n");
-} /* printspheres */
-
-
-/*----------------------------------------------
--printsummary-
-                see qhull.c
-*/
-
-/*---------------------------------
-  
-  qh_printvdiagram( fp, format, facetlist, facets, printall )
-    print voronoi diagram
-      # of pairs of input sites
-      #indices site1 site2 vertex1 ...
-    
-    sites indexed by input point id
-      point 0 is the first input point
-    vertices indexed by 'o' and 'p' order
-      vertex 0 is the 'vertex-at-infinity'
-      vertex 1 is the first Voronoi vertex
-
-  see:
-    qh_printvoronoi()
-    qh_eachvoronoi_all()
-
-  notes:
-    if all facets are upperdelaunay, 
-      prints upper hull (furthest-site Voronoi diagram)
-*/
-void qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  setT *vertices;
-  int totcount, numcenters;
-  boolT islower;
-  qh_RIDGE innerouter= qh_RIDGEall;
-  printvridgeT printvridge= NULL;
-
-  if (format == qh_PRINTvertices) {
-    innerouter= qh_RIDGEall;
-    printvridge= qh_printvridge;
-  }else if (format == qh_PRINTinner) {
-    innerouter= qh_RIDGEinner;
-    printvridge= qh_printvnorm;
-  }else if (format == qh_PRINTouter) {
-    innerouter= qh_RIDGEouter;
-    printvridge= qh_printvnorm;
-  }else {
-    fprintf(qh ferr, "qh_printvdiagram: unknown print format %d.\n", format);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  vertices= qh_markvoronoi (facetlist, facets, printall, &islower, &numcenters);
-  totcount= qh_printvdiagram2 (NULL, NULL, vertices, innerouter, False);
-  fprintf (fp, "%d\n", totcount);
-  totcount= qh_printvdiagram2 (fp, printvridge, vertices, innerouter, True /* inorder*/);
-  qh_settempfree (&vertices);
-#if 0  /* for testing qh_eachvoronoi_all */
-  fprintf (fp, "\n");
-  totcount= qh_eachvoronoi_all(fp, printvridge, qh UPPERdelaunay, innerouter, True /* inorder*/);
-  fprintf (fp, "%d\n", totcount);
-#endif
-} /* printvdiagram */
-  
-/*---------------------------------
-  
-  qh_printvdiagram2( fp, printvridge, vertices, innerouter, inorder )
-    visit all pairs of input sites (vertices) for selected Voronoi vertices
-    vertices may include NULLs
-  
-  innerouter:
-    qh_RIDGEall   print inner ridges (bounded) and outer ridges (unbounded)
-    qh_RIDGEinner print only inner ridges
-    qh_RIDGEouter print only outer ridges
-  
-  inorder:
-    print 3-d Voronoi vertices in order
-  
-  assumes:
-    qh_markvoronoi marked facet->visitid for Voronoi vertices
-    all facet->seen= False
-    all facet->seen2= True
-  
-  returns:
-    total number of Voronoi ridges 
-    if printvridge,
-      calls printvridge( fp, vertex, vertexA, centers) for each ridge
-      [see qh_eachvoronoi()]
-  
-  see:
-    qh_eachvoronoi_all()
-*/
-int qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder) {
-  int totcount= 0;
-  int vertex_i, vertex_n;
-  vertexT *vertex;
-
-  FORALLvertices 
-    vertex->seen= False;
-  FOREACHvertex_i_(vertices) {
-    if (vertex) {
-      if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex)
-	continue;
-      totcount += qh_eachvoronoi (fp, printvridge, vertex, !qh_ALL, innerouter, inorder);
-    }
-  }
-  return totcount;
-} /* printvdiagram2 */
-  
-/*---------------------------------
-  
-  qh_printvertex( fp, vertex )
-    prints the information in a vertex
-*/
-void qh_printvertex(FILE *fp, vertexT *vertex) {
-  pointT *point;
-  int k, count= 0;
-  facetT *neighbor, **neighborp;
-  realT r; /*bug fix*/
-
-  if (!vertex) {
-    fprintf (fp, "  NULLvertex\n");
-    return;
-  }
-  fprintf(fp, "- p%d (v%d):", qh_pointid(vertex->point), vertex->id);
-  point= vertex->point;
-  if (point) {
-    for(k= qh hull_dim; k--; ) {
-      r= *point++;
-      fprintf(fp, " %5.2g", r);
-    }
-  }
-  if (vertex->deleted)
-    fprintf(fp, " deleted");
-  if (vertex->delridge)
-    fprintf (fp, " ridgedeleted");
-  fprintf(fp, "\n");
-  if (vertex->neighbors) {
-    fprintf(fp, "  neighbors:");
-    FOREACHneighbor_(vertex) {
-      if (++count % 100 == 0)
-	fprintf (fp, "\n     ");
-      fprintf(fp, " f%d", neighbor->id);
-    }
-    fprintf(fp, "\n");
-  }
-} /* printvertex */
-
-
-/*---------------------------------
-  
-  qh_printvertexlist( fp, string, facetlist, facets, printall )
-    prints vertices used by a facetlist or facet set
-    tests qh_skipfacet() if !printall
-*/
-void qh_printvertexlist (FILE *fp, char* string, facetT *facetlist, 
-                         setT *facets, boolT printall) {
-  vertexT *vertex, **vertexp;
-  setT *vertices;
-  
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  fputs (string, fp);
-  FOREACHvertex_(vertices)
-    qh_printvertex(fp, vertex);
-  qh_settempfree (&vertices);
-} /* printvertexlist */
-
-
-/*---------------------------------
-  
-  qh_printvertices( fp, string, vertices )
-    prints vertices in a set
-*/
-void qh_printvertices(FILE *fp, char* string, setT *vertices) {
-  vertexT *vertex, **vertexp;
-  
-  fputs (string, fp);
-  FOREACHvertex_(vertices) 
-    fprintf (fp, " p%d (v%d)", qh_pointid(vertex->point), vertex->id);
-  fprintf(fp, "\n");
-} /* printvertices */
-
-/*---------------------------------
-  
-  qh_printvneighbors( fp, facetlist, facets, printall )
-    print vertex neighbors of vertices in facetlist and facets ('FN')
-
-  notes:
-    qh_countfacets clears facet->visitid for non-printed facets
-
-  design:
-    collect facet count and related statistics
-    if necessary, build neighbor sets for each vertex
-    collect vertices in facetlist and facets
-    build a point array for point->vertex and point->coplanar facet
-    for each point
-      list vertex neighbors or coplanar facet
-*/
-void qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall) {
-  int numfacets, numsimplicial, numridges, totneighbors, numneighbors, numcoplanars, numtricoplanars;
-  setT *vertices, *vertex_points, *coplanar_points;
-  int numpoints= qh num_points + qh_setsize (qh other_points);
-  vertexT *vertex, **vertexp;
-  int vertex_i, vertex_n;
-  facetT *facet, **facetp, *neighbor, **neighborp;
-  pointT *point, **pointp;
-
-  qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);  /* sets facet->visitid */
-  fprintf (fp, "%d\n", numpoints);
-  qh_vertexneighbors();
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  vertex_points= qh_settemp (numpoints);
-  coplanar_points= qh_settemp (numpoints);
-  qh_setzero (vertex_points, 0, numpoints);
-  qh_setzero (coplanar_points, 0, numpoints);
-  FOREACHvertex_(vertices)
-    qh_point_add (vertex_points, vertex->point, vertex);
-  FORALLfacet_(facetlist) {
-    FOREACHpoint_(facet->coplanarset)
-      qh_point_add (coplanar_points, point, facet);
-  }
-  FOREACHfacet_(facets) {
-    FOREACHpoint_(facet->coplanarset)
-      qh_point_add (coplanar_points, point, facet);
-  }
-  FOREACHvertex_i_(vertex_points) {
-    if (vertex) { 
-      numneighbors= qh_setsize (vertex->neighbors);
-      fprintf (fp, "%d", numneighbors);
-      if (qh hull_dim == 3)
-        qh_order_vertexneighbors (vertex);
-      else if (qh hull_dim >= 4)
-        qsort (SETaddr_(vertex->neighbors, facetT), numneighbors,
-             sizeof (facetT *), qh_compare_facetvisit);
-      FOREACHneighbor_(vertex) 
-        fprintf (fp, " %d", 
-		 neighbor->visitid ? neighbor->visitid - 1 : - neighbor->id);
-      fprintf (fp, "\n");
-    }else if ((facet= SETelemt_(coplanar_points, vertex_i, facetT)))
-      fprintf (fp, "1 %d\n",
-                  facet->visitid ? facet->visitid - 1 : - facet->id);
-    else
-      fprintf (fp, "0\n");
-  }
-  qh_settempfree (&coplanar_points);
-  qh_settempfree (&vertex_points);
-  qh_settempfree (&vertices);
-} /* printvneighbors */
-
-/*---------------------------------
-  
-  qh_printvoronoi( fp, format, facetlist, facets, printall )
-    print voronoi diagram in 'o' or 'G' format
-    for 'o' format
-      prints voronoi centers for each facet and for infinity
-      for each vertex, lists ids of printed facets or infinity
-      assumes facetlist and facets are disjoint
-    for 'G' format
-      prints an OFF object
-      adds a 0 coordinate to center
-      prints infinity but does not list in vertices
-
-  see:
-    qh_printvdiagram()
-
-  notes:
-    if 'o', 
-      prints a line for each point except "at-infinity"
-    if all facets are upperdelaunay, 
-      reverses lower and upper hull
-*/
-void qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int k, numcenters, numvertices= 0, numneighbors, numinf, vid=1, vertex_i, vertex_n;
-  facetT *facet, **facetp, *neighbor, **neighborp;
-  setT *vertices;
-  vertexT *vertex;
-  boolT islower;
-  unsigned int numfacets= (unsigned int) qh num_facets;
-
-  vertices= qh_markvoronoi (facetlist, facets, printall, &islower, &numcenters);
-  FOREACHvertex_i_(vertices) {
-    if (vertex) {
-      numvertices++;
-      numneighbors = numinf = 0;
-      FOREACHneighbor_(vertex) {
-        if (neighbor->visitid == 0)
-	  numinf= 1;
-        else if (neighbor->visitid < numfacets)
-          numneighbors++;
-      }
-      if (numinf && !numneighbors) {
-	SETelem_(vertices, vertex_i)= NULL;
-	numvertices--;
-      }
-    }
-  }
-  if (format == qh_PRINTgeom) 
-    fprintf (fp, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n", 
-                numcenters, numvertices);
-  else
-    fprintf (fp, "%d\n%d %d 1\n", qh hull_dim-1, numcenters, qh_setsize(vertices));
-  if (format == qh_PRINTgeom) {
-    for (k= qh hull_dim-1; k--; )
-      fprintf (fp, qh_REAL_1, 0.0);
-    fprintf (fp, " 0 # infinity not used\n");
-  }else {
-    for (k= qh hull_dim-1; k--; )
-      fprintf (fp, qh_REAL_1, qh_INFINITE);
-    fprintf (fp, "\n");
-  }
-  FORALLfacet_(facetlist) {
-    if (facet->visitid && facet->visitid < numfacets) {
-      if (format == qh_PRINTgeom)
-        fprintf (fp, "# %d f%d\n", vid++, facet->id);
-      qh_printcenter (fp, format, NULL, facet);
-    }
-  }
-  FOREACHfacet_(facets) {
-    if (facet->visitid && facet->visitid < numfacets) {
-      if (format == qh_PRINTgeom)
-        fprintf (fp, "# %d f%d\n", vid++, facet->id);
-      qh_printcenter (fp, format, NULL, facet);
-    }
-  }
-  FOREACHvertex_i_(vertices) {
-    numneighbors= 0;
-    numinf=0;
-    if (vertex) {
-      if (qh hull_dim == 3)
-        qh_order_vertexneighbors(vertex);
-      else if (qh hull_dim >= 4)
-        qsort (SETaddr_(vertex->neighbors, vertexT), 
-	     qh_setsize (vertex->neighbors),
-	     sizeof (facetT *), qh_compare_facetvisit);
-      FOREACHneighbor_(vertex) {
-        if (neighbor->visitid == 0)
-	  numinf= 1;
-	else if (neighbor->visitid < numfacets)
-          numneighbors++;
-      }
-    }
-    if (format == qh_PRINTgeom) {
-      if (vertex) {
-	fprintf (fp, "%d", numneighbors);
-	if (vertex) {
-	  FOREACHneighbor_(vertex) {
-	    if (neighbor->visitid && neighbor->visitid < numfacets)
-	      fprintf (fp, " %d", neighbor->visitid);
-	  }
-	}
-	fprintf (fp, " # p%d (v%d)\n", vertex_i, vertex->id);
-      }else
-	fprintf (fp, " # p%d is coplanar or isolated\n", vertex_i);
-    }else {
-      if (numinf)
-	numneighbors++;
-      fprintf (fp, "%d", numneighbors);
-      if (vertex) {
-        FOREACHneighbor_(vertex) {
-  	  if (neighbor->visitid == 0) {
-  	    if (numinf) {
-  	      numinf= 0;
-	      fprintf (fp, " %d", neighbor->visitid);
-	    }
-	  }else if (neighbor->visitid < numfacets)
-	    fprintf (fp, " %d", neighbor->visitid);
-	}
-      }
-      fprintf (fp, "\n");
-    }
-  }
-  if (format == qh_PRINTgeom)
-    fprintf (fp, "}\n");
-  qh_settempfree (&vertices);
-} /* printvoronoi */
-  
-/*---------------------------------
-  
-  qh_printvnorm( fp, vertex, vertexA, centers, unbounded )
-    print one separating plane of the Voronoi diagram for a pair of input sites
-    unbounded==True if centers includes vertex-at-infinity
-  
-  assumes:
-    qh_ASvoronoi and qh_vertexneighbors() already set
-    
-  see:
-    qh_printvdiagram()
-    qh_eachvoronoi()
-*/
-void qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
-  pointT *normal;
-  realT offset;
-  int k;
-  
-  normal= qh_detvnorm (vertex, vertexA, centers, &offset);
-  fprintf (fp, "%d %d %d ", 
-      2+qh hull_dim, qh_pointid (vertex->point), qh_pointid (vertexA->point));
-  for (k= 0; k< qh hull_dim-1; k++)
-    fprintf (fp, qh_REAL_1, normal[k]);
-  fprintf (fp, qh_REAL_1, offset);
-  fprintf (fp, "\n");
-} /* printvnorm */
-
-/*---------------------------------
-  
-  qh_printvridge( fp, vertex, vertexA, centers, unbounded )
-    print one ridge of the Voronoi diagram for a pair of input sites
-    unbounded==True if centers includes vertex-at-infinity
-  
-  see:
-    qh_printvdiagram()
-  
-  notes:
-    the user may use a different function
-*/
-void qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
-  facetT *facet, **facetp;
-
-  fprintf (fp, "%d %d %d", qh_setsize (centers)+2, 
-       qh_pointid (vertex->point), qh_pointid (vertexA->point));
-  FOREACHfacet_(centers) 
-    fprintf (fp, " %d", facet->visitid);
-  fprintf (fp, "\n");
-} /* printvridge */
-
-/*---------------------------------
-  
-  qh_projectdim3( source, destination )
-    project 2-d 3-d or 4-d point to a 3-d point
-    uses qh.DROPdim and qh.hull_dim
-    source and destination may be the same
-    
-  notes:
-    allocate 4 elements to destination just in case
-*/
-void qh_projectdim3 (pointT *source, pointT *destination) {
-  int i,k;
-
-  for (k= 0, i=0; k < qh hull_dim; k++) {
-    if (qh hull_dim == 4) {
-      if (k != qh DROPdim)
-        destination[i++]= source[k];
-    }else if (k == qh DROPdim)
-      destination[i++]= 0;
-    else
-      destination[i++]= source[k];
-  }
-  while (i < 3)
-    destination[i++]= 0.0;
-} /* projectdim3 */
-
-/*---------------------------------
-  
-  qh_readfeasible( dim, remainder )
-    read feasible point from remainder string and qh.fin
-
-  returns:
-    number of lines read from qh.fin
-    sets qh.FEASIBLEpoint with malloc'd coordinates
-
-  notes:
-    checks for qh.HALFspace
-    assumes dim > 1
-
-  see:
-    qh_setfeasible
-*/
-int qh_readfeasible (int dim, char *remainder) {
-  boolT isfirst= True;
-  int linecount= 0, tokcount= 0;
-  char *s, *t, firstline[qh_MAXfirst+1];
-  coordT *coords, value;
-
-  if (!qh HALFspace) {
-    fprintf  (qh ferr, "qhull input error: feasible point (dim 1 coords) is only valid for halfspace intersection\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }  
-  if (qh feasible_string)
-    fprintf  (qh ferr, "qhull input warning: feasible point (dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n");
-  if (!(qh feasible_point= (coordT*)malloc (dim* sizeof(coordT)))) {
-    fprintf(qh ferr, "qhull error: insufficient memory for feasible point\n");
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  coords= qh feasible_point;
-  while ((s= (isfirst ?  remainder : fgets(firstline, qh_MAXfirst, qh fin)))) {
-    if (isfirst)
-      isfirst= False;
-    else
-      linecount++;
-    while (*s) {
-      while (isspace(*s))
-        s++;
-      value= qh_strtod (s, &t);
-      if (s == t)
-        break;
-      s= t;
-      *(coords++)= value;
-      if (++tokcount == dim) {
-        while (isspace (*s))
-          s++;
-        qh_strtod (s, &t);
-        if (s != t) {
-          fprintf (qh ferr, "qhull input error: coordinates for feasible point do not finish out the line: %s\n",
-               s);
-          qh_errexit (qh_ERRinput, NULL, NULL);
-        }
-        return linecount;
-      }
-    }
-  }
-  fprintf (qh ferr, "qhull input error: only %d coordinates.  Could not read %d-d feasible point.\n",
-           tokcount, dim);
-  qh_errexit (qh_ERRinput, NULL, NULL);
-  return 0;
-} /* readfeasible */
-
-/*---------------------------------
-  
-  qh_readpoints( numpoints, dimension, ismalloc )
-    read points from qh.fin into qh.first_point, qh.num_points
-    qh.fin is lines of coordinates, one per vertex, first line number of points
-    if 'rbox D4',
-      gives message
-    if qh.ATinfinity,
-      adds point-at-infinity for Delaunay triangulations
-
-  returns:
-    number of points, array of point coordinates, dimension, ismalloc True
-    if qh.DELAUNAY & !qh.PROJECTinput, projects points to paraboloid
-        and clears qh.PROJECTdelaunay
-    if qh.HALFspace, reads optional feasible point, reads halfspaces,
-        converts to dual.
-
-  for feasible point in "cdd format" in 3-d:
-    3 1
-    coordinates
-    comments
-    begin
-    n 4 real/integer
-    ...
-    end
-
-  notes:
-    dimension will change in qh_initqhull_globals if qh.PROJECTinput
-    uses malloc() since qh_mem not initialized
-    FIXUP: this routine needs rewriting
-*/
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) {
-  coordT *points, *coords, *infinity= NULL;
-  realT paraboloid, maxboloid= -REALmax, value;
-  realT *coordp= NULL, *offsetp= NULL, *normalp= NULL;
-  char *s, *t, firstline[qh_MAXfirst+1];
-  int diminput=0, numinput=0, dimfeasible= 0, newnum, k, tempi;
-  int firsttext=0, firstshort=0, firstlong=0, firstpoint=0;
-  int tokcount= 0, linecount=0, maxcount, coordcount=0;
-  boolT islong, isfirst= True, wasbegin= False;
-  boolT isdelaunay= qh DELAUNAY && !qh PROJECTinput;
-
-  if (qh CDDinput) {
-    while ((s= fgets(firstline, qh_MAXfirst, qh fin))) {
-      linecount++;
-      if (qh HALFspace && linecount == 1 && isdigit(*s)) {
-	dimfeasible= qh_strtol (s, &s);	
-	while (isspace(*s))
-          s++;
-        if (qh_strtol (s, &s) == 1)
-          linecount += qh_readfeasible (dimfeasible, s);
-        else
-          dimfeasible= 0;
-      }else if (!memcmp (firstline, "begin", 5) || !memcmp (firstline, "BEGIN", 5))
-        break;
-      else if (!*qh rbox_command)
-	strncat(qh rbox_command, s, sizeof (qh rbox_command)-1);
-    }
-    if (!s) {
-      fprintf (qh ferr, "qhull input error: missing \"begin\" for cdd-formated input\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-  }
-  while(!numinput && (s= fgets(firstline, qh_MAXfirst, qh fin))) {
-    linecount++;
-    if (!memcmp (s, "begin", 5) || !memcmp (s, "BEGIN", 5))
-      wasbegin= True;
-    while (*s) {
-      while (isspace(*s))
-        s++;
-      if (!*s)
-        break;
-      if (!isdigit(*s)) {
-        if (!*qh rbox_command) {
-          strncat(qh rbox_command, s, sizeof (qh rbox_command)-1);
-	  firsttext= linecount;
-        }
-        break;
-      }
-      if (!diminput) 
-        diminput= qh_strtol (s, &s);
-      else {
-        numinput= qh_strtol (s, &s);
-        if (numinput == 1 && diminput >= 2 && qh HALFspace && !qh CDDinput) {
-          linecount += qh_readfeasible (diminput, s); /* checks if ok */
-          dimfeasible= diminput;
-          diminput= numinput= 0;
-        }else 
-          break;
-      }
-    }
-  }
-  if (!s) {
-    fprintf(qh ferr, "qhull input error: short input file.  Did not find dimension and number of points\n");
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (diminput > numinput) {
-    tempi= diminput;	/* exchange dim and n, e.g., for cdd input format */
-    diminput= numinput;
-    numinput= tempi;
-  }
-  if (diminput < 2) {
-    fprintf(qh ferr,"qhull input error: dimension %d (first number) should be at least 2\n",
-	    diminput);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (isdelaunay) {
-    qh PROJECTdelaunay= False;
-    if (qh CDDinput)
-      *dimension= diminput;
-    else
-      *dimension= diminput+1;
-    *numpoints= numinput;
-    if (qh ATinfinity)
-      (*numpoints)++;
-  }else if (qh HALFspace) {
-    *dimension= diminput - 1;
-    *numpoints= numinput;
-    if (diminput < 3) {
-      fprintf(qh ferr,"qhull input error: dimension %d (first number, includes offset) should be at least 3 for halfspaces\n",
-  	    diminput);
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    if (dimfeasible) {
-      if (dimfeasible != *dimension) {
-        fprintf(qh ferr,"qhull input error: dimension %d of feasible point is not one less than dimension %d for halfspaces\n",
-          dimfeasible, diminput);
-        qh_errexit(qh_ERRinput, NULL, NULL);
-      }
-    }else 
-      qh_setfeasible (*dimension);
-  }else {
-    if (qh CDDinput) 
-      *dimension= diminput-1;
-    else
-      *dimension= diminput;
-    *numpoints= numinput;
-  }
-  qh normal_size= *dimension * sizeof(coordT); /* for tracing with qh_printpoint */
-  if (qh HALFspace) {
-    qh half_space= coordp= (coordT*) malloc (qh normal_size + sizeof(coordT));
-    if (qh CDDinput) {
-      offsetp= qh half_space;
-      normalp= offsetp + 1;
-    }else {
-      normalp= qh half_space;
-      offsetp= normalp + *dimension;
-    }
-  } 
-  qh maxline= diminput * (qh_REALdigits + 5);
-  maximize_(qh maxline, 500);
-  qh line= (char*)malloc ((qh maxline+1) * sizeof (char));
-  *ismalloc= True;  /* use malloc since memory not setup */
-  coords= points= qh temp_malloc= 
-        (coordT*)malloc((*numpoints)*(*dimension)*sizeof(coordT));
-  if (!coords || !qh line || (qh HALFspace && !qh half_space)) {
-    fprintf(qh ferr, "qhull error: insufficient memory to read %d points\n",
-	    numinput);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  if (isdelaunay && qh ATinfinity) {
-    infinity= points + numinput * (*dimension);
-    for (k= (*dimension) - 1; k--; )
-      infinity[k]= 0.0;
-  }
-  maxcount= numinput * diminput;
-  paraboloid= 0.0;
-  while ((s= (isfirst ?  s : fgets(qh line, qh maxline, qh fin)))) {
-    if (!isfirst) {
-      linecount++;
-      if (*s == 'e' || *s == 'E') {
-	if (!memcmp (s, "end", 3) || !memcmp (s, "END", 3)) {
-	  if (qh CDDinput )
-	    break;
-	  else if (wasbegin) 
-	    fprintf (qh ferr, "qhull input warning: the input appears to be in cdd format.  If so, use 'Fd'\n");
-	}
-      }
-    }
-    islong= False;
-    while (*s) {
-      while (isspace(*s))
-        s++;
-      value= qh_strtod (s, &t);
-      if (s == t) {
-        if (!*qh rbox_command)
- 	 strncat(qh rbox_command, s, sizeof (qh rbox_command)-1);
-        if (*s && !firsttext) 
-          firsttext= linecount;
-        if (!islong && !firstshort && coordcount)
-          firstshort= linecount;
-        break;
-      }
-      if (!firstpoint)
-	firstpoint= linecount;
-      s= t;
-      if (++tokcount > maxcount)
-        continue;
-      if (qh HALFspace) {
-	if (qh CDDinput) 
-	  *(coordp++)= -value; /* both coefficients and offset */
-	else
-	  *(coordp++)= value;
-      }else {
-        *(coords++)= value;
-        if (qh CDDinput && !coordcount) {
-          if (value != 1.0) {
-            fprintf (qh ferr, "qhull input error: for cdd format, point at line %d does not start with '1'\n",
-                   linecount);
-            qh_errexit (qh_ERRinput, NULL, NULL);
-          }
-          coords--;
-        }else if (isdelaunay) {
-	  paraboloid += value * value;
-	  if (qh ATinfinity) {
-	    if (qh CDDinput)
-	      infinity[coordcount-1] += value;
-	    else
-	      infinity[coordcount] += value;
-	  }
-	}
-      }
-      if (++coordcount == diminput) {
-        coordcount= 0;
-        if (isdelaunay) {
-          *(coords++)= paraboloid;
-          maximize_(maxboloid, paraboloid);
-          paraboloid= 0.0;
-        }else if (qh HALFspace) {
-          if (!qh_sethalfspace (*dimension, coords, &coords, normalp, offsetp, qh feasible_point)) {
-	    fprintf (qh ferr, "The halfspace was on line %d\n", linecount);
-	    if (wasbegin)
-	      fprintf (qh ferr, "The input appears to be in cdd format.  If so, you should use option 'Fd'\n");
-	    qh_errexit (qh_ERRinput, NULL, NULL);
-	  }
-          coordp= qh half_space;
-        }          
-        while (isspace(*s))
-          s++;
-        if (*s) {
-          islong= True;
-          if (!firstlong)
-            firstlong= linecount;
-	}
-      }
-    }
-    if (!islong && !firstshort && coordcount)
-      firstshort= linecount;
-    if (!isfirst && s - qh line >= qh maxline) {
-      fprintf(qh ferr, "qhull input error: line %d contained more than %d characters\n", 
-	      linecount, (int) (s - qh line));
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    isfirst= False;
-  }
-  if (tokcount != maxcount) {
-    newnum= fmin_(numinput, tokcount/diminput);
-    fprintf(qh ferr,"\
-qhull warning: instead of %d %d-dimensional points, input contains\n\
-%d points and %d extra coordinates.  Line %d is the first\npoint",
-       numinput, diminput, tokcount/diminput, tokcount % diminput, firstpoint);
-    if (firsttext)
-      fprintf(qh ferr, ", line %d is the first comment", firsttext);
-    if (firstshort)
-      fprintf(qh ferr, ", line %d is the first short\nline", firstshort);
-    if (firstlong)
-      fprintf(qh ferr, ", line %d is the first long line", firstlong);
-    fprintf(qh ferr, ".  Continue with %d points.\n", newnum);
-    numinput= newnum;
-    if (isdelaunay && qh ATinfinity) {
-      for (k= tokcount % diminput; k--; )
-	infinity[k] -= *(--coords);
-      *numpoints= newnum+1;
-    }else {
-      coords -= tokcount % diminput;
-      *numpoints= newnum;
-    }
-  }
-  if (isdelaunay && qh ATinfinity) {
-    for (k= (*dimension) -1; k--; )
-      infinity[k] /= numinput;
-    if (coords == infinity)
-      coords += (*dimension) -1;
-    else {
-      for (k= 0; k < (*dimension) -1; k++)
-	*(coords++)= infinity[k];
-    }
-    *(coords++)= maxboloid * 1.1;
-  }
-  if (qh rbox_command[0]) {
-    qh rbox_command[strlen(qh rbox_command)-1]= '\0';
-    if (!strcmp (qh rbox_command, "./rbox D4")) 
-      fprintf (qh ferr, "\n\
-This is the qhull test case.  If any errors or core dumps occur,\n\
-recompile qhull with 'make new'.  If errors still occur, there is\n\
-an incompatibility.  You should try a different compiler.  You can also\n\
-change the choices in user.h.  If you discover the source of the problem,\n\
-please send mail to qhull_bug@geom.umn.edu.\n\
-\n\
-Type 'qhull' for a short list of options.\n");
-  }
-  free (qh line);
-  qh line= NULL;
-  if (qh half_space) {
-    free (qh half_space);
-    qh half_space= NULL;
-  }
-  qh temp_malloc= NULL;
-  trace1((qh ferr,"qh_readpoints: read in %d %d-dimensional points\n",
-	  numinput, diminput));
-  return(points);
-} /* readpoints */
-
-
-/*---------------------------------
-  
-  qh_setfeasible( dim )
-    set qh.FEASIBLEpoint from qh.feasible_string in "n,n,n" or "n n n" format
-
-  notes:
-    "n,n,n" already checked by qh_initflags()
-    see qh_readfeasible()
-*/
-void qh_setfeasible (int dim) {
-  int tokcount= 0;
-  char *s;
-  coordT *coords, value;
-
-  if (!(s= qh feasible_string)) {
-    fprintf(qh ferr, "\
-qhull input error: halfspace intersection needs a feasible point.\n\
-Either prepend the input with 1 point or use 'Hn,n,n'.  See manual.\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (!(qh feasible_point= (pointT*)malloc (dim* sizeof(coordT)))) {
-    fprintf(qh ferr, "qhull error: insufficient memory for 'Hn,n,n'\n");
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  coords= qh feasible_point;
-  while (*s) {
-    value= qh_strtod (s, &s);
-    if (++tokcount > dim) {
-      fprintf (qh ferr, "qhull input warning: more coordinates for 'H%s' than dimension %d\n",
-          qh feasible_string, dim);
-      break;
-    }
-    *(coords++)= value;
-    if (*s)
-      s++;
-  }
-  while (++tokcount <= dim)    
-    *(coords++)= 0.0;
-} /* setfeasible */
-
-/*---------------------------------
-  
-  qh_skipfacet( facet )
-    returns 'True' if this facet is not to be printed 
-
-  notes:
-    based on the user provided slice thresholds and 'good' specifications
-*/
-boolT qh_skipfacet(facetT *facet) {
-  facetT *neighbor, **neighborp;
-
-  if (qh PRINTneighbors) {
-    if (facet->good)
-      return !qh PRINTgood;
-    FOREACHneighbor_(facet) {
-      if (neighbor->good)
-	return False;
-    }
-    return True;
-  }else if (qh PRINTgood)
-    return !facet->good;
-  else if (!facet->normal)
-    return True;
-  return (!qh_inthresholds (facet->normal, NULL));
-} /* skipfacet */
-
diff --git a/extern/qhull/src/io.h b/extern/qhull/src/io.h
deleted file mode 100644
index 351d56b3708..00000000000
--- a/extern/qhull/src/io.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
  ---------------------------------
-
-   io.h 
-   declarations of Input/Output functions
-
-   see README, qhull.h and io.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFio
-#define qhDEFio 1
-
-/*============ constants and flags ==================*/
-
-/*----------------------------------
-  
-  qh_MAXfirst
-    maximum length of first two lines of stdin
-*/
-#define qh_MAXfirst  200
-
-/*----------------------------------
-  
-  qh_MINradius
-    min radius for Gp and Gv, fraction of maxcoord
-*/
-#define qh_MINradius 0.02
-
-/*----------------------------------
-  
-  qh_GEOMepsilon
-    adjust outer planes for 'lines closer' and geomview roundoff.  
-    This prevents bleed through.
-*/
-#define qh_GEOMepsilon 2e-3
-
-/*----------------------------------
-  
-  qh_WHITESPACE
-    possible values of white space
-*/
-#define qh_WHITESPACE " \n\t\v\r\f"
-
-
-/*----------------------------------
-  
-  qh_RIDGE
-    to select which ridges to print in qh_eachvoronoi
-*/
-typedef enum
-{
-    qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
-}
-qh_RIDGE;
-
-/*----------------------------------
-  
-  printvridgeT
-    prints results of qh_printvdiagram
-
-  see:
-    qh_printvridge for an example
-*/
-typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-
-/*============== -prototypes in alphabetical order =========*/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void    qh_countfacets (facetT *facetlist, setT *facets, boolT printall, 
-              int *numfacetsp, int *numsimplicialp, int *totneighborsp, 
-              int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
-pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
-setT   *qh_detvridge (vertexT *vertex);
-setT   *qh_detvridge3 (vertexT *atvertex, vertexT *vertex);
-int     qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
-int     qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder);
-void	qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-void    qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane);
-void    qh_markkeep (facetT *facetlist);
-setT   *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp);
-void    qh_order_vertexneighbors(vertexT *vertex);
-void	qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall);
-void    qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void 	qh_printcenter (FILE *fp, int format, char *string, facetT *facet);
-void    qh_printcentrum (FILE *fp, facetT *facet, realT radius);
-void    qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printend4geom (FILE *fp, facetT *facet, int *num, boolT printall);
-void    qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void	qh_printfacet(FILE *fp, facetT *facet);
-void	qh_printfacet2math(FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]);
-void    qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
-			       facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3math (FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3vertex(FILE *fp, facetT *facet, int format);
-void	qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int format);
-void	qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format);
-void    qh_printfacetheader(FILE *fp, facetT *facet);
-void    qh_printfacetridges(FILE *fp, facetT *facet);
-void	qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void	qh_printhelp_degenerate(FILE *fp);
-void	qh_printhelp_singular(FILE *fp);
-void	qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
-  		   setT *vertices, realT color[3]);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void    qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
-void	qh_printpoint(FILE *fp, char *string, pointT *point);
-void	qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id);
-void    qh_printpoint3 (FILE *fp, pointT *point);
-void    qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
-void    qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
-void	qh_printridge(FILE *fp, ridgeT *ridge);
-void    qh_printspheres(FILE *fp, setT *vertices, realT radius);
-void    qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-int     qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
-void	qh_printvertex(FILE *fp, vertexT *vertex);
-void	qh_printvertexlist (FILE *fp, char* string, facetT *facetlist,
-                         setT *facets, boolT printall);
-void	qh_printvertices (FILE *fp, char* string, setT *vertices);
-void    qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall);
-void    qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void    qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void	qh_produce_output(void);
-void    qh_projectdim3 (pointT *source, pointT *destination);
-int     qh_readfeasible (int dim, char *remainder);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-void    qh_setfeasible (int dim);
-boolT	qh_skipfacet(facetT *facet);
-
-#endif /* qhDEFio */
diff --git a/extern/qhull/src/mem.c b/extern/qhull/src/mem.c
deleted file mode 100644
index 72934626684..00000000000
--- a/extern/qhull/src/mem.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
  ---------------------------------
-
-  mem.c 
-    memory management routines for qhull
-
-  This is a standalone program.
-   
-  To initialize memory:
-
-    qh_meminit (stderr);  
-    qh_meminitbuffers (qh IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
-    qh_memsize(sizeof(facetT));
-    qh_memsize(sizeof(facetT));
-    ...
-    qh_memsetup();
-    
-  To free up all memory buffers:
-    qh_memfreeshort (&curlong, &totlong);
-         
-  if qh_NOmem, 
-    malloc/free is used instead of mem.c
-
-  notes: 
-    uses Quickfit algorithm (freelists for commonly allocated sizes)
-    assumes small sizes for freelists (it discards the tail of memory buffers)
-   
-  see:
-    qh-mem.htm and mem.h
-    global.c (qh_initbuffers) for an example of using mem.c 
-   
-  copyright (c) 1993-2002 The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include "mem.h"
-
-#ifndef qhDEFqhull
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-void    qh_errexit(int exitcode, facetT *, ridgeT *);
-#endif
-
-/*============ -global data structure ==============
-    see mem.h for definition
-*/
-
-qhmemT qhmem= {0};     /* remove "= {0}" if this causes a compiler error */
-
-#ifndef qh_NOmem
-
-/*============= internal functions ==============*/
-  
-static int qh_intcompare(const void *i, const void *j);
-
-/*========== functions in alphabetical order ======== */
-
-/*---------------------------------
-  
-  qh_intcompare( i, j )
-    used by qsort and bsearch to compare two integers
-*/
-static int qh_intcompare(const void *i, const void *j) {
-  return(*((int *)i) - *((int *)j));
-} /* intcompare */
-
-
-/*----------------------------------
-   
-  qh_memalloc( insize )  
-    returns object of insize bytes
-    qhmem is the global memory structure 
-    
-  returns:
-    pointer to allocated memory 
-    errors if insufficient memory
-
-  notes:
-    use explicit type conversion to avoid type warnings on some compilers
-    actual object may be larger than insize
-    use qh_memalloc_() for inline code for quick allocations
-    logs allocations if 'T5'
-  
-  design:
-    if size < qhmem.LASTsize
-      if qhmem.freelists[size] non-empty
-        return first object on freelist
-      else
-        round up request to size of qhmem.freelists[size]
-        allocate new allocation buffer if necessary
-        allocate object from allocation buffer
-    else
-      allocate object with malloc()
-*/
-void *qh_memalloc(int insize) {
-  void **freelistp, *newbuffer;
-  int index, size;
-  int outsize, bufsize;
-  void *object;
-
-  if ((unsigned) insize <= (unsigned) qhmem.LASTsize) {
-    index= qhmem.indextable[insize];
-    freelistp= qhmem.freelists+index;
-    if ((object= *freelistp)) {
-      qhmem.cntquick++;  
-      *freelistp= *((void **)*freelistp);  /* replace freelist with next object */
-      return (object);
-    }else {
-      outsize= qhmem.sizetable[index];
-      qhmem.cntshort++;
-      if (outsize > qhmem .freesize) {
-	if (!qhmem.curbuffer)
-	  bufsize= qhmem.BUFinit;
-        else
-	  bufsize= qhmem.BUFsize;
-        qhmem.totshort += bufsize;
-	if (!(newbuffer= malloc(bufsize))) {
-	  fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n");
-	  qh_errexit(qhmem_ERRmem, NULL, NULL);
-	} 
-	*((void **)newbuffer)= qhmem.curbuffer;  /* prepend newbuffer to curbuffer 
-						    list */
-	qhmem.curbuffer= newbuffer;
-        size= (sizeof(void **) + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
-	qhmem.freemem= (void *)((char *)newbuffer+size);
-	qhmem.freesize= bufsize - size;
-      }
-      object= qhmem.freemem;
-      qhmem.freemem= (void *)((char *)qhmem.freemem + outsize);
-      qhmem.freesize -= outsize;
-      return object;
-    }
-  }else {                     /* long allocation */
-    if (!qhmem.indextable) {
-      fprintf (qhmem.ferr, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
-      qh_errexit(qhmem_ERRqhull, NULL, NULL);
-    }
-    outsize= insize;
-    qhmem .cntlong++;
-    qhmem .curlong++;
-    qhmem .totlong += outsize;
-    if (qhmem.maxlong < qhmem.totlong)
-      qhmem.maxlong= qhmem.totlong;
-    if (!(object= malloc(outsize))) {
-      fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n");
-      qh_errexit(qhmem_ERRmem, NULL, NULL);
-    }
-    if (qhmem.IStracing >= 5)
-      fprintf (qhmem.ferr, "qh_memalloc long: %d bytes at %p\n", outsize, object);
-  }
-  return (object);
-} /* memalloc */
-
-
-/*----------------------------------
-   
-  qh_memfree( object, size ) 
-    free up an object of size bytes
-    size is insize from qh_memalloc
-
-  notes:
-    object may be NULL
-    type checking warns if using (void **)object
-    use qh_memfree_() for quick free's of small objects
- 
-  design:
-    if size <= qhmem.LASTsize
-      append object to corresponding freelist
-    else
-      call free(object)
-*/
-void qh_memfree(void *object, int size) {
-  void **freelistp;
-
-  if (!object)
-    return;
-  if (size <= qhmem.LASTsize) {
-    qhmem .freeshort++;
-    freelistp= qhmem.freelists + qhmem.indextable[size];
-    *((void **)object)= *freelistp;
-    *freelistp= object;
-  }else {
-    qhmem .freelong++;
-    qhmem .totlong -= size;
-    free (object);
-    if (qhmem.IStracing >= 5)
-      fprintf (qhmem.ferr, "qh_memfree long: %d bytes at %p\n", size, object);
-  }
-} /* memfree */
-
-
-/*---------------------------------
-  
-  qh_memfreeshort( curlong, totlong )
-    frees up all short and qhmem memory allocations
-
-  returns:
-    number and size of current long allocations
-*/
-void qh_memfreeshort (int *curlong, int *totlong) {
-  void *buffer, *nextbuffer;
-
-  *curlong= qhmem .cntlong - qhmem .freelong;
-  *totlong= qhmem .totlong;
-  for(buffer= qhmem.curbuffer; buffer; buffer= nextbuffer) {
-    nextbuffer= *((void **) buffer);
-    free(buffer);
-  }
-  qhmem.curbuffer= NULL;
-  if (qhmem .LASTsize) {
-    free (qhmem .indextable);
-    free (qhmem .freelists);
-    free (qhmem .sizetable);
-  }
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-} /* memfreeshort */
-
-
-/*----------------------------------
-   
-  qh_meminit( ferr )
-    initialize qhmem and test sizeof( void*)
-*/
-void qh_meminit (FILE *ferr) {
-  
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-  qhmem.ferr= ferr;
-  if (sizeof(void*) < sizeof(int)) {
-    fprintf (ferr, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int).  qset.c will not work\n");
-    exit (1);  /* can not use qh_errexit() */
-  }
-} /* meminit */
-
-/*---------------------------------
-  
-  qh_meminitbuffers( tracelevel, alignment, numsizes, bufsize, bufinit )
-    initialize qhmem
-    if tracelevel >= 5, trace memory allocations
-    alignment= desired address alignment for memory allocations
-    numsizes= number of freelists
-    bufsize=  size of additional memory buffers for short allocations
-    bufinit=  size of initial memory buffer for short allocations
-*/
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
-
-  qhmem.IStracing= tracelevel;
-  qhmem.NUMsizes= numsizes;
-  qhmem.BUFsize= bufsize;
-  qhmem.BUFinit= bufinit;
-  qhmem.ALIGNmask= alignment-1;
-  if (qhmem.ALIGNmask & ~qhmem.ALIGNmask) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  qhmem.sizetable= (int *) calloc (numsizes, sizeof(int));
-  qhmem.freelists= (void **) calloc (numsizes, sizeof(void *));
-  if (!qhmem.sizetable || !qhmem.freelists) {
-    fprintf(qhmem.ferr, "qhull error (qh_meminit): insufficient memory\n");
-    qh_errexit (qhmem_ERRmem, NULL, NULL);
-  }
-  if (qhmem.IStracing >= 1)
-    fprintf (qhmem.ferr, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
-} /* meminitbuffers */
-
-/*---------------------------------
-  
-  qh_memsetup()
-    set up memory after running memsize()
-*/
-void qh_memsetup (void) {
-  int k,i;
-
-  qsort(qhmem.sizetable, qhmem.TABLEsize, sizeof(int), qh_intcompare);
-  qhmem.LASTsize= qhmem.sizetable[qhmem.TABLEsize-1];
-  if (qhmem .LASTsize >= qhmem .BUFsize || qhmem.LASTsize >= qhmem .BUFinit) {
-    fprintf (qhmem.ferr, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
-            qhmem .LASTsize, qhmem .BUFsize, qhmem .BUFinit);
-    qh_errexit(qhmem_ERRmem, NULL, NULL);
-  }
-  if (!(qhmem.indextable= (int *)malloc((qhmem.LASTsize+1) * sizeof(int)))) {
-    fprintf(qhmem.ferr, "qhull error (qh_memsetup): insufficient memory\n");
-    qh_errexit(qhmem_ERRmem, NULL, NULL);
-  }
-  for(k=qhmem.LASTsize+1; k--; )
-    qhmem.indextable[k]= k;
-  i= 0;
-  for(k= 0; k <= qhmem.LASTsize; k++) {
-    if (qhmem.indextable[k] <= qhmem.sizetable[i])
-      qhmem.indextable[k]= i;
-    else
-      qhmem.indextable[k]= ++i;
-  }
-} /* memsetup */
-
-/*---------------------------------
-  
-  qh_memsize( size )
-    define a free list for this size
-*/
-void qh_memsize(int size) {
-  int k;
-
-  if (qhmem .LASTsize) {
-    fprintf (qhmem .ferr, "qhull error (qh_memsize): called after qhmem_setup\n");
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  size= (size + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
-  for(k= qhmem.TABLEsize; k--; ) {
-    if (qhmem.sizetable[k] == size)
-      return;
-  }
-  if (qhmem.TABLEsize < qhmem.NUMsizes)
-    qhmem.sizetable[qhmem.TABLEsize++]= size;
-  else
-    fprintf(qhmem.ferr, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes);
-} /* memsize */
-
-
-/*---------------------------------
-  
-  qh_memstatistics( fp )
-    print out memory statistics
-
-  notes:
-    does not account for wasted memory at the end of each block
-*/
-void qh_memstatistics (FILE *fp) {
-  int i, count, totfree= 0;
-  void *object;
-  
-  for (i=0; i < qhmem.TABLEsize; i++) {
-    count=0;
-    for (object= qhmem .freelists[i]; object; object= *((void **)object))
-      count++;
-    totfree += qhmem.sizetable[i] * count;
-  }
-  fprintf (fp, "\nmemory statistics:\n\
-%7d quick allocations\n\
-%7d short allocations\n\
-%7d long allocations\n\
-%7d short frees\n\
-%7d long frees\n\
-%7d bytes of short memory in use\n\
-%7d bytes of short memory in freelists\n\
-%7d bytes of long memory allocated (except for input)\n\
-%7d bytes of long memory in use (in %d pieces)\n\
-%7d bytes per memory buffer (initially %d bytes)\n",
-	   qhmem .cntquick, qhmem.cntshort, qhmem.cntlong,
-	   qhmem .freeshort, qhmem.freelong, 
-	   qhmem .totshort - qhmem .freesize - totfree,
-	   totfree,
-	   qhmem .maxlong, qhmem .totlong, qhmem .cntlong - qhmem .freelong,
-	   qhmem .BUFsize, qhmem .BUFinit);
-  if (qhmem.cntlarger) {
-    fprintf (fp, "%7d calls to qh_setlarger\n%7.2g     average copy size\n",
-	   qhmem.cntlarger, ((float) qhmem.totlarger)/ qhmem.cntlarger);
-    fprintf (fp, "  freelists (bytes->count):");
-  }
-  for (i=0; i < qhmem.TABLEsize; i++) {
-    count=0;
-    for (object= qhmem .freelists[i]; object; object= *((void **)object))
-      count++;
-    fprintf (fp, " %d->%d", qhmem.sizetable[i], count);
-  }
-  fprintf (fp, "\n\n");
-} /* memstatistics */
-
-
-/*---------------------------------
-  
-  qh_NOmem
-    turn off quick-fit memory allocation
-
-  notes:
-    uses malloc() and free() instead
-*/
-#else /* qh_NOmem */
-
-void *qh_memalloc(int insize) {
-  void *object;
-
-  if (!(object= malloc(insize))) {
-    fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n");
-    qh_errexit(qhmem_ERRmem, NULL, NULL);
-  }
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_memalloc long: %d bytes at %p\n", insize, object);
-  return object;
-}
-
-void qh_memfree(void *object, int size) {
-
-  if (!object)
-    return;
-  free (object);
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_memfree long: %d bytes at %p\n", size, object);
-}
-
-void qh_memfreeshort (int *curlong, int *totlong) {
-
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-  *curlong= 0;
-  *totlong= 0;
-}
-
-void qh_meminit (FILE *ferr) {
-
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-  qhmem.ferr= ferr;
-  if (sizeof(void*) < sizeof(int)) {
-    fprintf (ferr, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int).  qset.c will not work\n");
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-}
-
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
-
-  qhmem.IStracing= tracelevel;
-
-}
-
-void qh_memsetup (void) {
-
-}
-
-void qh_memsize(int size) {
-
-}
-
-void qh_memstatistics (FILE *fp) {
-
-}
-
-#endif /* qh_NOmem */
diff --git a/extern/qhull/src/mem.h b/extern/qhull/src/mem.h
deleted file mode 100644
index e9ebd1bb9bc..00000000000
--- a/extern/qhull/src/mem.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
  ---------------------------------
-
-   mem.h 
-     prototypes for memory management functions
-
-   see qh-mem.htm, mem.c and qset.h
-
-   for error handling, writes message and calls
-     qh_errexit (qhmem_ERRmem, NULL, NULL) if insufficient memory
-       and
-     qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmem
-#define qhDEFmem
-
-/*---------------------------------
-  
-  qh_NOmem
-    turn off quick-fit memory allocation
-
-  notes:
-    mem.c implements Quickfit memory allocation for about 20% time
-    savings.  If it fails on your machine, try to locate the
-    problem, and send the answer to qhull@geom.umn.edu.  If this can
-    not be done, define qh_NOmem to use malloc/free instead.
-
-   #define qh_NOmem
-*/
-
-/*-------------------------------------------
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers.  If gcc is available, 
-    use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
-
-   see qh_MEMalign in user.h for qhull's alignment
-*/
-
-#define qhmem_ERRmem 4    /* matches qh_ERRmem in qhull.h */
-#define qhmem_ERRqhull 5  /* matches qh_ERRqhull in qhull.h */
-
-/*----------------------------------
-  
-  ptr_intT
-    for casting a void* to an integer-type
-  
-  notes:
-    On 64-bit machines, a pointer may be larger than an 'int'.  
-    qh_meminit() checks that 'long' holds a 'void*'
-*/
-typedef unsigned long ptr_intT;
-
-/*----------------------------------
- 
-  qhmemT
-    global memory structure for mem.c
- 
- notes:
-   users should ignore qhmem except for writing extensions
-   qhmem is allocated in mem.c 
-   
-   qhmem could be swapable like qh and qhstat, but then
-   multiple qh's and qhmem's would need to keep in synch.  
-   A swapable qhmem would also waste memory buffers.  As long
-   as memory operations are atomic, there is no problem with
-   multiple qh structures being active at the same time.
-   If you need separate address spaces, you can swap the
-   contents of qhmem.
-*/
-typedef struct qhmemT qhmemT;
-extern qhmemT qhmem; 
-
-struct qhmemT {               /* global memory management variables */
-  int      BUFsize;	      /* size of memory allocation buffer */
-  int      BUFinit;	      /* initial size of memory allocation buffer */
-  int      TABLEsize;         /* actual number of sizes in free list table */
-  int      NUMsizes;          /* maximum number of sizes in free list table */
-  int      LASTsize;          /* last size in free list table */
-  int      ALIGNmask;         /* worst-case alignment, must be 2^n-1 */
-  void	 **freelists;          /* free list table, linked by offset 0 */
-  int     *sizetable;         /* size of each freelist */
-  int     *indextable;        /* size->index table */
-  void    *curbuffer;         /* current buffer, linked by offset 0 */
-  void    *freemem;           /*   free memory in curbuffer */
-  int 	   freesize;          /*   size of free memory in bytes */
-  void 	  *tempstack;         /* stack of temporary memory, managed by users */
-  FILE    *ferr;              /* file for reporting errors */
-  int      IStracing;         /* =5 if tracing memory allocations */
-  int      cntquick;          /* count of quick allocations */
-                              /* remove statistics doesn't effect speed */
-  int      cntshort;          /* count of short allocations */
-  int      cntlong;           /* count of long allocations */
-  int      curlong;           /* current count of inuse, long allocations */
-  int      freeshort;	      /* count of short memfrees */
-  int      freelong;	      /* count of long memfrees */
-  int      totshort;          /* total size of short allocations */
-  int      totlong;           /* total size of long allocations */
-  int      maxlong;           /* maximum totlong */
-  int      cntlarger;         /* count of setlarger's */
-  int      totlarger;         /* total copied by setlarger */
-};
-
-
-/*==================== -macros ====================*/
-
-/*----------------------------------
-   
-  qh_memalloc_(size, object, type)  
-    returns object of size bytes 
-	assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-
-#ifdef qh_NOmem
-#define qh_memalloc_(size, freelistp, object, type) {\
-  object= (type*)qh_memalloc (size); }
-#else /* !qh_NOmem */
-
-#define qh_memalloc_(size, freelistp, object, type) {\
-  freelistp= qhmem.freelists + qhmem.indextable[size];\
-  if ((object= (type*)*freelistp)) {\
-    qhmem.cntquick++;  \
-    *freelistp= *((void **)*freelistp);\
-  }else object= (type*)qh_memalloc (size);}
-#endif
-
-/*----------------------------------
-   
-  qh_memfree_(object, size) 
-    free up an object
-
-  notes:
-    object may be NULL
-    assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-#ifdef qh_NOmem
-#define qh_memfree_(object, size, freelistp) {\
-  qh_memfree (object, size); }
-#else /* !qh_NOmem */
-
-#define qh_memfree_(object, size, freelistp) {\
-  if (object) { \
-    qhmem .freeshort++;\
-    freelistp= qhmem.freelists + qhmem.indextable[size];\
-    *((void **)object)= *freelistp;\
-    *freelistp= object;}}
-#endif
-
-/*=============== prototypes in alphabetical order ============*/
-
-void *qh_memalloc(int insize);
-void qh_memfree (void *object, int size);
-void qh_memfreeshort (int *curlong, int *totlong);
-void qh_meminit (FILE *ferr);
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes,
-			int bufsize, int bufinit);
-void qh_memsetup (void);
-void qh_memsize(int size);
-void qh_memstatistics (FILE *fp);
-
-#endif /* qhDEFmem */
diff --git a/extern/qhull/src/merge.c b/extern/qhull/src/merge.c
deleted file mode 100644
index 34ecda1865f..00000000000
--- a/extern/qhull/src/merge.c
+++ /dev/null
@@ -1,3626 +0,0 @@
-/*
  ---------------------------------
-
-   merge.c 
-   merges non-convex facets
-
-   see qh-merge.htm and merge.h
-
-   other modules call qh_premerge() and qh_postmerge()
-
-   the user may call qh_postmerge() to perform additional merges.
-
-   To remove deleted facets and vertices (qhull() in qhull.c):
-     qh_partitionvisible (!qh_ALL, &numoutside);  // visible_list, newfacet_list
-     qh_deletevisible ();         // qh.visible_list
-     qh_resetlists (False, qh_RESETvisible);       // qh.visible_list newvertex_list newfacet_list 
-
-   assumes qh.CENTERtype= centrum
-
-   merges occur in qh_mergefacet and in qh_mergecycle
-   vertex->neighbors not set until the first merge occurs
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include "qhull_a.h"
-
-#ifndef qh_NOmerge
-
-/*=========== internal prototypes =========*/
-
-static int qh_compareangle(const void *p1, const void *p2);
-static int qh_comparemerge(const void *p1, const void *p2);
-static int qh_comparevisit (const void *p1, const void *p2);
-
-																														
-/*===== functions (alphabetical after premerge and postmerge) ======*/
-
-/*---------------------------------
-  
-  qh_premerge( apex, maxcentrum )
-    pre-merge nonconvex facets in qh.newfacet_list for apex
-    maxcentrum defines coplanar and concave (qh_test_appendmerge)
-
-  returns:
-    deleted facets added to qh.visible_list with facet->visible set
-
-  notes:
-    uses globals, qh.MERGEexact, qh.PREmerge
-
-  design:
-    mark duplicate ridges in qh.newfacet_list
-    merge facet cycles in qh.newfacet_list
-    merge duplicate ridges and concave facets in qh.newfacet_list
-    check merged facet cycles for degenerate and redundant facets
-    merge degenerate and redundant facets
-    collect coplanar and concave facets
-    merge concave, coplanar, degenerate, and redundant facets
-*/
-void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle) {
-  boolT othermerge= False;
-  facetT *newfacet;
-  
-  if (qh ZEROcentrum && qh_checkzero(!qh_ALL))
-    return;    
-  trace2((qh ferr, "qh_premerge: premerge centrum %2.2g angle %2.2g for apex v%d facetlist f%d\n",
-	    maxcentrum, maxangle, apex->id, getid_(qh newfacet_list)));
-  if (qh IStracing >= 4 && qh num_facets < 50)
-    qh_printlists();
-  qh centrum_radius= maxcentrum;
-  qh cos_max= maxangle;
-  qh degen_mergeset= qh_settemp (qh TEMPsize);
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  if (qh hull_dim >=3) { 
-    qh_mark_dupridges (qh newfacet_list); /* facet_mergeset */
-    qh_mergecycle_all (qh newfacet_list, &othermerge);
-    qh_forcedmerges (&othermerge /* qh facet_mergeset */); 
-    FORALLnew_facets {  /* test samecycle merges */
-      if (!newfacet->simplicial && !newfacet->mergeridge)
-	qh_degen_redundant_neighbors (newfacet, NULL);
-    }
-    if (qh_merge_degenredundant())
-      othermerge= True;
-  }else /* qh hull_dim == 2 */
-    qh_mergecycle_all (qh newfacet_list, &othermerge);
-  qh_flippedmerges (qh newfacet_list, &othermerge);
-  if (!qh MERGEexact || zzval_(Ztotmerge)) {
-    zinc_(Zpremergetot);
-    qh POSTmerging= False;
-    qh_getmergeset_initial (qh newfacet_list);
-    qh_all_merges (othermerge, False);
-  }
-  qh_settempfree(&qh facet_mergeset);
-  qh_settempfree(&qh degen_mergeset);
-} /* premerge */
-  
-/*---------------------------------
-  
-  qh_postmerge( reason, maxcentrum, maxangle, vneighbors )
-    post-merge nonconvex facets as defined by maxcentrum and maxangle
-    'reason' is for reporting progress
-    if vneighbors, 
-      calls qh_test_vneighbors at end of qh_all_merge 
-    if firstmerge, 
-      calls qh_reducevertices before qh_getmergeset
-
-  returns:
-    if first call (qh.visible_list != qh.facet_list), 
-      builds qh.facet_newlist, qh.newvertex_list
-    deleted facets added to qh.visible_list with facet->visible
-    qh.visible_list == qh.facet_list
-
-  notes:
-
-
-  design:
-    if first call
-      set qh.visible_list and qh.newfacet_list to qh.facet_list
-      add all facets to qh.newfacet_list
-      mark non-simplicial facets, facet->newmerge
-      set qh.newvertext_list to qh.vertex_list
-      add all vertices to qh.newvertex_list
-      if a pre-merge occured
-        set vertex->delridge {will retest the ridge}
-        if qh.MERGEexact
-          call qh_reducevertices()
-      if no pre-merging 
-        merge flipped facets
-    determine non-convex facets
-    merge all non-convex facets
-*/
-void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-                      boolT vneighbors) {
-  facetT *newfacet;
-  boolT othermerges= False;
-  vertexT *vertex;
-
-  if (qh REPORTfreq || qh IStracing) {
-    qh_buildtracing (NULL, NULL);
-    qh_printsummary (qh ferr);
-    if (qh PRINTstatistics) 
-      qh_printallstatistics (qh ferr, "reason");
-    fprintf (qh ferr, "\n%s with 'C%.2g' and 'A%.2g'\n", 
-        reason, maxcentrum, maxangle);
-  }
-  trace2((qh ferr, "qh_postmerge: postmerge.  test vneighbors? %d\n",
-	    vneighbors));
-  qh centrum_radius= maxcentrum;
-  qh cos_max= maxangle;
-  qh POSTmerging= True;
-  qh degen_mergeset= qh_settemp (qh TEMPsize);
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  if (qh visible_list != qh facet_list) {  /* first call */
-    qh NEWfacets= True;
-    qh visible_list= qh newfacet_list= qh facet_list;
-    FORALLnew_facets {
-      newfacet->newfacet= True;
-       if (!newfacet->simplicial)
-        newfacet->newmerge= True;
-     zinc_(Zpostfacets);
-    }
-    qh newvertex_list= qh vertex_list;
-    FORALLvertices
-      vertex->newlist= True;
-    if (qh VERTEXneighbors) { /* a merge has occurred */
-      FORALLvertices
-	vertex->delridge= True; /* test for redundant, needed? */
-      if (qh MERGEexact) {
-	if (qh hull_dim <= qh_DIMreduceBuild)
-	  qh_reducevertices(); /* was skipped during pre-merging */
-      }
-    }
-    if (!qh PREmerge && !qh MERGEexact) 
-      qh_flippedmerges (qh newfacet_list, &othermerges);
-  }
-  qh_getmergeset_initial (qh newfacet_list);
-  qh_all_merges (False, vneighbors);
-  qh_settempfree(&qh facet_mergeset);
-  qh_settempfree(&qh degen_mergeset);
-} /* post_merge */
-
-/*---------------------------------
-  
-  qh_all_merges( othermerge, vneighbors )
-    merge all non-convex facets
-    
-    set othermerge if already merged facets (for qh_reducevertices)
-    if vneighbors
-      tests vertex neighbors for convexity at end
-    qh.facet_mergeset lists the non-convex ridges in qh_newfacet_list
-    qh.degen_mergeset is defined
-    if qh.MERGEexact && !qh.POSTmerging, 
-      does not merge coplanar facets
-
-  returns:
-    deleted facets added to qh.visible_list with facet->visible
-    deleted vertices added qh.delvertex_list with vertex->delvertex
-  
-  notes:
-    unless !qh.MERGEindependent, 
-      merges facets in independent sets
-    uses qh.newfacet_list as argument since merges call qh_removefacet()
-
-  design:
-    while merges occur
-      for each merge in qh.facet_mergeset
-        unless one of the facets was already merged in this pass
-          merge the facets
-        test merged facets for additional merges
-        add merges to qh.facet_mergeset
-      if vertices record neighboring facets
-        rename redundant vertices
-          update qh.facet_mergeset
-    if vneighbors ??
-      tests vertex neighbors for convexity at end
-*/
-void qh_all_merges (boolT othermerge, boolT vneighbors) {
-  facetT *facet1, *facet2;
-  mergeT *merge;
-  boolT wasmerge= True, isreduce;
-  void **freelistp;  /* used !qh_NOmem */
-  vertexT *vertex;
-  mergeType mergetype;
-  int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0;
-  
-  trace2((qh ferr, "qh_all_merges: starting to merge facets beginning from f%d\n",
-	    getid_(qh newfacet_list)));
-  while (True) {
-    wasmerge= False;
-    while (qh_setsize (qh facet_mergeset)) {
-      while ((merge= (mergeT*)qh_setdellast(qh facet_mergeset))) {
-	facet1= merge->facet1;
-	facet2= merge->facet2;
-	mergetype= merge->type;
-	qh_memfree_(merge, sizeof(mergeT), freelistp);
-	if (facet1->visible || facet2->visible) /*deleted facet*/
-	  continue;  
-	if ((facet1->newfacet && !facet1->tested)
-	        || (facet2->newfacet && !facet2->tested)) {
-	  if (qh MERGEindependent && mergetype <= MRGanglecoplanar)
-	    continue;      /* perform independent sets of merges */
-	}
-	qh_merge_nonconvex (facet1, facet2, mergetype);
-        numdegenredun += qh_merge_degenredundant();
-        numnewmerges++;
-        wasmerge= True;
-	if (mergetype == MRGconcave)
-	  numconcave++;
-	else /* MRGcoplanar or MRGanglecoplanar */
-	  numcoplanar++;
-      } /* while setdellast */
-      if (qh POSTmerging && qh hull_dim <= qh_DIMreduceBuild 
-      && numnewmerges > qh_MAXnewmerges) {
-	numnewmerges= 0;
-	qh_reducevertices();  /* otherwise large post merges too slow */
-      }
-      qh_getmergeset (qh newfacet_list); /* facet_mergeset */
-    } /* while mergeset */
-    if (qh VERTEXneighbors) {
-      isreduce= False;
-      if (qh hull_dim >=4 && qh POSTmerging) {
-	FORALLvertices  
-	  vertex->delridge= True;
-	isreduce= True;
-      }
-      if ((wasmerge || othermerge) && (!qh MERGEexact || qh POSTmerging) 
-	  && qh hull_dim <= qh_DIMreduceBuild) {
-	othermerge= False;
-	isreduce= True;
-      }
-      if (isreduce) {
-	if (qh_reducevertices()) {
-	  qh_getmergeset (qh newfacet_list); /* facet_mergeset */
-	  continue;
-	}
-      }
-    }
-    if (vneighbors && qh_test_vneighbors(/* qh newfacet_list */)) 
-      continue;
-    break;
-  } /* while (True) */
-  if (qh CHECKfrequently && !qh MERGEexact) {
-    qh old_randomdist= qh RANDOMdist;
-    qh RANDOMdist= False;
-    qh_checkconvex (qh newfacet_list, qh_ALGORITHMfault);
-    /* qh_checkconnect (); [this is slow and it changes the facet order] */
-    qh RANDOMdist= qh old_randomdist;
-  }
-  trace1((qh ferr, "qh_all_merges: merged %d coplanar facets %d concave facets and %d degen or redundant facets.\n",
-    numcoplanar, numconcave, numdegenredun));
-  if (qh IStracing >= 4 && qh num_facets < 50)
-    qh_printlists ();
-} /* all_merges */
-
-
-/*---------------------------------
-  
-  qh_appendmergeset( facet, neighbor, mergetype, angle )
-    appends an entry to qh.facet_mergeset or qh.degen_mergeset
-
-    angle ignored if NULL or !qh.ANGLEmerge
-
-  returns:
-    merge appended to facet_mergeset or degen_mergeset
-      sets ->degenerate or ->redundant if degen_mergeset
-  
-  see:
-    qh_test_appendmerge()
-
-  design:
-    allocate merge entry
-    if regular merge
-      append to qh.facet_mergeset
-    else if degenerate merge and qh.facet_mergeset is all degenerate
-      append to qh.degen_mergeset 
-    else if degenerate merge
-      prepend to qh.degen_mergeset 
-    else if redundant merge
-      append to qh.degen_mergeset 
-*/
-void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle) {
-  mergeT *merge, *lastmerge;
-  void **freelistp; /* used !qh_NOmem */
-
-  if (facet->redundant)
-    return;
-  if (facet->degenerate && mergetype == MRGdegen)
-    return;
-  qh_memalloc_(sizeof(mergeT), freelistp, merge, mergeT);
-  merge->facet1= facet;
-  merge->facet2= neighbor;
-  merge->type= mergetype;
-  if (angle && qh ANGLEmerge)
-    merge->angle= *angle;
-  if (mergetype < MRGdegen)
-    qh_setappend (&(qh facet_mergeset), merge);
-  else if (mergetype == MRGdegen) {
-    facet->degenerate= True;
-    if (!(lastmerge= (mergeT*)qh_setlast (qh degen_mergeset)) 
-    || lastmerge->type == MRGdegen)
-      qh_setappend (&(qh degen_mergeset), merge);
-    else
-      qh_setaddnth (&(qh degen_mergeset), 0, merge);
-  }else if (mergetype == MRGredundant) {
-    facet->redundant= True;
-    qh_setappend (&(qh degen_mergeset), merge);
-  }else /* mergetype == MRGmirror */ {
-    if (facet->redundant || neighbor->redundant) {
-      fprintf(qh ferr, "qhull error (qh_appendmergeset): facet f%d or f%d is already a mirrored facet\n",
-	   facet->id, neighbor->id);
-      qh_errexit2 (qh_ERRqhull, facet, neighbor);
-    }
-    if (!qh_setequal (facet->vertices, neighbor->vertices)) {
-      fprintf(qh ferr, "qhull error (qh_appendmergeset): mirrored facets f%d and f%d do not have the same vertices\n",
-	   facet->id, neighbor->id);
-      qh_errexit2 (qh_ERRqhull, facet, neighbor);
-    }
-    facet->redundant= True;
-    neighbor->redundant= True;
-    qh_setappend (&(qh degen_mergeset), merge);
-  }
-} /* appendmergeset */
-
-
-/*---------------------------------
-  
-  qh_basevertices( samecycle )
-    return temporary set of base vertices for samecycle
-    samecycle is first facet in the cycle
-    assumes apex is SETfirst_( samecycle->vertices )
-
-  returns:
-    vertices (settemp)
-    all ->seen are cleared
-
-  notes:
-    uses qh_vertex_visit;
-
-  design:
-    for each facet in samecycle
-      for each unseen vertex in facet->vertices
-        append to result  
-*/
-setT *qh_basevertices (facetT *samecycle) {
-  facetT *same;
-  vertexT *apex, *vertex, **vertexp;
-  setT *vertices= qh_settemp (qh TEMPsize);
-  
-  apex= SETfirstt_(samecycle->vertices, vertexT);
-  apex->visitid= ++qh vertex_visit;
-  FORALLsame_cycle_(samecycle) {
-    if (same->mergeridge)
-      continue;
-    FOREACHvertex_(same->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        qh_setappend (&vertices, vertex);
-        vertex->visitid= qh vertex_visit;
-        vertex->seen= False;
-      }
-    }
-  }
-  trace4((qh ferr, "qh_basevertices: found %d vertices\n", 
-         qh_setsize (vertices)));
-  return vertices;
-} /* basevertices */
-
-/*---------------------------------
-  
-  qh_checkconnect()
-    check that new facets are connected
-    new facets are on qh.newfacet_list
-    
-  notes:
-    this is slow and it changes the order of the facets
-    uses qh.visit_id
-
-  design:
-    move first new facet to end of qh.facet_list
-    for all newly appended facets
-      append unvisited neighbors to end of qh.facet_list
-    for all new facets
-      report error if unvisited
-*/
-void qh_checkconnect (void /* qh newfacet_list */) {
-  facetT *facet, *newfacet, *errfacet= NULL, *neighbor, **neighborp;
-
-  facet= qh newfacet_list;
-  qh_removefacet (facet);
-  qh_appendfacet (facet);
-  facet->visitid= ++qh visit_id;
-  FORALLfacet_(facet) {
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-        qh_removefacet (neighbor);
-        qh_appendfacet (neighbor);
-        neighbor->visitid= qh visit_id;
-      }
-    }
-  }
-  FORALLnew_facets {
-    if (newfacet->visitid == qh visit_id)
-      break;
-    fprintf(qh ferr, "qhull error: f%d is not attached to the new facets\n",
-         newfacet->id);
-    errfacet= newfacet;
-  }
-  if (errfacet)
-    qh_errexit (qh_ERRqhull, errfacet, NULL);
-} /* checkconnect */
-
-/*---------------------------------
-  
-  qh_checkzero( testall )
-    check that facets are clearly convex for qh.DISTround with qh.MERGEexact
-
-    if testall, 
-      test all facets for qh.MERGEexact post-merging
-    else 
-      test qh.newfacet_list
-      
-    if qh.MERGEexact, 
-      allows coplanar ridges
-      skips convexity test while qh.ZEROall_ok
-
-  returns:
-    True if all facets !flipped, !dupridge, normal
-         if all horizon facets are simplicial
-         if all vertices are clearly below neighbor
-         if all opposite vertices of horizon are below 
-    clears qh.ZEROall_ok if any problems or coplanar facets
-
-  notes:
-    uses qh.vertex_visit
-    horizon facets may define multiple new facets
-
-  design:
-    for all facets in qh.newfacet_list or qh.facet_list
-      check for flagged faults (flipped, etc.)
-    for all facets in qh.newfacet_list or qh.facet_list
-      for each neighbor of facet
-        skip horizon facets for qh.newfacet_list
-        test the opposite vertex
-      if qh.newfacet_list
-        test the other vertices in the facet's horizon facet
-*/
-boolT qh_checkzero (boolT testall) {
-  facetT *facet, *neighbor, **neighborp;
-  facetT *horizon, *facetlist;
-  int neighbor_i;
-  vertexT *vertex, **vertexp;
-  realT dist;
-
-  if (testall) 
-    facetlist= qh facet_list;
-  else {
-    facetlist= qh newfacet_list;
-    FORALLfacet_(facetlist) {
-      horizon= SETfirstt_(facet->neighbors, facetT);
-      if (!horizon->simplicial)
-        goto LABELproblem;
-      if (facet->flipped || facet->dupridge || !facet->normal)
-        goto LABELproblem;
-    }
-    if (qh MERGEexact && qh ZEROall_ok) {
-      trace2((qh ferr, "qh_checkzero: skip convexity check until first pre-merge\n"));
-      return True;
-    }
-  }
-  FORALLfacet_(facetlist) {
-    qh vertex_visit++;
-    neighbor_i= 0;
-    horizon= NULL;
-    FOREACHneighbor_(facet) {
-      if (!neighbor_i && !testall) {
-        horizon= neighbor;
-	neighbor_i++;
-        continue; /* horizon facet tested in qh_findhorizon */
-      }
-      vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
-      vertex->visitid= qh vertex_visit;
-      zzinc_(Zdistzero);
-      qh_distplane (vertex->point, neighbor, &dist);
-      if (dist >= -qh DISTround) {
-        qh ZEROall_ok= False;
-        if (!qh MERGEexact || testall || dist > qh DISTround)
-          goto LABELnonconvex;
-      }
-    }
-    if (!testall) {
-      FOREACHvertex_(horizon->vertices) {
-	if (vertex->visitid != qh vertex_visit) {
-	  zzinc_(Zdistzero);
-	  qh_distplane (vertex->point, facet, &dist);
-	  if (dist >= -qh DISTround) {
-	    qh ZEROall_ok= False;
-	    if (!qh MERGEexact || dist > qh DISTround)
-	      goto LABELnonconvex;
-	  }
-	  break;
-	}
-      }
-    }
-  }
-  trace2((qh ferr, "qh_checkzero: testall %d, facets are %s\n", testall,
-        (qh MERGEexact && !testall) ? 
-           "not concave, flipped, or duplicate ridged" : "clearly convex"));
-  return True;
-
- LABELproblem:
-  qh ZEROall_ok= False;
-  trace2((qh ferr, "qh_checkzero: facet f%d needs pre-merging\n",
-       facet->id));
-  return False;
-
- LABELnonconvex:
-  trace2((qh ferr, "qh_checkzero: facet f%d and f%d are not clearly convex.  v%d dist %.2g\n",
-         facet->id, neighbor->id, vertex->id, dist));
-  return False;
-} /* checkzero */
-
-/*---------------------------------
-  
-  qh_compareangle( angle1, angle2 )
-    used by qsort() to order merges by angle
-*/
-static int qh_compareangle(const void *p1, const void *p2) {
-  mergeT *a= *((mergeT **)p1), *b= *((mergeT **)p2);
- 
-  return ((a->angle > b->angle) ? 1 : -1);
-} /* compareangle */
-
-/*---------------------------------
-  
-  qh_comparemerge( merge1, merge2 )
-    used by qsort() to order merges
-*/
-static int qh_comparemerge(const void *p1, const void *p2) {
-  mergeT *a= *((mergeT **)p1), *b= *((mergeT **)p2);
- 
-  return (a->type - b->type);
-} /* comparemerge */
-
-/*---------------------------------
-  
-  qh_comparevisit( vertex1, vertex2 )
-    used by qsort() to order vertices by their visitid
-*/
-static int qh_comparevisit (const void *p1, const void *p2) {
-  vertexT *a= *((vertexT **)p1), *b= *((vertexT **)p2);
- 
-  return (a->visitid - b->visitid);
-} /* comparevisit */
-
-/*---------------------------------
-  
-  qh_copynonconvex( atridge )
-    set non-convex flag on other ridges (if any) between same neighbors
-
-  notes:
-    may be faster if use smaller ridge set
-
-  design:
-    for each ridge of atridge's top facet
-      if ridge shares the same neighbor
-        set nonconvex flag
-*/
-void qh_copynonconvex (ridgeT *atridge) {
-  facetT *facet, *otherfacet;
-  ridgeT *ridge, **ridgep;
-
-  facet= atridge->top;
-  otherfacet= atridge->bottom;
-  FOREACHridge_(facet->ridges) {
-    if (otherfacet == otherfacet_(ridge, facet) && ridge != atridge) {
-      ridge->nonconvex= True;
-      trace4((qh ferr, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n",
-	      atridge->id, ridge->id));
-      break;
-    }
-  }
-} /* copynonconvex */
-
-/*---------------------------------
-  
-  qh_degen_redundant_facet( facet )
-    check facet for degen. or redundancy
-
-  notes:
-    bumps vertex_visit
-    called if a facet was redundant but no longer is (qh_merge_degenredundant)
-    qh_appendmergeset() only appends first reference to facet (i.e., redundant)
-
-  see:
-    qh_degen_redundant_neighbors()
-
-  design:
-    test for redundant neighbor
-    test for degenerate facet
-*/
-void qh_degen_redundant_facet (facetT *facet) {
-  vertexT *vertex, **vertexp;
-  facetT *neighbor, **neighborp;
-
-  trace4((qh ferr, "qh_degen_redundant_facet: test facet f%d for degen/redundant\n",
-	  facet->id));
-  FOREACHneighbor_(facet) {
-    qh vertex_visit++;
-    FOREACHvertex_(neighbor->vertices)
-      vertex->visitid= qh vertex_visit;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit)
-	break;
-    }
-    if (!vertex) {
-      qh_appendmergeset (facet, neighbor, MRGredundant, NULL);
-      trace2((qh ferr, "qh_degen_redundant_facet: f%d is contained in f%d.  merge\n", facet->id, neighbor->id)); 
-      return;
-    }
-  }
-  if (qh_setsize (facet->neighbors) < qh hull_dim) {
-    qh_appendmergeset (facet, facet, MRGdegen, NULL);
-    trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is degenerate.\n", facet->id));
-  }
-} /* degen_redundant_facet */
-
-
-/*---------------------------------
-  
-  qh_degen_redundant_neighbors( facet, delfacet,  )
-    append degenerate and redundant neighbors to facet_mergeset
-    if delfacet, 
-      only checks neighbors of both delfacet and facet
-    also checks current facet for degeneracy
-
-  notes:
-    bumps vertex_visit
-    called for each qh_mergefacet() and qh_mergecycle()
-    merge and statistics occur in merge_nonconvex
-    qh_appendmergeset() only appends first reference to facet (i.e., redundant)
-      it appends redundant facets after degenerate ones
-
-    a degenerate facet has fewer than hull_dim neighbors
-    a redundant facet's vertices is a subset of its neighbor's vertices
-    tests for redundant merges first (appendmergeset is nop for others)
-    in a merge, only needs to test neighbors of merged facet
-  
-  see:
-    qh_merge_degenredundant() and qh_degen_redundant_facet()
-
-  design:
-    test for degenerate facet
-    test for redundant neighbor
-    test for degenerate neighbor
-*/
-void qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet) {
-  vertexT *vertex, **vertexp;
-  facetT *neighbor, **neighborp;
-  int size;
-
-  trace4((qh ferr, "qh_degen_redundant_neighbors: test neighbors of f%d with delfacet f%d\n", 
-	  facet->id, getid_(delfacet)));
-  if ((size= qh_setsize (facet->neighbors)) < qh hull_dim) {
-    qh_appendmergeset (facet, facet, MRGdegen, NULL);
-    trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.\n", facet->id, size));
-  }
-  if (!delfacet)
-    delfacet= facet;
-  qh vertex_visit++;
-  FOREACHvertex_(facet->vertices)
-    vertex->visitid= qh vertex_visit;
-  FOREACHneighbor_(delfacet) {
-    /* uses early out instead of checking vertex count */
-    if (neighbor == facet)
-      continue;
-    FOREACHvertex_(neighbor->vertices) {
-      if (vertex->visitid != qh vertex_visit)
-        break;
-    }
-    if (!vertex) {
-      qh_appendmergeset (neighbor, facet, MRGredundant, NULL);
-      trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is contained in f%d.  merge\n", neighbor->id, facet->id)); 
-    }
-  }
-  FOREACHneighbor_(delfacet) {   /* redundant merges occur first */
-    if (neighbor == facet)
-      continue;
-    if ((size= qh_setsize (neighbor->neighbors)) < qh hull_dim) {
-      qh_appendmergeset (neighbor, neighbor, MRGdegen, NULL);
-      trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.  Neighbor of f%d.\n", neighbor->id, size, facet->id)); 
-    }
-  }
-} /* degen_redundant_neighbors */
-
-
-/*---------------------------------
-  
-  qh_find_newvertex( oldvertex, vertices, ridges )
-    locate new vertex for renaming old vertex
-    vertices is a set of possible new vertices
-      vertices sorted by number of deleted ridges
-
-  returns:
-    newvertex or NULL
-      each ridge includes both vertex and oldvertex
-    vertices sorted by number of deleted ridges
-      
-  notes:
-    modifies vertex->visitid
-    new vertex is in one of the ridges
-    renaming will not cause a duplicate ridge
-    renaming will minimize the number of deleted ridges
-    newvertex may not be adjacent in the dual (though unlikely)
-
-  design:
-    for each vertex in vertices
-      set vertex->visitid to number of references in ridges
-    remove unvisited vertices 
-    set qh.vertex_visit above all possible values
-    sort vertices by number of references in ridges
-    add each ridge to qh.hash_table
-    for each vertex in vertices
-      look for a vertex that would not cause a duplicate ridge after a rename
-*/
-vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges) {
-  vertexT *vertex, **vertexp;
-  setT *newridges;
-  ridgeT *ridge, **ridgep;
-  int size, hashsize;
-  int hash;
-
-#ifndef qh_NOtrace
-  if (qh IStracing >= 4) {
-    fprintf (qh ferr, "qh_find_newvertex: find new vertex for v%d from ",
-	     oldvertex->id);
-    FOREACHvertex_(vertices) 
-      fprintf (qh ferr, "v%d ", vertex->id);
-    FOREACHridge_(ridges)
-      fprintf (qh ferr, "r%d ", ridge->id);
-    fprintf (qh ferr, "\n");
-  }
-#endif
-  FOREACHvertex_(vertices) 
-    vertex->visitid= 0;
-  FOREACHridge_(ridges) {
-    FOREACHvertex_(ridge->vertices) 
-      vertex->visitid++;
-  }
-  FOREACHvertex_(vertices) {
-    if (!vertex->visitid) {
-      qh_setdelnth (vertices, SETindex_(vertices,vertex));
-      vertexp--; /* repeat since deleted this vertex */
-    }
-  }
-  qh vertex_visit += qh_setsize (ridges);
-  if (!qh_setsize (vertices)) {
-    trace4((qh ferr, "qh_find_newvertex: vertices not in ridges for v%d\n",
-	    oldvertex->id));
-    return NULL;
-  }
-  qsort (SETaddr_(vertices, vertexT), qh_setsize (vertices),
-	        sizeof (vertexT *), qh_comparevisit);
-  /* can now use qh vertex_visit */
-  if (qh PRINTstatistics) {
-    size= qh_setsize (vertices);
-    zinc_(Zintersect);
-    zadd_(Zintersecttot, size);
-    zmax_(Zintersectmax, size);
-  }
-  hashsize= qh_newhashtable (qh_setsize (ridges));
-  FOREACHridge_(ridges)
-    qh_hashridge (qh hash_table, hashsize, ridge, oldvertex);
-  FOREACHvertex_(vertices) {
-    newridges= qh_vertexridges (vertex);
-    FOREACHridge_(newridges) {
-      if (qh_hashridge_find (qh hash_table, hashsize, ridge, vertex, oldvertex, &hash)) {
-	zinc_(Zdupridge);
-	break;
-      }
-    }
-    qh_settempfree (&newridges);
-    if (!ridge)
-      break;  /* found a rename */
-  }
-  if (vertex) {
-    /* counted in qh_renamevertex */
-    trace2((qh ferr, "qh_find_newvertex: found v%d for old v%d from %d vertices and %d ridges.\n",
-      vertex->id, oldvertex->id, qh_setsize (vertices), qh_setsize (ridges)));
-  }else {
-    zinc_(Zfindfail);
-    trace0((qh ferr, "qh_find_newvertex: no vertex for renaming v%d (all duplicated ridges) during p%d\n",
-      oldvertex->id, qh furthest_id));
-  }
-  qh_setfree (&qh hash_table);
-  return vertex;
-} /* find_newvertex */
-
-/*---------------------------------
-  
-  qh_findbest_test( testcentrum, facet, neighbor, bestfacet, dist, mindist, maxdist )
-    test neighbor of facet for qh_findbestneighbor()
-    if testcentrum,
-      tests centrum (assumes it is defined)
-    else 
-      tests vertices
-
-  returns:
-    if a better facet (i.e., vertices/centrum of facet closer to neighbor)
-      updates bestfacet, dist, mindist, and maxdist
-*/
-void qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor,
-      facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp) {
-  realT dist, mindist, maxdist;
-
-  if (testcentrum) {
-    zzinc_(Zbestdist);
-    qh_distplane(facet->center, neighbor, &dist);
-    dist *= qh hull_dim; /* estimate furthest vertex */
-    if (dist < 0) {
-      maxdist= 0;
-      mindist= dist;
-      dist= -dist;
-    }else
-      maxdist= dist;
-  }else
-    dist= qh_getdistance (facet, neighbor, &mindist, &maxdist);
-  if (dist < *distp) {
-    *bestfacet= neighbor;
-    *mindistp= mindist;
-    *maxdistp= maxdist;
-    *distp= dist;
-  }
-} /* findbest_test */
-
-/*---------------------------------
-  
-  qh_findbestneighbor( facet, dist, mindist, maxdist )
-    finds best neighbor (least dist) of a facet for merging
-
-  returns:
-    returns min and max distances and their max absolute value
-  
-  notes:
-    avoids merging old into new
-    assumes ridge->nonconvex only set on one ridge between a pair of facets
-    could use an early out predicate but not worth it
-
-  design:
-    if a large facet
-      will test centrum
-    else
-      will test vertices
-    if a large facet
-      test nonconvex neighbors for best merge
-    else
-      test all neighbors for the best merge
-    if testing centrum
-      get distance information
-*/
-facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp) {
-  facetT *neighbor, **neighborp, *bestfacet= NULL;
-  ridgeT *ridge, **ridgep;
-  boolT nonconvex= True, testcentrum= False;
-  int size= qh_setsize (facet->vertices);
-
-  *distp= REALmax;
-  if (size > qh_BESTcentrum2 * qh hull_dim + qh_BESTcentrum) {
-    testcentrum= True;
-    zinc_(Zbestcentrum);
-    if (!facet->center)
-       facet->center= qh_getcentrum (facet);
-  }
-  if (size > qh hull_dim + qh_BESTnonconvex) {
-    FOREACHridge_(facet->ridges) {
-      if (ridge->nonconvex) {
-        neighbor= otherfacet_(ridge, facet);
-	qh_findbest_test (testcentrum, facet, neighbor,
-			  &bestfacet, distp, mindistp, maxdistp);
-      }
-    }
-  }
-  if (!bestfacet) {     
-    nonconvex= False;
-    FOREACHneighbor_(facet)
-      qh_findbest_test (testcentrum, facet, neighbor,
-			&bestfacet, distp, mindistp, maxdistp);
-  }
-  if (!bestfacet) {
-    fprintf (qh ferr, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id);
-    
-    qh_errexit (qh_ERRqhull, facet, NULL);
-  }
-  if (testcentrum) 
-    qh_getdistance (facet, bestfacet, mindistp, maxdistp);
-  trace3((qh ferr, "qh_findbestneighbor: f%d is best neighbor for f%d testcentrum? %d nonconvex? %d dist %2.2g min %2.2g max %2.2g\n",
-     bestfacet->id, facet->id, testcentrum, nonconvex, *distp, *mindistp, *maxdistp));
-  return(bestfacet);
-} /* findbestneighbor */
-
-
-/*---------------------------------
-  
-  qh_flippedmerges( facetlist, wasmerge )
-    merge flipped facets into best neighbor
-    assumes qh.facet_mergeset at top of temporary stack
-
-  returns:
-    no flipped facets on facetlist
-    sets wasmerge if merge occurred
-    degen/redundant merges passed through
-
-  notes:
-    othermerges not needed since qh.facet_mergeset is empty before & after
-      keep it in case of change
-
-  design:
-    append flipped facets to qh.facetmergeset
-    for each flipped merge
-      find best neighbor
-      merge facet into neighbor
-      merge degenerate and redundant facets
-    remove flipped merges from qh.facet_mergeset
-*/
-void qh_flippedmerges(facetT *facetlist, boolT *wasmerge) {
-  facetT *facet, *neighbor, *facet1;
-  realT dist, mindist, maxdist;
-  mergeT *merge, **mergep;
-  setT *othermerges;
-  int nummerge=0;
-
-  trace4((qh ferr, "qh_flippedmerges: begin\n"));
-  FORALLfacet_(facetlist) {
-    if (facet->flipped && !facet->visible) 
-      qh_appendmergeset (facet, facet, MRGflip, NULL);
-  }
-  othermerges= qh_settemppop(); /* was facet_mergeset */
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  qh_settemppush (othermerges);
-  FOREACHmerge_(othermerges) {
-    facet1= merge->facet1;
-    if (merge->type != MRGflip || facet1->visible) 
-      continue;
-    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-      qhmem.IStracing= qh IStracing= qh TRACElevel;
-    neighbor= qh_findbestneighbor (facet1, &dist, &mindist, &maxdist);
-    trace0((qh ferr, "qh_flippedmerges: merge flipped f%d into f%d dist %2.2g during p%d\n",
-      facet1->id, neighbor->id, dist, qh furthest_id));
-    qh_mergefacet (facet1, neighbor, &mindist, &maxdist, !qh_MERGEapex);
-    nummerge++;
-    if (qh PRINTstatistics) {
-      zinc_(Zflipped);
-      wadd_(Wflippedtot, dist);
-      wmax_(Wflippedmax, dist);
-    }
-    qh_merge_degenredundant();
-  }
-  FOREACHmerge_(othermerges) {
-    if (merge->facet1->visible || merge->facet2->visible)
-      qh_memfree (merge, sizeof(mergeT));
-    else
-      qh_setappend (&qh facet_mergeset, merge);
-  }
-  qh_settempfree (&othermerges);
-  if (nummerge)
-    *wasmerge= True;
-  trace1((qh ferr, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge));
-} /* flippedmerges */
-
-
-/*---------------------------------
-  
-  qh_forcedmerges( wasmerge )
-    merge duplicated ridges
-
-  returns:
-    removes all duplicate ridges on facet_mergeset
-    wasmerge set if merge
-    qh.facet_mergeset may include non-forced merges (none for now)
-    qh.degen_mergeset includes degen/redun merges
-
-  notes: 
-    duplicate ridges occur when the horizon is pinched,
-        i.e. a subridge occurs in more than two horizon ridges.
-     could rename vertices that pinch the horizon
-    assumes qh_merge_degenredundant() has not be called
-    othermerges isn't needed since facet_mergeset is empty afterwards
-      keep it in case of change
-
-  design:
-    for each duplicate ridge
-      find current facets by chasing f.replace links
-      determine best direction for facet
-      merge one facet into the other
-      remove duplicate ridges from qh.facet_mergeset
-*/
-void qh_forcedmerges(boolT *wasmerge) {
-  facetT *facet1, *facet2;
-  mergeT *merge, **mergep;
-  realT dist1, dist2, mindist1, mindist2, maxdist1, maxdist2;
-  setT *othermerges;
-  int nummerge=0, numflip=0;
-
-  if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-    qhmem.IStracing= qh IStracing= qh TRACElevel;
-  trace4((qh ferr, "qh_forcedmerges: begin\n"));  
-  othermerges= qh_settemppop(); /* was facet_mergeset */
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  qh_settemppush (othermerges);
-  FOREACHmerge_(othermerges) {
-    if (merge->type != MRGridge) 
-    	continue;
-    facet1= merge->facet1;
-    facet2= merge->facet2;
-    while (facet1->visible)    	 /* must exist, no qh_merge_degenredunant */
-      facet1= facet1->f.replace; /* previously merged facet */
-    while (facet2->visible)
-      facet2= facet2->f.replace; /* previously merged facet */
-    if (facet1 == facet2)
-      continue;
-    if (!qh_setin (facet2->neighbors, facet1)) {
-      fprintf (qh ferr, "qhull internal error (qh_forcedmerges): f%d and f%d had a duplicate ridge but as f%d and f%d they are no longer neighbors\n",
-	       merge->facet1->id, merge->facet2->id, facet1->id, facet2->id);
-      qh_errexit2 (qh_ERRqhull, facet1, facet2);
-    }
-    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-      qhmem.IStracing= qh IStracing= qh TRACElevel;
-    dist1= qh_getdistance (facet1, facet2, &mindist1, &maxdist1);
-    dist2= qh_getdistance (facet2, facet1, &mindist2, &maxdist2);
-    trace0((qh ferr, "qh_forcedmerges: duplicate ridge between f%d and f%d, dist %2.2g and reverse dist %2.2g during p%d\n",
-	    facet1->id, facet2->id, dist1, dist2, qh furthest_id));
-    if (dist1 < dist2) 
-      qh_mergefacet (facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex);
-    else {
-      qh_mergefacet (facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex);
-      dist1= dist2;
-      facet1= facet2;
-    }
-    if (facet1->flipped) {
-      zinc_(Zmergeflipdup);
-      numflip++;
-    }else
-      nummerge++;
-    if (qh PRINTstatistics) {
-      zinc_(Zduplicate);
-      wadd_(Wduplicatetot, dist1);
-      wmax_(Wduplicatemax, dist1);
-    }
-  }
-  FOREACHmerge_(othermerges) {
-    if (merge->type == MRGridge)
-      qh_memfree (merge, sizeof(mergeT));
-    else
-      qh_setappend (&qh facet_mergeset, merge);
-  }
-  qh_settempfree (&othermerges);
-  if (nummerge)
-    *wasmerge= True;
-  trace1((qh ferr, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n", 
-                nummerge, numflip));
-} /* forcedmerges */
-
-
-/*---------------------------------
-  
-  qh_getmergeset( facetlist )
-    determines nonconvex facets on facetlist
-    tests !tested ridges and nonconvex ridges of !tested facets
-
-  returns:
-    returns sorted qh.facet_mergeset of facet-neighbor pairs to be merged
-    all ridges tested
-  
-  notes:
-    assumes no nonconvex ridges with both facets tested
-    uses facet->tested/ridge->tested to prevent duplicate tests
-    can not limit tests to modified ridges since the centrum changed
-    uses qh.visit_id
-  
-  see:
-    qh_getmergeset_initial()
-
-  design:
-    for each facet on facetlist
-      for each ridge of facet
-        if untested ridge
-          test ridge for convexity
-          if non-convex
-            append ridge to qh.facet_mergeset
-    sort qh.facet_mergeset by angle  
-*/
-void qh_getmergeset(facetT *facetlist) {
-  facetT *facet, *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int nummerges;
-  
-  nummerges= qh_setsize (qh facet_mergeset);
-  trace4((qh ferr, "qh_getmergeset: started.\n"));
-  qh visit_id++;
-  FORALLfacet_(facetlist) {
-    if (facet->tested)
-      continue;
-    facet->visitid= qh visit_id;
-    facet->tested= True;  /* must be non-simplicial due to merge */
-    FOREACHneighbor_(facet)
-      neighbor->seen= False;
-    FOREACHridge_(facet->ridges) {
-      if (ridge->tested && !ridge->nonconvex)
-	continue;
-      /* if tested & nonconvex, need to append merge */
-      neighbor= otherfacet_(ridge, facet);
-      if (neighbor->seen) {
-	ridge->tested= True;
-	ridge->nonconvex= False;
-      }else if (neighbor->visitid != qh visit_id) {
-        ridge->tested= True;
-        ridge->nonconvex= False;
-	neighbor->seen= True;      /* only one ridge is marked nonconvex */
-	if (qh_test_appendmerge (facet, neighbor))
-	  ridge->nonconvex= True;
-      }
-    }
-  }
-  nummerges= qh_setsize (qh facet_mergeset);
-  if (qh ANGLEmerge)
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_compareangle);
-  else
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_comparemerge);
-  if (qh POSTmerging) {
-    zadd_(Zmergesettot2, nummerges);
-  }else {
-    zadd_(Zmergesettot, nummerges);
-    zmax_(Zmergesetmax, nummerges);
-  }
-  trace2((qh ferr, "qh_getmergeset: %d merges found\n", nummerges));
-} /* getmergeset */
-
-
-/*---------------------------------
-  
-  qh_getmergeset_initial( facetlist )
-    determine initial qh.facet_mergeset for facets
-    tests all facet/neighbor pairs on facetlist
-
-  returns:
-    sorted qh.facet_mergeset with nonconvex ridges
-    sets facet->tested, ridge->tested, and ridge->nonconvex
-
-  notes:
-    uses visit_id, assumes ridge->nonconvex is False
-
-  see:
-    qh_getmergeset()
-
-  design:
-    for each facet on facetlist
-      for each untested neighbor of facet
-        test facet and neighbor for convexity
-        if non-convex
-          append merge to qh.facet_mergeset
-          mark one of the ridges as nonconvex
-    sort qh.facet_mergeset by angle
-*/
-void qh_getmergeset_initial (facetT *facetlist) {
-  facetT *facet, *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int nummerges;
-
-  qh visit_id++;
-  FORALLfacet_(facetlist) {
-    facet->visitid= qh visit_id;
-    facet->tested= True;
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-        if (qh_test_appendmerge (facet, neighbor)) {
-          FOREACHridge_(neighbor->ridges) {
-            if (facet == otherfacet_(ridge, neighbor)) {
-              ridge->nonconvex= True;
-              break;	/* only one ridge is marked nonconvex */
-            }
-          }
-        }
-      }
-    }
-    FOREACHridge_(facet->ridges)
-      ridge->tested= True;
-  }
-  nummerges= qh_setsize (qh facet_mergeset);
-  if (qh ANGLEmerge)
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_compareangle);
-  else
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_comparemerge);
-  if (qh POSTmerging) {
-    zadd_(Zmergeinittot2, nummerges);
-  }else {
-    zadd_(Zmergeinittot, nummerges);
-    zmax_(Zmergeinitmax, nummerges);
-  }
-  trace2((qh ferr, "qh_getmergeset_initial: %d merges found\n", nummerges));
-} /* getmergeset_initial */
-
-
-/*---------------------------------
-  
-  qh_hashridge( hashtable, hashsize, ridge, oldvertex )
-    add ridge to hashtable without oldvertex
-
-  notes:
-    assumes hashtable is large enough
-
-  design:
-    determine hash value for ridge without oldvertex
-    find next empty slot for ridge
-*/
-void qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) {
-  int hash;
-  ridgeT *ridgeA;
-
-  hash= (int)qh_gethash (hashsize, ridge->vertices, qh hull_dim-1, 0, oldvertex);
-  while (True) {
-    if (!(ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
-      SETelem_(hashtable, hash)= ridge;
-      break;
-    }else if (ridgeA == ridge)
-      break;
-    if (++hash == hashsize)
-      hash= 0;
-  }
-} /* hashridge */
-
-
-/*---------------------------------
-  
-  qh_hashridge_find( hashtable, hashsize, ridge, vertex, oldvertex, hashslot )
-    returns matching ridge without oldvertex in hashtable 
-      for ridge without vertex
-    if oldvertex is NULL 
-      matches with any one skip
-
-  returns:
-    matching ridge or NULL
-    if no match,
-      if ridge already in   table
-        hashslot= -1 
-      else 
-        hashslot= next NULL index
-        
-  notes:
-    assumes hashtable is large enough
-    can't match ridge to itself
-
-  design:
-    get hash value for ridge without vertex
-    for each hashslot
-      return match if ridge matches ridgeA without oldvertex
-*/
-ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, 
-              vertexT *vertex, vertexT *oldvertex, int *hashslot) {
-  int hash;
-  ridgeT *ridgeA;
-
-  *hashslot= 0;
-  zinc_(Zhashridge);
-  hash= (int)qh_gethash (hashsize, ridge->vertices, qh hull_dim-1, 0, vertex);
-  while ((ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
-    if (ridgeA == ridge)
-      *hashslot= -1;      
-    else {
-      zinc_(Zhashridgetest);
-      if (qh_setequal_except (ridge->vertices, vertex, ridgeA->vertices, oldvertex))
-        return ridgeA;
-    }
-    if (++hash == hashsize)
-      hash= 0;
-  }
-  if (!*hashslot)
-    *hashslot= hash;
-  return NULL;
-} /* hashridge_find */
-
-
-/*---------------------------------
-  
-  qh_makeridges( facet )
-    creates explicit ridges between simplicial facets
-
-  returns:
-    facet with ridges and without qh_MERGEridge
-    ->simplicial is False
-  
-  notes:
-    allows qh_MERGEridge flag
-    uses existing ridges
-    duplicate neighbors ok if ridges already exist (qh_mergecycle_ridges)
-
-  see:
-    qh_mergecycle_ridges()
-
-  design:
-    look for qh_MERGEridge neighbors
-    mark neighbors that already have ridges
-    for each unprocessed neighbor of facet    
-      create a ridge for neighbor and facet
-    if any qh_MERGEridge neighbors
-      delete qh_MERGEridge flags (already handled by qh_mark_dupridges)
-*/
-void qh_makeridges(facetT *facet) {
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int neighbor_i, neighbor_n;
-  boolT toporient, mergeridge= False;
-  
-  if (!facet->simplicial)
-    return;
-  trace4((qh ferr, "qh_makeridges: make ridges for f%d\n", facet->id));
-  facet->simplicial= False;
-  FOREACHneighbor_(facet) {
-    if (neighbor == qh_MERGEridge)
-      mergeridge= True;
-    else
-      neighbor->seen= False;
-  }
-  FOREACHridge_(facet->ridges)
-    otherfacet_(ridge, facet)->seen= True;
-  FOREACHneighbor_i_(facet) {
-    if (neighbor == qh_MERGEridge)
-      continue;  /* fixed by qh_mark_dupridges */
-    else if (!neighbor->seen) {  /* no current ridges */
-      ridge= qh_newridge();
-      ridge->vertices= qh_setnew_delnthsorted (facet->vertices, qh hull_dim,
-					                  neighbor_i, 0);
-      toporient= facet->toporient ^ (neighbor_i & 0x1);
-      if (toporient) {
-        ridge->top= facet;
-        ridge->bottom= neighbor;
-      }else {
-        ridge->top= neighbor;
-        ridge->bottom= facet;
-      }
-#if 0 /* this also works */
-      flip= (facet->toporient ^ neighbor->toporient)^(skip1 & 0x1) ^ (skip2 & 0x1);
-      if (facet->toporient ^ (skip1 & 0x1) ^ flip) {
-        ridge->top= neighbor;
-        ridge->bottom= facet;
-      }else {
-        ridge->top= facet;
-        ridge->bottom= neighbor;
-      }
-#endif
-      qh_setappend(&(facet->ridges), ridge);
-      qh_setappend(&(neighbor->ridges), ridge);
-    }
-  }
-  if (mergeridge) {
-    while (qh_setdel (facet->neighbors, qh_MERGEridge))
-      ; /* delete each one */
-  }
-} /* makeridges */
-
-
-/*---------------------------------
-  
-  qh_mark_dupridges( facetlist )
-    add duplicated ridges to qh.facet_mergeset
-    facet->dupridge is true
-
-  returns:
-    duplicate ridges on qh.facet_mergeset
-    ->mergeridge/->mergeridge2 set
-    duplicate ridges marked by qh_MERGEridge and both sides facet->dupridge
-    no MERGEridges in neighbor sets
-    
-  notes:
-    duplicate ridges occur when the horizon is pinched,
-        i.e. a subridge occurs in more than two horizon ridges.
-    could rename vertices that pinch the horizon
-    uses qh.visit_id
-
-  design:
-    for all facets on facetlist
-      if facet contains a duplicate ridge
-        for each neighbor of facet
-          if neighbor marked qh_MERGEridge (one side of the merge)
-            set facet->mergeridge      
-          else
-            if neighbor contains a duplicate ridge 
-            and the back link is qh_MERGEridge
-              append duplicate ridge to qh.facet_mergeset
-   for each duplicate ridge
-     make ridge sets in preparation for merging
-     remove qh_MERGEridge from neighbor set
-   for each duplicate ridge
-     restore the missing neighbor from the neighbor set that was qh_MERGEridge
-     add the missing ridge for this neighbor
-*/
-void qh_mark_dupridges(facetT *facetlist) {
-  facetT *facet, *neighbor, **neighborp;
-  int nummerge=0;
-  mergeT *merge, **mergep;
-  
-
-  trace4((qh ferr, "qh_mark_dupridges: identify duplicate ridges\n"));  
-  FORALLfacet_(facetlist) {
-    if (facet->dupridge) {
-      FOREACHneighbor_(facet) {
-        if (neighbor == qh_MERGEridge) {
-	  facet->mergeridge= True;
-	  continue;
-	}
-        if (neighbor->dupridge
-	&& !qh_setin (neighbor->neighbors, facet)) { /* qh_MERGEridge */
-	  qh_appendmergeset (facet, neighbor, MRGridge, NULL);
-	  facet->mergeridge2= True;
-	  facet->mergeridge= True;
-	  nummerge++;
-	}
-      }
-    }
-  }
-  if (!nummerge)
-    return;
-  FORALLfacet_(facetlist) {            /* gets rid of qh_MERGEridge */
-    if (facet->mergeridge && !facet->mergeridge2)   
-      qh_makeridges (facet);
-  }
-  FOREACHmerge_(qh facet_mergeset) {   /* restore the missing neighbors */
-    if (merge->type == MRGridge) {
-      qh_setappend (&merge->facet2->neighbors, merge->facet1);
-      qh_makeridges (merge->facet1);   /* and the missing ridges */
-    }
-  }
-  trace1((qh ferr, "qh_mark_dupridges: found %d duplicated ridges\n", 
-                nummerge));
-} /* mark_dupridges */
-
-/*---------------------------------
-  
-  qh_maydropneighbor( facet )
-    drop neighbor relationship if no ridge between facet and neighbor
-
-  returns:
-    neighbor sets updated
-    appends degenerate facets to qh.facet_mergeset
-  
-  notes:
-    won't cause redundant facets since vertex inclusion is the same
-    may drop vertex and neighbor if no ridge
-    uses qh.visit_id
-
-  design:
-    visit all neighbors with ridges
-    for each unvisited neighbor of facet
-      delete neighbor and facet from the neighbor sets
-      if neighbor becomes degenerate
-        append neighbor to qh.degen_mergeset
-    if facet is degenerate
-      append facet to qh.degen_mergeset
-*/
-void qh_maydropneighbor (facetT *facet) {
-  ridgeT *ridge, **ridgep;
-  realT angledegen= qh_ANGLEdegen;
-  facetT *neighbor, **neighborp;
-
-  qh visit_id++;
-  trace4((qh ferr, "qh_maydropneighbor: test f%d for no ridges to a neighbor\n",
-	  facet->id));
-  FOREACHridge_(facet->ridges) {
-    ridge->top->visitid= qh visit_id;
-    ridge->bottom->visitid= qh visit_id;
-  }
-  FOREACHneighbor_(facet) {
-    if (neighbor->visitid != qh visit_id) {
-      trace0((qh ferr, "qh_maydropneighbor: facets f%d and f%d are no longer neighbors during p%d\n",
-	    facet->id, neighbor->id, qh furthest_id));
-      zinc_(Zdropneighbor);
-      qh_setdel (facet->neighbors, neighbor);
-      neighborp--;  /* repeat, deleted a neighbor */
-      qh_setdel (neighbor->neighbors, facet);
-      if (qh_setsize (neighbor->neighbors) < qh hull_dim) {
-        zinc_(Zdropdegen);
-        qh_appendmergeset (neighbor, neighbor, MRGdegen, &angledegen);
-        trace2((qh ferr, "qh_maydropneighbors: f%d is degenerate.\n", neighbor->id));
-      }
-    }
-  }
-  if (qh_setsize (facet->neighbors) < qh hull_dim) {
-    zinc_(Zdropdegen);
-    qh_appendmergeset (facet, facet, MRGdegen, &angledegen);
-    trace2((qh ferr, "qh_maydropneighbors: f%d is degenerate.\n", facet->id));
-  }
-} /* maydropneighbor */
-
-
-/*---------------------------------
-  
-  qh_merge_degenredundant()
-    merge all degenerate and redundant facets
-    qh.degen_mergeset contains merges from qh_degen_redundant_neighbors()
-
-  returns:
-    number of merges performed
-    resets facet->degenerate/redundant
-    if deleted (visible) facet has no neighbors
-      sets ->f.replace to NULL
-
-  notes:
-    redundant merges happen before degenerate ones
-    merging and renaming vertices can result in degen/redundant facets
-
-  design:
-    for each merge on qh.degen_mergeset
-      if redundant merge
-        if non-redundant facet merged into redundant facet
-          recheck facet for redundancy
-        else
-          merge redundant facet into other facet
-*/
-int qh_merge_degenredundant (void) {
-  int size;
-  mergeT *merge;
-  facetT *bestneighbor, *facet1, *facet2;
-  realT dist, mindist, maxdist;
-  vertexT *vertex, **vertexp;
-  int nummerges= 0;
-  mergeType mergetype;
-
-  while ((merge= (mergeT*)qh_setdellast (qh degen_mergeset))) {
-    facet1= merge->facet1;
-    facet2= merge->facet2;
-    mergetype= merge->type;
-    qh_memfree (merge, sizeof(mergeT));
-    if (facet1->visible)
-      continue;
-    facet1->degenerate= False; 
-    facet1->redundant= False; 
-    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-      qhmem.IStracing= qh IStracing= qh TRACElevel;
-    if (mergetype == MRGredundant) {
-      zinc_(Zneighbor);
-      while (facet2->visible) {
-        if (!facet2->f.replace) {
-          fprintf (qh ferr, "qhull internal error (qh_merge_degenredunant): f%d redundant but f%d has no replacement\n",
-	       facet1->id, facet2->id);
-          qh_errexit2 (qh_ERRqhull, facet1, facet2);
-        }
-        facet2= facet2->f.replace;
-      }
-      if (facet1 == facet2) {
-	qh_degen_redundant_facet (facet1); /* in case of others */
-	continue;
-      }
-      trace2((qh ferr, "qh_merge_degenredundant: facet f%d is contained in f%d, will merge\n",
-	    facet1->id, facet2->id));
-      qh_mergefacet(facet1, facet2, NULL, NULL, !qh_MERGEapex);
-      /* merge distance is already accounted for */
-      nummerges++;
-    }else {  /* mergetype == MRGdegen, other merges may have fixed */
-      if (!(size= qh_setsize (facet1->neighbors))) {
-        zinc_(Zdelfacetdup);
-        trace2((qh ferr, "qh_merge_degenredundant: facet f%d has no neighbors.  Deleted\n", facet1->id));
-        qh_willdelete (facet1, NULL);
-        FOREACHvertex_(facet1->vertices) {
-  	  qh_setdel (vertex->neighbors, facet1);
-	  if (!SETfirst_(vertex->neighbors)) {
-	    zinc_(Zdegenvertex);
-	    trace2((qh ferr, "qh_merge_degenredundant: deleted v%d because f%d has no neighbors\n",
-         	 vertex->id, facet1->id));
-	    vertex->deleted= True;
-	    qh_setappend (&qh del_vertices, vertex);
-	  }
-        }
-        nummerges++;
-      }else if (size < qh hull_dim) {
-        bestneighbor= qh_findbestneighbor(facet1, &dist, &mindist, &maxdist);
-        trace2((qh ferr, "qh_merge_degenredundant: facet f%d has %d neighbors, merge into f%d dist %2.2g\n",
-	      facet1->id, size, bestneighbor->id, dist));
-        qh_mergefacet(facet1, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
-        nummerges++;
-        if (qh PRINTstatistics) {
-	  zinc_(Zdegen);
-	  wadd_(Wdegentot, dist);
-	  wmax_(Wdegenmax, dist);
-        }
-      }	/* else, another merge fixed the degeneracy and redundancy tested */
-    }
-  }
-  return nummerges;
-} /* merge_degenredundant */
-
-/*---------------------------------
-  
-  qh_merge_nonconvex( facet1, facet2, mergetype )
-    remove non-convex ridge between facet1 into facet2 
-    mergetype gives why the facet's are non-convex
-
-  returns:
-    merges one of the facets into the best neighbor
-    
-  design:
-    if one of the facets is a new facet
-      prefer merging new facet into old facet
-    find best neighbors for both facets
-    merge the nearest facet into its best neighbor
-    update the statistics
-*/
-void qh_merge_nonconvex (facetT *facet1, facetT *facet2, mergeType mergetype) {
-  facetT *bestfacet, *bestneighbor, *neighbor;
-  realT dist, dist2, mindist, mindist2, maxdist, maxdist2;
-
-  if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-    qhmem.IStracing= qh IStracing= qh TRACElevel;
-  trace3((qh ferr, "qh_merge_nonconvex: merge #%d for f%d and f%d type %d\n",
-      zzval_(Ztotmerge) + 1, facet1->id, facet2->id, mergetype));
-  /* concave or coplanar */
-  if (!facet1->newfacet) {
-    bestfacet= facet2;   /* avoid merging old facet if new is ok */
-    facet2= facet1;
-    facet1= bestfacet;
-  }else
-    bestfacet= facet1;
-  bestneighbor= qh_findbestneighbor(bestfacet, &dist, &mindist, &maxdist);
-  neighbor= qh_findbestneighbor(facet2, &dist2, &mindist2, &maxdist2);
-  if (dist < dist2) {
-    qh_mergefacet(bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
-  }else if (qh AVOIDold && !facet2->newfacet
-  && ((mindist >= -qh MAXcoplanar && maxdist <= qh max_outside)
-       || dist * 1.5 < dist2)) {
-    zinc_(Zavoidold);
-    wadd_(Wavoidoldtot, dist);
-    wmax_(Wavoidoldmax, dist);
-    trace2((qh ferr, "qh_merge_nonconvex: avoid merging old facet f%d dist %2.2g.  Use f%d dist %2.2g instead\n",
-           facet2->id, dist2, facet1->id, dist2));
-    qh_mergefacet(bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
-  }else {
-    qh_mergefacet(facet2, neighbor, &mindist2, &maxdist2, !qh_MERGEapex);
-    dist= dist2;
-  }
-  if (qh PRINTstatistics) {
-    if (mergetype == MRGanglecoplanar) {
-      zinc_(Zacoplanar);
-      wadd_(Wacoplanartot, dist);
-      wmax_(Wacoplanarmax, dist);
-    }else if (mergetype == MRGconcave) {
-      zinc_(Zconcave);
-      wadd_(Wconcavetot, dist);
-      wmax_(Wconcavemax, dist);
-    }else { /* MRGcoplanar */
-      zinc_(Zcoplanar);
-      wadd_(Wcoplanartot, dist);
-      wmax_(Wcoplanarmax, dist);
-    }
-  }
-} /* merge_nonconvex */
-
-/*---------------------------------
-  
-  qh_mergecycle( samecycle, newfacet )
-    merge a cycle of facets starting at samecycle into a newfacet 
-    newfacet is a horizon facet with ->normal
-    samecycle facets are simplicial from an apex
-
-  returns:
-    initializes vertex neighbors on first merge
-    samecycle deleted (placed on qh.visible_list)
-    newfacet at end of qh.facet_list
-    deleted vertices on qh.del_vertices
-
-  see:
-    qh_mergefacet()
-    called by qh_mergecycle_all() for multiple, same cycle facets
-
-  design:
-    make vertex neighbors if necessary
-    make ridges for newfacet
-    merge neighbor sets of samecycle into newfacet
-    merge ridges of samecycle into newfacet
-    merge vertex neighbors of samecycle into newfacet
-    make apex of samecycle the apex of newfacet
-    if newfacet wasn't a new facet
-      add its vertices to qh.newvertex_list
-    delete samecycle facets a make newfacet a newfacet
-*/
-void qh_mergecycle (facetT *samecycle, facetT *newfacet) {
-  int traceonce= False, tracerestore= 0;
-  vertexT *apex;
-#ifndef qh_NOtrace
-  facetT *same;
-#endif
-
-  if (newfacet->tricoplanar) {
-    if (!qh TRInormals) {
-      fprintf (qh ferr, "qh_mergecycle: does not work for tricoplanar facets.  Use option 'Q11'\n");
-      qh_errexit (qh_ERRqhull, newfacet, NULL);
-    }
-    newfacet->tricoplanar= False;
-    newfacet->keepcentrum= False;
-  }
-  if (!qh VERTEXneighbors)
-    qh_vertexneighbors();
-  zzinc_(Ztotmerge);
-  if (qh REPORTfreq2 && qh POSTmerging) {
-    if (zzval_(Ztotmerge) > qh mergereport + qh REPORTfreq2)
-      qh_tracemerging();
-  }
-#ifndef qh_NOtrace
-  if (qh TRACEmerge == zzval_(Ztotmerge))
-    qhmem.IStracing= qh IStracing= qh TRACElevel;
-  trace2((qh ferr, "qh_mergecycle: merge #%d for facets from cycle f%d into coplanar horizon f%d\n", 
-        zzval_(Ztotmerge), samecycle->id, newfacet->id));
-  if (newfacet == qh tracefacet) {
-    tracerestore= qh IStracing;
-    qh IStracing= 4;
-    fprintf (qh ferr, "qh_mergecycle: ========= trace merge %d of samecycle %d into trace f%d, furthest is p%d\n",
-	       zzval_(Ztotmerge), samecycle->id, newfacet->id,  qh furthest_id);
-    traceonce= True;
-  }
-  if (qh IStracing >=4) {
-    fprintf (qh ferr, "  same cycle:");
-    FORALLsame_cycle_(samecycle)
-      fprintf(qh ferr, " f%d", same->id);
-    fprintf (qh ferr, "\n");
-  }
-  if (qh IStracing >=4)
-    qh_errprint ("MERGING CYCLE", samecycle, newfacet, NULL, NULL);
-#endif /* !qh_NOtrace */
-  apex= SETfirstt_(samecycle->vertices, vertexT);
-  qh_makeridges (newfacet);
-  qh_mergecycle_neighbors (samecycle, newfacet);
-  qh_mergecycle_ridges (samecycle, newfacet);
-  qh_mergecycle_vneighbors (samecycle, newfacet);
-  if (SETfirstt_(newfacet->vertices, vertexT) != apex) 
-    qh_setaddnth (&newfacet->vertices, 0, apex);  /* apex has last id */
-  if (!newfacet->newfacet)
-    qh_newvertices (newfacet->vertices);
-  qh_mergecycle_facets (samecycle, newfacet);
-  qh_tracemerge (samecycle, newfacet);
-  /* check for degen_redundant_neighbors after qh_forcedmerges() */
-  if (traceonce) {
-    fprintf (qh ferr, "qh_mergecycle: end of trace facet\n");
-    qh IStracing= tracerestore;
-  }
-} /* mergecycle */
-
-/*---------------------------------
-  
-  qh_mergecycle_all( facetlist, wasmerge )
-    merge all samecycles of coplanar facets into horizon
-    don't merge facets with ->mergeridge (these already have ->normal)
-    all facets are simplicial from apex
-    all facet->cycledone == False
-
-  returns:
-    all newfacets merged into coplanar horizon facets
-    deleted vertices on  qh.del_vertices
-    sets wasmerge if any merge
-
-  see:
-    calls qh_mergecycle for multiple, same cycle facets
-
-  design:
-    for each facet on facetlist
-      skip facets with duplicate ridges and normals
-      check that facet is in a samecycle (->mergehorizon)
-      if facet only member of samecycle
-	sets vertex->delridge for all vertices except apex
-        merge facet into horizon
-      else
-        mark all facets in samecycle
-        remove facets with duplicate ridges from samecycle
-        merge samecycle into horizon (deletes facets from facetlist)
-*/
-void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) {
-  facetT *facet, *same, *prev, *horizon;
-  facetT *samecycle= NULL, *nextfacet, *nextsame;
-  vertexT *apex, *vertex, **vertexp;
-  int cycles=0, total=0, facets, nummerge;
-
-  trace2((qh ferr, "qh_mergecycle_all: begin\n"));
-  for (facet= facetlist; facet && (nextfacet= facet->next); facet= nextfacet) {
-    if (facet->normal)
-      continue;
-    if (!facet->mergehorizon) {
-      fprintf (qh ferr, "qh_mergecycle_all: f%d without normal\n", facet->id);
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-    horizon= SETfirstt_(facet->neighbors, facetT);
-    if (facet->f.samecycle == facet) {
-      zinc_(Zonehorizon);  
-      /* merge distance done in qh_findhorizon */
-      apex= SETfirstt_(facet->vertices, vertexT);
-      FOREACHvertex_(facet->vertices) {
-	if (vertex != apex)
-          vertex->delridge= True;
-      }
-      horizon->f.newcycle= NULL;
-      qh_mergefacet (facet, horizon, NULL, NULL, qh_MERGEapex);
-    }else {
-      samecycle= facet;
-      facets= 0;
-      prev= facet;
-      for (same= facet->f.samecycle; same;  /* FORALLsame_cycle_(facet) */
-	   same= (same == facet ? NULL :nextsame)) { /* ends at facet */
-	nextsame= same->f.samecycle;
-        if (same->cycledone || same->visible)
-          qh_infiniteloop (same);
-        same->cycledone= True;
-        if (same->normal) { 
-          prev->f.samecycle= same->f.samecycle; /* unlink ->mergeridge */
-	  same->f.samecycle= NULL;
-        }else {
-          prev= same;
-	  facets++;
-	}
-      }
-      while (nextfacet && nextfacet->cycledone)  /* will delete samecycle */
-	nextfacet= nextfacet->next;
-      horizon->f.newcycle= NULL;
-      qh_mergecycle (samecycle, horizon);
-      nummerge= horizon->nummerge + facets;
-      if (nummerge > qh_MAXnummerge) 
-      	horizon->nummerge= qh_MAXnummerge;
-      else
-        horizon->nummerge= nummerge;
-      zzinc_(Zcyclehorizon);
-      total += facets;
-      zzadd_(Zcyclefacettot, facets);
-      zmax_(Zcyclefacetmax, facets);
-    }
-    cycles++;
-  }
-  if (cycles)
-    *wasmerge= True;
-  trace1((qh ferr, "qh_mergecycle_all: merged %d same cycles or facets into coplanar horizons\n", cycles));
-} /* mergecycle_all */
-
-/*---------------------------------
-  
-  qh_mergecycle_facets( samecycle, newfacet )
-    finish merge of samecycle into newfacet
-
-  returns:
-    samecycle prepended to visible_list for later deletion and partitioning
-      each facet->f.replace == newfacet
-      
-    newfacet moved to end of qh.facet_list
-      makes newfacet a newfacet (get's facet1->id if it was old)
-      sets newfacet->newmerge
-      clears newfacet->center (unless merging into a large facet)
-      clears newfacet->tested and ridge->tested for facet1
-      
-    adds neighboring facets to facet_mergeset if redundant or degenerate
-
-  design:
-    make newfacet a new facet and set its flags
-    move samecycle facets to qh.visible_list for later deletion
-    unless newfacet is large
-      remove its centrum
-*/
-void qh_mergecycle_facets (facetT *samecycle, facetT *newfacet) {
-  facetT *same, *next;
-  
-  trace4((qh ferr, "qh_mergecycle_facets: make newfacet new and samecycle deleted\n"));  
-  qh_removefacet(newfacet);  /* append as a newfacet to end of qh facet_list */
-  qh_appendfacet(newfacet);
-  newfacet->newfacet= True;
-  newfacet->simplicial= False;
-  newfacet->newmerge= True;
-  
-  for (same= samecycle->f.samecycle; same; same= (same == samecycle ?  NULL : next)) {
-    next= same->f.samecycle;  /* reused by willdelete */
-    qh_willdelete (same, newfacet);
-  }
-  if (newfacet->center 
-      && qh_setsize (newfacet->vertices) <= qh hull_dim + qh_MAXnewcentrum) {
-    qh_memfree (newfacet->center, qh normal_size);
-    newfacet->center= NULL;
-  }
-  trace3((qh ferr, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n", 
-             samecycle->id, newfacet->id));
-} /* mergecycle_facets */
-
-/*---------------------------------
-  
-  qh_mergecycle_neighbors( samecycle, newfacet )
-    add neighbors for samecycle facets to newfacet
-
-  returns:
-    newfacet with updated neighbors and vice-versa
-    newfacet has ridges
-    all neighbors of newfacet marked with qh.visit_id
-    samecycle facets marked with qh.visit_id-1
-    ridges updated for simplicial neighbors of samecycle with a ridge
-
-  notes:
-    assumes newfacet not in samecycle
-    usually, samecycle facets are new, simplicial facets without internal ridges 
-      not so if horizon facet is coplanar to two different samecycles
-  
-  see:
-    qh_mergeneighbors()
-
-  design:
-    check samecycle
-    delete neighbors from newfacet that are also in samecycle
-    for each neighbor of a facet in samecycle
-      if neighbor is simplicial
-        if first visit
-          move the neighbor relation to newfacet
-          update facet links for its ridges
-        else
-          make ridges for neighbor
-          remove samecycle reference
-      else
-        update neighbor sets
-*/
-void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet) {
-  facetT *same, *neighbor, **neighborp;
-  int delneighbors= 0, newneighbors= 0;
-  unsigned int samevisitid;
-  ridgeT *ridge, **ridgep;
-
-  samevisitid= ++qh visit_id;
-  FORALLsame_cycle_(samecycle) {
-    if (same->visitid == samevisitid || same->visible)
-      qh_infiniteloop (samecycle);
-    same->visitid= samevisitid;
-  }
-  newfacet->visitid= ++qh visit_id;
-  trace4((qh ferr, "qh_mergecycle_neighbors: delete shared neighbors from newfacet\n"));  
-  FOREACHneighbor_(newfacet) {
-    if (neighbor->visitid == samevisitid) {
-      SETref_(neighbor)= NULL;  /* samecycle neighbors deleted */
-      delneighbors++;
-    }else
-      neighbor->visitid= qh visit_id;
-  }
-  qh_setcompact (newfacet->neighbors);
-
-  trace4((qh ferr, "qh_mergecycle_neighbors: update neighbors\n"));  
-  FORALLsame_cycle_(samecycle) {
-    FOREACHneighbor_(same) {
-      if (neighbor->visitid == samevisitid)
-	continue;
-      if (neighbor->simplicial) {
-	if (neighbor->visitid != qh visit_id) {
-	  qh_setappend (&newfacet->neighbors, neighbor);
-	  qh_setreplace (neighbor->neighbors, same, newfacet);
-	  newneighbors++;
-	  neighbor->visitid= qh visit_id;
-	  FOREACHridge_(neighbor->ridges) { /* update ridge in case of qh_makeridges */
-	    if (ridge->top == same) {
-	      ridge->top= newfacet;
-	      break;
-	    }else if (ridge->bottom == same) {
-	      ridge->bottom= newfacet;
-	      break;
-	    }
-	  }
-	}else {
-	  qh_makeridges (neighbor);
-	  qh_setdel (neighbor->neighbors, same);
-	  /* same can't be horizon facet for neighbor */
-	}
-      }else { /* non-simplicial neighbor */
-        qh_setdel (neighbor->neighbors, same);
-        if (neighbor->visitid != qh visit_id) {
-          qh_setappend (&neighbor->neighbors, newfacet);
-          qh_setappend (&newfacet->neighbors, neighbor);
-          neighbor->visitid= qh visit_id;
-          newneighbors++;
-        } 
-      }
-    }
-  }
-  trace2((qh ferr, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n", 
-             delneighbors, newneighbors));
-} /* mergecycle_neighbors */
-
-/*---------------------------------
-  
-  qh_mergecycle_ridges( samecycle, newfacet )
-    add ridges/neighbors for facets in samecycle to newfacet
-    all new/old neighbors of newfacet marked with qh.visit_id
-    facets in samecycle marked with qh.visit_id-1
-    newfacet marked with qh.visit_id
-
-  returns:
-    newfacet has merged ridges
-  
-  notes:
-    ridge already updated for simplicial neighbors of samecycle with a ridge
-
-  see:
-    qh_mergeridges()
-    qh_makeridges()
-
-  design:
-    remove ridges between newfacet and samecycle
-    for each facet in samecycle
-      for each ridge in facet
-        update facet pointers in ridge
-        skip ridges processed in qh_mergecycle_neighors
-        free ridges between newfacet and samecycle
-        free ridges between facets of samecycle (on 2nd visit)
-        append remaining ridges to newfacet
-      if simpilicial facet
-        for each neighbor of facet
-          if simplicial facet
-          and not samecycle facet or newfacet
-            make ridge between neighbor and newfacet
-*/
-void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) {
-  facetT *same, *neighbor= NULL;
-  int numold=0, numnew=0;
-  int neighbor_i, neighbor_n;
-  unsigned int samevisitid;
-  ridgeT *ridge, **ridgep;
-  boolT toporient;
-  void **freelistp; /* used !qh_NOmem */
-
-  trace4((qh ferr, "qh_mergecycle_ridges: delete shared ridges from newfacet\n"));  
-  samevisitid= qh visit_id -1;
-  FOREACHridge_(newfacet->ridges) {
-    neighbor= otherfacet_(ridge, newfacet);
-    if (neighbor->visitid == samevisitid)
-      SETref_(ridge)= NULL; /* ridge free'd below */  
-  }
-  qh_setcompact (newfacet->ridges);
-  
-  trace4((qh ferr, "qh_mergecycle_ridges: add ridges to newfacet\n"));  
-  FORALLsame_cycle_(samecycle) {
-    FOREACHridge_(same->ridges) {
-      if (ridge->top == same) {
-        ridge->top= newfacet;
-	neighbor= ridge->bottom;
-      }else if (ridge->bottom == same) {
-	ridge->bottom= newfacet;
-	neighbor= ridge->top;
-      }else if (ridge->top == newfacet || ridge->bottom == newfacet) {
-        qh_setappend (&newfacet->ridges, ridge);
-        numold++;  /* already set by qh_mergecycle_neighbors */
-	continue;  
-      }else {
-	fprintf (qh ferr, "qhull internal error (qh_mergecycle_ridges): bad ridge r%d\n", ridge->id);
-	qh_errexit (qh_ERRqhull, NULL, ridge);
-      }
-      if (neighbor == newfacet) {
-        qh_setfree(&(ridge->vertices)); 
-        qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-        numold++;
-      }else if (neighbor->visitid == samevisitid) {
-	qh_setdel (neighbor->ridges, ridge);
-	qh_setfree(&(ridge->vertices)); 
-	qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-	numold++;
-      }else {
-        qh_setappend (&newfacet->ridges, ridge);
-        numold++;
-      }
-    }
-    if (same->ridges)
-      qh_settruncate (same->ridges, 0);
-    if (!same->simplicial)
-      continue;
-    FOREACHneighbor_i_(same) {       /* note: !newfact->simplicial */
-      if (neighbor->visitid != samevisitid && neighbor->simplicial) {
-        ridge= qh_newridge();
-        ridge->vertices= qh_setnew_delnthsorted (same->vertices, qh hull_dim,
-  					                  neighbor_i, 0);
-        toporient= same->toporient ^ (neighbor_i & 0x1);
-        if (toporient) {
-          ridge->top= newfacet;
-          ridge->bottom= neighbor;
-        }else {
-          ridge->top= neighbor;
-          ridge->bottom= newfacet;
-        }
-        qh_setappend(&(newfacet->ridges), ridge);
-        qh_setappend(&(neighbor->ridges), ridge);
-        numnew++;
-      }
-    }
-  }
-
-  trace2((qh ferr, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n", 
-             numold, numnew));
-} /* mergecycle_ridges */
-
-/*---------------------------------
-  
-  qh_mergecycle_vneighbors( samecycle, newfacet )
-    create vertex neighbors for newfacet from vertices of facets in samecycle
-    samecycle marked with visitid == qh.visit_id - 1
-
-  returns:
-    newfacet vertices with updated neighbors
-    marks newfacet with qh.visit_id-1
-    deletes vertices that are merged away
-    sets delridge on all vertices (faster here than in mergecycle_ridges)
-
-  see:
-    qh_mergevertex_neighbors()
-
-  design:
-    for each vertex of samecycle facet
-      set vertex->delridge
-      delete samecycle facets from vertex neighbors
-      append newfacet to vertex neighbors
-      if vertex only in newfacet
-        delete it from newfacet
-        add it to qh.del_vertices for later deletion
-*/
-void qh_mergecycle_vneighbors (facetT *samecycle, facetT *newfacet) {
-  facetT *neighbor, **neighborp;
-  unsigned int mergeid;
-  vertexT *vertex, **vertexp, *apex;
-  setT *vertices;
-  
-  trace4((qh ferr, "qh_mergecycle_vneighbors: update vertex neighbors for newfacet\n"));  
-  mergeid= qh visit_id - 1;
-  newfacet->visitid= mergeid;
-  vertices= qh_basevertices (samecycle); /* temp */
-  apex= SETfirstt_(samecycle->vertices, vertexT);
-  qh_setappend (&vertices, apex);
-  FOREACHvertex_(vertices) {
-    vertex->delridge= True;
-    FOREACHneighbor_(vertex) {
-      if (neighbor->visitid == mergeid)
-        SETref_(neighbor)= NULL;
-    }
-    qh_setcompact (vertex->neighbors);
-    qh_setappend (&vertex->neighbors, newfacet);
-    if (!SETsecond_(vertex->neighbors)) {
-      zinc_(Zcyclevertex);
-      trace2((qh ferr, "qh_mergecycle_vneighbors: deleted v%d when merging cycle f%d into f%d\n",
-        vertex->id, samecycle->id, newfacet->id));
-      qh_setdelsorted (newfacet->vertices, vertex);
-      vertex->deleted= True;
-      qh_setappend (&qh del_vertices, vertex);
-    }
-  }
-  qh_settempfree (&vertices);
-  trace3((qh ferr, "qh_mergecycle_vneighbors: merged vertices from cycle f%d into f%d\n", 
-             samecycle->id, newfacet->id));
-} /* mergecycle_vneighbors */
-
-/*---------------------------------
-  
-  qh_mergefacet( facet1, facet2, mindist, maxdist, mergeapex )
-    merges facet1 into facet2
-    mergeapex==qh_MERGEapex if merging new facet into coplanar horizon
-    
-  returns:
-    qh.max_outside and qh.min_vertex updated
-    initializes vertex neighbors on first merge
-
-  returns:
-    facet2 contains facet1's vertices, neighbors, and ridges
-      facet2 moved to end of qh.facet_list
-      makes facet2 a newfacet
-      sets facet2->newmerge set
-      clears facet2->center (unless merging into a large facet)
-      clears facet2->tested and ridge->tested for facet1
-
-    facet1 prepended to visible_list for later deletion and partitioning
-      facet1->f.replace == facet2
-
-    adds neighboring facets to facet_mergeset if redundant or degenerate
-
-  notes: 
-    mindist/maxdist may be NULL
-    traces merge if fmax_(maxdist,-mindist) > TRACEdist
-
-  see: 
-    qh_mergecycle()
-
-  design:
-    trace merge and check for degenerate simplex
-    make ridges for both facets
-    update qh.max_outside, qh.max_vertex, qh.min_vertex
-    update facet2->maxoutside and keepcentrum
-    update facet2->nummerge
-    update tested flags for facet2
-    if facet1 is simplicial
-      merge facet1 into facet2
-    else
-      merge facet1's neighbors into facet2
-      merge facet1's ridges into facet2
-      merge facet1's vertices into facet2
-      merge facet1's vertex neighbors into facet2
-      add facet2's vertices to qh.new_vertexlist
-      unless qh_MERGEapex
-        test facet2 for degenerate or redundant neighbors
-      move facet1 to qh.visible_list for later deletion
-      move facet2 to end of qh.newfacet_list
-*/
-void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex) {
-  boolT traceonce= False;
-  vertexT *vertex, **vertexp;
-  int tracerestore=0, nummerge;
-
-  if (facet1->tricoplanar || facet2->tricoplanar) {
-    if (!qh TRInormals) {
-      fprintf (qh ferr, "qh_mergefacet: does not work for tricoplanar facets.  Use option 'Q11'\n");
-      qh_errexit2 (qh_ERRqhull, facet1, facet2);
-    }
-    if (facet2->tricoplanar) {
-      facet2->tricoplanar= False;
-      facet2->keepcentrum= False;
-    }
-  }
-  zzinc_(Ztotmerge);
-  if (qh REPORTfreq2 && qh POSTmerging) {
-    if (zzval_(Ztotmerge) > qh mergereport + qh REPORTfreq2)
-      qh_tracemerging();
-  }
-#ifndef qh_NOtrace
-  if (qh build_cnt >= qh RERUN) {
-    if (mindist && (-*mindist > qh TRACEdist || *maxdist > qh TRACEdist)) {
-      tracerestore= 0;
-      qh IStracing= qh TRACElevel;
-      traceonce= True;
-      fprintf (qh ferr, "qh_mergefacet: ========= trace wide merge #%d (%2.2g) for f%d into f%d, last point was p%d\n", zzval_(Ztotmerge),
-	     fmax_(-*mindist, *maxdist), facet1->id, facet2->id, qh furthest_id);
-    }else if (facet1 == qh tracefacet || facet2 == qh tracefacet) {
-      tracerestore= qh IStracing;
-      qh IStracing= 4;
-      traceonce= True;
-      fprintf (qh ferr, "qh_mergefacet: ========= trace merge #%d involving f%d, furthest is p%d\n",
-		 zzval_(Ztotmerge), qh tracefacet_id,  qh furthest_id);
-    }
-  }
-  if (qh IStracing >= 2) {
-    realT mergemin= -2;
-    realT mergemax= -2;
-    
-    if (mindist) {
-      mergemin= *mindist;
-      mergemax= *maxdist;
-    }
-    fprintf (qh ferr, "qh_mergefacet: #%d merge f%d into f%d, mindist= %2.2g, maxdist= %2.2g\n", 
-    zzval_(Ztotmerge), facet1->id, facet2->id, mergemin, mergemax);
-  }
-#endif /* !qh_NOtrace */
-  if (facet1 == facet2 || facet1->visible || facet2->visible) {
-    fprintf (qh ferr, "qhull internal error (qh_mergefacet): either f%d and f%d are the same or one is a visible facet\n",
-	     facet1->id, facet2->id);
-    qh_errexit2 (qh_ERRqhull, facet1, facet2);
-  }
-  if (qh num_facets - qh num_visible <= qh hull_dim + 1) {
-    fprintf(qh ferr, "\n\
-qhull precision error: Only %d facets remain.  Can not merge another\n\
-pair.  The input is too degenerate or the convexity constraints are\n\
-too strong.\n", qh hull_dim+1);
-    if (qh hull_dim >= 5 && !qh MERGEexact)
-      fprintf(qh ferr, "Option 'Qx' may avoid this problem.\n");
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (!qh VERTEXneighbors)
-    qh_vertexneighbors();
-  qh_makeridges(facet1);
-  qh_makeridges(facet2);
-  if (qh IStracing >=4)
-    qh_errprint ("MERGING", facet1, facet2, NULL, NULL);
-  if (mindist) {
-    maximize_(qh max_outside, *maxdist);
-    maximize_(qh max_vertex, *maxdist);
-#if qh_MAXoutside
-    maximize_(facet2->maxoutside, *maxdist);
-#endif
-    minimize_(qh min_vertex, *mindist);
-    if (!facet2->keepcentrum 
-    && (*maxdist > qh WIDEfacet || *mindist < -qh WIDEfacet)) {
-      facet2->keepcentrum= True;
-      zinc_(Zwidefacet);
-    }
-  }
-  nummerge= facet1->nummerge + facet2->nummerge + 1;
-  if (nummerge >= qh_MAXnummerge) 
-    facet2->nummerge= qh_MAXnummerge;
-  else
-    facet2->nummerge= nummerge;
-  facet2->newmerge= True;
-  facet2->dupridge= False;
-  qh_updatetested  (facet1, facet2);
-  if (qh hull_dim > 2 && qh_setsize (facet1->vertices) == qh hull_dim)
-    qh_mergesimplex (facet1, facet2, mergeapex);
-  else {
-    qh vertex_visit++;
-    FOREACHvertex_(facet2->vertices)
-      vertex->visitid= qh vertex_visit;
-    if (qh hull_dim == 2) 
-      qh_mergefacet2d(facet1, facet2);
-    else {
-      qh_mergeneighbors(facet1, facet2);
-      qh_mergevertices(facet1->vertices, &facet2->vertices);
-    }
-    qh_mergeridges(facet1, facet2);
-    qh_mergevertex_neighbors(facet1, facet2);
-    if (!facet2->newfacet)
-      qh_newvertices (facet2->vertices);
-  }
-  if (!mergeapex)
-    qh_degen_redundant_neighbors (facet2, facet1);
-  if (facet2->coplanar || !facet2->newfacet) {
-    zinc_(Zmergeintohorizon);
-  }else if (!facet1->newfacet && facet2->newfacet) {
-    zinc_(Zmergehorizon);
-  }else {
-    zinc_(Zmergenew);
-  }
-  qh_willdelete (facet1, facet2);
-  qh_removefacet(facet2);  /* append as a newfacet to end of qh facet_list */
-  qh_appendfacet(facet2);
-  facet2->newfacet= True;
-  facet2->tested= False;
-  qh_tracemerge (facet1, facet2);
-  if (traceonce) {
-    fprintf (qh ferr, "qh_mergefacet: end of wide tracing\n");
-    qh IStracing= tracerestore;
-  }
-} /* mergefacet */
-
-
-/*---------------------------------
-  
-  qh_mergefacet2d( facet1, facet2 )
-    in 2d, merges neighbors and vertices of facet1 into facet2
-    
-  returns:
-    build ridges for neighbors if necessary
-    facet2 looks like a simplicial facet except for centrum, ridges
-      neighbors are opposite the corresponding vertex
-      maintains orientation of facet2
-
-  notes:
-    qh_mergefacet() retains non-simplicial structures
-      they are not needed in 2d, but later routines may use them
-    preserves qh.vertex_visit for qh_mergevertex_neighbors()
-  
-  design:
-    get vertices and neighbors
-    determine new vertices and neighbors
-    set new vertices and neighbors and adjust orientation
-    make ridges for new neighbor if needed
-*/
-void qh_mergefacet2d (facetT *facet1, facetT *facet2) {
-  vertexT *vertex1A, *vertex1B, *vertex2A, *vertex2B, *vertexA, *vertexB;
-  facetT *neighbor1A, *neighbor1B, *neighbor2A, *neighbor2B, *neighborA, *neighborB;
-
-  vertex1A= SETfirstt_(facet1->vertices, vertexT);
-  vertex1B= SETsecondt_(facet1->vertices, vertexT);
-  vertex2A= SETfirstt_(facet2->vertices, vertexT);
-  vertex2B= SETsecondt_(facet2->vertices, vertexT);
-  neighbor1A= SETfirstt_(facet1->neighbors, facetT);
-  neighbor1B= SETsecondt_(facet1->neighbors, facetT);
-  neighbor2A= SETfirstt_(facet2->neighbors, facetT);
-  neighbor2B= SETsecondt_(facet2->neighbors, facetT);
-  if (vertex1A == vertex2A) {
-    vertexA= vertex1B;
-    vertexB= vertex2B;
-    neighborA= neighbor2A;
-    neighborB= neighbor1A;
-  }else if (vertex1A == vertex2B) {
-    vertexA= vertex1B;
-    vertexB= vertex2A;
-    neighborA= neighbor2B;
-    neighborB= neighbor1A;
-  }else if (vertex1B == vertex2A) {
-    vertexA= vertex1A;
-    vertexB= vertex2B;
-    neighborA= neighbor2A;
-    neighborB= neighbor1B;
-  }else { /* 1B == 2B */
-    vertexA= vertex1A;
-    vertexB= vertex2A;
-    neighborA= neighbor2B;
-    neighborB= neighbor1B;
-  }
-  /* vertexB always from facet2, neighborB always from facet1 */
-  if (vertexA->id > vertexB->id) {
-    SETfirst_(facet2->vertices)= vertexA;
-    SETsecond_(facet2->vertices)= vertexB;
-    if (vertexB == vertex2A)
-      facet2->toporient= !facet2->toporient;
-    SETfirst_(facet2->neighbors)= neighborA;
-    SETsecond_(facet2->neighbors)= neighborB;
-  }else {
-    SETfirst_(facet2->vertices)= vertexB;
-    SETsecond_(facet2->vertices)= vertexA;
-    if (vertexB == vertex2B)
-      facet2->toporient= !facet2->toporient;
-    SETfirst_(facet2->neighbors)= neighborB;
-    SETsecond_(facet2->neighbors)= neighborA;
-  }
-  qh_makeridges (neighborB);
-  qh_setreplace(neighborB->neighbors, facet1, facet2);
-  trace4((qh ferr, "qh_mergefacet2d: merged v%d and neighbor f%d of f%d into f%d\n",
-       vertexA->id, neighborB->id, facet1->id, facet2->id));
-} /* mergefacet2d */
-
-
-/*---------------------------------
-  
-  qh_mergeneighbors( facet1, facet2 )
-    merges the neighbors of facet1 into facet2
-
-  see: 
-    qh_mergecycle_neighbors()
-
-  design:
-    for each neighbor of facet1
-      if neighbor is also a neighbor of facet2
-        if neighbor is simpilicial
-          make ridges for later deletion as a degenerate facet
-        update its neighbor set
-      else
-        move the neighbor relation to facet2
-    remove the neighbor relation for facet1 and facet2
-*/
-void qh_mergeneighbors(facetT *facet1, facetT *facet2) {
-  facetT *neighbor, **neighborp;
-
-  trace4((qh ferr, "qh_mergeneighbors: merge neighbors of f%d and f%d\n",
-	  facet1->id, facet2->id));
-  qh visit_id++;
-  FOREACHneighbor_(facet2) {
-    neighbor->visitid= qh visit_id;
-  }
-  FOREACHneighbor_(facet1) {
-    if (neighbor->visitid == qh visit_id) {
-      if (neighbor->simplicial)    /* is degen, needs ridges */
-	qh_makeridges (neighbor);
-      if (SETfirstt_(neighbor->neighbors, facetT) != facet1) /*keep newfacet->horizon*/
-	qh_setdel (neighbor->neighbors, facet1);
-      else {
-        qh_setdel(neighbor->neighbors, facet2);
-        qh_setreplace(neighbor->neighbors, facet1, facet2);
-      }
-    }else if (neighbor != facet2) {
-      qh_setappend(&(facet2->neighbors), neighbor);
-      qh_setreplace(neighbor->neighbors, facet1, facet2);
-    }
-  }
-  qh_setdel(facet1->neighbors, facet2);  /* here for makeridges */
-  qh_setdel(facet2->neighbors, facet1);
-} /* mergeneighbors */
-
-
-/*---------------------------------
-  
-  qh_mergeridges( facet1, facet2 )
-    merges the ridge set of facet1 into facet2
-
-  returns:
-    may delete all ridges for a vertex
-    sets vertex->delridge on deleted ridges
-
-  see:
-    qh_mergecycle_ridges()
-
-  design:
-    delete ridges between facet1 and facet2
-      mark (delridge) vertices on these ridges for later testing   
-    for each remaining ridge
-      rename facet1 to facet2  
-*/
-void qh_mergeridges(facetT *facet1, facetT *facet2) {
-  ridgeT *ridge, **ridgep;
-  vertexT *vertex, **vertexp;
-
-  trace4((qh ferr, "qh_mergeridges: merge ridges of f%d and f%d\n",
-	  facet1->id, facet2->id));
-  FOREACHridge_(facet2->ridges) {
-    if ((ridge->top == facet1) || (ridge->bottom == facet1)) {
-      FOREACHvertex_(ridge->vertices)
-        vertex->delridge= True;
-      qh_delridge(ridge);  /* expensive in high-d, could rebuild */
-      ridgep--; /*repeat*/
-    }
-  }
-  FOREACHridge_(facet1->ridges) {
-    if (ridge->top == facet1)
-      ridge->top= facet2;
-    else
-      ridge->bottom= facet2;
-    qh_setappend(&(facet2->ridges), ridge);
-  }
-} /* mergeridges */
-
-
-/*---------------------------------
-  
-  qh_mergesimplex( facet1, facet2, mergeapex )
-    merge simplicial facet1 into facet2
-    mergeapex==qh_MERGEapex if merging samecycle into horizon facet
-      vertex id is latest (most recently created)
-    facet1 may be contained in facet2
-    ridges exist for both facets
-
-  returns:
-    facet2 with updated vertices, ridges, neighbors
-    updated neighbors for facet1's vertices
-    facet1 not deleted
-    sets vertex->delridge on deleted ridges
-  
-  notes:
-    special case code since this is the most common merge
-    called from qh_mergefacet()
-
-  design:
-    if qh_MERGEapex
-      add vertices of facet2 to qh.new_vertexlist if necessary
-      add apex to facet2
-    else
-      for each ridge between facet1 and facet2
-        set vertex->delridge
-      determine the apex for facet1 (i.e., vertex to be merged)
-      unless apex already in facet2
-        insert apex into vertices for facet2
-      add vertices of facet2 to qh.new_vertexlist if necessary
-      add apex to qh.new_vertexlist if necessary
-      for each vertex of facet1
-        if apex
-          rename facet1 to facet2 in its vertex neighbors
-        else
-          delete facet1 from vertex neighors
-          if only in facet2
-            add vertex to qh.del_vertices for later deletion
-      for each ridge of facet1
-        delete ridges between facet1 and facet2
-        append other ridges to facet2 after renaming facet to facet2
-*/
-void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) {
-  vertexT *vertex, **vertexp, *apex;
-  ridgeT *ridge, **ridgep;
-  boolT issubset= False;
-  int vertex_i= -1, vertex_n;
-  facetT *neighbor, **neighborp, *otherfacet;
-
-  if (mergeapex) {
-    if (!facet2->newfacet)
-      qh_newvertices (facet2->vertices);  /* apex is new */
-    apex= SETfirstt_(facet1->vertices, vertexT);
-    if (SETfirstt_(facet2->vertices, vertexT) != apex) 
-      qh_setaddnth (&facet2->vertices, 0, apex);  /* apex has last id */
-    else
-      issubset= True;
-  }else {
-    zinc_(Zmergesimplex);
-    FOREACHvertex_(facet1->vertices)
-      vertex->seen= False;
-    FOREACHridge_(facet1->ridges) {
-      if (otherfacet_(ridge, facet1) == facet2) {
-	FOREACHvertex_(ridge->vertices) {
-	  vertex->seen= True;
-	  vertex->delridge= True;
-	}
-	break;
-      }
-    }
-    FOREACHvertex_(facet1->vertices) {
-      if (!vertex->seen)
-	break;  /* must occur */
-    }
-    apex= vertex;
-    trace4((qh ferr, "qh_mergesimplex: merge apex v%d of f%d into facet f%d\n",
-	  apex->id, facet1->id, facet2->id));
-    FOREACHvertex_i_(facet2->vertices) {
-      if (vertex->id < apex->id) {
-	break;
-      }else if (vertex->id == apex->id) {
-	issubset= True;
-	break;
-      }
-    }
-    if (!issubset)
-      qh_setaddnth (&facet2->vertices, vertex_i, apex);
-    if (!facet2->newfacet)
-      qh_newvertices (facet2->vertices);
-    else if (!apex->newlist) {
-      qh_removevertex (apex);
-      qh_appendvertex (apex);
-    }
-  }
-  trace4((qh ferr, "qh_mergesimplex: update vertex neighbors of f%d\n",
-	  facet1->id));
-  FOREACHvertex_(facet1->vertices) {
-    if (vertex == apex && !issubset)
-      qh_setreplace (vertex->neighbors, facet1, facet2);
-    else {
-      qh_setdel (vertex->neighbors, facet1);
-      if (!SETsecond_(vertex->neighbors))
-	qh_mergevertex_del (vertex, facet1, facet2);
-    }
-  }
-  trace4((qh ferr, "qh_mergesimplex: merge ridges and neighbors of f%d into f%d\n",
-	  facet1->id, facet2->id));
-  qh visit_id++;
-  FOREACHneighbor_(facet2)
-    neighbor->visitid= qh visit_id;
-  FOREACHridge_(facet1->ridges) {
-    otherfacet= otherfacet_(ridge, facet1);
-    if (otherfacet == facet2) {
-      qh_setdel (facet2->ridges, ridge);
-      qh_setfree(&(ridge->vertices)); 
-      qh_memfree (ridge, sizeof(ridgeT));
-      qh_setdel (facet2->neighbors, facet1);
-    }else {
-      qh_setappend (&facet2->ridges, ridge);
-      if (otherfacet->visitid != qh visit_id) {
-	qh_setappend (&facet2->neighbors, otherfacet);
-	qh_setreplace (otherfacet->neighbors, facet1, facet2);
-	otherfacet->visitid= qh visit_id;
-      }else {
-	if (otherfacet->simplicial)    /* is degen, needs ridges */
-	  qh_makeridges (otherfacet);
-	if (SETfirstt_(otherfacet->neighbors, facetT) != facet1)
-	  qh_setdel (otherfacet->neighbors, facet1);
-	else {   /*keep newfacet->neighbors->horizon*/
-	  qh_setdel(otherfacet->neighbors, facet2);
-	  qh_setreplace(otherfacet->neighbors, facet1, facet2);
-	}
-      }
-      if (ridge->top == facet1) /* wait until after qh_makeridges */
-	ridge->top= facet2;
-      else 
-	ridge->bottom= facet2;
-    }
-  }
-  SETfirst_(facet1->ridges)= NULL; /* it will be deleted */
-  trace3((qh ferr, "qh_mergesimplex: merged simplex f%d apex v%d into facet f%d\n",
-	  facet1->id, getid_(apex), facet2->id));
-} /* mergesimplex */
-
-/*---------------------------------
-  
-  qh_mergevertex_del( vertex, facet1, facet2 )
-    delete a vertex because of merging facet1 into facet2
-
-  returns:
-    deletes vertex from facet2
-    adds vertex to qh.del_vertices for later deletion 
-*/
-void qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2) {
-
-  zinc_(Zmergevertex);
-  trace2((qh ferr, "qh_mergevertex_del: deleted v%d when merging f%d into f%d\n",
-          vertex->id, facet1->id, facet2->id));
-  qh_setdelsorted (facet2->vertices, vertex);
-  vertex->deleted= True;
-  qh_setappend (&qh del_vertices, vertex);
-} /* mergevertex_del */
-
-/*---------------------------------
-  
-  qh_mergevertex_neighbors( facet1, facet2 )
-    merge the vertex neighbors of facet1 to facet2
-
-  returns:
-    if vertex is current qh.vertex_visit
-      deletes facet1 from vertex->neighbors
-    else
-      renames facet1 to facet2 in vertex->neighbors 
-    deletes vertices if only one neighbor
-  
-  notes:
-    assumes vertex neighbor sets are good
-*/
-void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2) {
-  vertexT *vertex, **vertexp;
-
-  trace4((qh ferr, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n",
-	  facet1->id, facet2->id));
-  if (qh tracevertex) {
-    fprintf (qh ferr, "qh_mergevertex_neighbors: of f%d and f%d at furthest p%d f0= %p\n",
-	     facet1->id, facet2->id, qh furthest_id, qh tracevertex->neighbors->e[0].p);
-    qh_errprint ("TRACE", NULL, NULL, NULL, qh tracevertex);
-  }
-  FOREACHvertex_(facet1->vertices) {
-    if (vertex->visitid != qh vertex_visit) 
-      qh_setreplace(vertex->neighbors, facet1, facet2);
-    else {
-      qh_setdel(vertex->neighbors, facet1);
-      if (!SETsecond_(vertex->neighbors))
-	qh_mergevertex_del (vertex, facet1, facet2);
-    }
-  }
-  if (qh tracevertex) 
-    qh_errprint ("TRACE", NULL, NULL, NULL, qh tracevertex);
-} /* mergevertex_neighbors */
-
-
-/*---------------------------------
-  
-  qh_mergevertices( vertices1, vertices2 )
-    merges the vertex set of facet1 into facet2
-
-  returns:
-    replaces vertices2 with merged set
-    preserves vertex_visit for qh_mergevertex_neighbors
-    updates qh.newvertex_list
-
-  design:
-    create a merged set of both vertices (in inverse id order)
-*/
-void qh_mergevertices(setT *vertices1, setT **vertices2) {
-  int newsize= qh_setsize(vertices1)+qh_setsize(*vertices2) - qh hull_dim + 1;
-  setT *mergedvertices;
-  vertexT *vertex, **vertexp, **vertex2= SETaddr_(*vertices2, vertexT);
-
-  mergedvertices= qh_settemp (newsize);
-  FOREACHvertex_(vertices1) {
-    if (!*vertex2 || vertex->id > (*vertex2)->id)
-      qh_setappend (&mergedvertices, vertex);
-    else {
-      while (*vertex2 && (*vertex2)->id > vertex->id)
-	qh_setappend (&mergedvertices, *vertex2++);
-      if (!*vertex2 || (*vertex2)->id < vertex->id)
-	qh_setappend (&mergedvertices, vertex);
-      else
-	qh_setappend (&mergedvertices, *vertex2++);
-    }
-  }
-  while (*vertex2)
-    qh_setappend (&mergedvertices, *vertex2++);
-  if (newsize < qh_setsize (mergedvertices)) {
-    fprintf (qh ferr, "qhull internal error (qh_mergevertices): facets did not share a ridge\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh_setfree(vertices2);
-  *vertices2= mergedvertices;
-  qh_settemppop ();
-} /* mergevertices */
-
-
-/*---------------------------------
-  
-  qh_neighbor_intersections( vertex )
-    return intersection of all vertices in vertex->neighbors except for vertex
-
-  returns:
-    returns temporary set of vertices
-    does not include vertex
-    NULL if a neighbor is simplicial
-    NULL if empty set
-    
-  notes:
-    used for renaming vertices
-
-  design:
-    initialize the intersection set with vertices of the first two neighbors
-    delete vertex from the intersection
-    for each remaining neighbor
-      intersect its vertex set with the intersection set
-      return NULL if empty
-    return the intersection set  
-*/
-setT *qh_neighbor_intersections (vertexT *vertex) {
-  facetT *neighbor, **neighborp, *neighborA, *neighborB;
-  setT *intersect;
-  int neighbor_i, neighbor_n;
-
-  FOREACHneighbor_(vertex) {
-    if (neighbor->simplicial)
-      return NULL;
-  }
-  neighborA= SETfirstt_(vertex->neighbors, facetT);
-  neighborB= SETsecondt_(vertex->neighbors, facetT);
-  zinc_(Zintersectnum);
-  if (!neighborA)
-    return NULL;
-  if (!neighborB)
-    intersect= qh_setcopy (neighborA->vertices, 0);
-  else
-    intersect= qh_vertexintersect_new (neighborA->vertices, neighborB->vertices);
-  qh_settemppush (intersect);
-  qh_setdelsorted (intersect, vertex);
-  FOREACHneighbor_i_(vertex) {
-    if (neighbor_i >= 2) {
-      zinc_(Zintersectnum);
-      qh_vertexintersect (&intersect, neighbor->vertices);
-      if (!SETfirst_(intersect)) {
-        zinc_(Zintersectfail);
-        qh_settempfree (&intersect);
-        return NULL;
-      }
-    }
-  }
-  trace3((qh ferr, "qh_neighbor_intersections: %d vertices in neighbor intersection of v%d\n", 
-          qh_setsize (intersect), vertex->id));
-  return intersect;
-} /* neighbor_intersections */
-
-/*---------------------------------
-  
-  qh_newvertices( vertices )
-    add vertices to end of qh.vertex_list (marks as new vertices)
-
-  returns:
-    vertices on qh.newvertex_list
-    vertex->newlist set
-*/
-void qh_newvertices (setT *vertices) {
-  vertexT *vertex, **vertexp;
-
-  FOREACHvertex_(vertices) {
-    if (!vertex->newlist) {
-      qh_removevertex (vertex);
-      qh_appendvertex (vertex);
-    }
-  }
-} /* newvertices */
-
-/*---------------------------------
-  
-  qh_reducevertices()
-    reduce extra vertices, shared vertices, and redundant vertices
-    facet->newmerge is set if merged since last call
-    if !qh.MERGEvertices, only removes extra vertices
-
-  returns:
-    True if also merged degen_redundant facets
-    vertices are renamed if possible
-    clears facet->newmerge and vertex->delridge
-
-  notes:
-    ignored if 2-d
-
-  design:
-    merge any degenerate or redundant facets
-    for each newly merged facet
-      remove extra vertices
-    if qh.MERGEvertices
-      for each newly merged facet
-        for each vertex
-          if vertex was on a deleted ridge
-            rename vertex if it is shared
-      remove delridge flag from new vertices
-*/
-boolT qh_reducevertices (void) {
-  int numshare=0, numrename= 0;
-  boolT degenredun= False;
-  facetT *newfacet;
-  vertexT *vertex, **vertexp;
-
-  if (qh hull_dim == 2) 
-    return False;
-  if (qh_merge_degenredundant())
-    degenredun= True;
- LABELrestart:
-  FORALLnew_facets {
-    if (newfacet->newmerge) { 
-      if (!qh MERGEvertices)
-        newfacet->newmerge= False;
-      qh_remove_extravertices (newfacet);
-    }
-  }
-  if (!qh MERGEvertices)
-    return False;
-  FORALLnew_facets {
-    if (newfacet->newmerge) {
-      newfacet->newmerge= False;
-      FOREACHvertex_(newfacet->vertices) {
-	if (vertex->delridge) {
-	  if (qh_rename_sharedvertex (vertex, newfacet)) {
-	    numshare++;
-	    vertexp--; /* repeat since deleted vertex */
-	  }
-        }
-      }
-    }
-  }
-  FORALLvertex_(qh newvertex_list) {
-    if (vertex->delridge && !vertex->deleted) {
-      vertex->delridge= False;
-      if (qh hull_dim >= 4 && qh_redundant_vertex (vertex)) {
-	numrename++;
-	if (qh_merge_degenredundant()) {
-	  degenredun= True;
-	  goto LABELrestart;
-	}
-      }
-    }
-  }
-  trace1((qh ferr, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n",
-	  numshare, numrename, degenredun));
-  return degenredun;
-} /* reducevertices */
-      
-/*---------------------------------
-  
-  qh_redundant_vertex( vertex )
-    detect and rename a redundant vertex
-    vertices have full vertex->neighbors 
-
-  returns:
-    returns true if find a redundant vertex
-      deletes vertex (vertex->deleted)
-  
-  notes:
-    only needed if vertex->delridge and hull_dim >= 4
-    may add degenerate facets to qh.facet_mergeset
-    doesn't change vertex->neighbors or create redundant facets
-
-  design:
-    intersect vertices of all facet neighbors of vertex
-    determine ridges for these vertices
-    if find a new vertex for vertex amoung these ridges and vertices
-      rename vertex to the new vertex
-*/
-vertexT *qh_redundant_vertex (vertexT *vertex) {
-  vertexT *newvertex= NULL;
-  setT *vertices, *ridges;
-
-  trace3((qh ferr, "qh_redundant_vertex: check if v%d can be renamed\n", vertex->id));  
-  if ((vertices= qh_neighbor_intersections (vertex))) {
-    ridges= qh_vertexridges (vertex);
-    if ((newvertex= qh_find_newvertex (vertex, vertices, ridges)))
-      qh_renamevertex (vertex, newvertex, ridges, NULL, NULL);
-    qh_settempfree (&ridges);
-    qh_settempfree (&vertices);
-  }
-  return newvertex;
-} /* redundant_vertex */
-
-/*---------------------------------
-  
-  qh_remove_extravertices( facet )
-    remove extra vertices from non-simplicial facets
-
-  returns:
-    returns True if it finds them
-
-  design:
-    for each vertex in facet
-      if vertex not in a ridge (i.e., no longer used)
-        delete vertex from facet
-        delete facet from vertice's neighbors
-        unless vertex in another facet
-          add vertex to qh.del_vertices for later deletion
-*/
-boolT qh_remove_extravertices (facetT *facet) {
-  ridgeT *ridge, **ridgep;
-  vertexT *vertex, **vertexp;
-  boolT foundrem= False;
-
-  trace4((qh ferr, "qh_remove_extravertices: test f%d for extra vertices\n",
-	  facet->id));
-  FOREACHvertex_(facet->vertices)
-    vertex->seen= False;
-  FOREACHridge_(facet->ridges) { 
-    FOREACHvertex_(ridge->vertices)
-      vertex->seen= True;
-  }
-  FOREACHvertex_(facet->vertices) {
-    if (!vertex->seen) {
-      foundrem= True;
-      zinc_(Zremvertex);
-      qh_setdelsorted (facet->vertices, vertex);
-      qh_setdel (vertex->neighbors, facet);
-      if (!qh_setsize (vertex->neighbors)) {
-	vertex->deleted= True;
-	qh_setappend (&qh del_vertices, vertex);
-	zinc_(Zremvertexdel);
-	trace2((qh ferr, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id));
-      }else
-	trace3((qh ferr, "qh_remove_extravertices: v%d removed from f%d because it's lost all ridges\n", vertex->id, facet->id));
-      vertexp--; /*repeat*/
-    }
-  }
-  return foundrem;
-} /* remove_extravertices */
-
-/*---------------------------------
-  
-  qh_rename_sharedvertex( vertex, facet )
-    detect and rename if shared vertex in facet
-    vertices have full ->neighbors
-
-  returns:
-    newvertex or NULL
-    the vertex may still exist in other facets (i.e., a neighbor was pinched)
-    does not change facet->neighbors
-    updates vertex->neighbors
-  
-  notes:
-    a shared vertex for a facet is only in ridges to one neighbor
-    this may undo a pinched facet
- 
-    it does not catch pinches involving multiple facets.  These appear
-      to be difficult to detect, since an exhaustive search is too expensive.
-
-  design:
-    if vertex only has two neighbors
-      determine the ridges that contain the vertex
-      determine the vertices shared by both neighbors
-      if can find a new vertex in this set
-        rename the vertex to the new vertex
-*/
-vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet) {
-  facetT *neighbor, **neighborp, *neighborA= NULL;
-  setT *vertices, *ridges;
-  vertexT *newvertex;
-
-  if (qh_setsize (vertex->neighbors) == 2) {
-    neighborA= SETfirstt_(vertex->neighbors, facetT);
-    if (neighborA == facet)
-      neighborA= SETsecondt_(vertex->neighbors, facetT);
-  }else if (qh hull_dim == 3)
-    return NULL;
-  else {
-    qh visit_id++;
-    FOREACHneighbor_(facet)
-      neighbor->visitid= qh visit_id;
-    FOREACHneighbor_(vertex) {
-      if (neighbor->visitid == qh visit_id) {
-        if (neighborA)
-          return NULL;
-        neighborA= neighbor;
-      }
-    }
-    if (!neighborA) {
-      fprintf (qh ferr, "qhull internal error (qh_rename_sharedvertex): v%d's neighbors not in f%d\n",
-        vertex->id, facet->id);
-      qh_errprint ("ERRONEOUS", facet, NULL, NULL, vertex);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-  }
-  /* the vertex is shared by facet and neighborA */
-  ridges= qh_settemp (qh TEMPsize);
-  neighborA->visitid= ++qh visit_id;
-  qh_vertexridges_facet (vertex, facet, &ridges);
-  trace2((qh ferr, "qh_rename_sharedvertex: p%d (v%d) is shared by f%d (%d ridges) and f%d\n",
-    qh_pointid(vertex->point), vertex->id, facet->id, qh_setsize (ridges), neighborA->id));
-  zinc_(Zintersectnum);
-  vertices= qh_vertexintersect_new (facet->vertices, neighborA->vertices);
-  qh_setdel (vertices, vertex);
-  qh_settemppush (vertices);
-  if ((newvertex= qh_find_newvertex (vertex, vertices, ridges))) 
-    qh_renamevertex (vertex, newvertex, ridges, facet, neighborA);
-  qh_settempfree (&vertices);
-  qh_settempfree (&ridges);
-  return newvertex;
-} /* rename_sharedvertex */
-
-/*---------------------------------
-  
-  qh_renameridgevertex( ridge, oldvertex, newvertex )
-    renames oldvertex as newvertex in ridge
-
-  returns:
-  
-  design:
-    delete oldvertex from ridge
-    if newvertex already in ridge
-      copy ridge->noconvex to another ridge if possible
-      delete the ridge
-    else
-      insert newvertex into the ridge
-      adjust the ridge's orientation
-*/
-void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) {
-  int nth= 0, oldnth;
-  facetT *temp;
-  vertexT *vertex, **vertexp;
-
-  oldnth= qh_setindex (ridge->vertices, oldvertex);
-  qh_setdelnthsorted (ridge->vertices, oldnth);
-  FOREACHvertex_(ridge->vertices) {
-    if (vertex == newvertex) {
-      zinc_(Zdelridge);
-      if (ridge->nonconvex) /* only one ridge has nonconvex set */
-	qh_copynonconvex (ridge);
-      qh_delridge (ridge);
-      trace2((qh ferr, "qh_renameridgevertex: ridge r%d deleted.  It contained both v%d and v%d\n",
-        ridge->id, oldvertex->id, newvertex->id));
-      return;
-    }
-    if (vertex->id < newvertex->id)
-      break;
-    nth++;
-  }
-  qh_setaddnth(&ridge->vertices, nth, newvertex);
-  if (abs(oldnth - nth)%2) {
-    trace3((qh ferr, "qh_renameridgevertex: swapped the top and bottom of ridge r%d\n", 
-	    ridge->id));
-    temp= ridge->top;
-    ridge->top= ridge->bottom;
-    ridge->bottom= temp;
-  }
-} /* renameridgevertex */
-
-
-/*---------------------------------
-  
-  qh_renamevertex( oldvertex, newvertex, ridges, oldfacet, neighborA )
-    renames oldvertex as newvertex in ridges 
-    gives oldfacet/neighborA if oldvertex is shared between two facets
-
-  returns:
-    oldvertex may still exist afterwards
-    
-
-  notes:
-    can not change neighbors of newvertex (since it's a subset)
-
-  design:
-    for each ridge in ridges
-      rename oldvertex to newvertex and delete degenerate ridges
-    if oldfacet not defined
-      for each neighbor of oldvertex
-        delete oldvertex from neighbor's vertices
-        remove extra vertices from neighbor
-      add oldvertex to qh.del_vertices
-    else if oldvertex only between oldfacet and neighborA
-      delete oldvertex from oldfacet and neighborA
-      add oldvertex to qh.del_vertices
-    else oldvertex is in oldfacet and neighborA and other facets (i.e., pinched)
-      delete oldvertex from oldfacet
-      delete oldfacet from oldvertice's neighbors
-      remove extra vertices (e.g., oldvertex) from neighborA
-*/
-void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges, facetT *oldfacet, facetT *neighborA) {
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  boolT istrace= False;
-
-  if (qh IStracing >= 2 || oldvertex->id == qh tracevertex_id ||
-	newvertex->id == qh tracevertex_id)
-    istrace= True;
-  FOREACHridge_(ridges) 
-    qh_renameridgevertex (ridge, oldvertex, newvertex);
-  if (!oldfacet) {
-    zinc_(Zrenameall);
-    if (istrace)
-      fprintf (qh ferr, "qh_renamevertex: renamed v%d to v%d in several facets\n",
-               oldvertex->id, newvertex->id);
-    FOREACHneighbor_(oldvertex) {
-      qh_maydropneighbor (neighbor);
-      qh_setdelsorted (neighbor->vertices, oldvertex);
-      if (qh_remove_extravertices (neighbor))
-        neighborp--; /* neighbor may be deleted */
-    }
-    if (!oldvertex->deleted) {
-      oldvertex->deleted= True;
-      qh_setappend (&qh del_vertices, oldvertex);
-    }
-  }else if (qh_setsize (oldvertex->neighbors) == 2) {
-    zinc_(Zrenameshare);
-    if (istrace)
-      fprintf (qh ferr, "qh_renamevertex: renamed v%d to v%d in oldfacet f%d\n", 
-               oldvertex->id, newvertex->id, oldfacet->id);
-    FOREACHneighbor_(oldvertex)
-      qh_setdelsorted (neighbor->vertices, oldvertex);
-    oldvertex->deleted= True;
-    qh_setappend (&qh del_vertices, oldvertex);
-  }else {
-    zinc_(Zrenamepinch);
-    if (istrace || qh IStracing)
-      fprintf (qh ferr, "qh_renamevertex: renamed pinched v%d to v%d between f%d and f%d\n", 
-               oldvertex->id, newvertex->id, oldfacet->id, neighborA->id);
-    qh_setdelsorted (oldfacet->vertices, oldvertex);
-    qh_setdel (oldvertex->neighbors, oldfacet);
-    qh_remove_extravertices (neighborA);
-  }
-} /* renamevertex */
-
-
-/*---------------------------------
-  
-  qh_test_appendmerge( facet, neighbor )
-    tests facet/neighbor for convexity
-    appends to mergeset if non-convex
-    if pre-merging, 
-      nop if qh.SKIPconvex, or qh.MERGEexact and coplanar
-
-  returns:
-    true if appends facet/neighbor to mergeset
-    sets facet->center as needed
-    does not change facet->seen
-
-  design:
-    if qh.cos_max is defined
-      if the angle between facet normals is too shallow
-        append an angle-coplanar merge to qh.mergeset
-        return True
-    make facet's centrum if needed
-    if facet's centrum is above the neighbor
-      set isconcave
-    else
-      if facet's centrum is not below the neighbor
-        set iscoplanar
-      make neighbor's centrum if needed
-      if neighbor's centrum is above the facet
-        set isconcave
-      else if neighbor's centrum is not below the facet
-        set iscoplanar
-   if isconcave or iscoplanar
-     get angle if needed
-     append concave or coplanar merge to qh.mergeset
-*/
-boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) {
-  realT dist, dist2= -REALmax, angle= -REALmax;
-  boolT isconcave= False, iscoplanar= False, okangle= False;
-
-  if (qh SKIPconvex && !qh POSTmerging)
-    return False;
-  if ((!qh MERGEexact || qh POSTmerging) && qh cos_max < REALmax/2) {
-    angle= qh_getangle(facet->normal, neighbor->normal);
-    zinc_(Zangletests);
-    if (angle > qh cos_max) {
-      zinc_(Zcoplanarangle);
-      qh_appendmergeset(facet, neighbor, MRGanglecoplanar, &angle);
-      trace2((qh ferr, "qh_test_appendmerge: coplanar angle %4.4g between f%d and f%d\n",
-         angle, facet->id, neighbor->id));
-      return True;
-    }else
-      okangle= True;
-  }
-  if (!facet->center)
-    facet->center= qh_getcentrum (facet);
-  zzinc_(Zcentrumtests);
-  qh_distplane(facet->center, neighbor, &dist);
-  if (dist > qh centrum_radius)
-    isconcave= True;
-  else {
-    if (dist > -qh centrum_radius)
-      iscoplanar= True;
-    if (!neighbor->center)
-      neighbor->center= qh_getcentrum (neighbor);
-    zzinc_(Zcentrumtests);
-    qh_distplane(neighbor->center, facet, &dist2);
-    if (dist2 > qh centrum_radius)
-      isconcave= True;
-    else if (!iscoplanar && dist2 > -qh centrum_radius)
-      iscoplanar= True;
-  }
-  if (!isconcave && (!iscoplanar || (qh MERGEexact && !qh POSTmerging)))
-    return False;
-  if (!okangle && qh ANGLEmerge) {
-    angle= qh_getangle(facet->normal, neighbor->normal);
-    zinc_(Zangletests);
-  }
-  if (isconcave) {
-    zinc_(Zconcaveridge);
-    if (qh ANGLEmerge)
-      angle += qh_ANGLEconcave + 0.5;
-    qh_appendmergeset(facet, neighbor, MRGconcave, &angle);
-    trace0((qh ferr, "qh_test_appendmerge: concave f%d to f%d dist %4.4g and reverse dist %4.4g angle %4.4g during p%d\n",
-	   facet->id, neighbor->id, dist, dist2, angle, qh furthest_id));
-  }else /* iscoplanar */ {
-    zinc_(Zcoplanarcentrum);
-    qh_appendmergeset(facet, neighbor, MRGcoplanar, &angle);
-    trace2((qh ferr, "qh_test_appendmerge: coplanar f%d to f%d dist %4.4g, reverse dist %4.4g angle %4.4g\n",
-	      facet->id, neighbor->id, dist, dist2, angle));
-  }
-  return True;
-} /* test_appendmerge */
-
-/*---------------------------------
-  
-  qh_test_vneighbors()
-    test vertex neighbors for convexity
-    tests all facets on qh.newfacet_list
-
-  returns:
-    true if non-convex vneighbors appended to qh.facet_mergeset
-    initializes vertex neighbors if needed
-
-  notes:
-    assumes all facet neighbors have been tested
-    this can be expensive
-    this does not guarantee that a centrum is below all facets
-      but it is unlikely
-    uses qh.visit_id
-
-  design:
-    build vertex neighbors if necessary
-    for all new facets
-      for all vertices
-        for each unvisited facet neighbor of the vertex
-          test new facet and neighbor for convexity
-*/
-boolT qh_test_vneighbors (void /* qh newfacet_list */) {
-  facetT *newfacet, *neighbor, **neighborp;
-  vertexT *vertex, **vertexp;
-  int nummerges= 0;
-
-  trace1((qh ferr, "qh_test_vneighbors: testing vertex neighbors for convexity\n"));
-  if (!qh VERTEXneighbors)
-    qh_vertexneighbors();
-  FORALLnew_facets 
-    newfacet->seen= False;
-  FORALLnew_facets {
-    newfacet->seen= True;
-    newfacet->visitid= qh visit_id++;
-    FOREACHneighbor_(newfacet)
-      newfacet->visitid= qh visit_id;
-    FOREACHvertex_(newfacet->vertices) {
-      FOREACHneighbor_(vertex) {
-      	if (neighbor->seen || neighbor->visitid == qh visit_id)
-      	  continue;
-      	if (qh_test_appendmerge (newfacet, neighbor))
-          nummerges++;
-      }
-    }
-  }
-  zadd_(Ztestvneighbor, nummerges);
-  trace1((qh ferr, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n",
-           nummerges));
-  return (nummerges > 0);    
-} /* test_vneighbors */
-
-/*---------------------------------
-  
-  qh_tracemerge( facet1, facet2 )
-    print trace message after merge
-*/
-void qh_tracemerge (facetT *facet1, facetT *facet2) {
-  boolT waserror= False;
-
-#ifndef qh_NOtrace
-  if (qh IStracing >= 4) 
-    qh_errprint ("MERGED", facet2, NULL, NULL, NULL);
-  if (facet2 == qh tracefacet || (qh tracevertex && qh tracevertex->newlist)) {
-    fprintf (qh ferr, "qh_tracemerge: trace facet and vertex after merge of f%d and f%d, furthest p%d\n", facet1->id, facet2->id, qh furthest_id);
-    if (facet2 != qh tracefacet)
-      qh_errprint ("TRACE", qh tracefacet, 
-        (qh tracevertex && qh tracevertex->neighbors) ? 
-           SETfirstt_(qh tracevertex->neighbors, facetT) : NULL,
-        NULL, qh tracevertex);      
-  }
-  if (qh tracevertex) {
-    if (qh tracevertex->deleted)
-      fprintf (qh ferr, "qh_tracemerge: trace vertex deleted at furthest p%d\n",
-	    qh furthest_id);
-    else
-      qh_checkvertex (qh tracevertex);
-  }
-  if (qh tracefacet) {
-    qh_checkfacet (qh tracefacet, True, &waserror);
-    if (waserror)
-      qh_errexit (qh_ERRqhull, qh tracefacet, NULL);
-  }
-#endif /* !qh_NOtrace */
-  if (qh CHECKfrequently || qh IStracing >= 4) { /* can't check polygon here */
-    qh_checkfacet (facet2, True, &waserror);
-    if (waserror)
-      qh_errexit(qh_ERRqhull, NULL, NULL);
-  }
-} /* tracemerge */
-
-/*---------------------------------
-  
-  qh_tracemerging()
-    print trace message during POSTmerging
-
-  returns:
-    updates qh.mergereport
-  
-  notes:
-    called from qh_mergecycle() and qh_mergefacet()
-  
-  see:
-    qh_buildtracing()
-*/
-void qh_tracemerging (void) {
-  realT cpu;
-  int total;
-  time_t timedata;
-  struct tm *tp;
-
-  qh mergereport= zzval_(Ztotmerge);
-  time (&timedata);
-  tp= localtime (&timedata);
-  cpu= qh_CPUclock;
-  cpu /= qh_SECticks;
-  total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-  fprintf (qh ferr, "\n\
-At %d:%d:%d & %2.5g CPU secs, qhull has merged %d facets.  The hull\n\
-  contains %d facets and %d vertices.\n",
-      tp->tm_hour, tp->tm_min, tp->tm_sec, cpu,
-      total, qh num_facets - qh num_visible,
-      qh num_vertices-qh_setsize (qh del_vertices));
-} /* tracemerging */
-
-/*---------------------------------
-  
-  qh_updatetested( facet1, facet2 )
-    clear facet2->tested and facet1->ridge->tested for merge
-
-  returns:
-    deletes facet2->center unless it's already large
-      if so, clears facet2->ridge->tested
-
-  design:
-    clear facet2->tested
-    clear ridge->tested for facet1's ridges
-    if facet2 has a centrum
-      if facet2 is large
-        set facet2->keepcentrum 
-      else if facet2 has 3 vertices due to many merges, or not large and post merging
-        clear facet2->keepcentrum
-      unless facet2->keepcentrum
-        clear facet2->center to recompute centrum later
-        clear ridge->tested for facet2's ridges
-*/
-void qh_updatetested (facetT *facet1, facetT *facet2) {
-  ridgeT *ridge, **ridgep;
-  int size;
-  
-  facet2->tested= False;
-  FOREACHridge_(facet1->ridges)
-    ridge->tested= False;
-  if (!facet2->center)
-    return;
-  size= qh_setsize (facet2->vertices);
-  if (!facet2->keepcentrum) {
-    if (size > qh hull_dim + qh_MAXnewcentrum) {
-      facet2->keepcentrum= True;
-      zinc_(Zwidevertices);
-    }
-  }else if (size <= qh hull_dim + qh_MAXnewcentrum) {
-    /* center and keepcentrum was set */
-    if (size == qh hull_dim || qh POSTmerging)
-      facet2->keepcentrum= False; /* if many merges need to recompute centrum */
-  }
-  if (!facet2->keepcentrum) {
-    qh_memfree (facet2->center, qh normal_size);
-    facet2->center= NULL;
-    FOREACHridge_(facet2->ridges)
-      ridge->tested= False;
-  }
-} /* updatetested */
-
-/*---------------------------------
-  
-  qh_vertexridges( vertex )
-    return temporary set of ridges adjacent to a vertex
-    vertex->neighbors defined
-
-  ntoes:
-    uses qh.visit_id
-    does not include implicit ridges for simplicial facets
-
-  design:
-    for each neighbor of vertex
-      add ridges that include the vertex to ridges  
-*/
-setT *qh_vertexridges (vertexT *vertex) {
-  facetT *neighbor, **neighborp;
-  setT *ridges= qh_settemp (qh TEMPsize);
-  int size;
-
-  qh visit_id++;
-  FOREACHneighbor_(vertex)
-    neighbor->visitid= qh visit_id;
-  FOREACHneighbor_(vertex) {
-    if (*neighborp)   /* no new ridges in last neighbor */
-      qh_vertexridges_facet (vertex, neighbor, &ridges);
-  }
-  if (qh PRINTstatistics || qh IStracing) {
-    size= qh_setsize (ridges);
-    zinc_(Zvertexridge);
-    zadd_(Zvertexridgetot, size);
-    zmax_(Zvertexridgemax, size);
-    trace3((qh ferr, "qh_vertexridges: found %d ridges for v%d\n",
-             size, vertex->id));
-  }
-  return ridges;
-} /* vertexridges */
-
-/*---------------------------------
-  
-  qh_vertexridges_facet( vertex, facet, ridges )
-    add adjacent ridges for vertex in facet
-    neighbor->visitid==qh.visit_id if it hasn't been visited
-
-  returns:
-    ridges updated
-    sets facet->visitid to qh.visit_id-1
-
-  design:
-    for each ridge of facet
-      if ridge of visited neighbor (i.e., unprocessed)
-        if vertex in ridge
-          append ridge to vertex
-    mark facet processed
-*/
-void qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges) {
-  ridgeT *ridge, **ridgep;
-  facetT *neighbor;
-
-  FOREACHridge_(facet->ridges) {
-    neighbor= otherfacet_(ridge, facet);
-    if (neighbor->visitid == qh visit_id 
-    && qh_setin (ridge->vertices, vertex))
-      qh_setappend (ridges, ridge);
-  }
-  facet->visitid= qh visit_id-1;
-} /* vertexridges_facet */
-
-/*---------------------------------
-  
-  qh_willdelete( facet, replace )
-    moves facet to visible list
-    sets facet->f.replace to replace (may be NULL)
-
-  returns:
-    bumps qh.num_visible
-*/
-void qh_willdelete (facetT *facet, facetT *replace) {
-
-  qh_removefacet(facet);
-  qh_prependfacet (facet, &qh visible_list);
-  qh num_visible++;
-  facet->visible= True;
-  facet->f.replace= replace;
-} /* willdelete */
-
-#else /* qh_NOmerge */
-void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle) {
-}
-void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-                      boolT vneighbors) {
-}
-boolT qh_checkzero (boolT testall) {
-   }
-#endif /* qh_NOmerge */
-
diff --git a/extern/qhull/src/merge.h b/extern/qhull/src/merge.h
deleted file mode 100644
index 7fc2afa5967..00000000000
--- a/extern/qhull/src/merge.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
  ---------------------------------
-
-   merge.h 
-   header file for merge.c
-
-   see qh-merge.htm and merge.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmerge
-#define qhDEFmerge 1
-
-
-/*============ -constants- ==============*/
-
-/*----------------------------------
-
-  qh_ANGLEredundant
-    indicates redundant merge in mergeT->angle
-*/
-#define qh_ANGLEredundant 6.0
-
-/*----------------------------------
-  
-  qh_ANGLEdegen
-    indicates degenerate facet in mergeT->angle
-*/
-#define qh_ANGLEdegen     5.0
-
-/*----------------------------------
-  
-  qh_ANGLEconcave
-    offset to indicate concave facets in mergeT->angle
-  
-  notes:
-    concave facets are assigned the range of [2,4] in mergeT->angle
-    roundoff error may make the angle less than 2
-*/
-#define qh_ANGLEconcave  1.5
-
-/*----------------------------------
-  
-  MRG... (mergeType)
-    indicates the type of a merge (mergeT->type)
-*/
-typedef enum {	/* in sort order for facet_mergeset */
-  MRGnone= 0,
-  MRGcoplanar,		/* centrum coplanar */
-  MRGanglecoplanar,	/* angle coplanar */
-  			/* could detect half concave ridges */
-  MRGconcave,		/* concave ridge */
-  MRGflip,		/* flipped facet. facet1 == facet2 */
-  MRGridge,		/* duplicate ridge (qh_MERGEridge) */
-                        /* degen and redundant go onto degen_mergeset */
-  MRGdegen,		/* degenerate facet (not enough neighbors) facet1 == facet2 */
-  MRGredundant,		/* redundant facet (vertex subset) */
-  			/* merge_degenredundant assumes degen < redundant */
-  MRGmirror,	        /* mirror facet from qh_triangulate */
-  ENDmrg
-} mergeType;
-
-/*----------------------------------
-  
-  qh_MERGEapex
-    flag for qh_mergefacet() to indicate an apex merge  
-*/
-#define qh_MERGEapex     True
-
-/*============ -structures- ====================*/
-
-/*----------------------------------
-     
-  mergeT
-    structure used to merge facets
-*/
-
-typedef struct mergeT mergeT;
-struct mergeT {		/* initialize in qh_appendmergeset */
-  realT   angle;        /* angle between normals of facet1 and facet2 */
-  facetT *facet1; 	/* will merge facet1 into facet2 */
-  facetT *facet2;
-  mergeType type;
-};
-
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-     
-  FOREACHmerge_( merges ) {...}
-    assign 'merge' to each merge in merges
-       
-  notes:
-    uses 'mergeT *merge, **mergep;'
-    if qh_mergefacet(),
-      restart since qh.facet_mergeset may change
-    see FOREACHsetelement_
-*/
-#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
-
-/*============ prototypes in alphabetical order after pre/postmerge =======*/
-
-void    qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle);
-void    qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-             boolT vneighbors);
-void    qh_all_merges (boolT othermerge, boolT vneighbors);
-void    qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
-setT   *qh_basevertices( facetT *samecycle);
-void    qh_checkconnect (void /* qh new_facets */);
-boolT   qh_checkzero (boolT testall);
-void    qh_copynonconvex (ridgeT *atridge);
-void    qh_degen_redundant_facet (facetT *facet);
-void   	qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet);
-vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges);
-void    qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor,
-           facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
-facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
-void 	qh_flippedmerges(facetT *facetlist, boolT *wasmerge);
-void 	qh_forcedmerges( boolT *wasmerge);
-void	qh_getmergeset(facetT *facetlist);
-void 	qh_getmergeset_initial (facetT *facetlist);
-void    qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
-ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, 
-              vertexT *vertex, vertexT *oldvertex, int *hashslot);
-void 	qh_makeridges(facetT *facet);
-void    qh_mark_dupridges(facetT *facetlist);
-void    qh_maydropneighbor (facetT *facet);
-int     qh_merge_degenredundant (void);
-void    qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype);
-void    qh_mergecycle (facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_all (facetT *facetlist, boolT *wasmerge);
-void    qh_mergecycle_facets( facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet);
-void 	qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
-void    qh_mergefacet2d (facetT *facet1, facetT *facet2);
-void 	qh_mergeneighbors(facetT *facet1, facetT *facet2);
-void 	qh_mergeridges(facetT *facet1, facetT *facet2);
-void    qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex);
-void    qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2);
-void    qh_mergevertex_neighbors(facetT *facet1, facetT *facet2);
-void	qh_mergevertices(setT *vertices1, setT **vertices);
-setT   *qh_neighbor_intersections (vertexT *vertex);
-void    qh_newvertices (setT *vertices);
-boolT   qh_reducevertices (void);
-vertexT *qh_redundant_vertex (vertexT *vertex);
-boolT   qh_remove_extravertices (facetT *facet);
-vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet);
-void	qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
-void    qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges,
-			facetT *oldfacet, facetT *neighborA);
-boolT 	qh_test_appendmerge (facetT *facet, facetT *neighbor);
-boolT   qh_test_vneighbors (void /* qh newfacet_list */);
-void    qh_tracemerge (facetT *facet1, facetT *facet2);
-void    qh_tracemerging (void);
-void    qh_updatetested( facetT *facet1, facetT *facet2);
-setT   *qh_vertexridges (vertexT *vertex);
-void    qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges);
-void    qh_willdelete (facetT *facet, facetT *replace);
-
-#endif /* qhDEFmerge */
diff --git a/extern/qhull/src/poly.c b/extern/qhull/src/poly.c
deleted file mode 100644
index 6319e43d66a..00000000000
--- a/extern/qhull/src/poly.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
  ---------------------------------
-
-   poly.c 
-   implements polygons and simplices
-
-   see qh-poly.htm, poly.h and qhull.h
-
-   infrequent code is in poly2.c 
-   (all but top 50 and their callers 12/3/95)
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include "qhull_a.h"
-
-/*======== functions in alphabetical order ==========*/
-
-/*---------------------------------
-  
-  qh_appendfacet( facet )
-    appends facet to end of qh.facet_list,
-
-  returns:
-    updates qh.newfacet_list, facet_next, facet_list
-    increments qh.numfacets
-  
-  notes:
-    assumes qh.facet_list/facet_tail is defined (createsimplex)
-
-  see:
-    qh_removefacet()
-
-*/
-void qh_appendfacet(facetT *facet) {
-  facetT *tail= qh facet_tail;
-
-  if (tail == qh newfacet_list)
-    qh newfacet_list= facet;
-  if (tail == qh facet_next)
-    qh facet_next= facet;
-  facet->previous= tail->previous;
-  facet->next= tail;
-  if (tail->previous)
-    tail->previous->next= facet;
-  else
-    qh facet_list= facet;
-  tail->previous= facet;
-  qh num_facets++;
-  trace4((qh ferr, "qh_appendfacet: append f%d to facet_list\n", facet->id));
-} /* appendfacet */
-
-
-/*---------------------------------
-  
-  qh_appendvertex( vertex )
-    appends vertex to end of qh.vertex_list,
-
-  returns:
-    sets vertex->newlist
-    updates qh.vertex_list, newvertex_list
-    increments qh.num_vertices
-
-  notes:
-    assumes qh.vertex_list/vertex_tail is defined (createsimplex)
-
-*/
-void qh_appendvertex (vertexT *vertex) {
-  vertexT *tail= qh vertex_tail;
-
-  if (tail == qh newvertex_list)
-    qh newvertex_list= vertex;
-  vertex->newlist= True;
-  vertex->previous= tail->previous;
-  vertex->next= tail;
-  if (tail->previous)
-    tail->previous->next= vertex;
-  else
-    qh vertex_list= vertex;
-  tail->previous= vertex;
-  qh num_vertices++;
-  trace4((qh ferr, "qh_appendvertex: append v%d to vertex_list\n", vertex->id));
-} /* appendvertex */
-
-
-/*---------------------------------
-  
-  qh_attachnewfacets( )
-    attach horizon facets to new facets in qh.newfacet_list
-    newfacets have neighbor and ridge links to horizon but not vice versa
-    only needed for qh.ONLYgood
-
-  returns:
-    set qh.NEWfacets
-    horizon facets linked to new facets 
-      ridges changed from visible facets to new facets
-      simplicial ridges deleted
-    qh.visible_list, no ridges valid
-    facet->f.replace is a newfacet (if any)
-
-  design:
-    delete interior ridges and neighbor sets by
-      for each visible, non-simplicial facet
-        for each ridge
-          if last visit or if neighbor is simplicial
-            if horizon neighbor
-              delete ridge for horizon's ridge set
-            delete ridge
-        erase neighbor set
-    attach horizon facets and new facets by
-      for all new facets
-        if corresponding horizon facet is simplicial
-          locate corresponding visible facet {may be more than one}
-          link visible facet to new facet
-          replace visible facet with new facet in horizon
-        else it's non-simplicial
-          for all visible neighbors of the horizon facet
-            link visible neighbor to new facet
-            delete visible neighbor from horizon facet
-          append new facet to horizon's neighbors
-          the first ridge of the new facet is the horizon ridge
-          link the new facet into the horizon ridge
-*/
-void qh_attachnewfacets (void ) {
-  facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
-  ridgeT *ridge, **ridgep;
-
-  qh NEWfacets= True;
-  trace3((qh ferr, "qh_attachnewfacets: delete interior ridges\n"));
-  qh visit_id++;
-  FORALLvisible_facets {
-    visible->visitid= qh visit_id;
-    if (visible->ridges) {
-      FOREACHridge_(visible->ridges) {
-	neighbor= otherfacet_(ridge, visible);
-	if (neighbor->visitid == qh visit_id
-	    || (!neighbor->visible && neighbor->simplicial)) {
-	  if (!neighbor->visible)  /* delete ridge for simplicial horizon */
-	    qh_setdel (neighbor->ridges, ridge);
-	  qh_setfree (&(ridge->vertices)); /* delete on 2nd visit */
-	  qh_memfree (ridge, sizeof(ridgeT));
-	}
-      }
-      SETfirst_(visible->ridges)= NULL;
-    }
-    SETfirst_(visible->neighbors)= NULL;
-  }
-  trace1((qh ferr, "qh_attachnewfacets: attach horizon facets to new facets\n"));
-  FORALLnew_facets {
-    horizon= SETfirstt_(newfacet->neighbors, facetT);
-    if (horizon->simplicial) {
-      visible= NULL;
-      FOREACHneighbor_(horizon) {   /* may have more than one horizon ridge */
-	if (neighbor->visible) {
-	  if (visible) {
-	    if (qh_setequal_skip (newfacet->vertices, 0, horizon->vertices,
-				  SETindex_(horizon->neighbors, neighbor))) {
-	      visible= neighbor;
-	      break;
-	    }
-	  }else
-	    visible= neighbor;
-	}
-      }
-      if (visible) {
-	visible->f.replace= newfacet;
-	qh_setreplace (horizon->neighbors, visible, newfacet);
-      }else {
-	fprintf (qh ferr, "qhull internal error (qh_attachnewfacets): couldn't find visible facet for horizon f%d of newfacet f%d\n",
-		 horizon->id, newfacet->id);
-	qh_errexit2 (qh_ERRqhull, horizon, newfacet);
-      }
-    }else { /* non-simplicial, with a ridge for newfacet */
-      FOREACHneighbor_(horizon) {    /* may hold for many new facets */
-	if (neighbor->visible) {
-	  neighbor->f.replace= newfacet;
-	  qh_setdelnth (horizon->neighbors,
-			SETindex_(horizon->neighbors, neighbor));
-	  neighborp--; /* repeat */
-	}
-      }
-      qh_setappend (&horizon->neighbors, newfacet);
-      ridge= SETfirstt_(newfacet->ridges, ridgeT);
-      if (ridge->top == horizon)
-	ridge->bottom= newfacet;
-      else
-	ridge->top= newfacet;
-      }
-  } /* newfacets */
-  if (qh PRINTstatistics) {
-    FORALLvisible_facets {
-      if (!visible->f.replace) 
-	zinc_(Zinsidevisible);
-    }
-  }
-} /* attachnewfacets */
-
-/*---------------------------------
-  
-  qh_checkflipped( facet, dist, allerror )
-    checks facet orientation to interior point
-
-    if allerror set,
-      tests against qh.DISTround
-    else
-      tests against 0 since tested against DISTround before
-
-  returns:
-    False if it flipped orientation (sets facet->flipped)
-    distance if non-NULL
-*/
-boolT qh_checkflipped (facetT *facet, realT *distp, boolT allerror) {
-  realT dist;
-
-  if (facet->flipped && !distp)
-    return False;
-  zzinc_(Zdistcheck);
-  qh_distplane(qh interior_point, facet, &dist);
-  if (distp)
-    *distp= dist;
-  if ((allerror && dist > -qh DISTround)|| (!allerror && dist >= 0.0)) {
-    facet->flipped= True;
-    zzinc_(Zflippedfacets);
-    trace0((qh ferr, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n",
-              facet->id, dist, qh furthest_id));
-    qh_precision ("flipped facet");
-    return False;
-  }
-  return True;
-} /* checkflipped */
-
-/*---------------------------------
-  
-  qh_delfacet( facet )
-    removes facet from facet_list and frees up its memory
-
-  notes:
-    assumes vertices and ridges already freed
-*/
-void qh_delfacet(facetT *facet) {
-  void **freelistp; /* used !qh_NOmem */
-
-  trace4((qh ferr, "qh_delfacet: delete f%d\n", facet->id));
-  if (facet == qh tracefacet)
-    qh tracefacet= NULL;
-  if (facet == qh GOODclosest)
-    qh GOODclosest= NULL;
-  qh_removefacet(facet);
-  if (!facet->tricoplanar || facet->keepcentrum) {
-    qh_memfree_(facet->normal, qh normal_size, freelistp);
-    if (qh CENTERtype == qh_ASvoronoi) {   /* uses macro calls */
-      qh_memfree_(facet->center, qh center_size, freelistp);
-    }else /* AScentrum */ {
-      qh_memfree_(facet->center, qh normal_size, freelistp);
-    }
-  }
-  qh_setfree(&(facet->neighbors));
-  if (facet->ridges)
-    qh_setfree(&(facet->ridges));
-  qh_setfree(&(facet->vertices));
-  if (facet->outsideset)
-    qh_setfree(&(facet->outsideset));
-  if (facet->coplanarset)
-    qh_setfree(&(facet->coplanarset));
-  qh_memfree_(facet, sizeof(facetT), freelistp);
-} /* delfacet */
-
-
-/*---------------------------------
-  
-  qh_deletevisible()
-    delete visible facets and vertices
-
-  returns:
-    deletes each facet and removes from facetlist
-    at exit, qh.visible_list empty (== qh.newfacet_list)
-
-  notes:
-    ridges already deleted
-    horizon facets do not reference facets on qh.visible_list
-    new facets in qh.newfacet_list
-    uses   qh.visit_id;
-*/
-void qh_deletevisible (void /*qh visible_list*/) {
-  facetT *visible, *nextfacet;
-  vertexT *vertex, **vertexp;
-  int numvisible= 0, numdel= qh_setsize(qh del_vertices);
-
-  trace1((qh ferr, "qh_deletevisible: delete %d visible facets and %d vertices\n",
-         qh num_visible, numdel));
-  for (visible= qh visible_list; visible && visible->visible; 
-                visible= nextfacet) { /* deleting current */
-    nextfacet= visible->next;        
-    numvisible++;
-    qh_delfacet(visible);
-  }
-  if (numvisible != qh num_visible) {
-    fprintf (qh ferr, "qhull internal error (qh_deletevisible): qh num_visible %d is not number of visible facets %d\n",
-             qh num_visible, numvisible);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh num_visible= 0;
-  zadd_(Zvisfacettot, numvisible);
-  zmax_(Zvisfacetmax, numvisible);
-  zzadd_(Zdelvertextot, numdel);
-  zmax_(Zdelvertexmax, numdel);
-  FOREACHvertex_(qh del_vertices) 
-    qh_delvertex (vertex);
-  qh_settruncate (qh del_vertices, 0);
-} /* deletevisible */
-
-/*---------------------------------
-  
-  qh_facetintersect( facetA, facetB, skipa, skipB, prepend )
-    return vertices for intersection of two simplicial facets
-    may include 1 prepended entry (if more, need to settemppush)
-    
-  returns:
-    returns set of qh.hull_dim-1 + prepend vertices
-    returns skipped index for each test and checks for exactly one
-
-  notes:
-    does not need settemp since set in quick memory
-  
-  see also:
-    qh_vertexintersect and qh_vertexintersect_new
-    use qh_setnew_delnthsorted to get nth ridge (no skip information)
-
-  design:
-    locate skipped vertex by scanning facet A's neighbors
-    locate skipped vertex by scanning facet B's neighbors
-    intersect the vertex sets
-*/
-setT *qh_facetintersect (facetT *facetA, facetT *facetB,
-			 int *skipA,int *skipB, int prepend) {
-  setT *intersect;
-  int dim= qh hull_dim, i, j;
-  facetT **neighborsA, **neighborsB;
-
-  neighborsA= SETaddr_(facetA->neighbors, facetT);
-  neighborsB= SETaddr_(facetB->neighbors, facetT);
-  i= j= 0;
-  if (facetB == *neighborsA++)
-    *skipA= 0;
-  else if (facetB == *neighborsA++)
-    *skipA= 1;
-  else if (facetB == *neighborsA++)
-    *skipA= 2;
-  else {
-    for (i= 3; i < dim; i++) {
-      if (facetB == *neighborsA++) {
-        *skipA= i;
-        break;
-      }
-    }
-  }
-  if (facetA == *neighborsB++)
-    *skipB= 0;
-  else if (facetA == *neighborsB++)
-    *skipB= 1;
-  else if (facetA == *neighborsB++)
-    *skipB= 2;
-  else {
-    for (j= 3; j < dim; j++) {
-      if (facetA == *neighborsB++) {
-        *skipB= j;
-        break;
-      }
-    }
-  }
-  if (i >= dim || j >= dim) {
-    fprintf (qh ferr, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n",
-            facetA->id, facetB->id);
-    qh_errexit2 (qh_ERRqhull, facetA, facetB);
-  }
-  intersect= qh_setnew_delnthsorted (facetA->vertices, qh hull_dim, *skipA, prepend);
-  trace4((qh ferr, "qh_facetintersect: f%d skip %d matches f%d skip %d\n",
-	  facetA->id, *skipA, facetB->id, *skipB));
-  return(intersect);
-} /* facetintersect */
-
-/*---------------------------------
-  
-  qh_gethash( hashsize, set, size, firstindex, skipelem )
-    return hashvalue for a set with firstindex and skipelem
-
-  notes:
-    assumes at least firstindex+1 elements
-    assumes skipelem is NULL, in set, or part of hash
-    
-    hashes memory addresses which may change over different runs of the same data
-    using sum for hash does badly in high d
-*/
-unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem) {
-  void **elemp= SETelemaddr_(set, firstindex, void);
-  ptr_intT hash = 0, elem;
-  int i;
-
-  switch (size-firstindex) {
-  case 1:
-    hash= (ptr_intT)(*elemp) - (ptr_intT) skipelem;
-    break;
-  case 2:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] - (ptr_intT) skipelem;
-    break;
-  case 3:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      - (ptr_intT) skipelem;
-    break;
-  case 4:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      + (ptr_intT)elemp[3] - (ptr_intT) skipelem;
-    break;
-  case 5:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      + (ptr_intT)elemp[3] + (ptr_intT)elemp[4] - (ptr_intT) skipelem;
-    break;
-  case 6:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      + (ptr_intT)elemp[3] + (ptr_intT)elemp[4]+ (ptr_intT)elemp[5]
-      - (ptr_intT) skipelem;
-    break;
-  default:
-    hash= 0;
-    i= 3;
-    do {     /* this is about 10% in 10-d */
-      if ((elem= (ptr_intT)*elemp++) != (ptr_intT)skipelem) {
-        hash ^= (elem << i) + (elem >> (32-i));
-	i += 3;
-	if (i >= 32)
-	  i -= 32;
-      }
-    }while(*elemp);
-    break;
-  }
-  hash %= (ptr_intT) hashsize;
-  /* hash= 0; for debugging purposes */
-  return hash;
-} /* gethash */
-
-/*---------------------------------
-  
-  qh_makenewfacet( vertices, toporient, horizon )
-    creates a toporient? facet from vertices
-
-  returns:
-    returns newfacet
-      adds newfacet to qh.facet_list
-      newfacet->vertices= vertices
-      if horizon
-        newfacet->neighbor= horizon, but not vice versa
-    newvertex_list updated with vertices
-*/
-facetT *qh_makenewfacet(setT *vertices, boolT toporient,facetT *horizon) {
-  facetT *newfacet;
-  vertexT *vertex, **vertexp;
-
-  FOREACHvertex_(vertices) {
-    if (!vertex->newlist) {
-      qh_removevertex (vertex);
-      qh_appendvertex (vertex);
-    }
-  }
-  newfacet= qh_newfacet();
-  newfacet->vertices= vertices;
-  newfacet->toporient= toporient;
-  if (horizon)
-    qh_setappend(&(newfacet->neighbors), horizon);
-  qh_appendfacet(newfacet);
-  return(newfacet);
-} /* makenewfacet */
-
-
-/*---------------------------------
-  
-  qh_makenewplanes()
-    make new hyperplanes for facets on qh.newfacet_list
-
-  returns:
-    all facets have hyperplanes or are marked for   merging
-    doesn't create hyperplane if horizon is coplanar (will merge)
-    updates qh.min_vertex if qh.JOGGLEmax
-
-  notes:
-    facet->f.samecycle is defined for facet->mergehorizon facets
-*/
-void qh_makenewplanes (void /* newfacet_list */) {
-  facetT *newfacet;
-
-  FORALLnew_facets {
-    if (!newfacet->mergehorizon)
-      qh_setfacetplane (newfacet);  
-  }
-  if (qh JOGGLEmax < REALmax/2)  
-    minimize_(qh min_vertex, -wwval_(Wnewvertexmax));
-} /* makenewplanes */
-
-/*---------------------------------
-  
-  qh_makenew_nonsimplicial( visible, apex, numnew )
-    make new facets for ridges of a visible facet
-    
-  returns:
-    first newfacet, bumps numnew as needed
-    attaches new facets if !qh.ONLYgood
-    marks ridge neighbors for simplicial visible
-    if (qh.ONLYgood)
-      ridges on newfacet, horizon, and visible
-    else
-      ridge and neighbors between newfacet and   horizon
-      visible facet's ridges are deleted    
-
-  notes:
-    qh.visit_id if visible has already been processed
-    sets neighbor->seen for building f.samecycle
-      assumes all 'seen' flags initially false
-    
-  design:
-    for each ridge of visible facet
-      get neighbor of visible facet
-      if neighbor was already processed
-        delete the ridge (will delete all visible facets later)
-      if neighbor is a horizon facet
-        create a new facet
-        if neighbor coplanar
-          adds newfacet to f.samecycle for later merging
-        else 
-          updates neighbor's neighbor set
-          (checks for non-simplicial facet with multiple ridges to visible facet)
-        updates neighbor's ridge set
-        (checks for simplicial neighbor to non-simplicial visible facet)
-	(deletes ridge if neighbor is simplicial)
-          
-*/
-#ifndef qh_NOmerge
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) {
-  void **freelistp; /* used !qh_NOmem */
-  ridgeT *ridge, **ridgep;
-  facetT *neighbor, *newfacet= NULL, *samecycle;
-  setT *vertices;
-  boolT toporient;
-  int ridgeid;
-
-  FOREACHridge_(visible->ridges) {
-    ridgeid= ridge->id;
-    neighbor= otherfacet_(ridge, visible);
-    if (neighbor->visible) {
-      if (!qh ONLYgood) {
-        if (neighbor->visitid == qh visit_id) {
-          qh_setfree (&(ridge->vertices));  /* delete on 2nd visit */
-	  qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-	}
-      }
-    }else {  /* neighbor is an horizon facet */
-      toporient= (ridge->top == visible);
-      vertices= qh_setnew (qh hull_dim); /* makes sure this is quick */
-      qh_setappend (&vertices, apex);
-      qh_setappend_set (&vertices, ridge->vertices);
-      newfacet= qh_makenewfacet(vertices, toporient, neighbor);
-      (*numnew)++;
-      if (neighbor->coplanar) {
-	newfacet->mergehorizon= True;
-        if (!neighbor->seen) {
-          newfacet->f.samecycle= newfacet;
-          neighbor->f.newcycle= newfacet;
-        }else {
-          samecycle= neighbor->f.newcycle;
-          newfacet->f.samecycle= samecycle->f.samecycle;
-          samecycle->f.samecycle= newfacet;
-	}
-      }
-      if (qh ONLYgood) {
-        if (!neighbor->simplicial)
- 	  qh_setappend(&(newfacet->ridges), ridge);
-      }else {  /* qh_attachnewfacets */
-        if (neighbor->seen) {
-	  if (neighbor->simplicial) {
-	    fprintf (qh ferr, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n", 
-	           neighbor->id, visible->id);
-	    qh_errexit2 (qh_ERRqhull, neighbor, visible);
-	  }
-	  qh_setappend (&(neighbor->neighbors), newfacet);
-	}else
-          qh_setreplace (neighbor->neighbors, visible, newfacet);
-        if (neighbor->simplicial) {
-          qh_setdel (neighbor->ridges, ridge);
-          qh_setfree (&(ridge->vertices)); 
-	  qh_memfree (ridge, sizeof(ridgeT));
-	}else {
- 	  qh_setappend(&(newfacet->ridges), ridge);
- 	  if (toporient)
- 	    ridge->top= newfacet;
- 	  else
- 	    ridge->bottom= newfacet;
- 	}
-      trace4((qh ferr, "qh_makenew_nonsimplicial: created facet f%d from v%d and r%d of horizon f%d\n",
-	    newfacet->id, apex->id, ridgeid, neighbor->id));
-      }
-    }
-    neighbor->seen= True;        
-  } /* for each ridge */
-  if (!qh ONLYgood)
-    SETfirst_(visible->ridges)= NULL;
-  return newfacet;
-} /* makenew_nonsimplicial */
-#else /* qh_NOmerge */
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) {
-  return NULL;
-}
-#endif /* qh_NOmerge */
-
-/*---------------------------------
-  
-  qh_makenew_simplicial( visible, apex, numnew )
-    make new facets for simplicial visible facet and apex
-
-  returns:
-    attaches new facets if (!qh.ONLYgood)
-      neighbors between newfacet and horizon
-
-  notes:
-    nop if neighbor->seen or neighbor->visible (see qh_makenew_nonsimplicial)
-
-  design:
-    locate neighboring horizon facet for visible facet
-    determine vertices and orientation
-    create new facet
-    if coplanar,
-      add new facet to f.samecycle
-    update horizon facet's neighbor list        
-*/
-facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew) {
-  facetT *neighbor, **neighborp, *newfacet= NULL;
-  setT *vertices;
-  boolT flip, toporient;
-  int horizonskip, visibleskip;
-
-  FOREACHneighbor_(visible) {
-    if (!neighbor->seen && !neighbor->visible) {
-      vertices= qh_facetintersect(neighbor,visible, &horizonskip, &visibleskip, 1);
-      SETfirst_(vertices)= apex;
-      flip= ((horizonskip & 0x1) ^ (visibleskip & 0x1));
-      if (neighbor->toporient)         
-	toporient= horizonskip & 0x1;
-      else
-	toporient= (horizonskip & 0x1) ^ 0x1;
-      newfacet= qh_makenewfacet(vertices, toporient, neighbor);
-      (*numnew)++;
-      if (neighbor->coplanar && (qh PREmerge || qh MERGEexact)) {
-#ifndef qh_NOmerge
-	newfacet->f.samecycle= newfacet;
-	newfacet->mergehorizon= True;
-#endif
-      }
-      if (!qh ONLYgood)
-        SETelem_(neighbor->neighbors, horizonskip)= newfacet;
-      trace4((qh ferr, "qh_makenew_simplicial: create facet f%d top %d from v%d and horizon f%d skip %d top %d and visible f%d skip %d, flip? %d\n",
-	    newfacet->id, toporient, apex->id, neighbor->id, horizonskip,
-	      neighbor->toporient, visible->id, visibleskip, flip));
-    }
-  }
-  return newfacet;
-} /* makenew_simplicial */
-
-/*---------------------------------
-  
-  qh_matchneighbor( newfacet, newskip, hashsize, hashcount )
-    either match subridge of newfacet with neighbor or add to hash_table
-
-  returns:
-    duplicate ridges are unmatched and marked by qh_DUPLICATEridge
-
-  notes:
-    ridge is newfacet->vertices w/o newskip vertex
-    do not allocate memory (need to free hash_table cleanly)
-    uses linear hash chains
-  
-  see also:
-    qh_matchduplicates
-
-  design:
-    for each possible matching facet in qh.hash_table
-      if vertices match
-        set ismatch, if facets have opposite orientation
-        if ismatch and matching facet doesn't have a match
-          match the facets by updating their neighbor sets
-        else
-          indicate a duplicate ridge
-          set facet hyperplane for later testing
-          add facet to hashtable
-          unless the other facet was already a duplicate ridge
-            mark both facets with a duplicate ridge
-            add other facet (if defined) to hash table
-*/
-void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcount) {
-  boolT newfound= False;   /* True, if new facet is already in hash chain */
-  boolT same, ismatch;
-  int hash, scan;
-  facetT *facet, *matchfacet;
-  int skip, matchskip;
-
-  hash= (int)qh_gethash (hashsize, newfacet->vertices, qh hull_dim, 1, 
-                     SETelem_(newfacet->vertices, newskip));
-  trace4((qh ferr, "qh_matchneighbor: newfacet f%d skip %d hash %d hashcount %d\n",
-	  newfacet->id, newskip, hash, *hashcount));
-  zinc_(Zhashlookup);
-  for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT)); 
-       scan= (++scan >= hashsize ? 0 : scan)) {
-    if (facet == newfacet) {
-      newfound= True;
-      continue;
-    }
-    zinc_(Zhashtests);
-    if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
-      if (SETelem_(newfacet->vertices, newskip) == 
-          SETelem_(facet->vertices, skip)) {
-        qh_precision ("two facets with the same vertices");
-        fprintf (qh ferr, "qhull precision error: Vertex sets are the same for f%d and f%d.  Can not force output.\n",
-          facet->id, newfacet->id);
-        qh_errexit2 (qh_ERRprec, facet, newfacet);
-      }
-      ismatch= (same == (newfacet->toporient ^ facet->toporient));
-      matchfacet= SETelemt_(facet->neighbors, skip, facetT);
-      if (ismatch && !matchfacet) {
-        SETelem_(facet->neighbors, skip)= newfacet;
-        SETelem_(newfacet->neighbors, newskip)= facet;
-        (*hashcount)--;
-        trace4((qh ferr, "qh_matchneighbor: f%d skip %d matched with new f%d skip %d\n",
-           facet->id, skip, newfacet->id, newskip));
-        return;
-      }
-      if (!qh PREmerge && !qh MERGEexact) {
-        qh_precision ("a ridge with more than two neighbors");
-	fprintf (qh ferr, "qhull precision error: facets f%d, f%d and f%d meet at a ridge with more than 2 neighbors.  Can not continue.\n",
-		 facet->id, newfacet->id, getid_(matchfacet));
-	qh_errexit2 (qh_ERRprec, facet, newfacet);
-      }
-      SETelem_(newfacet->neighbors, newskip)= qh_DUPLICATEridge;
-      newfacet->dupridge= True;
-      if (!newfacet->normal)
-	qh_setfacetplane (newfacet);
-      qh_addhash (newfacet, qh hash_table, hashsize, hash);
-      (*hashcount)++;
-      if (!facet->normal)
-	qh_setfacetplane (facet);
-      if (matchfacet != qh_DUPLICATEridge) {
-	SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge;
-	facet->dupridge= True;
-	if (!facet->normal)
-	  qh_setfacetplane (facet);
-	if (matchfacet) {
-	  matchskip= qh_setindex (matchfacet->neighbors, facet);
-	  SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge;
-	  matchfacet->dupridge= True;
-	  if (!matchfacet->normal)
-	    qh_setfacetplane (matchfacet);
-	  qh_addhash (matchfacet, qh hash_table, hashsize, hash);
-	  *hashcount += 2;
-	}
-      }
-      trace4((qh ferr, "qh_matchneighbor: new f%d skip %d duplicates ridge for f%d skip %d matching f%d ismatch %d at hash %d\n",
-	   newfacet->id, newskip, facet->id, skip, 
-	   (matchfacet == qh_DUPLICATEridge ? -2 : getid_(matchfacet)), 
-	   ismatch, hash));
-      return; /* end of duplicate ridge */
-    }
-  }
-  if (!newfound) 
-    SETelem_(qh hash_table, scan)= newfacet;  /* same as qh_addhash */
-  (*hashcount)++;
-  trace4((qh ferr, "qh_matchneighbor: no match for f%d skip %d at hash %d\n",
-           newfacet->id, newskip, hash));
-} /* matchneighbor */
-
-
-/*---------------------------------
-  
-  qh_matchnewfacets()
-    match newfacets in qh.newfacet_list to their newfacet neighbors
-
-  returns:
-    qh.newfacet_list with full neighbor sets
-      get vertices with nth neighbor by deleting nth vertex
-    if qh.PREmerge/MERGEexact or qh.FORCEoutput 
-      sets facet->flippped if flipped normal (also prevents point partitioning)
-    if duplicate ridges and qh.PREmerge/MERGEexact
-      sets facet->dupridge
-      missing neighbor links identifies extra ridges to be merging (qh_MERGEridge)
-
-  notes:
-    newfacets already have neighbor[0] (horizon facet)
-    assumes qh.hash_table is NULL
-    vertex->neighbors has not been updated yet
-    do not allocate memory after qh.hash_table (need to free it cleanly)
-
-  design:
-    delete neighbor sets for all new facets
-    initialize a hash table
-    for all new facets
-      match facet with neighbors
-    if unmatched facets (due to duplicate ridges)
-      for each new facet with a duplicate ridge
-        match it with a facet
-    check for flipped facets
-*/
-void qh_matchnewfacets (void /* qh newfacet_list */) {
-  int numnew=0, hashcount=0, newskip;
-  facetT *newfacet, *neighbor;
-  int dim= qh hull_dim, hashsize, neighbor_i, neighbor_n;
-  setT *neighbors;
-#ifndef qh_NOtrace
-  int facet_i, facet_n, numfree= 0;
-  facetT *facet;
-#endif
-  
-  trace1((qh ferr, "qh_matchnewfacets: match neighbors for new facets.\n"));
-  FORALLnew_facets {
-    numnew++;
-    {  /* inline qh_setzero (newfacet->neighbors, 1, qh hull_dim); */
-      neighbors= newfacet->neighbors;
-      neighbors->e[neighbors->maxsize].i= dim+1; /*may be overwritten*/
-      memset ((char *)SETelemaddr_(neighbors, 1, void), 0, dim * SETelemsize);
-    }    
-  }
-  qh_newhashtable (numnew*(qh hull_dim-1)); /* twice what is normally needed,
-                                     but every ridge could be DUPLICATEridge */
-  hashsize= qh_setsize (qh hash_table);
-  FORALLnew_facets {
-    for (newskip=1; newskipneighbors, k, facetT);
-	  if (!neighbor || neighbor == qh_DUPLICATEridge)
-	    count++;
-	}
-	if (facet == newfacet)
-	  break;
-      }
-      if (count != hashcount) {
-	fprintf (qh ferr, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n",
-		 newfacet->id, hashcount, count);
-	qh_errexit (qh_ERRqhull, newfacet, NULL);
-      }
-    }
-#endif  /* end of trap code */
-  }
-  if (hashcount) {
-    FORALLnew_facets {
-      if (newfacet->dupridge) {
-        FOREACHneighbor_i_(newfacet) {
-          if (neighbor == qh_DUPLICATEridge) {
-            qh_matchduplicates (newfacet, neighbor_i, hashsize, &hashcount);
-         	    /* this may report MERGEfacet */
-	  }
-        }
-      }
-    }
-  }
-  if (hashcount) {
-    fprintf (qh ferr, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n",
-        hashcount);
-    qh_printhashtable (qh ferr);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-#ifndef qh_NOtrace
-  if (qh IStracing >= 2) {
-    FOREACHfacet_i_(qh hash_table) {
-      if (!facet)
-        numfree++;
-    }
-    fprintf (qh ferr, "qh_matchnewfacets: %d new facets, %d unused hash entries .  hashsize %d\n",
-	     numnew, numfree, qh_setsize (qh hash_table));
-  }
-#endif /* !qh_NOtrace */
-  qh_setfree (&qh hash_table);
-  if (qh PREmerge || qh MERGEexact) {
-    if (qh IStracing >= 4)
-      qh_printfacetlist (qh newfacet_list, NULL, qh_ALL);
-    FORALLnew_facets {
-      if (newfacet->normal)
-	qh_checkflipped (newfacet, NULL, qh_ALL);
-    }
-  }else if (qh FORCEoutput)
-    qh_checkflipped_all (qh newfacet_list);  /* prints warnings for flipped */
-} /* matchnewfacets */
-
-    
-/*---------------------------------
-  
-  qh_matchvertices( firstindex, verticesA, skipA, verticesB, skipB, same )
-    tests whether vertices match with a single skip
-    starts match at firstindex since all new facets have a common vertex
-
-  returns:
-    true if matched vertices
-    skip index for each set
-    sets same iff vertices have the same orientation
-
-  notes:
-    assumes skipA is in A and both sets are the same size
-
-  design:
-    set up pointers
-    scan both sets checking for a match
-    test orientation
-*/
-boolT qh_matchvertices (int firstindex, setT *verticesA, int skipA, 
-       setT *verticesB, int *skipB, boolT *same) {
-  vertexT **elemAp, **elemBp, **skipBp=NULL, **skipAp;
-
-  elemAp= SETelemaddr_(verticesA, firstindex, vertexT);
-  elemBp= SETelemaddr_(verticesB, firstindex, vertexT);
-  skipAp= SETelemaddr_(verticesA, skipA, vertexT);
-  do if (elemAp != skipAp) {
-    while (*elemAp != *elemBp++) {
-      if (skipBp)
-        return False;
-      skipBp= elemBp;  /* one extra like FOREACH */
-    }
-  }while(*(++elemAp));
-  if (!skipBp)
-    skipBp= ++elemBp;
-  *skipB= SETindex_(verticesB, skipB);
-  *same= !(((ptr_intT)skipA & 0x1) ^ ((ptr_intT)*skipB & 0x1));
-  trace4((qh ferr, "qh_matchvertices: matched by skip %d (v%d) and skip %d (v%d) same? %d\n",
-	  skipA, (*skipAp)->id, *skipB, (*(skipBp-1))->id, *same));
-  return (True);
-} /* matchvertices */
-
-/*---------------------------------
-  
-  qh_newfacet()
-    return a new facet 
-
-  returns:
-    all fields initialized or cleared   (NULL)
-    preallocates neighbors set
-*/
-facetT *qh_newfacet(void) {
-  facetT *facet;
-  void **freelistp; /* used !qh_NOmem */
-  
-  qh_memalloc_(sizeof(facetT), freelistp, facet, facetT);
-  memset ((char *)facet, 0, sizeof(facetT));
-  if (qh facet_id == qh tracefacet_id)
-    qh tracefacet= facet;
-  facet->id= qh facet_id++;
-  facet->neighbors= qh_setnew(qh hull_dim);
-#if !qh_COMPUTEfurthest
-  facet->furthestdist= 0.0;
-#endif
-#if qh_MAXoutside
-  if (qh FORCEoutput && qh APPROXhull)
-    facet->maxoutside= qh MINoutside;
-  else
-    facet->maxoutside= qh DISTround;
-#endif
-  facet->simplicial= True;
-  facet->good= True;
-  facet->newfacet= True;
-  trace4((qh ferr, "qh_newfacet: created facet f%d\n", facet->id));
-  return (facet);
-} /* newfacet */
-
-
-/*---------------------------------
-  
-  qh_newridge()
-    return a new ridge
-*/
-ridgeT *qh_newridge(void) {
-  ridgeT *ridge;
-  void **freelistp;   /* used !qh_NOmem */
-
-  qh_memalloc_(sizeof(ridgeT), freelistp, ridge, ridgeT);
-  memset ((char *)ridge, 0, sizeof(ridgeT));
-  zinc_(Ztotridges);
-  if (qh ridge_id == 0xFFFFFF) {
-    fprintf(qh ferr, "\
-qhull warning: more than %d ridges.  ID field overflows and two ridges\n\
-may have the same identifier.  Otherwise output ok.\n", 0xFFFFFF);
-  }
-  ridge->id= qh ridge_id++;     
-  trace4((qh ferr, "qh_newridge: created ridge r%d\n", ridge->id));
-  return (ridge);
-} /* newridge */
-
-
-/*---------------------------------
-  
-  qh_pointid(  )
-    return id for a point, 
-    returns -3 if null, -2 if interior, or -1 if not known
-
-  alternative code:
-    unsigned long id;
-    id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size;
-
-  notes:
-    if point not in point array
-      the code does a comparison of unrelated pointers.
-*/
-int qh_pointid (pointT *point) {
-  long offset, id;
-
-  if (!point)
-    id= -3;
-  else if (point == qh interior_point)
-    id= -2;
-  else if (point >= qh first_point
-  && point < qh first_point + qh num_points * qh hull_dim) {
-    offset= point - qh first_point;
-    id= offset / qh hull_dim;
-  }else if ((id= qh_setindex (qh other_points, point)) != -1)
-    id += qh num_points;
-  else
-    id= -1;
-  return (int) id;
-} /* pointid */
-  
-/*---------------------------------
-  
-  qh_removefacet( facet )
-    unlinks facet from qh.facet_list,
-
-  returns:
-    updates qh.facet_list .newfacet_list .facet_next visible_list
-    decrements qh.num_facets
-
-  see:
-    qh_appendfacet
-*/
-void qh_removefacet(facetT *facet) {
-  facetT *next= facet->next, *previous= facet->previous;
-  
-  if (facet == qh newfacet_list)
-    qh newfacet_list= next;
-  if (facet == qh facet_next)
-    qh facet_next= next;
-  if (facet == qh visible_list)
-    qh visible_list= next; 
-  if (previous) {
-    previous->next= next;
-    next->previous= previous;
-  }else {  /* 1st facet in qh facet_list */
-    qh facet_list= next;
-    qh facet_list->previous= NULL;
-  }
-  qh num_facets--;
-  trace4((qh ferr, "qh_removefacet: remove f%d from facet_list\n", facet->id));
-} /* removefacet */
-
-
-/*---------------------------------
-  
-  qh_removevertex( vertex )
-    unlinks vertex from qh.vertex_list,
-
-  returns:
-    updates qh.vertex_list .newvertex_list 
-    decrements qh.num_vertices
-*/
-void qh_removevertex(vertexT *vertex) {
-  vertexT *next= vertex->next, *previous= vertex->previous;
-  
-  if (vertex == qh newvertex_list)
-    qh newvertex_list= next;
-  if (previous) {
-    previous->next= next;
-    next->previous= previous;
-  }else {  /* 1st vertex in qh vertex_list */
-    qh vertex_list= vertex->next;
-    qh vertex_list->previous= NULL;
-  }
-  qh num_vertices--;
-  trace4((qh ferr, "qh_removevertex: remove v%d from vertex_list\n", vertex->id));
-} /* removevertex */
-
-
-/*---------------------------------
-  
-  qh_updatevertices()
-    update vertex neighbors and delete interior vertices
-
-  returns:
-    if qh.VERTEXneighbors, updates neighbors for each vertex
-      if qh.newvertex_list, 
-         removes visible neighbors  from vertex neighbors
-      if qh.newfacet_list
-         adds new facets to vertex neighbors
-    if qh.visible_list
-       interior vertices added to qh.del_vertices for later partitioning
-
-  design:
-    if qh.VERTEXneighbors
-      deletes references to visible facets from vertex neighbors
-      appends new facets to the neighbor list for each vertex
-      checks all vertices of visible facets
-        removes visible facets from neighbor lists
-        marks unused vertices for deletion
-*/
-void qh_updatevertices (void /*qh newvertex_list, newfacet_list, visible_list*/) {
-  facetT *newfacet= NULL, *neighbor, **neighborp, *visible;
-  vertexT *vertex, **vertexp;
-
-  trace3((qh ferr, "qh_updatevertices: delete interior vertices and update vertex->neighbors\n"));
-  if (qh VERTEXneighbors) {
-    FORALLvertex_(qh newvertex_list) {
-      FOREACHneighbor_(vertex) {
-	if (neighbor->visible) 
-	  SETref_(neighbor)= NULL;
-      }
-      qh_setcompact (vertex->neighbors);
-    }
-    FORALLnew_facets {
-      FOREACHvertex_(newfacet->vertices)
-        qh_setappend (&vertex->neighbors, newfacet);
-    }
-    FORALLvisible_facets {
-      FOREACHvertex_(visible->vertices) {
-        if (!vertex->newlist && !vertex->deleted) {
-  	  FOREACHneighbor_(vertex) { /* this can happen under merging */
-	    if (!neighbor->visible)
-	      break;
-	  }
-	  if (neighbor)
-	    qh_setdel (vertex->neighbors, visible);
-	  else {
-	    vertex->deleted= True;
-	    qh_setappend (&qh del_vertices, vertex);
-	    trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n",
-		  qh_pointid(vertex->point), vertex->id, visible->id));
-  	  }
-        }
-      }
-    }
-  }else {  /* !VERTEXneighbors */
-    FORALLvisible_facets {
-      FOREACHvertex_(visible->vertices) {
-        if (!vertex->newlist && !vertex->deleted) {
-          vertex->deleted= True;
-	  qh_setappend (&qh del_vertices, vertex);
-	  trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n",
-		  qh_pointid(vertex->point), vertex->id, visible->id));
-  	}
-      }
-    }
-  }
-} /* updatevertices */
-
-
-
diff --git a/extern/qhull/src/poly.h b/extern/qhull/src/poly.h
deleted file mode 100644
index 294ec9527fc..00000000000
--- a/extern/qhull/src/poly.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
  ---------------------------------
-
-   poly.h 
-   header file for poly.c and poly2.c
-
-   see qh-poly.htm, qhull.h and poly.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFpoly
-#define qhDEFpoly 1
-
-/*===============   constants ========================== */
-
-/*----------------------------------
-  
-  ALGORITHMfault   
-    use as argument to checkconvex() to report errors during buildhull
-*/
-#define qh_ALGORITHMfault 0
-
-/*----------------------------------
-  
-  DATAfault        
-    use as argument to checkconvex() to report errors during initialhull
-*/
-#define qh_DATAfault 1
-
-/*----------------------------------
-  
-  DUPLICATEridge
-    special value for facet->neighbor to indicate a duplicate ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_DUPLICATEridge ( facetT * ) 1L
-
-/*----------------------------------
-  
-  MERGEridge       flag in facet
-    special value for facet->neighbor to indicate a merged ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_MERGEridge ( facetT * ) 2L
-
-
-/*============ -structures- ====================*/
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-  
-  FORALLfacet_( facetlist ) { ... }
-    assign 'facet' to each facet in facetlist
-    
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-    
-  see:
-    FORALLfacets
-*/
-#define FORALLfacet_( facetlist ) if ( facetlist ) for( facet=( facetlist );facet && facet->next;facet=facet->next )
-
-/*----------------------------------
-  
-  FORALLnew_facets { ... } 
-    assign 'newfacet' to each facet in qh.newfacet_list
-    
-  notes:
-    uses 'facetT *newfacet;'
-    at exit, newfacet==NULL
-*/
-#define FORALLnew_facets for( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
-
-/*----------------------------------
-  
-  FORALLvertex_( vertexlist ) { ... }
-    assign 'vertex' to each vertex in vertexlist
-    
-  notes:
-    uses 'vertexT *vertex;'
-    at exit, vertex==NULL
-*/
-#define FORALLvertex_( vertexlist ) for ( vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
-
-/*----------------------------------
-  
-  FORALLvisible_facets { ... }
-    assign 'visible' to each visible facet in qh.visible_list
-    
-  notes:
-    uses 'vacetT *visible;'
-    at exit, visible==NULL
-*/
-#define FORALLvisible_facets for (visible=qh visible_list; visible && visible->visible; visible= visible->next)
-
-/*----------------------------------
-  
-  FORALLsame_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    stops when it returns to newfacet
-*/
-#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
-
-/*----------------------------------
-  
-  FORALLsame_cycle_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    at exit, same == NULL
-*/
-#define FORALLsame_cycle_(newfacet) \
-     for (same= newfacet->f.samecycle; \
-         same; same= (same == newfacet ?  NULL : same->f.samecycle))
-
-/*----------------------------------
-  
-  FOREACHneighborA_( facet ) { ... }
-    assign 'neighborA' to each neighbor in facet->neighbors
-  
-  FOREACHneighborA_( vertex ) { ... }
-    assign 'neighborA' to each neighbor in vertex->neighbors
-  
-  declare:
-    facetT *neighborA, **neighborAp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighborA_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighborA)
-
-/*----------------------------------
-  
-  FOREACHvisible_( facets ) { ... } 
-    assign 'visible' to each facet in facets
-    
-  notes:
-    uses 'facetT *facet, *facetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
-
-/*----------------------------------
-  
-  FOREACHnewfacet_( facets ) { ... } 
-    assign 'newfacet' to each facet in facets
-    
-  notes:
-    uses 'facetT *newfacet, *newfacetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
-
-/*----------------------------------
-  
-  FOREACHvertexA_( vertices ) { ... } 
-    assign 'vertexA' to each vertex in vertices
-    
-  notes:
-    uses 'vertexT *vertexA, *vertexAp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
-
-/*----------------------------------
-  
-  FOREACHvertexreverse12_( vertices ) { ... } 
-    assign 'vertex' to each vertex in vertices
-    reverse order of first two vertices
-    
-  notes:
-    uses 'vertexT *vertex, *vertexp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
-
-
-/*=============== prototypes poly.c in alphabetical order ================*/
-
-void    qh_appendfacet(facetT *facet);
-void    qh_appendvertex(vertexT *vertex);
-void 	qh_attachnewfacets (void);
-boolT   qh_checkflipped (facetT *facet, realT *dist, boolT allerror);
-void	qh_delfacet(facetT *facet);
-void 	qh_deletevisible(void /*qh visible_list, qh horizon_list*/);
-setT   *qh_facetintersect (facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
-unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem);
-facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet);
-void    qh_makenewplanes ( void /* newfacet_list */);
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew);
-facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew);
-void    qh_matchneighbor (facetT *newfacet, int newskip, int hashsize,
-			  int *hashcount);
-void	qh_matchnewfacets (void);
-boolT   qh_matchvertices (int firstindex, setT *verticesA, int skipA, 
-			  setT *verticesB, int *skipB, boolT *same);
-facetT *qh_newfacet(void);
-ridgeT *qh_newridge(void);
-int     qh_pointid (pointT *point);
-void 	qh_removefacet(facetT *facet);
-void 	qh_removevertex(vertexT *vertex);
-void    qh_updatevertices (void);
-
-
-/*========== -prototypes poly2.c in alphabetical order ===========*/
-
-void    qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash);
-void 	qh_check_bestdist (void);
-void    qh_check_maxout (void);
-void    qh_check_output (void);
-void    qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
-void   	qh_check_points(void);
-void 	qh_checkconvex(facetT *facetlist, int fault);
-void    qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp);
-void 	qh_checkflipped_all (facetT *facetlist);
-void 	qh_checkpolygon(facetT *facetlist);
-void    qh_checkvertex (vertexT *vertex);
-void 	qh_clearcenters (qh_CENTER type);
-void 	qh_createsimplex(setT *vertices);
-void 	qh_delridge(ridgeT *ridge);
-void    qh_delvertex (vertexT *vertex);
-setT   *qh_facet3vertex (facetT *facet);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside,
-			  int *numpart);
-int 	qh_findgood (facetT *facetlist, int goodhorizon);
-void 	qh_findgood_all (facetT *facetlist);
-void    qh_furthestnext (void /* qh facet_list */);
-void    qh_furthestout (facetT *facet);
-void    qh_infiniteloop (facetT *facet);
-void 	qh_initbuild(void);
-void 	qh_initialhull(setT *vertices);
-setT   *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints);
-vertexT *qh_isvertex (pointT *point, setT *vertices);
-vertexT *qh_makenewfacets (pointT *point /*horizon_list, visible_list*/);
-void    qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount);
-void    qh_nearcoplanar ( void /* qh.facet_list */);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-int 	qh_newhashtable(int newsize);
-vertexT *qh_newvertex(pointT *point);
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp);
-void    qh_outcoplanar (void /* facet_list */);
-pointT *qh_point (int id);
-void 	qh_point_add (setT *set, pointT *point, void *elem);
-setT   *qh_pointfacet (void /*qh facet_list*/);
-setT   *qh_pointvertex (void /*qh facet_list*/);
-void 	qh_prependfacet(facetT *facet, facetT **facetlist);
-void	qh_printhashtable(FILE *fp);
-void    qh_printlists (void);
-void    qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-void    qh_triangulate_facet (facetT *facetA, vertexT **first_vertex);
-void    qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
-void	qh_triangulate_mirror (facetT *facetA, facetT *facetB);
-void    qh_triangulate_null (facetT *facetA);
-void    qh_vertexintersect(setT **vertexsetA,setT *vertexsetB);
-setT   *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB);
-void    qh_vertexneighbors (void /*qh facet_list*/);
-boolT 	qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
-
-
-#endif /* qhDEFpoly */
diff --git a/extern/qhull/src/poly2.c b/extern/qhull/src/poly2.c
deleted file mode 100644
index 713faab8bed..00000000000
--- a/extern/qhull/src/poly2.c
+++ /dev/null
@@ -1,3070 +0,0 @@
-/*
  ---------------------------------
-
-   poly2.c 
-   implements polygons and simplices
-
-   see qh-poly.htm, poly.h and qhull.h
-
-   frequently used code is in poly.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include "qhull_a.h"
-
-/*======== functions in alphabetical order ==========*/
-
-/*---------------------------------
-  
-  qh_addhash( newelem, hashtable, hashsize, hash )
-    add newelem to linear hash table at hash if not already there
-*/
-void qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash) {
-  int scan;
-  void *elem;
-
-  for (scan= (int)hash; (elem= SETelem_(hashtable, scan)); 
-       scan= (++scan >= hashsize ? 0 : scan)) {
-    if (elem == newelem)
-      break;
-  }
-  /* loop terminates because qh_HASHfactor >= 1.1 by qh_initbuffers */
-  if (!elem)
-    SETelem_(hashtable, scan)= newelem;
-} /* addhash */
-
-/*---------------------------------
-  
-  qh_check_bestdist()
-    check that all points are within max_outside of the nearest facet
-    if qh.ONLYgood,
-      ignores !good facets
-
-  see: 
-    qh_check_maxout(), qh_outerinner()
-
-  notes:
-    only called from qh_check_points()
-      seldom used since qh.MERGING is almost always set
-    if notverified>0 at end of routine
-      some points were well inside the hull.  If the hull contains
-      a lens-shaped component, these points were not verified.  Use
-      options 'Qi Tv' to verify all points.  (Exhaustive check also verifies)
-
-  design:
-    determine facet for each point (if any)
-    for each point
-      start with the assigned facet or with the first facet
-      find the best facet for the point and check all coplanar facets
-      error if point is outside of facet
-*/
-void qh_check_bestdist (void) {
-  boolT waserror= False, unassigned;
-  facetT *facet, *bestfacet, *errfacet1= NULL, *errfacet2= NULL;
-  facetT *facetlist; 
-  realT dist, maxoutside, maxdist= -REALmax;
-  pointT *point;
-  int numpart= 0, facet_i, facet_n, notgood= 0, notverified= 0;
-  setT *facets;
-
-  trace1((qh ferr, "qh_check_bestdist: check points below nearest facet.  Facet_list f%d\n",
-      qh facet_list->id));
-  maxoutside= qh_maxouter();
-  maxoutside += qh DISTround;
-  /* one more qh.DISTround for check computation */
-  trace1((qh ferr, "qh_check_bestdist: check that all points are within %2.2g of best facet\n", maxoutside));
-  facets= qh_pointfacet (/*qh facet_list*/);
-  if (!qh_QUICKhelp && qh PRINTprecision)
-    fprintf (qh ferr, "\n\
-qhull output completed.  Verifying that %d points are\n\
-below %2.2g of the nearest %sfacet.\n",
-	     qh_setsize(facets), maxoutside, (qh ONLYgood ?  "good " : ""));
-  FOREACHfacet_i_(facets) {  /* for each point with facet assignment */
-    if (facet)
-      unassigned= False;
-    else {
-      unassigned= True;
-      facet= qh facet_list;
-    }
-    point= qh_point(facet_i);
-    if (point == qh GOODpointp)
-      continue;
-    qh_distplane(point, facet, &dist);
-    numpart++;
-    bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, facet, qh_NOupper, &dist, &numpart);
-    /* occurs after statistics reported */
-    maximize_(maxdist, dist);
-    if (dist > maxoutside) {
-      if (qh ONLYgood && !bestfacet->good 
-	  && !((bestfacet= qh_findgooddist (point, bestfacet, &dist, &facetlist))
-	       && dist > maxoutside))
-	notgood++;
-      else {
-	waserror= True;
-	fprintf(qh ferr, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n", 
-		facet_i, bestfacet->id, dist, maxoutside);
-	if (errfacet1 != bestfacet) {
-	  errfacet2= errfacet1;
-	  errfacet1= bestfacet;
-	}
-      }
-    }else if (unassigned && dist < -qh MAXcoplanar)
-      notverified++;
-  }
-  qh_settempfree (&facets);
-  if (notverified && !qh DELAUNAY && !qh_QUICKhelp && qh PRINTprecision) 
-    fprintf(qh ferr, "\n%d points were well inside the hull.  If the hull contains\n\
-a lens-shaped component, these points were not verified.  Use\n\
-options 'Qci Tv' to verify all points.\n", notverified); 
-  if (maxdist > qh outside_err) {
-    fprintf( qh ferr, "qhull precision error (qh_check_bestdist): a coplanar point is %6.2g from convex hull.  The maximum value (qh.outside_err) is %6.2g\n",
-              maxdist, qh outside_err);
-    qh_errexit2 (qh_ERRprec, errfacet1, errfacet2);
-  }else if (waserror && qh outside_err > REALmax/2)
-    qh_errexit2 (qh_ERRprec, errfacet1, errfacet2);
-  else if (waserror)
-    ;                       /* the error was logged to qh.ferr but does not effect the output */
-  trace0((qh ferr, "qh_check_bestdist: max distance outside %2.2g\n", maxdist));
-} /* check_bestdist */
-
-/*---------------------------------
-  
-  qh_check_maxout()
-    updates qh.max_outside by checking all points against bestfacet
-    if qh.ONLYgood, ignores !good facets
-
-  returns:
-    updates facet->maxoutside via qh_findbesthorizon()
-    sets qh.maxoutdone
-    if printing qh.min_vertex (qh_outerinner), 
-      it is updated to the current vertices
-    removes inside/coplanar points from coplanarset as needed
-
-  notes:
-    defines coplanar as min_vertex instead of MAXcoplanar 
-    may not need to check near-inside points because of qh.MAXcoplanar 
-      and qh.KEEPnearinside (before it was -DISTround)
-
-  see also:
-    qh_check_bestdist()
-
-  design:
-    if qh.min_vertex is needed
-      for all neighbors of all vertices
-        test distance from vertex to neighbor
-    determine facet for each point (if any)
-    for each point with an assigned facet
-      find the best facet for the point and check all coplanar facets
-        (updates outer planes)
-    remove near-inside points from coplanar sets
-*/
-#ifndef qh_NOmerge
-void qh_check_maxout (void) {
-  facetT *facet, *bestfacet, *neighbor, **neighborp, *facetlist;
-  realT dist, maxoutside, minvertex, old_maxoutside;
-  pointT *point;
-  int numpart= 0, facet_i, facet_n, notgood= 0;
-  setT *facets, *vertices;
-  vertexT *vertex;
-
-  trace1((qh ferr, "qh_check_maxout: check and update maxoutside for each facet.\n"));
-  maxoutside= minvertex= 0;
-  if (qh VERTEXneighbors 
-  && (qh PRINTsummary || qh KEEPinside || qh KEEPcoplanar 
-	|| qh TRACElevel || qh PRINTstatistics
-	|| qh PRINTout[0] == qh_PRINTsummary || qh PRINTout[0] == qh_PRINTnone)) { 
-    trace1((qh ferr, "qh_check_maxout: determine actual maxoutside and minvertex\n"));
-    vertices= qh_pointvertex (/*qh facet_list*/);
-    FORALLvertices {
-      FOREACHneighbor_(vertex) {
-        zinc_(Zdistvertex);  /* distance also computed by main loop below */
-	qh_distplane (vertex->point, neighbor, &dist);
-	minimize_(minvertex, dist);
-	if (-dist > qh TRACEdist || dist > qh TRACEdist 
-	|| neighbor == qh tracefacet || vertex == qh tracevertex)
-	  fprintf (qh ferr, "qh_check_maxout: p%d (v%d) is %.2g from f%d\n",
-		    qh_pointid (vertex->point), vertex->id, dist, neighbor->id);
-      }
-    }
-    if (qh MERGING) {
-      wmin_(Wminvertex, qh min_vertex);
-    }
-    qh min_vertex= minvertex;
-    qh_settempfree (&vertices);  
-  }
-  facets= qh_pointfacet (/*qh facet_list*/);
-  do {
-    old_maxoutside= fmax_(qh max_outside, maxoutside);
-    FOREACHfacet_i_(facets) {     /* for each point with facet assignment */
-      if (facet) { 
-	point= qh_point(facet_i);
-	if (point == qh GOODpointp)
-	  continue;
-	zinc_(Ztotcheck);
-	qh_distplane(point, facet, &dist);
-	numpart++;
-	bestfacet= qh_findbesthorizon (qh_IScheckmax, point, facet, !qh_NOupper, &dist, &numpart);
-	if (bestfacet && dist > maxoutside) {
-	  if (qh ONLYgood && !bestfacet->good 
-	  && !((bestfacet= qh_findgooddist (point, bestfacet, &dist, &facetlist))
-	       && dist > maxoutside))
-	    notgood++;
-	  else
-	    maxoutside= dist;
-	}
-	if (dist > qh TRACEdist || (bestfacet && bestfacet == qh tracefacet))
-	  fprintf (qh ferr, "qh_check_maxout: p%d is %.2g above f%d\n",
-		     qh_pointid (point), dist, bestfacet->id);
-      }
-    }
-  }while 
-    (maxoutside > 2*old_maxoutside);
-    /* if qh.maxoutside increases substantially, qh_SEARCHdist is not valid 
-          e.g., RBOX 5000 s Z1 G1e-13 t1001200614 | qhull */
-  zzadd_(Zcheckpart, numpart);
-  qh_settempfree (&facets);
-  wval_(Wmaxout)= maxoutside - qh max_outside;
-  wmax_(Wmaxoutside, qh max_outside);
-  qh max_outside= maxoutside;
-  qh_nearcoplanar (/*qh.facet_list*/);
-  qh maxoutdone= True;
-  trace1((qh ferr, "qh_check_maxout: maxoutside %2.2g, min_vertex %2.2g, outside of not good %d\n",
-       maxoutside, qh min_vertex, notgood));
-} /* check_maxout */
-#else /* qh_NOmerge */
-void qh_check_maxout (void) {
-}
-#endif
-
-/*---------------------------------
-  
-  qh_check_output()
-    performs the checks at the end of qhull algorithm
-    Maybe called after voronoi output.  Will recompute otherwise centrums are Voronoi centers instead
-*/
-void qh_check_output (void) {
-  int i;
-
-  if (qh STOPcone)
-    return;
-  if (qh VERIFYoutput | qh IStracing | qh CHECKfrequently) {
-    qh_checkpolygon (qh facet_list);
-    qh_checkflipped_all (qh facet_list);
-    qh_checkconvex (qh facet_list, qh_ALGORITHMfault);
-  }else if (!qh MERGING && qh_newstats (qhstat precision, &i)) {
-    qh_checkflipped_all (qh facet_list);
-    qh_checkconvex (qh facet_list, qh_ALGORITHMfault);
-  }
-} /* check_output */
-
-
-
-/*---------------------------------
-  
-  qh_check_point( point, facet, maxoutside, maxdist, errfacet1, errfacet2 )
-    check that point is less than maxoutside from facet
-*/
-void qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2) {
-  realT dist;
-
-  /* occurs after statistics reported */
-  qh_distplane(point, facet, &dist);
-  if (dist > *maxoutside) {
-    if (*errfacet1 != facet) {
-      *errfacet2= *errfacet1;
-      *errfacet1= facet;
-    }
-    fprintf(qh ferr, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n", 
-	      qh_pointid(point), facet->id, dist, *maxoutside);
-  }
-  maximize_(*maxdist, dist);
-} /* qh_check_point */
-
-
-/*---------------------------------
-  
-  qh_check_points()
-    checks that all points are inside all facets
-
-  notes:
-    if many points and qh_check_maxout not called (i.e., !qh.MERGING), 
-       calls qh_findbesthorizon (seldom done).
-    ignores flipped facets
-    maxoutside includes 2 qh.DISTrounds
-      one qh.DISTround for the computed distances in qh_check_points
-    qh_printafacet and qh_printsummary needs only one qh.DISTround
-    the computation for qh.VERIFYdirect does not account for qh.other_points
-
-  design:
-    if many points
-      use qh_check_bestdist()
-    else
-      for all facets
-        for all points
-          check that point is inside facet
-*/
-void qh_check_points (void) {
-  facetT *facet, *errfacet1= NULL, *errfacet2= NULL;
-  realT total, maxoutside, maxdist= -REALmax;
-  pointT *point, **pointp, *pointtemp;
-  boolT testouter;
-
-  maxoutside= qh_maxouter();
-  maxoutside += qh DISTround;
-  /* one more qh.DISTround for check computation */
-  trace1((qh ferr, "qh_check_points: check all points below %2.2g of all facet planes\n",
-	  maxoutside));
-  if (qh num_good)   /* miss counts other_points and !good facets */
-     total= (float) qh num_good * qh num_points;
-  else
-     total= (float) qh num_facets * qh num_points;
-  if (total >= qh_VERIFYdirect && !qh maxoutdone) {
-    if (!qh_QUICKhelp && qh SKIPcheckmax && qh MERGING)
-      fprintf (qh ferr, "\n\
-qhull input warning: merging without checking outer planes ('Q5' or 'Po').\n\
-Verify may report that a point is outside of a facet.\n");
-    qh_check_bestdist();
-  }else {
-    if (qh_MAXoutside && qh maxoutdone)
-      testouter= True;
-    else
-      testouter= False;
-    if (!qh_QUICKhelp) {
-      if (qh MERGEexact)
-	fprintf (qh ferr, "\n\
-qhull input warning: exact merge ('Qx').  Verify may report that a point\n\
-is outside of a facet.  See qh-optq.htm#Qx\n");
-      else if (qh SKIPcheckmax || qh NOnearinside)
-	fprintf (qh ferr, "\n\
-qhull input warning: no outer plane check ('Q5') or no processing of\n\
-near-inside points ('Q8').  Verify may report that a point is outside\n\
-of a facet.\n");
-    }
-    if (qh PRINTprecision) {
-      if (testouter)
-	fprintf (qh ferr, "\n\
-Output completed.  Verifying that all points are below outer planes of\n\
-all %sfacets.  Will make %2.0f distance computations.\n", 
-	      (qh ONLYgood ?  "good " : ""), total);
-      else
-	fprintf (qh ferr, "\n\
-Output completed.  Verifying that all points are below %2.2g of\n\
-all %sfacets.  Will make %2.0f distance computations.\n", 
-	      maxoutside, (qh ONLYgood ?  "good " : ""), total);
-    }
-    FORALLfacets {
-      if (!facet->good && qh ONLYgood)
-        continue;
-      if (facet->flipped)
-        continue;
-      if (!facet->normal) {
-	fprintf( qh ferr, "qhull warning (qh_check_points): missing normal for facet f%d\n", facet->id);
-        continue;
-      }
-      if (testouter) {
-#if qh_MAXoutside
-	maxoutside= facet->maxoutside + 2* qh DISTround;
-	/* one DISTround to actual point and another to computed point */
-#endif
-      }
-      FORALLpoints {
-	if (point != qh GOODpointp)
-	  qh_check_point (point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
-      }
-      FOREACHpoint_(qh other_points) {
-	if (point != qh GOODpointp)
-	  qh_check_point (point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
-      }
-    }
-    if (maxdist > qh outside_err) {
-      fprintf( qh ferr, "qhull precision error (qh_check_points): a coplanar point is %6.2g from convex hull.  The maximum value (qh.outside_err) is %6.2g\n",
-                maxdist, qh outside_err );
-      qh_errexit2( qh_ERRprec, errfacet1, errfacet2 );
-    }else if (errfacet1 && qh outside_err > REALmax/2)
-        qh_errexit2( qh_ERRprec, errfacet1, errfacet2 );
-    else if (errfacet1)
-        ;  /* the error was logged to qh.ferr but does not effect the output */
-    trace0((qh ferr, "qh_check_points: max distance outside %2.2g\n", maxdist));
-  }
-} /* check_points */
-
-
-/*---------------------------------
-  
-  qh_checkconvex( facetlist, fault )
-    check that each ridge in facetlist is convex
-    fault = qh_DATAfault if reporting errors
-          = qh_ALGORITHMfault otherwise
-
-  returns:
-    counts Zconcaveridges and Zcoplanarridges
-    errors if concaveridge or if merging an coplanar ridge
-
-  note:
-    if not merging, 
-      tests vertices for neighboring simplicial facets
-    else if ZEROcentrum, 
-      tests vertices for neighboring simplicial   facets
-    else 
-      tests centrums of neighboring facets
-
-  design:
-    for all facets
-      report flipped facets
-      if ZEROcentrum and simplicial neighbors
-        test vertices for neighboring simplicial facets
-      else
-        test centrum against all neighbors 
-*/
-void qh_checkconvex(facetT *facetlist, int fault) {
-  facetT *facet, *neighbor, **neighborp, *errfacet1=NULL, *errfacet2=NULL;
-  vertexT *vertex;
-  realT dist;
-  pointT *centrum;
-  boolT waserror= False, centrum_warning= False, tempcentrum= False, allsimplicial;
-  int neighbor_i;
-
-  trace1((qh ferr, "qh_checkconvex: check all ridges are convex\n"));
-  if (!qh RERUN) {
-    zzval_(Zconcaveridges)= 0;
-    zzval_(Zcoplanarridges)= 0;
-  }
-  FORALLfacet_(facetlist) {
-    if (facet->flipped) {
-      qh_precision ("flipped facet");
-      fprintf (qh ferr, "qhull precision error: f%d is flipped (interior point is outside)\n",
-	       facet->id);
-      errfacet1= facet;
-      waserror= True;
-      continue;
-    }
-    if (qh MERGING && (!qh ZEROcentrum || !facet->simplicial || facet->tricoplanar))
-      allsimplicial= False;
-    else {
-      allsimplicial= True;
-      neighbor_i= 0;
-      FOREACHneighbor_(facet) {
-        vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
-	if (!neighbor->simplicial || neighbor->tricoplanar) {
-	  allsimplicial= False;
-	  continue;
-	}
-        qh_distplane (vertex->point, neighbor, &dist);
-        if (dist > -qh DISTround) {
-	  if (fault == qh_DATAfault) {
-            qh_precision ("coplanar or concave ridge");
-	    fprintf (qh ferr, "qhull precision error: initial simplex is not convex. Distance=%.2g\n", dist);
-	    qh_errexit(qh_ERRsingular, NULL, NULL);
-	  }
-          if (dist > qh DISTround) {
-            zzinc_(Zconcaveridges);
-            qh_precision ("concave ridge");
-            fprintf (qh ferr, "qhull precision error: f%d is concave to f%d, since p%d (v%d) is %6.4g above\n",
-              facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist);
-            errfacet1= facet;
-            errfacet2= neighbor;
-            waserror= True;
-          }else if (qh ZEROcentrum) {
-            if (dist > 0) {     /* qh_checkzero checks that dist < - qh DISTround */
-              zzinc_(Zcoplanarridges); 
-              qh_precision ("coplanar ridge");
-              fprintf (qh ferr, "qhull precision error: f%d is clearly not convex to f%d, since p%d (v%d) is %6.4g above\n",
-                facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist);
-              errfacet1= facet;
-              errfacet2= neighbor;
-              waserror= True;
-	    }
-	  }else {              
-            zzinc_(Zcoplanarridges);
-            qh_precision ("coplanar ridge");
-            trace0((qh ferr, "qhull precision error: f%d may be coplanar to f%d, since p%d (v%d) is within %6.4g during p%d\n",
-              facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist, qh furthest_id));
-          }
-        }
-      }
-    }
-    if (!allsimplicial) {
-      if (qh CENTERtype == qh_AScentrum) {
-        if (!facet->center)
-          facet->center= qh_getcentrum (facet);
-        centrum= facet->center;
-      }else {
-	if (!centrum_warning && (!facet->simplicial || facet->tricoplanar)) {
-	   centrum_warning= True;
-	   fprintf (qh ferr, "qhull note: recomputing centrums for convexity test.  This may lead to false, precision errors.\n");
-	}
-        centrum= qh_getcentrum(facet);
-        tempcentrum= True;
-      }
-      FOREACHneighbor_(facet) {
-	if (qh ZEROcentrum && facet->simplicial && neighbor->simplicial)
-	  continue;
-	if (facet->tricoplanar || neighbor->tricoplanar)
-	  continue;
-        zzinc_(Zdistconvex);
-        qh_distplane (centrum, neighbor, &dist);
-        if (dist > qh DISTround) {
-          zzinc_(Zconcaveridges);
-          qh_precision ("concave ridge");
-          fprintf (qh ferr, "qhull precision error: f%d is concave to f%d.  Centrum of f%d is %6.4g above f%d\n",
-            facet->id, neighbor->id, facet->id, dist, neighbor->id);
-          errfacet1= facet;
-          errfacet2= neighbor;
-          waserror= True;
-	}else if (dist >= 0.0) {   /* if arithmetic always rounds the same,
-				     can test against centrum radius instead */
-          zzinc_(Zcoplanarridges);
-          qh_precision ("coplanar ridge");
-          fprintf (qh ferr, "qhull precision error: f%d is coplanar or concave to f%d.  Centrum of f%d is %6.4g above f%d\n",
-            facet->id, neighbor->id, facet->id, dist, neighbor->id);
-	  errfacet1= facet;
-	  errfacet2= neighbor;
-	  waserror= True;
-        }
-      }
-      if (tempcentrum)
-        qh_memfree(centrum, qh normal_size);
-    }
-  }
-  if (waserror && !qh FORCEoutput)
-    qh_errexit2 (qh_ERRprec, errfacet1, errfacet2);
-} /* checkconvex */
-
-
-/*---------------------------------
-  
-  qh_checkfacet( facet, newmerge, waserror )
-    checks for consistency errors in facet
-    newmerge set if from merge.c
-
-  returns:
-    sets waserror if any error occurs
-
-  checks:
-    vertex ids are inverse sorted
-    unless newmerge, at least hull_dim neighbors and vertices (exactly if simplicial)
-    if non-simplicial, at least as many ridges as neighbors
-    neighbors are not duplicated
-    ridges are not duplicated
-    in 3-d, ridges=verticies
-    (qh.hull_dim-1) ridge vertices
-    neighbors are reciprocated
-    ridge neighbors are facet neighbors and a ridge for every neighbor
-    simplicial neighbors match facetintersect
-    vertex intersection matches vertices of common ridges 
-    vertex neighbors and facet vertices agree
-    all ridges have distinct vertex sets
-
-  notes:  
-    uses neighbor->seen
-
-  design:
-    check sets
-    check vertices
-    check sizes of neighbors and vertices
-    check for qh_MERGEridge and qh_DUPLICATEridge flags
-    check neighbor set
-    check ridge set
-    check ridges, neighbors, and vertices
-*/
-void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) {
-  facetT *neighbor, **neighborp, *errother=NULL;
-  ridgeT *ridge, **ridgep, *errridge= NULL, *ridge2;
-  vertexT *vertex, **vertexp;
-  unsigned previousid= INT_MAX;
-  int numneighbors, numvertices, numridges=0, numRvertices=0;
-  boolT waserror= False;
-  int skipA, skipB, ridge_i, ridge_n, i;
-  setT *intersection;
-
-  if (facet->visible) {
-    fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d is on the visible_list\n",
-      facet->id);
-    qh_errexit (qh_ERRqhull, facet, NULL);
-  }
-  if (!facet->normal) {
-    fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d does not have  a normal\n",
-      facet->id);
-    waserror= True;
-  }
-  qh_setcheck (facet->vertices, "vertices for f", facet->id);
-  qh_setcheck (facet->ridges, "ridges for f", facet->id);
-  qh_setcheck (facet->outsideset, "outsideset for f", facet->id);
-  qh_setcheck (facet->coplanarset, "coplanarset for f", facet->id);
-  qh_setcheck (facet->neighbors, "neighbors for f", facet->id);
-  FOREACHvertex_(facet->vertices) {
-    if (vertex->deleted) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): deleted vertex v%d in f%d\n", vertex->id, facet->id);
-      qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex);
-      waserror= True;
-    }
-    if (vertex->id >= previousid) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): vertices of f%d are not in descending id order at v%d\n", facet->id, vertex->id);
-      waserror= True;
-      break;
-    }
-    previousid= vertex->id;
-  }
-  numneighbors= qh_setsize(facet->neighbors);
-  numvertices= qh_setsize(facet->vertices);
-  numridges= qh_setsize(facet->ridges);
-  if (facet->simplicial) {
-    if (numvertices+numneighbors != 2*qh hull_dim 
-    && !facet->degenerate && !facet->redundant) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): for simplicial facet f%d, #vertices %d + #neighbors %d != 2*qh hull_dim\n", 
-                facet->id, numvertices, numneighbors);
-      qh_setprint (qh ferr, "", facet->neighbors);
-      waserror= True;
-    }
-  }else { /* non-simplicial */
-    if (!newmerge 
-    &&(numvertices < qh hull_dim || numneighbors < qh hull_dim)
-    && !facet->degenerate && !facet->redundant) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, #vertices %d or #neighbors %d < qh hull_dim\n",
-         facet->id, numvertices, numneighbors);
-       waserror= True;
-    }
-    /* in 3-d, can get a vertex twice in an edge list, e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv TP624 TW1e-13 T4 */
-    if (numridges < numneighbors
-    ||(qh hull_dim == 3 && numvertices > numridges && !qh NEWfacets)
-    ||(qh hull_dim == 2 && numridges + numvertices + numneighbors != 6)) {
-      if (!facet->degenerate && !facet->redundant) {
-	fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, #ridges %d < #neighbors %d or (3-d) > #vertices %d or (2-d) not all 2\n",
-	    facet->id, numridges, numneighbors, numvertices);
-	waserror= True;
-      }
-    }
-  }
-  FOREACHneighbor_(facet) {
-    if (neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d still has a MERGE or DUP neighbor\n", facet->id);
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-    neighbor->seen= True;
-  }
-  FOREACHneighbor_(facet) {
-    if (!qh_setin(neighbor->neighbors, facet)) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has neighbor f%d, but f%d does not have neighbor f%d\n",
-	      facet->id, neighbor->id, neighbor->id, facet->id);
-      errother= neighbor;
-      waserror= True;
-    }
-    if (!neighbor->seen) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has a duplicate neighbor f%d\n",
-	      facet->id, neighbor->id);
-      errother= neighbor;
-      waserror= True;
-    }    
-    neighbor->seen= False;
-  }
-  FOREACHridge_(facet->ridges) {
-    qh_setcheck (ridge->vertices, "vertices for r", ridge->id);
-    ridge->seen= False;
-  }
-  FOREACHridge_(facet->ridges) {
-    if (ridge->seen) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has a duplicate ridge r%d\n",
-	      facet->id, ridge->id);
-      errridge= ridge;
-      waserror= True;
-    }    
-    ridge->seen= True;
-    numRvertices= qh_setsize(ridge->vertices);
-    if (numRvertices != qh hull_dim - 1) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): ridge between f%d and f%d has %d vertices\n", 
-                ridge->top->id, ridge->bottom->id, numRvertices);
-      errridge= ridge;
-      waserror= True;
-    }
-    neighbor= otherfacet_(ridge, facet);
-    neighbor->seen= True;
-    if (!qh_setin(facet->neighbors, neighbor)) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, neighbor f%d of ridge r%d not in facet\n",
-           facet->id, neighbor->id, ridge->id);
-      errridge= ridge;
-      waserror= True;
-    }
-  }
-  if (!facet->simplicial) {
-    FOREACHneighbor_(facet) {
-      if (!neighbor->seen) {
-        fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d does not have a ridge for neighbor f%d\n",
-	      facet->id, neighbor->id);
-	errother= neighbor;
-        waserror= True;
-      }
-      intersection= qh_vertexintersect_new(facet->vertices, neighbor->vertices);
-      qh_settemppush (intersection);
-      FOREACHvertex_(facet->vertices) {
-	vertex->seen= False;
-	vertex->seen2= False;
-      }
-      FOREACHvertex_(intersection)
-	vertex->seen= True;
-      FOREACHridge_(facet->ridges) {
-	if (neighbor != otherfacet_(ridge, facet))
-	    continue;
-	FOREACHvertex_(ridge->vertices) {
-	  if (!vertex->seen) {
-	    fprintf (qh ferr, "qhull internal error (qh_checkfacet): vertex v%d in r%d not in f%d intersect f%d\n",
-  	          vertex->id, ridge->id, facet->id, neighbor->id);
-	    qh_errexit (qh_ERRqhull, facet, ridge);
-	  }
-	  vertex->seen2= True;
-	}
-      }
-      if (!newmerge) {
-	FOREACHvertex_(intersection) {
-	  if (!vertex->seen2) {
-	    if (qh IStracing >=3 || !qh MERGING) {
-	      fprintf (qh ferr, "qhull precision error (qh_checkfacet): vertex v%d in f%d intersect f%d but\n\
- not in a ridge.  This is ok under merging.  Last point was p%d\n",
-		     vertex->id, facet->id, neighbor->id, qh furthest_id);
-	      if (!qh FORCEoutput && !qh MERGING) {
-		qh_errprint ("ERRONEOUS", facet, neighbor, NULL, vertex);
-		if (!qh MERGING)
-		  qh_errexit (qh_ERRqhull, NULL, NULL);
-	      }
-	    }
-	  }
-	}
-      }      
-      qh_settempfree (&intersection);
-    }
-  }else { /* simplicial */
-    FOREACHneighbor_(facet) {
-      if (neighbor->simplicial) {    
-	skipA= SETindex_(facet->neighbors, neighbor);
-	skipB= qh_setindex (neighbor->neighbors, facet);
-	if (!qh_setequal_skip (facet->vertices, skipA, neighbor->vertices, skipB)) {
-	  fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d skip %d and neighbor f%d skip %d do not match \n",
-		   facet->id, skipA, neighbor->id, skipB);
-	  errother= neighbor;
-	  waserror= True;
-	}
-      }
-    }
-  }
-  if (qh hull_dim < 5 && (qh IStracing > 2 || qh CHECKfrequently)) {
-    FOREACHridge_i_(facet->ridges) {           /* expensive */
-      for (i= ridge_i+1; i < ridge_n; i++) {
-	ridge2= SETelemt_(facet->ridges, i, ridgeT);
-	if (qh_setequal (ridge->vertices, ridge2->vertices)) {
-	  fprintf (qh ferr, "qh_checkfacet: ridges r%d and r%d have the same vertices\n",
-		  ridge->id, ridge2->id);
-	  errridge= ridge;
-	  waserror= True;
-	}
-      }
-    }
-  }
-  if (waserror) {
-    qh_errprint("ERRONEOUS", facet, errother, errridge, NULL);
-    *waserrorp= True;
-  }
-} /* checkfacet */
-
-
-/*---------------------------------
-  
-  qh_checkflipped_all( facetlist )
-    checks orientation of facets in list against interior point
-*/
-void qh_checkflipped_all (facetT *facetlist) {
-  facetT *facet;
-  boolT waserror= False;
-  realT dist;
-
-  if (facetlist == qh facet_list)
-    zzval_(Zflippedfacets)= 0;
-  FORALLfacet_(facetlist) {
-    if (facet->normal && !qh_checkflipped (facet, &dist, !qh_ALL)) {
-      fprintf(qh ferr, "qhull precision error: facet f%d is flipped, distance= %6.12g\n",
-	      facet->id, dist);
-      if (!qh FORCEoutput) {
-	qh_errprint("ERRONEOUS", facet, NULL, NULL, NULL);
-	waserror= True;
-      }
-    }
-  }
-  if (waserror) {
-    fprintf (qh ferr, "\n\
-A flipped facet occurs when its distance to the interior point is\n\
-greater than %2.2g, the maximum roundoff error.\n", -qh DISTround);
-    qh_errexit(qh_ERRprec, NULL, NULL);
-  }
-} /* checkflipped_all */
-
-/*---------------------------------
-  
-  qh_checkpolygon( facetlist )
-    checks the correctness of the structure
-
-  notes:
-    call with either qh.facet_list or qh.newfacet_list
-    checks num_facets and num_vertices if qh.facet_list
-
-  design:
-    for each facet
-      checks facet and outside set
-    initializes vertexlist
-    for each facet
-      checks vertex set
-    if checking all facets (qh.facetlist)
-      check facet count
-      if qh.VERTEXneighbors
-        check vertex neighbors and count
-      check vertex count
-*/
-void qh_checkpolygon(facetT *facetlist) {
-  facetT *facet;
-  vertexT *vertex, **vertexp, *vertexlist;
-  int numfacets= 0, numvertices= 0, numridges= 0;
-  int totvneighbors= 0, totvertices= 0;
-  boolT waserror= False, nextseen= False, visibleseen= False;
-  
-  trace1((qh ferr, "qh_checkpolygon: check all facets from f%d\n", facetlist->id));
-  if (facetlist != qh facet_list || qh ONLYgood)
-    nextseen= True;
-  FORALLfacet_(facetlist) {
-    if (facet == qh visible_list)
-      visibleseen= True;
-    if (!facet->visible) {
-      if (!nextseen) {
-	if (facet == qh facet_next)
-	  nextseen= True;
-	else if (qh_setsize (facet->outsideset)) {
-	  if (!qh NARROWhull
-#if !qh_COMPUTEfurthest
-	       || facet->furthestdist >= qh MINoutside
-#endif
-			) {
-	    fprintf (qh ferr, "qhull internal error (qh_checkpolygon): f%d has outside points before qh facet_next\n",
-		     facet->id);
-	    qh_errexit (qh_ERRqhull, facet, NULL);
-	  }
-	}
-      }
-      numfacets++;
-      qh_checkfacet(facet, False, &waserror);
-    }
-  }
-  if (qh visible_list && !visibleseen && facetlist == qh facet_list) {
-    fprintf (qh ferr, "qhull internal error (qh_checkpolygon): visible list f%d no longer on facet list\n", qh visible_list->id);
-    qh_printlists();
-    qh_errexit (qh_ERRqhull, qh visible_list, NULL);
-  }
-  if (facetlist == qh facet_list)
-    vertexlist= qh vertex_list;
-  else if (facetlist == qh newfacet_list)
-    vertexlist= qh newvertex_list;
-  else
-    vertexlist= NULL;
-  FORALLvertex_(vertexlist) {
-    vertex->seen= False;
-    vertex->visitid= 0;
-  }  
-  FORALLfacet_(facetlist) {
-    if (facet->visible)
-      continue;
-    if (facet->simplicial)
-      numridges += qh hull_dim;
-    else
-      numridges += qh_setsize (facet->ridges);
-    FOREACHvertex_(facet->vertices) {
-      vertex->visitid++;
-      if (!vertex->seen) {
-	vertex->seen= True;
-	numvertices++;
-	if (qh_pointid (vertex->point) == -1) {
-	  fprintf (qh ferr, "qhull internal error (qh_checkpolygon): unknown point %p for vertex v%d first_point %p\n",
-		   vertex->point, vertex->id, qh first_point);
-	  waserror= True;
-	}
-      }
-    }
-  }
-  qh vertex_visit += numfacets;
-  if (facetlist == qh facet_list) {
-    if (numfacets != qh num_facets - qh num_visible) {
-      fprintf(qh ferr, "qhull internal error (qh_checkpolygon): actual number of facets is %d, cumulative facet count is %d - %d visible facets\n",
-	      numfacets, qh num_facets, qh num_visible);
-      waserror= True;
-    }
-    qh vertex_visit++;
-    if (qh VERTEXneighbors) {
-      FORALLvertices {
-	qh_setcheck (vertex->neighbors, "neighbors for v", vertex->id);
-	if (vertex->deleted)
-	  continue;
-	totvneighbors += qh_setsize (vertex->neighbors);
-      }
-      FORALLfacet_(facetlist)
-	totvertices += qh_setsize (facet->vertices);
-      if (totvneighbors != totvertices) {
-	fprintf(qh ferr, "qhull internal error (qh_checkpolygon): vertex neighbors inconsistent.  Totvneighbors %d, totvertices %d\n",
-		totvneighbors, totvertices);
-	waserror= True;
-      }
-    }
-    if (numvertices != qh num_vertices - qh_setsize(qh del_vertices)) {
-      fprintf(qh ferr, "qhull internal error (qh_checkpolygon): actual number of vertices is %d, cumulative vertex count is %d\n",
-	      numvertices, qh num_vertices - qh_setsize(qh del_vertices));
-      waserror= True;
-    }
-    if (qh hull_dim == 2 && numvertices != numfacets) {
-      fprintf (qh ferr, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n",
-        numvertices, numfacets);
-      waserror= True;
-    }
-    if (qh hull_dim == 3 && numvertices + numfacets - numridges/2 != 2) {
-      fprintf (qh ferr, "qhull warning: #vertices %d + #facets %d - #edges %d != 2\n\
-	A vertex appears twice in a edge list.  May occur during merging.",
-        numvertices, numfacets, numridges/2);
-      /* occurs if lots of merging and a vertex ends up twice in an edge list.  e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv */
-    }
-  }
-  if (waserror) 
-    qh_errexit(qh_ERRqhull, NULL, NULL);
-} /* checkpolygon */
-
-
-/*---------------------------------
-  
-  qh_checkvertex( vertex )
-    check vertex for consistency
-    checks vertex->neighbors
-
-  notes:
-    neighbors checked efficiently in checkpolygon
-*/
-void qh_checkvertex (vertexT *vertex) {
-  boolT waserror= False;
-  facetT *neighbor, **neighborp, *errfacet=NULL;
-
-  if (qh_pointid (vertex->point) == -1) {
-    fprintf (qh ferr, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point);
-    waserror= True;
-  }
-  if (vertex->id >= qh vertex_id) {
-    fprintf (qh ferr, "qhull internal error (qh_checkvertex): unknown vertex id %d\n", vertex->id);
-    waserror= True;
-  }
-  if (!waserror && !vertex->deleted) {
-    if (qh_setsize (vertex->neighbors)) {
-      FOREACHneighbor_(vertex) {
-        if (!qh_setin (neighbor->vertices, vertex)) {
-          fprintf (qh ferr, "qhull internal error (qh_checkvertex): neighbor f%d does not contain v%d\n", neighbor->id, vertex->id);
-	  errfacet= neighbor;
-	  waserror= True;
-	}
-      }
-    }
-  }
-  if (waserror) {
-    qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex);
-    qh_errexit (qh_ERRqhull, errfacet, NULL);
-  }
-} /* checkvertex */
-  
-/*---------------------------------
-  
-  qh_clearcenters( type )
-    clear old data from facet->center
-
-  notes:
-    sets new centertype
-    nop if CENTERtype is the same
-*/
-void qh_clearcenters (qh_CENTER type) {
-  facetT *facet;
-  
-  if (qh CENTERtype != type) {
-    FORALLfacets {
-      if (qh CENTERtype == qh_ASvoronoi){
-        if (facet->center) {
-          qh_memfree (facet->center, qh center_size);
-          facet->center= NULL;
-        }
-      }else /* qh CENTERtype == qh_AScentrum */ {
-        if (facet->center) {
-          qh_memfree (facet->center, qh normal_size);
-	  facet->center= NULL;
-        }
-      }
-    }
-    qh CENTERtype= type;
-  }
-  trace2((qh ferr, "qh_clearcenters: switched to center type %d\n", type));
-} /* clearcenters */
-
-/*---------------------------------
-  
-  qh_createsimplex( vertices )
-    creates a simplex from a set of vertices
-
-  returns:
-    initializes qh.facet_list to the simplex
-    initializes qh.newfacet_list, .facet_tail
-    initializes qh.vertex_list, .newvertex_list, .vertex_tail
-
-  design:
-    initializes lists
-    for each vertex
-      create a new facet
-    for each new facet
-      create its neighbor set
-*/
-void qh_createsimplex(setT *vertices) {
-  facetT *facet= NULL, *newfacet;
-  boolT toporient= True;
-  int vertex_i, vertex_n, nth;
-  setT *newfacets= qh_settemp (qh hull_dim+1);
-  vertexT *vertex;
-  
-  qh facet_list= qh newfacet_list= qh facet_tail= qh_newfacet();
-  qh num_facets= qh num_vertices= qh num_visible= 0;
-  qh vertex_list= qh newvertex_list= qh vertex_tail= qh_newvertex(NULL);
-  FOREACHvertex_i_(vertices) {
-    newfacet= qh_newfacet();
-    newfacet->vertices= qh_setnew_delnthsorted (vertices, vertex_n,
-						vertex_i, 0);
-    newfacet->toporient= toporient;
-    qh_appendfacet(newfacet);
-    newfacet->newfacet= True;
-    qh_appendvertex (vertex);
-    qh_setappend (&newfacets, newfacet);
-    toporient ^= True;
-  }
-  FORALLnew_facets {
-    nth= 0;
-    FORALLfacet_(qh newfacet_list) {
-      if (facet != newfacet) 
-        SETelem_(newfacet->neighbors, nth++)= facet;
-    }
-    qh_settruncate (newfacet->neighbors, qh hull_dim);
-  }
-  qh_settempfree (&newfacets);
-  trace1((qh ferr, "qh_createsimplex: created simplex\n"));
-} /* createsimplex */
-
-/*---------------------------------
-  
-  qh_delridge( ridge )
-    deletes ridge from data structures it belongs to
-    frees up its memory
-
-  notes:
-    in merge.c, caller sets vertex->delridge for each vertex
-    ridges also freed in qh_freeqhull
-*/
-void qh_delridge(ridgeT *ridge) {
-  void **freelistp; /* used !qh_NOmem */
-  
-  qh_setdel(ridge->top->ridges, ridge);
-  qh_setdel(ridge->bottom->ridges, ridge);
-  qh_setfree(&(ridge->vertices));
-  qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-} /* delridge */
-
-
-/*---------------------------------
-  
-  qh_delvertex( vertex )
-    deletes a vertex and frees its memory
-
-  notes:
-    assumes vertex->adjacencies have been updated if needed
-    unlinks from vertex_list
-*/
-void qh_delvertex (vertexT *vertex) {
-
-  if (vertex == qh tracevertex)
-    qh tracevertex= NULL;
-  qh_removevertex (vertex);
-  qh_setfree (&vertex->neighbors);
-  qh_memfree(vertex, sizeof(vertexT));
-} /* delvertex */
-
-
-/*---------------------------------
-  
-  qh_facet3vertex(  )
-    return temporary set of 3-d vertices in qh_ORIENTclock order
-
-  design:
-    if simplicial facet
-      build set from facet->vertices with facet->toporient
-    else
-      for each ridge in order
-        build set from ridge's vertices
-*/
-setT *qh_facet3vertex (facetT *facet) {
-  ridgeT *ridge, *firstridge;
-  vertexT *vertex;
-  int cntvertices, cntprojected=0;
-  setT *vertices;
-
-  cntvertices= qh_setsize(facet->vertices);
-  vertices= qh_settemp (cntvertices);
-  if (facet->simplicial) {
-    if (cntvertices != 3) {
-      fprintf (qh ferr, "qhull internal error (qh_facet3vertex): only %d vertices for simplicial facet f%d\n", 
-                  cntvertices, facet->id);
-      qh_errexit(qh_ERRqhull, facet, NULL);
-    }
-    qh_setappend (&vertices, SETfirst_(facet->vertices));
-    if (facet->toporient ^ qh_ORIENTclock)
-      qh_setappend (&vertices, SETsecond_(facet->vertices));
-    else
-      qh_setaddnth (&vertices, 0, SETsecond_(facet->vertices));
-    qh_setappend (&vertices, SETelem_(facet->vertices, 2));
-  }else {
-    ridge= firstridge= SETfirstt_(facet->ridges, ridgeT);   /* no infinite */
-    while ((ridge= qh_nextridge3d (ridge, facet, &vertex))) {
-      qh_setappend (&vertices, vertex);
-      if (++cntprojected > cntvertices || ridge == firstridge)
-        break;
-    }
-    if (!ridge || cntprojected != cntvertices) {
-      fprintf (qh ferr, "qhull internal error (qh_facet3vertex): ridges for facet %d don't match up.  got at least %d\n", 
-                  facet->id, cntprojected);
-      qh_errexit(qh_ERRqhull, facet, ridge);
-    }
-  }
-  return vertices;
-} /* facet3vertex */
-
-/*---------------------------------
-  
-  qh_findbestfacet( point, bestoutside, bestdist, isoutside )
-    find facet that is furthest below a point 
-
-    for Delaunay triangulations, 
-      Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
-      Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates. 
-
-  returns:
-    if bestoutside is set (e.g., qh_ALL)
-      returns best facet that is not upperdelaunay
-      if Delaunay and inside, point is outside circumsphere of bestfacet
-    else
-      returns first facet below point
-      if point is inside, returns nearest, !upperdelaunay facet
-    distance to facet
-    isoutside set if outside of facet
-    
-  notes:
-    this works for all distributions
-    if inside, qh_findbestfacet performs an exhaustive search
-       this may be too conservative.  Sometimes it is clearly required.
-    qh_findbestfacet is not used by qhull.
-    uses qh.visit_id and qh.coplanarset
-    
-  see:
-    qh_findbest
-*/
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside) {
-  facetT *bestfacet= NULL;
-  int numpart, totpart= 0;
-  
-  bestfacet= qh_findbest (point, qh facet_list, 
-			    bestoutside, !qh_ISnewfacets, bestoutside /* qh_NOupper */,
-			    bestdist, isoutside, &totpart);
-  if (*bestdist < -qh DISTround) {
-    bestfacet= qh_findfacet_all (point, bestdist, isoutside, &numpart);
-    totpart += numpart;
-    if ((isoutside && bestoutside)
-    || (!isoutside && bestfacet->upperdelaunay)) {
-      bestfacet= qh_findbest (point, bestfacet, 
-			    bestoutside, False, bestoutside,
-			    bestdist, isoutside, &totpart);
-      totpart += numpart;
-    }
-  }
-  trace3((qh ferr, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
-	  bestfacet->id, *bestdist, *isoutside, totpart));
-  return bestfacet;
-} /* findbestfacet */ 
- 
-/*---------------------------------
-  
-  qh_findfacet_all( point, bestdist, isoutside, numpart )
-    exhaustive search for facet below a point 
-
-    for Delaunay triangulations, 
-      Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
-      Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates. 
-
-  returns:
-    returns first facet below point
-    if point is inside, 
-      returns nearest facet
-    distance to facet
-    isoutside if point is outside of the hull
-    number of distance tests
-*/
-facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside,
-			  int *numpart) {
-  facetT *bestfacet= NULL, *facet;
-  realT dist;
-  int totpart= 0;
-  
-  *bestdist= REALmin;
-  *isoutside= False;
-  FORALLfacets {
-    if (facet->flipped || !facet->normal)
-      continue;
-    totpart++;
-    qh_distplane (point, facet, &dist);
-    if (dist > *bestdist) {
-      *bestdist= dist;
-      bestfacet= facet;
-      if (dist > qh MINoutside) {
-        *isoutside= True;
-        break;
-      }
-    }
-  }
-  *numpart= totpart;
-  trace3((qh ferr, "qh_findfacet_all: f%d dist %2.2g isoutside %d totpart %d\n",
-	  getid_(bestfacet), *bestdist, *isoutside, totpart));
-  return bestfacet;
-} /* findfacet_all */ 
- 
-/*---------------------------------
-  
-  qh_findgood( facetlist, goodhorizon )
-    identify good facets for qh.PRINTgood
-    if qh.GOODvertex>0
-      facet includes point as vertex
-      if !match, returns goodhorizon
-      inactive if qh.MERGING
-    if qh.GOODpoint
-      facet is visible or coplanar (>0) or not visible (<0) 
-    if qh.GOODthreshold
-      facet->normal matches threshold
-    if !goodhorizon and !match, 
-      selects facet with closest angle
-      sets GOODclosest
-      
-  returns:
-    number of new, good facets found
-    determines facet->good
-    may update qh.GOODclosest
-    
-  notes:
-    qh_findgood_all further reduces the good region
-
-  design:
-    count good facets
-    mark good facets for qh.GOODpoint  
-    mark good facets for qh.GOODthreshold
-    if necessary
-      update qh.GOODclosest  
-*/
-int qh_findgood (facetT *facetlist, int goodhorizon) {
-  facetT *facet, *bestfacet= NULL;
-  realT angle, bestangle= REALmax, dist;
-  int  numgood=0;
-
-  FORALLfacet_(facetlist) {
-    if (facet->good)
-      numgood++;
-  }
-  if (qh GOODvertex>0 && !qh MERGING) {
-    FORALLfacet_(facetlist) {
-      if (!qh_isvertex (qh GOODvertexp, facet->vertices)) {
-        facet->good= False;
-        numgood--;
-      }
-    }
-  }
-  if (qh GOODpoint && numgood) {
-    FORALLfacet_(facetlist) {
-      if (facet->good && facet->normal) {
-        zinc_(Zdistgood);
-        qh_distplane (qh GOODpointp, facet, &dist);
-        if ((qh GOODpoint > 0) ^ (dist > 0.0)) {
-          facet->good= False;
-          numgood--;
-        }
-      }
-    }
-  }
-  if (qh GOODthreshold && (numgood || goodhorizon || qh GOODclosest)) {
-    FORALLfacet_(facetlist) {
-      if (facet->good && facet->normal) {
-        if (!qh_inthresholds (facet->normal, &angle)) {
-          facet->good= False;
-          numgood--;
-          if (angle < bestangle) {
-            bestangle= angle;
-            bestfacet= facet;
-          }
-        }
-      }
-    }
-    if (!numgood && (!goodhorizon || qh GOODclosest)) {
-      if (qh GOODclosest) {
-	if (qh GOODclosest->visible)
-	  qh GOODclosest= NULL;
-	else {
-	  qh_inthresholds (qh GOODclosest->normal, &angle);
-	  if (angle < bestangle)
-	    bestfacet= qh GOODclosest;
-	}
-      }
-      if (bestfacet && bestfacet != qh GOODclosest) {
-	if (qh GOODclosest)
-	  qh GOODclosest->good= False;
-	qh GOODclosest= bestfacet;
-	bestfacet->good= True;
-	numgood++;
-	trace2((qh ferr, "qh_findgood: f%d is closest (%2.2g) to thresholds\n", 
-           bestfacet->id, bestangle));
-	return numgood;
-      }
-    }else if (qh GOODclosest) { /* numgood > 0 */
-      qh GOODclosest->good= False;
-      qh GOODclosest= NULL;
-    }
-  }
-  zadd_(Zgoodfacet, numgood);
-  trace2((qh ferr, "qh_findgood: found %d good facets with %d good horizon\n",
-               numgood, goodhorizon));
-  if (!numgood && qh GOODvertex>0 && !qh MERGING) 
-    return goodhorizon;
-  return numgood;
-} /* findgood */
-
-/*---------------------------------
-  
-  qh_findgood_all( facetlist )
-    apply other constraints for good facets (used by qh.PRINTgood)
-    if qh.GOODvertex 
-      facet includes (>0) or doesn't include (<0) point as vertex
-      if last good facet and ONLYgood, prints warning and continues
-    if qh.SPLITthresholds
-      facet->normal matches threshold, or if none, the closest one
-    calls qh_findgood
-    nop if good not used
-
-  returns:
-    clears facet->good if not good
-    sets qh.num_good
-
-  notes:
-    this is like qh_findgood but more restrictive
-
-  design:
-    uses qh_findgood to mark good facets
-    marks facets for qh.GOODvertex
-    marks facets for qh.SPLITthreholds  
-*/
-void qh_findgood_all (facetT *facetlist) {
-  facetT *facet, *bestfacet=NULL;
-  realT angle, bestangle= REALmax;
-  int  numgood=0, startgood;
-
-  if (!qh GOODvertex && !qh GOODthreshold && !qh GOODpoint 
-  && !qh SPLITthresholds)
-    return;
-  if (!qh ONLYgood)
-    qh_findgood (qh facet_list, 0);
-  FORALLfacet_(facetlist) {
-    if (facet->good)
-      numgood++;
-  }
-  if (qh GOODvertex <0 || (qh GOODvertex > 0 && qh MERGING)) {
-    FORALLfacet_(facetlist) {
-      if (facet->good && ((qh GOODvertex > 0) ^ !!qh_isvertex (qh GOODvertexp, facet->vertices))) {
-        if (!--numgood) {
-	  if (qh ONLYgood) {
-            fprintf (qh ferr, "qhull warning: good vertex p%d does not match last good facet f%d.  Ignored.\n",
-               qh_pointid(qh GOODvertexp), facet->id);
-	    return;
-	  }else if (qh GOODvertex > 0)
-            fprintf (qh ferr, "qhull warning: point p%d is not a vertex ('QV%d').\n",
-		qh GOODvertex-1, qh GOODvertex-1);
-	  else
-            fprintf (qh ferr, "qhull warning: point p%d is a vertex for every facet ('QV-%d').\n",
-	        -qh GOODvertex - 1, -qh GOODvertex - 1);
-        }
-        facet->good= False;
-      }
-    }
-  }
-  startgood= numgood;
-  if (qh SPLITthresholds) {
-    FORALLfacet_(facetlist) {
-      if (facet->good) {
-        if (!qh_inthresholds (facet->normal, &angle)) {
-          facet->good= False;
-          numgood--;
-          if (angle < bestangle) {
-            bestangle= angle;
-            bestfacet= facet;
-          }
-        }
-      }
-    }
-    if (!numgood && bestfacet) {
-      bestfacet->good= True;
-      numgood++;
-      trace0((qh ferr, "qh_findgood_all: f%d is closest (%2.2g) to thresholds\n", 
-           bestfacet->id, bestangle));
-      return;
-    }
-  }
-  qh num_good= numgood;
-  trace0((qh ferr, "qh_findgood_all: %d good facets remain out of %d facets\n",
-        numgood, startgood));
-} /* findgood_all */
-
-/*---------------------------------
-  
-  qh_furthestnext()
-    set qh.facet_next to facet with furthest of all furthest points
-    searches all facets on qh.facet_list
-
-  notes:
-    this may help avoid precision problems
-*/
-void qh_furthestnext (void /* qh facet_list */) {
-  facetT *facet, *bestfacet= NULL;
-  realT dist, bestdist= -REALmax;
-
-  FORALLfacets {
-    if (facet->outsideset) {
-#if qh_COMPUTEfurthest
-      pointT *furthest;
-      furthest= (pointT*)qh_setlast (facet->outsideset);
-      zinc_(Zcomputefurthest);
-      qh_distplane (furthest, facet, &dist);
-#else
-      dist= facet->furthestdist;
-#endif
-      if (dist > bestdist) {
-	bestfacet= facet;
-	bestdist= dist;
-      }
-    }
-  }
-  if (bestfacet) {
-    qh_removefacet (bestfacet);
-    qh_prependfacet (bestfacet, &qh facet_next);
-    trace1((qh ferr, "qh_furthestnext: made f%d next facet (dist %.2g)\n",
-	    bestfacet->id, bestdist));
-  }
-} /* furthestnext */
-
-/*---------------------------------
-  
-  qh_furthestout( facet )
-    make furthest outside point the last point of outsideset
-
-  returns:
-    updates facet->outsideset
-    clears facet->notfurthest
-    sets facet->furthestdist
-
-  design:
-    determine best point of outsideset
-    make it the last point of outsideset
-*/
-void qh_furthestout (facetT *facet) {
-  pointT *point, **pointp, *bestpoint= NULL;
-  realT dist, bestdist= -REALmax;
-
-  FOREACHpoint_(facet->outsideset) {
-    qh_distplane (point, facet, &dist);
-    zinc_(Zcomputefurthest);
-    if (dist > bestdist) {
-      bestpoint= point;
-      bestdist= dist;
-    }
-  }
-  if (bestpoint) {
-    qh_setdel (facet->outsideset, point);
-    qh_setappend (&facet->outsideset, point);
-#if !qh_COMPUTEfurthest
-    facet->furthestdist= bestdist;
-#endif
-  }
-  facet->notfurthest= False;
-  trace3((qh ferr, "qh_furthestout: p%d is furthest outside point of f%d\n",
-	  qh_pointid (point), facet->id));
-} /* furthestout */
-
-
-/*---------------------------------
-  
-  qh_infiniteloop( facet )
-    report infinite loop error due to facet
-*/
-void qh_infiniteloop (facetT *facet) {
-
-  fprintf (qh ferr, "qhull internal error (qh_infiniteloop): potential infinite loop detected\n");
-  qh_errexit (qh_ERRqhull, facet, NULL);
-} /* qh_infiniteloop */
-
-/*---------------------------------
-  
-  qh_initbuild()
-    initialize hull and outside sets with point array
-    qh.FIRSTpoint/qh.NUMpoints is point array
-    if qh.GOODpoint
-      adds qh.GOODpoint to initial hull
-
-  returns:
-    qh_facetlist with initial hull
-    points partioned into outside sets, coplanar sets, or inside
-    initializes qh.GOODpointp, qh.GOODvertexp,
-
-  design:
-    initialize global variables used during qh_buildhull
-    determine precision constants and points with max/min coordinate values
-      if qh.SCALElast, scale last coordinate (for 'd')
-    build initial simplex
-    partition input points into facets of initial simplex
-    set up lists
-    if qh.ONLYgood
-      check consistency  
-      add qh.GOODvertex if defined
-*/
-void qh_initbuild( void) {
-  setT *maxpoints, *vertices;
-  facetT *facet;
-  int i, numpart;
-  realT dist;
-  boolT isoutside;
-
-  qh furthest_id= -1;
-  qh lastreport= 0;
-  qh facet_id= qh vertex_id= qh ridge_id= 0;
-  qh visit_id= qh vertex_visit= 0;
-  qh maxoutdone= False;
-
-  if (qh GOODpoint > 0) 
-    qh GOODpointp= qh_point (qh GOODpoint-1);
-  else if (qh GOODpoint < 0) 
-    qh GOODpointp= qh_point (-qh GOODpoint-1);
-  if (qh GOODvertex > 0)
-    qh GOODvertexp= qh_point (qh GOODvertex-1);
-  else if (qh GOODvertex < 0) 
-    qh GOODvertexp= qh_point (-qh GOODvertex-1);
-  if ((qh GOODpoint  
-       && (qh GOODpointp < qh first_point  /* also catches !GOODpointp */
-	   || qh GOODpointp > qh_point (qh num_points-1)))
-    || (qh GOODvertex
-	&& (qh GOODvertexp < qh first_point  /* also catches !GOODvertexp */
-	    || qh GOODvertexp > qh_point (qh num_points-1)))) {
-    fprintf (qh ferr, "qhull input error: either QGn or QVn point is > p%d\n",
-	     qh num_points-1);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  maxpoints= qh_maxmin(qh first_point, qh num_points, qh hull_dim);
-  if (qh SCALElast)
-    qh_scalelast (qh first_point, qh num_points, qh hull_dim,
-               qh MINlastcoord, qh MAXlastcoord, qh MAXwidth);
-  qh_detroundoff();
-  if (qh DELAUNAY && qh upper_threshold[qh hull_dim-1] > REALmax/2
-                  && qh lower_threshold[qh hull_dim-1] < -REALmax/2) {
-    for (i= qh_PRINTEND; i--; ) {
-      if (qh PRINTout[i] == qh_PRINTgeom && qh DROPdim < 0 
- 	  && !qh GOODthreshold && !qh SPLITthresholds)
-	break;  /* in this case, don't set upper_threshold */
-    }
-    if (i < 0) {
-      if (qh UPPERdelaunay) { /* matches qh.upperdelaunay in qh_setfacetplane */
-	qh lower_threshold[qh hull_dim-1]= qh ANGLEround * qh_ZEROdelaunay;
-	qh GOODthreshold= True;
-      }else { 
-	qh upper_threshold[qh hull_dim-1]= -qh ANGLEround * qh_ZEROdelaunay;
-        if (!qh GOODthreshold) 
-	  qh SPLITthresholds= True; /* build upper-convex hull even if Qg */
-          /* qh_initqhull_globals errors if Qg without Pdk/etc. */
-      }
-    }
-  }
-  vertices= qh_initialvertices(qh hull_dim, maxpoints, qh first_point, qh num_points); 
-  qh_initialhull (vertices);  /* initial qh facet_list */
-  qh_partitionall (vertices, qh first_point, qh num_points);
-  if (qh PRINToptions1st || qh TRACElevel || qh IStracing) {
-    if (qh TRACElevel || qh IStracing)
-      fprintf (qh ferr, "\nTrace level %d for %s | %s\n", 
-         qh IStracing ? qh IStracing : qh TRACElevel, qh rbox_command, qh qhull_command);
-    fprintf (qh ferr, "Options selected for Qhull %s:\n%s\n", qh_VERSION, qh qhull_options);
-  }
-  qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-  qh facet_next= qh facet_list;
-  qh_furthestnext (/* qh facet_list */);
-  if (qh PREmerge) {
-    qh cos_max= qh premerge_cos;
-    qh centrum_radius= qh premerge_centrum;
-  }
-  if (qh ONLYgood) {
-    if (qh GOODvertex > 0 && qh MERGING) {
-      fprintf (qh ferr, "qhull input error: 'Qg QVn' (only good vertex) does not work with merging.\nUse 'QJ' to joggle the input or 'Q0' to turn off merging.\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (!(qh GOODthreshold || qh GOODpoint
-         || (!qh MERGEexact && !qh PREmerge && qh GOODvertexp))) {
-      fprintf (qh ferr, "qhull input error: 'Qg' (ONLYgood) needs a good threshold ('Pd0D0'), a\n\
-good point (QGn or QG-n), or a good vertex with 'QJ' or 'Q0' (QVn).\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (qh GOODvertex > 0  && !qh MERGING  /* matches qh_partitionall */
-	&& !qh_isvertex (qh GOODvertexp, vertices)) {
-      facet= qh_findbestnew (qh GOODvertexp, qh facet_list, 
-			  &dist, !qh_ALL, &isoutside, &numpart);
-      zadd_(Zdistgood, numpart);
-      if (!isoutside) {
-        fprintf (qh ferr, "qhull input error: point for QV%d is inside initial simplex.  It can not be made a vertex.\n",
-	       qh_pointid(qh GOODvertexp));
-        qh_errexit (qh_ERRinput, NULL, NULL);
-      }
-      if (!qh_addpoint (qh GOODvertexp, facet, False)) {
-	qh_settempfree(&vertices);
-	qh_settempfree(&maxpoints);
-	return;
-      }
-    }
-    qh_findgood (qh facet_list, 0);
-  }
-  qh_settempfree(&vertices);
-  qh_settempfree(&maxpoints);
-  trace1((qh ferr, "qh_initbuild: initial hull created and points partitioned\n"));
-} /* initbuild */
-
-/*---------------------------------
-  
-  qh_initialhull( vertices )
-    constructs the initial hull as a DIM3 simplex of vertices
-
-  design:
-    creates a simplex (initializes lists)
-    determines orientation of simplex
-    sets hyperplanes for facets
-    doubles checks orientation (in case of axis-parallel facets with Gaussian elimination)
-    checks for flipped facets and qh.NARROWhull
-    checks the result   
-*/
-void qh_initialhull(setT *vertices) {
-  facetT *facet, *firstfacet, *neighbor, **neighborp;
-  realT dist, angle, minangle= REALmax;
-#ifndef qh_NOtrace
-  int k;
-#endif
-
-  qh_createsimplex(vertices);  /* qh facet_list */
-  qh_resetlists (False, qh_RESETvisible);
-  qh facet_next= qh facet_list;      /* advance facet when processed */
-  qh interior_point= qh_getcenter(vertices);
-  firstfacet= qh facet_list;
-  qh_setfacetplane(firstfacet);
-  zinc_(Znumvisibility); /* needs to be in printsummary */
-  qh_distplane(qh interior_point, firstfacet, &dist);
-  if (dist > 0) {  
-    FORALLfacets
-      facet->toporient ^= True;
-  }
-  FORALLfacets
-    qh_setfacetplane(facet);
-  FORALLfacets {
-    if (!qh_checkflipped (facet, NULL, qh_ALL)) {/* due to axis-parallel facet */
-      trace1((qh ferr, "qh_initialhull: initial orientation incorrect.  Correct all facets\n"));
-      facet->flipped= False;
-      FORALLfacets {
-	facet->toporient ^= True;
-	qh_orientoutside (facet);
-      }
-      break;
-    }
-  }
-  FORALLfacets {
-    if (!qh_checkflipped (facet, NULL, !qh_ALL)) {  /* can happen with 'R0.1' */
-      qh_precision ("initial facet is coplanar with interior point");
-      fprintf (qh ferr, "qhull precision error: initial facet %d is coplanar with the interior point\n",
-                   facet->id);
-      qh_errexit (qh_ERRsingular, facet, NULL);
-    }
-    FOREACHneighbor_(facet) {
-      angle= qh_getangle (facet->normal, neighbor->normal);
-      minimize_( minangle, angle);
-    }
-  }
-  if (minangle < qh_MAXnarrow && !qh NOnarrow) { 
-    realT diff= 1.0 + minangle;
-
-    qh NARROWhull= True;
-    qh_option ("_narrow-hull", NULL, &diff);
-    if (minangle < qh_WARNnarrow && !qh RERUN && qh PRINTprecision)
-      fprintf (qh ferr, "qhull precision warning: \n\
-The initial hull is narrow (cosine of min. angle is %.16f).\n\
-A coplanar point may lead to a wide facet.  Options 'QbB' (scale to unit box)\n\
-or 'Qbb' (scale last coordinate) may remove this warning.  Use 'Pp' to skip\n\
-this warning.  See 'Limitations' in qh-impre.htm.\n",
-          -minangle);   /* convert from angle between normals to angle between facets */
-  }
-  zzval_(Zprocessed)= qh hull_dim+1;
-  qh_checkpolygon (qh facet_list);
-  qh_checkconvex(qh facet_list,   qh_DATAfault);
-#ifndef qh_NOtrace
-  if (qh IStracing >= 1) {
-    fprintf(qh ferr, "qh_initialhull: simplex constructed, interior point:");
-    for (k=0; k < qh hull_dim; k++) 
-      fprintf (qh ferr, " %6.4g", qh interior_point[k]);
-    fprintf (qh ferr, "\n");
-  }
-#endif
-} /* initialhull */
-
-/*---------------------------------
-  
-  qh_initialvertices( dim, maxpoints, points, numpoints )
-    determines a non-singular set of initial vertices
-    maxpoints may include duplicate points
-
-  returns:
-    temporary set of dim+1 vertices in descending order by vertex id
-    if qh.RANDOMoutside && !qh.ALLpoints
-      picks random points
-    if dim >= qh_INITIALmax, 
-      uses min/max x and max points with non-zero determinants
-
-  notes:
-    unless qh.ALLpoints, 
-      uses maxpoints as long as determinate is non-zero
-*/
-setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints) {
-  pointT *point, **pointp;
-  setT *vertices, *simplex, *tested;
-  realT randr;
-  int index, point_i, point_n, k;
-  boolT nearzero= False;
-  
-  vertices= qh_settemp (dim + 1);
-  simplex= qh_settemp (dim+1);
-  if (qh ALLpoints) 
-    qh_maxsimplex (dim, NULL, points, numpoints, &simplex);
-  else if (qh RANDOMoutside) {
-    while (qh_setsize (simplex) != dim+1) {
-      randr= qh_RANDOMint;
-      randr= randr/(qh_RANDOMmax+1);
-      index= (int)floor(qh num_points * randr);
-      while (qh_setin (simplex, qh_point (index))) {
-	index++; /* in case qh_RANDOMint always returns the same value */
-        index= index < qh num_points ? index : 0;
-      }
-      qh_setappend (&simplex, qh_point (index));
-    }
-  }else if (qh hull_dim >= qh_INITIALmax) {
-    tested= qh_settemp (dim+1);
-    qh_setappend (&simplex, SETfirst_(maxpoints));   /* max and min X coord */
-    qh_setappend (&simplex, SETsecond_(maxpoints));
-    qh_maxsimplex (fmin_(qh_INITIALsearch, dim), maxpoints, points, numpoints, &simplex);
-    k= qh_setsize (simplex);
-    FOREACHpoint_i_(maxpoints) { 
-      if (point_i & 0x1) {     /* first pick up max. coord. points */
-      	if (!qh_setin (simplex, point) && !qh_setin (tested, point)){
-	  qh_detsimplex(point, simplex, k, &nearzero);
-          if (nearzero)
-            qh_setappend (&tested, point);
-          else {
-            qh_setappend (&simplex, point);
-            if (++k == dim)  /* use search for last point */
-	      break;
-	  }
-	}
-      }
-    }
-    while (k != dim && (point= (pointT*)qh_setdellast (maxpoints))) {
-      if (!qh_setin (simplex, point) && !qh_setin (tested, point)){
-        qh_detsimplex (point, simplex, k, &nearzero);
-        if (nearzero)
-          qh_setappend (&tested, point);
-        else {
-          qh_setappend (&simplex, point);
-          k++;
-	}
-      }
-    }
-    index= 0;
-    while (k != dim && (point= qh_point (index++))) {
-      if (!qh_setin (simplex, point) && !qh_setin (tested, point)){
-        qh_detsimplex (point, simplex, k, &nearzero);
-        if (!nearzero){
-          qh_setappend (&simplex, point);
-          k++;
-	}
-      }
-    }
-    qh_settempfree (&tested);
-    qh_maxsimplex (dim, maxpoints, points, numpoints, &simplex);
-  }else
-    qh_maxsimplex (dim, maxpoints, points, numpoints, &simplex);
-  FOREACHpoint_(simplex) 
-    qh_setaddnth (&vertices, 0, qh_newvertex(point)); /* descending order */
-  qh_settempfree (&simplex);
-  return vertices;
-} /* initialvertices */
-
-
-/*---------------------------------
-  
-  qh_isvertex(  )
-    returns vertex if point is in vertex set, else returns NULL
-
-  notes:
-    for qh.GOODvertex
-*/
-vertexT *qh_isvertex (pointT *point, setT *vertices) {
-  vertexT *vertex, **vertexp;
-
-  FOREACHvertex_(vertices) {
-    if (vertex->point == point)
-      return vertex;
-  }
-  return NULL;
-} /* isvertex */
-
-/*---------------------------------
-  
-  qh_makenewfacets( point )
-    make new facets from point and qh.visible_list
-
-  returns:
-    qh.newfacet_list= list of new facets with hyperplanes and ->newfacet
-    qh.newvertex_list= list of vertices in new facets with ->newlist set
-    
-    if (qh.ONLYgood)
-      newfacets reference horizon facets, but not vice versa
-      ridges reference non-simplicial horizon ridges, but not vice versa
-      does not change existing facets
-    else
-      sets qh.NEWfacets
-      new facets attached to horizon facets and ridges
-      for visible facets, 
-        visible->r.replace is corresponding new facet
-
-  see also: 
-    qh_makenewplanes() -- make hyperplanes for facets
-    qh_attachnewfacets() -- attachnewfacets if not done here (qh ONLYgood)
-    qh_matchnewfacets() -- match up neighbors
-    qh_updatevertices() -- update vertex neighbors and delvertices
-    qh_deletevisible() -- delete visible facets
-    qh_checkpolygon() --check the result
-    qh_triangulate() -- triangulate a non-simplicial facet
-
-  design:
-    for each visible facet
-      make new facets to its horizon facets
-      update its f.replace 
-      clear its neighbor set
-*/
-vertexT *qh_makenewfacets (pointT *point /*visible_list*/) {
-  facetT *visible, *newfacet= NULL, *newfacet2= NULL, *neighbor, **neighborp;
-  vertexT *apex;
-  int numnew=0;
-
-  qh newfacet_list= qh facet_tail;
-  qh newvertex_list= qh vertex_tail;
-  apex= qh_newvertex(point);
-  qh_appendvertex (apex);  
-  qh visit_id++;
-  if (!qh ONLYgood)
-    qh NEWfacets= True;
-  FORALLvisible_facets {
-    FOREACHneighbor_(visible) 
-      neighbor->seen= False;
-    if (visible->ridges) {
-      visible->visitid= qh visit_id;
-      newfacet2= qh_makenew_nonsimplicial (visible, apex, &numnew);
-    }
-    if (visible->simplicial)
-      newfacet= qh_makenew_simplicial (visible, apex, &numnew);
-    if (!qh ONLYgood) {
-      if (newfacet2)  /* newfacet is null if all ridges defined */
-        newfacet= newfacet2;
-      if (newfacet)
-      	visible->f.replace= newfacet;
-      else
-        zinc_(Zinsidevisible);
-      SETfirst_(visible->neighbors)= NULL;
-    }
-  }
-  trace1((qh ferr, "qh_makenewfacets: created %d new facets from point p%d to horizon\n",
-	  numnew, qh_pointid(point)));
-  if (qh IStracing >= 4)
-    qh_printfacetlist (qh newfacet_list, NULL, qh_ALL);
-  return apex;
-} /* makenewfacets */
-
-/*---------------------------------
-  
-  qh_matchduplicates( atfacet, atskip, hashsize, hashcount )
-    match duplicate ridges in qh.hash_table for atfacet/atskip
-    duplicates marked with ->dupridge and qh_DUPLICATEridge
-
-  returns:
-    picks match with worst merge (min distance apart)
-    updates hashcount
-  
-  see also:
-    qh_matchneighbor
-
-  notes:
-
-  design:
-    compute hash value for atfacet and atskip
-    repeat twice -- once to make best matches, once to match the rest
-      for each possible facet in qh.hash_table
-        if it is a matching facet and pass 2
-          make match 
-	  unless tricoplanar, mark match for merging (qh_MERGEridge)
-          [e.g., tricoplanar RBOX s 1000 t993602376 | QHULL C-1e-3 d Qbb FA Qt]
-        if it is a matching facet and pass 1
-          test if this is a better match
-      if pass 1,
-        make best match (it will not be merged)
-*/
-#ifndef qh_NOmerge
-void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount) {
-  boolT same, ismatch;
-  int hash, scan;
-  facetT *facet, *newfacet, *maxmatch= NULL, *maxmatch2= NULL, *nextfacet;
-  int skip, newskip, nextskip= 0, maxskip= 0, maxskip2= 0, makematch;
-  realT maxdist= -REALmax, mindist, dist2, low, high;
-
-  hash= (int)qh_gethash (hashsize, atfacet->vertices, qh hull_dim, 1, 
-                     SETelem_(atfacet->vertices, atskip));
-  trace2((qh ferr, "qh_matchduplicates: find duplicate matches for f%d skip %d hash %d hashcount %d\n",
-	  atfacet->id, atskip, hash, *hashcount));
-  for (makematch= 0; makematch < 2; makematch++) {
-    qh visit_id++;
-    for (newfacet= atfacet, newskip= atskip; newfacet; newfacet= nextfacet, newskip= nextskip) {
-      zinc_(Zhashlookup);
-      nextfacet= NULL;
-      newfacet->visitid= qh visit_id;
-      for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT)); 
-	   scan= (++scan >= hashsize ? 0 : scan)) {
-	if (!facet->dupridge || facet->visitid == qh visit_id)
-	  continue;
-	zinc_(Zhashtests);
-	if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
-	  ismatch= (same == (newfacet->toporient ^ facet->toporient));
-	  if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) {
-	    if (!makematch) {
-	      fprintf (qh ferr, "qhull internal error (qh_matchduplicates): missing dupridge at f%d skip %d for new f%d skip %d hash %d\n",
-		     facet->id, skip, newfacet->id, newskip, hash);
-	      qh_errexit2 (qh_ERRqhull, facet, newfacet);
-	    }
-	  }else if (ismatch && makematch) {
-	    if (SETelemt_(newfacet->neighbors, newskip, facetT) == qh_DUPLICATEridge) {
-	      SETelem_(facet->neighbors, skip)= newfacet;
-	      if (newfacet->tricoplanar)
-  		SETelem_(newfacet->neighbors, newskip)= facet;
-	      else
-		SETelem_(newfacet->neighbors, newskip)= qh_MERGEridge;
-	      *hashcount -= 2; /* removed two unmatched facets */
-	      trace4((qh ferr, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d merge\n",
-		    facet->id, skip, newfacet->id, newskip));
-	    }
-	  }else if (ismatch) {
-	    mindist= qh_getdistance (facet, newfacet, &low, &high);
-	    dist2= qh_getdistance (newfacet, facet, &low, &high);
-	    minimize_(mindist, dist2);
-	    if (mindist > maxdist) {
-	      maxdist= mindist;
-	      maxmatch= facet;
-	      maxskip= skip;
-	      maxmatch2= newfacet;
-	      maxskip2= newskip;
-	    }
-	    trace3((qh ferr, "qh_matchduplicates: duplicate f%d skip %d new f%d skip %d at dist %2.2g, max is now f%d f%d\n",
-		    facet->id, skip, newfacet->id, newskip, mindist, 
-		    maxmatch->id, maxmatch2->id));
-	  }else { /* !ismatch */
-	    nextfacet= facet;
-	    nextskip= skip;
-	  }
-	}
-	if (makematch && !facet 
-        && SETelemt_(facet->neighbors, skip, facetT) == qh_DUPLICATEridge) {
-	  fprintf (qh ferr, "qhull internal error (qh_matchduplicates): no MERGEridge match for duplicate f%d skip %d at hash %d\n",
-		     newfacet->id, newskip, hash);
-	  qh_errexit (qh_ERRqhull, newfacet, NULL);
-	}
-      }
-    } /* end of for each new facet at hash */
-    if (!makematch) {
-      if (!maxmatch) {
-	fprintf (qh ferr, "qhull internal error (qh_matchduplicates): no maximum match at duplicate f%d skip %d at hash %d\n",
-		     atfacet->id, atskip, hash);
-	qh_errexit (qh_ERRqhull, atfacet, NULL);
-      }
-      SETelem_(maxmatch->neighbors, maxskip)= maxmatch2;
-      SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch;
-      *hashcount -= 2; /* removed two unmatched facets */
-      zzinc_(Zmultiridge);
-      trace0((qh ferr, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d keep\n",
-	      maxmatch->id, maxskip, maxmatch2->id, maxskip2));
-      qh_precision ("ridge with multiple neighbors");
-      if (qh IStracing >= 4)
-	qh_errprint ("DUPLICATED/MATCH", maxmatch, maxmatch2, NULL, NULL);
-    }
-  }
-} /* matchduplicates */
-
-/*---------------------------------
-  
-  qh_nearcoplanar()
-    for all facets, remove near-inside points from facet->coplanarset
-    coplanar points defined by innerplane from qh_outerinner()
-
-  returns:
-    if qh KEEPcoplanar && !qh KEEPinside
-      facet->coplanarset only contains coplanar points
-    if qh.JOGGLEmax
-      drops inner plane by another qh.JOGGLEmax diagonal since a
-        vertex could shift out while a coplanar point shifts in
-  
-  notes:
-    used for qh.PREmerge and qh.JOGGLEmax
-    must agree with computation of qh.NEARcoplanar in qh_detroundoff()
-  design:
-    if not keeping coplanar or inside points
-      free all coplanar sets
-    else if not keeping both coplanar and inside points
-      remove !coplanar or !inside points from coplanar sets
-*/
-void qh_nearcoplanar ( void /* qh.facet_list */) {
-  facetT *facet;
-  pointT *point, **pointp;
-  int numpart;
-  realT dist, innerplane;
-
-  if (!qh KEEPcoplanar && !qh KEEPinside) {
-    FORALLfacets {
-      if (facet->coplanarset) 
-        qh_setfree( &facet->coplanarset);
-    }
-  }else if (!qh KEEPcoplanar || !qh KEEPinside) {
-    qh_outerinner (NULL, NULL, &innerplane);
-    if (qh JOGGLEmax < REALmax/2)
-      innerplane -= qh JOGGLEmax * sqrt (qh hull_dim);
-    numpart= 0;
-    FORALLfacets { 
-      if (facet->coplanarset) {
-        FOREACHpoint_(facet->coplanarset) {
-          numpart++;
-	  qh_distplane (point, facet, &dist); 
-  	  if (dist < innerplane) {
-	    if (!qh KEEPinside)
-              SETref_(point)= NULL;
-          }else if (!qh KEEPcoplanar)
-            SETref_(point)= NULL;
-        }
-	qh_setcompact (facet->coplanarset);
-      }
-    }
-    zzadd_(Zcheckpart, numpart);
-  }
-} /* nearcoplanar */
-
-/*---------------------------------
-  
-  qh_nearvertex( facet, point, bestdist )
-    return nearest vertex in facet to point
-
-  returns:
-    vertex and its distance
-    
-  notes:
-    if qh.DELAUNAY
-      distance is measured in the input set
-    searches neighboring tricoplanar facets (requires vertexneighbors)
-      Slow implementation.  Recomputes vertex set for each point.
-    The vertex set could be stored in the qh.keepcentrum facet.
-*/
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp) {
-  realT bestdist= REALmax, dist;
-  vertexT *bestvertex= NULL, *vertex, **vertexp, *apex;
-  coordT *center;
-  facetT *neighbor, **neighborp;
-  setT *vertices;
-  int dim= qh hull_dim;
-
-  if (qh DELAUNAY)
-    dim--;
-  if (facet->tricoplanar) {
-    if (!qh VERTEXneighbors || !facet->center) {
-      fprintf(qh ferr, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n");
-      qh_errexit(qh_ERRqhull, NULL, NULL);
-    }
-    vertices= qh_settemp (qh TEMPsize);
-    apex= SETfirst_(facet->vertices);
-    center= facet->center;
-    FOREACHneighbor_(apex) {
-      if (neighbor->center == center) {
-	FOREACHvertex_(neighbor->vertices) 
-	  qh_setappend(&vertices, vertex);
-      }
-    }
-  }else 
-    vertices= facet->vertices;
-  FOREACHvertex_(vertices) {
-    dist= qh_pointdist (vertex->point, point, -dim);
-    if (dist < bestdist) {
-      bestdist= dist;
-      bestvertex= vertex;
-    }
-  }
-  if (facet->tricoplanar)
-    qh_settempfree (&vertices);
-  *bestdistp= sqrt (bestdist);
-  return bestvertex;
-} /* nearvertex */
-
-/*---------------------------------
-  
-  qh_newhashtable( newsize )
-    returns size of qh.hash_table of at least newsize slots
-
-  notes:
-    assumes qh.hash_table is NULL
-    qh_HASHfactor determines the number of extra slots
-    size is not divisible by 2, 3, or 5
-*/
-int qh_newhashtable(int newsize) {
-  int size;
-
-  size= ((newsize+1)*qh_HASHfactor) | 0x1;  /* odd number */
-  while (True) { 
-    if ((size%3) && (size%5))
-      break;
-    size += 2;
-    /* loop terminates because there is an infinite number of primes */
-  }
-  qh hash_table= qh_setnew (size);
-  qh_setzero (qh hash_table, 0, size);
-  return size;
-} /* newhashtable */
-
-/*---------------------------------
-  
-  qh_newvertex( point )
-    returns a new vertex for point
-*/
-vertexT *qh_newvertex(pointT *point) {
-  vertexT *vertex;
-
-  zinc_(Ztotvertices);
-  vertex= (vertexT *)qh_memalloc(sizeof(vertexT));
-  memset ((char *) vertex, 0, sizeof (vertexT));
-  if (qh vertex_id == 0xFFFFFF) {
-    fprintf(qh ferr, "qhull input error: more than %d vertices.  ID field overflows and two vertices\n\
-may have the same identifier.  Vertices not sorted correctly.\n", 0xFFFFFF);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (qh vertex_id == qh tracevertex_id)
-    qh tracevertex= vertex;
-  vertex->id= qh vertex_id++;
-  vertex->point= point;
-  trace4((qh ferr, "qh_newvertex: vertex p%d (v%d) created\n", qh_pointid(vertex->point), 
-	  vertex->id));
-  return (vertex);
-} /* newvertex */
-
-/*---------------------------------
-  
-  qh_nextridge3d( atridge, facet, vertex )
-    return next ridge and vertex for a 3d facet
-
-  notes:
-    in qh_ORIENTclock order
-    this is a O(n^2) implementation to trace all ridges
-    be sure to stop on any 2nd visit
-  
-  design:
-    for each ridge
-      exit if it is the ridge after atridge
-*/
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) {
-  vertexT *atvertex, *vertex, *othervertex;
-  ridgeT *ridge, **ridgep;
-
-  if ((atridge->top == facet) ^ qh_ORIENTclock)
-    atvertex= SETsecondt_(atridge->vertices, vertexT);
-  else
-    atvertex= SETfirstt_(atridge->vertices, vertexT);
-  FOREACHridge_(facet->ridges) {
-    if (ridge == atridge)
-      continue;
-    if ((ridge->top == facet) ^ qh_ORIENTclock) {
-      othervertex= SETsecondt_(ridge->vertices, vertexT);
-      vertex= SETfirstt_(ridge->vertices, vertexT);
-    }else {
-      vertex= SETsecondt_(ridge->vertices, vertexT);
-      othervertex= SETfirstt_(ridge->vertices, vertexT);
-    }
-    if (vertex == atvertex) {
-      if (vertexp)
-        *vertexp= othervertex;
-      return ridge;
-    }
-  }
-  return NULL;
-} /* nextridge3d */
-#else /* qh_NOmerge */
-void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount) {
-}
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) {
-
-  return NULL;
-}
-#endif /* qh_NOmerge */
-  
-/*---------------------------------
-  
-  qh_outcoplanar()
-    move points from all facets' outsidesets to their coplanarsets
-
-  notes:
-    for post-processing under qh.NARROWhull
-
-  design:
-    for each facet
-      for each outside point for facet
-        partition point into coplanar set
-*/
-void qh_outcoplanar (void /* facet_list */) {
-  pointT *point, **pointp;
-  facetT *facet;
-  realT dist;
-
-  trace1((qh ferr, "qh_outcoplanar: move outsideset to coplanarset for qh NARROWhull\n"));
-  FORALLfacets {
-    FOREACHpoint_(facet->outsideset) {
-      qh num_outside--;
-      if (qh KEEPcoplanar || qh KEEPnearinside) {
-	qh_distplane (point, facet, &dist);
-        zinc_(Zpartition);
-	qh_partitioncoplanar (point, facet, &dist);
-      }
-    }
-    qh_setfree (&facet->outsideset);
-  }
-} /* outcoplanar */
-
-/*---------------------------------
-  
-  qh_point( id )
-    return point for a point id, or NULL if unknown
-
-  alternative code:
-    return ((pointT *)((unsigned   long)qh.first_point
-           + (unsigned long)((id)*qh.normal_size)));
-*/
-pointT *qh_point (int id) {
-
-  if (id < 0)
-    return NULL;
-  if (id < qh num_points)
-    return qh first_point + id * qh hull_dim;
-  id -= qh num_points;
-  if (id < qh_setsize (qh other_points))
-    return SETelemt_(qh other_points, id, pointT);
-  return NULL;
-} /* point */
-  
-/*---------------------------------
-  
-  qh_point_add( set, point, elem )
-    stores elem at set[point.id]
-  
-  returns:
-    access function for qh_pointfacet and qh_pointvertex
-
-  notes:
-    checks point.id
-*/
-void qh_point_add (setT *set, pointT *point, void *elem) {
-  int id, size;
-
-  SETreturnsize_(set, size);
-  if ((id= qh_pointid(point)) < 0)
-    fprintf (qh ferr, "qhull internal warning (point_add): unknown point %p id %d\n", 
-      point, id);
-  else if (id >= size) {
-    fprintf (qh ferr, "qhull internal errror (point_add): point p%d is out of bounds (%d)\n",
-	     id, size);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }else
-    SETelem_(set, id)= elem;
-} /* point_add */
-
-
-/*---------------------------------
-  
-  qh_pointfacet()
-    return temporary set of facet for each point
-    the set is indexed by point id
-
-  notes:
-    vertices assigned to one of the facets
-    coplanarset assigned to the facet
-    outside set assigned to the facet
-    NULL if no facet for point (inside)
-      includes qh.GOODpointp
-
-  access:
-    FOREACHfacet_i_(facets) { ... }
-    SETelem_(facets, i)
-  
-  design:
-    for each facet
-      add each vertex
-      add each coplanar point
-      add each outside point
-*/
-setT *qh_pointfacet (void /*qh facet_list*/) {
-  int numpoints= qh num_points + qh_setsize (qh other_points);
-  setT *facets;
-  facetT *facet;
-  vertexT *vertex, **vertexp;
-  pointT *point, **pointp;
-  
-  facets= qh_settemp (numpoints);
-  qh_setzero (facets, 0, numpoints);
-  qh vertex_visit++;
-  FORALLfacets {
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        vertex->visitid= qh vertex_visit;
-        qh_point_add (facets, vertex->point, facet);
-      }
-    }
-    FOREACHpoint_(facet->coplanarset) 
-      qh_point_add (facets, point, facet);
-    FOREACHpoint_(facet->outsideset) 
-      qh_point_add (facets, point, facet);
-  }
-  return facets;
-} /* pointfacet */
-
-/*---------------------------------
-  
-  qh_pointvertex(  )
-    return temporary set of vertices indexed by point id
-    entry is NULL if no vertex for a point
-      this will include qh.GOODpointp
-
-  access:
-    FOREACHvertex_i_(vertices) { ... }
-    SETelem_(vertices, i)
-*/
-setT *qh_pointvertex (void /*qh facet_list*/) {
-  int numpoints= qh num_points + qh_setsize (qh other_points);
-  setT *vertices;
-  vertexT *vertex;
-  
-  vertices= qh_settemp (numpoints);
-  qh_setzero (vertices, 0, numpoints);
-  FORALLvertices 
-    qh_point_add (vertices, vertex->point, vertex);
-  return vertices;
-} /* pointvertex */
-
-
-/*---------------------------------
-  
-  qh_prependfacet( facet, facetlist )
-    prepend facet to the start of a facetlist
-
-  returns:
-    increments qh.numfacets
-    updates facetlist, qh.facet_list, facet_next
-  
-  notes:
-    be careful of prepending since it can lose a pointer.
-      e.g., can lose _next by deleting and then prepending before _next
-*/
-void qh_prependfacet(facetT *facet, facetT **facetlist) {
-  facetT *prevfacet, *list;
-  
-
-  trace4((qh ferr, "qh_prependfacet: prepend f%d before f%d\n",
-	  facet->id, getid_(*facetlist)));
-  if (!*facetlist)
-    (*facetlist)= qh facet_tail;
-  list= *facetlist;
-  prevfacet= list->previous;
-  facet->previous= prevfacet;
-  if (prevfacet)
-    prevfacet->next= facet;
-  list->previous= facet;
-  facet->next= *facetlist;
-  if (qh facet_list == list)  /* this may change *facetlist */
-    qh facet_list= facet;
-  if (qh facet_next == list)
-    qh facet_next= facet;
-  *facetlist= facet;
-  qh num_facets++;
-} /* prependfacet */
-
-
-/*---------------------------------
-  
-  qh_printhashtable( fp )
-    print hash table to fp
-
-  notes:
-    not in I/O to avoid bringing io.c in
-  
-  design:
-    for each hash entry
-      if defined
-        if unmatched or will merge (NULL, qh_MERGEridge, qh_DUPLICATEridge)
-          print entry and neighbors
-*/
-void qh_printhashtable(FILE *fp) {
-  facetT *facet, *neighbor;
-  int id, facet_i, facet_n, neighbor_i= 0, neighbor_n= 0;
-  vertexT *vertex, **vertexp;
-
-  FOREACHfacet_i_(qh hash_table) {
-    if (facet) {
-      FOREACHneighbor_i_(facet) {
-        if (!neighbor || neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) 
-          break;
-      }
-      if (neighbor_i == neighbor_n)
-        continue;
-      fprintf (fp, "hash %d f%d ", facet_i, facet->id);
-      FOREACHvertex_(facet->vertices)
-        fprintf (fp, "v%d ", vertex->id);
-      fprintf (fp, "\n neighbors:");
-      FOREACHneighbor_i_(facet) {
-	if (neighbor == qh_MERGEridge)
-	  id= -3;
-	else if (neighbor == qh_DUPLICATEridge)
-	  id= -2;
-	else
-	  id= getid_(neighbor);
-        fprintf (fp, " %d", id);
-      }
-      fprintf (fp, "\n");
-    }
-  }
-} /* printhashtable */
-     
-
-/*---------------------------------
-  
-  qh_printlists( fp )
-    print out facet and vertex list for debugging (without 'f/v' tags)
-*/
-void qh_printlists (void) {
-  facetT *facet;
-  vertexT *vertex;
-  int count= 0;
-  
-  fprintf (qh ferr, "qh_printlists: facets:");
-  FORALLfacets {
-    if (++count % 100 == 0)
-      fprintf (qh ferr, "\n     ");
-    fprintf (qh ferr, " %d", facet->id);
-  }
-  fprintf (qh ferr, "\n  new facets %d visible facets %d next facet for qh_addpoint %d\n  vertices (new %d):",
-     getid_(qh newfacet_list), getid_(qh visible_list), getid_(qh facet_next),
-     getid_(qh newvertex_list));
-  count = 0;
-  FORALLvertices {
-    if (++count % 100 == 0)
-      fprintf (qh ferr, "\n     ");
-    fprintf (qh ferr, " %d", vertex->id);
-  }
-  fprintf (qh ferr, "\n");
-} /* printlists */
-  
-/*---------------------------------
-  
-  qh_resetlists( stats, qh_RESETvisible )
-    reset newvertex_list, newfacet_list, visible_list
-    if stats, 
-      maintains statistics
-
-  returns:
-    visible_list is empty if qh_deletevisible was called
-*/
-void qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/) {
-  vertexT *vertex;
-  facetT *newfacet, *visible;
-  int totnew=0, totver=0;
-  
-  if (stats) {
-    FORALLvertex_(qh newvertex_list)
-      totver++;
-    FORALLnew_facets 
-      totnew++;
-    zadd_(Zvisvertextot, totver);
-    zmax_(Zvisvertexmax, totver);
-    zadd_(Znewfacettot, totnew);
-    zmax_(Znewfacetmax, totnew);
-  }
-  FORALLvertex_(qh newvertex_list)
-    vertex->newlist= False;
-  qh newvertex_list= NULL;
-  FORALLnew_facets
-    newfacet->newfacet= False;
-  qh newfacet_list= NULL;
-  if (resetVisible) {
-    FORALLvisible_facets {
-      visible->f.replace= NULL;
-      visible->visible= False;
-    }
-    qh num_visible= 0;
-  }
-  qh visible_list= NULL; /* may still have visible facets via qh_triangulate */
-  qh NEWfacets= False;
-} /* resetlists */
-
-/*---------------------------------
-  
-  qh_setvoronoi_all()
-    compute Voronoi centers for all facets
-    includes upperDelaunay facets if qh.UPPERdelaunay ('Qu')
-
-  returns:
-    facet->center is the Voronoi center
-    
-  notes:
-    this is unused/untested code
-      please email bradb@shore.net if this works ok for you
-  
-  use:
-    FORALLvertices {...} to locate the vertex for a point.  
-    FOREACHneighbor_(vertex) {...} to visit the Voronoi centers for a Voronoi cell.
-*/
-void qh_setvoronoi_all (void) {
-  facetT *facet;
-
-  qh_clearcenters (qh_ASvoronoi);
-  qh_vertexneighbors();
-  
-  FORALLfacets {
-    if (!facet->normal || !facet->upperdelaunay || qh UPPERdelaunay) {
-      if (!facet->center)
-        facet->center= qh_facetcenter (facet->vertices);
-    }
-  }
-} /* setvoronoi_all */
-
-#ifndef qh_NOmerge
-
-/*---------------------------------
-  
-  qh_triangulate()
-    triangulate non-simplicial facets on qh.facet_list, 
-    if qh.CENTERtype=qh_ASvoronoi, sets Voronoi centers of non-simplicial facets
-
-  returns:
-    all facets simplicial
-    each tricoplanar facet has ->f.triowner == owner of ->center,normal,etc.
-
-  notes:
-    call after qh_check_output since may switch to Voronoi centers
-    Output may overwrite ->f.triowner with ->f.area
-*/
-void qh_triangulate (void /*qh facet_list*/) {
-  facetT *facet, *nextfacet, *owner;
-  int onlygood= qh ONLYgood;
-  facetT *neighbor, *visible= NULL, *facet1, *facet2, *new_facet_list= NULL;
-  facetT *orig_neighbor= NULL, *otherfacet;
-  vertexT *new_vertex_list= NULL;
-  mergeT *merge; 
-  mergeType mergetype;
-  int neighbor_i, neighbor_n;
-
-  trace1((qh ferr, "qh_triangulate: triangulate non-simplicial facets\n"));
-  if (qh hull_dim == 2)
-    return;
-  if (qh VORONOI) {  /* otherwise lose Voronoi centers [could rebuild vertex set from tricoplanar] */
-    qh_clearcenters (qh_ASvoronoi);
-    qh_vertexneighbors();
-  }
-  qh ONLYgood= False; /* for makenew_nonsimplicial */
-  qh visit_id++;
-  qh NEWfacets= True;
-  qh degen_mergeset= qh_settemp (qh TEMPsize);
-  qh newvertex_list= qh vertex_tail;
-  for (facet= qh facet_list; facet && facet->next; facet= nextfacet) { /* non-simplicial facets moved to end */
-    nextfacet= facet->next;
-    if (facet->visible || facet->simplicial)
-      continue;
-    /* triangulate all non-simplicial facets, otherwise merging does not work, e.g., RBOX c P-0.1 P+0.1 P+0.1 D3 | QHULL d Qt Tv */
-    if (!new_facet_list)
-      new_facet_list= facet;  /* will be moved to end */
-    qh_triangulate_facet (facet, &new_vertex_list);
-  }
-  trace2((qh ferr, "qh_triangulate: delete null facets from f%d -- apex same as second vertex\n", getid_(new_facet_list)));
-  for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* null facets moved to end */
-    nextfacet= facet->next;
-    if (facet->visible) 
-      continue;
-    if (facet->ridges) {
-      if (qh_setsize(facet->ridges) > 0) {
-	fprintf( qh ferr, "qhull error (qh_triangulate): ridges still defined for f%d\n", facet->id);
-	qh_errexit (qh_ERRqhull, facet, NULL);
-      }
-      qh_setfree (&facet->ridges);
-    }
-    if (SETfirst_(facet->vertices) == SETsecond_(facet->vertices)) {
-      zinc_(Ztrinull);
-      qh_triangulate_null (facet);
-    }
-  }
-  trace2((qh ferr, "qh_triangulate: delete %d or more mirror facets -- same vertices and neighbors\n", qh_setsize(qh degen_mergeset)));
-  qh visible_list= qh facet_tail;
-  while ((merge= (mergeT*)qh_setdellast (qh degen_mergeset))) {
-    facet1= merge->facet1;
-    facet2= merge->facet2;
-    mergetype= merge->type;
-    qh_memfree (merge, sizeof(mergeT));
-    if (mergetype == MRGmirror) {
-      zinc_(Ztrimirror);
-      qh_triangulate_mirror (facet1, facet2);
-    }
-  }
-  qh_settempfree(&qh degen_mergeset);
-  trace2((qh ferr, "qh_triangulate: update neighbor lists for vertices from v%d\n", getid_(new_vertex_list)));
-  qh newvertex_list= new_vertex_list;  /* all vertices of new facets */
-  qh visible_list= NULL;
-  qh_updatevertices(/*qh newvertex_list, empty newfacet_list and visible_list*/);
-  qh_resetlists (False, !qh_RESETvisible /*qh newvertex_list, empty newfacet_list and visible_list*/);
-
-  trace2((qh ferr, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list)));
-  trace2((qh ferr, "qh_triangulate: and replace facet->f.triowner with tricoplanar facets that own center, normal, etc.\n"));
-  FORALLfacet_(new_facet_list) {
-    if (facet->tricoplanar && !facet->visible) {
-      FOREACHneighbor_i_(facet) {
-	if (neighbor_i == 0) {  /* first iteration */
-	  if (neighbor->tricoplanar)
-            orig_neighbor= neighbor->f.triowner;
-	  else
-	    orig_neighbor= neighbor;
-	}else {
-	  if (neighbor->tricoplanar)
-  	    otherfacet= neighbor->f.triowner;
-	  else
-	    otherfacet= neighbor;
-	  if (orig_neighbor == otherfacet) {
-	    zinc_(Ztridegen);
-	    facet->degenerate= True;
-	    break;
-	  }
-	}
-      }
-    }
-  }
-
-  trace2((qh ferr, "qh_triangulate: delete visible facets -- non-simplicial, null, and mirrored facets\n"));
-  owner= NULL;
-  visible= NULL;
-  for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* may delete facet */
-    nextfacet= facet->next;
-    if (facet->visible) {
-      if (facet->tricoplanar) { /* a null or mirrored facet */
-	qh_delfacet(facet);
-	qh num_visible--;
-      }else {  /* a non-simplicial facet followed by its tricoplanars */
-	if (visible && !owner) {
-	  /*  RBOX 200 s D5 t1001471447 | QHULL Qt C-0.01 Qx Qc Tv Qt -- f4483 had 6 vertices/neighbors and 8 ridges */
-	  trace2((qh ferr, "qh_triangulate: all tricoplanar facets degenerate for non-simplicial facet f%d\n",
-		       visible->id));
-	  qh_delfacet(visible);
-	  qh num_visible--;
-	}
-	visible= facet;
-	owner= NULL;
-      }
-    }else if (facet->tricoplanar) {
-      if (facet->f.triowner != visible) { 
-	fprintf( qh ferr, "qhull error (qh_triangulate): tricoplanar facet f%d not owned by its visible, non-simplicial facet f%d\n", facet->id, getid_(visible));
-	qh_errexit2 (qh_ERRqhull, facet, visible);
-      }
-      if (owner) 
-	facet->f.triowner= owner;
-      else if (!facet->degenerate) {
-	owner= facet;
-	nextfacet= visible->next; /* rescan tricoplanar facets with owner */
-	facet->keepcentrum= True;  /* one facet owns ->normal, etc. */
-	facet->coplanarset= visible->coplanarset;
-	facet->outsideset= visible->outsideset;
-  	visible->coplanarset= NULL;
-	visible->outsideset= NULL;
-        if (!qh TRInormals) { /* center and normal copied to tricoplanar facets */
-	  visible->center= NULL;
-	  visible->normal= NULL;
-	}
-	qh_delfacet(visible);
-	qh num_visible--;
-      }
-    }
-  }
-  if (visible && !owner) {
-    trace2((qh ferr, "qh_triangulate: all tricoplanar facets degenerate for last non-simplicial facet f%d\n",
-	         visible->id));
-    qh_delfacet(visible);
-    qh num_visible--;
-  }
-  qh NEWfacets= False;
-  qh ONLYgood= onlygood; /* restore value */
-  if (qh CHECKfrequently) 
-    qh_checkpolygon (qh facet_list);
-} /* triangulate */
-
-
-/*---------------------------------
-  
-  qh_triangulate_facet (facetA)
-    triangulate a non-simplicial facet
-      if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center
-  returns:
-    qh.newfacet_list == simplicial facets
-      facet->tricoplanar set and ->keepcentrum false
-      facet->degenerate set if duplicated apex
-      facet->f.trivisible set to facetA
-      facet->center copied from facetA (created if qh_ASvoronoi)
-	qh_eachvoronoi, qh_detvridge, qh_detvridge3 assume centers copied
-      facet->normal,offset,maxoutside copied from facetA
-
-  notes:
-      qh_makenew_nonsimplicial uses neighbor->seen for the same
-
-  see also:
-      qh_addpoint() -- add a point
-      qh_makenewfacets() -- construct a cone of facets for a new vertex
-
-  design:
-      if qh_ASvoronoi, 
-	 compute Voronoi center (facet->center)
-      select first vertex (highest ID to preserve ID ordering of ->vertices)
-      triangulate from vertex to ridges
-      copy facet->center, normal, offset
-      update vertex neighbors
-*/
-void qh_triangulate_facet (facetT *facetA, vertexT **first_vertex) {
-  facetT *newfacet;
-  facetT *neighbor, **neighborp;
-  vertexT *apex;
-  int numnew=0;
-
-  trace3((qh ferr, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id));
-
-  if (qh IStracing >= 4)
-    qh_printfacet (qh ferr, facetA);
-  FOREACHneighbor_(facetA) {
-    neighbor->seen= False;
-    neighbor->coplanar= False;
-  }
-  if (qh CENTERtype == qh_ASvoronoi && !facetA->center  /* matches upperdelaunay in qh_setfacetplane() */
-        && fabs_(facetA->normal[qh hull_dim -1]) >= qh ANGLEround * qh_ZEROdelaunay) {
-    facetA->center= qh_facetcenter (facetA->vertices);
-  }
-  qh_willdelete (facetA, NULL);
-  qh newfacet_list= qh facet_tail;
-  facetA->visitid= qh visit_id;
-  apex= SETfirst_(facetA->vertices);
-  qh_makenew_nonsimplicial (facetA, apex, &numnew);
-  SETfirst_(facetA->neighbors)= NULL;
-  FORALLnew_facets {
-    newfacet->tricoplanar= True;
-    newfacet->f.trivisible= facetA;
-    newfacet->degenerate= False;
-    newfacet->upperdelaunay= facetA->upperdelaunay;
-    newfacet->good= facetA->good;
-    if (qh TRInormals) { 
-      newfacet->keepcentrum= True;
-      newfacet->normal= qh_copypoints (facetA->normal, 1, qh hull_dim);
-      if (qh CENTERtype == qh_AScentrum) 
-	newfacet->center= qh_getcentrum (newfacet);
-      else
-	newfacet->center= qh_copypoints (facetA->center, 1, qh hull_dim);
-    }else {
-      newfacet->keepcentrum= False;
-      newfacet->normal= facetA->normal;
-      newfacet->center= facetA->center;
-    }
-    newfacet->offset= facetA->offset;
-#if qh_MAXoutside
-    newfacet->maxoutside= facetA->maxoutside;
-#endif
-  }
-  qh_matchnewfacets(/*qh newfacet_list*/);
-  zinc_(Ztricoplanar);
-  zadd_(Ztricoplanartot, numnew);
-  zmax_(Ztricoplanarmax, numnew);
-  qh visible_list= NULL;
-  if (!(*first_vertex))
-    (*first_vertex)= qh newvertex_list;
-  qh newvertex_list= NULL;
-  qh_updatevertices(/*qh newfacet_list, empty visible_list and newvertex_list*/);
-  qh_resetlists (False, !qh_RESETvisible /*qh newfacet_list, empty visible_list and newvertex_list*/);
-} /* triangulate_facet */
-
-/*---------------------------------
-  
-  qh_triangulate_link (oldfacetA, facetA, oldfacetB, facetB)
-    relink facetA to facetB via oldfacets
-  returns:
-    adds mirror facets to qh degen_mergeset (4-d and up only)
-  design:
-    if they are already neighbors, the opposing neighbors become MRGmirror facets
-*/
-void qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB) {
-  int errmirror= False;
-
-  trace3((qh ferr, "qh_triangulate_link: relink old facets f%d and f%d between neighbors f%d and f%d\n", 
-         oldfacetA->id, oldfacetB->id, facetA->id, facetB->id));
-  if (qh_setin (facetA->neighbors, facetB)) {
-    if (!qh_setin (facetB->neighbors, facetA)) 
-      errmirror= True;
-    else
-      qh_appendmergeset (facetA, facetB, MRGmirror, NULL);
-  }else if (qh_setin (facetB->neighbors, facetA)) 
-    errmirror= True;
-  if (errmirror) {
-    fprintf( qh ferr, "qhull error (qh_triangulate_link): mirror facets f%d and f%d do not match for old facets f%d and f%d\n",
-       facetA->id, facetB->id, oldfacetA->id, oldfacetB->id);
-    qh_errexit2 (qh_ERRqhull, facetA, facetB);
-  }
-  qh_setreplace (facetB->neighbors, oldfacetB, facetA);
-  qh_setreplace (facetA->neighbors, oldfacetA, facetB);
-} /* triangulate_link */
-
-/*---------------------------------
-  
-  qh_triangulate_mirror (facetA, facetB)
-    delete mirrored facets from qh_triangulate_null() and qh_triangulate_mirror
-      a mirrored facet shares the same vertices of a logical ridge
-  design:
-    since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
-    if they are already neighbors, the opposing neighbors become MRGmirror facets
-*/
-void qh_triangulate_mirror (facetT *facetA, facetT *facetB) {
-  facetT *neighbor, *neighborB;
-  int neighbor_i, neighbor_n;
-
-  trace3((qh ferr, "qh_triangulate_mirror: delete mirrored facets f%d and f%d\n", 
-         facetA->id, facetB->id));
-  FOREACHneighbor_i_(facetA) {
-    neighborB= SETelemt_(facetB->neighbors, neighbor_i, facetT);
-    if (neighbor == neighborB)
-      continue; /* occurs twice */
-    qh_triangulate_link (facetA, neighbor, facetB, neighborB);
-  }
-  qh_willdelete (facetA, NULL);
-  qh_willdelete (facetB, NULL);
-} /* triangulate_mirror */
-
-/*---------------------------------
-  
-  qh_triangulate_null (facetA)
-    remove null facetA from qh_triangulate_facet()
-      a null facet has vertex #1 (apex) == vertex #2
-  returns:
-    adds facetA to ->visible for deletion after qh_updatevertices
-    qh degen_mergeset contains mirror facets (4-d and up only)
-  design:
-    since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
-    if they are already neighbors, the opposing neighbors become MRGmirror facets
-*/
-void qh_triangulate_null (facetT *facetA) {
-  facetT *neighbor, *otherfacet;
-
-  trace3((qh ferr, "qh_triangulate_null: delete null facet f%d\n", facetA->id));
-  neighbor= SETfirst_(facetA->neighbors);
-  otherfacet= SETsecond_(facetA->neighbors);
-  qh_triangulate_link (facetA, neighbor, facetA, otherfacet);
-  qh_willdelete (facetA, NULL);
-} /* triangulate_null */
-
-#else /* qh_NOmerge */
-void qh_triangulate (void) {
-}
-#endif /* qh_NOmerge */
-
-   /*---------------------------------
-  
-  qh_vertexintersect( vertexsetA, vertexsetB )
-    intersects two vertex sets (inverse id ordered)
-    vertexsetA is a temporary set at the top of qhmem.tempstack
-
-  returns:
-    replaces vertexsetA with the intersection
-  
-  notes:
-    could overwrite vertexsetA if currently too slow
-*/
-void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB) {
-  setT *intersection;
-
-  intersection= qh_vertexintersect_new (*vertexsetA, vertexsetB);
-  qh_settempfree (vertexsetA);
-  *vertexsetA= intersection;
-  qh_settemppush (intersection);
-} /* vertexintersect */
-
-/*---------------------------------
-  
-  qh_vertexintersect_new(  )
-    intersects two vertex sets (inverse id ordered)
-
-  returns:
-    a new set
-*/
-setT *qh_vertexintersect_new (setT *vertexsetA,setT *vertexsetB) {
-  setT *intersection= qh_setnew (qh hull_dim - 1);
-  vertexT **vertexA= SETaddr_(vertexsetA, vertexT); 
-  vertexT **vertexB= SETaddr_(vertexsetB, vertexT); 
-
-  while (*vertexA && *vertexB) {
-    if (*vertexA  == *vertexB) {
-      qh_setappend(&intersection, *vertexA);
-      vertexA++; vertexB++;
-    }else {
-      if ((*vertexA)->id > (*vertexB)->id)
-        vertexA++;
-      else
-        vertexB++;
-    }
-  }
-  return intersection;
-} /* vertexintersect_new */
-
-/*---------------------------------
-  
-  qh_vertexneighbors()
-    for each vertex in qh.facet_list, 
-      determine its neighboring facets 
-
-  returns:
-    sets qh.VERTEXneighbors
-      nop if qh.VERTEXneighbors already set
-      qh_addpoint() will maintain them
-
-  notes:
-    assumes all vertex->neighbors are NULL
-
-  design:
-    for each facet
-      for each vertex
-        append facet to vertex->neighbors
-*/
-void qh_vertexneighbors (void /*qh facet_list*/) {
-  facetT *facet;
-  vertexT *vertex, **vertexp;
-
-  if (qh VERTEXneighbors)
-    return;
-  trace1((qh ferr, "qh_vertexneighbors: determing neighboring facets for each vertex\n"));
-  qh vertex_visit++;
-  FORALLfacets {
-    if (facet->visible)
-      continue;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        vertex->visitid= qh vertex_visit;
-        vertex->neighbors= qh_setnew (qh hull_dim);
-      }
-      qh_setappend (&vertex->neighbors, facet);
-    }
-  }
-  qh VERTEXneighbors= True;
-} /* vertexneighbors */
-
-/*---------------------------------
-  
-  qh_vertexsubset( vertexsetA, vertexsetB )
-    returns True if vertexsetA is a subset of vertexsetB
-    assumes vertexsets are sorted
-
-  note:    
-    empty set is a subset of any other set
-*/
-boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB) {
-  vertexT **vertexA= (vertexT **) SETaddr_(vertexsetA, vertexT);
-  vertexT **vertexB= (vertexT **) SETaddr_(vertexsetB, vertexT);
-
-  while (True) {
-    if (!*vertexA)
-      return True;
-    if (!*vertexB)
-      return False;
-    if ((*vertexA)->id > (*vertexB)->id)
-      return False;
-    if (*vertexA  == *vertexB)
-      vertexA++;
-    vertexB++; 
-  }
-  return False; /* avoid warnings */
-} /* vertexsubset */
diff --git a/extern/qhull/src/qconvex.c b/extern/qhull/src/qconvex.c
deleted file mode 100644
index 67b78646e50..00000000000
--- a/extern/qhull/src/qconvex.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
  ---------------------------------
-
-   qconvex.c
-      compute convex hulls using qhull
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt
-    long prompt for qconvex
-    
-  notes:
-    restricted version of qhull.c
-
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qconvex.htm */
-char hidden_options[]=" d v H Qbb Qf Qg Qm Qr Qu Qv Qx Qz TR E V Fp Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-	       
-char qh_prompta[]= "\n\
-qconvex- compute the convex hull\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Qc   - keep coplanar points with nearest facet\n\
-    Qi   - keep interior points with nearest facet\n\
-\n\
-Qhull control options:\n\
-    Qbk:n   - scale coord k so that low bound is n\n\
-      QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
-    QbB  - scale input to unit cube centered at the origin\n\
-    Qbk:0Bk:0 - remove k-th coordinate from input\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-    QRn  - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qs   - search all points for the initial simplex\n\
-    QGn  - good facet if visible from point n, -n for not visible\n\
-    QVn  - good facet if it includes point n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Un   - max distance below plane for a new, coplanar point\n\
-    Wn   - min facet width for outside point (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (see below)\n\
-    i    - vertices incident to each facet\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    n    - normals with offsets\n\
-    o    - OFF file format (dim, points and facets; Voronoi regions)\n\
-    p    - point coordinates \n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fa   - area for each facet\n\
-    FA   - compute total area and volume for option 's'\n\
-    Fc   - count plus coplanar points for each facet\n\
-           use 'Qc' (default) for coplanar and 'Qi' for interior\n\
-    FC   - centrum for each facet\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for numeric output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    Fi   - inner plane for each facet\n\
-    FI   - ID for each facet\n\
-    Fm   - merge count for each facet (511 max)\n\
-    Fn   - count plus neighboring facets for each facet\n\
-    FN   - count plus neighboring facets for each point\n\
-    Fo   - outer plane (or max_outside) for each facet\n\
-    FO   - options and precision constants\n\
-    FP   - nearest vertex for each coplanar point\n\
-    FQ   - command used for qconvex\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                      for output: #vertices, #facets,\n\
-                                  #coplanar points, #non-simplicial facets\n\
-                    #real (2), max outer plane, min vertex\n\
-    FS   - sizes:   #int (0) \n\
-                    #real(2) tot area, tot volume\n\
-    Ft   - triangulation with centrums for non-simplicial facets (OFF format)\n\
-    Fv   - count plus vertices for each facet\n\
-    FV   - average of vertices (a feasible point for 'H')\n\
-    Fx   - extreme points (in order for 2-d)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview output (2-d, 3-d, and 4-d)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc   - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest facets by area\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good facets (needs 'QGn' or 'QVn')\n\
-    PFn  - keep facets whose area is at least n\n\
-    PG   - print neighbors of good facets\n\
-    PMn  - keep n facets with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qconvex- compute the convex hull.  Qhull %s\n\
-    input (stdin): dimension, number of points, point coordinates\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qconvex.htm):\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    i    - vertices incident to each facet\n\
-    n    - normals with offsets\n\
-    p    - vertex coordinates (includes coplanar points if 'Qc')\n\
-    Fx   - extreme points (convex hull vertices)\n\
-    FA   - compute total area and volume\n\
-    o    - OFF format (dim, n, points, facets)\n\
-    G    - Geomview output (2-d, 3-d, and 4-d)\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    QVn  - print facets that include point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox c D2 | qconvex s n                    rbox c D2 | qconvex i\n\
-    rbox c D2 | qconvex o                      rbox 1000 s | qconvex s Tv FA\n\
-    rbox c d D2 | qconvex s Qc Fx              rbox y 1000 W0 | qconvex s n\n\
-    rbox y 1000 W0 | qconvex s QJ              rbox d G1 D12 | qconvex QR0 FA Pp\n\
-    rbox c D7 | qconvex FA TF1000\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- incidences     mathematica    normals        OFF_format     points\n\
- summary        facet_dump\n\
-\n\
- Farea          FArea_total    Fcoplanars     FCentrums      Fd_cdd_in\n\
- FD_cdd_out     FFacet_xridge  Finner         FIDs           Fmerges\n\
- Fneighbors     FNeigh_vertex  Fouter         FOptions       FPoint_near\n\
- FQhull         Fsummary       FSize          Fvertices      FVertex_ave\n\
- Fxtremes\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
-\n\
- PArea_keep     Pdrop d0:0D0   PFacet_area_keep Pgood        PGood_neighbors\n\
- PMerge_keep    Poutput_forced Pprecision_not\n\
-\n\
- QbBound 0:0.5  QbB_scale_box  Qcoplanar      QGood_point    Qinterior\n\
- QJoggle        Qrandom        QRotate        Qsearch_1st    Qtriangulate\n\
- QVertex_good\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Ucoplanar_max  Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION, qh_DEFAULTbox, 
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("Qxact_merge", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/qdelaun.c b/extern/qhull/src/qdelaun.c
deleted file mode 100644
index 0e49d9c381e..00000000000
--- a/extern/qhull/src/qdelaun.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
  ---------------------------------
-
-   qdelaun.c
-     compute Delaunay triangulations and furthest-point Delaunay
-     triangulations using qhull
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  notes:
-    restricted version of qhull.c
- 
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qdelau_f.htm and qdelaun.htm */
-char hidden_options[]=" d n v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V FC Fi Fo Ft Fp FV Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-
-char qh_prompta[]= "\n\
-qdelaunay- compute the Delaunay triangulation\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Qu   - compute furthest-site Delaunay triangulation\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-\n\
-Qhull control options:\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qs   - search all points for the initial simplex\n\
-    Qz   - add point-at-infinity to Delaunay triangulation\n\
-    QGn  - print Delaunay region if visible from point n, -n if not\n\
-    QVn  - print Delaunay regions that include point n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Wn   - min facet width for outside point (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (see below)\n\
-    i    - vertices incident to each Delaunay region\n\
-    m    - Mathematica output (2-d only, lifted to a paraboloid)\n\
-    o    - OFF format (dim, points, and facets as a paraboloid)\n\
-    p    - point coordinates (lifted to a paraboloid)\n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fa   - area for each Delaunay region\n\
-    FA   - compute total area for option 's'\n\
-    Fc   - count plus coincident points for each Delaunay region\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for numeric output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    FI   - ID of each Delaunay region\n\
-    Fm   - merge count for each Delaunay region (511 max)\n\
-    Fn   - count plus neighboring region for each Delaunay region\n\
-    FN   - count plus neighboring region for each point\n\
-    FO   - options and precision constants\n\
-    FP   - nearest point and distance for each coincident point\n\
-    FQ   - command used for qdelaunay\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                    for output: #vertices, #Delaunay regions,\n\
-                                #coincident points, #non-simplicial regions\n\
-                    #real (2), max outer plane, min vertex\n\
-    FS   - sizes:   #int (0)\n\
-                    #real(2) tot area, 0\n\
-    Fv   - count plus vertices for each Delaunay region\n\
-    Fx   - extreme points of Delaunay triangulation (on convex hull)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview options (2-d and 3-d)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc	   - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-    Gt   - transparent outer ridges to view 3-d Delaunay\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest Delaunay regions by area\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good Delaunay regions (needs 'QGn' or 'QVn')\n\
-    PFn  - keep Delaunay regions whose area is at least n\n\
-    PG   - print neighbors of good regions (needs 'QGn' or 'QVn')\n\
-    PMn  - keep n Delaunay regions with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qdelaunay- compute the Delaunay triangulation. Qhull %s\n\
-    input (stdin): dimension, number of points, point coordinates\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qdelaun.htm):\n\
-    Qu   - furthest-site Delaunay triangulation\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    i    - vertices incident to each Delaunay region\n\
-    Fx   - extreme points (vertices of the convex hull)\n\
-    o    - OFF format (shows the points lifted to a paraboloid)\n\
-    G    - Geomview output (2-d and 3-d points lifted to a paraboloid)\n\
-    m    - Mathematica output (2-d inputs lifted to a paraboloid)\n\
-    QVn  - print Delaunay regions that include point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox c P0 D2 | qdelaunay s o          rbox c P0 D2 | qdelaunay i\n\
-    rbox c P0 D2 | qdelaunay Fv           rbox c P0 D2 | qdelaunay s Qu Fv\n\
-    rbox c G1 d D2 | qdelaunay s i        rbox c G1 d D2 | qdelaunay Qt\n\
-    rbox M3,4 z 100 D2 | qdelaunay s      rbox M3,4 z 100 D2 | qdelaunay s Qt\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- incidences     mathematica    OFF_format     points_lifted  summary\n\
- facet_dump\n\
-\n\
- Farea          FArea_total    Fcoincident    Fd_cdd_in      FD_cdd_out\n\
- FF_dump_xridge FIDs           Fmerges        Fneighbors     FNeigh_vertex\n\
- FOptions       FPoint_near    FQdelaun       Fsummary       FSize\n\
- Fvertices      Fxtremes\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
- Gtransparent\n\
-\n\
- PArea_keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge_keep   Poutput_forced Pprecision_not\n\
-\n\
- QGood_point    QJoggle        Qsearch_1st    Qtriangulate   QupperDelaunay\n\
- QVertex_good   Qzinfinite\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION,  
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_option ("delaunay  Qbbound-last", NULL, NULL);
-    qh DELAUNAY= True;     /* 'd'   */
-    qh SCALElast= True;    /* 'Qbb' */
-    qh KEEPcoplanar= True; /* 'Qc', to keep coplanars in 'p' */
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("Qxact_merge", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/qhalf.c b/extern/qhull/src/qhalf.c
deleted file mode 100644
index a2b3875dd7f..00000000000
--- a/extern/qhull/src/qhalf.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
  ---------------------------------
-
-   qhalf.c
-     compute the intersection of halfspaces about a point
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  notes:
-    restricted version of qhull.c
- 
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qhalf.htm */
-char hidden_options[]=" d n v Qbb QbB Qf Qg Qm Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-
-char qh_prompta[]= "\n\
-qhalf- compute the intersection of halfspaces about a point\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    optional interior point: dimension, 1, coordinates\n\
-    first lines: dimension+1 and number of halfspaces\n\
-    other lines: halfspace coefficients followed by offset\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Hn,n - specify coordinates of interior point\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Qc   - keep coplanar halfspaces\n\
-    Qi   - keep other redundant halfspaces\n\
-\n\
-Qhull control options:\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qbk:0Bk:0 - remove k-th coordinate from input\n\
-    Qs   - search all halfspaces for the initial simplex\n\
-    QGn  - print intersection if visible to halfspace n, -n for not\n\
-    QVn  - print intersections for halfspace n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and redundancy\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when halfspace n added to intersection\n\
-    TMn  - turn on tracing at merge n\n\
-    TWn  - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding halfspace n, -n for before (see TCn)\n\
-    TCn  - stop qhull after building cone for halfspace n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Un   - max distance below plane for a new, coplanar halfspace\n\
-    Wn   - min facet width for outside halfspace (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (dual convex hull)\n\
-    i    - non-redundant halfspaces incident to each intersection\n\
-    m    - Mathematica output (dual convex hull)\n\
-    o    - OFF format (dual convex hull: dimension, points, and facets)\n\
-    p    - vertex coordinates of dual convex hull (coplanars if 'Qc' or 'Qi')\n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fc   - count plus redundant halfspaces for each intersection\n\
-         -   Qc (default) for coplanar and Qi for other redundant\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FF   - facet dump without ridges\n\
-    FI   - ID of each intersection\n\
-    Fm   - merge count for each intersection (511 max)\n\
-    Fn   - count plus neighboring intersections for each intersection\n\
-    FN   - count plus intersections for each non-redundant halfspace\n\
-    FO   - options and precision constants\n\
-    Fp   - dim, count, and intersection coordinates\n\
-    FP   - nearest halfspace and distance for each redundant halfspace\n\
-    FQ   - command used for qhalf\n\
-    Fs   - summary: #int (8), dim, #halfspaces, #non-redundant, #intersections\n\
-                      for output: #non-redundant, #intersections, #coplanar\n\
-                                  halfspaces, #non-simplicial intersections\n\
-                    #real (2), max outer plane, min vertex\n\
-    Fv   - count plus non-redundant halfspaces for each intersection\n\
-    Fx   - non-redundant halfspaces\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview output (2-d, 3-d and 4-d; dual convex hull)\n\
-    Ga   - all points (i.e., transformed halfspaces) as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices (i.e., non-redundant halfspaces) as spheres\n\
-    Gi   - inner planes (i.e., halfspace intersections) only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc	 - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest facets (i.e., intersections) by area\n\
-    Pdk:n- drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n- drop facet if normal[k] >= n\n\
-    Pg   - print good facets (needs 'QGn' or 'QVn')\n\
-    PFn  - keep facets whose area is at least n\n\
-    PG   - print neighbors of good facets\n\
-    PMn  - keep n facets with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qhalf- halfspace intersection about a point. Qhull %s\n\
-    input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qhalf.htm):\n\
-    Hn,n - specify coordinates of interior point\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and redundancy\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    Fp   - intersection coordinates\n\
-    Fv   - non-redundant halfspaces incident to each intersection\n\
-    Fx   - non-redundant halfspaces\n\
-    o    - OFF file format (dual convex hull)\n\
-    G    - Geomview output (dual convex hull)\n\
-    m    - Mathematica output (dual convex hull)\n\
-    QVn  - print intersections for halfspace n, -n if not\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox d | qconvex FQ n | qhalf s H0,0,0 Fp\n\
-    rbox c | qconvex FQ FV n | qhalf s i\n\
-    rbox c | qconvex FQ FV n | qhalf s o\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper_case options take an argument.\n\
-\n\
- incidences     Geomview       mathematica    OFF_format     point_dual\n\
- summary        facet_dump\n\
-\n\
- Fc_redundant   Fd_cdd_in      FF_dump_xridge FIDs           Fmerges\n\
- Fneighbors     FN_intersect   FOptions       Fp_coordinates FP_nearest\n\
- FQhalf         Fsummary       Fv_halfspace   Fx_non_redundant\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
-\n\
- PArea_keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge_keep   Poutput_forced Pprecision_not\n\
-\n\
- Qbk:0Bk:0_drop Qcoplanar      QG_half_good   Qi_redundant   QJoggle\n\
- Qsearch_1st    Qtriangulate   QVertex_good\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Ucoplanar_max  Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION, 
-        qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_option ("Halfspace", NULL, NULL);
-    qh HALFspace= True;    /* 'H'   */
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    if (qh SCALEinput) {
-      fprintf(qh ferr, "\
-qhull error: options 'Qbk:n' and 'QBk:n' are not used with qhalf.\n\
-             Use 'Qbk:0Bk:0 to drop dimension k.\n");
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("Qxact_merge", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/qhull.c b/extern/qhull/src/qhull.c
deleted file mode 100644
index dc835bb4f28..00000000000
--- a/extern/qhull/src/qhull.c
+++ /dev/null
@@ -1,1395 +0,0 @@
-/*
  ---------------------------------
-
-   qhull.c
-   Quickhull algorithm for convex hulls
-
-   qhull() and top-level routines
-
-   see qh-qhull.htm, qhull.h, unix.c
-
-   see qhull_a.h for internal functions
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include "qhull_a.h" 
-
-/*============= functions in alphabetic order after qhull() =======*/
-
-/*---------------------------------
-  
-  qh_qhull()
-    compute DIM3 convex hull of qh.num_points starting at qh.first_point
-    qh contains all global options and variables
-
-  returns:
-    returns polyhedron
-      qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices,
-    
-    returns global variables
-      qh.hulltime, qh.max_outside, qh.interior_point, qh.max_vertex, qh.min_vertex
-    
-    returns precision constants
-      qh.ANGLEround, centrum_radius, cos_max, DISTround, MAXabs_coord, ONEmerge
-
-  notes:
-    unless needed for output
-      qh.max_vertex and qh.min_vertex are max/min due to merges
-      
-  see:
-    to add individual points to either qh.num_points
-      use qh_addpoint()
-      
-    if qh.GETarea
-      qh_produceoutput() returns qh.totarea and qh.totvol via qh_getarea()
-
-  design:
-    record starting time
-    initialize hull and partition points
-    build convex hull
-    unless early termination
-      update facet->maxoutside for vertices, coplanar, and near-inside points
-    error if temporary sets exist
-    record end time
-*/
-void qh_qhull (void) {
-  int numoutside;
-
-  qh hulltime= qh_CPUclock;
-  if (qh RERUN || qh JOGGLEmax < REALmax/2) 
-    qh_build_withrestart();
-  else {
-    qh_initbuild();
-    qh_buildhull();
-  }
-  if (!qh STOPpoint && !qh STOPcone) {
-    if (qh ZEROall_ok && !qh TESTvneighbors && qh MERGEexact)
-      qh_checkzero( qh_ALL);
-    if (qh ZEROall_ok && !qh TESTvneighbors && !qh WAScoplanar) {
-      trace2((qh ferr, "qh_qhull: all facets are clearly convex and no coplanar points.  Post-merging and check of maxout not needed.\n"));
-      qh DOcheckmax= False;
-    }else {
-      if (qh MERGEexact || (qh hull_dim > qh_DIMreduceBuild && qh PREmerge))
-        qh_postmerge ("First post-merge", qh premerge_centrum, qh premerge_cos, 
-             (qh POSTmerge ? False : qh TESTvneighbors));
-      else if (!qh POSTmerge && qh TESTvneighbors) 
-        qh_postmerge ("For testing vertex neighbors", qh premerge_centrum,
-             qh premerge_cos, True); 
-      if (qh POSTmerge)
-        qh_postmerge ("For post-merging", qh postmerge_centrum, 
-             qh postmerge_cos, qh TESTvneighbors);
-      if (qh visible_list == qh facet_list) { /* i.e., merging done */
-        qh findbestnew= True;
-        qh_partitionvisible (/*visible_list, newfacet_list*/ !qh_ALL, &numoutside);
-        qh findbestnew= False;
-        qh_deletevisible (/*qh visible_list*/);
-        qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-      }
-    }
-    if (qh DOcheckmax){
-      if (qh REPORTfreq) {
-	qh_buildtracing (NULL, NULL); 
-	fprintf (qh ferr, "\nTesting all coplanar points.\n");
-      }
-      qh_check_maxout();
-    }
-    if (qh KEEPnearinside && !qh maxoutdone)  
-      qh_nearcoplanar();
-  }
-  if (qh_setsize ((setT*)qhmem.tempstack) != 0) {
-    fprintf (qh ferr, "qhull internal error (qh_qhull): temporary sets not empty (%d)\n",
-	     qh_setsize ((setT*)qhmem.tempstack));
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh hulltime= qh_CPUclock - qh hulltime;
-  qh QHULLfinished= True;
-  trace1((qh ferr, "qh_qhull: algorithm completed\n"));
-} /* qhull */
-
-/*---------------------------------
-  
-  qh_addpoint( furthest, facet, checkdist )
-    add point (usually furthest point) above facet to hull 
-    if checkdist, 
-      check that point is above facet.
-      if point is not outside of the hull, uses qh_partitioncoplanar()
-      assumes that facet is defined by qh_findbestfacet()
-    else if facet specified,
-      assumes that point is above facet (major damage if below)
-    for Delaunay triangulations, 
-      Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
-      Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates. 
-
-  returns:
-    returns False if user requested an early termination
-     qh.visible_list, newfacet_list, delvertex_list, NEWfacets may be defined
-    updates qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices
-    clear qh.maxoutdone (will need to call qh_check_maxout() for facet->maxoutside)
-    if unknown point, adds a pointer to qh.other_points
-      do not deallocate the point's coordinates
-  
-  notes:
-    assumes point is near its best facet and not at a local minimum of a lens
-      distributions.  Use qh_findbestfacet to avoid this case.
-    uses qh.visible_list, qh.newfacet_list, qh.delvertex_list, qh.NEWfacets
-
-  see also:
-    qh_triangulate() -- triangulate non-simplicial facets
-
-  design:
-    check point in qh.first_point/.num_points
-    if checkdist
-      if point not above facet
-        partition coplanar point 
-        exit
-    exit if pre STOPpoint requested
-    find horizon and visible facets for point
-    make new facets for point to horizon
-    make hyperplanes for point
-    compute balance statistics
-    match neighboring new facets
-    update vertex neighbors and delete interior vertices
-    exit if STOPcone requested
-    merge non-convex new facets
-    if merge found, many merges, or 'Qf'
-       use qh_findbestnew() instead of qh_findbest()
-    partition outside points from visible facets
-    delete visible facets
-    check polyhedron if requested
-    exit if post STOPpoint requested
-    reset working lists of facets and vertices
-*/
-boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) {
-  int goodvisible, goodhorizon;
-  vertexT *vertex;
-  facetT *newfacet;
-  realT dist, newbalance, pbalance;
-  boolT isoutside= False;
-  int numpart, numpoints, numnew, firstnew;
-
-  qh maxoutdone= False;
-  if (qh_pointid (furthest) == -1)
-    qh_setappend (&qh other_points, furthest);
-  if (!facet) {
-    fprintf (qh ferr, "qh_addpoint: NULL facet.  Need to call qh_findbestfacet first\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (checkdist) {
-    facet= qh_findbest (furthest, facet, !qh_ALL, !qh_ISnewfacets, !qh_NOupper,
-			&dist, &isoutside, &numpart);
-    zzadd_(Zpartition, numpart);
-    if (!isoutside) {
-      zinc_(Znotmax);  /* last point of outsideset is no longer furthest. */
-      facet->notfurthest= True;
-      qh_partitioncoplanar (furthest, facet, &dist);
-      return True;
-    }
-  }
-  qh_buildtracing (furthest, facet);
-  if (qh STOPpoint < 0 && qh furthest_id == -qh STOPpoint-1) {
-    facet->notfurthest= True;
-    return False;
-  }
-  qh_findhorizon (furthest, facet, &goodvisible, &goodhorizon); 
-  if (qh ONLYgood && !(goodvisible+goodhorizon) && !qh GOODclosest) {
-    zinc_(Znotgood);  
-    facet->notfurthest= True;
-    /* last point of outsideset is no longer furthest.  This is ok
-       since all points of the outside are likely to be bad */
-    qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-    return True;
-  }
-  zzinc_(Zprocessed);
-  firstnew= qh facet_id;
-  vertex= qh_makenewfacets (furthest /*visible_list, attaches if !ONLYgood */);
-  qh_makenewplanes (/* newfacet_list */);
-  numnew= qh facet_id - firstnew;
-  newbalance= numnew - (realT) (qh num_facets-qh num_visible)
-                         * qh hull_dim/qh num_vertices;
-  wadd_(Wnewbalance, newbalance);
-  wadd_(Wnewbalance2, newbalance * newbalance);
-  if (qh ONLYgood 
-  && !qh_findgood (qh newfacet_list, goodhorizon) && !qh GOODclosest) {
-    FORALLnew_facets 
-      qh_delfacet (newfacet);
-    qh_delvertex (vertex);
-    qh_resetlists (True, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-    zinc_(Znotgoodnew);
-    facet->notfurthest= True;
-    return True;
-  }
-  if (qh ONLYgood)
-    qh_attachnewfacets(/*visible_list*/);
-  qh_matchnewfacets();
-  qh_updatevertices();
-  if (qh STOPcone && qh furthest_id == qh STOPcone-1) {
-    facet->notfurthest= True;
-    return False;  /* visible_list etc. still defined */
-  }
-  qh findbestnew= False;
-  if (qh PREmerge || qh MERGEexact) {
-    qh_premerge (vertex, qh premerge_centrum, qh premerge_cos);
-    if (qh_USEfindbestnew)
-      qh findbestnew= True;
-    else {
-      FORALLnew_facets {
-	if (!newfacet->simplicial) {
-	  qh findbestnew= True;  /* use qh_findbestnew instead of qh_findbest*/
-	  break;
-	}
-      }
-    }
-  }else if (qh BESToutside)
-    qh findbestnew= True;
-  qh_partitionvisible (/*visible_list, newfacet_list*/ !qh_ALL, &numpoints);
-  qh findbestnew= False;
-  qh findbest_notsharp= False;
-  zinc_(Zpbalance);
-  pbalance= numpoints - (realT) qh hull_dim /* assumes all points extreme */
-                * (qh num_points - qh num_vertices)/qh num_vertices;
-  wadd_(Wpbalance, pbalance);
-  wadd_(Wpbalance2, pbalance * pbalance);
-  qh_deletevisible (/*qh visible_list*/);
-  zmax_(Zmaxvertex, qh num_vertices);
-  qh NEWfacets= False;
-  if (qh IStracing >= 4) {
-    if (qh num_facets < 2000)
-      qh_printlists();
-    qh_printfacetlist (qh newfacet_list, NULL, True);
-    qh_checkpolygon (qh facet_list);
-  }else if (qh CHECKfrequently) {
-    if (qh num_facets < 50)
-      qh_checkpolygon (qh facet_list);
-    else
-      qh_checkpolygon (qh newfacet_list);
-  }
-  if (qh STOPpoint > 0 && qh furthest_id == qh STOPpoint-1) 
-    return False; 
-  qh_resetlists (True, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-  /* qh_triangulate(); to test qh.TRInormals */
-  trace2((qh ferr, "qh_addpoint: added p%d new facets %d new balance %2.2g point balance %2.2g\n",
-    qh_pointid (furthest), numnew, newbalance, pbalance));
-  return True;
-} /* addpoint */
-
-/*---------------------------------
-  
-  qh_build_withrestart()
-    allow restarts due to qh.JOGGLEmax while calling qh_buildhull()
-    qh.FIRSTpoint/qh.NUMpoints is point array
-        it may be moved by qh_joggleinput()
-*/
-void qh_build_withrestart (void) {
-  int restart;
-
-  qh ALLOWrestart= True;
-  while (True) {
-    restart= setjmp (qh restartexit); /* simple statement for CRAY J916 */
-    if (restart) {       /* only from qh_precision() */
-      zzinc_(Zretry);
-      wmax_(Wretrymax, qh JOGGLEmax);
-      qh ERREXITcalled= False;
-      qh STOPcone= True; /* if break, prevents normal output */
-    }
-    if (!qh RERUN && qh JOGGLEmax < REALmax/2) {
-      if (qh build_cnt > qh_JOGGLEmaxretry) {
-	fprintf(qh ferr, "\n\
-qhull precision error: %d attempts to construct a convex hull\n\
-        with joggled input.  Increase joggle above 'QJ%2.2g'\n\
-	or modify qh_JOGGLE... parameters in user.h\n",
-	   qh build_cnt, qh JOGGLEmax);
-	qh_errexit (qh_ERRqhull, NULL, NULL);
-      }
-      if (qh build_cnt && !restart)
-	break;
-    }else if (qh build_cnt && qh build_cnt >= qh RERUN)
-      break;
-    qh STOPcone= False;
-    qh_freebuild (True);  /* first call is a nop */
-    qh build_cnt++;
-    if (!qh qhull_optionsiz)
-      qh qhull_optionsiz= strlen (qh qhull_options);
-    else { 
-      qh qhull_options [qh qhull_optionsiz]= '\0';
-      qh qhull_optionlen= 80;
-    }
-    qh_option("_run", &qh build_cnt, NULL);
-    if (qh build_cnt == qh RERUN) {
-      qh IStracing= qh TRACElastrun;  /* duplicated from qh_initqhull_globals */
-      if (qh TRACEpoint != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
-        qh TRACElevel= (qh IStracing? qh IStracing : 3);
-        qh IStracing= 0;
-      }
-      qhmem.IStracing= qh IStracing;
-    }
-    if (qh JOGGLEmax < REALmax/2)
-      qh_joggleinput();
-    qh_initbuild();
-    qh_buildhull();
-    if (qh JOGGLEmax < REALmax/2 && !qh MERGING)
-      qh_checkconvex (qh facet_list, qh_ALGORITHMfault);
-  }
-  qh ALLOWrestart= False;
-} /* qh_build_withrestart */
-
-/*---------------------------------
-  
-  qh_buildhull()
-    construct a convex hull by adding outside points one at a time
-
-  returns:
-  
-  notes:
-    may be called multiple times
-    checks facet and vertex lists for incorrect flags
-    to recover from STOPcone, call qh_deletevisible and qh_resetlists
-
-  design:
-    check visible facet and newfacet flags
-    check newlist vertex flags and qh.STOPcone/STOPpoint
-    for each facet with a furthest outside point
-      add point to facet
-      exit if qh.STOPcone or qh.STOPpoint requested
-    if qh.NARROWhull for initial simplex
-      partition remaining outside points to coplanar sets
-*/
-void qh_buildhull(void) {
-  facetT *facet;
-  pointT *furthest;
-  vertexT *vertex;
-  int id;
-  
-  trace1((qh ferr, "qh_buildhull: start build hull\n"));
-  FORALLfacets {
-    if (facet->visible || facet->newfacet) {
-      fprintf (qh ferr, "qhull internal error (qh_buildhull): visible or new facet f%d in facet list\n",
-                   facet->id);    
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-  }
-  FORALLvertices {
-    if (vertex->newlist) {
-      fprintf (qh ferr, "qhull internal error (qh_buildhull): new vertex f%d in vertex list\n",
-                   vertex->id);
-      qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-    id= qh_pointid (vertex->point);
-    if ((qh STOPpoint>0 && id == qh STOPpoint-1) ||
-	(qh STOPpoint<0 && id == -qh STOPpoint-1) ||
-	(qh STOPcone>0 && id == qh STOPcone-1)) {
-      trace1((qh ferr,"qh_buildhull: stop point or cone P%d in initial hull\n", id));
-      return;
-    }
-  }
-  qh facet_next= qh facet_list;      /* advance facet when processed */
-  while ((furthest= qh_nextfurthest (&facet))) {
-    qh num_outside--;  /* if ONLYmax, furthest may not be outside */
-    if (!qh_addpoint (furthest, facet, qh ONLYmax))
-      break;
-  }
-  if (qh NARROWhull) /* move points from outsideset to coplanarset */
-    qh_outcoplanar( /* facet_list */ );
-  if (qh num_outside && !furthest) {
-    fprintf (qh ferr, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh num_outside);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  trace1((qh ferr, "qh_buildhull: completed the hull construction\n"));
-} /* buildhull */
-  
-
-/*---------------------------------
-  
-  qh_buildtracing( furthest, facet )
-    trace an iteration of qh_buildhull() for furthest point and facet
-    if !furthest, prints progress message
-
-  returns:
-    tracks progress with qh.lastreport
-    updates qh.furthest_id (-3 if furthest is NULL)
-    also resets visit_id, vertext_visit on wrap around
-
-  see:
-    qh_tracemerging()
-
-  design:
-    if !furthest
-      print progress message
-      exit
-    if 'TFn' iteration
-      print progress message
-    else if tracing
-      trace furthest point and facet
-    reset qh.visit_id and qh.vertex_visit if overflow may occur
-    set qh.furthest_id for tracing
-*/
-void qh_buildtracing (pointT *furthest, facetT *facet) {
-  realT dist= 0;
-  float cpu;
-  int total, furthestid;
-  time_t timedata;
-  struct tm *tp;
-  vertexT *vertex;
-
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  if (!furthest) {
-    time (&timedata);
-    tp= localtime (&timedata);
-    cpu= qh_CPUclock - qh hulltime;
-    cpu /= qh_SECticks;
-    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-    fprintf (qh ferr, "\n\
-At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
- The current hull contains %d facets and %d vertices.  Last point was p%d\n",
-      tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1,
-      total, qh num_facets, qh num_vertices, qh furthest_id);
-    return;
-  }
-  furthestid= qh_pointid (furthest);
-  if (qh TRACEpoint == furthestid) {
-    qh IStracing= qh TRACElevel;
-    qhmem.IStracing= qh TRACElevel;
-  }else if (qh TRACEpoint != -1 && qh TRACEdist < REALmax/2) {
-    qh IStracing= 0;
-    qhmem.IStracing= 0;
-  }
-  if (qh REPORTfreq && (qh facet_id-1 > qh lastreport+qh REPORTfreq)) {
-    qh lastreport= qh facet_id-1;
-    time (&timedata);
-    tp= localtime (&timedata);
-    cpu= qh_CPUclock - qh hulltime;
-    cpu /= qh_SECticks;
-    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-    zinc_(Zdistio);
-    qh_distplane (furthest, facet, &dist);
-    fprintf (qh ferr, "\n\
-At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
- The current hull contains %d facets and %d vertices.  There are %d\n\
- outside points.  Next is point p%d (v%d), %2.2g above f%d.\n",
-      tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1,
-      total, qh num_facets, qh num_vertices, qh num_outside+1,
-      furthestid, qh vertex_id, dist, getid_(facet));
-  }else if (qh IStracing >=1) {
-    cpu= qh_CPUclock - qh hulltime;
-    cpu /= qh_SECticks;
-    qh_distplane (furthest, facet, &dist);
-    fprintf (qh ferr, "qh_addpoint: add p%d (v%d) to hull of %d facets (%2.2g above f%d) and %d outside at %4.4g CPU secs.  Previous was p%d.\n",
-      furthestid, qh vertex_id, qh num_facets, dist,
-      getid_(facet), qh num_outside+1, cpu, qh furthest_id);
-  }
-  if (qh visit_id > (unsigned) INT_MAX) {
-    qh visit_id= 0;
-    FORALLfacets
-      facet->visitid= qh visit_id;
-  }
-  if (qh vertex_visit > (unsigned) INT_MAX) {
-    qh vertex_visit= 0;
-    FORALLvertices
-      vertex->visitid= qh vertex_visit;
-  }
-  qh furthest_id= furthestid;
-  qh RANDOMdist= qh old_randomdist;
-} /* buildtracing */
-
-/*---------------------------------
-  
-  qh_errexit2( exitcode, facet, otherfacet )
-    return exitcode to system after an error
-    report two facets
-
-  returns:
-    assumes exitcode non-zero
-
-  see:
-    normally use qh_errexit() in user.c (reports a facet and a ridge)
-*/
-void qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet) {
-  
-  qh_errprint("ERRONEOUS", facet, otherfacet, NULL, NULL);
-  qh_errexit (exitcode, NULL, NULL);
-} /* errexit2 */
-
-
-/*---------------------------------
-  
-  qh_findhorizon( point, facet, goodvisible, goodhorizon )
-    given a visible facet, find the point's horizon and visible facets
-    for all facets, !facet-visible
-
-  returns:
-    returns qh.visible_list/num_visible with all visible facets 
-      marks visible facets with ->visible 
-    updates count of good visible and good horizon facets
-    updates qh.max_outside, qh.max_vertex, facet->maxoutside
-
-  see:
-    similar to qh_delpoint()
-
-  design:
-    move facet to qh.visible_list at end of qh.facet_list
-    for all visible facets
-     for each unvisited neighbor of a visible facet
-       compute distance of point to neighbor
-       if point above neighbor
-         move neighbor to end of qh.visible_list
-       else if point is coplanar with neighbor
-         update qh.max_outside, qh.max_vertex, neighbor->maxoutside
-         mark neighbor coplanar (will create a samecycle later)
-         update horizon statistics         
-*/
-void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhorizon) {
-  facetT *neighbor, **neighborp, *visible;
-  int numhorizon= 0, coplanar= 0;
-  realT dist;
-  
-  trace1((qh ferr,"qh_findhorizon: find horizon for point p%d facet f%d\n",qh_pointid(point),facet->id));
-  *goodvisible= *goodhorizon= 0;
-  zinc_(Ztotvisible);
-  qh_removefacet(facet);  /* visible_list at end of qh facet_list */
-  qh_appendfacet(facet);
-  qh num_visible= 1;
-  if (facet->good)
-    (*goodvisible)++;
-  qh visible_list= facet;
-  facet->visible= True;
-  facet->f.replace= NULL;
-  if (qh IStracing >=4)
-    qh_errprint ("visible", facet, NULL, NULL, NULL);
-  qh visit_id++;
-  FORALLvisible_facets {
-    if (visible->tricoplanar && !qh TRInormals) {
-      fprintf (qh ferr, "qh_findhorizon: does not work for tricoplanar facets.  Use option 'Q11'\n");
-      qh_errexit (qh_ERRqhull, visible, NULL);
-    }
-    visible->visitid= qh visit_id;
-    FOREACHneighbor_(visible) {
-      if (neighbor->visitid == qh visit_id) 
-        continue;
-      neighbor->visitid= qh visit_id;
-      zzinc_(Znumvisibility);
-      qh_distplane(point, neighbor, &dist);
-      if (dist > qh MINvisible) {
-        zinc_(Ztotvisible);
-	qh_removefacet(neighbor);  /* append to end of qh visible_list */
-	qh_appendfacet(neighbor);
-	neighbor->visible= True;
-        neighbor->f.replace= NULL;
-	qh num_visible++;
-	if (neighbor->good)
-	  (*goodvisible)++;
-        if (qh IStracing >=4)
-          qh_errprint ("visible", neighbor, NULL, NULL, NULL);
-      }else {
- 	if (dist > - qh MAXcoplanar) {
-    	  neighbor->coplanar= True;
-          zzinc_(Zcoplanarhorizon);
-          qh_precision ("coplanar horizon");
-	  coplanar++;
-	  if (qh MERGING) {
-	    if (dist > 0) {
-	      maximize_(qh max_outside, dist);
-	      maximize_(qh max_vertex, dist);
-#if qh_MAXoutside
-	      maximize_(neighbor->maxoutside, dist);
-#endif
-	    }else
-	      minimize_(qh min_vertex, dist);  /* due to merge later */
-	  }
-      	  trace2((qh ferr, "qh_findhorizon: point p%d is coplanar to horizon f%d, dist=%2.7g < qh MINvisible (%2.7g)\n",
-	      qh_pointid(point), neighbor->id, dist, qh MINvisible));
-	}else
-    	  neighbor->coplanar= False;
-    	zinc_(Ztothorizon);
-        numhorizon++;
-	if (neighbor->good)
-	  (*goodhorizon)++;
-        if (qh IStracing >=4)
-          qh_errprint ("horizon", neighbor, NULL, NULL, NULL);
-      }
-    }
-  }
-  if (!numhorizon) {
-    qh_precision ("empty horizon");
-    fprintf(qh ferr, "qhull precision error (qh_findhorizon): empty horizon\n\
-Point p%d was above all facets.\n", qh_pointid(point));
-    qh_printfacetlist (qh facet_list, NULL, True);
-    qh_errexit(qh_ERRprec, NULL, NULL);
-  }
-  trace1((qh ferr, "qh_findhorizon: %d horizon facets (good %d), %d visible (good %d), %d coplanar\n", 
-       numhorizon, *goodhorizon, qh num_visible, *goodvisible, coplanar));
-  if (qh IStracing >= 4 && qh num_facets < 50) 
-    qh_printlists ();
-} /* findhorizon */
-
-/*---------------------------------
-  
-  qh_nextfurthest( visible )
-    returns next furthest point and visible facet for qh_addpoint()
-    starts search at qh.facet_next
-
-  returns:
-    removes furthest point from outside set
-    NULL if none available
-    advances qh.facet_next over facets with empty outside sets  
-
-  design:
-    for each facet from qh.facet_next
-      if empty outside set
-        advance qh.facet_next
-      else if qh.NARROWhull
-        determine furthest outside point
-        if furthest point is not outside
-          advance qh.facet_next (point will be coplanar)
-    remove furthest point from outside set
-*/
-pointT *qh_nextfurthest (facetT **visible) {
-  facetT *facet;
-  int size, index;
-  realT randr, dist;
-  pointT *furthest;
-
-  while ((facet= qh facet_next) != qh facet_tail) {
-    if (!facet->outsideset) {
-      qh facet_next= facet->next;
-      continue;
-    }
-    SETreturnsize_(facet->outsideset, size);
-    if (!size) {
-      qh_setfree (&facet->outsideset);
-      qh facet_next= facet->next;
-      continue;
-    }
-    if (qh NARROWhull) {
-      if (facet->notfurthest) 
-	qh_furthestout (facet);
-      furthest= (pointT*)qh_setlast (facet->outsideset);
-#if qh_COMPUTEfurthest
-      qh_distplane (furthest, facet, &dist);
-      zinc_(Zcomputefurthest);
-#else
-      dist= facet->furthestdist;
-#endif
-      if (dist < qh MINoutside) { /* remainder of outside set is coplanar for qh_outcoplanar */
-	qh facet_next= facet->next;
-	continue;
-      }
-    }
-    if (!qh RANDOMoutside && !qh VIRTUALmemory) {
-      if (qh PICKfurthest) {
-	qh_furthestnext (/* qh facet_list */);
-	facet= qh facet_next;
-      }
-      *visible= facet;
-      return ((pointT*)qh_setdellast (facet->outsideset));
-    }
-    if (qh RANDOMoutside) {
-      int outcoplanar = 0;
-      if (qh NARROWhull) {
-        FORALLfacets {
-	  if (facet == qh facet_next)
-	    break;
-	  if (facet->outsideset)
-  	    outcoplanar += qh_setsize( facet->outsideset);
-	}
-      }
-      randr= qh_RANDOMint;
-      randr= randr/(qh_RANDOMmax+1);
-      index= (int)floor((qh num_outside - outcoplanar) * randr);
-      FORALLfacet_(qh facet_next) {
-        if (facet->outsideset) {
-          SETreturnsize_(facet->outsideset, size);
-          if (!size)
-            qh_setfree (&facet->outsideset);
-          else if (size > index) {
-            *visible= facet;
-            return ((pointT*)qh_setdelnth (facet->outsideset, index));
-          }else
-            index -= size;
-        }
-      }
-      fprintf (qh ferr, "qhull internal error (qh_nextfurthest): num_outside %d is too low\nby at least %d, or a random real %g >= 1.0\n",
-              qh num_outside, index+1, randr);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }else { /* VIRTUALmemory */
-      facet= qh facet_tail->previous;
-      if (!(furthest= (pointT*)qh_setdellast(facet->outsideset))) {
-        if (facet->outsideset)
-          qh_setfree (&facet->outsideset);
-        qh_removefacet (facet);
-        qh_prependfacet (facet, &qh facet_list);
-        continue;
-      }
-      *visible= facet;
-      return furthest;
-    }
-  }
-  return NULL;
-} /* nextfurthest */
-
-/*---------------------------------
-  
-  qh_partitionall( vertices, points, numpoints )
-    partitions all points in points/numpoints to the outsidesets of facets
-    vertices= vertices in qh.facet_list (not partitioned)
-
-  returns:
-    builds facet->outsideset
-    does not partition qh.GOODpoint
-    if qh.ONLYgood && !qh.MERGING, 
-      does not partition qh.GOODvertex
-
-  notes:
-    faster if qh.facet_list sorted by anticipated size of outside set
-
-  design:
-    initialize pointset with all points
-    remove vertices from pointset
-    remove qh.GOODpointp from pointset (unless it's qh.STOPcone or qh.STOPpoint)
-    for all facets
-      for all remaining points in pointset
-        compute distance from point to facet
-        if point is outside facet
-          remove point from pointset (by not reappending)
-          update bestpoint
-          append point or old bestpoint to facet's outside set
-      append bestpoint to facet's outside set (furthest)
-    for all points remaining in pointset
-      partition point into facets' outside sets and coplanar sets
-*/
-void qh_partitionall(setT *vertices, pointT *points, int numpoints){
-  setT *pointset;
-  vertexT *vertex, **vertexp;
-  pointT *point, **pointp, *bestpoint;
-  int size, point_i, point_n, point_end, remaining, i, id;
-  facetT *facet;
-  realT bestdist= -REALmax, dist, distoutside;
-    
-  trace1((qh ferr, "qh_partitionall: partition all points into outside sets\n"));
-  pointset= qh_settemp (numpoints);
-  qh num_outside= 0;
-  pointp= SETaddr_(pointset, pointT);
-  for (i=numpoints, point= points; i--; point += qh hull_dim)
-    *(pointp++)= point;
-  qh_settruncate (pointset, numpoints);
-  FOREACHvertex_(vertices) {
-    if ((id= qh_pointid(vertex->point)) >= 0)
-      SETelem_(pointset, id)= NULL;
-  }
-  id= qh_pointid (qh GOODpointp);
-  if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id)
-    SETelem_(pointset, id)= NULL;
-  if (qh GOODvertexp && qh ONLYgood && !qh MERGING) { /* matches qhull()*/
-    if ((id= qh_pointid(qh GOODvertexp)) >= 0)
-      SETelem_(pointset, id)= NULL;
-  }
-  if (!qh BESToutside) {  /* matches conditional for qh_partitionpoint below */
-    distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
-    zval_(Ztotpartition)= qh num_points - qh hull_dim - 1; /*misses GOOD... */
-    remaining= qh num_facets;
-    point_end= numpoints;
-    FORALLfacets {
-      size= point_end/(remaining--) + 100;
-      facet->outsideset= qh_setnew (size);
-      bestpoint= NULL;
-      point_end= 0;
-      FOREACHpoint_i_(pointset) {
-        if (point) {
-          zzinc_(Zpartitionall);
-          qh_distplane (point, facet, &dist);
-          if (dist < distoutside)
-            SETelem_(pointset, point_end++)= point;
-          else {
-	    qh num_outside++;
-            if (!bestpoint) {
-              bestpoint= point;
-              bestdist= dist;
-            }else if (dist > bestdist) {
-              qh_setappend (&facet->outsideset, bestpoint);
-              bestpoint= point;
-              bestdist= dist;
-            }else 
-              qh_setappend (&facet->outsideset, point);
-          }
-        }
-      }
-      if (bestpoint) {
-        qh_setappend (&facet->outsideset, bestpoint);
-#if !qh_COMPUTEfurthest
-	facet->furthestdist= bestdist;
-#endif
-      }else
-        qh_setfree (&facet->outsideset);
-      qh_settruncate (pointset, point_end);
-    }
-  }
-  /* if !qh BESToutside, pointset contains points not assigned to outsideset */
-  if (qh BESToutside || qh MERGING || qh KEEPcoplanar || qh KEEPinside) {
-    qh findbestnew= True;
-    FOREACHpoint_i_(pointset) { 
-      if (point)
-        qh_partitionpoint(point, qh facet_list);
-    }
-    qh findbestnew= False;
-  }
-  zzadd_(Zpartitionall, zzval_(Zpartition));
-  zzval_(Zpartition)= 0;
-  qh_settempfree(&pointset);
-  if (qh IStracing >= 4)
-    qh_printfacetlist (qh facet_list, NULL, True);
-} /* partitionall */
-
-
-/*---------------------------------
-  
-  qh_partitioncoplanar( point, facet, dist )
-    partition coplanar point to a facet
-    dist is distance from point to facet
-    if dist NULL, 
-      searches for bestfacet and does nothing if inside
-    if qh.findbestnew set, 
-      searches new facets instead of using qh_findbest()
-
-  returns:
-    qh.max_ouside updated
-    if qh.KEEPcoplanar or qh.KEEPinside
-      point assigned to best coplanarset
-  
-  notes:
-    facet->maxoutside is updated at end by qh_check_maxout
-
-  design:
-    if dist undefined
-      find best facet for point
-      if point sufficiently below facet (depends on qh.NEARinside and qh.KEEPinside)
-        exit
-    if keeping coplanar/nearinside/inside points
-      if point is above furthest coplanar point
-        append point to coplanar set (it is the new furthest)
-        update qh.max_outside
-      else
-        append point one before end of coplanar set
-    else if point is clearly outside of qh.max_outside and bestfacet->coplanarset
-    and bestfacet is more than perpendicular to facet
-      repartition the point using qh_findbest() -- it may be put on an outsideset
-    else
-      update qh.max_outside
-*/
-void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) {
-  facetT *bestfacet;
-  pointT *oldfurthest;
-  realT bestdist, dist2, angle;
-  int numpart= 0, oldfindbest;
-  boolT isoutside;
-
-  qh WAScoplanar= True;
-  if (!dist) {
-    if (qh findbestnew)
-      bestfacet= qh_findbestnew (point, facet, &bestdist, qh_ALL, &isoutside, &numpart);
-    else
-      bestfacet= qh_findbest (point, facet, qh_ALL, !qh_ISnewfacets, qh DELAUNAY, 
-                          &bestdist, &isoutside, &numpart);
-    zinc_(Ztotpartcoplanar);
-    zzadd_(Zpartcoplanar, numpart);
-    if (!qh DELAUNAY && !qh KEEPinside) { /*  for 'd', bestdist skips upperDelaunay facets */
-      if (qh KEEPnearinside) {
-        if (bestdist < -qh NEARinside) { 
-          zinc_(Zcoplanarinside);
-	  trace4((qh ferr, "qh_partitioncoplanar: point p%d is more than near-inside facet f%d dist %2.2g findbestnew %d\n",
-		  qh_pointid(point), bestfacet->id, bestdist, qh findbestnew));
-          return;
-        }
-      }else if (bestdist < -qh MAXcoplanar) {
-	  trace4((qh ferr, "qh_partitioncoplanar: point p%d is inside facet f%d dist %2.2g findbestnew %d\n",
-		  qh_pointid(point), bestfacet->id, bestdist, qh findbestnew));
-        zinc_(Zcoplanarinside);
-        return;
-      }
-    }
-  }else {
-    bestfacet= facet;
-    bestdist= *dist;
-  }
-  if (bestdist > qh max_outside) {
-    if (!dist && facet != bestfacet) { 
-      zinc_(Zpartangle);
-      angle= qh_getangle(facet->normal, bestfacet->normal);
-      if (angle < 0) {
-	/* typically due to deleted vertex and coplanar facets, e.g.,
-	     RBOX 1000 s Z1 G1e-13 t1001185205 | QHULL Tv */
-	zinc_(Zpartflip);
-	trace2((qh ferr, "qh_partitioncoplanar: repartition point p%d from f%d.  It is above flipped facet f%d dist %2.2g\n",
-		qh_pointid(point), facet->id, bestfacet->id, bestdist));
-	oldfindbest= qh findbestnew;
-        qh findbestnew= False;
-	qh_partitionpoint(point, bestfacet);
-        qh findbestnew= oldfindbest;
-	return;
-      }
-    }
-    qh max_outside= bestdist;
-    if (bestdist > qh TRACEdist) {
-      fprintf (qh ferr, "qh_partitioncoplanar: ====== p%d from f%d increases max_outside to %2.2g of f%d last p%d\n",
-		     qh_pointid(point), facet->id, bestdist, bestfacet->id, qh furthest_id);
-      qh_errprint ("DISTANT", facet, bestfacet, NULL, NULL);
-    }
-  }
-  if (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside) {
-    oldfurthest= (pointT*)qh_setlast (bestfacet->coplanarset);
-    if (oldfurthest) {
-      zinc_(Zcomputefurthest);
-      qh_distplane (oldfurthest, bestfacet, &dist2);
-    }
-    if (!oldfurthest || dist2 < bestdist) 
-      qh_setappend(&bestfacet->coplanarset, point);
-    else 
-      qh_setappend2ndlast(&bestfacet->coplanarset, point);
-  }
-  trace4((qh ferr, "qh_partitioncoplanar: point p%d is coplanar with facet f%d (or inside) dist %2.2g\n",
-	  qh_pointid(point), bestfacet->id, bestdist));
-} /* partitioncoplanar */
-
-/*---------------------------------
-  
-  qh_partitionpoint( point, facet )
-    assigns point to an outside set, coplanar set, or inside set (i.e., dropt)
-    if qh.findbestnew
-      uses qh_findbestnew() to search all new facets
-    else
-      uses qh_findbest()
-  
-  notes:
-    after qh_distplane(), this and qh_findbest() are most expensive in 3-d
-
-  design:
-    find best facet for point 
-      (either exhaustive search of new facets or directed search from facet)
-    if qh.NARROWhull
-      retain coplanar and nearinside points as outside points
-    if point is outside bestfacet
-      if point above furthest point for bestfacet
-        append point to outside set (it becomes the new furthest)
-        if outside set was empty
-          move bestfacet to end of qh.facet_list (i.e., after qh.facet_next)
-        update bestfacet->furthestdist
-      else
-        append point one before end of outside set
-    else if point is coplanar to bestfacet
-      if keeping coplanar points or need to update qh.max_outside
-        partition coplanar point into bestfacet
-    else if near-inside point        
-      partition as coplanar point into bestfacet
-    else is an inside point
-      if keeping inside points 
-        partition as coplanar point into bestfacet
-*/
-void qh_partitionpoint (pointT *point, facetT *facet) {
-  realT bestdist;
-  boolT isoutside;
-  facetT *bestfacet;
-  int numpart;
-#if qh_COMPUTEfurthest
-  realT dist;
-#endif
-
-  if (qh findbestnew)
-    bestfacet= qh_findbestnew (point, facet, &bestdist, qh BESToutside, &isoutside, &numpart);
-  else
-    bestfacet= qh_findbest (point, facet, qh BESToutside, qh_ISnewfacets, !qh_NOupper,
-			  &bestdist, &isoutside, &numpart);
-  zinc_(Ztotpartition);
-  zzadd_(Zpartition, numpart);
-  if (qh NARROWhull) {
-    if (qh DELAUNAY && !isoutside && bestdist >= -qh MAXcoplanar)
-      qh_precision ("nearly incident point (narrow hull)");
-    if (qh KEEPnearinside) {
-      if (bestdist >= -qh NEARinside)
-	isoutside= True;
-    }else if (bestdist >= -qh MAXcoplanar)
-      isoutside= True;
-  }
-
-  if (isoutside) {
-    if (!bestfacet->outsideset 
-    || !qh_setlast (bestfacet->outsideset)) {
-      qh_setappend(&(bestfacet->outsideset), point);
-      if (!bestfacet->newfacet) {
-        qh_removefacet (bestfacet);  /* make sure it's after qh facet_next */
-        qh_appendfacet (bestfacet);
-      }
-#if !qh_COMPUTEfurthest
-      bestfacet->furthestdist= bestdist;
-#endif
-    }else {
-#if qh_COMPUTEfurthest
-      zinc_(Zcomputefurthest);
-      qh_distplane (oldfurthest, bestfacet, &dist);
-      if (dist < bestdist) 
-	qh_setappend(&(bestfacet->outsideset), point);
-      else
-	qh_setappend2ndlast(&(bestfacet->outsideset), point);
-#else
-      if (bestfacet->furthestdist < bestdist) {
-	qh_setappend(&(bestfacet->outsideset), point);
-	bestfacet->furthestdist= bestdist;
-      }else
-	qh_setappend2ndlast(&(bestfacet->outsideset), point);
-#endif
-    }
-    qh num_outside++;
-    trace4((qh ferr, "qh_partitionpoint: point p%d is outside facet f%d new? %d(or narrowhull)\n",
-	  qh_pointid(point), bestfacet->id, bestfacet->newfacet));
-  }else if (qh DELAUNAY || bestdist >= -qh MAXcoplanar) { /* for 'd', bestdist skips upperDelaunay facets */
-    zzinc_(Zcoplanarpart);
-    if (qh DELAUNAY)
-      qh_precision ("nearly incident point");
-    if ((qh KEEPcoplanar + qh KEEPnearinside) || bestdist > qh max_outside) 
-      qh_partitioncoplanar (point, bestfacet, &bestdist);
-    else {
-      trace4((qh ferr, "qh_partitionpoint: point p%d is coplanar to facet f%d (dropped)\n",
-	  qh_pointid(point), bestfacet->id));
-    }
-  }else if (qh KEEPnearinside && bestdist > -qh NEARinside) {
-    zinc_(Zpartnear);
-    qh_partitioncoplanar (point, bestfacet, &bestdist);
-  }else {
-    zinc_(Zpartinside);
-    trace4((qh ferr, "qh_partitionpoint: point p%d is inside all facets, closest to f%d dist %2.2g\n",
-	  qh_pointid(point), bestfacet->id, bestdist));
-    if (qh KEEPinside)
-      qh_partitioncoplanar (point, bestfacet, &bestdist);
-  }
-} /* partitionpoint */
-
-/*---------------------------------
-  
-  qh_partitionvisible( allpoints, numoutside )
-    partitions points in visible facets to qh.newfacet_list
-    qh.visible_list= visible facets
-    for visible facets
-      1st neighbor (if any) points to a horizon facet or a new facet
-    if allpoints (not used),
-      repartitions coplanar points
-
-  returns:
-    updates outside sets and coplanar sets of qh.newfacet_list
-    updates qh.num_outside (count of outside points)
-  
-  notes:
-    qh.findbest_notsharp should be clear (extra work if set)
-
-  design:
-    for all visible facets with outside set or coplanar set
-      select a newfacet for visible facet
-      if outside set
-        partition outside set into new facets
-      if coplanar set and keeping coplanar/near-inside/inside points
-        if allpoints
-          partition coplanar set into new facets, may be assigned outside
-        else
-          partition coplanar set into coplanar sets of new facets
-    for each deleted vertex
-      if allpoints
-        partition vertex into new facets, may be assigned outside
-      else
-        partition vertex into coplanar sets of new facets
-*/
-void qh_partitionvisible(/*visible_list*/ boolT allpoints, int *numoutside) {
-  facetT *visible, *newfacet;
-  pointT *point, **pointp;
-  int coplanar=0, size;
-  unsigned count;
-  vertexT *vertex, **vertexp;
-  
-  if (qh ONLYmax)
-    maximize_(qh MINoutside, qh max_vertex);
-  *numoutside= 0;
-  FORALLvisible_facets {
-    if (!visible->outsideset && !visible->coplanarset)
-      continue;
-    newfacet= visible->f.replace;
-    count= 0;
-    while (newfacet && newfacet->visible) {
-      newfacet= newfacet->f.replace;
-      if (count++ > qh facet_id)
-	qh_infiniteloop (visible);
-    }
-    if (!newfacet)
-      newfacet= qh newfacet_list;
-    if (newfacet == qh facet_tail) {
-      fprintf (qh ferr, "qhull precision error (qh_partitionvisible): all new facets deleted as\n        degenerate facets. Can not continue.\n");
-      qh_errexit (qh_ERRprec, NULL, NULL);
-    }
-    if (visible->outsideset) {
-      size= qh_setsize (visible->outsideset);
-      *numoutside += size;
-      qh num_outside -= size;
-      FOREACHpoint_(visible->outsideset) 
-        qh_partitionpoint (point, newfacet);
-    }
-    if (visible->coplanarset && (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside)) {
-      size= qh_setsize (visible->coplanarset);
-      coplanar += size;
-      FOREACHpoint_(visible->coplanarset) {
-        if (allpoints) /* not used */
-          qh_partitionpoint (point, newfacet);
-        else
-          qh_partitioncoplanar (point, newfacet, NULL);
-      }
-    }
-  }
-  FOREACHvertex_(qh del_vertices) {
-    if (vertex->point) {
-      if (allpoints) /* not used */
-        qh_partitionpoint (vertex->point, qh newfacet_list);
-      else
-        qh_partitioncoplanar (vertex->point, qh newfacet_list, NULL);
-    }
-  }
-  trace1((qh ferr,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar));
-} /* partitionvisible */
-
-
-
-/*---------------------------------
-  
-  qh_precision( reason )
-    restart on precision errors if not merging and if 'QJn'
-*/
-void qh_precision (char *reason) {
-
-  if (qh ALLOWrestart && !qh PREmerge && !qh MERGEexact) {
-    if (qh JOGGLEmax < REALmax/2) {
-      trace0((qh ferr, "qh_precision: qhull restart because of %s\n", reason));
-      longjmp(qh restartexit, qh_ERRprec);
-    }
-  }
-} /* qh_precision */
-
-/*---------------------------------
-  
-  qh_printsummary( fp )
-    prints summary to fp
-
-  notes:
-    not in io.c so that user_eg.c can prevent io.c from loading
-    qh_printsummary and qh_countfacets must match counts
-
-  design:
-    determine number of points, vertices, and coplanar points
-    print summary
-*/
-void qh_printsummary(FILE *fp) {
-  realT ratio, outerplane, innerplane;
-  float cpu;
-  int size, id, nummerged, numvertices, numcoplanars= 0, nonsimplicial=0;
-  int goodused;
-  facetT *facet;
-  char *s;
-  int numdel= zzval_(Zdelvertextot);
-  int numtricoplanars= 0;
-
-  size= qh num_points + qh_setsize (qh other_points);
-  numvertices= qh num_vertices - qh_setsize (qh del_vertices);
-  id= qh_pointid (qh GOODpointp);
-  FORALLfacets {
-    if (facet->coplanarset)
-      numcoplanars += qh_setsize( facet->coplanarset);
-    if (facet->good) {
-      if (facet->simplicial) {
-	if (facet->keepcentrum && facet->tricoplanar)
-	  numtricoplanars++;
-      }else if (qh_setsize(facet->vertices) != qh hull_dim)
-	nonsimplicial++;
-    }
-  }
-  if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id)
-    size--;
-  if (qh STOPcone || qh STOPpoint)
-      fprintf (fp, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error.");
-  if (qh UPPERdelaunay)
-    goodused= qh GOODvertex + qh GOODpoint + qh SPLITthresholds;
-  else if (qh DELAUNAY)
-    goodused= qh GOODvertex + qh GOODpoint + qh GOODthreshold;
-  else
-    goodused= qh num_good;
-  nummerged= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-  if (qh VORONOI) {
-    if (qh UPPERdelaunay)
-      fprintf (fp, "\n\
-Furthest-site Voronoi vertices by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    else
-      fprintf (fp, "\n\
-Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of Voronoi regions%s: %d\n",
-              qh ATinfinity ? " and at-infinity" : "", numvertices);
-    if (numdel)
-      fprintf(fp, "  Total number of deleted points due to merging: %d\n", numdel); 
-    if (numcoplanars - numdel > 0) 
-      fprintf(fp, "  Number of nearly incident points: %d\n", numcoplanars - numdel); 
-    else if (size - numvertices - numdel > 0) 
-      fprintf(fp, "  Total number of nearly incident points: %d\n", size - numvertices - numdel); 
-    fprintf(fp, "  Number of%s Voronoi vertices: %d\n", 
-              goodused ? " 'good'" : "", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial Voronoi vertices: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }else if (qh DELAUNAY) {
-    if (qh UPPERdelaunay)
-      fprintf (fp, "\n\
-Furthest-site Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    else
-      fprintf (fp, "\n\
-Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of input sites%s: %d\n", 
-              qh ATinfinity ? " and at-infinity" : "", numvertices);
-    if (numdel)
-      fprintf(fp, "  Total number of deleted points due to merging: %d\n", numdel); 
-    if (numcoplanars - numdel > 0) 
-      fprintf(fp, "  Number of nearly incident points: %d\n", numcoplanars - numdel); 
-    else if (size - numvertices - numdel > 0)
-      fprintf(fp, "  Total number of nearly incident points: %d\n", size - numvertices - numdel); 
-    fprintf(fp, "  Number of%s Delaunay regions: %d\n", 
-              goodused ? " 'good'" : "", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial Delaunay regions: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }else if (qh HALFspace) {
-    fprintf (fp, "\n\
-Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of halfspaces: %d\n", size);
-    fprintf(fp, "  Number of non-redundant halfspaces: %d\n", numvertices);
-    if (numcoplanars) {
-      if (qh KEEPinside && qh KEEPcoplanar)
-      	s= "similar and redundant";
-      else if (qh KEEPinside)
-        s= "redundant";
-      else
-        s= "similar"; 
-      fprintf(fp, "  Number of %s halfspaces: %d\n", s, numcoplanars);
-    } 
-    fprintf(fp, "  Number of intersection points: %d\n", qh num_facets - qh num_visible);
-    if (goodused)
-      fprintf(fp, "  Number of 'good' intersection points: %d\n", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial intersection points: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }else {
-    fprintf (fp, "\n\
-Convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of vertices: %d\n", numvertices);
-    if (numcoplanars) {
-      if (qh KEEPinside && qh KEEPcoplanar)
-      	s= "coplanar and interior";
-      else if (qh KEEPinside)
-        s= "interior";
-      else
-        s= "coplanar"; 
-      fprintf(fp, "  Number of %s points: %d\n", s, numcoplanars);
-    } 
-    fprintf(fp, "  Number of facets: %d\n", qh num_facets - qh num_visible);
-    if (goodused)
-      fprintf(fp, "  Number of 'good' facets: %d\n", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial facets: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }
-  if (numtricoplanars)
-      fprintf(fp, "  Number of triangulated facets: %d\n", numtricoplanars);
-  fprintf(fp, "\nStatistics for: %s | %s", 
-                      qh rbox_command, qh qhull_command);
-  if (qh ROTATErandom != INT_MIN)
-    fprintf(fp, " QR%d\n\n", qh ROTATErandom);
-  else
-    fprintf(fp, "\n\n");
-  fprintf(fp, "  Number of points processed: %d\n", zzval_(Zprocessed));
-  fprintf(fp, "  Number of hyperplanes created: %d\n", zzval_(Zsetplane));
-  if (qh DELAUNAY)
-    fprintf(fp, "  Number of facets in hull: %d\n", qh num_facets - qh num_visible);
-  fprintf(fp, "  Number of distance tests for qhull: %d\n", zzval_(Zpartition)+
-      zzval_(Zpartitionall)+zzval_(Znumvisibility)+zzval_(Zpartcoplanar));
-#if 0  /* NOTE: must print before printstatistics() */
-  {realT stddev, ave;
-  fprintf(fp, "  average new facet balance: %2.2g\n",
-	  wval_(Wnewbalance)/zval_(Zprocessed));
-  stddev= qh_stddev (zval_(Zprocessed), wval_(Wnewbalance), 
-                                 wval_(Wnewbalance2), &ave);
-  fprintf(fp, "  new facet standard deviation: %2.2g\n", stddev);
-  fprintf(fp, "  average partition balance: %2.2g\n",
-	  wval_(Wpbalance)/zval_(Zpbalance));
-  stddev= qh_stddev (zval_(Zpbalance), wval_(Wpbalance), 
-                                 wval_(Wpbalance2), &ave);
-  fprintf(fp, "  partition standard deviation: %2.2g\n", stddev);
-  }
-#endif
-  if (nummerged) {
-    fprintf(fp,"  Number of distance tests for merging: %d\n",zzval_(Zbestdist)+
-          zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+
-          zzval_(Zdistzero));
-    fprintf(fp,"  Number of distance tests for checking: %d\n",zzval_(Zcheckpart));
-    fprintf(fp,"  Number of merged facets: %d\n", nummerged);
-  }
-  if (!qh RANDOMoutside && qh QHULLfinished) {
-    cpu= qh hulltime;
-    cpu /= qh_SECticks;
-    wval_(Wcpu)= cpu;
-    fprintf (fp, "  CPU seconds to compute hull (after input): %2.4g\n", cpu);
-  }
-  if (qh RERUN) {
-    if (!qh PREmerge && !qh MERGEexact)
-      fprintf(fp, "  Percentage of runs with precision errors: %4.1f\n",
-	   zzval_(Zretry)*100.0/qh build_cnt);  /* careful of order */
-  }else if (qh JOGGLEmax < REALmax/2) {
-    if (zzval_(Zretry))
-      fprintf(fp, "  After %d retries, input joggled by: %2.2g\n",
-         zzval_(Zretry), qh JOGGLEmax);
-    else
-      fprintf(fp, "  Input joggled by: %2.2g\n", qh JOGGLEmax);
-  }
-  if (qh totarea != 0.0) 
-    fprintf(fp, "  %s facet area:   %2.8g\n", 
-	    zzval_(Ztotmerge) ? "Approximate" : "Total", qh totarea);
-  if (qh totvol != 0.0) 
-    fprintf(fp, "  %s volume:       %2.8g\n", 
-	    zzval_(Ztotmerge) ? "Approximate" : "Total", qh totvol);
-  if (qh MERGING) {
-    qh_outerinner (NULL, &outerplane, &innerplane);
-    if (outerplane > 2 * qh DISTround) {
-      fprintf(fp, "  Maximum distance of %spoint above facet: %2.2g", 
-	    (qh QHULLfinished ? "" : "merged "), outerplane);
-      ratio= outerplane/(qh ONEmerge + qh DISTround);
-      /* don't report ratio if MINoutside is large */
-      if (ratio > 0.05 && 2* qh ONEmerge > qh MINoutside && qh JOGGLEmax > REALmax/2)
-        fprintf (fp, " (%.1fx)\n", ratio);
-      else
-        fprintf (fp, "\n");
-    }
-    if (innerplane < -2 * qh DISTround) {
-      fprintf(fp, "  Maximum distance of %svertex below facet: %2.2g", 
-	    (qh QHULLfinished ? "" : "merged "), innerplane);
-      ratio= -innerplane/(qh ONEmerge+qh DISTround);
-      if (ratio > 0.05 && qh JOGGLEmax > REALmax/2)
-        fprintf (fp, " (%.1fx)\n", ratio);
-      else
-        fprintf (fp, "\n");
-    }
-  }
-  fprintf(fp, "\n");
-} /* printsummary */
-
-
diff --git a/extern/qhull/src/qhull.h b/extern/qhull/src/qhull.h
deleted file mode 100644
index 896ec1e9c18..00000000000
--- a/extern/qhull/src/qhull.h
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
  ---------------------------------
-
-   qhull.h
-   user-level header file for using qhull.a library
-
-   see qh-qhull.htm, qhull_a.h
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   NOTE: access to qh_qh is via the 'qh' macro.  This allows
-   qh_qh to be either a pointer or a structure.  An example
-   of using qh is "qh DROPdim" which accesses the DROPdim
-   field of qh_qh.  Similarly, access to qh_qhstat is via
-   the 'qhstat' macro.
-
-   includes function prototypes for qhull.c, geom.c, global.c, io.c, user.c
-
-   use mem.h for mem.c
-   use qset.h for qset.c
-
-   see unix.c for an example of using qhull.h
-
-   recompile qhull if you change this file
-*/
-
-#ifndef qhDEFqhull
-#define qhDEFqhull 1
-
-/*=========================== -included files ==============*/
-
-#include 
-#include 
-#include 
-
-#if __MWERKS__ && __POWERPC__
-#include  
-#include  
-#include	
-#endif
-
-#ifndef __STDC__
-#ifndef __cplusplus
-#if     !_MSC_VER
-#error  Neither __STDC__ nor __cplusplus is defined.  Please use strict ANSI C or C++ to compile
-#error  Qhull.  You may need to turn off compiler extensions in your project configuration.  If
-#error  your compiler is a standard C compiler, you can delete this warning from qhull.h
-#endif
-#endif
-#endif
-
-#include "user.h"      /* user defineable constants */
-
-/*============ constants and basic types ====================*/
-
-/*----------------------------------
-
-  qh_VERSION
-    version string by year and date
-
-    the revision increases on code changes only
-
-  notes:
-    change date:    Changes.txt, Announce.txt, README.txt, qhull.man
-                    qhull-news.html, Eudora signatures, 
-    change version: README.txt, qhull.html, file_id.diz, Makefile
-    change year:    Copying.txt
-    check download size
-    recompile user_eg.c, rbox.c, qhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c
-    make copy of qhull-news.html as qh-news.htm
-*/
-
-#define qh_VERSION "2002.1 2002/8/20"
-
-/*----------------------------------
-
-  coordT
-    coordinates and coefficients are stored as realT (i.e., double)
-
-  notes:
-    could use 'float' for data and 'double' for calculations (realT vs. coordT)
-      This requires many type casts, and adjusted error bounds.
-      Also C compilers may do expressions in double anyway.
-*/
-#define coordT realT
-
-/*----------------------------------
-
-  pointT
-    a point is an array of DIM3 coordinates
-*/
-#define pointT coordT
-
-/*----------------------------------
-
-  flagT
-    Boolean flag as a bit
-*/
-#define flagT unsigned int
-
-/*----------------------------------
-
-  boolT
-    boolean value, either True or False
-
-  notes:
-    needed for portability
-*/
-#define boolT unsigned int
-#ifdef False
-#undef False
-#endif
-#ifdef True
-#undef True
-#endif
-#define False 0
-#define True 1
-
-/*----------------------------------
-
-  qh_CENTER
-    to distinguish facet->center
-*/
-typedef enum
-{
-    qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum
-}
-qh_CENTER;
-
-/*----------------------------------
-
-  qh_PRINT
-    output formats for printing (qh.PRINTout).
-    'Fa' 'FV' 'Fc' 'FC' 
-       
-
-   notes:
-   some of these names are similar to qh names.  The similar names are only
-   used in switch statements in qh_printbegin() etc.
-*/
-typedef enum {qh_PRINTnone= 0, 
-  qh_PRINTarea, qh_PRINTaverage,           /* 'Fa' 'FV' 'Fc' 'FC' */
-  qh_PRINTcoplanars, qh_PRINTcentrums, 
-  qh_PRINTfacets, qh_PRINTfacets_xridge,   /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */
-  qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, 
-  qh_PRINTnormals, qh_PRINTouter,          /* 'n' 'Fo' 'i' 'm' 'Fm' 'o' */
-  qh_PRINTincidences, qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff, 
-  qh_PRINToptions, qh_PRINTpointintersect, /* 'FO' 'Fp' 'FP' 'p' 'FQ' 'FS' */
-  qh_PRINTpointnearest, qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize, 
-  qh_PRINTsummary, qh_PRINTtriangles,      /* 'Fs' 'Ft' 'Fv' 'FN' 'Fx' */
-  qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes,
-  qh_PRINTEND} qh_PRINT;
-
-/*----------------------------------
-
-  qh_ALL
-    argument flag for selecting everything
-*/
-#define qh_ALL      True
-#define qh_NOupper  True     /* argument for qh_findbest */
-#define qh_IScheckmax  True     /* argument for qh_findbesthorizon */
-#define qh_ISnewfacets  True     /* argument for qh_findbest */
-#define qh_RESETvisible  True     /* argument for qh_resetlists */
-
-/*----------------------------------
-
-  qh_ERR
-    Qhull exit codes, for indicating errors
-*/
-#define qh_ERRnone  0    /* no error occurred during qhull */
-#define qh_ERRinput 1    /* input inconsistency */
-#define qh_ERRsingular 2 /* singular input data */
-#define qh_ERRprec  3    /* precision error */
-#define qh_ERRmem   4    /* insufficient memory, matches mem.h */
-#define qh_ERRqhull 5    /* internal error detected, matches mem.h */
-
-/* ============ -structures- ====================
-   each of the following structures is defined by a typedef
-   all realT and coordT fields occur at the beginning of a structure
-        (otherwise space may be wasted due to alignment)
-   define all flags together and pack into 32-bit number
-*/
-
-typedef struct vertexT vertexT;
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;          /* defined in qset.h */
-#endif
-
-/*----------------------------------
-
-  facetT
-    defines a facet
-
-  notes:
-   qhull() generates the hull as a list of facets.
-
-  topological information:
-    f.previous,next     doubly-linked list of facets
-    f.vertices          set of vertices
-    f.ridges            set of ridges
-    f.neighbors         set of neighbors
-    f.toporient         True if facet has top-orientation (else bottom)
-
-  geometric information:
-    f.offset,normal     hyperplane equation
-    f.maxoutside        offset to outer plane -- all points inside
-    f.center            centrum for testing convexity
-    f.simplicial        True if facet is simplicial
-    f.flipped           True if facet does not include qh.interior_point
-
-  for constructing hull:
-    f.visible           True if facet on list of visible facets (will be deleted)
-    f.newfacet          True if facet on list of newly created facets
-    f.coplanarset       set of points coplanar with this facet
-                        (includes near-inside points for later testing)
-    f.outsideset        set of points outside of this facet
-    f.furthestdist      distance to furthest point of outside set
-    f.visitid           marks visited facets during a loop
-    f.replace           replacement facet for to-be-deleted, visible facets
-    f.samecycle,newcycle cycle of facets for merging into horizon facet
-
-  see below for other flags and fields
-*/
-struct facetT {
-#if !qh_COMPUTEfurthest
-  coordT   furthestdist;/* distance to furthest point of outsideset */
-#endif
-#if qh_MAXoutside
-  coordT   maxoutside;  /* max computed distance of point to facet
-  			Before QHULLfinished this is an approximation
-  			since maxdist not always set for mergefacet
-			Actual outer plane is +DISTround and
-			computed outer plane is +2*DISTround */
-#endif
-  coordT   offset;      /* exact offset of hyperplane from origin */
-  coordT  *normal;      /* normal of hyperplane, hull_dim coefficients */
-			/*   if tricoplanar, shared with a neighbor */
-  union {               /* in order of testing */
-   realT   area;        /* area of facet, only in io.c if  ->isarea */
-   facetT *replace;	/*  replacement facet if ->visible and NEWfacets
-  			     is NULL only if qh_mergedegen_redundant or interior */
-   facetT *samecycle;   /*  cycle of facets from the same visible/horizon intersection,
-   			     if ->newfacet */
-   facetT *newcycle;    /*  in horizon facet, current samecycle of new facets */ 
-   facetT *trivisible;  /* visible facet for ->tricoplanar facets during qh_triangulate() */
-   facetT *triowner;    /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
-  }f;
-  coordT  *center;      /*  centrum for convexity, qh CENTERtype == qh_AScentrum */
-      			/*  Voronoi center, qh CENTERtype == qh_ASvoronoi */
-			/*   if tricoplanar, shared with a neighbor */
-  facetT  *previous;    /* previous facet in the facet_list */
-  facetT  *next;        /* next facet in the facet_list */
-  setT    *vertices;    /* vertices for this facet, inverse sorted by ID 
-                           if simplicial, 1st vertex was apex/furthest */
-  setT    *ridges;      /* explicit ridges for nonsimplicial facets.
-  			   for simplicial facets, neighbors defines ridge */
-  setT    *neighbors;   /* neighbors of the facet.  If simplicial, the kth
-			   neighbor is opposite the kth vertex, and the first
-			   neighbor is the horizon facet for the first vertex*/
-  setT    *outsideset;  /* set of points outside this facet
-		           if non-empty, last point is furthest
-			   if NARROWhull, includes coplanars for partitioning*/
-  setT    *coplanarset; /* set of points coplanar with this facet
-  			   > qh.min_vertex and <= facet->max_outside
-                           a point is assigned to the furthest facet
-		           if non-empty, last point is furthest away */
-  unsigned visitid;     /* visit_id, for visiting all neighbors,
-			   all uses are independent */
-  unsigned id;	        /* unique identifier from qh facet_id */
-  unsigned nummerge:9;  /* number of merges */
-#define qh_MAXnummerge 511 /*     2^9-1, 32 flags total, see "flags:" in io.c */
-  flagT    tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
-			  /*   all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
-			  /*   all tricoplanars share the same apex */
-                          /*   if ->degenerate, does not span facet (one logical ridge) */
-                          /*   one tricoplanar has ->keepcentrum and ->coplanarset */
-                          /*   during qh_triangulate, f.trivisible points to original facet */
-  flagT	   newfacet:1;  /* True if facet on qh newfacet_list (new or merged) */
-  flagT	   visible:1;   /* True if visible facet (will be deleted) */
-  flagT    toporient:1; /* True if created with top orientation
-			   after merging, use ridge orientation */
-  flagT    simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
-  flagT    seen:1;      /* used to perform operations only once, like visitid */
-  flagT    seen2:1;     /* used to perform operations only once, like visitid */
-  flagT	   flipped:1;   /* True if facet is flipped */
-  flagT    upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
-  flagT    notfurthest:1; /* True if last point of outsideset is not furthest*/
-
-/*-------- flags primarily for output ---------*/
-  flagT	   good:1;      /* True if a facet marked good for output */
-  flagT    isarea:1;    /* True if facet->f.area is defined */
-
-/*-------- flags for merging ------------------*/
-  flagT    dupridge:1;  /* True if duplicate ridge in facet */
-  flagT    mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
-                            ->normal defined (also defined for mergeridge2) */
-  flagT    mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */
-  flagT    coplanar:1;  /* True if horizon facet is coplanar at last use */
-  flagT     mergehorizon:1; /* True if will merge into horizon (->coplanar) */
-  flagT	    cycledone:1;/* True if mergecycle_all already done */
-  flagT    tested:1;    /* True if facet convexity has been tested (false after merge */
-  flagT    keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
-  flagT	   newmerge:1;  /* True if facet is newly merged for reducevertices */
-  flagT	   degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
-  flagT	   redundant:1;  /* True if facet is redundant (degen_mergeset) */
-};
-
-
-/*----------------------------------
-
-  ridgeT
-    defines a ridge
-
-  notes:
-  a ridge is DIM3-1 simplex between two neighboring facets.  If the
-  facets are non-simplicial, there may be more than one ridge between
-  two facets.  E.G. a 4-d hypercube has two triangles between each pair
-  of neighboring facets.
-
-  topological information:
-    vertices            a set of vertices
-    top,bottom          neighboring facets with orientation
-
-  geometric information:
-    tested              True if ridge is clearly convex
-    nonconvex           True if ridge is non-convex
-*/
-struct ridgeT {
-  setT    *vertices;    /* vertices belonging to this ridge, inverse sorted by ID 
-                           NULL if a degen ridge (matchsame) */
-  facetT  *top;         /* top facet this ridge is part of */
-  facetT  *bottom;      /* bottom facet this ridge is part of */
-  unsigned id:24;       /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    tested:1;    /* True when ridge is tested for convexity */
-  flagT    nonconvex:1; /* True if getmergeset detected a non-convex neighbor
-			   only one ridge between neighbors may have nonconvex */
-};
-
-/*----------------------------------
-
-  vertexT
-     defines a vertex
-
-  topological information:
-    next,previous       doubly-linked list of all vertices
-    neighbors           set of adjacent facets (only if qh.VERTEXneighbors)
-
-  geometric information:
-    point               array of DIM3 coordinates
-*/
-struct vertexT {
-  vertexT *next;        /* next vertex in vertex_list */
-  vertexT *previous;    /* previous vertex in vertex_list */
-  pointT  *point;       /* hull_dim coordinates (coordT) */
-  setT    *neighbors;   /* neighboring facets of vertex, qh_vertexneighbors()
-			   inits in io.c or after first merge */
-  unsigned visitid; /* for use with qh vertex_visit */
-  unsigned id:24;   /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    seen2:1;     /* another seen flag */
-  flagT    delridge:1;  /* vertex was part of a deleted ridge */
-  flagT	   deleted:1;   /* true if vertex on qh del_vertices */
-  flagT    newlist:1;   /* true if vertex on qh newvertex_list */
-};
-
-/*======= -global variables -qh ============================*/
-
-/*----------------------------------
-
-  qh
-   all global variables for qhull are in qh, qhmem, and qhstat
-
-  notes:
-   qhmem is defined in mem.h and qhstat is defined in stat.h
-   access to qh_qh is via the "qh" macro.  See qh_QHpointer in user.h
-*/
-typedef struct qhT qhT;
-#if qh_QHpointer
-#define qh qh_qh->
-extern qhT *qh_qh;     /* allocated in global.c */
-#else
-#define qh qh_qh.
-extern qhT qh_qh;
-#endif
-
-struct qhT {
-
-/*----------------------------------
-
-  qh constants
-    configuration flags and constants for Qhull
-
-  notes:
-    The user configures Qhull by defining flags.  They are
-    copied into qh by qh_setflags().  qh-quick.htm#options defines the flags.
-*/
-  boolT ALLpoints;        /* true 'Qs' if search all points for initial simplex */
-  boolT ANGLEmerge;	  /* true 'Qa' if sort potential merges by angle */
-  boolT APPROXhull;       /* true 'Wn' if MINoutside set */
-  realT MINoutside;       /*   'Wn' min. distance for an outside point */
-  boolT ATinfinity;       /* true 'Qz' if point num_points-1 is "at-infinity"
-                             for improving precision in Delaunay triangulations */
-  boolT AVOIDold;         /* true 'Q4' if avoid old->new merges */
-  boolT BESToutside;      /* true 'Qf' if partition points into best outsideset */
-  boolT CDDinput;         /* true 'Pc' if input uses CDD format (1.0/offset first) */
-  boolT CDDoutput;        /* true 'PC' if print normals in CDD format (offset first) */
-  boolT CHECKfrequently;  /* true 'Tc' if checking frequently */
-  realT premerge_cos;     /*   'A-n'   cos_max when pre merging */
-  realT postmerge_cos;    /*   'An'    cos_max when post merging */
-  boolT DELAUNAY;         /* true 'd' if computing DELAUNAY triangulation */
-  boolT DOintersections;  /* true 'Gh' if print hyperplane intersections */
-  int   DROPdim;          /* drops dim 'GDn' for 4-d -> 3-d output */
-  boolT FORCEoutput;      /* true 'Po' if forcing output despite degeneracies */
-  int   GOODpoint;        /* 1+n for 'QGn', good facet if visible/not(-) from point n*/
-  pointT *GOODpointp;     /*   the actual point */
-  boolT GOODthreshold;    /* true if qh lower_threshold/upper_threshold defined
-  			     false if qh SPLITthreshold */
-  int   GOODvertex;       /* 1+n, good facet if vertex for point n */
-  pointT *GOODvertexp;     /*   the actual point */
-  boolT HALFspace;        /* true 'Hn,n,n' if halfspace intersection */
-  int   IStracing;        /* trace execution, 0=none, 1=least, 4=most, -1=events */
-  int   KEEParea;         /* 'PAn' number of largest facets to keep */
-  boolT KEEPcoplanar;     /* true 'Qc' if keeping nearest facet for coplanar points */
-  boolT KEEPinside;       /* true 'Qi' if keeping nearest facet for inside points
-			      set automatically if 'd Qc' */
-  int   KEEPmerge;        /* 'PMn' number of facets to keep with most merges */
-  realT KEEPminArea;      /* 'PFn' minimum facet area to keep */
-  realT MAXcoplanar;      /* 'Un' max distance below a facet to be coplanar*/
-  boolT MERGEexact;	  /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */
-  boolT MERGEindependent; /* true 'Q2' if merging independent sets */
-  boolT MERGING;          /* true if exact-, pre- or post-merging, with angle and centrum tests */
-  realT   premerge_centrum;  /*   'C-n' centrum_radius when pre merging.  Default is round-off */
-  realT   postmerge_centrum; /*   'Cn' centrum_radius when post merging.  Default is round-off */
-  boolT MERGEvertices;	  /* true 'Q3' if merging redundant vertices */
-  realT MINvisible;       /* 'Vn' min. distance for a facet to be visible */
-  boolT NOnarrow;         /* true 'Q10' if no special processing for narrow distributions */
-  boolT NOnearinside;     /* true 'Q8' if ignore near-inside points when partitioning */
-  boolT NOpremerge;       /* true 'Q0' if no defaults for C-0 or Qx */
-  boolT ONLYgood; 	  /* true 'Qg' if process points with good visible or horizon facets */
-  boolT ONLYmax; 	  /* true 'Qm' if only process points that increase max_outside */
-  boolT PICKfurthest;     /* true 'Q9' if process furthest of furthest points*/
-  boolT POSTmerge;        /* true if merging after buildhull (Cn or An) */
-  boolT PREmerge;         /* true if merging during buildhull (C-n or A-n) */
-  			/* NOTE: some of these names are similar to qh_PRINT names */
-  boolT PRINTcentrums;	  /* true 'Gc' if printing centrums */
-  boolT PRINTcoplanar;    /* true 'Gp' if printing coplanar points */
-  int	PRINTdim;      	  /* print dimension for Geomview output */
-  boolT PRINTdots;        /* true 'Ga' if printing all points as dots */
-  boolT PRINTgood;        /* true 'Pg' if printing good facets */
-  boolT PRINTinner;	  /* true 'Gi' if printing inner planes */
-  boolT PRINTneighbors;	  /* true 'PG' if printing neighbors of good facets */
-  boolT PRINTnoplanes;	  /* true 'Gn' if printing no planes */
-  boolT PRINToptions1st;  /* true 'FO' if printing options to stderr */
-  boolT PRINTouter;	  /* true 'Go' if printing outer planes */
-  boolT PRINTprecision;   /* false 'Pp' if not reporting precision problems */
-  qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */
-  boolT PRINTridges;      /* true 'Gr' if print ridges */
-  boolT PRINTspheres;     /* true 'Gv' if print vertices as spheres */
-  boolT PRINTstatistics;  /* true 'Ts' if printing statistics to stderr */
-  boolT PRINTsummary;     /* true 's' if printing summary to stderr */
-  boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */
-  boolT PROJECTdelaunay;  /* true if DELAUNAY, no readpoints() and
-			     need projectinput() for Delaunay in qh_init_B */
-  int   PROJECTinput;     /* number of projected dimensions 'bn:0Bn:0' */
-  boolT QUICKhelp;	  /* true if quick help message for degen input */
-  boolT RANDOMdist;       /* true if randomly change distplane and setfacetplane */
-  realT RANDOMfactor;     /*    maximum random perturbation */
-  realT RANDOMa;         /*  qh_randomfactor is randr * RANDOMa + RANDOMb */
-  realT RANDOMb;
-  boolT RANDOMoutside;    /* true if select a random outside point */
-  int	REPORTfreq;       /* buildtracing reports every n facets */
-  int   REPORTfreq2;	  /* tracemerging reports every REPORTfreq/2 facets */
-  int	RERUN;            /* 'TRn' rerun qhull n times (qh.build_cnt) */
-  int	ROTATErandom;	  /* 'QRn' seed, 0 time, >= rotate input */
-  boolT SCALEinput;       /* true 'Qbk' if scaling input */
-  boolT SCALElast;        /* true 'Qbb' if scale last coord to max prev coord */
-  boolT SETroundoff;      /* true 'E' if qh DISTround is predefined */
-  boolT SKIPcheckmax;	  /* true 'Q5' if skip qh_check_maxout */
-  boolT SKIPconvex;       /* true 'Q6' if skip convexity testing during pre-merge */
-  boolT SPLITthresholds;  /* true if upper_/lower_threshold defines a region
-                               used only for printing (not for qh ONLYgood) */
-  int	STOPcone;         /* 'TCn' 1+n for stopping after cone for point n*/
-			  /*       also used by qh_build_withresart for err exit*/
-  int	STOPpoint;        /* 'TVn' 'TV-n' 1+n for stopping after/before(-)
-			                adding point n */
-  int	TESTpoints;	  /* 'QTn' num of test points after qh.num_points.  Test points always coplanar. */
-  boolT TESTvneighbors;   /*  true 'Qv' if test vertex neighbors at end */
-  int   TRACElevel;       /* 'Tn' conditional IStracing level */
-  int	TRACElastrun;	  /*  qh.TRACElevel applies to last qh.RERUN */
-  int   TRACEpoint;       /* 'TPn' start tracing when point n is a vertex */
-  realT TRACEdist;        /* 'TWn' start tracing when merge distance too big */
-  int   TRACEmerge;       /* 'TMn' start tracing before this merge */
-  boolT TRIangulate;	  /* true 'Qt' if triangulate non-simplicial facets */
-  boolT TRInormals;	  /* true 'Q11' if triangulate duplicates normals (sets Qt) */
-  boolT UPPERdelaunay;    /* true 'Qu' if computing furthest-site Delaunay */
-  boolT VERIFYoutput;     /* true 'Tv' if verify output at end of qhull */
-  boolT VIRTUALmemory;    /* true 'Q7' if depth-first processing in buildhull */
-  boolT VORONOI;	  /* true 'v' if computing Voronoi diagram */
-
-  /*--------input constants ---------*/
-  realT AREAfactor;       /* 1/(hull_dim-1)! for converting det's to area */
-  boolT DOcheckmax;       /* true if calling qh_check_maxout (qh_initqhull_globals) */
-  char	*feasible_string;  /* feasible point 'Hn,n,n' for halfspace intersection */
-  coordT *feasible_point;  /*    as coordinates, both malloc'd */
-  boolT GETarea;          /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io.c */
-  boolT KEEPnearinside;   /* true if near-inside points in coplanarset */
-  int 	hull_dim;         /* dimension of hull, set by initbuffers */
-  int 	input_dim;	  /* dimension of input, set by initbuffers */
-  int 	num_points;       /* number of input points */
-  pointT *first_point;    /* array of input points, see POINTSmalloc */
-  boolT POINTSmalloc;     /*   true if qh first_point/num_points allocated */
-  pointT *input_points;   /* copy of original qh.first_point for input points for qh_joggleinput */
-  boolT input_malloc;     /* true if qh input_points malloc'd */
-  char 	qhull_command[256];/* command line that invoked this program */
-  char 	rbox_command[256]; /* command line that produced the input points */
-  char  qhull_options[512];/* descriptive list of options */
-  int   qhull_optionlen;  /*    length of last line */
-  int   qhull_optionsiz;  /*     size of qhull_options before qh_initbuild */
-  boolT VERTEXneighbors;  /* true if maintaining vertex neighbors */
-  boolT ZEROcentrum;      /* true if 'C-0' or 'C-0 Qx'.  sets ZEROall_ok */
-  realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k]
-                             must set either GOODthreshold or SPLITthreshold
-  			     if Delaunay, default is 0.0 for upper envelope */
-  realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */
-  realT *upper_bound;     /* scale point[k] to new upper bound */
-  realT *lower_bound;     /* scale point[k] to new lower bound
-  			     project if both upper_ and lower_bound == 0 */
-
-/*----------------------------------
-
-  qh precision constants
-    precision constants for Qhull
-
-  notes:
-    qh_detroundoff() computes the maximum roundoff error for distance
-    and other computations.  It also sets default values for the
-    qh constants above.
-*/
-  realT ANGLEround;       /* max round off error for angles */
-  realT centrum_radius;   /* max centrum radius for convexity (roundoff added) */
-  realT cos_max;	  /* max cosine for convexity (roundoff added) */
-  realT DISTround;        /* max round off error for distances, 'E' overrides */
-  realT MAXabs_coord;     /* max absolute coordinate */
-  realT MAXlastcoord;     /* max last coordinate for qh_scalelast */
-  realT MAXsumcoord;      /* max sum of coordinates */
-  realT MAXwidth;         /* max rectilinear width of point coordinates */
-  realT MINdenom_1;       /* min. abs. value for 1/x */
-  realT MINdenom;         /*    use divzero if denominator < MINdenom */
-  realT MINdenom_1_2;     /* min. abs. val for 1/x that allows normalization */
-  realT MINdenom_2;       /*    use divzero if denominator < MINdenom_2 */
-  realT MINlastcoord;     /* min. last coordinate for qh_scalelast */
-  boolT NARROWhull;       /* set in qh_initialhull if angle < qh_MAXnarrow */
-  realT *NEARzero;        /* hull_dim array for near zero in gausselim */
-  realT NEARinside;       /* keep points for qh_check_maxout if close to facet */
-  realT ONEmerge;         /* max distance for merging simplicial facets */
-  realT outside_err;      /* application's epsilon for coplanar points
-                             qh_check_bestdist() qh_check_points() reports error if point outside */
-  realT WIDEfacet;        /* size of wide facet for skipping ridge in
-			     area computation and locking centrum */
-  
-/*----------------------------------
-
-  qh internal constants
-    internal constants for Qhull
-*/
-  char qhull[sizeof("qhull")]; /* for checking ownership */
-  void *old_stat;         /* pointer to saved qh_qhstat, qh_save_qhull */
-  jmp_buf errexit;        /* exit label for qh_errexit, defined by setjmp() */
-  char jmpXtra[40];       /* extra bytes in case jmp_buf is defined wrong by compiler */
-  jmp_buf restartexit;    /* restart label for qh_errexit, defined by setjmp() */
-  char jmpXtra2[40];      /* extra bytes in case jmp_buf is defined wrong by compiler*/
-  FILE *fin;              /* pointer to input file, init by qh_meminit */
-  FILE *fout;             /* pointer to output file */
-  FILE *ferr;             /* pointer to error file */
-  pointT *interior_point; /* center point of the initial simplex*/
-  int   normal_size;      /* size in bytes for facet normals and point coords*/
-  int   center_size;      /* size in bytes for Voronoi centers */
-  int   TEMPsize;         /* size for small, temporary sets (in quick mem) */
-
-/*----------------------------------
-
-  qh facet and vertex lists
-    defines lists of facets, new facets, visible facets, vertices, and
-    new vertices.  Includes counts, next ids, and trace ids.
-  see:
-    qh_resetlists()
-*/
-  facetT *facet_list;     /* first facet */
-  facetT  *facet_tail;     /* end of facet_list (dummy facet) */
-  facetT *facet_next;     /* next facet for buildhull()
-    			     previous facets do not have outside sets
-                             NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
-  facetT *newfacet_list;  /* list of new facets to end of facet_list */
-  facetT *visible_list;   /* list of visible facets preceeding newfacet_list,
-                             facet->visible set */
-  int       num_visible;  /* current number of visible facets */
-  unsigned tracefacet_id;  /* set at init, then can print whenever */
-  facetT *tracefacet;     /*   set in newfacet/mergefacet, undone in delfacet*/
-  unsigned tracevertex_id;  /* set at buildtracing, can print whenever */
-  vertexT *tracevertex;     /*   set in newvertex, undone in delvertex*/
-  vertexT *vertex_list;     /* list of all vertices, to vertex_tail */
-  vertexT  *vertex_tail;    /*      end of vertex_list (dummy vertex) */
-  vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
-                             all vertices have 'newlist' set */
-  int 	num_facets;	  /* number of facets in facet_list
-			     includes visble faces (num_visible) */
-  int 	num_vertices;     /* number of vertices in facet_list */
-  int   num_outside;      /* number of points in outsidesets (for tracing and RANDOMoutside)
-                               includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
-  int   num_good;         /* number of good facets (after findgood_all) */
-  unsigned facet_id;      /* ID of next, new facet from newfacet() */
-  unsigned ridge_id;      /* ID of next, new ridge from newridge() */
-  unsigned vertex_id;     /* ID of next, new vertex from newvertex() */
-
-/*----------------------------------
-
-  qh global variables
-    defines minimum and maximum distances, next visit ids, several flags,
-    and other global variables.
-    initialize in qh_initbuild or qh_maxmin if used in qh_buildhull
-*/
-  unsigned long hulltime; /* ignore time to set up input and randomize */
-                          /*   use unsigned to avoid wrap-around errors */
-  boolT ALLOWrestart;     /* true if qh_precision can use qh.restartexit */
-  int   build_cnt;        /* number of calls to qh_initbuild */
-  qh_CENTER CENTERtype;   /* current type of facet->center, qh_CENTER */
-  int 	furthest_id;      /* pointid of furthest point, for tracing */
-  facetT *GOODclosest;    /* closest facet to GOODthreshold in qh_findgood */
-  realT JOGGLEmax;        /* set 'QJn' if randomly joggle input */
-  boolT maxoutdone;       /* set qh_check_maxout(), cleared by qh_addpoint() */
-  realT max_outside;      /* maximum distance from a point to a facet,
-			       before roundoff, not simplicial vertices
-			       actual outer plane is +DISTround and
-			       computed outer plane is +2*DISTround */
-  realT max_vertex;       /* maximum distance (>0) from vertex to a facet,
-			       before roundoff, due to a merge */
-  realT min_vertex;       /* minimum distance (<0) from vertex to a facet,
-			       before roundoff, due to a merge
-			       if qh.JOGGLEmax, qh_makenewplanes sets it
-  			       recomputed if qh.DOcheckmax, default -qh.DISTround */
-  boolT NEWfacets;        /* true while visible facets invalid due to new or merge
-			      from makecone/attachnewfacets to deletevisible */
-  boolT findbestnew;	  /* true if partitioning calls qh_findbestnew */
-  boolT findbest_notsharp; /* true if new facets are at least 90 degrees */
-  boolT NOerrexit;        /* true if qh.errexit is not available */
-  realT PRINTcradius;     /* radius for printing centrums */
-  realT PRINTradius;      /* radius for printing vertex spheres and points */
-  boolT POSTmerging;      /* true when post merging */
-  int 	printoutvar;	  /* temporary variable for qh_printbegin, etc. */
-  int 	printoutnum;	  /* number of facets printed */
-  boolT QHULLfinished;    /* True after qhull() is finished */
-  realT totarea;          /* 'FA': total facet area computed by qh_getarea */
-  realT totvol;           /* 'FA': total volume computed by qh_getarea */
-  unsigned int visit_id;  /* unique ID for searching neighborhoods, */
-  unsigned int vertex_visit; /* unique ID for searching vertices */
-  boolT ZEROall_ok;       /* True if qh_checkzero always succeeds */
-  boolT WAScoplanar;      /* True if qh_partitioncoplanar (qh_check_maxout) */
-  
-/*----------------------------------
-
-  qh global sets
-    defines sets for merging, initial simplex, hashing, extra input points,
-    and deleted vertices
-*/
-  setT *facet_mergeset;   /* temporary set of merges to be done */
-  setT *degen_mergeset;   /* temporary set of degenerate and redundant merges */
-  setT *hash_table;	  /* hash table for matching ridges in qh_matchfacets
-                             size is setsize() */
-  setT *other_points;     /* additional points (first is qh interior_point) */
-  setT *del_vertices;     /* vertices to partition and delete with visible
-                             facets.  Have deleted set for checkfacet */
-
-/*----------------------------------
-
-  qh global buffers
-    defines buffers for maxtrix operations, input, and error messages
-*/
-  coordT *gm_matrix;      /* (dim+1)Xdim matrix for geom.c */
-  coordT **gm_row;        /* array of gm_matrix rows */
-  char* line;             /* malloc'd input line of maxline+1 chars */
-  int maxline;
-  coordT *half_space;     /* malloc'd input array for halfspace (qh normal_size+coordT) */
-  coordT *temp_malloc;    /* malloc'd input array for points */
-  
-/*----------------------------------
-
-  qh static variables
-    defines static variables for individual functions
-
-  notes:
-    do not use 'static' within a function.  Multiple instances of qhull
-    may exist.
-
-    do not assume zero initialization, 'QPn' may cause a restart
-*/
-  boolT ERREXITcalled;    /* true during errexit (prevents duplicate calls */
-  boolT firstcentrum; 	  /* for qh_printcentrum */
-  realT last_low;         /* qh_scalelast parameters for qh_setdelaunay */
-  realT last_high;
-  realT last_newhigh;
-  unsigned lastreport;    /* for qh_buildtracing */
-  int mergereport;        /* for qh_tracemerging */
-  boolT old_randomdist;   /* save RANDOMdist when io, tracing, or statistics */
-  int   ridgeoutnum;      /* number of ridges in 4OFF output */
-  void *old_qhstat;       /* for saving qh_qhstat in save_qhull() */
-  setT *old_tempstack;     /* for saving qhmem.tempstack in save_qhull */
-  setT *coplanarset;      /* set of coplanar facets for searching qh_findbesthorizon() */
-};
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-
-  otherfacet_(ridge, facet)
-    return neighboring facet for a ridge in facet
-*/
-#define otherfacet_(ridge, facet) \
-                        (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
-
-/*----------------------------------
-
-  getid_(p)
-    return ID for facet, ridge, or vertex
-    return MAXINT if NULL (-1 causes type conversion error )
-*/
-#define getid_(p)       ((p) ? (p)->id : -1)
-
-/*============== FORALL macros ===================*/
-
-/*----------------------------------
-
-  FORALLfacets { ... }
-    assign 'facet' to each facet in qh.facet_list
-
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-
-  see:
-    FORALLfacet_( facetlist )
-*/
-#define FORALLfacets for (facet=qh facet_list;facet && facet->next;facet=facet->next)
-
-/*----------------------------------
-
-  FORALLpoints { ... }
-    assign 'point' to each point in qh.first_point, qh.num_points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoints FORALLpoint_(qh first_point, qh num_points)
-
-/*----------------------------------
-
-  FORALLpoint_( points, num) { ... }
-    assign 'point' to each point in points array of num points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoint_(points, num) for(point= (points), \
-      pointtemp= (points)+qh hull_dim*(num); point < pointtemp; point += qh hull_dim)
-
-/*----------------------------------
-
-  FORALLvertices { ... }
-    assign 'vertex' to each vertex in qh.vertex_list
-
-  declare:
-    vertexT *vertex;
-
-  notes:
-    assumes qh.vertex_list terminated with a sentinel
-*/
-#define FORALLvertices for (vertex=qh vertex_list;vertex && vertex->next;vertex= vertex->next)
-
-/*----------------------------------
-
-  FOREACHfacet_( facets ) { ... }
-    assign 'facet' to each facet in facets
-
-  declare:
-    facetT *facet, **facetp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHfacet_(facets)    FOREACHsetelement_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_( facet ) { ... }
-    assign 'neighbor' to each neighbor in facet->neighbors
-
-  FOREACHneighbor_( vertex ) { ... }
-    assign 'neighbor' to each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor, **neighborp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighbor_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_( points ) { ... }
-    assign 'point' to each point in points set
-
-  declare:
-    pointT *point, **pointp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHpoint_(points)    FOREACHsetelement_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_( ridges ) { ... }
-    assign 'ridge' to each ridge in ridges set
-
-  declare:
-    ridgeT *ridge, **ridgep;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHridge_(ridges)    FOREACHsetelement_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_( vertices ) { ... }
-    assign 'vertex' to each vertex in vertices set
-
-  declare:
-    vertexT *vertex, **vertexp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
-
-/*----------------------------------
-
-  FOREACHfacet_i_( facets ) { ... }
-    assign 'facet' and 'facet_i' for each facet in facets set
-
-  declare:
-    facetT *facet;
-    int     facet_n, facet_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHfacet_i_(facets)    FOREACHsetelement_i_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_i_( facet ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
-
-  FOREACHneighbor_i_( vertex ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor;
-    int     neighbor_n, neighbor_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHneighbor_i_(facet)  FOREACHsetelement_i_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_i_( points ) { ... }
-    assign 'point' and 'point_i' for each point in points set
-
-  declare:
-    pointT *point;
-    int     point_n, point_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHpoint_i_(points)    FOREACHsetelement_i_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_i_( ridges ) { ... }
-    assign 'ridge' and 'ridge_i' for each ridge in ridges set
-
-  declare:
-    ridgeT *ridge;
-    int     ridge_n, ridge_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHridge_i_(ridges)    FOREACHsetelement_i_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_i_( vertices ) { ... }
-    assign 'vertex' and 'vertex_i' for each vertex in vertices set
-
-  declare:
-    vertexT *vertex;
-    int     vertex_n, vertex_i;
-
-  see:
-    FOREACHsetelement_i_
- */
-#define FOREACHvertex_i_(vertices) FOREACHsetelement_i_(vertexT, vertices,vertex)
-
-/********* -qhull.c prototypes (duplicated from qhull_a.h) **********************/
-
-void    qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void	qh_printsummary(FILE *fp);
-
-/********* -user.c prototypes (alphabetical) **********************/
-
-void 	qh_errexit(int exitcode, facetT *facet, ridgeT *ridge);
-void 	qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
-int     qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc,
-		char *qhull_cmd, FILE *outfile, FILE *errfile);
-void    qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall);
-void 	qh_user_memsizes (void);
-
-/***** -geom.c/geom2.c prototypes (duplicated from geom.h) ****************/
-
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT newfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet,
-                     realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-void	qh_printsummary(FILE *fp);
-void    qh_projectinput (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_scaleinput (void);
-void    qh_setdelaunay (int dim, int count, pointT *points);
-coordT  *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-
-/***** -global.c prototypes (alphabetical) ***********************/
-
-unsigned long qh_clock (void);
-void 	qh_checkflags (char *command, char *hiddenflags);
-void 	qh_freebuffers (void);
-void    qh_freeqhull (boolT allmem);
-void    qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
-void    qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_init_qhull_command (int argc, char *argv[]);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_initflags (char *command);
-void 	qh_initqhull_buffers (void);
-void 	qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc);
-void    qh_initqhull_mem (void);
-void 	qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile);
-void 	qh_initthresholds (char *command);
-void    qh_option (char *option, int *i, realT *r);
-#if qh_QHpointer
-void 	qh_restore_qhull (qhT **oldqh);
-qhT    *qh_save_qhull (void);
-#endif
-
-/***** -io.c prototypes (duplicated from io.h) ***********************/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void	qh_produce_output(void);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-
-
-/********* -mem.c prototypes (duplicated from mem.h) **********************/
-
-void qh_meminit (FILE *ferr);
-void qh_memfreeshort (int *curlong, int *totlong);
-
-/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/
-
-void    qh_check_output (void);
-void    qh_check_points (void);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-pointT *qh_point (int id);
-setT   *qh_pointfacet (void /*qh.facet_list*/);
-int     qh_pointid (pointT *point);
-setT   *qh_pointvertex (void /*qh.facet_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-
-/********* -stat.c prototypes (duplicated from stat.h) **********************/
-
-void    qh_collectstatistics (void);
-void    qh_printallstatistics (FILE *fp, char *string);
-
-#endif /* qhDEFqhull */
diff --git a/extern/qhull/src/qhull_a.h b/extern/qhull/src/qhull_a.h
deleted file mode 100644
index d4e69b071be..00000000000
--- a/extern/qhull/src/qhull_a.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
  ---------------------------------
-
-   qhull_a.h 
-   all header files for compiling qhull
-
-   see qh-qhull.htm
-
-   see qhull.h for user-level definitions
-   
-   see user.h for user-defineable constants
-   
-   defines internal functions for qhull.c global.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   Notes:  grep for ((" and (" to catch fprintf("lkasdjf");
-           full parens around (x?y:z)
-	   use '#include qhull/qhull_a.h' to avoid name clashes
-*/
-
-#ifndef qhDEFqhulla
-#define qhDEFqhulla
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include     /* some compilers will not need float.h */
-#include 
-#include 
-#include 
-/*** uncomment here and qset.c
-     if string.h does not define memcpy()
-#include 
-*/
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-#include "geom.h"
-#include "merge.h"
-#include "poly.h"
-#include "io.h"
-#include "stat.h"
-
-#if qh_CLOCKtype == 2  /* defined in user.h from qhull.h */
-#include 
-#include 
-#include 
-#endif
-
-#ifdef _MSC_VER  /* Microsoft Visual C++ */
-#pragma warning( disable : 4056)  /* float constant expression.  Looks like a compiler bug */
-#pragma warning( disable : 4146)  /* unary minus applied to unsigned type */
-#pragma warning( disable : 4244)  /* conversion from 'unsigned long' to 'real' */
-#pragma warning( disable : 4305)  /* conversion from 'const double' to 'float' */
-#endif
-
-/* ======= -macros- =========== */
-
-/*----------------------------------
-  
-  traceN((fp.ferr, "format\n", vars));  
-    calls fprintf if qh.IStracing >= N
-  
-  notes:
-    removing tracing reduces code size but doesn't change execution speed
-*/
-#ifndef qh_NOtrace
-#define trace0(args) {if (qh IStracing) fprintf args;}
-#define trace1(args) {if (qh IStracing >= 1) fprintf args;}
-#define trace2(args) {if (qh IStracing >= 2) fprintf args;}
-#define trace3(args) {if (qh IStracing >= 3) fprintf args;}
-#define trace4(args) {if (qh IStracing >= 4) fprintf args;}
-#define trace5(args) {if (qh IStracing >= 5) fprintf args;}
-#else /* qh_NOtrace */
-#define trace0(args) {}
-#define trace1(args) {}
-#define trace2(args) {}
-#define trace3(args) {}
-#define trace4(args) {}
-#define trace5(args) {}
-#endif /* qh_NOtrace */
-
-/***** -qhull.c prototypes (alphabetical after qhull) ********************/
-
-void 	qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void 	qh_buildhull(void);
-void    qh_buildtracing (pointT *furthest, facetT *facet);
-void    qh_build_withrestart (void);
-void 	qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet);
-void    qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
-pointT *qh_nextfurthest (facetT **visible);
-void 	qh_partitionall(setT *vertices, pointT *points,int npoints);
-void    qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist);
-void    qh_partitionpoint (pointT *point, facetT *facet);
-void 	qh_partitionvisible(boolT allpoints, int *numpoints);
-void    qh_precision (char *reason);
-void	qh_printsummary(FILE *fp);
-
-/***** -global.c internal prototypes (alphabetical) ***********************/
-
-void    qh_appendprint (qh_PRINT format);
-void 	qh_freebuild (boolT allmem);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-int     qh_strtol (const char *s, char **endp);
-double  qh_strtod (const char *s, char **endp);
-
-/***** -stat.c internal prototypes (alphabetical) ***********************/
-
-void	qh_allstatA (void);
-void	qh_allstatB (void);
-void	qh_allstatC (void);
-void	qh_allstatD (void);
-void	qh_allstatE (void);
-void	qh_allstatE2 (void);
-void	qh_allstatF (void);
-void	qh_allstatG (void);
-void	qh_allstatH (void);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-
-#endif /* qhDEFqhulla */
diff --git a/extern/qhull/src/qhull_interface.cpp b/extern/qhull/src/qhull_interface.cpp
deleted file mode 100644
index 6ecc640e82b..00000000000
--- a/extern/qhull/src/qhull_interface.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
  ---------------------------------
-*/
-
-#include 
-#include 
-
-//--- Include qhull, so it works from with in a C++ source file
-//---
-//--- In MVC one cannot just do:
-//---
-//---    extern "C"
-//---    {
-//---      #include "qhull_a.h"
-//---    }
-//---
-//--- Because qhull_a.h includes math.h, which can not appear
-//--- inside a extern "C" declaration.
-//---
-//--- Maybe that why Numerical recipes in C avoid this problem, by removing
-//--- standard include headers from its header files and add them in the
-//--- respective source files instead.
-//---
-//--- [K. Erleben]
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#if defined(__cplusplus)
-}
-#endif
-
-/*********************************************************************/
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*********************************************************************/
-
-void compute_convex_hull(void)
-{  
-	int dim;  	              /* dimension of points */
-	int numpoints;            /* number of points */
-	coordT *points;           /* array of coordinates for each point */ 
-	boolT ismalloc;           /* True if qhull should free points in qh_freeqhull() or reallocation */ 
-	char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
-	FILE *outfile= stdout;    /* output from qh_produce_output()			
-	                             use NULL to skip qh_produce_output() */ 
-	FILE *errfile= stderr;    /* error messages from qhull code */ 
-	int exitcode;             /* 0 if no error from qhull */
-	facetT *facet;	          /* set by FORALLfacets */
-	int curlong, totlong;	  /* memory remaining after qh_memfreeshort */
-
-   	/* initialize dim, numpoints, points[], ismalloc here */
-	exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-							flags, outfile, errfile);
-	if (!exitcode) { /* if no error */ 
-		/* 'qh facet_list' contains the convex hull */
-		FORALLfacets {
-			/* ... your code ... */ 
-		}
-	}
-	qh_freeqhull(!qh_ALL);  
-	qh_memfreeshort (&curlong, &totlong);
-	if (curlong || totlong)
-		fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", 
-		             totlong, curlong);
-};
-
-/*********************************************************************/
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*********************************************************************/
-
-void main() 
-{ 
-	cout << "Hello world" << endl;
-	
-	cout << "Press any key..." << endl;  
-	
-	while(!_kbhit());
-
-};
diff --git a/extern/qhull/src/qset.c b/extern/qhull/src/qset.c
deleted file mode 100644
index 9e78464c07e..00000000000
--- a/extern/qhull/src/qset.c
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*
  ---------------------------------
-
-   qset.c 
-   implements set manipulations needed for quickhull 
-
-   see qh-set.htm and qset.h
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include 
-#include 
-/*** uncomment here and qhull_a.h 
-     if string.h does not define memcpy()
-#include 
-*/
-#include "qset.h"
-#include "mem.h"
-
-#ifndef qhDEFqhull
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-void    qh_errexit(int exitcode, facetT *, ridgeT *);
-#endif
-
-/*=============== internal macros ===========================*/
-
-/*---------------------------------
-   
-  SETsizeaddr_(set) 
-    return pointer to actual size+1 of set (set CANNOT be NULL!!)
-      
-  notes:
-    *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
-*/
-#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize].i))
-
-/*============ functions in alphabetical order ===================*/
-  
-/*----------------------------------
-   
-  qh_setaddnth( setp, nth, newelem)
-    adds newelem as n'th element of sorted or unsorted *setp
-      
-  notes:
-    *setp and newelem must be defined
-    *setp may be a temp set
-    nth=0 is first element
-    errors if nth is out of bounds
-   
-  design:
-    expand *setp if empty or full
-    move tail of *setp up one
-    insert newelem
-*/
-void qh_setaddnth(setT **setp, int nth, void *newelem) {
-  int *sizep, oldsize, i;
-  void **oldp, **newp;
-
-  if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
-    qh_setlarger(setp);
-    sizep= SETsizeaddr_(*setp);
-  }
-  oldsize= *sizep - 1;
-  if (nth < 0 || nth > oldsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", *setp);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  (*sizep)++;
-  oldp= SETelemaddr_(*setp, oldsize, void);   /* NULL */
-  newp= oldp+1;
-  for (i= oldsize-nth+1; i--; )  /* move at least NULL  */
-    *(newp--)= *(oldp--);       /* may overwrite *sizep */
-  *newp= newelem;
-} /* setaddnth */
-
-
-/*----------------------------------
-   
-  setaddsorted( setp, newelem )
-    adds an newelem into sorted *setp
-      
-  notes:
-    *setp and newelem must be defined
-    *setp may be a temp set
-    nop if newelem already in set
-  
-  design:
-    find newelem's position in *setp
-    insert newelem
-*/
-void qh_setaddsorted(setT **setp, void *newelem) {
-  int newindex=0;
-  void *elem, **elemp;
-
-  FOREACHelem_(*setp) {          /* could use binary search instead */
-    if (elem < newelem)
-      newindex++;
-    else if (elem == newelem)
-      return;
-    else
-      break;
-  }
-  qh_setaddnth(setp, newindex, newelem);
-} /* setaddsorted */
-
-
-/*---------------------------------
-  
-  qh_setappend( setp, newelem)
-    append newelem to *setp
-
-  notes:
-    *setp may be a temp set
-    *setp and newelem may be NULL
-
-  design:
-    expand *setp if empty or full
-    append newelem to *setp
-    
-*/
-void qh_setappend(setT **setp, void *newelem) {
-  int *sizep;
-  void **endp;
-
-  if (!newelem)
-    return;
-  if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
-    qh_setlarger(setp);
-    sizep= SETsizeaddr_(*setp);
-  }
-  *(endp= &((*setp)->e[(*sizep)++ - 1].p))= newelem;
-  *(++endp)= NULL;
-} /* setappend */
-
-/*---------------------------------
-  
-  qh_setappend_set( setp, setA) 
-    appends setA to *setp
-
-  notes:
-    *setp can not be a temp set
-    *setp and setA may be NULL
-
-  design:
-    setup for copy
-    expand *setp if it is too small
-    append all elements of setA to *setp 
-*/
-void qh_setappend_set(setT **setp, setT *setA) {
-  int *sizep, sizeA, size;
-  setT *oldset;
-
-  if (!setA)
-    return;
-  SETreturnsize_(setA, sizeA);
-  if (!*setp)
-    *setp= qh_setnew (sizeA);
-  sizep= SETsizeaddr_(*setp);
-  if (!(size= *sizep))
-    size= (*setp)->maxsize;
-  else
-    size--;
-  if (size + sizeA > (*setp)->maxsize) {
-    oldset= *setp;
-    *setp= qh_setcopy (oldset, sizeA);
-    qh_setfree (&oldset);
-    sizep= SETsizeaddr_(*setp);
-  }
-  *sizep= size+sizeA+1;   /* memcpy may overwrite */
-  if (sizeA > 0) 
-    memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), SETelemsize *(sizeA+1));
-} /* setappend_set */
-
-
-/*---------------------------------
-  
-  qh_setappend2ndlast( setp, newelem )
-    makes newelem the next to the last element in *setp
-
-  notes:
-    *setp must have at least one element
-    newelem must be defined
-    *setp may be a temp set
-
-  design:
-    expand *setp if empty or full
-    move last element of *setp up one
-    insert newelem
-*/
-void qh_setappend2ndlast(setT **setp, void *newelem) {
-  int *sizep;
-  void **endp, **lastp;
-  
-  if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
-    qh_setlarger(setp);
-    sizep= SETsizeaddr_(*setp);
-  }
-  endp= SETelemaddr_(*setp, (*sizep)++ -1, void); /* NULL */
-  lastp= endp-1;
-  *(endp++)= *lastp;
-  *endp= NULL;    /* may overwrite *sizep */
-  *lastp= newelem;
-} /* setappend2ndlast */
-
-
-/*---------------------------------
-  
-  qh_setcheck( set, typename, id ) 
-    check set for validity
-    report errors with typename and id
-
-  design:
-    checks that maxsize, actual size, and NULL terminator agree
-*/
-void qh_setcheck(setT *set, char *tname, int id) {
-  int maxsize, size;
-  int waserr= 0;
-
-  if (!set)
-    return;
-  SETreturnsize_(set, size);
-  maxsize= set->maxsize;
-  if (size > maxsize || !maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): actual size %d of %s%d is greater than max size %d\n",
-	     size, tname, id, maxsize);
-    waserr= 1;
-  }else if (set->e[size].p) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): %s%d (size %d max %d) is not null terminated.\n",
-	     tname, id, maxsize, size-1);
-    waserr= 1;
-  }
-  if (waserr) {
-    qh_setprint (qhmem.ferr, "ERRONEOUS", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-} /* setcheck */
-
-
-/*---------------------------------
-  
-  qh_setcompact( set )
-    remove internal NULLs from an unsorted set
-
-  returns:
-    updated set
-
-  notes:
-    set may be NULL
-    it would be faster to swap tail of set into holes, like qh_setdel
-
-  design:
-    setup pointers into set
-    skip NULLs while copying elements to start of set 
-    update the actual size
-*/
-void qh_setcompact(setT *set) {
-  int size;
-  void **destp, **elemp, **endp, **firstp;
-
-  if (!set)
-    return;
-  SETreturnsize_(set, size);
-  destp= elemp= firstp= SETaddr_(set, void);
-  endp= destp + size;
-  while (1) {
-    if (!(*destp++ = *elemp++)) {
-      destp--;
-      if (elemp > endp)
-	break;
-    }
-  }
-  qh_settruncate (set, destp-firstp);
-} /* setcompact */
-
-
-/*---------------------------------
-  
-  qh_setcopy( set, extra )
-    make a copy of a sorted or unsorted set with extra slots
-
-  returns:
-    new set
-
-  design:
-    create a newset with extra slots
-    copy the elements to the newset
-    
-*/
-setT *qh_setcopy(setT *set, int extra) {
-  setT *newset;
-  int size;
-
-  if (extra < 0)
-    extra= 0;
-  SETreturnsize_(set, size);
-  newset= qh_setnew(size+extra);
-  *SETsizeaddr_(newset)= size+1;    /* memcpy may overwrite */
-  memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), SETelemsize *(size+1));
-  return (newset);
-} /* setcopy */
-
-
-/*---------------------------------
-  
-  qh_setdel( set, oldelem )
-    delete oldelem from an unsorted set
-
-  returns:
-    returns oldelem if found
-    returns NULL otherwise
-    
-  notes:
-    set may be NULL
-    oldelem must not be NULL;
-    only deletes one copy of oldelem in set
-     
-  design:
-    locate oldelem
-    update actual size if it was full
-    move the last element to the oldelem's location
-*/
-void *qh_setdel(setT *set, void *oldelem) {
-  void **elemp, **lastp;
-  int *sizep;
-
-  if (!set)
-    return NULL;
-  elemp= SETaddr_(set, void);
-  while (*elemp != oldelem && *elemp)
-    elemp++;
-  if (*elemp) {
-    sizep= SETsizeaddr_(set);
-    if (!(*sizep)--)         /*  if was a full set */
-      *sizep= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
-    lastp= SETelemaddr_(set, *sizep-1, void);
-    *elemp= *lastp;      /* may overwrite itself */
-    *lastp= NULL;
-    return oldelem;
-  }
-  return NULL;
-} /* setdel */
-
-
-/*---------------------------------
-  
-  qh_setdellast( set) 
-    return last element of set or NULL
-
-  notes:
-    deletes element from set
-    set may be NULL
-
-  design:
-    return NULL if empty
-    if full set
-      delete last element and set actual size
-    else
-      delete last element and update actual size 
-*/
-void *qh_setdellast(setT *set) {
-  int setsize;  /* actually, actual_size + 1 */
-  int maxsize;
-  int *sizep;
-  void *returnvalue;
-  
-  if (!set || !(set->e[0].p))
-    return NULL;
-  sizep= SETsizeaddr_(set);
-  if ((setsize= *sizep)) {
-    returnvalue= set->e[setsize - 2].p;
-    set->e[setsize - 2].p= NULL;
-    (*sizep)--;
-  }else {
-    maxsize= set->maxsize;
-    returnvalue= set->e[maxsize - 1].p;
-    set->e[maxsize - 1].p= NULL;
-    *sizep= maxsize;
-  }
-  return returnvalue;
-} /* setdellast */
-
-
-/*---------------------------------
-  
-  qh_setdelnth( set, nth )
-    deletes nth element from unsorted set 
-    0 is first element
-
-  returns:
-    returns the element (needs type conversion)
-
-  notes:
-    errors if nth invalid
-
-  design:
-    setup points and check nth
-    delete nth element and overwrite with last element
-*/
-void *qh_setdelnth(setT *set, int nth) {
-  void **elemp, **lastp, *elem;
-  int *sizep;
-
-
-  elemp= SETelemaddr_(set, nth, void);
-  sizep= SETsizeaddr_(set);
-  if (!(*sizep)--)         /*  if was a full set */
-    *sizep= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
-  if (nth < 0 || nth >= *sizep) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  lastp= SETelemaddr_(set, *sizep-1, void);
-  elem= *elemp;
-  *elemp= *lastp;      /* may overwrite itself */
-  *lastp= NULL;
-  return elem;
-} /* setdelnth */
-
-/*---------------------------------
-  
-  qh_setdelnthsorted( set, nth )
-    deletes nth element from sorted set
-
-  returns:
-    returns the element (use type conversion)
-  
-  notes:
-    errors if nth invalid
-    
-  see also: 
-    setnew_delnthsorted
-
-  design:
-    setup points and check nth
-    copy remaining elements down one
-    update actual size  
-*/
-void *qh_setdelnthsorted(setT *set, int nth) {
-  void **newp, **oldp, *elem;
-  int *sizep;
-
-  sizep= SETsizeaddr_(set);
-  if (nth < 0 || (*sizep && nth >= *sizep-1) || nth >= set->maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  newp= SETelemaddr_(set, nth, void);
-  elem= *newp;
-  oldp= newp+1;
-  while ((*(newp++)= *(oldp++)))
-    ; /* copy remaining elements and NULL */
-  if (!(*sizep)--)         /*  if was a full set */
-    *sizep= set->maxsize;  /*     *sizep= (max size-1)+ 1 */
-  return elem;
-} /* setdelnthsorted */
-
-
-/*---------------------------------
-  
-  qh_setdelsorted( set, oldelem )
-    deletes oldelem from sorted set
-
-  returns:
-    returns oldelem if it was deleted
-  
-  notes:
-    set may be NULL
-
-  design:
-    locate oldelem in set
-    copy remaining elements down one
-    update actual size  
-*/
-void *qh_setdelsorted(setT *set, void *oldelem) {
-  void **newp, **oldp;
-  int *sizep;
-
-  if (!set)
-    return NULL;
-  newp= SETaddr_(set, void);
-  while(*newp != oldelem && *newp)
-    newp++;
-  if (*newp) {
-    oldp= newp+1;
-    while ((*(newp++)= *(oldp++)))
-      ; /* copy remaining elements */
-    sizep= SETsizeaddr_(set);
-    if (!(*sizep)--)    /*  if was a full set */
-      *sizep= set->maxsize;  /*     *sizep= (max size-1)+ 1 */
-    return oldelem;
-  }
-  return NULL;
-} /* setdelsorted */
-
-
-/*---------------------------------
-  
-  qh_setduplicate( set, elemsize )
-    duplicate a set of elemsize elements
-
-  notes:
-    use setcopy if retaining old elements
-
-  design:
-    create a new set
-    for each elem of the old set
-      create a newelem
-      append newelem to newset
-*/
-setT *qh_setduplicate (setT *set, int elemsize) {
-  void		*elem, **elemp, *newElem;
-  setT		*newSet;
-  int		size;
-  
-  if (!(size= qh_setsize (set)))
-    return NULL;
-  newSet= qh_setnew (size);
-  FOREACHelem_(set) {
-    newElem= qh_memalloc (elemsize);
-    memcpy (newElem, elem, elemsize);
-    qh_setappend (&newSet, newElem);
-  }
-  return newSet;
-} /* setduplicate */
-
-
-/*---------------------------------
-  
-  qh_setequal(  )
-    returns 1 if two sorted sets are equal, otherwise returns 0
-
-  notes:
-    either set may be NULL
-
-  design:
-    check size of each set
-    setup pointers
-    compare elements of each set
-*/
-int qh_setequal(setT *setA, setT *setB) {
-  void **elemAp, **elemBp;
-  int sizeA, sizeB;
-  
-  SETreturnsize_(setA, sizeA);
-  SETreturnsize_(setB, sizeB);
-  if (sizeA != sizeB)
-    return 0;
-  if (!sizeA)
-    return 1;
-  elemAp= SETaddr_(setA, void);
-  elemBp= SETaddr_(setB, void);
-  if (!memcmp((char *)elemAp, (char *)elemBp, sizeA*SETelemsize))
-    return 1;
-  return 0;
-} /* setequal */
-
-
-/*---------------------------------
-  
-  qh_setequal_except( setA, skipelemA, setB, skipelemB )
-    returns 1 if sorted setA and setB are equal except for skipelemA & B
-
-  returns:
-    false if either skipelemA or skipelemB are missing
-  
-  notes:
-    neither set may be NULL
-
-    if skipelemB is NULL, 
-      can skip any one element of setB
-
-  design:
-    setup pointers
-    search for skipelemA, skipelemB, and mismatches
-    check results
-*/
-int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB) {
-  void **elemA, **elemB;
-  int skip=0;
-
-  elemA= SETaddr_(setA, void);
-  elemB= SETaddr_(setB, void);
-  while (1) {
-    if (*elemA == skipelemA) {
-      skip++;
-      elemA++;
-    }
-    if (skipelemB) {
-      if (*elemB == skipelemB) {
-        skip++;
-        elemB++;
-      }
-    }else if (*elemA != *elemB) {
-      skip++;
-      if (!(skipelemB= *elemB++))
-        return 0;
-    }
-    if (!*elemA)
-      break;
-    if (*elemA++ != *elemB++) 
-      return 0;
-  }
-  if (skip != 2 || *elemB)
-    return 0;
-  return 1;
-} /* setequal_except */
-  
-
-/*---------------------------------
-  
-  qh_setequal_skip( setA, skipA, setB, skipB )
-    returns 1 if sorted setA and setB are equal except for elements skipA & B
-
-  returns:
-    false if different size
-
-  notes:
-    neither set may be NULL
-
-  design:
-    setup pointers
-    search for mismatches while skipping skipA and skipB
-*/
-int qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB) {
-  void **elemA, **elemB, **skipAp, **skipBp;
-
-  elemA= SETaddr_(setA, void);
-  elemB= SETaddr_(setB, void);
-  skipAp= SETelemaddr_(setA, skipA, void);
-  skipBp= SETelemaddr_(setB, skipB, void);
-  while (1) {
-    if (elemA == skipAp)
-      elemA++;
-    if (elemB == skipBp)
-      elemB++;
-    if (!*elemA)
-      break;
-    if (*elemA++ != *elemB++) 
-      return 0;
-  }
-  if (*elemB)
-    return 0;
-  return 1;
-} /* setequal_skip */
-  
-
-/*---------------------------------
-  
-  qh_setfree( setp )
-    frees the space occupied by a sorted or unsorted set
-
-  returns:
-    sets setp to NULL
-    
-  notes:
-    set may be NULL
-
-  design:
-    free array
-    free set
-*/
-void qh_setfree(setT **setp) {
-  int size;
-  void **freelistp;  /* used !qh_NOmem */
-  
-  if (*setp) {
-    size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; 
-    if (size <= qhmem.LASTsize) {
-      qh_memfree_(*setp, size, freelistp);
-    }else
-      qh_memfree (*setp, size);
-    *setp= NULL;
-  }
-} /* setfree */
-
-
-/*---------------------------------
-  
-  qh_setfree2( setp, elemsize )
-    frees the space occupied by a set and its elements
-
-  notes:
-    set may be NULL
-
-  design:
-    free each element
-    free set 
-*/
-void qh_setfree2 (setT **setp, int elemsize) {
-  void		*elem, **elemp;
-  
-  FOREACHelem_(*setp)
-    qh_memfree (elem, elemsize);
-  qh_setfree (setp);
-} /* setfree2 */
-
-
-      
-/*---------------------------------
-  
-  qh_setfreelong( setp )
-    frees a set only if it's in long memory
-
-  returns:
-    sets setp to NULL if it is freed
-    
-  notes:
-    set may be NULL
-
-  design:
-    if set is large
-      free it    
-*/
-void qh_setfreelong(setT **setp) {
-  int size;
-  
-  if (*setp) {
-    size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; 
-    if (size > qhmem.LASTsize) {
-      qh_memfree (*setp, size);
-      *setp= NULL;
-    }
-  }
-} /* setfreelong */
-
-
-/*---------------------------------
-  
-  qh_setin( set, setelem )
-    returns 1 if setelem is in a set, 0 otherwise
-
-  notes:
-    set may be NULL or unsorted
-
-  design:
-    scans set for setelem
-*/
-int qh_setin(setT *set, void *setelem) {
-  void *elem, **elemp;
-
-  FOREACHelem_(set) {
-    if (elem == setelem)
-      return 1;
-  }
-  return 0;
-} /* setin */
-
-
-/*---------------------------------
-  
-  qh_setindex( set, atelem )
-    returns the index of atelem in set.   
-    returns -1, if not in set or maxsize wrong
-
-  notes:
-    set may be NULL and may contain nulls.
-
-  design:
-    checks maxsize
-    scans set for atelem
-*/
-int qh_setindex(setT *set, void *atelem) {
-  void **elem;
-  int size, i;
-
-  SETreturnsize_(set, size);
-  if (size > set->maxsize)
-    return -1;
-  elem= SETaddr_(set, void);
-  for (i=0; i < size; i++) {
-    if (*elem++ == atelem)
-      return i;
-  }
-  return -1;
-} /* setindex */
-
-
-/*---------------------------------
-  
-  qh_setlarger( oldsetp )
-    returns a larger set that contains all elements of *oldsetp
-
-  notes:
-    the set is at least twice as large
-    if temp set, updates qhmem.tempstack
-
-  design:
-    creates a new set
-    copies the old set to the new set
-    updates pointers in tempstack
-    deletes the old set
-*/
-void qh_setlarger(setT **oldsetp) {
-  int size= 1, *sizep;
-  setT *newset, *set, **setp, *oldset;
-  void **oldp, **newp;
-
-  if (*oldsetp) {
-    oldset= *oldsetp;
-    SETreturnsize_(oldset, size);
-    qhmem.cntlarger++;
-    qhmem.totlarger += size+1;
-    newset= qh_setnew(2 * size);
-    oldp= SETaddr_(oldset, void);
-    newp= SETaddr_(newset, void);
-    memcpy((char *)newp, (char *)oldp, (size+1) * SETelemsize);
-    sizep= SETsizeaddr_(newset);
-    *sizep= size+1;
-    FOREACHset_((setT *)qhmem.tempstack) {
-      if (set == oldset)
-	*(setp-1)= newset;
-    }
-    qh_setfree(oldsetp);
-  }else 
-    newset= qh_setnew(3);
-  *oldsetp= newset;
-} /* setlarger */
-
-
-/*---------------------------------
-  
-  qh_setlast(  )
-    return last element of set or NULL (use type conversion)
-
-  notes:
-    set may be NULL
-
-  design:
-    return last element  
-*/
-void *qh_setlast(setT *set) {
-  int size;
-
-  if (set) {
-    size= *SETsizeaddr_(set);
-    if (!size) 
-      return SETelem_(set, set->maxsize - 1);
-    else if (size > 1)
-      return SETelem_(set, size - 2);
-  }
-  return NULL;
-} /* setlast */
-
-
-/*---------------------------------
-  
-  qh_setnew( setsize )
-    creates and allocates space for a set
-
-  notes:
-    setsize means the number of elements (NOT including the NULL terminator)
-    use qh_settemp/qh_setfreetemp if set is temporary
-
-  design:
-    allocate memory for set
-    roundup memory if small set
-    initialize as empty set
-*/
-setT *qh_setnew(int setsize) {
-  setT *set;
-  int sizereceived; /* used !qh_NOmem */
-  int size;
-  void **freelistp; /* used !qh_NOmem */
-
-  if (!setsize)
-    setsize++;
-  size= sizeof(setT) + setsize * SETelemsize;
-  if ((unsigned) size <= (unsigned) qhmem.LASTsize) {
-    qh_memalloc_(size, freelistp, set, setT);
-#ifndef qh_NOmem
-    sizereceived= qhmem.sizetable[ qhmem.indextable[size]];
-    if (sizereceived > size) 
-      setsize += (sizereceived - size)/SETelemsize;
-#endif
-  }else
-    set= (setT*)qh_memalloc (size);
-  set->maxsize= setsize;
-  set->e[setsize].i= 1;
-  set->e[0].p= NULL;
-  return (set);
-} /* setnew */
-
-
-/*---------------------------------
-  
-  qh_setnew_delnthsorted( set, size, nth, prepend )
-    creates a sorted set not containing nth element
-    if prepend, the first prepend elements are undefined
-
-  notes:
-    set must be defined
-    checks nth
-    see also: setdelnthsorted
-
-  design:
-    create new set
-    setup pointers and allocate room for prepend'ed entries
-    append head of old set to new set
-    append tail of old set to new set
-*/
-setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend) {
-  setT *newset;
-  void **oldp, **newp;
-  int tailsize= size - nth -1, newsize;
-
-  if (tailsize < 0) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  newsize= size-1 + prepend;
-  newset= qh_setnew(newsize);
-  newset->e[newset->maxsize].i= newsize+1;  /* may be overwritten */
-  oldp= SETaddr_(set, void);
-  newp= SETaddr_(newset, void) + prepend;
-  switch (nth) {
-  case 0:
-    break;
-  case 1:
-    *(newp++)= *oldp++;
-    break;
-  case 2:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 3:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 4:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  default:
-    memcpy((char *)newp, (char *)oldp, nth * SETelemsize);
-    newp += nth;
-    oldp += nth;
-    break;
-  }
-  oldp++;
-  switch (tailsize) {
-  case 0:
-    break;
-  case 1:
-    *(newp++)= *oldp++;
-    break;
-  case 2:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 3:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 4:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  default:
-    memcpy((char *)newp, (char *)oldp, tailsize * SETelemsize);
-    newp += tailsize;
-  }
-  *newp= NULL;
-  return(newset);
-} /* setnew_delnthsorted */
-
-
-/*---------------------------------
-  
-  qh_setprint( fp, string, set )
-    print set elements to fp with identifying string
-
-  notes:
-    never errors
-*/
-void qh_setprint(FILE *fp, char* string, setT *set) {
-  int size, k;
-
-  if (!set)
-    fprintf (fp, "%s set is null\n", string);
-  else {
-    SETreturnsize_(set, size);
-    fprintf (fp, "%s set=%p maxsize=%d size=%d elems=",
-	     string, set, set->maxsize, size);
-    if (size > set->maxsize)
-      size= set->maxsize+1;
-    for (k=0; k < size; k++)
-      fprintf(fp, " %p", set->e[k].p);
-    fprintf(fp, "\n");
-  }
-} /* setprint */
-
-/*---------------------------------
-  
-  qh_setreplace( set, oldelem, newelem )
-    replaces oldelem in set with newelem
-
-  notes:
-    errors if oldelem not in the set
-    newelem may be NULL, but it turns the set into an indexed set (no FOREACH)
-
-  design:
-    find oldelem
-    replace with newelem
-*/
-void qh_setreplace(setT *set, void *oldelem, void *newelem) {
-  void **elemp;
-  
-  elemp= SETaddr_(set, void);
-  while(*elemp != oldelem && *elemp)
-    elemp++;
-  if (*elemp)
-    *elemp= newelem;
-  else {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setreplace): elem %p not found in set\n",
-       oldelem);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-} /* setreplace */
-
-
-/*---------------------------------
-  
-  qh_setsize( set )
-    returns the size of a set
-
-  notes:
-    errors if set's maxsize is incorrect
-    same as SETreturnsize_(set)
-
-  design:
-    determine actual size of set from maxsize
-*/
-int qh_setsize(setT *set) {
-  int size, *sizep;
-  
-  if (!set)
-    return (0);
-  sizep= SETsizeaddr_(set);
-  if ((size= *sizep)) {
-    size--;
-    if (size > set->maxsize) {
-      fprintf (qhmem.ferr, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n",
-	       size, set->maxsize);
-      qh_setprint (qhmem.ferr, "set: ", set);
-      qh_errexit (qhmem_ERRqhull, NULL, NULL);
-    }
-  }else
-    size= set->maxsize;
-  return size;
-} /* setsize */
-
-/*---------------------------------
-  
-  qh_settemp( setsize )
-    return a stacked, temporary set of upto setsize elements
-
-  notes:
-    use settempfree or settempfree_all to release from qhmem.tempstack
-    see also qh_setnew
-
-  design:
-    allocate set
-    append to qhmem.tempstack
-    
-*/
-setT *qh_settemp(int setsize) {
-  setT *newset;
-  
-  newset= qh_setnew (setsize);
-  qh_setappend ((setT **)&qhmem.tempstack, newset);
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_settemp: temp set %p of %d elements, depth %d\n",
-       newset, newset->maxsize, qh_setsize ((setT*)qhmem.tempstack));
-  return newset;
-} /* settemp */
-
-/*---------------------------------
-  
-  qh_settempfree( set )
-    free temporary set at top of qhmem.tempstack
-
-  notes:
-    nop if set is NULL
-    errors if set not from previous   qh_settemp
-  
-  to locate errors:
-    use 'T2' to find source and then find mis-matching qh_settemp
-
-  design:
-    check top of qhmem.tempstack
-    free it
-*/
-void qh_settempfree(setT **set) {
-  setT *stackedset;
-
-  if (!*set)
-    return;
-  stackedset= qh_settemppop ();
-  if (stackedset != *set) {
-    qh_settemppush(stackedset);
-    fprintf (qhmem.ferr, "qhull internal error (qh_settempfree): set %p (size %d) was not last temporary allocated (depth %d, set %p, size %d)\n",
-	     *set, qh_setsize(*set), qh_setsize((setT*)qhmem.tempstack)+1,
-	     stackedset, qh_setsize(stackedset));
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  qh_setfree (set);
-} /* settempfree */
-
-/*---------------------------------
-  
-  qh_settempfree_all(  )
-    free all temporary sets in qhmem.tempstack
-
-  design:
-    for each set in tempstack
-      free set
-    free qhmem.tempstack
-*/
-void qh_settempfree_all(void) {
-  setT *set, **setp;
-
-  FOREACHset_((setT *)qhmem.tempstack) 
-    qh_setfree(&set);
-  qh_setfree((setT **)&qhmem.tempstack);
-} /* settempfree_all */
-
-/*---------------------------------
-  
-  qh_settemppop(  )
-    pop and return temporary set from qhmem.tempstack 
-
-  notes:
-    the returned set is permanent
-    
-  design:
-    pop and check top of qhmem.tempstack
-*/
-setT *qh_settemppop(void) {
-  setT *stackedset;
-  
-  stackedset= (setT*)qh_setdellast((setT *)qhmem.tempstack);
-  if (!stackedset) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_settemppop: depth %d temp set %p of %d elements\n",
-       qh_setsize((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset));
-  return stackedset;
-} /* settemppop */
-
-/*---------------------------------
-  
-  qh_settemppush( set )
-    push temporary set unto qhmem.tempstack (makes it temporary)
-
-  notes:
-    duplicates settemp() for tracing
-
-  design:
-    append set to tempstack  
-*/
-void qh_settemppush(setT *set) {
-  
-  qh_setappend ((setT**)&qhmem.tempstack, set);
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_settemppush: depth %d temp set %p of %d elements\n",
-    qh_setsize((setT*)qhmem.tempstack), set, qh_setsize(set));
-} /* settemppush */
-
- 
-/*---------------------------------
-  
-  qh_settruncate( set, size )
-    truncate set to size elements
-
-  notes:
-    set must be defined
-  
-  see:
-    SETtruncate_
-
-  design:
-    check size
-    update actual size of set
-*/
-void qh_settruncate (setT *set, int size) {
-
-  if (size < 0 || size > set->maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  set->e[set->maxsize].i= size+1;   /* maybe overwritten */
-  set->e[size].p= NULL;
-} /* settruncate */
-    
-/*---------------------------------
-  
-  qh_setunique( set, elem )
-    add elem to unsorted set unless it is already in set
-
-  notes:
-    returns 1 if it is appended
-
-  design:
-    if elem not in set
-      append elem to set
-*/
-int qh_setunique (setT **set, void *elem) {
-
-  if (!qh_setin (*set, elem)) {
-    qh_setappend (set, elem);
-    return 1;
-  }
-  return 0;
-} /* setunique */
-    
-/*---------------------------------
-  
-  qh_setzero( set, index, size )
-    zero elements from index on
-    set actual size of set to size
-
-  notes:
-    set must be defined
-    the set becomes an indexed set (can not use FOREACH...)
-  
-  see also:
-    qh_settruncate
-    
-  design:
-    check index and size
-    update actual size
-    zero elements starting at e[index]   
-*/
-void qh_setzero (setT *set, int index, int size) {
-  int count;
-
-  if (index < 0 || index >= size || size > set->maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", index, size);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  set->e[set->maxsize].i=  size+1;  /* may be overwritten */
-  count= size - index + 1;   /* +1 for NULL terminator */
-  memset ((char *)SETelemaddr_(set, index, void), 0, count * SETelemsize);
-} /* setzero */
-
-    
diff --git a/extern/qhull/src/qset.h b/extern/qhull/src/qset.h
deleted file mode 100644
index 6c0ff758de4..00000000000
--- a/extern/qhull/src/qset.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
  ---------------------------------
-
-   qset.h
-     header file for qset.c that implements set
-
-   see qh-set.htm and qset.c
-   
-   only uses mem.c, malloc/free
-
-   for error handling, writes message and calls
-      qh_errexit (qhmem_ERRqhull, NULL, NULL);
-   
-   set operations satisfy the following properties:
-    - sets have a max size, the actual size (if different) is stored at the end
-    - every set is NULL terminated
-    - sets may be sorted or unsorted, the caller must distinguish this
-   
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFset
-#define qhDEFset 1
-
-/*================= -structures- ===============*/
-
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;   /* a set is a sorted or unsorted array of pointers */
-#endif
-
-/*------------------------------------------
-   
-setT
-  a set or list of pointers with maximum size and actual size.
-
-variations:
-  unsorted, unique   -- a list of unique pointers with NULL terminator
-  			   user guarantees uniqueness
-  sorted	     -- a sorted list of unique pointers with NULL terminator
-  			   qset.c guarantees uniqueness
-  unsorted           -- a list of pointers terminated with NULL
-  indexed  	     -- an array of pointers with NULL elements 
-
-structure for set of n elements:
-
-	--------------
-	|  maxsize 
-	--------------
-	|  e[0] - a pointer, may be NULL for indexed sets
-	--------------
-	|  e[1]
-	
-	--------------
-	|  ...
-	--------------
-	|  e[n-1]
-	--------------
-	|  e[n] = NULL
-	--------------
-	|  ...
-	--------------
-	|  e[maxsize] - n+1 or NULL (determines actual size of set)
-	--------------
-
-*/
-
-/*-- setelemT -- internal type to allow both pointers and indices
-*/
-typedef union setelemT setelemT;
-union setelemT {
-  void    *p;
-  int      i;         /* integer used for e[maxSize] */
-};
-
-struct setT {
-  int maxsize;          /* maximum number of elements (except NULL) */
-  setelemT e[1];        /* array of pointers, tail is NULL */
-                        /* last slot (unless NULL) is actual size+1 
-                           e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
-                        /* this may generate a warning since e[] contains
-			   maxsize elements */
-};
-
-/*=========== -constants- =========================*/
-
-/*-------------------------------------
-   
-  SETelemsize
-    size of a set element in bytes
-*/
-#define SETelemsize sizeof(setelemT) 
-
-
-/*=========== -macros- =========================*/
-
-/*-------------------------------------
-   
-   FOREACHsetelement_(type, set, variable)
-     define FOREACH iterator
-
-   declare:  
-     assumes *variable and **variablep are declared
-     no space in "variable)" [DEC Alpha cc compiler]
-
-   each iteration:
-     variable is set element
-     variablep is one beyond variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-
-   example:  
-     #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
-
-   notes:
-     use FOREACHsetelement_i_() if need index or include NULLs
-
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[0].p); \
-	  (variable= *variable##p++);)
-
-/*------------------------------------------
-
-   FOREACHsetelement_i_(type, set, variable)
-     define indexed FOREACH iterator
-
-   declare:  
-     type *variable, variable_n, variable_i;
-
-   each iteration:
-     variable is set element, may be NULL
-     variable_i is index, variable_n is qh_setsize()
-
-   to repeat an element:
-     variable_i--; variable_n-- repeats for deleted element
-
-   at exit:
-     variable==NULL and variable_i==variable_n
-
-   example:
-     #define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet )
-   
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_i_(type, set, variable) \
-        if (((variable= NULL), set)) for (\
-          variable##_i= 0, variable= (type *)((set)->e[0].p), \
-                   variable##_n= qh_setsize(set);\
-          variable##_i < variable##_n;\
-          variable= (type *)((set)->e[++variable##_i].p) )
-
-/*----------------------------------------
-
-   FOREACHsetelementreverse_(type, set, variable)- 
-     define FOREACH iterator in reverse order
-
-   declare:  
-     assumes *variable and **variablep are declared
-     also declare 'int variabletemp'
-
-   each iteration:
-     variable is set element
-
-   to repeat an element:
-     variabletemp++; / *repeat* /
-
-   at exit:
-     variable is NULL
-
-   example:
-     #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
-  
-   notes:
-     use FOREACHsetelementreverse12_() to reverse first two elements
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-	   variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\
-	   variable; variable= \
-	   ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
-
-/*-------------------------------------
-
-   FOREACHsetelementreverse12_(type, set, variable)- 
-     define FOREACH iterator with e[1] and e[0] reversed
-
-   declare:  
-     assumes *variable and **variablep are declared
-
-   each iteration:
-     variable is set element
-     variablep is one after variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-  
-   example
-     #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
-
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse12_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[1].p); \
-	  (variable= *variable##p); \
-          variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
-	      (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
-
-/*-------------------------------------
-
-   FOREACHelem_( set )- 
-     iterate elements in a set
-
-   declare:  
-     void *elem, *elemp;
-
-   each iteration:
-     elem is set element
-     elemp is one beyond
-
-   to repeat an element:
-     elemp--; / *repeat* /
-
-   at exit:
-     elem == NULL at end of loop
-  
-   example:
-     FOREACHelem_(set) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
-
-/*-------------------------------------
-
-   FOREACHset_( set )- 
-     iterate a set of sets
-
-   declare:  
-     setT *set, **setp;
-
-   each iteration:
-     set is set element
-     setp is one beyond
-
-   to repeat an element:
-     setp--; / *repeat* /
-
-   at exit:
-     set == NULL at end of loop
-  
-   example
-     FOREACHset_(sets) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
-
-/*-------------------------------------------
-
-   SETindex_( set, elem )
-     return index of elem in set
-
-   notes:   
-     for use with FOREACH iteration
-
-   example:
-     i= SETindex_(ridges, ridge)
-*/
-#define SETindex_(set, elem) ((void **)elem##p - (void **)&(set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETref_( elem )
-     l.h.s. for modifying the current element in a FOREACH iteration
-
-   example:
-     SETref_(ridge)= anotherridge;
-*/
-#define SETref_(elem) (elem##p[-1])
-
-/*-----------------------------------------
-
-   SETelem_(set, n)
-     return the n'th element of set
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-      use SETelemt_() for type cast
-*/
-#define SETelem_(set, n)           ((set)->e[n].p)
-
-/*-----------------------------------------
-
-   SETelemt_(set, n, type)
-     return the n'th element of set as a type
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-*/
-#define SETelemt_(set, n, type)    ((type*)((set)->e[n].p))
-
-/*-----------------------------------------
-
-   SETelemaddr_(set, n, type)
-     return address of the n'th element of a set
-   
-   notes:
-      assumes that n is valid [0..size] and set is defined 
-*/
-#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
-
-/*-----------------------------------------
-
-   SETfirst_(set)
-     return first element of set
-   
-*/
-#define SETfirst_(set)             ((set)->e[0].p)
-
-/*-----------------------------------------
-
-   SETfirstt_(set, type)
-     return first element of set as a type
-   
-*/
-#define SETfirstt_(set, type)      ((type*)((set)->e[0].p))
-
-/*-----------------------------------------
-
-   SETsecond_(set)
-     return second element of set
-   
-*/
-#define SETsecond_(set)            ((set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETsecondt_(set, type)
-     return second element of set as a type
-*/
-#define SETsecondt_(set, type)     ((type*)((set)->e[1].p))
-
-/*-----------------------------------------
-
-   SETaddr_(set, type)
-       return address of set's elements
-*/
-#define SETaddr_(set,type)	   ((type **)(&((set)->e[0].p)))
-
-/*-----------------------------------------
-
-   SETreturnsize_(set, size) 
-     return size of a set
-   
-   notes:
-      set must be defined
-      use qh_setsize(set) unless speed is critical
-*/
-#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
-
-/*-----------------------------------------
-
-   SETempty_(set) 
-     return true (1) if set is empty
-   
-   notes:
-      set may be NULL
-*/
-#define SETempty_(set) 	          (!set || (SETfirst_(set) ? 0:1))
-
-/*-----------------------------------------
-
-   SETtruncate_(set)
-     return first element of set
-
-   see:
-     qh_settruncate()
-   
-*/
-#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
-      set->e[size].p= NULL;}
-
-/*======= prototypes in alphabetical order ============*/
-
-void  qh_setaddsorted(setT **setp, void *elem);
-void  qh_setaddnth(setT **setp, int nth, void *newelem);
-void  qh_setappend(setT **setp, void *elem);
-void  qh_setappend_set(setT **setp, setT *setA);
-void  qh_setappend2ndlast(setT **setp, void *elem);
-void  qh_setcheck(setT *set, char *tname, int id);
-void  qh_setcompact(setT *set);
-setT *qh_setcopy(setT *set, int extra);
-void *qh_setdel(setT *set, void *elem);
-void *qh_setdellast(setT *set);
-void *qh_setdelnth(setT *set, int nth);
-void *qh_setdelnthsorted(setT *set, int nth);
-void *qh_setdelsorted(setT *set, void *newelem);
-setT *qh_setduplicate( setT *set, int elemsize);
-int   qh_setequal(setT *setA, setT *setB);
-int   qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB);
-int   qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB);
-void  qh_setfree(setT **set);
-void  qh_setfree2( setT **setp, int elemsize);
-void  qh_setfreelong(setT **set);
-int   qh_setin(setT *set, void *setelem);
-int   qh_setindex(setT *set, void *setelem);
-void  qh_setlarger(setT **setp);
-void *qh_setlast(setT *set);
-setT *qh_setnew(int size);
-setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend);
-void  qh_setprint(FILE *fp, char* string, setT *set);
-void  qh_setreplace(setT *set, void *oldelem, void *newelem);
-int   qh_setsize(setT *set);
-setT *qh_settemp(int setsize);
-void  qh_settempfree(setT **set);
-void  qh_settempfree_all(void);
-setT *qh_settemppop(void);
-void  qh_settemppush(setT *set);
-void  qh_settruncate (setT *set, int size);
-int   qh_setunique (setT **set, void *elem);
-void  qh_setzero (setT *set, int index, int size);
-
-
-#endif /* qhDEFset */
diff --git a/extern/qhull/src/qvoronoi.c b/extern/qhull/src/qvoronoi.c
deleted file mode 100644
index ebeb7367b87..00000000000
--- a/extern/qhull/src/qvoronoi.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
  ---------------------------------
-
-   qvoronoi.c
-     compute Voronoi diagrams and furthest-point Voronoi
-     diagrams using qhull
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  notes:
-    restricted version of qhull.c
- 
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qvoron_f.htm and qvoronoi.htm */
-char hidden_options[]=" d n m v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V Fa FA FC Fp FS Ft FV Pv Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-
-char qh_prompta[]= "\n\
-qvoronoi- compute the Voronoi diagram\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Qu   - compute furthest-site Voronoi diagram\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-\n\
-Qhull control options:\n\
-    Qz   - add point-at-infinity to Voronoi diagram\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qs   - search all points for the initial simplex\n\
-    QGn  - Voronoi vertices if visible from point n, -n if not\n\
-    QVn  - Voronoi vertices for input point n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - statistics\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Wn   - min facet width for non-coincident point (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    s    - summary to stderr\n\
-    p    - Voronoi vertices\n\
-    o    - OFF format (dim, Voronoi vertices, and Voronoi regions)\n\
-    i    - Delaunay regions (use 'Pp' to avoid warning)\n\
-    f    - facet dump\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fc   - count plus coincident points (by Voronoi vertex)\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    Fi   - separating hyperplanes for bounded Voronoi regions\n\
-    FI   - ID for each Voronoi vertex\n\
-    Fm   - merge count for each Voronoi vertex (511 max)\n\
-    Fn   - count plus neighboring Voronoi vertices for each Voronoi vertex\n\
-    FN   - count and Voronoi vertices for each Voronoi region\n\
-    Fo   - separating hyperplanes for unbounded Voronoi regions\n\
-    FO   - options and precision constants\n\
-    FP   - nearest point and distance for each coincident point\n\
-    FQ   - command used for qvoronoi\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                    for output: #Voronoi regions, #Voronoi vertices,\n\
-                                #coincident points, #non-simplicial regions\n\
-                    #real (2), max outer plane and min vertex\n\
-    Fv   - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
-    Fx   - extreme points of Delaunay triangulation (on convex hull)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview options (2-d only)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc	 - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest Voronoi vertices by 'area'\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good Voronoi vertices (needs 'QGn' or 'QVn')\n\
-    PFn  - keep Voronoi vertices whose 'area' is at least n\n\
-    PG   - print neighbors of good Voronoi vertices\n\
-    PMn  - keep n Voronoi vertices with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qvoronoi- compute the Voronoi diagram. Qhull %s\n\
-    input (stdin): dimension, number of points, point coordinates\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qvoronoi.htm):\n\
-    Qu   - compute furthest-site Voronoi diagram\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    p    - Voronoi vertices\n\
-    o    - OFF file format (dim, Voronoi vertices, and Voronoi regions)\n\
-    FN   - count and Voronoi vertices for each Voronoi region\n\
-    Fv   - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
-    Fi   - separating hyperplanes for bounded regions, 'Fo' for unbounded\n\
-    G    - Geomview output (2-d only)\n\
-    QVn  - Voronoi vertices for input point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-rbox c P0 D2 | qvoronoi s o         rbox c P0 D2 | qvoronoi Fi\n\
-rbox c P0 D2 | qvoronoi Fo          rbox c P0 D2 | qvoronoi Fv\n\
-rbox c P0 D2 | qvoronoi s Qu Fv     rbox c P0 D2 | qvoronoi Qu Fo\n\
-rbox c G1 d D2 | qvoronoi s p       rbox c G1 d D2 | qvoronoi QJ s p\n\
-rbox c P0 D2 | qvoronoi s Fv QV0\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- OFF_format     p_vertices     i_delaunay     summary        facet_dump\n\
-\n\
- Fcoincident    Fd_cdd_in      FD_cdd_out     FF-dump-xridge Fi_bounded\n\
- Fxtremes       Fmerges        Fneighbors     FNeigh_region  FOptions\n\
- Fo_unbounded   FPoint_near    FQvoronoi      Fsummary       Fvoronoi\n\
- FIDs\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
-\n\
- PArea_keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge_keep   Poutput_forced Pprecision_not\n\
-\n\
- QG_vertex_good QJoggle        Qsearch_1st    Qtriangulate   Qupper_voronoi\n\
- QV_point_good  Qzinfinite\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION,  
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_option ("voronoi  _bbound-last  _coplanar-keep", NULL, NULL);
-    qh DELAUNAY= True;     /* 'v'   */
-    qh VORONOI= True; 
-    qh SCALElast= True;    /* 'Qbb' */
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("_merge-exact", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/rbox.c b/extern/qhull/src/rbox.c
deleted file mode 100644
index 1c288bddc96..00000000000
--- a/extern/qhull/src/rbox.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
  ---------------------------------
-
-   rbox.c
-     Generate input points for qhull.
-   
-   notes:
-     50 points generated for 'rbox D4'
-
-     This code needs a full rewrite.  It needs separate procedures for each 
-     distribution with common, helper procedures.
-   
-   WARNING: 
-     incorrect range if qh_RANDOMmax is defined wrong (user.h)
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "user.h"
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-#endif
-
-#ifdef _MSC_VER  /* Microsoft Visual C++ */
-#pragma warning( disable : 4244)  /* conversion from double to int */
-#endif
-
-#define MINVALUE 0.8
-#define MAXdim 200
-#define PI 3.1415926535897932384
-#define DEFAULTzbox 1e6
-
-char prompt[]= "\n\
--rbox- generate various point distributions.  Default is random in cube.\n\
-\n\
-args (any order, space separated):                    Version: 2001/06/24\n\
-  3000    number of random points in cube, lens, spiral, sphere or grid\n\
-  D3      dimension 3-d\n\
-  c       add a unit cube to the output ('c G2.0' sets size)\n\
-  d       add a unit diamond to the output ('d G2.0' sets size)\n\
-  l       generate a regular 3-d spiral\n\
-  r       generate a regular polygon, ('r s Z1 G0.1' makes a cone)\n\
-  s       generate cospherical points\n\
-  x       generate random points in simplex, may use 'r' or 'Wn'\n\
-  y       same as 'x', plus simplex\n\
-  Pn,m,r  add point [n,m,r] first, pads with 0\n\
-\n\
-  Ln      lens distribution of radius n.  Also 's', 'r', 'G', 'W'.\n\
-  Mn,m,r  lattice (Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...\n\
-          '27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}.  Try 'M3,4 z'.\n\
-  W0.1    random distribution within 0.1 of the cube's or sphere's surface\n\
-  Z0.5 s  random points in a 0.5 disk projected to a sphere\n\
-  Z0.5 s G0.6 same as Z0.5 within a 0.6 gap\n\
-\n\
-  Bn      bounding box coordinates, default %2.2g\n\
-  h       output as homogeneous coordinates for cdd\n\
-  n       remove command line from the first line of output\n\
-  On      offset coordinates by n\n\
-  t       use time as the random number seed (default is command line)\n\
-  tn      use n as the random number seed\n\
-  z       print integer coordinates, default 'Bn' is %2.2g\n\
-";
-
-/* ------------------------------ prototypes ----------------*/
-int roundi( double a);
-void out1( double a);
-void out2n( double a, double b);
-void out3n( double a, double b, double c);
-int     qh_rand( void);
-void    qh_srand( int seed);
-
-
-/* ------------------------------ globals -------------------*/
-
-    FILE *fp;
-    int isinteger= 0;
-    double out_offset= 0.0;
-
-
-/*--------------------------------------------
--rbox-  main procedure of rbox application
-*/
-int main(int argc, char **argv) {
-    int i,j,k;
-    int gendim;
-    int cubesize, diamondsize, seed=0, count, apex;
-    int dim=3 , numpoints= 0, totpoints, addpoints=0;
-    int issphere=0, isaxis=0,  iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0;
-    int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0, istime=0;
-    int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
-    double width=0.0, gap=0.0, radius= 0.0;
-    double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
-    double *simplex, *simplexp;
-    int nthroot, mult[MAXdim];
-    double norm, factor, randr, rangap, lensangle= 0, lensbase= 1;
-    double anglediff, angle, x, y, cube= 0.0, diamond= 0.0;
-    double box= qh_DEFAULTbox; /* scale all numbers before output */
-    double randmax= qh_RANDOMmax;
-    char command[200], *s, seedbuf[200];    
-    time_t timedata;
-
-#if __MWERKS__ && __POWERPC__
-    char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-    SIOUXSettings.showstatusline= False;
-    SIOUXSettings.tabspaces= 1;
-    SIOUXSettings.rows= 40;
-    if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-    || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-    || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-      	fprintf ( stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-    argc= ccommand(&argv);
-#endif
-    if (argc == 1) {
- 	printf (prompt, box, DEFAULTzbox);
-    	exit(1);
-    }
-    if ((s = strrchr( argv[0], '\\'))) /* Borland gives full path */
-      strcpy (command, s+1);
-    else
-      strcpy (command, argv[0]);
-    if ((s= strstr (command, ".EXE"))
-    ||  (s= strstr (command, ".exe")))
-      *s= '\0';
-    /* ============= read flags =============== */
-    for (i=1; i < argc; i++) {
-  	if (strlen (command) + strlen(argv[i]) + 1 < sizeof(command) ) {
-	    strcat (command, " ");
-	    strcat (command, argv[i]);
-	}
-        if (isdigit (argv[i][0])) {
-      	    numpoints= atoi (argv[i]);
-      	    continue;
-	}
-	if (argv[i][0] == '-')
-	  (argv[i])++;
-        switch (argv[i][0]) {
-	  case 'c':
-	    addcube= 1;
-	    if (i+1 < argc && argv[i+1][0] == 'G')
-	      cube= (double) atof (&argv[++i][1]);
-	    break;
-	  case 'd':
-	    adddiamond= 1;
-	    if (i+1 < argc && argv[i+1][0] == 'G')
-	      diamond= (double) atof (&argv[++i][1]);
-	    break;
-	  case 'h':
-	    iscdd= 1;
-            break;
-	  case 'l':
-	    isspiral= 1;
-            break;
-	  case 'n':
-	    NOcommand= 1;
-	    break;
-	  case 'r':
-	    isregular= 1;
-	    break;
-	  case 's':
-	    issphere= 1;
-            break;
-	  case 't':
-	    istime= 1;
-	    if (isdigit (argv[i][1]))
-	      seed= atoi (&argv[i][1]);
-	    else {
-	      seed= time (&timedata);
-	      sprintf (seedbuf, "%d", seed);
-	      strcat (command, seedbuf);
-	    }
-            break;
-	  case 'x':
-	    issimplex= 1;
-	    break;
-	  case 'y':
-	    issimplex2= 1;
-	    break;
-	  case 'z':
-	    isinteger= 1;
-	    break;
-	  case 'B':
-	    box= (double) atof (&argv[i][1]);
-	    isbox= 1;
-	    break;
-	  case 'D':
-	    dim= atoi (&argv[i][1]);
-	    if (dim < 1
-	    || dim > MAXdim) {
-		fprintf (stderr, "rbox error: dim %d too large or too small\n", dim);
-		exit (1);
-	    }
-            break;
-	  case 'G':
-	    if (argv[i][1])
-	      gap= (double) atof (&argv[i][1]);
-	    else
-	      gap= 0.5;
-	    isgap= 1;
-	    break;
-	  case 'L':
-	    if (argv[i][1])
-	      radius= (double) atof (&argv[i][1]);
-	    else
-	      radius= 10;
-	    islens= 1;
-	    break;
-	  case 'M':
-	    ismesh= 1;
-    	    s= argv[i]+1;
-	    if (*s)
-	      meshn= strtod (s, &s);
-	    if (*s == ',')
-	      meshm= strtod (++s, &s);
-	    else
-	      meshm= 0.0;
-	    if (*s == ',')
-	      meshr= strtod (++s, &s);
-	    else
-	      meshr= sqrt (meshn*meshn + meshm*meshm);
-	    if (*s) {
-	      fprintf (stderr, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
-	      meshn= 3.0, meshm=4.0, meshr=5.0;
-	    }
-	    break;
-	  case 'O':
-	    out_offset= (double) atof (&argv[i][1]);
-	    break;
-	  case 'P':
-	    addpoints++;
-	    break;
-	  case 'W':
-	    width= (double) atof (&argv[i][1]);
-	    iswidth= 1;
-	    break;
-	  case 'Z':
-	    if (argv[i][1])
-	      radius= (double) atof (&argv[i][1]);
-	    else
-	      radius= 1.0;
-	    isaxis= 1;
-	    break;
-	  default:
-            fprintf (stderr, "rbox warning: unknown flag %s.\nExecute 'rbox' without arguments for documentation.\n", argv[i]);
-	}
-    }
-    /* ============= defaults, constants, and sizes =============== */
-    if (isinteger && !isbox)
-      box= DEFAULTzbox;
-    if (addcube) {
-      cubesize= floor(ldexp(1.0,dim)+0.5);
-      if (cube == 0.0)
-        cube= box;
-    }else
-      cubesize= 0;
-    if (adddiamond) {
-      diamondsize= 2*dim;
-      if (diamond == 0.0)
-        diamond= box;
-    }else
-      diamondsize= 0;
-    if (islens) {
-      if (isaxis) {
-  	fprintf (stderr, "rbox error: can not combine 'Ln' with 'Zn'\n");
-  	exit(1);
-      }
-      if (radius <= 1.0) {
-  	fprintf (stderr, "rbox error: lens radius %.2g should be greater than 1.0\n",
-  	       radius);
-  	exit(1);
-      }
-      lensangle= asin (1.0/radius);
-      lensbase= radius * cos (lensangle);
-    }
-    if (!numpoints) {
-      if (issimplex2)
-	; /* ok */
-      else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
-	fprintf (stderr, "rbox error: missing count\n");
-	exit(1);
-      }else if (adddiamond + addcube + addpoints)
-	; /* ok */
-      else { 
-	numpoints= 50;  /* ./rbox D4 is the test case */
-	issphere= 1;
-      }
-    }
-    if ((issimplex + islens + isspiral + ismesh > 1) 
-    || (issimplex + issphere + isspiral + ismesh > 1)) {
-      fprintf (stderr, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
-      exit(1);
-    }
-    fp= stdout;
-    /* ============= print header with total points =============== */
-    if (issimplex || ismesh)
-      totpoints= numpoints;
-    else if (issimplex2)
-      totpoints= numpoints+dim+1;
-    else if (isregular) {
-      totpoints= numpoints;
-      if (dim == 2) {
-      	if (islens)
-      	  totpoints += numpoints - 2;
-      }else if (dim == 3) {
-      	if (islens)
-      	  totpoints += 2 * numpoints;
-        else if (isgap)
-          totpoints += 1 + numpoints;
-        else
-          totpoints += 2;
-      }
-    }else
-      totpoints= numpoints + isaxis;
-    totpoints += cubesize + diamondsize + addpoints;
-    if (iscdd) 
-      fprintf(fp, "%s\nbegin\n        %d %d %s\n", 
-            NOcommand ? "" : command, 
-            totpoints, dim+1,
-            isinteger ? "integer" : "real");
-    else if (NOcommand)
-      fprintf(fp,  "%d\n%d\n", dim, totpoints);
-    else
-      fprintf(fp,  "%d %s\n%d\n", dim, command, totpoints);
-    /* ============= seed randoms =============== */
-    if (istime == 0) {
-      for (s=command; *s; s++) {
-	if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
-	  i= 'x';
-	else
-	  i= *s;
-	seed= 11*seed + i;
-      }
-    } /* else, seed explicitly set to n or to time */
-    qh_RANDOMseed_(seed);
-    /* ============= explicit points =============== */
-    for (i=1; i < argc; i++) {
-      if (argv[i][0] == 'P') {
-	s= argv[i]+1;
-	count= 0;
-	if (iscdd)
-	  out1( 1.0);
-	while (*s) {
-	  out1( strtod (s, &s));
-	  count++;
-	  if (*s) { 
-	    if (*s++ != ',') {
-	      fprintf (stderr, "rbox error: missing comma after coordinate in %s\n\n", argv[i]);
-	      exit (1);
-	    }
-          }
-	}
-	if (count < dim) {
-	  for (k= dim-count; k--; )
-	    out1( 0.0);
-	}else if (count > dim) {
-	  fprintf (stderr, "rbox error: %d coordinates instead of %d coordinates in %s\n\n", 
-                 count, dim, argv[i]);
-	  exit (1);
-	}
-	fprintf (fp, "\n");
-      }
-    }
-    /* ============= simplex distribution =============== */
-    if (issimplex+issimplex2) {
-      if (!(simplex= malloc( dim * (dim+1) * sizeof(double)))) {
-	fprintf (stderr, "insufficient memory for simplex\n");
-	exit(0);
-      }
-      simplexp= simplex;
-      if (isregular) {
-        for (i= 0; i randmax/2)
-	    coord[dim-1]= -coord[dim-1];
-	/* ============= project 'Wn' point toward boundary =============== */
-	}else if (iswidth && !issphere) {
-	  j= qh_RANDOMint % gendim;
-	  if (coord[j] < 0)
-	    coord[j]= -1.0 - coord[j] * width;
-	  else
-	    coord[j]= 1.0 - coord[j] * width;
-	}
-	/* ============= write point =============== */
-	if (iscdd)
-	  out1( 1.0);
-	for (k=0; k < dim; k++) 
-	  out1( coord[k] * box);
-	fprintf (fp, "\n");
-      }
-    }
-    /* ============= write cube vertices =============== */
-    if (addcube) {
-      for (j=0; j=0; k--) {
-	  if (j & ( 1 << k))
-	    out1( cube);
-	  else
-	    out1( -cube);
-	}
-	fprintf (fp, "\n");
-      }
-    }
-    /* ============= write diamond vertices =============== */
-    if (adddiamond) {
-      for (j=0; j=0; k--) {
-	  if (j/2 != k)
-	    out1( 0.0);
-	  else if (j & 0x1)
-	    out1( diamond);
-	  else
-	    out1( -diamond);
-	}
-	fprintf (fp, "\n");
-      }
-    }
-    if (iscdd)
-      fprintf (fp, "end\nhull\n");
-    return 0;
-  } /* rbox */
-
-/*------------------------------------------------
--outxxx - output functions
-*/
-int roundi( double a) {
-  if (a < 0.0) {
-    if (a - 0.5 < INT_MIN) {
-      fprintf(stderr, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
-      exit (1);
-    }
-    return a - 0.5;
-  }else {
-    if (a + 0.5 > INT_MAX) {
-      fprintf(stderr, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
-      exit (1);
-    }
-    return a + 0.5;
-  }
-} /* roundi */
-
-void out1(double a) {
-
-  if (isinteger) 
-    fprintf(fp, "%d ", roundi( a+out_offset));
-  else
-    fprintf(fp, qh_REAL_1, a+out_offset);
-} /* out1 */
-
-void out2n( double a, double b) {
-
-  if (isinteger)
-    fprintf(fp, "%d %d\n", roundi(a+out_offset), roundi(b+out_offset));
-  else
-    fprintf(fp, qh_REAL_2n, a+out_offset, b+out_offset);
-} /* out2n */
-
-void out3n( double a, double b, double c) { 
-
-  if (isinteger)
-    fprintf(fp, "%d %d %d\n", roundi(a+out_offset), roundi(b+out_offset), roundi(c+out_offset));
-  else
-    fprintf(fp, qh_REAL_3n, a+out_offset, b+out_offset, c+out_offset);
-} /* out3n */
-
-/*-------------------------------------------------
--rand & srand- generate pseudo-random number between 1 and 2^31 -2
-  from Park & Miller's minimimal standard random number generator
-  Communications of the ACM, 31:1192-1201, 1988.
-notes:
-  does not use 0 or 2^31 -1
-  this is silently enforced by qh_srand()
-  copied from geom2.c
-*/
-static int seed = 1;  /* global static */
-
-int qh_rand( void) {
-#define qh_rand_a 16807
-#define qh_rand_m 2147483647
-#define qh_rand_q 127773  /* m div a */
-#define qh_rand_r 2836    /* m mod a */
-  int lo, hi, test;
-
-  hi = seed / qh_rand_q;  /* seed div q */
-  lo = seed % qh_rand_q;  /* seed mod q */
-  test = qh_rand_a * lo - qh_rand_r * hi;
-  if (test > 0)
-    seed= test;
-  else
-    seed= test + qh_rand_m;
-  return seed;
-} /* rand */
-
-void qh_srand( int newseed) {
-  if (newseed < 1)
-    seed= 1;
-  else if (newseed >= qh_rand_m)
-    seed= qh_rand_m - 1;
-  else
-    seed= newseed;
-} /* qh_srand */
-
diff --git a/extern/qhull/src/stat.c b/extern/qhull/src/stat.c
deleted file mode 100644
index ede0323cb88..00000000000
--- a/extern/qhull/src/stat.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
  ---------------------------------
-
-   stat.c 
-   contains all statistics that are collected for qhull
-
-   see qh-stat.htm and stat.h
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include "qhull_a.h"
-
-/*============ global data structure ==========*/
-
-#if qh_QHpointer
-qhstatT *qh_qhstat=NULL;  /* global data structure */
-#else
-qhstatT qh_qhstat;   /* add "={0}" if this causes a compiler error */
-#endif
-
-/*========== functions in alphabetic order ================*/
-
-/*---------------------------------
-  
-  qh_allstatA()
-    define statistics in groups of 20
-
-  notes:
-    (otherwise, 'gcc -O2' uses too much memory)
-    uses qhstat.next
-*/
-void qh_allstatA (void) {
-  
-   /* zdef_(type,name,doc,average) */
-  zzdef_(zdoc, Zdoc2, "precision statistics", -1);
-  zdef_(zinc, Znewvertex, NULL, -1);
-  zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet (not 0s)", Znewvertex);
-  zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
-  zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
-  zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
-  zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
-
-  qhstat precision= qhstat next;  /* call qh_precision for each of these */
-  zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
-  zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
-  zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
-  zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
-  zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
-  zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
-  zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
-  zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
-  zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
-  zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
-  zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1);
-}
-void qh_allstatB (void) {
-  zzdef_(zdoc, Zdoc1, "summary information", -1);
-  zdef_(zinc, Zvertices, "number of vertices in output", -1);
-  zdef_(zinc, Znumfacets, "number of facets in output", -1);
-  zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
-  zdef_(zinc, Znowsimplicial, "number of simplicial facets that were merged", -1);
-  zdef_(zinc, Znumridges, "number of ridges in output", -1);
-  zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
-  zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
-  zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
-  zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
-  zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
-  zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
-  zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
-  zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
-  zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
-  zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
-  zzdef_(zinc, Zsetplane, "facets created altogether", -1);
-  zdef_(zinc, Ztotridges, "ridges created altogether", -1);
-  zdef_(zinc, Zpostfacets, "facets before post merge", -1);
-  zdef_(zadd, Znummergetot, "average merges per facet (at most 511)", Znumfacets);
-  zdef_(zmax, Znummergemax, "  maximum merges for a facet (at most 511)", -1);
-  zdef_(zinc, Zangle, NULL, -1);
-  zdef_(wadd, Wangle, "average angle (cosine) of facet normals for all ridges", Zangle);
-  zdef_(wmax, Wanglemax, "  maximum angle (cosine) of facet normals across a ridge", -1);
-  zdef_(wmin, Wanglemin, "  minimum angle (cosine) of facet normals across a ridge", -1);
-  zdef_(wadd, Wareatot, "total area of facets", -1);
-  zdef_(wmax, Wareamax, "  maximum facet area", -1);
-  zdef_(wmin, Wareamin, "  minimum facet area", -1);
-}  
-void qh_allstatC (void) {
-  zdef_(zdoc, Zdoc9, "build hull statistics", -1);
-  zzdef_(zinc, Zprocessed, "points processed", -1);
-  zzdef_(zinc, Zretry, "retries due to precision problems", -1);
-  zdef_(wmax, Wretrymax, "  max. random joggle", -1);
-  zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
-  zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
-  zdef_(zinc, Zinsidevisible, "  ave. visible facets without an horizon neighbor", Zprocessed);
-  zdef_(zadd, Zvisfacettot,  "  ave. facets deleted per iteration", Zprocessed);
-  zdef_(zmax, Zvisfacetmax,  "    maximum", -1);
-  zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
-  zdef_(zmax, Zvisvertexmax, "    maximum", -1);
-  zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
-  zdef_(zadd, Znewfacettot,  "ave. new or merged facets per iteration", Zprocessed);
-  zdef_(zmax, Znewfacetmax,  "    maximum (includes initial simplex)", -1);
-  zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
-  zdef_(wadd, Wnewbalance2, "  standard deviation", -1);
-  zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
-  zdef_(wadd, Wpbalance2, "  standard deviation", -1);
-  zdef_(zinc, Zpbalance, "  number of trials", -1);
-  zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
-  zdef_(zinc, Zdetsimplex, "determinants computed (area & initial hull)", -1);
-  zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1);
-  zdef_(zinc, Znotmax, "points ignored (not above max_outside)", -1);
-  zdef_(zinc, Znotgood, "points ignored (not above a good facet)", -1);
-  zdef_(zinc, Znotgoodnew, "points ignored (didn't create a good new facet)", -1);
-  zdef_(zinc, Zgoodfacet, "good facets found", -1);
-  zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
-  zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
-  zdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
-  zzdef_(zinc, Zcheckpart, "  ave. distance tests per check", Ztotcheck);
-}
-void qh_allstatD(void) {
-  zdef_(zdoc, Zdoc4, "partitioning statistics (see previous for outer planes)", -1);
-  zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
-  zdef_(zmax, Zdelvertexmax, "    maximum vertices deleted per iteration", -1);
-  zdef_(zinc, Zfindbest, "calls to findbest", -1);
-  zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
-  zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
-  zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
-  zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
-  zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
-  zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
-  zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
-  zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
-  zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
-  zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
-  zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
-  zdef_(zinc, Zfindjump,       " ave. clearly better", Zfindhorizon);
-  zdef_(zinc, Zparthorizon, " horizon facets better than bestfacet", -1);
-  zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
-  zdef_(zinc, Zpartflip, "  repartitioned coplanar points for flipped orientation", -1);
-  zdef_(zinc, Zpartinside, "inside points", -1);
-  zdef_(zinc, Zpartnear, "  inside points kept with a facet", -1);
-  zdef_(zinc, Zcoplanarinside, "  inside points that were coplanar with a facet", -1);
-  zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
-}
-void qh_allstatE(void) {
-  zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
-  zdef_(zinc, Ztotpartition, "partitions of a point", -1);
-  zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
-  zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1); 
-  zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1); 
-  zdef_(zinc, Zdistgood, "distance tests for checking good point", -1); 
-  zdef_(zinc, Zdistio, "distance tests for output", -1); 
-  zdef_(zinc, Zdiststat, "distance tests for statistics", -1); 
-  zdef_(zinc, Zdistplane, "total number of distance tests", -1);
-  zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
-  zzdef_(zinc, Zpartcoplanar, "   distance tests for these partitions", -1);
-  zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
-}
-void qh_allstatE2(void) {
-  zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
-  zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
-  zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
-  zdef_(zinc, Zhashridge, "total lookups of subridges (duplicates and boundary)", -1);
-  zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
-  zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
-  zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
-
-  zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
-  zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
-  zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
-  zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
-  zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
-  zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
-  zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
-  zdef_(zinc, Zcoplanarcentrum, "coplanar centrums in getmergeset", -1);
-  zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
-}
-void qh_allstatF(void) {
-  zdef_(zdoc, Zdoc7, "statistics for merging", -1);
-  zdef_(zinc, Zpremergetot, "merge iterations", -1);
-  zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
-  zdef_(zadd, Zmergeinitmax, "  maximum", -1);
-  zdef_(zadd, Zmergesettot, "  ave. additional non-convex ridges per iteration", Zpremergetot);
-  zdef_(zadd, Zmergesetmax, "  maximum additional in one pass", -1);
-  zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
-  zdef_(zadd, Zmergesettot2, "  additional non-convex ridges", -1);
-  zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet (w/roundoff)", -1);
-  zdef_(wmin, Wminvertex, "max distance of merged vertex below facet (or roundoff)", -1);
-  zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
-  zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
-  zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
-  zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
-  zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
-  zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
-  zzdef_(zadd, Zcyclefacettot, "  ave. facets per cycle", Zcyclehorizon);
-  zdef_(zmax, Zcyclefacetmax, "  max. facets", -1);
-  zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
-  zdef_(zinc, Zmergenew, "new facets merged", -1);
-  zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
-  zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
-  zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
-  zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
-  zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
-  zdef_(zinc, Zneighbor, "merges due to redundant neighbors", -1);
-  zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1); 
-}
-void qh_allstatG(void) {
-  zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
-  zdef_(wadd, Wacoplanartot, "  average merge distance", Zacoplanar);
-  zdef_(wmax, Wacoplanarmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
-  zdef_(wadd, Wcoplanartot, "  average merge distance", Zcoplanar);
-  zdef_(wmax, Wcoplanarmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zconcave, "merges due to concave facets", -1);
-  zdef_(wadd, Wconcavetot, "  average merge distance", Zconcave);
-  zdef_(wmax, Wconcavemax, "  maximum merge distance", -1);
-  zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
-  zdef_(wadd, Wavoidoldtot, "  average merge distance", Zavoidold);
-  zdef_(wmax, Wavoidoldmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
-  zdef_(wadd, Wdegentot, "  average merge distance", Zdegen);
-  zdef_(wmax, Wdegenmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
-  zdef_(wadd, Wflippedtot, "  average merge distance", Zflipped);
-  zdef_(wmax, Wflippedmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zduplicate, "merges due to duplicated ridges", -1);
-  zdef_(wadd, Wduplicatetot, "  average merge distance", Zduplicate);
-  zdef_(wmax, Wduplicatemax, "  maximum merge distance", -1);
-}
-void qh_allstatH(void) {
-  zdef_(zdoc, Zdoc8, "renamed vertex statistics", -1);
-  zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
-  zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
-  zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
-  zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
-  zdef_(zinc, Zdupridge, "  duplicate ridges detected", -1);
-  zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
-  zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
-  zdef_(zinc, Zdropdegen, "degenerate facets due to dropped neighbors", -1);
-  zdef_(zinc, Zdelfacetdup, "  facets deleted because of no neighbors", -1);
-  zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
-  zdef_(zinc, Zremvertexdel, "  deleted", -1);
-  zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
-  zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
-  zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
-  zdef_(zadd, Zintersecttot, "   ave. number found per vertex", Zintersect);
-  zdef_(zmax, Zintersectmax, "   max. found for a vertex", -1);
-  zdef_(zinc, Zvertexridge, NULL, -1);
-  zdef_(zadd, Zvertexridgetot, "  ave. number of ridges per tested vertex", Zvertexridge);
-  zdef_(zmax, Zvertexridgemax, "  max. number of ridges per tested vertex", -1);
-
-  zdef_(zdoc, Zdoc10, "memory usage statistics (in bytes)", -1);
-  zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
-  zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
-  zdef_(zadd, Zmempoints, "for input points and outside and coplanar sets",-1);
-  zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
-} /* allstat */
-
-void qh_allstatI(void) {
-  qhstat vridges= qhstat next;
-  zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
-  zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
-  zzdef_(wadd, Wridge, "  ave. distance to ridge", Zridge);
-  zzdef_(wmax, Wridgemax, "  max. distance to ridge", -1);
-  zzdef_(zinc, Zridgemid, "bounded ridges", -1);
-  zzdef_(wadd, Wridgemid, "  ave. distance of midpoint to ridge", Zridgemid);
-  zzdef_(wmax, Wridgemidmax, "  max. distance of midpoint to ridge", -1);
-  zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
-  zzdef_(wadd, Wridgeok, "  ave. angle to ridge", Zridgeok);
-  zzdef_(wmax, Wridgeokmax, "  max. angle to ridge", -1);
-  zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
-  zzdef_(wadd, Wridge0, "  ave. angle to ridge", Zridge0);
-  zzdef_(wmax, Wridge0max, "  max. angle to ridge", -1);
-
-  zdef_(zdoc, Zdoc12, "Triangulation statistics (Qt)", -1);
-  zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
-  zdef_(zadd, Ztricoplanartot, "  ave. new facets created (may be deleted)", Ztricoplanar);
-  zdef_(zmax, Ztricoplanarmax, "  max. new facets created", -1);
-  zdef_(zinc, Ztrinull, "null new facets deleted (duplicated vertex)", -1);
-  zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted (same vertices)", -1);
-  zdef_(zinc, Ztridegen, "degenerate new facets in output (same ridge)", -1);
-} /* allstat */
-
-/*---------------------------------
-  
-  qh_allstatistics()
-    reset printed flag for all statistics
-*/
-void qh_allstatistics (void) {
-  int i;
-  
-  for (i=ZEND; i--; ) 
-    qhstat printed[i]= False;
-} /* allstatistics */
-
-#if qh_KEEPstatistics
-/*---------------------------------
-  
-  qh_collectstatistics()
-    collect statistics for qh.facet_list
-
-*/
-void qh_collectstatistics (void) {
-  facetT *facet, *neighbor, **neighborp;
-  vertexT *vertex, **vertexp;
-  realT dotproduct, dist;
-  int sizneighbors, sizridges, sizvertices, i;
-  
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  zval_(Zmempoints)= qh num_points * qh normal_size + 
-                             sizeof (qhT) + sizeof (qhstatT);
-  zval_(Zmemfacets)= 0;
-  zval_(Zmemridges)= 0;
-  zval_(Zmemvertices)= 0;
-  zval_(Zangle)= 0;
-  wval_(Wangle)= 0.0;
-  zval_(Znumridges)= 0;
-  zval_(Znumfacets)= 0;
-  zval_(Znumneighbors)= 0;
-  zval_(Znumvertices)= 0;
-  zval_(Znumvneighbors)= 0;
-  zval_(Znummergetot)= 0;
-  zval_(Znummergemax)= 0;
-  zval_(Zvertices)= qh num_vertices - qh_setsize (qh del_vertices);
-  if (qh MERGING || qh APPROXhull || qh JOGGLEmax < REALmax/2)
-    wmax_(Wmaxoutside, qh max_outside);
-  if (qh MERGING)
-    wmin_(Wminvertex, qh min_vertex);
-  FORALLfacets
-    facet->seen= False;
-  if (qh DELAUNAY) {
-    FORALLfacets {
-      if (facet->upperdelaunay != qh UPPERdelaunay)
-        facet->seen= True; /* remove from angle statistics */
-    }
-  }
-  FORALLfacets {
-    if (facet->visible && qh NEWfacets)
-      continue;
-    sizvertices= qh_setsize (facet->vertices);
-    sizneighbors= qh_setsize (facet->neighbors);
-    sizridges= qh_setsize (facet->ridges);
-    zinc_(Znumfacets);
-    zadd_(Znumvertices, sizvertices);
-    zmax_(Zmaxvertices, sizvertices);
-    zadd_(Znumneighbors, sizneighbors);
-    zmax_(Zmaxneighbors, sizneighbors);
-    zadd_(Znummergetot, facet->nummerge);
-    i= facet->nummerge; /* avoid warnings */
-    zmax_(Znummergemax, i); 
-    if (!facet->simplicial) {
-      if (sizvertices == qh hull_dim) {
-	zinc_(Znowsimplicial);
-      }else {
-        zinc_(Znonsimplicial);
-      }
-    }
-    if (sizridges) {
-      zadd_(Znumridges, sizridges);
-      zmax_(Zmaxridges, sizridges);
-    }
-    zadd_(Zmemfacets, sizeof (facetT) + qh normal_size + 2*sizeof (setT) 
-       + SETelemsize * (sizneighbors + sizvertices));
-    if (facet->ridges) {
-      zadd_(Zmemridges,
-	 sizeof (setT) + SETelemsize * sizridges + sizridges * 
-         (sizeof (ridgeT) + sizeof (setT) + SETelemsize * (qh hull_dim-1))/2);
-    }
-    if (facet->outsideset)
-      zadd_(Zmempoints, sizeof (setT) + SETelemsize * qh_setsize (facet->outsideset));
-    if (facet->coplanarset)
-      zadd_(Zmempoints, sizeof (setT) + SETelemsize * qh_setsize (facet->coplanarset));
-    if (facet->seen) /* Delaunay upper envelope */
-      continue;
-    facet->seen= True;
-    FOREACHneighbor_(facet) {
-      if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
-	  || neighbor->seen || !facet->normal || !neighbor->normal)
-	continue;
-      dotproduct= qh_getangle(facet->normal, neighbor->normal);
-      zinc_(Zangle);
-      wadd_(Wangle, dotproduct);
-      wmax_(Wanglemax, dotproduct)
-      wmin_(Wanglemin, dotproduct)
-    }
-    if (facet->normal) {
-      FOREACHvertex_(facet->vertices) {
-        zinc_(Zdiststat);
-        qh_distplane(vertex->point, facet, &dist);
-        wmax_(Wvertexmax, dist);
-        wmin_(Wvertexmin, dist);
-      }
-    }
-  }
-  FORALLvertices {
-    if (vertex->deleted)
-      continue;
-    zadd_(Zmemvertices, sizeof (vertexT));
-    if (vertex->neighbors) {
-      sizneighbors= qh_setsize (vertex->neighbors);
-      zadd_(Znumvneighbors, sizneighbors);
-      zmax_(Zmaxvneighbors, sizneighbors);
-      zadd_(Zmemvertices, sizeof (vertexT) + SETelemsize * sizneighbors);
-    }
-  }
-  qh RANDOMdist= qh old_randomdist;
-} /* collectstatistics */
-#endif /* qh_KEEPstatistics */
-
-/*---------------------------------
-  
-  qh_freestatistics(  )
-    free memory used for statistics
-*/
-void qh_freestatistics (void) {
-
-#if qh_QHpointer
-  free (qh_qhstat);
-  qh_qhstat= NULL;
-#endif
-} /* freestatistics */
-
-/*---------------------------------
-  
-  qh_initstatistics(  )
-    allocate and initialize statistics
-
-  notes:
-    uses malloc() instead of qh_memalloc() since mem.c not set up yet
-*/
-void qh_initstatistics (void) {
-  int i;
-  realT realx;
-  int intx;
-
-#if qh_QHpointer
-  if (!(qh_qhstat= (qhstatT *)malloc (sizeof(qhstatT)))) {
-    fprintf (qhmem.ferr, "qhull error (qh_initstatistics): insufficient memory\n");
-    exit (1);  /* can not use qh_errexit() */
-  }
-#endif
-  
-  qhstat next= 0;
-  qh_allstatA();
-  qh_allstatB();
-  qh_allstatC();
-  qh_allstatD();
-  qh_allstatE();
-  qh_allstatE2();
-  qh_allstatF();
-  qh_allstatG();
-  qh_allstatH();
-  qh_allstatI();
-  if (qhstat next > sizeof(qhstat id)) {
-    fprintf (qhmem.ferr, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
-      qhstat.next %d should be <= sizeof(qhstat id) %ld\n", qhstat next, sizeof(qhstat id));
-#if 0 /* for locating error, Znumridges should be duplicated */
-    for (i=0; i < ZEND; i++) {
-      int j;
-      for (j=i+1; j < ZEND; j++) {
-	if (qhstat id[i] == qhstat id[j]) {
-          fprintf (qhmem.ferr, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n", 
-	      qhstat id[i], i, j);
-	}
-      }
-    }
-#endif 
-    exit (1);  /* can not use qh_errexit() */
-  }
-  qhstat init[zinc].i= 0;
-  qhstat init[zadd].i= 0;
-  qhstat init[zmin].i= INT_MAX;
-  qhstat init[zmax].i= INT_MIN;
-  qhstat init[wadd].r= 0;
-  qhstat init[wmin].r= REALmax;
-  qhstat init[wmax].r= -REALmax;
-  for (i=0; i < ZEND; i++) {
-    if (qhstat type[i] > ZTYPEreal) {
-      realx= qhstat init[(unsigned char)(qhstat type[i])].r;
-      qhstat stats[i].r= realx;
-    }else if (qhstat type[i] != zdoc) {
-      intx= qhstat init[(unsigned char)(qhstat type[i])].i;
-      qhstat stats[i].i= intx;
-    }
-  }
-} /* initstatistics */
-
-/*---------------------------------
-  
-  qh_newstats(  )
-    returns True if statistics for zdoc
-
-  returns:
-    next zdoc
-*/
-boolT qh_newstats (int index, int *nextindex) {
-  boolT isnew= False;
-  int start, i;
-
-  if (qhstat type[qhstat id[index]] == zdoc) 
-    start= index+1;
-  else
-    start= index;
-  for (i= start; i < qhstat next && qhstat type[qhstat id[i]] != zdoc; i++) {
-    if (!qh_nostatistic(qhstat id[i]) && !qhstat printed[qhstat id[i]])
-	isnew= True;
-  }
-  *nextindex= i;
-  return isnew;
-} /* newstats */
-
-/*---------------------------------
-  
-  qh_nostatistic( index )
-    true if no statistic to print
-*/
-boolT qh_nostatistic (int i) {
-  
-  if ((qhstat type[i] > ZTYPEreal
-       &&qhstat stats[i].r == qhstat init[(unsigned char)(qhstat type[i])].r)
-      || (qhstat type[i] < ZTYPEreal
-	  &&qhstat stats[i].i == qhstat init[(unsigned char)(qhstat type[i])].i))
-    return True;
-  return False;
-} /* nostatistic */
-
-#if qh_KEEPstatistics
-/*---------------------------------
-  
-  qh_printallstatistics( fp, string )
-    print all statistics with header 'string'
-*/
-void qh_printallstatistics (FILE *fp, char *string) {
-
-  qh_allstatistics();
-  qh_collectstatistics();
-  qh_printstatistics (fp, string);
-  qh_memstatistics (fp);
-}
-
-
-/*---------------------------------
-  
-  qh_printstatistics( fp, string )
-    print statistics to a file with header 'string'
-    skips statistics with qhstat.printed[] (reset with qh_allstatistics)
-
-  see: 
-    qh_printallstatistics()
-*/
-void qh_printstatistics (FILE *fp, char *string) {
-  int i, k;
-  realT ave;
-  
-  if (qh num_points != qh num_vertices) {
-    wval_(Wpbalance)= 0;
-    wval_(Wpbalance2)= 0;
-  }else
-    wval_(Wpbalance2)= qh_stddev (zval_(Zpbalance), wval_(Wpbalance), 
-                                 wval_(Wpbalance2), &ave);
-  wval_(Wnewbalance2)= qh_stddev (zval_(Zprocessed), wval_(Wnewbalance), 
-                                 wval_(Wnewbalance2), &ave);
-  fprintf (fp, "\n\
-%s\n\
- qhull invoked by: %s | %s\n%s with options:\n%s\n", string, qh rbox_command, 
-     qh qhull_command, qh_VERSION, qh qhull_options);
-  fprintf (fp, "\nprecision constants:\n\
- %6.2g max. abs. coordinate in the (transformed) input ('Qbd:n')\n\
- %6.2g max. roundoff error for distance computation ('En')\n\
- %6.2g max. roundoff error for angle computations\n\
- %6.2g min. distance for outside points ('Wn')\n\
- %6.2g min. distance for visible facets ('Vn')\n\
- %6.2g max. distance for coplanar facets ('Un')\n\
- %6.2g max. facet width for recomputing centrum and area\n\
-", 
-  qh MAXabs_coord, qh DISTround, qh ANGLEround, qh MINoutside, 
-        qh MINvisible, qh MAXcoplanar, qh WIDEfacet);
-  if (qh KEEPnearinside)
-    fprintf(fp, "\
- %6.2g max. distance for near-inside points\n", qh NEARinside);
-  if (qh premerge_cos < REALmax/2) fprintf (fp, "\
- %6.2g max. cosine for pre-merge angle\n", qh premerge_cos);
-  if (qh PREmerge) fprintf (fp, "\
- %6.2g radius of pre-merge centrum\n", qh premerge_centrum);
-  if (qh postmerge_cos < REALmax/2) fprintf (fp, "\
- %6.2g max. cosine for post-merge angle\n", qh postmerge_cos);
-  if (qh POSTmerge) fprintf (fp, "\
- %6.2g radius of post-merge centrum\n", qh postmerge_centrum);
-  fprintf (fp, "\
- %6.2g max. distance for merging two simplicial facets\n\
- %6.2g max. roundoff error for arithmetic operations\n\
- %6.2g min. denominator for divisions\n\
-  zero diagonal for Gauss: ", qh ONEmerge, REALepsilon, qh MINdenom);
-  for (k=0; k < qh hull_dim; k++)
-    fprintf (fp, "%6.2e ", qh NEARzero[k]);
-  fprintf (fp, "\n\n");
-  for (i=0 ; i < qhstat next; ) 
-    qh_printstats (fp, i, &i);
-} /* printstatistics */
-#endif /* qh_KEEPstatistics */
-
-/*---------------------------------
-  
-  qh_printstatlevel( fp, id )
-    print level information for a statistic
-
-  notes:
-    nop if id >= ZEND, printed, or same as initial value
-*/
-void qh_printstatlevel (FILE *fp, int id, int start) {
-#define NULLfield "       "
-
-  if (id >= ZEND || qhstat printed[id])
-    return;
-  if (qhstat type[id] == zdoc) {
-    fprintf (fp, "%s\n", qhstat doc[id]);
-    return;
-  }
-  start= 0; /* not used */
-  if (qh_nostatistic(id) || !qhstat doc[id])
-    return;
-  qhstat printed[id]= True;
-  if (qhstat count[id] != -1 
-      && qhstat stats[(unsigned char)(qhstat count[id])].i == 0)
-    fprintf (fp, " *0 cnt*");
-  else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] == -1)
-    fprintf (fp, "%7.2g", qhstat stats[id].r);
-  else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] != -1)
-    fprintf (fp, "%7.2g", qhstat stats[id].r/ qhstat stats[(unsigned char)(qhstat count[id])].i);
-  else if (qhstat type[id] < ZTYPEreal && qhstat count[id] == -1)
-    fprintf (fp, "%7d", qhstat stats[id].i);
-  else if (qhstat type[id] < ZTYPEreal && qhstat count[id] != -1)
-    fprintf (fp, "%7.3g", (realT) qhstat stats[id].i / qhstat stats[(unsigned char)(qhstat count[id])].i);
-  fprintf (fp, " %s\n", qhstat doc[id]);
-} /* printstatlevel */
-
-
-/*---------------------------------
-  
-  qh_printstats( fp, index, nextindex )
-    print statistics for a zdoc group
-
-  returns:
-    next zdoc if non-null
-*/
-void qh_printstats (FILE *fp, int index, int *nextindex) {
-  int j, nexti;
-
-  if (qh_newstats (index, &nexti)) {
-    fprintf (fp, "\n");
-    for (j=index; j--------------------------------
-  
-  qh_stddev( num, tot, tot2, ave )
-    compute the standard deviation and average from statistics
-
-    tot2 is the sum of the squares
-  notes:
-    computes r.m.s.: 
-      (x-ave)^2 
-      == x^2 - 2x tot/num +   (tot/num)^2
-      == tot2 - 2 tot tot/num + tot tot/num 
-      == tot2 - tot ave
-*/
-realT qh_stddev (int num, realT tot, realT tot2, realT *ave) {
-  realT stddev;
-
-  *ave= tot/num;
-  stddev= sqrt (tot2/num - *ave * *ave);
-  return stddev;
-} /* stddev */
-
-#endif /* qh_KEEPstatistics */ 
-
-#if !qh_KEEPstatistics
-void    qh_collectstatistics (void) {}
-void    qh_printallstatistics (FILE *fp, char *string) {};
-void    qh_printstatistics (FILE *fp, char *string) {}
-#endif
-
diff --git a/extern/qhull/src/stat.h b/extern/qhull/src/stat.h
deleted file mode 100644
index 1dae54ed21d..00000000000
--- a/extern/qhull/src/stat.h
+++ /dev/null
@@ -1,520 +0,0 @@
-  /*
  ---------------------------------
-
-   stat.h 
-     contains all statistics that are collected for qhull
-
-   see qh-stat.htm and stat.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   recompile qhull if you change this file
-
-   Integer statistics are Z* while real statistics are W*.  
-
-   define maydebugx to call a routine at every statistic event
-
-*/
-
-#ifndef qhDEFstat
-#define qhDEFstat 1
-
-
-/*---------------------------------
-
-  qh_KEEPstatistics
-    0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
-*/
-#ifndef qh_KEEPstatistics
-#define qh_KEEPstatistics 1
-#endif
-
-/*---------------------------------
-
-  Zxxx for integers, Wxxx for reals
-
-  notes:
-    be sure that all statistics are defined in stat.c
-      otherwise initialization may core dump
-    can pick up all statistics by:
-      grep '[zw].*_[(][ZW]' *.c >z.x
-    remove trailers with query">-
-    remove leaders with  query-replace-regexp [ ^I]+  (
-*/
-#if qh_KEEPstatistics
-enum statistics {     /* alphabetical after Z/W */
-    Zacoplanar,
-    Wacoplanarmax,
-    Wacoplanartot,
-    Zangle,
-    Wangle,
-    Wanglemax,
-    Wanglemin,
-    Zangletests,
-    Wareatot,
-    Wareamax,
-    Wareamin,
-    Zavoidold,
-    Wavoidoldmax,
-    Wavoidoldtot,
-    Zback0,
-    Zbestcentrum,
-    Zbestdist,
-    Zcentrumtests,
-    Zcheckpart,
-    Zcomputefurthest,
-    Zconcave,
-    Wconcavemax,
-    Wconcavetot,
-    Zconcaveridges,
-    Zconcaveridge,
-    Zcoplanar,
-    Wcoplanarmax,
-    Wcoplanartot,
-    Zcoplanarangle,
-    Zcoplanarcentrum,
-    Zcoplanarhorizon,
-    Zcoplanarinside,
-    Zcoplanarpart,
-    Zcoplanarridges,
-    Wcpu,
-    Zcyclefacetmax,
-    Zcyclefacettot,
-    Zcyclehorizon,
-    Zcyclevertex,
-    Zdegen,
-    Wdegenmax,
-    Wdegentot,
-    Zdegenvertex,
-    Zdelfacetdup, 
-    Zdelridge,
-    Zdelvertextot,
-    Zdelvertexmax,
-    Zdetsimplex,
-    Zdistcheck,
-    Zdistconvex,
-    Zdistgood,
-    Zdistio,
-    Zdistplane,
-    Zdiststat,
-    Zdistvertex,
-    Zdistzero,
-    Zdoc1,
-    Zdoc2,
-    Zdoc3,
-    Zdoc4,
-    Zdoc5,
-    Zdoc6,
-    Zdoc7,
-    Zdoc8,
-    Zdoc9,
-    Zdoc10,
-    Zdoc11,
-    Zdoc12,
-    Zdropdegen,
-    Zdropneighbor,
-    Zdupflip,
-    Zduplicate,
-    Wduplicatemax,
-    Wduplicatetot,
-    Zdupridge,
-    Zdupsame,
-    Zflipped, 
-    Wflippedmax, 
-    Wflippedtot, 
-    Zflippedfacets,
-    Zfindbest,
-    Zfindbestmax,
-    Zfindbesttot,
-    Zfindcoplanar,
-    Zfindfail,
-    Zfindhorizon,
-    Zfindhorizonmax,
-    Zfindhorizontot,
-    Zfindjump,
-    Zfindnew,
-    Zfindnewmax,
-    Zfindnewtot,
-    Zfindnewjump,
-    Zfindnewsharp,
-    Zgauss0,
-    Zgoodfacet,
-    Zhashlookup,
-    Zhashridge,
-    Zhashridgetest,
-    Zhashtests,
-    Zinsidevisible,
-    Zintersect,
-    Zintersectfail,
-    Zintersectmax,
-    Zintersectnum,
-    Zintersecttot,
-    Zmaxneighbors,
-    Wmaxout,
-    Wmaxoutside,
-    Zmaxridges,
-    Zmaxvertex,
-    Zmaxvertices,
-    Zmaxvneighbors,
-    Zmemfacets,
-    Zmempoints,
-    Zmemridges,
-    Zmemvertices,
-    Zmergeflipdup,
-    Zmergehorizon,
-    Zmergeinittot,
-    Zmergeinitmax,
-    Zmergeinittot2,
-    Zmergeintohorizon,
-    Zmergenew,
-    Zmergesettot,
-    Zmergesetmax,
-    Zmergesettot2,
-    Zmergesimplex,
-    Zmergevertex,
-    Wmindenom,
-    Wminvertex,
-    Zminnorm,
-    Zmultiridge,
-    Znearlysingular,
-    Zneighbor,
-    Wnewbalance,
-    Wnewbalance2,
-    Znewfacettot,
-    Znewfacetmax,
-    Znewvertex,
-    Wnewvertex,
-    Wnewvertexmax,
-    Znoarea,
-    Znonsimplicial,
-    Znowsimplicial,
-    Znotgood,
-    Znotgoodnew,
-    Znotmax,
-    Znumfacets,
-    Znummergemax,
-    Znummergetot,
-    Znumneighbors,
-    Znumridges,
-    Znumvertices,
-    Znumvisibility,
-    Znumvneighbors,
-    Zonehorizon,
-    Zpartangle,
-    Zpartcoplanar,
-    Zpartflip,
-    Zparthorizon,
-    Zpartinside,
-    Zpartition, 
-    Zpartitionall,
-    Zpartnear,
-    Zpbalance,
-    Wpbalance,
-    Wpbalance2, 
-    Zpostfacets, 
-    Zpremergetot,
-    Zprocessed,
-    Zremvertex,
-    Zremvertexdel,
-    Zrenameall,
-    Zrenamepinch,
-    Zrenameshare,
-    Zretry,
-    Wretrymax,
-    Zridge,
-    Wridge,
-    Wridgemax,
-    Zridge0,
-    Wridge0,
-    Wridge0max,
-    Zridgemid,
-    Wridgemid,
-    Wridgemidmax,
-    Zridgeok,
-    Wridgeok,
-    Wridgeokmax,
-    Zsearchpoints,
-    Zsetplane,
-    Ztestvneighbor,
-    Ztotcheck,
-    Ztothorizon,
-    Ztotmerge,
-    Ztotpartcoplanar,
-    Ztotpartition,
-    Ztotridges,
-    Ztotvertices,
-    Ztotvisible,
-    Ztricoplanar,
-    Ztricoplanarmax,
-    Ztricoplanartot,
-    Ztridegen,
-    Ztrimirror,
-    Ztrinull,
-    Wvertexmax,
-    Wvertexmin,
-    Zvertexridge,
-    Zvertexridgetot,
-    Zvertexridgemax,
-    Zvertices,
-    Zvisfacettot,
-    Zvisfacetmax,
-    Zvisvertextot,
-    Zvisvertexmax,
-    Zwidefacet,
-    Zwidevertices,
-    ZEND};
-
-/*---------------------------------
-
-  Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
-
-  notes:
-    be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
-*/
-#else
-enum statistics {     /* for zzdef etc. macros */
-  Zback0,
-  Zbestdist,
-  Zcentrumtests,
-  Zcheckpart,
-  Zconcaveridges,
-  Zcoplanarhorizon,
-  Zcoplanarpart,
-  Zcoplanarridges,
-  Zcyclefacettot,
-  Zcyclehorizon,
-  Zdelvertextot,
-  Zdistcheck,
-  Zdistconvex,
-  Zdistzero,
-  Zdoc1,
-  Zdoc2,
-  Zdoc3,
-  Zdoc11,
-  Zflippedfacets,
-  Zgauss0,
-  Zminnorm,
-  Zmultiridge,
-  Znearlysingular,
-  Wnewvertexmax,
-  Znumvisibility,
-  Zpartcoplanar,
-  Zpartition,
-  Zpartitionall,
-  Zprocessed,
-  Zretry,
-  Zridge,
-  Wridge,
-  Wridgemax,
-  Zridge0,
-  Wridge0,
-  Wridge0max,
-  Zridgemid,
-  Wridgemid,
-  Wridgemidmax,
-  Zridgeok,
-  Wridgeok,
-  Wridgeokmax,
-  Zsetplane,
-  Ztotmerge,
-    ZEND};
-#endif
-
-/*---------------------------------
-  
-  ztype
-    the type of a statistic sets its initial value.  
-
-  notes:
-    The type should be the same as the macro for collecting the statistic
-*/
-enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
-
-/*========== macros and constants =============*/
-
-/*----------------------------------
-  
-  MAYdebugx
-    define as maydebug() to be called frequently for error trapping
-*/
-#define MAYdebugx 
-
-/*----------------------------------
-  
-  zzdef_, zdef_( type, name, doc, -1)
-    define a statistic (assumes 'qhstat.next= 0;')
-
-  zdef_( type, name, doc, count)
-    define an averaged statistic
-    printed as name/count
-*/
-#define zzdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#if qh_KEEPstatistics
-#define zdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#else
-#define zdef_(type,name,doc,count)
-#endif
-
-/*----------------------------------
-  
-  zzinc_( name ), zinc_( name)
-    increment an integer statistic
-*/
-#define zzinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#if qh_KEEPstatistics
-#define zinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#else
-#define zinc_(id) {}
-#endif
-
-/*----------------------------------
-  
-  zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
-    add value to an integer or real statistic
-*/
-#define zzadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wwadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#if qh_KEEPstatistics
-#define zadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#else
-#define zadd_(id, val) {}
-#define wadd_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zzval_( name ), zval_( name ), wwval_( name )
-    set or return value of a statistic
-*/
-#define zzval_(id) ((qhstat stats[id]).i)
-#define wwval_(id) ((qhstat stats[id]).r)
-#if qh_KEEPstatistics
-#define zval_(id) ((qhstat stats[id]).i)
-#define wval_(id) ((qhstat stats[id]).r)
-#else
-#define zval_(id) qhstat tempi
-#define wval_(id) qhstat tempr
-#endif
-
-/*----------------------------------
-
-  zmax_( id, val ), wmax_( id, value )
-    maximize id with val
-*/
-#define wwmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#if qh_KEEPstatistics
-#define zmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].i,(val));}
-#define wmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#else
-#define zmax_(id, val) {}
-#define wmax_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zmin_( id, val ), wmin_( id, value )
-    minimize id with val
-*/
-#if qh_KEEPstatistics
-#define zmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].i,(val));}
-#define wmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].r,(val));}
-#else
-#define zmin_(id, val) {}
-#define wmin_(id, val) {}
-#endif
-
-/*================== stat.h types ==============*/
-
-
-/*----------------------------------
- 
-  intrealT
-    union of integer and real, used for statistics
-*/
-typedef union intrealT intrealT;    /* union of int and realT */
-union intrealT {
-    int i;
-    realT r;
-};
-
-/*----------------------------------
-  
-  qhstat
-    global data structure for statistics
-  
-  notes:
-   access to qh_qhstat is via the "qhstat" macro.  There are two choices
-   qh_QHpointer = 1     access globals via a pointer
-                        enables qh_saveqhull() and qh_restoreqhull()
-		= 0     qh_qhstat is a static data structure
-		        only one instance of qhull() can be active at a time
-			default value
-   qh_QHpointer is defined in qhull.h
-
-   allocated in stat.c
-*/
-typedef struct qhstatT qhstatT; 
-#if qh_QHpointer
-#define qhstat qh_qhstat->
-extern qhstatT *qh_qhstat;
-#else
-#define qhstat qh_qhstat.
-extern qhstatT qh_qhstat; 
-#endif
-struct qhstatT {  
-  intrealT   stats[ZEND];     /* integer and real statistics */
-  unsigned   char id[ZEND+10]; /* id's in print order */
-  char      *doc[ZEND];       /* array of documentation strings */
-  short int  count[ZEND];     /* -1 if none, else index of count to use */
-  char       type[ZEND];      /* type, see ztypes above */
-  char       printed[ZEND];   /* true, if statistic has been printed */
-  intrealT   init[ZTYPEend];  /* initial values by types, set initstatistics */
-
-  int        next;            /* next index for zdef_ */
-  int        precision;       /* index for precision problems */
-  int        vridges;         /* index for Voronoi ridges */
-  int        tempi;
-  realT      tempr;
-};
-
-/*========== function prototypes ===========*/
-
-void    qh_allstatA(void);
-void    qh_allstatB(void);
-void    qh_allstatC(void);
-void    qh_allstatD(void);
-void    qh_allstatE(void);
-void    qh_allstatE2(void);
-void    qh_allstatF(void);
-void    qh_allstatG(void);
-void    qh_allstatH(void);
-void    qh_allstatI(void);
-void    qh_allstatistics (void);
-void    qh_collectstatistics (void);
-void	qh_freestatistics (void);
-void    qh_initstatistics (void);
-boolT 	qh_newstats (int index, int *nextindex);
-boolT 	qh_nostatistic (int i);
-void    qh_printallstatistics (FILE *fp, char *string);
-void    qh_printstatistics (FILE *fp, char *string);
-void  	qh_printstatlevel (FILE *fp, int id, int start);
-void  	qh_printstats (FILE *fp, int index, int *nextindex);
-realT   qh_stddev (int num, realT tot, realT tot2, realT *ave);
-
-#endif   /* qhDEFstat */
diff --git a/extern/qhull/src/unix.c b/extern/qhull/src/unix.c
deleted file mode 100644
index 5ec5feab16c..00000000000
--- a/extern/qhull/src/unix.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
  ---------------------------------
-
-   unix.c
-     command line interface to qhull
-	 includes SIOUX interface for Macintoshes
-
-   see qh-qhull.htm
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  see:
-    concise prompt below
-*/  
-char qh_prompta[]= "\n\
-qhull- compute convex hulls and related structures.\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-    halfspaces:  use dim plus one and put offset after coefficients.\n\
-                 May be preceeded by a single interior point ('H').\n\
-\n\
-options:\n\
-    d    - Delaunay triangulation by lifting points to a paraboloid\n\
-    d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
-    v    - Voronoi diagram (dual of the Delaunay triangulation)\n\
-    v Qu - furthest-site Voronoi diagram\n\
-    Hn,n,... - halfspace intersection about point [n,n,0,...]\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Qc   - keep coplanar points with nearest facet\n\
-    Qi   - keep interior points with nearest facet\n\
-\n\
-Qhull control options:\n\
-    Qbk:n   - scale coord k so that low bound is n\n\
-      QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
-    QbB  - scale input to unit cube centered at the origin\n\
-    Qbb  - scale last coordinate to [0,m] for Delaunay triangulations\n\
-    Qbk:0Bk:0 - remove k-th coordinate from input\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-    QRn  - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qf   - partition point to furthest outside facet\n\
-    Qg   - only build good facets (needs 'QGn', 'QVn', or 'PdD')\n\
-    Qm   - only process points that would increase max_outside\n\
-    Qr   - process random outside points instead of furthest ones\n\
-    Qs   - search all points for the initial simplex\n\
-    Qu   - for 'd' or 'v', compute upper hull without point at-infinity\n\
-              returns furthest-site Delaunay triangulation\n\
-    Qv   - test vertex neighbors for convexity\n\
-    Qx   - exact pre-merges (skips coplanar and angle-coplanar facets)\n\
-    Qz   - add point-at-infinity to Delaunay triangulation\n\
-    QGn  - good facet if visible from point n, -n for not visible\n\
-    QVn  - good facet if it includes point n, -n if not\n\
-    Q0   - turn off default premerge with 'C-0'/'Qx'\n\
-    Q1	   - sort merges by type instead of angle\n\
-    Q2   - merge all non-convex at once instead of independent sets\n\
-    Q3   - do not merge redundant vertices\n\
-    Q4   - avoid old->new merges\n\
-    Q5   - do not correct outer planes at end of qhull\n\
-    Q6   - do not pre-merge concave or coplanar facets\n\
-    Q7   - depth-first processing instead of breadth-first\n\
-    Q8   - do not process near-inside points\n\
-    Q9   - process furthest of furthest points\n\
-    Q10  - no special processing for narrow distributions\n\
-    Q11  - copy normals and recompute centrums for tricoplanar facets\n\
-\n\
-";
-char qh_promptc[]= "\
-Topts- Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TRn  - rerun qhull n times.  Use with 'QJn'\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    En   - max roundoff error for distance computation\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Vn   - min distance above plane for a visible facet (default 3C-n or En)\n\
-    Un   - max distance below plane for a new, coplanar point (default Vn)\n\
-    Wn   - min facet width for outside point (before roundoff, default 2Vn)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (see below)\n\
-    i    - vertices incident to each facet\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    o    - OFF format (dim, points and facets; Voronoi regions)\n\
-    n    - normals with offsets\n\
-    p    - vertex coordinates or Voronoi vertices (coplanar points if 'Qc')\n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fa   - area for each facet\n\
-    FA   - compute total area and volume for option 's'\n\
-    Fc   - count plus coplanar points for each facet\n\
-           use 'Qc' (default) for coplanar and 'Qi' for interior\n\
-    FC   - centrum or Voronoi center for each facet\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for numeric output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    Fi   - inner plane for each facet\n\
-           for 'v', separating hyperplanes for bounded Voronoi regions\n\
-    FI   - ID of each facet\n\
-    Fm   - merge count for each facet (511 max)\n\
-    Fn   - count plus neighboring facets for each facet\n\
-    FN   - count plus neighboring facets for each point\n\
-    Fo   - outer plane (or max_outside) for each facet\n\
-           for 'v', separating hyperplanes for unbounded Voronoi regions\n\
-    FO   - options and precision constants\n\
-    Fp   - dim, count, and intersection coordinates (halfspace only)\n\
-    FP   - nearest vertex and distance for each coplanar point\n\
-    FQ   - command used for qhull\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                      output: #vertices, #facets, #coplanars, #nonsimplicial\n\
-                    #real (2), max outer plane, min vertex\n\
-    FS   - sizes:   #int (0)\n\
-                    #real(2) tot area, tot volume\n\
-    Ft   - triangulation with centrums for non-simplicial facets (OFF format)\n\
-    Fv   - count plus vertices for each facet\n\
-           for 'v', Voronoi diagram as Voronoi vertices for pairs of sites\n\
-    FV   - average of vertices (a feasible point for 'H')\n\
-    Fx   - extreme points (in order for 2-d)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview options (2-d, 3-d, and 4-d; 2-d Voronoi)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc   - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-    Gt   - for 3-d 'd', transparent outer ridges\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest facets by area\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good facets (needs 'QGn' or 'QVn')\n\
-    PFn  - keep facets whose area is at least n\n\
-    PG   - print neighbors of good facets\n\
-    PMn  - keep n facets with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull
-*/
-char qh_prompt2[]= "\n\
-qhull- compute convex hulls and related structures.  %s\n\
-    input (stdin): dimension, n, point coordinates\n\
-    comments start with a non-numeric character\n\
-    halfspace: use dim+1 and put offsets after coefficients\n\
-\n\
-options (qh-quick.htm):\n\
-    d    - Delaunay triangulation by lifting points to a paraboloid\n\
-    d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
-    v    - Voronoi diagram as the dual of the Delaunay triangulation\n\
-    v Qu - furthest-site Voronoi diagram\n\
-    H1,1 - Halfspace intersection about [1,1,0,...] via polar duality\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-Output options (subset):\n\
-    s    - summary of results (default)\n\
-    i    - vertices incident to each facet\n\
-    n    - normals with offsets\n\
-    p    - vertex coordinates (if 'Qc', includes coplanar points)\n\
-           if 'v', Voronoi vertices\n\
-    Fp   - halfspace intersections\n\
-    Fx   - extreme points (convex hull vertices)\n\
-    FA   - compute total area and volume\n\
-    o    - OFF format (if 'v', outputs Voronoi regions)\n\
-    G    - Geomview output (2-d, 3-d and 4-d)\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    QVn  - print facets that include point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox c d D2 | qhull Qc s f Fx | more      rbox 1000 s | qhull Tv s FA\n\
-    rbox 10 D2 | qhull d QJ s i TO result     rbox 10 D2 | qhull v QJ p\n\
-    rbox 10 D2 | qhull d Qu QJ m              rbox 10 D2 | qhull v Qu QJ o\n\
-    rbox c | qhull n                          rbox c | qhull FV n | qhull H Fp\n\
-    rbox d D12 | qhull QR0 FA                 rbox c D7 | qhull FA TF1000\n\
-    rbox y 1000 W0 | qhull                    rbox 10 | qhull v QJ o Fv\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull
-*/
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- delaunay       voronoi	       Geomview       Halfspace      facet_dump\n\
- incidences     mathematica    normals        OFF_format     points\n\
- summary\n\
-\n\
- Farea          FArea-total    Fcoplanars     FCentrums      Fd-cdd-in\n\
- FD-cdd-out     FF-dump-xridge Finner         FIDs           Fmerges\n\
- Fneighbors     FNeigh-vertex  Fouter         FOptions       Fpoint-intersect\n\
- FPoint_near    FQhull         Fsummary       FSize          Ftriangles\n\
- Fvertices      Fvoronoi       FVertex-ave    Fxtremes\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
- Gtransparent\n\
-\n\
- PArea-keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge-keep   Poutput_forced Pprecision_not\n\
-\n\
- QbBound 0:0.5  Qbk:0Bk:0_drop QbB-scale-box  Qbb-scale-last Qcoplanar\n\
- Qfurthest      Qgood_only     QGood_point    Qinterior      Qmax_out\n\
- QJoggle        Qrandom        QRotate        Qsearch_1st    Qtriangulate\n\
- QupperDelaunay QVertex_good   Qvneighbors    Qxact_merge    Qzinfinite\n\
-\n\
- Q0_no_premerge Q1_no_angle    Q2_no_independ Q3_no_redundant Q4_no_old\n\
- Q5_no_check_out Q6_no_concave Q7_depth_first Q8_no_near_in  Q9_pick_furthest\n\
- Q10_no_narrow  Q11_trinormals\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TRerun         TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Error_round    Random_dist    Visible_min\n\
- Ucoplanar_max  Wide_outside\n\
-";
-
-/*---------------------------------
-
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION, qh_DEFAULTbox,
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong)
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/user.c b/extern/qhull/src/user.c
deleted file mode 100644
index 94b31aaf99f..00000000000
--- a/extern/qhull/src/user.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
  ---------------------------------
-
-   user.c 
-   user redefinable functions
-
-   see README.txt  see COPYING.txt for copyright information.
-
-   see qhull.h for data structures, macros, and user-callable functions.
-
-   see user_eg.c, unix.c, and qhull_interface.cpp for examples.
-
-   see user.h for user-definable constants
-
-      use qh_NOmem in mem.h to turn off memory management
-      use qh_NOmerge in user.h to turn off facet merging
-      set qh_KEEPstatistics in user.h to 0 to turn off statistics
-
-   This is unsupported software.  You're welcome to make changes,
-   but you're on your own if something goes wrong.  Use 'Tc' to
-   check frequently.  Usually qhull will report an error if 
-   a data structure becomes inconsistent.  If so, it also reports
-   the last point added to the hull, e.g., 102.  You can then trace
-   the execution of qhull with "T4P102".  
-
-   Please report any errors that you fix to qhull@geom.umn.edu
-
-   call_qhull is a template for calling qhull from within your application
-
-   if you recompile and load this module, then user.o will not be loaded
-   from qhull.a
-
-   you can add additional quick allocation sizes in qh_user_memsizes
-
-   if the other functions here are redefined to not use qh_print...,
-   then io.o will not be loaded from qhull.a.  See user_eg.c for an
-   example.  We recommend keeping io.o for the extra debugging 
-   information it supplies.
-*/
-
-#include "qhull_a.h" 
-
-/*---------------------------------
-
-  qh_call_qhull( void )
-    template for calling qhull from inside your program
-    remove #if 0, #endif to compile
-
-  returns: 
-    exit code (see qh_ERR... in qhull.h)
-    all memory freed
-
-  notes:
-    This can be called any number of times.  
-
-  see:
-    qh_call_qhull_once()
-    
-*/
-#if 0
-{
-  int dim;	            /* dimension of points */
-  int numpoints;            /* number of points */
-  coordT *points;           /* array of coordinates for each point */
-  boolT ismalloc;           /* True if qhull should free points in qh_freeqhull() or reallocation */
-  char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
-  FILE *outfile= stdout;    /* output from qh_produce_output()
-			       use NULL to skip qh_produce_output() */
-  FILE *errfile= stderr;    /* error messages from qhull code */
-  int exitcode;             /* 0 if no error from qhull */
-  facetT *facet;	    /* set by FORALLfacets */
-  int curlong, totlong;	    /* memory remaining after qh_memfreeshort */
-
-  /* initialize dim, numpoints, points[], ismalloc here */
-  exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) {                  /* if no error */
-    /* 'qh facet_list' contains the convex hull */
-    FORALLfacets {
-       /* ... your code ... */
-    }
-  }
-  qh_freeqhull(!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
-}
-#endif
-
-/*---------------------------------
-
-  qh_new_qhull( dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
-    build new qhull data structure and return exitcode (0 if no errors)
-
-  notes:
-    do not modify points until finished with results.
-      The qhull data structure contains pointers into the points array.
-    do not call qhull functions before qh_new_qhull().
-      The qhull data structure is not initialized until qh_new_qhull().
-
-    outfile may be null
-    qhull_cmd must start with "qhull "
-    projects points to a new point array for Delaunay triangulations ('d' and 'v')
-    transforms points into a new point array for halfspace intersection ('H')
-       
-
-  To allow multiple, concurrent calls to qhull() 
-    - set qh_QHpointer in user.h
-    - use qh_save_qhull and qh_restore_qhull to swap the global data structure between calls.
-    - use qh_freeqhull(qh_ALL) to free intermediate convex hulls
-
-  see:
-    user_eg.c for an example
-*/
-int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, 
-		char *qhull_cmd, FILE *outfile, FILE *errfile) {
-  int exitcode, hulldim;
-  boolT new_ismalloc;
-  static boolT firstcall = True;
-  coordT *new_points;
-
-  if (firstcall) {
-    qh_meminit (errfile);
-    firstcall= False;
-  }
-  if (strncmp (qhull_cmd,"qhull ", 6)) {
-    fprintf (errfile, "qh_new_qhull: start qhull_cmd argument with \"qhull \"\n");
-    exit(1);
-  }
-  qh_initqhull_start (NULL, outfile, errfile);
-  trace1(( qh ferr, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
-  exitcode = setjmp (qh errexit);
-  if (!exitcode)
-  {
-    qh NOerrexit = False;
-    qh_initflags (qhull_cmd);
-    if (qh DELAUNAY)
-      qh PROJECTdelaunay= True;
-    if (qh HALFspace) {
-      /* points is an array of halfspaces, 
-         the last coordinate of each halfspace is its offset */
-      hulldim= dim-1;
-      qh_setfeasible (hulldim); 
-      new_points= qh_sethalfspace_all (dim, numpoints, points, qh feasible_point);
-      new_ismalloc= True;
-      if (ismalloc)
-	free (points);
-    }else {
-      hulldim= dim;
-      new_points= points;
-      new_ismalloc= ismalloc;
-    }
-    qh_init_B (new_points, numpoints, hulldim, new_ismalloc);
-    qh_qhull();
-    qh_check_output();
-    if (outfile)
-      qh_produce_output(); 
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-  }
-  qh NOerrexit = True;
-  return exitcode;
-} /* new_qhull */
-
-/*---------------------------------
-  
-  qh_errexit( exitcode, facet, ridge )
-    report and exit from an error
-    report facet and ridge if non-NULL
-    reports useful information such as last point processed
-    set qh.FORCEoutput to print neighborhood of facet
-
-  see: 
-    qh_errexit2() in qhull.c for printing 2 facets
-
-  design:
-    check for error within error processing
-    compute qh.hulltime
-    print facet and ridge (if any)
-    report commandString, options, qh.furthest_id
-    print summary and statistics (including precision statistics)
-    if qh_ERRsingular
-      print help text for singular data set
-    exit program via long jump (if defined) or exit()      
-*/
-void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
-
-  if (qh ERREXITcalled) {
-    fprintf (qh ferr, "\nqhull error while processing previous error.  Exit program\n");
-    exit(1);
-  }
-  qh ERREXITcalled= True;
-  if (!qh QHULLfinished)
-    qh hulltime= qh_CPUclock - qh hulltime;
-  qh_errprint("ERRONEOUS", facet, NULL, ridge, NULL);
-  fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
-  fprintf(qh ferr, "Options selected for Qhull %s:\n%s\n", qh_VERSION, qh qhull_options);
-  if (qh furthest_id >= 0) {
-    fprintf(qh ferr, "Last point added to hull was p%d.", qh furthest_id);
-    if (zzval_(Ztotmerge))
-      fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
-    if (qh QHULLfinished)
-      fprintf(qh ferr, "\nQhull has finished constructing the hull.");
-    else if (qh POSTmerging)
-      fprintf(qh ferr, "\nQhull has started post-merging.");
-    fprintf (qh ferr, "\n");
-  }
-  if (qh FORCEoutput && (qh QHULLfinished || (!facet && !ridge)))
-    qh_produce_output();
-  else {
-    if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) {
-      fprintf (qh ferr, "\nAt error exit:\n");
-      qh_printsummary (qh ferr);
-      if (qh PRINTstatistics) {
-	qh_collectstatistics();
-	qh_printstatistics(qh ferr, "at error exit");
-	qh_memstatistics (qh ferr);
-      }
-    }
-    if (qh PRINTprecision)
-      qh_printstats (qh ferr, qhstat precision, NULL);
-  }
-  if (!exitcode)
-    exitcode= qh_ERRqhull;
-  else if (exitcode == qh_ERRsingular)
-    qh_printhelp_singular(qh ferr);
-  else if (exitcode == qh_ERRprec && !qh PREmerge)
-    qh_printhelp_degenerate (qh ferr);
-  if (qh NOerrexit) {
-    fprintf (qh ferr, "qhull error while ending program.  Exit program\n");
-    exit(1);
-  }
-  qh NOerrexit= True;
-  longjmp(qh errexit, exitcode);
-} /* errexit */
-
-
-/*---------------------------------
-  
-  qh_errprint( fp, string, atfacet, otherfacet, atridge, atvertex )
-    prints out the information of facets and ridges to fp
-    also prints neighbors and geomview output
-    
-  notes:
-    except for string, any parameter may be NULL
-*/
-void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
-  int i;
-
-  if (atfacet) {
-    fprintf(qh ferr, "%s FACET:\n", string);
-    qh_printfacet(qh ferr, atfacet);
-  }
-  if (otherfacet) {
-    fprintf(qh ferr, "%s OTHER FACET:\n", string);
-    qh_printfacet(qh ferr, otherfacet);
-  }
-  if (atridge) {
-    fprintf(qh ferr, "%s RIDGE:\n", string);
-    qh_printridge(qh ferr, atridge);
-    if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
-      qh_printfacet(qh ferr, atridge->top);
-    if (atridge->bottom
-	&& atridge->bottom != atfacet && atridge->bottom != otherfacet)
-      qh_printfacet(qh ferr, atridge->bottom);
-    if (!atfacet)
-      atfacet= atridge->top;
-    if (!otherfacet)
-      otherfacet= otherfacet_(atridge, atfacet);
-  }
-  if (atvertex) {
-    fprintf(qh ferr, "%s VERTEX:\n", string);
-    qh_printvertex (qh ferr, atvertex);
-  }
-  if (qh fout && qh FORCEoutput && atfacet && !qh QHULLfinished && !qh IStracing) {
-    fprintf(qh ferr, "ERRONEOUS and NEIGHBORING FACETS to output\n");
-    for (i= 0; i < qh_PRINTEND; i++)  /* use fout for geomview output */
-      qh_printneighborhood (qh fout, qh PRINTout[i], atfacet, otherfacet,
-			    !qh_ALL);
-  }
-} /* errprint */
-
-
-/*---------------------------------
-  
-  qh_printfacetlist( fp, facetlist, facets, printall )
-    print all fields for a facet list and/or set of facets to fp
-    if !printall, 
-      only prints good facets
-
-  notes:
-    also prints all vertices
-*/
-void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
-  facetT *facet, **facetp;
-
-  qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall);
-  FORALLfacet_(facetlist)
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
-  FOREACHfacet_(facets)
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
-  qh_printend (qh ferr, qh_PRINTfacets, facetlist, facets, printall);
-} /* printfacetlist */
-
-
-/*---------------------------------
-  
-  qh_user_memsizes()
-    allocate up to 10 additional, quick allocation sizes
-
-  notes:
-    increase maximum number of allocations in qh_initqhull_mem()
-*/
-void qh_user_memsizes (void) {
-
-  /* qh_memsize (size); */
-} /* user_memsizes */
-
diff --git a/extern/qhull/src/user.h b/extern/qhull/src/user.h
deleted file mode 100644
index 79558967a52..00000000000
--- a/extern/qhull/src/user.h
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
  ---------------------------------
-
-   user.h
-   user redefinable constants
-
-   see qh-user.htm.  see COPYING for copyright information.
-
-   before reading any code, review qhull.h for data structure definitions and 
-   the "qh" macro.
-*/
-
-#ifndef qhDEFuser
-#define qhDEFuser 1
-
-/*============= data types and configuration macros ==========*/
-
-/*----------------------------------
-  
-  realT
-    set the size of floating point numbers
-  
-  qh_REALdigits 
-    maximimum number of significant digits
-  
-  qh_REAL_1, qh_REAL_2n, qh_REAL_3n
-    format strings for printf
-  
-  qh_REALmax, qh_REALmin
-    maximum and minimum (near zero) values  
-  
-  qh_REALepsilon
-    machine roundoff.  Maximum roundoff error for addition and multiplication.
-    
-  notes:
-   Select whether to store floating point numbers in single precision (float)
-   or double precision (double).
-   
-   Use 'float' to save about 8% in time and 25% in space.  This is particularly
-   help if high-d where convex hulls are space limited.  Using 'float' also
-   reduces the printed size of Qhull's output since numbers have 8 digits of 
-   precision.
-   
-   Use 'double' when greater arithmetic precision is needed.  This is needed
-   for Delaunay triangulations and Voronoi diagrams when you are not merging 
-   facets.
-
-   If 'double' gives insufficient precision, your data probably includes
-   degeneracies.  If so you should use facet merging (done by default)
-   or exact arithmetic (see imprecision section of manual, qh-impre.htm).  
-   You may also use option 'Po' to force output despite precision errors.
-
-   You may use 'long double', but many format statements need to be changed
-   and you may need a 'long double' square root routine.  S. Grundmann
-   (sg@eeiwzb.et.tu-dresden.de) has done this.  He reports that the code runs 
-   much slower with little gain in precision.    
-
-   WARNING: on some machines,    int f(){realT a= REALmax;return (a == REALmax);}
-      returns False.  Use (a > REALmax/2) instead of (a == REALmax).
-
-   REALfloat =   1      all numbers are 'float' type
-             =   0      all numbers are 'double' type
-*/
-#define REALfloat 0
-
-#if (REALfloat == 1)
-#define realT float
-#define REALmax FLT_MAX
-#define REALmin FLT_MIN
-#define REALepsilon FLT_EPSILON
-#define qh_REALdigits 8   /* maximum number of significant digits */
-#define qh_REAL_1 "%6.8g "
-#define qh_REAL_2n "%6.8g %6.8g\n"
-#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
-
-#elif (REALfloat == 0)
-#define realT double
-#define REALmax DBL_MAX
-#define REALmin DBL_MIN
-#define REALepsilon DBL_EPSILON
-#define qh_REALdigits 16    /* maximum number of significant digits */
-#define qh_REAL_1 "%6.16g "
-#define qh_REAL_2n "%6.16g %6.16g\n"
-#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
-
-#else
-#error unknown float option
-#endif
-
-/*----------------------------------
-  
-  qh_CPUclock
-    define the clock() function for reporting the total time spent by Qhull
-    returns CPU ticks as a 'long int'
-    qh_CPUclock is only used for reporting the total time spent by Qhull
-
-  qh_SECticks 
-    the number of clock ticks per second
-
-  notes:
-    looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
-    to define a custom clock, set qh_CLOCKtype to 0
-
-    if your system does not use clock() to return CPU ticks, replace
-    qh_CPUclock with the corresponding function.  It is converted
-    to unsigned long to prevent wrap-around during long runs.
-   
-
-   Set qh_CLOCKtype to
-   
-     1	   	for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
-                Note:  may fail if more than 1 hour elapsed time
-
-     2	   	use qh_clock() with POSIX times() (see global.c)
-*/
-#define qh_CLOCKtype 1  /* change to the desired number */
-
-#if (qh_CLOCKtype == 1)
-
-#if defined (CLOCKS_PER_SECOND)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SECOND
-
-#elif defined (CLOCKS_PER_SEC)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SEC
-
-#elif defined (CLK_TCK)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLK_TCK
-
-#else
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks 1E6
-#endif
-
-#elif (qh_CLOCKtype == 2)
-#define qh_CPUclock    qh_clock()  /* return CPU clock */
-#define qh_SECticks 100
-
-#else /* qh_CLOCKtype == ? */
-#error unknown clock option
-#endif
-
-/*----------------------------------
-  
-  qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
-    define random number generator
-
-    qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.  
-    qh_RANDOMseed sets the random number seed for qh_RANDOMint
-
-  Set qh_RANDOMtype (default 5) to:
-    1       for random() with 31 bits (UCB)
-    2       for rand() with RAND_MAX or 15 bits (system 5)
-    3       for rand() with 31 bits (Sun)
-    4       for lrand48() with 31 bits (Solaris)
-    5       for qh_rand() with 31 bits (included with Qhull)
-  
-  notes:
-    Random numbers are used by rbox to generate point sets.  Random
-    numbers are used by Qhull to rotate the input ('QRn' option),
-    simulate a randomized algorithm ('Qr' option), and to simulate
-    roundoff errors ('Rn' option).
-
-    Random number generators differ between systems.  Most systems provide
-    rand() but the period varies.  The period of rand() is not critical
-    since qhull does not normally use random numbers.  
-
-    The default generator is Park & Miller's minimal standard random
-    number generator [CACM 31:1195 '88].  It is included with Qhull.
-
-    If qh_RANDOMmax is wrong, qhull will report a warning and Geomview 
-    output will likely be invisible.
-*/
-#define qh_RANDOMtype 5   /* *** change to the desired number *** */
-
-#if (qh_RANDOMtype == 1)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, random()/MAX */
-#define qh_RANDOMint random()
-#define qh_RANDOMseed_(seed) srandom(seed);
-
-#elif (qh_RANDOMtype == 2)
-#ifdef RAND_MAX
-#define qh_RANDOMmax ((realT)RAND_MAX)
-#else
-#define qh_RANDOMmax ((realT)32767)   /* 15 bits (System 5) */
-#endif
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-  
-#elif (qh_RANDOMtype == 3)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, Sun */
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-
-#elif (qh_RANDOMtype == 4)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, lrand38()/MAX */
-#define qh_RANDOMint lrand48()
-#define qh_RANDOMseed_(seed) srand48(seed);
-
-#elif (qh_RANDOMtype == 5)
-#define qh_RANDOMmax ((realT)2147483646UL)  /* 31 bits, qh_rand/MAX */
-#define qh_RANDOMint qh_rand()
-#define qh_RANDOMseed_(seed) qh_srand(seed);
-/* unlike rand(), never returns 0 */
-
-#else
-#error: unknown random option
-#endif
-
-/*----------------------------------
-  
-  qh_ORIENTclock
-    0 for inward pointing normals by Geomview convention
-*/
-#define qh_ORIENTclock 0 
-
-
-/*========= performance related constants =========*/
-
-/*----------------------------------
-  
-  qh_HASHfactor
-    total hash slots / used hash slots.  Must be at least 1.1.
-      
-  notes:
-    =2 for at worst 50% occupancy for qh hash_table and normally 25% occupancy
-*/
-#define qh_HASHfactor 2
-
-/*----------------------------------
-  
-  qh_VERIFYdirect
-    with 'Tv' verify all points against all facets if op count is smaller
-
-  notes:
-    if greater, calls qh_check_bestdist() instead
-*/
-#define qh_VERIFYdirect 1000000 
-
-/*----------------------------------
-  
-  qh_INITIALsearch
-     if qh_INITIALmax, search points up to this dimension
-*/
-#define qh_INITIALsearch 6
-
-/*----------------------------------
-  
-  qh_INITIALmax
-    if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
-      
-  notes:
-    from points with non-zero determinants
-    use option 'Qs' to override (much slower)
-*/
-#define qh_INITIALmax 8
-
-/*----------------------------------
-  
-  qh_JOGGLEdefault
-    default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
-
-  notes:
-    rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
-    rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
-    rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
-    rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
-    rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
-    rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
-    rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
-    rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
-    rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
-    the later have about 20 points per facet, each of which may interfere
-
-    pick a value large enough to avoid retries on most inputs
-*/
-#define qh_JOGGLEdefault 30000.0
-
-/*----------------------------------
-  
-  qh_JOGGLEincrease
-    factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
-*/
-#define qh_JOGGLEincrease 10.0
-
-/*----------------------------------
-  
-  qh_JOGGLEretry
-    if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
-
-  notes:
-    try twice at the original value in case of bad luck the first time
-*/
-#define qh_JOGGLEretry 2
-
-/*----------------------------------
-  
-  qh_JOGGLEagain
-    every following qh_JOGGLEagain, increase qh.JOGGLEmax
-
-  notes:
-    1 is OK since it's already failed qh_JOGGLEretry times
-*/
-#define qh_JOGGLEagain 1
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxincrease
-    maximum qh.JOGGLEmax due to qh_JOGGLEincrease
-    relative to qh.MAXwidth
-
-  notes:
-    qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
-*/
-#define qh_JOGGLEmaxincrease 1e-2
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxretry
-    stop after qh_JOGGLEmaxretry attempts
-*/
-#define qh_JOGGLEmaxretry 100
-
-/*========= memory constants =========*/
-
-/*----------------------------------
-  
-  qh_MEMalign
-    memory alignment for qh_meminitbuffers() in global.c
-    
-  notes:
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers. 
-
-    If using gcc, best alignment is
-              #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
-*/
-#define qh_MEMalign fmax_(sizeof(realT), sizeof(void *))
-
-/*----------------------------------
-  
-  qh_MEMbufsize
-    size of additional memory buffers
-    
-  notes:
-    used for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
-
-/*----------------------------------
-  
-  qh_MEMinitbuf
-    size of initial memory buffer
-    
-  notes:
-    use for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMinitbuf 0x20000      /* initially allocate 128K buffer */
-
-/*----------------------------------
-  
-  qh_INFINITE
-    on output, indicates Voronoi center at infinity
-*/
-#define qh_INFINITE  -10.101
-
-/*----------------------------------
-  
-  qh_DEFAULTbox
-    default box size (Geomview expects 0.5)
-*/
-#define qh_DEFAULTbox 0.5 
-
-/*======= conditional compilation ============================*/
-
-/*----------------------------------
-
-  __cplusplus
-    defined by C++ compilers
-
-  __MSC_VER
-    defined by Microsoft Visual C++
-  
-  __MWERKS__ && __POWERPC__
-    defined by Metrowerks when compiling for the Power Macintosh
-
-  __STDC__
-    defined for strict ANSI C 
-*/
-
-/*----------------------------------
- 
-  qh_COMPUTEfurthest 
-    compute furthest distance to an outside point instead of storing it with the facet
-    =1 to compute furthest
-  
-  notes:
-    computing furthest saves memory but costs time
-      about 40% more distance tests for partitioning
-      removes facet->furthestdist 
-*/
-#define qh_COMPUTEfurthest 0
-                         
-/*----------------------------------
- 
-  qh_KEEPstatistics   
-    =0 removes most of statistic gathering and reporting
-
-  notes:
-    if 0, code size is reduced by about 4%.
-*/
-#define qh_KEEPstatistics 1
-                       
-/*----------------------------------
- 
-  qh_MAXoutside 
-    record outer plane for each facet
-    =1 to record facet->maxoutside
-  
-  notes:
-    this takes a realT per facet and slightly slows down qhull
-    it produces better outer planes for geomview output 
-*/
-#define qh_MAXoutside 1
-
-/*----------------------------------
- 
-  qh_NOmerge
-    disables facet merging if defined
-    
-  notes:
-    This saves about 10% space.
-    
-    Unless 'Q0'
-      qh_NOmerge sets 'QJ' to avoid precision errors
-
-    #define qh_NOmerge    
-
-  see:
-    qh_NOmem in mem.c
-    
-    see user.c/user_eg.c for removing io.o
-*/  
-    
-/*----------------------------------
- 
-  qh_NOtrace
-    no tracing if defined 
-  
-  notes:
-    This saves about 5% space.
-
-    #define qh_NOtrace
-*/    
-
-/*----------------------------------
-  
-  qh_QHpointer
-    access global data with pointer or static structure
-
-  qh_QHpointer  = 1     access globals via a pointer to allocated memory
-                        enables qh_saveqhull() and qh_restoreqhull()
-			costs about 8% in time and 2% in space
-
-		= 0     qh_qh and qh_qhstat are static data structures
-		        only one instance of qhull() can be active at a time
-			default value
-
-  notes:
-    all global variables for qhull are in qh, qhmem, and qhstat
-    qh is defined in qhull.h
-    qhmem is defined in mem.h
-    qhstat is defined in stat.h
-
-  see:
-    user_eg.c for an example
-*/
-#define qh_QHpointer 0
-#if 0  /* sample code */
-    qhT *oldqhA, *oldqhB;
-
-    exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from first call to qh_new_qhull */
-    oldqhA= qh_save_qhull();
-    exitcode= qh_new_qhull (dimB, numpointsB, pointsB, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from second call to qh_new_qhull */
-    oldqhB= qh_save_qhull();
-    qh_restore_qhull (&oldqhA);
-    /* use results from first call to qh_new_qhull */
-    qh_freeqhull (qh_ALL);  /* frees all memory used by first call */
-    qh_restore_qhull (&oldqhB);
-    /* use results from second call to qh_new_qhull */
-    qh_freeqhull (!qh_ALL); /* frees long memory used by second call */
-    qh_memfreeshort (&curlong, &totlong);  /* frees short memory and memory allocator */
-#endif
-
-/*----------------------------------
- 
-  qh_QUICKhelp        
-    =1 to use abbreviated help messages, e.g., for degenerate inputs
-*/
-#define qh_QUICKhelp    0  
-
-/* ============ -merge constants- ====================
-
-   These constants effect facet merging.  You probably will not need
-   to modify these.  They effect the performance of facet merging.
-*/
-
-/*----------------------------------
-  
-  qh_DIMmergeVertex
-    max dimension for vertex merging (it is not effective in high-d)
-*/
-#define qh_DIMmergeVertex 6
-
-/*----------------------------------
-  
-  qh_DIMreduceBuild
-     max dimension for vertex reduction during build (slow in high-d)
-*/
-#define qh_DIMreduceBuild 5
-
-/*----------------------------------
-     
-  qh_BESTcentrum
-     if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
-     else, qh_findbestneighbor() tests all vertices (much better merges)
-
-  qh_BESTcentrum2
-     if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
-*/
-#define qh_BESTcentrum 20
-#define qh_BESTcentrum2 2
-
-/*----------------------------------
-  
-  qh_BESTnonconvex
-    if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
-    
-  notes:
-    It is needed because qh_findbestneighbor is slow for large facets
-*/
-#define qh_BESTnonconvex 15 
-
-/*----------------------------------
-  
-  qh_MAXnewmerges
-    if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
-     
-  notes:
-    It is needed because postmerge can merge many facets at once
-*/
-#define qh_MAXnewmerges 2
-
-/*----------------------------------
-  
-  qh_MAXnewcentrum
-    if <= dim+n vertices (n approximates the number of merges),
-      reset the centrum in qh_updatetested() and qh_mergecycle_facets()
-    
-  notes:
-    needed to reduce cost and because centrums may move too much if 
-    many vertices in high-d
-*/
-#define qh_MAXnewcentrum 5
-
-/*----------------------------------
-  
-  qh_COPLANARratio
-    for 3-d+ merging, qh.MINvisible is n*premerge_centrum
-
-  notes:
-    for non-merging, it's DISTround
-*/
-#define qh_COPLANARratio 3
-
-/*----------------------------------
-  
-  qh_DISToutside
-    When is a point clearly outside of a facet?  
-    Stops search in qh_findbestnew or qh_partitionall
-    qh_findbest uses qh.MINoutside since since it is only called if no merges.
-     
-  notes:
-    'Qf' always searches for best facet
-    if !qh.MERGING, same as qh.MINoutside. 
-    if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
-      [Note: Zdelvertextot occurs normally with interior points]
-            RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
-    When there is a sharp edge, need to move points to a
-    clearly good facet; otherwise may be lost in another partitioning.
-    if too big then O(n^2) behavior for partitioning in cone
-    if very small then important points not processed
-    Needed in qh_partitionall for
-      RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
-    Needed in qh_findbestnew for many instances of
-      RBOX 1000 s Z1 G1e-13 t | QHULL Tv
-
-  See:  
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
-     fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside))
-
-/*----------------------------------
-  
-  qh_RATIOnearinside
-    ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
-    qh_check_maxout().  
-  
-  notes:
-    This is overkill since do not know the correct value.
-    It effects whether 'Qc' reports all coplanar points
-    Not used for 'd' since non-extreme points are coplanar
-*/
-#define qh_RATIOnearinside 5
-
-/*----------------------------------
-  
-  qh_SEARCHdist
-    When is a facet coplanar with the best facet?  
-    qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
-
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
-      (qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar)));
-
-/*----------------------------------
-  
-  qh_USEfindbestnew
-     Always use qh_findbestnew for qh_partitionpoint, otherwise use
-     qh_findbestnew if merged new facet or sharpnewfacets.
-  
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
-
-/*----------------------------------
-  
-  qh_WIDEcoplanar
-    n*MAXcoplanar or n*MINvisible for a WIDEfacet 
-    
-    if vertex is further than qh.WIDEfacet from the hyperplane
-    then its ridges are not counted in computing the area, and
-    the facet's centrum is frozen. 
-    
-  notes:
-   qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
-      qh_WIDEcoplanar * qh.MINvisible);
-*/
-#define qh_WIDEcoplanar 6
-
-/*----------------------------------
-  
-  qh_MAXnarrow
-    max. cosine in initial hull that sets qh.NARROWhull
-       
-  notes:
-    If qh.NARROWhull, the initial partition does not make 
-    coplanar points.  If narrow, a coplanar point can be 
-    coplanar to two facets of opposite orientations and
-    distant from the exact convex hull.
-
-    Conservative estimate.  Don't actually see problems until it is -1.0
-*/
-#define qh_MAXnarrow -0.99999999
-
-/*----------------------------------
-  
-  qh_WARNnarrow
-    max. cosine in initial hull to warn about qh.NARROWhull
-      
-  notes:
-    this is a conservative estimate.  
-    Don't actually see problems until it is -1.0.  See qh-impre.htm
-*/
-#define qh_WARNnarrow -0.999999999999999
-
-/*----------------------------------
-  
-  qh_ZEROdelaunay
-    a zero Delaunay facet occurs for input sites coplanar with their convex hull
-    the last normal coefficient of a zero Delaunay facet is within
-        qh_ZEROdelaunay * qh.ANGLEround of 0
-      
-  notes:
-    qh_ZEROdelaunay does not allow for joggled input ('QJ').
-
-    You can avoid zero Delaunay facets by surrounding the input with a box.
-
-    Use option 'PDk:-n' to explicitly define zero Delaunay facets
-      k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
-      n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
-*/
-#define qh_ZEROdelaunay 2
-
-#endif /* qh_DEFuser */
-
-
-
diff --git a/extern/qhull/src/user_eg.c b/extern/qhull/src/user_eg.c
deleted file mode 100644
index 97e4aa7a89a..00000000000
--- a/extern/qhull/src/user_eg.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
  ---------------------------------
-
-  user_eg.c
-  sample code for calling qhull() from an application
-  
-  call with:
-
-     user_eg "cube/diamond options" "delaunay options" "halfspace options"
-
-  for example:
-
-     user_eg                             # return summaries
-
-     user_eg "n" "o" "Fp"                # return normals, OFF, points
-
-     user_eg "n Qt" "o" "Fp"             # triangulated cube
-
-     user_eg "QR0 p" "QR0 v p" "QR0 Fp"  # rotate input and return points
-                                         # 'v' returns Voronoi
-					 # transform is rotated for halfspaces
-
-   main() makes three runs of qhull.
-
-     1) compute the convex hull of a cube
-
-     2a) compute the Delaunay triangulation of random points
-
-     2b) find the Delaunay triangle closest to a point.
-
-     3) compute the halfspace intersection of a diamond
-
- notes:
- 
-   For another example, see main() in unix.c and user_eg2.c.
-   These examples, call qh_qhull() directly.  They allow
-   tighter control on the code loaded with Qhull.
-
-   For a simple C++ example, see qhull_interface.cpp
-
-   Summaries are sent to stderr if other output formats are used
-
-   compiled by 'make user_eg'
-
-   see qhull.h for data structures, macros, and user-callable functions.
-*/
-
-#include "qhull_a.h"
-
-/*-------------------------------------------------
--internal function prototypes
-*/
-void print_summary (void);
-void makecube (coordT *points, int numpoints, int dim);
-void makeDelaunay (coordT *points, int numpoints, int dim, int seed);
-void findDelaunay (int dim);
-void makehalf (coordT *points, int numpoints, int dim);
-
-/*-------------------------------------------------
--print_summary()
-*/
-void print_summary (void) {
-  facetT *facet;
-  int k;
-
-  printf ("\n%d vertices and %d facets with normals:\n", 
-                 qh num_vertices, qh num_facets);
-  FORALLfacets {
-    for (k=0; k < qh hull_dim; k++) 
-      printf ("%6.2g ", facet->normal[k]);
-    printf ("\n");
-  }
-}
-
-/*--------------------------------------------------
--makecube- set points to vertices of cube
-  points is numpoints X dim
-*/
-void makecube (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; jvertices) {
-    for (k=0; k < dim; k++)
-      printf ("%5.2f ", vertex->point[k]);
-    printf ("\n");
-  }
-} /*.findDelaunay.*/
-
-/*--------------------------------------------------
--makehalf- set points to halfspaces for a (dim)-dimensional diamond
-  points is numpoints X dim+1
-
-  each halfspace consists of dim coefficients followed by an offset
-*/
-void makehalf (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; j= 2 ? argv[1] : "");
-  numpoints= SIZEcube;
-  makecube (points, numpoints, DIM);
-  for (i=numpoints; i--; )
-    rows[i]= points+dim*i;
-  qh_printmatrix (outfile, "input", rows, numpoints, dim);
-  exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) {                  /* if no error */
-    /* 'qh facet_list' contains the convex hull */
-    print_summary();
-    FORALLfacets {
-       /* ... your code ... */
-    }
-  }
-  qh_freeqhull(!qh_ALL);                   /* free long memory  */
-  qh_memfreeshort (&curlong, &totlong);    /* free short memory and memory allocator */
-  if (curlong || totlong) 
-    fprintf (errfile, "qhull internal warning (user_eg, #1): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
-
-  /*
-    Run 2: Delaunay triangulation
-  */
-
-  printf( "\ncompute 3-d Delaunay triangulation\n");
-  sprintf (flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
-  numpoints= SIZEcube;
-  makeDelaunay (points, numpoints, dim, time(NULL));
-  for (i=numpoints; i--; )
-    rows[i]= points+dim*i;
-  qh_printmatrix (outfile, "input", rows, numpoints, dim);
-  exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) {                  /* if no error */
-    /* 'qh facet_list' contains the convex hull */
-    /* If you want a Voronoi diagram ('v') and do not request output (i.e., outfile=NULL), 
-       call qh_setvoronoi_all() after qh_new_qhull(). */
-    print_summary();
-    FORALLfacets {
-       /* ... your code ... */
-    }
-    printf( "\nfind 3-d Delaunay triangle closest to [0.5, 0.5, ...]\n");
-    exitcode= setjmp (qh errexit);  
-    if (!exitcode) {
-      /* Trap Qhull errors in findDelaunay().  Without the setjmp(), Qhull
-         will exit() after reporting an error */
-      qh NOerrexit= False;
-      findDelaunay (DIM);
-    }
-    qh NOerrexit= True;
-  }
-#if qh_QHpointer  /* see user.h */
-  {
-    qhT *oldqhA, *oldqhB;
-    coordT pointsB[DIM*TOTpoints]; /* array of coordinates for each point */
-
-
-    printf( "\nsave first triangulation and compute a new triangulation\n");
-    oldqhA= qh_save_qhull();
-    sprintf (flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
-    numpoints= SIZEcube;
-    makeDelaunay (pointsB, numpoints, dim, time(NULL)+1);
-    for (i=numpoints; i--; )
-      rows[i]= pointsB+dim*i;
-    qh_printmatrix (outfile, "input", rows, numpoints, dim);
-    exitcode= qh_new_qhull (dim, numpoints, pointsB, ismalloc,
-                      flags, outfile, errfile); 
-    if (!exitcode)
-      print_summary();
-    printf( "\nsave second triangulation and restore first one\n");
-    oldqhB= qh_save_qhull();
-    qh_restore_qhull (&oldqhA);
-    print_summary();
-    printf( "\nfree first triangulation and restore second one.\n");
-    qh_freeqhull (qh_ALL);               /* free short and long memory used by first call */
-			                 /* do not use qh_memfreeshort */
-    qh_restore_qhull (&oldqhB);
-    print_summary();
-  }
-#endif
-  qh_freeqhull(!qh_ALL);                 /* free long memory */
-  qh_memfreeshort (&curlong, &totlong);  /* free short memory and memory allocator */
-  if (curlong || totlong) 
-    fprintf (errfile, "qhull internal warning (user_eg, #2): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
-
-  /*
-    Run 3: halfspace intersection about the origin
-  */
-  printf( "\ncompute halfspace intersection about the origin for a diamond\n");
-  sprintf (flags, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "Fp");
-  numpoints= SIZEcube;
-  makehalf (points, numpoints, dim);
-  for (i=numpoints; i--; )
-    rows[i]= points+(dim+1)*i;
-  qh_printmatrix (outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1);
-  /* use qh_sethalfspace_all to transform the halfspaces yourself.  
-     If so, set 'qh feasible_point and do not use option 'Hn,...' [it would retransform the halfspaces]
-  */
-  exitcode= qh_new_qhull (dim+1, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) 
-    print_summary();
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong)  /* could also check previous runs */
-    fprintf (stderr, "qhull internal warning (user_eg, #3): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/user_eg2.c b/extern/qhull/src/user_eg2.c
deleted file mode 100644
index 1eb42ccfe8a..00000000000
--- a/extern/qhull/src/user_eg2.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
  ---------------------------------
-
-  user_eg2.c
-
-  sample code for calling qhull() from an application.
-
-  See user_eg.c for a simpler method using qh_new_qhull().
-  The method used here and in unix.c gives you additional
-  control over Qhull. 
-  
-  call with:
-
-     user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options"
-
-  for example:
-
-     user_eg2                             # return summaries
-
-     user_eg2 "n" "o" "Fp"                # return normals, OFF, points
-
-     user_eg2 "QR0 p" "QR0 v p" "QR0 Fp"  # rotate input and return points
-                                         # 'v' returns Voronoi
-					 # transform is rotated for halfspaces
-
-   main() makes three runs of qhull.
-
-     1) compute the convex hull of a cube, and incrementally add a diamond
-
-     2a) compute the Delaunay triangulation of random points, and add points.
-
-     2b) find the Delaunay triangle closest to a point.
-
-     3) compute the halfspace intersection of a diamond, and add a cube
-
- notes:
- 
-   summaries are sent to stderr if other output formats are used
-
-   derived from unix.c and compiled by 'make user_eg2'
-
-   see qhull.h for data structures, macros, and user-callable functions.
-   
-   If you want to control all output to stdio and input to stdin,
-   set the #if below to "1" and delete all lines that contain "io.c".  
-   This prevents the loading of io.o.  Qhull will
-   still write to 'qh ferr' (stderr) for error reporting and tracing.
-
-   Defining #if 1, also prevents user.o from being loaded.
-*/
-
-#include "qhull_a.h"
-
-/*-------------------------------------------------
--internal function prototypes
-*/
-void print_summary (void);
-void makecube (coordT *points, int numpoints, int dim);
-void adddiamond (coordT *points, int numpoints, int numnew, int dim);
-void makeDelaunay (coordT *points, int numpoints, int dim);
-void addDelaunay (coordT *points, int numpoints, int numnew, int dim);
-void findDelaunay (int dim);
-void makehalf (coordT *points, int numpoints, int dim);
-void addhalf (coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
-
-/*-------------------------------------------------
--print_summary()
-*/
-void print_summary (void) {
-  facetT *facet;
-  int k;
-
-  printf ("\n%d vertices and %d facets with normals:\n", 
-                 qh num_vertices, qh num_facets);
-  FORALLfacets {
-    for (k=0; k < qh hull_dim; k++) 
-      printf ("%6.2g ", facet->normal[k]);
-    printf ("\n");
-  }
-}
-
-/*--------------------------------------------------
--makecube- set points to vertices of cube
-  points is numpoints X dim
-*/
-void makecube (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; jvertices) {
-    for (k=0; k < dim-1; k++)
-      printf ("%5.2f ", vertex->point[k]);
-    printf ("\n");
-  }
-} /*.findDelaunay.*/
-
-/*--------------------------------------------------
--makehalf- set points to halfspaces for a (dim)-d diamond
-  points is numpoints X dim+1
-
-  each halfspace consists of dim coefficients followed by an offset
-*/
-void makehalf (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; j= 2 ? argv[1] : "");
-    qh_initflags (options);
-    printf( "\ncompute triangulated convex hull of cube after rotating input\n");
-    makecube (array[0], SIZEcube, DIM);
-    qh_init_B (array[0], SIZEcube, DIM, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_triangulate();  /* requires option 'Q11' if want to add points */ 
-    print_summary ();
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nadd points in a diamond\n");
-    adddiamond (array[0], SIZEcube, SIZEdiamond, DIM);
-    qh_check_output();
-    print_summary (); 
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-  }
-  qh NOerrexit= True;
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  /*
-    Run 2: Delaunay triangulation
-  */
-  qh_init_A (stdin, stdout, stderr, 0, NULL);
-  exitcode= setjmp (qh errexit);
-  if (!exitcode) {
-    coordT array[TOTpoints][DIM];
-
-    strcat (qh rbox_command, "user_eg Delaunay");
-    sprintf (options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
-    qh_initflags (options);
-    printf( "\ncompute 2-d Delaunay triangulation\n");
-    makeDelaunay (array[0], SIZEcube, DIM);
-    /* Instead of makeDelaunay with qh_setdelaunay, you may
-       produce a 2-d array of points, set DIM to 2, and set 
-       qh PROJECTdelaunay to True.  qh_init_B will call 
-       qh_projectinput to project the points to the paraboloid
-       and add a point "at-infinity".
-    */
-    qh_init_B (array[0], SIZEcube, DIM, ismalloc);
-    qh_qhull();
-    /* If you want Voronoi ('v') without qh_produce_output(), call
-       qh_setvoronoi_all() after qh_qhull() */
-    qh_check_output();
-    print_summary ();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nadd points to triangulation\n");
-    addDelaunay (array[0], SIZEcube, SIZEdiamond, DIM); 
-    qh_check_output();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
-    findDelaunay (DIM);
-  }
-  qh NOerrexit= True;
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  /*
-    Run 3: halfspace intersection
-  */
-  qh_init_A (stdin, stdout, stderr, 0, NULL);
-  exitcode= setjmp (qh errexit);
-  if (!exitcode) {
-    coordT array[TOTpoints][DIM+1];  /* +1 for halfspace offset */
-    pointT *points;
-
-    strcat (qh rbox_command, "user_eg halfspaces");
-    sprintf (options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
-    qh_initflags (options);
-    printf( "\ncompute halfspace intersection about the origin for a diamond\n");
-    makehalf (array[0], SIZEcube, DIM);
-    qh_setfeasible (DIM); /* from io.c, sets qh feasible_point from 'Hn,n' */
-    /* you may malloc and set qh feasible_point directly.  It is only used for
-       option 'Fp' */
-    points= qh_sethalfspace_all ( DIM+1, SIZEcube, array[0], qh feasible_point); 
-    qh_init_B (points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nadd halfspaces for cube to intersection\n");
-    addhalf (array[0], SIZEcube, SIZEdiamond, DIM, qh feasible_point); 
-    qh_check_output();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-  }
-  qh NOerrexit= True;
-  qh NOerrexit= True;
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong)  /* could also check previous runs */
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-  return exitcode;
-} /* main */
-
-#if 1    /* use 1 to prevent loading of io.o and user.o */
-/*-------------------------------------------
--errexit- return exitcode to system after an error
-  assumes exitcode non-zero
-  prints useful information
-  see qh_errexit2() in qhull.c for 2 facets
-*/
-void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
-
-  if (qh ERREXITcalled) {
-    fprintf (qh ferr, "qhull error while processing previous error.  Exit program\n");
-    exit(1);
-  }
-  qh ERREXITcalled= True;
-  if (!qh QHULLfinished)
-    qh hulltime= (unsigned)clock() - qh hulltime;
-  fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
-  fprintf(qh ferr, "Options selected:\n%s\n", qh qhull_options);
-  if (qh furthest_id >= 0) {
-    fprintf(qh ferr, "\nLast point added to hull was p%d", qh furthest_id);
-    if (zzval_(Ztotmerge))
-      fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
-    if (qh QHULLfinished)
-      fprintf(qh ferr, "\nQhull has finished constructing the hull.");
-    else if (qh POSTmerging)
-      fprintf(qh ferr, "\nQhull has started post-merging");
-    fprintf(qh ferr, "\n\n");
-  }
-  if (qh NOerrexit) {
-    fprintf (qh ferr, "qhull error while ending program.  Exit program\n");
-    exit(1);
-  }
-  if (!exitcode)
-    exitcode= qh_ERRqhull;
-  qh NOerrexit= True;
-  longjmp(qh errexit, exitcode);
-} /* errexit */
-
-
-/*-------------------------------------------
--errprint- prints out the information of the erroneous object
-    any parameter may be NULL, also prints neighbors and geomview output
-*/
-void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
-
-  fprintf (qh ferr, "%s facets f%d f%d ridge r%d vertex v%d\n",
-	   string, getid_(atfacet), getid_(otherfacet), getid_(atridge),
-	   getid_(atvertex));
-} /* errprint */
-
-
-void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
-  facetT *facet, **facetp;
-
-  /* remove these calls to help avoid io.c */
-  qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
-  FORALLfacet_(facetlist)                                              /*io.c*/
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
-  FOREACHfacet_(facets)                                                /*io.c*/
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
-  qh_printend (qh ferr, qh_PRINTfacets, facetlist, facets, printall);  /*io.c*/
-
-  FORALLfacet_(facetlist)
-    fprintf( qh ferr, "facet f%d\n", facet->id);
-} /* printfacetlist */
-
-
-
-/*-----------------------------------------
--user_memsizes- allocate up to 10 additional, quick allocation sizes
-*/
-void qh_user_memsizes (void) {
-
-  /* qh_memsize (size); */
-} /* user_memsizes */
-
-#endif
diff --git a/extern/solid/CMakeLists.txt b/extern/solid/CMakeLists.txt
deleted file mode 100644
index 7840dd6b423..00000000000
--- a/extern/solid/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-# $Id$
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2006, Blender Foundation
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): Jacques Beaurain.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-SET(INC include src src/broad src/complex src/convex ../qhull/include)
-
-FILE(GLOB SRC src/*.cpp src/convex/*.cpp src/complex/*.cpp src/broad/*.cpp)
-
-ADD_DEFINITIONS(-DUSE_DOUBLES -DQHULL -D_LIB)
-
-BLENDERLIB(extern_solid "${SRC}" "${INC}")
-#, libtype=['game2','player'], priority=[45, 75]
diff --git a/extern/solid/LICENSE_GPL.txt b/extern/solid/LICENSE_GPL.txt
deleted file mode 100644
index 07db89585a2..00000000000
--- a/extern/solid/LICENSE_GPL.txt
+++ /dev/null
@@ -1,349 +0,0 @@
-
- The SOLID library is Copyright (C) 2001-2003  Dtecta.
-
- You may use, distribute and copy the SOLID library under the terms of
- GNU General Public License version 2, which is displayed below.
-
--------------------------------------------------------------------------
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    
-    Copyright (C)   
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  , 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-
--------------------------------------------------------------------------
diff --git a/extern/solid/LICENSE_QPL.txt b/extern/solid/LICENSE_QPL.txt
deleted file mode 100644
index 3fca00466e2..00000000000
--- a/extern/solid/LICENSE_QPL.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-
- The SOLID library is Copyright (C) 2001-2003  Dtecta.
-
- You may use, distribute and copy the SOLID library under the terms of
- the Q Public License, which is displayed below.
-
--------------------------------------------------------------------------
-			     THE Q PUBLIC LICENSE
-				  version 1.0
-
-		   Copyright (C) 1999-2000 Trolltech AS, Norway.
-		       Everyone is permitted to copy and
-		       distribute this license document.
-
-The intent of this license is to establish freedom to share and change the
-software regulated by this license under the open source model.
-
-This license applies to any software containing a notice placed by the
-copyright holder saying that it may be distributed under the terms of
-the Q Public License version 1.0.  Such software is herein referred to as
-the Software.  This license covers modification and distribution of the
-Software, use of third-party application programs based on the Software,
-and development of free software which uses the Software.
-
-				 Granted Rights
-
-1. You are granted the non-exclusive rights set forth in this license
-   provided you agree to and comply with any and all conditions in this
-   license.  Whole or partial distribution of the Software, or software
-   items that link with the Software, in any form signifies acceptance of
-   this license.
-
-2. You may copy and distribute the Software in unmodified form provided
-   that the entire package, including - but not restricted to - copyright,
-   trademark notices and disclaimers, as released by the initial developer
-   of the Software, is distributed.
-
-3. You may make modifications to the Software and distribute your
-   modifications, in a form that is separate from the Software, such as
-   patches. The following restrictions apply to modifications:
-
-     a. Modifications must not alter or remove any copyright notices in
-        the Software.
-
-     b. When modifications to the Software are released under this
-        license, a non-exclusive royalty-free right is granted to the
-        initial developer of the Software to distribute your modification
-        in future versions of the Software provided such versions remain
-        available under these terms in addition to any other license(s) of
-        the initial developer.
-
-4. You may distribute machine-executable forms of the Software or
-   machine-executable forms of modified versions of the Software, provided
-   that you meet these restrictions:
-
-     a. You must include this license document in the distribution.
-
-     b. You must ensure that all recipients of the machine-executable forms
-        are also able to receive the complete machine-readable source code
-        to the distributed Software, including all modifications, without
-        any charge beyond the costs of data transfer, and place prominent
-        notices in the distribution explaining this.
-
-     c. You must ensure that all modifications included in the
-        machine-executable forms are available under the terms of this
-        license.
-
-5. You may use the original or modified versions of the Software to
-   compile, link and run application programs legally developed by you
-   or by others.
-
-6. You may develop application programs, reusable components and other
-   software items that link with the original or modified versions of the
-   Software.  These items, when distributed, are subject to the following
-   requirements:
-
-     a. You must ensure that all recipients of machine-executable forms of
-        these items are also able to receive and use the complete
-        machine-readable source code to the items without any charge
-        beyond the costs of data transfer.
-
-     b. You must explicitly license all recipients of your items to use
-        and re-distribute original and modified versions of the items in
-        both machine-executable and source code forms. The recipients must
-        be able to do so without any charges whatsoever, and they must be
-        able to re-distribute to anyone they choose.
-
-
-     c. If the items are not available to the general public, and the
-        initial developer of the Software requests a copy of the items,
-        then you must supply one.
-
-			    Limitations of Liability
-
-In no event shall the initial developers or copyright holders be liable
-for any damages whatsoever, including - but not restricted to - lost
-revenue or profits or other direct, indirect, special, incidental or
-consequential damages, even if they have been advised of the possibility
-of such damages, except to the extent invariable law, if any, provides
-otherwise.
-
-			          No Warranty
-
-The Software and this license document are provided AS IS with NO WARRANTY
-OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE.
-                                 Choice of Law
-
-This license is governed by the Laws of Norway. Disputes shall be settled
-by Oslo City Court.
diff --git a/extern/solid/Makefile b/extern/solid/Makefile
deleted file mode 100644
index 206dc21c3fb..00000000000
--- a/extern/solid/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
-# vim: tabstop=8
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): GSR
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-include nan_definitions.mk
-
-SOURCEDIR = extern/solid
-LIBNAMES = solid solid_broad solid_convex solid_complex
-DIR = $(OCGDIR)/extern/
-DIRS = src
-
-include nan_subdirs.mk
-
-install:  $(ALL_OR_DEBUG)
-	@[ -d $(NAN_SOLID) ] || mkdir -p $(NAN_SOLID)
-	@[ -d $(NAN_SOLID)/include/SOLID ] || mkdir -p $(NAN_SOLID)/include/SOLID
-	@[ -d $(NAN_SOLID)/include/SOLID/MT ] || mkdir -p $(NAN_SOLID)/include/SOLID/MT
-	@[ -d $(NAN_SOLID)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_SOLID)/lib/$(DEBUG_DIR)
-	@for i in $(LIBNAMES); do \
-	    $(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$$i/$(DEBUG_DIR)lib$$i.a $(NAN_SOLID)/lib/$(DEBUG_DIR) ; \
-	    if [ $(OS) = darwin ] ; then \
-            ranlib $(NAN_SOLID)/lib/$(DEBUG_DIR)lib$$i.a ; \
-        fi ; \
-	done
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh include/*.h $(NAN_SOLID)/include/SOLID
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh include/MT/*.h $(NAN_SOLID)/include/SOLID/MT
-
-
diff --git a/extern/solid/README.txt b/extern/solid/README.txt
deleted file mode 100644
index 348d92b35cb..00000000000
--- a/extern/solid/README.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-
-		 SOLID - Software Library for Interference Detection
-
-SOLID is a software library containing functions for performing
-intersection tests and proximity queries that are useful in the context
-of collision detection. Collision detection is the process of detecting
-pairs of geometric objects that are intersecting or are within a given
-proximity of each other. In particular, SOLID is useful for detecting
-collisions between objects that are moving relatively of each other over
-time. The motions of objects are controlled by the client application,
-and are not determined or affected by SOLID. 
-
-This open-source edition of SOLID version 3 is released under the terms of
-either the GNU Public License (GPL) or the Q Public License (QPL). This means
-that for software created with SOLID version 3 you must comply with the terms
-of one of these licenses. You may choose wich of these licenses best suits
-your purpose. See the following files contained in this distribution for a
-complete list of terms and conditions of these licenses:  
-
-		 LICENSE_QPL.txt	 The Q Public License 
-		 LICENSE_GPL.txt	 The GNU General Public License
-
-These licenses do not permit the use of SOLID 3 in closed-source software
-products. For enquiries about commercial use of SOLID, please contact
-info@dtecta.com.    
-
-SOLID 3 uses Qhull from The Geometry Center of the University of Minnesota.
-Qhull is copyrighted as noted below.  Qhull is free software and may be
-obtained via anonymous ftp from geom.umn.edu.   
-        
-                    Qhull, Copyright (c) 1993-2002
-
-       The National Science and Technology Research Center for
-        Computation and Visualization of Geometric Structures
-                        (The Geometry Center)
-                       University of Minnesota
-                            400 Lind Hall
-                        207 Church Street S.E.
-                      Minneapolis, MN 55455  USA
-
-                       email: qhull@geom.umn.edu
-
-Installation
-
-For details on how to install SOLID see the documention in the 'doc' directory.
-
-Platforms
-
-SOLID 3 has been tested on the following platforms:
-
-    Linux IA32  gcc 2.95.3, gcc 3.3
-	Win32		MSVC++ 6.0 SP4, MSVC++ 7.1 
-
-  
-
diff --git a/extern/solid/SConscript b/extern/solid/SConscript
deleted file mode 100644
index 8c54442ca73..00000000000
--- a/extern/solid/SConscript
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-import sys
-
-Import('env')
-
-defs = 'USE_DOUBLES QHULL _LIB'
-cflags = []
-
-if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
-    defs += ' WIN32 NDEBUG _WINDOWS _LIB'
-    cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6']
-elif env['OURPLATFORM']=='win32-mingw':
-    defs += ' NDEBUG'
-    cflags += ['-O2']
-elif sys.platform=='linux2' or sys.platform=='linux-i386' or sys.platform=='freebsd4' or sys.platform=='freebsd5' or sys.platform=='openbsd3' or sys.platform=='sunos5':
-    defs += ' NDEBUG'
-    cflags += ['-O2']
-elif sys.platform=='darwin' :
-    defs += ' NDEBUG'
-    cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math']
-
-else:
-    print "################################################"
-    print 
-    print "Check if solid builds on your platform correctly"
-    print "Add your platform specific defines"
-    print "and cflags / cxxflags to the"
-    print "extern/solid/SConscript file"
-
-sources = env.Glob('src/*.cpp') + env.Glob('src/convex/*.cpp') + env.Glob('src/complex/*.cpp') + env.Glob('src/broad/*.cpp')
-
-incs = 'include src src/broad src/complex src/convex ../qhull/include'
-
-env.BlenderLib ( libname='extern_solid', sources=sources, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[10] , compileflags = cflags)
diff --git a/extern/solid/SOLID/SOLID.h b/extern/solid/SOLID/SOLID.h
deleted file mode 100644
index 37d74340f8c..00000000000
--- a/extern/solid/SOLID/SOLID.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_H
-#define SOLID_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" { 
-#endif
-    
-	DT_DECLARE_HANDLE(DT_ObjectHandle);
-	DT_DECLARE_HANDLE(DT_SceneHandle);
-	DT_DECLARE_HANDLE(DT_ShapeHandle);
-	DT_DECLARE_HANDLE(DT_VertexBaseHandle);
-	DT_DECLARE_HANDLE(DT_RespTableHandle);
-	DT_DECLARE_HANDLE(DT_ArchiveHandle);
-
-	typedef unsigned int DT_ResponseClass;
-
-	typedef enum DT_ResponseType { 
-		DT_NO_RESPONSE,                  /* No response (obsolete) */        
-		DT_BROAD_RESPONSE,      
-		DT_SIMPLE_RESPONSE,              /* No collision data */
-		DT_WITNESSED_RESPONSE,           /* A point common to both objects
-											is returned as collision data
-										 */
-		DT_DEPTH_RESPONSE                /* The penetration depth is returned
-											as collision data. The penetration depth
-											is the shortest vector over which one 
-											object needs to be translated in order
-											to bring the objects in touching contact. 
-										 */ 
-	} DT_ResponseType;
-    
-/* For witnessed response, the following structure represents a common point. The world 
-   coordinates of 'point1' and 'point2' coincide. 'normal' is the zero vector.
-   
-   For depth response, the following structure represents the penetration depth. 
-   'point1' en 'point2' are the witness points of the penetration depth in world coordinates.
-   The penetration depth vector in world coordinates is represented by 'normal'.
-*/
-
-	typedef struct DT_CollData {
-		DT_Vector3 point1;               /* Point in object1 in world coordinates */ 
-		DT_Vector3 point2;               /* Point in object2 in world coordinates */
-		DT_Vector3 normal;               /* point2 - point1 */ 
-	} DT_CollData;
-
-/* A response callback is called by SOLID for each pair of collding objects. 'client-data'
-   is a pointer to an arbitrary structure in the client application. The client objects are
-   pointers to structures in the client application associated with the coliding objects.
-   'coll_data' is the collision data computed by SOLID.
-*/
-
-	typedef DT_Bool (*DT_ResponseCallback)(void *client_data,
-										   void *client_object1,
-										   void *client_object2,
-										   const DT_CollData *coll_data);
-										
-/* Shape definition */
-
-
-	extern DECLSPEC DT_ShapeHandle DT_NewBox(DT_Scalar x, DT_Scalar y, DT_Scalar z);
-	extern DECLSPEC DT_ShapeHandle DT_NewCone(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewCylinder(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewSphere(DT_Scalar radius);
-	extern DECLSPEC DT_ShapeHandle DT_NewPoint(const DT_Vector3 point);
-	extern DECLSPEC DT_ShapeHandle DT_NewLineSegment(const DT_Vector3 source, const DT_Vector3 target);
-	extern DECLSPEC DT_ShapeHandle DT_NewMinkowski(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-	extern DECLSPEC DT_ShapeHandle DT_NewHull(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-
-	extern DECLSPEC DT_VertexBaseHandle DT_NewVertexBase(const void *pointer, DT_Size stride);
-	extern DECLSPEC void DT_DeleteVertexBase(DT_VertexBaseHandle vertexBase);	
-	extern DECLSPEC void DT_ChangeVertexBase(DT_VertexBaseHandle vertexBase, const void *pointer);
-
-	extern DECLSPEC DT_ShapeHandle DT_NewComplexShape(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndComplexShape();
-
-	extern DECLSPEC DT_ShapeHandle DT_NewPolytope(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndPolytope();
-
-	extern DECLSPEC void DT_Begin();
-	extern DECLSPEC void DT_End();
-
-	extern DECLSPEC void DT_Vertex(const DT_Vector3 vertex);
-	extern DECLSPEC void DT_VertexIndex(DT_Index index);
-
-	extern DECLSPEC void DT_VertexIndices(DT_Count count, const DT_Index *indices);
-	extern DECLSPEC void DT_VertexRange(DT_Index first, DT_Count count); 
-
-	extern DECLSPEC void DT_DeleteShape(DT_ShapeHandle shape);
-
-/* Object  */
-
-	extern DECLSPEC DT_ObjectHandle DT_CreateObject(
-		void *client_object,      /* pointer to object in client memory */
-		DT_ShapeHandle shape  /* the shape or geometry of the object */
-		);
-
-	extern DECLSPEC void DT_DestroyObject(DT_ObjectHandle object);
-
-
-
-	extern DECLSPEC void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position);
-	extern DECLSPEC void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation);
-	extern DECLSPEC void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling);
-
-/* The margin is an offset from the actual shape. The actual geometry of an
-   object is the set of points whose distance to the transformed shape is at 
-   most the  margin. During the lifetime of an object the margin can be 
-   modified. 
-*/
-   
-	extern DECLSPEC void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin);
-
-
-/* These commands assume a column-major 4x4 OpenGL matrix representation */
-
-	extern DECLSPEC void DT_SetMatrixf(DT_ObjectHandle object, const float *m); 
-	extern DECLSPEC void DT_GetMatrixf(DT_ObjectHandle object, float *m); 
-
-	extern DECLSPEC void DT_SetMatrixd(DT_ObjectHandle object, const double *m); 
-	extern DECLSPEC void DT_GetMatrixd(DT_ObjectHandle object, double *m); 
-
-	extern DECLSPEC void DT_GetBBox(DT_ObjectHandle object, DT_Vector3 min, DT_Vector3 max);
-
-
-	extern DECLSPEC DT_Bool  DT_GetIntersect(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 v);
-/* This next command returns the distance between the objects. De returned
-   closest points are given in world coordinates.
-*/
-	extern DECLSPEC DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point1, DT_Vector3 point2);  
-
-	extern DECLSPEC DT_Bool   DT_GetCommonPoint(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point);
-
-	extern DECLSPEC DT_Bool   DT_GetPenDepth(DT_ObjectHandle object1, DT_ObjectHandle object2,
-											 DT_Vector3 point1, DT_Vector3 point2);  
-
-/* Scene */
-
-	extern DECLSPEC DT_SceneHandle DT_CreateScene(); 
-	extern DECLSPEC void           DT_DestroyScene(DT_SceneHandle scene);
-
-	extern DECLSPEC void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object);
-	extern DECLSPEC void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object);
-
-/* Note that objects can be assigned to multiple scenes! */
-
-/* Response */
-
-/* Response tables are defined independent of the scenes in which they are used.
-   Multiple response tables can be used in one scene, and a response table
-   can be shared among scenes.
-*/
-	extern DECLSPEC DT_RespTableHandle DT_CreateRespTable(); 
-	extern DECLSPEC void               DT_DestroyRespTable(DT_RespTableHandle respTable); 
-
-/* Responses are defined on (pairs of) response classes. Each response table 
-   maintains its set of response classes.
-*/
-	extern DECLSPEC DT_ResponseClass DT_GenResponseClass(DT_RespTableHandle respTable);
-
-/* To each object for which a response is defined in the response table a
-   response class needs to be assigned. 
-*/
-
-	extern DECLSPEC void DT_SetResponseClass(DT_RespTableHandle respTable,
-											 DT_ObjectHandle object,
-											 DT_ResponseClass responseClass);
-
-	extern DECLSPEC void DT_ClearResponseClass(DT_RespTableHandle respTable, 
-											   DT_ObjectHandle object);
-
-	extern DECLSPEC void DT_CallResponse(DT_RespTableHandle respTable,
-										 DT_ObjectHandle object1,
-										 DT_ObjectHandle object2,
-										 const DT_CollData *coll_data);
-
-/* For each pair of objects multiple responses can be defined. A response is a callback
-   together with its response type and client data. */
-    
-/* Responses can be defined for all pairs of response classes... */
-	extern DECLSPEC void DT_AddDefaultResponse(DT_RespTableHandle respTable,
-											   DT_ResponseCallback response, 
-											   DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveDefaultResponse(DT_RespTableHandle respTable,
-												  DT_ResponseCallback response);
-/* ...per response class... */
-	extern DECLSPEC void DT_AddClassResponse(DT_RespTableHandle respTable,
-											 DT_ResponseClass responseClass,
-											 DT_ResponseCallback response,
-											 DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveClassResponse(DT_RespTableHandle respTable,
-												DT_ResponseClass responseClass,
-												DT_ResponseCallback response);
-
-/* ... and per pair of response classes...*/
-	extern DECLSPEC void DT_AddPairResponse(DT_RespTableHandle respTable,
-											DT_ResponseClass responseClass1,
-											DT_ResponseClass responseClass2, 
-											DT_ResponseCallback response,
-											DT_ResponseType type, void *client_data);
-	extern DECLSPEC void DT_RemovePairResponse(DT_RespTableHandle respTable,
-											   DT_ResponseClass responseClass1,
-											   DT_ResponseClass responseClass2,
-											   DT_ResponseCallback response);
-
-/* The next command calls the response callbacks for all intersecting pairs of objects in a scene. 
-   'DT_Test' returns the number of pairs of objects for which callbacks have been called. 
-*/
- 
-	extern DECLSPEC DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable);
-
-/* Set the maximum relative error in the closest points and penetration depth
-   computation. The default for `max_error' is 1.0e-3. Larger errors result
-   in better performance. Non-positive error tolerances are ignored.
-*/ 
-
-	extern DECLSPEC void DT_SetAccuracy(DT_Scalar max_error);
-
-/* Set the maximum tolerance on relative errors due to rounding.  The default for `tol_error' 
-   is the machine epsilon. Very large tolerances result in false collisions. Setting tol_error too small 
-   results in missed collisions. Non-positive error tolerances are ignored. 
-*/ 
-    
-	extern DECLSPEC void DT_SetTolerance(DT_Scalar tol_error);
-
-
-/* This function returns the client pointer to the first object in a scene hit by the ray 
-   (actually a line segment) defined by the points 'from' en 'to'. The spot is the hit point 
-   on the object in local coordinates. 'normal' is the normal to the surface of the object in
-   world coordinates. The ignore_client pointer is used to make one of the objects transparent.
-
-   NB: Currently ray tests are implemented for spheres, boxes, and meshes only!!
-*/   
-
-	extern DECLSPEC void *DT_RayCast(DT_SceneHandle scene, void *ignore_client,
-									 const DT_Vector3 source, const DT_Vector3 target,
-									 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-/* Similar, only here a single object is tested and a boolean is returned */
-
-	extern DECLSPEC DT_Bool DT_ObjectRayCast(DT_ObjectHandle object,
-											 const DT_Vector3 source, const DT_Vector3 target,
-											 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/SOLID/SOLID_broad.h b/extern/solid/SOLID/SOLID_broad.h
deleted file mode 100644
index 74e4214fa67..00000000000
--- a/extern/solid/SOLID/SOLID_broad.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_BROAD_H
-#define SOLID_BROAD_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    
-	DT_DECLARE_HANDLE(BP_SceneHandle);
-	DT_DECLARE_HANDLE(BP_ProxyHandle);
-	
-	typedef void (*BP_Callback)(void *client_data,
-								void *object1,
-								void *object2);
-
-	typedef bool (*BP_RayCastCallback)(void *client_data,
-									   void *object,
-									   const DT_Vector3 source,
-									   const DT_Vector3 target,
-									   DT_Scalar *lambda);
-	
-	extern DECLSPEC BP_SceneHandle BP_CreateScene(void *client_data,
-												  BP_Callback beginOverlap,
-												  BP_Callback endOverlap);
-	
-	extern DECLSPEC void           BP_DestroyScene(BP_SceneHandle scene);
-	
-	extern DECLSPEC BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, 
-												  void *object,
-												  const DT_Vector3 min, 
-												  const DT_Vector3 max);
-	
-	extern DECLSPEC void           BP_DestroyProxy(BP_SceneHandle scene, 
-												  BP_ProxyHandle proxy);
-	
-	extern DECLSPEC void BP_SetBBox(BP_ProxyHandle proxy, 
-									const DT_Vector3 min, 
-									const DT_Vector3 max);
-	
-	extern DECLSPEC void *BP_RayCast(BP_SceneHandle scene, 
-									 BP_RayCastCallback objectRayCast, 
-									 void *client_data,
-									 const DT_Vector3 source,
-									 const DT_Vector3 target,
-									 DT_Scalar *lambda);		
-	
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/SOLID/SOLID_types.h b/extern/solid/SOLID/SOLID_types.h
deleted file mode 100644
index 630594e447f..00000000000
--- a/extern/solid/SOLID/SOLID_types.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_TYPES_H
-#define SOLID_TYPES_H
-
-#ifndef DECLSPEC
-# ifdef WIN32
-#  define DECLSPEC __declspec(dllexport)
-# else
-#  define DECLSPEC
-# endif
-#endif
-
-#define DT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
-    
-
-typedef unsigned short DT_Index;
-typedef unsigned short DT_Count;
-typedef unsigned int   DT_Size;
-typedef float          DT_Scalar; 
-typedef int            DT_Bool;
-
-#define DT_FALSE 0
-#define DT_TRUE  1
-
-#define DT_CONTINUE 0
-#define DT_DONE 1
-
-typedef DT_Scalar DT_Vector3[3]; 
-typedef DT_Scalar DT_Quaternion[4]; 
-
-#endif
diff --git a/extern/solid/VisualC6/broad/broad.dsp b/extern/solid/VisualC6/broad/broad.dsp
deleted file mode 100644
index 1161d68fcd6..00000000000
--- a/extern/solid/VisualC6/broad/broad.dsp
+++ /dev/null
@@ -1,132 +0,0 @@
-# Microsoft Developer Studio Project File - Name="broad" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=broad - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "broad.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "broad.mak" CFG="broad - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "broad - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "broad - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "broad - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "broad - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "broad - Win32 Release"
-# Name "broad - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\..\src\broad\BP_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_EndpointList.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Proxy.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Scene.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Endpoint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_EndpointList.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Proxy.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_ProxyList.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Scene.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/complex/complex.dsp b/extern/solid/VisualC6/complex/complex.dsp
deleted file mode 100644
index 74ea67b9e23..00000000000
--- a/extern/solid/VisualC6/complex/complex.dsp
+++ /dev/null
@@ -1,116 +0,0 @@
-# Microsoft Developer Studio Project File - Name="complex" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=complex - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "complex.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "complex.mak" CFG="complex - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "complex - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "complex - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "complex - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../../src/convex" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "complex - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /I "../../src/convex" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "complex - Win32 Release"
-# Name "complex - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_BBoxTree.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_Complex.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_BBoxTree.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_CBox.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_Complex.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/convex/convex.dsp b/extern/solid/VisualC6/convex/convex.dsp
deleted file mode 100644
index ec9caace9d9..00000000000
--- a/extern/solid/VisualC6/convex/convex.dsp
+++ /dev/null
@@ -1,232 +0,0 @@
-# Microsoft Developer Studio Project File - Name="convex" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=convex - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "convex.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "convex.mak" CFG="convex - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "convex - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "convex - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "convex - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../../../qhull/include" /D "NDEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "convex - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /I "../../../qhull/include" /D "_DEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "convex - Win32 Release"
-# Name "convex - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Accuracy.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Box.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cone.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Convex.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cylinder.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Facet.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_LineSegment.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_PenDepth.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Point.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polyhedron.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polytope.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Sphere.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Triangle.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Accuracy.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Array.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Box.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cone.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Convex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cylinder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Facet.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_GJK.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Hull.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_IndexArray.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_LineSegment.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Minkowski.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_PenDepth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Point.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polyhedron.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polytope.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Shape.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Sphere.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Transform.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Triangle.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_VertexBase.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/dynamics/dynamics.dsp b/extern/solid/VisualC6/dynamics/dynamics.dsp
deleted file mode 100644
index 9659cbf8a56..00000000000
--- a/extern/solid/VisualC6/dynamics/dynamics.dsp
+++ /dev/null
@@ -1,120 +0,0 @@
-# Microsoft Developer Studio Project File - Name="dynamics" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=dynamics - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "dynamics.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "dynamics.mak" CFG="dynamics - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "dynamics - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "dynamics - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "dynamics - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "dynamics - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "dynamics - Win32 Release"
-# Name "dynamics - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Dynamic.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Kinetic.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\RigidBody.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Dynamic.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Kinetic.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\RigidBody.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/gldemo/gldemo.dsp b/extern/solid/VisualC6/gldemo/gldemo.dsp
deleted file mode 100644
index f3cde286161..00000000000
--- a/extern/solid/VisualC6/gldemo/gldemo.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="gldemo" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=gldemo - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "gldemo.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "gldemo.mak" CFG="gldemo - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "gldemo - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "gldemo - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "gldemo - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "gldemo - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "gldemo - Win32 Release"
-# Name "gldemo - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\gldemo.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/mnm/mnm.dsp b/extern/solid/VisualC6/mnm/mnm.dsp
deleted file mode 100644
index 2df6d951794..00000000000
--- a/extern/solid/VisualC6/mnm/mnm.dsp
+++ /dev/null
@@ -1,100 +0,0 @@
-# Microsoft Developer Studio Project File - Name="mnm" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=mnm - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "mnm.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "mnm.mak" CFG="mnm - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "mnm - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "mnm - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "mnm - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "mnm - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "mnm - Win32 Release"
-# Name "mnm - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\mnm.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/physics/physics.dsp b/extern/solid/VisualC6/physics/physics.dsp
deleted file mode 100644
index dd69b6a35b2..00000000000
--- a/extern/solid/VisualC6/physics/physics.dsp
+++ /dev/null
@@ -1,100 +0,0 @@
-# Microsoft Developer Studio Project File - Name="physics" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=physics - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "physics.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "physics.mak" CFG="physics - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "physics - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "physics - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "physics - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "physics - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "physics - Win32 Release"
-# Name "physics - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\physics.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/sample/sample.dsp b/extern/solid/VisualC6/sample/sample.dsp
deleted file mode 100644
index c6e0423cd04..00000000000
--- a/extern/solid/VisualC6/sample/sample.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sample" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=sample - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "sample.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "sample.mak" CFG="sample - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "sample - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "sample - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "sample - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "sample - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "sample - Win32 Release"
-# Name "sample - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\sample.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/solid.dsw b/extern/solid/VisualC6/solid.dsw
deleted file mode 100644
index 397cc4bf371..00000000000
--- a/extern/solid/VisualC6/solid.dsw
+++ /dev/null
@@ -1,89 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "broad"=".\broad\broad.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "complex"=".\complex\complex.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "convex"=".\convex\convex.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name qhull
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "qhull"="..\..\qhull\VisualC6\qhull\qhull.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "solid"=".\solid\solid.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name broad
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name complex
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name convex
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/extern/solid/VisualC6/solid/solid.dsp b/extern/solid/VisualC6/solid/solid.dsp
deleted file mode 100644
index 4ac7459c2f9..00000000000
--- a/extern/solid/VisualC6/solid/solid.dsp
+++ /dev/null
@@ -1,148 +0,0 @@
-# Microsoft Developer Studio Project File - Name="solid" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=solid - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "solid.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "solid.mak" CFG="solid - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "solid - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "solid - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "solid - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "NDEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=XCOPY   /Y   ..\..\include\SOLID*.h   ..\..\..\..\..\lib\windows\solid\include\solid\  	XCOPY   /Y   Release\*.lib   ..\..\..\..\..\lib\windows\solid\lib\ 
-# End Special Build Tool
-
-!ELSEIF  "$(CFG)" == "solid - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "_DEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=XCOPY   /Y   ..\..\include\SOLID*.h   ..\..\..\..\..\lib\windows\solid\include\solid\  	XCOPY   /Y   Debug\*.lib   ..\..\..\..\..\lib\windows\solid\lib\Debug\ 
-# End Special Build Tool
-
-!ENDIF 
-
-# Begin Target
-
-# Name "solid - Win32 Release"
-# Name "solid - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\..\src\DT_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\DT_AlgoTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Response.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/solid_dll/solid_dll.dsp b/extern/solid/VisualC6/solid_dll/solid_dll.dsp
deleted file mode 100644
index eed092502e0..00000000000
--- a/extern/solid/VisualC6/solid_dll/solid_dll.dsp
+++ /dev/null
@@ -1,147 +0,0 @@
-# Microsoft Developer Studio Project File - Name="solid_dll" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=solid_dll - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "solid_dll.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "solid_dll.mak" CFG="solid_dll - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "solid_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "solid_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "solid_dll - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "../../lib/win32/vc6"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "NDEBUG" /D "USE_DOUBLES" /D "QHULL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../lib/win32/vc6/solid.dll"
-
-!ELSEIF  "$(CFG)" == "solid_dll - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "../../lib/win32/vc6"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "_DEBUG" /D "QHULL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../lib/win32/vc6/solidd.dll" /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "solid_dll - Win32 Release"
-# Name "solid_dll - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\..\src\DT_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\DT_AlgoTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Response.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/include/GEN_MinMax.h b/extern/solid/include/GEN_MinMax.h
deleted file mode 100644
index 9ea961cfe4f..00000000000
--- a/extern/solid/include/GEN_MinMax.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef GEN_MINMAX_H
-#define GEN_MINMAX_H
-
-template 
-inline const T& GEN_min(const T& a, const T& b) 
-{
-  return b < a ? b : a;
-}
-
-template 
-inline const T& GEN_max(const T& a, const T& b) 
-{
-  return  a < b ? b : a;
-}
-
-template 
-inline const T& GEN_clamped(const T& a, const T& lb, const T& ub) 
-{
-	return a < lb ? lb : (ub < a ? ub : a); 
-}
-
-template 
-inline void GEN_set_min(T& a, const T& b) 
-{
-    if (b < a) 
-	{
-		a = b;
-	}
-}
-
-template 
-inline void GEN_set_max(T& a, const T& b) 
-{
-    if (a < b) 
-	{
-		a = b;
-	}
-}
-
-template 
-inline void GEN_clamp(T& a, const T& lb, const T& ub) 
-{
-	if (a < lb) 
-	{
-		a = lb; 
-	}
-	else if (ub < a) 
-	{
-		a = ub;
-	}
-}
-
-#endif
diff --git a/extern/solid/include/GEN_random.h b/extern/solid/include/GEN_random.h
deleted file mode 100644
index 4690a05511a..00000000000
--- a/extern/solid/include/GEN_random.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef GEN_RANDOM_H
-#define GEN_RANDOM_H
-
-#ifdef MT19937
-
-#include 
-#include 
-
-#define GEN_RAND_MAX UINT_MAX
-
-inline void         GEN_srand(unsigned int seed) { init_genrand(seed); }
-inline unsigned int GEN_rand()                   { return genrand_int32(); }
-
-#else
-
-#include 
-
-#define GEN_RAND_MAX RAND_MAX
-
-inline void         GEN_srand(unsigned int seed) { srand(seed); } 
-inline unsigned int GEN_rand()                   { return rand(); }
-
-#endif
-
-#endif
-
diff --git a/extern/solid/include/MT/Interval.h b/extern/solid/include/MT/Interval.h
deleted file mode 100644
index c6ba2fc1681..00000000000
--- a/extern/solid/include/MT/Interval.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef INTERVAL_H
-#define INTERVAL_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include 
-#include 
-
-namespace MT {
-
-	template 
-	class Interval {
-	public:
-		Interval() {}
-		
-
-#if _MSC_VER <= 1200
-        explicit Interval(const Scalar& x) 
-		    : m_lb(x), m_ub(x)
-	    {}
-        
- 
-		Interval(const Scalar& lb, const Scalar& ub) 
-			: m_lb(lb), m_ub(ub)
-		{
-			assert(lb <= ub);
-		}
-#else
-		template 
-		explicit Interval(const Scalar2& x) 
-			: m_lb(x), m_ub(x)
-		{}
-		
-		template 
-		Interval(const Scalar2& lb, const Scalar2& ub) 
-			: m_lb(lb), m_ub(ub)
-		{
-			assert(lb <= ub);
-		}
-		
-		template 
-		Interval(const Interval& z) 
-		{ 
-			*this = z; 
-		}
-		
-		template 
-		Interval& operator=(const Interval& z) 
-		{ 
-			m_lb = Scalar(z.lower()); 
-			m_ub = Scalar(z.upper()); 
-			return *this;
-		}
-#endif
-      
-		
-
-		Scalar&       lower()       { return m_lb; }
-		const Scalar& lower() const { return m_lb; }
-		
-		Scalar&       upper()       { return m_ub; }
-		const Scalar& upper() const { return m_ub; }
-		 
-		Scalar center() const { return (m_lb + m_ub) * Scalar(0.5); } 
-		Scalar extent() const { return (m_ub - m_lb) * Scalar(0.5); } 
-
-	
-	protected:
-		Scalar m_lb, m_ub;
-	};
-
-	template 
-	inline Interval 
-	operator+(const Interval& z1, const Interval& z2)
-	{
-		return Interval(z1.lower() + z2.lower(), 
-								z1.upper() + z2.upper());
-	}
-
-	template 
-	inline Interval 
-	operator-(const Interval& z1, const Interval& z2)
-	{
-		return Interval(z1.lower() - z2.upper(), 
-								z1.upper() - z2.lower());
-	}
-	
-	template 
-	inline std::ostream& 
-	operator<<(std::ostream& os, const Interval& z)
-	{
-		return os << '[' << z.lower() << ", " << z.upper() << ']';
-	}
-
-	template 
-	inline Scalar 
-	median(const Interval& z) 
-	{
-		return (z.lower() + z.upper()) * Scalar(0.5);
-	}
-	
-	template 
-	inline Scalar 
-	width(const Interval& z) 
-	{
-		return z.upper() - z.lower();
-	}
-	
-	template 
-	inline bool 
-	overlap(const Interval& z1, const Interval& z2) 
-	{
-		return z1.lower() <= z2.upper() && z2.lower() <= z1.upper();
-	}
-
-	template 
-	inline bool 
-	in(const Interval& z1, const Interval& z2) 
-	{
-		return z2.lower() <= z1.lower() && z1.upper() <= z2.upper();
-	}
-
-	template 
-	inline bool 
-	in(Scalar x, const Interval& z) 
-	{
-		return z.lower() <= x && x <= z.upper();
-	}
-	
-	template 
-	inline Interval 
-	widen(const Interval& z, const Scalar& x) 
-	{
-		return Interval(z.lower() - x, z.upper() + x);
-	}	
-		
-	template
-	inline Interval
-	hull(const Interval& z1, const Interval& z2)
-	{
-		return Interval(GEN_min(z1.lower(), z2.lower()), 
-								GEN_max(z1.upper(), z2.upper()));
-	}	
-   
-   template
-	inline Interval
-	operator+(Scalar x, const Interval& z)
-	{
-		return Interval(x + z.lower(), x + z.upper());
-	}
-}
-
-#endif
diff --git a/extern/solid/include/MT/Matrix3x3.h b/extern/solid/include/MT/Matrix3x3.h
deleted file mode 100644
index 85e0d4cac84..00000000000
--- a/extern/solid/include/MT/Matrix3x3.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MATRIX3X3_H
-#define MATRIX3X3_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include "Vector3.h"
-#include "Quaternion.h"
-
-namespace MT {
-
-  // Row-major 3x3 matrix
-  
-	template 
-	class Matrix3x3 {
-	public:
-		Matrix3x3() {}
-		
-		template 
-		explicit Matrix3x3(const Scalar2 *m) { setValue(m); }
-		
-		explicit Matrix3x3(const Quaternion& q) { setRotation(q); }
-		
-		template 
-		Matrix3x3(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll)
-		{ 
-			setEuler(yaw, pitch, roll);
-		}
-		
-		template 
-		Matrix3x3(const Scalar2& xx, const Scalar2& xy, const Scalar2& xz,
-				  const Scalar2& yx, const Scalar2& yy, const Scalar2& yz,
-				  const Scalar2& zx, const Scalar2& zy, const Scalar2& zz)
-		{ 
-			setValue(xx, xy, xz, 
-					 yx, yy, yz, 
-					 zx, zy, zz);
-		}
-		
-		Vector3&  operator[](int i)
-		{ 
-			assert(0 <= i && i < 3);
-			return m_el[i]; 
-		}
-		
-		const Vector3& operator[](int i) const
-		{
-			assert(0 <= i && i < 3);
-			return m_el[i]; 
-		}
-		
-		Matrix3x3& operator*=(const Matrix3x3& m); 
-		
-		template 
-		void setValue(const Scalar2 *m)
-		{
-			m_el[0][0] = Scalar(m[0]); 
-			m_el[1][0] = Scalar(m[1]); 
-			m_el[2][0] = Scalar(m[2]);
-			m_el[0][1] = Scalar(m[4]); 
-			m_el[1][1] = Scalar(m[5]); 
-			m_el[2][1] = Scalar(m[6]);
-			m_el[0][2] = Scalar(m[8]); 
-			m_el[1][2] = Scalar(m[9]); 
-			m_el[2][2] = Scalar(m[10]);
-		}
-
-		template 
-		void setValue(const Scalar2& xx, const Scalar2& xy, const Scalar2& xz, 
-					  const Scalar2& yx, const Scalar2& yy, const Scalar2& yz, 
-					  const Scalar2& zx, const Scalar2& zy, const Scalar2& zz)
-		{
-			m_el[0][0] = Scalar(xx); 
-			m_el[0][1] = Scalar(xy); 
-			m_el[0][2] = Scalar(xz);
-			m_el[1][0] = Scalar(yx); 
-			m_el[1][1] = Scalar(yy); 
-			m_el[1][2] = Scalar(yz);
-			m_el[2][0] = Scalar(zx); 
-			m_el[2][1] = Scalar(zy); 
-			m_el[2][2] = Scalar(zz);
-		}
-  
-		void setRotation(const Quaternion& q) 
-		{
-			Scalar d = q.length2();
-			assert(d != Scalar(0.0));
-			Scalar s = Scalar(2.0) / d;
-			Scalar xs = q[0] * s,   ys = q[1] * s,   zs = q[2] * s;
-			Scalar wx = q[3] * xs,  wy = q[3] * ys,  wz = q[3] * zs;
-			Scalar xx = q[0] * xs,  xy = q[0] * ys,  xz = q[0] * zs;
-			Scalar yy = q[1] * ys,  yz = q[1] * zs,  zz = q[2] * zs;
-			setValue(Scalar(1.0) - (yy + zz), xy - wz, xz + wy,
-					 xy + wz, Scalar(1.0) - (xx + zz), yz - wx,
-					 xz - wy, yz + wx, Scalar(1.0) - (xx + yy));
-		}
-		
-		template  
-		void setEuler(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll) 
-		{
-			Scalar cy(Scalar_traits::cos(yaw)); 
-			Scalar sy(Scalar_traits::sin(yaw)); 
-			Scalar cp(Scalar_traits::cos(pitch)); 
-			Scalar sp(Scalar_traits::sin(pitch)); 
-			Scalar cr(Scalar_traits::cos(roll));
-			Scalar sr(Scalar_traits::sin(roll));
-			Scalar cc = cy * cr; 
-			Scalar cs = cy * sr; 
-			Scalar sc = sy * cr; 
-			Scalar ss = sy * sr;
-			setValue(cy * cp, -sc + sp * cs,  ss - sp * cc,
-					 sy * cp,  cc + sp * ss, -cs + sp * sc,
-					     -sp,       cp * sr,       cp * cr);
-		}
-		void setIdentity()
-		{ 
-			setValue(Scalar(1.0), Scalar(0.0), Scalar(0.0), 
-					 Scalar(0.0), Scalar(1.0), Scalar(0.0), 
-					 Scalar(0.0), Scalar(0.0), Scalar(1.0)); 
-		}
-    
-		template 
-		void getValue(Scalar2 *m) const 
-		{
-			m[0]  = Scalar2(m_el[0][0]); 
-			m[1]  = Scalar2(m_el[1][0]);
-			m[2]  = Scalar2(m_el[2][0]);
-			m[3]  = Scalar2(0.0); 
-			m[4]  = Scalar2(m_el[0][1]);
-			m[5]  = Scalar2(m_el[1][1]);
-			m[6]  = Scalar2(m_el[2][1]);
-			m[7]  = Scalar2(0.0); 
-			m[8]  = Scalar2(m_el[0][2]); 
-			m[9]  = Scalar2(m_el[1][2]);
-			m[10] = Scalar2(m_el[2][2]);
-			m[11] = Scalar2(0.0); 
-		}
-		
-		void getRotation(Quaternion& q) const
-		{
-			Scalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2];
-			
-			if (trace > Scalar(0.0)) 
-			{
-				Scalar s = Scalar_traits::sqrt(trace + Scalar(1.0));
-				q[3] = s * Scalar(0.5);
-				s = Scalar(0.5) / s;
-				
-				q[0] = (m_el[2][1] - m_el[1][2]) * s;
-				q[1] = (m_el[0][2] - m_el[2][0]) * s;
-				q[2] = (m_el[1][0] - m_el[0][1]) * s;
-			} 
-			else 
-			{
-				int i = m_el[0][0] < m_el[1][1] ? 
-					(m_el[1][1] < m_el[2][2] ? 2 : 1) :
-					(m_el[0][0] < m_el[2][2] ? 2 : 0); 
-				int j = (i + 1) % 3;  
-				int k = (i + 2) % 3;
-				
-				Scalar s = Scalar_traits::sqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + Scalar(1.0));
-				q[i] = s * Scalar(0.5);
-				s = Scalar(0.5) / s;
-				
-				q[3] = (m_el[k][j] - m_el[j][k]) * s;
-				q[j] = (m_el[j][i] + m_el[i][j]) * s;
-				q[k] = (m_el[k][i] + m_el[i][k]) * s;
-			}
-		}
-
-
-		
-		template 
-		void getEuler(Scalar2& yaw, Scalar2& pitch, Scalar2& roll) const
-		{
-			pitch = Scalar2(Scalar_traits::asin(-m_el[2][0]));
-			if (pitch < Scalar_traits::TwoTimesPi())
-			{
-				if (pitch > Scalar_traits::TwoTimesPi())
-				{
-					yaw = Scalar2(Scalar_traits::atan2(m_el[1][0], m_el[0][0]));
-					roll = Scalar2(Scalar_traits::atan2(m_el[2][1], m_el[2][2]));
-				}
-				else 
-				{
-					yaw = Scalar2(-Scalar_traits::atan2(-m_el[0][1], m_el[0][2]));
-					roll = Scalar2(0.0);
-				}
-			}
-			else
-			{
-				yaw = Scalar2(Scalar_traits::atan2(-m_el[0][1], m_el[0][2]));
-				roll = Scalar2(0.0);
-			}
-		}
-
-		Vector3 getScaling() const
-		{
-			return Vector3(m_el[0][0] * m_el[0][0] + m_el[1][0] * m_el[1][0] + m_el[2][0] * m_el[2][0],
-								   m_el[0][1] * m_el[0][1] + m_el[1][1] * m_el[1][1] + m_el[2][1] * m_el[2][1],
-								   m_el[0][2] * m_el[0][2] + m_el[1][2] * m_el[1][2] + m_el[2][2] * m_el[2][2]);
-		}
-		
-		
-		Matrix3x3 scaled(const Vector3& s) const
-		{
-			return Matrix3x3(m_el[0][0] * s[0], m_el[0][1] * s[1], m_el[0][2] * s[2],
-									 m_el[1][0] * s[0], m_el[1][1] * s[1], m_el[1][2] * s[2],
-									 m_el[2][0] * s[0], m_el[2][1] * s[1], m_el[2][2] * s[2]);
-		}
-
-		Scalar            determinant() const;
-		Matrix3x3 adjoint() const;
-		Matrix3x3 absolute() const;
-		Matrix3x3 transpose() const;
-		Matrix3x3 inverse() const; 
-		
-		Matrix3x3 transposeTimes(const Matrix3x3& m) const;
-		Matrix3x3 timesTranspose(const Matrix3x3& m) const;
-		
-		Scalar tdot(int c, const Vector3& v) const 
-		{
-			return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2];
-		}
-		
-	protected:
-		Scalar cofac(int r1, int c1, int r2, int c2) const 
-		{
-			return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
-		}
-
-		Vector3 m_el[3];
-	};
-	
-	template 
-	inline std::ostream& 
-	operator<<(std::ostream& os, const Matrix3x3& m)
-	{
-		return os << m[0] << std::endl << m[1] << std::endl << m[2] << std::endl;
-	}
-	
-	template 
-	inline Matrix3x3& 
-	Matrix3x3::operator*=(const Matrix3x3& m)
-	{
-		setValue(m.tdot(0, m_el[0]), m.tdot(1, m_el[0]), m.tdot(2, m_el[0]),
-				 m.tdot(0, m_el[1]), m.tdot(1, m_el[1]), m.tdot(2, m_el[1]),
-				 m.tdot(0, m_el[2]), m.tdot(1, m_el[2]), m.tdot(2, m_el[2]));
-		return *this;
-	}
-	
-	template 
-	inline Scalar 
-	Matrix3x3::determinant() const
-	{ 
-		return triple((*this)[0], (*this)[1], (*this)[2]);
-	}
-	
-
-	template 
-	inline Matrix3x3 
-	Matrix3x3::absolute() const
-	{
-		return Matrix3x3(
-			Scalar_traits::abs(m_el[0][0]), Scalar_traits::abs(m_el[0][1]), Scalar_traits::abs(m_el[0][2]),
-			Scalar_traits::abs(m_el[1][0]), Scalar_traits::abs(m_el[1][1]), Scalar_traits::abs(m_el[1][2]),
-			Scalar_traits::abs(m_el[2][0]), Scalar_traits::abs(m_el[2][1]), Scalar_traits::abs(m_el[2][2]));
-	}
-
-	template 
-	inline Matrix3x3 
-	Matrix3x3::transpose() const 
-	{
-		return Matrix3x3(m_el[0][0], m_el[1][0], m_el[2][0],
-								 m_el[0][1], m_el[1][1], m_el[2][1],
-								 m_el[0][2], m_el[1][2], m_el[2][2]);
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::adjoint() const 
-	{
-		return Matrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
-								 cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
-								 cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::inverse() const
-	{
-		Vector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
-		Scalar det = (*this)[0].dot(co);
-		assert(det != Scalar(0.0));
-		Scalar s = Scalar(1.0) / det;
-		return Matrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
-								 co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
-								 co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::transposeTimes(const Matrix3x3& m) const
-	{
-		return Matrix3x3(
-			m_el[0][0] * m[0][0] + m_el[1][0] * m[1][0] + m_el[2][0] * m[2][0],
-			m_el[0][0] * m[0][1] + m_el[1][0] * m[1][1] + m_el[2][0] * m[2][1],
-			m_el[0][0] * m[0][2] + m_el[1][0] * m[1][2] + m_el[2][0] * m[2][2],
-			m_el[0][1] * m[0][0] + m_el[1][1] * m[1][0] + m_el[2][1] * m[2][0],
-			m_el[0][1] * m[0][1] + m_el[1][1] * m[1][1] + m_el[2][1] * m[2][1],
-			m_el[0][1] * m[0][2] + m_el[1][1] * m[1][2] + m_el[2][1] * m[2][2],
-			m_el[0][2] * m[0][0] + m_el[1][2] * m[1][0] + m_el[2][2] * m[2][0],
-			m_el[0][2] * m[0][1] + m_el[1][2] * m[1][1] + m_el[2][2] * m[2][1],
-			m_el[0][2] * m[0][2] + m_el[1][2] * m[1][2] + m_el[2][2] * m[2][2]);
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::timesTranspose(const Matrix3x3& m) const
-	{
-		return Matrix3x3(
-			m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
-			m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
-			m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
-		
-	}
-
-	template 
-	inline Vector3 
-	operator*(const Matrix3x3& m, const Vector3& v) 
-	{
-		return Vector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
-	}
-	
-
-	template 
-	inline Vector3
-	operator*(const Vector3& v, const Matrix3x3& m)
-	{
-		return Vector3(m.tdot(0, v), m.tdot(1, v), m.tdot(2, v));
-	}
-
-	template 
-	inline Matrix3x3 
-	operator*(const Matrix3x3& m1, const Matrix3x3& m2)
-	{
-		return Matrix3x3(
-			m2.tdot(0, m1[0]), m2.tdot(1, m1[0]), m2.tdot(2, m1[0]),
-			m2.tdot(0, m1[1]), m2.tdot(1, m1[1]), m2.tdot(2, m1[1]),
-			m2.tdot(0, m1[2]), m2.tdot(1, m1[2]), m2.tdot(2, m1[2]));
-	}
-}
-
-#endif
diff --git a/extern/solid/include/MT/Quaternion.h b/extern/solid/include/MT/Quaternion.h
deleted file mode 100644
index a925f21cd5d..00000000000
--- a/extern/solid/include/MT/Quaternion.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef QUATERNION_H
-#define QUATERNION_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include "Tuple4.h"
-#include "Vector3.h"
-
-namespace MT {
-
-	template 	
-	class Quaternion : public Tuple4 {
-	public:
-		Quaternion() {}
-		
-		template 
-		explicit Quaternion(const Scalar2 *v) : Tuple4(v) {}
-		
-		template 
-		Quaternion(const Scalar2& x, const Scalar2& y, const Scalar2& z, const Scalar2& w) 
-			: Tuple4(x, y, z, w) 
-		{}
-		
-		Quaternion(const Vector3& axis, const Scalar& angle) 
-		{ 
-			setRotation(axis, angle); 
-		}
-
-		template 
-		Quaternion(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll)
-		{ 
-			setEuler(yaw, pitch, roll); 
-		}
-
-		void setRotation(const Vector3& axis, const Scalar& angle)
-		{
-			Scalar d = axis.length();
-			assert(d != Scalar(0.0));
-			Scalar s = Scalar_traits::sin(angle * Scalar(0.5)) / d;
-			setValue(axis[0] * s, axis[1] * s, axis[2] * s, 
-					 Scalar_traits::cos(angle * Scalar(0.5)));
-		}
-
-		template 
-		void setEuler(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll)
-		{
-			Scalar halfYaw = Scalar(yaw) * Scalar(0.5);  
-			Scalar halfPitch = Scalar(pitch) * Scalar(0.5);  
-			Scalar halfRoll = Scalar(roll) * Scalar(0.5);  
-			Scalar cosYaw = Scalar_traits::cos(halfYaw);
-			Scalar sinYaw = Scalar_traits::sin(halfYaw);
-			Scalar cosPitch = Scalar_traits::cos(halfPitch);
-			Scalar sinPitch = Scalar_traits::sin(halfPitch);
-			Scalar cosRoll = Scalar_traits::cos(halfRoll);
-			Scalar sinRoll = Scalar_traits::sin(halfRoll);
-			setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
-					 cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
-					 sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
-					 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
-		}
-  
-		Quaternion& operator+=(const Quaternion& q)
-		{
-			this->m_co[0] += q[0]; this->m_co[1] += q[1]; this->m_co[2] += q[2]; this->m_co[3] += q[3];
-			return *this;
-		}
-		
-		Quaternion& operator-=(const Quaternion& q) 
-		{
-			this->m_co[0] -= q[0]; this->m_co[1] -= q[1]; this->m_co[2] -= q[2]; this->m_co[3] -= q[3];
-			return *this;
-		}
-
-		Quaternion& operator*=(const Scalar& s)
-		{
-			this->m_co[0] *= s; this->m_co[1] *= s; this->m_co[2] *= s; this->m_co[3] *= s;
-			return *this;
-		}
-		
-		Quaternion& operator/=(const Scalar& s) 
-		{
-			assert(s != Scalar(0.0));
-			return *this *= Scalar(1.0) / s;
-		}
-  
-		Quaternion& operator*=(const Quaternion& q)
-		{
-			setValue(this->m_co[3] * q[0] + this->m_co[0] * q[3] + this->m_co[1] * q[2] - this->m_co[2] * q[1],
-					 this->m_co[3] * q[1] + this->m_co[1] * q[3] + this->m_co[2] * q[0] - this->m_co[0] * q[2],
-					 this->m_co[3] * q[2] + this->m_co[2] * q[3] + this->m_co[0] * q[1] - this->m_co[1] * q[0],
-					 this->m_co[3] * q[3] - this->m_co[0] * q[0] - this->m_co[1] * q[1] - this->m_co[2] * q[2]);
-			return *this;
-		}
-	
-		Scalar dot(const Quaternion& q) const
-		{
-			return this->m_co[0] * q[0] + this->m_co[1] * q[1] + this->m_co[2] * q[2] + this->m_co[3] * q[3];
-		}
-
-		Scalar length2() const
-		{
-			return dot(*this);
-		}
-
-		Scalar length() const
-		{
-			return Scalar_traits::sqrt(length2());
-		}
-
-		Quaternion& normalize() 
-		{
-			return *this /= length();
-		}
-		
-		Quaternion normalized() const 
-		{
-			return *this / length();
-		} 
-
-		Scalar angle(const Quaternion& q) const 
-		{
-			Scalar s = Scalar_traits::sqrt(length2() * q.length2());
-			assert(s != Scalar(0.0));
-			return Scalar_traits::acos(dot(q) / s);
-		}
-   
-		Quaternion conjugate() const 
-		{
-			return Quaternion(-this->m_co[0], -this->m_co[1], -this->m_co[2], this->m_co[3]);
-		}
-
-		Quaternion inverse() const
-		{
-			return conjugate / length2();
-		}
-		
-		Quaternion slerp(const Quaternion& q, const Scalar& t) const
-		{
-			Scalar theta = angle(q);
-			if (theta != Scalar(0.0))
-			{
-				Scalar d = Scalar(1.0) / Scalar_traits::sin(theta);
-				Scalar s0 = Scalar_traits::sin((Scalar(1.0) - t) * theta);
-				Scalar s1 = Scalar_traits::sin(t * theta);   
-				return Quaternion((this->m_co[0] * s0 + q[0] * s1) * d,
-										  (this->m_co[1] * s0 + q[1] * s1) * d,
-										  (this->m_co[2] * s0 + q[2] * s1) * d,
-										  (this->m_co[3] * s0 + q[3] * s1) * d);
-			}
-			else
-			{
-				return *this;
-			}
-		}
-
-		static Quaternion random() 
-		{
-			// From: "Uniform Random Rotations", Ken Shoemake, Graphics Gems III, 
-            //       pg. 124-132
-			Scalar x0 = Scalar_traits::random();
-			Scalar r1 = Scalar_traits::sqrt(Scalar(1.0) - x0);
-			Scalar r2 = Scalar_traits::sqrt(x0);
-			Scalar t1 = Scalar_traits::TwoTimesPi() * Scalar_traits::random();
-			Scalar t2 = Scalar_traits::TwoTimesPi() * Scalar_traits::random();
-			Scalar c1 = Scalar_traits::cos(t1);
-			Scalar s1 = Scalar_traits::sin(t1);
-			Scalar c2 = Scalar_traits::cos(t2);
-			Scalar s2 = Scalar_traits::sin(t2);
-			return Quaternion(s1 * r1, c1 * r1, s2 * r2, c2 * r2);
-		}
-
-	};
-
-	template 
-	inline Quaternion
-	operator+(const Quaternion& q1, const Quaternion& q2)
-	{
-		return Quaternion(q1[0] + q2[0], q1[1] + q2[1], q1[2] + q2[2], q1[3] + q2[3]);
-	}
-	
-	template 
-	inline Quaternion
-	operator-(const Quaternion& q1, const Quaternion& q2)
-	{
-		return Quaternion(q1[0] - q2[0], q1[1] - q2[1], q1[2] - q2[2], q1[3] - q2[3]);
-	}
-	
-	template 
-	inline Quaternion
-	operator-(const Quaternion& q)
-	{
-		return Quaternion(-q[0], -q[1], -q[2], -q[3]);
-	}
-
-	template 
-	inline Quaternion
-	operator*(const Quaternion& q, const Scalar& s)
-	{
-		return Quaternion(q[0] * s, q[1] * s, q[2] * s, q[3] * s);
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Scalar& s, const Quaternion& q)
-	{
-		return q * s;
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Quaternion& q1, const Quaternion& q2) {
-		return Quaternion(q1[3] * q2[0] + q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1],
-								  q1[3] * q2[1] + q1[1] * q2[3] + q1[2] * q2[0] - q1[0] * q2[2],
-								  q1[3] * q2[2] + q1[2] * q2[3] + q1[0] * q2[1] - q1[1] * q2[0],
-								  q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2]); 
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Quaternion& q, const Vector3& w)
-	{
-		return Quaternion( q[3] * w[0] + q[1] * w[2] - q[2] * w[1],
-								   q[3] * w[1] + q[2] * w[0] - q[0] * w[2],
-								   q[3] * w[2] + q[0] * w[1] - q[1] * w[0],
-								  -q[0] * w[0] - q[1] * w[1] - q[2] * w[2]); 
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Vector3& w, const Quaternion& q)
-	{
-		return Quaternion( w[0] * q[3] + w[1] * q[2] - w[2] * q[1],
-								   w[1] * q[3] + w[2] * q[0] - w[0] * q[2],
-								   w[2] * q[3] + w[0] * q[1] - w[1] * q[0],
-								  -w[0] * q[0] - w[1] * q[1] - w[2] * q[2]); 
-	}
-	
-	template 
-	inline Scalar 
-	dot(const Quaternion& q1, const Quaternion& q2) 
-	{ 
-		return q1.dot(q2); 
-	}
-
-	template 
-	inline Scalar
-	length2(const Quaternion& q) 
-	{ 
-		return q.length2(); 
-	}
-
-	template 
-	inline Scalar
-	length(const Quaternion& q) 
-	{ 
-		return q.length(); 
-	}
-
-	template 
-	inline Scalar
-	angle(const Quaternion& q1, const Quaternion& q2) 
-	{ 
-		return q1.angle(q2); 
-	}
-
-	template 
-	inline Quaternion
-	conjugate(const Quaternion& q) 
-	{
-		return q.conjugate();
-	}
-
-	template 
-	inline Quaternion
-	inverse(const Quaternion& q) 
-	{
-		return q.inverse();
-	}
-
-	template 
-	inline Quaternion
-	slerp(const Quaternion& q1, const Quaternion& q2, const Scalar& t) 
-	{
-		return q1.slerp(q2, t);
-	}
-	
-}
-
-#endif
diff --git a/extern/solid/include/MT/Transform.h b/extern/solid/include/MT/Transform.h
deleted file mode 100644
index b80dc1bc18b..00000000000
--- a/extern/solid/include/MT/Transform.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef TRANSFORM_H
-#define TRANSFORM_H
-
-#include "Vector3.h"
-#include "Matrix3x3.h"
-
-namespace MT {
-
-	template 
-	class Transform {
-		enum { 
-			TRANSLATION = 0x01,
-			ROTATION    = 0x02,
-			RIGID       = TRANSLATION | ROTATION,  
-			SCALING     = 0x04,
-			LINEAR      = ROTATION | SCALING,
-			AFFINE      = TRANSLATION | LINEAR
-		};
-    
-	public:
-		Transform() {}
-		
-		template 
-		explicit Transform(const Scalar2 *m) { setValue(m); }
-
-		explicit Transform(const Quaternion& q, 
-						   const Vector3& c = Vector3(Scalar(0), Scalar(0), Scalar(0))) 
-			: m_basis(q),
-			  m_origin(c),
-			  m_type(RIGID)
-		{}
-
-		explicit Transform(const Matrix3x3& b, 
-						   const Vector3& c = Vector3(Scalar(0), Scalar(0), Scalar(0)), 
-						   unsigned int type = AFFINE)
-			: m_basis(b),
-			  m_origin(c),
-			  m_type(type)
-		{}
-
-		Vector3 operator()(const Vector3& x) const
-		{
-			return Vector3(m_basis[0].dot(x) + m_origin[0], 
-								   m_basis[1].dot(x) + m_origin[1], 
-								   m_basis[2].dot(x) + m_origin[2]);
-		}
-    
-		Vector3 operator*(const Vector3& x) const
-		{
-			return (*this)(x);
-		}
-
-		Matrix3x3&       getBasis()          { return m_basis; }
-		const Matrix3x3& getBasis()    const { return m_basis; }
-
-		Vector3&         getOrigin()         { return m_origin; }
-		const Vector3&   getOrigin()   const { return m_origin; }
-
-		Quaternion getRotation() const { return m_basis.getRotation(); }
-		template 
-		void setValue(const Scalar2 *m) 
-		{
-			m_basis.setValue(m);
-			m_origin.setValue(&m[12]);
-			m_type = AFFINE;
-		}
-
-		template 
-		void getValue(Scalar2 *m) const 
-		{
-			m_basis.getValue(m);
-			m_origin.getValue(&m[12]);
-			m[15] = Scalar2(1.0);
-		}
-
-		void setOrigin(const Vector3& origin) 
-		{ 
-			m_origin = origin;
-			m_type |= TRANSLATION;
-		}
-
-		void setBasis(const Matrix3x3& basis)
-		{ 
-			m_basis = basis;
-			m_type |= LINEAR;
-		}
-
-		void setRotation(const Quaternion& q)
-		{
-			m_basis.setRotation(q);
-			m_type = (m_type & ~LINEAR) | ROTATION;
-		}
-
-    	void scale(const Vector3& scaling)
-		{
-			m_basis = m_basis.scaled(scaling);
-			m_type |= SCALING;
-		}
-    
-		void setIdentity()
-		{
-			m_basis.setIdentity();
-			m_origin.setValue(Scalar(0.0), Scalar(0.0), Scalar(0.0));
-			m_type = 0x0;
-		}
-		
-		bool isIdentity() const { return m_type == 0x0; }
-    
-		Transform& operator*=(const Transform& t) 
-		{
-			m_origin += m_basis * t.m_origin;
-			m_basis *= t.m_basis;
-			m_type |= t.m_type; 
-			return *this;
-		}
-
-		Transform inverse() const
-		{ 
-			Matrix3x3 inv = (m_type & SCALING) ? 
-				                    m_basis.inverse() : 
-				                    m_basis.transpose();
-			
-			return Transform(inv, inv * -m_origin, m_type);
-		}
-
-		Transform inverseTimes(const Transform& t) const;  
-
-		Transform operator*(const Transform& t) const;
-
-	private:
-		
-		Matrix3x3 m_basis;
-		Vector3   m_origin;
-		unsigned int      m_type;
-	};
-
-
-	template 
-	inline Transform 
-	Transform::inverseTimes(const Transform& t) const  
-	{
-		Vector3 v = t.getOrigin() - m_origin;
-		if (m_type & SCALING) 
-		{
-			Matrix3x3 inv = m_basis.inverse();
-			return Transform(inv * t.getBasis(), inv * v, 
-									 m_type | t.m_type);
-		}
-		else 
-		{
-			return Transform(m_basis.transposeTimes(t.m_basis),
-									 v * m_basis, m_type | t.m_type);
-		}
-	}
-
-	template 
-	inline Transform 
-	Transform::operator*(const Transform& t) const
-	{
-		return Transform(m_basis * t.m_basis, 
-								 (*this)(t.m_origin), 
-								 m_type | t.m_type);
-	}	
-}
-
-#endif
diff --git a/extern/solid/include/MT/Tuple3.h b/extern/solid/include/MT/Tuple3.h
deleted file mode 100644
index 52ea33b7f58..00000000000
--- a/extern/solid/include/MT/Tuple3.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef TUPLE3_H
-#define TUPLE3_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include 
-
-namespace MT {
-
-	template 
-	class Tuple3 {
-	public:
-		Tuple3() {}
-		
-		template 
-		explicit Tuple3(const Scalar2 *v) 
-		{ 
-			setValue(v);
-		}
-		
-		template 
-		Tuple3(const Scalar2& x, const Scalar2& y, const Scalar2& z) 
-		{ 
-			setValue(x, y, z); 
-		}
-		
-		template 
-		Tuple3(const Tuple3& t) 
-		{ 
-			*this = t; 
-		}
-		
-		template 
-		Tuple3& operator=(const Tuple3& t) 
-		{ 
-			m_co[0] = Scalar(t[0]); 
-			m_co[1] = Scalar(t[1]); 
-			m_co[2] = Scalar(t[2]);
-			return *this;
-		}
-		
-		operator       Scalar *()       { return m_co; }
-		operator const Scalar *() const { return m_co; }
-
-		Scalar&       operator[](int i)       { return m_co[i];	}      
-		const Scalar& operator[](int i) const { return m_co[i]; }
-
-		Scalar&       x()       { return m_co[0]; }
-		const Scalar& x() const { return m_co[0]; }
-		
-		Scalar&       y()       { return m_co[1]; }
-		const Scalar& y() const { return m_co[1]; }
-		
-		Scalar&       z()       { return m_co[2]; }
-		const Scalar& z() const { return m_co[2]; }
-
-		template 
-		void setValue(const Scalar2 *v) 
-		{
-			m_co[0] = Scalar(v[0]); 
-			m_co[1] = Scalar(v[1]); 
-			m_co[2] = Scalar(v[2]);
-		}
-
-		template 
-		void setValue(const Scalar2& x, const Scalar2& y, const Scalar2& z)
-		{
-			m_co[0] = Scalar(x); 
-			m_co[1] = Scalar(y); 
-			m_co[2] = Scalar(z);
-		}
-
-		template 
-		void getValue(Scalar2 *v) const 
-		{
-			v[0] = Scalar2(m_co[0]);
-			v[1] = Scalar2(m_co[1]);
-			v[2] = Scalar2(m_co[2]);
-		}
-    
-	protected:
-		Scalar m_co[3];                            
-	};
-
-	template 
-	inline std::ostream& 
-	operator<<(std::ostream& os, const Tuple3& t)
-	{
-		return os << t[0] << ' ' << t[1] << ' ' << t[2];
-	}
-}
-
-#endif
diff --git a/extern/solid/include/MT/Tuple4.h b/extern/solid/include/MT/Tuple4.h
deleted file mode 100644
index 6930541271e..00000000000
--- a/extern/solid/include/MT/Tuple4.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef TUPLE4_H
-#define TUPLE4_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include 
-
-namespace MT {
-
-	template 
-	class Tuple4 {
-	public:
-		Tuple4() {}
-		
-		template 
-		explicit Tuple4(const Scalar2 *v) 
-		{ 
-			setValue(v);
-		}
-		
-		template 
-		Tuple4(const Scalar2& x, const Scalar2& y, const Scalar2& z, const Scalar2& w) 
-		{ 
-			setValue(x, y, z, w); 
-		}
-		
-		operator       Scalar *()       { return m_co; }
-		operator const Scalar *() const { return m_co; }
-
-		Scalar&       operator[](int i)       { return m_co[i]; }      
-		const Scalar& operator[](int i) const {	return m_co[i];	}
-		
-		Scalar&       x()       { return m_co[0]; }
-		const Scalar& x() const { return m_co[0]; }
-		
-		Scalar&       y()       { return m_co[1]; }
-		const Scalar& y() const { return m_co[1]; }
-		
-		Scalar&       z()       { return m_co[2]; }
-		const Scalar& z() const { return m_co[2]; }
-
-		Scalar&       w()       { return m_co[3]; }
-		const Scalar& w() const { return m_co[3]; }
-    
-		template 
-		void setValue(const Scalar2 *v) 
-		{
-			m_co[0] = Scalar(v[0]); 
-			m_co[1] = Scalar(v[1]); 
-			m_co[2] = Scalar(v[2]);
-			m_co[3] = Scalar(v[3]);
-		}
-
-		template 
-		void setValue(const Scalar2& x, const Scalar2& y, const Scalar2& z, const Scalar2& w)
-		{
-			m_co[0] = Scalar(x); 
-			m_co[1] = Scalar(y); 
-			m_co[2] = Scalar(z);
-			m_co[3] = Scalar(w);
-		}
-
-		template 
-		void getValue(Scalar2 *v) const 
-		{
-			v[0] = Scalar2(m_co[0]);
-			v[1] = Scalar2(m_co[1]);
-			v[2] = Scalar2(m_co[2]);
-			v[3] = Scalar2(m_co[3]);
-		}
-
-	protected:
-		Scalar m_co[4];
-	};
-
-	template 
-	inline std::ostream&
-	operator<<(std::ostream& os, const Tuple4& t)
-	{
-		return os << t[0] << ' ' << t[1] << ' ' << t[2] << ' ' << t[3];
-	}
-
-}
-
-#endif
diff --git a/extern/solid/include/MT/Vector3.h b/extern/solid/include/MT/Vector3.h
deleted file mode 100644
index b569c003f59..00000000000
--- a/extern/solid/include/MT/Vector3.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef VECTOR3_H
-#define VECTOR3_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include "Tuple3.h"
-
-namespace MT {
-
-	template 	
-	class Vector3 : public Tuple3 {
-	public:
-		Vector3() {}
-	
-		template 
-		explicit Vector3(const Scalar2 *v) : Tuple3(v) {}
-		
-		template 
-		Vector3(const Scalar2& x, const Scalar2& y, const Scalar2& z) 
-			: Tuple3(x, y, z) 
-		{}
-		
-		Vector3& operator+=(const Vector3& v)
-		{
-			this->m_co[0] += v[0]; this->m_co[1] += v[1]; this->m_co[2] += v[2];
-			return *this;
-		}
-		
-		Vector3& operator-=(const Vector3& v) 
-		{
-			this->m_co[0] -= v[0]; this->m_co[1] -= v[1]; this->m_co[2] -= v[2];
-			return *this;
-		}
-
-		Vector3& operator*=(const Scalar& s)
-		{
-			this->m_co[0] *= s; this->m_co[1] *= s; this->m_co[2] *= s;
-			return *this;
-		}
-		
-		Vector3& operator/=(const Scalar& s) 
-		{
-			assert(s != Scalar(0.0));
-			return *this *= Scalar(1.0) / s;
-		}
-  
-		Scalar dot(const Vector3& v) const
-		{
-			return this->m_co[0] * v[0] + this->m_co[1] * v[1] + this->m_co[2] * v[2];
-		}
-
-		Scalar length2() const
-		{
-			return dot(*this);
-		}
-
-		Scalar length() const
-		{
-			return Scalar_traits::sqrt(length2());
-		}
-
-		Scalar distance2(const Vector3& v) const 
-		{
-			return (v - *this).length2();
-		}
-
-		Scalar distance(const Vector3& v) const 
-		{
-			return (v - *this).length();
-		}
-		
-		Vector3& normalize() 
-		{
-			return *this /= length();
-		}
-		
-		Vector3 normalized() const 
-		{
-			return *this / length();
-		} 
-
-		Scalar angle(const Vector3& v) const 
-		{
-			Scalar s = Scalar_traits::sqrt(length2() * v.length2());
-			assert(s != Scalar(0.0));
-			return Scalar_traits::acos(dot(v) / s);
-		}
-   
-		Vector3 absolute() const 
-		{
-			return Vector3(Scalar_traits::abs(this->m_co[0]), 
-								   Scalar_traits::abs(this->m_co[1]), 
-								   Scalar_traits::abs(this->m_co[2]));
-		}
-
-		Vector3 cross(const Vector3& v) const
-		{
-			return Vector3(this->m_co[1] * v[2] - this->m_co[2] * v[1],
-								   this->m_co[2] * v[0] - this->m_co[0] * v[2],
-								   this->m_co[0] * v[1] - this->m_co[1] * v[0]);
-		}
-		
-		Scalar triple(const Vector3& v1, const Vector3& v2) const
-		{
-			return this->m_co[0] * (v1[1] * v2[2] - v1[2] * v2[1]) + 
-				   this->m_co[1] * (v1[2] * v2[0] - v1[0] * v2[2]) + 
-				   this->m_co[2] * (v1[0] * v2[1] - v1[1] * v2[0]);
-		}
-
-		int minAxis() const
-		{
-			return this->m_co[0] < this->m_co[1] ? (this->m_co[0] < this->m_co[2] ? 0 : 2) : (this->m_co[1] < this->m_co[2] ? 1 : 2);
-		}
-
-		int maxAxis() const 
-		{
-			return this->m_co[0] < this->m_co[1] ? (this->m_co[1] < this->m_co[2] ? 2 : 1) : (this->m_co[0] < this->m_co[2] ? 2 : 0);
-		}
-
-		int furthestAxis() const
-		{
-			return absolute().minAxis();
-		}
-
-		int closestAxis() const 
-		{
-			return absolute().maxAxis();
-		}
-
-		Vector3 lerp(const Vector3& v, const Scalar& t) const 
-		{
-			return Vector3(this->m_co[0] + (v[0] - this->m_co[0]) * t,
-								   this->m_co[1] + (v[1] - this->m_co[1]) * t,
-								   this->m_co[2] + (v[2] - this->m_co[2]) * t);
-		}
-    
-		static Vector3 random() 
-		{
-			Scalar z = Scalar(2.0) * Scalar_traits::random() - Scalar(1.0);
-			Scalar r = Scalar_traits::sqrt(Scalar(1.0) - z * z);
-			Scalar t = Scalar_traits::TwoTimesPi() * Scalar_traits::random();
-			return Vector3(r * Scalar_traits::cos(t), 
-								   r * Scalar_traits::sin(t), 
-								   z);
-		}
-	};
-
-	template 
-	inline Vector3 
-	operator+(const Vector3& v1, const Vector3& v2) 
-	{
-		return Vector3(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
-	}
-
-	template 
-	inline Vector3 
-	operator-(const Vector3& v1, const Vector3& v2)
-	{
-		return Vector3(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
-	}
-	
-	template 
-	inline Vector3 
-	operator-(const Vector3& v)
-	{
-		return Vector3(-v[0], -v[1], -v[2]);
-	}
-	
-	template 
-	inline Vector3 
-	operator*(const Vector3& v, const Scalar& s)
-	{
-		return Vector3(v[0] * s, v[1] * s, v[2] * s);
-	}
-	
-	template 
-	inline Vector3 
-	operator*(const Scalar& s, const Vector3& v)
-	{ 
-		return v * s; 
-	}
-	
-	template 
-	inline Vector3
-	operator/(const Vector3& v, const Scalar& s)
-	{
-		assert(s != Scalar(0.0));
-		return v * (Scalar(1.0) / s);
-	}
-	
-	template 
-	inline Scalar 
-	dot(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.dot(v2); 
-	}
-	
-	template 
-	inline Scalar
-	length2(const Vector3& v) 
-	{ 
-		return v.length2(); 
-	}
-
-	template 
-	inline Scalar
-	length(const Vector3& v) 
-	{ 
-		return v.length(); 
-	}
-
-	template 
-	inline Scalar
-	distance2(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.distance2(v2); 
-	}
-
-	template 
-	inline Scalar
-	distance(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.distance(v2); 
-	}
-
-	template 
-	inline Scalar
-	angle(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.angle(v2); 
-	}
-
-	template 
-	inline Vector3 
-	cross(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.cross(v2); 
-	}
-
-	template 
-	inline Scalar
-	triple(const Vector3& v1, const Vector3& v2, const Vector3& v3)
-	{
-		return v1.triple(v2, v3);
-	}
-
-	template 
-	inline Vector3 
-	lerp(const Vector3& v1, const Vector3& v2, const Scalar& t)
-	{
-		return v1.lerp(v2, t);
-	}
-
-}
-
-#endif
diff --git a/extern/solid/include/MT_BBox.h b/extern/solid/include/MT_BBox.h
deleted file mode 100644
index b5dc537e0d9..00000000000
--- a/extern/solid/include/MT_BBox.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_BBOX_H
-#define MT_BBOX_H
-
-#include "MT_Scalar.h"
-#include "MT_Point3.h"
-#include "MT_Vector3.h"
-
-#include  
-#include "MT_Interval.h" 
-
-
-
-class MT_BBox : public MT::Tuple3 {
-public:
-    MT_BBox() {}
-	MT_BBox(const MT_Point3& p)
-		: MT::Tuple3(MT_Interval(p[0]), 
-				                  MT_Interval(p[1]), 
-				                  MT_Interval(p[2]))
-	{}
-	MT_BBox(const MT_Point3& lb, const MT_Point3& ub)
-		: MT::Tuple3(MT_Interval(lb[0], ub[0]),
-				                  MT_Interval(lb[1], ub[1]),
-				                  MT_Interval(lb[2], ub[2]))
-	{}
-	MT_BBox(const MT_Interval& x, const MT_Interval& y, const MT_Interval& z) 
-		: MT::Tuple3(x, y, z) 
-	{}
-
-	MT_Point3 getMin() const 
-	{ 
-		return MT_Point3(m_co[0].lower(), m_co[1].lower(), m_co[2].lower());
-	}
-
-	MT_Point3 getMax() const 
-	{ 
-		return MT_Point3(m_co[0].upper(), m_co[1].upper(), m_co[2].upper());
-	}
-	
-	MT_Point3 getCenter() const
-	{
-		return MT_Point3(MT::median(m_co[0]), MT::median(m_co[1]), MT::median(m_co[2]));
-	}
-
-	MT_Vector3 getExtent() const
-	{
-		return MT_Vector3(MT::width(m_co[0]) * MT_Scalar(0.5), MT::width(m_co[1]) * MT_Scalar(0.5), MT::width(m_co[2]) * MT_Scalar(0.5));
-	}
-
-	void extend(const MT_Vector3& v) 
-	{
-		m_co[0] = MT::widen(m_co[0], v[0]);
-		m_co[1] = MT::widen(m_co[1], v[1]);
-		m_co[2] = MT::widen(m_co[2], v[2]);
-	}
-
-    bool overlaps(const MT_BBox& b) const 
-	{
-        return MT::overlap(m_co[0], b[0]) &&
-			   MT::overlap(m_co[1], b[1]) &&
-			   MT::overlap(m_co[2], b[2]);
-    }
-
-	bool inside(const MT_BBox& b) const 
-	{
-        return MT::in(m_co[0], b[0]) &&
-			   MT::in(m_co[1], b[1]) &&
-			   MT::in(m_co[2], b[2]);
-    }
-
-	MT_BBox hull(const MT_BBox& b) const 
-	{
-		return MT_BBox(MT::hull(m_co[0], b[0]), 
-					   MT::hull(m_co[1], b[1]), 
-					   MT::hull(m_co[2], b[2])); 
-	}
-
-	bool contains(const MT_Point3& p) const 
-	{
-		return MT::in(p[0], m_co[0]) && MT::in(p[1], m_co[1]) && MT::in(p[2], m_co[2]);
-	}
-};
-
-inline MT_BBox operator+(const MT_BBox& b1, const MT_BBox& b2) 
-{
-	return MT_BBox(b1[0] + b2[0], b1[1] + b2[1], b1[2] + b2[2]);
-}
-
-inline MT_BBox operator-(const MT_BBox& b1, const MT_BBox& b2) 
-{
-	return MT_BBox(b1[0] - b2[0], b1[1] - b2[1], b1[2] - b2[2]);
-}
-
-#endif
-
-
diff --git a/extern/solid/include/MT_Interval.h b/extern/solid/include/MT_Interval.h
deleted file mode 100644
index 25ebfd0a67d..00000000000
--- a/extern/solid/include/MT_Interval.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_INTERVAL_H
-#define MT_INTERVAL_H
-
-#include 
-
-#include "MT_Scalar.h"
-
-typedef MT::Interval MT_Interval;
-
-#endif
diff --git a/extern/solid/include/MT_Matrix3x3.h b/extern/solid/include/MT_Matrix3x3.h
deleted file mode 100644
index f7572f90fa2..00000000000
--- a/extern/solid/include/MT_Matrix3x3.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_MATRIX3X3_H
-#define MT_MATRIX3X3_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Matrix3x3 MT_Matrix3x3;
-
-
-
-#endif
diff --git a/extern/solid/include/MT_Point3.h b/extern/solid/include/MT_Point3.h
deleted file mode 100644
index ca84f652b65..00000000000
--- a/extern/solid/include/MT_Point3.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_POINT3_H
-#define MT_POINT3_H
-
-#include "MT_Vector3.h"
-
-typedef MT_Vector3 MT_Point3;
-
-#endif
diff --git a/extern/solid/include/MT_Quaternion.h b/extern/solid/include/MT_Quaternion.h
deleted file mode 100644
index ca860db711c..00000000000
--- a/extern/solid/include/MT_Quaternion.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_QUATERNION_H
-#define MT_QUATERNION_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Quaternion MT_Quaternion;
-
-#endif
-
-
-
diff --git a/extern/solid/include/MT_Scalar.h b/extern/solid/include/MT_Scalar.h
deleted file mode 100644
index 663a1f1839c..00000000000
--- a/extern/solid/include/MT_Scalar.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_SCALAR_H
-#define MT_SCALAR_H
-
-#if defined (__sun__) || defined ( __sun ) || defined (__sparc) || defined (__sparc__) || defined (__sgi)
-#include 
-#include 
-#else
-#include 
-#include 
-#include 
-#endif
-
-#undef max
-
-#include "SOLID_types.h"
-
-#include "GEN_MinMax.h"
-#include "GEN_random.h"
-
-template 
-struct Scalar_traits {};
-
-template<>
-struct Scalar_traits {
-	static float TwoTimesPi() { return 6.283185307179586232f; }
-	static float epsilon() { return FLT_EPSILON; }
-	static float max() { return FLT_MAX; }
-	
-	static float random() { return float(GEN_rand()) / float(GEN_RAND_MAX); }
-#if defined (__sun) || defined (__sun__) || defined (__sparc) || defined (__APPLE__)
-	static float sqrt(float x) { return ::sqrt(x); } 
-	static float abs(float x) { return ::fabs(x); } 
-
-	static float cos(float x) { return ::cos(x); } 
-	static float sin(float x) { return ::sin(x); } 
-	static float tan(float x) { return ::tan(x); } 
-
-	static float acos(float x) { return ::acos(x); } 
-	static float asin(float x) { return ::asin(x); } 
-	static float atan(float x) { return ::atan(x); } 
-	static float atan2(float x, float y) { return ::atan2(x, y); } 
-
-	static float exp(float x) { return ::exp(x); } 
-	static float log(float x) { return ::log(x); } 
-	static float pow(float x, float y) { return ::pow(x, y); } 
-
-#else
-	static float sqrt(float x) { return ::sqrtf(x); } 
-	static float abs(float x) { return ::fabsf(x); } 
-
-	static float cos(float x) { return ::cosf(x); } 
-	static float sin(float x) { return ::sinf(x); } 
-	static float tan(float x) { return ::tanf(x); } 
-
-	static float acos(float x) { return ::acosf(x); } 
-	static float asin(float x) { return ::asinf(x); } 
-	static float atan(float x) { return ::atanf(x); } 
-	static float atan2(float x, float y) { return ::atan2f(x, y); } 
-
-	static float exp(float x) { return ::expf(x); } 
-	static float log(float x) { return ::logf(x); } 
-	static float pow(float x, float y) { return ::powf(x, y); } 
-#endif
-};
-
-template<>
-struct Scalar_traits {
-	static double TwoTimesPi() { return 6.283185307179586232; }
-	static double epsilon() { return DBL_EPSILON; }
-	static double max() { return DBL_MAX; }
-	
-	static double random() { return double(GEN_rand()) / double(GEN_RAND_MAX); }
-	static double sqrt(double x) { return ::sqrt(x); } 
-	static double abs(double x) { return ::fabs(x); } 
-
-	static double cos(double x) { return ::cos(x); } 
-	static double sin(double x) { return ::sin(x); } 
-	static double tan(double x) { return ::tan(x); } 
-
-	static double acos(double x) { return ::acos(x); } 
-	static double asin(double x) { return ::asin(x); } 
-	static double atan(double x) { return ::atan(x); } 
-	static double atan2(double x, double y) { return ::atan2(x, y); } 
-
-	static double exp(double x) { return ::exp(x); } 
-	static double log(double x) { return ::log(x); } 
-	static double pow(double x, double y) { return ::pow(x, y); } 
-};
-
-#ifdef USE_TRACER
-#include "MT_ScalarTracer.h"
-
-#ifdef USE_DOUBLES
-typedef MT_ScalarTracer   MT_Scalar;
-#else
-typedef MT_ScalarTracer    MT_Scalar;
-#endif
-
-#else
-
-#ifdef USE_DOUBLES
-typedef double   MT_Scalar;
-#else
-typedef float    MT_Scalar;
-#endif
-
-#endif
-
-
-const MT_Scalar  MT_2_PI         = Scalar_traits::TwoTimesPi();
-const MT_Scalar  MT_PI           = MT_2_PI * MT_Scalar(0.5);
-const MT_Scalar  MT_HALF_PI		 = MT_2_PI * MT_Scalar(0.25);
-const MT_Scalar  MT_RADS_PER_DEG = MT_2_PI / MT_Scalar(360.0);
-const MT_Scalar  MT_DEGS_PER_RAD = MT_Scalar(360.0) / MT_2_PI;
-
-const MT_Scalar  MT_EPSILON      = Scalar_traits::epsilon();
-const MT_Scalar  MT_INFINITY     = Scalar_traits::max();
-
-inline MT_Scalar MT_random() { return  Scalar_traits::random(); }
-inline MT_Scalar MT_abs(MT_Scalar x) { return Scalar_traits::abs(x); }
-inline MT_Scalar MT_sqrt(MT_Scalar x) { return Scalar_traits::sqrt(x); }
-
-inline MT_Scalar MT_cos(MT_Scalar x) { return Scalar_traits::cos(x); }
-inline MT_Scalar MT_sin(MT_Scalar x) { return Scalar_traits::sin(x); }
-inline MT_Scalar MT_tan(MT_Scalar x) { return Scalar_traits::tan(x); }
-
-inline MT_Scalar MT_acos(MT_Scalar x) { return Scalar_traits::acos(x); }
-inline MT_Scalar MT_asin(MT_Scalar x) { return Scalar_traits::asin(x); }
-inline MT_Scalar MT_atan(MT_Scalar x) { return Scalar_traits::atan(x); }
-inline MT_Scalar MT_atan2(MT_Scalar x, MT_Scalar y) { return Scalar_traits::atan2(x, y); }
-
-inline MT_Scalar MT_radians(MT_Scalar x) { return x * MT_RADS_PER_DEG; }
-inline MT_Scalar MT_degrees(MT_Scalar x) { return x * MT_DEGS_PER_RAD; }
-
-#endif
diff --git a/extern/solid/include/MT_Transform.h b/extern/solid/include/MT_Transform.h
deleted file mode 100644
index 66f92428054..00000000000
--- a/extern/solid/include/MT_Transform.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_TRANSFORM_H
-#define MT_TRANSFORM_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Matrix3x3 MT_Matrix3x3;
-typedef MT::Transform MT_Transform;
-
-#endif
-
-
-
-
-
diff --git a/extern/solid/include/MT_Vector3.h b/extern/solid/include/MT_Vector3.h
deleted file mode 100644
index d50e80dc287..00000000000
--- a/extern/solid/include/MT_Vector3.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_VECTOR3_H
-#define MT_VECTOR3_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Vector3 MT_Vector3;
-
-#ifdef CPU_CMP
-
-inline bool operator==(const MT_Vector3& p1, const MT_Vector3& p2) 
-{
-	const unsigned int *i1 = (const unsigned int *)&p1;
-	const unsigned int *i2 = (const unsigned int *)&p2;
-    return i1[0] == i2[0] && i1[1] == i2[1] && i1[2] == i2[2];
-}
-
-#else
-
-inline bool operator==(const MT_Vector3& p1, const MT_Vector3& p2) 
-{
-	return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2];
-}
-
-#endif
-
-#endif
diff --git a/extern/solid/include/SOLID.h b/extern/solid/include/SOLID.h
deleted file mode 100644
index 96d40f1ea6b..00000000000
--- a/extern/solid/include/SOLID.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_H
-#define SOLID_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" { 
-#endif
-    
-	DT_DECLARE_HANDLE(DT_ObjectHandle);
-	DT_DECLARE_HANDLE(DT_SceneHandle);
-	DT_DECLARE_HANDLE(DT_ShapeHandle);
-	DT_DECLARE_HANDLE(DT_VertexBaseHandle);
-	DT_DECLARE_HANDLE(DT_RespTableHandle);
-	DT_DECLARE_HANDLE(DT_ArchiveHandle);
-
-	typedef unsigned int DT_ResponseClass;
-
-	typedef enum DT_ResponseType { 
-		DT_NO_RESPONSE,                  /* No response (obsolete) */
-		DT_BROAD_RESPONSE,               /* Broad phase response is returned. */
-		DT_SIMPLE_RESPONSE,              /* No collision data */
-		DT_WITNESSED_RESPONSE,           /* A point common to both objects
-											is returned as collision data
-										 */
-		DT_DEPTH_RESPONSE                /* The penetration depth is returned
-											as collision data. The penetration depth
-											is the shortest vector over which one 
-											object needs to be translated in order
-											to bring the objects in touching contact. 
-										 */ 
-	} DT_ResponseType;
-    
-/* For witnessed response, the following structure represents a common point. The world 
-   coordinates of 'point1' and 'point2' coincide. 'normal' is the zero vector.
-   
-   For depth response, the following structure represents the penetration depth. 
-   'point1' en 'point2' are the witness points of the penetration depth in world coordinates.
-   The penetration depth vector in world coordinates is represented by 'normal'.
-*/
-
-	typedef struct DT_CollData {
-		DT_Vector3 point1;               /* Point in object1 in world coordinates */ 
-		DT_Vector3 point2;               /* Point in object2 in world coordinates */
-		DT_Vector3 normal;               /* point2 - point1 */ 
-	} DT_CollData;
-
-/* A response callback is called by SOLID for each pair of collding objects. 'client-data'
-   is a pointer to an arbitrary structure in the client application. The client objects are
-   pointers to structures in the client application associated with the coliding objects.
-   'coll_data' is the collision data computed by SOLID.
-*/
-
-	typedef DT_Bool (*DT_ResponseCallback)(void *client_data,
-										   void *client_object1,
-										   void *client_object2,
-										   const DT_CollData *coll_data);
-										
-/* Shape definition */
-
-
-	extern DECLSPEC DT_ShapeHandle DT_NewBox(DT_Scalar x, DT_Scalar y, DT_Scalar z);
-	extern DECLSPEC DT_ShapeHandle DT_NewCone(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewCylinder(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewSphere(DT_Scalar radius);
-	extern DECLSPEC DT_ShapeHandle DT_NewPoint(const DT_Vector3 point);
-	extern DECLSPEC DT_ShapeHandle DT_NewLineSegment(const DT_Vector3 source, const DT_Vector3 target);
-	extern DECLSPEC DT_ShapeHandle DT_NewMinkowski(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-	extern DECLSPEC DT_ShapeHandle DT_NewHull(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-
-	extern DECLSPEC DT_VertexBaseHandle DT_NewVertexBase(const void *pointer, DT_Size stride);
-	extern DECLSPEC void DT_DeleteVertexBase(DT_VertexBaseHandle vertexBase);	
-	extern DECLSPEC void DT_ChangeVertexBase(DT_VertexBaseHandle vertexBase, const void *pointer);
-
-	extern DECLSPEC DT_ShapeHandle DT_NewComplexShape(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndComplexShape();
-
-	extern DECLSPEC DT_ShapeHandle DT_NewPolytope(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndPolytope();
-
-	extern DECLSPEC void DT_Begin();
-	extern DECLSPEC void DT_End();
-
-	extern DECLSPEC void DT_Vertex(const DT_Vector3 vertex);
-	extern DECLSPEC void DT_VertexIndex(DT_Index index);
-
-	extern DECLSPEC void DT_VertexIndices(DT_Count count, const DT_Index *indices);
-	extern DECLSPEC void DT_VertexRange(DT_Index first, DT_Count count); 
-
-	extern DECLSPEC void DT_DeleteShape(DT_ShapeHandle shape);
-
-/* Object  */
-
-	extern DECLSPEC DT_ObjectHandle DT_CreateObject(
-		void *client_object,      /* pointer to object in client memory */
-		DT_ShapeHandle shape  /* the shape or geometry of the object */
-		);
-
-	extern DECLSPEC void DT_DestroyObject(DT_ObjectHandle object);
-
-
-
-	extern DECLSPEC void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position);
-	extern DECLSPEC void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation);
-	extern DECLSPEC void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling);
-
-/* The margin is an offset from the actual shape. The actual geometry of an
-   object is the set of points whose distance to the transformed shape is at 
-   most the  margin. During the lifetime of an object the margin can be 
-   modified. 
-*/
-   
-	extern DECLSPEC void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin);
-
-
-/* These commands assume a column-major 4x4 OpenGL matrix representation */
-
-	extern DECLSPEC void DT_SetMatrixf(DT_ObjectHandle object, const float *m); 
-	extern DECLSPEC void DT_GetMatrixf(DT_ObjectHandle object, float *m); 
-
-	extern DECLSPEC void DT_SetMatrixd(DT_ObjectHandle object, const double *m); 
-	extern DECLSPEC void DT_GetMatrixd(DT_ObjectHandle object, double *m); 
-
-	extern DECLSPEC void DT_GetBBox(DT_ObjectHandle object, DT_Vector3 min, DT_Vector3 max);
-
-	
-	extern DECLSPEC DT_Bool  DT_GetIntersect(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 v);
-/* This next command returns the distance between the objects. De returned
-   closest points are given in world coordinates.
-*/
-	extern DECLSPEC DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point1, DT_Vector3 point2);  
-
-	extern DECLSPEC DT_Bool   DT_GetCommonPoint(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point);
-
-	extern DECLSPEC DT_Bool   DT_GetPenDepth(DT_ObjectHandle object1, DT_ObjectHandle object2,
-											 DT_Vector3 point1, DT_Vector3 point2);  
-
-/* Scene */
-
-	extern DECLSPEC DT_SceneHandle DT_CreateScene(); 
-	extern DECLSPEC void           DT_DestroyScene(DT_SceneHandle scene);
-
-	extern DECLSPEC void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object);
-	extern DECLSPEC void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object);
-
-/* Note that objects can be assigned to multiple scenes! */
-
-/* Response */
-
-/* Response tables are defined independent of the scenes in which they are used.
-   Multiple response tables can be used in one scene, and a response table
-   can be shared among scenes.
-*/
-	extern DECLSPEC DT_RespTableHandle DT_CreateRespTable(); 
-	extern DECLSPEC void               DT_DestroyRespTable(DT_RespTableHandle respTable); 
-
-/* Responses are defined on (pairs of) response classes. Each response table 
-   maintains its set of response classes.
-*/
-	extern DECLSPEC DT_ResponseClass DT_GenResponseClass(DT_RespTableHandle respTable);
-
-/* To each object for which a response is defined in the response table a
-   response class needs to be assigned. 
-*/
-
-	extern DECLSPEC void DT_SetResponseClass(DT_RespTableHandle respTable,
-											 DT_ObjectHandle object,
-											 DT_ResponseClass responseClass);
-
-	extern DECLSPEC void DT_ClearResponseClass(DT_RespTableHandle respTable, 
-											   DT_ObjectHandle object);
-
-	extern DECLSPEC void DT_CallResponse(DT_RespTableHandle respTable,
-										 DT_ObjectHandle object1,
-										 DT_ObjectHandle object2,
-										 const DT_CollData *coll_data);
-
-/* For each pair of objects multiple responses can be defined. A response is a callback
-   together with its response type and client data. */
-    
-/* Responses can be defined for all pairs of response classes... */
-	extern DECLSPEC void DT_AddDefaultResponse(DT_RespTableHandle respTable,
-											   DT_ResponseCallback response, 
-											   DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveDefaultResponse(DT_RespTableHandle respTable,
-												  DT_ResponseCallback response);
-/* ...per response class... */
-	extern DECLSPEC void DT_AddClassResponse(DT_RespTableHandle respTable,
-											 DT_ResponseClass responseClass,
-											 DT_ResponseCallback response,
-											 DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveClassResponse(DT_RespTableHandle respTable,
-												DT_ResponseClass responseClass,
-												DT_ResponseCallback response);
-
-/* ... and per pair of response classes...*/
-	extern DECLSPEC void DT_AddPairResponse(DT_RespTableHandle respTable,
-											DT_ResponseClass responseClass1,
-											DT_ResponseClass responseClass2, 
-											DT_ResponseCallback response,
-											DT_ResponseType type, void *client_data);
-	extern DECLSPEC void DT_RemovePairResponse(DT_RespTableHandle respTable,
-											   DT_ResponseClass responseClass1,
-											   DT_ResponseClass responseClass2,
-											   DT_ResponseCallback response);
-
-/* The next command calls the response callbacks for all intersecting pairs of objects in a scene. 
-   'DT_Test' returns the number of pairs of objects for which callbacks have been called. 
-*/
- 
-	extern DECLSPEC DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable);
-
-/* Set the maximum relative error in the closest points and penetration depth
-   computation. The default for `max_error' is 1.0e-3. Larger errors result
-   in better performance. Non-positive error tolerances are ignored.
-*/ 
-
-	extern DECLSPEC void DT_SetAccuracy(DT_Scalar max_error);
-
-/* Set the maximum tolerance on relative errors due to rounding.  The default for `tol_error' 
-   is the machine epsilon. Very large tolerances result in false collisions. Setting tol_error too small 
-   results in missed collisions. Non-positive error tolerances are ignored. 
-*/ 
-    
-	extern DECLSPEC void DT_SetTolerance(DT_Scalar tol_error);
-
-
-/* This function returns the client pointer to the first object in a scene hit by the ray 
-   (actually a line segment) defined by the points 'from' en 'to'. The spot is the hit point 
-   on the object in local coordinates. 'normal' is the normal to the surface of the object in
-   world coordinates. The ignore_client pointer is used to make one of the objects transparent.
-
-   NB: Currently ray tests are implemented for spheres, boxes, and meshes only!!
-*/   
-
-	extern DECLSPEC void *DT_RayCast(DT_SceneHandle scene, void *ignore_client,
-									 const DT_Vector3 source, const DT_Vector3 target,
-									 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-/* Similar, only here a single object is tested and a boolean is returned */
-
-	extern DECLSPEC DT_Bool DT_ObjectRayCast(DT_ObjectHandle object,
-											 const DT_Vector3 source, const DT_Vector3 target,
-											 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/include/SOLID_broad.h b/extern/solid/include/SOLID_broad.h
deleted file mode 100644
index 74e4214fa67..00000000000
--- a/extern/solid/include/SOLID_broad.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_BROAD_H
-#define SOLID_BROAD_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    
-	DT_DECLARE_HANDLE(BP_SceneHandle);
-	DT_DECLARE_HANDLE(BP_ProxyHandle);
-	
-	typedef void (*BP_Callback)(void *client_data,
-								void *object1,
-								void *object2);
-
-	typedef bool (*BP_RayCastCallback)(void *client_data,
-									   void *object,
-									   const DT_Vector3 source,
-									   const DT_Vector3 target,
-									   DT_Scalar *lambda);
-	
-	extern DECLSPEC BP_SceneHandle BP_CreateScene(void *client_data,
-												  BP_Callback beginOverlap,
-												  BP_Callback endOverlap);
-	
-	extern DECLSPEC void           BP_DestroyScene(BP_SceneHandle scene);
-	
-	extern DECLSPEC BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, 
-												  void *object,
-												  const DT_Vector3 min, 
-												  const DT_Vector3 max);
-	
-	extern DECLSPEC void           BP_DestroyProxy(BP_SceneHandle scene, 
-												  BP_ProxyHandle proxy);
-	
-	extern DECLSPEC void BP_SetBBox(BP_ProxyHandle proxy, 
-									const DT_Vector3 min, 
-									const DT_Vector3 max);
-	
-	extern DECLSPEC void *BP_RayCast(BP_SceneHandle scene, 
-									 BP_RayCastCallback objectRayCast, 
-									 void *client_data,
-									 const DT_Vector3 source,
-									 const DT_Vector3 target,
-									 DT_Scalar *lambda);		
-	
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/include/SOLID_types.h b/extern/solid/include/SOLID_types.h
deleted file mode 100644
index 630594e447f..00000000000
--- a/extern/solid/include/SOLID_types.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_TYPES_H
-#define SOLID_TYPES_H
-
-#ifndef DECLSPEC
-# ifdef WIN32
-#  define DECLSPEC __declspec(dllexport)
-# else
-#  define DECLSPEC
-# endif
-#endif
-
-#define DT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
-    
-
-typedef unsigned short DT_Index;
-typedef unsigned short DT_Count;
-typedef unsigned int   DT_Size;
-typedef float          DT_Scalar; 
-typedef int            DT_Bool;
-
-#define DT_FALSE 0
-#define DT_TRUE  1
-
-#define DT_CONTINUE 0
-#define DT_DONE 1
-
-typedef DT_Scalar DT_Vector3[3]; 
-typedef DT_Scalar DT_Quaternion[4]; 
-
-#endif
diff --git a/extern/solid/make/msvc_7_0/broad/broad.vcproj b/extern/solid/make/msvc_7_0/broad/broad.vcproj
deleted file mode 100644
index adb56424e60..00000000000
--- a/extern/solid/make/msvc_7_0/broad/broad.vcproj
+++ /dev/null
@@ -1,262 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_7_0/complex/complex.vcproj b/extern/solid/make/msvc_7_0/complex/complex.vcproj
deleted file mode 100644
index 2a895fa28d3..00000000000
--- a/extern/solid/make/msvc_7_0/complex/complex.vcproj
+++ /dev/null
@@ -1,252 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_7_0/convex/convex.vcproj b/extern/solid/make/msvc_7_0/convex/convex.vcproj
deleted file mode 100644
index da088b5972f..00000000000
--- a/extern/solid/make/msvc_7_0/convex/convex.vcproj
+++ /dev/null
@@ -1,337 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_7_0/solid.vcproj b/extern/solid/make/msvc_7_0/solid.vcproj
deleted file mode 100644
index d9e6332987c..00000000000
--- a/extern/solid/make/msvc_7_0/solid.vcproj
+++ /dev/null
@@ -1,462 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/broad/broad.vcproj b/extern/solid/make/msvc_9_0/broad/broad.vcproj
deleted file mode 100644
index c58cb08b2c3..00000000000
--- a/extern/solid/make/msvc_9_0/broad/broad.vcproj
+++ /dev/null
@@ -1,369 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/complex/complex.vcproj b/extern/solid/make/msvc_9_0/complex/complex.vcproj
deleted file mode 100644
index 1828c489fc6..00000000000
--- a/extern/solid/make/msvc_9_0/complex/complex.vcproj
+++ /dev/null
@@ -1,355 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/convex/convex.vcproj b/extern/solid/make/msvc_9_0/convex/convex.vcproj
deleted file mode 100644
index cb35a0ea199..00000000000
--- a/extern/solid/make/msvc_9_0/convex/convex.vcproj
+++ /dev/null
@@ -1,469 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/solid.vcproj b/extern/solid/make/msvc_9_0/solid.vcproj
deleted file mode 100644
index ed81c374696..00000000000
--- a/extern/solid/make/msvc_9_0/solid.vcproj
+++ /dev/null
@@ -1,595 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/src/DT_AlgoTable.h b/extern/solid/src/DT_AlgoTable.h
deleted file mode 100644
index 0749ca7fdd9..00000000000
--- a/extern/solid/src/DT_AlgoTable.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ALGOTABLE_H
-#define DT_ALGOTABLE_H
-
-#include "DT_Shape.h"
-
-template 
-class AlgoTable {
-public:
-  void addEntry(DT_ShapeType type1, DT_ShapeType type2, Function function) 
-  { 
-    table[type2][type1] = function;
-    table[type1][type2] = function;
-  }
-
-  Function lookup(DT_ShapeType type1, DT_ShapeType type2) const 
-  {
-    return table[type1][type2];
-  }
-
-private:
-  Function table[NUM_TYPES][NUM_TYPES];
-};
-
-#endif
diff --git a/extern/solid/src/DT_C-api.cpp b/extern/solid/src/DT_C-api.cpp
deleted file mode 100644
index ac16deda87d..00000000000
--- a/extern/solid/src/DT_C-api.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-
-#include "SOLID.h"
-
-#include "DT_Box.h"
-#include "DT_Cone.h"
-#include "DT_Cylinder.h"
-#include "DT_Sphere.h"
-#include "DT_Complex.h"
-#include "DT_Polytope.h"
-#include "DT_Polyhedron.h"
-#include "DT_Point.h"
-#include "DT_LineSegment.h"
-#include "DT_Triangle.h"
-#include "DT_Minkowski.h"
-#include "DT_Hull.h"
-
-#include "DT_Response.h"
-#include "DT_RespTable.h"
-
-#include "DT_Scene.h"
-#include "DT_Object.h"
-
-#include "DT_VertexBase.h"
-
-#include "DT_Accuracy.h"
-
-typedef MT::Tuple3 T_Vertex;
-typedef std::vector T_VertexBuf;
-typedef std::vector T_IndexBuf;
-typedef std::vector T_PolyList;
-
-static T_VertexBuf vertexBuf;
-static T_IndexBuf indexBuf;
-static T_PolyList polyList; 
-
-static DT_Complex       *currentComplex    = 0;
-static DT_Polyhedron    *currentPolyhedron = 0;
-static DT_VertexBase    *currentBase = 0;
-
-
-
-
-
-		
-DT_VertexBaseHandle DT_NewVertexBase(const void *pointer, DT_Size stride) 
-{
-    return (DT_VertexBaseHandle)new DT_VertexBase(pointer, stride);
-}
-
-void DT_DeleteVertexBase(DT_VertexBaseHandle vertexBase) 
-{ 
-    delete (DT_VertexBase *)vertexBase; 
-}
-
-void DT_ChangeVertexBase(DT_VertexBaseHandle vertexBase, const void *pointer) 
-{ 
-	DT_VertexBase *base = (DT_VertexBase *)vertexBase;
-	base->setPointer(pointer);
-	const DT_ComplexList& complexList = base->getComplexList();
-	DT_ComplexList::const_iterator it;
-	for (it = complexList.begin(); it != complexList.end(); ++it)
-	{
-		(*it)->refit();
-	}
-}
-
-
-DT_ShapeHandle DT_NewBox(DT_Scalar x, DT_Scalar y, DT_Scalar z) 
-{
-    return (DT_ShapeHandle)new DT_Box(MT_Scalar(x) * MT_Scalar(0.5), 
-									  MT_Scalar(y) * MT_Scalar(0.5), 
-									  MT_Scalar(z) * MT_Scalar(0.5));
-}
-
-DT_ShapeHandle DT_NewCone(DT_Scalar radius, DT_Scalar height)
-{
-    return (DT_ShapeHandle)new DT_Cone(MT_Scalar(radius), MT_Scalar(height));
-}
-
-DT_ShapeHandle DT_NewCylinder(DT_Scalar radius, DT_Scalar height) 
-{
-    return (DT_ShapeHandle)new DT_Cylinder(MT_Scalar(radius), MT_Scalar(height));
-}
-
-DT_ShapeHandle DT_NewSphere(DT_Scalar radius) 
-{
-    return (DT_ShapeHandle)new DT_Sphere(MT_Scalar(radius));
-}
-
-DT_ShapeHandle DT_NewPoint(const DT_Vector3 point) 
-{
-	return (DT_ShapeHandle)new DT_Point(MT_Point3(point));
-}
-
-DT_ShapeHandle DT_NewLineSegment(const DT_Vector3 source, const DT_Vector3 target) 
-{
-	return (DT_ShapeHandle)new DT_LineSegment(MT_Point3(source), MT_Point3(target));
-}
-
-DT_ShapeHandle DT_NewMinkowski(DT_ShapeHandle shape1, DT_ShapeHandle shape2) 
-{
-	if (((DT_Shape *)shape1)->getType() != CONVEX ||
-		((DT_Shape *)shape2)->getType() != CONVEX) 
-	{
-		return 0;
-	}
-
-	return (DT_ShapeHandle)new DT_Minkowski(*(DT_Convex *)shape1, *(DT_Convex *)shape2);
-}
-	
-DT_ShapeHandle DT_NewHull(DT_ShapeHandle shape1, DT_ShapeHandle shape2)
-{
-	if (((DT_Shape *)shape1)->getType() != CONVEX ||
-		((DT_Shape *)shape2)->getType() != CONVEX) 
-	{
-		return 0;
-	}
-
-	return (DT_ShapeHandle)new DT_Hull(*(DT_Convex *)shape1, *(DT_Convex *)shape2);
-}
-
-DT_ShapeHandle DT_NewComplexShape(const DT_VertexBaseHandle vertexBase) 
-{
-    if (!currentComplex) 
-	{
-		currentBase = vertexBase ? (DT_VertexBase *)vertexBase : new DT_VertexBase;
-		currentComplex = new DT_Complex(currentBase);
-	}
-    return (DT_ShapeHandle)currentComplex;
-}
-
-void DT_EndComplexShape() 
-{
-    if (currentComplex) 
-	{
-        if (currentBase->getPointer() == 0) 
-		{
-            T_Vertex *vertexArray = new T_Vertex[vertexBuf.size()];   
-			assert(vertexArray);	
-            std::copy(vertexBuf.begin(), vertexBuf.end(), &vertexArray[0]);
-            currentBase->setPointer(vertexArray, true);		
-        }
-		
-		vertexBuf.clear();
-        
-        currentComplex->finish(polyList.size(), &polyList[0]);
-        polyList.clear();
-        currentComplex = 0;
-        currentBase = 0; 
-    }
-}
-
-DT_ShapeHandle DT_NewPolytope(const DT_VertexBaseHandle vertexBase) 
-{
-    if (!currentPolyhedron) 
-	{
-		currentBase = vertexBase ? (DT_VertexBase *)vertexBase : new DT_VertexBase;
-        currentPolyhedron = new DT_Polyhedron;
-		
-    }
-    return (DT_ShapeHandle)currentPolyhedron;
-}
-
-void DT_EndPolytope() 
-{
-    if (currentPolyhedron) 
-	{
-        if (currentBase->getPointer() == 0) 
-		{
-			currentBase->setPointer(&vertexBuf[0]);		
-			new (currentPolyhedron) DT_Polyhedron(currentBase, indexBuf.size(), &indexBuf[0]);
-			
-			delete currentBase;
-		}
-		else
-		{
-			new (currentPolyhedron) DT_Polyhedron(currentBase, indexBuf.size(), &indexBuf[0]);
-		}
-		vertexBuf.clear();
-        indexBuf.clear();
-        currentPolyhedron = 0;
-        currentBase = 0;
-    }
-}
-
-void DT_Begin() 
-{}
-
-void DT_End() 
-{ 
-	if (currentComplex) 
-	{
-		DT_VertexIndices(indexBuf.size(), &indexBuf[0]);
-		indexBuf.clear();
-	}
-}
-
-void DT_Vertex(const DT_Vector3 vertex)
-{
-    MT::Vector3 p(vertex);
-    int i = GEN_max((int)vertexBuf.size() - 20, 0);
-	int n = static_cast(vertexBuf.size());
-	
-    while (i != n  && !(vertexBuf[i] == p)) 
-	{
-		++i;
-	}
-
-    if (i == n) 
-	{
-		vertexBuf.push_back(p);
-	}
-    indexBuf.push_back(i);
-}
-
-
-void DT_VertexIndex(DT_Index index) { indexBuf.push_back(index); }
-
-void DT_VertexIndices(DT_Count count, const DT_Index *indices) 
-{
-    if (currentComplex) 
-	{
-		DT_Convex *poly = count == 3 ? 
-			              static_cast(new DT_Triangle(currentBase, indices[0], indices[1], indices[2])) :
-						  static_cast(new DT_Polytope(currentBase, count, indices));  
-		polyList.push_back(poly);
-      
-    }
-
-    if (currentPolyhedron) 
-	{
-		int i;
-		for (i = 0; i < count; ++i) 
-		{
-            indexBuf.push_back(indices[i]);
-        }
-    }   
-}
-
-void DT_VertexRange(DT_Index first, DT_Count count) 
-{
-    DT_Index *indices = new DT_Index[count];
-    
-	DT_Index i;
-    for (i = 0; i != count; ++i) 
-	{
-        indices[i] = first + i;
-    }
-    DT_VertexIndices(count, indices);
-
-    delete [] indices;	
-}
-
-void DT_DeleteShape(DT_ShapeHandle shape) 
-{ 
-    delete (DT_Shape *)shape; 
-}
-
-
-
-
-// Scene
-
-
-DT_SceneHandle DT_CreateScene() 
-{
-    return (DT_SceneHandle)new DT_Scene; 
-}
-
-void DT_DestroyScene(DT_SceneHandle scene) 
-{
-    delete (DT_Scene *)scene;
-}
-
-void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object) 
-{
-    assert(scene);
-    assert(object);
-    ((DT_Scene *)scene)->addObject(*(DT_Object *)object);
-}
-
-void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object) 
-{
-    assert(scene);
-    assert(object);
-    ((DT_Scene *)scene)->removeObject(*(DT_Object *)object);
-}
-
-
-// Object instantiation
-
-
-DT_ObjectHandle DT_CreateObject(void *client_object,
-                                DT_ShapeHandle shape)
-{
-	return (DT_ObjectHandle)new DT_Object(client_object, *(DT_Shape *)shape);
-}
-
-void DT_DestroyObject(DT_ObjectHandle object) 
-{
-    delete (DT_Object *)object;
-}
-
-void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin) 
-{
-    ((DT_Object *)object)->setMargin(MT_Scalar(margin));
-}
-
-
-void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling) 
-{
-    ((DT_Object *)object)->setScaling(MT_Vector3(scaling));
-}
-
-void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position) 
-{
-    ((DT_Object *)object)->setPosition(MT_Point3(position));
-}
-
-void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation) 
-{
-    ((DT_Object *)object)->setOrientation(MT_Quaternion(orientation));   
-}
-
-
-void DT_SetMatrixf(DT_ObjectHandle object, const float *m) 
-{
-    ((DT_Object *)object)->setMatrix(m);
-}
-
-void DT_GetMatrixf(DT_ObjectHandle object, float *m) 
-{
-    ((DT_Object *)object)->getMatrix(m);
-}
-
-void DT_SetMatrixd(DT_ObjectHandle object, const double *m) 
-{
-    ((DT_Object *)object)->setMatrix(m);
-}
-void DT_GetMatrixd(DT_ObjectHandle object, double *m) 
-{
-    ((DT_Object *)object)->getMatrix(m);
-}
-
-void DT_GetBBox(DT_ObjectHandle object, DT_Vector3 min, DT_Vector3 max) 
-{
-	const MT_BBox& bbox = ((DT_Object *)object)->getBBox();
-	bbox.getMin().getValue(min);
-	bbox.getMax().getValue(max);
-}
-
-DT_Bool DT_GetIntersect(DT_ObjectHandle object1, DT_ObjectHandle object2, DT_Vector3 vec)
-{
-	MT_Vector3 v;
-	DT_Bool result = intersect(*(DT_Object*)object1, *(DT_Object*)object2, v);
-	v.getValue(vec);
-	return result;
-}
-
-DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
-							DT_Vector3 point1, DT_Vector3 point2) 
-{
-    MT_Point3 p1, p2;
-    
-    MT_Scalar result = closest_points(*(DT_Object *)object1, 
-									  *(DT_Object *)object2,
-									  p1, p2);
-	p1.getValue(point1);
-	p2.getValue(point2);
-
-    return MT_sqrt(result);
-}
-
-DT_Bool DT_GetCommonPoint(DT_ObjectHandle object1, DT_ObjectHandle object2,
-						  DT_Vector3 point) 
-{
-    MT_Point3   p1, p2;
-	MT_Vector3  v(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)); 
-    
-    bool result = common_point(*(DT_Object *)object1, *(DT_Object *)object2, v, p1, p2);
-
-	if (result) 
-	{
-		p1.getValue(point);
-	}
-
-    return result;
-}
-
-DT_Bool DT_GetPenDepth(DT_ObjectHandle object1, DT_ObjectHandle object2,
-				    DT_Vector3 point1, DT_Vector3 point2) 
-{
-    MT_Point3   p1, p2;
-	MT_Vector3  v(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)); 
-    
-    bool result = penetration_depth(*(DT_Object *)object1, *(DT_Object *)object2, v, p1, p2);
-
-	if (result) 
-	{
-		p1.getValue(point1);
-		p2.getValue(point2);
-	}
-
-    return result;
-}
-
-// Response
-
-DT_RespTableHandle DT_CreateRespTable() 
-{
-    return (DT_RespTableHandle)new DT_RespTable;
-}    
-
-void DT_DestroyRespTable(DT_RespTableHandle respTable) 
-{
-    delete (DT_RespTable *)respTable;
-}
-
-DT_ResponseClass DT_GenResponseClass(DT_RespTableHandle respTable) 
-{
-	return ((DT_RespTable *)respTable)->genResponseClass();
-}
-
-void DT_SetResponseClass(DT_RespTableHandle respTable, DT_ObjectHandle object,
-						 DT_ResponseClass responseClass)
-{
-	((DT_RespTable *)respTable)->setResponseClass(object, responseClass);
-}
-
-void DT_ClearResponseClass(DT_RespTableHandle respTable, 
-						   DT_ObjectHandle object)
-{
-	((DT_RespTable *)respTable)->clearResponseClass(object);
-}
-
-void DT_CallResponse(DT_RespTableHandle respTable,
-					 DT_ObjectHandle object1,
-					 DT_ObjectHandle object2,
-					 const DT_CollData *coll_data)
-{
-	const DT_ResponseList& responseList =
-		((DT_RespTable *)respTable)->find(object1, object2);
-	
-	if (responseList.getType() != DT_NO_RESPONSE) 
-	{
-		responseList(((DT_Object *)object1)->getClientObject(), 
-					 ((DT_Object *)object2)->getClientObject(),
-					 coll_data);
-	}
-}
-
-
-void DT_AddDefaultResponse(DT_RespTableHandle respTable,
-                           DT_ResponseCallback response, 
-						   DT_ResponseType type, void *client_data)
-{
-    ((DT_RespTable *)respTable)->addDefault(DT_Response(response, type, client_data));
-}
-
-void DT_RemoveDefaultResponse(DT_RespTableHandle respTable,
-							  DT_ResponseCallback response)
-{
-      ((DT_RespTable *)respTable)->removeDefault(DT_Response(response));
-}
-
-void DT_AddClassResponse(DT_RespTableHandle respTable,
-						 DT_ResponseClass responseClass, 
-						 DT_ResponseCallback response, 
-						 DT_ResponseType type, void *client_data)
-{
-    ((DT_RespTable *)respTable)->addSingle(responseClass, 
-										   DT_Response(response, type, client_data));
-}
-
-void DT_RemoveClassResponse(DT_RespTableHandle respTable,
-							DT_ResponseClass responseClass, 
-							DT_ResponseCallback response) 
-{
-    ((DT_RespTable *)respTable)->removeSingle(responseClass, 
-											  DT_Response(response));
-}
-
-void DT_AddPairResponse(DT_RespTableHandle respTable,
-                        DT_ResponseClass responseClass1, 
-						DT_ResponseClass responseClass2, 
-                        DT_ResponseCallback response,
-						DT_ResponseType type, void *client_data)
-{
-    ((DT_RespTable *)respTable)->addPair(responseClass1, responseClass2, 
-										 DT_Response(response, type, client_data));
-}
-
-void DT_RemovePairResponse(DT_RespTableHandle respTable,
-						   DT_ResponseClass responseClass1, 
-						   DT_ResponseClass responseClass2, 
-						   DT_ResponseCallback response)
-{
-    ((DT_RespTable *)respTable)->removePair(responseClass1, responseClass2, 
-											DT_Response(response));
-}
-
-
-// Runtime
-
-void DT_SetAccuracy(DT_Scalar max_error) 
-{ 
-	if (max_error > MT_Scalar(0.0)) 
-	{
-		DT_Accuracy::setAccuracy(MT_Scalar(max_error)); 
-	}
-}
-
-void DT_SetTolerance(DT_Scalar tol_error) 
-{ 
-	if (tol_error > MT_Scalar(0.0)) 
-	{
-		DT_Accuracy::setTolerance(MT_Scalar(tol_error)); 
-	}
-}
-
-DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable) 
-{ 
-    return ((DT_Scene *)scene)->handleCollisions((DT_RespTable *)respTable);
-}
-
-void *DT_RayCast(DT_SceneHandle scene, void *ignore_client,
-				 const DT_Vector3 source, const DT_Vector3 target,
-				 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal) 
-{
-	DT_Scalar  lambda = max_param;
-
-	void *client_object = ((DT_Scene *)scene)->rayCast(ignore_client, source, target, 
-													   lambda, normal);
-   if (client_object)
-   {
-      *param = lambda;
-   }
-	return client_object;
-}
-
-DT_Bool DT_ObjectRayCast(DT_ObjectHandle object,
-	   				     const DT_Vector3 source, const DT_Vector3 target,
-					     DT_Scalar max_param, DT_Scalar *param, DT_Vector3 hit_normal) 
-{
-	MT_Scalar lambda = MT_Scalar(max_param);
-	MT_Vector3 normal;  
-
-	bool result = ((DT_Object *)object)->ray_cast(MT_Point3(source), MT_Point3(target), 
-												  lambda, normal);
-
-	if (result) 
-	{
-		*param = lambda;
-		normal.getValue(hit_normal);
-	}
-	return result;
-}
-
diff --git a/extern/solid/src/DT_Encounter.cpp b/extern/solid/src/DT_Encounter.cpp
deleted file mode 100644
index 36de33154a3..00000000000
--- a/extern/solid/src/DT_Encounter.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_RespTable.h"
-#include "DT_Encounter.h"
-#include "DT_Object.h"
-#include "GEN_MinMax.h"
-
-DT_Bool DT_Encounter::exactTest(const DT_RespTable *respTable, int& count) const 
-{
-	const DT_ResponseList& responseList = respTable->find(m_obj_ptr1, m_obj_ptr2);
-
-   switch (responseList.getType()) 
-   {
-   case DT_BROAD_RESPONSE:
-	   return (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2)) ?
-			   responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), 0) :   
-			   responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), 0);    
-   case DT_SIMPLE_RESPONSE: 
-	   if (intersect(*m_obj_ptr1, *m_obj_ptr2, m_sep_axis)) 
-	   {
-		   ++count;
-		   return (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2)) ?
-			   responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), 0) :   
-			   responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), 0);    
- 
-	   }
-	   break;
-   case DT_WITNESSED_RESPONSE: {
-	   MT_Point3  p1, p2;
-	   
-	   if (common_point(*m_obj_ptr1, *m_obj_ptr2, m_sep_axis, p1, p2)) 
-	   { 
-		   ++count;
-           if (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2))
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point1);
-			   p2.getValue(coll_data.point2);
-			   
-               return responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), &coll_data);
-           }
-           else
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point2);
-			   p2.getValue(coll_data.point1);
-			   
-               return responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), &coll_data);
-           }
-	   }
-	   break;
-   }
-   case DT_DEPTH_RESPONSE: {
-	   MT_Point3  p1, p2;
-	   
-	   if (penetration_depth(*m_obj_ptr1, *m_obj_ptr2, m_sep_axis, p1, p2)) 
-	   { 
-		   ++count;
-           if (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2))
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point1);
-			   p2.getValue(coll_data.point2);	
-               (p2 - p1).getValue(coll_data.normal);
-			   
-               return responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), &coll_data);
-           }
-           else
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point2);
-			   p2.getValue(coll_data.point1); 
-               (p1 - p2).getValue(coll_data.normal);
-			   
-               return responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), &coll_data);
-           }
-	   }
-	   break;
-   }
-   case DT_NO_RESPONSE:
-	   break;
-   default:
-	   assert(false);
-   }
-   return DT_CONTINUE;
-}
diff --git a/extern/solid/src/DT_Encounter.h b/extern/solid/src/DT_Encounter.h
deleted file mode 100644
index f20ea3936b0..00000000000
--- a/extern/solid/src/DT_Encounter.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ENCOUNTER_H
-#define DT_ENCOUNTER_H
-
-#include 
-
-#include "MT_Vector3.h"
-#include "DT_Object.h"
-#include "DT_Shape.h"
-
-class DT_RespTable;
-
-class DT_Encounter {
-public:
-    DT_Encounter() {}
-    DT_Encounter(DT_Object *obj_ptr1, DT_Object *obj_ptr2) 
-        : m_sep_axis(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)) 
-    {
-		assert(obj_ptr1 != obj_ptr2);
-        if (obj_ptr2->getType() < obj_ptr1->getType() || 
-            (obj_ptr2->getType() == obj_ptr1->getType() &&
-             obj_ptr2 < obj_ptr1))
-        { 
-            m_obj_ptr1 = obj_ptr2; 
-            m_obj_ptr2 = obj_ptr1; 
-        }
-        else 
-        { 
-            m_obj_ptr1 = obj_ptr1; 
-            m_obj_ptr2 = obj_ptr2; 
-        }
-    }
-
-    DT_Object         *first()          const { return m_obj_ptr1; }
-    DT_Object         *second()         const { return m_obj_ptr2; }
-    const MT_Vector3&  separatingAxis() const { return m_sep_axis; }
-
- 	DT_Bool exactTest(const DT_RespTable *respTable, int& count) const;
-
-private:
-    DT_Object          *m_obj_ptr1;
-    DT_Object          *m_obj_ptr2;
-    mutable MT_Vector3  m_sep_axis;
-};
-
-inline bool operator<(const DT_Encounter& a, const DT_Encounter& b) 
-{ 
-    return a.first() < b.first() || 
-        (a.first() == b.first() && a.second() < b.second()); 
-}
-
-
-
-inline std::ostream& operator<<(std::ostream& os, const DT_Encounter& a) {
-    return os << '(' << a.first() << ", " << a.second() << ')';
-}
-
-
-
-typedef std::set DT_EncounterTable;
-
-#endif
diff --git a/extern/solid/src/DT_Object.cpp b/extern/solid/src/DT_Object.cpp
deleted file mode 100644
index ed43a7bdaf2..00000000000
--- a/extern/solid/src/DT_Object.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Object.h"
-#include "DT_AlgoTable.h"
-#include "DT_Convex.h" 
-#include "DT_Complex.h" 
-#include "DT_LineSegment.h" 
-#include "DT_Transform.h"
-#include "DT_Minkowski.h"
-#include "DT_Sphere.h"
-
-void DT_Object::setBBox() 
-{
-	m_bbox = m_shape.bbox(m_xform, m_margin); 
-	DT_Vector3 min, max;
-	m_bbox.getMin().getValue(min);
-	m_bbox.getMax().getValue(max);
-	
-	T_ProxyList::const_iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it) 
-	{
-		BP_SetBBox(*it, min, max);
-	}
-}
-
-bool DT_Object::ray_cast(const MT_Point3& source, const MT_Point3& target, 
-						 MT_Scalar& lambda, MT_Vector3& normal) const 
-{	
-	MT_Transform inv_xform = m_xform.inverse();
-	MT_Point3 local_source = inv_xform(source);
-	MT_Point3 local_target = inv_xform(target);
-	MT_Vector3 local_normal;
-
-	bool result = m_shape.ray_cast(local_source, local_target, lambda, local_normal);
-    	
-	if (result) 
-	{
-		normal = local_normal * inv_xform.getBasis();
-      MT_Scalar len = normal.length();
-		if (len > MT_Scalar(0.0))
-      {
-         normal /= len;
-      }
-	}
-
-	return result;
-}
-
-
-typedef AlgoTable IntersectTable;
-typedef AlgoTable Common_pointTable;
-typedef AlgoTable Penetration_depthTable;
-typedef AlgoTable Closest_pointsTable;
-
-
-bool intersectConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                           MT_Vector3& v) 
-{
-	DT_Transform ta(a2w, (const DT_Convex&)a);
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-    return intersect((a_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : static_cast(ta)), 
-			         (b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v);
-}
-
-bool intersectComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						    const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                            MT_Vector3& v) 
-{
-	if (a.getType() == COMPLEX)
-	{
-		DT_Transform tb(b2w, (const DT_Convex&)b);
-		return intersect((const DT_Complex&)a, a2w, a_margin, 
-		             (b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v);
-	}
-	
-	bool r = intersectComplexConvex(b, b2w, b_margin, a, a2w, a_margin, v);
-	v *= -1.;
-	return r;
-}
-
-bool intersectComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-							 const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                             MT_Vector3& v) 
-{
-    return intersect((const DT_Complex&)a, a2w, a_margin, 
-					 (const DT_Complex&)b, b2w, b_margin, v);
-}
-
-IntersectTable *intersectInitialize() 
-{
-    IntersectTable *p = new IntersectTable;
-    p->addEntry(COMPLEX, COMPLEX, intersectComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, intersectComplexConvex);
-    p->addEntry(CONVEX, CONVEX, intersectConvexConvex);
-    return p;
-}
-
-bool intersect(const DT_Object& a, const DT_Object& b, MT_Vector3& v) 
-{
-    static IntersectTable *intersectTable = intersectInitialize();
-    Intersect intersect = intersectTable->lookup(a.getType(), b.getType());
-    return intersect(a.m_shape, a.m_xform, a.m_margin, 
-		             b.m_shape, b.m_xform, b.m_margin, v);
-}
-
-bool common_pointConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-							  const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-							  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-	DT_Transform ta(a2w, (const DT_Convex&)a);
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-    return common_point((a_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : static_cast(ta)), 
-						(b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v, pa, pb);
-}
-
-bool common_pointComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-							   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-							   MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-	if (a.getType() == COMPLEX)
-	{
-		DT_Transform tb(b2w, (const DT_Convex&)b);
-		return common_point((const DT_Complex&)a, a2w, a_margin,
-					(b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v, pa, pb);
-	}
-	
-	bool r = common_pointComplexConvex(b, b2w, b_margin, a, a2w, a_margin, v, pb, pa);
-	v *= -1.;
-	return r;
-}
-
-bool common_pointComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-								const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-								MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    return common_point((const DT_Complex&)a, a2w, a_margin, 
-						(const DT_Complex&)b, b2w, b_margin, v, pa, pb);
-}
-
-Common_pointTable *common_pointInitialize() 
-{
-    Common_pointTable *p = new Common_pointTable;
-    p->addEntry(COMPLEX, COMPLEX, common_pointComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, common_pointComplexConvex);
-    p->addEntry(CONVEX, CONVEX, common_pointConvexConvex);
-    return p;
-}
-
-bool common_point(const DT_Object& a, const DT_Object& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    static Common_pointTable *common_pointTable = common_pointInitialize();
-    Common_point common_point = common_pointTable->lookup(a.getType(), b.getType());
-    return common_point(a.m_shape, a.m_xform, a.m_margin, 
-						b.m_shape, b.m_xform, b.m_margin, v, pa, pb);
-}
-
-
-
-bool penetration_depthConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-								   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                   MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    return hybrid_penetration_depth(DT_Transform(a2w, (const DT_Convex&)a), a_margin, 
-									DT_Transform(b2w, (const DT_Convex&)b), b_margin, v, pa, pb);
-}
-
-bool penetration_depthComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                    MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    if (a.getType() == COMPLEX)
-    	return penetration_depth((const DT_Complex&)a, a2w, a_margin,
-							 DT_Transform(b2w, (const DT_Convex&)b), b_margin, v, pa, pb);
-
-    bool r = penetration_depthComplexConvex(b, b2w, b_margin, a, a2w, a_margin, v, pb, pa);
-    v *= -1.;
-    return r;
-}
-
-bool penetration_depthComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									 const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                     MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    return penetration_depth((const DT_Complex&)a, a2w, a_margin, (const DT_Complex&)b, b2w, b_margin, v, pa, pb);
-}
-
-Penetration_depthTable *penetration_depthInitialize() 
-{
-    Penetration_depthTable *p = new Penetration_depthTable;
-    p->addEntry(COMPLEX, COMPLEX, penetration_depthComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, penetration_depthComplexConvex);
-    p->addEntry(CONVEX, CONVEX, penetration_depthConvexConvex);
-    return p;
-}
-
-bool penetration_depth(const DT_Object& a, const DT_Object& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    static Penetration_depthTable *penetration_depthTable = penetration_depthInitialize();
-    Penetration_depth penetration_depth = penetration_depthTable->lookup(a.getType(), b.getType());
-    return penetration_depth(a.m_shape, a.m_xform, a.m_margin, 
-		                     b.m_shape, b.m_xform, b.m_margin, v, pa, pb);
-}
-
-
-MT_Scalar closest_pointsConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									 const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									 MT_Point3& pa, MT_Point3& pb)
-{
-	DT_Transform ta(a2w, (const DT_Convex&)a);
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-    return closest_points((a_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : static_cast(ta)), 
-						  (b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), MT_INFINITY, pa, pb);
-}
-
-MT_Scalar closest_pointsComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									  const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									  MT_Point3& pa, MT_Point3& pb)
-{
-    if (a.getType() == COMPLEX)
-    {
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-	return closest_points((const DT_Complex&)a, a2w, a_margin,
-							(b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), pa, pb);
-    }
-    
-    return closest_pointsComplexConvex(b, b2w, b_margin, a, a2w, a_margin, pb, pa);
-}
-
-MT_Scalar closest_pointsComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									   MT_Point3& pa, MT_Point3& pb) 
-{
-    return closest_points((const DT_Complex&)a, a2w, a_margin, 
-						  (const DT_Complex&)b, b2w, b_margin, pa, pb);
-}
-
-Closest_pointsTable *closest_pointsInitialize()
-{
-    Closest_pointsTable *p = new Closest_pointsTable;
-    p->addEntry(COMPLEX, COMPLEX, closest_pointsComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, closest_pointsComplexConvex);
-    p->addEntry(CONVEX, CONVEX, closest_pointsConvexConvex);
-    return p;
-}
-
-MT_Scalar closest_points(const DT_Object& a, const DT_Object& b,
-						 MT_Point3& pa, MT_Point3& pb) 
-{
-    static Closest_pointsTable *closest_pointsTable = closest_pointsInitialize();
-    Closest_points closest_points = closest_pointsTable->lookup(a.getType(), b.getType());
-    return closest_points(a.m_shape, a.m_xform, a.m_margin, 
-						  b.m_shape, b.m_xform, b.m_margin, pa, pb);
-}
-
diff --git a/extern/solid/src/DT_Object.h b/extern/solid/src/DT_Object.h
deleted file mode 100644
index 78beee2ab57..00000000000
--- a/extern/solid/src/DT_Object.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_OBJECT_H
-#define DT_OBJECT_H
-
-#include 
-
-#include "SOLID.h"
-#include "SOLID_broad.h"
-
-#include "MT_Transform.h"
-#include "MT_Quaternion.h"
-#include "MT_BBox.h"
-#include "DT_Shape.h"
-
-class DT_Convex;
-
-class DT_Object {
-public:
-    DT_Object(void *client_object, const DT_Shape& shape) :
-		m_client_object(client_object),
-		m_shape(shape), 
-		m_margin(MT_Scalar(0.0))
-	{
-		m_xform.setIdentity();
-		setBBox();
-	}
-
-	void setMargin(MT_Scalar margin) 
-	{ 
-		m_margin = margin; 
-		setBBox();
-	}
-
-	void setScaling(const MT_Vector3& scaling)
-	{
-        m_xform.scale(scaling);
-        setBBox();
-    }
-
-    void setPosition(const MT_Point3& pos) 
-	{ 
-        m_xform.setOrigin(pos);
-        setBBox();
-    }
-    
-    void setOrientation(const MT_Quaternion& orn)
-	{
-		m_xform.setRotation(orn);
-		setBBox();
-    }
-
-	void setMatrix(const float *m) 
-	{
-        m_xform.setValue(m);
-		assert(m_xform.getBasis().determinant() != MT_Scalar(0.0));
-        setBBox();
-    }
-
-    void setMatrix(const double *m)
-	{
-        m_xform.setValue(m);
-		assert(m_xform.getBasis().determinant() != MT_Scalar(0.0));
-        setBBox();
-    }
-
-    void getMatrix(float *m) const
-	{
-        m_xform.getValue(m);
-    }
-
-    void getMatrix(double *m) const 
-	{
-        m_xform.getValue(m);
-    }
-
-	void setBBox();
-
-	const MT_BBox& getBBox() const { return m_bbox; }	
-	
-    DT_ResponseClass getResponseClass() const { return m_responseClass; }
-    
-	void setResponseClass(DT_ResponseClass responseClass) 
-	{ 
-		m_responseClass = responseClass;
-	}
-
-    DT_ShapeType getType() const { return m_shape.getType(); }
-
-    void *getClientObject() const { return m_client_object; }
-
-	bool ray_cast(const MT_Point3& source, const MT_Point3& target, 
-				  MT_Scalar& param, MT_Vector3& normal) const; 
-
-	void addProxy(BP_ProxyHandle proxy) { m_proxies.push_back(proxy); }
-
-	void removeProxy(BP_ProxyHandle proxy) 
-	{ 
-		T_ProxyList::iterator it = std::find(m_proxies.begin(), m_proxies.end(), proxy);
-		if (it != m_proxies.end()) {
-			m_proxies.erase(it);
-		}
-	}
-
-
-	friend bool intersect(const DT_Object&, const DT_Object&, MT_Vector3& v);
-	
-	friend bool common_point(const DT_Object&, const DT_Object&, MT_Vector3&, 
-							 MT_Point3&, MT_Point3&);
-	
-	friend bool penetration_depth(const DT_Object&, const DT_Object&, 
-								  MT_Vector3&, MT_Point3&, MT_Point3&);
-	
-	friend MT_Scalar closest_points(const DT_Object&, const DT_Object&, 
-									MT_Point3&, MT_Point3&);
-
-private:
-	typedef std::vector T_ProxyList;
-
-	void              *m_client_object;
-	DT_ResponseClass   m_responseClass;
-    const DT_Shape&    m_shape;
-    MT_Scalar          m_margin;
-	MT_Transform       m_xform;
-	T_ProxyList		   m_proxies;
-	MT_BBox            m_bbox;
-};
-
-#endif
-
-
-
-
-
-
-
diff --git a/extern/solid/src/DT_RespTable.cpp b/extern/solid/src/DT_RespTable.cpp
deleted file mode 100644
index 20fbfc06aac..00000000000
--- a/extern/solid/src/DT_RespTable.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_RespTable.h"
-
-#include 
-
-DT_ResponseList DT_RespTable::g_emptyResponseList;
-
-DT_RespTable::~DT_RespTable()
-{
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		delete [] m_table[i];
-	}
-}
-
-DT_ResponseClass DT_RespTable::genResponseClass()
-{
-	DT_ResponseClass newClass = m_responseClass++;
-	DT_ResponseList *newList = new DT_ResponseList[m_responseClass];
-	assert(newList);
-	m_table.push_back(newList);
-	m_singleList.resize(m_responseClass);
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		newList[i].append(m_default);
-		newList[i].append(m_singleList[i]);
-	}
-	return newClass;
-}
-
-void DT_RespTable::setResponseClass(void *object, 
-									DT_ResponseClass responseClass) 
-{
-	assert(responseClass < m_responseClass);
-	m_objectMap[object] = responseClass;
-}
-
-DT_ResponseClass DT_RespTable::getResponseClass(void *object) const
-{
-	T_ObjectMap::const_iterator it = m_objectMap.find(object);
-	assert(it != m_objectMap.end());
-	return (*it).second;
-}
-
-void DT_RespTable::clearResponseClass(void *object) 
-{
-	m_objectMap.erase(object);
-}
-
-const DT_ResponseList& DT_RespTable::find(void *object1, void *object2) const
-{
-	T_ObjectMap::const_iterator it = m_objectMap.find(object1);
-	if (it != m_objectMap.end()) 
-	{
-		DT_ResponseClass responseClass1 = (*it).second;
-		it = m_objectMap.find(object2);
-		if (it != m_objectMap.end()) 
-		{
-			DT_ResponseClass responseClass2 = (*it).second;
-			if (responseClass1 < responseClass2) 
-			{
-				std::swap(responseClass1, responseClass2);
-			}
-			return m_table[responseClass1][responseClass2];
-		}
-	}
-	return g_emptyResponseList;
-}
-
-void DT_RespTable::addDefault(const DT_Response& response)
-{
-	m_default.addResponse(response);
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		DT_ResponseClass j;
-		for (j = 0; j <= i; ++j) 
-		{
-			m_table[i][j].addResponse(response);
-		}
-	}
-}
-
-void DT_RespTable::removeDefault(const DT_Response& response)
-{
-	m_default.removeResponse(response);
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		DT_ResponseClass j;
-		for (j = 0; j <= i; ++j) 
-		{
-			m_table[i][j].removeResponse(response);
-		}
-	}
-}
-
-void DT_RespTable::addSingle(DT_ResponseClass responseClass, 
-							 const DT_Response& response)
-{	
-	assert(responseClass < m_responseClass);
-	m_singleList[responseClass].addResponse(response);
-	DT_ResponseClass j;
-	for (j = 0; j < responseClass; ++j) 
-	{
-		m_table[responseClass][j].addResponse(response);
-	}
-	
-	DT_ResponseClass i;
-	for (i = responseClass; i < m_responseClass; ++i) 
-	{
-		m_table[i][responseClass].addResponse(response);
-	}
-}
-
-void DT_RespTable::removeSingle(DT_ResponseClass responseClass, 
-								const DT_Response& response)
-{	
-	assert(responseClass < m_responseClass);
-	m_singleList[responseClass].removeResponse(response);
-	DT_ResponseClass j;
-	for (j = 0; j < responseClass; ++j) 
-	{
-		m_table[responseClass][j].removeResponse(response);
-	}
-	
-	DT_ResponseClass i;
-	for (i = responseClass; i < m_responseClass; ++i) 
-	{
-		m_table[i][responseClass].removeResponse(response);
-	}
-}
-
-void DT_RespTable::addPair(DT_ResponseClass responseClass1,
-						   DT_ResponseClass responseClass2, 
-						   const DT_Response& response)
-{
-	assert(responseClass1 < m_responseClass);
-	assert(responseClass2 < m_responseClass);
-	if (responseClass1 < responseClass2) 
-	{
-		std::swap(responseClass1, responseClass2);
-	}
-	m_table[responseClass1][responseClass2].addResponse(response);
-}
-
-
-void DT_RespTable::removePair(DT_ResponseClass responseClass1,
-							  DT_ResponseClass responseClass2, 
-							  const DT_Response& response)
-{
-	assert(responseClass1 < m_responseClass);
-	assert(responseClass2 < m_responseClass);
-	if (responseClass1 < responseClass2) 
-	{
-		std::swap(responseClass1, responseClass2);
-	}
-	m_table[responseClass1][responseClass2].removeResponse(response);
-}
-
diff --git a/extern/solid/src/DT_RespTable.h b/extern/solid/src/DT_RespTable.h
deleted file mode 100644
index 9a17f562937..00000000000
--- a/extern/solid/src/DT_RespTable.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_RESPTABLE_H
-#define DT_RESPTABLE_H
-
-#include 
-#include 
-#include 
-#include 
-#include "GEN_MinMax.h"
-#include "DT_Response.h"
-
-class DT_ResponseList : public std::list {
-public:
-    DT_ResponseList() : m_type(DT_NO_RESPONSE) {}
-
-	DT_ResponseType getType() const { return m_type; }
-
-    void addResponse(const DT_Response& response) 
-	{
-        if (response.getType() != DT_NO_RESPONSE) 
-		{
-            push_back(response);
-            GEN_set_max(m_type, response.getType());
-        }
-    }
-
-    void removeResponse(const DT_Response& response) 
-	{
-		iterator it = std::find(begin(), end(), response);
-		if (it != end()) 
-		{
-			erase(it);
-			m_type = DT_NO_RESPONSE;
-			for (it = begin(); it != end(); ++it) 
-			{
-				GEN_set_max(m_type, (*it).getType());
-			}
-		}
-    }
-	
-    void append(const DT_ResponseList& responseList) 
-	{
-        if (responseList.getType() != DT_NO_RESPONSE) 
-		{
-			const_iterator it;
-			for (it = responseList.begin(); it != responseList.end(); ++it) 
-			{
-				addResponse(*it);
-			}
-		}
-	}
-
-    DT_Bool operator()(void *a, void *b, const DT_CollData *coll_data) const 
-	{
-		DT_Bool done = DT_CONTINUE;
-		const_iterator it;
-        for (it = begin(); !done && it != end(); ++it) 
-		{
-            done = (*it)(a, b, coll_data);
-        }
-		return done;
-    }
-    
-private:
-	DT_ResponseType    m_type;
-};
-
-class DT_RespTable {
-private:
-	typedef std::map T_ObjectMap; 
-	typedef std::vector T_PairTable;
-	typedef std::vector T_SingleList;
-
-public:
-	DT_RespTable() : m_responseClass(0) {}
-
-	~DT_RespTable();
-
-	DT_ResponseClass genResponseClass();
-	
-	void setResponseClass(void *object, DT_ResponseClass responseClass);
-	DT_ResponseClass getResponseClass(void *object) const;
-	
-	void clearResponseClass(void *object);
-	
-	const DT_ResponseList& find(void *object1, void *object2) const;
-
-    void addDefault(const DT_Response& response); 
-    void removeDefault(const DT_Response& response); 
-
-    void addSingle(DT_ResponseClass responseClass, 
-				   const DT_Response& response);
-    void removeSingle(DT_ResponseClass responseClass, 
-					  const DT_Response& response);
-	
-    void addPair(DT_ResponseClass responseClass1, 
-				 DT_ResponseClass responseClass2, 
-				 const DT_Response& response);
-    void removePair(DT_ResponseClass responseClass1, 
-					DT_ResponseClass responseClass2, 
-					const DT_Response& response);
-
-private:
-	static DT_ResponseList g_emptyResponseList;
-
-	T_ObjectMap      m_objectMap;
-	DT_ResponseClass m_responseClass;
-	T_PairTable      m_table;
-	T_SingleList     m_singleList;
-    DT_ResponseList  m_default;
-};
-
-#endif
-
-
-
-
diff --git a/extern/solid/src/DT_Response.h b/extern/solid/src/DT_Response.h
deleted file mode 100644
index e58d9bb9944..00000000000
--- a/extern/solid/src/DT_Response.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_RESPONSE_H
-#define DT_RESPONSE_H
-
-#include "SOLID.h"
-
-class DT_Response {
-public:
-    DT_Response(DT_ResponseCallback response    = 0, 
-				DT_ResponseType     type        = DT_NO_RESPONSE, 
-				void               *client_data = 0) 
-	  : m_response(response), 
-		m_type(type), 
-		m_client_data(client_data) {}
-    
-	DT_ResponseType getType() const { return m_type; }
-
-	DT_Bool operator()(void *a, void *b, const DT_CollData *coll_data) const 
-	{  
-		return (*m_response)(m_client_data, a, b, coll_data); 
-	}
-
-	friend bool operator==(const DT_Response& a, const DT_Response& b) 
-	{
-		return a.m_response == b.m_response;
-	}
-    
-	friend bool operator!=(const DT_Response& a, const DT_Response& b) 
-	{
-		return a.m_response != b.m_response;
-	}
-    
-private:
-    DT_ResponseCallback  m_response;
-    DT_ResponseType      m_type;
-    void                *m_client_data;
-};
-
-#endif  
-
-
diff --git a/extern/solid/src/DT_Scene.cpp b/extern/solid/src/DT_Scene.cpp
deleted file mode 100644
index 56cea1633ca..00000000000
--- a/extern/solid/src/DT_Scene.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Scene.h"
-#include "DT_Object.h"
-#include "DT_Convex.h"
-
-//#define DEBUG
-
-static void beginOverlap(void *client_data, void *object1, void *object2) 
-{
-	DT_Encounter e((DT_Object *)object1, (DT_Object *)object2);
-	DT_EncounterTable *encounterTable = static_cast(client_data);
-
-#ifdef DEBUG	
-	std::cout << "Begin: " << e << std::endl; 
-#endif
-
-	encounterTable->insert(e);
-}
-
-
-static void endOverlap(void *client_data, void *object1, void *object2) 
-{
-	DT_Encounter e((DT_Object *)object1, (DT_Object *)object2);
-	DT_EncounterTable *encounterTable = static_cast(client_data);
-
-#ifdef DEBUG
-	std::cout << "End:   " << e << std::endl; 
-#endif
-	
-	assert(encounterTable->find(e) != encounterTable->end()); 
-	encounterTable->erase(e);
-}
-
-struct DT_RayCastData {
-	DT_RayCastData(const void *ignore) 
-	  : m_ignore(ignore) 
-	{}
-
-	const void  *m_ignore;
-	MT_Vector3  m_normal;
-};
-
-static bool objectRayCast(void *client_data, 
-						  void *object,  
-						  const DT_Vector3 source,
-						  const DT_Vector3 target,
-						  DT_Scalar *lambda) 
-{
-	DT_RayCastData *data = static_cast(client_data); 
-	if (((DT_Object *)object)->getClientObject() != data->m_ignore)
-	{
-		MT_Scalar param = MT_Scalar(*lambda);
-		
-		if (((DT_Object *)object)->ray_cast(MT_Point3(source), MT_Point3(target),
-											param, data->m_normal))
-		{
-			*lambda = param;
-			return true;
-		}
-	}
-	return false;
-}
-
-DT_Scene::DT_Scene() 
-  : m_broadphase(BP_CreateScene(&m_encounterTable, &beginOverlap, &endOverlap))
-{}
-
-DT_Scene::~DT_Scene()
-{
-	BP_DestroyScene(m_broadphase);
-}
-
-void DT_Scene::addObject(DT_Object &object)
-{
-	const MT_BBox& bbox = object.getBBox();
-	DT_Vector3 min, max;
-	bbox.getMin().getValue(min);
-	bbox.getMax().getValue(max);
-    BP_ProxyHandle proxy = BP_CreateProxy(m_broadphase, &object, min, max);
-	
-#ifdef DEBUG
-	DT_EncounterTable::iterator it;	
-	std::cout << "Add " << &object << ':';
-	for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it) {
-		std::cout << ' ' << (*it);
-	}
-	std::cout << std::endl;
-#endif
-	object.addProxy(proxy);
-    m_objectList.push_back(std::make_pair(&object, proxy));
-}
-
-
-
-void DT_Scene::removeObject(DT_Object& object)
-{
-    T_ObjectList::iterator it = m_objectList.begin();
-
-    while (it != m_objectList.end() && &object != (*it).first)
-	{
-        ++it;
-    }
-
-    if (it != m_objectList.end())
-	{
-		object.removeProxy((*it).second);
-        BP_DestroyProxy(m_broadphase, (*it).second);
-		m_objectList.erase(it);
-
-#ifdef DEBUG
-		std::cout << "Remove " << &object << ':';
-		DT_EncounterTable::iterator it;	
-		for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it)
-		{
-			std::cout << ' ' << (*it);
-			assert((*it).first() != &object &&
-				   (*it).second() != &object);
-		}
-		std::cout << std::endl;
-#endif
-    }
-}
-
-
-
-int DT_Scene::handleCollisions(const DT_RespTable *respTable)
-{
-    int count = 0;
-
-    assert(respTable);
-
-	DT_EncounterTable::iterator it;	
-	for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it)
-	{
-		if ((*it).exactTest(respTable, count))
-		{
-			break;
-        }
-	
-    }
-    return count;
-}
-
-void *DT_Scene::rayCast(const void *ignore_client,
-						const DT_Vector3 source, const DT_Vector3 target, 
-						DT_Scalar& lambda, DT_Vector3 normal) const 
-{
-	DT_RayCastData data(ignore_client);
-	DT_Object *object = (DT_Object *)BP_RayCast(m_broadphase, 
-												&objectRayCast, 
-												&data, 
-												source, target,
-												&lambda);
-	if (object)
-	{
-		data.m_normal.getValue(normal);
-		return object->getClientObject();
-	}
-	
-	return 0;
-}
diff --git a/extern/solid/src/DT_Scene.h b/extern/solid/src/DT_Scene.h
deleted file mode 100644
index 9b061910312..00000000000
--- a/extern/solid/src/DT_Scene.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_SCENE_H
-#define DT_SCENE_H
-
-#include 
-
-#include "SOLID_broad.h"
-#include "DT_Encounter.h"
-
-class DT_Object;
-class DT_RespTable;
-
-class DT_Scene {
-public:
-    DT_Scene();
-    ~DT_Scene();
-
-    void addObject(DT_Object& object);
-    void removeObject(DT_Object& object);
-
-    int  handleCollisions(const DT_RespTable *respTable);
-
-	void *rayCast(const void *ignore_client, 
-				  const DT_Vector3 source, const DT_Vector3 target, 
-				  DT_Scalar& lambda, DT_Vector3 normal) const;
-
-private:
-	typedef std::vector > T_ObjectList;
-
-	BP_SceneHandle      m_broadphase;
-	T_ObjectList        m_objectList;
-    DT_EncounterTable   m_encounterTable;
-};
-
-#endif
diff --git a/extern/solid/src/Makefile b/extern/solid/src/Makefile
deleted file mode 100644
index e8ef7a606c9..00000000000
--- a/extern/solid/src/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-SOURCEDIR = extern/solid/src
-LIBNAME = solid
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-DIRS = broad complex convex
-
-include nan_subdirs.mk
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../include -I$(NAN_QHULL)/include
-CPPFLAGS += -Iconvex -Icomplex
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
diff --git a/extern/solid/src/broad/BP_C-api.cpp b/extern/solid/src/broad/BP_C-api.cpp
deleted file mode 100644
index 43e1172927b..00000000000
--- a/extern/solid/src/broad/BP_C-api.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "SOLID_broad.h"
-
-#include "BP_Scene.h"
-#include "BP_Proxy.h"
-
-BP_SceneHandle BP_CreateScene(void *client_data,
-							  BP_Callback beginOverlap,
-							  BP_Callback endOverlap)
-{
-	return (BP_SceneHandle)new BP_Scene(client_data, 
-										beginOverlap, 
-										endOverlap);
-}
-
- 
-void BP_DestroyScene(BP_SceneHandle scene)
-{
-	delete (BP_Scene *)scene;
-}
-	
-
-BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, void *object,
-							  const DT_Vector3 min, const DT_Vector3 max)
-{
-	return (BP_ProxyHandle)
-		((BP_Scene *)scene)->createProxy(object, min, max);
-}
-
-
-void BP_DestroyProxy(BP_SceneHandle scene, BP_ProxyHandle proxy) 
-{
-	((BP_Scene *)scene)->destroyProxy((BP_Proxy *)proxy);
-}
-
-
-
-void BP_SetBBox(BP_ProxyHandle proxy, const DT_Vector3 min, const DT_Vector3 max)	
-{
-	((BP_Proxy *)proxy)->setBBox(min, max);
-}
-
-void *BP_RayCast(BP_SceneHandle scene, 
-				 BP_RayCastCallback objectRayCast,
-				 void *client_data,
-				 const DT_Vector3 source,
-				 const DT_Vector3 target,
-				 DT_Scalar *lambda) 
-{
-	return ((BP_Scene *)scene)->rayCast(objectRayCast,
-										client_data,
-										source,	target,
-										*lambda);
-}
-
diff --git a/extern/solid/src/broad/BP_Endpoint.h b/extern/solid/src/broad/BP_Endpoint.h
deleted file mode 100644
index 8de6e67ce65..00000000000
--- a/extern/solid/src/broad/BP_Endpoint.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_ENDPOINT_H
-#define BP_ENDPOINT_H
-
-#include "SOLID_types.h"
-
-class BP_Proxy;
-
-class BP_Link {
-public:
-	BP_Link() {}
-	explicit BP_Link(BP_Proxy *proxy) :
-		m_proxy(proxy)
-	{}
-
-	DT_Index  m_index;
-	DT_Count  m_count;
-	BP_Proxy *m_proxy;
-};
-
-typedef unsigned int Uint32;
-
-class BP_Endpoint {
-public:
-    enum { 
-		MINIMUM = 0x00000000, 
-		MAXIMUM = 0x80000000,	
-		TYPEBIT = 0x00000001
-	};
-
-    BP_Endpoint() {}
-    BP_Endpoint(DT_Scalar pos, Uint32 type, BP_Link *link) 
-	  :	m_link(link)
-	{
-		setPos(pos, type);
-	}
- 
-	DT_Scalar getPos()   const { return m_pos; }
-	DT_Index&   getIndex() const { return m_link->m_index; }
-	DT_Count&   getCount() const { return m_link->m_count; }
-	BP_Proxy *getProxy() const { return m_link->m_proxy; }
-	
-	DT_Index   getEndIndex()   const { return (m_link + 1)->m_index; }
-	
-	Uint32 getType() const 
-	{ 
-		return (m_bits & TYPEBIT) ? (~m_bits & MAXIMUM) : (m_bits & MAXIMUM);
-	}
-
-	void setPos(DT_Scalar pos, Uint32 type) 
-	{
-		m_pos = pos; 
-		if ((m_bits & MAXIMUM) == type) 
-		{
-			m_bits &= ~TYPEBIT;
-		}
-		else 
-		{
-			m_bits |= TYPEBIT;
-		}
-	}
-
-private:
-	union {
-		DT_Scalar    m_pos;
-		Uint32       m_bits;
-	};
-	BP_Link        *m_link;
-};
-
-inline bool operator<(const BP_Endpoint& a, const BP_Endpoint& b) 
-{
-    return a.getPos() < b.getPos(); 
-}
-
-#endif
-
-
-
-
-
-
-
-
-
-
diff --git a/extern/solid/src/broad/BP_EndpointList.cpp b/extern/solid/src/broad/BP_EndpointList.cpp
deleted file mode 100644
index aa094ffeb0a..00000000000
--- a/extern/solid/src/broad/BP_EndpointList.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include 
-#include 
-
-#include "BP_EndpointList.h"
-#include "BP_Scene.h"
-#include "BP_Proxy.h"
-#include "BP_ProxyList.h"
-
-DT_Index BP_EndpointList::stab(const BP_Endpoint& pos, BP_ProxyList& proxies) const 
-{
-	DT_Index result = std::upper_bound(begin(), end(), pos) - begin();
-	
-	if (result != 0) 
-	{
-		DT_Index i = result - 1;
-		DT_Count count = (*this)[i].getCount(); 
-		while (count) 
-		{
-			const BP_Endpoint& endpoint = (*this)[i];
-			if (endpoint.getType() == BP_Endpoint::MINIMUM &&
-				pos < (*this)[endpoint.getEndIndex()]) 
-			{
-				proxies.add(endpoint.getProxy());
-				--count;
-			}
-			assert(i != 0 || count == 0);
-			--i;
-		}											
-	}
-	return result;
-}
-
-DT_Scalar BP_EndpointList::nextLambda(DT_Index& index, 
-									  DT_Scalar source, 
-									  DT_Scalar delta) const
-{
-	if (delta != 0.0f) 
-	{
-		if (delta < 0.0f) 
-		{
-			if (index != 0) 
-			{
-				return ((*this)[--index].getPos() - source) / delta;
-			}
-		}
-		else 
-		{
-			if (index != size()) 
-			{
-				return ((*this)[index++].getPos() - source) / delta;
-			}
-		}
-	}
-	return FLT_MAX;
-}
-
-
-void BP_EndpointList::range(const BP_Endpoint& min, 
-							const BP_Endpoint& max,
-							DT_Index& first, DT_Index& last,
-							BP_ProxyList& proxies) const 
-{
-	first = stab(min, proxies);
-	last  = std::upper_bound(begin(), end(), max) - begin();
-	
-	DT_Index i;
-	for (i = first; i != last; ++i) 
-	{
-		const BP_Endpoint& endpoint = (*this)[i];
-		if (endpoint.getType() == BP_Endpoint::MINIMUM) 
-		{
-			proxies.add(endpoint.getProxy());
-		}
-	}
-}
-
-void BP_EndpointList::addInterval(const BP_Endpoint& min, 
-								  const BP_Endpoint& max,
-								  BP_ProxyList& proxies) 
-{
-	assert(invariant());
-	DT_Index first, last;
-	range(min, max, first, last, proxies);
-	insert(begin() + last, max);
-	insert(begin() + first, min);
-	++last; 
-	
-	(*this)[first].getCount() = first != 0 ? (*this)[first - 1].getCount() : 0;
-	(*this)[last].getCount() = (*this)[last - 1].getCount();
-	
-	
-	DT_Index i;
-	for (i = first; i != last; ++i) 
-	{
-		++(*this)[i].getCount();
-		(*this)[i].getIndex() = i;
-	} 
-	for (; i != size(); ++i) 
-	{
-		(*this)[i].getIndex() = i;
-	} 
-	
-	assert(invariant());
-}
-
-void BP_EndpointList::removeInterval(DT_Index first, DT_Index last,
-									 BP_ProxyList& proxies) 
-{ 
-	assert(invariant());
-	
-	BP_Endpoint min = (*this)[first];
-	BP_Endpoint max = (*this)[last]; 
-	
-	erase(begin() + last);
-	erase(begin() + first);
-	--last;
-	
-	DT_Index i;
-	for (i = first; i != last; ++i) 
-	{
-		--(*this)[i].getCount();
-		(*this)[i].getIndex() = i;
-	} 
-	for (; i != size(); ++i) 
-	{
-		(*this)[i].getIndex() = i;
-	} 
-	
-	range(min, max, first, last, proxies);
-	
-	assert(invariant());
-}
-
-void BP_EndpointList::move(DT_Index index, DT_Scalar pos, Uint32 type,  
-						   BP_Scene& scene, T_Overlap overlap)
-{
-	assert(invariant());
-	
-	BP_Endpoint endpoint = (*this)[index];
-    DT_Scalar delta = pos - endpoint.getPos();
-	
-    if (delta != DT_Scalar(0.0)) 
-	{
-		endpoint.setPos(pos, type);
-		if (delta < DT_Scalar(0.0)) 
-		{
-			while (index != 0 && endpoint < (*this)[index - 1]) 
-			{
-				(*this)[index] = (*this)[index - 1];
-				(*this)[index].getIndex() = index;
-				encounters((*this)[index], endpoint, scene, overlap);
-				--index;
-			}
-		}
-		else 
-		{
-			DT_Index last = size() - 1;
-			while (index != last && (*this)[index + 1] < endpoint) 
-			{
-				(*this)[index] = (*this)[index + 1];
-				(*this)[index].getIndex() = index;
-				encounters(endpoint, (*this)[index], scene, overlap);
-				++index;
-			}
-		}
-		(*this)[index] = endpoint;
-		(*this)[index].getIndex() = index;
-    }
-
-	assert(invariant());
-}
-
-void BP_EndpointList::encounters(const BP_Endpoint& a, const BP_Endpoint& b,
-								 BP_Scene& scene, T_Overlap overlap)
-{
-	assert(a.getProxy() != b.getProxy());
-	
-	if (a.getType() != b.getType()) 
-	{
-		if (a.getType() == BP_Endpoint::MAXIMUM) 
-		{
-			if (overlap(*a.getProxy(), *b.getProxy())) 
-			{
-				scene.callBeginOverlap(a.getProxy()->getObject(), 
-									   b.getProxy()->getObject());
-			}
-			++a.getCount();
-			++b.getCount();
-		}
-		else 
-		{
-			if (overlap(*a.getProxy(), *b.getProxy())) 
-			{
-				scene.callEndOverlap(a.getProxy()->getObject(), 
-									 b.getProxy()->getObject());
-			}
-			--a.getCount();
-			--b.getCount();
-		}
-	}
-	else 
-	{
-		if (a.getType() == BP_Endpoint::MAXIMUM) 
-		{
-			--a.getCount();
-			++b.getCount();
-		}
-		else 
-		{
-			++a.getCount();
-			--b.getCount();
-		}
-	}
-}
diff --git a/extern/solid/src/broad/BP_EndpointList.h b/extern/solid/src/broad/BP_EndpointList.h
deleted file mode 100644
index 6154991ed3d..00000000000
--- a/extern/solid/src/broad/BP_EndpointList.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_ENDPOINTLIST_H
-#define BP_ENDPOINTLIST_H
-
-//#define PARANOID
-
-#include 
-
-#include "BP_Endpoint.h"
-#include "BP_ProxyList.h"
-
-class BP_Scene;
-
-typedef bool (*T_Overlap)(const BP_Proxy& a, const BP_Proxy& b);
-
-class BP_EndpointList : public std::vector {
-public:
-	BP_EndpointList() {}
-	
-	DT_Index stab(const BP_Endpoint& pos, BP_ProxyList& proxies) const;
-	
-	DT_Index stab(DT_Scalar pos, BP_ProxyList& proxies) const
-	{
-		return stab(BP_Endpoint(pos, BP_Endpoint::MINIMUM, 0), proxies);
-	}
-	
-
-   void range(const BP_Endpoint& min, const BP_Endpoint& max, 
-			  DT_Index& first, DT_Index& last, BP_ProxyList& proxies) const;
-	
-	void range(DT_Scalar lb, DT_Scalar ub, DT_Index& first, DT_Index& last, BP_ProxyList& proxies) const 
-	{
-		range(BP_Endpoint(lb, BP_Endpoint::MINIMUM, 0), 
-			  BP_Endpoint(ub, BP_Endpoint::MAXIMUM, 0),
-			  first, last, proxies);
-	}
-	
-	void addInterval(const BP_Endpoint& min, const BP_Endpoint& max, BP_ProxyList& proxies);
-	void removeInterval(DT_Index first, DT_Index last, BP_ProxyList& proxies);
-
-	void move(DT_Index index, DT_Scalar pos, Uint32 type, BP_Scene& scene, T_Overlap overlap);	
-   
-   DT_Scalar nextLambda(DT_Index& index, DT_Scalar source, DT_Scalar target) const;
-	
-
-private:
-	void encounters(const BP_Endpoint& a, const BP_Endpoint& b,
-					    BP_Scene& scene, T_Overlap overlap);
-
-
-#ifdef PARANOID
-	bool invariant() const 
-	{
-		DT_Count count = 0;
-		DT_Index i;
-		for (i = 0; i != size(); ++i) 
-		{
-         const BP_Endpoint& endpoint = (*this)[i];
-
-			if (endpoint.getType() == BP_Endpoint::MINIMUM) 
-			{
-				++count;
-			}
-			else 
-			{
-				--count;
-			}
-			if (endpoint.getCount() != count)
-			{
-				return false;
-			}
-			if (endpoint.getIndex() != i) 
-			{
-				return false;
-			}
-		}
-		return true;
-	}
-#else
-	bool invariant() const { return true; }
-#endif
-
-};
-
-
-
-#endif
diff --git a/extern/solid/src/broad/BP_Proxy.cpp b/extern/solid/src/broad/BP_Proxy.cpp
deleted file mode 100644
index e8007df240d..00000000000
--- a/extern/solid/src/broad/BP_Proxy.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include 
-
-#include "BP_Proxy.h"
-#include "BP_Scene.h"
-
-BP_Proxy::BP_Proxy(void *object, 
-				   BP_Scene& scene) 
-  :	m_object(object),
-	m_scene(scene)
-{
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		new (&m_interval[i]) BP_Interval(this);
-	}
-}
-
-void BP_Proxy::add(const DT_Vector3 min,
-				   const DT_Vector3 max,
-				   BP_ProxyList& proxies) 
-{
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		m_scene.getList(i).addInterval(
-			BP_Endpoint(min[i], BP_Endpoint::MINIMUM, &m_interval[i].m_min), 
-			BP_Endpoint(max[i], BP_Endpoint::MAXIMUM, &m_interval[i].m_max), 
-			proxies);
-	}
-}
-
-void BP_Proxy::remove(BP_ProxyList& proxies) 
-{
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		m_scene.getList(i).removeInterval(
-			m_interval[i].m_min.m_index,
-			m_interval[i].m_max.m_index,
-			proxies);
-	}
-}
-
-DT_Scalar BP_Proxy::getMin(int i) const 
-{ 
-	return m_scene.getList(i)[m_interval[i].m_min.m_index].getPos(); 
-}
-
-DT_Scalar BP_Proxy::getMax(int i) const 
-{ 
-	return m_scene.getList(i)[m_interval[i].m_max.m_index].getPos(); 
-}
-
-bool overlapXY(const BP_Proxy& a, const BP_Proxy& b)
-{
-	return a.getMin(0) <= b.getMax(0) && b.getMin(0) <= a.getMax(0) && 
-		   a.getMin(1) <= b.getMax(1) && b.getMin(1) <= a.getMax(1);
-}
-
-bool overlapXZ(const BP_Proxy& a, const BP_Proxy& b)
-{
-	return a.getMin(0) <= b.getMax(0) && b.getMin(0) <= a.getMax(0) && 
-		   a.getMin(2) <= b.getMax(2) && b.getMin(2) <= a.getMax(2); 
-}
-
-bool overlapYZ(const BP_Proxy& a, const BP_Proxy& b)
-{
-	return a.getMin(1) <= b.getMax(1) && b.getMin(1) <= a.getMax(1) && 
-		   a.getMin(2) <= b.getMax(2) && b.getMin(2) <= a.getMax(2); 
-}
-
-void BP_Proxy::setBBox(const DT_Vector3 min, const DT_Vector3 max)
-{	
-	static T_Overlap overlap[3] = { overlapYZ, overlapXZ, overlapXY };
-
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		if (min[i] > getMax(i)) 
-		{
-			m_scene.getList(i).move(m_interval[i].m_max.m_index, max[i], 
-									BP_Endpoint::MAXIMUM, m_scene, overlap[i]);
-			m_scene.getList(i).move(m_interval[i].m_min.m_index, min[i], 
-									BP_Endpoint::MINIMUM, m_scene, overlap[i]);
-		}
-		else 
-		{
-			m_scene.getList(i).move(m_interval[i].m_min.m_index, min[i], 
-									BP_Endpoint::MINIMUM, m_scene, overlap[i]);
-			m_scene.getList(i).move(m_interval[i].m_max.m_index, max[i], 
-									BP_Endpoint::MAXIMUM, m_scene, overlap[i]);
-		}
-	}
-}
-
-
-
diff --git a/extern/solid/src/broad/BP_Proxy.h b/extern/solid/src/broad/BP_Proxy.h
deleted file mode 100644
index b4500ddca44..00000000000
--- a/extern/solid/src/broad/BP_Proxy.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_PROXY_H
-#define BP_PROXY_H
-
-#include "BP_Endpoint.h"
-#include "BP_ProxyList.h"
-
-class BP_Interval {
-public:
-	BP_Interval() {}
-	BP_Interval(BP_Proxy *proxy) :
-		m_min(proxy),
-		m_max(proxy) 
-	{}
-
-	BP_Link m_min;
-	BP_Link m_max;
-};
-
-class BP_Scene;
-
-class BP_Proxy {
-public:
-    BP_Proxy(void *object, BP_Scene& scene);
-
-	void add(const DT_Vector3 min,
-			 const DT_Vector3 max,
-			 BP_ProxyList& proxies);
-	
-    void remove(BP_ProxyList& proxies);
-	
-	void setBBox(const DT_Vector3 min, const DT_Vector3 max);
-    
-    void *getObject() { return m_object; }
-
-	DT_Scalar getMin(int i) const;
-	DT_Scalar getMax(int i) const;
-
-private:
-	BP_Interval  m_interval[3];
-    void        *m_object;
-	BP_Scene&    m_scene;
-};
-
-inline bool BP_overlap(const BP_Proxy *a, const BP_Proxy *b)
-{
-	return a->getMin(0) <= b->getMax(0) && b->getMin(0) <= a->getMax(0) && 
-		   a->getMin(1) <= b->getMax(1) && b->getMin(1) <= a->getMax(1) &&
-		   a->getMin(2) <= b->getMax(2) && b->getMin(2) <= a->getMax(2);
-}
-
-#endif
-
-
-
-
diff --git a/extern/solid/src/broad/BP_ProxyList.h b/extern/solid/src/broad/BP_ProxyList.h
deleted file mode 100644
index 2f449777d2d..00000000000
--- a/extern/solid/src/broad/BP_ProxyList.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_PROXYLIST_H
-#define BP_PROXYLIST_H
-
-#include 
-
-#include 
-#include 
-#include 
-
-class BP_Proxy;
-
-typedef std::pair BP_ProxyEntry; 
-
-inline bool operator<(const BP_ProxyEntry& a, const BP_ProxyEntry& b) 
-{
-	return a.first < b.first;
-}
-
-class BP_ProxyList : public std::vector {
-public:
-   BP_ProxyList(size_t n = 20) : std::vector(n) {}      
-
-	iterator add(BP_Proxy *proxy) 
-	{
-		BP_ProxyEntry entry = std::make_pair(proxy, (unsigned int)0);
-		iterator it = std::lower_bound(begin(), end(), entry);
-		if (it == end() || (*it).first != proxy) 
-		{
-			it = insert(it, entry);
-		}
-		++(*it).second;
-		return it;
-	}
-
-	void remove(BP_Proxy *proxy) 
-	{
-		BP_ProxyEntry entry = std::make_pair(proxy, (unsigned int)0);
-		iterator it = std::lower_bound(begin(), end(), entry);
-		if (it != end() && (*it).first == proxy && --(*it).second == 0) 
-		{
-			erase(it);	
-		}	
-	}
-};
-
-#endif
diff --git a/extern/solid/src/broad/BP_Scene.cpp b/extern/solid/src/broad/BP_Scene.cpp
deleted file mode 100644
index c0cd83ba311..00000000000
--- a/extern/solid/src/broad/BP_Scene.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "BP_Scene.h"
-#include "BP_Proxy.h"
-
-#include 
-
-BP_Proxy *BP_Scene::createProxy(void *object, 
-								const DT_Vector3 min,
-								const DT_Vector3 max)
-{
-	BP_Proxy *proxy = new BP_Proxy(object, *this);
-
-	proxy->add(min, max, m_proxies);
-	
-	BP_ProxyList::iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it)
-	{
-		if ((*it).second == 3)
-		{
-			callBeginOverlap(proxy->getObject(), (*it).first->getObject());
-		}
-	}
-
-	m_proxies.clear();
-
-	return proxy;
-}
-
-void BP_Scene::destroyProxy(BP_Proxy *proxy)
-{
-	proxy->remove(m_proxies);
-	
-	BP_ProxyList::iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it)
-	{
-		if ((*it).second == 3)
-		{
-			callEndOverlap(proxy->getObject(), (*it).first->getObject());
-		}
-	}
-	
-	m_proxies.clear();
-
-	delete proxy;
-}
-
-void *BP_Scene::rayCast(BP_RayCastCallback objectRayCast,
-						void *client_data,
-						const DT_Vector3 source, 
-						const DT_Vector3 target, 
-						DT_Scalar& lambda) const 
-{
-	void *client_object = 0;
-	
-	DT_Index index[3];
-	index[0] = m_endpointList[0].stab(source[0], m_proxies);
-	index[1] = m_endpointList[1].stab(source[1], m_proxies);
-	index[2] = m_endpointList[2].stab(source[2], m_proxies);
-
-	BP_ProxyList::iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it) 
-	{
-		if ((*it).second == 3 &&
-            (*objectRayCast)(client_data, (*it).first->getObject(), source, target, &lambda))
-		{
-			client_object = (*it).first->getObject();
-		}
-	}
-
-	DT_Vector3 delta;
-	delta[0] = target[0] - source[0];
-	delta[1] = target[1] - source[1];
-	delta[2] = target[2] - source[2];
-	
-	DT_Vector3 lambdas;
-	lambdas[0] = m_endpointList[0].nextLambda(index[0], source[0], delta[0]);
-	lambdas[1] = m_endpointList[1].nextLambda(index[1], source[1], delta[1]);
-	lambdas[2] = m_endpointList[2].nextLambda(index[2], source[2], delta[2]);
-	int closest = lambdas[0] < lambdas[1] ? (lambdas[0] < lambdas[2] ? 0 : 2) : (lambdas[1] < lambdas[2] ? 1 : 2);
-	
-	while (lambdas[closest] < lambda)
-	{
-		if (delta[closest] < 0.0f)
-		{
-			const BP_Endpoint& endpoint = m_endpointList[closest][index[closest]];
-
-			if (endpoint.getType() == BP_Endpoint::MAXIMUM) 
-			{
-				it = m_proxies.add(endpoint.getProxy());
-				if ((*it).second == 3 &&
-					(*objectRayCast)(client_data, (*it).first->getObject(), source, target, &lambda))
-				{
-					client_object = (*it).first->getObject();
-				}
-			}
-			else
-			{
-				m_proxies.remove(endpoint.getProxy());
-			}
-		}
-		else 
-		{
-			const BP_Endpoint& endpoint = m_endpointList[closest][index[closest] - 1];
-			
-			if (endpoint.getType() == BP_Endpoint::MINIMUM) 
-			{
-				it = m_proxies.add(endpoint.getProxy());
-				if ((*it).second == 3 &&
-					(*objectRayCast)(client_data, (*it).first->getObject(), source, target, &lambda))
-				{
-					client_object = (*it).first->getObject();
-				}
-			}
-			else
-			{
-				m_proxies.remove(endpoint.getProxy());
-			}
-		}
-
-		lambdas[closest] = m_endpointList[closest].nextLambda(index[closest], source[closest], delta[closest]);
-		closest = lambdas[0] < lambdas[1] ?	(lambdas[0] < lambdas[2] ? 0 : 2) : (lambdas[1] < lambdas[2] ? 1 : 2);
-	}
-
-	m_proxies.clear();
-
-	return client_object;
-}
-
-
diff --git a/extern/solid/src/broad/BP_Scene.h b/extern/solid/src/broad/BP_Scene.h
deleted file mode 100644
index ef55374c43b..00000000000
--- a/extern/solid/src/broad/BP_Scene.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_SCENE_H
-#define BP_SCENE_H
-
-#include 
-
-#include "BP_EndpointList.h"
-#include "BP_ProxyList.h"
-
-class BP_Proxy;
-
-class BP_Scene {
-public:
-    BP_Scene(void *client_data,
-			 BP_Callback beginOverlap,
-			 BP_Callback endOverlap) 
-      :	m_client_data(client_data),
-		m_beginOverlap(beginOverlap),
-		m_endOverlap(endOverlap),
-		m_proxies(20)
-	{}
-
-    ~BP_Scene() {}
-
-    BP_Proxy *createProxy(void *object, 
-						  const DT_Vector3 min,
-						  const DT_Vector3 max);
-
-    void destroyProxy(BP_Proxy *proxy);
-	
-	void *rayCast(BP_RayCastCallback objectRayCast,
-				  void *client_data,
-				  const DT_Vector3 source, 
-				  const DT_Vector3 target, 
-				  DT_Scalar& lambda) const;
-	
-  	void callBeginOverlap(void *object1, void *object2) 
-	{
-		(*m_beginOverlap)(m_client_data, object1, object2);
-	}
-	
-	void callEndOverlap(void *object1, void *object2) 
-	{
-		(*m_endOverlap)(m_client_data, object1, object2);
-	}
-	
-	BP_EndpointList& getList(int i) { return m_endpointList[i]; }
-
-private:
-	void                    *m_client_data;
-	BP_Callback              m_beginOverlap; 
-	BP_Callback              m_endOverlap; 
-    BP_EndpointList          m_endpointList[3];
-	mutable BP_ProxyList     m_proxies;
-};
-
-#endif
diff --git a/extern/solid/src/broad/Makefile b/extern/solid/src/broad/Makefile
deleted file mode 100644
index ce10e5f0bcf..00000000000
--- a/extern/solid/src/broad/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = solid_broad
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../../include -I$(NAN_QHULL)/include
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
-
diff --git a/extern/solid/src/complex/DT_BBoxTree.cpp b/extern/solid/src/complex/DT_BBoxTree.cpp
deleted file mode 100644
index 4f10f61f2e2..00000000000
--- a/extern/solid/src/complex/DT_BBoxTree.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_BBoxTree.h"
-
-inline DT_CBox getBBox(int first, int last, const DT_CBox *boxes, const DT_Index *indices) 
-{
-	assert(last - first >= 1);
-
-	DT_CBox bbox = boxes[indices[first]];
-	int i;
-	for (i = first; i < last; ++i) 
-	{
-		bbox = bbox.hull(boxes[indices[i]]);
-	}
-
-	return bbox;
-}
-
-DT_BBoxNode::DT_BBoxNode(int first, int last, int& node, DT_BBoxNode *free_nodes, const DT_CBox *boxes, DT_Index *indices, const DT_CBox& bbox)
-{
-	assert(last - first >= 2);
-	
-	int axis = bbox.longestAxis();
-	MT_Scalar abscissa = bbox.getCenter()[axis];
-	int i = first, mid = last;
-	while (i < mid) 
-	{
-		if (boxes[indices[i]].getCenter()[axis] < abscissa)
-		{
-			++i;
-		}
-		else
-		{
-			--mid;
-			std::swap(indices[i], indices[mid]);
-		}
-	}
-
-	if (mid == first || mid == last) 
-	{
-		mid = (first + last) / 2;
-	}
-	
-	m_lbox = getBBox(first, mid, boxes, indices);
-	m_rbox = getBBox(mid, last, boxes, indices);
-	m_flags = 0x0;
-
-	if (mid - first == 1)
-	{
-		m_flags |= LLEAF;
-		m_lchild = indices[first];
-	}
-	else 
-	{	
-		m_lchild = node++;
-		new(&free_nodes[m_lchild]) DT_BBoxNode(first, mid, node, free_nodes, boxes, indices, m_lbox);
-	}
-
-	if (last - mid == 1)
-	{
-		m_flags |= RLEAF;
-		m_rchild = indices[mid];
-	}
-	else 
-	{
-		m_rchild = node++;
-		new(&free_nodes[m_rchild]) DT_BBoxNode(mid, last, node, free_nodes, boxes, indices, m_rbox); 
-	}
-}
diff --git a/extern/solid/src/complex/DT_BBoxTree.h b/extern/solid/src/complex/DT_BBoxTree.h
deleted file mode 100644
index 3d9da6e34ba..00000000000
--- a/extern/solid/src/complex/DT_BBoxTree.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_BBOXTREE_H
-#define DT_BBOXTREE_H
-
-#include 
-#include 
-
-#include "DT_Convex.h"
-#include "DT_CBox.h"
-
-
-class DT_BBoxTree {
-public:
-    enum NodeType { INTERNAL = 0, LEAF = 1 };
-    
-    DT_BBoxTree() {}
-    DT_BBoxTree(const DT_CBox& cbox, DT_Index index, NodeType type) 
-      : m_cbox(cbox),
-        m_index(index),
-        m_type(type)
-    {}
-    
-    DT_CBox  m_cbox;
-    DT_Index m_index;
-    NodeType m_type;
-};
-
-
-
-class DT_BBoxNode {
-public:
-    DT_BBoxNode() {}    
-    DT_BBoxNode(int first, int last, int& node, DT_BBoxNode *free_nodes, const DT_CBox *boxes, DT_Index *indices, const DT_CBox& bbox);
-
-    void makeChildren(DT_BBoxTree& ltree, DT_BBoxTree& rtree) const;
-    void makeChildren(const DT_CBox& added, DT_BBoxTree& ltree, DT_BBoxTree& rtree) const;
-
-    DT_CBox hull() const { return m_lbox.hull(m_rbox); }  
-    
-    enum FlagType { LLEAF = 0x80, RLEAF = 0x40 };
-
-    DT_CBox              m_lbox;
-    DT_CBox              m_rbox;
-    DT_Index             m_lchild;
-    DT_Index             m_rchild;
-    unsigned char        m_flags;
-};
-
-inline void DT_BBoxNode::makeChildren(DT_BBoxTree& ltree, DT_BBoxTree& rtree) const
-{
-    new (<ree) DT_BBoxTree(m_lbox, m_lchild, (m_flags & LLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-    new (&rtree) DT_BBoxTree(m_rbox, m_rchild, (m_flags & RLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-
-}
-
-inline void DT_BBoxNode::makeChildren(const DT_CBox& added, DT_BBoxTree& ltree, DT_BBoxTree& rtree) const
-{ 
-    new (<ree) DT_BBoxTree(m_lbox + added, m_lchild, (m_flags & LLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-    new (&rtree) DT_BBoxTree(m_rbox + added, m_rchild, (m_flags & RLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-}
-
-
-template 
-class DT_RootData {
-public:
-    DT_RootData(const DT_BBoxNode *nodes, 
-                const Shape *leaves) 
-      : m_nodes(nodes),
-        m_leaves(leaves)
-    {}
-
-    const DT_BBoxNode   *m_nodes;
-    const Shape         *m_leaves;
-};
-
-template 
-class DT_ObjectData : public DT_RootData {
-public:
-    DT_ObjectData(const DT_BBoxNode *nodes, 
-                  const Shape1 *leaves, 
-                  const MT_Transform& xform, 
-                  Shape2 plus) 
-      : DT_RootData(nodes, leaves),
-        m_xform(xform),
-        m_inv_xform(xform.inverse()),   
-        m_plus(plus),
-        m_added(computeCBox(plus, m_inv_xform))
-    {}
-
-    const MT_Transform&  m_xform;
-    MT_Transform         m_inv_xform;
-    Shape2               m_plus;
-    DT_CBox              m_added;
-};
-
-template 
-class DT_Pack {
-public:
-    DT_Pack(const DT_ObjectData& a, const DT_Convex& b)
-      : m_a(a),
-        m_b(b),
-        m_b_cbox(b.bbox(m_a.m_inv_xform))
-    {}
-    
-    DT_ObjectData  m_a;
-    const DT_Convex&               m_b;
-    DT_CBox                        m_b_cbox;
-};
-
-template 
-class DT_HybridPack : public DT_Pack {
-public:
-    DT_HybridPack(const DT_ObjectData& a, const DT_Convex& b, MT_Scalar margin)
-      : DT_Pack(a, b),
-        m_margin(margin)
-    {
-        this->m_b_cbox += computeCBox(margin, this->m_a.m_inv_xform);
-    }
-    
-    MT_Scalar m_margin;
-};
-
-template 
-class DT_DuoPack {
-public:
-    DT_DuoPack(const DT_ObjectData& a, const DT_ObjectData& b) 
-      : m_a(a),
-        m_b(b)
-    {
-        m_b2a = a.m_inv_xform * b.m_xform;
-        m_a2b = b.m_inv_xform * a.m_xform;
-        m_abs_b2a = m_b2a.getBasis().absolute();
-        m_abs_a2b = m_a2b.getBasis().absolute();    
-    }
-    
-    DT_ObjectData  m_a, m_b;
-    MT_Transform                   m_b2a, m_a2b;
-    MT_Matrix3x3                   m_abs_b2a, m_abs_a2b;
-};
-
-
-template 
-inline void refit(DT_BBoxNode& node, const DT_RootData& rd)
-{
-    node.m_lbox = (node.m_flags & DT_BBoxNode::LLEAF) ? 
-                  computeCBox(rd.m_leaves[node.m_lchild]) : 
-                  rd.m_nodes[node.m_lchild].hull(); 
-    node.m_rbox = (node.m_flags & DT_BBoxNode::RLEAF) ? 
-                  computeCBox(rd.m_leaves[node.m_rchild]) : 
-                  rd.m_nodes[node.m_rchild].hull(); 
-}
-
-
-template 
-bool ray_cast(const DT_BBoxTree& a, const DT_RootData& rd,
-              const MT_Point3& source, const MT_Point3& target, 
-              MT_Scalar& lambda, MT_Vector3& normal) 
-{
-    if (!a.m_cbox.overlapsLineSegment(source, source.lerp(target, lambda))) 
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    { 
-        return ray_cast(rd, a.m_index, source, target, lambda, normal); 
-    }
-    else 
-    {
-        DT_BBoxTree ltree, rtree;
-        rd.m_nodes[a.m_index].makeChildren(ltree, rtree);
-        
-        bool lresult = ray_cast(ltree, rd, source, target, lambda, normal);
-        bool rresult = ray_cast(rtree, rd, source, target, lambda, normal);
-        return lresult || rresult;
-    }
-}
-
-
-#ifdef STATISTICS
-int num_box_tests = 0;
-#endif
-
-template 
-inline bool intersect(const DT_CBox& a, const DT_CBox& b, const DT_DuoPack& pack)
-{
-#ifdef STATISTICS
-    ++num_box_tests;
-#endif
-
-    
-    MT_Vector3 abs_pos_b2a = (pack.m_b2a(b.getCenter()) - a.getCenter()).absolute();
-    MT_Vector3 abs_pos_a2b = (pack.m_a2b(a.getCenter()) - b.getCenter()).absolute();
-    return  (a.getExtent()[0] + pack.m_abs_b2a[0].dot(b.getExtent()) >=  abs_pos_b2a[0]) && 
-            (a.getExtent()[1] + pack.m_abs_b2a[1].dot(b.getExtent()) >=  abs_pos_b2a[1]) && 
-            (a.getExtent()[2] + pack.m_abs_b2a[2].dot(b.getExtent()) >=  abs_pos_b2a[2]) && 
-            (b.getExtent()[0] + pack.m_abs_a2b[0].dot(a.getExtent()) >=  abs_pos_a2b[0]) && 
-            (b.getExtent()[1] + pack.m_abs_a2b[1].dot(a.getExtent()) >=  abs_pos_a2b[1]) &&
-            (b.getExtent()[2] + pack.m_abs_a2b[2].dot(a.getExtent()) >=  abs_pos_a2b[2]);
-}
-
-
-
-
-template 
-bool intersect(const DT_BBoxTree& a, const DT_Pack& pack, MT_Vector3& v)
-{ 
-    if (!a.m_cbox.overlaps(pack.m_b_cbox)) 
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        return intersect(pack, a.m_index, v);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return intersect(a_ltree, pack, v) || intersect(a_rtree, pack, v);
-    }
-}
-
-template 
-bool intersect(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack, MT_Vector3& v)
-{ 
-    if (!intersect(a.m_cbox, b.m_cbox, pack)) 
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        return intersect(pack, a.m_index, b.m_index, v);
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-
-        return intersect(a, b_ltree, pack, v) || intersect(a, b_rtree, pack, v);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return intersect(a_ltree, b, pack, v) || intersect(a_rtree, b, pack, v);
-    }
-}
-
-template 
-bool common_point(const DT_BBoxTree& a, const DT_Pack& pack,  
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{ 
-    if (!a.m_cbox.overlaps(pack.m_b_cbox))
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        return common_point(pack, a.m_index, v, pa, pb);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return common_point(a_ltree, pack, v, pa, pb) ||
-               common_point(a_rtree, pack, v, pa ,pb);
-    }
-}
-
-template 
-bool common_point(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack,  
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{ 
-    if (!intersect(a.m_cbox, b.m_cbox, pack))
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        return common_point(pack, a.m_index, b.m_index, v, pa, pb);
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-        return common_point(a, b_ltree, pack, v, pa, pb) ||
-               common_point(a, b_rtree, pack, v, pa, pb);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return common_point(a_ltree, b, pack, v, pa, pb) ||
-               common_point(a_rtree, b, pack, v, pa ,pb);
-    }
-}
-
-
-template 
-bool penetration_depth(const DT_BBoxTree& a, const DT_HybridPack& pack, 
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb, MT_Scalar& max_pen_len) 
-{ 
-    if (!a.m_cbox.overlaps(pack.m_b_cbox))
-    {
-        return false;
-    }
-    
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        if (penetration_depth(pack, a.m_index, v, pa, pb))
-        {
-            max_pen_len = pa.distance2(pb);
-            return true;
-        }
-        else 
-        {
-            return false;
-        }
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        if (penetration_depth(a_ltree, pack, v, pa, pb, max_pen_len)) 
-        {
-            MT_Vector3 rv;
-            MT_Point3 rpa, rpb;
-            MT_Scalar rmax_pen_len;
-            if (penetration_depth(a_rtree, pack, rv, rpa, rpb, rmax_pen_len) &&
-                (max_pen_len < rmax_pen_len))
-            {
-                max_pen_len = rmax_pen_len;
-                v = rv;
-                pa = rpa;
-                pb = rpb;
-            }
-            return true;
-        }
-        else 
-        {
-            return penetration_depth(a_rtree, pack, v, pa, pb, max_pen_len);
-        }
-    }
-}
-
-template 
-bool penetration_depth(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack, 
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb, MT_Scalar& max_pen_len) 
-{ 
-    if (!intersect(a.m_cbox, b.m_cbox, pack))
-    {
-        return false;
-    }
-  
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        if (penetration_depth(pack, a.m_index, b.m_index, v, pa, pb))
-        {
-            max_pen_len = pa.distance2(pb);
-            return true;
-        }
-        else 
-        {
-            return false;
-        }
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-        if (penetration_depth(a, b_ltree, pack, v, pa, pb, max_pen_len)) 
-        {
-            MT_Point3 rpa, rpb;
-            MT_Scalar rmax_pen_len;
-            if (penetration_depth(a, b_rtree, pack, v, rpa, rpb, rmax_pen_len) &&
-                (max_pen_len < rmax_pen_len))
-            {
-                max_pen_len = rmax_pen_len;
-                pa = rpa;
-                pb = rpb;
-            }
-            return true;
-        }
-        else
-        {
-            return penetration_depth(a, b_rtree, pack, v, pa, pb, max_pen_len);
-        }
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        if (penetration_depth(a_ltree, b, pack, v, pa, pb, max_pen_len)) 
-        {
-            MT_Point3 rpa, rpb;
-            MT_Scalar rmax_pen_len;
-            if (penetration_depth(a_rtree, b, pack, v, rpa, rpb, rmax_pen_len) &&
-                (max_pen_len < rmax_pen_len))
-            {
-                max_pen_len = rmax_pen_len;
-                pa = rpa;
-                pb = rpb;
-            }
-            return true;
-        }
-        else 
-        {
-            return penetration_depth(a_rtree, b, pack, v, pa, pb, max_pen_len);
-        }
-    }
-}
-
-
-// Returns a lower bound for the distance for quick rejection in closest_points
-inline MT_Scalar distance2(const DT_CBox& a, const MT_Transform& a2w,
-                           const DT_CBox& b, const MT_Transform& b2w)
-{
-    MT_Vector3 v = b2w(b.getCenter()) - a2w(a.getCenter());
-    MT_Scalar dist2 = v.length2();
-    if (dist2 > MT_Scalar(0.0))
-    {
-        MT_Vector3 w = b2w(b.support(-v * b2w.getBasis())) - a2w(a.support(v * a2w.getBasis()));
-        MT_Scalar delta = v.dot(w);
-        return delta > MT_Scalar(0.0) ? delta * delta / dist2 : MT_Scalar(0.0);
-    }
-    return MT_Scalar(0.0);
-}
-
-
-template 
-MT_Scalar closest_points(const DT_BBoxTree& a, const DT_Pack& pack, 
-                         MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{ 
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        return closest_points(pack, a.m_index, max_dist2, pa, pb);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        MT_Scalar ldist2 = distance2(a_ltree.m_cbox, pack.m_a.m_xform, pack.m_b_cbox, pack.m_a.m_xform);
-        MT_Scalar rdist2 = distance2(a_rtree.m_cbox, pack.m_a.m_xform, pack.m_b_cbox, pack.m_a.m_xform);
-        if (ldist2 < rdist2) 
-        {
-            MT_Scalar dist2 = ldist2 < max_dist2 ? closest_points(a_ltree, pack, max_dist2, pa, pb) : MT_INFINITY;
-            GEN_set_min(max_dist2, dist2);
-            return rdist2 < max_dist2 ? GEN_min(dist2, closest_points(a_rtree, pack, max_dist2, pa, pb)) : dist2;
-        }
-        else
-        {
-            MT_Scalar dist2 = rdist2 < max_dist2 ? closest_points(a_rtree, pack, max_dist2, pa, pb) : MT_INFINITY;
-            GEN_set_min(max_dist2, dist2);  
-            return ldist2 < max_dist2 ? GEN_min(dist2, closest_points(a_ltree, pack, max_dist2, pa, pb)) : dist2;       
-        }
-    }
-}
-
-    
-template 
-MT_Scalar closest_points(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack, 
-                         MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{   
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        return closest_points(pack, a.m_index, b.m_index, max_dist2, pa, pb);
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-        MT_Scalar ldist2 = distance2(a.m_cbox, pack.m_a.m_xform, b_ltree.m_cbox, pack.m_b.m_xform);
-        MT_Scalar rdist2 = distance2(a.m_cbox, pack.m_a.m_xform, b_rtree.m_cbox, pack.m_b.m_xform);
-        if (ldist2 < rdist2)
-        {
-            MT_Scalar dist2 = ldist2 < max_dist2 ? closest_points(a, b_ltree, pack, max_dist2, pa, pb): MT_INFINITY;;
-            GEN_set_min(max_dist2, dist2);
-            return rdist2 < max_dist2 ? GEN_min(dist2, closest_points(a, b_rtree, pack, max_dist2, pa, pb)) : dist2;        
-        }
-        else
-        {
-            MT_Scalar dist2 =  rdist2 < max_dist2 ? closest_points(a, b_rtree, pack, max_dist2, pa, pb) : MT_INFINITY;;
-            GEN_set_min(max_dist2, dist2);
-            return ldist2 < max_dist2 ? GEN_min(dist2, closest_points(a, b_ltree, pack, max_dist2, pa, pb)) : dist2;
-        }
-    }
-    else
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        MT_Scalar ldist2 = distance2(a_ltree.m_cbox, pack.m_a.m_xform, b.m_cbox, pack.m_b.m_xform);
-        MT_Scalar rdist2 = distance2(a_rtree.m_cbox, pack.m_a.m_xform, b.m_cbox, pack.m_b.m_xform);
-        if (ldist2 < rdist2) 
-        {
-            MT_Scalar dist2 = ldist2 < max_dist2 ? closest_points(a_ltree, b, pack, max_dist2, pa, pb) : MT_INFINITY;;
-            GEN_set_min(max_dist2, dist2);
-            return rdist2 < max_dist2 ? GEN_min(dist2,closest_points(a_rtree, b, pack, max_dist2, pa, pb)) : dist2;
-        }
-        else
-        {
-            MT_Scalar dist2 = rdist2 < max_dist2 ? closest_points(a_rtree, b, pack, max_dist2, pa, pb) : MT_INFINITY;
-            GEN_set_min(max_dist2, dist2);
-            return ldist2 < max_dist2 ? GEN_min(dist2, closest_points(a_ltree, b, pack, max_dist2, pa, pb)) : dist2;
-        }
-    }
-}
-
-#endif
-
diff --git a/extern/solid/src/complex/DT_CBox.h b/extern/solid/src/complex/DT_CBox.h
deleted file mode 100644
index 7fc7c5df4db..00000000000
--- a/extern/solid/src/complex/DT_CBox.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CBOX_H
-#define DT_CBOX_H
-
-#include "MT_BBox.h"
-
-struct DT_CBox {
-    DT_CBox() {}
-    DT_CBox(const MT_Point3& center, const MT_Vector3& extent) 
-      : m_center(center),
-        m_extent(extent)
-    {}
-
-    explicit DT_CBox(const MT_BBox& bbox) { set(bbox); }
-
-    const MT_Point3& getCenter() const { return m_center; }
-    const MT_Vector3& getExtent() const { return m_extent; }
-
-    void set(const MT_BBox& bbox)
-    {
-        m_center = bbox.getCenter();
-        m_extent = bbox.getExtent();
-    }
- 
-    MT_BBox get() const
-    {
-        return MT_BBox(m_center - m_extent, m_center + m_extent);
-    }
-
-    MT_Scalar size() const  
-    {
-        return GEN_max(GEN_max(m_extent[0], m_extent[1]), m_extent[2]);
-    }
-
-
-    DT_CBox& operator+=(const DT_CBox& box)
-    {
-        m_center += box.getCenter();
-        m_extent += box.getExtent();
-        return *this;
-    }
-    
-    int longestAxis() const { return m_extent.closestAxis(); }
-        
-    DT_CBox hull(const DT_CBox& b) const 
-    {
-        return DT_CBox(this->get().hull(b.get()));
-    }
-
-    bool overlaps(const DT_CBox& b) const 
-    {
-        return MT_abs(m_center[0] - b.m_center[0]) <= m_extent[0] + b.m_extent[0] &&
-               MT_abs(m_center[1] - b.m_center[1]) <= m_extent[1] + b.m_extent[1] &&
-               MT_abs(m_center[2] - b.m_center[2]) <= m_extent[2] + b.m_extent[2];
-    }
-    
-    bool overlapsLineSegment(const MT_Point3& p, const MT_Point3& q) const 
-    {
-        MT_Vector3 r = q - p;   
-        MT_Vector3 r_abs = r.absolute();
-        
-        if (!overlaps(DT_CBox(p + r * MT_Scalar(0.5), r_abs * MT_Scalar(0.5))))
-        {
-            return false;
-        }
-        
-        MT_Vector3 s = p - m_center;
-
-        if (MT_abs(r[2] * s[1] - r[1] * s[2]) > r_abs[2] * m_extent[1] + r_abs[1] * m_extent[2])
-        {
-            return false;
-        }
-                    
-        if (MT_abs(r[0] * s[2] - r[2] * s[0]) > r_abs[0] * m_extent[2] + r_abs[2] * m_extent[0])
-        {
-            return false;
-        }
-                    
-        if (MT_abs(r[1] * s[0] - r[0] * s[1]) > r_abs[1] * m_extent[0] + r_abs[0] * m_extent[1])
-        {
-            return false;
-        }
-            
-        return true;
-    }
-    
-    MT_Point3 support(const MT_Vector3& v) const 
-    {
-        return m_center + MT_Vector3(v[0] < MT_Scalar(0.0) ? -m_extent[0] : m_extent[0],
-                                     v[1] < MT_Scalar(0.0) ? -m_extent[1] : m_extent[1],
-                                     v[2] < MT_Scalar(0.0) ? -m_extent[2] : m_extent[2]); 
-    
-    }
-
-private:
-    MT_Point3  m_center;
-    MT_Vector3 m_extent;
-};
-
-inline DT_CBox operator+(const DT_CBox& b1, const DT_CBox& b2) 
-{
-    return DT_CBox(b1.getCenter() + b2.getCenter(), 
-                   b1.getExtent() + b2.getExtent());
-}
-
-inline DT_CBox operator-(const DT_CBox& b1, const DT_CBox& b2) 
-{
-    return DT_CBox(b1.getCenter() - b2.getCenter(), 
-                   b1.getExtent() + b2.getExtent());
-}
-
-#endif
diff --git a/extern/solid/src/complex/DT_Complex.cpp b/extern/solid/src/complex/DT_Complex.cpp
deleted file mode 100644
index 023383a8427..00000000000
--- a/extern/solid/src/complex/DT_Complex.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include 
-#include 
-
-#include "DT_Complex.h"
-#include "DT_Minkowski.h"
-#include "DT_Sphere.h"
-#include "DT_Transform.h"
-
-DT_Complex::DT_Complex(const DT_VertexBase *base) 
-  : m_base(base),
-    m_count(0),
-    m_leaves(0),
-	m_nodes(0)
-{ 
-	assert(base);
-	base->addComplex(this);
-}
-
-
-DT_Complex::~DT_Complex()
-{
-    DT_Index i;
-    for (i = 0; i != m_count; ++i) 
-    {
-        delete m_leaves[i];
-    }
-    delete [] m_leaves;
-    delete [] m_nodes;
-    
-    m_base->removeComplex(this);
-    if (m_base->isOwner()) 
-    {
-        delete m_base;
-    }
-}
-
-void DT_Complex::finish(DT_Count n, const DT_Convex *p[]) 
-{
-	m_count = n;
-
-   
-    assert(n >= 1);
-
-    m_leaves = new const DT_Convex *[n];
-    assert(m_leaves);
-
-    DT_CBox *boxes = new DT_CBox[n];
-    DT_Index *indices = new DT_Index[n];
-    assert(boxes);
-       
-    DT_Index i;
-    for (i = 0; i != n; ++i) 
-    {
-        m_leaves[i] = p[i];
-        boxes[i].set(p[i]->bbox());
-        indices[i] = i;
-    }
-
-    m_cbox = boxes[0];
-    for (i = 1; i != n; ++i) 
-    {
-        m_cbox = m_cbox.hull(boxes[i]);
-    }
-
-    if (n == 1)
-    {
-        m_nodes = 0;
-        m_type = DT_BBoxTree::LEAF;
-    }
-    else 
-    {
-        m_nodes = new DT_BBoxNode[n - 1];
-        assert(m_nodes);
-    
-        int num_nodes = 0;
-        new(&m_nodes[num_nodes++]) DT_BBoxNode(0, n, num_nodes, m_nodes, boxes, indices, m_cbox);
-
-        assert(num_nodes == n - 1);
-        
-        m_type = DT_BBoxTree::INTERNAL;
-    }
-
-    delete [] boxes;
-}
-
-
-MT_BBox DT_Complex::bbox(const MT_Transform& t, MT_Scalar margin) const 
-{
-    MT_Matrix3x3 abs_b = t.getBasis().absolute();  
-    MT_Point3 center = t(m_cbox.getCenter());
-    MT_Vector3 extent(margin + abs_b[0].dot(m_cbox.getExtent()),
-                      margin + abs_b[1].dot(m_cbox.getExtent()),
-                      margin + abs_b[2].dot(m_cbox.getExtent()));
-    
-    return MT_BBox(center - extent, center + extent);
-}
-
-inline DT_CBox computeCBox(const DT_Convex *p)
-{
-    return DT_CBox(p->bbox()); 
-}
-
-inline DT_CBox computeCBox(MT_Scalar margin, const MT_Transform& xform) 
-{
-    const MT_Matrix3x3& basis = xform.getBasis();
-    return DT_CBox(MT_Point3(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)), 
-                   MT_Vector3(basis[0].length() * margin, 
-                              basis[1].length() * margin, 
-                              basis[2].length() * margin));
-} 
-
-void DT_Complex::refit()
-{
-    DT_RootData rd(m_nodes, m_leaves);
-    DT_Index i = m_count - 1;
-    while (i--)
-    {
-        ::refit(m_nodes[i], rd);
-    }
-    m_cbox = m_type == DT_BBoxTree::LEAF ? computeCBox(m_leaves[0]) : m_nodes[0].hull();
-}
-
-inline bool ray_cast(const DT_RootData& rd, DT_Index index, const MT_Point3& source, const MT_Point3& target, 
-                     MT_Scalar& lambda, MT_Vector3& normal)
-{
-    return rd.m_leaves[index]->ray_cast(source, target, lambda, normal);
-}
-
-bool DT_Complex::ray_cast(const MT_Point3& source, const MT_Point3& target,
-                          MT_Scalar& lambda, MT_Vector3& normal) const 
-{
-    DT_RootData rd(m_nodes, m_leaves);
-
-    return ::ray_cast(DT_BBoxTree(m_cbox, 0, m_type), rd, source, target, lambda, normal);
-}
-
-inline bool intersect(const DT_Pack& pack, DT_Index a_index, MT_Vector3& v) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    return ::intersect((a_margin > MT_Scalar(0.0) ? 
-                        static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) :  
-                        static_cast(ta)), 
-                       pack.m_b, v); 
-}
-
-bool intersect(const DT_Complex& a,  const MT_Transform& a2w,  MT_Scalar a_margin, 
-               const DT_Convex& b, MT_Vector3& v) 
-{
-    DT_Pack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b);
-
-    return intersect(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, v);
-}
-
-inline bool intersect(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Vector3& v) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    MT_Scalar b_margin = pack.m_b.m_plus;
-    return ::intersect((a_margin > MT_Scalar(0.0) ?
-                        static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : 
-                        static_cast(ta)), 
-                       (b_margin > MT_Scalar(0.0) ? 
-                        static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : 
-                        static_cast(tb)), 
-                       v);   
-}
-
-bool intersect(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-               const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, MT_Vector3& v) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                                                  DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-
-    return intersect(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                     DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type), pack, v);
-}
-
-inline bool common_point(const DT_Pack& pack, DT_Index a_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    return ::common_point((a_margin > MT_Scalar(0.0) ? 
-                           static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) :
-                           static_cast(ta)), 
-                          pack.m_b, v, pa, pb); 
-}
-    
-bool common_point(const DT_Complex& a,  const MT_Transform& a2w,  MT_Scalar a_margin, 
-                  const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-     DT_Pack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b);
-
-    return common_point(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, v, pb, pa);
-}
-
-inline bool common_point(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    MT_Scalar b_margin = pack.m_b.m_plus;
-    return ::common_point((a_margin > MT_Scalar(0.0) ? 
-                           static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : 
-                           static_cast(ta)), 
-                          (b_margin > MT_Scalar(0.0) ? 
-                           static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : 
-                           static_cast(tb)), 
-                          v, pa, pb);    
-}
-    
-bool common_point(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                  const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, 
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                                                  DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-    return common_point(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                        DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type),  pack, v, pa, pb);
-}
-
-inline bool penetration_depth(const DT_HybridPack& pack, DT_Index a_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    return ::hybrid_penetration_depth(ta, pack.m_a.m_plus, pack.m_b, pack.m_margin, v, pa, pb); 
-}
-
-bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-                       const DT_Convex& b, MT_Scalar b_margin, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_HybridPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b, b_margin);
-     
-    MT_Scalar  max_pen_len = MT_Scalar(0.0);
-    return penetration_depth(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, v, pa, pb, max_pen_len);
-}
-
-inline bool penetration_depth(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    return ::hybrid_penetration_depth(ta, pack.m_a.m_plus, tb, pack.m_a.m_plus, v, pa, pb);  
-}
-
-bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                       const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, 
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                                                  DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-    MT_Scalar  max_pen_len = MT_Scalar(0.0);
-    return penetration_depth(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                             DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type), pack, v, pa, pb, max_pen_len);
-}
-
-
-
-inline MT_Scalar closest_points(const DT_Pack& pack, DT_Index a_index, MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    return ::closest_points((a_margin > MT_Scalar(0.0) ? 
-                             static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) :  
-                             static_cast(ta)), 
-                            pack.m_b, max_dist2, pa, pb); 
-}
-
-MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                         const DT_Convex& b, MT_Point3& pa, MT_Point3& pb)
-{
-    DT_Pack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b);
-
-    return closest_points(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, MT_INFINITY, pa, pb); 
-}
-
-inline MT_Scalar closest_points(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    MT_Scalar b_margin = pack.m_b.m_plus;
-    return ::closest_points((a_margin > MT_Scalar(0.0) ? 
-                             static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : 
-                             static_cast(ta)), 
-                            (b_margin > MT_Scalar(0.0) ? 
-                             static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : 
-                             static_cast(tb)), max_dist2, pa, pb);     
-}
-
-MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                         const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, 
-                         MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                               DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-    return closest_points(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                          DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type), pack, MT_INFINITY, pa, pb);
-}
-
-
diff --git a/extern/solid/src/complex/DT_Complex.h b/extern/solid/src/complex/DT_Complex.h
deleted file mode 100644
index ae08a05d4c9..00000000000
--- a/extern/solid/src/complex/DT_Complex.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_COMPLEX_H
-#define DT_COMPLEX_H
-
-#include 
-
-#include "MT_Transform.h"
-#include "DT_VertexBase.h"
-
-#include "DT_Shape.h"
-#include "DT_CBox.h"
-#include "DT_BBoxTree.h"
-
-class DT_Convex;
-
-class DT_Complex : public DT_Shape  {
-public:
-	DT_Complex(const DT_VertexBase *base);
-	virtual ~DT_Complex();
-	
-	void finish(DT_Count n, const DT_Convex *p[]);
-    
-	virtual DT_ShapeType getType() const { return COMPLEX; }
-
-    virtual MT_BBox bbox(const MT_Transform& t, MT_Scalar margin) const;
-
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, 
-						  MT_Scalar& lambda, MT_Vector3& normal) const; 
-
-	void refit();
-	
-
-    friend bool intersect(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                  const DT_Convex& b, MT_Vector3& v);
-    
-    friend bool intersect(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                  const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                          MT_Vector3& v);
-   
-    friend bool common_point(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                     const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-    
-    friend bool common_point(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                     const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                             MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-    
-    friend bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-								  const DT_Convex& b, MT_Scalar b_margin, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-    
-    friend bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-								  const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-								  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-    friend MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                            const DT_Convex& b, MT_Point3& pa, MT_Point3& pb);
-    
-    friend MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                            const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									MT_Point3& pa, MT_Point3& pb);
-
-	const DT_VertexBase   *m_base;
-	DT_Count               m_count;
-	const DT_Convex      **m_leaves;
-	DT_BBoxNode           *m_nodes;
-	DT_CBox                m_cbox;
-	DT_BBoxTree::NodeType  m_type;
-};
-
-#endif
-
-
-
diff --git a/extern/solid/src/complex/Makefile b/extern/solid/src/complex/Makefile
deleted file mode 100644
index e8df4df51a3..00000000000
--- a/extern/solid/src/complex/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = solid_complex
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../../include -I$(NAN_QHULL)/include
-CPPFLAGS += -I../convex
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
-
diff --git a/extern/solid/src/convex/DT_Accuracy.cpp b/extern/solid/src/convex/DT_Accuracy.cpp
deleted file mode 100644
index 113275b0dbd..00000000000
--- a/extern/solid/src/convex/DT_Accuracy.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Accuracy.h"
-
-static const MT_Scalar rel_error = MT_Scalar(1.0e-3);
-
-MT_Scalar DT_Accuracy::rel_error2 = rel_error * rel_error;
-MT_Scalar DT_Accuracy::depth_tolerance = MT_Scalar(1.0) + MT_Scalar(2.0) * rel_error; 
-MT_Scalar DT_Accuracy::tol_error = MT_EPSILON;
diff --git a/extern/solid/src/convex/DT_Accuracy.h b/extern/solid/src/convex/DT_Accuracy.h
deleted file mode 100644
index 9759a6fd4c5..00000000000
--- a/extern/solid/src/convex/DT_Accuracy.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ACCURACY_H
-#define DT_ACCURACY_H
-
-#include "MT_Scalar.h"
-
-class DT_Accuracy {
-public:
-	static MT_Scalar rel_error2; // squared relative error in the computed distance
-	static MT_Scalar depth_tolerance; // terminate EPA if upper_bound <= depth_tolerance * dist2
-	static MT_Scalar tol_error; // error tolerance if the distance is almost zero
-	
-	static void setAccuracy(MT_Scalar rel_error) 
-	{ 
-		rel_error2 = rel_error * rel_error;
-		depth_tolerance = MT_Scalar(1.0) + MT_Scalar(2.0) * rel_error;
-	}	
-   
-	static void setTolerance(MT_Scalar epsilon) 
-	{ 
-		tol_error = epsilon;
-	}
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Array.h b/extern/solid/src/convex/DT_Array.h
deleted file mode 100644
index 1694f884e53..00000000000
--- a/extern/solid/src/convex/DT_Array.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ARRAY_H
-#define DT_ARRAY_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-template 
-class DT_Array {
-public:
-	DT_Array() 
-      :	m_count(0), 
-		m_data(0) 
-	{}
-
-	explicit DT_Array(Size count)
-	  :	m_count(count),
-		m_data(new Data[count]) 
-	{
-		assert(m_data);
-	}
-	
-	DT_Array(Size count, const Data *data) 
-	  :	m_count(count),
-		m_data(new Data[count]) 
-	{
-		assert(m_data);		
-		std::copy(&data[0], &data[count], m_data);
-	}
-	
-	~DT_Array() 
-	{ 
-		delete [] m_data; 
-	}
-	
-	const Data& operator[](int i) const { return m_data[i]; }
-	Data&       operator[](int i)       { return m_data[i]; }
-
-	Size size() const { return m_count; }
-	
-private:
-	DT_Array(const DT_Array&);
-	DT_Array& operator=(const DT_Array&);
-
-	Size  m_count;
-	Data *m_data;
-};
-  
-#endif
-
diff --git a/extern/solid/src/convex/DT_Box.cpp b/extern/solid/src/convex/DT_Box.cpp
deleted file mode 100644
index 0b46f566fe8..00000000000
--- a/extern/solid/src/convex/DT_Box.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Box.h"
-
-MT_Scalar DT_Box::supportH(const MT_Vector3& v) const 
-{
-    return v.absolute().dot(m_extent);
-}
-
-MT_Point3 DT_Box::support(const MT_Vector3& v) const 
-{
-    return MT_Point3(v[0] < MT_Scalar(0.0) ? -m_extent[0] : m_extent[0],
-                     v[1] < MT_Scalar(0.0) ? -m_extent[1] : m_extent[1],
-                     v[2] < MT_Scalar(0.0) ? -m_extent[2] : m_extent[2]); 
-    
-}
-
-
-bool DT_Box::ray_cast(const MT_Point3& source, const MT_Point3& target,
-					  MT_Scalar& param, MT_Vector3& normal) const 
-{
-	T_Outcode source_bits = outcode(source);
-	T_Outcode target_bits = outcode(target);
-
-	if ((source_bits & target_bits) == 0x0)
-		// None of the side planes separate the ray from the box.
-	{
-		MT_Scalar lambda_enter = MT_Scalar(0.0);
-		MT_Scalar lambda_exit  = param;
-		MT_Vector3 r = target - source;
-		T_Outcode normal_bit = 0x0; // Indicates the axis that is returned as normal.
-		T_Outcode bit = 0x01;
-		int i;
-		for (i = 0; i != 3; ++i)
-		{
-			if (source_bits & bit)
-				// Point of intersection is entering
-			{
-				MT_Scalar lambda = (-source[i] - m_extent[i]) / r[i];
-				if (lambda_enter < lambda)
-				{
-					lambda_enter = lambda;
-					normal_bit = bit;
-				}
-			}
-			else if (target_bits & bit) 
-				// Point of intersection is exiting
-			{
-				MT_Scalar lambda = (-source[i] - m_extent[i]) / r[i];
-				GEN_set_min(lambda_exit, lambda);
-			}
-			bit <<=1;
-			if (source_bits & bit)
-				// Point of intersection is entering
-			{
-				MT_Scalar lambda =  (-source[i] + m_extent[i]) / r[i];
-				if (lambda_enter < lambda)
-				{
-					lambda_enter = lambda;
-					normal_bit = bit;
-				}
-			}
-			else if (target_bits & bit) 
-				// Point of intersection is exiting
-			{
-				MT_Scalar lambda =  (-source[i] + m_extent[i]) / r[i];
-				GEN_set_min(lambda_exit, lambda);
-			}
-			bit <<=1;
-		}
-		if (lambda_enter <= lambda_exit)
-			// The ray intersects the box
-		{
-			param = lambda_enter;
-			normal.setValue(normal_bit == 0x01 ? -MT_Scalar(1.0) : 
-							normal_bit == 0x02 ?  MT_Scalar(1.0) : 
-							MT_Scalar(0.0),
-							normal_bit == 0x04 ? -MT_Scalar(1.0) : 
-							normal_bit == 0x08 ?  MT_Scalar(1.0) : 
-							MT_Scalar(0.0),
-							normal_bit == 0x10 ? -MT_Scalar(1.0) : 
-							normal_bit == 0x20 ?  MT_Scalar(1.0) : 
-							MT_Scalar(0.0));
-			return true;
-		}
-	}
-
-	return false;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Box.h b/extern/solid/src/convex/DT_Box.h
deleted file mode 100644
index ace9634b5e3..00000000000
--- a/extern/solid/src/convex/DT_Box.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_BOX_H
-#define DT_BOX_H
-
-#include "DT_Convex.h"
-
-class DT_Box : public DT_Convex {
-public:
-    DT_Box(MT_Scalar x, MT_Scalar y, MT_Scalar z) : 
-        m_extent(x, y, z) 
-	{}
-
-    DT_Box(const MT_Vector3& e) : 
-		m_extent(e) 
-	{}
-
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target,
-						  MT_Scalar& param, MT_Vector3& normal) const;
-    
-    const MT_Vector3& getExtent() const { return m_extent; }
-	
-protected:
-	typedef unsigned int T_Outcode;
-	
-	T_Outcode outcode(const MT_Point3& p) const
-	{
-		return (p[0] < -m_extent[0] ? 0x01 : 0x0) |    
-			   (p[0] >  m_extent[0] ? 0x02 : 0x0) |
-			   (p[1] < -m_extent[1] ? 0x04 : 0x0) |    
-			   (p[1] >  m_extent[1] ? 0x08 : 0x0) |
-			   (p[2] < -m_extent[2] ? 0x10 : 0x0) |    
-			   (p[2] >  m_extent[2] ? 0x20 : 0x0);
-	}
-    
-    MT_Vector3 m_extent;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Cone.cpp b/extern/solid/src/convex/DT_Cone.cpp
deleted file mode 100644
index 1dd6a7ddbbe..00000000000
--- a/extern/solid/src/convex/DT_Cone.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Cone.h"
-
-MT_Point3 DT_Cone::support(const MT_Vector3& v) const 
-{
-    MT_Scalar v_len = v.length();
-
-    if (v[1] > v_len * sinAngle)
-	{
-		return MT_Point3(MT_Scalar(0.0), halfHeight, MT_Scalar(0.0));
-	}
-    else
-	{
-        MT_Scalar s = MT_sqrt(v[0] * v[0] + v[2] * v[2]);
-        if (s != MT_Scalar(0.0))
-		{
-            MT_Scalar d = bottomRadius / s;  
-            return MT_Point3(v[0] * d, -halfHeight, v[2] * d);
-        }
-        else
-		{
-			return MT_Point3(bottomRadius, -halfHeight, MT_Scalar(0.0));
-		}
-    }
-}
-
diff --git a/extern/solid/src/convex/DT_Cone.h b/extern/solid/src/convex/DT_Cone.h
deleted file mode 100644
index 85e416877dd..00000000000
--- a/extern/solid/src/convex/DT_Cone.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CONE_H
-#define DT_CONE_H
-
-#include "DT_Convex.h"
-
-class DT_Cone : public DT_Convex {
-public:
-	DT_Cone(MT_Scalar r, MT_Scalar h) : 
-        bottomRadius(r), 
-        halfHeight(h * MT_Scalar(0.5)), 
-        sinAngle(r / MT_sqrt(r * r + h * h))
-    {} 
-  
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-  
-protected:
-    MT_Scalar bottomRadius;
-    MT_Scalar halfHeight;
-    MT_Scalar sinAngle;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Convex.cpp b/extern/solid/src/convex/DT_Convex.cpp
deleted file mode 100644
index 3be47f6ed02..00000000000
--- a/extern/solid/src/convex/DT_Convex.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Convex.h"
-#include "GEN_MinMax.h"
-
-//#define DEBUG
-#define SAFE_EXIT
-
-#include "DT_GJK.h"
-#include "DT_PenDepth.h"
-
-#include 
-#include 
-
-#include "MT_BBox.h"
-#include "DT_Sphere.h"
-#include "DT_Minkowski.h"
-
-#include "DT_Accuracy.h"
-
-#ifdef STATISTICS
-int num_iterations = 0;
-int num_irregularities = 0;
-#endif
-
-MT_BBox DT_Convex::bbox() const 
-{
-	MT_Point3 min(-supportH(MT_Vector3(-1.0f, 0.0f, 0.0f)),
-                  -supportH(MT_Vector3(0.0f, -1.0f, 0.0f)),
-				  -supportH(MT_Vector3(0.0f, 0.0f, -1.0f)));
-	MT_Point3 max( supportH(MT_Vector3(1.0f, 0.0f, 0.0f)),
-                   supportH(MT_Vector3(0.0f, 1.0f, 0.0f)),
-				   supportH(MT_Vector3(0.0f, 0.0f, 1.0f)));
-
-	
-    return MT_BBox(min, max);
-}
-
-MT_BBox DT_Convex::bbox(const MT_Matrix3x3& basis) const 
-{
-    MT_Point3 min(-supportH(-basis[0]),
-                  -supportH(-basis[1]),
-		          -supportH(-basis[2])); 
-    MT_Point3 max( supportH( basis[0]),
-                   supportH( basis[1]),
-                   supportH( basis[2])); 
-    return MT_BBox(min, max);
-}
-
-MT_BBox DT_Convex::bbox(const MT_Transform& t, MT_Scalar margin) const 
-{
-    MT_Point3 min(t.getOrigin()[0] - supportH(-t.getBasis()[0]) - margin,
-                  t.getOrigin()[1] - supportH(-t.getBasis()[1]) - margin,
-		          t.getOrigin()[2] - supportH(-t.getBasis()[2]) - margin); 
-    MT_Point3 max(t.getOrigin()[0] + supportH( t.getBasis()[0]) + margin,
-                  t.getOrigin()[1] + supportH( t.getBasis()[1]) + margin,
-                  t.getOrigin()[2] + supportH( t.getBasis()[2]) + margin); 
-    return MT_BBox(min, max);
-}
-
-bool DT_Convex::ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& lambda, MT_Vector3& normal) const
-{
-	// Still working on this one...
-    return false;
-}
-
-bool intersect(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v)
-{
-	DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-	MT_Scalar dist2 = MT_INFINITY;
-
-	do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-		
-        if (v.dot(w) > MT_Scalar(0.0)) 
-		{
-			return false;
-		}
- 
-		gjk.addVertex(w);
-
-#ifdef STATISTICS
-        ++num_iterations;
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            return false;
-        }
-
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-			return false;
-		}
-#endif
-    } 
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-
-    v.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-
-    return true;
-}
-
-
-
-
-bool common_point(const DT_Convex& a, const DT_Convex& b,
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-
-	MT_Scalar dist2 = MT_INFINITY;
-
-    do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-		
-        if (v.dot(w) > MT_Scalar(0.0)) 
-		{
-			return false;
-		}
- 
-		gjk.addVertex(w, p, q);
-
-#ifdef STATISTICS
-        ++num_iterations;
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            return false;
-        }		
-		
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-			return false;
-		}
-#endif
-    }
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-    
-	gjk.compute_points(pa, pb);
-
-    v.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-
-    return true;
-}
-
-
-
-
-
-
-	
-bool penetration_depth(const DT_Convex& a, const DT_Convex& b,
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-
-	MT_Scalar dist2 = MT_INFINITY;
-
-    do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-		
-        if (v.dot(w) > MT_Scalar(0.0)) 
-		{
-			return false;
-		}
- 
-		gjk.addVertex(w, p, q);
-
-#ifdef STATISTICS
-        ++num_iterations;
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            return false;
-        }		
-		
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-			return false;
-		}
-#endif
-    }
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-    
-
-	return penDepth(gjk, a, b, v, pa, pb);
-
-}
-
-bool hybrid_penetration_depth(const DT_Convex& a, MT_Scalar a_margin, 
-							  const DT_Convex& b, MT_Scalar b_margin,
-                              MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	MT_Scalar margin = a_margin + b_margin;
-	if (margin > MT_Scalar(0.0))
-	{
-		MT_Scalar margin2 = margin * margin;
-
-		DT_GJK gjk;
-
-#ifdef STATISTICS
-		num_iterations = 0;
-#endif
-		MT_Scalar dist2 = MT_INFINITY;
-
-		do
-		{
-			MT_Point3  p = a.support(-v);	
-			MT_Point3  q = b.support(v);
-			
-			MT_Vector3 w = p - q; 
-			
-			MT_Scalar delta = v.dot(w);
-			
-			if (delta > MT_Scalar(0.0) && delta * delta > dist2 * margin2) 
-			{
-				return false;
-			}
-			
-			if (gjk.inSimplex(w) || dist2 - delta <= dist2 * DT_Accuracy::rel_error2)
-			{
-				gjk.compute_points(pa, pb);
-				MT_Scalar s = MT_sqrt(dist2);
-				assert(s > MT_Scalar(0.0));
-				pa -= v * (a_margin / s);
-				pb += v * (b_margin / s);
-				return true;
-			}
-			
-			gjk.addVertex(w, p, q);
-			
-#ifdef STATISTICS
-			++num_iterations;
-#endif
-			if (!gjk.closest(v)) 
-			{
-#ifdef STATISTICS
-				++num_irregularities;
-#endif
-				gjk.compute_points(pa, pb);
-				MT_Scalar s = MT_sqrt(dist2);
-				assert(s > MT_Scalar(0.0));
-				pa -= v * (a_margin / s);
-				pb += v * (b_margin / s);
-				return true;
-			}
-			
-#ifdef SAFE_EXIT
-			MT_Scalar prev_dist2 = dist2;
-#endif
-			
-			dist2 = v.length2();
-			
-#ifdef SAFE_EXIT
-			if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-			{ 
-				gjk.backup_closest(v);
-				dist2 = v.length2();
-				gjk.compute_points(pa, pb);
-				MT_Scalar s = MT_sqrt(dist2);
-				assert(s > MT_Scalar(0.0));
-				pa -= v * (a_margin / s);
-				pb += v * (b_margin / s);
-				return true;
-			}
-#endif
-		}
-		while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-		
-	}
-	// Second GJK phase. compute points on the boundary of the offset object
-	
-	return penetration_depth((a_margin > MT_Scalar(0.0) ? 
-							  static_cast(DT_Minkowski(a, DT_Sphere(a_margin))) : 
-							  static_cast(a)), 
-							 (b_margin > MT_Scalar(0.0) ? 
-							  static_cast(DT_Minkowski(b, DT_Sphere(b_margin))) : 
-							  static_cast(b)), v, pa, pb);
-}
-
-
-MT_Scalar closest_points(const DT_Convex& a, const DT_Convex& b, MT_Scalar max_dist2,
-                         MT_Point3& pa, MT_Point3& pb) 
-{
-	MT_Vector3 v(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-	
-    DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-
-	MT_Scalar dist2 = MT_INFINITY;
-
-    do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-
-		MT_Scalar delta = v.dot(w);
-		if (delta > MT_Scalar(0.0) && delta * delta > dist2 * max_dist2) 
-		{
-			return MT_INFINITY;
-		}
-
-		if (gjk.inSimplex(w) || dist2 - delta <= dist2 * DT_Accuracy::rel_error2) 
-		{
-            break;
-		}
-
-		gjk.addVertex(w, p, q);
-
-#ifdef STATISTICS
-        ++num_iterations;
-        if (num_iterations > 1000) 
-		{
-			std::cout << "v: " << v << " w: " << w << std::endl;
-		}
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            break;
-        }
-
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-         gjk.backup_closest(v);
-         dist2 = v.length2();
-			break;
-		}
-#endif
-    }
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-
-	assert(!gjk.emptySimplex());
-	
-	if (dist2 <= max_dist2)
-	{
-		gjk.compute_points(pa, pb);
-	}
-	
-	return dist2;
-}
diff --git a/extern/solid/src/convex/DT_Convex.h b/extern/solid/src/convex/DT_Convex.h
deleted file mode 100644
index dd620ac8b98..00000000000
--- a/extern/solid/src/convex/DT_Convex.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CONVEX_H
-#define DT_CONVEX_H
-
-#include "DT_Shape.h"
-
-#include "MT_Vector3.h"
-#include "MT_Point3.h"
-
-#include "MT_Matrix3x3.h"
-#include "MT_Transform.h"
-
-class DT_Convex : public DT_Shape {
-public:
-    virtual ~DT_Convex() {}
-	virtual DT_ShapeType getType() const { return CONVEX; } 
-    
-	virtual MT_Scalar supportH(const MT_Vector3& v) const {	return v.dot(support(v)); }
-    virtual MT_Point3 support(const MT_Vector3& v) const = 0;
-	virtual MT_BBox bbox() const;
-    virtual MT_BBox bbox(const MT_Matrix3x3& basis) const;
-    virtual MT_BBox bbox(const MT_Transform& t, MT_Scalar margin = MT_Scalar(0.0)) const;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& param, MT_Vector3& normal) const;
-	
-protected:
-	DT_Convex() {}
-};
-
-
-bool intersect(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v);
-
-bool common_point(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-MT_Scalar closest_points(const DT_Convex&, const DT_Convex&, MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb);
-
-bool penetration_depth(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-bool hybrid_penetration_depth(const DT_Convex& a, MT_Scalar a_margin, 
-							  const DT_Convex& b, MT_Scalar b_margin,
-                              MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-#endif
diff --git a/extern/solid/src/convex/DT_Cylinder.cpp b/extern/solid/src/convex/DT_Cylinder.cpp
deleted file mode 100644
index cff5ebcefb1..00000000000
--- a/extern/solid/src/convex/DT_Cylinder.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Cylinder.h"
-
-MT_Point3 DT_Cylinder::support(const MT_Vector3& v) const 
-{
-    MT_Scalar s = MT_sqrt(v[0] * v[0] + v[2] * v[2]);
-    if (s != MT_Scalar(0.0))
-	{
-        MT_Scalar d = radius / s;  
-        return MT_Point3(v[0] * d, v[1] < 0.0 ? -halfHeight : halfHeight, v[2] * d);
-    }
-    else
-	{
-        return MT_Point3(radius, v[1] < 0.0 ? -halfHeight : halfHeight, MT_Scalar(0.0));
-    }
-}
-  
diff --git a/extern/solid/src/convex/DT_Cylinder.h b/extern/solid/src/convex/DT_Cylinder.h
deleted file mode 100644
index 2a0c07fd579..00000000000
--- a/extern/solid/src/convex/DT_Cylinder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CYLINDER_H
-#define DT_CYLINDER_H
-
-#include "DT_Convex.h"
-
-class DT_Cylinder : public DT_Convex {
-public:
-    DT_Cylinder(MT_Scalar r, MT_Scalar h) : 
-        radius(r), 
-        halfHeight(h * MT_Scalar(0.5)) {}
-    
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-    
-protected:
-    MT_Scalar radius;
-    MT_Scalar halfHeight;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Facet.cpp b/extern/solid/src/convex/DT_Facet.cpp
deleted file mode 100644
index 87ae5c3e0be..00000000000
--- a/extern/solid/src/convex/DT_Facet.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Facet.h"
-
-bool DT_Facet::link(int edge0, DT_Facet *facet, int edge1) 
-{
-    m_adjFacets[edge0] = facet;
-    m_adjEdges[edge0] = edge1;
-    facet->m_adjFacets[edge1] = this;
-    facet->m_adjEdges[edge1] = edge0;
-
-    bool b = m_indices[edge0] == facet->m_indices[incMod3(edge1)] &&
-	m_indices[incMod3(edge0)] == facet->m_indices[edge1];
-    return b;
-}
-
-bool DT_Facet::computeClosest(const MT_Vector3 *verts)
-{
-    const MT_Vector3& p0 = verts[m_indices[0]]; 
-
-    MT_Vector3 v1 = verts[m_indices[1]] - p0;
-    MT_Vector3 v2 = verts[m_indices[2]] - p0;
-    MT_Scalar v1dv1 = v1.length2();
-    MT_Scalar v1dv2 = v1.dot(v2);
-    MT_Scalar v2dv2 = v2.length2();
-    MT_Scalar p0dv1 = p0.dot(v1); 
-    MT_Scalar p0dv2 = p0.dot(v2);
-    
-    m_det = v1dv1 * v2dv2 - v1dv2 * v1dv2; // non-negative
-    m_lambda1 = p0dv2 * v1dv2 - p0dv1 * v2dv2;
-    m_lambda2 = p0dv1 * v1dv2 - p0dv2 * v1dv1; 
-    
-    if (m_det > MT_Scalar(0.0)) {	
-	m_closest = p0 + (m_lambda1 * v1 + m_lambda2 * v2) / m_det;
-	m_dist2 = m_closest.length2();
-	return true;
-    }
-    
-    return false;
-} 
-
-void DT_Facet::silhouette(int index, const MT_Vector3& w, 
-			  DT_EdgeBuffer& edgeBuffer) 
-{
-    if (!m_obsolete) {
-		if (m_closest.dot(w) < m_dist2) {
-			edgeBuffer.push_back(DT_Edge(this, index));
-		}	
-	else {
-	    m_obsolete = true; // Facet is visible 
-	    int next = incMod3(index);
-	    m_adjFacets[next]->silhouette(m_adjEdges[next], w, edgeBuffer);
-	    next = incMod3(next);
-	    m_adjFacets[next]->silhouette(m_adjEdges[next], w, edgeBuffer);
-	}
-    }
-}
-
-
diff --git a/extern/solid/src/convex/DT_Facet.h b/extern/solid/src/convex/DT_Facet.h
deleted file mode 100644
index 873706346b8..00000000000
--- a/extern/solid/src/convex/DT_Facet.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_FACET_H
-#define DT_FACET_H
-
-#include 
-#include 
-
-#include 
-#include 
-
-class DT_Facet;
-
-
-class DT_Edge {
-public:
-    DT_Edge() {}
-    DT_Edge(DT_Facet *facet, int index) : 
-	m_facet(facet), 
-	m_index(index) {}
-
-    DT_Facet *getFacet() const { return m_facet; }
-    int       getIndex() const { return m_index; }
-
-    int getSource() const;
-    int getTarget() const;
-
-private:    
-    DT_Facet *m_facet;
-    int       m_index;
-};
-
-typedef std::vector DT_EdgeBuffer;
-
-
-class DT_Facet {
-public:
-    DT_Facet() {}
-    DT_Facet(int i0, int i1, int i2) 
-	  :	m_obsolete(false) 
-    {
-		m_indices[0] = i0; 
-		m_indices[1] = i1; 
-		m_indices[2] = i2;
-    }
-	
-    int operator[](int i) const { return m_indices[i]; } 
-
-    bool link(int edge0, DT_Facet *facet, int edge1);
-
-    
-    bool isObsolete() const { return m_obsolete; }
-    
-
-    bool computeClosest(const MT_Vector3 *verts);
-    
-    const MT_Vector3& getClosest() const { return m_closest; } 
-    
-    bool isClosestInternal() const
-	{ 
-		return m_lambda1 >= MT_Scalar(0.0) && 
-			m_lambda2 >= MT_Scalar(0.0) && 
-			m_lambda1 + m_lambda2 <= m_det;
-    } 
-
-    MT_Scalar getDist2() const { return m_dist2; }
-	
-    MT_Point3 getClosestPoint(const MT_Point3 *points) const 
-	{
-		const MT_Point3& p0 = points[m_indices[0]];
-		
-		return p0 + (m_lambda1 * (points[m_indices[1]] - p0) + 
-					 m_lambda2 * (points[m_indices[2]] - p0)) / m_det;
-    }
-    
-    void silhouette(const MT_Vector3& w, DT_EdgeBuffer& edgeBuffer) 
-	{
-		edgeBuffer.clear();
-		m_obsolete = true;
-		m_adjFacets[0]->silhouette(m_adjEdges[0], w, edgeBuffer);
-		m_adjFacets[1]->silhouette(m_adjEdges[1], w, edgeBuffer);
-		m_adjFacets[2]->silhouette(m_adjEdges[2], w, edgeBuffer);
-    }
-	
-private:
-    void silhouette(int index, const MT_Vector3& w, DT_EdgeBuffer& edgeBuffer);
-	
-    int         m_indices[3];
-    bool        m_obsolete;
-    DT_Facet   *m_adjFacets[3];
-    int         m_adjEdges[3];
-	
-    MT_Scalar   m_det;
-    MT_Scalar   m_lambda1;
-    MT_Scalar   m_lambda2;
-    MT_Vector3  m_closest;
-    MT_Scalar   m_dist2;
-};
-
-
-inline int incMod3(int i) { return ++i % 3; } 
-
-inline int DT_Edge::getSource() const 
-{
-    return (*m_facet)[m_index];
-}
-
-inline int DT_Edge::getTarget() const 
-{
-    return (*m_facet)[incMod3(m_index)];
-}
-
-#endif
diff --git a/extern/solid/src/convex/DT_GJK.h b/extern/solid/src/convex/DT_GJK.h
deleted file mode 100644
index d8f44acf85e..00000000000
--- a/extern/solid/src/convex/DT_GJK.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_GJK_H
-#define DT_GJK_H
-
-//#define USE_BACKUP_PROCEDURE
-#define JOHNSON_ROBUST
-#define FAST_CLOSEST
-
-#include "MT_Point3.h"
-#include "MT_Vector3.h"
-#include "GEN_MinMax.h"
-#include "DT_Accuracy.h"
-
-
-class DT_GJK {
-private:
-	typedef unsigned int T_Bits;
-	inline static bool subseteq(T_Bits a, T_Bits b) { return (a & b) == a; }
-	inline static bool contains(T_Bits a, T_Bits b) { return (a & b) != 0x0; }
-
-public:
-	DT_GJK() :
-		m_bits(0x0),
-		m_all_bits(0x0)
-	{}
-
-	bool emptySimplex() const { return m_bits == 0x0; }
-	bool fullSimplex() const { return m_bits == 0xf; }
-
-	void reset() 
-	{
-		m_bits = 0x0;
-		m_all_bits = 0x0;	
-	}
-
-	bool inSimplex(const MT_Vector3& w) 
-	{
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-		{
-			if (contains(m_all_bits, bit) && w == m_y[i])
-			{
-				return true;
-			}
-		}
-		return false;
-	}
-
-	void addVertex(const MT_Vector3& w) 
-	{
-		assert(!fullSimplex());
-		m_last = 0;
-        m_last_bit = 0x1;
-        while (contains(m_bits, m_last_bit)) 
-		{ 
-			++m_last; 
-			m_last_bit <<= 1; 
-		}
-		m_y[m_last] = w;
-		m_ylen2[m_last] = w.length2();
-        m_all_bits = m_bits | m_last_bit;
-
-		update_cache();
-		compute_det();
-	}
-
-	void addVertex(const MT_Vector3& w, const MT_Point3& p, const MT_Point3& q)
-	{
-		addVertex(w);
-		m_p[m_last] = p;
-		m_q[m_last] = q;
-	}
-
-	int getSimplex(MT_Point3 *pBuf, MT_Point3 *qBuf, MT_Vector3 *yBuf) const 
-	{
-		int num_verts = 0;
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1) 
-		{
-			if (contains(m_bits, bit)) 
-			{
-				pBuf[num_verts] = m_p[i];
-				qBuf[num_verts] = m_q[i];
-				yBuf[num_verts] = m_y[i];
-				
-#ifdef DEBUG
-				std::cout << "Point " << i << " = " << m_y[i] << std::endl;
-#endif
-				
-				++num_verts;
-			}
-		}
-		return num_verts;
-    }
-
-	void compute_points(MT_Point3& p1, MT_Point3& p2) 
-	{
-		MT_Scalar sum = MT_Scalar(0.0);
-		p1.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-		p2.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1) 
-		{
-			if (contains(m_bits, bit))
-			{
-				sum += m_det[m_bits][i];
-				p1 += m_p[i] * m_det[m_bits][i];
-				p2 += m_q[i] * m_det[m_bits][i];
-			}
-		}
-
-		assert(sum > MT_Scalar(0.0));
-		MT_Scalar s = MT_Scalar(1.0) / sum;
-		p1 *= s;
-		p2 *= s;
-	}
-
-	bool closest(MT_Vector3& v) 
-	{
-#ifdef FAST_CLOSEST
-		T_Bits s;
-		for (s = m_bits; s != 0x0; --s)
-		{
-			if (subseteq(s, m_bits) && valid(s | m_last_bit)) 
-			{
-				m_bits = s | m_last_bit;
-				compute_vector(m_bits, v);
-				return true;
-			}
-		}
-		if (valid(m_last_bit)) 
-		{
-			m_bits = m_last_bit;
-			m_maxlen2 = m_ylen2[m_last];
-			v = m_y[m_last];
-			return true;
-		}
-#else
-		T_Bits s;
-		for (s = m_all_bits; s != 0x0; --s)
-		{
-			if (subseteq(s, m_all_bits) && valid(s)) 
-			{
-				m_bits = s;
-				compute_vector(m_bits, v);
-				return true;
-			}
-		}
-#endif
-		
-		// Original GJK calls the backup procedure at this point.
-#ifdef USE_BACKUP_PROCEDURE
-		backup_closest(MT_Vector3& v); 
-#endif
-		return false;  
-	}
-
-	void backup_closest(MT_Vector3& v)
-	{ 		
-		MT_Scalar min_dist2 = MT_INFINITY;
-		
-      T_Bits s;
-		for (s = m_all_bits; s != 0x0; --s) 
-		{
-			if (subseteq(s, m_all_bits) && proper(s))
-			{	
-				MT_Vector3 u;
-				compute_vector(s, u);
-				MT_Scalar dist2 = u.length2();
-				if (dist2 < min_dist2)
-				{
-					min_dist2 = dist2;
-					m_bits = s;
-					v = u;
-				}
-			}
-		}
-	}
-	
-	MT_Scalar maxVertex() { return m_maxlen2; }
-
-
-private:
-	void update_cache();
-	void compute_det();
-
-	bool valid(T_Bits s) 
-	{
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-		{
-			if (contains(m_all_bits, bit)) 
-			{
-				if (contains(s, bit)) 
-				{
-					if (m_det[s][i] <= MT_Scalar(0.0)) 
-					{
-						return false; 
-					}
-				}
-				else if (m_det[s | bit][i] > MT_Scalar(0.0))
-				{ 
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-
-	bool proper(T_Bits s)
-	{ 
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-		{
-			if (contains(s, bit) && m_det[s][i] <= MT_Scalar(0.0))
-			{
-				return false; 
-			}
-		}
-		return true;
-	}
-
-	void compute_vector(T_Bits s, MT_Vector3& v) 
-	{
-		m_maxlen2 = MT_Scalar(0.0);
-		MT_Scalar sum = MT_Scalar(0.0);
-		v .setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1) 
-		{
-			if (contains(s, bit))
-			{
-				sum += m_det[s][i];
-				GEN_set_max(m_maxlen2, m_ylen2[i]);
-				v += m_y[i] * m_det[s][i];
-			}
-		}
-		
-		assert(sum > MT_Scalar(0.0));
-
-		v /= sum;
-	}
- 
-private:
-	MT_Scalar	m_det[16][4]; // cached sub-determinants
-    MT_Vector3	m_edge[4][4];
-
-#ifdef JOHNSON_ROBUST
-    MT_Scalar	m_norm[4][4];
-#endif
-
-	MT_Point3	m_p[4];    // support points of object A in local coordinates 
-	MT_Point3	m_q[4];    // support points of object B in local coordinates 
-	MT_Vector3	m_y[4];   // support points of A - B in world coordinates
-	MT_Scalar	m_ylen2[4];   // Squared lengths support points y
-
-	MT_Scalar	m_maxlen2; // Maximum squared length to a vertex of the current 
-	                      // simplex
-	T_Bits		m_bits;      // identifies current simplex
-	T_Bits		m_last;      // identifies last found support point
-	T_Bits		m_last_bit;  // m_last_bit == 0x1 << last
-	T_Bits		m_all_bits;  // m_all_bits == m_bits  | m_last_bit 
-};
-
-
-
-
-inline void DT_GJK::update_cache() 
-{
-	int i;
-	T_Bits bit;
-    for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-	{
-        if (contains(m_bits, bit)) 
-		{
-			m_edge[i][m_last] = m_y[i] - m_y[m_last];
-			m_edge[m_last][i] = -m_edge[i][m_last];
-
-#ifdef JOHNSON_ROBUST
-			m_norm[i][m_last] = m_norm[m_last][i] = m_edge[i][m_last].length2();
-#endif
-
-		}
-	}
-}
-
-#ifdef JOHNSON_ROBUST
-
-inline void DT_GJK::compute_det() 
-{
-    m_det[m_last_bit][m_last] = 1;
-
-	int i;
-	T_Bits si;
-    for (i = 0, si = 0x1; i < 4; ++i, si <<= 1) 
-	{
-        if (contains(m_bits, si)) 
-		{
-            T_Bits s2 = si | m_last_bit;
-            m_det[s2][i] = m_edge[m_last][i].dot(m_y[m_last]); 
-            m_det[s2][m_last] = m_edge[i][m_last].dot(m_y[i]);
-
-			int j;
-			T_Bits sj;
-            for (j = 0, sj = 0x1; j < i; ++j, sj <<= 1) 
-			{
-                if (contains(m_bits, sj)) 
-				{
-					int k;
-                    T_Bits s3 = sj | s2;			
-					
-					k = m_norm[i][j] < m_norm[m_last][j] ? i : m_last;
-                    m_det[s3][j] = m_det[s2][i] * m_edge[k][j].dot(m_y[i]) + 
-                                   m_det[s2][m_last] * m_edge[k][j].dot(m_y[m_last]);
-					k = m_norm[j][i] < m_norm[m_last][i] ? j : m_last;
-                    m_det[s3][i] = m_det[sj|m_last_bit][j] * m_edge[k][i].dot(m_y[j]) +  
-                                   m_det[sj|m_last_bit][m_last] * m_edge[k][i].dot(m_y[m_last]);
-					k = m_norm[i][m_last] < m_norm[j][m_last] ? i : j;
-                    m_det[s3][m_last] = m_det[sj|si][j] * m_edge[k][m_last].dot(m_y[j]) + 
-                                        m_det[sj|si][i] * m_edge[k][m_last].dot(m_y[i]);
-                }
-            }
-        }
-    }
-
-    if (m_all_bits == 0xf) 
-	{
-		int k;
-
-		k = m_norm[1][0] < m_norm[2][0] ? (m_norm[1][0] < m_norm[3][0] ? 1 : 3) : (m_norm[2][0] < m_norm[3][0] ? 2 : 3);
-		
-        m_det[0xf][0] = m_det[0xe][1] * m_edge[k][0].dot(m_y[1]) + 
-                        m_det[0xe][2] * m_edge[k][0].dot(m_y[2]) + 
-                        m_det[0xe][3] * m_edge[k][0].dot(m_y[3]);
-
-		k = m_norm[0][1] < m_norm[2][1] ? (m_norm[0][1] < m_norm[3][1] ? 0 : 3) : (m_norm[2][1] < m_norm[3][1] ? 2 : 3);
-		
-        m_det[0xf][1] = m_det[0xd][0] * m_edge[k][1].dot(m_y[0]) + 
-                        m_det[0xd][2] * m_edge[k][1].dot(m_y[2]) +
-                        m_det[0xd][3] * m_edge[k][1].dot(m_y[3]);
-
-		k = m_norm[0][2] < m_norm[1][2] ? (m_norm[0][2] < m_norm[3][2] ? 0 : 3) : (m_norm[1][2] < m_norm[3][2] ? 1 : 3);
-		
-        m_det[0xf][2] = m_det[0xb][0] * m_edge[k][2].dot(m_y[0]) + 
-                        m_det[0xb][1] * m_edge[k][2].dot(m_y[1]) +  
-                        m_det[0xb][3] * m_edge[k][2].dot(m_y[3]);
-
-		k = m_norm[0][3] < m_norm[1][3] ? (m_norm[0][3] < m_norm[2][3] ? 0 : 2) : (m_norm[1][3] < m_norm[2][3] ? 1 : 2);
-		
-        m_det[0xf][3] = m_det[0x7][0] * m_edge[k][3].dot(m_y[0]) + 
-                        m_det[0x7][1] * m_edge[k][3].dot(m_y[1]) + 
-                        m_det[0x7][2] * m_edge[k][3].dot(m_y[2]);
-    }
-}
-
-#else
-
-inline void DT_GJK::compute_det() 
-{
-    m_det[m_last_bit][m_last] = 1;
-
-	int i;
-	T_Bits si;
-    for (i = 0, si = 0x1; i < 4; ++i, si <<= 1) 
-	{
-        if (contains(m_bits, si)) 
-		{
-            T_Bits s2 = si | m_last_bit;
-            m_det[s2][i] = m_edge[m_last][i].dot(m_y[m_last]); 
-            m_det[s2][m_last] = m_edge[i][m_last].dot(m_y[i]);
-
-			int j;
-			T_Bits sj;
-            for (j = 0, sj = 0x1; j < i; ++j, sj <<= 1)
-			{
-                if (contains(m_bits, sj)) 
-				{
-                    T_Bits s3 = sj | s2;
-                    m_det[s3][j] = m_det[s2][i] * m_edge[i][j].dot(m_y[i]) + 
-                                   m_det[s2][m_last] * m_edge[i][j].dot(m_y[m_last]);
-                    m_det[s3][i] = m_det[sj|m_last_bit][j] * m_edge[j][i].dot(m_y[j]) +  
-                                   m_det[sj|m_last_bit][m_last] * m_edge[j][i].dot(m_y[m_last]);
-                    m_det[s3][m_last] = m_det[sj|si][j] * m_edge[j][m_last].dot(m_y[j]) + 
-                                        m_det[sj|si][i] * m_edge[j][m_last].dot(m_y[i]);
-                }
-            }
-        }
-    }
-
-    if (m_all_bits == 0xf) 
-	{
-        m_det[0xf][0] = m_det[0xe][1] * m_edge[1][0].dot(m_y[1]) + 
-                        m_det[0xe][2] * m_edge[1][0].dot(m_y[2]) + 
-                        m_det[0xe][3] * m_edge[1][0].dot(m_y[3]);
-        m_det[0xf][1] = m_det[0xd][0] * m_edge[0][1].dot(m_y[0]) + 
-                        m_det[0xd][2] * m_edge[0][1].dot(m_y[2]) +
-                        m_det[0xd][3] * m_edge[0][1].dot(m_y[3]);
-        m_det[0xf][2] = m_det[0xb][0] * m_edge[0][2].dot(m_y[0]) + 
-                        m_det[0xb][1] * m_edge[0][2].dot(m_y[1]) +  
-                        m_det[0xb][3] * m_edge[0][2].dot(m_y[3]);
-        m_det[0xf][3] = m_det[0x7][0] * m_edge[0][3].dot(m_y[0]) + 
-                        m_det[0x7][1] * m_edge[0][3].dot(m_y[1]) + 
-                        m_det[0x7][2] * m_edge[0][3].dot(m_y[2]);
-    }
-}
-
-#endif
-
-#endif
diff --git a/extern/solid/src/convex/DT_Hull.h b/extern/solid/src/convex/DT_Hull.h
deleted file mode 100644
index a5bf56ae59d..00000000000
--- a/extern/solid/src/convex/DT_Hull.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_HULL_H
-#define DT_HULL_H
-
-#include "DT_Convex.h"
-
-class DT_Hull : public DT_Convex {
-public:
-	DT_Hull(const DT_Convex& lchild, const DT_Convex& rchild) :
-		m_lchild(lchild), 
-		m_rchild(rchild) 
-	{}
-
-	virtual MT_Scalar supportH(const MT_Vector3& v) const 
-	{
-		return GEN_max(m_lchild.supportH(v), m_rchild.supportH(v));
-	}
-
-	virtual MT_Point3 support(const MT_Vector3& v) const 
-	{
-		MT_Point3 lpnt = m_lchild.support(v);
-		MT_Point3 rpnt = m_rchild.support(v);
-		return v.dot(lpnt) > v.dot(rpnt) ? lpnt : rpnt;
-	}
-
-private:
-	const DT_Convex& m_lchild;
-	const DT_Convex& m_rchild;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_IndexArray.h b/extern/solid/src/convex/DT_IndexArray.h
deleted file mode 100644
index 95551fa8483..00000000000
--- a/extern/solid/src/convex/DT_IndexArray.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_INDEXARRAY_H
-#define DT_INDEXARRAY_H
-
-#include "SOLID_types.h"
-#include "DT_Array.h"
-
-typedef DT_Array DT_IndexArray;
-
-#endif
-
diff --git a/extern/solid/src/convex/DT_LineSegment.cpp b/extern/solid/src/convex/DT_LineSegment.cpp
deleted file mode 100644
index 6c7ccf6b9b7..00000000000
--- a/extern/solid/src/convex/DT_LineSegment.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_LineSegment.h"
-
-MT_Scalar DT_LineSegment::supportH(const MT_Vector3& v) const
-{
-    return GEN_max(v.dot(m_source), v.dot(m_target));
-}
-
-MT_Point3 DT_LineSegment::support(const MT_Vector3& v) const
-{
-    return v.dot(m_source) > v.dot(m_target) ?	m_source : m_target;
-}
-
-
diff --git a/extern/solid/src/convex/DT_LineSegment.h b/extern/solid/src/convex/DT_LineSegment.h
deleted file mode 100644
index 979ff8a18a9..00000000000
--- a/extern/solid/src/convex/DT_LineSegment.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_LINESEGMENT_H
-#define DT_LINESEGMENT_H
-
-#include "DT_Convex.h"
-
-class DT_LineSegment : public DT_Convex {
-public:
-    DT_LineSegment(const MT_Point3& source, const MT_Point3& target) : 
-	   m_source(source), 
-	   m_target(target) {}
-
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-	const MT_Point3& getSource() const { return m_source; }
-	const MT_Point3& getTarget() const { return m_target; }
-
-private:
-	MT_Point3 m_source;
-	MT_Point3 m_target;
-};
-
-#endif
-
-
-
-
-
-
diff --git a/extern/solid/src/convex/DT_Minkowski.h b/extern/solid/src/convex/DT_Minkowski.h
deleted file mode 100644
index e90fed6a8e0..00000000000
--- a/extern/solid/src/convex/DT_Minkowski.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_MINKOWSKI_H
-#define DT_MINKOWSKI_H
-
-#include "DT_Convex.h"
-
-class DT_Minkowski : public DT_Convex {
-public:
-	DT_Minkowski(const DT_Convex& lchild, const DT_Convex& rchild) 
-     : m_lchild(lchild), 
-       m_rchild(rchild) 
-   {}
-
-	virtual MT_Scalar supportH(const MT_Vector3& v) const 
-	{
-		return m_lchild.supportH(v) + m_rchild.supportH(v); 
-	}
-
-	virtual MT_Point3 support(const MT_Vector3& v) const 
-	{
-		return m_lchild.support(v) + (MT_Vector3)m_rchild.support(v); 
-	}
-
-private:
-	const DT_Convex& m_lchild;
-	const DT_Convex& m_rchild;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_PenDepth.cpp b/extern/solid/src/convex/DT_PenDepth.cpp
deleted file mode 100644
index e1c5c9a3949..00000000000
--- a/extern/solid/src/convex/DT_PenDepth.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_PenDepth.h"
-
-#include "MT_Vector3.h"
-#include "MT_Point3.h"
-#include "MT_Quaternion.h"
-#include "DT_Convex.h"
-#include "DT_GJK.h"
-#include "DT_Facet.h"
-
-//#define DEBUG
-
-const int       MaxSupportPoints = 1000;
-const int       MaxFacets         = 2000;
-
-static MT_Point3  pBuf[MaxSupportPoints];
-static MT_Point3  qBuf[MaxSupportPoints];
-static MT_Vector3 yBuf[MaxSupportPoints];
-
-static DT_Facet facetBuf[MaxFacets];
-static int  freeFacet = 0;
-static DT_Facet *facetHeap[MaxFacets];
-static int  num_facets;
-
-class DT_FacetComp {
-public:
-    
-    bool operator()(const DT_Facet *face1, const DT_Facet *face2) 
-	{ 
-		return face1->getDist2() > face2->getDist2();
-    }
-    
-} facetComp;
-
-inline DT_Facet *addFacet(int i0, int i1, int i2,
-						  MT_Scalar lower2, MT_Scalar upper2) 
-{
-    assert(i0 != i1 && i0 != i2 && i1 != i2);
-    if (freeFacet < MaxFacets)
-	{
-		DT_Facet *facet = new(&facetBuf[freeFacet++]) DT_Facet(i0, i1, i2);
-#ifdef DEBUG
-		std::cout << "Facet " << i0 << ' ' << i1 << ' ' << i2;
-#endif
-		if (facet->computeClosest(yBuf)) 
-		{
-			if (facet->isClosestInternal() && 
-				lower2 <= facet->getDist2() && facet->getDist2() <= upper2) 
-			{
-				facetHeap[num_facets++] = facet;
-				std::push_heap(&facetHeap[0], &facetHeap[num_facets], facetComp);
-#ifdef DEBUG
-				std::cout << " accepted" << std::endl;
-#endif
-			}
-			else 
-			{
-#ifdef DEBUG
-				std::cout << " rejected, ";
-				if (!facet->isClosestInternal()) 
-				{
-					std::cout << "closest point not internal";
-				}
-				else if (lower2 > facet->getDist2()) 
-				{
-					std::cout << "facet is closer than orignal facet";
-				}
-				else 
-				{
-					std::cout << "facet is further than upper bound";
-				}
-				std::cout << std::endl;
-#endif
-			}
-			
-			return facet;
-		}
-    }
-    
-    return 0;
-}
-
-inline bool originInTetrahedron(const MT_Vector3& p1, const MT_Vector3& p2, 
-								const MT_Vector3& p3, const MT_Vector3& p4)
-{
-    MT_Vector3 normal1 = (p2 - p1).cross(p3 - p1);
-    MT_Vector3 normal2 = (p3 - p2).cross(p4 - p2);
-    MT_Vector3 normal3 = (p4 - p3).cross(p1 - p3);
-    MT_Vector3 normal4 = (p1 - p4).cross(p2 - p4);
-    
-    return 
-		normal1.dot(p1) > MT_Scalar(0.0) != normal1.dot(p4) > MT_Scalar(0.0) &&
-		normal2.dot(p2) > MT_Scalar(0.0) != normal2.dot(p1) > MT_Scalar(0.0) &&
-		normal3.dot(p3) > MT_Scalar(0.0) != normal3.dot(p2) > MT_Scalar(0.0) &&
-		normal4.dot(p4) > MT_Scalar(0.0) != normal4.dot(p3) > MT_Scalar(0.0);
-}
-
-
-bool penDepth(const DT_GJK& gjk, const DT_Convex& a, const DT_Convex& b,
-			  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	
-    int num_verts = gjk.getSimplex(pBuf, qBuf, yBuf);
-    
-    switch (num_verts) 
-	{
-	case 1:
-	    // Touching contact. Yes, we have a collision,
-	    // but no penetration.
-	    return false;
-	case 2:	
-	{
-	    // We have a line segment inside the Minkowski sum containing the
-	    // origin. Blow it up by adding three additional support points.
-	    
-	    MT_Vector3 dir  = (yBuf[1] - yBuf[0]).normalized();
-	    int        axis = dir.furthestAxis();
-	    
-	    static MT_Scalar sin_60 = MT_sqrt(MT_Scalar(3.0)) * MT_Scalar(0.5);
-	    
-	    MT_Quaternion rot(dir[0] * sin_60, dir[1] * sin_60, dir[2] * sin_60, MT_Scalar(0.5));
-	    MT_Matrix3x3 rot_mat(rot);
-	    
-	    MT_Vector3 aux1 = dir.cross(MT_Vector3(axis == 0, axis == 1, axis == 2));
-	    MT_Vector3 aux2 = rot_mat * aux1;
-	    MT_Vector3 aux3 = rot_mat * aux2;
-	    
-	    pBuf[2] = a.support(aux1);
-	    qBuf[2] = b.support(-aux1);
-	    yBuf[2] = pBuf[2] - qBuf[2];
-	    
-	    pBuf[3] = a.support(aux2);
-	    qBuf[3] = b.support(-aux2);
-	    yBuf[3] = pBuf[3] - qBuf[3];
-	    
-	    pBuf[4] = a.support(aux3);
-	    qBuf[4] = b.support(-aux3);
-	    yBuf[4] = pBuf[4] - qBuf[4];
-	    
-	    if (originInTetrahedron(yBuf[0], yBuf[2], yBuf[3], yBuf[4])) 
-		{
-			pBuf[1] = pBuf[4];
-			qBuf[1] = qBuf[4];
-			yBuf[1] = yBuf[4];
-	    }
-	    else if (originInTetrahedron(yBuf[1], yBuf[2], yBuf[3], yBuf[4])) 
-		{
-			pBuf[0] = pBuf[4];
-			qBuf[0] = qBuf[4];
-			yBuf[0] = yBuf[4];
-	    } 
-	    else 
-		{
-			// Origin not in initial polytope
-			return false;
-	    }
-	    
-	    num_verts = 4;
-	    
-	    break;
-	}
-	case 3: 
-	{
-	    // We have a triangle inside the Minkowski sum containing
-	    // the origin. First blow it up.
-	    
-	    MT_Vector3 v1     = yBuf[1] - yBuf[0];
-	    MT_Vector3 v2     = yBuf[2] - yBuf[0];
-	    MT_Vector3 vv     = v1.cross(v2);
-	    
-	    pBuf[3] = a.support(vv);
-	    qBuf[3] = b.support(-vv);
-	    yBuf[3] = pBuf[3] - qBuf[3];
-	    pBuf[4] = a.support(-vv);
-	    qBuf[4] = b.support(vv);
-	    yBuf[4] = pBuf[4] - qBuf[4];
-	    
-	   
-	    if (originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[4])) 
-		{
-			pBuf[3] = pBuf[4];
-			qBuf[3] = qBuf[4];
-			yBuf[3] = yBuf[4];
-	    }
-	    else if (!originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[3]))
-		{ 
-			// Origin not in initial polytope
-			return false;
-	    }
-	    
-	    num_verts = 4;
-	    
-	    break;
-	}
-    }
-    
-    // We have a tetrahedron inside the Minkowski sum containing
-    // the origin (if GJK did it's job right ;-)
-      
-    
-    if (!originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[3])) 
-	{
-		//	assert(false);
-		return false;
-	}
-    
-	num_facets = 0;
-    freeFacet = 0;
-
-    DT_Facet *f0 = addFacet(0, 1, 2, MT_Scalar(0.0), MT_INFINITY);
-    DT_Facet *f1 = addFacet(0, 3, 1, MT_Scalar(0.0), MT_INFINITY);
-    DT_Facet *f2 = addFacet(0, 2, 3, MT_Scalar(0.0), MT_INFINITY);
-    DT_Facet *f3 = addFacet(1, 3, 2, MT_Scalar(0.0), MT_INFINITY);
-    
-    if (!f0 || f0->getDist2() == MT_Scalar(0.0) ||
-		!f1 || f1->getDist2() == MT_Scalar(0.0) ||
-		!f2 || f2->getDist2() == MT_Scalar(0.0) ||
-		!f3 || f3->getDist2() == MT_Scalar(0.0)) 
-	{
-		return false;
-    }
-    
-    f0->link(0, f1, 2);
-    f0->link(1, f3, 2);
-    f0->link(2, f2, 0);
-    f1->link(0, f2, 2);
-    f1->link(1, f3, 0);
-    f2->link(1, f3, 1);
-    
-    if (num_facets == 0) 
-	{
-		return false;
-    }
-    
-    // at least one facet on the heap.	
-    
-    DT_EdgeBuffer edgeBuffer(20);
-
-    DT_Facet *facet = 0;
-    
-    MT_Scalar upper_bound2 = MT_INFINITY; 	
-    
-    do {
-        facet = facetHeap[0];
-        std::pop_heap(&facetHeap[0], &facetHeap[num_facets], facetComp);
-        --num_facets;
-		
-		if (!facet->isObsolete()) 
-		{
-			assert(facet->getDist2() > MT_Scalar(0.0));
-			
-			if (num_verts == MaxSupportPoints)
-			{
-#ifdef DEBUG
-				std::cout << "Ouch, no convergence!!!" << std::endl;
-#endif 
-				assert(false);	
-				break;
-			}
-			
-			pBuf[num_verts] = a.support(facet->getClosest());
-			qBuf[num_verts] = b.support(-facet->getClosest());
-			yBuf[num_verts] = pBuf[num_verts] - qBuf[num_verts];
-			
-			int index = num_verts++;
-			MT_Scalar far_dist2 = yBuf[index].dot(facet->getClosest());
-			
-			// Make sure the support mapping is OK.
-			assert(far_dist2 > MT_Scalar(0.0));
-			
-			GEN_set_min(upper_bound2, far_dist2 * far_dist2 / facet->getDist2());
-			
-			if (upper_bound2 <= DT_Accuracy::depth_tolerance * facet->getDist2()
-#define CHECK_NEW_SUPPORT
-#ifdef CHECK_NEW_SUPPORT
-				|| yBuf[index] == yBuf[(*facet)[0]] 
-				|| yBuf[index] == yBuf[(*facet)[1]]
-				|| yBuf[index] == yBuf[(*facet)[2]]
-#endif
-				) 
-			{
-				break;
-			}
-			
-			// Compute the silhouette cast by the new vertex
-			// Note that the new vertex is on the positive side
-			// of the current facet, so the current facet is will
-			// not be in the convex hull. Start local search
-			// from this facet.
-			
-			facet->silhouette(yBuf[index], edgeBuffer);
-			
-			if (edgeBuffer.empty()) 
-			{
-				return false;
-			}
-			
-			DT_EdgeBuffer::const_iterator it = edgeBuffer.begin();
-			DT_Facet *firstFacet = 
-				addFacet((*it).getTarget(), (*it).getSource(),
-						 index, facet->getDist2(), upper_bound2);
-			
-			if (!firstFacet) 
-			{
-				break;
-			}
-			
-			firstFacet->link(0, (*it).getFacet(), (*it).getIndex());
-			DT_Facet *lastFacet = firstFacet;
-			
-			++it;
-			for (; it != edgeBuffer.end(); ++it) 
-			{
-				DT_Facet *newFacet = 
-					addFacet((*it).getTarget(), (*it).getSource(),
-							 index, facet->getDist2(), upper_bound2);
-				
-				if (!newFacet) 
-				{
-					break;
-				}
-				
-				if (!newFacet->link(0, (*it).getFacet(), (*it).getIndex())) 
-				{
-					break;
-				}
-				
-				if (!newFacet->link(2, lastFacet, 1)) 
-				{
-					break;
-				}
-				
-				lastFacet = newFacet;				
-			}
-			if (it != edgeBuffer.end()) 
-			{
-				break;
-			}
-			
-			firstFacet->link(2, lastFacet, 1);
-		}
-    }
-    while (num_facets > 0 && facetHeap[0]->getDist2() <= upper_bound2);
-	
-#ifdef DEBUG    
-    std::cout << "#facets left = " << num_facets << std::endl;
-#endif
-    
-    v = facet->getClosest();
-    pa = facet->getClosestPoint(pBuf);    
-    pb = facet->getClosestPoint(qBuf);    
-    return true;
-}
-
diff --git a/extern/solid/src/convex/DT_PenDepth.h b/extern/solid/src/convex/DT_PenDepth.h
deleted file mode 100644
index 97b3c6c0e0e..00000000000
--- a/extern/solid/src/convex/DT_PenDepth.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_PENDEPTH_H
-#define DT_PENDEPTH_H
-
-#include "MT_Vector3.h"
-#include "MT_Point3.h"
-
-class DT_GJK;
-class DT_Convex;
-
-bool penDepth(const DT_GJK& gjk, const DT_Convex& a, const DT_Convex& b, 
-			  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-#endif
diff --git a/extern/solid/src/convex/DT_Point.cpp b/extern/solid/src/convex/DT_Point.cpp
deleted file mode 100644
index 770fe7775b7..00000000000
--- a/extern/solid/src/convex/DT_Point.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Point.h"
-
-MT_Scalar DT_Point::supportH(const MT_Vector3& v) const
-{
-    return v.dot(m_point);
-}
-
-MT_Point3 DT_Point::support(const MT_Vector3& v) const
-{
-    return m_point;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Point.h b/extern/solid/src/convex/DT_Point.h
deleted file mode 100644
index b35d158ee53..00000000000
--- a/extern/solid/src/convex/DT_Point.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_POINT_H
-#define DT_POINT_H
-
-#include "DT_Convex.h"
-
-class DT_Point : public DT_Convex {
-public:
-    DT_Point(const MT_Point3& point) : m_point(point) {}
-
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-private:
-	MT_Point3 m_point;
-};
-
-#endif
-
-
-
-
-
-
diff --git a/extern/solid/src/convex/DT_Polyhedron.cpp b/extern/solid/src/convex/DT_Polyhedron.cpp
deleted file mode 100644
index f48ac6e4b6d..00000000000
--- a/extern/solid/src/convex/DT_Polyhedron.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Polyhedron.h"
-
-#ifdef QHULL
-
-extern "C" {
-#include 
-}
-
-#include 
-#include   
-
-typedef std::vector T_VertexBuf;
-typedef std::vector T_IndexBuf;
-typedef std::vector T_MultiIndexBuf;
-
-static char options[] = "qhull Qts i Tv";
-
-#define DK_HIERARCHY
-
-T_IndexBuf *adjacency_graph(DT_Count count, const MT_Point3 *verts, const char *flags)
-{
-	int curlong, totlong, exitcode;
-	
-    facetT *facet;
-    vertexT *vertex;
-    vertexT **vertexp;
-    
-    std::vector > array;
-	T_IndexBuf index;
-    DT_Index i;
-    for (i = 0; i != count; ++i) 
-	{
-		if (flags == 0 || flags[i])
-		{
-            array.push_back(MT::Tuple3(verts[i]));
-			index.push_back(i);
-		}
-    }
-
-    qh_init_A(stdin, stdout, stderr, 0, NULL);
-    if ((exitcode = setjmp(qh errexit))) 
-	{
-		exit(exitcode);
-	}
-    qh_initflags(options);
-    qh_init_B(array[0], array.size(), 3, False);
-    qh_qhull();
-    qh_check_output();
-    
-    T_IndexBuf *indexBuf = new T_IndexBuf[count];
-    FORALLfacets 
-	{
-		setT *vertices = qh_facet3vertex(facet);
-		
-		T_IndexBuf  facetIndices;
-
-		FOREACHvertex_(vertices) 
-		{
-			facetIndices.push_back(index[qh_pointid(vertex->point)]);
-		}
-		int i, j;
-		for (i = 0, j = facetIndices.size()-1; i < (int)facetIndices.size(); j = i++)
-		{
-			indexBuf[facetIndices[j]].push_back(facetIndices[i]);
-		}
-    }
-
-    
-    qh NOerrexit = True;
-    qh_freeqhull(!qh_ALL);
-    qh_memfreeshort(&curlong, &totlong);
-
-	return indexBuf;
-}
-
-T_IndexBuf *simplex_adjacency_graph(DT_Count count, const char *flags)
-{
-	T_IndexBuf *indexBuf = new T_IndexBuf[count];
-
-	DT_Index index[4];
-	
-	DT_Index k = 0;
-	DT_Index i;
-	for (i = 0; i != count; ++i) 
-	{
-		if (flags == 0 || flags[i])
-		{
-			index[k++] = i;
-		}
-	}
-
-	assert(k <= 4);
-
-	for (i = 0; i != k; ++i)
-	{
-		DT_Index j;
-		for (j = 0; j != k; ++j)
-		{
-			if (i != j)
-			{
-				indexBuf[index[i]].push_back(index[j]);
-			}
-		}
-	}
-
-	return indexBuf;
-}
-
-#ifdef DK_HIERARCHY
-
-void prune(DT_Count count, T_MultiIndexBuf *cobound)
-{
-	DT_Index i;
-	for (i = 0; i != count; ++i)
-	{
-		assert(cobound[i].size());
-
-		DT_Index j;
-		for (j = 0; j != cobound[i].size() - 1; ++j)
-		{
-			T_IndexBuf::iterator it = cobound[i][j].begin();
-			while (it != cobound[i][j].end())
-			{
-				T_IndexBuf::iterator jt = 
-					std::find(cobound[i][j+1].begin(), cobound[i][j+1].end(), *it);
-
-				if (jt != cobound[i][j+1].end())
-				{
-					std::swap(*it, cobound[i][j].back());
-					cobound[i][j].pop_back();
-				}
-				else
-				{
-					++it;
-				}
-			}
-		}
-	}	
-}
-
-#endif
-
-DT_Polyhedron::DT_Polyhedron(const DT_VertexBase *base, DT_Count count, const DT_Index *indices)
-{
-	assert(count);
-
-	std::vector vertexBuf;
-	DT_Index i;
-	for (i = 0; i != count; ++i) 
-	{
-		vertexBuf.push_back((*base)[indices[i]]);
-	}
-
-	T_IndexBuf *indexBuf = count > 4 ? adjacency_graph(count, &vertexBuf[0], 0) : simplex_adjacency_graph(count, 0);
-	
-	std::vector pointBuf;
-	
-	for (i = 0; i != count; ++i) 
-	{
-		if (!indexBuf[i].empty()) 
-		{
-			pointBuf.push_back(vertexBuf[i]);
-		}
-	}
-			
-	delete [] indexBuf;
-
-	m_count = pointBuf.size();
-	m_verts = new MT_Point3[m_count];	
-	std::copy(pointBuf.begin(), pointBuf.end(), &m_verts[0]);
-
-	T_MultiIndexBuf *cobound = new T_MultiIndexBuf[m_count];
-    char *flags = new char[m_count];
-	std::fill(&flags[0], &flags[m_count], 1);
-
-	DT_Count num_layers = 0;
-	DT_Count layer_count = m_count;
-	while (layer_count > 4)
-	{
-		T_IndexBuf *indexBuf = adjacency_graph(m_count, m_verts, flags);
-		
-		DT_Index i;
-		for (i = 0; i != m_count; ++i) 
-		{
-			if (flags[i])
-			{
-				assert(!indexBuf[i].empty());
-				cobound[i].push_back(indexBuf[i]);
-			}
-		}
-			
-		++num_layers;
-
-		delete [] indexBuf;
-
-		std::fill(&flags[0], &flags[m_count], 0);
-
-		for (i = 0; i != m_count; ++i)
-		{
-			if (cobound[i].size() == num_layers) 
-			{
-				T_IndexBuf& curr_cobound = cobound[i].back();	
-				if (!flags[i] && curr_cobound.size() <= 8)
-				{	
-					DT_Index j;
-					for (j  = 0; j != curr_cobound.size(); ++j)
-					{
-						flags[curr_cobound[j]] = 1;
-					}
-				}
-			}
-		}
-		
-		layer_count = 0;
-		
-		for (i = 0; i != m_count; ++i)
-		{
-			if (flags[i])
-			{
-				++layer_count;
-			}
-		}	
-	}
-	
-	indexBuf = simplex_adjacency_graph(m_count, flags);
-		
-	for (i = 0; i != m_count; ++i) 
-	{
-		if (flags[i])
-		{
-			assert(!indexBuf[i].empty());
-			cobound[i].push_back(indexBuf[i]);
-		}
-	}
-	
-	++num_layers;
-
-	delete [] indexBuf;
-	delete [] flags;
-		
-
-
-#ifdef DK_HIERARCHY
-	prune(m_count, cobound);
-#endif
-
-	m_cobound = new T_MultiIndexArray[m_count];
-
-	for (i = 0; i != m_count; ++i)
-	{
-		new (&m_cobound[i]) T_MultiIndexArray(cobound[i].size());
-		
-		DT_Index j;
-		for (j = 0; j != cobound[i].size(); ++j)
-		{
-			new (&m_cobound[i][j]) DT_IndexArray(cobound[i][j].size(), &cobound[i][j][0]);
-		}
-	}
-		
-	delete [] cobound;
-
-	m_start_vertex = 0;
-	while (m_cobound[m_start_vertex].size() != num_layers) 
-	{
-		++m_start_vertex;
-		assert(m_start_vertex < m_count);
-	}
-
-	m_curr_vertex = m_start_vertex;
-} 
-
-
-DT_Polyhedron::~DT_Polyhedron() 
-{
-	delete [] m_verts;
-    delete [] m_cobound;
-}
-
-#ifdef DK_HIERARCHY
-
-MT_Scalar DT_Polyhedron::supportH(const MT_Vector3& v) const 
-{
-    m_curr_vertex = m_start_vertex;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	int curr_layer;
-	for (curr_layer = m_cobound[m_start_vertex].size(); curr_layer != 0; --curr_layer)
-	{
-		const DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][curr_layer-1];
-        DT_Index i;
-		for (i = 0; i != curr_cobound.size(); ++i) 
-		{
-			d = (*this)[curr_cobound[i]].dot(v);
-			if (d > h)
-			{
-				m_curr_vertex = curr_cobound[i];
-				h = d;
-			}
-		}
-	}
-	
-    return h;
-}
-
-MT_Point3 DT_Polyhedron::support(const MT_Vector3& v) const 
-{
-	m_curr_vertex = m_start_vertex;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	int curr_layer;
-	for (curr_layer = m_cobound[m_start_vertex].size(); curr_layer != 0; --curr_layer)
-	{
-		const DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][curr_layer-1];
-        DT_Index i;
-		for (i = 0; i != curr_cobound.size(); ++i) 
-		{
-			d = (*this)[curr_cobound[i]].dot(v);
-			if (d > h)
-			{
-				m_curr_vertex = curr_cobound[i];
-				h = d;
-			}
-		}
-	}
-	
-    return (*this)[m_curr_vertex];
-}
-
-#else
-
-MT_Scalar DT_Polyhedron::supportH(const MT_Vector3& v) const 
-{
-    int last_vertex = -1;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	
-	for (;;) 
-	{
-        DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][0];
-        int i = 0, n = curr_cobound.size(); 
-        while (i != n && 
-               (curr_cobound[i] == last_vertex || 
-				(d = (*this)[curr_cobound[i]].dot(v)) - h <= MT_abs(h) * MT_EPSILON)) 
-		{
-            ++i;
-		}
-		
-        if (i == n) 
-		{
-			break;
-		}
-		
-        last_vertex = m_curr_vertex;
-        m_curr_vertex = curr_cobound[i];
-        h = d;
-    }
-    return h;
-}
-
-MT_Point3 DT_Polyhedron::support(const MT_Vector3& v) const 
-{
-	int last_vertex = -1;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	
-    for (;;)
-	{
-        DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][0];
-        int i = 0, n = curr_cobound.size();
-        while (i != n && 
-               (curr_cobound[i] == last_vertex || 
-				(d = (*this)[curr_cobound[i]].dot(v)) - h <= MT_abs(h) * MT_EPSILON)) 
-		{
-            ++i;
-		}
-		
-        if (i == n)
-		{
-			break;
-		}
-		
-		last_vertex = m_curr_vertex;
-        m_curr_vertex = curr_cobound[i];
-        h = d;
-    }
-    return (*this)[m_curr_vertex];
-}
-
-#endif
-
-#endif
-
diff --git a/extern/solid/src/convex/DT_Polyhedron.h b/extern/solid/src/convex/DT_Polyhedron.h
deleted file mode 100644
index 58c991bd152..00000000000
--- a/extern/solid/src/convex/DT_Polyhedron.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_POLYHEDRON_H
-#define DT_POLYHEDRON_H
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-# if HAVE_QHULL_QHULL_A_H
-#  define QHULL
-# endif
-#endif
-
-
-#ifdef QHULL
-
-#include "DT_Convex.h"
-#include "DT_IndexArray.h"
-#include "DT_VertexBase.h"
-
-class DT_Polyhedron : public DT_Convex {
-	typedef DT_Array T_MultiIndexArray;
-public:
-	DT_Polyhedron() 
-		: m_verts(0),
-		  m_cobound(0)
-	{}
-		
-	DT_Polyhedron(const DT_VertexBase *base, DT_Count count, const DT_Index *indices);
-
-	virtual ~DT_Polyhedron();
-    
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-	const MT_Point3& operator[](int i) const { return m_verts[i]; }
-    DT_Count numVerts() const { return m_count; }
-
-private:
-	DT_Count              m_count;
-	MT_Point3			 *m_verts;
-	T_MultiIndexArray    *m_cobound;
-    DT_Index              m_start_vertex;
-	mutable DT_Index      m_curr_vertex;
-};
-
-#else 
-
-#include "DT_Polytope.h"
-
-typedef DT_Polytope DT_Polyhedron;
-
-#endif
-
-#endif
-
diff --git a/extern/solid/src/convex/DT_Polytope.cpp b/extern/solid/src/convex/DT_Polytope.cpp
deleted file mode 100644
index e757c3bfdb4..00000000000
--- a/extern/solid/src/convex/DT_Polytope.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Polytope.h"
-
-MT_BBox DT_Polytope::bbox() const 
-{
-	MT_BBox bbox = (*this)[0];
-	DT_Index i;
-    for (i = 1; i < numVerts(); ++i) 
-	{
-        bbox = bbox.hull((*this)[i]);
-    }
-    return bbox;
-}
-
-MT_Scalar DT_Polytope::supportH(const MT_Vector3& v) const 
-{
-    int c = 0;
-    MT_Scalar h = (*this)[0].dot(v), d;
-	DT_Index i;
-    for (i = 1; i < numVerts(); ++i) 
-	{
-        if ((d = (*this)[i].dot(v)) > h) 
-		{ 
-			c = i; 
-			h = d; 
-		}
-    }
-    return h;
-}
-
-MT_Point3 DT_Polytope::support(const MT_Vector3& v) const 
-{
-    int c = 0;
-    MT_Scalar h = (*this)[0].dot(v), d;
-	DT_Index i;
-    for (i = 1; i < numVerts(); ++i)
-	{
-        if ((d = (*this)[i].dot(v)) > h)
-		{ 
-			c = i;
-			h = d; 
-		}
-    }
-    return (*this)[c];
-}
-
-
diff --git a/extern/solid/src/convex/DT_Polytope.h b/extern/solid/src/convex/DT_Polytope.h
deleted file mode 100644
index c715598defe..00000000000
--- a/extern/solid/src/convex/DT_Polytope.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_POLYTOPE_H
-#define DT_POLYTOPE_H
-
-#include "DT_Convex.h"
-#include "DT_IndexArray.h"
-#include "DT_VertexBase.h"
-
-class DT_Polytope : public DT_Convex {
-public:	
-	DT_Polytope() {}
-    DT_Polytope(const DT_VertexBase *base, DT_Count count, const DT_Index *indices) 
-	  : m_base(base), 
-		m_index(count, indices) 
-	{}
- 
-	virtual MT_BBox bbox() const;
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-	MT_Point3 operator[](int i) const { return (*m_base)[m_index[i]]; }
-    DT_Count numVerts() const { return m_index.size(); }
-
-protected:
-    const DT_VertexBase *m_base;
-    DT_IndexArray        m_index;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Shape.h b/extern/solid/src/convex/DT_Shape.h
deleted file mode 100644
index d48942fe515..00000000000
--- a/extern/solid/src/convex/DT_Shape.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_SHAPE_H
-#define DT_SHAPE_H
-
-#include 
-
-#include "MT_BBox.h"
-
-#include "MT_Transform.h"
-
-class DT_Object;
-
-enum DT_ShapeType {
-    COMPLEX,
-    CONVEX
-};
-
-class DT_Shape {
-public:
-    virtual ~DT_Shape() {}
-    virtual DT_ShapeType getType() const = 0;
-	virtual MT_BBox bbox(const MT_Transform& t, MT_Scalar margin) const = 0;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& param, MT_Vector3& normal) const = 0;
-
-protected:
-	DT_Shape()  {}
-};
-
-typedef bool (*Intersect)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						  const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-						  MT_Vector3&);
-
-typedef bool (*Common_point)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						     const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-			                 MT_Vector3&, MT_Point3&, MT_Point3&);
-
-typedef bool (*Penetration_depth)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						          const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                  MT_Vector3&, MT_Point3&, MT_Point3&);
-
-typedef MT_Scalar (*Closest_points)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						            const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									MT_Point3&, MT_Point3&);
-
-#endif
-
-
-
-
-
diff --git a/extern/solid/src/convex/DT_Sphere.cpp b/extern/solid/src/convex/DT_Sphere.cpp
deleted file mode 100644
index 3f2443dcf53..00000000000
--- a/extern/solid/src/convex/DT_Sphere.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Sphere.h"
-#include "GEN_MinMax.h"
-
-MT_Scalar DT_Sphere::supportH(const MT_Vector3& v) const 
-{
-	return m_radius * v.length();
-}
-
-MT_Point3 DT_Sphere::support(const MT_Vector3& v) const 
-{
-   MT_Scalar s = v.length();
-	
-	if (s > MT_Scalar(0.0))
-	{
-		s = m_radius / s;
-		return MT_Point3(v[0] * s, v[1] * s, v[2] * s);
-	}
-	else
-	{
-		return MT_Point3(m_radius, MT_Scalar(0.0), MT_Scalar(0.0));
-	}
-}
-
-bool DT_Sphere::ray_cast(const MT_Point3& source, const MT_Point3& target,
-						 MT_Scalar& param, MT_Vector3& normal) const 
-{
-	MT_Vector3 r = target - source;
-	MT_Scalar  delta = -source.dot(r);  
-	MT_Scalar  r_length2 = r.length2();
-	MT_Scalar  sigma = delta * delta - r_length2 * (source.length2() - m_radius * m_radius);
-
-	if (sigma >= MT_Scalar(0.0))
-		// The line trough source and target intersects the sphere.
-	{
-		MT_Scalar sqrt_sigma = MT_sqrt(sigma);
-		// We need only the sign of lambda2, so the division by the positive 
-		// r_length2 can be left out.
-		MT_Scalar lambda2 = (delta + sqrt_sigma) /* / r_length2 */ ;
-		if (lambda2 >= MT_Scalar(0.0))
-			// The ray points at the sphere
-		{
-			MT_Scalar lambda1 = (delta - sqrt_sigma) / r_length2;
-			if (lambda1 <= param)
-				// The ray hits the sphere, since 
-				// [lambda1, lambda2] overlaps [0, param]. 
-			{
-				if (lambda1 > MT_Scalar(0.0))
-				{
-					param = lambda1;
-					normal = (source + r * lambda1) / m_radius;
-					// NB: division by m_radius to normalize the normal.
-				}
-				else
-				{
-					param = MT_Scalar(0.0);
-					normal.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-				}
-						
-				return true;
-			}
-		}
-	}
-
-	return false;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Sphere.h b/extern/solid/src/convex/DT_Sphere.h
deleted file mode 100644
index 92386a66f3a..00000000000
--- a/extern/solid/src/convex/DT_Sphere.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_SPHERE_H
-#define DT_SPHERE_H
-
-#include "DT_Convex.h"
-
-class DT_Sphere : public DT_Convex {
-public:
-   DT_Sphere(MT_Scalar radius) : m_radius(radius) {}
-	
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-	virtual MT_Point3 support(const MT_Vector3& v) const;
-	
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target,
-						  MT_Scalar& param, MT_Vector3& normal) const;
-
-protected:
-    MT_Scalar m_radius;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Transform.h b/extern/solid/src/convex/DT_Transform.h
deleted file mode 100644
index a976d48d22b..00000000000
--- a/extern/solid/src/convex/DT_Transform.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_TRANSFORM_H
-#define DT_TRANSFORM_H
-
-#include "DT_Convex.h"
-
-class DT_Transform : public DT_Convex {
-public:
-	DT_Transform(const MT_Transform& xform, const DT_Convex& child) :
-		m_xform(xform), 
-		m_child(child)
-	{}
-
-	virtual MT_Scalar supportH(const MT_Vector3& v) const
-	{
-		return m_child.supportH(v * m_xform.getBasis()) + 
-			   v.dot(m_xform.getOrigin());
-	}
-
-	virtual MT_Point3 support(const MT_Vector3& v) const
-	{
-		return m_xform(m_child.support(v * m_xform.getBasis()));
-	}
-
-private:
-	const MT_Transform& m_xform;
-	const DT_Convex&    m_child;
-};
-
-
-#endif
diff --git a/extern/solid/src/convex/DT_Triangle.cpp b/extern/solid/src/convex/DT_Triangle.cpp
deleted file mode 100644
index 1917910b39d..00000000000
--- a/extern/solid/src/convex/DT_Triangle.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-//#define BACKFACE_CULLING
-
-#include "DT_Triangle.h"
-
-MT_BBox DT_Triangle::bbox() const 
-{
-	return MT_BBox((*this)[0]).hull((*this)[1]).hull((*this)[2]);
-}
-
-MT_Scalar DT_Triangle::supportH(const MT_Vector3& v) const
-{
-    return GEN_max(GEN_max(v.dot((*this)[0]), v.dot((*this)[1])), v.dot((*this)[2]));
-}
-
-MT_Point3 DT_Triangle::support(const MT_Vector3& v) const
-{
-    MT_Vector3 dots(v.dot((*this)[0]), v.dot((*this)[1]), v.dot((*this)[2]));
-
-	return (*this)[dots.maxAxis()];
-}
-
-bool DT_Triangle::ray_cast(const MT_Point3& source, const MT_Point3& target, 
-						   MT_Scalar& param, MT_Vector3& normal) const 
-{
-	MT_Vector3 d1 = (*this)[1] - (*this)[0];
-	MT_Vector3 d2 = (*this)[2] - (*this)[0];
-	MT_Vector3 n = d1.cross(d2);
-	MT_Vector3 r = target - source;
-	MT_Scalar delta = -r.dot(n);
-
-   MT_Scalar rounding_error = GEN_max(GEN_max(MT_abs(n[0]), MT_abs(n[1])), MT_abs(n[2])) * MT_EPSILON; 
-
-#ifdef BACKFACE_CULLING	
-   if (delta > rounding_error)
-#else
-	if (MT_abs(delta) > rounding_error)
-#endif      
-		// The ray is not parallel to the triangle's plane. 
-		// (Coplanar rays are ignored.)
-	{
-		MT_Vector3 b = source - (*this)[0];
-		MT_Scalar lambda = b.dot(n) / delta;
-
-		if (MT_Scalar(0.0) <= lambda && lambda <= param)
-			// The ray intersects the triangle's plane.
-		{
-			MT_Vector3 u = b.cross(r);
-			MT_Scalar mu1 = d2.dot(u) / delta;
-
-			if (MT_Scalar(0.0) <= mu1 && mu1 <= MT_Scalar(1.0)) 
-			{
-				MT_Scalar mu2 = -d1.dot(u) / delta;
-
-				if (MT_Scalar(0.0) <= mu2 && mu1 + mu2 <= MT_Scalar(1.0)) 
-					// The ray intersects the triangle.
-				{
-					param = lambda;
-					// Return a normal that points at the source.
-#ifdef BACKFACE_CULLING
-               normal = n;
-#else
-					normal = delta > MT_Scalar(0.0) ? n : -n;
-#endif
-					return true;
-				}
-			}
-		}
-	}
-
-	return false;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Triangle.h b/extern/solid/src/convex/DT_Triangle.h
deleted file mode 100644
index 4192b5629ac..00000000000
--- a/extern/solid/src/convex/DT_Triangle.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_TRIANGLE_H
-#define DT_TRIANGLE_H
-
-#include "SOLID_types.h"
-
-#include "DT_Convex.h"
-#include "DT_IndexArray.h"
-#include "DT_VertexBase.h"
-
-class DT_Triangle : public DT_Convex {
-public:
-    DT_Triangle(const DT_VertexBase *base, DT_Index i0, DT_Index i1, DT_Index i2) : 
-        m_base(base)
-	{
-		m_index[0] = i0;
-		m_index[1] = i1;
-		m_index[2] = i2;
-	}
-
-    DT_Triangle(const DT_VertexBase *base, const DT_Index *index) : 
-        m_base(base)
-	{
-		m_index[0] = index[0];
-		m_index[1] = index[1];
-		m_index[2] = index[2];
-	}
-
-	virtual MT_BBox bbox() const;
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& lambda, MT_Vector3& normal) const;
-
-    MT_Point3 operator[](int i) const { return (*m_base)[m_index[i]]; }
-
-private:
-    const DT_VertexBase *m_base;
-    DT_Index             m_index[3];
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_VertexBase.h b/extern/solid/src/convex/DT_VertexBase.h
deleted file mode 100644
index 37646fdd935..00000000000
--- a/extern/solid/src/convex/DT_VertexBase.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_VERTEXBASE_H
-#define DT_VERTEXBASE_H
-
-#include "MT_Point3.h"
-
-#include 
-
-class DT_Complex;
-
-typedef std::vectorDT_ComplexList;
-
-class DT_VertexBase {
-public:
-    explicit DT_VertexBase(const void *base = 0, DT_Size stride = 0, bool owner = false) : 
-        m_base((char *)base),
-		m_stride(stride ? stride : 3 * sizeof(DT_Scalar)),
-		m_owner(owner)
-	{}
-	
-	~DT_VertexBase()
-	{
-		if (m_owner)
-		{
-			delete [] m_base;
-		}
-	}
-    
-    MT_Point3 operator[](DT_Index i) const 
-	{ 
-        return MT_Point3(reinterpret_cast(m_base + i * m_stride));
-    }
-    
-    void setPointer(const void *base, bool owner = false)
-	{
-		m_base = (char *)base; 
-		m_owner = owner;
-	} 
-	
-    const void *getPointer() const { return m_base; }	
-	bool        isOwner() const { return m_owner; }
-    
-	void addComplex(DT_Complex *complex) const { m_complexList.push_back(complex); }
-	void removeComplex(DT_Complex *complex) const
-	{
-		DT_ComplexList::iterator it = std::find(m_complexList.begin(), m_complexList.end(), complex); 
-		if (it != m_complexList.end())
-		{
-			m_complexList.erase(it);
-		}
-	}
-	
-	const DT_ComplexList& getComplexList() const { return m_complexList; }
-	
-private:    
-    char                  *m_base;
-    DT_Size                m_stride;
-	bool                   m_owner;
-	mutable DT_ComplexList m_complexList;
-};
-
-#endif
diff --git a/extern/solid/src/convex/Makefile b/extern/solid/src/convex/Makefile
deleted file mode 100644
index 75fa578a292..00000000000
--- a/extern/solid/src/convex/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = solid_convex
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../../include -I$(NAN_QHULL)/include
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
-
diff --git a/intern/bsp/test/Makefile b/intern/bsp/test/Makefile
index eebf7470a0f..91e4497b267 100644
--- a/intern/bsp/test/Makefile
+++ b/intern/bsp/test/Makefile
@@ -47,7 +47,7 @@ SLIBS += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
 SLIBS += $(NAN_GHOST)/lib/$(DEBUG_DIR)libghost.a
 SLIBS += $(NAN_STRING)/lib/$(DEBUG_DIR)libstring.a
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin linux freebsd openbsd"))
+ifeq ($(OS),$(findstring $(OS), "darwin linux freebsd openbsd"))
     LLIBS = -L/usr/X11R6/lib -lglut -pthread -lXi -lXmu
 endif
 
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 7bdca7339fc..3b5f6a0caf9 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -38,8 +38,7 @@
 #include 
 
 /* mmap exception */
-#if defined(AMIGA) || defined(__BeOS)
-#elif defined(WIN32)
+#if defined(WIN32)
 #include 
 #include "mmap_win.h"
 #else
@@ -292,9 +291,6 @@ void *MEM_callocN(unsigned int len, const char *str)
 /* note; mmap returns zero'd memory */
 void *MEM_mapallocN(unsigned int len, const char *str)
 {
-#if defined(AMIGA) || defined(__BeOS)
-	return MEM_callocN(len, str);
-#else
 	MemHead *memh;
 
 	mem_lock_thread();
@@ -329,7 +325,6 @@ void *MEM_mapallocN(unsigned int len, const char *str)
 		print_error("Mapalloc returns nill, fallback to regular malloc: len=%d in %s, total %u\n",len, str, mmap_in_use);
 		return MEM_callocN(len, str);
 	}
-#endif
 }
 
 /* Memory statistics print */
@@ -589,10 +584,6 @@ static void rem_memblock(MemHead *memh)
     totblock--;
     mem_in_use -= memh->len;
    
-#if defined(AMIGA) || defined(__BeOS)
-    free(memh);
-#else   
-   
     if(memh->mmap) {
         mmap_in_use -= memh->len;
         if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
@@ -603,7 +594,6 @@ static void rem_memblock(MemHead *memh)
 			memset(memh+1, 255, memh->len);
         free(memh);
 	}
-#endif
 }
 
 static void MemorY_ErroR(const char *block, const char *error)
diff --git a/intern/iksolver/test/Makefile b/intern/iksolver/test/Makefile
index 4ab317f9e9f..ed867ba2a73 100644
--- a/intern/iksolver/test/Makefile
+++ b/intern/iksolver/test/Makefile
@@ -46,7 +46,7 @@ LIBS += $(OCGDIR)/intern/$(LIBNAME)/$(DEBUG_DIR)libiksolver.a
 
 SLIBS += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin linux freebsd openbsd"))
+ifeq ($(OS),$(findstring $(OS), "darwin linux freebsd openbsd"))
     LLIBS = -L/usr/X11R6/lib -lglut -pthread
 endif
 
diff --git a/intern/moto/include/MT_Matrix3x3.h b/intern/moto/include/MT_Matrix3x3.h
index 899a2731588..c6d299d19fd 100644
--- a/intern/moto/include/MT_Matrix3x3.h
+++ b/intern/moto/include/MT_Matrix3x3.h
@@ -98,6 +98,18 @@ public:
         m_el[0][2] = *m++; m_el[1][2] = *m++; m_el[2][2] = *m;
     }
 
+    void setValue3x3(const float *m) {
+        m_el[0][0] = *m++; m_el[1][0] = *m++; m_el[2][0] = *m++;
+        m_el[0][1] = *m++; m_el[1][1] = *m++; m_el[2][1] = *m++;
+        m_el[0][2] = *m++; m_el[1][2] = *m++; m_el[2][2] = *m;
+    }
+
+    void setValue3x3(const double *m) {
+        m_el[0][0] = *m++; m_el[1][0] = *m++; m_el[2][0] = *m++;
+        m_el[0][1] = *m++; m_el[1][1] = *m++; m_el[2][1] = *m++;
+        m_el[0][2] = *m++; m_el[1][2] = *m++; m_el[2][2] = *m;
+    }
+
     void setValue(MT_Scalar xx, MT_Scalar xy, MT_Scalar xz, 
                   MT_Scalar yx, MT_Scalar yy, MT_Scalar yz, 
                   MT_Scalar zx, MT_Scalar zy, MT_Scalar zz) {
@@ -194,6 +206,18 @@ public:
         *m++ = m_el[0][2]; *m++ = m_el[1][2]; *m++ = m_el[2][2]; *m   = 0.0;
     }
 
+    void getValue3x3(float *m) const {
+        *m++ = (float) m_el[0][0]; *m++ = (float) m_el[1][0]; *m++ = (float) m_el[2][0];
+        *m++ = (float) m_el[0][1]; *m++ = (float) m_el[1][1]; *m++ = (float) m_el[2][1];
+        *m++ = (float) m_el[0][2]; *m++ = (float) m_el[1][2]; *m++ = (float) m_el[2][2];
+    }
+
+    void getValue3x3(double *m) const {
+        *m++ = m_el[0][0]; *m++ = m_el[1][0]; *m++ = m_el[2][0];
+        *m++ = m_el[0][1]; *m++ = m_el[1][1]; *m++ = m_el[2][1];
+        *m++ = m_el[0][2]; *m++ = m_el[1][2]; *m++ = m_el[2][2];
+    }
+
     MT_Quaternion getRotation() const;
 
     MT_Matrix3x3& operator*=(const MT_Matrix3x3& m); 
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
index dcc52e2a3e7..646b1a853dc 100644
--- a/intern/string/intern/STR_String.cpp
+++ b/intern/string/intern/STR_String.cpp
@@ -559,7 +559,8 @@ STR_String&	STR_String::TrimLeft()
 {
 	int skip;
 	assertd(pData != NULL);
-	for (skip=0; isSpace(pData[skip]); skip++, Len--);
+	for (skip=0; isSpace(pData[skip]); skip++, Len--)
+		{};
 	memmove(pData, pData+skip, Len+1);
 	return *this;
 }
@@ -598,7 +599,8 @@ STR_String&	STR_String::TrimLeft(char *set)
 {
 	int skip;
 	assertd(pData != NULL);
-	for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--);
+	for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--)
+		{};
 	memmove(pData, pData+skip, Len+1);
 	return *this;
 }
diff --git a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
index e66693cc86f..f6a740ee5b0 100644
--- a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
+++ b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
@@ -43,7 +43,7 @@
 			
 				
 			
+			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+			
 		
 		
 			
 		
 		
 			
 		
 	
diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
index cc464b9101a..63b2b21971f 100644
--- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
@@ -43,7 +43,7 @@
 			
 			
 			
 			
 			
 			
+			
+			
 			
@@ -758,6 +762,10 @@
 				RelativePath="..\..\..\source\blender\editors\space_file\file_ops.c"
 				>
 			
+			
+			
 			
@@ -791,11 +799,11 @@
 			Name="space_info"
 			>
 			
 			
 			
 			
 			
 			
+			
+			
 			
@@ -1351,6 +1363,30 @@
 				>
 			
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	
diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
index 0f3d2b01030..a19c6dce8b0 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
@@ -138,7 +138,7 @@
 			
-			
-			
 			
@@ -684,6 +680,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_main.c"
 				>
 			
+			
+			
 			
@@ -692,6 +692,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_mesh.c"
 				>
 			
+			
+			
 			
@@ -708,6 +712,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_object.c"
 				>
 			
+			
+			
 			
@@ -728,10 +736,6 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_property.c"
 				>
 			
-			
-			
 			
@@ -780,6 +784,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_ui.c"
 				>
 			
+			
+			
 			
@@ -796,6 +804,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm.c"
 				>
 			
+			
+			
 			
diff --git a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
index d99d14c0979..19e47f19d3c 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
@@ -114,7 +114,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
+				AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
 				MinimalRebuild="true"
 				RuntimeLibrary="0"
@@ -182,6 +182,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_armature_gen.c"
 				>
 			
+			
+			
 			
@@ -294,10 +298,6 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_property_gen.c"
 				>
 			
-			
-			
 			
diff --git a/projectfiles_vc9/blender/nodes/nodes.vcproj b/projectfiles_vc9/blender/nodes/nodes.vcproj
index b8b92ac072b..f7dc938d8f2 100644
--- a/projectfiles_vc9/blender/nodes/nodes.vcproj
+++ b/projectfiles_vc9/blender/nodes/nodes.vcproj
@@ -42,7 +42,7 @@
 			
 			
 			
 			
-			
-			
 			
@@ -601,10 +597,6 @@
 				RelativePath="..\..\..\source\gameengine\Ketsji\KX_SG_NodeRelationships.cpp"
 				>
 			
-			
-			
 			
diff --git a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
index fc197d0d1f4..c6edae137b7 100644
--- a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
+++ b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
@@ -43,7 +43,7 @@
 			
 			
 			
 			 1:
+			col.itemO("OBJECT_OT_vertex_group_copy_to_linked", icon="ICON_BLANK1", text="")
+
+		if context.edit_object:
+			row = layout.row(align=True)
+
+			row.itemO("OBJECT_OT_vertex_group_assign", text="Assign")
+			row.itemO("OBJECT_OT_vertex_group_remove_from", text="Remove")
+			row.itemO("OBJECT_OT_vertex_group_select", text="Select")
+			row.itemO("OBJECT_OT_vertex_group_deselect", text="Deselect")
+
+			layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight")
+
+class DATA_PT_shape_keys(DataButtonsPanel):
+	__idname__ = "DATA_PT_shape_keys"
+	__label__ = "Shape Keys"
+	
+	def poll(self, context):
+		return (context.object and context.object.type in ('MESH', 'LATTICE'))
+
+	def draw(self, context):
+		layout = self.layout
+		ob = context.object
+
+		row = layout.row()
+
+		key = ob.data.shape_keys
+
+		row.template_list(key, "keys", ob, "active_shape_key_index")
+
+		col = row.column(align=True)
+		col.itemO("OBJECT_OT_shape_key_add", icon="ICON_ZOOMIN", text="")
+		col.itemO("OBJECT_OT_shape_key_remove", icon="ICON_ZOOMOUT", text="")
+
+		if context.edit_object:
+			layout.enabled = False
+
+class DATA_PT_uv_texture(DataButtonsPanel):
+	__idname__ = "DATA_PT_uv_texture"
+	__label__ = "UV Texture"
+	
+	def draw(self, context):
+		layout = self.layout
+		me = context.mesh
+
+		row = layout.row()
+
+		row.template_list(me, "uv_textures", me, "active_uv_texture_index")
+
+		col = row.column(align=True)
+		col.itemO("MESH_OT_uv_texture_add", icon="ICON_ZOOMIN", text="")
+		col.itemO("MESH_OT_uv_texture_remove", icon="ICON_ZOOMOUT", text="")
+
+class DATA_PT_vertex_colors(DataButtonsPanel):
+	__idname__ = "DATA_PT_vertex_colors"
+	__label__ = "Vertex Colors"
+	
+	def draw(self, context):
+		layout = self.layout
+		me = context.mesh
+
+		row = layout.row()
+
+		row.template_list(me, "vertex_colors", me, "active_vertex_color_index")
+
+		col = row.column(align=True)
+		col.itemO("MESH_OT_vertex_color_add", icon="ICON_ZOOMIN", text="")
+		col.itemO("MESH_OT_vertex_color_remove", icon="ICON_ZOOMOUT", text="")
+
 bpy.types.register(DATA_PT_mesh)
+bpy.types.register(DATA_PT_materials)
+bpy.types.register(DATA_PT_vertex_groups)
+bpy.types.register(DATA_PT_shape_keys)
+bpy.types.register(DATA_PT_uv_texture)
+bpy.types.register(DATA_PT_vertex_colors)
+
diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py
index ecb0590f8e5..953fc1f0974 100644
--- a/release/ui/buttons_data_modifier.py
+++ b/release/ui/buttons_data_modifier.py
@@ -23,68 +23,68 @@ class DATA_PT_modifiers(DataButtonsPanel):
 
 			if box:
 				if md.type == 'ARMATURE':
-					self.armature(box, md)
+					self.armature(box, ob, md)
 				if md.type == 'ARRAY':
-					self.array(box, md)
+					self.array(box, ob, md)
 				if md.type == 'BEVEL':
-					self.bevel(box, md)
+					self.bevel(box, ob, md)
 				if md.type == 'BOOLEAN':
-					self.boolean(box, md)
+					self.boolean(box, ob, md)
 				if md.type == 'BUILD':
-					self.build(box, md)
+					self.build(box, ob, md)
 				if md.type == 'CAST':
-					self.cast(box, md)
+					self.cast(box, ob, md)
 				if md.type == 'CLOTH':
-					self.cloth(box, md)
+					self.cloth(box, ob, md)
 				if md.type == 'COLLISION':
-					self.collision(box, md)
+					self.collision(box, ob, md)
 				if md.type == 'CURVE':
-					self.curve(box, md)
+					self.curve(box, ob, md)
 				if md.type == 'DECIMATE':
-					self.decimate(box, md)
+					self.decimate(box, ob, md)
 				if md.type == 'DISPLACE':
-					self.displace(box, md)
+					self.displace(box, ob, md)
 				if md.type == 'EDGE_SPLIT':
-					self.edgesplit(box, md)
+					self.edgesplit(box, ob, md)
 				if md.type == 'EXPLODE':
-					self.explode(box, md)
+					self.explode(box, ob, md)
 				if md.type == 'FLUID_SIMULATION':
-					self.fluid(box, md)
+					self.fluid(box, ob, md)
 				if md.type == 'HOOK':
-					self.hook(box, md)
+					self.hook(box, ob, md)
 				if md.type == 'LATTICE':
-					self.lattice(box, md)
+					self.lattice(box, ob, md)
 				if md.type == 'MASK':
-					self.mask(box, md)
+					self.mask(box, ob, md)
 				if md.type == 'MESH_DEFORM':
-					self.mesh_deform(box, md)
+					self.mesh_deform(box, ob, md)
 				if md.type == 'MIRROR':
-					self.mirror(box, md)
+					self.mirror(box, ob, md)
 				if md.type == 'MULTIRES':
-					self.multires(box, md)
+					self.multires(box, ob, md)
 				if md.type == 'PARTICLE_INSTANCE':
-					self.particleinstance(box, md)
+					self.particleinstance(box, ob, md)
 				if md.type == 'PARTICLE_SYSTEM':
-					self.particlesystem(box, md)
+					self.particlesystem(box, ob, md)
 				if md.type == 'SHRINKWRAP':
-					self.shrinkwrap(box, md)
+					self.shrinkwrap(box, ob, md)
 				if md.type == 'SIMPLE_DEFORM':
-					self.simpledeform(box, md)
+					self.simpledeform(box, ob, md)
 				if md.type == 'SMOOTH':
-					self.smooth(box, md)
+					self.smooth(box, ob, md)
 				if md.type == 'SOFTBODY':
-					self.softbody(box, md)
+					self.softbody(box, ob, md)
 				if md.type == 'SUBSURF':
-					self.subsurf(box, md)
+					self.subsurf(box, ob, md)
 				if md.type == 'UV_PROJECT':
-					self.uvproject(box, md)
+					self.uvproject(box, ob, md)
 				if md.type == 'WAVE':
-					self.wave(box, md)
+					self.wave(box, ob, md)
 							
-	def armature(self, layout, md):
+	def armature(self, layout, ob, md):
 		layout.itemR(md, "object")
 		row = layout.row()
-		row.itemR(md, "vertex_group")
+		row.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		row.itemR(md, "invert")
 		flow = layout.column_flow()
 		flow.itemR(md, "use_vertex_groups", text="Vertex Groups")
@@ -92,7 +92,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		flow.itemR(md, "quaternion")
 		flow.itemR(md, "multi_modifier")
 		
-	def array(self, layout, md):
+	def array(self, layout, ob, md):
 		layout.itemR(md, "fit_type")
 		if md.fit_type == 'FIXED_COUNT':
 			layout.itemR(md, "count")
@@ -141,7 +141,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "start_cap")
 		col.itemR(md, "end_cap")
 	
-	def bevel(self, layout, md):
+	def bevel(self, layout, ob, md):
 		row = layout.row()
 		row.itemR(md, "width")
 		row.itemR(md, "only_vertices")
@@ -156,11 +156,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			row = layout.row()
 			row.itemR(md, "edge_weight_method", expand=True)
 			
-	def boolean(self, layout, md):
+	def boolean(self, layout, ob, md):
 		layout.itemR(md, "operation")
 		layout.itemR(md, "object")
 		
-	def build(self, layout, md):
+	def build(self, layout, ob, md):
 		split = layout.split()
 		
 		col = split.column()
@@ -175,7 +175,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			
 		
 			
-	def cast(self, layout, md):
+	def cast(self, layout, ob, md):
 		layout.itemR(md, "cast_type")
 		col = layout.column_flow()
 		col.itemR(md, "x")
@@ -184,26 +184,26 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "factor")
 		col.itemR(md, "radius")
 		col.itemR(md, "size")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		#Missing: "OB" and "From Radius"
 		
-	def cloth(self, layout, md):
+	def cloth(self, layout, ob, md):
 		layout.itemL(text="See Cloth panel.")
 		
-	def collision(self, layout, md):
+	def collision(self, layout, ob, md):
 		layout.itemL(text="See Collision panel.")
 		
-	def curve(self, layout, md):
+	def curve(self, layout, ob, md):
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "deform_axis")
 		
-	def decimate(self, layout, md):
+	def decimate(self, layout, ob, md):
 		layout.itemR(md, "ratio")
 		layout.itemR(md, "face_count")
 		
-	def displace(self, layout, md):
-		layout.itemR(md, "vertex_group")
+	def displace(self, layout, ob, md):
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "texture")
 		layout.itemR(md, "midlevel")
 		layout.itemR(md, "strength")
@@ -211,10 +211,10 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		layout.itemR(md, "texture_coordinates")
 		if md.texture_coordinates == 'OBJECT':
 			layout.itemR(md, "texture_coordinate_object", text="Object")
-		if md.texture_coordinates == 'UV':
-			layout.itemR(md, "uv_layer")
+		if md.texture_coordinates == 'UV' and ob.type == 'MESH':
+			layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
 	
-	def edgesplit(self, layout, md):
+	def edgesplit(self, layout, ob, md):
 		split = layout.split()
 		
 		col = split.column()
@@ -225,8 +225,8 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col = split.column()
 		col.itemR(md, "use_sharp", text="Sharp Edges")
 		
-	def explode(self, layout, md):
-		layout.itemR(md, "vertex_group")
+	def explode(self, layout, ob, md):
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "protect")
 		layout.itemR(md, "split_edges")
 		layout.itemR(md, "unborn")
@@ -234,31 +234,31 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		layout.itemR(md, "dead")
 		# Missing: "Refresh" and "Clear Vertex Group" ?
 		
-	def fluid(self, layout, md):
+	def fluid(self, layout, ob, md):
 		layout.itemL(text="See Fluidsim panel.")
 		
-	def hook(self, layout, md):
+	def hook(self, layout, ob, md):
 		layout.itemR(md, "falloff")
 		layout.itemR(md, "force", slider=True)
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		# Missing: "Reset" and "Recenter"
 		
-	def lattice(self, layout, md):
+	def lattice(self, layout, ob, md):
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		
-	def mask(self, layout, md):
+	def mask(self, layout, ob, md):
 		layout.itemR(md, "mode")
 		if md.mode == 'ARMATURE':
 			layout.itemR(md, "armature")
 		if md.mode == 'VERTEX_GROUP':
-			layout.itemR(md, "vertex_group")
+			layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "inverse")
 		
-	def mesh_deform(self, layout, md):
+	def mesh_deform(self, layout, ob, md):
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "invert")
 
 		layout.itemS()
@@ -267,7 +267,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		row.itemR(md, "precision")
 		row.itemR(md, "dynamic")
 		
-	def mirror(self, layout, md):
+	def mirror(self, layout, ob, md):
 		layout.itemR(md, "merge_limit")
 		split = layout.split()
 		
@@ -285,12 +285,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		
 		layout.itemR(md, "mirror_object")
 		
-	def multires(self, layout, md):
+	def multires(self, layout, ob, md):
 		layout.itemR(md, "subdivision_type")
 		layout.itemO("OBJECT_OT_multires_subdivide", text="Subdivide")
 		layout.itemR(md, "level")
 	
-	def particleinstance(self, layout, md):
+	def particleinstance(self, layout, ob, md):
 		layout.itemR(md, "object")
 		layout.itemR(md, "particle_system_number")
 		
@@ -302,12 +302,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "alive")
 		col.itemR(md, "dead")
 		
-	def particlesystem(self, layout, md):
+	def particlesystem(self, layout, ob, md):
 		layout.itemL(text="See Particle panel.")
 		
-	def shrinkwrap(self, layout, md):
+	def shrinkwrap(self, layout, ob, md):
 		layout.itemR(md, "target")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "offset")
 		layout.itemR(md, "subsurf_levels")
 		layout.itemR(md, "mode")
@@ -329,9 +329,9 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			layout.itemR(md, "keep_above_surface")
 		# To-Do: Validate if structs
 		
-	def simpledeform(self, layout, md):
+	def simpledeform(self, layout, ob, md):
 		layout.itemR(md, "mode")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "origin")
 		layout.itemR(md, "relative")
 		layout.itemR(md, "factor")
@@ -340,7 +340,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			layout.itemR(md, "lock_x_axis")
 			layout.itemR(md, "lock_y_axis")
 	
-	def smooth(self, layout, md):
+	def smooth(self, layout, ob, md):
 		split = layout.split()
 		sub = split.column()
 		sub.itemR(md, "x")
@@ -350,12 +350,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		sub.itemR(md, "factor")
 		sub.itemR(md, "repeat")
 		
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		
-	def softbody(self, layout, md):
+	def softbody(self, layout, ob, md):
 		layout.itemL(text="See Softbody panel.")
 	
-	def subsurf(self, layout, md):
+	def subsurf(self, layout, ob, md):
 		layout.itemR(md, "subdivision_type")
 		col = layout.column_flow()
 		col.itemR(md, "levels", text="Preview")
@@ -363,16 +363,17 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "optimal_draw", text="Optimal Display")
 		col.itemR(md, "subsurf_uv")
 	
-	def uvproject(self, layout, md):
-		layout.itemR(md, "uv_layer")
-		layout.itemR(md, "projectors")
-		layout.itemR(md, "image")
-		layout.itemR(md, "horizontal_aspect_ratio")
-		layout.itemR(md, "vertical_aspect_ratio")
-		layout.itemR(md, "override_image")
-		#"Projectors" don't work.
-		
-	def wave(self, layout, md):
+	def uvproject(self, layout, ob, md):
+		if ob.type == 'MESH':
+			layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
+			layout.itemR(md, "projectors")
+			layout.itemR(md, "image")
+			layout.itemR(md, "horizontal_aspect_ratio")
+			layout.itemR(md, "vertical_aspect_ratio")
+			layout.itemR(md, "override_image")
+			#"Projectors" don't work.
+		
+	def wave(self, layout, ob, md):
 		split = layout.split()
 		
 		sub = split.column()
@@ -398,11 +399,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "start_position_y")
 		
 		layout.itemR(md, "start_position_object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "texture")
 		layout.itemR(md, "texture_coordinates")
-		if md.texture_coordinates == 'MAP_UV':
-			layout.itemR(md, "uv_layer")
+		if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
+			layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
 		if md.texture_coordinates == 'OBJECT':
 			layout.itemR(md, "texture_coordinates_object")
 		
@@ -412,4 +413,4 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "width", slider=True)
 		col.itemR(md, "narrowness", slider=True)
 
-bpy.types.register(DATA_PT_modifiers)
\ No newline at end of file
+bpy.types.register(DATA_PT_modifiers)
diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py
index bce16e78a40..5f4cdd3f838 100644
--- a/release/ui/buttons_data_text.py
+++ b/release/ui/buttons_data_text.py
@@ -27,10 +27,10 @@ class DATA_PT_shape_text(DataButtonsPanel):
 		split = layout.split(percentage=0.65)
 
 		if ob:
-			split.template_ID(context, ob, "data")
+			split.template_ID(ob, "data")
 			split.itemS()
 		elif curve:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 			split.itemS()
 
 		if curve:
diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py
index 124fba83608..8b0ef82b628 100644
--- a/release/ui/buttons_material.py
+++ b/release/ui/buttons_material.py
@@ -40,10 +40,10 @@ class MATERIAL_PT_material(MaterialButtonsPanel):
 		split = layout.split(percentage=0.65)
 
 		if ob and slot:
-			split.template_ID(context, slot, "material", new="MATERIAL_OT_new")
+			split.template_ID(slot, "material", new="MATERIAL_OT_new")
 			split.itemR(ob, "active_material_index", text="Active")
 		elif mat:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 			split.itemS()
 
 		if mat:
diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py
index f4507f9149d..f2b0b986ab9 100644
--- a/release/ui/buttons_object_constraint.py
+++ b/release/ui/buttons_object_constraint.py
@@ -67,7 +67,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
 				row.itemR(con, "target_space", text="")
 
 			if target and owner:
-				row.itemL(icon=8) # XXX
+				row.itemL(icon="ICON_ARROW_LEFTRIGHT")
 
 			if owner:
 				row.itemR(con, "owner_space", text="")
@@ -77,13 +77,14 @@ class ConstraintButtonsPanel(bpy.types.Panel):
 		
 		if con.target and subtargets:
 			if con.target.type == "ARMATURE":
-				layout.itemR(con, "subtarget", text="Bone") # XXX autocomplete
+				layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
 				
-				row = layout.row()
-				row.itemL(text="Head/Tail:")
-				row.itemR(con, "head_tail", text="")
+				if con.type == 'COPY_LOCATION':
+					row = layout.row()
+					row.itemL(text="Head/Tail:")
+					row.itemR(con, "head_tail", text="")
 			elif con.target.type in ("MESH", "LATTICE"):
-				layout.itemR(con, "subtarget", text="Vertex Group") # XXX autocomplete
+				layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
 	
 	def child_of(self, layout, con):
 		self.target_template(layout, con)
@@ -528,23 +529,23 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
 class BONE_PT_constraints(ConstraintButtonsPanel):
 	__idname__ = "BONE_PT_constraints"
 	__label__ = "Bone Constraints"
-	__context__ = "constraint"
+	__context__ = "bone"
 
 	def poll(self, context):
 		ob = context.object
-		return (ob and ob.type == "ARMATURE")
+		return (ob and ob.type == "ARMATURE" and context.bone)
 		
 	def draw(self, context):
 		ob = context.object
-		pchan = ob.pose.pose_channels[0] # XXX
+		pchan = ob.pose.pose_channels[context.bone.name]
 		layout = self.layout
 
-		#row = layout.row()
-		#row.item_menu_enumO("BONE_OT_constraint_add", "type")
-		#row.itemL();
+		row = layout.row()
+		row.item_menu_enumO("OBJECT_OT_constraint_add", "type")
+		row.itemL();
 
 		for con in pchan.constraints:
 			self.draw_constraint(con)
 
 bpy.types.register(OBJECT_PT_constraints)
-bpy.types.register(BONE_PT_constraints)
\ No newline at end of file
+bpy.types.register(BONE_PT_constraints)
diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py
index 571cafb709d..49ceaf6aae1 100644
--- a/release/ui/buttons_particle.py
+++ b/release/ui/buttons_particle.py
@@ -7,6 +7,7 @@ def particle_panel_enabled(psys):
 def particle_panel_poll(context):
 	psys = context.particle_system
 	if psys==None:	return False
+	if psys.settings==None:  return False
 	return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
 
 class ParticleButtonsPanel(bpy.types.Panel):
@@ -29,75 +30,51 @@ class PARTICLE_PT_particles(ParticleButtonsPanel):
 		ob = context.object
 		psys = context.particle_system
 
-		split = layout.split(percentage=0.65)
+		if ob:
+			row = layout.row()
 
-		if psys:
-			split.template_ID(context, psys, "settings")
+			row.template_list(ob, "particle_systems", ob, "active_particle_system_index")
 
-			#if ob:
-			#	split.itemR(ob, "active_particle_system_index", text="Active")
+			col = row.column(align=True)
+			col.itemO("OBJECT_OT_particle_system_add", icon="ICON_ZOOMIN", text="")
+			col.itemO("OBJECT_OT_particle_system_remove", icon="ICON_ZOOMOUT", text="")
 
 		if psys:
-			#row = layout.row()
-			#row.itemL(text="Particle system datablock")
-			#row.itemL(text="Viewport")
-			#row.itemL(text="Render")
+			split = layout.split(percentage=0.65)
 			
-			part = psys.settings
-			ptype = psys.settings.type
-			
-			if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
-				layout.itemL(text="No settings for fluid particles")
-				return
-			
-			row = layout.row()
-			row.enabled = particle_panel_enabled(psys)
-			row.itemR(part, "type")
-			row.itemR(psys, "seed")
+			split.template_ID(psys, "settings", new="PARTICLE_OT_new")
 			
-			row = layout.row()
-			if part.type=='HAIR':
-				if psys.editable==True:
-					row.itemO("PARTICLE_OT_editable_set", text="Free Edit")
-				else:
-					row.itemO("PARTICLE_OT_editable_set", text="Make Editable")
-				subrow = row.row()
-				subrow.enabled = particle_panel_enabled(psys)
-				subrow.itemR(part, "hair_step")
-			elif part.type=='REACTOR':
-				row.itemR(psys, "reactor_target_object")
-				row.itemR(psys, "reactor_target_particle_system", text="Particle System")
-		
-		if psys:
 			#row = layout.row()
-			#row.itemL(text="Particle system datablock")
 			#row.itemL(text="Viewport")
 			#row.itemL(text="Render")
 			
 			part = psys.settings
-			ptype = psys.settings.type
 			
-			if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
-				layout.itemL(text="No settings for fluid particles")
-				return
-			
-			row = layout.row()
-			row.enabled = particle_panel_enabled(psys)
-			row.itemR(part, "type", expand=True)
-			
-			
-			row = layout.row()
-			if part.type=='HAIR':
-				if psys.editable==True:
-					row.itemO("PARTICLE_OT_editable_set", text="Free Edit")
-				else:
-					row.itemO("PARTICLE_OT_editable_set", text="Make Editable")
-				subrow = row.row()
-				subrow.enabled = particle_panel_enabled(psys)
-				subrow.itemR(part, "hair_step")
-			elif part.type=='REACTOR':
-				row.itemR(psys, "reactor_target_object")
-				row.itemR(psys, "reactor_target_particle_system", text="Particle System")
+			if part:
+				ptype = psys.settings.type
+				if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
+					layout.itemL(text="No settings for fluid particles")
+					return
+					
+				split = layout.split(percentage=0.65)
+				
+				split.enabled = particle_panel_enabled(psys)
+				split.itemR(part, "type")
+				split.itemR(psys, "seed")
+				
+				split = layout.split(percentage=0.65)
+				if part.type=='HAIR':
+					if psys.editable==True:
+						split.itemO("PARTICLE_OT_editable_set", text="Free Edit")
+					else:
+						split.itemO("PARTICLE_OT_editable_set", text="Make Editable")
+					row = split.row()
+					row.enabled = particle_panel_enabled(psys)
+					row.itemR(part, "hair_step")
+				elif part.type=='REACTOR':
+					split.enabled = particle_panel_enabled(psys)
+					split.itemR(psys, "reactor_target_object")
+					split.itemR(psys, "reactor_target_particle_system", text="Particle System")
 		
 class PARTICLE_PT_emission(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_emission"
@@ -112,9 +89,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
 		layout.enabled = particle_panel_enabled(psys)
 		
 		row = layout.row()
-		#col.itemL(text="TODO: Rate instead of amount")
 		row.itemR(part, "amount")
-		row.itemR(psys, "seed")
 		
 		split = layout.split()
 		
@@ -150,10 +125,12 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
 class PARTICLE_PT_cache(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_cache"
 	__label__ = "Cache"
+	__default_closed__ = True
 	
 	def poll(self, context):
 		psys = context.particle_system
 		if psys==None:	return False
+		if psys.settings==None:  return False
 		return psys.settings.type in ('EMITTER', 'REACTOR')
 
 	def draw(self, context):
@@ -163,15 +140,42 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
 		part = psys.settings
 		cache = psys.point_cache
 		
-		#if cache.baked==True:
-			#layout.itemO("PARTICLE_OT_free_bake", text="BAKE")
-		#else:
 		row = layout.row()
-			#row.itemO("PARTICLE_OT_bake", text="BAKE")
-		row.itemR(cache, "start_frame")
-		row.itemR(cache, "end_frame")
-			
-			#layout.row().itemL(text="No simulation frames in disk cache.")
+		row.itemR(cache, "name")
+		
+		row = layout.row()
+		
+		if cache.baked == True:
+			row.itemO("PTCACHE_OT_free_bake_particle_system", text="Free Bake")
+		else:
+			row.item_booleanO("PTCACHE_OT_cache_particle_system", "bake", True, text="Bake")
+		
+		subrow = row.row()
+		subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
+		subrow.itemO("PTCACHE_OT_cache_particle_system", text="Calculate to Current Frame")
+		
+		row = layout.row()
+		row.enabled = particle_panel_enabled(psys)
+		row.itemO("PTCACHE_OT_bake_from_particles_cache", text="Current Cache to Bake")
+		row.itemR(cache, "step");
+	
+		row = layout.row()
+		row.enabled = particle_panel_enabled(psys)
+		row.itemR(cache, "quick_cache")
+		row.itemR(cache, "disk_cache")
+		
+		layout.itemL(text=cache.info)
+		
+		layout.itemS()
+		
+		row = layout.row()
+		row.item_booleanO("PTCACHE_OT_bake_all", "bake", True, text="Bake All Dynamics")
+		row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
+		layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
+		
+		# for particles these are figured out automatically
+		#row.itemR(cache, "start_frame")
+		#row.itemR(cache, "end_frame")
 
 class PARTICLE_PT_initial(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_initial"
@@ -184,8 +188,6 @@ class PARTICLE_PT_initial(ParticleButtonsPanel):
 		part = psys.settings
 		
 		layout.enabled = particle_panel_enabled(psys)
-		
-		#layout.row().itemL(text="")
 				
 		layout.row().itemL(text="Direction:")
 	
@@ -296,7 +298,10 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 	__label__ = "Render"
 	
 	def poll(self, context):
-		return (context.particle_system != None)
+		psys = context.particle_system
+		if psys==None: return False
+		if psys.settings==None: return False
+		return True;
 		
 	def draw(self, context):
 		layout = self.layout
@@ -304,7 +309,9 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 		psys = context.particle_system
 		part = psys.settings
 		
-		layout.itemR(part, "material")
+		row = layout.row()
+		row.itemR(part, "material")
+		row.itemR(psys, "parent");
 		
 		split = layout.split()
 			
@@ -362,27 +369,14 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 			row = layout.row()
 			col = row.column()
 			
-			
-#			subrow = col.row()
-#			subrow.active = part.render_strand == False
-#			subrow.itemR(part, "render_adaptive")
-#			col = row.column(align=True)
-#			subrow = col.row()
-#			subrow.active = part.render_adaptive or part.render_strand == True
-#			subrow.itemR(part, "adaptive_angle")
-#			subrow = col.row()
-#			subrow.active = part.render_adaptive == True and part.render_strand == False
-#			subrow.itemR(part, "adaptive_pix")
-			
 			if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
 				layout.itemR(part, "enable_simplify")
 				if part.enable_simplify==True:
-					box = layout.box()
-					row = box.row()
+					row = layout.row()
 					row.itemR(part, "simplify_refsize")
 					row.itemR(part, "simplify_rate")
 					row.itemR(part, "simplify_transition")
-					row = box.row()
+					row = layout.row()
 					row.itemR(part, "viewport")
 					subrow = row.row()
 					subrow.active = part.viewport==True
@@ -438,9 +432,13 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 class PARTICLE_PT_draw(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_draw"
 	__label__ = "Display"
+	__default_closed__ = True
 	
 	def poll(self, context):
-		return (context.particle_system != None)
+		psys = context.particle_system
+		if psys==None: return False
+		if psys.settings==None: return False
+		return True;
 	
 	def draw(self, context):
 		layout = self.layout
@@ -490,6 +488,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel):
 class PARTICLE_PT_children(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_children"
 	__label__ = "Children"
+	__default_closed__ = True
 
 	def draw(self, context):
 		layout = self.layout
@@ -557,6 +556,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel):
 class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_vertexgroups"
 	__label__ = "Vertexgroups"
+	__default_closed__ = True
 
 	def draw(self, context):
 		layout = self.layout
diff --git a/release/ui/buttons_physic_cloth.py b/release/ui/buttons_physic_cloth.py
index bd65392ad63..a06c644322a 100644
--- a/release/ui/buttons_physic_cloth.py
+++ b/release/ui/buttons_physic_cloth.py
@@ -43,7 +43,54 @@ class Physic_PT_cloth(PhysicButtonsPanel):
 			col.itemR(cloth, "goal_spring", text="Stiffness")
 			col.itemR(cloth, "goal_friction", text="Friction")
 		"""
+
+class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
+	__idname__= "PHYSICS_PT_cloth_cache"
+	__label__ = "Cache"
+	__default_closed__ = True
+
+	def draw(self, context):
+		layout = self.layout
+
+		cache = context.cloth.point_cache
+		
+		row = layout.row()
+		row.itemR(cache, "name")
+		
+		row = layout.row()
+		row.itemR(cache, "start_frame")
+		row.itemR(cache, "end_frame")
+		
+		row = layout.row()
+		
+		if cache.baked == True:
+			row.itemO("PTCACHE_OT_free_bake_cloth", text="Free Bake")
+		else:
+			row.item_booleanO("PTCACHE_OT_cache_cloth", "bake", True, text="Bake")
+		
+		subrow = row.row()
+		subrow.enabled = cache.frames_skipped or cache.outdated
+		subrow.itemO("PTCACHE_OT_cache_cloth", text="Calculate to Current Frame")
+			
+		row = layout.row()
+		#row.enabled = particle_panel_enabled(psys)
+		row.itemO("PTCACHE_OT_bake_from_cloth_cache", text="Current Cache to Bake")
+		row.itemR(cache, "step");
 	
+		row = layout.row()
+		#row.enabled = particle_panel_enabled(psys)
+		row.itemR(cache, "quick_cache")
+		row.itemR(cache, "disk_cache")
+		
+		layout.itemL(text=cache.info)
+		
+		layout.itemS()
+		
+		row = layout.row()
+		row.itemO("PTCACHE_OT_bake_all", "bake", True, text="Bake All Dynamics")
+		row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
+		layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
+		
 class Physic_PT_cloth_collision(PhysicButtonsPanel):
 	__idname__ = "Physic_PT_clothcollision"
 	__label__ = "Cloth Collision"
@@ -102,5 +149,6 @@ class Physic_PT_cloth_stiffness(PhysicButtonsPanel):
 		sub.itemR(cloth, "bending_stiffness_max", text="Max")
 		
 bpy.types.register(Physic_PT_cloth)
+bpy.types.register(PHYSICS_PT_cloth_cache)
 bpy.types.register(Physic_PT_cloth_collision)
 bpy.types.register(Physic_PT_cloth_stiffness)
diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py
index de166cef796..31908d5ec9c 100644
--- a/release/ui/buttons_texture.py
+++ b/release/ui/buttons_texture.py
@@ -43,7 +43,7 @@ class TEXTURE_PT_texture(TextureButtonsPanel):
 
 		if ma or la or wo:
 			if slot:
-				split.template_ID(context, slot, "texture", new="TEXTURE_OT_new")
+				split.template_ID(slot, "texture", new="TEXTURE_OT_new")
 			else:
 				split.itemS()
 
@@ -54,7 +54,7 @@ class TEXTURE_PT_texture(TextureButtonsPanel):
 			elif wo:
 				split.itemR(wo, "active_texture_index", text="Active")
 		elif tex:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 			split.itemS()
 
 		layout.itemS()
diff --git a/release/ui/buttons_world.py b/release/ui/buttons_world.py
index d9516cb7900..39b5eca04ff 100644
--- a/release/ui/buttons_world.py
+++ b/release/ui/buttons_world.py
@@ -37,9 +37,9 @@ class WORLD_PT_world(WorldButtonsPanel):
 		split = layout.split(percentage=0.65)
 
 		if scene:
-			split.template_ID(context, scene, "world", new="WORLD_OT_new")
+			split.template_ID(scene, "world", new="WORLD_OT_new")
 		elif world:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 
 		split.itemS()
 
diff --git a/release/ui/space_buttons.py b/release/ui/space_buttons.py
new file mode 100644
index 00000000000..cae9a813433
--- /dev/null
+++ b/release/ui/space_buttons.py
@@ -0,0 +1,36 @@
+
+import bpy
+
+class Buttons_HT_header(bpy.types.Header):
+	__space_type__ = "BUTTONS_WINDOW"
+	__idname__ = "BUTTONS_HT_header"
+
+	def draw(self, context):
+		layout = self.layout
+		
+		so = context.space_data
+		scene = context.scene
+
+		layout.template_header()
+
+		if context.area.show_menus:
+			row = layout.row(align=True)
+			row.itemM("Buttons_MT_view", text="View")
+			
+		row = layout.row()
+		row.itemR(so, "buttons_context", expand=True, text="")
+		row.itemR(scene, "current_frame")
+
+class Buttons_MT_view(bpy.types.Menu):
+	__space_type__ = "BUTTONS_WINDOW"
+	__label__ = "View"
+
+	def draw(self, context):
+		layout = self.layout
+		so = context.space_data
+
+		col = layout.column()
+		col.itemR(so, "panel_alignment", expand=True)
+
+bpy.types.register(Buttons_HT_header)
+bpy.types.register(Buttons_MT_view)
diff --git a/release/ui/space_filebrowser.py b/release/ui/space_filebrowser.py
new file mode 100644
index 00000000000..820134d3e87
--- /dev/null
+++ b/release/ui/space_filebrowser.py
@@ -0,0 +1,65 @@
+
+import bpy
+
+
+class FILEBROWSER_HT_header(bpy.types.Header):
+	__space_type__ = "FILE_BROWSER"
+	__idname__ = "FILEBROWSER_HT_header"
+
+	def draw(self, context):
+		st = context.space_data
+		layout = self.layout
+		
+		params = st.params 
+		layout.template_header()
+
+		if context.area.show_menus:
+			row = layout.row()
+			row.itemM("FILEBROWSER_MT_directory")
+			row.itemM("FILEBROWSER_MT_bookmarks")
+			
+		row = layout.row(align=True)
+		row.itemO("FILE_OT_parent", text="", icon='ICON_FILE_PARENT')
+		row.itemO("FILE_OT_refresh", text="", icon='ICON_FILE_REFRESH')
+
+		layout.itemR(params, "display", expand=True, text="")
+		layout.itemR(params, "sort", expand=True, text="")
+		
+		layout.itemR(params, "hide_dot")
+		layout.itemR(params, "do_filter")
+		
+		row = layout.row(align=True)
+		row.itemR(params, "filter_folder", text="");
+		row.itemR(params, "filter_blender", text="");
+		row.itemR(params, "filter_image", text="");
+		row.itemR(params, "filter_movie", text="");
+		row.itemR(params, "filter_script", text="");
+		row.itemR(params, "filter_font", text="");
+		row.itemR(params, "filter_sound", text="");
+		row.itemR(params, "filter_text", text="");
+
+		row.active = params.do_filter
+
+class FILEBROWSER_MT_directory(bpy.types.Menu):
+	__space_type__ = "FILE_BROWSER"
+	__label__ = "Directory"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.itemO("FILE_OT_refresh", text="Refresh", icon='ICON_FILE_REFRESH')
+		layout.itemO("FILE_OT_parent", text="Parent", icon='ICON_FILE_PARENT')
+		
+class FILEBROWSER_MT_bookmarks(bpy.types.Menu):
+	__space_type__ = "FILE_BROWSER"
+	__label__ = "Bookmarks"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.itemO("FILE_OT_add_bookmark", text="Add current directory", icon='ICON_BOOKMARKS')
+
+		
+bpy.types.register(FILEBROWSER_HT_header)
+bpy.types.register(FILEBROWSER_MT_directory)
+bpy.types.register(FILEBROWSER_MT_bookmarks)
diff --git a/release/ui/space_image.py b/release/ui/space_image.py
index 3623b914942..49ef18705c4 100644
--- a/release/ui/space_image.py
+++ b/release/ui/space_image.py
@@ -9,6 +9,7 @@ class IMAGE_MT_view(bpy.types.Menu):
 		layout = self.layout
 		sima = context.space_data
 		uv = sima.uv_editor
+		settings = context.scene.tool_settings
 
 		show_uvedit = sima.show_uvedit
 
@@ -17,8 +18,8 @@ class IMAGE_MT_view(bpy.types.Menu):
 		layout.itemS()
 
 		layout.itemR(sima, "update_automatically")
-		# XXX if show_uvedit:
-		# XXX	layout.itemR(uv, "local_view") # "UV Local View", Numpad /
+		if show_uvedit:
+			layout.itemR(settings, "uv_local_view") # Numpad /
 
 		layout.itemS()
 
@@ -95,9 +96,9 @@ class IMAGE_MT_image(bpy.types.Menu):
 				else:
 					layout.itemO("IMAGE_OT_pack")
 
-				# only for dirty && specific image types : XXX poll?
-				#if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
-				if False:
+				# only for dirty && specific image types, perhaps
+				# this could be done in operator poll too
+				if ima.dirty:
 					if ima.source in ("FILE", "GENERATED") and ima.type != "MULTILAYER":
 						layout.item_booleanO("IMAGE_OT_pack", "as_png", True, text="Pack As PNG")
 
@@ -156,7 +157,7 @@ class IMAGE_MT_uvs(bpy.types.Menu):
 		layout = self.layout
 		sima = context.space_data
 		uv = sima.uv_editor
-		scene = context.scene
+		settings = context.scene.tool_settings
 
 		layout.itemR(uv, "snap_to_pixels")
 		layout.itemR(uv, "constrain_to_image_bounds")
@@ -177,18 +178,18 @@ class IMAGE_MT_uvs(bpy.types.Menu):
 
 		layout.itemS()
 
-		layout.itemM(context, "IMAGE_MT_uvs_transform")
-		layout.itemM(context, "IMAGE_MT_uvs_mirror")
-		layout.itemM(context, "IMAGE_MT_uvs_weldalign")
+		layout.itemM("IMAGE_MT_uvs_transform")
+		layout.itemM("IMAGE_MT_uvs_mirror")
+		layout.itemM("IMAGE_MT_uvs_weldalign")
 
 		layout.itemS()
 
-		# XXX layout.itemR(scene, "proportional_editing")
-		layout.item_menu_enumR(scene, "proportional_editing_falloff")
+		layout.itemR(settings, "proportional_editing")
+		layout.item_menu_enumR(settings, "proportional_editing_falloff")
 
 		layout.itemS()
 
-		layout.itemM(context, "IMAGE_MT_uvs_showhide")
+		layout.itemM("IMAGE_MT_uvs_showhide")
 
 class IMAGE_HT_header(bpy.types.Header):
 	__space_type__ = "IMAGE_EDITOR"
@@ -196,29 +197,33 @@ class IMAGE_HT_header(bpy.types.Header):
 	def draw(self, context):
 		sima = context.space_data
 		ima = sima.image
+		iuser = sima.image_user
 		layout = self.layout
+		settings = context.scene.tool_settings
 
 		show_render = sima.show_render
 		show_paint = sima.show_paint
 		show_uvedit = sima.show_uvedit
 
-		layout.template_header(context)
+		layout.template_header()
 
 		# menus
 		if context.area.show_menus:
 			row = layout.row()
-			row.itemM(context, "IMAGE_MT_view")
+			row.itemM("IMAGE_MT_view")
 
 			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_select")
+				row.itemM("IMAGE_MT_select")
 
-			# XXX menuname= (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))? "Image*": "Image";
-			row.itemM(context, "IMAGE_MT_image")
+			if ima and ima.dirty:
+				row.itemM("IMAGE_MT_image", text="Image*")
+			else:
+				row.itemM("IMAGE_MT_image", text="Image")
 
 			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_uvs")
+				row.itemM("IMAGE_MT_uvs")
 
-		layout.template_ID(context, sima, "image", new="IMAGE_OT_new", open="IMAGE_OT_open")
+		layout.template_ID(sima, "image", new="IMAGE_OT_new", open="IMAGE_OT_open")
 
 		"""
 		/* image select */
@@ -250,109 +255,34 @@ class IMAGE_HT_header(bpy.types.Header):
 
 		# uv editing
 		if show_uvedit:
-			pass
-		
-		"""
-		/* uv editing */
-		if(show_uvedit) {
-			/* pivot */
-			uiDefIconTextButS(block, ICONTEXTROW, B_NOP, ICON_ROTATE,
-					"Pivot: %t|Bounding Box Center %x0|Median Point %x3|2D Cursor %x1",
-					xco,yco,XIC+10,YIC, &ar->v2d.around, 0, 3.0, 0, 0,
-					"Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period)");
-			xco+= XIC + 18;
-			
-			/* selection modes */
-			uiDefIconButBitS(block, TOG, UV_SYNC_SELECTION, B_REDR, ICON_EDIT, xco,yco,XIC,YIC, &scene->toolsettings->uv_flag, 0, 0, 0, 0, "Sync UV and Mesh Selection");
-			xco+= XIC+8;
-
-			if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-				uiBlockBeginAlign(block);
-				
-				uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
-
-				uiBlockEndAlign(block);
-			}
-			else {
-				uiBlockBeginAlign(block);
-
-				uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_VERTEX, 0, 0, "Vertex select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_EDGE, 0, 0, "Edge select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_FACE, 0, 0, "Face select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_LINKEDSEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_ISLAND, 0, 0, "Island select mode");
-
-				uiBlockEndAlign(block);
-
-				/* would use these if const's could go in strings 
-				 * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
-				but = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
-						"Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
-						xco+=XIC+10,yco,XIC+10,YIC, &(sima->sticky), 0, 3.0, 0, 0,
-						"Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
-			}
-
-			xco+= XIC + 16;
-			
-			/* snap options, identical to options in 3d view header */
-			uiBlockBeginAlign(block);
-
-			if (scene->snap_flag & SCE_SNAP) {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
-				xco+= XIC;
-				uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
-				xco+= 70;
-			}
-			else {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
-				xco+= XIC;
-			}
+			uvedit = sima.uv_editor
 
-			uiBlockEndAlign(block);
-			xco+= 8;
+			layout.itemS()
 
-			/* uv layers */
-			{
-				Object *obedit= CTX_data_edit_object(C);
-				char menustr[34*MAX_MTFACE];
-				static int act;
-				
-				image_menu_uvlayers(obedit, menustr, &act);
+			layout.itemR(uvedit, "pivot", text="")
+			layout.itemR(settings, "uv_sync_selection", text="")
 
-				but = uiDefButI(block, MENU, B_NOP, menustr ,xco,yco,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing.");
-				// uiButSetFunc(but, do_image_buttons_set_uvlayer_callback, &act, NULL);
-				
-				xco+= 85;
-			}
+			if settings.uv_sync_selection:
+				layout.itemR(settings, "mesh_selection_mode", text="", expand=True)
+			else:
+				layout.itemR(settings, "uv_selection_mode", text="", expand=True)
+				layout.itemR(uvedit, "sticky_selection_mode", text="")
+			pass
 
-			xco+= 8;
-		}
-		"""
+			row = layout.row(align=True)
+			row.itemR(settings, "snap", text="")
+			if settings.snap:
+				row.itemR(settings, "snap_mode", text="")
 
-		if ima:
 			"""
-			RenderResult *rr;
-		
-			/* render layers and passes */
-			rr= BKE_image_get_renderresult(scene, ima);
-			if(rr) {
-				uiBlockBeginAlign(block);
-#if 0
-				uiblock_layer_pass_buttons(block, rr, &sima->iuser, B_REDR, xco, 0, 160);
-#endif
-				uiBlockEndAlign(block);
-				xco+= 166;
-			}
+			mesh = context.edit_object.data
+			row.item_pointerR(mesh, "active_uv_layer", mesh, "uv_layers")
 			"""
 
+		if ima:
+			# layers
+			layout.template_image_layers(ima, iuser)
+
 			# painting
 			layout.itemR(sima, "image_painting", text="")
 
@@ -373,6 +303,10 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
 	__region_type__ = "UI"
 	__label__ = "Game Properties"
 
+	def poll(self, context):
+		sima = context.space_data
+		return (sima and sima.image)
+
 	def draw(self, context):
 		sima = context.space_data
 		layout = self.layout
@@ -382,446 +316,74 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
 		if ima:
 			split = layout.split()
 
-			col = split.column(align=True)
-			col.itemR(ima, "animated")
+			col = split.column()
+
+			subcol = col.column(align=True)
+			subcol.itemR(ima, "clamp_x")
+			subcol.itemR(ima, "clamp_y")
+
+			col.itemR(ima, "mapping", expand=True)
+			col.itemR(ima, "tiles")
+
+			col = split.column()
+
+			subcol = col.column(align=True)
+			subcol.itemR(ima, "animated")
 
-			subcol = col.column()
+			subcol = subcol.column()
 			subcol.itemR(ima, "animation_start", text="Start")
 			subcol.itemR(ima, "animation_end", text="End")
 			subcol.itemR(ima, "animation_speed", text="Speed")
 			subcol.active = ima.animated
 
-			col = split.column()
-			col.itemR(ima, "tiles")
-
 			subrow = col.row(align=True)
 			subrow.itemR(ima, "tiles_x", text="X")
 			subrow.itemR(ima, "tiles_y", text="Y")
-			subrow.active = ima.tiles
-
-			col.itemS()
-			col.itemR(ima, "clamp_x")
-			col.itemR(ima, "clamp_y")
+			subrow.active = ima.tiles or ima.animated
 
-			col.itemR(ima, "mapping", expand=True)
-
-bpy.types.register(IMAGE_MT_view)
-bpy.types.register(IMAGE_MT_select)
-bpy.types.register(IMAGE_MT_image)
-bpy.types.register(IMAGE_MT_uvs_showhide)
-bpy.types.register(IMAGE_MT_uvs_transform)
-bpy.types.register(IMAGE_MT_uvs_mirror)
-bpy.types.register(IMAGE_MT_uvs_weldalign)
-bpy.types.register(IMAGE_MT_uvs)
-bpy.types.register(IMAGE_HT_header)
-bpy.types.register(IMAGE_PT_game_properties)
-
-
-import bpy
-
-class IMAGE_MT_view(bpy.types.Menu):
+class IMAGE_PT_view_properties(bpy.types.Panel):
 	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "View"
+	__region_type__ = "UI"
+	__label__ = "View Properties"
 
-	def draw(self, context):
-		layout = self.layout
+	def poll(self, context):
 		sima = context.space_data
-		uv = sima.uv_editor
-
-		show_uvedit = sima.show_uvedit
-
-		layout.itemO("IMAGE_OT_properties") # icon
-
-		layout.itemS()
-
-		layout.itemR(sima, "update_automatically")
-		# XXX if show_uvedit:
-		# XXX	layout.itemR(uv, "local_view") # "UV Local View", Numpad /
-
-		layout.itemS()
-
-		layout.itemO("IMAGE_OT_view_zoom_in")
-		layout.itemO("IMAGE_OT_view_zoom_out")
-
-		layout.itemS()
-
-		ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]];
-
-		for a, b in ratios:
-			text = "Zoom %d:%d" % (a, b)
-			layout.item_floatO("IMAGE_OT_view_zoom_ratio", "ratio", a/b, text=text)
-
-		layout.itemS()
-
-		if show_uvedit:
-			layout.itemO("IMAGE_OT_view_selected")
-
-		layout.itemO("IMAGE_OT_view_all")
-		layout.itemO("SCREEN_OT_screen_full_area")
-
-class IMAGE_MT_select(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Select"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.itemO("UV_OT_select_border")
-		layout.item_booleanO("UV_OT_select_border", "pinned", True)
-
-		layout.itemS()
-		
-		layout.itemO("UV_OT_select_all_toggle")
-		layout.itemO("UV_OT_select_invert")
-		layout.itemO("UV_OT_unlink_selection")
-		
-		layout.itemS()
-
-		layout.itemO("UV_OT_select_pinned")
-		layout.itemO("UV_OT_select_linked")
-
-class IMAGE_MT_image(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Image"
+		return (sima and (sima.image or sima.show_uvedit))
 
 	def draw(self, context):
-		layout = self.layout
 		sima = context.space_data
-		ima = sima.image
-
-		layout.itemO("IMAGE_OT_new")
-		layout.itemO("IMAGE_OT_open")
-
-		show_render = sima.show_render
-
-		if ima:
-			if show_render:
-				layout.itemO("IMAGE_OT_replace")
-				layout.itemO("IMAGE_OT_reload")
-
-			layout.itemO("IMAGE_OT_save")
-			layout.itemO("IMAGE_OT_save_as")
-
-			if ima.source == "SEQUENCE":
-				layout.itemO("IMAGE_OT_save_sequence")
-
-			if not show_render:
-				layout.itemS()
-
-				if ima.packed_file:
-					layout.itemO("IMAGE_OT_unpack")
-				else:
-					layout.itemO("IMAGE_OT_pack")
-
-				# only for dirty && specific image types : XXX poll?
-				#if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
-				if False:
-					if ima.source in ("FILE", "GENERATED") and ima.type != "MULTILAYER":
-						layout.item_booleanO("IMAGE_OT_pack", "as_png", True, text="Pack As PNG")
-
-			layout.itemS()
-
-			layout.itemR(sima, "image_painting")
-
-class IMAGE_MT_uvs_showhide(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Show/Hide Faces"
-
-	def draw(self, context):
 		layout = self.layout
 
-		layout.itemO("UV_OT_reveal")
-		layout.itemO("UV_OT_hide")
-		layout.item_booleanO("UV_OT_hide", "unselected", True)
-
-class IMAGE_MT_uvs_transform(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Transform"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.item_enumO("TFM_OT_transform", "mode", "TRANSLATION")
-		layout.item_enumO("TFM_OT_transform", "mode", "ROTATION")
-		layout.item_enumO("TFM_OT_transform", "mode", "RESIZE")
-
-class IMAGE_MT_uvs_mirror(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Mirror"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.item_enumO("UV_OT_mirror", "axis", "MIRROR_X") # "X Axis", M, 
-		layout.item_enumO("UV_OT_mirror", "axis", "MIRROR_Y") # "Y Axis", M, 
-
-class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Weld/Align"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.itemO("UV_OT_weld") # W, 1
-		layout.items_enumO("UV_OT_align", "axis") # W, 2/3/4
-
-
-class IMAGE_MT_uvs(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "UVs"
-
-	def draw(self, context):
-		layout = self.layout
-		sima = context.space_data
-		uv = sima.uv_editor
-		scene = context.scene
-
-		layout.itemR(uv, "snap_to_pixels")
-		layout.itemR(uv, "constrain_to_image_bounds")
-
-		layout.itemS()
-
-		layout.itemR(uv, "live_unwrap")
-		layout.itemO("UV_OT_unwrap")
-		layout.item_booleanO("UV_OT_pin", "clear", True, text="Unpin")
-		layout.itemO("UV_OT_pin")
-
-		layout.itemS()
-
-		layout.itemO("UV_OT_pack_islands")
-		layout.itemO("UV_OT_average_islands_scale")
-		layout.itemO("UV_OT_minimize_stretch")
-		layout.itemO("UV_OT_stitch")
-
-		layout.itemS()
-
-		layout.itemM(context, "IMAGE_MT_uvs_transform")
-		layout.itemM(context, "IMAGE_MT_uvs_mirror")
-		layout.itemM(context, "IMAGE_MT_uvs_weldalign")
-
-		layout.itemS()
-
-		# XXX layout.itemR(scene, "proportional_editing")
-		layout.item_menu_enumR(scene, "proportional_editing_falloff")
-
-		layout.itemS()
-
-		layout.itemM(context, "IMAGE_MT_uvs_showhide")
-
-class IMAGE_HT_header(bpy.types.Header):
-	__space_type__ = "IMAGE_EDITOR"
-
-	def draw(self, context):
-		sima = context.space_data
 		ima = sima.image
-		layout = self.layout
-
-		show_render = sima.show_render
-		show_paint = sima.show_paint
 		show_uvedit = sima.show_uvedit
+		uvedit = sima.uv_editor
 
-		layout.template_header(context)
-
-		# menus
-		if context.area.show_menus:
-			row = layout.row()
-			row.itemM(context, "IMAGE_MT_view")
-
-			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_select")
-
-			# XXX menuname= (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))? "Image*": "Image";
-			row.itemM(context, "IMAGE_MT_image")
-
-			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_uvs")
-
-		layout.template_ID(context, sima, "image", new="IMAGE_OT_new", open="IMAGE_OT_open")
-
-		"""
-		/* image select */
-
-		pinflag= (show_render)? 0: UI_ID_PIN;
-		xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)sima->image, ID_IM, &sima->pin, xco, yco,
-			sima_idpoin_handle, UI_ID_BROWSE|UI_ID_BROWSE_RENDER|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|pinflag);
-		xco += 8;
-		"""
-
-		"""
-		if(ima && !ELEM3(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_VIEWER) && ima->ok) {
-			/* XXX this should not be a static var */
-			static int headerbuttons_packdummy;
-			
-			headerbuttons_packdummy = 0;
-
-			if (ima->packedfile) {
-				headerbuttons_packdummy = 1;
-			}
-			if (ima->packedfile && ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
-				uiDefIconButBitI(block, TOG, 1, 0 /* XXX B_SIMA_REPACK */, ICON_UGLYPACKAGE,	xco,yco,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Re-Pack this image as PNG");
-			else
-				uiDefIconButBitI(block, TOG, 1, 0 /* XXX B_SIMAPACKIMA */, ICON_PACKAGE,	xco,yco,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
-				
-			xco+= XIC+8;
-		}
-		"""
-
-		# uv editing
-		if show_uvedit:
-			pass
-		
-		"""
-		/* uv editing */
-		if(show_uvedit) {
-			/* pivot */
-			uiDefIconTextButS(block, ICONTEXTROW, B_NOP, ICON_ROTATE,
-					"Pivot: %t|Bounding Box Center %x0|Median Point %x3|2D Cursor %x1",
-					xco,yco,XIC+10,YIC, &ar->v2d.around, 0, 3.0, 0, 0,
-					"Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period)");
-			xco+= XIC + 18;
-			
-			/* selection modes */
-			uiDefIconButBitS(block, TOG, UV_SYNC_SELECTION, B_REDR, ICON_EDIT, xco,yco,XIC,YIC, &scene->toolsettings->uv_flag, 0, 0, 0, 0, "Sync UV and Mesh Selection");
-			xco+= XIC+8;
-
-			if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-				uiBlockBeginAlign(block);
-				
-				uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
-
-				uiBlockEndAlign(block);
-			}
-			else {
-				uiBlockBeginAlign(block);
-
-				uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_VERTEX, 0, 0, "Vertex select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_EDGE, 0, 0, "Edge select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_FACE, 0, 0, "Face select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_LINKEDSEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_ISLAND, 0, 0, "Island select mode");
-
-				uiBlockEndAlign(block);
-
-				/* would use these if const's could go in strings 
-				 * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
-				but = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
-						"Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
-						xco+=XIC+10,yco,XIC+10,YIC, &(sima->sticky), 0, 3.0, 0, 0,
-						"Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
-			}
-
-			xco+= XIC + 16;
-			
-			/* snap options, identical to options in 3d view header */
-			uiBlockBeginAlign(block);
-
-			if (scene->snap_flag & SCE_SNAP) {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
-				xco+= XIC;
-				uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
-				xco+= 70;
-			}
-			else {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
-				xco+= XIC;
-			}
-
-			uiBlockEndAlign(block);
-			xco+= 8;
-
-			/* uv layers */
-			{
-				Object *obedit= CTX_data_edit_object(C);
-				char menustr[34*MAX_MTFACE];
-				static int act;
-				
-				image_menu_uvlayers(obedit, menustr, &act);
-
-				but = uiDefButI(block, MENU, B_NOP, menustr ,xco,yco,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing.");
-				// uiButSetFunc(but, do_image_buttons_set_uvlayer_callback, &act, NULL);
-				
-				xco+= 85;
-			}
-
-			xco+= 8;
-		}
-		"""
-
-		if ima:
-			"""
-			RenderResult *rr;
-		
-			/* render layers and passes */
-			rr= BKE_image_get_renderresult(scene, ima);
-			if(rr) {
-				uiBlockBeginAlign(block);
-#if 0
-				uiblock_layer_pass_buttons(block, rr, &sima->iuser, B_REDR, xco, 0, 160);
-#endif
-				uiBlockEndAlign(block);
-				xco+= 166;
-			}
-			"""
-
-			# painting
-			layout.itemR(sima, "image_painting", text="")
-
-			# draw options
-			row = layout.row(align=True)
-			row.itemR(sima, "draw_channels", text="", expand=True)
-
-			row = layout.row(align=True)
-			if ima.type == "COMPOSITE":
-				row.itemO("IMAGE_OT_record_composite", icon="ICON_REC")
-			if ima.type == "COMPOSITE" and ima.source in ("MOVIE", "SEQUENCE"):
-				row.itemO("IMAGE_OT_play_composite", icon="ICON_PLAY")
-		
-		layout.itemR(sima, "update_automatically", text="")
-
-class IMAGE_PT_game_properties(bpy.types.Panel):
-	__space_type__ = "IMAGE_EDITOR"
-	__region_type__ = "UI"
-	__label__ = "Game Properties"
-
-	def draw(self, context):
-		sima = context.space_data
-		layout = self.layout
-
-		ima = sima.image
+		split = layout.split()
 
+		col = split.column()
 		if ima:
-			split = layout.split()
-
-			col = split.column(align=True)
-			col.itemR(ima, "animated")
-
-			subcol = col.column()
-			subcol.itemR(ima, "animation_start", text="Start")
-			subcol.itemR(ima, "animation_end", text="End")
-			subcol.itemR(ima, "animation_speed", text="Speed")
-			subcol.active = ima.animated
+			col.itemR(ima, "display_aspect")
 
 			col = split.column()
-			col.itemR(ima, "tiles")
-
-			subrow = col.row(align=True)
-			subrow.itemR(ima, "tiles_x", text="X")
-			subrow.itemR(ima, "tiles_y", text="Y")
-			subrow.active = ima.tiles
-
-			col.itemS()
-			col.itemR(ima, "clamp_x")
-			col.itemR(ima, "clamp_y")
+			col.itemR(sima, "draw_repeated", text="Repeat")
+			if show_uvedit:
+				col.itemR(uvedit, "normalized_coordinates", text="Normalized")
+		elif show_uvedit:
+			col.itemR(uvedit, "normalized_coordinates", text="Normalized")
 
-			col.itemR(ima, "mapping", expand=True)
+		if show_uvedit:
+			col = layout.column()
+			row = col.row()
+			row.itemR(uvedit, "edge_draw_type", expand=True)
+			row = col.row()
+			row.itemR(uvedit, "draw_smooth_edges", text="Smooth")
+			row.itemR(uvedit, "draw_modified_edges", text="Modified")
+
+			row = col.row()
+			row.itemR(uvedit, "draw_stretch", text="Stretch")
+			row.itemR(uvedit, "draw_stretch_type", text="")
+			#col.itemR(uvedit, "draw_edges")
+			#col.itemR(uvedit, "draw_faces")
 
 bpy.types.register(IMAGE_MT_view)
 bpy.types.register(IMAGE_MT_select)
@@ -833,4 +395,5 @@ bpy.types.register(IMAGE_MT_uvs_weldalign)
 bpy.types.register(IMAGE_MT_uvs)
 bpy.types.register(IMAGE_HT_header)
 bpy.types.register(IMAGE_PT_game_properties)
+bpy.types.register(IMAGE_PT_view_properties)
 
diff --git a/release/ui/space_info.py b/release/ui/space_info.py
new file mode 100644
index 00000000000..de3346711e9
--- /dev/null
+++ b/release/ui/space_info.py
@@ -0,0 +1,119 @@
+
+import bpy
+
+class INFO_HT_header(bpy.types.Header):
+	__space_type__ = "USER_PREFERENCES"
+	__idname__ = "INFO_HT_header"
+
+	def draw(self, context):
+		st = context.space_data
+		layout = self.layout
+		
+		layout.template_header()
+
+		if context.area.show_menus:
+			row = layout.row()
+			row.itemM("INFO_MT_file")
+			row.itemM("INFO_MT_add")
+			row.itemM("INFO_MT_timeline")
+			row.itemM("INFO_MT_game")
+			row.itemM("INFO_MT_render")
+			row.itemM("INFO_MT_help")
+
+		layout.template_ID(context.window, "screen") #, new="SCREEN_OT_new", open="SCREEN_OT_unlink")
+		layout.template_ID(context.screen, "scene") #, new="SCENE_OT_new", unlink="SCENE_OT_unlink")
+
+		layout.itemS()
+
+		layout.template_operator_search()
+		layout.template_running_jobs()
+			
+class INFO_MT_file(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "File"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.operator_context = "EXEC_AREA"
+		layout.itemO("WM_OT_read_homefile")
+		layout.operator_context = "INVOKE_AREA"
+		layout.itemO("WM_OT_open_mainfile")
+
+		layout.itemS()
+
+		layout.operator_context = "EXEC_AREA"
+		layout.itemO("WM_OT_save_mainfile")
+		layout.operator_context = "INVOKE_AREA"
+		layout.itemO("WM_OT_save_as_mainfile")
+
+		layout.itemS()
+
+		layout.itemM("INFO_MT_file_external_data")
+
+class INFO_MT_file_external_data(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "External Data"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.itemO("FILE_OT_pack_all", text="Pack into .blend file")
+		layout.itemO("FILE_OT_unpack_all", text="Unpack into Files...")
+
+		layout.itemS()
+
+		layout.itemO("FILE_OT_make_paths_relative")
+		layout.itemO("FILE_OT_make_paths_absolute")
+		layout.itemO("FILE_OT_report_missing_files")
+		layout.itemO("FILE_OT_find_missing_files")
+
+class INFO_MT_add(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Add"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_timeline(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Timeline"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_game(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Game"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_render(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Render"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_help(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Help"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+bpy.types.register(INFO_HT_header)
+bpy.types.register(INFO_MT_file)
+bpy.types.register(INFO_MT_file_external_data)
+bpy.types.register(INFO_MT_add)
+bpy.types.register(INFO_MT_timeline)
+bpy.types.register(INFO_MT_game)
+bpy.types.register(INFO_MT_render)
+bpy.types.register(INFO_MT_help)
+
diff --git a/release/ui/space_logic.py b/release/ui/space_logic.py
index 71d94c86bf3..f862f6e2667 100644
--- a/release/ui/space_logic.py
+++ b/release/ui/space_logic.py
@@ -5,6 +5,10 @@ class LOGIC_PT_physics(bpy.types.Panel):
 	__region_type__ = "UI"
 	__label__ = "Physics"
 
+	def poll(self, context):
+		ob = context.active_object
+		return ob and ob.game
+
 	def draw(self, context):
 		layout = self.layout
 		ob = context.active_object
@@ -56,6 +60,10 @@ class LOGIC_PT_collision_bounds(bpy.types.Panel):
 	__space_type__ = "LOGIC_EDITOR"
 	__region_type__ = "UI"
 	__label__ = "Collision Bounds"
+
+	def poll(self, context):
+		ob = context.active_object
+		return ob and ob.game
 	
 	def draw_header(self, context):
 		layout = self.layout
diff --git a/release/ui/space_outliner.py b/release/ui/space_outliner.py
index f039eb3f7c3..5a6ee5ea2aa 100644
--- a/release/ui/space_outliner.py
+++ b/release/ui/space_outliner.py
@@ -10,11 +10,11 @@ class OUTLINER_HT_header(bpy.types.Header):
 		sce = context.scene
 		layout = self.layout
 
-		layout.template_header(context)
+		layout.template_header()
 
 		if context.area.show_menus:
 			row = layout.row(align=True)
-			row.itemM(context, "OUTLINER_MT_view")
+			row.itemM("OUTLINER_MT_view")
 			
 		row = layout.row()
 		row.itemR(so, "display_mode", text="")
diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py
index 94858db81ad..b64e7d8e0c4 100644
--- a/release/ui/space_sequencer.py
+++ b/release/ui/space_sequencer.py
@@ -15,21 +15,21 @@ class SEQUENCER_HT_header(bpy.types.Header):
 		st = context.space_data
 		layout = self.layout
 
-		layout.template_header(context)
+		layout.template_header()
 		
 		if context.area.show_menus:
 			row = layout.row()
-			row.itemM(context, "SEQUENCER_MT_view")
+			row.itemM("SEQUENCER_MT_view")
 			
 			row.itemR(st, "display_mode")
 			
 			layout.itemS()
 			
 			if st.display_mode == 'SEQUENCER':
-				row.itemM(context, "SEQUENCER_MT_select")
-				row.itemM(context, "SEQUENCER_MT_marker")
-				row.itemM(context, "SEQUENCER_MT_add")
-				row.itemM(context, "SEQUENCER_MT_strip")
+				row.itemM("SEQUENCER_MT_select")
+				row.itemM("SEQUENCER_MT_marker")
+				row.itemM("SEQUENCER_MT_add")
+				row.itemM("SEQUENCER_MT_strip")
 				layout.itemS()
 				row.itemO("SEQUENCER_OT_reload")
 			else:
@@ -151,7 +151,7 @@ class SEQUENCER_MT_add(bpy.types.Menu):
 		layout.itemO("SEQUENCER_OT_sound_strip_add", text="Sound (Ram)")
 		layout.item_booleanO("SEQUENCER_OT_sound_strip_add", "hd", True, text="Sound (Streaming)") # FFMPEG ONLY
 		
-		layout.itemM(context, "SEQUENCER_MT_add_effect")
+		layout.itemM("SEQUENCER_MT_add_effect")
 
 
 class SEQUENCER_MT_add_effect(bpy.types.Menu):
diff --git a/release/ui/space_text.py b/release/ui/space_text.py
index 42e5347ce6a..07e43f32054 100644
--- a/release/ui/space_text.py
+++ b/release/ui/space_text.py
@@ -1,10 +1,6 @@
 
 import bpy
 
-# temporary
-ICON_TEXT = 120
-ICON_HELP = 1
-
 class TEXT_HT_header(bpy.types.Header):
 	__space_type__ = "TEXT_EDITOR"
 	__idname__ = "TEXT_HT_header"
@@ -14,14 +10,14 @@ class TEXT_HT_header(bpy.types.Header):
 		text = st.text
 		layout = self.layout
 
-		layout.template_header(context)
+		layout.template_header()
 
 		if context.area.show_menus:
 			row = layout.row()
-			row.itemM(context, "TEXT_MT_text")
+			row.itemM("TEXT_MT_text")
 			if text:
-				row.itemM(context, "TEXT_MT_edit")
-				row.itemM(context, "TEXT_MT_format")
+				row.itemM("TEXT_MT_edit")
+				row.itemM("TEXT_MT_format")
 
 		if text and text.modified:
 			row = layout.row()
@@ -33,7 +29,7 @@ class TEXT_HT_header(bpy.types.Header):
 		row.itemR(st, "word_wrap", text="")
 		row.itemR(st, "syntax_highlight", text="")
 
-		layout.template_ID(context, st, "text", new="TEXT_OT_new", open="TEXT_OT_open", unlink="TEXT_OT_unlink")
+		layout.template_ID(st, "text", new="TEXT_OT_new", unlink="TEXT_OT_unlink")
 
 		if text:
 			row = layout.row()
@@ -217,9 +213,9 @@ class TEXT_MT_edit(bpy.types.Menu):
 
 		layout.itemS()
 
-		layout.itemM(context, "TEXT_MT_edit_view")
-		layout.itemM(context, "TEXT_MT_edit_select")
-		layout.itemM(context, "TEXT_MT_edit_markers")
+		layout.itemM("TEXT_MT_edit_view")
+		layout.itemM("TEXT_MT_edit_select")
+		layout.itemM("TEXT_MT_edit_markers")
 
 		layout.itemS()
 
@@ -228,7 +224,7 @@ class TEXT_MT_edit(bpy.types.Menu):
 
 		layout.itemS()
 
-		layout.itemM(context, "TEXT_MT_edit_to3d")
+		layout.itemM("TEXT_MT_edit_to3d")
 
 bpy.types.register(TEXT_HT_header)
 bpy.types.register(TEXT_PT_properties)
diff --git a/source/Makefile b/source/Makefile
index 2df57f58c73..62eb25acbc1 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -115,25 +115,16 @@ ifneq ($(NAN_NO_KETSJI),true)
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
     COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
     COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid_broad.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid_complex.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid_convex.a
-    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/fuzzics/$(DEBUG_DIR)libfuzzics.a
     COMLIB += $(NAN_QHULL)/lib/libqhull.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/blode/$(DEBUG_DIR)libblode.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/blphys/blbullet/$(DEBUG_DIR)libblbullet.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
     COMLIB += $(OCGDIR)/gameengine/logic/$(DEBUG_DIR)liblogic.a
@@ -143,8 +134,6 @@ ifneq ($(NAN_NO_KETSJI),true)
     COMLIB += $(OCGDIR)/gameengine/expression/$(DEBUG_DIR)libexpression.a
     COMLIB += $(OCGDIR)/gameengine/scenegraph/$(DEBUG_DIR)libscenegraph.a
     COMLIB += $(OCGDIR)/gameengine/videotex/$(DEBUG_DIR)libvideotex.a
-#    COMLIB += $(OCGDIR)/sumo/$(DEBUG_DIR)libfuzzics.a
-#    COMLIB += $(OCGDIR)/sumo/$(DEBUG_DIR)libsolid.a
     COMLIB += $(NAN_MOTO)/lib/libmoto.a
     COMLIB += $(NAN_SND_LIBS)
     COMLIB += $(OCGDIR)/kernel/gen_system/$(DEBUG_DIR)libgen_system.a
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index a53b15673e2..a9e3d50211f 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -37,7 +37,6 @@ ADD_SUBDIRECTORY(imbuf/intern/cineon)
 ADD_SUBDIRECTORY(gpu)
 ADD_SUBDIRECTORY(makesdna)
 ADD_SUBDIRECTORY(makesrna)
-ADD_SUBDIRECTORY(radiosity)
 ADD_SUBDIRECTORY(readblenfile)
 ADD_SUBDIRECTORY(render)
 ADD_SUBDIRECTORY(blenfont)
diff --git a/source/blender/Makefile b/source/blender/Makefile
index 64eb1a2614b..31636f838c3 100644
--- a/source/blender/Makefile
+++ b/source/blender/Makefile
@@ -31,7 +31,7 @@
 include nan_definitions.mk
 
 DIRS = windowmanager editors blenloader readblenfile
-DIRS += avi imbuf render radiosity blenlib blenkernel blenpluginapi
+DIRS += avi imbuf render blenlib blenkernel blenpluginapi
 DIRS += makesdna makesrna
 DIRS += python nodes gpu
 DIRS += blenfont
diff --git a/source/blender/SConscript b/source/blender/SConscript
index 691fbf9b494..a064850c170 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -13,7 +13,6 @@ SConscript(['avi/SConscript',
             'imbuf/intern/cineon/SConscript',
             'makesdna/SConscript',
             'makesrna/SConscript',
-            'radiosity/SConscript',
             'readblenfile/SConscript',
             'render/SConscript',
             'nodes/SConscript',
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index e871de490f3..2ee31a17fa6 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -90,6 +90,21 @@ void BLF_kerning(float space);
 void BLF_enable(int option);
 void BLF_disable(int option);
 
+/*
+ * Shadow options, level is the blur level, can be 3, 5 or 0 and
+ * the other argument are the rgba color.
+ * Take care that shadow need to be enable using BLF_enable!!.
+ */
+void BLF_shadow(int level, float r, float g, float b, float a);
+
+/*
+ * Set the offset for shadow text, this is the current cursor
+ * position plus this offset, don't need call BLF_position before
+ * this function, the current position is calculate only on
+ * BLF_draw, so it's safe call this whenever you like.
+ */
+void BLF_shadow_offset(int x, int y);
+
 /*
  * Search the path directory to the locale files, this try all
  * the case for Linux, Win and Mac.
@@ -119,6 +134,8 @@ void BLF_dir_free(char **dirs, int count);
 #define BLF_CLIPPING (1<<1)
 #define BLF_FONT_KERNING (1<<2)
 #define BLF_USER_KERNING (1<<3)
+#define BLF_SHADOW (1<<4)
+#define BLF_OVERLAP_CHAR (1<<5)
 
 /* font->mode. */
 #define BLF_MODE_TEXTURE 0
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index f06c7fb0d28..9dad5a4bfa0 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -500,3 +500,28 @@ void BLF_kerning(float space)
 	if (font)
 		font->kerning= space;
 }
+
+void BLF_shadow(int level, float r, float g, float b, float a)
+{
+	FontBLF *font;
+
+	font= global_font[global_font_cur];
+	if (font) {
+		font->shadow= level;
+		font->shadow_col[0]= r;
+		font->shadow_col[1]= g;
+		font->shadow_col[2]= b;
+		font->shadow_col[3]= a;
+	}
+}
+
+void BLF_shadow_offset(int x, int y)
+{
+	FontBLF *font;
+
+	font= global_font[global_font_cur];
+	if (font) {
+		font->shadow_x= x;
+		font->shadow_y= y;
+	}
+}
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index 88b0105a292..92dfe8457b0 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_dir.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index ee4ba0ee71a..a3c5232cc76 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -146,20 +146,22 @@ void blf_font_draw(FontBLF *font, char *str)
 
 			if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
 				pen_x += delta.x >> 6;
-/*
-				if (pen_x < old_pen_x)
-					pen_x= old_pen_x;
-*/
+
+				if (font->flags & BLF_OVERLAP_CHAR) {
+					if (pen_x < old_pen_x)
+						pen_x= old_pen_x;
+				}
 			}
 		}
 
 		if (font->flags & BLF_USER_KERNING) {
 			old_pen_x= pen_x;
 			pen_x += font->kerning;
-/*
-			if (pen_x < old_pen_x)
-				pen_x= old_pen_x;
-*/
+
+			if (font->flags & BLF_OVERLAP_CHAR) {
+				if (pen_x < old_pen_x)
+					pen_x= old_pen_x;
+			}
 		}
 
 		/* do not return this loop if clipped, we want every character tested */
@@ -228,20 +230,22 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
 
 			if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
 				pen_x += delta.x >> 6;
-/*
-				if (pen_x < old_pen_x)
-					old_pen_x= pen_x;
-*/
+
+				if (font->flags & BLF_OVERLAP_CHAR) {
+					if (pen_x < old_pen_x)
+						pen_x= old_pen_x;
+				}
 			}
 		}
 
 		if (font->flags & BLF_USER_KERNING) {
 			old_pen_x= pen_x;
 			pen_x += font->kerning;
-/*
-			if (pen_x < old_pen_x)
-				old_pen_x= pen_x;
-*/
+
+			if (font->flags & BLF_OVERLAP_CHAR) {
+				if (pen_x < old_pen_x)
+					pen_x= old_pen_x;
+			}
 		}
 
 		gbox.xmin= g->box.xmin + pen_x;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 33a435cc5be..a637774d7bf 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -496,8 +496,20 @@ int blf_glyph_texture_render(FontBLF *font, GlyphBLF *g, float x, float y)
 	GLint cur_tex;
 	float dx, dx1;
 	float y1, y2;
+	float xo, yo;
+	float color[4];
 
 	gt= g->tex_data;
+	xo= 0.0f;
+	yo= 0.0f;
+
+	if (font->flags & BLF_SHADOW) {
+		xo= x;
+		yo= y;
+		x += font->shadow_x;
+		y += font->shadow_y;
+	}
+
 	dx= floor(x + gt->pos_x);
 	dx1= dx + gt->width;
 	y1= y + gt->pos_y;
@@ -518,6 +530,27 @@ int blf_glyph_texture_render(FontBLF *font, GlyphBLF *g, float x, float y)
 	if (cur_tex != gt->tex)
 		glBindTexture(GL_TEXTURE_2D, gt->tex);
 
+	if (font->flags & BLF_SHADOW) {
+		glGetFloatv(GL_CURRENT_COLOR, color);
+		glColor4fv(font->shadow_col);
+
+		if (font->shadow == 3)
+			blf_texture3_draw(gt->uv, dx, y1, dx1, y2);
+		else if (font->shadow == 5)
+			blf_texture5_draw(gt->uv, dx, y1, dx1, y2);
+		else
+			blf_texture_draw(gt->uv, dx, y1, dx1, y2);
+
+		glColor4fv(color);
+		x= xo;
+		y= yo;
+
+		dx= floor(x + gt->pos_x);
+		dx1= dx + gt->width;
+		y1= y + gt->pos_y;
+		y2= y + gt->pos_y - gt->height;
+	}
+
 	if (font->blur==3)
 		blf_texture3_draw(gt->uv, dx, y1, dx1, y2);
 	else if (font->blur==5)
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index af237690b58..c9bdc428ebb 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_internal.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index ba988c522f0..5382ac19aae 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_internal_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -154,6 +154,16 @@ typedef struct FontBLF {
 	
 	/* blur: 3 or 5 large kernel */
 	int blur;
+
+	/* shadow level. */
+	int shadow;
+
+	/* and shadow offset. */
+	int shadow_x;
+	int shadow_y;
+
+	/* shadow color. */
+	float shadow_col[4];
 	
 	/* this is the matrix that we load before rotate/scale/translate. */
 	float mat[4][4];
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 757a18f0165..024172d6db4 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_lang.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index e09be838f06..4270c677338 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -46,6 +46,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BKE_collision.h"
 
@@ -245,8 +246,8 @@ void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving );
 void bvhselftree_update_from_cloth ( ClothModifierData *clmd, int moving );
 
 // needed for editmesh.c
-void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr );
-int cloth_read_cache ( Object *ob, ClothModifierData *clmd, float framenr );
+void cloth_write_cache( Object *ob, ClothModifierData *clmd, int framenr );
+int cloth_read_cache( Scene *scene, Object *ob, ClothModifierData *clmd, float framenr, int *old_framenr );
 
 // needed for button_object.c
 void cloth_clear_cache ( Object *ob, ClothModifierData *clmd, float framenr );
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 1845665a96d..f536e117b7b 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BKE_context.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -131,6 +131,7 @@ void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
    - the dir listbase consits of LinkData items */
 
 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
+PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
 ListBase CTX_data_collection_get(const bContext *C, const char *member);
 ListBase CTX_data_dir_get(const bContext *C);
 void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
diff --git a/source/blender/blenkernel/BKE_exotic.h b/source/blender/blenkernel/BKE_exotic.h
index 11dc1f41109..5c47eeabfe8 100644
--- a/source/blender/blenkernel/BKE_exotic.h
+++ b/source/blender/blenkernel/BKE_exotic.h
@@ -47,7 +47,6 @@ int BKE_read_exotic(struct Scene *scene, char *name);
 
 void write_dxf(struct Scene *scene, char *str);
 void write_vrml(struct Scene *scene, char *str);
-void write_videoscape(struct Scene *scene, char *str);
 void write_stl(struct Scene *scene, char *str);
 
 #endif
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 581285be21c..1892c8e71a4 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BDR_gpencil.h 19541 2009-04-05 06:54:47Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 38a1d9b13b7..382754ee2b2 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -39,6 +39,8 @@ struct Material;
 struct ID;
 struct Object;
 
+/* materials */
+
 void init_def_material(void);
 void free_material(struct Material *sc); 
 void test_object_materials(struct ID *id);
@@ -47,15 +49,22 @@ struct Material *add_material(char *name);
 struct Material *copy_material(struct Material *ma);
 void make_local_material(struct Material *ma);
 
+void automatname(struct Material *);
+
+/* material slots */
+
 struct Material ***give_matarar(struct Object *ob);
 short *give_totcolp(struct Object *ob);
 struct Material *give_current_material(struct Object *ob, int act);
 struct ID *material_from(struct Object *ob, int act);
 void assign_material(struct Object *ob, struct Material *ma, int act);
-void new_material_to_objectdata(struct Object *ob);
 
 int find_material_index(struct Object *ob, struct Material *ma);
 
+void object_add_material_slot(struct Object *ob);
+void object_remove_material_slot(struct Object *ob);
+
+/* rendering */
 
 void init_render_material(struct Material *, int, float *);
 void init_render_materials(int, float *);
@@ -64,12 +73,8 @@ void end_render_materials(void);
 
 int material_in_material(struct Material *parmat, struct Material *mat);
 
-void automatname(struct Material *);
-void delete_material_index(struct Object *ob);            
-
 void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col);
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index 2d5acc51b7b..efd930d375a 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -31,31 +31,43 @@
 #ifndef BKE_PACKEDFILE_H
 #define BKE_PACKEDFILE_H
 
-#define RET_OK 0
-#define RET_ERROR 1
+#define RET_OK		0
+#define RET_ERROR	1
 
-struct PackedFile;
-struct VFont;
 struct bSample;
 struct bSound;
 struct Image;
+struct Main;
+struct PackedFile;
+struct ReportList;
+struct VFont;
+
+/* pack */
+struct PackedFile *newPackedFile(struct ReportList *reports, char *filename);
+struct PackedFile *newPackedFileMemory(void *mem, int memlen);
+
+void packAll(struct Main *bmain, struct ReportList *reports);
+
+/* unpack */
+char *unpackFile(struct ReportList *reports, char *abs_name, char *local_name, struct PackedFile *pf, int how);
+int unpackVFont(struct ReportList *reports, struct VFont *vfont, int how);
+int unpackSample(struct ReportList *reports, struct bSample *sample, int how);
+int unpackImage(struct ReportList *reports, struct Image *ima, int how);
+void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
+
+int writePackedFile(struct ReportList *reports, char *filename, struct PackedFile *pf, int guimode);
+
+/* free */
+void freePackedFile(struct PackedFile *pf);
+
+/* info */
+int countPackedFiles(struct Main *bmain);
+int checkPackedFile(char *filename, struct PackedFile *pf);
+
+/* read */
+int seekPackedFile(struct PackedFile *pf, int offset, int whence);
+void rewindPackedFile(struct PackedFile *pf);
+int readPackedFile(struct PackedFile *pf, void *data, int size);
 
-struct PackedFile * newPackedFile(char * filename);
-struct PackedFile * newPackedFileMemory(void *mem, int memlen);
-
-int seekPackedFile(struct PackedFile * pf, int offset, int whence);
-void rewindPackedFile(struct PackedFile * pf);
-int readPackedFile(struct PackedFile * pf, void * data, int size);
-int countPackedFiles(void);
-void freePackedFile(struct PackedFile * pf);
-void packAll(void);
-int writePackedFile(char * filename, struct PackedFile *pf, int guimode);
-int checkPackedFile(char * filename, struct PackedFile * pf);
-char * unpackFile(char * abs_name, char * local_name, struct PackedFile * pf, int how);
-int unpackVFont(struct VFont * vfont, int how);
-int unpackSample(struct bSample *sample, int how);
-int unpackImage(struct Image * ima, int how);
-void unpackAll(int how);
-	
 #endif
 
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 4efd9a7f8ba..73f0195d1d8 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -217,6 +217,8 @@ char *psys_menu_string(struct Object *ob, int for_sb);
 
 struct ParticleSystem *psys_get_current(struct Object *ob);
 short psys_get_current_num(struct Object *ob);
+void psys_set_current_num(Object *ob, int index);
+struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
 //struct ParticleSystem *psys_get(struct Object *ob, int index);
 struct ParticleData *psys_get_selected_particle(struct ParticleSystem *psys, int *index);
 struct ParticleKey *psys_get_selected_key(struct ParticleSystem *psys, int pa_index, int *key_index);
@@ -249,6 +251,8 @@ void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int tim
 void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
 struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
 
+void object_add_particle_system(struct Scene *scene, struct Object *ob);
+void object_remove_particle_system(struct Scene *scene, struct Object *ob);
 struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
 struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
 void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
@@ -290,10 +294,13 @@ void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, str
 void psys_init_effectors(struct Scene *scene, struct Object *obsrc, struct Group *group, struct ParticleSystem *psys);
 void psys_end_effectors(struct ParticleSystem *psys);
 
+void psys_get_pointcache_start_end(struct Scene *scene, struct ParticleSystem *psys, int *sfra, int *efra);
+
 void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
 
 /* ----------- functions needed only inside particlesystem ------------ */
 /* particle.c */
+void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity);
 void psys_key_to_object(struct Object *ob, struct ParticleKey *key, float imat[][4]);
 //void psys_key_to_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
 //void psys_key_from_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 8ef3ff4d4b7..3f1c45d28ec 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -31,6 +31,8 @@
 
 #include "DNA_ID.h"
 
+#include "MEM_guardedalloc.h"
+
 /* Point cache clearing option, for BKE_ptcache_id_clear, before
  * and after are non inclusive (they wont remove the cfra) */
 #define PTCACHE_CLEAR_ALL		0
@@ -42,6 +44,7 @@
 #define PTCACHE_RESET_DEPSGRAPH		0
 #define PTCACHE_RESET_BAKED			1
 #define PTCACHE_RESET_OUTDATED		2
+#define PTCACHE_RESET_FREE			3
 
 /* Add the blendfile name after blendcache_ */
 #define PTCACHE_EXT ".bphys"
@@ -56,6 +59,11 @@
 #define PTCACHE_TYPE_PARTICLES	1
 #define PTCACHE_TYPE_CLOTH		2
 
+/* PTCache read return code */
+#define PTCACHE_READ_EXACT				1
+#define PTCACHE_READ_INTERPOLATED		2
+#define PTCACHE_READ_OLD				3
+
 /* Structs */
 struct Object;
 struct Scene;
@@ -80,6 +88,40 @@ typedef struct PTCacheID {
 	struct PointCache *cache;
 } PTCacheID;
 
+typedef struct PTCacheWriter {
+	struct PTCacheID *pid;
+	int cfra;
+	int totelem;
+
+	void (*set_elem)(int index, void *calldata, float *data);
+	void *calldata;
+} PTCacheWriter;
+
+typedef struct PTCacheReader {
+	struct Scene *scene;
+	struct PTCacheID *pid;
+	float cfra;
+	int totelem;
+
+	void (*set_elem)(int elem_index, void *calldata, float *data);
+	void (*interpolate_elem)(int index, void *calldata, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2);
+	void *calldata;
+
+	int *old_frame;
+} PTCacheReader;
+
+typedef struct PTCacheBaker {
+	struct Scene *scene;
+	int bake;
+	int render;
+	int quick_step;
+	struct PTCacheID *pid;
+	int (*break_test)(void *data);
+	void *break_data;
+	void (*progressbar)(void *data, int num);
+	void *progresscontext;
+} PTCacheBaker;
+
 /* Creating ID's */
 void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb);
 void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
@@ -93,9 +135,9 @@ void BKE_ptcache_remove(void);
 /* ID specific functions */
 void	BKE_ptcache_id_clear(PTCacheID *id, int mode, int cfra);
 int		BKE_ptcache_id_exist(PTCacheID *id, int cfra);
-int		BKE_ptcache_id_reset(PTCacheID *id, int mode);
+int		BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode);
 void	BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale);
-int		BKE_ptcache_object_reset(struct Object *ob, int mode);
+int		BKE_ptcache_object_reset(struct Scene *scene, struct Object *ob, int mode);
 
 /* File reading/writing */
 PTCacheFile	*BKE_ptcache_file_open(PTCacheID *id, int mode, int cfra);
@@ -103,6 +145,12 @@ void         BKE_ptcache_file_close(PTCacheFile *pf);
 int          BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot);
 int          BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot);
 
+void BKE_ptcache_update_info(PTCacheID *pid);
+
+/* General cache reading/writing */
+int			 BKE_ptcache_read_cache(PTCacheReader *reader);
+int			 BKE_ptcache_write_cache(PTCacheWriter *writer);
+
 /* Continue physics */
 void BKE_ptcache_set_continue_physics(struct Scene *scene, int enable);
 int BKE_ptcache_get_continue_physics(void);
@@ -112,4 +160,9 @@ struct PointCache *BKE_ptcache_add(void);
 void BKE_ptcache_free(struct PointCache *cache);
 struct PointCache *BKE_ptcache_copy(struct PointCache *cache);
 
+/* Baking */
+void BKE_ptcache_quick_cache_all(struct Scene *scene);
+void BKE_ptcache_make_cache(struct PTCacheBaker* baker);
+void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid);
+
 #endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 60e48004fb1..1bb7152fbf3 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BKE_report.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,7 +34,10 @@ extern "C" {
 
 #include "DNA_listBase.h"
 
-/* Reporting Information and Errors */
+/* Reporting Information and Errors
+ *
+ * These functions also accept NULL in case no error reporting
+ * is needed. */
 
 typedef enum ReportType {
 	RPT_DEBUG					= 0,
diff --git a/source/blender/blenkernel/BKE_sequence.h b/source/blender/blenkernel/BKE_sequence.h
index 93f68f00d2f..65a3b0216fe 100644
--- a/source/blender/blenkernel/BKE_sequence.h
+++ b/source/blender/blenkernel/BKE_sequence.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BKE_sequence.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index 6584af085cd..419f0f5beeb 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -130,7 +130,7 @@
 #define IN_RANGE(a, b, c) ((b < c)? ((bid.newid ) (a)= (void *)(a)->id.newid
 
 #define FORM MAKE_ID('F','O','R','M')
-#define DDG1 MAKE_ID('3','D','G','1')
-#define DDG2 MAKE_ID('3','D','G','2')
-#define DDG3 MAKE_ID('3','D','G','3')
-#define DDG4 MAKE_ID('3','D','G','4')
-
-#define GOUR MAKE_ID('G','O','U','R')
 
 #define BLEN MAKE_ID('B','L','E','N')
 #define DER_ MAKE_ID('D','E','R','_')
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 30dcb383ef6..441e17f3318 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -43,6 +43,7 @@ static short id_has_animdata (ID *id)
 		case ID_OB:
 		case ID_CU:
 		case ID_KE:
+		case ID_PA:
 		case ID_MA: case ID_TE: case ID_NT:
 		case ID_LA: case ID_CA: case ID_WO:
 		case ID_SCE:
@@ -883,6 +884,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
 	/* meshes */
 	// TODO...
 	
+	/* particles */
+	EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
+	
 	/* objects */
 		/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets 
 		 * this tagged by Depsgraph on framechange 
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 5fc7d18689d..d3d21018c1c 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -221,7 +221,6 @@ static void clear_global(void)
 {
 //	extern short winqueue_break;	/* screen.c */
 
-// XXX	freeAllRad();
 	fastshade_free_render();	/* lamps hang otherwise */
 	free_main(G.main);			/* free all lib data */
 	
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 57ef920f75b..706eece108c 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1220,7 +1220,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
 	BLI_edgehashIterator_free(ehi);
 
 	/* free old CustomData and assign new one */
-	CustomData_free(&dm->edgeData, dm->numVertData);
+	CustomData_free(&dm->edgeData, dm->numEdgeData);
 	dm->edgeData = edgeData;
 	dm->numEdgeData = numEdges;
 
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index e98d7bb01a4..08caea565aa 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -33,6 +33,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_force.h"
 #include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
 
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
@@ -42,6 +43,7 @@
 #include "BKE_object.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
+#include "BKE_particle.h"
 
 #include "BKE_pointcache.h"
 
@@ -339,78 +341,99 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
 }
 
 int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
+static void cloth_write_state(int index, Cloth *cloth, float *data)
+{
+	ClothVertex *vert = cloth->verts + index;
 
-int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
+	memcpy(data, vert->x, 3 * sizeof(float));
+	memcpy(data + 3, vert->xconst, 3 * sizeof(float));
+	memcpy(data + 6, vert->v, 3 * sizeof(float));
+}
+static void cloth_read_state(int index, Cloth *cloth, float *data)
 {
-	PTCacheID pid;
-	PTCacheFile *pf;
-	Cloth *cloth = clmd->clothObject;
-	unsigned int a, ret = 1;
+	ClothVertex *vert = cloth->verts + index;
 	
-	if(!cloth)
-		return 0;
-	
-	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-	pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
-	if(pf) {
-		for(a = 0; a < cloth->numverts; a++) {
-			if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].x, 3)) {
-				ret = 0;
-				break;
-			}
-			if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].xconst, 3)) {
-				ret = 0;
-				break;
-			}
-			if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].v, 3)) {
-				ret = 0;
-				break;
-			}
-		}
-		
-		BKE_ptcache_file_close(pf);
-	}
-	else
-		ret = 0;
-	
-	return ret;
+	memcpy(vert->x, data, 3 * sizeof(float));
+	memcpy(vert->xconst, data + 3, 3 * sizeof(float));
+	memcpy(vert->v, data + 6, 3 * sizeof(float));
 }
+static void cloth_cache_interpolate(int index, Cloth *cloth, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
+{
+	ClothVertex *vert = cloth->verts + index;
+	ParticleKey keys[4];
+	float dfra;
 
-void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
+	if(cfra1 == cfra2) {
+		cloth_read_state(index, cloth, data1);
+		return;
+	}
+
+	memcpy(keys[1].co, data1, 3 * sizeof(float));
+	memcpy(keys[1].vel, data1 + 6, 3 * sizeof(float));
+
+	memcpy(keys[2].co, data2, 3 * sizeof(float));
+	memcpy(keys[2].vel, data2 + 6, 3 * sizeof(float));
+
+	dfra = cfra2 - cfra1;
+
+	VecMulf(keys[1].vel, dfra);
+	VecMulf(keys[2].vel, dfra);
+
+	psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1);
+
+	VecMulf(keys->vel, 1.0f / dfra);
+
+	memcpy(vert->x, keys->co, 3 * sizeof(float));
+	memcpy(vert->v, keys->vel, 3 * sizeof(float));
+
+	/* not sure what to do with this - jahka */
+	memcpy(vert->xconst, data1 + 3, 3 * sizeof(float));
+}
+void cloth_write_cache(Object *ob, ClothModifierData *clmd, int cfra)
 {
+	PTCacheWriter writer;
 	PTCacheID pid;
-	
+
 	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
 
-	// don't do anything as long as we're in editmode!
-	if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
-		return;
-	
-	BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
+	writer.calldata = clmd->clothObject;
+	writer.cfra = cfra;
+	writer.set_elem = cloth_write_state;
+	writer.pid = &pid;
+	writer.totelem = clmd->clothObject->numverts;
+
+	BKE_ptcache_write_cache(&writer);
 }
 
-void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
+int cloth_read_cache(Scene *scene, Object *ob, ClothModifierData *clmd, float cfra, int *old_framenr)
 {
-	Cloth *cloth = clmd->clothObject;
+	PTCacheReader reader;
 	PTCacheID pid;
-	PTCacheFile *pf;
-	unsigned int a;
 	
-	if(!cloth)
-		return;
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+	reader.calldata = clmd->clothObject;
+	reader.cfra = cfra;
+	reader.interpolate_elem = cloth_cache_interpolate;
+	reader.old_frame = old_framenr;
+	reader.pid = &pid;
+	reader.scene = scene;
+	reader.set_elem = cloth_read_state;
+	reader.totelem = clmd->clothObject->numverts;
+
+	return BKE_ptcache_read_cache(&reader);
+}
+void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
+{
+	PTCacheID pid;
 	
 	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-	pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
-	if(!pf)
+
+	// don't do anything as long as we're in editmode!
+	if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 		return;
 	
-	for(a = 0; a < cloth->numverts; a++) {
-		BKE_ptcache_file_write_floats(pf, cloth->verts[a].x, 3);
-		BKE_ptcache_file_write_floats(pf, cloth->verts[a].xconst, 3);
-		BKE_ptcache_file_write_floats(pf, cloth->verts[a].v, 3);
-	}
-	
-	BKE_ptcache_file_close(pf);
+	BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
 }
 
 static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
@@ -486,6 +509,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	PTCacheID pid;
 	float timescale;
 	int framedelta, framenr, startframe, endframe;
+	int cache_result, old_framenr;
 
 	clmd->scene= scene;	/* nice to pass on later :) */
 	framenr= (int)scene->r.cfra;
@@ -499,6 +523,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	if(!result) {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 		return dm;
 	}
 	
@@ -510,6 +535,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 		if(result->getNumVerts(result) != clmd->clothObject->numverts) {
 			cache->flag &= ~PTCACHE_SIMULATION_VALID;
 			cache->simframe= 0;
+			cache->last_exact= 0;
 			return result;
 		}
 	}
@@ -521,6 +547,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	if(BKE_ptcache_get_continue_physics()) {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 
 		/* do simulation */
 		if(!do_init_cloth(ob, clmd, result, framenr))
@@ -536,6 +563,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	if(framenr < startframe) {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 		return result;
 	}
 	else if(framenr > endframe) {
@@ -552,7 +580,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 		return result;
 
 	/* try to read from cache */
-	if(cloth_read_cache(ob, clmd, framenr)) {
+	cache_result = cloth_read_cache(scene, ob, clmd, framenr, &old_framenr);
+
+	if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
 		cache->flag |= PTCACHE_SIMULATION_VALID;
 		cache->simframe= framenr;
 
@@ -561,25 +591,40 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 
 		return result;
 	}
+	else if(cache_result==PTCACHE_READ_OLD) {
+		BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
+
+		implicit_set_positions(clmd);
+
+		cache->flag |= PTCACHE_SIMULATION_VALID;
+		cache->simframe= old_framenr;
+	}
 	else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
 		/* if baked and nothing in cache, do nothing */
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 		return result;
 	}
 
 	if(framenr == startframe) {
+		if(cache->flag & PTCACHE_REDO_NEEDED) {
+			BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+			do_init_cloth(ob, clmd, result, framenr);
+		}
 		cache->flag |= PTCACHE_SIMULATION_VALID;
 		cache->simframe= framenr;
 
 		/* don't write cache on first frame, but on second frame write
 		 * cache for frame 1 and 2 */
 	}
-	else if(framedelta == 1) {
+	else {
 		/* if on second frame, write cache for first frame */
-		if(framenr == startframe+1)
+		if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
 			cloth_write_cache(ob, clmd, startframe);
 
+		clmd->sim_parms->timescale *= framenr - cache->simframe;
+
 		/* do simulation */
 		cache->flag |= PTCACHE_SIMULATION_VALID;
 		cache->simframe= framenr;
@@ -587,16 +632,13 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 		if(!do_step_cloth(ob, clmd, result, framenr)) {
 			cache->flag &= ~PTCACHE_SIMULATION_VALID;
 			cache->simframe= 0;
+			cache->last_exact= 0;
 		}
 		else
 			cloth_write_cache(ob, clmd, framenr);
 
 		cloth_to_object (ob, clmd, result);
 	}
-	else {
-		cache->flag &= ~PTCACHE_SIMULATION_VALID;
-		cache->simframe= 0;
-	}
 
 	return result;
 }
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index a43389a2ef6..88e73a00ba7 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3028,7 +3028,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 	if (VALID_CONS_TARGET(ct)) {
 		float loc[3], eul[3], size[3];
 		float dvec[3], sval[3];
-		short i;
+		int i;
 		
 		/* obtain target effect */
 		switch (data->from) {
@@ -3075,7 +3075,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 		switch (data->to) {
 			case 2: /* scaling */
 				for (i=0; i<3; i++)
-					size[i]= data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i])); 
+					size[i]= data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])); 
 				break;
 			case 1: /* rotation */
 				for (i=0; i<3; i++) {
@@ -3085,7 +3085,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 					tmax= data->to_max[i];
 					
 					/* all values here should be in degrees */
-					eul[i]= tmin + (sval[data->map[i]] * (tmax - tmin)); 
+					eul[i]= tmin + (sval[(int)data->map[i]] * (tmax - tmin)); 
 					
 					/* now convert final value back to radians */
 					eul[i] = (float)(eul[i] / 180 * M_PI);
@@ -3094,7 +3094,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 			default: /* location */
 				/* get new location */
 				for (i=0; i<3; i++)
-					loc[i]= (data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i])));
+					loc[i]= (data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])));
 				
 				/* add original location back on (so that it can still be moved) */
 				VecAddf(loc, cob->matrix[3], loc);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 6afbcf4950c..fbad585d9b7 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -1,5 +1,5 @@
 /**
- * $Id: context.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -358,6 +358,9 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa
 		return 1;
 	}
 
+	list->first= NULL;
+	list->last= NULL;
+
 	return 0;
 }
 
@@ -365,15 +368,20 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
 {
 	bContextDataResult result;
 
-	if(ctx_data_get((bContext*)C, member, &result)) {
+	if(ctx_data_get((bContext*)C, member, &result))
 		return result.ptr;
-	}
-	else {
-		PointerRNA ptr;
-		memset(&ptr, 0, sizeof(ptr));
-		return ptr;
-	}
+	else
+		return PointerRNA_NULL;
+}
+
+PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
+{
+	PointerRNA ptr = CTX_data_pointer_get(C, member);
 
+	if(ptr.data && ptr.type == type)
+		return ptr;
+	
+	return PointerRNA_NULL;
 }
 
 ListBase CTX_data_collection_get(const bContext *C, const char *member)
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 8bb34bde122..a36b825293e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -559,7 +559,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
 
 			dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
 
-			if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE)
+			if(!psys_check_enabled(ob, psys))
 				continue;
 
 			if(part->phystype==PART_PHYS_KEYED && psys->keyed_ob &&
@@ -1831,7 +1831,7 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
 }
 
 /* node was checked to have lasttime != curtime , and is of type ID_OB */
-static void flush_pointcache_reset(DagNode *node, int curtime, int reset)
+static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int reset)
 {
 	DagAdjList *itA;
 	Object *ob;
@@ -1844,13 +1844,13 @@ static void flush_pointcache_reset(DagNode *node, int curtime, int reset)
 				ob= (Object*)(node->ob);
 
 				if(reset || (ob->recalc & OB_RECALC)) {
-					if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+					if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
 						ob->recalc |= OB_RECALC_DATA;
 
-					flush_pointcache_reset(itA->node, curtime, 1);
+					flush_pointcache_reset(scene, itA->node, curtime, 1);
 				}
 				else
-					flush_pointcache_reset(itA->node, curtime, 0);
+					flush_pointcache_reset(scene, itA->node, curtime, 0);
 			}
 		}
 	}
@@ -1908,13 +1908,13 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
 				ob= (Object*)(itA->node->ob);
 
 				if(ob->recalc & OB_RECALC) {
-					if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+					if(BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH))
 						ob->recalc |= OB_RECALC_DATA;
 
-					flush_pointcache_reset(itA->node, lasttime, 1);
+					flush_pointcache_reset(sce, itA->node, lasttime, 1);
 				}
 				else
-					flush_pointcache_reset(itA->node, lasttime, 0);
+					flush_pointcache_reset(sce, itA->node, lasttime, 0);
 			}
 		}
 	}
@@ -2132,7 +2132,7 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
 	if(ob==NULL || sce->theDag==NULL) return;
 
 	ob->recalc |= flag;
-	BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH);
+	BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
 	
 	/* all users of this ob->data should be checked */
 	/* BUT! displists for curves are still only on cu */
@@ -2147,7 +2147,7 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
 					for (obt=G.main->object.first; obt; obt= obt->id.next) {
 						if (obt != ob && obt->data==ob->data) {
 							obt->recalc |= OB_RECALC_DATA;
-							BKE_ptcache_object_reset(obt, PTCACHE_RESET_DEPSGRAPH);
+							BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
 						}
 					}
 				}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 736165a8a98..cdf4b90cee1 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -315,13 +315,19 @@ static void init_fastshade_shadeinput(Render *re)
 
 static Render *fastshade_get_render(Scene *scene)
 {
-	Render *re= RE_GetRender("_Shade View_");
-	if(re==NULL) {
-		re= RE_NewRender("_Shade View_");
-	
-		RE_Database_Baking(re, scene, 0, 0);	/* 0= no faces */
+	/* XXX ugly global still, but we can't do preview while rendering */
+	if(G.rendering==0) {
+		
+		Render *re= RE_GetRender("_Shade View_");
+		if(re==NULL) {
+			re= RE_NewRender("_Shade View_");
+		
+			RE_Database_Baking(re, scene, 0, 0);	/* 0= no faces */
+		}
+		return re;
 	}
-	return re;
+	
+	return NULL;
 }
 
 /* called on file reading */
@@ -611,18 +617,20 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
 
 void shadeMeshMCol(Scene *scene, Object *ob, Mesh *me)
 {
+	Render *re= fastshade_get_render(scene);
 	int a;
 	char *cp;
 	unsigned int *mcol= (unsigned int*)me->mcol;
 	
-	Render *re= fastshade_get_render(scene);
-	mesh_create_shadedColors(re, ob, 1, &mcol, NULL);
-	me->mcol= (MCol*)mcol;
+	if(re) {
+		mesh_create_shadedColors(re, ob, 1, &mcol, NULL);
+		me->mcol= (MCol*)mcol;
 
-	/* swap bytes */
-	for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) {
-		SWAP(char, cp[0], cp[3]);
-		SWAP(char, cp[1], cp[2]);
+		/* swap bytes */
+		for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) {
+			SWAP(char, cp[0], cp[3]);
+			SWAP(char, cp[1], cp[2]);
+		}
 	}
 }
 
@@ -641,6 +649,8 @@ void shadeDispList(Scene *scene, Base *base)
 	int a, need_orco;
 	
 	re= fastshade_get_render(scene);
+	if(re==NULL)
+		return;
 	
 	dl = find_displist(&ob->disp, DL_VERTCOL);
 	if (dl) {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 9858025af5a..eaa2d541638 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -29,6 +29,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include 
 #include 
 
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index 929d3f942dc..4e7e76dfae3 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -27,48 +27,9 @@
  *
  * - Blender Foundation
  *
- * ***** END GPL LICENSE BLOCK *****
- *  
- *  eigen videoscape formaat:
- *
- * 
- * lamp:
- *		3DG2
-		aantal_lampen
-		
-		type
-		spsi spbl
-		r, g, b, energy
-		locx, locy, locz
-		vecx, vecy, vecz
-
-		
-	curve / nurbs:
-		3DG3
-		5 of 11 (curve of surf)
-		aantal_nurbs
-		extr1 extr2
-		
-		mat[0][0] mat[0][1] mat[0][2] mat[0][3]
-		mat[1][0] mat[1][1] mat[1][2] mat[1][3]
-		...		
-		
-		type
-		pntsu, pntsv
-		resolu, resolv
-		orderu, orderv
-		flagu, flagv
-		
-		(als type==nurb) x y z w
-						 x y z w
-						 ...
-		(als type==bez)  xyz xyz xyz h1 h2 h3
-						 xyz xyz xyz h1 h2 h3
-						 ...
- *  
- * 
- */
+ * ***** END GPL LICENSE BLOCK *****/
 
+#include "BLI_storage.h"
 
 #include  /* isdigit, isspace */
 #include 
@@ -482,385 +443,6 @@ static void read_stl_mesh_ascii(Scene *scene, char *str)
 #undef STLREADLINE
 #undef STLREADVERT
 
-static void read_videoscape_mesh(Scene *scene, char *str)
-{
-	Object *ob;
-	Mesh *me;
-	MVert *mvert;
-	MFace *mface;
-	Material *ma;
-	FILE *fp;
-	float *vertdata, *vd, min[3], max[3], cent[3], ftemp;
-	unsigned int color[32], col;
-	int totcol, a, b, verts, tottria=0, totquad=0, totedge=0, poly, nr0, nr, first;
-	int end;
-	char s[50];
-	
-	fp= fopen(str, "rb");
-	if(fp==NULL) {
-		//XXX error("Can't read file");
-		return;
-	}
-	
-	fscanf(fp, "%40s", s);
-	
-	fscanf(fp, "%d\n", &verts);
-	if(verts<=0) {
-		fclose(fp);
-		//XXX error("Read error");
-		return;
-	}
-	
-	if(verts>MESH_MAX_VERTS) {
-		//XXX error("too many vertices");
-		fclose(fp);
-		return;
-	}
-	
-	INIT_MINMAX(min, max);
-	vd= vertdata= MEM_mallocN(sizeof(float)*3*verts, "videoscapelezer");
-	
-	for(a=0; a0) {
-		end= fscanf(fp,"%d", &poly);
-		if(end<=0) break;
-	
-		if(poly==3) tottria++;
-		else if(poly==4) totquad++;
-		else totedge+= poly;
-	
-		for(a=0;a=totcol && totcol<32) {
-			color[totcol]= col;
-			totcol++;
-		}
-	}
-
-	/* new object */
-	ob= add_object(scene, OB_MESH);
-	me= ob->data;
-	me->totvert= verts;
-	me->totface= totedge+tottria+totquad;
-	
-	me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
-	                                NULL, me->totvert);
-	me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
-	                                NULL, me->totface);
-	
-	/* colors */
-	if(totcol) {
-		ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
-		me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
-		me->totcol= totcol;
-		ob->totcol= (unsigned char) me->totcol;
-		ob->actcol= 1;
-	}
-	
-	/* materials */
-	for(a=0; amat.first;
-		while(ma) {
-			if(ma->mtex[0]==0) {
-				col= rgb_to_cpack(ma->r, ma->g, ma->b);
-				if(color[a]==col) {
-					me->mat[a]= ma;
-					ma->id.us++;
-					break;
-				}
-			}
-			ma= ma->id.next;
-		}
-		if(ma==0) {
-			ma= add_material("ext");
-			me->mat[a]= ma;
-			cpack_to_rgb(color[a], cent, cent+1, cent+2);
-			ma->r= cent[0];
-			ma->g= cent[1];
-			ma->b= cent[2];
-			automatname(ma);
-		}
-	}
-	
-	/* verts */
-	
-	cent[0]= (min[0]+max[0])/2.0f;
-	cent[1]= (min[1]+max[1])/2.0f;
-	cent[2]= (min[2]+max[2])/2.0f;
-	VECCOPY(ob->loc, cent);
-	
-	a= me->totvert;
-	vd= vertdata;
-	mvert= me->mvert;
-	while(a--) {
-		VecSubf(mvert->co, vd, cent);
-		mvert++;
-		vd+= 3;
-	}
-	
-	/* faces */
-	if(me->totface) {
-		rewind(fp);
-	
-		fscanf(fp, "%40s", s);
-		fscanf(fp, "%d\n", &verts);
-		/* fake read */
-		for(a=0;atotface;
-		mface= me->mface;
-		while(a--) {
-			end= fscanf(fp,"%d", &poly);
-			if(end<=0) break;
-	
-			if(poly==3 || poly==4) {
-				fscanf(fp,"%d", &nr);
-				mface->v1= MIN2(nr, me->totvert-1);
-				fscanf(fp,"%d", &nr);
-				mface->v2= MIN2(nr, me->totvert-1);
-				fscanf(fp,"%d", &nr);
-				mface->v3= MIN2(nr, me->totvert-1);
-				if(poly==4) {
-					if( fscanf(fp,"%d", &nr) <=0 ) break;
-					mface->v4= MIN2(nr, me->totvert-1);
-				}
-				
-				test_index_face(mface, NULL, 0, poly);
-				
-				mface++;
-			}
-			else {
-				if( fscanf(fp,"%d", &nr0) <=0) break;
-				first= nr0;
-				for(b=1; btotvert-1);
-					mface->v1= nr;
-					mface->v2= nr0;
-					nr0= nr;
-					mface++;
-					a--;
-				}
-				mface->v1= first;
-				mface->v2= nr;
-				mface++;
-				if(end<=0) break;
-			}
-			end= fscanf(fp,"%i", &col);
-			col &= 0xF0F0F0;
-			if(end<=0) break;
-			
-			for(b=0; bmat_nr= b;
-					break;
-				}
-			}
-		}
-	}
-	
-	fclose(fp);
-	MEM_freeN(vertdata);
-	
-	mesh_add_normals_flags(me);
-	make_edges(me, 0);
-
-	//XXX waitcursor(1);
-}
-
-static void read_videoscape_lamp(Scene *scene, char *str)
-{
-	Object *ob;
-	Lamp *la;
-	FILE *fp;
-	float vec[3], q1[4];
-	int tot, val;
-	char s[50];
-	
-	fp= fopen(str, "rb");
-	if(fp==NULL) {
-		//XXX error("Can't read file");
-		return;
-	}
-
-	fscanf(fp, "%40s", s);
-	fscanf(fp, "%d\n", &tot);
-	
-	while(tot--) {
-		ob= add_object(scene, OB_LAMP);
-		la= ob->data;
-		
-		fscanf(fp, "%d\n", &val);
-		la->type= val;
-		if(la->type==1) la->type= LA_SPOT;
-		else if(la->type==2) la->type= LA_SUN;
-		
-		fscanf(fp, "%f %f\n", &la->spotsize, &la->spotblend);
-		
-		fscanf(fp, "%f %f %f %f\n", &la->r, &la->g, &la->b, &la->energy);		
-		
-		fscanf(fp, "%f %f %f\n", ob->loc, ob->loc+1, ob->loc+2);
-		val= fscanf(fp, "%f %f %f\n", vec, vec+1, vec+2);
-		vectoquat(vec, 5, 2, q1);
-		QuatToEul(q1, ob->rot);
-		
-		if(val<=0) break;
-		
-	}
-	fclose(fp);
-}
-
-static void read_videoscape_nurbs(Scene *scene, char *str)
-{
-	Object *ob;
-	Curve *cu;
-	Nurb *nu;
-	BezTriple *bezt;
-	BPoint *bp;
-	FILE *fp;
-	float tmat[4][4], omat[3][3], imat[3][3], mat[3][3];
-	int a, tot, type, val;
-	char s[50];
-
-	fp= fopen(str, "rb");
-	if(fp==NULL) {
-		//XXX error("Can't read file");
-		return;
-	}
-
-	fscanf(fp, "%40s", s);
-	fscanf(fp, "%d\n", &type);
-	
-	if(type==5) ob= add_object(scene, OB_SURF);
-	else ob= add_object(scene, OB_CURVE);
-	cu= ob->data;
-	
-	fscanf(fp, "%d\n", &tot);
-	fscanf(fp, "%d %d\n", &type, &val);
-	
-	cu->ext1= 0.002f*type;
-	cu->ext2= 0.002f*val;
-
-	for(a=0; a<4; a++) fscanf(fp, "%e %e %e %e\n", tmat[a], tmat[a]+1, tmat[a]+2, tmat[a]+3);
-
-	VECCOPY(ob->loc, tmat[3]);
-
-	Mat3CpyMat4(omat, tmat);
-	Mat3ToEul(omat, ob->rot);
-	EulToMat3(ob->rot, mat);
-	Mat3Inv(imat, mat);
-	Mat3MulMat3((float ( * )[3])tmat, imat, omat);
-	
-	while(tot--) {
-		nu= (Nurb*)MEM_callocN(sizeof(Nurb),"nu from exotic");
-		BLI_addtail(&cu->nurb, nu);
-		
-		fscanf(fp, "%d\n", &type);
-		nu->type= type;
-
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->pntsu= type; nu->pntsv= val;
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->resolu= type; nu->resolv= val;
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->orderu= type; nu->orderv= val;
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->flagu= type; nu->flagv= val;
-		
-		if( (nu->type & 7)==CU_BEZIER) {
-			a= nu->pntsu;
-			nu->bezt= bezt= MEM_callocN(a*sizeof(BezTriple), "bezt from exotic");
-			while(a--) {
-				fscanf(fp, "%f %f %f ", bezt->vec[0], bezt->vec[0]+1, bezt->vec[0]+2);
-				Mat4MulVecfl(tmat, bezt->vec[0]);
-				fscanf(fp, "%f %f %f ", bezt->vec[1], bezt->vec[1]+1, bezt->vec[1]+2);
-				Mat4MulVecfl(tmat, bezt->vec[1]);
-				fscanf(fp, "%f %f %f ", bezt->vec[2], bezt->vec[2]+1, bezt->vec[2]+2);
-				Mat4MulVecfl(tmat, bezt->vec[2]);
-				fscanf(fp, "%d %d\n", &type, &val);
-				bezt->h1= type;
-				bezt->h2= val;
-				bezt++;
-			}
-		}
-		else {
-			a= nu->pntsu*nu->pntsv;
-			if(a) {
-				nu->bp= bp= MEM_callocN(a*sizeof(BPoint), "bp from exotic");
-				while(a--) {
-					fscanf(fp, "%f %f %f %f\n", bp->vec, bp->vec+1, bp->vec+2, bp->vec+3);
-					Mat4MulVecfl(tmat, bp->vec);
-					bp++;
-				}
-				
-				val= KNOTSU(nu);
-				nu->knotsu= MEM_mallocN(sizeof(float)*val, "knots");
-				for(a=0; aknotsu+a);
-				
-				if(nu->pntsv>1) {
-					val= KNOTSV(nu);
-					nu->knotsv= MEM_mallocN(sizeof(float)*val, "knots");
-					for(a=0; aknotsv+a);
-				}
-			}
-			else {
-				BLI_remlink(&cu->nurb, nu);
-				MEM_freeN(nu);
-			}
-		}
-	}
-	fclose(fp);
-}
-
-static void read_videoscape(Scene *scene, char *str)
-{
-	int file, type;
-	unsigned int val;
-	unsigned short numlen;
-	char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXFILE];
-	
-	strcpy(name, str);
-
-	while( TRUE ) {
-		file= open(name, O_BINARY|O_RDONLY);
-		if(file<=0) break;
-		else {
-			read(file, &type, 4);
-			close(file);
-			
-			if(type==DDG1) read_videoscape_mesh(scene, name);
-			else if(type==DDG2) read_videoscape_lamp(scene, name);
-			else if(type==DDG3) read_videoscape_nurbs(scene, name);
-		}
-
-		val = BLI_stringdec(name, head, tail, &numlen);
-		BLI_stringenc(name, head, tail, numlen, val + 1);
-
-	}
-}
-
-
 /* ***************** INVENTOR ******************* */
 
 
@@ -2204,16 +1786,7 @@ int BKE_read_exotic(Scene *scene, char *name)
 			if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
 
 				//XXX waitcursor(1);
-				
-				if(ELEM4(*s0, DDG1, DDG2, DDG3, DDG4)) {
-					if(0) { // XXX obedit) {
-						//XXX error("Unable to perform function in EditMode");
-					} else {
-						read_videoscape(scene, name);
-						retval = 1;
-					}
-				}
-				else if(strncmp(str, "#Inventor V1.0", 14)==0) {
+				if(strncmp(str, "#Inventor V1.0", 14)==0) {
 					if( strncmp(str+15, "ascii", 5)==0) {
 						read_inventor(scene, name, &lbase);
 						displist_to_objects(scene, &lbase);				
@@ -2385,167 +1958,6 @@ void write_stl(Scene *scene, char *str)
 	//XXX waitcursor(0);
 }
 
-static void write_videoscape_mesh(Scene *scene, Object *ob, char *str)
-{
-	Mesh *me= ob->data;
-	EditMesh *em = BKE_mesh_get_editmesh(me);
-	Material *ma;
-	MFace *mface;
-	FILE *fp;
-	EditVert *eve;
-	EditFace *evl;
-	unsigned int kleur[32];
-	float co[3];
-	int a;
-	intptr_t tot;
-	char *cp;
-	
-	if(ob && ob->type==OB_MESH);
-	else {
-		return;
-	}
-
-	kleur[0]= 0x00C0C0C0;
-
-	cp= (char *)kleur;
-	for(a=0; atotcol; a++, cp+=4) {
-		
-		ma= give_current_material(ob, a+1);
-		if(ma) {
-			cp[0]= (unsigned char) (255.0*ma->emit);
-			cp[1]= (unsigned char) (255.0*ma->b);
-			cp[2]= (unsigned char) (255.0*ma->g);
-			cp[3]= (unsigned char) (255.0*ma->r);
-			if(ENDIAN_ORDER==L_ENDIAN) SWITCH_INT(kleur[a]);
-		}
-		else kleur[a]= 0x00C0C0C0;
-	
-		if(a>30) break;
-	}
-	
-	fp= fopen(str, "wb");
-	if(fp==NULL) return;
-
-	fprintf(fp,"3DG1\n");
-
-	if(em) {
-
-		fprintf(fp, "%d\n", em->totvert);
-	
-		tot= 0;
-		eve= em->verts.first;
-		while(eve) {
-			VECCOPY(co, eve->co);
-			Mat4MulVecfl(ob->obmat, co);
-			fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
-			eve->tmp.l = tot;
-			tot++;
-			eve= eve->next;
-		}
-		evl= em->faces.first;
-		while(evl) {
-
-			if(evl->v4==0) {
-				fprintf(fp, "3 %ld %ld %ld 0x%x\n", 
-						(intptr_t) evl->v1->tmp.l,
-						(intptr_t) evl->v2->tmp.l,
-						(intptr_t) evl->v3->tmp.l, 
-						kleur[evl->mat_nr]);
-			}
-			else {
-				fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n", 
-						(intptr_t) evl->v1->tmp.l, 
-						(intptr_t) evl->v2->tmp.l, 
-						(intptr_t) evl->v3->tmp.l, 
-						(intptr_t) evl->v4->tmp.l, 
-						kleur[evl->mat_nr]);
-			}
-			evl= evl->next;
-		}
-	}
-	else {
-		DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
-		
-		me= ob->data;
-		
-		fprintf(fp, "%d\n", me->totvert);
-		
-		mface= me->mface;
-		for(a=0; atotvert; a++) {
-			dm->getVertCo(dm, a, co);
-			Mat4MulVecfl(ob->obmat, co);
-			fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
-		}
-		for(a=0; atotface; a++, mface++) {
-			if(mface->v4==0) {
-				fprintf(fp, "3 %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, kleur[(int)mface->mat_nr]);
-			}
-			else {
-				fprintf(fp, "4 %d %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, mface->v4, kleur[(int)mface->mat_nr]);
-			}
-		}
-
-		dm->release(dm);
-	}
-	
-	fclose(fp);
-
-	if (em) BKE_mesh_end_editmesh(me, em);
-	
-}
-
-
-void write_videoscape(Scene *scene, char *str)
-{
-	Base *base;
-	int file, val, lampdone=0;
-	unsigned short numlen;
-	char head[FILE_MAXFILE], tail[FILE_MAXFILE];
-	
-	if(BLI_testextensie(str,".trace")) str[ strlen(str)-6]= 0;
-	if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
-	if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
-	if(BLI_testextensie(str,".obj")==0) strcat(str, ".obj");
-
-	file= open(str,O_BINARY|O_RDONLY);
-	close(file);
-	//XXX saveover()
-	// if(file>-1) if(!during_script() && saveover(str)==0) return;
-
-	strcpy(temp_dir, str);
-
-	base= scene->base.first;
-	while(base) {
-		if((base->flag & SELECT) && (base->lay & scene->lay))  {
-			if(base->object->type==OB_MESH) {
-				write_videoscape_mesh(scene, base->object, str);
-				val = BLI_stringdec(str, head, tail, &numlen);
-				BLI_stringenc(str, head, tail, numlen, val + 1);
-			}
-			else if(base->object->type==OB_CURVE || base->object->type==OB_SURF) {
-				/* write_videoscape_nurbs(base->object, str); */
-				/* val = stringdec(str, head, tail, &numlen); */
-				/* stringenc(str, head, tail, numlen, val + 1); */
-			}
-			else if(lampdone==0 && base->object->type==OB_LAMP) {
-				/* lampdone= 1; */
-				/* write_videoscape_lamps(str); */
-				/* val = stringdec(str, head, tail, &numlen); */
-				/* stringenc(str, head, tail, numlen, val + 1); */
-			}
-		}
-		base= base->next;
-	}
-	
-	
-	/* remove when higher numbers exist */
-	while(remove(str)==0) {
-		
-		val = BLI_stringdec(str, head, tail, &numlen);
-		BLI_stringenc(str, head, tail, numlen, val + 1);
-	}
-}
-
 /* ******************************* WRITE VRML ***************************** */
 
 static void replace_chars(char *str1, char *str2)
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 9eefd48cae4..54008185f72 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -28,6 +28,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include "MEM_guardedalloc.h"
 
 #include "DNA_mesh_types.h"
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 60a7ffc28d9..70901778585 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -333,11 +333,11 @@ static VFontData *vfont_get_data(VFont *vfont)
 					BLI_addtail(&ttfdata, tmpfnt);
 				}
 			} else {
-				pf= newPackedFile(vfont->name);
+				pf= newPackedFile(NULL, vfont->name);
 				
 				if(!tmpfnt)
 				{
-					tpf= newPackedFile(vfont->name);
+					tpf= newPackedFile(NULL, vfont->name);
 					
 					// Add temporary packed file to globals
 					tmpfnt= (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
@@ -385,8 +385,8 @@ VFont *load_vfont(char *name)
 		strcpy(dir, name);
 		BLI_splitdirstring(dir, filename);
 
-		pf= newPackedFile(name);
-		tpf= newPackedFile(name);		
+		pf= newPackedFile(NULL, name);
+		tpf= newPackedFile(NULL, name);		
 		
 		is_builtin= 0;
 	}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 6086aa58d40..dd8f44c71d5 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1,5 +1,5 @@
 /**
- * $Id: gpencil.c 19758 2009-04-16 13:10:08Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 3be47778674..54366aadd92 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -230,16 +230,16 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
 	 */
 	newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
 
-	newarr = MEM_callocN(idp_size_table[prop->subtype]*newsize, "idproperty array resized");
+	newarr = MEM_callocN(idp_size_table[(int)prop->subtype]*newsize, "idproperty array resized");
 	if (newlen >= prop->len) {
 		/* newlen is bigger*/
-		memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[prop->subtype]);
+		memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[(int)prop->subtype]);
 		idp_resize_group_array(prop, newlen, newarr);
 	}
 	else {
 		/* newlen is smaller*/
 		idp_resize_group_array(prop, newlen, newarr);
-		memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[prop->subtype]);
+		memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[(int)prop->subtype]);
 	}
 
 	MEM_freeN(prop->data.pointer);
@@ -546,7 +546,7 @@ int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
 		return BSTR_EQ(IDP_String(prop1), IDP_String(prop2));
 	else if(prop1->type == IDP_ARRAY) {
 		if(prop1->len == prop2->len && prop1->subtype == prop2->subtype)
-			return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[prop1->subtype]*prop1->len);
+			return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype]*prop1->len);
 		else
 			return 0;
 	}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 8eef9984c92..ef0984bf93d 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1431,7 +1431,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 		/* try to repack file */
 		if(ima->packedfile) {
 			PackedFile *pf;
-			pf = newPackedFile(ima->name);
+			pf = newPackedFile(NULL, ima->name);
 			if (pf) {
 				freePackedFile(ima->packedfile);
 				ima->packedfile = pf;
@@ -1750,7 +1750,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
 			
 			/* make packed file for autopack */
 			if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK))
-				ima->packedfile = newPackedFile(str);
+				ima->packedfile = newPackedFile(NULL, str);
 		}
 		
 		if(ima->flag & IMA_DO_PREMUL)
@@ -1812,7 +1812,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
 	Render *re= NULL;
 	RenderResult *rr= NULL;
 	
-	if(iuser->scene) {
+	if(iuser && iuser->scene) {
 		re= RE_GetRender(iuser->scene->id.name);
 		rr= RE_GetResult(re);
 	}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 40c98c1d9cc..fc5213d5532 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1600,6 +1600,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 		
 		if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
 		{
+			float temp = clmd->sim_parms->stepsPerFrame;
+			/* not too nice hack, but collisions need this correction -jahka */
+			clmd->sim_parms->stepsPerFrame /= clmd->sim_parms->timescale;
+
 			// collisions 
 			// itstart();
 			
@@ -1614,7 +1618,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 			
 			// call collision function
 			// TODO: check if "step" or "step+dt" is correct - dg
-			result = cloth_bvh_objcollision(ob, clmd, step, dt);
+			result = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
 			
 			// correct velocity again, just to be sure we had to change it due to adaptive collisions
 			for(i = 0; i < numverts; i++)
@@ -1637,6 +1641,9 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 				}
 			}
 			
+			/* restore original stepsPerFrame */
+			clmd->sim_parms->stepsPerFrame = temp;
+			
 			// X = Xnew;
 			cp_lfvector(id->X, id->Xnew, numverts);
 			
@@ -1654,7 +1661,6 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 				
 				simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
 			}
-			
 		}
 		else
 		{
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index b410c521dea..57b88bb0b3f 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -615,7 +615,7 @@ int find_material_index(Object *ob, Material *ma)
 	return 0;	   
 }
 
-void new_material_to_objectdata(Object *ob)
+void object_add_material_slot(Object *ob)
 {
 	Material *ma;
 	
@@ -854,7 +854,7 @@ void automatname(Material *ma)
 }
 
 
-void delete_material_index(Object *ob)
+void object_remove_material_slot(Object *ob)
 {
 	Material *mao, ***matarar;
 	Object *obt;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index bf3d27cafbf..80a9f173d6a 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -3543,7 +3543,7 @@ static void displaceModifier_updateDepgraph(
 	}
 }
 
-static void validate_layer_name(const CustomData *data, int type, char *name)
+static void validate_layer_name(const CustomData *data, int type, char *name, char *outname)
 {
 	int index = -1;
 
@@ -3556,8 +3556,10 @@ static void validate_layer_name(const CustomData *data, int type, char *name)
 		* deleted, so assign the active layer to name
 		*/
 		index = CustomData_get_active_layer_index(data, CD_MTFACE);
-		strcpy(name, data->layers[index].name);
+		strcpy(outname, data->layers[index].name);
 	}
+	else
+		strcpy(outname, name);
 }
 
 static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
@@ -3583,12 +3585,11 @@ static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
 			char *done = MEM_callocN(sizeof(*done) * numVerts,
 					"get_texture_coords done");
 			int numFaces = dm->getNumFaces(dm);
+			char uvname[32];
 			MTFace *tf;
 
-			validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name);
-
-			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-					dmd->uvlayer_name);
+			validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
+			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
 			/* verts are given the UV from the first face that uses them */
 			for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -3884,6 +3885,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 	Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
 	int num_projectors = 0;
 	float aspect;
+	char uvname[32];
 	
 	if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
 	else aspect = 1.0f;
@@ -3898,12 +3900,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 	if(!dm->getFaceDataArray(dm, CD_MTFACE)) return dm;
 
 	/* make sure we're using an existing layer */
-	validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name);
+	validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
 
 	/* make sure we are not modifying the original UV layer */
 	tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-			CD_MTFACE,
-   umd->uvlayer_name);
+			CD_MTFACE, uvname);
 
 	numVerts = dm->getNumVerts(dm);
 
@@ -5185,12 +5186,11 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
 			char *done = MEM_callocN(sizeof(*done) * numVerts,
 					"get_texture_coords done");
 			int numFaces = dm->getNumFaces(dm);
+			char uvname[32];
 			MTFace *tf;
 
-			validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name);
-
-			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-					wmd->uvlayer_name);
+			validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
+			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
 			/* verts are given the UV from the first face that uses them */
 			for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -6295,6 +6295,9 @@ CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData
 	MTex *mtex;
 	int i;
 
+	if(!psmd->psys->part)
+		return 0;
+
 	ma= give_current_material(ob, psmd->psys->part->omat);
 	if(ma) {
 		for(i=0; ivdata, lvl->totvert);
 			CustomData_free(&mr->fdata, lvl->totface);
-			MEM_freeN(mr->edge_flags);
-			MEM_freeN(mr->edge_creases);
+			if(mr->edge_flags)
+				MEM_freeN(mr->edge_flags);
+			if(mr->edge_creases)
+				MEM_freeN(mr->edge_creases);
 		}
 
 		while(lvl) {
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 22e4e8a8309..4d88556d8bf 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -61,8 +61,9 @@
 #include "BKE_image.h"
 #include "BKE_font.h"
 #include "BKE_packedFile.h"
+#include "BKE_report.h"
 
-int seekPackedFile(PackedFile * pf, int offset, int whence)
+int seekPackedFile(PackedFile *pf, int offset, int whence)
 {
 	int oldseek = -1, seek = 0;
 
@@ -92,12 +93,12 @@ int seekPackedFile(PackedFile * pf, int offset, int whence)
 	return(oldseek);
 }
 	
-void rewindPackedFile(PackedFile * pf)
+void rewindPackedFile(PackedFile *pf)
 {
 	seekPackedFile(pf, 0, SEEK_SET);
 }
 
-int readPackedFile(PackedFile * pf, void * data, int size)
+int readPackedFile(PackedFile *pf, void *data, int size)
 { 
 	if ((pf != NULL) && (size >= 0) && (data != NULL)) {
 		if (size + pf->seek > pf->size) {
@@ -118,66 +119,55 @@ int readPackedFile(PackedFile * pf, void * data, int size)
 	return(size);
 }
 
-int countPackedFiles()
+int countPackedFiles(Main *bmain)
 {
-	int count = 0;
 	Image *ima;
 	VFont *vf;
 	bSample *sample;
+	int count = 0;
 	
 	// let's check if there are packed files...
-	ima = G.main->image.first;
-	while (ima) {
-		if (ima->packedfile) {
+	for(ima=bmain->image.first; ima; ima=ima->id.next)
+		if(ima->packedfile)
 			count++;
-		}
-		ima= ima->id.next;
-	}
 
-	vf = G.main->vfont.first;
-	while (vf) {
-		if (vf->packedfile) {
+	for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+		if(vf->packedfile)
 			count++;
-		}
-		vf = vf->id.next;
-	}
 
-	sample = samples->first;
-	while (sample) {
-		if (sample->packedfile) {
-			count++;
-		}
-		sample = sample->id.next;
-	}
+	if(samples)
+		for(sample=samples->first; sample; sample=sample->id.next)
+			if(sample->packedfile)
+				count++;
 
-	return(count);
+	return count;
 }
 
-void freePackedFile(PackedFile * pf)
+void freePackedFile(PackedFile *pf)
 {
-	if (pf) {
+	if(pf) {
 		MEM_freeN(pf->data);
 		MEM_freeN(pf);
-	} else {
-		printf("freePackedFile: Trying to free a NULL pointer\n");
 	}
+	else
+		printf("freePackedFile: Trying to free a NULL pointer\n");
 }
 	
-PackedFile * newPackedFileMemory(void *mem, int memlen)
+PackedFile *newPackedFileMemory(void *mem, int memlen)
 {
-	PackedFile * pf = MEM_callocN(sizeof(*pf), "PackedFile");
+	PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
 	pf->data = mem;
 	pf->size = memlen;
 	
 	return pf;
 }
 
-PackedFile * newPackedFile(char * filename)
+PackedFile *newPackedFile(ReportList *reports, char *filename)
 {
-	PackedFile * pf = NULL;
+	PackedFile *pf = NULL;
 	int file, filelen;
 	char name[FILE_MAXDIR+FILE_MAXFILE];
-	void * data;
+	void *data;
 	
 	//XXX waitcursor(1);
 	
@@ -191,7 +181,7 @@ PackedFile * newPackedFile(char * filename)
 
 	file= open(name, O_BINARY|O_RDONLY);
 	if (file <= 0) {
-		// error("Can't open file: %s", name);
+		BKE_reportf(reports, RPT_ERROR, "Can't open file: %s", name);
 	} else {
 		filelen = BLI_filesize(file);
 
@@ -214,36 +204,24 @@ PackedFile * newPackedFile(char * filename)
 	return (pf);
 }
 
-void packAll()
+void packAll(Main *bmain, ReportList *reports)
 {
 	Image *ima;
 	VFont *vf;
 	bSample *sample;
 	
-	ima = G.main->image.first;
-	while (ima) {
-		if (ima->packedfile == NULL) {
-			ima->packedfile = newPackedFile(ima->name);
-		}
-		ima= ima->id.next;
-	}
-	
-	vf = G.main->vfont.first;
-	while (vf) {
-		if (vf->packedfile == NULL) {
-			vf->packedfile = newPackedFile(vf->name);
-		}
-		vf = vf->id.next;
-	}
+	for(ima=bmain->image.first; ima; ima=ima->id.next)
+		if(ima->packedfile == NULL)
+			ima->packedfile = newPackedFile(reports, ima->name);
 
+	for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+		if(vf->packedfile == NULL)
+			vf->packedfile = newPackedFile(reports, vf->name);
 
-	sample = samples->first;
-	while (sample) {
-		if (sample->packedfile == NULL) {
-			sound_set_packedfile(sample, newPackedFile(sample->name));
-		}
-		sample = sample->id.next;
-	}
+	if(samples)
+		for(sample=samples->first; sample; sample=sample->id.next)
+			if(sample->packedfile == NULL)
+				sound_set_packedfile(sample, newPackedFile(reports, sample->name));
 }
 
 
@@ -252,10 +230,10 @@ void packAll()
 // attempt to create a function that generates an unique filename
 // this will work when all funtions in fileops.c understand relative filenames...
 
-char * find_new_name(char * name)
+char *find_new_name(char *name)
 {
 	char tempname[FILE_MAXDIR + FILE_MAXFILE];
-	char * newname;
+	char *newname;
 	
 	if (fop_exists(name)) {
 		for (number = 1; number <= 999; number++) {
@@ -274,13 +252,13 @@ char * find_new_name(char * name)
 	
 */
 
-int writePackedFile(char * filename, PackedFile *pf, int guimode)
+int writePackedFile(ReportList *reports, char *filename, PackedFile *pf, int guimode)
 {
 	int file, number, remove_tmp = FALSE;
 	int ret_value = RET_OK;
 	char name[FILE_MAXDIR + FILE_MAXFILE];
 	char tempname[FILE_MAXDIR + FILE_MAXFILE];
-/*  	void * data; */
+/*  	void *data; */
 	
 	if (guimode); //XXX  waitcursor(1);
 	
@@ -305,23 +283,23 @@ int writePackedFile(char * filename, PackedFile *pf, int guimode)
 	file = open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
 	if (file >= 0) {
 		if (write(file, pf->data, pf->size) != pf->size) {
-			if(guimode) ; //XXX error("Error writing file: %s", name);
+			BKE_reportf(reports, RPT_ERROR, "Error writing file: %s", name);
 			ret_value = RET_ERROR;
 		}
 		close(file);
 	} else {
-		if(guimode); //XXX error("Error creating file: %s", name);
+		BKE_reportf(reports, RPT_ERROR, "Error creating file: %s", name);
 		ret_value = RET_ERROR;
 	}
 	
 	if (remove_tmp) {
 		if (ret_value == RET_ERROR) {
 			if (BLI_rename(tempname, name) != 0) {
-				if(guimode); //XXX error("Error restoring tempfile. Check files: '%s' '%s'", tempname, name);
+				BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name);
 			}
 		} else {
 			if (BLI_delete(tempname, 0, 0) != 0) {
-				if(guimode); //XXX error("Error deleting '%s' (ignored)");
+				BKE_reportf(reports, RPT_ERROR, "Error deleting '%s' (ignored)", tempname);
 			}
 		}
 	}
@@ -342,7 +320,7 @@ PF_NOFILE		- the original file doens't exist
 
 */
 
-int checkPackedFile(char * filename, PackedFile * pf)
+int checkPackedFile(char *filename, PackedFile *pf)
 {
 	struct stat st;
 	int ret_val, i, len, file;
@@ -390,68 +368,23 @@ int checkPackedFile(char * filename, PackedFile * pf)
 
 /*
 
-unpackFile() looks at the existing files (abs_name, local_name) and a packed file.
-If how == PF_ASK it offers the user a couple of options what to do with the packed file.
+   unpackFile() looks at the existing files (abs_name, local_name) and a packed file.
 
-It returns a char * to the existing file name / new file name or NULL when
+It returns a char *to the existing file name / new file name or NULL when
 there was an error or when the user desides to cancel the operation.
 
 */
 
-char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
+char *unpackFile(ReportList *reports, char *abs_name, char *local_name, PackedFile *pf, int how)
 {
-	char menu[6 * (FILE_MAXDIR + FILE_MAXFILE + 100)];
+	char menu[6 *(FILE_MAXDIR + FILE_MAXFILE + 100)];
 	char line[FILE_MAXDIR + FILE_MAXFILE + 100];
-	char * newname = NULL, * temp = NULL;
+	char *newname = NULL, *temp = NULL;
 	
 	// char newabs[FILE_MAXDIR + FILE_MAXFILE];
 	// char newlocal[FILE_MAXDIR + FILE_MAXFILE];
 	
 	if (pf != NULL) {
-		if (how == PF_ASK) {
-			sprintf(menu, "UnPack file%%t|Remove Pack %%x%d", PF_REMOVE);
-			
-			if (strcmp(abs_name, local_name)) {
-				switch (checkPackedFile(local_name, pf)) {
-					case PF_NOFILE:
-						sprintf(line, "|Create %s%%x%d", local_name, PF_WRITE_LOCAL);
-						strcat(menu, line);
-						break;
-					case PF_EQUAL:
-						sprintf(line, "|Use %s (identical)%%x%d", local_name, PF_USE_LOCAL);
-						strcat(menu, line);
-						break;
-					case PF_DIFFERS:
-						sprintf(line, "|Use %s (differs)%%x%d", local_name, PF_USE_LOCAL);
-						strcat(menu, line);
-						sprintf(line, "|Overwrite %s%%x%d", local_name, PF_WRITE_LOCAL);
-						strcat(menu, line);
-						break;
-				}
-				// sprintf(line, "|%%x%d", PF_INVALID);
-				// strcat(menu, line);
-			}
-			
-			switch (checkPackedFile(abs_name, pf)) {
-				case PF_NOFILE:
-					sprintf(line, "|Create %s%%x%d", abs_name, PF_WRITE_ORIGINAL);
-					strcat(menu, line);
-					break;
-				case PF_EQUAL:
-					sprintf(line, "|Use %s (identical)%%x%d", abs_name, PF_USE_ORIGINAL);
-					strcat(menu, line);
-					break;
-				case PF_DIFFERS:
-					sprintf(line, "|Use %s (differs)%%x%d", abs_name, PF_USE_ORIGINAL);
-					strcat(menu, line);
-					sprintf(line, "|Overwrite %s%%x%d", abs_name, PF_WRITE_ORIGINAL);
-					strcat(menu, line);
-					break;
-			}
-			
-			//XXX how = pupmenu(menu);
-		}
-		
 		switch (how) {
 			case -1:
 			case PF_KEEP:
@@ -467,7 +400,7 @@ char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 				}
 				// else fall through and create it
 			case PF_WRITE_LOCAL:
-				if (writePackedFile(local_name, pf, 1) == RET_OK) {
+				if (writePackedFile(reports, local_name, pf, 1) == RET_OK) {
 					temp = local_name;
 				}
 				break;
@@ -479,7 +412,7 @@ char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 				}
 				// else fall through and create it
 			case PF_WRITE_ORIGINAL:
-				if (writePackedFile(abs_name, pf, 1) == RET_OK) {
+				if (writePackedFile(reports, abs_name, pf, 1) == RET_OK) {
 					temp = abs_name;
 				}
 				break;
@@ -498,10 +431,10 @@ char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 }
 
 
-int unpackVFont(VFont * vfont, int how)
+int unpackVFont(ReportList *reports, VFont *vfont, int how)
 {
 	char localname[FILE_MAXDIR + FILE_MAXFILE], fi[FILE_MAXFILE];
-	char * newname;
+	char *newname;
 	int ret_value = RET_ERROR;
 	
 	if (vfont != NULL) {
@@ -510,7 +443,7 @@ int unpackVFont(VFont * vfont, int how)
 		
 		sprintf(localname, "//fonts/%s", fi);
 		
-		newname = unpackFile(vfont->name, localname, vfont->packedfile, how);
+		newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
 		if (newname != NULL) {
 			ret_value = RET_OK;
 			freePackedFile(vfont->packedfile);
@@ -523,10 +456,10 @@ int unpackVFont(VFont * vfont, int how)
 	return (ret_value);
 }
 
-int unpackSample(bSample *sample, int how)
+int unpackSample(ReportList *reports, bSample *sample, int how)
 {
 	char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
-	char * newname;
+	char *newname;
 	int ret_value = RET_ERROR;
 	PackedFile *pf;
 	
@@ -535,7 +468,7 @@ int unpackSample(bSample *sample, int how)
 		BLI_splitdirstring(localname, fi);
 		sprintf(localname, "//samples/%s", fi);
 		
-		newname = unpackFile(sample->name, localname, sample->packedfile, how);
+		newname = unpackFile(reports, sample->name, localname, sample->packedfile, how);
 		if (newname != NULL) {
 			strcpy(sample->name, newname);
 			MEM_freeN(newname);
@@ -553,10 +486,10 @@ int unpackSample(bSample *sample, int how)
 	return(ret_value);
 }
 
-int unpackImage(Image * ima, int how)
+int unpackImage(ReportList *reports, Image *ima, int how)
 {
 	char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
-	char * newname;
+	char *newname;
 	int ret_value = RET_ERROR;
 	
 	if (ima != NULL) {
@@ -564,7 +497,7 @@ int unpackImage(Image * ima, int how)
 		BLI_splitdirstring(localname, fi);
 		sprintf(localname, "//textures/%s", fi);
 			
-		newname = unpackFile(ima->name, localname, ima->packedfile, how);
+		newname = unpackFile(reports, ima->name, localname, ima->packedfile, how);
 		if (newname != NULL) {
 			ret_value = RET_OK;
 			freePackedFile(ima->packedfile);
@@ -578,33 +511,23 @@ int unpackImage(Image * ima, int how)
 	return(ret_value);
 }
 
-void unpackAll(int how)
+void unpackAll(Main *bmain, ReportList *reports, int how)
 {
 	Image *ima;
 	VFont *vf;
 	bSample *sample;
-		
-	ima = G.main->image.first;
-	while (ima) {
-		if (ima->packedfile) {
-			unpackImage(ima, how);
-		}
-		ima= ima->id.next;
-	}
-	
-	vf = G.main->vfont.first;
-	while (vf) {
-		if (vf->packedfile) {
-			unpackVFont(vf, how);
-		}
-		vf = vf->id.next;
-	}
 
-	sample = samples->first;
-	while (sample) {
-		if (sample->packedfile) {
-			unpackSample(sample, how);
-		}
-		sample = sample->id.next;
-	}
+	for(ima=bmain->image.first; ima; ima=ima->id.next)
+		if(ima->packedfile)
+			unpackImage(reports, ima, how);
+
+	for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+		if(vf->packedfile)
+			unpackVFont(reports, vf, how);
+
+	if(samples)
+		for(sample=samples->first; sample; sample=sample->id.next)
+			if(sample->packedfile)
+				unpackSample(reports, sample, how);
 }
+
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 34e69b2d736..5bf9335d211 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -222,6 +222,34 @@ short psys_get_current_num(Object *ob)
 	
 	return i;
 }
+void psys_set_current_num(Object *ob, int index)
+{
+	ParticleSystem *psys;
+	short i;
+
+	if(ob==0) return;
+
+	for(psys=ob->particlesystem.first, i=0; psys; psys=psys->next, i++) {
+		if(i == index)
+			psys->flag |= PSYS_CURRENT;
+		else
+			psys->flag &= ~PSYS_CURRENT;
+	}
+}
+Object *psys_find_object(Scene *scene, ParticleSystem *psys)
+{
+	Base *base = scene->base.first;
+	ParticleSystem *tpsys;
+
+	for(base = scene->base.first; base; base = base->next) {
+		for(tpsys = base->object->particlesystem.first; psys; psys=psys->next) {
+			if(tpsys == psys)
+				return base->object;
+		}
+	}
+
+	return NULL;
+}
 /* change object's active particle system */
 void psys_change_act(void *ob_v, void *act_v)
 {
@@ -293,7 +321,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
 	ParticleSystemModifierData *psmd;
 	Mesh *me;
 
-	if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE)
+	if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE || !psys->part)
 		return 0;
 
 	if(ob->type == OB_MESH) {
@@ -864,7 +892,7 @@ static void weighted_particle_vector(float *v1, float *v2, float *v3, float *v4,
 	vec[1]= weights[0]*v1[1] + weights[1]*v2[1] + weights[2]*v3[1] + weights[3]*v4[1];
 	vec[2]= weights[0]*v1[2] + weights[1]*v2[2] + weights[2]*v3[2] + weights[3]*v4[2];
 }
-static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
+void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
 {
 	float t[4];
 
@@ -2569,7 +2597,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
 			}
 
 			/* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/
-			interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
+			psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
 				: ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
 				,keys, keytime, &result, 0);
 
@@ -2901,6 +2929,61 @@ void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleDa
 /************************************************/
 /*			ParticleSettings handling			*/
 /************************************************/
+void object_add_particle_system(Scene *scene, Object *ob)
+{
+	ParticleSystem *psys;
+	ModifierData *md;
+	ParticleSystemModifierData *psmd;
+
+	if(!ob || ob->type != OB_MESH)
+		return;
+
+	psys = ob->particlesystem.first;
+	for(; psys; psys=psys->next)
+		psys->flag &= ~PSYS_CURRENT;
+
+	psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+	psys->pointcache = BKE_ptcache_add();
+	BLI_addtail(&ob->particlesystem, psys);
+
+	psys->part = psys_new_settings("PSys", NULL);
+
+	md= modifier_new(eModifierType_ParticleSystem);
+	sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+	psmd= (ParticleSystemModifierData*) md;
+	psmd->psys=psys;
+	BLI_addtail(&ob->modifiers, md);
+
+	psys->totpart=0;
+	psys->flag = PSYS_ENABLED|PSYS_CURRENT;
+	psys->cfra=bsystem_time(scene,ob,scene->r.cfra+1,0.0);
+
+	DAG_scene_sort(scene);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+void object_remove_particle_system(Scene *scene, Object *ob)
+{
+	ParticleSystem *psys = psys_get_current(ob);
+	ParticleSystemModifierData *psmd;
+
+	if(!psys)
+		return;
+
+	/* clear modifier */
+	psmd= psys_get_modifier(ob, psys);
+	BLI_remlink(&ob->modifiers, psmd);
+	modifier_free((ModifierData *)psmd);
+
+	/* clear particle system */
+	BLI_remlink(&ob->particlesystem, psys);
+	psys_free(ob,psys);
+
+	if(ob->particlesystem.first)
+		((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT;
+
+	DAG_scene_sort(scene);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
 static void default_particle_settings(ParticleSettings *part)
 {
 	int i;
@@ -2987,6 +3070,9 @@ ParticleSettings *psys_new_settings(char *name, Main *main)
 {
 	ParticleSettings *part;
 
+	if(main==NULL)
+		main = G.main;
+
 	part= alloc_libblock(&main->particle, ID_PA, name);
 	
 	default_particle_settings(part);
@@ -3062,7 +3148,6 @@ void make_local_particlesettings(ParticleSettings *part)
 		}
 	}
 }
-
 void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
 {
 	Base *base = scene->base.first;
@@ -3495,7 +3580,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
 			QuatInterpol(state->rot,keys[1].rot,keys[2].rot,keytime);
 		}
 
-		interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
+		psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
 			: ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
 			,keys, keytime, state, 1);
 
@@ -3702,6 +3787,8 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
 			if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
 				|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
 				return 0;
+
+		state->time = MIN2(state->time, pa->dietime);
 	}
 
 	if(psys->flag & PSYS_KEYED){
@@ -3776,7 +3863,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
 							VecMulf(keys[1].vel, dfra / frs_sec);
 							VecMulf(keys[2].vel, dfra / frs_sec);
 							
-							interpolate_particle(-1, keys, keytime, state, 1);
+							psys_interpolate_particle(-1, keys, keytime, state, 1);
 							
 							/* convert back to real velocity */
 							VecMulf(state->vel, frs_sec / dfra);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 52f13eeadb8..591b6ca9be5 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -29,6 +29,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include 
 #include 
 #include 
@@ -104,7 +106,8 @@ static int get_current_display_percentage(ParticleSystem *psys)
 {
 	ParticleSettings *part=psys->part;
 
-	if(psys->renderdata || (part->child_nbr && part->childtype)) 
+	if(psys->renderdata || (part->child_nbr && part->childtype)
+		|| (psys->pointcache->flag & PTCACHE_BAKING))
 		return 100;
 
 	if(part->phystype==PART_PHYS_KEYED){
@@ -2195,57 +2198,91 @@ void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_o
 /************************************************/
 /*			Point Cache							*/
 /************************************************/
+void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
+{
+	ParticleSettings *part = psys->part;
 
-static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
+	*sfra = MAX2(1, (int)part->sta);
+	*efra = MIN2((int)(part->end + part->lifetime + 1.0), scene->r.efra);
+}
+static void particle_write_state(int index, ParticleSystem *psys, float *data)
 {
-	PTCacheID pid;
-	PTCacheFile *pf;
-	ParticleData *pa;
-	int i, totpart= psys->totpart;
+	memcpy(data, (float *)(&(psys->particles+index)->state), sizeof(ParticleKey));
+}
+static void particle_read_state(int index, void *psys_ptr, float *data)
+{
+	ParticleSystem *psys= psys_ptr;
+	ParticleData *pa = psys->particles + index;
+	ParticleKey *key = (ParticleKey *)data;
 
-	if(totpart == 0)
-		return;
+	if(key->time > pa->state.time)
+		copy_particle_key(&pa->prev_state, &pa->state, 1);
 
-	BKE_ptcache_id_from_particles(&pid, ob, psys);
-	pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, cfra);
-	if(!pf)
+	copy_particle_key(&pa->state, key, 1);
+}
+static void particle_cache_interpolate(int index, void *psys_ptr, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
+{
+	ParticleSystem *psys= psys_ptr;
+	ParticleData *pa = psys->particles + index;
+	ParticleKey keys[4];
+	float dfra, cfra1f = (float)cfra1, cfra2f(float);
+
+	cfra = MIN2(cfra, pa->dietime);
+	cfra1 = MIN2(cfra1, pa->dietime);
+	cfra2 = MIN2(cfra2, pa->dietime);
+
+	keys[1] = *((ParticleKey*)data1);
+	keys[2] = *((ParticleKey*)data2);
+
+	if(cfra1 == cfra2) {
+		copy_particle_key(&pa->state, &keys[1], 1);
 		return;
+	}
 
-	/* assuming struct consists of tightly packed floats */
-	for(i=0, pa=psys->particles; istate, sizeof(ParticleKey)/sizeof(float));
-	
-	BKE_ptcache_file_close(pf);
-}
+	dfra = cfra2 - cfra1;
 
-static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
+	VecMulf(keys[1].vel, dfra / frs_sec);
+	VecMulf(keys[2].vel, dfra / frs_sec);
+
+	psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
+
+	VecMulf(pa->state.vel, frs_sec / dfra);
+
+	pa->state.time = cfra;
+}
+static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
 {
+	PTCacheWriter writer;
 	PTCacheID pid;
-	PTCacheFile *pf;
-	ParticleData *pa;
-	int i, totpart= psys->totpart;
-
-	if(totpart == 0)
-		return 0;
 
 	BKE_ptcache_id_from_particles(&pid, ob, psys);
-	pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, cfra);
-	if(!pf)
-		return 0;
 
-	/* assuming struct consists of tightly packed floats */
-	for(i=0, pa=psys->particles; istate.time)
-			copy_particle_key(&pa->prev_state,&pa->state,1);
-		if(!BKE_ptcache_file_read_floats(pf, (float*)&pa->state, sizeof(ParticleKey)/sizeof(float))) {
-			BKE_ptcache_file_close(pf);
-			return 0;
-		}
-	}
+	writer.calldata = psys;
+	writer.cfra = cfra;
+	writer.set_elem = particle_write_state;
+	writer.pid = &pid;
+	writer.totelem = psys->totpart;
 
-	BKE_ptcache_file_close(pf);
+	BKE_ptcache_write_cache(&writer);
+}
 
-	return 1;
+static int get_particles_from_cache(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int *old_frame)
+{
+	PTCacheReader reader;
+	PTCacheID pid;
+	
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+
+	reader.calldata = psys;
+	reader.cfra = cfra;
+	reader.interpolate_elem = particle_cache_interpolate;
+	reader.old_frame = old_frame;
+	reader.pid = &pid;
+	reader.scene = scene;
+	reader.set_elem = particle_read_state;
+	reader.totelem = psys->totpart;
+
+	return BKE_ptcache_read_cache(&reader);
 }
 
 /************************************************/
@@ -2372,6 +2409,8 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs
 		Object *tob;
 
 		for(i=0; epsys; epsys=epsys->next,i++){
+			if(!psys_check_enabled(ob, epsys))
+				continue;
 			type=0;
 			if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
 				epart=epsys->part;
@@ -4085,7 +4124,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
 
 		/* main loop: calculate physics for all particles */
 		for(p=0, pa=psys->particles; pflag & PARS_UNEXIST) continue;
+			if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
 
 			copy_particle_key(&pa->prev_state,&pa->state,1);
 			
@@ -4110,25 +4149,26 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
 			if(pa->alive==PARS_UNBORN
 				|| pa->alive==PARS_KILLED
 				|| ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
-				|| birthtime >= cfra){
+				|| birthtime >= psys->cfra){
 				reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
 			}
 
 			pa_dfra = dfra;
 			pa_dtime = dtime;
 
-			if(birthtime <= cfra && birthtime >= psys->cfra){
+
+			if(dietime <= cfra && psys->cfra < dietime){
+				/* particle dies some time between this and last step */
+				pa_dfra = dietime - ((birthtime > psys->cfra) ? birthtime : psys->cfra);
+				pa_dtime = pa_dfra * timestep;
+				pa->alive = PARS_DYING;
+			}
+			else if(birthtime <= cfra && birthtime >= psys->cfra){
 				/* particle is born some time between this and last step*/
 				pa->alive = PARS_ALIVE;
 				pa_dfra = cfra - birthtime;
 				pa_dtime = pa_dfra*timestep;
 			}
-			else if(dietime <= cfra && psys->cfra < dietime){
-				/* particle dies some time between this and last step */
-				pa_dfra = dietime - psys->cfra;
-				pa_dtime = pa_dfra * timestep;
-				pa->alive = PARS_DYING;
-			}
 			else if(dietime < cfra){
 				/* nothing to be done when particle is dead */
 			}
@@ -4335,7 +4375,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
 			pa->alive = PARS_UNBORN;
 		else if(dietime <= cfra){
 			if(dietime > psys->cfra){
-				state.time = pa->dietime;
+				state.time = dietime;
 				psys_get_particle_state(scene, ob,psys,p,&state,1);
 				push_reaction(ob,psys,p,PART_EVENT_DEATH,&state);
 			}
@@ -4520,7 +4560,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 	int totpart, oldtotpart, totchild, oldtotchild, p;
 	float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
 	int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
-	int framenr, framedelta, startframe, endframe;
+	int framenr, framedelta, startframe, endframe, old_framenr;
 
 	part= psys->part;
 	cache= psys->pointcache;
@@ -4528,6 +4568,10 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 	framenr= (int)scene->r.cfra;
 	framedelta= framenr - cache->simframe;
 
+	/* set suitable cache range automatically */
+	if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0)
+		psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe);
+
 	BKE_ptcache_id_from_particles(&pid, ob, psys);
 	BKE_ptcache_id_time(&pid, scene, 0.0f, &startframe, &endframe, NULL);
 
@@ -4600,9 +4644,13 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 
 	if(init) {
 		if(distr) {
-			if(alloc)
+			if(alloc) {
 				realloc_particles(ob, psys, totpart);
 
+				if(usecache)
+					BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
+			}
+
 			distribute_particles(scene, ob, psys, part->from);
 
 			if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
@@ -4616,9 +4664,11 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 			free_keyed_keys(psys);
 
 			initialize_all_particles(ob, psys, psmd);
+			
 
-			if(alloc)
+			if(alloc) {
 				reset_all_particles(scene, ob, psys, psmd, 0.0, cfra, oldtotpart);
+			}
 		}
 
 		/* flag for possible explode modifiers after this system */
@@ -4627,46 +4677,59 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 
 	/* try to read from the cache */
 	if(usecache) {
-		if(get_particles_from_cache(ob, psys, framenr)) {
-			if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
-				psys_count_keyed_targets(ob,psys);
-				set_keyed_keys(scene, ob, psys);
-			}
+		int result = get_particles_from_cache(scene, ob, psys, (float)framenr, &old_framenr);
+
+		if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
+			//if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
+			//	psys_count_keyed_targets(ob,psys);
+			//	set_keyed_keys(scene, ob, psys);
+			//}
 
 			cached_step(scene, ob, psmd, psys, cfra);
 			psys->cfra=cfra;
 			psys->recalc = 0;
 
-			if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
-				psys_update_path_cache(scene, ob, psmd, psys, framenr);
-			}
+			//if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
+			//	psys_update_path_cache(scene, ob, psmd, psys, framenr);
+			//}
 
 			cache->simframe= framenr;
 			cache->flag |= PTCACHE_SIMULATION_VALID;
 
+			if(result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+				write_particles_to_cache(ob, psys, cfra);
+
 			return;
 		}
+		else if(result==PTCACHE_READ_OLD) {
+			/* set old cfra */
+			psys->cfra = (float)old_framenr;
+
+			for(p=0, pa=psys->particles; ptime > psys->cfra)
+					pa->alive = PARS_UNBORN;
+				else if(pa->dietime <= psys->cfra)
+					pa->alive = PARS_DEAD;
+				else
+					pa->alive = PARS_ALIVE;
+			}
+		}
 		else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
 			psys_reset(psys, PSYS_RESET_CACHE_MISS);
 			psys->cfra=cfra;
 			psys->recalc = 0;
 			return;
 		}
-
-		if(framenr != startframe && framedelta != 1) {
-			psys_reset(psys, PSYS_RESET_CACHE_MISS);
-			psys->cfra = cfra;
-			psys->recalc = 0;
-			return;
-		}
 	}
 	else {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 	}
 
 	/* if on second frame, write cache for first frame */
-	if(usecache && framenr == startframe+1)
+	if(usecache && psys->cfra == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
 		write_particles_to_cache(ob, psys, startframe);
 
 	if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED)
@@ -4768,8 +4831,7 @@ static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys)
 static int hair_needs_recalc(ParticleSystem *psys)
 {
 	if((psys->flag & PSYS_EDITED)==0 &&
-		((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_REDO)) {
-		psys->recalc &= ~PSYS_RECALC_REDO;
+		((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET)) {
 		return 1;
 	}
 
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index b00755f7135..64473d07151 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -51,9 +51,11 @@
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_scene.h"
 #include "BKE_softbody.h"
 #include "BKE_utildefines.h"
 
+#include "BLI_blenlib.h"
 
 /* needed for directory lookup */
 #ifndef WIN32
@@ -213,21 +215,29 @@ static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, sho
 	filename[0] = '\0';
 	newname = filename;
 	
-	/*if (!G.relbase_valid) return 0; *//* save blend file before using pointcache */
+	if (!G.relbase_valid) return 0; /* save blend file before using disk pointcache */
 	
 	/* start with temp dir */
 	if (do_path) {
 		len = ptcache_path(pid, filename);
 		newname += len;
 	}
-	idname = (pid->ob->id.name+2);
-	/* convert chars to hex so they are always a valid filename */
-	while('\0' != *idname) {
-		snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
-		newname+=2;
-		len += 2;
+	if(strcmp(pid->cache->name, "")==0) {
+		idname = (pid->ob->id.name+2);
+		/* convert chars to hex so they are always a valid filename */
+		while('\0' != *idname) {
+			snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
+			newname+=2;
+			len += 2;
+		}
 	}
-	
+	else {
+		int temp = strlen(pid->cache->name); 
+		strcpy(newname, pid->cache->name); 
+		newname+=temp;
+		len += temp;
+	}
+
 	if (do_ext) {
 		snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
 		len += 16;
@@ -247,7 +257,7 @@ PTCacheFile *BKE_ptcache_file_open(PTCacheID *pid, int mode, int cfra)
 	if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
 		return NULL;
 
-	/*if (!G.relbase_valid) return NULL; *//* save blend file before using pointcache */
+	if (!G.relbase_valid) return NULL; /* save blend file before using disk pointcache */
 	
 	BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
 
@@ -286,6 +296,427 @@ int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot)
 	return (fwrite(f, sizeof(float), tot, pf->fp) == tot);
 }
 
+static int ptcache_pid_elemsize(PTCacheID *pid)
+{
+	if(pid->type==PTCACHE_TYPE_SOFTBODY)
+		return 0; // TODO
+	else if(pid->type==PTCACHE_TYPE_PARTICLES)
+		return sizeof(ParticleKey);
+	else if(pid->type==PTCACHE_TYPE_CLOTH)
+		return 9 * sizeof(float);
+
+	return 0;
+}
+static int ptcache_pid_totelem(PTCacheID *pid)
+{
+	if(pid->type==PTCACHE_TYPE_SOFTBODY)
+		return 0; // TODO
+	else if(pid->type==PTCACHE_TYPE_PARTICLES) {
+		ParticleSystem *psys = pid->data;
+		return psys->totpart;
+	}
+	else if(pid->type==PTCACHE_TYPE_CLOTH)
+		return 0; // TODO
+
+	return 0;
+}
+
+void BKE_ptcache_update_info(PTCacheID *pid)
+{
+	PointCache *cache = pid->cache;
+	int totframes = 0;
+	char mem_info[64];
+
+	if(cache->flag & PTCACHE_DISK_CACHE) {
+		int cfra = cache->startframe;
+
+		for(; cfra<=cache->endframe; cfra++) {
+			if(BKE_ptcache_id_exist(pid, cfra))
+				totframes++;
+		}
+
+		sprintf(mem_info, "%i frames on disk", totframes);
+	}
+	else {
+		PTCacheMem *pm = cache->mem_cache.first;		
+		float framesize = 0.0f, bytes = 0.0f;
+		int mb;
+
+		if(pm)
+			framesize = (float)ptcache_pid_elemsize(pid) * (float)pm->totpoint;
+		
+		for(; pm; pm=pm->next)
+			totframes++;
+
+		bytes = totframes * framesize;
+
+		mb = (bytes > 1024.0f * 1024.0f);
+
+		sprintf(mem_info, "%i frames in memory (%.1f %s)",
+			totframes,
+			bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
+			mb ? "Mb" : "kb");
+	}
+
+	if(cache->flag & PTCACHE_OUTDATED) {
+		sprintf(cache->info, "%s, cache is outdated!", mem_info);
+	}
+	else if(cache->flag & PTCACHE_FRAMES_SKIPPED) {
+		sprintf(cache->info, "%s, not exact since frame %i.", mem_info, cache->last_exact);
+	}
+	else
+		sprintf(cache->info, "%s.", mem_info);
+}
+/* reads cache from disk or memory */
+/* possible to get old or interpolated result */
+int BKE_ptcache_read_cache(PTCacheReader *reader)
+{
+	PTCacheID *pid = reader->pid;
+	PTCacheFile *pf=NULL, *pf2=NULL;
+	PTCacheMem *pm=NULL, *pm2=NULL;
+	int totelem = reader->totelem;
+	float cfra = reader->cfra;
+	int cfrai = (int)cfra;
+	int elemsize = ptcache_pid_elemsize(pid);
+	int i, incr = elemsize / sizeof(float);
+	float frs_sec = reader->scene->r.frs_sec;
+	int cfra1=0, cfra2;
+	int ret = 0;
+
+	if(totelem == 0)
+		return 0;
+
+
+	/* first check if we have the actual frame cached */
+	if(cfra == (float)cfrai) {
+		if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+			pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+		}
+		else {
+			pm = pid->cache->mem_cache.first;
+
+			for(; pm; pm=pm->next) {
+				if(pm->frame == cfrai)
+					break;
+			}
+		}
+	}
+
+	/* if found, use exact frame */
+	if(pf || pm) {
+		float *data;
+
+		if(pm)
+			data = pm->data;
+		else
+			data = MEM_callocN(elemsize, "pointcache read data");
+
+		for(i=0; iset_elem(i, reader->calldata, data);
+			}
+			else {
+				reader->set_elem(i, reader->calldata, data);
+				data += incr;
+			}
+		}
+
+		if(pf) {
+			BKE_ptcache_file_close(pf);
+			MEM_freeN(data);
+		}
+
+		ret = PTCACHE_READ_EXACT;
+	}
+
+	if(ret)
+		;
+	/* no exact cache frame found so try to find cached frames around cfra */
+	else if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+		pf=NULL;
+		while(cfrai > pid->cache->startframe && !pf) {
+			cfrai--;
+			pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+			cfra1 = cfrai;
+		}
+
+		if(reader->old_frame)
+			*(reader->old_frame) = cfrai;
+
+		cfrai = (int)cfra;
+		while(cfrai < pid->cache->endframe && !pf2) {
+			cfrai++;
+			pf2= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+			cfra2 = cfrai;
+		}
+	}
+	else if(pid->cache->mem_cache.first){
+		pm = pid->cache->mem_cache.first;
+
+		while(pm->next && pm->next->frame < cfra)
+			pm= pm->next;
+
+		if(pm) {
+			if(reader->old_frame)
+				*(reader->old_frame) = pm->frame;
+			cfra1 = pm->frame;
+		}
+
+		pm2 = pid->cache->mem_cache.last;
+
+		if(pm2 && pm2->frame < cfra)
+			pm2 = NULL;
+		else {
+			while(pm2->prev && pm2->prev->frame > cfra)
+				pm2= pm2->prev;
+
+			if(pm2)
+				cfra2 = pm2->frame;
+		}
+	}
+
+	if(ret)
+		;
+	else if((pf && pf2) || (pm && pm2)) {
+		/* interpolate from nearest frames if cache isn't outdated */
+		float *data1, *data2;
+
+		if(pm) {
+			data1 = pm->data;
+			data2 = pm2->data;
+		}
+		else {
+			data1 = MEM_callocN(elemsize, "pointcache read data1");
+			data2 = MEM_callocN(elemsize, "pointcache read data2");
+		}
+
+		for(i=0; iinterpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
+			}
+			else {
+				reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
+				data1 += incr;
+				data2 += incr;
+			}
+		}
+
+		if(pf) {
+			BKE_ptcache_file_close(pf);
+			BKE_ptcache_file_close(pf2);
+			MEM_freeN(data1);
+			MEM_freeN(data2);
+		}
+
+		ret = PTCACHE_READ_INTERPOLATED;
+	}
+	else if(pf || pm) {
+		/* use last valid cache frame */
+		float *data;
+
+		/* don't read cache if allready simulated past cached frame */
+		if(cfra1 && cfra1 <= pid->cache->simframe) {
+			if(pf)
+				BKE_ptcache_file_close(pf);
+			if(pf2)
+				BKE_ptcache_file_close(pf2);
+
+			return 0;
+		}
+
+		if(pm)
+			data = pm->data;
+		else
+			data = MEM_callocN(elemsize, "pointcache read data");
+
+		for(i=0; iset_elem(i, reader->calldata, data);
+			}
+			else {
+				reader->set_elem(i, reader->calldata, data);
+				data += incr;
+			}
+		}
+
+		if(pf) {
+			BKE_ptcache_file_close(pf);
+			MEM_freeN(data);
+		}
+		if(pf2)
+			BKE_ptcache_file_close(pf2);
+
+		ret = PTCACHE_READ_OLD;
+	}
+
+	if(pf)
+		BKE_ptcache_file_close(pf);
+	if(pf2)
+		BKE_ptcache_file_close(pf2);
+
+	if((pid->cache->flag & PTCACHE_QUICK_CACHE)==0) {
+		/* clear invalid cache frames so that better stuff can be simulated */
+		if(pid->cache->flag & PTCACHE_OUTDATED) {
+			BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfra);
+		}
+		else if(pid->cache->flag & PTCACHE_FRAMES_SKIPPED) {
+			if(cfra <= pid->cache->last_exact)
+				pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
+
+			BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfra,pid->cache->last_exact));
+		}
+	}
+
+	return ret;
+}
+/* writes cache to disk or memory */
+int BKE_ptcache_write_cache(PTCacheWriter *writer)
+{
+	PointCache *cache = writer->pid->cache;
+	PTCacheFile *pf= NULL;
+	int elemsize = ptcache_pid_elemsize(writer->pid);
+	int i, incr = elemsize / sizeof(float);
+	int add = 0, overwrite = 0, ocfra;
+	float temp[14];
+
+	if(writer->totelem == 0 || writer->cfra <= 0)
+		return 0;
+
+	if(cache->flag & PTCACHE_DISK_CACHE) {
+		/* allways start from scratch on the first frame */
+		if(writer->cfra == cache->startframe) {
+			BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
+			cache->flag &= ~PTCACHE_REDO_NEEDED;
+			add = 1;
+		}
+		else {
+			int cfra = cache->endframe;
+			/* find last cached frame */
+			while(cfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, cfra))
+				cfra--;
+
+			/* find second last cached frame */
+			ocfra = cfra-1;
+			while(ocfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, ocfra))
+				ocfra--;
+
+			if(writer->cfra > cfra) {
+				if(ocfra >= cache->startframe && cfra - ocfra < cache->step)
+					overwrite = 1;
+				else
+					add = 1;
+			}
+		}
+
+		if(add || overwrite) {
+			if(overwrite)
+				BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_FRAME, ocfra);
+
+			pf = BKE_ptcache_file_open(writer->pid, PTCACHE_FILE_WRITE, writer->cfra);
+			if(!pf)
+				return 0;
+
+			for(i=0; itotelem; i++) {
+				writer->set_elem(i, writer->calldata, &temp);
+				BKE_ptcache_file_write_floats(pf, &temp, incr);
+			}
+		}
+	}
+	else {
+		PTCacheMem *pm;
+		PTCacheMem *pm2;
+		float *pmdata;
+
+		pm2 = cache->mem_cache.first;
+		
+		/* allways start from scratch on the first frame */
+		if(writer->cfra == cache->startframe) {
+			BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
+			cache->flag &= ~PTCACHE_REDO_NEEDED;
+			add = 1;
+		}
+		else {
+			pm2 = cache->mem_cache.last;
+
+			if(pm2 && writer->cfra > pm2->frame) {
+				if(pm2 && pm2->prev && pm2->frame - pm2->prev->frame < cache->step)
+					overwrite = 1;
+				else
+					add = 1;
+			}
+		}
+
+		if(overwrite) {
+			pm = cache->mem_cache.last;
+			pmdata = pm->data;
+
+			for(i=0; itotelem; i++, pmdata+=incr) {
+				writer->set_elem(i, writer->calldata, &temp);
+				memcpy(pmdata, &temp, elemsize);
+			}
+
+			pm->frame = writer->cfra;
+		}
+		else if(add) {
+			pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+			pm->data = MEM_callocN(elemsize * writer->totelem, "Pointcache mem data");
+			pmdata = pm->data;
+
+			for(i=0; itotelem; i++, pmdata+=incr) {
+				writer->set_elem(i, writer->calldata, &temp);
+				memcpy(pmdata, &temp, elemsize);
+			}
+
+			pm->frame = writer->cfra;
+			pm->totpoint = writer->totelem;
+
+			BLI_addtail(&cache->mem_cache, pm);
+		}
+	}
+
+	if(add || overwrite) {
+		if(writer->cfra - cache->last_exact == 1
+			|| writer->cfra == cache->startframe) {
+			cache->last_exact = writer->cfra;
+			cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
+		}
+		else
+			cache->flag |= PTCACHE_FRAMES_SKIPPED;
+	}
+	
+	if(pf)
+		BKE_ptcache_file_close(pf);
+
+	BKE_ptcache_update_info(writer->pid);
+
+	return 1;
+}
 /* youll need to close yourself after!
  * mode - PTCACHE_CLEAR_ALL, 
 
@@ -317,62 +748,116 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
 	case PTCACHE_CLEAR_ALL:
 	case PTCACHE_CLEAR_BEFORE:	
 	case PTCACHE_CLEAR_AFTER:
-		ptcache_path(pid, path);
-		
-		len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
-		
-		dir = opendir(path);
-		if (dir==NULL)
-			return;
-
-		snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
-		
-		while ((de = readdir(dir)) != NULL) {
-			if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
-				if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
-					if (mode == PTCACHE_CLEAR_ALL) {
-						BLI_join_dirfile(path_full, path, de->d_name);
-						BLI_delete(path_full, 0, 0);
-					} else {
-						/* read the number of the file */
-						int frame, len2 = strlen(de->d_name);
-						char num[7];
-
-						if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
-							BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
-							frame = atoi(num);
-							
-							if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra)	|| 
-							   (mode==PTCACHE_CLEAR_AFTER && frame > cfra)	) {
+		if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+			ptcache_path(pid, path);
+			
+			len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
+			
+			dir = opendir(path);
+			if (dir==NULL)
+				return;
+
+			snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
+			
+			while ((de = readdir(dir)) != NULL) {
+				if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
+					if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+						if (mode == PTCACHE_CLEAR_ALL) {
+							pid->cache->last_exact = 0;
+							BLI_join_dirfile(path_full, path, de->d_name);
+							BLI_delete(path_full, 0, 0);
+						} else {
+							/* read the number of the file */
+							int frame, len2 = strlen(de->d_name);
+							char num[7];
+
+							if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+								BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
+								frame = atoi(num);
 								
-								BLI_join_dirfile(path_full, path, de->d_name);
-								BLI_delete(path_full, 0, 0);
+								if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra)	|| 
+								(mode==PTCACHE_CLEAR_AFTER && frame > cfra)	) {
+									
+									BLI_join_dirfile(path_full, path, de->d_name);
+									BLI_delete(path_full, 0, 0);
+								}
 							}
 						}
 					}
 				}
 			}
+			closedir(dir);
+		}
+		else {
+			PTCacheMem *pm= pid->cache->mem_cache.first;
+			PTCacheMem *link= NULL;
+
+			if(mode == PTCACHE_CLEAR_ALL) {
+				pid->cache->last_exact = 0;
+				for(; pm; pm=pm->next)
+					MEM_freeN(pm->data);
+				BLI_freelistN(&pid->cache->mem_cache);
+			} else {
+				while(pm) {
+					if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra)	|| 
+					(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra)	) {
+						link = pm;
+						pm = pm->next;
+						MEM_freeN(link->data);
+						BLI_freelinkN(&pid->cache->mem_cache, link);
+					}
+					else
+						pm = pm->next;
+				}
+			}
 		}
-		closedir(dir);
 		break;
 		
 	case PTCACHE_CLEAR_FRAME:
-		len = BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
-		BLI_delete(filename, 0, 0);
+		if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+			if(BKE_ptcache_id_exist(pid, cfra)) {
+				BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
+				BLI_delete(filename, 0, 0);
+			}
+		}
+		else {
+			PTCacheMem *pm = pid->cache->mem_cache.first;
+
+			for(; pm; pm=pm->next) {
+				if(pm->frame == cfra) {
+					MEM_freeN(pm->data);
+					BLI_freelinkN(&pid->cache->mem_cache, pm);
+					break;
+				}
+			}
+		}
 		break;
 	}
+
+	BKE_ptcache_update_info(pid);
 }
 
 int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
 {
-	char filename[MAX_PTCACHE_FILE];
-
 	if(!pid->cache)
 		return 0;
 	
-	BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
+	if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+		char filename[MAX_PTCACHE_FILE];
+		
+		BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
 
-	return BLI_exists(filename);
+		return BLI_exists(filename);
+	}
+	else {
+		PTCacheMem *pm = pid->cache->mem_cache.first;
+
+		for(; pm; pm=pm->next) {
+			if(pm->frame==cfra)
+				return 1;
+		}
+		return 0;
+	}
 }
 
 void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
@@ -381,6 +866,9 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
 	PointCache *cache;
 	float offset, time, nexttime;
 
+	/* TODO: this has to be sorter out once bsystem_time gets redone, */
+	/*       now caches can handle interpolating etc. too - jahka */
+
 	/* time handling for point cache:
 	 * - simulation time is scaled by result of bsystem_time
 	 * - for offsetting time only time offset is taken into account, since
@@ -414,10 +902,10 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
 	}
 }
 
-int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
+int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
 {
 	PointCache *cache;
-	int reset, clear;
+	int reset, clear, after;
 
 	if(!pid->cache)
 		return 0;
@@ -425,14 +913,17 @@ int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
 	cache= pid->cache;
 	reset= 0;
 	clear= 0;
+	after= 0;
 
 	if(mode == PTCACHE_RESET_DEPSGRAPH) {
 		if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
-			reset= 1;
-			clear= 1;
+			if(cache->flag & PTCACHE_QUICK_CACHE)
+				clear= 1;
+
+			after= 1;
 		}
-		else
-			cache->flag |= PTCACHE_OUTDATED;
+
+		cache->flag |= PTCACHE_OUTDATED;
 	}
 	else if(mode == PTCACHE_RESET_BAKED) {
 		if(!BKE_ptcache_get_continue_physics()) {
@@ -451,8 +942,9 @@ int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
 	}
 
 	if(reset) {
-		cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_SIMULATION_VALID);
+		cache->flag &= ~(PTCACHE_REDO_NEEDED|PTCACHE_SIMULATION_VALID);
 		cache->simframe= 0;
+		cache->last_exact= 0;
 
 		if(pid->type == PTCACHE_TYPE_CLOTH)
 			cloth_free_modifier(pid->ob, pid->data);
@@ -463,11 +955,13 @@ int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
 	}
 	if(clear)
 		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+	else if(after)
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, CFRA);
 
-	return (reset || clear);
+	return (reset || clear || after);
 }
 
-int BKE_ptcache_object_reset(Object *ob, int mode)
+int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
 {
 	PTCacheID pid;
 	ParticleSystem *psys;
@@ -479,7 +973,7 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
 
 	if(ob->soft) {
 		BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
-		reset |= BKE_ptcache_id_reset(&pid, mode);
+		reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 	}
 
 	for(psys=ob->particlesystem.first; psys; psys=psys->next) {
@@ -488,23 +982,23 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
 		if(psys->soft) {
 			BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
 			if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED))) 
-				reset |= BKE_ptcache_id_reset(&pid, mode);
+				reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 			else
 				skip = 1;
 		}
-		else if((psys->recalc & PSYS_RECALC_RESET)==0)
+		else if(psys->recalc & PSYS_RECALC_REDO || psys->recalc & PSYS_RECALC_CHILD)
 			skip = 1;
 
 		if(skip == 0) {
 			BKE_ptcache_id_from_particles(&pid, ob, psys);
-			reset |= BKE_ptcache_id_reset(&pid, mode);
+			reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 		}
 	}
 
 	for(md=ob->modifiers.first; md; md=md->next) {
 		if(md->type == eModifierType_Cloth) {
 			BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
-			reset |= BKE_ptcache_id_reset(&pid, mode);
+			reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 		}
 	}
 
@@ -564,7 +1058,7 @@ void BKE_ptcache_set_continue_physics(Scene *scene, int enable)
 
 		if(CONTINUE_PHYSICS == 0) {
 			for(ob=G.main->object.first; ob; ob=ob->id.next)
-				if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_OUTDATED))
+				if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
 					DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
 		}
 	}
@@ -584,12 +1078,21 @@ PointCache *BKE_ptcache_add()
 	cache= MEM_callocN(sizeof(PointCache), "PointCache");
 	cache->startframe= 1;
 	cache->endframe= 250;
+	cache->step= 10;
 
 	return cache;
 }
 
 void BKE_ptcache_free(PointCache *cache)
 {
+	PTCacheMem *pm = cache->mem_cache.first;
+	if(pm) {
+		for(; pm; pm=pm->next)
+			MEM_freeN(pm->data);
+
+		BLI_freelistN(&cache->mem_cache);
+	}
+
 	MEM_freeN(cache);
 }
 
@@ -605,3 +1108,276 @@ PointCache *BKE_ptcache_copy(PointCache *cache)
 	return ncache;
 }
 
+
+
+/* Baking */
+static int count_quick_cache(Scene *scene, int *quick_step)
+{
+	Base *base = scene->base.first;
+	PTCacheID *pid;
+	ListBase pidlist;
+	int autocache_count= 0;
+
+	for(base = scene->base.first; base; base = base->next) {
+		if(base->object) {
+			BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+			for(pid=pidlist.first; pid; pid=pid->next) {
+				if((pid->cache->flag & PTCACHE_BAKED)
+					|| (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
+					continue;
+
+				if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
+					if(!autocache_count)
+						*quick_step = pid->cache->step;
+					else
+						*quick_step = MIN2(*quick_step, pid->cache->step);
+
+					autocache_count++;
+				}
+			}
+
+			BLI_freelistN(&pidlist);
+		}
+	}
+
+	return autocache_count;
+}
+void BKE_ptcache_quick_cache_all(Scene *scene)
+{
+	PTCacheBaker baker;
+
+	baker.bake=0;
+	baker.break_data=NULL;
+	baker.break_test=NULL;
+	baker.pid=NULL;
+	baker.progressbar=NULL;
+	baker.progresscontext=NULL;
+	baker.render=0;
+	baker.scene=scene;
+
+	if(count_quick_cache(scene, &baker.quick_step))
+		BKE_ptcache_make_cache(&baker);
+}
+
+/* if bake is not given run simulations to current frame */
+void BKE_ptcache_make_cache(PTCacheBaker* baker)
+{
+	Scene *scene = baker->scene;
+	Base *base;
+	ListBase pidlist;
+	PTCacheID *pid = baker->pid;
+	PointCache *cache;
+	float frameleno = scene->r.framelen;
+	int cfrao = CFRA;
+	int startframe = MAXFRAME;
+	int endframe = CFRA;
+	int bake = baker->bake;
+	int render = baker->render;
+	int step = baker->quick_step;
+
+	G.afbreek = 0;
+
+	/* set caches to baking mode and figure out start frame */
+	if(pid) {
+		/* cache/bake a single object */
+		cache = pid->cache;
+		if((cache->flag & PTCACHE_BAKED)==0) {
+			if(pid->type==PTCACHE_TYPE_PARTICLES)
+				psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
+
+			if(bake || cache->flag & PTCACHE_REDO_NEEDED)
+				BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+			startframe = MAX2(cache->last_exact, cache->startframe);
+
+			if(bake) {
+				endframe = cache->endframe;
+				cache->flag |= PTCACHE_BAKING;
+			}
+			else {
+				endframe = MIN2(endframe, cache->endframe);
+			}
+
+			cache->flag &= ~PTCACHE_BAKED;
+		}
+	}
+	else for(base=scene->base.first; base; base= base->next) {
+		/* cache/bake everything in the scene */
+		BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+		for(pid=pidlist.first; pid; pid=pid->next) {
+			cache = pid->cache;
+			if((cache->flag & PTCACHE_BAKED)==0) {
+				if(pid->type==PTCACHE_TYPE_PARTICLES)
+					psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
+
+				if((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0)
+					&& ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake))
+					BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+				startframe = MIN2(startframe, cache->startframe);
+
+				if(bake || render) {
+					cache->flag |= PTCACHE_BAKING;
+
+					if(bake)
+						endframe = MAX2(endframe, cache->endframe);
+				}
+
+				cache->flag &= ~PTCACHE_BAKED;
+
+			}
+		}
+		BLI_freelistN(&pidlist);
+	}
+
+	CFRA= startframe;
+	scene->r.framelen = 1.0;
+
+	for(; CFRA <= endframe; CFRA+=step) {
+		float prog;
+
+		if(bake)
+			prog = (int)(100.0 * (float)(CFRA - startframe)/(float)(endframe-startframe));
+		else
+			prog = CFRA;
+
+		/* NOTE: baking should not redraw whole ui as this slows things down */
+		if(baker->progressbar)
+			baker->progressbar(baker->progresscontext, prog);
+		
+		scene_update_for_newframe(scene, scene->lay);
+
+		/* NOTE: breaking baking should leave calculated frames in cache, not clear it */
+		if(baker->break_test && baker->break_test(baker->break_data))
+			break;
+	}
+
+	/* clear baking flag */
+	if(pid) {
+		cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
+		cache->flag |= PTCACHE_SIMULATION_VALID;
+		if(bake)
+			cache->flag |= PTCACHE_BAKED;
+	}
+	else for(base=scene->base.first; base; base= base->next) {
+		BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+		for(pid=pidlist.first; pid; pid=pid->next) {
+			cache = pid->cache;
+
+			if(step > 1)
+				cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED);
+			else
+				cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
+
+			cache->flag |= PTCACHE_SIMULATION_VALID;
+
+			if(bake)
+				cache->flag |= PTCACHE_BAKED;
+		}
+		BLI_freelistN(&pidlist);
+	}
+
+	scene->r.framelen = frameleno;
+	CFRA = cfrao;
+	scene_update_for_newframe(scene, scene->lay);
+
+	/* TODO: call redraw all windows somehow */
+}
+
+void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
+	PointCache *cache = pid->cache;
+	PTCacheFile *pf;
+	PTCacheMem *pm;
+	int totelem=0;
+	int float_count=0;
+	int tot;
+	int last_exact = cache->last_exact;
+
+	if (!G.relbase_valid){
+		cache->flag &= ~PTCACHE_DISK_CACHE;
+		return;
+	}
+
+	totelem = ptcache_pid_totelem(pid);
+	float_count = ptcache_pid_elemsize(pid) / sizeof(float);
+
+	if(totelem==0 || float_count==0)
+		return;
+
+	tot = totelem*float_count;
+
+	/* MEM -> DISK */
+	if(cache->flag & PTCACHE_DISK_CACHE) {
+		pm = cache->mem_cache.first;
+
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+		for(; pm; pm=pm->next) {
+			pf = BKE_ptcache_file_open(pid, PTCACHE_FILE_WRITE, pm->frame);
+
+			if(pf) {
+				if(fwrite(pm->data, sizeof(float), tot, pf->fp) != tot) {
+					printf("Error writing to disk cache\n");
+					
+					cache->flag &= ~PTCACHE_DISK_CACHE;
+
+					BKE_ptcache_file_close(pf);
+					return;
+				}
+				BKE_ptcache_file_close(pf);
+			}
+			else
+				printf("Error creating disk cache file\n");
+		}
+
+		cache->flag &= ~PTCACHE_DISK_CACHE;
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+		cache->flag |= PTCACHE_DISK_CACHE;
+	}
+	/* DISK -> MEM */
+	else {
+		int cfra;
+		int sfra = cache->startframe;
+		int efra = cache->endframe;
+
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+		for(cfra=sfra; cfra <= efra; cfra++) {
+			pf = BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
+
+			if(pf) {
+				pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+				pm->data = MEM_callocN(sizeof(float)*tot, "Pointcache mem data");
+
+				if(fread(pm->data, sizeof(float), tot, pf->fp)!= tot) {
+					printf("Error reading from disk cache\n");
+
+					cache->flag |= PTCACHE_DISK_CACHE;
+
+					MEM_freeN(pm->data);
+					MEM_freeN(pm);
+					BKE_ptcache_file_close(pf);
+					return;
+				}
+
+				pm->frame = cfra;
+				pm->totpoint = totelem;
+
+				BLI_addtail(&pid->cache->mem_cache, pm);
+
+				BKE_ptcache_file_close(pf);
+			}
+		}
+
+		cache->flag |= PTCACHE_DISK_CACHE;
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+		cache->flag &= ~PTCACHE_DISK_CACHE;
+	}
+	
+	cache->last_exact = last_exact;
+
+	BKE_ptcache_update_info(pid);
+}
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 1d97eccb9f3..8de8cf8d0f4 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -1,5 +1,5 @@
 /**
- * $Id: report.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -65,8 +65,8 @@ void BKE_reports_init(ReportList *reports, int flag)
 
 	memset(reports, 0, sizeof(ReportList));
 
-	reports->storelevel= RPT_WARNING;
-	reports->printlevel= RPT_WARNING;
+	reports->storelevel= RPT_INFO;
+	reports->printlevel= RPT_INFO;
 	reports->flag= flag;
 }
 
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 156bdae9b00..23da5c66850 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -142,8 +142,6 @@ void free_scene(Scene *sce)
 
 	BLI_freelistN(&sce->base);
 	seq_free_editing(sce->ed);
-	if(sce->radio) MEM_freeN(sce->radio);
-	sce->radio= 0;
 	
 #ifndef DISABLE_PYTHON
 	BPY_free_scriptlink(&sce->scriptlink);
@@ -205,9 +203,6 @@ Scene *add_scene(char *name)
 
 	sce= alloc_libblock(&G.main->scene, ID_SCE, name);
 	sce->lay= 1;
-	sce->selectmode= SCE_SELECT_VERTEX;
-	sce->editbutsize= 0.1;
-	sce->autokey_mode= U.autokey_mode;
 	
 	sce->r.mode= R_GAMMA;
 	sce->r.cfra= 1;
@@ -277,6 +272,10 @@ Scene *add_scene(char *name)
 	sce->toolsettings->select_thresh= 0.01f;
 	sce->toolsettings->jointrilimit = 0.8f;
 
+	sce->toolsettings->selectmode= SCE_SELECT_VERTEX;
+	sce->toolsettings->normalsize= 0.1;
+	sce->toolsettings->autokey_mode= U.autokey_mode;
+
 	sce->toolsettings->skgen_resolution = 100;
 	sce->toolsettings->skgen_threshold_internal 	= 0.01f;
 	sce->toolsettings->skgen_threshold_external 	= 0.01f;
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index bb0665a5b0f..7fc262b4796 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -1,5 +1,5 @@
 /**
-* $Id: sequence.c 17508 2008-11-20 00:34:24Z campbellbarton $
+* $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index d2fb62141de..d0b106b59c3 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -26,7 +26,7 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  * 
- * $Id: $ 
+ * $Id$ 
 */
 
 #ifndef BLI_LISTBASE_H
diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h
index 9f72c5e7b54..0886eb3a8a5 100644
--- a/source/blender/blenlib/BLI_noise.h
+++ b/source/blender/blenlib/BLI_noise.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index c7026b21494..c36a41af84b 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/BLI_storage.h b/source/blender/blenlib/BLI_storage.h
index d7bf3bd13f8..fa44bb36e15 100644
--- a/source/blender/blenlib/BLI_storage.h
+++ b/source/blender/blenlib/BLI_storage.h
@@ -25,15 +25,20 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+
 #ifndef BLI_STORAGE_H
 #define BLI_STORAGE_H
 
+/* NOTE: these have to be defined before including unistd.h! */
 #ifndef __APPLE__
 #ifndef WIN32
-#define _LARGEFILE_SOURCE 1
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
 #define _FILE_OFFSET_BITS 64
 #endif
 #endif
+#endif
 
 struct direntry;
 
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 4e5bf650196..bf93dc19cc5 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -26,7 +26,7 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  *
- * $Id: $ 
+ * $Id$ 
 */
 
 #ifndef BLI_STRING_H
diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h
index 30c9fc353b3..a138ea780ea 100644
--- a/source/blender/blenlib/BLI_util.h
+++ b/source/blender/blenlib/BLI_util.h
@@ -50,6 +50,7 @@ void BLI_make_existing_file(char *name);
 void BLI_split_dirfile(char *string, char *dir, char *file);
 void BLI_split_dirfile_basic(const char *string, char *dir, char *file);
 void BLI_join_dirfile(char *string, const char *dir, const char *file);
+void BLI_getlastdir(const char* dir, char *last, int maxlen);
 int BLI_testextensie(const char *str, const char *ext);
 void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], char delim, short name_offs, short len);
 void BLI_newname(char * name, int add);
diff --git a/source/blender/blenlib/intern/dynamiclist.c b/source/blender/blenlib/intern/dynamiclist.c
index fbb87124bba..4fe654cffb6 100644
--- a/source/blender/blenlib/intern/dynamiclist.c
+++ b/source/blender/blenlib/intern/dynamiclist.c
@@ -3,7 +3,7 @@
  * various string, file, list operations.
  *
  *
- * $Id: util.c 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/dynamiclist.h b/source/blender/blenlib/intern/dynamiclist.h
index aba3eda0696..e8c93fbcf23 100644
--- a/source/blender/blenlib/intern/dynamiclist.h
+++ b/source/blender/blenlib/intern/dynamiclist.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BLI_dynamiclist.h 13161 2008-01-07 19:13:47Z hos $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index e0fd5c37494..1064c8ac1bf 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -3,7 +3,7 @@
  * various string, file, list operations.
  *
  *
- * $Id: util.c 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c
index 39d38e4cf3a..269e674a62f 100644
--- a/source/blender/blenlib/intern/psfont.c
+++ b/source/blender/blenlib/intern/psfont.c
@@ -837,7 +837,7 @@ static int decodetype1(PackedFile * pf, char *outname)
 		while(newfgets(oneline, LINELEN, pf)) {
 			hptr = (char *)oneline;
 			while(*hptr) {
-				if(hextab[*hptr] != NOTHEX)
+				if(hextab[(int)*hptr] != NOTHEX)
 					hexdat[hexbytes++] = *hptr;
 				hptr++;
 			}
@@ -853,7 +853,7 @@ static int decodetype1(PackedFile * pf, char *outname)
 		bptr = bindat;
 		c = datbytes;
 		while(c--) {
-			*bptr++  = (hextab[hptr[0]]<<4)+hextab[hptr[1]];
+			*bptr++  = (hextab[(int)hptr[0]]<<4)+hextab[(int)hptr[1]];
 			hptr += 2;
 		}
 
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 688a4ab901b..3204d5f74e1 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -62,13 +62,6 @@
 #include 
 #endif
 
-#ifdef __BeOS
-struct statfs {
-	int f_bsize;
-	int f_bfree;
-};
-#endif
-
 #ifdef __APPLE__
 /* For statfs */
 #include 
@@ -77,7 +70,7 @@ struct statfs {
 
 
 #include 
-#if !defined(__BeOS) && !defined(WIN32)
+#if !defined(WIN32)
 #include 			/* tape comando's */
 #endif
 #include 			/* strcpy etc.. */
@@ -201,9 +194,6 @@ double BLI_diskfree(char *dir)
 #if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) 
 	if (statfs(name, &disk)) return(-1);
 #endif
-#ifdef __BeOS
-	return -1;
-#endif
 
 #if defined (__sun__) || defined (__sun) || defined (__sgi)
 	if (statvfs(name, &disk)) return(-1);	
@@ -228,7 +218,7 @@ void BLI_builddir(char *dirname, char *relname)
 {
 	struct dirent *fname;
 	struct dirlink *dlink;
-	int rellen, newnum = 0, seen_ = 0, seen__ = 0;
+	int rellen, newnum = 0, ignore;
 	char buf[256];
 	DIR *dir;
 
@@ -248,21 +238,17 @@ void BLI_builddir(char *dirname, char *relname)
 	if ( (dir = (DIR *)opendir(".")) ){
 		while ((fname = (struct dirent*) readdir(dir)) != NULL) {
 			
-			if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0);
+			if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0) {
+			}
+			else if ( ( (fname->d_name[0] == '.') && (fname->d_name[1] == 0) ) ||
+					  ( (fname->d_name[0] == '.') && (fname->d_name[1] == '.') && (fname->d_name[2] == 0)) ) {
+				/* ignore '.' and '..' */
+			}
 			else {
-				
 				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
 				if (dlink){
 					strcpy(buf+rellen,fname->d_name);
-	
 					dlink->name = BLI_strdup(buf);
-	
-					if (dlink->name[0] == '.') {
-						if (dlink->name[1] == 0) seen_ = 1;
-						else if (dlink->name[1] == '.') {
-							if (dlink->name[2] == 0) seen__ = 1;
-						}
-					}
 					BLI_addhead(dirbase,dlink);
 					newnum++;
 				}
@@ -270,30 +256,6 @@ void BLI_builddir(char *dirname, char *relname)
 		}
 		
 		if (newnum){
-#ifndef WIN32		
-			if (seen_ == 0) {	/* Cachefs PATCH */
-				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
-				strcpy(buf+rellen,"./.");
-				dlink->name = BLI_strdup(buf);
-				BLI_addhead(dirbase,dlink);
-				newnum++;
-			}
-			if (seen__ == 0) {	/* MAC PATCH */
-				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
-				strcpy(buf+rellen,"./..");
-				dlink->name = BLI_strdup(buf);
-				BLI_addhead(dirbase,dlink);
-				newnum++;
-			}
-#else // WIN32
-			if (seen_ == 0) {	/* should only happen for root paths like "C:\" */
-				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
-				strcpy(buf+rellen,".");
-				dlink->name = BLI_strdup(buf);
-				BLI_addhead(dirbase,dlink);
-				newnum++;
-			}
-#endif			
 
 			if (files) files=(struct direntry *)realloc(files,(totnum+newnum) * sizeof(struct direntry));
 			else files=(struct direntry *)malloc(newnum * sizeof(struct direntry));
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index fa4bcbc26bc..4cd04aa232c 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -3,7 +3,7 @@
  * various string, file, list operations.
  *
  *
- * $Id: util.c 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index df4ad4e7c75..b9d4daaf5b2 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -736,11 +736,27 @@ void BLI_splitdirstring(char *di, char *fi)
 	}
 }
 
-char *BLI_gethome(void) {
-	#ifdef __BeOS
-		return "/boot/home/";		/* BeOS 4.5: doubleclick at icon doesnt give home env */
+void BLI_getlastdir(const char* dir, char *last, int maxlen)
+{
+	char *s = dir;
+	char *lslash = NULL;
+	char *prevslash = NULL;
+	while (*s) {
+		if ((*s == '\\') || (*s == '/')) {
+			prevslash = lslash;
+			lslash = s;
+		}
+		s++;
+	}
+	if (prevslash) {
+		BLI_strncpy(last, prevslash+1, maxlen);
+	} else {
+		BLI_strncpy(last, dir, maxlen);
+	}
+}
 
-	#elif !defined(WIN32)
+char *BLI_gethome(void) {
+	#if !defined(WIN32)
 		return getenv("HOME");
 
 	#else /* Windows */
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 0c8b8a6b31d..1f276913ea8 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -32,6 +32,8 @@
 #include 
 #endif
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include 
 #include 
 #include 
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1502b475350..c89f515f319 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2878,6 +2878,16 @@ static void direct_link_material(FileData *fd, Material *ma)
 
 static void direct_link_pointcache(FileData *fd, PointCache *cache)
 {
+	if((cache->flag & PTCACHE_DISK_CACHE)==0) {
+		PTCacheMem *pm;
+
+		link_list(fd, &cache->mem_cache);
+
+		pm = cache->mem_cache.first;
+
+		for(; pm; pm=pm->next)
+			pm->data = newdataadr(fd, pm->data);
+	}
 	cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE);
 	cache->simframe= 0;
 }
@@ -2889,7 +2899,9 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 	part= main->particle.first;
 	while(part) {
 		if(part->id.flag & LIB_NEEDLINK) {
+			if (part->adt) lib_link_animdata(fd, &part->id, part->adt);
 			part->ipo= newlibadr_us(fd, part->id.lib, part->ipo); // XXX depreceated - old animation system
+			
 			part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
 			part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
 			part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
@@ -2902,6 +2914,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 
 static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 {
+	part->adt= newdataadr(fd, part->adt);
 	part->pd= newdataadr(fd, part->pd);
 	part->pd2= newdataadr(fd, part->pd2);
 }
@@ -3142,10 +3155,8 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
 		direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
 		direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
 		
-		if(!mesh->mr->edge_flags)
-			mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
-		if(!mesh->mr->edge_creases)
-			mesh->mr->edge_creases= MEM_callocN(sizeof(char)*lvl->totedge, "Multires Edge Creases");
+		mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
+		mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
 
 		mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
 			
@@ -3933,8 +3944,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
 	direct_link_keyingsets(fd, &sce->keyingsets);
 	
 	sce->basact= newdataadr(fd, sce->basact);
-
-	sce->radio= newdataadr(fd, sce->radio);
 	
 	sce->toolsettings= newdataadr(fd, sce->toolsettings);
 	if(sce->toolsettings) {
@@ -5586,21 +5595,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
 				/* temporarily hide it */
 				ar->flag = RGN_FLAG_HIDDEN;
 				break;
-				
-			case SPACE_FILE:
-				/* channel (bookmarks/directories) region */
-				ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
-				BLI_addtail(lb, ar);
-				ar->regiontype= RGN_TYPE_CHANNELS;
-				ar->alignment= RGN_ALIGN_LEFT;
-				ar->v2d.scroll= V2D_SCROLL_RIGHT;
-				/* button UI region */
-				ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
-				BLI_addtail(lb, ar);
-				ar->regiontype= RGN_TYPE_UI;
-				ar->alignment= RGN_ALIGN_TOP;
-				break;
-
 #if 0
 			case SPACE_BUTS:
 				/* context UI region */
@@ -7096,22 +7090,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	
 
 	if(main->versionfile <= 234) {
-		Scene *sce;
 		World *wo;
 		bScreen *sc;
-		int set_zbuf_sel=0;
 		
 		// force sumo engine to be active
 		for (wo = main->world.first; wo; wo= wo->id.next) {
 			if(wo->physicsEngine==0) wo->physicsEngine = 2;
 		}
 		
-		for (sce= main->scene.first; sce; sce= sce->id.next) {
-			if(sce->selectmode==0) {
-				sce->selectmode= SCE_SELECT_VERTEX;
-				set_zbuf_sel= 1;
-			}
-		}
 		for (sc= main->screen.first; sc; sc= sc->id.next) {
 			ScrArea *sa;
 			for (sa= sc->areabase.first; sa; sa= sa->next) {
@@ -7119,7 +7105,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 				for (sl= sa->spacedata.first; sl; sl= sl->next) {
 					if(sl->spacetype==SPACE_VIEW3D) {
 						View3D *v3d= (View3D *)sl;
-						if(set_zbuf_sel) v3d->flag |= V3D_ZBUF_SELECT;
+						v3d->flag |= V3D_ZBUF_SELECT;
 					}
 					else if(sl->spacetype==SPACE_TEXT) {
 						SpaceText *st= (SpaceText *)sl;
@@ -7154,16 +7140,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	}
 	if(main->versionfile <= 236) {
 		Object *ob;
-		Scene *sce= main->scene.first;
 		Camera *cam= main->camera.first;
 		Material *ma;
 		bScreen *sc;
 
-		while(sce) {
-			if(sce->editbutsize==0.0) sce->editbutsize= 0.1f;
-			
-			sce= sce->id.next;
-		}
 		while(cam) {
 			if(cam->ortho_scale==0.0) {
 				cam->ortho_scale= 256.0f/cam->lens;
@@ -8789,15 +8769,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 			}
 		}
 	}
-	/* autokey mode settings now used from scene, but need to be initialised off userprefs */
-	if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 8)) {
-		Scene *sce;
-		
-		for (sce= main->scene.first; sce; sce= sce->id.next) {
-			if (sce->autokey_mode == 0)
-				sce->autokey_mode= U.autokey_mode;
-		}
-	}
 
 	if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 9)) {
 		Lamp *la= main->lamp.first;
@@ -8990,6 +8961,34 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	
 	}
 
+	if (main->versionfile < 249 && main->subversionfile < 2) {
+		Scene *sce= main->scene.first;
+		Sequence *seq;
+		Editing *ed;
+		
+		while(sce) {
+			ed= sce->ed;
+			if(ed) {
+				SEQP_BEGIN(ed, seq) {
+					if (seq->strip && seq->strip->proxy){
+						if (sce->r.size != 100.0) {
+							seq->strip->proxy->size
+								= sce->r.size;
+						} else {
+							seq->strip->proxy->size
+								= 25.0;
+						}
+						seq->strip->proxy->quality =90;
+					}
+				}
+				SEQ_END
+			}
+			
+			sce= sce->id.next;
+		}
+
+	}
+
 	if (main->versionfile < 250) {
 		bScreen *screen;
 		Scene *scene;
@@ -8998,6 +8997,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 		Scene *sce;
 		Tex *tx;
 		ParticleSettings *part;
+		Object *ob;
+		PTCacheID *pid;
+		ListBase pidlist;
 		
 		for(screen= main->screen.first; screen; screen= screen->id.next) {
 			do_versions_windowmanager_2_50(screen);
@@ -9009,12 +9011,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 		 */
 		//do_versions_ipos_to_animato(main);
 		
-		/* struct audio data moved to renderdata */
+		/* toolsettings */
 		for(scene= main->scene.first; scene; scene= scene->id.next) {
 			scene->r.audio = scene->audio;
 			
-			if(!scene->toolsettings->uv_selectmode)
+			if(!scene->toolsettings->uv_selectmode) {
 				scene->toolsettings->uv_selectmode= UV_SELECT_VERTEX;
+				scene->toolsettings->vgroup_weight= 1.0f;
+			}
 		}
 		
 		/* shader, composit and texture node trees have id.name empty, put something in
@@ -9040,7 +9044,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 			me->drawflag= ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
 		}
 
-		/* particle settings conversion */
+		/* particle draw and render types */
 		for(part= main->particle.first; part; part= part->id.next) {
 			if(part->draw_as) {
 				if(part->draw_as == PART_DRAW_DOT) {
@@ -9056,6 +9060,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 				}
 			}
 		}
+		/* set old pointcaches to have disk cache flag */
+		for(ob = main->object.first; ob; ob= ob->id.next) {
+
+			BKE_ptcache_ids_from_object(&pidlist, ob);
+
+			for(pid=pidlist.first; pid; pid=pid->next)
+				pid->cache->flag |= PTCACHE_DISK_CACHE;
+
+			BLI_freelistN(&pidlist);
+		}
 	}
 
 	/* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can
@@ -9063,6 +9077,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	{
 		Object *ob;
 		Material *ma;
+		Scene *sce;
+		ToolSettings *ts;
 		int i;
 
 		for(ob = main->object.first; ob; ob = ob->id.next) {
@@ -9135,37 +9151,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 				ma->mode &= ~MA_HALO;
 			}
 		}
-	}
-	
-	if (main->versionfile < 249 && main->subversionfile < 2) {
-		Scene *sce= main->scene.first;
-		Sequence *seq;
-		Editing *ed;
-		
-		while(sce) {
-			ed= sce->ed;
-			if(ed) {
-				SEQP_BEGIN(ed, seq) {
-					if (seq->strip && seq->strip->proxy){
-						if (sce->r.size != 100.0) {
-							seq->strip->proxy->size
-								= sce->r.size;
-						} else {
-							seq->strip->proxy->size
-								= 25.0;
-						}
-						seq->strip->proxy->quality =90;
-					}
-				}
-				SEQ_END
+
+		for(sce = main->scene.first; sce; sce = sce->id.next) {
+			ts= sce->toolsettings;
+			if(ts->normalsize == 0.0) {
+				ts->normalsize= 0.1f;
+				ts->selectmode= SCE_SELECT_VERTEX;
+				ts->autokey_mode= U.autokey_mode;
 			}
-			
-			sce= sce->id.next;
 		}
-
 	}
 
-
 	/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
 	/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
@@ -9517,6 +9513,8 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
 	expand_doit(fd, mainvar, part->dup_group);
 	expand_doit(fd, mainvar, part->eff_group);
 	expand_doit(fd, mainvar, part->bb_ob);
+	
+	expand_animdata(fd, mainvar, part->adt);
 }
 
 static void expand_group(FileData *fd, Main *mainvar, Group *group)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index f8112406e80..c433232d084 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -382,6 +382,7 @@ static void writedata(WriteData *wd, int filecode, int len, void *adr)	/* do not
 /*These functions are used by blender's .blend system for file saving/loading.*/
 void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
 void IDP_WriteProperty(IDProperty *prop, void *wd);
+static void write_animdata(WriteData *wd, AnimData *adt); // XXX code needs reshuffling, but not before NLA SoC is merged back into 2.5
 
 static void IDP_WriteArray(IDProperty *prop, void *wd)
 {
@@ -549,6 +550,25 @@ static void write_userdef(WriteData *wd)
 	}
 }
 
+/* TODO: replace *cache with *cachelist once it's coded */
+#define PTCACHE_WRITE_PSYS	0
+#define PTCACHE_WRITE_CLOTH	1
+static void write_pointcaches(WriteData *wd, PointCache *cache, int type)
+{
+	writestruct(wd, DATA, "PointCache", 1, cache);
+
+	if((cache->flag & PTCACHE_DISK_CACHE)==0) {
+		PTCacheMem *pm = cache->mem_cache.first;
+
+		for(; pm; pm=pm->next) {
+			writestruct(wd, DATA, "PTCacheMem", 1, pm);
+			if(type==PTCACHE_WRITE_PSYS)
+				writestruct(wd, DATA, "ParticleKey", pm->totpoint, pm->data);
+			else if(type==PTCACHE_WRITE_CLOTH)
+				writedata(wd, DATA, 9 * sizeof(float) * pm->totpoint, pm->data);
+		}
+	}
+}
 static void write_particlesettings(WriteData *wd, ListBase *idbase)
 {
 	ParticleSettings *part;
@@ -559,6 +579,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
 			/* write LibData */
 			writestruct(wd, ID_PA, "ParticleSettings", 1, part);
 			if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
+			if (part->adt) write_animdata(wd, part->adt);
 			writestruct(wd, DATA, "PartDeflect", 1, part->pd);
 			writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
 		}
@@ -585,8 +606,8 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
 		}
 		if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
 		writestruct(wd, DATA, "SoftBody", 1, psys->soft);
-		if(psys->soft) writestruct(wd, DATA, "PointCache", 1, psys->soft->pointcache);
-		writestruct(wd, DATA, "PointCache", 1, psys->pointcache);
+		if(psys->soft) write_pointcaches(wd, psys->soft->pointcache, PTCACHE_WRITE_PSYS);
+		write_pointcaches(wd, psys->pointcache, PTCACHE_WRITE_PSYS);
 	}
 }
 
@@ -1007,7 +1028,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
 			
 			writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
 			writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
-			writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
+			write_pointcaches(wd, clmd->point_cache, PTCACHE_WRITE_CLOTH);
 		} 
 		else if(md->type==eModifierType_Fluidsim) {
 			FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
@@ -1584,7 +1605,6 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
 			base= base->next;
 		}
 		
-		writestruct(wd, DATA, "Radio", 1, sce->radio);
 		writestruct(wd, DATA, "ToolSettings", 1, sce->toolsettings);
 		if(sce->toolsettings->vpaint)
 			writestruct(wd, DATA, "VPaint", 1, sce->toolsettings->vpaint);
diff --git a/source/blender/blenpluginapi/intern/Makefile b/source/blender/blenpluginapi/intern/Makefile
index 51905cad8ec..20a61e9a25c 100644
--- a/source/blender/blenpluginapi/intern/Makefile
+++ b/source/blender/blenpluginapi/intern/Makefile
@@ -33,10 +33,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
 
 include nan_compile.mk
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris"))
-    CFLAGS += -shared
-endif
-
 CFLAGS += $(LEVEL_1_C_WARNINGS)
 
 # path to our own external headerfiles. On win2k this needs to be
diff --git a/source/blender/editors/animation/Makefile b/source/blender/editors/animation/Makefile
index 19b62891b63..a7f36aa58ac 100644
--- a/source/blender/editors/animation/Makefile
+++ b/source/blender/editors/animation/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c
index c52ade1bba8..05d50f98e8e 100644
--- a/source/blender/editors/animation/anim_channels.c
+++ b/source/blender/editors/animation/anim_channels.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index cfbd6d2bced..d0e83eeaec7 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h
index 2d46cfa41e6..bde079c45fb 100644
--- a/source/blender/editors/armature/BIF_generate.h
+++ b/source/blender/editors/armature/BIF_generate.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_generate.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h
index 56f7e4cdd5d..c39f410424a 100644
--- a/source/blender/editors/armature/BIF_retarget.h
+++ b/source/blender/editors/armature/BIF_retarget.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_retarget.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/Makefile b/source/blender/editors/armature/Makefile
index 6c7ce81a8a1..0291bcb1830 100644
--- a/source/blender/editors/armature/Makefile
+++ b/source/blender/editors/armature/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index a50f767cf14..6d271375c64 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editarmature_generate.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 1b879569e9c..fb030b91ce1 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editarmature_sketch.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -243,6 +243,7 @@ void BIF_makeListTemplates(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	Base *base;
 	int index = 0;
 
@@ -263,7 +264,7 @@ void BIF_makeListTemplates(bContext *C)
 			index++;
 			BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
 			
-			if (ob == scene->toolsettings->skgen_template)
+			if (ob == ts->skgen_template)
 			{
 				TEMPLATES_CURRENT = index;
 			}
@@ -305,8 +306,9 @@ char *BIF_listTemplates(bContext *C)
 
 int   BIF_currentTemplate(bContext *C)
 {
-	Scene *scene = CTX_data_scene(C);
-	if (TEMPLATES_CURRENT == 0 && scene->toolsettings->skgen_template != NULL)
+	ToolSettings *ts = CTX_data_tool_settings(C);
+
+	if (TEMPLATES_CURRENT == 0 && ts->skgen_template != NULL)
 	{
 		GHashIterator ghi;
 		BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
@@ -316,7 +318,7 @@ int   BIF_currentTemplate(bContext *C)
 			Object *ob = BLI_ghashIterator_getValue(&ghi);
 			int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
 			
-			if (ob == scene->toolsettings->skgen_template)
+			if (ob == ts->skgen_template)
 			{
 				TEMPLATES_CURRENT = key;
 				break;
@@ -360,8 +362,8 @@ RigGraph* sk_makeTemplateGraph(bContext *C, Object *ob)
 
 int BIF_nbJointsTemplate(bContext *C)
 {
-	Scene *scene = CTX_data_scene(C);
-	RigGraph *rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+	ToolSettings *ts = CTX_data_tool_settings(C);
+	RigGraph *rg = sk_makeTemplateGraph(C, ts->skgen_template);
 	
 	if (rg)
 	{
@@ -375,7 +377,7 @@ int BIF_nbJointsTemplate(bContext *C)
 
 char * BIF_nameBoneTemplate(bContext *C)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	SK_Sketch *stk = GLOBAL_sketch;
 	RigGraph *rg;
 	int index = 0;
@@ -385,7 +387,7 @@ char * BIF_nameBoneTemplate(bContext *C)
 		index = stk->active_stroke->nb_points;
 	}
 	
-	rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+	rg = sk_makeTemplateGraph(C, ts->skgen_template);
 	
 	if (rg == NULL)
 	{
@@ -418,14 +420,14 @@ void  BIF_freeTemplates(bContext *C)
 
 void  BIF_setTemplate(bContext *C, int index)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	if (index > 0)
 	{
-		scene->toolsettings->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
+		ts->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
 	}
 	else
 	{
-		scene->toolsettings->skgen_template = NULL;
+		ts->skgen_template = NULL;
 		
 		if (TEMPLATE_RIGG != NULL)
 		{
@@ -439,19 +441,19 @@ void  BIF_setTemplate(bContext *C, int index)
 
 void sk_autoname(bContext *C, ReebArc *arc)
 {
-	Scene *scene = CTX_data_scene(C);
-	if (scene->toolsettings->skgen_retarget_options & SK_RETARGET_AUTONAME)
+	ToolSettings *ts = CTX_data_tool_settings(C);
+	if (ts->skgen_retarget_options & SK_RETARGET_AUTONAME)
 	{
 		if (arc == NULL)
 		{
-			char *num = scene->toolsettings->skgen_num_string;
+			char *num = ts->skgen_num_string;
 			int i = atoi(num);
 			i++;
 			BLI_snprintf(num, 8, "%i", i);
 		}
 		else
 		{
-			char *side = scene->toolsettings->skgen_side_string;
+			char *side = ts->skgen_side_string;
 			int valid = 0;
 			int caps = 0;
 			
@@ -525,7 +527,7 @@ ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
 
 void sk_retargetStroke(bContext *C, SK_Stroke *stk)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	Object *obedit = CTX_data_edit_object(C);
 	float imat[4][4];
 	float tmat[3][3];
@@ -541,7 +543,7 @@ void sk_retargetStroke(bContext *C, SK_Stroke *stk)
 	
 	sk_autoname(C, arc);
 	
-	rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+	rg = sk_makeTemplateGraph(C, ts->skgen_template);
 
 	BIF_retargetArc(C, arc, rg);
 	
@@ -1408,10 +1410,10 @@ void sk_startStroke(SK_Sketch *sketch)
 
 void sk_endStroke(bContext *C, SK_Sketch *sketch)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	sk_shrinkStrokeBuffer(sketch->active_stroke);
 
-	if (scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
+	if (ts->bone_sketching & BONE_SKETCHING_ADJUST)
 	{
 		sk_endOverdraw(sketch);
 	}
@@ -1521,10 +1523,10 @@ int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_Dra
 
 int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	int point_added = 0;
 
-	if (scene->snap_mode == SCE_SNAP_MODE_VOLUME)
+	if (ts->snap_mode == SCE_SNAP_MODE_VOLUME)
 	{
 		ListBase depth_peels;
 		DepthPeel *p1, *p2;
@@ -1557,7 +1559,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
 				p1->flag = 1;
 	
 				/* if peeling objects, take the first and last from each object */			
-				if (scene->snap_flag & SCE_SNAP_PEEL_OBJECT)
+				if (ts->snap_flag & SCE_SNAP_PEEL_OBJECT)
 				{
 					DepthPeel *peel;
 					for (peel = p1->next; peel; peel = peel->next)
@@ -1627,7 +1629,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
 		int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
 
 		/* snap to strokes */
-		// if (scene->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
+		// if (ts->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
 		for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next)
 		{
 			SK_Point *spt = NULL;
@@ -1713,7 +1715,7 @@ int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_Dra
 
 void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	int point_added = 0;
 	
 	if (snap)
@@ -1726,7 +1728,7 @@ void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawDa
 		point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
 	}
 	
-	if (stk == sketch->active_stroke && scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
+	if (stk == sketch->active_stroke && ts->bone_sketching & BONE_SKETCHING_ADJUST)
 	{
 		sk_updateOverdraw(C, sketch, stk, dd);
 	}
@@ -1951,7 +1953,7 @@ static int iteratorStopped(void *arg)
 void sk_convertStroke(bContext *C, SK_Stroke *stk)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	bArmature *arm = obedit->data;
 	SK_Point *head;
 	EditBone *parent = NULL;
@@ -1990,17 +1992,17 @@ void sk_convertStroke(bContext *C, SK_Stroke *stk)
 
 					initStrokeIterator(iter, stk, head_index, i);
 					
-					if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
+					if (ts->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
 					{
-						bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
+						bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
 					}
-					else if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
+					else if (ts->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
 					{
-						bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
+						bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
 					}
-					else if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
+					else if (ts->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
 					{
-						bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
+						bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
 					}
 				}
 				
@@ -2042,14 +2044,14 @@ void sk_convertStroke(bContext *C, SK_Stroke *stk)
 
 void sk_convert(bContext *C, SK_Sketch *sketch)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	SK_Stroke *stk;
 	
 	for (stk = sketch->strokes.first; stk; stk = stk->next)
 	{
 		if (stk->selected == 1)
 		{
-			if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+			if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
 			{
 				sk_retargetStroke(C, stk);
 			}
@@ -2693,7 +2695,7 @@ void sk_selectStroke(bContext *C, SK_Sketch *sketch, short mval[2], int extend)
 	rect.ymin= mval[1]-5;
 	rect.ymax= mval[1]+5;
 		
-	hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
+	hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
 
 	if (hits>0)
 	{
@@ -2743,6 +2745,7 @@ void sk_queueRedrawSketch(SK_Sketch *sketch)
 
 void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 {
+	ToolSettings *ts= scene->toolsettings;
 	SK_Stroke *stk;
 	
 	glDisable(GL_DEPTH_TEST);
@@ -2779,7 +2782,7 @@ void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 		
 			if (stk->selected == 1)
 			{
-				sk_drawStrokeSubdivision(scene->toolsettings, stk);
+				sk_drawStrokeSubdivision(ts, stk);
 			}
 		}
 	
@@ -2794,9 +2797,9 @@ void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 		{
 			SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
 			
-			if (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
+			if (ts->bone_sketching & BONE_SKETCHING_QUICK)
 			{
-				sk_drawStrokeSubdivision(scene->toolsettings, sketch->active_stroke);
+				sk_drawStrokeSubdivision(ts, sketch->active_stroke);
 			}
 			
 			if (last != NULL)
@@ -2839,7 +2842,7 @@ void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 
 int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 
 	if (sketch->active_stroke != NULL)
 	{
@@ -2847,9 +2850,9 @@ int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
 		
 		sk_endStroke(C, sketch);
 		
-		if (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
+		if (ts->bone_sketching & BONE_SKETCHING_QUICK)
 		{
-			if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+			if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
 			{
 				sk_retargetStroke(C, stk);
 			}
@@ -3196,11 +3199,11 @@ static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
 int ED_operator_sketch_mode_active_stroke(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING &&
+		ts->bone_sketching & BONE_SKETCHING &&
 		GLOBAL_sketch != NULL &&
 		GLOBAL_sketch->active_stroke != NULL)
 	{
@@ -3215,12 +3218,12 @@ int ED_operator_sketch_mode_active_stroke(bContext *C)
 int ED_operator_sketch_mode_gesture(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING &&
-		(scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
+		ts->bone_sketching & BONE_SKETCHING &&
+		(ts->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
 		GLOBAL_sketch != NULL &&
 		GLOBAL_sketch->active_stroke == NULL)
 	{
@@ -3235,12 +3238,12 @@ int ED_operator_sketch_mode_gesture(bContext *C)
 int ED_operator_sketch_full_mode(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING && 
-		(scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0)
+		ts->bone_sketching & BONE_SKETCHING && 
+		(ts->bone_sketching & BONE_SKETCHING_QUICK) == 0)
 	{
 		return 1;
 	}
@@ -3253,11 +3256,11 @@ int ED_operator_sketch_full_mode(bContext *C)
 int ED_operator_sketch_mode(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING)
+		ts->bone_sketching & BONE_SKETCHING)
 	{
 		return 1;
 	}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 4a0ee474f25..d74c8dbd0e1 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1,5 +1,5 @@
 /**
- * $Id: meshlaplacian.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h
index ff921e93909..00c0aefaec7 100644
--- a/source/blender/editors/armature/meshlaplacian.h
+++ b/source/blender/editors/armature/meshlaplacian.h
@@ -1,5 +1,5 @@
 /**
- * $Id: meshlaplacian.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/curve/Makefile b/source/blender/editors/curve/Makefile
index 6b1f628f231..6449700e50b 100644
--- a/source/blender/editors/curve/Makefile
+++ b/source/blender/editors/curve/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index a73a54323ee..2146855a75e 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -49,7 +49,6 @@ void FONT_OT_case_toggle(struct wmOperatorType *ot);
 void FONT_OT_case_set(struct wmOperatorType *ot);
 void FONT_OT_style_toggle(struct wmOperatorType *ot);
 void FONT_OT_style_set(struct wmOperatorType *ot);
-void FONT_OT_material_set(struct wmOperatorType *ot);
 
 void FONT_OT_text_copy(struct wmOperatorType *ot);
 void FONT_OT_text_cut(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 5292d86d3c9..66cde772f3e 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -106,7 +106,6 @@ void ED_operatortypes_curve(void)
 	WM_operatortype_append(FONT_OT_case_set);
 	WM_operatortype_append(FONT_OT_style_toggle);
 	WM_operatortype_append(FONT_OT_style_set);
-	WM_operatortype_append(FONT_OT_material_set);
 
 	WM_operatortype_append(FONT_OT_text_copy);
 	WM_operatortype_append(FONT_OT_text_cut);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 466908c562c..5283aacf39e 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -189,7 +189,7 @@ static short swap_selection_bpoint(BPoint *bp)
 		return select_bpoint(bp, SELECT, 1, VISIBLE);
 }
 
-short isNurbsel(Nurb *nu)
+int isNurbsel(Nurb *nu)
 {
 	BezTriple *bezt;
 	BPoint *bp;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 5389db9e2ee..9f2bd6f26f9 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -700,50 +700,6 @@ void FONT_OT_style_toggle(wmOperatorType *ot)
 	RNA_def_enum(ot->srna, "style", style_items, CU_BOLD, "Style", "Style to set selection to.");
 }
 
-/******************* set material operator ********************/
-
-static int set_material_exec(bContext *C, wmOperator *op)
-{
-	Scene *scene= CTX_data_scene(C);
-	Object *obedit= CTX_data_edit_object(C);
-	Curve *cu= obedit->data;
-	EditFont *ef= cu->editfont;
-	int i, mat_nr, selstart, selend;
-
-	if(!BKE_font_getselection(obedit, &selstart, &selend))
-		return OPERATOR_CANCELLED;
-
-	if(RNA_property_is_set(op->ptr, "index"))
-		mat_nr= RNA_int_get(op->ptr, "index");
-	else
-		mat_nr= obedit->actcol;
-
-	for(i=selstart; i<=selend; i++)
-		ef->textbufinfo[i].mat_nr = mat_nr;
-
-	DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
-
-	return OPERATOR_FINISHED;
-}
-
-void FONT_OT_material_set(wmOperatorType *ot)
-{
-	/* identifiers */
-	ot->name= "Set Material";
-	ot->idname= "FONT_OT_material_set";
-	
-	/* api callbacks */
-	ot->exec= set_material_exec;
-	ot->poll= ED_operator_editfont;
-	
-	/* flags */
-	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
-	/* properties */
-	RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Material Index", "Material slot index.", 0, INT_MAX);
-}
-
 /******************* copy text operator ********************/
 
 static void copy_selection(Object *obedit)
diff --git a/source/blender/editors/datafiles/Bfont.c b/source/blender/editors/datafiles/Bfont.c
index 4080a0d369f..cd45debcbe4 100644
--- a/source/blender/editors/datafiles/Bfont.c
+++ b/source/blender/editors/datafiles/Bfont.c
@@ -1,6 +1,6 @@
 /* DataToC output of file  */
 /*
- * $Id: Bfont.c 125 2002-11-25 12:02:15Z mein $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/datafiles/Makefile b/source/blender/editors/datafiles/Makefile
index 4162125623e..d7bb4e7222f 100644
--- a/source/blender/editors/datafiles/Makefile
+++ b/source/blender/editors/datafiles/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/gpencil/Makefile b/source/blender/editors/gpencil/Makefile
index f4c1cd246f4..9bc5f491a83 100644
--- a/source/blender/editors/gpencil/Makefile
+++ b/source/blender/editors/gpencil/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index bad86c170ab..c0c1cbc7ac6 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1,5 +1,5 @@
 /**
- * $Id: gpencil.c 19758 2009-04-16 13:10:08Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index 014201648c9..c1b3b056d62 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_gl.h 10455 2007-04-04 13:18:41Z campbellbarton $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index c619ee80f70..2cebc6a572a 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -30,6 +30,7 @@
 
 struct Base;
 struct bContext;
+struct Nurb;
 struct Object;
 struct Scene;
 struct Text;
@@ -52,6 +53,8 @@ void	mouse_nurb		(struct bContext *C, short mval[2], int extend);
 
 struct Nurb *add_nurbs_primitive(struct bContext *C, int type, int newname);
 
+int		isNurbsel		(struct Nurb *nu);;
+
 /* editfont.h */
 void	undo_push_font	(struct bContext *C, char *name);
 void	make_editText	(struct Object *obedit);
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index c1802c2952b..5d24b93418b 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -1,5 +1,5 @@
 /**
- * $Id: ED_datafiles.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 34aefa91225..01882ecd9bc 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -29,34 +29,8 @@
 #define ED_FILES_H
 
 struct SpaceFile;
-
-#define FILE_SHORTDISPLAY	1
-#define FILE_LONGDISPLAY	2
-#define FILE_IMGDISPLAY		3
-
-typedef struct FileSelectParams {
-	char title[24]; /* title, also used for the text of the execute button */
-	char dir[240]; /* directory */
-	char file[80]; /* file */
-
-	short flag; /* settings for filter, hiding files and display mode */
-	short sort; /* sort order */
-	short display; /* display mode flag */
-	short filter; /* filter when (flags & FILE_FILTER) is true */
-
-	/* XXX - temporary, better move to filelist */
-	short active_bookmark;
-	int	active_file;
-	int selstate;
-
-	/* XXX --- still unused -- */
-	short f_fp; /* show font preview */
-	char fp_str[8]; /* string to use for font preview */
-	
-	char *pupmenu; /* allows menu for save options - result stored in menup */
-	short menu; /* currently selected option in pupmenu */
-	/* XXX --- end unused -- */
-} FileSelectParams;
+struct ARegion;
+struct FileSelectParams;
 
 #define FILE_LAYOUT_HOR 1
 #define FILE_LAYOUT_VER 2
@@ -93,7 +67,7 @@ typedef struct FileLayout
 	float column_widths[MAX_FILE_COLUMN];
 } FileLayout;
 
-FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile);
+struct FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile);
 
 short ED_fileselect_set_params(struct SpaceFile *sfile, const char *title, const char *path, 
 						   short flag, short display, short filter, short sort);
diff --git a/source/blender/editors/include/ED_fluidsim.h b/source/blender/editors/include/ED_fluidsim.h
index bda879173c3..586f16f42aa 100644
--- a/source/blender/editors/include/ED_fluidsim.h
+++ b/source/blender/editors/include/ED_fluidsim.h
@@ -1,7 +1,7 @@
 /**
  * BKE_fluidsim.h 
  *	
- * $Id: LBM_fluidsim.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 81420ac95e5..e104bce90f6 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BDR_drawaction.h 17579 2008-11-26 11:01:56Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index fbb469f8d43..9d063910aa9 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_keyframing.h 17216 2008-10-29 11:20:02Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -178,9 +178,9 @@ void ANIM_OT_remove_driver_button(struct wmOperatorType *ot);
 
 /* Auto-Keying macros for use by various tools */
 	/* check if auto-keyframing is enabled (per scene takes presidence) */
-#define IS_AUTOKEY_ON(scene)	((scene) ? (scene->autokey_mode & AUTOKEY_ON) : (U.autokey_mode & AUTOKEY_ON))
+#define IS_AUTOKEY_ON(scene)	((scene) ? (scene->toolsettings->autokey_mode & AUTOKEY_ON) : (U.autokey_mode & AUTOKEY_ON))
 	/* check the mode for auto-keyframing (per scene takes presidence)  */
-#define IS_AUTOKEY_MODE(scene, mode) 	((scene) ? (scene->autokey_mode == AUTOKEY_MODE_##mode) : (U.autokey_mode == AUTOKEY_MODE_##mode))
+#define IS_AUTOKEY_MODE(scene, mode) 	((scene) ? (scene->toolsettings->autokey_mode == AUTOKEY_MODE_##mode) : (U.autokey_mode == AUTOKEY_MODE_##mode))
 	/* check if a flag is set for auto-keyframing (as userprefs only!) */
 #define IS_AUTOKEY_FLAG(flag)	(U.autokey_flag & AUTOKEY_FLAG_##flag)
 
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 6dff4ee6ca4..8952305d6ab 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -110,7 +110,6 @@ void		undo_push_mesh(struct bContext *C, char *name);
 struct EditFace	*EM_get_actFace(struct EditMesh *em, int sloppy);
 void             EM_set_actFace(struct EditMesh *em, struct EditFace *efa);
 float            EM_face_area(struct EditFace *efa);
-void             EM_add_data_layer(struct EditMesh *em, struct CustomData *data, int type);
 
 void		EM_select_edge(struct EditEdge *eed, int sel);
 void		EM_select_face(struct EditFace *efa, int sel);
@@ -134,6 +133,9 @@ struct UvVertMap *EM_make_uv_vert_map(struct EditMesh *em, int selected, int do_
 struct UvMapVert *EM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
 void              EM_free_uv_vert_map(struct UvVertMap *vmap);
 
+void		EM_add_data_layer(struct EditMesh *em, struct CustomData *data, int type);
+void		EM_free_data_layer(struct EditMesh *em, struct CustomData *data, int type);
+
 /* editmesh_mods.c */
 extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs;
 
@@ -147,6 +149,9 @@ int			EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short r
 void		EM_hide_mesh(struct EditMesh *em, int swap);
 void		EM_reveal_mesh(struct EditMesh *em);
 
+void		EM_select_by_material(struct EditMesh *em, int index);
+void		EM_deselect_by_material(struct EditMesh *em, int index); 
+
 /* editface.c */
 struct MTFace	*EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy);
 
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index bfa819632c9..e4e4b1d0486 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -63,6 +63,7 @@ struct Base *ED_object_add_duplicate(struct Scene *scene, struct Base *base, int
 #define EM_FREEDATA		1
 #define EM_FREEUNDO		2
 #define EM_WAITCURSOR	4
+#define EM_DO_UNDO		8
 void ED_object_exit_editmode(struct bContext *C, int flag);
 void ED_object_enter_editmode(struct bContext *C, int flag);
 
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 0e5d7302837..43cb5053f48 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -1,5 +1,5 @@
 /* 
- * $Id: ED_editparticle.h $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_pointcache.h b/source/blender/editors/include/ED_pointcache.h
new file mode 100644
index 00000000000..dc50e274fa9
--- /dev/null
+++ b/source/blender/editors/include/ED_pointcache.h
@@ -0,0 +1,38 @@
+/* 
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef ED_PHYSICS_H
+#define ED_PHYSICS_H
+
+/* operators */
+void ED_operatortypes_pointcache(void);
+//void ED_keymap_pointcache(struct wmWindowManager *wm);
+
+#endif /* ED_PHYSICS_H */
+
diff --git a/source/blender/editors/include/ED_previewrender.h b/source/blender/editors/include/ED_previewrender.h
index c74cb0f9958..10067510e53 100644
--- a/source/blender/editors/include/ED_previewrender.h
+++ b/source/blender/editors/include/ED_previewrender.h
@@ -29,17 +29,14 @@
 struct View3D;
 struct SpaceButs;
 struct RenderInfo;
+struct Scene;
 struct Image;
-struct ScrArea;
-struct uiBlock;
 struct Render;
 struct bContext;
 struct ID;
 
 #define PREVIEW_RENDERSIZE 140
 
-typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
-
 /* stores rendered preview  - is also used for icons */
 typedef struct RenderInfo {
 	int pr_rectx;
@@ -74,6 +71,7 @@ void ED_preview_init_dbase(void);
 void ED_preview_free_dbase(void);
 
 void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, int sizex, int sizey);
+void ED_preview_iconrender(struct Scene *scene, struct ID *id, int *rect, int sizex, int sizey);
 
 void ED_preview_draw(const struct bContext *C, void *idp, rcti *rect);
 
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 38e52a8f59c..b576299c1d0 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -132,6 +132,8 @@ int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, in
 
 /* modes */
 void ED_view3d_exit_paint_modes(struct bContext *C);
+/* get 3d region from context, also if mouse is in header or toolbar */
+struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C);
 
 #endif /* ED_VIEW3D_H */
 
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index a38dfd93c30..602e94838b7 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -74,8 +74,8 @@ DEF_ICON(ICON_CHECKBOX_DEHLT)
 DEF_ICON(ICON_CHECKBOX_HLT)
 DEF_ICON(ICON_UNLOCKED)
 DEF_ICON(ICON_LOCKED)
-DEF_ICON(ICON_PINNED)
 DEF_ICON(ICON_UNPINNED)
+DEF_ICON(ICON_PINNED)
 DEF_ICON(ICON_BLANK015)
 DEF_ICON(ICON_RIGHTARROW)
 DEF_ICON(ICON_DOWNARROW_HLT)
@@ -658,12 +658,12 @@ DEF_ICON(ICON_SNAP_VERTEX)
 DEF_ICON(ICON_SNAP_EDGE)
 DEF_ICON(ICON_SNAP_FACE)
 DEF_ICON(ICON_SNAP_VOLUME)
+DEF_ICON(ICON_UVS_FACE)
 DEF_ICON(ICON_STICKY_UVS_LOC)
 DEF_ICON(ICON_STICKY_UVS_DISABLE)
 DEF_ICON(ICON_STICKY_UVS_VERT)
 DEF_ICON(ICON_CLIPUV_DEHLT)
 DEF_ICON(ICON_CLIPUV_HLT)
-DEF_ICON(ICON_BLANK219)
 DEF_ICON(ICON_SNAP_PEEL_OBJECT)
 DEF_ICON(ICON_BLANK221)
 DEF_ICON(ICON_GRID)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index c53087464c0..cc8b936b04f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1,5 +1,5 @@
 /**
- * $Id: UI_interface.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -53,6 +53,8 @@ struct uiStyle;
 struct uiFontStyle;
 struct ColorBand;
 struct CurveMapping;
+struct Image;
+struct ImageUser;
 
 typedef struct uiBut uiBut;
 typedef struct uiBlock uiBlock;
@@ -415,7 +417,7 @@ void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *
 void uiBlockColorbandButtons(struct uiBlock *block, struct ColorBand *coba, struct rctf *butr, int event);
 
 uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
-void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr);
+void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr, int columns);
 
 /* Links
  *
@@ -452,9 +454,9 @@ typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, char *str,
 typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
 		
 		/* use inside searchfunc to add items */
-int		uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin);
+int		uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid);
 		/* bfunc gets search item *poin as arg2, or if NULL the old string */
-void	uiButSetSearchFunc	(uiBut *but,		uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc);
+void	uiButSetSearchFunc	(uiBut *but,		uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active);
 		/* height in pixels, it's using hardcoded values still */
 int		uiSearchBoxhHeight(void);
 
@@ -607,13 +609,17 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout);
 /* templates */
 void uiTemplateHeader(uiLayout *layout, struct bContext *C);
 void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
-	char *newop, char *openop, char *unlinkop);
+	char *newop, char *unlinkop);
 uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
 uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
 void uiTemplatePreview(uiLayout *layout, struct ID *id);
 void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
 void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type);
 void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);
+void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
+ListBase uiTemplateList(uiLayout *layout, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int columns, int compact);
+void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C);
+void uiTemplateOperatorSearch(uiLayout *layout);
 
 /* items */
 void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
@@ -630,6 +636,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, cha
 void uiItemFullR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int expand, int slider, int toggle);
 void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value);
 void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname);
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname);
 
 void uiItemL(uiLayout *layout, char *name, int icon); /* label */
 void uiItemM(uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname); /* menu */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 7168e593a8a..1ae3634c73b 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -1,5 +1,5 @@
 /**
- * $Id: UI_resources.h 13057 2007-12-30 12:08:28Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/interface/Makefile b/source/blender/editors/interface/Makefile
index dfc8187de49..a3d0692f1e1 100644
--- a/source/blender/editors/interface/Makefile
+++ b/source/blender/editors/interface/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 5ffc6440dc4..00ec875bd86 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface.c 16882 2008-10-02 12:29:45Z ton $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -80,7 +80,6 @@
  */
 
 static void ui_free_but(const bContext *C, uiBut *but);
-static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but);
 
 /* ************* translation ************** */
 
@@ -671,7 +670,8 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
 	/* widgets */
 	for(but= block->buttons.first; but; but= but->next) {
 		ui_but_to_pixelrect(&rect, ar, block, but);
-		ui_draw_but(C, ar, &style, but, &rect);
+		if(!(but->flag & UI_HIDDEN))
+			ui_draw_but(C, ar, &style, but, &rect);
 	}
 	
 	/* restore matrix */
@@ -1281,17 +1281,13 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
 		else if(type == PROP_POINTER) {
 			/* RNA pointer */
 			PointerRNA ptr= RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
-			PropertyRNA *nameprop;
-
-			if(ptr.data && (nameprop = RNA_struct_name_property(ptr.type)))
-				buf= RNA_property_string_get_alloc(&ptr, nameprop, str, maxlen);
-			else
-				BLI_strncpy(str, "", maxlen);
+			buf= RNA_struct_name_get_alloc(&ptr, str, maxlen);
 		}
-		else
-			BLI_strncpy(str, "", maxlen);
 
-		if(buf && buf != str) {
+		if(!buf) {
+			BLI_strncpy(str, "", maxlen);
+		}
+		else if(buf && buf != str) {
 			/* string was too long, we have to truncate */
 			BLI_strncpy(str, buf, maxlen);
 			MEM_freeN(buf);
@@ -1337,72 +1333,6 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
 	}
 }
 
-static void ui_rna_ID_collection(bContext *C, uiBut *but, PointerRNA *ptr, PropertyRNA **prop)
-{
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *iprop;
-	StructRNA *srna;
-
-	/* look for collection property in Main */
-	RNA_pointer_create(NULL, &RNA_Main, CTX_data_main(C), ptr);
-
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-	*prop= NULL;
-
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		iprop= iter.ptr.data;
-
-		/* if it's a collection and has same pointer type, we've got it */
-		if(RNA_property_type(iprop) == PROP_COLLECTION) {
-			srna= RNA_property_pointer_type(ptr, iprop);
-
-			if(RNA_property_pointer_type(ptr, but->rnaprop) == srna) {
-				*prop= iprop;
-				break;
-			}
-		}
-	}
-
-	RNA_property_collection_end(&iter);
-}
-
-/* autocomplete callback for RNA pointers */
-static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but)
-{
-	uiBut *but= arg_but;
-	AutoComplete *autocpl;
-	CollectionPropertyIterator iter;
-	PointerRNA ptr;
-	PropertyRNA *prop, *nameprop;
-	char *name;
-	
-	if(str[0]==0) return;
-
-	/* get the collection */
-	ui_rna_ID_collection(C, but, &ptr, &prop);
-	if(prop==NULL) return;
-
-	autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
-	RNA_property_collection_begin(&ptr, prop, &iter);
-
-	/* loop over items in collection */
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) {
-			name= RNA_property_string_get_alloc(&iter.ptr, nameprop, NULL, 0);
-
-			if(name) {
-				/* test item name */
-				autocomplete_do_name(autocpl, name);
-				MEM_freeN(name);
-			}
-		}
-	}
-
-	RNA_property_collection_end(&iter);
-	autocomplete_end(autocpl, str);
-}
-
 int ui_set_but_string(bContext *C, uiBut *but, const char *str)
 {
 	if(but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
@@ -1421,21 +1351,21 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
 				PointerRNA ptr, rptr;
 				PropertyRNA *prop;
 
-				/* XXX only ID pointers at the moment, needs to support
-				 * custom collection too for bones, vertex groups, .. */
-				ui_rna_ID_collection(C, but, &ptr, &prop);
-
 				if(str == NULL || str[0] == '\0') {
-					memset(&rptr, 0, sizeof(rptr));
-					RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+					RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL);
 					return 1;
 				}
-				else if(prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
-					RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+				else {
+					ptr= but->rnasearchpoin;
+					prop= but->rnasearchprop;
+					
+					if(prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr))
+						RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+
 					return 1;
 				}
-				else
-					return 0;
+
+				return 0;
 			}
 		}
 	}
@@ -2147,13 +2077,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
 		rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2);
 	}
 
-	if((block->flag & UI_BLOCK_LOOP) || ELEM6(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM)) {
-		but->flag |= UI_TEXT_LEFT;
-	}
-	
-	if(but->type==BUT_TOGDUAL) {
+	if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU))
+		but->flag |= (UI_TEXT_LEFT|UI_ICON_LEFT);
+	else if(but->type==BUT_TOGDUAL)
 		but->flag |= UI_ICON_LEFT;
-	}
 
 	but->flag |= (block->flag & UI_BUT_ALIGN);
 
@@ -2257,7 +2184,7 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
 				RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
 				RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
 
-				if(min == max) {
+				if(type != ROW && min == max) {
 					min= hardmin;
 					max= hardmax;
 				}
@@ -2272,7 +2199,7 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
 				RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
 				RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
 
-				if(min == max) {
+				if(type != ROW && min == max) {
 					min= hardmin;
 					max= hardmax;
 				}
@@ -2303,10 +2230,6 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
 			but->rnaindex= index;
 		else
 			but->rnaindex= 0;
-
-		if(type == IDPOIN)
-			uiButSetCompleteFunc(but, ui_rna_ID_autocomplete, but);
-
 	}
 
 	if(icon) {
@@ -2422,7 +2345,11 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
 		else {
 			/* remove from truncate what is not in bone->name */
 			for(a=0; amaxlen-1; a++) {
-				if(truncate[a]!=name[a])
+				if(name[a] == 0) {
+					truncate[a]= 0;
+					break;
+				}
+				else if(truncate[a]!=name[a])
 					truncate[a]= 0;
 			}
 		}
@@ -2753,7 +2680,7 @@ void uiBlockFlipOrder(uiBlock *block)
 	uiBut *but, *next;
 	float centy, miny=10000, maxy= -10000;
 
-	if(!(U.uiflag & USER_DIRECTIONALORDER))
+	if(U.uiflag & USER_MENUFIXEDORDER)
 		return;
 	
 	for(but= block->buttons.first; but; but= but->next) {
@@ -2992,15 +2919,15 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
 }
 
 /* arg is user value, searchfunc and handlefunc both get it as arg */
-void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc)
+/* if active set, button opens with this item visible and selected */
+void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active)
 {
 	but->search_func= sfunc;
 	but->search_arg= arg;
 	
-	uiButSetFunc(but, bfunc, arg, NULL);
+	uiButSetFunc(but, bfunc, arg, active);
 }
 
-
 /* Program Init/Exit */
 
 void UI_init(void)
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 6d6d4ab9299..8400fee0c55 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_draw.c 15733 2008-07-24 09:23:13Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fb5afbf5e36..7ad422ef3b5 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -112,6 +112,9 @@ typedef struct uiHandleButtonData {
 	/* tooltip */
 	ARegion *tooltip;
 	wmTimer *tooltiptimer;
+	
+	/* auto open */
+	int used_mouse;
 	wmTimer *autoopentimer;
 
 	/* text selection/editing */
@@ -284,16 +287,6 @@ static void ui_apply_but_funcs_after(bContext *C)
 		if(after.context)
 			CTX_store_set(C, after.context);
 
-		if(after.func)
-			after.func(C, after.func_arg1, after.func_arg2);
-		if(after.funcN)
-			after.funcN(C, after.func_argN, after.func_arg2);
-		
-		if(after.handle_func)
-			after.handle_func(C, after.handle_func_arg, after.retval);
-		if(after.butm_func)
-			after.butm_func(C, after.butm_func_arg, after.a2);
-
 		if(after.optype)
 			WM_operator_name_call(C, after.optype->idname, after.opcontext, after.opptr);
 		if(after.opptr) {
@@ -308,6 +301,16 @@ static void ui_apply_but_funcs_after(bContext *C)
 			CTX_store_set(C, NULL);
 			CTX_store_free(after.context);
 		}
+
+		if(after.func)
+			after.func(C, after.func_arg1, after.func_arg2);
+		if(after.funcN)
+			after.funcN(C, after.func_argN, after.func_arg2);
+		
+		if(after.handle_func)
+			after.handle_func(C, after.handle_func_arg, after.retval);
+		if(after.butm_func)
+			after.butm_func(C, after.butm_func_arg, after.a2);
 	}
 }
 
@@ -404,7 +407,15 @@ static void ui_apply_but_TOG(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 
 static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
 {
+	uiBut *bt;
+	
 	ui_set_but_val(but, but->hardmax);
+	
+	/* states of other row buttons */
+	for(bt= block->buttons.first; bt; bt= bt->next)
+		if(bt!=but && bt->poin==but->poin && bt->type==ROW)
+			ui_check_but(bt);
+	
 	ui_apply_but_func(C, but);
 
 	data->retval= but->retval;
@@ -738,11 +749,8 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
 			ui_apply_but_ROW(C, block, but, data);
 			break;
 		case SCROLL:
-			break;
 		case NUM:
 		case NUMABS:
-			ui_apply_but_NUM(C, but, data);
-			break;
 		case SLI:
 		case NUMSLI:
 			ui_apply_but_NUM(C, but, data);
@@ -1218,8 +1226,14 @@ static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData
 	int changed= 1;
 
 	str= data->str;
-	but->autocomplete_func(C, str, but->autofunc_arg);
+
+	if(data->searchbox)
+		ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
+	else
+		but->autocomplete_func(C, str, but->autofunc_arg);
+
 	but->pos= strlen(str);
+	but->selsta= but->selend= but->pos;
 
 	return changed;
 }
@@ -1346,14 +1360,14 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
 		return;
 
 	for(but= actbut->next; but; but= but->next) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
 		}
 	}
 	for(but= block->buttons.first; but!=actbut; but= but->next) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
@@ -1370,14 +1384,14 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
 		return;
 
 	for(but= actbut->prev; but; but= but->prev) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
 		}
 	}
 	for(but= block->buttons.last; but!=actbut; but= but->prev) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
@@ -1433,7 +1447,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
 				}
 			}
 			else if(inbox) {
-				printf("release inside \n");
 				button_activate_state(C, but, BUTTON_STATE_EXIT);
 				retval= WM_UI_HANDLER_BREAK;
 			}
@@ -1502,7 +1515,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
 				
 			case TABKEY:
 				/* there is a key conflict here, we can't tab with autocomplete */
-				if(but->autocomplete_func) {
+				if(but->autocomplete_func || data->searchbox) {
 					changed= ui_textedit_autocomplete(C, but, data);
 					retval= WM_UI_HANDLER_BREAK;
 				}
@@ -2053,6 +2066,11 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
 
 	if(but->type==NUMSLI) deler= ((but->x2-but->x1) - 5.0*but->aspect);
 	else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
+	else if(but->type==SCROLL) {
+		int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
+		float size= (horizontal)? (but->x2-but->x1): -(but->y2-but->y1);
+		deler= size*(but->softmax - but->softmin)/(but->softmax - but->softmin + but->a1);
+	}
 	else deler= (but->x2-but->x1- 5.0*but->aspect);
 
 	f= (float)(mx-data->dragstartx)/deler + data->dragfstart;
@@ -2223,6 +2241,54 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 	return retval;
 }
 
+static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+	int mx, my, click= 0;
+	int retval= WM_UI_HANDLER_CONTINUE;
+	int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
+	
+	mx= event->x;
+	my= event->y;
+	ui_window_to_block(data->region, block, &mx, &my);
+
+	if(data->state == BUTTON_STATE_HIGHLIGHT) {
+		if(event->val==KM_PRESS) {
+			if(event->type == LEFTMOUSE) {
+				if(horizontal) {
+					data->dragstartx= mx;
+					data->draglastx= mx;
+				}
+				else {
+					data->dragstartx= my;
+					data->draglastx= my;
+				}
+				button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+				retval= WM_UI_HANDLER_BREAK;
+			}
+			else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS)
+				click= 1;
+		}
+	}
+	else if(data->state == BUTTON_STATE_NUM_EDITING) {
+		if(event->type == ESCKEY) {
+			data->cancel= 1;
+			data->escapecancel= 1;
+			button_activate_state(C, but, BUTTON_STATE_EXIT);
+		}
+		else if(event->type == LEFTMOUSE && event->val!=KM_PRESS) {
+			button_activate_state(C, but, BUTTON_STATE_EXIT);
+		}
+		else if(event->type == MOUSEMOVE) {
+			if(ui_numedit_but_SLI(but, data, 0, 0, (horizontal)? mx: my))
+				ui_numedit_apply(C, block, but, data);
+		}
+
+		retval= WM_UI_HANDLER_BREAK;
+	}
+	
+	return retval;
+}
+
 static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
 	
@@ -3065,13 +3131,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
 	case OPTIONN:
 		retval= ui_do_but_TOG(C, but, data, event);
 		break;
-#if 0
 	case SCROLL:
-		/* DrawBut(b, 1); */
-		/* do_scrollbut(b); */
-		/* DrawBut(b,0); */
+		retval= ui_do_but_SCROLL(C, block, but, data, event);
 		break;
-#endif
 	case NUM:
 	case NUMABS:
 		retval= ui_do_but_NUM(C, block, but, data, event);
@@ -3232,7 +3294,8 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
 		for(but=block->buttons.first; but; but= but->next) {
 			if(ELEM3(but->type, LABEL, ROUNDBOX, SEPR))
 				continue;
-
+			if(but->flag & UI_HIDDEN)
+				continue;
 			if(ui_but_contains_pt(but, mx, my))
 				/* give precedence to already activated buttons */
 				if(!butover || (!butover->active && but->active))
@@ -3284,7 +3347,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
 
 		/* automatic open pulldown block timer */
 		if(ELEM3(but->type, BLOCK, PULLDOWN, ICONTEXTROW)) {
-			if(!data->autoopentimer) {
+			if(data->used_mouse && !data->autoopentimer) {
 				int time;
 
 				if(but->block->auto_open==2) time= 1;    // test for toolbox
@@ -3387,6 +3450,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
 		if(but->block->auto_open_last+BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer())
 			but->block->auto_open= 0;
 
+	if(type == BUTTON_ACTIVATE_OVER) {
+		data->used_mouse= 1;
+	}
 	button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
 	
 	if(type == BUTTON_ACTIVATE_OPEN) {
@@ -3705,12 +3771,19 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
 		button_activate_exit(C, data, but, 1);
 	}
 	else if(menu->menuretval == UI_RETURN_OUT) {
-		if(ui_mouse_inside_button(data->region, but, event->x, event->y)) {
+		if(event->type==MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) {
 			button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
 		}
 		else {
-			data->cancel= 1;
-			button_activate_exit(C, data, but, 1);
+			but= ui_but_find_activated(data->region);
+			if(but) {
+				but->active->used_mouse= 0;
+				button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
+			}
+			else {
+				data->cancel= 1;
+				button_activate_exit(C, data, but, 1);
+			}
 		}
 	}
 }
@@ -4049,7 +4122,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
 	uiBlock *block;
 	uiHandleButtonData *data;
 	uiPopupBlockHandle *submenu;
-	int mx, my;
+	int mx, my, update;
 
 	ar= menu->region;
 	block= ar->uiblocks.first;
@@ -4067,14 +4140,16 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
 				menu->butretval= data->retval;
 			}
 		}
-		else if(submenu->menuretval == UI_RETURN_UPDATE)
+
+		update= (submenu->menuretval == UI_RETURN_UPDATE);
+		if(update)
 			menu->menuretval = UI_RETURN_UPDATE;
 
 		/* now let activated button in this menu exit, which
 		 * will actually close the submenu too */
 		ui_handle_button_return_submenu(C, event, but);
 
-		if(submenu->menuretval == UI_RETURN_UPDATE)
+		if(update)
 			submenu->menuretval = 0;
 	}
 
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index df069069a33..315b8693905 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -41,28 +41,30 @@
 #include "BLI_blenlib.h"
 #include "BLI_storage_types.h"
 
+#include "DNA_material_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 
-
-#include "BKE_utildefines.h"
 #include "BKE_image.h"
 #include "BKE_icons.h"
+#include "BKE_utildefines.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
-#include "UI_interface.h"
-#include "UI_interface_icons.h"
 
-// XXX #include "BIF_previewrender.h"
-// XXX #include "BIF_screen.h"
+#include "ED_datafiles.h"
+#include "ED_previewrender.h"
 
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
 #include "UI_resources.h" /* elubie: should be removed once the enum for the ICONS is in BIF_preview_icons.h */
+
 #include "interface_intern.h"
-#include "ED_datafiles.h"
+
 
 #define ICON_IMAGE_W		600
 #define ICON_IMAGE_H		640
@@ -650,7 +652,6 @@ void UI_icons_init(int first_dyn_id)
 	init_internal_icons();
 }
 
-#if 0
 static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
 {
 	struct ImBuf *ima;
@@ -727,21 +728,28 @@ static void icon_create_mipmap(struct PreviewImage* prv_img, int miplevel)
 }
 
 /* create single icon from jpg, png etc. */
-static void icon_from_image(Image *img, int miplevel)
+static void icon_from_image(Scene *scene, Image *img, int miplevel)
 {
+	ImBuf *ibuf= NULL;
+	ImageUser iuser;
+	PreviewImage *pi;
 	unsigned int pr_size;
 	short image_loaded = 0;
-	struct ImBuf* ibuf=NULL;
-	PreviewImage* pi;
 
 	/* img->ok is zero when Image cannot load */
 	if (img==NULL || img->ok==0)
 		return;
 
+	/* setup dummy image user */
+	memset(&iuser, 0, sizeof(ImageUser));
+	iuser.ok= iuser.framenr= 1;
+	iuser.scene= scene;
+	
 	/* elubie: this needs to be changed: here image is always loaded if not
 	   already there. Very expensive for large images. Need to find a way to 
 	   only get existing ibuf */
-	ibuf = BKE_image_get_ibuf(img, NULL);
+	
+	ibuf = BKE_image_get_ibuf(img, &iuser);
 	if(ibuf==NULL || ibuf->rect==NULL) {
 		return;
 	}
@@ -771,18 +779,14 @@ static void set_alpha(char* cp, int sizex, int sizey, char alpha)
 		}
 	}
 }
-#endif
 
 /* only called when icon has changed */
 /* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int miplevel)
+static void icon_set_image(Scene *scene, ID *id, PreviewImage* prv_img, int miplevel)
 {
-#if 0 // XXX - preview renders have to be redesigned - possibly low level op (elubie)
 	RenderInfo ri;	
 	unsigned int pr_size = 0;
 	
-	if (!di) return;				
-	
 	if (!prv_img) {
 		printf("No preview image for this ID: %s\n", id->name);
 		return;
@@ -791,20 +795,19 @@ static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int mipl
 	/* no drawing (see last parameter doDraw, just calculate preview image 
 		- hopefully small enough to be fast */
 	if (GS(id->name) == ID_IM)
-		icon_from_image((struct Image*)id, miplevel);
+		icon_from_image(scene, (struct Image*)id, miplevel);
 	else {	
 		/* create the preview rect */
 		icon_create_mipmap(prv_img, miplevel);
 
 		ri.curtile= 0;
 		ri.tottile= 0;
-		ri.rect = NULL;
 		ri.pr_rectx = prv_img->w[miplevel];
 		ri.pr_recty = prv_img->h[miplevel];
-
 		pr_size = ri.pr_rectx*ri.pr_recty*sizeof(unsigned int);
+		ri.rect = MEM_callocN(pr_size, "pr icon rect");
 
-		BIF_previewrender(id, &ri, NULL, PR_ICON_RENDER);
+		ED_preview_iconrender(scene, id, ri.rect, ri.pr_rectx, ri.pr_recty);
 
 		/* world is rendered with alpha=0, so it wasn't displayed 
 		   this could be render option for sky to, for later */
@@ -818,15 +821,11 @@ static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int mipl
 			}
 		}
 
-		if (ri.rect) {
-			memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
+		memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
 
-			/* and clean up */
-			MEM_freeN(ri.rect);
-			ri.rect = 0;
-		}
+		/* and clean up */
+		MEM_freeN(ri.rect);
 	}
-#endif
 }
 
 static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect)
@@ -912,14 +911,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
 		PreviewImage* pi = BKE_previewimg_get((ID*)icon->obj); 
 
 		if (pi) {			
-			if (!nocreate && (pi->changed[miplevel] ||!pi->rect[miplevel])) /* changed only ever set by dynamic icons */
-			{
-				// XXX waitcursor(1);
-				/* create the preview rect if necessary */				
-				icon_set_image((ID*)icon->obj, icon->drawinfo, pi, miplevel);
-				pi->changed[miplevel] = 0;
-				// XXX waitcursor(0);
-			}
+			/* no create icon on this level in code */
 			
 			if (!pi->rect[miplevel]) return; /* something has gone wrong! */
 			
@@ -928,6 +920,43 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
 	}
 }
 
+void ui_id_icon_render(Scene *scene, ID *id)
+{
+	PreviewImage *pi = BKE_previewimg_get(id); 
+		
+	if (pi) {			
+		if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
+		{
+			/* create the preview rect if necessary */				
+			icon_set_image(scene, id, pi, 0);
+			pi->changed[0] = 0;
+		}
+	}
+}
+
+int ui_id_icon_get(Scene *scene, ID *id)
+{
+	int iconid= 0;
+	
+	/* icon */
+	switch(GS(id->name))
+	{
+		case ID_MA: /* fall through */
+		case ID_TE: /* fall through */
+		case ID_IM: /* fall through */
+		case ID_WO: /* fall through */
+		case ID_LA: /* fall through */
+			iconid= BKE_icon_getid(id);
+			/* checks if not exists, or changed */
+			ui_id_icon_render(scene, id);
+			break;
+		default:
+			break;
+	}
+
+	return iconid;
+}
+
 static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate)
 {
 	int draw_size = preview_size(miplevel);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 3aed2a7c299..1b16155c7e6 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1,5 +1,5 @@
 /**
- * $Id: interface.h 14444 2008-04-16 22:40:48Z hos $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -44,12 +44,17 @@ struct uiStyle;
 struct uiWidgetColors;
 struct uiLayout;
 struct bContextStore;
+struct Scene;
+struct ID;
 
 /* ****************** general defines ************** */
 
 /* visual types for drawing */
 /* for time being separated from functional types */
 typedef enum {
+	/* default */
+	UI_WTYPE_REGULAR,
+
 	/* standard set */
 	UI_WTYPE_LABEL,
 	UI_WTYPE_TOGGLE,
@@ -78,7 +83,8 @@ typedef enum {
 	UI_WTYPE_SWATCH,
 	UI_WTYPE_RGB_PICKER,
 	UI_WTYPE_NORMAL,
-	UI_WTYPE_BOX
+	UI_WTYPE_BOX,
+	UI_WTYPE_SCROLL
 	
 } uiWidgetTypeEnum;
 
@@ -98,7 +104,7 @@ typedef enum {
 #define UI_ACTIVE		4
 #define UI_HAS_ICON		8
 #define UI_TEXTINPUT	16
-
+#define UI_HIDDEN		32
 /* warn: rest of uiBut->flag in UI_interface.h */
 
 /* internal panel drawing defines */
@@ -205,6 +211,9 @@ struct uiBut {
 	struct PropertyRNA *rnaprop;
 	int rnaindex;
 
+	struct PointerRNA rnasearchpoin;
+	struct PropertyRNA *rnasearchprop;
+
 	/* Operator data */
 	struct wmOperatorType *optype;
 	int opcontext;
@@ -365,6 +374,7 @@ void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
 ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
 int ui_searchbox_inside(struct ARegion *ar, int x, int y);
 void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, int reset);
+void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
 void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, struct wmEvent *event);
 void ui_searchbox_apply(uiBut *but, struct ARegion *ar);
 void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
@@ -416,11 +426,15 @@ extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *s
 struct ThemeUI;
 void ui_widget_color_init(struct ThemeUI *tui);
 
-void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int state);
+void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
 
 /* interface_style.c */
 void uiStyleInit(void);
 
+/* interface_icons.c */
+void ui_id_icon_render(struct Scene *scene, struct ID *id);
+int ui_id_icon_get(struct Scene *scene, struct ID *id);
+
 /* resources.c */
 void init_userdef_do_versions(void);
 void ui_theme_init_userdef(void);
@@ -428,8 +442,9 @@ void ui_resources_init(void);
 void ui_resources_free(void);
 
 /* interface_layout.c */
-void ui_layout_add_but(struct uiLayout *layout, uiBut *but);
+void ui_layout_add_but(uiLayout *layout, uiBut *but);
 int ui_but_can_align(uiBut *but);
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
 
 /* interface_anim.c */
 void ui_but_anim_flag(uiBut *but, float cfra);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 9101fd743ee..f9816235b88 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_layout.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -455,9 +455,10 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr,
 }
 
 /* create label + button for RNA property */
-static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
+static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
 {
 	uiLayout *sub;
+	uiBut *but;
 	PropertySubType subtype;
 
 	sub= uiLayoutRow(layout, 0);
@@ -473,12 +474,13 @@ static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int
 	if(subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
 		uiBlockSetCurLayout(block, uiLayoutRow(sub, 1));
 		uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w-UI_UNIT_X, h);
-		uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
+		but= uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
 	}
 	else
-		uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
+		but= uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
 
 	uiBlockSetCurLayout(block, layout);
+	return but;
 }
 
 /********************* Button Items *************************/
@@ -601,7 +603,7 @@ void uiItemsEnumO(uiLayout *layout, char *opname, char *propname)
 		RNA_property_enum_items(&ptr, prop, &item, &totitem);
 
 		for(i=0; iroot->type == UI_LAYOUT_MENU) {
@@ -778,8 +784,10 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
 	else if(type == PROP_ENUM && expand)
 		ui_item_enum_row(layout, block, ptr, prop, name, 0, 0, w, h);
 	/* property with separate label */
-	else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER)
-		ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+	else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
+		but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+		ui_but_add_search(but, ptr, prop, NULL, NULL);
+	}
 	/* single button */
 	else {
 		but= uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h);
@@ -850,6 +858,142 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
 	}
 }
 
+/* Pointer RNA button with search */
+
+static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, uiSearchItems *items)
+{
+	Scene *scene= CTX_data_scene(C);
+	uiBut *but= arg_but;
+	char *name;
+	int i, iconid;
+
+	i = 0;
+	RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
+		iconid= 0;
+		if(RNA_struct_is_ID(itemptr.type))
+			iconid= ui_id_icon_get(scene, itemptr.data);
+
+		name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+		if(name) {
+			if(BLI_strcasestr(name, str)) {
+				if(!uiSearchItemAdd(items, name, SET_INT_IN_POINTER(i), iconid)) {
+					MEM_freeN(name);
+					break;
+				}
+			}
+
+			MEM_freeN(name);
+		}
+
+		i++;
+	}
+	RNA_PROP_END;
+}
+
+static void search_id_collection(StructRNA *ptype, PointerRNA *ptr, PropertyRNA **prop)
+{
+	StructRNA *srna;
+
+	/* look for collection property in Main */
+	RNA_main_pointer_create(G.main, ptr);
+
+	*prop= NULL;
+
+	RNA_STRUCT_BEGIN(ptr, iprop) {
+		/* if it's a collection and has same pointer type, we've got it */
+		if(RNA_property_type(iprop) == PROP_COLLECTION) {
+			srna= RNA_property_pointer_type(ptr, iprop);
+
+			if(ptype == srna) {
+				*prop= iprop;
+				break;
+			}
+		}
+	}
+	RNA_STRUCT_END;
+}
+
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
+{
+	StructRNA *ptype;
+	PointerRNA sptr;
+
+	/* for ID's we do automatic lookup */
+	if(!searchprop) {
+		if(RNA_property_type(prop) == PROP_POINTER) {
+			ptype= RNA_property_pointer_type(ptr, prop);
+			search_id_collection(ptype, &sptr, &searchprop);
+			searchptr= &sptr;
+		}
+	}
+
+	/* turn button into search button */
+	if(searchprop) {
+		but->type= SEARCH_MENU;
+		but->hardmax= MAX2(but->hardmax, 256);
+		but->rnasearchpoin= *searchptr;
+		but->rnasearchprop= searchprop;
+		but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT;
+
+		uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL);
+	}
+}
+
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname)
+{
+	PropertyRNA *prop, *searchprop;
+	PropertyType type;
+	uiBut *but;
+	uiBlock *block;
+	StructRNA *icontype;
+	int w, h;
+	
+	/* validate arguments */
+	if(!ptr->data || !searchptr->data)
+		return;
+
+	prop= RNA_struct_find_property(ptr, propname);
+
+	if(!prop) {
+		printf("uiItemPointerR: property not found: %s\n", propname);
+		return;
+	}
+	
+	type= RNA_property_type(prop);
+	if(!ELEM(type, PROP_POINTER, PROP_STRING)) {
+		printf("uiItemPointerR: property %s must be a pointer or string.\n", propname);
+		return;
+	}
+
+	searchprop= RNA_struct_find_property(searchptr, searchpropname);
+
+	if(!searchprop || RNA_property_type(searchprop) != PROP_COLLECTION) {
+		printf("uiItemPointerR: search collection property not found: %s\n", searchpropname);
+		return;
+	}
+
+	/* get icon & name */
+	if(!icon) {
+		if(type == PROP_POINTER)
+			icontype= RNA_property_pointer_type(ptr, prop);
+		else
+			icontype= RNA_property_pointer_type(searchptr, searchprop);
+
+		icon= RNA_struct_ui_icon(icontype);
+	}
+	if(!name)
+		name= (char*)RNA_property_ui_name(prop);
+
+	/* create button */
+	block= uiLayoutGetBlock(layout);
+
+	ui_item_rna_size(layout, name, icon, prop, 0, &w, &h);
+	but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h);
+
+	ui_but_add_search(but, ptr, prop, searchptr, searchprop);
+}
+
 /* menu item */
 static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
 {
@@ -1267,7 +1411,6 @@ static void ui_litem_layout_box(uiLayout *litem)
 	h= litem->h;
 
 	litem->x += style->boxspace;
-	litem->y -= style->boxspace;
 
 	if(w != 0) litem->w -= 2*style->boxspace;
 	if(h != 0) litem->h -= 2*style->boxspace;
@@ -1348,6 +1491,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
 		}
 	}
 
+	litem->w= x;
 	litem->h= litem->y - miny;
 }
 
@@ -1453,9 +1597,9 @@ static void ui_litem_layout_free(uiLayout *litem)
 	totw -= minx;
 	toth -= miny;
 
-	if(litem->w && totw > litem->w)
+	if(litem->w && totw > 0)
 		scalex= (float)litem->w/(float)totw;
-	if(litem->h && toth > litem->h)
+	if(litem->h && toth > 0)
 		scaley= (float)litem->h/(float)toth;
 	
 	x= litem->x;
@@ -1466,15 +1610,15 @@ static void ui_litem_layout_free(uiLayout *litem)
 		ui_item_size(item, &itemw, &itemh);
 
 		if(scalex != 1.0f) {
-			newx= itemx*scalex;
-			itemw= (itemx + itemw)*scalex - newx;
-			itemx= newx;
+			newx= (itemx - minx)*scalex;
+			itemw= (itemx - minx + itemw)*scalex - newx;
+			itemx= minx + newx;
 		}
 
 		if(scaley != 1.0f) {
-			newy= itemy*scaley;
-			itemh= (itemy + itemh)*scaley - newy;
-			itemy= newy;
+			newy= (itemy - miny)*scaley;
+			itemh= (itemy - miny + itemh)*scaley - newy;
+			itemy= miny + newy;
 		}
 
 		ui_item_position(item, x+itemx-minx, y+itemy-miny, itemw, itemh);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 72076175ad5..a20884a61a3 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -104,7 +104,9 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
 		SpaceButs *sbuts= sa->spacedata.first;
 		return sbuts->align;
 	}
-	else if(ar->regiontype==RGN_TYPE_UI)
+	else if(sa->spacetype==SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
+		return BUT_VERTICAL;
+	else if(ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS))
 		return BUT_VERTICAL;
 	
 	return 0;
@@ -126,6 +128,8 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
 	}
 	else if(ar->regiontype==RGN_TYPE_UI)
 		return 1;
+	else if(sa->spacetype==SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
+		return 1;
 
 	/* in case panel is added or disappears */
 	for(pa=ar->panels.first; pa; pa=pa->next) {
@@ -1288,6 +1292,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
 
 /**************** window level modal panel interaction **************/
 
+/* note, this is modal handler and should not swallow events for animation */
 static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
 {
 	Panel *panel= userdata;
@@ -1303,8 +1308,6 @@ static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
 			panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
 		else
 			panel_activate_state(C, panel, PANEL_STATE_EXIT);
-
-		return WM_UI_HANDLER_BREAK;
 	}
 	else if(event->type == MOUSEMOVE) {
 		if(data->state == PANEL_STATE_WAIT_UNTAB)
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 32bcae77e6b..27fb0731d67 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -40,6 +40,7 @@
 #include "BLI_dynstr.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
 #include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_texture.h"
@@ -181,7 +182,7 @@ MenuData *decompose_menu_string(char *str)
 				*s= '\0';
 				s++;
 			}
-		} else if (c=='|' || c=='\0') {
+		} else if (c=='|' || c == '\n' || c=='\0') {
 			if (nitem) {
 				*s= '\0';
 
@@ -433,7 +434,10 @@ struct uiSearchItems {
 	
 	char **names;
 	void **pointers;
-	
+	int *icons;
+
+	AutoComplete *autocpl;
+	void *active;
 };
 
 typedef struct uiSearchboxData {
@@ -448,8 +452,21 @@ typedef struct uiSearchboxData {
 
 /* exported for use by search callbacks */
 /* returns zero if nothing to add */
-int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
+int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid)
 {
+	/* hijack for autocomplete */
+	if(items->autocpl) {
+		autocomplete_do_name(items->autocpl, name);
+		return 1;
+	}
+	
+	/* hijack for finding active item */
+	if(items->active) {
+		if(poin==items->active)
+			items->offset_i= items->totitem;
+		items->totitem++;
+		return 1;
+	}
 	
 	if(items->totitem>=items->maxitem) {
 		items->more= 1;
@@ -464,6 +481,7 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
 	
 	BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
 	items->pointers[items->totitem]= poin;
+	items->icons[items->totitem]= iconid;
 	
 	items->totitem++;
 	
@@ -588,20 +606,52 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
 	/* reset vars */
 	data->items.totitem= 0;
 	data->items.more= 0;
-	if(reset==0)
+	if(reset==0) {
 		data->items.offset_i= data->items.offset;
+	}
 	else {
 		data->items.offset_i= data->items.offset= 0;
 		data->active= 0;
+		
+		/* handle active */
+		if(but->search_func && but->func_arg2) {
+			data->items.active= but->func_arg2;
+			but->search_func(C, but->search_arg, but->editstr, &data->items);
+			data->items.active= NULL;
+			
+			/* found active item, calculate real offset by centering it */
+			if(data->items.totitem) {
+				/* first case, begin of list */
+				if(data->items.offset_i < data->items.maxitem) {
+					data->active= data->items.offset_i+1;
+					data->items.offset_i= 0;
+				}
+				else {
+					/* second case, end of list */
+					if(data->items.totitem - data->items.offset_i <= data->items.maxitem) {
+						data->active= 1 + data->items.offset_i - data->items.totitem + data->items.maxitem;
+						data->items.offset_i= data->items.totitem - data->items.maxitem;
+					}
+					else {
+						/* center active item */
+						data->items.offset_i -= data->items.maxitem/2;
+						data->active= 1 + data->items.maxitem/2;
+					}
+				}
+			}
+			data->items.offset= data->items.offset_i;
+			data->items.totitem= 0;
+		}
 	}
 	
 	/* callback */
 	if(but->search_func)
 		but->search_func(C, but->search_arg, but->editstr, &data->items);
 	
-	if(reset) {
+	/* handle case where editstr is equal to one of items */
+	if(reset && data->active==0) {
 		int a;
-		/* handle case where editstr is equal to one of items */
+		
 		for(a=0; aitems.totitem; a++) {
 			char *cpoin= strchr(data->items.names[a], '|');
 			
@@ -620,6 +670,18 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
 	ED_region_tag_redraw(ar);
 }
 
+void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
+{
+	uiSearchboxData *data= ar->regiondata;
+
+	data->items.autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
+
+	but->search_func(C, but->search_arg, but->editstr, &data->items);
+
+	autocomplete_end(data->items.autocpl, str);
+	data->items.autocpl= NULL;
+}
+
 static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 {
 	uiSearchboxData *data= ar->regiondata;
@@ -639,18 +701,21 @@ static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 		for(a=0; aitems.totitem; a++) {
 			ui_searchbox_butrect(&rect, data, a);
 			
-			ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], (a+1)==data->active?UI_ACTIVE:0);
+			/* widget itself */
+			ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
 			
 		}
 		/* indicate more */
 		if(data->items.more) {
+			ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
 			glEnable(GL_BLEND);
-			UI_icon_draw((data->bbox.xmax-data->bbox.xmin)/2, 8, ICON_TRIA_DOWN);
+			UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
 			glDisable(GL_BLEND);
 		}
 		if(data->items.offset) {
+			ui_searchbox_butrect(&rect, data, 0);
 			glEnable(GL_BLEND);
-			UI_icon_draw((data->bbox.xmax-data->bbox.xmin)/2, data->bbox.ymax-13, ICON_TRIA_UP);
+			UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
 			glDisable(GL_BLEND);
 		}
 	}
@@ -666,6 +731,7 @@ static void ui_searchbox_region_free(ARegion *ar)
 		MEM_freeN(data->items.names[a]);
 	MEM_freeN(data->items.names);
 	MEM_freeN(data->items.pointers);
+	MEM_freeN(data->items.icons);
 	
 	MEM_freeN(data);
 	ar->regiondata= NULL;
@@ -679,7 +745,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
 	uiSearchboxData *data;
 	float aspect= but->block->aspect;
 	float x1f, x2f, y1f, y2f;
-	int x1, x2, y1, y2, winx, winy;
+	int x1, x2, y1, y2, winx, winy, ofsx, ofsy;
 	
 	/* create area region */
 	ar= ui_add_temporary_region(CTX_wm_screen(C));
@@ -732,6 +798,14 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
 		x2f= but->x2 + 5;	/* symmetrical */
 		y2f= but->y1;
 		y1f= y2f - uiSearchBoxhHeight();
+
+		ofsx= (but->block->panel)? but->block->panel->ofsx: 0;
+		ofsy= (but->block->panel)? but->block->panel->ofsy: 0;
+
+		x1f += ofsx;
+		x2f += ofsx;
+		y1f += ofsy;
+		y2f += ofsy;
 	
 		/* minimal width */
 		if(x2f - x1f < 150) x2f= x1f+150; // XXX arbitrary
@@ -794,6 +868,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
 	data->items.totitem= 0;
 	data->items.names= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search names");
 	data->items.pointers= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search pointers");
+	data->items.icons= MEM_callocN(SEARCH_ITEMS*sizeof(int), "search icons");
 	for(x1=0; x1items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers");
 	
@@ -1720,24 +1795,118 @@ static void do_picker_small_cb(bContext *C, void *bt1, void *hsv1)
 		popup->menuretval= UI_RETURN_UPDATE;
 }
 
+/* picker sizes S hsize, F full size, D spacer, B button/pallette height  */
+#define SPICK1	150.0
+#define DPICK1	6.0
 
-/* only the color, a circle, slider */
-void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+/* only the color, a HS circle and V slider */
+static void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
 {
 	uiBut *bt;
 	
 	VECCOPY(old, col);	// old color stored there, for palette_cb to work
 	
 	/* HS circle */
-	bt= uiDefButF(block, HSVCIRCLE, retval, "",	0, 0,SPICK,SPICK, col, 0.0, 0.0, 0, 0, "");
+	bt= uiDefButF(block, HSVCIRCLE, retval, "",	0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
 	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
 
 	/* value */
-	bt= uiDefButF(block, HSVCUBE, retval, "",	SPICK+DPICK,0,14,SPICK, col, 0.0, 0.0, 4, 0, "");
+	bt= uiDefButF(block, HSVCUBE, retval, "",	SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
+	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+}
+
+
+static void picker_new_hide_reveal(uiBlock *block, short colormode)
+{
+	uiBut *bt;
+	
+	/* tag buttons */
+	for(bt= block->buttons.first; bt; bt= bt->next) {
+		
+		if(bt->type==NUMSLI || bt->type==TEX) {
+			if( bt->str[1]=='e') {
+				if(colormode==2) bt->flag &= ~UI_HIDDEN;
+				else bt->flag |= UI_HIDDEN;
+			}
+			else if( ELEM3(bt->str[0], 'R', 'G', 'B')) {
+				if(colormode==0) bt->flag &= ~UI_HIDDEN;
+				else bt->flag |= UI_HIDDEN;
+			}
+			else if( ELEM3(bt->str[0], 'H', 'S', 'V')) {
+				if(colormode==1) bt->flag &= ~UI_HIDDEN;
+				else bt->flag |= UI_HIDDEN;
+			}
+		}
+	}
+}
+
+static void do_picker_new_mode_cb(bContext *C, void *bt1, void *colv)
+{
+	uiBut *bt= bt1;
+	short colormode= ui_get_but_val(bt);
+
+	picker_new_hide_reveal(bt->block, colormode);
+}
+
+
+/* a HS circle, V slider, rgb/hsv/hex sliders */
+static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+{
+	static short colormode= 0;	/* temp? 0=rgb, 1=hsv, 2=hex */
+	uiBut *bt;
+	int width;
+	
+	VECCOPY(old, col);	// old color stored there, for palette_cb to work
+	
+	/* HS circle */
+	bt= uiDefButF(block, HSVCIRCLE, retval, "",	0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+	
+	/* value */
+	bt= uiDefButF(block, HSVCUBE, retval, "",	SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
 	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+	
+	/* mode */
+	width= (SPICK1+DPICK1+14)/3;
+	uiBlockBeginAlign(block);
+	bt= uiDefButS(block, ROW, retval, "RGB",	0, -30, width, 19, &colormode, 0.0, 0.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_new_mode_cb, bt, col);
+	bt= uiDefButS(block, ROW, retval, "HSV",	width, -30, width, 19, &colormode, 0.0, 1.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_new_mode_cb, bt, hsv);
+	bt= uiDefButS(block, ROW, retval, "Hex",	2*width, -30, width, 19, &colormode, 0.0, 2.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_new_mode_cb, bt, hexcol);
+	uiBlockEndAlign(block);
+	
+	/* sliders or hex */
+	width= (SPICK1+DPICK1+14);
+	rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
+	sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));	
 
+	uiBlockBeginAlign(block);
+	bt= uiDefButF(block, NUMSLI, 0, "R ",	0, -60, width, 19, col, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+	bt= uiDefButF(block, NUMSLI, 0, "G ",	0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+	bt= uiDefButF(block, NUMSLI, 0, "B ",	0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+	uiBlockEndAlign(block);
+
+	uiBlockBeginAlign(block);
+	bt= uiDefButF(block, NUMSLI, 0, "H ",	0, -60, width, 19, hsv, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette2_cb, bt, col);
+	bt= uiDefButF(block, NUMSLI, 0, "S ",	0, -80, width, 19, hsv+1, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette2_cb, bt, col);
+	bt= uiDefButF(block, NUMSLI, 0, "V ",	0, -100, width, 19, hsv+2, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette2_cb, bt, col);
+	uiBlockEndAlign(block);
+
+	bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -80, width, 19, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
+	uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
+
+	picker_new_hide_reveal(block, colormode);
 }
 
+
 static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *event)
 {
 	float add= 0.0f;
@@ -1790,13 +1959,22 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
 		block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
 		uiBoundsBlock(block, 3);
 	}
-	else {
+	else if(win->eventstate->alt) {
 		uiBlockPickerSmall(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
 		block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_OUT_1;
 		uiBoundsBlock(block, 10);
 		
 		block->block_event_func= ui_picker_small_wheel;
-	}		
+	}
+	else {
+		uiBlockPickerNew(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
+		block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
+		uiBoundsBlock(block, 10);
+		
+		block->block_event_func= ui_picker_small_wheel;
+	}
+	
+	
 	/* and lets go */
 	block->direction= UI_TOP;
 	
@@ -2464,7 +2642,6 @@ static uiPopupBlockHandle *ui_pup_menu(bContext *C, int maxrow, uiMenuHandleFunc
 	return menu;
 }
 
-
 static void operator_name_cb(bContext *C, void *arg, int retval)
 {
 	const char *opname= arg;
@@ -2585,6 +2762,8 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
 			BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message);
 		else if(report->type >= RPT_WARNING)
 			BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message);
+		else if(report->type >= RPT_INFO)
+			BLI_dynstr_appendf(ds, "Info %%t|%s", report->message);
 	}
 
 	str= BLI_dynstr_get_cstring(ds);
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 831a8a5bf6c..e8fba38f793 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -92,6 +92,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
 	style->paneltitle.uifont_id= UIFONT_DEFAULT;
 	style->paneltitle.points= 13;
 	style->paneltitle.kerning= 0.0;
+	style->paneltitle.overlap= 0;
 	style->paneltitle.shadow= 5;
 	style->paneltitle.shadx= 2;
 	style->paneltitle.shady= -2;
@@ -101,6 +102,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
 	style->grouplabel.uifont_id= UIFONT_DEFAULT;
 	style->grouplabel.points= 12;
 	style->grouplabel.kerning= 0.0;
+	style->grouplabel.overlap= 0;
 	style->grouplabel.shadow= 3;
 	style->grouplabel.shadx= 1;
 	style->grouplabel.shady= -1;
@@ -109,6 +111,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
 	style->widgetlabel.uifont_id= UIFONT_DEFAULT;
 	style->widgetlabel.points= 11;
 	style->widgetlabel.kerning= 0.0;
+	style->widgetlabel.overlap= 0;
 	style->widgetlabel.shadow= 3;
 	style->widgetlabel.shadx= 1;
 	style->widgetlabel.shady= -1;
@@ -145,22 +148,6 @@ static uiFont *uifont_to_blfont(int id)
 
 /* *************** draw ************************ */
 
-static void ui_font_shadow_draw(uiFontStyle *fs, int x, int y, char *str)
-{
-	float color[4];
-	
-	glGetFloatv(GL_CURRENT_COLOR, color);
-	
-	glColor4f(fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha);
-	
-	BLF_blur(fs->shadow);
-	BLF_position(x+fs->shadx, y+fs->shady, 0.0f);
-	BLF_draw(str);
-	BLF_blur(0);
-	
-	glColor4fv(color);
-}
-
 void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
 {
 	float height;
@@ -179,14 +166,23 @@ void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
 	/* clip is very strict, so we give it some space */
 	BLF_clipping(rect->xmin-1, rect->ymin-4, rect->xmax+1, rect->ymax+4);
 	BLF_enable(BLF_CLIPPING);
-	
-	if(fs->shadow) 
-		ui_font_shadow_draw(fs, rect->xmin+xofs, rect->ymin+yofs, str);
-	
 	BLF_position(rect->xmin+xofs, rect->ymin+yofs, 0.0f);
-	BLF_draw(str);
 
+	if (fs->shadow) {
+		BLF_enable(BLF_SHADOW);
+		BLF_shadow(fs->shadow, fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha);
+		BLF_shadow_offset(fs->shadx, fs->shady);
+	}
+
+	if (fs->overlap)
+		BLF_enable(BLF_OVERLAP_CHAR);
+
+	BLF_draw(str);
 	BLF_disable(BLF_CLIPPING);
+	if (fs->shadow)
+		BLF_disable(BLF_SHADOW);
+	if (fs->overlap)
+		BLF_disable(BLF_OVERLAP_CHAR);
 }
 
 /* ************** helpers ************************ */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 15c0619e4e1..8f1d57b28ed 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_templates.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -27,9 +27,14 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
 #include "BLI_string.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
+#include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_utildefines.h"
 
@@ -43,6 +48,7 @@
 
 #include "UI_interface.h"
 #include "UI_resources.h"
+#include "interface_intern.h"
 
 void ui_template_fix_linking()
 {
@@ -58,107 +64,55 @@ void uiTemplateHeader(uiLayout *layout, bContext *C)
 	ED_area_header_standardbuttons(C, block, 0);
 }
 
-/******************* Header ID Template ************************/
+/********************** Search Callbacks *************************/
 
 typedef struct TemplateID {
 	PointerRNA ptr;
 	PropertyRNA *prop;
 
-	int flag;
-	short browse;
-
-	char newop[256];
-	char openop[256];
-	char unlinkop[256];
-	
-	short idtype;
+	ListBase *idlb;
 } TemplateID;
 
-static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
+/* Search browse menu, assign  */
+static void id_search_call_cb(struct bContext *C, void *arg_template, void *item)
 {
-	TemplateID *template= (TemplateID*)arg_litem;
-	PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-	ID *id= idptr.data;
-	int event= GET_INT_FROM_POINTER(arg_event);
-	
-	if(event == UI_ID_BROWSE && template->browse == 32767)
-		event= UI_ID_ADD_NEW;
-	else if(event == UI_ID_BROWSE && template->browse == 32766)
-		event= UI_ID_OPEN;
+	TemplateID *template= (TemplateID*)arg_template;
 
-	switch(event) {
-		case UI_ID_BROWSE:
-			printf("warning, id browse shouldnt come here\n");
-			break;
-		case UI_ID_DELETE:
-			memset(&idptr, 0, sizeof(idptr));
-			RNA_property_pointer_set(&template->ptr, template->prop, idptr);
-			RNA_property_update(C, &template->ptr, template->prop);
-			break;
-		case UI_ID_FAKE_USER:
-			if(id) {
-				if(id->flag & LIB_FAKEUSER) id->us++;
-				else id->us--;
-			}
-			else return;
-			break;
-		case UI_ID_PIN:
-			break;
-		case UI_ID_ADD_NEW:
-			WM_operator_name_call(C, template->newop, WM_OP_INVOKE_REGION_WIN, NULL);
-			break;
-		case UI_ID_OPEN:
-			WM_operator_name_call(C, template->openop, WM_OP_INVOKE_REGION_WIN, NULL);
-			break;
-#if 0
-		case UI_ID_ALONE:
-			if(!id || id->us < 1)
-				return;
-			break;
-		case UI_ID_LOCAL:
-			if(!id || id->us < 1)
-				return;
-			break;
-		case UI_ID_AUTO_NAME:
-			break;
-#endif
-	}
-}
-
-/* ID Search browse menu, assign  */
-static void id_search_call_cb(struct bContext *C, void *arg_litem, void *item)
-{
+	/* ID */
 	if(item) {
-		TemplateID *template= (TemplateID*)arg_litem;
-		PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
+		PointerRNA idptr;
 
 		RNA_id_pointer_create(item, &idptr);
 		RNA_property_pointer_set(&template->ptr, template->prop, idptr);
 		RNA_property_update(C, &template->ptr, template->prop);
-	}	
+	}
 }
 
 /* ID Search browse menu, do the search */
-static void id_search_cb(const struct bContext *C, void *arg_litem, char *str, uiSearchItems *items)
+static void id_search_cb(const struct bContext *C, void *arg_template, char *str, uiSearchItems *items)
 {
-	TemplateID *template= (TemplateID*)arg_litem;
-	ListBase *lb= wich_libbase(CTX_data_main(C), template->idtype);
+	TemplateID *template= (TemplateID*)arg_template;
+	Scene *scene= CTX_data_scene(C);
+	ListBase *lb= template->idlb;
 	ID *id;
-	
+	int iconid;
+
+	/* ID listbase */
 	for(id= lb->first; id; id= id->next) {
-		
-		if(BLI_strcasestr(id->name+2, str)) {
-			if(0==uiSearchItemAdd(items, id->name+2, id))
+		iconid= ui_id_icon_get(scene, id);
+
+		if(BLI_strcasestr(id->name+2, str))
+			if(!uiSearchItemAdd(items, id->name+2, id, iconid))
 				break;
-		}
 	}
 }
 
 /* ID Search browse menu, open */
-static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
+static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem)
 {
 	static char search[256];
 	static TemplateID template;
+	PointerRNA idptr;
 	wmEvent event;
 	wmWindow *win= CTX_wm_window(C);
 	uiBlock *block;
@@ -169,6 +123,9 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
 	/* arg_litem is malloced, can be freed by parent button */
 	template= *((TemplateID*)arg_litem);
 	
+	/* get active id for showing first item */
+	idptr= RNA_property_pointer_get(&template.ptr, template.prop);
+
 	block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
 	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
 	
@@ -176,7 +133,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
 	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
 	
 	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
-	uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb);
+	uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
 	
 	uiBoundsBlock(block, 6);
 	uiBlockSetDirection(block, UI_DOWN);	
@@ -192,47 +149,73 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
 	return block;
 }
 
-/* ****************** */
+/************************ ID Template ***************************/
 
+static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
+{
+	TemplateID *template= (TemplateID*)arg_litem;
+	PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
+	ID *id= idptr.data;
+	int event= GET_INT_FROM_POINTER(arg_event);
+	
+	switch(event) {
+		case UI_ID_BROWSE:
+		case UI_ID_PIN:
+			printf("warning, id event %d shouldnt come here\n", event);
+			break;
+		case UI_ID_OPEN:
+		case UI_ID_ADD_NEW:
+			if(template->idlb->last) {
+				RNA_id_pointer_create(template->idlb->last, &idptr);
+				RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+				RNA_property_update(C, &template->ptr, template->prop);
+			}
+			break;
+		case UI_ID_DELETE:
+			memset(&idptr, 0, sizeof(idptr));
+			RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+			RNA_property_update(C, &template->ptr, template->prop);
+			break;
+		case UI_ID_FAKE_USER:
+			if(id) {
+				if(id->flag & LIB_FAKEUSER) id->us++;
+				else id->us--;
+			}
+			else return;
+			break;
+#if 0
+		case UI_ID_ALONE:
+			if(!id || id->us < 1)
+				return;
+			break;
+		case UI_ID_LOCAL:
+			if(!id || id->us < 1)
+				return;
+			break;
+		case UI_ID_AUTO_NAME:
+			break;
+#endif
+	}
+}
 
-static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type)
+static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop)
 {
 	uiBut *but;
 	PointerRNA idptr;
 	ListBase *lb;
 
 	idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-	lb= wich_libbase(CTX_data_main(C), template->idtype);
+	lb= template->idlb;
+
+	uiBlockBeginAlign(block);
 
 	if(idptr.type)
 		type= idptr.type;
 	if(type)
 		uiDefIconBut(block, LABEL, 0, RNA_struct_ui_icon(type), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
-	uiBlockBeginAlign(block);
-	if(template->flag & UI_ID_BROWSE) {
-		/*
-		char *extrastr, *str;
-		
-		if((template->flag & UI_ID_ADD_NEW) && (template->flag & UI_ID_OPEN))
-			extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
-		else if(template->flag & UI_ID_ADD_NEW)
-			extrastr= "ADD NEW %x 32767";
-		else if(template->flag & UI_ID_OPEN)
-			extrastr= "OPEN NEW %x 32766";
-		else
-			extrastr= NULL;
-
-		duptemplate= MEM_dupallocN(template);
-		IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse);
-
-		but= uiDefButS(block, MENU, 0, str, 0, 0, UI_UNIT_X, UI_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new");
-		uiButSetNFunc(but, template_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE));
-	
-		MEM_freeN(str);
-		*/
-		uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Browse ID data");
-	}
+	if(flag & UI_ID_BROWSE)
+		uiDefBlockButN(block, search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Browse ID data");
 
 	/* text button with name */
 	if(idptr.data) {
@@ -244,11 +227,12 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
 		uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
 	}
 	
-	if(template->flag & UI_ID_ADD_NEW) {
+	if(flag & UI_ID_ADD_NEW) {
 		int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
 		
-		if(template->newop[0]) {
-			but= uiDefIconTextButO(block, BUT, template->newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+		if(newop) {
+			but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+			uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
 		}
 		else {
 			but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
@@ -257,9 +241,9 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
 	}
 	
 	/* delete button */
-	if(idptr.data && (template->flag & UI_ID_DELETE)) {
-		if(template->unlinkop[0]) {
-			but= uiDefIconButO(block, BUT, template->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+	if(idptr.data && (flag & UI_ID_DELETE)) {
+		if(unlinkop) {
+			but= uiDefIconButO(block, BUT, unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
 		}
 		else {
 			but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
@@ -270,12 +254,13 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
 	uiBlockEndAlign(block);
 }
 
-void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *unlinkop)
 {
 	TemplateID *template;
 	uiBlock *block;
 	PropertyRNA *prop;
 	StructRNA *type;
+	int flag;
 
 	if(!ptr->data)
 		return;
@@ -290,26 +275,19 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
 	template= MEM_callocN(sizeof(TemplateID), "TemplateID");
 	template->ptr= *ptr;
 	template->prop= prop;
-	template->flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
 
-	if(newop) {
-		template->flag |= UI_ID_ADD_NEW;
-		BLI_strncpy(template->newop, newop, sizeof(template->newop));
-	}
-	if(openop) {
-		template->flag |= UI_ID_OPEN;
-		BLI_strncpy(template->openop, openop, sizeof(template->openop));
-	}
-	if(unlinkop)
-		BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop));
+	flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
+
+	if(newop)
+		flag |= UI_ID_ADD_NEW;
 
 	type= RNA_property_pointer_type(ptr, prop);
-	template->idtype = RNA_type_to_ID_code(type);
+	template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
 
-	if(template->idtype) {
+	if(template->idlb) {
 		uiLayoutRow(layout, 1);
 		block= uiLayoutGetBlock(layout);
-		template_header_ID(C, block, template, type);
+		template_ID(C, block, template, type, flag, newop, unlinkop);
 	}
 
 	MEM_freeN(template);
@@ -362,6 +340,15 @@ static void modifiers_del(bContext *C, void *ob_v, void *md_v)
 	BKE_reports_clear(&reports);
 }
 
+static void modifiers_activate(bContext *C, void *ob_v, void *md_v)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= ob_v;
+
+	WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+
 static void modifiers_moveUp(bContext *C, void *ob_v, void *md_v)
 {
 	Scene *scene= CTX_data_scene(C);
@@ -555,7 +542,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
 		uiBlockSetEmboss(block, UI_EMBOSSN);
 		uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, 0, ICON_TRIA_RIGHT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
 	}
-
+	
+	/* modifier-type icon */
+	uiDefIconBut(block, BUT, 0, RNA_struct_ui_icon(ptr.type), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Current Modifier Type");
+	
 	uiBlockSetEmboss(block, UI_EMBOSS);
 	
 	if (isVirtual) {
@@ -566,14 +556,16 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
 		uiButSetFunc(but, modifiers_convertToReal, ob, md);
 	} else {
 		uiBlockBeginAlign(block);
-		uiDefBut(block, TEX, 0, "", 0, 0, buttonWidth-60, UI_UNIT_Y, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
+		uiDefBut(block, TEX, 0, "", 0, 0, buttonWidth-40, UI_UNIT_Y, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
 
 		/* Softbody not allowed in this situation, enforce! */
 		if (((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
 			uiDefIconButBitI(block, TOG, eModifierMode_Render, 0, ICON_SCENE, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
 			but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, 0, ICON_VIEW3D, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
+			uiButSetFunc(but, modifiers_activate, ob, md);
 			if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
-				uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+				but= uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+				uiButSetFunc(but, modifiers_activate, ob, md);
 			}
 		}
 		uiBlockEndAlign(block);
@@ -1490,3 +1482,264 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
 		}
 	}
 }
+
+
+/************************* List Template **************************/
+
+ListBase uiTemplateList(uiLayout *layout, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int columns, int compact)
+{
+	CollectionPointerLink *link;
+	PropertyRNA *prop= NULL, *activeprop;
+	PropertyType type, activetype;
+	uiLayout *box, *row, *col;
+	uiBlock *block;
+	uiBut *but;
+	Panel *pa;
+	ListBase lb;
+	char *name, str[32];
+	int i= 0, activei= 0, len, items, found, min, max;
+
+	lb.first= lb.last= NULL;
+	
+	/* validate arguments */
+	block= uiLayoutGetBlock(layout);
+	pa= block->panel;
+
+	if(!pa) {
+		printf("uiTemplateList: only works inside a panel.\n");
+		return lb;
+	}
+
+	if(!activeptr->data)
+		return lb;
+	
+	if(ptr->data) {
+		prop= RNA_struct_find_property(ptr, propname);
+		if(!prop) {
+			printf("uiTemplateList: property not found: %s\n", propname);
+			return lb;
+		}
+	}
+
+	activeprop= RNA_struct_find_property(activeptr, activepropname);
+	if(!activeprop) {
+		printf("uiTemplateList: property not found: %s\n", activepropname);
+		return lb;
+	}
+
+	if(prop) {
+		type= RNA_property_type(prop);
+		if(type != PROP_COLLECTION) {
+			printf("uiTemplateList: expected collection property.\n");
+			return lb;
+		}
+	}
+
+	activetype= RNA_property_type(activeprop);
+	if(activetype != PROP_INT) {
+		printf("uiTemplateList: expected integer property.\n");
+		return lb;
+	}
+
+	/* get active data */
+	activei= RNA_property_int_get(activeptr, activeprop);
+
+	if(compact) {
+		/* compact layout */
+		found= 0;
+
+		row= uiLayoutRow(layout, 1);
+
+		if(ptr->data && prop) {
+			/* create list items */
+			RNA_PROP_BEGIN(ptr, itemptr, prop) {
+				found= (activei == i);
+
+				if(found) {
+					/* create button */
+					name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+					if(name) {
+						uiItemL(row, name, RNA_struct_ui_icon(itemptr.type));
+						MEM_freeN(name);
+					}
+
+					/* add to list to return */
+					link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+					link->ptr= itemptr;
+					BLI_addtail(&lb, link);
+				}
+
+				i++;
+			}
+			RNA_PROP_END;
+		}
+
+		/* if not found, add in dummy button */
+		if(i == 0)
+			uiItemL(row, "", 0);
+
+		/* next/prev button */
+		sprintf(str, "%d :", i);
+		but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activepropname, 0, 0, 0, 0, 0, "");
+		if(i == 0)
+			uiButSetFlag(but, UI_BUT_DISABLED);
+	}
+	else {
+		/* default rows/columns */
+		if(rows == 0)
+			rows= 5;
+		if(columns == 0)
+			columns= 1;
+
+		/* layout */
+		box= uiLayoutBox(layout);
+		row= uiLayoutRow(box, 0);
+		col = uiLayoutColumn(row, 1);
+
+		uiBlockSetEmboss(block, UI_EMBOSSN);
+
+		/* init numbers */
+		RNA_property_int_range(activeptr, activeprop, &min, &max);
+
+		len= max - min + 1;
+		items= rows*columns;
+
+		pa->list_scroll= MIN2(pa->list_scroll, len-items);
+		pa->list_scroll= MAX2(pa->list_scroll, 0);
+
+		if(ptr->data && prop) {
+			/* create list items */
+			RNA_PROP_BEGIN(ptr, itemptr, prop) {
+				if(i >= pa->list_scroll && ilist_scroll+items) {
+					name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+					if(name) {
+						/* create button */
+						but= uiDefIconTextButR(block, ROW, 0, RNA_struct_ui_icon(itemptr.type), name, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+						uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
+
+						MEM_freeN(name);
+					}
+
+					/* add to list to return */
+					link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+					link->ptr= itemptr;
+					BLI_addtail(&lb, link);
+				}
+
+				i++;
+			}
+			RNA_PROP_END;
+		}
+
+		/* add dummy buttons to fill space */
+		while(i < pa->list_scroll+items) {
+			if(i >= pa->list_scroll)
+				uiItemL(col, "", 0);
+			i++;
+		}
+
+		uiBlockSetEmboss(block, UI_EMBOSS);
+
+		/* add scrollbar */
+		if(len > items) {
+			col= uiLayoutColumn(row, 0);
+			uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &pa->list_scroll, 0, len-items, items, 0, "");
+		}
+	}
+
+	/* return items in list */
+	return lb;
+}
+
+/************************* Operator Search Template **************************/
+
+static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+	wmOperatorType *ot= arg2;
+	
+	if(ot)
+		WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+	wmOperatorType *ot = WM_operatortype_first();
+	
+	for(; ot; ot= ot->next) {
+		
+		if(BLI_strcasestr(ot->name, str)) {
+			if(ot->poll==NULL || ot->poll((bContext *)C)) {
+				char name[256];
+				int len= strlen(ot->name);
+				
+				/* display name for menu, can hold hotkey */
+				BLI_strncpy(name, ot->name, 256);
+				
+				/* check for hotkey */
+				if(len < 256-6) {
+					if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
+						name[len]= '|';
+				}
+				
+				if(0==uiSearchItemAdd(items, name, ot, 0))
+					break;
+			}
+		}
+	}
+}
+
+void uiTemplateOperatorSearch(uiLayout *layout)
+{
+	uiBlock *block;
+	uiBut *but;
+	static char search[256]= "";
+		
+	block= uiLayoutGetBlock(layout);
+	uiBlockSetCurLayout(block, layout);
+
+	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, "");
+	uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
+}
+
+/************************* Running Jobs Template **************************/
+
+#define B_STOPRENDER	1
+#define B_STOPCAST		2
+#define B_STOPANIM		3
+
+static void do_running_jobs(bContext *C, void *arg, int event)
+{
+	switch(event) {
+		case B_STOPRENDER:
+			G.afbreek= 1;
+			break;
+		case B_STOPCAST:
+			WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
+			break;
+		case B_STOPANIM:
+			ED_screen_animation_timer(C, 0, 0);
+			break;
+	}
+}
+
+void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
+{
+	bScreen *screen= CTX_wm_screen(C);
+	Scene *scene= CTX_data_scene(C);
+	wmWindowManager *wm= CTX_wm_manager(C);
+	uiBlock *block;
+
+	block= uiLayoutGetBlock(layout);
+	uiBlockSetCurLayout(block, layout);
+
+	uiBlockSetHandleFunc(block, do_running_jobs, NULL);
+
+	if(WM_jobs_test(wm, scene))
+		uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", 0,0,75,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
+	if(WM_jobs_test(wm, screen))
+		uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
+	if(screen->animtimer)
+		uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
+}
+
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index a75a3402774..eb79848d7d2 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -43,6 +43,7 @@
 #include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_idprop.h"
+#include "BKE_icons.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_texture.h"
@@ -110,7 +111,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
 			but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
 			break;
 		case PROP_STRING:
-			but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+			if(icon && name && strcmp(name, "") == 0)
+				but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+			else if(icon)
+				but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+			else
+				but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
 			break;
 		case PROP_POINTER: {
 			PointerRNA pptr;
@@ -120,6 +126,8 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
 			if(!pptr.type)
 				pptr.type= RNA_property_pointer_type(ptr, prop);
 			icon= RNA_struct_ui_icon(pptr.type);
+			if(icon == ICON_DOT)
+				icon= 0;
 
 			but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
 			break;
@@ -139,69 +147,39 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
 	return but;
 }
 
-void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr)
+void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int columns)
 {
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *prop;
-	uiLayout *split;
+	uiLayout *split, *col;
 	char *name;
 
 	uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0);
 
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		prop= iter.ptr.data;
-
+	RNA_STRUCT_BEGIN(ptr, prop) {
 		if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
 			continue;
 
-		split = uiLayoutSplit(layout, 0.5f);
-
 		name= (char*)RNA_property_ui_name(prop);
 
-		uiItemL(uiLayoutColumn(split, 0), name, 0);
-		uiItemFullR(uiLayoutColumn(split, 0), "", 0, ptr, prop, -1, 0, 0, 0, 0);
-	}
+		if(columns == 1) {
+			col= uiLayoutColumn(layout, 1);
+			uiItemL(col, name, 0);
+		}
+		else if(columns == 2) {
+			split = uiLayoutSplit(layout, 0.5f);
 
-	RNA_property_collection_end(&iter);
-}
+			uiItemL(uiLayoutColumn(split, 0), name, 0);
+			col= uiLayoutColumn(split, 0);
+		}
 
-/* temp call, single collumn, test for toolbar only */
-void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr)
-{
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *prop;
-	uiLayout *col;
-	char *name;
-	
-	uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0);
-	
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-	
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		prop= iter.ptr.data;
-		
-		if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
-			continue;
-		
-		name= (char*)RNA_property_ui_name(prop);
-		col= uiLayoutColumn(layout, 1);
-		uiItemL(col, name, 0);
-		
 		/* temp hack to show normal button for spin/screw */
 		if(strcmp(name, "Axis")==0) {
-			uiDefButR(uiLayoutGetBlock(layout), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
+			uiDefButR(uiLayoutGetBlock(col), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
 		}
 		else uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0, 0, 0);
 	}
-	
-	RNA_property_collection_end(&iter);
+	RNA_STRUCT_END;
 }
 
-
 /***************************** ID Utilities *******************************/
 /* note, C code version, will be replaced with version in interface_templates.c */
 
@@ -304,9 +282,25 @@ static void id_search_cb(const struct bContext *C, void *arg_params, char *str,
 	ID *id;
 	
 	for(id= params->lb->first; id; id= id->next) {
+		int iconid= 0;
+		
+		
+		/* icon */
+		switch(GS(id->name))
+		{
+			case ID_MA: /* fall through */
+			case ID_TE: /* fall through */
+			case ID_IM: /* fall through */
+			case ID_WO: /* fall through */
+			case ID_LA: /* fall through */
+				iconid= BKE_icon_getid(id);
+				break;
+			default:
+				break;
+		}
 		
 		if(BLI_strcasestr(id->name+2, str)) {
-			if(0==uiSearchItemAdd(items, id->name+2, id))
+			if(0==uiSearchItemAdd(items, id->name+2, id, iconid))
 				break;
 		}
 	}
@@ -333,7 +327,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_params)
 	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
 	
 	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
-	uiButSetSearchFunc(but, id_search_cb, ¶ms, id_search_call_cb);
+	uiButSetSearchFunc(but, id_search_cb, ¶ms, id_search_call_cb, NULL);
 	
 	uiBoundsBlock(block, 6);
 	uiBlockSetDirection(block, UI_DOWN);	
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 14df9026078..ed2d00cb00d 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -102,6 +102,7 @@ typedef struct uiWidgetBase {
 	float inner_uv[64][2];
 	
 	short inner, outline, emboss; /* set on/off */
+	short shadedir;
 	
 	uiWidgetTrias tria1;
 	uiWidgetTrias tria2;
@@ -199,6 +200,7 @@ static void widget_init(uiWidgetBase *wtb)
 	wtb->inner= 1;
 	wtb->outline= 1;
 	wtb->emboss= 1;
+	wtb->shadedir= 1;
 }
 
 /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
@@ -583,7 +585,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
 			glShadeModel(GL_SMOOTH);
 			glBegin(GL_POLYGON);
 			for(a=0; atotvert; a++) {
-				round_box_shade_col4(col1, col2, wtb->inner_uv[a][1]);
+				round_box_shade_col4(col1, col2, wtb->inner_uv[a][wtb->shadedir]);
 				glVertex2fv(wtb->inner_v[a]);
 			}
 			glEnd();
@@ -1026,7 +1028,7 @@ static struct uiWidgetColors wcol_menu_back= {
 	{0, 0, 0, 255},
 	{25, 25, 25, 230},
 	{45, 45, 45, 230},
-	{255, 255, 255, 255},
+	{100, 100, 100, 255},
 	
 	{255, 255, 255, 255},
 	{255, 255, 255, 255},
@@ -1088,6 +1090,32 @@ static struct uiWidgetColors wcol_box= {
 	0, 0
 };
 
+static struct uiWidgetColors wcol_toggle= {
+	{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
+};
+
+static struct uiWidgetColors wcol_scroll= {
+	{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, -20
+};
+
 /* free wcol struct to play with */
 static struct uiWidgetColors wcol_tmp= {
 	{0, 0, 0, 255},
@@ -1109,9 +1137,10 @@ void ui_widget_color_init(ThemeUI *tui)
 
 	tui->wcol_regular= wcol_regular;
 	tui->wcol_tool= wcol_tool;
-	tui->wcol_radio= wcol_radio;
 	tui->wcol_text= wcol_text;
+	tui->wcol_radio= wcol_radio;
 	tui->wcol_option= wcol_option;
+	tui->wcol_toggle= wcol_toggle;
 	tui->wcol_num= wcol_num;
 	tui->wcol_numslider= wcol_numslider;
 	tui->wcol_menu= wcol_menu;
@@ -1119,6 +1148,7 @@ void ui_widget_color_init(ThemeUI *tui)
 	tui->wcol_menu_back= wcol_menu_back;
 	tui->wcol_menu_item= wcol_menu_item;
 	tui->wcol_box= wcol_box;
+	tui->wcol_scroll= wcol_scroll;
 }
 
 /* ************ button callbacks, state ***************** */
@@ -1602,6 +1632,75 @@ void ui_draw_link_bezier(rcti *rect)
 	}
 }
 
+static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+	uiWidgetBase wtb;
+	rcti rect1;
+	double value;
+	char inner[3];
+	float fac, size, rad;
+	int horizontal;
+
+	/* determine horizontal/vertical */
+	horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin);
+
+	if(horizontal)
+		rad= 0.5f*(rect->ymax - rect->ymin);
+	else
+		rad= 0.5f*(rect->xmax - rect->xmin);
+
+	widget_init(&wtb);
+	wtb.shadedir= (horizontal)? 1: 0;
+
+	/* draw back part, colors swapped and shading inverted */
+	VECCOPY(inner, wcol->inner);
+	VECCOPY(wcol->inner, wcol->item);
+	if(horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	if(state & UI_SELECT)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	
+	round_box_edges(&wtb, roundboxalign, rect, rad); /* XXX vertical gradient is wrong */
+	widgetbase_draw(&wtb, wcol);
+
+	VECCOPY(wcol->inner, inner);
+	if(horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	if(state & UI_SELECT)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	
+	/* front part */
+	value= ui_get_but_val(but);
+
+	size= (but->softmax + but->a1 - but->softmin);
+	size= MAX2(size, 2);
+	
+	/* position */
+	rect1= *rect;
+
+	if(horizontal) {
+		fac= (rect->xmax - rect->xmin)/(size);
+		rect1.xmin= rect1.xmin + ceil(fac*(value - but->softmin));
+		rect1.xmax= rect1.xmin + ceil(fac*(but->a1 - but->softmin));
+	}
+	else {
+		fac= (rect->ymax - rect->ymin)/(size);
+		rect1.ymax= rect1.ymax - ceil(fac*(value - but->softmin));
+		rect1.ymin= rect1.ymax - ceil(fac*(but->a1 - but->softmin));
+	}
+
+	/* draw */
+	wtb.emboss= 0; /* only emboss once */
+
+	if(!horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+
+	round_box_edges(&wtb, roundboxalign, &rect1, rad); /* XXX vertical gradient is wrong */
+	widgetbase_draw(&wtb, wcol);
+
+	if(!horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+}
 
 static void widget_link(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
@@ -1896,12 +1995,16 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 	wt.text= widget_draw_text_icon;
 	
 	switch(type) {
+		case UI_WTYPE_REGULAR:
+			break;
+
 		case UI_WTYPE_LABEL:
 			wt.draw= NULL;
 			wt.state= widget_state_label;
 			break;
 			
 		case UI_WTYPE_TOGGLE:
+			wt.wcol_theme= &btheme->tui.wcol_toggle;
 			break;
 			
 		case UI_WTYPE_OPTION:
@@ -1914,7 +2017,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 			wt.wcol_theme= &btheme->tui.wcol_radio;
 			wt.draw= widget_radiobut;
 			break;
-			
+
 		case UI_WTYPE_NUMBER:
 			wt.wcol_theme= &btheme->tui.wcol_num;
 			wt.draw= widget_numbut;
@@ -1995,6 +2098,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 			
 		case UI_WTYPE_NORMAL:
 			break;
+
+		case UI_WTYPE_SCROLL:
+			wt.wcol_theme= &btheme->tui.wcol_scroll;
+			wt.custom= widget_scroll;
+			break;
 	}
 	
 	return &wt;
@@ -2089,6 +2197,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
 			case BUT:
 				wt= widget_type(UI_WTYPE_EXEC);
 				break;
+
 			case NUM:
 				wt= widget_type(UI_WTYPE_NUMBER);
 				break;
@@ -2184,9 +2293,13 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
 			case BUT_CURVE:
 				ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
 				break;
-				
+
+			case SCROLL:
+				wt= widget_type(UI_WTYPE_SCROLL);
+				break;
+
 			default:
-				wt= widget_type(UI_WTYPE_TOGGLE);
+				wt= widget_type(UI_WTYPE_REGULAR);
 		}
 	}
 	
@@ -2195,6 +2308,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
 		int roundboxalign, state;
 		
 		roundboxalign= widget_roundbox_set(but, rect);
+
 		state= but->flag;
 		if(but->editstr) state |= UI_TEXTINPUT;
 		
@@ -2242,7 +2356,7 @@ void ui_draw_search_back(uiStyle *style, uiBlock *block, rcti *rect)
 
 /* helper call to draw a menu item without button */
 /* state: UI_ACTIVE or 0 */
-void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
+void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state)
 {
 	uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM);
 	rcti _rect= *rect;
@@ -2256,6 +2370,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
 	
 	/* text location offset */
 	rect->xmin+=5;
+	if(iconid) rect->xmin+= ICON_HEIGHT;
 
 	/* cut string in 2 parts? */
 	cpoin= strchr(name, '|');
@@ -2278,5 +2393,12 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
 	/* restore rect, was messed with */
 	*rect= _rect;
 
+	if(iconid) {
+		int xs= rect->xmin+4;
+		int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2;
+		glEnable(GL_BLEND);
+		UI_icon_draw_aspect_blended(xs, ys, iconid, 1.2f, 0); /* XXX scale weak get from fstyle? */
+		glDisable(GL_BLEND);
+	}
 }
 
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 0a65718b708..f83dee23417 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1,5 +1,5 @@
 /**
- * $Id: resources.c 12755 2007-12-02 05:50:38Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 189898cc907..aa5aa65d300 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1,5 +1,5 @@
 /**
- * $Id: view2d.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -316,6 +316,12 @@ void UI_view2d_curRect_validate(View2D *v2d)
 	if (v2d->keepzoom & V2D_LOCKZOOM_Y)
 		height= winy;
 		
+	/* values used to divide, so make it safe */
+	if(width<1) width= 1;
+	if(height<1) height= 1;
+	if(winx<1) winx= 1;
+	if(winy<1) winy= 1;
+	
 	/* keepzoom (V2D_KEEPZOOM set), indicates that zoom level on each axis must not exceed limits 
 	 * NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
 	 */
diff --git a/source/blender/editors/mesh/Makefile b/source/blender/editors/mesh/Makefile
index 650771519cd..8ae40e1b957 100644
--- a/source/blender/editors/mesh/Makefile
+++ b/source/blender/editors/mesh/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/mesh/editdeform.c b/source/blender/editors/mesh/editdeform.c
deleted file mode 100644
index 3ccd4d56ece..00000000000
--- a/source/blender/editors/mesh/editdeform.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- * Creator-specific support for vertex deformation groups
- * Added: apply deform function (ton)
- */
-
-#include 
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_cloth_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_scene_types.h"
-#include "DNA_particle_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_editVert.h"
-
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.h"
-#include "BKE_deform.h"
-#include "BKE_displist.h"
-#include "BKE_global.h"
-#include "BKE_lattice.h"
-#include "BKE_mesh.h"
-#include "BKE_utildefines.h"
-
-#include "ED_mesh.h"
-#include "ED_view3d.h"
-#include "mesh_intern.h"
-
-/* XXX */
-static void BIF_undo_push() {}
-static void error() {}
-
-static Lattice *def_get_lattice(Object *ob)
-{
-	if(ob->type==OB_LATTICE) {
-		Lattice *lt= ob->data;
-		if(lt->editlatt)
-			return lt->editlatt;
-		return lt;
-	}
-	return NULL;
-}
-
-/* only in editmode */
-void sel_verts_defgroup (Object *obedit, int select)
-{
-	EditVert *eve;
-	Object *ob;
-	int i;
-	MDeformVert *dvert;
-
-	ob= obedit;
-
-	if (!ob)
-		return;
-
-	switch (ob->type){
-	case OB_MESH:
-	{
-		Mesh *me= ob->data;
-		EditMesh *em = BKE_mesh_get_editmesh(me);
-
-		for (eve=em->verts.first; eve; eve=eve->next){
-			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
-
-			if (dvert && dvert->totweight){
-				for (i=0; itotweight; i++){
-					if (dvert->dw[i].def_nr == (ob->actdef-1)){
-						if (select) eve->f |= SELECT;
-						else eve->f &= ~SELECT;
-						
-						break;
-					}
-				}
-			}
-		}
-		/* this has to be called, because this function operates on vertices only */
-		if(select) EM_select_flush(em);	// vertices to edges/faces
-		else EM_deselect_flush(em);
-
-		BKE_mesh_end_editmesh(me, em);
-	}
-		break;
-	case OB_LATTICE:
-	{
-		Lattice *lt= def_get_lattice(ob);
-		
-		if(lt->dvert) {
-			BPoint *bp;
-			int a, tot;
-			
-			dvert= lt->dvert;
-
-			tot= lt->pntsu*lt->pntsv*lt->pntsw;
-			for(a=0, bp= lt->def; atotweight; i++){
-					if (dvert->dw[i].def_nr == (ob->actdef-1)) {
-						if(select) bp->f1 |= SELECT;
-						else bp->f1 &= ~SELECT;
-						
-						break;
-					}
-				}
-			}
-		}
-	}
-		break;
-		
-	default:
-		break;
-	}
-}
-
-/* check if deform vertex has defgroup index */
-MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
-{
-	int i;
-	
-	if (!dv || defgroup<0)
-		return NULL;
-	
-	for (i=0; itotweight; i++){
-		if (dv->dw[i].def_nr == defgroup)
-			return dv->dw+i;
-	}
-	return NULL;
-}
-
-/* Ensures that mv has a deform weight entry for
-   the specified defweight group */
-/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
-MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
-{
-	MDeformWeight *newdw;
-
-	/* do this check always, this function is used to check for it */
-	if (!dv || defgroup<0)
-		return NULL;
-	
-	newdw = get_defweight (dv, defgroup);
-	if (newdw)
-		return newdw;
-	
-	newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
-	if (dv->dw){
-		memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
-		MEM_freeN (dv->dw);
-	}
-	dv->dw=newdw;
-	
-	dv->dw[dv->totweight].weight=0.0f;
-	dv->dw[dv->totweight].def_nr=defgroup;
-	/* Group index */
-	
-	dv->totweight++;
-
-	return dv->dw+(dv->totweight-1);
-}
-
-bDeformGroup *add_defgroup_name (Object *ob, char *name)
-{
-	bDeformGroup	*defgroup;
-	
-	if (!ob)
-		return NULL;
-	
-	defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup");
-
-	BLI_strncpy (defgroup->name, name, 32);
-
-	BLI_addtail(&ob->defbase, defgroup);
-	unique_vertexgroup_name(defgroup, ob);
-
-	ob->actdef = BLI_countlist(&ob->defbase);
-
-	return defgroup;
-}
-
-void add_defgroup (Object *ob) 
-{
-	add_defgroup_name (ob, "Group");
-}
-
-
-void duplicate_defgroup ( Object *ob )
-{
-	bDeformGroup *dg, *cdg;
-	char name[32], s[32];
-	MDeformWeight *org, *cpy;
-	MDeformVert *dvert, *dvert_array;
-	int i, idg, icdg, dvert_tot;
-
-	if (ob->type != OB_MESH && ob->type != OB_LATTICE)
-		return;
-
-	dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
-	if (!dg)
-		return;
-	
-	if (strstr(dg->name, "_copy")) {
-		BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */
-	} else {
-		BLI_snprintf (name, 32, "%s_copy", dg->name);
-		while (get_named_vertexgroup (ob, name)) {
-			if ((strlen (name) + 6) > 32) {
-				error ("Error: the name for the new group is > 32 characters");
-				return;
-			}
-			strcpy (s, name);
-			BLI_snprintf (name, 32, "%s_copy", s);
-		}
-	}		
-
-	cdg = copy_defgroup (dg);
-	strcpy (cdg->name, name);
-	unique_vertexgroup_name(cdg, ob);
-	
-	BLI_addtail (&ob->defbase, cdg);
-
-	idg = (ob->actdef-1);
-	ob->actdef = BLI_countlist (&ob->defbase);
-	icdg = (ob->actdef-1);
-
-	if(ob->type == OB_MESH) {
-		Mesh *me = get_mesh (ob);
-		dvert_array= me->dvert;
-		dvert_tot= me->totvert;
-	}
-	else if (ob->type == OB_LATTICE) {
-		Lattice *lt= (Lattice *)ob->data;
-		dvert_array= lt->dvert;
-		dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
-	}
-	
-	if (!dvert_array)
-		return;
-
-	for (i = 0; i < dvert_tot; i++) {
-		dvert = dvert_array+i;
-		org = get_defweight (dvert, idg);
-		if (org) {
-			float weight = org->weight;
-			/* verify_defweight re-allocs org so need to store the weight first */
-			cpy = verify_defweight (dvert, icdg);
-			cpy->weight = weight;
-		}
-	}
-}
-
-static void del_defgroup_update_users(Object *ob, int id)
-{
-	ExplodeModifierData *emd;
-	ModifierData *md;
-	ParticleSystem *psys;
-	ClothModifierData *clmd;
-	ClothSimSettings *clsim;
-	int a;
-
-	/* these cases don't use names to refer to vertex groups, so when
-	 * they get deleted the numbers get out of sync, this corrects that */
-
-	if(ob->soft) {
-		if(ob->soft->vertgroup == id)
-			ob->soft->vertgroup= 0;
-		else if(ob->soft->vertgroup > id)
-			ob->soft->vertgroup--;
-	}
-
-	for(md=ob->modifiers.first; md; md=md->next) {
-		if(md->type == eModifierType_Explode) {
-			emd= (ExplodeModifierData*)md;
-
-			if(emd->vgroup == id)
-				emd->vgroup= 0;
-			else if(emd->vgroup > id)
-				emd->vgroup--;
-		}
-		else if(md->type == eModifierType_Cloth) {
-			clmd= (ClothModifierData*)md;
-			clsim= clmd->sim_parms;
-
-			if(clsim) {
-				if(clsim->vgroup_mass == id)
-					clsim->vgroup_mass= 0;
-				else if(clsim->vgroup_mass > id)
-					clsim->vgroup_mass--;
-
-				if(clsim->vgroup_bend == id)
-					clsim->vgroup_bend= 0;
-				else if(clsim->vgroup_bend > id)
-					clsim->vgroup_bend--;
-
-				if(clsim->vgroup_struct == id)
-					clsim->vgroup_struct= 0;
-				else if(clsim->vgroup_struct > id)
-					clsim->vgroup_struct--;
-			}
-		}
-	}
-
-	for(psys=ob->particlesystem.first; psys; psys=psys->next) {
-		for(a=0; avgroup[a] == id)
-				psys->vgroup[a]= 0;
-			else if(psys->vgroup[a] > id)
-				psys->vgroup[a]--;
-	}
-}
-
-void del_defgroup_in_object_mode ( Object *ob )
-{
-	bDeformGroup *dg;
-	MDeformVert *dvert_array, *dvert;
-	
-	int i, e, dvert_tot;
-
-	if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE))
-		return;
-
-	if(ob->type == OB_MESH) {
-		Mesh *me = get_mesh (ob);
-		dvert_array= me->dvert;
-		dvert_tot= me->totvert;
-	}
-	else if (ob->type == OB_LATTICE) {
-		Lattice *lt= (Lattice *)ob->data;
-		dvert_array= lt->dvert;
-		dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
-	}
-	
-	dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
-	if (!dg)
-		return;
-	
-	if (dvert_array) {
-		for (i = 0; i < dvert_tot; i++) {
-			dvert = dvert_array + i;
-			if (dvert) {
-				if (get_defweight (dvert, (ob->actdef-1)))
-					remove_vert_defgroup (ob, dg, i);
-			}
-		}
-
-		for (i = 0; i < dvert_tot; i++) {
-			dvert = dvert_array+i;
-			if (dvert) {
-				for (e = 0; e < dvert->totweight; e++) {
-					if (dvert->dw[e].def_nr > (ob->actdef-1))
-						dvert->dw[e].def_nr--;
-				}
-			}
-		}
-	}
-
-	del_defgroup_update_users(ob, ob->actdef);
-
-	/* Update the active deform index if necessary */
-	if (ob->actdef == BLI_countlist(&ob->defbase))
-		ob->actdef--;
-  
-	/* Remove the group */
-	BLI_freelinkN (&ob->defbase, dg);
-}
-
-void del_defgroup (Object *ob)
-{
-	bDeformGroup	*defgroup;
-	int				i;
-
-	if (!ob)
-		return;
-
-	if (!ob->actdef)
-		return;
-
-	defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
-	if (!defgroup)
-		return;
-
-	/* Make sure that no verts are using this group */
-	remove_verts_defgroup(ob, 1);
-
-	/* Make sure that any verts with higher indices are adjusted accordingly */
-	if(ob->type==OB_MESH) {
-		Mesh *me= ob->data;
-		EditMesh *em = BKE_mesh_get_editmesh(me);
-		EditVert *eve;
-		MDeformVert *dvert;
-		
-		for (eve=em->verts.first; eve; eve=eve->next){
-			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
-
-			if (dvert)
-				for (i=0; itotweight; i++)
-					if (dvert->dw[i].def_nr > (ob->actdef-1))
-						dvert->dw[i].def_nr--;
-		}
-		BKE_mesh_end_editmesh(me, em);
-	}
-	else if(ob->type==OB_LATTICE) {
-		Lattice *lt= def_get_lattice(ob);
-		BPoint *bp;
-		MDeformVert *dvert= lt->dvert;
-		int a, tot;
-		
-		if (dvert) {
-			tot= lt->pntsu*lt->pntsv*lt->pntsw;
-			for(a=0, bp= lt->def; atotweight; i++){
-					if (dvert->dw[i].def_nr > (ob->actdef-1))
-						dvert->dw[i].def_nr--;
-				}
-			}
-		}
-	}
-
-	del_defgroup_update_users(ob, ob->actdef);
-
-	/* Update the active deform index if necessary */
-	if (ob->actdef==BLI_countlist(&ob->defbase))
-		ob->actdef--;
-	
-	/* Remove the group */
-	BLI_freelinkN (&ob->defbase, defgroup);
-	
-	/* remove all dverts */
-	if(ob->actdef==0) {
-		if(ob->type==OB_MESH) {
-			Mesh *me= ob->data;
-			CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
-			me->dvert= NULL;
-		}
-		else if(ob->type==OB_LATTICE) {
-			Lattice *lt= def_get_lattice(ob);
-			if (lt->dvert) {
-				MEM_freeN(lt->dvert);
-				lt->dvert= NULL;
-			}
-		}
-	}
-}
-
-void del_all_defgroups (Object *ob)
-{
-	/* Sanity check */
-	if (ob == NULL)
-		return;
-	
-	/* Remove all DVerts */
-	if (ob->type==OB_MESH) {
-		Mesh *me= ob->data;
-		CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
-		me->dvert= NULL;
-	}
-	else if(ob->type==OB_LATTICE) {
-		Lattice *lt= def_get_lattice(ob);
-		if (lt->dvert) {
-			MEM_freeN(lt->dvert);
-			lt->dvert= NULL;
-		}
-	}
-	
-	/* Remove all DefGroups */
-	BLI_freelistN(&ob->defbase);
-	
-	/* Fix counters/indices */
-	ob->actdef= 0;
-}
-
-void create_dverts(ID *id)
-{
-	/* create deform verts
-	 */
-
-	if( GS(id->name)==ID_ME) {
-		Mesh *me= (Mesh *)id;
-		me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
-	}
-	else if( GS(id->name)==ID_LT) {
-		Lattice *lt= (Lattice *)id;
-		lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
-	}
-}
-
-/* for mesh in object mode
-   lattice can be in editmode */
-void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
-{
-	/* This routine removes the vertex from the deform
-	 * group with number def_nr.
-	 *
-	 * This routine is meant to be fast, so it is the
-	 * responsibility of the calling routine to:
-	 *   a) test whether ob is non-NULL
-	 *   b) test whether ob is a mesh
-	 *   c) calculate def_nr
-	 */
-
-	MDeformWeight *newdw;
-	MDeformVert *dvert= NULL;
-	int i;
-
-	/* get the deform vertices corresponding to the
-	 * vertnum
-	 */
-	if(ob->type==OB_MESH) {
-		if( ((Mesh*)ob->data)->dvert )
-			dvert = ((Mesh*)ob->data)->dvert + vertnum;
-	}
-	else if(ob->type==OB_LATTICE) {
-		Lattice *lt= def_get_lattice(ob);
-		
-		if(lt->dvert)
-			dvert = lt->dvert + vertnum;
-	}
-	
-	if(dvert==NULL)
-		return;
-	
-	/* for all of the deform weights in the
-	 * deform vert
-	 */
-	for (i=dvert->totweight - 1 ; i>=0 ; i--){
-
-		/* if the def_nr is the same as the one
-		 * for our weight group then remove it
-		 * from this deform vert.
-		 */
-		if (dvert->dw[i].def_nr == def_nr) {
-			dvert->totweight--;
-        
-			/* if there are still other deform weights
-			 * attached to this vert then remove this
-			 * deform weight, and reshuffle the others
-			 */
-			if (dvert->totweight) {
-				newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), 
-									 "deformWeight");
-				if (dvert->dw){
-					memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
-					memcpy (newdw+i, dvert->dw+i+1, 
-							sizeof(MDeformWeight)*(dvert->totweight-i));
-					MEM_freeN (dvert->dw);
-				}
-				dvert->dw=newdw;
-			}
-			/* if there are no other deform weights
-			 * left then just remove the deform weight
-			 */
-			else {
-				MEM_freeN (dvert->dw);
-				dvert->dw = NULL;
-				break;
-			}
-		}
-	}
-
-}
-
-/* for Mesh in Object mode */
-/* allows editmode for Lattice */
-void add_vert_defnr (Object *ob, int def_nr, int vertnum, 
-                           float weight, int assignmode)
-{
-	/* add the vert to the deform group with the
-	 * specified number
-	 */
-	MDeformVert *dv= NULL;
-	MDeformWeight *newdw;
-	int	i;
-
-	/* get the vert */
-	if(ob->type==OB_MESH) {
-		if(((Mesh*)ob->data)->dvert)
-			dv = ((Mesh*)ob->data)->dvert + vertnum;
-	}
-	else if(ob->type==OB_LATTICE) {
-		Lattice *lt= def_get_lattice(ob);
-		
-		if(lt->dvert)
-			dv = lt->dvert + vertnum;
-	}
-	
-	if(dv==NULL)
-		return;
-	
-	/* Lets first check to see if this vert is
-	 * already in the weight group -- if so
-	 * lets update it
-	 */
-	for (i=0; itotweight; i++){
-		
-		/* if this weight cooresponds to the
-		 * deform group, then add it using
-		 * the assign mode provided
-		 */
-		if (dv->dw[i].def_nr == def_nr){
-			
-			switch (assignmode) {
-			case WEIGHT_REPLACE:
-				dv->dw[i].weight=weight;
-				break;
-			case WEIGHT_ADD:
-				dv->dw[i].weight+=weight;
-				if (dv->dw[i].weight >= 1.0)
-					dv->dw[i].weight = 1.0;
-				break;
-			case WEIGHT_SUBTRACT:
-				dv->dw[i].weight-=weight;
-				/* if the weight is zero or less then
-				 * remove the vert from the deform group
-				 */
-				if (dv->dw[i].weight <= 0.0)
-					remove_vert_def_nr(ob, def_nr, vertnum);
-				break;
-			}
-			return;
-		}
-	}
-
-	/* if the vert wasn't in the deform group then
-	 * we must take a different form of action ...
-	 */
-
-	switch (assignmode) {
-	case WEIGHT_SUBTRACT:
-		/* if we are subtracting then we don't
-		 * need to do anything
-		 */
-		return;
-
-	case WEIGHT_REPLACE:
-	case WEIGHT_ADD:
-		/* if we are doing an additive assignment, then
-		 * we need to create the deform weight
-		 */
-		newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), 
-							 "deformWeight");
-		if (dv->dw){
-			memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
-			MEM_freeN (dv->dw);
-		}
-		dv->dw=newdw;
-    
-		dv->dw[dv->totweight].weight=weight;
-		dv->dw[dv->totweight].def_nr=def_nr;
-    
-		dv->totweight++;
-		break;
-	}
-}
-
-/* called while not in editmode */
-void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, 
-                           float weight, int assignmode)
-{
-	/* add the vert to the deform group with the
-	 * specified assign mode
-	 */
-	int	def_nr;
-
-	/* get the deform group number, exit if
-	 * it can't be found
-	 */
-	def_nr = get_defgroup_num(ob, dg);
-	if (def_nr < 0) return;
-
-	/* if there's no deform verts then
-	 * create some
-	 */
-	if(ob->type==OB_MESH) {
-		if (!((Mesh*)ob->data)->dvert)
-			create_dverts(ob->data);
-	}
-	else if(ob->type==OB_LATTICE) {
-		if (!((Lattice*)ob->data)->dvert)
-			create_dverts(ob->data);
-	}
-
-	/* call another function to do the work
-	 */
-	add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
-}
-
-/* Only available in editmode */
-void assign_verts_defgroup (Object *obedit, float weight)
-{
-	Object *ob;
-	EditVert *eve;
-	bDeformGroup *dg, *eg;
-	MDeformWeight *newdw;
-	MDeformVert *dvert;
-	int	i, done;
-	
-// XXX	if(multires_level1_test()) return;
-
-	ob= obedit;
-
-	if (!ob)
-		return;
-
-	dg=BLI_findlink(&ob->defbase, ob->actdef-1);
-	if (!dg){
-		error ("No vertex group is active");
-		return;
-	}
-
-	switch (ob->type){
-	case OB_MESH:
-	{
-		Mesh *me= ob->data;
-		EditMesh *em = BKE_mesh_get_editmesh(me);
-
-		if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
-			EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT);
-
-		/* Go through the list of editverts and assign them */
-		for (eve=em->verts.first; eve; eve=eve->next){
-			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
-
-			if (dvert && (eve->f & 1)){
-				done=0;
-				/* See if this vert already has a reference to this group */
-				/*		If so: Change its weight */
-				done=0;
-				for (i=0; itotweight; i++){
-					eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
-					/* Find the actual group */
-					if (eg==dg){
-						dvert->dw[i].weight= weight;
-						done=1;
-						break;
-					}
-			 	}
-				/*		If not: Add the group and set its weight */
-				if (!done){
-					newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
-					if (dvert->dw){
-						memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
-						MEM_freeN (dvert->dw);
-					}
-					dvert->dw=newdw;
-
-					dvert->dw[dvert->totweight].weight= weight;
-					dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
-
-					dvert->totweight++;
-
-				}
-			}
-		}
-		BKE_mesh_end_editmesh(me, em);
-	}
-		break;
-	case OB_LATTICE:
-		{
-			Lattice *lt= def_get_lattice(ob);
-			BPoint *bp;
-			int a, tot;
-			
-			if(lt->dvert==NULL)
-				create_dverts(<->id);
-			
-			tot= lt->pntsu*lt->pntsv*lt->pntsw;
-			for(a=0, bp= lt->def; af1 & SELECT)
-					add_vert_defnr (ob, ob->actdef-1, a, weight, WEIGHT_REPLACE);
-			}
-		}
-		break;
-	default:
-		printf ("Assigning deformation groups to unknown object type\n");
-		break;
-	}
-
-}
-
-/* mesh object mode, lattice can be in editmode */
-void remove_vert_defgroup (Object *ob, bDeformGroup	*dg, int vertnum)
-{
-	/* This routine removes the vertex from the specified
-	 * deform group.
-	 */
-
-	int def_nr;
-
-	/* if the object is NULL abort
-	 */
-	if (!ob)
-		return;
-
-	/* get the deform number that cooresponds
-	 * to this deform group, and abort if it
-	 * can not be found.
-	 */
-	def_nr = get_defgroup_num(ob, dg);
-	if (def_nr < 0) return;
-
-	/* call another routine to do the work
-	 */
-	remove_vert_def_nr (ob, def_nr, vertnum);
-}
-
-/* for mesh in object mode lattice can be in editmode */
-static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
-{
-	MDeformVert *dvert= NULL;
-	int i;
-
-	/* get the deform vertices corresponding to the
-	 * vertnum
-	 */
-	if(ob->type==OB_MESH) {
-		if( ((Mesh*)ob->data)->dvert )
-			dvert = ((Mesh*)ob->data)->dvert + vertnum;
-	}
-	else if(ob->type==OB_LATTICE) {
-		Lattice *lt= def_get_lattice(ob);
-		
-		if(lt->dvert)
-			dvert = lt->dvert + vertnum;
-	}
-	
-	if(dvert==NULL)
-		return 0.0f;
-	
-	for(i=dvert->totweight-1 ; i>=0 ; i--)
-		if(dvert->dw[i].def_nr == def_nr)
-			return dvert->dw[i].weight;
-
-	return 0.0f;
-}
-
-/* mesh object mode, lattice can be in editmode */
-float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
-{
-	int def_nr;
-
-	if(!ob)
-		return 0.0f;
-
-	def_nr = get_defgroup_num(ob, dg);
-	if(def_nr < 0) return 0.0f;
-
-	return get_vert_def_nr (ob, def_nr, vertnum);
-}
-
-/* Only available in editmode */
-/* removes from active defgroup, if allverts==0 only selected vertices */
-void remove_verts_defgroup (Object *obedit, int allverts)
-{
-	Object *ob;
-	EditVert *eve;
-	MDeformVert *dvert;
-	MDeformWeight *newdw;
-	bDeformGroup *dg, *eg;
-	int	i;
-	
-// XXX	if(multires_level1_test()) return;
-
-	ob= obedit;
-
-	if (!ob)
-		return;
-
-	dg=BLI_findlink(&ob->defbase, ob->actdef-1);
-	if (!dg){
-		error ("No vertex group is active");
-		return;
-	}
-
-	switch (ob->type){
-	case OB_MESH:
-	{
-		Mesh *me= ob->data;
-		EditMesh *em = BKE_mesh_get_editmesh(me);
-
-		for (eve=em->verts.first; eve; eve=eve->next){
-			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
-		
-			if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
-				for (i=0; itotweight; i++){
-					/* Find group */
-					eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
-					if (eg == dg){
-						dvert->totweight--;
-						if (dvert->totweight){
-							newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
-							
-							if (dvert->dw){
-								memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
-								memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
-								MEM_freeN (dvert->dw);
-							}
-							dvert->dw=newdw;
-						}
-						else{
-							MEM_freeN (dvert->dw);
-							dvert->dw=NULL;
-							break;
-						}
-					}
-				}
-			}
-		}
-		BKE_mesh_end_editmesh(me, em);
-	}
-		break;
-	case OB_LATTICE:
-	{
-		Lattice *lt= def_get_lattice(ob);
-		
-		if(lt->dvert) {
-			BPoint *bp;
-			int a, tot= lt->pntsu*lt->pntsv*lt->pntsw;
-				
-			for(a=0, bp= lt->def; af1 & SELECT))
-					remove_vert_defgroup (ob, dg, a);
-			}
-		}
-	}
-		break;
-		
-	default:
-		printf ("Removing deformation groups from unknown object type\n");
-		break;
-	}
-}
-
-/* Only available in editmode */
-/* removes from all defgroup, if allverts==0 only selected vertices */
-void remove_verts_defgroups(Object *obedit, int allverts)
-{
-	Object *ob;
-	int actdef, defCount;
-	
-//  XXX	if (multires_level1_test()) return;
-
-	ob= obedit;
-	if (ob == NULL) return;
-	
-	actdef= ob->actdef;
-	defCount= BLI_countlist(&ob->defbase);
-	
-	if (defCount == 0) {
-		error("Object has no vertex groups");
-		return;
-	}
-	
-	/* To prevent code redundancy, we just use remove_verts_defgroup, but that
-	 * only operates on the active vgroup. So we iterate through all groups, by changing
-	 * active group index
-	 */
-	for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++)
-		remove_verts_defgroup(ob, allverts);
-		
-	ob->actdef= actdef;
-}
-
-void vertexgroup_select_by_name(Object *ob, char *name)
-{
-	bDeformGroup *curdef;
-	int actdef= 1;
-	
-	if(ob==NULL) return;
-	
-	for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
-		if (!strcmp(curdef->name, name)) {
-			ob->actdef= actdef;
-			return;
-		}
-	}
-	ob->actdef=0;	// this signals on painting to create a new one, if a bone in posemode is selected */
-}
-
-/* This function provides a shortcut for adding/removing verts from 
- * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes
- * and Lattices. (currently only restricted to those two)
- * It is only responsible for 
- */
-void vgroup_assign_with_menu(Scene *scene, Object *ob)
-{
-	VPaint *wp= scene->toolsettings->wpaint;
-	int defCount;
-	int mode= 0;
-	
-	/* prevent crashes */
-	if (wp==NULL || ob==NULL) return;
-	
-	defCount= BLI_countlist(&ob->defbase);
-	
-	/* give user choices of adding to current/new or removing from current */
-// XXX	if (defCount && ob->actdef)
-//		mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4");
-//	else
-//		mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
-	
-	/* handle choices */
-	switch (mode) {
-		case 1: /* add to new group */
-			add_defgroup(ob);
-			assign_verts_defgroup(ob, wp->brush->alpha);
-			BIF_undo_push("Assign to vertex group");
-			break;
-		case 2: /* add to current group */
-			assign_verts_defgroup(ob, wp->brush->alpha);
-			BIF_undo_push("Assign to vertex group");
-			break;
-		case 3:	/* remove from current group */
-			remove_verts_defgroup(ob, 0);
-			BIF_undo_push("Remove from vertex group");
-			break;
-		case 4: /* remove from all groups */
-			remove_verts_defgroups(ob, 0);
-			BIF_undo_push("Remove from all vertex groups");
-			break;
-	}
-}
-
-/* This function provides a shortcut for commonly used vertex group 
- * functions - change weight (not implemented), change active group, delete active group,
- * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now).
- */
-void vgroup_operation_with_menu(Object *ob)
-{
-	int defCount;
-	int mode= 0;
-	
-	/* prevent crashes and useless cases */
-	if (ob==NULL) return;
-	
-	defCount= BLI_countlist(&ob->defbase);
-	if (defCount == 0) return;
-	
-	/* give user choices of adding to current/new or removing from current */
-// XXX	if (ob->actdef)
-//		mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3");
-//	else
-//		mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3");
-	
-	/* handle choices */
-	switch (mode) {
-		case 1: /* change active group*/
-			{
-				char *menustr= NULL; // XXX get_vertexgroup_menustr(ob);
-				short nr;
-				
-				if (menustr) {
-// XXX					nr= pupmenu(menustr);
-					
-					if ((nr >= 1) && (nr <= defCount)) 
-						ob->actdef= nr;
-						
-					MEM_freeN(menustr);
-				}
-			}
-			break;
-		case 2: /* delete active group  */
-			{
-				del_defgroup(ob);
-				BIF_undo_push("Delete vertex group");
-			}
-			break;
-		case 3: /* delete all groups */
-			{
-				del_all_defgroups(ob);
-				BIF_undo_push("Delete all vertex groups");
-			}
-			break;
-	}
-}
-
-
diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c
index dd003d103d5..7f5201f4704 100644
--- a/source/blender/editors/mesh/editmesh.c
+++ b/source/blender/editors/mesh/editmesh.c
@@ -841,7 +841,7 @@ void make_editMesh(Scene *scene, Object *ob)
 	
 	em= me->edit_mesh;
 	
-	em->selectmode= scene->selectmode; // warning needs to be synced
+	em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
 	em->act_face = NULL;
 	em->totvert= tot= me->totvert;
 	em->totedge= me->totedge;
@@ -1556,7 +1556,7 @@ static int mesh_separate_material(Scene *scene, Base *editbase)
 		/* clear selection, we're going to use that to select material group */
 		EM_clear_flag_all(em, SELECT);
 		/* select the material */
-		editmesh_select_by_material(em, curr_mat);
+		EM_select_by_material(em, curr_mat);
 		/* and now separate */
 		if(0==mesh_separate_selected(scene, editbase)) {
 			BKE_mesh_end_editmesh(me, em);
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 57fb2c19c75..12138ee13d2 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -1276,7 +1276,7 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
 	Object *obedit= CTX_data_edit_object(C);
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d =CTX_wm_view3d(C);
-	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	RegionView3D *rv3d= ED_view3d_context_rv3d(C);
 	float *curs, mat[3][3], vmat[3][3], cmat[3][3], imat[3][3];
 	
 	Mat4One(primmat);
@@ -1295,9 +1295,9 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
 	/* center */
 	curs= give_cursor(scene, v3d);
 	VECCOPY(primmat[3], curs);
+	VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
 	Mat3Inv(imat, mat);
 	Mat3MulVecfl(imat, primmat[3]);
-	VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
 	
 	if(v3d) return v3d->grid;
 	return 1.0f;
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index a1f8b3251c8..70a0c6b82da 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -3242,7 +3242,7 @@ static int toggle_select_all_exec(bContext *C, wmOperator *op)
 void MESH_OT_select_all_toggle(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Select or Deselect All";
+	ot->name= "Select/Deselect All";
 	ot->idname= "MESH_OT_select_all_toggle";
 	
 	/* api callbacks */
@@ -3484,7 +3484,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
 	RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
 }
 
-void editmesh_select_by_material(EditMesh *em, int index) 
+void EM_select_by_material(EditMesh *em, int index) 
 {
 	EditFace *efa;
 	
@@ -3497,7 +3497,7 @@ void editmesh_select_by_material(EditMesh *em, int index)
 	EM_selectmode_flush(em);
 }
 
-void editmesh_deselect_by_material(EditMesh *em, int index) 
+void EM_deselect_by_material(EditMesh *em, int index) 
 {
 	EditFace *efa;
 	
@@ -3531,7 +3531,7 @@ static void mesh_selection_type(Scene *scene, EditMesh *em, int val)
 		
 		/* note, em stores selectmode to be able to pass it on everywhere without scene,
 		   this is only until all select modes and toolsettings are settled more */
-		scene->selectmode= em->selectmode;
+		scene->toolsettings->selectmode= em->selectmode;
 //		if (EM_texFaceCheck())
 	}
 }
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index b26fded4fb6..dc9c8c6b6d2 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -787,7 +787,7 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op)
 	Object *obedit= CTX_data_edit_object(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
-	RegionView3D *rv3d = CTX_wm_region_view3d(C);		
+	RegionView3D *rv3d = ED_view3d_context_rv3d(C);		
 		
 	int steps = RNA_int_get(op->ptr,"steps");
 	
@@ -949,7 +949,7 @@ static int spin_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	RegionView3D *rv3d= ED_view3d_context_rv3d(C);
 	
 	RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d));
 	RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[2]);
@@ -1056,7 +1056,7 @@ static int screw_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	RegionView3D *rv3d= ED_view3d_context_rv3d(C);
 	
 	RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d));
 	RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[1]);
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 83a4211dda1..22e3b4060a4 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -234,5 +234,14 @@ void MESH_OT_colors_mirror(struct wmOperatorType *ot);
 void MESH_OT_delete(struct wmOperatorType *ot);
 void MESH_OT_rip(struct wmOperatorType *ot);
 
+/* ******************* mesh_layers.c */
+
+void MESH_OT_uv_texture_add(struct wmOperatorType *ot);
+void MESH_OT_uv_texture_remove(struct wmOperatorType *ot);
+void MESH_OT_vertex_color_add(struct wmOperatorType *ot);
+void MESH_OT_vertex_color_remove(struct wmOperatorType *ot);
+void MESH_OT_sticky_add(struct wmOperatorType *ot);
+void MESH_OT_sticky_remove(struct wmOperatorType *ot);
+
 #endif // MESH_INTERN_H
 
diff --git a/source/blender/editors/mesh/mesh_layers.c b/source/blender/editors/mesh/mesh_layers.c
new file mode 100644
index 00000000000..99d50d1a9b0
--- /dev/null
+++ b/source/blender/editors/mesh/mesh_layers.c
@@ -0,0 +1,424 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include 
+#include 
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_customdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+
+#include "BLI_editVert.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_mesh.h"
+#include "ED_view3d.h"
+
+#include "mesh_intern.h"
+
+static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer)
+{
+	CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
+	void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
+	int type= layer->type;
+	int index= CustomData_get_layer_index(data, type);
+	int i, actindex, rndindex, cloneindex, maskindex;
+	
+	/* ok, deleting a non-active layer needs to preserve the active layer indices.
+	  to do this, we store a pointer to the .data member of both layer and the active layer,
+	  (to detect if we're deleting the active layer or not), then use the active
+	  layer data pointer to find where the active layer has ended up.
+	  
+	  this is necassary because the deletion functions only support deleting the active
+	  layer. */
+	actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
+	rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
+	clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
+	masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
+	CustomData_set_layer_active(data, type, layer - &data->layers[index]);
+
+	if(me->edit_mesh) {
+		EM_free_data_layer(me->edit_mesh, data, type);
+	}
+	else {
+		CustomData_free_layer_active(data, type, me->totface);
+		mesh_update_customdata_pointers(me);
+	}
+
+	if(!CustomData_has_layer(data, type))
+		if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
+			G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
+
+	/* reconstruct active layer */
+	if (actlayerdata != layerdata) {
+		/* find index */
+		actindex = CustomData_get_layer_index(data, type);
+		for (i=actindex; itotlayer; i++) {
+			if (data->layers[i].data == actlayerdata) {
+				actindex = i - actindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_active(data, type, actindex);
+	}
+	
+	if (rndlayerdata != layerdata) {
+		/* find index */
+		rndindex = CustomData_get_layer_index(data, type);
+		for (i=rndindex; itotlayer; i++) {
+			if (data->layers[i].data == rndlayerdata) {
+				rndindex = i - rndindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_render(data, type, rndindex);
+	}
+	
+	if (clonelayerdata != layerdata) {
+		/* find index */
+		cloneindex = CustomData_get_layer_index(data, type);
+		for (i=cloneindex; itotlayer; i++) {
+			if (data->layers[i].data == clonelayerdata) {
+				cloneindex = i - cloneindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_clone(data, type, cloneindex);
+	}
+	
+	if (masklayerdata != layerdata) {
+		/* find index */
+		maskindex = CustomData_get_layer_index(data, type);
+		for (i=maskindex; itotlayer; i++) {
+			if (data->layers[i].data == masklayerdata) {
+				maskindex = i - maskindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_mask(data, type, maskindex);
+	}
+}
+
+/*********************** UV texture operators ************************/
+
+static int uv_texture_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	EditMesh *em;
+	int layernum;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(scene->obedit == ob) {
+		em= me->edit_mesh;
+
+		layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+		if(layernum >= MAX_MTFACE)
+			return OPERATOR_CANCELLED;
+
+		EM_add_data_layer(em, &em->fdata, CD_MTFACE);
+		CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
+	}
+	else if(ob) {
+		layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+		if(layernum >= MAX_MTFACE)
+			return OPERATOR_CANCELLED;
+
+		if(me->mtface)
+			CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface);
+		else
+			CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface);
+
+		CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
+		mesh_update_customdata_pointers(me);
+	}
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_uv_texture_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add UV Texture";
+	ot->idname= "MESH_OT_uv_texture_add";
+	
+	/* api callbacks */
+	ot->exec= uv_texture_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int uv_texture_remove_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	CustomDataLayer *cdl;
+	int index;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+ 	index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+	cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+	if(!cdl)
+		return OPERATOR_CANCELLED;
+
+	delete_customdata_layer(me, cdl);
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_uv_texture_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove UV Texture";
+	ot->idname= "MESH_OT_uv_texture_remove";
+	
+	/* api callbacks */
+	ot->exec= uv_texture_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/*********************** vertex color operators ************************/
+
+static int vertex_color_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	EditMesh *em;
+	MCol *mcol;
+	int layernum;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(scene->obedit == ob) {
+		em= me->edit_mesh;
+
+		layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
+		if(layernum >= MAX_MCOL)
+			return OPERATOR_CANCELLED;
+
+		EM_add_data_layer(em, &em->fdata, CD_MCOL);
+		CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
+	}
+	else {
+		layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
+		if(layernum >= MAX_MCOL)
+			return OPERATOR_CANCELLED;
+
+		mcol= me->mcol;
+
+		if(me->mcol)
+			CustomData_add_layer(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface);
+		else
+			CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
+
+		CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
+		mesh_update_customdata_pointers(me);
+
+		if(!mcol)
+			shadeMeshMCol(scene, ob, me);
+	}
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vertex_color_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Vertex Color";
+	ot->idname= "MESH_OT_vertex_color_add";
+	
+	/* api callbacks */
+	ot->exec= vertex_color_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_color_remove_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	CustomDataLayer *cdl;
+	int index;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+ 	index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
+	cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+	if(!cdl)
+		return OPERATOR_CANCELLED;
+
+	delete_customdata_layer(me, cdl);
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vertex_color_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Vertex Color";
+	ot->idname= "MESH_OT_vertex_color_remove";
+	
+	/* api callbacks */
+	ot->exec= vertex_color_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/*********************** sticky operators ************************/
+
+static int sticky_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(me->msticky)
+		return OPERATOR_CANCELLED;
+
+	// XXX RE_make_sticky();
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sticky_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Sticky";
+	ot->idname= "MESH_OT_sticky_add";
+	
+	/* api callbacks */
+	ot->exec= sticky_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int sticky_remove_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(!me->msticky)
+		return OPERATOR_CANCELLED;
+
+	CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
+	me->msticky= NULL;
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sticky_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Sticky";
+	ot->idname= "MESH_OT_sticky_remove";
+	
+	/* api callbacks */
+	ot->exec= sticky_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 5a86180a60f..2a9357ed0f0 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -183,6 +183,12 @@ void ED_operatortypes_mesh(void)
 	WM_operatortype_append(MESH_OT_knife_cut);
 	WM_operatortype_append(MESH_OT_rip);
 	
+	WM_operatortype_append(MESH_OT_uv_texture_add);
+	WM_operatortype_append(MESH_OT_uv_texture_remove);
+	WM_operatortype_append(MESH_OT_vertex_color_add);
+	WM_operatortype_append(MESH_OT_vertex_color_remove);
+	WM_operatortype_append(MESH_OT_sticky_add);
+	WM_operatortype_append(MESH_OT_sticky_remove);
 }
 
 /* note mesh keymap also for other space? */
diff --git a/source/blender/editors/object/Makefile b/source/blender/editors/object/Makefile
index c0312023bfd..70ada46c80f 100644
--- a/source/blender/editors/object/Makefile
+++ b/source/blender/editors/object/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/object/editkey.c b/source/blender/editors/object/editkey.c
index 913046c5ab8..1c31c7c7653 100644
--- a/source/blender/editors/object/editkey.c
+++ b/source/blender/editors/object/editkey.c
@@ -55,6 +55,7 @@
 
 #include "BKE_action.h"
 #include "BKE_anim.h"
+#include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
@@ -70,11 +71,15 @@
 
 #include "ED_object.h"
 
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
 #include "object_intern.h"
 
 /* XXX */
 static void BIF_undo_push() {}
-static void error() {}
 /* XXX */
 
 #if 0 // XXX old animation system
@@ -394,25 +399,6 @@ void insert_curvekey(Scene *scene, Curve *cu, short rel)
 
 /* ******************** */
 
-void insert_shapekey(Scene *scene, Object *ob)
-{
-	if(get_mesh(ob) && get_mesh(ob)->mr) {
-		error("Cannot create shape keys on a multires mesh.");
-	}
-	else {
-		Key *key;
-	
-		if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1);
-		else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1);
-		else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1);
-	
-		key= ob_get_key(ob);
-		ob->shapenr= BLI_countlist(&key->block);
-	
-		BIF_undo_push("Add Shapekey");
-	}
-}
-
 void delete_key(Scene *scene, Object *ob)
 {
 	KeyBlock *kb, *rkb;
@@ -473,6 +459,123 @@ void delete_key(Scene *scene, Object *ob)
 	BIF_undo_push("Delete Shapekey");
 }
 
+/********************** shape key operators *********************/
+
+static int shape_key_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Key *key;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1);
+	else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1);
+	else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1);
+
+	key= ob_get_key(ob);
+	ob->shapenr= BLI_countlist(&key->block);
+
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_shape_key_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Shape Key";
+	ot->idname= "OBJECT_OT_shape_key_add";
+	
+	/* api callbacks */
+	ot->exec= shape_key_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int shape_key_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene= CTX_data_scene(C);
+	Main *bmain= CTX_data_main(C);
+	KeyBlock *kb, *rkb;
+	Key *key;
+	//IpoCurve *icu;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+	
+	key= ob_get_key(ob);
+	if(key==NULL)
+		return OPERATOR_CANCELLED;
+	
+	kb= BLI_findlink(&key->block, ob->shapenr-1);
+
+	if(kb) {
+		for(rkb= key->block.first; rkb; rkb= rkb->next)
+			if(rkb->relative == ob->shapenr-1)
+				rkb->relative= 0;
+
+		BLI_remlink(&key->block, kb);
+		key->totkey--;
+		if(key->refkey== kb)
+			key->refkey= key->block.first;
+			
+		if(kb->data) MEM_freeN(kb->data);
+		MEM_freeN(kb);
+		
+		for(kb= key->block.first; kb; kb= kb->next)
+			if(kb->adrcode>=ob->shapenr)
+				kb->adrcode--;
+		
+#if 0 // XXX old animation system
+		if(key->ipo) {
+			
+			for(icu= key->ipo->curve.first; icu; icu= icu->next) {
+				if(icu->adrcode==ob->shapenr-1) {
+					BLI_remlink(&key->ipo->curve, icu);
+					free_ipo_curve(icu);
+					break;
+				}
+			}
+			for(icu= key->ipo->curve.first; icu; icu= icu->next) 
+				if(icu->adrcode>=ob->shapenr)
+					icu->adrcode--;
+		}
+#endif // XXX old animation system		
+		
+		if(ob->shapenr>1) ob->shapenr--;
+	}
+	
+	if(key->totkey==0) {
+		if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL;
+		else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL;
+		else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL;
+
+		free_libblock_us(&(bmain->key), key);
+	}
+	
+	DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Shape Key";
+	ot->idname= "OBJECT_OT_shape_key_remove";
+	
+	/* api callbacks */
+	ot->exec= shape_key_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 void move_keys(Object *ob)
 {
 #if 0
@@ -560,3 +663,4 @@ void move_keys(Object *ob)
 	BIF_undo_push("Move Shapekey(s)");
 #endif
 }
+
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 74a1fc12631..c436ccdb328 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -340,7 +340,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
 	
 	if(obedit==NULL || obedit->type!=OB_MESH) {
 		object_add_type(C, OB_MESH);
-		ED_object_enter_editmode(C, 0);
+		ED_object_enter_editmode(C, EM_DO_UNDO);
 		newob = 1;
 	}
 	else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
@@ -388,7 +388,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_mesh_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Mesh";
+	ot->name= "Add Mesh";
 	ot->description = "Add a mesh object to the scene.";
 	ot->idname= "OBJECT_OT_mesh_add";
 	
@@ -398,8 +398,8 @@ void OBJECT_OT_mesh_add(wmOperatorType *ot)
 	
 	ot->poll= ED_operator_scene_editable;
 	
-	/* flags */
-	ot->flag= 0;
+	/* flags: no register or undo, this operator calls operators */
+	ot->flag= 0; //OPTYPE_REGISTER|OPTYPE_UNDO;
 	
 	RNA_def_enum(ot->srna, "type", prop_mesh_types, 0, "Primitive", "");
 }
@@ -462,7 +462,7 @@ static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event)
 void OBJECT_OT_curve_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Curve";
+	ot->name= "Add Curve";
 	ot->description = "Add a curve object to the scene.";
 	ot->idname= "OBJECT_OT_curve_add";
 	
@@ -520,7 +520,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_surface_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Surface";
+	ot->name= "Add Surface";
 	ot->description = "Add a surface object to the scene.";
 	ot->idname= "OBJECT_OT_surface_add";
 	
@@ -557,7 +557,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_text_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Text";
+	ot->name= "Add Text";
 	ot->description = "Add a text object to the scene";
 	ot->idname= "OBJECT_OT_text_add";
 	
@@ -602,7 +602,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_armature_add(wmOperatorType *ot)
 {	
 	/* identifiers */
-	ot->name= "Armature";
+	ot->name= "Add Armature";
 	ot->description = "Add an armature object to the scene.";
 	ot->idname= "OBJECT_OT_armature_add";
 	
@@ -1395,7 +1395,8 @@ static int parent_clear_exec(bContext *C, wmOperator *op)
 	
 	DAG_scene_sort(CTX_data_scene(C));
 	ED_anim_dag_flush_update(C);
-	
+	WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
 	return OPERATOR_FINISHED;
 }
 
@@ -2600,7 +2601,8 @@ static int parent_set_exec(bContext *C, wmOperator *op)
 	CTX_DATA_END;
 	
 	DAG_scene_sort(CTX_data_scene(C));
-	ED_anim_dag_flush_update(C);	
+	ED_anim_dag_flush_update(C);
+	WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
 	
 	return OPERATOR_FINISHED;
 }
@@ -2648,7 +2650,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
 	ot->poll= ED_operator_object_active;
 	
 	/* flags */
-	ot->flag= 0;
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 	
 	RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
 }
@@ -3349,6 +3351,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
 		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
 	}
 	
+	if(flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode");
 	if(flag & EM_WAITCURSOR) waitcursor(0);
 }
 
@@ -3661,7 +3664,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
 			if(!psys)
 				return;
 
-			if(scene->selectmode & SCE_SELECT_POINT)
+			if(pset->selectmode & SCE_SELECT_POINT)
 				nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5");
 			else
 				nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5");
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 1eb867e19a0..a52acdd4e1e 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -92,5 +92,19 @@ void OBJECT_OT_modifier_mdef_bind(struct wmOperatorType *ot);
 /* editconstraint.c */
 void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
 
+/* object_vgroup.c */
+void OBJECT_OT_vertex_group_add(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_remove(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_assign(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
+
+/* editkey.c */
+void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);
+void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot);
+
 #endif /* ED_OBJECT_INTERN_H */
 
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index ee506220b67..4bcfcc4d5ab 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1,5 +1,5 @@
 /**
- * $Id: object_modifier.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index cfee6a55152..6fa78a53840 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -104,6 +104,18 @@ void ED_operatortypes_object(void)
 	WM_operatortype_append(OBJECT_OT_modifier_mdef_bind);
 
 	WM_operatortype_append(OBJECT_OT_constraint_add);
+
+	WM_operatortype_append(OBJECT_OT_vertex_group_add);
+	WM_operatortype_append(OBJECT_OT_vertex_group_remove);
+	WM_operatortype_append(OBJECT_OT_vertex_group_assign);
+	WM_operatortype_append(OBJECT_OT_vertex_group_remove_from);
+	WM_operatortype_append(OBJECT_OT_vertex_group_select);
+	WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
+	WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
+	WM_operatortype_append(OBJECT_OT_vertex_group_copy);
+
+	WM_operatortype_append(OBJECT_OT_shape_key_add);
+	WM_operatortype_append(OBJECT_OT_shape_key_remove);
 }
 
 void ED_keymap_object(wmWindowManager *wm)
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
new file mode 100644
index 00000000000..fb71fc09108
--- /dev/null
+++ b/source/blender/editors/object/object_vgroup.c
@@ -0,0 +1,1344 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * Creator-specific support for vertex deformation groups
+ * Added: apply deform function (ton)
+ */
+
+#include 
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_cloth_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
+#include "BKE_lattice.h"
+#include "BKE_mesh.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_mesh.h"
+#include "ED_view3d.h"
+
+#include "object_intern.h"
+
+/* XXX */
+static void BIF_undo_push() {}
+static void error() {}
+
+static Lattice *def_get_lattice(Object *ob)
+{
+	if(ob->type==OB_LATTICE) {
+		Lattice *lt= ob->data;
+		if(lt->editlatt)
+			return lt->editlatt;
+		return lt;
+	}
+	return NULL;
+}
+
+/* only in editmode */
+void sel_verts_defgroup (Object *obedit, int select)
+{
+	EditVert *eve;
+	Object *ob;
+	int i;
+	MDeformVert *dvert;
+
+	ob= obedit;
+
+	if (!ob)
+		return;
+
+	switch (ob->type){
+	case OB_MESH:
+	{
+		Mesh *me= ob->data;
+		EditMesh *em = BKE_mesh_get_editmesh(me);
+
+		for (eve=em->verts.first; eve; eve=eve->next){
+			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+
+			if (dvert && dvert->totweight){
+				for (i=0; itotweight; i++){
+					if (dvert->dw[i].def_nr == (ob->actdef-1)){
+						if (select) eve->f |= SELECT;
+						else eve->f &= ~SELECT;
+						
+						break;
+					}
+				}
+			}
+		}
+		/* this has to be called, because this function operates on vertices only */
+		if(select) EM_select_flush(em);	// vertices to edges/faces
+		else EM_deselect_flush(em);
+
+		BKE_mesh_end_editmesh(me, em);
+	}
+		break;
+	case OB_LATTICE:
+	{
+		Lattice *lt= def_get_lattice(ob);
+		
+		if(lt->dvert) {
+			BPoint *bp;
+			int a, tot;
+			
+			dvert= lt->dvert;
+
+			tot= lt->pntsu*lt->pntsv*lt->pntsw;
+			for(a=0, bp= lt->def; atotweight; i++){
+					if (dvert->dw[i].def_nr == (ob->actdef-1)) {
+						if(select) bp->f1 |= SELECT;
+						else bp->f1 &= ~SELECT;
+						
+						break;
+					}
+				}
+			}
+		}
+	}
+		break;
+		
+	default:
+		break;
+	}
+}
+
+/* check if deform vertex has defgroup index */
+MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
+{
+	int i;
+	
+	if (!dv || defgroup<0)
+		return NULL;
+	
+	for (i=0; itotweight; i++){
+		if (dv->dw[i].def_nr == defgroup)
+			return dv->dw+i;
+	}
+	return NULL;
+}
+
+/* Ensures that mv has a deform weight entry for
+   the specified defweight group */
+/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
+MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
+{
+	MDeformWeight *newdw;
+
+	/* do this check always, this function is used to check for it */
+	if (!dv || defgroup<0)
+		return NULL;
+	
+	newdw = get_defweight (dv, defgroup);
+	if (newdw)
+		return newdw;
+	
+	newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
+	if (dv->dw){
+		memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+		MEM_freeN (dv->dw);
+	}
+	dv->dw=newdw;
+	
+	dv->dw[dv->totweight].weight=0.0f;
+	dv->dw[dv->totweight].def_nr=defgroup;
+	/* Group index */
+	
+	dv->totweight++;
+
+	return dv->dw+(dv->totweight-1);
+}
+
+bDeformGroup *add_defgroup_name (Object *ob, char *name)
+{
+	bDeformGroup	*defgroup;
+	
+	if (!ob)
+		return NULL;
+	
+	defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup");
+
+	BLI_strncpy (defgroup->name, name, 32);
+
+	BLI_addtail(&ob->defbase, defgroup);
+	unique_vertexgroup_name(defgroup, ob);
+
+	ob->actdef = BLI_countlist(&ob->defbase);
+
+	return defgroup;
+}
+
+void add_defgroup (Object *ob) 
+{
+	add_defgroup_name (ob, "Group");
+}
+
+
+void duplicate_defgroup ( Object *ob )
+{
+	bDeformGroup *dg, *cdg;
+	char name[32], s[32];
+	MDeformWeight *org, *cpy;
+	MDeformVert *dvert, *dvert_array;
+	int i, idg, icdg, dvert_tot;
+
+	if (ob->type != OB_MESH && ob->type != OB_LATTICE)
+		return;
+
+	dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
+	if (!dg)
+		return;
+	
+	if (strstr(dg->name, "_copy")) {
+		BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */
+	} else {
+		BLI_snprintf (name, 32, "%s_copy", dg->name);
+		while (get_named_vertexgroup (ob, name)) {
+			if ((strlen (name) + 6) > 32) {
+				error ("Error: the name for the new group is > 32 characters");
+				return;
+			}
+			strcpy (s, name);
+			BLI_snprintf (name, 32, "%s_copy", s);
+		}
+	}		
+
+	cdg = copy_defgroup (dg);
+	strcpy (cdg->name, name);
+	unique_vertexgroup_name(cdg, ob);
+	
+	BLI_addtail (&ob->defbase, cdg);
+
+	idg = (ob->actdef-1);
+	ob->actdef = BLI_countlist (&ob->defbase);
+	icdg = (ob->actdef-1);
+
+	if(ob->type == OB_MESH) {
+		Mesh *me = get_mesh (ob);
+		dvert_array= me->dvert;
+		dvert_tot= me->totvert;
+	}
+	else if (ob->type == OB_LATTICE) {
+		Lattice *lt= (Lattice *)ob->data;
+		dvert_array= lt->dvert;
+		dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
+	}
+	
+	if (!dvert_array)
+		return;
+
+	for (i = 0; i < dvert_tot; i++) {
+		dvert = dvert_array+i;
+		org = get_defweight (dvert, idg);
+		if (org) {
+			float weight = org->weight;
+			/* verify_defweight re-allocs org so need to store the weight first */
+			cpy = verify_defweight (dvert, icdg);
+			cpy->weight = weight;
+		}
+	}
+}
+
+static void del_defgroup_update_users(Object *ob, int id)
+{
+	ExplodeModifierData *emd;
+	ModifierData *md;
+	ParticleSystem *psys;
+	ClothModifierData *clmd;
+	ClothSimSettings *clsim;
+	int a;
+
+	/* these cases don't use names to refer to vertex groups, so when
+	 * they get deleted the numbers get out of sync, this corrects that */
+
+	if(ob->soft) {
+		if(ob->soft->vertgroup == id)
+			ob->soft->vertgroup= 0;
+		else if(ob->soft->vertgroup > id)
+			ob->soft->vertgroup--;
+	}
+
+	for(md=ob->modifiers.first; md; md=md->next) {
+		if(md->type == eModifierType_Explode) {
+			emd= (ExplodeModifierData*)md;
+
+			if(emd->vgroup == id)
+				emd->vgroup= 0;
+			else if(emd->vgroup > id)
+				emd->vgroup--;
+		}
+		else if(md->type == eModifierType_Cloth) {
+			clmd= (ClothModifierData*)md;
+			clsim= clmd->sim_parms;
+
+			if(clsim) {
+				if(clsim->vgroup_mass == id)
+					clsim->vgroup_mass= 0;
+				else if(clsim->vgroup_mass > id)
+					clsim->vgroup_mass--;
+
+				if(clsim->vgroup_bend == id)
+					clsim->vgroup_bend= 0;
+				else if(clsim->vgroup_bend > id)
+					clsim->vgroup_bend--;
+
+				if(clsim->vgroup_struct == id)
+					clsim->vgroup_struct= 0;
+				else if(clsim->vgroup_struct > id)
+					clsim->vgroup_struct--;
+			}
+		}
+	}
+
+	for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+		for(a=0; avgroup[a] == id)
+				psys->vgroup[a]= 0;
+			else if(psys->vgroup[a] > id)
+				psys->vgroup[a]--;
+	}
+}
+
+void del_defgroup_in_object_mode ( Object *ob )
+{
+	bDeformGroup *dg;
+	MDeformVert *dvert_array, *dvert;
+	
+	int i, e, dvert_tot;
+
+	if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE))
+		return;
+
+	if(ob->type == OB_MESH) {
+		Mesh *me = get_mesh (ob);
+		dvert_array= me->dvert;
+		dvert_tot= me->totvert;
+	}
+	else if (ob->type == OB_LATTICE) {
+		Lattice *lt= (Lattice *)ob->data;
+		dvert_array= lt->dvert;
+		dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
+	}
+	
+	dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
+	if (!dg)
+		return;
+	
+	if (dvert_array) {
+		for (i = 0; i < dvert_tot; i++) {
+			dvert = dvert_array + i;
+			if (dvert) {
+				if (get_defweight (dvert, (ob->actdef-1)))
+					remove_vert_defgroup (ob, dg, i);
+			}
+		}
+
+		for (i = 0; i < dvert_tot; i++) {
+			dvert = dvert_array+i;
+			if (dvert) {
+				for (e = 0; e < dvert->totweight; e++) {
+					if (dvert->dw[e].def_nr > (ob->actdef-1))
+						dvert->dw[e].def_nr--;
+				}
+			}
+		}
+	}
+
+	del_defgroup_update_users(ob, ob->actdef);
+
+	/* Update the active deform index if necessary */
+	if (ob->actdef == BLI_countlist(&ob->defbase))
+		ob->actdef--;
+  
+	/* Remove the group */
+	BLI_freelinkN (&ob->defbase, dg);
+}
+
+void del_defgroup (Object *ob)
+{
+	bDeformGroup	*defgroup;
+	int				i;
+
+	if (!ob)
+		return;
+
+	if (!ob->actdef)
+		return;
+
+	defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
+	if (!defgroup)
+		return;
+
+	/* Make sure that no verts are using this group */
+	remove_verts_defgroup(ob, 1);
+
+	/* Make sure that any verts with higher indices are adjusted accordingly */
+	if(ob->type==OB_MESH) {
+		Mesh *me= ob->data;
+		EditMesh *em = BKE_mesh_get_editmesh(me);
+		EditVert *eve;
+		MDeformVert *dvert;
+		
+		for (eve=em->verts.first; eve; eve=eve->next){
+			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+
+			if (dvert)
+				for (i=0; itotweight; i++)
+					if (dvert->dw[i].def_nr > (ob->actdef-1))
+						dvert->dw[i].def_nr--;
+		}
+		BKE_mesh_end_editmesh(me, em);
+	}
+	else if(ob->type==OB_LATTICE) {
+		Lattice *lt= def_get_lattice(ob);
+		BPoint *bp;
+		MDeformVert *dvert= lt->dvert;
+		int a, tot;
+		
+		if (dvert) {
+			tot= lt->pntsu*lt->pntsv*lt->pntsw;
+			for(a=0, bp= lt->def; atotweight; i++){
+					if (dvert->dw[i].def_nr > (ob->actdef-1))
+						dvert->dw[i].def_nr--;
+				}
+			}
+		}
+	}
+
+	del_defgroup_update_users(ob, ob->actdef);
+
+	/* Update the active deform index if necessary */
+	if (ob->actdef==BLI_countlist(&ob->defbase))
+		ob->actdef--;
+	
+	/* Remove the group */
+	BLI_freelinkN (&ob->defbase, defgroup);
+	
+	/* remove all dverts */
+	if(ob->actdef==0) {
+		if(ob->type==OB_MESH) {
+			Mesh *me= ob->data;
+			CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+			me->dvert= NULL;
+		}
+		else if(ob->type==OB_LATTICE) {
+			Lattice *lt= def_get_lattice(ob);
+			if (lt->dvert) {
+				MEM_freeN(lt->dvert);
+				lt->dvert= NULL;
+			}
+		}
+	}
+}
+
+void del_all_defgroups (Object *ob)
+{
+	/* Sanity check */
+	if (ob == NULL)
+		return;
+	
+	/* Remove all DVerts */
+	if (ob->type==OB_MESH) {
+		Mesh *me= ob->data;
+		CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+		me->dvert= NULL;
+	}
+	else if(ob->type==OB_LATTICE) {
+		Lattice *lt= def_get_lattice(ob);
+		if (lt->dvert) {
+			MEM_freeN(lt->dvert);
+			lt->dvert= NULL;
+		}
+	}
+	
+	/* Remove all DefGroups */
+	BLI_freelistN(&ob->defbase);
+	
+	/* Fix counters/indices */
+	ob->actdef= 0;
+}
+
+void create_dverts(ID *id)
+{
+	/* create deform verts
+	 */
+
+	if( GS(id->name)==ID_ME) {
+		Mesh *me= (Mesh *)id;
+		me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
+	}
+	else if( GS(id->name)==ID_LT) {
+		Lattice *lt= (Lattice *)id;
+		lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
+	}
+}
+
+/* for mesh in object mode
+   lattice can be in editmode */
+void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
+{
+	/* This routine removes the vertex from the deform
+	 * group with number def_nr.
+	 *
+	 * This routine is meant to be fast, so it is the
+	 * responsibility of the calling routine to:
+	 *   a) test whether ob is non-NULL
+	 *   b) test whether ob is a mesh
+	 *   c) calculate def_nr
+	 */
+
+	MDeformWeight *newdw;
+	MDeformVert *dvert= NULL;
+	int i;
+
+	/* get the deform vertices corresponding to the
+	 * vertnum
+	 */
+	if(ob->type==OB_MESH) {
+		if( ((Mesh*)ob->data)->dvert )
+			dvert = ((Mesh*)ob->data)->dvert + vertnum;
+	}
+	else if(ob->type==OB_LATTICE) {
+		Lattice *lt= def_get_lattice(ob);
+		
+		if(lt->dvert)
+			dvert = lt->dvert + vertnum;
+	}
+	
+	if(dvert==NULL)
+		return;
+	
+	/* for all of the deform weights in the
+	 * deform vert
+	 */
+	for (i=dvert->totweight - 1 ; i>=0 ; i--){
+
+		/* if the def_nr is the same as the one
+		 * for our weight group then remove it
+		 * from this deform vert.
+		 */
+		if (dvert->dw[i].def_nr == def_nr) {
+			dvert->totweight--;
+        
+			/* if there are still other deform weights
+			 * attached to this vert then remove this
+			 * deform weight, and reshuffle the others
+			 */
+			if (dvert->totweight) {
+				newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), 
+									 "deformWeight");
+				if (dvert->dw){
+					memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
+					memcpy (newdw+i, dvert->dw+i+1, 
+							sizeof(MDeformWeight)*(dvert->totweight-i));
+					MEM_freeN (dvert->dw);
+				}
+				dvert->dw=newdw;
+			}
+			/* if there are no other deform weights
+			 * left then just remove the deform weight
+			 */
+			else {
+				MEM_freeN (dvert->dw);
+				dvert->dw = NULL;
+				break;
+			}
+		}
+	}
+
+}
+
+/* for Mesh in Object mode */
+/* allows editmode for Lattice */
+void add_vert_defnr (Object *ob, int def_nr, int vertnum, 
+                           float weight, int assignmode)
+{
+	/* add the vert to the deform group with the
+	 * specified number
+	 */
+	MDeformVert *dv= NULL;
+	MDeformWeight *newdw;
+	int	i;
+
+	/* get the vert */
+	if(ob->type==OB_MESH) {
+		if(((Mesh*)ob->data)->dvert)
+			dv = ((Mesh*)ob->data)->dvert + vertnum;
+	}
+	else if(ob->type==OB_LATTICE) {
+		Lattice *lt= def_get_lattice(ob);
+		
+		if(lt->dvert)
+			dv = lt->dvert + vertnum;
+	}
+	
+	if(dv==NULL)
+		return;
+	
+	/* Lets first check to see if this vert is
+	 * already in the weight group -- if so
+	 * lets update it
+	 */
+	for (i=0; itotweight; i++){
+		
+		/* if this weight cooresponds to the
+		 * deform group, then add it using
+		 * the assign mode provided
+		 */
+		if (dv->dw[i].def_nr == def_nr){
+			
+			switch (assignmode) {
+			case WEIGHT_REPLACE:
+				dv->dw[i].weight=weight;
+				break;
+			case WEIGHT_ADD:
+				dv->dw[i].weight+=weight;
+				if (dv->dw[i].weight >= 1.0)
+					dv->dw[i].weight = 1.0;
+				break;
+			case WEIGHT_SUBTRACT:
+				dv->dw[i].weight-=weight;
+				/* if the weight is zero or less then
+				 * remove the vert from the deform group
+				 */
+				if (dv->dw[i].weight <= 0.0)
+					remove_vert_def_nr(ob, def_nr, vertnum);
+				break;
+			}
+			return;
+		}
+	}
+
+	/* if the vert wasn't in the deform group then
+	 * we must take a different form of action ...
+	 */
+
+	switch (assignmode) {
+	case WEIGHT_SUBTRACT:
+		/* if we are subtracting then we don't
+		 * need to do anything
+		 */
+		return;
+
+	case WEIGHT_REPLACE:
+	case WEIGHT_ADD:
+		/* if we are doing an additive assignment, then
+		 * we need to create the deform weight
+		 */
+		newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), 
+							 "deformWeight");
+		if (dv->dw){
+			memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+			MEM_freeN (dv->dw);
+		}
+		dv->dw=newdw;
+    
+		dv->dw[dv->totweight].weight=weight;
+		dv->dw[dv->totweight].def_nr=def_nr;
+    
+		dv->totweight++;
+		break;
+	}
+}
+
+/* called while not in editmode */
+void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, 
+                           float weight, int assignmode)
+{
+	/* add the vert to the deform group with the
+	 * specified assign mode
+	 */
+	int	def_nr;
+
+	/* get the deform group number, exit if
+	 * it can't be found
+	 */
+	def_nr = get_defgroup_num(ob, dg);
+	if (def_nr < 0) return;
+
+	/* if there's no deform verts then
+	 * create some
+	 */
+	if(ob->type==OB_MESH) {
+		if (!((Mesh*)ob->data)->dvert)
+			create_dverts(ob->data);
+	}
+	else if(ob->type==OB_LATTICE) {
+		if (!((Lattice*)ob->data)->dvert)
+			create_dverts(ob->data);
+	}
+
+	/* call another function to do the work
+	 */
+	add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
+}
+
+/* Only available in editmode */
+void assign_verts_defgroup (Object *ob, float weight)
+{
+	EditVert *eve;
+	bDeformGroup *dg, *eg;
+	MDeformWeight *newdw;
+	MDeformVert *dvert;
+	int	i, done;
+
+	if (!ob)
+		return;
+
+	dg=BLI_findlink(&ob->defbase, ob->actdef-1);
+	if (!dg){
+		error ("No vertex group is active");
+		return;
+	}
+
+	switch (ob->type){
+	case OB_MESH:
+	{
+		Mesh *me= ob->data;
+		EditMesh *em = BKE_mesh_get_editmesh(me);
+
+		if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+			EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT);
+
+		/* Go through the list of editverts and assign them */
+		for (eve=em->verts.first; eve; eve=eve->next){
+			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+
+			if (dvert && (eve->f & 1)){
+				done=0;
+				/* See if this vert already has a reference to this group */
+				/*		If so: Change its weight */
+				done=0;
+				for (i=0; itotweight; i++){
+					eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
+					/* Find the actual group */
+					if (eg==dg){
+						dvert->dw[i].weight= weight;
+						done=1;
+						break;
+					}
+			 	}
+				/*		If not: Add the group and set its weight */
+				if (!done){
+					newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
+					if (dvert->dw){
+						memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
+						MEM_freeN (dvert->dw);
+					}
+					dvert->dw=newdw;
+
+					dvert->dw[dvert->totweight].weight= weight;
+					dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
+
+					dvert->totweight++;
+
+				}
+			}
+		}
+		BKE_mesh_end_editmesh(me, em);
+	}
+		break;
+	case OB_LATTICE:
+		{
+			Lattice *lt= def_get_lattice(ob);
+			BPoint *bp;
+			int a, tot;
+			
+			if(lt->dvert==NULL)
+				create_dverts(<->id);
+			
+			tot= lt->pntsu*lt->pntsv*lt->pntsw;
+			for(a=0, bp= lt->def; af1 & SELECT)
+					add_vert_defnr (ob, ob->actdef-1, a, weight, WEIGHT_REPLACE);
+			}
+		}
+		break;
+	default:
+		printf ("Assigning deformation groups to unknown object type\n");
+		break;
+	}
+
+}
+
+/* mesh object mode, lattice can be in editmode */
+void remove_vert_defgroup (Object *ob, bDeformGroup	*dg, int vertnum)
+{
+	/* This routine removes the vertex from the specified
+	 * deform group.
+	 */
+
+	int def_nr;
+
+	/* if the object is NULL abort
+	 */
+	if (!ob)
+		return;
+
+	/* get the deform number that cooresponds
+	 * to this deform group, and abort if it
+	 * can not be found.
+	 */
+	def_nr = get_defgroup_num(ob, dg);
+	if (def_nr < 0) return;
+
+	/* call another routine to do the work
+	 */
+	remove_vert_def_nr (ob, def_nr, vertnum);
+}
+
+/* for mesh in object mode lattice can be in editmode */
+static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
+{
+	MDeformVert *dvert= NULL;
+	int i;
+
+	/* get the deform vertices corresponding to the
+	 * vertnum
+	 */
+	if(ob->type==OB_MESH) {
+		if( ((Mesh*)ob->data)->dvert )
+			dvert = ((Mesh*)ob->data)->dvert + vertnum;
+	}
+	else if(ob->type==OB_LATTICE) {
+		Lattice *lt= def_get_lattice(ob);
+		
+		if(lt->dvert)
+			dvert = lt->dvert + vertnum;
+	}
+	
+	if(dvert==NULL)
+		return 0.0f;
+	
+	for(i=dvert->totweight-1 ; i>=0 ; i--)
+		if(dvert->dw[i].def_nr == def_nr)
+			return dvert->dw[i].weight;
+
+	return 0.0f;
+}
+
+/* mesh object mode, lattice can be in editmode */
+float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
+{
+	int def_nr;
+
+	if(!ob)
+		return 0.0f;
+
+	def_nr = get_defgroup_num(ob, dg);
+	if(def_nr < 0) return 0.0f;
+
+	return get_vert_def_nr (ob, def_nr, vertnum);
+}
+
+/* Only available in editmode */
+/* removes from active defgroup, if allverts==0 only selected vertices */
+void remove_verts_defgroup (Object *ob, int allverts)
+{
+	EditVert *eve;
+	MDeformVert *dvert;
+	MDeformWeight *newdw;
+	bDeformGroup *dg, *eg;
+	int	i;
+
+	if (!ob)
+		return;
+
+	dg=BLI_findlink(&ob->defbase, ob->actdef-1);
+	if (!dg){
+		error ("No vertex group is active");
+		return;
+	}
+
+	switch (ob->type){
+	case OB_MESH:
+	{
+		Mesh *me= ob->data;
+		EditMesh *em = BKE_mesh_get_editmesh(me);
+
+		for (eve=em->verts.first; eve; eve=eve->next){
+			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+		
+			if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
+				for (i=0; itotweight; i++){
+					/* Find group */
+					eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
+					if (eg == dg){
+						dvert->totweight--;
+						if (dvert->totweight){
+							newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
+							
+							if (dvert->dw){
+								memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
+								memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
+								MEM_freeN (dvert->dw);
+							}
+							dvert->dw=newdw;
+						}
+						else{
+							MEM_freeN (dvert->dw);
+							dvert->dw=NULL;
+							break;
+						}
+					}
+				}
+			}
+		}
+		BKE_mesh_end_editmesh(me, em);
+	}
+		break;
+	case OB_LATTICE:
+	{
+		Lattice *lt= def_get_lattice(ob);
+		
+		if(lt->dvert) {
+			BPoint *bp;
+			int a, tot= lt->pntsu*lt->pntsv*lt->pntsw;
+				
+			for(a=0, bp= lt->def; af1 & SELECT))
+					remove_vert_defgroup (ob, dg, a);
+			}
+		}
+	}
+		break;
+		
+	default:
+		printf ("Removing deformation groups from unknown object type\n");
+		break;
+	}
+}
+
+/* Only available in editmode */
+/* removes from all defgroup, if allverts==0 only selected vertices */
+void remove_verts_defgroups(Object *ob, int allverts)
+{
+	int actdef, defCount;
+
+	if (ob == NULL) return;
+	
+	actdef= ob->actdef;
+	defCount= BLI_countlist(&ob->defbase);
+	
+	if (defCount == 0) {
+		error("Object has no vertex groups");
+		return;
+	}
+	
+	/* To prevent code redundancy, we just use remove_verts_defgroup, but that
+	 * only operates on the active vgroup. So we iterate through all groups, by changing
+	 * active group index
+	 */
+	for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++)
+		remove_verts_defgroup(ob, allverts);
+		
+	ob->actdef= actdef;
+}
+
+void vertexgroup_select_by_name(Object *ob, char *name)
+{
+	bDeformGroup *curdef;
+	int actdef= 1;
+	
+	if(ob==NULL) return;
+	
+	for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
+		if (!strcmp(curdef->name, name)) {
+			ob->actdef= actdef;
+			return;
+		}
+	}
+	ob->actdef=0;	// this signals on painting to create a new one, if a bone in posemode is selected */
+}
+
+/* This function provides a shortcut for adding/removing verts from 
+ * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes
+ * and Lattices. (currently only restricted to those two)
+ * It is only responsible for 
+ */
+void vgroup_assign_with_menu(Scene *scene, Object *ob)
+{
+	VPaint *wp= scene->toolsettings->wpaint;
+	int defCount;
+	int mode= 0;
+	
+	/* prevent crashes */
+	if (wp==NULL || ob==NULL) return;
+	
+	defCount= BLI_countlist(&ob->defbase);
+	
+	/* give user choices of adding to current/new or removing from current */
+// XXX	if (defCount && ob->actdef)
+//		mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4");
+//	else
+//		mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
+	
+	/* handle choices */
+	switch (mode) {
+		case 1: /* add to new group */
+			add_defgroup(ob);
+			assign_verts_defgroup(ob, wp->brush->alpha);
+			BIF_undo_push("Assign to vertex group");
+			break;
+		case 2: /* add to current group */
+			assign_verts_defgroup(ob, wp->brush->alpha);
+			BIF_undo_push("Assign to vertex group");
+			break;
+		case 3:	/* remove from current group */
+			remove_verts_defgroup(ob, 0);
+			BIF_undo_push("Remove from vertex group");
+			break;
+		case 4: /* remove from all groups */
+			remove_verts_defgroups(ob, 0);
+			BIF_undo_push("Remove from all vertex groups");
+			break;
+	}
+}
+
+/* This function provides a shortcut for commonly used vertex group 
+ * functions - change weight (not implemented), change active group, delete active group,
+ * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now).
+ */
+void vgroup_operation_with_menu(Object *ob)
+{
+	int defCount;
+	int mode= 0;
+	
+	/* prevent crashes and useless cases */
+	if (ob==NULL) return;
+	
+	defCount= BLI_countlist(&ob->defbase);
+	if (defCount == 0) return;
+	
+	/* give user choices of adding to current/new or removing from current */
+// XXX	if (ob->actdef)
+//		mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3");
+//	else
+//		mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3");
+	
+	/* handle choices */
+	switch (mode) {
+		case 1: /* change active group*/
+			{
+				char *menustr= NULL; // XXX get_vertexgroup_menustr(ob);
+				short nr;
+				
+				if (menustr) {
+// XXX					nr= pupmenu(menustr);
+					
+					if ((nr >= 1) && (nr <= defCount)) 
+						ob->actdef= nr;
+						
+					MEM_freeN(menustr);
+				}
+			}
+			break;
+		case 2: /* delete active group  */
+			{
+				del_defgroup(ob);
+				BIF_undo_push("Delete vertex group");
+			}
+			break;
+		case 3: /* delete all groups */
+			{
+				del_all_defgroups(ob);
+				BIF_undo_push("Delete all vertex groups");
+			}
+			break;
+	}
+}
+
+/********************** vertex group operators *********************/
+
+static int vertex_group_add_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene= CTX_data_scene(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	add_defgroup(ob);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_add";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene= CTX_data_scene(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(scene->obedit == ob) {
+		del_defgroup(ob);
+		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	}
+	else {
+		del_defgroup_in_object_mode(ob);
+		DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	}
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_remove";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_assign_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	assign_verts_defgroup(ob, ts->vgroup_weight);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Assign Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_assign";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_assign_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	remove_verts_defgroup(ob, 0);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove from Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_remove_from";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_remove_from_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_select_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	sel_verts_defgroup(ob, 1); /* runs countall() */
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Select Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_select";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_select_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_deselect_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	sel_verts_defgroup(ob, 0); /* runs countall() */
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Deselect Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_deselect";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_deselect_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_copy_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	duplicate_defgroup(ob);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Copy Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_copy";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_copy_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+    Base *base;
+	int retval= OPERATOR_CANCELLED;
+
+	if(!ob)
+		return retval;
+
+    for(base=scene->base.first; base; base= base->next) {
+        if(base->object->type==ob->type) {
+            if(base->object!=ob && base->object->data==ob->data) {
+                BLI_freelistN(&base->object->defbase);
+                BLI_duplicatelist(&base->object->defbase, &ob->defbase);
+                base->object->actdef= ob->actdef;
+
+                DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
+				WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, base->object);
+
+				retval = OPERATOR_FINISHED;
+            }
+        }
+    }
+	
+	return retval;
+}
+
+void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Copy Vertex Group to Linked";
+	ot->idname= "OBJECT_OT_vertex_group_copy_to_linked";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_copy_to_linked_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
diff --git a/source/blender/editors/physics/Makefile b/source/blender/editors/physics/Makefile
index a71ea9e2083..63968fdd537 100644
--- a/source/blender/editors/physics/Makefile
+++ b/source/blender/editors/physics/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c
new file mode 100644
index 00000000000..893c59a521d
--- /dev/null
+++ b/source/blender/editors/physics/ed_pointcache.c
@@ -0,0 +1,382 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
+#include "DNA_modifier_types.h"
+
+#include "BKE_context.h"
+#include "BKE_particle.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h" 
+#include "BKE_pointcache.h"
+#include "BKE_global.h"
+#include "BKE_modifier.h"
+
+#include "BLI_blenlib.h"
+
+#include "ED_screen.h"
+#include "ED_pointcache.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "physics_intern.h"
+
+static int cache_break_test(void *cbd) {
+	return G.afbreek==1;
+}
+/**************************** general **********************************/
+static int ptcache_bake_all_poll(bContext *C)
+{
+	Scene *scene= CTX_data_scene(C);
+
+	if(!scene)
+		return 0;
+	
+	return 1;
+}
+
+static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	PTCacheBaker baker;
+
+
+	baker.scene = scene;
+	baker.pid = NULL;
+	baker.bake = RNA_boolean_get(op->ptr, "bake");
+	baker.render = 0;
+	baker.quick_step = 1;
+	baker.break_test = cache_break_test;
+	baker.break_data = NULL;
+	baker.progressbar = (void (*)(void *, int))WM_timecursor;
+	baker.progresscontext = CTX_wm_window(C);
+
+	BKE_ptcache_make_cache(&baker);
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Base *base;
+	PTCacheID *pid;
+	ListBase pidlist;
+
+	for(base=scene->base.first; base; base= base->next) {
+		BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+		for(pid=pidlist.first; pid; pid=pid->next) {
+			pid->cache->flag &= ~PTCACHE_BAKED;
+		}
+		
+		BLI_freelistN(&pidlist);
+	}
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+
+void PTCACHE_OT_bake_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake All Physics";
+	ot->idname= "PTCACHE_OT_bake_all";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_all_exec;
+	ot->poll= ptcache_bake_all_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Free All Physics Bakes";
+	ot->idname= "PTCACHE_OT_free_bake_all";
+	
+	/* api callbacks */
+	ot->exec= ptcache_free_bake_all_exec;
+	ot->poll= ptcache_bake_all_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/**************************** cloth **********************************/
+static int ptcache_bake_cloth_poll(bContext *C)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+	if(!scene || !ob || ob->id.lib || !clmd)
+		return 0;
+	
+	return 1;
+}
+
+static int ptcache_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+	PTCacheID pid;
+	PTCacheBaker baker;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+	baker.scene = scene;
+	baker.pid = &pid;
+	baker.bake = RNA_boolean_get(op->ptr, "bake");
+	baker.render = 0;
+	baker.quick_step = 1;
+	baker.break_test = cache_break_test;
+	baker.break_data = NULL;
+	baker.progressbar = WM_timecursor;
+	baker.progresscontext = CTX_wm_window(C);
+
+	BKE_ptcache_make_cache(&baker);
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+	pid.cache->flag &= ~PTCACHE_BAKED;
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_cloth(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake Cloth";
+	ot->idname= "PTCACHE_OT_cache_cloth";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_cloth_exec;
+	ot->poll= ptcache_bake_cloth_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_cloth(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Free Cloth Bake";
+	ot->idname= "PTCACHE_OT_free_bake_cloth";
+	
+	/* api callbacks */
+	ot->exec= ptcache_free_bake_cloth_exec;
+	ot->poll= ptcache_bake_cloth_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_cloth_cache_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+	pid.cache->flag |= PTCACHE_BAKED;
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_cloth_cache(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake From Cache";
+	ot->idname= "PTCACHE_OT_bake_from_cloth_cache";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_from_cloth_cache_exec;
+	ot->poll= ptcache_bake_cloth_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/**************************** particles **********************************/
+static int ptcache_bake_particle_system_poll(bContext *C)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+
+	if(!scene || !ob || ob->id.lib)
+		return 0;
+	
+	return (ob->particlesystem.first != NULL);
+}
+
+static int ptcache_bake_particle_system_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ParticleSystem *psys =psys_get_current(ob);
+	PTCacheID pid;
+	PTCacheBaker baker;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+
+	baker.scene = scene;
+	baker.pid = &pid;
+	baker.bake = RNA_boolean_get(op->ptr, "bake");
+	baker.render = 0;
+	baker.quick_step = 1;
+	baker.break_test = cache_break_test;
+	baker.break_data = NULL;
+	baker.progressbar = (void (*)(void *, int))WM_timecursor;
+	baker.progresscontext = CTX_wm_window(C);
+
+	BKE_ptcache_make_cache(&baker);
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_particle_system_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ParticleSystem *psys= psys_get_current(ob);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+	psys->pointcache->flag &= ~PTCACHE_BAKED;
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_particle_system(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake Particles";
+	ot->idname= "PTCACHE_OT_cache_particle_system";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_particle_system_exec;
+	ot->poll= ptcache_bake_particle_system_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_particle_system(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Free Particles Bake";
+	ot->idname= "PTCACHE_OT_free_bake_particle_system";
+	
+	/* api callbacks */
+	ot->exec= ptcache_free_bake_particle_system_exec;
+	ot->poll= ptcache_bake_particle_system_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_particles_cache_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_active_object(C);
+	ParticleSystem *psys= psys_get_current(ob);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+	psys->pointcache->flag |= PTCACHE_BAKED;
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_particles_cache(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake From Cache";
+	ot->idname= "PTCACHE_OT_bake_from_particles_cache";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_from_particles_cache_exec;
+	ot->poll= ptcache_bake_particle_system_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/**************************** registration **********************************/
+
+void ED_operatortypes_pointcache(void)
+{
+	WM_operatortype_append(PTCACHE_OT_bake_all);
+	WM_operatortype_append(PTCACHE_OT_free_bake_all);
+	WM_operatortype_append(PTCACHE_OT_cache_particle_system);
+	WM_operatortype_append(PTCACHE_OT_free_bake_particle_system);
+	WM_operatortype_append(PTCACHE_OT_bake_from_particles_cache);
+	WM_operatortype_append(PTCACHE_OT_cache_cloth);
+	WM_operatortype_append(PTCACHE_OT_free_bake_cloth);
+	WM_operatortype_append(PTCACHE_OT_bake_from_cloth_cache);
+}
+
+//void ED_keymap_pointcache(wmWindowManager *wm)
+//{
+//	ListBase *keymap= WM_keymap_listbase(wm, "Pointcache", 0, 0);
+//	
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0);
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0);
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0);
+//}
+
diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c
index b6625cb387c..1b6b5b43522 100644
--- a/source/blender/editors/physics/editparticle.c
+++ b/source/blender/editors/physics/editparticle.c
@@ -1,5 +1,5 @@
 /*
- * $Id: editparticle.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -225,7 +225,7 @@ void PE_hide_keys_time(Scene *scene, ParticleSystem *psys, float cfra)
 	ParticleEditSettings *pset=PE_settings(scene);
 	int i, k, totpart= psys->totpart;
 
-	if(pset->draw_timed && scene->selectmode==SCE_SELECT_POINT) {
+	if(pset->draw_timed && pset->selectmode==SCE_SELECT_POINT) {
 		LOOP_PARTICLES(i, pa) {
 			LOOP_KEYS(k, key) {
 				if(fabs(cfra-*key->time) < pset->draw_timed)
@@ -425,11 +425,12 @@ static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest)
 	ParticleEdit *edit= psys->edit;
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(data->scene);
 	int i, k, totpart, nearest_pa, nearest_key;
 	float dist= data->rad;
 
 	/* in path select mode we have no keys */
-	if(data->scene->selectmode==SCE_SELECT_PATH)
+	if(pset->selectmode==SCE_SELECT_PATH)
 		return;
 
 	totpart= psys->totpart;
@@ -439,7 +440,7 @@ static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest)
 	LOOP_PARTICLES(i, pa) {
 		if(pa->flag & PARS_HIDE) continue;
 
-		if(data->scene->selectmode == SCE_SELECT_END) {
+		if(pset->selectmode == SCE_SELECT_END) {
 			/* only do end keys */
 			key= edit->keys[i] + pa->totkey-1;
 
@@ -481,18 +482,19 @@ static void foreach_mouse_hit_particle(PEData *data, ForParticleFunc func, int s
 	ParticleSystem *psys= data->psys;
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(data->scene);
 	int i, k, totpart;
 
 	totpart= psys->totpart;
 
 	/* all is selected in path mode */
-	if(data->scene->selectmode==SCE_SELECT_PATH)
+	if(pset->selectmode==SCE_SELECT_PATH)
 		selected=0;
 
 	LOOP_PARTICLES(i, pa) {
 		if(pa->flag & PARS_HIDE) continue;
 
-		if(data->scene->selectmode==SCE_SELECT_END) {
+		if(pset->selectmode==SCE_SELECT_END) {
 			/* only do end keys */
 			key= psys->edit->keys[i] + pa->totkey-1;
 
@@ -522,6 +524,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 	ParticleData *pa;
 	ParticleEditKey *key;
 	ParticleSystemModifierData *psmd=0;
+	ParticleEditSettings *pset= PE_settings(data->scene);
 	int i, k, totpart;
 	float mat[4][4], imat[4][4];
 
@@ -529,7 +532,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 	totpart= psys->totpart;
 
 	/* all is selected in path mode */
-	if(data->scene->selectmode==SCE_SELECT_PATH)
+	if(pset->selectmode==SCE_SELECT_PATH)
 		selected= 0;
 
 	Mat4One(imat);
@@ -541,7 +544,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 		psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, pa, mat);
 		Mat4Invert(imat,mat);
 
-		if(data->scene->selectmode==SCE_SELECT_END) {
+		if(pset->selectmode==SCE_SELECT_END) {
 			/* only do end keys */
 			key= psys->edit->keys[i] + pa->totkey-1;
 
@@ -610,6 +613,7 @@ static int count_selected_keys(Scene *scene, ParticleSystem *psys)
 {
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(scene);
 	int i, k, totpart, sel= 0;
 
 	totpart= psys->totpart;
@@ -619,12 +623,12 @@ static int count_selected_keys(Scene *scene, ParticleSystem *psys)
 
 		key= psys->edit->keys[i];
 
-		if(scene->selectmode==SCE_SELECT_POINT) {
+		if(pset->selectmode==SCE_SELECT_POINT) {
 			for(k=0; ktotkey; k++,key++)
 				if(key->flag & PEK_SELECT)
 					sel++;
 		}
-		else if(scene->selectmode==SCE_SELECT_END) {
+		else if(pset->selectmode==SCE_SELECT_END) {
 			key += pa->totkey-1;
 
 			if(key->flag & PEK_SELECT)
@@ -1454,6 +1458,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select)
 	ParticleEdit *edit;
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(scene);
 	float co[3], mat[4][4];
 	short vertco[2];
 	int i, k, totpart;
@@ -1470,7 +1475,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select)
 
 		psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
 
-		if(scene->selectmode==SCE_SELECT_POINT) {
+		if(pset->selectmode==SCE_SELECT_POINT) {
 			LOOP_KEYS(k, key) {
 				VECCOPY(co, key->co);
 				Mat4MulVecfl(mat, co);
@@ -1487,7 +1492,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select)
 				}
 			}
 		}
-		else if(scene->selectmode==SCE_SELECT_END) {
+		else if(pset->selectmode==SCE_SELECT_END) {
 			key= edit->keys[i] + pa->totkey - 1;
 
 			VECCOPY(co, key->co);
@@ -2349,7 +2354,7 @@ enum { DEL_PARTICLE, DEL_KEY };
 static EnumPropertyItem delete_type_items[]= {
 	{DEL_PARTICLE, "PARTICLE", 0, "Particle", ""},
 	{DEL_KEY, "KEY", 0, "Key", ""},
-	{0, NULL, NULL}};
+	{0, NULL, 0, NULL, NULL}};
 
 static void set_delete_particle(PEData *data, int pa_index)
 {
@@ -3842,6 +3847,7 @@ void PE_change_act_psys(Scene *scene, Object *ob, ParticleSystem *psys)
 static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene= CTX_data_scene(C);
+	ParticleEditSettings *pset=PE_settings(scene);
 	uiPopupMenu *pup;
 	uiLayout *layout;
 
@@ -3849,7 +3855,7 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
 	layout= uiPupMenuLayout(pup);
 
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey");
-	if(scene->selectmode & SCE_SELECT_POINT) {
+	if(pset->selectmode & SCE_SELECT_POINT) {
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide");
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first");
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last");
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index cbc94b3a058..e03649575cb 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -1,5 +1,5 @@
 /*
- * $Id: physics_intern.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/preview/Makefile b/source/blender/editors/preview/Makefile
index c44da6753f3..48e1dc64673 100644
--- a/source/blender/editors/preview/Makefile
+++ b/source/blender/editors/preview/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c
index 1ce20fcb0af..1efa5108b96 100644
--- a/source/blender/editors/preview/previewrender.c
+++ b/source/blender/editors/preview/previewrender.c
@@ -114,46 +114,12 @@ typedef struct ShaderPreview {
 	ID *id;
 	
 	int sizex, sizey;
+	int *pr_rect;
 	int pr_method;
 	
 } ShaderPreview;
 
 
-static void set_previewrect(ScrArea *sa, RenderInfo *ri)
-{
-	ARegion *ar= NULL; // XXX
-	rctf viewplane;
-	
-	BLI_init_rctf(&viewplane, PR_XMIN, PR_XMAX, PR_YMIN, PR_YMAX);
-
-//	ui_graphics_to_window_rct(ar->win, &viewplane, &ri->disprect);
-	
-	/* correction for gla draw */
-	BLI_translate_rcti(&ri->disprect, -ar->winrct.xmin, -ar->winrct.ymin);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	
-	glaDefine2DArea(&ar->winrct);
-
-	ri->pr_rectx= (ri->disprect.xmax-ri->disprect.xmin);
-	ri->pr_recty= (ri->disprect.ymax-ri->disprect.ymin);
-}
-
-static void end_previewrect(ARegion *ar)
-{
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-	
-	// restore viewport / scissor which was set by glaDefine2DArea
-	glViewport(ar->winrct.xmin, ar->winrct.ymin, ar->winx, ar->winy);
-	glScissor(ar->winrct.xmin, ar->winrct.ymin, ar->winx, ar->winy);
-
-}
 
 /* unused now */
 void draw_tex_crop(Tex *tex)
@@ -438,196 +404,6 @@ static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp
 	return NULL;
 }
 
-void previewrender_progress(void *handle, RenderResult *rr, volatile rcti *renrect)
-{
-	SpaceButs *sbuts= NULL; // XXX
-	RenderLayer *rl;
-	RenderInfo *ri= sbuts->ri;
-	float ofsx, ofsy;
-	
-	if(renrect) return;
-	
-	rl= rr->layers.first;
-	
-	ofsx= ri->disprect.xmin + rr->tilerect.xmin;
-	ofsy= ri->disprect.ymin + rr->tilerect.ymin;
-	
-	glDrawBuffer(GL_FRONT);
-	glaDrawPixelsSafe_to32(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, rl->rectf);
-	bglFlush();
-	glDrawBuffer(GL_BACK);
-}
-
-
-/* called by interface_icons.c, or by BIF_previewrender_buts or by nodes... */
-void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method)
-{
-	SpaceButs *sbuts= NULL; // XXX
-	Render *re;
-	RenderStats *rstats;
-	Scene *sce;
-	int oldx= ri->pr_rectx, oldy= ri->pr_recty;
-	char name [32];
-	
-	if(ri->tottile && ri->curtile>=ri->tottile) return;
-	
-	/* check for return with a new event */
-	if(pr_method!=PR_ICON_RENDER && qtest()) {
-//		if(area)
-//			addafterqueue(area->win, RENDERPREVIEW, 1);
-		return;
-	}
-	
-	/* get the stuff from the builtin preview dbase */
-//	sce= preview_prepare_scene(scene, ri, GS(id->name), id, pr_method);
-	if(sce==NULL) return;
-	
-	/* set drawing conditions OK */
-	if(area) {
-		sbuts= area->spacedata.first;	/* needed for flag */
-		
-		set_previewrect(area, ri); // uses UImat
-		
-		/* because preview render size can differs */
-		if(ri->rect && (oldx!=ri->pr_rectx || oldy!=ri->pr_recty)) {
-			MEM_freeN(ri->rect);
-			ri->rect= NULL;
-			ri->curtile= 0;
-		}
-	}
-	
-// XXX	sprintf(name, "ButsPreview %d", area?area->win:0);
-	re= RE_GetRender(name);
-	
-	/* full refreshed render from first tile */
-	if(re==NULL || ri->curtile==0) {
-		
-		re= RE_NewRender(name);
-		
-		/* handle cases */
-		if(pr_method==PR_DRAW_RENDER) {
-//			RE_display_draw_cb(re, previewrender_progress);
-//			RE_test_break_cb(re, qtest);
-			sce->r.scemode |= R_NODE_PREVIEW;
-			if(sbuts->flag & SB_PRV_OSA)
-				sce->r.mode |= R_OSA;
-			sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-		}
-		else if(pr_method==PR_DO_RENDER) {
-//			RE_test_break_cb(re, qtest);
-			sce->r.scemode |= R_NODE_PREVIEW;
-			sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-		}
-		else {	/* PR_ICON_RENDER */
-			sce->r.scemode &= ~R_NODE_PREVIEW;
-			sce->r.scemode |= R_NO_IMAGE_LOAD;
-		}
-		
-		/* allocates render result */
-		RE_InitState(re, NULL, &sce->r, ri->pr_rectx, ri->pr_recty, NULL);
-		
-		/* enforce preview image clear */
-		if(GS(id->name)==ID_MA) {
-			Material *ma= (Material *)id;
-			ntreeClearPreview(ma->nodetree);
-		}
-	}
-	/* entire cycle for render engine */
-	RE_SetCamera(re, sce->camera);
-	RE_Database_FromScene(re, sce, 1);
-	RE_TileProcessor(re, ri->curtile, 0);	// actual render engine
-	RE_Database_Free(re);
-	
-	/* handle results */
-	if(pr_method==PR_ICON_RENDER) {
-		if(ri->rect==NULL)
-			ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-		RE_ResultGet32(re, ri->rect);
-	}
-	else {
-		rstats= RE_GetStats(re);
-		
-		if(rstats->partsdone!=ri->curtile) {
-			if(ri->rect==NULL)
-				ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-			RE_ResultGet32(re, ri->rect);
-		}
-		
-		if(rstats->totpart==rstats->partsdone && rstats->partsdone) {
-			// allqueues
-		}
-		else {
-//			if(pr_method==PR_DRAW_RENDER && qtest())
-//				addafterqueue(area->win, RENDERPREVIEW, 1);
-		}
-		
-		ri->curtile= rstats->partsdone;
-		ri->tottile= rstats->totpart;
-	}
-
-	/* unassign the pointers, reset vars */
-//	preview_prepare_scene(scene, ri, GS(id->name), NULL, 0);
-	
-}
-
-
-/* afterqueue call */
-void BIF_previewrender_buts(Scene *scene, SpaceButs *sbuts)
-{
-//	ScrArea *sa= NULL; // XXX
-	ARegion *ar= NULL; // XXX
-	uiBlock *block;
-	struct ID* id = 0;
-//	struct ID* idfrom = 0;
-	struct ID* idshow = 0;
-	Object *ob;
-	
-	if (!sbuts->ri) return;
-	
-	
-//	block= uiFindOpenPanelBlockName(&sa->uiblocks, "Preview");
-	if(block==NULL) return;
-	
-	ob= ((scene->basact)? (scene->basact)->object: 0);
-	
-	/* we cant trust this global lockpoin.. for example with headerless window */
-//	buttons_active_id(&id, &idfrom);
-	sbuts->lockpoin= id;
-	
-	if(sbuts->mainb==CONTEXT_SHADING) {
-		int tab= TAB_SHADING_MAT; // XXX sbuts->tab[CONTEXT_SHADING];
-		
-		if(tab==TAB_SHADING_MAT) 
-			idshow = sbuts->lockpoin;
-		else if(tab==TAB_SHADING_TEX) 
-			idshow = sbuts->lockpoin;
-		else if(tab==TAB_SHADING_LAMP) {
-			if(ob && ob->type==OB_LAMP) idshow= ob->data;
-		}
-		else if(tab==TAB_SHADING_WORLD)
-			idshow = sbuts->lockpoin;
-	}
-	else if(sbuts->mainb==CONTEXT_OBJECT) {
-		if(ob && ob->type==OB_LAMP) idshow = ob->data;
-	}
-	
-	if (idshow) {
-		BKE_icon_changed(BKE_icon_getid(idshow));
-//		uiPanelPush(block);
-//		BIF_previewrender(scene, idshow, sbuts->ri, sbuts->area, PR_DRAW_RENDER);
-//		uiPanelPop(block);
-		end_previewrect(ar);
-	}
-	else {
-		/* no active block to draw. But we do draw black if possible */
-		if(sbuts->ri->rect) {
-			memset(sbuts->ri->rect, 0, sizeof(int)*sbuts->ri->pr_rectx*sbuts->ri->pr_recty);
-			sbuts->ri->tottile= 10000;
-//			addqueue(sa->win, REDRAW, 1);
-		}
-		return;
-	}
-}
 
 /* new UI convention: draw is in pixel space already. */
 /* uses ROUNDBOX button in block to get the rect */
@@ -1006,7 +782,7 @@ static void shader_preview_updatejob(void *spv)
 	
 }
 
-/* runs inside thread */
+/* runs inside thread for material, in foreground for icons */
 static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
 {
 	ShaderPreview *sp= customdata;
@@ -1064,9 +840,8 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
 
 	/* handle results */
 	if(sp->pr_method==PR_ICON_RENDER) {
-		//if(ri->rect==NULL)
-		//	ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-		//RE_ResultGet32(re, ri->rect);
+		if(sp->pr_rect)
+			RE_ResultGet32(re, sp->pr_rect);
 	}
 	else {
 		/* validate owner */
@@ -1113,6 +888,29 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in
 	WM_jobs_callbacks(steve, shader_preview_startjob, NULL, shader_preview_updatejob);
 	
 	WM_jobs_start(CTX_wm_manager(C), steve);
+	
+	/* signal to rerender icon in menus */
+	BKE_icon_changed(BKE_icon_getid(id));
 }
 
+/* rect should be allocated, sizex/sizy pixels, 32 bits */
+void ED_preview_iconrender(Scene *scene, ID *id, int *rect, int sizex, int sizey)
+{
+	ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
+	short stop=0, do_update=0;
+	
+	/* customdata for preview thread */
+	sp->scene= scene;
+	sp->sizex= sizex;
+	sp->sizey= sizey;
+	sp->pr_method= PR_ICON_RENDER;
+	sp->pr_rect= rect;
+	sp->id = id;
+
+	shader_preview_startjob(sp, &stop, &do_update);
+	
+	MEM_freeN(sp);
+}
+
+
 
diff --git a/source/blender/editors/screen/Makefile b/source/blender/editors/screen/Makefile
index cf6e692c304..923a020afcf 100644
--- a/source/blender/editors/screen/Makefile
+++ b/source/blender/editors/screen/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 07d8fb370e6..535e99ccfef 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -259,14 +259,16 @@ static void region_scissor_winrct(ARegion *ar, rcti *winrct)
 	while(ar->prev) {
 		ar= ar->prev;
 		
-		if(ar->flag & RGN_FLAG_HIDDEN);
-		else if(ar->alignment==RGN_OVERLAP_LEFT) {
-			winrct->xmin= ar->winrct.xmax + 1;
-		}
-		else if(ar->alignment==RGN_OVERLAP_RIGHT) {
-			winrct->xmax= ar->winrct.xmin - 1;
+		if(BLI_isect_rcti(winrct, &ar->winrct, NULL)) {
+			if(ar->flag & RGN_FLAG_HIDDEN);
+			else if(ar->alignment==RGN_OVERLAP_LEFT) {
+				winrct->xmin= ar->winrct.xmax + 1;
+			}
+			else if(ar->alignment==RGN_OVERLAP_RIGHT) {
+				winrct->xmax= ar->winrct.xmin - 1;
+			}
+			else break;
 		}
-		else break;
 	}
 }
 
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index a81a52fd544..a23487effa1 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -1,5 +1,5 @@
 /**
- * $Id: glutil.c 11920 2007-09-02 17:25:03Z elubie $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 2aa6758850e..dcfdfbf8285 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -59,6 +59,7 @@
 #include "ED_util.h"
 #include "ED_screen.h"
 #include "ED_mesh.h"
+#include "ED_object.h"
 #include "ED_screen_types.h"
 
 #include "RE_pipeline.h"
@@ -2509,7 +2510,9 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
 	/* flush multires changes (for sculpt) */
 	multires_force_update(CTX_data_active_object(C));
 	
-	// get editmode results
+	/* get editmode results */
+	ED_object_exit_editmode(C, 0);	/* 0 = does not exit editmode */
+	
 	// store spare
 	// get view3d layer, local layer, make this nice api call to render
 	// store spare
diff --git a/source/blender/editors/sculpt_paint/Makefile b/source/blender/editors/sculpt_paint/Makefile
index 9353116a4bc..012a39b8d25 100644
--- a/source/blender/editors/sculpt_paint/Makefile
+++ b/source/blender/editors/sculpt_paint/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index fa33e214737..a2b883eabfc 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1,5 +1,5 @@
 /*
- * $Id: sculptmode.c 18309 2009-01-04 07:47:11Z nicholasbishop $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -148,6 +148,7 @@ typedef struct StrokeCache {
 	float *layer_disps; /* Displacements for each vertex */
  	float (*mesh_store)[3]; /* Copy of the mesh vertices' locations */
 	short (*orig_norms)[3]; /* Copy of the mesh vertices' normals */
+	float (*face_norms)[3]; /* Copy of the mesh faces' normals */
 	float rotation; /* Texture rotation (radians) for anchored and rake modes */
 	int pixel_radius, previous_pixel_radius;
 	ListBase grab_active_verts[8]; /* The same list of verts is used throught grab stroke */
@@ -155,7 +156,6 @@ typedef struct StrokeCache {
 	float old_grab_location[3];
 	int symmetry; /* Symmetry index between 0 and 7 */
 	float view_normal[3], view_normal_symmetry[3];
-	int last_dot[2]; /* Last location of stroke application */
 	int last_rake[2]; /* Last location of updating rake rotation */
 } StrokeCache;
 
@@ -240,7 +240,6 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
 	float dir= sd->brush->flag & BRUSH_DIR_IN ? -1 : 1;
 	float pressure= 1;
 	float flip= cache->flip ? -1:1;
-	float anchored = sd->brush->flag & BRUSH_ANCHORED ? 25 : 1;
 
 	if(sd->brush->flag & BRUSH_ALPHA_PRESSURE)
 		pressure *= cache->pressure;
@@ -250,6 +249,7 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
 	case SCULPT_TOOL_INFLATE:
 	case SCULPT_TOOL_CLAY:
 	case SCULPT_TOOL_FLATTEN:
+	case SCULPT_TOOL_LAYER:
 		return alpha * dir * pressure * flip; /*XXX: not sure why? was multiplied by G.vd->grid */;
 	case SCULPT_TOOL_SMOOTH:
 		return alpha * 4 * pressure;
@@ -257,46 +257,27 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
 		return alpha / 2 * dir * pressure * flip;
 	case SCULPT_TOOL_GRAB:
 		return 1;
-	case SCULPT_TOOL_LAYER:
-		return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */;
 	default:
 		return 0;
 	}
 }
 
-/* For clipping against a mirror modifier */
-static void sculpt_clip(StrokeCache *cache, float *co, const float val[3])
+/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */
+static void sculpt_clip(Sculpt *sd, float *co, const float val[3])
 {
 	int i;
+
 	for(i=0; i<3; ++i) {
-		if((cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= cache->clip_tolerance[i]))
+		if(sd->flags & (SCULPT_LOCK_X << i))
+			continue;
+
+		if((sd->session->cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= sd->session->cache->clip_tolerance[i]))
 			co[i]= 0.0f;
 		else
 			co[i]= val[i];
 	}		
 }
 
-static void sculpt_axislock(Sculpt *sd, float *co)
-{
-	if(sd->flags == (SCULPT_LOCK_X|SCULPT_LOCK_Y|SCULPT_LOCK_Z))
-		return;
-
-	if(sd->session->cache->vc.v3d->twmode == V3D_MANIP_LOCAL) {
-		float mat[3][3], imat[3][3];
-		Mat3CpyMat4(mat, sd->session->cache->vc.obact->obmat);
-		Mat3Inv(imat, mat);
-		Mat3MulVecfl(mat, co);
-		if (sd->flags & SCULPT_LOCK_X) co[0] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Y) co[1] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Z) co[2] = 0.0;		
-		Mat3MulVecfl(imat, co);
-	} else {
-		if (sd->flags & SCULPT_LOCK_X) co[0] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Y) co[1] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Z) co[2] = 0.0;		
-	}
-}
-
 static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], const short no[3])
 {
 	float fno[3] = {no[0], no[1], no[2]};
@@ -353,8 +334,6 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
 
 	calc_area_normal(sd, area_normal, active_verts);
 	
-	sculpt_axislock(sd, area_normal);
-	
 	while(node){
 		float *co= ss->mvert[node->Index].co;
 
@@ -362,7 +341,7 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
 		                     co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1],
 		                     co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]};
 		                     
-		sculpt_clip(ss->cache, co, val);
+		sculpt_clip(sd, co, val);
 		
 		node= node->next;
 	}
@@ -412,37 +391,37 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert)
 		VecCopyf(avg, ss->mvert[vert].co);
 }
 
-static void do_smooth_brush(SculptSession *ss, const ListBase* active_verts)
+static void do_smooth_brush(Sculpt *s, const ListBase* active_verts)
 {
 	ActiveData *node= active_verts->first;
 	int i;
 	
 	for(i = 0; i < 2; ++i) {
 		while(node){
-			float *co= ss->mvert[node->Index].co;
+			float *co= s->session->mvert[node->Index].co;
 			float avg[3], val[3];
 			
-			neighbor_average(ss, avg, node->Index);
+			neighbor_average(s->session, avg, node->Index);
 			val[0] = co[0]+(avg[0]-co[0])*node->Fade;
 			val[1] = co[1]+(avg[1]-co[1])*node->Fade;
 			val[2] = co[2]+(avg[2]-co[2])*node->Fade;
 			
-			sculpt_clip(ss->cache, co, val);
+			sculpt_clip(s, co, val);
 			node= node->next;
 		}
 	}
 }
 
-static void do_pinch_brush(SculptSession *ss, const ListBase* active_verts)
+static void do_pinch_brush(Sculpt *s, const ListBase* active_verts)
 {
  	ActiveData *node= active_verts->first;
 
 	while(node) {
-		float *co= ss->mvert[node->Index].co;
-		const float val[3]= {co[0]+(ss->cache->location[0]-co[0])*node->Fade,
-		                     co[1]+(ss->cache->location[1]-co[1])*node->Fade,
-		                     co[2]+(ss->cache->location[2]-co[2])*node->Fade};
-		sculpt_clip(ss->cache, co, val);
+		float *co= s->session->mvert[node->Index].co;
+		const float val[3]= {co[0]+(s->session->cache->location[0]-co[0])*node->Fade,
+		                     co[1]+(s->session->cache->location[1]-co[1])*node->Fade,
+		                     co[2]+(s->session->cache->location[2]-co[2])*node->Fade};
+		sculpt_clip(s, co, val);
 		node= node->next;
 	}
 }
@@ -454,7 +433,6 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
 	float grab_delta[3];
 	
 	VecCopyf(grab_delta, ss->cache->grab_delta_symmetry);
-	sculpt_axislock(sd, grab_delta);
 	
 	while(node) {
 		float *co= ss->mvert[node->Index].co;
@@ -462,7 +440,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
 		VecCopyf(add, grab_delta);
 		VecMulf(add, node->Fade);
 		VecAddf(add, add, co);
-		sculpt_clip(ss->cache, co, add);
+		sculpt_clip(sd, co, add);
 
 		node= node->next;
 	}
@@ -473,42 +451,38 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
 {
 	float area_normal[3];
 	ActiveData *node= active_verts->first;
-	float lim= brush_strength(sd, ss->cache);
+	float lim= ss->cache->radius / 4;
 
-	if(sd->brush->flag & BRUSH_DIR_IN)
+	if(ss->cache->flip)
 		lim = -lim;
 
 	calc_area_normal(sd, area_normal, active_verts);
 
 	while(node){
 		float *disp= &ss->cache->layer_disps[node->Index];
+		float *co= ss->mvert[node->Index].co;
+		float val[3];
 		
-		if((lim > 0 && *disp < lim) ||
-		   (lim < 0 && *disp > lim)) {
-		  	float *co= ss->mvert[node->Index].co;
-			float val[3];
-		  	
-			*disp+= node->Fade;
-
-			if(lim < 0 && *disp < lim)
-				*disp = lim;
-			else if(lim > 0 && *disp > lim)
-					*disp = lim;
-
-			val[0] = ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0];
-			val[1] = ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
-			val[2] = ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
-			//VecMulf(val, ss->cache->radius);
-			sculpt_clip(ss->cache, co, val);
-		}
+		*disp+= node->Fade;
+		
+		/* Don't let the displacement go past the limit */
+		if((lim < 0 && *disp < lim) || (lim > 0 && *disp > lim))
+			*disp = lim;
+		
+		val[0] = ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0];
+		val[1] = ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
+		val[2] = ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
+
+		sculpt_clip(sd, co, val);
 
 		node= node->next;
 	}
 }
 
-static void do_inflate_brush(SculptSession *ss, const ListBase *active_verts)
+static void do_inflate_brush(Sculpt *s, const ListBase *active_verts)
 {
 	ActiveData *node= active_verts->first;
+	SculptSession *ss = s->session;
 	float add[3];
 	
 	while(node) {
@@ -524,7 +498,7 @@ static void do_inflate_brush(SculptSession *ss, const ListBase *active_verts)
 		add[2]*= ss->cache->scale[2];
 		VecAddf(add, add, co);
 		
-		sculpt_clip(ss->cache, co, add);
+		sculpt_clip(s, co, add);
 
 		node= node->next;
 	}
@@ -587,7 +561,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
 			VecAddf(val, val, tmp);
 		}
 
-		sculpt_clip(ss->cache, co, val);
+		sculpt_clip(sd, co, val);
 		
 		node= node->next;
 	}
@@ -763,37 +737,6 @@ static void sculpt_add_damaged_rect(SculptSession *ss)
 	}
 }
 
-/* Clears the depth buffer in each modified area. */
-#if 0
-static void sculpt_clear_damaged_areas(SculptSession *ss)
-{
-	RectNode *rn= NULL;
-
-	for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
-		rcti clp = rn->r;
-		rcti *win = NULL; /*XXX: &curarea->winrct; */
-		
-		clp.xmin += win->xmin;
-		clp.xmax += win->xmin;
-		clp.ymin += win->ymin;
-		clp.ymax += win->ymin;
-		
-		if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
-		   clp.ymin < win->ymax && clp.ymax > win->ymin) {
-			if(clp.xmin < win->xmin) clp.xmin = win->xmin;
-			if(clp.ymin < win->ymin) clp.ymin = win->ymin;
-			if(clp.xmax > win->xmax) clp.xmax = win->xmax;
-			if(clp.ymax > win->ymax) clp.ymax = win->ymax;
-
-			glScissor(clp.xmin + 1, clp.ymin + 1,
-				  clp.xmax - clp.xmin - 2,
-				  clp.ymax - clp.ymin - 2);
-		}
-		
-		glClear(GL_DEPTH_BUFFER_BIT);
-	}
-}
-#endif
 static void do_brush_action(Sculpt *sd, StrokeCache *cache)
 {
 	SculptSession *ss = sd->session;
@@ -845,13 +788,13 @@ static void do_brush_action(Sculpt *sd, StrokeCache *cache)
 			do_draw_brush(sd, ss, &active_verts);
 			break;
 		case SCULPT_TOOL_SMOOTH:
-			do_smooth_brush(ss, &active_verts);
+			do_smooth_brush(sd, &active_verts);
 			break;
 		case SCULPT_TOOL_PINCH:
-			do_pinch_brush(ss, &active_verts);
+			do_pinch_brush(sd, &active_verts);
 			break;
 		case SCULPT_TOOL_INFLATE:
-			do_inflate_brush(ss, &active_verts);
+			do_inflate_brush(sd, &active_verts);
 			break;
 		case SCULPT_TOOL_GRAB:
 			do_grab_brush(sd, ss);
@@ -905,15 +848,6 @@ static void do_symmetrical_brush_actions(Sculpt *sd, StrokeCache *cache)
 	const char symm = sd->flags & 7;
 	int i;
 
-	/* Brush spacing: only apply dot if next dot is far enough away */
-	if((sd->brush->flag & BRUSH_SPACE) && !(sd->brush->flag & BRUSH_ANCHORED) && !cache->first_time) {
-		int dx = cache->last_dot[0] - cache->mouse[0];
-		int dy = cache->last_dot[1] - cache->mouse[1];
-		if(sqrt(dx*dx+dy*dy) < sd->brush->spacing)
-			return;
-	}
-	memcpy(cache->last_dot, cache->mouse, sizeof(int) * 2);
-
 	VecCopyf(cache->location, cache->true_location);
 	VecCopyf(cache->grab_delta_symmetry, cache->grab_delta);
 	cache->symmetry = 0;
@@ -1012,25 +946,6 @@ static void sculpt_update_tex(Sculpt *sd)
 	}
 }
 
-void sculptmode_selectbrush_menu(void)
-{
-	/* XXX: I guess menus belong elsewhere too?
-
-	Sculpt *sd= sculpt_data();
-	int val;
-	
-	pupmenu_set_active(sd->brush_type);
-	
-	val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
-
-	if(val>0) {
-		sd->brush_type= val;
-
-		allqueue(REDRAWVIEW3D, 1);
-		allqueue(REDRAWBUTSEDIT, 1);
-	}*/
-}
-
 static void sculptmode_update_all_projverts(SculptSession *ss)
 {
 	unsigned i;
@@ -1109,89 +1024,11 @@ static void sculpt_update_mesh_elements(bContext *C)
 	}
 }
 
-/* XXX: lots of drawing code (partial redraw), has to go elsewhere */
-#if 0
-void sculptmode_draw_wires(SculptSession *ss, int only_damaged)
+static int sculpt_mode_poll(bContext *C)
 {
-	Mesh *me = get_mesh(OBACT);
-	int i;
-
-	bglPolygonOffset(1.0);
-	glDepthMask(0);
-	BIF_ThemeColor((OBACT==OBACT)?TH_ACTIVE:TH_SELECT);
-
-	for(i=0; itotedge; i++) {
-		MEdge *med= &me->medge[i];
-
-		if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
-		   (med->flag & ME_EDGEDRAW)) {
-			glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
-		}
-	}
-
-	glDepthMask(1);
-	bglPolygonOffset(0.0);
+	return G.f & G_SCULPTMODE;
 }
 
-void sculptmode_draw_mesh(int only_damaged) 
-{
-	int i, j, dt, drawCurrentMat = 1, matnr= -1;
-	SculptSession *ss = sculpt_session();
-
-	sculpt_update_mesh_elements(ss, OBACT);
-
-	persp(PERSP_VIEW);
-	mymultmatrix(OBACT->obmat);
-	glEnable(GL_DEPTH_TEST);
-	glEnable(GL_LIGHTING);
-	/* XXX: GPU_set_object_materials(G.scene, OBACT, 0, NULL); */
-	glEnable(GL_CULL_FACE);
-
-	glShadeModel(GL_SMOOTH);
-
-	glVertexPointer(3, GL_FLOAT, sizeof(MVert), &cache->mvert[0].co);
-	glNormalPointer(GL_SHORT, sizeof(MVert), &cache->mvert[0].no);
-
-	dt= MIN2(G.vd->drawtype, OBACT->dt);
-	if(dt==OB_WIRE)
-		glColorMask(0,0,0,0);
-
-	for(i=0; itotface; ++i) {
-		MFace *f= &ss->mface[i];
-		char inside= 0;
-		int new_matnr= f->mat_nr + 1;
-		
-		if(new_matnr != matnr)
-			drawCurrentMat= GPU_enable_material(matnr = new_matnr, NULL);
-		
-		/* If only_damaged!=0, only draw faces that are partially
-		   inside the area(s) modified by the brush */
-		if(only_damaged) {
-			for(j=0; j<(f->v4?4:3); ++j) {
-				if(ss->projverts[*((&f->v1)+j)].inside) {
-					inside= 1;
-					break;
-				}
-			}
-		}
-		else
-			inside= 1;
-			
-		if(inside && drawCurrentMat)
-			glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
-	}
-
-	glDisable(GL_CULL_FACE);
-	glDisable(GL_LIGHTING);
-	glColorMask(1,1,1,1);
-
-	if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
-		sculptmode_draw_wires(ss, only_damaged);
-
-	glDisable(GL_DEPTH_TEST);
-}
-#endif
-
 static int sculpt_poll(bContext *C)
 {
 	return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
@@ -1203,16 +1040,21 @@ static void draw_paint_cursor(bContext *C, int x, int y, void *customdata)
 {
 	Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
 	
-	glTranslatef((float)x, (float)y, 0.0f);
-	
 	glColor4ub(255, 100, 100, 128);
 	glEnable( GL_LINE_SMOOTH );
 	glEnable(GL_BLEND);
+
+	glTranslatef((float)x, (float)y, 0.0f);
 	glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40);
+	glTranslatef((float)-x, (float)-y, 0.0f);
+
+	if(sd->session && sd->session->cache && sd->brush && (sd->brush->flag & BRUSH_SMOOTH_STROKE)) {
+		ARegion *ar = CTX_wm_region(C);
+		sdrawline(x, y, sd->session->cache->mouse[0] - ar->winrct.xmin, sd->session->cache->mouse[1] - ar->winrct.ymin);
+	}
+
 	glDisable(GL_BLEND);
 	glDisable( GL_LINE_SMOOTH );
-	
-	glTranslatef((float)-x, (float)-y, 0.0f);
 }
 
 static void toggle_paint_cursor(bContext *C)
@@ -1269,7 +1111,7 @@ static void SCULPT_OT_brush_curve_preset(wmOperatorType *ot)
 	ot->idname= "SCULPT_OT_brush_curve_preset";
 
 	ot->exec= sculpt_brush_curve_preset_exec;
-	ot->poll= sculpt_poll;
+	ot->poll= sculpt_mode_poll;
 
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
@@ -1334,6 +1176,8 @@ static void sculpt_cache_free(StrokeCache *cache)
 		MEM_freeN(cache->mesh_store);
 	if(cache->orig_norms)
 		MEM_freeN(cache->orig_norms);
+	if(cache->face_norms)
+		MEM_freeN(cache->face_norms);
 	if(cache->mats)
 		MEM_freeN(cache->mats);
 	MEM_freeN(cache);
@@ -1353,6 +1197,9 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
 	RNA_int_get_array(op->ptr, "initial_mouse", cache->initial_mouse);
 	cache->depth = RNA_float_get(op->ptr, "depth");
 
+	cache->mouse[0] = cache->initial_mouse[0];
+	cache->mouse[1] = cache->initial_mouse[1];
+
 	/* Truly temporary data that isn't stored in properties */
 
 	view3d_set_viewcontext(C, &cache->vc);
@@ -1362,9 +1209,11 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
 
 	sculpt_update_mesh_elements(C);
 
+	if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
+		cache->layer_disps = MEM_callocN(sizeof(float) * sd->session->totvert, "layer brush displacements");
+
 	/* Make copies of the mesh vertex locations and normals for some tools */
 	if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER || (sd->brush->flag & BRUSH_ANCHORED)) {
-		cache->layer_disps = MEM_callocN(sizeof(float) * sd->session->totvert, "layer brush displacements");
 		cache->mesh_store= MEM_mallocN(sizeof(float) * 3 * sd->session->totvert, "sculpt mesh vertices copy");
 		for(i = 0; i < sd->session->totvert; ++i)
 			VecCopyf(cache->mesh_store[i], sd->session->mvert[i].co);
@@ -1376,6 +1225,13 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
 				cache->orig_norms[i][1] = sd->session->mvert[i].no[1];
 				cache->orig_norms[i][2] = sd->session->mvert[i].no[2];
 			}
+
+			if(sd->session->face_normals) {
+				float *fn = sd->session->face_normals;
+				cache->face_norms= MEM_mallocN(sizeof(float) * 3 * sd->session->totface, "Sculpt face norms");
+				for(i = 0; i < sd->session->totface; ++i, fn += 3)
+					VecCopyf(cache->face_norms[i], fn);
+			}
 		}
 	}
 
@@ -1485,9 +1341,6 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
 	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
 
 	view3d_operator_needs_opengl(C);
-	sculpt_brush_stroke_init_properties(C, op, event, sd->session);
-
-	sculptmode_update_all_projverts(sd->session);
 
 	/* TODO: Shouldn't really have to do this at the start of every
 	   stroke, but sculpt would need some sort of notification when
@@ -1502,17 +1355,27 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
 
 static void sculpt_restore_mesh(Sculpt *sd)
 {
-	StrokeCache *cache = sd->session->cache;
+	SculptSession *ss = sd->session;
+	StrokeCache *cache = ss->cache;
 	int i;
 	
 	/* Restore the mesh before continuing with anchored stroke */
 	if((sd->brush->flag & BRUSH_ANCHORED) && cache->mesh_store) {
-		for(i = 0; i < sd->session->totvert; ++i) {
-			VecCopyf(sd->session->mvert[i].co, cache->mesh_store[i]);
-			sd->session->mvert[i].no[0] = cache->orig_norms[i][0];
-			sd->session->mvert[i].no[1] = cache->orig_norms[i][1];
-			sd->session->mvert[i].no[2] = cache->orig_norms[i][2];
+		for(i = 0; i < ss->totvert; ++i) {
+			VecCopyf(ss->mvert[i].co, cache->mesh_store[i]);
+			ss->mvert[i].no[0] = cache->orig_norms[i][0];
+			ss->mvert[i].no[1] = cache->orig_norms[i][1];
+			ss->mvert[i].no[2] = cache->orig_norms[i][2];
+		}
+
+		if(ss->face_normals) {
+			float *fn = ss->face_normals;
+			for(i = 0; i < ss->totface; ++i, fn += 3)
+				VecCopyf(fn, cache->face_norms[i]);
 		}
+
+		if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
+			memset(cache->layer_disps, 0, sizeof(float) * ss->totvert);
 	}
 }
 
@@ -1542,38 +1405,141 @@ static void sculpt_flush_update(bContext *C)
 	ED_region_tag_redraw(ar);
 }
 
-static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+/* Returns zero if no sculpt changes should be made, non-zero otherwise */
+static int sculpt_smooth_stroke(Sculpt *s, int output[2], wmEvent *event)
 {
-	PointerRNA itemptr;
-	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
-	float center[3];
-	int mouse[2] = {event->x, event->y};
+	output[0] = event->x;
+	output[1] = event->y;
 
-	sculpt_update_mesh_elements(C);
+	if(s->brush->flag & BRUSH_SMOOTH_STROKE && s->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
+		StrokeCache *cache = s->session->cache;
+		float u = .9, v = 1.0 - u;
+		int dx = cache->mouse[0] - event->x, dy = cache->mouse[1] - event->y;
+		int radius = 50;
+
+		/* If the mouse is moving within the radius of the last move,
+		   don't update the mouse position. This allows sharp turns. */
+		if(dx*dx + dy*dy < radius*radius)
+			return 0;
 
-	unproject(sd->session->cache->mats, center, event->x, event->y,
-		  read_cached_depth(&sd->session->cache->vc, event->x, event->y));
+		output[0] = event->x * v + cache->mouse[0] * u;
+		output[1] = event->y * v + cache->mouse[1] * u;
+	}
+
+	return 1;
+}
+
+/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
+int sculpt_space_stroke_enabled(Sculpt *s)
+{
+	Brush *br = s->brush;
+	return (br->flag & BRUSH_SPACE) && !(br->flag & BRUSH_ANCHORED) && (br->sculpt_tool != SCULPT_TOOL_GRAB);
+}
+
+/* Put the location of the next sculpt stroke dot into the stroke RNA and apply it to the mesh */
+static void sculpt_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, int mouse[2])
+{
+	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+	StrokeCache *cache = sd->session->cache;
+	PointerRNA itemptr;
+	float cur_depth;
+	float center[3];
 
+	cur_depth = read_cached_depth(&cache->vc, mouse[0], mouse[1]);
+	unproject(sd->session->cache->mats, center, mouse[0], mouse[1], cur_depth);
+				
 	/* Add to stroke */
 	RNA_collection_add(op->ptr, "stroke", &itemptr);
 	RNA_float_set_array(&itemptr, "location", center);
 	RNA_int_set_array(&itemptr, "mouse", mouse);
 	RNA_boolean_set(&itemptr, "flip", event->shift);
 	sculpt_update_cache_variants(sd, &itemptr);
-
+				
 	sculpt_restore_mesh(sd);
-	do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
-
-	sculpt_flush_update(C);
+	do_symmetrical_brush_actions(sd, cache);
+				
 	sculpt_post_stroke_free(sd->session);
+}
 
-	/* Finished */
-	if(event->type == LEFTMOUSE && event->val == 0) {
-		request_depth_update(sd->session->cache->vc.rv3d);
+/* For brushes with stroke spacing enabled, moves mouse in steps
+   towards the final mouse location. */
+static int sculpt_space_stroke(bContext *C, wmOperator *op, wmEvent *event, Sculpt *s, const int final_mouse[2])
+{
+	StrokeCache *cache = s->session->cache;
+	int cnt = 0;
+
+	if(sculpt_space_stroke_enabled(s)) {
+		float vec[2] = {final_mouse[0] - cache->mouse[0], final_mouse[1] - cache->mouse[1]};
+		int mouse[2] = {cache->mouse[0], cache->mouse[1]};
+		float length, scale;
+		int steps = 0, i;
+
+		/* Normalize the vector between the last stroke dot and the goal */
+		length = sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
+
+		if(length > FLT_EPSILON) {
+			scale = s->brush->spacing / length;
+			vec[0] *= scale;
+			vec[1] *= scale;
+
+			steps = (int)(length / s->brush->spacing);
+			for(i = 0; i < steps; ++i, ++cnt) {
+				mouse[0] += vec[0];
+				mouse[1] += vec[1];
+				sculpt_brush_stroke_add_step(C, op, event, mouse);
+			}
+		}
+	}
+
+	return cnt;
+}
+
+static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+	ARegion *ar = CTX_wm_region(C);
+	float cur_depth;
 
-		sculpt_cache_free(sd->session->cache);
+	sculpt_update_mesh_elements(C);
 
-		sculpt_undo_push(C, sd);
+	if(!sd->session->cache) {
+		ViewContext vc;
+		view3d_set_viewcontext(C, &vc);
+		cur_depth = read_cached_depth(&vc, event->x, event->y);
+
+		/* Don't start the stroke until a valid depth is found */
+		if(cur_depth < 1.0 - FLT_EPSILON) {
+			sculpt_brush_stroke_init_properties(C, op, event, sd->session);
+			sculptmode_update_all_projverts(sd->session);
+		}
+
+		ED_region_tag_redraw(ar);
+	}
+
+	if(sd->session->cache) {
+		int mouse[2];
+
+		if(sculpt_smooth_stroke(sd, mouse, event)) {
+			if(sculpt_space_stroke_enabled(sd)) {
+				if(!sculpt_space_stroke(C, op, event, sd, mouse))
+					ED_region_tag_redraw(ar);
+			}
+			else
+				sculpt_brush_stroke_add_step(C, op, event, mouse);
+			sculpt_flush_update(C);
+		}
+		else
+			ED_region_tag_redraw(ar);
+	}
+
+	/* Finished */
+	if(event->type == LEFTMOUSE && event->val == 0) {
+		if(sd->session->cache) {
+			request_depth_update(sd->session->cache->vc.rv3d);
+			sculpt_cache_free(sd->session->cache);
+			sd->session->cache = NULL;
+			sculpt_undo_push(C, sd);
+		}
 
 		return OPERATOR_FINISHED;
 	}
@@ -1717,454 +1683,3 @@ void ED_operatortypes_sculpt()
 	WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
 	WM_operatortype_append(SCULPT_OT_brush_curve_preset);
 }
-
-void sculpt(Sculpt *sd)
-{
-#if 0
-	SculptSession *ss= sd->session;
-	Object *ob= NULL; /*XXX */
-	Mesh *me;
-	MultiresModifierData *mmd = NULL;
-	/* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
-	short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
-	short modifier_calculations= 0;
-	BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
-	short spacing= 32000;
-	int scissor_box[4];
-	float offsetRot;
-	int smooth_stroke = 0, i;
-	int anchored, rake = 0 /* XXX: rake = ? */;
-
-	/* XXX: checking that sculpting is allowed
-	if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
-		return;
-	if(!(ob->lay & G.vd->lay))
-		error("Active object is not in this layer");
-	if(ob_get_keyblock(ob)) {
-		if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
-			error("Cannot sculpt on unlocked shape key");
-			return;
-		}
-	}*/
-	
-	anchored = sd->brush->flag & BRUSH_ANCHORED;
-	smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && !anchored;
-
-	if(smooth_stroke)
-		sculpt_stroke_new(256);
-
-	ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-	ss->damaged_verts.first = ss->damaged_verts.last = NULL;
-	ss->vertexcosnos = NULL;
-
-	mmd = sculpt_multires_active(ob);
-
-	/* Check that vertex users are up-to-date */
-	if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != cache->totvert) {
-		sculpt_vertexusers_free(ss);
-		calc_vertex_users(ss);
-		if(ss->projverts)
-			MEM_freeN(ss->projverts);
-		ss->projverts = NULL;
-		active_ob= ob;
-	}
-		
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-
-	/*XXX:
-	persp(PERSP_VIEW);
-	getmouseco_areawin(mvalo);*/
-
-	/* Init texture
-	   FIXME: Shouldn't be doing this every time! */
-	if(sd->tex_mode!=SCULPTREPT_3D)
-		sculptmode_update_tex(sd);
-
-	/*XXX: getmouseco_areawin(mouse); */
-	mvalo[0]= mouse[0];
-	mvalo[1]= mouse[1];
-	lastSigMouse[0]=mouse[0];
-	lastSigMouse[1]=mouse[1];
-	mousebut = 0; /* XXX: L_MOUSE; */
-
-	/* If modifier_calculations is true, then extra time must be spent
-	   updating the mesh. This takes a *lot* longer, so it's worth
-	   skipping if the modifier stack is empty. */
-	modifier_calculations= sculpt_modifiers_active(ob);
-
-	if(modifier_calculations)
-		ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /* XXX: scene = ? */
-	sculptmode_update_all_projverts(ss);
-
-	/* Capture original copy */
-	if(sd->flags & SCULPT_DRAW_FAST)
-		glAccum(GL_LOAD, 1);
-
-	/* Get original scissor box */
-	glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
-	
-	/* For raking, get the original angle*/
-	offsetRot=sculpt_tex_angle(sd);
-
-	me = get_mesh(ob);
-
-	while (/*XXX:get_mbut() & mousebut*/0) {
-		/* XXX: getmouseco_areawin(mouse); */
-		/* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
-		if (rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
-			/*Nasty looking, but just orig + new angle really*/
-			set_tex_angle(sd, offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
-			lastSigMouse[0]=mouse[0];
-			lastSigMouse[1]=mouse[1];
-		}
-		
-		if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] ||
-		   sd->brush->flag & BRUSH_AIRBRUSH) {
-			a->firsttime = firsttime;
-			firsttime= 0;
-
-			if(smooth_stroke)
-				sculpt_stroke_add_point(ss->stroke, mouse[0], mouse[1]);
-
-			spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
-
-			if(modifier_calculations && !ss->vertexcosnos)
-				ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /*XXX scene = ? */
-
-			if(sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
-				if(anchored) {
- 					/* Restore the mesh before continuing with anchored stroke */
- 					/*if(a->mesh_store) {
- 						for(i = 0; i < cache->totvert; ++i) {
- 							VecCopyf(cache->mvert[i].co, &a->mesh_store[i].x);
-							cache->mvert[i].no[0] = a->orig_norms[i][0];
-							cache->mvert[i].no[1] = a->orig_norms[i][1];
-							cache->mvert[i].no[2] = a->orig_norms[i][2];
-						}
-						}*/
-					
-  					//do_symmetrical_brush_actions(sd, a, mouse, NULL);
-  				}
-				else {
-					if(smooth_stroke) {
-						sculpt_stroke_apply(sd, ss->stroke);
-					}
-					else if(sd->spacing==0 || spacing>sd->spacing) {
-						//do_symmetrical_brush_actions(sd, a, mouse, NULL);
-						spacing= 0;
-					}
-				}
-			}
-			else {
-				//do_symmetrical_brush_actions(sd, a, mouse, mvalo);
-				//unproject(ss, sd->pivot, mouse[0], mouse[1], a->depth);
-			}
-
-			if((!ss->multires && modifier_calculations) || ob_get_keyblock(ob)) {
-				/* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); */ }
-
-			if(modifier_calculations || sd->brush->sculpt_tool == SCULPT_TOOL_GRAB || !(sd->flags & SCULPT_DRAW_FAST)) {
-				calc_damaged_verts(ss, a);
-				/*XXX: scrarea_do_windraw(curarea);
-				screen_swapbuffers(); */
-			} else { /* Optimized drawing */
-				calc_damaged_verts(ss, a);
-
-				/* Draw the stored image to the screen */
-				glAccum(GL_RETURN, 1);
-
-				sculpt_clear_damaged_areas(ss);
-				
-				/* Draw all the polygons that are inside the modified area(s) */
-				glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
-				/* XXX: sculptmode_draw_mesh(1); */
-				glAccum(GL_LOAD, 1);
-
-				projverts_clear_inside(ss);
-
-				/* XXX: persp(PERSP_WIN); */
-				glDisable(GL_DEPTH_TEST);
-				
-				/* Draw cursor */
-				if(sd->flags & SCULPT_TOOL_DRAW)
-					fdrawXORcirc((float)mouse[0],(float)mouse[1],sd->brush->size);
-				/* XXX: if(smooth_stroke)
-				   sculpt_stroke_draw();
-				
-				myswapbuffers(); */
-			}
-
-			BLI_freelistN(&ss->damaged_rects);
-			ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-	
-			mvalo[0]= mouse[0];
-			mvalo[1]= mouse[1];
-
-			if(ss->vertexcosnos) {
-				MEM_freeN(ss->vertexcosnos);
-				ss->vertexcosnos= NULL;
-			}
-
-		}
-		else { /*XXX:BIF_wait_for_statechange();*/ }
-	}
-
-	/* Set the rotation of the brush back to what it was before any rake */
-	set_tex_angle(sd, offsetRot);
-	
-	if(smooth_stroke) {
-		sculpt_stroke_apply_all(sd, ss->stroke);
-		calc_damaged_verts(ss, a);
-		BLI_freelistN(&ss->damaged_rects);
-	}
-
-	//if(a->layer_disps) MEM_freeN(a->layer_disps);
-	//if(a->mesh_store) MEM_freeN(a->mesh_store);
-	//if(a->orig_norms) MEM_freeN(a->orig_norms);
-	for(i=0; i<8; ++i)
-		BLI_freelistN(&a->grab_active_verts[i]);
-	MEM_freeN(a);
-	sculpt_stroke_free(ss->stroke);
-	ss->stroke = NULL;
-
-	if(mmd) {
-		if(mmd->undo_verts && mmd->undo_verts != cache->mvert)
-			MEM_freeN(mmd->undo_verts);
-		
-		mmd->undo_verts = cache->mvert;
-		mmd->undo_verts_tot = cache->totvert;
-	}
-
-	//sculpt_undo_push(sd);
-
-	/* XXX: if(G.vd->depths) G.vd->depths->damaged= 1;
-	   allqueue(REDRAWVIEW3D, 0); */
-#endif
-}
-
-/* Partial Mesh Visibility */
-
-/* XXX: Partial vis. always was a mess, have to figure something out */
-#if 0
-/* mode: 0=hide outside selection, 1=hide inside selection */
-static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
-{
-	Mesh *me= get_mesh(ob);
-	float hidebox[6][3];
-	vec3f plane_normals[4];
-	float plane_ds[4];
-	unsigned i, j;
-	unsigned ndx_show, ndx_hide;
-	MVert *nve;
-	unsigned face_cnt_show= 0, face_ndx_show= 0;
-	unsigned edge_cnt_show= 0, edge_ndx_show= 0;
-	unsigned *old_map= NULL;
-	const unsigned SHOW= 0, HIDE=1;
-
-	/* Convert hide box from 2D to 3D */
-	unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
-	unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
-	unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
-	unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
-	unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
-	unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
-	
-	/* Calculate normals for each side of hide box */
-	CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
-	CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
-	CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
-	CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
-	
-	/* Calculate D for each side of hide box */
-	for(i= 0; i<4; ++i)
-		plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
-			hidebox[i][2]*plane_normals[i].z;
-	
-	/* Add partial visibility to mesh */
-	if(!me->pv) {
-		me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
-	} else {
-		old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
-		for(i=0; ipv->totvert; ++i) {
-			old_map[i]= me->pv->vert_map[i]totvert?0:1;
-		}
-		mesh_pmv_revert(ob, me);
-	}
-	
-	/* Kill sculpt data */
-	active_ob= NULL;
-	
-	/* Initalize map with which verts are to be hidden */
-	me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
-	me->pv->totvert= me->totvert;
-	me->totvert= 0;
-	for(i=0; ipv->totvert; ++i) {
-		me->pv->vert_map[i]= mode ? HIDE:SHOW;
-		for(j=0; j<4; ++j) {
-			if(me->mvert[i].co[0] * plane_normals[j].x +
-			   me->mvert[i].co[1] * plane_normals[j].y +
-			   me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
-				me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
-				break;
-			}
-		}
-		if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
-		if(!me->pv->vert_map[i]) ++me->totvert;
-
-	}
-	if(old_map) MEM_freeN(old_map);
-
-	/* Find out how many faces to show */
-	for(i=0; itotface; ++i) {
-		if(!me->pv->vert_map[me->mface[i].v1] &&
-		   !me->pv->vert_map[me->mface[i].v2] &&
-		   !me->pv->vert_map[me->mface[i].v3]) {
-			if(me->mface[i].v4) {
-				if(!me->pv->vert_map[me->mface[i].v4])
-					++face_cnt_show;
-			}
-			else ++face_cnt_show;
-		}
-	}
-	/* Find out how many edges to show */
-	for(i=0; itotedge; ++i) {
-		if(!me->pv->vert_map[me->medge[i].v1] &&
-		   !me->pv->vert_map[me->medge[i].v2])
-			++edge_cnt_show;
-	}
-
-	/* Create new vert array and reset each vert's map with map[old]=new index */
-	nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
-	ndx_show= 0; ndx_hide= me->totvert;
-	for(i=0; ipv->totvert; ++i) {
-		if(me->pv->vert_map[i]) {
-			me->pv->vert_map[i]= ndx_hide;
-			nve[me->pv->vert_map[i]]= me->mvert[i];
-			++ndx_hide;
-		} else {
-			me->pv->vert_map[i]= ndx_show;
-			nve[me->pv->vert_map[i]]= me->mvert[i];
-			++ndx_show;
-		}
-	}
-	CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
-	me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
-
-	/* Create new face array */
-	me->pv->old_faces= me->mface;
-	me->pv->totface= me->totface;
-	me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
-	for(i=0; itotface; ++i) {
-		MFace *pr_f= &me->pv->old_faces[i];
-		char show= 0;
-
-		if(me->pv->vert_map[pr_f->v1] < me->totvert &&
-		   me->pv->vert_map[pr_f->v2] < me->totvert &&
-		   me->pv->vert_map[pr_f->v3] < me->totvert) {
-			if(pr_f->v4) {
-				if(me->pv->vert_map[pr_f->v4] < me->totvert)
-					show= 1;
-			}
-			else show= 1;
-		}
-
-		if(show) {
-			MFace *cr_f= &me->mface[face_ndx_show];
-			*cr_f= *pr_f;
-			cr_f->v1= me->pv->vert_map[pr_f->v1];
-			cr_f->v2= me->pv->vert_map[pr_f->v2];
-			cr_f->v3= me->pv->vert_map[pr_f->v3];
-			cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
-			test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
-			++face_ndx_show;
-		}
-	}
-	me->totface= face_cnt_show;
-	CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
-	/* Create new edge array */
-	me->pv->old_edges= me->medge;
-	me->pv->totedge= me->totedge;
-	me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
-	me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
-	for(i=0; itotedge; ++i) {
-		if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
-		   me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
-			MEdge *cr_e= &me->medge[edge_ndx_show];
-			me->pv->edge_map[i]= edge_ndx_show;
-			*cr_e= me->pv->old_edges[i];
-			cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
-			cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
-			++edge_ndx_show;
-		}
-		else me->pv->edge_map[i]= -1;
-	}
-	me->totedge= edge_cnt_show;
-	CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
-
-	/* XXX: DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); */
-}
-
-static rcti sculptmode_pmv_box()
-{
-	/*XXX:	short down[2], mouse[2];
-	rcti ret;
-
-	getmouseco_areawin(down);
-
-	while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
-		getmouseco_areawin(mouse);
-
-		scrarea_do_windraw(curarea);
-
-		persp(PERSP_WIN);
-		glLineWidth(2);
-		setlinestyle(2);
-		sdrawXORline(down[0],down[1],mouse[0],down[1]);
-		sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
-		sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
-		sdrawXORline(down[0],mouse[1],down[0],down[1]);
-		setlinestyle(0);
-		glLineWidth(1);
-		persp(PERSP_VIEW);
-
-		screen_swapbuffers();
-		backdrawview3d(0);
-	}
-
-	ret.xmin= down[0]mouse[0]?down[0]:mouse[0];
-	ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
-	return ret;*/
-}
-
-void sculptmode_pmv(int mode)
-{
-	Object *ob= NULL; /*XXX: OBACT; */
-	rcti hb_2d;
-	
-	if(ob_get_key(ob)) {
-		error("Cannot hide mesh with shape keys enabled");
-		return;
-	}
-	
-	hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
-	
-	sculptmode_correct_state();
-
-	waitcursor(1);
-
-	if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
-		init_sculptmatrices();
-
-		sculptmode_do_pmv(ob,&hb_2d,mode);
-	}
-	else mesh_pmv_off(ob, get_mesh(ob));
-
-	/*XXX: scrarea_do_windraw(curarea); */
-
-	waitcursor(0);
-}
-#endif
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 112da5b4f0f..febca301939 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BDR_sculptmode.h 13396 2008-01-25 04:17:38Z nicholasbishop $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/sculpt_paint/sculpt_stroke.c b/source/blender/editors/sculpt_paint/sculpt_stroke.c
index 1c23ec2a546..554ff580358 100644
--- a/source/blender/editors/sculpt_paint/sculpt_stroke.c
+++ b/source/blender/editors/sculpt_paint/sculpt_stroke.c
@@ -1,5 +1,5 @@
 /*
- * $Id: sculpt_stroke.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_action/Makefile b/source/blender/editors/space_action/Makefile
index 840f31b8a40..e856587acca 100644
--- a/source/blender/editors/space_action/Makefile
+++ b/source/blender/editors/space_action/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 6eae581aa40..2c9f91e0941 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index a0f1adbd97e..5d262cb03c5 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index b82e44f3aa3..06f35f5cf05 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_api/Makefile b/source/blender/editors/space_api/Makefile
index 46f926afbc9..474fbe89053 100644
--- a/source/blender/editors/space_api/Makefile
+++ b/source/blender/editors/space_api/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 4f9c1f4b7a7..510103895f4 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -50,6 +50,7 @@
 #include "ED_screen.h"
 #include "ED_space_api.h"
 #include "ED_uvedit.h"
+#include "ED_pointcache.h"
 
 /* only call once on startup, storage is global in BKE kernel listbase */
 void ED_spacetypes_init(void)
@@ -89,6 +90,7 @@ void ED_spacetypes_init(void)
 	ED_operatortypes_curve();
 	ED_operatortypes_armature();
 	ED_marker_operatortypes();
+	ED_operatortypes_pointcache();
 	
 	ui_view2d_operatortypes();
 	
diff --git a/source/blender/editors/space_buttons/Makefile b/source/blender/editors/space_buttons/Makefile
index b96d1cc5495..a4894ede06b 100644
--- a/source/blender/editors/space_buttons/Makefile
+++ b/source/blender/editors/space_buttons/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript
index 541da52f7f9..a0a7dad4077 100644
--- a/source/blender/editors/space_buttons/SConscript
+++ b/source/blender/editors/space_buttons/SConscript
@@ -12,7 +12,4 @@ defs = []
 if env['WITH_BF_GAMEENGINE']:
 	defs.append('GAMEBLENDER=1')
 
-	if env['WITH_BF_SOLID']:
-		defs.append('USE_SUMO_SOLID')
-
 env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), defs, libtype=['core'], priority=[120] )
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index d97b4acdb96..01794d1bba8 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -552,7 +552,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
 		if(ptr) {
 			Object *ob= ptr->data;
 
-			if(ob && ob->type && (ob->typetype && (ob->typetotcol)
 				CTX_data_pointer_set(result, &ob->id, &RNA_MaterialSlot, ob->mat+ob->actcol-1);
 		}
 
@@ -668,7 +668,6 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 	uiBlock *block;
 	uiBut *but;
 	PointerRNA *ptr;
-	PropertyRNA *nameprop;
 	char namebuf[128], *name;
 	int a, icon;
 
@@ -688,7 +687,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 
 		if(ptr->data) {
 			icon= RNA_struct_ui_icon(ptr->type);
-			nameprop= RNA_struct_name_property(ptr->type);
+			name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf));
 
 #if 0
 			if(sbuts->mainb != BCONTEXT_SCENE && ptr->type == &RNA_Scene) {
@@ -696,9 +695,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 			}
 			else
 #endif
-			if(nameprop) {
-				name= RNA_property_string_get_alloc(ptr, nameprop, namebuf, sizeof(namebuf));
-
+			if(name) {
 				uiItemL(row, name, icon);
 
 				if(name != namebuf)
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 98fd198d84b..7c622f172a2 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: buttons_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -173,10 +173,10 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
 		uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,	ICON_OBJECT_DATA,	xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object");
 	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint");
-	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
 	if(sbuts->pathflag & (1<dataicon,	xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data");
+	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
 	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone");
 	if(sbuts->pathflag & (1<name= "Add Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_add";
+	
+	/* api callbacks */
+	ot->exec= material_slot_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	object_remove_material_slot(ob);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_remove";
+	
+	/* api callbacks */
+	ot->exec= material_slot_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_assign_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(ob && ob->actcol>0) {
+		if(ob->type == OB_MESH) {
+			EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+			EditFace *efa;
+
+			if(em) {
+				for(efa= em->faces.first; efa; efa=efa->next)
+					if(efa->f & SELECT)
+						efa->mat_nr= ob->actcol-1;
+			}
+		}
+		else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+			ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+			Nurb *nu;
+
+			if(editnurb) {
+				for(nu= editnurb->first; nu; nu= nu->next)
+					if(isNurbsel(nu))
+						nu->mat_nr= nu->charidx= ob->actcol-1;
+			}
+		}
+		else if(ob->type == OB_FONT) {
+			EditFont *ef= ((Curve*)ob->data)->editfont;
+    		int i, selstart, selend;
+
+			if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
+				for(i=selstart; i<=selend; i++)
+					ef->textbufinfo[i].mat_nr = ob->actcol-1;
+			}
+		}
+	}
+
+    DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+    WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Assign Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_assign";
+	
+	/* api callbacks */
+	ot->exec= material_slot_assign_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_de_select(bContext *C, int select)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(ob->type == OB_MESH) {
+		EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+
+		if(em) {
+			if(select)
+				EM_select_by_material(em, ob->actcol-1);
+			else
+				EM_deselect_by_material(em, ob->actcol-1);
+		}
+	}
+	else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+		ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+		Nurb *nu;
+		BPoint *bp;
+		BezTriple *bezt;
+		int a;
+
+		for(nu= editnurb->first; nu; nu=nu->next) {
+			if(nu->mat_nr==ob->actcol-1) {
+				if(nu->bezt) {
+					a= nu->pntsu;
+					bezt= nu->bezt;
+					while(a--) {
+						if(bezt->hide==0) {
+							if(select) {
+								bezt->f1 |= SELECT;
+								bezt->f2 |= SELECT;
+								bezt->f3 |= SELECT;
+							}
+							else {
+								bezt->f1 &= ~SELECT;
+								bezt->f2 &= ~SELECT;
+								bezt->f3 &= ~SELECT;
+							}
+						}
+						bezt++;
+					}
+				}
+				else if(nu->bp) {
+					a= nu->pntsu*nu->pntsv;
+					bp= nu->bp;
+					while(a--) {
+						if(bp->hide==0) {
+							if(select) bp->f1 |= SELECT;
+							else bp->f1 &= ~SELECT;
+						}
+						bp++;
+					}
+				}
+			}
+		}
+	}
+
+    WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+static int material_slot_select_exec(bContext *C, wmOperator *op)
+{
+	return material_slot_de_select(C, 1);
+}
+
+void OBJECT_OT_material_slot_select(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Select Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_select";
+	
+	/* api callbacks */
+	ot->exec= material_slot_select_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_deselect_exec(bContext *C, wmOperator *op)
+{
+	return material_slot_de_select(C, 0);
+}
+
+void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Deselect Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_deselect";
+	
+	/* api callbacks */
+	ot->exec= material_slot_deselect_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /********************** new material operator *********************/
 
 static int new_material_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr;
-	Material *ma;
+	Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
 	Object *ob;
+	PointerRNA ptr;
 	int index;
 
 	/* add or copy material */
-	ptr= CTX_data_pointer_get(C, "material");
-	ma= (RNA_struct_is_a(ptr.type, &RNA_Material))? ptr.data: NULL;
-
 	if(ma)
 		ma= copy_material(ma);
 	else
@@ -70,9 +291,9 @@ static int new_material_exec(bContext *C, wmOperator *op)
 	ma->id.us--; /* compensating for us++ in assign_material */
 
 	/* attempt to assign to material slot */
-	ptr= CTX_data_pointer_get(C, "material_slot");
+	ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
 
-	if(RNA_struct_is_a(ptr.type, &RNA_MaterialSlot)) {
+	if(ptr.data) {
 		ob= ptr.id.data;
 		index= (Material**)ptr.data - ob->mat;
 
@@ -80,6 +301,8 @@ static int new_material_exec(bContext *C, wmOperator *op)
 
 		WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
 	}
+
+	WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
 	
 	return OPERATOR_FINISHED;
 }
@@ -101,15 +324,12 @@ void MATERIAL_OT_new(wmOperatorType *ot)
 
 static int new_texture_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr;
+	Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
 	ID *id;
-	Tex *tex;
 	MTex *mtex;
+	PointerRNA ptr;
 
 	/* add or copy texture */
-	ptr= CTX_data_pointer_get(C, "texture");
-	tex= (RNA_struct_is_a(ptr.type, &RNA_Texture))? ptr.data: NULL;
-
 	if(tex)
 		tex= copy_texture(tex);
 	else
@@ -118,9 +338,9 @@ static int new_texture_exec(bContext *C, wmOperator *op)
 	id_us_min(&tex->id);
 
 	/* attempt to assign to texture slot */
-	ptr= CTX_data_pointer_get(C, "texture_slot");
+	ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
 
-	if(RNA_struct_is_a(ptr.type, &RNA_TextureSlot)) {
+	if(ptr.data) {
 		id= ptr.id.data;
 		mtex= ptr.data;
 
@@ -133,6 +353,8 @@ static int new_texture_exec(bContext *C, wmOperator *op)
 
 		/* XXX nodes, notifier .. */
 	}
+
+	WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
 	
 	return OPERATOR_FINISHED;
 }
@@ -154,27 +376,21 @@ void TEXTURE_OT_new(wmOperatorType *ot)
 
 static int new_world_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr;
-	Scene *scene;
-	World *wo;
+	Scene *scene= CTX_data_scene(C);
+	World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
 
 	/* add or copy world */
-	ptr= CTX_data_pointer_get(C, "world");
-	wo= (RNA_struct_is_a(ptr.type, &RNA_World))? ptr.data: NULL;
-
 	if(wo)
 		wo= copy_world(wo);
 	else
 		wo= add_world("World");
 
 	/* assign to scene */
-	scene= CTX_data_scene(C);
-
 	if(scene->world)
 		id_us_min(&scene->world->id);
 	scene->world= wo;
 
-	// XXX notifier
+	WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
 	
 	return OPERATOR_FINISHED;
 }
@@ -192,3 +408,109 @@ void WORLD_OT_new(wmOperatorType *ot)
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+
+
+/********************** particle system slot operators *********************/
+
+static int particle_system_add_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene = CTX_data_scene(C);
+
+	if(!scene || !ob)
+		return OPERATOR_CANCELLED;
+
+	object_add_particle_system(scene, ob);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Particle System Slot";
+	ot->idname= "OBJECT_OT_particle_system_add";
+	
+	/* api callbacks */
+	ot->exec= particle_system_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int particle_system_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene = CTX_data_scene(C);
+
+	if(!scene || !ob)
+		return OPERATOR_CANCELLED;
+
+	object_remove_particle_system(scene, ob);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Particle System Slot";
+	ot->idname= "OBJECT_OT_particle_system_remove";
+	
+	/* api callbacks */
+	ot->exec= particle_system_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new particle settings operator *********************/
+
+static int new_particle_settings_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene = CTX_data_scene(C);
+	ParticleSettings *part= CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings).data;
+	Object *ob;
+	PointerRNA ptr;
+
+	/* add or copy particle setting */
+	if(part)
+		part= psys_copy_settings(part);
+	else
+		part= psys_new_settings("PSys", NULL);
+
+	/* attempt to assign to material slot */
+	ptr= CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+
+	if(ptr.data) {
+		ParticleSystem *psys = (ParticleSystem*)ptr.data;
+		ob= ptr.id.data;
+
+		if(psys->part)
+			psys->part->id.us--;
+
+		psys->part = part;
+
+		DAG_scene_sort(scene);
+		DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+		WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	}
+	
+	return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_new(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "New Particle Settings";
+	ot->idname= "PARTICLE_OT_new";
+	
+	/* api callbacks */
+	ot->exec= new_particle_settings_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 38ce88019ed..b89a13ce218 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -210,9 +210,20 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
 
 void buttons_operatortypes(void)
 {
+	WM_operatortype_append(OBJECT_OT_material_slot_add);
+	WM_operatortype_append(OBJECT_OT_material_slot_remove);
+	WM_operatortype_append(OBJECT_OT_material_slot_assign);
+	WM_operatortype_append(OBJECT_OT_material_slot_select);
+	WM_operatortype_append(OBJECT_OT_material_slot_deselect);
+
 	WM_operatortype_append(MATERIAL_OT_new);
 	WM_operatortype_append(TEXTURE_OT_new);
 	WM_operatortype_append(WORLD_OT_new);
+
+	WM_operatortype_append(OBJECT_OT_particle_system_add);
+	WM_operatortype_append(OBJECT_OT_particle_system_remove);
+
+	WM_operatortype_append(PARTICLE_OT_new);
 }
 
 void buttons_keymap(struct wmWindowManager *wm)
@@ -220,14 +231,23 @@ void buttons_keymap(struct wmWindowManager *wm)
 	
 }
 
+//#define PY_HEADER
 /* add handlers, stuff you only do once or on area/region changes */
 static void buttons_header_area_init(wmWindowManager *wm, ARegion *ar)
 {
+#ifdef PY_HEADER
+	ED_region_header_init(ar);
+#else
 	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+#endif
 }
 
 static void buttons_header_area_draw(const bContext *C, ARegion *ar)
 {
+#ifdef PY_HEADER
+	ED_region_header(C, ar);
+#else
+
 	float col[3];
 	
 	/* clear */
@@ -243,7 +263,8 @@ static void buttons_header_area_draw(const bContext *C, ARegion *ar)
 	UI_view2d_view_ortho(C, &ar->v2d);
 	
 	buttons_header_buttons(C, ar);
-	
+#endif	
+
 	/* restore view matrix? */
 	UI_view2d_view_restore(C);
 }
@@ -310,6 +331,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
 		case NC_SCENE:
 			switch(wmn->data) {
 				case ND_FRAME:
+				case ND_MODE:
 					ED_area_tag_redraw(sa);
 					break;
 					
@@ -327,6 +349,11 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
 				case ND_GEOM_SELECT:
 					ED_area_tag_redraw(sa);
 					break;
+				case ND_SHADING:
+				case ND_SHADING_DRAW:
+					/* currently works by redraws... if preview is set, it (re)starts job */
+					sbuts->preview= 1;
+					break;
 			}
 			break;
 		case NC_MATERIAL:
@@ -337,7 +364,6 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
 				case ND_SHADING_DRAW:
 					/* currently works by redraws... if preview is set, it (re)starts job */
 					sbuts->preview= 1;
-					printf("shader notifier \n");
 					break;
 			}					
 			break;
diff --git a/source/blender/editors/space_file/Makefile b/source/blender/editors/space_file/Makefile
index 8f48217473c..2f4180448e5 100644
--- a/source/blender/editors/space_file/Makefile
+++ b/source/blender/editors/space_file/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 6ed8f87d987..02ee8f508c1 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -550,81 +550,4 @@ void file_draw_list(const bContext *C, ARegion *ar)
 	}
 }
 
-static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCategory category, const char* category_name, short *starty)
-{
-	struct FSMenu* fsmenu = fsmenu_get();
-	char bookmark[FILE_MAX];
-	int nentries = fsmenu_get_nentries(fsmenu, category);
-	
-	short sx, sy, xpos, ypos;
-	int bmwidth = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*TILE_BORDER_X - ICON_DEFAULT_WIDTH - 4;
-	int fontsize = file_font_pointsize();
-	int cat_icon;
-	int i;
-
-	sx = ar->v2d.cur.xmin + TILE_BORDER_X;
-	sy = *starty;
-
-	UI_ThemeColor(TH_TEXT_HI);
-	file_draw_string(sx, sy, category_name, bmwidth, fontsize, FILE_SHORTEN_END);
-	
-	sy -= fontsize*2.0f;
-
-	switch(category) {
-		case FS_CATEGORY_SYSTEM:
-			cat_icon = ICON_DISK_DRIVE; break;
-		case FS_CATEGORY_BOOKMARKS:
-			cat_icon = ICON_BOOKMARKS; break;
-		case FS_CATEGORY_RECENT:
-			cat_icon = ICON_FILE_FOLDER; break;
-	}
 
-	for (i=0; i< nentries && (sy > ar->v2d.cur.ymin) ;++i) {
-		char *fname = fsmenu_get_entry(fsmenu, category, i);
-
-		if (fname) {
-			int sl;
-			BLI_strncpy(bookmark, fname, FILE_MAX);
-		
-			sl = strlen(bookmark)-1;
-			if (sl > 1) {
-			while (bookmark[sl] == '\\' || bookmark[sl] == '/') {
-				bookmark[sl] = '\0';
-				sl--;
-			}
-			}
-			
-			if (fsmenu_is_selected(fsmenu, category, i) ) {
-				UI_ThemeColor(TH_HILITE);
-				uiRoundBox(sx, sy - fontsize*2.0f, ar->v2d.cur.xmax - TILE_BORDER_X, sy, 4.0f);
-				UI_ThemeColor(TH_TEXT);
-			} else {
-				UI_ThemeColor(TH_TEXT_HI);
-			}
-
-			xpos = sx;
-			ypos = sy - (TILE_BORDER_Y * 0.5);
-			
-			file_draw_icon(xpos, ypos, cat_icon, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH);
-			xpos += ICON_DEFAULT_WIDTH + 4;
-			file_draw_string(xpos, ypos, bookmark, bmwidth, fontsize, FILE_SHORTEN_FRONT);
-			sy -= fontsize*2.0;
-			fsmenu_set_pos(fsmenu, category, i, xpos, ypos);
-		}
-	}
-
-	*starty = sy;
-}
-
-void file_draw_fsmenu(const bContext *C, ARegion *ar)
-{
-	int linestep = file_font_pointsize()*2.0f;
-	short sy= ar->v2d.cur.ymax-2*TILE_BORDER_Y;
-
-	file_draw_fsmenu_category(C, ar, FS_CATEGORY_SYSTEM, "SYSTEM", &sy);
-	sy -= linestep;
-	file_draw_fsmenu_category(C, ar, FS_CATEGORY_BOOKMARKS, "BOOKMARKS", &sy);
-	sy -= linestep;
-	file_draw_fsmenu_category(C, ar, FS_CATEGORY_RECENT, "RECENT", &sy);
-	
-}
diff --git a/source/blender/editors/space_file/file_header.c b/source/blender/editors/space_file/file_header.c
index 34374268d5c..4799003d6c7 100644
--- a/source/blender/editors/space_file/file_header.c
+++ b/source/blender/editors/space_file/file_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: file_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 642189ad3fd..668e14c95e6 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -30,6 +30,9 @@
 
 /* internal exports only */
 
+struct ARegion;
+struct ARegionType;
+struct SpaceFile;
 
 /* file_header.c */
 void file_header_buttons(const bContext *C, ARegion *ar);
@@ -45,7 +48,6 @@ void file_draw_buttons(const bContext *C, ARegion *ar);
 void file_calc_previews(const bContext *C, ARegion *ar);
 void file_draw_previews(const bContext *C, ARegion *ar);
 void file_draw_list(const bContext *C, ARegion *ar);
-void file_draw_fsmenu(const bContext *C, ARegion *ar);
 
 /* file_ops.h */
 struct wmOperatorType;
@@ -56,6 +58,9 @@ void FILE_OT_select(struct wmOperatorType *ot);
 void FILE_OT_select_all_toggle(struct wmOperatorType *ot);
 void FILE_OT_select_border(struct wmOperatorType *ot);
 void FILE_OT_select_bookmark(struct wmOperatorType *ot);
+void FILE_OT_add_bookmark(struct wmOperatorType *ot);
+void FILE_OT_delete_bookmark(struct wmOperatorType *ot);
+void FILE_OT_hidedot(struct wmOperatorType *ot);
 void FILE_OT_loadimages(struct wmOperatorType *ot);
 void FILE_OT_exec(struct wmOperatorType *ot);
 void FILE_OT_cancel(struct wmOperatorType *ot);
@@ -66,11 +71,14 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot);
 int file_exec(bContext *C, struct wmOperator *unused);
 int file_cancel_exec(bContext *C, struct wmOperator *unused);
 int file_parent_exec(bContext *C, struct wmOperator *unused);
-int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my);
+int file_hilight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
 
 /* filesel.c */
 float file_string_width(const char* str);
 float file_font_pointsize();
 
+/* file_panels.c */
+void file_panels_register(struct ARegionType *art);
+
 #endif /* ED_FILE_INTERN_H */
 
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 0c6cadc05c1..aaa1793efbb 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -42,6 +42,8 @@
 #include "ED_screen.h"
 #include "ED_fileselect.h"
 
+#include "MEM_guardedalloc.h"
+
 #include "RNA_access.h"
 #include "RNA_define.h"
 
@@ -135,22 +137,15 @@ static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short v
 		params->active_file = last_file;
 
 		if(file && S_ISDIR(file->type)) {
-			/* the path is too long and we are not going up! */
-			if (strcmp(file->relname, ".") &&
-				strcmp(file->relname, "..") &&
-				strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) 
+			/* the path is too long! */
+			if (strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) 
 			{
 				// XXX error("Path too long, cannot enter this directory");
 			} else {
-				if (strcmp(file->relname, "..")==0) {
-					/* avoids /../../ */
-					BLI_parent_dir(params->dir);
-				} else {
-					strcat(params->dir, file->relname);
-					strcat(params->dir,"/");
-					params->file[0] = '\0';
-					BLI_cleanup_dir(G.sce, params->dir);
-				}
+				strcat(params->dir, file->relname);
+				strcat(params->dir,"/");
+				params->file[0] = '\0';
+				BLI_cleanup_dir(G.sce, params->dir);
 				filelist_setdir(sfile->files, params->dir);
 				filelist_free(sfile->files);
 				params->active_file = -1;
@@ -190,7 +185,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
 	rect.xmax= RNA_int_get(op->ptr, "xmax");
 	rect.ymax= RNA_int_get(op->ptr, "ymax");
 
-	BLI_isect_rctf(&(ar->v2d.mask), &rect, &rect);
+	BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect);
 	
 	file_select(sfile, ar, &rect, val );
 	WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -234,7 +229,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 		/* single select, deselect all selected first */
 		file_deselect_all(sfile);
 		file_select(sfile, ar, &rect, val );
-		WM_event_add_notifier(C, NC_WINDOW, NULL);
+		WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL);
 	}
 	return OPERATOR_FINISHED;
 }
@@ -299,89 +294,106 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
 
 /* ---------- BOOKMARKS ----------- */
 
-static int file_select_bookmark_category(SpaceFile* sfile, ARegion* ar, short x, short y, FSMenuCategory category)
+static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-	struct FSMenu* fsmenu = fsmenu_get();
-	int nentries = fsmenu_get_nentries(fsmenu, category);
-	int linestep = file_font_pointsize()*2.0f;
-	short xs, ys;
-	int i;
-	int selected = -1;
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
 
-	for (i=0; i < nentries; ++i) {
-		fsmenu_get_pos(fsmenu, category, i, &xs, &ys);
-		if ( (y<=ys) && (y>ys-linestep) ) {
-			fsmenu_select_entry(fsmenu, category, i);
-			selected = i;
-			break;
-		}
+	if(RNA_struct_find_property(op->ptr, "dir")) {
+		char entry[256];
+		FileSelectParams* params = sfile->params;
+
+		RNA_string_get(op->ptr, "dir", entry);
+		BLI_strncpy(params->dir, entry, sizeof(params->dir));
+		BLI_cleanup_dir(G.sce, params->dir);
+		filelist_free(sfile->files);	
+		filelist_setdir(sfile->files, params->dir);
+		params->file[0] = '\0';			
+		params->active_file = -1;
+
+		WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL);
 	}
-	return selected;
+	
+	return OPERATOR_FINISHED;
 }
 
-static void file_select_bookmark(SpaceFile* sfile, ARegion* ar, short x, short y)
+void FILE_OT_select_bookmark(wmOperatorType *ot)
 {
-	float fx, fy;
-	int selected;
-	FSMenuCategory category = FS_CATEGORY_SYSTEM;
-
-	if (BLI_in_rcti(&ar->v2d.mask, x, y)) {
-		char *entry;
+	/* identifiers */
+	ot->name= "Select Directory";
+	ot->idname= "FILE_OT_select_bookmark";
+	
+	/* api callbacks */
+	ot->invoke= bookmark_select_invoke;
+	ot->poll= ED_operator_file_active;
 
-		UI_view2d_region_to_view(&ar->v2d, x, y, &fx, &fy);
-		selected = file_select_bookmark_category(sfile, ar, fx, fy, FS_CATEGORY_SYSTEM);
-		if (selected<0) {
-			category = FS_CATEGORY_BOOKMARKS;
-			selected = file_select_bookmark_category(sfile, ar, fx, fy, category);
-		}
-		if (selected<0) {
-			category = FS_CATEGORY_RECENT;
-			selected = file_select_bookmark_category(sfile, ar, fx, fy, category);
-		}
-		
-		if (selected>=0) {
-			entry= fsmenu_get_entry(fsmenu_get(), category, selected);			
-			/* which string */
-			if (entry) {
-				FileSelectParams* params = sfile->params;
-				BLI_strncpy(params->dir, entry, sizeof(params->dir));
-				BLI_cleanup_dir(G.sce, params->dir);
-				filelist_free(sfile->files);	
-				filelist_setdir(sfile->files, params->dir);
-				params->file[0] = '\0';			
-				params->active_file = -1;
-			}
-		}
-	}
+	RNA_def_string(ot->srna, "dir", "", 256, "Dir", "");
 }
 
-static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int bookmark_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	ScrArea *sa= CTX_wm_area(C);
-	ARegion *ar= CTX_wm_region(C);	
 	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	struct FSMenu* fsmenu = fsmenu_get();
+	struct FileSelectParams* params= ED_fileselect_get_params(sfile);
 
-	short x, y;
-
-	x = event->x - ar->winrct.xmin;
-	y = event->y - ar->winrct.ymin;
+	if (params->dir[0] != '\0') {
+		char name[FILE_MAX];
+	
+		fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, 0, 1);
+		BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
+		fsmenu_write_file(fsmenu, name);
+	}
 
-	file_select_bookmark(sfile, ar, x, y);
 	ED_area_tag_redraw(sa);
 	return OPERATOR_FINISHED;
 }
 
-void FILE_OT_select_bookmark(wmOperatorType *ot)
+void FILE_OT_add_bookmark(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Select Directory";
-	ot->idname= "FILE_OT_select_bookmark";
+	ot->name= "Add Bookmark";
+	ot->idname= "FILE_OT_add_bookmark";
 	
 	/* api callbacks */
-	ot->invoke= bookmark_select_invoke;
+	ot->invoke= bookmark_add_invoke;
 	ot->poll= ED_operator_file_active;
 }
 
+static int bookmark_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	ScrArea *sa= CTX_wm_area(C);
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	struct FSMenu* fsmenu = fsmenu_get();
+	int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+	if(RNA_struct_find_property(op->ptr, "index")) {
+		int index = RNA_int_get(op->ptr, "index");
+		if ( (index >-1) && (index < nentries)) {
+			char name[FILE_MAX];
+			
+			fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
+			BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
+			fsmenu_write_file(fsmenu, name);
+			ED_area_tag_redraw(sa);
+		}
+	}
+
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_delete_bookmark(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Delete Bookmark";
+	ot->idname= "FILE_OT_delete_bookmark";
+	
+	/* api callbacks */
+	ot->invoke= bookmark_delete_invoke;
+	ot->poll= ED_operator_file_active;
+
+	RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000);
+}
+
+
 static int loadimages_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	ScrArea *sa= CTX_wm_area(C);
@@ -548,7 +560,7 @@ int file_parent_exec(bContext *C, wmOperator *unused)
 		filelist_free(sfile->files);
 		sfile->params->active_file = -1;
 	}		
-	ED_area_tag_redraw(CTX_wm_area(C));
+	WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL);
 
 	return OPERATOR_FINISHED;
 
@@ -575,8 +587,8 @@ int file_refresh_exec(bContext *C, wmOperator *unused)
 		filelist_setdir(sfile->files, sfile->params->dir);
 		filelist_free(sfile->files);
 		sfile->params->active_file = -1;
-	}		
-	ED_area_tag_redraw(CTX_wm_area(C));
+	}
+	WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL);
 
 	return OPERATOR_FINISHED;
 
@@ -594,14 +606,58 @@ void FILE_OT_refresh(struct wmOperatorType *ot)
 	ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
 }
 
+int file_hidedot_exec(bContext *C, wmOperator *unused)
+{
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	
+	if(sfile->params) {
+		sfile->params->flag ^= FILE_HIDE_DOT;
+		filelist_free(sfile->files);
+		sfile->params->active_file = -1;
+		WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL);
+	}
+	
+	return OPERATOR_FINISHED;
+
+}
+
+
+void FILE_OT_hidedot(struct wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Toggle Hide Dot Files";
+	ot->idname= "FILE_OT_hidedot";
+	
+	/* api callbacks */
+	ot->exec= file_hidedot_exec;
+	ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+}
+
 struct ARegion *file_buttons_region(struct ScrArea *sa)
 {
-	ARegion *ar;
+	ARegion *ar, *arnew;
 	
 	for(ar= sa->regionbase.first; ar; ar= ar->next)
 		if(ar->regiontype==RGN_TYPE_CHANNELS)
 			return ar;
-	return NULL;
+
+	/* add subdiv level; after header */
+	for(ar= sa->regionbase.first; ar; ar= ar->next)
+		if(ar->regiontype==RGN_TYPE_HEADER)
+			break;
+	
+	/* is error! */
+	if(ar==NULL) return NULL;
+	
+	arnew= MEM_callocN(sizeof(ARegion), "buttons for file panels");
+	
+	BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+	arnew->regiontype= RGN_TYPE_CHANNELS;
+	arnew->alignment= RGN_ALIGN_LEFT;
+	
+	arnew->flag = RGN_FLAG_HIDDEN;
+	
+	return arnew;
 }
 
 int file_bookmark_toggle_exec(bContext *C, wmOperator *unused)
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
new file mode 100644
index 00000000000..29c759d43c0
--- /dev/null
+++ b/source/blender/editors/space_file/file_panels.c
@@ -0,0 +1,165 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation, Andrea Weikert
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+
+#include "BLI_blenlib.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "file_intern.h"
+#include "fsmenu.h"
+
+#include 
+
+static void do_file_panel_events(bContext *C, void *arg, int event)
+{
+
+}
+
+static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, int icon, int allow_delete)
+{
+	uiBlock *block;
+	uiStyle *style= U.uistyles.first;
+	int i;
+	int fontsize = file_font_pointsize();
+	struct FSMenu* fsmenu = fsmenu_get();
+	int nentries = fsmenu_get_nentries(fsmenu, category);
+
+	uiLayoutSetAlignment(pa->layout, UI_LAYOUT_ALIGN_LEFT);
+	block= uiLayoutFreeBlock(pa->layout);
+	uiBlockSetHandleFunc(block, do_file_panel_events, NULL);
+	uiBlockSetEmboss(block, UI_EMBOSSP);
+	uiBlockBeginAlign(block);
+	for (i=0; i< nentries;++i) {
+		char dir[FILE_MAX];
+		char temp[FILE_MAX];
+		uiLayout* layout = uiLayoutRow(pa->layout, UI_LAYOUT_ALIGN_LEFT);
+		char *entry = fsmenu_get_entry(fsmenu, category, i);
+
+		/* create nice bookmark name, shows last directory in the full path currently */
+		BLI_strncpy(temp, entry, FILE_MAX);
+		BLI_add_slash(temp);
+		BLI_getlastdir(temp, dir, FILE_MAX);
+		BLI_del_slash(dir);
+
+		/* operator shows the short bookmark name, should eventually have tooltip */
+		uiItemStringO(layout, dir, icon, "FILE_OT_select_bookmark", "dir", entry);
+		if (allow_delete && fsmenu_can_save(fsmenu, category, i) )
+			uiItemIntO(layout, "", ICON_X, "FILE_OT_delete_bookmark", "index", i);
+	}
+	uiBlockEndAlign(block);
+}
+
+static void file_panel_system(const bContext *C, Panel *pa)
+{
+	file_panel_category(C, pa, FS_CATEGORY_SYSTEM, ICON_DISK_DRIVE, 0);
+}
+
+static void file_panel_bookmarks(const bContext *C, Panel *pa)
+{
+	file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, ICON_BOOKMARKS, 1);
+}
+
+
+static void file_panel_recent(const bContext *C, Panel *pa)
+{
+	file_panel_category(C, pa, FS_CATEGORY_RECENT, ICON_FILE_FOLDER, 0);
+}
+
+
+static void file_panel_operator(const bContext *C, Panel *pa)
+{
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	struct wmOperator *op = sfile ? sfile->op : NULL;
+	uiBlock *block;
+	int sy;
+
+	block= uiLayoutFreeBlock(pa->layout);
+	uiBlockSetHandleFunc(block, do_file_panel_events, NULL);
+
+	sy= 0;
+	if (op) {
+		uiBlockBeginAlign(block);
+		RNA_STRUCT_BEGIN(op->ptr, prop) {
+			if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
+				continue;
+			if(strcmp(RNA_property_identifier(prop), "filename") == 0)
+				continue;
+
+			uiItemFullR(pa->layout, NULL, 0, op->ptr, prop, -1, 0, 0, 0, 0);
+		}
+		RNA_STRUCT_END;
+		uiBlockEndAlign(block);
+	}
+	uiBlockLayoutResolve(C, block, NULL, &sy);
+	uiEndBlock(C, block);
+	uiDrawBlock(C, block);
+}
+
+
+void file_panels_register(ARegionType *art)
+{
+	PanelType *pt;
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file system directories");
+	strcpy(pt->idname, "FILE_PT_system");
+	strcpy(pt->label, "System");
+	pt->draw= file_panel_system;
+	BLI_addtail(&art->paneltypes, pt);
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file bookmarks");
+	strcpy(pt->idname, "FILE_PT_bookmarks");
+	strcpy(pt->label, "Bookmarks");
+	pt->draw= file_panel_bookmarks;
+	BLI_addtail(&art->paneltypes, pt);
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file recent directories");
+	strcpy(pt->idname, "FILE_PT_recent");
+	strcpy(pt->label, "Recent");
+	pt->draw= file_panel_recent;
+	BLI_addtail(&art->paneltypes, pt);
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file operator properties");
+	strcpy(pt->idname, "FILE_PT_operator");
+	strcpy(pt->label, "Operator");
+	pt->draw= file_panel_operator;
+	BLI_addtail(&art->paneltypes, pt);
+}
\ No newline at end of file
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 766dec7c064..573aed72728 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -823,16 +823,16 @@ void filelist_sort(struct FileList* filelist, short sort)
 	int num;/*  , act= 0; */
 
 	switch(sort) {
-	case FILE_SORTALPHA:
+	case FILE_SORT_ALPHA:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);	
 		break;
-	case FILE_SORTDATE:
+	case FILE_SORT_TIME:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);	
 		break;
-	case FILE_SORTSIZE:
+	case FILE_SORT_SIZE:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);	
 		break;
-	case FILE_SORTEXTENS:
+	case FILE_SORT_EXTENSION:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);	
 	}
 
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index f10c89926d6..e929e028849 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -49,7 +49,6 @@ void				filelist_free_icons();
 struct FileList *	filelist_copy(struct FileList* filelist);
 int					filelist_find(struct FileList* filelist, char *file);
 void				filelist_free(struct FileList* filelist);
-void				filelist_freelib(struct FileList* filelist);
 void				filelist_sort(struct FileList* filelist, short sort);
 int					filelist_numfiles(struct FileList* filelist);
 const char *		filelist_dir(struct FileList* filelist);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index d57fc7f90bc..ea42ad80fe6 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -84,7 +84,7 @@
 FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile)
 {
 	if (!sfile->params) {
-		ED_fileselect_set_params(sfile, "", "/", 0, FILE_SHORTDISPLAY, 0, FILE_SORTALPHA);
+		ED_fileselect_set_params(sfile, "", "/", 0, FILE_SHORTDISPLAY, 0, FILE_SORT_ALPHA);
 	}
 	return sfile->params;
 }
@@ -159,7 +159,7 @@ float file_string_width(const char* str)
 {
 	uiStyle *style= U.uistyles.first;
 	uiStyleFontSet(&style->widget);
-	return BLF_width(str);
+	return BLF_width((char *)str);
 }
 
 float file_font_pointsize()
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 59e8dcf82e6..a87ad4c4fd8 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -65,7 +65,6 @@ struct _FSMenuEntry {
 
 	char *path;
 	short save;
-	short xs, ys;
 };
 
 typedef struct FSMenu
@@ -74,9 +73,6 @@ typedef struct FSMenu
 	FSMenuEntry *fsmenu_bookmarks;
 	FSMenuEntry *fsmenu_recent;
 
-	FSMenuCategory selected_category;
-	int selected_entry;
-
 } FSMenu;
 
 static FSMenu *g_fsmenu = NULL;
@@ -89,17 +85,6 @@ struct FSMenu* fsmenu_get(void)
 	return g_fsmenu;
 }
 
-void fsmenu_select_entry(struct FSMenu* fsmenu, FSMenuCategory category, int index)
-{
-	fsmenu->selected_category = category;
-	fsmenu->selected_entry = index;
-}
-
-int	fsmenu_is_selected(struct FSMenu* fsmenu, FSMenuCategory category, int index)
-{
-	return (category==fsmenu->selected_category) && (index==fsmenu->selected_entry);
-}
-
 static FSMenuEntry *fsmenu_get_category(struct FSMenu* fsmenu, FSMenuCategory category)
 {
 	FSMenuEntry *fsms = NULL;
@@ -154,36 +139,16 @@ char *fsmenu_get_entry(struct FSMenu* fsmenu, FSMenuCategory category, int idx)
 	return fsme?fsme->path:NULL;
 }
 
-void fsmenu_set_pos(struct FSMenu* fsmenu, FSMenuCategory category, int idx, short xs, short ys)
+short fsmenu_can_save (struct FSMenu* fsmenu, FSMenuCategory category, int idx)
 {
 	FSMenuEntry *fsme;
 
 	for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
 		idx--;
 
-	if (fsme) {
-		fsme->xs = xs;
-		fsme->ys = ys;
-	}
+	return fsme?fsme->save:0;
 }
 
-int	fsmenu_get_pos (struct FSMenu* fsmenu, FSMenuCategory category, int idx, short* xs, short* ys)
-{
-	FSMenuEntry *fsme;
-
-	for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
-		idx--;
-
-	if (fsme) {
-		*xs = fsme->xs;
-		*ys = fsme->ys;
-		return 1;
-	}
-
-	return 0;
-}
-
-
 void fsmenu_insert_entry(struct FSMenu* fsmenu, FSMenuCategory category, char *path, int sorted, short save)
 {
 	FSMenuEntry *prev;
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index c51c45b7dc4..2cab622d523 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -52,22 +52,15 @@ int		fsmenu_get_nentries		(struct FSMenu* fsmenu, FSMenuCategory category);
 	 */
 char*	fsmenu_get_entry		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
 
-void	fsmenu_select_entry		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
-
-int		fsmenu_is_selected		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
-
-	/** Sets the position of the  fsmenu entry at @a index */
-void	fsmenu_set_pos			(struct FSMenu* fsmenu, FSMenuCategory category, int index, short xs, short ys);
-
-	/** Returns the position of the  fsmenu entry at @a index. return value is 1 if successful, 0 otherwise */
-int		fsmenu_get_pos			(struct FSMenu* fsmenu, FSMenuCategory category, int index, short* xs, short* ys);
-
 	/** Inserts a new fsmenu entry with the given @a path.
 	 * Duplicate entries are not added.
 	 * @param sorted Should entry be inserted in sorted order?
 	 */
 void	fsmenu_insert_entry		(struct FSMenu* fsmenu, FSMenuCategory category, char *path, int sorted, short save);
 
+	/** Return whether the entry was created by the user and can be saved and deleted */
+short   fsmenu_can_save			(struct FSMenu* fsmenu, FSMenuCategory category, int index);
+
 	/** Removes the fsmenu entry at the given @a index. */
 void	fsmenu_remove_entry		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
 
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 37d8f2bffa4..156c7d6f9be 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -163,6 +163,46 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
 	return (SpaceLink *)sfilen;
 }
 
+static void file_refresh(const bContext *C, ScrArea *sa)
+{
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	FileSelectParams *params = ED_fileselect_get_params(sfile);
+
+	if (!sfile->files) {
+		sfile->files = filelist_new();
+		filelist_setdir(sfile->files, params->dir);
+		params->active_file = -1; // added this so it opens nicer (ton)
+	}
+	filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT);
+	if (filelist_empty(sfile->files))
+	{
+		filelist_readdir(sfile->files);
+	}
+	filelist_setfilter(sfile->files, params->flag & FILE_FILTER ? params->filter : 0);	
+	if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort);		
+}
+
+static void file_listener(ScrArea *sa, wmNotifier *wmn)
+{
+	SpaceFile* sfile = (SpaceFile*)sa->spacedata.first;
+
+	/* context changes */
+	switch(wmn->category) {
+		case NC_FILE:
+			switch (wmn->data) {
+				case ND_FILELIST:
+					if (sfile->files) filelist_free(sfile->files);
+					ED_area_tag_refresh(sa);
+					ED_area_tag_redraw(sa);
+					break;
+				case ND_PARAMS:
+					ED_area_tag_refresh(sa);
+					ED_area_tag_redraw(sa);
+					break;
+			}
+			break;
+	}
+}
 
 /* add handlers, stuff you only do once or on area/region changes */
 static void file_main_area_init(wmWindowManager *wm, ARegion *ar)
@@ -188,31 +228,9 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
 	View2D *v2d= &ar->v2d;
 	View2DScrollers *scrollers;
 	float col[3];
-	
-	if (!sfile->files) {
-		sfile->files = filelist_new();
-		filelist_setdir(sfile->files, params->dir);
-		params->active_file = -1; // added this so it opens nicer (ton)
-	}
 
 	layout = ED_fileselect_get_layout(sfile, ar);
 
-	if (filelist_empty(sfile->files))
-	{
-		unsigned int filter = 0;
-		filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT);
-		if (params->flag & FILE_FILTER) {
-			filter = params->filter ;
-		} else {
-			filter = 0;
-		}
-
-		filelist_setfilter(sfile->files, filter);
-		filelist_readdir(sfile->files);
-		
-		if(params->sort!=FILE_SORTALPHA) filelist_sort(sfile->files, params->sort);		
-	}
-
 	/* clear and setup matrix */
 	UI_GetThemeColor3fv(TH_BACK, col);
 	glClearColor(col[0], col[1], col[2], 0.0);
@@ -274,20 +292,25 @@ void file_operatortypes(void)
 	WM_operatortype_append(FILE_OT_parent);
 	WM_operatortype_append(FILE_OT_refresh);
 	WM_operatortype_append(FILE_OT_bookmark_toggle);
+	WM_operatortype_append(FILE_OT_add_bookmark);
+	WM_operatortype_append(FILE_OT_delete_bookmark);
+	WM_operatortype_append(FILE_OT_hidedot);
 }
 
 /* NOTE: do not add .blend file reading on this level */
 void file_keymap(struct wmWindowManager *wm)
 {
 	ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
+	WM_keymap_add_item(keymap, "FILE_OT_bookmark_toggle", NKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_highlight", MOUSEMOVE, KM_ANY, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0);
-	
+	WM_keymap_add_item(keymap, "FILE_OT_add_bookmark", BKEY, KM_PRESS, KM_CTRL, 0);
+	WM_keymap_add_item(keymap, "FILE_OT_hidedot", HKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_loadimages", TIMER1, KM_ANY, KM_ANY, 0);
-
+	
 	keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select_bookmark", LEFTMOUSE, KM_PRESS, 0, 0);
 }
@@ -295,56 +318,31 @@ void file_keymap(struct wmWindowManager *wm)
 
 static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
 {
-	ListBase *keymap;
-
-	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
-	/* own keymap */
-	keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
-	WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, NULL);
+	ED_region_panels_init(wm, ar);
 }
 
 static void file_channel_area_draw(const bContext *C, ARegion *ar)
 {
-	View2D *v2d= &ar->v2d;
-	float col[3];
-
-	UI_GetThemeColor3fv(TH_PANEL, col);
-	glClearColor(col[0], col[1], col[2], 0.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-
-	/* data... */
-	UI_view2d_view_ortho(C, v2d);
+	ED_region_panels(C, ar, 1, NULL);
+}
 
-	file_draw_fsmenu(C, ar);
+static void file_channel_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+	/* context changes */
+	switch(wmn->category) {
+		
+	}
 }
 
 /* add handlers, stuff you only do once or on area/region changes */
 static void file_header_area_init(wmWindowManager *wm, ARegion *ar)
 {
-	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+	ED_region_header_init(ar);
 }
 
 static void file_header_area_draw(const bContext *C, ARegion *ar)
 {
-	float col[3];
-	
-	/* clear */
-	if(ED_screen_area_active(C))
-		UI_GetThemeColor3fv(TH_HEADER, col);
-	else
-		UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-	
-	glClearColor(col[0], col[1], col[2], 0.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-	
-	/* set view2d view matrix for scrolling (without scrollers) */
-	UI_view2d_view_ortho(C, &ar->v2d);
-	
-	file_header_buttons(C, ar);
-	
-	/* restore view matrix? */
-	UI_view2d_view_restore(C);
+	ED_region_header(C, ar);
 }
 
 /* add handlers, stuff you only do once or on area/region changes */
@@ -386,6 +384,8 @@ void ED_spacetype_file(void)
 	st->free= file_free;
 	st->init= file_init;
 	st->duplicate= file_duplicate;
+	st->refresh= file_refresh;
+	st->listener= file_listener;
 	st->operatortypes= file_operatortypes;
 	st->keymap= file_keymap;
 	
@@ -405,6 +405,7 @@ void ED_spacetype_file(void)
 	art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
 	art->init= file_header_area_init;
 	art->draw= file_header_area_draw;
+	// art->listener= file_header_area_listener;
 	BLI_addhead(&st->regiontypes, art);
 	
 	/* regions: ui */
@@ -421,10 +422,13 @@ void ED_spacetype_file(void)
 	art->regionid = RGN_TYPE_CHANNELS;
 	art->minsizex= 240;
 	art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+	art->listener= file_channel_area_listener;
 	art->init= file_channel_area_init;
 	art->draw= file_channel_area_draw;
 	BLI_addhead(&st->regiontypes, art);
-	
+	file_panels_register(art);
+
+
 	BKE_spacetype_register(st);
 
 }
diff --git a/source/blender/editors/space_graph/Makefile b/source/blender/editors/space_graph/Makefile
index 340495ecc79..e04a354fb1d 100644
--- a/source/blender/editors/space_graph/Makefile
+++ b/source/blender/editors/space_graph/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index acf712d0147..ddf4105fdf4 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawipo.c 17512 2008-11-20 05:55:42Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 49397ed0edd..b624d02a633 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 9aaef9fca8a..7746f49d135 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_image/Makefile b/source/blender/editors/space_image/Makefile
index 44d841a0606..e7e9a9b5665 100644
--- a/source/blender/editors/space_image/Makefile
+++ b/source/blender/editors/space_image/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index b5df0257e71..edf9bcbd896 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -383,6 +383,7 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block
 	}
 }
 
+#if 0
 static void image_panel_view_properties(const bContext *C, Panel *pa)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
@@ -439,6 +440,7 @@ static void image_panel_view_properties(const bContext *C, Panel *pa)
 	}
 	image_editcursor_buts(C, &ar->v2d, block);
 }
+#endif
 
 void brush_buttons(const bContext *C, uiBlock *block, short fromsima,
 				   int evt_nop, int evt_change,
@@ -1023,42 +1025,53 @@ static void image_load_fs_cb(bContext *C, void *ima_pp_v, void *iuser_v)
 static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	BKE_image_multilayer_index(rr_v, iuser_v); 
+	WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 }
 static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	RenderResult *rr= rr_v;
 	ImageUser *iuser= iuser_v;
 	int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0);  /* fake compo result layer */
-	if(iuser->layerlayerlayer++;
-	BKE_image_multilayer_index(rr, iuser); 
+		BKE_image_multilayer_index(rr, iuser); 
+		WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
+	}
 }
 static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	ImageUser *iuser= iuser_v;
-	if(iuser->layer>0)
+
+	if(iuser->layer>0) {
 		iuser->layer--;
-	BKE_image_multilayer_index(rr_v, iuser); 
+		BKE_image_multilayer_index(rr_v, iuser); 
+		WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
+	}
 }
 static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	RenderResult *rr= rr_v;
 	ImageUser *iuser= iuser_v;
 	RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer);
+
 	if(rl) {
 		int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0);	/* builtin render result has no combined pass in list */
 		if(iuser->passpass++;
 			BKE_image_multilayer_index(rr, iuser); 
+			WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 		}
 	}
 }
 static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	ImageUser *iuser= iuser_v;
+
 	if(iuser->pass>0) {
 		iuser->pass--;
 		BKE_image_multilayer_index(rr_v, iuser); 
+		WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 	}
 }
 
@@ -1075,7 +1088,7 @@ static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v)
 				}
 				
 				if ((G.fileflags & G_AUTOPACK) == 0) {
-					unpackImage(ima, PF_ASK);
+					unpackImage(NULL, ima, PF_ASK); /* XXX report errors */
 					ED_undo_push(C, "Unpack image");
 				}
 			} 
@@ -1084,7 +1097,7 @@ static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v)
 				if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
 					// XXX error("Can't pack painted image. Save image or use Repack as PNG.");
 				} else {
-					ima->packedfile = newPackedFile(ima->name);
+					ima->packedfile = newPackedFile(NULL, ima->name); /* XXX report errors */
 					ED_undo_push(C, "Pack image");
 				}
 			}
@@ -1353,6 +1366,23 @@ void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, I
 	 uiBlockEndAlign(block);
 }	
 
+void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
+{
+	uiBlock *block= uiLayoutFreeBlock(layout);
+	Scene *scene= CTX_data_scene(C);
+	RenderResult *rr;
+
+	/* render layers and passes */
+	if(ima && iuser) {
+		rr= BKE_image_get_renderresult(scene, ima);
+
+		if(rr) {
+			uiBlockBeginAlign(block);
+			uiblock_layer_pass_buttons(block, rr, iuser, 0, 0, 0, 160);
+			uiBlockEndAlign(block);
+		}
+	}
+}
 
 static void image_panel_properties(const bContext *C, Panel *pa)
 {
@@ -1377,12 +1407,6 @@ void image_buttons_register(ARegionType *art)
 	pt->draw= image_panel_properties;
 	BLI_addtail(&art->paneltypes, pt);
 
-	pt= MEM_callocN(sizeof(PanelType), "spacetype image view properties");
-	strcpy(pt->idname, "IMAGE_PT_view_properties");
-	strcpy(pt->label, "View Properties");
-	pt->draw= image_panel_view_properties;
-	BLI_addtail(&art->paneltypes, pt);
-
 	pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint");
 	strcpy(pt->idname, "IMAGE_PT_paint");
 	strcpy(pt->label, "Paint");
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 122e298baaa..e61931f2fad 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -311,12 +311,14 @@ static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, fl
 //	glColorMask(1, 1, 1, 1);
 }
 
+#ifdef WITH_LCMS
 static void sima_draw_colorcorrected_pixels(float x1, float y1, ImBuf *ibuf)
 {
 	colorcorrection_do_ibuf(ibuf, "MONOSCNR.ICM"); /* path is hardcoded here, find some place better */
 	
 	glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->crect);
 }
+#endif
 
 static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti)
 {
@@ -450,7 +452,7 @@ static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty,
 	return rectmain;
 }
 
-static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
+static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
 {
 	unsigned int *rect;
 	int dx, dy, sx, sy, x, y;
@@ -477,7 +479,7 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, I
 	/* draw repeated */
 	for(sy=0; sy+dy<=ibuf->y; sy+= dy) {
 		for(sx=0; sx+dx<=ibuf->x; sx+= dx) {
-			UI_view2d_view_to_region(&ar->v2d, (float)sx/(float)ibuf->x, (float)sy/(float)ibuf->y, &x, &y);
+			UI_view2d_to_region_no_clip(&ar->v2d, fx + (float)sx/(float)ibuf->x, fy + (float)sy/(float)ibuf->y, &x, &y);
 
 			glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect);
 		}
@@ -488,16 +490,19 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, I
 	MEM_freeN(rect);
 }
 
-static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float zoomx, float zoomy)
+static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
 {
 	float x, y;
 	double time_current;
 	
 	time_current = PIL_check_seconds_timer();
 
-	for(x=ar->v2d.cur.xmin; xv2d.cur.xmax; x += zoomx) { 
-		for(y=ar->v2d.cur.ymin; yv2d.cur.ymax; y += zoomy) { 
-			draw_image_buffer(sima, ar, scene, ibuf, x, y, zoomx, zoomy);
+	for(x=floor(ar->v2d.cur.xmin); xv2d.cur.xmax; x += 1.0f) { 
+		for(y=floor(ar->v2d.cur.ymin); yv2d.cur.ymax; y += 1.0f) { 
+			if(ima && (ima->tpageflag & IMA_TILES))
+				draw_image_buffer_tiled(sima, ar, ima, ibuf, x, y, zoomx, zoomy);
+			else
+				draw_image_buffer(sima, ar, scene, ibuf, x, y, zoomx, zoomy);
 
 			/* only draw until running out of time */
 			if((PIL_check_seconds_timer() - time_current) > 0.25)
@@ -667,9 +672,9 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
 	if(ibuf==NULL)
 		draw_image_grid(ar, zoomx, zoomy);
 	else if(sima->flag & SI_DRAW_TILE)
-		draw_image_buffer_repeated(sima, ar, scene, ibuf, zoomx, zoomy);
+		draw_image_buffer_repeated(sima, ar, scene, ima, ibuf, zoomx, zoomy);
 	else if(ima && (ima->tpageflag & IMA_TILES))
-		draw_image_buffer_tiled(sima, ar, ima, ibuf, zoomx, zoomy);
+		draw_image_buffer_tiled(sima, ar, ima, ibuf, 0.0f, 0.0, zoomx, zoomy);
 	else
 		draw_image_buffer(sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy);
 
@@ -699,12 +704,5 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
 		}
 	}
 #endif
-
-#if 0
-	/* it is important to end a view in a transform compatible with buttons */
-	bwin_scalematrix(sa->win, sima->blockscale, sima->blockscale, sima->blockscale);
-	if(!(G.rendering && show_render))
-		image_blockhandlers(sa);
-#endif
 }
 
diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c
index adf4772efde..9550c4c3a29 100644
--- a/source/blender/editors/space_image/image_header.c
+++ b/source/blender/editors/space_image/image_header.c
@@ -802,11 +802,11 @@ void image_header_buttons(const bContext *C, ARegion *ar)
 			uiBlockBeginAlign(block);
 			
 			uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
-				xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
+				xco,yco,XIC,YIC, &scene->toolsettings->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
 			uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
-				xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
+				xco+=XIC,yco,XIC,YIC, &scene->toolsettings->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
 			uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
-				xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
+				xco+=XIC,yco,XIC,YIC, &scene->toolsettings->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
 
 			uiBlockEndAlign(block);
 		}
@@ -837,14 +837,14 @@ void image_header_buttons(const bContext *C, ARegion *ar)
 		/* snap options, identical to options in 3d view header */
 		uiBlockBeginAlign(block);
 
-		if (scene->snap_flag & SCE_SNAP) {
-			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
+		if (scene->toolsettings->snap_flag & SCE_SNAP) {
+			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
 			xco+= XIC;
-			uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
+			uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->toolsettings->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
 			xco+= 70;
 		}
 		else {
-			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
+			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
 			xco+= XIC;
 		}
 
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 537996601b8..24781cc115e 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -577,34 +577,30 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
 
 /**************** load/replace/save callbacks ******************/
 
-static char *filesel_imagetype_string(Image *ima)
-{
-	char *strp, *str= MEM_callocN(15*32, "menu for filesel");
-	
-	strp= str;
-	str += sprintf(str, "Save Image as: %%t|");
-	str += sprintf(str, "Targa %%x%d|", R_TARGA);
-	str += sprintf(str, "Targa Raw %%x%d|", R_RAWTGA);
-	str += sprintf(str, "PNG %%x%d|", R_PNG);
-	str += sprintf(str, "BMP %%x%d|", R_BMP);
-	str += sprintf(str, "Jpeg %%x%d|", R_JPEG90);
+/* XXX make dynamic */
+static const EnumPropertyItem image_file_type_items[] = {
+		{R_TARGA, "TARGA", 0, "Targa", ""},
+		{R_RAWTGA, "TARGA RAW", 0, "Targa Raw", ""},
+		{R_PNG, "PNG", 0, "PNG", ""},
+		{R_BMP, "BMP", 0, "BMP", ""},
+		{R_JPEG90, "JPEG", 0, "Jpeg", ""},
 #ifdef WITH_OPENJPEG
-	str += sprintf(str, "Jpeg 2000 %%x%d|", R_JP2);
+		{R_JP2, "JPEG_2000", 0, "Jpeg 2000", ""},
 #endif
-	str += sprintf(str, "Iris %%x%d|", R_IRIS);
-	if(G.have_libtiff)
-		str += sprintf(str, "Tiff %%x%d|", R_TIFF);
-	str += sprintf(str, "Radiance HDR %%x%d|", R_RADHDR);
-	str += sprintf(str, "Cineon %%x%d|", R_CINEON);
-	str += sprintf(str, "DPX %%x%d|", R_DPX);
+		{R_IRIS, "IRIS", 0, "Iris", ""},
+	//if(G.have_libtiff)
+		{R_TIFF, "TIFF", 0, "Tiff", ""},
+		{R_RADHDR, "RADIANCE_HDR", 0, "Radiance HDR", ""},
+		{R_CINEON, "CINEON", 0, "Cineon", ""},
+		{R_DPX, "DPX", 0, "DPX", ""},
 #ifdef WITH_OPENEXR
-	str += sprintf(str, "OpenEXR %%x%d|", R_OPENEXR);
+		{R_OPENEXR, "OPENEXR", 0, "OpenEXR", ""},
 	/* saving sequences of multilayer won't work, they copy buffers  */
-	if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
-	else str += sprintf(str, "MultiLayer %%x%d|", R_MULTILAYER);
+	/*if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
+	else*/
+		{R_MULTILAYER, "MULTILAYER", 0, "MultiLayer", ""},
 #endif	
-	return strp;
-}
+		{0, NULL, 0, NULL, NULL}};
 
 static void image_filesel(bContext *C, wmOperator *op, const char *path)
 {
@@ -799,7 +795,9 @@ static int save_as_exec(bContext *C, wmOperator *op)
 	if(!ima)
 		return OPERATOR_CANCELLED;
 
+	sima->imtypenr= RNA_enum_get(op->ptr, "file_type");
 	RNA_string_get(op->ptr, "filename", str);
+
 	save_image_doit(C, sima, scene, op, str);
 
 	return OPERATOR_FINISHED;
@@ -820,10 +818,6 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
 	/* always opens fileselect */
 	if(ibuf) {
-		char *strp;
-		
-		strp= filesel_imagetype_string(ima); // XXX unused still
-		
 		/* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
 		if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
 			sima->imtypenr= R_MULTILAYER;
@@ -831,14 +825,14 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
 			sima->imtypenr= scene->r.imtype;
 		else
 			sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
+
+		RNA_enum_set(op->ptr, "file_type", sima->imtypenr);
 		
 		if(ibuf->name[0]==0)
 			BLI_strncpy(ibuf->name, G.ima, FILE_MAX);
 		
 		// XXX note: we can give default menu enums to operator for this 
 		image_filesel(C, op, ibuf->name);
-
-		MEM_freeN(strp);
 		
 		return OPERATOR_RUNNING_MODAL;
 	}
@@ -862,6 +856,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
 
 	/* properties */
 	RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "File path to save image to.");
+	RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as.");
 }
 
 /******************** save image operator ********************/
@@ -1119,7 +1114,7 @@ static int pack_exec(bContext *C, wmOperator *op)
 	if(as_png)
 		BKE_image_memorypack(ima);
 	else
-		ima->packedfile= newPackedFile(ima->name);
+		ima->packedfile= newPackedFile(op->reports, ima->name);
 
 	return OPERATOR_FINISHED;
 }
@@ -1167,13 +1162,96 @@ void IMAGE_OT_pack(wmOperatorType *ot)
 
 /********************* unpack operator *********************/
 
+/* XXX move this to some place where it can be reused */
+
+const EnumPropertyItem unpack_method_items[] = {
+	{PF_USE_LOCAL, "USE_LOCAL", 0, "Use Local File", ""},
+	{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write Local File (overwrite existing)", ""},
+	{PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use Original File", ""},
+	{PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write Original File (overwrite existing)", ""},
+	{0, NULL, 0, NULL, NULL}};
+
+void unpack_menu(bContext *C, char *opname, char *abs_name, char *folder, PackedFile *pf)
+{
+	uiPopupMenu *pup;
+	uiLayout *layout;
+	char line[FILE_MAXDIR + FILE_MAXFILE + 100];
+	char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+	
+	strcpy(local_name, abs_name);
+	BLI_splitdirstring(local_name, fi);
+	sprintf(local_name, "//%s/%s", folder, fi);
+
+	pup= uiPupMenuBegin(C, "Unpack file", 0);
+	layout= uiPupMenuLayout(pup);
+
+	uiItemEnumO(layout, "Remove Pack", 0, opname, "method", PF_REMOVE);
+
+	if(strcmp(abs_name, local_name)) {
+		switch(checkPackedFile(local_name, pf)) {
+			case PF_NOFILE:
+				sprintf(line, "Create %s", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_LOCAL);
+				break;
+			case PF_EQUAL:
+				sprintf(line, "Use %s (identical)", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_USE_LOCAL);
+				break;
+			case PF_DIFFERS:
+				sprintf(line, "Use %s (differs)", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_USE_LOCAL);
+				sprintf(line, "Overwrite %s", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_LOCAL);
+				break;
+		}
+	}
+	
+	switch(checkPackedFile(abs_name, pf)) {
+		case PF_NOFILE:
+			sprintf(line, "Create %s", abs_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_ORIGINAL);
+			break;
+		case PF_EQUAL:
+			sprintf(line, "Use %s (identical)", abs_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_USE_ORIGINAL);
+			break;
+		case PF_DIFFERS:
+			sprintf(line, "Use %s (differs)", local_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_USE_ORIGINAL);
+			sprintf(line, "Overwrite %s", local_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_ORIGINAL);
+			break;
+	}
+
+	uiPupMenuEnd(C, pup);
+}
+
 static int unpack_exec(bContext *C, wmOperator *op)
 {
 	Image *ima= CTX_data_edit_image(C);
+	int method= RNA_enum_get(op->ptr, "method");
 
-	if(!ima)
+	if(!ima || !ima->packedfile)
 		return OPERATOR_CANCELLED;
-	if(!ima->packedfile)
+
+	if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
+		BKE_report(op->reports, RPT_ERROR, "Can't unpack movie or image sequence.");
+		return OPERATOR_CANCELLED;
+	}
+
+	if(G.fileflags & G_AUTOPACK)
+		BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
+	
+	unpackImage(op->reports, ima, method);
+
+	return OPERATOR_FINISHED;
+}
+
+static int unpack_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Image *ima= CTX_data_edit_image(C);
+
+	if(!ima || !ima->packedfile)
 		return OPERATOR_CANCELLED;
 
 	if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
@@ -1184,7 +1262,7 @@ static int unpack_exec(bContext *C, wmOperator *op)
 	if(G.fileflags & G_AUTOPACK)
 		BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
 	
-	unpackImage(ima, PF_ASK);
+	unpack_menu(C, "IMAGE_OT_unpack", ima->name, "textures", ima->packedfile);
 
 	return OPERATOR_FINISHED;
 }
@@ -1197,10 +1275,14 @@ void IMAGE_OT_unpack(wmOperatorType *ot)
 	
 	/* api callbacks */
 	ot->exec= unpack_exec;
+	ot->invoke= unpack_invoke;
 	ot->poll= space_image_poll;
 
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_enum(ot->srna, "method", unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack.");
 }
 
 /******************** sample image operator ********************/
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 49f950fe67b..7d6faa00dfc 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -327,12 +327,10 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *sce
 #endif
 	if(sima->image) {
 		ImBuf *ibuf= ED_space_image_buffer(sima);
-		float xuser_asp, yuser_asp;
 		
-		ED_image_aspect(sima->image, &xuser_asp, &yuser_asp);
 		if(ibuf) {
-			width= ibuf->x*xuser_asp;
-			height= ibuf->y*yuser_asp;
+			width= ibuf->x;
+			height= ibuf->y;
 		}
 		else if(sima->image->type==IMA_TYPE_R_RESULT) {
 			/* not very important, just nice */
@@ -683,7 +681,7 @@ void ED_image_aspect(Image *ima, float *aspx, float *aspy)
 	*aspx= *aspy= 1.0;
 
 	if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
-	   (ima->tpageflag & IMA_TILES) || (ima->aspx==0.0 || ima->aspy==0.0))
+	   (ima->aspx==0.0 || ima->aspy==0.0))
 		return;
 
 	/* x is always 1 */
diff --git a/source/blender/editors/space_info/Makefile b/source/blender/editors/space_info/Makefile
index bc04ddc7824..931c2f2097c 100644
--- a/source/blender/editors/space_info/Makefile
+++ b/source/blender/editors/space_info/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript
index 05afcae162e..01268115687 100644
--- a/source/blender/editors/space_info/SConscript
+++ b/source/blender/editors/space_info/SConscript
@@ -11,7 +11,4 @@ defs = []
 if env['WITH_BF_GAMEENGINE']:
 	defs.append('GAMEBLENDER=1')
 
-	if env['WITH_BF_SOLID']:
-		defs.append('USE_SUMO_SOLID')
-
 env.BlenderLib ( 'bf_editors_space_info', sources, Split(incs), defs, libtype=['core'], priority=[70] )
diff --git a/source/blender/editors/space_info/info_header.c b/source/blender/editors/space_info/info_header.c
deleted file mode 100644
index ac39c67d8f2..00000000000
--- a/source/blender/editors/space_info/info_header.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/**
- * $Id: info_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. 
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- *
- * 
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include 
-#include 
-
-#include "DNA_packedFile_types.h"
-#include "DNA_space_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
-
-#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_main.h"
-#include "BKE_packedFile.h"
-#include "BKE_screen.h"
-
-#include "ED_screen.h"
-#include "ED_types.h"
-#include "ED_util.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
-
-#include "IMB_imbuf_types.h"
-
-#include "info_intern.h"
-
-static int pupmenu() {return 0;}
-static int okee() {return 0;}
-static int error() {return 0;}
-
-/* ************************ header area region *********************** */
-
-#define B_STOPRENDER	1
-#define B_STOPCAST		2
-#define B_STOPANIM		3
-
-static void do_viewmenu(bContext *C, void *arg, int event)
-{
-}
-
-static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
-{
-	ScrArea *curarea= CTX_wm_area(C);
-	uiBlock *block;
-	short yco= 0, menuwidth=120;
-	
-	block= uiBeginBlock(C, ar, "dummy_viewmenu", UI_EMBOSSP);
-	uiBlockSetButmFunc(block, do_viewmenu, NULL);
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20, 
-					 menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-	
-	if(curarea->headertype==HEADERTOP) {
-		uiBlockSetDirection(block, UI_DOWN);
-	}
-	else {
-		uiBlockSetDirection(block, UI_TOP);
-		uiBlockFlipOrder(block);
-	}
-	
-	uiTextBoundsBlock(block, 50);
-	uiEndBlock(C, block);
-	
-	return block;
-}
-
-static int buttons_do_unpack()
-{
-	int how;
-	char menu[2048];
-	char *line = menu;
-	int ret_value = 1, count = 0;
-	
-	count = countPackedFiles();
-	
-	if(!count) {
-		pupmenu("No packed files. Autopack disabled");
-		return ret_value;
-	}
-	if (count == 1)
-		line += sprintf(line, "Unpack 1 file%%t");
-	else
-		line += sprintf(line, "Unpack %d files%%t", count);
-	
-	line += sprintf(line, "|Use files in current directory (create when necessary)%%x%d", PF_USE_LOCAL);
-	line += sprintf(line, "|Write files to current directory (overwrite existing files)%%x%d", PF_WRITE_LOCAL);
-	line += sprintf(line, "|%%l|Use files in original location (create when necessary)%%x%d", PF_USE_ORIGINAL);
-	line += sprintf(line, "|Write files to original location (overwrite existing files)%%x%d", PF_WRITE_ORIGINAL);
-	line += sprintf(line, "|%%l|Disable AutoPack, keep all packed files %%x%d", PF_KEEP);
-	line += sprintf(line, "|Ask for each file %%x%d", PF_ASK);
-	
-	how = pupmenu(menu);
-	
-	if(how == -1)
-		ret_value = 0;
-	else {
-		if (how != PF_KEEP) unpackAll(how);
-		G.fileflags &= ~G_AUTOPACK;
- 	}
- 	
-	return ret_value;
-}
-
-static void check_packAll()
-{
-	// first check for dirty images
-	Image *ima;
-	
-	for(ima = G.main->image.first; ima; ima= ima->id.next) {
-		if (ima->ibufs.first) { /* XXX FIX */
-			ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
-			
-			if (ibuf && (ibuf->userflags &= IB_BITMAPDIRTY))
-				break;
-		}
-	}
-
-	if (ima == NULL || okee("Some images are painted on. These changes will be lost. Continue ?")) {
-		packAll();
-		G.fileflags |= G_AUTOPACK;
-	}
-}
-
-static void do_info_externalfiles(bContext *C, void *arg, int event)
-{
-	switch (event) {
-		
-		case 1: /* pack data */
-			check_packAll();
-			break;
-		case 3: /* unpack data */
-			if (buttons_do_unpack() != 0) {
-				/* Clear autopack bit only if user selected one of the unpack options */
-				G.fileflags &= ~G_AUTOPACK;
-			}
-			break;
-		case 10: /* make all paths relative */
-			if (G.relbase_valid) {
-				int tot,changed,failed,linked;
-				char str[512];
-				char txtname[24]; /* text block name */
-				txtname[0] = '\0';
-				makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
-				if (failed) sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
-				else		sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-				pupmenu(str);
-			} else {
-				pupmenu("Can't set relative paths with an unsaved blend file");
-			}
-			break;
-		case 11: /* make all paths absolute */
-		{
-			int tot,changed,failed,linked;
-			char str[512];
-			char txtname[24]; /* text block name */
-			txtname[0] = '\0';
-			makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
-			sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-			if (failed) sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
-			else		sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-			
-			pupmenu(str);
-		}
-			break;
-		case 12: /* check images exist */
-		{
-			char txtname[24]; /* text block name */
-			txtname[0] = '\0';
-			
-			/* run the missing file check */
-			checkMissingFiles( txtname );
-			
-			if (txtname[0] == '\0') {
-				okee("No external files missing");
-			} else {
-				char str[128];
-				sprintf(str, "Missing files listed in Text \"%s\"", txtname );
-				error(str);
-			}
-		}
-			break;
-		case 13: /* search for referenced files that are not available  */
-// XXX			if(curarea->spacetype==SPACE_INFO) {
-//				ScrArea *sa;
-//				sa= closest_bigger_area();
-//				areawinset(sa->win);
-//			}
-//			activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles);
-			break;
-	}
-	
-}
-
-
-uiBlock *info_externalfiles(bContext *C, ARegion *ar, void *arg_unused)
-{
-	uiBlock *block;
-	short yco = 20, menuwidth = 120;
-	
-	block= uiBeginBlock(C, ar, "info_externalfiles", UI_EMBOSSP);
-	uiBlockSetButmFunc(block, do_info_externalfiles, NULL);
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into .blend file",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack into Files...",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Absolute",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files...",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files...",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, "");
-	
-	uiBlockSetDirection(block, UI_RIGHT);
-	uiTextBoundsBlock(block, 60);
-	return block;
-}
-
-
-
-static void info_filemenu(bContext *C, uiLayout *layout, void *arg_unused)
-{
-	
-	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_read_homefile"); 
-	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_open_mainfile"); 
-//	uiDefIconTextBlockBut(block, info_openrecentmenu, NULL, ICON_RIGHTARROW_THIN, "Open Recent",0, yco-=20, 120, 19, "");
-//	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
-	
-	uiItemS(layout);
-	
-	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_save_mainfile"); 
-	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_save_as_mainfile"); 
-
-#if 0
-	if(U.flag & USER_FILECOMPRESS) {
-		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
-	} else {
-		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
-	}
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Rendered Image...|F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
-#if GAMEBLENDER == 1
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Game As Runtime...",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
-#endif
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Default Settings|Ctrl U",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 31, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Load Factory Settings",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 32, "");
-	
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link|Shift F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link (Image Browser)|Ctrl F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
-//	uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, "");
-//	uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, "");
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
-	uiBlockSetDirection(block, UI_DOWN);
-	uiTextBoundsBlock(block, 80);
-	
-	uiEndBlock(C, block);
-	return block;
-#endif
-}
-
-
-static void do_info_buttons(bContext *C, void *arg, int event)
-{
-	switch(event) {
-		case B_STOPRENDER:
-			G.afbreek= 1;
-			break;
-		case B_STOPCAST:
-			WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
-			break;
-		case B_STOPANIM:
-			ED_screen_animation_timer(C, 0, 0);
-			break;
-	}
-}
-
-static void screen_idpoin_handle(bContext *C, ID *id, int event)
-{
-	switch(event) {
-		case UI_ID_BROWSE:
-			/* exception: can't set screens inside of area/region handers */
-			WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, id);
-			break;
-		case UI_ID_DELETE:
-			ED_undo_push(C, "");
-			break;
-		case UI_ID_RENAME:
-			break;
-		case UI_ID_ADD_NEW:
-			/* XXX not implemented */
-			break;
-		case UI_ID_OPEN:
-			/* XXX not implemented */
-			break;
-		case UI_ID_ALONE:
-			/* XXX not implemented */
-			break;
-		case UI_ID_PIN:
-			break;
-	}
-}
-
-static void scene_idpoin_handle(bContext *C, ID *id, int event)
-{
-	switch(event) {
-		case UI_ID_BROWSE:
-			/* exception: can't set screens inside of area/region handers */
-			WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, id);
-			break;
-		case UI_ID_DELETE:
-			ED_undo_push(C, "");
-			break;
-		case UI_ID_RENAME:
-			break;
-		case UI_ID_ADD_NEW:
-			/* XXX not implemented */
-			break;
-		case UI_ID_OPEN:
-			/* XXX not implemented */
-			break;
-		case UI_ID_ALONE:
-			/* XXX not implemented */
-			break;
-		case UI_ID_PIN:
-			break;
-	}
-}
-
-static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
-{
-	wmOperatorType *ot= arg2;
-	
-	if(ot)
-		WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
-}
-
-static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
-{
-	wmOperatorType *ot = WM_operatortype_first();
-	
-	for(; ot; ot= ot->next) {
-		
-		if(BLI_strcasestr(ot->name, str)) {
-			if(ot->poll==NULL || ot->poll((bContext *)C)) {
-				char name[256];
-				int len= strlen(ot->name);
-				
-				/* display name for menu, can hold hotkey */
-				BLI_strncpy(name, ot->name, 256);
-				
-				/* check for hotkey */
-				if(len < 256-6) {
-					if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
-						name[len]= '|';
-				}
-				
-				if(0==uiSearchItemAdd(items, name, ot))
-					break;
-			}
-		}
-	}
-}
-
-void info_header_buttons(const bContext *C, ARegion *ar)
-{
-	wmWindow *win= CTX_wm_window(C);
-	bScreen *screen= CTX_wm_screen(C);
-	ScrArea *sa= CTX_wm_area(C);
-	uiBlock *block;
-	int xco, yco= 3;
-	
-	block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS);
-	uiBlockSetHandleFunc(block, do_info_buttons, NULL);
-	
-	xco= ED_area_header_standardbuttons(C, block, yco);
-	
-	if((sa->flag & HEADER_NO_PULLDOWN)==0) {
-		int xmax;
-		
-		xmax= GetButStringLength("File");
-		uiDefMenuBut(block, info_filemenu, NULL, "File", xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Add");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Add",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Timeline");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Timeline",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Game");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Game",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Render");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Render",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Help");
-		uiDefPulldownBut(block, dummy_viewmenu, NULL, "Help",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-	}
-	
-	uiBlockSetEmboss(block, UI_EMBOSS);
-	
-	if(screen->full==0) {
-		xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)win->screen, ID_SCR, NULL, xco, yco,
-						 screen_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE);
-		xco += 8;
-		xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)screen->scene, ID_SCE, NULL, xco, yco,
-							 scene_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE);
-		xco += 8;
-	}	
-
-	if(WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C))) {
-		uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", xco+5,yco,75,19, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
-		xco+= 80;
-	}
-	if(WM_jobs_test(CTX_wm_manager(C), CTX_wm_screen(C))) {
-		uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", xco+5,yco,85,19, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
-		xco+= 90;
-	}
-	if(screen->animtimer) {
-		uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", xco+5,yco,85,19, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
-		xco+= 90;
-	}
-	
-	{
-		static char search[256]= "";
-		uiBut *but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, xco+5, yco, 120, 19, "");
-		
-		uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb);
-
-		xco+= 125;
-	}
-
-	
-	/* always as last  */
-	UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
-	
-	uiEndBlock(C, block);
-	uiDrawBlock(C, block);
-}
-
-
diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h
index 213c0688f20..519364b58d9 100644
--- a/source/blender/editors/space_info/info_intern.h
+++ b/source/blender/editors/space_info/info_intern.h
@@ -30,10 +30,17 @@
 
 /* internal exports only */
 
+struct wmOperatorType;
 
 /* info_header.c */
 void info_header_buttons(const bContext *C, ARegion *ar);
 
+void FILE_OT_pack_all(struct wmOperatorType *ot);
+void FILE_OT_unpack_all(struct wmOperatorType *ot);
+void FILE_OT_make_paths_relative(struct wmOperatorType *ot);
+void FILE_OT_make_paths_absolute(struct wmOperatorType *ot);
+void FILE_OT_report_missing_files(struct wmOperatorType *ot);
+void FILE_OT_find_missing_files(struct wmOperatorType *ot);
 
 #endif /* ED_INFO_INTERN_H */
 
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
new file mode 100644
index 00000000000..56f925a2e81
--- /dev/null
+++ b/source/blender/editors/space_info/info_ops.c
@@ -0,0 +1,397 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include 
+#include 
+
+#include "DNA_packedFile_types.h"
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_bpath.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_packedFile.h"
+#include "BKE_report.h"
+#include "BKE_screen.h"
+
+#include "ED_screen.h"
+#include "ED_types.h"
+#include "ED_util.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_types.h"
+
+#include "info_intern.h"
+
+/********************* pack all operator *********************/
+
+static int pack_all_exec(bContext *C, wmOperator *op)
+{
+	Main *bmain= CTX_data_main(C);
+
+	packAll(bmain, op->reports);
+	G.fileflags |= G_AUTOPACK;
+
+	return OPERATOR_FINISHED;
+}
+
+static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Main *bmain= CTX_data_main(C);
+	Image *ima;
+	ImBuf *ibuf;
+
+	// first check for dirty images
+	for(ima=bmain->image.first; ima; ima=ima->id.next) {
+		if(ima->ibufs.first) { /* XXX FIX */
+			ibuf= BKE_image_get_ibuf(ima, NULL);
+			
+			if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+				break;
+		}
+	}
+
+	if(ima) {
+		uiPupMenuOkee(C, "FILE_OT_pack_all", "Some images are painted on. These changes will be lost. Continue?");
+		return OPERATOR_CANCELLED;
+	}
+
+	return pack_all_exec(C, op);
+}
+
+void FILE_OT_pack_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Pack All";
+	ot->idname= "FILE_OT_pack_all";
+	
+	/* api callbacks */
+	ot->exec= pack_all_exec;
+	ot->invoke= pack_all_invoke;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* unpack all operator *********************/
+
+static const EnumPropertyItem unpack_all_method_items[] = {
+	{PF_USE_LOCAL, "USE_LOCAL", 0, "Use files in current directory (create when necessary)", ""},
+	{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write files to current directory (overwrite existing files)", ""},
+	{PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""},
+	{PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""},
+	{PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""},
+	{PF_ASK, "ASK", 0, "Ask for each file", ""},
+	{0, NULL, 0, NULL, NULL}};
+
+static int unpack_all_exec(bContext *C, wmOperator *op)
+{
+	Main *bmain= CTX_data_main(C);
+	int method= RNA_enum_get(op->ptr, "method");
+
+	if(method != PF_KEEP) unpackAll(bmain, op->reports, method); /* XXX PF_ASK can't work here */
+	G.fileflags &= ~G_AUTOPACK;
+
+	return OPERATOR_FINISHED;
+}
+
+static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Main *bmain= CTX_data_main(C);
+	uiPopupMenu *pup;
+	uiLayout *layout;
+	char title[128];
+	int count = 0;
+	
+	count = countPackedFiles(bmain);
+	
+	if(!count) {
+		BKE_report(op->reports, RPT_WARNING, "No packed files. Autopack disabled.");
+		G.fileflags &= ~G_AUTOPACK;
+		return OPERATOR_CANCELLED;
+	}
+
+	if(count == 1)
+		sprintf(title, "Unpack 1 file");
+	else
+		sprintf(title, "Unpack %d files", count);
+	
+	pup= uiPupMenuBegin(C, title, 0);
+	layout= uiPupMenuLayout(pup);
+
+	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+	uiItemsEnumO(layout, "FILE_OT_unpack_all", "method");
+
+	uiPupMenuEnd(C, pup);
+
+	return OPERATOR_CANCELLED;
+}
+
+void FILE_OT_unpack_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Unpack All";
+	ot->idname= "FILE_OT_unpack_all";
+	
+	/* api callbacks */
+	ot->exec= unpack_all_exec;
+	ot->invoke= unpack_all_invoke;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_enum(ot->srna, "method", unpack_all_method_items, PF_USE_LOCAL, "Method", "How to unpack.");
+}
+
+/********************* make paths relative operator *********************/
+
+static int make_paths_relative_exec(bContext *C, wmOperator *op)
+{
+	char txtname[24]; /* text block name */
+	int tot, changed, failed, linked;
+
+	if(!G.relbase_valid) {
+		BKE_report(op->reports, RPT_WARNING, "Can't set relative paths with an unsaved blend file.");
+		return OPERATOR_CANCELLED;
+	}
+
+	txtname[0] = '\0';
+	makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
+
+	if(failed)
+		BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked); 
+	else
+		BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_make_paths_relative(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Make All Paths Relative";
+	ot->idname= "FILE_OT_make_paths_relative";
+	
+	/* api callbacks */
+	ot->exec= make_paths_relative_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* make paths absolute operator *********************/
+
+static int make_paths_absolute_exec(bContext *C, wmOperator *op)
+{
+	char txtname[24]; /* text block name */
+	int tot, changed, failed, linked;
+
+	if(!G.relbase_valid) {
+		BKE_report(op->reports, RPT_WARNING, "Can't set absolute paths with an unsaved blend file.");
+		return OPERATOR_CANCELLED;
+	}
+
+	txtname[0] = '\0';
+	makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
+
+	if(failed)
+		BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked); 
+	else
+		BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_make_paths_absolute(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Make All Paths Absolute";
+	ot->idname= "FILE_OT_make_paths_absolute";
+	
+	/* api callbacks */
+	ot->exec= make_paths_absolute_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* report missing files operator *********************/
+
+static int report_missing_files_exec(bContext *C, wmOperator *op)
+{
+	char txtname[24]; /* text block name */
+
+	txtname[0] = '\0';
+	
+	/* run the missing file check */
+	checkMissingFiles(txtname);
+	
+	if(txtname[0] == '\0')
+		BKE_report(op->reports, RPT_INFO, "No external files missing.");
+	else
+		BKE_reportf(op->reports, RPT_ERROR, "Missing files listed in Text \"%s\"", txtname);
+	
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_report_missing_files(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Report Missing Files...";
+	ot->idname= "FILE_OT_report_missing_files";
+	
+	/* api callbacks */
+	ot->exec= report_missing_files_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* find missing files operator *********************/
+
+static int find_missing_files_exec(bContext *C, wmOperator *op)
+{
+	char *filename;
+	
+	filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0);
+	findMissingFiles(filename);
+	MEM_freeN(filename);
+
+	return OPERATOR_FINISHED;
+}
+
+static int find_missing_files_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	/* XXX file open button text "Find Missing Files" */
+	WM_event_add_fileselect(C, op); 
+	return OPERATOR_RUNNING_MODAL;
+}
+
+void FILE_OT_find_missing_files(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Find Missing Files...";
+	ot->idname= "FILE_OT_find_missing_files";
+	
+	/* api callbacks */
+	ot->exec= find_missing_files_exec;
+	ot->invoke= find_missing_files_invoke;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "File path of image to open.");
+}
+
+#if 0
+static void info_filemenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+	
+	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_read_homefile"); 
+	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_open_mainfile"); 
+//	uiDefIconTextBlockBut(block, info_openrecentmenu, NULL, ICON_RIGHTARROW_THIN, "Open Recent",0, yco-=20, 120, 19, "");
+//	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+	
+	uiItemS(layout);
+	
+	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_save_mainfile"); 
+	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_save_as_mainfile"); 
+
+#if 0
+	if(U.flag & USER_FILECOMPRESS) {
+		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
+	} else {
+		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
+	}
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Rendered Image...|F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
+#if GAMEBLENDER == 1
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Game As Runtime...",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
+#endif
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Default Settings|Ctrl U",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 31, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Load Factory Settings",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 32, "");
+	
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link|Shift F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link (Image Browser)|Ctrl F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+//	uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, "");
+//	uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, "");
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+	uiBlockSetDirection(block, UI_DOWN);
+	uiTextBoundsBlock(block, 80);
+	
+	uiEndBlock(C, block);
+	return block;
+#endif
+}
+#endif
+
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index d72ecd60da9..7b24e8f4e07 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -151,7 +151,12 @@ static void info_main_area_draw(const bContext *C, ARegion *ar)
 
 void info_operatortypes(void)
 {
-	
+	WM_operatortype_append(FILE_OT_pack_all);
+	WM_operatortype_append(FILE_OT_unpack_all);
+	WM_operatortype_append(FILE_OT_make_paths_relative);
+	WM_operatortype_append(FILE_OT_make_paths_absolute);
+	WM_operatortype_append(FILE_OT_report_missing_files);
+	WM_operatortype_append(FILE_OT_find_missing_files);
 }
 
 void info_keymap(struct wmWindowManager *wm)
@@ -162,29 +167,12 @@ void info_keymap(struct wmWindowManager *wm)
 /* add handlers, stuff you only do once or on area/region changes */
 static void info_header_area_init(wmWindowManager *wm, ARegion *ar)
 {
-	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+	ED_region_header_init(ar);
 }
 
 static void info_header_area_draw(const bContext *C, ARegion *ar)
 {
-	float col[3];
-	
-	/* clear */
-	if(ED_screen_area_active(C))
-		UI_GetThemeColor3fv(TH_HEADER, col);
-	else
-		UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-	
-	glClearColor(col[0], col[1], col[2], 0.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-	
-	/* set view2d view matrix for scrolling (without scrollers) */
-	UI_view2d_view_ortho(C, &ar->v2d);
-	
-	info_header_buttons(C, ar);
-	
-	/* restore view matrix? */
-	UI_view2d_view_restore(C);
+	ED_region_header(C, ar);
 }
 
 static void info_main_area_listener(ARegion *ar, wmNotifier *wmn)
diff --git a/source/blender/editors/space_logic/Makefile b/source/blender/editors/space_logic/Makefile
index e07a5bbf4a9..d5709993368 100644
--- a/source/blender/editors/space_logic/Makefile
+++ b/source/blender/editors/space_logic/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_logic/SConscript b/source/blender/editors/space_logic/SConscript
index 46a9858a836..e32fcc1b535 100644
--- a/source/blender/editors/space_logic/SConscript
+++ b/source/blender/editors/space_logic/SConscript
@@ -12,7 +12,4 @@ defs = []
 if env['WITH_BF_GAMEENGINE']:
 	defs.append('GAMEBLENDER=1')
 
-	if env['WITH_BF_SOLID']:
-		defs.append('USE_SUMO_SOLID')
-
 env.BlenderLib ( 'bf_editors_space_game', sources, Split(incs), defs, libtype=['core'], priority=[120] )
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index 240ddfc2614..b082d5d6ae2 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -1,5 +1,5 @@
 /**
- * $Id: image_buttons.c 20913 2009-06-16 01:22:56Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_logic/logic_header.c b/source/blender/editors/space_logic/logic_header.c
index 00fc130e771..d0e905728be 100644
--- a/source/blender/editors/space_logic/logic_header.c
+++ b/source/blender/editors/space_logic/logic_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: logic_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index b9385a54d34..55e21561c34 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -1,5 +1,5 @@
 /**
- * $Id: logic_window.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -3056,12 +3056,12 @@ void logic_buttons(bContext *C, ARegion *ar)
 	/* ******************************* */
 	xco= 500; yco= 170; width= 300;
 
-	uiDefPulldownBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
+	uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, UI_UNIT_Y, "");
 	
 	uiBlockBeginAlign(block);
-	uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-	uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
-	uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
+	uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+	uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
+	uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
 	uiBlockEndAlign(block);
 	
 	ob= CTX_data_active_object(C);
@@ -3077,9 +3077,9 @@ void logic_buttons(bContext *C, ARegion *ar)
 		/* presume it is only objects for now */
 		uiBlockBeginAlign(block);
 //		if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
-		uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
+		uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
 //		if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
-		uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
+		uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
 		uiBlockEndAlign(block);
 		yco-=20;
 		
@@ -3100,7 +3100,7 @@ void logic_buttons(bContext *C, ARegion *ar)
 		if(ob->scaflag & OB_SHOWCONT) {
 
 			/* first show the state */
-			uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 36, 19, "Object state menu: store and retrieve initial state");
+			uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 36, UI_UNIT_Y, "Object state menu: store and retrieve initial state");
 
 			if (!ob->state)
 				ob->state = 1;
@@ -3116,9 +3116,9 @@ void logic_buttons(bContext *C, ARegion *ar)
 				}
 			}
 			uiBlockBeginAlign(block);
-			uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+226), yco-10, 22, 19, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
-			uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+248), yco-10, 22, 19, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
-			uiDefButBitS(block, TOG, OB_DEBUGSTATE, 0, "D",(short)(xco+270), yco-10, 15, 19, &ob->scaflag, 0, 0, 0, 0, "Print state debug info");
+			uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+226), yco-10, 22, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
+			uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+248), yco-10, 22, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
+			uiDefButBitS(block, TOG, OB_DEBUGSTATE, 0, "D",(short)(xco+270), yco-10, 15, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Print state debug info");
 			uiBlockEndAlign(block);
 
 			yco-=35;
@@ -3142,17 +3142,17 @@ void logic_buttons(bContext *C, ARegion *ar)
 							if (act)
 								act->flag |= ACT_VISIBLE;
 						}
-						uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
-						uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
-						uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)");
+						uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Delete Controller");
+						uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Controller settings");
+						uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)");
 
 						sprintf(name, "%d", first_bit(cont->state_mask)+1);
-						uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)");
+						uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
 				
 						if(cont->flag & CONT_SHOW) {
 							cont->otype= cont->type;
-							uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, 19, &cont->type, 0, 0, 0, 0, "Controller type");
-							but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), 19, cont->name, 0, 31, 0, 0, "Controller name");
+							uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, UI_UNIT_Y, &cont->type, 0, 0, 0, 0, "Controller type");
+							but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), UI_UNIT_Y, cont->name, 0, 31, 0, 0, "Controller name");
 							uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
 				
 							ycoo= yco;
@@ -3162,17 +3162,17 @@ void logic_buttons(bContext *C, ARegion *ar)
 						else {
 							cpack(0x999999);
 							glRecti(xco+22, yco, xco+width-22,yco+19);
-							but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, 19, cont, 0, 0, 0, 0, "Controller type");
+							but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller type");
 							uiButSetFunc(but, sca_move_controller, cont, NULL);
-							but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), 19, cont, 0, 0, 0, 0, "Controller name");
+							but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller name");
 							uiButSetFunc(but, sca_move_controller, cont, NULL);
 							ycoo= yco;
 						}
 				
-						but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+						but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
 						uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
 				
-						uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
+						uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
 						/* offset is >0 if at least one controller was displayed */
 						offset++;
 						yco-=20;
@@ -3188,13 +3188,13 @@ void logic_buttons(bContext *C, ARegion *ar)
 	/* ******************************* */
 	xco= 10; yco= 170; width= 400;
 
-	uiDefPulldownBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, 19, "");
+	uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, UI_UNIT_Y, "");
 	
 	uiBlockBeginAlign(block);
-	uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-	uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
-	uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
-	uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
+	uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+	uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
+	uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+	uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
 	uiBlockEndAlign(block);
 	
 	for(a=0; asensors.first) uiSetCurFont(block, UI_HELVB);
-		uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
+		uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
 //		if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
-		uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
+		uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
 		uiBlockEndAlign(block);
 		yco-=20;
 		
@@ -3226,17 +3226,17 @@ void logic_buttons(bContext *C, ARegion *ar)
 					pin = (slogic->scaflag & BUTS_SENS_STATE && (sens->flag & SENS_SHOW || sens->flag & SENS_PIN)) ? 1:0 ;
 					
 					sens->flag |= SENS_VISIBLE;
-					uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,	xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
+					uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,	xco, yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
 					if (pin)
-						uiDefIconButBitS(block, ICONTOG, SENS_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
+						uiDefIconButBitS(block, ICONTOG, SENS_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
 					
-					uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+					uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Sensor settings");
 
 					ycoo= yco;
 					if(sens->flag & SENS_SHOW)
 					{
-						uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),	(short)(xco+22), yco, 80, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
-						but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), 19, sens->name, 0, 31, 0, 0, "Sensor name");
+						uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),	(short)(xco+22), yco, 80, UI_UNIT_Y, &sens->type, 0, 0, 0, 0, "Sensor type");
+						but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens->name, 0, 31, 0, 0, "Sensor name");
 						uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
 
 						sens->otype= sens->type;
@@ -3246,13 +3246,13 @@ void logic_buttons(bContext *C, ARegion *ar)
 					else {
 						set_col_sensor(sens->type, 1);
 						glRecti(xco+22, yco, xco+width-22,yco+19);
-						but= uiDefBut(block, LABEL, 0, sensor_name(sens->type),	(short)(xco+22), yco, 80, 19, sens, 0, 0, 0, 0, "");
+						but= uiDefBut(block, LABEL, 0, sensor_name(sens->type),	(short)(xco+22), yco, 80, UI_UNIT_Y, sens, 0, 0, 0, 0, "");
 						uiButSetFunc(but, sca_move_sensor, sens, NULL);
-						but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), 19, sens, 0, 31, 0, 0, "");
+						but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, 31, 0, 0, "");
 						uiButSetFunc(but, sca_move_sensor, sens, NULL);
 					}
 
-					but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+					but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
 					uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
 
 					yco-=20;
@@ -3266,13 +3266,13 @@ void logic_buttons(bContext *C, ARegion *ar)
 	/* ******************************* */
 	xco= 900; yco= 170; width= 400;
 	
-	uiDefPulldownBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, 19, "");
+	uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, UI_UNIT_Y, "");
 
 	uiBlockBeginAlign(block);
-	uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-	uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
-	uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
-	uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
+	uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+	uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
+	uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+	uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
 	uiBlockEndAlign(block);
 	for(a=0; aactuators.first) uiSetCurFont(block, UI_HELVB);
-		uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2,(short)(xco-10), yco,(short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators");
+		uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2,(short)(xco-10), yco,(short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators");
 //		if(ob->actuators.first) uiSetCurFont(block, UI_HELV);
-		uiDefButBitS(block, TOG, OB_ADDACT, B_ADD_ACT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Actuator");
+		uiDefButBitS(block, TOG, OB_ADDACT, B_ADD_ACT, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Actuator");
 		uiBlockEndAlign(block);
 		yco-=20;
 		
@@ -3301,15 +3301,15 @@ void logic_buttons(bContext *C, ARegion *ar)
 					pin = (slogic->scaflag & BUTS_ACT_STATE && (act->flag & SENS_SHOW || act->flag & SENS_PIN)) ? 1:0 ;
 					
 					act->flag |= ACT_VISIBLE;	/* mark the actuator as visible to help implementing the up/down action */
-					uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,	xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
+					uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,	xco, yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Delete Actuator");
 					if (pin)
-						uiDefIconButBitS(block, ICONTOG, ACT_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
-					uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Display the actuator");
+						uiDefIconButBitS(block, ICONTOG, ACT_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
+					uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Display the actuator");
 					
 					if(act->flag & ACT_SHOW) {
 						act->otype= act->type;
-						uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),	(short)(xco+22), yco, 90, 19, &act->type, 0, 0, 0, 0, "Actuator type");
-						but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), 19, act->name, 0, 31, 0, 0, "Actuator name");
+						uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),	(short)(xco+22), yco, 90, UI_UNIT_Y, &act->type, 0, 0, 0, 0, "Actuator type");
+						but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act->name, 0, 31, 0, 0, "Actuator name");
 						uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
 
 						ycoo= yco;
@@ -3319,14 +3319,14 @@ void logic_buttons(bContext *C, ARegion *ar)
 					else {
 						set_col_actuator(act->type, 1);
 						glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
-						but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, 19, act, 0, 0, 0, 0, "Actuator type");
+						but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator type");
 						uiButSetFunc(but, sca_move_actuator, act, NULL);
-						but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-(pin?156:134)), 19, act, 0, 0, 0, 0, "Actuator name");
+						but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator name");
 						uiButSetFunc(but, sca_move_actuator, act, NULL);
 						ycoo= yco;
 					}
 
-					uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
+					uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
 
 					yco-=20;
 				}
diff --git a/source/blender/editors/space_nla/Makefile b/source/blender/editors/space_nla/Makefile
index 43f010e6adc..d7c9477dc83 100644
--- a/source/blender/editors/space_nla/Makefile
+++ b/source/blender/editors/space_nla/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c
index 2366a888d3b..0f6b77da6f5 100644
--- a/source/blender/editors/space_nla/nla_header.c
+++ b/source/blender/editors/space_nla/nla_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: nla_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_node/Makefile b/source/blender/editors/space_node/Makefile
index 60f81255a74..5bd6e95e28c 100644
--- a/source/blender/editors/space_node/Makefile
+++ b/source/blender/editors/space_node/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 0670dd9e01f..f2e2486075b 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawnode.c 17439 2008-11-13 09:57:11Z kakbarnf $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index 1031ad213f4..8c48d4b54e1 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: node_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_outliner/Makefile b/source/blender/editors/space_outliner/Makefile
index 19d40a4a31e..8d7cd017e0b 100644
--- a/source/blender/editors/space_outliner/Makefile
+++ b/source/blender/editors/space_outliner/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 16748af39d5..8017b8437ff 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -1031,7 +1031,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
 	}
 	else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
 		PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv;
-		PropertyRNA *prop, *iterprop, *nameprop;
+		PropertyRNA *prop, *iterprop;
 		PropertyType proptype;
 		PropertySubType propsubtype;
 		int a, tot;
@@ -1043,12 +1043,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
 		}
 		else if(type == TSE_RNA_STRUCT) {
 			/* struct */
-			nameprop= RNA_struct_name_property(ptr->type);
+			te->name= RNA_struct_name_get_alloc(ptr, NULL, 0);
 
-			if(nameprop) {
-				te->name= RNA_property_string_get_alloc(ptr, nameprop, NULL, 0);
+			if(te->name)
 				te->flag |= TE_FREE_NAME;
-			}
 			else
 				te->name= (char*)RNA_struct_ui_name(ptr->type);
 
@@ -3075,7 +3073,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
 	TreeElement *tem, *temnext, *temsub;
 	TreeStoreElem *tse, *tsenext;
 	PointerRNA *ptr, *nextptr;
-	PropertyRNA *prop, *nameprop;
+	PropertyRNA *prop;
 	char *newpath=NULL;
 	
 	/* optimise tricks:
@@ -3119,17 +3117,16 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
 					newpath= RNA_path_append(*path, ptr, prop, 0, NULL);
 				}
 				else if(RNA_property_type(prop) == PROP_COLLECTION) {
+					char buf[128], *name;
+
 					temnext= (TreeElement*)(ld->next->data);
 					tsenext= TREESTORE(temnext);
 					
 					nextptr= &temnext->rnaptr;
-					nameprop= RNA_struct_name_property(nextptr->type);
+					name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf));
 					
-					if(nameprop) {
+					if(name) {
 						/* if possible, use name as a key in the path */
-						char buf[128], *name;
-						name= RNA_property_string_get_alloc(nextptr, nameprop, buf, sizeof(buf));
-						
 						newpath= RNA_path_append(*path, NULL, prop, 0, name);
 						
 						if(name != buf)
diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c
index b630eb2acf3..fe2f054899c 100644
--- a/source/blender/editors/space_outliner/outliner_header.c
+++ b/source/blender/editors/space_outliner/outliner_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: outliner_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index cc7880fcae7..4ddb586beb4 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -1,5 +1,5 @@
 /**
- * $Id: space_outliner.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_script/Makefile b/source/blender/editors/space_script/Makefile
index 48e1cd8e861..3322cb61a7f 100644
--- a/source/blender/editors/space_script/Makefile
+++ b/source/blender/editors/space_script/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_script/script_header.c b/source/blender/editors/space_script/script_header.c
index 548ed8d2331..d9851df4185 100644
--- a/source/blender/editors/space_script/script_header.c
+++ b/source/blender/editors/space_script/script_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: script_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_sequencer/Makefile b/source/blender/editors/space_sequencer/Makefile
index 80699db4baa..7be0bc9cfef 100644
--- a/source/blender/editors/space_sequencer/Makefile
+++ b/source/blender/editors/space_sequencer/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index f127ab4b0cf..cc4f5cf5ce3 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -1,5 +1,5 @@
 /**
- * $Id: sequencer_buttons.c 20279 2009-05-19 17:13:33Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_sound/Makefile b/source/blender/editors/space_sound/Makefile
index 4d375282223..a072684d543 100644
--- a/source/blender/editors/space_sound/Makefile
+++ b/source/blender/editors/space_sound/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_sound/sound_header.c b/source/blender/editors/space_sound/sound_header.c
index b674438210d..ae3410663c2 100644
--- a/source/blender/editors/space_sound/sound_header.c
+++ b/source/blender/editors/space_sound/sound_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: sound_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_text/Makefile b/source/blender/editors/space_text/Makefile
index 33e12dc1abb..50871017085 100644
--- a/source/blender/editors/space_text/Makefile
+++ b/source/blender/editors/space_text/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index 1a3f998bb8a..c761587198f 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: text_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -88,6 +88,7 @@
 /* ************************ header area region *********************** */
 
 #ifndef DISABLE_PYTHON
+#if 0
 static void do_text_template_scriptsmenu(bContext *C, void *arg, int event)
 {
 	// XXX BPY_menu_do_python(PYMENU_SCRIPTTEMPLATE, event);
@@ -154,6 +155,7 @@ static uiBlock *text_plugin_scriptsmenu(bContext *C, void *args_unused)
 	return block;
 }
 #endif
+#endif
 
 /************************** properties ******************************/
 
diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c
index e4c697dc2b5..4fa54cdf27b 100644
--- a/source/blender/editors/space_text/text_python.c
+++ b/source/blender/editors/space_text/text_python.c
@@ -1,5 +1,5 @@
 /**
- * $Id: text_python.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_time/Makefile b/source/blender/editors/space_time/Makefile
index 20877b48559..e0bf3943dd8 100644
--- a/source/blender/editors/space_time/Makefile
+++ b/source/blender/editors/space_time/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 67759bb1b46..c4ca4d8522f 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -1,5 +1,5 @@
 /**
- * $Id: space_time.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_time/time_header.c b/source/blender/editors/space_time/time_header.c
index 2b00459fc17..29f31671670 100644
--- a/source/blender/editors/space_time/time_header.c
+++ b/source/blender/editors/space_time/time_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: time_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -567,12 +567,12 @@ void time_header_buttons(const bContext *C, ARegion *ar)
 	
 	uiBlockBeginAlign(block);
 		uiDefIconButBitS(block, TOG, AUTOKEY_ON, B_REDRAWALL, ICON_REC,
-						 xco, yco, XIC, YIC, &(scene->autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
+						 xco, yco, XIC, YIC, &(scene->toolsettings->autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
 		xco+= XIC;
 		if (IS_AUTOKEY_ON(scene)) {
 			uiDefButS(block, MENU, B_REDRAWALL, 
 					  "Auto-Keying Mode %t|Add/Replace Keys%x3|Replace Keys %x5", 
-					  xco, yco, (int)5.5*XIC, YIC, &(scene->autokey_mode), 0, 1, 0, 0, 
+					  xco, yco, (int)5.5*XIC, YIC, &(scene->toolsettings->autokey_mode), 0, 1, 0, 0, 
 					  "Mode of automatic keyframe insertion for Objects and Bones");
 			xco+= (6*XIC);
 		}
diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile
index dd4eab89411..5e6f8a6c426 100644
--- a/source/blender/editors/space_view3d/Makefile
+++ b/source/blender/editors/space_view3d/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index a67e8c8a1c3..05490e2fce1 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -117,7 +117,7 @@
 	(vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
 #define CHECK_OB_DRAWFACEDOT(sce, vd, dt) \
-(	(sce->selectmode & SCE_SELECT_FACE) && \
+(	(sce->toolsettings->selectmode & SCE_SELECT_FACE) && \
 	(vd->drawtype<=OB_SOLID) && \
 	(((vd->drawtype==OB_SOLID) && (dt>=OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX) && (vd->flag & V3D_ZBUF_SELECT)) == 0) \
 	)
@@ -1493,14 +1493,14 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
 
 static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
 {
-	Scene *scene= (Scene *)userData;
+	ToolSettings *ts= ((Scene *)userData)->toolsettings;
 	EditFace *efa = EM_get_face_for_index(index);
 
 	if (efa->h==0 && efa->fgonf!=EM_FGON) {
 		glVertex3fv(cent);
-		glVertex3f(	cent[0] + no[0]*scene->editbutsize,
-					cent[1] + no[1]*scene->editbutsize,
-					cent[2] + no[2]*scene->editbutsize);
+		glVertex3f(	cent[0] + no[0]*ts->normalsize,
+					cent[1] + no[1]*ts->normalsize,
+					cent[2] + no[2]*ts->normalsize);
 	}
 }
 static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
@@ -1529,19 +1529,20 @@ static void draw_dm_face_centers(DerivedMesh *dm, int sel)
 static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
 	Scene *scene= (Scene *)userData;
+	ToolSettings *ts= scene->toolsettings;
 	EditVert *eve = EM_get_vert_for_index(index);
 
 	if (eve->h==0) {
 		glVertex3fv(co);
 
 		if (no_f) {
-			glVertex3f(	co[0] + no_f[0]*scene->editbutsize,
-						co[1] + no_f[1]*scene->editbutsize,
-						co[2] + no_f[2]*scene->editbutsize);
+			glVertex3f(	co[0] + no_f[0]*ts->normalsize,
+						co[1] + no_f[1]*ts->normalsize,
+						co[2] + no_f[2]*ts->normalsize);
 		} else {
-			glVertex3f(	co[0] + no_s[0]*scene->editbutsize/32767.0f,
-						co[1] + no_s[1]*scene->editbutsize/32767.0f,
-						co[2] + no_s[2]*scene->editbutsize/32767.0f);
+			glVertex3f(	co[0] + no_s[0]*ts->normalsize/32767.0f,
+						co[1] + no_s[1]*ts->normalsize/32767.0f,
+						co[2] + no_s[2]*ts->normalsize/32767.0f);
 		}
 	}
 }
@@ -1762,7 +1763,9 @@ static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, floa
 }
 static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 {
-	if (scene->selectmode & SCE_SELECT_VERTEX) {
+	ToolSettings *ts= scene->toolsettings;
+
+	if (ts->selectmode & SCE_SELECT_VERTEX) {
 		glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
 		bglBegin(GL_POINTS);
 		dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
@@ -1786,6 +1789,7 @@ static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 
 static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em, DerivedMesh *cageDM, EditVert *eve_act)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int sel;
 
 	if(v3d->zbuf) glDepthMask(0);		// disable write in zbuffer, zbuf select
@@ -1817,7 +1821,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
 				col[3] = fcol[3] = 255;
 			}
 				
-			if(scene->selectmode & SCE_SELECT_VERTEX) {
+			if(ts->selectmode & SCE_SELECT_VERTEX) {
 				glPointSize(size);
 				glColor4ubv((GLubyte *)col);
 				draw_dm_verts(cageDM, sel, eve_act);
@@ -1842,6 +1846,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
 
 static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int pass;
 	unsigned char wireCol[4], selCol[4], actCol[4];
 
@@ -1871,11 +1876,11 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh
 			if (!sel_only) wireCol[3] = 255;
 		}
 
-		if(scene->selectmode == SCE_SELECT_FACE) {
+		if(ts->selectmode == SCE_SELECT_FACE) {
 			draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
 		}	
-		else if( (me->drawflag & ME_DRAWEDGES) || (scene->selectmode & SCE_SELECT_EDGE) ) {	
-			if(cageDM->drawMappedEdgesInterp && (scene->selectmode & SCE_SELECT_VERTEX)) {
+		else if( (me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE) ) {	
+			if(cageDM->drawMappedEdgesInterp && (ts->selectmode & SCE_SELECT_VERTEX)) {
 				glShadeModel(GL_SMOOTH);
 				draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
 				glShadeModel(GL_FLAT);
@@ -3239,6 +3244,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 			if(draw_as!=PART_DRAW_PATH){
 				state.time=cfra;
 				if(psys_get_particle_state(scene,ob,psys,a,&state,0)){
+					if(psys->parent)
+						Mat4MulVecfl(psys->parent->obmat, state.co);
+
 					/* create actiual particle data */
 					switch(draw_as){
 						case PART_DRAW_DOT:
@@ -3661,13 +3669,13 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob
 	}
 
 	/* draw edit vertices */
-	if(scene->selectmode!=SCE_SELECT_PATH){
+	if(pset->selectmode!=SCE_SELECT_PATH){
 		glDisableClientState(GL_NORMAL_ARRAY);
 		glEnableClientState(GL_COLOR_ARRAY);
 		glDisable(GL_LIGHTING);
 		glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
 
-		if(scene->selectmode==SCE_SELECT_POINT){
+		if(pset->selectmode==SCE_SELECT_POINT){
 			float *cd=0,*cdata=0;
 			cd=cdata=MEM_callocN(edit->totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
 
@@ -3706,7 +3714,7 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob
 				MEM_freeN(cdata);
 			cd=cdata=0;
 		}
-		else if(scene->selectmode == SCE_SELECT_END){
+		else if(pset->selectmode == SCE_SELECT_END){
 			for(i=0, pa=psys->particles; iflag & PARS_HIDE)==0){
 					key = edit->keys[i] + pa->totkey - 1;
@@ -3944,6 +3952,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
 
 static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, int dt)
 {
+	ToolSettings *ts= scene->toolsettings;
 	Object *ob= base->object;
 	Curve *cu = ob->data;
 	Nurb *nu;
@@ -3975,7 +3984,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 
 	/*	direction vectors for 3d curve paths
 		when at its lowest, dont render normals */
-	if(cu->flag & CU_3D && scene->editbutsize > 0.0015) {
+	if(cu->flag & CU_3D && ts->normalsize > 0.0015) {
 		UI_ThemeColor(TH_WIRE);
 		for (bl=cu->bev.first,nu=nurb; nu && bl; bl=bl->next,nu=nu->next) {
 			BevPoint *bevp= (BevPoint *)(bl+1);		
@@ -3983,7 +3992,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 			int skip= nu->resolu/16;
 			
 			while (nr-->0) { /* accounts for empty bevel lists */
-				float fac= bevp->radius * scene->editbutsize;
+				float fac= bevp->radius * ts->normalsize;
 				float ox,oy,oz; // Offset perpendicular to the curve
 				float dx,dy,dz; // Delta along the curve
 				
@@ -5405,6 +5414,7 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
 
 void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
 {
+	ToolSettings *ts= scene->toolsettings;
 
 	wmMultMatrix(ob->obmat);
 
@@ -5422,8 +5432,8 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
 
 			EM_init_index_arrays(em, 1, 1, 1);
 
-			bbs_mesh_solid_EM(scene, v3d, ob, dm, scene->selectmode & SCE_SELECT_FACE);
-			if(scene->selectmode & SCE_SELECT_FACE)
+			bbs_mesh_solid_EM(scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
+			if(ts->selectmode & SCE_SELECT_FACE)
 				em_solidoffs = 1+em->totface;
 			else
 				em_solidoffs= 1;
@@ -5435,7 +5445,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
 			em_wireoffs= em_solidoffs + em->totedge;
 			
 			// we draw verts if vert select mode or if in transform (for snap).
-			if(scene->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
+			if(ts->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
 				bbs_mesh_verts(dm, em_wireoffs);
 				em_vertoffs= em_wireoffs + em->totvert;
 			}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2d6a57d5a34..625b1838951 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -122,6 +122,24 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
 	return arnew;
 }
 
+/* ****************************************************** */
+
+/* function to always find a regionview3d context inside 3D window */
+RegionView3D *ED_view3d_context_rv3d(bContext *C)
+{
+	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	
+	if(rv3d==NULL) {
+		ScrArea *sa =CTX_wm_area(C);
+		if(sa->spacetype==SPACE_VIEW3D) {
+			ARegion *ar;
+			for(ar= sa->regionbase.first; ar; ar= ar->next)
+				if(ar->regiontype==RGN_TYPE_WINDOW)
+					return ar->regiondata;
+		}
+	}
+	return rv3d;
+}
 
 
 /* ******************** default callbacks for view3d space ***************** */
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index b6e9e05b120..91565235591 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -1663,7 +1663,7 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
 
 	uiBlockEndAlign(block);
 	
-	uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
+	uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
 }
 
 
@@ -1710,7 +1710,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 	}
 	
 	RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-	uiDefAutoButsRNA(C, pa->layout, &ptr);
+	uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
 }
 
 void view3d_buttons_register(ARegionType *art)
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 1c528aac6a3..5edcd203e16 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: view3d_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -1812,6 +1812,7 @@ static void do_view3d_transformmenu(bContext *C, void *arg, int event)
 {
 #if 0
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	
 	switch(event) {
 	case 1:
@@ -1870,22 +1871,22 @@ static void do_view3d_transformmenu(bContext *C, void *arg, int event)
 		Transform();
 		break;
 	case 15:
-		scene->snap_flag &= ~SCE_SNAP;
+		ts->snap_flag &= ~SCE_SNAP;
 		break;
 	case 16:
-		scene->snap_flag |= SCE_SNAP;
+		ts->snap_flag |= SCE_SNAP;
 		break;
 	case 17:
-		scene->snap_target = SCE_SNAP_TARGET_CLOSEST;
+		ts->snap_target = SCE_SNAP_TARGET_CLOSEST;
 		break;
 	case 18:
-		scene->snap_target = SCE_SNAP_TARGET_CENTER;
+		ts->snap_target = SCE_SNAP_TARGET_CENTER;
 		break;
 	case 19:
-		scene->snap_target = SCE_SNAP_TARGET_MEDIAN;
+		ts->snap_target = SCE_SNAP_TARGET_MEDIAN;
 		break;
 	case 20:
-		scene->snap_target = SCE_SNAP_TARGET_ACTIVE;
+		ts->snap_target = SCE_SNAP_TARGET_ACTIVE;
 		break;
 	case 21:
 		alignmenu();
@@ -1896,7 +1897,7 @@ static void do_view3d_transformmenu(bContext *C, void *arg, int event)
 
 static uiBlock *view3d_transformmenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit = CTX_data_edit_object(C);
 	uiBlock *block;
 	short yco = 20, menuwidth = 120;
@@ -1948,7 +1949,7 @@ static uiBlock *view3d_transformmenu(bContext *C, ARegion *ar, void *arg_unused)
 	{
 		uiDefBut(block, SEPR, 0, "",                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 	
-		if (scene->snap_flag & SCE_SNAP)
+		if (ts->snap_flag & SCE_SNAP)
 		{
 			uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Grid",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
 			uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
@@ -1961,7 +1962,7 @@ static uiBlock *view3d_transformmenu(bContext *C, ARegion *ar, void *arg_unused)
 			
 		uiDefBut(block, SEPR, 0, "",                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
-		switch(scene->snap_target)
+		switch(ts->snap_target)
 		{
 			case SCE_SNAP_TARGET_CLOSEST:
 				uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Closest",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
@@ -2650,34 +2651,34 @@ static uiBlock *view3d_edit_objectmenu(bContext *C, ARegion *ar, void *arg_unuse
 
 static void do_view3d_edit_propfalloffmenu(bContext *C, void *arg, int event)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	
-	scene->prop_mode= event;
+	ts->prop_mode= event;
 	
 }
 
 static uiBlock *view3d_edit_propfalloffmenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	uiBlock *block;
 	short yco = 20, menuwidth = 120;
 
 	block= uiBeginBlock(C, ar, "view3d_edit_propfalloffmenu", UI_EMBOSSP);
 	uiBlockSetButmFunc(block, do_view3d_edit_propfalloffmenu, NULL);
 	
-	if (scene->prop_mode==PROP_SMOOTH) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Smooth|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
+	if (ts->prop_mode==PROP_SMOOTH) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Smooth|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Smooth|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
-	if (scene->prop_mode==PROP_SPHERE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sphere|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
+	if (ts->prop_mode==PROP_SPHERE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sphere|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sphere|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
-	if (scene->prop_mode==PROP_ROOT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Root|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
+	if (ts->prop_mode==PROP_ROOT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Root|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Root|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
-	if (scene->prop_mode==PROP_SHARP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sharp|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
+	if (ts->prop_mode==PROP_SHARP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sharp|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sharp|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
-	if (scene->prop_mode==PROP_LIN) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Linear|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
+	if (ts->prop_mode==PROP_LIN) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Linear|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Linear|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
-	if (scene->prop_mode==PROP_RANDOM) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Random|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_RANDOM, "");
+	if (ts->prop_mode==PROP_RANDOM) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Random|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_RANDOM, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Random|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_RANDOM, "");
-	if (scene->prop_mode==PROP_CONST) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Constant|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
+	if (ts->prop_mode==PROP_CONST) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Constant|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Constant|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
 		
 	uiBlockSetDirection(block, UI_RIGHT);
@@ -2698,7 +2699,7 @@ void do_view3d_edit_mesh_verticesmenu(bContext *C, void *arg, int event)
 		make_parent();
 		break;
 	case 1: /* remove doubles */
-		count= removedoublesflag(1, 0, scene->toolsettings->doublimit);
+		count= removedoublesflag(1, 0, ts->doublimit);
 		notice("Removed: %d", count);
 		if (count) { /* only undo and redraw if an action is taken */
 			DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
@@ -2768,18 +2769,18 @@ void do_view3d_edit_mesh_edgesmenu(bContext *C, void *arg, int event)
 	switch(event) {
 		 
 	case 0: /* subdivide smooth */
-		esubdivideflag(1, 0.0, scene->toolsettings->editbutflag | B_SMOOTH,1,0);
+		esubdivideflag(1, 0.0, ts->editbutflag | B_SMOOTH,1,0);
 		ED_undo_push(C, "Subdivide Smooth");
 		break;
 	case 1: /*subdivide fractal */
 		randfac= 10;
 		if(button(&randfac, 1, 100, "Rand fac:")==0) return;
 		fac= -( (float)randfac )/100;
-		esubdivideflag(1, fac, scene->toolsettings->editbutflag,1,0);
+		esubdivideflag(1, fac, ts->editbutflag,1,0);
 		ED_undo_push(C, "Subdivide Fractal");
 		break;
 	case 2: /* subdivide */
-		esubdivideflag(1, 0.0, scene->toolsettings->editbutflag,1,0);
+		esubdivideflag(1, 0.0, ts->editbutflag,1,0);
 		ED_undo_push(C, "Subdivide");
 		break;
 	case 3: /* knife subdivide */
@@ -3142,6 +3143,7 @@ static uiBlock *view3d_edit_mesh_scriptsmenu(bContext *C, ARegion *ar, void *arg
 static void do_view3d_edit_meshmenu(bContext *C, void *arg, int event)
 {
 #if 0
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Scene *scene= CTX_data_scene(C);
 	ScrArea *sa= CTX_wm_area(C);
 	View3D *v3d= sa->spacedata.first;
@@ -3185,12 +3187,12 @@ static void do_view3d_edit_meshmenu(bContext *C, void *arg, int event)
 		Transform();
 		break;
 	case 12: /* proportional edit (toggle) */
-		if(scene->proportional) scene->proportional= 0;
-		else scene->proportional= 1;
+		if(ts->proportional) ts->proportional= 0;
+		else ts->proportional= 1;
 		break;
 	case 13: /* automerge edit (toggle) */
-		if(scene->automerge) scene->automerge= 0;
-		else scene->automerge= 1;
+		if(ts->automerge) ts->automerge= 0;
+		else ts->automerge= 1;
 		break;
 	case 15:
 		uv_autocalc_tface();
@@ -3204,7 +3206,7 @@ static void do_view3d_edit_meshmenu(bContext *C, void *arg, int event)
 
 static uiBlock *view3d_edit_meshmenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit = CTX_data_edit_object(C);
 	uiBlock *block;
 	short yco= 0, menuwidth=120;
@@ -3250,7 +3252,7 @@ static uiBlock *view3d_edit_meshmenu(bContext *C, ARegion *ar, void *arg_unused)
 		
 	
 	
-	if(scene->proportional) {
+	if(ts->proportional) {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
 	} else {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
@@ -3261,7 +3263,7 @@ static uiBlock *view3d_edit_meshmenu(bContext *C, ARegion *ar, void *arg_unused)
 	
 	/* PITA but we should let users know that automerge cant work with multires :/ */
 	uiDefIconTextBut(block, BUTM, 1,
-			scene->automerge ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT,
+			ts->automerge ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT,
 			((Mesh*)obedit->data)->mr ? "AutoMerge Editing (disabled by multires)" : "AutoMerge Editing",
 			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
 	
@@ -3536,8 +3538,8 @@ static void do_view3d_edit_latticemenu(bContext *C, void *arg, int event)
 		Transform();
 		break;
 	case 5: /* proportional edit (toggle) */
-		if(scene->proportional) scene->proportional= 0;
-		else scene->proportional= 1;
+		if(ts->proportional) ts->proportional= 0;
+		else ts->proportional= 1;
 		break;
 	case 7: /* delete keyframe */
 		common_deletekey();
@@ -3548,7 +3550,7 @@ static void do_view3d_edit_latticemenu(bContext *C, void *arg, int event)
 
 static uiBlock *view3d_edit_latticemenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	uiBlock *block;
 	short yco= 0, menuwidth=120;
 		
@@ -3574,7 +3576,7 @@ static uiBlock *view3d_edit_latticemenu(bContext *C, ARegion *ar, void *arg_unus
 	
 	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 	
-	if(scene->proportional) {
+	if(ts->proportional) {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
 	} else {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
@@ -4555,6 +4557,7 @@ static void view3d_sculpt_menu(bContext *C, uiLayout *layout, void *arg_unused)
 	uiItemR(layout, NULL, 0, &rna, "rake", 0, 0, 0);
 	uiItemR(layout, NULL, 0, &rna, "anchored", 0, 0, 0);
 	uiItemR(layout, NULL, 0, &rna, "space", 0, 0, 0);
+	uiItemR(layout, NULL, 0, &rna, "smooth_stroke", 0, 0, 0);
 
 	uiItemR(layout, NULL, 0, &rna, "flip_direction", 0, 0, 0);
 }
@@ -4695,7 +4698,7 @@ static uiBlock *view3d_faceselmenu(bContext *C, ARegion *ar, void *arg_unused)
 
 static void view3d_select_particlemenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 
 	uiItemO(layout, NULL, 0, "VIEW3D_OT_select_border");
 
@@ -4704,7 +4707,7 @@ static void view3d_select_particlemenu(bContext *C, uiLayout *layout, void *arg_
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_select_all_toggle");
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_select_linked");
 
-	if(scene->selectmode & SCE_SELECT_POINT) {
+	if(ts->particle.selectmode & SCE_SELECT_POINT) {
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last"); // |W, 4
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first"); // |W, 3
 	}
@@ -4724,7 +4727,7 @@ static void view3d_particle_showhidemenu(bContext *C, uiLayout *layout, void *ar
 
 static void view3d_particlemenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 
 	// XXX uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Particle Edit Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
 	// add_blockhandler(sa, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
@@ -4739,7 +4742,7 @@ static void view3d_particlemenu(bContext *C, uiLayout *layout, void *arg_unused)
 
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_remove_doubles"); // |W, 5
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_delete");
-	if(scene->selectmode & SCE_SELECT_POINT)
+	if(ts->particle.selectmode & SCE_SELECT_POINT)
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide"); // |W, 2
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); // |W, 1
 
@@ -4873,6 +4876,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 {
 	wmWindow *win= CTX_wm_window(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	ScrArea *sa= CTX_wm_area(C);
 	View3D *v3d= sa->spacedata.first;
 	Base *basact= CTX_data_active_base(C);
@@ -5007,7 +5011,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 		if(em) {
 			if(shift==0 || em->selectmode==0)
 				em->selectmode= SCE_SELECT_VERTEX;
-			scene->selectmode= em->selectmode;
+			ts->selectmode= em->selectmode;
 			EM_selectmode_set(em);
 			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 			ED_undo_push(C, "Selectmode Set: Vertex");
@@ -5021,7 +5025,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 				}
 				em->selectmode = SCE_SELECT_EDGE;
 			}
-			scene->selectmode= em->selectmode;
+			ts->selectmode= em->selectmode;
 			EM_selectmode_set(em);
 			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 			ED_undo_push(C, "Selectmode Set: Edge");
@@ -5030,12 +5034,12 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 	case B_SEL_FACE:
 		if(em) {
 			if( shift==0 || em->selectmode==0){
-				if( ((scene->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((scene->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){
-					if(ctrl) EM_convertsel(em, (scene->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE);
+				if( ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){
+					if(ctrl) EM_convertsel(em, (ts->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE);
 				}
 				em->selectmode = SCE_SELECT_FACE;
 			}
-			scene->selectmode= em->selectmode;
+			ts->selectmode= em->selectmode;
 			EM_selectmode_set(em);
 			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 			ED_undo_push(C, "Selectmode Set: Face");
@@ -5043,15 +5047,15 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 		break;	
 
 	case B_SEL_PATH:
-		scene->selectmode= SCE_SELECT_PATH;
+		ts->particle.selectmode= SCE_SELECT_PATH;
 		ED_undo_push(C, "Selectmode Set: Path");
 		break;
 	case B_SEL_POINT:
-		scene->selectmode = SCE_SELECT_POINT;
+		ts->particle.selectmode = SCE_SELECT_POINT;
 		ED_undo_push(C, "Selectmode Set: Point");
 		break;
 	case B_SEL_END:
-		scene->selectmode = SCE_SELECT_END;
+		ts->particle.selectmode = SCE_SELECT_END;
 		ED_undo_push(C, "Selectmode Set: End point");
 		break;	
 	
@@ -5280,6 +5284,7 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 	ScrArea *sa= CTX_wm_area(C);
 	View3D *v3d= sa->spacedata.first;
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *ob= OBACT;
 	Object *obedit = CTX_data_edit_object(C);
 	uiBlock *block;
@@ -5449,11 +5454,11 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 		if((obedit && (obedit->type == OB_MESH || obedit->type == OB_CURVE || obedit->type == OB_SURF || obedit->type == OB_LATTICE)) || G.f & G_PARTICLEEDIT) {
 		
 			uiBlockBeginAlign(block);
-			uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,yco,XIC+10,YIC, &(scene->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
+			uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,yco,XIC+10,YIC, &(ts->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
 			xco+= XIC+10;
 		
-			if(scene->proportional) {
-				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SMOOTHCURVE, propfalloff_pup(), xco,yco,XIC+10,YIC, &(scene->prop_mode), 0.0, 0.0, 0, 0, "Proportional Edit Falloff (Hotkey: Shift O) ");
+			if(ts->proportional) {
+				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SMOOTHCURVE, propfalloff_pup(), xco,yco,XIC+10,YIC, &(ts->prop_mode), 0.0, 0.0, 0, 0, "Proportional Edit Falloff (Hotkey: Shift O) ");
 				xco+= XIC+10;
 			}
 			uiBlockEndAlign(block);
@@ -5464,21 +5469,21 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 		if (BIF_snappingSupported(obedit)) {
 			uiBlockBeginAlign(block);
 
-			if (scene->snap_flag & SCE_SNAP) {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
+			if (ts->snap_flag & SCE_SNAP) {
+				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
 				xco+= XIC;
-				uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target");	
+				uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target");	
 				xco+= XIC;
-				if (scene->snap_mode == SCE_SNAP_MODE_VOLUME) {
-					uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center");	
+				if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) {
+					uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center");	
 					xco+= XIC;
 				}
-				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(scene->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
+				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
 				xco+= XIC;
-				uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
+				uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode");
 				xco+= XIC+70;
 			} else {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");	
+				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");	
 				xco+= XIC;
 			}
 
@@ -5509,11 +5514,11 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 		}
 		else if(G.f & G_PARTICLEEDIT) {
 			uiBlockBeginAlign(block);
-			uiDefIconButBitS(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Path edit mode");
+			uiDefIconButBitI(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Path edit mode");
 			xco+= XIC;
-			uiDefIconButBitS(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Point select mode");
+			uiDefIconButBitI(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Point select mode");
 			xco+= XIC;
-			uiDefIconButBitS(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Tip select mode");
+			uiDefIconButBitI(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Tip select mode");
 			xco+= XIC;
 			uiBlockEndAlign(block);
 			
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e0e8ac7c7a7..a153f795292 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -438,6 +438,7 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, EditFace *efa, in
 static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves, short select)
 {
 	struct { ViewContext vc; rcti *rect; short (*mcords)[2], moves, select, pass, done; } data;
+	ToolSettings *ts= vc->scene->toolsettings;
 	rcti rect;
 	int bbsel;
 	
@@ -456,14 +457,14 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves
 
 	bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 	
-	if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
+	if(ts->selectmode & SCE_SELECT_VERTEX) {
 		if (bbsel) {
 			EM_backbuf_checkAndSelectVerts(vc->em, select);
 		} else {
 			mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, 1);
 		}
 	}
-	if(vc->scene->selectmode & SCE_SELECT_EDGE) {
+	if(ts->selectmode & SCE_SELECT_EDGE) {
 			/* Does both bbsel and non-bbsel versions (need screen cos for both) */
 
 		data.pass = 0;
@@ -475,7 +476,7 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves
 		}
 	}
 	
-	if(vc->scene->selectmode & SCE_SELECT_FACE) {
+	if(ts->selectmode & SCE_SELECT_FACE) {
 		if (bbsel) {
 			EM_backbuf_checkAndSelectFaces(vc->em, select);
 		} else {
@@ -1277,6 +1278,7 @@ static void do_mesh_box_select__doSelectFace(void *userData, EditFace *efa, int
 static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
 {
 	struct { ViewContext vc; rcti *rect; short select, pass, done; } data;
+	ToolSettings *ts= vc->scene->toolsettings;
 	int bbsel;
 	
 	data.vc= *vc;
@@ -1287,14 +1289,14 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
 
 	bbsel= EM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
 
-	if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
+	if(ts->selectmode & SCE_SELECT_VERTEX) {
 		if (bbsel) {
 			EM_backbuf_checkAndSelectVerts(vc->em, select);
 		} else {
 			mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, 1);
 		}
 	}
-	if(vc->scene->selectmode & SCE_SELECT_EDGE) {
+	if(ts->selectmode & SCE_SELECT_EDGE) {
 			/* Does both bbsel and non-bbsel versions (need screen cos for both) */
 
 		data.pass = 0;
@@ -1306,7 +1308,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
 		}
 	}
 	
-	if(vc->scene->selectmode & SCE_SELECT_FACE) {
+	if(ts->selectmode & SCE_SELECT_FACE) {
 		if(bbsel) {
 			EM_backbuf_checkAndSelectFaces(vc->em, select);
 		} else {
@@ -1639,6 +1641,7 @@ static void mesh_circle_doSelectFace(void *userData, EditFace *efa, int x, int y
 
 static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, float rad)
 {
+	ToolSettings *ts= vc->scene->toolsettings;
 	int bbsel;
 	
 	if(vc->obedit==NULL && (FACESEL_PAINT_TEST)) {
@@ -1666,7 +1669,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
 		data.mval[1] = mval[1];
 		data.radius = rad;
 
-		if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
+		if(ts->selectmode & SCE_SELECT_VERTEX) {
 			if(bbsel) {
 				EM_backbuf_checkAndSelectVerts(vc->em, selecting==LEFTMOUSE);
 			} else {
@@ -1674,7 +1677,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
 			}
 		}
 
-		if(vc->scene->selectmode & SCE_SELECT_EDGE) {
+		if(ts->selectmode & SCE_SELECT_EDGE) {
 			if (bbsel) {
 				EM_backbuf_checkAndSelectEdges(vc->em, selecting==LEFTMOUSE);
 			} else {
@@ -1682,7 +1685,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
 			}
 		}
 		
-		if(vc->scene->selectmode & SCE_SELECT_FACE) {
+		if(ts->selectmode & SCE_SELECT_FACE) {
 			if(bbsel) {
 				EM_backbuf_checkAndSelectFaces(vc->em, selecting==LEFTMOUSE);
 			} else {
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 1e55f2e4a9a..ea365d59ac7 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -120,8 +120,6 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2)
 
 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 {
-	/* XXX temp */
-	extern void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr);
 	wmWindowManager *wm= CTX_wm_manager(C);
 	wmOperator *op;
 	PointerRNA ptr;
@@ -136,7 +134,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 	
 	if(op==NULL)
 		return;
-	if(op->type->poll && op->type->poll(C)==0)
+	if(op->type->poll && op->type->poll((bContext *)C)==0)
 		return;
 	
 	uiBlockSetFunc(block, redo_cb, op, NULL);
@@ -147,13 +145,132 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 	}
 	
 	RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-	uiDefAutoButsRNA_single(C, pa->layout, &ptr);
+	uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
 }
 
+/* ******************* */
+
+typedef struct CustomTool {
+	struct CustomTool *next, *prev;
+	char opname[OP_MAX_TYPENAME];
+} CustomTool;
+
+static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
+{
+	wmOperatorType *ot= arg2;
+	
+	if(ot) {
+		CustomTool *ct= MEM_callocN(sizeof(CustomTool), "CustomTool");
+		
+		BLI_addtail(arg_listbase, ct);
+		BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
+	}
+		
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+	wmOperatorType *ot = WM_operatortype_first();
+	
+	for(; ot; ot= ot->next) {
+		
+		if(BLI_strcasestr(ot->name, str)) {
+			if(ot->poll==NULL || ot->poll((bContext *)C)) {
+				
+				if(0==uiSearchItemAdd(items, ot->name, ot, 0))
+					break;
+			}
+		}
+	}
+}
+
+
+/* ID Search browse menu, open */
+static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
+{
+	static char search[OP_MAX_TYPENAME];
+	wmEvent event;
+	wmWindow *win= CTX_wm_window(C);
+	uiBlock *block;
+	uiBut *but;
+	
+	/* clear initial search string, then all items show */
+	search[0]= 0;
+	
+	block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+	
+	/* fake button, it holds space for search items */
+	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+	
+	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, "");
+	uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
+	
+	uiBoundsBlock(block, 6);
+	uiBlockSetDirection(block, UI_DOWN);	
+	uiEndBlock(C, block);
+	
+	event= *(win->eventstate);	/* XXX huh huh? make api call */
+	event.type= EVT_BUT_OPEN;
+	event.val= KM_PRESS;
+	event.customdata= but;
+	event.customdatafree= FALSE;
+	wm_event_add(win, &event);
+	
+	return block;
+}
+
+
+static void view3d_panel_tools(const bContext *C, Panel *pa)
+{
+	static ListBase tools= {NULL, NULL};
+	Object *obedit= CTX_data_edit_object(C);
+//	Object *obact = CTX_data_active_object(C);
+	uiLayout *col;
+	
+	if(obedit) {
+		if(obedit->type==OB_MESH) {
+			
+			col= uiLayoutColumn(pa->layout, 1);
+			uiItemFullO(col, NULL, 0, "MESH_OT_spin", NULL, WM_OP_INVOKE_REGION_WIN);
+			uiItemFullO(col, NULL, 0, "MESH_OT_screw", NULL, WM_OP_INVOKE_REGION_WIN);
+			
+			if(tools.first) {
+				CustomTool *ct;
+				
+				for(ct= tools.first; ct; ct= ct->next) {
+					col= uiLayoutColumn(pa->layout, 1);
+					uiItemFullO(col, NULL, 0, ct->opname, NULL, WM_OP_INVOKE_REGION_WIN);
+				}
+			}
+			col= uiLayoutColumn(pa->layout, 1);
+			uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &tools, "Add Operator", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add tool");
+		}
+	}
+	else {
+		
+		col= uiLayoutColumn(pa->layout, 1);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_delete", NULL, WM_OP_INVOKE_REGION_WIN);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_primitive_add", NULL, WM_OP_INVOKE_REGION_WIN);
+		
+		col= uiLayoutColumn(pa->layout, 1);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_parent_set", NULL, WM_OP_INVOKE_REGION_WIN);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_parent_clear", NULL, WM_OP_INVOKE_REGION_WIN);
+		
+	}
+}
+
+
 void view3d_toolbar_register(ARegionType *art)
 {
 	PanelType *pt;
 
+	pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel tools");
+	strcpy(pt->idname, "VIEW3D_PT_tools");
+	strcpy(pt->label, "Tools");
+	pt->draw= view3d_panel_tools;
+	BLI_addtail(&art->paneltypes, pt);
+	
 	pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel last operator");
 	strcpy(pt->idname, "VIEW3D_PT_last_operator");
 	strcpy(pt->label, "Last Operator");
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 2db5f2c97fd..b57f4a91004 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -76,11 +76,12 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
+#include "GPU_draw.h"
+
 #include "PIL_time.h" /* smoothview */
 
 #include "view3d_intern.h"	// own include
 
-
 /* use this call when executing an operator,
    event system doesn't set for each event the
    opengl drawing context */
@@ -1430,6 +1431,9 @@ static int game_engine_exec(bContext *C, wmOperator *unused)
 	Scene *startscene = CTX_data_scene(C);
 	
 #if GAMEBLENDER == 1
+	
+	view3d_operator_needs_opengl(C);
+	
 	SaveState(C);
 	StartKetsjiShell(C, 1);
 	RestoreState(C);
diff --git a/source/blender/editors/transform/Makefile b/source/blender/editors/transform/Makefile
index bc3e08a2ae8..607038b413b 100644
--- a/source/blender/editors/transform/Makefile
+++ b/source/blender/editors/transform/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 674de81a9f5..3311fb7d0fe 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1134,7 +1134,7 @@ void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg)
 
 void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 {
-	Scene *sce = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	int constraint_axis[3] = {0, 0, 0};
 	int proportional = 0;
 
@@ -1195,8 +1195,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 	// XXX If modal, save settings back in scene
 	if (t->flag & T_MODAL)
 	{
-		sce->prop_mode = t->prop_mode;
-		sce->proportional = proportional;
+		ts->prop_mode = t->prop_mode;
+		ts->proportional = proportional;
 
 		if(t->spacetype == SPACE_VIEW3D)
 		{
@@ -2359,7 +2359,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
 		}
 		else if (t->flag & T_EDIT) {
 			
-			if(t->around==V3D_LOCAL && (t->scene->selectmode & SCE_SELECT_FACE)) {
+			if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
 				VECCOPY(center, td->center);
 			}
 			else {
@@ -2660,7 +2660,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
 		}
 		else {
 			/* !TODO! Make this if not rely on G */
-			if(around==V3D_LOCAL && (t->scene->selectmode & SCE_SELECT_FACE)) {
+			if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
 				center = td->center;
 			}
 		}
@@ -3126,7 +3126,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
 		sprintf(distvec, "%.4f", dist);
 		
 	if(t->flag & T_AUTOIK) {
-		short chainlen= t->scene->toolsettings->autoik_chainlen;
+		short chainlen= t->settings->autoik_chainlen;
 		
 		if(chainlen)
 			sprintf(autoik, "AutoIK-Len: %d", chainlen);
@@ -4251,7 +4251,7 @@ int Align(TransInfo *t, short mval[2])
 			VECCOPY(t->center, td->center);
 		}
 		else {
-			if(t->scene->selectmode & SCE_SELECT_FACE) {
+			if(t->settings->selectmode & SCE_SELECT_FACE) {
 				VECCOPY(t->center, td->center);
 			}
 		}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index ee767fada58..534f142734a 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -257,6 +257,7 @@ typedef struct TransInfo {
 	struct ScrArea	*sa;
 	struct ARegion	*ar;
 	struct Scene	*scene;
+	struct ToolSettings *settings;
 	struct wmTimer *animtimer;
     short       mval[2];        /* current mouse position               */
     struct Object   *obedit;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 6c7aa1ee49d..490ce820b30 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -777,7 +777,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->scene->toolsettings->autoik_chainlen;
+	short *chainlen= &t->settings->autoik_chainlen;
 	bPoseChannel *pchan;
 	
 	/* mode determines what change to apply to chainlen */
@@ -1631,7 +1631,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
 	int count = 0, hasselected = 0;
 	int propmode = t->flag & T_PROP_EDIT;
 
-	if(psys==NULL || t->scene->selectmode==SCE_SELECT_PATH) return;
+	if(psys==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return;
 
 	psmd = psys_get_modifier(ob,psys);
 
@@ -2101,7 +2101,7 @@ void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
 
 static void createTransEditVerts(bContext *C, TransInfo *t)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	TransData *tob = NULL;
 	EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 	EditVert *eve;
@@ -2119,7 +2119,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
 	}
 
 	// transform now requires awareness for select mode, so we tag the f1 flags in verts
-	if(scene->selectmode & SCE_SELECT_VERTEX) {
+	if(ts->selectmode & SCE_SELECT_VERTEX) {
 		for(eve= em->verts.first; eve; eve= eve->next) {
 			if(eve->h==0 && (eve->f & SELECT)) 
 				eve->f1= SELECT;
@@ -2127,7 +2127,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
 				eve->f1= 0;
 		}
 	}
-	else if(scene->selectmode & SCE_SELECT_EDGE) {
+	else if(ts->selectmode & SCE_SELECT_EDGE) {
 		EditEdge *eed;
 		for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 		for(eed= em->edges.first; eed; eed= eed->next) {
@@ -4672,8 +4672,14 @@ void special_aftertrans_update(TransInfo *t)
 			
 			if (base->flag & SELECT && (t->mode != TFM_DUMMY)) {
 				/* pointcache refresh */
-				if (BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+				if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
 					ob->recalc |= OB_RECALC_DATA;
+
+				/* Needed for proper updating of "quick cached" dynamics. */
+				/* Creates troubles for moving animated objects without */
+				/* autokey though, probably needed is an anim sys override? */
+				/* Please remove if some other solution is found. -jahka */
+				DAG_object_flush_update(scene, ob, OB_RECALC_OB);
 				
 				/* Set autokey if necessary */
 				if (!cancelled)
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 171665c9282..e157d7f68f9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -665,6 +665,7 @@ void resetTransRestrictions(TransInfo *t)
 int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 {
 	Scene *sce = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	ARegion *ar = CTX_wm_region(C);
 	ScrArea *sa = CTX_wm_area(C);
 	Object *obedit = CTX_data_edit_object(C);
@@ -679,6 +680,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	t->sa = sa;
 	t->ar = ar;
 	t->obedit = obedit;
+	t->settings = ts;
 
 	t->data = NULL;
 	t->ext = NULL;
@@ -752,9 +754,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else if(t->spacetype==SPACE_IMAGE || t->spacetype==SPACE_NODE)
 	{
+		SpaceImage *sima = sa->spacedata.first;
 		// XXX for now, get View2D  from the active region
 		t->view = &ar->v2d;
-		t->around = ar->v2d.around;
+		t->around = sima->around;
 	}
 	else
 	{
@@ -774,7 +777,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	// Need stuff to take it from edit mesh or whatnot here
 	else
 	{
-		if (t->obedit && t->obedit->type == OB_MESH && sce->toolsettings->editbutflag & B_MESH_X_MIRROR)
+		if (t->obedit && t->obedit->type == OB_MESH && ts->editbutflag & B_MESH_X_MIRROR)
 		{
 			t->flag |= T_MIRROR;
 		}
@@ -794,10 +797,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else
 	{
-		if ((t->options & CTX_NO_PET) == 0 && (sce->proportional)) {
+		if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) {
 			t->flag |= T_PROP_EDIT;
 			
-			if(sce->proportional == 2)
+			if(ts->proportional == 2)
 				t->flag |= T_PROP_CONNECTED;	// yes i know, has to become define
 		}
 	}
@@ -808,7 +811,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else
 	{
-		t->prop_size = sce->toolsettings->proportional_size;
+		t->prop_size = ts->proportional_size;
 	}
 	
 	if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
@@ -817,7 +820,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else
 	{
-		t->prop_mode = sce->prop_mode;
+		t->prop_mode = ts->prop_mode;
 	}
 
 	/* TRANSFORM_FIX_ME rna restrictions */
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 4d721a83c78..631eb1eb134 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -1,5 +1,5 @@
 /**
- * $Id: transform_input.c 18142 2008-12-29 07:19:16Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -26,6 +26,7 @@
 #include 
 
 #include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "BLI_arithb.h"
 
diff --git a/source/blender/editors/transform/transform_ndofinput.c b/source/blender/editors/transform/transform_ndofinput.c
index c52492ebd6b..9c2a1a7db6d 100644
--- a/source/blender/editors/transform/transform_ndofinput.c
+++ b/source/blender/editors/transform/transform_ndofinput.c
@@ -31,6 +31,7 @@
 #include "BKE_utildefines.h"	/* ABS */
 
 #include "DNA_view3d_types.h" /* for G.vd (view3d) */
+#include "DNA_windowmanager_types.h" /* for G.vd (view3d) */
 
 #include "WM_types.h"
 
diff --git a/source/blender/editors/transform/transform_numinput.c b/source/blender/editors/transform/transform_numinput.c
index 34976105db3..f5f1d5fac9e 100644
--- a/source/blender/editors/transform/transform_numinput.c
+++ b/source/blender/editors/transform/transform_numinput.c
@@ -34,6 +34,7 @@
 #include "BKE_utildefines.h"	/* ABS */
 
 #include "WM_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "transform.h"
 
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index e697b6dfa7d..9e4115f38f0 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -1,5 +1,5 @@
 /**
- * $Id: transform_ops.c 17542 2008-11-23 15:27:53Z theeth $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 72901110388..0b9a176dbdf 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -210,7 +210,7 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
 	if (BIF_snappingSupported(t->obedit) && event->type == TABKEY && event->shift)
 	{
 		/* toggle snap and reinit */
-		t->scene->snap_flag ^= SCE_SNAP;
+		t->settings->snap_flag ^= SCE_SNAP;
 		initSnapping(t, NULL);
 		status = 1;
 	}
@@ -282,10 +282,10 @@ int validSnappingNormal(TransInfo *t)
 
 void initSnapping(TransInfo *t, wmOperator *op)
 {
-	Scene *scene = t->scene;
+	ToolSettings *ts = t->settings;
 	Object *obedit = t->obedit;
 	int snapping = 0;
-	short snap_mode = t->scene->snap_target;
+	short snap_mode = t->settings->snap_target;
 	
 	resetSnapping(t);
 	
@@ -310,8 +310,8 @@ void initSnapping(TransInfo *t, wmOperator *op)
 	}
 	else
 	{
-		snapping = ((scene->snap_flag & SCE_SNAP) == SCE_SNAP);
-		t->tsnap.align = ((t->scene->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+		snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP);
+		t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
 	}
 	
 	if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
@@ -542,7 +542,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
 		int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
 		SnapMode mode;
 		
-		if (t->scene->snap_mode == SCE_SNAP_MODE_VOLUME)
+		if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME)
 		{
 			ListBase depth_peels;
 			DepthPeel *p1, *p2;
@@ -575,7 +575,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
 					p1->flag = 1;
 		
 					/* if peeling objects, take the first and last from each object */			
-					if (t->scene->snap_flag & SCE_SNAP_PEEL_OBJECT)
+					if (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT)
 					{
 						DepthPeel *peel;
 						for (peel = p1->next; peel; peel = peel->next)
@@ -1346,6 +1346,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
 
 int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int retval = 0;
 	
 	if (ob->type == OB_MESH) {
@@ -1363,13 +1364,13 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma
 			dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
 		}
 		
-		retval = snapDerivedMesh(scene->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+		retval = snapDerivedMesh(ts->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
 
 		dm->release(dm);
 	}
 	else if (ob->type == OB_ARMATURE)
 	{
-		retval = snapArmature(scene->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+		retval = snapArmature(ts->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
 	}
 	
 	return retval;
diff --git a/source/blender/editors/util/Makefile b/source/blender/editors/util/Makefile
index da701dc5d86..303079daeee 100644
--- a/source/blender/editors/util/Makefile
+++ b/source/blender/editors/util/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 62ce76a7614..1d79c542fa9 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -183,6 +183,8 @@ void ED_undo_redo(bContext *C)
 
 static int ed_undo_exec(bContext *C, wmOperator *op)
 {
+	/* "last operator" should disappear, later we can tie ths with undo stack nicer */
+	WM_operator_stack_clear(C);
 	return ed_undo_step(C, 1);
 }
 static int ed_redo_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/uvedit/Makefile b/source/blender/editors/uvedit/Makefile
index b8a8f0bc8af..d589bbec3bc 100644
--- a/source/blender/editors/uvedit/Makefile
+++ b/source/blender/editors/uvedit/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index aded5a4cff9..b811906f5e5 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -102,17 +102,19 @@ static void drawcursor_sima(SpaceImage *sima, ARegion *ar)
 
 static int draw_uvs_face_check(Scene *scene)
 {
+	ToolSettings *ts= scene->toolsettings;
+
 	/* checks if we are selecting only faces */
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			return 2;
-		else if(scene->selectmode & SCE_SELECT_FACE)
+		else if(ts->selectmode & SCE_SELECT_FACE)
 			return 1;
 		else
 			return 0;
 	}
 	else
-		return (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
+		return (ts->uv_selectmode == UV_SELECT_FACE);
 }
 
 static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
@@ -418,7 +420,7 @@ static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFac
 /* draws uv's in the image space */
 static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 {
-	ToolSettings *settings;
+	ToolSettings *ts;
 	Mesh *me= obedit->data;
 	EditMesh *em;
 	EditFace *efa, *efa_act;
@@ -432,13 +434,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 	em= BKE_mesh_get_editmesh(me);
 	activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */
 
-	settings= scene->toolsettings;
+	ts= scene->toolsettings;
 
 	drawfaces= draw_uvs_face_check(scene);
-	if(settings->uv_flag & UV_SYNC_SELECTION)
-		interpedges= (scene->selectmode & SCE_SELECT_VERTEX);
+	if(ts->uv_flag & UV_SYNC_SELECTION)
+		interpedges= (ts->selectmode & SCE_SELECT_VERTEX);
 	else
-		interpedges= (settings->uv_selectmode == UV_SELECT_VERTEX);
+		interpedges= (ts->uv_selectmode == UV_SELECT_VERTEX);
 	
 	/* draw other uvs */
 	if(sima->flag & SI_DRAW_OTHER)
@@ -454,7 +456,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 
 			/* when sync selection is enabled, all faces are drawn (except for hidden)
 			 * so if cage is the same as the final, theres no point in drawing this */
-			if(!((settings->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
+			if(!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
 				draw_uvs_dm_shadow(finaldm);
 			
 			/* release derivedmesh again */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 7dca4d34c48..7582145c63b 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -191,7 +191,9 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 
 int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		return (efa->h==0);
 	else
 		return (efa->h==0 && (efa->f & SELECT));
@@ -199,7 +201,9 @@ int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
 
 int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SHOW_SAME_IMAGE)
 		return (tf->tpage==ima)? uvedit_face_visible_nolocal(scene, efa): 0;
 	else
 		return uvedit_face_visible_nolocal(scene, efa);
@@ -207,7 +211,9 @@ int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
 
 int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		return (efa->f & SELECT);
 	else
 		return (!(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&(!efa->v4 || tf->flag & TF_SEL4));
@@ -215,7 +221,9 @@ int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
 
 void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		EM_select_face(efa, 1);
 	else
 		tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
@@ -223,7 +231,9 @@ void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
 
 void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		EM_select_face(efa, 0);
 	else
 		tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
@@ -231,12 +241,13 @@ void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
 
 int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int nvert= (efa->v4)? 4: 3;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			return (efa->f & SELECT);
-		else if(scene->selectmode == SCE_SELECT_EDGE)
+		else if(ts->selectmode == SCE_SELECT_EDGE)
 			return (*(&efa->e1 + i))->f & SELECT;
 		else
 			return (((efa->v1 + i)->f & SELECT) && ((efa->v1 + (i+1)%nvert)->f & SELECT));
@@ -247,12 +258,13 @@ int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int nvert= (efa->v4)? 4: 3;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 1);
-		else if(scene->selectmode == SCE_SELECT_EDGE)
+		else if(ts->selectmode == SCE_SELECT_EDGE)
 			EM_select_edge((*(&efa->e1 + i)), 1);
 		else {
 			(efa->v1 + i)->f |= SELECT;
@@ -265,12 +277,13 @@ void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int nvert= (efa->v4)? 4: 3;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 0);
-		else if(scene->selectmode == SCE_SELECT_EDGE)
+		else if(ts->selectmode == SCE_SELECT_EDGE)
 			EM_select_edge((*(&efa->e1 + i)), 0);
 		else {
 			(efa->v1 + i)->f &= ~SELECT;
@@ -283,8 +296,10 @@ void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			return (efa->f & SELECT);
 		else
 			return (*(&efa->v1 + i))->f & SELECT;
@@ -295,8 +310,10 @@ int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 1);
 		else
 			(*(&efa->v1 + i))->f |= SELECT;
@@ -307,8 +324,10 @@ void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_uv_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 0);
 		else
 			(*(&efa->v1 + i))->f &= ~SELECT;
@@ -1289,6 +1308,7 @@ void UV_OT_stitch(wmOperatorType *ot)
 static int select_inverse_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene;
+	ToolSettings *ts;
 	Object *obedit;
 	EditMesh *em;
 	EditFace *efa;
@@ -1296,11 +1316,12 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
 	MTFace *tf;
 	
 	scene= CTX_data_scene(C);
+	ts= CTX_data_tool_settings(C);
 	obedit= CTX_data_edit_object(C);
 	em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	ima= CTX_data_edit_image(C);
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_select_swap(em);
 	}
 	else {
@@ -1339,6 +1360,7 @@ void UV_OT_select_invert(wmOperatorType *ot)
 static int de_select_all_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene;
+	ToolSettings *ts;
 	Object *obedit;
 	EditMesh *em;
 	EditFace *efa;
@@ -1347,11 +1369,12 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
 	int sel;
 	
 	scene= CTX_data_scene(C);
+	ts= CTX_data_tool_settings(C);
 	obedit= CTX_data_edit_object(C);
 	em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	ima= CTX_data_edit_image(C);
 	
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_toggle_select_all(em);
 	}
 	else {
@@ -1431,6 +1454,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
@@ -1445,12 +1469,12 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 	uvedit_pixel_to_float(sima, penalty, 5.0f);
 
 	/* retrieve operation mode */
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		sync= 1;
 
-		if(scene->selectmode & SCE_SELECT_FACE)
+		if(ts->selectmode & SCE_SELECT_FACE)
 			selectmode= UV_SELECT_FACE;
-		else if(scene->selectmode & SCE_SELECT_EDGE)
+		else if(ts->selectmode & SCE_SELECT_EDGE)
 			selectmode= UV_SELECT_EDGE;
 		else
 			selectmode= UV_SELECT_VERTEX;
@@ -1459,7 +1483,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 	}
 	else {
 		sync= 0;
-		selectmode= scene->toolsettings->uv_selectmode;
+		selectmode= ts->uv_selectmode;
 		sticky= sima->sticky;
 	}
 
@@ -1681,7 +1705,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 	
 	if(sync) {
 		/* flush for mesh selection */
-		if(scene->selectmode != SCE_SELECT_FACE) {
+		if(ts->selectmode != SCE_SELECT_FACE) {
 			if(flush==1)		EM_select_flush(em);
 			else if(flush==-1)	EM_deselect_flush(em);
 		}
@@ -1794,13 +1818,14 @@ static int select_linked_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	float limit[2];
 	int extend;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled.");
 		BKE_mesh_end_editmesh(obedit->data, em);
 		return OPERATOR_CANCELLED;
@@ -1838,13 +1863,14 @@ void UV_OT_select_linked(wmOperatorType *ot)
 static int unlink_selection_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled.");
 		BKE_mesh_end_editmesh(obedit->data, em);
 		return OPERATOR_CANCELLED;
@@ -1901,12 +1927,13 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 	 * This only needs to be done when the Mesh is not used for
 	 * selection (so for sticky modes, vertex or location based). */
 	
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 	int nverts, i;
 	
-	if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
+	if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
 		/* Tag all verts as untouched, then touch the ones that have a face center
 		 * in the loop and select all MTFace UV's that use a touched vert. */
 		EditVert *eve;
@@ -1937,7 +1964,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 			}
 		}
 	}
-	else if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
+	else if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
 		EditFace *efa_vlist;
 		MTFace *tf_vlist;
 		UvMapVert *start_vlist=NULL, *vlist_iter;
@@ -2008,7 +2035,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 		EM_free_uv_vert_map(vmap);
 		
 	}
-	else { /* SI_STICKY_DISABLE or scene->toolsettings->uv_flag & UV_SYNC_SELECTION */
+	else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
 		for(efa= em->faces.first; efa; efa= efa->next) {
 			if(efa->tmp.l) {
 				tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -2026,6 +2053,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	ARegion *ar= CTX_wm_region(C);
@@ -2049,10 +2077,10 @@ static int border_select_exec(bContext *C, wmOperator *op)
 	select= (RNA_int_get(op->ptr, "event_type") == LEFTMOUSE); // XXX hardcoded
 	pinned= RNA_boolean_get(op->ptr, "pinned");
 	
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
-		faces= (scene->selectmode == SCE_SELECT_FACE);
+	if(ts->uv_flag & UV_SYNC_SELECTION)
+		faces= (ts->selectmode == SCE_SELECT_FACE);
 	else
-		faces= (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
+		faces= (ts->uv_selectmode == UV_SELECT_FACE);
 
 	/* do actual selection */
 	if(faces && !pinned) {
@@ -2084,7 +2112,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
 		for(efa= em->faces.first; efa; efa= efa->next) {
 			tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 			if(uvedit_face_visible(scene, ima, efa, tface)) {
-				if(!pinned || (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) ) {
+				if(!pinned || (ts->uv_flag & UV_SYNC_SELECTION) ) {
 					/* UV_SYNC_SELECTION - can't do pinned selection */
 					if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
 						if(select)	uvedit_uv_select(scene, efa, tface, 0);
@@ -2133,8 +2161,8 @@ static int border_select_exec(bContext *C, wmOperator *op)
 
 	if(change) {
 		/* make sure newly selected vert selection is updated*/
-		if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-			if(scene->selectmode != SCE_SELECT_FACE) {
+		if(ts->uv_flag & UV_SYNC_SELECTION) {
+			if(ts->selectmode != SCE_SELECT_FACE) {
 				if(select)	EM_select_flush(em);
 				else		EM_deselect_flush(em);
 			}
@@ -2668,14 +2696,14 @@ void UV_OT_select_pinned(wmOperatorType *ot)
 static int hide_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 	int swap= RNA_boolean_get(op->ptr, "unselected");
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_hide_mesh(em, swap);
 		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
@@ -2811,14 +2839,14 @@ void UV_OT_hide(wmOperatorType *ot)
 static int reveal_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 	
 	/* call the mesh function if we are in mesh sync sel */
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_reveal_mesh(em);
 		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
diff --git a/source/blender/gpu/intern/Makefile b/source/blender/gpu/intern/Makefile
index 733ee3f764c..3a3ac20ff6c 100644
--- a/source/blender/gpu/intern/Makefile
+++ b/source/blender/gpu/intern/Makefile
@@ -35,7 +35,7 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
 
 include nan_compile.mk
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
+ifeq ($(OS),$(findstring $(OS), "darwin freebsd linux openbsd solaris windows"))
     CFLAGS += -funsigned-char
 endif
 
diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h
index bd2a0d3082f..7b5d668ce2b 100644
--- a/source/blender/imbuf/intern/imbuf.h
+++ b/source/blender/imbuf/intern/imbuf.h
@@ -51,7 +51,7 @@
 #include 
 #endif
 
-#if !defined(WIN32) && !defined(__BeOS)
+#if !defined(WIN32)
 #define O_BINARY 0
 #endif
 
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 6df92f69fff..1a6ab104bcf 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -244,26 +244,6 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
 
 	size = BLI_filesize(file);
 
-#if defined(AMIGA) || defined(__BeOS)
-	mem= (int *)malloc(size);
-	if (mem==0) {
-		printf("Out of mem\n");
-		return (0);
-	}
-
-	if (read(file, mem, size)!=size){
-		printf("Read Error\n");
-		free(mem);
-		return (0);
-	}
-
-	ibuf = IMB_ibImageFromMemory(mem, size, flags);
-	free(mem);
-
-	/* for jpeg read */
-	lseek(file, 0L, SEEK_SET);
-
-#else
 	mem= (int *)mmap(0,size,PROT_READ,MAP_SHARED,file,0);
 	if (mem==(int *)-1){
 		printf("Couldn't get mapping\n");
@@ -275,7 +255,6 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
 	if (munmap( (void *) mem, size)){
 		printf("Couldn't unmap file.\n");
 	}
-#endif
 	return(ibuf);
 }
 
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 8ce0b439b29..93a974c1180 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -84,6 +84,7 @@ typedef struct Brush {
 #define BRUSH_ANCHORED		256
 #define BRUSH_DIR_IN		512
 #define BRUSH_SPACE		1024
+#define BRUSH_SMOOTH_STROKE	2048
 
 /* Brush.blend */
 #define BRUSH_BLEND_MIX 		0
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 718d1a17834..88d9894cf7a 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -33,6 +33,8 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+#include "DNA_listBase.h"
 	
 typedef struct PartDeflect {
 	short deflect;		/* Deflection flag - does mesh deflect particles*/
@@ -72,12 +74,26 @@ typedef struct PartDeflect {
 	int seed; /* wind noise random seed */
 } PartDeflect;
 
+typedef struct PTCacheMem {
+	struct PTCacheMem *next, *prev;
+	int frame, totpoint;
+	float *data;	/* data points */
+	void *xdata;	/* extra data */
+} PTCacheMem;
+
 typedef struct PointCache {
 	int flag;		/* generic flag */
+	int step;		/* frames between cached frames */
 	int simframe;	/* current frame of simulation (only if SIMULATION_VALID) */
 	int startframe;	/* simulation start frame */
 	int endframe;	/* simulation end frame */
 	int editframe;	/* frame being edited (runtime only) */
+	int last_exact; /* last exact frame that's cached */
+	int xdata_type;	/* type of extra data */
+	char name[64];
+	char prev_name[64];
+	char info[64];
+	struct ListBase mem_cache;
 } PointCache;
 
 typedef struct SBVertex {
@@ -247,6 +263,12 @@ typedef struct SoftBody {
 #define PTCACHE_BAKING				8
 #define PTCACHE_BAKE_EDIT			16
 #define PTCACHE_BAKE_EDIT_ACTIVE	32
+#define PTCACHE_DISK_CACHE			64
+#define PTCACHE_QUICK_CACHE			128
+#define PTCACHE_FRAMES_SKIPPED		256
+
+/* PTCACHE_OUTDATED + PTCACHE_FRAMES_SKIPPED */
+#define PTCACHE_REDO_NEEDED			258
 
 /* ob->softflag */
 #define OB_SB_ENABLE	1
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 6805082d094..05f1cc1f351 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -34,6 +34,8 @@
 
 #include "DNA_ID.h"
 
+struct AnimData;
+
 typedef struct HairKey {
 	float co[3];	/* location of hair vertex */
 	float time;		/* time along hair, default 0-100 */
@@ -100,6 +102,7 @@ typedef struct ParticleData {
 
 typedef struct ParticleSettings {
 	ID id;
+	struct AnimData *adt;
 
 	int flag;
 	short type, from, distr;
@@ -167,7 +170,7 @@ typedef struct ParticleSettings {
 	struct Group *eff_group;
 	struct Object *dup_ob;
 	struct Object *bb_ob;
-	struct Ipo *ipo;
+	struct Ipo *ipo;				// xxx depreceated... old animation system
 	struct PartDeflect *pd;
 	struct PartDeflect *pd2;
 } ParticleSettings;
@@ -192,6 +195,7 @@ typedef struct ParticleSystem{				/* note, make sure all (runtime) are NULL's in
 	struct Object *target_ob;
 	struct Object *keyed_ob;
 	struct Object *lattice;
+	struct Object *parent;					/* particles from global space -> parent space */
 
 	struct ListBase effectors, reactevents;	/* runtime */
 	
diff --git a/source/blender/makesdna/DNA_radio_types.h b/source/blender/makesdna/DNA_radio_types.h
deleted file mode 100644
index 4219bf59b93..00000000000
--- a/source/blender/makesdna/DNA_radio_types.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * radio_types.h    dec 2000 Nzc
- *
- * All type defs for the Blender core.
- *
- * $Id$ 
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- * 
- */
-
-#ifndef DNA_RADIO_TYPES_H
-#define DNA_RADIO_TYPES_H
-
-typedef struct Radio {
-	short hemires, maxiter;
-	short drawtype, flag;			/* bit 0 and 1: show limits */
-	short subshootp, subshoote, nodelim, maxsublamp;
-	short pama, pami, elma, elmi;	/* patch and elem limits */
-	int maxnode;
-	float convergence;
-	float radfac, gamma;		/* for display */
-	
-} Radio;
-
-
-/* **************** RADIOSITY ********************* */
-
-/* draw type */
-#define RAD_WIREFRAME	0
-#define RAD_SOLID		1
-#define RAD_GOURAUD		2
-
-/* flag */
-#define RAD_SHOWLIMITS	1
-#define RAD_SHOWZ		2
-
-#endif
-
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index e8279604100..1199bd1e2b1 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -39,7 +39,6 @@ extern "C" {
 #include "DNA_scriptlink_types.h"
 #include "DNA_ID.h"
 
-struct Radio;
 struct Object;
 struct World;
 struct Scene;
@@ -48,6 +47,7 @@ struct Group;
 struct Text;
 struct bNodeTree;
 struct AnimData;
+struct Editing;
 
 typedef struct Base {
 	struct Base *next, *prev;
@@ -158,7 +158,7 @@ typedef struct SceneRenderLayer {
 #define SCE_PASS_REFRACT	1024
 #define SCE_PASS_INDEXOB	2048
 #define SCE_PASS_UV			4096
-#define SCE_PASS_RADIO		8192
+#define SCE_PASS_RADIO		8192 /* Radio removed, can use for new GI? */
 #define SCE_PASS_MIST		16384
 
 /* note, srl->passflag is treestore element 'nr' in outliner, short still... */
@@ -385,6 +385,8 @@ typedef struct ParticleEditSettings {
 
 	float emitterdist;
 	int draw_timed;
+
+	int selectmode, pad;
 } ParticleEditSettings;
 
 typedef struct TransformOrientation {
@@ -439,19 +441,27 @@ typedef struct ToolSettings {
 	VPaint *wpaint;		/* weight paint */
 	Sculpt *sculpt;
 	
+	/* Vertex groups */
+	float vgroup_weight;
+
 	/* Subdivide Settings */
 	short cornertype;
 	short editbutflag;
 	/*Triangle to Quad conversion threshold*/
 	float jointrilimit;
-	/* Extrude Tools */
+	/* Editmode Tools */
 	float degr; 
 	short step;
 	short turn; 
 	
-	float extr_offs; 
-	float doublimit;
-	
+	float extr_offs; 	/* extrude offset */
+	float doublimit;	/* remove doubles limit */
+	float normalsize;	/* size of normals */
+	short automerge;
+
+	/* Selection Mode for Mesh */
+	short selectmode;
+
 	/* Primitive Settings */
 	/* UV Sphere */
 	short segments;
@@ -465,7 +475,6 @@ typedef struct ToolSettings {
 	float uvcalc_radius;
 	float uvcalc_cubesize;
 	float uvcalc_margin;
-	float pad;
 	short uvcalc_mapdir;
 	short uvcalc_mapalign;
 	short uvcalc_flag;
@@ -487,8 +496,11 @@ typedef struct ToolSettings {
 	/* Select Group Threshold */
 	float select_thresh;
 	
-	/* IPO-Editor */
+	/* Graph Editor */
 	float clean_thresh;
+
+	/* Auto-Keying Mode */
+	short autokey_mode, pad2;	/* defines in DNA_userdef_types.h */
 	
 	/* Retopo */
 	char retopo_mode;
@@ -515,7 +527,6 @@ typedef struct ToolSettings {
 	char  skgen_postpro_passes;
 	char  skgen_subdivisions[3];
 	char  skgen_multi_level;
-	int   skgen_pad;
 	
 	/* Skeleton Sketching */
 	struct Object *skgen_template;
@@ -529,7 +540,10 @@ typedef struct ToolSettings {
 	
 	/* Alt+RMB option */
 	char edge_mode;
-	char pad3[2];
+
+	/* Transform */
+	short snap_mode, snap_flag, snap_target;
+	short proportional, prop_mode;
 } ToolSettings;
 
 typedef struct bStats {
@@ -550,29 +564,22 @@ typedef struct Scene {
 	struct Image *ima;
 	
 	ListBase base;
-	struct Base *basact;
+	struct Base *basact;		/* active base */
 	struct Object *obedit;		/* name replaces old G.obedit */
 	
-	float cursor[3];
+	float cursor[3];			/* 3d cursor location */
 	float twcent[3];			/* center for transform widget */
 	float twmin[3], twmax[3];	/* boundbox of selection for transform widget */
 	unsigned int lay;
 	
-	/* editmode stuff */
-	float editbutsize;                      /* size of normals */
-	short selectmode;						/* for mesh only! */
-	short proportional, prop_mode;
-	short automerge, pad5;
 	
 	short flag;								/* various settings */
-	short autokey_mode; 					/* mode for autokeying (defines in DNA_userdef_types.h) */
 	
 	short use_nodes;
 	
 	struct bNodeTree *nodetree;	
 	
-	void *ed;								/* sequence editor data is allocated here */
-	struct Radio *radio;
+	struct Editing *ed;								/* sequence editor data is allocated here */
 	
 	struct GameFraming framing;
 
@@ -582,20 +589,20 @@ typedef struct Scene {
 	/* migrate or replace? depends on some internal things... */
 	/* no, is on the right place (ton) */
 	struct RenderData r;
-	struct AudioData audio;		/* DEPRICATED 2.5 */
+	struct AudioData audio;		/* DEPRECATED 2.5 */
 	
 	ScriptLink scriptlink;
 	
 	ListBase markers;
 	ListBase transform_spaces;
 	
-	short jumpframe;
-	short snap_mode, snap_flag, snap_target;
 	
 	/* none of the dependancy graph  vars is mean to be saved */
 	struct  DagForest *theDag;
 	short dagisvalid, dagflags;
-	short pad4, recalc;				/* recalc = counterpart of ob->recalc */
+	short recalc;				/* recalc = counterpart of ob->recalc */
+
+	short jumpframe;
 
 	/* frame step. */
 	int frame_step;
@@ -801,27 +808,27 @@ typedef struct Scene {
 
 /* base->flag is in DNA_object_types.h */
 
-/* scene->snap_flag */
+/* toolsettings->snap_flag */
 #define SCE_SNAP				1
 #define SCE_SNAP_ROTATE			2
 #define SCE_SNAP_PEEL_OBJECT	4
-/* scene->snap_target */
+/* toolsettings->snap_target */
 #define SCE_SNAP_TARGET_CLOSEST	0
 #define SCE_SNAP_TARGET_CENTER	1
 #define SCE_SNAP_TARGET_MEDIAN	2
 #define SCE_SNAP_TARGET_ACTIVE	3
-/* scene->snap_mode */
+/* toolsettings->snap_mode */
 #define SCE_SNAP_MODE_VERTEX	0
 #define SCE_SNAP_MODE_EDGE		1
 #define SCE_SNAP_MODE_FACE		2
 #define SCE_SNAP_MODE_VOLUME	3
 
-/* sce->selectmode */
+/* toolsettings->selectmode */
 #define SCE_SELECT_VERTEX	1 /* for mesh */
 #define SCE_SELECT_EDGE		2
 #define SCE_SELECT_FACE		4
 
-/* sce->selectmode for particles */
+/* toolsettings->particle.selectmode for particles */
 #define SCE_SELECT_PATH		1
 #define SCE_SELECT_POINT	2
 #define SCE_SELECT_END		4
@@ -829,7 +836,7 @@ typedef struct Scene {
 /* sce->recalc (now in use by previewrender) */
 #define SCE_PRV_CHANGED		1
 
-/* sce->prop_mode (proportional falloff) */
+/* toolsettings->prop_mode (proportional falloff) */
 #define PROP_SMOOTH            0
 #define PROP_SPHERE            1
 #define PROP_ROOT              2
@@ -896,7 +903,7 @@ typedef enum SculptFlags {
 
 /* toolsettings->uv_selectmode */
 #define UV_SELECT_VERTEX	1
-#define UV_SELECT_EDGE		2 /* not implemented */
+#define UV_SELECT_EDGE		2
 #define UV_SELECT_FACE		4
 #define UV_SELECT_ISLAND	8
 
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 4891f44e1cd..d9d68490425 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -53,6 +53,7 @@ typedef struct bScreen {
 	ListBase regionbase;				/* screen level regions (menus), runtime only */
 	
 	struct Scene *scene;
+	struct Scene *newscene;				/* temporary when switching */
 	
 	short full;							/* fade out? */
 	short winid;						/* winid from WM, starts with 1 */
@@ -104,6 +105,9 @@ typedef struct Panel {		/* the part from uiBlock that needs saved in file */
 	int sortorder;			/* panels are aligned according to increasing sortorder */
 	struct Panel *paneltab;		/* this panel is tabbed in *paneltab */
 	void *activedata;			/* runtime for panel manipulation */
+
+	int list_scroll, list_size;
+	char list_search[64];
 } Panel;
 
 typedef struct Header {
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 416acd7467e..53dc5ed26e8 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -165,6 +165,48 @@ typedef struct SpaceSeq {
 	struct bGPdata *gpd;		/* grease-pencil data */
 } SpaceSeq;
 
+typedef struct FileSelectParams {
+	char title[24]; /* title, also used for the text of the execute button */
+	char dir[240]; /* directory */
+	char file[80]; /* file */
+
+	short flag; /* settings for filter, hiding files and display mode */
+	short sort; /* sort order */
+	short display; /* display mode flag */
+	short filter; /* filter when (flags & FILE_FILTER) is true */
+
+	/* XXX - temporary, better move to filelist */
+	short active_bookmark;
+	short pad;
+	int	active_file;
+	int selstate;
+
+	/* XXX --- still unused -- */
+	short f_fp; /* show font preview */
+	short menu; /* currently selected option in pupmenu */
+	char fp_str[8]; /* string to use for font preview */
+	
+	char *pupmenu; /* allows menu for save options - result stored in menup */
+	
+	/* XXX --- end unused -- */
+} FileSelectParams;
+
+/* FileSelectParams.display */
+enum FileDisplayTypeE {
+	FILE_SHORTDISPLAY = 1,
+	FILE_LONGDISPLAY,
+	FILE_IMGDISPLAY
+};
+
+/* FileSelectParams.sort */
+enum FileSortTypeE {
+	FILE_SORT_NONE = 0,
+	FILE_SORT_ALPHA = 1,
+	FILE_SORT_EXTENSION,
+	FILE_SORT_TIME,
+	FILE_SORT_SIZE
+};
+
 typedef struct SpaceFile {
 	SpaceLink *next, *prev;
 	ListBase regionbase;		/* storage of regions for inactive spaces */
@@ -229,7 +271,7 @@ typedef struct SpaceImage {
 	char dt_uv; /* UV draw type */
 	char sticky; /* sticky selection type */
 	char dt_uvstretch;
-	char pad;
+	char around;
 	
 	float xof, yof;					/* user defined offset, image is centered */
 	float zoom, pad4;				/* user defined zoom level */
@@ -554,12 +596,6 @@ typedef struct SpaceImaSel {
 #define FILE_FILTER			256
 #define FILE_BOOKMARKS		512
 
-/* sfile->sort */
-#define FILE_SORTALPHA		0
-#define FILE_SORTDATE		1
-#define FILE_SORTSIZE		2
-#define FILE_SORTEXTENS		3
-
 /* files in filesel list: 2=ACTIVE  */
 #define HILITE				1
 #define BLENDERFILE			4
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 9d554c88a95..771a7e43793 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -67,7 +67,8 @@ typedef struct uiFontStyle {
 	short uifont_id;		/* saved in file, 0 is default */
 	short points;			/* actual size depends on 'global' dpi */
 	float kerning;			/* kerning space between characters. */
-	float pad;
+	short overlap;			/* check overlaped characters. */
+	short pad;
 	short italic, bold;		/* style hint */
 	short shadow;			/* value is amount of pixels blur */
 	short shadx, shady;		/* shadow offset in pixels */
@@ -123,10 +124,11 @@ typedef struct uiWidgetColors {
 typedef struct ThemeUI {
 	
 	/* Interface Elements (buttons, menus, icons) */
-	uiWidgetColors wcol_regular, wcol_tool, wcol_radio, wcol_text, wcol_option;
+	uiWidgetColors wcol_regular, wcol_tool, wcol_text;
+	uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
 	uiWidgetColors wcol_num, wcol_numslider;
 	uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item;
-	uiWidgetColors wcol_box;
+	uiWidgetColors wcol_box, wcol_scroll;
 	
 	char iconfile[80];	// FILE_MAXFILE length
 	
@@ -379,7 +381,7 @@ extern UserDef U; /* from blenkernel blender.c */
 #define USER_ZOOM_TO_MOUSEPOS	(1 << 20)
 #define USER_SHOW_FPS			(1 << 21)
 #define USER_MMB_PASTE			(1 << 22)
-#define USER_DIRECTIONALORDER	(1 << 23)
+#define USER_MENUFIXEDORDER		(1 << 23)
 
 /* Auto-Keying mode */
 	/* AUTOKEY_ON is a bitflag */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 7d6b5ec8764..b63fb35c193 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -88,7 +88,8 @@ typedef struct wmWindow {
 	
 	int winid, pad;		/* winid also in screens, is for retrieving this window after read */
 	
-	struct bScreen *screen;	/* active screen */
+	struct bScreen *screen;		/* active screen */
+	struct bScreen *newscreen;	/* temporary when switching */
 	char screenname[32];	/* MAX_ID_NAME for matching window with active screen after file read */
 	
 	short posx, posy, sizex, sizey;	/* window coords */
@@ -222,5 +223,36 @@ typedef enum wmRadialControlMode {
 	WM_RADIALCONTROL_ANGLE
 } wmRadialControlMode;
 
+/* ************** wmEvent ************************ */
+/* for read-only rna access, dont save this */
+
+/* each event should have full modifier state */
+/* event comes from eventmanager and from keymap */
+typedef struct wmEvent {
+	struct wmEvent *next, *prev;
+	
+	short type;			/* event code itself (short, is also in keymap) */
+	short val;			/* press, release, scrollvalue */
+	short x, y;			/* mouse pointer position, screen coord */
+	short mval[2];		/* region mouse position, name convention pre 2.5 :) */
+	short prevx, prevy;	/* previous mouse pointer position */
+	short unicode;		/* future, ghost? */
+	char ascii;			/* from ghost */
+	char pad;
+	
+	/* modifier states */
+	short shift, ctrl, alt, oskey;	/* oskey is apple or windowskey, value denotes order of pressed */
+	short keymodifier;				/* rawkey modifier */
+	
+	/* keymap item, set by handler (weak?) */
+	const char *keymap_idname;
+	
+	/* custom data */
+	short custom;	/* custom data type, stylus, 6dof, see wm_event_types.h */
+	void *customdata;	/* ascii, unicode, mouse coords, angles, vectors, dragdrop info */
+	short customdatafree;
+	
+} wmEvent;
+
 #endif /* DNA_WINDOWMANAGER_TYPES_H */
 
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index bf2f0f3900e..91e9e617ea9 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -98,7 +98,6 @@ char *includefiles[] = {
 	"DNA_object_force.h",
 	"DNA_object_fluidsim.h",
 	"DNA_world_types.h",
-	"DNA_radio_types.h",
 	"DNA_scene_types.h",
 	"DNA_view3d_types.h",
 	"DNA_view2d_types.h",	
@@ -1124,7 +1123,6 @@ int main(int argc, char ** argv)
 #include "DNA_object_force.h"
 #include "DNA_object_fluidsim.h"
 #include "DNA_world_types.h"
-#include "DNA_radio_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_view2d_types.h"	
diff --git a/source/blender/makesrna/Makefile b/source/blender/makesrna/Makefile
index 25625af57a6..bed3e85550d 100644
--- a/source/blender/makesrna/Makefile
+++ b/source/blender/makesrna/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 21247 2009-06-29 21:50:53Z jaguarandi $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index c1a659fee9b..d69439e25bc 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_access.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -172,7 +172,9 @@ extern StructRNA RNA_EnvironmentMap;
 extern StructRNA RNA_EnvironmentMapTexture;
 extern StructRNA RNA_ExplodeModifier;
 extern StructRNA RNA_ExpressionController;
+extern StructRNA RNA_Event;
 extern StructRNA RNA_FCurve;
+extern StructRNA RNA_FileSelectParams;
 extern StructRNA RNA_FModifier;
 extern StructRNA RNA_FModifierCycles;
 extern StructRNA RNA_FModifierEnvelope;
@@ -368,6 +370,7 @@ extern StructRNA RNA_SpaceImageEditor;
 extern StructRNA RNA_SpaceOutliner;
 extern StructRNA RNA_SpaceSequenceEditor;
 extern StructRNA RNA_SpaceTextEditor;
+extern StructRNA RNA_SpaceFileBrowser;
 extern StructRNA RNA_SpaceUVEditor;
 extern StructRNA RNA_SpeedControlSequence;
 extern StructRNA RNA_SpotLamp;
@@ -513,6 +516,8 @@ const struct ListBase *RNA_struct_defined_properties(StructRNA *srna);
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier);
 const struct ListBase *RNA_struct_defined_functions(StructRNA *srna);
 
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen);
+
 /* Properties
  *
  * Access to struct properties. All this works with RNA pointers rather than
@@ -541,6 +546,9 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin,
 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax);
 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision);
 
+int RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **identifier);
+int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **name);
+
 void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem);
 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value);
 int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
@@ -594,6 +602,14 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop);
 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr);
 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr);
 
+/* efficient functions to set properties for arrays */
+int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array);
+int RNA_property_collection_raw_get(struct ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len);
+int RNA_property_collection_raw_set(struct ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len);
+int RNA_raw_type_sizeof(RawPropertyType type);
+RawPropertyType RNA_property_raw_type(PropertyRNA *prop);
+
+
 /* to create ID property groups */
 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop);
 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop);
@@ -689,6 +705,28 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
 		RNA_property_collection_end(&rna_macro_iter); \
 	}
 
+#define RNA_PROP_BEGIN(sptr, itemptr, prop) \
+	{ \
+		CollectionPropertyIterator rna_macro_iter; \
+		for(RNA_property_collection_begin(sptr, prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \
+			PointerRNA itemptr= rna_macro_iter.ptr;
+
+#define RNA_PROP_END \
+		} \
+		RNA_property_collection_end(&rna_macro_iter); \
+	}
+
+#define RNA_STRUCT_BEGIN(sptr, prop) \
+	{ \
+		CollectionPropertyIterator rna_macro_iter; \
+		for(RNA_property_collection_begin(sptr, RNA_struct_iterator_property(sptr->type), &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \
+			PropertyRNA *prop= rna_macro_iter.ptr.data;
+
+#define RNA_STRUCT_END \
+		} \
+		RNA_property_collection_end(&rna_macro_iter); \
+	}
+
 /* check if the idproperty exists, for operators */
 int RNA_property_is_set(PointerRNA *ptr, const char *name);
 
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 91669616d89..85a148be2e2 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_define.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -80,7 +80,7 @@ PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, c
 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 
-PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
+PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
 
 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 841b397f276..276f421c586 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_enum_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -40,6 +40,9 @@ extern EnumPropertyItem beztriple_interpolation_mode_items[];
 
 extern EnumPropertyItem fmodifier_type_items[];
 
+extern EnumPropertyItem event_value_items[];
+extern EnumPropertyItem event_type_items[];
+
 #endif /* RNA_ENUM_TYPES */
 
 
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index a0fa2cc3344..923191cba78 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -110,7 +110,9 @@ typedef enum PropertyFlag {
 	PROP_BUILTIN = 128,
 	PROP_EXPORT = 256,
 	PROP_RUNTIME = 512,
-	PROP_IDPROPERTY = 1024
+	PROP_IDPROPERTY = 1024,
+	PROP_RAW_ACCESS = 8192,
+	PROP_RAW_ARRAY = 16384,
 } PropertyFlag;
 
 typedef struct CollectionPropertyIterator {
@@ -132,6 +134,21 @@ typedef struct CollectionPointerLink {
 	PointerRNA ptr;
 } CollectionPointerLink;
 
+typedef enum RawPropertyType {
+	PROP_RAW_CHAR,
+	PROP_RAW_SHORT,
+	PROP_RAW_INT,
+	PROP_RAW_FLOAT,
+	PROP_RAW_DOUBLE
+} RawPropertyType;
+
+typedef struct RawArray {
+	void *array;
+	RawPropertyType type;
+	int len;
+	int stride;
+} RawArray;
+
 /* Iterator Utility */
 
 typedef struct EnumPropertyItem {
diff --git a/source/blender/makesrna/intern/Makefile b/source/blender/makesrna/intern/Makefile
index 03f75f0bea6..1694e55ed4c 100644
--- a/source/blender/makesrna/intern/Makefile
+++ b/source/blender/makesrna/intern/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 13161 2008-01-07 19:13:47Z hos $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 1db61a842e5..c42bc866f99 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1,5 +1,5 @@
 /**
- * $Id: makesrna.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -36,7 +36,7 @@
 
 #include "rna_internal.h"
 
-#define RNA_VERSION_DATE "$Id: makesrna.c 21247 2009-06-29 21:50:53Z jaguarandi $"
+#define RNA_VERSION_DATE "$Id$"
 
 #ifdef _WIN32
 #ifndef snprintf
@@ -248,8 +248,7 @@ static const char *rna_parameter_type_name(PropertyRNA *parm)
 				return rna_find_dna_type((const char *)pparm->type);
 		}
 		case PROP_COLLECTION: {
-			CollectionPropertyRNA *cparm= (CollectionPropertyRNA*)parm;
-			return rna_find_dna_type((const char *)cparm->type);
+			return "ListBase";
 		}
 		default:
 			return "";
@@ -763,6 +762,42 @@ static char *rna_def_property_end_func(FILE *f, StructRNA *srna, PropertyRNA *pr
 	return func;
 }
 
+static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
+{
+	if(dp->dnapointerlevel != 0)
+		return;
+	if(!dp->dnatype || !dp->dnaname || !dp->dnastructname)
+		return;
+	
+	if(strcmp(dp->dnatype, "char") == 0) {
+		prop->rawtype= PROP_RAW_CHAR;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "short") == 0) {
+		prop->rawtype= PROP_RAW_SHORT;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "int") == 0) {
+		prop->rawtype= PROP_RAW_INT;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "float") == 0) {
+		prop->rawtype= PROP_RAW_FLOAT;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "double") == 0) {
+		prop->rawtype= PROP_RAW_DOUBLE;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+}
+
+static void rna_set_raw_offset(FILE *f, StructRNA *srna, PropertyRNA *prop)
+{
+	PropertyDefRNA *dp= rna_find_struct_property_def(srna, prop);
+
+	fprintf(f, "\toffsetof(%s, %s), %d", dp->dnastructname, dp->dnaname, prop->rawtype);
+}
+
 static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 {
 	PropertyRNA *prop;
@@ -774,6 +809,9 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
 
 			if(!prop->arraylength) {
+				if(!bprop->get && !bprop->set && !dp->booleanbit)
+					rna_set_raw_property(dp, prop);
+
 				bprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)bprop->get);
 				bprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)bprop->set);
 			}
@@ -787,10 +825,16 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
 
 			if(!prop->arraylength) {
+				if(!iprop->get && !iprop->set)
+					rna_set_raw_property(dp, prop);
+
 				iprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->get);
 				iprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->set);
 			}
 			else {
+				if(!iprop->getarray && !iprop->setarray)
+					rna_set_raw_property(dp, prop);
+
 				iprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->getarray);
 				iprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->setarray);
 			}
@@ -800,10 +844,16 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
 
 			if(!prop->arraylength) {
+				if(!fprop->get && !fprop->set)
+					rna_set_raw_property(dp, prop);
+
 				fprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->get);
 				fprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->set);
 			}
 			else {
+				if(!fprop->getarray && !fprop->setarray)
+					rna_set_raw_property(dp, prop);
+
 				fprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->getarray);
 				fprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->setarray);
 			}
@@ -842,6 +892,13 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			else if(dp->dnalengthname || dp->dnalengthfixed)
 				cprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp, (char*)cprop->length);
 
+			/* test if we can allow raw array access, if it is using our standard
+			 * array get/next function, we can be sure it is an actual array */
+			if(cprop->next && cprop->get)
+				if(strcmp((char*)cprop->next, "rna_iterator_array_next") == 0 &&
+				   strcmp((char*)cprop->get, "rna_iterator_array_get") == 0)
+					prop->flag |= PROP_RAW_ARRAY;
+
 			cprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)cprop->get);
 			cprop->begin= (void*)rna_def_property_begin_func(f, srna, prop, dp, (char*)cprop->begin);
 			cprop->next= (void*)rna_def_property_next_func(f, srna, prop, dp, (char*)cprop->next);
@@ -1116,9 +1173,11 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
 
 	funcname= rna_alloc_function_name(srna->identifier, func->identifier, "call");
 
+	/* function definition */
 	fprintf(f, "void %s(bContext *C, ReportList *reports, PointerRNA *_ptr, ParameterList *_parms)", funcname);
 	fprintf(f, "\n{\n");
 
+	/* variable definitions */
 	if((func->flag & FUNC_NO_SELF)==0) {
 		if(dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
 		else fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
@@ -1135,6 +1194,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
 	fprintf(f, ";\n");
 	fprintf(f, "\t\n");
 
+	/* assign self */
 	if((func->flag & FUNC_NO_SELF)==0) {
 		if(dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
 		else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
@@ -1405,6 +1465,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
 	dsrna= rna_find_struct_def(srna);
 	func= dfunc->func;
 
+	/* return type */
 	for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
 		if(dparm->prop==func->ret) {
 			if(dparm->prop->arraylength)
@@ -1418,13 +1479,16 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
 		}
 	}
 
+	/* void if nothing to return */
 	if(!dparm)
 		fprintf(f, "void ");
 
+	/* function name */
 	fprintf(f, "%s(", dfunc->call);
 
 	first= 1;
 
+	/* self, context and reports parameters */
 	if((func->flag & FUNC_NO_SELF)==0) {
 		if(dsrna->dnaname) fprintf(f, "struct %s *_self", dsrna->dnaname);
 		else fprintf(f, "struct %s *_self", srna->identifier);
@@ -1443,6 +1507,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
 		fprintf(f, "ReportList *reports");
 	}
 
+	/* defined parameters */
 	for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
 		if(dparm->prop==func->ret)
 			continue;
@@ -1531,7 +1596,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					DefRNA.error= 1;
 				}
 				break;
-											}
+			}
 			case PROP_BOOLEAN: {
 				BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
 				unsigned int i;
@@ -1551,7 +1616,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "};\n\n");
 				}
 				break;
-												 }
+			}
 			case PROP_INT: {
 				IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
 				unsigned int i;
@@ -1571,7 +1636,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "};\n\n");
 				}
 				break;
-										 }
+			}
 			case PROP_FLOAT: {
 				FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
 				unsigned int i;
@@ -1591,7 +1656,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "};\n\n");
 				}
 				break;
-											 }
+			}
 			default:
 				break;
 	}
@@ -1606,10 +1671,14 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 	rna_print_c_string(f, prop->identifier);
 	fprintf(f, ", %d, ", prop->flag);
 	rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
-	rna_print_c_string(f, prop->description); fprintf(f, ",\n");
-	fprintf(f, "%d, ", prop->icon);
+	rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
+	fprintf(f, "%d,\n", prop->icon);
 	fprintf(f, "\t%s, %s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), prop->arraylength);
-	fprintf(f, "\t%s, %d, %s},\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable));
+	fprintf(f, "\t%s, %d, %s,\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable));
+
+	if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
+	else fprintf(f, "\t0, 0");
+	fprintf(f, "},\n");
 
 	switch(prop->type) {
 			case PROP_BOOLEAN: {
@@ -1618,7 +1687,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 				if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
 				else fprintf(f, "NULL\n");
 				break;
-												 }
+			}
 			case PROP_INT: {
 				IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %s, %s,\n\t", rna_function_string(iprop->get), rna_function_string(iprop->set), rna_function_string(iprop->getarray), rna_function_string(iprop->setarray), rna_function_string(iprop->range));
@@ -1631,7 +1700,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 				if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
 				else fprintf(f, "NULL\n");
 				break;
-										 }
+			 }
 			case PROP_FLOAT: {
 				FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range));
@@ -1645,13 +1714,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 				if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
 				else fprintf(f, "NULL\n");
 				break;
-											 }
+			 }
 			case PROP_STRING: {
 				StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength);
 				rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
 				break;
-												}
+			}
 			case PROP_ENUM: {
 				EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, ", rna_function_string(eprop->get), rna_function_string(eprop->set), rna_function_string(eprop->itemf));
@@ -1661,14 +1730,14 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "NULL, ");
 				fprintf(f, "%d, %d\n", eprop->totitem, eprop->defaultvalue);
 				break;
-											}
+			}
 			case PROP_POINTER: {
 				PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, ", rna_function_string(pprop->get), rna_function_string(pprop->set), rna_function_string(pprop->typef));
 				if(pprop->type) fprintf(f, "&RNA_%s\n", (char*)pprop->type);
 				else fprintf(f, "NULL\n");
 				break;
-												 }
+			 }
 			case PROP_COLLECTION: {
 				CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring));
@@ -1853,7 +1922,6 @@ RNAProcessItem PROCESS_ITEMS[]= {
 	{"rna_particle.c", NULL, RNA_def_particle},
 	{"rna_pose.c", NULL, RNA_def_pose},
 	{"rna_property.c", NULL, RNA_def_gameproperty},
-	{"rna_radio.c", NULL, RNA_def_radio},
 	{"rna_scene.c", NULL, RNA_def_scene},
 	{"rna_screen.c", NULL, RNA_def_screen},
 	{"rna_scriptlink.c", NULL, RNA_def_scriptlink},
@@ -1884,6 +1952,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, char *filename, char *api_fi
 	fprintf(f, "#include \n");
 	fprintf(f, "#include \n");
 	fprintf(f, "#include \n\n");
+	fprintf(f, "#include \n\n");
 
 	fprintf(f, "#include \"DNA_ID.h\"\n");
 
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index e70cd6ff8d3..7d8bab8bee8 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_ID.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 3073029d9b4..cc8704dc350 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_access.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -426,23 +426,16 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
 /* Find the property which uses the given nested struct */
 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
 {
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *prop;
-	int i = 0;
-
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-	prop= NULL;
+	PropertyRNA *prop= NULL;
 
-	for(; iter.valid; RNA_property_collection_next(&iter), i++) {
+	RNA_STRUCT_BEGIN(ptr, iprop) {
 		/* This assumes that there can only be one user of this nested struct */
-		if (RNA_property_pointer_type(ptr, iter.ptr.data) == srna) {
-			prop= iter.ptr.data;
+		if (RNA_property_pointer_type(ptr, iprop) == srna) {
+			prop= iprop;
 			break;
 		}
 	}
-
-	RNA_property_collection_end(&iter);
+	RNA_PROP_END;
 
 	return prop;
 }
@@ -455,25 +448,21 @@ const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
 {
 	PointerRNA tptr;
-	CollectionPropertyIterator iter;
 	PropertyRNA *iterprop;
 	FunctionRNA *func;
-	int i = 0;
 
 	RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
 	iterprop= RNA_struct_find_property(&tptr, "functions");
 
-	RNA_property_collection_begin(&tptr, iterprop, &iter);
 	func= NULL;
 
-	for(; iter.valid; RNA_property_collection_next(&iter), i++) {
-		if(strcmp(identifier, RNA_function_identifier(iter.ptr.data)) == 0) {
-			func= iter.ptr.data;
+	RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
+		if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
+			func= funcptr.data;
 			break;
 		}
 	}
-
-	RNA_property_collection_end(&iter);
+	RNA_PROP_END;
 
 	return func;
 }
@@ -518,6 +507,16 @@ void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
 	srna->blender_type= blender_type;
 }
 
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
+{
+	PropertyRNA *nameprop;
+
+	if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
+		return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
+
+	return NULL;
+}
+
 /* Property Information */
 
 const char *RNA_property_identifier(PropertyRNA *prop)
@@ -643,25 +642,27 @@ void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPrope
 
 	if(eprop->itemf) {
 		*item= eprop->itemf(ptr);
-		for(tot=0; (*item)[tot].identifier; tot++);
-		*totitem= tot;
+		if(totitem) {
+			for(tot=0; (*item)[tot].identifier; tot++);
+			*totitem= tot;
+		}
 	}
 	else {
 		*item= eprop->item;
-		*totitem= eprop->totitem;
+		if(totitem)
+			*totitem= eprop->totitem;
 	}
 }
 
 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
 {	
 	const EnumPropertyItem *item;
-	int totitem, i;
 	
-	RNA_property_enum_items(ptr, prop, &item, &totitem);
+	RNA_property_enum_items(ptr, prop, &item, NULL);
 	
-	for(i=0; iidentifier; item++) {
+		if(strcmp(item->identifier, identifier)==0) {
+			*value = item->value;
 			return 1;
 		}
 	}
@@ -669,23 +670,36 @@ int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *iden
 	return 0;
 }
 
-int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
-{	
-	const EnumPropertyItem *item;
-	int totitem, i;
-	
-	RNA_property_enum_items(ptr, prop, &item, &totitem);
-	
-	for(i=0; iidentifier; item++) {
+		if(item->value==value) {
+			*identifier = item->identifier;
 			return 1;
 		}
 	}
-	
 	return 0;
 }
 
+int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **name)
+{
+	for (; item->identifier; item++) {
+		if(item->value==value) {
+			*name = item->name;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
+{	
+	const EnumPropertyItem *item= NULL;
+	
+	RNA_property_enum_items(ptr, prop, &item, NULL);
+	return RNA_enum_identifier(item, value, identifier);
+}
+
 const char *RNA_property_ui_name(PropertyRNA *prop)
 {
 	return rna_ensure_property_name(prop);
@@ -1508,6 +1522,323 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, co
 	}
 }
 
+int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
+{
+	CollectionPropertyIterator iter;
+	ArrayIterator *internal;
+	char *arrayp;
+
+	if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
+		return 0;
+
+	RNA_property_collection_begin(ptr, prop, &iter);
+
+	if(iter.valid) {
+		/* get data from array iterator and item property */
+		internal= iter.internal;
+		arrayp= (iter.valid)? iter.ptr.data: NULL;
+
+		if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
+			/* we might skip some items, so it's not a proper array */
+			RNA_property_collection_end(&iter);
+			return 0;
+		}
+
+		array->array= arrayp + itemprop->rawoffset;
+		array->stride= internal->itemsize;
+		array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
+		array->type= itemprop->rawtype;
+	}
+	else
+		memset(array, 0, sizeof(RawArray));
+
+	RNA_property_collection_end(&iter);
+
+	return 1;
+}
+
+#define RAW_GET(dtype, var, raw, a) \
+{ \
+	switch(raw.type) { \
+		case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
+		case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
+		case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
+		case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
+		case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
+		default: var = (dtype)0; \
+	} \
+}
+
+#define RAW_SET(dtype, raw, a, var) \
+{ \
+	switch(raw.type) { \
+		case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
+		case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
+		case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
+		case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
+		case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
+	} \
+}
+
+int RNA_raw_type_sizeof(RawPropertyType type)
+{
+	switch(type) {
+		case PROP_RAW_CHAR: return sizeof(char);
+		case PROP_RAW_SHORT: return sizeof(short);
+		case PROP_RAW_INT: return sizeof(int);
+		case PROP_RAW_FLOAT: return sizeof(float);
+		case PROP_RAW_DOUBLE: return sizeof(double);
+		default: return 0;
+	}
+}
+
+static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
+{
+	StructRNA *ptype;
+	PointerRNA itemptr;
+	PropertyRNA *itemprop, *iprop;
+	PropertyType itemtype;
+	RawArray in;
+	int itemlen= 0;
+
+	/* initialize in array, stride assumed 0 in following code */
+	in.array= inarray;
+	in.type= intype;
+	in.len= inlen;
+	in.stride= 0;
+
+	ptype= RNA_property_pointer_type(ptr, prop);
+
+	/* try to get item property pointer */
+	RNA_pointer_create(NULL, ptype, NULL, &itemptr);
+	itemprop= RNA_struct_find_property(&itemptr, propname);
+
+	if(itemprop) {
+		/* we have item property pointer */
+		RawArray out;
+
+		/* check type */
+		itemtype= RNA_property_type(itemprop);
+
+		if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
+			BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
+			return 0;
+		}
+
+		/* check item array */
+		itemlen= RNA_property_array_length(itemprop);
+
+		/* try to access as raw array */
+		if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
+			if(in.len != itemlen*out.len) {
+				BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
+				return 0;
+			}
+			
+			/* matching raw types */
+			if(out.type == in.type) {
+				void *inp= in.array;
+				void *outp= out.array;
+				int a, size;
+
+				itemlen= (itemlen == 0)? 1: itemlen;
+				size= RNA_raw_type_sizeof(out.type) * itemlen;
+
+				for(a=0; a in.len) {
+						BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
+						err= 1;
+						break;
+					}
+
+					if(itemlen == 0) {
+						/* handle conversions */
+						if(set) {
+							switch(itemtype) {
+								case PROP_BOOLEAN: {
+									int b;
+									RAW_GET(int, b, in, a);
+									RNA_property_boolean_set(&itemptr, iprop, b);
+									break;
+								}
+								case PROP_INT: {
+									int i;
+									RAW_GET(int, i, in, a);
+									RNA_property_int_set(&itemptr, iprop, i);
+									break;
+								}
+								case PROP_FLOAT: {
+									float f;
+									RAW_GET(float, f, in, a);
+									RNA_property_float_set(&itemptr, iprop, f);
+									break;
+								}
+								default:
+									break;
+							}
+						}
+						else {
+							switch(itemtype) {
+								case PROP_BOOLEAN: {
+									int b= RNA_property_boolean_get(&itemptr, iprop);
+									RAW_SET(int, in, a, b);
+									break;
+								}
+								case PROP_INT: {
+									int i= RNA_property_int_get(&itemptr, iprop);
+									RAW_SET(int, in, a, i);
+									break;
+								}
+								case PROP_FLOAT: {
+									float f= RNA_property_float_get(&itemptr, iprop);
+									RAW_SET(float, in, a, f);
+									break;
+								}
+								default:
+									break;
+							}
+						}
+						a++;
+					}
+					else {
+						/* allocate temporary array if needed */
+						if(tmparray && tmplen != itemlen) {
+							MEM_freeN(tmparray);
+							tmparray= NULL;
+						}
+						if(!tmparray) {
+							tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
+							tmplen= itemlen;
+						}
+
+						/* handle conversions */
+						if(set) {
+							switch(itemtype) {
+								case PROP_BOOLEAN: {
+									for(j=0; jrawtype;
+}
+
+int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
+{
+	return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
+}
+
+int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
+{
+	return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
+}
+
 /* Standard iterator functions */
 
 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
@@ -2052,14 +2383,13 @@ int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname)
 {
 	PropertyRNA *prop= RNA_struct_find_property(ptr, name);
 	const EnumPropertyItem *item;
-	int a, totitem;
 
 	if(prop) {
-		RNA_property_enum_items(ptr, prop, &item, &totitem);
+		RNA_property_enum_items(ptr, prop, &item, NULL);
 
-		for(a=0; aidentifier; item++)
+			if(strcmp(item->identifier, enumname) == 0)
+				return (item->value == RNA_property_enum_get(ptr, prop));
 
 		printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
 		return 0;
@@ -2232,17 +2562,12 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
 	DynStr *dynstr= BLI_dynstr_new();
 	char *cstring;
 	
-	PropertyRNA *prop, *iterprop;
-	CollectionPropertyIterator iter;
 	const char *propname;
 	int first_time = 1;
 	
 	BLI_dynstr_append(dynstr, "{");
 	
-	iterprop= RNA_struct_iterator_property(ptr->type);
-
-	for(RNA_property_collection_begin(ptr, iterprop, &iter); iter.valid; RNA_property_collection_next(&iter)) {
-		prop= iter.ptr.data;
+	RNA_STRUCT_BEGIN(ptr, prop) {
 		propname = RNA_property_identifier(prop);
 		
 		if(strcmp(propname, "rna_type")==0)
@@ -2256,8 +2581,8 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
 		BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
 		MEM_freeN(cstring);
 	}
+	RNA_STRUCT_END;
 
-	RNA_property_collection_end(&iter);
 	BLI_dynstr_append(dynstr, "}");	
 	
 	
@@ -2449,6 +2774,17 @@ ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func)
 
 void RNA_parameter_list_free(ParameterList *parms)
 {
+	PropertyRNA *parm;
+	int tot;
+
+	parm= parms->func->cont.properties.first;
+	for(tot= 0; parm; parm= parm->next) {
+		if(parm->type == PROP_COLLECTION)
+			BLI_freelistN((ListBase*)((char*)parms->data+tot));
+
+		tot+= rna_parameter_size(parm);
+	}
+
 	MEM_freeN(parms->data);
 	parms->data= NULL;
 
@@ -2714,23 +3050,46 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
 
 			if(prop->flag & PROP_RNAPTR) {
 				*((PointerRNA*)dest)= *((PointerRNA*)src);
+				break;
+ 			}
+			
+			if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
+				fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
+				return -1;
 			}
-			else if (ptype!=srna) {
-				if (!RNA_struct_is_a(srna, ptype)) {
-					fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(ptype));
-					return -1;
-				}
-
-				*((void**)dest)= *((void**)src);
-			}
+ 
+			*((void**)dest)= *((void**)src);
 
 			break;
 		}
 	case PROP_COLLECTION:
 		{
-			/* XXX collections are not supported yet */
-			fprintf(stderr, "%s.%s: for parameter %s, collections are not supported yet\n", tid, fid, pid);
-			return -1;
+			StructRNA *ptype;
+			ListBase *lb, *clb;
+			Link *link;
+			CollectionPointerLink *clink;
+
+			if (ftype!='C') {
+				fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection was expected\n", tid, fid, pid);
+				return -1;
+			}
+
+			lb= (ListBase *)src;
+			clb= (ListBase *)dest;
+			ptype= RNA_property_pointer_type(ptr, prop);
+			
+			if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
+				fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection of objects of type %s was expected, passed a collection of objects of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
+				return -1;
+			}
+
+			for (link= lb->first; link; link= link->next) {
+				clink= MEM_callocN(sizeof(CollectionPointerLink), "CCollectionPointerLink");
+				RNA_pointer_create(NULL, srna, link, &clink->ptr);
+				BLI_addtail(clb, clink);
+			}
+
+			break;
 		}
 	default: 
 		{
@@ -2828,6 +3187,13 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
 				err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
 				break;
 			}
+		case PROP_COLLECTION:
+			{
+				StructRNA *srna= va_arg(args, StructRNA*);
+				ListBase *arg= va_arg(args, ListBase*);
+				err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
+				break;
+			}
 		default:
 			{
 				/* handle errors */
@@ -2885,6 +3251,13 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
 					err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
 					break;
 				}
+			case PROP_COLLECTION:
+				{
+					StructRNA *srna= va_arg(args, StructRNA*);
+					ListBase **arg= va_arg(args, ListBase**);
+					err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
+					break;
+				}			
 			default:
 				{
 					/* handle errors */
@@ -2913,3 +3286,4 @@ int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, Pointer
 	return 0;
 }
 
+
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 588c94380dc..3639d6d3fff 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_action.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 05d55d284a7..3eb88e706e9 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_actuator.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index d119783766d..2ed47effec1 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_animation.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 389257e9331..caa970eff57 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_armature.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -443,6 +443,30 @@ void rna_EditBone_tail_selected_set(PointerRNA *ptr, int value)
 	else data->flag &= ~BONE_TIPSEL;
 }
 
+static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
+{
+	ListBaseIterator *internal= iter->internal;
+	Bone *bone= (Bone*)internal->link;
+
+	if(bone->childbase.first)
+		internal->link= (Link*)bone->childbase.first;
+	else if(bone->next)
+		internal->link= (Link*)bone->next;
+	else {
+		internal->link= NULL;
+
+		do {
+			bone= bone->parent;
+			if(bone && bone->next) {
+				internal->link= (Link*)bone->next;
+				break;
+			}
+		} while(bone);
+	}
+
+	iter->valid= (internal->link != NULL);
+}
+
 #else
 
 static void rna_def_bone_common(StructRNA *srna, int editbone)
@@ -660,6 +684,7 @@ void rna_def_armature(BlenderRNA *brna)
 	/* Collections */
 	prop= RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
+	RNA_def_property_collection_funcs(prop, 0, "rna_Armature_bones_next", 0, 0, 0, 0, 0, 0, 0);
 	RNA_def_property_struct_type(prop, "Bone");
 	RNA_def_property_ui_text(prop, "Bones", "");
 
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index d3213c01846..7355261c5aa 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_brush.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -184,6 +184,10 @@ void rna_def_brush(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "space", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE);
 	RNA_def_property_ui_text(prop, "Space", "Limit brush application to the distance specified by spacing.");
+
+	prop= RNA_def_property(srna, "smooth_stroke", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SMOOTH_STROKE);
+	RNA_def_property_ui_text(prop, "Smooth Stroke", "Brush lags behind mouse and follows a smoother path.");
 	
 	/* not exposed in the interface yet
 	prop= RNA_def_property(srna, "fixed_tex", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 928086b951c..4814f9583a9 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_camera.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 7f61125bc11..cefd2316fbf 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_cloth.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,9 +34,24 @@
 #include "BKE_modifier.h"
 
 #include "DNA_cloth_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
 
 #ifdef RNA_RUNTIME
 
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+
+static void rna_cloth_update(bContext *C, PointerRNA *ptr)
+{
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = ptr->id.data;
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+
 static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value)
 {
 	ClothSimSettings *settings = (ClothSimSettings*)ptr->data;
@@ -165,42 +180,50 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 	RNA_def_property_float_sdna(prop, NULL, "mingoal");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "maxgoal");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "defgoal");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "goalspring");
 	RNA_def_property_range(prop, 0.0f, 0.999f);
 	RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "goalfrict");
 	RNA_def_property_range(prop, 0.0f, 50.0f);
 	RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* mass */
 
 	prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, 10.0f);
 	RNA_def_property_ui_text(prop, "Mass", "Mass of cloth material.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "mass_vertex_group", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_ClothSettings_mass_vgroup_get", "rna_ClothSettings_mass_vgroup_length", "rna_ClothSettings_mass_vgroup_set");
 	RNA_def_property_ui_text(prop, "Mass Vertex Group", "Vertex group for fine control over mass distribution.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_VECTOR);
 	RNA_def_property_array(prop, 3);
 	RNA_def_property_range(prop, -100.0, 100.0);
 	RNA_def_property_float_funcs(prop, "rna_ClothSettings_gravity_get", "rna_ClothSettings_gravity_set", NULL);
 	RNA_def_property_ui_text(prop, "Gravity", "Gravity or external force vector.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* various */
 
@@ -208,61 +231,73 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 	RNA_def_property_float_sdna(prop, NULL, "Cvi");
 	RNA_def_property_range(prop, 0.0f, 10.0f);
 	RNA_def_property_ui_text(prop, "Air Damping", "Air has normally some thickness which slows falling things down.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "pin_cloth", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL);
 	RNA_def_property_ui_text(prop, "Pin Cloth", "Define forces for vertices to stick to animated position.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "pin_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "goalspring");
 	RNA_def_property_range(prop, 0.0f, 50.0);
 	RNA_def_property_ui_text(prop, "Pin Stiffness", "Pin (vertex target position) spring stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "quality", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "stepsPerFrame");
 	RNA_def_property_range(prop, 4, 80);
 	RNA_def_property_ui_text(prop, "Quality", "Quality of the simulation in steps per frame (higher is better quality but slower).");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* springs */
 
 	prop= RNA_def_property(srna, "stiffness_scaling", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_SCALING);
 	RNA_def_property_ui_text(prop, "Stiffness Scaling", "If enabled, stiffness can be scaled along a weight painted vertex group.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "Cdis");
 	RNA_def_property_range(prop, 0.0f, 50.0f);
 	RNA_def_property_ui_text(prop, "Spring Damping", "Damping of cloth velocity (higher = more smooth, less jiggling)");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "structural_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "structural");
 	RNA_def_property_range(prop, 1.0f, 10000.0f);
 	RNA_def_property_ui_text(prop, "Structural Stiffness", "Overall stiffness of structure.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "structural_stiffness_max", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "max_struct");
 	RNA_def_property_range(prop, 0.0f, 10000.0f);
 	RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_struct_set", NULL);
 	RNA_def_property_ui_text(prop, "Structural Stiffness Maximum", "Maximum structural stiffness value.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "structural_stiffness_vertex_group", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_ClothSettings_struct_vgroup_get", "rna_ClothSettings_struct_vgroup_length", "rna_ClothSettings_struct_vgroup_set");
 	RNA_def_property_ui_text(prop, "Structural Stiffness Vertex Group", "Vertex group for fine control over structural stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "bending_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "bending");
 	RNA_def_property_range(prop, 0.0f, 10000.0f);
 	RNA_def_property_ui_text(prop, "Bending Stiffness", "Wrinkle coefficient (higher = less smaller but more big wrinkles).");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "bending_stiffness_max", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "max_bend");
 	RNA_def_property_range(prop, 0.0f, 10000.0f);
 	RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_bend_set", NULL);
 	RNA_def_property_ui_text(prop, "Bending Stiffness Maximum", "Maximum bending stiffness value.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "bending_vertex_group", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_ClothSettings_bend_vgroup_get", "rna_ClothSettings_bend_vgroup_length", "rna_ClothSettings_bend_vgroup_set");
 	RNA_def_property_ui_text(prop, "Bending Stiffness Vertex Group", "Vertex group for fine control over bending stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* unused */
 
@@ -323,40 +358,48 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "enable_collision", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_ENABLED);
 	RNA_def_property_ui_text(prop, "Enable Collision", "Enable collisions with other objects.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "min_distance", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "epsilon");
 	RNA_def_property_range(prop, 0.001f, 1.0f);
 	RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance between collision objects before collision response takes in, can be changed for each frame.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, 80.0f);
 	RNA_def_property_ui_text(prop, "Friction", "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "collision_quality", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "loop_count");
 	RNA_def_property_range(prop, 1, 20);
 	RNA_def_property_ui_text(prop, "Collision Quality", "How many collision iterations should be done. (higher is better quality but slower)");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* self collision */
 
 	prop= RNA_def_property(srna, "enable_self_collision", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_SELF);
 	RNA_def_property_ui_text(prop, "Enable Self Collision", "Enable self collisions.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "self_min_distance", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "selfepsilon");
 	RNA_def_property_range(prop, 0.5f, 1.0f);
 	RNA_def_property_ui_text(prop, "Self Minimum Distance", "0.5 means no distance at all, 1.0 is maximum distance");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "self_friction", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, 80.0f);
 	RNA_def_property_ui_text(prop, "Self Friction", "Friction/damping with self contact.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "self_collision_quality", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "self_loop_count");
 	RNA_def_property_range(prop, 1, 10);
 	RNA_def_property_ui_text(prop, "Self Collision Quality", "How many self collision iterations should be done. (higher is better quality but slower), can be changed for each frame.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 }
 
 void RNA_def_cloth(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index c1464ec87f2..179808ab66d 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_color.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index ec1676eea95..5c4b6a95524 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_constraint.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -534,6 +534,12 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
 
 	srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint");
 	RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target.");
+
+	prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
+	RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
+	RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
 	RNA_def_struct_sdna_from(srna, "bLocateLikeConstraint", "data");
 
 	prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
@@ -582,13 +588,6 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_OFFSET);
 	RNA_def_property_ui_text(prop, "Offset", "Add original location into copied location.");
 	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
-	RNA_def_struct_sdna(srna, "bConstraint");
-
-	prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
-	RNA_def_property_float_sdna(prop, NULL, "headtail");
-	RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
-	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 }
 
 static void rna_def_constraint_minmax(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index 7624d4a1144..7fa27348002 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_context.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -40,11 +40,11 @@ static PointerRNA rna_Context_manager_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_WindowManager, CTX_wm_manager(C));
 }
 
-/*static PointerRNA rna_Context_window_get(PointerRNA *ptr)
+static PointerRNA rna_Context_window_get(PointerRNA *ptr)
 {
 	bContext *C= (bContext*)ptr->data;
 	return rna_pointer_inherit_refine(ptr, &RNA_Window, CTX_wm_window(C));
-}*/
+}
 
 static PointerRNA rna_Context_screen_get(PointerRNA *ptr)
 {
@@ -96,6 +96,12 @@ static PointerRNA rna_Context_scene_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_Scene, CTX_data_scene(C));
 }
 
+static PointerRNA rna_Context_tool_settings_get(PointerRNA *ptr)
+{
+	bContext *C= (bContext*)ptr->data;
+	return rna_pointer_inherit_refine(ptr, &RNA_ToolSettings, CTX_data_tool_settings(C));
+}
+
 #else
 
 void RNA_def_context(BlenderRNA *brna)
@@ -113,10 +119,10 @@ void RNA_def_context(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "WindowManager");
 	RNA_def_property_pointer_funcs(prop, "rna_Context_manager_get", NULL, NULL);
 
-	/* prop= RNA_def_property(srna, "window", PROP_POINTER, PROP_NONE);
+	prop= RNA_def_property(srna, "window", PROP_POINTER, PROP_NONE);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_struct_type(prop, "Window");
-	RNA_def_property_pointer_funcs(prop, "rna_Context_window_get", NULL, NULL); */
+	RNA_def_property_pointer_funcs(prop, "rna_Context_window_get", NULL, NULL);
 
 	prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NONE);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -153,6 +159,12 @@ void RNA_def_context(BlenderRNA *brna)
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_struct_type(prop, "Scene");
 	RNA_def_property_pointer_funcs(prop, "rna_Context_scene_get", NULL, NULL);
+
+	prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_struct_type(prop, "ToolSettings");
+	RNA_def_property_pointer_funcs(prop, "rna_Context_tool_settings_get", NULL, NULL);
+
 }
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index 47399090b4e..4d5ef7aa123 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_controller.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index c592625c7dc..41a47e279e9 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_curve.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 98a2ae8b32d..715f03bb3f1 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_define.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -112,7 +112,7 @@ StructDefRNA *rna_find_struct_def(StructRNA *srna)
 	return NULL;
 }
 
-PropertyDefRNA *rna_find_struct_property_def(PropertyRNA *prop)
+PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
 {
 	StructDefRNA *dsrna;
 	PropertyDefRNA *dprop;
@@ -123,7 +123,7 @@ PropertyDefRNA *rna_find_struct_property_def(PropertyRNA *prop)
 		return NULL;
 	}
 
-	dsrna= rna_find_struct_def(DefRNA.laststruct);
+	dsrna= rna_find_struct_def(srna);
 	dprop= dsrna->cont.properties.last;
 	for (; dprop; dprop= dprop->prev)
 		if (dprop->prop==prop)
@@ -150,7 +150,7 @@ PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
 		return NULL;
 	}
 
-	dprop= rna_find_struct_property_def(prop);
+	dprop= rna_find_struct_property_def(DefRNA.laststruct, prop);
 	if (dprop)
 		return dprop;
 
@@ -1311,7 +1311,7 @@ static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *stru
 	StructDefRNA *ds;
 	PropertyDefRNA *dp;
 
-	dp= rna_find_struct_property_def(prop);
+	dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
 	if (dp==NULL) return NULL;
 
 	ds= rna_find_struct_def((StructRNA*)dp->cont);
@@ -1371,7 +1371,7 @@ void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *struc
 
 	RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
 
-	dp= rna_find_struct_property_def(prop);
+	dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
 
 	if(dp)
 		dp->booleannegative= 1;
@@ -1468,7 +1468,7 @@ void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structnam
 
 	RNA_def_property_enum_sdna(prop, structname, propname);
 
-	dp= rna_find_struct_property_def(prop);
+	dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
 
 	if(dp)
 		dp->enumbitflags= 1;
@@ -1946,7 +1946,7 @@ PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *ide
 	return prop;
 }
 
-PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, EnumPropertyItem *items, int default_value, 
+PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, 
 	const char *ui_name, const char *ui_description)
 {
 	ContainerRNA *cont= cont_;
@@ -2249,7 +2249,6 @@ int rna_parameter_size(PropertyRNA *parm)
 #endif
 			}
 			case PROP_COLLECTION:
-				/* XXX does not work yet */
 				return sizeof(ListBase);
 		}
 	}
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 70e511de323..806219ec6bf 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_fcurve.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index ac51aa6d0d7..4e047ff7772 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_fluidsim.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 82bdd66802a..1406ad1ae60 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_group.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 7c8b0c3bf8e..c74e46c17da 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_image.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -35,8 +35,12 @@
 #include "BKE_context.h"
 #include "BKE_image.h"
 
+#include "WM_types.h"
+
 #ifdef RNA_RUNTIME
 
+#include "IMB_imbuf_types.h"
+
 static void rna_Image_animated_update(bContext *C, PointerRNA *ptr)
 {
 	Image *ima= (Image*)ptr->data;
@@ -50,6 +54,18 @@ static void rna_Image_animated_update(bContext *C, PointerRNA *ptr)
 	}
 }
 
+static int rna_Image_dirty_get(PointerRNA *ptr)
+{
+	Image *ima= (Image*)ptr->data;
+	ImBuf *ibuf;
+
+	for(ibuf=ima->ibufs.first; ibuf; ibuf=ibuf->next)
+		if(ibuf->userflags & IB_BITMAPDIRTY)
+			return 1;
+	
+	return 0;
+}
+
 #else
 
 static void rna_def_imageuser(BlenderRNA *brna)
@@ -133,16 +149,19 @@ static void rna_def_image(BlenderRNA *brna)
 	RNA_def_property_string_sdna(prop, NULL, "name");
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
 	RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_items(prop, prop_source_items);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
 	RNA_def_property_ui_text(prop, "Source", "Where the image comes from.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_items(prop, prop_type_items);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
 	RNA_def_property_ui_text(prop, "Type", "How to generate the image.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
@@ -152,90 +171,110 @@ static void rna_def_image(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "fields", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS);
 	RNA_def_property_ui_text(prop, "Fields", "Use fields of the image.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "odd_fields", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_STD_FIELD);
 	RNA_def_property_ui_text(prop, "Odd Fields", "Standard field toggle.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "antialias", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANTIALI);
 	RNA_def_property_ui_text(prop, "Anti-alias", "Toggles image anti-aliasing, only works with solid colors");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "premultiply", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DO_PREMUL);
 	RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+
+	prop= RNA_def_property(srna, "dirty", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Dirty", "Image has changed and is not saved.");
 
 	/* generated image (image_generated_change_cb) */
 	prop= RNA_def_property(srna, "generated_type", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "gen_type");
 	RNA_def_property_enum_items(prop, prop_generated_type_items);
 	RNA_def_property_ui_text(prop, "Generated Type", "Generated image type.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "gen_x");
 	RNA_def_property_range(prop, 1, 16384);
 	RNA_def_property_ui_text(prop, "Generated Width", "Generated image width.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "generated_height", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "gen_y");
 	RNA_def_property_range(prop, 1, 16384);
 	RNA_def_property_ui_text(prop, "Generated Height", "Generated image height.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	/* realtime properties */
 	prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
 	RNA_def_property_enum_items(prop, prop_mapping_items);
 	RNA_def_property_ui_text(prop, "Mapping", "Mapping type to use for this image in the game engine.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "display_aspect", PROP_FLOAT, PROP_VECTOR);
 	RNA_def_property_float_sdna(prop, NULL, "aspx");
 	RNA_def_property_array(prop, 2);
 	RNA_def_property_range(prop, 0.1f, 5000.0f);
 	RNA_def_property_ui_text(prop, "Display Aspect", "Display Aspect for this image, does not affect rendering.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "animated", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_TWINANIM);
 	RNA_def_property_ui_text(prop, "Animated", "Use as animated texture in the game engine.");
-	RNA_def_property_update(prop, 0, "rna_Image_animated_update");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_animated_update");
 
 	prop= RNA_def_property(srna, "animation_start", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "twsta");
 	RNA_def_property_range(prop, 0, 128);
 	RNA_def_property_ui_text(prop, "Animation Start", "Start frame of an animated texture.");
-	RNA_def_property_update(prop, 0, "rna_Image_animated_update");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_animated_update");
 
 	prop= RNA_def_property(srna, "animation_end", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "twend");
 	RNA_def_property_range(prop, 0, 128);
 	RNA_def_property_ui_text(prop, "Animation End", "End frame of an animated texture.");
-	RNA_def_property_update(prop, 0, "rna_Image_animated_update");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_animated_update");
 
 	prop= RNA_def_property(srna, "animation_speed", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "animspeed");
 	RNA_def_property_range(prop, 1, 100);
 	RNA_def_property_ui_text(prop, "Animation Speed", "Speed of the animation in frames per second.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "tiles", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_TILES);
 	RNA_def_property_ui_text(prop, "Tiles", "Use of tilemode for faces (default shift-LMB to pick the tile for selected faces).");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "tiles_x", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "xrep");
 	RNA_def_property_range(prop, 1, 16);
 	RNA_def_property_ui_text(prop, "Tiles X", "Degree of repetition in the X direction.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "tiles_y", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "yrep");
 	RNA_def_property_range(prop, 1, 16);
 	RNA_def_property_ui_text(prop, "Tiles Y", "Degree of repetition in the Y direction.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "clamp_x", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_U);
 	RNA_def_property_ui_text(prop, "Clamp X", "Disable texture repeating horizontally.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "clamp_y", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_V);
 	RNA_def_property_ui_text(prop, "Clamp Y", "Disable texture repeating vertically.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 }
 
 void RNA_def_image(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index a41f522bb0f..3d66682771d 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_internal.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -145,7 +145,6 @@ void RNA_def_object_force(struct BlenderRNA *brna);
 void RNA_def_packedfile(struct BlenderRNA *brna);
 void RNA_def_particle(struct BlenderRNA *brna);
 void RNA_def_pose(struct BlenderRNA *brna);
-void RNA_def_radio(struct BlenderRNA *brna);
 void RNA_def_rna(struct BlenderRNA *brna);
 void RNA_def_scene(struct BlenderRNA *brna);
 void RNA_def_screen(struct BlenderRNA *brna);
@@ -256,6 +255,7 @@ void rna_freelistN(struct ListBase *listbase);
 StructDefRNA *rna_find_struct_def(StructRNA *srna);
 FunctionDefRNA *rna_find_function_def(FunctionRNA *func);
 PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm);
+PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop);
 
 /* Pointer Handling */
 
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 3cf250151c7..401b430ebc9 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_internal_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -146,6 +146,10 @@ struct PropertyRNA {
 
 	/* callback for testing if editable/evaluated */
 	EditableFunc editable;
+
+	/* raw access */
+	int rawoffset;
+	RawPropertyType rawtype;
 };
 
 /* Property Types */
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index b97dd95c4d4..71e424bbd69 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_key.c 19382 2009-03-23 13:24:48Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index c6cf2b0a410..a49b4377d9d 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_lamp.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -253,11 +253,11 @@ static void rna_def_lamp(BlenderRNA *brna)
 	PropertyRNA *prop;
 
 	static EnumPropertyItem prop_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}};
 
 	srna= RNA_def_struct(brna, "Lamp", "ID");
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index 3af448b0233..f67267ce0d0 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_lattice.c 19382 2009-03-23 13:24:48Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 6b1ce8c02ae..26fc3c2941e 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_main.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -264,7 +264,7 @@ void RNA_def_main(BlenderRNA *brna)
 	{
 		prop= RNA_def_property(srna, lists[i][0], PROP_COLLECTION, PROP_NONE);
 		RNA_def_property_struct_type(prop, lists[i][1]);
-		RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, "add_mesh", "remove_mesh");
+		RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0, 0);
 		RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]);
 	}
 
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 2d699b6b229..6d56b2b00f9 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_main_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 66e30f7ee50..41f31594f6e 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_material.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 25b8739e074..39fa6f36f23 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_mesh.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,10 +34,37 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
-#include "BKE_customdata.h"
-
 #ifdef RNA_RUNTIME
 
+#include "DNA_scene_types.h"
+
+#include "BLI_editVert.h"
+
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_utildefines.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+static void rna_Mesh_update_data(bContext *C, PointerRNA *ptr)
+{
+	Main *bmain= CTX_data_main(C);
+	Scene *scene= CTX_data_scene(C);
+	ID *id= ptr->id.data;
+	Object *ob;
+
+	for(ob=bmain->object.first; ob; ob= ob->id.next) {
+		if(ob->data == id) {
+			/* XXX this will loop over all objects again (slow) */
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+		}
+	}
+}
+
 static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
 {
 	MVert *mvert= (MVert*)ptr->data;
@@ -183,13 +210,19 @@ static void rna_MeshFace_material_index_range(PointerRNA *ptr, int *min, int *ma
 	*max= me->totcol-1;
 }
 
+static CustomData *rna_mesh_fdata(Mesh *me)
+{
+	return (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
+}
+
 static int rna_CustomDataLayer_length(PointerRNA *ptr, int type)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
+	CustomData *fdata= rna_mesh_fdata(me);
 	CustomDataLayer *layer;
 	int i, length= 0;
 
-	for(layer=me->fdata.layers, i=0; ifdata.totlayer; layer++, i++)
+	for(layer=fdata->layers, i=0; itotlayer; layer++, i++)
 		if(layer->type == type)
 			length++;
 
@@ -199,41 +232,96 @@ static int rna_CustomDataLayer_length(PointerRNA *ptr, int type)
 static int rna_CustomDataLayer_active_get(PointerRNA *ptr, int type, int render)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
-	int n= ((CustomDataLayer*)ptr->data) - me->fdata.layers;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int n= ((CustomDataLayer*)ptr->data) - fdata->layers;
 
-	if(render) return (n == CustomData_get_render_layer_index(&me->fdata, type));
-	else return (n == CustomData_get_active_layer_index(&me->fdata, type));
+	if(render) return (n == CustomData_get_render_layer_index(fdata, type));
+	else return (n == CustomData_get_active_layer_index(fdata, type));
 }
 
 static void rna_CustomDataLayer_active_set(PointerRNA *ptr, int value, int type, int render)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
-	int n= ((CustomDataLayer*)ptr->data) - me->fdata.layers;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int n= ((CustomDataLayer*)ptr->data) - fdata->layers;
 
 	if(value == 0)
 		return;
 
-	if(render) CustomData_set_layer_render_index(&me->fdata, type, n);
-	else CustomData_set_layer_active_index(&me->fdata, type, n);
+	if(render) CustomData_set_layer_render_index(fdata, type, n);
+	else CustomData_set_layer_active_index(fdata, type, n);
 }
 
-static int rna_uv_layer_check(CollectionPropertyIterator *iter, void *data)
+static int rna_uv_texture_check(CollectionPropertyIterator *iter, void *data)
 {
 	CustomDataLayer *layer= (CustomDataLayer*)data;
 	return (layer->type != CD_MTFACE);
 }
 
-static void rna_Mesh_uv_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+static void rna_Mesh_uv_textures_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_uv_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_uv_texture_check);
 }
 
-static int rna_Mesh_uv_layers_length(PointerRNA *ptr)
+static int rna_Mesh_uv_textures_length(PointerRNA *ptr)
 {
 	return rna_CustomDataLayer_length(ptr, CD_MTFACE);
 }
 
+static PointerRNA rna_Mesh_active_uv_texture_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int index= CustomData_get_active_layer_index(fdata, CD_MTFACE);
+	CustomDataLayer *cdl= (index == -1)? NULL: &fdata->layers[index];
+
+	return rna_pointer_inherit_refine(ptr, &RNA_MeshTextureFaceLayer, cdl);
+}
+
+static void rna_Mesh_active_uv_texture_set(PointerRNA *ptr, PointerRNA value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	CustomDataLayer *cdl;
+	int a;
+
+	for(cdl=fdata->layers, a=0; atotlayer; cdl++, a++) {
+		if(value.data == cdl) {
+			CustomData_set_layer_active_index(fdata, CD_MTFACE, a);
+			mesh_update_customdata_pointers(me);
+			return;
+		}
+	}
+}
+
+static int rna_Mesh_active_uv_texture_index_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	return CustomData_get_active_layer(fdata, CD_MTFACE);
+}
+
+static void rna_Mesh_active_uv_texture_index_set(PointerRNA *ptr, int value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	CustomData_set_layer_active(fdata, CD_MTFACE, value);
+	mesh_update_customdata_pointers(me);
+}
+
+static void rna_Mesh_active_uv_texture_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	*min= 0;
+	*max= CustomData_number_of_layers(fdata, CD_MTFACE)-1;
+	*max= MAX2(0, *max);
+}
+
 static void rna_MeshTextureFace_uv1_get(PointerRNA *ptr, float *values)
 {
 	MTFace *mtface= (MTFace*)ptr->data;
@@ -331,23 +419,84 @@ static void rna_MeshTextureFaceLayer_active_set(PointerRNA *ptr, int value)
 	rna_CustomDataLayer_active_set(ptr, value, CD_MTFACE, 0);
 }
 
-static int rna_vcol_layer_check(CollectionPropertyIterator *iter, void *data)
+static void rna_MeshTextureFaceLayer_name_set(PointerRNA *ptr, const char *value)
+{
+	Mesh *me= (Mesh*)ptr->id.data;
+	CustomDataLayer *cdl= (CustomDataLayer*)ptr->data;
+	BLI_strncpy(cdl->name, value, sizeof(cdl->name));
+	CustomData_set_layer_unique_name(&me->fdata, cdl - me->fdata.layers);
+}
+
+static int rna_vertex_color_check(CollectionPropertyIterator *iter, void *data)
 {
 	CustomDataLayer *layer= (CustomDataLayer*)data;
 	return (layer->type != CD_MCOL);
 }
 
-static void rna_Mesh_vcol_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+static void rna_Mesh_vertex_colors_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_vcol_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_vertex_color_check);
 }
 
-static int rna_Mesh_vcol_layers_length(PointerRNA *ptr)
+static int rna_Mesh_vertex_colors_length(PointerRNA *ptr)
 {
 	return rna_CustomDataLayer_length(ptr, CD_MCOL);
 }
 
+static PointerRNA rna_Mesh_active_vertex_color_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int index= CustomData_get_active_layer_index(fdata, CD_MCOL);
+	CustomDataLayer *cdl= (index == -1)? NULL: &fdata->layers[index];
+
+	return rna_pointer_inherit_refine(ptr, &RNA_MeshColorLayer, cdl);
+}
+
+static void rna_Mesh_active_vertex_color_set(PointerRNA *ptr, PointerRNA value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	CustomDataLayer *cdl;
+	int a;
+
+	for(cdl=fdata->layers, a=0; atotlayer; cdl++, a++) {
+		if(value.data == cdl) {
+			CustomData_set_layer_active_index(fdata, CD_MCOL, a);
+			mesh_update_customdata_pointers(me);
+			return;
+		}
+	}
+}
+
+static int rna_Mesh_active_vertex_color_index_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	return CustomData_get_active_layer(fdata, CD_MCOL);
+}
+
+static void rna_Mesh_active_vertex_color_index_set(PointerRNA *ptr, int value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	CustomData_set_layer_active(fdata, CD_MCOL, value);
+	mesh_update_customdata_pointers(me);
+}
+
+static void rna_Mesh_active_vertex_color_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	*min= 0;
+	*max= CustomData_number_of_layers(fdata, CD_MCOL)-1;
+	*max= MAX2(0, *max);
+}
+
 static void rna_MeshColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
@@ -381,6 +530,14 @@ static void rna_MeshColorLayer_active_set(PointerRNA *ptr, int value)
 	rna_CustomDataLayer_active_set(ptr, value, CD_MCOL, 0);
 }
 
+static void rna_MeshColorLayer_name_set(PointerRNA *ptr, const char *value)
+{
+	Mesh *me= (Mesh*)ptr->id.data;
+	CustomDataLayer *cdl= (CustomDataLayer*)ptr->data;
+	BLI_strncpy(cdl->name, value, sizeof(cdl->name));
+	CustomData_set_layer_unique_name(&me->fdata, cdl - me->fdata.layers);
+}
+
 static void rna_MeshFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
@@ -403,7 +560,8 @@ static int rna_float_layer_check(CollectionPropertyIterator *iter, void *data)
 static void rna_Mesh_float_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_float_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_float_layer_check);
 }
 
 static int rna_Mesh_float_layers_length(PointerRNA *ptr)
@@ -433,7 +591,8 @@ static int rna_MeshIntPropertyLayer_data_length(PointerRNA *ptr)
 static void rna_Mesh_int_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_int_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_int_layer_check);
 }
 
 static int rna_Mesh_int_layers_length(PointerRNA *ptr)
@@ -463,7 +622,8 @@ static int rna_MeshStringPropertyLayer_data_length(PointerRNA *ptr)
 static void rna_Mesh_string_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_string_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_string_layer_check);
 }
 
 static int rna_Mesh_string_layers_length(PointerRNA *ptr)
@@ -522,17 +682,18 @@ static char *rna_MeshVertex_path(PointerRNA *ptr)
 
 static char *rna_MeshTextureFaceLayer_path(PointerRNA *ptr)
 {
-	return BLI_sprintfN("uv_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+	return BLI_sprintfN("uv_textures[%s]", ((CustomDataLayer*)ptr->data)->name);
 }
 
 static char *rna_CustomDataData_path(PointerRNA *ptr, char *collection, int type)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
+	CustomData *fdata= rna_mesh_fdata(me);
 	CustomDataLayer *cdl;
 	int a;
 	size_t b;
 
-	for(cdl=me->fdata.layers, a=0; afdata.totlayer; cdl++, a++) {
+	for(cdl=fdata->layers, a=0; atotlayer; cdl++, a++) {
 		if(cdl->type == type) {
 			b= ((char*)ptr->data - ((char*)cdl->data))/CustomData_sizeof(type);
 			if(b >= 0 && b < me->totface)
@@ -545,17 +706,17 @@ static char *rna_CustomDataData_path(PointerRNA *ptr, char *collection, int type
 
 static char *rna_MeshTextureFace_path(PointerRNA *ptr)
 {
-	return rna_CustomDataData_path(ptr, "uv_layers", CD_MTFACE);
+	return rna_CustomDataData_path(ptr, "uv_textures", CD_MTFACE);
 }
 
 static char *rna_MeshColorLayer_path(PointerRNA *ptr)
 {
-	return BLI_sprintfN("vcol_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+	return BLI_sprintfN("vertex_colors[%s]", ((CustomDataLayer*)ptr->data)->name);
 }
 
 static char *rna_MeshColor_path(PointerRNA *ptr)
 {
-	return rna_CustomDataData_path(ptr, "vcol_layers", CD_MCOL);
+	return rna_CustomDataData_path(ptr, "vertex_colors", CD_MCOL);
 }
 
 static char *rna_MeshSticky_path(PointerRNA *ptr)
@@ -670,8 +831,8 @@ static void rna_def_medge(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "v1");
 	RNA_def_property_array(prop, 2);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
+	// XXX allows creating invalid meshes
 
 	prop= RNA_def_property(srna, "crease", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_funcs(prop, "rna_MEdge_crease_get", "rna_MEdge_crease_set", NULL);
@@ -712,8 +873,8 @@ static void rna_def_mface(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "v1");
 	RNA_def_property_array(prop, 4);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
+	// XXX allows creating invalid meshes
 
 	prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "mat_nr");
@@ -752,6 +913,7 @@ static void rna_def_mtface(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshTextureFaceLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "");
 
 	prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
@@ -889,6 +1051,7 @@ static void rna_def_mcol(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshColorLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "");
 
 	prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
@@ -1058,7 +1221,6 @@ static void rna_def_mesh(BlenderRNA *brna)
 	RNA_def_property_collection_sdna(prop, NULL, "mvert", "totvert");
 	RNA_def_property_struct_type(prop, "MeshVertex");
 	RNA_def_property_ui_text(prop, "Vertices", "Vertices of the mesh.");
-	// XXX RNA_def_property_collection_funcs(prop, "rna_Mesh_verts_begin", 0, 0, 0, 0, 0, 0, "add_verts", "remove_verts");
 
 	prop= RNA_def_property(srna, "edges", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "medge", "totedge");
@@ -1075,17 +1237,45 @@ static void rna_def_mesh(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "MeshSticky");
 	RNA_def_property_ui_text(prop, "Sticky", "Sticky texture coordinates.");
 
-	prop= RNA_def_property(srna, "uv_layers", PROP_COLLECTION, PROP_NONE);
+	/* UV textures */
+
+	prop= RNA_def_property(srna, "uv_textures", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
-	RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_layers_begin", 0, 0, 0, "rna_Mesh_uv_layers_length", 0, 0, 0, 0);
+	RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_textures_begin", 0, 0, 0, "rna_Mesh_uv_textures_length", 0, 0, 0, 0);
+	RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
+	RNA_def_property_ui_text(prop, "UV Textures", "");
+
+	prop= RNA_def_property(srna, "active_uv_texture", PROP_POINTER, PROP_UNSIGNED);
 	RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
-	RNA_def_property_ui_text(prop, "UV Layers", "");
+	RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_uv_texture_get", "rna_Mesh_active_uv_texture_set", NULL);
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Active UV Texture", "Active UV texture.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+	prop= RNA_def_property(srna, "active_uv_texture_index", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_funcs(prop, "rna_Mesh_active_uv_texture_index_get", "rna_Mesh_active_uv_texture_index_set", "rna_Mesh_active_uv_texture_index_range");
+	RNA_def_property_ui_text(prop, "Active UV Texture Index", "Active UV texture index.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 
-	prop= RNA_def_property(srna, "vcol_layers", PROP_COLLECTION, PROP_NONE);
+	/* Vertex colors */
+
+	prop= RNA_def_property(srna, "vertex_colors", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
-	RNA_def_property_collection_funcs(prop, "rna_Mesh_vcol_layers_begin", 0, 0, 0, "rna_Mesh_vcol_layers_length", 0, 0, 0, 0);
+	RNA_def_property_collection_funcs(prop, "rna_Mesh_vertex_colors_begin", 0, 0, 0, "rna_Mesh_vertex_colors_length", 0, 0, 0, 0);
+	RNA_def_property_struct_type(prop, "MeshColorLayer");
+	RNA_def_property_ui_text(prop, "Vertex Colors", "");
+
+	prop= RNA_def_property(srna, "active_vertex_color", PROP_POINTER, PROP_UNSIGNED);
 	RNA_def_property_struct_type(prop, "MeshColorLayer");
-	RNA_def_property_ui_text(prop, "Vertex Color Layers", "");
+	RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_vertex_color_get", "rna_Mesh_active_vertex_color_set", NULL);
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+	prop= RNA_def_property(srna, "active_vertex_color_index", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_funcs(prop, "rna_Mesh_active_vertex_color_index_get", "rna_Mesh_active_vertex_color_index_set", "rna_Mesh_active_vertex_color_index_range");
+	RNA_def_property_ui_text(prop, "Active Vertex Color Index", "Active vertex color index.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 
 	prop= RNA_def_property(srna, "float_layers", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
@@ -1121,6 +1311,7 @@ static void rna_def_mesh(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "double_sided", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_TWOSIDED);
 	RNA_def_property_ui_text(prop, "Double Sided", "Render/display the mesh with double or single sided lighting");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 
 	prop= RNA_def_property(srna, "texco_mesh", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "texcomesh");
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 02c079920ea..c98b3fb7b09 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_mesh_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,74 +34,207 @@
 
 #ifdef RNA_RUNTIME
 
+#include "DNA_mesh_types.h"
+#include "DNA_scene_types.h"
+
 #include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
 
-#include "DNA_mesh_types.h"
-#include "DNA_scene_types.h"
+#include "BLI_edgehash.h"
 
-/*
-void rna_Mesh_copy(Mesh *me, Mesh *from)
+#include "WM_api.h"
+#include "WM_types.h"
+
+static void rna_Mesh_calc_edges(Mesh *mesh)
 {
-	copy_mesh_data(me, from);
+	CustomData edata;
+	EdgeHashIterator *ehi;
+	MFace *mf = mesh->mface;
+	MEdge *med;
+	EdgeHash *eh = BLI_edgehash_new();
+	int i, *index, totedge, totface = mesh->totface;
+
+	for (i = 0; i < totface; i++, mf++) {
+		if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
+			BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
+		if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
+			BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
+		
+		if (mf->v4) {
+			if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
+				BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
+			if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
+				BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
+		} else {
+			if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
+				BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+		}
+	}
+
+	totedge = BLI_edgehash_size(eh);
+
+	/* write new edges into a temporary CustomData */
+	memset(&edata, 0, sizeof(edata));
+	CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+
+	ehi = BLI_edgehashIterator_new(eh);
+	med = CustomData_get_layer(&edata, CD_MEDGE);
+	for(i = 0; !BLI_edgehashIterator_isDone(ehi);
+	    BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
+		BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
+
+		med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+	}
+	BLI_edgehashIterator_free(ehi);
+
+	/* free old CustomData and assign new one */
+	CustomData_free(&mesh->edata, mesh->totedge);
+	mesh->edata = edata;
+	mesh->totedge = totedge;
+
+	mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
+
+	BLI_edgehash_free(eh, NULL);
 }
 
-void rna_Mesh_copy_applied(Mesh *me, Scene *sce, Object *ob)
+static void rna_Mesh_update(Mesh *mesh, bContext *C)
 {
-	DerivedMesh *dm= mesh_create_derived_view(sce, ob, CD_MASK_MESH);
-	DM_to_mesh(dm, me);
-	dm->release(dm);
+	Main *bmain= CTX_data_main(C);
+	Object *ob;
+
+	if(mesh->totface && mesh->totedge == 0)
+		rna_Mesh_calc_edges(mesh);
+
+	mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
+
+	for(ob=bmain->object.first; ob; ob=ob->id.next) {
+		if(ob->data == mesh) {
+			ob->recalc |= OB_RECALC_DATA;
+			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+		}
+	}
 }
-*/
 
-void rna_Mesh_transform(Mesh *me, float **mat)
+static void rna_Mesh_add_verts(Mesh *mesh, int len)
 {
+	CustomData vdata;
+	MVert *mvert;
+	int i, totvert;
+
+	if(len == 0)
+		return;
+
+	totvert= mesh->totvert + len;
+	CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
+	CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
+
+	if(!CustomData_has_layer(&vdata, CD_MVERT))
+		CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
+
+	CustomData_free(&mesh->vdata, mesh->totvert);
+	mesh->vdata= vdata;
+	mesh_update_customdata_pointers(mesh);
+
+	/* scan the input list and insert the new vertices */
+
+	mvert= &mesh->mvert[mesh->totvert];
+	for(i=0; iflag |= SELECT;
+
+	/* set final vertex list size */
+	mesh->totvert= totvert;
 }
 
-#if 0
-/* extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); */
+static void rna_Mesh_add_edges(Mesh *mesh, int len)
+{
+	CustomData edata;
+	MEdge *medge;
+	int i, totedge;
+
+	if(len == 0)
+		return;
+
+	totedge= mesh->totedge+len;
+
+	/* update customdata  */
+	CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
+	CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
 
-static void rna_Mesh_verts_add(PointerRNA *ptr, PointerRNA *ptr_item)
+	if(!CustomData_has_layer(&edata, CD_MEDGE))
+		CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+
+	CustomData_free(&mesh->edata, mesh->totedge);
+	mesh->edata= edata;
+	mesh_update_customdata_pointers(mesh);
+
+	/* set default flags */
+	medge= &mesh->medge[mesh->totedge];
+	for(i=0; iflag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
+
+	mesh->totedge= totedge;
+}
+
+static void rna_Mesh_add_faces(Mesh *mesh, int len)
 {
-	//Mesh *me= (Mesh*)ptr->data;
+	CustomData fdata;
+	MFace *mface;
+	int i, totface;
 
-	/*
-	// XXX if item is not MVert we fail silently
-	if (item->type == RNA_MeshVertex)
+	if(len == 0)
 		return;
 
-	// XXX this must be slow...
-	EditMesh *em= BKE_mesh_get_editmesh(me);
+	totface= mesh->totface + len;	/* new face count */
+
+	/* update customdata */
+	CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
+	CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
+
+	if(!CustomData_has_layer(&fdata, CD_MFACE))
+		CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
+
+	CustomData_free(&mesh->fdata, mesh->totface);
+	mesh->fdata= fdata;
+	mesh_update_customdata_pointers(mesh);
 
-	MVert *v = (MVert*)ptr_item->ptr->data;
-	addvertlist(em, v->co, NULL);
+	/* set default flags */
+	mface= &mesh->mface[mesh->totface];
+	for(i=0; iflag= SELECT;
 
-	BKE_mesh_end_editmesh(me, em);
-	*/
+	mesh->totface= totface;
+}
+
+static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces)
+{
+	if(verts)
+		rna_Mesh_add_verts(mesh, verts);
+	if(edges)
+		rna_Mesh_add_edges(mesh, edges);
+	if(faces)
+		rna_Mesh_add_faces(mesh, faces);
 }
-#endif
 
 #else
 
 void RNA_api_mesh(StructRNA *srna)
 {
-	/*FunctionRNA *func;
-	PropertyRNA *prop;*/
-
-	/*
-	func= RNA_def_function(srna, "copy", "rna_Mesh_copy");
-	RNA_def_function_ui_description(func, "Copy mesh data.");
-	prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from.");
-	RNA_def_property_flag(prop, PROP_REQUIRED);*/
-
-	/*
-	func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom");
-	RNA_def_function_ui_description(func, "Add geometry data to mesh.");
-	prop= RNA_def_collection(func, "verts", "?", "", "Vertices.");
-	RNA_def_property_flag(prop, PROP_REQUIRED);
-	prop= RNA_def_collection(func, "faces", "?", "", "Faces.");
-	RNA_def_property_flag(prop, PROP_REQUIRED);
-	*/
+	FunctionRNA *func;
+	PropertyRNA *parm;
+
+	func= RNA_def_function(srna, "add_geometry", "rna_Mesh_add_geometry");
+	parm= RNA_def_int(func, "verts", 0, 0, INT_MAX, "Number", "Number of vertices to add.", 0, INT_MAX);
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_int(func, "edges", 0, 0, INT_MAX, "Number", "Number of edges to add.", 0, INT_MAX);
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_int(func, "faces", 0, 0, INT_MAX, "Number", "Number of faces to add.", 0, INT_MAX);
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+
+	func= RNA_def_function(srna, "update", "rna_Mesh_update");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 }
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index ce5b883f0a9..5f95336af2d 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_meta.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 4c7bb3f52da..9b3ff6e74a0 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_modifier.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -41,35 +41,35 @@
 #include "WM_types.h"
 
 EnumPropertyItem modifier_type_items[] ={
-	{eModifierType_Armature, "ARMATURE", 0, "Armature", ""},
-	{eModifierType_Array, "ARRAY", 0, "Array", ""},
-	{eModifierType_Bevel, "BEVEL", 0, "Bevel", ""},
-	{eModifierType_Boolean, "BOOLEAN", 0, "Boolean", ""},
-	{eModifierType_Build, "BUILD", 0, "Build", ""},
-	{eModifierType_Cast, "CAST", 0, "Cast", ""},
-	{eModifierType_Cloth, "CLOTH", 0, "Cloth", ""},
-	{eModifierType_Collision, "COLLISION", 0, "Collision", ""},
-	{eModifierType_Curve, "CURVE", 0, "Curve", ""},
-	{eModifierType_Decimate, "DECIMATE", 0, "Decimate", ""},
-	{eModifierType_Displace, "DISPLACE", 0, "Displace", ""},
-	{eModifierType_EdgeSplit, "EDGE_SPLIT", 0, "Edge Split", ""},
-	{eModifierType_Explode, "EXPLODE", 0, "Explode", ""},
-	{eModifierType_Fluidsim, "FLUID_SIMULATION", 0, "Fluid Simulation", ""},
-	{eModifierType_Hook, "HOOK", 0, "Hook", ""},
-	{eModifierType_Lattice, "LATTICE", 0, "Lattice", ""},
-	{eModifierType_Mask, "MASK", 0, "Mask", ""},
-	{eModifierType_MeshDeform, "MESH_DEFORM", 0, "Mesh Deform", ""},
-	{eModifierType_Mirror, "MIRROR", 0, "Mirror", ""},
-	{eModifierType_Multires, "MULTIRES", 0, "Multires", ""},
-	{eModifierType_ParticleInstance, "PARTICLE_INSTANCE", 0, "Particle Instance", ""},
-	{eModifierType_ParticleSystem, "PARTICLE_SYSTEM", 0, "Particle System", ""},
-	{eModifierType_Shrinkwrap, "SHRINKWRAP", 0, "Shrinkwrap", ""},
-	{eModifierType_SimpleDeform, "SIMPLE_DEFORM", 0, "Simple Deform", ""},
-	{eModifierType_Smooth, "SMOOTH", 0, "Smooth", ""},
-	{eModifierType_Softbody, "SOFTBODY", 0, "Softbody", ""},
-	{eModifierType_Subsurf, "SUBSURF", 0, "Subsurf", ""},
-	{eModifierType_UVProject, "UV_PROJECT", 0, "UV Project", ""},
-	{eModifierType_Wave, "WAVE", 0, "Wave", ""},
+	{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
+	{eModifierType_Array, "ARRAY", ICON_MOD_ARRAY, "Array", ""},
+	{eModifierType_Bevel, "BEVEL", ICON_MOD_BEVEL, "Bevel", ""},
+	{eModifierType_Boolean, "BOOLEAN", ICON_MOD_BOOLEAN, "Boolean", ""},
+	{eModifierType_Build, "BUILD", ICON_MOD_BUILD, "Build", ""},
+	{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
+	{eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""},
+	{eModifierType_Collision, "COLLISION", ICON_MOD_PHYSICS, "Collision", ""},
+	{eModifierType_Curve, "CURVE", ICON_MOD_CURVE, "Curve", ""},
+	{eModifierType_Decimate, "DECIMATE", ICON_MOD_DECIM, "Decimate", ""},
+	{eModifierType_Displace, "DISPLACE", ICON_MOD_DISPLACE, "Displace", ""},
+	{eModifierType_EdgeSplit, "EDGE_SPLIT", ICON_MOD_EDGESPLIT, "Edge Split", ""},
+	{eModifierType_Explode, "EXPLODE", ICON_MOD_EXPLODE, "Explode", ""},
+	{eModifierType_Fluidsim, "FLUID_SIMULATION", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""},
+	{eModifierType_Hook, "HOOK", ICON_HOOK, "Hook", ""},
+	{eModifierType_Lattice, "LATTICE", ICON_MOD_LATTICE, "Lattice", ""},
+	{eModifierType_Mask, "MASK", ICON_MOD_MASK, "Mask", ""},
+	{eModifierType_MeshDeform, "MESH_DEFORM", ICON_MOD_MESHDEFORM, "Mesh Deform", ""},
+	{eModifierType_Mirror, "MIRROR", ICON_MOD_MIRROR, "Mirror", ""},
+	{eModifierType_Multires, "MULTIRES", ICON_MOD_MULTIRES, "Multires", ""},
+	{eModifierType_ParticleInstance, "PARTICLE_INSTANCE", ICON_MOD_PARTICLES, "Particle Instance", ""},
+	{eModifierType_ParticleSystem, "PARTICLE_SYSTEM", ICON_MOD_PARTICLES, "Particle System", ""},
+	{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
+	{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
+	{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
+	{eModifierType_Softbody, "SOFTBODY", ICON_MOD_SOFT, "Softbody", ""},
+	{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subsurf", ""},
+	{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
+	{eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""},
 	{0, NULL, 0, NULL, NULL}};
 
 
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index bad3d36bfc2..b35b02b2063 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_nodetree.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index cff3984a56a..47a7be163b1 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_nodetree_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 8fa07ecf813..947846f8d8d 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_object.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -33,6 +33,7 @@
 #include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_object_force.h"
 #include "DNA_object_types.h"
 #include "DNA_property_types.h"
 #include "DNA_scene_types.h"
@@ -41,10 +42,13 @@
 
 #ifdef RNA_RUNTIME
 
+#include "DNA_key_types.h"
+
 #include "BKE_armature.h"
 #include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
+#include "BKE_key.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_particle.h"
@@ -130,6 +134,27 @@ static PointerRNA rna_Object_active_vertex_group_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_VertexGroup, BLI_findlink(&ob->defbase, ob->actdef));
 }
 
+static int rna_Object_active_vertex_group_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	return MAX2(ob->actdef-1, 0);
+}
+
+static void rna_Object_active_vertex_group_index_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ob->actdef= value+1;
+}
+
+static void rna_Object_active_vertex_group_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	*min= 0;
+	*max= BLI_countlist(&ob->defbase)-1;
+	*max= MAX2(0, *max);
+}
+
 void rna_object_vgroup_name_index_get(PointerRNA *ptr, char *value, int index)
 {
 	Object *ob= (Object*)ptr->id.data;
@@ -227,11 +252,23 @@ void rna_object_vcollayer_name_set(PointerRNA *ptr, const char *value, char *res
 	BLI_strncpy(result, "", maxlen);
 }
 
+static int rna_Object_active_material_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	return MAX2(ob->actcol-1, 0);
+}
+
+static void rna_Object_active_material_index_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ob->actcol= value+1;
+}
+
 static void rna_Object_active_material_index_range(PointerRNA *ptr, int *min, int *max)
 {
 	Object *ob= (Object*)ptr->id.data;
-	*min= 1;
-	*max= ob->totcol;
+	*min= 0;
+	*max= MAX2(ob->totcol-1, 0);
 }
 
 static PointerRNA rna_Object_active_material_get(PointerRNA *ptr)
@@ -240,6 +277,26 @@ static PointerRNA rna_Object_active_material_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_MaterialSlot, ob->mat+ob->actcol);
 }
 
+static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Object *ob= (Object*)ptr->id.data;
+	*min= 0;
+	*max= BLI_countlist(&ob->particlesystem)-1;
+	*max= MAX2(0, *max);
+}
+
+static int rna_Object_active_particle_system_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	return psys_get_current_num(ob);
+}
+
+static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	psys_set_current_num(ob, value);
+}
+
 #if 0
 static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
 {
@@ -364,6 +421,41 @@ static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values)
 	}
 }
 
+static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Object *ob= (Object*)ptr->id.data;
+	Key *key= ob_get_key(ob);
+
+	*min= 0;
+	*max= (key)? BLI_countlist(&key->block)-1: 0;
+	*max= MAX2(0, *max);
+}
+
+static int rna_Object_active_shape_key_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	return MAX2(ob->shapenr-1, 0);
+}
+
+static void rna_Object_active_shape_key_index_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	ob->shapenr= value+1;
+	ob->shapeflag |= OB_SHAPE_TEMPLOCK;
+}
+
+static void rna_Object_shape_key_lock_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	if(value) ob->shapeflag |= OB_SHAPE_LOCK;
+	else ob->shapeflag &= ~OB_SHAPE_LOCK;
+
+	ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+}
+
 #else
 
 static void rna_def_vertex_group(BlenderRNA *brna)
@@ -409,11 +501,13 @@ static void rna_def_material_slot(BlenderRNA *brna)
 	RNA_def_property_flag(prop, PROP_EDITABLE);
 	RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL);
 	RNA_def_property_ui_text(prop, "Material", "Material datablock used by this material slot.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, "rna_Object_update");
 
 	prop= RNA_def_property(srna, "link", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_items(prop, link_items);
 	RNA_def_property_enum_funcs(prop, "rna_MaterialSlot_link_get", "rna_MaterialSlot_link_set", NULL);
 	RNA_def_property_ui_text(prop, "Link", "Link material to object or the object's data.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, "rna_Object_update");
 
 	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_MaterialSlot_name_get", "rna_MaterialSlot_name_length", NULL);
@@ -792,7 +886,7 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "active_material_index", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "actcol");
-	RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Object_active_material_index_range");
+	RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set", "rna_Object_active_material_index_range");
 	RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot.");
 
 	/* transform */
@@ -873,8 +967,15 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "active_vertex_group", PROP_POINTER, PROP_NONE);
 	RNA_def_property_struct_type(prop, "VertexGroup");
-	RNA_def_property_pointer_funcs(prop, "rna_Object_active_vertex_group_get", NULL, NULL);
+	RNA_def_property_pointer_funcs(prop, "rna_Object_active_vertex_group_get", "rna_Object_active_vertex_group_set", NULL);
 	RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
+
+	prop= RNA_def_property(srna, "active_vertex_group_index", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "actdef");
+	RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get", "rna_Object_active_vertex_group_index_set", "rna_Object_active_vertex_group_index_range");
+	RNA_def_property_ui_text(prop, "Active Vertex Group Index", "Active index in vertex group array.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
 
 	/* empty */
 
@@ -926,6 +1027,10 @@ static void rna_def_object(BlenderRNA *brna)
 	RNA_def_property_pointer_funcs(prop, "rna_Object_active_particle_system_get", NULL, NULL);
 	RNA_def_property_ui_text(prop, "Active Particle System", "Active particle system being displayed");
 
+	prop= RNA_def_property(srna, "active_particle_system_index", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_funcs(prop, "rna_Object_active_particle_system_index_get", "rna_Object_active_particle_system_index_set", "rna_Object_active_particle_system_index_range");
+	RNA_def_property_ui_text(prop, "Active Particle System Index", "Index of active particle system slot.");
+
 	/* restrict */
 
 	prop= RNA_def_property(srna, "restrict_view", PROP_BOOLEAN, PROP_NONE);
@@ -1145,13 +1250,15 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "shape_key_lock", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_LOCK);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_shape_key_lock_set");
 	RNA_def_property_ui_text(prop, "Shape Key Lock", "Always show the current Shape for this Object.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
 
-	prop= RNA_def_property(srna, "active_shape_key", PROP_INT, PROP_NONE);
+	prop= RNA_def_property(srna, "active_shape_key_index", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "shapenr");
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-	RNA_def_property_ui_text(prop, "Active Shape Key", "Current shape key index.");
+	RNA_def_property_int_funcs(prop, "rna_Object_active_shape_key_index_get", "rna_Object_active_shape_key_index_set", "rna_Object_active_shape_key_index_range");
+	RNA_def_property_ui_text(prop, "Active Shape Key Index", "Current shape key index.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
 
 	RNA_api_object(srna);
 }
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 4ed97164988..053ab115b3b 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_object_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 41ff8c98f73..4d8c728db12 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_object_force.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -31,9 +31,225 @@
 
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
 
 #ifdef RNA_RUNTIME
 
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+#include "BKE_pointcache.h"
+#include "BKE_depsgraph.h"
+
+#include "BLI_blenlib.h"
+
+static void rna_Cache_change(bContext *C, PointerRNA *ptr)
+{
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = CTX_data_active_object(C);
+	PointCache *cache = (PointCache*)ptr->data;
+	PTCacheID *pid = NULL;
+	ListBase pidlist;
+
+	if(!ob)
+		return;
+
+	cache->flag |= PTCACHE_OUTDATED;
+
+	BKE_ptcache_ids_from_object(&pidlist, ob);
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+	for(pid=pidlist.first; pid; pid=pid->next) {
+		if(pid->cache==cache)
+			break;
+	}
+
+	if(pid)
+		BKE_ptcache_update_info(pid);
+
+	BLI_freelistN(&pidlist);
+}
+
+static void rna_Cache_toggle_disk_cache(bContext *C, PointerRNA *ptr)
+{
+	Object *ob = CTX_data_active_object(C);
+	PointCache *cache = (PointCache*)ptr->data;
+	PTCacheID *pid = NULL;
+	ListBase pidlist;
+
+	if(!ob)
+		return;
+
+	BKE_ptcache_ids_from_object(&pidlist, ob);
+
+	for(pid=pidlist.first; pid; pid=pid->next) {
+		if(pid->cache==cache)
+			break;
+	}
+
+	if(pid)
+		BKE_ptcache_toggle_disk_cache(pid);
+
+	BLI_freelistN(&pidlist);
+}
+
+static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr)
+{
+	Object *ob = CTX_data_active_object(C);
+	PointCache *cache = (PointCache*)ptr->data;
+	PTCacheID *pid = NULL, *pid2;
+	ListBase pidlist;
+	int new_name = 1;
+	char name[80];
+
+	if(!ob)
+		return;
+
+	/* TODO: check for proper characters */
+
+	BKE_ptcache_ids_from_object(&pidlist, ob);
+
+	for(pid=pidlist.first; pid; pid=pid->next) {
+		if(pid->cache==cache)
+			pid2 = pid;
+		else if(strcmp(cache->name, "") && strcmp(cache->name,pid->cache->name)==0) {
+			/*TODO: report "name exists" to user */
+			strcpy(cache->name, cache->prev_name);
+			new_name = 0;
+		}
+	}
+
+	if(new_name) {
+		if(pid2 && cache->flag & PTCACHE_DISK_CACHE) {
+			strcpy(name, cache->name);
+			strcpy(cache->name, cache->prev_name);
+
+			cache->flag &= ~PTCACHE_DISK_CACHE;
+
+			BKE_ptcache_toggle_disk_cache(pid2);
+
+			strcpy(cache->name, name);
+
+			cache->flag |= PTCACHE_DISK_CACHE;
+
+			BKE_ptcache_toggle_disk_cache(pid2);
+		}
+
+		strcpy(cache->prev_name, cache->name);
+	}
+
+	BLI_freelistN(&pidlist);
+}
+
+static int rna_SoftBodySettings_use_edges_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_EDGES) != 0);
+}
+
+static void rna_SoftBodySettings_use_edges_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_EDGES;
+	else data->softflag &= ~OB_SB_EDGES;
+}
+
+static int rna_SoftBodySettings_use_goal_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_GOAL) != 0);
+}
+
+static void rna_SoftBodySettings_use_goal_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_GOAL;
+	else data->softflag &= ~OB_SB_GOAL;
+}
+
+static int rna_SoftBodySettings_stiff_quads_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_QUADS) != 0);
+}
+
+static void rna_SoftBodySettings_stiff_quads_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_QUADS;
+	else data->softflag &= ~OB_SB_QUADS;
+}
+
+static int rna_SoftBodySettings_self_collision_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_SELF) != 0);
+}
+
+static void rna_SoftBodySettings_self_collision_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_SELF;
+	else data->softflag &= ~OB_SB_SELF;
+}
+
+static int rna_SoftBodySettings_new_aero_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_AERO_ANGLE) != 0);
+}
+
+static void rna_SoftBodySettings_new_aero_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_AERO_ANGLE;
+	else data->softflag &= ~OB_SB_AERO_ANGLE;
+}
+
+static int rna_SoftBodySettings_enabled_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_ENABLE) != 0);
+}
+
+#if 0
+static void rna_SoftBodySettings_enabled_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_ENABLE;
+	else data->softflag &= ~OB_SB_ENABLE;
+}
+#endif
+
+static int rna_SoftBodySettings_face_collision_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_FACECOLL) != 0);
+}
+
+static void rna_SoftBodySettings_face_collision_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_FACECOLL;
+	else data->softflag &= ~OB_SB_FACECOLL;
+}
+
+static int rna_SoftBodySettings_edge_collision_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_EDGECOLL) != 0);
+}
+
+static void rna_SoftBodySettings_edge_collision_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_EDGECOLL;
+	else data->softflag &= ~OB_SB_EDGECOLL;
+}
+
 #else
 
 static void rna_def_pointcache(BlenderRNA *brna)
@@ -54,12 +270,47 @@ static void rna_def_pointcache(BlenderRNA *brna)
 	RNA_def_property_range(prop, 1, 300000);
 	RNA_def_property_ui_text(prop, "End", "Frame on which the simulation stops.");
 
+	prop= RNA_def_property(srna, "step", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "step");
+	RNA_def_property_range(prop, 1, 20);
+	RNA_def_property_ui_text(prop, "Cache Step", "Number of frames between cached frames.");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change");
+
 	/* flags */
 	prop= RNA_def_property(srna, "baked", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKED);
 
 	prop= RNA_def_property(srna, "baking", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKING);
+
+	prop= RNA_def_property(srna, "disk_cache", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_DISK_CACHE);
+	RNA_def_property_ui_text(prop, "Disk Cache", "Save cache files to disk");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_toggle_disk_cache");
+
+	prop= RNA_def_property(srna, "outdated", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_OUTDATED);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Cache is outdated", "");
+
+	prop= RNA_def_property(srna, "frames_skipped", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_FRAMES_SKIPPED);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "name");
+	RNA_def_property_ui_text(prop, "Name", "Cache name");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change");
+
+	prop= RNA_def_property(srna, "quick_cache", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_QUICK_CACHE);
+	RNA_def_property_ui_text(prop, "Quick Cache", "Update simulation with cache steps");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change");
+
+	prop= RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "info");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Cache Info", "Info on current cache status.");
 }
 
 static void rna_def_collision(BlenderRNA *brna)
@@ -163,6 +414,7 @@ static void rna_def_field(BlenderRNA *brna)
 	srna= RNA_def_struct(brna, "FieldSettings", NULL);
 	RNA_def_struct_sdna(srna, "PartDeflect");
 	RNA_def_struct_ui_text(srna, "Field Settings", "Field settings for an object in physics simulation.");
+	RNA_def_struct_ui_icon(srna, ICON_PHYSICS);
 	
 	/* Enums */
 	
@@ -305,10 +557,206 @@ static void rna_def_game_softbody(BlenderRNA *brna)
 static void rna_def_softbody(BlenderRNA *brna)
 {
 	StructRNA *srna;
+	PropertyRNA *prop;
+	
+	static EnumPropertyItem collision_type_items[] = {
+		{SBC_MODE_MANUAL, "MANUAL", 0, "Manual", "Manual adjust"},
+		{SBC_MODE_AVG, "AVERAGE", 0, "Average", "Average Spring lenght * Ball Size"},
+		{SBC_MODE_MIN, "MINIMAL", 0, "Minimal", "Minimal Spring lenght * Ball Size"},
+		{SBC_MODE_MAX, "MAXIMAL", 0, "Maximal", "Maximal Spring lenght * Ball Size"},
+		{SBC_MODE_AVGMINMAX, "MINMAX", 0, "AvMinMax", "(Min+Max)/2 * Ball Size"},
+		{0, NULL, 0, NULL, NULL}};
 
 	srna= RNA_def_struct(brna, "SoftBodySettings", NULL);
 	RNA_def_struct_sdna(srna, "SoftBody");
 	RNA_def_struct_ui_text(srna, "Soft Body Settings", "Soft body simulation settings for an object.");
+	
+	/* General Settings */
+	
+	prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "mediafrict");
+	RNA_def_property_range(prop, 0.0f, 50.0f);
+	RNA_def_property_ui_text(prop, "Friction", "General media friction for point movements");
+	
+	prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "nodemass");
+	RNA_def_property_range(prop, 0.0f, 50000.0f);
+	RNA_def_property_ui_text(prop, "Mass", "");
+	
+	prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "grav");
+	RNA_def_property_range(prop, -10.0f, 10.0f);
+	RNA_def_property_ui_text(prop, "Gravitation", "Apply gravitation to point movement");
+	
+	prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "physics_speed");
+	RNA_def_property_range(prop, 0.01f, 100.0f);
+	RNA_def_property_ui_text(prop, "Speed", "Tweak timing for physics to control frequency and speed");
+	
+	/* Goal */
+	
+	/*prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "vertgroup");
+	RNA_def_property_ui_text(prop, "Vertex Group", "Use control point weight values");*/
+	
+	prop= RNA_def_property(srna, "goal_min", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "mingoal");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range.");
+
+	prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "maxgoal");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range.");
+
+	prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "defgoal");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used.");
+	
+	prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "goalspring");
+	RNA_def_property_range(prop, 0.0f, 0.999f);
+	RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness.");
+	
+	prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "goalfrict");
+	RNA_def_property_range(prop, 0.0f, 50.0f);
+	RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction.");
+	
+	/* Edge Spring Settings */
+	
+	prop= RNA_def_property(srna, "pull", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "inspring");
+	RNA_def_property_range(prop, 0.0f, 0.999f);
+	RNA_def_property_ui_text(prop, "Pull", "Edge spring stiffness when longer than rest length");
+	
+	prop= RNA_def_property(srna, "push", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "inpush");
+	RNA_def_property_range(prop, 0.0f, 0.999f);
+	RNA_def_property_ui_text(prop, "Push", "Edge spring stiffness when shorter than rest length");
+	
+	prop= RNA_def_property(srna, "damp", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "infrict");
+	RNA_def_property_range(prop, 0.0f, 50.0f);
+	RNA_def_property_ui_text(prop, "Damp", "Edge spring friction");
+	
+	prop= RNA_def_property(srna, "spring_lenght", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "springpreload");
+	RNA_def_property_range(prop, 0.0f, 200.0f);
+	RNA_def_property_ui_text(prop, "SL", "Alter spring lenght to shrink/blow up (unit %) 0 to disable");
+	
+	prop= RNA_def_property(srna, "aero", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "aeroedge");
+	RNA_def_property_range(prop, 0.0f, 30000.0f);
+	RNA_def_property_ui_text(prop, "Aero", "Make edges 'sail'");
+	
+	prop= RNA_def_property(srna, "plastic", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "plastic");
+	RNA_def_property_range(prop, 0.0f, 100.0f);
+	RNA_def_property_ui_text(prop, "Plastic", "Permanent deform");
+	
+	prop= RNA_def_property(srna, "bending", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "secondspring");
+	RNA_def_property_range(prop, 0.0f, 10.0f);
+	RNA_def_property_ui_text(prop, "Bending", "Bending Stiffness");
+	
+	prop= RNA_def_property(srna, "shear", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "shearstiff");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Shear", "Shear Stiffness");
+	
+	/* Collision */
+	
+	prop= RNA_def_property(srna, "collision_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "sbc_mode");
+	RNA_def_property_enum_items(prop, collision_type_items);
+	RNA_def_property_ui_text(prop, "Collision Type", "Choose Collision Type");
+	
+	prop= RNA_def_property(srna, "ball_size", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "colball");
+	RNA_def_property_range(prop, -10.0f, 10.0f);
+	RNA_def_property_ui_text(prop, "Ball Size", "Absolute ball size or factor if not manual adjusted");
+	
+	prop= RNA_def_property(srna, "ball_stiff", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "ballstiff");
+	RNA_def_property_range(prop, 0.001f, 100.0f);
+	RNA_def_property_ui_text(prop, "Ball Size", "Ball inflating presure");
+	
+	prop= RNA_def_property(srna, "ball_damp", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "balldamp");
+	RNA_def_property_range(prop, 0.001f, 1.0f);
+	RNA_def_property_ui_text(prop, "Ball Size", "Blending to inelastic collision");
+	
+	/* Solver */
+	
+	prop= RNA_def_property(srna, "error_limit", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "rklimit");
+	RNA_def_property_range(prop, 0.001f, 10.0f);
+	RNA_def_property_ui_text(prop, "Error Limit", "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+	
+	prop= RNA_def_property(srna, "minstep", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "minloops");
+	RNA_def_property_range(prop, 0, 30000);
+	RNA_def_property_ui_text(prop, "Min Step", "Minimal # solver steps/frame");
+	
+	prop= RNA_def_property(srna, "maxstep", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "maxloops");
+	RNA_def_property_range(prop, 0, 30000);
+	RNA_def_property_ui_text(prop, "Max Step", "Maximal # solver steps/frame");
+	
+	prop= RNA_def_property(srna, "choke", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "choke");
+	RNA_def_property_range(prop, 0, 100);
+	RNA_def_property_ui_text(prop, "Choke", "'Viscosity' inside collision target");
+	
+	prop= RNA_def_property(srna, "fuzzy", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "fuzzyness");
+	RNA_def_property_range(prop, 1, 100);
+	RNA_def_property_ui_text(prop, "Fuzzy", "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+	
+	prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_OLDERR);
+	RNA_def_property_ui_text(prop, "V", "Use velocities for automagic step sizes");
+	
+	prop= RNA_def_property(srna, "diagnose", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_MONITOR);
+	RNA_def_property_ui_text(prop, "Print Performance to Console", "Turn on SB diagnose console prints");
+	
+	/* Flags */
+	
+	prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_enabled_get", "rna_SoftBodySettings_enabled_set");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Enable", "Sets object to become soft body.");
+	
+	prop= RNA_def_property(srna, "use_goal", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_goal_get", "rna_SoftBodySettings_use_goal_set");
+	RNA_def_property_ui_text(prop, "Use Goal", "Define forces for vertices to stick to animated position.");
+	
+	prop= RNA_def_property(srna, "use_edges", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_edges_get", "rna_SoftBodySettings_use_edges_set");
+	RNA_def_property_ui_text(prop, "Use Edges", "Use Edges as springs");
+	
+	prop= RNA_def_property(srna, "stiff_quads", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_stiff_quads_get", "rna_SoftBodySettings_stiff_quads_set");
+	RNA_def_property_ui_text(prop, "Stiff Quads", "Adds diagonal springs on 4-gons.");
+	
+	prop= RNA_def_property(srna, "edge_collision", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_edge_collision_get", "rna_SoftBodySettings_edge_collision_set");
+	RNA_def_property_ui_text(prop, "Edge Collision", "Edges collide too.");
+	
+	prop= RNA_def_property(srna, "face_collision", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_face_collision_get", "rna_SoftBodySettings_face_collision_set");
+	RNA_def_property_ui_text(prop, "Face Collision", "Faces collide too, SLOOOOOW warning.");
+	
+	prop= RNA_def_property(srna, "new_aero", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_new_aero_get", "rna_SoftBodySettings_new_aero_set");
+	RNA_def_property_ui_text(prop, "N", "New aero(uses angle and length).");
+	
+	prop= RNA_def_property(srna, "self_collision", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get", "rna_SoftBodySettings_self_collision_set");
+	RNA_def_property_ui_text(prop, "Self Collision", "Enable naive vertex ball self collision.");
 }
 
 void RNA_def_object_force(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_packedfile.c b/source/blender/makesrna/intern/rna_packedfile.c
index 6b6db71ef87..6b9a708f555 100644
--- a/source/blender/makesrna/intern/rna_packedfile.c
+++ b/source/blender/makesrna/intern/rna_packedfile.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_packedfile.c 19382 2009-03-23 13:24:48Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index efcd9dbd434..d60a215b498 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_particle.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -38,6 +38,7 @@
 #include "DNA_scene_types.h"
 
 #include "WM_types.h"
+#include "WM_api.h"
 
 #ifdef RNA_RUNTIME
 
@@ -45,48 +46,110 @@
 #include "BKE_depsgraph.h"
 #include "BKE_particle.h"
 
+#include "BLI_arithb.h"
+
+/* property update functions */
 static void rna_Particle_redo(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_REDO;
+
+		if(ob)
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	}
+	else {
 		part = ptr->id.data;
-
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_REDO);
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_REDO);
+	}
 }
 
 static void rna_Particle_reset(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
-		part = ptr->id.data;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_RESET|PSYS_RECALC_REDO);
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_RESET;
+
+		if(ob) {
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+		}
+	}
+	else {
+		part = ptr->id.data;
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
+	}
 }
 
 static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
-		part = ptr->id.data;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE|PSYS_RECALC_REDO);
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_RESET|PSYS_RECALC_TYPE;
+
+		if(ob) {
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+		}
+	}
+	else {
+		part = ptr->id.data;
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE);
+	}
 }
 
 static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
+
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_CHILD;
+
+		if(ob)
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	}
+	else {
 		part = ptr->id.data;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_CHILD);
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_CHILD);
+	}
+}
+static PointerRNA rna_particle_settings_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ParticleSettings *part = psys_get_current(ob)->part;
+
+	return rna_pointer_inherit_refine(ptr, &RNA_ParticleSettings, part);
+}
+
+static void rna_particle_settings_set(PointerRNA *ptr, PointerRNA value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ParticleSystem *psys = psys_get_current(ob);
+
+	if(psys->part)
+		psys->part->id.us--;
+
+	psys->part = (ParticleSettings *)value.data;
+
+	if(psys->part)
+		psys->part->id.us++;
 }
 static void rna_PartSettings_start_set(struct PointerRNA *ptr, float value)
 {
@@ -887,7 +950,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 	RNA_def_property_int_sdna(prop, NULL, "disp");
 	RNA_def_property_range(prop, 0, 100);
 	RNA_def_property_ui_text(prop, "Display", "Percentage of particles to display in 3d view");
-	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
+	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
 	prop= RNA_def_property(srna, "material", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "omat");
@@ -1424,14 +1487,9 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 	RNA_def_property_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Billboard Object", "Billboards face this object (default is active camera)");
 	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
-#if 0
-	prop= RNA_def_property(srna, "ipo", PROP_POINTER, PROP_NONE);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-	RNA_def_property_pointer_sdna(prop, NULL, "ipo");
-	RNA_def_property_struct_type(prop, "Ipo");
-	RNA_def_property_ui_text(prop, "Ipo", "");
-#endif
+	
+	/* animation here? */
+	rna_def_animdata_common(srna);
 
 //	struct PartDeflect *pd;
 //	struct PartDeflect *pd2;
@@ -1452,9 +1510,15 @@ static void rna_def_particle_system(BlenderRNA *brna)
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_struct_name_property(srna, prop);
 
+	/* access to particle settings is redirected through functions */
+	/* to allow proper id-buttons functionality */
 	prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
-	RNA_def_property_pointer_sdna(prop, NULL, "part");
+	//RNA_def_property_pointer_sdna(prop, NULL, "part");
+	RNA_def_property_struct_type(prop, "ParticleSettings");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_pointer_funcs(prop, "rna_particle_settings_get", "rna_particle_settings_set", NULL);
 	RNA_def_property_ui_text(prop, "Settings", "Particle system settings.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
 	prop= RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart");
@@ -1669,6 +1733,14 @@ static void rna_def_particle_system(BlenderRNA *brna)
 	RNA_def_property_pointer_sdna(prop, NULL, "pointcache");
 	RNA_def_property_struct_type(prop, "PointCache");
 	RNA_def_property_ui_text(prop, "Point Cache", "");
+
+	/* offset ob */
+	prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
+	RNA_def_property_pointer_sdna(prop, NULL, "parent");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Parent", "Use this object's coordinate system instead of global coordinate system.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
+
 }
 
 void RNA_def_particle(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 54cf1dea0ac..b8863540bdf 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_pose.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c
index a0a5c41b19c..a840552b86f 100644
--- a/source/blender/makesrna/intern/rna_property.c
+++ b/source/blender/makesrna/intern/rna_property.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_property.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_radio.c b/source/blender/makesrna/intern/rna_radio.c
deleted file mode 100644
index 8b862b4c535..00000000000
--- a/source/blender/makesrna/intern/rna_radio.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Contributor(s): Blender Foundation (2008).
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include 
-
-#include "RNA_define.h"
-#include "RNA_types.h"
-
-#include "rna_internal.h"
-
-#include "DNA_radio_types.h"
-
-#ifdef RNA_RUNTIME
-
-#else
-
-void RNA_def_radio(BlenderRNA *brna)
-{
-	StructRNA *srna;
-	PropertyRNA *prop;
-	static EnumPropertyItem prop_drawtype_items[] = { 
-		{RAD_WIREFRAME, "WIREFRAME", 0, "Wireframe", "Enables Wireframe draw mode"},
-		{RAD_SOLID, "SOLID", 0, "Solid", "Enables Solid draw mode"},
-		{RAD_GOURAUD, "GOURAUD", 0, "Gouraud", "Enables Gouraud draw mode"},
-		{0, NULL, 0, NULL, NULL}};
-
-	srna= RNA_def_struct(brna, "Radiosity", NULL);
-	RNA_def_struct_ui_text(srna, "Radiosity", "Settings for radiosity simulation of indirect diffuse lighting.");
-	RNA_def_struct_sdna(srna, "Radio");
-
-	/* Enums */
-	prop= RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "drawtype");
-	RNA_def_property_enum_items(prop, prop_drawtype_items);
-	RNA_def_property_ui_text(prop, "Draw Mode", "Radiosity draw modes.");
-
-	/* Number values */
-	prop= RNA_def_property(srna, "hemi_resolution", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "hemires");
-	RNA_def_property_range(prop, 100, 1000);
-	RNA_def_property_ui_text(prop, "Hemi Resolution", "Sets the size of a hemicube.");
-
-	prop= RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "maxiter");
-	RNA_def_property_range(prop, 0, 10000);
-	RNA_def_property_ui_text(prop, "Max Iterations", "Limits the maximum number of radiosity rounds.");
-
-	prop= RNA_def_property(srna, "multiplier", PROP_FLOAT, PROP_NONE);
-	RNA_def_property_float_sdna(prop, NULL, "radfac");
-	RNA_def_property_range(prop, 0.001f, 250.0f);
-	RNA_def_property_ui_text(prop, "Multiplier", "Multiplies the energy values.");
-
-	prop= RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE);
-	RNA_def_property_float_sdna(prop, NULL, "gamma");
-	RNA_def_property_range(prop, 0.2f, 10.0f);
-	RNA_def_property_ui_text(prop, "Gamma", "Changes the contrast of the energy values.");
-
-	prop= RNA_def_property(srna, "convergence", PROP_FLOAT, PROP_NONE);
-	RNA_def_property_float_sdna(prop, NULL, "convergence");
-	RNA_def_property_range(prop, 0.0f, 1.0f);
-	RNA_def_property_ui_text(prop, "Convergence", "Sets the lower threshold of unshot energy.");
-
-	prop= RNA_def_property(srna, "element_max", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "elma");
-	RNA_def_property_range(prop, 1, 500);
-	RNA_def_property_ui_text(prop, "Element Max", "Sets maximum size of an element");
-
-	prop= RNA_def_property(srna, "element_min", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "elmi");
-	RNA_def_property_range(prop, 1, 100);
-	RNA_def_property_ui_text(prop, "Element Min", "Sets minimum size of an element");
-
-	prop= RNA_def_property(srna, "patch_max", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "pama");
-	RNA_def_property_range(prop, 10, 1000);
-	RNA_def_property_ui_text(prop, "Patch Max", "Sets maximum size of a patch.");
-
-	prop= RNA_def_property(srna, "patch_min", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "pami");
-	RNA_def_property_range(prop, 10, 1000);
-	RNA_def_property_ui_text(prop, "Patch Min", "Sets minimum size of a patch.");
-
-	prop= RNA_def_property(srna, "subshoot_patch", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "subshootp");
-	RNA_def_property_range(prop, 0, 10);
-	RNA_def_property_ui_text(prop, "SubShoot Patch", "Sets the number of times the environment is tested to detect paths.");
-
-	prop= RNA_def_property(srna, "subshoot_element", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "subshoote");
-	RNA_def_property_range(prop, 0, 10);
-	RNA_def_property_ui_text(prop, "SubShoot Element", "Sets the number of times the environment is tested to detect elements.");
-
-	prop= RNA_def_property(srna, "max_elements", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "maxnode");
-	RNA_def_property_range(prop, 1, 250000);
-	RNA_def_property_ui_text(prop, "Max Elements", "Sets the maximum allowed number of elements.");
-
-	prop= RNA_def_property(srna, "max_subdiv_shoot", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "maxsublamp");
-	RNA_def_property_range(prop, 1, 250);
-	RNA_def_property_ui_text(prop, "Max Subdiv Shoot", "Sets the maximum number of initial shoot patches that are evaluated");
-
-	prop= RNA_def_property(srna, "remove_doubles_limit", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "nodelim");
-	RNA_def_property_range(prop, 0, 50);
-	RNA_def_property_ui_text(prop, "Remove Doubles Limit", "Sets the range for removing doubles");
-
-	/* flag */
-	prop= RNA_def_property(srna, "show_limits", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", RAD_SHOWLIMITS);
-	RNA_def_property_ui_text(prop, "Show Limits", "Draws patch and element limits");
-
-	prop= RNA_def_property(srna, "show_z", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", RAD_SHOWZ);
-	RNA_def_property_ui_text(prop, "Show Z", "Draws limits differently");
-}
-
-#endif
-
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 5066654434e..14db8ea3377 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_rna.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -309,14 +309,16 @@ PointerRNA rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key
 		}
 	} while((srna=srna->base));
 
-	group= RNA_struct_idproperties(ptr, 0);
+	if(ptr->data) {
+		group= RNA_struct_idproperties(ptr, 0);
 
-	if(group) {
-		for(idp=group->data.group.first; idp; idp=idp->next) {
-			if(strcmp(idp->name, key) == 0) {
-				propptr.type= &RNA_Property;
-				propptr.data= idp;
-				return propptr;
+		if(group) {
+			for(idp=group->data.group.first; idp; idp=idp->next) {
+				if(strcmp(idp->name, key) == 0) {
+					propptr.type= &RNA_Property;
+					propptr.data= idp;
+					return propptr;
+				}
 			}
 		}
 	}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 875d657dee4..59d036a84dc 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_scene.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -151,8 +151,34 @@ void rna_def_tool_settings(BlenderRNA  *brna)
 	StructRNA *srna;
 	PropertyRNA *prop;
 
+	static EnumPropertyItem uv_select_mode_items[] = {
+		{UV_SELECT_VERTEX, "VERTEX", ICON_VERTEXSEL, "Vertex", "Vertex selection mode."},
+		{UV_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edge", "Edge selection mode."},
+		{UV_SELECT_FACE, "FACE", ICON_FACESEL, "Face", "Face selection mode."},
+		{UV_SELECT_ISLAND, "ISLAND", ICON_LINKEDSEL, "Island", "Island selection mode."},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem mesh_select_mode_items[] = {
+		{SCE_SELECT_VERTEX, "VERTEX", ICON_VERTEXSEL, "Vertex", "Vertex selection mode."},
+		{SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edge", "Edge selection mode."},
+		{SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Face", "Face selection mode."},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem snap_element_items[] = {
+		{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices."},
+		{SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges."},
+		{SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap to faces."},
+		{SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume."},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem snap_mode_items[] = {
+		{SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."},
+		{SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."},
+		{SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."},
+		{SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."},
+		{0, NULL, 0, NULL, NULL}};
+
 	srna= RNA_def_struct(brna, "ToolSettings", NULL);
-	RNA_def_struct_nested(brna, srna, "Scene");
 	RNA_def_struct_ui_text(srna, "Tool Settings", "");
 	
 	prop= RNA_def_property(srna, "sculpt", PROP_POINTER, PROP_NONE);
@@ -163,6 +189,67 @@ void rna_def_tool_settings(BlenderRNA  *brna)
 	RNA_def_property_struct_type(prop, "VPaint");
 	RNA_def_property_ui_text(prop, "Vertex Paint", "");
 
+	/* Transform */
+	prop= RNA_def_property(srna, "proportional_editing", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "proportional", 0);
+	RNA_def_property_ui_text(prop, "Proportional Editing", "Proportional editing mode.");
+
+	prop= RNA_def_property(srna, "proportional_editing_falloff", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "prop_mode");
+	RNA_def_property_enum_items(prop, prop_mode_items);
+	RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
+
+	prop= RNA_def_property(srna, "snap", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP);
+	RNA_def_property_ui_text(prop, "Snap", "Snap while Ctrl is held during transform.");
+	RNA_def_property_ui_icon(prop, ICON_SNAP_GEAR, 1);
+
+	prop= RNA_def_property(srna, "snap_align_rotation", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_ROTATE);
+	RNA_def_property_ui_text(prop, "Snap Align Rotation", "Align rotation with the snapping target.");
+	RNA_def_property_ui_icon(prop, ICON_SNAP_NORMAL, 0);
+
+	prop= RNA_def_property(srna, "snap_element", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "snap_mode");
+	RNA_def_property_enum_items(prop, snap_element_items);
+	RNA_def_property_ui_text(prop, "Snap Element", "Type of element to snap to.");
+
+	prop= RNA_def_property(srna, "snap_mode", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "snap_target");
+	RNA_def_property_enum_items(prop, snap_mode_items);
+	RNA_def_property_ui_text(prop, "Snap Mode", "Which part to snap onto the target.");
+
+	prop= RNA_def_property(srna, "snap_peel_object", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PEEL_OBJECT);
+	RNA_def_property_ui_text(prop, "Snap Peel Object", "Consider objects as whole when finding volume center.");
+	RNA_def_property_ui_icon(prop, ICON_SNAP_PEEL_OBJECT, 0);
+
+	/* UV */
+	prop= RNA_def_property(srna, "uv_selection_mode", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "uv_selectmode");
+	RNA_def_property_enum_items(prop, uv_select_mode_items);
+	RNA_def_property_ui_text(prop, "UV Selection Mode", "UV selection and display mode.");
+
+	prop= RNA_def_property(srna, "uv_sync_selection", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "uv_flag", UV_SYNC_SELECTION);
+	RNA_def_property_ui_text(prop, "UV Sync Selection", "Keep UV and edit mode mesh selection in sync.");
+	RNA_def_property_ui_icon(prop, ICON_EDIT, 0);
+
+	prop= RNA_def_property(srna, "uv_local_view", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "uv_flag", UV_SHOW_SAME_IMAGE);
+	RNA_def_property_ui_text(prop, "UV Local View", "Draw only faces with the currently displayed image assigned.");
+
+	/* Mesh */
+	prop= RNA_def_property(srna, "mesh_selection_mode", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_bitflag_sdna(prop, NULL, "selectmode");
+	RNA_def_property_enum_items(prop, mesh_select_mode_items);
+	RNA_def_property_ui_text(prop, "Mesh Selection Mode", "Mesh selection and display mode.");
+
+	prop= RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_PERCENTAGE);
+	RNA_def_property_float_sdna(prop, NULL, "vgroup_weight");
+	RNA_def_property_ui_text(prop, "Vertex Group Weight", "Weight to assign in vertex groups.");
+
+	/* Sculpt */
 	rna_def_sculpt(brna);
 }
 
@@ -852,10 +939,6 @@ void RNA_def_scene(BlenderRNA *brna)
 {
 	StructRNA *srna;
 	PropertyRNA *prop;
-	static EnumPropertyItem unwrapper_items[] = {
-		{0, "CONFORMAL", 0, "Conformal", ""},
-		{1, "ANGLEBASED", 0, "Angle Based", ""}, 
-		{0, NULL, 0, NULL, NULL}};
 
 	srna= RNA_def_struct(brna, "Scene", "ID");
 	RNA_def_struct_ui_text(srna, "Scene", "Scene consisting objects and defining time and render related settings.");
@@ -887,11 +970,6 @@ void RNA_def_scene(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Visible Layers", "Layers visible when rendering the scene.");
 	RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_layer_set");
 
-	prop= RNA_def_property(srna, "proportional_editing_falloff", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "prop_mode");
-	RNA_def_property_enum_items(prop, prop_mode_items);
-	RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
-
 	prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_NONE);
 	RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
 	RNA_def_property_int_sdna(prop, NULL, "r.cfra");
@@ -924,11 +1002,6 @@ void RNA_def_scene(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Stamp Note", "User define note for the render stamping.");
 	RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
 
-	prop= RNA_def_property(srna, "unwrapper", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "toolsettings->unwrapper");
-	RNA_def_property_enum_items(prop, unwrapper_items);
-	RNA_def_property_ui_text(prop, "Unwrapper", "Unwrap algorithm used by the Unwrap tool.");
-	
 	prop= RNA_def_property(srna, "nodetree", PROP_POINTER, PROP_NONE);
 	RNA_def_property_ui_text(prop, "Node Tree", "Compositing node tree.");
 	
@@ -936,10 +1009,6 @@ void RNA_def_scene(BlenderRNA *brna)
 	RNA_def_property_pointer_sdna(prop, NULL, "ed");
 	RNA_def_property_struct_type(prop, "SequenceEditor");
 	RNA_def_property_ui_text(prop, "Sequence Editor", "");
-
-	prop= RNA_def_property(srna, "radiosity", PROP_POINTER, PROP_NONE);
-	RNA_def_property_pointer_sdna(prop, NULL, "radio");
-	RNA_def_property_ui_text(prop, "Radiosity", "");
 	
 	prop= RNA_def_property(srna, "keyingsets", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "keyingsets", NULL);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 35191744f22..a4ba6ec172b 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_screen.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -42,6 +42,31 @@ EnumPropertyItem region_type_items[] = {
 
 #ifdef RNA_RUNTIME
 
+#include "WM_api.h"
+#include "WM_types.h"
+
+static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value)
+{
+	bScreen *sc= (bScreen*)ptr->data;
+
+	if(value.data == NULL)
+		return;
+
+	/* exception: can't set screens inside of area/region handers */
+	sc->newscene= value.data;
+}
+
+static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr)
+{
+	bScreen *sc= (bScreen*)ptr->data;
+
+	/* exception: can't set screens inside of area/region handers */
+	if(sc->newscene) {
+		WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene);
+		sc->newscene= NULL;
+	}
+}
+
 #else
 
 static void rna_def_scrarea(BlenderRNA *brna)
@@ -94,6 +119,9 @@ static void rna_def_bscreen(BlenderRNA *brna)
 	
 	prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NEVER_NULL);
 	RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen.");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_Screen_scene_set", NULL);
+	RNA_def_property_update(prop, 0, "rna_Screen_scene_update");
 	
 	prop= RNA_def_property(srna, "areas", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "areabase", NULL);
diff --git a/source/blender/makesrna/intern/rna_scriptlink.c b/source/blender/makesrna/intern/rna_scriptlink.c
index db33e7a8543..b486cd4a874 100644
--- a/source/blender/makesrna/intern/rna_scriptlink.c
+++ b/source/blender/makesrna/intern/rna_scriptlink.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_scriptlink.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index d31ec7b9b83..53bd230870f 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_sensor.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c
index 5b76db4ff43..055e67fb135 100644
--- a/source/blender/makesrna/intern/rna_sequence.c
+++ b/source/blender/makesrna/intern/rna_sequence.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_sequence.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c
index f26024f7a9e..363a5595b43 100644
--- a/source/blender/makesrna/intern/rna_sound.c
+++ b/source/blender/makesrna/intern/rna_sound.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_sound.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 12f0c110ea2..ae3b249e51f 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_space.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -96,8 +96,8 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr)
 			return &RNA_SpaceOutliner;
 		case SPACE_BUTS:
 			return &RNA_SpaceButtonsWindow;
-		/* case SPACE_FILE:
-			return &RNA_SpaceFileBrowser;*/
+		case SPACE_FILE:
+			return &RNA_SpaceFileBrowser;
 		case SPACE_IMAGE:
 			return &RNA_SpaceImageEditor;
 		/*case SPACE_INFO:
@@ -210,6 +210,13 @@ void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value)
 	st->top= 0;
 }
 
+void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value)
+{
+	SpaceFile *sfile= (SpaceFile*)(ptr->data);
+
+	sfile->params= value.data;
+}
+
 /* Space Buttons */
 
 StructRNA *rna_SpaceButtonsWindow_pin_id_typef(PointerRNA *ptr)
@@ -246,19 +253,10 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 	StructRNA *srna;
 	PropertyRNA *prop;
 
-#if 0
-	static EnumPropertyItem select_mode_items[] = {
-		{SI_SELECT_VERTEX, "VERTEX", 0, "Vertex", "Vertex selection mode."},
-		//{SI_SELECT_EDGE, "Edge", 0, "Edge", "Edge selection mode."},
-		{SI_SELECT_FACE, "FACE", 0, "Face", "Face selection mode."},
-		{SI_SELECT_ISLAND, "ISLAND", 0, "Island", "Island selection mode."},
-		{0, NULL, 0, NULL, NULL}};
-#endif
-
 	static EnumPropertyItem sticky_mode_items[] = {
-		{SI_STICKY_DISABLE, "DISABLED", 0, "Disabled", "Sticky vertex selection disabled."},
-		{SI_STICKY_LOC, "SHARED_LOCATION", 0, "SHARED_LOCATION", "Select UVs that are at the same location and share a mesh vertex."},
-		{SI_STICKY_VERTEX, "SHARED_VERTEX", 0, "SHARED_VERTEX", "Select UVs that share mesh vertex, irrespective if they are in the same location."},
+		{SI_STICKY_DISABLE, "DISABLED", ICON_STICKY_UVS_DISABLE, "Disabled", "Sticky vertex selection disabled."},
+		{SI_STICKY_LOC, "SHARED_LOCATION", ICON_STICKY_UVS_LOC, "SHARED_LOCATION", "Select UVs that are at the same location and share a mesh vertex."},
+		{SI_STICKY_VERTEX, "SHARED_VERTEX", ICON_STICKY_UVS_VERT, "SHARED_VERTEX", "Select UVs that share mesh vertex, irrespective if they are in the same location."},
 		{0, NULL, 0, NULL, NULL}};
 
 	static EnumPropertyItem dt_uv_items[] = {
@@ -273,17 +271,18 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 		{SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces."},
 		{0, NULL, 0, NULL, NULL}};
 
+	static EnumPropertyItem pivot_items[] = {
+		{V3D_CENTER, "CENTER", ICON_ROTATE, "Bounding Box Center", ""},
+		{V3D_CENTROID, "MEDIAN", ICON_ROTATECENTER, "Median Point", ""},
+		{V3D_CURSOR, "CURSOR", ICON_CURSOR, "2D Cursor", ""},
+		{0, NULL, 0, NULL, NULL}};
+
 	srna= RNA_def_struct(brna, "SpaceUVEditor", NULL);
 	RNA_def_struct_sdna(srna, "SpaceImage");
 	RNA_def_struct_nested(brna, srna, "SpaceImageEditor");
 	RNA_def_struct_ui_text(srna, "Space UV Editor", "UV editor data for the image editor space.");
 
 	/* selection */
-	/*prop= RNA_def_property(srna, "selection_mode", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "selectmode");
-	RNA_def_property_enum_items(prop, select_mode_items);
-	RNA_def_property_ui_text(prop, "Selection Mode", "UV selection and display mode.");*/
-
 	prop= RNA_def_property(srna, "sticky_selection_mode", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "sticky");
 	RNA_def_property_enum_items(prop, sticky_mode_items);
@@ -313,16 +312,15 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Draw Stretch Type", "Type of stretch to draw.");
 	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
-	prop= RNA_def_property(srna, "draw_modified_edges", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "dt_uvstretch");
-	RNA_def_property_enum_items(prop, dt_uvstretch_items);
-	RNA_def_property_ui_text(prop, "Draw Modified Edges", "Draw edges from the final mesh after object modifier evaluation.");
+	prop= RNA_def_property(srna, "draw_modified_edges", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAWSHADOW);
+	RNA_def_property_ui_text(prop, "Draw Modified Edges", "Draw edges after modifiers are applied.");
 	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
-	/*prop= RNA_def_property(srna, "local_view", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_LOCAL_UV);
-	RNA_def_property_ui_text(prop, "Local View", "Draw only faces with the currently displayed image assigned.");
-	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);*/
+	prop= RNA_def_property(srna, "draw_other_objects", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_OTHER);
+	RNA_def_property_ui_text(prop, "Draw Other Objects", "Draw other selected objects that share the same image.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "normalized_coordinates", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_COORDFLOATS);
@@ -331,12 +329,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 
 	/* todo: move edge and face drawing options here from G.f */
 
-	/* editing */
-	/*prop= RNA_def_property(srna, "sync_selection", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SYNC_UVSEL);
-	RNA_def_property_ui_text(prop, "Sync Selection", "Keep UV and edit mode mesh selection in sync.");
-	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);*/
-
 	prop= RNA_def_property(srna, "snap_to_pixels", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_PIXELSNAP);
 	RNA_def_property_ui_text(prop, "Snap to Pixels", "Snap UVs to pixel locations while editing.");
@@ -348,6 +340,12 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "live_unwrap", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_LIVE_UNWRAP);
 	RNA_def_property_ui_text(prop, "Live Unwrap", "Continuously unwrap the selected UV island while transforming pinned vertices.");
+
+	prop= RNA_def_property(srna, "pivot", 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", "Rotation/Scaling Pivot.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 }
 
 static void rna_def_space_outliner(BlenderRNA *brna)
@@ -575,18 +573,17 @@ static void rna_def_space_buttons(BlenderRNA *brna)
 	PropertyRNA *prop;
 
 	static EnumPropertyItem buttons_context_items[] = {
-		{BCONTEXT_SCENE, "SCENE", 0, "Scene", ""},
-		{BCONTEXT_WORLD, "WORLD", 0, "World", ""},
-		{BCONTEXT_OBJECT, "OBJECT", 0, "Object", ""},
-		{BCONTEXT_DATA, "DATA", 0, "Data", ""},
-		{BCONTEXT_MATERIAL, "MATERIAL", 0, "Material", ""},
-		{BCONTEXT_TEXTURE, "TEXTURE", 0, "Texture", ""},
-		{BCONTEXT_PARTICLE, "PARTICLE", 0, "Particle", ""},
-		{BCONTEXT_PHYSICS, "PHYSICS", 0, "Physics", ""},
-		{BCONTEXT_GAME, "GAME", 0, "Game", ""},
-		{BCONTEXT_BONE, "BONE", 0, "Bone", ""},
-		{BCONTEXT_MODIFIER, "MODIFIER", 0, "Modifier", ""},
-		{BCONTEXT_CONSTRAINT, "CONSTRAINT", 0, "Constraint", ""},
+		{BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
+		{BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
+		{BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
+		{BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraint", "Constraint"},
+		{BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifier", "Modifier"},
+		{BCONTEXT_DATA, "DATA", 0, "Data", "Data"},
+		{BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
+		{BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
+		{BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
+		{BCONTEXT_PARTICLE, "PARTICLE", ICON_PARTICLES, "Particle", "Particle"},
+		{BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
 		{0, NULL, 0, NULL, NULL}};
 		
 	static EnumPropertyItem panel_alignment_items[] = {
@@ -602,11 +599,13 @@ static void rna_def_space_buttons(BlenderRNA *brna)
 	RNA_def_property_enum_sdna(prop, NULL, "mainb");
 	RNA_def_property_enum_items(prop, buttons_context_items);
 	RNA_def_property_ui_text(prop, "Buttons Context", "The type of active data to display and edit in the buttons window");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 	
 	prop= RNA_def_property(srna, "panel_alignment", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "align");
 	RNA_def_property_enum_items(prop, panel_alignment_items);
 	RNA_def_property_ui_text(prop, "Panel Alignment", "Arrangement of the panels within the buttons window");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 
 	/* pinned data */
 	prop= RNA_def_property(srna, "pin_id", PROP_POINTER, PROP_NONE);
@@ -868,12 +867,124 @@ static void rna_def_space_text(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Replace Text", "Text to replace selected text with using the replace tool.");
 }
 
+static void rna_def_fileselect_params(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+	
+	static EnumPropertyItem file_display_items[] = {
+		{FILE_SHORTDISPLAY, "FILE_SHORTDISPLAY", ICON_SHORTDISPLAY, "Short List", "Display files as short list"},
+		{FILE_LONGDISPLAY, "FILE_LONGDISPLAY", ICON_LONGDISPLAY, "Long List", "Display files as a detailed list"},
+		{FILE_IMGDISPLAY, "FILE_IMGDISPLAY", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem file_sort_items[] = {
+		{FILE_SORT_ALPHA, "FILE_SORT_ALPHA", ICON_SORTALPHA, "Sort alphabetically", "Sort the file list alphabetically."},
+		{FILE_SORT_EXTENSION, "FILE_SORT_EXTENSION", ICON_SORTBYEXT, "Sort by extension", "Sort the file list by extension."},
+		{FILE_SORT_TIME, "FILE_SORT_TIME", ICON_SORTTIME, "Sort by time", "Sort files by modification time."},
+		{FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_SORTSIZE, "Sort by size", "Sort files by size."},
+		{0, NULL, 0, NULL, NULL}};
+
+	srna= RNA_def_struct(brna, "FileSelectParams", NULL);
+	RNA_def_struct_ui_text(srna, "File Select Parameters", "File Select Parameters.");
+
+	prop= RNA_def_property(srna, "display", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "display");
+	RNA_def_property_enum_items(prop, file_display_items);
+	RNA_def_property_ui_text(prop, "Display Mode", "Display mode for the file list");
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "do_filter", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_FILTER);
+	RNA_def_property_ui_text(prop, "Filter Files", "Enable filtering of files.");
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "hide_dot", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_HIDE_DOT);
+	RNA_def_property_ui_text(prop, "Hide Dot Files", "Hide hidden dot files.");
+	RNA_def_property_update(prop, NC_FILE | ND_FILELIST , NULL);
+
+	prop= RNA_def_property(srna, "sort", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "sort");
+	RNA_def_property_enum_items(prop, file_sort_items);
+	RNA_def_property_ui_text(prop, "Sort", "");
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_image", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", IMAGEFILE);
+	RNA_def_property_ui_text(prop, "Filter Images", "Show image files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_IMAGE, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_blender", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", BLENDERFILE);
+	RNA_def_property_ui_text(prop, "Filter Blender", "Show .blend files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_BLEND, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_movie", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", MOVIEFILE);
+	RNA_def_property_ui_text(prop, "Filter Movies", "Show movie files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_MOVIE, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_script", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", PYSCRIPTFILE);
+	RNA_def_property_ui_text(prop, "Filter Script", "Show script files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_SCRIPT, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_font", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", FTFONTFILE);
+	RNA_def_property_ui_text(prop, "Filter Fonts", "Show font files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_FONT, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_sound", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", SOUNDFILE);
+	RNA_def_property_ui_text(prop, "Filter Sound", "Show sound files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_SOUND, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_text", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", TEXTFILE);
+	RNA_def_property_ui_text(prop, "Filter Text", "Show text files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_BLANK, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_folder", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", FOLDERFILE);
+	RNA_def_property_ui_text(prop, "Filter Folder", "Show folders.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_FOLDER, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	
+}
+
+static void rna_def_space_filebrowser(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna= RNA_def_struct(brna, "SpaceFileBrowser", "Space");
+	RNA_def_struct_sdna(srna, "SpaceFile");
+	RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data.");
+
+	prop= RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
+	RNA_def_property_pointer_sdna(prop, NULL, "params");
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceFileBrowser_params_set", NULL);
+	RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser.");
+
+}
+
 void RNA_def_space(BlenderRNA *brna)
 {
 	rna_def_space(brna);
 	rna_def_space_image(brna);
 	rna_def_space_sequencer(brna);
 	rna_def_space_text(brna);
+	rna_def_fileselect_params(brna);
+	rna_def_space_filebrowser(brna);
 	rna_def_space_outliner(brna);
 	rna_def_background_image(brna);
 	rna_def_space_3dview(brna);
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index b44c392d741..cd39c317bc5 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_text.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 33d7c8fd6c0..2a7f65e2d90 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_texture.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_timeline.c b/source/blender/makesrna/intern/rna_timeline.c
index deb40f85986..d42603e1952 100644
--- a/source/blender/makesrna/intern/rna_timeline.c
+++ b/source/blender/makesrna/intern/rna_timeline.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_timeline.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 976ccc670bb..eef221e45a4 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_ui.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -416,12 +416,12 @@ static int rna_UILayout_active_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_active_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetActive(ptr->data, value);
+	uiLayoutSetActive(ptr->data, value);
 }
 
 static void rna_UILayout_op_context_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetOperatorContext(ptr->data, value);
+	uiLayoutSetOperatorContext(ptr->data, value);
 }
 
 static int rna_UILayout_op_context_get(struct PointerRNA *ptr)
@@ -436,7 +436,7 @@ static int rna_UILayout_enabled_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_enabled_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetEnabled(ptr->data, value);
+	uiLayoutSetEnabled(ptr->data, value);
 }
 
 static int rna_UILayout_red_alert_get(struct PointerRNA *ptr)
@@ -446,7 +446,7 @@ static int rna_UILayout_red_alert_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_red_alert_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetRedAlert(ptr->data, value);
+	uiLayoutSetRedAlert(ptr->data, value);
 }
 
 static int rna_UILayout_keep_aspect_get(struct PointerRNA *ptr)
@@ -456,7 +456,7 @@ static int rna_UILayout_keep_aspect_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_keep_aspect_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetKeepAspect(ptr->data, value);
+	uiLayoutSetKeepAspect(ptr->data, value);
 }
 
 static int rna_UILayout_alignment_get(struct PointerRNA *ptr)
@@ -466,7 +466,7 @@ static int rna_UILayout_alignment_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_alignment_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetAlignment(ptr->data, value);
+	uiLayoutSetAlignment(ptr->data, value);
 }
 
 static float rna_UILayout_scale_x_get(struct PointerRNA *ptr)
@@ -476,7 +476,7 @@ static float rna_UILayout_scale_x_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_scale_x_set(struct PointerRNA *ptr, float value)
 {
-	return uiLayoutSetScaleX(ptr->data, value);
+	uiLayoutSetScaleX(ptr->data, value);
 }
 
 static float rna_UILayout_scale_y_get(struct PointerRNA *ptr)
@@ -486,7 +486,7 @@ static float rna_UILayout_scale_y_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_scale_y_set(struct PointerRNA *ptr, float value)
 {
-	return uiLayoutSetScaleY(ptr->data, value);
+	uiLayoutSetScaleY(ptr->data, value);
 }
 
 #else // RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index d06d4d4406d..3df3fad3f15 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -136,6 +136,14 @@ void RNA_api_ui_layout(StructRNA *srna)
 	parm= RNA_def_string(func, "value", "", 0, "", "Enum property value.");
 	RNA_def_property_flag(parm, PROP_REQUIRED);*/
 
+	func= RNA_def_function(srna, "item_pointerR", "uiItemPointerR");
+	api_ui_item_common(func);
+	api_ui_item_rna_common(func);
+	parm= RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in.");
+	RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+	parm= RNA_def_string(func, "search_property", "", 0, "", "Identifier of search collection property.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+
 	func= RNA_def_function(srna, "itemO", "uiItemO");
 	api_ui_item_op_common(func);
 
@@ -189,8 +197,7 @@ void RNA_api_ui_layout(StructRNA *srna)
 	api_ui_item_common(func);
 
 	func= RNA_def_function(srna, "itemM", "uiItemM");
-	parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
-	RNA_def_property_flag(parm, PROP_REQUIRED);
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 	api_ui_item_common(func);
 	parm= RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu.");
 	RNA_def_property_flag(parm, PROP_REQUIRED);
@@ -206,15 +213,12 @@ void RNA_api_ui_layout(StructRNA *srna)
 
 	/* templates */
 	func= RNA_def_function(srna, "template_header", "uiTemplateHeader");
-	parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
-	RNA_def_property_flag(parm, PROP_REQUIRED);
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 
 	func= RNA_def_function(srna, "template_ID", "uiTemplateID");
-	parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
-	RNA_def_property_flag(parm, PROP_REQUIRED);
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 	api_ui_item_rna_common(func);
 	RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
-	RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a new ID block.");
 	RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
 
 	func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
@@ -245,6 +249,30 @@ void RNA_api_ui_layout(StructRNA *srna)
 	
 	func= RNA_def_function(srna, "template_layers", "uiTemplateLayers");
 	api_ui_item_rna_common(func);
+
+	func= RNA_def_function(srna, "template_image_layers", "uiTemplateImageLayers");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+	parm= RNA_def_pointer(func, "image", "Image", "", "");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_pointer(func, "image_user", "ImageUser", "", "");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+
+	func= RNA_def_function(srna, "template_list", "uiTemplateList");
+	api_ui_item_rna_common(func);
+	parm= RNA_def_pointer(func, "active_data", "AnyType", "", "Data from which to take property for the active element.");
+	RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+	parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display.", 0, INT_MAX);
+	parm= RNA_def_int(func, "columns", 5, 0, INT_MAX, "", "Number of columns to display.", 0, INT_MAX);
+	parm= RNA_def_boolean(func, "compact", 0, "", "Use compact, single row list template.");
+	parm= RNA_def_collection(func, "items", 0, "", "Items visible in the list.");
+	RNA_def_function_return(func, parm);
+
+	func= RNA_def_function(srna, "template_running_jobs", "uiTemplateRunningJobs");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
+	func= RNA_def_function(srna, "template_operator_search", "uiTemplateOperatorSearch");
 }
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index ad3875280fb..609082144e1 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_userdef.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -139,7 +139,12 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "kerning", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, -5.0, 5.0);
-	RNA_def_property_ui_text(prop, "Kerning", "");
+	RNA_def_property_ui_text(prop, "Kerning", "User kerning value in pixels");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+	prop= RNA_def_property(srna, "overlap", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "overlap", 1);
+	RNA_def_property_ui_text(prop, "Overlap", "Check for overlap characters");
 	RNA_def_property_update(prop, NC_WINDOW, NULL);
 
 	prop= RNA_def_property(srna, "shadow", PROP_INT, PROP_NONE);
@@ -301,6 +306,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
 	RNA_def_property_ui_text(prop, "Option Widget Colors", "");
 	RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+	prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NEVER_NULL);
+	RNA_def_property_pointer_sdna(prop, NULL, "wcol_toggle");
+	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
+	RNA_def_property_ui_text(prop, "Toggle Widget Colors", "");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 	
 	prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NEVER_NULL);
 	RNA_def_property_pointer_sdna(prop, NULL, "wcol_num");
@@ -343,7 +354,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
 	RNA_def_property_ui_text(prop, "Menu Item Colors", "");
 	RNA_def_property_update(prop, NC_WINDOW, NULL);
-	
+
+	prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NEVER_NULL);
+	RNA_def_property_pointer_sdna(prop, NULL, "wcol_scroll");
+	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
+	RNA_def_property_ui_text(prop, "Scroll Widget Colors", "");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 	
 	prop= RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH);
 	RNA_def_property_string_sdna(prop, NULL, "iconfile");
@@ -1505,7 +1521,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Toolbox Column Layout", "Use a column layout for toolbox.");
 
 	prop= RNA_def_property(srna, "directional_menus", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DIRECTIONALORDER);
+	RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_MENUFIXEDORDER);
 	RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction.");
 
 	/* snap to grid */
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index 7837a0b5657..aa2aaaf6342 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_vfont.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_vpaint.c b/source/blender/makesrna/intern/rna_vpaint.c
index 6a831467487..a34099dffb7 100644
--- a/source/blender/makesrna/intern/rna_vpaint.c
+++ b/source/blender/makesrna/intern/rna_vpaint.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_vpaint.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 3cb3f4ee4cb..f8ab3a86744 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_wm.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -30,9 +30,125 @@
 #include "rna_internal.h"
 
 #include "DNA_windowmanager_types.h"
+#include "WM_types.h" /* wmEvent */
+
+
+EnumPropertyItem event_value_items[] = {
+	{KM_ANY, "ANY", 0, "Any", ""},
+	{KM_NOTHING, "NOTHING", 0, "Nothing", ""},
+	{KM_PRESS, "PRESS", 0, "Press", ""},
+	{KM_RELEASE, "RELEASE", 0, "Release", ""},
+	{0, NULL, 0, NULL, NULL}};
+
+/* not returned: CAPSLOCKKEY, UNKNOWNKEY, COMMANDKEY, GRLESSKEY */
+EnumPropertyItem event_type_items[] = {
+	{AKEY, "A", 0, "A", ""},
+	{BKEY, "B", 0, "B", ""},
+	{CKEY, "C", 0, "C", ""},
+	{DKEY, "D", 0, "D", ""},
+	{EKEY, "E", 0, "E", ""},
+	{FKEY, "F", 0, "F", ""},
+	{GKEY, "G", 0, "G", ""},
+	{HKEY, "H", 0, "H", ""},
+	{IKEY, "I", 0, "I", ""},
+	{JKEY, "J", 0, "J", ""},
+	{KKEY, "K", 0, "K", ""},
+	{LKEY, "L", 0, "L", ""},
+	{MKEY, "M", 0, "M", ""},
+	{NKEY, "N", 0, "N", ""},
+	{OKEY, "O", 0, "O", ""},
+	{PKEY, "P", 0, "P", ""},
+	{QKEY, "Q", 0, "Q", ""},
+	{RKEY, "R", 0, "R", ""},
+	{SKEY, "S", 0, "S", ""},
+	{TKEY, "T", 0, "T", ""},
+	{UKEY, "U", 0, "U", ""},
+	{VKEY, "V", 0, "V", ""},
+	{WKEY, "W", 0, "W", ""},
+	{XKEY, "X", 0, "X", ""},
+	{YKEY, "Y", 0, "Y", ""},
+	{ZKEY, "Z", 0, "Z", ""},
+	
+	{ZEROKEY, "ZERO",	0, "Zero Key", ""},
+	{ONEKEY, "ONE",		0, "One Key", ""},
+	{TWOKEY, "TWO",		0, "Two Key", ""},
+	{THREEKEY, "THREE",	0, "Three Key", ""},
+	{FOURKEY, "FOUR",	0, "Four Key", ""},
+	{FIVEKEY, "FIVE",	0, "Five Key", ""},
+	{SIXKEY, "SIX",		0, "Six Key", ""},
+	{SEVENKEY, "SEVEN",	0, "Seven Key", ""},
+	{EIGHTKEY, "EIGHT",	0, "Eight Key", ""},
+	{NINEKEY, "NINE",	0, "Nine Key", ""},
+	
+	{LEFTCTRLKEY,	"LEFT_CTRL",	0, "Left Ctrl", ""},
+	{LEFTALTKEY,	"LEFT_ALT",		0, "Left Alt", ""},
+	{RIGHTALTKEY,	"RIGHT_ALT",	0, "Right Alt", ""},
+	{RIGHTCTRLKEY,	"RIGHT_CTRL",	0, "Rightctrl", ""},
+	{RIGHTSHIFTKEY,	"RIGHT_SHIFT",	0, "Rightshift", ""},
+	{LEFTSHIFTKEY,	"LEFT_SHIFT",	0, "Leftshift", ""},
+	
+	{ESCKEY, "ESC", 0, "Esc", ""},
+	{TABKEY, "TAB", 0, "Tab", ""},
+	{RETKEY, "RET", 0, "Return", ""},
+	{SPACEKEY, "SPACE", 0, "Spacebar", ""},
+	{LINEFEEDKEY, "LINE_FEED", 0, "Line Feed", ""},
+	{BACKSPACEKEY, "BACK_SPACE", 0, "Back Space", ""},
+	{DELKEY, "DEL", 0, "Delete", ""},
+	{SEMICOLONKEY, "SEMI_COLON", 0, "Semicolon", ""},
+	{PERIODKEY, "PERIOD", 0, "Period", ""},
+	{COMMAKEY, "COMMA", 0, "Comma", ""},
+	{QUOTEKEY, "QUOTE", 0, "Quote", ""},
+	{ACCENTGRAVEKEY, "ACCENT_GRAVE", 0, "Accentgrave", ""},
+	{MINUSKEY, "MINUS", 0, "Minus", ""},
+	{SLASHKEY, "SLASH", 0, "Slash", ""},
+	{BACKSLASHKEY, "BACK_SLASH", 0, "Backslash", ""},
+	{EQUALKEY, "EQUAL", 0, "Equal", ""},
+	{LEFTBRACKETKEY, "LEFT_BRACKET", 0, "Leftbracket", ""},
+	{RIGHTBRACKETKEY, "RIGHT_BRACKET", 0, "Rightbracket", ""},
+	{LEFTARROWKEY, "LEFT_ARROW", 0, "Left Arrow", ""},
+	{DOWNARROWKEY, "DOWN_ARROW", 0, "Down Arrow", ""},
+	{RIGHTARROWKEY, "RIGHT_ARROW", 0, "Right Arrow", ""},
+	{UPARROWKEY, "UP_ARROW", 0, "Up Arrow", ""},
+	{PAD2, "NUMPAD_2", 0, "Numpad 2", ""},
+	{PAD4, "NUMPAD_4", 0, "Numpad 4", ""},
+	{PAD6, "NUMPAD_6", 0, "Numpad 6", ""},
+	{PAD8, "NUMPAD_8", 0, "Numpad 8", ""},
+	{PAD1, "NUMPAD_1", 0, "Numpad 1", ""},
+	{PAD3, "NUMPAD_3", 0, "Numpad 3", ""},
+	{PAD5, "NUMPAD_5", 0, "Numpad 5", ""},
+	{PAD7, "NUMPAD_7", 0, "Numpad 7", ""},
+	{PAD9, "NUMPAD_9", 0, "Numpad 9", ""},
+	{PADPERIOD, "NUMPAD_PERIOD", 0, "Numpad .", ""},
+	{PADSLASHKEY, "NUMPAD_SLASH", 0, "Numpad /", ""},
+	{PADASTERKEY, "NUMPAD_ASTERIX", 0, "Numpad *", ""},
+	{PAD0, "NUMPAD_0", 0, "Numpad 0", ""},
+	{PADMINUS, "NUMPAD_MINUS", 0, "Numpad -", ""},
+	{PADENTER, "NUMPAD_ENTER", 0, "Numpad Enter", ""},
+	{PADPLUSKEY, "NUMPAD_PLUS", 0, "Numpad +", ""},
+	{F1KEY, "F1", 0, "F1", ""},
+	{F2KEY, "F2", 0, "F2", ""},
+	{F3KEY, "F3", 0, "F3", ""},
+	{F4KEY, "F4", 0, "F4", ""},
+	{F5KEY, "F5", 0, "F5", ""},
+	{F6KEY, "F6", 0, "F6", ""},
+	{F7KEY, "F7", 0, "F7", ""},
+	{F8KEY, "F8", 0, "F8", ""},
+	{F9KEY, "F9", 0, "F9", ""},
+	{F10KEY, "F10", 0, "F10", ""},
+	{F11KEY, "F11", 0, "F11", ""},
+	{F12KEY, "F12", 0, "F12", ""},
+	{PAUSEKEY, "PAUSE", 0, "Pause", ""},
+	{INSERTKEY, "INSERT", 0, "Insert", ""},
+	{HOMEKEY, "HOME", 0, "Home", ""},
+	{PAGEUPKEY, "PAGE_UP", 0, "Page Up", ""},
+	{PAGEDOWNKEY, "PAGE_DOWN", 0, "Page Down", ""},
+	{ENDKEY, "END", 0, "End", ""},
+	{0, NULL, 0, NULL, NULL}};	
 
 #ifdef RNA_RUNTIME
 
+#include "WM_api.h"
+
 #include "BKE_idprop.h"
 
 static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
@@ -87,6 +203,42 @@ static PointerRNA rna_Operator_properties_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_OperatorProperties, op->properties);
 }
 
+
+static void rna_Event_ascii_get(PointerRNA *ptr, char *value)
+{
+	wmEvent *event= (wmEvent*)ptr->id.data;
+	value[0]= event->ascii;
+	value[1]= '\0';
+}
+
+static int rna_Event_ascii_length(PointerRNA *ptr)
+{
+	wmEvent *event= (wmEvent*)ptr->id.data;
+	return (event->ascii)? 1 : 0;
+}
+
+static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
+{
+	wmWindow *win= (wmWindow*)ptr->data;
+
+	if(value.data == NULL)
+		return;
+
+	/* exception: can't set screens inside of area/region handers */
+	win->newscreen= value.data;
+}
+
+static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
+{
+	wmWindow *win= (wmWindow*)ptr->data;
+
+	/* exception: can't set screens inside of area/region handers */
+	if(win->newscreen) {
+		WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, win->newscreen);
+		win->newscreen= NULL;
+	}
+}
+
 #else
 
 static void rna_def_operator(BlenderRNA *brna)
@@ -146,7 +298,97 @@ static void rna_def_operator_filelist_element(BlenderRNA *brna)
 	RNA_def_property_flag(prop, PROP_IDPROPERTY);
 	RNA_def_property_ui_text(prop, "Name", "the name of a file or directory within a file list");
 }
+	
+static void rna_def_event(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+	
+	srna= RNA_def_struct(brna, "Event", NULL);
+	RNA_def_struct_ui_text(srna, "Event", "Window Manager Event");
+	RNA_def_struct_sdna(srna, "wmEvent");
 
+	/* strings */
+	prop= RNA_def_property(srna, "ascii", PROP_STRING, PROP_NONE);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_string_funcs(prop, "rna_Event_ascii_get", "rna_Event_ascii_length", NULL);
+	RNA_def_property_ui_text(prop, "ASCII", "Single ASCII character for this event.");
+
+
+	/* enums */
+	prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "val");
+	RNA_def_property_enum_items(prop, event_value_items);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Value",  "The type of event, only applies to some.");
+	
+	prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "type");
+	RNA_def_property_enum_items(prop, event_type_items);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Type",  "");
+
+
+	/* mouse */
+	prop= RNA_def_property(srna, "mouse_x", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "x");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse X Position", "The window relative vertical location of the mouse.");
+	
+	prop= RNA_def_property(srna, "mouse_y", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "y");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse Y Position", "The window relative horizontal location of the mouse.");
+	
+	prop= RNA_def_property(srna, "mouse_prev_x", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "prevx");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse Previous X Position", "The window relative vertical location of the mouse.");
+	
+	prop= RNA_def_property(srna, "mouse_prev_y", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "prevy");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse Previous Y Position", "The window relative horizontal location of the mouse.");	
+
+
+	/* modifiers */
+	prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "shift", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Shift", "True when the shift key is held.");
+	
+	prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Ctrl", "True when the shift key is held.");
+	
+	prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "alt", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Alt", "True when the shift key is held.");
+	
+	prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "oskey", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "OS Key", "True when the shift key is held.");
+}
+
+static void rna_def_window(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna= RNA_def_struct(brna, "Window", NULL);
+	RNA_def_struct_ui_text(srna, "Window", "Open window.");
+	RNA_def_struct_sdna(srna, "wmWindow");
+
+	prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NEVER_NULL);
+	RNA_def_property_struct_type(prop, "Screen");
+	RNA_def_property_ui_text(prop, "Screen", "Active screen showing in the window.");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL);
+	RNA_def_property_update(prop, 0, "rna_Window_screen_update");
+}
 
 static void rna_def_windowmanager(BlenderRNA *brna)
 {
@@ -161,6 +403,10 @@ static void rna_def_windowmanager(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "Operator");
 	RNA_def_property_ui_text(prop, "Operators", "Operator registry.");
 
+	prop= RNA_def_property(srna, "windows", PROP_COLLECTION, PROP_NONE);
+	RNA_def_property_struct_type(prop, "Window");
+	RNA_def_property_ui_text(prop, "Windows", "Open windows.");
+
 	RNA_api_wm(srna);
 }
 
@@ -169,6 +415,8 @@ void RNA_def_wm(BlenderRNA *brna)
 	rna_def_operator(brna);
 	rna_def_operator_utils(brna);
 	rna_def_operator_filelist_element(brna);
+	rna_def_event(brna);
+	rna_def_window(brna);
 	rna_def_windowmanager(brna);
 }
 
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 87a94993a42..fd34d7c4d70 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_wm_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index e313f01c194..f5eb81e3cea 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_world.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -337,7 +337,7 @@ void RNA_def_world(BlenderRNA *brna)
 	static EnumPropertyItem physics_engine_items[] = {
 		{WOPHY_NONE, "NONE", 0, "None", ""},
 		//{WOPHY_ENJI, "ENJI", 0, "Enji", ""},
-		{WOPHY_SUMO, "SUMO", 0, "Sumo (Deprecated)", ""},
+		//{WOPHY_SUMO, "SUMO", 0, "Sumo (Deprecated)", ""},
 		//{WOPHY_DYNAMO, "DYNAMO", 0, "Dynamo", ""},
 		//{WOPHY_ODE, "ODE", 0, "ODE", ""},
 		{WOPHY_BULLET, "BULLET", 0, "Bullet", ""},
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 855fdde50c5..d141a585378 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BPY_extern.h 12334 2007-10-21 23:00:29Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -50,6 +50,8 @@ struct bConstraintTarget; /* DNA_constraint_types.h*/
 struct Script;				/* DNA_screen_types.h */
 struct BPyMenu;
 struct bContext;
+struct ReportList;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c
deleted file mode 100644
index b67f1e717da..00000000000
--- a/source/blender/python/BPY_menus.c
+++ /dev/null
@@ -1,1118 +0,0 @@
-/* 
- * $Id: BPY_menus.c 12932 2007-12-17 20:21:06Z theeth $
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * This is a new part of Blender.
- *
- * Contributor(s): Willian P. Germano, Michael Reimpell
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
-*/
-
-/* 
- *This is the main file responsible for having bpython scripts accessible
- * from Blender menus.  To know more, please start with its header file.
- */
-
-#include "BPY_menus.h"
-
-#include 
-#ifndef WIN32
-  #include 
-#else
-  #include "BLI_winstuff.h"
-#endif
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BLI_blenlib.h"
-#include "MEM_guardedalloc.h"
-#include "DNA_userdef_types.h"	/* for U.pythondir */
-#include "api2_2x/EXPP_interface.h" /* for bpy_gethome() */
-
-#define BPYMENU_DATAFILE "Bpymenus"
-#define MAX_DIR_DEPTH 4 /* max depth for traversing scripts dirs */
-#define MAX_DIR_NUMBER 30 /* max number of dirs in scripts dirs trees */
-
-static int DEBUG;
-static int Dir_Depth;
-static int Dirs_Number;
-
-/* BPyMenuTable holds all registered pymenus, as linked lists for each menu
- * where they can appear (see PYMENUHOOKS enum in BPY_menus.h).
-*/
-BPyMenu *BPyMenuTable[PYMENU_TOTAL];
-
-static int bpymenu_group_atoi( char *str )
-{
-	if( !strcmp( str, "Export" ) )
-		return PYMENU_EXPORT;
-	else if( !strcmp( str, "Import" ) )
-		return PYMENU_IMPORT;
-	else if( !strcmp( str, "Help" ) )
-		return PYMENU_HELP;
-	else if( !strcmp( str, "HelpWebsites" ) )
-		return PYMENU_HELPWEBSITES;
-	else if( !strcmp( str, "HelpSystem" ) )
-		return PYMENU_HELPSYSTEM;
-	else if( !strcmp( str, "Render" ) )
-		return PYMENU_RENDER;
-	else if( !strcmp( str, "System" ) )
-		return PYMENU_SYSTEM;
-	else if( !strcmp( str, "Object" ) )
-		return PYMENU_OBJECT;
-	else if( !strcmp( str, "Mesh" ) )
-		return PYMENU_MESH;
-	else if( !strncmp( str, "Theme", 5 ) )
-		return PYMENU_THEMES;
-	else if( !strcmp( str, "Add" ) )
-		return PYMENU_ADD;
-	else if( !strcmp( str, "Wizards" ) )
-		return PYMENU_WIZARDS;
-	else if( !strcmp( str, "Animation" ) )
-		return PYMENU_ANIMATION;
-	else if( !strcmp( str, "Materials" ) )
-		return PYMENU_MATERIALS;
-	else if( !strcmp( str, "UV" ) )
-		return PYMENU_UV;
-	else if( !strcmp( str, "Image" ) )
-		return PYMENU_IMAGE;
-	else if( !strcmp( str, "FaceSelect" ) )
-		return PYMENU_FACESELECT;
-	else if( !strcmp( str, "WeightPaint" ) )
-		return PYMENU_WEIGHTPAINT;
-	else if( !strcmp( str, "VertexPaint" ) )
-		return PYMENU_VERTEXPAINT;
-	else if( !strcmp( str, "UVCalculation" ) )
-		return PYMENU_UVCALCULATION;
-	else if( !strcmp( str, "Armature" ) )
-		return PYMENU_ARMATURE;
-	else if( !strcmp( str, "ScriptTemplate" ) )
-		return PYMENU_SCRIPTTEMPLATE;
-	else if( !strcmp( str, "MeshFaceKey" ) )
-		return PYMENU_MESHFACEKEY;
-	else if( !strcmp( str, "AddMesh" ) )
-		return PYMENU_ADDMESH;
-	/* "Misc" or an inexistent group name: use misc */
-	else
-		return PYMENU_MISC;
-}
-
-char *BPyMenu_group_itoa( short menugroup )
-{
-	switch ( menugroup ) {
-	case PYMENU_EXPORT:
-		return "Export";
-		break;
-	case PYMENU_IMPORT:
-		return "Import";
-		break;
-	case PYMENU_ADD:
-		return "Add";
-		break;
-	case PYMENU_HELP:
-		return "Help";
-		break;
-	case PYMENU_HELPWEBSITES:
-		return "HelpWebsites";
-		break;
-	case PYMENU_HELPSYSTEM:
-		return "HelpSystem";
-		break;
-	case PYMENU_RENDER:
-		return "Render";
-		break;
-	case PYMENU_SYSTEM:
-		return "System";
-		break;
-	case PYMENU_OBJECT:
-		return "Object";
-		break;
-	case PYMENU_MESH:
-		return "Mesh";
-		break;
-	case PYMENU_THEMES:
-		return "Themes";
-		break;
-	case PYMENU_WIZARDS:
-		return "Wizards";
-		break;
-	case PYMENU_ANIMATION:
-		return "Animation";
-		break;
-	case PYMENU_MATERIALS:
-		return "Materials";
-		break;
-	case PYMENU_UV:
-		return "UV";
-		break;
-	case PYMENU_IMAGE:
-		return "Image";
-		break;
-	case PYMENU_FACESELECT:
-		return "FaceSelect";
-		break;
-	case PYMENU_WEIGHTPAINT:
-		return "WeightPaint";
-		break;
-	case PYMENU_VERTEXPAINT:
-		return "VertexPaint";
-		break;
-	case PYMENU_UVCALCULATION:
-		return "UVCalculation";
-		break;
-	case PYMENU_ARMATURE:
-		return "Armature";
-		break;
-	case PYMENU_SCRIPTTEMPLATE:
-		return "ScriptTemplate";
-		break;
-	case PYMENU_MESHFACEKEY:
-		return "MeshFaceKey";
-		break;
-	case PYMENU_ADDMESH:
-		return "AddMesh";
-		break;
-	case PYMENU_MISC:
-		return "Misc";
-		break;
-	}
-	return NULL;
-}
-
-/* BPyMenu_CreatePupmenuStr:
- * build and return a meaninful string to be used by pupmenu().  The
- * string is made of a bpymenu name as title and its submenus as possible
- * choices for the user.
-*/
-char *BPyMenu_CreatePupmenuStr( BPyMenu * pym, short menugroup )
-{
-	BPySubMenu *pysm = pym->submenus;
-	char str[1024], str2[100];
-	int i = 0, rlen;
-
-	if( !pym || !pysm )
-		return NULL;
-
-	str[0] = '\0';
-
-	PyOS_snprintf( str2, sizeof( str2 ), "%s: %s%%t",
-		       BPyMenu_group_itoa( menugroup ), pym->name );
-	strcat( str, str2 );
-
-	while( pysm ) {
-		PyOS_snprintf( str2, sizeof( str2 ), "|%s%%x%d", pysm->name,
-			       i );
-		rlen = sizeof( str ) - strlen( str );
-		strncat( str, str2, rlen );
-		i++;
-		pysm = pysm->next;
-	}
-
-	return BLI_strdup( str );
-}
-
-static void bpymenu_RemoveAllSubEntries( BPySubMenu * smenu )
-{
-	BPySubMenu *tmp;
-
-	while( smenu ) {
-		tmp = smenu->next;
-		if( smenu->name )
-			MEM_freeN( smenu->name );
-		if( smenu->arg )
-			MEM_freeN( smenu->arg );
-		MEM_freeN( smenu );
-		smenu = tmp;
-	}
-	return;
-}
-
-void BPyMenu_RemoveAllEntries( void )
-{
-	BPyMenu *tmp, *pymenu;
-	int i;
-
-	for( i = 0; i < PYMENU_TOTAL; i++ ) {
-		pymenu = BPyMenuTable[i];
-		while( pymenu ) {
-			tmp = pymenu->next;
-			if( pymenu->name )
-				MEM_freeN( pymenu->name );
-			if( pymenu->filename )
-				MEM_freeN( pymenu->filename );
-			if( pymenu->tooltip )
-				MEM_freeN( pymenu->tooltip );
-			if( pymenu->submenus )
-				bpymenu_RemoveAllSubEntries( pymenu->
-							     submenus );
-			MEM_freeN( pymenu );
-			pymenu = tmp;
-		}
-		BPyMenuTable[i] = NULL;
-	}
-
-	Dirs_Number = 0;
-	Dir_Depth = 0;
-
-	return;
-}
-
-static BPyMenu *bpymenu_FindEntry( short group, char *name )
-{
-	BPyMenu *pymenu;
-
-	if( ( group < 0 ) || ( group >= PYMENU_TOTAL ) )
-		return NULL;
-
-	pymenu = BPyMenuTable[group];
-
-	while( pymenu ) {
-		if( !strcmp( pymenu->name, name ) )
-			return pymenu;
-		pymenu = pymenu->next;
-	}
-
-	return NULL;
-}
-
-/* BPyMenu_GetEntry:
- * given a group and a position, return the entry in that position from
- * that group.
-*/
-BPyMenu *BPyMenu_GetEntry( short group, short pos )
-{
-	BPyMenu *pym = NULL;
-
-	if( ( group < 0 ) || ( group >= PYMENU_TOTAL ) )
-		return NULL;
-
-	pym = BPyMenuTable[group];
-
-	while( pos-- ) {
-		if( pym )
-			pym = pym->next;
-		else
-			break;
-	}
-
-	return pym;		/* found entry or NULL */
-}
-
-static void bpymenu_set_tooltip( BPyMenu * pymenu, char *tip )
-{
-	if( !pymenu )
-		return;
-
-	if( pymenu->tooltip )
-		MEM_freeN( pymenu->tooltip );
-	pymenu->tooltip = BLI_strdup( tip );
-
-	return;
-}
-
-/* bpymenu_AddEntry:
- * try to find an existing pymenu entry with the given type and name;
- * if found, update it with new info, otherwise create a new one and fill it.
- */
-static BPyMenu *bpymenu_AddEntry( short group, short version, char *name,
-	char *fname, int is_userdir, char *tooltip )
-{
-	BPyMenu *menu, *next = NULL, **iter;
-	int nameclash = 0;
-
-	if( ( group < 0 ) || ( group >= PYMENU_TOTAL ) )
-		return NULL;
-	if( !name || !fname )
-		return NULL;
-
-	menu = bpymenu_FindEntry( group, name );	/* already exists? */
-
-	/* if a menu with this name already exists in the same group:
-	 * - if one script is in the default dir and the other in U.pythondir,
-	 *   accept and let the new one override the other.
-	 * - otherwise, report the error and return NULL. */
-	if( menu ) {
-		if( menu->dir < is_userdir ) {	/* new one is in U.pythondir */
-			nameclash = 1;
-			if( menu->name )
-				MEM_freeN( menu->name );
-			if( menu->filename )
-				MEM_freeN( menu->filename );
-			if( menu->tooltip )
-				MEM_freeN( menu->tooltip );
-			if( menu->submenus )
-				bpymenu_RemoveAllSubEntries( menu->submenus );
-			next = menu->next;
-		} else {	/* they are in the same dir */
-			if (DEBUG) {
-				fprintf(stderr, "\n\
-Warning: script %s's menu name is already in use.\n\
-Edit the script and change its \n\
-Name: '%s'\n\
-field, please.\n\
-Note: if you really want to have two scripts for the same menu with\n\
-the same name, keep one in the default dir and the other in\n\
-the user defined dir (only the later will be registered).\n", fname, name);
-			}
-			return NULL;
-		}
-	} else
-		menu = MEM_mallocN( sizeof( BPyMenu ), "pymenu" );
-
-	if( !menu )
-		return NULL;
-
-	menu->name = BLI_strdup( name );
-	menu->version = version;
-	menu->filename = BLI_strdup( fname );
-	menu->tooltip = NULL;
-	if( tooltip )
-		menu->tooltip = BLI_strdup( tooltip );
-	menu->dir = is_userdir;
-	menu->submenus = NULL;
-	menu->next = next;	/* non-NULL if menu already existed */
-
-	if( nameclash )
-		return menu;	/* no need to place it, it's already at the list */
-	else {	/* insert the new entry in its correct position at the table */
-		BPyMenu *prev = NULL;
-		char *s = NULL;
-
-		iter = &BPyMenuTable[group];
-		while( *iter ) {
-			s = ( *iter )->name;
-			if( s )
-				if( strcmp( menu->name, s ) < 0 )
-					break;	/* sort by names */
-			prev = *iter;
-			iter = &( ( *iter )->next );
-		}
-
-		if( *iter ) {	/* prepend */
-			menu->next = *iter;
-			if( prev )
-				prev->next = menu;
-			else
-				BPyMenuTable[group] = menu;	/* is first entry */
-		} else
-			*iter = menu;	/* append */
-	}
-
-	return menu;
-}
-
-/* bpymenu_AddSubEntry:
- * add a submenu to an existing python menu.
- */
-static int bpymenu_AddSubEntry( BPyMenu * mentry, char *name, char *arg )
-{
-	BPySubMenu *smenu, **iter;
-
-	smenu = MEM_mallocN( sizeof( BPySubMenu ), "pysubmenu" );
-	if( !smenu )
-		return -1;
-
-	smenu->name = BLI_strdup( name );
-	smenu->arg = BLI_strdup( arg );
-	smenu->next = NULL;
-
-	if( !smenu->name || !smenu->arg )
-		return -1;
-
-	iter = &( mentry->submenus );
-	while( *iter )
-		iter = &( ( *iter )->next );
-
-	*iter = smenu;
-
-	return 0;
-}
-
-/* bpymenu_CreateFromFile:
- * parse the bpymenus data file where Python menu data is stored;
- * based on this data, create and fill the pymenu structs.
- */
-static int bpymenu_CreateFromFile( void )
-{
-	FILE *fp;
-	char line[255], w1[255], w2[255], tooltip[255], *tip;
-	char *homedir = NULL;
-	int parsing, version, is_userdir;
-	short group;
-	BPyMenu *pymenu = NULL;
-
-	/* init global bpymenu table (it is a list of pointers to struct BPyMenus
-	 * for each available cathegory: import, export, etc.) */
-	for( group = 0; group < PYMENU_TOTAL; group++ )
-		BPyMenuTable[group] = NULL;
-
-	/* let's try to open the file with bpymenu data */
-	homedir = bpy_gethome(0);
-	if (!homedir) {
-		if( DEBUG )
-			fprintf(stderr,
-				"BPyMenus error: couldn't open config file Bpymenus: no home dir.\n");
-		return -1;
-	}
-
-	BLI_make_file_string( "/", line, homedir, BPYMENU_DATAFILE );
-
-	fp = fopen( line, "rb" );
-
-	if( !fp ) {
-		if( DEBUG )
-			fprintf(stderr, "BPyMenus error: couldn't open config file %s.\n", line );
-		return -1;
-	}
-
-	fgets( line, 255, fp );	/* header */
-
-	/* check if the U.pythondir we saved at the file is different from the
-	 * current one.  If so, return to force updating from dirs */
-	w1[0] = '\0';
-	fscanf( fp, "# User defined scripts dir: %[^\n]\n", w1 );
-	if( w1 ) {
-		char upythondir[FILE_MAXDIR];
-
-		BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
-		BLI_convertstringcode(upythondir, G.sce, 0);
-		if( strcmp( w1, upythondir ) != 0 )
-			return -1;
-		w1[0] = '\0';
-	}
-
-	while( fgets( line, 255, fp ) ) {	/* parsing file lines */
-
-		switch ( line[0] ) {	/* check first char */
-		case '#':	/* comment */
-			continue;
-			break;
-		case '\n':
-			continue;
-			break;
-		default:
-			parsing = sscanf( line, "%s {\n", w1 );	/* menu group */
-			break;
-		}
-
-		if( parsing == 1 ) {	/* got menu group string */
-			group = (short)bpymenu_group_atoi( w1 );
-			if( group < 0 && DEBUG ) {	/* invalid type */
-				fprintf(stderr,
-					"BPyMenus error parsing config file: wrong group: %s,\n\
-will use 'Misc'.\n", w1 );
-			}
-		} else
-			continue;
-
-		for(;;) {
-			tip = NULL;	/* optional tooltip */
-			fgets( line, 255, fp );
-			if( line[0] == '}' )
-				break;
-			else if( line[0] == '\n' )
-				continue;
-			else if( line[0] == '\'' ) {	/* menu entry */
-				parsing =
-					sscanf( line,
-						"'%[^']' %d %s %d '%[^']'\n",
-						w1, &version, w2, &is_userdir,
-						tooltip );
-
-				if( parsing <= 0 ) {	/* invalid line, get rid of it */
-					fgets( line, 255, fp );
-				} else if( parsing == 5 )
-					tip = tooltip;	/* has tooltip */
-
-				pymenu = bpymenu_AddEntry( group,
-							   ( short ) version,
-							   w1, w2, is_userdir,
-							   tip );
-				if( !pymenu ) {
-					puts( "BPyMenus error: couldn't create bpymenu entry.\n" );
-					fclose( fp );
-					return -1;
-				}
-			} else if( line[0] == '|' && line[1] == '_' ) {	/* menu sub-entry */
-				if( !pymenu )
-					continue;	/* no menu yet, skip this line */
-				sscanf( line, "|_%[^:]: %s\n", w1, w2 );
-				bpymenu_AddSubEntry( pymenu, w1, w2 );
-			}
-		}
-	}
-
-	fclose( fp );
-	return 0;
-}
-
-/* bpymenu_WriteDataFile:
- * writes the registered scripts info to the user's home dir, for faster
- * access when the scripts dir hasn't changed.
-*/
-static void bpymenu_WriteDataFile( void )
-{
-	BPyMenu *pymenu;
-	BPySubMenu *smenu;
-	FILE *fp;
-	char fname[FILE_MAXDIR], *homedir;
-	int i;
-
-	homedir = bpy_gethome(0);
-
-	if (!homedir) {
-		if( DEBUG )
-			fprintf(stderr,
-				"BPyMenus error: couldn't write Bpymenus file: no home dir.\n\n");
-		return;
-	}
-
-	BLI_make_file_string( "/", fname, homedir, BPYMENU_DATAFILE );
-
-	fp = fopen( fname, "w" );
-	if( !fp ) {
-		if( DEBUG )
-			fprintf(stderr, "BPyMenus error: couldn't write %s file.\n\n",
-				fname );
-		return;
-	}
-
-	fprintf( fp,
-		 "# Blender: registered menu entries for bpython scripts\n" );
-
-	if (U.pythondir[0] != '\0' &&
-			strcmp(U.pythondir, "/") != 0 && strcmp(U.pythondir, "//") != 0)
-	{
-		char upythondir[FILE_MAXDIR];
-
-		BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
-		BLI_convertstringcode(upythondir, G.sce, 0);
-		fprintf( fp, "# User defined scripts dir: %s\n", upythondir );
-	}
-
-	for( i = 0; i < PYMENU_TOTAL; i++ ) {
-		pymenu = BPyMenuTable[i];
-		if( !pymenu )
-			continue;
-		fprintf( fp, "\n%s {\n", BPyMenu_group_itoa( (short)i ) );
-		while( pymenu ) {
-			fprintf( fp, "'%s' %d %s %d", pymenu->name,
-				 pymenu->version, pymenu->filename,
-				 pymenu->dir );
-			if( pymenu->tooltip )
-				fprintf( fp, " '%s'\n", pymenu->tooltip );
-			else
-				fprintf( fp, "\n" );
-			smenu = pymenu->submenus;
-			while( smenu ) {
-				fprintf( fp, "|_%s: %s\n", smenu->name,
-					 smenu->arg );
-				smenu = smenu->next;
-			}
-			pymenu = pymenu->next;
-		}
-		fprintf( fp, "}\n" );
-	}
-
-	fclose( fp );
-	return;
-}
-
-/* BPyMenu_PrintAllEntries:
- * useful for debugging.
- */
-void BPyMenu_PrintAllEntries( void )
-{
-	BPyMenu *pymenu;
-	BPySubMenu *smenu;
-	int i;
-
-	printf( "# Blender: registered menu entries for bpython scripts\n" );
-
-	for( i = 0; i < PYMENU_TOTAL; i++ ) {
-		pymenu = BPyMenuTable[i];
-		printf( "\n%s {\n", BPyMenu_group_itoa( (short)i ) );
-		while( pymenu ) {
-			printf( "'%s' %d %s %d", pymenu->name, pymenu->version,
-				pymenu->filename, pymenu->dir );
-			if( pymenu->tooltip )
-				printf( " '%s'\n", pymenu->tooltip );
-			else
-				printf( "\n" );
-			smenu = pymenu->submenus;
-			while( smenu ) {
-				printf( "|_%s: %s\n", smenu->name,
-					smenu->arg );
-				smenu = smenu->next;
-			}
-			pymenu = pymenu->next;
-		}
-		printf( "}\n" );
-	}
-}
-
-/* bpymenu_ParseFile:
- * recursively scans folders looking for scripts to register.
- *
- * This function scans the scripts directory looking for .py files with the
- * right header and menu info, using that to fill the bpymenu structs.
- * is_userdir defines if the script is in the default scripts dir or the
- * user defined one (U.pythondir: is_userdir == 1).
- * Speed is important.
- *
- * The first line of the script must be '#!BPY'.
- * The header registration lines must appear between the first pair of
- * '\"\"\"' and follow this order (the single-quotes are part of
- * the format):
- *
- * # \"\"\"
- * # Name: 'script name for the menu' - * # Blender: short int (minimal Blender version) - * # Group: 'group name' (defines menu) - * # Submenu: 'submenu name' related_1word_arg - * # Tooltip: 'tooltip for the menu' - * # \"\"\" - * - * Notes: - * - * - Commenting out header lines with "#" is optional, but recommended. - * - There may be more than one submenu line, or none: - * submenus and the tooltip are optional; - * - The Blender version is the same number reported by - * Blender.Get('version') in BPython or G.version in C; - * - Line length must be less than 99. - */ -static int bpymenu_ParseFile(FILE *file, char *fname, int is_userdir) -{ - char line[100]; - char head[100]; - char middle[100]; - char tail[100]; - int matches; - int parser_state; - - char script_name[100]; - int script_version = 1; - int script_group; - - BPyMenu *scriptMenu = NULL; - - if (file != NULL) { - parser_state = 1; /* state of parser, 0 to terminate */ - - while ((parser_state != 0) && (fgets(line, 100, file) != NULL)) { - - switch (parser_state) { - - case 1: /* !BPY */ - if (strncmp(line, "#!BPY", 5) == 0) { - parser_state++; - } else { - parser_state = 0; - } - break; - - case 2: /* \"\"\" */ - if ((strstr(line, "\"\"\""))) { - parser_state++; - } - break; - - case 3: /* Name: 'script name for the menu' */ - matches = sscanf(line, "%[^']'%[^']'%c", head, script_name, tail); - if ((matches == 3) && (strstr(head, "Name:") != NULL)) { - parser_state++; - } else { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Wrong 'Name' line: %s\n", fname); - parser_state = 0; - } - break; - - case 4: /* Blender: */ - matches = sscanf(line, "%[^1234567890]%i%c", head, &script_version, - tail); - if (matches == 3) { - parser_state++; - } else { - if (DEBUG) - fprintf(stderr,"BPyMenus error: Wrong 'Blender' line: %s\n",fname); - parser_state = 0; - } - break; - - case 5: /* Group: 'group name' */ - matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail); - if ((matches == 3) && (strstr(head, "Group:") != NULL)) { - script_group = bpymenu_group_atoi(middle); - if (script_group < 0) { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Unknown group \"%s\": %s\n", - middle, fname); - parser_state = 0; - } - - else { /* register script */ - scriptMenu = bpymenu_AddEntry((short)script_group, - (short int)script_version, script_name, fname, is_userdir,NULL); - if (scriptMenu == NULL) { - if (DEBUG) - fprintf(stderr, - "BPyMenus error: Couldn't create entry for: %s\n", fname); - parser_state = 0; - } else { - parser_state++; - } - } - - } else { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Wrong 'Group' line: %s\n",fname); - parser_state = 0; - } - break; - - case 6: /* optional elements */ - /* Submenu: 'submenu name' related_1word_arg */ - matches = sscanf(line, "%[^']'%[^']'%s\n", head, middle, tail); - if ((matches == 3) && (strstr(head, "Submenu:") != NULL)) { - bpymenu_AddSubEntry(scriptMenu, middle, tail); - } else { - /* Tooltip: 'tooltip for the menu */ - matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail); - if ((matches == 3) && ((strstr(head, "Tooltip:") != NULL) || - (strstr(head, "Tip:") != NULL))) { - bpymenu_set_tooltip(scriptMenu, middle); - } - parser_state = 0; - } - break; - - default: - parser_state = 0; - break; - } - } - } - - else { /* shouldn't happen, it's checked in bpymenus_ParseDir */ - if (DEBUG) - fprintf(stderr, "BPyMenus error: Couldn't open %s.\n", fname); - return -1; - } - - return 0; -} - -/* bpymenu_ParseDir: - * recursively scans folders looking for scripts to register. - * - * This function scans the scripts directory looking for .py files with the - * right header and menu info. - * - is_userdir defines if the script is in the default scripts dir or the - * user defined one (U.pythondir: is_userdir == 1); - * - parentdir is the parent dir name to store as part of the script filename, - * if we're down a subdir. - * Speed is important. - */ -static int bpymenu_ParseDir(char *dirname, char *parentdir, int is_userdir ) -{ - DIR *dir; - FILE *file = NULL; - struct dirent *de; - struct stat status; - char *file_extension; - char path[FILE_MAX]; - char subdir[FILE_MAX]; - char *s = NULL; - - dir = opendir(dirname); - - if (dir != NULL) { - while ((de = readdir(dir)) != NULL) { - - /* skip files and dirs starting with '.' or 'bpy' */ - if ((de->d_name[0] == '.') || !strncmp(de->d_name, "bpy", 3)) { - continue; - } - - BLI_make_file_string("/", path, dirname, de->d_name); - - if (stat(path, &status) != 0) { - if (DEBUG) - fprintf(stderr, "stat %s failed: %s\n", path, strerror(errno)); - } - - if (S_ISREG(status.st_mode)) { /* is file */ - - file_extension = strstr(de->d_name, ".py"); - - if (file_extension && *(file_extension + 3) == '\0') { - file = fopen(path, "rb"); - - if (file) { - s = de->d_name; - if (parentdir) { - /* Join parentdir and de->d_name */ - BLI_join_dirfile(subdir, parentdir, de->d_name); - - s = subdir; - } - bpymenu_ParseFile(file, s, is_userdir); - fclose(file); - } - - else { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Couldn't open %s.\n", path); - } - } - } - - else if (S_ISDIR(status.st_mode)) { /* is subdir */ - Dirs_Number++; - Dir_Depth++; - if (Dirs_Number > MAX_DIR_NUMBER) { - if (DEBUG) { - fprintf(stderr, "BPyMenus error: too many subdirs.\n"); - } - closedir(dir); - return -1; - } - else if (Dir_Depth > MAX_DIR_DEPTH) { - if (DEBUG) - fprintf(stderr, - "BPyMenus error: max depth reached traversing dir tree.\n"); - closedir(dir); - return -1; - } - s = de->d_name; - if (parentdir) { - /* Join parentdir and de->d_name */ - BLI_join_dirfile(subdir, parentdir, de->d_name); - s = subdir; - } - if (bpymenu_ParseDir(path, s, is_userdir) == -1) { - closedir(dir); - return -1; - } - Dir_Depth--; - } - - } - closedir(dir); - } - - else { /* open directory stream failed */ - if (DEBUG) - fprintf(stderr, "opendir %s failed: %s\n", dirname, strerror(errno)); - return -1; - } - - return 0; -} - -static int bpymenu_GetStatMTime( char *name, int is_file, time_t * mtime ) -{ - struct stat st; - int result; - - result = stat( name, &st ); - - if( result == -1 ) - return -1; - - if( is_file ) { - if( !S_ISREG( st.st_mode ) ) - return -2; - } else if( !S_ISDIR( st.st_mode ) ) - return -2; - - *mtime = st.st_mtime; - - return 0; -} - -/* BPyMenu_Init: - * import the bpython menus data to Blender, either from: - * - the BPYMENU_DATAFILE file (?/.blender/Bpymenus) or - * - the scripts dir(s), case newer than the datafile (then update the file). - * then fill the bpymenu table with this data. - * if param usedir != 0, then the data is recreated from the dir(s) anyway. -*/ -int BPyMenu_Init( int usedir ) -{ - char fname[FILE_MAXDIR]; - char dirname[FILE_MAXDIR]; - char upythondir[FILE_MAXDIR]; - char *upydir = U.pythondir, *sdir = NULL; - time_t time_dir1 = 0, time_dir2 = 0, time_file = 0; - int stat_dir1 = 0, stat_dir2 = 0, stat_file = 0; - int i; - - DEBUG = G.f & G_DEBUG; /* is Blender in debug mode (started with -d) ? */ - - /* init global bpymenu table (it is a list of pointers to struct BPyMenus - * for each available group: import, export, etc.) */ - for( i = 0; i < PYMENU_TOTAL; i++ ) - BPyMenuTable[i] = NULL; - - if( DEBUG ) - fprintf(stdout, "\nRegistering scripts in Blender menus ...\n\n" ); - - if( U.pythondir[0] == '\0') { - upydir = NULL; - } - else if (strcmp(U.pythondir, "/") == 0 || strcmp(U.pythondir, "//") == 0) { - /* these are not accepted to prevent possible slight slowdowns on startup; - * they should not be used as user defined scripts dir, anyway, also from - * speed considerations, since they'd not be dedicated scripts dirs */ - if (DEBUG) fprintf(stderr, - "BPyMenus: invalid user defined Python scripts dir: \"/\" or \"//\".\n"); - upydir = NULL; - } - else { - BLI_strncpy(upythondir, upydir, FILE_MAXDIR); - BLI_convertstringcode(upythondir, G.sce, 0); - } - - sdir = bpy_gethome(1); - - if (sdir) { - BLI_strncpy(dirname, sdir, FILE_MAXDIR); - stat_dir1 = bpymenu_GetStatMTime( dirname, 0, &time_dir1 ); - - if( stat_dir1 < 0 ) { - time_dir1 = 0; - if( DEBUG ) { - fprintf(stderr, - "\nDefault scripts dir: %s:\n%s\n", dirname, strerror(errno)); - if( upydir ) - fprintf(stdout, - "Getting scripts menu data from user defined dir: %s.\n", - upythondir ); - } - } - } - else stat_dir1 = -1; - - if( upydir ) { - stat_dir2 = bpymenu_GetStatMTime( upythondir, 0, &time_dir2 ); - - if( stat_dir2 < 0 ) { - time_dir2 = 0; - upydir = NULL; - if( DEBUG ) - fprintf(stderr, "\nUser defined scripts dir: %s:\n%s.\n", - upythondir, strerror( errno ) ); - if( stat_dir1 < 0 ) { - if( DEBUG ) - fprintf(stderr, "\ -To have scripts in menus, please add them to the default scripts dir:\n\ -%s\n\ -and / or go to 'Info window -> File Paths tab' and set a valid path for\n\ -the user defined Python scripts dir.\n", dirname ); - return -1; - } - } - } - else stat_dir2 = -1; - - if( ( stat_dir1 < 0 ) && ( stat_dir2 < 0 ) ) { - if( DEBUG ) { - fprintf(stderr, "\nCannot register scripts in menus, no scripts dir" - " available.\nExpected default dir at: %s \n", dirname ); - } - return -1; - } - - if (usedir) stat_file = -1; - else { /* if we're not forced to use the dir */ - char *homedir = bpy_gethome(0); - - if (homedir) { - BLI_make_file_string( "/", fname, homedir, BPYMENU_DATAFILE ); - stat_file = bpymenu_GetStatMTime( fname, 1, &time_file ); - if( stat_file < 0 ) - time_file = 0; - - /* comparing dates */ - - if((stat_file == 0) - && (time_file > time_dir1) && (time_file > time_dir2)) - { /* file is newer */ - stat_file = bpymenu_CreateFromFile( ); /* -1 if an error occurred */ - if( !stat_file && DEBUG ) - fprintf(stdout, - "Getting menu data for scripts from file:\n%s\n\n", fname ); - } - else stat_file = -1; - } - else stat_file = -1; /* -1 to use dirs: didn't use file or it was corrupted */ - } - - if( stat_file == -1 ) { /* use dirs */ - if( DEBUG ) { - fprintf(stdout, - "Getting menu data for scripts from dir(s):\ndefault: %s\n", dirname ); - if( upydir ) - fprintf(stdout, "user defined: %s\n", upythondir ); - fprintf(stdout, "\n"); - } - if( stat_dir1 == 0 ) { - i = bpymenu_ParseDir( dirname, NULL, 0 ); - if (i == -1 && DEBUG) - fprintf(stderr, "Default scripts dir does not seem valid.\n\n"); - } - if( stat_dir2 == 0 ) { - BLI_strncpy(dirname, U.pythondir, FILE_MAXDIR); - BLI_convertstringcode(dirname, G.sce, 0); - i = bpymenu_ParseDir( dirname, NULL, 1 ); - if (i == -1 && DEBUG) - fprintf(stderr, "User defined scripts dir does not seem valid.\n\n"); - } - - /* check if we got any data */ - for( i = 0; i < PYMENU_TOTAL; i++ ) - if( BPyMenuTable[i] ) - break; - - /* if we got, recreate the file */ - if( i < PYMENU_TOTAL ) - bpymenu_WriteDataFile( ); - else if( DEBUG ) { - fprintf(stderr, "\n\ -Warning: Registering scripts in menus -- no info found.\n\ -Either your scripts dirs have no .py scripts or the scripts\n\ -don't have a header with registration data.\n\ -Default scripts dir is:\n\ -%s\n", dirname ); - if( upydir ) - fprintf(stderr, "User defined scripts dir is: %s\n", - upythondir ); - } - } - - return 0; -} diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h deleted file mode 100644 index 6cdea608b10..00000000000 --- a/source/blender/python/BPY_menus.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * $Id: BPY_menus.h 12931 2007-12-17 18:20:48Z theeth $ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * This is a new part of Blender. - * - * Contributor(s): Willian P. Germano, Matt Ebb - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** -*/ - -#ifndef BPY_MENUS_H -#define BPY_MENUS_H - -/* This header exposes BPyMenu related public declarations. The implementation - * adds 'dynamic' menus to Blender, letting scripts register themselves in any - * of a few pre-defined (trivial to upgrade) places in menus. These places or - * slots are called groups here (Import, Export, etc). This is how it works: - * - scripts at dirs user pref U.pythondir and .blender/scripts/ are scanned - * for registration info. - * - this data is also saved to a Bpymenus file at the user's .blender/ dir and - * only re-created when the scripts folder gets modified. - * - on start-up Blender uses this info to fill a table, which is used to - * create the menu entries when they are needed (see header_info.c or - * header_script.c, under source/blender/src/, for examples). -*/ - -/* These two structs hold py menu/submenu info. - * BPyMenu holds a script's name (as should appear in the menu) and filename, - * plus an optional list of submenus. Each submenu is related to a string - * (arg) that the script can get from the __script__ pydict, to know which - * submenu was chosen. */ - -typedef struct BPySubMenu { - char *name; - char *arg; - struct BPySubMenu *next; -} BPySubMenu; - -typedef struct BPyMenu { - char *name; - char *filename; - char *tooltip; - short version; /* Blender version */ - int dir; /* 0: default, 1: U.pythondir */ - struct BPySubMenu *submenus; - struct BPyMenu *next; -} BPyMenu; - -/* Scripts can be added to only a few pre-defined places in menus, like - * File->Import, File->Export, etc. (for speed and better control). - * To make a new menu 'slot' available for scripts: - * - add an entry to the enum below, before PYMENU_TOTAL, of course; - * - update the bpymenu_group_atoi() and BPyMenu_group_itoa() functions in - * BPY_menus.c; - * - add the necessary code to the header_***.c file in - * source/blender/src/, like done in header_info.c for import/export; -*/ -typedef enum { - PYMENU_ADD,/* creates new objects */ - PYMENU_ANIMATION, - PYMENU_EXPORT, - PYMENU_IMPORT, - PYMENU_MATERIALS, - PYMENU_MESH, - PYMENU_MISC, - PYMENU_OBJECT, - PYMENU_RENDER,/* exporters to external renderers */ - PYMENU_SYSTEM, - PYMENU_THEMES, - PYMENU_UV,/* UV editing tools, to go in UV/Image editor space, 'UV' menu */ - PYMENU_IMAGE,/* Image editing tools, to go in UV/Image editor space, 'Image' menu */ - PYMENU_WIZARDS,/* complex 'app' scripts */ - - /* entries put after Wizards don't appear at the Scripts win->Scripts menu; - * see define right below */ - - PYMENU_FACESELECT, - PYMENU_WEIGHTPAINT, - PYMENU_VERTEXPAINT, - PYMENU_UVCALCULATION, - PYMENU_ARMATURE, - PYMENU_SCRIPTTEMPLATE, - PYMENU_HELP,/*Main Help menu items - prob best to leave for 'official' ones*/ - PYMENU_HELPSYSTEM,/* Resources, troubleshooting, system tools */ - PYMENU_HELPWEBSITES,/* Help -> Websites submenu */ - PYMENU_MESHFACEKEY, /* face key in mesh editmode */ - PYMENU_ADDMESH, /* adds mesh */ - PYMENU_TOTAL -} PYMENUHOOKS; - -#define PYMENU_SCRIPTS_MENU_TOTAL (PYMENU_WIZARDS + 1) - -/* BPyMenuTable holds all registered pymenus, as linked lists for each menu - * where they can appear (see PYMENUHOOKS enum above). -*/ -extern BPyMenu *BPyMenuTable[]; /* defined in BPY_menus.c */ - -/* public functions: */ -int BPyMenu_Init( int usedir ); -void BPyMenu_RemoveAllEntries( void ); -void BPyMenu_PrintAllEntries( void ); -char *BPyMenu_CreatePupmenuStr( BPyMenu * pym, short group ); -char *BPyMenu_group_itoa( short group ); -struct BPyMenu *BPyMenu_GetEntry( short group, short pos ); - -#endif /* BPY_MENUS_H */ diff --git a/source/blender/python/Makefile b/source/blender/python/Makefile index 0c4b9ab6578..8e2a04b8449 100644 --- a/source/blender/python/Makefile +++ b/source/blender/python/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 14444 2008-04-16 22:40:48Z hos $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/python/generic/BGL.c b/source/blender/python/generic/BGL.c index f1a72270ea1..de82781cf3a 100644 --- a/source/blender/python/generic/BGL.c +++ b/source/blender/python/generic/BGL.c @@ -1,5 +1,5 @@ /* - * $Id: BGL.c 20922 2009-06-16 07:16:51Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -83,8 +83,13 @@ static PyObject *Buffer_getattr( PyObject * self, char *name ); static PyObject *Buffer_repr( PyObject * self ); PyTypeObject buffer_Type = { - PyObject_HEAD_INIT( NULL ) /* required python macro */ - 0, /*ob_size */ +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "buffer", /*tp_name */ sizeof( Buffer ), /*tp_basicsize */ 0, /*tp_itemsize */ @@ -1087,7 +1092,7 @@ static struct PyMethodDef BGL_methods[] = { #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef BGL_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "BGL", /* m_name */ 0, /* m_doc */ 0, /* m_size */ diff --git a/source/blender/python/generic/BGL.h b/source/blender/python/generic/BGL.h index e2d1b0bb495..938c916bcea 100755 --- a/source/blender/python/generic/BGL.h +++ b/source/blender/python/generic/BGL.h @@ -1,5 +1,5 @@ /* - * $Id: BGL.h 19717 2009-04-14 17:19:09Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/Geometry.c b/source/blender/python/generic/Geometry.c index d1e8b471f75..b4a34d30051 100644 --- a/source/blender/python/generic/Geometry.c +++ b/source/blender/python/generic/Geometry.c @@ -1,5 +1,5 @@ /* - * $Id: Geometry.c 20922 2009-06-16 07:16:51Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -80,7 +80,7 @@ struct PyMethodDef M_Geometry_methods[] = { #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef M_Geometry_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "Geometry", /* m_name */ M_Geometry_doc, /* m_doc */ 0, /* m_size */ @@ -164,6 +164,10 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) for( index = 0; indexvec[0]; fp[1] = ((VectorObject *)polyVec)->vec[1]; if( ((VectorObject *)polyVec)->size > 2 ) @@ -234,6 +238,9 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2)) + return NULL; + a1x= line_a1->vec[0]; a1y= line_a1->vec[1]; a2x= line_a2->vec[0]; @@ -266,7 +273,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) /*X of vert, Y of hoz. no calculation needed */ newvec[0]= a1x; newvec[1]= b1y; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } yi = (float)(((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x))); @@ -278,7 +285,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) } newvec[0]= a1x; newvec[1]= yi; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } else if (fabs(a2y-a1y) < eul) { /* hoz line1 */ if (fabs(b2y-b1y) < eul) { /*hoz line2*/ Py_RETURN_NONE; /*2 hoz lines dont intersect*/ @@ -293,7 +300,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) } newvec[0]= xi; newvec[1]= a1y; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } b1 = (a2y-a1y)/(a2x-a1x); @@ -310,7 +317,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) { newvec[0]= xi; newvec[1]= yi; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } Py_RETURN_NONE; } @@ -330,6 +337,10 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" ); return NULL; } + + if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2)) + return NULL; + /* accept 2d verts */ if (pt->size==3) { VECCOPY(pt_in, pt->vec);} else { pt_in[2]=0.0; VECCOPY2D(pt_in, pt->vec) } @@ -344,7 +355,7 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args lambda = lambda_cp_line_ex(pt_in, l1, l2, pt_out); ret = PyTuple_New(2); - PyTuple_SET_ITEM( ret, 0, newVectorObject(pt_out, 3, Py_NEW) ); + PyTuple_SET_ITEM( ret, 0, newVectorObject(pt_out, 3, Py_NEW, NULL) ); PyTuple_SET_ITEM( ret, 1, PyFloat_FromDouble(lambda) ); return ret; } @@ -363,6 +374,9 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args return NULL; } + if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(tri_p1) || !BaseMath_ReadCallback(tri_p2) || !BaseMath_ReadCallback(tri_p3)) + return NULL; + return PyLong_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec)); } @@ -381,6 +395,9 @@ static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(quad_p1) || !BaseMath_ReadCallback(quad_p2) || !BaseMath_ReadCallback(quad_p3) || !BaseMath_ReadCallback(quad_p4)) + return NULL; + return PyLong_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec)); } @@ -500,6 +517,9 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2)) + return NULL; + dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; @@ -515,7 +535,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) list= PyList_New(resolu); fp= coord_array; for(i=0; i= 0x03000000) static struct PyModuleDef M_Mathutils_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "Mathutils", /* m_name */ M_Mathutils_doc, /* m_doc */ 0, /* m_size */ @@ -137,81 +137,12 @@ PyObject *Mathutils_Init(const char *from) PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type ); PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type ); + mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb); + return (submodule); } //-----------------------------METHODS---------------------------- -//----------------column_vector_multiplication (internal)--------- -//COLUMN VECTOR Multiplication (Matrix X Vector) -// [1][2][3] [a] -// [4][5][6] * [b] -// [7][8][9] [c] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) -{ - float vecNew[4], vecCopy[4]; - double dot = 0.0f; - int x, y, z = 0; - - if(mat->rowSize != vec->size){ - if(mat->rowSize == 4 && vec->size != 3){ - PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same"); - return NULL; - }else{ - vecCopy[3] = 1.0f; - } - } - - for(x = 0; x < vec->size; x++){ - vecCopy[x] = vec->vec[x]; - } - - for(x = 0; x < mat->rowSize; x++) { - for(y = 0; y < mat->colSize; y++) { - dot += mat->matrix[x][y] * vecCopy[y]; - } - vecNew[z++] = (float)dot; - dot = 0.0f; - } - return newVectorObject(vecNew, vec->size, Py_NEW); -} - -//-----------------row_vector_multiplication (internal)----------- -//ROW VECTOR Multiplication - Vector X Matrix -//[x][y][z] * [1][2][3] -// [4][5][6] -// [7][8][9] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) -{ - float vecNew[4], vecCopy[4]; - double dot = 0.0f; - int x, y, z = 0, vec_size = vec->size; - - if(mat->colSize != vec_size){ - if(mat->rowSize == 4 && vec_size != 3){ - PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); - return NULL; - }else{ - vecCopy[3] = 1.0f; - } - } - - for(x = 0; x < vec_size; x++){ - vecCopy[x] = vec->vec[x]; - } - - //muliplication - for(x = 0; x < mat->colSize; x++) { - for(y = 0; y < mat->rowSize; y++) { - dot += mat->matrix[y][x] * vecCopy[y]; - } - vecNew[z++] = (float)dot; - dot = 0.0f; - } - return newVectorObject(vecNew, vec_size, Py_NEW); -} - //-----------------quat_rotation (internal)----------- //This function multiplies a vector/point * quat or vice versa //to rotate the point/vector by the quaternion @@ -224,8 +155,15 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) if(QuaternionObject_Check(arg1)){ quat = (QuaternionObject*)arg1; + if(!BaseMath_ReadCallback(quat)) + return NULL; + if(VectorObject_Check(arg2)){ vec = (VectorObject*)arg2; + + if(!BaseMath_ReadCallback(vec)) + return NULL; + rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] + 2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] - @@ -238,12 +176,19 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] - quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2]; - return newVectorObject(rot, 3, Py_NEW); + return newVectorObject(rot, 3, Py_NEW, NULL); } }else if(VectorObject_Check(arg1)){ vec = (VectorObject*)arg1; + + if(!BaseMath_ReadCallback(vec)) + return NULL; + if(QuaternionObject_Check(arg2)){ quat = (QuaternionObject*)arg2; + if(!BaseMath_ReadCallback(quat)) + return NULL; + rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] + 2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] - @@ -256,7 +201,7 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] - quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2]; - return newVectorObject(rot, 3, Py_NEW); + return newVectorObject(rot, 3, Py_NEW, NULL); } } @@ -308,6 +253,9 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) if(vec1->size != vec2->size) goto AttributeError1; //bad sizes + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + //since size is the same.... size = vec1->size; @@ -327,8 +275,11 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) angleRads = (double)saacos(dot); +#ifdef USE_MATHUTILS_DEG return PyFloat_FromDouble(angleRads * (180/ Py_PI)); - +#else + return PyFloat_FromDouble(angleRads); +#endif AttributeError1: PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n"); return NULL; @@ -353,11 +304,14 @@ static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; for(x = 0; x < vec1->size; x++) { vec[x] = 0.5f * (vec1->vec[x] + vec2->vec[x]); } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } //----------------------------------Mathutils.ProjectVecs() ------------- //projects vector 1 onto vector 2 @@ -377,6 +331,10 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) return NULL; } + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + + //since they are the same size... size = vec1->size; @@ -390,7 +348,7 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) for(x = 0; x < size; x++) { vec[x] = (float)(dot * vec2->vec[x]); } - return newVectorObject(vec, size, Py_NEW); + return newVectorObject(vec, size, Py_NEW, NULL); } //----------------------------------MATRIX FUNCTIONS-------------------- //----------------------------------Mathutils.RotationMatrix() ---------- @@ -409,12 +367,19 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n"); return NULL; } - + +#ifdef USE_MATHUTILS_DEG /* Clamp to -360:360 */ while (angle<-360.0f) angle+=360.0; while (angle>360.0f) angle-=360.0; +#else + while (angle<-(Py_PI*2)) + angle+=(Py_PI*2); + while (angle>(Py_PI*2)) + angle-=(Py_PI*2); +#endif if(matSize != 2 && matSize != 3 && matSize != 4) { PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); @@ -439,9 +404,16 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + } +#ifdef USE_MATHUTILS_DEG //convert to radians angle = angle * (float) (Py_PI / 180); +#endif + if(axis == NULL && matSize == 2) { //2D rotation matrix mat[0] = (float) cos (angle); @@ -521,7 +493,7 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------Mathutils.TranslationMatrix() ------- //creates a translation matrix @@ -538,13 +510,17 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v PyErr_SetString(PyExc_TypeError, "Mathutils.TranslationMatrix(): vector must be 3D or 4D\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + //create a identity matrix and add translation Mat4One((float(*)[4]) mat); mat[12] = vec->vec[0]; mat[13] = vec->vec[1]; mat[14] = vec->vec[2]; - return newMatrixObject(mat, 4, 4, Py_NEW); + return newMatrixObject(mat, 4, 4, Py_NEW, NULL); } //----------------------------------Mathutils.ScaleMatrix() ------------- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. @@ -570,6 +546,10 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + } if(vec == NULL) { //scaling along axis if(matSize == 2) { @@ -618,7 +598,7 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------Mathutils.OrthoProjectionMatrix() --- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. @@ -645,6 +625,10 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + } if(vec == NULL) { //ortho projection onto cardinal plane if(((strcmp(plane, "x") == 0) @@ -717,7 +701,7 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------Mathutils.ShearMatrix() ------------- //creates a shear matrix @@ -784,7 +768,7 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------QUATERNION FUNCTIONS----------------- @@ -801,6 +785,10 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types"); return NULL; } + + if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV)) + return NULL; + tempQuat[0] = quatU->quat[0]; tempQuat[1] = -quatU->quat[1]; tempQuat[2] = -quatU->quat[2]; @@ -813,7 +801,7 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) tempQuat[x] /= (float)(dot * dot); } QuatMul(quat, tempQuat, quatV->quat); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------------Mathutils.Slerp() ------------------ //attemps to interpolate 2 quaternions and return the result @@ -828,6 +816,10 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float"); return NULL; } + + if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV)) + return NULL; + if(param > 1.0f || param < 0.0f) { PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0"); return NULL; @@ -870,7 +862,7 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) quat[2] = (float)(quat_u[2] * x + quat_v[2] * y); quat[3] = (float)(quat_u[3] * x + quat_v[3] * y); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------------EULER FUNCTIONS---------------------- //---------------------------------INTERSECTION FUNCTIONS-------------------- @@ -891,6 +883,9 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off)) + return NULL; + VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -941,7 +936,7 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) VecMulf(dir, t); VecAddf(pvec, orig, dir); - return newVectorObject(pvec, 3, Py_NEW); + return newVectorObject(pvec, 3, Py_NEW, NULL); } //----------------------------------Mathutils.LineIntersect() ------------------- /* Line-Line intersection using algorithm from mathworld.wolfram.com */ @@ -959,6 +954,10 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4)) + return NULL; + if( vec1->size == 3 || vec1->size == 2) { int result; @@ -994,8 +993,8 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) } else { tuple = PyTuple_New( 2 ); - PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) ); - PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) ); + PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL) ); + PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL) ); return tuple; } } @@ -1029,6 +1028,10 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4)) + return NULL; + VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -1052,7 +1055,7 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) VecAddf(n1, n2, n1); Normalize(n1); - return newVectorObject(n1, 3, Py_NEW); + return newVectorObject(n1, 3, Py_NEW, NULL); } //----------------------------Mathutils.TriangleNormal() ------------------- @@ -1073,6 +1076,9 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3)) + return NULL; VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); @@ -1085,7 +1091,7 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) Crossf(n, e2, e1); Normalize(n); - return newVectorObject(n, 3, Py_NEW); + return newVectorObject(n, 3, Py_NEW, NULL); } //--------------------------------- AREA FUNCTIONS-------------------- @@ -1105,6 +1111,9 @@ static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3)) + return NULL; if (vec1->size == 3) { VECCOPY(v1, vec1->vec); @@ -1154,8 +1163,8 @@ int EXPP_FloatsAreEqual(float A, float B, int floatSteps) } /*---------------------- EXPP_VectorsAreEqual ------------------------- Builds on EXPP_FloatsAreEqual to test vectors */ -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ - +int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) +{ int x; for (x=0; x< size; x++){ if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) @@ -1165,6 +1174,86 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ } +/* Mathutils Callbacks */ + +/* for mathutils internal use only, eventually should re-alloc but to start with we only have a few users */ +Mathutils_Callback *mathutils_callbacks[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + +int Mathutils_RegisterCallback(Mathutils_Callback *cb) +{ + int i; + + /* find the first free slot */ + for(i= 0; mathutils_callbacks[i]; i++) { + if(mathutils_callbacks[i]==cb) /* alredy registered? */ + return i; + } + + mathutils_callbacks[i] = cb; + return i; +} + +/* use macros to check for NULL */ +int _BaseMathObject_ReadCallback(BaseMathObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get(self->cb_user, self->cb_subtype, self->data)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +int _BaseMathObject_WriteCallback(BaseMathObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set(self->cb_user, self->cb_subtype, self->data)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get_index(self->cb_user, self->cb_subtype, self->data, index)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set_index(self->cb_user, self->cb_subtype, self->data, index)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +/* BaseMathObject generic functions for all mathutils types */ +PyObject *BaseMathObject_getOwner( BaseMathObject * self, void *type ) +{ + PyObject *ret= self->cb_user ? self->cb_user : Py_None; + Py_INCREF(ret); + return ret; +} + +PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void *type ) +{ + return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0); +} + +void BaseMathObject_dealloc(BaseMathObject * self) +{ + /* only free non wrapped */ + if(self->wrapped != Py_WRAP) + PyMem_Free(self->data); + + Py_XDECREF(self->cb_user); + Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes +} -//####################################################################### -//#############################DEPRECATED################################ diff --git a/source/blender/python/generic/Mathutils.h b/source/blender/python/generic/Mathutils.h index e8882c3dac2..6a4e28d6068 100644 --- a/source/blender/python/generic/Mathutils.h +++ b/source/blender/python/generic/Mathutils.h @@ -1,5 +1,5 @@ /* - * $Id: Mathutils.h 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -38,10 +38,28 @@ #include "quat.h" #include "euler.h" +/* #define USE_MATHUTILS_DEG - for backwards compat */ + +/* Can cast different mathutils types to this, use for generic funcs */ + +typedef struct { + PyObject_VAR_HEAD + float *data; /*array of data (alias), wrapped status depends on wrapped status */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ +} BaseMathObject; + +PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * ); +PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * ); +void BaseMathObject_dealloc(BaseMathObject * self); + + + + PyObject *Mathutils_Init( const char * from ); -PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); -PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); PyObject *quat_rotation(PyObject *arg1, PyObject *arg2); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); @@ -49,8 +67,9 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); #define Py_PI 3.14159265358979323846 -#define Py_WRAP 1024 -#define Py_NEW 2048 + +#define Py_NEW 1 +#define Py_WRAP 2 /* Mathutils is used by the BGE and Blender so have to define @@ -65,4 +84,26 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #endif +typedef struct Mathutils_Callback Mathutils_Callback; +struct Mathutils_Callback { + int (*check)(PyObject *user); /* checks the user is still valid */ + int (*get)(PyObject *user, int subtype, float *from); /* gets the vector from the user */ + int (*set)(PyObject *user, int subtype, float *to); /* sets the users vector values once the vector is modified */ + int (*get_index)(PyObject *user, int subtype, float *from,int index); /* same as above but only for an index */ + int (*set_index)(PyObject *user, int subtype, float *to, int index); /* same as above but only for an index */ +}; + +int Mathutils_RegisterCallback(Mathutils_Callback *cb); + +int _BaseMathObject_ReadCallback(BaseMathObject *self); +int _BaseMathObject_WriteCallback(BaseMathObject *self); +int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index); +int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index); + +/* since this is called so often avoid where possible */ +#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):1)) +#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):1)) +#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1)) +#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1)) + #endif /* EXPP_Mathutils_H */ diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index 6789aea9c10..c41ea386c0e 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -1,5 +1,5 @@ /* - * $Id: bpy_internal_import.c 20434 2009-05-26 18:06:09Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 475ec8dd118..aeeafb7c1c4 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -1,5 +1,5 @@ /* - * $Id: bpy_internal_import.h 20434 2009-05-26 18:06:09Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/python/generic/euler.c b/source/blender/python/generic/euler.c index a65feb7e949..1e0632f4040 100644 --- a/source/blender/python/generic/euler.c +++ b/source/blender/python/generic/euler.c @@ -1,5 +1,5 @@ /* - * $Id: euler.c 20248 2009-05-18 04:11:54Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -34,13 +34,6 @@ //-------------------------DOC STRINGS --------------------------- -static char Euler_Zero_doc[] = "() - set all values in the euler to 0"; -static char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock"; -static char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation"; -static char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation"; -static char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation"; -static char Euler_copy_doc[] = "() - returns a copy of the euler."; -static char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping)."; static PyObject *Euler_Zero( EulerObject * self ); static PyObject *Euler_Unique( EulerObject * self ); @@ -52,25 +45,24 @@ static PyObject *Euler_copy( EulerObject * self, PyObject *args ); //-----------------------METHOD DEFINITIONS ---------------------- static struct PyMethodDef Euler_methods[] = { - {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc}, - {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc}, - {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc}, - {"toQuat", (PyCFunction) Euler_ToQuat, METH_NOARGS, Euler_ToQuat_doc}, - {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, Euler_Rotate_doc}, - {"makeCompatible", (PyCFunction) Euler_MakeCompatible, METH_O, Euler_MakeCompatible_doc}, - {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, - {"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, + {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, NULL}, + {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, NULL}, + {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, NULL}, + {"toQuat", (PyCFunction) Euler_ToQuat, METH_NOARGS, NULL}, + {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, NULL}, + {"makeCompatible", (PyCFunction) Euler_MakeCompatible, METH_O, NULL}, + {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, NULL}, + {"copy", (PyCFunction) Euler_copy, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; //----------------------------------Mathutils.Euler() ------------------- //makes a new euler for you to play with -static PyObject *Euler_new(PyObject * self, PyObject * args) +static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) { - PyObject *listObject = NULL; int size, i; - float eul[3], scalar; + float eul[3]; PyObject *e; size = PyTuple_GET_SIZE(args); @@ -84,7 +76,7 @@ static PyObject *Euler_new(PyObject * self, PyObject * args) } } else if (size == 0) { //returns a new empty 3d euler - return newEulerObject(NULL, Py_NEW); + return newEulerObject(NULL, Py_NEW, NULL); } else { listObject = args; } @@ -102,17 +94,15 @@ static PyObject *Euler_new(PyObject * self, PyObject * args) return NULL; } - scalar= (float)PyFloat_AsDouble(e); + eul[i]= (float)PyFloat_AsDouble(e); Py_DECREF(e); - if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number + if(eul[i]==-1 && PyErr_Occurred()) { // parsed item is not a number PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); return NULL; } - - eul[i]= scalar; } - return newEulerObject(eul, Py_NEW); + return newEulerObject(eul, Py_NEW, NULL); } //-----------------------------METHODS---------------------------- @@ -120,14 +110,25 @@ static PyObject *Euler_new(PyObject * self, PyObject * args) //return a quaternion representation of the euler static PyObject *Euler_ToQuat(EulerObject * self) { - float eul[3], quat[4]; + float quat[4]; +#ifdef USE_MATHUTILS_DEG + float eul[3]; int x; +#endif + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul[x] = self->eul[x] * ((float)Py_PI / 180); } EulToQuat(eul, quat); - return newQuaternionObject(quat, Py_NEW); +#else + EulToQuat(self->eul, quat); +#endif + + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------Euler.toMatrix()--------------------- //return a matrix representation of the euler @@ -137,60 +138,80 @@ static PyObject *Euler_ToMatrix(EulerObject * self) float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; int x; + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul[x] = self->eul[x] * ((float)Py_PI / 180); } EulToMat3(eul, (float (*)[3]) mat); - return newMatrixObject(mat, 3, 3 , Py_NEW); +#else + EulToMat3(self->eul, (float (*)[3]) mat); +#endif + return newMatrixObject(mat, 3, 3 , Py_NEW, NULL); } //----------------------------Euler.unique()----------------------- //sets the x,y,z values to a unique euler rotation static PyObject *Euler_Unique(EulerObject * self) { +#define PI_2 (Py_PI * 2.0) +#define PI_HALF (Py_PI / 2.0) +#define PI_INV (1.0 / Py_PI) + double heading, pitch, bank; - double pi2 = Py_PI * 2.0f; - double piO2 = Py_PI / 2.0f; - double Opi2 = 1.0f / pi2; + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG //radians heading = self->eul[0] * (float)Py_PI / 180; pitch = self->eul[1] * (float)Py_PI / 180; bank = self->eul[2] * (float)Py_PI / 180; +#else + heading = self->eul[0]; + pitch = self->eul[1]; + bank = self->eul[2]; +#endif //wrap heading in +180 / -180 pitch += Py_PI; - pitch -= floor(pitch * Opi2) * pi2; + pitch -= floor(pitch * PI_INV) * PI_2; pitch -= Py_PI; - if(pitch < -piO2) { + if(pitch < -PI_HALF) { pitch = -Py_PI - pitch; heading += Py_PI; bank += Py_PI; - } else if(pitch > piO2) { + } else if(pitch > PI_HALF) { pitch = Py_PI - pitch; heading += Py_PI; bank += Py_PI; } //gimbal lock test - if(fabs(pitch) > piO2 - 1e-4) { + if(fabs(pitch) > PI_HALF - 1e-4) { heading += bank; bank = 0.0f; } else { bank += Py_PI; - bank -= (floor(bank * Opi2)) * pi2; + bank -= (floor(bank * PI_INV)) * PI_2; bank -= Py_PI; } heading += Py_PI; - heading -= (floor(heading * Opi2)) * pi2; + heading -= (floor(heading * PI_INV)) * PI_2; heading -= Py_PI; +#ifdef USE_MATHUTILS_DEG //back to degrees self->eul[0] = (float)(heading * 180 / (float)Py_PI); self->eul[1] = (float)(pitch * 180 / (float)Py_PI); self->eul[2] = (float)(bank * 180 / (float)Py_PI); +#endif + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -202,6 +223,7 @@ static PyObject *Euler_Zero(EulerObject * self) self->eul[1] = 0.0; self->eul[2] = 0.0; + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -223,42 +245,63 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args) return NULL; } + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG //covert to radians angle *= ((float)Py_PI / 180); for(x = 0; x < 3; x++) { self->eul[x] *= ((float)Py_PI / 180); } +#endif euler_rot(self->eul, angle, *axis); + +#ifdef USE_MATHUTILS_DEG //convert back from radians for(x = 0; x < 3; x++) { self->eul[x] *= (180 / (float)Py_PI); } +#endif + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) { +#ifdef USE_MATHUTILS_DEG float eul_from_rad[3]; int x; +#endif if(!EulerObject_Check(value)) { PyErr_SetString(PyExc_TypeError, "euler.makeCompatible(euler):expected a single euler argument."); return NULL; } + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + +#ifdef USE_MATHUTILS_DEG //covert to radians for(x = 0; x < 3; x++) { self->eul[x] = self->eul[x] * ((float)Py_PI / 180); eul_from_rad[x] = value->eul[x] * ((float)Py_PI / 180); } compatible_eul(self->eul, eul_from_rad); +#else + compatible_eul(self->eul, value->eul); +#endif + +#ifdef USE_MATHUTILS_DEG //convert back from radians for(x = 0; x < 3; x++) { self->eul[x] *= (180 / (float)Py_PI); } - +#endif + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -267,19 +310,10 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) // return a copy of the euler static PyObject *Euler_copy(EulerObject * self, PyObject *args) { - return newEulerObject(self->eul, Py_NEW); -} - + if(!BaseMath_ReadCallback(self)) + return NULL; -//----------------------------dealloc()(internal) ------------------ -//free the py_object -static void Euler_dealloc(EulerObject * self) -{ - //only free py_data - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); + return newEulerObject(self->eul, Py_NEW, Py_TYPE(self)); } //----------------------------print object (internal)-------------- @@ -287,6 +321,10 @@ static void Euler_dealloc(EulerObject * self) static PyObject *Euler_repr(EulerObject * self) { char str[64]; + + if(!BaseMath_ReadCallback(self)) + return NULL; + sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]); return PyUnicode_FromString(str); } @@ -297,7 +335,18 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar EulerObject *eulA = NULL, *eulB = NULL; int result = 0; - if (!EulerObject_Check(objectA) || !EulerObject_Check(objectB)){ + if(EulerObject_Check(objectA)) { + eulA = (EulerObject*)objectA; + if(!BaseMath_ReadCallback(eulA)) + return NULL; + } + if(EulerObject_Check(objectB)) { + eulB = (EulerObject*)objectB; + if(!BaseMath_ReadCallback(eulB)) + return NULL; + } + + if (!eulA || !eulB){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; }else{ @@ -329,8 +378,7 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar Py_RETURN_FALSE; } } -//------------------------tp_doc -static char EulerObject_doc[] = "This is a wrapper for euler objects."; + //---------------------SEQUENCE PROTOCOLS------------------------ //----------------------------len(object)------------------------ //sequence length @@ -342,13 +390,16 @@ static int Euler_len(EulerObject * self) //sequence accessor (get) static PyObject *Euler_item(EulerObject * self, int i) { - if(i<0) - i= 3-i; + if(i<0) i= 3-i; if(i < 0 || i >= 3) { PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range"); return NULL; } + + if(!BaseMath_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->eul[i]); } @@ -363,8 +414,7 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value) return -1; } - if(i<0) - i= 3-i; + if(i<0) i= 3-i; if(i < 0 || i >= 3){ PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n"); @@ -372,6 +422,10 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value) } self->eul[i] = f; + + if(!BaseMath_WriteIndexCallback(self, i)) + return -1; + return 0; } //----------------------------object[z:y]------------------------ @@ -381,6 +435,9 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!BaseMath_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, 3); if (end<0) end= 4+end; CLAMP(end, 0, 3); @@ -401,7 +458,10 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end, { int i, y, size = 0; float eul[3]; - PyObject *e, *f; + PyObject *e; + + if(!BaseMath_ReadCallback(self)) + return -1; CLAMP(begin, 0, 3); if (end<0) end= 4+end; @@ -421,21 +481,20 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end, return -1; } - f = PyNumber_Float(e); - if(f == NULL) { // parsed item not a number - Py_DECREF(e); + eul[i] = (float)PyFloat_AsDouble(e); + Py_DECREF(e); + + if(eul[i]==-1 && PyErr_Occurred()) { // parsed item not a number PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number"); return -1; } - - eul[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(e); } //parsed well - now set in vector for(y = 0; y < 3; y++){ self->eul[begin + y] = eul[y]; } + + BaseMath_WriteCallback(self); return 0; } //-----------------PROTCOL DECLARATIONS-------------------------- @@ -450,79 +509,30 @@ static PySequenceMethods Euler_SeqMethods = { }; - /* * vector axis, vector.x/y/z/w */ static PyObject *Euler_getAxis( EulerObject * self, void *type ) { - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - return PyFloat_FromDouble(self->eul[0]); - case 'Y': - return PyFloat_FromDouble(self->eul[1]); - case 'Z': - return PyFloat_FromDouble(self->eul[2]); - } - - PyErr_SetString(PyExc_SystemError, "corrupt euler, cannot get axis"); - return NULL; + return Euler_item(self, GET_INT_FROM_POINTER(type)); } static int Euler_setAxis( EulerObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected a number for the vector axis"); - return -1; - } - - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - self->eul[0]= param; - break; - case 'Y': - self->eul[1]= param; - break; - case 'Z': - self->eul[2]= param; - break; - } - - return 0; -} - -static PyObject *Euler_getWrapped( VectorObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; + return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value); } - /*****************************************************************************/ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Euler_getseters[] = { - {"x", - (getter)Euler_getAxis, (setter)Euler_setAxis, - "Euler X axis", - (void *)'X'}, - {"y", - (getter)Euler_getAxis, (setter)Euler_setAxis, - "Euler Y axis", - (void *)'Y'}, - {"z", - (getter)Euler_getAxis, (setter)Euler_setAxis, - "Euler Z axis", - (void *)'Z'}, - {"wrapped", - (getter)Euler_getWrapped, (setter)NULL, - "True when this wraps blenders internal data", - NULL}, + {"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis", (void *)0}, + {"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis", (void *)1}, + {"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis", (void *)2}, + + {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -538,7 +548,7 @@ PyTypeObject euler_Type = { "euler", //tp_name sizeof(EulerObject), //tp_basicsize 0, //tp_itemsize - (destructor)Euler_dealloc, //tp_dealloc + (destructor)BaseMathObject_dealloc, //tp_dealloc 0, //tp_print 0, //tp_getattr 0, //tp_setattr @@ -553,8 +563,8 @@ PyTypeObject euler_Type = { 0, //tp_getattro 0, //tp_setattro 0, //tp_as_buffer - Py_TPFLAGS_DEFAULT, //tp_flags - EulerObject_doc, //tp_doc + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + 0, //tp_doc 0, //tp_traverse 0, //tp_clear (richcmpfunc)Euler_richcmpr, //tp_richcompare @@ -587,30 +597,29 @@ PyTypeObject euler_Type = { (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newEulerObject(float *eul, int type) +PyObject *newEulerObject(float *eul, int type, PyTypeObject *base_type) { EulerObject *self; int x; - self = PyObject_NEW(EulerObject, &euler_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; + if(base_type) self = base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(EulerObject, &euler_Type); + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP){ - self->data.blend_data = eul; - self->eul = self->data.blend_data; + self->eul = eul; self->wrapped = Py_WRAP; }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(3 * sizeof(float)); - self->eul = self->data.py_data; + self->eul = PyMem_Malloc(3 * sizeof(float)); if(!eul) { //new empty for(x = 0; x < 3; x++) { self->eul[x] = 0.0f; } }else{ - for(x = 0; x < 3; x++){ - self->eul[x] = eul[x]; - } + VECCOPY(self->eul, eul); } self->wrapped = Py_NEW; }else{ //bad type @@ -618,3 +627,16 @@ PyObject *newEulerObject(float *eul, int type) } return (PyObject *)self; } + +PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) +{ + EulerObject *self= (EulerObject *)newEulerObject(NULL, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return (PyObject *)self; +} diff --git a/source/blender/python/generic/euler.h b/source/blender/python/generic/euler.h index 3206668ffa0..a3706d53756 100644 --- a/source/blender/python/generic/euler.h +++ b/source/blender/python/generic/euler.h @@ -1,5 +1,5 @@ /* - * $Id: euler.h 20248 2009-05-18 04:11:54Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,17 +35,17 @@ #include "../intern/bpy_compat.h" extern PyTypeObject euler_Type; - -#define EulerObject_Check(v) (Py_TYPE(v) == &euler_Type) +#define EulerObject_Check(_v) PyObject_TypeCheck((_v), &euler_Type) typedef struct { PyObject_VAR_HEAD - struct{ - float *py_data; //python managed - float *blend_data; //blender managed - }data; - float *eul; //1D array of data (alias) - int wrapped; //is wrapped data? + float *eul; /*1D array of data */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ + /* end BaseMathObject */ + } EulerObject; /*struct data contains a pointer to the actual data that the @@ -54,6 +54,7 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *newEulerObject( float *eul, int type ); +PyObject *newEulerObject( float *eul, int type, PyTypeObject *base_type); +PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype); #endif /* EXPP_euler_h */ diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index e2ab1c3c653..5bdbf804618 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -1,5 +1,5 @@ /* - * $Id: matrix.c 20249 2009-05-18 04:27:48Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -31,19 +31,72 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); /* utility func */ + + +/* matrix vector callbacks */ +int mathutils_matrix_vector_cb_index= -1; + +static int mathutils_matrix_vector_check(MatrixObject *self) +{ + return BaseMath_ReadCallback(self); +} + +static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *vec_from) +{ + int i; + if(!BaseMath_ReadCallback(self)) + return 0; + + for(i=0; icolSize; i++) + vec_from[i]= self->matrix[subtype][i]; + + return 1; +} + +static int mathutils_matrix_vector_set(MatrixObject *self, int subtype, float *vec_to) +{ + int i; + if(!BaseMath_ReadCallback(self)) + return 0; + + for(i=0; icolSize; i++) + self->matrix[subtype][i]= vec_to[i]; + + BaseMath_WriteCallback(self); + return 1; +} + +static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, float *vec_from, int index) +{ + if(!BaseMath_ReadCallback(self)) + return 0; + + vec_from[index]= self->matrix[subtype][index]; + return 1; +} + +static int mathutils_matrix_vector_set_index(MatrixObject *self, int subtype, float *vec_to, int index) +{ + if(!BaseMath_ReadCallback(self)) + return 0; + + self->matrix[subtype][index]= vec_to[index]; + + BaseMath_WriteCallback(self); + return 1; +} + +Mathutils_Callback mathutils_matrix_vector_cb = { + mathutils_matrix_vector_check, + mathutils_matrix_vector_get, + mathutils_matrix_vector_set, + mathutils_matrix_vector_get_index, + mathutils_matrix_vector_set_index +}; +/* matrix vector callbacks, this is so you can do matrix[i][j] = val */ + /*-------------------------DOC STRINGS ---------------------------*/ -static char Matrix_Zero_doc[] = "() - set all values in the matrix to 0"; -static char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix"; -static char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose"; -static char Matrix_Determinant_doc[] = "() - return the determinant of the matrix"; -static char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible"; -static char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix"; -static char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix"; -static char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector"; -static char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix"; -static char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with."; -static char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation"; -static char Matrix_copy_doc[] = "() - return a copy of the matrix"; static PyObject *Matrix_Zero( MatrixObject * self ); static PyObject *Matrix_Identity( MatrixObject * self ); @@ -60,19 +113,19 @@ static PyObject *Matrix_copy( MatrixObject * self ); /*-----------------------METHOD DEFINITIONS ----------------------*/ static struct PyMethodDef Matrix_methods[] = { - {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, Matrix_Zero_doc}, - {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, Matrix_Identity_doc}, - {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, Matrix_Transpose_doc}, - {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, Matrix_Determinant_doc}, - {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, Matrix_Invert_doc}, - {"translationPart", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, Matrix_TranslationPart_doc}, - {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc}, - {"scalePart", (PyCFunction) Matrix_scalePart, METH_NOARGS, Matrix_scalePart_doc}, - {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc}, - {"toEuler", (PyCFunction) Matrix_toEuler, METH_VARARGS, Matrix_toEuler_doc}, - {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc}, - {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, - {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, + {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, NULL}, + {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, NULL}, + {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, NULL}, + {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, NULL}, + {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, NULL}, + {"translationPart", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, NULL}, + {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, NULL}, + {"scalePart", (PyCFunction) Matrix_scalePart, METH_NOARGS, NULL}, + {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, NULL}, + {"toEuler", (PyCFunction) Matrix_toEuler, METH_VARARGS, NULL}, + {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, NULL}, + {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, NULL}, + {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; @@ -93,18 +146,16 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); return NULL; } else if (argSize == 0) { //return empty 4D matrix - return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW); + return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW, NULL); }else if (argSize == 1){ //copy constructor for matrix objects argObject = PyTuple_GET_ITEM(args, 0); if(MatrixObject_Check(argObject)){ mat = (MatrixObject*)argObject; + if(!BaseMath_ReadCallback(mat)) + return NULL; - argSize = mat->rowSize; //rows - seqSize = mat->colSize; //col - for(i = 0; i < (seqSize * argSize); i++){ - matrix[i] = mat->contigPtr[i]; - } + memcpy(matrix, mat->contigPtr, sizeof(float) * mat->rowSize * mat->colSize); } }else{ //2-4 arguments (all seqs? all same size?) for(i =0; i < argSize; i++){ @@ -149,7 +200,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } } - return newMatrixObject(matrix, argSize, seqSize, Py_NEW); + return newMatrixObject(matrix, argSize, seqSize, Py_NEW, NULL); } /*-----------------------------METHODS----------------------------*/ @@ -158,6 +209,9 @@ static PyObject *Matrix_toQuat(MatrixObject * self) { float quat[4]; + if(!BaseMath_ReadCallback(self)) + return NULL; + /*must be 3-4 cols, 3-4 rows, square matrix*/ if(self->colSize < 3 || self->rowSize < 3 || (self->colSize != self->rowSize)) { PyErr_SetString(PyExc_AttributeError, "Matrix.toQuat(): inappropriate matrix size - expects 3x3 or 4x4 matrix"); @@ -169,22 +223,34 @@ static PyObject *Matrix_toQuat(MatrixObject * self) Mat4ToQuat((float (*)[4])*self->matrix, quat); } - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } /*---------------------------Matrix.toEuler() --------------------*/ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args) { float eul[3], eul_compatf[3]; EulerObject *eul_compat = NULL; +#ifdef USE_MATHUTILS_DEG int x; +#endif + + if(!BaseMath_ReadCallback(self)) + return NULL; if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat)) return NULL; if(eul_compat) { + if(!BaseMath_ReadCallback(eul_compat)) + return NULL; + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180); } +#else + VECCOPY(eul_compatf, eul_compat->eul); +#endif } /*must be 3-4 cols, 3-4 rows, square matrix*/ @@ -202,28 +268,33 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args) PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); return NULL; } +#ifdef USE_MATHUTILS_DEG /*have to convert to degrees*/ for(x = 0; x < 3; x++) { eul[x] *= (float) (180 / Py_PI); } - return newEulerObject(eul, Py_NEW); +#endif + return newEulerObject(eul, Py_NEW, NULL); } /*---------------------------Matrix.resize4x4() ------------------*/ PyObject *Matrix_Resize4x4(MatrixObject * self) { int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index; - if(self->data.blend_data){ - PyErr_SetString(PyExc_TypeError, "cannot resize wrapped data - only python matrices"); + if(self->wrapped==Py_WRAP){ + PyErr_SetString(PyExc_TypeError, "cannot resize wrapped data - make a copy and resize that"); return NULL; } - - self->data.py_data = PyMem_Realloc(self->data.py_data, (sizeof(float) * 16)); - if(self->data.py_data == NULL) { + if(self->cb_user){ + PyErr_SetString(PyExc_TypeError, "cannot resize owned data - make a copy and resize that"); + return NULL; + } + + self->contigPtr = PyMem_Realloc(self->contigPtr, (sizeof(float) * 16)); + if(self->contigPtr == NULL) { PyErr_SetString(PyExc_MemoryError, "matrix.resize4x4(): problem allocating pointer space"); return NULL; } - self->contigPtr = self->data.py_data; /*force*/ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float *) * 4)); if(self->matrix == NULL) { PyErr_SetString(PyExc_MemoryError, "matrix.resize4x4(): problem allocating pointer space"); @@ -266,7 +337,10 @@ PyObject *Matrix_Resize4x4(MatrixObject * self) PyObject *Matrix_TranslationPart(MatrixObject * self) { float vec[4]; - + + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->colSize < 3 || self->rowSize < 4){ PyErr_SetString(PyExc_AttributeError, "Matrix.translationPart: inappropriate matrix size"); return NULL; @@ -276,7 +350,7 @@ PyObject *Matrix_TranslationPart(MatrixObject * self) vec[1] = self->matrix[3][1]; vec[2] = self->matrix[3][2]; - return newVectorObject(vec, 3, Py_NEW); + return newVectorObject(vec, 3, Py_NEW, NULL); } /*---------------------------Matrix.rotationPart() ---------------*/ PyObject *Matrix_RotationPart(MatrixObject * self) @@ -284,6 +358,9 @@ PyObject *Matrix_RotationPart(MatrixObject * self) float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->colSize < 3 || self->rowSize < 3){ PyErr_SetString(PyExc_AttributeError, "Matrix.rotationPart: inappropriate matrix size\n"); return NULL; @@ -299,7 +376,7 @@ PyObject *Matrix_RotationPart(MatrixObject * self) mat[7] = self->matrix[2][1]; mat[8] = self->matrix[2][2]; - return newMatrixObject(mat, 3, 3, Py_NEW); + return newMatrixObject(mat, 3, 3, Py_NEW, Py_TYPE(self)); } /*---------------------------Matrix.scalePart() --------------------*/ PyObject *Matrix_scalePart(MatrixObject * self) @@ -307,6 +384,9 @@ PyObject *Matrix_scalePart(MatrixObject * self) float scale[3], rot[3]; float mat[3][3], imat[3][3], tmat[3][3]; + if(!BaseMath_ReadCallback(self)) + return NULL; + /*must be 3-4 cols, 3-4 rows, square matrix*/ if(self->colSize == 4 && self->rowSize == 4) Mat3CpyMat4(mat, (float (*)[4])*self->matrix); @@ -325,7 +405,7 @@ PyObject *Matrix_scalePart(MatrixObject * self) scale[0]= tmat[0][0]; scale[1]= tmat[1][1]; scale[2]= tmat[2][2]; - return newVectorObject(scale, 3, Py_NEW); + return newVectorObject(scale, 3, Py_NEW, NULL); } /*---------------------------Matrix.invert() ---------------------*/ PyObject *Matrix_Invert(MatrixObject * self) @@ -337,6 +417,9 @@ PyObject *Matrix_Invert(MatrixObject * self) float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.invert(ed): only square matrices are supported"); return NULL; @@ -377,6 +460,7 @@ PyObject *Matrix_Invert(MatrixObject * self) return NULL; } + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -387,6 +471,9 @@ PyObject *Matrix_Determinant(MatrixObject * self) { float det = 0.0f; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.determinant: only square matrices are supported"); return NULL; @@ -412,6 +499,9 @@ PyObject *Matrix_Transpose(MatrixObject * self) { float t = 0.0f; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.transpose(d): only square matrices are supported"); return NULL; @@ -427,6 +517,7 @@ PyObject *Matrix_Transpose(MatrixObject * self) Mat4Transp((float (*)[4])*self->matrix); } + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -436,18 +527,25 @@ PyObject *Matrix_Transpose(MatrixObject * self) PyObject *Matrix_Zero(MatrixObject * self) { int row, col; - + for(row = 0; row < self->rowSize; row++) { for(col = 0; col < self->colSize; col++) { self->matrix[row][col] = 0.0f; } } + + if(!BaseMath_WriteCallback(self)) + return NULL; + Py_INCREF(self); return (PyObject *)self; } /*---------------------------Matrix.identity(() ------------------*/ PyObject *Matrix_Identity(MatrixObject * self) { + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.identity: only square matrices are supported\n"); return NULL; @@ -464,6 +562,9 @@ PyObject *Matrix_Identity(MatrixObject * self) Mat4One((float (*)[4]) *self->matrix); } + if(!BaseMath_WriteCallback(self)) + return NULL; + Py_INCREF(self); return (PyObject *)self; } @@ -471,19 +572,10 @@ PyObject *Matrix_Identity(MatrixObject * self) /*---------------------------Matrix.inverted() ------------------*/ PyObject *Matrix_copy(MatrixObject * self) { - return (PyObject*)(MatrixObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW); -} - -/*----------------------------dealloc()(internal) ----------------*/ -/*free the py_object*/ -static void Matrix_dealloc(MatrixObject * self) -{ - PyMem_Free(self->matrix); - /*only free py_data*/ - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); + if(!BaseMath_ReadCallback(self)) + return NULL; + + return (PyObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self)); } /*----------------------------print object (internal)-------------*/ @@ -493,6 +585,9 @@ static PyObject *Matrix_repr(MatrixObject * self) int x, y; char buffer[48], str[1024]; + if(!BaseMath_ReadCallback(self)) + return NULL; + BLI_strncpy(str,"",1024); for(x = 0; x < self->rowSize; x++){ sprintf(buffer, "["); @@ -529,6 +624,9 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa matA = (MatrixObject*)objectA; matB = (MatrixObject*)objectB; + if(!BaseMath_ReadCallback(matA) || !BaseMath_ReadCallback(matB)) + return NULL; + if (matA->colSize != matB->colSize || matA->rowSize != matB->rowSize){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; @@ -562,8 +660,7 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa Py_RETURN_FALSE; } } -/*------------------------tp_doc*/ -static char MatrixObject_doc[] = "This is a wrapper for matrix objects."; + /*---------------------SEQUENCE PROTOCOLS------------------------ ----------------------------len(object)------------------------ sequence length*/ @@ -576,11 +673,14 @@ static int Matrix_len(MatrixObject * self) the wrapped vector gives direct access to the matrix data*/ static PyObject *Matrix_item(MatrixObject * self, int i) { + if(!BaseMath_ReadCallback(self)) + return NULL; + if(i < 0 || i >= self->rowSize) { PyErr_SetString(PyExc_IndexError, "matrix[attribute]: array index out of range"); return NULL; } - return newVectorObject(self->matrix[i], self->colSize, Py_WRAP); + return newVectorObject_cb((PyObject *)self, self->colSize, mathutils_matrix_vector_cb_index, i); } /*----------------------------object[]------------------------- sequence accessor (set)*/ @@ -590,6 +690,9 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) float vec[4]; PyObject *m, *f; + if(!BaseMath_ReadCallback(self)) + return -1; + if(i >= self->rowSize || i < 0){ PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad row\n"); return -1; @@ -623,6 +726,8 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) for(y = 0; y < size; y++){ self->matrix[i][y] = vec[y]; } + + BaseMath_WriteCallback(self); return 0; }else{ PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size\n"); @@ -636,6 +741,9 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end) PyObject *list = NULL; int count; + + if(!BaseMath_ReadCallback(self)) + return NULL; CLAMP(begin, 0, self->rowSize); CLAMP(end, 0, self->rowSize); @@ -644,21 +752,24 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end) list = PyList_New(end - begin); for(count = begin; count < end; count++) { PyList_SetItem(list, count - begin, - newVectorObject(self->matrix[count], self->colSize, Py_WRAP)); + newVectorObject_cb((PyObject *)self, self->colSize, mathutils_matrix_vector_cb_index, count)); + } return list; } /*----------------------------object[z:y]------------------------ sequence slice (set)*/ -static int Matrix_ass_slice(MatrixObject * self, int begin, int end, - PyObject * seq) +static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject * seq) { int i, x, y, size, sub_size = 0; float mat[16], f; PyObject *subseq; PyObject *m; + if(!BaseMath_ReadCallback(self)) + return -1; + CLAMP(begin, 0, self->rowSize); CLAMP(end, 0, self->rowSize); begin = MIN2(begin,end); @@ -716,6 +827,8 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, for(x = 0; x < (size * sub_size); x++){ self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x]; } + + BaseMath_WriteCallback(self); return 0; }else{ PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n"); @@ -738,6 +851,10 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2) PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); return NULL; } + + if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2)) + return NULL; + if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); return NULL; @@ -749,7 +866,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2) } } - return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL); } /*------------------------obj - obj------------------------------ subtraction*/ @@ -767,6 +884,10 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2) PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); return NULL; } + + if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2)) + return NULL; + if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); return NULL; @@ -778,7 +899,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2) } } - return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL); } /*------------------------obj * obj------------------------------ mulplication*/ @@ -791,8 +912,16 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) double dot = 0.0f; MatrixObject *mat1 = NULL, *mat2 = NULL; - if(MatrixObject_Check(m1)) mat1 = (MatrixObject*)m1; - if(MatrixObject_Check(m2)) mat2 = (MatrixObject*)m2; + if(MatrixObject_Check(m1)) { + mat1 = (MatrixObject*)m1; + if(!BaseMath_ReadCallback(mat1)) + return NULL; + } + if(MatrixObject_Check(m2)) { + mat2 = (MatrixObject*)m2; + if(!BaseMath_ReadCallback(mat2)) + return NULL; + } if(mat1 && mat2) { /*MATRIX * MATRIX*/ if(mat1->colSize != mat2->rowSize){ @@ -809,7 +938,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } } - return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW, NULL); } if(mat1==NULL){ @@ -820,7 +949,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y]; } } - return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW); + return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW, NULL); } PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); @@ -829,7 +958,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) else /* if(mat1) { */ { if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */ - return column_vector_multiplication(mat1, (VectorObject *)m2); + return column_vector_multiplication(mat1, (VectorObject *)m2); /* vector update done inside the function */ } else { scalar= PyFloat_AsDouble(m2); @@ -839,7 +968,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y]; } } - return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL); } } PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); @@ -851,6 +980,9 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } static PyObject* Matrix_inv(MatrixObject *self) { + if(!BaseMath_ReadCallback(self)) + return NULL; + return Matrix_Invert(self); } @@ -864,6 +996,123 @@ static PySequenceMethods Matrix_SeqMethods = { (ssizeobjargproc) Matrix_ass_item, /* sq_ass_item */ (ssizessizeobjargproc) Matrix_ass_slice, /* sq_ass_slice */ }; + + + +#if (PY_VERSION_HEX >= 0x03000000) +static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->rowSize; + return Matrix_item(self, i); + } else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->rowSize, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return Matrix_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + item->ob_type->tp_name); + return NULL; + } +} + +static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->rowSize; + return Matrix_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->rowSize, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return Matrix_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "matrix indices must be integers, not %.200s", + item->ob_type->tp_name); + return -1; + } +} + +static PyMappingMethods Matrix_AsMapping = { + (lenfunc)Matrix_len, + (binaryfunc)Matrix_subscript, + (objobjargproc)Matrix_ass_subscript +}; +#endif /* (PY_VERSION_HEX >= 0x03000000) */ + + + +#if (PY_VERSION_HEX >= 0x03000000) +static PyNumberMethods Matrix_NumMethods = { + (binaryfunc) Matrix_add, /*nb_add*/ + (binaryfunc) Matrix_sub, /*nb_subtract*/ + (binaryfunc) Matrix_mul, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + (unaryfunc) 0, /*nb_negative*/ + (unaryfunc) 0, /*tp_positive*/ + (unaryfunc) 0, /*tp_absolute*/ + (inquiry) 0, /*tp_bool*/ + (unaryfunc) Matrix_inv, /*nb_invert*/ + 0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; +#else static PyNumberMethods Matrix_NumMethods = { (binaryfunc) Matrix_add, /* __add__ */ (binaryfunc) Matrix_sub, /* __sub__ */ @@ -889,6 +1138,7 @@ static PyNumberMethods Matrix_NumMethods = { (unaryfunc) 0, /* __oct__ */ (unaryfunc) 0, /* __hex__ */ }; +#endif static PyObject *Matrix_getRowSize( MatrixObject * self, void *type ) { @@ -900,21 +1150,15 @@ static PyObject *Matrix_getColSize( MatrixObject * self, void *type ) return PyLong_FromLong((long) self->colSize); } -static PyObject *Matrix_getWrapped( MatrixObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - /*****************************************************************************/ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Matrix_getseters[] = { {"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL}, {"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL}, - {"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL}, + {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL}, + {"__owner__",(getter)BaseMathObject_getOwner, (setter)NULL, "", + NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -930,7 +1174,7 @@ PyTypeObject matrix_Type = { "matrix", /*tp_name*/ sizeof(MatrixObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor)Matrix_dealloc, /*tp_dealloc*/ + (destructor)BaseMathObject_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -938,15 +1182,19 @@ PyTypeObject matrix_Type = { (reprfunc) Matrix_repr, /*tp_repr*/ &Matrix_NumMethods, /*tp_as_number*/ &Matrix_SeqMethods, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ +#if (PY_VERSION_HEX >= 0x03000000) + &Matrix_AsMapping, /*tp_as_mapping*/ +#else + 0, +#endif 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - MatrixObject_doc, /*tp_doc*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/ @@ -984,13 +1232,13 @@ self->matrix self->contiguous_ptr (reference to data.xxx) [4] [5] .... -self->matrix[1][1] = self->contiguous_ptr[4] = self->data.xxx_data[4]*/ +self->matrix[1][1] = self->contigPtr[4] */ /*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) +PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type, PyTypeObject *base_type) { MatrixObject *self; int x, row, col; @@ -1001,15 +1249,18 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) return NULL; } - self = PyObject_NEW(MatrixObject, &matrix_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; + if(base_type) self = (MatrixObject *)base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(MatrixObject, &matrix_Type); + self->rowSize = rowSize; self->colSize = colSize; + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP){ - self->data.blend_data = mat; - self->contigPtr = self->data.blend_data; + self->contigPtr = mat; /*create pointer array*/ self->matrix = PyMem_Malloc(rowSize * sizeof(float *)); if(self->matrix == NULL) { /*allocation failure*/ @@ -1022,16 +1273,15 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) } self->wrapped = Py_WRAP; }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(rowSize * colSize * sizeof(float)); - if(self->data.py_data == NULL) { /*allocation failure*/ + self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float)); + if(self->contigPtr == NULL) { /*allocation failure*/ PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space\n"); return NULL; } - self->contigPtr = self->data.py_data; /*create pointer array*/ self->matrix = PyMem_Malloc(rowSize * sizeof(float *)); if(self->matrix == NULL) { /*allocation failure*/ - PyMem_Free(self->data.py_data); + PyMem_Free(self->contigPtr); PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space"); return NULL; } @@ -1056,3 +1306,53 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) } return (PyObject *) self; } + +PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb_type, int cb_subtype) +{ + MatrixObject *self= (MatrixObject *)newMatrixObject(NULL, rowSize, colSize, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + return (PyObject *) self; +} + +//----------------column_vector_multiplication (internal)--------- +//COLUMN VECTOR Multiplication (Matrix X Vector) +// [1][2][3] [a] +// [4][5][6] * [b] +// [7][8][9] [c] +//vector/matrix multiplication IS NOT COMMUTATIVE!!!! +static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) +{ + float vecNew[4], vecCopy[4]; + double dot = 0.0f; + int x, y, z = 0; + + if(!BaseMath_ReadCallback(mat) || !BaseMath_ReadCallback(vec)) + return NULL; + + if(mat->rowSize != vec->size){ + if(mat->rowSize == 4 && vec->size != 3){ + PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same"); + return NULL; + }else{ + vecCopy[3] = 1.0f; + } + } + + for(x = 0; x < vec->size; x++){ + vecCopy[x] = vec->vec[x]; + } + + for(x = 0; x < mat->rowSize; x++) { + for(y = 0; y < mat->colSize; y++) { + dot += mat->matrix[x][y] * vecCopy[y]; + } + vecNew[z++] = (float)dot; + dot = 0.0f; + } + return newVectorObject(vecNew, vec->size, Py_NEW, NULL); +} diff --git a/source/blender/python/generic/matrix.h b/source/blender/python/generic/matrix.h index ef82263fe00..856c711c4ef 100644 --- a/source/blender/python/generic/matrix.h +++ b/source/blender/python/generic/matrix.h @@ -1,5 +1,5 @@ /* - * $Id: matrix.h 20248 2009-05-18 04:11:54Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -33,21 +33,22 @@ #include extern PyTypeObject matrix_Type; - -#define MatrixObject_Check(v) ((v)->ob_type == &matrix_Type) +#define MatrixObject_Check(_v) PyObject_TypeCheck((_v), &matrix_Type) typedef float **ptRow; -typedef struct _Matrix { - PyObject_VAR_HEAD - struct{ - float *py_data; /*python managed*/ - float *blend_data; /*blender managed*/ - }data; - ptRow matrix; /*ptr to the contigPtr (accessor)*/ - float *contigPtr; /*1D array of data (alias)*/ - int rowSize; - int colSize; - int wrapped; /*is wrapped data?*/ +typedef struct _Matrix { /* keep aligned with BaseMathObject in Mathutils.h */ + PyObject_VAR_HEAD + float *contigPtr; /*1D array of data (alias)*/ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /*is wrapped data?*/ + /* end BaseMathObject */ + + unsigned char rowSize; + unsigned int colSize; + ptRow matrix; /*ptr to the contigPtr (accessor)*/ + } MatrixObject; /*struct data contains a pointer to the actual data that the @@ -56,6 +57,10 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ /*prototypes*/ -PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type); +PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type, PyTypeObject *base_type); +PyObject *newMatrixObject_cb(PyObject *user, int rowSize, int colSize, int cb_type, int cb_subtype); + +extern int mathutils_matrix_vector_cb_index; +extern struct Mathutils_Callback mathutils_matrix_vector_cb; #endif /* EXPP_matrix_H */ diff --git a/source/blender/python/generic/quat.c b/source/blender/python/generic/quat.c index 4ad5d07b3b8..81d69834469 100644 --- a/source/blender/python/generic/quat.c +++ b/source/blender/python/generic/quat.c @@ -1,5 +1,5 @@ /* - * $Id: quat.c 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -34,16 +34,6 @@ //-------------------------DOC STRINGS --------------------------- -static char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)"; -static char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative"; -static char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate"; -static char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse"; -static char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion"; -static char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with."; -static char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion"; -static char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another"; -static char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another"; -static char Quaternion_copy_doc[] = "() - return a copy of the quat"; static PyObject *Quaternion_Identity( QuaternionObject * self ); static PyObject *Quaternion_Negate( QuaternionObject * self ); @@ -58,27 +48,27 @@ static PyObject *Quaternion_copy( QuaternionObject * self ); //-----------------------METHOD DEFINITIONS ---------------------- static struct PyMethodDef Quaternion_methods[] = { - {"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, Quaternion_Identity_doc}, - {"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, Quaternion_Negate_doc}, - {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc}, - {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, Quaternion_Inverse_doc}, - {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, Quaternion_Normalize_doc}, - {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, Quaternion_ToEuler_doc}, - {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, Quaternion_ToMatrix_doc}, - {"cross", (PyCFunction) Quaternion_Cross, METH_O, Quaternion_Cross_doc}, - {"dot", (PyCFunction) Quaternion_Dot, METH_O, Quaternion_Dot_doc}, - {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, - {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, + {"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, NULL}, + {"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, NULL}, + {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, NULL}, + {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, NULL}, + {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, NULL}, + {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, NULL}, + {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, NULL}, + {"cross", (PyCFunction) Quaternion_Cross, METH_O, NULL}, + {"dot", (PyCFunction) Quaternion_Dot, METH_O, NULL}, + {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, NULL}, + {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; //----------------------------------Mathutils.Quaternion() -------------- static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *listObject = NULL, *n, *q, *f; + PyObject *listObject = NULL, *n, *q; int size, i; - float quat[4], scalar; - double norm = 0.0f, angle = 0.0f; + float quat[4]; + double angle = 0.0f; size = PyTuple_GET_SIZE(args); if (size == 1 || size == 2) { //seq? @@ -127,7 +117,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw } } } else if (size == 0) { //returns a new empty quat - return newQuaternionObject(NULL, Py_NEW); + return newQuaternionObject(NULL, Py_NEW, NULL); } else { listObject = args; } @@ -151,31 +141,23 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw return NULL; } - scalar = PyFloat_AsDouble(q); - if (scalar==-1 && PyErr_Occurred()) { - Py_DECREF(q); + quat[i] = PyFloat_AsDouble(q); + Py_DECREF(q); + + if (quat[i]==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); return NULL; } - - quat[i] = scalar; - Py_DECREF(f); - Py_DECREF(q); - } - if(size == 3){ //calculate the quat based on axis/angle - norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]); - quat[0] /= (float)norm; - quat[1] /= (float)norm; - quat[2] /= (float)norm; - - angle = angle * (Py_PI / 180); - quat[3] =(float) (sin(angle/ 2.0f)) * quat[2]; - quat[2] =(float) (sin(angle/ 2.0f)) * quat[1]; - quat[1] =(float) (sin(angle/ 2.0f)) * quat[0]; - quat[0] =(float) (cos(angle/ 2.0f)); } - return newQuaternionObject(quat, Py_NEW); + if(size == 3) //calculate the quat based on axis/angle +#ifdef USE_MATHUTILS_DEG + AxisAngleToQuat(quat, quat, angle * (Py_PI / 180)); +#else + AxisAngleToQuat(quat, quat, angle); +#endif + + return newQuaternionObject(quat, Py_NEW, NULL); } //-----------------------------METHODS------------------------------ @@ -190,34 +172,48 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat)) return NULL; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(eul_compat) { float mat[3][3], eul_compatf[3]; + if(!BaseMath_ReadCallback(eul_compat)) + return NULL; + + QuatToMat3(self->quat, mat); + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180); } - - QuatToMat3(self->quat, mat); Mat3ToCompatibleEul(mat, eul, eul_compatf); +#else + Mat3ToCompatibleEul(mat, eul, eul_compat->eul); +#endif } else { QuatToEul(self->quat, eul); } - +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul[x] *= (180 / (float)Py_PI); } - return newEulerObject(eul, Py_NEW); +#endif + return newEulerObject(eul, Py_NEW, NULL); } //----------------------------Quaternion.toMatrix()------------------ //return the quat as a matrix static PyObject *Quaternion_ToMatrix(QuaternionObject * self) { - float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; - QuatToMat3(self->quat, (float (*)[3]) mat); + float mat[9]; /* all values are set */ - return newMatrixObject(mat, 3, 3, Py_NEW); + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatToMat3(self->quat, (float (*)[3]) mat); + return newMatrixObject(mat, 3, 3, Py_NEW, NULL); } //----------------------------Quaternion.cross(other)------------------ @@ -231,33 +227,38 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va return NULL; } + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + QuatMul(quat, self->quat, value->quat); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------Quaternion.dot(other)------------------ //return the dot quat static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value) { - int x; - double dot = 0.0; - if (!QuaternionObject_Check(value)) { PyErr_SetString( PyExc_TypeError, "quat.dot(value): expected a quaternion argument" ); return NULL; } - - for(x = 0; x < 4; x++) { - dot += self->quat[x] * value->quat[x]; - } - return PyFloat_FromDouble(dot); + + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + + return PyFloat_FromDouble(QuatDot(self->quat, value->quat)); } //----------------------------Quaternion.normalize()---------------- //normalize the axis of rotation of [theta,vector] static PyObject *Quaternion_Normalize(QuaternionObject * self) { + if(!BaseMath_ReadCallback(self)) + return NULL; + NormalQuat(self->quat); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -265,20 +266,12 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self) //invert the quat static PyObject *Quaternion_Inverse(QuaternionObject * self) { - double mag = 0.0f; - int x; + if(!BaseMath_ReadCallback(self)) + return NULL; - for(x = 1; x < 4; x++) { - self->quat[x] = -self->quat[x]; - } - for(x = 0; x < 4; x++) { - mag += (self->quat[x] * self->quat[x]); - } - mag = sqrt(mag); - for(x = 0; x < 4; x++) { - self->quat[x] /= (float)(mag * mag); - } + QuatInv(self->quat); + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -286,11 +279,12 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self) //generate the identity quaternion static PyObject *Quaternion_Identity(QuaternionObject * self) { - self->quat[0] = 1.0; - self->quat[1] = 0.0; - self->quat[2] = 0.0; - self->quat[3] = 0.0; + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatOne(self->quat); + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -298,10 +292,12 @@ static PyObject *Quaternion_Identity(QuaternionObject * self) //negate the quat static PyObject *Quaternion_Negate(QuaternionObject * self) { - int x; - for(x = 0; x < 4; x++) { - self->quat[x] = -self->quat[x]; - } + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatMulf(self->quat, -1.0f); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -309,10 +305,12 @@ static PyObject *Quaternion_Negate(QuaternionObject * self) //negate the vector part static PyObject *Quaternion_Conjugate(QuaternionObject * self) { - int x; - for(x = 1; x < 4; x++) { - self->quat[x] = -self->quat[x]; - } + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatConj(self->quat); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -320,18 +318,10 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self) //return a copy of the quat static PyObject *Quaternion_copy(QuaternionObject * self) { - return newQuaternionObject(self->quat, Py_NEW); -} + if(!BaseMath_ReadCallback(self)) + return NULL; -//----------------------------dealloc()(internal) ------------------ -//free the py_object -static void Quaternion_dealloc(QuaternionObject * self) -{ - //only free py_data - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); + return newQuaternionObject(self->quat, Py_NEW, Py_TYPE(self)); } //----------------------------print object (internal)-------------- @@ -339,6 +329,10 @@ static void Quaternion_dealloc(QuaternionObject * self) static PyObject *Quaternion_repr(QuaternionObject * self) { char str[64]; + + if(!BaseMath_ReadCallback(self)) + return NULL; + sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]); return PyUnicode_FromString(str); } @@ -349,15 +343,24 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c QuaternionObject *quatA = NULL, *quatB = NULL; int result = 0; - if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){ + if(QuaternionObject_Check(objectA)) { + quatA = (QuaternionObject*)objectA; + if(!BaseMath_ReadCallback(quatA)) + return NULL; + } + if(QuaternionObject_Check(objectB)) { + quatB = (QuaternionObject*)objectB; + if(!BaseMath_ReadCallback(quatB)) + return NULL; + } + + if (!quatA || !quatB){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; }else{ Py_RETURN_FALSE; } } - quatA = (QuaternionObject*)objectA; - quatB = (QuaternionObject*)objectB; switch (comparison_type){ case Py_EQ: @@ -381,8 +384,7 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c Py_RETURN_FALSE; } } -//------------------------tp_doc -static char QuaternionObject_doc[] = "This is a wrapper for quaternion objects."; + //---------------------SEQUENCE PROTOCOLS------------------------ //----------------------------len(object)------------------------ //sequence length @@ -394,10 +396,16 @@ static int Quaternion_len(QuaternionObject * self) //sequence accessor (get) static PyObject *Quaternion_item(QuaternionObject * self, int i) { + if(i<0) i= 4-i; + if(i < 0 || i >= 4) { PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range\n"); return NULL; } + + if(!BaseMath_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->quat[i]); } @@ -405,21 +413,23 @@ static PyObject *Quaternion_item(QuaternionObject * self, int i) //sequence accessor (set) static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob) { - PyObject *f = NULL; - - f = PyNumber_Float(ob); - if(f == NULL) { // parsed item not a number - PyErr_SetString(PyExc_TypeError, "quaternion[attribute] = x: argument not a number\n"); + float scalar= (float)PyFloat_AsDouble(ob); + if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ + PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: index argument not a number\n"); return -1; } + if(i<0) i= 4-i; + if(i < 0 || i >= 4){ - Py_DECREF(f); PyErr_SetString(PyExc_IndexError, "quaternion[attribute] = x: array assignment index out of range\n"); return -1; } - self->quat[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + self->quat[i] = scalar; + + if(!BaseMath_WriteIndexCallback(self, i)) + return -1; + return 0; } //----------------------------object[z:y]------------------------ @@ -429,6 +439,9 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!BaseMath_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, 4); if (end<0) end= 5+end; CLAMP(end, 0, 4); @@ -444,12 +457,14 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end) } //----------------------------object[z:y]------------------------ //sequence slice (set) -static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, - PyObject * seq) +static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, PyObject * seq) { int i, y, size = 0; float quat[4]; - PyObject *q, *f; + PyObject *q; + + if(!BaseMath_ReadCallback(self)) + return -1; CLAMP(begin, 0, 4); if (end<0) end= 5+end; @@ -469,21 +484,19 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, return -1; } - f = PyNumber_Float(q); - if(f == NULL) { // parsed item not a number - Py_DECREF(q); + quat[i]= (float)PyFloat_AsDouble(q); + Py_DECREF(q); + + if(quat[i]==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: sequence argument not a number\n"); return -1; } - - quat[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(q); } //parsed well - now set in vector - for(y = 0; y < size; y++){ + for(y = 0; y < size; y++) self->quat[begin + y] = quat[y]; - } + + BaseMath_WriteCallback(self); return 0; } //------------------------NUMERIC PROTOCOLS---------------------- @@ -491,7 +504,6 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, //addition static PyObject *Quaternion_add(PyObject * q1, PyObject * q2) { - int x; float quat[4]; QuaternionObject *quat1 = NULL, *quat2 = NULL; @@ -499,15 +511,14 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2) PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n"); return NULL; } - quat1 = (QuaternionObject*)q1; quat2 = (QuaternionObject*)q2; - for(x = 0; x < 4; x++) { - quat[x] = quat1->quat[x] + quat2->quat[x]; - } + if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2)) + return NULL; - return newQuaternionObject(quat, Py_NEW); + QuatAdd(quat, quat1->quat, quat2->quat, 1.0f); + return newQuaternionObject(quat, Py_NEW, NULL); } //------------------------obj - obj------------------------------ //subtraction @@ -525,40 +536,45 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2) quat1 = (QuaternionObject*)q1; quat2 = (QuaternionObject*)q2; + if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2)) + return NULL; + for(x = 0; x < 4; x++) { quat[x] = quat1->quat[x] - quat2->quat[x]; } - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //------------------------obj * obj------------------------------ //mulplication static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) { - int x; float quat[4], scalar; - double dot = 0.0f; QuaternionObject *quat1 = NULL, *quat2 = NULL; VectorObject *vec = NULL; - quat1 = (QuaternionObject*)q1; - quat2 = (QuaternionObject*)q2; + if(QuaternionObject_Check(q1)) { + quat1 = (QuaternionObject*)q1; + if(!BaseMath_ReadCallback(quat1)) + return NULL; + } + if(QuaternionObject_Check(q2)) { + quat2 = (QuaternionObject*)q2; + if(!BaseMath_ReadCallback(quat2)) + return NULL; + } - if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */ - for(x = 0; x < 4; x++) { - dot += quat1->quat[x] * quat1->quat[x]; - } - return PyFloat_FromDouble(dot); + if(quat1 && quat2) { /* QUAT*QUAT (dot product) */ + return PyFloat_FromDouble(QuatDot(quat1->quat, quat2->quat)); } /* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */ if(!QuaternionObject_Check(q1)) { scalar= PyFloat_AsDouble(q1); if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */ - for(x = 0; x < 4; x++) { - quat[x] = quat2->quat[x] * scalar; - } - return newQuaternionObject(quat, Py_NEW); + QUATCOPY(quat, quat2->quat); + QuatMulf(quat, scalar); + return newQuaternionObject(quat, Py_NEW, NULL); } PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type"); return NULL; @@ -570,15 +586,14 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n"); return NULL; } - return quat_rotation((PyObject*)quat1, (PyObject*)vec); + return quat_rotation((PyObject*)quat1, (PyObject*)vec); /* vector updating done inside the func */ } scalar= PyFloat_AsDouble(q2); if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */ - for(x = 0; x < 4; x++) { - quat[x] = quat1->quat[x] * scalar; - } - return newQuaternionObject(quat, Py_NEW); + QUATCOPY(quat, quat1->quat); + QuatMulf(quat, scalar); + return newQuaternionObject(quat, Py_NEW, NULL); } } @@ -596,6 +611,45 @@ static PySequenceMethods Quaternion_SeqMethods = { (ssizeobjargproc) Quaternion_ass_item, /* sq_ass_item */ (ssizessizeobjargproc) Quaternion_ass_slice, /* sq_ass_slice */ }; + +#if (PY_VERSION_HEX >= 0x03000000) +static PyNumberMethods Quaternion_NumMethods = { + (binaryfunc) Quaternion_add, /*nb_add*/ + (binaryfunc) Quaternion_sub, /*nb_subtract*/ + (binaryfunc) Quaternion_mul, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + (unaryfunc) 0, /*nb_negative*/ + (unaryfunc) 0, /*tp_positive*/ + (unaryfunc) 0, /*tp_absolute*/ + (inquiry) 0, /*tp_bool*/ + (unaryfunc) 0, /*nb_invert*/ + 0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; +#else static PyNumberMethods Quaternion_NumMethods = { (binaryfunc) Quaternion_add, /* __add__ */ (binaryfunc) Quaternion_sub, /* __sub__ */ @@ -620,76 +674,31 @@ static PyNumberMethods Quaternion_NumMethods = { (unaryfunc) 0, /* __float__ */ (unaryfunc) 0, /* __oct__ */ (unaryfunc) 0, /* __hex__ */ - }; - +#endif static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type ) { - switch( (long)type ) { - case 'W': - return PyFloat_FromDouble(self->quat[0]); - case 'X': - return PyFloat_FromDouble(self->quat[1]); - case 'Y': - return PyFloat_FromDouble(self->quat[2]); - case 'Z': - return PyFloat_FromDouble(self->quat[3]); - } - - PyErr_SetString(PyExc_SystemError, "corrupt quaternion, cannot get axis"); - return NULL; + return Quaternion_item(self, GET_INT_FROM_POINTER(type)); } static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); - return -1; - } - switch( (long)type ) { - case 'W': - self->quat[0]= param; - break; - case 'X': - self->quat[1]= param; - break; - case 'Y': - self->quat[2]= param; - break; - case 'Z': - self->quat[3]= param; - break; - } - - return 0; -} - -static PyObject *Quaternion_getWrapped( QuaternionObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; + return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value); } static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type ) { - double mag = 0.0; - int i; - for(i = 0; i < 4; i++) { - mag += self->quat[i] * self->quat[i]; - } - return PyFloat_FromDouble(sqrt(mag)); + return PyFloat_FromDouble(sqrt(QuatDot(self->quat, self->quat))); } static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type ) { double ang = self->quat[0]; ang = 2 * (saacos(ang)); +#ifdef USE_MATHUTILS_DEG ang *= (180 / Py_PI); +#endif return PyFloat_FromDouble(ang); } @@ -710,7 +719,7 @@ static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type ) EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){ vec[0] = 1.0f; } - return (PyObject *) newVectorObject(vec, 3, Py_NEW); + return (PyObject *) newVectorObject(vec, 3, Py_NEW, NULL); } @@ -721,19 +730,19 @@ static PyGetSetDef Quaternion_getseters[] = { {"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value", - (void *)'W'}, + (void *)0}, {"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis", - (void *)'X'}, + (void *)1}, {"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis", - (void *)'Y'}, + (void *)2}, {"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis", - (void *)'Z'}, + (void *)3}, {"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion", @@ -747,9 +756,14 @@ static PyGetSetDef Quaternion_getseters[] = { "quaternion axis as a vector", NULL}, {"wrapped", - (getter)Quaternion_getWrapped, (setter)NULL, + (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", + (getter)BaseMathObject_getOwner, (setter)NULL, + "Read only owner for vectors that depend on another object", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -766,7 +780,7 @@ PyTypeObject quaternion_Type = { "quaternion", //tp_name sizeof(QuaternionObject), //tp_basicsize 0, //tp_itemsize - (destructor)Quaternion_dealloc, //tp_dealloc + (destructor)BaseMathObject_dealloc, //tp_dealloc 0, //tp_print 0, //tp_getattr 0, //tp_setattr @@ -781,8 +795,8 @@ PyTypeObject quaternion_Type = { 0, //tp_getattro 0, //tp_setattro 0, //tp_as_buffer - Py_TPFLAGS_DEFAULT, //tp_flags - QuaternionObject_doc, //tp_doc + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + 0, //tp_doc 0, //tp_traverse 0, //tp_clear (richcmpfunc)Quaternion_richcmpr, //tp_richcompare @@ -815,29 +829,26 @@ PyTypeObject quaternion_Type = { (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newQuaternionObject(float *quat, int type) +PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type) { QuaternionObject *self; - int x; - self = PyObject_NEW(QuaternionObject, &quaternion_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; + if(base_type) self = base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(QuaternionObject, &quaternion_Type); + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP){ - self->data.blend_data = quat; - self->quat = self->data.blend_data; + self->quat = quat; self->wrapped = Py_WRAP; }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(4 * sizeof(float)); - self->quat = self->data.py_data; + self->quat = PyMem_Malloc(4 * sizeof(float)); if(!quat) { //new empty - Quaternion_Identity(self); - Py_DECREF(self); + QuatOne(self->quat); }else{ - for(x = 0; x < 4; x++){ - self->quat[x] = quat[x]; - } + QUATCOPY(self->quat, quat); } self->wrapped = Py_NEW; }else{ //bad type @@ -845,3 +856,16 @@ PyObject *newQuaternionObject(float *quat, int type) } return (PyObject *) self; } + +PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) +{ + QuaternionObject *self= (QuaternionObject *)newQuaternionObject(NULL, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return (PyObject *)self; +} diff --git a/source/blender/python/generic/quat.h b/source/blender/python/generic/quat.h index cfb50e4dbe1..a7cfb7898b1 100644 --- a/source/blender/python/generic/quat.h +++ b/source/blender/python/generic/quat.h @@ -1,5 +1,5 @@ /* - * $Id: quat.h 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,17 +35,17 @@ #include "../intern/bpy_compat.h" extern PyTypeObject quaternion_Type; +#define QuaternionObject_Check(_v) PyObject_TypeCheck((_v), &quaternion_Type) -#define QuaternionObject_Check(v) (Py_TYPE(v) == &quaternion_Type) - -typedef struct { +typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */ PyObject_VAR_HEAD - struct{ - float *py_data; //python managed - float *blend_data; //blender managed - }data; - float *quat; //1D array of data (alias) - int wrapped; //is wrapped data? + float *quat; /* 1D array of data (alias) */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ + /* end BaseMathObject */ + } QuaternionObject; /*struct data contains a pointer to the actual data that the @@ -54,6 +54,7 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *newQuaternionObject( float *quat, int type ); +PyObject *newQuaternionObject( float *quat, int type, PyTypeObject *base_type); +PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype); #endif /* EXPP_quat_h */ diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index 562413c6967..b4c74787e05 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -1,5 +1,5 @@ /* - * $Id: vector.c 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -39,19 +39,8 @@ #define SWIZZLE_VALID_AXIS 0x4 #define SWIZZLE_AXIS 0x3 -/*-------------------------DOC STRINGS ---------------------------*/ -static char Vector_Zero_doc[] = "() - set all values in the vector to 0"; -static char Vector_Normalize_doc[] = "() - normalize the vector"; -static char Vector_Negate_doc[] = "() - changes vector to it's additive inverse"; -static char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; -static char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; -static char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; -static char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; -static char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; -static char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another"; -static char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another"; -static char Vector_copy_doc[] = "() - return a copy of the vector"; -static char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order"; +static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); /* utility func */ + /*-----------------------METHOD DEFINITIONS ----------------------*/ static PyObject *Vector_Zero( VectorObject * self ); static PyObject *Vector_Normalize( VectorObject * self ); @@ -60,24 +49,24 @@ static PyObject *Vector_Resize2D( VectorObject * self ); static PyObject *Vector_Resize3D( VectorObject * self ); static PyObject *Vector_Resize4D( VectorObject * self ); static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); -static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ); +static PyObject *Vector_Reflect( VectorObject *self, VectorObject *value ); static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ); static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ); static PyObject *Vector_copy( VectorObject * self ); static struct PyMethodDef Vector_methods[] = { - {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc}, - {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc}, - {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc}, - {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, - {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, - {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc}, - {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Dot_doc}, - {"dot", ( PyCFunction ) Vector_Dot, METH_O, Vector_Cross_doc}, - {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, - {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, + {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, NULL}, + {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, NULL}, + {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, NULL}, + {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, NULL}, + {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, NULL}, + {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, NULL}, + {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, NULL}, + {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, NULL}, + {"cross", ( PyCFunction ) Vector_Cross, METH_O, NULL}, + {"dot", ( PyCFunction ) Vector_Dot, METH_O, NULL}, + {"copy", (PyCFunction) Vector_copy, METH_NOARGS, NULL}, + {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; @@ -102,7 +91,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } else if (size == 0) { //returns a new empty 3d vector - return newVectorObject(NULL, 3, Py_NEW); + return newVectorObject(NULL, 3, Py_NEW, type); } else { listObject = args; } @@ -129,7 +118,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) vec[i]= f; Py_DECREF(v); } - return newVectorObject(vec, size, Py_NEW); + return newVectorObject(vec, size, Py_NEW, type); } /*-----------------------------METHODS---------------------------- */ @@ -141,6 +130,8 @@ static PyObject *Vector_Zero(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] = 0.0f; } + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -151,6 +142,9 @@ static PyObject *Vector_Normalize(VectorObject * self) int i; float norm = 0.0f; + if(!BaseMath_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++) { norm += self->vec[i] * self->vec[i]; } @@ -158,6 +152,8 @@ static PyObject *Vector_Normalize(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] /= norm; } + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -171,6 +167,11 @@ static PyObject *Vector_Resize2D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize2d(): problem allocating pointer space\n\n"); @@ -189,6 +190,11 @@ static PyObject *Vector_Resize3D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize3d(): problem allocating pointer space\n\n"); @@ -210,6 +216,11 @@ static PyObject *Vector_Resize4D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize4d(): problem allocating pointer space\n\n"); @@ -241,6 +252,9 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only for 3D vectors\n" ); return NULL; } + + if(!BaseMath_ReadCallback(self)) + return NULL; if (strack) { if (strlen(strack) == 2) { @@ -335,16 +349,15 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) vectoquat(vec, track, up, quat); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } /*----------------------------Vector.reflect(mirror) ---------------------- return a reflected vector on the mirror normal ((2 * DotVecs(vec, mirror)) * mirror) - vec using arithb.c would be nice here */ -static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) +static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value ) { - VectorObject *mirrvec; float mirror[3]; float vec[3]; float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -358,11 +371,13 @@ static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" ); return NULL; } - mirrvec = (VectorObject *)value; - mirror[0] = mirrvec->vec[0]; - mirror[1] = mirrvec->vec[1]; - if (mirrvec->size > 2) mirror[2] = mirrvec->vec[2]; + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + + mirror[0] = value->vec[0]; + mirror[1] = value->vec[1]; + if (value->size > 2) mirror[2] = value->vec[2]; else mirror[2] = 0.0; /* normalize, whos idea was it not to use arithb.c? :-/ */ @@ -386,7 +401,7 @@ static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) reflect[1] = (dot2 * mirror[1]) - vec[1]; reflect[2] = (dot2 * mirror[2]) - vec[2]; - return newVectorObject(reflect, self->size, Py_NEW); + return newVectorObject(reflect, self->size, Py_NEW, NULL); } static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) @@ -403,7 +418,10 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) return NULL; } - vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW); + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + + vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW, NULL); Crossf(vecCross->vec, self->vec, value->vec); return (PyObject *)vecCross; } @@ -423,6 +441,9 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) return NULL; } + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + for(x = 0; x < self->size; x++) { dot += self->vec[x] * value->vec[x]; } @@ -433,18 +454,10 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) return a copy of the vector */ static PyObject *Vector_copy(VectorObject * self) { - return newVectorObject(self->vec, self->size, Py_NEW); -} - -/*----------------------------dealloc()(internal) ---------------- - free the py_object */ -static void Vector_dealloc(VectorObject * self) -{ - /* only free non wrapped */ - if(self->wrapped != Py_WRAP){ - PyMem_Free(self->vec); - } - PyObject_DEL(self); + if(!BaseMath_ReadCallback(self)) + return NULL; + + return newVectorObject(self->vec, self->size, Py_NEW, Py_TYPE(self)); } /*----------------------------print object (internal)------------- @@ -454,6 +467,9 @@ static PyObject *Vector_repr(VectorObject * self) int i; char buffer[48], str[1024]; + if(!BaseMath_ReadCallback(self)) + return NULL; + BLI_strncpy(str,"[",1024); for(i = 0; i < self->size; i++){ if(i < (self->size - 1)){ @@ -479,11 +495,16 @@ static int Vector_len(VectorObject * self) sequence accessor (get)*/ static PyObject *Vector_item(VectorObject * self, int i) { + if(i<0) i= self->size-i; + if(i < 0 || i >= self->size) { PyErr_SetString(PyExc_IndexError,"vector[index]: out of range\n"); return NULL; } + if(!BaseMath_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->vec[i]); } @@ -497,11 +518,16 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob) return -1; } + if(i<0) i= self->size-i; + if(i < 0 || i >= self->size){ PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n"); return -1; } self->vec[i] = scalar; + + if(!BaseMath_WriteIndexCallback(self, i)) + return -1; return 0; } @@ -512,6 +538,9 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!BaseMath_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, self->size); if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); @@ -534,6 +563,9 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, float vec[4], scalar; PyObject *v; + if(!BaseMath_ReadCallback(self)) + return -1; + CLAMP(begin, 0, self->size); if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); @@ -566,6 +598,10 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, for(y = 0; y < size; y++){ self->vec[begin + y] = vec[y]; } + + if(!BaseMath_WriteCallback(self)) + return -1; + return 0; } /*------------------------NUMERIC PROTOCOLS---------------------- @@ -586,6 +622,10 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + /*VECTOR + VECTOR*/ if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); @@ -594,7 +634,7 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] + vec2->vec[i]; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); @@ -617,6 +657,10 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + /*VECTOR + VECTOR*/ if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); @@ -629,6 +673,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) return v1; } + BaseMath_WriteCallback(vec1); PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); return NULL; } @@ -648,6 +693,9 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) vec1 = (VectorObject*)v1; vec2 = (VectorObject*)v2; + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); return NULL; @@ -656,14 +704,14 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) vec[i] = vec1->vec[i] - vec2->vec[i]; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } /*------------------------obj -= obj------------------------------ subtraction*/ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) { - int i, size; + int i; VectorObject *vec1 = NULL, *vec2 = NULL; if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { @@ -677,12 +725,15 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; - size = vec1->size; for(i = 0; i < vec1->size; i++) { vec1->vec[i] = vec1->vec[i] - vec2->vec[i]; } + BaseMath_WriteCallback(vec1); Py_INCREF( v1 ); return v1; } @@ -694,11 +745,17 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) VectorObject *vec1 = NULL, *vec2 = NULL; float scalar; - if VectorObject_Check(v1) + if VectorObject_Check(v1) { vec1= (VectorObject *)v1; - - if VectorObject_Check(v2) + if(!BaseMath_ReadCallback(vec1)) + return NULL; + } + if VectorObject_Check(v2) { vec2= (VectorObject *)v2; + if(!BaseMath_ReadCallback(vec2)) + return NULL; + } + /* make sure v1 is always the vector */ if (vec1 && vec2 ) { @@ -727,7 +784,8 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) /* VEC * MATRIX */ return row_vector_multiplication(vec1, (MatrixObject*)v2); } else if (QuaternionObject_Check(v2)) { - QuaternionObject *quat = (QuaternionObject*)v2; + QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */ + if(vec1->size != 3) { PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n"); return NULL; @@ -741,7 +799,7 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] * scalar; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } @@ -757,6 +815,9 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) int i; float scalar; + if(!BaseMath_ReadCallback(vec)) + return NULL; + /* only support vec*=float and vec*=mat vec*=vec result is a float so that wont work */ if (MatrixObject_Check(v2)) { @@ -764,6 +825,9 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) int x,y, size = vec->size; MatrixObject *mat= (MatrixObject*)v2; + if(!BaseMath_ReadCallback(mat)) + return NULL; + if(mat->colSize != size){ if(mat->rowSize == 4 && vec->size != 3){ PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); @@ -787,22 +851,21 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) } vec->vec[i] = (float)dot; } - Py_INCREF( v1 ); - return v1; } else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */ for(i = 0; i < vec->size; i++) { vec->vec[i] *= scalar; } - - Py_INCREF( v1 ); - return v1; - + } + else { + PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); + return NULL; } - PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); - return NULL; + BaseMath_WriteCallback(vec); + Py_INCREF( v1 ); + return v1; } /*------------------------obj / obj------------------------------ @@ -819,6 +882,9 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) } vec1 = (VectorObject*)v1; /* vector */ + if(!BaseMath_ReadCallback(vec1)) + return NULL; + scalar = (float)PyFloat_AsDouble(v2); if(scalar== -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); @@ -833,7 +899,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] / scalar; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } /*------------------------obj /= obj------------------------------ @@ -842,14 +908,10 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) { int i; float scalar; - VectorObject *vec1 = NULL; - - /*if(!VectorObject_Check(v1)) { - PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); - return -1; - }*/ + VectorObject *vec1 = (VectorObject*)v1; - vec1 = (VectorObject*)v1; /* vector */ + if(!BaseMath_ReadCallback(vec1)) + return NULL; scalar = (float)PyFloat_AsDouble(v2); if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ @@ -864,6 +926,9 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec1->vec[i] /= scalar; } + + BaseMath_WriteCallback(vec1); + Py_INCREF( v1 ); return v1; } @@ -874,15 +939,17 @@ static PyObject *Vector_neg(VectorObject *self) { int i; float vec[4]; + + if(!BaseMath_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++){ vec[i] = -self->vec[i]; } - return newVectorObject(vec, self->size, Py_NEW); + return newVectorObject(vec, self->size, Py_NEW, Py_TYPE(self)); } -/*------------------------tp_doc*/ -static char VectorObject_doc[] = "This is a wrapper for vector objects."; /*------------------------vec_magnitude_nosqrt (internal) - for comparing only */ static double vec_magnitude_nosqrt(float *data, int size) { @@ -919,6 +986,9 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa vecA = (VectorObject*)objectA; vecB = (VectorObject*)objectB; + if(!BaseMath_ReadCallback(vecA) || !BaseMath_ReadCallback(vecB)) + return NULL; + if (vecA->size != vecB->size){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; @@ -981,17 +1051,139 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa Py_RETURN_FALSE; } } + /*-----------------PROTCOL DECLARATIONS--------------------------*/ static PySequenceMethods Vector_SeqMethods = { (inquiry) Vector_len, /* sq_length */ (binaryfunc) 0, /* sq_concat */ - (ssizeargfunc) 0, /* sq_repeat */ + (ssizeargfunc) 0, /* sq_repeat */ (ssizeargfunc) Vector_item, /* sq_item */ - (ssizessizeargfunc) Vector_slice, /* sq_slice */ +#if (PY_VERSION_HEX < 0x03000000) + (ssizessizeargfunc) Vector_slice, /* sq_slice */ /* PY2 ONLY */ +#else + NULL, +#endif (ssizeobjargproc) Vector_ass_item, /* sq_ass_item */ - (ssizessizeobjargproc) Vector_ass_slice, /* sq_ass_slice */ +#if (PY_VERSION_HEX < 0x03000000) + (ssizessizeobjargproc) Vector_ass_slice, /* sq_ass_slice */ /* PY2 ONLY */ +#else + NULL, +#endif }; + + +#if (PY_VERSION_HEX >= 0x03000000) +static PyObject *Vector_subscript(VectorObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->size; + return Vector_item(self, i); + } else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->size, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return Vector_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + item->ob_type->tp_name); + return NULL; + } +} + +static int Vector_ass_subscript(VectorObject* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->size; + return Vector_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->size, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return Vector_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + item->ob_type->tp_name); + return -1; + } +} + +static PyMappingMethods Vector_AsMapping = { + (lenfunc)Vector_len, + (binaryfunc)Vector_subscript, + (objobjargproc)Vector_ass_subscript +}; +#endif /* (PY_VERSION_HEX >= 0x03000000) */ +#if (PY_VERSION_HEX >= 0x03000000) +static PyNumberMethods Vector_NumMethods = { + (binaryfunc) Vector_add, /*nb_add*/ + (binaryfunc) Vector_sub, /*nb_subtract*/ + (binaryfunc) Vector_mul, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + (unaryfunc) Vector_neg, /*nb_negative*/ + (unaryfunc) 0, /*tp_positive*/ + (unaryfunc) 0, /*tp_absolute*/ + (inquiry) 0, /*tp_bool*/ + (unaryfunc) 0, /*nb_invert*/ + 0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + Vector_iadd, /* nb_inplace_add */ + Vector_isub, /* nb_inplace_subtract */ + Vector_imul, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + Vector_div, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + Vector_idiv, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; +#else static PyNumberMethods Vector_NumMethods = { (binaryfunc) Vector_add, /* __add__ */ (binaryfunc) Vector_sub, /* __sub__ */ @@ -1037,6 +1229,8 @@ static PyNumberMethods Vector_NumMethods = { (binaryfunc) NULL, /*__ifloordiv__*/ (binaryfunc) NULL, /*__itruediv__*/ }; +#endif + /*------------------PY_OBECT DEFINITION--------------------------*/ /* @@ -1045,66 +1239,12 @@ static PyNumberMethods Vector_NumMethods = { static PyObject *Vector_getAxis( VectorObject * self, void *type ) { - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - return PyFloat_FromDouble(self->vec[0]); - case 'Y': - return PyFloat_FromDouble(self->vec[1]); - case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); - return NULL; - } - else { - return PyFloat_FromDouble(self->vec[2]); - } - case 'W': - if(self->size < 4) { - PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); - return NULL; - } - - return PyFloat_FromDouble(self->vec[3]); - default: - { - PyErr_SetString( PyExc_RuntimeError, "undefined type in Vector_getAxis" ); - return NULL; - } - } + return Vector_item(self, GET_INT_FROM_POINTER(type)); } static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); - return -1; - } - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - self->vec[0]= param; - break; - case 'Y': - self->vec[1]= param; - break; - case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); - return -1; - } - self->vec[2]= param; - break; - case 'W': - if(self->size < 4) { - PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); - return -1; - } - self->vec[3]= param; - break; - } - - return 0; + return Vector_ass_item(self, GET_INT_FROM_POINTER(type), value); } /* vector.length */ @@ -1113,6 +1253,9 @@ static PyObject *Vector_getLength( VectorObject * self, void *type ) double dot = 0.0f; int i; + if(!BaseMath_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++){ dot += (self->vec[i] * self->vec[i]); } @@ -1124,6 +1267,9 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) double dot = 0.0f, param; int i; + if(!BaseMath_ReadCallback(self)) + return -1; + param= PyFloat_AsDouble( value ); if(param==-1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "length must be set to a number"); @@ -1159,18 +1305,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) self->vec[i]= self->vec[i] / (float)dot; } + BaseMath_WriteCallback(self); /* checked alredy */ + return 0; } -static PyObject *Vector_getWrapped( VectorObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - - /* Get a new Vector according to the provided swizzle. This function has little error checking, as we are in control of the inputs: the closure is set by us in Vector_createSwizzleGetSeter. */ @@ -1181,6 +1320,9 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) float vec[MAX_DIMENSIONS]; unsigned int swizzleClosure; + if(!BaseMath_ReadCallback(self)) + return NULL; + /* Unpack the axes from the closure into an array. */ axisA = 0; swizzleClosure = (unsigned int) closure; @@ -1192,7 +1334,7 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) axisA++; } - return newVectorObject(vec, axisA, Py_NEW); + return newVectorObject(vec, axisA, Py_NEW, Py_TYPE(self)); } /* Set the items of this vector using a swizzle. @@ -1218,6 +1360,9 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur float vecTemp[MAX_DIMENSIONS]; + if(!BaseMath_ReadCallback(self)) + return -1; + /* Check that the closure can be used with this vector: even 2D vectors have swizzles defined for axes z and w, but they would be invalid. */ swizzleClosure = (unsigned int) closure; @@ -1247,7 +1392,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur axisB++; } memcpy(self->vec, vecTemp, axisB * sizeof(float)); - return 0; + /* continue with BaseMathObject_WriteCallback at the end */ } else if (PyList_Check(value)) { @@ -1273,7 +1418,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur axisB++; } memcpy(self->vec, vecTemp, axisB * sizeof(float)); - return 0; + /* continue with BaseMathObject_WriteCallback at the end */ } else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0) { @@ -1286,13 +1431,17 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; } - return 0; + /* continue with BaseMathObject_WriteCallback at the end */ } - else - { + else { PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." ); return -1; } + + if(!BaseMath_WriteCallback(vecVal)) + return -1; + else + return 0; } /*****************************************************************************/ @@ -1302,19 +1451,19 @@ static PyGetSetDef Vector_getseters[] = { {"x", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector X axis", - (void *)'X'}, + (void *)0}, {"y", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Y axis", - (void *)'Y'}, + (void *)1}, {"z", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis", - (void *)'Z'}, + (void *)2}, {"w", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis", - (void *)'W'}, + (void *)3}, {"length", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length", @@ -1324,347 +1473,351 @@ static PyGetSetDef Vector_getseters[] = { "Vector Length", NULL}, {"wrapped", - (getter)Vector_getWrapped, (setter)NULL, + (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", + (getter)BaseMathObject_getOwner, (setter)NULL, + "Read only owner for vectors that depend on another object", + NULL}, /* autogenerated swizzle attrs, see python script below */ - {"xx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, Vector_swizzle_doc, (void *)((unsigned int)((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<." */ - "Blender Vector", /* char *tp_name; */ + "vector", /* char *tp_name; */ sizeof( VectorObject ), /* int tp_basicsize; */ 0, /* tp_itemsize; For allocation */ /* Methods to implement standard operations */ - ( destructor ) Vector_dealloc,/* destructor tp_dealloc; */ + ( destructor ) BaseMathObject_dealloc,/* destructor tp_dealloc; */ NULL, /* printfunc tp_print; */ NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ @@ -1744,7 +1897,11 @@ PyTypeObject vector_Type = { &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */ &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */ - NULL, /* PyMappingMethods *tp_as_mapping; */ +#if (PY_VERSION_HEX >= 0x03000000) + &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */ +#else + NULL, +#endif /* More standard operations (here for binary compatibility) */ @@ -1758,8 +1915,8 @@ PyTypeObject vector_Type = { NULL, /* PyBufferProcs *tp_as_buffer; */ /*** Flags to define presence of optional/expanded features ***/ - Py_TPFLAGS_DEFAULT, - VectorObject_doc, /* char *tp_doc; Documentation string */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + NULL, /* char *tp_doc; Documentation string */ /*** Assigned meaning in release 2.0 ***/ /* call function for all accessible objects */ NULL, /* traverseproc tp_traverse; */ @@ -1811,14 +1968,21 @@ PyTypeObject vector_Type = { (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newVectorObject(float *vec, int size, int type) +PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_type) { int i; - VectorObject *self = PyObject_NEW(VectorObject, &vector_Type); + VectorObject *self; + + if(base_type) self = base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(VectorObject, &vector_Type); if(size > 4 || size < 2) return NULL; self->size = size; + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP) { self->vec = vec; @@ -1843,20 +2007,72 @@ PyObject *newVectorObject(float *vec, int size, int type) return (PyObject *) self; } -/* - #############################DEPRECATED################################ - ####################################################################### - ----------------------------Vector.negate() -------------------- +PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype) +{ + float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */ + VectorObject *self= (VectorObject *)newVectorObject(dummy, size, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return (PyObject *)self; +} + +//-----------------row_vector_multiplication (internal)----------- +//ROW VECTOR Multiplication - Vector X Matrix +//[x][y][z] * [1][2][3] +// [4][5][6] +// [7][8][9] +//vector/matrix multiplication IS NOT COMMUTATIVE!!!! +static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) +{ + float vecNew[4], vecCopy[4]; + double dot = 0.0f; + int x, y, z = 0, vec_size = vec->size; + + if(mat->colSize != vec_size){ + if(mat->rowSize == 4 && vec_size != 3){ + PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); + return NULL; + }else{ + vecCopy[3] = 1.0f; + } + } + + if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat)) + return NULL; + + for(x = 0; x < vec_size; x++){ + vecCopy[x] = vec->vec[x]; + } + + //muliplication + for(x = 0; x < mat->colSize; x++) { + for(y = 0; y < mat->rowSize; y++) { + dot += mat->matrix[y][x] * vecCopy[y]; + } + vecNew[z++] = (float)dot; + dot = 0.0f; + } + return newVectorObject(vecNew, vec_size, Py_NEW, NULL); +} + +/*----------------------------Vector.negate() -------------------- set the vector to it's negative -x, -y, -z */ static PyObject *Vector_Negate(VectorObject * self) { int i; - for(i = 0; i < self->size; i++) { + if(!BaseMath_ReadCallback(self)) + return NULL; + + for(i = 0; i < self->size; i++) self->vec[i] = -(self->vec[i]); - } - /*printf("Vector.negate(): Deprecated: use -vector instead\n");*/ + + BaseMath_WriteCallback(self); // alredy checked for error + Py_INCREF(self); return (PyObject*)self; } -/*################################################################### - ###########################DEPRECATED##############################*/ diff --git a/source/blender/python/generic/vector.h b/source/blender/python/generic/vector.h index d2eb826ef10..f6babac7ed9 100644 --- a/source/blender/python/generic/vector.h +++ b/source/blender/python/generic/vector.h @@ -1,4 +1,4 @@ -/* $Id: vector.h 20332 2009-05-22 03:22:56Z campbellbarton $ +/* $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -34,17 +34,22 @@ #include "../intern/bpy_compat.h" extern PyTypeObject vector_Type; +#define VectorObject_Check(_v) PyObject_TypeCheck((_v), &vector_Type) -#define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type) - -typedef struct { +typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */ PyObject_VAR_HEAD - float *vec; /*1D array of data (alias), wrapped status depends on wrapped status */ - short size; /* vec size 2,3 or 4 */ - short wrapped; /* is wrapped data? */ + float *vec; /*1D array of data (alias), wrapped status depends on wrapped status */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ + /* end BaseMathObject */ + + unsigned char size; /* vec size 2,3 or 4 */ } VectorObject; /*prototypes*/ -PyObject *newVectorObject(float *vec, int size, int type); +PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_type); +PyObject *newVectorObject_cb(PyObject *user, int size, int callback_type, int subtype); #endif /* EXPP_vector_h */ diff --git a/source/blender/python/intern/Makefile b/source/blender/python/intern/Makefile index 0c4a540a4bd..d210cfaf973 100644 --- a/source/blender/python/intern/Makefile +++ b/source/blender/python/intern/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 11904 2007-08-31 16:16:33Z sirdude $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/python/intern/bpy_compat.h b/source/blender/python/intern/bpy_compat.h index 032b60988d5..1ad9376c13b 100644 --- a/source/blender/python/intern/bpy_compat.h +++ b/source/blender/python/intern/bpy_compat.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_compat.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 559ed537757..8b5ad36f349 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -37,6 +37,11 @@ #include "BPY_extern.h" #include "../generic/bpy_internal_import.h" // our own imports +/* external util modukes */ + +#include "../generic/Mathutils.h" +#include "../generic/Geometry.h" +#include "../generic/BGL.h" void BPY_free_compiled_text( struct Text *text ) @@ -61,11 +66,17 @@ static void bpy_init_modules( void ) PyModule_AddObject( mod, "types", BPY_rna_types() ); PyModule_AddObject( mod, "props", BPY_rna_props() ); PyModule_AddObject( mod, "ops", BPY_operator_module() ); - PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant + PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent /* add the module so we can import it */ PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod); Py_DECREF(mod); + + + /* stand alone utility modules not related to blender directly */ + Geometry_Init("Geometry"); + Mathutils_Init("Mathutils"); + BGL_Init("BGL"); } #if (PY_VERSION_HEX < 0x02050000) diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 3ea330adc85..004cf2fb7c7 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_operator.h b/source/blender/python/intern/bpy_operator.h index 8a4493b5866..46ea144fd4d 100644 --- a/source/blender/python/intern/bpy_operator.h +++ b/source/blender/python/intern/bpy_operator.h @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 3d5427ddefd..60a9afda0c4 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator_wrap.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -47,98 +47,6 @@ #define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */ #define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */ -static PyObject *pyop_dict_from_event(wmEvent *event) -{ - PyObject *dict= PyDict_New(); - PyObject *item; - char *cstring, ascii[2]; - - /* type */ - item= PyUnicode_FromString(WM_key_event_string(event->type)); - PyDict_SetItemString(dict, "type", item); Py_DECREF(item); - - /* val */ - switch(event->val) { - case KM_ANY: - cstring = "ANY"; - break; - case KM_RELEASE: - cstring = "RELEASE"; - break; - case KM_PRESS: - cstring = "PRESS"; - break; - default: - cstring = "UNKNOWN"; - break; - } - - item= PyUnicode_FromString(cstring); - PyDict_SetItemString(dict, "val", item); Py_DECREF(item); - - /* x, y (mouse) */ - item= PyLong_FromLong(event->x); - PyDict_SetItemString(dict, "x", item); Py_DECREF(item); - - item= PyLong_FromLong(event->y); - PyDict_SetItemString(dict, "y", item); Py_DECREF(item); - - item= PyLong_FromLong(event->prevx); - PyDict_SetItemString(dict, "prevx", item); Py_DECREF(item); - - item= PyLong_FromLong(event->prevy); - PyDict_SetItemString(dict, "prevy", item); Py_DECREF(item); - - /* ascii */ - ascii[0]= event->ascii; - ascii[1]= '\0'; - item= PyUnicode_FromString(ascii); - PyDict_SetItemString(dict, "ascii", item); Py_DECREF(item); - - /* modifier keys */ - item= PyLong_FromLong(event->shift); - PyDict_SetItemString(dict, "shift", item); Py_DECREF(item); - - item= PyLong_FromLong(event->ctrl); - PyDict_SetItemString(dict, "ctrl", item); Py_DECREF(item); - - item= PyLong_FromLong(event->alt); - PyDict_SetItemString(dict, "alt", item); Py_DECREF(item); - - item= PyLong_FromLong(event->oskey); - PyDict_SetItemString(dict, "oskey", item); Py_DECREF(item); - - - - /* modifier */ -#if 0 - item= PyTuple_New(0); - if(event->keymodifier & KM_SHIFT) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("SHIFT")); - size++; - } - if(event->keymodifier & KM_CTRL) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("CTRL")); - size++; - } - if(event->keymodifier & KM_ALT) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("ALT")); - size++; - } - if(event->keymodifier & KM_OSKEY) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("OSKEY")); - size++; - } - PyDict_SetItemString(dict, "keymodifier", item); Py_DECREF(item); -#endif - - return dict; -} - static struct BPY_flag_def pyop_ret_flags[] = { {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL}, {"CANCELLED", OPERATOR_CANCELLED}, @@ -180,6 +88,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); PointerRNA ptr_context; PointerRNA ptr_operator; + PointerRNA ptr_event; PyObject *py_operator; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -198,15 +107,9 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve /* Assign instance attributes from operator properties */ { - PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; const char *arg_name; - iterprop= RNA_struct_iterator_property(op->ptr->type); - RNA_property_collection_begin(op->ptr, iterprop, &iter); - - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; + RNA_STRUCT_BEGIN(op->ptr, prop) { arg_name= RNA_property_identifier(prop); if (strcmp(arg_name, "rna_type")==0) continue; @@ -215,8 +118,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyObject_SetAttrString(py_class_instance, arg_name, item); Py_DECREF(item); } - - RNA_property_collection_end(&iter); + RNA_STRUCT_END; } /* set operator pointer RNA as instance "__operator__" attribute */ @@ -230,11 +132,13 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve if (mode==PYOP_INVOKE) { item= PyObject_GetAttrString(py_class, "invoke"); args = PyTuple_New(3); + + RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event); // PyTuple_SET_ITEM "steals" object reference, it is // an object passed shouldn't be DECREF'ed PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context)); - PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event)); + PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_event)); } else if (mode==PYOP_EXEC) { item= PyObject_GetAttrString(py_class, "execute"); @@ -449,7 +353,8 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) /* remove if it already exists */ if ((ot=WM_operatortype_find(idname))) { - Py_XDECREF((PyObject*)ot->pyop_data); + if(ot->pyop_data) + Py_XDECREF((PyObject*)ot->pyop_data); WM_operatortype_remove(idname); } diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h index c9efb1ea22f..2929d57ab82 100644 --- a/source/blender/python/intern/bpy_operator_wrap.h +++ b/source/blender/python/intern/bpy_operator_wrap.h @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator_wrap.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d131361294d..4729620bb8a 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1,5 +1,5 @@ /** - * $Id: bpy_rna.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,10 +35,99 @@ #include "RNA_define.h" /* for defining our own rna */ #include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" #include "BKE_context.h" #include "BKE_global.h" /* evil G.* */ #include "BKE_report.h" +#define USE_MATHUTILS + +#ifdef USE_MATHUTILS +#include "../generic/Mathutils.h" /* so we can have mathutils callbacks */ + +/* bpyrna vector/euler/quat callbacks */ +static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */ + +static int mathutils_rna_generic_check(BPy_PropertyRNA *self) +{ + return self->prop?1:0; +} + +static int mathutils_rna_vector_get(BPy_PropertyRNA *self, int subtype, float *vec_from) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_get_array(&self->ptr, self->prop, vec_from); + return 1; +} + +static int mathutils_rna_vector_set(BPy_PropertyRNA *self, int subtype, float *vec_to) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_set_array(&self->ptr, self->prop, vec_to); + return 1; +} + +static int mathutils_rna_vector_get_index(BPy_PropertyRNA *self, int subtype, float *vec_from, int index) +{ + if(self->prop==NULL) + return 0; + + vec_from[index]= RNA_property_float_get_index(&self->ptr, self->prop, index); + return 1; +} + +static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, float *vec_to, int index) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_set_index(&self->ptr, self->prop, index, vec_to[index]); + return 1; +} + +Mathutils_Callback mathutils_rna_array_cb = { + mathutils_rna_generic_check, + mathutils_rna_vector_get, + mathutils_rna_vector_set, + mathutils_rna_vector_get_index, + mathutils_rna_vector_set_index +}; + +/* bpyrna matrix callbacks */ +static int mathutils_rna_matrix_cb_index= -1; /* index for our callbacks */ + +static int mathutils_rna_matrix_get(BPy_PropertyRNA *self, int subtype, float *mat_from) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_get_array(&self->ptr, self->prop, mat_from); + return 1; +} + +static int mathutils_rna_matrix_set(BPy_PropertyRNA *self, int subtype, float *mat_to) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_set_array(&self->ptr, self->prop, mat_to); + return 1; +} + +Mathutils_Callback mathutils_rna_matrix_cb = { + mathutils_rna_generic_check, + mathutils_rna_matrix_get, + mathutils_rna_matrix_set, + NULL, + NULL +}; + +#endif + static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b ) { return (a->ptr.data==b->ptr.data) ? 0 : -1; @@ -73,14 +162,15 @@ static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, in /*----------------------repr--------------------------------------------*/ static PyObject *pyrna_struct_repr( BPy_StructRNA * self ) { - PropertyRNA *prop; - char str[512]; + PyObject *pyob; + char *name; /* print name if available */ - prop= RNA_struct_name_property(self->ptr.type); - if(prop) { - RNA_property_string_get(&self->ptr, prop, str); - return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(self->ptr.type), str); + name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0); + if(name) { + pyob= PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(self->ptr.type), name); + MEM_freeN(name); + return pyob; } return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\"]", RNA_struct_identifier(self->ptr.type)); @@ -88,20 +178,19 @@ static PyObject *pyrna_struct_repr( BPy_StructRNA * self ) static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self ) { - PropertyRNA *prop; + PyObject *pyob; PointerRNA ptr; - char str[512]; + char *name; /* if a pointer, try to print name of pointer target too */ if(RNA_property_type(self->prop) == PROP_POINTER) { ptr= RNA_property_pointer_get(&self->ptr, self->prop); + name= RNA_struct_name_get_alloc(&ptr, NULL, 0); - if(ptr.data) { - prop= RNA_struct_name_property(ptr.type); - if(prop) { - RNA_property_string_get(&ptr, prop, str); - return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), str); - } + if(name) { + pyob= PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); + MEM_freeN(name); + return pyob; } } @@ -116,13 +205,13 @@ static long pyrna_struct_hash( BPy_StructRNA * self ) /* use our own dealloc so we can free a property if we use one */ static void pyrna_struct_dealloc( BPy_StructRNA * self ) { - /* Note!! for some weired reason calling PyObject_DEL() directly crashes blender! */ if (self->freeptr && self->ptr.data) { IDP_FreeProperty(self->ptr.data); MEM_freeN(self->ptr.data); self->ptr.data= NULL; } + /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ Py_TYPE(self)->tp_free(self); return; } @@ -130,9 +219,8 @@ static void pyrna_struct_dealloc( BPy_StructRNA * self ) static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { const EnumPropertyItem *item; - int totitem; - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(ptr, prop, &item, NULL); return (char*)BPy_enum_as_string((EnumPropertyItem*)item); } @@ -144,7 +232,52 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) if (len > 0) { /* resolve the array from a new pytype */ - return pyrna_prop_CreatePyObject(ptr, prop); + PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop); + +#ifdef USE_MATHUTILS + + /* return a mathutils vector where possible */ + if(RNA_property_type(prop)==PROP_FLOAT) { + switch(RNA_property_subtype(prop)) { + case PROP_VECTOR: + if(len>=2 && len <= 4) { + PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, 0); + Py_DECREF(ret); /* the vector owns now */ + ret= vec_cb; /* return the vector instead */ + } + break; + case PROP_MATRIX: + if(len==16) { + PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } + else if (len==9) { + PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } + break; + case PROP_ROTATION: + if(len==3) { /* euler */ + PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= eul_cb; /* return the matrix instead */ + } + else if (len==4) { + PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= quat_cb; /* return the matrix instead */ + } + break; + default: + break; + } + } + +#endif + + return ret; } /* see if we can coorce into a python type - PropertyType */ @@ -213,17 +346,9 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi const char *arg_name= NULL; PyObject *item; - PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; - - iterprop= RNA_struct_iterator_property(ptr->type); - RNA_property_collection_begin(ptr, iterprop, &iter); - totkw = kw ? PyDict_Size(kw):0; - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; - + RNA_STRUCT_BEGIN(ptr, prop) { arg_name= RNA_property_identifier(prop); if (strcmp(arg_name, "rna_type")==0) continue; @@ -249,8 +374,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi totkw--; } - - RNA_property_collection_end(&iter); + RNA_STRUCT_END; if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */ PyObject *key, *value; @@ -271,12 +395,15 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw); -PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) +PyObject *pyrna_func_to_py(BPy_StructRNA *pyrna, FunctionRNA *func) { static PyMethodDef func_meth = {"", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"}; PyObject *self= PyTuple_New(2); PyObject *ret; - PyTuple_SET_ITEM(self, 0, pyrna_struct_CreatePyObject(ptr)); + + PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna); + Py_INCREF(pyrna); + PyTuple_SET_ITEM(self, 1, PyCObject_FromVoidPtr((void *)func, NULL)); ret= PyCFunction_New(&func_meth, self); @@ -294,15 +421,30 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v if (len > 0) { PyObject *item; + int py_len = -1; int i; - if (!PySequence_Check(value)) { - PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array."); + +#ifdef USE_MATHUTILS + if(MatrixObject_Check(value)) { + MatrixObject *mat = (MatrixObject*)value; + if(!BaseMath_ReadCallback(mat)) + return -1; + + py_len = mat->rowSize * mat->colSize; + } else /* continue... */ +#endif + if (PySequence_Check(value)) { + py_len= (int)PySequence_Length(value); + } + else { + PyErr_Format(PyExc_TypeError, "RNA array assignment expected a sequence instead of %s instance.", Py_TYPE(value)->tp_name); return -1; } + /* done getting the length */ - if ((int)PySequence_Length(value) != len) { - PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array."); + if (py_len != len) { + PyErr_Format(PyExc_AttributeError, "python sequence length %d did not match the RNA array length %d.", py_len, len); return -1; } @@ -368,14 +510,21 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v else param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array"); - - /* collect the variables */ - for (i=0; icontigPtr, sizeof(float) * len); + } else /* continue... */ +#endif + { + /* collect the variables */ + for (i=0; iptr= itemptr; + BLI_addtail(lb, link); + } + else + RNA_property_collection_add(ptr, prop, &itemptr); + if(pyrna_pydict_to_props(&itemptr, item, "Converting a python list to an RNA collection")==-1) { Py_DECREF(item); return -1; @@ -661,108 +821,246 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self ) return len; } -static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) +/* internal use only */ +static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynum) { - PyObject *ret; PointerRNA newptr; - int keynum = 0; - char *keyname = NULL; - + + if(keynum < 0) keynum += RNA_property_collection_length(&self->ptr, self->prop); + + if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr)) + return pyrna_struct_CreatePyObject(&newptr); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return NULL; +} +static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum) +{ + int len= RNA_property_array_length(self->prop); + + if(keynum < 0) keynum += len; + + if(keynum >= 0 && keynum < len) + return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return NULL; +} + +static PyObject *prop_subscript_collection_str(BPy_PropertyRNA * self, char *keyname) +{ + PointerRNA newptr; + if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) + return pyrna_struct_CreatePyObject(&newptr); + + PyErr_SetString(PyExc_KeyError, "key not found"); + return NULL; +} +/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA * self, char *keyname) */ + + + + +#if PY_VERSION_HEX >= 0x03000000 +static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA * self, int start, int stop) +{ + PointerRNA newptr; + PyObject *list = PyList_New(stop - start); + int count; + + start = MIN2(start,stop); /* values are clamped from */ + + for(count = start; count < stop; count++) { + if(RNA_property_collection_lookup_int(&self->ptr, self->prop, count - start, &newptr)) { + PyList_SetItem(list, count - start, pyrna_struct_CreatePyObject(&newptr)); + } + else { + Py_DECREF(list); + + PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection"); + return NULL; + } + } + + return list; +} +static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, int stop) +{ + PyObject *list = PyList_New(stop - start); + int count; + + start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */ + + for(count = start; count < stop; count++) + PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count)); + + return list; +} +#endif + +static PyObject *prop_subscript_collection(BPy_PropertyRNA * self, PyObject *key) +{ if (PyUnicode_Check(key)) { - keyname = _PyUnicode_AsString(key); - } else if (PyLong_Check(key)) { - keynum = PyLong_AsSsize_t(key); - } else { + return prop_subscript_collection_str(self, _PyUnicode_AsString(key)); + } + else if (PyLong_Check(key)) { + return prop_subscript_collection_int(self, PyLong_AsSsize_t(key)); + } +#if PY_VERSION_HEX >= 0x03000000 + else if (PySlice_Check(key)) { + int len= RNA_property_collection_length(&self->ptr, self->prop); + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return prop_subscript_collection_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + return NULL; + } + } +#endif + else { PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int"); return NULL; } - - if (RNA_property_type(self->prop) == PROP_COLLECTION) { - int ok; - if (keyname) ok = RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr); - else ok = RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr); - - if (ok) { - ret = pyrna_struct_CreatePyObject(&newptr); - } else { - PyErr_SetString(PyExc_AttributeError, "out of range"); - ret = NULL; +} + +static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key) +{ + /*if (PyUnicode_Check(key)) { + return prop_subscript_array_str(self, _PyUnicode_AsString(key)); + } else*/ + if (PyLong_Check(key)) { + return prop_subscript_array_int(self, PyLong_AsSsize_t(key)); + } +#if PY_VERSION_HEX >= 0x03000000 + else if (PySlice_Check(key)) { + int len= RNA_property_array_length(self->prop); + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); } - - } else if (keyname) { - PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections"); - ret = NULL; - } else { - int len = RNA_property_array_length(self->prop); - - if (len==0) { /* not an array*/ - PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum); - ret = NULL; + else if (step == 1) { + return prop_subscript_array_slice(self, start, stop); } - - if (keynum >= len){ - PyErr_SetString(PyExc_AttributeError, "index out of range"); - ret = NULL; - } else { /* not an array*/ - ret = pyrna_prop_to_py_index(&self->ptr, self->prop, keynum); + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + return NULL; } } - - return ret; +#endif + else { + PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); + return NULL; + } } +static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) +{ + if (RNA_property_type(self->prop) == PROP_COLLECTION) { + return prop_subscript_collection(self, key); + } else if (RNA_property_array_length(self->prop)) { /* arrays are currently fixed length, zero length means its not an array */ + return prop_subscript_array(self, key); + } else { + PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection"); + return NULL; + } + +} -static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value ) +#if PY_VERSION_HEX >= 0x03000000 +static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value) { - int ret = 0; - int keynum = 0; - char *keyname = NULL; + int count; + + /* values are clamped from */ + begin = MIN2(begin,end); + + for(count = begin; count < end; count++) { + if(pyrna_py_to_prop_index(&self->ptr, self->prop, count - begin, value) == -1) { + /* TODO - this is wrong since some values have been assigned... will need to fix that */ + return -1; /* pyrna_struct_CreatePyObject should set the error */ + } + } + + return 0; +} +#endif + +static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value) +{ + + int len= RNA_property_array_length(self->prop); + + if(keynum < 0) keynum += len; + + if(keynum >= 0 && keynum < len) + return pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return -1; +} + +static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value ) +{ + /* char *keyname = NULL; */ /* not supported yet */ if (!RNA_property_editable(&self->ptr, self->prop)) { PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) ); return -1; } - if (PyUnicode_Check(key)) { - keyname = _PyUnicode_AsString(key); - } else if (PyLong_Check(key)) { - keynum = PyLong_AsSsize_t(key); - } else { - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - invalid key, key must be a string or an int"); + /* maybe one day we can support this... */ + if (RNA_property_type(self->prop) == PROP_COLLECTION) { + PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%s\" from \"%s\" is a collection, assignment not supported", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) ); return -1; } - - if (RNA_property_type(self->prop) == PROP_COLLECTION) { - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - assignment is not supported for collections (yet)"); - ret = -1; - } else if (keyname) { - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - string keys are only supported for collections"); - ret = -1; - } else { - int len = RNA_property_array_length(self->prop); - - if (len==0) { /* not an array*/ - PyErr_Format(PyExc_AttributeError, "PropertyRNA - not an array or collection %d", keynum); - ret = -1; + + if (PyLong_Check(key)) { + return prop_subscript_ass_array_int(self, PyLong_AsSsize_t(key), value); + } +#if PY_VERSION_HEX >= 0x03000000 + else if (PySlice_Check(key)) { + int len= RNA_property_array_length(self->prop); + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (slicelength <= 0) { + return 0; } - - if (keynum >= len){ - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - index out of range"); - ret = -1; - } else { - ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value); + else if (step == 1) { + return prop_subscript_ass_array_slice(self, start, stop, value); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + return -1; } } - - return ret; +#endif + else { + PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); + return -1; + } } - static PyMappingMethods pyrna_prop_as_mapping = { ( lenfunc ) pyrna_prop_len, /* mp_length */ ( binaryfunc ) pyrna_prop_subscript, /* mp_subscript */ - ( objobjargproc ) pyrna_prop_assign_subscript, /* mp_ass_subscript */ + ( objobjargproc ) pyrna_prop_ass_subscript, /* mp_ass_subscript */ }; static int pyrna_prop_contains(BPy_PropertyRNA * self, PyObject *value) @@ -804,7 +1102,6 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) PyObject *pystring; /* for looping over attrs and funcs */ - CollectionPropertyIterator iter; PropertyRNA *iterprop; /* Include this incase this instance is a subtype of a python class @@ -833,26 +1130,23 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) /* * Collect RNA attributes */ - PropertyRNA *nameprop; char name[256], *nameptr; iterprop= RNA_struct_iterator_property(self->ptr.type); - RNA_property_collection_begin(&self->ptr, iterprop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) { - nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); - + RNA_PROP_BEGIN(&self->ptr, itemptr, iterprop) { + nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name)); + + if(nameptr) { pystring = PyUnicode_FromString(nameptr); PyList_Append(ret, pystring); Py_DECREF(pystring); - if ((char *)&name != nameptr) + if(name != nameptr) MEM_freeN(nameptr); } } - RNA_property_collection_end(&iter); - + RNA_PROP_END; } @@ -865,15 +1159,12 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) RNA_pointer_create(NULL, &RNA_Struct, self->ptr.type, &tptr); iterprop= RNA_struct_find_property(&tptr, "functions"); - RNA_property_collection_begin(&tptr, iterprop, &iter); - - for(; iter.valid; RNA_property_collection_next(&iter)) { - pystring = PyUnicode_FromString(RNA_function_identifier(iter.ptr.data)); + RNA_PROP_BEGIN(&tptr, itemptr, iterprop) { + pystring = PyUnicode_FromString(RNA_function_identifier(itemptr.data)); PyList_Append(ret, pystring); Py_DECREF(pystring); } - - RNA_property_collection_end(&iter); + RNA_PROP_END; } if(self->ptr.type == &RNA_Context) { @@ -915,7 +1206,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) ret = pyrna_prop_to_py(&self->ptr, prop); } else if ((func = RNA_struct_find_function(&self->ptr, name))) { - ret = pyrna_func_to_py(&self->ptr, func); + ret = pyrna_func_to_py(self, func); } else if (self->ptr.type == &RNA_Context) { PointerRNA newptr; @@ -978,7 +1269,7 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje return pyrna_py_to_prop(&self->ptr, prop, NULL, value); } -PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) +static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) { PyObject *ret; if (RNA_property_type(self->prop) != PROP_COLLECTION) { @@ -986,34 +1277,31 @@ PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) ret = NULL; } else { PyObject *item; - CollectionPropertyIterator iter; - PropertyRNA *nameprop; char name[256], *nameptr; ret = PyList_New(0); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) { - nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); - + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name)); + + if(nameptr) { /* add to python list */ item = PyUnicode_FromString( nameptr ); PyList_Append(ret, item); Py_DECREF(item); /* done */ - if ((char *)&name != nameptr) + if(name != nameptr) MEM_freeN(nameptr); } } - RNA_property_collection_end(&iter); + RNA_PROP_END; } return ret; } -PyObject *pyrna_prop_items(BPy_PropertyRNA *self) +static PyObject *pyrna_prop_items(BPy_PropertyRNA *self) { PyObject *ret; if (RNA_property_type(self->prop) != PROP_COLLECTION) { @@ -1021,28 +1309,25 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self) ret = NULL; } else { PyObject *item; - CollectionPropertyIterator iter; - PropertyRNA *nameprop; char name[256], *nameptr; int i= 0; ret = PyList_New(0); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - if(iter.ptr.data) { + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + if(itemptr.data) { /* add to python list */ item= PyTuple_New(2); - if(nameprop = RNA_struct_name_property(iter.ptr.type)) { - nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); + nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name)); + if(nameptr) { PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr )); - if ((char *)&name != nameptr) + if(name != nameptr) MEM_freeN(nameptr); } else { PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */ } - PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&iter.ptr)); + PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr)); PyList_Append(ret, item); Py_DECREF(item); @@ -1050,14 +1335,14 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self) i++; } } - RNA_property_collection_end(&iter); + RNA_PROP_END; } return ret; } -PyObject *pyrna_prop_values(BPy_PropertyRNA *self) +static PyObject *pyrna_prop_values(BPy_PropertyRNA *self) { PyObject *ret; @@ -1066,23 +1351,256 @@ PyObject *pyrna_prop_values(BPy_PropertyRNA *self) ret = NULL; } else { PyObject *item; - CollectionPropertyIterator iter; - PropertyRNA *iterprop; ret = PyList_New(0); - //iterprop= RNA_struct_iterator_property(self->ptr.type); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - item = pyrna_struct_CreatePyObject(&iter.ptr); + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + item = pyrna_struct_CreatePyObject(&itemptr); PyList_Append(ret, item); Py_DECREF(item); } - RNA_property_collection_end(&iter); + RNA_PROP_END; } return ret; } +#if (PY_VERSION_HEX >= 0x03000000) /* foreach needs py3 */ +static void foreach_attr_type( BPy_PropertyRNA *self, char *attr, + /* values to assign */ + RawPropertyType *raw_type, int *attr_tot, int *attr_signed ) +{ + PropertyRNA *prop; + *raw_type= -1; + *attr_tot= 0; + *attr_signed= 0; + + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + prop = RNA_struct_find_property(&itemptr, attr); + *raw_type= RNA_property_raw_type(prop); + *attr_tot = RNA_property_array_length(prop); + *attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? 0:1; + break; + } + RNA_PROP_END; +} + +/* pyrna_prop_foreach_get/set both use this */ +static int foreach_parse_args( + BPy_PropertyRNA *self, PyObject *args, + + /*values to assign */ + char **attr, PyObject **seq, int *tot, int *size, RawPropertyType *raw_type, int *attr_tot, int *attr_signed) +{ +#if 0 + int array_tot; + int target_tot; +#endif + + *size= *raw_type= *attr_tot= *attr_signed= 0; + + if(!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) { + PyErr_SetString( PyExc_TypeError, "foreach_get(attr, sequence) expects a string and a sequence" ); + return -1; + } + + *tot= PySequence_Length(*seq); // TODO - buffer may not be a sequence! array.array() is tho. + + if(*tot>0) { + foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed); + *size= RNA_raw_type_sizeof(*raw_type); + +#if 0 // works fine but not strictly needed, we could allow RNA_property_collection_raw_* to do the checks + if((*attr_tot) < 1) + *attr_tot= 1; + + if (RNA_property_type(self->prop) == PROP_COLLECTION) + array_tot = RNA_property_collection_length(&self->ptr, self->prop); + else + array_tot = RNA_property_array_length(self->prop); + + + target_tot= array_tot * (*attr_tot); + + /* rna_access.c - rna_raw_access(...) uses this same method */ + if(target_tot != (*tot)) { + PyErr_Format( PyExc_TypeError, "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d", *tot, target_tot); + return -1; + } +#endif + } + + return 0; +} + +static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) +{ + char f = format ? *format:'B'; /* B is assumed when not set */ + + switch(raw_type) { + case PROP_RAW_CHAR: + if (attr_signed) return (f=='b') ? 1:0; + else return (f=='B') ? 1:0; + case PROP_RAW_SHORT: + if (attr_signed) return (f=='h') ? 1:0; + else return (f=='H') ? 1:0; + case PROP_RAW_INT: + if (attr_signed) return (f=='i') ? 1:0; + else return (f=='I') ? 1:0; + case PROP_RAW_FLOAT: + return (f=='f') ? 1:0; + case PROP_RAW_DOUBLE: + return (f=='d') ? 1:0; + } + + return 0; +} + +static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) +{ + PyObject *item; + int i=0, ok, buffer_is_compat; + void *array= NULL; + + /* get/set both take the same args currently */ + char *attr; + PyObject *seq; + int tot, size, attr_tot, attr_signed; + RawPropertyType raw_type; + + if(foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) + return NULL; + + if(tot==0) + Py_RETURN_NONE; + + + + if(set) { /* get the array from python */ + buffer_is_compat = 0; + if(PyObject_CheckBuffer(seq)) { + Py_buffer buf; + PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); + + /* check if the buffer matches */ + + buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); + + if(buffer_is_compat) { + ok = RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); + } + + PyBuffer_Release(&buf); + } + + /* could not use the buffer, fallback to sequence */ + if(!buffer_is_compat) { + array= PyMem_Malloc(size * tot); + + for( ; iptr, self->prop, attr, array, raw_type, tot); + } + } + else { + buffer_is_compat = 0; + if(PyObject_CheckBuffer(seq)) { + Py_buffer buf; + PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); + + /* check if the buffer matches, TODO - signed/unsigned types */ + + buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); + + if(buffer_is_compat) { + ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); + } + + PyBuffer_Release(&buf); + } + + /* could not use the buffer, fallback to sequence */ + if(!buffer_is_compat) { + array= PyMem_Malloc(size * tot); + + ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, array, raw_type, tot); + + if(!ok) i= tot; /* skip the loop */ + + for( ; i= 0x03000000) */ + /* A bit of a kludge, make a list out of a collection or array, * then return the lists iter function, not especially fast but convenient for now */ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) @@ -1117,14 +1635,20 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) } static struct PyMethodDef pyrna_struct_methods[] = { - {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""}, + {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; static struct PyMethodDef pyrna_prop_methods[] = { - {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""}, - {"items", (PyCFunction)pyrna_prop_items, METH_NOARGS, ""}, - {"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, ""}, + {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, NULL}, + {"items", (PyCFunction)pyrna_prop_items, METH_NOARGS,NULL}, + {"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, NULL}, + +#if (PY_VERSION_HEX >= 0x03000000) + /* array accessor function */ + {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL}, + {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL}, +#endif {NULL, NULL, 0, NULL} }; @@ -1251,10 +1775,21 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) break; } case PROP_COLLECTION: - /* XXX not supported yet - * ret = pyrna_prop_CreatePyObject(ptr, prop); */ - ret = NULL; + { + ListBase *lb= (ListBase*)data; + CollectionPointerLink *link; + PyObject *linkptr; + + ret = PyList_New(0); + + for(link=lb->first; link; link=link->next) { + linkptr= pyrna_struct_CreatePyObject(&link->ptr); + PyList_Append(ret, linkptr); + Py_DECREF(linkptr); + } + break; + } default: PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); ret = NULL; @@ -1674,6 +2209,11 @@ PyObject *BPY_rna_module( void ) { PointerRNA ptr; +#ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once. + mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb); + mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); +#endif + /* This can't be set in the pytype struct because some compilers complain */ pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; @@ -1883,7 +2423,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) char *id, *name="", *description=""; int def=0; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:IntProperty", kwlist, &id, &name, &description, &def)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def)) return NULL; if (PyTuple_Size(args) > 0) { @@ -1897,7 +2437,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) Py_RETURN_NONE; } else { PyObject *ret = PyTuple_New(2); - PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL)); + PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_BoolProperty, NULL)); PyTuple_SET_ITEM(ret, 1, kw); Py_INCREF(kw); return ret; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 45614e992c6..d2f01b06336 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_rna.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index ccc8b2c206a..088fe436c69 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -1,5 +1,5 @@ /** - * $Id: bpy_ui.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_ui.h b/source/blender/python/intern/bpy_ui.h index be5e5e87015..4182a32d3f0 100644 --- a/source/blender/python/intern/bpy_ui.h +++ b/source/blender/python/intern/bpy_ui.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_ui.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 6ec01e0c3fc..bce73b903c0 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -1,5 +1,5 @@ /** - * $Id: bpy_util.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -171,7 +171,7 @@ void PyObSpit(char *name, PyObject *var) { else { PyObject_Print(var, stderr, 0); fprintf(stderr, " ref:%d ", var->ob_refcnt); - fprintf(stderr, " ptr:%ld", (long)var); + fprintf(stderr, " ptr:%p", (void *)var); fprintf(stderr, " type:"); if(Py_TYPE(var)) diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index bc87da75de6..6429af67eb0 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_util.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/radiosity/CMakeLists.txt b/source/blender/radiosity/CMakeLists.txt deleted file mode 100644 index e76f7409f99..00000000000 --- a/source/blender/radiosity/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# $Id$ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -FILE(GLOB SRC intern/source/*.c) - -SET(INC - extern/include ../blenlib ../blenkernel ../makesdna ../editors/include - ../../../intern/guardedalloc ../render/extern/include - ../render/intern/include ../blenloader ../../../extern/glew/include -) - -BLENDERLIB_NOLIST(blender_radiosity "${SRC}" "${INC}") -#env.BlenderLib ( 'blender_radiosity', sources, Split(incs), [], libtype='core', priority=50 ) diff --git a/source/blender/radiosity/Makefile b/source/blender/radiosity/Makefile deleted file mode 100644 index 91a13e2fd57..00000000000 --- a/source/blender/radiosity/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Makes module object directory and bounces make to subdirectories. - -SOURCEDIR = source/blender/radiosity -DIRS = intern - -include nan_subdirs.mk diff --git a/source/blender/radiosity/SConscript b/source/blender/radiosity/SConscript deleted file mode 100644 index 29854d2ee83..00000000000 --- a/source/blender/radiosity/SConscript +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python -Import ('env') - -sources = env.Glob('intern/source/*.c') - -incs = 'extern/include ../blenlib ../blenkernel ../makesdna ../editors/include' -incs += ' #/intern/guardedalloc ../render/extern/include' -incs += ' ../render/intern/include ../blenloader #/extern/glew/include' - -incs += ' ' + env['BF_OPENGL_INC'] - -env.BlenderLib ( 'bf_radiosity', sources, Split(incs), [], libtype='core', priority=150 ) diff --git a/source/blender/radiosity/extern/include/radio.h b/source/blender/radiosity/extern/include/radio.h deleted file mode 100644 index e7f23302880..00000000000 --- a/source/blender/radiosity/extern/include/radio.h +++ /dev/null @@ -1,173 +0,0 @@ -/* *************************************** - - - - radio.h nov/dec 1992 - revised for Blender may 1999 - - $Id$ - - ***** BEGIN GPL LICENSE BLOCK ***** - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - All rights reserved. - - The Original Code is: all of this file. - - Contributor(s): none yet. - - ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef RADIO_H -#define RADIO_H -#define RADIO_H - -/* type include */ -#include "radio_types.h" - -extern RadGlobal RG; -struct View3D; -struct Scene; - -/* radfactors.c */ -extern float calcStokefactor(RPatch *shoot, RPatch *rp, RNode *rn, float *area); -extern void calcTopfactors(void); -void calcSidefactors(void); -extern void initradiosity(void); -extern void rad_make_hocos(RadView *vw); -extern void hemizbuf(RadView *vw); -extern int makeformfactors(RPatch *shoot); -extern void applyformfactors(RPatch *shoot); -extern RPatch *findshootpatch(void); -extern void setnodeflags(RNode *rn, int flag, int set); -extern void backface_test(RPatch *shoot); -extern void clear_backface_test(void); -extern void progressiverad(void); -extern void minmaxradelem(RNode *rn, float *min, float *max); -extern void minmaxradelemfilt(RNode *rn, float *min, float *max, float *errmin, float *errmax); -extern void subdivideshootElements(int it); -extern void subdivideshootPatches(int it); -extern void inithemiwindows(void); -extern void closehemiwindows(void); -void rad_init_energy(void); - -/* radio.c */ -void freeAllRad(struct Scene *scene); -int rad_phase(void); -void rad_status_str(char *str); -void rad_printstatus(void); -void rad_setlimits(struct Scene *scene); -void set_radglobal(struct Scene *scene); -void add_radio(struct Scene *scene); -void delete_radio(struct Scene *scene); -int rad_go(struct Scene *scene); -void rad_subdivshootpatch(struct Scene *scene); -void rad_subdivshootelem(struct Scene *scene); -void rad_limit_subdivide(struct Scene *scene); - -/* radnode.c */ -extern void setnodelimit(float limit); -extern float *mallocVert(void); -extern float *callocVert(void); -extern void freeVert(float *vert); -extern int totalRadVert(void); -extern RNode *mallocNode(void); -extern RNode *callocNode(void); -extern void freeNode(RNode *node); -extern void freeNode_recurs(RNode *node); -extern RPatch *mallocPatch(void); -extern RPatch *callocPatch(void); -extern void freePatch(RPatch *patch); -extern void replaceAllNode(RNode *, RNode *); -extern void replaceAllNodeInv(RNode *neighb, RNode *old); -extern void replaceAllNodeUp(RNode *neighb, RNode *old); -extern void replaceTestNode(RNode *, RNode **, RNode *, int , float *); -extern void free_fastAll(void); - -/* radnode.c */ -extern void start_fastmalloc(char *str); -extern int setvertexpointersNode(RNode *neighb, RNode *node, int level, float **v1, float **v2); -extern float edlen(float *v1, float *v2); -extern void deleteNodes(RNode *node); -extern void subdivideTriNode(RNode *node, RNode *edge); -extern void subdivideNode(RNode *node, RNode *edge); -extern int comparelevel(RNode *node, RNode *nb, int level); - -/* radpreprocess.c */ -extern void splitconnected(void); -extern int vergedge(const void *v1,const void *v2); -extern void addedge(float *v1, float *v2, EdSort *es); -extern void setedgepointers(void); -extern void rad_collect_meshes(struct Scene *scene, struct View3D *v3d); -extern void countelem(RNode *rn); -extern void countglobaldata(void); -extern void addelem(RNode ***el, RNode *rn, RPatch *rp); -extern void makeGlobalElemArray(void); -extern void remakeGlobaldata(void); -extern void splitpatch(RPatch *old); -extern void addpatch(RPatch *old, RNode *rn); -extern void converttopatches(void); -extern void make_elements(void); -extern void subdividelamps(void); -extern void maxsizePatches(void); -extern void subdiv_elements(void); - -/* radpostprocess.c */ -void addaccu(register char *z, register char *t); -void addaccuweight(register char *z, register char *t, int w); -void triaweight(Face *face, int *w1, int *w2, int *w3); -void init_face_tab(void); -Face *addface(void); -Face *makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn); -void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag); -void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag); -float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2); -void make_face_tab(void); -void filterFaces(void); -void calcfiltrad(RNode *rn, float *cd); -void filterNodes(void); -void removeEqualNodes(short limit); -void rad_addmesh(struct Scene *scene); -void rad_replacemesh(struct Scene *scene); - -/* raddisplay.c */ -extern char calculatecolor(float col); -extern void make_node_display(void); -extern void drawnodeWire(RNode *rn); -extern void drawsingnodeWire(RNode *rn); -extern void drawnodeSolid(RNode *rn); -extern void drawnodeGour(RNode *rn); -extern void drawpatch(RPatch *patch, unsigned int col); -extern void drawfaceGour(Face *face); -extern void drawfaceSolid(Face *face); -extern void drawfaceWire(Face *face); -extern void drawsquare(float *cent, float size, short cox, short coy); -extern void drawlimits(void); -extern void setcolNode(RNode *rn, unsigned int *col); -extern void pseudoAmb(void); -extern void rad_forcedraw(void); -extern void drawpatch_ext(RPatch *patch, unsigned int col); -extern void RAD_drawall(int depth_is_on); - -/* radrender.c */ -struct Render; -extern void do_radio_render(struct Render *re); -void end_radio_render(void); - -#endif /* RADIO_H */ - diff --git a/source/blender/radiosity/extern/include/radio_types.h b/source/blender/radiosity/extern/include/radio_types.h deleted file mode 100644 index 5a218ee71be..00000000000 --- a/source/blender/radiosity/extern/include/radio_types.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * radio_types.h - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* #include "misc_util.h" */ /* for listbase...*/ - - -#ifndef RADIO_TYPES_H -#define RADIO_TYPES_H - -#include "DNA_listBase.h" -#include "DNA_material_types.h" - -struct Render; -struct CustomData; - -#define PI M_PI -#define RAD_MAXFACETAB 1024 -#define RAD_NEXTFACE(a) if( ((a) & 1023)==0 ) face= RG.facebase[(a)>>10]; else face++; - -/* RG.phase */ -#define RAD_SHOOTE 1 -#define RAD_SHOOTP 2 -#define RAD_SOLVE 3 - -typedef struct RadView { - float cam[3], tar[3], up[3]; - float wx1, wx2, wy1, wy2; - float mynear, myfar; - float viewmat[4][4], winmat[4][4]; - unsigned int *rect, *rectz; - short rectx, recty; - int wid; - -} RadView; - -/* rn->f */ -#define RAD_PATCH 1 -#define RAD_SHOOT 2 -#define RAD_SUBDIV 4 -#define RAD_BACKFACE 8 -#define RAD_TWOSIDED 16 - - -typedef struct RNode { /* length: 104 */ - struct RNode *down1, *down2, *up; - struct RNode *ed1, *ed2, *ed3, *ed4; - struct RPatch *par; - - char lev1, lev2, lev3, lev4; /* edgelevels */ - short type; /* type: 4==QUAD, 3==TRIA */ - short f; - float *v1, *v2, *v3, *v4; - float totrad[3], area; - - unsigned int col; - int orig; /* index in custom face data */ -} RNode; - - -typedef struct Face { /* length: 52 */ - float *v1, *v2, *v3, *v4; - unsigned int col, matindex; - int orig; /* index in custom face data */ -} Face; - -/* rp->f1 */ -#define RAD_NO_SPLIT 1 - -typedef struct RPatch { - struct RPatch *next, *prev; - RNode *first; /* first node==patch */ - - struct Object *from; - - int type; /* 3: TRIA, 4: QUAD */ - short f, f1; /* flags f: if node, only for subdiv */ - - float ref[3], emit[3], unshot[3]; - float cent[3], norm[3]; - float area; - int matindex; - -} RPatch; - - -typedef struct VeNoCo { /* needed for splitconnected */ - struct VeNoCo *next; - float *v; - float *n; - float *col; - int flag; -} VeNoCo; - - -typedef struct EdSort { /* sort edges */ - float *v1, *v2; - RNode *node; - int nr; -} EdSort; - -typedef struct { - struct Radio *radio; - unsigned int *hemibuf; - struct ListBase patchbase; - int totpatch, totelem, totvert, totlamp; - RNode **elem; /* global array with all pointers */ - VeNoCo *verts; /* temporal vertices from patches */ - float *formfactors; /* 1 factor per element */ - float *topfactors, *sidefactors; /* LUT for delta's */ - int *index; /* LUT for above LUT */ - Face **facebase; - int totface; - float min[3], max[3], size[3], cent[3]; /* world */ - float maxsize, totenergy; - float patchmin, patchmax; - float elemmin, elemmax; - float radfactor, lostenergy, igamma; /* radfac is in button, radfactor is calculated */ - int phase; - struct Render *re; /* for calling hemizbuf correctly */ - /* to preserve materials as used before, max 16 */ - Material *matar[MAXMAT]; - int totmat; - - /* for preserving face data */ - int mfdatatot; - struct CustomData *mfdata; - struct RNode **mfdatanodes; - - /* this part is a copy of struct Radio */ - short hemires, maxiter; - short drawtype, flag; /* bit 0 en 1: show limits */ - short subshootp, subshoote, nodelim, maxsublamp; - int maxnode; - float convergence; - float radfac, gamma; /* for display */ - -} RadGlobal; - -#endif /* radio_types.h */ - diff --git a/source/blender/radiosity/intern/Makefile b/source/blender/radiosity/intern/Makefile deleted file mode 100644 index 456b51cc56e..00000000000 --- a/source/blender/radiosity/intern/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Makes module object directory and bounces make to subdirectories. - -SOURCEDIR = source/blender/radiosity/intern -DIRS = source - -include nan_subdirs.mk diff --git a/source/blender/radiosity/intern/source/Makefile b/source/blender/radiosity/intern/source/Makefile deleted file mode 100644 index 44b38de9bae..00000000000 --- a/source/blender/radiosity/intern/source/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# radiosity uses the render lib -# - -LIBNAME = radiosity -DIR = $(OCGDIR)/blender/$(LIBNAME) - -include nan_compile.mk - -CFLAGS += $(LEVEL_1_C_WARNINGS) - -CPPFLAGS += -I$(NAN_GLEW)/include -CPPFLAGS += -I$(OPENGL_HEADERS) - -# not very neat.... -CPPFLAGS += -I../../../blenkernel -CPPFLAGS += -I../../../blenlib -CPPFLAGS += -I../../../makesdna -CPPFLAGS += -I../../../imbuf -CPPFLAGS += -I../../../ -CPPFLAGS += -I../../../blenloader -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include - -# first /include is my own includes, second are the external includes -# third is the external interface. there should be a nicer way to say this -CPPFLAGS += -I../include -I../../../editors/include -I../../extern/include -CPPFLAGS += -I../../../render/extern/include -CPPFLAGS += -I../../../render/intern/include diff --git a/source/blender/radiosity/intern/source/raddisplay.c b/source/blender/radiosity/intern/source/raddisplay.c deleted file mode 100644 index ab9e8eedc28..00000000000 --- a/source/blender/radiosity/intern/source/raddisplay.c +++ /dev/null @@ -1,477 +0,0 @@ -/* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - raddisplay.c nov/dec 1992 - may 1999 - - - drawing - - color calculation for display during solving - - $Id$ - - *************************************** */ - -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "BLI_blenlib.h" - -#include "DNA_radio_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_global.h" -#include "BKE_main.h" - -#include "BIF_gl.h" - -#include "radio.h" - -/* cpack has to be endian-insensitive! (old irisgl function) */ -#define cpack(x) glColor3ub( ((x)&0xFF), (((x)>>8)&0xFF), (((x)>>16)&0xFF) ) - -char calculatecolor(float col) -{ - int b; - - if(RG.gamma==1.0) { - b= RG.radfactor*col; - } - else if(RG.gamma==2.0) { - b= RG.radfactor*sqrt(col); - } - else { - b= RG.radfactor*pow(col, RG.igamma); - } - - if(b>255) b=255; - return b; -} - -void make_node_display() -{ - RNode *rn, **el; - int a; - char *charcol; - - RG.igamma= 1.0/RG.gamma; - RG.radfactor= RG.radfac*pow(64*64, RG.igamma); - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - charcol= (char *)&( rn->col ); - - charcol[3]= calculatecolor(rn->totrad[0]); - charcol[2]= calculatecolor(rn->totrad[1]); - charcol[1]= calculatecolor(rn->totrad[2]); - - /* gouraudcolor */ - *(rn->v1+3)= 0; - *(rn->v2+3)= 0; - *(rn->v3+3)= 0; - if(rn->v4) *(rn->v4+3)= 0; - } - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - addaccuweight( (char *)&(rn->col), (char *)(rn->v1+3), 16 ); - addaccuweight( (char *)&(rn->col), (char *)(rn->v2+3), 16 ); - addaccuweight( (char *)&(rn->col), (char *)(rn->v3+3), 16 ); - if(rn->v4) addaccuweight( (char *)&(rn->col), (char *)(rn->v4+3), 16 ); - } -} - -void drawnodeWire(RNode *rn) -{ - - if(rn->down1) { - drawnodeWire(rn->down1); - drawnodeWire(rn->down2); - } - else { - glBegin(GL_LINE_LOOP); - glVertex3fv(rn->v1); - glVertex3fv(rn->v2); - glVertex3fv(rn->v3); - if(rn->type==4) glVertex3fv(rn->v4); - glEnd(); - } -} - -void drawsingnodeWire(RNode *rn) -{ - - glBegin(GL_LINE_LOOP); - glVertex3fv(rn->v1); - glVertex3fv(rn->v2); - glVertex3fv(rn->v3); - if(rn->type==4) glVertex3fv(rn->v4); - glEnd(); -} - -void drawnodeSolid(RNode *rn) -{ - char *cp; - - if(rn->down1) { - drawnodeSolid(rn->down1); - drawnodeSolid(rn->down2); - } - else { - cp= (char *)&rn->col; - glColor3ub(cp[3], cp[2], cp[1]); - glBegin(GL_POLYGON); - glVertex3fv(rn->v1); - glVertex3fv(rn->v2); - glVertex3fv(rn->v3); - if(rn->type==4) glVertex3fv(rn->v4); - glEnd(); - } -} - -void drawnodeGour(RNode *rn) -{ - char *cp; - - if(rn->down1) { - drawnodeGour(rn->down1); - drawnodeGour(rn->down2); - } - else { - glBegin(GL_POLYGON); - cp= (char *)(rn->v1+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v1); - - cp= (char *)(rn->v2+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v2); - - cp= (char *)(rn->v3+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v3); - - if(rn->type==4) { - cp= (char *)(rn->v4+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v4); - } - glEnd(); - } -} - -void drawpatch_ext(RPatch *patch, unsigned int col) -{ - ScrArea *sa, *oldsa; - View3D *v3d; - glDrawBuffer(GL_FRONT); - - return; // XXX - - cpack(col); - - oldsa= NULL; // XXX curarea; - -// sa= G.curscreen->areabase.first; - while(sa) { - if (sa->spacetype==SPACE_VIEW3D) { - v3d= sa->spacedata.first; - - /* use mywinget() here: otherwise it draws in header */ -// XXX if(sa->win != mywinget()) areawinset(sa->win); -// XXX persp(PERSP_VIEW); - if(v3d->zbuf) glDisable(GL_DEPTH_TEST); - drawnodeWire(patch->first); - if(v3d->zbuf) glEnable(GL_DEPTH_TEST); // pretty useless? - } - sa= sa->next; - } - -// XXX if(oldsa && oldsa!=curarea) areawinset(oldsa->win); - - glFlush(); - glDrawBuffer(GL_BACK); -} - - -void drawfaceGour(Face *face) -{ - char *cp; - - glBegin(GL_POLYGON); - cp= (char *)(face->v1+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v1); - - cp= (char *)(face->v2+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v2); - - cp= (char *)(face->v3+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v3); - - if(face->v4) { - cp= (char *)(face->v4+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v4); - } - glEnd(); - -} - -void drawfaceSolid(Face *face) -{ - char *cp; - - cp= (char *)&face->col; - glColor3ub(cp[3], cp[2], cp[1]); - - glBegin(GL_POLYGON); - glVertex3fv(face->v1); - glVertex3fv(face->v2); - glVertex3fv(face->v3); - if(face->v4) { - glVertex3fv(face->v4); - } - glEnd(); - -} - -void drawfaceWire(Face *face) -{ - char *cp; - - cp= (char *)&face->col; - glColor3ub(cp[3], cp[2], cp[1]); - - glBegin(GL_LINE_LOOP); - glVertex3fv(face->v1); - glVertex3fv(face->v2); - glVertex3fv(face->v3); - if(face->v4) { - glVertex3fv(face->v4); - } - glEnd(); - -} - -void drawsquare(float *cent, float size, short cox, short coy) -{ - float vec[3]; - - vec[0]= cent[0]; - vec[1]= cent[1]; - vec[2]= cent[2]; - - glBegin(GL_LINE_LOOP); - vec[cox]+= .5*size; - vec[coy]+= .5*size; - glVertex3fv(vec); - vec[coy]-= size; - glVertex3fv(vec); - vec[cox]-= size; - glVertex3fv(vec); - vec[coy]+= size; - glVertex3fv(vec); - glEnd(); -} - -void drawlimits() -{ - /* center around cent */ - short cox=0, coy=1; - - if((RG.flag & (RAD_SHOWLIMITS|RAD_SHOWZ))==RAD_SHOWZ) coy= 2; - if((RG.flag & (RAD_SHOWLIMITS|RAD_SHOWZ))==(RAD_SHOWLIMITS|RAD_SHOWZ)) { - cox= 1; - coy= 2; - } - - cpack(0); - drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy); - - drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy); - - cpack(0xFFFFFF); - drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy); - cpack(0xFFFF00); - drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy); - -} - -void setcolNode(RNode *rn, unsigned int *col) -{ - - if(rn->down1) { - setcolNode(rn->down1, col); - setcolNode(rn->down2, col); - } - rn->col= *col; - - *((unsigned int *)rn->v1+3)= *col; - *((unsigned int *)rn->v2+3)= *col; - *((unsigned int *)rn->v3+3)= *col; - if(rn->v4) *((unsigned int *)rn->v4+3)= *col; -} - -void pseudoAmb() -{ - RPatch *rp; - float fac; - char col[4]; - - /* sets pseudo ambient color in the nodes */ - - rp= RG.patchbase.first; - while(rp) { - - if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) { - col[1]= col[2]= col[3]= 255; - } - else { - fac= rp->norm[0]+ rp->norm[1]+ rp->norm[2]; - fac= 225.0*(3+fac)/6.0; - - col[3]= fac*rp->ref[0]; - col[2]= fac*rp->ref[1]; - col[1]= fac*rp->ref[2]; - } - - setcolNode(rp->first, (unsigned int *)col); - - rp= rp->next; - } -} - -void RAD_drawall(int depth_is_on) -{ - /* displays elements or faces */ - Face *face = NULL; - RNode **el; - RPatch *rp; - int a; - - if(!depth_is_on) { - glEnable(GL_DEPTH_TEST); - glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); - } - - if(RG.totface) { - if(RG.drawtype==RAD_GOURAUD) { - glShadeModel(GL_SMOOTH); - for(a=0; afirst); - rp= rp->next; - } - } - } - else { - el= RG.elem; - if(RG.drawtype==RAD_GOURAUD) { - glShadeModel(GL_SMOOTH); - for(a=RG.totelem; a>0; a--, el++) { - drawnodeGour(*el); - } - } - else if(RG.drawtype==RAD_SOLID) { - for(a=RG.totelem; a>0; a--, el++) { - drawnodeSolid(*el); - } - } - else { - cpack(0); - for(a=RG.totelem; a>0; a--, el++) { - drawnodeWire(*el); - } - } - } - glShadeModel(GL_FLAT); - - if(RG.totpatch) { - if(RG.flag & (RAD_SHOWLIMITS|RAD_SHOWZ)) { - if(depth_is_on) glDisable(GL_DEPTH_TEST); - drawlimits(); - if(depth_is_on) glEnable(GL_DEPTH_TEST); - } - } - if(!depth_is_on) { - glDisable(GL_DEPTH_TEST); - } -} - -void rad_forcedraw() -{ - ScrArea *sa, *oldsa; - - return; // XXX - - oldsa= NULL; // XXX curarea; - -/// sa= G.curscreen->areabase.first; - while(sa) { - if (sa->spacetype==SPACE_VIEW3D) { - /* use mywinget() here: othwerwise it draws in header */ -// XXX if(sa->win != mywinget()) areawinset(sa->win); -// XXX scrarea_do_windraw(sa); - } - sa= sa->next; - } -// XXX screen_swapbuffers(); - -// XXX if(oldsa && oldsa!=curarea) areawinset(oldsa->win); -} - diff --git a/source/blender/radiosity/intern/source/radfactors.c b/source/blender/radiosity/intern/source/radfactors.c deleted file mode 100644 index b87473dd811..00000000000 --- a/source/blender/radiosity/intern/source/radfactors.c +++ /dev/null @@ -1,939 +0,0 @@ -/* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - formfactors.c nov/dec 1992 - - $Id$ - - *************************************** */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_rand.h" - -#include "BKE_utildefines.h" -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" -#include "RE_render_ext.h" /* for `RE_zbufferall_radio and RE_zbufferall_radio */ - -/* locals */ -static void rad_setmatrices(RadView *vw); -static void clearsubflagelem(RNode *rn); -static void setsubflagelem(RNode *rn); - -RadView hemitop, hemiside; - -float calcStokefactor(RPatch *shoot, RPatch *rp, RNode *rn, float *area) -{ - float tvec[3], fac; - float vec[4][3]; /* vectors of shoot->cent to vertices rp */ - float cross[4][3]; /* cross products of this */ - float rad[4]; /* anlgles between vecs */ - - /* test for direction */ - VecSubf(tvec, shoot->cent, rp->cent); - if( tvec[0]*shoot->norm[0]+ tvec[1]*shoot->norm[1]+ tvec[2]*shoot->norm[2]>0.0) - return 0.0; - - if(rp->type==4) { - - /* corner vectors */ - VecSubf(vec[0], shoot->cent, rn->v1); - VecSubf(vec[1], shoot->cent, rn->v2); - VecSubf(vec[2], shoot->cent, rn->v3); - VecSubf(vec[3], shoot->cent, rn->v4); - - Normalize(vec[0]); - Normalize(vec[1]); - Normalize(vec[2]); - Normalize(vec[3]); - - /* cross product */ - Crossf(cross[0], vec[0], vec[1]); - Crossf(cross[1], vec[1], vec[2]); - Crossf(cross[2], vec[2], vec[3]); - Crossf(cross[3], vec[3], vec[0]); - Normalize(cross[0]); - Normalize(cross[1]); - Normalize(cross[2]); - Normalize(cross[3]); - - /* angles */ - rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2]; - rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2]; - rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2]; - rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2]; - - rad[0]= acos(rad[0]); - rad[1]= acos(rad[1]); - rad[2]= acos(rad[2]); - rad[3]= acos(rad[3]); - - /* Stoke formula */ - VecMulf(cross[0], rad[0]); - VecMulf(cross[1], rad[1]); - VecMulf(cross[2], rad[2]); - VecMulf(cross[3], rad[3]); - - VECCOPY(tvec, shoot->norm); - fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2]; - fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2]; - fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2]; - fac+= tvec[0]*cross[3][0]+ tvec[1]*cross[3][1]+ tvec[2]*cross[3][2]; - } - else { - /* corner vectors */ - VecSubf(vec[0], shoot->cent, rn->v1); - VecSubf(vec[1], shoot->cent, rn->v2); - VecSubf(vec[2], shoot->cent, rn->v3); - - Normalize(vec[0]); - Normalize(vec[1]); - Normalize(vec[2]); - - /* cross product */ - Crossf(cross[0], vec[0], vec[1]); - Crossf(cross[1], vec[1], vec[2]); - Crossf(cross[2], vec[2], vec[0]); - Normalize(cross[0]); - Normalize(cross[1]); - Normalize(cross[2]); - - /* angles */ - rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2]; - rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2]; - rad[2]= vec[2][0]*vec[0][0]+ vec[2][1]*vec[0][1]+ vec[2][2]*vec[0][2]; - - rad[0]= acos(rad[0]); - rad[1]= acos(rad[1]); - rad[2]= acos(rad[2]); - - /* Stoke formula */ - VecMulf(cross[0], rad[0]); - VecMulf(cross[1], rad[1]); - VecMulf(cross[2], rad[2]); - - VECCOPY(tvec, shoot->norm); - fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2]; - fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2]; - fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2]; - } - - *area= -fac/(2.0*PI); - return (*area * (shoot->area/rn->area)); -} - - -void calcTopfactors() -{ - float xsq , ysq, xysq; - float n; - float *fp; - int a, b, hres; - - fp = RG.topfactors; - hres= RG.hemires/2; - n= hres; - - for (a=0; aho); */ - /* ver->clip = testclip(ver->ho); */ -/* */ - /* } */ -} - -static void rad_setmatrices(RadView *vw) /* for hemi's */ -{ - float up1[3], len, twist; - - i_lookat(vw->cam[0], vw->cam[1], vw->cam[2], vw->tar[0], vw->tar[1], vw->tar[2], 0, vw->viewmat); - up1[0] = vw->viewmat[0][0]*vw->up[0] + vw->viewmat[1][0]*vw->up[1] + vw->viewmat[2][0]*vw->up[2]; - up1[1] = vw->viewmat[0][1]*vw->up[0] + vw->viewmat[1][1]*vw->up[1] + vw->viewmat[2][1]*vw->up[2]; - up1[2] = vw->viewmat[0][2]*vw->up[0] + vw->viewmat[1][2]*vw->up[1] + vw->viewmat[2][2]*vw->up[2]; - - len= up1[0]*up1[0]+up1[1]*up1[1]; - if(len>0.0) { - twist= -atan2(up1[0], up1[1]); - } - else twist= 0.0; - - i_lookat(vw->cam[0], vw->cam[1], vw->cam[2], vw->tar[0], vw->tar[1], vw->tar[2], (180.0*twist/M_PI), vw->viewmat); - - /* window matrix was set in inithemiwindows */ - -} - - -void hemizbuf(RadView *vw) -{ - float *factors; - unsigned int *rz; - int a, b, inda, hres; - - rad_setmatrices(vw); - RE_zbufferall_radio(vw, RG.elem, RG.totelem, RG.re); /* Render for when we got renderfaces */ - - /* count factors */ - if(vw->recty==vw->rectx) factors= RG.topfactors; - else factors= RG.sidefactors; - hres= RG.hemires/2; - - rz= vw->rect; - for(a=0; arecty; a++) { - inda= hres*RG.index[a]; - for(b=0; brectx; b++, rz++) { - if(*rznorm, vec); - len= Normalize(up); - /* this safety for input normals that are zero or illegal sized */ - if(a>3) return 0; - } while(len==0.0 || len>1.0); - - VECCOPY(hemitop.up, up); - VECCOPY(hemiside.up, shoot->norm); - - Crossf(side, shoot->norm, up); - - /* five targets */ - VecAddf(tar[0], shoot->cent, shoot->norm); - VecAddf(tar[1], shoot->cent, up); - VecSubf(tar[2], shoot->cent, up); - VecAddf(tar[3], shoot->cent, side); - VecSubf(tar[4], shoot->cent, side); - - /* camera */ - VECCOPY(hemiside.cam, shoot->cent); - VECCOPY(hemitop.cam, shoot->cent); - - /* do it! */ - VECCOPY(hemitop.tar, tar[0]); - hemizbuf(&hemitop); - - for(a=1; a<5; a++) { - VECCOPY(hemiside.tar, tar[a]); - hemizbuf(&hemiside); - } - - /* convert factors to real radiosity */ - re= RG.elem; - fp= RG.formfactors; - - overfl= 0; - for(a= RG.totelem; a>0; a--, re++, fp++) { - - if(*fp!=0.0) { - - *fp *= shoot->area/(*re)->area; - - if(*fp>1.0) { - overfl= 1; - *fp= 1.0001; - } - } - } - - if(overfl) { - if(shoot->first->down1) { - splitpatch(shoot); - return 0; - } - } - - return 1; -} - -void applyformfactors(RPatch *shoot) -{ - RPatch *rp; - RNode **el, *rn; - float *fp, *ref, unr, ung, unb, r, g, b, w; - int a; - - unr= shoot->unshot[0]; - ung= shoot->unshot[1]; - unb= shoot->unshot[2]; - - fp= RG.formfactors; - el= RG.elem; - for(a=0; apar; - ref= rp->ref; - - r= (*fp)*unr*ref[0]; - g= (*fp)*ung*ref[1]; - b= (*fp)*unb*ref[2]; - - w= rn->area/rp->area; - rn->totrad[0]+= r; - rn->totrad[1]+= g; - rn->totrad[2]+= b; - - rp->unshot[0]+= w*r; - rp->unshot[1]+= w*g; - rp->unshot[2]+= w*b; - } - } - - shoot->unshot[0]= shoot->unshot[1]= shoot->unshot[2]= 0.0; -} - -RPatch *findshootpatch() -{ - RPatch *rp, *shoot; - float energy, maxenergy; - - shoot= 0; - maxenergy= 0.0; - rp= RG.patchbase.first; - while(rp) { - energy= rp->unshot[0]*rp->area; - energy+= rp->unshot[1]*rp->area; - energy+= rp->unshot[2]*rp->area; - - if(energy>maxenergy) { - shoot= rp; - maxenergy= energy; - } - rp= rp->next; - } - - if(shoot) { - maxenergy/= RG.totenergy; - if(maxenergydown1) { - setnodeflags(rn->down1, flag, set); - setnodeflags(rn->down2, flag, set); - } - else { - if(set) rn->f |= flag; - else rn->f &= ~flag; - } -} - -void backface_test(RPatch *shoot) -{ - RPatch *rp; - float tvec[3]; - - rp= RG.patchbase.first; - while(rp) { - if(rp!=shoot) { - - VecSubf(tvec, shoot->cent, rp->cent); - if( tvec[0]*rp->norm[0]+ tvec[1]*rp->norm[1]+ tvec[2]*rp->norm[2]<0.0) { - setnodeflags(rp->first, RAD_BACKFACE, 1); - } - } - rp= rp->next; - } -} - -void clear_backface_test() -{ - RNode **re; - int a; - - re= RG.elem; - for(a= RG.totelem-1; a>=0; a--, re++) { - (*re)->f &= ~RAD_BACKFACE; - } - -} - -void rad_init_energy() -{ - /* call before shooting */ - /* keep patches and elements, clear all data */ - RNode **el, *rn; - RPatch *rp; - int a; - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - VECCOPY(rn->totrad, rn->par->emit); - } - - RG.totenergy= 0.0; - rp= RG.patchbase.first; - while(rp) { - VECCOPY(rp->unshot, rp->emit); - - RG.totenergy+= rp->unshot[0]*rp->area; - RG.totenergy+= rp->unshot[1]*rp->area; - RG.totenergy+= rp->unshot[2]*rp->area; - - rp->f= 0; - - rp= rp->next; - } -} - -void progressiverad() -{ - RPatch *shoot; - float unshot[3]; - int it= 0; - - rad_printstatus(); - rad_init_energy(); - - shoot=findshootpatch(); - - while( shoot ) { - - setnodeflags(shoot->first, RAD_SHOOT, 1); - - backface_test(shoot); - - drawpatch_ext(shoot, 0x88FF00); - - if(shoot->first->f & RAD_TWOSIDED) { - VECCOPY(unshot, shoot->unshot); - VecNegf(shoot->norm); - if(makeformfactors(shoot)) - applyformfactors(shoot); - VecNegf(shoot->norm); - VECCOPY(shoot->unshot, unshot); - } - - if( makeformfactors(shoot) ) { - applyformfactors(shoot); - - it++; - //XXX set_timecursor(it); - if( (it & 3)==1 ) { - make_node_display(); - rad_forcedraw(); - } - setnodeflags(shoot->first, RAD_SHOOT, 0); - } - - clear_backface_test(); - - //XXX if(blender_test_break()) break; - if(RG.maxiter && RG.maxiter<=it) break; - - shoot=findshootpatch(); - - } - -} - - -/* ************* subdivideshoot *********** */ - -void minmaxradelem(RNode *rn, float *min, float *max) -{ - int c; - - if(rn->down1) { - minmaxradelem(rn->down1, min, max); - minmaxradelem(rn->down2, min, max); - } - else { - for(c=0; c<3; c++) { - min[c]= MIN2(min[c], rn->totrad[c]); - max[c]= MAX2(max[c], rn->totrad[c]); - } - } -} - -void minmaxradelemfilt(RNode *rn, float *min, float *max, float *errmin, float *errmax) -{ - float col[3], area; - int c; - - if(rn->down1) { - minmaxradelemfilt(rn->down1, min, max, errmin, errmax); - minmaxradelemfilt(rn->down2, min, max, errmin, errmax); - } - else { - VECCOPY(col, rn->totrad); - - for(c=0; c<3; c++) { - min[c]= MIN2(min[c], col[c]); - max[c]= MAX2(max[c], col[c]); - } - - VecMulf(col, 2.0); - area= 2.0; - if(rn->ed1) { - VecAddf(col, rn->ed1->totrad, col); - area+= 1.0; - } - if(rn->ed2) { - VecAddf(col, rn->ed2->totrad, col); - area+= 1.0; - } - if(rn->ed3) { - VecAddf(col, rn->ed3->totrad, col); - area+= 1.0; - } - if(rn->ed4) { - VecAddf(col, rn->ed4->totrad, col); - area+= 1.0; - } - VecMulf(col, 1.0/area); - - for(c=0; c<3; c++) { - errmin[c]= MIN2(errmin[c], col[c]); - errmax[c]= MAX2(errmax[c], col[c]); - } - } -} - -static void setsubflagelem(RNode *rn) -{ - - if(rn->down1) { - setsubflagelem(rn->down1); - setsubflagelem(rn->down2); - } - else { - rn->f |= RAD_SUBDIV; - } -} - -static void clearsubflagelem(RNode *rn) -{ - - if(rn->down1) { - setsubflagelem(rn->down1); - setsubflagelem(rn->down2); - } - else { - rn->f &= ~RAD_SUBDIV; - } -} - -void subdivideshootElements(int it) -{ - RPatch *rp, *shoot; - RNode **el, *rn; - float *fp, err, stoke, area, min[3], max[3], errmin[3], errmax[3]; - int a, b, c, d, e, f, contin; - int maxlamp; - - if(RG.maxsublamp==0) maxlamp= RG.totlamp; - else maxlamp= RG.maxsublamp; - - while(it) { - rad_printstatus(); - rad_init_energy(); - it--; - - for(a=0; afirst, RAD_SHOOT, 1); - if( makeformfactors(shoot) ) { - - fp= RG.formfactors; - el= RG.elem; - for(b=RG.totelem; b>0; b--, el++) { - rn= *el; - - if( (rn->f & RAD_SUBDIV)==0 && *fp!=0.0) { - if(rn->par->emit[0]+rn->par->emit[1]+rn->par->emit[2]==0.0) { - - stoke= calcStokefactor(shoot, rn->par, rn, &area); - if(stoke!= 0.0) { - - err= *fp/stoke; - - /* area error */ - area*=(0.5*RG.hemires*RG.hemires); - - if(area>35.0) { - if(err<0.95 || err>1.05) { - if(err>0.05) { - rn->f |= RAD_SUBDIV; - rn->par->f |= RAD_SUBDIV; - } - } - } - } - - } - } - - fp++; - - } - - applyformfactors(shoot); - - if( (a & 3)==1 ) { - make_node_display(); - rad_forcedraw(); - } - - setnodeflags(shoot->first, RAD_SHOOT, 0); - } - else a--; - - //XXX if(blender_test_break()) break; - } - - /* test for extreme small color change within a patch with subdivflag */ - - rp= RG.patchbase.first; - - while(rp) { - if(rp->f & RAD_SUBDIV) { /* rp has elems that need subdiv */ - /* at least 4 levels deep */ - rn= rp->first->down1; - if(rn) { - rn= rn->down1; - if(rn) { - rn= rn->down1; - if(rn) rn= rn->down1; - } - } - if(rn) { - INIT_MINMAX(min, max); - /* errmin and max are the filtered colors */ - INIT_MINMAX(errmin, errmax); - minmaxradelemfilt(rp->first, min, max, errmin, errmax); - - /* if small difference between colors: no subdiv */ - /* also test for the filtered ones: but with higher critical level */ - - contin= 0; - a= abs( calculatecolor(min[0])-calculatecolor(max[0])); - b= abs( calculatecolor(errmin[0])-calculatecolor(errmax[0])); - if(a<15 || b<7) { - c= abs( calculatecolor(min[1])-calculatecolor(max[1])); - d= abs( calculatecolor(errmin[1])-calculatecolor(errmax[1])); - if(c<15 || d<7) { - e= abs( calculatecolor(min[2])-calculatecolor(max[2])); - f= abs( calculatecolor(errmin[2])-calculatecolor(errmax[2])); - if(e<15 || f<7) { - contin= 1; - clearsubflagelem(rp->first); - /* printf("%d %d %d %d %d %d\n", a, b, c, d, e, f); */ - } - } - } - if(contin) { - drawpatch_ext(rp, 0xFFFF); - } - } - } - rp->f &= ~RAD_SUBDIV; - rp= rp->next; - } - - contin= 0; - - el= RG.elem; - for(b=RG.totelem; b>0; b--, el++) { - rn= *el; - if(rn->f & RAD_SUBDIV) { - rn->f-= RAD_SUBDIV; - subdivideNode(rn, 0); - if(rn->down1) { - subdivideNode(rn->down1, 0); - subdivideNode(rn->down2, 0); - contin= 1; - } - } - } - makeGlobalElemArray(); - - //XXX if(contin==0 || blender_test_break()) break; - } - - make_node_display(); -} - -void subdivideshootPatches(int it) -{ - RPatch *rp, *shoot, *next; - float *fp, err, stoke, area; - int a, contin; - int maxlamp; - - if(RG.maxsublamp==0) maxlamp= RG.totlamp; - else maxlamp= RG.maxsublamp; - - while(it) { - rad_printstatus(); - rad_init_energy(); - it--; - - for(a=0; afirst, RAD_SHOOT, 1); - - if( makeformfactors(shoot) ) { - - fp= RG.formfactors; - rp= RG.patchbase.first; - while(rp) { - if(*fp!=0.0 && rp!=shoot) { - - stoke= calcStokefactor(shoot, rp, rp->first, &area); - if(stoke!= 0.0) { - if(area>.1) { /* does patch receive more than (about)10% of energy? */ - rp->f= RAD_SUBDIV; - } - else { - - err= *fp/stoke; - - /* area error */ - area*=(0.5*RG.hemires*RG.hemires); - - if(area>45.0) { - if(err<0.95 || err>1.05) { - if(err>0.05) { - - rp->f= RAD_SUBDIV; - - } - } - } - } - } - } - fp++; - - rp= rp->next; - } - - applyformfactors(shoot); - - if( (a & 3)==1 ) { - make_node_display(); - rad_forcedraw(); - } - - setnodeflags(shoot->first, RAD_SHOOT, 0); - - //XXX if(blender_test_break()) break; - } - else a--; - - } - - contin= 0; - - rp= RG.patchbase.first; - while(rp) { - next= rp->next; - if(rp->f & RAD_SUBDIV) { - if(rp->emit[0]+rp->emit[1]+rp->emit[2]==0.0) { - contin= 1; - subdivideNode(rp->first, 0); - if(rp->first->down1) { - subdivideNode(rp->first->down1, 0); - subdivideNode(rp->first->down2, 0); - } - } - } - rp= next; - } - - converttopatches(); - makeGlobalElemArray(); - - //XXX if(contin==0 || blender_test_break()) break; - } - make_node_display(); -} - -void inithemiwindows() -{ - RadView *vw; - - /* the hemiwindows */ - vw= &(hemitop); - memset(vw, 0, sizeof(RadView)); - vw->rectx= RG.hemires; - vw->recty= RG.hemires; - vw->rectz= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows"); - vw->rect= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows"); - vw->mynear= RG.maxsize/2000.0; - vw->myfar= 2.0*RG.maxsize; - vw->wx1= -vw->mynear; - vw->wx2= vw->mynear; - vw->wy1= -vw->mynear; - vw->wy2= vw->mynear; - - i_window(vw->wx1, vw->wx2, vw->wy1, vw->wy2, vw->mynear, vw->myfar, vw->winmat); - - hemiside= hemitop; - - vw= &(hemiside); - vw->recty/= 2; - vw->wy1= vw->wy2; - vw->wy2= 0.0; - - i_window(vw->wx1, vw->wx2, vw->wy1, vw->wy2, vw->mynear, vw->myfar, vw->winmat); - -} - -void closehemiwindows() -{ - - if(hemiside.rect) MEM_freeN(hemiside.rect); - if(hemiside.rectz) MEM_freeN(hemiside.rectz); - hemiside.rectz= 0; - hemiside.rect= 0; - hemitop.rectz= 0; - hemitop.rect= 0; -} diff --git a/source/blender/radiosity/intern/source/radio.c b/source/blender/radiosity/intern/source/radio.c deleted file mode 100644 index 63032b2d603..00000000000 --- a/source/blender/radiosity/intern/source/radio.c +++ /dev/null @@ -1,390 +0,0 @@ -/* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - radio.c nov/dec 1992 - may 1999 - - $Id$ - - - mainloop - - interactivity - - - - PREPROCES - - collect meshes - - spitconnected (all faces with different color and normals) - - setedgepointers (nodes pointing to neighbours) - - - EDITING - - min-max patch en min-max element size - - using this info patches subdividing - - lamp subdivide - - - if there are too many lamps for subdivide shooting: - - temporal join patches - - - SUBDIVIDE SHOOTING - - except for last shooting, this defines patch subdivide - - if subdivided patches still > 2*minsize : continue - - at the end create as many elements as possible - - als store if lamp (can still) cause subdivide. - - - REFINEMENT SHOOTING - - test for overflows (shootpatch subdivide) - - testen for extreme color transitions: - - if possible: shootpatch subdivide - - elements subdivide = start over ? - - continue itterate until ? - - - DEFINITIVE SHOOTING - - user indicates how many faces maximum and duration of itteration. - - - POST PROCESS - - join element- nodes when nothing happens in it (filter nodes, filter faces) - - define gamma & mul - - *************************************** */ - -#include -#include - -#include "MEM_guardedalloc.h" -#include "PIL_time.h" - -#include "BLI_blenlib.h" - -#include "DNA_object_types.h" -#include "DNA_radio_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* locals? This one was already done in radio.h... */ -/* void rad_status_str(char *str); */ - -RadGlobal RG= {0, 0}; - -void freeAllRad(Scene *scene) -{ - Base *base; - extern int Ntotvert, Ntotnode, Ntotpatch; - - /* clear flag that disables drawing the meshes */ - if(scene) { - base= (scene->base.first); - while(base) { - if(base->object->type==OB_MESH) { - base->flag &= ~OB_RADIO; - } - base= base->next; - } - } - - free_fastAll(); /* verts, nodes, patches */ - RG.patchbase.first= RG.patchbase.last= 0; - Ntotvert= Ntotnode= Ntotpatch= 0; - - closehemiwindows(); /* not real windows anymore... */ - if(RG.elem) MEM_freeN(RG.elem); - RG.elem= 0; - if(RG.verts) MEM_freeN(RG.verts); - RG.verts= 0; - if(RG.topfactors) MEM_freeN(RG.topfactors); - RG.topfactors= 0; - if(RG.sidefactors) MEM_freeN(RG.sidefactors); - RG.sidefactors= 0; - if(RG.formfactors) MEM_freeN(RG.formfactors); - RG.formfactors= 0; - if(RG.index) MEM_freeN(RG.index); - RG.index= 0; - if(RG.facebase) { - init_face_tab(); /* frees all tables */ - MEM_freeN(RG.facebase); - RG.facebase= 0; - } - - if(RG.mfdata) { - CustomData_free(RG.mfdata, RG.mfdatatot); - MEM_freeN(RG.mfdata); - MEM_freeN(RG.mfdatanodes); - RG.mfdatanodes= NULL; - RG.mfdata= NULL; - RG.mfdatatot= 0; - } - RG.totelem= RG.totpatch= RG.totvert= RG.totface= RG.totlamp= RG.totmat= 0; -} - -int rad_phase() -{ - int flag= 0; - - if(RG.totpatch) flag |= RAD_PHASE_PATCHES; - if(RG.totface) flag |= RAD_PHASE_FACES; - - return flag; -} - -void rad_status_str(char *str) -{ - extern int totfastmem; - int tot; - char *phase; - - tot= (RG.totface*sizeof(Face))/1024; - tot+= totfastmem/1024; - - if(RG.phase==RAD_SHOOTE) phase= "Phase: ELEMENT SUBD, "; - else if(RG.phase==RAD_SHOOTP) phase= "Phase: PATCH SUBD, "; - else if(RG.phase==RAD_SOLVE) phase= "Phase: SOLVE, "; - else if(RG.totpatch==0) phase= "Phase: COLLECT MESHES "; - else if(RG.totface) phase= "Phase: FINISHED, "; - else phase= "Phase: INIT, "; - - if(RG.totpatch==0) strcpy(str, phase); - else sprintf(str, "%s TotPatch: %d TotElem: %d Emit: %d Faces %d Mem: %d k ", phase, RG.totpatch, RG.totelem, RG.totlamp, RG.totface, tot); - - if(RG.phase==RAD_SOLVE) strcat(str, "(press ESC to stop)"); -} - -void rad_printstatus() -{ - /* actions always are started from a buttonswindow */ -// XX if(curarea) { -// scrarea_do_windraw(curarea); -// screen_swapbuffers(); -// } -} - -void rad_setlimits(Scene *scene) -{ - Radio *rad= scene->radio; - float fac; - - fac= 0.0005*rad->pama; - RG.patchmax= RG.maxsize*fac; - RG.patchmax*= RG.patchmax; - fac= 0.0005*rad->pami; - RG.patchmin= RG.maxsize*fac; - RG.patchmin*= RG.patchmin; - - fac= 0.0005*rad->elma; - RG.elemmax= RG.maxsize*fac; - RG.elemmax*= RG.elemmax; - fac= 0.0005*rad->elmi; - RG.elemmin= RG.maxsize*fac; - RG.elemmin*= RG.elemmin; -} - -void set_radglobal(Scene *scene) -{ - /* always call before any action is performed */ - Radio *rad= scene->radio; - - if(RG.radio==0) { - /* firsttime and to be sure */ - memset(&RG, 0, sizeof(RadGlobal)); - } - - if(rad==0) return; - - if(rad != RG.radio) { - if(RG.radio) freeAllRad(scene); - memset(&RG, 0, sizeof(RadGlobal)); - RG.radio= rad; - } - - RG.hemires= rad->hemires & 0xFFF0; - RG.drawtype= rad->drawtype; - RG.flag= rad->flag; - RG.subshootp= rad->subshootp; - RG.subshoote= rad->subshoote; - RG.nodelim= rad->nodelim; - RG.maxsublamp= rad->maxsublamp; - RG.maxnode= 2*rad->maxnode; /* in button:max elem, subdividing! */ - RG.convergence= rad->convergence/1000.0; - RG.radfac= rad->radfac; - RG.gamma= rad->gamma; - RG.maxiter= rad->maxiter; - - RG.re= NULL; /* struct render, for when call it from render engine */ - - rad_setlimits(scene); -} - -/* called from buttons.c */ -void add_radio(Scene *scene) -{ - Radio *rad; - - if(scene->radio) MEM_freeN(scene->radio); - rad= scene->radio= MEM_callocN(sizeof(Radio), "radio"); - - rad->hemires= 300; - rad->convergence= 0.1; - rad->radfac= 30.0; - rad->gamma= 2.0; - rad->drawtype= RAD_SOLID; - rad->subshootp= 1; - rad->subshoote= 2; - rad->maxsublamp= 0; - - rad->pama= 500; - rad->pami= 200; - rad->elma= 100; - rad->elmi= 20; - rad->nodelim= 0; - rad->maxnode= 10000; - rad->maxiter= 120; // arbitrary - rad->flag= 2; - set_radglobal(scene); -} - -void delete_radio(Scene *scene) -{ - freeAllRad(scene); - if(scene->radio) MEM_freeN(scene->radio); - scene->radio= 0; - - RG.radio= 0; -} - -int rad_go(Scene *scene) /* return 0 when user escapes */ -{ - double stime= PIL_check_seconds_timer(); - int retval; - - if(RG.totface) return 0; - - G.afbreek= 0; - - set_radglobal(scene); - initradiosity(); /* LUT's */ - inithemiwindows(); /* views */ - - maxsizePatches(); - - setnodelimit(RG.patchmin); - RG.phase= RAD_SHOOTP; - subdivideshootPatches(RG.subshootp); - - setnodelimit(RG.elemmin); - RG.phase= RAD_SHOOTE; - subdivideshootElements(RG.subshoote); - - setnodelimit(RG.patchmin); - subdividelamps(); - - setnodelimit(RG.elemmin); - - RG.phase= RAD_SOLVE; - subdiv_elements(); - - progressiverad(); - - removeEqualNodes(RG.nodelim); - - make_face_tab(); /* now anchored */ - - closehemiwindows(); - RG.phase= 0; - - stime= PIL_check_seconds_timer()-stime; - printf("Radiosity solving time: %dms\n", (int) (stime*1000)); - - if(G.afbreek==1) retval= 1; - else retval= 0; - - G.afbreek= 0; - - return retval; -} - -void rad_subdivshootpatch(Scene *scene) -{ - - if(RG.totface) return; - - G.afbreek= 0; - - set_radglobal(scene); - initradiosity(); /* LUT's */ - inithemiwindows(); /* views */ - - subdivideshootPatches(1); - - removeEqualNodes(RG.nodelim); - closehemiwindows(); - -// XXX allqueue(REDRAWVIEW3D, 1); -} - -void rad_subdivshootelem(Scene *scene) -{ - - if(RG.totface) return; - - G.afbreek= 0; - - set_radglobal(scene); - initradiosity(); /* LUT's */ - inithemiwindows(); /* views */ - - subdivideshootElements(1); - - removeEqualNodes(RG.nodelim); - closehemiwindows(); - -// XXX allqueue(REDRAWVIEW3D, 1); -} - -void rad_limit_subdivide(Scene *scene) -{ - - if(scene->radio==0) return; - - set_radglobal(scene); - - if(RG.totpatch==0) { - /* printf("exit: no relevant data\n"); */ - return; - } - - maxsizePatches(); - - init_face_tab(); /* free faces */ -} diff --git a/source/blender/radiosity/intern/source/radnode.c b/source/blender/radiosity/intern/source/radnode.c deleted file mode 100644 index fa23ca5da57..00000000000 --- a/source/blender/radiosity/intern/source/radnode.c +++ /dev/null @@ -1,1103 +0,0 @@ -/* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - node.c nov/dec 1992 - may 1999 - - $Id$ - - *************************************** */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" - -#include "BLO_sys_types.h" // for intptr_t support - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* locals */ -static void *malloc_fast(int size); -static void *calloc_fast(int size); -static void free_fast(void *poin, int siz); -static void deleteTriNodes(RNode *node); -/* lower because of local type define */ -/* void check_mallocgroup(MallocGroup *mg); */ - - -/* ********** fastmalloc ************** */ - -#define MAL_GROUPSIZE 256 -#define MAL_AVAILABLE 1 -#define MAL_FULL 2 - - - - -ListBase MallocBase= {0, 0}; -int totfastmem= 0; - -typedef struct MallocGroup { - struct MallocGroup *next, *prev; - short size, flag; - short curfree, tot; - char flags[MAL_GROUPSIZE]; - char *data; -} MallocGroup; - -/* one more local */ -void check_mallocgroup(MallocGroup *mg); - -void check_mallocgroup(MallocGroup *mg) -{ - int a; - char *cp; - - if(mg->tot==MAL_GROUPSIZE) { - mg->flag= MAL_FULL; - return; - } - - cp= mg->flags; - - if(mg->curfreecurfree+1]==0) { - mg->curfree++; - return; - } - } - if(mg->curfree>0) { - if(cp[mg->curfree-1]==0) { - mg->curfree--; - return; - } - } - - for(a=0; acurfree= a; - return; - } - } - printf("fastmalloc: shouldnt be here\n"); -} - -static void *malloc_fast(int size) -{ - MallocGroup *mg; - void *retval; - - mg= MallocBase.last; - while(mg) { - if(mg->size==size) { - if(mg->flag & MAL_AVAILABLE) { - mg->flags[mg->curfree]= 1; - mg->tot++; - retval= mg->data+mg->curfree*mg->size; - check_mallocgroup(mg); - return retval; - } - } - mg= mg->prev; - } - - /* no free block found */ - mg= MEM_callocN(sizeof(MallocGroup), "mallocgroup"); - BLI_addtail(&MallocBase, mg); - mg->data= MEM_mallocN(MAL_GROUPSIZE*size, "mallocgroupdata"); - mg->flag= MAL_AVAILABLE; - mg->flags[0]= 1; - mg->curfree= 1; - mg->size= size; - mg->tot= 1; - - totfastmem+= sizeof(MallocGroup)+MAL_GROUPSIZE*size; - - return mg->data; -} - -static void *calloc_fast(int size) -{ - void *poin; - - poin= malloc_fast(size); - memset(poin, 0, size); - - return poin; -} - -static void free_fast(void *poin, int size) -{ - MallocGroup *mg; - intptr_t val; - - mg= MallocBase.last; - while(mg) { - if(mg->size==size) { - if( ((intptr_t)poin) >= ((intptr_t)mg->data) ) { - if( ((intptr_t)poin) < ((intptr_t)(mg->data+MAL_GROUPSIZE*size)) ) { - val= ((intptr_t)poin) - ((intptr_t)mg->data); - val/= size; - mg->curfree= val; - mg->flags[val]= 0; - mg->flag= MAL_AVAILABLE; - - mg->tot--; - if(mg->tot==0) { - BLI_remlink(&MallocBase, mg); - MEM_freeN(mg->data); - MEM_freeN(mg); - totfastmem-= sizeof(MallocGroup)+MAL_GROUPSIZE*size; - } - return; - } - } - } - mg= mg->prev; - } - printf("fast free: pointer not in memlist %p size %d\n", - poin, size); -} - -/* security: only one function in a time can use it */ -static char *fastmallocstr= 0; - -void free_fastAll() -{ - MallocGroup *mg; - - mg= MallocBase.first; - while(mg) { - BLI_remlink(&MallocBase, mg); - MEM_freeN(mg->data); - MEM_freeN(mg); - mg= MallocBase.first; - } - totfastmem= 0; - fastmallocstr= 0; -} - -void start_fastmalloc(char *str) -{ - if(fastmallocstr) { -// XXX error("Fastmalloc in use: %s", fastmallocstr); - return; - } - fastmallocstr= str; -} - -/* **************************************** */ - -float nodelimit; - -void setnodelimit(float limit) -{ - nodelimit= limit; - -} - -/* ************ memory management *********** */ - -int Ntotvert=0, Ntotnode=0, Ntotpatch=0; - -float *mallocVert() -{ - Ntotvert++; - return (float *)malloc_fast(16); -} - -float *callocVert() -{ - Ntotvert++; - return (float *)calloc_fast(16); -} - -void freeVert(float *vert) -{ - free_fast(vert, 16); - Ntotvert--; -} - -int totalRadVert() -{ - return Ntotvert; -} - -RNode *mallocNode() -{ - Ntotnode++; - return (RNode *)malloc_fast(sizeof(RNode)); -} - -RNode *callocNode() -{ - Ntotnode++; - return (RNode *)calloc_fast(sizeof(RNode)); -} - -void freeNode(RNode *node) -{ - free_fast(node, sizeof(RNode)); - Ntotnode--; -} - -void freeNode_recurs(RNode *node) -{ - - if(node->down1) { - freeNode_recurs(node->down1); - freeNode_recurs(node->down2); - } - - node->down1= node->down2= 0; - freeNode(node); - -} - -RPatch *mallocPatch() -{ - Ntotpatch++; - return (RPatch *)malloc_fast(sizeof(RPatch)); -} - -RPatch *callocPatch() -{ - Ntotpatch++; - return (RPatch *)calloc_fast(sizeof(RPatch)); -} - -void freePatch(RPatch *patch) -{ - free_fast(patch, sizeof(RPatch)); - Ntotpatch--; -} - -/* ************ SUBDIVIDE *********** */ - - -void replaceAllNode(RNode *neighb, RNode *newn) -{ - /* changes from all neighbours the edgepointers that point to newn->up in new */ - int ok= 0; - - - if(neighb==0) return; - if(newn->up==0) return; - - if(neighb->ed1==newn->up) { - neighb->ed1= newn; - ok= 1; - } - else if(neighb->ed2==newn->up) { - neighb->ed2= newn; - ok= 1; - } - else if(neighb->ed3==newn->up) { - neighb->ed3= newn; - ok= 1; - } - else if(neighb->ed4==newn->up) { - neighb->ed4= newn; - ok= 1; - } - - if(ok && neighb->down1) { - replaceAllNode(neighb->down1, newn); - replaceAllNode(neighb->down2, newn); - } -} - -void replaceAllNodeInv(RNode *neighb, RNode *old) -{ - /* changes from all neighbours the edgepointers that point to old in old->up */ - if(neighb==0) return; - if(old->up==0) return; - - if(neighb->ed1==old) { - neighb->ed1= old->up; - } - else if(neighb->ed2==old) { - neighb->ed2= old->up; - } - else if(neighb->ed3==old) { - neighb->ed3= old->up; - } - else if(neighb->ed4==old) { - neighb->ed4= old->up; - } - - if(neighb->down1) { - replaceAllNodeInv(neighb->down1, old); - replaceAllNodeInv(neighb->down2, old); - } -} - -void replaceAllNodeUp(RNode *neighb, RNode *old) -{ - /* changes from all neighbours the edgepointers that point to old in old->up */ - if(neighb==0) return; - if(old->up==0) return; - neighb= neighb->up; - if(neighb==0) return; - - if(neighb->ed1==old) { - neighb->ed1= old->up; - } - else if(neighb->ed2==old) { - neighb->ed2= old->up; - } - else if(neighb->ed3==old) { - neighb->ed3= old->up; - } - else if(neighb->ed4==old) { - neighb->ed4= old->up; - } - - if(neighb->up) { - replaceAllNodeUp(neighb, old); - } -} - - -void replaceTestNode(RNode *neighb, RNode **edpp, RNode *newn, int level, float *vert) -{ - /* IF neighb->ed points to newn->up - * IF edgelevels equal - IF testvert is in neighb->ed - change pointers both ways - ELSE - RETURN - ELSE - IF neighb edgelevel is deeper - change neighb pointer - - */ - int ok= 0; - - if(neighb==0) return; - if(newn->up==0) return; - - if(neighb->ed1==newn->up) { - if(neighb->lev1==level) { - if(vert==neighb->v1 || vert==neighb->v2) { - *edpp= neighb; - neighb->ed1= newn; - } - else return; - } - else if(neighb->lev1>level) { - neighb->ed1= newn; - } - ok= 1; - } - else if(neighb->ed2==newn->up) { - if(neighb->lev2==level) { - if(vert==neighb->v2 || vert==neighb->v3) { - *edpp= neighb; - neighb->ed2= newn; - } - else return; - } - else if(neighb->lev2>level) { - neighb->ed2= newn; - } - ok= 1; - } - else if(neighb->ed3==newn->up) { - if(neighb->lev3==level) { - if(neighb->type==3) { - if(vert==neighb->v3 || vert==neighb->v1) { - *edpp= neighb; - neighb->ed3= newn; - } - else return; - } - else { - if(vert==neighb->v3 || vert==neighb->v4) { - *edpp= neighb; - neighb->ed3= newn; - } - else return; - } - } - else if(neighb->lev3>level) { - neighb->ed3= newn; - } - ok= 1; - } - else if(neighb->ed4==newn->up) { - if(neighb->lev4==level) { - if(vert==neighb->v4 || vert==neighb->v1) { - *edpp= neighb; - neighb->ed4= newn; - } - else return; - } - else if(neighb->lev4>level) { - neighb->ed4= newn; - } - ok= 1; - } - - if(ok && neighb->down1) { - replaceTestNode(neighb->down1, edpp, newn, level, vert); - replaceTestNode(neighb->down2, edpp, newn, level, vert); - } - -} - -int setvertexpointersNode(RNode *neighb, RNode *node, int level, float **v1, float **v2) -{ - /* compares edgelevels , if equal it sets the vertexpointers */ - - if(neighb==0) return 0; - - if(neighb->ed1==node) { - if(neighb->lev1==level) { - *v1= neighb->v1; - *v2= neighb->v2; - return 1; - } - } - else if(neighb->ed2==node) { - if(neighb->lev2==level) { - *v1= neighb->v2; - *v2= neighb->v3; - return 1; - } - } - else if(neighb->ed3==node) { - if(neighb->lev3==level) { - if(neighb->type==3) { - *v1= neighb->v3; - *v2= neighb->v1; - } - else { - *v1= neighb->v3; - *v2= neighb->v4; - } - return 1; - } - } - else if(neighb->ed4==node) { - if(neighb->lev4==level) { - *v1= neighb->v4; - *v2= neighb->v1; - return 1; - } - } - return 0; -} - -float edlen(float *v1, float *v2) -{ - return (v1[0]-v2[0])*(v1[0]-v2[0])+ (v1[1]-v2[1])*(v1[1]-v2[1])+ (v1[2]-v2[2])*(v1[2]-v2[2]); -} - - -void subdivideTriNode(RNode *node, RNode *edge) -{ - RNode *n1, *n2, *up; - float fu, fv, fl, *v1, *v2; /* , AreaT3Dfl(); ... from arithb... */ - int uvl; - - if(node->down1 || node->down2) { - /* printf("trinode: subd already done\n"); */ - return; - } - - /* defines subdivide direction */ - - if(edge==0) { - /* areathreshold */ - if(node->areav1, node->v2); - fv= edlen(node->v2, node->v3); - fl= edlen(node->v3, node->v1); - - if(fu>fv && fu>fl) uvl= 1; - else if(fv>fu && fv>fl) uvl= 2; - else uvl= 3; - } - else { - - if(edge==node->ed1) uvl= 1; - else if(edge==node->ed2) uvl= 2; - else uvl= 3; - } - - /* should neighbour nodes be deeper? Recursive! */ - n1= 0; - if(uvl==1) { - if(node->ed1 && node->ed1->down1==0) n1= node->ed1; - } - else if(uvl==2) { - if(node->ed2 && node->ed2->down1==0) n1= node->ed2; - } - else { - if(node->ed3 && node->ed3->down1==0) n1= node->ed3; - } - if(n1) { - up= node->up; - while(up) { /* also test for ed4 !!! */ - if(n1->ed1==up || n1->ed2==up || n1->ed3==up || n1->ed4==up) { - subdivideNode(n1, up); - break; - } - up= up->up; - } - } - - /* the subdividing */ - n1= mallocNode(); - memcpy(n1, node, sizeof(RNode)); - n2= mallocNode(); - memcpy(n2, node, sizeof(RNode)); - - n1->up= node; - n2->up= node; - - node->down1= n1; - node->down2= n2; - - /* subdivide edge 1 */ - if(uvl==1) { - - /* FIRST NODE gets edge 2 */ - n1->ed3= n2; - n1->lev3= 0; - replaceAllNode(n1->ed2, n1); - n1->lev1++; - replaceTestNode(n1->ed1, &(n1->ed1), n1, n1->lev1, n1->v2); - - /* SECOND NODE gets edge 3 */ - n2->ed2= n1; - n2->lev2= 0; - replaceAllNode(n2->ed3, n2); - n2->lev1++; - replaceTestNode(n2->ed1, &(n2->ed1), n2, n2->lev1, n2->v1); - - /* NEW VERTEX from edge 1 */ - if( setvertexpointersNode(n1->ed1, n1, n1->lev1, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v1= v2; - n2->v2= v2; - } - else { - n1->v1= v1; - n2->v2= v1; - } - } - else { - n1->v1= n2->v2= mallocVert(); - n1->v1[0]= 0.5*(node->v1[0]+ node->v2[0]); - n1->v1[1]= 0.5*(node->v1[1]+ node->v2[1]); - n1->v1[2]= 0.5*(node->v1[2]+ node->v2[2]); - n1->v1[3]= node->v1[3]; /* color */ - } - } - else if(uvl==2) { - - /* FIRST NODE gets edge 1 */ - n1->ed3= n2; - n1->lev3= 0; - replaceAllNode(n1->ed1, n1); - n1->lev2++; - replaceTestNode(n1->ed2, &(n1->ed2), n1, n1->lev2, n1->v2); - - /* SECOND NODE gets edge 3 */ - n2->ed1= n1; - n2->lev1= 0; - replaceAllNode(n2->ed3, n2); - n2->lev2++; - replaceTestNode(n2->ed2, &(n2->ed2), n2, n2->lev2, n2->v3); - - /* NEW VERTEX from edge 2 */ - if( setvertexpointersNode(n1->ed2, n1, n1->lev2, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v3= v2; - n2->v2= v2; - } - else { - n1->v3= v1; - n2->v2= v1; - } - } - else { - n1->v3= n2->v2= mallocVert(); - n1->v3[0]= 0.5*(node->v2[0]+ node->v3[0]); - n1->v3[1]= 0.5*(node->v2[1]+ node->v3[1]); - n1->v3[2]= 0.5*(node->v2[2]+ node->v3[2]); - n1->v3[3]= node->v1[3]; /* color */ - } - } - else if(uvl==3) { - - /* FIRST NODE gets edge 1 */ - n1->ed2= n2; - n1->lev2= 0; - replaceAllNode(n1->ed1, n1); - n1->lev3++; - replaceTestNode(n1->ed3, &(n1->ed3), n1, n1->lev3, n1->v1); - - /* SECOND NODE gets edge 2 */ - n2->ed1= n1; - n2->lev1= 0; - replaceAllNode(n2->ed2, n2); - n2->lev3++; - replaceTestNode(n2->ed3, &(n2->ed3), n2, n2->lev3, n2->v3); - - /* NEW VERTEX from edge 3 */ - if( setvertexpointersNode(n1->ed3, n1, n1->lev3, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v1) { - n1->v3= v2; - n2->v1= v2; - } - else { - n1->v3= v1; - n2->v1= v1; - } - } - else { - n1->v3= n2->v1= mallocVert(); - n1->v3[0]= 0.5*(node->v1[0]+ node->v3[0]); - n1->v3[1]= 0.5*(node->v1[1]+ node->v3[1]); - n1->v3[2]= 0.5*(node->v1[2]+ node->v3[2]); - n1->v3[3]= node->v3[3]; /* color */ - } - } - n1->area= AreaT3Dfl(n1->v1, n1->v2, n1->v3); - n2->area= AreaT3Dfl(n2->v1, n2->v2, n2->v3); - -} - - -void subdivideNode(RNode *node, RNode *edge) -{ - RNode *n1, *n2, *up; - float fu, fv, *v1, *v2;/*, AreaQ3Dfl(); ... from arithb... */ - int uvl; - - if(Ntotnode>RG.maxnode) return; - - if(node->type==3) { - subdivideTriNode(node, edge); - return; - } - - if(node->down1 || node->down2) { - /* printf("subdivide Node: already done \n"); */ - return; - } - - /* defines subdivide direction */ - - if(edge==0) { - /* areathreshold */ - if(node->areav1[0]- node->v2[0])+ fabs(node->v1[1]- node->v2[1]) +fabs(node->v1[2]- node->v2[2]); - fv= fabs(node->v1[0]- node->v4[0])+ fabs(node->v1[1]- node->v4[1]) +fabs(node->v1[2]- node->v4[2]); - if(fu>fv) uvl= 1; - else uvl= 2; - } - else { - if(edge==node->ed1 || edge==node->ed3) uvl= 1; - else uvl= 2; - } - - /* do neighbour nodes have to be deeper? Recursive! */ - n1= n2= 0; - if(uvl==1) { - if(node->ed1 && node->ed1->down1==0) n1= node->ed1; - if(node->ed3 && node->ed3->down1==0) n2= node->ed3; - } - else { - if(node->ed2 && node->ed2->down1==0) n1= node->ed2; - if(node->ed4 && node->ed4->down1==0) n2= node->ed4; - } - if(n1) { - up= node->up; - while(up) { - if(n1->ed1==up || n1->ed2==up || n1->ed3==up || n1->ed4==up) { - /* printf("recurs subd\n"); */ - subdivideNode(n1, up); - break; - } - up= up->up; - } - } - if(n2) { - up= node->up; - while(up) { - if(n2->ed1==up || n2->ed2==up || n2->ed3==up || n2->ed4==up) { - /* printf("recurs subd\n"); */ - subdivideNode(n2, up); - break; - } - up= up->up; - } - } - - /* the subdividing */ - n1= mallocNode(); - memcpy(n1, node, sizeof(RNode)); - n2= mallocNode(); - memcpy(n2, node, sizeof(RNode)); - - n1->up= node; - n2->up= node; - - node->down1= n1; - node->down2= n2; - - /* subdivide edge 1 and 3 */ - if(uvl==1) { - - /* FIRST NODE gets edge 2 */ - n1->ed4= n2; - n1->lev4= 0; - replaceAllNode(n1->ed2, n1); - n1->lev1++; - n1->lev3++; - replaceTestNode(n1->ed1, &(n1->ed1), n1, n1->lev1, n1->v2); - replaceTestNode(n1->ed3, &(n1->ed3), n1, n1->lev3, n1->v3); - - /* SECOND NODE gets edge 4 */ - n2->ed2= n1; - n2->lev2= 0; - replaceAllNode(n2->ed4, n2); - n2->lev1++; - n2->lev3++; - replaceTestNode(n2->ed1, &(n2->ed1), n2, n2->lev1, n2->v1); - replaceTestNode(n2->ed3, &(n2->ed3), n2, n2->lev3, n2->v4); - - /* NEW VERTEX from edge 1 */ - if( setvertexpointersNode(n1->ed1, n1, n1->lev1, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v1= v2; - n2->v2= v2; - } - else { - n1->v1= v1; - n2->v2= v1; - } - } - else { - n1->v1= n2->v2= mallocVert(); - n1->v1[0]= 0.5*(node->v1[0]+ node->v2[0]); - n1->v1[1]= 0.5*(node->v1[1]+ node->v2[1]); - n1->v1[2]= 0.5*(node->v1[2]+ node->v2[2]); - n1->v1[3]= node->v1[3]; /* color */ - } - - /* NEW VERTEX from edge 3 */ - if( setvertexpointersNode(n1->ed3, n1, n1->lev3, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v3) { - n1->v4= v2; - n2->v3= v2; - } - else { - n1->v4= v1; - n2->v3= v1; - } - } - else { - n1->v4= n2->v3= mallocVert(); - n1->v4[0]= 0.5*(node->v3[0]+ node->v4[0]); - n1->v4[1]= 0.5*(node->v3[1]+ node->v4[1]); - n1->v4[2]= 0.5*(node->v3[2]+ node->v4[2]); - n1->v4[3]= node->v4[3]; /* color */ - } - } - /* subdivide edge 2 and 4 */ - else if(uvl==2) { - - /* FIRST NODE gets edge 1 */ - n1->ed3= n2; - n1->lev3= 0; - replaceAllNode(n1->ed1, n1); - n1->lev2++; - n1->lev4++; - replaceTestNode(n1->ed2, &(n1->ed2), n1, n1->lev2, n1->v2); - replaceTestNode(n1->ed4, &(n1->ed4), n1, n1->lev4, n1->v1); - - /* SECOND NODE gets edge 3 */ - n2->ed1= n1; - n2->lev1= 0; - replaceAllNode(n2->ed3, n2); - n2->lev2++; - n2->lev4++; - replaceTestNode(n2->ed2, &(n2->ed2), n2, n2->lev2, n2->v3); - replaceTestNode(n2->ed4, &(n2->ed4), n2, n2->lev4, n2->v4); - - /* NEW VERTEX from edge 2 */ - if( setvertexpointersNode(n1->ed2, n1, n1->lev2, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v3= v2; - n2->v2= v2; - } - else { - n1->v3= v1; - n2->v2= v1; - } - } - else { - n1->v3= n2->v2= mallocVert(); - n1->v3[0]= 0.5*(node->v2[0]+ node->v3[0]); - n1->v3[1]= 0.5*(node->v2[1]+ node->v3[1]); - n1->v3[2]= 0.5*(node->v2[2]+ node->v3[2]); - n1->v3[3]= node->v3[3]; /* color */ - } - - /* NEW VERTEX from edge 4 */ - if( setvertexpointersNode(n1->ed4, n1, n1->lev4, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v1) { - n1->v4= v2; - n2->v1= v2; - } - else { - n1->v4= v1; - n2->v1= v1; - } - } - else { - n1->v4= n2->v1= mallocVert(); - n1->v4[0]= 0.5*(node->v1[0]+ node->v4[0]); - n1->v4[1]= 0.5*(node->v1[1]+ node->v4[1]); - n1->v4[2]= 0.5*(node->v1[2]+ node->v4[2]); - n1->v4[3]= node->v4[3]; /* color */ - } - } - - n1->area= AreaQ3Dfl(n1->v1, n1->v2, n1->v3, n1->v4); - n2->area= AreaQ3Dfl(n2->v1, n2->v2, n2->v3, n2->v4); - -} - -int comparelevel(RNode *node, RNode *nb, int level) -{ - /* recursive descent: test with deepest node */ - /* return 1 means equal or higher */ - - if(nb==0) return 1; - - if(nb->down1) { - return 0; - - /* THERE IS AN ERROR HERE, BUT WHAT? (without this function the system - works too, but is slower) (ton) */ - - /* - n1= nb->down1; - if(n1->ed1==node) return comparelevel(node, n1, level); - if(n1->ed2==node) return comparelevel(node, n1, level); - if(n1->ed3==node) return comparelevel(node, n1, level); - if(n1->ed4==node) return comparelevel(node, n1, level); - n1= nb->down2; - if(n1->ed1==node) return comparelevel(node, n1, level); - if(n1->ed2==node) return comparelevel(node, n1, level); - if(n1->ed3==node) return comparelevel(node, n1, level); - if(n1->ed4==node) return comparelevel(node, n1, level); - printf(" dit kan niet "); - return 0; - */ - - } - - if(nb->down1==0) { - /* if(nb->ed1==node) return (nb->lev1<=level); */ - /* if(nb->ed2==node) return (nb->lev2<=level); */ - /* if(nb->ed3==node) return (nb->lev3<=level); */ - /* if(nb->ed4==node) return (nb->lev4<=level); */ - - return 1; /* is higher node */ - } - return 1; -} - -static void deleteTriNodes(RNode *node) /* both children of node */ -{ - RNode *n1, *n2; - - /* if neighbour nodes are deeper: no delete */ - /* just test 2 nodes, from the others the level doesn't change */ - - n1= node->down1; - n2= node->down2; - - if(n1==0 || n2==0) return; - - if(n1->down1 || n2->down1) return; - - /* at the edges no subdivided node is allowed */ - - if(n1->ed1 && n1->ed1->down1) return; - if(n1->ed2 && n1->ed2->down1) return; - if(n1->ed3 && n1->ed3->down1) return; - - if(n2->ed1 && n2->ed1->down1) return; - if(n2->ed2 && n2->ed2->down1) return; - if(n2->ed3 && n2->ed3->down1) return; - - replaceAllNodeInv(n1->ed1, n1); - replaceAllNodeInv(n1->ed2, n1); - replaceAllNodeInv(n1->ed3, n1); - - replaceAllNodeUp(n1->ed1, n1); - replaceAllNodeUp(n1->ed2, n1); - replaceAllNodeUp(n1->ed3, n1); - - replaceAllNodeInv(n2->ed1, n2); - replaceAllNodeInv(n2->ed2, n2); - replaceAllNodeInv(n2->ed3, n2); - - replaceAllNodeUp(n2->ed1, n2); - replaceAllNodeUp(n2->ed2, n2); - replaceAllNodeUp(n2->ed3, n2); - - n1->down1= (RNode *)12; /* for debug */ - n2->down1= (RNode *)12; - - freeNode(n1); - freeNode(n2); - node->down1= node->down2= 0; - -} - - /* both children of node */ -void deleteNodes(RNode *node) -{ - RNode *n1, *n2; - - /* if neighbour nodes are deeper: no delete */ - /* just test 2 nodes, from the others the level doesn't change */ - - if(node->type==3) { - deleteTriNodes(node); - return; - } - - n1= node->down1; - n2= node->down2; - - if(n1==0 || n2==0) return; - - if(n1->down1 || n2->down1) return; - - if(n1->ed3==n2) { - - /* at the edges no subdivided node is allowed */ - - if(n1->ed1 && n1->ed1->down1) return; - if(n1->ed2 && n1->ed2->down1) return; - if(n1->ed4 && n1->ed4->down1) return; - - if(n2->ed2 && n2->ed2->down1) return; - if(n2->ed3 && n2->ed3->down1) return; - if(n2->ed4 && n2->ed4->down1) return; - - replaceAllNodeInv(n1->ed1, n1); - replaceAllNodeInv(n1->ed2, n1); - replaceAllNodeInv(n1->ed4, n1); - - replaceAllNodeUp(n1->ed1, n1); - replaceAllNodeUp(n1->ed2, n1); - replaceAllNodeUp(n1->ed4, n1); - - replaceAllNodeInv(n2->ed2, n2); - replaceAllNodeInv(n2->ed3, n2); - replaceAllNodeInv(n2->ed4, n2); - - replaceAllNodeUp(n2->ed2, n2); - replaceAllNodeUp(n2->ed3, n2); - replaceAllNodeUp(n2->ed4, n2); - - n1->down1= (RNode *)12; /* for debug */ - n2->down1= (RNode *)12; - - freeNode(n1); - freeNode(n2); - node->down1= node->down2= 0; - - return; - } - else if(n1->ed4==n2) { - - if(n1->ed1 && n1->ed1->down1) return; - if(n1->ed2 && n1->ed2->down1) return; - if(n1->ed3 && n1->ed3->down1) return; - - if(n2->ed1 && n2->ed1->down1) return; - if(n2->ed3 && n2->ed3->down1) return; - if(n2->ed4 && n2->ed4->down1) return; - - replaceAllNodeInv(n1->ed1, n1); - replaceAllNodeInv(n1->ed2, n1); - replaceAllNodeInv(n1->ed3, n1); - - replaceAllNodeUp(n1->ed1, n1); - replaceAllNodeUp(n1->ed2, n1); - replaceAllNodeUp(n1->ed3, n1); - - replaceAllNodeInv(n2->ed1, n2); - replaceAllNodeInv(n2->ed3, n2); - replaceAllNodeInv(n2->ed4, n2); - - replaceAllNodeUp(n2->ed1, n2); - replaceAllNodeUp(n2->ed3, n2); - replaceAllNodeUp(n2->ed4, n2); - - n1->down1= (RNode *)12; /* for debug */ - n2->down1= (RNode *)12; - - freeNode(n1); - freeNode(n2); - node->down1= node->down2= 0; - - return; - } - -} - - diff --git a/source/blender/radiosity/intern/source/radpostprocess.c b/source/blender/radiosity/intern/source/radpostprocess.c deleted file mode 100644 index 6912c737a51..00000000000 --- a/source/blender/radiosity/intern/source/radpostprocess.c +++ /dev/null @@ -1,824 +0,0 @@ -/* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - radpostprocess.c nov/dec 1992 - may 1999 - - - faces - - filtering and node-limit - - apply to meshes - $Id$ - - *************************************** */ - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_ghash.h" - -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_radio_types.h" -#include "DNA_scene_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_material.h" -#include "BKE_mesh.h" -#include "BKE_object.h" -#include "BKE_utildefines.h" - -#include "radio.h" - -/* locals? not. done in radio.h... */ -/* void rad_addmesh(void); */ -/* void rad_replacemesh(void); */ - -void addaccu(register char *z, register char *t) -{ - register int div, mul; - - mul= *t; - div= mul+1; - (*t)++; - - t[1]= (mul*t[1]+z[1])/div; - t[2]= (mul*t[2]+z[2])/div; - t[3]= (mul*t[3]+z[3])/div; - -} - -void addaccuweight(register char *z, register char *t, int w) -{ - register int div, mul; - - if(w==0) w= 1; - - mul= *t; - div= mul+w; - if(div>255) return; - (*t)= div; - - t[1]= (mul*t[1]+w*z[1])/div; - t[2]= (mul*t[2]+w*z[2])/div; - t[3]= (mul*t[3]+w*z[3])/div; - -} - -void triaweight(Face *face, int *w1, int *w2, int *w3) -{ - float n1[3], n2[3], n3[3], temp; - - n1[0]= face->v2[0]-face->v1[0]; - n1[1]= face->v2[1]-face->v1[1]; - n1[2]= face->v2[2]-face->v1[2]; - n2[0]= face->v3[0]-face->v2[0]; - n2[1]= face->v3[1]-face->v2[1]; - n2[2]= face->v3[2]-face->v2[2]; - n3[0]= face->v1[0]-face->v3[0]; - n3[1]= face->v1[1]-face->v3[1]; - n3[2]= face->v1[2]-face->v3[2]; - Normalize(n1); - Normalize(n2); - Normalize(n3); - temp= 32.0/(PI); - *w1= 0.5+temp*acos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]); - *w2= 0.5+temp*acos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); - *w3= 0.5+temp*acos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); - -} - - - -void init_face_tab() -{ - int a= 0; - - if(RG.facebase==0) { - RG.facebase= MEM_callocN(sizeof(void *)*RAD_MAXFACETAB, "init_face_tab"); - } - for(a=0; aRAD_MAXFACETAB*1024 ) { - printf("error in addface: %d\n", RG.totface); - return 0; - } - a= RG.totface>>10; - face= RG.facebase[a]; - if(face==0) { - face= MEM_callocN(1024*sizeof(Face),"addface"); - RG.facebase[a]= face; - } - face+= (RG.totface & 1023); - - RG.totface++; - - return face; - -} - -Face * makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn) -{ - Face *face; - - face= addface(); - face->v1= v1; - face->v2= v2; - face->v3= v3; - face->v4= v4; - face->col= rn->col; - face->matindex= rn->par->matindex; - face->orig= rn->orig; - - return face; -} - -void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag) -{ - Face *face; - - switch(flag) { - case 1: - face = makeface(rn->v1, v1, rn->v4, NULL, rn); - face = makeface(v1, rn->v3, rn->v4, NULL, rn); - face = makeface(v1, rn->v2, rn->v3, NULL, rn); - break; - case 2: - face = makeface(rn->v2, v2, rn->v1, NULL, rn); - face = makeface(v2, rn->v4, rn->v1, NULL, rn); - face = makeface(v2, rn->v3, rn->v4, NULL, rn); - break; - case 4: - face = makeface(rn->v3, v3, rn->v2, NULL, rn); - face = makeface(v3, rn->v1, rn->v2, NULL, rn); - face = makeface(v3, rn->v4, rn->v1, NULL, rn); - break; - case 8: - face = makeface(rn->v4, v4, rn->v3, NULL, rn); - face = makeface(v4, rn->v2, rn->v3, NULL, rn); - face = makeface(v4, rn->v1, rn->v2, NULL, rn); - break; - case 3: - face = makeface(rn->v1, v1, rn->v4, NULL, rn); - face = makeface(v1, v2, rn->v4, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - face = makeface(v2, rn->v3, rn->v4, NULL, rn); - break; - case 6: - face = makeface(rn->v2, v2, rn->v1, NULL, rn); - face = makeface(v2, v3, rn->v1, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - face = makeface(v3, rn->v4, rn->v1, NULL, rn); - break; - case 12: - face = makeface(rn->v3, v3, rn->v2, NULL, rn); - face = makeface(v3, v4, rn->v2, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - face = makeface(v4, rn->v1, rn->v2, NULL, rn); - break; - case 9: - face = makeface(rn->v4, v4, rn->v3, NULL, rn); - face = makeface(v4, v1, rn->v3, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - face = makeface(v1, rn->v2, rn->v3, NULL, rn); - break; - case 5: - face = makeface(rn->v1, v1, v3, rn->v4, rn); - face = makeface(v1, rn->v2, rn->v3, v3, rn); - break; - case 10: - face = makeface(rn->v1, rn->v2, v2, v4, rn); - face = makeface(v4, v2, rn->v3, rn->v4, rn); - break; - case 7: - face = makeface(rn->v1, v1, v3, rn->v4, rn); - face = makeface(v1, v2, v3, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - break; - case 14: - face = makeface(rn->v2, v2, v4, rn->v1, rn); - face = makeface(v2, v3, v4, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - break; - case 13: - face = makeface(rn->v3, v3, v1, rn->v2, rn); - face = makeface(v3, v4, v1, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - break; - case 11: - face = makeface(rn->v4, v4, v2, rn->v3, rn); - face = makeface(v4, v1, v2, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - break; - case 15: - face = makeface(v1, v2, v3, v4, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - break; - } -} - -void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag) -{ - Face *face; - - switch(flag) { - case 1: - face = makeface(rn->v1, v1, rn->v3, NULL, rn); - face = makeface(v1, rn->v2, rn->v3, NULL, rn); - break; - case 2: - face = makeface(rn->v2, v2, rn->v1, NULL, rn); - face = makeface(v2, rn->v3, rn->v1, NULL, rn); - break; - case 4: - face = makeface(rn->v3, v3, rn->v2, NULL, rn); - face = makeface(v3, rn->v1, rn->v2, NULL, rn); - break; - case 3: - face = makeface(rn->v1, v2, rn->v3, NULL, rn); - face = makeface(rn->v1, v1, v2, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - break; - case 6: - face = makeface(rn->v2, v3, rn->v1, NULL, rn); - face = makeface(rn->v2, v2, v3, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - break; - case 5: - face = makeface(rn->v3, v1, rn->v2, NULL, rn); - face = makeface(rn->v3, v3, v1, NULL, rn); - face = makeface(v3, rn->v1, v1, NULL, rn); - break; - - case 7: - face = makeface(v1, v2, v3, NULL, rn); - face = makeface(rn->v1, v1, v3, NULL, rn); - face = makeface(rn->v2, v2, v1, NULL, rn); - face = makeface(rn->v3, v3, v2, NULL, rn); - break; - } -} - - -float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2) -{ - int test= 0; - - if(nb==0) return 0; - - if(nb->ed1==node) { - if(nb->v1==v1 || nb->v1==v2) test++; - if(nb->v2==v1 || nb->v2==v2) test+=2; - if(test==1) return nb->v2; - else if(test==2) return nb->v1; - } - else if(nb->ed2==node) { - if(nb->v2==v1 || nb->v2==v2) test++; - if(nb->v3==v1 || nb->v3==v2) test+=2; - if(test==1) return nb->v3; - else if(test==2) return nb->v2; - } - else if(nb->ed3==node) { - if(nb->type==4) { - if(nb->v3==v1 || nb->v3==v2) test++; - if(nb->v4==v1 || nb->v4==v2) test+=2; - if(test==1) return nb->v4; - else if(test==2) return nb->v3; - } - else { - if(nb->v3==v1 || nb->v3==v2) test++; - if(nb->v1==v1 || nb->v1==v2) test+=2; - if(test==1) return nb->v1; - else if(test==2) return nb->v3; - } - } - else if(nb->ed4==node) { - if(nb->v4==v1 || nb->v4==v2) test++; - if(nb->v1==v1 || nb->v1==v2) test+=2; - if(test==1) return nb->v1; - else if(test==2) return nb->v4; - } - return 0; -} - -void make_face_tab() /* takes care of anchoring */ -{ - RNode *rn, **el; - Face *face = NULL; - float *v1, *v2, *v3, *v4; - int a, flag, w1, w2, w3; - char *charcol; - - if(RG.totelem==0) return; - - init_face_tab(); - - RG.igamma= 1.0/RG.gamma; - RG.radfactor= RG.radfac*pow(64*64, RG.igamma); - - /* convert face colors */ - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - charcol= (char *)&( rn->col ); - - charcol[3]= calculatecolor(rn->totrad[0]); - charcol[2]= calculatecolor(rn->totrad[1]); - charcol[1]= calculatecolor(rn->totrad[2]); - } - - /* check nodes and make faces */ - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - - rn= *el; - - rn->v1[3]= 0.0; - rn->v2[3]= 0.0; - rn->v3[3]= 0.0; - if(rn->v4) rn->v4[3]= 0.0; - - /* test edges for subdivide */ - flag= 0; - v1= v2= v3= v4= 0; - if(rn->ed1) { - v1= findmiddlevertex(rn, rn->ed1->down1, rn->v1, rn->v2); - if(v1) flag |= 1; - } - if(rn->ed2) { - v2= findmiddlevertex(rn, rn->ed2->down1, rn->v2, rn->v3); - if(v2) flag |= 2; - } - if(rn->ed3) { - if(rn->type==4) - v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v4); - else - v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v1); - if(v3) flag |= 4; - } - if(rn->ed4) { - v4= findmiddlevertex(rn, rn->ed4->down1, rn->v4, rn->v1); - if(v4) flag |= 8; - } - - /* using flag and vertexpointers now Faces can be made */ - - if(flag==0) { - makeface(rn->v1, rn->v2, rn->v3, rn->v4, rn); - } - else if(rn->type==4) anchorQuadface(rn, v1, v2, v3, v4, flag); - else anchorTriface(rn, v1, v2, v3, flag); - } - - /* add */ - for(a=0; av4) { - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 ); - } - else { - triaweight(face, &w1, &w2, &w3); - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 ); - } - } - -} - -void filterFaces() -{ - /* put vertex colors in faces, and put them back */ - - Face *face = NULL; - int a, w1, w2, w3; - - if(RG.totface==0) return; - - /* clear */ - for(a=0; acol= 0; - } - - /* add: vertices with faces */ - for(a=0; av4) { - addaccuweight( (char *)(face->v1+3), (char *)&(face->col), 16 ); - addaccuweight( (char *)(face->v2+3), (char *)&(face->col), 16 ); - addaccuweight( (char *)(face->v3+3), (char *)&(face->col), 16 ); - addaccuweight( (char *)(face->v4+3), (char *)&(face->col), 16 ); - } - else { - triaweight(face, &w1, &w2, &w3); - addaccuweight( (char *)(face->v1+3), (char *)&(face->col), w1 ); - addaccuweight( (char *)(face->v2+3), (char *)&(face->col), w2 ); - addaccuweight( (char *)(face->v3+3), (char *)&(face->col), w3 ); - } - } - - /* clear */ - for(a=0; av1[3]= 0.0; - face->v2[3]= 0.0; - face->v3[3]= 0.0; - if(face->v4) face->v4[3]= 0.0; - } - - - /* add: faces with vertices */ - for(a=0; av4) { - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 ); - } - else { - triaweight(face, &w1, &w2, &w3); - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 ); - } - } -} - -void calcfiltrad(RNode *rn, float *cd) -{ - float area; - - cd[0]= 2.0*rn->totrad[0]; - cd[1]= 2.0*rn->totrad[1]; - cd[2]= 2.0*rn->totrad[2]; - area= 2.0; - - if(rn->ed1) { - cd[0]+= rn->ed1->totrad[0]; - cd[1]+= rn->ed1->totrad[1]; - cd[2]+= rn->ed1->totrad[2]; - area+= 1.0; - } - if(rn->ed2) { - cd[0]+= rn->ed2->totrad[0]; - cd[1]+= rn->ed2->totrad[1]; - cd[2]+= rn->ed2->totrad[2]; - area+= 1.0; - } - if(rn->ed3) { - cd[0]+= rn->ed3->totrad[0]; - cd[1]+= rn->ed3->totrad[1]; - cd[2]+= rn->ed3->totrad[2]; - area+= 1.0; - } - if(rn->ed4) { - cd[0]+= rn->ed4->totrad[0]; - cd[1]+= rn->ed4->totrad[1]; - cd[2]+= rn->ed4->totrad[2]; - area+= 1.0; - } - cd[0]/= area; - cd[1]/= area; - cd[2]/= area; - -} - -void filterNodes() -{ - /* colors from nodes in tempblock and back */ - - RNode *rn, **el; - float *coldata, *cd; - int a; - - if(RG.totelem==0) return; - /* the up-nodes need a color */ - el= RG.elem; - for(a=0; aup) { - rn->up->totrad[0]= 0.0; - rn->up->totrad[1]= 0.0; - rn->up->totrad[2]= 0.0; - if(rn->up->up) { - rn->up->up->totrad[0]= 0.0; - rn->up->up->totrad[1]= 0.0; - rn->up->up->totrad[2]= 0.0; - } - } - } - el= RG.elem; - for(a=0; aup) { - rn->up->totrad[0]+= 0.5*rn->totrad[0]; - rn->up->totrad[1]+= 0.5*rn->totrad[1]; - rn->up->totrad[2]+= 0.5*rn->totrad[2]; - if(rn->up->up) { - rn->up->up->totrad[0]+= 0.25*rn->totrad[0]; - rn->up->up->totrad[1]+= 0.25*rn->totrad[1]; - rn->up->up->totrad[2]+= 0.25*rn->totrad[2]; - } - } - } - - /* add using area */ - cd= coldata= MEM_mallocN(3*4*RG.totelem, "filterNodes"); - el= RG.elem; - for(a=0; atotrad, cd); - cd+= 3; - } - MEM_freeN(coldata); -} - -void removeEqualNodes(short limit) -{ - /* nodes with equal colors: remove */ - RNode **el, *rn, *rn1; - float thresh, f1, f2; - int a, foundone=1, ok; - int c1, c2; - - if(limit==0) return; - - thresh= 1.0/(256.0*RG.radfactor); - thresh= 3.0*pow(thresh, RG.gamma); - -// XXX waitcursor(1); - - while(foundone) { - foundone= 0; - - el= RG.elem; - for(a=RG.totelem; a>1; a--, el++) { - rn= *el; - rn1= *(el+1); - - if(rn!=rn->par->first && rn1!=rn1->par->first) { - if(rn->up && rn->up==rn1->up) { - f1= rn->totrad[0]+ rn->totrad[1]+ rn->totrad[2]; - f2= rn1->totrad[0]+ rn1->totrad[1]+ rn1->totrad[2]; - - ok= 0; - if(f1totrad[0]); - c2= calculatecolor(rn1->totrad[0]); - - if( abs(c1-c2)<=limit ) { - c1= calculatecolor(rn->totrad[1]); - c2= calculatecolor(rn1->totrad[1]); - - if( abs(c1-c2)<=limit ) { - c1= calculatecolor(rn->totrad[2]); - c2= calculatecolor(rn1->totrad[2]); - - if( abs(c1-c2)<=limit ) { - ok= 1; - } - } - } - } - - if(ok) { - rn->up->totrad[0]= 0.5f*(rn->totrad[0]+rn1->totrad[0]); - rn->up->totrad[1]= 0.5f*(rn->totrad[1]+rn1->totrad[1]); - rn->up->totrad[2]= 0.5f*(rn->totrad[2]+rn1->totrad[2]); - rn1= rn->up; - deleteNodes(rn1); - if(rn1->down1) ; - else { - foundone++; - a--; el++; - } - } - } - } - } - if(foundone) { - makeGlobalElemArray(); - } - } -// XXX waitcursor(0); -} - -unsigned int rad_find_or_add_mvert(Mesh *me, MFace *mf, RNode *orignode, float *w, float *radco, GHash *hash) -{ - MVert *mvert = BLI_ghash_lookup(hash, radco); - - if(!mvert) { - mvert = &me->mvert[me->totvert]; - VECCOPY(mvert->co, radco); - me->totvert++; - - BLI_ghash_insert(hash, radco, mvert); - } - - InterpWeightsQ3Dfl(orignode->v1, orignode->v2, orignode->v3, - orignode->v4, mvert->co, w); - - return (unsigned int)(mvert - me->mvert); -} - -void rad_addmesh(Scene *scene) -{ - Face *face = NULL; - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mf; - RNode *node; - Material *ma=0; - GHash *verthash; - unsigned int *mcol; - float cent[3], min[3], max[3], w[4][4]; - int a; - - if(RG.totface==0) - return; - -// if(RG.totmat==MAXMAT) -// XXX notice("warning: cannot assign more than 16 materials to 1 mesh"); - - /* create the mesh */ - ob= add_object(scene, OB_MESH); - - me= ob->data; - me->totvert= totalRadVert(); - me->totface= RG.totface; - me->flag= 0; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface); - - CustomData_merge(RG.mfdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface); - mesh_update_customdata_pointers(me); - - /* create materials and set vertex color flag */ - for(a=0; amode |= MA_VERTEXCOL; - } - - /* create vertices and faces in one go, adding vertices to the end of the - mvert array if they were not added already */ - me->totvert= 0; - verthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - - mcol= (unsigned int*)me->mcol; - mf= me->mface; - - for(a=0; atotface; a++, mf++, mcol+=4) { - RAD_NEXTFACE(a); - - /* the original node that this node is a subnode of */ - node= RG.mfdatanodes[face->orig]; - - /* set mverts from the radio data, and compute interpolation weights */ - mf->v1= rad_find_or_add_mvert(me, mf, node, w[0], face->v1, verthash); - mf->v2= rad_find_or_add_mvert(me, mf, node, w[1], face->v2, verthash); - mf->v3= rad_find_or_add_mvert(me, mf, node, w[2], face->v3, verthash); - if(face->v4) - mf->v4= rad_find_or_add_mvert(me, mf, node, w[3], face->v4, verthash); - - /* copy face and interpolate data */ - mf->mat_nr= face->matindex; - - CustomData_copy_data(RG.mfdata, &me->fdata, face->orig, a, 1); - CustomData_interp(RG.mfdata, &me->fdata, &face->orig, NULL, (float*)w, 1, a); - - /* load face vertex colors, with alpha added */ - mcol[0]= *((unsigned int*)face->v1+3) | 0x1000000; - mcol[1]= *((unsigned int*)face->v2+3) | 0x1000000; - mcol[2]= *((unsigned int*)face->v3+3) | 0x1000000; - if(face->v4) - mcol[3]= *((unsigned int*)face->v4+3) | 0x1000000; - - /* reorder face indices if needed to make face->v4 == 0 */ - test_index_face(mf, &me->fdata, a, face->v4? 4: 3); - } - - BLI_ghash_free(verthash, NULL, NULL); - - /* boundbox and center new */ - INIT_MINMAX(min, max); - - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - DO_MINMAX(mvert->co, min, max); - } - - cent[0]= (min[0]+max[0])/2.0f; - cent[1]= (min[1]+max[1])/2.0f; - cent[2]= (min[2]+max[2])/2.0f; - - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - VecSubf(mvert->co, mvert->co, cent); - } - - VECCOPY(ob->loc, cent); - - /* create edges */ - make_edges(me, 0); -} - -void rad_replacemesh(Scene *scene) -{ - RPatch *rp; - -// XXX deselectall(); - - rp= RG.patchbase.first; - while(rp) { - if( exist_object(rp->from)) { - if (rp->from->type == OB_MESH) { - rp->from->flag |= SELECT; - } - } - rp= rp->next; - } - - copy_objectflags(scene); -// XXX delete_obj(1); - - rad_addmesh(scene); -} - diff --git a/source/blender/radiosity/intern/source/radpreprocess.c b/source/blender/radiosity/intern/source/radpreprocess.c deleted file mode 100644 index 2b3ce1a856b..00000000000 --- a/source/blender/radiosity/intern/source/radpreprocess.c +++ /dev/null @@ -1,828 +0,0 @@ - /* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - preproces.c nov/dec 1992 - may 1999 - - - collect from meshes - - countglobaldata() - - makeGlobalElemArray() - - $Id$ - - *************************************** */ - -#include -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_material.h" -#include "BKE_mesh.h" -#include "BKE_object.h" /* during_script() */ -#include "BKE_utildefines.h" - -#include "radio.h" - -#include "BLO_sys_types.h" // for intptr_t support - -void setparelem(RNode *rn, RPatch *par); - -void splitconnected() -{ - /* Since input meshes can have faces with sharing vertices, the geometry is being tested here. - * Using normals and colors, faces are split separately. we do this by storing for each - * vertex a normal and a color - */ - RPatch *rp; - RNode *rn; - VeNoCo *vnc, *next, *vnc1; - int a; - - /* test if we need a split */ - - rp= RG.patchbase.first; - while(rp) { - rn= rp->first; - if((rp->f1 & RAD_NO_SPLIT)==0) { - for(a=0; atype; a++) { - - if(a==0) vnc= (VeNoCo *)rn->v1; - else if(a==1) vnc= (VeNoCo *)rn->v2; - else if(a==2) vnc= (VeNoCo *)rn->v3; - else vnc= (VeNoCo *)rn->v4; - - if(vnc->flag==0) { - vnc->n= (float *)rp->norm; - vnc->col= (float *)rp->ref; - vnc->flag= 1; - } - else { /* is face from this vertex allowed for gouraud? */ - vnc1= vnc; - while(vnc1) { - if(VecCompare(vnc1->n, rp->norm, 0.01f)) { - if(VecCompare(vnc1->col, rp->ref, 0.01f)) { - break; - } - } - vnc= vnc1; - vnc1= vnc1->next; - } - if(vnc1==0) { - vnc1= MEM_mallocN(sizeof(VeNoCo), "splitconn"); - vnc1->next= 0; - vnc1->v= mallocVert(); - vnc->next= vnc1; - VECCOPY(vnc1->v, vnc->v); - vnc1->n= (float *)rp->norm; - vnc1->col= (float *)rp->ref; - } - if(a==0) rn->v1= (float *)vnc1; - else if(a==1) rn->v2= (float *)vnc1; - else if(a==2) rn->v3= (float *)vnc1; - else rn->v4= (float *)vnc1; - } - } - } - rp= rp->next; - } - /* adapt vertexpointers from nodes */ - - rp= RG.patchbase.first; - while(rp) { - rn= rp->first; - rn->v1= ((VeNoCo *)(rn->v1))->v; - rn->v2= ((VeNoCo *)(rn->v2))->v; - rn->v3= ((VeNoCo *)(rn->v3))->v; - if(rp->type==4) rn->v4= ((VeNoCo *)(rn->v4))->v; - - rp= rp->next; - } - - - /* free all */ - vnc= RG.verts; - for(a=0; anext; - while(vnc1) { - next= vnc1->next; - MEM_freeN(vnc1); - vnc1= next; - } - vnc++; - } - MEM_freeN(RG.verts); - RG.verts= 0; -} - -int vergedge(const void *v1,const void *v2) -{ - int *e1, *e2; - - e1= (int *)v1; - e2= (int *)v2; - - if( e1[0] > e2[0] ) return 1; - else if( e1[0] < e2[0] ) return -1; - else if( e1[1] > e2[1] ) return 1; - else if( e1[1] < e2[1] ) return -1; - - return 0; -} - - -void addedge(float *v1, float *v2, EdSort *es) -{ - if( ((intptr_t)v1)<((intptr_t)v2) ) { - es->v1= v1; - es->v2= v2; - } - else { - es->v2= v1; - es->v1= v2; - } -} - -static void setedge(RNode *node, RNode *nb, int nr, int nrb) -{ - switch(nr) { - case 1: - node->ed1= nb; - break; - case 2: - node->ed2= nb; - break; - case 3: - node->ed3= nb; - break; - case 4: - node->ed4= nb; - break; - } - switch(nrb) { - case 1: - nb->ed1= node; - break; - case 2: - nb->ed2= node; - break; - case 3: - nb->ed3= node; - break; - case 4: - nb->ed4= node; - break; - } -} - -void setedgepointers() -{ - /* make edge-array and sort it */ - /* pairs of edges are put together: fill in pointers in nodes */ - EdSort *es, *esblock; - RPatch *rp; - RNode *rn; - int tot= 0; - - rp= RG.patchbase.first; - while(rp) { - tot+= rp->type; - rp= rp->next; - } - - if(tot==0) return; - - es=esblock= MEM_mallocN(tot*sizeof(EdSort), "setedgepointers"); - rp= RG.patchbase.first; - while(rp) { - rn= rp->first; - addedge(rn->v1, rn->v2, es); - es->nr= 1; - es->node= rn; - es++; - addedge(rn->v2, rn->v3, es); - es->nr= 2; - es->node= rn; - es++; - if(rp->type==3) { - addedge(rn->v3, rn->v1, es); - es->nr= 3; - es->node= rn; - es++; - } - else { - addedge(rn->v3, rn->v4, es); - es->nr= 3; - es->node= rn; - es++; - addedge(rn->v4, rn->v1, es); - es->nr= 4; - es->node= rn; - es++; - } - rp= rp->next; - } - - qsort(esblock,tot,sizeof(EdSort),vergedge); - - es= esblock; - while(tot>0) { - if( es->v1== (es+1)->v1 ) { - if( es->v2== (es+1)->v2 ) { - setedge(es->node, (es+1)->node, es->nr, (es+1)->nr); - tot--; - es++; - } - } - es++; - tot--; - } - - MEM_freeN(esblock); -} - -static int materialIndex(Material *ma) -{ - int i = 0; - for(i=0;i< RG.totmat; i++) - { - if (RG.matar[i] == ma) { - return i; - } - } - return -1; -} - -void rad_collect_meshes(Scene *scene, View3D *v3d) -{ - extern Material defmaterial; - Base *base; - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mface; - MTFace *tf, *tface; - Material *ma = NULL, *noma= NULL; - RPatch *rp; - RNode *rn; - VeNoCo *vnc, **nodevert; - float *vd, *v1, *v2, *v3, *v4 = NULL; - int a, b, offs, index, mfdatatot; - - if (v3d==NULL) { - printf("Error, trying to collect radiosity meshes with no 3d view\n"); - return; - } - - set_radglobal(scene); - - freeAllRad(scene); - - start_fastmalloc("Radiosity"); - - /* count the number of verts */ - RG.totvert= 0; - RG.totface= 0; - base= (scene->base.first); - while(base) { - if(((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { - if(base->object->type==OB_MESH) { - base->flag |= OB_RADIO; - me= base->object->data; - RG.totvert+= me->totvert; - } - } - base= base->next; - } - if(RG.totvert==0) { - if (!during_script()); //XXX error("No vertices"); - return; - } - vnc= RG.verts= MEM_callocN(RG.totvert*sizeof(VeNoCo), "radioverts"); - - RG.min[0]= RG.min[1]= RG.min[2]= 1.0e20f; - RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20f; - - mfdatatot= 0; - - /* min-max and material array */ - base= (scene->base.first); - while(base) { - if( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { - if(base->object->type==OB_MESH) { - me= base->object->data; - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - vd= mallocVert(); - VECCOPY(vd, mvert->co); - /* Should make MTC its own module... */ - Mat4MulVecfl(base->object->obmat, vd); - - vnc->v= vd; - for(b=0; b<3; b++) { - RG.min[b]= MIN2(RG.min[b], vd[b]); - RG.max[b]= MAX2(RG.max[b], vd[b]); - } - vnc++; - } - - if(base->object->totcol==0) { - if(RG.totmatobject->totcol; a++) { - if(RG.totmat >= MAXMAT) break; - - ma = give_current_material(base->object, a+1); - - if (materialIndex(ma)!=-1) break; - - RG.matar[RG.totmat]= ma; - RG.totmat++; - } - } - - mfdatatot += me->totface; - } - } - base= base->next; - } - - RG.cent[0]= (RG.min[0]+ RG.max[0])/2; - RG.cent[1]= (RG.min[1]+ RG.max[1])/2; - RG.cent[2]= (RG.min[2]+ RG.max[2])/2; - RG.size[0]= (RG.max[0]- RG.min[0]); - RG.size[1]= (RG.max[1]- RG.min[1]); - RG.size[2]= (RG.max[2]- RG.min[2]); - RG.maxsize= MAX3(RG.size[0],RG.size[1],RG.size[2]); - - RG.mfdata= MEM_callocN(sizeof(CustomData), "radiomfdata"); - RG.mfdatanodes= MEM_mallocN(sizeof(RNode*)*mfdatatot, "radiomfdatanodes"); - RG.mfdatatot= mfdatatot; - - /* make patches */ - - RG.totelem= 0; - RG.totpatch= 0; - RG.totlamp= 0; - offs= 0; - - base= (scene->base.first); - while(base) { - if( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { - if(base->object->type==OB_MESH) { - ob= base->object; - me= ob->data; - mface= me->mface; - tface= me->mtface; - - index= -1; - - CustomData_merge(&me->fdata, RG.mfdata, CD_MASK_DERIVEDMESH, - CD_DEFAULT, mfdatatot); - - for(a=0; atotface; a++, mface++) { - tf= tface? tface+a: NULL; - - if (tf && (tf->mode & TF_INVISIBLE)) - continue; - - rp= callocPatch(); - BLI_addtail(&(RG.patchbase), rp); - rp->from= ob; - - if(mface->v4) rp->type= 4; - else rp->type= 3; - - rp->first= rn= callocNode(); - - if(mface->flag & ME_SMOOTH) rp->f1= RAD_NO_SPLIT; - - /* temporal: we store the venoco in the node */ - rn->v1= (float *)(RG.verts+mface->v1+offs); - v1= (RG.verts+mface->v1+offs)->v; - rn->v2= (float *)(RG.verts+mface->v2+offs); - v2= (RG.verts+mface->v2+offs)->v; - rn->v3= (float *)(RG.verts+mface->v3+offs); - v3= (RG.verts+mface->v3+offs)->v; - - if(mface->v4) { - rn->v4= (float *)(RG.verts+mface->v4+offs); - v4= (RG.verts+mface->v4+offs)->v; - } - rn->par= rp; - rn->f= RAD_PATCH; /* this node is a Patch */ - rn->type= rp->type; - - if(rn->type==4) { - rp->area= AreaQ3Dfl(v1, v2, v3, v4); - CalcNormFloat4(v1, v2, v3, v4, rp->norm); - } - else { - rp->area= AreaT3Dfl(v1, v2, v3); - CalcNormFloat(v1, v2, v3, rp->norm); - } - - rn->area= rp->area; - - /* color and emit */ - if(mface->mat_nr != index) { - index= mface->mat_nr; - ma= give_current_material(ob, index+1); - if(ma==0) ma= &defmaterial; - } - rp->ref[0]= ma->r; - rp->ref[1]= ma->g; - rp->ref[2]= ma->b; - - if(ma->emit) RG.totlamp++; - - rp->emit[0]= rp->emit[1]= rp->emit[2]= ma->emit; - rp->emit[0]*= rp->ref[0]; - rp->emit[1]*= rp->ref[1]; - rp->emit[2]*= rp->ref[2]; - -// uncommented, this is not satisfying, but i leave it in code for now (ton) -// if(ma->translucency!=0.0) rn->f |= RAD_TWOSIDED; - - nodevert= (VeNoCo **)&(rn->v1); - for(b=0; btype; b++) { - rp->cent[0]+= (*nodevert)->v[0]; - rp->cent[1]+= (*nodevert)->v[1]; - rp->cent[2]+= (*nodevert)->v[2]; - nodevert++; - } - rp->cent[0]/= (float)rp->type; - rp->cent[1]/= (float)rp->type; - rp->cent[2]/= (float)rp->type; - - /* for reconstruction materials */ - rp->matindex= materialIndex(ma); - if(rp->matindex==-1) rp->matindex= 1; - - /* these RNode's are stored now for later use in rad_addmesh - they should not get deleted before that */ - rn->orig= RG.totelem; - RG.mfdatanodes[RG.totelem]= rn; - - CustomData_copy_data(&me->fdata, RG.mfdata, a, RG.totelem, 1); - - RG.totelem++; - RG.totpatch++; - } - - offs+= me->totvert; - } - } - base= base->next; - } - - splitconnected(); - setedgepointers(); - - makeGlobalElemArray(); - pseudoAmb(); - rad_setlimits(scene); -} - -void setparelem(RNode *rn, RPatch *par) -{ - - if(rn->down1) { - setparelem(rn->down1, par); - setparelem(rn->down2, par); - } - else { - rn->par= par; - } -} - -void countelem(RNode *rn) -{ - - if(rn->down1) { - countelem(rn->down1); - countelem(rn->down2); - } - else RG.totelem++; -} - -void countglobaldata() -{ - /* counts elements and patches*/ - RPatch *rp; - - RG.totelem= RG.totpatch= 0; - - rp= RG.patchbase.first; - while(rp) { - RG.totpatch++; - countelem(rp->first); - rp= rp->next; - } -} - -void addelem(RNode ***el, RNode *rn, RPatch *rp) -{ - if(rn->down1) { - addelem(el, rn->down1, rp); - addelem(el, rn->down2, rp); - } - else { - rn->par= rp; - **el= rn; - (*el)++; - } -} - -void makeGlobalElemArray() -{ - /* always called when # of elements change */ - RPatch *rp; - RNode **el; - - countglobaldata(); - - if(RG.elem) MEM_freeN(RG.elem); - if(RG.totelem) { - el= RG.elem= MEM_mallocN(sizeof(void *)*RG.totelem, "makeGlobalElemArray"); - } - else { - RG.elem= 0; - return; - } - - /* recursive adding elements */ - rp= RG.patchbase.first; - while(rp) { - addelem(&el, rp->first, rp); - rp= rp->next; - } - - /* formfactor array */ - if(RG.formfactors) MEM_freeN(RG.formfactors); - if(RG.totelem) - RG.formfactors= MEM_mallocN(sizeof(float)*RG.totelem, "formfactors"); - else - RG.formfactors= 0; -} - -void splitpatch(RPatch *old) /* in case of overflow during shoot */ -{ - RNode *rn; - float **fpp; - RPatch *rp; - int a; - - rn= old->first; - if(rn->down1==0) return; - rn= rn->down1; - - old->unshot[0]/=2.0; - old->unshot[1]/=2.0; - old->unshot[2]/=2.0; - setnodeflags(old->first, 2, 0); - - rp= mallocPatch(); - *rp= *old; - BLI_addhead(&RG.patchbase, rp); - rp->first= rn; - rp->area= rn->area; - rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0; - fpp= &(rn->v1); - for(a=0; atype; a++) { - rp->cent[0]+= (*fpp)[0]; - rp->cent[1]+= (*fpp)[1]; - rp->cent[2]+= (*fpp)[2]; - fpp++; - } - rp->cent[0]/=(float)rp->type; - rp->cent[1]/=(float)rp->type; - rp->cent[2]/=(float)rp->type; - - setparelem(rn, rp); - - rn= old->first->down2; - - rp= mallocPatch(); - *rp= *old; - BLI_addhead(&RG.patchbase, rp); - rp->first= rn; - rp->area= rn->area; - rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0; - fpp= &(rn->v1); - for(a=0; atype; a++) { - rp->cent[0]+= (*fpp)[0]; - rp->cent[1]+= (*fpp)[1]; - rp->cent[2]+= (*fpp)[2]; - fpp++; - } - rp->cent[0]/=(float)rp->type; - rp->cent[1]/=(float)rp->type; - rp->cent[2]/=(float)rp->type; - - setparelem(rn, rp); - - BLI_remlink(&RG.patchbase, old); - freePatch(old); -} - - -void addpatch(RPatch *old, RNode *rn) -{ - float **fpp; - RPatch *rp; - int a; - - if(rn->down1) { - addpatch(old, rn->down1); - addpatch(old, rn->down2); - } - else { - rp= mallocPatch(); - *rp= *old; - BLI_addhead(&RG.patchbase, rp); - rp->first= rn; - - rp->area= rn->area; - rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0; - fpp= &(rn->v1); - for(a=0; atype; a++) { - rp->cent[0]+= (*fpp)[0]; - rp->cent[1]+= (*fpp)[1]; - rp->cent[2]+= (*fpp)[2]; - fpp++; - } - rp->cent[0]/=(float)rp->type; - rp->cent[1]/=(float)rp->type; - rp->cent[2]/=(float)rp->type; - - rn->par= rp; - } -} - -void converttopatches() -{ - /* chacks patches list, if node subdivided: new patch */ - RPatch *rp, *next; - - rp= RG.patchbase.first; - while(rp) { - next= rp->next; - if(rp->first->down1) { - addpatch(rp, rp->first); - BLI_remlink(&RG.patchbase, rp); - freePatch(rp); - } - rp= next; - } - -} - -void subdiv_elements() -{ - RNode **el, *rn; - int a, toobig= 1; - - rad_init_energy(); - - /* first maxsize elements */ - - while(toobig) { - toobig= 0; - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - if( rn->totrad[0]==0.0 && rn->totrad[1]==0.0 && rn->totrad[2]==0.0) { - if(rn->area>RG.elemmin) { - subdivideNode(rn, 0); - if(rn->down1 ) { - toobig= 1; - if(rn->down1->area>RG.elemmin) - subdivideNode( rn->down1, 0); - if(rn->down2->area>RG.elemmin) - subdivideNode( rn->down2, 0); - } - } - } - } - if(toobig) makeGlobalElemArray(); - } - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - if( rn->totrad[0]==0.0 && rn->totrad[1]==0.0 && rn->totrad[2]==0.0) { - subdivideNode(rn, 0); - if( rn->down1 ) { - subdivideNode( rn->down1, 0); - subdivideNode( rn->down2, 0); - } - } - } - makeGlobalElemArray(); -} - -void subdividelamps() -{ - RPatch *rp, *next; - - rp= RG.patchbase.first; - while(rp) { - next= rp->next; - if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) { - subdivideNode( rp->first, 0); - if(rp->first->down1) { - subdivideNode(rp->first->down1, 0); - subdivideNode(rp->first->down2, 0); - } - - addpatch(rp, rp->first); - BLI_remlink(&RG.patchbase, rp); - freePatch(rp); - } - rp= next; - } - -} - -void maxsizePatches() -{ - RPatch *rp; - int toobig= 1; - - while(toobig) { - toobig= 0; - rp= RG.patchbase.first; - while(rp) { - if(rp->area>RG.patchmax) { - subdivideNode( rp->first, 0); - if(rp->first->down1) toobig= 1; - } - rp= rp->next; - } - - if(toobig) converttopatches(); - } - - /* count lamps */ - rp= RG.patchbase.first; - RG.totlamp= 0; - while(rp) { - if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) { - RG.totlamp++; - } - rp= rp->next; - } - makeGlobalElemArray(); -} - - - diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c deleted file mode 100644 index d33bbc90ee3..00000000000 --- a/source/blender/radiosity/intern/source/radrender.c +++ /dev/null @@ -1,530 +0,0 @@ -/* *************************************** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* radrender.c, aug 2003 - * - * Most of the code here is copied from radiosity code, to optimize for renderfaces. - * Shared function calls mostly reside in radfactors.c - * No adaptive subdivision takes place - * - * - do_radio_render(); main call, extern - * - initradfaces(); add radface structs in render faces, init radio globals - * - - * - initradiosity(); LUTs - * - inithemiwindows(); - * - progressiverad(); main itteration loop - * - hemi zbuffers - * - calc rad factors - * - * - closehemiwindows(); - * - freeAllRad(); - * - make vertex colors - * - * - during render, materials use totrad as ambient replacement - * - free radfaces - */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_rand.h" - -#include "BKE_utildefines.h" -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" - -/* the radiosity module uses internal includes from render! */ -#include "renderpipeline.h" -#include "render_types.h" -#include "renderdatabase.h" - - -/* only needed now for a print, if its useful move to RG */ -static float maxenergy; - -/* find the face with maximum energy to become shooter */ -/* nb: _rr means rad-render version of existing radio call */ -static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p) -{ - RadFace *rf, *shootrf, **radface; - ObjectRen *obr; - VlakRen *vlr=NULL, *shoot; - float energy; - int a; - - shoot= NULL; - shootrf= NULL; - maxenergy= 0.0; - - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - rf->flag &= ~RAD_SHOOT; - - energy= rf->unshot[0]*rf->area; - energy+= rf->unshot[1]*rf->area; - energy+= rf->unshot[2]*rf->area; - - if(energy>maxenergy) { - shoot= vlr; - shootrf= rf; - maxenergy= energy; - } - } - } - } - - if(shootrf) { - maxenergy/= RG.totenergy; - if(maxenergyflag |= RAD_SHOOT; - } - - *shoot_p= shoot; - *shootrf_p= shootrf; -} - -static void backface_test_rr(Render *re, VlakRen *shoot, RadFace *shootrf) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float tvec[3]; - int a; - - /* backface testing */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - VecSubf(tvec, shootrf->cent, rf->cent); - - if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0) - rf->flag |= RAD_BACKFACE; - } - } - } -} - -static void clear_backface_test_rr(Render *re) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - int a; - - /* backface flag clear */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - rf->flag &= ~RAD_BACKFACE; - } - } - } -} - -extern RadView hemitop, hemiside; // radfactors.c - -/* hemi-zbuffering, delivers formfactors array */ -static void makeformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float len, vec[3], up[3], side[3], tar[5][3], *fp; - int a; - - memset(RG.formfactors, 0, sizeof(float)*RG.totelem); - - /* set up hemiview */ - /* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */ - - VecSubf(vec, shoot->v1->co, shootrf->cent); - Crossf(up, shootrf->norm, vec); - len= Normalize(up); - - VECCOPY(hemitop.up, up); - VECCOPY(hemiside.up, shootrf->norm); - - Crossf(side, shootrf->norm, up); - - /* five targets */ - VecAddf(tar[0], shootrf->cent, shootrf->norm); - VecAddf(tar[1], shootrf->cent, up); - VecSubf(tar[2], shootrf->cent, up); - VecAddf(tar[3], shootrf->cent, side); - VecSubf(tar[4], shootrf->cent, side); - - /* camera */ - VECCOPY(hemiside.cam, shootrf->cent); - VECCOPY(hemitop.cam, shootrf->cent); - - /* do it! */ - VECCOPY(hemitop.tar, tar[0]); - hemizbuf(&hemitop); - - for(a=1; a<5; a++) { - VECCOPY(hemiside.tar, tar[a]); - hemizbuf(&hemiside); - } - - /* convert factors to real radiosity */ - fp= RG.formfactors; - - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - if(*fp!=0.0 && rf->area!=0.0) { - *fp *= shootrf->area/rf->area; - if(*fp>1.0) *fp= 1.0001; - } - fp++; - } - } - } -} - -/* based at RG.formfactors array, distribute shoot energy over other faces */ -static void applyformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float *fp, *ref, unr, ung, unb, r, g, b; - int a; - - unr= shootrf->unshot[0]; - ung= shootrf->unshot[1]; - unb= shootrf->unshot[2]; - - fp= RG.formfactors; - - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - if(*fp!= 0.0) { - - ref= &(vlr->mat->r); - - r= (*fp)*unr*ref[0]; - g= (*fp)*ung*ref[1]; - b= (*fp)*unb*ref[2]; - - // if(rf->flag & RAD_BACKFACE) { - - rf->totrad[0]+= r; - rf->totrad[1]+= g; - rf->totrad[2]+= b; - - rf->unshot[0]+= r; - rf->unshot[1]+= g; - rf->unshot[2]+= b; - } - fp++; - } - } - } - /* shoot energy has been shot */ - shootrf->unshot[0]= shootrf->unshot[1]= shootrf->unshot[2]= 0.0; -} - - -/* main loop for itterations */ -static void progressiverad_rr(Render *re) -{ - VlakRen *shoot; - RadFace *shootrf; - float unshot[3]; - int it= 0; - - findshoot_rr(re, &shoot, &shootrf); - while( shoot ) { - - /* backfaces receive no energy, but are zbuffered... */ - backface_test_rr(re, shoot, shootrf); - - /* ...unless it's two sided */ - if(shootrf->flag & RAD_TWOSIDED) { - VECCOPY(unshot, shootrf->unshot); - VecNegf(shootrf->norm); - makeformfactors_rr(re, shoot, shootrf); - applyformfactors_rr(re, shoot, shootrf); - VecNegf(shootrf->norm); - VECCOPY(shootrf->unshot, unshot); - } - - /* hemi-zbuffers */ - makeformfactors_rr(re, shoot, shootrf); - /* based at RG.formfactors array, distribute shoot energy over other faces */ - applyformfactors_rr(re, shoot, shootrf); - - it++; - re->timecursor(re->tch, it); - - clear_backface_test_rr(re); - - if(re->test_break(re->tbh)) break; - if(RG.maxiter && RG.maxiter<=it) break; - - findshoot_rr(re, &shoot, &shootrf); - } - printf(" Unshot energy:%f\n", 1000.0*maxenergy); - - re->timecursor(re->tch, re->scene->r.cfra); -} - -static RadFace *radfaces=NULL; - -static void initradfaces(Render *re) -{ - ObjectRen *obr; - VlakRen *vlr= NULL; - RadFace *rf, **radface; - int a, b; - - /* globals */ - RG.totenergy= 0.0; - RG.totpatch= 0; // we count initial emittors here - RG.totelem= 0; // total # faces are put here (so we can use radfactors.c calls) - /* size is needed for hemicube clipping */ - RG.min[0]= RG.min[1]= RG.min[2]= 1.0e20; - RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20; - - /* count first for fast malloc */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if(vlr->mat->mode & MA_RADIO) { - if(vlr->mat->emit > 0.0) { - RG.totpatch++; - } - RG.totelem++; - } - } - } - -printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch); - if(RG.totelem==0 || RG.totpatch==0) return; - - /* make/init radfaces */ - rf=radfaces= MEM_callocN(RG.totelem*sizeof(RadFace), "radfaces"); - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if(vlr->mat->mode & MA_RADIO) { - - /* during render, vlr->n gets flipped/corrected, we cannot have that */ - if (obr->ob->transflag & OB_NEG_SCALE){ - /* The object has negative scale that will cause the normals to flip. - To counter this unwanted normal flip, swap vertex 2 and 4 for a quad - or vertex 2 and 3 (see flip_face) for a triangle in the call to CalcNormFloat4 - in order to flip the normals back to the way they were in the original mesh. */ - if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v4->co, vlr->v3->co, vlr->v2->co, rf->norm); - else CalcNormFloat(vlr->v1->co, vlr->v3->co, vlr->v2->co, rf->norm); - }else{ - if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm); - else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm); - } - - rf->totrad[0]= vlr->mat->emit*vlr->mat->r; - rf->totrad[1]= vlr->mat->emit*vlr->mat->g; - rf->totrad[2]= vlr->mat->emit*vlr->mat->b; - VECCOPY(rf->unshot, rf->totrad); - - if(vlr->v4) { - rf->area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); - CalcCent4f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); - } - else { - rf->area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co); - CalcCent3f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co); - } - - RG.totenergy+= rf->unshot[0]*rf->area; - RG.totenergy+= rf->unshot[1]*rf->area; - RG.totenergy+= rf->unshot[2]*rf->area; - - for(b=0; b<3; b++) { - RG.min[b]= MIN2(RG.min[b], rf->cent[b]); - RG.max[b]= MAX2(RG.max[b], rf->cent[b]); - } - - // uncommented; this isnt satisfying, but i leave it in the code for now (ton) - // if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED; - - radface=RE_vlakren_get_radface(obr, vlr, 1); - *radface= rf++; - } - } - } - RG.size[0]= (RG.max[0]- RG.min[0]); - RG.size[1]= (RG.max[1]- RG.min[1]); - RG.size[2]= (RG.max[2]- RG.min[2]); - RG.maxsize= MAX3(RG.size[0],RG.size[1],RG.size[2]); - - /* formfactor array */ - if(RG.formfactors) MEM_freeN(RG.formfactors); - if(RG.totelem) - RG.formfactors= MEM_mallocN(sizeof(float)*RG.totelem, "formfactors"); - else - RG.formfactors= NULL; - -} - -static void vecaddfac(float *vec, float *v1, float *v2, float fac) -{ - vec[0]= v1[0] + fac*v2[0]; - vec[1]= v1[1] + fac*v2[1]; - vec[2]= v1[2] + fac*v2[2]; - -} - -/* unused now, doesnt work..., find it in cvs of nov 2005 or older */ -/* static void filter_rad_values(void) */ - - -static void make_vertex_rad_values(Render *re) -{ - ObjectRen *obr; - VertRen *v1=NULL; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float *col; - int a; - - RG.igamma= 1.0/RG.gamma; - RG.radfactor= RG.radfac*pow(64*64, RG.igamma)/128.0; /* compatible with radio-tool */ - - /* accumulate vertexcolors */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - - /* apply correction */ - rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma); - rf->totrad[1]= RG.radfactor*pow( rf->totrad[1], RG.igamma); - rf->totrad[2]= RG.radfactor*pow( rf->totrad[2], RG.igamma); - - /* correct rf->rad values for color */ - if(vlr->mat->r > 0.0) rf->totrad[0]/= vlr->mat->r; - if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g; - if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b; - - col= RE_vertren_get_rad(obr, vlr->v1, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - - col= RE_vertren_get_rad(obr, vlr->v2, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - - col= RE_vertren_get_rad(obr, vlr->v3, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - - if(vlr->v4) { - col= RE_vertren_get_rad(obr, vlr->v4, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - } - } - } - - /* make vertex colors */ - for(a=0; atotvert; a++) { - if((a & 255)==0) v1= RE_findOrAddVert(obr, a); else v1++; - - col= RE_vertren_get_rad(obr, v1, 0); - if(col && col[3]>0.0) { - col[0]/= col[3]; - col[1]/= col[3]; - col[2]/= col[3]; - } - } - } -} - -/* main call, extern */ -void do_radio_render(Render *re) -{ - if(re->scene->radio==NULL) add_radio(re->scene); - freeAllRad(re->scene); /* just in case radio-tool is still used */ - - set_radglobal(re->scene); /* init the RG struct */ - RG.re= re; /* only used by hemizbuf(), prevents polluting radio code all over */ - - initradfaces(re); /* add radface structs to render faces */ - if(RG.totenergy>0.0) { - - initradiosity(); /* LUT's */ - inithemiwindows(); /* views, need RG.maxsize for clipping */ - - progressiverad_rr(re); /* main radio loop */ - - make_vertex_rad_values(re); /* convert face energy to vertex ones */ - - } - - freeAllRad(re->scene); /* luts, hemis, sets vars at zero */ -} - -/* free call, after rendering, extern */ -void end_radio_render(void) -{ - if(radfaces) MEM_freeN(radfaces); - radfaces= NULL; -} - diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 20eea0c98bd..15b59f2c8cc 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -47,7 +47,8 @@ struct Render; struct MTex; struct ImBuf; -void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); +// RADIO REMOVED, Maybe this will be useful later +//void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); /* particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */ int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 98e5819c0d3..a00cd2211fc 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -104,7 +104,6 @@ #include "rendercore.h" #include "renderdatabase.h" #include "renderpipeline.h" -#include "radio.h" #include "shadbuf.h" #include "shading.h" #include "strand.h" @@ -1886,6 +1885,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(psys_get_particle_state(re->scene,ob,psys,a,&state,0)==0) continue; + if(psys->parent) + Mat4MulVecfl(psys->parent->obmat, state.co); + VECCOPY(loc,state.co); if(part->ren_as!=PART_DRAW_BB) MTC_Mat4MulVecfl(re->viewmat,loc); @@ -4308,8 +4310,9 @@ void RE_Database_Free(Render *re) } free_mesh_orco_hash(re); - +#if 0 /* radio can be redone better */ end_radio_render(); +#endif end_render_materials(); end_render_textures(); @@ -4736,10 +4739,11 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) /* yafray: 'direct' radiosity, environment maps and raytree init not needed for yafray render */ /* although radio mode could be useful at some point, later */ if (re->r.renderer==R_INTERN) { +#if 0 /* RADIO was removed */ /* RADIO (uses no R anymore) */ if(!re->test_break(re->tbh)) if(re->r.mode & R_RADIO) do_radio_render(re); - +#endif /* raytree */ if(!re->test_break(re->tbh)) { if(re->r.mode & R_RAYTRACE) { diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 07560edb76b..ccc793e4235 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -46,6 +46,7 @@ #include "BKE_object.h" #include "BKE_scene.h" #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ +#include "BKE_pointcache.h" #include "MEM_guardedalloc.h" @@ -61,7 +62,6 @@ #include "intern/openexr/openexr_multi.h" #include "RE_pipeline.h" -#include "radio.h" /* internal */ #include "render_types.h" @@ -2413,6 +2413,21 @@ static int is_rendering_allowed(Render *re) return 1; } +static void update_physics_cache(Render *re, Scene *scene) +{ + PTCacheBaker baker; + + baker.scene = scene; + baker.pid = NULL; + baker.bake = 0; + baker.render = 1; + baker.quick_step = 1; + baker.break_test = re->test_break; + baker.break_data = re->tbh; + baker.progressbar = NULL; + + BKE_ptcache_make_cache(&baker); +} /* evaluating scene options for general Blender render */ static int render_initialize_from_scene(Render *re, Scene *scene, int anim) { @@ -2450,6 +2465,9 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim) /* check all scenes involved */ tag_scenes_for_render(re); + + /* make sure dynamics are up to date */ + update_physics_cache(re, scene); if(scene->r.scemode & R_SINGLE_LAYER) push_render_result(re); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index b68cecce7bd..21c3977fc0b 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -49,14 +49,12 @@ #include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_meshdata_types.h" +#include "DNA_material_types.h" #include "BKE_global.h" #include "BKE_material.h" #include "BKE_utildefines.h" -#include "radio_types.h" -#include "radio.h" /* needs RG, some root data for radiosity */ - #include "RE_render_ext.h" /* local includes */ @@ -2301,110 +2299,6 @@ static int hashlist_projectvert(float *v1, float winmat[][4], float *hoco) return buck->clip; } -/* used for booth radio 'tool' as during render */ -void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Render *re) -{ - ZSpan zspan; - float hoco[4][4], winmat[4][4]; - int a, zvlnr; - int c1, c2, c3, c4= 0; - - if(rg_totelem==0) return; - - hashlist_projectvert(NULL, winmat, NULL); - - /* needed for projectvert */ - MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat); - - /* 1.0f for clipping in clippyra()... bad stuff actually */ - zbuf_alloc_span(&zspan, vw->rectx, vw->recty, 1.0f); - zspan.zmulx= ((float)vw->rectx)/2.0; - zspan.zmuly= ((float)vw->recty)/2.0; - zspan.zofsx= -0.5f; - zspan.zofsy= -0.5f; - - /* the buffers */ - zspan.rectz= (int *)vw->rectz; - zspan.rectp= (int *)vw->rect; - zspan.recto= MEM_callocN(sizeof(int)*vw->rectx*vw->recty, "radiorecto"); - fillrect(zspan.rectz, vw->rectx, vw->recty, 0x7FFFFFFF); - fillrect(zspan.rectp, vw->rectx, vw->recty, 0xFFFFFF); - - /* filling methods */ - zspan.zbuffunc= zbuffillGL4; - - if(rg_elem) { /* radio tool */ - RNode **re, *rn; - - re= rg_elem; - re+= (rg_totelem-1); - for(a= rg_totelem-1; a>=0; a--, re--) { - rn= *re; - if( (rn->f & RAD_SHOOT)==0 ) { /* no shootelement */ - - if( rn->f & RAD_TWOSIDED) zvlnr= a; - else if( rn->f & RAD_BACKFACE) zvlnr= 0xFFFFFF; - else zvlnr= a; - - c1= hashlist_projectvert(rn->v1, winmat, hoco[0]); - c2= hashlist_projectvert(rn->v2, winmat, hoco[1]); - c3= hashlist_projectvert(rn->v3, winmat, hoco[2]); - - if(rn->v4) { - c4= hashlist_projectvert(rn->v4, winmat, hoco[3]); - } - - if(rn->v4) - zbufclip4(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - else - zbufclip(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); - } - } - } - else { /* radio render */ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace **radface, *rf; - int totface=0; - - /* note: radio render doesn't support duplis */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - hashlist_projectvert(NULL, NULL, NULL); /* clear hashlist */ - - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */ - - if( rf->flag & RAD_TWOSIDED) zvlnr= totface; - else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */ - else zvlnr= totface; - - c1= hashlist_projectvert(vlr->v1->co, winmat, hoco[0]); - c2= hashlist_projectvert(vlr->v2->co, winmat, hoco[1]); - c3= hashlist_projectvert(vlr->v3->co, winmat, hoco[2]); - - if(vlr->v4) { - c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]); - } - - if(vlr->v4) - zbufclip4(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - else - zbufclip(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); - } - totface++; - } - } - } - } - - MEM_freeN(zspan.recto); - zbuf_free_span(&zspan); -} - void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 7acb2921bec..ffeb342df77 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -79,7 +79,7 @@ void WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid, int spaceid, int regionid); -char *WM_key_event_string(short type); +const char *WM_key_event_string(short type); char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); /* handlers */ @@ -129,6 +129,8 @@ int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op); /* operator api */ void WM_operator_free (struct wmOperator *op); +void WM_operator_stack_clear(struct bContext *C); + wmOperatorType *WM_operatortype_find(const char *idname); wmOperatorType *WM_operatortype_first(void); void WM_operatortype_append (void (*opfunc)(wmOperatorType*)); @@ -212,8 +214,8 @@ void WM_jobs_stop(struct wmWindowManager *wm, void *owner); void WM_jobs_stop_all(struct wmWindowManager *wm); /* clipboard */ -char *WM_clipboard_text_get(int selection); -void WM_clipboard_text_set(char *buf, int selection); +char *WM_clipboard_text_get(int selection); +void WM_clipboard_text_set(char *buf, int selection); #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 739cfbcc1ac..e3a7a906fef 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -58,37 +58,6 @@ enum { WM_OP_EXEC_SCREEN }; -/* ************** wmEvent ************************ */ - -/* each event should have full modifier state */ -/* event comes from eventmanager and from keymap */ -typedef struct wmEvent { - struct wmEvent *next, *prev; - - short type; /* event code itself (short, is also in keymap) */ - short val; /* press, release, scrollvalue */ - short x, y; /* mouse pointer position, screen coord */ - short mval[2]; /* region mouse position, name convention pre 2.5 :) */ - short prevx, prevy; /* previous mouse pointer position */ - short unicode; /* future, ghost? */ - char ascii; /* from ghost */ - char pad; - - /* modifier states */ - short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ - short keymodifier; /* rawkey modifier */ - - /* keymap item, set by handler (weak?) */ - const char *keymap_idname; - - /* custom data */ - short custom; /* custom data type, stylus, 6dof, see wm_event_types.h */ - void *customdata; /* ascii, unicode, mouse coords, angles, vectors, dragdrop info */ - short customdatafree; - -} wmEvent; - - /* ************** wmKeyMap ************************ */ /* modifier */ @@ -159,6 +128,7 @@ typedef struct wmNotifier { #define NC_BRUSH (11<<24) #define NC_TEXT (12<<24) #define NC_WORLD (13<<24) +#define NC_FILE (14<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 @@ -213,6 +183,10 @@ typedef struct wmNotifier { /* NC_TEXT Text */ #define ND_CURSOR (50<<16) #define ND_DISPLAY (51<<16) + + /* NC_FILE Filebrowser */ +#define ND_PARAMS (60<<16) +#define ND_FILELIST (61<<16) /* subtype, 256 entries too */ #define NOTE_SUBTYPE 0x0000FF00 diff --git a/source/blender/windowmanager/intern/Makefile b/source/blender/windowmanager/intern/Makefile index 80ae58f9398..8f0f47c52d0 100644 --- a/source/blender/windowmanager/intern/Makefile +++ b/source/blender/windowmanager/intern/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 11904 2007-08-31 16:16:33Z sirdude $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 37fdc9fa2c5..7dec14664ae 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -95,6 +95,18 @@ void wm_operator_register(wmWindowManager *wm, wmOperator *op) } +void WM_operator_stack_clear(bContext *C) +{ + wmWindowManager *wm= CTX_wm_manager(C); + wmOperator *op; + + while((op= wm->operators.first)) { + BLI_remlink(&wm->operators, op); + WM_operator_free(op); + } + +} + /* ****************************************** */ void wm_check(bContext *C) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ea6a65859e5..e520067b9e5 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -49,6 +49,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_utildefines.h" +#include "BKE_pointcache.h" #include "ED_fileselect.h" #include "ED_screen.h" @@ -234,6 +235,8 @@ void wm_event_do_notifiers(bContext *C) for(base= scene->base.first; base; base= base->next) { object_handle_update(scene, base->object); } + + BKE_ptcache_quick_cache_all(scene); } } CTX_wm_window_set(C, NULL); @@ -730,17 +733,20 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve ScrArea *area= CTX_wm_area(C); ARegion *region= CTX_wm_region(C); ARegion *menu= CTX_wm_menu(C); - int retval; + int retval, always_pass; /* we set context to where ui handler came from */ if(handler->ui_area) CTX_wm_area_set(C, handler->ui_area); if(handler->ui_region) CTX_wm_region_set(C, handler->ui_region); if(handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu); + /* in advance to avoid access to freed event on window close */ + always_pass= wm_event_always_pass(event); + retval= handler->ui_handle(C, event, handler->ui_userdata); /* putting back screen context */ - if((retval != WM_UI_HANDLER_BREAK) || wm_event_always_pass(event)) { + if((retval != WM_UI_HANDLER_BREAK) || always_pass) { CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); CTX_wm_menu_set(C, menu); @@ -773,7 +779,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa case EVT_FILESELECT_OPEN: case EVT_FILESELECT_FULL_OPEN: { - short flag =0; short display =FILE_SHORTDISPLAY; short filter =0; short sort =FILE_SORTALPHA; + short flag =0; short display =FILE_SHORTDISPLAY; short filter =0; short sort =FILE_SORT_ALPHA; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); if(event->val==EVT_FILESELECT_OPEN) @@ -869,6 +875,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { wmEventHandler *handler, *nexthandler; int action= WM_HANDLER_CONTINUE; + int always_pass; if(handlers==NULL) return action; @@ -878,6 +885,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) /* optional boundbox */ if(handler_boundbox_test(handler, event)) { + /* in advance to avoid access to freed event on window close */ + always_pass= wm_event_always_pass(event); /* modal+blocking handler */ if(handler->flag & WM_HANDLER_BLOCKING) @@ -909,7 +918,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= wm_handler_operator_call(C, handlers, handler, event, NULL); } - if(!wm_event_always_pass(event) && action==WM_HANDLER_BREAK) + if(!always_pass && action==WM_HANDLER_BREAK) break; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index d13d8ec6ccc..29ec58befd9 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -294,8 +294,6 @@ int WM_read_homefile(bContext *C, wmOperator *op) G.relbase_valid = 0; if (!from_memory) { BLI_make_file_string(G.sce, tstr, home, ".B25.blend"); - if(!BLI_exists(tstr)) - BLI_make_file_string(G.sce, tstr, home, ".B.blend"); } strcpy(scestr, G.sce); /* temporary store */ @@ -577,7 +575,7 @@ void WM_write_file(bContext *C, char *target, ReportList *reports) // } if (G.fileflags & G_AUTOPACK) { - packAll(); + packAll(G.main, reports); } ED_object_exit_editmode(C, 0); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index adbc43e439d..0bc35ffa9b2 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -58,8 +58,6 @@ #include "RE_pipeline.h" /* RE_ free stuff */ -#include "radio.h" - #ifndef DISABLE_PYTHON #include "BPY_extern.h" #endif @@ -196,9 +194,6 @@ void WM_exit(bContext *C) // BIF_freeRetarget(); BIF_freeTemplates(C); BIF_freeSketch(C); - - /* Context should still working here. but radio tool needs cleaning... */ - freeAllRad(CTX_data_scene(C)); free_ttfont(); /* bke_font.h */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 7528321c7c5..b914e63788d 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -44,6 +44,7 @@ #include "RNA_access.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -153,315 +154,11 @@ ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, int spacei /* ***************** get string from key events **************** */ -char *WM_key_event_string(short type) +const char *WM_key_event_string(short type) { - /* not returned: CAPSLOCKKEY, UNKNOWNKEY, COMMANDKEY, GRLESSKEY */ - - switch(type) { - case AKEY: - return "A"; - break; - case BKEY: - return "B"; - break; - case CKEY: - return "C"; - break; - case DKEY: - return "D"; - break; - case EKEY: - return "E"; - break; - case FKEY: - return "F"; - break; - case GKEY: - return "G"; - break; - case HKEY: - return "H"; - break; - case IKEY: - return "I"; - break; - case JKEY: - return "J"; - break; - case KKEY: - return "K"; - break; - case LKEY: - return "L"; - break; - case MKEY: - return "M"; - break; - case NKEY: - return "N"; - break; - case OKEY: - return "O"; - break; - case PKEY: - return "P"; - break; - case QKEY: - return "Q"; - break; - case RKEY: - return "R"; - break; - case SKEY: - return "S"; - break; - case TKEY: - return "T"; - break; - case UKEY: - return "U"; - break; - case VKEY: - return "V"; - break; - case WKEY: - return "W"; - break; - case XKEY: - return "X"; - break; - case YKEY: - return "Y"; - break; - case ZKEY: - return "Z"; - break; - - case ZEROKEY: - return "Zero"; - break; - case ONEKEY: - return "One"; - break; - case TWOKEY: - return "Two"; - break; - case THREEKEY: - return "Three"; - break; - case FOURKEY: - return "Four"; - break; - case FIVEKEY: - return "Five"; - break; - case SIXKEY: - return "Six"; - break; - case SEVENKEY: - return "Seven"; - break; - case EIGHTKEY: - return "Eight"; - break; - case NINEKEY: - return "Nine"; - break; - - case LEFTCTRLKEY: - return "Leftctrl"; - break; - case LEFTALTKEY: - return "Leftalt"; - break; - case RIGHTALTKEY: - return "Rightalt"; - break; - case RIGHTCTRLKEY: - return "Rightctrl"; - break; - case RIGHTSHIFTKEY: - return "Rightshift"; - break; - case LEFTSHIFTKEY: - return "Leftshift"; - break; - - case ESCKEY: - return "Esc"; - break; - case TABKEY: - return "Tab"; - break; - case RETKEY: - return "Ret"; - break; - case SPACEKEY: - return "Space"; - break; - case LINEFEEDKEY: - return "Linefeed"; - break; - case BACKSPACEKEY: - return "Backspace"; - break; - case DELKEY: - return "Del"; - break; - case SEMICOLONKEY: - return "Semicolon"; - break; - case PERIODKEY: - return "Period"; - break; - case COMMAKEY: - return "Comma"; - break; - case QUOTEKEY: - return "Quote"; - break; - case ACCENTGRAVEKEY: - return "Accentgrave"; - break; - case MINUSKEY: - return "Minus"; - break; - case SLASHKEY: - return "Slash"; - break; - case BACKSLASHKEY: - return "Backslash"; - break; - case EQUALKEY: - return "Equal"; - break; - case LEFTBRACKETKEY: - return "Leftbracket"; - break; - case RIGHTBRACKETKEY: - return "Rightbracket"; - break; - - case LEFTARROWKEY: - return "Leftarrow"; - break; - case DOWNARROWKEY: - return "Downarrow"; - break; - case RIGHTARROWKEY: - return "Rightarrow"; - break; - case UPARROWKEY: - return "Uparrow"; - break; - - case PAD2: - return "Numpad 2"; - break; - case PAD4: - return "Numpad 4"; - break; - case PAD6: - return "Numpad 6"; - break; - case PAD8: - return "Numpad 8"; - break; - case PAD1: - return "Numpad 1"; - break; - case PAD3: - return "Numpad 3"; - break; - case PAD5: - return "Numpad 5"; - break; - case PAD7: - return "Numpad 7"; - break; - case PAD9: - return "Numpad 9"; - break; - - case PADPERIOD: - return "Numpad ."; - break; - case PADSLASHKEY: - return "Numpad /"; - break; - case PADASTERKEY: - return "Numpad *"; - break; - - case PAD0: - return "Numpad 0"; - break; - case PADMINUS: - return "Numpad -"; - break; - case PADENTER: - return "Numpad Enter"; - break; - case PADPLUSKEY: - return "Numpad +"; - break; - - case F1KEY: - return "F1"; - break; - case F2KEY: - return "F2"; - break; - case F3KEY: - return "F3"; - break; - case F4KEY: - return "F4"; - break; - case F5KEY: - return "F5"; - break; - case F6KEY: - return "F6"; - break; - case F7KEY: - return "F7"; - break; - case F8KEY: - return "F8"; - break; - case F9KEY: - return "F9"; - break; - case F10KEY: - return "F10"; - break; - case F11KEY: - return "F11"; - break; - case F12KEY: - return "F12"; - break; - - case PAUSEKEY: - return "Pause"; - break; - case INSERTKEY: - return "Insert"; - break; - case HOMEKEY: - return "Home"; - break; - case PAGEUPKEY: - return "Pageup"; - break; - case PAGEDOWNKEY: - return "Pagedown"; - break; - case ENDKEY: - return "End"; - break; - } + const char *name= NULL; + if(RNA_enum_name(event_type_items, (int)type, &name)) + return name; return ""; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 46e9df10adc..7f9a2153dc3 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -145,7 +145,6 @@ char *WM_operator_pystring(wmOperator *op) const char *arg_name= NULL; PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; /* for building the string */ DynStr *dynstr= BLI_dynstr_new(); @@ -155,10 +154,9 @@ char *WM_operator_pystring(wmOperator *op) BLI_dynstr_appendf(dynstr, "%s(", op->idname); iterprop= RNA_struct_iterator_property(op->ptr->type); - RNA_property_collection_begin(op->ptr, iterprop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; + RNA_PROP_BEGIN(op->ptr, propptr, iterprop) { + prop= propptr.data; arg_name= RNA_property_identifier(prop); if (strcmp(arg_name, "rna_type")==0) continue; @@ -170,8 +168,7 @@ char *WM_operator_pystring(wmOperator *op) MEM_freeN(buf); first_iter = 0; } - - RNA_property_collection_end(&iter); + RNA_PROP_END; BLI_dynstr_append(dynstr, ")"); @@ -291,7 +288,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 300, 20, style); - uiDefAutoButsRNA(C, layout, &ptr); + uiDefAutoButsRNA(C, layout, &ptr, 2); uiPopupBoundsBlock(block, 4.0f, 0, 0); uiEndBlock(C, block); @@ -333,7 +330,7 @@ static uiBlock *wm_block_create_menu(bContext *C, ARegion *ar, void *arg_op) uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1); layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 300, 20, style); - uiDefAutoButsRNA(C, layout, op->ptr); + uiDefAutoButsRNA(C, layout, op->ptr, 2); uiPopupBoundsBlock(block, 4.0f, 0, 0); uiEndBlock(C, block); @@ -402,7 +399,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u name[len]= '|'; } - if(0==uiSearchItemAdd(items, name, ot)) + if(0==uiSearchItemAdd(items, name, ot, 0)) break; } } @@ -421,7 +418,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *arg_op) uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1); but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, ""); - uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb); + uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); @@ -503,7 +500,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot) static int recentfile_exec(bContext *C, wmOperator *op) { - int event= RNA_enum_get(op->ptr, "nr"); + int event= RNA_int_get(op->ptr, "nr"); // XXX wm in context is not set correctly after WM_read_file -> crash // do it before for now, but is this correct with multiple windows? @@ -557,7 +554,7 @@ static void WM_OT_open_recentfile(wmOperatorType *ot) ot->exec= recentfile_exec; ot->poll= WM_operator_winactive; - RNA_def_property(ot->srna, "nr", PROP_ENUM, PROP_NONE); + RNA_def_property(ot->srna, "nr", PROP_INT, PROP_UNSIGNED); } /* ********* main file *********** */ diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 9bd55e1c5a7..835fdca52fe 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -1,5 +1,5 @@ /** - * $Id: mywindow.c 9584 2007-01-03 13:45:03Z ton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h index 1a1a0d0b71d..3d1b49983ed 100644 --- a/source/blender/windowmanager/wm_cursors.h +++ b/source/blender/windowmanager/wm_cursors.h @@ -1,5 +1,5 @@ /** - * $Id: BIF_cursors.h 7739 2006-06-15 14:22:59Z broken $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h index dfba9c27f17..c0c492018ff 100644 --- a/source/blender/windowmanager/wm_subwindow.h +++ b/source/blender/windowmanager/wm_subwindow.h @@ -1,5 +1,5 @@ /** - * $Id: wm_subwindow.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 4701eba810f..cd0d551211f 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -151,7 +151,7 @@ IF(WIN32) COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\ui\\*.*\" \"${TARGETDIR}\\.blender\\ui\" COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\" COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python25.zip\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python26.zip\" \"${TARGETDIR}\\\" ) FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR) @@ -164,7 +164,8 @@ IF(WIN32) COMMAND copy /Y \"${WIN_LIBDIR}\\sdl\\lib\\SDL.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\zlib\\lib\\zlib.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\tiff\\lib\\libtiff.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python25.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python26.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python26_d.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\pthreads\\lib\\pthreadVC2.dll\" \"${TARGETDIR}\\\" ) @@ -198,7 +199,7 @@ ADD_DEPENDENCIES(blender makesdna) FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS) -SET(BLENDER_LINK_LIBS bf_nodes ${BLENDER_LINK_LIBS} bf_windowmanager bf_editors blender_render blender_radiosity) +SET(BLENDER_LINK_LIBS bf_nodes ${BLENDER_LINK_LIBS} bf_windowmanager bf_editors blender_render) IF(WITH_ELBEEM) SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} bf_elbeem) @@ -218,7 +219,6 @@ IF(UNIX) bf_ghost bf_string blender_render - blender_radiosity blender_ONL bf_python bf_gen_python @@ -238,7 +238,6 @@ IF(UNIX) bf_kernel bf_decimation bf_elbeem - bf_yafray bf_IK bf_memutil bf_guardedalloc @@ -264,10 +263,7 @@ IF(UNIX) bf_ngnetwork extern_bullet bf_loopbacknetwork - bf_sumo bf_common - extern_solid - extern_qhull bf_moto bf_python bf_gen_python diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 44678cb73eb..fb222b419c3 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -65,6 +65,14 @@ #include "SYS_System.h" +#include "GPU_extensions.h" +#include "Value.h" + + + +#ifdef __cplusplus +extern "C" { +#endif /***/ #include "DNA_view3d_types.h" #include "DNA_screen_types.h" @@ -77,21 +85,13 @@ //XXX #include "BIF_scrarea.h" #include "BKE_main.h" -//#include "BKE_context.h" #include "BLI_blenlib.h" #include "BLO_readfile.h" #include "DNA_scene_types.h" /***/ -#include "GPU_extensions.h" -#include "Value.h" - - - -#ifdef __cplusplus -extern "C" { -#endif //XXX #include "BSE_headerbuttons.h" +#include "BKE_context.h" #include "../../blender/windowmanager/WM_types.h" #include "../../blender/windowmanager/wm_window.h" #include "../../blender/windowmanager/wm_event_system.h" @@ -118,19 +118,10 @@ static BlendFileData *load_game_data(char *filename) return bfd; } - -/* screw it, BKE_context.h is complaining! */ -extern "C" struct wmWindow *CTX_wm_window(const bContext *C); -extern "C" struct ScrArea *CTX_wm_area(const bContext *C); -extern "C" struct ARegion *CTX_wm_region(const bContext *C); -extern "C" struct Scene *CTX_data_scene(const bContext *C); -extern "C" struct Main *CTX_data_main(const bContext *C); - extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_framing) { /* context values */ struct wmWindow *win= CTX_wm_window(C); - struct ScrArea *area= CTX_wm_area(C); // curarea struct ARegion *ar= CTX_wm_region(C); struct Scene *scene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); @@ -159,8 +150,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami do { - View3D *v3d= (View3D*) area->spacedata.first; - RegionView3D *rv3d= (RegionView3D*) ar->regiondata; + View3D *v3d= CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); @@ -239,13 +230,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami scene->camera= v3d->camera; } - // some blender stuff MT_CmMatrix4x4 projmat; MT_CmMatrix4x4 viewmat; float camzoom; int i; - + for (i = 0; i < 16; i++) { float *viewmat_linear= (float*) rv3d->viewmat; @@ -257,7 +247,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami projmat.setElem(i, projmat_linear[i]); } - if(v3d->persp==V3D_CAMOB) { + if(rv3d->persp==V3D_CAMOB) { camzoom = (1.41421 + (rv3d->camzoom / 50.0)); camzoom *= camzoom; } @@ -348,10 +338,10 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { - if (v3d->persp != V3D_CAMOB) + if (rv3d->persp != V3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); - ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == V3D_ORTHO)); + ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == V3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(projmat); ketsjiengine->SetCameraOverrideViewMatrix(viewmat); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); @@ -587,7 +577,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami } extern "C" void StartKetsjiShellSimulation(struct wmWindow *win, - struct ScrArea *area, struct ARegion *ar, char* scenename, struct Main* maggie, diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 3b690a21584..2874a0273cc 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -19,7 +19,8 @@ SET(INC ../../../source/blender/windowmanager ../../../source/blender ../../../source/blender/include - ../../../source/blender/makesdna + ../../../source/blender/makesdna + ../../../source/blender/makesrna ../../../source/gameengine/Rasterizer ../../../source/gameengine/GameLogic ../../../source/gameengine/Expressions diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index aa83d17a03a..360794ceb33 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -28,11 +28,13 @@ #include "KX_BlenderCanvas.h" #include "DNA_screen_types.h" +#include "stdio.h" #ifdef HAVE_CONFIG_H #include #endif + KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, ARegion *ar) : m_win(win), m_ar(ar) diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile index f5486bae87b..ffa99a0c1b2 100644 --- a/source/gameengine/BlenderRoutines/Makefile +++ b/source/gameengine/BlenderRoutines/Makefile @@ -36,8 +36,6 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_GLEW)/include -CPPFLAGS += -I$(NAN_SUMO)/include -I$(NAN_SOLID)/include -CPPFLAGS += -I$(NAN_SOLID) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_FUZZICS)/include @@ -56,6 +54,7 @@ CPPFLAGS += -I../../blender/render/extern/include CPPFLAGS += -I../../blender/blenloader CPPFLAGS += -I../../blender/blenfont CPPFLAGS += -I../../blender/gpu +CPPFLAGS += -I../../blender/makesrna CPPFLAGS += -I../Converter CPPFLAGS += -I../Expressions CPPFLAGS += -I../GameLogic @@ -67,7 +66,6 @@ CPPFLAGS += -I../../kernel/gen_system CPPFLAGS += -I../Network CPPFLAGS += -I../Network/LoopBackNetwork CPPFLAGS += -I../Physics/common -CPPFLAGS += -I../Physics/Sumo CPPFLAGS += -I. ifeq ($(OS),windows) diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index a0cc3af3611..fc12f453d86 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -11,7 +11,8 @@ incs += ' #intern/ghost/include' incs += ' #intern/moto/include #source/gameengine/Ketsji #source/blender/blenlib' incs += ' #source/blender/blenkernel #source/blender' incs += ' #source/blender/blenfont #source/blender/editors/include' -incs += ' #source/blender/makesdna #source/gameengine/Rasterizer #source/gameengine/GameLogic' +incs += ' #source/blender/makesdna #source/blender/makesrna' +incs += ' #source/gameengine/Rasterizer #source/gameengine/GameLogic' incs += ' #source/gameengine/Expressions #source/gameengine/Network' incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common' incs += ' #source/gameengine/Physics/Bullet' @@ -20,11 +21,6 @@ incs += ' #intern/SoundSystem #source/blender/misc #source/blender/blenloader' incs += ' #extern/glew/include #source/blender/gpu' incs += ' #source/blender/windowmanager' -if env['WITH_BF_SOLID']: - incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' - incs += ' ' + env['BF_SOLID_INC'] - defs.append('USE_SUMO_SOLID') - if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt index fd05858710d..f546a31fb2e 100644 --- a/source/gameengine/CMakeLists.txt +++ b/source/gameengine/CMakeLists.txt @@ -38,7 +38,6 @@ ADD_SUBDIRECTORY(Rasterizer) ADD_SUBDIRECTORY(Rasterizer/RAS_OpenGLRasterizer) ADD_SUBDIRECTORY(SceneGraph) ADD_SUBDIRECTORY(Physics/Bullet) -ADD_SUBDIRECTORY(Physics/Sumo) ADD_SUBDIRECTORY(VideoTexture) IF(WITH_PLAYER) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index c0d28d28bda..bed99a4f502 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -446,7 +446,7 @@ PyObject* BL_ActionActuator::PyGetAction(PyObject* args, ShowDeprecationWarning("getAction()", "the action property"); if (m_action){ - return PyString_FromString(m_action->id.name+2); + return PyUnicode_FromString(m_action->id.name+2); } Py_RETURN_NONE; } @@ -796,7 +796,7 @@ PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* args, } PyObject* BL_ActionActuator::PyGetChannel(PyObject* value) { - char *string= PyString_AsString(value); + char *string= _PyUnicode_AsString(value); if (!string) { PyErr_SetString(PyExc_TypeError, "expected a single string"); @@ -888,7 +888,7 @@ PyObject* BL_ActionActuator::PySetType(PyObject* args, PyObject* BL_ActionActuator::PyGetContinue() { ShowDeprecationWarning("getContinue()", "the continue property"); - return PyInt_FromLong((long)(m_end_reset==0)); + return PyLong_FromSsize_t((long)(m_end_reset==0)); } PyObject* BL_ActionActuator::PySetContinue(PyObject* value) { @@ -962,9 +962,9 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, else { MT_Vector3 loc; MT_Vector3 size; - MT_Vector4 quat; + MT_Quaternion quat; - if (!PyVecTo(pyloc, loc) || !PyVecTo(pysize, size) || !PyVecTo(pyquat, quat)) + if (!PyVecTo(pyloc, loc) || !PyVecTo(pysize, size) || !PyQuatTo(pyquat, quat)) return NULL; // same as above @@ -977,7 +977,7 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, // for some reason loc.setValue(pchan->loc) fails pchan->loc[0]= loc[0]; pchan->loc[1]= loc[1]; pchan->loc[2]= loc[2]; pchan->size[0]= size[0]; pchan->size[1]= size[1]; pchan->size[2]= size[2]; - pchan->quat[0]= quat[0]; pchan->quat[1]= quat[1]; pchan->quat[2]= quat[2]; pchan->quat[3]= quat[3]; + pchan->quat[0]= quat[3]; pchan->quat[1]= quat[0]; pchan->quat[2]= quat[1]; pchan->quat[3]= quat[2]; /* notice xyzw -> wxyz is intentional */ } pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE; @@ -1005,19 +1005,15 @@ PyTypeObject BL_ActionActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject BL_ActionActuator::Parents[] = { - &BL_ActionActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef BL_ActionActuator::Methods[] = { @@ -1065,37 +1061,24 @@ PyAttributeDef BL_ActionActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* BL_ActionActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* BL_ActionActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int BL_ActionActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - - PyObject* BL_ActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { BL_ActionActuator* self= static_cast(self_v); - return PyString_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); + return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); } int BL_ActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { BL_ActionActuator* self= static_cast(self_v); - if (!PyString_Check(value)) + if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Action Actuator, expected the string name of the action"); return PY_SET_ATTR_FAIL; } bAction *action= NULL; - STR_String val = PyString_AsString(value); + STR_String val = _PyUnicode_AsString(value); if (val != "") { diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 422b16bb3ec..e328ce126ca 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -49,9 +49,8 @@ public: short blendin, short priority, short end_reset, - float stride, - PyTypeObject* T=&Type) - : SCA_IActuator(gameobj,T), + float stride) + : SCA_IActuator(gameobj), m_lastpos(0, 0, 0), m_blendframe(0), @@ -113,10 +112,6 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,setChannel); - virtual PyObject* py_getattro(PyObject* attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject* attr, PyObject* value); - static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b907e300879..177f261e40b 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -163,7 +163,6 @@ extern "C" { #include "SG_BBox.h" #include "SG_Tree.h" -// defines USE_ODE to choose physics engine #include "KX_ConvertPhysicsObject.h" #ifdef USE_BULLET #include "CcdPhysicsEnvironment.h" @@ -1610,18 +1609,6 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, break; #endif -#ifdef USE_SUMO_SOLID - case UseSumo: - KX_ConvertSumoObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop); - break; -#endif - -#ifdef USE_ODE - case UseODE: - KX_ConvertODEEngineObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop); - break; -#endif //USE_ODE - case UseDynamo: //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop); break; diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 7aa8714de3a..970539777f4 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -427,21 +427,18 @@ PyTypeObject BL_ShapeActionActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject BL_ShapeActionActuator::Parents[] = { - &BL_ShapeActionActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; + PyMethodDef BL_ShapeActionActuator::Methods[] = { {"setAction", (PyCFunction) BL_ShapeActionActuator::sPySetAction, METH_VARARGS, (PY_METHODCHAR)SetAction_doc}, {"setStart", (PyCFunction) BL_ShapeActionActuator::sPySetStart, METH_VARARGS, (PY_METHODCHAR)SetStart_doc}, @@ -480,19 +477,6 @@ PyAttributeDef BL_ShapeActionActuator::Attributes[] = { { NULL } //Sentinel }; - -PyObject* BL_ShapeActionActuator::py_getattro(PyObject* attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* BL_ShapeActionActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int BL_ShapeActionActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - /* setStart */ const char BL_ShapeActionActuator::GetAction_doc[] = "getAction()\n" @@ -501,7 +485,7 @@ const char BL_ShapeActionActuator::GetAction_doc[] = PyObject* BL_ShapeActionActuator::PyGetAction() { ShowDeprecationWarning("getAction()", "the action property"); if (m_action){ - return PyString_FromString(m_action->id.name+2); + return PyUnicode_FromString(m_action->id.name+2); } Py_RETURN_NONE; } @@ -860,21 +844,21 @@ PyObject* BL_ShapeActionActuator::PySetType(PyObject* args) { PyObject* BL_ShapeActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { BL_ShapeActionActuator* self= static_cast(self_v); - return PyString_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); + return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); } int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { BL_ShapeActionActuator* self= static_cast(self_v); /* exact copy of BL_ActionActuator's function from here down */ - if (!PyString_Check(value)) + if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, expected the string name of the action"); return PY_SET_ATTR_FAIL; } bAction *action= NULL; - STR_String val = PyString_AsString(value); + STR_String val = _PyUnicode_AsString(value); if (val != "") { diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index d268eef6d23..890fe3f9de9 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -50,9 +50,8 @@ public: short playtype, short blendin, short priority, - float stride, - PyTypeObject* T=&Type) - : SCA_IActuator(gameobj,T), + float stride) + : SCA_IActuator(gameobj), m_lastpos(0, 0, 0), m_blendframe(0), @@ -106,10 +105,6 @@ public: KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetType); KX_PYMETHOD_DOC_VARARGS(BL_ShapeActionActuator,SetType); - virtual PyObject* py_getattro(PyObject* attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject* attr, PyObject* value); - static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 86e20b88580..9e0a710f44f 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -44,21 +44,12 @@ #include "DummyPhysicsEnvironment.h" -//to decide to use sumo/ode or dummy physics - defines USE_ODE #include "KX_ConvertPhysicsObject.h" #ifdef USE_BULLET #include "CcdPhysicsEnvironment.h" #endif -#ifdef USE_ODE -#include "OdePhysicsEnvironment.h" -#endif //USE_ODE - -#ifdef USE_SUMO_SOLID -#include "SumoPhysicsEnvironment.h" -#endif - #include "KX_BlenderSceneConverter.h" #include "KX_BlenderScalarInterpolator.h" #include "BL_BlenderDataConversion.h" @@ -145,10 +136,6 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itm).second; itm++; } - -#ifdef USE_SUMO_SOLID - KX_ClearSumoSharedShapes(); -#endif #ifdef USE_BULLET KX_ClearBulletSharedShapes(); @@ -331,20 +318,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, destinationscene->SetPhysicsEnvironment(ccdPhysEnv); break; } -#endif - -#ifdef USE_SUMO_SOLID - case UseSumo: - destinationscene ->SetPhysicsEnvironment(new SumoPhysicsEnvironment()); - break; -#endif -#ifdef USE_ODE - - case UseODE: - destinationscene ->SetPhysicsEnvironment(new ODEPhysicsEnvironment()); - break; -#endif //USE_ODE - +#endif case UseDynamo: { } diff --git a/source/gameengine/Converter/Makefile b/source/gameengine/Converter/Makefile index abded70f289..ed95aa968c7 100644 --- a/source/gameengine/Converter/Makefile +++ b/source/gameengine/Converter/Makefile @@ -39,8 +39,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SOLID)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_BULLET2)/include CPPFLAGS += -I../../blender diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 3e0929e605a..05ea01c902a 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -21,11 +21,6 @@ incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu' incs += ' #source/blender/windowmanager' incs += ' #source/blender/makesrna' -if env['WITH_BF_SOLID']: - incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' - incs += ' ' + env['BF_SOLID_INC'] - defs.append('USE_SUMO_SOLID') - incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp index d90da8b3a92..6779c2ea780 100644 --- a/source/gameengine/Expressions/BoolValue.cpp +++ b/source/gameengine/Expressions/BoolValue.cpp @@ -29,7 +29,6 @@ const STR_String CBoolValue::sTrueString = "TRUE"; const STR_String CBoolValue::sFalseString = "FALSE"; - CBoolValue::CBoolValue() /* pre: false @@ -210,5 +209,5 @@ CValue* CBoolValue::GetReplica() PyObject* CBoolValue::ConvertValueToPython() { - return PyInt_FromLong(m_bool != 0); + return PyBool_FromLong(m_bool != 0); } diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index e3942b46557..dffd13f64ff 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -32,6 +32,7 @@ SET(INC ../../../intern/string ../../../intern/moto/include ../../../source/gameengine/SceneGraph + ../../../source/blender/blenloader ${PYTHON_INC} ) diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index 227518e9439..b782de4bef6 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -330,7 +330,7 @@ void CIntValue::SetValue(CValue* newval) PyObject* CIntValue::ConvertValueToPython() { if((m_int > INT_MIN) && (m_int < INT_MAX)) - return PyInt_FromLong(m_int); + return PyLong_FromSsize_t(m_int); else return PyLong_FromLongLong(m_int); } diff --git a/source/gameengine/Expressions/KX_Python.h b/source/gameengine/Expressions/KX_Python.h index b8006fdf0ed..61f7ef05042 100644 --- a/source/gameengine/Expressions/KX_Python.h +++ b/source/gameengine/Expressions/KX_Python.h @@ -32,6 +32,8 @@ //#define USE_DL_EXPORT #include "Python.h" +#define USE_MATHUTILS // Blender 2.5x api will use mathutils, for a while we might want to test without it + #ifdef __FreeBSD__ #include #if __FreeBSD_version > 500039 diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 59344ddb7b7..38b00dcc8fb 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -76,9 +76,9 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) return NULL; } - if (PyString_Check(pyindex)) + if (PyUnicode_Check(pyindex)) { - CValue *item = ((CListValue*) list)->FindValue(PyString_AsString(pyindex)); + CValue *item = ((CListValue*) list)->FindValue(_PyUnicode_AsString(pyindex)); if (item) { PyObject* pyobj = item->ConvertValueToPython(); if(pyobj) @@ -87,14 +87,14 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) return item->GetProxy(); } } - else if (PyInt_Check(pyindex)) + else if (PyLong_Check(pyindex)) { - int index = PyInt_AsLong(pyindex); + int index = PyLong_AsSsize_t(pyindex); return listvalue_buffer_item(self, index); /* wont add a ref */ } PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */ - PyErr_Format(PyExc_KeyError, "CList[key]: '%s' key not in list", PyString_AsString(pyindex_str)); + PyErr_Format(PyExc_KeyError, "CList[key]: '%s' key not in list", _PyUnicode_AsString(pyindex_str)); Py_DECREF(pyindex_str); return NULL; } @@ -220,12 +220,12 @@ static int listvalue_buffer_contains(PyObject *self_v, PyObject *value) return -1; } - if (PyString_Check(value)) { - if (self->FindValue((const char *)PyString_AsString(value))) { + if (PyUnicode_Check(value)) { + if (self->FindValue((const char *)_PyUnicode_AsString(value))) { return 1; } } - else if (BGE_PROXY_CHECK_TYPE(value)) { /* not dict like at all but this worked before __contains__ was used */ + else if (PyObject_TypeCheck(value, &CValue::Type)) { /* not dict like at all but this worked before __contains__ was used */ CValue *item= static_cast(BGE_PROXY_REF(value)); for (int i=0; i < self->GetCount(); i++) if (self->GetValue(i) == item) // Com @@ -289,25 +289,19 @@ PyTypeObject CListValue::Type = { 0, /*tp_hash*/ 0, /*tp_call */ 0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject CListValue::Parents[] = { - &CListValue::Type, + Methods, + 0, + 0, &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - - PyMethodDef CListValue::Methods[] = { /* List style access */ {"append", (PyCFunction)CListValue::sPyappend,METH_O}, @@ -329,21 +323,12 @@ PyAttributeDef CListValue::Attributes[] = { { NULL } //Sentinel }; -PyObject* CListValue::py_getattro(PyObject* attr) { - py_getattro_up(CValue); -} - -PyObject* CListValue::py_getattro_dict() { - py_getattro_dict_up(CValue); -} - - ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// -CListValue::CListValue(PyTypeObject *T ) -: CPropValue(T) +CListValue::CListValue() +: CPropValue() { m_bReleaseContents=true; } @@ -559,7 +544,7 @@ PyObject* CListValue::Pyindex(PyObject *value) CValue* elem = GetValue(i); if (checkobj==elem || CheckEqual(checkobj,elem)) { - result = PyInt_FromLong(i); + result = PyLong_FromSsize_t(i); break; } } @@ -582,7 +567,7 @@ PyObject* CListValue::Pycount(PyObject* value) if (checkobj==NULL) { /* in this case just return that there are no items in the list */ PyErr_Clear(); - return PyInt_FromLong(0); + return PyLong_FromSsize_t(0); } int numelem = GetCount(); @@ -596,7 +581,7 @@ PyObject* CListValue::Pycount(PyObject* value) } checkobj->Release(); - return PyInt_FromLong(numfound); + return PyLong_FromSsize_t(numfound); } /* Matches python dict.get(key, [default]) */ @@ -623,7 +608,7 @@ PyObject* CListValue::Pyget(PyObject *args) /* Matches python dict.has_key() */ PyObject* CListValue::Pyhas_key(PyObject* value) { - if (PyString_Check(value) && FindValue((const char *)PyString_AsString(value))) + if (PyUnicode_Check(value) && FindValue((const char *)_PyUnicode_AsString(value))) Py_RETURN_TRUE; Py_RETURN_FALSE; diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 68e900e25e0..98e6f216f11 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -24,7 +24,7 @@ class CListValue : public CPropValue //PLUGIN_DECLARE_SERIAL (CListValue,CValue) public: - CListValue(PyTypeObject *T = &Type); + CListValue(); virtual ~CListValue(); void AddConfigurationData(CValue* menuvalue); @@ -60,8 +60,6 @@ public: bool CheckEqual(CValue* first,CValue* second); - virtual PyObject* py_getattro(PyObject* attr); - virtual PyObject* py_getattro_dict(); virtual PyObject* py_repr(void) { PyObject *py_proxy= this->GetProxy(); PyObject *py_list= PySequence_List(py_proxy); diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile index f46c0037200..09512c3ae87 100644 --- a/source/gameengine/Expressions/Makefile +++ b/source/gameengine/Expressions/Makefile @@ -37,6 +37,7 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I../../blender/makesdna +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index defb6853e67..729fff31052 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -74,11 +74,13 @@ PyTypeObject PyObjectPlus::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + NULL // no subtype }; @@ -91,6 +93,88 @@ PyObjectPlus::~PyObjectPlus() // assert(ob_refcnt==0); } + +PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the entry in Type. +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(self); + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return NULL; + } + + return self_plus->py_repr(); +} + + +PyObject * PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyTypeObject *base_type; + PyObjectPlus_Proxy *base = NULL; + + if (!PyArg_ParseTuple(args, "O:Base PyObjectPlus", &base)) + return NULL; + + /* the 'base' PyObject may be subclassed (multiple times even) + * we need to find the first C++ defined class to check 'type' + * is a subclass of the base arguments type. + * + * This way we can share one tp_new function for every PyObjectPlus + * + * eg. + * + * # CustomOb is called 'type' in this C code + * class CustomOb(GameTypes.KX_GameObject): + * pass + * + * # this calls py_base_new(...), the type of 'CustomOb' is checked to be a subclass of the 'cont.owner' type + * ob = CustomOb(cont.owner) + * + * */ + base_type= Py_TYPE(base); + while(base_type && !BGE_PROXY_CHECK_TYPE(base_type)) + base_type= base_type->tp_base; + + if(base_type==NULL || !BGE_PROXY_CHECK_TYPE(base_type)) { + PyErr_SetString(PyExc_TypeError, "can't subclass from a blender game type because the argument given is not a game class or subclass"); + return NULL; + } + + /* use base_type rather then Py_TYPE(base) because we could alredy be subtyped */ + if(!PyType_IsSubtype(type, base_type)) { + PyErr_Format(PyExc_TypeError, "can't subclass blender game type <%s> from <%s> because it is not a subclass", base_type->tp_name, type->tp_name); + return NULL; + } + + /* invalidate the existing base and return a new subclassed one, + * this is a bit dodgy in that it also attaches its self to the existing object + * which is not really 'correct' python OO but for our use its OK. */ + + PyObjectPlus_Proxy *ret = (PyObjectPlus_Proxy *) type->tp_alloc(type, 0); /* starts with 1 ref, used for the return ref' */ + ret->ref= base->ref; + base->ref= NULL; /* invalidate! disallow further access */ + + ret->py_owns= base->py_owns; + + ret->ref->m_proxy= NULL; + + /* 'base' may be free'd after this func finished but not necessarily + * there is no reference to the BGE data now so it will throw an error on access */ + Py_DECREF(base); + + ret->ref->m_proxy= (PyObject *)ret; /* no need to add a ref because one is added when creating. */ + Py_INCREF(ret); /* we return a new ref but m_proxy holds a ref so we need to add one */ + + + /* 'ret' will have 2 references. + * - One ref is needed because ret->ref->m_proxy holds a refcount to the current proxy. + * - Another is needed for returning the value. + * + * So we should be ok with 2 refs, but for some reason this crashes. so adding a new ref... + * */ + + return (PyObject *)ret; +} + void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper { PyObjectPlus *self_plus= BGE_PROXY_REF(self); @@ -99,143 +183,56 @@ void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */ delete self_plus; } - + BGE_PROXY_REF(self)= NULL; // not really needed } + +#if 0 + /* is ok normally but not for subtyping, use tp_free instead. */ PyObject_DEL( self ); +#else + Py_TYPE(self)->tp_free(self); +#endif }; -PyObjectPlus::PyObjectPlus(PyTypeObject *T) : SG_QList() // constructor +PyObjectPlus::PyObjectPlus() : SG_QList() // constructor { - MT_assert(T != NULL); m_proxy= NULL; }; - + /*------------------------------ * PyObjectPlus Methods -- Every class, even the abstract one should have a Methods ------------------------------*/ PyMethodDef PyObjectPlus::Methods[] = { - {"isA", (PyCFunction) sPyisA, METH_O}, {NULL, NULL} /* Sentinel */ }; +#define attr_invalid (&(PyObjectPlus::Attributes[0])) PyAttributeDef PyObjectPlus::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("invalid", PyObjectPlus, pyattr_get_invalid), {NULL} //Sentinel }; -PyObject* PyObjectPlus::pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ - Py_RETURN_FALSE; -} -/*------------------------------ - * PyObjectPlus Parents -- Every class, even the abstract one should have parents -------------------------------*/ -PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL}; -/*------------------------------ - * PyObjectPlus attributes -- attributes -------------------------------*/ - - -/* This should be the entry in Type since it takes the C++ class from PyObjectPlus_Proxy */ -PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) +PyObject* PyObjectPlus::pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - PyObjectPlus *self_plus= BGE_PROXY_REF(self); - if(self_plus==NULL) { - if(!strcmp("invalid", PyString_AsString(attr))) { - Py_RETURN_TRUE; - } - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return NULL; - } - - PyObject *ret= self_plus->py_getattro(attr); - - /* Attribute not found, was this a __dict__ lookup?, otherwise set an error if none is set */ - if(ret==NULL) { - char *attr_str= PyString_AsString(attr); - - if (strcmp(attr_str, "__dict__")==0) - { - /* the error string will probably not - * be set but just incase clear it */ - PyErr_Clear(); - ret= self_plus->py_getattro_dict(); - } - else if (!PyErr_Occurred()) { - /* We looked for an attribute but it wasnt found - * since py_getattro didnt set the error, set it here */ - PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", self->ob_type->tp_name, attr_str); - } - } - return ret; + return PyBool_FromLong(self_v ? 1:0); } -/* This should be the entry in Type since it takes the C++ class from PyObjectPlus_Proxy */ -int PyObjectPlus::py_base_setattro(PyObject *self, PyObject *attr, PyObject *value) +/* note, this is called as a python 'getset, where the PyAttributeDef is the closure */ +PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef) { - PyObjectPlus *self_plus= BGE_PROXY_REF(self); - if(self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return -1; - } - - if (value==NULL) - return self_plus->py_delattro(attr); - - return self_plus->py_setattro(attr, value); -} + void *self= (void *)(BGE_PROXY_REF(self_py)); + if(self==NULL) { + if(attrdef == attr_invalid) + Py_RETURN_TRUE; // dont bother running the function -PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the entry in Type. -{ - - PyObjectPlus *self_plus= BGE_PROXY_REF(self); - if(self_plus==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); return NULL; } - - return self_plus->py_repr(); -} -PyObject *PyObjectPlus::py_getattro(PyObject* attr) -{ - PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ - if (descr == NULL) { - return NULL; /* py_base_getattro sets the error, this way we can avoid setting the error at many levels */ - } else { - /* Copied from py_getattro_up */ - if (PyCObject_Check(descr)) { - return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); - } else if (descr->ob_type->tp_descr_get) { - return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); - } else { - return NULL; - } - /* end py_getattro_up copy */ - } -} - -PyObject* PyObjectPlus::py_getattro_dict() { - return py_getattr_dict(NULL, Type.tp_dict); -} -int PyObjectPlus::py_delattro(PyObject* attr) -{ - PyErr_SetString(PyExc_AttributeError, "attribute cant be deleted"); - return 1; -} - -int PyObjectPlus::py_setattro(PyObject *attr, PyObject* value) -{ - PyErr_SetString(PyExc_AttributeError, "attribute cant be set"); - return PY_SET_ATTR_MISSING; -} - -PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef) -{ if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY) { // fake attribute, ignore @@ -259,14 +256,14 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef { bool *val = reinterpret_cast(ptr); ptr += sizeof(bool); - PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val)); break; } case KX_PYATTRIBUTE_TYPE_SHORT: { short int *val = reinterpret_cast(ptr); ptr += sizeof(short int); - PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val)); break; } case KX_PYATTRIBUTE_TYPE_ENUM: @@ -281,7 +278,7 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef { int *val = reinterpret_cast(ptr); ptr += sizeof(int); - PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val)); break; } case KX_PYATTRIBUTE_TYPE_FLOAT: @@ -305,12 +302,12 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef case KX_PYATTRIBUTE_TYPE_BOOL: { bool *val = reinterpret_cast(ptr); - return PyInt_FromLong(*val); + return PyLong_FromSsize_t(*val); } case KX_PYATTRIBUTE_TYPE_SHORT: { short int *val = reinterpret_cast(ptr); - return PyInt_FromLong(*val); + return PyLong_FromSsize_t(*val); } case KX_PYATTRIBUTE_TYPE_ENUM: // enum are like int, just make sure the field size is the same @@ -322,7 +319,7 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef case KX_PYATTRIBUTE_TYPE_INT: { int *val = reinterpret_cast(ptr); - return PyInt_FromLong(*val); + return PyLong_FromSsize_t(*val); } case KX_PYATTRIBUTE_TYPE_FLOAT: { @@ -331,18 +328,23 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef } case KX_PYATTRIBUTE_TYPE_VECTOR: { - PyObject* resultlist = PyList_New(3); MT_Vector3 *val = reinterpret_cast(ptr); +#ifdef USE_MATHUTILS + float fval[3]= {(*val)[0], (*val)[1], (*val)[2]}; + return newVectorObject(fval, 3, Py_NEW, NULL); +#else + PyObject* resultlist = PyList_New(3); for (unsigned int i=0; i<3; i++) { PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i])); } return resultlist; +#endif } case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *val = reinterpret_cast(ptr); - return PyString_FromString(*val); + return PyUnicode_FromString(*val); } default: return NULL; @@ -350,8 +352,15 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef } } -int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value) +/* note, this is called as a python getset */ +int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef) { + void *self= (void *)(BGE_PROXY_REF(self_py)); + if(self==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return PY_SET_ATTR_FAIL; + } + void *undoBuffer = NULL; void *sourceBuffer = NULL; size_t bufferSize = 0; @@ -416,9 +425,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { bool *var = reinterpret_cast(ptr); ptr += sizeof(bool); - if (PyInt_Check(item)) + if (PyLong_Check(item)) { - *var = (PyInt_AsLong(item) != 0); + *var = (PyLong_AsSsize_t(item) != 0); } else if (PyBool_Check(item)) { @@ -435,9 +444,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { short int *var = reinterpret_cast(ptr); ptr += sizeof(short int); - if (PyInt_Check(item)) + if (PyLong_Check(item)) { - long val = PyInt_AsLong(item); + long val = PyLong_AsSsize_t(item); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -471,9 +480,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { int *var = reinterpret_cast(ptr); ptr += sizeof(int); - if (PyInt_Check(item)) + if (PyLong_Check(item)) { - long val = PyInt_AsLong(item); + long val = PyLong_AsSsize_t(item); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -606,9 +615,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_BOOL: { bool *var = reinterpret_cast(ptr); - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - *var = (PyInt_AsLong(value) != 0); + *var = (PyLong_AsSsize_t(value) != 0); } else if (PyBool_Check(value)) { @@ -624,9 +633,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_SHORT: { short int *var = reinterpret_cast(ptr); - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - long val = PyInt_AsLong(value); + long val = PyLong_AsSsize_t(value); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -659,9 +668,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_INT: { int *var = reinterpret_cast(ptr); - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - long val = PyInt_AsLong(value); + long val = PyLong_AsSsize_t(value); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -746,9 +755,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *var = reinterpret_cast(ptr); - if (PyString_Check(value)) + if (PyUnicode_Check(value)) { - char *val = PyString_AsString(value); + char *val = _PyUnicode_AsString(value); if (attrdef->m_clamp) { if (strlen(val) < attrdef->m_imin) @@ -829,48 +838,6 @@ PyObject *PyObjectPlus::py_repr(void) return NULL; } -/*------------------------------ - * PyObjectPlus isA -- the isA functions -------------------------------*/ -bool PyObjectPlus::isA(PyTypeObject *T) // if called with a Type, use "typename" -{ - int i; - PyParentObject P; - PyParentObject *Ps = GetParents(); - - for (P = Ps[i=0]; P != NULL; P = Ps[i++]) - if (P==T) - return true; - - return false; -} - - -bool PyObjectPlus::isA(const char *mytypename) // check typename of each parent -{ - int i; - PyParentObject P; - PyParentObject *Ps = GetParents(); - - for (P = Ps[i=0]; P != NULL; P = Ps[i++]) - if (strcmp(P->tp_name, mytypename)==0) - return true; - - return false; -} - -PyObject *PyObjectPlus::PyisA(PyObject *value) // Python wrapper for isA -{ - if (PyType_Check(value)) { - return PyBool_FromLong(isA((PyTypeObject *)value)); - } else if (PyString_Check(value)) { - return PyBool_FromLong(isA(PyString_AsString(value))); - } - PyErr_SetString(PyExc_TypeError, "object.isA(value): expected a type or a string"); - return NULL; -} - - void PyObjectPlus::ProcessReplica() { /* Clear the proxy, will be created again if needed with GetProxy() @@ -895,27 +862,6 @@ void PyObjectPlus::InvalidateProxy() // check typename of each parent } } -/* Utility function called by the macro py_getattro_up() - * for getting ob.__dict__() values from our PyObject - * this is used by python for doing dir() on an object, so its good - * if we return a list of attributes and methods. - * - * Other then making dir() useful the value returned from __dict__() is not useful - * since every value is a Py_None - * */ -PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict) -{ - if(pydict==NULL) { /* incase calling __dict__ on the parent of this object raised an error */ - PyErr_Clear(); - pydict = PyDict_New(); - } - - PyDict_Update(pydict, tp_dict); - return pydict; -} - - - PyObject *PyObjectPlus::GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp) { if (self->m_proxy==NULL) @@ -986,7 +932,7 @@ void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* n co_filename= PyObject_GetAttrString(f_code, "co_filename"); if (co_filename) { - printf("\t%s:%d\n", PyString_AsString(co_filename), (int)PyInt_AsLong(f_lineno)); + printf("\t%s:%d\n", _PyUnicode_AsString(co_filename), (int)PyLong_AsSsize_t(f_lineno)); Py_DECREF(f_lineno); Py_DECREF(f_code); diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index c002dccefe4..a18df9d36a9 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -45,21 +45,15 @@ * Python defines ------------------------------*/ - - -#if PY_VERSION_HEX > 0x03000000 -#define PyString_FromString PyUnicode_FromString -#define PyString_FromFormat PyUnicode_FromFormat -#define PyString_Check PyUnicode_Check -#define PyString_Size PyUnicode_GetSize - -#define PyInt_FromLong PyLong_FromSsize_t -#define PyInt_AsLong PyLong_AsSsize_t -#define PyString_AsString _PyUnicode_AsString -#define PyInt_Check PyLong_Check -#define PyInt_AS_LONG PyLong_AsLong // TODO - check this one +#ifdef USE_MATHUTILS +extern "C" { +#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */ +} #endif +extern "C" { +#include "../../blender/python/intern/bpy_compat.h" +} /* @@ -141,7 +135,7 @@ typedef struct { #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns) /* Note, sometimes we dont care what BGE type this is as long as its a proxy */ -#define BGE_PROXY_CHECK_TYPE(_self) ((_self)->ob_type->tp_dealloc == PyObjectPlus::py_base_dealloc) +#define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc) // This must be the first line of each @@ -151,41 +145,10 @@ typedef struct { static PyTypeObject Type; \ static PyMethodDef Methods[]; \ static PyAttributeDef Attributes[]; \ - static PyParentObject Parents[]; \ virtual PyTypeObject *GetType(void) {return &Type;}; \ - virtual PyParentObject *GetParents(void) {return Parents;} \ virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \ virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \ - - - - // This defines the py_getattro_up macro - // which allows attribute and method calls - // to be properly passed up the hierarchy. - // - // Note, PyDict_GetItem() WONT set an exception! - // let the py_base_getattro function do this. - -#define py_getattro_up(Parent) \ - \ - PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ - \ - if(descr) { \ - if (PyCObject_Check(descr)) { \ - return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); \ - } else if (descr->ob_type->tp_descr_get) { \ - return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \ - } else { \ - return NULL; \ - } \ - } else { \ - return Parent::py_getattro(attr); \ - } - -#define py_getattro_dict_up(Parent) \ - return py_getattr_dict(Parent::py_getattro_dict(), Type.tp_dict); - /* * nonzero values are an error for setattr * however because of the nested lookups we need to know if the errors @@ -197,29 +160,6 @@ typedef struct { #define PY_SET_ATTR_MISSING -1 #define PY_SET_ATTR_SUCCESS 0 -#define py_setattro_up(Parent) \ - PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ - \ - if(descr) { \ - if (PyCObject_Check(descr)) { \ - const PyAttributeDef* attrdef= reinterpret_cast(PyCObject_AsVoidPtr(descr)); \ - if (attrdef->m_access == KX_PYATTRIBUTE_RO) { \ - PyErr_Format(PyExc_AttributeError, "\"%s\" is read only", PyString_AsString(attr)); \ - return PY_SET_ATTR_FAIL; \ - } \ - else { \ - return py_set_attrdef((void *)this, attrdef, value); \ - } \ - } else { \ - PyErr_Format(PyExc_AttributeError, "\"%s\" cannot be set", PyString_AsString(attr)); \ - return PY_SET_ATTR_FAIL; \ - } \ - } else { \ - PyErr_Clear(); \ - return Parent::py_setattro(attr, value); \ - } - - /** * These macros are helpfull when embedding Python routines. The second * macro is one that also requires a documentation string @@ -489,7 +429,7 @@ class PyObjectPlus : public SG_QList Py_Header; // Always start with Py_Header public: - PyObjectPlus(PyTypeObject *T); + PyObjectPlus(); PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */ @@ -497,30 +437,19 @@ public: /* These static functions are referenced by ALL PyObjectPlus_Proxy types * they take the C++ reference from the PyObjectPlus_Proxy and call - * its own virtual py_getattro, py_setattro etc. functions. + * its own virtual py_repr, py_base_dealloc ,etc. functions. */ + + static PyObject* py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* allows subclassing */ static void py_base_dealloc(PyObject *self); - static PyObject* py_base_getattro(PyObject * self, PyObject *attr); - static int py_base_setattro(PyObject *self, PyObject *attr, PyObject *value); static PyObject* py_base_repr(PyObject *self); /* These are all virtual python methods that are defined in each class * Our own fake subclassing calls these on each class, then calls the parent */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_delattro(PyObject *attr); - virtual int py_setattro(PyObject *attr, PyObject *value); virtual PyObject* py_repr(void); - static PyObject* py_get_attrdef(void *self, const PyAttributeDef *attrdef); - static int py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value); - - /* isA() methods, shonky replacement for pythons issubclass() - * which we cant use because we have our own subclass system */ - bool isA(PyTypeObject *T); - bool isA(const char *mytypename); - - KX_PYMETHOD_O(PyObjectPlus,isA); + static PyObject* py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef); + static int py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef); /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */ static PyObject* pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h index 52f8a580f4d..c580e8fd23a 100644 --- a/source/gameengine/Expressions/StringValue.h +++ b/source/gameengine/Expressions/StringValue.h @@ -40,7 +40,7 @@ public: virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); }; virtual CValue* GetReplica(); virtual PyObject* ConvertValueToPython() { - return PyString_FromString(m_strString.Ptr()); + return PyUnicode_FromString(m_strString.Ptr()); } private: diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 61dabff510b..d8c81f56f66 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -54,15 +54,17 @@ PyTypeObject CValue::Type = { py_base_repr, 0, 0,0,0,0,0, - py_base_getattro, - py_base_setattro, - 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject CValue::Parents[] = { - &CValue::Type, - NULL + NULL, + NULL, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; PyMethodDef CValue::Methods[] = { @@ -74,7 +76,7 @@ PyObject* CValue::PyGetName() { ShowDeprecationWarning("getName()", "the name property"); - return PyString_FromString(this->GetName()); + return PyUnicode_FromString(this->GetName()); } /*#define CVALUE_DEBUG*/ @@ -100,8 +102,8 @@ std::vector gRefList; //int gRefCountValue; #endif -CValue::CValue(PyTypeObject *T) - : PyObjectPlus(T), +CValue::CValue() + : PyObjectPlus(), #else CValue::CValue() : @@ -553,33 +555,9 @@ PyAttributeDef CValue::Attributes[] = { { NULL } //Sentinel }; - -PyObject* CValue::py_getattro(PyObject *attr) -{ - char *attr_str= PyString_AsString(attr); - CValue* resultattr = GetProperty(attr_str); - if (resultattr) - { - /* only show the wanting here because python inspects for __class__ and KX_MeshProxy uses CValues name attr */ - ShowDeprecationWarning("val = ob.attr", "val = ob['attr']"); - - PyObject* pyconvert = resultattr->ConvertValueToPython(); - - if (pyconvert) - return pyconvert; - else - return resultattr->GetProxy(); - } - py_getattro_up(PyObjectPlus); -} - -PyObject* CValue::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - PyObject * CValue::pyattr_get_name(void * self_v, const KX_PYATTRIBUTE_DEF * attrdef) { CValue * self = static_cast (self_v); - return PyString_FromString(self->GetName()); + return PyUnicode_FromString(self->GetName()); } CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) @@ -623,30 +601,23 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) { vallie = new CFloatValue( (float)PyFloat_AsDouble(pyobj) ); } else +#if PY_VERSION_HEX < 0x03000000 if (PyInt_Check(pyobj)) { vallie = new CIntValue( (cInt)PyInt_AS_LONG(pyobj) ); } else +#endif if (PyLong_Check(pyobj)) { vallie = new CIntValue( (cInt)PyLong_AsLongLong(pyobj) ); } else - if (PyString_Check(pyobj)) + if (PyUnicode_Check(pyobj)) { - vallie = new CStringValue(PyString_AsString(pyobj),""); + vallie = new CStringValue(_PyUnicode_AsString(pyobj),""); } else - if (BGE_PROXY_CHECK_TYPE(pyobj)) /* Note, dont let these get assigned to GameObject props, must check elsewhere */ + if (PyObject_TypeCheck(pyobj, &CValue::Type)) /* Note, dont let these get assigned to GameObject props, must check elsewhere */ { - if (BGE_PROXY_REF(pyobj) && (BGE_PROXY_REF(pyobj))->isA(&CValue::Type)) - { - vallie = (static_cast(BGE_PROXY_REF(pyobj)))->AddRef(); - } else { - - if(BGE_PROXY_REF(pyobj)) /* this is not a CValue */ - PyErr_Format(PyExc_TypeError, "%sgame engine python type cannot be used as a property", error_prefix); - else /* PyObjectPlus_Proxy has been removed, cant use */ - PyErr_Format(PyExc_SystemError, "%s"BGE_PROXY_ERROR_MSG, error_prefix); - } + vallie = (static_cast(BGE_PROXY_REF(pyobj)))->AddRef(); } else { /* return an error value from the caller */ @@ -656,57 +627,6 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) } -int CValue::py_delattro(PyObject *attr) -{ - ShowDeprecationWarning("del ob.attr", "del ob['attr']"); - - char *attr_str= PyString_AsString(attr); - if (RemoveProperty(attr_str)) - return 0; - - PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str); - return PY_SET_ATTR_MISSING; -} - -int CValue::py_setattro(PyObject *attr, PyObject* pyobj) -{ - ShowDeprecationWarning("ob.attr = val", "ob['attr'] = val"); - - char *attr_str= PyString_AsString(attr); - CValue* oldprop = GetProperty(attr_str); - CValue* vallie; - - /* Dissallow python to assign GameObjects, Scenes etc as values */ - if ((BGE_PROXY_CHECK_TYPE(pyobj)==0) && (vallie = ConvertPythonToValue(pyobj, "cvalue.attr = value: "))) - { - if (oldprop) - oldprop->SetValue(vallie); - else - SetProperty(attr_str, vallie); - - vallie->Release(); - } - else { - // ConvertPythonToValue sets the error message - // must return missing so KX_GameObect knows this - // attribute was not a function or bult in attribute, - // - // CValue attributes override internal attributes - // so if it exists as a CValue attribute already, - // assume your trying to set it to a differnt CValue attribute - // otherwise return PY_SET_ATTR_MISSING so children - // classes know they can set it without conflict - - if (GetProperty(attr_str)) - return PY_SET_ATTR_COERCE_FAIL; /* failed to set an existing attribute */ - else - return PY_SET_ATTR_MISSING; /* allow the KX_GameObject dict to set */ - } - - //PyObjectPlus::py_setattro(attr,value); - return PY_SET_ATTR_SUCCESS; -}; - PyObject* CValue::ConvertKeysToPython( void ) { PyObject *pylist = PyList_New( 0 ); @@ -717,7 +637,7 @@ PyObject* CValue::ConvertKeysToPython( void ) std::map::iterator it; for (it= m_pNamedPropertyArray->begin(); (it != m_pNamedPropertyArray->end()); it++) { - pystr = PyString_FromString( (*it).first ); + pystr = PyUnicode_FromString( (*it).first ); PyList_Append(pylist, pystr); Py_DECREF( pystr ); } diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 29ef19b46c9..8c9f99b335e 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -215,26 +215,18 @@ public: // Construction / Destruction #ifndef NO_EXP_PYTHON_EMBEDDING - CValue(PyTypeObject *T = &Type); + CValue(); //static PyObject* PyMake(PyObject*,PyObject*); virtual PyObject *py_repr(void) { - return PyString_FromString((const char*)GetText()); + return PyUnicode_FromString((const char*)GetText()); } - - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); virtual PyObject* ConvertValueToPython() { return NULL; } virtual CValue* ConvertPythonToValue(PyObject* pyobj, const char *error_prefix); - - - virtual int py_delattro(PyObject *attr); - virtual int py_setattro(PyObject *attr, PyObject* value); static PyObject * pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef); @@ -417,8 +409,8 @@ class CPropValue : public CValue public: #ifndef NO_EXP_PYTHON_EMBEDDING - CPropValue(PyTypeObject* T=&Type) : - CValue(T), + CPropValue() : + CValue(), #else CPropValue() : #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index caed85b9938..04d46e259d3 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -42,9 +42,8 @@ SCA_2DFilterActuator::SCA_2DFilterActuator( float float_arg, int int_arg, RAS_IRasterizer* rasterizer, - RAS_IRenderTools* rendertools, - PyTypeObject* T) - : SCA_IActuator(gameobj, T), + RAS_IRenderTools* rendertools) + : SCA_IActuator(gameobj), m_type(type), m_disableMotionBlur(flag), m_float_arg(float_arg), @@ -124,23 +123,17 @@ PyTypeObject SCA_2DFilterActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject SCA_2DFilterActuator::Parents[] = { - &SCA_2DFilterActuator::Type, - &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef SCA_2DFilterActuator::Methods[] = { /* add python functions to deal with m_msg... */ {NULL,NULL} @@ -154,18 +147,3 @@ PyAttributeDef SCA_2DFilterActuator::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RW("value", 0.0, 100.0, SCA_2DFilterActuator, m_float_arg), { NULL } //Sentinel }; - -PyObject* SCA_2DFilterActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* SCA_2DFilterActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int SCA_2DFilterActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index 13b9997a010..c357c4f3e37 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -56,23 +56,12 @@ public: float float_arg, int int_arg, RAS_IRasterizer* rasterizer, - RAS_IRenderTools* rendertools, - PyTypeObject* T=&Type - ); + RAS_IRenderTools* rendertools); void SetShaderText(const char *text); virtual ~SCA_2DFilterActuator(); virtual bool Update(); virtual CValue* GetReplica(); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - }; #endif diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index 87f7c612e7c..78e1350428e 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_ANDController::SCA_ANDController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_ANDController::SCA_ANDController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -116,19 +115,15 @@ PyTypeObject SCA_ANDController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ANDController::Parents[] = { - &SCA_ANDController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_ANDController::Methods[] = { @@ -139,12 +134,4 @@ PyAttributeDef SCA_ANDController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ANDController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_ANDController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index 9a359d57cb4..cb16d7fca01 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -39,18 +39,10 @@ class SCA_ANDController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_ANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_ANDController(SCA_IObject* gameobj); virtual ~SCA_ANDController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_ANDCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index 4dad65c5a25..bdcc923e1d9 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -40,9 +40,8 @@ SCA_ActuatorSensor::SCA_ActuatorSensor(SCA_EventManager* eventmgr, SCA_IObject* gameobj, - const STR_String& actname, - PyTypeObject* T ) - : SCA_ISensor(gameobj,eventmgr,T), + const STR_String& actname) + : SCA_ISensor(gameobj,eventmgr), m_checkactname(actname) { m_actuator = GetParent()->FindActuator(m_checkactname); @@ -138,19 +137,15 @@ PyTypeObject SCA_ActuatorSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ActuatorSensor::Parents[] = { - &SCA_ActuatorSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_ActuatorSensor::Methods[] = { @@ -166,18 +161,6 @@ PyAttributeDef SCA_ActuatorSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ActuatorSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_ActuatorSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_ActuatorSensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - int SCA_ActuatorSensor::CheckActuator(void *self, const PyAttributeDef*) { SCA_ActuatorSensor* sensor = reinterpret_cast(self); @@ -197,7 +180,7 @@ const char SCA_ActuatorSensor::GetActuator_doc[] = PyObject* SCA_ActuatorSensor::PyGetActuator() { ShowDeprecationWarning("getActuator()", "the actuator property"); - return PyString_FromString(m_checkactname); + return PyUnicode_FromString(m_checkactname); } /* 4. setActuator */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 6655e08dc70..cf8e735cad4 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -46,8 +46,7 @@ class SCA_ActuatorSensor : public SCA_ISensor public: SCA_ActuatorSensor(class SCA_EventManager* eventmgr, SCA_IObject* gameobj, - const STR_String& actname, - PyTypeObject* T=&Type ); + const STR_String& actname); virtual ~SCA_ActuatorSensor(); virtual CValue* GetReplica(); @@ -61,10 +60,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 3. setProperty */ KX_PYMETHOD_DOC_VARARGS(SCA_ActuatorSensor,SetActuator); /* 4. getProperty */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index ff02680f191..ddb54c580b8 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -48,9 +48,8 @@ /* ------------------------------------------------------------------------- */ SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr, - SCA_IObject* gameobj, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T) + SCA_IObject* gameobj) + : SCA_ISensor(gameobj,eventmgr) { //SetDrawColor(255,0,0); Init(); @@ -121,19 +120,15 @@ PyTypeObject SCA_AlwaysSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_AlwaysSensor::Parents[] = { - &SCA_AlwaysSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_AlwaysSensor::Methods[] = { @@ -144,12 +139,4 @@ PyAttributeDef SCA_AlwaysSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_AlwaysSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_AlwaysSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 0f85a641ef1..d58e05564d1 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -39,22 +39,12 @@ class SCA_AlwaysSensor : public SCA_ISensor bool m_alwaysresult; public: SCA_AlwaysSensor(class SCA_EventManager* eventmgr, - SCA_IObject* gameobj, - PyTypeObject* T =&Type); + SCA_IObject* gameobj); virtual ~SCA_AlwaysSensor(); virtual CValue* GetReplica(); virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); - - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_ALWAYSSENSOR diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index dcdae0b4e75..11c6996a0a1 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -51,9 +51,8 @@ SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr, SCA_IObject* gameobj, int delay, int duration, - bool repeat, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + bool repeat) + : SCA_ISensor(gameobj,eventmgr), m_repeat(repeat), m_delay(delay), m_duration(duration) @@ -147,19 +146,15 @@ PyTypeObject SCA_DelaySensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_DelaySensor::Parents[] = { - &SCA_DelaySensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_DelaySensor::Methods[] = { @@ -183,19 +178,6 @@ PyAttributeDef SCA_DelaySensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_DelaySensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_DelaySensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_DelaySensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - - const char SCA_DelaySensor::SetDelay_doc[] = "setDelay(delay)\n" "\t- delay: length of the initial OFF period as number of frame\n" @@ -262,7 +244,7 @@ const char SCA_DelaySensor::GetDelay_doc[] = PyObject* SCA_DelaySensor::PyGetDelay() { ShowDeprecationWarning("getDelay()", "the delay property"); - return PyInt_FromLong(m_delay); + return PyLong_FromSsize_t(m_delay); } const char SCA_DelaySensor::GetDuration_doc[] = @@ -271,7 +253,7 @@ const char SCA_DelaySensor::GetDuration_doc[] = PyObject* SCA_DelaySensor::PyGetDuration() { ShowDeprecationWarning("getDuration()", "the duration property"); - return PyInt_FromLong(m_duration); + return PyLong_FromSsize_t(m_duration); } const char SCA_DelaySensor::GetRepeat_doc[] = diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index 5ccb33f8a16..8270e8959b7 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -47,8 +47,7 @@ public: SCA_IObject* gameobj, int delay, int duration, - bool repeat, - PyTypeObject* T =&Type); + bool repeat); virtual ~SCA_DelaySensor(); virtual CValue* GetReplica(); virtual bool Evaluate(); @@ -59,10 +58,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); /* setProperty */ KX_PYMETHOD_DOC_VARARGS(SCA_DelaySensor,SetDelay); diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index 8e044b89c71..60969300474 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -46,9 +46,8 @@ /* ------------------------------------------------------------------------- */ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj, - const STR_String& exprtext, - PyTypeObject* T) - :SCA_IController(gameobj,T), + const STR_String& exprtext) + :SCA_IController(gameobj), m_exprText(exprtext), m_exprCache(NULL) { diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 6a34d7b2dff..705f6dfc415 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -42,8 +42,7 @@ class SCA_ExpressionController : public SCA_IController public: SCA_ExpressionController(SCA_IObject* gameobj, - const STR_String& exprtext, - PyTypeObject* T=&Type ); + const STR_String& exprtext); virtual ~SCA_ExpressionController(); virtual CValue* GetReplica(); @@ -54,14 +53,6 @@ public: * so that self references are removed before the controller itself is released */ virtual void Delete(); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - -// virtual PyObject* py_getattro(PyObject *attr); -// virtual PyObject* py_getattro_dict(); - }; #endif //__KX_EXPRESSIONCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index be7c2651686..0fda75590c1 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -34,9 +34,8 @@ using namespace std; -SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, - PyTypeObject* T) : - SCA_ILogicBrick(gameobj,T), +SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj) : + SCA_ILogicBrick(gameobj), m_links(0), m_posevent(false), m_negevent(false) diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 27afcbc386b..13c718ee837 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -61,8 +61,7 @@ public: * This class also inherits the default copy constructors */ - SCA_IActuator(SCA_IObject* gameobj, - PyTypeObject* T =&Type); + SCA_IActuator(SCA_IObject* gameobj); /** * UnlinkObject(...) diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index f2c3c83a2d9..7cbb728753a 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -37,10 +37,9 @@ #include #endif -SCA_IController::SCA_IController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_IController::SCA_IController(SCA_IObject* gameobj) : - SCA_ILogicBrick(gameobj,T), + SCA_ILogicBrick(gameobj), m_statemask(0), m_justActivated(false) { @@ -216,17 +215,15 @@ PyTypeObject SCA_IController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_IController::Parents[] = { - &SCA_IController::Type, - &CValue::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_ILogicBrick::Type, + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_IController::Methods[] = { @@ -248,22 +245,6 @@ PyAttributeDef SCA_IController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_IController::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ILogicBrick); -} - -PyObject* SCA_IController::py_getattro_dict() { - py_getattro_dict_up(SCA_ILogicBrick); -} - -int SCA_IController::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ILogicBrick); -} - - - PyObject* SCA_IController::PyGetActuators() { ShowDeprecationWarning("getActuators()", "the actuators property"); @@ -281,7 +262,7 @@ PyObject* SCA_IController::PyGetSensor(PyObject* value) { ShowDeprecationWarning("getSensor(string)", "the sensors[string] property"); - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)"); return NULL; @@ -305,7 +286,7 @@ PyObject* SCA_IController::PyGetActuator(PyObject* value) { ShowDeprecationWarning("getActuator(string)", "the actuators[string] property"); - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)"); return NULL; @@ -340,13 +321,13 @@ PyObject* SCA_IController::PyGetSensors() PyObject* SCA_IController::PyGetState() { ShowDeprecationWarning("getState()", "the state property"); - return PyInt_FromLong(m_statemask); + return PyLong_FromSsize_t(m_statemask); } PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_IController* self= static_cast(self_v); - return PyInt_FromLong(self->m_statemask); + return PyLong_FromSsize_t(self->m_statemask); } PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index a52c57ab3ed..523878bee26 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -47,7 +47,7 @@ protected: bool m_justActivated; bool m_bookmark; public: - SCA_IController(SCA_IObject* gameobj,PyTypeObject* T); + SCA_IController(SCA_IObject* gameobj); virtual ~SCA_IController(); virtual void Trigger(class SCA_LogicManager* logicmgr)=0; void LinkToSensor(SCA_ISensor* sensor); @@ -98,10 +98,6 @@ public: } } - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - KX_PYMETHOD_NOARGS(SCA_IController,GetSensors); KX_PYMETHOD_NOARGS(SCA_IController,GetActuators); KX_PYMETHOD_O(SCA_IController,GetSensor); diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 2dc80f54568..ccb79a2d49f 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -35,10 +35,9 @@ SCA_LogicManager* SCA_ILogicBrick::m_sCurrentLogicManager = NULL; -SCA_ILogicBrick::SCA_ILogicBrick(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_ILogicBrick::SCA_ILogicBrick(SCA_IObject* gameobj) : - CValue(T), + CValue(), m_gameobj(gameobj), m_Execute_Priority(0), m_Execute_Ueber_Priority(0), @@ -194,23 +193,17 @@ PyTypeObject SCA_ILogicBrick::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject SCA_ILogicBrick::Parents[] = { - &SCA_ILogicBrick::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef SCA_ILogicBrick::Methods[] = { // --> Deprecated {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS}, @@ -245,21 +238,6 @@ int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef) return 0; } -PyObject* SCA_ILogicBrick::py_getattro(PyObject *attr) -{ - py_getattro_up(CValue); -} - -PyObject* SCA_ILogicBrick::py_getattro_dict() { - py_getattro_dict_up(CValue); -} - -int SCA_ILogicBrick::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(CValue); -} - - PyObject* SCA_ILogicBrick::PyGetOwner() { ShowDeprecationWarning("getOwner()", "the owner property"); @@ -296,7 +274,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args) PyObject* SCA_ILogicBrick::PyGetExecutePriority() { ShowDeprecationWarning("getExecutePriority()", "the executePriority property"); - return PyInt_FromLong(m_Execute_Priority); + return PyLong_FromSsize_t(m_Execute_Priority); } @@ -326,5 +304,5 @@ bool SCA_ILogicBrick::PyArgToBool(int boolArg) PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg) { - return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE); + return PyLong_FromSsize_t(boolarg? KX_TRUE: KX_FALSE); } diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index 779e5397a6a..50679856802 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -53,7 +53,7 @@ protected: CValue* GetEvent(); public: - SCA_ILogicBrick(SCA_IObject* gameobj,PyTypeObject* T ); + SCA_ILogicBrick(SCA_IObject* gameobj); virtual ~SCA_ILogicBrick(); void SetExecutePriority(int execute_Priority); @@ -121,10 +121,6 @@ public: } virtual bool LessComparedTo(SCA_ILogicBrick* other); - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); static class SCA_LogicManager* m_sCurrentLogicManager; diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 9876f2512c0..6cd11f9e553 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -41,8 +41,11 @@ MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0); SG_QList SCA_IObject::m_activeBookmarkedControllers; -SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0), m_firstState(NULL) - +SCA_IObject::SCA_IObject(): + CValue(), + m_initState(0), + m_state(0), + m_firstState(NULL) { m_suspended = false; } @@ -218,51 +221,6 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname) } - -#if 0 -const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist) -{ - bool error = false; - m_sDummy = MT_Vector3(0,0,0); - if (pylist->ob_type == &CListValue::Type) - { - CListValue* listval = (CListValue*) pylist; - int numelem = listval->GetCount(); - if ( numelem <= 3) - { - int index; - for (index = 0;indexGetValue(index)->GetNumber(); - } - } else - { - error = true; - } - - } else - { - - // assert the list is long enough... - int numitems = PyList_Size(pylist); - if (numitems <= 3) - { - int index; - for (index=0;indexIsTriggered(this); - return PyInt_FromLong(retval); + return PyLong_FromSsize_t(retval); } /** @@ -355,7 +354,7 @@ const char SCA_ISensor::GetFrequency_doc[] = PyObject* SCA_ISensor::PyGetFrequency() { ShowDeprecationWarning("getFrequency()", "the frequency property"); - return PyInt_FromLong(m_pulse_frequency); + return PyLong_FromSsize_t(m_pulse_frequency); } /** @@ -489,19 +488,17 @@ PyTypeObject SCA_ISensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ISensor::Parents[] = { - &SCA_ISensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; + PyMethodDef SCA_ISensor::Methods[] = { //Deprecated functions -----> {"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive, @@ -548,19 +545,6 @@ PyAttributeDef SCA_ISensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ISensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ILogicBrick); -} - -PyObject* SCA_ISensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ILogicBrick); -} - -int SCA_ISensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ILogicBrick); -} PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -568,13 +552,13 @@ PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_D int retval = 0; if (SCA_PythonController::m_sCurrentController) retval = SCA_PythonController::m_sCurrentController->IsTriggered(self); - return PyInt_FromLong(retval); + return PyLong_FromSsize_t(retval); } PyObject* SCA_ISensor::pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_ISensor* self= static_cast(self_v); - return PyInt_FromLong(self->GetState()); + return PyLong_FromSsize_t(self->GetState()); } int SCA_ISensor::pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 9bbd6ed41e4..81864ab6a34 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -101,8 +101,7 @@ public: }; SCA_ISensor(SCA_IObject* gameobj, - class SCA_EventManager* eventmgr, - PyTypeObject* T );; + class SCA_EventManager* eventmgr);; ~SCA_ISensor(); virtual void ReParent(SCA_IObject* parent); @@ -173,10 +172,6 @@ public: { return !m_links; } /* Python functions: */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated functions -----> KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive); diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 336529667d7..f55921e648b 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -46,9 +46,8 @@ SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr, short int joymode, int axis, int axisf,int prec, int button, - int hat, int hatf, bool allevents, - PyTypeObject* T ) - :SCA_ISensor(gameobj,eventmgr,T), + int hat, int hatf, bool allevents) + :SCA_ISensor(gameobj,eventmgr), m_pJoystickMgr(eventmgr), m_axis(axis), m_axisf(axisf), @@ -269,23 +268,17 @@ PyTypeObject SCA_JoystickSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject SCA_JoystickSensor::Parents[] = { - &SCA_JoystickSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef SCA_JoystickSensor::Methods[] = { //Deprecated functions ------> {"getIndex", (PyCFunction) SCA_JoystickSensor::sPyGetIndex, METH_NOARGS, (PY_METHODCHAR)GetIndex_doc}, @@ -328,20 +321,6 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_JoystickSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_JoystickSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_JoystickSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* get index ---------------------------------------------------------- */ const char SCA_JoystickSensor::GetIndex_doc[] = @@ -349,7 +328,7 @@ const char SCA_JoystickSensor::GetIndex_doc[] = "\tReturns the joystick index to use.\n"; PyObject* SCA_JoystickSensor::PyGetIndex( ) { ShowDeprecationWarning("getIndex()", "the index property"); - return PyInt_FromLong(m_joyindex); + return PyLong_FromSsize_t(m_joyindex); } @@ -359,7 +338,7 @@ const char SCA_JoystickSensor::SetIndex_doc[] = "\tSets the joystick index to use.\n"; PyObject* SCA_JoystickSensor::PySetIndex( PyObject* value ) { ShowDeprecationWarning("setIndex()", "the index property"); - int index = PyInt_AsLong( value ); /* -1 on error, will raise an error in this case */ + int index = PyLong_AsSsize_t( value ); /* -1 on error, will raise an error in this case */ if (index < 0 || index >= JOYINDEX_MAX) { PyErr_SetString(PyExc_ValueError, "joystick index out of range or not an int"); return NULL; @@ -410,7 +389,7 @@ PyObject* SCA_JoystickSensor::PyGetAxisValue( ) { PyObject *list= PyList_New(axis_index); while(axis_index--) { - PyList_SET_ITEM(list, axis_index, PyInt_FromLong(joy->GetAxisPosition(axis_index))); + PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index))); } return list; @@ -423,7 +402,7 @@ const char SCA_JoystickSensor::GetThreshold_doc[] = "\tReturns the threshold of the axis.\n"; PyObject* SCA_JoystickSensor::PyGetThreshold( ) { ShowDeprecationWarning("getThreshold()", "the threshold property"); - return PyInt_FromLong(m_precision); + return PyLong_FromSsize_t(m_precision); } @@ -447,7 +426,7 @@ const char SCA_JoystickSensor::GetButton_doc[] = "\tReturns the current button this sensor is checking.\n"; PyObject* SCA_JoystickSensor::PyGetButton( ) { ShowDeprecationWarning("getButton()", "the button property"); - return PyInt_FromLong(m_button); + return PyLong_FromSsize_t(m_button); } /* set button -------------------------------------------------------- */ @@ -456,7 +435,7 @@ const char SCA_JoystickSensor::SetButton_doc[] = "\tSets the button the sensor reacts to.\n"; PyObject* SCA_JoystickSensor::PySetButton( PyObject* value ) { ShowDeprecationWarning("setButton()", "the button property"); - int button = PyInt_AsLong(value); + int button = PyLong_AsSsize_t(value); if(button==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "expected an int"); return NULL; @@ -487,7 +466,7 @@ PyObject* SCA_JoystickSensor::PyGetButtonActiveList( ) { if(joy) { for (i=0; i < joy->GetNumberOfButtons(); i++) { if (joy->aButtonPressIsPositive(i)) { - value = PyInt_FromLong(i); + value = PyLong_FromSsize_t(i); PyList_Append(ls, value); Py_DECREF(value); } @@ -549,7 +528,7 @@ PyObject* SCA_JoystickSensor::PyNumberOfAxes( ) { ShowDeprecationWarning("getNumAxes()", "the numAxis property"); SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); // when the joystick is null their is 0 exis still. dumb but scripters should use isConnected() - return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 ); } @@ -559,7 +538,7 @@ const char SCA_JoystickSensor::NumberOfButtons_doc[] = PyObject* SCA_JoystickSensor::PyNumberOfButtons( ) { ShowDeprecationWarning("getNumButtons()", "the numButtons property"); SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 ); } @@ -569,7 +548,7 @@ const char SCA_JoystickSensor::NumberOfHats_doc[] = PyObject* SCA_JoystickSensor::PyNumberOfHats( ) { ShowDeprecationWarning("getNumHats()", "the numHats property"); SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 ); } const char SCA_JoystickSensor::Connected_doc[] = @@ -591,7 +570,7 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYAT PyObject *list= PyList_New(axis_index); while(axis_index--) { - PyList_SET_ITEM(list, axis_index, PyInt_FromLong(joy->GetAxisPosition(axis_index))); + PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index))); } return list; @@ -607,7 +586,7 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYAT return NULL; } - return PyInt_FromLong(joy->GetAxisPosition(self->m_axis-1)); + return PyLong_FromSsize_t(joy->GetAxisPosition(self->m_axis-1)); } PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -619,7 +598,7 @@ PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATT PyObject *list= PyList_New(hat_index); while(hat_index--) { - PyList_SET_ITEM(list, hat_index, PyInt_FromLong(joy->GetHat(hat_index))); + PyList_SET_ITEM(list, hat_index, PyLong_FromSsize_t(joy->GetHat(hat_index))); } return list; @@ -630,28 +609,28 @@ PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATT SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong(joy->GetHat(self->m_hat-1)); + return PyLong_FromSsize_t(joy->GetHat(self->m_hat-1)); } PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 ); } PyObject* SCA_JoystickSensor::pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 ); } PyObject* SCA_JoystickSensor::pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 ); } PyObject* SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index e6a1d2eef32..32f8ce567d2 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -106,8 +106,7 @@ public: short int joymode, int axis, int axisf,int prec, int button, - int hat, int hatf, bool allevents, - PyTypeObject* T=&Type ); + int hat, int hatf, bool allevents); virtual ~SCA_JoystickSensor(); virtual CValue* GetReplica(); @@ -123,10 +122,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* Joystick Index */ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetIndex); KX_PYMETHOD_DOC_O(SCA_JoystickSensor,SetIndex); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index f8ee8ed8b41..999e34dfa36 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -48,9 +48,8 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr, bool bAllKeys, const STR_String& targetProp, const STR_String& toggleProp, - SCA_IObject* gameobj, - PyTypeObject* T ) - :SCA_ISensor(gameobj,keybdmgr,T), + SCA_IObject* gameobj) + :SCA_ISensor(gameobj,keybdmgr), m_pKeyboardMgr(keybdmgr), m_hotkey(hotkey), m_qual(qual), @@ -418,7 +417,7 @@ const char SCA_KeyboardSensor::GetKey_doc[] = PyObject* SCA_KeyboardSensor::PyGetKey() { ShowDeprecationWarning("getKey()", "the key property"); - return PyInt_FromLong(m_hotkey); + return PyLong_FromSsize_t(m_hotkey); } /** 2. SetKey: change the key to look at */ @@ -450,7 +449,7 @@ const char SCA_KeyboardSensor::GetHold1_doc[] = PyObject* SCA_KeyboardSensor::PyGetHold1() { ShowDeprecationWarning("getHold1()", "the hold1 property"); - return PyInt_FromLong(m_qual); + return PyLong_FromSsize_t(m_qual); } /** 4. SetHold1: change the first bucky bit */ @@ -482,7 +481,7 @@ const char SCA_KeyboardSensor::GetHold2_doc[] = PyObject* SCA_KeyboardSensor::PyGetHold2() { ShowDeprecationWarning("getHold2()", "the hold2 property"); - return PyInt_FromLong(m_qual2); + return PyLong_FromSsize_t(m_qual2); } /** 6. SetHold2: change the second bucky bit */ @@ -532,8 +531,8 @@ PyObject* SCA_KeyboardSensor::PyGetPressedKeys() || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)) { PyObject* keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i)); + PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status)); PyList_SET_ITEM(resultlist,index,keypair); index++; @@ -572,8 +571,8 @@ PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys() || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)) { PyObject* keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i)); + PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status)); PyList_SET_ITEM(resultlist,index,keypair); index++; @@ -592,12 +591,12 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, "getKeyStatus(keycode)\n" "\tGet the given key's status (KX_NO_INPUTSTATUS, KX_JUSTACTIVATED, KX_ACTIVE or KX_JUSTRELEASED).\n") { - if (!PyInt_Check(value)) { + if (!PyLong_Check(value)) { PyErr_SetString(PyExc_ValueError, "sensor.getKeyStatus(int): Keyboard Sensor, expected an int"); return NULL; } - int keycode = PyInt_AsLong(value); + int keycode = PyLong_AsSsize_t(value); if ((keycode < SCA_IInputDevice::KX_BEGINKEY) || (keycode > SCA_IInputDevice::KX_ENDKEY)){ @@ -607,7 +606,7 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice(); const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) keycode); - return PyInt_FromLong(inevent.m_status); + return PyLong_FromSsize_t(inevent.m_status); } /* ------------------------------------------------------------------------- */ @@ -631,19 +630,15 @@ PyTypeObject SCA_KeyboardSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_KeyboardSensor::Parents[] = { - &SCA_KeyboardSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_KeyboardSensor::Methods[] = { @@ -672,20 +667,6 @@ PyAttributeDef SCA_KeyboardSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_KeyboardSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_KeyboardSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_KeyboardSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -701,8 +682,8 @@ PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBU if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS) { PyObject* keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i)); + PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status)); PyList_Append(resultlist,keypair); } } diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 033225cd9be..3185b386d41 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -94,8 +94,7 @@ public: bool bAllKeys, const STR_String& targetProp, const STR_String& toggleProp, - SCA_IObject* gameobj, - PyTypeObject* T=&Type ); + SCA_IObject* gameobj); virtual ~SCA_KeyboardSensor(); virtual CValue* GetReplica(); virtual void Init(); @@ -110,10 +109,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - //Deprecated functions -----> /** 1. GetKey : check which key this sensor looks at */ KX_PYMETHOD_DOC_NOARGS(SCA_KeyboardSensor,GetKey); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index 83271288154..b782c6dfb93 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -307,6 +307,7 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I controller->Activate(m_triggeredControllerSet); // so that the controller knows which sensor has activited it // only needed for python controller + // Note that this is safe even if the controller is subclassed. if (controller->GetType() == &SCA_PythonController::Type) { SCA_PythonController* pythonController = (SCA_PythonController*)controller; diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index c5e1c3c0441..49fa19dce38 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -49,9 +49,8 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, int startx,int starty, short int mousemode, - SCA_IObject* gameobj, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + SCA_IObject* gameobj) + : SCA_ISensor(gameobj,eventmgr), m_pMouseMgr(eventmgr), m_x(startx), m_y(starty) @@ -254,7 +253,7 @@ const char SCA_MouseSensor::GetXPosition_doc[] = "\tpixels\n"; PyObject* SCA_MouseSensor::PyGetXPosition() { ShowDeprecationWarning("getXPosition()", "the position property"); - return PyInt_FromLong(m_x); + return PyLong_FromSsize_t(m_x); } /* get y position ---------------------------------------------------------- */ @@ -265,7 +264,7 @@ const char SCA_MouseSensor::GetYPosition_doc[] = "\tpixels\n"; PyObject* SCA_MouseSensor::PyGetYPosition() { ShowDeprecationWarning("getYPosition()", "the position property"); - return PyInt_FromLong(m_y); + return PyLong_FromSsize_t(m_y); } //<----- Deprecated @@ -273,9 +272,9 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, "getButtonStatus(button)\n" "\tGet the given button's status (KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED).\n") { - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - int button = PyInt_AsLong(value); + int button = PyLong_AsSsize_t(value); if ((button < SCA_IInputDevice::KX_LEFTMOUSE) || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){ @@ -285,7 +284,7 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice(); const SCA_InputEvent& event = mousedev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) button); - return PyInt_FromLong(event.m_status); + return PyLong_FromSsize_t(event.m_status); } Py_RETURN_NONE; @@ -312,19 +311,15 @@ PyTypeObject SCA_MouseSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_MouseSensor::Parents[] = { - &SCA_MouseSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_MouseSensor::Methods[] = { @@ -342,18 +337,4 @@ PyAttributeDef SCA_MouseSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_MouseSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_MouseSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_MouseSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index 6d6302b514a..47f0378bf69 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -92,8 +92,7 @@ class SCA_MouseSensor : public SCA_ISensor SCA_MouseSensor(class SCA_MouseManager* keybdmgr, int startx,int starty, short int mousemode, - SCA_IObject* gameobj, - PyTypeObject* T=&Type ); + SCA_IObject* gameobj); virtual ~SCA_MouseSensor(); virtual CValue* GetReplica(); @@ -109,10 +108,6 @@ class SCA_MouseSensor : public SCA_ISensor /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - //Deprecated functions -----> /* read x-coordinate */ KX_PYMETHOD_DOC_NOARGS(SCA_MouseSensor,GetXPosition); diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index d27aea5e6f7..c00e5d6e617 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_NANDController::SCA_NANDController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_NANDController::SCA_NANDController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -116,19 +115,15 @@ PyTypeObject SCA_NANDController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_NANDController::Parents[] = { - &SCA_NANDController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_NANDController::Methods[] = { @@ -139,12 +134,4 @@ PyAttributeDef SCA_NANDController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_NANDController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_NANDController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 0ae0ff19745..36a145e5f2b 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -39,7 +39,7 @@ class SCA_NANDController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_NANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_NANDController(SCA_IObject* gameobj); virtual ~SCA_NANDController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); @@ -47,10 +47,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_NANDCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index 6c9141636b2..9762d44fd5d 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_NORController::SCA_NORController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_NORController::SCA_NORController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -116,19 +115,15 @@ PyTypeObject SCA_NORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_NORController::Parents[] = { - &SCA_NORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_NORController::Methods[] = { @@ -139,12 +134,4 @@ PyAttributeDef SCA_NORController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_NORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_NORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index 06cbb70a489..b96232375d6 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -39,18 +39,10 @@ class SCA_NORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_NORController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_NORController(SCA_IObject* gameobj); virtual ~SCA_NORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_NORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 42c0a67d657..a526dd8353c 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -42,9 +42,8 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_ORController::SCA_ORController(SCA_IObject* gameobj, - PyTypeObject* T) - :SCA_IController(gameobj, T) +SCA_ORController::SCA_ORController(SCA_IObject* gameobj) + :SCA_IController(gameobj) { } @@ -110,19 +109,15 @@ PyTypeObject SCA_ORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ORController::Parents[] = { - &SCA_ORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_ORController::Methods[] = { @@ -133,13 +128,4 @@ PyAttributeDef SCA_ORController::Attributes[] = { { NULL } //Sentinel }; - -PyObject* SCA_ORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_ORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index 66f772c739e..09d31a85190 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -39,18 +39,11 @@ class SCA_ORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_ORController(SCA_IObject* gameobj, PyTypeObject* T=&Type); + SCA_ORController(SCA_IObject* gameobj); virtual ~SCA_ORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); }; #endif //__KX_ORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index 4faa4b55d4a..215e30eceaf 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -42,8 +42,8 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T ) - : SCA_IActuator(gameobj,T), +SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype) + : SCA_IActuator(gameobj), m_type(acttype), m_propname(propname), m_exprtxt(expr), @@ -244,19 +244,15 @@ PyTypeObject SCA_PropertyActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_PropertyActuator::Parents[] = { - &SCA_PropertyActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_PropertyActuator::Methods[] = { @@ -276,18 +272,6 @@ PyAttributeDef SCA_PropertyActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_PropertyActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* SCA_PropertyActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int SCA_PropertyActuator::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_IActuator); -} - /* 1. setProperty */ const char SCA_PropertyActuator::SetProperty_doc[] = "setProperty(name)\n" @@ -322,7 +306,7 @@ const char SCA_PropertyActuator::GetProperty_doc[] = PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* args, PyObject* kwds) { ShowDeprecationWarning("getProperty()", "the 'propName' property"); - return PyString_FromString(m_propname); + return PyUnicode_FromString(m_propname); } /* 3. setValue */ @@ -352,7 +336,7 @@ const char SCA_PropertyActuator::GetValue_doc[] = PyObject* SCA_PropertyActuator::PyGetValue(PyObject* args, PyObject* kwds) { ShowDeprecationWarning("getValue()", "the value property"); - return PyString_FromString(m_exprtxt); + return PyUnicode_FromString(m_exprtxt); } /* eof */ diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index a8df08dfc6e..8fb2e7a7bc5 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -64,9 +64,7 @@ public: SCA_IObject* sourceObj, const STR_String& propname, const STR_String& expr, - int acttype, - PyTypeObject* T=&Type - ); + int acttype); ~SCA_PropertyActuator(); @@ -86,10 +84,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // python wrapped methods KX_PYMETHOD_DOC(SCA_PropertyActuator,SetProperty); KX_PYMETHOD_DOC(SCA_PropertyActuator,GetProperty); diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index 3b343af3cba..6d2e1a0aca5 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -48,9 +48,8 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr, const STR_String& propname, const STR_String& propval, const STR_String& propmaxval, - KX_PROPSENSOR_TYPE checktype, - PyTypeObject* T ) - : SCA_ISensor(gameobj,eventmgr,T), + KX_PROPSENSOR_TYPE checktype) + : SCA_ISensor(gameobj,eventmgr), m_checktype(checktype), m_checkpropval(propval), m_checkpropmaxval(propmaxval), @@ -319,19 +318,15 @@ PyTypeObject SCA_PropertySensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_PropertySensor::Parents[] = { - &SCA_PropertySensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_PropertySensor::Methods[] = { @@ -353,19 +348,6 @@ PyAttributeDef SCA_PropertySensor::Attributes[] = { { NULL } //Sentinel }; - -PyObject* SCA_PropertySensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_PropertySensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_PropertySensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - /* 1. getType */ const char SCA_PropertySensor::GetType_doc[] = "getType()\n" @@ -373,7 +355,7 @@ const char SCA_PropertySensor::GetType_doc[] = PyObject* SCA_PropertySensor::PyGetType() { ShowDeprecationWarning("getType()", "the mode property"); - return PyInt_FromLong(m_checktype); + return PyLong_FromSsize_t(m_checktype); } /* 2. setType */ @@ -407,7 +389,7 @@ const char SCA_PropertySensor::GetProperty_doc[] = PyObject* SCA_PropertySensor::PyGetProperty() { ShowDeprecationWarning("getProperty()", "the 'propName' property"); - return PyString_FromString(m_checkpropname); + return PyUnicode_FromString(m_checkpropname); } /* 4. setProperty */ @@ -444,7 +426,7 @@ const char SCA_PropertySensor::GetValue_doc[] = PyObject* SCA_PropertySensor::PyGetValue() { ShowDeprecationWarning("getValue()", "the value property"); - return PyString_FromString(m_checkpropval); + return PyUnicode_FromString(m_checkpropval); } /* 6. setValue */ diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index 538ecd65949..3513fcdf5ae 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -67,8 +67,7 @@ public: const STR_String& propname, const STR_String& propval, const STR_String& propmaxval, - KX_PROPSENSOR_TYPE checktype, - PyTypeObject* T=&Type ); + KX_PROPSENSOR_TYPE checktype); /** * For property sensor, it is used to release the pre-calculated expression @@ -89,10 +88,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. getType */ KX_PYMETHOD_DOC_NOARGS(SCA_PropertySensor,GetType); /* 2. setType */ diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 80e4f54c9c5..ffd95f00699 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -47,10 +47,8 @@ SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL; -SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, - int mode, - PyTypeObject* T) - : SCA_IController(gameobj, T), +SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, int mode) + : SCA_IController(gameobj), m_bytecode(NULL), m_function(NULL), m_function_argc(0), @@ -150,7 +148,7 @@ void SCA_PythonController::SetDictionary(PyObject* pythondictionary) /* Without __file__ set the sys.argv[0] is used for the filename * which ends up with lines from the blender binary being printed in the console */ - PyDict_SetItemString(m_pythondictionary, "__file__", PyString_FromString(m_scriptName.Ptr())); + PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_FromString(m_scriptName.Ptr())); } @@ -180,16 +178,16 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) std::vector lacts = m_sCurrentController->GetLinkedActuators(); std::vector::iterator it; - if (PyString_Check(value)) { + if (PyUnicode_Check(value)) { /* get the actuator from the name */ - char *name= PyString_AsString(value); + char *name= _PyUnicode_AsString(value); for(it = lacts.begin(); it!= lacts.end(); ++it) { if( name == (*it)->GetName() ) { return *it; } } } - else if (BGE_PROXY_CHECK_TYPE(value)) { + else if (PyObject_TypeCheck(value, &SCA_IActuator::Type)) { PyObjectPlus *value_plus= BGE_PROXY_REF(value); for(it = lacts.begin(); it!= lacts.end(); ++it) { if( static_cast(value_plus) == (*it) ) { @@ -200,7 +198,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) /* set the exception */ PyObject *value_str = PyObject_Repr(value); /* new ref */ - PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", PyString_AsString(value_str)); + PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", _PyUnicode_AsString(value_str)); Py_DECREF(value_str); return false; @@ -245,19 +243,17 @@ PyTypeObject SCA_PythonController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IController::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject SCA_PythonController::Parents[] = { - &SCA_PythonController::Type, - &SCA_IController::Type, - &CValue::Type, - NULL -}; PyMethodDef SCA_PythonController::Methods[] = { {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O}, {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O}, @@ -490,22 +486,6 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) m_sCurrentController = NULL; } - - -PyObject* SCA_PythonController::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IController); -} - -PyObject* SCA_PythonController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - -int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IController); -} - PyObject* SCA_PythonController::PyActivate(PyObject *value) { if(m_sCurrentController != this) { @@ -540,13 +520,13 @@ PyObject* SCA_PythonController::PyDeActivate(PyObject *value) PyObject* SCA_PythonController::PyGetScript() { ShowDeprecationWarning("getScript()", "the script property"); - return PyString_FromString(m_scriptText); + return PyUnicode_FromString(m_scriptText); } /* 2. setScript */ PyObject* SCA_PythonController::PySetScript(PyObject* value) { - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); ShowDeprecationWarning("setScript()", "the script property"); @@ -565,15 +545,20 @@ PyObject* SCA_PythonController::PySetScript(PyObject* value) PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { + //SCA_PythonController* self= static_cast(static_cast(static_cast(static_cast(static_cast(self_v))))); + // static_cast(dynamic_cast(obj)) - static_cast(obj) + SCA_PythonController* self= static_cast(self_v); - return PyString_FromString(self->m_scriptText); + return PyUnicode_FromString(self->m_scriptText); } + + int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { SCA_PythonController* self= static_cast(self_v); - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text"); diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 0c2af79c3a3..9311b3f355e 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -72,7 +72,7 @@ class SCA_PythonController : public SCA_IController //virtual CValue* AddRef(); //virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap) - SCA_PythonController(SCA_IObject* gameobj, int mode, PyTypeObject* T = &Type); + SCA_PythonController(SCA_IObject* gameobj, int mode); virtual ~SCA_PythonController(); virtual CValue* GetReplica(); @@ -96,10 +96,6 @@ class SCA_PythonController : public SCA_IController static PyObject* sPyAddActiveActuator(PyObject* self, PyObject* args); static SCA_IActuator* LinkedActuatorFromPy(PyObject *value); - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); KX_PYMETHOD_O(SCA_PythonController,Activate); diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index a722590dd10..e903d10f9a5 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -50,9 +50,8 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj, SCA_RandomActuator::KX_RANDOMACT_MODE mode, float para1, float para2, - const STR_String &propName, - PyTypeObject* T) - : SCA_IActuator(gameobj, T), + const STR_String &propName) + : SCA_IActuator(gameobj), m_propname(propName), m_parameter1(para1), m_parameter2(para2), @@ -332,19 +331,15 @@ PyTypeObject SCA_RandomActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_RandomActuator::Parents[] = { - &SCA_RandomActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_RandomActuator::Methods[] = { @@ -384,14 +379,14 @@ PyAttributeDef SCA_RandomActuator::Attributes[] = { PyObject* SCA_RandomActuator::pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { SCA_RandomActuator* act = static_cast(self); - return PyInt_FromLong(act->m_base->GetSeed()); + return PyLong_FromSsize_t(act->m_base->GetSeed()); } int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { SCA_RandomActuator* act = static_cast(self); - if (PyInt_Check(value)) { - int ival = PyInt_AsLong(value); + if (PyLong_Check(value)) { + int ival = PyLong_AsSsize_t(value); act->m_base->SetSeed(ival); return PY_SET_ATTR_SUCCESS; } else { @@ -400,19 +395,6 @@ int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_ } } -PyObject* SCA_RandomActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* SCA_RandomActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int SCA_RandomActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - /* 1. setSeed */ const char SCA_RandomActuator::SetSeed_doc[] = "setSeed(seed)\n" @@ -439,7 +421,7 @@ const char SCA_RandomActuator::GetSeed_doc[] = PyObject* SCA_RandomActuator::PyGetSeed() { ShowDeprecationWarning("getSeed()", "the seed property"); - return PyInt_FromLong(m_base->GetSeed()); + return PyLong_FromSsize_t(m_base->GetSeed()); } /* 4. getPara1 */ @@ -473,7 +455,7 @@ const char SCA_RandomActuator::GetDistribution_doc[] = PyObject* SCA_RandomActuator::PyGetDistribution() { ShowDeprecationWarning("getDistribution()", "the distribution property"); - return PyInt_FromLong(m_distribution); + return PyLong_FromSsize_t(m_distribution); } /* 9. setProperty */ @@ -508,7 +490,7 @@ const char SCA_RandomActuator::GetProperty_doc[] = PyObject* SCA_RandomActuator::PyGetProperty() { ShowDeprecationWarning("getProperty()", "the 'propName' property"); - return PyString_FromString(m_propname); + return PyUnicode_FromString(m_propname); } /* 11. setBoolConst */ diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index 59863589b60..c7d3fe21217 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -85,8 +85,7 @@ class SCA_RandomActuator : public SCA_IActuator KX_RANDOMACT_MODE mode, float para1, float para2, - const STR_String &propName, - PyTypeObject* T=&Type); + const STR_String &propName); virtual ~SCA_RandomActuator(); virtual bool Update(); @@ -97,10 +96,6 @@ class SCA_RandomActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - static PyObject* pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index d5cbeef01ae..e036a77707e 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -46,9 +46,8 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, SCA_IObject* gameobj, - int startseed, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T) + int startseed) + : SCA_ISensor(gameobj,eventmgr) { m_basegenerator = new SCA_RandomNumberGenerator(startseed); Init(); @@ -147,19 +146,15 @@ PyTypeObject SCA_RandomSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_RandomSensor::Parents[] = { - &SCA_RandomSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_RandomSensor::Methods[] = { @@ -177,19 +172,6 @@ PyAttributeDef SCA_RandomSensor::Attributes[] = { {NULL} //Sentinel }; -PyObject* SCA_RandomSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_RandomSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_RandomSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* 1. setSeed */ const char SCA_RandomSensor::SetSeed_doc[] = "setSeed(seed)\n" @@ -216,7 +198,7 @@ const char SCA_RandomSensor::GetSeed_doc[] = "\tequal series.\n"; PyObject* SCA_RandomSensor::PyGetSeed() { ShowDeprecationWarning("getSeed()", "the seed property"); - return PyInt_FromLong(m_basegenerator->GetSeed()); + return PyLong_FromSsize_t(m_basegenerator->GetSeed()); } /* 3. getLastDraw */ @@ -225,24 +207,24 @@ const char SCA_RandomSensor::GetLastDraw_doc[] = "\tReturn the last value that was drawn.\n"; PyObject* SCA_RandomSensor::PyGetLastDraw() { ShowDeprecationWarning("getLastDraw()", "the lastDraw property"); - return PyInt_FromLong(m_lastdraw); + return PyLong_FromSsize_t(m_lastdraw); } PyObject* SCA_RandomSensor::pyattr_get_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_RandomSensor* self= static_cast(self_v); - return PyInt_FromLong(self->m_basegenerator->GetSeed()); + return PyLong_FromSsize_t(self->m_basegenerator->GetSeed()); } int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { SCA_RandomSensor* self= static_cast(self_v); - if (!PyInt_Check(value)) { + if (!PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "sensor.seed = int: Random Sensor, expected an integer"); return PY_SET_ATTR_FAIL; } - self->m_basegenerator->SetSeed(PyInt_AsLong(value)); + self->m_basegenerator->SetSeed(PyLong_AsSsize_t(value)); return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index b2bf2440966..5e66c36cccf 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -48,8 +48,7 @@ class SCA_RandomSensor : public SCA_ISensor public: SCA_RandomSensor(class SCA_EventManager* rndmgr, SCA_IObject* gameobj, - int startseed, - PyTypeObject* T=&Type); + int startseed); virtual ~SCA_RandomSensor(); virtual CValue* GetReplica(); virtual void ProcessReplica(); @@ -61,10 +60,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. setSeed */ KX_PYMETHOD_DOC_VARARGS(SCA_RandomSensor,SetSeed); /* 2. getSeed */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index aee8e26c21a..527adc70cc6 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_XNORController::SCA_XNORController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_XNORController::SCA_XNORController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -120,19 +119,15 @@ PyTypeObject SCA_XNORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_XNORController::Parents[] = { - &SCA_XNORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_XNORController::Methods[] = { @@ -143,12 +138,4 @@ PyAttributeDef SCA_XNORController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_XNORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_XNORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index 4aad5763cb0..18e77fae665 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -39,7 +39,7 @@ class SCA_XNORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_XNORController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_XNORController(SCA_IObject* gameobj); virtual ~SCA_XNORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); @@ -48,9 +48,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_XNORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 5afb3a750f5..c0916224fe6 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_XORController::SCA_XORController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_XORController::SCA_XORController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -120,19 +119,15 @@ PyTypeObject SCA_XORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_XORController::Parents[] = { - &SCA_XORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_XORController::Methods[] = { @@ -143,12 +138,4 @@ PyAttributeDef SCA_XORController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_XORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_XORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index feb9f2ed07c..2607a533661 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -39,18 +39,10 @@ class SCA_XORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_XORController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_XORController(SCA_IObject* gameobj); virtual ~SCA_XORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_XORCONTROLLER diff --git a/source/gameengine/GamePlayer/common/Makefile b/source/gameengine/GamePlayer/common/Makefile index 84b4a4170a9..4a952856739 100644 --- a/source/gameengine/GamePlayer/common/Makefile +++ b/source/gameengine/GamePlayer/common/Makefile @@ -50,8 +50,6 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_FUZZICS)/include CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SUMO)/include -CPPFLAGS += -I$(NAN_SOLID)/include CPPFLAGS += -I$(NAN_PNG)/include CPPFLAGS += -I$(NAN_ZLIB)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) @@ -69,7 +67,6 @@ CPPFLAGS += -I../../../gameengine/Network/LoopBackNetwork CPPFLAGS += -I../../../gameengine/Rasterizer CPPFLAGS += -I../../../gameengine/SceneGraph CPPFLAGS += -I../../../gameengine/Rasterizer/RAS_OpenGLRasterizer -CPPFLAGS += -I../../../gameengine/Physics/Sumo CPPFLAGS += -I../../../gameengine/Physics/common ############################### diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index e96b2c5400b..f899385c841 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -59,11 +59,6 @@ incs = ['.', # 'unix/GPU_System.cpp'] # gp_common_env.Append ( CPPPATH = ['unix']) -if env['WITH_BF_SOLID']: - incs.append('#source/gameengine/Physics/Sumo') - incs.append('#source/gameengine/Physics/Sumo/Fuzzics/include') - incs += Split(env['BF_SOLID_INC']) - incs += Split(env['BF_PYTHON_INC']) incs += Split(env['BF_PNG_INC']) incs += Split(env['BF_ZLIB_INC']) diff --git a/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp b/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp index a5dec02c753..0ef087efbfe 100644 --- a/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp +++ b/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp @@ -44,9 +44,6 @@ #include "NG_LoopBackNetworkDeviceInterface.h" #include "SND_DeviceManager.h" #include "KX_BlenderSceneConverter.h" -#ifdef USE_SUMO_SOLID - #include "SM_Scene.h" -#endif #include "KX_KetsjiEngine.h" #include "GPC_RenderTools.h" diff --git a/source/gameengine/GamePlayer/common/unix/Makefile b/source/gameengine/GamePlayer/common/unix/Makefile index 90342c7b735..08c52ddc904 100644 --- a/source/gameengine/GamePlayer/common/unix/Makefile +++ b/source/gameengine/GamePlayer/common/unix/Makefile @@ -57,10 +57,8 @@ CPPFLAGS += -I../../../../gameengine/Rasterizer/RAS_OpenGLRasterizer CPPFLAGS += -I../../../../gameengine/SceneGraph CPPFLAGS += -I$(NAN_FUZZICS)/include -CPPFLAGS += -I$(NAN_SUMO)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include CPPFLAGS += -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SOLID)/include # Blender stuff CPPFLAGS += -I../../../../blender/blenkernel diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 390b6f5e089..19234cb663c 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -41,10 +41,6 @@ incs = ['.', '#source/blender/gpu', '#extern/glew/include'] -if env['WITH_BF_SOLID']: - incs.append(['#source/gameengine/Physics/Sumo', '#source/gameengine/Physics/Sumo/Fuzzics/include']) - incs += Split(env['BF_SOLID_INC']) - incs += Split(env['BF_PYTHON_INC']) cxxflags = [] diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index c5c517c8a65..8bde5dd3a51 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -113,8 +113,8 @@ bool BL_Shader::Ok()const return (mShader !=0 && mOk && mUse); } -BL_Shader::BL_Shader(PyTypeObject *T) -: PyObjectPlus(T), +BL_Shader::BL_Shader() +: PyObjectPlus(), mShader(0), mPass(1), mOk(0), @@ -728,17 +728,6 @@ void BL_Shader::SetUniform(int uniform, const int* val, int len) } } - -PyObject* BL_Shader::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* BL_Shader::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - - PyMethodDef BL_Shader::Methods[] = { // creation @@ -792,21 +781,17 @@ PyTypeObject BL_Shader::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject BL_Shader::Parents[] = { - &BL_Shader::Type, - &PyObjectPlus::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" ) { if(mShader !=0 && mOk ) @@ -848,17 +833,17 @@ KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" ) { - return PyInt_FromLong( ( mShader !=0 && mOk ) ); + return PyLong_FromSsize_t( ( mShader !=0 && mOk ) ); } KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" ) { - return PyString_FromString(vertProg?vertProg:""); + return PyUnicode_FromString(vertProg?vertProg:""); } KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" ) { - return PyString_FromString(fragProg?fragProg:""); + return PyUnicode_FromString(fragProg?fragProg:""); } KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") @@ -1223,7 +1208,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( uniform_name, (list2 for(unsigned int i=0; (i // 1. SetToPropName PyObject* KX_NetworkMessageActuator::PySetToPropName( @@ -240,4 +223,4 @@ PyObject* KX_NetworkMessageActuator::PySetBody( Py_RETURN_NONE; } -// <----- Deprecated \ No newline at end of file +// <----- Deprecated diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index cf92fd46fe0..b4f55f2a466 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -50,8 +50,7 @@ public: const STR_String &toPropName, const STR_String &subject, int bodyType, - const STR_String &body, - PyTypeObject* T=&Type); + const STR_String &body); virtual ~KX_NetworkMessageActuator(); virtual bool Update(); @@ -61,10 +60,6 @@ public: /* Python interface ------------------------------------------- */ /* ------------------------------------------------------------ */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName); KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject); diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index 8ddcd87b66f..78dda1f6db7 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -50,10 +50,9 @@ KX_NetworkMessageSensor::KX_NetworkMessageSensor( class KX_NetworkEventManager* eventmgr, // our eventmanager class NG_NetworkScene *NetworkScene, // our scene SCA_IObject* gameobj, // the sensor controlling object - const STR_String &subject, - PyTypeObject* T + const STR_String &subject ) : - SCA_ISensor(gameobj,eventmgr,T), + SCA_ISensor(gameobj,eventmgr), m_Networkeventmgr(eventmgr), m_NetworkScene(NetworkScene), m_subject(subject), @@ -182,19 +181,15 @@ PyTypeObject KX_NetworkMessageSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_NetworkMessageSensor::Parents[] = { - &KX_NetworkMessageSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_NetworkMessageSensor::Methods[] = { @@ -226,18 +221,6 @@ PyAttributeDef KX_NetworkMessageSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_NetworkMessageSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* KX_NetworkMessageSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int KX_NetworkMessageSensor::py_setattro(PyObject *attr, PyObject *value) { - return SCA_ISensor::py_setattro(attr, value); -} - PyObject* KX_NetworkMessageSensor::pyattr_get_bodies(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_NetworkMessageSensor *self = static_cast(self_v); @@ -267,7 +250,7 @@ const char KX_NetworkMessageSensor::SetSubjectFilterText_doc[] = PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText(PyObject* value) { ShowDeprecationWarning("setSubjectFilterText()", "subject"); - char* Subject = PyString_AsString(value); + char* Subject = _PyUnicode_AsString(value); if (Subject==NULL) { PyErr_SetString(PyExc_TypeError, "sensor.tsetSubjectFilterText(string): KX_NetworkMessageSensor, expected a string message"); return NULL; @@ -285,7 +268,7 @@ const char KX_NetworkMessageSensor::GetFrameMessageCount_doc[] = PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount() { ShowDeprecationWarning("getFrameMessageCount()", "frameMessageCount"); - return PyInt_FromLong(long(m_frame_message_count)); + return PyLong_FromSsize_t(long(m_frame_message_count)); } // 3. Get the message bodies @@ -311,7 +294,7 @@ const char KX_NetworkMessageSensor::GetSubject_doc[] = PyObject* KX_NetworkMessageSensor::PyGetSubject() { ShowDeprecationWarning("getSubject()", "subject"); - return PyString_FromString(m_subject ? m_subject : ""); + return PyUnicode_FromString(m_subject ? m_subject : ""); } // 5. Get the message subjects @@ -328,4 +311,4 @@ PyObject* KX_NetworkMessageSensor::PyGetSubjects() return (new CListValue())->NewProxy(true); } } -// <----- Deprecated \ No newline at end of file +// <----- Deprecated diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 53183f33826..ade87697303 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -57,8 +57,7 @@ public: KX_NetworkEventManager* eventmgr, // our eventmanager NG_NetworkScene *NetworkScene, // our scene SCA_IObject* gameobj, // the sensor controlling object - const STR_String &subject, - PyTypeObject* T=&Type + const STR_String &subject ); virtual ~KX_NetworkMessageSensor(); @@ -72,10 +71,6 @@ public: /* Python interface -------------------------------------------- */ /* ------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD_DOC_O(KX_NetworkMessageSensor, SetSubjectFilterText); KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetFrameMessageCount); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 30057fc039d..314becc702d 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -42,10 +42,8 @@ BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; //static PyObject *gTextureDict = 0; -KX_BlenderMaterial::KX_BlenderMaterial( - PyTypeObject *T - ) -: PyObjectPlus(T), +KX_BlenderMaterial::KX_BlenderMaterial() +: PyObjectPlus(), RAS_IPolyMaterial(), mMaterial(NULL), mShader(0), @@ -813,36 +811,17 @@ PyTypeObject KX_BlenderMaterial::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject KX_BlenderMaterial::Parents[] = { - &KX_BlenderMaterial::Type, - &PyObjectPlus::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - -PyObject* KX_BlenderMaterial::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_BlenderMaterial::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_BlenderMaterial::py_setattro(PyObject *attr, PyObject *pyvalue) -{ - return PyObjectPlus::py_setattro(attr, pyvalue); -} - - KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") { if( !GLEW_ARB_fragment_shader) { @@ -912,7 +891,7 @@ void KX_BlenderMaterial::SetBlenderGLSLShader(int layer) KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") { - return PyInt_FromLong( GetMaterialIndex() ); + return PyLong_FromSsize_t( GetMaterialIndex() ); } KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" ) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index b29f2df98db..1f5edc1d7d1 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -23,9 +23,7 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial Py_Header; public: // -------------------------------- - KX_BlenderMaterial( - PyTypeObject* T=&Type - ); + KX_BlenderMaterial(); void Initialize( class KX_Scene* scene, BL_Material* mat, @@ -83,10 +81,7 @@ public: ); // -------------------------------- - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); - virtual PyObject* py_repr(void) { return PyString_FromString(mMaterial->matname.ReadPtr()); } + virtual PyObject* py_repr(void) { return PyUnicode_FromString(mMaterial->matname.ReadPtr()); } KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader ); KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex ); diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index 8511526fd5f..bfca81f45d9 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -48,9 +48,8 @@ KX_CDActuator::KX_CDActuator(SCA_IObject* gameobject, KX_CDACT_TYPE type, int track, short start, - short end, - PyTypeObject* T) - : SCA_IActuator(gameobject,T) + short end) + : SCA_IActuator(gameobject) { m_soundscene = soundscene; m_type = type; @@ -171,25 +170,17 @@ PyTypeObject KX_CDActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_CDActuator::Parents[] = { - &KX_CDActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_CDActuator::Methods[] = { // Deprecated -----> {"setGain",(PyCFunction) KX_CDActuator::sPySetGain,METH_VARARGS,NULL}, @@ -217,22 +208,6 @@ int KX_CDActuator::pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *a return PY_SET_ATTR_SUCCESS; } -PyObject* KX_CDActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_CDActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_CDActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - - - KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, startCD, "startCD()\n" "\tStarts the CD playing.\n") @@ -273,8 +248,8 @@ KX_PYMETHODDEF_DOC_O(KX_CDActuator, playTrack, "playTrack(trackNumber)\n" "\tPlays the track selected.\n") { - if (PyInt_Check(value)) { - int track = PyInt_AsLong(value); + if (PyLong_Check(value)) { + int track = PyLong_AsSsize_t(value); SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK); SND_CDObject::Instance()->SetTrack(track); SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h index 2fd05ab72e5..b01ad73777e 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.h +++ b/source/gameengine/Ketsji/KX_CDActuator.h @@ -68,8 +68,7 @@ public: KX_CDACT_TYPE type, int track, short start, - short end, - PyTypeObject* T=&Type); + short end); ~KX_CDActuator(); @@ -81,10 +80,6 @@ public: /* Python interface --------------------------------------------------- */ /* -------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD_VARARGS(KX_CDActuator,SetGain); KX_PYMETHOD_VARARGS(KX_CDActuator,GetGain); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 40f6c99c03c..f762699f780 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -42,10 +42,9 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, SG_Callbacks callbacks, const RAS_CameraData& camdata, bool frustum_culling, - bool delete_node, - PyTypeObject *T) + bool delete_node) : - KX_GameObject(sgReplicationInfo,callbacks,T), + KX_GameObject(sgReplicationInfo,callbacks), m_camdata(camdata), m_dirty(true), m_normalized(false), @@ -551,41 +550,19 @@ PyTypeObject KX_Camera::Type = { &KX_GameObject::Sequence, &KX_GameObject::Mapping, 0,0,0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - - - - - - -PyParentObject KX_Camera::Parents[] = { - &KX_Camera::Type, - &KX_GameObject::Type, - &SCA_IObject::Type, - &CValue::Type, - NULL + Methods, + 0, + 0, + &KX_GameObject::Type, + 0,0,0,0,0,0, + py_base_new }; -PyObject* KX_Camera::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_GameObject); -} - -PyObject* KX_Camera::py_getattro_dict() { - py_getattro_dict_up(KX_GameObject); -} - -int KX_Camera::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(KX_GameObject); -} - KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum, "sphereInsideFrustum(center, radius) -> Integer\n" "\treturns INSIDE, OUTSIDE or INTERSECT if the given sphere is\n" @@ -611,7 +588,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum, MT_Point3 center; if (PyVecTo(pycenter, center)) { - return PyInt_FromLong(SphereInsideFrustum(center, radius)); /* new ref */ + return PyLong_FromSsize_t(SphereInsideFrustum(center, radius)); /* new ref */ } } @@ -662,7 +639,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, boxInsideFrustum, return NULL; } - return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */ + return PyLong_FromSsize_t(BoxInsideFrustum(box)); /* new ref */ } KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum, @@ -684,7 +661,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum, MT_Point3 point; if (PyVecTo(value, point)) { - return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */ + return PyLong_FromSsize_t(PointInsideFrustum(point)); /* new ref */ } PyErr_SetString(PyExc_TypeError, "camera.pointInsideFrustum(point): KX_Camera, expected point argument."); @@ -952,11 +929,11 @@ PyObject* KX_Camera::pyattr_get_world_to_camera(void *self_v, const KX_PYATTRIBU PyObject* KX_Camera::pyattr_get_INSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ return PyInt_FromLong(INSIDE); } +{ return PyLong_FromSsize_t(INSIDE); } PyObject* KX_Camera::pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ return PyInt_FromLong(OUTSIDE); } +{ return PyLong_FromSsize_t(OUTSIDE); } PyObject* KX_Camera::pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ return PyInt_FromLong(INTERSECT); } +{ return PyLong_FromSsize_t(INTERSECT); } bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix) @@ -978,14 +955,14 @@ bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok } } - if (PyString_Check(value)) { - STR_String value_str = PyString_AsString(value); + if (PyUnicode_Check(value)) { + STR_String value_str = _PyUnicode_AsString(value); *object = KX_GetActiveScene()->FindCamera(value_str); if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, PyString_AsString(value)); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, _PyUnicode_AsString(value)); return false; } } @@ -1142,7 +1119,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay, PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect)); PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist)); if (propName) - PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName)); + PyTuple_SET_ITEM(argValue, 2, PyUnicode_FromString(propName)); PyObject* ret= this->PyrayCastTo(argValue,NULL); Py_DECREF(argValue); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index aef21cd91e4..74c8e6d4e4f 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -143,7 +143,7 @@ public: enum { INSIDE, INTERSECT, OUTSIDE } ; - KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false, PyTypeObject *T = &Type); + KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false); virtual ~KX_Camera(); /** @@ -265,6 +265,7 @@ public: */ int GetViewportTop() const; + virtual int GetGameObjectType() { return OBJ_CAMERA; } KX_PYMETHOD_DOC_VARARGS(KX_Camera, sphereInsideFrustum); KX_PYMETHOD_DOC_O(KX_Camera, boxInsideFrustum); @@ -282,10 +283,6 @@ public: KX_PYMETHOD_DOC_O(KX_Camera, getScreenPosition); KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenVect); KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenRay); - - virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */ - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); static PyObject* pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index f8557dac2c4..3d3b68ed85d 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -56,10 +56,9 @@ KX_CameraActuator::KX_CameraActuator( float hght, float minhght, float maxhght, - bool xytog, - PyTypeObject* T + bool xytog ): - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_ob (obj), m_height (hght), m_minHeight (minhght), @@ -385,19 +384,15 @@ PyTypeObject KX_CameraActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_CameraActuator::Parents[] = { - &KX_CameraActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_CameraActuator::Methods[] = { @@ -424,18 +419,6 @@ PyAttributeDef KX_CameraActuator::Attributes[] = { {NULL} }; -PyObject* KX_CameraActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_CameraActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_CameraActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - /* get obj ---------------------------------------------------------- */ const char KX_CameraActuator::GetObject_doc[] = "getObject(name_only = 1)\n" @@ -454,7 +437,7 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_ob->GetName().ReadPtr()); + return PyUnicode_FromString(m_ob->GetName().ReadPtr()); else return m_ob->GetProxy(); } @@ -579,7 +562,7 @@ const char KX_CameraActuator::GetXY_doc[] = PyObject* KX_CameraActuator::PyGetXY() { ShowDeprecationWarning("getXY()", "the xy property"); - return PyInt_FromLong(m_x); + return PyLong_FromSsize_t(m_x); } PyObject* KX_CameraActuator::pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index efa4e2f38d7..057c6fed770 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -91,9 +91,7 @@ private : float hght, float minhght, float maxhght, - bool xytog, - PyTypeObject* T=&Type - + bool xytog ); @@ -120,10 +118,6 @@ private : /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - /* set object to look at */ KX_PYMETHOD_DOC_O(KX_CameraActuator,SetObject); /* get current object */ diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 077ac96f0ac..1898dc71ef8 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -30,9 +30,6 @@ #define __KX_CLIENTOBJECT_INFO_H /* Note, the way this works with/without sumo is a bit odd */ -#ifdef USE_SUMO_SOLID -#include -#endif //USE_SUMO_SOLID #include @@ -42,9 +39,6 @@ class KX_GameObject; * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks */ struct KX_ClientObjectInfo -#ifdef USE_SUMO_SOLID - : public SM_ClientObject -#endif { enum clienttype { STATIC, @@ -59,18 +53,12 @@ struct KX_ClientObjectInfo std::list m_sensors; public: KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC, void *auxilary_info = NULL) : -#ifdef USE_SUMO_SOLID - SM_ClientObject(), -#endif m_type(type), m_gameobject(gameobject), m_auxilary_info(auxilary_info) {} KX_ClientObjectInfo(const KX_ClientObjectInfo ©) : -#ifdef USE_SUMO_SOLID - SM_ClientObject(copy), -#endif m_type(copy.m_type), m_gameobject(copy.m_gameobject), m_auxilary_info(copy.m_auxilary_info) diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index bd03dea486b..d09eae647c8 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -54,9 +54,8 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj, int locrotxyz, int time, int option, - char *property, - PyTypeObject* T) : - SCA_IActuator(gameobj, T), + char *property) : + SCA_IActuator(gameobj), m_refDirVector(refDir), m_currentTime(0) { @@ -581,19 +580,15 @@ PyTypeObject KX_ConstraintActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ConstraintActuator::Parents[] = { - &KX_ConstraintActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_ConstraintActuator::Methods[] = { @@ -639,21 +634,6 @@ PyAttributeDef KX_ConstraintActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_ConstraintActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_ConstraintActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_ConstraintActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - - int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_ConstraintActuator* act = static_cast(self); @@ -691,7 +671,7 @@ const char KX_ConstraintActuator::GetDamp_doc[] = "\tReturns the damping parameter.\n"; PyObject* KX_ConstraintActuator::PyGetDamp(){ ShowDeprecationWarning("getDamp()", "the damp property"); - return PyInt_FromLong(m_posDampTime); + return PyLong_FromSsize_t(m_posDampTime); } /* 2. setRotDamp */ @@ -718,7 +698,7 @@ const char KX_ConstraintActuator::GetRotDamp_doc[] = "\tReturns the damping time for application of the constraint.\n"; PyObject* KX_ConstraintActuator::PyGetRotDamp(){ ShowDeprecationWarning("getRotDamp()", "the rotDamp property"); - return PyInt_FromLong(m_rotDampTime); + return PyLong_FromSsize_t(m_rotDampTime); } /* 2. setDirection */ @@ -791,7 +771,7 @@ const char KX_ConstraintActuator::GetOption_doc[] = "\tReturns the option parameter.\n"; PyObject* KX_ConstraintActuator::PyGetOption(){ ShowDeprecationWarning("getOption()", "the option property"); - return PyInt_FromLong(m_option); + return PyLong_FromSsize_t(m_option); } /* 2. setTime */ @@ -820,7 +800,7 @@ const char KX_ConstraintActuator::GetTime_doc[] = "\tReturns the time parameter.\n"; PyObject* KX_ConstraintActuator::PyGetTime(){ ShowDeprecationWarning("getTime()", "the time property"); - return PyInt_FromLong(m_activeTime); + return PyLong_FromSsize_t(m_activeTime); } /* 2. setProperty */ @@ -849,7 +829,7 @@ const char KX_ConstraintActuator::GetProperty_doc[] = "\tReturns the property parameter.\n"; PyObject* KX_ConstraintActuator::PyGetProperty(){ ShowDeprecationWarning("getProperty()", "the 'property' property"); - return PyString_FromString(m_property.Ptr()); + return PyUnicode_FromString(m_property.Ptr()); } /* 4. setDistance */ @@ -978,7 +958,7 @@ const char KX_ConstraintActuator::GetLimit_doc[] = "\tReturns the type of constraint.\n"; PyObject* KX_ConstraintActuator::PyGetLimit() { ShowDeprecationWarning("setLimit()", "the limit property"); - return PyInt_FromLong(m_locrot); + return PyLong_FromSsize_t(m_locrot); } /* eof */ diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 40607b44947..677904aedc9 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -126,8 +126,7 @@ protected: int locrot, int time, int option, - char *property, - PyTypeObject* T=&Type); + char *property); virtual ~KX_ConstraintActuator(); virtual CValue* GetReplica() { KX_ConstraintActuator* replica = new KX_ConstraintActuator(*this); @@ -141,10 +140,6 @@ protected: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - static int pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_check_min(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index c5cf67af67d..ec7bb470235 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -38,8 +38,8 @@ KX_ConstraintWrapper::KX_ConstraintWrapper( PHY_ConstraintType ctype, int constraintId, - PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) : - PyObjectPlus(T), + PHY_IPhysicsEnvironment* physenv) : + PyObjectPlus(), m_constraintId(constraintId), m_constraintType(ctype), m_physenv(physenv) @@ -51,7 +51,7 @@ KX_ConstraintWrapper::~KX_ConstraintWrapper() PyObject* KX_ConstraintWrapper::PyGetConstraintId() { - return PyInt_FromLong(m_constraintId); + return PyLong_FromSsize_t(m_constraintId); } @@ -99,37 +99,17 @@ PyTypeObject KX_ConstraintWrapper::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ConstraintWrapper::Parents[] = { - &KX_ConstraintWrapper::Type, - NULL -}; - -//here you can search for existing data members (like mass,friction etc.) -PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_ConstraintWrapper::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value) -{ - py_setattro_up(PyObjectPlus); + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - - - - PyMethodDef KX_ConstraintWrapper::Methods[] = { {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_NOARGS}, {"setParam",(PyCFunction) KX_ConstraintWrapper::sPySetParam, METH_VARARGS}, diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 03813e0f167..74670944415 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -35,11 +35,8 @@ class KX_ConstraintWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); public: - KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_ConstraintWrapper (); int getConstraintId() { return m_constraintId;}; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 74042366bae..9d3b9cdaf74 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -32,11 +32,8 @@ /* These are defined by the build system... */ //but the build system is broken, because it doesn't allow for 2 or more defines at once. //Please leave Sumo _AND_ Bullet enabled -//#define USE_SUMO_SOLID // scons defines this #define USE_BULLET -//#define USE_ODE - //on visual studio 7/8, always enable BULLET for now //you can have multiple physics engines running anyway, and //the scons build system doesn't really support this at the moment. @@ -148,20 +145,6 @@ struct KX_ObjectProperties } m_boundobject; }; -#ifdef USE_ODE - - -void KX_ConvertODEEngineObject(KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - KX_Scene* kxscene, - struct PHY_ShapeProps* shapeprops, - struct PHY_MaterialProps* smmaterial, - struct KX_ObjectProperties* objprop); - - -#endif //USE_ODE - - void KX_ConvertDynamoObject(KX_GameObject* gameobj, RAS_MeshObject* meshobj, KX_Scene* kxscene, @@ -169,19 +152,6 @@ void KX_ConvertDynamoObject(KX_GameObject* gameobj, struct PHY_MaterialProps* smmaterial, struct KX_ObjectProperties* objprop); -#ifdef USE_SUMO_SOLID - -void KX_ConvertSumoObject( class KX_GameObject* gameobj, - class RAS_MeshObject* meshobj, - class KX_Scene* kxscene, - struct PHY_ShapeProps* shapeprops, - struct PHY_MaterialProps* smmaterial, - struct KX_ObjectProperties* objprop); - -void KX_ClearSumoSharedShapes(); -bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj); - -#endif #ifdef USE_BULLET diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 51c41c0686d..64b5760de28 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -32,7 +32,6 @@ #include "MT_assert.h" -// defines USE_ODE to choose physics engine #include "KX_ConvertPhysicsObject.h" #include "BL_DeformableGameObject.h" #include "RAS_MeshObject.h" @@ -56,597 +55,6 @@ extern "C"{ #include "BKE_DerivedMesh.h" } -#ifdef USE_ODE - -#include "KX_OdePhysicsController.h" -#include "OdePhysicsEnvironment.h" -#endif //USE_ODE - - -// USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObject.h -#ifdef USE_SUMO_SOLID - - -#include "SumoPhysicsEnvironment.h" -#include "KX_SumoPhysicsController.h" - - -// sumo physics specific -#include "SM_Object.h" -#include "SM_FhObject.h" -#include "SM_Scene.h" -#include "SM_ClientObjectInfo.h" - -#include "KX_SumoPhysicsController.h" - -struct KX_PhysicsInstance -{ - DT_VertexBaseHandle m_vertexbase; - RAS_DisplayArray* m_darray; - RAS_IPolyMaterial* m_material; - - KX_PhysicsInstance(DT_VertexBaseHandle vertex_base, RAS_DisplayArray *darray, RAS_IPolyMaterial* mat) - : m_vertexbase(vertex_base), - m_darray(darray), - m_material(mat) - { - } - - ~KX_PhysicsInstance() - { - DT_DeleteVertexBase(m_vertexbase); - } -}; - -static GEN_Map map_gamemesh_to_sumoshape; -static GEN_Map map_gamemesh_to_instance; - -// forward declarations -static void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,class SM_Object* sumoObj,const STR_String& matname,bool isDynamic,bool isActor); -static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope); - -void KX_ConvertSumoObject( KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - KX_Scene* kxscene, - PHY_ShapeProps* kxshapeprops, - PHY_MaterialProps* kxmaterial, - struct KX_ObjectProperties* objprop) - - -{ - SM_ShapeProps* smprop = new SM_ShapeProps; - - smprop->m_ang_drag = kxshapeprops->m_ang_drag; - smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic; - smprop->m_do_fh = kxshapeprops->m_do_fh; - smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ; - smprop->m_friction_scaling[0] = kxshapeprops->m_friction_scaling[0]; - smprop->m_friction_scaling[1] = kxshapeprops->m_friction_scaling[1]; - smprop->m_friction_scaling[2] = kxshapeprops->m_friction_scaling[2]; - smprop->m_inertia = MT_Vector3(1., 1., 1.) * kxshapeprops->m_inertia; - smprop->m_lin_drag = kxshapeprops->m_lin_drag; - smprop->m_mass = kxshapeprops->m_mass; - smprop->m_radius = objprop->m_radius; - - - SM_MaterialProps* smmaterial = new SM_MaterialProps; - - smmaterial->m_fh_damping = kxmaterial->m_fh_damping; - smmaterial->m_fh_distance = kxmaterial->m_fh_distance; - smmaterial->m_fh_normal = kxmaterial->m_fh_normal; - smmaterial->m_fh_spring = kxmaterial->m_fh_spring; - smmaterial->m_friction = kxmaterial->m_friction; - smmaterial->m_restitution = kxmaterial->m_restitution; - - SumoPhysicsEnvironment* sumoEnv = - (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); - - SM_Scene* sceneptr = sumoEnv->GetSumoScene(); - - SM_Object* sumoObj=NULL; - - if (objprop->m_dyna && objprop->m_isactor) - { - DT_ShapeHandle shape = NULL; - bool polytope = false; - switch (objprop->m_boundclass) - { - case KX_BOUNDBOX: - shape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], - objprop->m_boundobject.box.m_extends[1], - objprop->m_boundobject.box.m_extends[2]); - smprop->m_inertia.scale(objprop->m_boundobject.box.m_extends[0]*objprop->m_boundobject.box.m_extends[0], - objprop->m_boundobject.box.m_extends[1]*objprop->m_boundobject.box.m_extends[1], - objprop->m_boundobject.box.m_extends[2]*objprop->m_boundobject.box.m_extends[2]); - smprop->m_inertia *= smprop->m_mass/MT_Vector3(objprop->m_boundobject.box.m_extends).length(); - break; - case KX_BOUNDCYLINDER: - shape = DT_NewCylinder(smprop->m_radius, objprop->m_boundobject.c.m_height); - smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height); - break; - case KX_BOUNDCONE: - shape = DT_NewCone(objprop->m_radius, objprop->m_boundobject.c.m_height); - smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height); - break; - /* Dynamic mesh objects. WARNING! slow. */ - case KX_BOUNDPOLYTOPE: - polytope = true; - // fall through - case KX_BOUNDMESH: - if (meshobj && meshobj->NumPolygons() > 0) - { - if ((shape = CreateShapeFromMesh(meshobj, polytope))) - { - // TODO: calculate proper inertia - smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius; - break; - } - } - /* If CreateShapeFromMesh fails, fall through and use sphere */ - default: - case KX_BOUNDSPHERE: - shape = DT_NewSphere(objprop->m_radius); - smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius; - break; - - } - - sumoObj = new SM_Object(shape, !objprop->m_ghost?smmaterial:NULL,smprop,NULL); - - sumoObj->setRigidBody(objprop->m_angular_rigidbody?true:false); - - BL_RegisterSumoObject(gameobj,sceneptr,sumoObj,"",true, true); - - } - else { - // non physics object - if (meshobj) - { - int numpolys = meshobj->NumPolygons(); - { - - DT_ShapeHandle complexshape=0; - bool polytope = false; - - switch (objprop->m_boundclass) - { - case KX_BOUNDBOX: - complexshape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], objprop->m_boundobject.box.m_extends[1], objprop->m_boundobject.box.m_extends[2]); - break; - case KX_BOUNDSPHERE: - complexshape = DT_NewSphere(objprop->m_boundobject.c.m_radius); - break; - case KX_BOUNDCYLINDER: - complexshape = DT_NewCylinder(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height); - break; - case KX_BOUNDCONE: - complexshape = DT_NewCone(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height); - break; - case KX_BOUNDPOLYTOPE: - polytope = true; - // fall through - default: - case KX_BOUNDMESH: - if (numpolys>0) - { - complexshape = CreateShapeFromMesh(meshobj, polytope); - //std::cout << "Convert Physics Mesh: " << meshobj->GetName() << std::endl; -/* if (!complexshape) - { - // Something has to be done here - if the object has no polygons, it will not be able to have - // sensors attached to it. - DT_Vector3 pt = {0., 0., 0.}; - complexshape = DT_NewSphere(1.0); - objprop->m_ghost = evilObject = true; - } */ - } - break; - } - - if (complexshape) - { - SM_Object *dynamicParent = NULL; - - if (objprop->m_dynamic_parent) - { - // problem is how to find the dynamic parent - // in the scenegraph - KX_SumoPhysicsController* sumoctrl = - (KX_SumoPhysicsController*) - objprop->m_dynamic_parent->GetPhysicsController(); - - if (sumoctrl) - { - dynamicParent = sumoctrl->GetSumoObject(); - } - - MT_assert(dynamicParent); - } - - - sumoObj = new SM_Object(complexshape,!objprop->m_ghost?smmaterial:NULL,NULL, dynamicParent); - const STR_String& matname=meshobj->GetMaterialName(0); - - - BL_RegisterSumoObject(gameobj,sceneptr, - sumoObj, - matname, - objprop->m_dyna, - objprop->m_isactor); - } - } - } - } - - // physics object get updated here ! - - - // lazy evaluation because we might not support scaling !gameobj->UpdateTransform(); - - if (objprop->m_in_active_layer && sumoObj) - { - sceneptr->add(*sumoObj); - } - -} - - - -static void BL_RegisterSumoObject( - KX_GameObject* gameobj, - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - const STR_String& matname, - bool isDynamic, - bool isActor) -{ - PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); - - // need easy access, not via 'node' etc. - KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,sumoObj,motionstate,isDynamic); - gameobj->SetPhysicsController(physicscontroller,isDynamic); - - - if (!gameobj->getClientInfo()) - std::cout << "BL_RegisterSumoObject: WARNING: Object " << gameobj->GetName() << " has no client info" << std::endl; - physicscontroller->setNewClientInfo(gameobj->getClientInfo()); - - - gameobj->GetSGNode()->AddSGController(physicscontroller); - - gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC); - - // store materialname in auxinfo, needed for touchsensors - gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL); - - physicscontroller->SetObject(gameobj->GetSGNode()); -} - -static DT_ShapeHandle InstancePhysicsComplex(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat) -{ - // instance a mesh from a single vertex array & material - const RAS_TexVert *vertex_array = &darray->m_vertex[0]; - DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert)); - - DT_ShapeHandle shape = DT_NewComplexShape(vertex_base); - - std::vector indices; - for (int p = 0; p < meshobj->NumPolygons(); p++) - { - RAS_Polygon* poly = meshobj->GetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - DT_Begin(); - DT_VertexIndex(poly->GetVertexOffset(0)); - DT_VertexIndex(poly->GetVertexOffset(1)); - DT_VertexIndex(poly->GetVertexOffset(2)); - DT_End(); - - // tesselate - if (poly->VertexCount() == 4) - { - DT_Begin(); - DT_VertexIndex(poly->GetVertexOffset(0)); - DT_VertexIndex(poly->GetVertexOffset(2)); - DT_VertexIndex(poly->GetVertexOffset(3)); - DT_End(); - } - } - } - - //DT_VertexIndices(indices.size(), &indices[0]); - DT_EndComplexShape(); - - map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat)); - return shape; -} - -static DT_ShapeHandle InstancePhysicsPolytope(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat) -{ - // instance a mesh from a single vertex array & material - const RAS_TexVert *vertex_array = &darray->m_vertex[0]; - DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert)); - - std::vector indices; - for (int p = 0; p < meshobj->NumPolygons(); p++) - { - RAS_Polygon* poly = meshobj->GetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - indices.push_back(poly->GetVertexOffset(0)); - indices.push_back(poly->GetVertexOffset(1)); - indices.push_back(poly->GetVertexOffset(2)); - - if (poly->VertexCount() == 4) - indices.push_back(poly->GetVertexOffset(3)); - } - } - - DT_ShapeHandle shape = DT_NewPolytope(vertex_base); - DT_VertexIndices(indices.size(), &indices[0]); - DT_EndPolytope(); - - map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat)); - return shape; -} - -// This will have to be a method in a class somewhere... -// Update SOLID with a changed physics mesh. -// not used... yet. -bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj) -{ - KX_PhysicsInstance *instance = *map_gamemesh_to_instance[GEN_HashedPtr(meshobj)]; - if (instance) - { - const RAS_TexVert *vertex_array = &instance->m_darray->m_vertex[0]; - DT_ChangeVertexBase(instance->m_vertexbase, vertex_array[0].getXYZ()); - return true; - } - return false; -} - -static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope) -{ - - DT_ShapeHandle *shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)]; - // Mesh has already been converted: reuse - if (shapeptr) - { - return *shapeptr; - } - - // Mesh has no polygons! - int numpolys = meshobj->NumPolygons(); - if (!numpolys) - { - return NULL; - } - - // Count the number of collision polygons and check they all come from the same - // vertex array - int numvalidpolys = 0; - RAS_DisplayArray *darray = NULL; - RAS_IPolyMaterial *poly_material = NULL; - bool reinstance = true; - - for (int p=0; pGetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - // check polygon is from the same vertex array - if (poly->GetDisplayArray() != darray) - { - if (darray == NULL) - darray = poly->GetDisplayArray(); - else - { - reinstance = false; - darray = NULL; - } - } - - // check poly is from the same material - if (poly->GetMaterial()->GetPolyMaterial() != poly_material) - { - if (poly_material) - { - reinstance = false; - poly_material = NULL; - } - else - poly_material = poly->GetMaterial()->GetPolyMaterial(); - } - - // count the number of collision polys - numvalidpolys++; - - // We have one collision poly, and we can't reinstance, so we - // might as well break here. - if (!reinstance) - break; - } - } - - // No collision polygons - if (numvalidpolys < 1) - return NULL; - - DT_ShapeHandle shape; - if (reinstance) - { - if (polytope) - shape = InstancePhysicsPolytope(meshobj, darray, poly_material); - else - shape = InstancePhysicsComplex(meshobj, darray, poly_material); - } - else - { - if (polytope) - { - std::cout << "CreateShapeFromMesh: " << meshobj->GetName() << " is not suitable for polytope." << std::endl; - if (!poly_material) - std::cout << " Check mesh materials." << std::endl; - if (darray == NULL) - std::cout << " Check number of vertices." << std::endl; - } - - shape = DT_NewComplexShape(NULL); - - numvalidpolys = 0; - - for (int p2=0; p2GetPolygon(p2); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { /* We have to tesselate here because SOLID can only raycast triangles */ - DT_Begin(); - /* V1, V2, V3 */ - DT_Vertex(poly->GetVertex(2)->getXYZ()); - DT_Vertex(poly->GetVertex(1)->getXYZ()); - DT_Vertex(poly->GetVertex(0)->getXYZ()); - - numvalidpolys++; - DT_End(); - - if (poly->VertexCount() == 4) - { - DT_Begin(); - /* V1, V3, V4 */ - DT_Vertex(poly->GetVertex(3)->getXYZ()); - DT_Vertex(poly->GetVertex(2)->getXYZ()); - DT_Vertex(poly->GetVertex(0)->getXYZ()); - - numvalidpolys++; - DT_End(); - } - - } - } - - DT_EndComplexShape(); - } - - if (numvalidpolys > 0) - { - map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape); - return shape; - } - - delete shape; - return NULL; -} - -void KX_ClearSumoSharedShapes() -{ - int numshapes = map_gamemesh_to_sumoshape.size(); - int i; - for (i=0;im_dyna; - bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0; - bool phantom = objprop->m_ghost; - class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); - - class ODEPhysicsEnvironment* odeEnv = - (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); - - dxSpace* space = odeEnv->GetOdeSpace(); - dxWorld* world = odeEnv->GetOdeWorld(); - - bool isSphere = false; - - switch (objprop->m_boundclass) - { - case KX_BOUNDBOX: - { - - KX_OdePhysicsController* physicscontroller = - new KX_OdePhysicsController( - dyna, - fullRigidBody, - phantom, - motionstate, - space, - world, - shapeprops->m_mass, - smmaterial->m_friction, - smmaterial->m_restitution, - isSphere, - objprop->m_boundobject.box.m_center, - objprop->m_boundobject.box.m_extends, - objprop->m_boundobject.c.m_radius - ); - - gameobj->SetPhysicsController(physicscontroller); - physicscontroller->setNewClientInfo(gameobj->getClientInfo()); - gameobj->GetSGNode()->AddSGController(physicscontroller); - - bool isActor = objprop->m_isactor; - STR_String materialname; - if (meshobj) - materialname = meshobj->GetMaterialName(0); - - const char* matname = materialname.ReadPtr(); - - - physicscontroller->SetObject(gameobj->GetSGNode()); - - break; - } - default: - { - } - }; - -} - - -#endif // USE_ODE - - #ifdef USE_BULLET #include "CcdPhysicsEnvironment.h" diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 28bf12f5e87..560c7fa4bb4 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -49,9 +49,8 @@ KX_GameActuator::KX_GameActuator(SCA_IObject *gameobj, const STR_String& filename, const STR_String& loadinganimationname, KX_Scene* scene, - KX_KetsjiEngine* ketsjiengine, - PyTypeObject* T) - : SCA_IActuator(gameobj, T) + KX_KetsjiEngine* ketsjiengine) + : SCA_IActuator(gameobj) { m_mode = mode; m_filename = filename; @@ -224,26 +223,17 @@ PyTypeObject KX_GameActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_GameActuator::Parents[] = -{ - &KX_GameActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_GameActuator::Methods[] = { // Deprecated -----> @@ -259,21 +249,6 @@ PyAttributeDef KX_GameActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_GameActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_GameActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_GameActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - - // Deprecated -----> /* getFile */ const char KX_GameActuator::GetFile_doc[] = @@ -282,7 +257,7 @@ const char KX_GameActuator::GetFile_doc[] = PyObject* KX_GameActuator::PyGetFile(PyObject* args, PyObject* kwds) { ShowDeprecationWarning("getFile()", "the fileName property"); - return PyString_FromString(m_filename); + return PyUnicode_FromString(m_filename); } /* setFile */ diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h index b2b1d6ec2b9..cabbf827b40 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.h +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -65,8 +65,7 @@ protected: const STR_String& filename, const STR_String& loadinganimationname, KX_Scene* scene, - KX_KetsjiEngine* ketsjiEngine, - PyTypeObject* T=&Type); + KX_KetsjiEngine* ketsjiEngine); virtual ~KX_GameActuator(); virtual CValue* GetReplica(); @@ -77,10 +76,6 @@ protected: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated functions -----> KX_PYMETHOD_DOC(KX_GameActuator,GetFile); KX_PYMETHOD_DOC(KX_GameActuator,SetFile); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index b266095c715..bf80eec36d9 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -86,10 +86,8 @@ static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0, KX_GameObject::KX_GameObject( void* sgReplicationInfo, - SG_Callbacks callbacks, - PyTypeObject* T -) : - SCA_IObject(T), + SG_Callbacks callbacks) + : SCA_IObject(), m_bDyna(false), m_layer(0), m_pBlenderObject(NULL), @@ -983,7 +981,17 @@ void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot) GetSGNode()->SetLocalOrientation(rot); } +void KX_GameObject::NodeSetGlobalOrientation(const MT_Matrix3x3& rot) +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + if (GetSGNode()->GetSGParent()) + GetSGNode()->SetLocalOrientation(GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); + else + GetSGNode()->SetLocalOrientation(rot); +} void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale) { @@ -1062,7 +1070,13 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const return GetSGNode()->GetWorldOrientation(); } - +const MT_Matrix3x3& KX_GameObject::NodeGetLocalOrientation() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return dummy_orientation; + return GetSGNode()->GetLocalOrientation(); +} const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const { @@ -1073,7 +1087,14 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const return GetSGNode()->GetWorldScaling(); } +const MT_Vector3& KX_GameObject::NodeGetLocalScaling() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return dummy_scaling; + return GetSGNode()->GetLocalScale(); +} const MT_Point3& KX_GameObject::NodeGetWorldPosition() const { @@ -1084,6 +1105,16 @@ const MT_Point3& KX_GameObject::NodeGetWorldPosition() const return dummy_point; } +const MT_Point3& KX_GameObject::NodeGetLocalPosition() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (GetSGNode()) + return GetSGNode()->GetLocalPosition(); + else + return dummy_point; +} + + /* Suspend/ resume: for the dynamic behaviour, there is a simple * method. For the residual motion, there is not. I wonder what the * correct solution is for Sumo. Remove from the motion-update tree? @@ -1151,6 +1182,181 @@ CListValue* KX_GameObject::GetChildrenRecursive() return list; } +#ifdef USE_MATHUTILS + +/* These require an SGNode */ +#define MATHUTILS_VEC_CB_POS_LOCAL 1 +#define MATHUTILS_VEC_CB_POS_GLOBAL 2 +#define MATHUTILS_VEC_CB_SCALE_LOCAL 3 +#define MATHUTILS_VEC_CB_SCALE_GLOBAL 4 +#define MATHUTILS_VEC_CB_INERTIA_LOCAL 5 + +static int mathutils_kxgameob_vector_cb_index= -1; /* index for our callbacks */ + +static int mathutils_kxgameob_generic_check(PyObject *self_v) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + return 1; +} + +static int mathutils_kxgameob_vector_get(PyObject *self_v, int subtype, float *vec_from) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_POS_LOCAL: + self->NodeGetLocalPosition().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_POS_GLOBAL: + self->NodeGetWorldPosition().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_SCALE_LOCAL: + self->NodeGetLocalScaling().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_SCALE_GLOBAL: + self->NodeGetWorldScaling().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_INERTIA_LOCAL: + if(!self->GetPhysicsController()) return 0; + self->GetPhysicsController()->GetLocalInertia().getValue(vec_from); + break; + } + + return 1; +} + +static int mathutils_kxgameob_vector_set(PyObject *self_v, int subtype, float *vec_to) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_POS_LOCAL: + self->NodeSetLocalPosition(MT_Point3(vec_to)); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_VEC_CB_POS_GLOBAL: + self->NodeSetWorldPosition(MT_Point3(vec_to)); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_VEC_CB_SCALE_LOCAL: + self->NodeSetLocalScale(MT_Point3(vec_to)); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_VEC_CB_SCALE_GLOBAL: + break; + case MATHUTILS_VEC_CB_INERTIA_LOCAL: + /* read only */ + break; + } + + return 1; +} + +static int mathutils_kxgameob_vector_get_index(PyObject *self_v, int subtype, float *vec_from, int index) +{ + float f[4]; + /* lazy, avoid repeteing the case statement */ + if(!mathutils_kxgameob_vector_get(self_v, subtype, f)) + return 0; + + vec_from[index]= f[index]; + return 1; +} + +static int mathutils_kxgameob_vector_set_index(PyObject *self_v, int subtype, float *vec_to, int index) +{ + float f= vec_to[index]; + + /* lazy, avoid repeteing the case statement */ + if(!mathutils_kxgameob_vector_get(self_v, subtype, vec_to)) + return 0; + + vec_to[index]= f; + mathutils_kxgameob_vector_set(self_v, subtype, vec_to); + + return 1; +} + +Mathutils_Callback mathutils_kxgameob_vector_cb = { + mathutils_kxgameob_generic_check, + mathutils_kxgameob_vector_get, + mathutils_kxgameob_vector_set, + mathutils_kxgameob_vector_get_index, + mathutils_kxgameob_vector_set_index +}; + +/* Matrix */ +#define MATHUTILS_MAT_CB_ORI_LOCAL 1 +#define MATHUTILS_MAT_CB_ORI_GLOBAL 2 + +static int mathutils_kxgameob_matrix_cb_index= -1; /* index for our callbacks */ + +static int mathutils_kxgameob_matrix_get(PyObject *self_v, int subtype, float *mat_from) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_MAT_CB_ORI_LOCAL: + self->NodeGetLocalOrientation().getValue3x3(mat_from); + break; + case MATHUTILS_MAT_CB_ORI_GLOBAL: + self->NodeGetWorldOrientation().getValue3x3(mat_from); + break; + } + + return 1; +} + + +static int mathutils_kxgameob_matrix_set(PyObject *self_v, int subtype, float *mat_to) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + MT_Matrix3x3 mat3x3; + switch(subtype) { + case MATHUTILS_MAT_CB_ORI_LOCAL: + mat3x3.setValue3x3(mat_to); + self->NodeSetLocalOrientation(mat3x3); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_MAT_CB_ORI_GLOBAL: + mat3x3.setValue3x3(mat_to); + self->NodeSetLocalOrientation(mat3x3); + self->NodeUpdateGS(0.f); + break; + } + + return 1; +} + +Mathutils_Callback mathutils_kxgameob_matrix_cb = { + mathutils_kxgameob_generic_check, + mathutils_kxgameob_matrix_get, + mathutils_kxgameob_matrix_set, + NULL, + NULL +}; + + +void KX_GameObject_Mathutils_Callback_Init(void) +{ + // register mathutils callbacks, ok to run more then once. + mathutils_kxgameob_vector_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_vector_cb); + mathutils_kxgameob_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_matrix_cb); +} + +#endif // USE_MATHUTILS /* ------- python stuff ---------------------------------------------------*/ @@ -1290,7 +1496,7 @@ PyObject* KX_GameObject::PyGetPosition() static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) { KX_GameObject* self= static_castBGE_PROXY_REF(self_v); - const char *attr_str= PyString_AsString(item); + const char *attr_str= _PyUnicode_AsString(item); CValue* resultattr; PyObject* pyconvert; @@ -1324,7 +1530,7 @@ static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) { KX_GameObject* self= static_castBGE_PROXY_REF(self_v); - const char *attr_str= PyString_AsString(key); + const char *attr_str= _PyUnicode_AsString(key); if(attr_str==NULL) PyErr_Clear(); @@ -1356,7 +1562,7 @@ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) int set= 0; /* as CValue */ - if(attr_str && BGE_PROXY_CHECK_TYPE(val)==0) /* dont allow GameObjects for eg to be assigned to CValue props */ + if(attr_str && PyObject_TypeCheck(val, &PyObjectPlus::Type)==0) /* dont allow GameObjects for eg to be assigned to CValue props */ { CValue* vallie = self->ConvertPythonToValue(val, ""); /* error unused */ @@ -1418,7 +1624,7 @@ static int Seq_Contains(PyObject *self_v, PyObject *value) return -1; } - if(PyString_Check(value) && self->GetProperty(PyString_AsString(value))) + if(PyUnicode_Check(value) && self->GetProperty(_PyUnicode_AsString(value))) return 1; if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value)) @@ -1466,30 +1672,23 @@ PyTypeObject KX_GameObject::Type = { &Sequence, &Mapping, 0,0,0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - - - - - - -PyParentObject KX_GameObject::Parents[] = { - &KX_GameObject::Type, + Methods, + 0, + 0, &SCA_IObject::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyObject* KX_GameObject::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - return PyString_FromString(self->GetName().ReadPtr()); + return PyUnicode_FromString(self->GetName().ReadPtr()); } PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1596,7 +1795,11 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_GLOBAL); +#else return PyObjectFrom(self->NodeGetWorldPosition()); +#endif } int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1614,10 +1817,11 @@ int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_D PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalPosition()); - else - return PyObjectFrom(dummy_point); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL); +#else + return PyObjectFrom(self->NodeGetLocalPosition()); +#endif } int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1635,17 +1839,23 @@ int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_D PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_INERTIA_LOCAL); +#else if (self->GetPhysicsController()) - { return PyObjectFrom(self->GetPhysicsController()->GetLocalInertia()); - } return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f); +#endif } PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { +#ifdef USE_MATHUTILS + return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL); +#else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetWorldOrientation()); +#endif } int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1657,12 +1867,7 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, ")) return PY_SET_ATTR_FAIL; - if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) { - self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); - } - else { - self->NodeSetLocalOrientation(rot); - } + self->NodeSetGlobalOrientation(rot); self->NodeUpdateGS(0.f); return PY_SET_ATTR_SUCCESS; @@ -1670,11 +1875,12 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { +#ifdef USE_MATHUTILS + return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL); +#else KX_GameObject* self= static_cast(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalOrientation()); - else - return PyObjectFrom(dummy_orientation); + return PyObjectFrom(self->NodeGetLocalOrientation()); +#endif } int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1694,16 +1900,21 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_GLOBAL); +#else return PyObjectFrom(self->NodeGetWorldScaling()); +#endif } PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalScale()); - else - return PyObjectFrom(dummy_scaling); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL); +#else + return PyObjectFrom(self->NodeGetLocalScaling()); +#endif } int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1750,13 +1961,13 @@ PyObject* KX_GameObject::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF KX_GameObject* self= static_cast(self_v); int state = 0; state |= self->GetState(); - return PyInt_FromLong(state); + return PyLong_FromSsize_t(state); } int KX_GameObject::pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_GameObject* self= static_cast(self_v); - int state_i = PyInt_AsLong(value); + int state_i = PyLong_AsSsize_t(value); unsigned int state = 0; if (state_i == -1 && PyErr_Occurred()) { @@ -1827,128 +2038,6 @@ PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_ return self->m_attr_dict; } -/* We need these because the macros have a return in them */ -PyObject* KX_GameObject::py_getattro__internal(PyObject *attr) -{ - py_getattro_up(SCA_IObject); -} - -int KX_GameObject::py_setattro__internal(PyObject *attr, PyObject *value) // py_setattro method -{ - py_setattro_up(SCA_IObject); -} - - -PyObject* KX_GameObject::py_getattro(PyObject *attr) -{ - PyObject *object= py_getattro__internal(attr); - - if (object==NULL && m_attr_dict) - { - /* backup the exception incase the attr doesnt exist in the dict either */ - PyObject *err_type, *err_value, *err_tb; - PyErr_Fetch(&err_type, &err_value, &err_tb); - - object= PyDict_GetItem(m_attr_dict, attr); - if (object) { - Py_INCREF(object); - - PyErr_Clear(); - Py_XDECREF( err_type ); - Py_XDECREF( err_value ); - Py_XDECREF( err_tb ); - } - else { - PyErr_Restore(err_type, err_value, err_tb); /* use the error from the parent function */ - } - } - return object; -} - -PyObject* KX_GameObject::py_getattro_dict() { - //py_getattro_dict_up(SCA_IObject); - PyObject *dict= py_getattr_dict(SCA_IObject::py_getattro_dict(), Type.tp_dict); - if(dict==NULL) - return NULL; - - /* normally just return this but KX_GameObject has some more items */ - - - /* Not super fast getting as a list then making into dict keys but its only for dir() */ - PyObject *list= ConvertKeysToPython(); - if(list) - { - int i; - for(i=0; iGetUserData(); } - return PyInt_FromLong((long)physid); + return PyLong_FromSsize_t((long)physid); } PyObject* KX_GameObject::PyGetPropertyNames() @@ -2788,8 +2877,8 @@ PyObject* KX_GameObject::Pyget(PyObject *args) return NULL; - if(PyString_Check(key)) { - CValue *item = GetProperty(PyString_AsString(key)); + if(PyUnicode_Check(key)) { + CValue *item = GetProperty(_PyUnicode_AsString(key)); if (item) { ret = item->ConvertValueToPython(); if(ret) @@ -2858,13 +2947,13 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py } } - if (PyString_Check(value)) { - *object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( PyString_AsString(value) )); + if (PyUnicode_Check(value)) { + *object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( _PyUnicode_AsString(value) )); if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_GameObject in this scene", error_prefix, PyString_AsString(value)); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_GameObject in this scene", error_prefix, _PyUnicode_AsString(value)); return false; } } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index ff5c8a01e6e..947cc9959ff 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -63,6 +63,10 @@ struct Object; /* utility conversion function */ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix); +#ifdef USE_MATHUTILS +void KX_GameObject_Mathutils_Callback_Init(void); +#endif + /** * KX_GameObject is the main class for dynamic objects. */ @@ -185,8 +189,7 @@ public: KX_GameObject( void* sgReplicationInfo, - SG_Callbacks callbacks, - PyTypeObject* T=&Type + SG_Callbacks callbacks ); virtual @@ -393,6 +396,7 @@ public: void NodeSetLocalPosition(const MT_Point3& trans ); void NodeSetLocalOrientation(const MT_Matrix3x3& rot ); + void NodeSetGlobalOrientation(const MT_Matrix3x3& rot ); void NodeSetLocalScale( const MT_Vector3& scale ); @@ -406,21 +410,13 @@ public: double time ); - const - MT_Matrix3x3& - NodeGetWorldOrientation( - ) const; - - const - MT_Vector3& - NodeGetWorldScaling( - ) const; - - const - MT_Point3& - NodeGetWorldPosition( - ) const; + const MT_Matrix3x3& NodeGetWorldOrientation( ) const; + const MT_Vector3& NodeGetWorldScaling( ) const; + const MT_Point3& NodeGetWorldPosition( ) const; + const MT_Matrix3x3& NodeGetLocalOrientation( ) const; + const MT_Vector3& NodeGetLocalScaling( ) const; + const MT_Point3& NodeGetLocalPosition( ) const; /** * @section scene graph node accessor functions. @@ -811,22 +807,10 @@ public: /** * @section Python interface functions. */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); // py_setattro method - virtual int py_delattro(PyObject *attr); virtual PyObject* py_repr(void) { - return PyString_FromString(GetName().ReadPtr()); + return PyUnicode_FromString(GetName().ReadPtr()); } - - - /* quite annoying that we need these but the bloody - * py_getattro_up and py_setattro_up macro's have a returns in them! */ - PyObject* py_getattro__internal(PyObject *attr); - int py_setattro__internal(PyObject *attr, PyObject *value); // py_setattro method - KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition); KX_PYMETHOD_O(KX_GameObject,SetPosition); diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index 3ec0598ac03..73a370a1681 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -70,9 +70,8 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, int acttype, bool ipo_as_force, bool ipo_add, - bool ipo_local, - PyTypeObject* T) - : SCA_IActuator(gameobj,T), + bool ipo_local) + : SCA_IActuator(gameobj), m_bNegativeEvent(false), m_startframe (starttime), m_endframe(endtime), @@ -429,19 +428,15 @@ PyTypeObject KX_IpoActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_IpoActuator::Parents[] = { - &KX_IpoActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_IpoActuator::Methods[] = { @@ -477,18 +472,6 @@ PyAttributeDef KX_IpoActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_IpoActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_IpoActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_IpoActuator::py_setattro(PyObject *attr, PyObject *value) // py_setattro method -{ - py_setattro_up(SCA_IActuator); -} /* set --------------------------------------------------------------------- */ const char KX_IpoActuator::Set_doc[] = @@ -689,7 +672,7 @@ const char KX_IpoActuator::GetType_doc[] = "\tReturns the operation mode of the actuator.\n"; PyObject* KX_IpoActuator::PyGetType() { ShowDeprecationWarning("getType()", "the mode property"); - return PyInt_FromLong(m_type); + return PyLong_FromSsize_t(m_type); } /* 10. setForceIpoActsLocal: */ diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 9ea597def1e..01051ca82dc 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -121,8 +121,7 @@ public: int acttype, bool ipo_as_force, bool ipo_add, - bool ipo_local, - PyTypeObject* T=&Type); + bool ipo_local); virtual ~KX_IpoActuator() {}; virtual CValue* GetReplica() { @@ -138,10 +137,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,Set); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index a43ea59220b..cc0f50d9e7a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -61,10 +61,6 @@ #include "KX_PyConstraintBinding.h" #include "PHY_IPhysicsEnvironment.h" -#ifdef USE_SUMO_SOLID -#include "SumoPhysicsEnvironment.h" -#endif - #include "SND_Scene.h" #include "SND_IAudioDevice.h" @@ -400,9 +396,9 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo) World* world = m_scenes[0]->GetBlenderScene()->world; if (world) { - m_ticrate = world->ticrate; - m_maxLogicFrame = world->maxlogicstep; - m_maxPhysicsFrame = world->maxphystep; + m_ticrate = world->ticrate ? world->ticrate : DEFAULT_LOGIC_TIC_RATE; + m_maxLogicFrame = world->maxlogicstep ? world->maxlogicstep : 5; + m_maxPhysicsFrame = world->maxphystep ? world->maxlogicstep : 5; } else { diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index ae9e097a96e..fb385f8a9a2 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -51,12 +51,9 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, class RAS_IRenderTools* rendertools, const RAS_LightObject& lightobj, - bool glsl, - PyTypeObject* T - ) - : - KX_GameObject(sgReplicationInfo,callbacks,T), - m_rendertools(rendertools) + bool glsl) + : KX_GameObject(sgReplicationInfo,callbacks), + m_rendertools(rendertools) { m_lightobj = lightobj; m_lightobj.m_scene = sgReplicationInfo; @@ -271,11 +268,6 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) /* Python Integration Hooks */ /* ------------------------------------------------------------------------- */ -PyObject* KX_LightObject::py_getattro_dict() { - py_getattro_dict_up(KX_GameObject); -} - - PyTypeObject KX_LightObject::Type = { #if (PY_VERSION_HEX >= 0x02060000) PyVarObject_HEAD_INIT(NULL, 0) @@ -297,20 +289,17 @@ PyTypeObject KX_LightObject::Type = { &KX_GameObject::Sequence, &KX_GameObject::Mapping, 0,0,0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_LightObject::Parents[] = { - &KX_LightObject::Type, - &KX_GameObject::Type, - &SCA_IObject::Type, - &CValue::Type, - NULL + Methods, + 0, + 0, + &KX_GameObject::Type, + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_LightObject::Methods[] = { @@ -362,11 +351,11 @@ PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUT const char* type = attrdef->m_name; if(strcmp(type, "SPOT")) { - retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SPOT); + retvalue = PyLong_FromSsize_t(RAS_LightObject::LIGHT_SPOT); } else if (strcmp(type, "SUN")) { - retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SUN); + retvalue = PyLong_FromSsize_t(RAS_LightObject::LIGHT_SUN); } else if (strcmp(type, "NORMAL")) { - retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL); + retvalue = PyLong_FromSsize_t(RAS_LightObject::LIGHT_NORMAL); } return retvalue; @@ -375,13 +364,13 @@ PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUT PyObject* KX_LightObject::pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_LightObject* self = static_cast(self_v); - return PyInt_FromLong(self->m_lightobj.m_type); + return PyLong_FromSsize_t(self->m_lightobj.m_type); } int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value) { KX_LightObject* self = static_cast(self_v); - int val = PyInt_AsLong(value); + int val = PyLong_AsSsize_t(value); if((val==-1 && PyErr_Occurred()) || val<0 || val>2) { PyErr_SetString(PyExc_ValueError, "light.type= val: KX_LightObject, expected an int between 0 and 2"); return PY_SET_ATTR_FAIL; @@ -401,14 +390,3 @@ int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attr return PY_SET_ATTR_SUCCESS; } - - -PyObject* KX_LightObject::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_GameObject); -} - -int KX_LightObject::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(KX_GameObject); -} diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 358c705080a..0b7ccbe81ab 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -49,7 +49,7 @@ protected: Scene* m_blenderscene; public: - KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl, PyTypeObject *T = &Type); + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl); virtual ~KX_LightObject(); virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} @@ -64,10 +64,6 @@ public: void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans); void UnbindShadowBuffer(class RAS_IRasterizer *ras); void Update(); - - virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */ - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); /* attributes */ static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 11effa1ca98..96e8f61e4c8 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -62,18 +62,15 @@ PyTypeObject KX_MeshProxy::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_MeshProxy::Parents[] = { - &KX_MeshProxy::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - &PyObjectPlus::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_MeshProxy::Methods[] = { @@ -106,24 +103,8 @@ void KX_MeshProxy::SetMeshModified(bool v) m_meshobj->SetMeshModified(v); } - -PyObject* KX_MeshProxy::py_getattro(PyObject *attr) -{ - py_getattro_up(CValue); -} - -PyObject* KX_MeshProxy::py_getattro_dict() { - py_getattro_dict_up(CValue); -} - -int KX_MeshProxy::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(CValue); -} - - KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh) - : CValue(&Type), m_meshobj(mesh) + : CValue(), m_meshobj(mesh) { } @@ -150,14 +131,14 @@ PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* args, PyObject* kwds) { int num = m_meshobj->NumMaterials(); ShowDeprecationWarning("getNumMaterials()", "the numMaterials property"); - return PyInt_FromLong(num); + return PyLong_FromSsize_t(num); } PyObject* KX_MeshProxy::PyGetNumPolygons() { int num = m_meshobj->NumPolygons(); ShowDeprecationWarning("getNumPolygons()", "the numPolygons property"); - return PyInt_FromLong(num); + return PyLong_FromSsize_t(num); } PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* args, PyObject* kwds) @@ -173,7 +154,7 @@ PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* args, PyObject* kwds) return NULL; } - return PyString_FromString(matname.Ptr()); + return PyUnicode_FromString(matname.Ptr()); } @@ -191,7 +172,7 @@ PyObject* KX_MeshProxy::PyGetTextureName(PyObject* args, PyObject* kwds) return NULL; } - return PyString_FromString(matname.Ptr()); + return PyUnicode_FromString(matname.Ptr()); } @@ -214,7 +195,7 @@ PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* args, PyObject* kwds) length = m_meshobj->NumVertices(mat); } - return PyInt_FromLong(length); + return PyLong_FromSsize_t(length); } @@ -304,12 +285,12 @@ PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_ PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) { KX_MeshProxy * self = static_cast (selfv); - return PyInt_FromLong(self->m_meshobj->NumMaterials()); + return PyLong_FromSsize_t(self->m_meshobj->NumMaterials()); } PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) { KX_MeshProxy * self = static_cast (selfv); - return PyInt_FromLong(self->m_meshobj->NumPolygons()); + return PyLong_FromSsize_t(self->m_meshobj->NumPolygons()); } /* a close copy of ConvertPythonToGameObject but for meshes */ @@ -332,13 +313,13 @@ bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **object, bool py_none } } - if (PyString_Check(value)) { - *object = (RAS_MeshObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String( PyString_AsString(value) )); + if (PyUnicode_Check(value)) { + *object = (RAS_MeshObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String( _PyUnicode_AsString(value) )); if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_MeshProxy in this scene", error_prefix, PyString_AsString(value)); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_MeshProxy in this scene", error_prefix, _PyUnicode_AsString(value)); return false; } } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index bfdd4be4118..4b6543677ad 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -56,9 +56,6 @@ public: virtual CValue* GetReplica(); // stuff for python integration - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); KX_PYMETHOD(KX_MeshProxy,GetNumMaterials); // Deprecated KX_PYMETHOD(KX_MeshProxy,GetMaterialName); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index fde10a493db..ba4b47cb03f 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -63,9 +63,8 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, int focusmode, KX_Scene* kxscene, KX_KetsjiEngine *kxengine, - SCA_IObject* gameobj, - PyTypeObject* T) - : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T), + SCA_IObject* gameobj) + : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj), m_focusmode(focusmode), m_kxscene(kxscene), m_kxengine(kxengine) @@ -356,20 +355,15 @@ PyTypeObject KX_MouseFocusSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_MouseFocusSensor::Parents[] = { - &KX_MouseFocusSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_MouseSensor::Type, - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_MouseFocusSensor::Methods[] = { @@ -393,15 +387,6 @@ PyAttributeDef KX_MouseFocusSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_MouseFocusSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_MouseSensor); -} - -PyObject* KX_MouseFocusSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_MouseSensor); -} - - const char KX_MouseFocusSensor::GetHitObject_doc[] = "getHitObject()\n" "\tReturns the object that was hit by this ray.\n"; diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 29d674eb305..dfada7a59cc 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -56,8 +56,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor int focusmode, KX_Scene* kxscene, KX_KetsjiEngine* kxengine, - SCA_IObject* gameobj, - PyTypeObject* T=&Type ); + SCA_IObject* gameobj); virtual ~KX_MouseFocusSensor() { ; }; virtual CValue* GetReplica() { @@ -89,8 +88,6 @@ class KX_MouseFocusSensor : public SCA_MouseSensor /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayTarget); KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRaySource); diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index 44842b7f5b3..1a211a64b35 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -48,15 +48,13 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, - PHY_IPhysicsController* ctrl, - PyTypeObject* T) + PHY_IPhysicsController* ctrl) :KX_TouchSensor(eventmgr, gameobj, bFindMaterial, false, - touchedpropname, - /* scene, */ - T), + touchedpropname + /*, scene */), m_Margin(margin), m_ResetMargin(resetmargin) @@ -272,26 +270,17 @@ PyTypeObject KX_NearSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_NearSensor::Parents[] = { - &KX_NearSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &KX_TouchSensor::Type, - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_NearSensor::Methods[] = { //No methods {NULL,NULL} //Sentinel @@ -302,18 +291,3 @@ PyAttributeDef KX_NearSensor::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 100, KX_NearSensor, m_ResetMargin, CheckResetDistance), {NULL} //Sentinel }; - - -PyObject* KX_NearSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_TouchSensor); -} - -PyObject* KX_NearSensor::py_getattro_dict() { - py_getattro_dict_up(KX_TouchSensor); -} - -int KX_NearSensor::py_setattro(PyObject*attr, PyObject* value) -{ - py_setattro_up(KX_TouchSensor); -} diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 63099e181a0..f3c1d74805c 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -54,8 +54,7 @@ public: bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, - PHY_IPhysicsController* ctrl, - PyTypeObject* T=&Type); + PHY_IPhysicsController* ctrl); /* public: KX_NearSensor(class SCA_EventManager* eventmgr, @@ -64,8 +63,7 @@ public: double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, - class KX_Scene* scene, - PyTypeObject* T=&Type); + class KX_Scene* scene); */ virtual ~KX_NearSensor(); virtual void SynchronizeTransform(); @@ -83,9 +81,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); //No methods diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index eaae04d406d..ae340d12be4 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -53,10 +53,9 @@ KX_ObjectActuator( const MT_Vector3& linV, const MT_Vector3& angV, const short damping, - const KX_LocalFlags& flag, - PyTypeObject* T + const KX_LocalFlags& flag ) : - SCA_IActuator(gameobj,T), + SCA_IActuator(gameobj), m_force(force), m_torque(torque), m_dloc(dloc), @@ -342,19 +341,15 @@ PyTypeObject KX_ObjectActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ObjectActuator::Parents[] = { - &KX_ObjectActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_ObjectActuator::Methods[] = { @@ -396,9 +391,14 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("useLocalDLoc", KX_ObjectActuator, m_bitLocalFlag.DLoc), KX_PYATTRIBUTE_VECTOR_RW_CHECK("dRot", -1000, 1000, false, KX_ObjectActuator, m_drot, PyUpdateFuzzyFlags), KX_PYATTRIBUTE_BOOL_RW("useLocalDRot", KX_ObjectActuator, m_bitLocalFlag.DRot), +#ifdef USE_MATHUTILS + KX_PYATTRIBUTE_RW_FUNCTION("linV", KX_ObjectActuator, pyattr_get_linV, pyattr_set_linV), + KX_PYATTRIBUTE_RW_FUNCTION("angV", KX_ObjectActuator, pyattr_get_angV, pyattr_set_angV), +#else KX_PYATTRIBUTE_VECTOR_RW_CHECK("linV", -1000, 1000, false, KX_ObjectActuator, m_linear_velocity, PyUpdateFuzzyFlags), - KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity), KX_PYATTRIBUTE_VECTOR_RW_CHECK("angV", -1000, 1000, false, KX_ObjectActuator, m_angular_velocity, PyUpdateFuzzyFlags), +#endif + KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity), KX_PYATTRIBUTE_BOOL_RW("useLocalAngV", KX_ObjectActuator, m_bitLocalFlag.AngularVelocity), KX_PYATTRIBUTE_SHORT_RW("damping", 0, 1000, false, KX_ObjectActuator, m_damping), KX_PYATTRIBUTE_RW_FUNCTION("forceLimitX", KX_ObjectActuator, pyattr_get_forceLimitX, pyattr_set_forceLimitX), @@ -409,21 +409,130 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); +/* Attribute get/set functions */ + +#ifdef USE_MATHUTILS + +/* These require an SGNode */ +#define MATHUTILS_VEC_CB_LINV 1 +#define MATHUTILS_VEC_CB_ANGV 2 + +static int mathutils_kxobactu_vector_cb_index= -1; /* index for our callbacks */ + +static int mathutils_obactu_generic_check(PyObject *self_v) +{ + KX_ObjectActuator* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + return 1; +} + +static int mathutils_obactu_vector_get(PyObject *self_v, int subtype, float *vec_from) +{ + KX_ObjectActuator* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_LINV: + self->m_linear_velocity.getValue(vec_from); + break; + case MATHUTILS_VEC_CB_ANGV: + self->m_angular_velocity.getValue(vec_from); + break; + } + + return 1; } +static int mathutils_obactu_vector_set(PyObject *self_v, int subtype, float *vec_to) +{ + KX_ObjectActuator* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_LINV: + self->m_linear_velocity.setValue(vec_to); + break; + case MATHUTILS_VEC_CB_ANGV: + self->m_angular_velocity.setValue(vec_to); + break; + } -PyObject* KX_ObjectActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); + return 1; } -int KX_ObjectActuator::py_setattro(PyObject *attr, PyObject *value) +static int mathutils_obactu_vector_get_index(PyObject *self_v, int subtype, float *vec_from, int index) { - py_setattro_up(SCA_IActuator); + float f[4]; + /* lazy, avoid repeteing the case statement */ + if(!mathutils_obactu_vector_get(self_v, subtype, f)) + return 0; + + vec_from[index]= f[index]; + return 1; } -/* Attribute get/set functions */ +static int mathutils_obactu_vector_set_index(PyObject *self_v, int subtype, float *vec_to, int index) +{ + float f= vec_to[index]; + + /* lazy, avoid repeteing the case statement */ + if(!mathutils_obactu_vector_get(self_v, subtype, vec_to)) + return 0; + + vec_to[index]= f; + mathutils_obactu_vector_set(self_v, subtype, vec_to); + + return 1; +} + +Mathutils_Callback mathutils_obactu_vector_cb = { + mathutils_obactu_generic_check, + mathutils_obactu_vector_get, + mathutils_obactu_vector_set, + mathutils_obactu_vector_get_index, + mathutils_obactu_vector_set_index +}; + +PyObject* KX_ObjectActuator::pyattr_get_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV); +} + +int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self= static_cast(self_v); + if (!PyVecTo(value, self->m_linear_velocity)) + return PY_SET_ATTR_FAIL; + + return PY_SET_ATTR_SUCCESS; +} + +PyObject* KX_ObjectActuator::pyattr_get_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV); +} + +int KX_ObjectActuator::pyattr_set_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self= static_cast(self_v); + if (!PyVecTo(value, self->m_angular_velocity)) + return PY_SET_ATTR_FAIL; + + return PY_SET_ATTR_SUCCESS; +} + + +void KX_ObjectActuator_Mathutils_Callback_Init(void) +{ + // register mathutils callbacks, ok to run more then once. + mathutils_kxobactu_vector_cb_index= Mathutils_RegisterCallback(&mathutils_obactu_vector_cb); +} + +#endif // USE_MATHUTILS PyObject* KX_ObjectActuator::pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -446,7 +555,7 @@ int KX_ObjectActuator::pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE { self->m_drot[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); self->m_dloc[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); - self->m_bitLocalFlag.Torque = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + self->m_bitLocalFlag.Torque = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)) != 0); if (!PyErr_Occurred()) { @@ -482,7 +591,7 @@ int KX_ObjectActuator::pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE { self->m_drot[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); self->m_dloc[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); - self->m_bitLocalFlag.DLoc = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + self->m_bitLocalFlag.DLoc = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)) != 0); if (!PyErr_Occurred()) { @@ -518,7 +627,7 @@ int KX_ObjectActuator::pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE { self->m_drot[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); self->m_dloc[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); - self->m_bitLocalFlag.DRot = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + self->m_bitLocalFlag.DRot = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)) != 0); if (!PyErr_Occurred()) { diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index f9bd2a0c748..20aec9e0e86 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -35,6 +35,10 @@ #include "SCA_IActuator.h" #include "MT_Vector3.h" +#ifdef USE_MATHUTILS +void KX_ObjectActuator_Mathutils_Callback_Init(void); +#endif + class KX_GameObject; // @@ -131,8 +135,7 @@ public: const MT_Vector3& linV, const MT_Vector3& angV, const short damping, - const KX_LocalFlags& flag, - PyTypeObject* T=&Type + const KX_LocalFlags& flag ); ~KX_ObjectActuator(); CValue* GetReplica(); @@ -159,10 +162,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce); KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForce); @@ -197,6 +196,13 @@ public: static PyObject* pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); +#ifdef USE_MATHUTILS + static PyObject* pyattr_get_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); +#endif + // This lets the attribute macros use UpdateFuzzyFlags() static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef) { diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp deleted file mode 100644 index dc6990267d4..00000000000 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include "KX_ConvertPhysicsObject.h" - -#ifdef USE_ODE - -#include "KX_OdePhysicsController.h" -#include "KX_GameObject.h" -#include "KX_MotionState.h" - -#include "MT_assert.h" - -#include "PHY_IPhysicsEnvironment.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -KX_OdePhysicsController::KX_OdePhysicsController( - bool dyna, - bool fullRigidBody, - bool phantom, - class PHY_IMotionState* motionstate, - struct dxSpace* space, - struct dxWorld* world, - float mass, - float friction, - float restitution, - bool implicitsphere, - float center[3], - float extends[3], - float radius - ) -: KX_IPhysicsController(dyna,false,(PHY_IPhysicsController*)this), -ODEPhysicsController( -dyna,fullRigidBody,phantom,motionstate, -space,world,mass,friction,restitution, -implicitsphere,center,extends,radius) -{ -}; - - -bool KX_OdePhysicsController::Update(double time) -{ - return SynchronizeMotionStates(time); -} - -void KX_OdePhysicsController::SetObject (SG_IObject* object) -{ - SG_Controller::SetObject(object); - - // cheating here... - KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); - gameobj->SetPhysicsController(this); - -} - - - -void KX_OdePhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) -{ - ODEPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); -} - - - -void KX_OdePhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) -{ - ODEPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); - -} -void KX_OdePhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) -{ - double oldmat[12]; - drot.getValue(oldmat); - float newmat[9]; - float *m = &newmat[0]; - double *orgm = &oldmat[0]; - - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - - ODEPhysicsController::RelativeRotate(newmat,local); - -} - -void KX_OdePhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) -{ - ODEPhysicsController::ApplyTorque(torque[0],torque[1],torque[2],local); - -} -void KX_OdePhysicsController::ApplyForce(const MT_Vector3& force,bool local) -{ - ODEPhysicsController::ApplyForce(force[0],force[1],force[2],local); - -} -MT_Vector3 KX_OdePhysicsController::GetLinearVelocity() -{ - return MT_Vector3(0,0,0); -} - -MT_Vector3 KX_OdePhysicsController::GetVelocity(const MT_Point3& pos) -{ - return MT_Vector3(0,0,0); -} - -void KX_OdePhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) -{ - -} -void KX_OdePhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) -{ - ODEPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local); -} - -void KX_OdePhysicsController::setOrientation(const MT_Matrix3x3& rot) -{ - MT_Quaternion orn = rot.getRotation(); - ODEPhysicsController::setOrientation(orn[0],orn[1],orn[2],orn[3]); -} - -void KX_OdePhysicsController::getOrientation(MT_Quaternion& orn) -{ - float florn[4]; - florn[0]=orn[0]; - florn[1]=orn[1]; - florn[2]=orn[2]; - florn[3]=orn[3]; - ODEPhysicsController::getOrientation(florn[0],florn[1],florn[2],florn[3]); - orn[0] = florn[0]; - orn[1] = florn[1]; - orn[2] = florn[2]; - orn[3] = florn[3]; - - -} - -void KX_OdePhysicsController::setPosition(const MT_Point3& pos) -{ - ODEPhysicsController::setPosition(pos[0],pos[1],pos[2]); -} - -void KX_OdePhysicsController::setScaling(const MT_Vector3& scaling) -{ -} - -MT_Scalar KX_OdePhysicsController::GetMass() -{ - return ODEPhysicsController::getMass(); -} - -MT_Scalar KX_OdePhysicsController::GetRadius() -{ - return MT_Scalar(0.f); -} - -MT_Vector3 KX_OdePhysicsController::getReactionForce() -{ - return MT_Vector3(0,0,0); -} -void KX_OdePhysicsController::setRigidBody(bool rigid) -{ - -} - -void KX_OdePhysicsController::SuspendDynamics(bool) -{ - ODEPhysicsController::SuspendDynamics(); -} -void KX_OdePhysicsController::RestoreDynamics() -{ - ODEPhysicsController::RestoreDynamics(); -} - - -SG_Controller* KX_OdePhysicsController::GetReplica(class SG_Node* destnode) -{ - PHY_IMotionState* motionstate = new KX_MotionState(destnode); - KX_OdePhysicsController* copyctrl = new KX_OdePhysicsController(*this); - - // nlin: copied from KX_SumoPhysicsController.cpp. Not 100% sure what this does.... - // furthermore, the parentctrl is not used in ODEPhysicsController::PostProcessReplica, but - // maybe it can/should be used in the future... - - // begin copy block ------------------------------------------------------------------ - - //parentcontroller is here be able to avoid collisions between parent/child - - PHY_IPhysicsController* parentctrl = NULL; - - if (destnode != destnode->GetRootSGParent()) - { - KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); - if (clientgameobj) - { - parentctrl = (KX_OdePhysicsController*)clientgameobj->GetPhysicsController(); - } else - { - // it could be a false node, try the children - NodeList::const_iterator childit; - for ( - childit = destnode->GetSGChildren().begin(); - childit!= destnode->GetSGChildren().end(); - ++childit - ) { - KX_GameObject* clientgameobj = static_cast( (*childit)->GetSGClientObject()); - if (clientgameobj) - { - parentctrl = (KX_OdePhysicsController*)clientgameobj->GetPhysicsController(); - } - } - } - } - // end copy block ------------------------------------------------------------------ - - copyctrl->PostProcessReplica(motionstate, this); - - return copyctrl; - -} - -void KX_OdePhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ -} - - -void KX_OdePhysicsController::SetSumoTransform(bool nondynaonly) -{ - -} - // todo: remove next line ! -void KX_OdePhysicsController::SetSimulatedTime(double time) -{ - -} - -#endif //USE_ODE diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h deleted file mode 100644 index 8c3974c38a3..00000000000 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __KX_ODEPHYSICSCONTROLLER_H -#define __KX_ODEPHYSICSCONTROLLER_H - -#include "KX_IPhysicsController.h" -#include "OdePhysicsController.h" - -/** - Physics Controller, a special kind of Scene Graph Transformation Controller. - It get's callbacks from Physics in case a transformation change took place. - Each time the scene graph get's updated, the controller get's a chance - in the 'Update' method to reflect changed. -*/ - -class KX_OdePhysicsController : public KX_IPhysicsController, public ODEPhysicsController - -{ - -public: - KX_OdePhysicsController( - bool dyna, - bool fullRigidBody, - bool phantom, - class PHY_IMotionState* motionstate, - struct dxSpace* space, - struct dxWorld* world, - float mass, - float friction, - float restitution, - bool implicitsphere, - float center[3], - float extends[3], - float radius); - - virtual ~KX_OdePhysicsController() {}; - - virtual void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse); - virtual void SetObject (SG_IObject* object); - - virtual void RelativeTranslate(const MT_Vector3& dloc,bool local); - virtual void RelativeRotate(const MT_Matrix3x3& drot,bool local); - virtual void ApplyTorque(const MT_Vector3& torque,bool local); - virtual void ApplyForce(const MT_Vector3& force,bool local); - virtual MT_Vector3 GetLinearVelocity(); - virtual MT_Vector3 GetVelocity(const MT_Point3& pos); - virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); - virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); - virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - virtual void getOrientation(MT_Quaternion& orn); - virtual void setOrientation(const MT_Matrix3x3& orn); - virtual void setPosition(const MT_Point3& pos); - virtual void setScaling(const MT_Vector3& scaling); - virtual void SetTransform() {} - virtual MT_Scalar GetMass(); - virtual MT_Vector3 getReactionForce(); - virtual void setRigidBody(bool rigid); - virtual void AddCompoundChild(KX_IPhysicsController* child) { } - virtual void RemoveCompoundChild(KX_IPhysicsController* child) { } - - virtual void SuspendDynamics(bool); - virtual void RestoreDynamics(); - virtual MT_Scalar GetRadius(); - - virtual SG_Controller* GetReplica(class SG_Node* destnode); - - virtual float GetLinVelocityMin() { return ODEPhysicsController::GetLinVelocityMin(); } - virtual void SetLinVelocityMin(float val) { ODEPhysicsController::SetLinVelocityMin(val); } - virtual float GetLinVelocityMax() { return ODEPhysicsController::GetLinVelocityMax(); } - virtual void SetLinVelocityMax(float val) { ODEPhysicsController::SetLinVelocityMax(val); } - - virtual void SetSumoTransform(bool nondynaonly); - // todo: remove next line ! - virtual void SetSimulatedTime(double time); - - // call from scene graph to update - virtual bool Update(double time); - - void - SetOption( - int option, - int value - ){ - // intentionally empty - }; - -}; - -#endif //__KX_ODEPHYSICSCONTROLLER_H - diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index cd2ed456c48..befa2aaff56 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -50,9 +50,8 @@ KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, int mode, bool addToCompound, bool ghost, - SCA_IObject *ob, - PyTypeObject* T) - : SCA_IActuator(gameobj, T), + SCA_IObject *ob) + : SCA_IActuator(gameobj), m_mode(mode), m_addToCompound(addToCompound), m_ghost(ghost), @@ -157,19 +156,15 @@ PyTypeObject KX_ParentActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ParentActuator::Parents[] = { - &KX_ParentActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_ParentActuator::Methods[] = { @@ -217,18 +212,6 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE } -PyObject* KX_ParentActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_ParentActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_ParentActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - /* Deprecated -----> */ /* 1. setObject */ const char KX_ParentActuator::SetObject_doc[] = @@ -273,7 +256,7 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_ob->GetName().ReadPtr()); + return PyUnicode_FromString(m_ob->GetName().ReadPtr()); else return m_ob->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index 148375e994c..aeb39eabf89 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -68,8 +68,7 @@ class KX_ParentActuator : public SCA_IActuator int mode, bool addToCompound, bool ghost, - SCA_IObject *ob, - PyTypeObject* T=&Type); + SCA_IObject *ob); virtual ~KX_ParentActuator(); virtual bool Update(); @@ -82,10 +81,6 @@ class KX_ParentActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - /* These are used to get and set m_ob */ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp index c968e50957e..7bce311f1b6 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp @@ -39,8 +39,8 @@ KX_PhysicsObjectWrapper::KX_PhysicsObjectWrapper( PHY_IPhysicsController* ctrl, - PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) : - PyObjectPlus(T), + PHY_IPhysicsEnvironment* physenv) : + PyObjectPlus(), m_ctrl(ctrl), m_physenv(physenv) { @@ -129,46 +129,17 @@ PyTypeObject KX_PhysicsObjectWrapper::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_PhysicsObjectWrapper::Parents[] = { - &KX_PhysicsObjectWrapper::Type, - NULL -}; - -PyObject* KX_PhysicsObjectWrapper::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_PhysicsObjectWrapper::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_PhysicsObjectWrapper::py_setattro(PyObject *attr,PyObject *pyobj) -{ - int result = 1; - - if (PyInt_Check(pyobj)) - { - result = 0; - } - if (PyString_Check(pyobj)) - { - result = 0; - } - if (result) - result = PyObjectPlus::py_setattro(attr,pyobj); - - return result; + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef KX_PhysicsObjectWrapper::Methods[] = { {"setPosition",(PyCFunction) KX_PhysicsObjectWrapper::sPySetPosition, METH_VARARGS}, {"setLinearVelocity",(PyCFunction) KX_PhysicsObjectWrapper::sPySetLinearVelocity, METH_VARARGS}, diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h index 1b59686babc..fa6fd1d1f2a 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -35,12 +35,8 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus { Py_Header; - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); public: - KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_PhysicsObjectWrapper(); KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetPosition); diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index b56b5500c39..a1571b17756 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -55,18 +55,15 @@ PyTypeObject KX_PolyProxy::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_PolyProxy::Parents[] = { - &KX_PolyProxy::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - &PyObjectPlus::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_PolyProxy::Methods[] = { @@ -98,16 +95,17 @@ PyAttributeDef KX_PolyProxy::Attributes[] = { { NULL } //Sentinel }; +#if 0 PyObject* KX_PolyProxy::py_getattro(PyObject *attr) { - char *attr_str= PyString_AsString(attr); + char *attr_str= _PyUnicode_AsString(attr); if (!strcmp(attr_str, "matname")) { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); } if (!strcmp(attr_str, "texture")) { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); } if (!strcmp(attr_str, "material")) { @@ -136,38 +134,35 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr) // found it break; } - return PyInt_FromLong(matid); + return PyLong_FromSsize_t(matid); } if (!strcmp(attr_str, "v1")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(0)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(0)); } if (!strcmp(attr_str, "v2")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(1)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(1)); } if (!strcmp(attr_str, "v3")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(2)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(2)); } if (!strcmp(attr_str, "v4")) { - return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0)); + return PyLong_FromSsize_t(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0)); } if (!strcmp(attr_str, "visible")) { - return PyInt_FromLong(m_polygon->IsVisible()); + return PyLong_FromSsize_t(m_polygon->IsVisible()); } if (!strcmp(attr_str, "collide")) { - return PyInt_FromLong(m_polygon->IsCollider()); + return PyLong_FromSsize_t(m_polygon->IsCollider()); } - py_getattro_up(CValue); -} - -PyObject* KX_PolyProxy::py_getattro_dict() { - py_getattro_dict_up(CValue); + // py_getattro_up(CValue); // XXX -- todo, make all these attributes } +#endif KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon) : m_polygon(polygon), @@ -204,37 +199,37 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex, // found it break; } - return PyInt_FromLong(matid); + return PyLong_FromSsize_t(matid); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getNumVertex, "getNumVertex() : returns the number of vertex of the polygon, 3 or 4\n") { - return PyInt_FromLong(m_polygon->VertexCount()); + return PyLong_FromSsize_t(m_polygon->VertexCount()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isVisible, "isVisible() : returns whether the polygon is visible or not\n") { - return PyInt_FromLong(m_polygon->IsVisible()); + return PyLong_FromSsize_t(m_polygon->IsVisible()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isCollider, "isCollider() : returns whether the polygon is receives collision or not\n") { - return PyInt_FromLong(m_polygon->IsCollider()); + return PyLong_FromSsize_t(m_polygon->IsCollider()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialName, "getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n") { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getTextureName, "getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n") { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); } KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex, @@ -255,9 +250,9 @@ KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex, } if (index < m_polygon->VertexCount()) { - return PyInt_FromLong(m_polygon->GetVertexOffset(index)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(index)); } - return PyInt_FromLong(0); + return PyLong_FromSsize_t(0); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh, diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index d8fd36fec6c..e619617d312 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -52,8 +52,6 @@ public: // stuff for python integration - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialIndex) KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getNumVertex) diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 506c167a905..9bc84127572 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -51,8 +51,8 @@ #include "KX_PyMath.h" -KX_PolygonMaterial::KX_PolygonMaterial(PyTypeObject *T) - : PyObjectPlus(T), +KX_PolygonMaterial::KX_PolygonMaterial() + : PyObjectPlus(), RAS_IPolyMaterial(), m_tface(NULL), @@ -115,7 +115,7 @@ bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingI PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this->m_proxy); if (ret) { - bool value = PyInt_AsLong(ret); + bool value = PyLong_AsSsize_t(ret); Py_DECREF(ret); dopass = value; } @@ -255,33 +255,17 @@ PyTypeObject KX_PolygonMaterial::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_PolygonMaterial::Parents[] = { - &KX_PolygonMaterial::Type, - &PyObjectPlus::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; -PyObject* KX_PolygonMaterial::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_PolygonMaterial::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_PolygonMaterial::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(PyObjectPlus); -} - KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(material)") { PyObject *material; @@ -347,13 +331,13 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)") PyObject* KX_PolygonMaterial::pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_PolygonMaterial* self= static_cast(self_v); - return PyString_FromString(self->m_texturename.ReadPtr()); + return PyUnicode_FromString(self->m_texturename.ReadPtr()); } PyObject* KX_PolygonMaterial::pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_PolygonMaterial* self= static_cast(self_v); - return PyString_FromString(self->m_materialname.ReadPtr()); + return PyUnicode_FromString(self->m_materialname.ReadPtr()); } /* this does not seem useful */ @@ -370,7 +354,7 @@ PyObject* KX_PolygonMaterial::pyattr_get_gl_texture(void *self_v, const KX_PYATT if (self->m_tface && self->m_tface->tpage) bindcode= self->m_tface->tpage->bindcode; - return PyInt_FromLong(bindcode); + return PyLong_FromSsize_t(bindcode); } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 89ecb026da9..266b4d7e789 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -57,7 +57,7 @@ private: mutable int m_pass; public: - KX_PolygonMaterial(PyTypeObject *T = &Type); + KX_PolygonMaterial(); void Initialize(const STR_String &texname, Material* ma, int materialindex, @@ -116,10 +116,7 @@ public: KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial); KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram); - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); - virtual PyObject* py_repr(void) { return PyString_FromString(m_material ? ((ID *)m_material)->name+2 : ""); } + virtual PyObject* py_repr(void) { return PyUnicode_FromString(m_material ? ((ID *)m_material)->name+2 : ""); } static PyObject* pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 4ec901a2f5e..94e8d1fd583 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -640,7 +640,7 @@ PyObject* initPythonConstraintBinding() // Add some symbolic constants to the module d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("PhysicsConstraints.error"); + ErrorObject = PyUnicode_FromString("PhysicsConstraints.error"); PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index 051d7ae7dba..6d33c38190c 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -46,35 +46,6 @@ #include "KX_Python.h" #include "KX_PyMath.h" -bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) -{ - if (!pymat) - return false; - - unsigned int y; - if (PySequence_Check(pymat)) - { - unsigned int rows = PySequence_Size(pymat); - if (rows != rank) - return false; - - bool ismatrix = true; - for (y = 0; y < rank && ismatrix; y++) - { - PyObject *pyrow = PySequence_GetItem(pymat, y); /* new ref */ - if (PySequence_Check(pyrow)) - { - if (((unsigned int)PySequence_Size(pyrow)) != rank) - ismatrix = false; - } else - ismatrix = false; - Py_DECREF(pyrow); - } - return ismatrix; - } - return false; -} - bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefix) { int size= PySequence_Size(pyval); @@ -82,7 +53,7 @@ bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefi if (size == 4) { MT_Quaternion qrot; - if (PyVecTo(pyval, qrot)) + if (PyQuatTo(pyval, qrot)) { rot.setRotation(qrot); return true; @@ -108,14 +79,27 @@ bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefi return false; } +bool PyQuatTo(PyObject* pyval, MT_Quaternion &qrot) +{ + if(!PyVecTo(pyval, qrot)) + return false; + + /* annoying!, Blender/Mathutils have the W axis first! */ + MT_Scalar w= qrot[0]; /* from python, this is actually the W */ + qrot[0]= qrot[1]; + qrot[1]= qrot[2]; + qrot[2]= qrot[3]; + qrot[3]= w; + + return true; +} + PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) { -#if 0 - return Py_BuildValue("[[ffff][ffff][ffff][ffff]]", - mat[0][0], mat[0][1], mat[0][2], mat[0][3], - mat[1][0], mat[1][1], mat[1][2], mat[1][3], - mat[2][0], mat[2][1], mat[2][2], mat[2][3], - mat[3][0], mat[3][1], mat[3][2], mat[3][3]); +#ifdef USE_MATHUTILS + float fmat[16]; + mat.getValue(fmat); + return newMatrixObject(fmat, 4, 4, Py_NEW, NULL); #else PyObject *list = PyList_New(4); PyObject *sublist; @@ -136,11 +120,10 @@ PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) PyObject* PyObjectFrom(const MT_Matrix3x3 &mat) { -#if 0 - return Py_BuildValue("[[fff][fff][fff]]", - mat[0][0], mat[0][1], mat[0][2], - mat[1][0], mat[1][1], mat[1][2], - mat[2][0], mat[2][1], mat[2][2]); +#ifdef USE_MATHUTILS + float fmat[9]; + mat.getValue3x3(fmat); + return newMatrixObject(fmat, 3, 3, Py_NEW, NULL); #else PyObject *list = PyList_New(3); PyObject *sublist; @@ -158,11 +141,20 @@ PyObject* PyObjectFrom(const MT_Matrix3x3 &mat) #endif } +#ifdef USE_MATHUTILS +PyObject* PyObjectFrom(const MT_Quaternion &qrot) +{ + /* NOTE, were re-ordering here for Mathutils compat */ + float fvec[4]= {qrot[3], qrot[0], qrot[1], qrot[2]}; + return newQuaternionObject(fvec, Py_WRAP, NULL); +} +#endif + PyObject* PyObjectFrom(const MT_Tuple4 &vec) { -#if 0 - return Py_BuildValue("[ffff]", - vec[0], vec[1], vec[2], vec[3]); +#ifdef USE_MATHUTILS + float fvec[4]= {vec[0], vec[1], vec[2], vec[3]}; + return newVectorObject(fvec, 4, Py_WRAP, NULL); #else PyObject *list = PyList_New(4); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); @@ -175,9 +167,9 @@ PyObject* PyObjectFrom(const MT_Tuple4 &vec) PyObject* PyObjectFrom(const MT_Tuple3 &vec) { -#if 0 - return Py_BuildValue("[fff]", - vec[0], vec[1], vec[2]); +#ifdef USE_MATHUTILS + float fvec[3]= {vec[0], vec[1], vec[2]}; + return newVectorObject(fvec, 3, Py_WRAP, NULL); #else PyObject *list = PyList_New(3); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); @@ -189,9 +181,9 @@ PyObject* PyObjectFrom(const MT_Tuple3 &vec) PyObject* PyObjectFrom(const MT_Tuple2 &vec) { -#if 0 - return Py_BuildValue("[ff]", - vec[0], vec[1]); +#ifdef USE_MATHUTILS + float fvec[2]= {vec[0], vec[1]}; + return newVectorObject(fvec, 2, Py_WRAP, NULL); #else PyObject *list = PyList_New(2); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index a7ce4bc6930..9ee11c9e745 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -42,6 +42,12 @@ #include "KX_Python.h" #include "PyObjectPlus.h" +#ifdef USE_MATHUTILS +extern "C" { +#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */ +} +#endif + inline unsigned int Size(const MT_Matrix4x4&) { return 4; } inline unsigned int Size(const MT_Matrix3x3&) { return 3; } inline unsigned int Size(const MT_Tuple2&) { return 2; } @@ -98,7 +104,38 @@ bool PyMatTo(PyObject* pymat, T& mat) template bool PyVecTo(PyObject* pyval, T& vec) { - +#ifdef USE_MATHUTILS + /* no need for BaseMath_ReadCallback() here, reading the sequences will do this */ + + if(VectorObject_Check(pyval)) { + VectorObject *pyvec= (VectorObject *)pyval; + if (pyvec->size != Size(vec)) { + PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", pyvec->size, Size(vec)); + return false; + } + vec.getValue((float *) pyvec->vec); + return true; + } + else if(QuaternionObject_Check(pyval)) { + QuaternionObject *pyquat= (QuaternionObject *)pyval; + if (4 != Size(vec)) { + PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 4, Size(vec)); + return false; + } + /* xyzw -> wxyz reordering is done by PyQuatTo */ + vec.getValue((float *) pyquat->quat); + return true; + } + else if(EulerObject_Check(pyval)) { + EulerObject *pyeul= (EulerObject *)pyval; + if (3 != Size(vec)) { + PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 3, Size(vec)); + return false; + } + vec.getValue((float *) pyeul->eul); + return true; + } else +#endif if(PyTuple_Check(pyval)) { unsigned int numitems = PyTuple_GET_SIZE(pyval); @@ -117,7 +154,7 @@ bool PyVecTo(PyObject* pyval, T& vec) return true; } - else if (BGE_PROXY_CHECK_TYPE(pyval)) + else if (PyObject_TypeCheck(pyval, &PyObjectPlus::Type)) { /* note, include this check because PySequence_Check does too much introspection * on the PyObject (like getting its __class__, on a BGE type this means searching up * the parent list each time only to discover its not a sequence. @@ -159,6 +196,9 @@ bool PyVecTo(PyObject* pyval, T& vec) return false; } + +bool PyQuatTo(PyObject* pyval, MT_Quaternion &qrot); + bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix); /** @@ -181,15 +221,16 @@ PyObject* PyObjectFrom(const MT_Tuple2 &vec); */ PyObject* PyObjectFrom(const MT_Tuple3 &vec); +#ifdef USE_MATHUTILS /** - * Converts an MT_Tuple4 to a python object. + * Converts an MT_Quaternion to a python object. */ -PyObject* PyObjectFrom(const MT_Tuple4 &pos); +PyObject* PyObjectFrom(const MT_Quaternion &qrot); +#endif /** - * True if the given PyObject can be converted to an MT_Matrix - * @param rank = 3 (for MT_Matrix3x3) or 4 (for MT_Matrix4x4) + * Converts an MT_Tuple4 to a python object. */ -bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank); +PyObject* PyObjectFrom(const MT_Tuple4 &pos); #endif diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 736460d33db..eead7a51885 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -130,10 +130,10 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons } /* Macro for building the keyboard translation */ -//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name)) -#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name)); Py_DECREF(item) +//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromSsize_t(SCA_IInputDevice::KX_##name)) +#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name)); Py_DECREF(item) /* For the defines for types from logic bricks, we do stuff explicitly... */ -#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name2)); Py_DECREF(item) +#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name2)); Py_DECREF(item) // temporarily python stuff, will be put in another place later ! @@ -181,7 +181,7 @@ static PyObject* gPyExpandPath(PyObject*, PyObject* args) BLI_strncpy(expanded, filename, FILE_MAXDIR + FILE_MAXFILE); BLI_convertstringcode(expanded, gp_GamePythonPath); - return PyString_FromString(expanded); + return PyUnicode_FromString(expanded); } static char gPySendMessage_doc[] = @@ -306,7 +306,7 @@ static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args) static PyObject* gPyGetMaxLogicFrame(PyObject*) { - return PyInt_FromLong(KX_KetsjiEngine::GetMaxLogicFrame()); + return PyLong_FromSsize_t(KX_KetsjiEngine::GetMaxLogicFrame()); } static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args) @@ -321,7 +321,7 @@ static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args) static PyObject* gPyGetMaxPhysicsFrame(PyObject*) { - return PyInt_FromLong(KX_KetsjiEngine::GetMaxPhysicsFrame()); + return PyLong_FromSsize_t(KX_KetsjiEngine::GetMaxPhysicsFrame()); } static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args) @@ -386,7 +386,7 @@ static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args) while ((dirp = readdir(dp)) != NULL) { if (BLI_testextensie(dirp->d_name, ".blend")) { - value = PyString_FromString(dirp->d_name); + value = PyUnicode_FromString(dirp->d_name); PyList_Append(list, value); Py_DECREF(value); } @@ -500,7 +500,7 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) static PyObject *gEvalExpression(PyObject*, PyObject* value) { - char* txt= PyString_AsString(value); + char* txt= _PyUnicode_AsString(value); if (txt==NULL) { PyErr_SetString(PyExc_TypeError, "Expression.calc(text): expects a single string argument"); @@ -558,14 +558,14 @@ static struct PyMethodDef game_methods[] = { static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args) { - return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetHeight() : 0)); + return PyLong_FromSsize_t((gp_Canvas ? gp_Canvas->GetHeight() : 0)); } static PyObject* gPyGetWindowWidth(PyObject*, PyObject* args) { - return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetWidth() : 0)); + return PyLong_FromSsize_t((gp_Canvas ? gp_Canvas->GetWidth() : 0)); } @@ -893,7 +893,7 @@ static PyObject* gPyGetGLSLMaterialSetting(PyObject*, } enabled = ((G.fileflags & flag) != 0); - return PyInt_FromLong(enabled); + return PyLong_FromSsize_t(enabled); } #define KX_TEXFACE_MATERIAL 0 @@ -937,7 +937,7 @@ static PyObject* gPyGetMaterialType(PyObject*) else flag = KX_TEXFACE_MATERIAL; - return PyInt_FromLong(flag); + return PyLong_FromSsize_t(flag); } static PyObject* gPyDrawLine(PyObject*, PyObject* args) @@ -1075,7 +1075,7 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack PyDict_SetItemString(d, "globalDict", item=PyDict_New()); Py_DECREF(item); - ErrorObject = PyString_FromString("GameLogic.error"); + ErrorObject = PyUnicode_FromString("GameLogic.error"); PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); @@ -1362,7 +1362,7 @@ PyObject *KXpy_import(PyObject *self, PyObject *args) /* check for builtin modules */ m = PyImport_AddModule("sys"); l = PyObject_GetAttrString(m, "builtin_module_names"); - n = PyString_FromString(name); + n = PyUnicode_FromString(name); if (PySequence_Contains(l, n)) { return PyImport_ImportModuleEx(name, globals, locals, fromlist); @@ -1538,7 +1538,7 @@ static void initPySysObjects__append(PyObject *sys_path, char *filename) BLI_split_dirfile_basic(filename, expanded, NULL); /* get the dir part of filename only */ BLI_convertstringcode(expanded, gp_GamePythonPath); /* filename from lib->filename is (always?) absolute, so this may not be needed but it wont hurt */ BLI_cleanup_file(gp_GamePythonPath, expanded); /* Dont use BLI_cleanup_dir because it adds a slash - BREAKS WIN32 ONLY */ - item= PyString_FromString(expanded); + item= PyUnicode_FromString(expanded); // printf("SysPath - '%s', '%s', '%s'\n", expanded, filename, gp_GamePythonPath); @@ -1735,7 +1735,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) // Add some symbolic constants to the module d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("Rasterizer.error"); + ErrorObject = PyUnicode_FromString("Rasterizer.error"); PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); @@ -1813,10 +1813,10 @@ static PyObject* gPyEventToCharacter(PyObject*, PyObject* args) if(IsPrintable(event)) { char ch[2] = {'\0', '\0'}; ch[0] = ToCharacter(event, (bool)shift); - return PyString_FromString(ch); + return PyUnicode_FromString(ch); } else { - return PyString_FromString(""); + return PyUnicode_FromString(""); } } @@ -2044,7 +2044,7 @@ int saveGamePythonConfig( char **marshal_buffer) char *marshal_cstring; #if PY_VERSION_HEX < 0x03000000 - marshal_cstring = PyString_AsString(pyGlobalDictMarshal); + marshal_cstring = _PyUnicode_AsString(pyGlobalDictMarshal); marshal_length= PyString_Size(pyGlobalDictMarshal); #else // py3 uses byte arrays marshal_cstring = PyBytes_AsString(pyGlobalDictMarshal); diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 83c4dcbb34c..8ff0bfd5379 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -87,69 +87,54 @@ #include "SCA_RandomActuator.h" #include "SCA_IController.h" - -void initPyObjectPlusType(PyTypeObject **parents) +static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes, int init_getset) { - int i; - - for (i=0; parents[i]; i++) { - if(PyType_Ready(parents[i]) < 0) { - /* This is very very unlikely */ - printf("Error, pytype could not initialize, Blender may crash \"%s\"\n", parents[i]->tp_name); - return; - } + PyAttributeDef *attr; -#if 0 - PyObject_Print(reinterpret_castparents[i], stderr, 0); - fprintf(stderr, "\n"); - PyObject_Print(parents[i]->tp_dict, stderr, 0); - fprintf(stderr, "\n\n"); -#endif + if(init_getset) { + /* we need to do this for all types before calling PyType_Ready + * since they will call the parents PyType_Ready and those might not have initialized vars yet */ - } + //if(tp->tp_base==NULL) + // printf("Debug: No Parents - '%s'\n" , tp->tp_name); - PyObject *dict= NULL; + if(tp->tp_getset==NULL && attributes->m_name) { + PyGetSetDef *attr_getset; + int attr_tot= 0; - while(i) { - i--; + for(attr= attributes; attr->m_name; attr++, attr_tot++) {}; - if (dict) { - PyDict_Update(parents[i]->tp_dict, dict); - } - dict= parents[i]->tp_dict; + tp->tp_getset = attr_getset = reinterpret_cast(PyMem_Malloc((attr_tot+1) * sizeof(PyGetSetDef))); // XXX - Todo, free -#if 1 - PyObject_Print(reinterpret_cast(parents[i]), stderr, 0); - fprintf(stderr, "\n"); - PyObject_Print(parents[i]->tp_dict, stderr, 0); - fprintf(stderr, "\n\n"); -#endif - } -} + for(attr= attributes; attr->m_name; attr++, attr_getset++) { + attr_getset->name= (char *)attr->m_name; + attr_getset->doc= NULL; + attr_getset->get= reinterpret_cast(PyObjectPlus::py_get_attrdef); + if(attr->m_access==KX_PYATTRIBUTE_RO) + attr_getset->set= NULL; + else + attr_getset->set= reinterpret_cast(PyObjectPlus::py_set_attrdef); + attr_getset->closure= reinterpret_cast(attr); + } -static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes) -{ - PyAttributeDef *attr; - PyObject *item; - - PyType_Ready(tp); - PyDict_SetItemString(dict, tp->tp_name, reinterpret_cast(tp)); + memset(attr_getset, 0, sizeof(PyGetSetDef)); + } + } else { - /* store attr defs in the tp_dict for to avoid string lookups */ - for(attr= attributes; attr->m_name; attr++) { - item= PyCObject_FromVoidPtr(attr, NULL); - PyDict_SetItemString(tp->tp_dict, attr->m_name, item); - Py_DECREF(item); + PyObject *item; + + PyType_Ready(tp); + PyDict_SetItemString(dict, tp->tp_name, reinterpret_cast(tp)); } } -#define PyType_Ready_Attr(d, n) PyType_Ready_ADD(d, &n::Type, n::Attributes) +#define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, i) void initPyTypes(void) { @@ -165,72 +150,82 @@ void initPyTypes(void) PyDict_SetItemString(PySys_GetObject((char *)"modules"), (char *)"GameTypes", mod); Py_DECREF(mod); - PyType_Ready_Attr(dict, BL_ActionActuator); - PyType_Ready_Attr(dict, BL_Shader); - PyType_Ready_Attr(dict, BL_ShapeActionActuator); - PyType_Ready_Attr(dict, CListValue); - PyType_Ready_Attr(dict, CValue); - PyType_Ready_Attr(dict, KX_BlenderMaterial); - PyType_Ready_Attr(dict, KX_CDActuator); - PyType_Ready_Attr(dict, KX_Camera); - PyType_Ready_Attr(dict, KX_CameraActuator); - PyType_Ready_Attr(dict, KX_ConstraintActuator); - PyType_Ready_Attr(dict, KX_ConstraintWrapper); - PyType_Ready_Attr(dict, KX_GameActuator); - PyType_Ready_Attr(dict, KX_GameObject); - PyType_Ready_Attr(dict, KX_IpoActuator); - PyType_Ready_Attr(dict, KX_LightObject); - PyType_Ready_Attr(dict, KX_MeshProxy); - PyType_Ready_Attr(dict, KX_MouseFocusSensor); - PyType_Ready_Attr(dict, KX_NearSensor); - PyType_Ready_Attr(dict, KX_NetworkMessageActuator); - PyType_Ready_Attr(dict, KX_NetworkMessageSensor); - PyType_Ready_Attr(dict, KX_ObjectActuator); - PyType_Ready_Attr(dict, KX_ParentActuator); - PyType_Ready_Attr(dict, KX_PhysicsObjectWrapper); - PyType_Ready_Attr(dict, KX_PolyProxy); - PyType_Ready_Attr(dict, KX_PolygonMaterial); - PyType_Ready_Attr(dict, KX_RadarSensor); - PyType_Ready_Attr(dict, KX_RaySensor); - PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator); - PyType_Ready_Attr(dict, KX_SCA_DynamicActuator); - PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator); - PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator); - PyType_Ready_Attr(dict, KX_Scene); - PyType_Ready_Attr(dict, KX_SceneActuator); - PyType_Ready_Attr(dict, KX_SoundActuator); - PyType_Ready_Attr(dict, KX_StateActuator); - PyType_Ready_Attr(dict, KX_TouchSensor); - PyType_Ready_Attr(dict, KX_TrackToActuator); - PyType_Ready_Attr(dict, KX_VehicleWrapper); - PyType_Ready_Attr(dict, KX_VertexProxy); - PyType_Ready_Attr(dict, KX_VisibilityActuator); - PyType_Ready_Attr(dict, PyObjectPlus); - PyType_Ready_Attr(dict, SCA_2DFilterActuator); - PyType_Ready_Attr(dict, SCA_ANDController); - PyType_Ready_Attr(dict, SCA_ActuatorSensor); - PyType_Ready_Attr(dict, SCA_AlwaysSensor); - PyType_Ready_Attr(dict, SCA_DelaySensor); - PyType_Ready_Attr(dict, SCA_ILogicBrick); - PyType_Ready_Attr(dict, SCA_IObject); - PyType_Ready_Attr(dict, SCA_ISensor); - PyType_Ready_Attr(dict, SCA_JoystickSensor); - PyType_Ready_Attr(dict, SCA_KeyboardSensor); - PyType_Ready_Attr(dict, SCA_MouseSensor); - PyType_Ready_Attr(dict, SCA_NANDController); - PyType_Ready_Attr(dict, SCA_NORController); - PyType_Ready_Attr(dict, SCA_ORController); - PyType_Ready_Attr(dict, SCA_PropertyActuator); - PyType_Ready_Attr(dict, SCA_PropertySensor); - PyType_Ready_Attr(dict, SCA_PythonController); - PyType_Ready_Attr(dict, SCA_RandomActuator); - PyType_Ready_Attr(dict, SCA_RandomSensor); - PyType_Ready_Attr(dict, SCA_XNORController); - PyType_Ready_Attr(dict, SCA_XORController); - PyType_Ready_Attr(dict, SCA_IController); + for(int init_getset= 1; init_getset > -1; init_getset--) { /* run twice, once to init the getsets another to run PyType_Ready */ + PyType_Ready_Attr(dict, BL_ActionActuator, init_getset); + PyType_Ready_Attr(dict, BL_Shader, init_getset); + PyType_Ready_Attr(dict, BL_ShapeActionActuator, init_getset); + PyType_Ready_Attr(dict, CListValue, init_getset); + PyType_Ready_Attr(dict, CValue, init_getset); + PyType_Ready_Attr(dict, KX_BlenderMaterial, init_getset); + PyType_Ready_Attr(dict, KX_CDActuator, init_getset); + PyType_Ready_Attr(dict, KX_Camera, init_getset); + PyType_Ready_Attr(dict, KX_CameraActuator, init_getset); + PyType_Ready_Attr(dict, KX_ConstraintActuator, init_getset); + PyType_Ready_Attr(dict, KX_ConstraintWrapper, init_getset); + PyType_Ready_Attr(dict, KX_GameActuator, init_getset); + PyType_Ready_Attr(dict, KX_GameObject, init_getset); + PyType_Ready_Attr(dict, KX_IpoActuator, init_getset); + PyType_Ready_Attr(dict, KX_LightObject, init_getset); + PyType_Ready_Attr(dict, KX_MeshProxy, init_getset); + PyType_Ready_Attr(dict, KX_MouseFocusSensor, init_getset); + PyType_Ready_Attr(dict, KX_NearSensor, init_getset); + PyType_Ready_Attr(dict, KX_NetworkMessageActuator, init_getset); + PyType_Ready_Attr(dict, KX_NetworkMessageSensor, init_getset); + PyType_Ready_Attr(dict, KX_ObjectActuator, init_getset); + PyType_Ready_Attr(dict, KX_ParentActuator, init_getset); + PyType_Ready_Attr(dict, KX_PhysicsObjectWrapper, init_getset); + PyType_Ready_Attr(dict, KX_PolyProxy, init_getset); + PyType_Ready_Attr(dict, KX_PolygonMaterial, init_getset); + PyType_Ready_Attr(dict, KX_RadarSensor, init_getset); + PyType_Ready_Attr(dict, KX_RaySensor, init_getset); + PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator, init_getset); + PyType_Ready_Attr(dict, KX_SCA_DynamicActuator, init_getset); + PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator, init_getset); + PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator, init_getset); + PyType_Ready_Attr(dict, KX_Scene, init_getset); + PyType_Ready_Attr(dict, KX_SceneActuator, init_getset); + PyType_Ready_Attr(dict, KX_SoundActuator, init_getset); + PyType_Ready_Attr(dict, KX_StateActuator, init_getset); + PyType_Ready_Attr(dict, KX_TouchSensor, init_getset); + PyType_Ready_Attr(dict, KX_TrackToActuator, init_getset); + PyType_Ready_Attr(dict, KX_VehicleWrapper, init_getset); + PyType_Ready_Attr(dict, KX_VertexProxy, init_getset); + PyType_Ready_Attr(dict, KX_VisibilityActuator, init_getset); + PyType_Ready_Attr(dict, PyObjectPlus, init_getset); + PyType_Ready_Attr(dict, SCA_2DFilterActuator, init_getset); + PyType_Ready_Attr(dict, SCA_ANDController, init_getset); + PyType_Ready_Attr(dict, SCA_ActuatorSensor, init_getset); + PyType_Ready_Attr(dict, SCA_AlwaysSensor, init_getset); + PyType_Ready_Attr(dict, SCA_DelaySensor, init_getset); + PyType_Ready_Attr(dict, SCA_ILogicBrick, init_getset); + PyType_Ready_Attr(dict, SCA_IObject, init_getset); + PyType_Ready_Attr(dict, SCA_ISensor, init_getset); + PyType_Ready_Attr(dict, SCA_JoystickSensor, init_getset); + PyType_Ready_Attr(dict, SCA_KeyboardSensor, init_getset); + PyType_Ready_Attr(dict, SCA_MouseSensor, init_getset); + PyType_Ready_Attr(dict, SCA_NANDController, init_getset); + PyType_Ready_Attr(dict, SCA_NORController, init_getset); + PyType_Ready_Attr(dict, SCA_ORController, init_getset); + PyType_Ready_Attr(dict, SCA_PropertyActuator, init_getset); + PyType_Ready_Attr(dict, SCA_PropertySensor, init_getset); + PyType_Ready_Attr(dict, SCA_PythonController, init_getset); + PyType_Ready_Attr(dict, SCA_RandomActuator, init_getset); + PyType_Ready_Attr(dict, SCA_RandomSensor, init_getset); + PyType_Ready_Attr(dict, SCA_XNORController, init_getset); + PyType_Ready_Attr(dict, SCA_XORController, init_getset); + PyType_Ready_Attr(dict, SCA_IController, init_getset); + } + + /* Normal python type */ PyType_Ready(&KX_PythonSeq_Type); + +#ifdef USE_MATHUTILS + /* Init mathutils callbacks */ + KX_GameObject_Mathutils_Callback_Init(); + KX_ObjectActuator_Mathutils_Callback_Init(); +#endif } -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 524d957a80c..5b4d77156db 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -221,11 +221,11 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) return NULL; } - if (PyInt_Check(key)) { - return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key )); + if (PyLong_Check(key)) { + return KX_PythonSeq_getIndex(self, PyLong_AsSsize_t( key )); } - else if ( PyString_Check(key) ) { - char *name = PyString_AsString(key); + else if ( PyUnicode_Check(key) ) { + char *name = _PyUnicode_AsString(key); PyObjectPlus *ret = KX_PythonSeq_subscript__internal(self, name); if(ret) { @@ -250,12 +250,12 @@ static int KX_PythonSeq_contains(PyObject *self, PyObject *key) PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: "BGE_PROXY_ERROR_MSG); return -1; } - if(!PyString_Check(key)) { + if(!PyUnicode_Check(key)) { PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: key must be a string"); return -1; } - if(KX_PythonSeq_subscript__internal(self, PyString_AsString(key))) + if(KX_PythonSeq_subscript__internal(self, _PyUnicode_AsString(key))) return 1; return 0; diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 064dc9126ac..e39d3756b71 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -49,8 +49,7 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, - class KX_Scene* kxscene, - PyTypeObject* T) + class KX_Scene* kxscene) : KX_NearSensor( eventmgr, @@ -61,8 +60,8 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, bFindMaterial, touchedpropname, kxscene, - physCtrl, - T), + physCtrl), + m_coneradius(coneradius), m_coneheight(coneheight), m_axis(axis) @@ -245,21 +244,15 @@ PyTypeObject KX_RadarSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_RadarSensor::Parents[] = { - &KX_RadarSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &KX_NearSensor::Type, - &KX_TouchSensor::Type, - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_RadarSensor::Methods[] = { @@ -283,16 +276,3 @@ PyAttributeDef KX_RadarSensor::Attributes[] = { {NULL} //Sentinel }; -PyObject* KX_RadarSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_NearSensor); -} - -PyObject* KX_RadarSensor::py_getattro_dict() { - py_getattro_dict_up(KX_NearSensor); -} - -int KX_RadarSensor::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(KX_NearSensor); -} diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 2e5a0e68bed..344be0e399f 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -70,8 +70,7 @@ public: double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, - class KX_Scene* kxscene, - PyTypeObject* T = &Type); + class KX_Scene* kxscene); KX_RadarSensor(); virtual ~KX_RadarSensor(); virtual void SynchronizeTransform(); @@ -89,9 +88,7 @@ public: KX_RADAR_AXIS_NEG_Z }; - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); + /* python */ virtual sensortype GetSensorType() { return ST_RADAR; } //Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 78a61e9d95e..3f27496df71 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -55,9 +55,8 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr, bool bXRay, double distance, int axis, - KX_Scene* ketsjiScene, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + KX_Scene* ketsjiScene) + : SCA_ISensor(gameobj,eventmgr), m_propertyname(propname), m_bFindMaterial(bFindMaterial), m_bXRay(bXRay), @@ -336,20 +335,16 @@ PyTypeObject KX_RaySensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods - -}; - -PyParentObject KX_RaySensor::Parents[] = { - &KX_RaySensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new + }; PyMethodDef KX_RaySensor::Methods[] = { @@ -447,18 +442,4 @@ PyObject* KX_RaySensor::PyGetHitNormal() return retVal; } - - -PyObject* KX_RaySensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* KX_RaySensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int KX_RaySensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - // <----- Deprecated diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 9efb046742f..530c8ce54e5 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -62,8 +62,7 @@ public: bool bXRay, double distance, int axis, - class KX_Scene* ketsjiScene, - PyTypeObject* T = &Type); + class KX_Scene* ketsjiScene); virtual ~KX_RaySensor(); virtual CValue* GetReplica(); @@ -84,11 +83,6 @@ public: KX_RAY_AXIS_NEG_Y, KX_RAY_AXIS_NEG_Z }; - - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitObject); diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 75435b97797..239c4a0be67 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -55,10 +55,9 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj, const float *linvel, bool linv_local, const float *angvel, - bool angv_local, - PyTypeObject* T) + bool angv_local) : - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_OriginalObject(original), m_scene(scene), @@ -187,20 +186,17 @@ PyTypeObject KX_SCA_AddObjectActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_SCA_AddObjectActuator::Parents[] = { - &KX_SCA_AddObjectActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; + PyMethodDef KX_SCA_AddObjectActuator::Methods[] = { // ---> deprecated {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, (PY_METHODCHAR)SetTime_doc}, @@ -263,21 +259,6 @@ PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, con return actuator->m_lastCreatedObject->GetProxy(); } - -PyObject* KX_SCA_AddObjectActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_AddObjectActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SCA_AddObjectActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - /* 1. setObject */ const char KX_SCA_AddObjectActuator::SetObject_doc[] = "setObject(object)\n" @@ -316,7 +297,7 @@ const char KX_SCA_AddObjectActuator::SetTime_doc[] = PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* value) { ShowDeprecationWarning("setTime()", "the time property"); - int deltatime = PyInt_AsLong(value); + int deltatime = PyLong_AsSsize_t(value); if (deltatime==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "expected an int"); return NULL; @@ -339,7 +320,7 @@ const char KX_SCA_AddObjectActuator::GetTime_doc[] = PyObject* KX_SCA_AddObjectActuator::PyGetTime() { ShowDeprecationWarning("getTime()", "the time property"); - return PyInt_FromLong(m_timeProp); + return PyLong_FromSsize_t(m_timeProp); } @@ -361,7 +342,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_OriginalObject->GetName().ReadPtr()); + return PyUnicode_FromString(m_OriginalObject->GetName().ReadPtr()); else return m_OriginalObject->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 6746b7d1bc6..3151e7a89ca 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -88,8 +88,7 @@ public: const float *linvel, bool linv_local, const float *angvel, - bool angv_local, - PyTypeObject* T=&Type + bool angv_local ); ~KX_SCA_AddObjectActuator(void); @@ -110,10 +109,6 @@ public: virtual bool Update(); - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - SCA_IObject* GetLastCreatedObject( ) const ; diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index a50764a54e6..423fd0db7f2 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -47,9 +47,7 @@ /* Integration hooks ------------------------------------------------------- */ - PyTypeObject - -KX_SCA_DynamicActuator::Type = { +PyTypeObject KX_SCA_DynamicActuator::Type = { #if (PY_VERSION_HEX >= 0x02060000) PyVarObject_HEAD_INIT(NULL, 0) #else @@ -66,22 +64,17 @@ KX_SCA_DynamicActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_SCA_DynamicActuator::Parents[] = { - &KX_SCA_DynamicActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef KX_SCA_DynamicActuator::Methods[] = { // ---> deprecated KX_PYMETHODTABLE(KX_SCA_DynamicActuator, setOperation), @@ -96,21 +89,6 @@ PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = { }; -PyObject* KX_SCA_DynamicActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_DynamicActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SCA_DynamicActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - - /* 1. setOperation */ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation, "setOperation(operation?)\n" @@ -142,7 +120,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, ) { ShowDeprecationWarning("getOperation()", "the mode property"); - return PyInt_FromLong((long)m_dyn_operation); + return PyLong_FromSsize_t((long)m_dyn_operation); } @@ -152,10 +130,9 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, KX_SCA_DynamicActuator::KX_SCA_DynamicActuator(SCA_IObject *gameobj, short dyn_operation, - float setmass, - PyTypeObject* T) : + float setmass) : - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_dyn_operation(dyn_operation), m_setmass(setmass) { diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h index 4add707f8cd..8b598c9ecfa 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h @@ -50,8 +50,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator KX_SCA_DynamicActuator( SCA_IObject* gameobj, short dyn_operation, - float setmass, - PyTypeObject* T=&Type + float setmass ); ~KX_SCA_DynamicActuator( @@ -73,11 +72,6 @@ class KX_SCA_DynamicActuator : public SCA_IActuator KX_DYN_SET_MASS, }; - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. setOperation */ KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,setOperation); KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,getOperation); diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp index 728254e7f48..47c5c3aeeeb 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -43,9 +43,8 @@ #endif KX_SCA_EndObjectActuator::KX_SCA_EndObjectActuator(SCA_IObject *gameobj, - SCA_IScene* scene, - PyTypeObject* T): - SCA_IActuator(gameobj, T), + SCA_IScene* scene): + SCA_IActuator(gameobj), m_scene(scene) { // intentionally empty @@ -108,24 +107,17 @@ PyTypeObject KX_SCA_EndObjectActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject KX_SCA_EndObjectActuator::Parents[] = { - &KX_SCA_EndObjectActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SCA_EndObjectActuator::Methods[] = { {NULL,NULL} //Sentinel }; @@ -134,13 +126,4 @@ PyAttributeDef KX_SCA_EndObjectActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_SCA_EndObjectActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_EndObjectActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - /* eof */ diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h index 70d72f1f8da..782a24b1ef1 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h @@ -47,8 +47,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator public: KX_SCA_EndObjectActuator( SCA_IObject* gameobj, - SCA_IScene* scene, - PyTypeObject* T=&Type + SCA_IScene* scene ); ~KX_SCA_EndObjectActuator(); @@ -63,9 +62,6 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); }; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 00842d7012a..2884bb76565 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -50,9 +50,7 @@ /* Integration hooks ------------------------------------------------------- */ - PyTypeObject - -KX_SCA_ReplaceMeshActuator::Type = { +PyTypeObject KX_SCA_ReplaceMeshActuator::Type = { #if (PY_VERSION_HEX >= 0x02060000) PyVarObject_HEAD_INIT(NULL, 0) #else @@ -69,23 +67,17 @@ KX_SCA_ReplaceMeshActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_SCA_ReplaceMeshActuator::Parents[] = { - &KX_SCA_ReplaceMeshActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = { KX_PYMETHODTABLE(KX_SCA_ReplaceMeshActuator, instantReplaceMesh), // Deprecated -----> @@ -99,20 +91,6 @@ PyAttributeDef KX_SCA_ReplaceMeshActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_SCA_ReplaceMeshActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_ReplaceMeshActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SCA_ReplaceMeshActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - PyObject* KX_SCA_ReplaceMeshActuator::pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SCA_ReplaceMeshActuator* actuator = static_cast(self); @@ -161,7 +139,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, getMesh, if (!m_mesh) Py_RETURN_NONE; - return PyString_FromString(const_cast(m_mesh->GetName().ReadPtr())); + return PyUnicode_FromString(const_cast(m_mesh->GetName().ReadPtr())); } @@ -178,10 +156,9 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, instantReplaceMesh, KX_SCA_ReplaceMeshActuator::KX_SCA_ReplaceMeshActuator(SCA_IObject *gameobj, class RAS_MeshObject *mesh, - SCA_IScene* scene, - PyTypeObject* T) : + SCA_IScene* scene) : - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_mesh(mesh), m_scene(scene) { diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 0e7f7852701..6a68bd88cc5 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -55,9 +55,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator KX_SCA_ReplaceMeshActuator( SCA_IObject* gameobj, RAS_MeshObject *mesh, - SCA_IScene* scene, - PyTypeObject* T=&Type - ); + SCA_IScene* scene); ~KX_SCA_ReplaceMeshActuator( ); @@ -71,10 +69,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator void InstantReplaceMesh(); - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - + /* python api */ static PyObject* pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index c0d8a7090c4..51f5276e075 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -138,7 +138,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, class SND_IAudioDevice* adi, const STR_String& sceneName, Scene *scene): - PyObjectPlus(&KX_Scene::Type), + PyObjectPlus(), m_keyboardmgr(NULL), m_mousemgr(NULL), m_sceneConverter(NULL), @@ -1629,17 +1629,15 @@ PyTypeObject KX_Scene::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_Scene::Parents[] = { - &KX_Scene::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_Scene::Methods[] = { @@ -1654,7 +1652,7 @@ PyMethodDef KX_Scene::Methods[] = { PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast(self_v); - return PyString_FromString(self->GetName().ReadPtr()); + return PyUnicode_FromString(self->GetName().ReadPtr()); } PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1730,72 +1728,6 @@ PyAttributeDef KX_Scene::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_Scene::py_getattro__internal(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *value) -{ - py_setattro_up(PyObjectPlus); -} - -PyObject* KX_Scene::py_getattro(PyObject *attr) -{ - PyObject *object = py_getattro__internal(attr); - - if (object==NULL) - { - PyErr_Clear(); - object = PyDict_GetItem(m_attr_dict, attr); - if(object) { - Py_INCREF(object); - } - else { - PyErr_Format(PyExc_AttributeError, "value = scene.myAttr: KX_Scene, attribute \"%s\" not found", PyString_AsString(attr)); - } - } - - return object; -} - -PyObject* KX_Scene::py_getattro_dict() { - //py_getattro_dict_up(PyObjectPlus); - - PyObject *dict= py_getattr_dict(PyObjectPlus::py_getattro_dict(), Type.tp_dict); - if(dict==NULL) - return NULL; - - /* normally just return this but KX_Scene has some more items */ - - PyDict_Update(dict, m_attr_dict); - return dict; -} - -int KX_Scene::py_setattro(PyObject *attr, PyObject *value) -{ - int ret= py_setattro__internal(attr, value); - - if (ret==PY_SET_ATTR_MISSING) { - if (PyDict_SetItem(m_attr_dict, attr, value)==0) { - PyErr_Clear(); - ret= PY_SET_ATTR_SUCCESS; - } - else { - PyErr_SetString(PyExc_AttributeError, "scene.UserAttr = value: KX_Scenes, failed assigning value to internal dictionary"); - ret= PY_SET_ATTR_FAIL; - } - } - - return ret; -} - -int KX_Scene::py_delattro(PyObject *attr) -{ - PyDict_DelItem(m_attr_dict, attr); - return 0; -} - KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList, "getLightList() -> list [KX_Light]\n" "Returns a list of all lights in the scene.\n" @@ -1820,7 +1752,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName, ) { ShowDeprecationWarning("getName()", "the name property"); - return PyString_FromString(GetName()); + return PyUnicode_FromString(GetName()); } KX_PYMETHODDEF_DOC(KX_Scene, addObject, diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 79d3f7fd828..2792f1f5fe4 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -563,15 +563,7 @@ public: static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); - virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ - virtual PyObject* py_getattro_dict(); - - virtual int py_setattro(PyObject *attr, PyObject *value); - virtual int py_delattro(PyObject *attr); - virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); } - - PyObject* py_getattro__internal(PyObject *attr); - int py_setattro__internal(PyObject *attr, PyObject *pyvalue); + virtual PyObject* py_repr(void) { return PyUnicode_FromString(GetName().ReadPtr()); } /** * Sets the time the scene was suspended diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 1b790ec9824..5528e58ef77 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -49,9 +49,8 @@ KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, KX_Scene *scene, KX_KetsjiEngine* ketsjiEngine, const STR_String& nextSceneName, - KX_Camera* camera, - PyTypeObject* T) - : SCA_IActuator(gameobj, T) + KX_Camera* camera) + : SCA_IActuator(gameobj) { m_mode = mode; m_scene = scene; @@ -134,7 +133,7 @@ bool KX_SceneActuator::Update() { // if no camera is set and the parent object is a camera, use it as the camera SCA_IObject* parent = GetParent(); - if (parent->isA(&KX_Camera::Type)) + if (parent->GetGameObjectType()==SCA_IObject::OBJ_CAMERA) { m_scene->SetActiveCamera((KX_Camera*)parent); } @@ -239,26 +238,17 @@ PyTypeObject KX_SceneActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_SceneActuator::Parents[] = -{ - &KX_SceneActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SceneActuator::Methods[] = { //Deprecated functions ------> @@ -280,20 +270,6 @@ PyAttributeDef KX_SceneActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_SceneActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SceneActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SceneActuator* actuator = static_cast(self); @@ -355,7 +331,7 @@ const char KX_SceneActuator::GetUseRestart_doc[] = PyObject* KX_SceneActuator::PyGetUseRestart() { ShowDeprecationWarning("getUseRestart()", "the useRestart property"); - return PyInt_FromLong(!(m_restart == 0)); + return PyLong_FromSsize_t(!(m_restart == 0)); } @@ -391,7 +367,7 @@ const char KX_SceneActuator::GetScene_doc[] = PyObject* KX_SceneActuator::PyGetScene() { ShowDeprecationWarning("getScene()", "the scene property"); - return PyString_FromString(m_nextSceneName); + return PyUnicode_FromString(m_nextSceneName); } @@ -432,7 +408,7 @@ PyObject* KX_SceneActuator::PyGetCamera() { ShowDeprecationWarning("getCamera()", "the camera property"); if (m_camera) { - return PyString_FromString(m_camera->GetName()); + return PyUnicode_FromString(m_camera->GetName()); } else { Py_RETURN_NONE; diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 2412dd02590..86de3395d1e 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -77,8 +77,7 @@ class KX_SceneActuator : public SCA_IActuator KX_Scene* scene, KX_KetsjiEngine* ketsjiEngine, const STR_String& nextSceneName, - KX_Camera* camera, - PyTypeObject* T=&Type); + KX_Camera* camera); virtual ~KX_SceneActuator(); virtual CValue* GetReplica(); @@ -92,10 +91,6 @@ class KX_SceneActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. set */ /* Removed */ diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index c13271f66a5..673f42283dd 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -50,9 +50,8 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj, SND_Scene* sndscene, KX_SOUNDACT_TYPE type, short start, - short end, - PyTypeObject* T) - : SCA_IActuator(gameobj,T) + short end) + : SCA_IActuator(gameobj) { m_soundObject = sndobj; m_soundScene = sndscene; @@ -250,25 +249,17 @@ PyTypeObject KX_SoundActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_SoundActuator::Parents[] = { - &KX_SoundActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SoundActuator::Methods[] = { // Deprecated -----> {"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL}, @@ -340,25 +331,13 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound, } /* Atribute setting and getting -------------------------------------------- */ -PyObject* KX_SoundActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SoundActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SoundActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SoundActuator * actuator = static_cast (self); if (!actuator->m_soundObject) { - return PyString_FromString(""); + return PyUnicode_FromString(""); } STR_String objectname = actuator->m_soundObject->GetObjectName(); char* name = objectname.Ptr(); @@ -367,7 +346,7 @@ PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYAT PyErr_SetString(PyExc_RuntimeError, "value = actuator.fileName: KX_SoundActuator, unable to get sound fileName"); return NULL; } else - return PyString_FromString(name); + return PyUnicode_FromString(name); } PyObject* KX_SoundActuator::pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) @@ -402,7 +381,7 @@ PyObject* KX_SoundActuator::pyattr_get_looping(void *self, const struct KX_PYATT { KX_SoundActuator * actuator = static_cast (self); int looping = (actuator->m_soundObject) ? actuator->m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF; - PyObject* result = PyInt_FromLong(looping); + PyObject* result = PyLong_FromSsize_t(looping); return result; } @@ -580,7 +559,7 @@ PyObject* KX_SoundActuator::PyGetFilename() ShowDeprecationWarning("getFilename()", "the fileName property"); if (!m_soundObject) { - return PyString_FromString(""); + return PyUnicode_FromString(""); } STR_String objectname = m_soundObject->GetObjectName(); char* name = objectname.Ptr(); @@ -589,7 +568,7 @@ PyObject* KX_SoundActuator::PyGetFilename() PyErr_SetString(PyExc_RuntimeError, "Unable to get sound fileName"); return NULL; } else - return PyString_FromString(name); + return PyUnicode_FromString(name); } PyObject* KX_SoundActuator::PySetGain(PyObject* args) @@ -689,7 +668,7 @@ PyObject* KX_SoundActuator::PyGetLooping() { ShowDeprecationWarning("getLooping()", "the looping property"); int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF; - PyObject* result = PyInt_FromLong(looping); + PyObject* result = PyLong_FromSsize_t(looping); return result; } @@ -777,7 +756,7 @@ PyObject* KX_SoundActuator::PySetType(PyObject* args) PyObject* KX_SoundActuator::PyGetType() { ShowDeprecationWarning("getType()", "the mode property"); - return PyInt_FromLong(m_type); + return PyLong_FromSsize_t(m_type); } // <----- diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index a7491355667..adafee0a30b 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -66,8 +66,7 @@ public: class SND_Scene* sndscene, KX_SOUNDACT_TYPE type, short start, - short end, - PyTypeObject* T=&Type); + short end); ~KX_SoundActuator(); @@ -81,10 +80,6 @@ public: /* Python interface --------------------------------------------------- */ /* -------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, startSound); KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, pauseSound); KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, stopSound); diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index f6979eee0f4..9815d6274aa 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -38,10 +38,9 @@ KX_StateActuator::KX_StateActuator( SCA_IObject* gameobj, int operation, - unsigned int mask, - PyTypeObject* T + unsigned int mask ) - : SCA_IActuator(gameobj,T), + : SCA_IActuator(gameobj), m_operation(operation), m_mask(mask) { @@ -154,24 +153,18 @@ PyTypeObject KX_StateActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject -KX_StateActuator::Parents[] = { - &KX_StateActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; -PyMethodDef -KX_StateActuator::Methods[] = { +PyMethodDef KX_StateActuator::Methods[] = { // deprecated --> {"setOperation", (PyCFunction) KX_StateActuator::sPySetOperation, METH_VARARGS, (PY_METHODCHAR)SetOperation_doc}, @@ -187,20 +180,6 @@ PyAttributeDef KX_StateActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_StateActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_StateActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_StateActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - /* set operation ---------------------------------------------------------- */ const char diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index a4191a4c5fd..ce86c4b44fe 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -66,9 +66,8 @@ class KX_StateActuator : public SCA_IActuator KX_StateActuator( SCA_IObject* gameobj, int operation, - unsigned int mask, - PyTypeObject* T=&Type - ); + unsigned int mask + ); virtual ~KX_StateActuator( @@ -89,10 +88,6 @@ class KX_StateActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetOperation); KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetMask); diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp deleted file mode 100644 index fc053f05e63..00000000000 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp +++ /dev/null @@ -1,244 +0,0 @@ -#include "KX_ConvertPhysicsObject.h" - -#ifdef USE_SUMO_SOLID - -#ifdef WIN32 -#pragma warning (disable : 4786) -#endif - -#include "KX_SumoPhysicsController.h" -#include "SG_Spatial.h" -#include "SM_Scene.h" -#include "KX_GameObject.h" -#include "KX_MotionState.h" -#include "KX_ClientObjectInfo.h" - -#include "PHY_IPhysicsEnvironment.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -void KX_SumoPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) -{ - SumoPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); -} -void KX_SumoPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) -{ - SumoPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); - -} -void KX_SumoPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) -{ - float oldmat[12]; - drot.getValue(oldmat); -/* float newmat[9]; - float *m = &newmat[0]; - double *orgm = &oldmat[0]; - - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; */ - - SumoPhysicsController::RelativeRotate(oldmat,local); -} - -void KX_SumoPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) -{ - SumoPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local); - -} - -void KX_SumoPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) -{ - SumoPhysicsController::SetAngularVelocity(ang_vel[0],ang_vel[1],ang_vel[2],local); -} - -MT_Vector3 KX_SumoPhysicsController::GetVelocity(const MT_Point3& pos) -{ - - float linvel[3]; - SumoPhysicsController::GetVelocity(pos[0],pos[1],pos[2],linvel[0],linvel[1],linvel[2]); - - return MT_Vector3 (linvel); -} - -MT_Vector3 KX_SumoPhysicsController::GetLinearVelocity() -{ - return GetVelocity(MT_Point3(0,0,0)); - -} - -void KX_SumoPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ - SumoPhysicsController::resolveCombinedVelocities(linvelX,linvelY,linvelZ,angVelX,angVelY,angVelZ); -} - -void KX_SumoPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) -{ - SumoPhysicsController::ApplyTorque(torque[0],torque[1],torque[2],local); - -} - -void KX_SumoPhysicsController::ApplyForce(const MT_Vector3& force,bool local) -{ - SumoPhysicsController::ApplyForce(force[0],force[1],force[2],local); -} - -bool KX_SumoPhysicsController::Update(double time) -{ - return SynchronizeMotionStates(time); -} - -void KX_SumoPhysicsController::SetSimulatedTime(double time) -{ - -} - -void KX_SumoPhysicsController::SetSumoTransform(bool nondynaonly) -{ - SumoPhysicsController::setSumoTransform(nondynaonly); - -} - -void KX_SumoPhysicsController::SuspendDynamics(bool) -{ - SumoPhysicsController::SuspendDynamics(); -} - -void KX_SumoPhysicsController::RestoreDynamics() -{ - SumoPhysicsController::RestoreDynamics(); -} - -SG_Controller* KX_SumoPhysicsController::GetReplica(SG_Node* destnode) -{ - - PHY_IMotionState* motionstate = new KX_MotionState(destnode); - - KX_SumoPhysicsController* physicsreplica = new KX_SumoPhysicsController(*this); - - //parentcontroller is here be able to avoid collisions between parent/child - - PHY_IPhysicsController* parentctrl = NULL; - - if (destnode != destnode->GetRootSGParent()) - { - KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); - if (clientgameobj) - { - parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController(); - } else - { - // it could be a false node, try the children - NodeList::const_iterator childit; - for ( - childit = destnode->GetSGChildren().begin(); - childit!= destnode->GetSGChildren().end(); - ++childit - ) { - KX_GameObject *clientgameobj = static_cast( (*childit)->GetSGClientObject()); - if (clientgameobj) - { - parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController(); - } - } - } - } - - physicsreplica->PostProcessReplica(motionstate,parentctrl); - - return physicsreplica; -} - - -void KX_SumoPhysicsController::SetObject (SG_IObject* object) -{ - SG_Controller::SetObject(object); - - // cheating here... -//should not be necessary, is it for duplicates ? - -KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); -gameobj->SetPhysicsController(this,gameobj->IsDynamic()); -GetSumoObject()->setClientObject(gameobj->getClientInfo()); -} - -void KX_SumoPhysicsController::setMargin(float collisionMargin) -{ - SumoPhysicsController::SetMargin(collisionMargin); -} - - -void KX_SumoPhysicsController::setOrientation(const MT_Matrix3x3& rot) -{ - MT_Quaternion orn = rot.getRotation(); - SumoPhysicsController::setOrientation( - orn[0],orn[1],orn[2],orn[3]); - -} -void KX_SumoPhysicsController::getOrientation(MT_Quaternion& orn) -{ - - float quat[4]; - - SumoPhysicsController::getOrientation(quat[0],quat[1],quat[2],quat[3]); - - orn = MT_Quaternion(quat); - -} - -void KX_SumoPhysicsController::setPosition(const MT_Point3& pos) -{ - SumoPhysicsController::setPosition(pos[0],pos[1],pos[2]); - -} - -void KX_SumoPhysicsController::setScaling(const MT_Vector3& scaling) -{ - SumoPhysicsController::setScaling(scaling[0],scaling[1],scaling[2]); - -} - -MT_Scalar KX_SumoPhysicsController::GetMass() -{ - return SumoPhysicsController::getMass(); -} - -void KX_SumoPhysicsController::SetMass(MT_Scalar newmass) -{ -} - -MT_Vector3 KX_SumoPhysicsController::GetLocalInertia() -{ - return MT_Vector3(0.f, 0.f, 0.f); // \todo -} - -MT_Scalar KX_SumoPhysicsController::GetRadius() -{ - return SumoPhysicsController::GetRadius(); -} - -MT_Vector3 KX_SumoPhysicsController::getReactionForce() -{ - float force[3]; - SumoPhysicsController::getReactionForce(force[0],force[1],force[2]); - return MT_Vector3(force); - -} - -void KX_SumoPhysicsController::setRigidBody(bool rigid) -{ - SumoPhysicsController::setRigidBody(rigid); - -} - - -KX_SumoPhysicsController::~KX_SumoPhysicsController() -{ - - -} - - -#endif//USE_SUMO_SOLID diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h deleted file mode 100644 index 278994c6ae7..00000000000 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __KX_SUMOPHYSICSCONTROLLER_H -#define __KX_SUMOPHYSICSCONTROLLER_H - -#include "PHY_IPhysicsController.h" - -/** - Physics Controller, a special kind of Scene Graph Transformation Controller. - It get's callbacks from Sumo in case a transformation change took place. - Each time the scene graph get's updated, the controller get's a chance - in the 'Update' method to reflect changed. -*/ - -#include "SumoPhysicsController.h" -#include "KX_IPhysicsController.h" - -class KX_SumoPhysicsController : public KX_IPhysicsController, - public SumoPhysicsController - -{ - - -public: - KX_SumoPhysicsController( - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - class PHY_IMotionState* motionstate - ,bool dyna) - : KX_IPhysicsController(dyna,false,false,NULL) , - SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna) - { - }; - virtual ~KX_SumoPhysicsController(); - - void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse); - virtual void SetObject (SG_IObject* object); - virtual void setMargin (float collisionMargin); - - void RelativeTranslate(const MT_Vector3& dloc,bool local); - void RelativeRotate(const MT_Matrix3x3& drot,bool local); - void ApplyTorque(const MT_Vector3& torque,bool local); - void ApplyForce(const MT_Vector3& force,bool local); - MT_Vector3 GetLinearVelocity(); - MT_Vector3 GetAngularVelocity() // to keep compiler happy - { return MT_Vector3(0.0,0.0,0.0); } - MT_Vector3 GetVelocity(const MT_Point3& pos); - void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); - void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); - void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - - - void SuspendDynamics(bool); - void RestoreDynamics(); - virtual void AddCompoundChild(KX_IPhysicsController* child) { } - virtual void RemoveCompoundChild(KX_IPhysicsController* child) { } - - virtual void getOrientation(MT_Quaternion& orn); - virtual void setOrientation(const MT_Matrix3x3& orn); - virtual void SetTransform() {} - - virtual void setPosition(const MT_Point3& pos); - virtual void setScaling(const MT_Vector3& scaling); - virtual MT_Scalar GetMass(); - virtual void SetMass(MT_Scalar newmass); - virtual MT_Vector3 GetLocalInertia(); - virtual MT_Scalar GetRadius(); - virtual MT_Vector3 getReactionForce(); - virtual void setRigidBody(bool rigid); - - virtual float GetLinVelocityMin() { return SumoPhysicsController::GetLinVelocityMin(); } - virtual void SetLinVelocityMin(float val) { SumoPhysicsController::SetLinVelocityMin(val); } - virtual float GetLinVelocityMax() { return SumoPhysicsController::GetLinVelocityMax(); } - virtual void SetLinVelocityMax(float val) { SumoPhysicsController::SetLinVelocityMax(val); } - - virtual SG_Controller* GetReplica(class SG_Node* destnode); - - - void SetSumoTransform(bool nondynaonly); - // todo: remove next line ! - virtual void SetSimulatedTime(double time); - - // call from scene graph to update - virtual bool Update(double time); - - void - SetOption( - int option, - int value - ){ - // intentionally empty - }; -}; - -#endif //__KX_SUMOPHYSICSCONTROLLER_H - diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index c06acd4a873..b0cf172c27a 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -97,8 +97,8 @@ bool KX_TouchSensor::Evaluate() return result; } -KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,bool bTouchPulse,const STR_String& touchedpropname,PyTypeObject* T) -:SCA_ISensor(gameobj,eventmgr,T), +KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,bool bTouchPulse,const STR_String& touchedpropname) +:SCA_ISensor(gameobj,eventmgr), m_touchedpropname(touchedpropname), m_bFindMaterial(bFindMaterial), m_bTouchPulse(bTouchPulse), @@ -310,19 +310,15 @@ PyTypeObject KX_TouchSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_TouchSensor::Parents[] = { - &KX_TouchSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_TouchSensor::Methods[] = { @@ -348,20 +344,6 @@ PyAttributeDef KX_TouchSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_TouchSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* KX_TouchSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int KX_TouchSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* Python API */ /* 1. setProperty */ @@ -374,7 +356,7 @@ const char KX_TouchSensor::SetProperty_doc[] = PyObject* KX_TouchSensor::PySetProperty(PyObject* value) { ShowDeprecationWarning("setProperty()", "the propName property"); - char *nameArg= PyString_AsString(value); + char *nameArg= _PyUnicode_AsString(value); if (nameArg==NULL) { PyErr_SetString(PyExc_ValueError, "expected a "); return NULL; @@ -392,7 +374,7 @@ const char KX_TouchSensor::GetProperty_doc[] = PyObject* KX_TouchSensor::PyGetProperty() { ShowDeprecationWarning("getProperty()", "the propName property"); - return PyString_FromString(m_touchedpropname); + return PyUnicode_FromString(m_touchedpropname); } const char KX_TouchSensor::GetHitObject_doc[] = @@ -433,7 +415,7 @@ const char KX_TouchSensor::GetTouchMaterial_doc[] = PyObject* KX_TouchSensor::PyGetTouchMaterial() { ShowDeprecationWarning("getTouchMaterial()", "the useMaterial property"); - return PyInt_FromLong(m_bFindMaterial); + return PyLong_FromSsize_t(m_bFindMaterial); } /* 6. setTouchMaterial */ @@ -446,7 +428,7 @@ const char KX_TouchSensor::SetTouchMaterial_doc[] = PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject *value) { ShowDeprecationWarning("setTouchMaterial()", "the useMaterial property"); - int pulseArg = PyInt_AsLong(value); + int pulseArg = PyLong_AsSsize_t(value); if(pulseArg ==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "expected a bool"); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 476c63e89db..6cbf5b15e3b 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -79,8 +79,7 @@ public: class KX_GameObject* gameobj, bool bFindMaterial, bool bTouchPulse, - const STR_String& touchedpropname, - PyTypeObject* T=&Type) ; + const STR_String& touchedpropname) ; virtual ~KX_TouchSensor(); virtual CValue* GetReplica(); @@ -121,10 +120,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated -----> /* 1. setProperty */ diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 5a50d0fb944..e8a06d8d619 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -59,10 +59,8 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, int time, bool allow3D, int trackflag, - int upflag, - PyTypeObject* T) - : - SCA_IActuator(gameobj, T) + int upflag) + : SCA_IActuator(gameobj) { m_time = time; m_allow3D = allow3D; @@ -74,7 +72,6 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, if (m_object) m_object->RegisterActuator(this); - if (gameobj->isA(&KX_GameObject::Type)) { // if the object is vertex parented, don't check parent orientation as the link is broken if (!((KX_GameObject*)gameobj)->IsVertexParent()){ @@ -450,25 +447,17 @@ PyTypeObject KX_TrackToActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_TrackToActuator::Parents[] = { - &KX_TrackToActuator::Type, - &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_TrackToActuator::Methods[] = { // ---> deprecated {"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, (PY_METHODCHAR)SetTime_doc}, @@ -518,20 +507,6 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT } -PyObject* KX_TrackToActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_TrackToActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_TrackToActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - /* 1. setObject */ const char KX_TrackToActuator::SetObject_doc[] = "setObject(object)\n" @@ -576,7 +551,7 @@ PyObject* KX_TrackToActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_object->GetName()); + return PyUnicode_FromString(m_object->GetName()); else return m_object->GetProxy(); } @@ -613,7 +588,7 @@ const char KX_TrackToActuator::GetTime_doc[] = PyObject* KX_TrackToActuator::PyGetTime() { ShowDeprecationWarning("getTime()", "the timer property"); - return PyInt_FromLong(m_time); + return PyLong_FromSsize_t(m_time); } @@ -625,7 +600,7 @@ const char KX_TrackToActuator::GetUse3D_doc[] = PyObject* KX_TrackToActuator::PyGetUse3D() { ShowDeprecationWarning("setTime()", "the use3D property"); - return PyInt_FromLong(!(m_allow3D == 0)); + return PyLong_FromSsize_t(!(m_allow3D == 0)); } diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index c4cc2b1f062..801e695bb9b 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -56,7 +56,7 @@ class KX_TrackToActuator : public SCA_IActuator public: KX_TrackToActuator(SCA_IObject* gameobj, SCA_IObject *ob, int time, - bool threedee,int trackflag,int upflag, PyTypeObject* T=&Type); + bool threedee,int trackflag,int upflag); virtual ~KX_TrackToActuator(); virtual CValue* GetReplica() { KX_TrackToActuator* replica = new KX_TrackToActuator(*this); @@ -70,9 +70,6 @@ class KX_TrackToActuator : public SCA_IActuator virtual bool Update(double curtime, bool frame); /* Python part */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); /* These are used to get and set m_ob */ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 8146d04a878..7001bfc8b7e 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -16,8 +16,8 @@ KX_VehicleWrapper::KX_VehicleWrapper( PHY_IVehicle* vehicle, - PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) : - PyObjectPlus(T), + PHY_IPhysicsEnvironment* physenv) : + PyObjectPlus(), m_vehicle(vehicle), m_physenv(physenv) { @@ -127,13 +127,13 @@ PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* args) PyObject* KX_VehicleWrapper::PyGetNumWheels(PyObject* args) { - return PyInt_FromLong(m_vehicle->GetNumWheels()); + return PyLong_FromSsize_t(m_vehicle->GetNumWheels()); } PyObject* KX_VehicleWrapper::PyGetConstraintId(PyObject* args) { - return PyInt_FromLong(m_vehicle->GetUserConstraintId()); + return PyLong_FromSsize_t(m_vehicle->GetUserConstraintId()); } @@ -264,7 +264,7 @@ PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* args) PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* args) { - return PyInt_FromLong(m_vehicle->GetUserConstraintType()); + return PyLong_FromSsize_t(m_vehicle->GetUserConstraintType()); } @@ -289,35 +289,17 @@ PyTypeObject KX_VehicleWrapper::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_VehicleWrapper::Parents[] = { - &KX_VehicleWrapper::Type, - &PyObjectPlus::Type, - NULL -}; - -PyObject* KX_VehicleWrapper::py_getattro(PyObject *attr) -{ - //here you can search for existing data members (like mass,friction etc.) - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_VehicleWrapper::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* value) -{ - py_setattro_up(PyObjectPlus); + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef KX_VehicleWrapper::Methods[] = { {"addWheel",(PyCFunction) KX_VehicleWrapper::sPyAddWheel, METH_VARARGS}, {"getNumWheels",(PyCFunction) KX_VehicleWrapper::sPyGetNumWheels, METH_VARARGS}, diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index c2b5e3d9251..d7f2da5cd7c 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -12,14 +12,11 @@ class PHY_IMotionState; class KX_VehicleWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); std::vector m_motionStates; public: - KX_VehicleWrapper(PHY_IVehicle* vehicle,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + KX_VehicleWrapper(PHY_IVehicle* vehicle,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_VehicleWrapper (); int getConstraintId(); diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 4b0ad083473..cb8c891969d 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -53,18 +53,15 @@ PyTypeObject KX_VertexProxy::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_VertexProxy::Parents[] = { - &KX_VertexProxy::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - &PyObjectPlus::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_VertexProxy::Methods[] = { @@ -85,37 +82,38 @@ PyMethodDef KX_VertexProxy::Methods[] = { PyAttributeDef KX_VertexProxy::Attributes[] = { //KX_PYATTRIBUTE_TODO("DummyProps"), - + KX_PYATTRIBUTE_DUMMY("x"), KX_PYATTRIBUTE_DUMMY("y"), KX_PYATTRIBUTE_DUMMY("z"), - + KX_PYATTRIBUTE_DUMMY("r"), KX_PYATTRIBUTE_DUMMY("g"), KX_PYATTRIBUTE_DUMMY("b"), KX_PYATTRIBUTE_DUMMY("a"), - + KX_PYATTRIBUTE_DUMMY("u"), KX_PYATTRIBUTE_DUMMY("v"), - + KX_PYATTRIBUTE_DUMMY("u2"), KX_PYATTRIBUTE_DUMMY("v2"), - + KX_PYATTRIBUTE_DUMMY("XYZ"), KX_PYATTRIBUTE_DUMMY("UV"), - + KX_PYATTRIBUTE_DUMMY("color"), KX_PYATTRIBUTE_DUMMY("colour"), - + KX_PYATTRIBUTE_DUMMY("normal"), - + { NULL } //Sentinel }; +#if 0 PyObject* KX_VertexProxy::py_getattro(PyObject *attr) { - char *attr_str= PyString_AsString(attr); + char *attr_str= _PyUnicode_AsString(attr); if (attr_str[1]=='\0') { // Group single letters // pos if (attr_str[0]=='x') @@ -141,8 +139,8 @@ KX_VertexProxy::py_getattro(PyObject *attr) if (attr_str[0]=='v') return PyFloat_FromDouble(m_vertex->getUV1()[1]); } - - + + if (!strcmp(attr_str, "XYZ")) return PyObjectFrom(MT_Vector3(m_vertex->getXYZ())); @@ -156,22 +154,21 @@ KX_VertexProxy::py_getattro(PyObject *attr) color /= 255.0; return PyObjectFrom(color); } - + if (!strcmp(attr_str, "normal")) { return PyObjectFrom(MT_Vector3(m_vertex->getNormal())); } - + py_getattro_up(CValue); } +#endif -PyObject* KX_VertexProxy::py_getattro_dict() { - py_getattro_dict_up(CValue); -} +#if 0 int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) { - char *attr_str= PyString_AsString(attr); + char *attr_str= _PyUnicode_AsString(attr); if (PySequence_Check(pyvalue)) { if (!strcmp(attr_str, "XYZ")) @@ -185,7 +182,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } return PY_SET_ATTR_FAIL; } - + if (!strcmp(attr_str, "UV")) { MT_Point2 vec; @@ -197,7 +194,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } return PY_SET_ATTR_FAIL; } - + if (!strcmp(attr_str, "color") || !strcmp(attr_str, "colour")) { MT_Vector4 vec; @@ -209,7 +206,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } return PY_SET_ATTR_FAIL; } - + if (!strcmp(attr_str, "normal")) { MT_Vector3 vec; @@ -222,7 +219,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) return PY_SET_ATTR_FAIL; } } - + if (PyFloat_Check(pyvalue)) { float val = PyFloat_AsDouble(pyvalue); @@ -235,7 +232,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + if (!strcmp(attr_str, "y")) { pos.y() = val; @@ -243,7 +240,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + if (!strcmp(attr_str, "z")) { pos.z() = val; @@ -251,7 +248,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + // uv MT_Point2 uv = m_vertex->getUV1(); if (!strcmp(attr_str, "u")) @@ -287,7 +284,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + // col unsigned int icol = *((const unsigned int *)m_vertex->getRGBA()); unsigned char *cp = (unsigned char*) &icol; @@ -321,9 +318,10 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) return PY_SET_ATTR_SUCCESS; } } - + return CValue::py_setattro(attr, pyvalue); } +#endif KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex) : m_vertex(vertex), @@ -339,7 +337,7 @@ KX_VertexProxy::~KX_VertexProxy() // stuff for cvalue related things CValue* KX_VertexProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;} -CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;} +CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;} STR_String sVertexName="vertex"; const STR_String & KX_VertexProxy::GetText() {return sVertexName;}; double KX_VertexProxy::GetNumber() { return -1;} @@ -348,7 +346,7 @@ void KX_VertexProxy::SetName(const char *) { }; CValue* KX_VertexProxy::GetReplica() { return NULL;} // stuff for python integration - + PyObject* KX_VertexProxy::PyGetXYZ() { return PyObjectFrom(MT_Point3(m_vertex->getXYZ())); @@ -359,7 +357,7 @@ PyObject* KX_VertexProxy::PySetXYZ(PyObject* value) MT_Point3 vec; if (!PyVecTo(value, vec)) return NULL; - + m_vertex->SetXYZ(vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; @@ -375,7 +373,7 @@ PyObject* KX_VertexProxy::PySetNormal(PyObject* value) MT_Vector3 vec; if (!PyVecTo(value, vec)) return NULL; - + m_vertex->SetNormal(vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; @@ -385,18 +383,18 @@ PyObject* KX_VertexProxy::PySetNormal(PyObject* value) PyObject* KX_VertexProxy::PyGetRGBA() { int *rgba = (int *) m_vertex->getRGBA(); - return PyInt_FromLong(*rgba); + return PyLong_FromSsize_t(*rgba); } PyObject* KX_VertexProxy::PySetRGBA(PyObject* value) { - if PyInt_Check(value) { - int rgba = PyInt_AsLong(value); + if PyLong_Check(value) { + int rgba = PyLong_AsSsize_t(value); m_vertex->SetRGBA(rgba); m_mesh->SetMeshModified(true); Py_RETURN_NONE; } - else { + else { MT_Vector4 vec; if (PyVecTo(value, vec)) { @@ -405,7 +403,7 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject* value) Py_RETURN_NONE; } } - + PyErr_SetString(PyExc_TypeError, "vert.setRGBA(value): KX_VertexProxy, expected a 4D vector or an int"); return NULL; } @@ -421,7 +419,7 @@ PyObject* KX_VertexProxy::PySetUV(PyObject* value) MT_Point2 vec; if (!PyVecTo(value, vec)) return NULL; - + m_vertex->SetUV(vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; @@ -436,14 +434,14 @@ PyObject* KX_VertexProxy::PySetUV2(PyObject* args) { MT_Point2 vec; unsigned int unit= RAS_TexVert::SECOND_UV; - + PyObject* list= NULL; if(!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit)) return NULL; - + if (!PyVecTo(list, vec)) return NULL; - + m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV)); m_vertex->SetUnit(unit); m_vertex->SetUV2(vec); diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 42db5fbc322..13c57e9f556 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -53,9 +53,6 @@ public: // stuff for python integration - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ); KX_PYMETHOD_O(KX_VertexProxy,SetXYZ); diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index d848065ad73..3561ccde9d9 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -39,10 +39,9 @@ KX_VisibilityActuator::KX_VisibilityActuator( SCA_IObject* gameobj, bool visible, bool occlusion, - bool recursive, - PyTypeObject* T + bool recursive ) - : SCA_IActuator(gameobj,T), + : SCA_IActuator(gameobj), m_visible(visible), m_occlusion(occlusion), m_recursive(recursive) @@ -108,25 +107,18 @@ PyTypeObject KX_VisibilityActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods - -}; - -PyParentObject -KX_VisibilityActuator::Parents[] = { - &KX_VisibilityActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; -PyMethodDef -KX_VisibilityActuator::Methods[] = { +PyMethodDef KX_VisibilityActuator::Methods[] = { // Deprecated -----> {"set", (PyCFunction) KX_VisibilityActuator::sPySetVisible, METH_VARARGS, (PY_METHODCHAR) SetVisible_doc}, @@ -141,21 +133,6 @@ PyAttributeDef KX_VisibilityActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_VisibilityActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_VisibilityActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_VisibilityActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - - /* set visibility ---------------------------------------------------------- */ const char KX_VisibilityActuator::SetVisible_doc[] = diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h index 45aba50f645..3ad50c6cea2 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.h +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -48,9 +48,7 @@ class KX_VisibilityActuator : public SCA_IActuator SCA_IObject* gameobj, bool visible, bool occlusion, - bool recursive, - PyTypeObject* T=&Type - ); + bool recursive); virtual ~KX_VisibilityActuator( @@ -69,10 +67,6 @@ class KX_VisibilityActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD_DOC_VARARGS(KX_VisibilityActuator,SetVisible); // <----- diff --git a/source/gameengine/Ketsji/Makefile b/source/gameengine/Ketsji/Makefile index 59b3ff178fb..8e91eb6ff9a 100644 --- a/source/gameengine/Ketsji/Makefile +++ b/source/gameengine/Ketsji/Makefile @@ -44,7 +44,7 @@ CPPFLAGS += -I../../blender/python CPPFLAGS += -I../../blender/python/generic CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_SOLID)/include CPPFLAGS += -I$(NAN_BULLET2)/include CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer @@ -54,14 +54,11 @@ CPPFLAGS += -I../../kernel/gen_system CPPFLAGS += -I../Network -IKXNetwork CPPFLAGS += -I../Physics/common CPPFLAGS += -I../Physics/Dummy -CPPFLAGS += -I../Physics/Sumo -CPPFLAGS += -I../Physics/BlOde CPPFLAGS += -I../Physics/Bullet CPPFLAGS += -I. CPPFLAGS += -I../Converter CPPFLAGS += -I../../blender/blenkernel CPPFLAGS += -I../../blender/blenlib -CPPFLAGS += -I../../blender/editors/include CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I../../blender/imbuf CPPFLAGS += -I../../blender/gpu diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 49dbacc8916..b09267b79ff 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -18,16 +18,9 @@ incs += ' #source/blender/blenkernel #source/blender #source/blender/editors/inc incs += ' #source/blender/makesdna #source/blender/python #source/gameengine/Rasterizer' incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/gameengine/Network' incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common #source/gameengine/Physics/Bullet' -incs += ' #source/gameengine/Physics/BlOde #source/gameengine/Physics/Dummy' +incs += ' #source/gameengine/Physics/Dummy' incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include #source/blender/gpu' -if env['WITH_BF_SOLID']: - incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include' - incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' - incs += ' ' + env['BF_SOLID_INC'] - defs += ' USE_SUMO_SOLID' - - incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] diff --git a/source/gameengine/Physics/BlOde/Makefile b/source/gameengine/Physics/BlOde/Makefile deleted file mode 100644 index 1fbbf198377..00000000000 --- a/source/gameengine/Physics/BlOde/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# - -LIBNAME = blode -DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME) - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I$(OPENGL_HEADERS) -CPPFLAGS += -I$(NAN_STRING)/include -CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) - -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_ODE)/include -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include -CPPFLAGS += -I../../Physics/common -CPPFLAGS += -I../../Physics/Dummy -# nlin: fix this, should put in NAN_ODE dir -#CPPFLAGS += -I./ode/ode/include diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp b/source/gameengine/Physics/BlOde/OdePhysicsController.cpp deleted file mode 100644 index 5efd0994311..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#define USE_ODE -#ifdef USE_ODE - -#include "OdePhysicsController.h" -#include "PHY_IMotionState.h" - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -/////////////////////////////////////////////////////////////////////////// -// -// general to-do list for ODE physics. This is maintained in doxygen format. -// -/// \todo determine assignment time for bounding spheres. -/// -/// it appears you have to select "sphere" for bounding volume AND "draw bounds" -/// in order for a bounding sphere to be generated. otherwise a box is generated. -/// determine exactly when and how the bounding volumes are generated and make -/// this consistent. -/// } -/// -/// \todo bounding sphere size incorrect -/// -/// it appears NOT to use the size of the shown bounding sphere (button "draw bounds"). -/// it appears instead to use the size of the "size" dynamic parameter in the -/// gamebuttons but this "size" draws an incorrectly-sized circle on screen for the -/// bounding sphere (leftover skewed size calculation from sumo?) so figure out WHERE -/// its getting the radius from. -/// -/// \todo ODE collisions must fire collision actuator -/// -/// See OdePhysicsEnvironment::OdeNearCallback. If a sensor was created to check -/// for the presence of this collision, then in the NearCallback you need to -/// take appropriate action regarding the sensor - something like checking its -/// controller and if needed firing its actuator. Need to find similar code in -/// Fuzzics which fires collision controllers/actuators. -/// -/// \todo Are ghost collisions possible? -/// -/// How do ghost collisions work? Do they require collision detection through ODE -/// and NON-CREATION of contact-joint in OdeNearCallback? Currently OdeNearCallback -/// creates joints ALWAYS for collisions. -/// -/// \todo Why is KX_GameObject::addLinearVelocity commented out? -/// -/// Try putting this code back in. -/// -/// \todo Too many non-dynamic actors bogs down ODE physics -/// -/// Lots of "geoms" (ODE static geometry) probably slows down ode. Try a test file -/// with lots of static geometry - the game performance in Blender says it is -/// spending all its time in physics, and I bet all that time is in collision -/// detection. It's ode's non-hierarchical collision detection. -/// try making a separate ode test program (not within blender) with 1000 geoms and -/// see how fast it is. if it is really slow, there is the culprit. -/// isnt someone working on an improved ODE collision detector? check -/// ode mailing list. -/// -/// -/// \todo support collision of dynas with non-dynamic triangle meshes -/// -/// ODE has trimesh-collision support but only for trimeshes without a transform -/// matrix. update ODE tricollider to support a transform matrix. this will allow -/// moving trimeshes non-dynamically (e.g. through Ipos). then collide trimeshes -/// with dynas. this allows dynamic primitives (spheres, boxes) to collide with -/// non-dynamic or kinematically controlled tri-meshes. full dynamic trimesh to -/// dynamic trimesh support is hard because it requires (a) collision and penetration -/// depth for trimesh to trimesh and (hard to compute) (b) an intertia tensor -/// (easy to compute). -/// -/// a triangle mesh collision geometry should be created when the blender -/// bounding volume (F9, EDITBUTTONS) is set to "polyheder", since this is -/// currently the place where sphere/box selection is made -/// -/// \todo specify ODE ERP+CFM in blender interface -/// -/// when ODE physics selected, have to be able to set global cfm and erp. -/// per-joint erp/cfm could be handled in constraint window. -/// -/// \todo moving infinite mass objects should impart extra impulse to objects they collide with -/// -/// currently ODE's ERP pushes them apart but doesn't account for their motion. -/// you have to detect if one body in a collision is a non-dyna. This -/// requires adding a new accessor method to -/// KX_IPhysicsInterfaceController to access the hidden m_isDyna variable, -/// currently it can only be written, not read). If one of the bodies in a -/// collision is a non-dyna, then impart an extra impulse based on the -/// motion of the static object (using its last 2 frames as an approximation -/// of its linear and angular velocity). Linear velocity is easy to -/// approximate, but angular? you have orientation at this frame and -/// orientation at previous frame. The question is what is the angular -/// velocity which would have taken you from the previous frame's orientation -/// to this frame's orientation? -/// -/// \todo allow tweaking bounding volume size -/// -/// the scene converter currently uses the blender bounding volume of the selected -/// object as the geometry for ODE collision purposes. this is good and automatic -/// intuitive - lets you choose between cube, sphere, mesh. but you need to be able -/// to tweak this size for physics. -/// -/// \todo off center meshes totally wrong for ode -/// -/// ode uses x, y, z extents regradless of center. then places geom at center of object. -/// but visual geom is not necessarily at center. need to detect off-center situations. -/// then do what? treat it as an encapsulated off-center mass, or recenter it? -/// -/// i.o.w. recalculate center, or recalculate mass distribution (using encapsulation)? -/// -/// \todo allow off-center mass -/// -/// using ode geometry encapsulators -/// -/// \todo allow entering compound geoms for complex collision shapes specified as a union of simpler shapes -/// -/// The collision shape for arbitrary triangle meshes can probably in general be -///well approximated by a compound ODE geometry object, which is merely a combination -///of many primitives (capsule, sphere, box). I eventually want to add the ability -///to associate compound geometry objects with Blender gameobjects. I think one -///way of doing this would be to add a new button in the GameButtons, "RigidBodyCompound". -///If the object is "Dynamic" + "RigidBody", then the object's bounding volume (sphere, -///box) is created. If an object is "Dynamic" + "RigidBodyCompound", then the object itself -///will merely create a "wrapper" compound object, with the actual geometry objects -///being created from the object's children in Blender. E.g. if I wanted to make a -///compound collision object consisting of a sphere and 2 boxes, I would create a -///parent gameobject with the actual triangle mesh, and set its GameButtons to -///"RigidBodyCompound". I would then create 3 children of this object, 1 sphere and -///2 boxes, and set the GameButtons for the children to be "RigidBody". Then at -///scene conversion time, the scene converter sees "RigidBodyCompound" for the -///top-level object, then appropriately traverses the children and creates the compound -///collision geometry consisting of 2 boxes and a sphere. In this way, arbitrary -///mesh-mesh collision becomes much less necessary - the artist can (or must, -///depending on your point of view!) approximate the collision shape for arbitrary -///meshes with a combination of one or more primitive shapes. I think using the -///parent/child relationship in Blender and a new button "RigidBodyCompound" for the -///parent object of a compound is a feasible way of doing this in Blender. -/// -///See ODE demo test_boxstack and look at the code when you drop a compound object -///with the "X" key. -/// -/// \todo add visual specification of constraints -/// -/// extend the armature constraint system. by using empties and constraining one empty -/// to "copy location" of another, you can get a p2p constraint between the two empties. -/// by making the two empties each a parent of a blender object, you effectively have -/// a p2p constraint between 2 blender bodies. the scene converter can detect these -/// empties, detect the constraint, and generate an ODE constraint. -/// -/// then add a new constraint type "hinge" and "slider" to correspond to ODE joints. -/// e.g. a slider would be a constraint which restricts the axis of its object to lie -/// along the same line as another axis of a different object. e.g. you constrain x-axis -/// of one empty to lie along the same line as the z-axis of another empty; this gives -/// a slider joint. -/// -/// open questions: how to handle powered joints? to what extent should/must constraints -/// be enforced during modeling? use CCD-style algorithm in modeler to enforce constraints? -/// how about ODE powered constraints e.g. motors? -/// -/// \todo enable suspension of bodies -/// ODE offers native support for suspending dynas. but what about suspending non-dynas -/// (e.g. geoms)? suspending geoms is also necessary to ease the load of ODE's (simple?) -/// collision detector. suspending dynas and geoms is important for the activity culling, -/// which apparently works at a simple level. perhaps suspension should actually -/// remove or insert geoms/dynas into the ODE space/world? is this operation (insertion/ -/// removal) fast enough at run-time? test it. if fast enough, then suspension=remove from -/// ODE simulation, awakening=insertion into ODE simulation. -/// -/// \todo python interface for tweaking constraints via python -/// -/// \todo raytesting to support gameengine sensors that need it -/// -/// \todo investigate compatibility issues with old Blender 2.25 physics engine (sumo/fuzzics) -/// is it possible to have compatibility? how hard is it? how important is it? - - -ODEPhysicsController::ODEPhysicsController(bool dyna, bool fullRigidBody, - bool phantom, class PHY_IMotionState* motionstate, struct dxSpace* space, - struct dxWorld* world, float mass,float friction,float restitution, - bool implicitsphere,float center[3],float extents[3],float radius) - : - m_OdeDyna(dyna), - m_firstTime(true), - m_bFullRigidBody(fullRigidBody), - m_bPhantom(phantom), - m_bKinematic(false), - m_bPrevKinematic(false), - m_MotionState(motionstate), - m_OdeSuspendDynamics(false), - m_space(space), - m_world(world), - m_mass(mass), - m_friction(friction), - m_restitution(restitution), - m_bodyId(0), - m_geomId(0), - m_implicitsphere(implicitsphere), - m_radius(radius) -{ - m_center[0] = center[0]; - m_center[1] = center[1]; - m_center[2] = center[2]; - m_extends[0] = extents[0]; - m_extends[1] = extents[1]; - m_extends[2] = extents[2]; -}; - - -ODEPhysicsController::~ODEPhysicsController() -{ - if (m_geomId) - { - dGeomDestroy (m_geomId); - } -} - -float ODEPhysicsController::getMass() -{ - dMass mass; - dBodyGetMass(m_bodyId,&mass); - return mass.mass; -} - -////////////////////////////////////////////////////////////////////// -/// \todo Impart some extra impulse to dynamic objects when they collide with kinematically controlled "static" objects (ODE geoms), by using last 2 frames as 1st order approximation to the linear/angular velocity, and computing an appropriate impulse. Sumo (old physics engine) did this, see for details. -/// \todo handle scaling of static ODE geoms or fail with error message if Ipo tries to change scale of a static geom object - -bool ODEPhysicsController::SynchronizeMotionStates(float time) -{ - /** - 'Late binding' of the rigidbody, because the World Scaling is not available until the scenegraph is traversed - */ - - - if (m_firstTime) - { - m_firstTime=false; - - m_MotionState->calculateWorldTransformations(); - - dQuaternion worldquat; - float worldpos[3]; - -#ifdef dDOUBLE - m_MotionState->getWorldOrientation((float)worldquat[1], - (float)worldquat[2],(float)worldquat[3],(float)worldquat[0]); -#else - m_MotionState->getWorldOrientation(worldquat[1], - worldquat[2],worldquat[3],worldquat[0]); -#endif - m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); - - float scaling[3]; - m_MotionState->getWorldScaling(scaling[0],scaling[1],scaling[2]); - - if (!m_bPhantom) - { - if (m_implicitsphere) - { - m_geomId = dCreateSphere (m_space,m_radius*scaling[0]); - } else - { - m_geomId = dCreateBox (m_space, m_extends[0]*scaling[0],m_extends[1]*scaling[1],m_extends[2]*scaling[2]); - } - } else - { - m_geomId=0; - } - - if (m_geomId) - dGeomSetData(m_geomId,this); - - if (!this->m_OdeDyna) - { - if (!m_bPhantom) - { - dGeomSetPosition (this->m_geomId,worldpos[0],worldpos[1],worldpos[2]); - dMatrix3 R; - dQtoR (worldquat, R); - dGeomSetRotation (this->m_geomId,R); - } - } else - { - //it's dynamic, so create a 'model' - m_bodyId = dBodyCreate(this->m_world); - dBodySetPosition (m_bodyId,worldpos[0],worldpos[1],worldpos[2]); - dBodySetQuaternion (this->m_bodyId,worldquat); - //this contains both scalar mass and inertia tensor - dMass m; - float length=1,width=1,height=1; - dMassSetBox (&m,1,m_extends[0]*scaling[0],m_extends[1]*scaling[1],m_extends[2]*scaling[2]); - dMassAdjust (&m,this->m_mass); - dBodySetMass (m_bodyId,&m); - - if (!m_bPhantom) - { - dGeomSetBody (m_geomId,m_bodyId); - } - - - } - - if (this->m_OdeDyna && !m_bFullRigidBody) - { - // ?? huh? what to do here? - } - } - - - - if (m_OdeDyna) - { - if (this->m_OdeSuspendDynamics) - { - return false; - } - - const float* worldPos = (float *)dBodyGetPosition(m_bodyId); - m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - - const float* worldquat = (float *)dBodyGetQuaternion(m_bodyId); - m_MotionState->setWorldOrientation(worldquat[1],worldquat[2],worldquat[3],worldquat[0]); - } - else { - // not a dyna, so dynamics (i.e. this controller) has not updated - // anything. BUT! an Ipo or something else might have changed the - // position/orientation of this geometry. - // so update the static geom position - - /// \todo impart some extra impulse to colliding objects! - dQuaternion worldquat; - float worldpos[3]; - -#ifdef dDOUBLE - m_MotionState->getWorldOrientation((float)worldquat[1], - (float)worldquat[2],(float)worldquat[3],(float)worldquat[0]); -#else - m_MotionState->getWorldOrientation(worldquat[1], - worldquat[2],worldquat[3],worldquat[0]); -#endif - m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); - - float scaling[3]; - m_MotionState->getWorldScaling(scaling[0],scaling[1],scaling[2]); - - /// \todo handle scaling! what if Ipo changes scale of object? - // Must propagate to geom... is scaling geoms possible with ODE? Also - // what about scaling trimeshes, that is certainly difficult... - dGeomSetPosition (this->m_geomId,worldpos[0],worldpos[1],worldpos[2]); - dMatrix3 R; - dQtoR (worldquat, R); - dGeomSetRotation (this->m_geomId,R); - } - - return false; //it update the worldpos -} - -PHY_IMotionState* ODEPhysicsController::GetMotionState() -{ - return m_MotionState; -} - - -// kinematic methods -void ODEPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local) -{ - -} -void ODEPhysicsController::RelativeRotate(const float drot[9],bool local) -{ -} -void ODEPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal) -{ - - dQuaternion worldquat; - worldquat[0] = quatReal; - worldquat[1] = quatImag0; - worldquat[2] = quatImag1; - worldquat[3] = quatImag2; - - if (!this->m_OdeDyna) - { - dMatrix3 R; - dQtoR (worldquat, R); - dGeomSetRotation (this->m_geomId,R); - } else - { - dBodySetQuaternion (m_bodyId,worldquat); - this->m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal); - } - -} - -void ODEPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) -{ - float q[4]; - this->m_MotionState->getWorldOrientation(q[0],q[1],q[2],q[3]); - quatImag0=q[0]; - quatImag1=q[1]; - quatImag2=q[2]; - quatReal=q[3]; -} - -void ODEPhysicsController::getPosition(PHY__Vector3& pos) const -{ - m_MotionState->getWorldPosition(pos[0],pos[1],pos[2]); - -} - -void ODEPhysicsController::setPosition(float posX,float posY,float posZ) -{ - if (!m_bPhantom) - { - if (!this->m_OdeDyna) - { - dGeomSetPosition (m_geomId, posX, posY, posZ); - } else - { - dBodySetPosition (m_bodyId, posX, posY, posZ); - } - } -} -void ODEPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) -{ -} - -// physics methods -void ODEPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local) -{ - if (m_OdeDyna) { - if(local) { - dBodyAddRelTorque(m_bodyId, torqueX, torqueY, torqueZ); - } else { - dBodyAddTorque (m_bodyId, torqueX, torqueY, torqueZ); - } - } -} - -void ODEPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local) -{ - if (m_OdeDyna) { - if(local) { - dBodyAddRelForce(m_bodyId, forceX, forceY, forceZ); - } else { - dBodyAddForce (m_bodyId, forceX, forceY, forceZ); - } - } -} - -void ODEPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local) -{ - if (m_OdeDyna) { - if(local) { - // TODO: translate angular vel into local frame, then apply - } else { - dBodySetAngularVel (m_bodyId, ang_velX,ang_velY,ang_velZ); - } - } -} - -void ODEPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local) -{ - if (m_OdeDyna) - { - dVector3 vel = {lin_velX,lin_velY,lin_velZ, 1.0}; - if (local) - { - dMatrix3 worldmat; - dVector3 localvel; - dQuaternion worldquat; - -#ifdef dDOUBLE - m_MotionState->getWorldOrientation((float)worldquat[1], - (float)worldquat[2], (float)worldquat[3],(float)worldquat[0]); -#else - m_MotionState->getWorldOrientation(worldquat[1],worldquat[2], - worldquat[3],worldquat[0]); -#endif - dQtoR (worldquat, worldmat); - - dMULTIPLY0_331 (localvel,worldmat,vel); - dBodySetLinearVel (m_bodyId, localvel[0],localvel[1],localvel[2]); - - } else - { - dBodySetLinearVel (m_bodyId, lin_velX,lin_velY,lin_velZ); - } - } -} - -void ODEPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) -{ - if (m_OdeDyna) - { - //apply linear and angular effect - const dReal* linvel = dBodyGetLinearVel(m_bodyId); - float mass = getMass(); - if (mass >= 0.00001f) - { - float massinv = 1.f/mass; - float newvel[3]; - newvel[0]=linvel[0]+impulseX*massinv; - newvel[1]=linvel[1]+impulseY*massinv; - newvel[2]=linvel[2]+impulseZ*massinv; - dBodySetLinearVel(m_bodyId,newvel[0],newvel[1],newvel[2]); - - const float* worldPos = (float *)dBodyGetPosition(m_bodyId); - - const float* angvelc = (float *)dBodyGetAngularVel(m_bodyId); - float angvel[3]; - angvel[0]=angvelc[0]; - angvel[1]=angvelc[1]; - angvel[2]=angvelc[2]; - - dVector3 impulse; - impulse[0]=impulseX; - impulse[1]=impulseY; - impulse[2]=impulseZ; - - dVector3 ap; - ap[0]=attachX-worldPos[0]; - ap[1]=attachY-worldPos[1]; - ap[2]=attachZ-worldPos[2]; - - dCROSS(angvel,+=,ap,impulse); - dBodySetAngularVel(m_bodyId,angvel[0],angvel[1],angvel[2]); - - } - - } - -} - -void ODEPhysicsController::SuspendDynamics() -{ - -} - -void ODEPhysicsController::RestoreDynamics() -{ - -} - - -/** - reading out information from physics -*/ -void ODEPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ) -{ - if (m_OdeDyna) - { - const float* vel = (float *)dBodyGetLinearVel(m_bodyId); - linvX = vel[0]; - linvY = vel[1]; - linvZ = vel[2]; - } else - { - linvX = 0.f; - linvY = 0.f; - linvZ = 0.f; - - } -} -/** - GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). -*/ -void ODEPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ) -{ - -} - - -void ODEPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ) -{ - -} -void ODEPhysicsController::setRigidBody(bool rigid) -{ - -} - - -void ODEPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) -{ - m_MotionState = motionstate; - m_bKinematic = false; - m_bPrevKinematic = false; - m_firstTime = true; -} - - -void ODEPhysicsController::SetSimulatedTime(float time) -{ -} - - -void ODEPhysicsController::WriteMotionStateToDynamics(bool nondynaonly) -{ - -} -#endif diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.h b/source/gameengine/Physics/BlOde/OdePhysicsController.h deleted file mode 100644 index 544d11da2ca..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __ODE_PHYSICSCONTROLLER_H -#define __ODE_PHYSICSCONTROLLER_H - - -#include "PHY_IPhysicsController.h" - -/** - ODE Physics Controller, a special kind of a PhysicsController. - A Physics Controller is a special kind of Scene Graph Transformation Controller. - Each time the scene graph get's updated, the controller get's a chance - in the 'Update' method to reflect changes. -*/ - -class ODEPhysicsController : public PHY_IPhysicsController - -{ - - bool m_OdeDyna; - -public: - ODEPhysicsController( - bool dyna, - bool fullRigidBody, - bool phantom, - class PHY_IMotionState* motionstate, - struct dxSpace* space, - struct dxWorld* world, - float mass, - float friction, - float restitution, - bool implicitsphere, - float center[3], - float extends[3], - float radius); - - virtual ~ODEPhysicsController(); - - // kinematic methods - virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local); - virtual void RelativeRotate(const float drot[9],bool local); - virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal); - virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal); - virtual void setPosition(float posX,float posY,float posZ); - virtual void getPosition(PHY__Vector3& pos) const; - - virtual void setScaling(float scaleX,float scaleY,float scaleZ); - - // physics methods - virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local); - virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local); - virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local); - virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local); - virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ); - virtual void SetActive(bool active){}; - virtual void SuspendDynamics(); - virtual void RestoreDynamics(); - virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) - { - //todo ? - } - - - /** - reading out information from physics - */ - virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ); - /** - GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). - */ - virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ); - virtual float getMass(); - virtual void getReactionForce(float& forceX,float& forceY,float& forceZ); - virtual void setRigidBody(bool rigid); - - - virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); - - // \todo remove next line ! - virtual void SetSimulatedTime(float time); - - - virtual void WriteDynamicsToMotionState() {}; - virtual void WriteMotionStateToDynamics(bool nondynaonly); - virtual class PHY_IMotionState* GetMotionState(); - - /** - call from Scene Graph Node to 'update'. - */ - virtual bool SynchronizeMotionStates(float time); - - virtual void calcXform(){} - virtual void SetMargin(float margin) {} - virtual float GetMargin() const {return 0.f;} - virtual float GetRadius() const {return 0.f;} - virtual void SetRadius(float margin) {} - - // clientinfo for raycasts for example - virtual void* getNewClientInfo() { return m_clientInfo;} - virtual void setNewClientInfo(void* clientinfo) {m_clientInfo = clientinfo;}; - void* m_clientInfo; - - struct dxBody* GetOdeBodyId() { return m_bodyId; } - - float getFriction() { return m_friction;} - float getRestitution() { return m_restitution;} - - float GetLinVelocityMin() const { return 0.f; } - void SetLinVelocityMin(float val) { } - float GetLinVelocityMax() const { return 0.f; } - void SetLinVelocityMax(float val) { } - - -private: - - bool m_firstTime; - bool m_bFullRigidBody; - bool m_bPhantom; // special flag for objects that are not affected by physics 'resolver' - - // data to calculate fake velocities for kinematic objects (non-dynas) - bool m_bKinematic; - bool m_bPrevKinematic; - - - float m_lastTime; - bool m_OdeSuspendDynamics; - class PHY_IMotionState* m_MotionState; - - //Ode specific members - struct dxBody* m_bodyId; - struct dxGeom* m_geomId; - struct dxSpace* m_space; - struct dxWorld* m_world; - float m_mass; - float m_friction; - float m_restitution; - bool m_implicitsphere; - float m_center[3]; - float m_extends[3]; - float m_radius; -}; - -#endif //__ODE_PHYSICSCONTROLLER_H - diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp deleted file mode 100644 index 54e97858b7f..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include "OdePhysicsEnvironment.h" -#include "PHY_IMotionState.h" -#include "OdePhysicsController.h" - -#include -#include <../ode/src/joint.h> -#include - -ODEPhysicsEnvironment::ODEPhysicsEnvironment() -{ - m_OdeWorld = dWorldCreate(); - m_OdeSpace = dHashSpaceCreate(); - m_OdeContactGroup = dJointGroupCreate (0); - dWorldSetCFM (m_OdeWorld,1e-5f); - - m_JointGroup = dJointGroupCreate(0); - - setFixedTimeStep(true,1.f/60.f); -} - - - -ODEPhysicsEnvironment::~ODEPhysicsEnvironment() -{ - dJointGroupDestroy (m_OdeContactGroup); - dJointGroupDestroy (m_JointGroup); - - dSpaceDestroy (m_OdeSpace); - dWorldDestroy (m_OdeWorld); -} - - - -void ODEPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) -{ - m_useFixedTimeStep = useFixedTimeStep; - - if (useFixedTimeStep) - { - m_fixedTimeStep = fixedTimeStep; - } else - { - m_fixedTimeStep = 0.f; - } - m_currentTime = 0.f; - - //todo:implement fixed timestepping - -} -float ODEPhysicsEnvironment::getFixedTimeStep() -{ - return m_fixedTimeStep; -} - - - -bool ODEPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep1,float interval) -{ - - float deltaTime = timeStep1; - int numSteps = 1; - - if (m_useFixedTimeStep) - { - m_currentTime += timeStep1; - // equal to subSampling (might be a little smaller). - numSteps = (int)(m_currentTime / m_fixedTimeStep); - m_currentTime -= m_fixedTimeStep * (float)numSteps; - deltaTime = m_fixedTimeStep; - //todo: experiment by smoothing the remaining time over the substeps - } - - for (int i=0;iClearOdeContactGroup(); - } - return true; -} - -void ODEPhysicsEnvironment::setGravity(float x,float y,float z) -{ - dWorldSetGravity (m_OdeWorld,x,y,z); -} - - - -int ODEPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ) -{ - - int constraintid = 0; - ODEPhysicsController* dynactrl = (ODEPhysicsController*)ctrl; - ODEPhysicsController* dynactrl2 = (ODEPhysicsController*)ctrl2; - - switch (type) - { - case PHY_POINT2POINT_CONSTRAINT: - { - if (dynactrl) - { - dJointID jointid = dJointCreateBall (m_OdeWorld,m_JointGroup); - struct dxBody* bodyid1 = dynactrl->GetOdeBodyId(); - struct dxBody* bodyid2=0; - const dReal* pos = dBodyGetPosition(bodyid1); - const dReal* R = dBodyGetRotation(bodyid1); - dReal offset[3] = {pivotX,pivotY,pivotZ}; - dReal newoffset[3]; - dMULTIPLY0_331 (newoffset,R,offset); - newoffset[0] += pos[0]; - newoffset[1] += pos[1]; - newoffset[2] += pos[2]; - - - if (dynactrl2) - bodyid2 = dynactrl2->GetOdeBodyId(); - - dJointAttach (jointid, bodyid1, bodyid2); - - dJointSetBallAnchor (jointid, newoffset[0], newoffset[1], newoffset[2]); - - constraintid = (int) jointid; - } - break; - } - case PHY_LINEHINGE_CONSTRAINT: - { - if (dynactrl) - { - dJointID jointid = dJointCreateHinge (m_OdeWorld,m_JointGroup); - struct dxBody* bodyid1 = dynactrl->GetOdeBodyId(); - struct dxBody* bodyid2=0; - const dReal* pos = dBodyGetPosition(bodyid1); - const dReal* R = dBodyGetRotation(bodyid1); - dReal offset[3] = {pivotX,pivotY,pivotZ}; - dReal axisset[3] = {axisX,axisY,axisZ}; - - dReal newoffset[3]; - dReal newaxis[3]; - dMULTIPLY0_331 (newaxis,R,axisset); - - dMULTIPLY0_331 (newoffset,R,offset); - newoffset[0] += pos[0]; - newoffset[1] += pos[1]; - newoffset[2] += pos[2]; - - - if (dynactrl2) - bodyid2 = dynactrl2->GetOdeBodyId(); - - dJointAttach (jointid, bodyid1, bodyid2); - - dJointSetHingeAnchor (jointid, newoffset[0], newoffset[1], newoffset[2]); - dJointSetHingeAxis(jointid,newaxis[0],newaxis[1],newaxis[2]); - - constraintid = (int) jointid; - } - break; - } - default: - { - //not yet - } - } - - return constraintid; - -} - -void ODEPhysicsEnvironment::removeConstraint(void *constraintid) -{ - if (constraintid) - { - dJointDestroy((dJointID) constraintid); - } -} - -PHY_IPhysicsController* ODEPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ) -{ - - //m_OdeWorld - //collision detection / raytesting - return NULL; -} - - -void ODEPhysicsEnvironment::OdeNearCallback (void *data, dGeomID o1, dGeomID o2) -{ - // \todo if this is a registered collision sensor - // fire the callback - - int i; - // if (o1->body && o2->body) return; - ODEPhysicsEnvironment* env = (ODEPhysicsEnvironment*) data; - dBodyID b1,b2; - - b1 = dGeomGetBody(o1); - b2 = dGeomGetBody(o2); - // exit without doing anything if the two bodies are connected by a joint - if (b1 && b2 && dAreConnected (b1,b2)) return; - - ODEPhysicsController * ctrl1 =(ODEPhysicsController *)dGeomGetData(o1); - ODEPhysicsController * ctrl2 =(ODEPhysicsController *)dGeomGetData(o2); - float friction=ctrl1->getFriction(); - float restitution = ctrl1->getRestitution(); - //for friction, take minimum - - friction=(friction < ctrl2->getFriction() ? - friction :ctrl2->getFriction()); - - //restitution:take minimum - restitution = restitution < ctrl2->getRestitution()? - restitution : ctrl2->getRestitution(); - - dContact contact[3]; // up to 3 contacts per box - for (i=0; i<3; i++) { - contact[i].surface.mode = dContactBounce; //dContactMu2; - contact[i].surface.mu = friction;//dInfinity; - contact[i].surface.mu2 = 0; - contact[i].surface.bounce = restitution;//0.5; - contact[i].surface.bounce_vel = 0.1f; - contact[i].surface.slip1=0.0; - } - - if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { - // dMatrix3 RI; - // dRSetIdentity (RI); - // const dReal ss[3] = {0.02,0.02,0.02}; - for (i=0; im_OdeWorld,env->m_OdeContactGroup,contact+i); - dJointAttach (c,b1,b2); - } - } -} - - -void ODEPhysicsEnvironment::ClearOdeContactGroup() -{ - dJointGroupEmpty (m_OdeContactGroup); -} - -int ODEPhysicsEnvironment::GetNumOdeContacts() -{ - return m_OdeContactGroup->num; -} - diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h deleted file mode 100644 index 54e4f7f90e1..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef _ODEPHYSICSENVIRONMENT -#define _ODEPHYSICSENVIRONMENT - - -#include "PHY_IPhysicsEnvironment.h" - -/** -* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) -* A derived class may be able to 'construct' entities by loading and/or converting -*/ -class ODEPhysicsEnvironment : public PHY_IPhysicsEnvironment -{ - - bool m_useFixedTimeStep; - float m_fixedTimeStep; - float m_currentTime; - -public: - ODEPhysicsEnvironment(); - virtual ~ODEPhysicsEnvironment(); - virtual void beginFrame() {} - virtual void endFrame() {} - - -// Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); - virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); - virtual float getFixedTimeStep(); - - virtual void setGravity(float x,float y,float z); - virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ); - - virtual void removeConstraint(void * constraintid); - virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes) { return false; } - - - //gamelogic callbacks - virtual void addSensor(PHY_IPhysicsController* ctrl) {} - virtual void removeSensor(PHY_IPhysicsController* ctrl) {} - virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) - { - } - virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl) {return false;} - virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl) {return false;} - virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;} - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} - - - - struct dxWorld* GetOdeWorld() { return m_OdeWorld; }; - struct dxSpace* GetOdeSpace() { return m_OdeSpace;}; - -private: - - - // ODE physics response - struct dxWorld* m_OdeWorld; - // ODE collision detection - struct dxSpace* m_OdeSpace; - void ClearOdeContactGroup(); - struct dxJointGroup* m_OdeContactGroup; - struct dxJointGroup* m_JointGroup; - - static void OdeNearCallback(void *data, struct dxGeom* o1, struct dxGeom* o2); - int GetNumOdeContacts(); - -}; - -#endif //_ODEPHYSICSENVIRONMENT - diff --git a/source/gameengine/Physics/BlOde/SConscript b/source/gameengine/Physics/BlOde/SConscript deleted file mode 100644 index 90e949d2d86..00000000000 --- a/source/gameengine/Physics/BlOde/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/python -Import ('user_options_dict') -Import ('library_env') - -phy_ode_env = library_env.Copy () - -source_files = ['OdePhysicsController.cpp', - 'OdePhysicsEnvironment.cpp'] - -phy_ode_env.Append (CPPPATH=['.', - '../common', - ]) -phy_ode_env.Append (CPPPATH=user_options_dict['ODE_INCLUDE']) - -phy_ode_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/PHY_Ode', source=source_files) diff --git a/source/gameengine/Physics/Dummy/Makefile b/source/gameengine/Physics/Dummy/Makefile index b0c1b855322..c016a0bebcb 100644 --- a/source/gameengine/Physics/Dummy/Makefile +++ b/source/gameengine/Physics/Dummy/Makefile @@ -39,7 +39,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../Physics/common CPPFLAGS += -I../../Physics/Dummy diff --git a/source/gameengine/Physics/Makefile b/source/gameengine/Physics/Makefile index b192e497f35..da0d4cafd2e 100644 --- a/source/gameengine/Physics/Makefile +++ b/source/gameengine/Physics/Makefile @@ -32,7 +32,6 @@ include nan_definitions.mk SOURCEDIR = source/gameengine/Physics DIR = $(OCGDIR)/gameengine/blphys -DIRS = common Sumo Dummy Bullet -#DIRS += BlOde +DIRS = common Dummy Bullet include nan_subdirs.mk diff --git a/source/gameengine/Physics/Sumo/CMakeLists.txt b/source/gameengine/Physics/Sumo/CMakeLists.txt deleted file mode 100644 index c57a4af6706..00000000000 --- a/source/gameengine/Physics/Sumo/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -# $Id$ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -SET(SRC - SumoPHYCallbackBridge.cpp - SumoPhysicsController.cpp - SumoPhysicsEnvironment.cpp - Fuzzics/src/SM_FhObject.cpp - Fuzzics/src/SM_Object.cpp - Fuzzics/src/SM_Scene.cpp - Fuzzics/src/SM_MotionState.cpp -) - -SET(INC - . - ../common - Fuzzics/include - ../../../../intern/moto/include - ../../../../extern/solid -) - -BLENDERLIB(bf_sumo "${SRC}" "${INC}") -#env.BlenderLib ( 'bf_sumo', sources, incs, [], libtype=['game2','player'], priority=[30, 70] , compileflags=cflags) diff --git a/source/gameengine/Physics/Sumo/Fuzzics/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/Makefile deleted file mode 100644 index 5ed2c31a1d0..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Bounces make to subdirectories. - -SOURCEDIR = source/gameengine/Physics/Sumo/Fuzzics -DIRS = src - -include nan_subdirs.mk diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h deleted file mode 100644 index 42b5ab48ab6..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef SM_CALLBACK_H -#define SM_CALLBACK_H - -class SM_Callback { -public: - virtual void do_me() = 0; - virtual ~SM_Callback() {} -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h deleted file mode 100644 index 6749e7957ec..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __SM_CLIENTOBJECT_INFO_H -#define __SM_CLIENTOBJECT_INFO_H - -/** - * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks - */ - -struct SM_ClientObjectInfo -{ - int m_type; - void* m_clientobject1; - void* m_auxilary_info; -}; - -#endif //__SM_CLIENTOBJECT_INFO_H - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h deleted file mode 100644 index 48d5906e53d..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h +++ /dev/null @@ -1,26 +0,0 @@ - - -#ifndef __SM_DEBUG_H__ -#define __SM_DEBUG_H__ - -/* Comment this to disable all SUMO debugging printfs */ - -#define SM_DEBUG - -#ifdef SM_DEBUG - -#include - -/* Uncomment this to printf all ray casts */ -//#define SM_DEBUG_RAYCAST - -/* Uncomment this to printf collision callbacks */ -//#define SM_DEBUG_BOING - -/* Uncomment this to printf Xform matrix calculations */ -//#define SM_DEBUG_XFORM - -#endif /* SM_DEBUG */ - -#endif /* __SM_DEBUG_H__ */ - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h deleted file mode 100644 index b03612ed15e..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_FHOBJECT_H -#define SM_FHOBJECT_H - -#include "SM_Object.h" - -class SM_FhObject : public SM_Object { -public: - virtual ~SM_FhObject(); - SM_FhObject(DT_ShapeHandle rayshape, MT_Vector3 ray, SM_Object *parent_object); - - const MT_Vector3& getRay() const { return m_ray; } - MT_Point3 getSpot() const { return getPosition() + m_ray; } - const MT_Vector3& getRayDirection() const { return m_ray_direction; } - SM_Object *getParentObject() const { return m_parent_object; } - - static DT_Bool ray_hit(void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data); - -private: - MT_Vector3 m_ray; - MT_Vector3 m_ray_direction; - SM_Object *m_parent_object; -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h deleted file mode 100644 index fdc45af5225..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_MOTIONSTATE_H -#define SM_MOTIONSTATE_H - -#include "MT_Transform.h" - -class SM_MotionState { -public: - SM_MotionState() : - m_time(0.0), - m_pos(0.0, 0.0, 0.0), - m_orn(0.0, 0.0, 0.0, 1.0), - m_lin_vel(0.0, 0.0, 0.0), - m_ang_vel(0.0, 0.0, 0.0) - {} - - void setPosition(const MT_Point3& pos) { m_pos = pos; } - void setOrientation(const MT_Quaternion& orn) { m_orn = orn; } - void setLinearVelocity(const MT_Vector3& lin_vel) { m_lin_vel = lin_vel; } - void setAngularVelocity(const MT_Vector3& ang_vel) { m_ang_vel = ang_vel; } - void setTime(MT_Scalar time) { m_time = time; } - - const MT_Point3& getPosition() const { return m_pos; } - const MT_Quaternion& getOrientation() const { return m_orn; } - const MT_Vector3& getLinearVelocity() const { return m_lin_vel; } - const MT_Vector3& getAngularVelocity() const { return m_ang_vel; } - - MT_Scalar getTime() const { return m_time; } - - void integrateMidpoint(MT_Scalar timeStep, const SM_MotionState &prev_state, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel); - void integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel); - void integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state); - - void lerp(const SM_MotionState &prev, const SM_MotionState &next); - void lerp(MT_Scalar t, const SM_MotionState &other); - - virtual MT_Transform getTransform() const { - return MT_Transform(m_pos, m_orn); - } - -protected: - MT_Scalar m_time; - MT_Point3 m_pos; - MT_Quaternion m_orn; - MT_Vector3 m_lin_vel; - MT_Vector3 m_ang_vel; -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h deleted file mode 100644 index 2d748a0f251..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h +++ /dev/null @@ -1,393 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_OBJECT_H -#define SM_OBJECT_H - -#include - -#include - -#include "SM_Callback.h" -#include "SM_MotionState.h" -#include - -class SM_FhObject; - -/** Properties of dynamic objects */ -struct SM_ShapeProps { - MT_Scalar m_mass; ///< Total mass - MT_Scalar m_radius; ///< Bound sphere size - MT_Vector3 m_inertia; ///< Inertia, should be a tensor some time - MT_Scalar m_lin_drag; ///< Linear drag (air, water) 0 = concrete, 1 = vacuum - MT_Scalar m_ang_drag; ///< Angular drag - MT_Scalar m_friction_scaling[3]; ///< Scaling for anisotropic friction. Component in range [0, 1] - bool m_do_anisotropic; ///< Should I do anisotropic friction? - bool m_do_fh; ///< Should the object have a linear Fh spring? - bool m_do_rot_fh; ///< Should the object have an angular Fh spring? -}; - - -/** Properties of collidable objects (non-ghost objects) */ -struct SM_MaterialProps { - MT_Scalar m_restitution; ///< restitution of energy after a collision 0 = inelastic, 1 = elastic - MT_Scalar m_friction; ///< Coulomb friction (= ratio between the normal en maximum friction force) - MT_Scalar m_fh_spring; ///< Spring constant (both linear and angular) - MT_Scalar m_fh_damping; ///< Damping factor (linear and angular) in range [0, 1] - MT_Scalar m_fh_distance; ///< The range above the surface where Fh is active. - bool m_fh_normal; ///< Should the object slide off slopes? -}; - -class SM_ClientObject -{ -public: - SM_ClientObject() {} - virtual ~SM_ClientObject() {} - - virtual bool hasCollisionCallback() = 0; -}; - -/** - * SM_Object is an internal part of the Sumo physics engine. - * - * It encapsulates an object in the physics scene, and is responsible - * for calculating the collision response of objects. - */ -class SM_Object -{ -public: - SM_Object() ; - SM_Object( - DT_ShapeHandle shape, - const SM_MaterialProps *materialProps, - const SM_ShapeProps *shapeProps, - SM_Object *dynamicParent - ); - virtual ~SM_Object(); - - bool isDynamic() const; - - /* nzc experimental. There seem to be two places where kinematics - * are evaluated: proceedKinematic (called from SM_Scene) and - * proceed() in this object. I'll just try and bunge these out for - * now. */ - - void suspend(void); - void resume(void); - - void suspendDynamics(); - - void restoreDynamics(); - - bool isGhost() const; - - void suspendMaterial(); - - void restoreMaterial(); - - SM_FhObject *getFhObject() const; - - void registerCallback(SM_Callback& callback); - - void calcXform(); - void notifyClient(); - void updateInvInertiaTensor(); - - - // Save the current state information for use in the - // velocity computation in the next frame. - - void proceedKinematic(MT_Scalar timeStep); - - void saveReactionForce(MT_Scalar timeStep) ; - - void clearForce() ; - - void clearMomentum() ; - - void setMargin(MT_Scalar margin) ; - - MT_Scalar getMargin() const ; - - const SM_MaterialProps *getMaterialProps() const ; - - const SM_ShapeProps *getShapeProps() const ; - - void setPosition(const MT_Point3& pos); - void setOrientation(const MT_Quaternion& orn); - void setScaling(const MT_Vector3& scaling); - - /** - * set an external velocity. This velocity complements - * the physics velocity. So setting it does not override the - * physics velocity. It is your responsibility to clear - * this external velocity. This velocity is not subject to - * friction or damping. - */ - void setExternalLinearVelocity(const MT_Vector3& lin_vel) ; - void addExternalLinearVelocity(const MT_Vector3& lin_vel) ; - - /** Override the physics velocity */ - void addLinearVelocity(const MT_Vector3& lin_vel); - void setLinearVelocity(const MT_Vector3& lin_vel); - - /** - * Set an external angular velocity. This velocity complemetns - * the physics angular velocity so does not override it. It is - * your responsibility to clear this velocity. This velocity - * is not subject to friction or damping. - */ - void setExternalAngularVelocity(const MT_Vector3& ang_vel) ; - void addExternalAngularVelocity(const MT_Vector3& ang_vel); - - /** Override the physics angular velocity */ - void addAngularVelocity(const MT_Vector3& ang_vel); - void setAngularVelocity(const MT_Vector3& ang_vel); - - /** Clear the external velocities */ - void clearCombinedVelocities(); - - /** - * Tell the physics system to combine the external velocity - * with the physics velocity. - */ - void resolveCombinedVelocities( - const MT_Vector3 & lin_vel, - const MT_Vector3 & ang_vel - ) ; - - - - MT_Scalar getInvMass() const; - - const MT_Vector3& getInvInertia() const ; - - const MT_Matrix3x3& getInvInertiaTensor() const; - - void applyForceField(const MT_Vector3& accel) ; - - void applyCenterForce(const MT_Vector3& force) ; - - void applyTorque(const MT_Vector3& torque) ; - - /** - * Apply an impulse to the object. The impulse will be split into - * angular and linear components. - * @param attach point to apply the impulse to (in world coordinates) - */ - void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) ; - - /** - * Applies an impulse through the center of this object. (ie the angular - * velocity will not change. - */ - void applyCenterImpulse(const MT_Vector3& impulse); - /** - * Applies an angular impulse. - */ - void applyAngularImpulse(const MT_Vector3& impulse); - - MT_Point3 getWorldCoord(const MT_Point3& local) const; - MT_Point3 getLocalCoord(const MT_Point3& world) const; - - MT_Vector3 getVelocity(const MT_Point3& local) const; - - - const MT_Vector3& getReactionForce() const ; - - void getMatrix(double *m) const ; - - const double *getMatrix() const ; - - // Still need this??? - const MT_Transform& getScaledTransform() const; - - DT_ObjectHandle getObjectHandle() const ; - DT_ShapeHandle getShapeHandle() const ; - - SM_Object *getDynamicParent() ; - - void integrateForces(MT_Scalar timeStep); - void integrateMomentum(MT_Scalar timeSteo); - - void setRigidBody(bool is_rigid_body) ; - - bool isRigidBody() const ; - - // This is the callback for handling collisions of dynamic objects - static - DT_Bool - boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data - ); - - static - DT_Bool - fix( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data - ); - - - SM_ClientObject *getClientObject() { return m_client_object; } - void setClientObject(SM_ClientObject *client_object) { m_client_object = client_object; } - void setPhysicsClientObject(void* physicsClientObject) - { - m_physicsClientObject = physicsClientObject; - } - void* getPhysicsClientObject() { - return m_physicsClientObject; - } - void relax(); - - SM_MotionState &getCurrentFrame(); - SM_MotionState &getPreviousFrame(); - SM_MotionState &getNextFrame(); - - const SM_MotionState &getCurrentFrame() const; - const SM_MotionState &getPreviousFrame() const; - const SM_MotionState &getNextFrame() const; - - // Motion state functions - const MT_Point3& getPosition() const; - const MT_Quaternion& getOrientation() const; - const MT_Vector3& getLinearVelocity() const; - const MT_Vector3& getAngularVelocity() const; - - MT_Scalar getTime() const; - - void setTime(MT_Scalar time); - - void interpolate(MT_Scalar timeStep); - void endFrame(); - -private: - friend class Contact; - // Tweak parameters - static MT_Scalar ImpulseThreshold; - - // return the actual linear_velocity of this object this - // is the addition of m_combined_lin_vel and m_lin_vel. - - const - MT_Vector3 - actualLinVelocity( - ) const ; - - const - MT_Vector3 - actualAngVelocity( - ) const ; - - void dynamicCollision(const MT_Point3 &local2, - const MT_Vector3 &normal, - MT_Scalar dist, - const MT_Vector3 &rel_vel, - MT_Scalar restitution, - MT_Scalar friction_factor, - MT_Scalar invMass - ); - - typedef std::vector T_CallbackList; - - - T_CallbackList m_callbackList; // Each object can have multiple callbacks from the client (=game engine) - SM_Object *m_dynamicParent; // Collisions between parent and children are ignored - - // as the collision callback now has only information - // on an SM_Object, there must be a way that the SM_Object client - // can identify it's clientdata after a collision - SM_ClientObject *m_client_object; - - void* m_physicsClientObject; - - DT_ShapeHandle m_shape; // Shape for collision detection - - // Material and shape properties are not owned by this class. - - const SM_MaterialProps *m_materialProps; - const SM_MaterialProps *m_materialPropsBackup; // Backup in case the object temporarily becomes a ghost. - const SM_ShapeProps *m_shapeProps; - const SM_ShapeProps *m_shapePropsBackup; // Backup in case the object's dynamics is temporarily suspended - DT_ObjectHandle m_object; // A handle to the corresponding object in SOLID. - MT_Scalar m_margin; // Offset for the object's shape (also for collision detection) - MT_Vector3 m_scaling; // Non-uniform scaling of the object's shape - - double m_ogl_matrix[16]; // An OpenGL-type 4x4 matrix - MT_Transform m_xform; // The object's local coordinate system - MT_Transform m_prev_xform; // The object's local coordinate system in the previous frame - SM_MotionState m_prev_state; // The object's motion state in the previous frame - MT_Scalar m_timeStep; // The duration of the last frame - - MT_Vector3 m_reaction_impulse; // The accumulated impulse resulting from collisions - MT_Vector3 m_reaction_force; // The reaction force derived from the reaction impulse - - MT_Vector3 m_lin_mom; // Linear momentum (linear velocity times mass) - MT_Vector3 m_ang_mom; // Angular momentum (angualr velocity times inertia) - MT_Vector3 m_force; // Force on center of mass (afffects linear momentum) - MT_Vector3 m_torque; // Torque around center of mass (affects angular momentum) - - SM_MotionState m_frames[3]; - - MT_Vector3 m_error; // Error in position:- amount object must be moved to prevent intersection with scene - - // Here are the values of externally set linear and angular - // velocity. These are updated from the outside - // (actuators and python) each frame and combined with the - // physics values. At the end of each frame (at the end of a - // call to proceed) they are set to zero. This allows the - // outside world to contribute to the velocity of an object - // but still have it react to physics. - - MT_Vector3 m_combined_lin_vel; - MT_Vector3 m_combined_ang_vel; - - // The force and torque are the accumulated forces and torques applied by the client (game logic, python). - - SM_FhObject *m_fh_object; // The ray object used for Fh - bool m_suspended; // Is this object frozen? - - // Mass properties - MT_Scalar m_inv_mass; // 1/mass - MT_Vector3 m_inv_inertia; // [1/inertia_x, 1/inertia_y, 1/inertia_z] - MT_Matrix3x3 m_inv_inertia_tensor; // Inverse Inertia Tensor - - bool m_kinematic; // Have I been displaced (translated, rotated, scaled) in this frame? - bool m_prev_kinematic; // Have I been displaced (translated, rotated, scaled) in the previous frame? - bool m_is_rigid_body; // Should friction give me a change in angular momentum? - int m_static; // temporarily static. - -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h deleted file mode 100644 index 81b4cb55b45..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_PROPSH -#define SM_PROPSH - -#include - -// Properties of dynamic objects -struct SM_ShapeProps { - MT_Scalar m_mass; // Total mass - MT_Scalar m_inertia; // Inertia, should be a tensor some time - MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum - MT_Scalar m_ang_drag; // Angular drag - MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1] - bool m_do_anisotropic; // Should I do anisotropic friction? - bool m_do_fh; // Should the object have a linear Fh spring? - bool m_do_rot_fh; // Should the object have an angular Fh spring? -}; - - -// Properties of collidable objects (non-ghost objects) -struct SM_MaterialProps { - MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic - MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force) - MT_Scalar m_fh_spring; // Spring constant (both linear and angular) - MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1] - MT_Scalar m_fh_distance; // The range above the surface where Fh is active. - bool m_fh_normal; // Should the object slide off slopes? -}; - -#endif //SM_PROPSH - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h deleted file mode 100644 index 3d8eef2bae0..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * $Id$ - * Copyright (C) 2001 NaN Technologies B.V. - * The physics scene. - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_SCENE_H -#define SM_SCENE_H - -#ifdef WIN32 -#pragma warning (disable : 4786) -#endif - -#include -#include -#include //needed for pair - -#include - -#include "MT_Vector3.h" -#include "MT_Point3.h" - -#include "SM_Object.h" - -enum -{ - FH_RESPONSE, - SENSOR_RESPONSE, /* Touch Sensors */ - CAMERA_RESPONSE, /* Visibility Culling */ - OBJECT_RESPONSE, /* Object Dynamic Geometry Response */ - STATIC_RESPONSE, /* Static Geometry Response */ - - NUM_RESPONSE -}; - -class SM_Scene { -public: - SM_Scene(); - - ~SM_Scene(); - - DT_RespTableHandle getRespTableHandle() const { - return m_respTable; - } - - const MT_Vector3& getForceField() const { - return m_forceField; - } - - MT_Vector3& getForceField() { - return m_forceField; - } - - void setForceField(const MT_Vector3& forceField) { - m_forceField = forceField; - } - - void addTouchCallback(int response_class, DT_ResponseCallback callback, void *user); - - void addSensor(SM_Object& object); - void add(SM_Object& object); - void remove(SM_Object& object); - - void notifyCollision(SM_Object *obj1, SM_Object *obj2); - - void setSecondaryRespTable(DT_RespTableHandle secondaryRespTable); - DT_RespTableHandle getSecondaryRespTable() { return m_secondaryRespTable; } - - void requestCollisionCallback(SM_Object &object); - - void beginFrame(); - void endFrame(); - - // Perform an integration step of duration 'timeStep'. - // 'subSampling' is the maximum duration of a substep, i.e., - // The maximum time interval between two collision checks. - // 'subSampling' can be used to control aliasing effects - // (fast moving objects traversing through walls and such). - bool proceed(MT_Scalar curtime, MT_Scalar ticrate); - void proceed(MT_Scalar subStep); - - /** - * Test whether any objects lie on the line defined by from and - * to. The search returns the first such bject starting at from, - * or NULL if there was none. - * @returns A reference to the object, or NULL if there was none. - * @param ignore_client Do not look for collisions with this - * object. This can be useful to avoid self-hits if - * starting from the location of an object. - * @param from The start point, in world coordinates, of the search. - * @param to The end point, in world coordinates, of the search. - * @param result A store to return the point where intersection - * took place (if there was an intersection). - * @param normal A store to return the normal of the hit object on - * the location of the intersection, if it took place. - */ - SM_Object *rayTest(void *ignore_client, - const MT_Point3& from, const MT_Point3& to, - MT_Point3& result, MT_Vector3& normal) const; - -private: - - // Clear the user set velocities. - void clearObjectCombinedVelocities(); - // This is the callback for handling collisions of dynamic objects - static - DT_Bool - boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data - ); - - /** internal type */ - typedef std::vector T_ObjectList; - - /** Handle to the scene in SOLID */ - DT_SceneHandle m_scene; - /** Following response table contains the callbacks for the dynmics */ - DT_RespTableHandle m_respTable; - DT_ResponseClass m_ResponseClass[NUM_RESPONSE]; - /** - * Following response table contains callbacks for the client (= - * game engine) */ - DT_RespTableHandle m_secondaryRespTable; // Handle - DT_ResponseClass m_secondaryResponseClass[NUM_RESPONSE]; - - /** - * Following resposne table contains callbacks for fixing the simulation - * ie making sure colliding objects do not intersect. - */ - DT_RespTableHandle m_fixRespTable; - DT_ResponseClass m_fixResponseClass[NUM_RESPONSE]; - - /** The acceleration from the force field */ - MT_Vector3 m_forceField; - - /** - * The list of objects that receive motion updates and do - * collision tests. */ - T_ObjectList m_objectList; - - unsigned int m_frames; -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile deleted file mode 100644 index 672dff39028..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# -# $Id$ -# Copyright (C) 2001 NaN Technologies B.V. - -DIR = $(OCGDIR)/sumo -ALLTARGETS = $(OBJS) $(DIR)/$(DEBUG_DIR)particle $(DIR)/$(DEBUG_DIR)particle0 - -include nan_compile.mk - -CPPFLAGS = -I../../include -I../include -I$(NAN_MOTO)/include -CPPFLAGS += -I$(OPENGL_HEADERS) - -clean:: - @$(RM) $(DIR)/particle $(DIR)/particle0 - @$(RM) $(DIR)/debug/particle $(DIR)/debug/particle0 - -LDFLAGS = -L$(DIR) -L/usr/X11R6/lib -OGL_LDLIBS = -lglut -lGLU -lGL -pthread -LDLIBS = -lfuzzics -lsolid $(NAN_MOTO)/lib/libmoto.a $(OGL_LDLIBS) - -$(DIR)/$(DEBUG_DIR)particle: particle.o $(DIR)/$(DEBUG_DIR)libfuzzics.a $(DIR)/$(DEBUG_DIR)libsolid.a - $(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS) - -$(DIR)/$(DEBUG_DIR)particle0: particle0.o $(DIR)/$(DEBUG_DIR)libfuzzics.a $(DIR)/$(DEBUG_DIR)libsolid.a - $(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS) diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp deleted file mode 100644 index d7aca326b42..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp +++ /dev/null @@ -1,709 +0,0 @@ -//#define FAKE_IT -#define USE_COMPLEX -#define QUADS - -#include -#include -#include - -#include "MT_MinMax.h" -#include "MT_Point3.h" -#include "MT_Vector3.h" -#include "MT_Quaternion.h" -#include "MT_Matrix3x3.h" -#include "MT_Transform.h" - -#include "SM_Object.h" -#include "SM_FhObject.h" -#include "SM_Scene.h" - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -const MT_Scalar bowl_curv = 0.10; -const MT_Scalar timeStep = 0.02; -const MT_Scalar ground_margin = 0.0; -const MT_Scalar sphere_radius = 0.5; - -const MT_Vector3 gravity(0, -9.8, 0); - -static MT_Scalar DISTANCE = 5; - -static MT_Scalar ele = 0, azi = 0; -static MT_Point3 eye(0, 0, DISTANCE); -static MT_Point3 center(0, 0, 0); - -inline double irnd() { return 2 * MT_random() - 1; } - -static const double SCALE_BOTTOM = 0.5; -static const double SCALE_FACTOR = 2.0; - -SM_ShapeProps g_shapeProps = { - 1.0, // mass - 1.0, // inertia - 0.1, // linear drag - 0.1, // angular drag - { 1.0, 0.0, 0.0 }, // anisotropic friction - false, // do anisotropic friction? - true, // do fh? - true // do rot fh? -}; - -SM_MaterialProps g_materialProps = { - 0.7, // restitution - 0.0, // friction - 10.0, // Fh spring constant - 1.0, // Fh damping - 0.5, // Fh distance - true // Fh leveling -}; - - -void toggleIdle(); - - -void newRandom(); - -void coordSystem() { - glDisable(GL_LIGHTING); - glBegin(GL_LINES); - glColor3f(1, 0, 0); - glVertex3d(0, 0, 0); - glVertex3d(10, 0, 0); - glColor3f(0, 1, 0); - glVertex3d(0, 0, 0); - glVertex3d(0, 10, 0); - glColor3f(0, 0, 1); - glVertex3d(0, 0, 0); - glVertex3d(0, 0, 10); - glEnd(); - glEnable(GL_LIGHTING); -} - - -void display_bbox(const MT_Point3& min, const MT_Point3& max) { - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(0, 1, 1); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glBegin(GL_QUAD_STRIP); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glVertex3d(max[0], min[1], min[2]); - glVertex3d(max[0], min[1], max[2]); - glVertex3d(max[0], max[1], min[2]); - glVertex3d(max[0], max[1], max[2]); - glVertex3d(min[0], max[1], min[2]); - glVertex3d(min[0], max[1], max[2]); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glEnd(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -} - - - - -class GLShape { -public: - virtual void paint(GLdouble *m) const = 0; -}; - - -class GLSphere : public GLShape { - MT_Scalar radius; -public: - GLSphere(MT_Scalar r) : radius(r) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glutSolidSphere(radius, 20, 20); - glPopMatrix(); - } -}; - - -class GLBox : public GLShape { - MT_Vector3 extent; -public: - GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) : - extent(x, y, z) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glPushMatrix(); - glScaled(extent[0], extent[1], extent[2]); - glutSolidCube(1.0); - glPopMatrix(); - glPopMatrix(); - } -}; - - -class GLCone : public GLShape { - MT_Scalar bottomRadius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCone(MT_Scalar r, MT_Scalar h) : - bottomRadius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, bottomRadius, 0, height, 15, 10); - glPopMatrix(); - glEndList(); - } - glPopMatrix(); - } -}; - -class GLCylinder : public GLShape { - MT_Scalar radius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCylinder(MT_Scalar r, MT_Scalar h) : - radius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, radius, radius, height, 15, 10); - glPopMatrix (); - glEndList(); - } - glPopMatrix(); - } -}; - -class Object; - -class Callback : public SM_Callback { -public: - Callback(Object& object) : m_object(object) {} - - virtual void do_me(); - -private: - Object& m_object; -}; - - -class Object { -public: - Object(GLShape *gl_shape, SM_Object& object) : - m_gl_shape(gl_shape), - m_object(object), - m_callback(*this) - { - m_object.registerCallback(m_callback); - } - - ~Object() {} - - void paint() { - if (m_gl_shape) { - m_gl_shape->paint(m); - // display_bbox(m_bbox.lower(), m_bbox.upper()); - } - } - - void print_reaction_force() const { - std::cout << m_object.getReactionForce() << std::endl; - } - - MT_Vector3 getAhead() { - return MT_Vector3(&m[4]); - } - - MT_Vector3 getUp() { - return MT_Vector3(&m[8]); - } - - void clearMomentum() { - m_object.clearMomentum(); - } - - void setMargin(MT_Scalar margin) { - m_object.setMargin(margin); - } - - void setScaling(const MT_Vector3& scaling) { - m_object.setScaling(scaling); - } - - const MT_Point3& getPosition() { - return m_object.getPosition(); - } - - void setPosition(const MT_Point3& pos) { - m_object.setPosition(pos); - } - - void setOrientation(const MT_Quaternion& orn) { - m_object.setOrientation(orn); - } - - void applyCenterForce(const MT_Vector3& force) { - m_object.applyCenterForce(force); - } - - void applyTorque(const MT_Vector3& torque) { - m_object.applyTorque(torque); - } - - MT_Point3 getWorldCoord(const MT_Point3& local) const { - return m_object.getWorldCoord(local); - } - - MT_Vector3 getLinearVelocity() const { - return m_object.getLinearVelocity(); - } - - MT_Vector3 getAngularVelocity() const { - return m_object.getAngularVelocity(); - } - - void setMatrix() { - m_object.calcXform(); - m_object.getMatrix(m); - } - - const double *getMatrix() { - m_object.calcXform(); - return m_object.getMatrix(); - } - -private: - GLShape *m_gl_shape; - SM_Object& m_object; - DT_Scalar m[16]; - Callback m_callback; -}; - - - -const MT_Scalar SPACE_SIZE = 2; - -static GLSphere gl_sphere(sphere_radius); -static GLBox gl_ground(50.0, 0.0, 50.0); - - - -#ifdef USE_COMPLEX - -const int GRID_SCALE = 10; -const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE; - -DT_ShapeHandle createComplex() { - DT_ShapeHandle shape = DT_NewComplexShape(); - for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) { - for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) { - int i1 = i0 + 1; - int j1 = j0 + 1; -#ifdef QUADS - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0); - DT_End(); -#else - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_End(); - - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0); - DT_End(); -#endif - - } - } - DT_EndComplexShape(); - return shape; -} - - -static DT_ShapeHandle ground_shape = createComplex(); - -#else - -static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50); - -#endif - -static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0); -static Object ground(&gl_ground, sm_ground); - -static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0); -static Object object(&gl_sphere, sm_sphere); - - -static SM_Scene g_scene; - - -bool g_hit = false; -MT_Point3 g_spot; -MT_Vector3 g_normal; - - -void Callback::do_me() -{ - m_object.setMatrix(); - m_object.print_reaction_force(); -} - -void myinit(void) { - - GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; - GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; - - /* light_position is NOT default value */ - GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; - GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; - - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - - glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT1, GL_POSITION, light_position1); - - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - // glEnable(GL_CULL_FACE); - // glCullFace(GL_BACK); - - ground.setPosition(MT_Point3(0, -10, 0)); - ground.setOrientation(MT_Quaternion(0, 0, 0, 1)); - ground.setMatrix(); - center.setValue(0.0, 0.0, 0.0); - sm_ground.setMargin(ground_margin); - - g_scene.setForceField(gravity); - g_scene.add(sm_ground); - - object.setMargin(sphere_radius); - - g_scene.add(sm_sphere); - - - newRandom(); -} - - -//MT_Point3 cp1, cp2; -//bool intersection; - -void display(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ground.paint(); - object.paint(); - - if (g_hit) { - glDisable(GL_LIGHTING); - glColor3f(1, 0, 0); - - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(g_spot[0], g_spot[1], g_spot[2]); - glEnd(); - glPointSize(1); - - glColor3f(1, 1, 0); - glBegin(GL_LINES); - glVertex3d(g_spot[0], g_spot[1], g_spot[2]); - glVertex3d(g_spot[0] + g_normal[0], - g_spot[1] + g_normal[1], - g_spot[2] + g_normal[2]); - glEnd(); - glEnable(GL_LIGHTING); - } - - - -#ifdef COLLISION - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(1, 1, 0); - if (intersection) { - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glEnd(); - glPointSize(1); - } - else { - glBegin(GL_LINES); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glVertex3d(cp2[0], cp2[1], cp2[2]); - glEnd(); - } - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -#endif - - glFlush(); - glutSwapBuffers(); -} - - - - - -void newRandom() { - object.setPosition(MT_Point3(0, 0, 0)); - object.setOrientation(MT_Quaternion::random()); - object.clearMomentum(); - object.setMatrix(); - - display(); -} - -void moveAndDisplay() { - g_scene.proceed(timeStep, 0.01); - - display(); - g_hit = false; -} - - -void turn_left() { - object.applyTorque(5.0 * object.getUp()); -} - -void turn_right() { - object.applyTorque(-5.0 * object.getUp()); -} - -void forward() { - object.applyCenterForce(10.0 * object.getAhead()); -} - -void backward() { - object.applyCenterForce(-10.0 * object.getAhead()); -} - -void jump() { - object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0)); -} - - -void toggleIdle() { - static bool idle = true; - if (idle) { - glutIdleFunc(moveAndDisplay); - idle = false; - } - else { - glutIdleFunc(NULL); - idle = true; - } -} - - -void setCamera() { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); - MT_Scalar rele = MT_radians(ele); - MT_Scalar razi = MT_radians(azi); - eye.setValue(DISTANCE * sin(razi) * cos(rele), - DISTANCE * sin(rele), - DISTANCE * cos(razi) * cos(rele)); - gluLookAt(eye[0], eye[1], eye[2], - center[0], center[1], center[2], - 0, 1, 0); - glMatrixMode(GL_MODELVIEW); - display(); -} - -const MT_Scalar STEPSIZE = 5; - -void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void zoomIn() { DISTANCE -= 1; setCamera(); } -void zoomOut() { DISTANCE += 1; setCamera(); } - - -void myReshape(int w, int h) { - glViewport(0, 0, w, h); - setCamera(); -} - -void myKeyboard(unsigned char key, int x, int y) -{ - switch (key) - { - case 'w': forward(); break; - case 's': backward(); break; - case 'a': turn_left(); break; - case 'd': turn_right(); break; - case 'e': jump(); break; - case 'l' : stepLeft(); break; - case 'r' : stepRight(); break; - case 'f' : stepFront(); break; - case 'b' : stepBack(); break; - case 'z' : zoomIn(); break; - case 'x' : zoomOut(); break; - case 'i' : toggleIdle(); break; - case ' ' : newRandom(); break; - default: -// std::cout << "unused key : " << key << std::endl; - break; - } -} - -void mySpecial(int key, int x, int y) -{ - switch (key) - { - case GLUT_KEY_LEFT : stepLeft(); break; - case GLUT_KEY_RIGHT : stepRight(); break; - case GLUT_KEY_UP : stepFront(); break; - case GLUT_KEY_DOWN : stepBack(); break; - case GLUT_KEY_PAGE_UP : zoomIn(); break; - case GLUT_KEY_PAGE_DOWN : zoomOut(); break; - case GLUT_KEY_HOME : toggleIdle(); break; - default: -// std::cout << "unused (special) key : " << key << std::endl; - break; - } -} - -void goodbye( void) -{ - g_scene.remove(sm_ground); - g_scene.remove(sm_sphere); - - std::cout << "goodbye ..." << std::endl; - exit(0); -} - -void menu(int choice) -{ - - static int fullScreen = 0; - static int px, py, sx, sy; - - switch(choice) { - case 1: - if (fullScreen == 1) { - glutPositionWindow(px,py); - glutReshapeWindow(sx,sy); - glutChangeToMenuEntry(1,"Full Screen",1); - fullScreen = 0; - } else { - px=glutGet((GLenum)GLUT_WINDOW_X); - py=glutGet((GLenum)GLUT_WINDOW_Y); - sx=glutGet((GLenum)GLUT_WINDOW_WIDTH); - sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT); - glutFullScreen(); - glutChangeToMenuEntry(1,"Close Full Screen",1); - fullScreen = 1; - } - break; - case 2: - toggleIdle(); - break; - case 3: - goodbye(); - break; - default: - break; - } -} - -void createMenu() -{ - glutCreateMenu(menu); - glutAddMenuEntry("Full Screen", 1); - glutAddMenuEntry("Toggle Idle (Start/Stop)", 2); - glutAddMenuEntry("Quit", 3); - glutAttachMenu(GLUT_RIGHT_BUTTON); -} - -int main(int argc, char **argv) { - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); - glutInitWindowPosition(0, 0); - glutInitWindowSize(500, 500); - glutCreateWindow("Physics demo"); - - myinit(); - glutKeyboardFunc(myKeyboard); - glutSpecialFunc(mySpecial); - glutReshapeFunc(myReshape); - createMenu(); - glutIdleFunc(NULL); - - glutDisplayFunc(display); - glutMainLoop(); - return 0; -} - - - - - - - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp deleted file mode 100644 index cdf0a2d8f64..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp +++ /dev/null @@ -1,695 +0,0 @@ -//#define FAKE_IT -#define USE_COMPLEX -#define QUADS - -#include -#include -#include - -#include "MT_MinMax.h" -#include "MT_Point3.h" -#include "MT_Vector3.h" -#include "MT_Quaternion.h" -#include "MT_Matrix3x3.h" -#include "MT_Transform.h" - -#include "SM_Object.h" -#include "SM_Scene.h" - -#include "solid.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -const MT_Scalar bowl_curv = 0.10; -const MT_Scalar timeStep = 0.04; -const MT_Scalar ground_margin = 0.0; -const MT_Scalar sphere_radius = 0.5; - -const MT_Vector3 gravity(0, -9.8, 0); - -static MT_Scalar DISTANCE = 5; - -static MT_Scalar ele = 0, azi = 0; -static MT_Point3 eye(0, 0, DISTANCE); -static MT_Point3 center(0, 0, 0); - -inline double irnd() { return 2 * MT_random() - 1; } - -static const double SCALE_BOTTOM = 0.5; -static const double SCALE_FACTOR = 2.0; - -SM_ShapeProps g_shapeProps = { - 1.0, // mass - 1.0, // inertia - 0.9, // linear drag - 0.9 // angular drag -}; - -SM_MaterialProps g_materialProps = { - 0.7, // restitution - 0.0, // friction - 0.0, // spring constant - 0.0 // damping -}; - - -void toggleIdle(); - - -void newRandom(); - -void coordSystem() { - glDisable(GL_LIGHTING); - glBegin(GL_LINES); - glColor3f(1, 0, 0); - glVertex3d(0, 0, 0); - glVertex3d(10, 0, 0); - glColor3f(0, 1, 0); - glVertex3d(0, 0, 0); - glVertex3d(0, 10, 0); - glColor3f(0, 0, 1); - glVertex3d(0, 0, 0); - glVertex3d(0, 0, 10); - glEnd(); - glEnable(GL_LIGHTING); -} - - -void display_bbox(const MT_Point3& min, const MT_Point3& max) { - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(0, 1, 1); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glBegin(GL_QUAD_STRIP); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glVertex3d(max[0], min[1], min[2]); - glVertex3d(max[0], min[1], max[2]); - glVertex3d(max[0], max[1], min[2]); - glVertex3d(max[0], max[1], max[2]); - glVertex3d(min[0], max[1], min[2]); - glVertex3d(min[0], max[1], max[2]); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glEnd(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -} - - - - -class GLShape { -public: - virtual void paint(GLdouble *m) const = 0; -}; - - -class GLSphere : public GLShape { - MT_Scalar radius; -public: - GLSphere(MT_Scalar r) : radius(r) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glutSolidSphere(radius, 20, 20); - glPopMatrix(); - } -}; - - -class GLBox : public GLShape { - MT_Vector3 extent; -public: - GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) : - extent(x, y, z) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glPushMatrix(); - glScaled(extent[0], extent[1], extent[2]); - glutSolidCube(1.0); - glPopMatrix(); - glPopMatrix(); - } -}; - - -class GLCone : public GLShape { - MT_Scalar bottomRadius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCone(MT_Scalar r, MT_Scalar h) : - bottomRadius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, bottomRadius, 0, height, 15, 10); - glPopMatrix(); - glEndList(); - } - glPopMatrix(); - } -}; - -class GLCylinder : public GLShape { - MT_Scalar radius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCylinder(MT_Scalar r, MT_Scalar h) : - radius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, radius, radius, height, 15, 10); - glPopMatrix (); - glEndList(); - } - glPopMatrix(); - } -}; - -class Object; - -class Callback : public SM_Callback { -public: - Callback(Object& object) : m_object(object) {} - - virtual void do_me(); - -private: - Object& m_object; -}; - - -class Object { -public: - Object(GLShape *gl_shape, SM_Object& object) : - m_gl_shape(gl_shape), - m_object(object), - m_callback(*this) - { - m_object.registerCallback(m_callback); - } - - ~Object() {} - - void paint() { - m_gl_shape->paint(m); - // display_bbox(m_bbox.lower(), m_bbox.upper()); - } - - MT_Vector3 getAhead() { - return MT_Vector3(-m[8], -m[9], -m[10]); - } - - void clearMomentum() { - m_object.clearMomentum(); - } - - void setMargin(MT_Scalar margin) { - m_object.setMargin(margin); - } - - void setScaling(const MT_Vector3& scaling) { - m_object.setScaling(scaling); - } - - void setPosition(const MT_Point3& pos) { - m_object.setPosition(pos); - } - - void setOrientation(const MT_Quaternion& orn) { - m_object.setOrientation(orn); - } - - void applyCenterForce(const MT_Vector3& force) { - m_object.applyCenterForce(force); - } - - void applyTorque(const MT_Vector3& torque) { - m_object.applyTorque(torque); - } - - MT_Point3 getWorldCoord(const MT_Point3& local) const { - return m_object.getWorldCoord(local); - } - - MT_Vector3 getLinearVelocity() const { - return m_object.getLinearVelocity(); - } - - void setMatrix() { - m_object.getMatrix(m); - } - -private: - GLShape *m_gl_shape; - SM_Object& m_object; - DT_Scalar m[16]; - Callback m_callback; -}; - - -void Callback::do_me() -{ - m_object.setMatrix(); -} - - -const MT_Scalar SPACE_SIZE = 2; - -static GLSphere gl_sphere(sphere_radius); -static GLBox gl_ground(50.0, 0.0, 50.0); - - - -#ifdef USE_COMPLEX - -const int GRID_SCALE = 10; -const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE; - -DT_ShapeHandle createComplex() { - DT_ShapeHandle shape = DT_NewComplexShape(); - for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) { - for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) { - int i1 = i0 + 1; - int j1 = j0 + 1; -#ifdef QUADS - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0); - DT_End(); -#else - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_End(); - - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0); - DT_End(); -#endif - - } - } - DT_EndComplexShape(); - return shape; -} - - -static DT_ShapeHandle ground_shape = createComplex(); - -#else - -static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50); - -#endif - -static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0); -static Object ground(&gl_ground, sm_ground); - -static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0); -static Object object(&gl_sphere, sm_sphere); - - -static SM_Object sm_ray(DT_Ray(0.0, -1.0, 0.0), 0, 0, 0); - -static SM_Scene g_scene; - - -void myinit(void) { - - GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; - GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; - - /* light_position is NOT default value */ - GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; - GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; - - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - - glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT1, GL_POSITION, light_position1); - - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - // glEnable(GL_CULL_FACE); - // glCullFace(GL_BACK); - - g_scene.setForceField(gravity); - g_scene.add(sm_ground); - sm_ground.setMargin(ground_margin); - - new(&object) Object(&gl_sphere, sm_sphere); - - - object.setMargin(sphere_radius); - - g_scene.add(sm_sphere); - - ground.setPosition(MT_Point3(0, -10, 0)); - ground.setOrientation(MT_Quaternion(0, 0, 0, 1)); - ground.setMatrix(); - center.setValue(0.0, 0.0, 0.0); - - newRandom(); -} - - -//MT_Point3 cp1, cp2; -//bool intersection; - -bool g_hit = false; -MT_Point3 g_spot; -MT_Vector3 g_normal; - - -void display(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ground.paint(); - object.paint(); - - if (g_hit) { - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(g_spot[0], g_spot[1], g_spot[2]); - glEnd(); - glPointSize(1); - } - - - -#ifdef COLLISION - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(1, 1, 0); - if (intersection) { - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glEnd(); - glPointSize(1); - } - else { - glBegin(GL_LINES); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glVertex3d(cp2[0], cp2[1], cp2[2]); - glEnd(); - } - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -#endif - - glFlush(); - glutSwapBuffers(); -} - - - - - -void newRandom() { - object.setPosition(MT_Point3(0, 0, 0)); - object.clearMomentum(); - object.setMatrix(); - - display(); -} - -void moveAndDisplay() { - g_scene.proceed(timeStep, 0.01); - - MT_Vector3 normal(0, 1, 0); - - MT_Point3 from = object.getWorldCoord(MT_Point3(0, 0, 0)); - MT_Point3 to = from - normal * 10.0; - - g_hit = DT_ObjectRayTest(sm_ground.getObjectHandle(), - from.getValue(), - to.getValue(), g_spot.getValue(), - g_normal.getValue()); - - // Scrap -#define DO_FH -#ifdef DO_FH - MT_Scalar dist = MT_distance(from, g_spot); - if (dist < 5.0) { - MT_Vector3 lin_vel = object.getLinearVelocity(); - MT_Scalar lin_vel_normal = lin_vel.dot(normal); - - MT_Scalar spring_extent = dist + lin_vel_normal * (timeStep * 0.5); - - MT_Scalar f_spring = (5.0 - spring_extent) * 3.0; - object.applyCenterForce(normal * f_spring); - object.applyCenterForce(-lin_vel_normal * normal); - } - -#endif - - - display(); -} - - -void turn_left() { - object.applyTorque(MT_Vector3(0.0, 10.0, 0.0)); -} - -void turn_right() { - object.applyTorque(MT_Vector3(0.0, -10.0, 0.0)); -} - -void forward() { - object.applyCenterForce(20.0 * object.getAhead()); -} - -void backward() { - object.applyCenterForce(-20.0 * object.getAhead()); -} - -void jump() { - object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0)); -} - - -void toggleIdle() { - static bool idle = true; - if (idle) { - glutIdleFunc(moveAndDisplay); - idle = false; - } - else { - glutIdleFunc(NULL); - idle = true; - } -} - - -void setCamera() { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); - MT_Scalar rele = MT_radians(ele); - MT_Scalar razi = MT_radians(azi); - eye.setValue(DISTANCE * sin(razi) * cos(rele), - DISTANCE * sin(rele), - DISTANCE * cos(razi) * cos(rele)); - gluLookAt(eye[0], eye[1], eye[2], - center[0], center[1], center[2], - 0, 1, 0); - glMatrixMode(GL_MODELVIEW); - display(); -} - -const MT_Scalar STEPSIZE = 5; - -void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void zoomIn() { DISTANCE -= 1; setCamera(); } -void zoomOut() { DISTANCE += 1; setCamera(); } - - -void myReshape(int w, int h) { - glViewport(0, 0, w, h); - setCamera(); -} - -void myKeyboard(unsigned char key, int x, int y) -{ - switch (key) - { - case 'w': forward(); break; - case 's': backward(); break; - case 'a': turn_left(); break; - case 'd': turn_right(); break; - case 'e': jump(); break; - case 'l' : stepLeft(); break; - case 'r' : stepRight(); break; - case 'f' : stepFront(); break; - case 'b' : stepBack(); break; - case 'z' : zoomIn(); break; - case 'x' : zoomOut(); break; - case 'i' : toggleIdle(); break; - case ' ' : newRandom(); break; - default: -// std::cout << "unused key : " << key << std::endl; - break; - } -} - -void mySpecial(int key, int x, int y) -{ - switch (key) - { - case GLUT_KEY_LEFT : stepLeft(); break; - case GLUT_KEY_RIGHT : stepRight(); break; - case GLUT_KEY_UP : stepFront(); break; - case GLUT_KEY_DOWN : stepBack(); break; - case GLUT_KEY_PAGE_UP : zoomIn(); break; - case GLUT_KEY_PAGE_DOWN : zoomOut(); break; - case GLUT_KEY_HOME : toggleIdle(); break; - default: -// std::cout << "unused (special) key : " << key << std::endl; - break; - } -} - -void goodbye( void) -{ - g_scene.remove(sm_ground); - g_scene.remove(sm_sphere); - - std::cout << "goodbye ..." << std::endl; - exit(0); -} - -void menu(int choice) -{ - - static int fullScreen = 0; - static int px, py, sx, sy; - - switch(choice) { - case 1: - if (fullScreen == 1) { - glutPositionWindow(px,py); - glutReshapeWindow(sx,sy); - glutChangeToMenuEntry(1,"Full Screen",1); - fullScreen = 0; - } else { - px=glutGet((GLenum)GLUT_WINDOW_X); - py=glutGet((GLenum)GLUT_WINDOW_Y); - sx=glutGet((GLenum)GLUT_WINDOW_WIDTH); - sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT); - glutFullScreen(); - glutChangeToMenuEntry(1,"Close Full Screen",1); - fullScreen = 1; - } - break; - case 2: - toggleIdle(); - break; - case 3: - goodbye(); - break; - default: - break; - } -} - -void createMenu() -{ - glutCreateMenu(menu); - glutAddMenuEntry("Full Screen", 1); - glutAddMenuEntry("Toggle Idle (Start/Stop)", 2); - glutAddMenuEntry("Quit", 3); - glutAttachMenu(GLUT_RIGHT_BUTTON); -} - -int main(int argc, char **argv) { - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); - glutInitWindowPosition(0, 0); - glutInitWindowSize(500, 500); - glutCreateWindow("Physics demo"); - - myinit(); - glutKeyboardFunc(myKeyboard); - glutSpecialFunc(mySpecial); - glutReshapeFunc(myReshape); - createMenu(); - glutIdleFunc(NULL); - - glutDisplayFunc(display); - glutMainLoop(); - return 0; -} - - - - - - - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile deleted file mode 100644 index b2744c5496a..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# $Id$ -# Copyright (C) 2001 NaN Technologies B.V. - -LIBNAME = fuzzics -DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME) - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I../include -I$(NAN_MOTO)/include -I../../include -CPPFLAGS += -I$(NAN_SOLID)/include - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp deleted file mode 100644 index d866cdb4922..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include "SM_FhObject.h" -#include "MT_MinMax.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -SM_FhObject::SM_FhObject(DT_ShapeHandle rayshape, MT_Vector3 ray, SM_Object *parent_object) : - SM_Object(rayshape, NULL, NULL, NULL), - m_ray(ray), - m_ray_direction(ray.normalized()), - m_parent_object(parent_object) -{ -} - -SM_FhObject::~SM_FhObject() -{ - DT_DeleteShape(getShapeHandle()); -} - -DT_Bool SM_FhObject::ray_hit(void *client_data, - void *client_object1, - void *client_object2, - const DT_CollData *coll_data) -{ - - SM_FhObject *fh_object = dynamic_cast((SM_Object *)client_object2); - if (!fh_object) - { - std::swap(client_object1, client_object2); - fh_object = dynamic_cast((SM_Object *)client_object2); - } - - SM_Object *hit_object = (SM_Object *)client_object1; - const SM_MaterialProps *matProps = hit_object->getMaterialProps(); - - if ((matProps == 0) || (matProps->m_fh_distance < MT_EPSILON)) { - return DT_CONTINUE; - } - - SM_Object *cl_object = fh_object->getParentObject(); - - assert(fh_object); - - if (hit_object == cl_object) { - // Shot myself in the foot... - return DT_CONTINUE; - } - - const SM_ShapeProps *shapeProps = cl_object->getShapeProps(); - - // Exit if the client object is not dynamic. - if (shapeProps == 0) { - return DT_CONTINUE; - } - - MT_Point3 lspot; - MT_Vector3 normal; - - DT_Vector3 from, to, dnormal; - DT_Scalar dlspot; - fh_object->getPosition().getValue(from); - fh_object->getSpot().getValue(to); - - - if (DT_ObjectRayCast(hit_object->getObjectHandle(), - from, - to, - 1., - &dlspot, - dnormal)) { - - lspot = fh_object->getPosition() + (fh_object->getSpot() - fh_object->getPosition()) * dlspot; - const MT_Vector3& ray_dir = fh_object->getRayDirection(); - MT_Scalar dist = MT_distance(fh_object->getPosition(), lspot) - - cl_object->getMargin() - shapeProps->m_radius; - - normal = MT_Vector3(dnormal).safe_normalized(); - - if (dist < matProps->m_fh_distance) { - - if (shapeProps->m_do_fh) { - lspot -= hit_object->getPosition(); - MT_Vector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocity(lspot); - MT_Scalar rel_vel_ray = ray_dir.dot(rel_vel); - MT_Scalar spring_extent = 1.0 - dist / matProps->m_fh_distance; - - MT_Scalar i_spring = spring_extent * matProps->m_fh_spring; - MT_Scalar i_damp = rel_vel_ray * matProps->m_fh_damping; - - cl_object->addLinearVelocity(-(i_spring + i_damp) * ray_dir); - if (matProps->m_fh_normal) { - cl_object->addLinearVelocity( - (i_spring + i_damp) * - (normal - normal.dot(ray_dir) * ray_dir)); - } - - MT_Vector3 lateral = rel_vel - rel_vel_ray * ray_dir; - const SM_ShapeProps *shapeProps = cl_object->getShapeProps(); - - if (shapeProps->m_do_anisotropic) { - MT_Matrix3x3 lcs(cl_object->getOrientation()); - MT_Vector3 loc_lateral = lateral * lcs; - const MT_Vector3& friction_scaling = - shapeProps->m_friction_scaling; - - loc_lateral.scale(friction_scaling[0], - friction_scaling[1], - friction_scaling[2]); - lateral = lcs * loc_lateral; - } - - - MT_Scalar rel_vel_lateral = lateral.length(); - - if (rel_vel_lateral > MT_EPSILON) { - MT_Scalar friction_factor = matProps->m_friction; - MT_Scalar max_friction = friction_factor * MT_max(MT_Scalar(0.0), i_spring); - - MT_Scalar rel_mom_lateral = rel_vel_lateral / - cl_object->getInvMass(); - - MT_Vector3 friction = - (rel_mom_lateral > max_friction) ? - -lateral * (max_friction / rel_vel_lateral) : - -lateral; - - cl_object->applyCenterImpulse(friction); - } - } - - if (shapeProps->m_do_rot_fh) { - const double *ogl_mat = cl_object->getMatrix(); - MT_Vector3 up(&ogl_mat[8]); - MT_Vector3 t_spring = up.cross(normal) * matProps->m_fh_spring; - MT_Vector3 ang_vel = cl_object->getAngularVelocity(); - - // only rotations that tilt relative to the normal are damped - ang_vel -= ang_vel.dot(normal) * normal; - - MT_Vector3 t_damp = ang_vel * matProps->m_fh_damping; - - cl_object->addAngularVelocity(t_spring - t_damp); - } - } - } - - return DT_CONTINUE; -} - - - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp deleted file mode 100644 index b8f4e0c591c..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include -#include -#include - -#include "SM_MotionState.h" - -void SM_MotionState::integrateMidpoint(MT_Scalar timeStep, const SM_MotionState &prev_state, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel) -{ - m_pos += (prev_state.getLinearVelocity() + velocity) * (timeStep * 0.5); - m_orn += (prev_state.getAngularVelocity() * prev_state.getOrientation() + ang_vel * m_orn) * (timeStep * 0.25); - m_orn.normalize(); -} - -void SM_MotionState::integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel) -{ - m_pos += velocity * timeStep; - m_orn += ang_vel * m_orn * (timeStep * 0.5); - m_orn.normalize(); -} - -void SM_MotionState::integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state) -{ - m_pos += prev_state.getLinearVelocity() * timeStep; - m_orn += prev_state.getAngularVelocity() * m_orn * (timeStep * 0.5); - m_orn.normalize(); -} - -/* -// Newtonian lerp: interpolate based on Newtonian motion -void SM_MotionState::nlerp(const SM_MotionState &prev, const SM_MotionState &next) -{ - MT_Scalar dt = next.getTime() - prev.getTime(); - MT_Scalar t = getTime() - prev.getTime(); - MT_Vector3 dx = next.getPosition() - prev.getPosition(); - MT_Vector3 a = dx/(dt*dt) - prev.getLinearVelocity()/dt; - - m_pos = prev.getPosition() + prev.getLinearVelocity()*t + a*t*t; -} -*/ - -void SM_MotionState::lerp(const SM_MotionState &prev, const SM_MotionState &next) -{ - MT_Scalar dt = next.getTime() - prev.getTime(); - if (MT_fuzzyZero(dt)) - { - *this = next; - return; - } - - MT_Scalar x = (getTime() - prev.getTime())/dt; - - m_pos = x*next.getPosition() + (1-x)*prev.getPosition(); - - m_orn = prev.getOrientation().slerp(next.getOrientation(), 1-x); - - m_lin_vel = x*next.getLinearVelocity() + (1-x)*prev.getLinearVelocity(); - m_ang_vel = x*next.getAngularVelocity() + (1-x)*prev.getAngularVelocity(); -} - -void SM_MotionState::lerp(MT_Scalar t, const SM_MotionState &other) -{ - MT_Scalar x = (t - getTime())/(other.getTime() - getTime()); - m_pos = (1-x)*m_pos + x*other.getPosition(); - - m_orn = other.getOrientation().slerp(m_orn, x); - - m_lin_vel = (1-x)*m_lin_vel + x*other.getLinearVelocity(); - m_ang_vel = (1-x)*m_ang_vel + x*other.getAngularVelocity(); - - m_time = t; -} - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp deleted file mode 100644 index 4b2c7cae008..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp +++ /dev/null @@ -1,1298 +0,0 @@ -/** - * $Id$ - * Copyright (C) 2001 NaN Technologies B.V. - * The basic physics object. - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) -#endif - -#include "MT_assert.h" - -#include "SM_Object.h" -#include "SM_Scene.h" -#include "SM_FhObject.h" -#include "SM_Debug.h" - -#include "MT_MinMax.h" - -MT_Scalar SM_Object::ImpulseThreshold = -1.0; - -struct Contact -{ - SM_Object *obj1; - SM_Object *obj2; - MT_Vector3 normal; - MT_Point3 pos; - - // Sort objects by height - bool operator()(const Contact *a, const Contact *b) - { - return a->pos[2] < b->pos[2]; - } - - Contact(SM_Object *o1, SM_Object *o2, const MT_Vector3 nor, const MT_Point3 p) - : obj1(o1), - obj2(o2), - normal(nor), - pos(p) - { - } - - Contact() - { - } - - void resolve() - { - if (obj1->m_static || obj2->m_static) - { - if (obj1->isDynamic()) - { - if (obj1->m_static && obj2->m_static) - { - if (obj1->m_static < obj2->m_static) - { - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - else - { - obj1->m_error += normal; - obj1->m_static = obj2->m_static + 1; - } - } - else - { - if (obj1->m_static) - { - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - else - { - obj1->m_error += normal; - obj1->m_static = obj2->m_static + 1; - } - } - } - else - { - obj2->m_error -= normal; - obj2->m_static = 1; - } - } - else - { - // This distinction between dynamic and non-dynamic objects should not be - // necessary. Non-dynamic objects are assumed to have infinite mass. - if (obj1->isDynamic()) { - MT_Vector3 error = normal * 0.5f; - obj1->m_error += error; - obj2->m_error -= error; - } - else { - // Same again but now obj1 is non-dynamic - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - } - - } - - - typedef std::set Set; -}; - -static Contact::Set contacts; - -SM_Object::SM_Object( - DT_ShapeHandle shape, - const SM_MaterialProps *materialProps, - const SM_ShapeProps *shapeProps, - SM_Object *dynamicParent) : - - m_dynamicParent(dynamicParent), - m_client_object(0), - m_physicsClientObject(0), - m_shape(shape), - m_materialProps(materialProps), - m_materialPropsBackup(0), - m_shapeProps(shapeProps), - m_shapePropsBackup(0), - m_margin(0.0), - m_scaling(1.0, 1.0, 1.0), - m_reaction_impulse(0.0, 0.0, 0.0), - m_reaction_force(0.0, 0.0, 0.0), - m_lin_mom(0.0, 0.0, 0.0), - m_ang_mom(0.0, 0.0, 0.0), - m_force(0.0, 0.0, 0.0), - m_torque(0.0, 0.0, 0.0), - m_error(0.0, 0.0, 0.0), - m_combined_lin_vel (0.0, 0.0, 0.0), - m_combined_ang_vel (0.0, 0.0, 0.0), - m_fh_object(0), - m_inv_mass(0.0), - m_inv_inertia(0., 0., 0.), - m_kinematic(false), - m_prev_kinematic(false), - m_is_rigid_body(false), - m_static(0) -{ - m_object = DT_CreateObject(this, shape); - m_xform.setIdentity(); - m_xform.getValue(m_ogl_matrix); - if (shapeProps) - { - if (shapeProps->m_do_fh || shapeProps->m_do_rot_fh) - { - DT_Vector3 zero = {0., 0., 0.}, ray = {0.0, 0.0, -10.0}; - m_fh_object = new SM_FhObject(DT_NewLineSegment(zero, ray), MT_Vector3(ray), this); - //printf("SM_Object:: WARNING! fh disabled.\n"); - } - m_inv_mass = 1. / shapeProps->m_mass; - m_inv_inertia = MT_Vector3(1./shapeProps->m_inertia[0], 1./shapeProps->m_inertia[1], 1./shapeProps->m_inertia[2]); - } - updateInvInertiaTensor(); - m_suspended = false; -} - - - void -SM_Object:: -integrateForces( - MT_Scalar timeStep -){ - if (!m_suspended) { - m_prev_state = getNextFrame(); - m_prev_state.setLinearVelocity(actualLinVelocity()); - m_prev_state.setAngularVelocity(actualAngVelocity()); - if (isDynamic()) { - // Integrate momentum (forward Euler) - m_lin_mom += m_force * timeStep; - m_ang_mom += m_torque * timeStep; - // Drain momentum because of air/water resistance - m_lin_mom *= pow(m_shapeProps->m_lin_drag, timeStep); - m_ang_mom *= pow(m_shapeProps->m_ang_drag, timeStep); - // Set velocities according momentum - getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass); - getNextFrame().setAngularVelocity(m_inv_inertia_tensor * m_ang_mom); - } - } - -}; - - void -SM_Object:: -integrateMomentum( - MT_Scalar timeStep -){ - // Integrate position and orientation - - // only do it for objects with linear and/or angular velocity - // else clients with hierarchies may get into trouble - if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero()) - { - - // those MIDPOINT and BACKWARD integration methods are - // in this form not ok with some testfiles ! - // For a release build please use forward euler unless completely tested - -//#define MIDPOINT -//#define BACKWARD -#ifdef MIDPOINT -// Midpoint rule - getNextFrame().integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity()); -#elif defined BACKWARD -// Backward Euler - getNextFrame().integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity()); -#else -// Forward Euler - getNextFrame().integrateForward(timeStep, m_prev_state); -#endif - - calcXform(); - notifyClient(); - - } -} - -/** - * dynamicCollision computes the response to a collision. - * - * @param local2 the contact point in local coordinates. - * @param normal the contact normal. - * @param dist the penetration depth of the contact. (unused) - * @param rel_vel the relative velocity of the objects - * @param restitution the amount of momentum conserved in the collision. Range: 0.0 - 1.0 - * @param friction_factor the amount of friction between the two surfaces. - * @param invMass the inverse mass of the collision objects (1.0 / mass) - */ -void SM_Object::dynamicCollision(const MT_Point3 &local2, - const MT_Vector3 &normal, - MT_Scalar dist, - const MT_Vector3 &rel_vel, - MT_Scalar restitution, - MT_Scalar friction_factor, - MT_Scalar invMass -) -{ - /** - * rel_vel_normal is the relative velocity in the contact normal direction. - */ - MT_Scalar rel_vel_normal = normal.dot(rel_vel); - - /** - * if rel_vel_normal > 0, the objects are moving apart! - */ - if (rel_vel_normal < -MT_EPSILON) { - /** - * if rel_vel_normal < ImpulseThreshold, scale the restitution down. - * This should improve the simulation where the object is stacked. - */ - restitution *= MT_min(MT_Scalar(1.0), rel_vel_normal/ImpulseThreshold); - - MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal; - - if (isRigidBody()) - { - MT_Vector3 temp = getInvInertiaTensor() * local2.cross(normal); - impulse /= invMass + normal.dot(temp.cross(local2)); - - /** - * Apply impulse at the collision point. - * Take rotational inertia into account. - */ - applyImpulse(local2 + getNextFrame().getPosition(), impulse * normal); - } else { - /** - * Apply impulse through object center. (no rotation.) - */ - impulse /= invMass; - applyCenterImpulse( impulse * normal ); - } - - MT_Vector3 external = m_combined_lin_vel + m_combined_ang_vel.cross(local2); - MT_Vector3 lateral = rel_vel - external - normal * (rel_vel_normal - external.dot(normal)); -#if 0 - // test - only do friction on the physics part of the - // velocity. - vel1 -= obj1->m_combined_lin_vel; - vel2 -= obj2->m_combined_lin_vel; - - // This should look familiar.... - rel_vel = vel2 - vel1; - rel_vel_normal = normal.dot(rel_vel); -#endif - /** - * The friction part starts here!!!!!!!! - * - * Compute the lateral component of the relative velocity - * lateral actually points in the opposite direction, i.e., - * into the direction of the friction force. - */ - if (m_shapeProps->m_do_anisotropic) { - - /** - * For anisotropic friction we scale the lateral component, - * rather than compute a direction-dependent fricition - * factor. For this the lateral component is transformed to - * local coordinates. - */ - - MT_Matrix3x3 lcs(getNextFrame().getOrientation()); - - /** - * We cannot use m_xform.getBasis() for the matrix, since - * it might contain a non-uniform scaling. - * OPT: it's a bit daft to compute the matrix since the - * quaternion itself can be used to do the transformation. - */ - MT_Vector3 loc_lateral = lateral * lcs; - - /** - * lcs is orthogonal so lcs.inversed() == lcs.transposed(), - * and lcs.transposed() * lateral == lateral * lcs. - */ - const MT_Vector3& friction_scaling = - m_shapeProps->m_friction_scaling; - - // Scale the local lateral... - loc_lateral.scale(friction_scaling[0], - friction_scaling[1], - friction_scaling[2]); - // ... and transform it back to global coordinates - lateral = lcs * loc_lateral; - } - - /** - * A tiny Coulomb friction primer: - * The Coulomb friction law states that the magnitude of the - * maximum possible friction force depends linearly on the - * magnitude of the normal force. - * - * \f[ - F_max_friction = friction_factor * F_normal - \f] - * - * (NB: independent of the contact area!!) - * - * The friction factor depends on the material. - * We use impulses rather than forces but let us not be - * bothered by this. - */ - MT_Scalar rel_vel_lateral = lateral.length(); - - if (rel_vel_lateral > MT_EPSILON) { - lateral /= rel_vel_lateral; - - // Compute the maximum friction impulse - MT_Scalar max_friction = - friction_factor * MT_max(MT_Scalar(0.0), impulse); - - // I guess the GEN_max is not necessary, so let's check it - - MT_assert(impulse >= 0.0); - - /** - * Here's the trick. We compute the impulse to make the - * lateral velocity zero. (Make the objects stick together - * at the contact point. If this impulse is larger than - * the maximum possible friction impulse, then shrink its - * magnitude to the maximum friction. - */ - - if (isRigidBody()) { - - /** - * For rigid bodies we take the inertia into account, - * since the friction impulse is going to change the - * angular momentum as well. - */ - MT_Vector3 temp = getInvInertiaTensor() * local2.cross(lateral); - MT_Scalar impulse_lateral = rel_vel_lateral / - (invMass + lateral.dot(temp.cross(local2))); - - MT_Scalar friction = MT_min(impulse_lateral, max_friction); - applyImpulse(local2 + getNextFrame().getPosition(), -lateral * friction); - } - else { - MT_Scalar impulse_lateral = rel_vel_lateral / invMass; - - MT_Scalar friction = MT_min(impulse_lateral, max_friction); - applyCenterImpulse( -friction * lateral); - } - - - } - - //calcXform(); - //notifyClient(); - - } -} - -static void AddCallback(SM_Scene *scene, SM_Object *obj1, SM_Object *obj2) -{ - // If we have callbacks on either of the client objects, do a collision test - // and add a callback if they intersect. - DT_Vector3 v; - if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || - (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()) && - DT_GetIntersect(obj1->getObjectHandle(), obj2->getObjectHandle(), v)) - scene->notifyCollision(obj1, obj2); -} - -DT_Bool SM_Object::boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data -){ - SM_Scene *scene = (SM_Scene *)client_data; - SM_Object *obj1 = (SM_Object *)object1; - SM_Object *obj2 = (SM_Object *)object2; - - // at this point it is unknown whether we are really intersecting (broad phase) - - DT_Vector3 p1, p2; - if (!obj2->isDynamic()) { - std::swap(obj1, obj2); - } - - // If one of the objects is a ghost then ignore it for the dynamics - if (obj1->isGhost() || obj2->isGhost()) { - AddCallback(scene, obj1, obj2); - return DT_CONTINUE; - } - - // Objects do not collide with parent objects - if (obj1->getDynamicParent() == obj2 || obj2->getDynamicParent() == obj1) { - AddCallback(scene, obj1, obj2); - return DT_CONTINUE; - } - - if (!obj2->isDynamic()) { - AddCallback(scene, obj1, obj2); - return DT_CONTINUE; - } - - // Get collision data from SOLID - if (!DT_GetPenDepth(obj1->getObjectHandle(), obj2->getObjectHandle(), p1, p2)) - return DT_CONTINUE; - - MT_Point3 local1(p1), local2(p2); - MT_Vector3 normal(local2 - local1); - MT_Scalar dist = normal.length(); - - if (dist < MT_EPSILON) - return DT_CONTINUE; - - // Now we are definitely intersecting. - - // Set callbacks for game engine. - if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || - (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback())) - scene->notifyCollision(obj1, obj2); - - local1 -= obj1->getNextFrame().getPosition(); - local2 -= obj2->getNextFrame().getPosition(); - - // Calculate collision parameters - MT_Vector3 rel_vel = obj1->getVelocity(local1) - obj2->getVelocity(local2); - - MT_Scalar restitution = - MT_min(obj1->getMaterialProps()->m_restitution, - obj2->getMaterialProps()->m_restitution); - - MT_Scalar friction_factor = - MT_min(obj1->getMaterialProps()->m_friction, - obj2->getMaterialProps()->m_friction); - - MT_Scalar invMass = obj1->getInvMass() + obj2->getInvMass(); - - normal /= dist; - - // Calculate reactions - if (obj1->isDynamic()) - obj1->dynamicCollision(local1, normal, dist, rel_vel, restitution, friction_factor, invMass); - - if (obj2->isDynamic()) - { - obj2->dynamicCollision(local2, -normal, dist, -rel_vel, restitution, friction_factor, invMass); - if (!obj1->isDynamic() || obj1->m_static) - obj2->m_static = obj1->m_static + 1; - } - - return DT_CONTINUE; -} - -DT_Bool SM_Object::fix( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data -){ - SM_Object *obj1 = (SM_Object *)object1; - SM_Object *obj2 = (SM_Object *)object2; - - // If one of the objects is a ghost then ignore it for the dynamics - if (obj1->isGhost() || obj2->isGhost()) { - return DT_CONTINUE; - } - - if (obj1->getDynamicParent() == obj2 || obj2->getDynamicParent() == obj1) { - return DT_CONTINUE; - } - - if (!obj2->isDynamic()) { - std::swap(obj1, obj2); - } - - if (!obj2->isDynamic()) { - return DT_CONTINUE; - } - - // obj1 points to a dynamic object - DT_Vector3 p1, p2; - if (!DT_GetPenDepth(obj1->getObjectHandle(), obj2->getObjectHandle(), p1, p2)) - return DT_CONTINUE; - MT_Point3 local1(p1), local2(p2); - // Get collision data from SOLID - MT_Vector3 normal(local2 - local1); - - MT_Scalar dist = normal.dot(normal); - if (dist < MT_EPSILON || dist > obj2->m_shapeProps->m_radius*obj2->m_shapeProps->m_radius) - return DT_CONTINUE; - - - if ((obj1->m_static || !obj1->isDynamic()) && obj1->m_static < obj2->m_static) - { - obj2->m_static = obj1->m_static + 1; - } else if (obj2->m_static && obj2->m_static < obj1->m_static) - { - obj1->m_static = obj2->m_static + 1; - } - - contacts.insert(new Contact(obj1, obj2, normal, MT_Point3(local1 + 0.5*(local2 - local1)))); - - - return DT_CONTINUE; -} - -void SM_Object::relax(void) -{ - for (Contact::Set::iterator csit = contacts.begin() ; csit != contacts.end(); ++csit) - { - (*csit)->resolve(); - delete (*csit); - } - - contacts.clear(); - if (m_error.fuzzyZero()) - return; - //std::cout << "SM_Object::relax: { " << m_error << " }" << std::endl; - - getNextFrame().setPosition(getNextFrame().getPosition() + m_error); - m_error.setValue(0., 0., 0.); - //calcXform(); - //notifyClient(); -} - -SM_Object::SM_Object() : - m_dynamicParent(0), - m_client_object(0), - m_physicsClientObject(0), - m_shape(0), - m_materialProps(0), - m_materialPropsBackup(0), - m_shapeProps(0), - m_shapePropsBackup(0), - m_object(0), - m_margin(0.0), - m_scaling(1.0, 1.0, 1.0), - m_reaction_impulse(0.0, 0.0, 0.0), - m_reaction_force(0.0, 0.0, 0.0), - m_lin_mom(0.0, 0.0, 0.0), - m_ang_mom(0.0, 0.0, 0.0), - m_force(0.0, 0.0, 0.0), - m_torque(0.0, 0.0, 0.0), - m_error(0.0, 0.0, 0.0), - m_combined_lin_vel (0.0, 0.0, 0.0), - m_combined_ang_vel (0.0, 0.0, 0.0), - m_fh_object(0), - m_kinematic(false), - m_prev_kinematic(false), - m_is_rigid_body(false) -{ - // warning no initialization of variables done by moto. -} - -SM_Object:: -~SM_Object() { - if (m_fh_object) - delete m_fh_object; - - DT_DestroyObject(m_object); - m_object = NULL; -} - - bool -SM_Object:: -isDynamic( -) const { - return m_shapeProps != 0; -} - -/* nzc experimental. There seem to be two places where kinematics - * are evaluated: proceedKinematic (called from SM_Scene) and - * proceed() in this object. I'll just try and bunge these out for - * now. */ - void -SM_Object:: -suspend( -){ - if (!m_suspended) { - m_suspended = true; - suspendDynamics(); - } -} - - void -SM_Object:: -resume( -) { - if (m_suspended) { - m_suspended = false; - restoreDynamics(); - } -} - - void -SM_Object:: -suspendDynamics( -) { - if (m_shapeProps) { - m_shapePropsBackup = m_shapeProps; - m_shapeProps = 0; - } -} - - void -SM_Object:: -restoreDynamics( -) { - if (m_shapePropsBackup) { - m_shapeProps = m_shapePropsBackup; - m_shapePropsBackup = 0; - } -} - - bool -SM_Object:: -isGhost( -) const { - return m_materialProps == 0; -} - - void -SM_Object:: -suspendMaterial( -) { - if (m_materialProps) { - m_materialPropsBackup = m_materialProps; - m_materialProps = 0; - } -} - - void -SM_Object:: -restoreMaterial( -) { - if (m_materialPropsBackup) { - m_materialProps = m_materialPropsBackup; - m_materialPropsBackup = 0; - } -} - - SM_FhObject * -SM_Object:: -getFhObject( -) const { - return m_fh_object; -} - - void -SM_Object:: -registerCallback( - SM_Callback& callback -) { - m_callbackList.push_back(&callback); -} - -// Set the local coordinate system according to the current state - void -SM_Object:: -calcXform() { -#ifdef SM_DEBUG_XFORM - printf("SM_Object::calcXform m_pos = { %-0.5f, %-0.5f, %-0.5f }\n", - m_pos[0], m_pos[1], m_pos[2]); - printf(" m_orn = { %-0.5f, %-0.5f, %-0.5f, %-0.5f }\n", - m_orn[0], m_orn[1], m_orn[2], m_orn[3]); - printf(" m_scaling = { %-0.5f, %-0.5f, %-0.5f }\n", - m_scaling[0], m_scaling[1], m_scaling[2]); -#endif - m_xform.setOrigin(getNextFrame().getPosition()); - m_xform.setBasis(MT_Matrix3x3(getNextFrame().getOrientation(), m_scaling)); - m_xform.getValue(m_ogl_matrix); - - /* Blender has been known to crash here. - This usually means SM_Object *this has been deleted more than once. */ - DT_SetMatrixd(m_object, m_ogl_matrix); - if (m_fh_object) { - m_fh_object->setPosition(getNextFrame().getPosition()); - m_fh_object->calcXform(); - } - updateInvInertiaTensor(); -#ifdef SM_DEBUG_XFORM - printf("\n | %-0.5f %-0.5f %-0.5f %-0.5f |\n", - m_ogl_matrix[0], m_ogl_matrix[4], m_ogl_matrix[ 8], m_ogl_matrix[12]); - printf( " | %-0.5f %-0.5f %-0.5f %-0.5f |\n", - m_ogl_matrix[1], m_ogl_matrix[5], m_ogl_matrix[ 9], m_ogl_matrix[13]); - printf( "m_ogl_matrix = | %-0.5f %-0.5f %-0.5f %-0.5f |\n", - m_ogl_matrix[2], m_ogl_matrix[6], m_ogl_matrix[10], m_ogl_matrix[14]); - printf( " | %-0.5f %-0.5f %-0.5f %-0.5f |\n\n", - m_ogl_matrix[3], m_ogl_matrix[7], m_ogl_matrix[11], m_ogl_matrix[15]); -#endif -} - - void -SM_Object::updateInvInertiaTensor() -{ - m_inv_inertia_tensor = m_xform.getBasis().scaled(m_inv_inertia[0], m_inv_inertia[1], m_inv_inertia[2]) * m_xform.getBasis().transposed(); -} - -// Call callbacks to notify the client of a change of placement - void -SM_Object:: -notifyClient() { - T_CallbackList::iterator i; - for (i = m_callbackList.begin(); i != m_callbackList.end(); ++i) { - (*i)->do_me(); - } -} - - -// Save the current state information for use in the velocity computation in the next frame. - void -SM_Object:: -proceedKinematic( - MT_Scalar timeStep -) { - /* nzc: need to bunge this for the logic bubbling as well? */ - if (!m_suspended) { - m_prev_kinematic = m_kinematic; - if (m_kinematic) { - m_prev_xform = m_xform; - m_timeStep = timeStep; - calcXform(); - m_kinematic = false; - } - } -} - - void -SM_Object:: -saveReactionForce( - MT_Scalar timeStep -) { - if (isDynamic()) { - m_reaction_force = m_reaction_impulse / timeStep; - m_reaction_impulse.setValue(0.0, 0.0, 0.0); - } -} - - void -SM_Object:: -clearForce( -) { - m_force.setValue(0.0, 0.0, 0.0); - m_torque.setValue(0.0, 0.0, 0.0); -} - - void -SM_Object:: -clearMomentum( -) { - m_lin_mom.setValue(0.0, 0.0, 0.0); - m_ang_mom.setValue(0.0, 0.0, 0.0); -} - - void -SM_Object:: -setMargin( - MT_Scalar margin -) { - m_margin = margin; - DT_SetMargin(m_object, margin); -} - - MT_Scalar -SM_Object:: -getMargin( -) const { - return m_margin; -} - -const - SM_MaterialProps * -SM_Object:: -getMaterialProps( -) const { - return m_materialProps; -} - -const - SM_ShapeProps * -SM_Object:: -getShapeProps( -) const { - return m_shapeProps; -} - - void -SM_Object:: -setPosition( - const MT_Point3& pos -){ - m_kinematic = true; - getNextFrame().setPosition(pos); - endFrame(); -} - - void -SM_Object:: -setOrientation( - const MT_Quaternion& orn -){ - MT_assert(!orn.fuzzyZero()); - m_kinematic = true; - getNextFrame().setOrientation(orn); - endFrame(); -} - - void -SM_Object:: -setScaling( - const MT_Vector3& scaling -){ - m_kinematic = true; - m_scaling = scaling; -} - -/** - * Functions to handle linear velocity - */ - - void -SM_Object:: -setExternalLinearVelocity( - const MT_Vector3& lin_vel -) { - m_combined_lin_vel=lin_vel; -} - - void -SM_Object:: -addExternalLinearVelocity( - const MT_Vector3& lin_vel -) { - m_combined_lin_vel+=lin_vel; -} - - void -SM_Object:: -addLinearVelocity( - const MT_Vector3& lin_vel -){ - setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel); -} - - void -SM_Object:: -setLinearVelocity( - const MT_Vector3& lin_vel -){ - getNextFrame().setLinearVelocity(lin_vel); - if (m_shapeProps) { - m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass; - } -} - -/** - * Functions to handle angular velocity - */ - - void -SM_Object:: -setExternalAngularVelocity( - const MT_Vector3& ang_vel -) { - m_combined_ang_vel = ang_vel; -} - - void -SM_Object:: -addExternalAngularVelocity( - const MT_Vector3& ang_vel -) { - m_combined_ang_vel += ang_vel; -} - - void -SM_Object:: -setAngularVelocity( - const MT_Vector3& ang_vel -) { - getNextFrame().setAngularVelocity(ang_vel); - if (m_shapeProps) { - m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia; - } -} - - void -SM_Object:: -addAngularVelocity( - const MT_Vector3& ang_vel -) { - setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel); -} - - - void -SM_Object:: -clearCombinedVelocities( -) { - m_combined_lin_vel = MT_Vector3(0,0,0); - m_combined_ang_vel = MT_Vector3(0,0,0); -} - - void -SM_Object:: -resolveCombinedVelocities( - const MT_Vector3 & lin_vel, - const MT_Vector3 & ang_vel -) { - - // Different behaviours for dynamic and non-dynamic - // objects. For non-dynamic we just set the velocity to - // zero. For dynmic the physics velocity has to be - // taken into account. We must make an arbitrary decision - // on how to resolve the 2 velocities. Choices are - // Add the physics velocity to the linear velocity. Objects - // will just keep on moving in the direction they were - // last set in - untill external forces affect them. - // Set the combinbed linear and physics velocity to zero. - // Set the physics velocity in the direction of the set velocity - // zero. - if (isDynamic()) { - -#if 1 - getNextFrame().setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel); - getNextFrame().setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel); -#else - - //compute the component of the physics velocity in the - // direction of the set velocity and set it to zero. - MT_Vector3 lin_vel_norm = lin_vel.normalized(); - - setLinearVelocity(getNextFrame().getLinearVelocity() - (getNextFrame().getLinearVelocity().dot(lin_vel_norm) * lin_vel_norm)); -#endif - m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass; - m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia; - clearCombinedVelocities(); - - } - -} - - - MT_Scalar -SM_Object:: -getInvMass( -) const { - return m_inv_mass; - // OPT: cache the result of this division rather than compute it each call -} - - const MT_Vector3& -SM_Object:: -getInvInertia( -) const { - return m_inv_inertia; - // OPT: cache the result of this division rather than compute it each call -} - - const MT_Matrix3x3& -SM_Object:: -getInvInertiaTensor( -) const { - return m_inv_inertia_tensor; -} - - void -SM_Object:: -applyForceField( - const MT_Vector3& accel -) { - if (m_shapeProps) { - m_force += m_shapeProps->m_mass * accel; // F = m * a - } -} - - void -SM_Object:: -applyCenterForce( - const MT_Vector3& force -) { - m_force += force; -} - - void -SM_Object:: -applyTorque( - const MT_Vector3& torque -) { - m_torque += torque; -} - - void -SM_Object:: -applyImpulse( - const MT_Point3& attach, const MT_Vector3& impulse -) { - applyCenterImpulse(impulse); // Change in linear momentum - applyAngularImpulse((attach - getNextFrame().getPosition()).cross(impulse)); // Change in angular momentump -} - - void -SM_Object:: -applyCenterImpulse( - const MT_Vector3& impulse -) { - if (m_shapeProps) { - m_lin_mom += impulse; - m_reaction_impulse += impulse; - getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass); - - // The linear velocity is immedialtely updated since otherwise - // simultaneous collisions will get a double impulse. - } -} - - void -SM_Object:: -applyAngularImpulse( - const MT_Vector3& impulse -) { - if (m_shapeProps) { - m_ang_mom += impulse; - getNextFrame().setAngularVelocity( m_inv_inertia_tensor * m_ang_mom); - } -} - - MT_Point3 -SM_Object:: -getWorldCoord( - const MT_Point3& local -) const { - return m_xform(local); -} - - MT_Vector3 -SM_Object:: -getVelocity( - const MT_Point3& local -) const { - if (m_prev_kinematic && !isDynamic()) - { - // For displaced objects the velocity is faked using the previous state. - // Dynamic objects get their own velocity, not the faked velocity. - // (Dynamic objects shouldn't be displaced in the first place!!) - return (m_xform(local) - m_prev_xform(local)) / m_timeStep; - } - - // NB: m_xform.getBasis() * local == m_xform(local) - m_xform.getOrigin() - return actualLinVelocity() + actualAngVelocity().cross(local); -} - - -const - MT_Vector3& -SM_Object:: -getReactionForce( -) const { - return m_reaction_force; -} - - void -SM_Object:: -getMatrix( - double *m -) const { - std::copy(&m_ogl_matrix[0], &m_ogl_matrix[16], &m[0]); -} - -const - double * -SM_Object:: -getMatrix( -) const { - return m_ogl_matrix; -} - -// Still need this??? -const - MT_Transform& -SM_Object:: -getScaledTransform( -) const { - return m_xform; -} - - DT_ObjectHandle -SM_Object:: -getObjectHandle( -) const { - return m_object; -} - - DT_ShapeHandle -SM_Object:: -getShapeHandle( -) const { - return m_shape; -} - - SM_Object * -SM_Object:: -getDynamicParent( -) { - return m_dynamicParent; -} - - void -SM_Object:: -setRigidBody( - bool is_rigid_body -) { - m_is_rigid_body = is_rigid_body; -} - - bool -SM_Object:: -isRigidBody( -) const { - return m_is_rigid_body; -} - -const - MT_Vector3 -SM_Object:: -actualLinVelocity( -) const { - return m_combined_lin_vel + getNextFrame().getLinearVelocity(); -}; - -const - MT_Vector3 -SM_Object:: -actualAngVelocity( -) const { - return m_combined_ang_vel + getNextFrame().getAngularVelocity(); -} - - -SM_MotionState& -SM_Object:: -getCurrentFrame() -{ - return m_frames[1]; -} - -SM_MotionState& -SM_Object:: -getPreviousFrame() -{ - return m_frames[0]; -} - -SM_MotionState & -SM_Object:: -getNextFrame() -{ - return m_frames[2]; -} - -const SM_MotionState & -SM_Object:: -getCurrentFrame() const -{ - return m_frames[1]; -} - -const SM_MotionState & -SM_Object:: -getPreviousFrame() const -{ - return m_frames[0]; -} - -const SM_MotionState & -SM_Object:: -getNextFrame() const -{ - return m_frames[2]; -} - - -const MT_Point3& -SM_Object:: -getPosition() const -{ - return m_frames[1].getPosition(); -} - -const MT_Quaternion& -SM_Object:: -getOrientation() const -{ - return m_frames[1].getOrientation(); -} - -const MT_Vector3& -SM_Object:: -getLinearVelocity() const -{ - return m_frames[1].getLinearVelocity(); -} - -const MT_Vector3& -SM_Object:: -getAngularVelocity() const -{ - return m_frames[1].getAngularVelocity(); -} - -void -SM_Object:: -interpolate(MT_Scalar timeStep) -{ - if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero()) - { - getCurrentFrame().setTime(timeStep); - getCurrentFrame().lerp(getPreviousFrame(), getNextFrame()); - notifyClient(); - } -} - -void -SM_Object:: -endFrame() -{ - getPreviousFrame() = getNextFrame(); - getCurrentFrame() = getNextFrame(); - m_static = 0; -} diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp deleted file mode 100644 index f0791bbf89f..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/** - * $Id$ - * Copyright (C) 2001 NaN Technologies B.V. - * The physics scene. - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -#pragma warning(disable : 4786) // shut off 255 char limit debug template warning -#endif - -#include "SM_Scene.h" -#include "SM_Object.h" -#include "SM_FhObject.h" - -#include "SM_Debug.h" - -#include - -SM_Scene::SM_Scene() : - m_scene(DT_CreateScene()), - m_respTable(DT_CreateRespTable()), - m_secondaryRespTable(DT_CreateRespTable()), - m_fixRespTable(DT_CreateRespTable()), - m_forceField(0.0, 0.0, 0.0), - m_frames(0) -{ - for (int i = 0 ; i < NUM_RESPONSE; i++) - { - m_ResponseClass[i] = DT_GenResponseClass(m_respTable); - m_secondaryResponseClass[i] = DT_GenResponseClass(m_secondaryRespTable); - m_fixResponseClass[i] = DT_GenResponseClass(m_fixRespTable); - } - - /* Sensor */ - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); - - /* Static */ - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[STATIC_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - - /* Object */ - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - - /* Fh Object */ - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); - - /* Object (Fix Pass) */ - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::fix, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::fix, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); -} - -void SM_Scene::addTouchCallback(int response_class, DT_ResponseCallback callback, void *user) -{ - DT_AddClassResponse(m_secondaryRespTable, m_secondaryResponseClass[response_class], callback, DT_BROAD_RESPONSE, user); -} - -void SM_Scene::addSensor(SM_Object& object) -{ - T_ObjectList::iterator i = - std::find(m_objectList.begin(), m_objectList.end(), &object); - if (i == m_objectList.end()) - { - object.calcXform(); - m_objectList.push_back(&object); - DT_AddObject(m_scene, object.getObjectHandle()); - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass [SENSOR_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]); - } -} - -void SM_Scene::add(SM_Object& object) { - object.calcXform(); - m_objectList.push_back(&object); - DT_AddObject(m_scene, object.getObjectHandle()); - if (object.isDynamic()) { - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[OBJECT_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[OBJECT_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); - } else { - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[STATIC_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[STATIC_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[STATIC_RESPONSE]); - } - - SM_FhObject *fh_object = object.getFhObject(); - - if (fh_object) { - DT_AddObject(m_scene, fh_object->getObjectHandle()); - DT_SetResponseClass(m_respTable, fh_object->getObjectHandle(), m_ResponseClass[FH_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, fh_object->getObjectHandle(), m_secondaryResponseClass[FH_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, fh_object->getObjectHandle(), m_fixResponseClass[FH_RESPONSE]); - } -} - -void SM_Scene::requestCollisionCallback(SM_Object &object) -{ - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[OBJECT_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[OBJECT_RESPONSE]); -// DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); -} - -void SM_Scene::remove(SM_Object& object) { - //std::cout << "SM_Scene::remove this =" << this << "object = " << &object << std::endl; - T_ObjectList::iterator i = - std::find(m_objectList.begin(), m_objectList.end(), &object); - if (!(i == m_objectList.end())) - { - std::swap(*i, m_objectList.back()); - m_objectList.pop_back(); - DT_RemoveObject(m_scene, object.getObjectHandle()); - - SM_FhObject *fh_object = object.getFhObject(); - - if (fh_object) { - DT_RemoveObject(m_scene, fh_object->getObjectHandle()); - } - } - else { - // tried to remove an object that is not in the scene - //assert(false); - } -} - -void SM_Scene::beginFrame() -{ - T_ObjectList::iterator i; - // Apply a forcefield (such as gravity) - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->applyForceField(m_forceField); - -} - -void SM_Scene::endFrame() -{ - T_ObjectList::iterator i; - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->clearForce(); -} - -bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) -{ - if (!m_frames) - { - if (ticrate > 0.) - m_frames = (unsigned int)(curtime*ticrate) + 1.0; - else - m_frames = (unsigned int)(curtime*65536.0); - } - - // Divide the timeStep into a number of subsamples of size roughly - // equal to subS (might be a little smaller). - MT_Scalar subStep; - int num_samples; - int frames = m_frames; - - // Compute the number of steps to do this update. - if (ticrate > 0.0) - { - // Fixed time step - subStep = 1.0/ticrate; - num_samples = (unsigned int)(curtime*ticrate + 1.0) - m_frames; - - if (num_samples > 4) - { - std::cout << "Dropping physics frames! frames:" << num_samples << " substep: " << subStep << std::endl; - MT_Scalar tr = ticrate; - do - { - frames = frames / 2; - tr = tr / 2.0; - num_samples = (unsigned int)(curtime*tr + 1.0) - frames; - subStep *= 2.0; - } while (num_samples > 8); - std::cout << " frames:" << num_samples << " substep: " << subStep << std::endl; - } - } - else - { - // Variable time step. (old update) - // Integrate at least 100 Hz - MT_Scalar timeStep = curtime - m_frames/65536.0; - subStep = timeStep > 0.01 ? 0.01 : timeStep; - num_samples = int(timeStep * 0.01); - if (num_samples < 1) - num_samples = 1; - } - - // Do a physics timestep. - T_ObjectList::iterator i; - if (num_samples > 0) - { - // Do the integration steps per object. - for (int step = 0; step != num_samples; ++step) - { - MT_Scalar time; - if (ticrate > 0.) - time = MT_Scalar(frames + step + 1) * subStep; - else - time = MT_Scalar(m_frames)/65536.0 + MT_Scalar(step + 1)*subStep; - - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - (*i)->endFrame(); - // Apply a forcefield (such as gravity) - (*i)->integrateForces(subStep); - // And second we update the object positions by performing - // an integration step for each object - (*i)->integrateMomentum(subStep); - } - - // So now first we let the physics scene respond to - // new forces, velocities set externally. - // The collsion and friction impulses are computed here. - // Collision phase - DT_Test(m_scene, m_respTable); - - // Contact phase - DT_Test(m_scene, m_fixRespTable); - - // Finish this timestep by saving al state information for the next - // timestep and clearing the accumulated forces. - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - (*i)->relax(); - (*i)->proceedKinematic(subStep); - (*i)->saveReactionForce(subStep); - (*i)->getNextFrame().setTime(time); - //(*i)->clearForce(); - } - } - } - - if (ticrate > 0) - { - // Interpolate between time steps. - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->interpolate(curtime); - - //only update the m_frames after an actual physics timestep - if (num_samples) - { - m_frames = (unsigned int)(curtime*ticrate) + 1.0; - } - } - else - { - m_frames = (unsigned int)(curtime*65536.0); - } - - return num_samples != 0; -} - -void SM_Scene::notifyCollision(SM_Object *obj1, SM_Object *obj2) -{ - // For each pair of object that collided, call the corresponding callback. - if (m_secondaryRespTable) - DT_CallResponse(m_secondaryRespTable, obj1->getObjectHandle(), obj2->getObjectHandle(), 0); -} - - -SM_Object *SM_Scene::rayTest(void *ignore_client, - const MT_Point3& from, const MT_Point3& to, - MT_Point3& result, MT_Vector3& normal) const { -#ifdef SM_DEBUG_RAYCAST - std::cout << "ray: { " << from << " } - { " << to << " }" << std::endl; -#endif - - DT_Vector3 n, dfrom, dto; - DT_Scalar param; - from.getValue(dfrom); - to.getValue(dto); - SM_Object *hit_object = (SM_Object *) - DT_RayCast(m_scene, ignore_client, dfrom, dto, 1., ¶m, n); - - if (hit_object) { - //result = hit_object->getWorldCoord(from + (to - from)*param); - result = from + (to - from) * param; - normal.setValue(n); -#ifdef SM_DEBUG_RAYCAST - std::cout << "ray: { " << from << " } -> { " << to << " }: { " << result - << " } (" << param << "), normal = { " << normal << " }" << std::endl; -#endif - } - - return hit_object; -} - -void SM_Scene::clearObjectCombinedVelocities() { - - T_ObjectList::iterator i; - - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - - (*i)->clearCombinedVelocities(); - - } - -} - - -void SM_Scene::setSecondaryRespTable(DT_RespTableHandle secondaryRespTable) { - m_secondaryRespTable = secondaryRespTable; -} - - -DT_Bool SM_Scene::boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData * -){ - SM_Scene *scene = (SM_Scene *)client_data; - SM_Object *obj1 = (SM_Object *)object1; - SM_Object *obj2 = (SM_Object *)object2; - - scene->notifyCollision(obj1, obj2); // Record this collision for client callbacks - -#ifdef SM_DEBUG_BOING - printf("SM_Scene::boing\n"); -#endif - - return DT_CONTINUE; -} - -SM_Scene::~SM_Scene() -{ - //std::cout << "SM_Scene::~ SM_Scene(): destroy " << this << std::endl; -// if (m_objectList.begin() != m_objectList.end()) -// std::cout << "SM_Scene::~SM_Scene: There are still objects in the Sumo scene!" << std::endl; - for (T_ObjectList::iterator it = m_objectList.begin() ; it != m_objectList.end() ; it++) - delete *it; - - DT_DestroyRespTable(m_respTable); - DT_DestroyRespTable(m_secondaryRespTable); - DT_DestroyRespTable(m_fixRespTable); - DT_DestroyScene(m_scene); -} diff --git a/source/gameengine/Physics/Sumo/Makefile b/source/gameengine/Physics/Sumo/Makefile deleted file mode 100644 index 69efc4d84eb..00000000000 --- a/source/gameengine/Physics/Sumo/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# - -SOURCEDIR = source/gameengine/Physics/Sumo -LIBNAME = sumo -DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME) -DIRS = Fuzzics - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I$(OPENGL_HEADERS) -CPPFLAGS += -I$(NAN_STRING)/include -CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) - -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SOLID)/include -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include -CPPFLAGS += -I../../Physics/common -CPPFLAGS += -I../../Physics/Dummy - -include nan_subdirs.mk diff --git a/source/gameengine/Physics/Sumo/SConscript b/source/gameengine/Physics/Sumo/SConscript deleted file mode 100644 index a228a986af2..00000000000 --- a/source/gameengine/Physics/Sumo/SConscript +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python -Import ('env') - -sources = ['SumoPHYCallbackBridge.cpp', - 'SumoPhysicsController.cpp', - 'SumoPhysicsEnvironment.cpp', - 'Fuzzics/src/SM_FhObject.cpp', - 'Fuzzics/src/SM_Object.cpp', - 'Fuzzics/src/SM_Scene.cpp', - 'Fuzzics/src/SM_MotionState.cpp' - ] - -incs =['.', - '../common', - 'Fuzzics/include', - '#/intern/moto/include' - ] -incs += [env['BF_SOLID_INC']] - -cflags = [] -if env['OURPLATFORM']=='win32-vc': - cflags.append('/GR') - cflags.append('/O1') - -env.BlenderLib ( 'bf_sumo', sources, incs, [], libtype=['core','player'], priority=[400, 55] , compileflags=cflags) diff --git a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp b/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp deleted file mode 100644 index 1992bbe3421..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "SumoPHYCallbackBridge.h" -#include "PHY_IPhysicsController.h" -#include "SM_Object.h" - - -SumoPHYCallbackBridge::SumoPHYCallbackBridge(void* clientData,PHY_ResponseCallback phyCallback) -:m_orgClientData(clientData), -m_phyCallback(phyCallback) -{ - -} -DT_Bool SumoPHYCallbackBridge::StaticSolidToPHYCallback(void *client_data, - void *client_object1, - void *client_object2, - const DT_CollData *coll_data) -{ - SumoPHYCallbackBridge* bridge = static_cast(client_data); - bridge->SolidToPHY(client_object1,client_object2,coll_data); - return false; -} - -DT_Bool SumoPHYCallbackBridge::SolidToPHY(void *client_object1, - void *client_object2, - const DT_CollData *coll_data) -{ - - SM_Object* smObject1 = static_cast(client_object1); - SM_Object* smObject2 = static_cast(client_object2); - - PHY_IPhysicsController* ctrl1 = static_cast(smObject1->getPhysicsClientObject()); - PHY_IPhysicsController* ctrl2 = static_cast(smObject2->getPhysicsClientObject()); - - if (!ctrl1 || !ctrl2) - { - //todo: check which objects are not linked up properly - return false; - } - if (coll_data) - { - PHY_CollData phyCollData; - - phyCollData.m_point1[0] = coll_data->point1[0]; - phyCollData.m_point1[1] = coll_data->point1[1]; - phyCollData.m_point1[2] = coll_data->point1[2]; - phyCollData.m_point1[3] = 0.f; - - phyCollData.m_point2[0] = coll_data->point2[0]; - phyCollData.m_point2[1] = coll_data->point2[1]; - phyCollData.m_point2[2] = coll_data->point2[2]; - phyCollData.m_point2[3] = 0.f; - - phyCollData.m_normal[0] = coll_data->normal[0]; - phyCollData.m_normal[1] = coll_data->normal[1]; - phyCollData.m_normal[2] = coll_data->normal[2]; - phyCollData.m_normal[3] = 0.f; - - - return m_phyCallback(m_orgClientData, - ctrl1,ctrl2,&phyCollData); - } - - return m_phyCallback(m_orgClientData, - ctrl1,ctrl2,0); - -} - diff --git a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h b/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h deleted file mode 100644 index cc980f3961d..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SUMO_PHY_CALLBACK_BRIDGE_H -#define SUMO_PHY_CALLBACK_BRIDGE_H - -#include -#include "PHY_DynamicTypes.h" - -class SumoPHYCallbackBridge -{ - void* m_orgClientData; - PHY_ResponseCallback m_phyCallback; - -public: - - SumoPHYCallbackBridge(void* clientData,PHY_ResponseCallback phyCallback); - - static DT_Bool StaticSolidToPHYCallback(void *client_data, - void *client_object1, - void *client_object2, - const DT_CollData *coll_data); - - DT_Bool SolidToPHY(void *client_object1, - void *client_object2, - const DT_CollData *coll_data); - - -}; - -#endif //SUMO_PHY_CALLBACK_BRIDGE_H diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp deleted file mode 100644 index 56caa9236bf..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp +++ /dev/null @@ -1,495 +0,0 @@ -/** - * @file $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "SumoPhysicsController.h" -#include "PHY_IMotionState.h" -#include "SM_Object.h" -#include "MT_Quaternion.h" - - -SumoPhysicsController::SumoPhysicsController( - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - class PHY_IMotionState* motionstate, - - bool dyna) - : - m_sumoObj(sumoObj) , - m_sumoScene(sumoScene), - m_bFirstTime(true), - m_bDyna(dyna), - m_MotionState(motionstate) -{ - if (m_sumoObj) - { - - PHY__Vector3 pos1; - getPosition(pos1); - MT_Point3 pos(pos1); - - //temp debugging check - //assert(pos.length() < 100000.f); - - //need this to do the upcast after the solid/sumo collision callback - m_sumoObj->setPhysicsClientObject(this); - //if it is a dyna, register for a callback - m_sumoObj->registerCallback(*this); - } -}; - - - -SumoPhysicsController::~SumoPhysicsController() -{ - if (m_sumoObj) - { - m_sumoScene->remove(*m_sumoObj); - - delete m_sumoObj; - m_sumoObj = NULL; - } -} - -float SumoPhysicsController::getMass() -{ - if (m_sumoObj) - { - const SM_ShapeProps *shapeprops = m_sumoObj->getShapeProps(); - if(shapeprops!=NULL) return shapeprops->m_mass; - } - return 0.f; -} - -bool SumoPhysicsController::SynchronizeMotionStates(float) -{ - if (m_bFirstTime) - { - setSumoTransform(!m_bFirstTime); - m_bFirstTime = false; - } - return false; -} - - - - -void SumoPhysicsController::GetWorldOrientation(MT_Matrix3x3& mat) -{ - float orn[4]; - m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - MT_Quaternion quat(orn); - mat.setRotation(quat); - -} - -void SumoPhysicsController::getPosition(PHY__Vector3& pos) const -{ - assert(m_sumoObj); - - pos[0] = m_sumoObj->getPosition()[0]; - pos[1] = m_sumoObj->getPosition()[0]; - pos[2] = m_sumoObj->getPosition()[0]; - - //m_MotionState->getWorldPosition(pos[0],pos[1],pos[2]); -} - -void SumoPhysicsController::GetWorldPosition(MT_Point3& pos) -{ -// assert(m_sumoObj); - -// pos[0] = m_sumoObj->getPosition()[0]; -// pos[1] = m_sumoObj->getPosition()[0]; -// pos[2] = m_sumoObj->getPosition()[0]; - - float worldpos[3]; - m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); - pos[0]=worldpos[0]; - pos[1]=worldpos[1]; - pos[2]=worldpos[2]; -} - -void SumoPhysicsController::GetWorldScaling(MT_Vector3& scale) -{ - float worldscale[3]; - m_MotionState->getWorldScaling(worldscale[0],worldscale[1],worldscale[2]); - scale[0]=worldscale[0]; - scale[1]=worldscale[1]; - scale[2]=worldscale[2]; -} - - - // kinematic methods -void SumoPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local) -{ - if (m_sumoObj) - { - MT_Matrix3x3 mat; - GetWorldOrientation(mat); - MT_Vector3 dloc(dlocX,dlocY,dlocZ); - - MT_Point3 newpos = m_sumoObj->getPosition(); - - newpos += (local ? mat * dloc : dloc); - m_sumoObj->setPosition(newpos); - } - -} -void SumoPhysicsController::RelativeRotate(const float drot[12],bool local) -{ - if (m_sumoObj ) - { - MT_Matrix3x3 drotmat(drot); - MT_Matrix3x3 currentOrn; - GetWorldOrientation(currentOrn); - - m_sumoObj->setOrientation(m_sumoObj->getOrientation()*(local ? - drotmat : (currentOrn.inverse() * drotmat * currentOrn)).getRotation()); - } - -} -void SumoPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal) -{ - m_sumoObj->setOrientation(MT_Quaternion(quatImag0,quatImag1,quatImag2,quatReal)); -} - -void SumoPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) -{ - const MT_Quaternion& q = m_sumoObj->getOrientation(); - quatImag0 = q[0]; - quatImag1 = q[1]; - quatImag2 = q[2]; - quatReal = q[3]; -} - -void SumoPhysicsController::setPosition(float posX,float posY,float posZ) -{ - m_sumoObj->setPosition(MT_Point3(posX,posY,posZ)); -} - -void SumoPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) -{ - if (!m_bDyna) - m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ)); -} - - // physics methods -void SumoPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local) -{ - if (m_sumoObj) - { - MT_Vector3 torque(torqueX,torqueY,torqueZ); - - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - m_sumoObj->applyTorque(local ? - orn * torque : - torque); - } -} - -void SumoPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local) -{ - if (m_sumoObj) - { - MT_Vector3 force(forceX,forceY,forceZ); - - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - - m_sumoObj->applyCenterForce(local ? - orn * force : - force); - } -} - -void SumoPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local) -{ - if (m_sumoObj) - { - MT_Vector3 ang_vel(ang_velX,ang_velY,ang_velZ); - - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - - m_sumoObj->setExternalAngularVelocity(local ? - orn * ang_vel : - ang_vel); - } -} - -void SumoPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local) -{ - if (m_sumoObj ) - { - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - - MT_Vector3 lin_vel(lin_velX,lin_velY,lin_velZ); - m_sumoObj->setExternalLinearVelocity(local ? - orn * lin_vel : - lin_vel); - } -} - -void SumoPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ - if (m_sumoObj) - m_sumoObj->resolveCombinedVelocities(MT_Vector3(linvelX,linvelY,linvelZ),MT_Vector3(angVelX,angVelY,angVelZ)); -} - - - - -void SumoPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) -{ - if (m_sumoObj) - { - MT_Point3 attach(attachX,attachY,attachZ); - MT_Vector3 impulse(impulseX,impulseY,impulseZ); - m_sumoObj->applyImpulse(attach,impulse); - } - -} - -void SumoPhysicsController::SuspendDynamics() -{ - m_suspendDynamics=true; - - if (m_sumoObj) - { - m_sumoObj->suspendDynamics(); - m_sumoObj->setLinearVelocity(MT_Vector3(0,0,0)); - m_sumoObj->setAngularVelocity(MT_Vector3(0,0,0)); - m_sumoObj->calcXform(); - } -} - -void SumoPhysicsController::RestoreDynamics() -{ - m_suspendDynamics=false; - - if (m_sumoObj) - { - m_sumoObj->restoreDynamics(); - } -} - - -/** - reading out information from physics -*/ -void SumoPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ) -{ - if (m_sumoObj) - { - // get velocity from the physics object (m_sumoObj) - const MT_Vector3& vel = m_sumoObj->getLinearVelocity(); - linvX = vel[0]; - linvY = vel[1]; - linvZ = vel[2]; - } - else - { - linvX = 0.f; - linvY = 0.f; - linvZ = 0.f; - } -} - -/** - GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). -*/ -void SumoPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ) -{ - if (m_sumoObj) - { - MT_Point3 pos(posX,posY,posZ); - // get velocity from the physics object (m_sumoObj) - const MT_Vector3& vel = m_sumoObj->getVelocity(pos); - linvX = vel[0]; - linvY = vel[1]; - linvZ = vel[2]; - } - else - { - linvX = 0.f; - linvY = 0.f; - linvZ = 0.f; - - } -} - -void SumoPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ) -{ - const MT_Vector3& force = m_sumoObj->getReactionForce(); - forceX = force[0]; - forceY = force[1]; - forceZ = force[2]; -} - -void SumoPhysicsController::setRigidBody(bool rigid) -{ - m_sumoObj->setRigidBody(rigid); -} - -void SumoPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) -{ - m_MotionState = motionstate; - - SM_Object* dynaparent=0; - SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl; - - if (sumoparentctrl) - { - dynaparent = sumoparentctrl->GetSumoObject(); - } - - SM_Object* orgsumoobject = m_sumoObj; - - - m_sumoObj = new SM_Object( - orgsumoobject->getShapeHandle(), - orgsumoobject->getMaterialProps(), - orgsumoobject->getShapeProps(), - dynaparent); - - m_sumoObj->setRigidBody(orgsumoobject->isRigidBody()); - - m_sumoObj->setMargin(orgsumoobject->getMargin()); - m_sumoObj->setPosition(orgsumoobject->getPosition()); - m_sumoObj->setOrientation(orgsumoobject->getOrientation()); - //if it is a dyna, register for a callback - m_sumoObj->registerCallback(*this); - - m_sumoScene->add(* (m_sumoObj)); -} - -PHY_IMotionState* SumoPhysicsController::GetMotionState() -{ - return m_MotionState; -} - -void SumoPhysicsController::SetSimulatedTime(float) -{ -} - - -void SumoPhysicsController::WriteMotionStateToDynamics(bool) -{ - -} -// this is the actual callback from sumo, and the position/orientation -//is written to the scenegraph, using the motionstate abstraction - -void SumoPhysicsController::do_me() -{ - MT_assert(m_sumoObj); - const MT_Point3& pos = m_sumoObj->getPosition(); - const MT_Quaternion& orn = m_sumoObj->getOrientation(); - - MT_assert(m_MotionState); - m_MotionState->setWorldPosition(pos[0],pos[1],pos[2]); - m_MotionState->setWorldOrientation(orn[0],orn[1],orn[2],orn[3]); -} - - -void SumoPhysicsController::setSumoTransform(bool nondynaonly) -{ - if (!nondynaonly || !m_bDyna) - { - if (m_sumoObj) - { - MT_Point3 pos; - GetWorldPosition(pos); - - m_sumoObj->setPosition(pos); - if (m_bDyna) - { - m_sumoObj->setScaling(MT_Vector3(1,1,1)); - } else - { - MT_Vector3 scale; - GetWorldScaling(scale); - m_sumoObj->setScaling(scale); - } - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - m_sumoObj->setOrientation(orn.getRotation()); - m_sumoObj->calcXform(); - } - } -} - - - // clientinfo for raycasts for example -void* SumoPhysicsController::getNewClientInfo() -{ - if (m_sumoObj) - return m_sumoObj->getClientObject(); - return 0; - -} -void SumoPhysicsController::setNewClientInfo(void* clientinfo) -{ - if (m_sumoObj) - { - SM_ClientObject* clOb = static_cast (clientinfo); - m_sumoObj->setClientObject(clOb); - } - -} - -void SumoPhysicsController::calcXform() -{ - if (m_sumoObj) - m_sumoObj->calcXform(); -} - -void SumoPhysicsController::SetMargin(float margin) -{ - if (m_sumoObj) - m_sumoObj->setMargin(margin); -} - -float SumoPhysicsController::GetMargin() const -{ - if (m_sumoObj) - m_sumoObj->getMargin(); - return 0.f; -} - -float SumoPhysicsController::GetRadius() const -{ - if (m_sumoObj && m_sumoObj->getShapeProps()) - { - return m_sumoObj->getShapeProps()->m_radius; - } - return 0.f; - -} diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.h b/source/gameengine/Physics/Sumo/SumoPhysicsController.h deleted file mode 100644 index adf29649f18..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __SUMO_PHYSICSCONTROLLER_H -#define __SUMO_PHYSICSCONTROLLER_H - -#include "PHY_IPhysicsController.h" -#include "SM_Scene.h" -#include "SM_Callback.h" - -/** - * Sumo Physics Controller, a special kind of a PhysicsController. - * A Physics Controller is a special kind of Scene Graph Transformation Controller. - * Each time the scene graph get's updated, the controller get's a chance - * in the 'Update' method to reflect changes. - * - * Sumo uses the SOLID library for collision detection. - */ -class SumoPhysicsController : public PHY_IPhysicsController , public SM_Callback - - -{ - - -public: - SumoPhysicsController( - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - class PHY_IMotionState* motionstate, - bool dyna); - - virtual ~SumoPhysicsController(); - - /** - * @name Kinematic Methods. - */ - /*@{*/ - virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local); - /** - * @param drot a 3x4 matrix. This will treated as a 3x3 rotation matrix. - * @warning RelativeRotate expects a 3x4 matrix. The fourth column is padding. - */ - virtual void RelativeRotate(const float drot[12],bool local); - virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal); - virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal); - virtual void setPosition(float posX,float posY,float posZ); - virtual void getPosition(PHY__Vector3& pos) const; - - virtual void setScaling(float scaleX,float scaleY,float scaleZ); - /*@}*/ - - /** - * @name Physics Methods - */ - /*@{*/ - virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local); - virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local); - virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local); - virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local); - virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ); - virtual void SetActive(bool active){}; - virtual void SuspendDynamics(); - virtual void RestoreDynamics(); - /*@}*/ - - - /** - * reading out information from physics - */ - virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ); - /** - * GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). - */ - virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ); - virtual float getMass(); - virtual void getReactionForce(float& forceX,float& forceY,float& forceZ); - virtual void setRigidBody(bool rigid); - - - virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); - - // TODO: remove next line ! - virtual void SetSimulatedTime(float time); - - virtual void WriteDynamicsToMotionState() {}; - virtual void WriteMotionStateToDynamics(bool nondynaonly); - virtual class PHY_IMotionState* GetMotionState(); - - /** - * call from Scene Graph Node to 'update'. - */ - virtual bool SynchronizeMotionStates(float time); - - virtual void calcXform(); - virtual void SetMargin(float margin) ; - virtual float GetMargin() const; - virtual float GetRadius() const ; - virtual void SetRadius(float margin) { SetMargin(margin); } - - - // clientinfo for raycasts for example - virtual void* getNewClientInfo(); - virtual void setNewClientInfo(void* clientinfo); - - float getFriction() { return m_friction;} - float getRestitution() { return m_restitution;} - - /** - * Sumo callback - */ - virtual void do_me(); - - class SM_Object* GetSumoObject () - { - return m_sumoObj; - }; - - void GetWorldOrientation(class MT_Matrix3x3& mat); - void GetWorldPosition(MT_Point3& pos); - void GetWorldScaling(MT_Vector3& scale); - - float GetLinVelocityMin() const { return 0.f; } - void SetLinVelocityMin(float val) { } - float GetLinVelocityMax() const { return 0.f; } - void SetLinVelocityMax(float val) { } - - -// void SetSumoObject(class SM_Object* sumoObj) { -// m_sumoObj = sumoObj; -// } -// void SetSumoScene(class SM_Scene* sumoScene) { -// m_sumoScene = sumoScene; -// } - - void setSumoTransform(bool nondynaonly); - - -private: - class SM_Object* m_sumoObj; - class SM_Scene* m_sumoScene; // needed for replication - bool m_bFirstTime; - bool m_bDyna; - - float m_friction; - float m_restitution; - - - bool m_suspendDynamics; - - bool m_firstTime; - bool m_bFullRigidBody; - bool m_bPhantom; // special flag for objects that are not affected by physics 'resolver' - - // data to calculate fake velocities for kinematic objects (non-dynas) - bool m_bKinematic; - bool m_bPrevKinematic; - - float m_lastTime; - - class PHY_IMotionState* m_MotionState; - - -}; - -#endif //__SUMO_PHYSICSCONTROLLER_H - diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp deleted file mode 100644 index b4daf0a3f80..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include // memset -#include "SumoPhysicsEnvironment.h" -#include "PHY_IMotionState.h" -#include "SumoPhysicsController.h" -#include "SM_Scene.h" -#include "SumoPHYCallbackBridge.h" -#include - -SumoPhysicsEnvironment::SumoPhysicsEnvironment() -{ - m_fixedTimeStep = 1.f/60.f; - m_useFixedTimeStep = true; - m_currentTime = 0.f; - - m_sumoScene = new SM_Scene(); -} - - - -SumoPhysicsEnvironment::~SumoPhysicsEnvironment() -{ - delete m_sumoScene; -} - - - -void SumoPhysicsEnvironment::beginFrame() -{ - m_sumoScene->beginFrame(); -} - -void SumoPhysicsEnvironment::endFrame() -{ - m_sumoScene->endFrame(); -} - -void SumoPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) -{ - m_useFixedTimeStep = useFixedTimeStep; - if (m_useFixedTimeStep) - { - m_fixedTimeStep = fixedTimeStep; - } else - { - m_fixedTimeStep = 0.f; - } - //reset current time ? - m_currentTime = 0.f; -} -float SumoPhysicsEnvironment::getFixedTimeStep() -{ - return m_fixedTimeStep; -} - - -bool SumoPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep,float interval) -{ - - bool result = false; - if (m_useFixedTimeStep) - { - m_currentTime += timeStep; - float ticrate = 1.f/m_fixedTimeStep; - - result = m_sumoScene->proceed(curTime, ticrate); - } else - { - m_currentTime += timeStep; - result = m_sumoScene->proceed(m_currentTime, timeStep); - } - return result; -} - -void SumoPhysicsEnvironment::setGravity(float x,float y,float z) -{ - m_sumoScene->setForceField(MT_Vector3(x,y,z)); -} - -int SumoPhysicsEnvironment::createConstraint( - class PHY_IPhysicsController* ctrl, - class PHY_IPhysicsController* ctrl2, - PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z, - int flag - ) -{ - int constraintid = 0; - return constraintid; -} - -void SumoPhysicsEnvironment::removeConstraint(int constraintid) -{ - if (constraintid) - { - } -} - -PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, - float fromX,float fromY,float fromZ, - float toX,float toY,float toZ) -{ - SumoPhysicsController* ignoreCtr = static_cast (filterCallback.m_ignoreController); - - //collision detection / raytesting - MT_Point3 hit, normal; - PHY_RayCastResult result; - - SM_Object* sm_ignore = 0; - if (ignoreCtr) - sm_ignore = ignoreCtr->GetSumoObject(); - - memset(&result, 0, sizeof(result)); - - SM_Object* smOb = m_sumoScene->rayTest(sm_ignore,MT_Point3(fromX, fromY, fromZ),MT_Point3(toX, toY, toZ), hit, normal); - if (smOb) - { - result.m_controller = (PHY_IPhysicsController *) smOb->getPhysicsClientObject(); - result.m_hitPoint[0] = hit[0]; - result.m_hitPoint[1] = hit[1]; - result.m_hitPoint[2] = hit[2]; - result.m_hitNormal[0] = normal[0]; - result.m_hitNormal[1] = normal[1]; - result.m_hitNormal[2] = normal[2]; - filterCallback.reportHit(&result); - } - return result.m_controller; -} -//gamelogic callbacks -void SumoPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl) -{ - SumoPhysicsController* smctrl = dynamic_cast(ctrl); - SM_Object* smObject = smctrl->GetSumoObject(); - assert(smObject); - if (smObject) - { - m_sumoScene->addSensor(*smObject); - } -} -void SumoPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl) -{ - SumoPhysicsController* smctrl = dynamic_cast(ctrl); - SM_Object* smObject = smctrl->GetSumoObject(); - assert(smObject); - if (smObject) - { - m_sumoScene->remove(*smObject); - } -} - - -void SumoPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) -{ - - int sumoRespClass = 0; - - //map PHY_ convention into SM_ convention - switch (response_class) - { - case PHY_FH_RESPONSE: - sumoRespClass = FH_RESPONSE; - break; - case PHY_SENSOR_RESPONSE: - sumoRespClass = SENSOR_RESPONSE; - break; - case PHY_CAMERA_RESPONSE: - sumoRespClass =CAMERA_RESPONSE; - break; - case PHY_OBJECT_RESPONSE: - sumoRespClass = OBJECT_RESPONSE; - break; - case PHY_STATIC_RESPONSE: - sumoRespClass = PHY_STATIC_RESPONSE; - break; - case PHY_BROADPH_RESPONSE: - return; - default: - assert(0); - return; - } - - SumoPHYCallbackBridge* bridge = new SumoPHYCallbackBridge(user,callback); - - m_sumoScene->addTouchCallback(sumoRespClass,SumoPHYCallbackBridge::StaticSolidToPHYCallback,bridge); -} -bool SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) -{ - SumoPhysicsController* smctrl = dynamic_cast(ctrl); - MT_assert(smctrl); - SM_Object* smObject = smctrl->GetSumoObject(); - MT_assert(smObject); - if (smObject) - { - //assert(smObject->getPhysicsClientObject() == ctrl); - smObject->setPhysicsClientObject(ctrl); - - m_sumoScene->requestCollisionCallback(*smObject); - return true; - } - return false; -} - -bool SumoPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) -{ - // intentionally empty - return false; -} - -PHY_IPhysicsController* SumoPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position) -{ - DT_ShapeHandle shape = DT_NewSphere(0.0); - SM_Object* ob = new SM_Object(shape,0,0,0); - ob->setPosition(MT_Point3(position)); - //testing - MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90)); - ob->setOrientation(rotquatje); - - PHY_IPhysicsController* ctrl = new SumoPhysicsController(m_sumoScene,ob,0,false); - ctrl->SetMargin(radius); - return ctrl; -} -PHY_IPhysicsController* SumoPhysicsEnvironment::CreateConeController(float coneradius,float coneheight) -{ - DT_ShapeHandle shape = DT_NewCone(coneradius,coneheight); - SM_Object* ob = new SM_Object(shape,0,0,0); - ob->setPosition(MT_Point3(0.f,0.f,0.f)); - MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90)); - ob->setOrientation(rotquatje); - - PHY_IPhysicsController* ctrl = new SumoPhysicsController(m_sumoScene,ob,0,false); - - return ctrl; -} - diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h deleted file mode 100644 index 5ae33eb4b0e..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef _SUMOPhysicsEnvironment -#define _SUMOPhysicsEnvironment - -#include "MT_Scalar.h" - -#include "PHY_IPhysicsEnvironment.h" -class SumoPHYCallbackBridge; -#include -/** -* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) -* A derived class may be able to 'construct' entities by loading and/or converting -*/ -class SumoPhysicsEnvironment : public PHY_IPhysicsEnvironment -{ - - class SM_Scene* m_sumoScene; - float m_currentTime; - float m_fixedTimeStep; - bool m_useFixedTimeStep; - - std::vector m_callbacks; - -public: - SumoPhysicsEnvironment(); - virtual ~SumoPhysicsEnvironment(); - virtual void beginFrame(); - virtual void endFrame(); -// Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); - virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); - virtual float getFixedTimeStep(); - - virtual void setGravity(float x,float y,float z); - virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 - - ); - - virtual void removeConstraint(int constraintid); - - //complex constraint for vehicles - virtual PHY_IVehicle* getVehicleConstraint(int constraintId) - { - return 0; - } - - virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes) { return false; } - - - //gamelogic callbacks - virtual void addSensor(PHY_IPhysicsController* ctrl); - virtual void removeSensor(PHY_IPhysicsController* ctrl); - virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user); - virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl); - virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl); - virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position); - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight); - - virtual float getConstraintParam(int constraintId,int param) - { - return 0.f; - } - virtual void setConstraintParam(int constraintId,int param,float value,float value1) - { - } - SM_Scene* GetSumoScene() - { - return m_sumoScene; - } - -protected: - // 60Hz (Default) - static MT_Scalar PhysicsTicRate; - -}; - -#endif //_SUMOPhysicsEnvironment - diff --git a/source/gameengine/Physics/Sumo/convert.txt b/source/gameengine/Physics/Sumo/convert.txt deleted file mode 100644 index 81f8f602cde..00000000000 --- a/source/gameengine/Physics/Sumo/convert.txt +++ /dev/null @@ -1,35 +0,0 @@ -static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj) -{ - DT_ShapeHandle shape = DT_NewComplexShape(); - int numpolys = meshobj->NumPolygons(); - int numvalidpolys = 0; - - for (int p=0; pGetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - DT_Begin(); - for (int v=0; vVertexCount(); v++) { - MT_Point3 pt = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, - poly->GetVertexIndexBase().m_indexarray[v], - poly->GetMaterial()->GetPolyMaterial())->xyz(); - DT_Vertex(pt[0],pt[1],pt[2]); - } - DT_End(); - - numvalidpolys++; - } - } - - DT_EndComplexShape(); - - if (numvalidpolys==0) { - delete shape; - return NULL; - } else { - return shape; - } -} diff --git a/source/gameengine/Physics/Sumo/include/interpolator.h b/source/gameengine/Physics/Sumo/include/interpolator.h deleted file mode 100644 index 055c242edc7..00000000000 --- a/source/gameengine/Physics/Sumo/include/interpolator.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef INTERPOLATOR_H -#define INTERPOLATOR_H - -#include "solid_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DT_DECLARE_HANDLE(IP_IpoHandle); - -typedef struct IP_ControlPoint { - DT_Scalar m_key; - DT_Scalar m_keyValue; -} IP_ControlPoint; - -IP_IpoHandle IP_CreateLinear(const IP_ControlPoint *cpoints, int num_cpoints); - -void IP_DeleteInterpolator(IP_IpoHandle ipo); - -DT_Scalar IP_GetValue(IP_IpoHandle ipo, DT_Scalar key); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/gameengine/Physics/common/Makefile b/source/gameengine/Physics/common/Makefile index e3edd426c36..f2dd0134b71 100644 --- a/source/gameengine/Physics/common/Makefile +++ b/source/gameengine/Physics/common/Makefile @@ -40,7 +40,7 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I../../blender # these two needed because of blenkernel CPPFLAGS += -I../../blender/makesdna diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript index 864e4c3ebee..592b138583f 100644 --- a/source/gameengine/SConscript +++ b/source/gameengine/SConscript @@ -18,13 +18,5 @@ SConscript(['BlenderRoutines/SConscript', 'VideoTexture/SConscript' ]) -if env['WITH_BF_SOLID']: - SConscript(['Physics/Sumo/SConscript']) - if env['WITH_BF_PLAYER']: SConscript(['GamePlayer/SConscript']) - -#if user_options_dict['USE_PHYSICS'] == 'solid': -# SConscript(['Physics/Sumo/SConscript']) -#elif user_options_dict['USE_PHYSICS'] == 'ode': -# SConscript(['Physics/BlOde/SConscript']) diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp index 6b23105a278..6d26e5b6d35 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -81,17 +81,17 @@ static int setColor (PyFilter * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 2))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints"); return -1; } // set color - getFilter(self)->setColor((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)))); + getFilter(self)->setColor((unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)))); // success return 0; } @@ -108,15 +108,15 @@ static int setLimits (PyFilter * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); return -1; } // set limits - getFilter(self)->setLimits((unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - (unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1)))); + getFilter(self)->setLimits((unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1)))); // success return 0; } diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index 5ff1f7f11ce..eb86f520e02 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -147,10 +147,10 @@ static int setMatrix (PyFilter * self, PyObject * value, void * closure) for (int c = 0; valid && c < 5; ++c) { // item must be int - valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c)); + valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c)); // if it is valid, save it in matrix if (valid) - mat[r][c] = short(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c))); + mat[r][c] = short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(row, c))); } } // if parameter is not valid, report error @@ -286,10 +286,10 @@ static int setLevels (PyFilter * self, PyObject * value, void * closure) for (int c = 0; valid && c < 2; ++c) { // item must be int - valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c)); + valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c)); // if it is valid, save it in matrix if (valid) - lev[r][c] = (unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c))); + lev[r][c] = (unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(row, c))); } } // if parameter is not valid, report error diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index 9a2b1e90d5a..002be6c3189 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -72,13 +72,13 @@ static PyObject * getColor (PyFilter * self, void * closure) static int setColor (PyFilter * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PyInt_Check(value)) + if (value == NULL || !PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "filt.colorIdx = int: VideoTexture.FilterNormal, expected the value must be a int"); return -1; } // set color index - getFilter(self)->setColor((unsigned short)(PyInt_AsLong(value))); + getFilter(self)->setColor((unsigned short)(PyLong_AsSsize_t(value))); // success return 0; } diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index c4fb1fefd9c..d8be08e0eb5 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -331,19 +331,19 @@ static int setBackground (PyImage * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 4 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 3))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 2)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 3))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 integer between 0 and 255"); return -1; } // set background color - getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 3)))); + getImageRender(self)->setBackground((unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 3)))); // success return 0; } diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index d2c23e758f6..55b14396280 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -218,16 +218,16 @@ static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * c { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); return -1; } // set position GLint pos [] = { - GLint(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - GLint(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + GLint(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + GLint(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))) }; getImageViewport(self)->setPosition(pos); // success @@ -246,16 +246,16 @@ int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closu { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); return -1; } // set capture size short size [] = { - short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))) }; getImageViewport(self)->setCaptureSize(size); // success diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp index 5d449a158d8..5de7a9e80a9 100644 --- a/source/gameengine/VideoTexture/VideoBase.cpp +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -167,13 +167,13 @@ PyObject * Video_getRepeat (PyImage * self, void * closure) int Video_setRepeat (PyImage * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PyInt_Check(value)) + if (value == NULL || !PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "The value must be an int"); return -1; } // set repeat - getVideo(self)->setRepeat(int(PyInt_AsLong(value))); + getVideo(self)->setRepeat(int(PyLong_AsSsize_t(value))); // success return 0; } diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 1a5481488c0..cf4ea88c1b5 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -1095,13 +1095,13 @@ PyObject * VideoFFmpeg_getPreseek (PyImage *self, void * closure) int VideoFFmpeg_setPreseek (PyImage * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PyInt_Check(value)) + if (value == NULL || !PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "The value must be an integer"); return -1; } // set preseek - getFFmpeg(self)->setPreseek(PyInt_AsLong(value)); + getFFmpeg(self)->setPreseek(PyLong_AsSsize_t(value)); // success return 0; } diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index dad52a426b6..22171f69321 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -67,7 +67,7 @@ static PyObject * getMaterialID (PyObject *self, PyObject *args) // get last error description static PyObject * getLastError (PyObject *self, PyObject *args) { - return PyString_FromString(Exception::m_lastError.c_str()); + return PyUnicode_FromString(Exception::m_lastError.c_str()); } // set log file diff --git a/source/nan_compile.mk b/source/nan_compile.mk index bd6dd6e1baa..bc264fe5c1d 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -71,21 +71,6 @@ DBG_CCFLAGS += -g # OS dependent parts --------------------------------------------------- -ifeq ($(OS),beos) - CC = gcc - CCC = g++ - CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 - NAN_DEPEND = true - OPENGL_HEADERS = . - CPPFLAGS += -D__BeOS - AR = ar - ARFLAGS = ruv - ARFLAGSQUIET = ru -endif - ifeq ($(OS),darwin) CC = gcc CCC = g++ diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index b9e623ed4e4..91f90525c1e 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -91,7 +91,6 @@ endif export BF_PROFILE ?= false export NAN_USE_BULLET ?= true export NAN_BULLET2 ?= $(LCGDIR)/bullet2 - export NAN_SUMO ?= $(SRCHOME)/gameengine/Physics/Sumo export NAN_FUZZICS ?= $(SRCHOME)/gameengine/Physics/Sumo/Fuzzics export NAN_BLENKEY ?= $(LCGDIR)/blenkey export NAN_DECIMATION ?= $(LCGDIR)/decimation @@ -131,45 +130,6 @@ endif endif # Platform Dependent settings go below: - ifeq ($(OS),beos) - - export ID = $(USER) - export HOST = $(HOSTNAME) - export NAN_PYTHON ?= $(LCGDIR)/python - export NAN_PYTHON_VERSION ?= 2.3 - export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION) - export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a - export NAN_OPENAL ?= $(LCGDIR)/openal - export NAN_JPEG ?= $(LCGDIR)/jpeg - export NAN_PNG ?= $(LCGDIR)/png - export NAN_TIFF ?= $(LCGDIR)/tiff - export NAN_ODE ?= $(LCGDIR)/ode - export NAN_TERRAPLAY ?= $(LCGDIR)/terraplay - export NAN_MESA ?= /usr/src/Mesa-3.1 - export NAN_ZLIB ?= $(LCGDIR)/zlib - export NAN_NSPR ?= $(LCGDIR)/nspr - export NAN_FREETYPE ?= $(LCGDIR)/freetype - export NAN_GETTEXT ?= $(LCGDIR)/gettext - export NAN_SDL ?= $(shell sdl-config --prefix) - export NAN_SDLLIBS ?= $(shell sdl-config --libs) - export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags) - - # Uncomment the following line to use Mozilla inplace of netscape - # CPPFLAGS +=-DMOZ_NOT_NET - # Location of MOZILLA/Netscape header files... - export NAN_MOZILLA_INC ?= $(LCGDIR)/mozilla/include - export NAN_MOZILLA_LIB ?= $(LCGDIR)/mozilla/lib/ - # Will fall back to look in NAN_MOZILLA_INC/nspr and NAN_MOZILLA_LIB - # if this is not set. - - export NAN_BUILDINFO ?= true - # Be paranoid regarding library creation (do not update archives) - export NAN_PARANOID ?= true - - # l10n - #export INTERNATIONAL ?= true - - else ifeq ($(OS),darwin) export ID = $(shell whoami) @@ -589,7 +549,6 @@ endif endif # irix endif # freebsd endif # darwin - endif # beos endif # CONFIG_GUESS diff --git a/source/nan_link.mk b/source/nan_link.mk index 42b17b425b3..63c9a578498 100644 --- a/source/nan_link.mk +++ b/source/nan_link.mk @@ -49,10 +49,6 @@ endif # default (overriden by windows) SOEXT = .so -ifeq ($(OS),beos) - LLIBS = -L/boot/develop/lib/x86/ -lGL -lbe -L/boot/home/config/lib/ -endif - ifeq ($(OS),darwin) LLIBS += -lGLU -lGL LLIBS += -lz -lstdc++ diff --git a/tools/btools.py b/tools/btools.py index 377a389941f..9603022deaa 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -44,9 +44,8 @@ def validate_arguments(args, bc): 'WITH_BF_INTERNATIONAL', 'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'BF_GETTEXT_LIBPATH', 'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH', - 'WITH_BF_ODE', 'BF_ODE', 'BF_ODE_INC', 'BF_ODE_LIB', - 'WITH_BF_GAMEENGINE', 'WITH_BF_SOLID', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', - 'BF_SOLID', 'BF_SOLID_INC', 'BF_WINTAB', 'BF_WINTAB_INC', + 'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', + 'BF_WINTAB', 'BF_WINTAB_INC', 'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH', 'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', @@ -251,19 +250,11 @@ def read_opts(cfg, args): (BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)), - (BoolVariable('WITH_BF_ODE', 'Use ODE if true', True)), - ('BF_ODE', 'ODE base path', ''), - ('BF_ODE_INC', 'ODE include path' , ''), - ('BF_ODE_LIB', 'ODE library', ''), - (BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)), ('BF_BULLET', 'Bullet base dir', ''), ('BF_BULLET_INC', 'Bullet include path', ''), ('BF_BULLET_LIB', 'Bullet library', ''), - (BoolVariable('WITH_BF_SOLID', 'Use Sumo/Solid deprecated physics system if true', True)), - ('BF_SOLID', 'Solid base dir', '#/extern/solid'), - ('BF_SOLID_INC', 'Solid include path', ''), ('BF_WINTAB', 'WinTab base dir', ''), ('BF_WINTAB_INC', 'WinTab include dir', ''), ('BF_CXX', 'c++ base path for libstdc++, only used when static linking', ''), -- cgit v1.2.3 From 5c207a61f3defc4c25dab1bc0f13c100b8bc4fca Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 2 Jul 2009 15:45:15 +0000 Subject: *RTBuilder now supports splitting leafs in N leafs something is wrong on rayobject_bvh as it looks slower than BLI_bvh and code is based on it --- .../render/intern/include/rayobject_rtbuild.h | 5 +- source/blender/render/intern/source/rayobject.c | 1 + .../blender/render/intern/source/rayobject_bvh.c | 97 +++++++++++++++++----- .../render/intern/source/rayobject_rtbuild.c | 49 +++++++---- 4 files changed, 116 insertions(+), 36 deletions(-) diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index fbe3930149c..af0a11508e8 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -41,7 +41,7 @@ * generate with simple calls, and then convert to the theirs * specific structure on the fly. */ -#define MAX_CHILDS 32 +#define RTBUILD_MAX_CHILDS 32 typedef struct RTBuilder { /* list to all primitives in this tree */ @@ -51,7 +51,7 @@ typedef struct RTBuilder int split_axis; /* child partitions calculated during splitting */ - int child_offset[MAX_CHILDS+1]; + int child_offset[RTBUILD_MAX_CHILDS+1]; } RTBuilder; @@ -67,5 +67,6 @@ RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); /* Calculates child partitions and returns number of efectively needed partitions */ int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); +int rtbuild_get_largest_axis(RTBuilder *b); #endif diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 7779c2aee82..a8564721422 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -296,6 +296,7 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) RE_RC_COUNT(isec->count->raycast.test); /* Setup vars used on raycast */ + isec->labda *= Normalize(isec->vec); isec->dist = VecLength(isec->vec); for(i=0; i<3; i++) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 4be57543a77..a67def00220 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -35,7 +35,7 @@ #include "rayobject_rtbuild.h" #include "rayobject.h" -#define BVH_NCHILDS 2 +#define BVH_NCHILDS 4 typedef struct BVHTree BVHTree; static int bvh_intersect(BVHTree *obj, Isect *isec); @@ -57,7 +57,7 @@ typedef struct BVHNode BVHNode; struct BVHNode { BVHNode *child[BVH_NCHILDS]; - float bb[2][3]; + float *bb; //[6]; //[2][3]; }; struct BVHTree @@ -65,6 +65,7 @@ struct BVHTree RayObject rayobj; BVHNode *alloc, *next_node, *root; + float *bb_alloc, *bb_next; RTBuilder *builder; }; @@ -90,6 +91,9 @@ static void bvh_free(BVHTree *obj) if(obj->alloc) MEM_freeN(obj->alloc); + if(obj->bb_alloc) + MEM_freeN(obj->bb_alloc); + MEM_freeN(obj); } @@ -99,8 +103,8 @@ static void bvh_merge_bb(BVHNode *node, float *min, float *max) if(RayObject_isAligned(node)) { //TODO only half operations needed - DO_MINMAX(node->bb[0], min, max); - DO_MINMAX(node->bb[1], min, max); + DO_MINMAX(node->bb , min, max); + DO_MINMAX(node->bb+3, min, max); } else { @@ -121,18 +125,40 @@ static int dfs_raycast(BVHNode *node, Isect *isec) int hit = 0; if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) { - int i; - for(i=0; ichild[i])) - { - hit |= dfs_raycast(node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } +// if(isec->idot_axis[node->split_axis] > 0.0f) + { + int i; + for(i=0; ichild[i])) + { + if(node->child[i] == 0) break; + + hit |= dfs_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } +/* + else + { + int i; + for(i=BVH_NCHILDS-1; i>=0; i--) + if(RayObject_isAligned(node->child[i])) + { + hit |= dfs_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } +*/ } return hit; } @@ -154,11 +180,36 @@ static void bvh_add(BVHTree *obj, RayObject *ob) rtbuild_add( obj->builder, ob ); } +static BVHNode *bvh_new_node(BVHTree *tree) +{ + BVHNode *node = tree->next_node++; + node->bb = tree->bb_next; + tree->bb_next += 6; + + return node; +} + static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder) { if(rtbuild_size(builder) == 1) { - return (BVHNode*)builder->begin[0]; +// return (BVHNode*)builder->begin[0]; +// +// + int i; + BVHNode *parent = bvh_new_node(tree); + + INIT_MINMAX(parent->bb, parent->bb+3); + + for(i=0; i<1; i++) + { + parent->child[i] = (BVHNode*)builder->begin[i]; + bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); + } + for(; ichild[i] = 0; + + return parent; } else { @@ -166,15 +217,17 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder) int nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); RTBuilder tmp; - BVHNode *parent = tree->next_node++; + BVHNode *parent = bvh_new_node(tree); - INIT_MINMAX(parent->bb[0], parent->bb[1]); + INIT_MINMAX(parent->bb, parent->bb+3); // bvh->split_axis = tmp->split_axis; for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp) ); - bvh_merge_bb(parent->child[i], parent->bb[0], parent->bb[1]); + bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); } + for(; ichild[i] = 0; return parent; } @@ -189,6 +242,10 @@ static void bvh_done(BVHTree *obj) assert(needed_nodes > 0); obj->alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); obj->next_node = obj->alloc; + + obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, "BVHTree.Nodes"); + obj->bb_next = obj->bb_alloc; + obj->root = bvh_rearrange( obj, obj->builder ); assert(obj->alloc+needed_nodes >= obj->next_node); diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 46833b8c15d..391aaeb10c2 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -1,8 +1,10 @@ +#include +#include + #include "rayobject_rtbuild.h" #include "MEM_guardedalloc.h" #include "BLI_arithb.h" #include "BKE_utildefines.h" -#include static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); @@ -16,7 +18,7 @@ static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) b->end = end; b->split_axis = 0; - for(i=0; ichild_offset[i] = 0; } @@ -59,7 +61,7 @@ static void merge_bb(RTBuilder *b, float *min, float *max) RE_rayobject_merge_bb(*index, min, max); } -static int calc_largest_axis(RTBuilder *b) +int rtbuild_get_largest_axis(RTBuilder *b) { float min[3], max[3], sub[3]; @@ -84,25 +86,44 @@ static int calc_largest_axis(RTBuilder *b) } -//Unballanced mean -//TODO better balance nodes -//TODO suport for variable number of partitions (its hardcoded in 2) +//Left balanced tree int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) { - b->child_offset[0] = 0; - b->child_offset[1] = (b->end - b->begin) / 2; - b->child_offset[2] = (b->end - b->begin); - - assert( b->child_offset[0] != b->child_offset[1] && b->child_offset[1] != b->child_offset[2]); + int i; + int leafs_per_child; + int tot_leafs = rtbuild_size(b); + + long long s; - split_leafs(b, b->child_offset, 2, axis); - return 2; + assert(nchilds <= RTBUILD_MAX_CHILDS); + + //TODO optimize calc of leafs_per_child + for(s=nchilds; s= tot_leafs); + + b->child_offset[0] = 0; + for(i=1; ; i++) + { + assert(i <= nchilds); + + b->child_offset[i] = b->child_offset[i-1] + leafs_per_child; + if(b->child_offset[i] >= tot_leafs) + { + b->child_offset[i] = tot_leafs; + split_leafs(b, b->child_offset, i, axis); + + assert(i > 1); + return i; + } + } } int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) { - int axis = calc_largest_axis(b); + int axis = rtbuild_get_largest_axis(b); return rtbuild_mean_split(b, nchilds, axis); } -- cgit v1.2.3 From 617851bf21ac5da10bfd171816187e1336cd4a69 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 2 Jul 2009 20:46:35 +0000 Subject: - added API functions: - Mesh.calc_normals - Object.add_vertex_to_group - Main.add_material - Main.add_texture - Material.add_texture - OBJ importer conversion in progress --- release/io/export_obj.py | 2 +- release/io/import_obj.py | 184 ++++++++++++---------- source/blender/makesrna/intern/makesrna.c | 2 +- source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_main_api.c | 30 +++- source/blender/makesrna/intern/rna_material.c | 2 + source/blender/makesrna/intern/rna_material_api.c | 126 +++++++++++++++ source/blender/makesrna/intern/rna_mesh_api.c | 8 + source/blender/makesrna/intern/rna_object_api.c | 33 +++- 9 files changed, 297 insertions(+), 91 deletions(-) create mode 100644 source/blender/makesrna/intern/rna_material_api.c diff --git a/release/io/export_obj.py b/release/io/export_obj.py index d139e872251..1ee685a52a3 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -464,7 +464,7 @@ def write(filename, objects, scene, # XXX # High Quality Normals if EXPORT_NORMALS and face_index_pairs: - pass + me.calc_normals() # if EXPORT_NORMALS_HQ: # BPyMesh.meshCalcNormals(me) # else: diff --git a/release/io/import_obj.py b/release/io/import_obj.py index b81ada15f89..e16780ce1d6 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -42,7 +42,7 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo from Blender import Mesh, Draw, Window, Texture, Material, sys import bpy -import BPyMesh +# import BPyMesh import BPyImage import BPyMessages @@ -130,9 +130,11 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ # This function sets textures defined in .mtl file # #==================================================================================# def load_material_image(blender_material, context_material_name, imagepath, type): - - texture= bpy.data.textures.new(type) - texture.setType('Image') + + texture= bpy.data.add_texture(type) + texture.type= 'IMAGE' +# texture= bpy.data.textures.new(type) +# texture.setType('Image') # Absolute path - c:\.. etc would work here image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) @@ -182,7 +184,8 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ #Create new materials for name in unique_materials: # .keys() if name != None: - unique_materials[name]= bpy.data.materials.new(name) + unique_materials[name]= bpy.data.add_material(name) +# unique_materials[name]= bpy.data.materials.new(name) unique_material_images[name]= None, False # assign None to all material images to start with, add to later. unique_materials[None]= None @@ -190,7 +193,8 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ for libname in material_libs: mtlpath= DIR + libname - if not sys.exists(mtlpath): + if not bpy.sys.exists(mtlpath): +# if not sys.exists(mtlpath): #print '\tError Missing MTL: "%s"' % mtlpath pass else: @@ -210,17 +214,23 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ line_split= line.split() line_lower= line.lower().lstrip() if line_lower.startswith('ka'): - context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + context_material.mirror_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) +# context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) elif line_lower.startswith('kd'): - context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + context_material.diffuse_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) +# context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) elif line_lower.startswith('ks'): - context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + context_material.specular_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) +# context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) elif line_lower.startswith('ns'): - context_material.setHardness( int((float(line_split[1])*0.51)) ) + context_material.specular_hardness = int((float(line_split[1])*0.51)) +# context_material.setHardness( int((float(line_split[1])*0.51)) ) elif line_lower.startswith('ni'): # Refraction index - context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3 + context_material.ior = max(1, min(float(line_split[1]), 3)) +# context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3 elif line_lower.startswith('d') or line_lower.startswith('tr'): - context_material.setAlpha(float(line_split[1])) + context_material.alpha = float(line_split[1]) +# context_material.setAlpha(float(line_split[1])) elif line_lower.startswith('map_ka'): img_filepath= line_value(line.split()) if img_filepath: @@ -395,39 +405,39 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l edge_dict[i1,i2]= 1 # FGons into triangles - if has_ngons and len_face_vert_loc_indicies > 4: +# if has_ngons and len_face_vert_loc_indicies > 4: - ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies) - faces.extend(\ - [(\ - [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ - [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ - context_material,\ - context_smooth_group,\ - context_object)\ - for ngon in ngon_face_indices]\ - ) +# ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies) +# faces.extend(\ +# [(\ +# [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ +# [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ +# context_material,\ +# context_smooth_group,\ +# context_object)\ +# for ngon in ngon_face_indices]\ +# ) - # edges to make fgons - if CREATE_FGONS: - edge_users= {} - for ngon in ngon_face_indices: - for i in (0,1,2): - i1= face_vert_loc_indicies[ngon[i ]] - i2= face_vert_loc_indicies[ngon[i-1]] - if i1>i2: i1,i2= i2,i1 +# # edges to make fgons +# if CREATE_FGONS: +# edge_users= {} +# for ngon in ngon_face_indices: +# for i in (0,1,2): +# i1= face_vert_loc_indicies[ngon[i ]] +# i2= face_vert_loc_indicies[ngon[i-1]] +# if i1>i2: i1,i2= i2,i1 - try: - edge_users[i1,i2]+=1 - except KeyError: - edge_users[i1,i2]= 1 +# try: +# edge_users[i1,i2]+=1 +# except KeyError: +# edge_users[i1,i2]= 1 - for key, users in edge_users.iteritems(): - if users>1: - fgon_edges[key]= None +# for key, users in edge_users.iteritems(): +# if users>1: +# fgon_edges[key]= None - # remove all after 3, means we dont have to pop this one. - faces.pop(f_idx) +# # remove all after 3, means we dont have to pop this one. +# faces.pop(f_idx) # Build sharp edges @@ -564,33 +574,36 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l # me_edges[ed].flag |= SHARP # del SHARP -# if CREATE_EDGES: + if CREATE_EDGES: + + me.add_geometry(0, len(edges)) + + # edges is (should be) a list of (a, b) tuples + me.edges.foreach_set("verts", unpack_list(edges)) # me_edges.extend( edges ) # del me_edges - + + me.calc_normals() # me.calcNormals() ob= bpy.data.add_object("MESH", "Mesh") ob.data= me + scn.add_object(ob) # ob= scn.objects.new(me) new_objects.append(ob) -# # Create the vertex groups. No need to have the flag passed here since we test for the -# # content of the vertex_groups. If the user selects to NOT have vertex groups saved then -# # the following test will never run -# for group_name, group_indicies in vertex_groups.iteritems(): -# i= ob.add_vertex_group(group_name) -# # me.addVertGroup(group_name) -# me.assign_verts_to_group(group_index, group_indicies, len(group_indicies), 1.0, 'REPLACE') -# # me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE) + # Create the vertex groups. No need to have the flag passed here since we test for the + # content of the vertex_groups. If the user selects to NOT have vertex groups saved then + # the following test will never run + for group_name, group_indicies in vertex_groups.iteritems(): + group= ob.add_vertex_group(group_name) +# me.addVertGroup(group_name) + for vertex_index in group_indicies: + ob.add_vertex_to_group(vertex_index, group, 1.0, 'REPLACE') +# me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE) -class Mesh(bpy.types.Mesh): - - def assign_verts_to_group(self, group_index, vert_indices, weight): - - def create_nurbs(scn, context_nurbs, vert_loc, new_objects): ''' Add nurbs object to blender, only support one type at the moment @@ -700,16 +713,16 @@ def get_float_func(filepath): return float def load_obj(filepath, - CLAMP_SIZE= 0.0, - CREATE_FGONS= True, - CREATE_SMOOTH_GROUPS= True, - CREATE_EDGES= True, - SPLIT_OBJECTS= True, - SPLIT_GROUPS= True, - SPLIT_MATERIALS= True, - ROTATE_X90= True, - IMAGE_SEARCH=True, - POLYGROUPS=False): + CLAMP_SIZE= 0.0, + CREATE_FGONS= True, + CREATE_SMOOTH_GROUPS= True, + CREATE_EDGES= True, + SPLIT_OBJECTS= True, + SPLIT_GROUPS= True, + SPLIT_MATERIALS= True, + ROTATE_X90= True, + IMAGE_SEARCH=True, + POLYGROUPS=False): ''' Called by the user interface or another script. load_obj(path) - should give acceptable results. @@ -997,30 +1010,30 @@ def load_obj(filepath, create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) # nurbs support - for context_nurbs in nurbs: - create_nurbs(scn, context_nurbs, verts_loc, new_objects) +# for context_nurbs in nurbs: +# create_nurbs(scn, context_nurbs, verts_loc, new_objects) axis_min= [ 1000000000]*3 axis_max= [-1000000000]*3 - if CLAMP_SIZE: - # Get all object bounds - for ob in new_objects: - for v in ob.getBoundBox(): - for axis, value in enumerate(v): - if axis_min[axis] > value: axis_min[axis]= value - if axis_max[axis] < value: axis_max[axis]= value +# if CLAMP_SIZE: +# # Get all object bounds +# for ob in new_objects: +# for v in ob.getBoundBox(): +# for axis, value in enumerate(v): +# if axis_min[axis] > value: axis_min[axis]= value +# if axis_max[axis] < value: axis_max[axis]= value - # Scale objects - max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2]) - scale= 1.0 +# # Scale objects +# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2]) +# scale= 1.0 - while CLAMP_SIZE < max_axis * scale: - scale= scale/10.0 +# while CLAMP_SIZE < max_axis * scale: +# scale= scale/10.0 - for ob in new_objects: - ob.setSize(scale, scale, scale) +# for ob in new_objects: +# ob.setSize(scale, scale, scale) # Better rotate the vert locations #if not ROTATE_X90: @@ -1276,5 +1289,10 @@ else: # NOTES (all line numbers refer to 2.4x import_obj.py, not this file) # check later: line 489 -# edge flags, edges, normals: lines 508-528 -# vertex groups: line 533 - cannot assign vertex groups +# can convert now: edge flags, edges: lines 508-528 +# ngon (uses python module BPyMesh): 384-414 +# nurbs: 947- +# clamp size: cannot get bound box with RNA - neither I can write RNA struct function that returns it - +# again, RNA limitation +# warning: uses bpy.sys.exists +# get back to l 140 (here) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index e779f901b3c..8a9fdb8531d 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1911,7 +1911,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_lamp.c", NULL, RNA_def_lamp}, {"rna_lattice.c", NULL, RNA_def_lattice}, {"rna_main.c", "rna_main_api.c", RNA_def_main}, - {"rna_material.c", NULL, RNA_def_material}, + {"rna_material.c", "rna_material_api.c", RNA_def_material}, {"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh}, {"rna_meta.c", NULL, RNA_def_meta}, {"rna_modifier.c", NULL, RNA_def_modifier}, diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index f465e733d68..7bf33760011 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -193,6 +193,7 @@ void RNA_api_object(struct StructRNA *srna); void RNA_api_ui_layout(struct StructRNA *srna); void RNA_api_wm(struct StructRNA *srna); void RNA_api_scene(struct StructRNA *srna); +void RNA_api_material(StructRNA *srna); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 08a3b7cee25..9dc32acff6f 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -40,6 +40,7 @@ #include "BKE_mesh.h" #include "BKE_library.h" #include "BKE_object.h" +#include "BKE_material.h" #include "DNA_mesh_types.h" @@ -68,7 +69,7 @@ static Object* rna_Main_add_object(Main *main, int type, char *name) } /* - WARNING: the following example shows when this function should not be called + NOTE: the following example shows when this function should _not_ be called ob = bpy.data.add_object() scene.add_object(ob) @@ -87,6 +88,20 @@ static void rna_Main_remove_object(Main *main, ReportList *reports, Object *ob) BKE_report(reports, RPT_ERROR, "Object must have zero users to be removed."); } +static Material *rna_Main_add_material(Main *main, char *name) +{ + return add_material(name); +} + +/* TODO: remove material? */ + +struct Tex *rna_Main_add_texture(Main *main, char *name) +{ + return add_texture(name); +} + +/* TODO: remove texture? */ + #else void RNA_api_main(StructRNA *srna) @@ -136,6 +151,19 @@ void RNA_api_main(StructRNA *srna) RNA_def_function_ui_description(func, "Remove a mesh if it has zero users."); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove."); RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "add_material", "rna_Main_add_material"); + RNA_def_function_ui_description(func, "Add a new material."); + parm= RNA_def_string(func, "name", "Material", 0, "", "New name for the datablock."); /* optional */ + parm= RNA_def_pointer(func, "material", "Material", "", "New material."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "add_texture", "rna_Main_add_texture"); + RNA_def_function_ui_description(func, "Add a new texture."); + parm= RNA_def_string(func, "name", "Tex", 0, "", "New name for the datablock."); /* optional */ + parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture."); + RNA_def_function_return(func, parm); + } #endif diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 41f31594f6e..6de13dbd440 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1134,6 +1134,8 @@ void RNA_def_material(BlenderRNA *brna) rna_def_material_sss(brna); rna_def_material_mtex(brna); rna_def_material_strand(brna); + + RNA_api_material(srna); } void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeget, const char *structname) diff --git a/source/blender/makesrna/intern/rna_material_api.c b/source/blender/makesrna/intern/rna_material_api.c new file mode 100644 index 00000000000..e2b47460fdb --- /dev/null +++ b/source/blender/makesrna/intern/rna_material_api.c @@ -0,0 +1,126 @@ +/** + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "DNA_material_types.h" + +#ifdef RNA_RUNTIME + +#include "BKE_material.h" +#include "BKE_texture.h" + +/* + Adds material to the first free texture slot. + If all slots are busy, replaces the first. +*/ +static void rna_Material_add_texture(Material *ma, Tex *tex, int mapto, int texco) +{ + int i; + MTex *mtex; + int slot= -1; + + for (i= 0; i < MAX_MTEX; i++) { + if (!ma->mtex[i]) { + slot= i; + break; + } + } + + if (slot == -1) + slot= 0; + + if (ma->mtex[slot]) { + ma->mtex[slot]->tex->id.us--; + } + else { + ma->mtex[slot]= add_mtex(); + } + + mtex= ma->mtex[slot]; + + mtex->tex= tex; + id_us_plus(&tex->id); + + mtex->texco= mapto; + mtex->mapto= texco; +} + +#else + +void RNA_api_material(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + /* copied from rna_def_material_mtex (rna_material.c) */ + static EnumPropertyItem prop_texture_coordinates_items[] = { + {TEXCO_GLOB, "GLOBAL", 0, "Global", "Uses global coordinates for the texture coordinates."}, + {TEXCO_OBJECT, "OBJECT", 0, "Object", "Uses linked object's coordinates for texture coordinates."}, + {TEXCO_UV, "UV", 0, "UV", "Uses UV coordinates for texture coordinates."}, + {TEXCO_ORCO, "ORCO", 0, "Generated", "Uses the original undeformed coordinates of the object."}, + {TEXCO_STRAND, "STRAND", 0, "Strand", "Uses normalized strand texture coordinate (1D)."}, + {TEXCO_STICKY, "STICKY", 0, "Sticky", "Uses mesh's sticky coordinates for the texture coordinates."}, + {TEXCO_WINDOW, "WINDOW", 0, "Window", "Uses screen coordinates as texture coordinates."}, + {TEXCO_NORM, "NORMAL", 0, "Normal", "Uses normal vector as texture coordinates."}, + {TEXCO_REFL, "REFLECTION", 0, "Reflection", "Uses reflection vector as texture coordinates."}, + {TEXCO_STRESS, "STRESS", 0, "Stress", "Uses the difference of edge lengths compared to original coordinates of the mesh."}, + {TEXCO_TANGENT, "TANGENT", 0, "Tangent", "Uses the optional tangent vector as texture coordinates."}, + + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem prop_texture_mapto_items[] = { + {MAP_COL, "COLOR", 0, "Color", "Causes the texture to affect basic color of the material"}, + {MAP_NORM, "NORMAL", 0, "Normal", "Causes the texture to affect the rendered normal"}, + {MAP_COLSPEC, "SPEC_COLOR", 0, "Specularity Color", "Causes the texture to affect the specularity color"}, + {MAP_COLMIR, "MIRROR", 0, "Mirror", "Causes the texture to affect the mirror color"}, + {MAP_REF, "REFLECTION", 0, "Reflection", "Causes the texture to affect the value of the materials reflectivity"}, + {MAP_SPEC, "SPECULARITY", 0, "Specularity", "Causes the texture to affect the value of specularity"}, + {MAP_EMIT, "EMIT", 0, "Emit", "Causes the texture to affect the emit value"}, + {MAP_ALPHA, "ALPHA", 0, "Alpha", "Causes the texture to affect the alpha value"}, + {MAP_HAR, "HARDNESS", 0, "Hardness", "Causes the texture to affect the hardness value"}, + {MAP_RAYMIRR, "RAY_MIRROR", 0, "Ray-Mirror", "Causes the texture to affect the ray-mirror value"}, + {MAP_TRANSLU, "TRANSLUCENCY", 0, "Translucency", "Causes the texture to affect the translucency value"}, + {MAP_AMB, "AMBIENT", 0, "Ambient", "Causes the texture to affect the value of ambient"}, + {MAP_DISPLACE, "DISPLACEMENT", 0, "Displacement", "Let the texture displace the surface"}, + {MAP_WARP, "WARP", 0, "Warp", "Let the texture warp texture coordinates of next channels"}, + {0, NULL, 0, NULL, NULL}}; + + func= RNA_def_function(srna, "add_texture", "rna_Material_add_texture"); + RNA_def_function_ui_description(func, "Add a texture to material's free texture slot."); + parm= RNA_def_pointer(func, "texture", "Texture", "", "Texture to add."); + parm= RNA_def_enum(func, "texture_coordinates", prop_texture_coordinates_items, TEXCO_UV, "", "Source of texture coordinate information."); /* optional */ + parm= RNA_def_enum(func, "map_to", prop_texture_mapto_items, MAP_COL, "", "Controls which material property the texture affects."); /* optional */ +} + +#endif + diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index ecc32b23249..b2157340207 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -253,6 +253,11 @@ static void rna_Mesh_add_uv_layer(Mesh *me) me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface); } +static void rna_Mesh_calc_normals(Mesh *me) +{ + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); +} + #else void RNA_api_mesh(StructRNA *srna) @@ -281,6 +286,9 @@ void RNA_api_mesh(StructRNA *srna) func= RNA_def_function(srna, "add_uv_layer", "rna_Mesh_add_uv_layer"); RNA_def_function_ui_description(func, "Add new UV layer to Mesh."); + func= RNA_def_function(srna, "calc_normals", "rna_Mesh_calc_normals"); + RNA_def_function_ui_description(func, "Calculate vertex normals."); + /* func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom"); RNA_def_function_ui_description(func, "Add geometry data to mesh."); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 9d1a6a39d51..02db7e83062 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -155,10 +155,15 @@ static void rna_Object_convert_to_triface(Object *ob, bContext *C, ReportList *r DAG_object_flush_update(sce, ob, OB_RECALC_DATA); } -static int rna_Object_add_vertex_group(Object *ob, char *group_name) +static bDeformGroup *rna_Object_add_vertex_group(Object *ob, char *group_name) { - bDeformGroup *defgroup= add_defgroup_name(ob, group_name); - return BLI_findindex(&ob->defbase, defgroup); + return add_defgroup_name(ob, group_name); +} + +static void rna_Object_add_vertex_to_group(Object *ob, int vertex_index, bDeformGroup *def, float weight, int assignmode) +{ + /* creates dverts if needed */ + add_vert_to_defgroup(ob, def, vertex_index, weight, assignmode); } /* @@ -210,6 +215,13 @@ void RNA_api_object(StructRNA *srna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem assign_mode_items[] = { + {WEIGHT_REPLACE, "REPLACE", 0, "Replace", "Replace."}, /* TODO: more meaningful descriptions */ + {WEIGHT_ADD, "ADD", 0, "Add", "Add."}, + {WEIGHT_SUBTRACT, "SUBTRACT", 0, "Subtract", "Subtract."}, + {0, NULL, 0, NULL, NULL} + }; + func= RNA_def_function(srna, "create_mesh", "rna_Object_create_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); @@ -234,9 +246,20 @@ void RNA_api_object(StructRNA *srna) func= RNA_def_function(srna, "add_vertex_group", "rna_Object_add_vertex_group"); RNA_def_function_ui_description(func, "Add vertex group to object."); - parm= RNA_def_string(func, "name", "Group", 0, "", "Vertex group name."); - parm= RNA_def_int(func, "group_index", 0, 0, 0, "", "Index of the created vertex group.", 0, 0); + parm= RNA_def_string(func, "name", "Group", 0, "", "Vertex group name."); /* optional */ + parm= RNA_def_pointer(func, "group", "VertexGroup", "", "New vertex group."); RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "add_vertex_to_group", "rna_Object_add_vertex_to_group"); + RNA_def_function_ui_description(func, "Add vertex to a vertex group."); + parm= RNA_def_int(func, "vertex_index", 0, 0, 0, "", "Vertex index.", 0, 0); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "group", "VertexGroup", "", "Vertex group to add vertex to."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_float(func, "weight", 0, 0.0f, 1.0f, "", "Vertex weight.", 0.0f, 1.0f); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "type", assign_mode_items, 0, "", "Vertex assign mode."); + RNA_def_property_flag(parm, PROP_REQUIRED); } #endif -- cgit v1.2.3 From 686a426cf010d3de627dbb44082bc3b9371f77f8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 2 Jul 2009 21:57:50 +0000 Subject: *fixed rtbuild (there was a sorting bug introduced while adapting code from BLI_bvh) This bvh should be at least as fast as BLI_kdopbvh now --- source/blender/render/intern/source/rayobject.c | 3 +- .../blender/render/intern/source/rayobject_bvh.c | 35 ++++++---- .../render/intern/source/rayobject_rtbuild.c | 78 +++++++++++++--------- 3 files changed, 71 insertions(+), 45 deletions(-) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index a8564721422..ffe1bba52c9 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -42,8 +42,9 @@ * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] */ -float RE_rayobject_bb_intersect(const Isect *isec, const float *bb) +float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb) { + const float *bb = _bb; float dist; float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index a67def00220..8bf0a72bbb5 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -27,6 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ #include +#include #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" @@ -58,6 +59,7 @@ struct BVHNode { BVHNode *child[BVH_NCHILDS]; float *bb; //[6]; //[2][3]; + char split_axis; }; struct BVHTree @@ -125,7 +127,7 @@ static int dfs_raycast(BVHNode *node, Isect *isec) int hit = 0; if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) { -// if(isec->idot_axis[node->split_axis] > 0.0f) + if(isec->idot_axis[node->split_axis] > 0.0f) { int i; for(i=0; imode == RE_RAY_SHADOW) return hit; } } -/* else { int i; @@ -158,7 +159,6 @@ static int dfs_raycast(BVHNode *node, Isect *isec) if(hit && isec->mode == RE_RAY_SHADOW) return hit; } } -*/ } return hit; } @@ -180,16 +180,25 @@ static void bvh_add(BVHTree *obj, RayObject *ob) rtbuild_add( obj->builder, ob ); } -static BVHNode *bvh_new_node(BVHTree *tree) +static BVHNode *bvh_new_node(BVHTree *tree, int nid) { - BVHNode *node = tree->next_node++; + BVHNode *node = tree->alloc + nid - 1; + if(node+1 > tree->next_node) + tree->next_node = node+1; + node->bb = tree->bb_next; tree->bb_next += 6; return node; } -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder) +static int child_id(int pid, int nchild) +{ + //N child of node A = A * K + (2 - K) + N, (0 <= N < K) + return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; +} + +static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) { if(rtbuild_size(builder) == 1) { @@ -197,7 +206,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder) // // int i; - BVHNode *parent = bvh_new_node(tree); + BVHNode *parent = bvh_new_node(tree, nid); INIT_MINMAX(parent->bb, parent->bb+3); @@ -217,13 +226,13 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder) int nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); RTBuilder tmp; - BVHNode *parent = bvh_new_node(tree); + BVHNode *parent = bvh_new_node(tree, nid); INIT_MINMAX(parent->bb, parent->bb+3); -// bvh->split_axis = tmp->split_axis; + parent->split_axis = builder->split_axis; for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp) ); + parent->child[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i) ); bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); } for(; ialloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); obj->next_node = obj->alloc; - obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, "BVHTree.Nodes"); + obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, "BVHTree.NodesBB"); obj->bb_next = obj->bb_alloc; - obj->root = bvh_rearrange( obj, obj->builder ); + obj->root = bvh_rearrange( obj, obj->builder, 1 ); assert(obj->alloc+needed_nodes >= obj->next_node); + printf("BVH: Used %d nodes\n", obj->next_node-obj->alloc); + rtbuild_free( obj->builder ); obj->builder = NULL; diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 391aaeb10c2..7be17312a52 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -67,8 +67,10 @@ int rtbuild_get_largest_axis(RTBuilder *b) INIT_MINMAX(min, max); merge_bb( b, min, max); - - VECSUB(sub, max, min); + + sub[0] = max[0]-min[0]; + sub[1] = max[1]-min[1]; + sub[2] = max[2]-min[2]; if(sub[0] > sub[1]) { if(sub[0] > sub[2]) @@ -90,8 +92,9 @@ int rtbuild_get_largest_axis(RTBuilder *b) int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) { int i; - int leafs_per_child; + int mleafs_per_child, Mleafs_per_child; int tot_leafs = rtbuild_size(b); + int missing_leafs; long long s; @@ -99,25 +102,41 @@ int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) //TODO optimize calc of leafs_per_child for(s=nchilds; s= tot_leafs); + Mleafs_per_child = s/nchilds; + mleafs_per_child = Mleafs_per_child/nchilds; + //split min leafs per child b->child_offset[0] = 0; - for(i=1; ; i++) + for(i=1; i<=nchilds; i++) + b->child_offset[i] = mleafs_per_child; + + //split remaining leafs + missing_leafs = tot_leafs - mleafs_per_child*nchilds; + for(i=1; i<=nchilds; i++) { - assert(i <= nchilds); - - b->child_offset[i] = b->child_offset[i-1] + leafs_per_child; - if(b->child_offset[i] >= tot_leafs) + if(missing_leafs > Mleafs_per_child - mleafs_per_child) { - b->child_offset[i] = tot_leafs; - split_leafs(b, b->child_offset, i, axis); - - assert(i > 1); - return i; + b->child_offset[i] += Mleafs_per_child - mleafs_per_child; + missing_leafs -= Mleafs_per_child - mleafs_per_child; + } + else + { + b->child_offset[i] += missing_leafs; + missing_leafs = 0; + break; } } + + //adjust for accumulative offsets + for(i=1; i<=nchilds; i++) + b->child_offset[i] += b->child_offset[i-1]; + + //Count created childs + for(i=nchilds; b->child_offset[i] == b->child_offset[i-1]; i--); + split_leafs(b, b->child_offset, i, axis); + + assert( b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs ); + return i; } @@ -166,15 +185,15 @@ static int medianof3(RTBuilder *d, int a, int b, int c) } else { - if(fc > fb) - return b; - else + if(fc < fb) { - if(fc > fa) - return c; - else + if(fc < fa) return a; + else + return c; } + else + return b; } } @@ -203,14 +222,9 @@ static int partition(RTBuilder *b, int lo, int mid, int hi) int i=lo, j=hi; while (1) { - while(sort_get_value(b,i) < x) - i++; - + while(sort_get_value(b,i) < x) i++; j--; - - while(x < sort_get_value(b,j)) - j--; - + while(x < sort_get_value(b,j)) j--; if(!(i < j)) return i; @@ -226,7 +240,7 @@ static int partition(RTBuilder *b, int lo, int mid, int hi) // after a call to this function you can expect one of: // every node to left of a[n] are smaller or equal to it // every node to the right of a[n] are greater or equal to it -static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n) +static int partition_nth_element(RTBuilder *b, int _begin, int n, int _end) { int begin = _begin, end = _end, cut; while(end-begin > 3) @@ -246,10 +260,10 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) { int i; b->split_axis = split_axis; + for(i=0; i < partitions-1; i++) { - if(nth[i] >= nth[partitions]) - break; + assert(nth[i] < nth[i+1] && nth[i+1] < nth[partitions]); partition_nth_element(b, nth[i], nth[i+1], nth[partitions] ); } -- cgit v1.2.3 From 4b81d44282f214f5e208f24ae79ce966e0a105d2 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 2 Jul 2009 22:12:26 +0000 Subject: *fixed crash --- source/blender/render/intern/source/rayobject_bvh.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 8bf0a72bbb5..8e9484d14b8 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -150,8 +150,11 @@ static int dfs_raycast(BVHNode *node, Isect *isec) for(i=BVH_NCHILDS-1; i>=0; i--) if(RayObject_isAligned(node->child[i])) { - hit |= dfs_raycast(node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; + if(node->child[i]) + { + hit |= dfs_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } } else { @@ -259,7 +262,7 @@ static void bvh_done(BVHTree *obj) assert(obj->alloc+needed_nodes >= obj->next_node); - printf("BVH: Used %d nodes\n", obj->next_node-obj->alloc); +// printf("BVH: Used %d nodes\n", obj->next_node-obj->alloc); rtbuild_free( obj->builder ); -- cgit v1.2.3 From 8394653ebd0f62615d8a4b71e5ff6bd905684dd9 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 3 Jul 2009 02:26:40 +0000 Subject: *No need of a BB if the underlying structure already has a BB --- .../blender/render/intern/source/rayobject_bvh.c | 38 +++++++++++++--------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 8e9484d14b8..f5805fc1a02 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -59,7 +59,7 @@ struct BVHNode { BVHNode *child[BVH_NCHILDS]; float *bb; //[6]; //[2][3]; - char split_axis; + int split_axis; }; struct BVHTree @@ -205,23 +205,31 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) { if(rtbuild_size(builder) == 1) { -// return (BVHNode*)builder->begin[0]; -// -// - int i; - BVHNode *parent = bvh_new_node(tree, nid); - - INIT_MINMAX(parent->bb, parent->bb+3); + RayObject *child = builder->begin[0]; - for(i=0; i<1; i++) + if(RayObject_isRayFace(child)) { - parent->child[i] = (BVHNode*)builder->begin[i]; - bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); + int i; + BVHNode *parent = bvh_new_node(tree, nid); + + INIT_MINMAX(parent->bb, parent->bb+3); + + for(i=0; i<1; i++) + { + parent->child[i] = (BVHNode*)builder->begin[i]; + bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); + } + for(; ichild[i] = 0; + + return parent; + } + else + { + //Its a sub-raytrace structure, assume it has it own raycast + //methods and adding a Bounding Box arround is unnecessary + return (BVHNode*)child; } - for(; ichild[i] = 0; - - return parent; } else { -- cgit v1.2.3 From 44ef6c1eac75a5076d459500323e0e4467509f56 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 3 Jul 2009 02:56:54 +0000 Subject: *little fix --- source/blender/render/intern/source/rayobject_bvh.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index f5805fc1a02..88f673cbcb1 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -186,6 +186,7 @@ static void bvh_add(BVHTree *obj, RayObject *ob) static BVHNode *bvh_new_node(BVHTree *tree, int nid) { BVHNode *node = tree->alloc + nid - 1; + assert(RayObject_isAligned(node)); if(node+1 > tree->next_node) tree->next_node = node+1; @@ -211,7 +212,8 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) { int i; BVHNode *parent = bvh_new_node(tree, nid); - + parent->split_axis = 0; + INIT_MINMAX(parent->bb, parent->bb+3); for(i=0; i<1; i++) @@ -226,6 +228,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) } else { + assert(!RayObject_isAligned(child)); //Its a sub-raytrace structure, assume it has it own raycast //methods and adding a Bounding Box arround is unnecessary return (BVHNode*)child; -- cgit v1.2.3 From 4a72557e6b3a4b2594ca0a3b971d7f7acf59072a Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 3 Jul 2009 17:10:54 +0000 Subject: Fixed memory aligns for 64bits --- source/blender/render/intern/include/rayobject.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 3b77341f229..c611e2ceca2 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -102,14 +102,13 @@ typedef struct RayObjectAPI } RayObjectAPI; -//TODO use intptr_t -#define RayObject_align(o) ((RayObject*)(((int)o)&(~3))) -#define RayObject_unalignRayFace(o) ((RayObject*)(((int)o)|1)) -#define RayObject_unalignRayAPI(o) ((RayObject*)(((int)o)|2)) - -#define RayObject_isAligned(o) ((((int)o)&3) == 0) -#define RayObject_isRayFace(o) ((((int)o)&3) == 1) -#define RayObject_isRayAPI(o) ((((int)o)&3) == 2) +#define RayObject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) +#define RayObject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) +#define RayObject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) + +#define RayObject_isAligned(o) ((((intptr_t)o)&3) == 0) +#define RayObject_isRayFace(o) ((((intptr_t)o)&3) == 1) +#define RayObject_isRayAPI(o) ((((intptr_t)o)&3) == 2) /* * Extend min/max coords so that the rayobject is inside them -- cgit v1.2.3 From 2a23fda9d55034e524be32bd8cb196ae4cd93920 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 3 Jul 2009 17:44:20 +0000 Subject: OBJ importer almost converted, except a few features (NURBS, NGON, FGON and sharp edges). Added to API: - Main.add_image - Material.z_transparency - two temporary properties: Image.depth and Image.has_data --- release/io/import_obj.py | 148 ++++++++++++++++++-------- source/blender/makesrna/intern/rna_image.c | 37 +++++++ source/blender/makesrna/intern/rna_main_api.c | 17 ++- source/blender/makesrna/intern/rna_material.c | 5 + 4 files changed, 159 insertions(+), 48 deletions(-) diff --git a/release/io/import_obj.py b/release/io/import_obj.py index e16780ce1d6..659d5207261 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -40,14 +40,16 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -from Blender import Mesh, Draw, Window, Texture, Material, sys import bpy -# import BPyMesh -import BPyImage -import BPyMessages +import os -try: import os -except: os= False +# from Blender import Mesh, Draw, Window, Texture, Material, sys +# # import BPyMesh +# import BPyImage +# import BPyMessages + +# try: import os +# except: os= False # Generic path functions def stripFile(path): @@ -101,22 +103,44 @@ def line_value(line_split): elif length > 2: return ' '.join( line_split[1:] ) +# limited replacement for BPyImage.comprehensiveImageLoad +def load_image(imagepath, direc): + + if os.path.exists(imagepath): + return bpy.data.add_image(imagepath) + + im_base = os.path.basename(imagepath) + + tmp = os.path.join(direc, im_base) + if os.path.exists(tmp): + return bpy.data.add_image(tmp) + + # TODO comprehensiveImageLoad also searched in bpy.config.textureDir + def obj_image_load(imagepath, DIR, IMAGE_SEARCH): - ''' - Mainly uses comprehensiveImageLoad - but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores. - ''' - + if '_' in imagepath: - image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) - if image: return image - # Did the exporter rename the image? - image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) + image= load_image(imagepath.replace('_', ' '), DIR) if image: return image - - # Return an image, placeholder if it dosnt exist - image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH) - return image + + return load_image(imagepath, DIR) + +# def obj_image_load(imagepath, DIR, IMAGE_SEARCH): +# ''' +# Mainly uses comprehensiveImageLoad +# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores. +# ''' + +# if '_' in imagepath: +# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) +# if image: return image +# # Did the exporter rename the image? +# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) +# if image: return image + +# # Return an image, placeholder if it dosnt exist +# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH) +# return image def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH): @@ -139,46 +163,65 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ # Absolute path - c:\.. etc would work here image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) has_data = image.has_data - texture.image = image + + if image: + texture.image = image # Adds textures for materials (rendering) if type == 'Kd': if has_data and image.depth == 32: # Image has alpha - blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) - texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') - blender_material.mode |= Material.Modes.ZTRANSP + + # XXX bitmask won't work? + blender_material.add_texture(texture, "UV", ("COLOR", "ALPHA")) + texture.mipmap = True + texture.interpolation = True + texture.use_alpha = True + blender_material.z_transparency = True blender_material.alpha = 0.0 + +# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) +# texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') +# blender_material.mode |= Material.Modes.ZTRANSP +# blender_material.alpha = 0.0 else: - blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) + blender_material.add_texture(texture, "UV", "COLOR") +# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) # adds textures to faces (Textured/Alt-Z mode) # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func. unique_material_images[context_material_name]= image, has_data # set the texface image elif type == 'Ka': - blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API + blender_material.add_texture(texture, "UV", "AMBIENT") +# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API elif type == 'Ks': - blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) + blender_material.add_texture(texture, "UV", "SPECULAR") +# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) elif type == 'Bump': - blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR) + blender_material.add_texture(texture, "UV", "NORMAL") +# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR) elif type == 'D': - blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA) - blender_material.mode |= Material.Modes.ZTRANSP + blender_material.add_texture(texture, "UV", "ALPHA") + blender_material.z_transparency = True blender_material.alpha = 0.0 +# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA) +# blender_material.mode |= Material.Modes.ZTRANSP +# blender_material.alpha = 0.0 # Todo, unset deffuse material alpha if it has an alpha channel elif type == 'refl': - blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF) + blender_material.add_texture(texture, "UV", "REFLECTION") +# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF) # Add an MTL with the same name as the obj if no MTLs are spesified. temp_mtl= stripExt(stripPath(filepath))+ '.mtl' if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: - material_libs.append( temp_mtl ) + material_libs.append( temp_mtl ) del temp_mtl #Create new materials @@ -578,7 +621,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l me.add_geometry(0, len(edges)) - # edges is (should be) a list of (a, b) tuples + # edges should be a list of (a, b) tuples me.edges.foreach_set("verts", unpack_list(edges)) # me_edges.extend( edges ) @@ -713,6 +756,7 @@ def get_float_func(filepath): return float def load_obj(filepath, + context, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS= True, @@ -733,8 +777,9 @@ def load_obj(filepath, if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: POLYGROUPS = False - - time_main= sys.time() + + time_main= bpy.sys.time() +# time_main= sys.time() verts_loc= [] verts_tex= [] @@ -772,7 +817,8 @@ def load_obj(filepath, context_multi_line= '' print '\tparsing obj file "%s"...' % filepath, - time_sub= sys.time() + time_sub= bpy.sys.time() +# time_sub= sys.time() file= open(filepath, 'rU') for line in file: #.xreadlines(): @@ -980,15 +1026,17 @@ def load_obj(filepath, ''' file.close() - time_new= sys.time() + time_new= bpy.sys.time() +# time_new= sys.time() print '%.4f sec' % (time_new-time_sub) time_sub= time_new print '\tloading materials and images...', create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) - - time_new= sys.time() + + time_new= bpy.sys.time() +# time_new= sys.time() print '%.4f sec' % (time_new-time_sub) time_sub= time_new @@ -996,8 +1044,12 @@ def load_obj(filepath, verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] # deselect all - scn = bpy.data.scenes.active - scn.objects.selected = [] + if context.selected_objects: + bpy.ops.OBJECT_OT_select_all_toggle() + + scene = context.scene +# scn = bpy.data.scenes.active +# scn.objects.selected = [] new_objects= [] # put new objects here print '\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), @@ -1007,7 +1059,7 @@ def load_obj(filepath, for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): # Create meshes from the data, warning 'vertex_groups' wont support splitting - create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) + create_mesh(scene, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) # nurbs support # for context_nurbs in nurbs: @@ -1039,8 +1091,9 @@ def load_obj(filepath, #if not ROTATE_X90: # for ob in new_objects: # ob.RotX = -1.570796326794896558 - - time_new= sys.time() + + time_new= bpy.sys.time() +# time_new= sys.time() print '%.4f sec' % (time_new-time_sub) print 'finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)) @@ -1292,7 +1345,10 @@ else: # can convert now: edge flags, edges: lines 508-528 # ngon (uses python module BPyMesh): 384-414 # nurbs: 947- -# clamp size: cannot get bound box with RNA - neither I can write RNA struct function that returns it - -# again, RNA limitation -# warning: uses bpy.sys.exists +# NEXT clamp size: get bound box with RNA # get back to l 140 (here) +# search image in bpy.config.textureDir - load_image +# replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load) +# bitmask won't work? - 132 +# uses operator bpy.ops.OBJECT_OT_select_all_toggle() to deselect all (not necessary?) +# uses bpy.sys.exists and bpy.sys.time() diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index c74e46c17da..fbef838d06c 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -66,6 +66,29 @@ static int rna_Image_dirty_get(PointerRNA *ptr) return 0; } +static int rna_Image_has_data_get(PointerRNA *ptr) +{ + Image *im= (Image*)ptr->data; + + if (im->ibufs.first) + return 1; + + return 0; +} + +static int rna_Image_depth_get(PointerRNA *ptr) +{ + Image *im= (Image*)ptr->data; + ImBuf *ibuf= BKE_image_get_ibuf(im, NULL); + + if (!ibuf) return 0; + + if (ibuf->rect_float) + return 128; + + return ibuf->depth; +} + #else static void rna_def_imageuser(BlenderRNA *brna) @@ -275,6 +298,20 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_V); RNA_def_property_ui_text(prop, "Clamp Y", "Disable texture repeating vertically."); RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + + /* + Image.has_data and Image.depth are temporary, + Update import_obj.py when they are replaced (Arystan) + */ + prop= RNA_def_property(srna, "has_data", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_Image_has_data_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Has data", "True if this image has data."); + + prop= RNA_def_property(srna, "depth", PROP_INT, PROP_NONE); + RNA_def_property_int_funcs(prop, "rna_Image_depth_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Depth", "Image bit depth."); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); } void RNA_def_image(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 9dc32acff6f..17f3800e10e 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -33,6 +33,8 @@ #include "RNA_types.h" #include "DNA_object_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" #ifdef RNA_RUNTIME @@ -41,8 +43,7 @@ #include "BKE_library.h" #include "BKE_object.h" #include "BKE_material.h" - -#include "DNA_mesh_types.h" +#include "BKE_image.h" static Mesh *rna_Main_add_mesh(Main *main, char *name) { @@ -102,6 +103,11 @@ struct Tex *rna_Main_add_texture(Main *main, char *name) /* TODO: remove texture? */ +struct Image *rna_Main_add_image(Main *main, char *filename) +{ + return BKE_add_image_file(filename, 0); +} + #else void RNA_api_main(StructRNA *srna) @@ -164,6 +170,13 @@ void RNA_api_main(StructRNA *srna) parm= RNA_def_pointer(func, "texture", "Texture", "", "New texture."); RNA_def_function_return(func, parm); + func= RNA_def_function(srna, "add_image", "rna_Main_add_image"); + RNA_def_function_ui_description(func, "Add a new image."); + parm= RNA_def_string(func, "filename", "", 0, "", "Filename to load image from."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "image", "Image", "", "New image."); + RNA_def_function_return(func, parm); + } #endif diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 6de13dbd440..326c37d8597 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1082,6 +1082,11 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TANGENT_V); RNA_def_property_ui_text(prop, "Tangent Shading", "Use the material's tangent vector instead of the normal for shading - for anisotropic shading effects"); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); + + prop= RNA_def_property(srna, "z_transparency", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ZTRA); + RNA_def_property_ui_text(prop, "ZTransp", "Z-buffer transparency"); + RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); /* nested structs */ prop= RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NEVER_NULL); -- cgit v1.2.3 From 3d06a104a42355f094dcdf5bb6922f685f3e98d2 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 3 Jul 2009 18:16:59 +0000 Subject: rayobject_octree fixed --- .../render/intern/source/rayobject_octree.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index b7850c05104..88ea2bb38ed 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -60,7 +60,7 @@ typedef struct OcVal typedef struct Node { - struct RayObject *v[8]; + struct RayFace *v[8]; struct OcVal ov[8]; struct Node *next; } Node; @@ -79,7 +79,7 @@ typedef struct Octree { /* during building only */ char *ocface; - RayObject **ro_nodes; + RayFace **ro_nodes; int ro_nodes_size, ro_nodes_used; } Octree; @@ -294,7 +294,7 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short while(no->v[a]!=NULL) a++; } - no->v[a]= (RayObject*)face; + no->v[a]= (RayFace*) RayObject_align(face); if(quad) calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]); @@ -456,7 +456,7 @@ RayObject *RE_rayobject_octree_create(int ocres, int size) oc->ocres = ocres; - oc->ro_nodes = MEM_callocN(sizeof(RayObject*)*size, "octree rayobject nodes"); + oc->ro_nodes = (RayFace**)MEM_callocN(sizeof(RayFace*)*size, "octree rayobject nodes"); oc->ro_nodes_size = size; oc->ro_nodes_used = 0; @@ -469,8 +469,9 @@ static void RayObject_octree_add(RayObject *tree, RayObject *node) { Octree *oc = (Octree*)tree; + assert( RayObject_isRayFace(node) ); assert( oc->ro_nodes_used < oc->ro_nodes_size ); - oc->ro_nodes[ oc->ro_nodes_used++ ] = node; + oc->ro_nodes[ oc->ro_nodes_used++ ] = (RayFace*)RayObject_align(node); } static void octree_fill_rayface(Octree *oc, RayFace *face) @@ -601,7 +602,7 @@ static void RayObject_octree_done(RayObject *tree) /* Calculate Bounding Box */ for(c=0; cro_nodes_used; c++) - RE_rayobject_merge_bb(oc->ro_nodes[c], oc->min, oc->max); + RE_rayobject_merge_bb( RayObject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max); /* Alloc memory */ oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); @@ -631,8 +632,7 @@ static void RayObject_octree_done(RayObject *tree) for(c=0; cro_nodes_used; c++) { - assert( RayObject_isRayFace(oc->ro_nodes[c]) ); - octree_fill_rayface(oc, (RayFace*)oc->ro_nodes[c]); + octree_fill_rayface(oc, oc->ro_nodes[c]); } MEM_freeN(oc->ocface); @@ -663,14 +663,14 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) for(; no; no = no->next) for(nr=0; nr<8; nr++) { - RayObject *face = no->v[nr]; + RayFace *face = no->v[nr]; OcVal *ov = no->ov+nr; if(!face) break; if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RE_rayobject_intersect(face,is) ) + if( RE_rayobject_intersect( RayObject_unalignRayFace(face),is) ) return 1; } } @@ -682,14 +682,14 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) for(; no; no = no->next) for(nr=0; nr<8; nr++) { - RayObject *face = no->v[nr]; + RayFace *face = no->v[nr]; OcVal *ov = no->ov+nr; if(!face) break; if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RE_rayobject_intersect(face,is) ) + if( RE_rayobject_intersect( RayObject_unalignRayFace(face),is) ) found= 1; } } -- cgit v1.2.3 From 621b37bed6528af2192539295b3a604271f29cdc Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 5 Jul 2009 00:38:53 +0000 Subject: *Added BIH --- source/blender/render/extern/include/RE_raytrace.h | 3 +- .../blender/render/intern/source/rayobject_bih.c | 254 +++++++++++++++++++++ .../blender/render/intern/source/rayobject_bvh.c | 39 ++-- 3 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 source/blender/render/intern/source/rayobject_bih.c diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index e1d03c996a4..ca21433f229 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -50,9 +50,10 @@ void RE_rayobject_free(RayObject *r); RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); -#define RE_rayobject_tree_create RE_rayobject_bvh_create +#define RE_rayobject_tree_create RE_rayobject_bih_create RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_bvh_create(int size); /* rayobject_bvh.c */ +RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ /* Ray Intersection */ diff --git a/source/blender/render/intern/source/rayobject_bih.c b/source/blender/render/intern/source/rayobject_bih.c new file mode 100644 index 00000000000..fb755e2c7e6 --- /dev/null +++ b/source/blender/render/intern/source/rayobject_bih.c @@ -0,0 +1,254 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include +#include + +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" + +#define BIH_NCHILDS 4 +typedef struct BIHTree BIHTree; + +static int bih_intersect(BIHTree *obj, Isect *isec); +static void bih_add(BIHTree *o, RayObject *ob); +static void bih_done(BIHTree *o); +static void bih_free(BIHTree *o); +static void bih_bb(BIHTree *o, float *min, float *max); + +static RayObjectAPI bih_api = +{ + (RE_rayobject_raycast_callback) bih_intersect, + (RE_rayobject_add_callback) bih_add, + (RE_rayobject_done_callback) bih_done, + (RE_rayobject_free_callback) bih_free, + (RE_rayobject_merge_bb_callback)bih_bb +}; + +typedef struct BIHNode BIHNode; +struct BIHNode +{ + BIHNode *child[BIH_NCHILDS]; + float bi[BIH_NCHILDS][2]; + int split_axis; +}; + +struct BIHTree +{ + RayObject rayobj; + + BIHNode *root; + + BIHNode *node_alloc, *node_next; + RTBuilder *builder; + + float bb[2][3]; +}; + + +RayObject *RE_rayobject_bih_create(int size) +{ + BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bih_api; + obj->root = NULL; + + obj->node_alloc = obj->node_next = NULL; + obj->builder = rtbuild_create( size ); + + return RayObject_unalignRayAPI((RayObject*) obj); +} + +static void bih_free(BIHTree *obj) +{ + if(obj->builder) + rtbuild_free(obj->builder); + + if(obj->node_alloc) + MEM_freeN(obj->node_alloc); + + MEM_freeN(obj); +} + +static void bih_bb(BIHTree *obj, float *min, float *max) +{ + //TODO only half operations needed + DO_MINMAX(obj->bb[0], min, max); + DO_MINMAX(obj->bb[1], min, max); +} + +/* + * Tree transverse + */ +static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float tmax) +{ + int i; + int hit = 0; + + const int *const offset = isec->bv_index + node->split_axis*2; + + //TODO diving heuristic + for(i=0; ibi[i][offset[0]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; + float t2 = (node->bi[i][offset[1]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; + + if(t1 < tmin) t1 = tmin; //t1 = MAX2(t1, tmin); + if(t2 > tmax) t2 = tmax; //t2 = MIN2(t2, tmax); + + if(t1 <= t2) + { + if(RayObject_isAligned(node->child[i])) + { + if(node->child[i] == 0) break; + + hit |= dfs_raycast(node->child[i], isec, t1, t2); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + + if(tmax > isec->labda) + tmax = isec->labda; + } + } + + return hit; +} + +static int bih_intersect(BIHTree *obj, Isect *isec) +{ + if(RayObject_isAligned(obj->root)) + return dfs_raycast(obj->root, isec, 0, isec->labda); + else + return RE_rayobject_intersect( (RayObject*)obj->root, isec); +} + + +/* + * Builds a BIH tree from builder object + */ +static void bih_add(BIHTree *obj, RayObject *ob) +{ + rtbuild_add( obj->builder, ob ); +} + +static BIHNode *bih_new_node(BIHTree *tree, int nid) +{ + BIHNode *node = tree->node_alloc + nid - 1; + assert(RayObject_isAligned(node)); + if(node+1 > tree->node_next) + tree->node_next = node+1; + + return node; +} + +static int child_id(int pid, int nchild) +{ + //N child of node A = A * K + (2 - K) + N, (0 <= N < K) + return pid*BIH_NCHILDS+(2-BIH_NCHILDS)+nchild; +} + +static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float *bb) +{ + if(rtbuild_size(builder) == 1) + { + RayObject *child = builder->begin[0]; + assert(!RayObject_isAligned(child)); + + INIT_MINMAX(bb, bb+3); + RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3); + + return (BIHNode*)child; + } + else + { + int i; + int nc = rtbuild_mean_split_largest_axis(builder, BIH_NCHILDS); + RTBuilder tmp; + + BIHNode *parent = bih_new_node(tree, nid); + + INIT_MINMAX(bb, bb+3); + parent->split_axis = builder->split_axis; + for(i=0; ichild[i] = bih_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), cbb ); + + parent->bi[i][0] = cbb[parent->split_axis]; + parent->bi[i][1] = cbb[parent->split_axis+3]; + + DO_MINMAX(cbb , bb, bb+3); + DO_MINMAX(cbb+3, bb, bb+3); + } + for(; ibi[i][0] = 1.0; + parent->bi[i][1] = -1.0; + parent->child[i] = 0; + } + + return parent; + } +} + +static void bih_info(BIHTree *obj) +{ + printf("BIH: Used %d nodes\n", obj->node_next - obj->node_alloc); +} + +static void bih_done(BIHTree *obj) +{ + int needed_nodes; + assert(obj->root == NULL && obj->node_alloc == NULL && obj->builder); + + //TODO exact calculate needed nodes + needed_nodes = (rtbuild_size(obj->builder)+1)*2; + assert(needed_nodes > 0); + + obj->node_alloc = (BIHNode*)MEM_mallocN( sizeof(BIHNode)*needed_nodes, "BIHTree.Nodes"); + obj->node_next = obj->node_alloc; + + obj->root = bih_rearrange( obj, obj->builder, 1, (float*)obj->bb ); + + rtbuild_free( obj->builder ); + obj->builder = NULL; + + assert(obj->node_alloc+needed_nodes >= obj->node_next); +} + diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 88f673cbcb1..d9d3832830a 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -66,7 +66,9 @@ struct BVHTree { RayObject rayobj; - BVHNode *alloc, *next_node, *root; + BVHNode *root; + + BVHNode *node_alloc, *node_next; float *bb_alloc, *bb_next; RTBuilder *builder; @@ -79,9 +81,12 @@ RayObject *RE_rayobject_bvh_create(int size) assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; - obj->builder = rtbuild_create( size ); obj->root = NULL; + obj->node_alloc = obj->node_next = NULL; + obj->bb_alloc = obj->bb_next = NULL; + obj->builder = rtbuild_create( size ); + return RayObject_unalignRayAPI((RayObject*) obj); } @@ -90,8 +95,8 @@ static void bvh_free(BVHTree *obj) if(obj->builder) rtbuild_free(obj->builder); - if(obj->alloc) - MEM_freeN(obj->alloc); + if(obj->node_alloc) + MEM_freeN(obj->node_alloc); if(obj->bb_alloc) MEM_freeN(obj->bb_alloc); @@ -185,10 +190,10 @@ static void bvh_add(BVHTree *obj, RayObject *ob) static BVHNode *bvh_new_node(BVHTree *tree, int nid) { - BVHNode *node = tree->alloc + nid - 1; + BVHNode *node = tree->node_alloc + nid - 1; assert(RayObject_isAligned(node)); - if(node+1 > tree->next_node) - tree->next_node = node+1; + if(node+1 > tree->node_next) + tree->node_next = node+1; node->bb = tree->bb_next; tree->bb_next += 6; @@ -255,28 +260,32 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) return parent; } } + +static void bvh_info(BVHTree *obj) +{ + printf("BVH: Used %d nodes\n", obj->node_next - obj->node_alloc); +} static void bvh_done(BVHTree *obj) { int needed_nodes; - assert(obj->root == NULL && obj->next_node == NULL && obj->builder); + assert(obj->root == NULL && obj->node_alloc == NULL && obj->bb_alloc == NULL && obj->builder); + //TODO exact calculate needed nodes needed_nodes = (rtbuild_size(obj->builder)+1)*2; assert(needed_nodes > 0); - obj->alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); - obj->next_node = obj->alloc; + + obj->node_alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); + obj->node_next = obj->node_alloc; obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, "BVHTree.NodesBB"); obj->bb_next = obj->bb_alloc; obj->root = bvh_rearrange( obj, obj->builder, 1 ); - assert(obj->alloc+needed_nodes >= obj->next_node); - -// printf("BVH: Used %d nodes\n", obj->next_node-obj->alloc); - - rtbuild_free( obj->builder ); obj->builder = NULL; + + assert(obj->node_alloc+needed_nodes >= obj->node_next); } -- cgit v1.2.3 From abc44f720ac3d463fcdf051ffd680373c4a43b2a Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 5 Jul 2009 18:46:23 +0000 Subject: Set BVH (rayobject_bvh.c) as default tree type --- source/blender/render/extern/include/RE_raytrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index f2fb8c5277a..b3c128c3019 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -50,7 +50,7 @@ void RE_rayobject_free(RayObject *r); RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); -#define RE_rayobject_tree_create RE_rayobject_blibvh_create +#define RE_rayobject_tree_create RE_rayobject_bvh_create RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_bvh_create(int size); /* rayobject_bvh.c */ RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ -- cgit v1.2.3 From ba1f3323bf21929d74504f3e9ada296d7df85290 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 6 Jul 2009 13:27:40 +0000 Subject: *Added output of BB/primitves test/hits *"Added" SCE_PASS_RAYHITS to visually see each pixel primitive and BB tests (not-completed for UI) *Added runtime exchange of tree structure *Removed FLOAT_EPSILON from BLI_bvhkdop BB's --- release/ui/buttons_scene.py | 1 + source/blender/makesdna/DNA_scene_types.h | 10 +++- source/blender/makesrna/intern/rna_scene.c | 12 ++++ source/blender/render/extern/include/RE_raytrace.h | 67 +++++++++++----------- .../blender/render/extern/include/RE_shader_ext.h | 6 ++ source/blender/render/intern/source/pipeline.c | 13 ++++- source/blender/render/intern/source/rayobject.c | 58 ++++++++++++++----- .../render/intern/source/rayobject_blibvh.c | 2 +- source/blender/render/intern/source/rayshade.c | 50 ++++++++++++++-- source/blender/render/intern/source/rendercore.c | 10 ++++ source/blender/render/intern/source/shadeinput.c | 11 ++++ 11 files changed, 186 insertions(+), 54 deletions(-) diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index 25ff12de306..c5ce455669f 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -26,6 +26,7 @@ class RENDER_PT_shading(RenderButtonsPanel): colsub = col.column() colsub.active = rd.render_raytracing colsub.itemR(rd, "raytrace_structure", text="Structure") + colsub.itemR(rd, "raytrace_tree_type", text="Tree Type") colsub.itemR(rd, "octree_resolution", text="Octree") col.itemR(rd, "dither_intensity", text="Dither", slider=True) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 1199bd1e2b1..bcbccecbb55 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -161,6 +161,8 @@ typedef struct SceneRenderLayer { #define SCE_PASS_RADIO 8192 /* Radio removed, can use for new GI? */ #define SCE_PASS_MIST 16384 +#define SCE_PASS_RAYHITS 32768 + /* note, srl->passflag is treestore element 'nr' in outliner, short still... */ @@ -233,7 +235,8 @@ typedef struct RenderData { /* render engine, octree resolution */ short renderer, ocres; short raystructure; - short pad4[3]; + short raytrace_tree_type; + short pad4[2]; /** * What to do with the sky/background. Picks sky/premul/key @@ -675,6 +678,11 @@ typedef struct Scene { #define R_RAYSTRUCTURE_SINGLE_OCTREE 2 #define R_RAYSTRUCTURE_SINGLE_BVH 3 +/* raytrace tree type */ +#define R_RAYTRACE_TREE_BVH 0 +#define R_RAYTRACE_TREE_BLIBVH 1 +#define R_RAYTRACE_TREE_BIH 2 + /* scemode (int now) */ #define R_DOSEQ 0x0001 #define R_BG_RENDER 0x0002 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 59d036a84dc..dfee6a9eb83 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -293,6 +293,12 @@ void rna_def_scene_render_data(BlenderRNA *brna) {R_RAYSTRUCTURE_SINGLE_BVH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "Single BVH", "BVH of all primitives (no instance support)"}, {R_RAYSTRUCTURE_SINGLE_OCTREE, "{R_RAYSTRUCTURE_SINGLE_OCTREE", 0, "Octree", "Octree of all primitives (no instance support)"}, {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem raytrace_tree_type_items[] = { + {R_RAYTRACE_TREE_BVH, "{R_RAYTRACE_TREE_BVH", 0, "BVH", "rayobject_bvh.c"}, + {R_RAYTRACE_TREE_BLIBVH, "{R_RAYTRACE_TREE_BLIBVH", 0, "BLIbvh", "rayobject_blibvh.c"}, + {R_RAYTRACE_TREE_BIH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "BIH", "rayobject_bih.c"}, + {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem fixed_oversample_items[] = { {5, "OVERSAMPLE_5", 0, "5", ""}, @@ -694,6 +700,12 @@ void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_items(prop, raytrace_structure_items); RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "raytrace_tree_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "raytrace_tree_type"); + RNA_def_property_enum_items(prop, raytrace_tree_type_items); + RNA_def_property_ui_text(prop, "Raytrace tree type", "Type of raytrace accelerator structure."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index b3c128c3019..fdd49cf1216 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -31,12 +31,43 @@ #ifndef RE_RAYTRACE_H #define RE_RAYTRACE_H -#define RE_RAY_COUNTER +#define RE_RAYCOUNTER +#ifdef RE_RAYCOUNTER + +typedef struct RayCounter RayCounter; +struct RayCounter +{ + + struct + { + unsigned long long test, hit; + + } faces, bb, raycast; + + unsigned long long rayshadow_last_hit_optimization; +}; + +/* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ +#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).raycounter) +void RE_RC_INFO (RayCounter *rc); +void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); +#define RE_RC_COUNT(var) (var)++ + +extern RayCounter re_rc_counter[]; + +#else + +#define RE_RC_INIT(isec,shi) +#define RE_RC_INFO(rc) +#define RE_RC_MERGE(dest,src) +#define RE_RC_COUNT(var) + +#endif + /* Internals about raycasting structures can be found on intern/raytree.h */ typedef struct RayObject RayObject; typedef struct Isect Isect; -typedef struct RayCounter RayCounter; struct DerivedMesh; struct Mesh; @@ -50,7 +81,6 @@ void RE_rayobject_free(RayObject *r); RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); -#define RE_rayobject_tree_create RE_rayobject_bvh_create RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_bvh_create(int size); /* rayobject_bvh.c */ RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ @@ -93,39 +123,12 @@ struct Isect void *userdata; -#ifdef RE_RAY_COUNTER - RayCounter *count; +#ifdef RE_RAYCOUNTER + RayCounter *raycounter; #endif }; -#ifdef RE_RAYCOUNTER - -struct RayCounter -{ - - struct - { - unsigned long long test, hit; - - } intersect_rayface, raycast; - - unsigned long long rayshadow_last_hit_optimization; -}; - -void RE_RC_INIT (RayCounter *rc); -void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); -#define RE_RC_COUNT(var) (var)++ - -#else - -#define RE_RC_INIT(rc) -#define RE_RC_MERGE(dest,src) -#define RE_RC_COUNT(var) - -#endif - - /* ray types */ #define RE_RAY_SHADOW 0 #define RE_RAY_MIRROR 1 diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 0ad48fe97a9..980ff59b86a 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -30,6 +30,7 @@ #ifndef RE_SHADER_EXT_H #define RE_SHADER_EXT_H +#include "RE_raytrace.h" /* For RE_RAYCOUNTER */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* this include is for shading and texture exports */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -57,6 +58,7 @@ typedef struct ShadeResult float nor[3]; float rad[3]; float winspeed[4]; + float rayhits[4]; } ShadeResult; /* only here for quick copy */ @@ -178,6 +180,10 @@ typedef struct ShadeInput struct Group *light_override; struct Material *mat_override; +#ifdef RE_RAYCOUNTER + RayCounter raycounter; +#endif + } ShadeInput; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index ec2660566f5..65ef85a04ca 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -347,6 +347,13 @@ static char *get_pass_name(int passtype, int channel) 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"; + return "Rayhits.B"; + } return "Unknown"; } @@ -398,6 +405,8 @@ static int passtype_from_name(char *str) if(strcmp(str, "Mist")==0) return SCE_PASS_MIST; + if(strcmp(str, "RAYHITS")==0) + return SCE_PASS_RAYHITS; return 0; } @@ -523,7 +532,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int rl->lay= srl->lay; rl->lay_zmask= srl->lay_zmask; rl->layflag= srl->layflag; - rl->passflag= srl->passflag; + rl->passflag= srl->passflag | SCE_PASS_RAYHITS; rl->pass_xor= srl->pass_xor; rl->light_override= srl->light_override; rl->mat_override= srl->mat_override; @@ -565,6 +574,8 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); if(srl->passflag & SCE_PASS_MIST) render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); + if(rl->passflag & SCE_PASS_RAYHITS) + render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); } /* sss, previewrender and envmap don't do layers, so we make a default one */ diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index ffe1bba52c9..e9cf46d0734 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -54,10 +54,14 @@ float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb) float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; + RE_RC_COUNT(isec->raycounter->bb.test); + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return FLT_MAX; if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return FLT_MAX; if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return FLT_MAX; + RE_RC_COUNT(isec->raycounter->bb.hit); + dist = t1x; if (t1y > dist) dist = t1y; if (t1z > dist) dist = t1z; @@ -157,7 +161,7 @@ static int intersect_rayface(RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; - RE_RC_COUNT(is->count->intersect_rayface.test); + RE_RC_COUNT(is->raycounter->faces.test); VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); @@ -276,7 +280,7 @@ static int intersect_rayface(RayFace *face, Isect *is) } #endif - RE_RC_COUNT(is->count->intersect_rayface.hit); + RE_RC_COUNT(is->raycounter->faces.hit); is->isect= ok; // wich half of the quad is->labda= labda; @@ -294,7 +298,7 @@ static int intersect_rayface(RayFace *face, Isect *is) int RE_rayobject_raycast(RayObject *r, Isect *isec) { int i; - RE_RC_COUNT(isec->count->raycast.test); + RE_RC_COUNT(isec->raycounter->raycast.test); /* Setup vars used on raycast */ isec->labda *= Normalize(isec->vec); @@ -315,15 +319,15 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) /* Last hit heuristic */ if(isec->mode==RE_RAY_SHADOW && isec->last_hit && RE_rayobject_intersect(isec->last_hit, isec)) { - RE_RC_COUNT(isec->count->raycast.hit); - RE_RC_COUNT(isec->count->rayshadow_last_hit_optimization ); + RE_RC_COUNT(isec->raycounter->raycast.hit); + RE_RC_COUNT(isec->raycounter->rayshadow_last_hit_optimization ); return 1; } #ifdef RE_RAYCOUNTER if(RE_rayobject_intersect(r, isec)) { - RE_RC_COUNT(isec->count->raycast.hit); + RE_RC_COUNT(isec->raycounter->raycast.hit); return 1; } return 0; @@ -383,16 +387,40 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) } #ifdef RE_RAYCOUNTER -void RE_merge_raycounter(RayCounter *dest, RayCounter *tmp) +void RE_RC_INFO(RayCounter *info) { - int i; - for(i=0; i<3; i++) dest->casted[i] += tmp->casted[i]; - for(i=0; i<3; i++) dest->hit [i] += tmp->hit [i]; - - dest->test_primitives += tmp->test_primitives; - dest->hit_primitives += tmp->hit_primitives; + printf("----------- Raycast counter --------\n"); + printf("Rays total: %llu\n", info->raycast.test ); + printf("Rays hit: %llu\n", info->raycast.hit ); + printf("\n"); + printf("BB tests: %llu\n", info->bb.test ); + printf("BB hits: %llu\n", info->bb.hit ); + printf("\n"); + printf("Primitives tests: %llu\n", info->faces.test ); + printf("Primitives hits: %llu\n", info->faces.hit ); + printf("\n"); + printf("Shadow Last hit reuse: %llu\n", info->rayshadow_last_hit_optimization); + printf("\n"); + printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); + printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); + printf("\n"); + printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) ); + printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) ); + printf("\n"); +} + +void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) +{ + dest->faces.test += tmp->faces.test; + dest->faces.hit += tmp->faces.hit; + + dest->bb.test += tmp->bb.test; + dest->bb.hit += tmp->bb.hit; + + dest->raycast.test += tmp->raycast.test; + dest->raycast.hit += tmp->raycast.hit; - dest->test_bb += tmp->test_bb; - dest->hit_bb += tmp->hit_bb; + dest->rayshadow_last_hit_optimization += tmp->rayshadow_last_hit_optimization; } + #endif \ No newline at end of file diff --git a/source/blender/render/intern/source/rayobject_blibvh.c b/source/blender/render/intern/source/rayobject_blibvh.c index 41da4679b6a..ab8d7f1236e 100644 --- a/source/blender/render/intern/source/rayobject_blibvh.c +++ b/source/blender/render/intern/source/rayobject_blibvh.c @@ -66,7 +66,7 @@ RayObject *RE_rayobject_blibvh_create(int size) assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; - obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 4, 6); + obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6); INIT_MINMAX(obj->bb[0], obj->bb[1]); return RayObject_unalignRayAPI((RayObject*) obj); diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 4c16ac05ec2..09bf0842734 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -70,6 +70,22 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +RayObject *RE_rayobject_tree_create(int type, int size) +{ + if(type == R_RAYTRACE_TREE_BVH) + return RE_rayobject_bvh_create(size); + if(type == R_RAYTRACE_TREE_BIH) + return RE_rayobject_bih_create(size); + if(type == R_RAYTRACE_TREE_BLIBVH) + return RE_rayobject_blibvh_create(size); + + return RE_rayobject_bvh_create(size); +} + +#ifdef RE_RAYCOUNTER +RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {}; +#endif + #if 0 static int vlr_check_intersect(Isect *is, int ob, RayFace *face) { @@ -123,6 +139,16 @@ void freeraytree(Render *re) obi->raytree = NULL; } } + +#ifdef RE_RAYCOUNTER + { + RayCounter sum = {}; + int i; + for(i=0; ir.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH) - raytree = obr->raytree = RE_rayobject_tree_create( faces ); + raytree = obr->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces ); face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); obr->rayobi = obi; @@ -240,7 +266,7 @@ static void makeraytree_hier(Render *re) num_objects++; //Create raytree - re->raytree = RE_rayobject_tree_create( num_objects ); + re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, num_objects ); for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) @@ -292,7 +318,7 @@ static void makeraytree_single(Render *re) if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) - raytree = re->raytree = RE_rayobject_tree_create( faces ); + raytree = re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces ); face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); @@ -322,6 +348,17 @@ static void makeraytree_single(Render *re) void makeraytree(Render *re) { +#ifdef RE_RAYCOUNTER + if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) + printf("Building single octree\n"); + else if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) + printf("Building single tree\n"); + else if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) + printf("Building tree of octrees\n"); + else + printf("Building tree of trees\n"); +#endif + if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE)) BENCH(makeraytree_single(re), tree_build); else @@ -563,6 +600,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo isec.orig.ob = obi; isec.orig.face = vlr; + RE_RC_INIT(isec, shi); if(RE_rayobject_raycast(R.raytree, &isec)) { float d= 1.0f; @@ -1306,7 +1344,6 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) do_tra= ((shi->mat->mode & (MA_RAYTRANSP)) && shr->alpha!=1.0f); do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0f); - /* raytrace mirror amd refract like to separate the spec color */ if(shi->combinedflag & SCE_PASS_SPEC) @@ -1465,6 +1502,7 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) isec.mode= RE_RAY_MIRROR; isec.orig.ob = ship->obi; isec.orig.face = ship->vlr; + RE_RC_INIT(isec, shi); for(a=0; a<8*8; a++) { @@ -1669,6 +1707,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) float dxyview[3], skyadded=0, div; int aocolor; + RE_RC_INIT(isec, *shi); isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; @@ -1802,6 +1841,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) float dxyview[3]; int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp; + RE_RC_INIT(isec, *shi); isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; @@ -2238,6 +2278,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) int lampvec; /* indicates if lampco is a vector lamp */ /* setup isec */ + RE_RC_INIT(isec, *shi); if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; else isec.mode= RE_RAY_SHADOW; @@ -2323,6 +2364,7 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float assert(0); /* setup isec */ + RE_RC_INIT(isec, *shi); isec.mode= RE_RAY_SHADOW_TRA; if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 89eb5e28598..507e1460d4c 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -521,6 +521,12 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, } } break; + + case SCE_PASS_RAYHITS: + /* */ + col= &shr->rayhits; + pixsize= 4; + break; } if(col) { fp= rpass->rect + pixsize*offset; @@ -597,6 +603,10 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult fp= rpass->rect + offset; *fp= shr->mist; break; + case SCE_PASS_RAYHITS: + col= shr->rayhits; + pixsize= 4; + break; } if(col) { fp= rpass->rect + pixsize*offset; diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 1cd8ec110f9..08c3ba07372 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -142,6 +142,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) float alpha; /* ------ main shading loop -------- */ + memset(&shi->raycounter, 0, sizeof(shi->raycounter)); if(shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); @@ -188,6 +189,16 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) /* add z */ shr->z= -shi->co[2]; + + /* RAYHITS */ + if(1 || shi->passflag & SCE_PASS_RAYHITS) + { + shr->rayhits[0] = (float)shi->raycounter.faces.test; + shr->rayhits[1] = (float)shi->raycounter.bb.hit; + shr->rayhits[2] = 0.0; + shr->rayhits[3] = 1.0; + RE_RC_MERGE(&re_rc_counter[shi->thread], &shi->raycounter); + } } /* **************************************************************************** */ -- cgit v1.2.3 From e0e66f6b74d988d8af59f8ee9235dc251577efc3 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 6 Jul 2009 14:36:26 +0000 Subject: *"Fixed" rayobject_bvh memory organization of BB's until now rayobject_bvh should be at least as fast as BLIBVH, this seemed to be the missing piece --- source/blender/render/intern/source/rayobject_bvh.c | 2 +- source/blender/render/intern/source/rayshade.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index d9d3832830a..9a6292d33e5 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -195,7 +195,7 @@ static BVHNode *bvh_new_node(BVHTree *tree, int nid) if(node+1 > tree->node_next) tree->node_next = node+1; - node->bb = tree->bb_next; + node->bb = tree->bb_alloc + nid - 1; tree->bb_next += 6; return node; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 09bf0842734..b70e4bf5000 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -348,15 +348,24 @@ static void makeraytree_single(Render *re) void makeraytree(Render *re) { + const char *tree_type = "Tree(unknown)"; + #ifdef RE_RAYCOUNTER + if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BVH) + tree_type = "BVH"; + if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BIH) + tree_type = "BIH"; + if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BLIBVH) + tree_type = "BLIBVH"; + if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) printf("Building single octree\n"); else if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) - printf("Building single tree\n"); + printf("Building single tree(%s)\n", tree_type); else if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) - printf("Building tree of octrees\n"); + printf("Building tree(%s) of octrees\n", tree_type); else - printf("Building tree of trees\n"); + printf("Building tree(%s) of trees(%s)\n", tree_type, tree_type); #endif if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE)) -- cgit v1.2.3 From aa12d2153fbc80d0bd4fb3e9cc1278e15bce6376 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 6 Jul 2009 15:35:46 +0000 Subject: *fix (forgot to multiply by BB size) --- source/blender/render/intern/source/rayobject_bvh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 9a6292d33e5..1798af6465f 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -195,7 +195,7 @@ static BVHNode *bvh_new_node(BVHTree *tree, int nid) if(node+1 > tree->node_next) tree->node_next = node+1; - node->bb = tree->bb_alloc + nid - 1; + node->bb = tree->bb_alloc + (nid - 1)*6; tree->bb_next += 6; return node; -- cgit v1.2.3 From c65a3e3166397928f8b276db7dd4d5445671574e Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 6 Jul 2009 19:45:00 +0000 Subject: *Added BLI_memarena on bvh *Median split support on rtbuild --- .../render/intern/include/rayobject_rtbuild.h | 6 +- .../blender/render/intern/source/rayobject_bvh.c | 65 ++++++++- .../render/intern/source/rayobject_rtbuild.c | 155 ++++++++++++++++++++- 3 files changed, 215 insertions(+), 11 deletions(-) diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index af0a11508e8..ed0b03ec03e 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -65,8 +65,12 @@ int rtbuild_size(RTBuilder *b); RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); /* Calculates child partitions and returns number of efectively needed partitions */ +int rtbuild_get_largest_axis(RTBuilder *b); + int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); -int rtbuild_get_largest_axis(RTBuilder *b); + +int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis); +int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); #endif diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 1798af6465f..15c0d70b248 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -32,10 +32,16 @@ #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" #include "BLI_arithb.h" +#include "BLI_memarena.h" #include "RE_raytrace.h" #include "rayobject_rtbuild.h" #include "rayobject.h" +#define DYNAMIC_ALLOC + +#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */ +//#define SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS /* space median split on the longest axis, childs BB are allowed to overlap */ + #define BVH_NCHILDS 4 typedef struct BVHTree BVHTree; @@ -58,7 +64,11 @@ typedef struct BVHNode BVHNode; struct BVHNode { BVHNode *child[BVH_NCHILDS]; +#ifdef DYNAMIC_ALLOC + float bb[6]; +#else float *bb; //[6]; //[2][3]; +#endif int split_axis; }; @@ -68,8 +78,12 @@ struct BVHTree BVHNode *root; +#ifdef DYNAMIC_ALLOC + MemArena *node_arena; +#else BVHNode *node_alloc, *node_next; float *bb_alloc, *bb_next; +#endif RTBuilder *builder; }; @@ -83,8 +97,12 @@ RayObject *RE_rayobject_bvh_create(int size) obj->rayobj.api = &bvh_api; obj->root = NULL; +#ifdef DYNAMIC_ALLOC + obj->node_arena = NULL; +#else obj->node_alloc = obj->node_next = NULL; obj->bb_alloc = obj->bb_next = NULL; +#endif obj->builder = rtbuild_create( size ); return RayObject_unalignRayAPI((RayObject*) obj); @@ -95,11 +113,16 @@ static void bvh_free(BVHTree *obj) if(obj->builder) rtbuild_free(obj->builder); +#ifdef DYNAMIC_ALLOC + if(obj->node_arena) + BLI_memarena_free(obj->node_arena); +#else if(obj->node_alloc) MEM_freeN(obj->node_alloc); if(obj->bb_alloc) MEM_freeN(obj->bb_alloc); +#endif MEM_freeN(obj); } @@ -190,6 +213,10 @@ static void bvh_add(BVHTree *obj, RayObject *ob) static BVHNode *bvh_new_node(BVHTree *tree, int nid) { +#ifdef DYNAMIC_ALLOC + BVHNode *node = BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + return node; +#else BVHNode *node = tree->node_alloc + nid - 1; assert(RayObject_isAligned(node)); if(node+1 > tree->node_next) @@ -199,6 +226,7 @@ static BVHNode *bvh_new_node(BVHTree *tree, int nid) tree->bb_next += 6; return node; +#endif } static int child_id(int pid, int nchild) @@ -209,6 +237,9 @@ static int child_id(int pid, int nchild) static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) { + if(rtbuild_size(builder) == 0) + return 0; + if(rtbuild_size(builder) == 1) { RayObject *child = builder->begin[0]; @@ -242,10 +273,17 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) else { int i; - int nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); RTBuilder tmp; - BVHNode *parent = bvh_new_node(tree, nid); + int nc; + +#ifdef SPLIT_OVERLAP_MEAN_LONGEST_AXIS + nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); +#elif defined(SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS) + nc = rtbuild_median_split_largest_axis(builder, BVH_NCHILDS); +#else + assert(0); +#endif INIT_MINMAX(parent->bb, parent->bb+3); parent->split_axis = builder->split_axis; @@ -261,31 +299,48 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) } } +/* static void bvh_info(BVHTree *obj) { printf("BVH: Used %d nodes\n", obj->node_next - obj->node_alloc); } +*/ static void bvh_done(BVHTree *obj) { + + +#ifdef DYNAMIC_ALLOC + int needed_nodes = (rtbuild_size(obj->builder)+1)*2; + if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) + needed_nodes = BLI_MEMARENA_STD_BUFSIZE; + + obj->node_arena = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(obj->node_arena); + +#else int needed_nodes; - assert(obj->root == NULL && obj->node_alloc == NULL && obj->bb_alloc == NULL && obj->builder); //TODO exact calculate needed nodes needed_nodes = (rtbuild_size(obj->builder)+1)*2; assert(needed_nodes > 0); + BVHNode *node = BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + return node; obj->node_alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); obj->node_next = obj->node_alloc; obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, "BVHTree.NodesBB"); obj->bb_next = obj->bb_alloc; +#endif obj->root = bvh_rearrange( obj, obj->builder, 1 ); + +#ifndef DYNAMIC_ALLOC + assert(obj->node_alloc+needed_nodes >= obj->node_next); +#endif rtbuild_free( obj->builder ); obj->builder = NULL; - - assert(obj->node_alloc+needed_nodes >= obj->node_next); } diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 7be17312a52..0c378dc5948 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -1,5 +1,6 @@ #include #include +#include #include "rayobject_rtbuild.h" #include "MEM_guardedalloc.h" @@ -8,6 +9,7 @@ static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); +static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane); static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) @@ -61,12 +63,9 @@ static void merge_bb(RTBuilder *b, float *min, float *max) RE_rayobject_merge_bb(*index, min, max); } -int rtbuild_get_largest_axis(RTBuilder *b) +static int largest_axis(float *min, float *max) { - float min[3], max[3], sub[3]; - - INIT_MINMAX(min, max); - merge_bb( b, min, max); + float sub[3]; sub[0] = max[0]-min[0]; sub[1] = max[1]-min[1]; @@ -87,7 +86,22 @@ int rtbuild_get_largest_axis(RTBuilder *b) } } +int rtbuild_get_largest_axis(RTBuilder *b) +{ + float min[3], max[3]; + + INIT_MINMAX(min, max); + merge_bb( b, min, max); + return largest_axis(min,max); +} + + +/* +int rtbuild_median_split(RTBuilder *b, int nchilds, int axis) +{ +} +*/ //Left balanced tree int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) { @@ -146,6 +160,123 @@ int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) return rtbuild_mean_split(b, nchilds, axis); } +/* + * "separators" is an array of dim NCHILDS-1 + * and indicates where to cut the childs + */ +int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis) +{ + int size = rtbuild_size(b); + + assert(nchilds <= RTBUILD_MAX_CHILDS); + if(size <= nchilds) + { + return rtbuild_mean_split(b, nchilds, axis); + } + else + { + int i; + + b->split_axis = axis; + + //Calculate child offsets + b->child_offset[0] = 0; + for(i=0; ichild_offset[i+1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]); + b->child_offset[nchilds] = size; + + for(i=0; ichild_offset[i+1] - b->child_offset[i] == size) + return rtbuild_mean_split(b, nchilds, axis); + + return nchilds; + } +} + +int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) +{ + int la, i; + float separators[RTBUILD_MAX_CHILDS]; + float min[3], max[3]; + + INIT_MINMAX(min, max); + merge_bb( b, min, max); + + la = largest_axis(min,max); + for(i=1; ikey < b->key) return -1; + if(a->key > b->key) return 1; + if(a->value < b->value) return -1; + if(a->value > b->value) return 1; + return 0; +} + +void costevent_sort(CostEvent *begin, CostEvent *end) +{ + //TODO introsort + qsort(begin, sizeof(*begin), end-begin, (int(*)(const void *, const void *)) costevent_cmp); +} + +/* +int rtbuild_heuristic_split(RTBuilder *b, int nchilds) +{ + int size = rtbuild_size(b); + + if(size <= nchilds) + { + return rtbuild_mean_split_largest_axis(b, nchilds); + } + else + { + CostEvent *events[3], *ev[3]; + RayObject *index; + int a = 0; + + for(a = 0; a<3; a++) + ev[a] = events[a] = MEM_malloc( sizeof(CostEvent)*2*size, "RTBuilder.SweepSplitCostEvent" ); + + for(index = b->begin; b != b->end; b++) + { + float min[3], max[3]; + INIT_MINMAX(min, max); + RE_rayobject_merge_bb(index, min, max); + for(a = 0; a<3; a++) + { + ev[a]->key = min[a]; + ev[a]->value = 1; + ev[a]++; + + ev[a]->key = max[a]; + ev[a]->value = -1; + ev[a]++; + } + } + for(a = 0; a<3; a++) + costevent_sort(events[a], ev[a]); + + + + for(a = 0; a<3; a++) + MEM_freeN(ev[a]); + } +} +*/ /* * Helper code @@ -268,3 +399,17 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) partition_nth_element(b, nth[i], nth[i+1], nth[partitions] ); } } + +static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane) +{ + int i; + for(i = begin; i != end; i++) + { + if(sort_get_value(b, i) < plane) + { + sort_swap(b, i, begin); + begin++; + } + } + return begin; +} -- cgit v1.2.3 From ad0b2c87d5c86b56f073c81f25df5c3988911d14 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 7 Jul 2009 08:38:18 +0000 Subject: Integrated unit testing framework with scons on Linux. I needed this to make sure that BKE_copy_images works properly, probably will be useful in future. Using Check framework (http://check.sourceforge.net/doc/check.html/index.html). WITH_BF_UNIT_TEST option builds 'alltest' program under [BUILDDIR]/bin, which, when executed, runs unit tests, currently only 1. Example output: ---------------------------------------------------------------------- Running suite(s): Image 0%: Checks: 1, Failures: 1, Errors: 0 tests/alltest.c:74:F:Core:test_copy_images:0: Expected //bar/image.png to be translated to /tmp/bar/image.png, got /tmp/bar/image.pn. ---------------------------------------------------------------------- Spent lots of time (a couple of days actually :) to figure out how to link the test program with Blender libraries. As it turned out there are circular dependencies among Blender libraries. GCC by default doesn't expect circular dependencies - dependant libs should precede libs they depend on. The magical --start-group linker option helped to solve this (http://stephane.carrez.free.fr/doc/ld_2.html#IDX122). Also: - added bpy.util module. bpy.sys.* functions will move here later - added bpy.util.copy_images that uses BKE_copy_images - export_obj.py uses bpy.util.copy_images --- SConstruct | 11 ++- release/io/export_obj.py | 23 +++-- source/blender/blenkernel/BKE_image.h | 6 ++ source/blender/blenkernel/SConscript | 3 + source/blender/blenkernel/intern/image.c | 117 +++++++++++++++++++++++ source/blender/python/intern/bpy_interface.c | 3 + source/blender/python/intern/bpy_util.c | 133 ++++++++++++++++++++++++++- source/blender/python/intern/bpy_util.h | 2 + tools/btools.py | 6 +- 9 files changed, 290 insertions(+), 14 deletions(-) diff --git a/SConstruct b/SConstruct index b85bc799ea5..2d1daba98b6 100644 --- a/SConstruct +++ b/SConstruct @@ -407,7 +407,16 @@ if env['WITH_BF_PLAYER']: if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: #env.BlenderProg(B.root_build_dir, "blender", dobj , [], mainlist + thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') - env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') + blen = env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') + + build_data = {"lib": thestatlibs + thesyslibs, "libpath": thelibincs, "blen": blen} + + Export('env') + Export('build_data') + + BuildDir(B.root_build_dir+'/tests', 'tests', duplicate=0) + SConscript(B.root_build_dir+'/tests/SConscript') + if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 1ee685a52a3..ee045053dd3 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -178,19 +178,22 @@ def copy_images(dest_dir): pass # Now copy images - copyCount = 0 +# copyCount = 0 - for bImage in uniqueImages.values(): - image_path = bpy.sys.expandpath(bImage.filename) - if bpy.sys.exists(image_path): - # Make a name for the target path. - dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] - if not bpy.sys.exists(dest_image_path): # Image isnt alredy there - print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) - copy_file(image_path, dest_image_path) - copyCount+=1 +# for bImage in uniqueImages.values(): +# image_path = bpy.sys.expandpath(bImage.filename) +# if bpy.sys.exists(image_path): +# # Make a name for the target path. +# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] +# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there +# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) +# copy_file(image_path, dest_image_path) +# copyCount+=1 + + paths= bpy.util.copy_images(uniqueImages.values(), dest_dir) print('\tCopied %d images' % copyCount) +# print('\tCopied %d images' % copyCount) # XXX not converted def test_nurbs_compat(ob): diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 816baa20467..f3f5266189a 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -40,6 +40,7 @@ struct ImBuf; struct Tex; struct anim; struct Scene; +struct ListBase; /* call from library */ void free_image(struct Image *me); @@ -154,6 +155,11 @@ struct Image *BKE_image_copy(struct Image *ima); /* merge source into dest, and free source */ void BKE_image_merge(struct Image *dest, struct Image *source); +/* ********************************** FOR EXPORTERS *********************** */ + +/* copy images into dest_dir */ +void BKE_copy_images(struct ListBase *images, char *dest_dir, struct ListBase *filenames); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index dbc990d0613..9aaea7e8aff 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -57,6 +57,9 @@ if env['BF_NO_ELBEEM']: if env['WITH_BF_LCMS']: defs.append('WITH_LCMS') + +if env['WITH_BF_UNIT_TEST']: + defs.append('WITH_UNIT_TEST') if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ef0984bf93d..039c2d07bce 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2109,3 +2109,120 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr) } } +/* + Copy list of images to dest_dir. + + paths is optional, if given, image paths for each image will be written in it. + If an image file doesn't exist, NULL is added in paths. + + Logic: + + For each image if it's "below" current .blend file directory, + rebuild the same dir structure in dest_dir. + + For example //textures/foo/bar.png becomes + [dest_dir]/textures/foo/bar.png. + + If an image is not "below" current .blend file directory, disregard + it's path and copy it in the same directory where 3D file goes. + + For example //../foo/bar.png becomes [dest_dir]/bar.png. + + This logic will help ensure that all image paths are relative and + that a user gets his images in one place. It'll also provide + consistent behaviour across exporters. +*/ +void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths) +{ + char path[FILE_MAX]; + char dir[FILE_MAX]; + char base[FILE_MAX]; + char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */ + char dest_path[FILE_MAX]; + int len; + Image *im; + LinkData *link; + + if (paths) { + memset(paths, 0, sizeof(*paths)); + } + + BLI_split_dirfile_basic(G.sce, blend_dir, NULL); + + link= images->first; + + while (link) { + im= link->data; + + BLI_strncpy(path, im->name, sizeof(path)); + + /* expand "//" in filename and get absolute path */ + BLI_convertstringcode(path, G.sce); + + /* in unit tests, we don't want to modify the filesystem */ +#ifndef WITH_UNIT_TEST + /* proceed only if image file exists */ + if (!BLI_exists(path)) { + + if (paths) { + LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData"); + ld->data= NULL; + BLI_addtail(paths, ld); + } + + continue; + } +#endif + + /* get the directory part */ + BLI_split_dirfile_basic(path, dir, base); + + len= strlen(blend_dir); + + /* if image is "below" current .blend file directory */ + if (!strncmp(path, blend_dir, len)) { + + /* if image is _in_ current .blend file directory */ + if (!strcmp(dir, blend_dir)) { + /* copy to dest_dir */ + BLI_join_dirfile(dest_path, dest_dir, base); + } + /* "below" */ + else { + char rel[FILE_MAX]; + + /* rel = image_path_dir - blend_dir */ + BLI_strncpy(rel, dir + len, sizeof(rel)); + + BLI_join_dirfile(dest_path, dest_dir, rel); + +#ifndef WITH_UNIT_TEST + /* build identical directory structure under dest_dir */ + BLI_make_existing_file(dest_path); +#endif + + BLI_join_dirfile(dest_path, dest_path, base); + } + + } + /* image is out of current directory */ + else { + /* copy to dest_dir */ + BLI_join_dirfile(dest_path, dest_dir, base); + } + +#ifndef WITH_UNIT_TEST + BLI_copy_fileops(path, dest_path); +#endif + + if (paths) { + LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData"); + len= strlen(dest_path) + 1; + ld->data= MEM_callocN(len, "PathLinkData"); + BLI_strncpy(ld->data, dest_path, len); + BLI_addtail(paths, ld); + } + + link= link->next; + } +} diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 96ef796839b..c895a41637d 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -92,6 +92,9 @@ void BPY_update_modules( void ) PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject( mod, "data", BPY_rna_module() ); PyModule_AddObject( mod, "types", BPY_rna_types() ); + PyModule_AddObject( mod, "util", BPY_util_module() ); + + /* XXX this will move to bpy.util */ PyModule_AddObject( mod, "sys", BPY_sys_module() ); } diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index bce73b903c0..5f235b91337 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -25,12 +25,17 @@ #include "DNA_listBase.h" #include "RNA_access.h" #include "bpy_util.h" -#include "BLI_dynstr.h" +#include "bpy_rna.h" + #include "MEM_guardedalloc.h" -#include "BKE_report.h" +#include "BLI_dynstr.h" +#include "BLI_listbase.h" +#include "BKE_report.h" +#include "BKE_image.h" #include "BKE_context.h" + bContext* __py_context = NULL; bContext* BPy_GetContext(void) { return __py_context; }; void BPy_SetContext(bContext *C) { __py_context= C; }; @@ -464,3 +469,127 @@ int BPy_errors_to_report(ReportList *reports) Py_DECREF(pystring); return 1; } + + +/* bpy.util module */ +static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args); + +struct PyMethodDef bpy_util_methods[] = { + {"copy_images", bpy_util_copy_images, METH_VARARGS, NULL}, + {NULL, NULL, 0, NULL} +}; + +#if PY_VERSION_HEX >= 0x03000000 +static struct PyModuleDef bpy_util_module = { + PyModuleDef_HEAD_INIT, + "bpyutil", + NULL, + -1, + bpy_util_methods, + NULL, NULL, NULL, NULL +}; +#endif + +PyObject *BPY_util_module( void ) +{ + PyObject *submodule, *dict; + +#if PY_VERSION_HEX >= 0x03000000 + submodule= PyModule_Create(&bpy_util_module); +#else /* Py2.x */ + submodule= Py_InitModule3("bpyutil", bpy_util_methods, NULL); +#endif + + dict = PyModule_GetDict(submodule); + + return submodule; +} + +/* + copy_images(images, dest_dir) + return filenames +*/ +static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args) +{ + const char *dest_dir; + ListBase *images; + ListBase *paths; + LinkData *link; + PyObject *seq; + PyObject *ret; + PyObject *item; + int i; + int len; + + /* check args/types */ + if (!PyArg_ParseTuple(args, "Os", &seq, &dest_dir)) { + PyErr_SetString(PyExc_TypeError, "Invalid arguments."); + return NULL; + } + + /* expecting a sequence of Image objects */ + if (!PySequence_Check(seq)) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of images."); + return NULL; + } + + /* create image list */ + len= PySequence_Size(seq); + + if (!len) { + PyErr_SetString(PyExc_TypeError, "At least one image should be specified."); + return NULL; + } + + /* make sure all sequence items are Image */ + for(i= 0; i < len; i++) { + item= PySequence_GetItem(seq, i); + + if (!BPy_StructRNA_Check(item) || ((BPy_StructRNA*)item)->ptr.type != &RNA_Image) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of Image objects."); + return NULL; + } + } + + images= MEM_callocN(sizeof(*images), "ListBase of images"); + + for(i= 0; i < len; i++) { + BPy_StructRNA* srna; + + item= PySequence_GetItem(seq, i); + srna= (BPy_StructRNA*)item; + + link= MEM_callocN(sizeof(LinkData), "LinkData image"); + link->data= srna->ptr.data; + BLI_addtail(images, link); + + Py_DECREF(item); + } + + paths= MEM_callocN(sizeof(*paths), "ListBase of image paths"); + + /* call BKE_copy_images */ + BKE_copy_images(images, dest_dir, paths); + + /* convert filenames */ + ret= PyList_New(0); + len= BLI_countlist(paths); + + for(link= paths->first, i= 0; link; link++, i++) { + if (link->data) { + item= PyUnicode_FromString(link->data); + PyList_Append(ret, item); + Py_DECREF(item); + } + else { + PyList_Append(ret, Py_None); + } + } + + /* free memory */ + BLI_freelistN(images); + BLI_freelistN(paths); + + /* return filenames */ + return ret; +} diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index 6429af67eb0..89d27ba8325 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -81,4 +81,6 @@ int BPy_errors_to_report(struct ReportList *reports); struct bContext *BPy_GetContext(void); void BPy_SetContext(struct bContext *C); +PyObject *BPY_util_module(void); + #endif diff --git a/tools/btools.py b/tools/btools.py index 9603022deaa..f4d79b1bb24 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -65,6 +65,8 @@ def validate_arguments(args, bc): 'WITH_BF_DOCS', 'BF_NUMJOBS', 'BF_MSVS', + + 'WITH_BF_UNIT_TEST' ] # Have options here that scons expects to be lists @@ -356,7 +358,9 @@ def read_opts(cfg, args): ('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'), ('BF_NUMJOBS', 'Number of build processes to spawn', '1'), - ('BF_MSVS', 'Generate MSVS project files and solution', False) + ('BF_MSVS', 'Generate MSVS project files and solution', False), + + (BoolVariable('WITH_BF_UNIT_TEST', 'Build unit tests', False)) ) # end of opts.AddOptions() -- cgit v1.2.3 From 08fa7862510e755b9112a64754ca4401138d957b Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 7 Jul 2009 15:42:08 +0000 Subject: *added Object SAH support to rtbuild: only for 2childs splits with "worse case heuristic" means each child is considered to have a cost linear on the number of leafs no termination criteria number of BB test/hits expected to "reduced" by some factor tree building is also expected to be slower as previous split was "object mean", which is quite fast to evaluate --- .../render/intern/include/rayobject_rtbuild.h | 5 + .../blender/render/intern/source/rayobject_bvh.c | 7 +- .../render/intern/source/rayobject_rtbuild.c | 142 ++++++++++++++++++++- 3 files changed, 146 insertions(+), 8 deletions(-) diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index ed0b03ec03e..0ead47eefca 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -67,10 +67,15 @@ RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); /* Calculates child partitions and returns number of efectively needed partitions */ int rtbuild_get_largest_axis(RTBuilder *b); +//Object partition int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); +int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds); + +//Space partition int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis); int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); + #endif diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 15c0d70b248..82aa4c57ccb 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -39,10 +39,11 @@ #define DYNAMIC_ALLOC -#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */ +//#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */ //#define SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS /* space median split on the longest axis, childs BB are allowed to overlap */ +#define SPLIT_OBJECTS_SAH /* split objects using heuristic */ -#define BVH_NCHILDS 4 +#define BVH_NCHILDS 2 typedef struct BVHTree BVHTree; static int bvh_intersect(BVHTree *obj, Isect *isec); @@ -281,6 +282,8 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); #elif defined(SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS) nc = rtbuild_median_split_largest_axis(builder, BVH_NCHILDS); +#elif defined(SPLIT_OBJECTS_SAH) + nc = rtbuild_heuristic_object_split(builder, BVH_NCHILDS); #else assert(0); #endif diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 0c378dc5948..5ed03a08f6a 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -209,7 +209,135 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) return rtbuild_median_split(b, separators, nchilds, la); } -//Heuristics Splitter +//Heuristics Object Splitter +typedef struct CostObject CostObject; +struct CostObject +{ + RayObject *obj; + float bb[6]; +}; + +//Ugly.. but using qsort and no globals its the cleaner I can get +#define costobject_cmp(axis) costobject_cmp##axis +#define define_costobject_cmp(axis) \ +int costobject_cmp(axis)(const CostObject *a, const CostObject *b) \ +{ \ + if(a->bb[axis] < b->bb[axis]) return -1; \ + if(a->bb[axis] > b->bb[axis]) return 1; \ + if(a->obj < b->obj) return -1; \ + if(a->obj > b->obj) return 1; \ + return 0; \ +} + +define_costobject_cmp(0) +define_costobject_cmp(1) +define_costobject_cmp(2) +define_costobject_cmp(3) +define_costobject_cmp(4) +define_costobject_cmp(5) + +void costobject_sort(CostObject *begin, CostObject *end, int axis) +{ + //TODO introsort + if(axis == 0) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(0)); + else if(axis == 1) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(1)); + else if(axis == 2) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(2)); + else if(axis == 3) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(3)); + else if(axis == 4) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(4)); + else if(axis == 5) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(5)); +} + +float bb_volume(float *min, float *max) +{ + return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]); +} + +float bb_area(float *min, float *max) +{ + float sub[3]; + sub[0] = max[0]-min[0]; + sub[1] = max[1]-min[1]; + sub[2] = max[2]-min[2]; + + return (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; +} + +int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) +{ + int size = rtbuild_size(b); + assert(nchilds == 2); + + if(size <= nchilds) + { + return rtbuild_mean_split_largest_axis(b, nchilds); + } + else + { + float bcost = FLT_MAX; + int i, axis, baxis, boffset; + CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); + float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); + + for(i=0; ibegin[i]; + INIT_MINMAX(cost[i].bb, cost[i].bb+3); + RE_rayobject_merge_bb(b->begin[i], cost[i].bb, cost[i].bb+3); + } + + for(axis=0; axis<3; axis++) + { + float other_bb[6]; + + costobject_sort(cost, cost+size, axis); + for(i=size-1; i>=0; i--) + { + float *bb = acc_bb+i*6; + if(i == size-1) + { + INIT_MINMAX( bb, bb+3 ); + } + else + { + VECCOPY( bb, bb+6 ); + VECCOPY( bb+3, bb+6+3 ); + } + RE_rayobject_merge_bb( cost[i].obj, bb, bb+3 ); + } + + INIT_MINMAX(other_bb, other_bb+3); + DO_MINMAX( cost[0].bb, other_bb, other_bb+3 ); + DO_MINMAX( cost[0].bb+3, other_bb, other_bb+3 ); + + for(i=1; ibegin[i] = cost[i].obj; + + b->child_offset[0] = 0; + b->child_offset[1] = boffset; + b->child_offset[2] = size; + + MEM_freeN(acc_bb); + MEM_freeN(cost); + return nchilds; + } +} + +//Heuristic Area Splitter typedef struct CostEvent CostEvent; struct CostEvent @@ -232,24 +360,26 @@ void costevent_sort(CostEvent *begin, CostEvent *end) //TODO introsort qsort(begin, sizeof(*begin), end-begin, (int(*)(const void *, const void *)) costevent_cmp); } - /* int rtbuild_heuristic_split(RTBuilder *b, int nchilds) { - int size = rtbuild_size(b); - + int size = rtbuild_size(b); + + assert(nchilds == 2); + if(size <= nchilds) { return rtbuild_mean_split_largest_axis(b, nchilds); } else { - CostEvent *events[3], *ev[3]; + CostEvent *events, *ev; RayObject *index; int a = 0; + events = MEM_malloc( sizeof(CostEvent)*2*size, "RTBuilder.SweepSplitCostEvent" ); for(a = 0; a<3; a++) - ev[a] = events[a] = MEM_malloc( sizeof(CostEvent)*2*size, "RTBuilder.SweepSplitCostEvent" ); + for(index = b->begin; b != b->end; b++) { -- cgit v1.2.3 From 5b75ea38ff034d40a67b331b161d0ce870848ebb Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 7 Jul 2009 19:07:53 +0000 Subject: made rtbuild object_heuristic_spliter faster I think its something like: old was: 4*nlogn + 3*(n*6) new is: (2*nlogn + 3*(n*6)) * f, with f<1 Still missing changing the sorting function to an introsort instead of qsort Other options like bucketing sort may be worth trying (for very large trees) --- source/blender/blenkernel/BKE_utildefines.h | 8 +++ .../render/intern/include/rayobject_rtbuild.h | 2 + .../blender/render/intern/source/rayobject_bih.c | 9 ++- .../render/intern/source/rayobject_blibvh.c | 8 +-- .../blender/render/intern/source/rayobject_bvh.c | 5 +- .../render/intern/source/rayobject_rtbuild.c | 68 ++++++++++++++++------ 6 files changed, 71 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 419f0f5beeb..1c88b94df85 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -80,6 +80,14 @@ #define INIT_MINMAX2(min, max) { (min)[0]= (min)[1]= 1.0e30f; (max)[0]= (max)[1]= -1.0e30f; } +#define DO_MIN(vec, min) { if( (min)[0]>(vec)[0] ) (min)[0]= (vec)[0]; \ + if( (min)[1]>(vec)[1] ) (min)[1]= (vec)[1]; \ + if( (min)[2]>(vec)[2] ) (min)[2]= (vec)[2]; } \ + +#define DO_MAX(vec, max) { if( (max)[0]<(vec)[0] ) (max)[0]= (vec)[0]; \ + if( (max)[1]<(vec)[1] ) (max)[1]= (vec)[1]; \ + if( (max)[2]<(vec)[2] ) (max)[2]= (vec)[2]; } \ + #define DO_MINMAX(vec, min, max) { if( (min)[0]>(vec)[0] ) (min)[0]= (vec)[0]; \ if( (min)[1]>(vec)[1] ) (min)[1]= (vec)[1]; \ if( (min)[2]>(vec)[2] ) (min)[2]= (vec)[2]; \ diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index 0ead47eefca..f27005a2fa7 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -52,6 +52,8 @@ typedef struct RTBuilder /* child partitions calculated during splitting */ int child_offset[RTBUILD_MAX_CHILDS+1]; + + int child_sorted_axis; /* -1 if not sorted */ } RTBuilder; diff --git a/source/blender/render/intern/source/rayobject_bih.c b/source/blender/render/intern/source/rayobject_bih.c index fb755e2c7e6..e2cb9bad302 100644 --- a/source/blender/render/intern/source/rayobject_bih.c +++ b/source/blender/render/intern/source/rayobject_bih.c @@ -102,9 +102,8 @@ static void bih_free(BIHTree *obj) static void bih_bb(BIHTree *obj, float *min, float *max) { - //TODO only half operations needed - DO_MINMAX(obj->bb[0], min, max); - DO_MINMAX(obj->bb[1], min, max); + DO_MIN(obj->bb[0], min); + DO_MAX(obj->bb[1], max); } /* @@ -213,8 +212,8 @@ static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float parent->bi[i][0] = cbb[parent->split_axis]; parent->bi[i][1] = cbb[parent->split_axis+3]; - DO_MINMAX(cbb , bb, bb+3); - DO_MINMAX(cbb+3, bb, bb+3); + DO_MIN(cbb , bb); + DO_MAX(cbb+3, bb+3); } for(; ibb[0], obj->bb[1]); - DO_MINMAX(min_max+3, obj->bb[0], obj->bb[1]); + DO_MIN(min_max , obj->bb[0]); + DO_MAX(min_max+3, obj->bb[1]); BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); } @@ -135,6 +135,6 @@ static void RayObject_blibvh_free(RayObject *o) static void RayObject_blibvh_bb(RayObject *o, float *min, float *max) { BVHObject *obj = (BVHObject*)o; - DO_MINMAX( obj->bb[0], min, max ); - DO_MINMAX( obj->bb[1], min, max ); + DO_MIN( obj->bb[0], min ); + DO_MAX( obj->bb[1], max ); } diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 82aa4c57ccb..62adcb75b7c 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -133,9 +133,8 @@ static void bvh_merge_bb(BVHNode *node, float *min, float *max) { if(RayObject_isAligned(node)) { - //TODO only half operations needed - DO_MINMAX(node->bb , min, max); - DO_MINMAX(node->bb+3, min, max); + DO_MIN(node->bb , min); + DO_MAX(node->bb+3, max); } else { diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 5ed03a08f6a..688b3a920b4 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -19,6 +19,7 @@ static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) b->begin = begin; b->end = end; b->split_axis = 0; + b->child_sorted_axis = -1; for(i=0; ichild_offset[i] = 0; @@ -46,6 +47,7 @@ void rtbuild_add(RTBuilder *b, RayObject *o) RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) { rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); + tmp->child_sorted_axis = b->child_sorted_axis; return tmp; } @@ -254,12 +256,14 @@ float bb_volume(float *min, float *max) float bb_area(float *min, float *max) { - float sub[3]; + float sub[3], a; sub[0] = max[0]-min[0]; sub[1] = max[1]-min[1]; sub[2] = max[2]-min[2]; - return (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; + a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; + assert(a >= 0.0); + return a; } int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) @@ -274,7 +278,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) else { float bcost = FLT_MAX; - int i, axis, baxis, boffset; + int i, axis, baxis, boffset, k, try_axis[3]; CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); @@ -285,7 +289,20 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) RE_rayobject_merge_bb(b->begin[i], cost[i].bb, cost[i].bb+3); } - for(axis=0; axis<3; axis++) + if(b->child_sorted_axis >= 0 && b->child_sorted_axis < 3) + { + try_axis[0] = b->child_sorted_axis; + try_axis[1] = (b->child_sorted_axis+1)%3; + try_axis[2] = (b->child_sorted_axis+2)%3; + } + else + { + try_axis[0] = 0; + try_axis[1] = 1; + try_axis[2] = 2; + } + + for(axis=try_axis[k=0]; k<3; axis=try_axis[++k]) { float other_bb[6]; @@ -295,37 +312,54 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) float *bb = acc_bb+i*6; if(i == size-1) { - INIT_MINMAX( bb, bb+3 ); + VECCOPY(bb, cost[i].bb); + VECCOPY(bb+3, cost[i].bb+3); } else { - VECCOPY( bb, bb+6 ); - VECCOPY( bb+3, bb+6+3 ); + bb[0] = MIN2(cost[i].bb[0], bb[6+0]); + bb[1] = MIN2(cost[i].bb[1], bb[6+1]); + bb[2] = MIN2(cost[i].bb[2], bb[6+2]); + + bb[3] = MAX2(cost[i].bb[3], bb[6+3]); + bb[4] = MAX2(cost[i].bb[4], bb[6+4]); + bb[5] = MAX2(cost[i].bb[5], bb[6+5]); } - RE_rayobject_merge_bb( cost[i].obj, bb, bb+3 ); } INIT_MINMAX(other_bb, other_bb+3); - DO_MINMAX( cost[0].bb, other_bb, other_bb+3 ); - DO_MINMAX( cost[0].bb+3, other_bb, other_bb+3 ); + DO_MIN( cost[0].bb, other_bb ); + DO_MAX( cost[0].bb+3, other_bb+3 ); for(i=1; i bcost) break; //No way we can find a better heuristic in this axis + + hcost = left_side+right_side; + if( hcost < bcost + || (hcost == bcost && axis < baxis)) //this makes sure the tree built is the same whatever is the order of the sorting axis { bcost = hcost; baxis = axis; boffset = i; } - DO_MINMAX( cost[i].bb, other_bb, other_bb+3 ); - DO_MINMAX( cost[i].bb+3, other_bb, other_bb+3 ); + DO_MIN( cost[i].bb, other_bb ); + DO_MAX( cost[i].bb+3, other_bb+3 ); + } + + if(baxis == axis) + { + for(i=0; ibegin[i] = cost[i].obj; + b->child_sorted_axis = axis; } } - costobject_sort(cost, cost+size, baxis); - for(i=0; ibegin[i] = cost[i].obj; b->child_offset[0] = 0; b->child_offset[1] = boffset; -- cgit v1.2.3 From f7438ff77a206049cb11873e15360215064c1961 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Tue, 7 Jul 2009 19:13:05 +0000 Subject: - slowly starting FBX exporter conversion - added Bone.matrix and Bone.armature_matrix --- release/io/export_fbx.py | 3112 +++++++++++++++++++++++++ release/io/export_obj.py | 1 + source/blender/makesrna/intern/rna_armature.c | 10 + source/blender/makesrna/intern/rna_pose_api.c | 56 + 4 files changed, 3179 insertions(+) create mode 100644 release/io/export_fbx.py create mode 100644 source/blender/makesrna/intern/rna_pose_api.c diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py new file mode 100644 index 00000000000..cea9f500533 --- /dev/null +++ b/release/io/export_fbx.py @@ -0,0 +1,3112 @@ +#!BPY +""" +Name: 'Autodesk FBX (.fbx)...' +Blender: 249 +Group: 'Export' +Tooltip: 'Selection to an ASCII Autodesk FBX ' +""" +__author__ = "Campbell Barton" +__url__ = ['www.blender.org', 'blenderartists.org'] +__version__ = "1.2" + +__bpydoc__ = """\ +This script is an exporter to the FBX file format. + +http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx +""" +# -------------------------------------------------------------------------- +# FBX Export v0.1 by Campbell Barton (AKA Ideasman) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +import os + +try: + import time + # import os # only needed for batch export, nbot used yet +except: + time = None # use this to check if they have python modules installed + +# for python 2.3 support +try: + set() +except: + try: + from sets import Set as set + except: + set = None # so it complains you dont have a ! + +# # os is only needed for batch 'own dir' option +# try: +# import os +# except: +# os = None + +import Blender +import bpy +from Blender.Mathutils import Matrix, Vector, RotationMatrix + +import BPyObject +import BPyMesh +import BPySys +import BPyMessages + +## This was used to make V, but faster not to do all that +##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' +##v = range(255) +##for c in valid: v.remove(ord(c)) +v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,47,58,59,60,61,62,63,64,92,94,96,124,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] +invalid = ''.join([chr(i) for i in v]) +def cleanName(name): + for ch in invalid: name = name.replace(ch, '_') + return name +del v, i + + +def copy_file(source, dest): + file = open(source, 'rb') + data = file.read() + file.close() + + file = open(dest, 'wb') + file.write(data) + file.close() + + +def copy_images(dest_dir, textures): + if not dest_dir.endswith(os.sep): + dest_dir += os.sep + + image_paths = set() + for tex in textures: + image_paths.add(Blender.sys.expandpath(tex.filename)) + + # Now copy images + copyCount = 0 + for image_path in image_paths: + if Blender.sys.exists(image_path): + # Make a name for the target path. + dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] + if not Blender.sys.exists(dest_image_path): # Image isnt alredy there + print '\tCopying "%s" > "%s"' % (image_path, dest_image_path) + try: + copy_file(image_path, dest_image_path) + copyCount+=1 + except: + print '\t\tWarning, file failed to copy, skipping.' + + print '\tCopied %d images' % copyCount + +mtx4_identity = Matrix() + +# testing +mtx_x90 = RotationMatrix( 90, 3, 'x') # used +#mtx_x90n = RotationMatrix(-90, 3, 'x') +#mtx_y90 = RotationMatrix( 90, 3, 'y') +#mtx_y90n = RotationMatrix(-90, 3, 'y') +#mtx_z90 = RotationMatrix( 90, 3, 'z') +#mtx_z90n = RotationMatrix(-90, 3, 'z') + +#mtx4_x90 = RotationMatrix( 90, 4, 'x') +mtx4_x90n = RotationMatrix(-90, 4, 'x') # used +#mtx4_y90 = RotationMatrix( 90, 4, 'y') +mtx4_y90n = RotationMatrix(-90, 4, 'y') # used +mtx4_z90 = RotationMatrix( 90, 4, 'z') # used +mtx4_z90n = RotationMatrix(-90, 4, 'z') # used + +def strip_path(p): + return p.split('\\')[-1].split('/')[-1] + +# Used to add the scene name into the filename without using odd chars +sane_name_mapping_ob = {} +sane_name_mapping_mat = {} +sane_name_mapping_tex = {} +sane_name_mapping_take = {} +sane_name_mapping_group = {} + +# Make sure reserved names are not used +sane_name_mapping_ob['Scene'] = 'Scene_' +sane_name_mapping_ob['blend_root'] = 'blend_root_' + +def increment_string(t): + name = t + num = '' + while name and name[-1].isdigit(): + num = name[-1] + num + name = name[:-1] + if num: return '%s%d' % (name, int(num)+1) + else: return name + '_0' + + + +# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up. +def sane_name(data, dct): + #if not data: return None + + if type(data)==tuple: # materials are paired up with images + data, other = data + use_other = True + else: + other = None + use_other = False + + if data: name = data.name + else: name = None + orig_name = name + + if other: + orig_name_other = other.name + name = '%s #%s' % (name, orig_name_other) + else: + orig_name_other = None + + # dont cache, only ever call once for each data type now, + # so as to avoid namespace collision between types - like with objects <-> bones + #try: return dct[name] + #except: pass + + if not name: + name = 'unnamed' # blank string, ASKING FOR TROUBLE! + else: + #name = BPySys.cleanName(name) + name = cleanName(name) # use our own + + while name in dct.itervalues(): name = increment_string(name) + + if use_other: # even if other is None - orig_name_other will be a string or None + dct[orig_name, orig_name_other] = name + else: + dct[orig_name] = name + + return name + +def sane_obname(data): return sane_name(data, sane_name_mapping_ob) +def sane_matname(data): return sane_name(data, sane_name_mapping_mat) +def sane_texname(data): return sane_name(data, sane_name_mapping_tex) +def sane_takename(data): return sane_name(data, sane_name_mapping_take) +def sane_groupname(data): return sane_name(data, sane_name_mapping_group) + +def derived_paths(fname_orig, basepath, FORCE_CWD=False): + ''' + fname_orig - blender path, can be relative + basepath - fname_rel will be relative to this + FORCE_CWD - dont use the basepath, just add a ./ to the filename. + use when we know the file will be in the basepath. + ''' + fname = Blender.sys.expandpath(fname_orig) + fname_strip = strip_path(fname) + if FORCE_CWD: fname_rel = '.' + os.sep + fname_strip + else: fname_rel = Blender.sys.relpath(fname, basepath) + if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:] + return fname, fname_strip, fname_rel + + +def mat4x4str(mat): + return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ]) + +def meshNormalizedWeights(me): + try: # account for old bad BPyMesh + groupNames, vWeightList = BPyMesh.meshWeight2List(me) + except: + return [],[] + + if not groupNames: + return [],[] + + for i, vWeights in enumerate(vWeightList): + tot = 0.0 + for w in vWeights: + tot+=w + + if tot: + for j, w in enumerate(vWeights): + vWeights[j] = w/tot + + return groupNames, vWeightList + +header_comment = \ +'''; FBX 6.1.0 project file +; Created by Blender FBX Exporter +; for support mail: ideasman42@gmail.com +; ---------------------------------------------------- + +''' + +# This func can be called with just the filename +def write(filename, batch_objects = None, \ + context = None, + EXP_OBS_SELECTED = True, + EXP_MESH = True, + EXP_MESH_APPLY_MOD = True, + EXP_MESH_HQ_NORMALS = False, + EXP_ARMATURE = True, + EXP_LAMP = True, + EXP_CAMERA = True, + EXP_EMPTY = True, + EXP_IMAGE_COPY = False, + GLOBAL_MATRIX = Matrix(), + ANIM_ENABLE = True, + ANIM_OPTIMIZE = True, + ANIM_OPTIMIZE_PRECISSION = 6, + ANIM_ACTION_ALL = False, + BATCH_ENABLE = False, + BATCH_GROUP = True, + BATCH_SCENE = False, + BATCH_FILE_PREFIX = '', + BATCH_OWN_DIR = False + ): + + # ----------------- Batch support! + if BATCH_ENABLE: + if os == None: BATCH_OWN_DIR = False + + fbxpath = filename + + # get the path component of filename + tmp_exists = bpy.sys.exists(fbxpath) +# tmp_exists = Blender.sys.exists(fbxpath) + + if tmp_exists != 2: # a file, we want a path + while fbxpath and fbxpath[-1] not in ('/', '\\'): + fbxpath = fbxpath[:-1] + if not filename: + # XXX + print('Error%t|Directory does not exist!') +# Draw.PupMenu('Error%t|Directory does not exist!') + return + + tmp_exists = bpy.sys.exists(fbxpath) +# tmp_exists = Blender.sys.exists(fbxpath) + + if tmp_exists != 2: + # XXX + print('Error%t|Directory does not exist!') +# Draw.PupMenu('Error%t|Directory does not exist!') + return + + if not fbxpath.endswith(os.sep): + fbxpath += os.sep + del tmp_exists + + + if BATCH_GROUP: + data_seq = bpy.data.groups + else: + data_seq = bpy.data.scenes + + # call this function within a loop with BATCH_ENABLE == False + orig_sce = context.scene +# orig_sce = bpy.data.scenes.active + + + new_fbxpath = fbxpath # own dir option modifies, we need to keep an original + for data in data_seq: # scene or group + newname = BATCH_FILE_PREFIX + cleanName(data.name) +# newname = BATCH_FILE_PREFIX + BPySys.cleanName(data.name) + + + if BATCH_OWN_DIR: + new_fbxpath = fbxpath + newname + os.sep + # path may alredy exist + # TODO - might exist but be a file. unlikely but should probably account for it. + + if bpy.sys.exists(new_fbxpath) == 0: +# if Blender.sys.exists(new_fbxpath) == 0: + os.mkdir(new_fbxpath) + + + filename = new_fbxpath + newname + '.fbx' + + print '\nBatch exporting %s as...\n\t"%s"' % (data, filename) + + # XXX don't know what to do with this, probably do the same? (Arystan) + if BATCH_GROUP: #group + # group, so objects update properly, add a dummy scene. + sce = bpy.data.scenes.new() + sce.Layers = (1<<20) -1 + bpy.data.scenes.active = sce + for ob_base in data.objects: + sce.objects.link(ob_base) + + sce.update(1) + + # TODO - BUMMER! Armatures not in the group wont animate the mesh + + else:# scene + + + data_seq.active = data + + + # Call self with modified args + # Dont pass batch options since we alredy usedt them + write(filename, data.objects, + context, + False, + EXP_MESH, + EXP_MESH_APPLY_MOD, + EXP_MESH_HQ_NORMALS, + EXP_ARMATURE, + EXP_LAMP, + EXP_CAMERA, + EXP_EMPTY, + EXP_IMAGE_COPY, + GLOBAL_MATRIX, + ANIM_ENABLE, + ANIM_OPTIMIZE, + ANIM_OPTIMIZE_PRECISSION, + ANIM_ACTION_ALL + ) + + if BATCH_GROUP: + # remove temp group scene + bpy.data.remove_scene(sce) +# bpy.data.scenes.unlink(sce) + + bpy.data.scenes.active = orig_sce + + return # so the script wont run after we have batch exported. + + # end batch support + + # Use this for working out paths relative to the export location + basepath = Blender.sys.dirname(filename) + + # ---------------------------------------------- + # storage classes + class my_bone_class: + __slots__ =(\ + 'blenName',\ + 'blenBone',\ + 'blenMeshes',\ + 'restMatrix',\ + 'parent',\ + 'blenName',\ + 'fbxName',\ + 'fbxArm',\ + '__pose_bone',\ + '__anim_poselist') + + def __init__(self, blenBone, fbxArm): + + # This is so 2 armatures dont have naming conflicts since FBX bones use object namespace + self.fbxName = sane_obname(blenBone) + + self.blenName = blenBone.name + self.blenBone = blenBone + self.blenMeshes = {} # fbxMeshObName : mesh + self.fbxArm = fbxArm + self.restMatrix = blenBone.armature_matrix + # self.restMatrix = blenBone.matrix['ARMATURESPACE'] + + # not used yet + # self.restMatrixInv = self.restMatrix.copy().invert() + # self.restMatrixLocal = None # set later, need parent matrix + + self.parent = None + + # not public + pose = fbxArm.blenObject.pose +# pose = fbxArm.blenObject.getPose() + self.__pose_bone = pose.bones[self.blenName] + + # store a list if matricies here, (poseMatrix, head, tail) + # {frame:posematrix, frame:posematrix, ...} + self.__anim_poselist = {} + + ''' + def calcRestMatrixLocal(self): + if self.parent: + self.restMatrixLocal = self.restMatrix * self.parent.restMatrix.copy().invert() + else: + self.restMatrixLocal = self.restMatrix.copy() + ''' + def setPoseFrame(self, f): + # cache pose info here, frame must be set beforehand + + # Didnt end up needing head or tail, if we do - here it is. + ''' + self.__anim_poselist[f] = (\ + self.__pose_bone.poseMatrix.copy(),\ + self.__pose_bone.head.copy(),\ + self.__pose_bone.tail.copy() ) + ''' + + self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy() + + # get pose from frame. + def getPoseMatrix(self, f):# ---------------------------------------------- + return self.__anim_poselist[f] + ''' + def getPoseHead(self, f): + #return self.__pose_bone.head.copy() + return self.__anim_poselist[f][1].copy() + def getPoseTail(self, f): + #return self.__pose_bone.tail.copy() + return self.__anim_poselist[f][2].copy() + ''' + # end + + def getAnimParRelMatrix(self, frame): + #arm_mat = self.fbxArm.matrixWorld + #arm_mat = self.fbxArm.parRelMatrix() + if not self.parent: + #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore + return mtx4_z90 * self.getPoseMatrix(frame) + else: + #return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat))) * (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert() + return (mtx4_z90 * (self.getPoseMatrix(frame))) * (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert() + + # we need thes because cameras and lights modified rotations + def getAnimParRelMatrixRot(self, frame): + return self.getAnimParRelMatrix(frame) + + def flushAnimData(self): + self.__anim_poselist.clear() + + + class my_object_generic: + # Other settings can be applied for each type - mesh, armature etc. + def __init__(self, ob, matrixWorld = None): + self.fbxName = sane_obname(ob) + self.blenObject = ob + self.fbxGroupNames = [] + self.fbxParent = None # set later on IF the parent is in the selection. + if matrixWorld: self.matrixWorld = matrixWorld * GLOBAL_MATRIX + else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX + self.__anim_poselist = {} # we should only access this + + def parRelMatrix(self): + if self.fbxParent: + return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert() + else: + return self.matrixWorld + + def setPoseFrame(self, f): + self.__anim_poselist[f] = self.blenObject.matrixWorld.copy() + + def getAnimParRelMatrix(self, frame): + if self.fbxParent: + #return (self.__anim_poselist[frame] * self.fbxParent.__anim_poselist[frame].copy().invert() ) * GLOBAL_MATRIX + return (self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert() + else: + return self.__anim_poselist[frame] * GLOBAL_MATRIX + + def getAnimParRelMatrixRot(self, frame): + type = self.blenObject.type + if self.fbxParent: + matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart() + else: + matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart() + + # Lamps need to be rotated + if type =='Lamp': + matrix_rot = mtx_x90 * matrix_rot + elif ob and type =='Camera': + y = Vector(0,1,0) * matrix_rot + matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y) + + return matrix_rot + + # ---------------------------------------------- + + + + + + print '\nFBX export starting...', filename + start_time = Blender.sys.time() + try: + file = open(filename, 'w') + except: + return False + + sce = bpy.data.scenes.active + world = sce.world + + + # ---------------------------- Write the header first + file.write(header_comment) + if time: + curtime = time.localtime()[0:6] + else: + curtime = (0,0,0,0,0,0) + # + file.write(\ +'''FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 6100 + CreationTimeStamp: { + Version: 1000 + Year: %.4i + Month: %.2i + Day: %.2i + Hour: %.2i + Minute: %.2i + Second: %.2i + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins build 20070228" + OtherFlags: { + FlagPLE: 0 + } +}''' % (curtime)) + + file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime) + file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version')) + + pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way + + # --------------- funcs for exporting + def object_tx(ob, loc, matrix, matrix_mod = None): + ''' + Matrix mod is so armature objects can modify their bone matricies + ''' + if isinstance(ob, Blender.Types.BoneType): + + # we know we have a matrix + # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod) + matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore + + parent = ob.parent + if parent: + #par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod) + par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore + matrix = matrix * par_matrix.copy().invert() + + matrix_rot = matrix.rotationPart() + + loc = tuple(matrix.translationPart()) + scale = tuple(matrix.scalePart()) + rot = tuple(matrix_rot.toEuler()) + + else: + # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore + #if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX + if ob and not matrix: raise "error: this should never happen!" + + matrix_rot = matrix + #if matrix: + # matrix = matrix_scale * matrix + + if matrix: + loc = tuple(matrix.translationPart()) + scale = tuple(matrix.scalePart()) + + matrix_rot = matrix.rotationPart() + # Lamps need to be rotated + if ob and ob.type =='Lamp': + matrix_rot = mtx_x90 * matrix_rot + rot = tuple(matrix_rot.toEuler()) + elif ob and ob.type =='Camera': + y = Vector(0,1,0) * matrix_rot + matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y) + rot = tuple(matrix_rot.toEuler()) + else: + rot = tuple(matrix_rot.toEuler()) + else: + if not loc: + loc = 0,0,0 + scale = 1,1,1 + rot = 0,0,0 + + return loc, rot, scale, matrix, matrix_rot + + def write_object_tx(ob, loc, matrix, matrix_mod= None): + ''' + We have loc to set the location if non blender objects that have a location + + matrix_mod is only used for bones at the moment + ''' + loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod) + + file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc) + file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) + file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale) + return loc, rot, scale, matrix, matrix_rot + + def write_object_props(ob=None, loc=None, matrix=None, matrix_mod=None): + # if the type is 0 its an empty otherwise its a mesh + # only difference at the moment is one has a color + file.write(''' + Properties60: { + Property: "QuaternionInterpolate", "bool", "",0 + Property: "Visibility", "Visibility", "A+",1''') + + loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix, matrix_mod) + + # Rotation order, note, for FBX files Iv loaded normal order is 1 + # setting to zero. + # eEULER_XYZ = 0 + # eEULER_XZY + # eEULER_YZX + # eEULER_YXZ + # eEULER_ZXY + # eEULER_ZYX + + file.write(''' + Property: "RotationOffset", "Vector3D", "",0,0,0 + Property: "RotationPivot", "Vector3D", "",0,0,0 + Property: "ScalingOffset", "Vector3D", "",0,0,0 + Property: "ScalingPivot", "Vector3D", "",0,0,0 + Property: "TranslationActive", "bool", "",0 + Property: "TranslationMin", "Vector3D", "",0,0,0 + Property: "TranslationMax", "Vector3D", "",0,0,0 + Property: "TranslationMinX", "bool", "",0 + Property: "TranslationMinY", "bool", "",0 + Property: "TranslationMinZ", "bool", "",0 + Property: "TranslationMaxX", "bool", "",0 + Property: "TranslationMaxY", "bool", "",0 + Property: "TranslationMaxZ", "bool", "",0 + Property: "RotationOrder", "enum", "",0 + Property: "RotationSpaceForLimitOnly", "bool", "",0 + Property: "AxisLen", "double", "",10 + Property: "PreRotation", "Vector3D", "",0,0,0 + Property: "PostRotation", "Vector3D", "",0,0,0 + Property: "RotationActive", "bool", "",0 + Property: "RotationMin", "Vector3D", "",0,0,0 + Property: "RotationMax", "Vector3D", "",0,0,0 + Property: "RotationMinX", "bool", "",0 + Property: "RotationMinY", "bool", "",0 + Property: "RotationMinZ", "bool", "",0 + Property: "RotationMaxX", "bool", "",0 + Property: "RotationMaxY", "bool", "",0 + Property: "RotationMaxZ", "bool", "",0 + Property: "RotationStiffnessX", "double", "",0 + Property: "RotationStiffnessY", "double", "",0 + Property: "RotationStiffnessZ", "double", "",0 + Property: "MinDampRangeX", "double", "",0 + Property: "MinDampRangeY", "double", "",0 + Property: "MinDampRangeZ", "double", "",0 + Property: "MaxDampRangeX", "double", "",0 + Property: "MaxDampRangeY", "double", "",0 + Property: "MaxDampRangeZ", "double", "",0 + Property: "MinDampStrengthX", "double", "",0 + Property: "MinDampStrengthY", "double", "",0 + Property: "MinDampStrengthZ", "double", "",0 + Property: "MaxDampStrengthX", "double", "",0 + Property: "MaxDampStrengthY", "double", "",0 + Property: "MaxDampStrengthZ", "double", "",0 + Property: "PreferedAngleX", "double", "",0 + Property: "PreferedAngleY", "double", "",0 + Property: "PreferedAngleZ", "double", "",0 + Property: "InheritType", "enum", "",0 + Property: "ScalingActive", "bool", "",0 + Property: "ScalingMin", "Vector3D", "",1,1,1 + Property: "ScalingMax", "Vector3D", "",1,1,1 + Property: "ScalingMinX", "bool", "",0 + Property: "ScalingMinY", "bool", "",0 + Property: "ScalingMinZ", "bool", "",0 + Property: "ScalingMaxX", "bool", "",0 + Property: "ScalingMaxY", "bool", "",0 + Property: "ScalingMaxZ", "bool", "",0 + Property: "GeometricTranslation", "Vector3D", "",0,0,0 + Property: "GeometricRotation", "Vector3D", "",0,0,0 + Property: "GeometricScaling", "Vector3D", "",1,1,1 + Property: "LookAtProperty", "object", "" + Property: "UpVectorProperty", "object", "" + Property: "Show", "bool", "",1 + Property: "NegativePercentShapeSupport", "bool", "",1 + Property: "DefaultAttributeIndex", "int", "",0''') + if ob and type(ob) != Blender.Types.BoneType: + # Only mesh objects have color + file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') + file.write('\n\t\t\tProperty: "Size", "double", "",100') + file.write('\n\t\t\tProperty: "Look", "enum", "",1') + + return loc, rot, scale, matrix, matrix_rot + + + # -------------------------------------------- Armatures + #def write_bone(bone, name, matrix_mod): + def write_bone(my_bone): + file.write('\n\tModel: "Model::%s", "Limb" {' % my_bone.fbxName) + file.write('\n\t\tVersion: 232') + + #poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.parRelMatrix())[3] + poseMatrix = write_object_props(my_bone.blenBone)[3] # dont apply bone matricies anymore + pose_items.append( (my_bone.fbxName, poseMatrix) ) + + + # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) + file.write('\n\t\t\tProperty: "Size", "double", "",1') + + #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.tail['ARMATURESPACE'] * my_bone.fbxArm.parRelMatrix())).length) + + """ + file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ + ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) + """ + + file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ + (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length) + + #file.write('\n\t\t\tProperty: "LimbLength", "double", "",1') + file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8') + file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 1') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Skeleton"') + file.write('\n\t}') + + def write_camera_switch(): + file.write(''' + Model: "Model::Camera Switcher", "CameraSwitcher" { + Version: 232''') + + write_object_props() + file.write(''' + Property: "Color", "Color", "A",0.8,0.8,0.8 + Property: "Camera Index", "Integer", "A+",100 + } + MultiLayer: 0 + MultiTake: 1 + Hidden: "True" + Shading: W + Culling: "CullingOff" + Version: 101 + Name: "Model::Camera Switcher" + CameraId: 0 + CameraName: 100 + CameraIndexName: + }''') + + def write_camera_dummy(name, loc, near, far, proj_type, up): + file.write('\n\tModel: "Model::%s", "Camera" {' % name ) + file.write('\n\t\tVersion: 232') + write_object_props(None, loc) + + file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') + file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') + file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",40') + file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",0') + file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",0') + file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0.63,0.63,0.63') + file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') + file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') + file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') + file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') + file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') + file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') + file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') + file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",21.3544940948486') + file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') + file.write('\n\t\t\tProperty: "AspectW", "double", "",320') + file.write('\n\t\t\tProperty: "AspectH", "double", "",200') + file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",1') + file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') + file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') + file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') + file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % near) + file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % far) + file.write('\n\t\t\tProperty: "FilmWidth", "double", "",0.816') + file.write('\n\t\t\tProperty: "FilmHeight", "double", "",0.612') + file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",1.33333333333333') + file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') + file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",4') + file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') + file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') + file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') + file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') + file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') + file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') + file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') + file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') + file.write('\n\t\t\tProperty: "Crop", "bool", "",0') + file.write('\n\t\t\tProperty: "Center", "bool", "",1') + file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') + file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') + file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') + file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') + file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') + file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') + file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",1.33333333333333') + file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') + file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') + file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') + file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') + file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",%i' % proj_type) + file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') + file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') + file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') + file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') + file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') + file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') + file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') + file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 0') + file.write('\n\t\tHidden: "True"') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Camera"') + file.write('\n\t\tGeometryVersion: 124') + file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) + file.write('\n\t\tUp: %i,%i,%i' % up) + file.write('\n\t\tLookAt: 0,0,0') + file.write('\n\t\tShowInfoOnMoving: 1') + file.write('\n\t\tShowAudio: 0') + file.write('\n\t\tAudioColor: 0,1,0') + file.write('\n\t\tCameraOrthoZoom: 1') + file.write('\n\t}') + + def write_camera_default(): + # This sucks but to match FBX converter its easier to + # write the cameras though they are not needed. + write_camera_dummy('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0)) + write_camera_dummy('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1)) + write_camera_dummy('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1)) + write_camera_dummy('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0)) + write_camera_dummy('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0)) + write_camera_dummy('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0)) + write_camera_dummy('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0)) + + def write_camera(my_cam): + ''' + Write a blender camera + ''' + render = sce.render + width = render.sizeX + height = render.sizeY + aspect = float(width)/height + + data = my_cam.blenObject.data + + file.write('\n\tModel: "Model::%s", "Camera" {' % my_cam.fbxName ) + file.write('\n\t\tVersion: 232') + loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject, None, my_cam.parRelMatrix()) + + file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') + file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle) + file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026') + file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units? + file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto + file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0') + file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') + file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') + file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') + file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') + file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') + file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') + file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') + file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') + file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width) + file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height) + + '''Camera aspect ratio modes. + 0 If the ratio mode is eWINDOW_SIZE, both width and height values aren't relevant. + 1 If the ratio mode is eFIXED_RATIO, the height value is set to 1.0 and the width value is relative to the height value. + 2 If the ratio mode is eFIXED_RESOLUTION, both width and height values are in pixels. + 3 If the ratio mode is eFIXED_WIDTH, the width value is in pixels and the height value is relative to the width value. + 4 If the ratio mode is eFIXED_HEIGHT, the height value is in pixels and the width value is relative to the height value. + + Definition at line 234 of file kfbxcamera.h. ''' + + file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",2') + + file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') + file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') + file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') + file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart) + file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart) + file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0') + file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0') + file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect) + file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') + file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",0') + file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') + file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') + file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') + file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') + file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') + file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') + file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') + file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') + file.write('\n\t\t\tProperty: "Crop", "bool", "",0') + file.write('\n\t\t\tProperty: "Center", "bool", "",1') + file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') + file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') + file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') + file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') + file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') + file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') + file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",%.6f' % aspect) + file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') + file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') + file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') + file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') + file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",0') + file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') + file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') + file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') + file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') + file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') + file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') + file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') + file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') + + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 0') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Camera"') + file.write('\n\t\tGeometryVersion: 124') + file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) + file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Vector(0,1,0) * matrix_rot) ) + file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Vector(0,0,-1)*matrix_rot) ) + + #file.write('\n\t\tUp: 0,0,0' ) + #file.write('\n\t\tLookAt: 0,0,0' ) + + file.write('\n\t\tShowInfoOnMoving: 1') + file.write('\n\t\tShowAudio: 0') + file.write('\n\t\tAudioColor: 0,1,0') + file.write('\n\t\tCameraOrthoZoom: 1') + file.write('\n\t}') + + def write_light(my_light): + light = my_light.blenObject.data + file.write('\n\tModel: "Model::%s", "Light" {' % my_light.fbxName) + file.write('\n\t\tVersion: 232') + + write_object_props(my_light.blenObject, None, my_light.parRelMatrix()) + + # Why are these values here twice?????? - oh well, follow the holy sdk's output + + # Blender light types match FBX's, funny coincidence, we just need to + # be sure that all unsupported types are made into a point light + #ePOINT, + #eDIRECTIONAL + #eSPOT + light_type = light.type + if light_type > 2: light_type = 1 # hemi and area lights become directional + + mode = light.mode + if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: + do_shadow = 1 + else: + do_shadow = 0 + + if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular): + do_light = 0 + else: + do_light = 1 + + scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case + + file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) + file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') + file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') + file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1') + file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 + file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) + file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') + file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col)) + file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 + file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) + file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') + file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) + file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light) + file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') + file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') + file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') + file.write('\n\t\t\tProperty: "DecayType", "enum", "",0') + file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist) + file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0') + file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0') + file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0') + file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0') + file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0') + file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0') + file.write('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow) + file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1') + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 0') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Light"') + file.write('\n\t\tGeometryVersion: 124') + file.write('\n\t}') + + # matrixOnly is not used at the moment + def write_null(my_null = None, fbxName = None, matrixOnly = None): + # ob can be null + if not fbxName: fbxName = my_null.fbxName + + file.write('\n\tModel: "Model::%s", "Null" {' % fbxName) + file.write('\n\t\tVersion: 232') + + # only use this for the root matrix at the moment + if matrixOnly: + poseMatrix = write_object_props(None, None, matrixOnly)[3] + + else: # all other Null's + if my_null: poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3] + else: poseMatrix = write_object_props()[3] + + pose_items.append((fbxName, poseMatrix)) + + file.write(''' + } + MultiLayer: 0 + MultiTake: 1 + Shading: Y + Culling: "CullingOff" + TypeFlags: "Null" + }''') + + # Material Settings + if world: world_amb = world.getAmb() + else: world_amb = (0,0,0) # Default value + + def write_material(matname, mat): + file.write('\n\tMaterial: "Material::%s", "" {' % matname) + + # Todo, add more material Properties. + if mat: + mat_cold = tuple(mat.rgbCol) + mat_cols = tuple(mat.specCol) + #mat_colm = tuple(mat.mirCol) # we wont use the mirror color + mat_colamb = tuple([c for c in world_amb]) + + mat_dif = mat.ref + mat_amb = mat.amb + mat_hard = (float(mat.hard)-1)/5.10 + mat_spec = mat.spec/2.0 + mat_alpha = mat.alpha + mat_emit = mat.emit + mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS + if mat_shadeless: + mat_shader = 'Lambert' + else: + if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT: + mat_shader = 'Lambert' + else: + mat_shader = 'Phong' + else: + mat_cols = mat_cold = 0.8, 0.8, 0.8 + mat_colamb = 0.0,0.0,0.0 + # mat_colm + mat_dif = 1.0 + mat_amb = 0.5 + mat_hard = 20.0 + mat_spec = 0.2 + mat_alpha = 1.0 + mat_emit = 0.0 + mat_shadeless = False + mat_shader = 'Phong' + + file.write('\n\t\tVersion: 102') + file.write('\n\t\tShadingModel: "%s"' % mat_shader.lower()) + file.write('\n\t\tMultiLayer: 0') + + file.write('\n\t\tProperties60: {') + file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader) + file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0') + file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender + file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit) + + file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb) + file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb) + file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) + file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif) + file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0') + file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1') + file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha)) + if not mat_shadeless: + file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols) + file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec) + file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0') + file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0') + file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1') + file.write('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0') + file.write('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb) + file.write('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold) + if not mat_shadeless: + file.write('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols) + file.write('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard) + file.write('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha) + if not mat_shadeless: + file.write('\n\t\t\tProperty: "Reflectivity", "double", "",0') + + file.write('\n\t\t}') + file.write('\n\t}') + + def write_video(texname, tex): + # Same as texture really! + file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) + + file.write(''' + Type: "Clip" + Properties60: { + Property: "FrameRate", "double", "",0 + Property: "LastFrame", "int", "",0 + Property: "Width", "int", "",0 + Property: "Height", "int", "",0''') + if tex: + fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) + else: + fname = fname_strip = fname_rel = '' + + file.write('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip) + + + file.write(''' + Property: "StartFrame", "int", "",0 + Property: "StopFrame", "int", "",0 + Property: "PlaySpeed", "double", "",1 + Property: "Offset", "KTime", "",0 + Property: "InterlaceMode", "enum", "",0 + Property: "FreeRunning", "bool", "",0 + Property: "Loop", "bool", "",0 + Property: "AccessMode", "enum", "",0 + } + UseMipMap: 0''') + + file.write('\n\t\tFilename: "%s"' % fname_strip) + if fname_strip: fname_strip = '/' + fname_strip + file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # make relative + file.write('\n\t}') + + + def write_texture(texname, tex, num): + # if tex == None then this is a dummy tex + file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname) + file.write('\n\t\tType: "TextureVideoClip"') + file.write('\n\t\tVersion: 202') + # TODO, rare case _empty_ exists as a name. + file.write('\n\t\tTextureName: "Texture::%s"' % texname) + + file.write(''' + Properties60: { + Property: "Translation", "Vector", "A+",0,0,0 + Property: "Rotation", "Vector", "A+",0,0,0 + Property: "Scaling", "Vector", "A+",1,1,1''') + file.write('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num) + + + # WrapModeU/V 0==rep, 1==clamp, TODO add support + file.write(''' + Property: "TextureTypeUse", "enum", "",0 + Property: "CurrentTextureBlendMode", "enum", "",1 + Property: "UseMaterial", "bool", "",0 + Property: "UseMipMap", "bool", "",0 + Property: "CurrentMappingType", "enum", "",0 + Property: "UVSwap", "bool", "",0''') + + file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX) + file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY) + + file.write(''' + Property: "TextureRotationPivot", "Vector3D", "",0,0,0 + Property: "TextureScalingPivot", "Vector3D", "",0,0,0 + Property: "VideoProperty", "object", "" + }''') + + file.write('\n\t\tMedia: "Video::%s"' % texname) + + if tex: + fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) + else: + fname = fname_strip = fname_rel = '' + + file.write('\n\t\tFileName: "%s"' % fname_strip) + file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # need some make relative command + + file.write(''' + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + }''') + + def write_deformer_skin(obname): + ''' + Each mesh has its own deformer + ''' + file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname) + file.write(''' + Version: 100 + MultiLayer: 0 + Type: "Skin" + Properties60: { + } + Link_DeformAcuracy: 50 + }''') + + # in the example was 'Bip01 L Thigh_2' + def write_sub_deformer_skin(my_mesh, my_bone, weights): + + ''' + Each subdeformer is spesific to a mesh, but the bone it links to can be used by many sub-deformers + So the SubDeformer needs the mesh-object name as a prefix to make it unique + + Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer, + a but silly but dosnt really matter + ''' + file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName)) + + file.write(''' + Version: 100 + MultiLayer: 0 + Type: "Cluster" + Properties60: { + Property: "SrcModel", "object", "" + Property: "SrcModelReference", "object", "" + } + UserData: "", ""''') + + # Support for bone parents + if my_mesh.fbxBoneParent: + if my_mesh.fbxBoneParent == my_bone: + # TODO - this is a bit lazy, we could have a simple write loop + # for this case because all weights are 1.0 but for now this is ok + # Parent Bones arent used all that much anyway. + vgroup_data = [(j, 1.0) for j in xrange(len(my_mesh.blenData.verts))] + else: + # This bone is not a parent of this mesh object, no weights + vgroup_data = [] + + else: + # Normal weight painted mesh + if my_bone.blenName in weights[0]: + # Before we used normalized wright list + #vgroup_data = me.getVertsFromGroup(bone.name, 1) + group_index = weights[0].index(my_bone.blenName) + vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]] + else: + vgroup_data = [] + + file.write('\n\t\tIndexes: ') + + i = -1 + for vg in vgroup_data: + if i == -1: + file.write('%i' % vg[0]) + i=0 + else: + if i==23: + file.write('\n\t\t') + i=0 + file.write(',%i' % vg[0]) + i+=1 + + file.write('\n\t\tWeights: ') + i = -1 + for vg in vgroup_data: + if i == -1: + file.write('%.8f' % vg[1]) + i=0 + else: + if i==38: + file.write('\n\t\t') + i=0 + file.write(',%.8f' % vg[1]) + i+=1 + + if my_mesh.fbxParent: + # TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible! + m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) + else: + # Yes! this is it... - but dosnt work when the mesh is a. + m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) + + #m = mtx4_z90 * my_bone.restMatrix + matstr = mat4x4str(m) + matstr_i = mat4x4str(m.invert()) + + file.write('\n\t\tTransform: %s' % matstr_i) # THIS IS __NOT__ THE GLOBAL MATRIX AS DOCUMENTED :/ + file.write('\n\t\tTransformLink: %s' % matstr) + file.write('\n\t}') + + def write_mesh(my_mesh): + + me = my_mesh.blenData + + # if there are non NULL materials on this mesh + if my_mesh.blenMaterials: do_materials = True + else: do_materials = False + + if my_mesh.blenTextures: do_textures = True + else: do_textures = False + + do_uvs = me.faceUV + + + file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) + file.write('\n\t\tVersion: 232') # newline is added in write_object_props + + poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3] + pose_items.append((my_mesh.fbxName, poseMatrix)) + + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 1') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + + + # Write the Real Mesh data here + file.write('\n\t\tVertices: ') + i=-1 + + for v in me.verts: + if i==-1: + file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0 + else: + if i==7: + file.write('\n\t\t'); i=0 + file.write(',%.6f,%.6f,%.6f'% tuple(v.co)) + i+=1 + + file.write('\n\t\tPolygonVertexIndex: ') + i=-1 + for f in me.faces: + fi = [v.index for v in f] + # flip the last index, odd but it looks like + # this is how fbx tells one face from another + fi[-1] = -(fi[-1]+1) + fi = tuple(fi) + if i==-1: + if len(f) == 3: file.write('%i,%i,%i' % fi ) + else: file.write('%i,%i,%i,%i' % fi ) + i=0 + else: + if i==13: + file.write('\n\t\t') + i=0 + if len(f) == 3: file.write(',%i,%i,%i' % fi ) + else: file.write(',%i,%i,%i,%i' % fi ) + i+=1 + + file.write('\n\t\tEdges: ') + i=-1 + for ed in me.edges: + if i==-1: + file.write('%i,%i' % (ed.v1.index, ed.v2.index)) + i=0 + else: + if i==13: + file.write('\n\t\t') + i=0 + file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) + i+=1 + + file.write('\n\t\tGeometryVersion: 124') + + file.write(''' + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: ''') + + i=-1 + for v in me.verts: + if i==-1: + file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0 + else: + if i==2: + file.write('\n '); i=0 + file.write(',%.15f,%.15f,%.15f' % tuple(v.no)) + i+=1 + file.write('\n\t\t}') + + # Write Face Smoothing + file.write(''' + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "Direct" + Smoothing: ''') + + i=-1 + for f in me.faces: + if i==-1: + file.write('%i' % f.smooth); i=0 + else: + if i==54: + file.write('\n '); i=0 + file.write(',%i' % f.smooth) + i+=1 + + file.write('\n\t\t}') + + # Write Edge Smoothing + file.write(''' + LayerElementSmoothing: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: ''') + + SHARP = Blender.Mesh.EdgeFlags.SHARP + i=-1 + for ed in me.edges: + if i==-1: + file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 + else: + if i==54: + file.write('\n '); i=0 + file.write(',%i' % ((ed.flag&SHARP)!=0)) + i+=1 + + file.write('\n\t\t}') + del SHARP + + + # Write VertexColor Layers + # note, no programs seem to use this info :/ + collayers = [] + if me.vertexColors: + collayers = me.getColorLayerNames() + collayer_orig = me.activeColorLayer + for colindex, collayer in enumerate(collayers): + me.activeColorLayer = collayer + file.write('\n\t\tLayerElementColor: %i {' % colindex) + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: "%s"' % collayer) + + file.write(''' + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + Colors: ''') + + i = -1 + ii = 0 # Count how many Colors we write + + for f in me.faces: + for col in f.col: + if i==-1: + file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) + i=0 + else: + if i==7: + file.write('\n\t\t\t\t') + i=0 + file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) + i+=1 + ii+=1 # One more Color + + file.write('\n\t\t\tColorIndex: ') + i = -1 + for j in xrange(ii): + if i == -1: + file.write('%i' % j) + i=0 + else: + if i==55: + file.write('\n\t\t\t\t') + i=0 + file.write(',%i' % j) + i+=1 + + file.write('\n\t\t}') + + + + # Write UV and texture layers. + uvlayers = [] + if do_uvs: + uvlayers = me.getUVLayerNames() + uvlayer_orig = me.activeUVLayer + for uvindex, uvlayer in enumerate(uvlayers): + me.activeUVLayer = uvlayer + file.write('\n\t\tLayerElementUV: %i {' % uvindex) + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: "%s"' % uvlayer) + + file.write(''' + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: ''') + + i = -1 + ii = 0 # Count how many UVs we write + + for f in me.faces: + for uv in f.uv: + if i==-1: + file.write('%.6f,%.6f' % tuple(uv)) + i=0 + else: + if i==7: + file.write('\n ') + i=0 + file.write(',%.6f,%.6f' % tuple(uv)) + i+=1 + ii+=1 # One more UV + + file.write('\n\t\t\tUVIndex: ') + i = -1 + for j in xrange(ii): + if i == -1: + file.write('%i' % j) + i=0 + else: + if i==55: + file.write('\n\t\t\t\t') + i=0 + file.write(',%i' % j) + i+=1 + + file.write('\n\t\t}') + + if do_textures: + file.write('\n\t\tLayerElementTexture: %i {' % uvindex) + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: "%s"' % uvlayer) + + if len(my_mesh.blenTextures) == 1: + file.write('\n\t\t\tMappingInformationType: "AllSame"') + else: + file.write('\n\t\t\tMappingInformationType: "ByPolygon"') + + file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') + file.write('\n\t\t\tBlendMode: "Translucent"') + file.write('\n\t\t\tTextureAlpha: 1') + file.write('\n\t\t\tTextureId: ') + + if len(my_mesh.blenTextures) == 1: + file.write('0') + else: + texture_mapping_local = {None:-1} + + i = 0 # 1 for dummy + for tex in my_mesh.blenTextures: + if tex: # None is set above + texture_mapping_local[tex] = i + i+=1 + + i=-1 + for f in me.faces: + img_key = f.image + + if i==-1: + i=0 + file.write( '%s' % texture_mapping_local[img_key]) + else: + if i==55: + file.write('\n ') + i=0 + + file.write(',%s' % texture_mapping_local[img_key]) + i+=1 + + else: + file.write(''' + LayerElementTexture: 0 { + Version: 101 + Name: "" + MappingInformationType: "NoMappingInformation" + ReferenceInformationType: "IndexToDirect" + BlendMode: "Translucent" + TextureAlpha: 1 + TextureId: ''') + file.write('\n\t\t}') + + me.activeUVLayer = uvlayer_orig + + # Done with UV/textures. + + if do_materials: + file.write('\n\t\tLayerElementMaterial: 0 {') + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: ""') + + if len(my_mesh.blenMaterials) == 1: + file.write('\n\t\t\tMappingInformationType: "AllSame"') + else: + file.write('\n\t\t\tMappingInformationType: "ByPolygon"') + + file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') + file.write('\n\t\t\tMaterials: ') + + if len(my_mesh.blenMaterials) == 1: + file.write('0') + else: + # Build a material mapping for this + material_mapping_local = {} # local-mat & tex : global index. + + for j, mat_tex_pair in enumerate(my_mesh.blenMaterials): + material_mapping_local[mat_tex_pair] = j + + len_material_mapping_local = len(material_mapping_local) + + mats = my_mesh.blenMaterialList + + i=-1 + for f in me.faces: + try: mat = mats[f.mat] + except:mat = None + + if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ + else: tex = None + + if i==-1: + i=0 + file.write( '%s' % (material_mapping_local[mat, tex])) # None for mat or tex is ok + else: + if i==55: + file.write('\n\t\t\t\t') + i=0 + + file.write(',%s' % (material_mapping_local[mat, tex])) + i+=1 + + file.write('\n\t\t}') + + file.write(''' + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + }''') + + if do_materials: + file.write(''' + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + }''') + + # Always write this + if do_textures: + file.write(''' + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + }''') + + if me.vertexColors: + file.write(''' + LayerElement: { + Type: "LayerElementColor" + TypedIndex: 0 + }''') + + if do_uvs: # same as me.faceUV + file.write(''' + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + }''') + + + file.write('\n\t\t}') + + if len(uvlayers) > 1: + for i in xrange(1, len(uvlayers)): + + file.write('\n\t\tLayer: %i {' % i) + file.write('\n\t\t\tVersion: 100') + + file.write(''' + LayerElement: { + Type: "LayerElementUV"''') + + file.write('\n\t\t\t\tTypedIndex: %i' % i) + file.write('\n\t\t\t}') + + if do_textures: + + file.write(''' + LayerElement: { + Type: "LayerElementTexture"''') + + file.write('\n\t\t\t\tTypedIndex: %i' % i) + file.write('\n\t\t\t}') + + file.write('\n\t\t}') + + if len(collayers) > 1: + # Take into account any UV layers + layer_offset = 0 + if uvlayers: layer_offset = len(uvlayers)-1 + + for i in xrange(layer_offset, len(collayers)+layer_offset): + file.write('\n\t\tLayer: %i {' % i) + file.write('\n\t\t\tVersion: 100') + + file.write(''' + LayerElement: { + Type: "LayerElementColor"''') + + file.write('\n\t\t\t\tTypedIndex: %i' % i) + file.write('\n\t\t\t}') + file.write('\n\t\t}') + file.write('\n\t}') + + def write_group(name): + file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name) + + file.write(''' + Properties60: { + Property: "MultiLayer", "bool", "",0 + Property: "Pickable", "bool", "",1 + Property: "Transformable", "bool", "",1 + Property: "Show", "bool", "",1 + } + MultiLayer: 0 + }''') + + + # add meshes here to clear because they are not used anywhere. + meshes_to_clear = [] + + ob_meshes = [] + ob_lights = [] + ob_cameras = [] + # in fbx we export bones as children of the mesh + # armatures not a part of a mesh, will be added to ob_arms + ob_bones = [] + ob_arms = [] + ob_null = [] # emptys + + # List of types that have blender objects (not bones) + ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null] + + groups = [] # blender groups, only add ones that have objects in the selections + materials = {} # (mat, image) keys, should be a set() + textures = {} # should be a set() + + tmp_ob_type = ob_type = None # incase no objects are exported, so as not to raise an error + + # if EXP_OBS_SELECTED is false, use sceens objects + if not batch_objects: + if EXP_OBS_SELECTED: tmp_objects = sce.objects.context + else: tmp_objects = sce.objects + else: + tmp_objects = batch_objects + + if EXP_ARMATURE: + # This is needed so applying modifiers dosnt apply the armature deformation, its also needed + # ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes. + # set every armature to its rest, backup the original values so we done mess up the scene + ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures] + + for arm in bpy.data.armatures: + arm.restPosition = True + + if ob_arms_orig_rest: + for ob_base in bpy.data.objects: + #if ob_base.type == 'Armature': + ob_base.makeDisplayList() + + # This causes the makeDisplayList command to effect the mesh + Blender.Set('curframe', Blender.Get('curframe')) + + + for ob_base in tmp_objects: + for ob, mtx in BPyObject.getDerivedObjects(ob_base): + #for ob in [ob_base,]: + tmp_ob_type = ob.type + if tmp_ob_type == 'Camera': + if EXP_CAMERA: + ob_cameras.append(my_object_generic(ob, mtx)) + elif tmp_ob_type == 'Lamp': + if EXP_LAMP: + ob_lights.append(my_object_generic(ob, mtx)) + elif tmp_ob_type == 'Armature': + if EXP_ARMATURE: + # TODO - armatures dont work in dupligroups! + if ob not in ob_arms: ob_arms.append(ob) + # ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)" + elif tmp_ob_type == 'Empty': + if EXP_EMPTY: + ob_null.append(my_object_generic(ob, mtx)) + elif EXP_MESH: + origData = True + if tmp_ob_type != 'Mesh': + me = bpy.data.meshes.new() + try: me.getFromObject(ob) + except: me = None + if me: + meshes_to_clear.append( me ) + mats = me.materials + origData = False + else: + # Mesh Type! + if EXP_MESH_APPLY_MOD: + me = bpy.data.meshes.new() + me.getFromObject(ob) + + # so we keep the vert groups + if EXP_ARMATURE: + orig_mesh = ob.getData(mesh=1) + if orig_mesh.getVertGroupNames(): + ob.copy().link(me) + # If new mesh has no vgroups we can try add if verts are teh same + if not me.getVertGroupNames(): # vgroups were not kept by the modifier + if len(me.verts) == len(orig_mesh.verts): + groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh) + BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) + + # print ob, me, me.getVertGroupNames() + meshes_to_clear.append( me ) + origData = False + mats = me.materials + else: + me = ob.getData(mesh=1) + mats = me.materials + + # Support object colors + tmp_colbits = ob.colbits + if tmp_colbits: + tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too. + for i in xrange(16): + if tmp_colbits & (1< fbxObject mapping + # this is needed for groups as well as fbxParenting + bpy.data.objects.tag = False + tmp_obmapping = {} + for ob_generic in ob_all_typegroups: + for ob_base in ob_generic: + ob_base.blenObject.tag = True + tmp_obmapping[ob_base.blenObject] = ob_base + + # Build Groups from objects we export + for blenGroup in bpy.data.groups: + fbxGroupName = None + for ob in blenGroup.objects: + if ob.tag: + if fbxGroupName == None: + fbxGroupName = sane_groupname(blenGroup) + groups.append((fbxGroupName, blenGroup)) + + tmp_obmapping[ob].fbxGroupNames.append(fbxGroupName) # also adds to the objects fbxGroupNames + + groups.sort() # not really needed + + # Assign parents using this mapping + for ob_generic in ob_all_typegroups: + for my_ob in ob_generic: + parent = my_ob.blenObject.parent + if parent and parent.tag: # does it exist and is it in the mapping + my_ob.fbxParent = tmp_obmapping[parent] + + + del tmp_obmapping + # Finished finding groups we use + + + materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.iterkeys()] + textures = [(sane_texname(tex), tex) for tex in textures.iterkeys() if tex] + materials.sort() # sort by name + textures.sort() + + camera_count = 8 + file.write(''' + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: %i''' % (\ + 1+1+camera_count+\ + len(ob_meshes)+\ + len(ob_lights)+\ + len(ob_cameras)+\ + len(ob_arms)+\ + len(ob_null)+\ + len(ob_bones)+\ + bone_deformer_count+\ + len(materials)+\ + (len(textures)*2))) # add 1 for the root model 1 for global settings + + del bone_deformer_count + + file.write(''' + ObjectType: "Model" { + Count: %i + }''' % (\ + 1+camera_count+\ + len(ob_meshes)+\ + len(ob_lights)+\ + len(ob_cameras)+\ + len(ob_arms)+\ + len(ob_null)+\ + len(ob_bones))) # add 1 for the root model + + file.write(''' + ObjectType: "Geometry" { + Count: %i + }''' % len(ob_meshes)) + + if materials: + file.write(''' + ObjectType: "Material" { + Count: %i + }''' % len(materials)) + + if textures: + file.write(''' + ObjectType: "Texture" { + Count: %i + }''' % len(textures)) # add 1 for an empty tex + file.write(''' + ObjectType: "Video" { + Count: %i + }''' % len(textures)) # add 1 for an empty tex + + tmp = 0 + # Add deformer nodes + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + tmp+=1 + + # Add subdeformers + for my_bone in ob_bones: + tmp += len(my_bone.blenMeshes) + + if tmp: + file.write(''' + ObjectType: "Deformer" { + Count: %i + }''' % tmp) + del tmp + + # we could avoid writing this possibly but for now just write it + + file.write(''' + ObjectType: "Pose" { + Count: 1 + }''') + + if groups: + file.write(''' + ObjectType: "GroupSelection" { + Count: %i + }''' % len(groups)) + + file.write(''' + ObjectType: "GlobalSettings" { + Count: 1 + } +}''') + + file.write(''' + +; Object properties +;------------------------------------------------------------------ + +Objects: {''') + + # To comply with other FBX FILES + write_camera_switch() + + # Write the null object + write_null(None, 'blend_root')# , GLOBAL_MATRIX) + + for my_null in ob_null: + write_null(my_null) + + for my_arm in ob_arms: + write_null(my_arm) + + for my_cam in ob_cameras: + write_camera(my_cam) + + for my_light in ob_lights: + write_light(my_light) + + for my_mesh in ob_meshes: + write_mesh(my_mesh) + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + write_bone(my_bone) + + write_camera_default() + + for matname, (mat, tex) in materials: + write_material(matname, mat) # We only need to have a material per image pair, but no need to write any image info into the material (dumb fbx standard) + + # each texture uses a video, odd + for texname, tex in textures: + write_video(texname, tex) + i = 0 + for texname, tex in textures: + write_texture(texname, tex, i) + i+=1 + + for groupname, group in groups: + write_group(groupname) + + # NOTE - c4d and motionbuilder dont need normalized weights, but deep-exploration 5 does and (max?) do. + + # Write armature modifiers + # TODO - add another MODEL? - because of this skin definition. + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + write_deformer_skin(my_mesh.fbxName) + + # Get normalized weights for temorary use + if my_mesh.fbxBoneParent: + weights = None + else: + weights = meshNormalizedWeights(my_mesh.blenData) + + #for bonename, bone, obname, bone_mesh, armob in ob_bones: + for my_bone in ob_bones: + if me in my_bone.blenMeshes.itervalues(): + write_sub_deformer_skin(my_mesh, my_bone, weights) + + # Write pose's really weired, only needed when an armature and mesh are used together + # each by themselves dont need pose data. for now only pose meshes and bones + + file.write(''' + Pose: "Pose::BIND_POSES", "BindPose" { + Type: "BindPose" + Version: 100 + Properties60: { + } + NbPoseNodes: ''') + file.write(str(len(pose_items))) + + + for fbxName, matrix in pose_items: + file.write('\n\t\tPoseNode: {') + file.write('\n\t\t\tNode: "Model::%s"' % fbxName ) + if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix)) + else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity)) + file.write('\n\t\t}') + + file.write('\n\t}') + + + # Finish Writing Objects + # Write global settings + file.write(''' + GlobalSettings: { + Version: 1000 + Properties60: { + Property: "UpAxis", "int", "",1 + Property: "UpAxisSign", "int", "",1 + Property: "FrontAxis", "int", "",2 + Property: "FrontAxisSign", "int", "",1 + Property: "CoordAxis", "int", "",0 + Property: "CoordAxisSign", "int", "",1 + Property: "UnitScaleFactor", "double", "",100 + } + } +''') + file.write('}') + + file.write(''' + +; Object relations +;------------------------------------------------------------------ + +Relations: {''') + + file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}') + + for my_null in ob_null: + file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_null.fbxName) + + for my_arm in ob_arms: + file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_arm.fbxName) + + for my_mesh in ob_meshes: + file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % my_mesh.fbxName) + + # TODO - limbs can have the same name for multiple armatures, should prefix. + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + file.write('\n\tModel: "Model::%s", "Limb" {\n\t}' % my_bone.fbxName) + + for my_cam in ob_cameras: + file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % my_cam.fbxName) + + for my_light in ob_lights: + file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % my_light.fbxName) + + file.write(''' + Model: "Model::Producer Perspective", "Camera" { + } + Model: "Model::Producer Top", "Camera" { + } + Model: "Model::Producer Bottom", "Camera" { + } + Model: "Model::Producer Front", "Camera" { + } + Model: "Model::Producer Back", "Camera" { + } + Model: "Model::Producer Right", "Camera" { + } + Model: "Model::Producer Left", "Camera" { + } + Model: "Model::Camera Switcher", "CameraSwitcher" { + }''') + + for matname, (mat, tex) in materials: + file.write('\n\tMaterial: "Material::%s", "" {\n\t}' % matname) + + if textures: + for texname, tex in textures: + file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {\n\t}' % texname) + for texname, tex in textures: + file.write('\n\tVideo: "Video::%s", "Clip" {\n\t}' % texname) + + # deformers - modifiers + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {\n\t}' % my_mesh.fbxName) + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + for fbxMeshObName in my_bone.blenMeshes: # .keys() - fbxMeshObName + # is this bone effecting a mesh? + file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {\n\t}' % (fbxMeshObName, my_bone.fbxName)) + + # This should be at the end + # file.write('\n\tPose: "Pose::BIND_POSES", "BindPose" {\n\t}') + + for groupname, group in groups: + file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {\n\t}' % groupname) + + file.write('\n}') + file.write(''' + +; Object connections +;------------------------------------------------------------------ + +Connections: {''') + + # NOTE - The FBX SDK dosnt care about the order but some importers DO! + # for instance, defining the material->mesh connection + # before the mesh->blend_root crashes cinema4d + + + # write the fake root node + file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"') + + for ob_generic in ob_all_typegroups: # all blender 'Object's we support + for my_ob in ob_generic: + if my_ob.fbxParent: + file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_ob.fbxName, my_ob.fbxParent.fbxName)) + else: + file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_ob.fbxName) + + if materials: + for my_mesh in ob_meshes: + # Connect all materials to all objects, not good form but ok for now. + for mat, tex in my_mesh.blenMaterials: + if mat: mat_name = mat.name + else: mat_name = None + + if tex: tex_name = tex.name + else: tex_name = None + + file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat_name, tex_name], my_mesh.fbxName)) + + if textures: + for my_mesh in ob_meshes: + if my_mesh.blenTextures: + # file.write('\n\tConnect: "OO", "Texture::_empty_", "Model::%s"' % my_mesh.fbxName) + for tex in my_mesh.blenTextures: + if tex: + file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (sane_name_mapping_tex[tex.name], my_mesh.fbxName)) + + for texname, tex in textures: + file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname)) + + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName)) + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + for fbxMeshObName in my_bone.blenMeshes: # .keys() + file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName)) + + # limbs -> deformers + # for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + for fbxMeshObName in my_bone.blenMeshes: # .keys() + file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName)) + + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + # Always parent to armature now + if my_bone.parent: + file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.parent.fbxName) ) + else: + # the armature object is written as an empty and all root level bones connect to it + file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.fbxArm.fbxName) ) + + # groups + if groups: + for ob_generic in ob_all_typegroups: + for ob_base in ob_generic: + for fbxGroupName in ob_base.fbxGroupNames: + file.write('\n\tConnect: "OO", "Model::%s", "GroupSelection::%s"' % (ob_base.fbxName, fbxGroupName)) + + for my_arm in ob_arms: + file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_arm.fbxName) + + file.write('\n}') + + + # Needed for scene footer as well as animation + render = sce.render + + # from the FBX sdk + #define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000)) + def fbx_time(t): + # 0.5 + val is the same as rounding. + return int(0.5 + ((t/fps) * 46186158000)) + + fps = float(render.fps) + start = render.sFrame + end = render.eFrame + if end < start: start, end = end, start + if start==end: ANIM_ENABLE = False + + # animations for these object types + ob_anim_lists = ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms + + if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]: + + frame_orig = Blender.Get('curframe') + + if ANIM_OPTIMIZE: + ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION + + # default action, when no actions are avaioable + tmp_actions = [None] # None is the default action + blenActionDefault = None + action_lastcompat = None + + if ANIM_ACTION_ALL: + bpy.data.actions.tag = False + tmp_actions = list(bpy.data.actions) + + + # find which actions are compatible with the armatures + # blenActions is not yet initialized so do it now. + tmp_act_count = 0 + for my_arm in ob_arms: + + # get the default name + if not blenActionDefault: + blenActionDefault = my_arm.blenAction + + arm_bone_names = set([my_bone.blenName for my_bone in my_arm.fbxBones]) + + for action in tmp_actions: + + action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) ) + + if action_chan_names: # at least one channel matches. + my_arm.blenActionList.append(action) + action.tag = True + tmp_act_count += 1 + + # incase there is no actions applied to armatures + action_lastcompat = action + + if tmp_act_count: + # unlikely to ever happen but if no actions applied to armatures, just use the last compatible armature. + if not blenActionDefault: + blenActionDefault = action_lastcompat + + del action_lastcompat + + file.write(''' +;Takes and animation section +;---------------------------------------------------- + +Takes: {''') + + if blenActionDefault: + file.write('\n\tCurrent: "%s"' % sane_takename(blenActionDefault)) + else: + file.write('\n\tCurrent: "Default Take"') + + for blenAction in tmp_actions: + # we have tagged all actious that are used be selected armatures + if blenAction: + if blenAction.tag: + print '\taction: "%s" exporting...' % blenAction.name + else: + print '\taction: "%s" has no armature using it, skipping' % blenAction.name + continue + + if blenAction == None: + # Warning, this only accounts for tmp_actions being [None] + file.write('\n\tTake: "Default Take" {') + act_start = start + act_end = end + else: + # use existing name + if blenAction == blenActionDefault: # have we alredy got the name + file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name]) + else: + file.write('\n\tTake: "%s" {' % sane_takename(blenAction)) + + tmp = blenAction.getFrameNumbers() + if tmp: + act_start = min(tmp) + act_end = max(tmp) + del tmp + else: + # Fallback on this, theres not much else we can do? :/ + # when an action has no length + act_start = start + act_end = end + + # Set the action active + for my_bone in ob_arms: + if blenAction in my_bone.blenActionList: + ob.action = blenAction + # print '\t\tSetting Action!', blenAction + # sce.update(1) + + file.write('\n\t\tFileName: "Default_Take.tak"') # ??? - not sure why this is needed + file.write('\n\t\tLocalTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed + file.write('\n\t\tReferenceTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed + + file.write(''' + + ;Models animation + ;----------------------------------------------------''') + + + # set pose data for all bones + # do this here incase the action changes + ''' + for my_bone in ob_bones: + my_bone.flushAnimData() + ''' + i = act_start + while i <= act_end: + Blender.Set('curframe', i) + for ob_generic in ob_anim_lists: + for my_ob in ob_generic: + #Blender.Window.RedrawAll() + if ob_generic == ob_meshes and my_ob.fbxArm: + # We cant animate armature meshes! + pass + else: + my_ob.setPoseFrame(i) + + i+=1 + + + #for bonename, bone, obname, me, armob in ob_bones: + for ob_generic in (ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms): + + for my_ob in ob_generic: + + if ob_generic == ob_meshes and my_ob.fbxArm: + # do nothing, + pass + else: + + file.write('\n\t\tModel: "Model::%s" {' % my_ob.fbxName) # ??? - not sure why this is needed + file.write('\n\t\t\tVersion: 1.1') + file.write('\n\t\t\tChannel: "Transform" {') + + context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in xrange(act_start, act_end+1) ] + + # ---------------- + # ---------------- + for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale + + if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats] + elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats] + elif TX_CHAN=='R': + # Was.... + # elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats] + # + # ...but we need to use the previous euler for compatible conversion. + context_bone_anim_vecs = [] + prev_eul = None + for mtx in context_bone_anim_mats: + if prev_eul: prev_eul = mtx[1].toEuler(prev_eul) + else: prev_eul = mtx[1].toEuler() + context_bone_anim_vecs.append(prev_eul) + + file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation + + for i in xrange(3): + # Loop on each axis of the bone + file.write('\n\t\t\t\t\tChannel: "%s" {'% ('XYZ'[i])) # translation + file.write('\n\t\t\t\t\t\tDefault: %.15f' % context_bone_anim_vecs[0][i] ) + file.write('\n\t\t\t\t\t\tKeyVer: 4005') + + if not ANIM_OPTIMIZE: + # Just write all frames, simple but in-eficient + file.write('\n\t\t\t\t\t\tKeyCount: %i' % (1 + act_end - act_start)) + file.write('\n\t\t\t\t\t\tKey: ') + frame = act_start + while frame <= act_end: + if frame!=act_start: + file.write(',') + + # Curve types are 'C,n' for constant, 'L' for linear + # C,n is for bezier? - linear is best for now so we can do simple keyframe removal + file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) + frame+=1 + else: + # remove unneeded keys, j is the frame, needed when some frames are removed. + context_bone_anim_keys = [ (vec[i], j) for j, vec in enumerate(context_bone_anim_vecs) ] + + # last frame to fisrt frame, missing 1 frame on either side. + # removeing in a backwards loop is faster + #for j in xrange( (act_end-act_start)-1, 0, -1 ): + # j = (act_end-act_start)-1 + j = len(context_bone_anim_keys)-2 + while j > 0 and len(context_bone_anim_keys) > 2: + # print j, len(context_bone_anim_keys) + # Is this key the same as the ones next to it? + + # co-linear horizontal... + if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\ + abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + + del context_bone_anim_keys[j] + + else: + frame_range = float(context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j-1][1]) + frame_range_fac1 = (context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j][1]) / frame_range + frame_range_fac2 = 1.0 - frame_range_fac1 + + if abs(((context_bone_anim_keys[j-1][0]*frame_range_fac1 + context_bone_anim_keys[j+1][0]*frame_range_fac2)) - context_bone_anim_keys[j][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + del context_bone_anim_keys[j] + else: + j-=1 + + # keep the index below the list length + if j > len(context_bone_anim_keys)-2: + j = len(context_bone_anim_keys)-2 + + if len(context_bone_anim_keys) == 2 and context_bone_anim_keys[0][0] == context_bone_anim_keys[1][0]: + # This axis has no moton, its okay to skip KeyCount and Keys in this case + pass + else: + # We only need to write these if there is at least one + file.write('\n\t\t\t\t\t\tKeyCount: %i' % len(context_bone_anim_keys)) + file.write('\n\t\t\t\t\t\tKey: ') + for val, frame in context_bone_anim_keys: + if frame != context_bone_anim_keys[0][1]: # not the first + file.write(',') + # frame is alredy one less then blenders frame + file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val )) + + if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0') + elif i==1: file.write('\n\t\t\t\t\t\tColor: 0,1,0') + elif i==2: file.write('\n\t\t\t\t\t\tColor: 0,0,1') + + file.write('\n\t\t\t\t\t}') + file.write('\n\t\t\t\t\tLayerType: %i' % (TX_LAYER+1) ) + file.write('\n\t\t\t\t}') + + # --------------- + + file.write('\n\t\t\t}') + file.write('\n\t\t}') + + # end the take + file.write('\n\t}') + + # end action loop. set original actions + # do this after every loop incase actions effect eachother. + for my_bone in ob_arms: + my_bone.blenObject.action = my_bone.blenAction + + file.write('\n}') + + Blender.Set('curframe', frame_orig) + + else: + # no animation + file.write('\n;Takes and animation section') + file.write('\n;----------------------------------------------------') + file.write('\n') + file.write('\nTakes: {') + file.write('\n\tCurrent: ""') + file.write('\n}') + + + # write meshes animation + #for obname, ob, mtx, me, mats, arm, armname in ob_meshes: + + + # Clear mesh data Only when writing with modifiers applied + for me in meshes_to_clear: + me.verts = None + + + + # --------------------------- Footer + if world: + has_mist = world.mode & 1 + mist_intense, mist_start, mist_end, mist_height = world.mist + world_hor = world.hor + else: + has_mist = mist_intense = mist_start = mist_end = mist_height = 0 + world_hor = 0,0,0 + + file.write('\n;Version 5 settings') + file.write('\n;------------------------------------------------------------------') + file.write('\n') + file.write('\nVersion5: {') + file.write('\n\tAmbientRenderSettings: {') + file.write('\n\t\tVersion: 101') + file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world_amb)) + file.write('\n\t}') + file.write('\n\tFogOptions: {') + file.write('\n\t\tFlogEnable: %i' % has_mist) + file.write('\n\t\tFogMode: 0') + file.write('\n\t\tFogDensity: %.3f' % mist_intense) + file.write('\n\t\tFogStart: %.3f' % mist_start) + file.write('\n\t\tFogEnd: %.3f' % mist_end) + file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world_hor)) + file.write('\n\t}') + file.write('\n\tSettings: {') + file.write('\n\t\tFrameRate: "%i"' % int(fps)) + file.write('\n\t\tTimeFormat: 1') + file.write('\n\t\tSnapOnFrames: 0') + file.write('\n\t\tReferenceTimeIndex: -1') + file.write('\n\t\tTimeLineStartTime: %i' % fbx_time(start-1)) + file.write('\n\t\tTimeLineStopTime: %i' % fbx_time(end-1)) + file.write('\n\t}') + file.write('\n\tRendererSetting: {') + file.write('\n\t\tDefaultCamera: "Producer Perspective"') + file.write('\n\t\tDefaultViewingMode: 0') + file.write('\n\t}') + file.write('\n}') + file.write('\n') + + # Incase sombody imports this, clean up by clearing global dicts + sane_name_mapping_ob.clear() + sane_name_mapping_mat.clear() + sane_name_mapping_tex.clear() + + ob_arms[:] = [] + ob_bones[:] = [] + ob_cameras[:] = [] + ob_lights[:] = [] + ob_meshes[:] = [] + ob_null[:] = [] + + + # copy images if enabled + if EXP_IMAGE_COPY: + copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) + + print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) + return True + + +# -------------------------------------------- +# UI Function - not a part of the exporter. +# this is to seperate the user interface from the rest of the exporter. +from Blender import Draw, Window +EVENT_NONE = 0 +EVENT_EXIT = 1 +EVENT_REDRAW = 2 +EVENT_FILESEL = 3 + +GLOBALS = {} + +# export opts + +def do_redraw(e,v): GLOBALS['EVENT'] = e + +# toggle between these 2, only allow one on at once +def do_obs_sel(e,v): + GLOBALS['EVENT'] = e + GLOBALS['EXP_OBS_SCENE'].val = 0 + GLOBALS['EXP_OBS_SELECTED'].val = 1 + +def do_obs_sce(e,v): + GLOBALS['EVENT'] = e + GLOBALS['EXP_OBS_SCENE'].val = 1 + GLOBALS['EXP_OBS_SELECTED'].val = 0 + +def do_obs_sce(e,v): + GLOBALS['EVENT'] = e + GLOBALS['EXP_OBS_SCENE'].val = 1 + GLOBALS['EXP_OBS_SELECTED'].val = 0 + +def do_batch_type_grp(e,v): + GLOBALS['EVENT'] = e + GLOBALS['BATCH_GROUP'].val = 1 + GLOBALS['BATCH_SCENE'].val = 0 + +def do_batch_type_sce(e,v): + GLOBALS['EVENT'] = e + GLOBALS['BATCH_GROUP'].val = 0 + GLOBALS['BATCH_SCENE'].val = 1 + +def do_anim_act_all(e,v): + GLOBALS['EVENT'] = e + GLOBALS['ANIM_ACTION_ALL'][0].val = 1 + GLOBALS['ANIM_ACTION_ALL'][1].val = 0 + +def do_anim_act_cur(e,v): + if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val: + Draw.PupMenu('Warning%t|Cant use this with batch export group option') + else: + GLOBALS['EVENT'] = e + GLOBALS['ANIM_ACTION_ALL'][0].val = 0 + GLOBALS['ANIM_ACTION_ALL'][1].val = 1 + +def fbx_ui_exit(e,v): + GLOBALS['EVENT'] = e + +def do_help(e,v): + url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' + print 'Trying to open web browser with documentation at this address...' + print '\t' + url + + try: + import webbrowser + webbrowser.open(url) + except: + Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation") + print '...could not open a browser window.' + + + +# run when export is pressed +#def fbx_ui_write(e,v): +def fbx_ui_write(filename, context): + + # Dont allow overwriting files when saving normally + if not GLOBALS['BATCH_ENABLE'].val: + if not BPyMessages.Warning_SaveOver(filename): + return + + GLOBALS['EVENT'] = EVENT_EXIT + + # Keep the order the same as above for simplicity + # the [] is a dummy arg used for objects + + Blender.Window.WaitCursor(1) + + # Make the matrix + GLOBAL_MATRIX = mtx4_identity + GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val + if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n + if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n + if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n + + ret = write(\ + filename, None,\ + context, + GLOBALS['EXP_OBS_SELECTED'].val,\ + GLOBALS['EXP_MESH'].val,\ + GLOBALS['EXP_MESH_APPLY_MOD'].val,\ + GLOBALS['EXP_MESH_HQ_NORMALS'].val,\ + GLOBALS['EXP_ARMATURE'].val,\ + GLOBALS['EXP_LAMP'].val,\ + GLOBALS['EXP_CAMERA'].val,\ + GLOBALS['EXP_EMPTY'].val,\ + GLOBALS['EXP_IMAGE_COPY'].val,\ + GLOBAL_MATRIX,\ + GLOBALS['ANIM_ENABLE'].val,\ + GLOBALS['ANIM_OPTIMIZE'].val,\ + GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\ + GLOBALS['ANIM_ACTION_ALL'][0].val,\ + GLOBALS['BATCH_ENABLE'].val,\ + GLOBALS['BATCH_GROUP'].val,\ + GLOBALS['BATCH_SCENE'].val,\ + GLOBALS['BATCH_FILE_PREFIX'].val,\ + GLOBALS['BATCH_OWN_DIR'].val,\ + ) + + Blender.Window.WaitCursor(0) + GLOBALS.clear() + + if ret == False: + Draw.PupMenu('Error%t|Path cannot be written to!') + + +def fbx_ui(): + # Only to center the UI + x,y = GLOBALS['MOUSE'] + x-=180; y-=0 # offset... just to get it centered + + Draw.Label('Export Objects...', x+20,y+165, 200, 20) + + if not GLOBALS['BATCH_ENABLE'].val: + Draw.BeginAlign() + GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel) + GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce) + Draw.EndAlign() + + Draw.BeginAlign() + GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)') + GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrese about the X axis') + GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrese about the Y axis') + GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrese about the Z axis') + Draw.EndAlign() + + y -= 35 + + Draw.BeginAlign() + GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects') + GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects') + GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects') + GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects') + GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z) + Draw.EndAlign() + + if GLOBALS['EXP_MESH'].val: + # below mesh but + Draw.BeginAlign() + GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z) + GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z) + Draw.EndAlign() + + GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z) + + + Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20) + + GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw) + if GLOBALS['ANIM_ENABLE'].val: + Draw.BeginAlign() + GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw) + if GLOBALS['ANIM_OPTIMIZE'].val: + GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)') + Draw.EndAlign() + + Draw.BeginAlign() + GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur) + GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all) + Draw.EndAlign() + + + Draw.Label('Export Batch...', x+20,y-60, 300, 20) + GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw) + + if GLOBALS['BATCH_ENABLE'].val: + Draw.BeginAlign() + GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp) + GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce) + + # Own dir requires OS module + if os: + GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file') + GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') + else: + GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') + + + Draw.EndAlign() + + #y+=80 + + ''' + Draw.BeginAlign() + GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ') + Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw) + ''' + # Until batch is added + # + + + #Draw.BeginAlign() + Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help) + Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit) + Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw) + + #Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write) + #Draw.EndAlign() + + # exit when mouse out of the view? + # GLOBALS['EVENT'] = EVENT_EXIT + +#def write_ui(filename): +def write_ui(): + + # globals + GLOBALS['EVENT'] = EVENT_REDRAW + #GLOBALS['MOUSE'] = Window.GetMouseCoords() + GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] + GLOBALS['FILENAME'] = '' + ''' + # IF called from the fileselector + if filename == None: + GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx')) + else: + GLOBALS['FILENAME'].val = filename + ''' + GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity + GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0) + + GLOBALS['EXP_MESH'] = Draw.Create(1) + GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1) + GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0) + GLOBALS['EXP_ARMATURE'] = Draw.Create(1) + GLOBALS['EXP_LAMP'] = Draw.Create(1) + GLOBALS['EXP_CAMERA'] = Draw.Create(1) + GLOBALS['EXP_EMPTY'] = Draw.Create(1) + GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0) + # animation opts + GLOBALS['ANIM_ENABLE'] = Draw.Create(1) + GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1) + GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places + GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action + + # batch export options + GLOBALS['BATCH_ENABLE'] = Draw.Create(0) + GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once. + GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above + GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1]) + GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0) + # done setting globals + + # Used by the user interface + GLOBALS['_SCALE'] = Draw.Create(1.0) + GLOBALS['_XROT90'] = Draw.Create(True) + GLOBALS['_YROT90'] = Draw.Create(False) + GLOBALS['_ZROT90'] = Draw.Create(False) + + # best not do move the cursor + # Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()]) + + # hack so the toggle buttons redraw. this is not nice at all + while GLOBALS['EVENT'] != EVENT_EXIT: + + if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val: + #Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ") + GLOBALS['ANIM_ACTION_ALL'][0].val = 1 + GLOBALS['ANIM_ACTION_ALL'][1].val = 0 + + if GLOBALS['EVENT'] == EVENT_FILESEL: + if GLOBALS['BATCH_ENABLE'].val: + txt = 'Batch FBX Dir' + name = Blender.sys.expandpath('//') + else: + txt = 'Export FBX' + name = Blender.sys.makename(ext='.fbx') + + Blender.Window.FileSelector(fbx_ui_write, txt, name) + #fbx_ui_write('/test.fbx') + break + + Draw.UIBlock(fbx_ui, 0) + + + # GLOBALS.clear() +#test = [write_ui] +if __name__ == '__main__': + # Cant call the file selector first because of a bug in the interface that crashes it. + # Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx')) + #write('/scratch/test.fbx') + #write_ui('/scratch/test.fbx') + + if not set: + Draw.PupMenu('Error%t|A full install of python2.3 or python 2.4+ is needed to run this script.') + else: + write_ui() + +# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts) +# +# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print +# - get rid of cleanName somehow +# - new scene creation, activation: lines 327-342, 368 + +# TODO + +# bpy.data.remove_scene: line 366 diff --git a/release/io/export_obj.py b/release/io/export_obj.py index ee045053dd3..26e6e248a45 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -962,3 +962,4 @@ if __name__ == "__main__": # - NURBS - needs API additions # - all scenes export # - normals calculation +# - get rid of cleanName somehow diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index caa970eff57..dc519e9ec6e 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -609,6 +609,16 @@ static void rna_def_bone(BlenderRNA *brna) prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED); RNA_def_property_ui_text(prop, "Selected", ""); + + prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "bone_mat"); + RNA_def_property_array(prop, 9); + RNA_def_property_ui_text(prop, "Bone Matrix", "3x3 bone matrix."); + + prop= RNA_def_property(srna, "armature_matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "arm_mat"); + RNA_def_property_array(prop, 16); + RNA_def_property_ui_text(prop, "Bone Armature Matrix", "4x4 bone matrix relative to armature."); } static void rna_def_edit_bone(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_pose_api.c b/source/blender/makesrna/intern/rna_pose_api.c new file mode 100644 index 00000000000..c0bf3339f4f --- /dev/null +++ b/source/blender/makesrna/intern/rna_pose_api.c @@ -0,0 +1,56 @@ +/** + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "DNA_object_types.h" + +/* #include "BLO_sys_types.h" */ + +#ifdef RNA_RUNTIME + +/* #include "DNA_anim_types.h" */ +#include "DNA_action_types.h" /* bPose */ + +#else + +void RNA_api_pose(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + +} + +#endif + -- cgit v1.2.3 From f90a0b838321cfa11cda2fd65d820a6f39a06e5c Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 8 Jul 2009 10:40:26 +0000 Subject: Added local stack during bvh transversal --- .../blender/render/intern/source/rayobject_bvh.c | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 62adcb75b7c..33821db0905 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -37,6 +37,7 @@ #include "rayobject_rtbuild.h" #include "rayobject.h" +#define DFS_STACK_SIZE 64 #define DYNAMIC_ALLOC //#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */ @@ -47,6 +48,7 @@ typedef struct BVHTree BVHTree; static int bvh_intersect(BVHTree *obj, Isect *isec); +static int bvh_intersect_stack(BVHTree *obj, Isect *isec); static void bvh_add(BVHTree *o, RayObject *ob); static void bvh_done(BVHTree *o); static void bvh_free(BVHTree *o); @@ -54,7 +56,11 @@ static void bvh_bb(BVHTree *o, float *min, float *max); static RayObjectAPI bvh_api = { +#ifdef DFS_STACK_SIZE + (RE_rayobject_raycast_callback) bvh_intersect_stack, +#else (RE_rayobject_raycast_callback) bvh_intersect, +#endif (RE_rayobject_add_callback) bvh_add, (RE_rayobject_done_callback) bvh_done, (RE_rayobject_free_callback) bvh_free, @@ -150,6 +156,55 @@ static void bvh_bb(BVHTree *obj, float *min, float *max) /* * Tree transverse */ +static int dfs_raycast_stack(BVHNode *root, Isect *isec) +{ + BVHNode *stack[DFS_STACK_SIZE]; + int hit = 0, stack_pos = 0; + + stack[stack_pos++] = root; + + while(stack_pos) + { + BVHNode *node = stack[--stack_pos]; + if(RayObject_isAligned(node)) + { + if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) + { + //push nodes in reverse visit order + if(isec->idot_axis[node->split_axis] < 0.0f) + { + int i; + for(i=0; ichild[i] == 0) break; + else stack[stack_pos++] = node->child[i]; + } + else + { + int i; + for(i=0; ichild[i] != 0) stack[stack_pos++] = node->child[i]; + else break; + } + assert(stack_pos <= DFS_STACK_SIZE); + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node, isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + return hit; +} + +static int bvh_intersect_stack(BVHTree *obj, Isect *isec) +{ + if(RayObject_isAligned(obj->root)) + return dfs_raycast_stack(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*)obj->root, isec); +} + static int dfs_raycast(BVHNode *node, Isect *isec) { int hit = 0; -- cgit v1.2.3 From f13d11ab712d22dc96dab594775f165eba1260ea Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 8 Jul 2009 15:34:41 +0000 Subject: Hint support (only for first hiearchic level and shadow rays, lets see if this is useful) That means each shadow ray tests: 1st: last hit face 2nd: last hit object 3rd: tree of all objects --- source/blender/render/extern/include/RE_raytrace.h | 16 ++++--- source/blender/render/intern/source/rayobject.c | 45 +++++++++++++------ .../blender/render/intern/source/rayobject_bvh.c | 50 ++++++++++++++++++++-- source/blender/render/intern/source/rayshade.c | 6 +++ 4 files changed, 96 insertions(+), 21 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index fdd49cf1216..ce21bb1c858 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -31,7 +31,10 @@ #ifndef RE_RAYTRACE_H #define RE_RAYTRACE_H +#define RT_USE_HINT /* 1 level hint */ #define RE_RAYCOUNTER + + #ifdef RE_RAYCOUNTER typedef struct RayCounter RayCounter; @@ -42,9 +45,7 @@ struct RayCounter { unsigned long long test, hit; - } faces, bb, raycast; - - unsigned long long rayshadow_last_hit_optimization; + } faces, bb, raycast, raytrace_hint, rayshadow_last_hit; }; /* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ @@ -68,6 +69,9 @@ extern RayCounter re_rc_counter[]; /* Internals about raycasting structures can be found on intern/raytree.h */ typedef struct RayObject RayObject; typedef struct Isect Isect; + +typedef struct RayTraceHint RayTraceHint; + struct DerivedMesh; struct Mesh; @@ -97,7 +101,6 @@ struct Isect int bv_index[6]; float idot_axis[3]; float dist; - /* float end[3]; - not used */ @@ -107,11 +110,14 @@ struct Isect { void *ob; void *face; -/* RayObject *obj; */ } hit, orig; RayObject *last_hit; /* last hit optimization */ + +#ifdef RT_USE_HINT + RayTraceHint *hint, *hit_hint; +#endif short isect; /* which half of quad */ short mode; /* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */ diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index e9cf46d0734..49d6e7cbefc 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -317,23 +317,34 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) /* Last hit heuristic */ - if(isec->mode==RE_RAY_SHADOW && isec->last_hit && RE_rayobject_intersect(isec->last_hit, isec)) + if(isec->mode==RE_RAY_SHADOW && isec->last_hit) { - RE_RC_COUNT(isec->raycounter->raycast.hit); - RE_RC_COUNT(isec->raycounter->rayshadow_last_hit_optimization ); - return 1; + RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test); + + if(RE_rayobject_intersect(isec->last_hit, isec)) + { + RE_RC_COUNT(isec->raycounter->raycast.hit); + RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit); + return 1; + } } -#ifdef RE_RAYCOUNTER +#ifdef RT_USE_HINT + isec->hit_hint = 0; +#endif + if(RE_rayobject_intersect(r, isec)) { +#ifdef RE_RAYCOUNTER RE_RC_COUNT(isec->raycounter->raycast.hit); +#endif + +#ifdef RT_USE_HINT + isec->hint = isec->hit_hint; +#endif return 1; } return 0; -#else - return RE_rayobject_intersect(r, isec); -#endif } int RE_rayobject_intersect(RayObject *r, Isect *i) @@ -398,15 +409,19 @@ void RE_RC_INFO(RayCounter *info) printf("\n"); printf("Primitives tests: %llu\n", info->faces.test ); printf("Primitives hits: %llu\n", info->faces.hit ); + printf("------------------------------------\n"); + printf("Shadow last-hit tests per ray: %f\n", info->rayshadow_last_hit.test / ((float)info->raycast.test) ); + printf("Shadow last-hit hits per ray: %f\n", info->rayshadow_last_hit.hit / ((float)info->raycast.test) ); printf("\n"); - printf("Shadow Last hit reuse: %llu\n", info->rayshadow_last_hit_optimization); - printf("\n"); - printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); - printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); + printf("Hint tests per ray: %f\n", info->raytrace_hint.test / ((float)info->raycast.test) ); + printf("Hint hits per ray: %f\n", info->raytrace_hint.hit / ((float)info->raycast.test) ); printf("\n"); printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) ); printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) ); printf("\n"); + printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); + printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); + printf("------------------------------------\n"); } void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) @@ -420,7 +435,11 @@ void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) dest->raycast.test += tmp->raycast.test; dest->raycast.hit += tmp->raycast.hit; - dest->rayshadow_last_hit_optimization += tmp->rayshadow_last_hit_optimization; + dest->rayshadow_last_hit.test += tmp->rayshadow_last_hit.test; + dest->rayshadow_last_hit.hit += tmp->rayshadow_last_hit.hit; + + dest->raytrace_hint.test += tmp->raytrace_hint.test; + dest->raytrace_hint.hit += tmp->raytrace_hint.hit; } #endif \ No newline at end of file diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 33821db0905..6f3a829ce6e 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -160,6 +160,9 @@ static int dfs_raycast_stack(BVHNode *root, Isect *isec) { BVHNode *stack[DFS_STACK_SIZE]; int hit = 0, stack_pos = 0; +#ifdef RT_USE_HINT + BVHNode *last_processed_node = 0; +#endif stack[stack_pos++] = root; @@ -170,19 +173,29 @@ static int dfs_raycast_stack(BVHNode *root, Isect *isec) { if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) { + last_processed_node = node; //push nodes in reverse visit order if(isec->idot_axis[node->split_axis] < 0.0f) { int i; for(i=0; ichild[i] == 0) break; - else stack[stack_pos++] = node->child[i]; + else +#ifdef RT_USE_HINT + if(node->child[i] != (BVHNode*)isec->hint) +#endif + stack[stack_pos++] = node->child[i]; } else { int i; for(i=0; ichild[i] != 0) stack[stack_pos++] = node->child[i]; + if(node->child[i] != 0 +#ifdef RT_USE_HINT + && node->child[i] != (BVHNode*)isec->hint +#endif + ) + stack[stack_pos++] = node->child[i]; else break; } assert(stack_pos <= DFS_STACK_SIZE); @@ -190,7 +203,19 @@ static int dfs_raycast_stack(BVHNode *root, Isect *isec) } else { - hit |= RE_rayobject_intersect( (RayObject*)node, isec); + int ghit; +#ifdef RT_USE_HINT + RayTraceHint *b_hint = isec->hint; + isec->hint = 0; +#endif + ghit = RE_rayobject_intersect( (RayObject*)node, isec); + +#ifdef RT_USE_HINT + isec->hint = b_hint; + if(ghit) + isec->hit_hint = (RayTraceHint*)last_processed_node; +#endif + hit |= ghit; if(hit && isec->mode == RE_RAY_SHADOW) return hit; } } @@ -200,7 +225,26 @@ static int dfs_raycast_stack(BVHNode *root, Isect *isec) static int bvh_intersect_stack(BVHTree *obj, Isect *isec) { if(RayObject_isAligned(obj->root)) + { +#ifdef RT_USE_HINT + if(isec->hint) + { + int hit; + RE_RC_COUNT(isec->raycounter->raytrace_hint.test); + hit = dfs_raycast_stack((BVHNode*) isec->hint, isec); + if(hit) + { + RE_RC_COUNT(isec->raycounter->raytrace_hint.hit); + + if(isec->mode == RE_RAY_SHADOW) return hit; + } + else isec->hint = 0; //Clear HINT on non-hit?, that sounds good, but no tests where made + + return hit | dfs_raycast_stack(obj->root, isec); + } +#endif return dfs_raycast_stack(obj->root, isec); + } else return RE_rayobject_intersect( (RayObject*)obj->root, isec); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index b70e4bf5000..80ff6f6418c 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -606,6 +606,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; isec.mode= RE_RAY_MIRROR; isec.skip = RE_SKIP_VLR_NEIGHBOUR; + isec.hint = 0; isec.orig.ob = obi; isec.orig.face = vlr; @@ -1511,6 +1512,7 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) isec.mode= RE_RAY_MIRROR; isec.orig.ob = ship->obi; isec.orig.face = ship->vlr; + isec.hint = 0; RE_RC_INIT(isec, shi); for(a=0; a<8*8; a++) { @@ -1720,6 +1722,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; + isec.hint = 0; isec.hit.ob = 0; isec.hit.face = 0; @@ -1854,6 +1857,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; + isec.hint = 0; isec.hit.ob = 0; isec.hit.face = 0; @@ -2290,6 +2294,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) RE_RC_INIT(isec, *shi); if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; else isec.mode= RE_RAY_SHADOW; + isec.hint = 0; if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) isec.lay= lar->lay; @@ -2375,6 +2380,7 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float /* setup isec */ RE_RC_INIT(isec, *shi); isec.mode= RE_RAY_SHADOW_TRA; + isec.hint = 0; if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; -- cgit v1.2.3 From 8105454cba0be3405fc0e6fe95c979f429ed0ca4 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 8 Jul 2009 19:39:37 +0000 Subject: Enabled #ifdefs to test LAST_HIT, LAST_HINT Disable last_hint as it only slow downs --- source/blender/render/extern/include/RE_raytrace.h | 4 +++- source/blender/render/intern/source/rayobject.c | 5 ++++- source/blender/render/intern/source/rayobject_bvh.c | 2 ++ source/blender/render/intern/source/rayshade.c | 12 ++++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index ce21bb1c858..7624cd09edb 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -31,7 +31,9 @@ #ifndef RE_RAYTRACE_H #define RE_RAYTRACE_H -#define RT_USE_HINT /* 1 level hint */ +#define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ +//#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */ + #define RE_RAYCOUNTER diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 49d6e7cbefc..247eb952429 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -288,7 +288,9 @@ static int intersect_rayface(RayFace *face, Isect *is) is->hit.ob = face->ob; is->hit.face = face->face; +#ifdef RT_USE_LAST_HIT is->last_hit = (RayObject*) RayObject_unalignRayFace(face); +#endif return 1; } @@ -315,7 +317,7 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; } - +#ifdef RT_USE_LAST_HIT /* Last hit heuristic */ if(isec->mode==RE_RAY_SHADOW && isec->last_hit) { @@ -328,6 +330,7 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) return 1; } } +#endif #ifdef RT_USE_HINT isec->hit_hint = 0; diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 6f3a829ce6e..a5158d96acc 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -173,7 +173,9 @@ static int dfs_raycast_stack(BVHNode *root, Isect *isec) { if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) { +#ifdef RT_USE_HINT last_processed_node = node; +#endif //push nodes in reverse visit order if(isec->idot_axis[node->split_axis] < 0.0f) { diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 80ff6f6418c..977cba75f55 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -606,7 +606,9 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; isec.mode= RE_RAY_MIRROR; isec.skip = RE_SKIP_VLR_NEIGHBOUR; +#ifdef RT_USE_HINT isec.hint = 0; +#endif isec.orig.ob = obi; isec.orig.face = vlr; @@ -1512,7 +1514,9 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) isec.mode= RE_RAY_MIRROR; isec.orig.ob = ship->obi; isec.orig.face = ship->vlr; +#ifdef RT_USE_HINT isec.hint = 0; +#endif RE_RC_INIT(isec, shi); for(a=0; a<8*8; a++) { @@ -1722,7 +1726,9 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; +#ifdef RT_USE_HINT isec.hint = 0; +#endif isec.hit.ob = 0; isec.hit.face = 0; @@ -1857,7 +1863,9 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; +#ifdef RT_USE_HINT isec.hint = 0; +#endif isec.hit.ob = 0; isec.hit.face = 0; @@ -2294,7 +2302,9 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) RE_RC_INIT(isec, *shi); if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; else isec.mode= RE_RAY_SHADOW; +#ifdef RT_USE_HINT isec.hint = 0; +#endif if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) isec.lay= lar->lay; @@ -2380,7 +2390,9 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float /* setup isec */ RE_RC_INIT(isec, *shi); isec.mode= RE_RAY_SHADOW_TRA; +#ifdef RT_USE_HINT isec.hint = 0; +#endif if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; -- cgit v1.2.3 From 85f6c108aca9f86fb5e219ade03e15791bb822e8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 8 Jul 2009 20:04:40 +0000 Subject: *Added support for variable cost per RayObject Suposedly usefull for creating trees of objects (where objects have very diferent size-NumFaces and shape-BB) Altought the implemented costs maybe not be very correct (for now), as i didnt cared about following a specific "corrected" model --- source/blender/render/intern/include/rayobject.h | 11 ++++++++- .../render/intern/include/rayobject_rtbuild.h | 3 +++ source/blender/render/intern/source/rayobject.c | 14 ++++++++++++ .../blender/render/intern/source/rayobject_bvh.c | 26 +++++++++++++++++----- .../render/intern/source/rayobject_rtbuild.c | 22 ++++++++++++++---- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index c611e2ceca2..de36a1e4888 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -86,11 +86,13 @@ struct RayObject }; + typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *); -typedef void (*RE_rayobject_add_callback)(RayObject *, RayObject *); +typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); typedef void (*RE_rayobject_done_callback)(RayObject *); typedef void (*RE_rayobject_free_callback)(RayObject *); typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); +typedef float (*RE_rayobject_cost_callback)(RayObject *); typedef struct RayObjectAPI { @@ -99,6 +101,7 @@ typedef struct RayObjectAPI RE_rayobject_done_callback done; RE_rayobject_free_callback free; RE_rayobject_merge_bb_callback bb; + RE_rayobject_cost_callback cost; } RayObjectAPI; @@ -128,6 +131,12 @@ int RE_rayobject_intersect(RayObject *r, Isect *i); */ float RE_rayobject_bb_intersect(const Isect *i, const float *bb); +/* + * Returns the expected cost of raycast on this node, primitives have a cost of 1 + */ +float RE_rayobject_cost(RayObject *r); + + #define ISECT_EPSILON ((float)FLT_EPSILON) diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index f27005a2fa7..6fef18433b9 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -80,4 +80,7 @@ int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis) int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); +/* bb utils */ +float bb_area(float *min, float *max); + #endif diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 247eb952429..949b7afb5a0 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -400,6 +400,20 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) else assert(0); } +float RE_rayobject_cost(RayObject *r) +{ + if(RayObject_isRayFace(r)) + { + return 1.0; + } + else if(RayObject_isRayAPI(r)) + { + r = RayObject_align( r ); + return r->api->cost( r ); + } + else assert(0); +} + #ifdef RE_RAYCOUNTER void RE_RC_INFO(RayCounter *info) { diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index a5158d96acc..d0e0e8b6dc5 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -53,6 +53,7 @@ static void bvh_add(BVHTree *o, RayObject *ob); static void bvh_done(BVHTree *o); static void bvh_free(BVHTree *o); static void bvh_bb(BVHTree *o, float *min, float *max); +static float bvh_cost(BVHTree *o); static RayObjectAPI bvh_api = { @@ -64,7 +65,8 @@ static RayObjectAPI bvh_api = (RE_rayobject_add_callback) bvh_add, (RE_rayobject_done_callback) bvh_done, (RE_rayobject_free_callback) bvh_free, - (RE_rayobject_merge_bb_callback)bvh_bb + (RE_rayobject_merge_bb_callback)bvh_bb, + (RE_rayobject_cost_callback) bvh_cost }; typedef struct BVHNode BVHNode; @@ -91,6 +93,7 @@ struct BVHTree BVHNode *node_alloc, *node_next; float *bb_alloc, *bb_next; #endif + float cost; RTBuilder *builder; }; @@ -153,6 +156,12 @@ static void bvh_bb(BVHTree *obj, float *min, float *max) bvh_merge_bb(obj->root, min, max); } +static float bvh_cost(BVHTree *obj) +{ + assert(obj->cost >= 0.0); + return obj->cost; +} + /* * Tree transverse */ @@ -336,8 +345,9 @@ static int child_id(int pid, int nchild) return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; } -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) +static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) { + *cost = 0; if(rtbuild_size(builder) == 0) return 0; @@ -361,6 +371,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) for(; ichild[i] = 0; + *cost = bb_area(parent->bb, parent->bb+3)*RE_rayobject_cost(child); return parent; } else @@ -368,6 +379,8 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) assert(!RayObject_isAligned(child)); //Its a sub-raytrace structure, assume it has it own raycast //methods and adding a Bounding Box arround is unnecessary + + *cost = RE_rayobject_cost(child); return (BVHNode*)child; } } @@ -392,12 +405,16 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid) parent->split_axis = builder->split_axis; for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i) ); + float tcost; + parent->child[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); + + *cost += tcost; } for(; ichild[i] = 0; + *cost *= bb_area(parent->bb, parent->bb+3); return parent; } } @@ -412,7 +429,6 @@ static void bvh_info(BVHTree *obj) static void bvh_done(BVHTree *obj) { - #ifdef DYNAMIC_ALLOC int needed_nodes = (rtbuild_size(obj->builder)+1)*2; if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) @@ -437,7 +453,7 @@ static void bvh_done(BVHTree *obj) obj->bb_next = obj->bb_alloc; #endif - obj->root = bvh_rearrange( obj, obj->builder, 1 ); + obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); #ifndef DYNAMIC_ALLOC assert(obj->node_alloc+needed_nodes >= obj->node_next); diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 688b3a920b4..2d5afe28600 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -216,6 +216,7 @@ typedef struct CostObject CostObject; struct CostObject { RayObject *obj; + float cost; float bb[6]; }; @@ -278,6 +279,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) else { float bcost = FLT_MAX; + float childrens_cost = 0; int i, axis, baxis, boffset, k, try_axis[3]; CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); @@ -286,12 +288,14 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) { cost[i].obj = b->begin[i]; INIT_MINMAX(cost[i].bb, cost[i].bb+3); - RE_rayobject_merge_bb(b->begin[i], cost[i].bb, cost[i].bb+3); + RE_rayobject_merge_bb(cost[i].obj, cost[i].bb, cost[i].bb+3); + cost[i].cost = RE_rayobject_cost(cost[i].obj); + childrens_cost += cost[i].cost; } if(b->child_sorted_axis >= 0 && b->child_sorted_axis < 3) { - try_axis[0] = b->child_sorted_axis; + try_axis[0] = b->child_sorted_axis; try_axis[1] = (b->child_sorted_axis+1)%3; try_axis[2] = (b->child_sorted_axis+2)%3; } @@ -304,8 +308,11 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) for(axis=try_axis[k=0]; k<3; axis=try_axis[++k]) { + float left_cost, right_cost; float other_bb[6]; + + costobject_sort(cost, cost+size, axis); for(i=size-1; i>=0; i--) { @@ -330,18 +337,22 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) INIT_MINMAX(other_bb, other_bb+3); DO_MIN( cost[0].bb, other_bb ); DO_MAX( cost[0].bb+3, other_bb+3 ); + left_cost = cost[0].cost; + right_cost = childrens_cost-cost[0].cost; + if(right_cost < 0) right_cost = 0; for(i=1; i bcost) break; //No way we can find a better heuristic in this axis hcost = left_side+right_side; + assert(hcost >= 0); if( hcost < bcost || (hcost == bcost && axis < baxis)) //this makes sure the tree built is the same whatever is the order of the sorting axis { @@ -351,6 +362,9 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) } DO_MIN( cost[i].bb, other_bb ); DO_MAX( cost[i].bb+3, other_bb+3 ); + left_cost += cost[i].cost; + right_cost -= cost[i].cost; + if(right_cost < 0.0f) right_cost = 0.0; } if(baxis == axis) -- cgit v1.2.3 From 2e4b9f3be4c362ab6f2bb5135c6479ee8b06817d Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 8 Jul 2009 21:56:24 +0000 Subject: *set cost of transversing a BVH as log(size) --- source/blender/render/intern/source/rayobject_bvh.c | 9 +++++++-- source/blender/render/intern/source/rayobject_rtbuild.c | 8 +++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index d0e0e8b6dc5..40719a15f0e 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -28,6 +28,7 @@ */ #include #include +#include #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" @@ -37,6 +38,7 @@ #include "rayobject_rtbuild.h" #include "rayobject.h" +#define RAY_BB_TEST_COST (0.2f) #define DFS_STACK_SIZE 64 #define DYNAMIC_ALLOC @@ -371,7 +373,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float for(; ichild[i] = 0; - *cost = bb_area(parent->bb, parent->bb+3)*RE_rayobject_cost(child); + *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; return parent; } else @@ -414,7 +416,8 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float for(; ichild[i] = 0; - *cost *= bb_area(parent->bb, parent->bb+3); + *cost /= nc*bb_area(parent->bb, parent->bb+3); + *cost += RAY_BB_TEST_COST; return parent; } } @@ -454,6 +457,8 @@ static void bvh_done(BVHTree *obj) #endif obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); +// obj->cost = 1.0; + obj->cost = logf( rtbuild_size( obj->builder ) ); #ifndef DYNAMIC_ALLOC assert(obj->node_alloc+needed_nodes >= obj->node_next); diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 2d5afe28600..46140d3d24d 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -280,7 +280,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) { float bcost = FLT_MAX; float childrens_cost = 0; - int i, axis, baxis, boffset, k, try_axis[3]; + int i, axis, baxis = -1, boffset = size/2, k, try_axis[3]; CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); @@ -346,8 +346,8 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) //Worst case heuristic (cost of each child is linear) float hcost, left_side, right_side; - left_side = bb_area(other_bb, other_bb+3)*left_cost; //(i+logf(i)); - right_side= bb_area(acc_bb+i*6, acc_bb+i*6+3)*right_cost; //(size-i+logf(size-i)); + left_side = bb_area(other_bb, other_bb+3)*(left_cost+logf(i)); + right_side= bb_area(acc_bb+i*6, acc_bb+i*6+3)*(right_cost+logf(i)); if(left_side > bcost) break; //No way we can find a better heuristic in this axis @@ -373,6 +373,8 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) b->begin[i] = cost[i].obj; b->child_sorted_axis = axis; } + + assert(baxis >= 0 && baxis < 3); } b->child_offset[0] = 0; -- cgit v1.2.3 From 797c6a2295f47f1c3a71f9094c710316cdf2ecf3 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 10 Jul 2009 14:46:52 +0000 Subject: - RNA-wrapped Bone props: head, armature_head, tail, armature_tail. - more FBX conversion --- release/io/export_fbx.py | 131 +++++++++++++++++--------- release/io/export_obj.py | 12 +-- source/blender/makesrna/intern/makesrna.c | 2 +- source/blender/makesrna/intern/rna_armature.c | 23 ++++- 4 files changed, 116 insertions(+), 52 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index cea9f500533..59480c4d455 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -210,10 +210,14 @@ def derived_paths(fname_orig, basepath, FORCE_CWD=False): FORCE_CWD - dont use the basepath, just add a ./ to the filename. use when we know the file will be in the basepath. ''' - fname = Blender.sys.expandpath(fname_orig) + fname = bpy.sys.expandpath(fname_orig) +# fname = Blender.sys.expandpath(fname_orig) fname_strip = strip_path(fname) - if FORCE_CWD: fname_rel = '.' + os.sep + fname_strip - else: fname_rel = Blender.sys.relpath(fname, basepath) + if FORCE_CWD: + fname_rel = '.' + os.sep + fname_strip + else: + fname_rel = bpy.sys.relpath(fname, basepath) +# fname_rel = Blender.sys.relpath(fname, basepath) if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:] return fname, fname_strip, fname_rel @@ -414,7 +418,7 @@ def write(filename, batch_objects = None, \ self.blenMeshes = {} # fbxMeshObName : mesh self.fbxArm = fbxArm self.restMatrix = blenBone.armature_matrix - # self.restMatrix = blenBone.matrix['ARMATURESPACE'] +# self.restMatrix = blenBone.matrix['ARMATURESPACE'] # not used yet # self.restMatrixInv = self.restMatrix.copy().invert() @@ -532,13 +536,15 @@ def write(filename, batch_objects = None, \ print '\nFBX export starting...', filename - start_time = Blender.sys.time() + start_time = bpy.sys.time() +# start_time = Blender.sys.time() try: file = open(filename, 'w') except: return False - - sce = bpy.data.scenes.active + + sce = context.scene +# sce = bpy.data.scenes.active world = sce.world @@ -570,7 +576,8 @@ def write(filename, batch_objects = None, \ }''' % (curtime)) file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime) - file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version')) + file.write('\nCreator: "Blender3D version 2.5"') +# file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version')) pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way @@ -579,16 +586,19 @@ def write(filename, batch_objects = None, \ ''' Matrix mod is so armature objects can modify their bone matricies ''' - if isinstance(ob, Blender.Types.BoneType): + if isinstance(ob, bpy.types.Bone): +# if isinstance(ob, Blender.Types.BoneType): # we know we have a matrix # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod) - matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore + matrix = mtx4_z90 * ob.armature_matrix # dont apply armature matrix anymore +# matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore parent = ob.parent if parent: #par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod) - par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore + par_matrix = mtx4_z90 * parent.armature_matrix # dont apply armature matrix anymore +# par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore matrix = matrix * par_matrix.copy().invert() matrix_rot = matrix.rotationPart() @@ -755,8 +765,9 @@ def write(filename, batch_objects = None, \ ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) """ - file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ - (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length) + file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' % + (my_bone.blenBone.armature_head - my_bone.blenBone.armature_tail).length) +# (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length) #file.write('\n\t\t\tProperty: "LimbLength", "double", "",1') file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8') @@ -895,9 +906,12 @@ def write(filename, batch_objects = None, \ ''' Write a blender camera ''' - render = sce.render - width = render.sizeX - height = render.sizeY + render = sce.render_data + width = render.resolution_x + height = render.resolution_y +# render = sce.render +# width = render.sizeX +# height = render.sizeY aspect = float(width)/height data = my_cam.blenObject.data @@ -911,8 +925,10 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026') - file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units? - file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto + file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shift_x) # not sure if this is in the correct units? +# file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units? + file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shift_y) # ditto +# file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0') file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') @@ -944,8 +960,10 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') - file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart) - file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart) + file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clip_start) +# file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart) + file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clip_end) +# file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart) file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0') file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0') file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect) @@ -1018,16 +1036,20 @@ def write(filename, batch_objects = None, \ #ePOINT, #eDIRECTIONAL #eSPOT - light_type = light.type + light_type_items = {'POINT': 0, 'SUN': 1, 'SPOT': 2, 'HEMI': 3, 'AREA': 4} + light_type = light_type_items[light.type] +# light_type = light.type if light_type > 2: light_type = 1 # hemi and area lights become directional - - mode = light.mode - if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: + +# mode = light.mode + if light.shadow_method == 'RAY_SHADOW' or light.shadow_method == 'BUFFER_SHADOW': +# if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: do_shadow = 1 else: do_shadow = 0 - - if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular): + + if light.only_shadow or (not light.diffuse and not light.specular): +# if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular): do_light = 0 else: do_light = 1 @@ -1042,11 +1064,16 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1') file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 - file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) + if light.type == 'SPOT': + file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spot_size * scale)) +# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') - file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col)) + file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.color)) +# file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col)) file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 - file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) +# + # duplication? see ^ (Arystan) +# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light) @@ -1055,7 +1082,8 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') file.write('\n\t\t\tProperty: "DecayType", "enum", "",0') - file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist) + file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.distance) +# file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist) file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0') file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0') file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0') @@ -1101,7 +1129,8 @@ def write(filename, batch_objects = None, \ }''') # Material Settings - if world: world_amb = world.getAmb() + if world: world_amb = tuple(world.ambient_color) +# if world: world_amb = world.getAmb() else: world_amb = (0,0,0) # Default value def write_material(matname, mat): @@ -1109,22 +1138,31 @@ def write(filename, batch_objects = None, \ # Todo, add more material Properties. if mat: - mat_cold = tuple(mat.rgbCol) - mat_cols = tuple(mat.specCol) + mat_cold = tuple(mat.diffuse_color) +# mat_cold = tuple(mat.rgbCol) + mat_cols = tuple(mat.specular_color) +# mat_cols = tuple(mat.specCol) #mat_colm = tuple(mat.mirCol) # we wont use the mirror color - mat_colamb = tuple([c for c in world_amb]) - - mat_dif = mat.ref - mat_amb = mat.amb - mat_hard = (float(mat.hard)-1)/5.10 - mat_spec = mat.spec/2.0 + mat_colamb = world_amb +# mat_colamb = tuple([c for c in world_amb]) + + mat_dif = mat.diffuse_reflection +# mat_dif = mat.ref + mat_amb = mat.ambient +# mat_amb = mat.amb + mat_hard = (float(mat.specular_hardness)-1)/5.10 +# mat_hard = (float(mat.hard)-1)/5.10 + mat_spec = mat.specular_reflection/2.0 +# mat_spec = mat.spec/2.0 mat_alpha = mat.alpha mat_emit = mat.emit - mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS + mat_shadeless = mat.shadeless +# mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS if mat_shadeless: mat_shader = 'Lambert' else: - if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT: + if mat.diffuse_shader == 'LAMBERT': +# if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT: mat_shader = 'Lambert' else: mat_shader = 'Phong' @@ -3102,11 +3140,16 @@ if __name__ == '__main__': write_ui() # NOTES (all line numbers correspond to original export_fbx.py (under release/scripts) -# # - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print # - get rid of cleanName somehow -# - new scene creation, activation: lines 327-342, 368 +# - isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 # TODO -# bpy.data.remove_scene: line 366 +# - bpy.data.remove_scene: line 366 +# - bpy.sys.time move to bpy.sys.util? +# - new scene creation, activation: lines 327-342, 368 +# - uses bpy.sys.expandpath, *.relpath - replace at least relpath + +# SMALL or COSMETICAL +# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version') diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 26e6e248a45..51d0403cdae 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -389,16 +389,13 @@ def write(filename, objects, scene, if ob_main.dupli_type != 'NONE': obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list] - # XXX + # XXX debug print print(ob_main.name, 'has', len(obs), 'dupli children') else: obs = [(ob_main, ob_main.matrix)] for ob, ob_mat in obs: - if EXPORT_ROTX90: - ob_mat = ob_mat * mat_xrot90 - # XXX postponed # # Nurbs curve support # if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): @@ -418,7 +415,10 @@ def write(filename, objects, scene, else: me = ob.data.create_copy() - me.transform(ob_mat) + if EXPORT_ROTX90: + me.transform(ob_mat * mat_xrot90) + else: + me.transform(ob_mat) # # Will work for non meshes now! :) # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) @@ -961,5 +961,5 @@ if __name__ == "__main__": # - duplis - only tested dupliverts # - NURBS - needs API additions # - all scenes export -# - normals calculation +# + normals calculation # - get rid of cleanName somehow diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 8a9fdb8531d..fb2d052e241 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1920,7 +1920,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_object_force.c", NULL, RNA_def_object_force}, {"rna_packedfile.c", NULL, RNA_def_packedfile}, {"rna_particle.c", NULL, RNA_def_particle}, - {"rna_pose.c", NULL, RNA_def_pose}, + {"rna_pose.c", "rna_pose_api.c", RNA_def_pose}, {"rna_property.c", NULL, RNA_def_gameproperty}, {"rna_scene.c", "rna_scene_api.c", RNA_def_scene}, {"rna_screen.c", NULL, RNA_def_screen}, diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index dc519e9ec6e..7d8391132b1 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -610,6 +610,7 @@ static void rna_def_bone(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED); RNA_def_property_ui_text(prop, "Selected", ""); + /* XXX better matrix descriptions possible (Arystan) */ prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "bone_mat"); RNA_def_property_array(prop, 9); @@ -618,7 +619,27 @@ static void rna_def_bone(BlenderRNA *brna) prop= RNA_def_property(srna, "armature_matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "arm_mat"); RNA_def_property_array(prop, 16); - RNA_def_property_ui_text(prop, "Bone Armature Matrix", "4x4 bone matrix relative to armature."); + RNA_def_property_ui_text(prop, "Bone Armature-Relative Matrix", "4x4 bone matrix relative to armature."); + + prop= RNA_def_property(srna, "tail", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "tail"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone."); + + prop= RNA_def_property(srna, "armature_tail", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "arm_tail"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Armature-Relative Tail", "Location of tail end of the bone relative to armature."); + + prop= RNA_def_property(srna, "head", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "head"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone."); + + prop= RNA_def_property(srna, "armature_head", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "arm_head"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Armature-Relative Head", "Location of head end of the bone relative to armature."); } static void rna_def_edit_bone(BlenderRNA *brna) -- cgit v1.2.3 From b60bfd613edfc23de848d0f4c37faeff8c85ad23 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 10 Jul 2009 15:33:35 +0000 Subject: Cost of a BVH is calculated using SA(child)/SA(parent) Although tests didnt showed this to be clearly superior to: cost(bvh) = log(size) --- source/blender/render/intern/source/rayobject_bvh.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 40719a15f0e..1622851edfc 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -407,17 +407,22 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float parent->split_axis = builder->split_axis; for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); - bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); - *cost += tcost; + INIT_MINMAX(cbb, cbb+3); + bvh_merge_bb(parent->child[i], cbb, cbb+3); + DO_MIN(cbb, parent->bb); + DO_MAX(cbb+3, parent->bb+3); + + *cost += tcost*bb_area(cbb, cbb+3); } for(; ichild[i] = 0; - *cost /= nc*bb_area(parent->bb, parent->bb+3); - *cost += RAY_BB_TEST_COST; + *cost /= bb_area(parent->bb, parent->bb+3); + *cost += nc*RAY_BB_TEST_COST; return parent; } } @@ -458,7 +463,7 @@ static void bvh_done(BVHTree *obj) obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); // obj->cost = 1.0; - obj->cost = logf( rtbuild_size( obj->builder ) ); +// obj->cost = logf( rtbuild_size( obj->builder ) ); #ifndef DYNAMIC_ALLOC assert(obj->node_alloc+needed_nodes >= obj->node_next); -- cgit v1.2.3 From c43fe4cca969e4f4755b041d3e1bc6aee322517f Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 10 Jul 2009 15:43:59 +0000 Subject: Should improve mirror rays (copy past error: was losing dive first heuristic sometimes) --- source/blender/render/intern/source/rayobject_bvh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 1622851edfc..181456c2b4d 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -202,14 +202,13 @@ static int dfs_raycast_stack(BVHNode *root, Isect *isec) else { int i; - for(i=0; i=0; i--) if(node->child[i] != 0 #ifdef RT_USE_HINT && node->child[i] != (BVHNode*)isec->hint #endif ) stack[stack_pos++] = node->child[i]; - else break; } assert(stack_pos <= DFS_STACK_SIZE); } -- cgit v1.2.3 From 81c356151345e99d7ae0968be1f6242cd3c6fce1 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 10 Jul 2009 16:42:51 +0000 Subject: *rtbuild now stores BB *fix in ray/bb hit tests inside instances --- .../render/intern/include/rayobject_rtbuild.h | 5 + .../render/intern/source/rayobject_instance.c | 39 +++- .../render/intern/source/rayobject_rtbuild.c | 210 +++++++-------------- 3 files changed, 114 insertions(+), 140 deletions(-) diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index 6fef18433b9..a98ed38a581 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -54,6 +54,8 @@ typedef struct RTBuilder int child_offset[RTBUILD_MAX_CHILDS+1]; int child_sorted_axis; /* -1 if not sorted */ + + float bb[6]; } RTBuilder; @@ -61,6 +63,7 @@ typedef struct RTBuilder RTBuilder* rtbuild_create(int size); void rtbuild_free(RTBuilder *b); void rtbuild_add(RTBuilder *b, RayObject *o); +void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); int rtbuild_size(RTBuilder *b); /* used during tree reorganization */ @@ -82,5 +85,7 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); /* bb utils */ float bb_area(float *min, float *max); +float bb_volume(float *min, float *max); +int bb_largest_axis(float *min, float *max); #endif diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c index 4a67e8108cb..14f333a7f86 100644 --- a/source/blender/render/intern/source/rayobject_instance.c +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -34,9 +34,12 @@ #include "RE_raytrace.h" #include "rayobject.h" +#define RE_COST_INSTANCE (1.0f) + static int RayObject_instance_intersect(RayObject *o, Isect *isec); static void RayObject_instance_free(RayObject *o); static void RayObject_instance_bb(RayObject *o, float *min, float *max); +static float RayObject_instance_cost(RayObject *o); static RayObjectAPI instance_api = { @@ -44,7 +47,8 @@ static RayObjectAPI instance_api = NULL, //static void RayObject_instance_add(RayObject *o, RayObject *ob); NULL, //static void RayObject_instance_done(RayObject *o); RayObject_instance_free, - RayObject_instance_bb + RayObject_instance_bb, + RayObject_instance_cost }; typedef struct InstanceRayObject @@ -85,7 +89,7 @@ static int RayObject_instance_intersect(RayObject *o, Isect *isec) InstanceRayObject *obj = (InstanceRayObject*)o; int res; float start[3], vec[3], labda, dist; - int changed = 0; + int changed = 0, i; //TODO - this is disabling self intersection on instances if(isec->orig.ob == obj->ob && obj->ob) @@ -111,6 +115,18 @@ static int RayObject_instance_intersect(RayObject *o, Isect *isec) isec->labda *= isec->dist / dist; + //Update idot_axis and bv_index + for(i=0; i<3; i++) + { + isec->idot_axis[i] = 1.0f / isec->vec[i]; + + isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i]; + + isec->bv_index[2*i] = i+3*isec->bv_index[2*i]; + isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; + } + //Raycast res = RE_rayobject_intersect(obj->target, isec); @@ -118,7 +134,6 @@ static int RayObject_instance_intersect(RayObject *o, Isect *isec) if(res == 0) { isec->labda = labda; - } else { @@ -131,6 +146,18 @@ static int RayObject_instance_intersect(RayObject *o, Isect *isec) if(changed) isec->orig.ob = obj->ob; + + //Update idot_axis and bv_index + for(i=0; i<3; i++) + { + isec->idot_axis[i] = 1.0f / isec->vec[i]; + + isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i]; + + isec->bv_index[2*i] = i+3*isec->bv_index[2*i]; + isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; + } return res; } @@ -141,6 +168,12 @@ static void RayObject_instance_free(RayObject *o) MEM_freeN(obj); } +static float RayObject_instance_cost(RayObject *o) +{ + InstanceRayObject *obj = (InstanceRayObject*)o; + return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE; +} + static void RayObject_instance_bb(RayObject *o, float *min, float *max) { //TODO: diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c index 46140d3d24d..3c301ce1f9f 100644 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ b/source/blender/render/intern/source/rayobject_rtbuild.c @@ -11,7 +11,6 @@ static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane); - static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) { int i; @@ -23,6 +22,8 @@ static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) for(i=0; ichild_offset[i] = 0; + + INIT_MINMAX(b->bb, b->bb+3); } RTBuilder* rtbuild_create(int size) @@ -44,66 +45,45 @@ void rtbuild_add(RTBuilder *b, RayObject *o) *(b->end++) = o; } -RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) +void rtbuild_calc_bb(RTBuilder *b) { - rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); - tmp->child_sorted_axis = b->child_sorted_axis; - return tmp; + if(b->bb[0] == 1.0e30f) + { + RayObject **index = b->begin; + for(; index != b->end; index++) + RE_rayobject_merge_bb(*index, b->bb, b->bb+3); + } } -int rtbuild_size(RTBuilder *b) +void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) { - return b->end - b->begin; + rtbuild_calc_bb(b); + DO_MIN(b->bb, min); + DO_MAX(b->bb+3, max); } -/* Split methods */ -static void merge_bb(RTBuilder *b, float *min, float *max) +int rtbuild_get_largest_axis(RTBuilder *b) { - RayObject **index = b->begin; - - for(; index != b->end; index++) - RE_rayobject_merge_bb(*index, min, max); + rtbuild_calc_bb(b); + return bb_largest_axis(b->bb, b->bb+3); } -static int largest_axis(float *min, float *max) -{ - float sub[3]; - - sub[0] = max[0]-min[0]; - sub[1] = max[1]-min[1]; - sub[2] = max[2]-min[2]; - if(sub[0] > sub[1]) - { - if(sub[0] > sub[2]) - return 0; - else - return 2; - } - else - { - if(sub[1] > sub[2]) - return 1; - else - return 2; - } -} -int rtbuild_get_largest_axis(RTBuilder *b) +int rtbuild_size(RTBuilder *b) { - float min[3], max[3]; - - INIT_MINMAX(min, max); - merge_bb( b, min, max); - - return largest_axis(min,max); + return b->end - b->begin; } -/* -int rtbuild_median_split(RTBuilder *b, int nchilds, int axis) +RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) { + rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); + tmp->child_sorted_axis = b->child_sorted_axis; + return tmp; } -*/ + + + //Left balanced tree int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) { @@ -199,14 +179,12 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) { int la, i; float separators[RTBUILD_MAX_CHILDS]; - float min[3], max[3]; - - INIT_MINMAX(min, max); - merge_bb( b, min, max); + + rtbuild_calc_bb(b); - la = largest_axis(min,max); + la = bb_largest_axis(b->bb,b->bb+3); for(i=1; ibb[la+3]-b->bb[la])*i / nchilds; return rtbuild_median_split(b, separators, nchilds, la); } @@ -250,23 +228,9 @@ void costobject_sort(CostObject *begin, CostObject *end, int axis) else if(axis == 5) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(5)); } -float bb_volume(float *min, float *max) -{ - return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]); -} - -float bb_area(float *min, float *max) -{ - float sub[3], a; - sub[0] = max[0]-min[0]; - sub[1] = max[1]-min[1]; - sub[2] = max[2]-min[2]; - a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; - assert(a >= 0.0); - return a; -} +/* Object Surface Area Heuristic splitter */ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) { int size = rtbuild_size(b); @@ -387,77 +351,6 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) } } -//Heuristic Area Splitter -typedef struct CostEvent CostEvent; - -struct CostEvent -{ - float key; - float value; -}; - -int costevent_cmp(const CostEvent *a, const CostEvent *b) -{ - if(a->key < b->key) return -1; - if(a->key > b->key) return 1; - if(a->value < b->value) return -1; - if(a->value > b->value) return 1; - return 0; -} - -void costevent_sort(CostEvent *begin, CostEvent *end) -{ - //TODO introsort - qsort(begin, sizeof(*begin), end-begin, (int(*)(const void *, const void *)) costevent_cmp); -} -/* -int rtbuild_heuristic_split(RTBuilder *b, int nchilds) -{ - int size = rtbuild_size(b); - - assert(nchilds == 2); - - if(size <= nchilds) - { - return rtbuild_mean_split_largest_axis(b, nchilds); - } - else - { - CostEvent *events, *ev; - RayObject *index; - int a = 0; - - events = MEM_malloc( sizeof(CostEvent)*2*size, "RTBuilder.SweepSplitCostEvent" ); - for(a = 0; a<3; a++) - - - for(index = b->begin; b != b->end; b++) - { - float min[3], max[3]; - INIT_MINMAX(min, max); - RE_rayobject_merge_bb(index, min, max); - for(a = 0; a<3; a++) - { - ev[a]->key = min[a]; - ev[a]->value = 1; - ev[a]++; - - ev[a]->key = max[a]; - ev[a]->value = -1; - ev[a]++; - } - } - for(a = 0; a<3; a++) - costevent_sort(events[a], ev[a]); - - - - for(a = 0; a<3; a++) - MEM_freeN(ev[a]); - } -} -*/ - /* * Helper code * PARTITION code / used on mean-split @@ -593,3 +486,46 @@ static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane) } return begin; } + +/* + * Bounding Box utils + */ +float bb_volume(float *min, float *max) +{ + return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]); +} + +float bb_area(float *min, float *max) +{ + float sub[3], a; + sub[0] = max[0]-min[0]; + sub[1] = max[1]-min[1]; + sub[2] = max[2]-min[2]; + + a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; + assert(a >= 0.0); + return a; +} + +int bb_largest_axis(float *min, float *max) +{ + float sub[3]; + + sub[0] = max[0]-min[0]; + sub[1] = max[1]-min[1]; + sub[2] = max[2]-min[2]; + if(sub[0] > sub[1]) + { + if(sub[0] > sub[2]) + return 0; + else + return 2; + } + else + { + if(sub[1] > sub[2]) + return 1; + else + return 2; + } +} -- cgit v1.2.3 From 9a23287fd8062674ad58829b9e58bb2b3e982f23 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 10 Jul 2009 17:41:49 +0000 Subject: SUN and HEMI lights back as trunk (i think) --- .../blender/render/intern/include/render_types.h | 1 + source/blender/render/intern/source/rayshade.c | 94 +++++++++++----------- 2 files changed, 46 insertions(+), 49 deletions(-) diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 88bf30bd9ef..c412921eb31 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -172,6 +172,7 @@ struct Render /* octree tables and variables for raytrace */ struct RayObject *raytree; struct RayFace *rayfaces; + float maxdist; /* needed for keeping an incorrect behaviour of SUN and HEMI lights (avoid breaking old scenes) */ /* occlusion tree */ void *occlusiontree; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 977cba75f55..b967f2bd8ce 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -348,6 +348,8 @@ static void makeraytree_single(Render *re) void makeraytree(Render *re) { + float min[3], max[3], sub[3]; + int i; const char *tree_type = "Tree(unknown)"; #ifdef RE_RAYCOUNTER @@ -372,6 +374,18 @@ void makeraytree(Render *re) BENCH(makeraytree_single(re), tree_build); else BENCH(makeraytree_hier(re), tree_build); + + + //Calculate raytree max_size + //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights + RE_rayobject_merge_bb( re->raytree, min, max ); + for(i=0; i<3; i++) + { + min[i] += 0.01f; + max[i] += 0.01f; + sub[i] = max[i]-min[i]; + } + re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] ); } @@ -2029,7 +2043,7 @@ static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_ } } -static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lampvec, float *shadfac, Isect *isec) +static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec) { QMCSampler *qsa=NULL; int samples=0; @@ -2135,20 +2149,10 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam } VECCOPY(isec->start, co); - if(lampvec) - { - isec->vec[0] = end[0]; - isec->vec[1] = end[1]; - isec->vec[2] = end[2]; - isec->labda = RE_RAYTRACE_MAXDIST; - } - else - { - isec->vec[0] = end[0]-isec->start[0]; - isec->vec[1] = end[1]-isec->start[1]; - isec->vec[2] = end[2]-isec->start[2]; - isec->labda = 1.0f; // * Normalize(isec->vec); - } + isec->vec[0] = end[0]-isec->start[0]; + isec->vec[1] = end[1]-isec->start[1]; + isec->vec[2] = end[2]-isec->start[2]; + isec->labda = 1.0f; // * Normalize(isec->vec); /* trace the ray */ if(isec->mode==RE_RAY_SHADOW_TRA) { @@ -2201,7 +2205,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam release_thread_qmcsampler(&R, shi->thread, qsa); } -static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, int lampvec, float *shadfac, Isect *isec) +static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec) { /* area soft shadow */ float *jitlamp; @@ -2243,21 +2247,11 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, int Mat3MulVecfl(lar->mat, vec); /* set start and vec */ - VECCOPY(isec->start, shi->co); - if(lampvec) - { - isec->vec[0] = vec[0]+lampco[0]; - isec->vec[1] = vec[1]+lampco[1]; - isec->vec[2] = vec[2]+lampco[2]; - isec->labda = RE_RAYTRACE_MAXDIST; - } - else - { - isec->vec[0] = vec[0]+lampco[0]-shi->co[0]; - isec->vec[1] = vec[1]+lampco[1]-shi->co[1]; - isec->vec[2] = vec[2]+lampco[2]-shi->co[2]; - isec->labda = 1.0f; - } + VECCOPY(isec->start, shi->co); + isec->vec[0] = vec[0]+lampco[0]-shi->co[0]; + isec->vec[1] = vec[1]+lampco[1]-shi->co[1]; + isec->vec[2] = vec[2]+lampco[2]-shi->co[2]; + isec->labda = 1.0f; isec->skip = RE_SKIP_VLR_NEIGHBOUR; if(isec->mode==RE_RAY_SHADOW_TRA) { @@ -2296,7 +2290,6 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) { Isect isec; float lampco[3]; - int lampvec; /* indicates if lampco is a vector lamp */ /* setup isec */ RE_RC_INIT(isec, *shi); @@ -2320,19 +2313,30 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) } if(lar->type==LA_SUN || lar->type==LA_HEMI) { - lampco[0]= -lar->vec[0]; - lampco[1]= -lar->vec[1]; - lampco[2]= -lar->vec[2]; - lampvec = 1; + /* jitter and QMC sampling add a displace vector to the lamp position + * that's incorrect because a SUN lamp does not has an exact position + * and the displace should be done at the ray vector instead of the + * lamp position. + * This is easily verified by noticing that shadows of SUN lights change + * with the scene BB. + * + * This was detected during SoC 2009 - Raytrace Optimization, but to keep + * consistency with older render code it wasn't removed. + * + * If the render code goes through some recode/serious bug-fix then this + * is something to consider! + */ + lampco[0]= shi->co[0] - R.maxdist*lar->vec[0]; + lampco[1]= shi->co[1] - R.maxdist*lar->vec[1]; + lampco[2]= shi->co[2] - R.maxdist*lar->vec[2]; } else { VECCOPY(lampco, lar->co); - lampvec = 0; } if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) { - ray_shadow_qmc(shi, lar, lampco, lampvec, shadfac, &isec); + ray_shadow_qmc(shi, lar, lampco, shadfac, &isec); } else { if(lar->ray_totsamp<2) { @@ -2344,16 +2348,8 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) /* set up isec vec */ VECCOPY(isec.start, shi->co); - if(lampvec) - { - VECCOPY(isec.vec, lampco); - isec.labda = RE_RAYTRACE_MAXDIST; - } - else - { - VECSUB(isec.vec, lampco, isec.start); - isec.labda = 1.0f; - } + VECSUB(isec.vec, lampco, isec.start); + isec.labda = 1.0f; if(isec.mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ @@ -2367,7 +2363,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) shadfac[3]= 0.0f; } else { - ray_shadow_jitter(shi, lar, lampco, lampvec, shadfac, &isec); + ray_shadow_jitter(shi, lar, lampco, shadfac, &isec); } } -- cgit v1.2.3 From f221d9128ddf593f7977251ed4214cfe682d7c40 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 11 Jul 2009 11:58:50 +0000 Subject: Added Scene.set_frame RNA function to get immediate scene update. Changing Scene.current_frame doesn't work in this case because it adds a notifier. Also added RNA_property_update call in pyrna_struct_setattro so that notifiers are added when a property changes. --- release/io/export_fbx.py | 6 ++-- release/scripts/export_fbx.py | 3 +- source/blender/makesrna/intern/makesrna.c | 2 +- source/blender/makesrna/intern/rna_action.c | 2 ++ source/blender/makesrna/intern/rna_action_api.c | 48 +++++++++++++++++++++++++ source/blender/makesrna/intern/rna_pose_api.c | 2 -- source/blender/makesrna/intern/rna_scene_api.c | 16 +++++++++ source/blender/python/intern/bpy_rna.c | 7 +++- 8 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 source/blender/makesrna/intern/rna_action_api.c diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 59480c4d455..62c8e0daaaf 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -2500,7 +2500,8 @@ Connections: {''') if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]: - frame_orig = Blender.Get('curframe') + frame_orig = sce.current_frame +# frame_orig = Blender.Get('curframe') if ANIM_OPTIMIZE: ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION @@ -2613,7 +2614,8 @@ Takes: {''') ''' i = act_start while i <= act_end: - Blender.Set('curframe', i) + sce.set_frame(i) +# Blender.Set('curframe', i) for ob_generic in ob_anim_lists: for my_ob in ob_generic: #Blender.Window.RedrawAll() diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 4115140a852..bac4c6cbcc4 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -2445,7 +2445,8 @@ Connections: {''') if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]: - frame_orig = Blender.Get('curframe') + frame_orig = sce.current_frame +# frame_orig = Blender.Get('curframe') if ANIM_OPTIMIZE: ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index d7c9ffe9800..7a8dfe78ca1 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1897,7 +1897,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_rna.c", NULL, RNA_def_rna}, {"rna_ID.c", NULL, RNA_def_ID}, {"rna_texture.c", NULL, RNA_def_texture}, - {"rna_action.c", NULL, RNA_def_action}, + {"rna_action.c", "rna_action_api.c", RNA_def_action}, {"rna_animation.c", NULL, RNA_def_animation}, {"rna_actuator.c", NULL, RNA_def_actuator}, {"rna_armature.c", NULL, RNA_def_armature}, diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 3639d6d3fff..bc59e06a978 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -100,6 +100,8 @@ void rna_def_action(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "markers", NULL); RNA_def_property_struct_type(prop, "TimelineMarker"); RNA_def_property_ui_text(prop, "Pose Markers", "Markers specific to this Action, for labeling poses."); + + RNA_api_action(srna); } /* --------- */ diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c new file mode 100644 index 00000000000..a758a2c56d0 --- /dev/null +++ b/source/blender/makesrna/intern/rna_action_api.c @@ -0,0 +1,48 @@ +/** + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "DNA_action_types.h" + +#ifdef RNA_RUNTIME + +#else + +void RNA_api_action(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + +} + +#endif diff --git a/source/blender/makesrna/intern/rna_pose_api.c b/source/blender/makesrna/intern/rna_pose_api.c index c0bf3339f4f..9ac7713b2e9 100644 --- a/source/blender/makesrna/intern/rna_pose_api.c +++ b/source/blender/makesrna/intern/rna_pose_api.c @@ -1,6 +1,4 @@ /** - * - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index a38622b48ae..f3cbb630df5 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -33,6 +33,7 @@ #include "RNA_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #ifdef RNA_RUNTIME @@ -67,6 +68,15 @@ static void rna_Scene_remove_object(Scene *sce, ReportList *reports, Object *ob) ED_base_object_free_and_unlink(sce, base); } +static void rna_Scene_set_frame(Scene *sce, bContext *C, int frame) +{ + sce->r.cfra= frame; + CLAMP(sce->r.cfra, MINAFRAME, MAXFRAME); + scene_update_for_newframe(sce, (1<<20) - 1); + + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, sce); +} + #else void RNA_api_scene(StructRNA *srna) @@ -85,6 +95,12 @@ void RNA_api_scene(StructRNA *srna) RNA_def_function_flag(func, FUNC_USE_REPORTS); parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove from scene."); RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "set_frame", "rna_Scene_set_frame"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Set scene frame updating all objects immediately."); + parm= RNA_def_int(func, "frame", 0, MINAFRAME, MAXFRAME, "", "Frame number to set.", MINAFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); } #endif diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index ef504b6fbd8..9619d6fbbbb 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1311,6 +1311,7 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje { char *name = _PyUnicode_AsString(pyname); PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name); + int ret; if (prop==NULL) { if (!BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) { @@ -1328,7 +1329,11 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje } /* pyrna_py_to_prop sets its own exceptions */ - return pyrna_py_to_prop(&self->ptr, prop, NULL, value); + ret= pyrna_py_to_prop(&self->ptr, prop, NULL, value); + + RNA_property_update(BPy_GetContext(), &self->ptr, prop); + + return ret; } static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) -- cgit v1.2.3 From 870a9d61042d8badb02673678dd1ed32a6ee994d Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 11 Jul 2009 16:11:26 +0000 Subject: RNA functions can now return dynamic arrays (float, int/boolean). RNA handles freeing memory. Example code: http://pastebin.mozilla.org/662154. --- source/blender/makesrna/RNA_types.h | 3 +++ source/blender/makesrna/intern/makesrna.c | 24 +++++++++++++++++++++--- source/blender/makesrna/intern/rna_access.c | 7 ++++++- source/blender/makesrna/intern/rna_action_api.c | 15 +++++++++++++++ source/blender/makesrna/intern/rna_define.c | 2 ++ source/blender/python/SConscript | 2 +- source/blender/python/intern/bpy_rna.c | 6 ++++++ 7 files changed, 54 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index dc2a2a1a1de..ed6f12681cc 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -106,6 +106,9 @@ typedef enum PropertyFlag { /* pointers */ PROP_ID_REFCOUNT = 64, + /* arrays */ + PROP_DYNAMIC_ARRAY = 32768, + /* internal flags */ PROP_BUILTIN = 128, PROP_EXPORT = 256, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 7a8dfe78ca1..5462c005bcf 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1200,6 +1200,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA fprintf(f, "\tchar *_data"); if(func->ret) fprintf(f, ", *_retdata"); fprintf(f, ";\n"); + if(func->ret && (func->ret->flag & PROP_DYNAMIC_ARRAY)) fprintf(f, "\tint _ret_array_length;\n"); fprintf(f, "\t\n"); /* assign self */ @@ -1254,6 +1255,12 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA fprintf(f, "reports"); } + if(func->ret && (func->ret->flag & PROP_DYNAMIC_ARRAY)) { + if(!first) fprintf(f, ", "); + first= 0; + fprintf(f, "&_ret_array_length"); + } + dparm= dfunc->cont.properties.first; for(; dparm; dparm= dparm->next) { if(dparm->prop==func->ret) @@ -1271,6 +1278,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm= rna_find_parameter_def(func->ret); ptrstr= dparm->prop->type == PROP_POINTER || dparm->prop->arraylength > 0 ? "*" : ""; fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->ret->identifier); + + if(func->ret && (func->ret->flag & PROP_DYNAMIC_ARRAY)) { + fprintf(f, "\t_parms->func->ret->arraylength= _ret_array_length;\n"); + } } } @@ -1476,9 +1487,9 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA /* return type */ for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) { if(dparm->prop==func->ret) { - if(dparm->prop->arraylength) - fprintf(f, "XXX no array return types yet"); /* XXX not supported */ - else if(dparm->prop->type == PROP_POINTER) + if(dparm->prop->arraylength && !(dparm->prop->flag & PROP_DYNAMIC_ARRAY)) + fprintf(f, "\"XXX array return types only allowed with PROP_DYNAMIC_ARRAY flag.\""); /* XXX not supported */ + else if(dparm->prop->type == PROP_POINTER || (dparm->prop->flag & PROP_DYNAMIC_ARRAY)) fprintf(f, "%s%s *", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); else fprintf(f, "%s%s ", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); @@ -1515,6 +1526,13 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA fprintf(f, "ReportList *reports"); } + /* dynamic array length paramter */ + if(func->ret && (func->ret->flag & PROP_DYNAMIC_ARRAY)) { + if(!first) fprintf(f, ", "); + first= 0; + fprintf(f, "int *array_length"); + } + /* defined parameters */ for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) { if(dparm->prop==func->ret) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index f20df81d6ad..b312b0b8e51 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2799,8 +2799,13 @@ void RNA_parameter_list_free(ParameterList *parms) parm= parms->func->cont.properties.first; for(tot= 0; parm; parm= parm->next) { - if(parm->type == PROP_COLLECTION) + if(parm->type == PROP_COLLECTION) { BLI_freelistN((ListBase*)((char*)parms->data+tot)); + } + else if(parm->flag & PROP_DYNAMIC_ARRAY) { + /* for dynamic arrays, data is a pointer to an array */ + MEM_freeN(*(char**)parms->data+tot); + } tot+= rna_parameter_size(parm); } diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c index a758a2c56d0..b989d2d66a9 100644 --- a/source/blender/makesrna/intern/rna_action_api.c +++ b/source/blender/makesrna/intern/rna_action_api.c @@ -36,6 +36,16 @@ #ifdef RNA_RUNTIME +int *rna_Action_get_frames(bAction *act, int *ret_length) +{ + *ret_length= 3; + int *ret= MEM_callocN(*ret_length * sizeof(int), "action frames"); + ret[0] = 1; + ret[1] = 2; + ret[2] = 3; + return ret; +} + #else void RNA_api_action(StructRNA *srna) @@ -43,6 +53,11 @@ void RNA_api_action(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; + func= RNA_def_function(srna, "get_frames", "rna_Action_get_frames"); + RNA_def_function_ui_description(func, "Get action frames."); /* XXX describe better */ + parm= RNA_def_int_array(func, "frames", 1, NULL, 0, 0, "", "", 0, 0); + RNA_def_property_flag(parm, PROP_DYNAMIC_ARRAY); + RNA_def_function_return(func, parm); } #endif diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 07515d3ad56..d0a2de515ed 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2220,6 +2220,8 @@ int rna_parameter_size(PropertyRNA *parm) PropertyType ptype= parm->type; int len= parm->arraylength; + if (parm->flag & PROP_DYNAMIC_ARRAY) return sizeof(void*); + if(len > 0) { switch (ptype) { case PROP_BOOLEAN: diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 73dc171fc3e..0ef6689de7e 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes' +incs = '. ../editors/include ../makesdna ../makesrna ../makesrna/intern ../blenlib ../blenkernel ../nodes' incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager' incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 9619d6fbbbb..fe68436c07f 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -44,6 +44,8 @@ #include "DNA_scene_types.h" #include "ED_keyframing.h" +#include "rna_internal_types.h" /* PropertyRNA */ + #define USE_MATHUTILS #ifdef USE_MATHUTILS @@ -1792,6 +1794,10 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) /* resolve the array from a new pytype */ ret = PyTuple_New(len); + /* for return values, data is a pointer to an array, not first element pointer */ + if (prop->flag & PROP_DYNAMIC_ARRAY) + data = *((char**)data); + switch (type) { case PROP_BOOLEAN: for(a=0; a Date: Sat, 11 Jul 2009 22:13:01 +0000 Subject: Added module bf_render_raytrace (source/blender/render/intern/raytrace) to be able to use C++ at raytrace code C++ used in here is basicly C with templates and function overloads, to make it easier to reuse code between structures. For now BVH was converted in C++ and moved to this module --- source/blender/render/SConscript | 2 + source/blender/render/intern/raytrace/bvh.h | 288 +++++++++++++ .../render/intern/raytrace/rayobject_bvh.cpp | 470 ++++++++++++++++++++ .../blender/render/intern/source/rayobject_bvh.c | 474 --------------------- 4 files changed, 760 insertions(+), 474 deletions(-) create mode 100644 source/blender/render/intern/raytrace/bvh.h create mode 100644 source/blender/render/intern/raytrace/rayobject_bvh.cpp delete mode 100644 source/blender/render/intern/source/rayobject_bvh.c diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 173f5db8482..a52f211e918 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -3,6 +3,7 @@ Import ('env') cflags='' sources = env.Glob('intern/source/*.c') +raysources = env.Glob('intern/raytrace/*.cpp') incs = 'intern/include #/intern/guardedalloc ../blenlib ../makesdna' incs += ' extern/include ../blenkernel ../radiosity/extern/include ../imbuf' @@ -24,3 +25,4 @@ if env['OURPLATFORM']=='linux2': cflags='-pthread' env.BlenderLib ( libname = 'bf_render', sources = sources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags ) +env.BlenderLib ( libname = 'bf_render_raytrace', sources = raysources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags ) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h new file mode 100644 index 00000000000..d2da2690c49 --- /dev/null +++ b/source/blender/render/intern/raytrace/bvh.h @@ -0,0 +1,288 @@ + +/* bvh tree generics */ +template static int bvh_intersect(Tree *obj, Isect *isec); + +template static void bvh_add(Tree *obj, RayObject *ob) +{ + rtbuild_add( obj->builder, ob ); +} + +template static void bvh_done(Tree *obj); + +template +static void bvh_free(Tree *obj) +{ + if(obj->builder) + rtbuild_free(obj->builder); + + if(obj->node_arena) + BLI_memarena_free(obj->node_arena); + + MEM_freeN(obj); +} + +template +static void bvh_bb(Tree *obj, float *min, float *max) +{ + bvh_node_merge_bb(obj->root, min, max); +} + + +template +static float bvh_cost(Tree *obj) +{ + assert(obj->cost >= 0.0); + return obj->cost; +} + + + +/* bvh tree nodes generics */ +template static inline int bvh_node_hit_test(Node *node, Isect *isec) +{ + return RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX; +} + + +template +static void bvh_node_merge_bb(Node *node, float *min, float *max) +{ + if(RayObject_isAligned(node)) + { + DO_MIN(node->bb , min); + DO_MAX(node->bb+3, max); + } + else + { + RE_rayobject_merge_bb( (RayObject*)node, min, max); + } +} + + + +/* + * recursivly transverse a BVH looking for a rayhit using a local stack + */ +template static inline void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos); + +template +static int bvh_node_stack_raycast(Node *root, Isect *isec) +{ + Node *stack[MAX_STACK_SIZE]; + int hit = 0, stack_pos = 0; + + stack[stack_pos++] = root; + while(stack_pos) + { + Node *node = stack[--stack_pos]; + if(RayObject_isAligned(node)) + { + if(bvh_node_hit_test(node,isec)) + { + bvh_node_push_childs(node, isec, stack, stack_pos); + assert(stack_pos <= MAX_STACK_SIZE); + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node, isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + return hit; + +} + +/* + * recursively transverse a BVH looking for a rayhit using system stack + */ +/* +template +static int bvh_node_raycast(Node *node, Isect *isec) +{ + int hit = 0; + if(bvh_test_node(node, isec)) + { + if(isec->idot_axis[node->split_axis] > 0.0f) + { + int i; + for(i=0; ichild[i])) + { + if(node->child[i] == 0) break; + + hit |= bvh_node_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + else + { + int i; + for(i=BVH_NCHILDS-1; i>=0; i--) + if(RayObject_isAligned(node->child[i])) + { + if(node->child[i]) + { + hit |= dfs_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + } + return hit; +} +*/ + +/* bvh tree generics */ +template static int bvh_intersect(Tree *obj, Isect *isec); + +template static void bvh_add(Tree *obj, RayObject *ob) +{ + rtbuild_add( obj->builder, ob ); +} + +template static void bvh_done(Tree *obj); + +template +static void bvh_free(Tree *obj) +{ + if(obj->builder) + rtbuild_free(obj->builder); + + if(obj->node_arena) + BLI_memarena_free(obj->node_arena); + + MEM_freeN(obj); +} + +template +static void bvh_bb(Tree *obj, float *min, float *max) +{ + bvh_node_merge_bb(obj->root, min, max); +} + + +template +static float bvh_cost(Tree *obj) +{ + assert(obj->cost >= 0.0); + return obj->cost; +} + + + +/* bvh tree nodes generics */ +template static inline int bvh_node_hit_test(Node *node, Isect *isec) +{ + return RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX; +} + + +template +static void bvh_node_merge_bb(Node *node, float *min, float *max) +{ + if(RayObject_isAligned(node)) + { + DO_MIN(node->bb , min); + DO_MAX(node->bb+3, max); + } + else + { + RE_rayobject_merge_bb( (RayObject*)node, min, max); + } +} + + + +/* + * recursivly transverse a BVH looking for a rayhit using a local stack + */ +template static inline void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos); + +template +static int bvh_node_stack_raycast(Node *root, Isect *isec) +{ + Node *stack[MAX_STACK_SIZE]; + int hit = 0, stack_pos = 0; + + stack[stack_pos++] = root; + while(stack_pos) + { + Node *node = stack[--stack_pos]; + if(RayObject_isAligned(node)) + { + if(bvh_node_hit_test(node,isec)) + { + bvh_node_push_childs(node, isec, stack, stack_pos); + assert(stack_pos <= MAX_STACK_SIZE); + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node, isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + return hit; + +} + +/* + * recursively transverse a BVH looking for a rayhit using system stack + */ +/* +template +static int bvh_node_raycast(Node *node, Isect *isec) +{ + int hit = 0; + if(bvh_test_node(node, isec)) + { + if(isec->idot_axis[node->split_axis] > 0.0f) + { + int i; + for(i=0; ichild[i])) + { + if(node->child[i] == 0) break; + + hit |= bvh_node_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + else + { + int i; + for(i=BVH_NCHILDS-1; i>=0; i--) + if(RayObject_isAligned(node->child[i])) + { + if(node->child[i]) + { + hit |= dfs_raycast(node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + } + return hit; +} +*/ diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp new file mode 100644 index 00000000000..7bf87e09181 --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -0,0 +1,470 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +extern "C" +{ +#include +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "BLI_memarena.h" +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" +}; + +#include "bvh.h" + +#define BVH_NCHILDS 2 +#define RAY_BB_TEST_COST (0.2f) +#define DFS_STACK_SIZE 64 +#define DYNAMIC_ALLOC + +//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ +//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ +#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ + +struct BVHNode +{ + BVHNode *child[BVH_NCHILDS]; + float bb[6]; + int split_axis; +}; + +struct BVHTree +{ + RayObject rayobj; + + BVHNode *root; + + MemArena *node_arena; + + float cost; + RTBuilder *builder; +}; + + +/* + * Push nodes (used on dfs) + */ +template +inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) +{ + //push nodes in reverse visit order + if(isec->idot_axis[node->split_axis] < 0.0f) + { + int i; + for(i=0; ichild[i] == 0) + break; + else + stack[stack_pos++] = node->child[i]; + } + else + { + int i; + for(i=BVH_NCHILDS-1; i>=0; i--) + if(node->child[i] != 0) + stack[stack_pos++] = node->child[i]; + } +} + +/* + * BVH done + */ +static BVHNode *bvh_new_node(BVHTree *tree, int nid) +{ + BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + return node; +} + +static int child_id(int pid, int nchild) +{ + //N child of node A = A * K + (2 - K) + N, (0 <= N < K) + return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; +} + + +static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) +{ + *cost = 0; + if(rtbuild_size(builder) == 0) + return 0; + + if(rtbuild_size(builder) == 1) + { + RayObject *child = builder->begin[0]; + + if(RayObject_isRayFace(child)) + { + int i; + BVHNode *parent = bvh_new_node(tree, nid); + parent->split_axis = 0; + + INIT_MINMAX(parent->bb, parent->bb+3); + + for(i=0; i<1; i++) + { + parent->child[i] = (BVHNode*)builder->begin[i]; + bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3); + } + for(; ichild[i] = 0; + + *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; + return parent; + } + else + { + assert(!RayObject_isAligned(child)); + //Its a sub-raytrace structure, assume it has it own raycast + //methods and adding a Bounding Box arround is unnecessary + + *cost = RE_rayobject_cost(child); + return (BVHNode*)child; + } + } + else + { + int i; + RTBuilder tmp; + BVHNode *parent = bvh_new_node(tree, nid); + int nc = rtbuild_split(builder, BVH_NCHILDS); + + + INIT_MINMAX(parent->bb, parent->bb+3); + parent->split_axis = builder->split_axis; + for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); + + INIT_MINMAX(cbb, cbb+3); + bvh_node_merge_bb(parent->child[i], cbb, cbb+3); + DO_MIN(cbb, parent->bb); + DO_MAX(cbb+3, parent->bb+3); + + *cost += tcost*bb_area(cbb, cbb+3); + } + for(; ichild[i] = 0; + + *cost /= bb_area(parent->bb, parent->bb+3); + *cost += nc*RAY_BB_TEST_COST; + return parent; + } +} + +template<> +void bvh_done(BVHTree *obj) +{ + int needed_nodes = (rtbuild_size(obj->builder)+1)*2; + if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) + needed_nodes = BLI_MEMARENA_STD_BUFSIZE; + + obj->node_arena = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(obj->node_arena); + + + obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); + + rtbuild_free( obj->builder ); + obj->builder = NULL; +} + +template<> +int bvh_intersect(BVHTree *obj, Isect* isec) +{ + if(RayObject_isAligned(obj->root)) + return bvh_node_stack_raycast(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); +} + + +/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ +static RayObjectAPI bvh_api = +{ + (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect), + (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), + (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), + (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) +}; + + +RayObject *RE_rayobject_bvh_create(int size) +{ + BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bvh_api; + obj->root = NULL; + + obj->node_arena = NULL; + obj->builder = rtbuild_create( size ); + + return RayObject_unalignRayAPI((RayObject*) obj); +} +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +extern "C" +{ +#include +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "BLI_memarena.h" +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" +}; + +#include "bvh.h" + +#define BVH_NCHILDS 2 +#define RAY_BB_TEST_COST (0.2f) +#define DFS_STACK_SIZE 64 +#define DYNAMIC_ALLOC + +//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ +//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ +#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ + +struct BVHNode +{ + BVHNode *child[BVH_NCHILDS]; + float bb[6]; + int split_axis; +}; + +struct BVHTree +{ + RayObject rayobj; + + BVHNode *root; + + MemArena *node_arena; + + float cost; + RTBuilder *builder; +}; + + +/* + * Push nodes (used on dfs) + */ +template +inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) +{ + //push nodes in reverse visit order + if(isec->idot_axis[node->split_axis] < 0.0f) + { + int i; + for(i=0; ichild[i] == 0) + break; + else + stack[stack_pos++] = node->child[i]; + } + else + { + int i; + for(i=BVH_NCHILDS-1; i>=0; i--) + if(node->child[i] != 0) + stack[stack_pos++] = node->child[i]; + } +} + +/* + * BVH done + */ +static BVHNode *bvh_new_node(BVHTree *tree, int nid) +{ + BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + return node; +} + +static int child_id(int pid, int nchild) +{ + //N child of node A = A * K + (2 - K) + N, (0 <= N < K) + return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; +} + + +static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) +{ + *cost = 0; + if(rtbuild_size(builder) == 0) + return 0; + + if(rtbuild_size(builder) == 1) + { + RayObject *child = builder->begin[0]; + + if(RayObject_isRayFace(child)) + { + int i; + BVHNode *parent = bvh_new_node(tree, nid); + parent->split_axis = 0; + + INIT_MINMAX(parent->bb, parent->bb+3); + + for(i=0; i<1; i++) + { + parent->child[i] = (BVHNode*)builder->begin[i]; + bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3); + } + for(; ichild[i] = 0; + + *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; + return parent; + } + else + { + assert(!RayObject_isAligned(child)); + //Its a sub-raytrace structure, assume it has it own raycast + //methods and adding a Bounding Box arround is unnecessary + + *cost = RE_rayobject_cost(child); + return (BVHNode*)child; + } + } + else + { + int i; + RTBuilder tmp; + BVHNode *parent = bvh_new_node(tree, nid); + int nc = rtbuild_split(builder, BVH_NCHILDS); + + + INIT_MINMAX(parent->bb, parent->bb+3); + parent->split_axis = builder->split_axis; + for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); + + INIT_MINMAX(cbb, cbb+3); + bvh_node_merge_bb(parent->child[i], cbb, cbb+3); + DO_MIN(cbb, parent->bb); + DO_MAX(cbb+3, parent->bb+3); + + *cost += tcost*bb_area(cbb, cbb+3); + } + for(; ichild[i] = 0; + + *cost /= bb_area(parent->bb, parent->bb+3); + *cost += nc*RAY_BB_TEST_COST; + return parent; + } +} + +template<> +void bvh_done(BVHTree *obj) +{ + int needed_nodes = (rtbuild_size(obj->builder)+1)*2; + if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) + needed_nodes = BLI_MEMARENA_STD_BUFSIZE; + + obj->node_arena = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(obj->node_arena); + + + obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); + + rtbuild_free( obj->builder ); + obj->builder = NULL; +} + +template<> +int bvh_intersect(BVHTree *obj, Isect* isec) +{ + if(RayObject_isAligned(obj->root)) + return bvh_node_stack_raycast(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); +} + + +/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ +static RayObjectAPI bvh_api = +{ + (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect), + (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), + (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), + (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) +}; + + +RayObject *RE_rayobject_bvh_create(int size) +{ + BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bvh_api; + obj->root = NULL; + + obj->node_arena = NULL; + obj->builder = rtbuild_create( size ); + + return RayObject_unalignRayAPI((RayObject*) obj); +} diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c deleted file mode 100644 index 181456c2b4d..00000000000 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ /dev/null @@ -1,474 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include -#include -#include - -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "BLI_memarena.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" - -#define RAY_BB_TEST_COST (0.2f) -#define DFS_STACK_SIZE 64 -#define DYNAMIC_ALLOC - -//#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */ -//#define SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS /* space median split on the longest axis, childs BB are allowed to overlap */ -#define SPLIT_OBJECTS_SAH /* split objects using heuristic */ - -#define BVH_NCHILDS 2 -typedef struct BVHTree BVHTree; - -static int bvh_intersect(BVHTree *obj, Isect *isec); -static int bvh_intersect_stack(BVHTree *obj, Isect *isec); -static void bvh_add(BVHTree *o, RayObject *ob); -static void bvh_done(BVHTree *o); -static void bvh_free(BVHTree *o); -static void bvh_bb(BVHTree *o, float *min, float *max); -static float bvh_cost(BVHTree *o); - -static RayObjectAPI bvh_api = -{ -#ifdef DFS_STACK_SIZE - (RE_rayobject_raycast_callback) bvh_intersect_stack, -#else - (RE_rayobject_raycast_callback) bvh_intersect, -#endif - (RE_rayobject_add_callback) bvh_add, - (RE_rayobject_done_callback) bvh_done, - (RE_rayobject_free_callback) bvh_free, - (RE_rayobject_merge_bb_callback)bvh_bb, - (RE_rayobject_cost_callback) bvh_cost -}; - -typedef struct BVHNode BVHNode; -struct BVHNode -{ - BVHNode *child[BVH_NCHILDS]; -#ifdef DYNAMIC_ALLOC - float bb[6]; -#else - float *bb; //[6]; //[2][3]; -#endif - int split_axis; -}; - -struct BVHTree -{ - RayObject rayobj; - - BVHNode *root; - -#ifdef DYNAMIC_ALLOC - MemArena *node_arena; -#else - BVHNode *node_alloc, *node_next; - float *bb_alloc, *bb_next; -#endif - float cost; - RTBuilder *builder; - -}; - - -RayObject *RE_rayobject_bvh_create(int size) -{ - BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bvh_api; - obj->root = NULL; - -#ifdef DYNAMIC_ALLOC - obj->node_arena = NULL; -#else - obj->node_alloc = obj->node_next = NULL; - obj->bb_alloc = obj->bb_next = NULL; -#endif - obj->builder = rtbuild_create( size ); - - return RayObject_unalignRayAPI((RayObject*) obj); -} - -static void bvh_free(BVHTree *obj) -{ - if(obj->builder) - rtbuild_free(obj->builder); - -#ifdef DYNAMIC_ALLOC - if(obj->node_arena) - BLI_memarena_free(obj->node_arena); -#else - if(obj->node_alloc) - MEM_freeN(obj->node_alloc); - - if(obj->bb_alloc) - MEM_freeN(obj->bb_alloc); -#endif - - MEM_freeN(obj); -} - - -static void bvh_merge_bb(BVHNode *node, float *min, float *max) -{ - if(RayObject_isAligned(node)) - { - DO_MIN(node->bb , min); - DO_MAX(node->bb+3, max); - } - else - { - RE_rayobject_merge_bb( (RayObject*)node, min, max); - } -} - -static void bvh_bb(BVHTree *obj, float *min, float *max) -{ - bvh_merge_bb(obj->root, min, max); -} - -static float bvh_cost(BVHTree *obj) -{ - assert(obj->cost >= 0.0); - return obj->cost; -} - -/* - * Tree transverse - */ -static int dfs_raycast_stack(BVHNode *root, Isect *isec) -{ - BVHNode *stack[DFS_STACK_SIZE]; - int hit = 0, stack_pos = 0; -#ifdef RT_USE_HINT - BVHNode *last_processed_node = 0; -#endif - - stack[stack_pos++] = root; - - while(stack_pos) - { - BVHNode *node = stack[--stack_pos]; - if(RayObject_isAligned(node)) - { - if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) - { -#ifdef RT_USE_HINT - last_processed_node = node; -#endif - //push nodes in reverse visit order - if(isec->idot_axis[node->split_axis] < 0.0f) - { - int i; - for(i=0; ichild[i] == 0) break; - else -#ifdef RT_USE_HINT - if(node->child[i] != (BVHNode*)isec->hint) -#endif - stack[stack_pos++] = node->child[i]; - } - else - { - int i; - for(i=BVH_NCHILDS-1; i>=0; i--) - if(node->child[i] != 0 -#ifdef RT_USE_HINT - && node->child[i] != (BVHNode*)isec->hint -#endif - ) - stack[stack_pos++] = node->child[i]; - } - assert(stack_pos <= DFS_STACK_SIZE); - } - } - else - { - int ghit; -#ifdef RT_USE_HINT - RayTraceHint *b_hint = isec->hint; - isec->hint = 0; -#endif - ghit = RE_rayobject_intersect( (RayObject*)node, isec); - -#ifdef RT_USE_HINT - isec->hint = b_hint; - if(ghit) - isec->hit_hint = (RayTraceHint*)last_processed_node; -#endif - hit |= ghit; - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - return hit; -} - -static int bvh_intersect_stack(BVHTree *obj, Isect *isec) -{ - if(RayObject_isAligned(obj->root)) - { -#ifdef RT_USE_HINT - if(isec->hint) - { - int hit; - RE_RC_COUNT(isec->raycounter->raytrace_hint.test); - hit = dfs_raycast_stack((BVHNode*) isec->hint, isec); - if(hit) - { - RE_RC_COUNT(isec->raycounter->raytrace_hint.hit); - - if(isec->mode == RE_RAY_SHADOW) return hit; - } - else isec->hint = 0; //Clear HINT on non-hit?, that sounds good, but no tests where made - - return hit | dfs_raycast_stack(obj->root, isec); - } -#endif - return dfs_raycast_stack(obj->root, isec); - } - else - return RE_rayobject_intersect( (RayObject*)obj->root, isec); -} - -static int dfs_raycast(BVHNode *node, Isect *isec) -{ - int hit = 0; - if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) - { - if(isec->idot_axis[node->split_axis] > 0.0f) - { - int i; - for(i=0; ichild[i])) - { - if(node->child[i] == 0) break; - - hit |= dfs_raycast(node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - else - { - int i; - for(i=BVH_NCHILDS-1; i>=0; i--) - if(RayObject_isAligned(node->child[i])) - { - if(node->child[i]) - { - hit |= dfs_raycast(node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - } - return hit; -} - -static int bvh_intersect(BVHTree *obj, Isect *isec) -{ - if(RayObject_isAligned(obj->root)) - return dfs_raycast(obj->root, isec); - else - return RE_rayobject_intersect( (RayObject*)obj->root, isec); -} - - -/* - * Builds a BVH tree from builder object - */ -static void bvh_add(BVHTree *obj, RayObject *ob) -{ - rtbuild_add( obj->builder, ob ); -} - -static BVHNode *bvh_new_node(BVHTree *tree, int nid) -{ -#ifdef DYNAMIC_ALLOC - BVHNode *node = BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); - return node; -#else - BVHNode *node = tree->node_alloc + nid - 1; - assert(RayObject_isAligned(node)); - if(node+1 > tree->node_next) - tree->node_next = node+1; - - node->bb = tree->bb_alloc + (nid - 1)*6; - tree->bb_next += 6; - - return node; -#endif -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; -} - -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) -{ - *cost = 0; - if(rtbuild_size(builder) == 0) - return 0; - - if(rtbuild_size(builder) == 1) - { - RayObject *child = builder->begin[0]; - - if(RayObject_isRayFace(child)) - { - int i; - BVHNode *parent = bvh_new_node(tree, nid); - parent->split_axis = 0; - - INIT_MINMAX(parent->bb, parent->bb+3); - - for(i=0; i<1; i++) - { - parent->child[i] = (BVHNode*)builder->begin[i]; - bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3); - } - for(; ichild[i] = 0; - - *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; - return parent; - } - else - { - assert(!RayObject_isAligned(child)); - //Its a sub-raytrace structure, assume it has it own raycast - //methods and adding a Bounding Box arround is unnecessary - - *cost = RE_rayobject_cost(child); - return (BVHNode*)child; - } - } - else - { - int i; - RTBuilder tmp; - BVHNode *parent = bvh_new_node(tree, nid); - int nc; - -#ifdef SPLIT_OVERLAP_MEAN_LONGEST_AXIS - nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS); -#elif defined(SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS) - nc = rtbuild_median_split_largest_axis(builder, BVH_NCHILDS); -#elif defined(SPLIT_OBJECTS_SAH) - nc = rtbuild_heuristic_object_split(builder, BVH_NCHILDS); -#else - assert(0); -#endif - - INIT_MINMAX(parent->bb, parent->bb+3); - parent->split_axis = builder->split_axis; - for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); - - INIT_MINMAX(cbb, cbb+3); - bvh_merge_bb(parent->child[i], cbb, cbb+3); - DO_MIN(cbb, parent->bb); - DO_MAX(cbb+3, parent->bb+3); - - *cost += tcost*bb_area(cbb, cbb+3); - } - for(; ichild[i] = 0; - - *cost /= bb_area(parent->bb, parent->bb+3); - *cost += nc*RAY_BB_TEST_COST; - return parent; - } -} - -/* -static void bvh_info(BVHTree *obj) -{ - printf("BVH: Used %d nodes\n", obj->node_next - obj->node_alloc); -} -*/ - -static void bvh_done(BVHTree *obj) -{ - -#ifdef DYNAMIC_ALLOC - int needed_nodes = (rtbuild_size(obj->builder)+1)*2; - if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) - needed_nodes = BLI_MEMARENA_STD_BUFSIZE; - - obj->node_arena = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(obj->node_arena); - -#else - int needed_nodes; - - //TODO exact calculate needed nodes - needed_nodes = (rtbuild_size(obj->builder)+1)*2; - assert(needed_nodes > 0); - - BVHNode *node = BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); - return node; - obj->node_alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, "BVHTree.Nodes"); - obj->node_next = obj->node_alloc; - - obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, "BVHTree.NodesBB"); - obj->bb_next = obj->bb_alloc; -#endif - - obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); -// obj->cost = 1.0; -// obj->cost = logf( rtbuild_size( obj->builder ) ); - -#ifndef DYNAMIC_ALLOC - assert(obj->node_alloc+needed_nodes >= obj->node_next); -#endif - - rtbuild_free( obj->builder ); - obj->builder = NULL; -} - -- cgit v1.2.3 From e264087fad7a55be67d409fe1748d4fc647fba0c Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sat, 11 Jul 2009 22:29:53 +0000 Subject: I had applied a patch twice.. code was duplicated --- source/blender/render/intern/raytrace/bvh.h | 170 +++------------ .../render/intern/raytrace/rayobject_bvh.cpp | 235 --------------------- 2 files changed, 27 insertions(+), 378 deletions(-) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index d2da2690c49..44f531faa9f 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -1,147 +1,31 @@ - -/* bvh tree generics */ -template static int bvh_intersect(Tree *obj, Isect *isec); - -template static void bvh_add(Tree *obj, RayObject *ob) -{ - rtbuild_add( obj->builder, ob ); -} - -template static void bvh_done(Tree *obj); - -template -static void bvh_free(Tree *obj) -{ - if(obj->builder) - rtbuild_free(obj->builder); - - if(obj->node_arena) - BLI_memarena_free(obj->node_arena); - - MEM_freeN(obj); -} - -template -static void bvh_bb(Tree *obj, float *min, float *max) -{ - bvh_node_merge_bb(obj->root, min, max); -} - - -template -static float bvh_cost(Tree *obj) -{ - assert(obj->cost >= 0.0); - return obj->cost; -} - - - -/* bvh tree nodes generics */ -template static inline int bvh_node_hit_test(Node *node, Isect *isec) -{ - return RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX; -} - - -template -static void bvh_node_merge_bb(Node *node, float *min, float *max) -{ - if(RayObject_isAligned(node)) - { - DO_MIN(node->bb , min); - DO_MAX(node->bb+3, max); - } - else - { - RE_rayobject_merge_bb( (RayObject*)node, min, max); - } -} - - - -/* - * recursivly transverse a BVH looking for a rayhit using a local stack +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** */ -template static inline void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos); - -template -static int bvh_node_stack_raycast(Node *root, Isect *isec) -{ - Node *stack[MAX_STACK_SIZE]; - int hit = 0, stack_pos = 0; - - stack[stack_pos++] = root; - while(stack_pos) - { - Node *node = stack[--stack_pos]; - if(RayObject_isAligned(node)) - { - if(bvh_node_hit_test(node,isec)) - { - bvh_node_push_childs(node, isec, stack, stack_pos); - assert(stack_pos <= MAX_STACK_SIZE); - } - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node, isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - return hit; - -} - -/* - * recursively transverse a BVH looking for a rayhit using system stack - */ -/* -template -static int bvh_node_raycast(Node *node, Isect *isec) -{ - int hit = 0; - if(bvh_test_node(node, isec)) - { - if(isec->idot_axis[node->split_axis] > 0.0f) - { - int i; - for(i=0; ichild[i])) - { - if(node->child[i] == 0) break; - - hit |= bvh_node_raycast(node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - else - { - int i; - for(i=BVH_NCHILDS-1; i>=0; i--) - if(RayObject_isAligned(node->child[i])) - { - if(node->child[i]) - { - hit |= dfs_raycast(node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - } - } - return hit; -} -*/ /* bvh tree generics */ template static int bvh_intersect(Tree *obj, Isect *isec); diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp index 7bf87e09181..8a63e088a34 100644 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -220,241 +220,6 @@ static RayObjectAPI bvh_api = }; -RayObject *RE_rayobject_bvh_create(int size) -{ - BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bvh_api; - obj->root = NULL; - - obj->node_arena = NULL; - obj->builder = rtbuild_create( size ); - - return RayObject_unalignRayAPI((RayObject*) obj); -} -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -extern "C" -{ -#include -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "BLI_memarena.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" -}; - -#include "bvh.h" - -#define BVH_NCHILDS 2 -#define RAY_BB_TEST_COST (0.2f) -#define DFS_STACK_SIZE 64 -#define DYNAMIC_ALLOC - -//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ -//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ -#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ - -struct BVHNode -{ - BVHNode *child[BVH_NCHILDS]; - float bb[6]; - int split_axis; -}; - -struct BVHTree -{ - RayObject rayobj; - - BVHNode *root; - - MemArena *node_arena; - - float cost; - RTBuilder *builder; -}; - - -/* - * Push nodes (used on dfs) - */ -template -inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) -{ - //push nodes in reverse visit order - if(isec->idot_axis[node->split_axis] < 0.0f) - { - int i; - for(i=0; ichild[i] == 0) - break; - else - stack[stack_pos++] = node->child[i]; - } - else - { - int i; - for(i=BVH_NCHILDS-1; i>=0; i--) - if(node->child[i] != 0) - stack[stack_pos++] = node->child[i]; - } -} - -/* - * BVH done - */ -static BVHNode *bvh_new_node(BVHTree *tree, int nid) -{ - BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); - return node; -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; -} - - -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) -{ - *cost = 0; - if(rtbuild_size(builder) == 0) - return 0; - - if(rtbuild_size(builder) == 1) - { - RayObject *child = builder->begin[0]; - - if(RayObject_isRayFace(child)) - { - int i; - BVHNode *parent = bvh_new_node(tree, nid); - parent->split_axis = 0; - - INIT_MINMAX(parent->bb, parent->bb+3); - - for(i=0; i<1; i++) - { - parent->child[i] = (BVHNode*)builder->begin[i]; - bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3); - } - for(; ichild[i] = 0; - - *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; - return parent; - } - else - { - assert(!RayObject_isAligned(child)); - //Its a sub-raytrace structure, assume it has it own raycast - //methods and adding a Bounding Box arround is unnecessary - - *cost = RE_rayobject_cost(child); - return (BVHNode*)child; - } - } - else - { - int i; - RTBuilder tmp; - BVHNode *parent = bvh_new_node(tree, nid); - int nc = rtbuild_split(builder, BVH_NCHILDS); - - - INIT_MINMAX(parent->bb, parent->bb+3); - parent->split_axis = builder->split_axis; - for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); - - INIT_MINMAX(cbb, cbb+3); - bvh_node_merge_bb(parent->child[i], cbb, cbb+3); - DO_MIN(cbb, parent->bb); - DO_MAX(cbb+3, parent->bb+3); - - *cost += tcost*bb_area(cbb, cbb+3); - } - for(; ichild[i] = 0; - - *cost /= bb_area(parent->bb, parent->bb+3); - *cost += nc*RAY_BB_TEST_COST; - return parent; - } -} - -template<> -void bvh_done(BVHTree *obj) -{ - int needed_nodes = (rtbuild_size(obj->builder)+1)*2; - if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) - needed_nodes = BLI_MEMARENA_STD_BUFSIZE; - - obj->node_arena = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(obj->node_arena); - - - obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); - - rtbuild_free( obj->builder ); - obj->builder = NULL; -} - -template<> -int bvh_intersect(BVHTree *obj, Isect* isec) -{ - if(RayObject_isAligned(obj->root)) - return bvh_node_stack_raycast(obj->root, isec); - else - return RE_rayobject_intersect( (RayObject*) obj->root, isec ); -} - - -/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -static RayObjectAPI bvh_api = -{ - (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect), - (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), - (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), - (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), - (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), - (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) -}; - - RayObject *RE_rayobject_bvh_create(int size) { BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); -- cgit v1.2.3 From 11a47a02c73387d9390f7b1d2a40b7c50cab9c6f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sun, 12 Jul 2009 06:59:57 +0000 Subject: Added Action.get_frame_range returning a (min, max) pair or (0, 0) if there are no keys. --- release/io/export_fbx.py | 23 +++++++------ source/blender/makesrna/intern/rna_action_api.c | 45 ++++++++++++++++++++----- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 62c8e0daaaf..063a52b2f7d 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -2577,17 +2577,18 @@ Takes: {''') file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name]) else: file.write('\n\tTake: "%s" {' % sane_takename(blenAction)) - - tmp = blenAction.getFrameNumbers() - if tmp: - act_start = min(tmp) - act_end = max(tmp) - del tmp - else: - # Fallback on this, theres not much else we can do? :/ - # when an action has no length - act_start = start - act_end = end + + act_start, act_end = blenAction.get_frame_range() +# tmp = blenAction.getFrameNumbers() +# if tmp: +# act_start = min(tmp) +# act_end = max(tmp) +# del tmp +# else: +# # Fallback on this, theres not much else we can do? :/ +# # when an action has no length +# act_start = start +# act_end = end # Set the action active for my_bone in ob_arms: diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c index b989d2d66a9..9f63d44f8ef 100644 --- a/source/blender/makesrna/intern/rna_action_api.c +++ b/source/blender/makesrna/intern/rna_action_api.c @@ -36,13 +36,40 @@ #ifdef RNA_RUNTIME -int *rna_Action_get_frames(bAction *act, int *ret_length) +#include "DNA_anim_types.h" +#include "DNA_curve_types.h" + +/* return frame range of all curves (min, max) or (0, 0) if there are no keys */ +int *rna_Action_get_frame_range(bAction *act, int *ret_length) { - *ret_length= 3; - int *ret= MEM_callocN(*ret_length * sizeof(int), "action frames"); - ret[0] = 1; - ret[1] = 2; - ret[2] = 3; + FCurve *cu; + int *ret; + + *ret_length= 2; + ret= MEM_callocN(*ret_length * sizeof(int), "rna_Action_get_frame_range"); + + ret[0]= 0; + ret[1]= 0; + + for (cu= act->curves.first; cu; cu= cu->next) { + int verts= cu->totvert; + BezTriple *bezt= cu->bezt; + while (verts) { + int frame= (int)bezt->vec[1][0]; + + if (cu == act->curves.first && verts == cu->totvert) + ret[0]= ret[1]= frame; + + if (frame < ret[0]) + ret[0]= frame; + if (frame > ret[1]) + ret[1]= frame; + + bezt++; + verts--; + } + } + return ret; } @@ -53,9 +80,9 @@ void RNA_api_action(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; - func= RNA_def_function(srna, "get_frames", "rna_Action_get_frames"); - RNA_def_function_ui_description(func, "Get action frames."); /* XXX describe better */ - parm= RNA_def_int_array(func, "frames", 1, NULL, 0, 0, "", "", 0, 0); + func= RNA_def_function(srna, "get_frame_range", "rna_Action_get_frame_range"); + RNA_def_function_ui_description(func, "Get action frame range as a (min, max) tuple."); + parm= RNA_def_int_array(func, "frame_range", 1, NULL, 0, 0, "", "Action frame range.", 0, 0); RNA_def_property_flag(parm, PROP_DYNAMIC_ARRAY); RNA_def_function_return(func, parm); } -- cgit v1.2.3 From ffa5636a8b348d47d08b76644ec567d90cc9d3c5 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sun, 12 Jul 2009 07:20:49 +0000 Subject: Reusing existing blenkernel function calc_action_range for Action.get_frame_range. --- source/blender/makesrna/intern/rna_action_api.c | 29 +++++-------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c index 9f63d44f8ef..2b51a424fcf 100644 --- a/source/blender/makesrna/intern/rna_action_api.c +++ b/source/blender/makesrna/intern/rna_action_api.c @@ -39,36 +39,19 @@ #include "DNA_anim_types.h" #include "DNA_curve_types.h" -/* return frame range of all curves (min, max) or (0, 0) if there are no keys */ +/* return frame range of all curves (min, max) or (0, 1) if there are no keys */ int *rna_Action_get_frame_range(bAction *act, int *ret_length) { - FCurve *cu; int *ret; + float start, end; + + calc_action_range(act, &start, &end, 1); *ret_length= 2; ret= MEM_callocN(*ret_length * sizeof(int), "rna_Action_get_frame_range"); - ret[0]= 0; - ret[1]= 0; - - for (cu= act->curves.first; cu; cu= cu->next) { - int verts= cu->totvert; - BezTriple *bezt= cu->bezt; - while (verts) { - int frame= (int)bezt->vec[1][0]; - - if (cu == act->curves.first && verts == cu->totvert) - ret[0]= ret[1]= frame; - - if (frame < ret[0]) - ret[0]= frame; - if (frame > ret[1]) - ret[1]= frame; - - bezt++; - verts--; - } - } + ret[0]= (int)start; + ret[1]= (int)end; return ret; } -- cgit v1.2.3 From a6b328b82577d3ec1429c02686ea1727e02140c0 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 12 Jul 2009 18:04:10 +0000 Subject: *Moved rtbuild to bf_render_raytrace *Added vbvh - Just a experimental tree type :) Variable Way BVH - there is no hardcoded number of childs per each Tree Node - idea is to optimize a tree to reduced the expected number of BB tests even after applying SAH (for that an hardcoded n-way is not enough) - for now childs are stored on a linked list --- source/blender/blenlib/BLI_memarena.h | 9 + source/blender/render/extern/include/RE_raytrace.h | 12 +- source/blender/render/intern/include/rayobject.h | 11 + .../render/intern/include/rayobject_rtbuild.h | 9 + source/blender/render/intern/raytrace/bvh.h | 7 +- .../render/intern/raytrace/rayobject_bvh.cpp | 11 +- .../render/intern/raytrace/rayobject_rtbuild.cpp | 531 +++++++++++++++++++++ .../render/intern/raytrace/rayobject_vbvh.cpp | 248 ++++++++++ .../render/intern/source/rayobject_rtbuild.c | 531 --------------------- source/blender/render/intern/source/rayshade.c | 8 +- 10 files changed, 835 insertions(+), 542 deletions(-) create mode 100644 source/blender/render/intern/raytrace/rayobject_rtbuild.cpp create mode 100644 source/blender/render/intern/raytrace/rayobject_vbvh.cpp delete mode 100644 source/blender/render/intern/source/rayobject_rtbuild.c diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index a2954f8fa0d..4b955e9fa20 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -37,6 +37,10 @@ #ifndef BLI_MEMARENA_H #define BLI_MEMARENA_H +#ifdef __cplusplus +extern "C" { +#endif + /* A reasonable standard buffer size, big * enough to not cause much internal fragmentation, * small enough not to waste resources @@ -55,5 +59,10 @@ void BLI_memarena_use_calloc (struct MemArena *ma); void* BLI_memarena_alloc (struct MemArena *ma, int size); +#ifdef __cplusplus +} +#endif + + #endif diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 7624cd09edb..4d0c0b1a88c 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -31,6 +31,11 @@ #ifndef RE_RAYTRACE_H #define RE_RAYTRACE_H +#ifdef __cplusplus +extern "C" { +#endif + + #define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ //#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */ @@ -88,7 +93,8 @@ RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ -RayObject* RE_rayobject_bvh_create(int size); /* rayobject_bvh.c */ +RayObject* RE_rayobject_bvh_create(int size); /* raytrace/rayobject_bvh.c */ +RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ @@ -151,5 +157,9 @@ struct Isect /* TODO use: FLT_MAX? */ #define RE_RAYTRACE_MAXDIST 1e33 +#ifdef __cplusplus +} +#endif + #endif /*__RE_RAYTRACE_H__*/ diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index de36a1e4888..16ebc537ef9 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -29,9 +29,14 @@ #ifndef RE_RAYOBJECT_H #define RE_RAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + #include "RE_raytrace.h" #include + /* RayObject A ray object is everything where we can cast rays like: @@ -166,4 +171,10 @@ float RE_rayobject_cost(RayObject *r); #endif + +#ifdef __cplusplus +} +#endif + + #endif diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index a98ed38a581..b80e0868739 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -29,8 +29,13 @@ #ifndef RE_RAYOBJECT_RTBUILD_H #define RE_RAYOBJECT_RTBUILD_H +#ifdef __cplusplus +extern "C" { +#endif + #include "rayobject.h" + /* * Ray Tree Builder * this structs helps building any type of tree @@ -88,4 +93,8 @@ float bb_area(float *min, float *max); float bb_volume(float *min, float *max); int bb_largest_axis(float *min, float *max); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 44f531faa9f..d9277f9a583 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -99,7 +99,12 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) Node *stack[MAX_STACK_SIZE]; int hit = 0, stack_pos = 0; - stack[stack_pos++] = root; + //Assume the BB of root always succeed + if(1) + bvh_node_push_childs(root, isec, stack, stack_pos); + else + stack[stack_pos++] = root; + while(stack_pos) { Node *node = stack[--stack_pos]; diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp index 8a63e088a34..2c2a260df98 100644 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -26,18 +26,15 @@ * * ***** END GPL LICENSE BLOCK ***** */ -extern "C" -{ #include + +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" #include "BLI_arithb.h" #include "BLI_memarena.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" -}; - #include "bvh.h" #define BVH_NCHILDS 2 diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp new file mode 100644 index 00000000000..dff0b02c00e --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -0,0 +1,531 @@ +#include +#include +#include + +#include "rayobject_rtbuild.h" +#include "MEM_guardedalloc.h" +#include "BLI_arithb.h" +#include "BKE_utildefines.h" + +static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); +static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); +static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane); + +static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) +{ + int i; + + b->begin = begin; + b->end = end; + b->split_axis = 0; + b->child_sorted_axis = -1; + + for(i=0; ichild_offset[i] = 0; + + INIT_MINMAX(b->bb, b->bb+3); +} + +RTBuilder* rtbuild_create(int size) +{ + RTBuilder *builder = (RTBuilder*) MEM_mallocN( sizeof(RTBuilder), "RTBuilder" ); + RayObject **memblock= (RayObject**)MEM_mallocN( sizeof(RayObject*)*size,"RTBuilder.objects"); + rtbuild_init(builder, memblock, memblock); + return builder; +} + +void rtbuild_free(RTBuilder *b) +{ + MEM_freeN(b->begin); + MEM_freeN(b); +} + +void rtbuild_add(RTBuilder *b, RayObject *o) +{ + *(b->end++) = o; +} + +void rtbuild_calc_bb(RTBuilder *b) +{ + if(b->bb[0] == 1.0e30f) + { + RayObject **index = b->begin; + for(; index != b->end; index++) + RE_rayobject_merge_bb(*index, b->bb, b->bb+3); + } +} + +void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) +{ + rtbuild_calc_bb(b); + DO_MIN(b->bb, min); + DO_MAX(b->bb+3, max); +} + +int rtbuild_get_largest_axis(RTBuilder *b) +{ + rtbuild_calc_bb(b); + return bb_largest_axis(b->bb, b->bb+3); +} + + +int rtbuild_size(RTBuilder *b) +{ + return b->end - b->begin; +} + + +RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) +{ + rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); + tmp->child_sorted_axis = b->child_sorted_axis; + return tmp; +} + + + +//Left balanced tree +int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) +{ + int i; + int mleafs_per_child, Mleafs_per_child; + int tot_leafs = rtbuild_size(b); + int missing_leafs; + + long long s; + + assert(nchilds <= RTBUILD_MAX_CHILDS); + + //TODO optimize calc of leafs_per_child + for(s=nchilds; schild_offset[0] = 0; + for(i=1; i<=nchilds; i++) + b->child_offset[i] = mleafs_per_child; + + //split remaining leafs + missing_leafs = tot_leafs - mleafs_per_child*nchilds; + for(i=1; i<=nchilds; i++) + { + if(missing_leafs > Mleafs_per_child - mleafs_per_child) + { + b->child_offset[i] += Mleafs_per_child - mleafs_per_child; + missing_leafs -= Mleafs_per_child - mleafs_per_child; + } + else + { + b->child_offset[i] += missing_leafs; + missing_leafs = 0; + break; + } + } + + //adjust for accumulative offsets + for(i=1; i<=nchilds; i++) + b->child_offset[i] += b->child_offset[i-1]; + + //Count created childs + for(i=nchilds; b->child_offset[i] == b->child_offset[i-1]; i--); + split_leafs(b, b->child_offset, i, axis); + + assert( b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs ); + return i; +} + + +int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) +{ + int axis = rtbuild_get_largest_axis(b); + return rtbuild_mean_split(b, nchilds, axis); +} + +/* + * "separators" is an array of dim NCHILDS-1 + * and indicates where to cut the childs + */ +int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis) +{ + int size = rtbuild_size(b); + + assert(nchilds <= RTBUILD_MAX_CHILDS); + if(size <= nchilds) + { + return rtbuild_mean_split(b, nchilds, axis); + } + else + { + int i; + + b->split_axis = axis; + + //Calculate child offsets + b->child_offset[0] = 0; + for(i=0; ichild_offset[i+1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]); + b->child_offset[nchilds] = size; + + for(i=0; ichild_offset[i+1] - b->child_offset[i] == size) + return rtbuild_mean_split(b, nchilds, axis); + + return nchilds; + } +} + +int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) +{ + int la, i; + float separators[RTBUILD_MAX_CHILDS]; + + rtbuild_calc_bb(b); + + la = bb_largest_axis(b->bb,b->bb+3); + for(i=1; ibb[la+3]-b->bb[la])*i / nchilds; + + return rtbuild_median_split(b, separators, nchilds, la); +} + +//Heuristics Object Splitter +typedef struct CostObject CostObject; +struct CostObject +{ + RayObject *obj; + float cost; + float bb[6]; +}; + +//Ugly.. but using qsort and no globals its the cleaner I can get +#define costobject_cmp(axis) costobject_cmp##axis +#define define_costobject_cmp(axis) \ +int costobject_cmp(axis)(const CostObject *a, const CostObject *b) \ +{ \ + if(a->bb[axis] < b->bb[axis]) return -1; \ + if(a->bb[axis] > b->bb[axis]) return 1; \ + if(a->obj < b->obj) return -1; \ + if(a->obj > b->obj) return 1; \ + return 0; \ +} + +define_costobject_cmp(0) +define_costobject_cmp(1) +define_costobject_cmp(2) +define_costobject_cmp(3) +define_costobject_cmp(4) +define_costobject_cmp(5) + +void costobject_sort(CostObject *begin, CostObject *end, int axis) +{ + //TODO introsort + if(axis == 0) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(0)); + else if(axis == 1) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(1)); + else if(axis == 2) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(2)); + else if(axis == 3) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(3)); + else if(axis == 4) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(4)); + else if(axis == 5) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(5)); +} + + + +/* Object Surface Area Heuristic splitter */ +int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) +{ + int size = rtbuild_size(b); + assert(nchilds == 2); + + if(size <= nchilds) + { + return rtbuild_mean_split_largest_axis(b, nchilds); + } + else + { + float bcost = FLT_MAX; + float childrens_cost = 0; + int i, axis, baxis = -1, boffset = size/2, k, try_axis[3]; + CostObject *cost = (CostObject*)MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); + float *acc_bb = (float*)MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); + + for(i=0; ibegin[i]; + INIT_MINMAX(cost[i].bb, cost[i].bb+3); + RE_rayobject_merge_bb(cost[i].obj, cost[i].bb, cost[i].bb+3); + cost[i].cost = RE_rayobject_cost(cost[i].obj); + childrens_cost += cost[i].cost; + } + + if(b->child_sorted_axis >= 0 && b->child_sorted_axis < 3) + { + try_axis[0] = b->child_sorted_axis; + try_axis[1] = (b->child_sorted_axis+1)%3; + try_axis[2] = (b->child_sorted_axis+2)%3; + } + else + { + try_axis[0] = 0; + try_axis[1] = 1; + try_axis[2] = 2; + } + + for(axis=try_axis[k=0]; k<3; axis=try_axis[++k]) + { + float left_cost, right_cost; + float other_bb[6]; + + + + costobject_sort(cost, cost+size, axis); + for(i=size-1; i>=0; i--) + { + float *bb = acc_bb+i*6; + if(i == size-1) + { + VECCOPY(bb, cost[i].bb); + VECCOPY(bb+3, cost[i].bb+3); + } + else + { + bb[0] = MIN2(cost[i].bb[0], bb[6+0]); + bb[1] = MIN2(cost[i].bb[1], bb[6+1]); + bb[2] = MIN2(cost[i].bb[2], bb[6+2]); + + bb[3] = MAX2(cost[i].bb[3], bb[6+3]); + bb[4] = MAX2(cost[i].bb[4], bb[6+4]); + bb[5] = MAX2(cost[i].bb[5], bb[6+5]); + } + } + + INIT_MINMAX(other_bb, other_bb+3); + DO_MIN( cost[0].bb, other_bb ); + DO_MAX( cost[0].bb+3, other_bb+3 ); + left_cost = cost[0].cost; + right_cost = childrens_cost-cost[0].cost; + if(right_cost < 0) right_cost = 0; + + for(i=1; i bcost) break; //No way we can find a better heuristic in this axis + + hcost = left_side+right_side; + assert(hcost >= 0); + if( hcost < bcost + || (hcost == bcost && axis < baxis)) //this makes sure the tree built is the same whatever is the order of the sorting axis + { + bcost = hcost; + baxis = axis; + boffset = i; + } + DO_MIN( cost[i].bb, other_bb ); + DO_MAX( cost[i].bb+3, other_bb+3 ); + left_cost += cost[i].cost; + right_cost -= cost[i].cost; + if(right_cost < 0.0f) right_cost = 0.0; + } + + if(baxis == axis) + { + for(i=0; ibegin[i] = cost[i].obj; + b->child_sorted_axis = axis; + } + + assert(baxis >= 0 && baxis < 3); + } + + b->child_offset[0] = 0; + b->child_offset[1] = boffset; + b->child_offset[2] = size; + + MEM_freeN(acc_bb); + MEM_freeN(cost); + return nchilds; + } +} + +/* + * Helper code + * PARTITION code / used on mean-split + * basicly this a std::nth_element (like on C++ STL algorithm) + */ +static void sort_swap(RTBuilder *b, int i, int j) +{ + SWAP(RayObject*, b->begin[i], b->begin[j]); +} + +static float sort_get_value(RTBuilder *b, int i) +{ + float min[3], max[3]; + INIT_MINMAX(min, max); + RE_rayobject_merge_bb(b->begin[i], min, max); + return max[b->split_axis]; +} + +static int medianof3(RTBuilder *d, int a, int b, int c) +{ + float fa = sort_get_value( d, a ); + float fb = sort_get_value( d, b ); + float fc = sort_get_value( d, c ); + + if(fb < fa) + { + if(fc < fb) + return b; + else + { + if(fc < fa) + return c; + else + return a; + } + } + else + { + if(fc < fb) + { + if(fc < fa) + return a; + else + return c; + } + else + return b; + } +} + +static void insertionsort(RTBuilder *b, int lo, int hi) +{ + int i; + for(i=lo; ibegin[i]; + float tv= sort_get_value(b, i); + int j=i; + + while( j != lo && tv < sort_get_value(b, j-1)) + { + b->begin[j] = b->begin[j-1]; + j--; + } + b->begin[j] = t; + } +} + +static int partition(RTBuilder *b, int lo, int mid, int hi) +{ + float x = sort_get_value( b, mid ); + + int i=lo, j=hi; + while (1) + { + while(sort_get_value(b,i) < x) i++; + j--; + while(x < sort_get_value(b,j)) j--; + if(!(i < j)) + return i; + + sort_swap(b, i, j); + i++; + } +} + +// +// PARTITION code / used on mean-split +// basicly this is an adapted std::nth_element (C++ STL ) +// +// after a call to this function you can expect one of: +// every node to left of a[n] are smaller or equal to it +// every node to the right of a[n] are greater or equal to it +static int partition_nth_element(RTBuilder *b, int _begin, int n, int _end) +{ + int begin = _begin, end = _end, cut; + while(end-begin > 3) + { + cut = partition(b, begin, medianof3(b, begin, begin+(end-begin)/2, end-1), end); + if(cut <= n) + begin = cut; + else + end = cut; + } + insertionsort(b, begin, end); + + return n; +} + +static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) +{ + int i; + b->split_axis = split_axis; + + for(i=0; i < partitions-1; i++) + { + assert(nth[i] < nth[i+1] && nth[i+1] < nth[partitions]); + + partition_nth_element(b, nth[i], nth[i+1], nth[partitions] ); + } +} + +static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane) +{ + int i; + for(i = begin; i != end; i++) + { + if(sort_get_value(b, i) < plane) + { + sort_swap(b, i, begin); + begin++; + } + } + return begin; +} + +/* + * Bounding Box utils + */ +float bb_volume(float *min, float *max) +{ + return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]); +} + +float bb_area(float *min, float *max) +{ + float sub[3], a; + sub[0] = max[0]-min[0]; + sub[1] = max[1]-min[1]; + sub[2] = max[2]-min[2]; + + a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; + assert(a >= 0.0); + return a; +} + +int bb_largest_axis(float *min, float *max) +{ + float sub[3]; + + sub[0] = max[0]-min[0]; + sub[1] = max[1]-min[1]; + sub[2] = max[2]-min[2]; + if(sub[0] > sub[1]) + { + if(sub[0] > sub[2]) + return 0; + else + return 2; + } + else + { + if(sub[1] > sub[2]) + return 1; + else + return 2; + } +} diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp new file mode 100644 index 00000000000..3f8f69a5abe --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -0,0 +1,248 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +extern "C" +{ +#include +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "BLI_memarena.h" +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" +}; + +#include "bvh.h" +#include + +#define BVHNode VBVHNode +#define BVHTree VBVHTree + +#define RAY_BB_TEST_COST (0.2f) +#define DFS_STACK_SIZE 128 +#define DYNAMIC_ALLOC + +//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ +//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ +#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ + +struct BVHNode +{ + BVHNode *child; + BVHNode *sibling; + + float bb[6]; +}; + +struct BVHTree +{ + RayObject rayobj; + + BVHNode *root; + + MemArena *node_arena; + + float cost; + RTBuilder *builder; +}; + + +/* + * Push nodes (used on dfs) + */ +template +inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) +{ + Node *child = node->child; + while(child) + { + stack[stack_pos++] = child; + if(RayObject_isAligned(child)) + child = child->sibling; + else break; + } +} + +/* + * BVH done + */ +static BVHNode *bvh_new_node(BVHTree *tree) +{ + BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + node->sibling = NULL; + node->child = NULL; + + assert(RayObject_isAligned(node)); + return node; +} + +template +float rtbuild_area(Builder *builder) +{ + float min[3], max[3]; + INIT_MINMAX(min, max); + rtbuild_merge_bb(builder, min, max); + return bb_area(min, max); +} + +template +void bvh_update_bb(Node *node) +{ + INIT_MINMAX(node->bb, node->bb+3); + Node *child = node->child; + + while(child) + { + bvh_node_merge_bb(child, node->bb, node->bb+3); + if(RayObject_isAligned(child)) + child = child->sibling; + else + child = 0; + } +} + + +template +Node *bvh_rearrange(Tree *tree, Builder *builder, float *cost) +{ + + int size = rtbuild_size(builder); + if(size == 1) + { + Node *node = bvh_new_node(tree); + INIT_MINMAX(node->bb, node->bb+3); + rtbuild_merge_bb(builder, node->bb, node->bb+3); + + node->child = (BVHNode*)builder->begin[0]; + + *cost = RE_rayobject_cost((RayObject*)node->child)+RAY_BB_TEST_COST; + return node; + } + else + { + Node *node = bvh_new_node(tree); + float parent_area; + + INIT_MINMAX(node->bb, node->bb+3); + rtbuild_merge_bb(builder, node->bb, node->bb+3); + + parent_area = bb_area( node->bb, node->bb+3 ); + Node **child = &node->child; + + std::queue childs; + childs.push(*builder); + + *cost = 0; + + while(!childs.empty()) + { + Builder b = childs.front(); + childs.pop(); + + float hit_prob = rtbuild_area(&b) / parent_area; + if(hit_prob > 1.0f / 2.0f && rtbuild_size(&b) > 1) + { + //The expected number of BB test is smaller if we directly add the 2 childs of this node + int nc = rtbuild_split(&b, 2); + assert(nc == 2); + for(int i=0; i(tree, &b, &tcost); + child = &((*child)->sibling); + + *cost += tcost*hit_prob + RAY_BB_TEST_COST; + } + } + assert(child != &node->child); + *child = 0; + + return node; + } +} + +template<> +void bvh_done(BVHTree *obj) +{ + int needed_nodes = (rtbuild_size(obj->builder)+1)*2; + if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) + needed_nodes = BLI_MEMARENA_STD_BUFSIZE; + + obj->node_arena = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(obj->node_arena); + + + obj->root = bvh_rearrange( obj, obj->builder, &obj->cost ); + obj->cost = 1.0; + + rtbuild_free( obj->builder ); + obj->builder = NULL; +} + +template<> +int bvh_intersect(BVHTree *obj, Isect* isec) +{ + if(RayObject_isAligned(obj->root)) + return bvh_node_stack_raycast(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); +} + +/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ +static RayObjectAPI bvh_api = +{ + (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect), + (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), + (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), + (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) +}; + +RayObject *RE_rayobject_vbvh_create(int size) +{ + BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bvh_api; + obj->root = NULL; + + obj->node_arena = NULL; + obj->builder = rtbuild_create( size ); + + return RayObject_unalignRayAPI((RayObject*) obj); +} diff --git a/source/blender/render/intern/source/rayobject_rtbuild.c b/source/blender/render/intern/source/rayobject_rtbuild.c deleted file mode 100644 index 3c301ce1f9f..00000000000 --- a/source/blender/render/intern/source/rayobject_rtbuild.c +++ /dev/null @@ -1,531 +0,0 @@ -#include -#include -#include - -#include "rayobject_rtbuild.h" -#include "MEM_guardedalloc.h" -#include "BLI_arithb.h" -#include "BKE_utildefines.h" - -static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); -static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); -static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane); - -static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) -{ - int i; - - b->begin = begin; - b->end = end; - b->split_axis = 0; - b->child_sorted_axis = -1; - - for(i=0; ichild_offset[i] = 0; - - INIT_MINMAX(b->bb, b->bb+3); -} - -RTBuilder* rtbuild_create(int size) -{ - RTBuilder *builder = (RTBuilder*) MEM_mallocN( sizeof(RTBuilder), "RTBuilder" ); - RayObject **memblock= (RayObject**)MEM_mallocN( sizeof(RayObject*)*size,"RTBuilder.objects"); - rtbuild_init(builder, memblock, memblock); - return builder; -} - -void rtbuild_free(RTBuilder *b) -{ - MEM_freeN(b->begin); - MEM_freeN(b); -} - -void rtbuild_add(RTBuilder *b, RayObject *o) -{ - *(b->end++) = o; -} - -void rtbuild_calc_bb(RTBuilder *b) -{ - if(b->bb[0] == 1.0e30f) - { - RayObject **index = b->begin; - for(; index != b->end; index++) - RE_rayobject_merge_bb(*index, b->bb, b->bb+3); - } -} - -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) -{ - rtbuild_calc_bb(b); - DO_MIN(b->bb, min); - DO_MAX(b->bb+3, max); -} - -int rtbuild_get_largest_axis(RTBuilder *b) -{ - rtbuild_calc_bb(b); - return bb_largest_axis(b->bb, b->bb+3); -} - - -int rtbuild_size(RTBuilder *b) -{ - return b->end - b->begin; -} - - -RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) -{ - rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); - tmp->child_sorted_axis = b->child_sorted_axis; - return tmp; -} - - - -//Left balanced tree -int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) -{ - int i; - int mleafs_per_child, Mleafs_per_child; - int tot_leafs = rtbuild_size(b); - int missing_leafs; - - long long s; - - assert(nchilds <= RTBUILD_MAX_CHILDS); - - //TODO optimize calc of leafs_per_child - for(s=nchilds; schild_offset[0] = 0; - for(i=1; i<=nchilds; i++) - b->child_offset[i] = mleafs_per_child; - - //split remaining leafs - missing_leafs = tot_leafs - mleafs_per_child*nchilds; - for(i=1; i<=nchilds; i++) - { - if(missing_leafs > Mleafs_per_child - mleafs_per_child) - { - b->child_offset[i] += Mleafs_per_child - mleafs_per_child; - missing_leafs -= Mleafs_per_child - mleafs_per_child; - } - else - { - b->child_offset[i] += missing_leafs; - missing_leafs = 0; - break; - } - } - - //adjust for accumulative offsets - for(i=1; i<=nchilds; i++) - b->child_offset[i] += b->child_offset[i-1]; - - //Count created childs - for(i=nchilds; b->child_offset[i] == b->child_offset[i-1]; i--); - split_leafs(b, b->child_offset, i, axis); - - assert( b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs ); - return i; -} - - -int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) -{ - int axis = rtbuild_get_largest_axis(b); - return rtbuild_mean_split(b, nchilds, axis); -} - -/* - * "separators" is an array of dim NCHILDS-1 - * and indicates where to cut the childs - */ -int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis) -{ - int size = rtbuild_size(b); - - assert(nchilds <= RTBUILD_MAX_CHILDS); - if(size <= nchilds) - { - return rtbuild_mean_split(b, nchilds, axis); - } - else - { - int i; - - b->split_axis = axis; - - //Calculate child offsets - b->child_offset[0] = 0; - for(i=0; ichild_offset[i+1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]); - b->child_offset[nchilds] = size; - - for(i=0; ichild_offset[i+1] - b->child_offset[i] == size) - return rtbuild_mean_split(b, nchilds, axis); - - return nchilds; - } -} - -int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) -{ - int la, i; - float separators[RTBUILD_MAX_CHILDS]; - - rtbuild_calc_bb(b); - - la = bb_largest_axis(b->bb,b->bb+3); - for(i=1; ibb[la+3]-b->bb[la])*i / nchilds; - - return rtbuild_median_split(b, separators, nchilds, la); -} - -//Heuristics Object Splitter -typedef struct CostObject CostObject; -struct CostObject -{ - RayObject *obj; - float cost; - float bb[6]; -}; - -//Ugly.. but using qsort and no globals its the cleaner I can get -#define costobject_cmp(axis) costobject_cmp##axis -#define define_costobject_cmp(axis) \ -int costobject_cmp(axis)(const CostObject *a, const CostObject *b) \ -{ \ - if(a->bb[axis] < b->bb[axis]) return -1; \ - if(a->bb[axis] > b->bb[axis]) return 1; \ - if(a->obj < b->obj) return -1; \ - if(a->obj > b->obj) return 1; \ - return 0; \ -} - -define_costobject_cmp(0) -define_costobject_cmp(1) -define_costobject_cmp(2) -define_costobject_cmp(3) -define_costobject_cmp(4) -define_costobject_cmp(5) - -void costobject_sort(CostObject *begin, CostObject *end, int axis) -{ - //TODO introsort - if(axis == 0) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(0)); - else if(axis == 1) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(1)); - else if(axis == 2) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(2)); - else if(axis == 3) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(3)); - else if(axis == 4) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(4)); - else if(axis == 5) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(5)); -} - - - -/* Object Surface Area Heuristic splitter */ -int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) -{ - int size = rtbuild_size(b); - assert(nchilds == 2); - - if(size <= nchilds) - { - return rtbuild_mean_split_largest_axis(b, nchilds); - } - else - { - float bcost = FLT_MAX; - float childrens_cost = 0; - int i, axis, baxis = -1, boffset = size/2, k, try_axis[3]; - CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); - float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); - - for(i=0; ibegin[i]; - INIT_MINMAX(cost[i].bb, cost[i].bb+3); - RE_rayobject_merge_bb(cost[i].obj, cost[i].bb, cost[i].bb+3); - cost[i].cost = RE_rayobject_cost(cost[i].obj); - childrens_cost += cost[i].cost; - } - - if(b->child_sorted_axis >= 0 && b->child_sorted_axis < 3) - { - try_axis[0] = b->child_sorted_axis; - try_axis[1] = (b->child_sorted_axis+1)%3; - try_axis[2] = (b->child_sorted_axis+2)%3; - } - else - { - try_axis[0] = 0; - try_axis[1] = 1; - try_axis[2] = 2; - } - - for(axis=try_axis[k=0]; k<3; axis=try_axis[++k]) - { - float left_cost, right_cost; - float other_bb[6]; - - - - costobject_sort(cost, cost+size, axis); - for(i=size-1; i>=0; i--) - { - float *bb = acc_bb+i*6; - if(i == size-1) - { - VECCOPY(bb, cost[i].bb); - VECCOPY(bb+3, cost[i].bb+3); - } - else - { - bb[0] = MIN2(cost[i].bb[0], bb[6+0]); - bb[1] = MIN2(cost[i].bb[1], bb[6+1]); - bb[2] = MIN2(cost[i].bb[2], bb[6+2]); - - bb[3] = MAX2(cost[i].bb[3], bb[6+3]); - bb[4] = MAX2(cost[i].bb[4], bb[6+4]); - bb[5] = MAX2(cost[i].bb[5], bb[6+5]); - } - } - - INIT_MINMAX(other_bb, other_bb+3); - DO_MIN( cost[0].bb, other_bb ); - DO_MAX( cost[0].bb+3, other_bb+3 ); - left_cost = cost[0].cost; - right_cost = childrens_cost-cost[0].cost; - if(right_cost < 0) right_cost = 0; - - for(i=1; i bcost) break; //No way we can find a better heuristic in this axis - - hcost = left_side+right_side; - assert(hcost >= 0); - if( hcost < bcost - || (hcost == bcost && axis < baxis)) //this makes sure the tree built is the same whatever is the order of the sorting axis - { - bcost = hcost; - baxis = axis; - boffset = i; - } - DO_MIN( cost[i].bb, other_bb ); - DO_MAX( cost[i].bb+3, other_bb+3 ); - left_cost += cost[i].cost; - right_cost -= cost[i].cost; - if(right_cost < 0.0f) right_cost = 0.0; - } - - if(baxis == axis) - { - for(i=0; ibegin[i] = cost[i].obj; - b->child_sorted_axis = axis; - } - - assert(baxis >= 0 && baxis < 3); - } - - b->child_offset[0] = 0; - b->child_offset[1] = boffset; - b->child_offset[2] = size; - - MEM_freeN(acc_bb); - MEM_freeN(cost); - return nchilds; - } -} - -/* - * Helper code - * PARTITION code / used on mean-split - * basicly this a std::nth_element (like on C++ STL algorithm) - */ -static void sort_swap(RTBuilder *b, int i, int j) -{ - SWAP(RayObject*, b->begin[i], b->begin[j]); -} - -static float sort_get_value(RTBuilder *b, int i) -{ - float min[3], max[3]; - INIT_MINMAX(min, max); - RE_rayobject_merge_bb(b->begin[i], min, max); - return max[b->split_axis]; -} - -static int medianof3(RTBuilder *d, int a, int b, int c) -{ - float fa = sort_get_value( d, a ); - float fb = sort_get_value( d, b ); - float fc = sort_get_value( d, c ); - - if(fb < fa) - { - if(fc < fb) - return b; - else - { - if(fc < fa) - return c; - else - return a; - } - } - else - { - if(fc < fb) - { - if(fc < fa) - return a; - else - return c; - } - else - return b; - } -} - -static void insertionsort(RTBuilder *b, int lo, int hi) -{ - int i; - for(i=lo; ibegin[i]; - float tv= sort_get_value(b, i); - int j=i; - - while( j != lo && tv < sort_get_value(b, j-1)) - { - b->begin[j] = b->begin[j-1]; - j--; - } - b->begin[j] = t; - } -} - -static int partition(RTBuilder *b, int lo, int mid, int hi) -{ - float x = sort_get_value( b, mid ); - - int i=lo, j=hi; - while (1) - { - while(sort_get_value(b,i) < x) i++; - j--; - while(x < sort_get_value(b,j)) j--; - if(!(i < j)) - return i; - - sort_swap(b, i, j); - i++; - } -} - -// -// PARTITION code / used on mean-split -// basicly this is an adapted std::nth_element (C++ STL ) -// -// after a call to this function you can expect one of: -// every node to left of a[n] are smaller or equal to it -// every node to the right of a[n] are greater or equal to it -static int partition_nth_element(RTBuilder *b, int _begin, int n, int _end) -{ - int begin = _begin, end = _end, cut; - while(end-begin > 3) - { - cut = partition(b, begin, medianof3(b, begin, begin+(end-begin)/2, end-1), end); - if(cut <= n) - begin = cut; - else - end = cut; - } - insertionsort(b, begin, end); - - return n; -} - -static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) -{ - int i; - b->split_axis = split_axis; - - for(i=0; i < partitions-1; i++) - { - assert(nth[i] < nth[i+1] && nth[i+1] < nth[partitions]); - - partition_nth_element(b, nth[i], nth[i+1], nth[partitions] ); - } -} - -static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane) -{ - int i; - for(i = begin; i != end; i++) - { - if(sort_get_value(b, i) < plane) - { - sort_swap(b, i, begin); - begin++; - } - } - return begin; -} - -/* - * Bounding Box utils - */ -float bb_volume(float *min, float *max) -{ - return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]); -} - -float bb_area(float *min, float *max) -{ - float sub[3], a; - sub[0] = max[0]-min[0]; - sub[1] = max[1]-min[1]; - sub[2] = max[2]-min[2]; - - a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; - assert(a >= 0.0); - return a; -} - -int bb_largest_axis(float *min, float *max) -{ - float sub[3]; - - sub[0] = max[0]-min[0]; - sub[1] = max[1]-min[1]; - sub[2] = max[2]-min[2]; - if(sub[0] > sub[1]) - { - if(sub[0] > sub[2]) - return 0; - else - return 2; - } - else - { - if(sub[1] > sub[2]) - return 1; - else - return 2; - } -} diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index b967f2bd8ce..52edd7a7e27 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -70,8 +70,13 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -RayObject *RE_rayobject_tree_create(int type, int size) +RayObject * RE_rayobject_tree_create(int type, int size) __attribute__((noinline)); + +RayObject * RE_rayobject_tree_create(int type, int size) { +// if(type == R_RAYTRACE_TREE_BIH) + return RE_rayobject_vbvh_create(size); + if(type == R_RAYTRACE_TREE_BVH) return RE_rayobject_bvh_create(size); if(type == R_RAYTRACE_TREE_BIH) @@ -79,7 +84,6 @@ RayObject *RE_rayobject_tree_create(int type, int size) if(type == R_RAYTRACE_TREE_BLIBVH) return RE_rayobject_blibvh_create(size); - return RE_rayobject_bvh_create(size); } #ifdef RE_RAYCOUNTER -- cgit v1.2.3 From fb150e12c560acd1418c106dbbe94f757731db09 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 13 Jul 2009 11:04:18 +0000 Subject: - FBX exporter conversion continued - added (uncommented actually) PoseChannel.pose_matrix - added Object.dag_update that calls DAG_object_flush_update. I'm not sure if it's needed, but FBX exporter uses it. --- release/io/export_fbx.py | 174 +++++++++++++++++------- source/blender/makesrna/intern/rna_object_api.c | 25 +++- source/blender/makesrna/intern/rna_pose.c | 9 +- 3 files changed, 147 insertions(+), 61 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 063a52b2f7d..0a6588c380b 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -37,12 +37,13 @@ http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx # -------------------------------------------------------------------------- import os +import time -try: - import time - # import os # only needed for batch export, nbot used yet -except: - time = None # use this to check if they have python modules installed +# try: +# import time +# # import os # only needed for batch export, nbot used yet +# except: +# time = None # use this to check if they have python modules installed # for python 2.3 support try: @@ -114,10 +115,41 @@ def copy_images(dest_dir, textures): print '\tCopied %d images' % copyCount -mtx4_identity = Matrix() +def BPyObject_getObjectArmature(ob): + ''' + This returns the first armature the mesh uses. + remember there can be more then 1 armature but most people dont do that. + ''' + if ob.type != 'MESH': + return None + + arm = ob.parent + if arm and arm.type == 'ARMATURE' and ob.parent_type == 'ARMATURE': + return arm + + for m in ob.modifiers: + if m.type== 'ARMATURE': + arm = m.object + if arm: + return arm + + return None + +# I guess FBX uses degrees instead of radians (Arystan). +# Call this function just before writing to FBX. +def eulerRadToDeg(eul): + ret = Mathutils.Euler() + + ret.x = 180 / math.pi * eul.x + ret.y = 180 / math.pi * eul.y + ret.z = 180 / math.pi * eul.z + + return ret + +mtx4_identity = Mathutils.Matrix() # testing -mtx_x90 = RotationMatrix( 90, 3, 'x') # used +mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used #mtx_x90n = RotationMatrix(-90, 3, 'x') #mtx_y90 = RotationMatrix( 90, 3, 'y') #mtx_y90n = RotationMatrix(-90, 3, 'y') @@ -125,14 +157,14 @@ mtx_x90 = RotationMatrix( 90, 3, 'x') # used #mtx_z90n = RotationMatrix(-90, 3, 'z') #mtx4_x90 = RotationMatrix( 90, 4, 'x') -mtx4_x90n = RotationMatrix(-90, 4, 'x') # used +mtx4_x90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'x') # used #mtx4_y90 = RotationMatrix( 90, 4, 'y') -mtx4_y90n = RotationMatrix(-90, 4, 'y') # used -mtx4_z90 = RotationMatrix( 90, 4, 'z') # used -mtx4_z90n = RotationMatrix(-90, 4, 'z') # used +mtx4_y90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'y') # used +mtx4_z90 = Mathutils.RotationMatrix( math.pi/2, 4, 'z') # used +mtx4_z90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'z') # used -def strip_path(p): - return p.split('\\')[-1].split('/')[-1] +# def strip_path(p): +# return p.split('\\')[-1].split('/')[-1] # Used to add the scene name into the filename without using odd chars sane_name_mapping_ob = {} @@ -212,7 +244,8 @@ def derived_paths(fname_orig, basepath, FORCE_CWD=False): ''' fname = bpy.sys.expandpath(fname_orig) # fname = Blender.sys.expandpath(fname_orig) - fname_strip = strip_path(fname) + fname_strip = os.path.basename(fname) +# fname_strip = strip_path(fname) if FORCE_CWD: fname_rel = '.' + os.sep + fname_strip else: @@ -265,7 +298,7 @@ def write(filename, batch_objects = None, \ EXP_CAMERA = True, EXP_EMPTY = True, EXP_IMAGE_COPY = False, - GLOBAL_MATRIX = Matrix(), + GLOBAL_MATRIX = Mathutils.Matrix(), ANIM_ENABLE = True, ANIM_OPTIMIZE = True, ANIM_OPTIMIZE_PRECISSION = 6, @@ -288,9 +321,11 @@ def write(filename, batch_objects = None, \ # tmp_exists = Blender.sys.exists(fbxpath) if tmp_exists != 2: # a file, we want a path - while fbxpath and fbxpath[-1] not in ('/', '\\'): - fbxpath = fbxpath[:-1] - if not filename: + fbxpath = os.path.dirname(fbxpath) +# while fbxpath and fbxpath[-1] not in ('/', '\\'): +# fbxpath = fbxpath[:-1] + if not fbxpath: +# if not filename: # XXX print('Error%t|Directory does not exist!') # Draw.PupMenu('Error%t|Directory does not exist!') @@ -391,7 +426,9 @@ def write(filename, batch_objects = None, \ # end batch support # Use this for working out paths relative to the export location - basepath = Blender.sys.dirname(filename) + basepath = os.path.dirname(filename) or '.' + basepath += os.sep +# basepath = Blender.sys.dirname(filename) # ---------------------------------------------- # storage classes @@ -429,7 +466,8 @@ def write(filename, batch_objects = None, \ # not public pose = fbxArm.blenObject.pose # pose = fbxArm.blenObject.getPose() - self.__pose_bone = pose.bones[self.blenName] + self.__pose_bone = pose.pose_channels[self.blenName] +# self.__pose_bone = pose.bones[self.blenName] # store a list if matricies here, (poseMatrix, head, tail) # {frame:posematrix, frame:posematrix, ...} @@ -452,8 +490,9 @@ def write(filename, batch_objects = None, \ self.__pose_bone.head.copy(),\ self.__pose_bone.tail.copy() ) ''' - - self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy() + + self.__anim_poselist[f] = self.__pose_bone.pose_matrix.copy() +# self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy() # get pose from frame. def getPoseMatrix(self, f):# ---------------------------------------------- @@ -521,11 +560,12 @@ def write(filename, batch_objects = None, \ matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart() # Lamps need to be rotated - if type =='Lamp': + if type =='LAMP': matrix_rot = mtx_x90 * matrix_rot - elif ob and type =='Camera': + elif type =='CAMERA': +# elif ob and type =='Camera': y = Vector(0,1,0) * matrix_rot - matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y) + matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) return matrix_rot @@ -627,7 +667,7 @@ def write(filename, batch_objects = None, \ rot = tuple(matrix_rot.toEuler()) elif ob and ob.type =='Camera': y = Vector(0,1,0) * matrix_rot - matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y) + matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) rot = tuple(matrix_rot.toEuler()) else: rot = tuple(matrix_rot.toEuler()) @@ -648,7 +688,8 @@ def write(filename, batch_objects = None, \ loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod) file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc) - file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) + file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % eulerRadToDeg(rot)) +# file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale) return loc, rot, scale, matrix, matrix_rot @@ -735,7 +776,8 @@ def write(filename, batch_objects = None, \ Property: "Show", "bool", "",1 Property: "NegativePercentShapeSupport", "bool", "",1 Property: "DefaultAttributeIndex", "int", "",0''') - if ob and type(ob) != Blender.Types.BoneType: + if ob and not isinstance(ob, bpy.types.Bone): +# if ob and type(ob) != Blender.Types.BoneType: # Only mesh objects have color file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') file.write('\n\t\t\tProperty: "Size", "double", "",100') @@ -1214,7 +1256,8 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t}') file.write('\n\t}') - + + # tex is an Image (Arystan) def write_video(texname, tex): # Same as texture really! file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) @@ -1276,9 +1319,11 @@ def write(filename, batch_objects = None, \ Property: "UseMipMap", "bool", "",0 Property: "CurrentMappingType", "enum", "",0 Property: "UVSwap", "bool", "",0''') - - file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX) - file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY) + + file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clamp_x) +# file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX) + file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clamp_y) +# file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY) file.write(''' Property: "TextureRotationPivot", "Vector3D", "",0,0,0 @@ -1915,13 +1960,16 @@ def write(filename, batch_objects = None, \ else: # Mesh Type! if EXP_MESH_APPLY_MOD: - me = bpy.data.meshes.new() - me.getFromObject(ob) +# me = bpy.data.meshes.new() + me = ob.create_mesh('PREVIEW') +# me.getFromObject(ob) # so we keep the vert groups if EXP_ARMATURE: - orig_mesh = ob.getData(mesh=1) - if orig_mesh.getVertGroupNames(): + orig_mesh = ob.data +# orig_mesh = ob.getData(mesh=1) + if len(ob.vertex_groups): +# if orig_mesh.getVertGroupNames(): ob.copy().link(me) # If new mesh has no vgroups we can try add if verts are teh same if not me.getVertGroupNames(): # vgroups were not kept by the modifier @@ -1980,7 +2028,7 @@ def write(filename, batch_objects = None, \ materials[None, None] = None if EXP_ARMATURE: - armob = BPyObject.getObjectArmature(ob) + armob = BPyObject_getObjectArmature(ob) blenParentBoneName = None # parent bone - special case @@ -2014,14 +2062,17 @@ def write(filename, batch_objects = None, \ if EXP_ARMATURE: # now we have the meshes, restore the rest arm position for i, arm in enumerate(bpy.data.armatures): - arm.restPosition = ob_arms_orig_rest[i] + arm.rest_position = ob_arms_orig_rest[i] +# arm.restPosition = ob_arms_orig_rest[i] if ob_arms_orig_rest: for ob_base in bpy.data.objects: if ob_base.type == 'Armature': - ob_base.makeDisplayList() + ob_base.dag_update() +# ob_base.makeDisplayList() # This causes the makeDisplayList command to effect the mesh - Blender.Set('curframe', Blender.Get('curframe')) + sce.set_frame(sce.current_frame) +# Blender.Set('curframe', Blender.Get('curframe')) del tmp_ob_type, tmp_objects @@ -2032,7 +2083,11 @@ def write(filename, batch_objects = None, \ my_arm.fbxBones = [] my_arm.blenData = ob.data - my_arm.blenAction = ob.action + if ob.animation_data: + my_arm.blenAction = ob.animation_data.action + else: + my_arm.blenAction = None +# my_arm.blenAction = ob.action my_arm.blenActionList = [] # fbxName, blenderObject, my_bones, blenderActions @@ -2087,7 +2142,8 @@ def write(filename, batch_objects = None, \ # Build blenObject -> fbxObject mapping # this is needed for groups as well as fbxParenting - bpy.data.objects.tag = False + for ob in bpy.data.objects: ob.tag = False +# bpy.data.objects.tag = False tmp_obmapping = {} for ob_generic in ob_all_typegroups: for ob_base in ob_generic: @@ -2512,7 +2568,8 @@ Connections: {''') action_lastcompat = None if ANIM_ACTION_ALL: - bpy.data.actions.tag = False + for a in bpy.data.actions: a.tag = False +# bpy.data.actions.tag = False tmp_actions = list(bpy.data.actions) @@ -2528,8 +2585,9 @@ Connections: {''') arm_bone_names = set([my_bone.blenName for my_bone in my_arm.fbxBones]) for action in tmp_actions: - - action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) ) + + action_chan_names = arm_bone_names.intersection( set([g.name for g in action.groups]) ) +# action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) ) if action_chan_names: # at least one channel matches. my_arm.blenActionList.append(action) @@ -2661,7 +2719,8 @@ Takes: {''') for mtx in context_bone_anim_mats: if prev_eul: prev_eul = mtx[1].toEuler(prev_eul) else: prev_eul = mtx[1].toEuler() - context_bone_anim_vecs.append(prev_eul) + context_bone_anim_vecs.append(eulerRadToDeg(prev_eul)) +# context_bone_anim_vecs.append(prev_eul) file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation @@ -2752,8 +2811,9 @@ Takes: {''') my_bone.blenObject.action = my_bone.blenAction file.write('\n}') - - Blender.Set('curframe', frame_orig) + + sce.set_frame(frame_orig) +# Blender.Set('curframe', frame_orig) else: # no animation @@ -2771,15 +2831,23 @@ Takes: {''') # Clear mesh data Only when writing with modifiers applied for me in meshes_to_clear: - me.verts = None + bpy.data.remove_mesh(me) +# me.verts = None # --------------------------- Footer if world: - has_mist = world.mode & 1 - mist_intense, mist_start, mist_end, mist_height = world.mist - world_hor = world.hor + m = world.mist + has_mist = m.enabled +# has_mist = world.mode & 1 + mist_intense = m.intensity + mist_start = m.start + mist_end = m.depth + mist_height = m.height +# mist_intense, mist_start, mist_end, mist_height = world.mist + world_hor = world.horizon_color +# world_hor = world.hor else: has_mist = mist_intense = mist_start = mist_end = mist_height = 0 world_hor = 0,0,0 @@ -3146,6 +3214,8 @@ if __name__ == '__main__': # - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print # - get rid of cleanName somehow # - isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 +# - get rid of BPyObject_getObjectArmature, move it in RNA? +# - BATCH_ENABLE and BATCH_GROUP options: line 327 # TODO diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 02db7e83062..bf1fb6d2b6a 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -166,6 +166,11 @@ static void rna_Object_add_vertex_to_group(Object *ob, int vertex_index, bDeform add_vert_to_defgroup(ob, def, vertex_index, weight, assignmode); } +static void rna_Object_dag_update(Object *ob, bContext *C) +{ + DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA); +} + /* static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int *indices, int totindex, float weight, int assignmode) { @@ -222,6 +227,7 @@ void RNA_api_object(StructRNA *srna) {0, NULL, 0, NULL, NULL} }; + /* mesh */ func= RNA_def_function(srna, "create_mesh", "rna_Object_create_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); @@ -230,6 +236,13 @@ void RNA_api_object(StructRNA *srna) parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); + func= RNA_def_function(srna, "convert_to_triface", "rna_Object_convert_to_triface"); + RNA_def_function_ui_description(func, "Convert all mesh faces to triangles."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); + parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object belongs."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /* duplis */ func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist"); RNA_def_function_ui_description(func, "Create a list of dupli objects for this object, needs to be freed manually with free_dupli_list."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); @@ -238,12 +251,7 @@ void RNA_api_object(StructRNA *srna) RNA_def_function_ui_description(func, "Free the list of dupli objects."); RNA_def_function_flag(func, FUNC_USE_REPORTS); - func= RNA_def_function(srna, "convert_to_triface", "rna_Object_convert_to_triface"); - RNA_def_function_ui_description(func, "Convert all mesh faces to triangles."); - RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object belongs."); - RNA_def_property_flag(parm, PROP_REQUIRED); - + /* vertex groups */ func= RNA_def_function(srna, "add_vertex_group", "rna_Object_add_vertex_group"); RNA_def_function_ui_description(func, "Add vertex group to object."); parm= RNA_def_string(func, "name", "Group", 0, "", "Vertex group name."); /* optional */ @@ -260,6 +268,11 @@ void RNA_api_object(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_enum(func, "type", assign_mode_items, 0, "", "Vertex assign mode."); RNA_def_property_flag(parm, PROP_REQUIRED); + + /* DAG */ + func= RNA_def_function(srna, "dag_update", "rna_Object_dag_update"); + RNA_def_function_ui_description(func, "DAG update."); /* XXX describe better */ + RNA_def_function_flag(func, FUNC_USE_CONTEXT); } #endif diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index b8863540bdf..2561322b9a2 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -181,15 +181,18 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");*/ /* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */ -/* prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX); - RNA_def_property_struct_type(prop, "pose_mat"); + prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, "pose_mat"); + RNA_def_property_array(prop, 16); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Pose Matrix", "Final 4x4 matrix for this channel."); + /* prop= RNA_def_property(srna, "constraint_inverse_matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_struct_type(prop, "constinv"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position."); */ + RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position."); + */ prop= RNA_def_property(srna, "pose_head", PROP_FLOAT, PROP_VECTOR); RNA_def_property_clear_flag(prop, PROP_EDITABLE); -- cgit v1.2.3 From 7afffd2950aba313de3cab1c74657380aaf08067 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 14 Jul 2009 23:08:55 +0000 Subject: Just another experimental stuff to optimize the expected number of BB test on bvh trees *tree pushdowns after the pushsups :P (its still not local optimum) --- source/blender/blenlib/intern/BLI_memarena.c | 1 + .../render/intern/include/rayobject_rtbuild.h | 1 + .../render/intern/raytrace/rayobject_rtbuild.cpp | 12 +++ .../render/intern/raytrace/rayobject_vbvh.cpp | 98 +++++++++++++++++++--- 4 files changed, 100 insertions(+), 12 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index 87d2f0426b2..6312cbb22ca 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -95,3 +95,4 @@ void *BLI_memarena_alloc(MemArena *ma, int size) { return ptr; } + diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h index b80e0868739..ed8560d948a 100644 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ b/source/blender/render/intern/include/rayobject_rtbuild.h @@ -92,6 +92,7 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); float bb_area(float *min, float *max); float bb_volume(float *min, float *max); int bb_largest_axis(float *min, float *max); +int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max); /* only returns 0 if merging inner and outerbox would create a box larger than outer box */ #ifdef __cplusplus } diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index dff0b02c00e..86a92417d03 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -529,3 +529,15 @@ int bb_largest_axis(float *min, float *max) return 2; } } + +int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max) +{ + int i; + for(i=0; i<3; i++) + if(outer_min[i] > inner_min[i]) return 0; + + for(i=0; i<3; i++) + if(outer_max[i] < inner_max[i]) return 0; + + return 1; +} diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 3f8f69a5abe..b4d30b51358 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -128,6 +128,41 @@ void bvh_update_bb(Node *node) } +static int tot_pushup = 0; +static int tot_pushdown = 0; + +template +void pushdown(Node *parent) +{ + Node **s_child = &parent->child; + Node * child = parent->child; + + while(child && RayObject_isAligned(child)) + { + Node *next = child->sibling; + + assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); + + for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) + if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3)) + { +// todo optimize (hsould the one with the smallest area +// float ia = bb_area(i->bb, i->bb+3) +// if(child->i) + *s_child = child->sibling; + child->sibling = i->child; + i->child = child; + + tot_pushdown++; + break; + } + child = next; + } + + for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) + pushdown( i ); +} + template Node *bvh_rearrange(Tree *tree, Builder *builder, float *cost) { @@ -177,6 +212,7 @@ Node *bvh_rearrange(Tree *tree, Builder *builder, float *cost) rtbuild_get_child(&b, i, &tmp); childs.push(tmp); } + tot_pushup++; } else @@ -207,38 +243,76 @@ void bvh_done(BVHTree *obj) obj->root = bvh_rearrange( obj, obj->builder, &obj->cost ); + pushdown(obj->root); obj->cost = 1.0; rtbuild_free( obj->builder ); obj->builder = NULL; } -template<> -int bvh_intersect(BVHTree *obj, Isect* isec) +template +int intersect(BVHTree *obj, Isect* isec) { if(RayObject_isAligned(obj->root)) - return bvh_node_stack_raycast(obj->root, isec); + return bvh_node_stack_raycast(obj->root, isec); else return RE_rayobject_intersect( (RayObject*) obj->root, isec ); } + +void bfree(BVHTree *tree) +{ + if(tot_pushup + tot_pushdown) + { + printf("tot pushups: %d\n", tot_pushup); + printf("tot pushdowns: %d\n", tot_pushdown); + tot_pushup = 0; + tot_pushdown = 0; + } + bvh_free(tree); +} + /* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -static RayObjectAPI bvh_api = +template +static RayObjectAPI make_api() { - (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect), - (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), - (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), - (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), - (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), - (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) -}; + static RayObjectAPI api = + { + (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &intersect), + (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), +// (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), + (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bfree), + (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) + }; + + return api; +} + +static RayObjectAPI* get_api(int maxstacksize) +{ +// static RayObjectAPI bvh_api16 = make_api<16>(); +// static RayObjectAPI bvh_api32 = make_api<32>(); +// static RayObjectAPI bvh_api64 = make_api<64>(); + static RayObjectAPI bvh_api128 = make_api<128>(); + static RayObjectAPI bvh_api256 = make_api<256>(); + +// if(maxstacksize <= 16 ) return &bvh_api16; +// if(maxstacksize <= 32 ) return &bvh_api32; +// if(maxstacksize <= 64 ) return &bvh_api64; + if(maxstacksize <= 128) return &bvh_api128; + if(maxstacksize <= 256) return &bvh_api256; + assert(maxstacksize <= 256); + return 0; +} RayObject *RE_rayobject_vbvh_create(int size) { BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - obj->rayobj.api = &bvh_api; + obj->rayobj.api = get_api(DFS_STACK_SIZE); obj->root = NULL; obj->node_arena = NULL; -- cgit v1.2.3 From e3f7cad32d4c597fec7576fe5530f5adc9a33159 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 14 Jul 2009 23:26:00 +0000 Subject: *fix (was losing childs) --- source/blender/render/intern/raytrace/rayobject_vbvh.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index b4d30b51358..305de145a72 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -140,6 +140,7 @@ void pushdown(Node *parent) while(child && RayObject_isAligned(child)) { Node *next = child->sibling; + Node **next_s_child = &child->sibling; assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); @@ -152,11 +153,13 @@ void pushdown(Node *parent) *s_child = child->sibling; child->sibling = i->child; i->child = child; + next_s_child = s_child; tot_pushdown++; break; } child = next; + s_child = next_s_child; } for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) -- cgit v1.2.3 From ef1fcd8ad1d8fb4feed704286982e8b5be03b149 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 15 Jul 2009 17:38:00 +0000 Subject: *Added support to "BB hints" (which works like a BB version of LCTS - longest common transversing subtree) It creates a tree cut after knowing that a given point will pass on a BB. This tree cut is used to accelarate the rays casted from a given BB, eliminating unnecessary BB tests from root till the tree cut. --- source/blender/render/extern/include/RE_raytrace.h | 26 ++++++- source/blender/render/intern/include/rayobject.h | 2 + source/blender/render/intern/raytrace/bvh.h | 5 +- .../render/intern/raytrace/rayobject_bvh.cpp | 2 +- .../render/intern/raytrace/rayobject_vbvh.cpp | 86 ++++++++++++++++++++-- source/blender/render/intern/source/rayobject.c | 14 ++++ source/blender/render/intern/source/rayshade.c | 61 +++++++++------ 7 files changed, 161 insertions(+), 35 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 4d0c0b1a88c..beae1b84b04 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -36,6 +36,7 @@ extern "C" { #endif +#define RE_RAY_LCTS_MAX_SIZE 256 #define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ //#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */ @@ -76,7 +77,7 @@ extern RayCounter re_rc_counter[]; /* Internals about raycasting structures can be found on intern/raytree.h */ typedef struct RayObject RayObject; typedef struct Isect Isect; - +typedef struct RayHint RayHint; typedef struct RayTraceHint RayTraceHint; struct DerivedMesh; @@ -87,6 +88,12 @@ void RE_rayobject_add (RayObject *r, RayObject *); void RE_rayobject_done(RayObject *r); void RE_rayobject_free(RayObject *r); +/* initializes an hint for optiming raycast where it is know that a ray will pass by the given BB often the origin point */ +void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max); + +/* initializes an hint for optiming raycast where it is know that a ray will be contained inside the given cone*/ +/* void RE_rayobject_hint_cone(RayObject *r, RayHint *hint, float *); */ + /* RayObject constructors */ RayObject* RE_rayobject_octree_create(int ocres, int size); @@ -97,6 +104,21 @@ RayObject* RE_rayobject_bvh_create(int size); /* raytrace/rayobject_bvh.c */ RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ +typedef struct LCTSHint LCTSHint; +struct LCTSHint +{ + int size; + RayObject *stack[RE_RAY_LCTS_MAX_SIZE]; +}; + +struct RayHint +{ + union + { + LCTSHint lcts; + } data; +}; + /* Ray Intersection */ struct Isect @@ -137,6 +159,8 @@ struct Isect void *userdata; + RayHint *hint; + #ifdef RE_RAYCOUNTER RayCounter *raycounter; #endif diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 16ebc537ef9..6f8debead19 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -98,6 +98,7 @@ typedef void (*RE_rayobject_done_callback)(RayObject *); typedef void (*RE_rayobject_free_callback)(RayObject *); typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); typedef float (*RE_rayobject_cost_callback)(RayObject *); +typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *); typedef struct RayObjectAPI { @@ -107,6 +108,7 @@ typedef struct RayObjectAPI RE_rayobject_free_callback free; RE_rayobject_merge_bb_callback bb; RE_rayobject_cost_callback cost; + RE_rayobject_hint_bb_callback hint_bb; } RayObjectAPI; diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index d9277f9a583..8f7e6111684 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -93,14 +93,13 @@ static void bvh_node_merge_bb(Node *node, float *min, float *max) */ template static inline void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos); -template +template static int bvh_node_stack_raycast(Node *root, Isect *isec) { Node *stack[MAX_STACK_SIZE]; int hit = 0, stack_pos = 0; - //Assume the BB of root always succeed - if(1) + if(!TEST_ROOT && RayObject_isAligned(root)) bvh_node_push_childs(root, isec, stack, stack_pos); else stack[stack_pos++] = root; diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp index 2c2a260df98..435c49cdc42 100644 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -199,7 +199,7 @@ template<> int bvh_intersect(BVHTree *obj, Isect* isec) { if(RayObject_isAligned(obj->root)) - return bvh_node_stack_raycast(obj->root, isec); + return bvh_node_stack_raycast(obj->root, isec); else return RE_rayobject_intersect( (RayObject*) obj->root, isec ); } diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 305de145a72..ce3218c25fa 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -130,6 +130,7 @@ void bvh_update_bb(Node *node) static int tot_pushup = 0; static int tot_pushdown = 0; +static int tot_hints = 0; template void pushdown(Node *parent) @@ -142,7 +143,7 @@ void pushdown(Node *parent) Node *next = child->sibling; Node **next_s_child = &child->sibling; - assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); + //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3)) @@ -256,21 +257,93 @@ void bvh_done(BVHTree *obj) template int intersect(BVHTree *obj, Isect* isec) { - if(RayObject_isAligned(obj->root)) - return bvh_node_stack_raycast(obj->root, isec); + if(isec->hint) + { + LCTSHint *lcts = (LCTSHint*)isec->hint; + isec->hint = 0; + + int hit = 0; + for(int i=0; isize; i++) + { + BVHNode *node = (BVHNode*)lcts->stack[i]; + if(RayObject_isAligned(node)) + hit |= bvh_node_stack_raycast(node, isec); + else + hit |= RE_rayobject_intersect( (RayObject*)node, isec ); + + if(hit && isec->mode == RE_RAY_SHADOW) + break; + } + isec->hint = (RayHint*)lcts; + return hit; + } else - return RE_rayobject_intersect( (RayObject*) obj->root, isec ); + { + if(RayObject_isAligned(obj->root)) + return bvh_node_stack_raycast(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); + } } +template +void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max); + +template +void bvh_dfs_make_hint_push_siblings(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max) +{ + if(!RayObject_isAligned(node)) + hint->stack[hint->size++] = (RayObject*)node; + else + { + if(node->sibling) + bvh_dfs_make_hint_push_siblings(node->sibling, hint, reserve_space+1, min, max); + + bvh_dfs_make_hint(node, hint, reserve_space, min, max); + } + + +} + +template +void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max) +{ + assert( hint->size - reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); + + if(hint->size - reserve_space + 1 == RE_RAY_LCTS_MAX_SIZE || !RayObject_isAligned(node)) + hint->stack[hint->size++] = (RayObject*)node; + else + { + /* We are 100% sure the ray will be pass inside this node */ + if(bb_fits_inside(node->bb, node->bb+3, min, max) ) + { + bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, min, max); + } + else + { + hint->stack[hint->size++] = (RayObject*)node; + } + } +} + +template +void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) +{ + hint->size = 0; + bvh_dfs_make_hint( tree->root, hint, 0, min, max ); + tot_hints++; +} void bfree(BVHTree *tree) { - if(tot_pushup + tot_pushdown) + if(tot_pushup + tot_pushdown + tot_hints) { printf("tot pushups: %d\n", tot_pushup); printf("tot pushdowns: %d\n", tot_pushdown); + printf("tot hints created: %d\n", tot_hints); tot_pushup = 0; tot_pushdown = 0; + tot_hints = 0; } bvh_free(tree); } @@ -287,7 +360,8 @@ static RayObjectAPI make_api() // (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bfree), (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), - (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) + (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost), + (RE_rayobject_hint_bb_callback) ((void(*)(BVHTree*,LCTSHint*,float*,float*)) &bvh_hint_bb) }; return api; diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 949b7afb5a0..2e63dc78c0e 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -414,6 +414,20 @@ float RE_rayobject_cost(RayObject *r) else assert(0); } +void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max) +{ + if(RayObject_isRayFace(r)) + { + return; + } + else if(RayObject_isRayAPI(r)) + { + r = RayObject_align( r ); + return r->api->hint_bb( r, hint, min, max ); + } + else assert(0); +} + #ifdef RE_RAYCOUNTER void RE_RC_INFO(RayCounter *info) { diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 52edd7a7e27..66f564d4364 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -624,9 +624,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; isec.mode= RE_RAY_MIRROR; isec.skip = RE_SKIP_VLR_NEIGHBOUR; -#ifdef RT_USE_HINT isec.hint = 0; -#endif isec.orig.ob = obi; isec.orig.face = vlr; @@ -1532,9 +1530,10 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) isec.mode= RE_RAY_MIRROR; isec.orig.ob = ship->obi; isec.orig.face = ship->vlr; -#ifdef RT_USE_HINT isec.hint = 0; -#endif + + VECCOPY(isec.start, ship->co); + RE_RC_INIT(isec, shi); for(a=0; a<8*8; a++) { @@ -1548,7 +1547,6 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) vec[2]-= vec[2]; } - VECCOPY(isec.start, ship->co); VECCOPY(isec.vec, vec ); isec.labda = RE_RAYTRACE_MAXDIST; @@ -1725,6 +1723,7 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys) static void ray_ao_qmc(ShadeInput *shi, float *shadfac) { Isect isec; + RayHint point_hint; QMCSampler *qsa=NULL; float samp3d[3]; float up[3], side[3], dir[3], nrm[3]; @@ -1744,9 +1743,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; -#ifdef RT_USE_HINT isec.hint = 0; -#endif isec.hit.ob = 0; isec.hit.face = 0; @@ -1756,6 +1753,11 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW; isec.lay= -1; + VECCOPY(isec.start, shi->co); + RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start ); + isec.hint = &point_hint; + + shadfac[0]= shadfac[1]= shadfac[2]= 0.0f; /* prevent sky colors to be added for only shadow (shadow becomes alpha) */ @@ -1793,6 +1795,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) QMC_initPixel(qsa, shi->thread); + while (samples < max_samples) { /* sampling, returns quasi-random vector in unit hemisphere */ @@ -1804,7 +1807,6 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) Normalize(dir); - VECCOPY(isec.start, shi->co); isec.vec[0] = -dir[0]; isec.vec[1] = -dir[1]; isec.vec[2] = -dir[2]; @@ -1872,6 +1874,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) { Isect isec; + RayHint point_hint; float *vec, *nrm, div, bias, sh=0.0f; float maxdist = R.wrld.aodist; float dxyview[3]; @@ -1881,9 +1884,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; isec.skip = RE_SKIP_VLR_NEIGHBOUR; -#ifdef RT_USE_HINT isec.hint = 0; -#endif isec.hit.ob = 0; isec.hit.face = 0; @@ -1893,6 +1894,9 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW; isec.lay= -1; + VECCOPY(isec.start, shi->co); + RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start ); + isec.hint = &point_hint; shadfac[0]= shadfac[1]= shadfac[2]= 0.0f; @@ -1940,7 +1944,6 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) actual++; /* always set start/vec/labda */ - VECCOPY(isec.start, shi->co); isec.vec[0] = -vec[0]; isec.vec[1] = -vec[1]; isec.vec[2] = -vec[2]; @@ -2058,7 +2061,10 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * float adapt_thresh = lar->adapt_thresh; int min_adapt_samples=4, max_samples = lar->ray_totsamp; float *co; - int do_soft=1, full_osa=0; + int do_soft=1, full_osa=0, i; + + float min[3], max[3]; + RayHint bb_hint; float jitco[RE_MAX_OSA][3]; int totjitco; @@ -2089,10 +2095,18 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples); QMC_initPixel(qsa, shi->thread); + + INIT_MINMAX(min, max); + for(i=0; ihint = &bb_hint; + isec->skip = RE_SKIP_VLR_NEIGHBOUR; VECCOPY(vec, lampco); - isec->skip = RE_SKIP_VLR_NEIGHBOUR; while (samples < max_samples) { isec->orig.ob = shi->obi; @@ -2215,6 +2229,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa float *jitlamp; float fac=0.0f, div=0.0f, vec[3]; int a, j= -1, mask; + RayHint point_hint; if(isec->mode==RE_RAY_SHADOW_TRA) { shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f; @@ -2231,6 +2246,12 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa if(a==4) mask |= (mask>>4)|(mask>>8); else if(a==9) mask |= (mask>>9); + VECCOPY(isec->start, shi->co); + isec->orig.ob = shi->obi; + isec->orig.face = shi->vlr; + RE_rayobject_hint_bb( R.raytree, &point_hint, isec->start, isec->start ); + isec->hint = &point_hint; + while(a--) { if(R.r.mode & R_OSA) { @@ -2242,19 +2263,15 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa } } - isec->orig.ob = shi->obi; - isec->orig.face = shi->vlr; - vec[0]= jitlamp[0]; vec[1]= jitlamp[1]; vec[2]= 0.0f; Mat3MulVecfl(lar->mat, vec); /* set start and vec */ - VECCOPY(isec->start, shi->co); - isec->vec[0] = vec[0]+lampco[0]-shi->co[0]; - isec->vec[1] = vec[1]+lampco[1]-shi->co[1]; - isec->vec[2] = vec[2]+lampco[2]-shi->co[2]; + isec->vec[0] = vec[0]+lampco[0]-isec->start[0]; + isec->vec[1] = vec[1]+lampco[1]-isec->start[1]; + isec->vec[2] = vec[2]+lampco[2]-isec->start[2]; isec->labda = 1.0f; isec->skip = RE_SKIP_VLR_NEIGHBOUR; @@ -2299,9 +2316,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) RE_RC_INIT(isec, *shi); if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA; else isec.mode= RE_RAY_SHADOW; -#ifdef RT_USE_HINT isec.hint = 0; -#endif if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) isec.lay= lar->lay; @@ -2390,9 +2405,7 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float /* setup isec */ RE_RC_INIT(isec, *shi); isec.mode= RE_RAY_SHADOW_TRA; -#ifdef RT_USE_HINT isec.hint = 0; -#endif if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; -- cgit v1.2.3 From 146b54d5e85c809858520674b2222f46e8ef1601 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 15 Jul 2009 17:44:25 +0000 Subject: *increased stack size (later this should be prepared for dealing with stack size in runtime) *put cost model back to normal --- source/blender/render/intern/raytrace/rayobject_vbvh.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index ce3218c25fa..8c2139fe6ca 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -45,7 +45,7 @@ extern "C" #define BVHTree VBVHTree #define RAY_BB_TEST_COST (0.2f) -#define DFS_STACK_SIZE 128 +#define DFS_STACK_SIZE 256 #define DYNAMIC_ALLOC //#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ @@ -248,7 +248,7 @@ void bvh_done(BVHTree *obj) obj->root = bvh_rearrange( obj, obj->builder, &obj->cost ); pushdown(obj->root); - obj->cost = 1.0; +// obj->cost = 1.0; rtbuild_free( obj->builder ); obj->builder = NULL; -- cgit v1.2.3 From 73ad2d320cca8c34d7901630dd8c6223ba4cd4a3 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 16 Jul 2009 08:20:15 +0000 Subject: More FBX exporter conversion. Experimenting with cross-compiling my branch with MinGW on Linux: - tweaked config/linuxcross.py, source/blender/makesdna/intern/SConscript and tools/Blender.py So far linking fails. --- config/linuxcross-config.py | 47 +++++-- release/io/export_fbx.py | 196 +++++++++++++++++++++++------- release/io/export_obj.py | 8 +- source/blender/makesdna/intern/SConscript | 2 +- source/blender/makesrna/intern/rna_pose.c | 2 +- tools/Blender.py | 6 +- 6 files changed, 198 insertions(+), 63 deletions(-) diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index 5e5c44ecd69..5253110be66 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -2,13 +2,13 @@ LCGDIR = '#../lib/windows' LIBDIR = '${LCGDIR}' BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '2.5' +BF_PYTHON_VERSION = '2.6' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' -BF_PYTHON_LIB = 'python25' +BF_PYTHON_LIB = 'python26' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' -WITH_BF_OPENAL = True +WITH_BF_OPENAL = False # XXX (Arystan) WITH_BF_STATICOPENAL = False BF_OPENAL = LIBDIR + '/openal' BF_OPENAL_INC = '${BF_OPENAL}/include' @@ -17,6 +17,12 @@ BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib' # Warning, this static lib configuration is untested! users of this OS please confirm. BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' +# copied from win32-mingw-config.py (Arystan) +WITH_BF_FFMPEG = False +BF_FFMPEG_LIB = 'avformat swscale avcodec avutil avdevice xvidcore x264' +BF_FFMPEG_LIBPATH = LIBDIR + '/gcc/ffmpeg/lib' +BF_FFMPEG_INC = LIBDIR + '/gcc/ffmpeg/include' + # Warning, this static lib configuration is untested! users of this OS please confirm. BF_CXX = '/usr' WITH_BF_STATICCXX = False @@ -33,7 +39,7 @@ BF_PTHREADS_INC = '${BF_PTHREADS}/include' BF_PTHREADS_LIB = 'pthreadGC2' BF_PTHREADS_LIBPATH = '${BF_PTHREADS}/lib' -WITH_BF_OPENEXR = True +WITH_BF_OPENEXR = False WITH_BF_STATICOPENEXR = False BF_OPENEXR = LIBDIR + '/gcc/openexr' BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR' @@ -58,6 +64,8 @@ BF_PNG_LIBPATH = '${BF_PNG}/lib' BF_TIFF = LIBDIR + '/tiff' BF_TIFF_INC = '${BF_TIFF}/include' +BF_TIFF_LIB = 'libtiff' +BF_TIFF_LIBPATH = '${BF_TIFF}/lib' WITH_BF_ZLIB = True BF_ZLIB = LIBDIR + '/zlib' @@ -69,16 +77,26 @@ WITH_BF_INTERNATIONAL = True BF_GETTEXT = LIBDIR + '/gettext' BF_GETTEXT_INC = '${BF_GETTEXT}/include' -BF_GETTEXT_LIB = 'gnu_gettext' +BF_GETTEXT_LIB = 'gettextlib' +# BF_GETTEXT_LIB = 'gnu_gettext' BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = False +WITH_BF_ODE = True +BF_ODE = LIBDIR + '/ode' +BF_ODE_INC = BF_ODE + '/include' +BF_ODE_LIB = BF_ODE + '/lib/libode.a' + WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' +BF_SOLID = '#extern/solid' +BF_SOLID_INC = '${BF_SOLID}' +BF_SOLID_LIB = 'extern_solid' + BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' @@ -100,9 +118,12 @@ BF_ICONV_LIBPATH = '${BF_ICONV}/lib' # Mesa Libs should go here if your using them as well.... WITH_BF_STATICOPENGL = False -BF_OPENGL = 'C:\\MingW' -BF_OPENGL_INC = '${BF_OPENGL}/include' -BF_OPENGL_LIBINC = '${BF_OPENGL}/lib' +BF_OPENGL = '' +# BF_OPENGL = 'C:\\MingW' +BF_OPENGL_INC = '' +# BF_OPENGL_INC = '${BF_OPENGL}/include' +BF_OPENGL_LIBINC = '' +# BF_OPENGL_LIBINC = '${BF_OPENGL}/lib' BF_OPENGL_LIB = 'opengl32 glu32' BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a', '${BF_OPENGL}/lib/libXmu.a', '${BF_OPENGL}/lib/libXext.a', @@ -111,9 +132,13 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a' CC = 'i586-mingw32msvc-gcc' CXX = 'i586-mingw32msvc-g++' +# Custom built MinGW (Arystan) +# CC = 'i586-pc-mingw32-gcc' +# CXX = 'i586-pc-mingw32-g++' + CCFLAGS = [ '-pipe', '-funsigned-char', '-fno-strict-aliasing' ] -CPPFLAGS = [ '-DXP_UNIX', '-DWIN32', '-DFREE_WINDOWS' ] +CPPFLAGS = [ '-DXP_UNIX', '-DWIN32', '-DFREE_WINDOWS', '-DLINUX_CROSS' ] CXXFLAGS = ['-pipe', '-mwindows', '-funsigned-char', '-fno-strict-aliasing' ] REL_CFLAGS = [ '-O2' ] REL_CCFLAGS = [ '-O2' ] @@ -122,7 +147,7 @@ C_WARN = [ '-Wall' , '-Wno-char-subscripts', '-Wdeclaration-after-statement' ] CC_WARN = [ '-Wall' ] -LLIBS = [ '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz'] #'-lutil', '-lc', '-lm', '-ldl', '-lpthread' ] +LLIBS = [ '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++'] #'-lutil', '-lc', '-lm', '-ldl', '-lpthread' ] BF_DEBUG = False BF_DEBUG_CCFLAGS= [] @@ -134,3 +159,5 @@ BF_PROFILE_LINKFLAGS = ['-pg'] BF_BUILDDIR = '../build/linuxcross' BF_INSTALLDIR='../install/linuxcross' BF_DOCDIR='../install/doc' + +# LINKFLAGS = ['-Wl,--start-group'] diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 0a6588c380b..c4f56b472dc 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -60,9 +60,10 @@ except: # except: # os = None -import Blender +# import Blender import bpy -from Blender.Mathutils import Matrix, Vector, RotationMatrix +import Mathutils +# from Blender.Mathutils import Matrix, Vector, RotationMatrix import BPyObject import BPyMesh @@ -258,9 +259,48 @@ def derived_paths(fname_orig, basepath, FORCE_CWD=False): def mat4x4str(mat): return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ]) +# XXX not used +# duplicated in OBJ exporter +def getVertsFromGroup(me, group_index): + ret = [] + + for i, v in enumerate(me.verts): + for g in v.groups: + if g.group == group_index: + ret.append((i, g.weight)) + + return ret + +# ob must be OB_MESH +def BPyMesh_meshWeight2List(ob): + ''' Takes a mesh and return its group names and a list of lists, one list per vertex. + aligning the each vert list with the group names, each list contains float value for the weight. + These 2 lists can be modified and then used with list2MeshWeight to apply the changes. + ''' + + me = ob.data + + # Clear the vert group. + groupNames= [g.name for g in ob.vertex_groups] + len_groupNames= len(groupNames) + + if not len_groupNames: + # no verts? return a vert aligned empty list + return [[] for i in xrange(len(me.verts))], [] + else: + vWeightList= [[0.0]*len_groupNames for i in xrange(len(me.verts))] + + for i, v in enumerate(me.verts): + for g in v.groups: + vWeightList[i][g.group] = g.weight + + return groupNames, vWeightList + + def meshNormalizedWeights(me): try: # account for old bad BPyMesh - groupNames, vWeightList = BPyMesh.meshWeight2List(me) + groupNames, vWeightList = BPyMesh_meshWeight2List(me) +# groupNames, vWeightList = BPyMesh.meshWeight2List(me) except: return [],[] @@ -564,7 +604,7 @@ def write(filename, batch_objects = None, \ matrix_rot = mtx_x90 * matrix_rot elif type =='CAMERA': # elif ob and type =='Camera': - y = Vector(0,1,0) * matrix_rot + y = Mathutils.Vector(0,1,0) * matrix_rot matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) return matrix_rot @@ -666,7 +706,7 @@ def write(filename, batch_objects = None, \ matrix_rot = mtx_x90 * matrix_rot rot = tuple(matrix_rot.toEuler()) elif ob and ob.type =='Camera': - y = Vector(0,1,0) * matrix_rot + y = Mathutils.Vector(0,1,0) * matrix_rot matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) rot = tuple(matrix_rot.toEuler()) else: @@ -1052,8 +1092,8 @@ def write(filename, batch_objects = None, \ file.write('\n\t\tTypeFlags: "Camera"') file.write('\n\t\tGeometryVersion: 124') file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) - file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Vector(0,1,0) * matrix_rot) ) - file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Vector(0,0,-1)*matrix_rot) ) + file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,1,0) * matrix_rot) ) + file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,0,-1)*matrix_rot) ) #file.write('\n\t\tUp: 0,0,0' ) #file.write('\n\t\tLookAt: 0,0,0' ) @@ -1458,7 +1498,8 @@ def write(filename, batch_objects = None, \ if my_mesh.blenTextures: do_textures = True else: do_textures = False - do_uvs = me.faceUV + do_uvs = len(me.uv_layers) > 0 +# do_uvs = me.faceUV file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) @@ -1490,20 +1531,24 @@ def write(filename, batch_objects = None, \ file.write('\n\t\tPolygonVertexIndex: ') i=-1 for f in me.faces: - fi = [v.index for v in f] + fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3] +# fi = [v.index for v in f] + # flip the last index, odd but it looks like # this is how fbx tells one face from another fi[-1] = -(fi[-1]+1) fi = tuple(fi) if i==-1: - if len(f) == 3: file.write('%i,%i,%i' % fi ) + if len(fi) == 3: file.write('%i,%i,%i' % fi ) +# if len(f) == 3: file.write('%i,%i,%i' % fi ) else: file.write('%i,%i,%i,%i' % fi ) i=0 else: if i==13: file.write('\n\t\t') i=0 - if len(f) == 3: file.write(',%i,%i,%i' % fi ) + if len(fi) == 3: file.write(',%i,%i,%i' % fi ) +# if len(f) == 3: file.write(',%i,%i,%i' % fi ) else: file.write(',%i,%i,%i,%i' % fi ) i+=1 @@ -1511,13 +1556,15 @@ def write(filename, batch_objects = None, \ i=-1 for ed in me.edges: if i==-1: - file.write('%i,%i' % (ed.v1.index, ed.v2.index)) + file.write('%i,%i' % (ed.verts[0], ed.verts[1])) +# file.write('%i,%i' % (ed.v1.index, ed.v2.index)) i=0 else: if i==13: file.write('\n\t\t') i=0 - file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) + file.write(',%i,%i' % (ed.verts[0], ed.verts[1])) +# file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) i+=1 file.write('\n\t\tGeometryVersion: 124') @@ -1533,11 +1580,13 @@ def write(filename, batch_objects = None, \ i=-1 for v in me.verts: if i==-1: - file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0 + file.write('%.15f,%.15f,%.15f' % tuple(v.normal)); i=0 +# file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0 else: if i==2: file.write('\n '); i=0 - file.write(',%.15f,%.15f,%.15f' % tuple(v.no)) + file.write(',%.15f,%.15f,%.15f' % tuple(v.normal)) +# file.write(',%.15f,%.15f,%.15f' % tuple(v.no)) i+=1 file.write('\n\t\t}') @@ -1571,32 +1620,49 @@ def write(filename, batch_objects = None, \ ReferenceInformationType: "Direct" Smoothing: ''') - SHARP = Blender.Mesh.EdgeFlags.SHARP +# SHARP = Blender.Mesh.EdgeFlags.SHARP i=-1 for ed in me.edges: if i==-1: - file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 + file.write('%i' % (ed.sharp)); i=0 +# file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 else: if i==54: file.write('\n '); i=0 - file.write(',%i' % ((ed.flag&SHARP)!=0)) + file.write(',%i' % (ed.sharp)) +# file.write(',%i' % ((ed.flag&SHARP)!=0)) i+=1 file.write('\n\t\t}') - del SHARP - +# del SHARP + + # small utility function + # returns a slice of data depending on number of face verts + # data is either a MeshTextureFace or MeshColor + def face_data(data, face): + if f.verts[3] == 0: + totvert = 3 + else: + totvert = 4 + + return data[:totvert] + # Write VertexColor Layers # note, no programs seem to use this info :/ collayers = [] - if me.vertexColors: - collayers = me.getColorLayerNames() - collayer_orig = me.activeColorLayer + if len(me.vertex_colors): +# if me.vertexColors: + collayers = me.vertex_colors +# collayers = me.getColorLayerNames() + collayer_orig = me.active_vertex_color +# collayer_orig = me.activeColorLayer for colindex, collayer in enumerate(collayers): - me.activeColorLayer = collayer +# me.activeColorLayer = collayer file.write('\n\t\tLayerElementColor: %i {' % colindex) file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % collayer) + file.write('\n\t\t\tName: "%s"' % collayer.name) +# file.write('\n\t\t\tName: "%s"' % collayer) file.write(''' MappingInformationType: "ByPolygonVertex" @@ -1605,19 +1671,37 @@ def write(filename, batch_objects = None, \ i = -1 ii = 0 # Count how many Colors we write - - for f in me.faces: - for col in f.col: + + for f, cf in zip(me.faces, collayer.data): + colors = [cf.color1, cf.color2, cf.color3, cf.color4] + + # determine number of verts + colors = face_data(colors, f) + + for col in colors: if i==-1: - file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) + file.write('%.4f,%.4f,%.4f,1' % tuple(col)) i=0 else: if i==7: file.write('\n\t\t\t\t') i=0 - file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) + file.write(',%.4f,%.4f,%.4f,1' % tuple(col)) i+=1 ii+=1 # One more Color + +# for f in me.faces: +# for col in f.col: +# if i==-1: +# file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) +# i=0 +# else: +# if i==7: +# file.write('\n\t\t\t\t') +# i=0 +# file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) +# i+=1 +# ii+=1 # One more Color file.write('\n\t\t\tColorIndex: ') i = -1 @@ -1639,13 +1723,17 @@ def write(filename, batch_objects = None, \ # Write UV and texture layers. uvlayers = [] if do_uvs: - uvlayers = me.getUVLayerNames() - uvlayer_orig = me.activeUVLayer - for uvindex, uvlayer in enumerate(uvlayers): - me.activeUVLayer = uvlayer + uvlayers = me.uv_textures +# uvlayers = me.getUVLayerNames() + uvlayer_orig = me.active_uv_texture +# uvlayer_orig = me.activeUVLayer + for uvindex, uvlayer in enumerate(me.uv_textures): +# for uvindex, uvlayer in enumerate(uvlayers): +# me.activeUVLayer = uvlayer file.write('\n\t\tLayerElementUV: %i {' % uvindex) file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % uvlayer) + file.write('\n\t\t\tName: "%s"' % uvlayer.name) +# file.write('\n\t\t\tName: "%s"' % uvlayer) file.write(''' MappingInformationType: "ByPolygonVertex" @@ -1655,8 +1743,13 @@ def write(filename, batch_objects = None, \ i = -1 ii = 0 # Count how many UVs we write - for f in me.faces: - for uv in f.uv: + for f, uf in zip(me.faces, uvlayer.data): +# for f in me.faces: + uvs = [uf.uv1, uf.uv2, uf.uv3, uf.uv4] + uvs = face_data(uvs, f) + + for uv in uvs: +# for uv in f.uv: if i==-1: file.write('%.6f,%.6f' % tuple(uv)) i=0 @@ -1686,7 +1779,8 @@ def write(filename, batch_objects = None, \ if do_textures: file.write('\n\t\tLayerElementTexture: %i {' % uvindex) file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % uvlayer) + file.write('\n\t\t\tName: "%s"' % uvlayer.name) +# file.write('\n\t\t\tName: "%s"' % uvlayer) if len(my_mesh.blenTextures) == 1: file.write('\n\t\t\tMappingInformationType: "AllSame"') @@ -1710,7 +1804,8 @@ def write(filename, batch_objects = None, \ i+=1 i=-1 - for f in me.faces: + for f in uvlayer.data: +# for f in me.faces: img_key = f.image if i==-1: @@ -1736,7 +1831,7 @@ def write(filename, batch_objects = None, \ TextureId: ''') file.write('\n\t\t}') - me.activeUVLayer = uvlayer_orig +# me.activeUVLayer = uvlayer_orig # Done with UV/textures. @@ -1765,13 +1860,21 @@ def write(filename, batch_objects = None, \ len_material_mapping_local = len(material_mapping_local) mats = my_mesh.blenMaterialList + + if me.active_uv_texture: + uv_faces = me.active_uv_texture.data + else: + uv_faces = [None] * len(me.faces) i=-1 - for f in me.faces: - try: mat = mats[f.mat] + for f, uf in zip(me.faces, uv_faces) +# for f in me.faces: + try: mat = mats[f.material_index] +# try: mat = mats[f.mat] except:mat = None - if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ + if do_uvs: tex = uf.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ +# if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ else: tex = None if i==-1: @@ -1810,7 +1913,8 @@ def write(filename, batch_objects = None, \ TypedIndex: 0 }''') - if me.vertexColors: + if me.vertex_colors: +# if me.vertexColors: file.write(''' LayerElement: { Type: "LayerElementColor" @@ -2331,7 +2435,8 @@ Objects: {''') if my_mesh.fbxBoneParent: weights = None else: - weights = meshNormalizedWeights(my_mesh.blenData) + weights = meshNormalizedWeights(my_mesh.blenObject) +# weights = meshNormalizedWeights(my_mesh.blenData) #for bonename, bone, obname, bone_mesh, armob in ob_bones: for my_bone in ob_bones: @@ -3216,6 +3321,7 @@ if __name__ == '__main__': # - isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 # - get rid of BPyObject_getObjectArmature, move it in RNA? # - BATCH_ENABLE and BATCH_GROUP options: line 327 +# - implement all BPyMesh_* used here with RNA # TODO diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 466fb2f2362..70be6bb541b 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -434,7 +434,7 @@ def write(filename, objects, scene, # continue if EXPORT_UV: - faceuv = len(me.uv_layers) > 0 + faceuv = len(me.uv_textures) > 0 else: faceuv = False @@ -508,7 +508,7 @@ def write(filename, objects, scene, pass elif faceuv: # XXX update - tface = me.active_uv_layer.data + tface = me.active_uv_texture.data # exception only raised if Python 2.3 or lower... try: @@ -570,7 +570,7 @@ def write(filename, objects, scene, uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ uv_dict = {} # could use a set() here - uv_layer = me.active_uv_layer + uv_layer = me.active_uv_texture for f, f_index in face_index_pairs: tface = uv_layer.data[f_index] @@ -652,7 +652,7 @@ def write(filename, objects, scene, # f_mat = min(f.mat, len(materialNames)-1) if faceuv: - tface = me.active_uv_layer.data[face_index_pairs[f_index][1]] + tface = me.active_uv_texture.data[face_index_pairs[f_index][1]] f_image = tface.image f_uv= [tface.uv1, tface.uv2, tface.uv3] diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript index 1c716019e80..9089718da83 100644 --- a/source/blender/makesdna/intern/SConscript +++ b/source/blender/makesdna/intern/SConscript @@ -61,6 +61,6 @@ if env['OURPLATFORM'] != 'linuxcross': else: dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna $TARGET") else: - dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna.exe $TARGET") + dna.Command ('dna.c', '', 'wine ' + root_build_dir+os.sep+"makesdna.exe $TARGET") obj = ['intern/dna.c', 'intern/dna_genfile.c'] Return ('obj') diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 2561322b9a2..12822024654 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -182,7 +182,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) /* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */ prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX); - RNA_def_property_float_sdna(prop, "pose_mat"); + RNA_def_property_float_sdna(prop, NULL, "pose_mat"); RNA_def_property_array(prop, 16); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Pose Matrix", "Final 4x4 matrix for this channel."); diff --git a/tools/Blender.py b/tools/Blender.py index 164a9d097e6..8866df2c0ae 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -112,7 +112,6 @@ def setup_staticlibs(lenv): #here libs for static linking ] libincs = [ - '/usr/lib', lenv['BF_OPENGL_LIBPATH'], lenv['BF_JPEG_LIBPATH'], lenv['BF_PNG_LIBPATH'], @@ -120,6 +119,9 @@ def setup_staticlibs(lenv): lenv['BF_ICONV_LIBPATH'] ] + if lenv['OURPLATFORM'] != 'linuxcross': + libincs = ['/usr/lib'] + libincs + libincs += Split(lenv['BF_FREETYPE_LIBPATH']) if lenv['WITH_BF_PYTHON']: libincs += Split(lenv['BF_PYTHON_LIBPATH']) @@ -223,7 +225,7 @@ def buildinfo(lenv, build_type): obj = [] if lenv['BF_BUILDINFO']: - if sys.platform=='win32': + if sys.platform=='win32' or lenv['OURPLATFORM']=='linuxcross': build_info_file = open("source/creator/winbuildinfo.h", 'w') build_info_file.write("char *build_date=\"%s\";\n"%build_date) build_info_file.write("char *build_time=\"%s\";\n"%build_time) -- cgit v1.2.3 From aede14d4e08b953e0e300c9992776f191e9fd94d Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 16 Jul 2009 13:19:43 +0000 Subject: - replaced Object.create_mesh body with 2.4x API's Mesh.createFromObject code to also support curves, surfaces and metaballs. - replaced Object.dag_update with Object.make_display_list, which copies old API's Object.makeDisplayList --- release/io/export_fbx.py | 47 +++-- release/io/export_obj.py | 9 +- source/blender/makesrna/intern/rna_object_api.c | 233 +++++++++++++++++++----- 3 files changed, 224 insertions(+), 65 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index c4f56b472dc..d74e6246104 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -2019,41 +2019,60 @@ def write(filename, batch_objects = None, \ # This is needed so applying modifiers dosnt apply the armature deformation, its also needed # ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes. # set every armature to its rest, backup the original values so we done mess up the scene - ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures] + ob_arms_orig_rest = [arm.rest_position for arm in bpy.data.armatures] +# ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures] for arm in bpy.data.armatures: - arm.restPosition = True + arm.rest_position = True +# arm.restPosition = True if ob_arms_orig_rest: for ob_base in bpy.data.objects: #if ob_base.type == 'Armature': - ob_base.makeDisplayList() + ob_base.make_display_list() +# ob_base.makeDisplayList() # This causes the makeDisplayList command to effect the mesh - Blender.Set('curframe', Blender.Get('curframe')) + sce.set_frame(sce.current_frame) +# Blender.Set('curframe', Blender.Get('curframe')) for ob_base in tmp_objects: - for ob, mtx in BPyObject.getDerivedObjects(ob_base): - #for ob in [ob_base,]: + + # ignore dupli children + if ob_base.parent and ob_base.parent.dupli_type != 'NONE': + continue + + obs = [(ob_base, ob_base.matrix)] + if ob_base.dupli_type != 'NONE': + ob_base.create_dupli_list() + obs = [(dob.object, dob.matrix) for dob in ob_base.dupli_list] + + for ob, mtx in obs: +# for ob, mtx in BPyObject.getDerivedObjects(ob_base): tmp_ob_type = ob.type - if tmp_ob_type == 'Camera': + if tmp_ob_type == 'CAMERA': +# if tmp_ob_type == 'Camera': if EXP_CAMERA: ob_cameras.append(my_object_generic(ob, mtx)) - elif tmp_ob_type == 'Lamp': + elif tmp_ob_type == 'LAMP': +# elif tmp_ob_type == 'Lamp': if EXP_LAMP: ob_lights.append(my_object_generic(ob, mtx)) - elif tmp_ob_type == 'Armature': + elif tmp_ob_type == 'ARMATURE': +# elif tmp_ob_type == 'Armature': if EXP_ARMATURE: # TODO - armatures dont work in dupligroups! if ob not in ob_arms: ob_arms.append(ob) # ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)" - elif tmp_ob_type == 'Empty': + elif tmp_ob_type == 'EMPTY': +# elif tmp_ob_type == 'Empty': if EXP_EMPTY: ob_null.append(my_object_generic(ob, mtx)) elif EXP_MESH: origData = True - if tmp_ob_type != 'Mesh': + if tmp_ob_type != 'MESH': +# if tmp_ob_type != 'Mesh': me = bpy.data.meshes.new() try: me.getFromObject(ob) except: me = None @@ -2171,8 +2190,9 @@ def write(filename, batch_objects = None, \ if ob_arms_orig_rest: for ob_base in bpy.data.objects: - if ob_base.type == 'Armature': - ob_base.dag_update() + if ob_base.type == 'ARMATURE': +# if ob_base.type == 'Armature': + ob_base.make_display_list() # ob_base.makeDisplayList() # This causes the makeDisplayList command to effect the mesh sce.set_frame(sce.current_frame) @@ -3322,6 +3342,7 @@ if __name__ == '__main__': # - get rid of BPyObject_getObjectArmature, move it in RNA? # - BATCH_ENABLE and BATCH_GROUP options: line 327 # - implement all BPyMesh_* used here with RNA +# - getDerivedObjects is not fully replicated with .dupli* funcs # TODO diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 70be6bb541b..251fdfcf113 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -380,11 +380,6 @@ def write(filename, objects, scene, # Get all meshes for ob_main in objects: - if ob_main.dupli_type != 'NONE': - # XXX - print('creating dupli_list on', ob_main.name) - ob_main.create_dupli_list() - # ignore dupli children if ob_main.parent and ob_main.parent.dupli_type != 'NONE': # XXX @@ -393,6 +388,10 @@ def write(filename, objects, scene, obs = [] if ob_main.dupli_type != 'NONE': + # XXX + print('creating dupli_list on', ob_main.name) + ob_main.create_dupli_list() + obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list] # XXX debug print diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index bf1fb6d2b6a..bae651bf806 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -40,62 +40,190 @@ #include "ED_mesh.h" -/* parameter to rna_Object_create_mesh */ -typedef enum CreateMeshType { - CREATE_MESH_PREVIEW = 0, - CREATE_MESH_RENDER = 1 -} CreateMeshType; - #ifdef RNA_RUNTIME -#include "BKE_customdata.h" +#include "BKE_main.h" +#include "BKE_global.h" +#include "BKE_context.h" +#include "BKE_report.h" +#include "BKE_object.h" +#include "BKE_mesh.h" #include "BKE_DerivedMesh.h" +#include "BKE_customdata.h" #include "BKE_anim.h" -#include "BKE_report.h" #include "BKE_depsgraph.h" +#include "BKE_displist.h" +#include "BKE_font.h" +#include "BKE_mball.h" + +#include "BLI_arithb.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" +#include "DNA_curve_types.h" -#include "BLI_arithb.h" +#include "MEM_guardedalloc.h" -/* copied from init_render_mesh (render code) */ -static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports, int type) +/* copied from Mesh_getFromObject and adapted to RNA interface */ +/* settings: 0 - preview, 1 - render */ +static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports, int apply_modifiers, int settings) { - /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */ - CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter, - for example, needs CD_MASK_MDEFORMVERT */ - DerivedMesh *dm; - Mesh *me; - Scene *sce; - - sce= CTX_data_scene(C); + Mesh *tmpmesh; + Curve *tmpcu = NULL; + Object *tmpobj = NULL; + int render = settings, i; + int cage = !apply_modifiers; + Scene *sce = CTX_data_scene(C); + + /* perform the mesh extraction based on type */ + switch (ob->type) { + case OB_FONT: + case OB_CURVE: + case OB_SURF: + + /* copies object and modifiers (but not the data) */ + tmpobj= copy_object(ob); + tmpcu = (Curve *)tmpobj->data; + tmpcu->id.us--; + + /* if getting the original caged mesh, delete object modifiers */ + if( cage ) + object_free_modifiers(tmpobj); + + /* copies the data */ + tmpobj->data = copy_curve( (Curve *) ob->data ); + +#if 0 + /* copy_curve() sets disp.first null, so currently not need */ + { + Curve *cu; + cu = (Curve *)tmpobj->data; + if( cu->disp.first ) + MEM_freeN( cu->disp.first ); + cu->disp.first = NULL; + } - /* TODO: other types */ - if(ob->type != OB_MESH) { - BKE_report(reports, RPT_ERROR, "Object should be of type MESH."); - return NULL; - } +#endif - if (type == CREATE_MESH_PREVIEW) { - dm= mesh_create_derived_view(sce, ob, mask); - } - else { - dm= mesh_create_derived_render(sce, ob, mask); - } + /* get updated display list, and convert to a mesh */ + makeDispListCurveTypes( sce, tmpobj, 0 ); + nurbs_to_mesh( tmpobj ); + + /* nurbs_to_mesh changes the type to a mesh, check it worked */ + if (tmpobj->type != OB_MESH) { + free_libblock_us( &G.main->object, tmpobj ); + BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); + return NULL; + } + tmpmesh = tmpobj->data; + free_libblock_us( &G.main->object, tmpobj ); + break; + + case OB_MBALL: + /* metaballs don't have modifiers, so just convert to mesh */ + ob = find_basis_mball( sce, ob ); + tmpmesh = add_mesh("Mesh"); + mball_to_mesh( &ob->disp, tmpmesh ); + break; + + case OB_MESH: + /* copies object and modifiers (but not the data) */ + if (cage) { + /* copies the data */ + tmpmesh = copy_mesh( ob->data ); + /* if not getting the original caged mesh, get final derived mesh */ + } else { + /* Make a dummy mesh, saves copying */ + DerivedMesh *dm; + /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */ + CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter, + for example, needs CD_MASK_MDEFORMVERT */ + + /* Write the display mesh into the dummy mesh */ + if (render) + dm = mesh_create_derived_render( sce, ob, mask ); + else + dm = mesh_create_derived_view( sce, ob, mask ); + + tmpmesh = add_mesh( "Mesh" ); + DM_to_mesh( dm, tmpmesh ); + dm->release( dm ); + } + + break; + default: + BKE_report(reports, RPT_ERROR, "Object does not have geometry data"); + return NULL; + } + + /* Copy materials to new mesh */ + switch (ob->type) { + case OB_SURF: + tmpmesh->totcol = tmpcu->totcol; + + /* free old material list (if it exists) and adjust user counts */ + if( tmpcu->mat ) { + for( i = tmpcu->totcol; i-- > 0; ) { + /* are we an object material or data based? */ + if (ob->colbits & 1<mat[i] = ob->mat[i]; + else + tmpmesh->mat[i] = tmpcu->mat[i]; + + if (tmpmesh->mat[i]) + tmpmesh->mat[i]->id.us++; + } + } + break; + +#if 0 + /* Crashes when assigning the new material, not sure why */ + case OB_MBALL: + tmpmb = (MetaBall *)ob->data; + tmpmesh->totcol = tmpmb->totcol; + + /* free old material list (if it exists) and adjust user counts */ + if( tmpmb->mat ) { + for( i = tmpmb->totcol; i-- > 0; ) { + tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */ + if (tmpmesh->mat[i]) { + tmpmb->mat[i]->id.us++; + } + } + } + break; +#endif - if(!dm) { - /* TODO: report */ - return NULL; - } + case OB_MESH: + if (!cage) { + Mesh *origmesh= ob->data; + tmpmesh->flag= origmesh->flag; + tmpmesh->mat = MEM_dupallocN(origmesh->mat); + tmpmesh->totcol = origmesh->totcol; + tmpmesh->smoothresh= origmesh->smoothresh; + if( origmesh->mat ) { + for( i = origmesh->totcol; i-- > 0; ) { + /* are we an object material or data based? */ + if (ob->colbits & 1<mat[i] = ob->mat[i]; + else + tmpmesh->mat[i] = origmesh->mat[i]; + if (tmpmesh->mat[i]) + tmpmesh->mat[i]->id.us++; + } + } + } + break; + } /* end copy materials */ - me= add_mesh("tmp_render_mesh"); - me->id.us--; /* we don't assign it to anything */ - DM_to_mesh(dm, me); - dm->release(dm); + /* we don't assign it to anything */ + tmpmesh->id.us--; + + /* make sure materials get updated in objects */ + test_object_materials( ( ID * ) tmpmesh ); - return me; + return tmpmesh; } /* When no longer needed, duplilist should be freed with Object.free_duplilist */ @@ -166,9 +294,18 @@ static void rna_Object_add_vertex_to_group(Object *ob, int vertex_index, bDeform add_vert_to_defgroup(ob, def, vertex_index, weight, assignmode); } -static void rna_Object_dag_update(Object *ob, bContext *C) +/* copied from old API Object.makeDisplayList (Object.c) */ +static void rna_Object_make_display_list(Object *ob, bContext *C) { - DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA); + Scene *sce= CTX_data_scene(C); + + if (ob->type == OB_FONT) { + Curve *cu = ob->data; + freedisplist(&cu->disp); + BKE_text_to_curve(sce, ob, CU_LEFT); + } + + DAG_object_flush_update(sce, ob, OB_RECALC_DATA); } /* @@ -215,8 +352,8 @@ void RNA_api_object(StructRNA *srna) PropertyRNA *parm; static EnumPropertyItem mesh_type_items[] = { - {CREATE_MESH_PREVIEW, "PREVIEW", 0, "Preview", "Apply preview settings."}, - {CREATE_MESH_RENDER, "RENDER", 0, "Render", "Apply render settings."}, + {0, "PREVIEW", 0, "Preview", "Apply modifier preview settings."}, + {1, "RENDER", 0, "Render", "Apply modifier render settings."}, {0, NULL, 0, NULL, NULL} }; @@ -229,9 +366,11 @@ void RNA_api_object(StructRNA *srna) /* mesh */ func= RNA_def_function(srna, "create_mesh", "rna_Object_create_mesh"); - RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); + RNA_def_function_ui_description(func, "Create a Mesh datablock with modifiers applied."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_enum(func, "type", mesh_type_items, 0, "", "Type of mesh settings to apply."); + RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Mesh settings to apply."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); @@ -270,8 +409,8 @@ void RNA_api_object(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); /* DAG */ - func= RNA_def_function(srna, "dag_update", "rna_Object_dag_update"); - RNA_def_function_ui_description(func, "DAG update."); /* XXX describe better */ + func= RNA_def_function(srna, "make_display_list", "rna_Object_make_display_list"); + RNA_def_function_ui_description(func, "Update object's display data."); /* XXX describe better */ RNA_def_function_flag(func, FUNC_USE_CONTEXT); } -- cgit v1.2.3 From 140f2b154f0a68cfe0ff6c42de8102883cd0958a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 16 Jul 2009 19:07:54 +0000 Subject: Reverted BF_GETTEXT_LIB in config/linuxcross-config.py to previous value. Cross-compiling works! Started a wiki page describing the process here: http://wiki.blender.org/index.php/User:Kazanbas/Cross-compiling_Blender_2.5_on_Linux TODO: - make scons copy DLLs to install directory - deal with python: which version, what to install, etc. - package up into .msi? --- config/linuxcross-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index 5253110be66..8bc1391db6d 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -77,7 +77,7 @@ WITH_BF_INTERNATIONAL = True BF_GETTEXT = LIBDIR + '/gettext' BF_GETTEXT_INC = '${BF_GETTEXT}/include' -BF_GETTEXT_LIB = 'gettextlib' +BF_GETTEXT_LIB = 'gnu_gettext' # BF_GETTEXT_LIB = 'gnu_gettext' BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' -- cgit v1.2.3 From 122104b3bb1a69549b0bd016c29aa01dc71f3704 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 17 Jul 2009 10:09:07 +0000 Subject: FBX exporter conversion almost done. Unit tests: - add a check that BKE_copy_images produces NULL filepath for images having type other than IMA_TYPE_IMAGE - also expect NULL filepath for images having empty filename Enhanced BKE_copy_images so the tests pass. --- release/io/export_fbx.py | 136 ++++++++++++++++-------- source/blender/blenkernel/intern/image.c | 26 ++--- source/blender/makesrna/intern/rna_object_api.c | 2 +- source/blender/python/intern/bpy_util.c | 3 +- 4 files changed, 104 insertions(+), 63 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index d74e6246104..c19a914d22e 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -297,6 +297,29 @@ def BPyMesh_meshWeight2List(ob): return groupNames, vWeightList +def BPyMesh_meshWeight2Dict(me, ob): + ''' Takes a mesh and return its group names and a list of dicts, one dict per vertex. + using the group as a key and a float value for the weight. + These 2 lists can be modified and then used with dict2MeshWeight to apply the changes. + ''' + + vWeightDict= [dict() for i in xrange(len(me.verts))] # Sync with vertlist. + + # Clear the vert group. + groupNames= [g.name for g in ob.vertex_groups] +# groupNames= me.getVertGroupNames() + + for group in groupNames: + for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples. + vWeightDict[vert_index][group]= weight + + # removed this because me may be copying teh vertex groups. + #for group in groupNames: + # me.removeVertGroup(group) + + return groupNames, vWeightDict + + def meshNormalizedWeights(me): try: # account for old bad BPyMesh groupNames, vWeightList = BPyMesh_meshWeight2List(me) @@ -1498,7 +1521,7 @@ def write(filename, batch_objects = None, \ if my_mesh.blenTextures: do_textures = True else: do_textures = False - do_uvs = len(me.uv_layers) > 0 + do_uvs = len(me.uv_textures) > 0 # do_uvs = me.faceUV @@ -2073,8 +2096,9 @@ def write(filename, batch_objects = None, \ origData = True if tmp_ob_type != 'MESH': # if tmp_ob_type != 'Mesh': - me = bpy.data.meshes.new() - try: me.getFromObject(ob) +# me = bpy.data.meshes.new() + try: me = ob.create_mesh(True, 'PREVIEW') +# try: me.getFromObject(ob) except: me = None if me: meshes_to_clear.append( me ) @@ -2084,65 +2108,70 @@ def write(filename, batch_objects = None, \ # Mesh Type! if EXP_MESH_APPLY_MOD: # me = bpy.data.meshes.new() - me = ob.create_mesh('PREVIEW') + me = ob.create_mesh(True, 'PREVIEW') # me.getFromObject(ob) # so we keep the vert groups - if EXP_ARMATURE: - orig_mesh = ob.data +# if EXP_ARMATURE: # orig_mesh = ob.getData(mesh=1) - if len(ob.vertex_groups): # if orig_mesh.getVertGroupNames(): - ob.copy().link(me) - # If new mesh has no vgroups we can try add if verts are teh same - if not me.getVertGroupNames(): # vgroups were not kept by the modifier - if len(me.verts) == len(orig_mesh.verts): - groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh) - BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) +# ob.copy().link(me) +# # If new mesh has no vgroups we can try add if verts are teh same +# if not me.getVertGroupNames(): # vgroups were not kept by the modifier +# if len(me.verts) == len(orig_mesh.verts): +# groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh) +# BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) # print ob, me, me.getVertGroupNames() meshes_to_clear.append( me ) origData = False mats = me.materials else: - me = ob.getData(mesh=1) + me = ob.data +# me = ob.getData(mesh=1) mats = me.materials - # Support object colors - tmp_colbits = ob.colbits - if tmp_colbits: - tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too. - for i in xrange(16): - if tmp_colbits & (1< 0: +# if me.faceUV: + uvlayer_orig = me.active_uv_texture +# uvlayer_orig = me.activeUVLayer + for uvlayer in me.uv_textures: +# for uvlayer in me.getUVLayerNames(): +# me.activeUVLayer = uvlayer + for f, uf in zip(me.faces, uvlayer.data): +# for f in me.faces: + tex = uf.image +# tex = f.image textures[tex] = texture_mapping_local[tex] = None - try: mat = mats[f.mat] + try: mat = mats[f.material_index] +# try: mat = mats[f.mat] except: mat = None materials[mat, tex] = material_mapping_local[mat, tex] = None # should use sets, wait for blender 2.5 - me.activeUVLayer = uvlayer_orig +# me.activeUVLayer = uvlayer_orig else: for mat in mats: # 2.44 use mat.lib too for uniqueness @@ -2155,9 +2184,12 @@ def write(filename, batch_objects = None, \ blenParentBoneName = None # parent bone - special case - if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE: + if (not armob) and ob.parent and ob.parent.type == 'ARMATURE' and \ + ob.parent_type == 'BONE': +# if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE: armob = ob.parent - blenParentBoneName = ob.parentbonename + blenParentBoneName = ob.parent_bone +# blenParentBoneName = ob.parentbonename if armob and armob not in ob_arms: @@ -2181,7 +2213,11 @@ def write(filename, batch_objects = None, \ my_mesh.fbxBoneParent = blenParentBoneName # replace with my_bone instance later ob_meshes.append( my_mesh ) - + + # not forgetting to free dupli_list + if ob_base.dupli_list: ob_base.free_dupli_list() + + if EXP_ARMATURE: # now we have the meshes, restore the rest arm position for i, arm in enumerate(bpy.data.armatures): @@ -2217,7 +2253,8 @@ def write(filename, batch_objects = None, \ # fbxName, blenderObject, my_bones, blenderActions #ob_arms[i] = fbxArmObName, ob, arm_my_bones, (ob.action, []) - for bone in my_arm.blenData.bones.values(): + for bone in my_arm.blenData.bones: +# for bone in my_arm.blenData.bones.values(): my_bone = my_bone_class(bone, my_arm) my_arm.fbxBones.append( my_bone ) ob_bones.append( my_bone ) @@ -2662,7 +2699,8 @@ Connections: {''') # Needed for scene footer as well as animation - render = sce.render + render = sce.render_data +# render = sce.render # from the FBX sdk #define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000)) @@ -2671,8 +2709,10 @@ Connections: {''') return int(0.5 + ((t/fps) * 46186158000)) fps = float(render.fps) - start = render.sFrame - end = render.eFrame + start = sce.start_frame +# start = render.sFrame + end = sce.end_frame +# end = render.eFrame if end < start: start, end = end, start if start==end: ANIM_ENABLE = False @@ -2959,8 +2999,6 @@ Takes: {''') bpy.data.remove_mesh(me) # me.verts = None - - # --------------------------- Footer if world: m = world.mist @@ -3025,7 +3063,8 @@ Takes: {''') if EXP_IMAGE_COPY: copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) - print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) + print 'export finished in %.4f sec.' % (bpy.sys.time() - start_time) +# print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) return True @@ -3338,11 +3377,14 @@ if __name__ == '__main__': # NOTES (all line numbers correspond to original export_fbx.py (under release/scripts) # - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print # - get rid of cleanName somehow -# - isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 +# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 # - get rid of BPyObject_getObjectArmature, move it in RNA? # - BATCH_ENABLE and BATCH_GROUP options: line 327 # - implement all BPyMesh_* used here with RNA # - getDerivedObjects is not fully replicated with .dupli* funcs +# - talk to Campbell, this code won't work? lines 1867-1875 +# - don't know what those colbits are, do we need them? they're said to be deprecated in DNA_object_types.h: 1886-1893 +# - no hq normals: 1900-1901 # TODO diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 495dd3ec523..833d5ac1a90 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2120,6 +2120,7 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr) Copy list of images to dest_dir. paths is optional, if given, image paths for each image will be written in it. + It will also contain NULLs for images that cannot be copied. If an image file doesn't exist, NULL is added in paths. Logic: @@ -2161,6 +2162,13 @@ void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths) while (link) { im= link->data; + LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData"); + ld->data= NULL; + BLI_addtail(paths, ld); + + if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE) + goto next; + BLI_strncpy(path, im->name, sizeof(path)); /* expand "//" in filename and get absolute path */ @@ -2169,16 +2177,8 @@ void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths) /* in unit tests, we don't want to modify the filesystem */ #ifndef WITH_UNIT_TEST /* proceed only if image file exists */ - if (!BLI_exists(path)) { - - if (paths) { - LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData"); - ld->data= NULL; - BLI_addtail(paths, ld); - } - - continue; - } + if (!BLI_exists(path)) + goto next; #endif /* get the directory part */ @@ -2219,17 +2219,17 @@ void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths) } #ifndef WITH_UNIT_TEST - BLI_copy_fileops(path, dest_path); + if (BLI_copy_fileops(path, dest_path) != 0) + goto next; #endif if (paths) { - LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData"); len= strlen(dest_path) + 1; ld->data= MEM_callocN(len, "PathLinkData"); BLI_strncpy(ld->data, dest_path, len); - BLI_addtail(paths, ld); } + next: link= link->next; } } diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index bae651bf806..27a0ceb21c1 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -370,7 +370,7 @@ void RNA_api_object(StructRNA *srna) RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers."); RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Mesh settings to apply."); + parm= RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 3295bdd91c0..c5fd030cdd6 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -583,9 +583,8 @@ static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args) /* convert filenames */ ret= PyList_New(0); - len= BLI_countlist(paths); - for(link= paths->first, i= 0; link; link++, i++) { + for(link= paths->first; link; link= link->next) { if (link->data) { item= PyUnicode_FromString(link->data); PyList_Append(ret, item); -- cgit v1.2.3 From 2830f25ff3bf7a80c88b86132f76081ced3e86a1 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 17 Jul 2009 19:09:42 +0000 Subject: Another try with building better trees (this should never make worst trees) Expected number of BB tests should reduce a bit (depending on the scene) --- .../render/intern/raytrace/rayobject_vbvh.cpp | 128 ++++++++++++------- source/blender/render/intern/raytrace/reorganize.h | 138 +++++++++++++++++++++ 2 files changed, 219 insertions(+), 47 deletions(-) create mode 100644 source/blender/render/intern/raytrace/reorganize.h diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 8c2139fe6ca..17ed63e3669 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -38,6 +38,7 @@ extern "C" #include "rayobject.h" }; +#include "reorganize.h" #include "bvh.h" #include @@ -146,9 +147,9 @@ void pushdown(Node *parent) //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) - if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3)) + if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3) && RayObject_isAligned(i->child)) { -// todo optimize (hsould the one with the smallest area +// todo optimize (should the one with the smallest area?) // float ia = bb_area(i->bb, i->bb+3) // if(child->i) *s_child = child->sibling; @@ -167,8 +168,65 @@ void pushdown(Node *parent) pushdown( i ); } +template +int count_childs(Node *parent) +{ + int n = 0; + for(Node *i = parent->child; i; i = i->sibling) + { + n++; + if(!RayObject_isAligned(i)) + break; + } + + return n; +} + +template +void append_sibling(Node *node, Node *sibling) +{ + while(node->sibling) + node = node->sibling; + + node->sibling = sibling; +} + +template +void pushup(Node *parent) +{ + float p_area = bb_area(parent->bb, parent->bb+3); + Node **prev = &parent->child; + for(Node *child = parent->child; RayObject_isAligned(child) && child; ) + { + float c_area = bb_area(child->bb, child->bb+3) ; + int nchilds = count_childs(child); + float original_cost = (c_area / p_area)*nchilds + 1; + float flatten_cost = nchilds; + if(flatten_cost < original_cost && nchilds >= 2) + { + append_sibling(child, child->child); + child = child->sibling; + *prev = child; + +// *prev = child->child; +// append_sibling( *prev, child->sibling ); +// child = *prev; + tot_pushup++; + } + else + { + *prev = child; + prev = &(*prev)->sibling; + child = *prev; + } + } + + for(Node *child = parent->child; RayObject_isAligned(child) && child; child = child->sibling) + pushup(child); +} + template -Node *bvh_rearrange(Tree *tree, Builder *builder, float *cost) +Node *bvh_rearrange(Tree *tree, Builder *builder) { int size = rtbuild_size(builder); @@ -176,61 +234,31 @@ Node *bvh_rearrange(Tree *tree, Builder *builder, float *cost) { Node *node = bvh_new_node(tree); INIT_MINMAX(node->bb, node->bb+3); - rtbuild_merge_bb(builder, node->bb, node->bb+3); - + rtbuild_merge_bb(builder, node->bb, node->bb+3); node->child = (BVHNode*)builder->begin[0]; - - *cost = RE_rayobject_cost((RayObject*)node->child)+RAY_BB_TEST_COST; return node; } else { Node *node = bvh_new_node(tree); - float parent_area; - + INIT_MINMAX(node->bb, node->bb+3); rtbuild_merge_bb(builder, node->bb, node->bb+3); - parent_area = bb_area( node->bb, node->bb+3 ); Node **child = &node->child; - - std::queue childs; - childs.push(*builder); - - *cost = 0; - - while(!childs.empty()) + + int nc = rtbuild_split(builder, 2); + assert(nc == 2); + for(int i=0; i 1.0f / 2.0f && rtbuild_size(&b) > 1) - { - //The expected number of BB test is smaller if we directly add the 2 childs of this node - int nc = rtbuild_split(&b, 2); - assert(nc == 2); - for(int i=0; i(tree, &b, &tcost); - child = &((*child)->sibling); - - *cost += tcost*hit_prob + RAY_BB_TEST_COST; - } + *child = bvh_rearrange(tree, &tmp); + child = &((*child)->sibling); } - assert(child != &node->child); - *child = 0; + *child = 0; return node; } } @@ -246,9 +274,13 @@ void bvh_done(BVHTree *obj) BLI_memarena_use_malloc(obj->node_arena); - obj->root = bvh_rearrange( obj, obj->builder, &obj->cost ); + obj->root = bvh_rearrange( obj, obj->builder ); + reorganize(obj->root); + remove_useless(obj->root, &obj->root); + pushup(obj->root); pushdown(obj->root); -// obj->cost = 1.0; +// obj->root = memory_rearrange(obj->root); + obj->cost = 1.0; rtbuild_free( obj->builder ); obj->builder = NULL; @@ -336,14 +368,16 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) void bfree(BVHTree *tree) { - if(tot_pushup + tot_pushdown + tot_hints) + if(tot_pushup + tot_pushdown + tot_hints + tot_moves) { printf("tot pushups: %d\n", tot_pushup); printf("tot pushdowns: %d\n", tot_pushdown); + printf("tot moves: %d\n", tot_moves); printf("tot hints created: %d\n", tot_hints); tot_pushup = 0; tot_pushdown = 0; tot_hints = 0; + tot_moves = 0; } bvh_free(tree); } diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h new file mode 100644 index 00000000000..723c2b77902 --- /dev/null +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -0,0 +1,138 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include +#include + +template +bool node_fits_inside(Node *a, Node *b) +{ + return bb_fits_inside(b->bb, b->bb+3, a->bb, a->bb+3); +} + +template +void reorganize_find_fittest_parent(Node *tree, Node *node, std::pair &cost) +{ + std::queue q; + q.push(tree); + + while(!q.empty()) + { + Node *parent = q.front(); + q.pop(); + + if(parent == node) continue; + if(node_fits_inside(node, parent) && RayObject_isAligned(parent->child) ) + { + float pcost = bb_area(parent->bb, parent->bb+3); + cost = std::min( cost, std::make_pair(pcost,parent) ); + for(Node *child = parent->child; child; child = child->sibling) + q.push(child); + } + } +} + +static int tot_moves = 0; +template +void reorganize(Node *root) +{ + std::queue q; + + q.push(root); + while(!q.empty()) + { + Node * node = q.front(); + q.pop(); + + if( RayObject_isAligned(node->child) ) + { + for(Node **prev = &node->child; *prev; ) + { + assert( RayObject_isAligned(*prev) ); + q.push(*prev); + + std::pair best(FLT_MAX, root); + reorganize_find_fittest_parent( root, *prev, best ); + + if(best.second == node) + { + //Already inside the fitnest BB + prev = &(*prev)->sibling; + } + else + { + Node *tmp = *prev; + *prev = (*prev)->sibling; + + tmp->sibling = best.second->child; + best.second->child = tmp; + + tot_moves++; + } + + + } + } + if(node != root) + { + } + } +} + +/* + * Prunes useless nodes from trees: + * erases nodes with total ammount of primitives = 0 + * prunes nodes with only one child (except if that child is a primitive) + */ +template +void remove_useless(Node *node, Node **new_node) +{ + if( RayObject_isAligned(node->child) ) + { + + for(Node **prev = &node->child; *prev; ) + { + Node *next = (*prev)->sibling; + remove_useless(*prev, prev); + if(*prev == 0) + *prev = next; + else + { + (*prev)->sibling = next; + prev = &((*prev)->sibling); + } + } + } + if(node->child) + { + if(RayObject_isAligned(node->child) && node->child->child == 0) + *new_node = node->child; + } + else if(node->child == 0) + *new_node = 0; +} -- cgit v1.2.3 From 00e219d8e97afcf3767a6d2b28a6d05bcc984279 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 22 Jul 2009 13:35:02 +0000 Subject: FBX exporter: - made an operator with props for UI. UI is still "raw" - ran 2to3 on export_fbx.py to make it python 3-compatible Next: testing/fixing. --- release/io/export_fbx.py | 189 +++++++++++++++++------- release/io/export_obj.py | 1 + release/io/export_ply.py | 2 +- source/blender/makesrna/intern/rna_object_api.c | 2 +- 4 files changed, 138 insertions(+), 56 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 64a8870bb3d..a861436d132 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -38,6 +38,7 @@ http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx import os import time +import math # math.pi # try: # import time @@ -65,10 +66,10 @@ import bpy import Mathutils # from Blender.Mathutils import Matrix, Vector, RotationMatrix -import BPyObject -import BPyMesh -import BPySys -import BPyMessages +# import BPyObject +# import BPyMesh +# import BPySys +# import BPyMessages ## This was used to make V, but faster not to do all that ##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' @@ -79,7 +80,7 @@ invalid = ''.join([chr(i) for i in v]) def cleanName(name): for ch in invalid: name = name.replace(ch, '_') return name -del v, i +# del v, i def copy_file(source, dest): @@ -107,14 +108,14 @@ def copy_images(dest_dir, textures): # Make a name for the target path. dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] if not Blender.sys.exists(dest_image_path): # Image isnt alredy there - print '\tCopying "%s" > "%s"' % (image_path, dest_image_path) + print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) try: copy_file(image_path, dest_image_path) copyCount+=1 except: - print '\t\tWarning, file failed to copy, skipping.' + print('\t\tWarning, file failed to copy, skipping.') - print '\tCopied %d images' % copyCount + print('\tCopied %d images' % copyCount) def BPyObject_getObjectArmature(ob): ''' @@ -141,9 +142,9 @@ def BPyObject_getObjectArmature(ob): def eulerRadToDeg(eul): ret = Mathutils.Euler() - ret.x = 180 / math.pi * eul.x - ret.y = 180 / math.pi * eul.y - ret.z = 180 / math.pi * eul.z + ret.x = 180 / math.pi * eul[0] + ret.y = 180 / math.pi * eul[1] + ret.z = 180 / math.pi * eul[2] return ret @@ -221,7 +222,7 @@ def sane_name(data, dct): #name = BPySys.cleanName(name) name = cleanName(name) # use our own - while name in dct.itervalues(): name = increment_string(name) + while name in iter(dct.values()): name = increment_string(name) if use_other: # even if other is None - orig_name_other will be a string or None dct[orig_name, orig_name_other] = name @@ -286,9 +287,9 @@ def BPyMesh_meshWeight2List(ob): if not len_groupNames: # no verts? return a vert aligned empty list - return [[] for i in xrange(len(me.verts))], [] + return [[] for i in range(len(me.verts))], [] else: - vWeightList= [[0.0]*len_groupNames for i in xrange(len(me.verts))] + vWeightList= [[0.0]*len_groupNames for i in range(len(me.verts))] for i, v in enumerate(me.verts): for g in v.groups: @@ -303,7 +304,7 @@ def BPyMesh_meshWeight2Dict(me, ob): These 2 lists can be modified and then used with dict2MeshWeight to apply the changes. ''' - vWeightDict= [dict() for i in xrange(len(me.verts))] # Sync with vertlist. + vWeightDict= [dict() for i in range(len(me.verts))] # Sync with vertlist. # Clear the vert group. groupNames= [g.name for g in ob.vertex_groups] @@ -368,7 +369,6 @@ def write(filename, batch_objects = None, \ ANIM_ACTION_ALL = False, BATCH_ENABLE = False, BATCH_GROUP = True, - BATCH_SCENE = False, BATCH_FILE_PREFIX = '', BATCH_OWN_DIR = False ): @@ -436,7 +436,7 @@ def write(filename, batch_objects = None, \ filename = new_fbxpath + newname + '.fbx' - print '\nBatch exporting %s as...\n\t"%s"' % (data, filename) + print('\nBatch exporting %s as...\n\t"%s"' % (data, filename)) # XXX don't know what to do with this, probably do the same? (Arystan) if BATCH_GROUP: #group @@ -596,7 +596,8 @@ def write(filename, batch_objects = None, \ self.fbxGroupNames = [] self.fbxParent = None # set later on IF the parent is in the selection. if matrixWorld: self.matrixWorld = matrixWorld * GLOBAL_MATRIX - else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX + else: self.matrixWorld = ob.matrix * GLOBAL_MATRIX +# else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX self.__anim_poselist = {} # we should only access this def parRelMatrix(self): @@ -606,7 +607,8 @@ def write(filename, batch_objects = None, \ return self.matrixWorld def setPoseFrame(self, f): - self.__anim_poselist[f] = self.blenObject.matrixWorld.copy() + self.__anim_poselist[f] = self.blenObject.matrix.copy() +# self.__anim_poselist[f] = self.blenObject.matrixWorld.copy() def getAnimParRelMatrix(self, frame): if self.fbxParent: @@ -638,7 +640,7 @@ def write(filename, batch_objects = None, \ - print '\nFBX export starting...', filename + print('\nFBX export starting...', filename) start_time = bpy.sys.time() # start_time = Blender.sys.time() try: @@ -713,7 +715,7 @@ def write(filename, batch_objects = None, \ else: # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore #if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX - if ob and not matrix: raise "error: this should never happen!" + if ob and not matrix: raise Exception("error: this should never happen!") matrix_rot = matrix #if matrix: @@ -751,7 +753,7 @@ def write(filename, batch_objects = None, \ loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod) file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc) - file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % eulerRadToDeg(rot)) + file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % tuple(eulerRadToDeg(rot))) # file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale) return loc, rot, scale, matrix, matrix_rot @@ -1453,7 +1455,7 @@ def write(filename, batch_objects = None, \ # TODO - this is a bit lazy, we could have a simple write loop # for this case because all weights are 1.0 but for now this is ok # Parent Bones arent used all that much anyway. - vgroup_data = [(j, 1.0) for j in xrange(len(my_mesh.blenData.verts))] + vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.verts))] else: # This bone is not a parent of this mesh object, no weights vgroup_data = [] @@ -1728,7 +1730,7 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tColorIndex: ') i = -1 - for j in xrange(ii): + for j in range(ii): if i == -1: file.write('%i' % j) i=0 @@ -1786,7 +1788,7 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t\tUVIndex: ') i = -1 - for j in xrange(ii): + for j in range(ii): if i == -1: file.write('%i' % j) i=0 @@ -1890,7 +1892,7 @@ def write(filename, batch_objects = None, \ uv_faces = [None] * len(me.faces) i=-1 - for f, uf in zip(me.faces, uv_faces) + for f, uf in zip(me.faces, uv_faces): # for f in me.faces: try: mat = mats[f.material_index] # try: mat = mats[f.mat] @@ -1955,7 +1957,7 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t}') if len(uvlayers) > 1: - for i in xrange(1, len(uvlayers)): + for i in range(1, len(uvlayers)): file.write('\n\t\tLayer: %i {' % i) file.write('\n\t\t\tVersion: 100') @@ -1983,7 +1985,7 @@ def write(filename, batch_objects = None, \ layer_offset = 0 if uvlayers: layer_offset = len(uvlayers)-1 - for i in xrange(layer_offset, len(collayers)+layer_offset): + for i in range(layer_offset, len(collayers)+layer_offset): file.write('\n\t\tLayer: %i {' % i) file.write('\n\t\t\tVersion: 100') @@ -2033,7 +2035,8 @@ def write(filename, batch_objects = None, \ # if EXP_OBS_SELECTED is false, use sceens objects if not batch_objects: - if EXP_OBS_SELECTED: tmp_objects = sce.objects.context + if EXP_OBS_SELECTED: tmp_objects = context.selected_objects +# if EXP_OBS_SELECTED: tmp_objects = sce.objects.context else: tmp_objects = sce.objects else: tmp_objects = batch_objects @@ -2201,9 +2204,9 @@ def write(filename, batch_objects = None, \ my_mesh = my_object_generic(ob, mtx) my_mesh.blenData = me my_mesh.origData = origData - my_mesh.blenMaterials = material_mapping_local.keys() + my_mesh.blenMaterials = list(material_mapping_local.keys()) my_mesh.blenMaterialList = mats - my_mesh.blenTextures = texture_mapping_local.keys() + my_mesh.blenTextures = list(texture_mapping_local.keys()) # if only 1 null texture then empty the list if len(my_mesh.blenTextures) == 1 and my_mesh.blenTextures[0] == None: @@ -2336,8 +2339,8 @@ def write(filename, batch_objects = None, \ # Finished finding groups we use - materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.iterkeys()] - textures = [(sane_texname(tex), tex) for tex in textures.iterkeys() if tex] + materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.keys()] + textures = [(sane_texname(tex), tex) for tex in textures.keys() if tex] materials.sort() # sort by name textures.sort() @@ -2497,7 +2500,7 @@ Objects: {''') #for bonename, bone, obname, bone_mesh, armob in ob_bones: for my_bone in ob_bones: - if me in my_bone.blenMeshes.itervalues(): + if me in iter(my_bone.blenMeshes.values()): write_sub_deformer_skin(my_mesh, my_bone, weights) # Write pose's really weired, only needed when an armature and mesh are used together @@ -2784,9 +2787,9 @@ Takes: {''') # we have tagged all actious that are used be selected armatures if blenAction: if blenAction.tag: - print '\taction: "%s" exporting...' % blenAction.name + print('\taction: "%s" exporting...' % blenAction.name) else: - print '\taction: "%s" has no armature using it, skipping' % blenAction.name + print('\taction: "%s" has no armature using it, skipping' % blenAction.name) continue if blenAction == None: @@ -2866,7 +2869,7 @@ Takes: {''') file.write('\n\t\t\tVersion: 1.1') file.write('\n\t\t\tChannel: "Transform" {') - context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in xrange(act_start, act_end+1) ] + context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in range(act_start, act_end+1) ] # ---------------- # ---------------- @@ -2889,7 +2892,7 @@ Takes: {''') file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation - for i in xrange(3): + for i in range(3): # Loop on each axis of the bone file.write('\n\t\t\t\t\tChannel: "%s" {'% ('XYZ'[i])) # translation file.write('\n\t\t\t\t\t\tDefault: %.15f' % context_bone_anim_vecs[0][i] ) @@ -3064,7 +3067,7 @@ Takes: {''') # copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) bpy.util.copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) - print 'export finished in %.4f sec.' % (bpy.sys.time() - start_time) + print('export finished in %.4f sec.' % (bpy.sys.time() - start_time)) # print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) return True @@ -3072,7 +3075,7 @@ Takes: {''') # -------------------------------------------- # UI Function - not a part of the exporter. # this is to seperate the user interface from the rest of the exporter. -from Blender import Draw, Window +# from Blender import Draw, Window EVENT_NONE = 0 EVENT_EXIT = 1 EVENT_REDRAW = 2 @@ -3123,15 +3126,15 @@ def fbx_ui_exit(e,v): def do_help(e,v): url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' - print 'Trying to open web browser with documentation at this address...' - print '\t' + url + print('Trying to open web browser with documentation at this address...') + print('\t' + url) try: import webbrowser webbrowser.open(url) except: Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation") - print '...could not open a browser window.' + print('...could not open a browser window.') @@ -3358,17 +3361,95 @@ def write_ui(): # GLOBALS.clear() -#test = [write_ui] -if __name__ == '__main__': - # Cant call the file selector first because of a bug in the interface that crashes it. - # Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx')) - #write('/scratch/test.fbx') - #write_ui('/scratch/test.fbx') - - if not set: - Draw.PupMenu('Error%t|A full install of python2.3 or python 2.4+ is needed to run this script.') - else: - write_ui() + +class EXPORT_OT_fbx(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "export.fbx" + __label__ = "Export FBX" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default=""), + bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True), +# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True), + bpy.props.FloatProperty(attr="_SCALE", name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0), + bpy.props.BoolProperty(attr="_XROT90", name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True), + bpy.props.BoolProperty(attr="_YROT90", name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False), + bpy.props.BoolProperty(attr="_ZROT90", name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False), + bpy.props.BoolProperty(attr="EXP_EMPTY", name="Empties", description="Export empty objects", default=True), + bpy.props.BoolProperty(attr="EXP_CAMERA", name="Cameras", description="Export camera objects", default=True), + bpy.props.BoolProperty(attr="EXP_LAMP", name="Lamps", description="Export lamp objects", default=True), + bpy.props.BoolProperty(attr="EXP_ARMATURE", name="Armatures", description="Export armature objects", default=True), + bpy.props.BoolProperty(attr="EXP_MESH", name="Meshes", description="Export mesh objects", default=True), + bpy.props.BoolProperty(attr="EXP_MESH_APPLY_MOD", name="Modifiers", description="Apply modifiers to mesh objects", default=True), + bpy.props.BoolProperty(attr="EXP_MESH_HQ_NORMALS", name="HQ Normals", description="Generate high quality normals", default=True), + bpy.props.BoolProperty(attr="EXP_IMAGE_COPY", name="Copy Image Files", description="Copy image files to the destination path", default=False), + # armature animation + bpy.props.BoolProperty(attr="ANIM_ENABLE", name="Enable Animation", description="Export keyframe animation", default=True), + bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True), + bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0), +# bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True), + bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures", default=False), + # batch + bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False), + bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False), + bpy.props.BoolProperty(attr="BATCH_OWN_DIR", name="Own Dir", description="Create a dir for each exported file", default=True), + bpy.props.StringProperty(attr="BATCH_FILE_PREFIX", name="Prefix", description="Prefix each file with this name", maxlen= 1024, default=""), + ] + + def poll(self, context): + print("Poll") + return context.active_object != None + + def execute(self, context): + if not self.filename: + raise Exception("filename not set") + + GLOBAL_MATRIX = mtx4_identity + GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self._SCALE + if self._XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n + if self._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n + if self._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n + + write(self.filename, + None, # XXX + context, + self.EXP_OBS_SELECTED, + self.EXP_MESH, + self.EXP_MESH_APPLY_MOD, + self.EXP_MESH_HQ_NORMALS, + self.EXP_ARMATURE, + self.EXP_LAMP, + self.EXP_CAMERA, + self.EXP_EMPTY, + self.EXP_IMAGE_COPY, + GLOBAL_MATRIX, + self.ANIM_ENABLE, + self.ANIM_OPTIMIZE, + self.ANIM_OPTIMIZE_PRECISSION, + self.ANIM_ACTION_ALL, + self.BATCH_ENABLE, + self.BATCH_GROUP, + self.BATCH_FILE_PREFIX, + self.BATCH_OWN_DIR) + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + +bpy.ops.add(EXPORT_OT_fbx) + +# if __name__ == "__main__": +# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply") + # NOTES (all line numbers correspond to original export_fbx.py (under release/scripts) # - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 251fdfcf113..bf3aa4ae819 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -891,6 +891,7 @@ class EXPORT_OT_obj(bpy.types.Operator): * multiple scene export (only active scene is written) * particles ''' + __idname__ = "export.obj" __label__ = 'Export OBJ' # List of operator properties, the attributes will be assigned diff --git a/release/io/export_ply.py b/release/io/export_ply.py index 2028358ff3b..8cbb2d5605a 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -238,7 +238,7 @@ def write(filename, scene, ob, \ class EXPORT_OT_ply(bpy.types.Operator): ''' - Operator documentatuon text, will be used for the operator tooltip and python docs. + Operator documentation text, will be used for the operator tooltip and python docs. ''' __idname__ = "export.ply" __label__ = "Export PLY" diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 27a0ceb21c1..bc031c4e5f2 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -368,7 +368,7 @@ void RNA_api_object(StructRNA *srna) func= RNA_def_function(srna, "create_mesh", "rna_Object_create_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with modifiers applied."); RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers."); + parm= RNA_def_boolean(func, "apply_modifiers", 0, "", "Apply modifiers."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply."); RNA_def_property_flag(parm, PROP_REQUIRED); -- cgit v1.2.3 From c96041628e141b7bfc1da28be09510e7e0e5cd0a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 23 Jul 2009 12:55:26 +0000 Subject: API: - replaced BKE_copy_images with BKE_export_image, now it handles only one image at a time, this is better since for exporters it is easier to export one image at a time writing new image path to a file - exposing BKE_export_image in RNA as Image.export, interestingly, RNA allowed me to define a function with PROP_STRING return type although it doesn't free memory, will fix that in the next commit - removed bpy.util.copy_images Unit tests: - re-wrote a test for BKE_export_image, it's more compact now - moved unit tests to the creator module to avoid another executable, now running tests with `blender --test` - as before, unit tests are built only if WITH_BF_UNIT_TEST is non 0 --- SConstruct | 8 -- release/io/export_fbx.py | 35 +++++--- source/blender/blenkernel/BKE_image.h | 5 +- source/blender/blenkernel/intern/image.c | 130 ++++++++++++--------------- source/blender/makesrna/intern/makesrna.c | 2 +- source/blender/makesrna/intern/rna_image.c | 2 + source/blender/python/intern/bpy_interface.c | 2 +- source/blender/python/intern/bpy_util.c | 123 ------------------------- source/creator/SConscript | 11 ++- source/creator/creator.c | 6 ++ source/creator/tests/alltest.c | 114 +++++++++++++++++++++++ tools/Blender.py | 2 + tools/btools.py | 6 +- 13 files changed, 222 insertions(+), 224 deletions(-) create mode 100644 source/creator/tests/alltest.c diff --git a/SConstruct b/SConstruct index 2d1daba98b6..c1b4f8da174 100644 --- a/SConstruct +++ b/SConstruct @@ -409,14 +409,6 @@ if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: #env.BlenderProg(B.root_build_dir, "blender", dobj , [], mainlist + thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') blen = env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') - build_data = {"lib": thestatlibs + thesyslibs, "libpath": thelibincs, "blen": blen} - - Export('env') - Export('build_data') - - BuildDir(B.root_build_dir+'/tests', 'tests', duplicate=0) - SConscript(B.root_build_dir+'/tests/SConscript') - if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index a861436d132..f98cefb076e 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -356,7 +356,7 @@ def write(filename, batch_objects = None, \ EXP_OBS_SELECTED = True, EXP_MESH = True, EXP_MESH_APPLY_MOD = True, - EXP_MESH_HQ_NORMALS = False, +# EXP_MESH_HQ_NORMALS = False, EXP_ARMATURE = True, EXP_LAMP = True, EXP_CAMERA = True, @@ -464,7 +464,7 @@ def write(filename, batch_objects = None, \ False, EXP_MESH, EXP_MESH_APPLY_MOD, - EXP_MESH_HQ_NORMALS, +# EXP_MESH_HQ_NORMALS, EXP_ARMATURE, EXP_LAMP, EXP_CAMERA, @@ -2306,19 +2306,25 @@ def write(filename, batch_objects = None, \ # Build blenObject -> fbxObject mapping # this is needed for groups as well as fbxParenting - for ob in bpy.data.objects: ob.tag = False +# for ob in bpy.data.objects: ob.tag = False # bpy.data.objects.tag = False + + # using a list of object names for tagging (Arystan) + tagged_objects = [] + tmp_obmapping = {} for ob_generic in ob_all_typegroups: for ob_base in ob_generic: - ob_base.blenObject.tag = True + tagged_objects.append(ob_base.blenObject.name) +# ob_base.blenObject.tag = True tmp_obmapping[ob_base.blenObject] = ob_base # Build Groups from objects we export for blenGroup in bpy.data.groups: fbxGroupName = None for ob in blenGroup.objects: - if ob.tag: + if ob.name in tagged_objects: +# if ob.tag: if fbxGroupName == None: fbxGroupName = sane_groupname(blenGroup) groups.append((fbxGroupName, blenGroup)) @@ -2331,7 +2337,8 @@ def write(filename, batch_objects = None, \ for ob_generic in ob_all_typegroups: for my_ob in ob_generic: parent = my_ob.blenObject.parent - if parent and parent.tag: # does it exist and is it in the mapping + if parent and parent.name in tagged_objects: # does it exist and is it in the mapping +# if parent and parent.tag: # does it exist and is it in the mapping my_ob.fbxParent = tmp_obmapping[parent] @@ -2734,9 +2741,11 @@ Connections: {''') tmp_actions = [None] # None is the default action blenActionDefault = None action_lastcompat = None + + # instead of tagging + tagged_actions = [] if ANIM_ACTION_ALL: - for a in bpy.data.actions: a.tag = False # bpy.data.actions.tag = False tmp_actions = list(bpy.data.actions) @@ -2759,7 +2768,8 @@ Connections: {''') if action_chan_names: # at least one channel matches. my_arm.blenActionList.append(action) - action.tag = True + tagged_actions.append(action.name) +# action.tag = True tmp_act_count += 1 # incase there is no actions applied to armatures @@ -2786,7 +2796,8 @@ Takes: {''') for blenAction in tmp_actions: # we have tagged all actious that are used be selected armatures if blenAction: - if blenAction.tag: + if blenAction.name in tagged_actions: +# if blenAction.tag: print('\taction: "%s" exporting...' % blenAction.name) else: print('\taction: "%s" has no armature using it, skipping' % blenAction.name) @@ -3065,7 +3076,7 @@ Takes: {''') # copy images if enabled if EXP_IMAGE_COPY: # copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) - bpy.util.copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) + bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath) print('export finished in %.4f sec.' % (bpy.sys.time() - start_time)) # print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) @@ -3393,7 +3404,7 @@ class EXPORT_OT_fbx(bpy.types.Operator): bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True), bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0), # bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True), - bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures", default=False), + bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures, if false, use current action", default=False), # batch bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False), bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False), @@ -3421,7 +3432,7 @@ class EXPORT_OT_fbx(bpy.types.Operator): self.EXP_OBS_SELECTED, self.EXP_MESH, self.EXP_MESH_APPLY_MOD, - self.EXP_MESH_HQ_NORMALS, +# self.EXP_MESH_HQ_NORMALS, self.EXP_ARMATURE, self.EXP_LAMP, self.EXP_CAMERA, diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index f3f5266189a..052f7738f2b 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -155,10 +155,9 @@ struct Image *BKE_image_copy(struct Image *ima); /* merge source into dest, and free source */ void BKE_image_merge(struct Image *dest, struct Image *source); -/* ********************************** FOR EXPORTERS *********************** */ +/* copy image file to a directory rebuilding subdirectory structure */ +int BKE_export_image(struct Image *im, const char *dest_dir, char *out_path, int out_path_len); -/* copy images into dest_dir */ -void BKE_copy_images(struct ListBase *images, char *dest_dir, struct ListBase *filenames); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 833d5ac1a90..a469752602e 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2117,30 +2117,27 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr) } /* - Copy list of images to dest_dir. - - paths is optional, if given, image paths for each image will be written in it. - It will also contain NULLs for images that cannot be copied. - If an image file doesn't exist, NULL is added in paths. + Copy an image to destination directory rebuilding subdirectory structure if needed. + Target image path is written to out_path. + Returns 1 on success, 0 otherwise. Logic: - For each image if it's "below" current .blend file directory, - rebuild the same dir structure in dest_dir. + - if an image is "below" current .blend file directory, rebuild the same dir structure in dest_dir - For example //textures/foo/bar.png becomes - [dest_dir]/textures/foo/bar.png. + For example //textures/foo/bar.png becomes [dest_dir]/textures/foo/bar.png. - If an image is not "below" current .blend file directory, disregard - it's path and copy it in the same directory where 3D file goes. + - if an image is not "below" current .blend file directory, disregard it's path and copy it in the + same directory where 3D file goes. For example //../foo/bar.png becomes [dest_dir]/bar.png. This logic will help ensure that all image paths are relative and that a user gets his images in one place. It'll also provide consistent behaviour across exporters. -*/ -void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths) + + */ +int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_path_len) { char path[FILE_MAX]; char dir[FILE_MAX]; @@ -2148,88 +2145,77 @@ void BKE_copy_images(ListBase *images, char *dest_dir, ListBase *paths) char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */ char dest_path[FILE_MAX]; int len; - Image *im; - LinkData *link; - if (paths) { - memset(paths, 0, sizeof(*paths)); - } + out_path[0]= 0; BLI_split_dirfile_basic(G.sce, blend_dir, NULL); - - link= images->first; - - while (link) { - im= link->data; - - LinkData *ld = MEM_callocN(sizeof(LinkData), "PathLinkData"); - ld->data= NULL; - BLI_addtail(paths, ld); - if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE) - goto next; + if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE) { + if (G.f & G_DEBUG) printf("invalid image type\n"); + return 0; + } - BLI_strncpy(path, im->name, sizeof(path)); + BLI_strncpy(path, im->name, sizeof(path)); - /* expand "//" in filename and get absolute path */ - BLI_convertstringcode(path, G.sce); + /* expand "//" in filename and get absolute path */ + BLI_convertstringcode(path, G.sce); - /* in unit tests, we don't want to modify the filesystem */ + /* in unit tests, we don't want to modify the filesystem */ #ifndef WITH_UNIT_TEST - /* proceed only if image file exists */ - if (!BLI_exists(path)) - goto next; + /* proceed only if image file exists */ + if (!BLI_exists(path)) { + if (G.f & G_DEBUG) printf("%s doesn't exist\n", path); + goto next; + } #endif - /* get the directory part */ - BLI_split_dirfile_basic(path, dir, base); + /* get the directory part */ + BLI_split_dirfile_basic(path, dir, base); - len= strlen(blend_dir); + len= strlen(blend_dir); - /* if image is "below" current .blend file directory */ - if (!strncmp(path, blend_dir, len)) { + /* if image is "below" current .blend file directory */ + if (!strncmp(path, blend_dir, len)) { - /* if image is _in_ current .blend file directory */ - if (!strcmp(dir, blend_dir)) { - /* copy to dest_dir */ - BLI_join_dirfile(dest_path, dest_dir, base); - } - /* "below" */ - else { - char rel[FILE_MAX]; + /* if image is _in_ current .blend file directory */ + if (!strcmp(dir, blend_dir)) { + /* copy to dest_dir */ + BLI_join_dirfile(dest_path, dest_dir, base); + } + /* "below" */ + else { + char rel[FILE_MAX]; - /* rel = image_path_dir - blend_dir */ - BLI_strncpy(rel, dir + len, sizeof(rel)); + /* rel = image_path_dir - blend_dir */ + BLI_strncpy(rel, dir + len, sizeof(rel)); - BLI_join_dirfile(dest_path, dest_dir, rel); + BLI_join_dirfile(dest_path, dest_dir, rel); #ifndef WITH_UNIT_TEST - /* build identical directory structure under dest_dir */ - BLI_make_existing_file(dest_path); + /* build identical directory structure under dest_dir */ + BLI_make_existing_file(dest_path); #endif - BLI_join_dirfile(dest_path, dest_path, base); - } - - } - /* image is out of current directory */ - else { - /* copy to dest_dir */ - BLI_join_dirfile(dest_path, dest_dir, base); + BLI_join_dirfile(dest_path, dest_path, base); } + + } + /* image is out of current directory */ + else { + /* copy to dest_dir */ + BLI_join_dirfile(dest_path, dest_dir, base); + } #ifndef WITH_UNIT_TEST - if (BLI_copy_fileops(path, dest_path) != 0) - goto next; + if (G.f & G_DEBUG) printf("copying %s to %s\n", path, dest_path); + + if (BLI_copy_fileops(path, dest_path) != 0) { + if (G.f & G_DEBUG) printf("couldn't copy %s to %s\n", path, dest_path); + return 0; + } #endif - if (paths) { - len= strlen(dest_path) + 1; - ld->data= MEM_callocN(len, "PathLinkData"); - BLI_strncpy(ld->data, dest_path, len); - } + BLI_strncpy(out_path, dest_path, out_path_len); - next: - link= link->next; - } + return 1; } diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 63ce5786ae3..03d8edde4b3 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1936,7 +1936,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_fcurve.c", NULL, RNA_def_fcurve}, {"rna_fluidsim.c", NULL, RNA_def_fluidsim}, {"rna_group.c", NULL, RNA_def_group}, - {"rna_image.c", NULL, RNA_def_image}, + {"rna_image.c", "rna_image_api.c", RNA_def_image}, {"rna_key.c", NULL, RNA_def_key}, {"rna_lamp.c", NULL, RNA_def_lamp}, {"rna_lattice.c", NULL, RNA_def_lattice}, diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index fbef838d06c..5366296a6b8 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -312,6 +312,8 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_int_funcs(prop, "rna_Image_depth_get", NULL, NULL); RNA_def_property_ui_text(prop, "Depth", "Image bit depth."); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + RNA_api_image(srna); } void RNA_def_image(BlenderRNA *brna) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index f045e977394..4ab79dcf074 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -93,7 +93,7 @@ void BPY_update_modules( void ) PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject( mod, "data", BPY_rna_module() ); PyModule_AddObject( mod, "types", BPY_rna_types() ); - PyModule_AddObject( mod, "util", BPY_util_module() ); + /* PyModule_AddObject( mod, "util", BPY_util_module() ); */ /* XXX this will move to bpy.util */ PyModule_AddObject( mod, "sys", BPY_sys_module() ); diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index dc3132814b4..89a68ba576c 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -488,126 +488,3 @@ int BPy_errors_to_report(ReportList *reports) Py_DECREF(pystring); return 1; } - - -/* bpy.util module */ -static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args); - -struct PyMethodDef bpy_util_methods[] = { - {"copy_images", bpy_util_copy_images, METH_VARARGS, NULL}, - {NULL, NULL, 0, NULL} -}; - -#if PY_VERSION_HEX >= 0x03000000 -static struct PyModuleDef bpy_util_module = { - PyModuleDef_HEAD_INIT, - "bpyutil", - NULL, - -1, - bpy_util_methods, - NULL, NULL, NULL, NULL -}; -#endif - -PyObject *BPY_util_module( void ) -{ - PyObject *submodule, *dict; - -#if PY_VERSION_HEX >= 0x03000000 - submodule= PyModule_Create(&bpy_util_module); -#else /* Py2.x */ - submodule= Py_InitModule3("bpyutil", bpy_util_methods, NULL); -#endif - - dict = PyModule_GetDict(submodule); - - return submodule; -} - -/* - copy_images(images, dest_dir) - return filenames -*/ -static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args) -{ - const char *dest_dir; - ListBase *images; - ListBase *paths; - LinkData *link; - PyObject *seq; - PyObject *ret; - PyObject *item; - int i; - int len; - - /* check args/types */ - if (!PyArg_ParseTuple(args, "Os", &seq, &dest_dir)) { - PyErr_SetString(PyExc_TypeError, "Invalid arguments."); - return NULL; - } - - /* expecting a sequence of Image objects */ - if (!PySequence_Check(seq)) { - PyErr_SetString(PyExc_TypeError, "Expected a sequence of images."); - return NULL; - } - - /* create image list */ - len= PySequence_Size(seq); - - if (!len) { - PyErr_SetString(PyExc_TypeError, "At least one image should be specified."); - return NULL; - } - - /* make sure all sequence items are Image */ - for(i= 0; i < len; i++) { - item= PySequence_GetItem(seq, i); - - if (!BPy_StructRNA_Check(item) || ((BPy_StructRNA*)item)->ptr.type != &RNA_Image) { - PyErr_SetString(PyExc_TypeError, "Expected a sequence of Image objects."); - return NULL; - } - } - - images= MEM_callocN(sizeof(*images), "ListBase of images"); - - for(i= 0; i < len; i++) { - BPy_StructRNA* srna; - - item= PySequence_GetItem(seq, i); - srna= (BPy_StructRNA*)item; - - link= MEM_callocN(sizeof(LinkData), "LinkData image"); - link->data= srna->ptr.data; - BLI_addtail(images, link); - - Py_DECREF(item); - } - - paths= MEM_callocN(sizeof(*paths), "ListBase of image paths"); - - /* call BKE_copy_images */ - BKE_copy_images(images, dest_dir, paths); - - /* convert filenames */ - ret= PyList_New(0); - - for(link= paths->first; link; link= link->next) { - if (link->data) { - item= PyUnicode_FromString(link->data); - PyList_Append(ret, item); - Py_DECREF(item); - } - else { - PyList_Append(ret, Py_None); - } - } - - /* free memory */ - BLI_freelistN(images); - BLI_freelistN(paths); - - /* return filenames */ - return ret; -} diff --git a/source/creator/SConscript b/source/creator/SConscript index 75e7494ebb5..82059c846e6 100644 --- a/source/creator/SConscript +++ b/source/creator/SConscript @@ -1,7 +1,10 @@ #!/usr/bin/python Import ('env') -sources = 'creator.c' +sources = ['creator.c'] + +if env['WITH_BF_UNIT_TEST']: + sources += env.Glob('tests/*.c') incs = '#/intern/guardedalloc ../blender/blenlib ../blender/blenkernel' incs += ' ../blender/editors/include ../blender/blenloader ../blender/imbuf' @@ -11,6 +14,10 @@ incs += ' ../kernel/gen_system #/extern/glew/include ../blender/gpu' incs += ' ' + env['BF_OPENGL_INC'] defs = [] + +if env['WITH_BF_UNIT_TEST']: + defs.append('WITH_UNIT_TEST') + if env['WITH_BF_QUICKTIME']: incs += ' ' + env['BF_QUICKTIME_INC'] defs.append('WITH_QUICKTIME') @@ -32,4 +39,4 @@ if env['WITH_BF_PYTHON']: else: defs.append('DISABLE_PYTHON') -env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 ) +env.BlenderLib ( libname = 'bf_creator', sources = sources, includes = Split(incs), defines = defs, libtype='core', priority = 0 ) diff --git a/source/creator/creator.c b/source/creator/creator.c index 8e0152b5e63..3a2a0ff32bc 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -338,6 +338,12 @@ int main(int argc, char **argv) exit(0); } +#ifdef WITH_UNIT_TEST + if (!strcmp(argv[a], "--test")) { + exit(run_tests()); + } +#endif + /* end argument processing after -- */ if (!strcmp( argv[a], "--")){ a = argc; diff --git a/source/creator/tests/alltest.c b/source/creator/tests/alltest.c new file mode 100644 index 00000000000..2173ecd224f --- /dev/null +++ b/source/creator/tests/alltest.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_blender.h" +#include "BKE_image.h" +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BLI_listbase.h" + +#include "DNA_image_types.h" + +char bprogname[FILE_MAXDIR+FILE_MAXFILE]; +char btempdir[FILE_MAXDIR+FILE_MAXFILE]; + +typedef struct ImageTestData { + char *path; /* image filename */ + char *expect_path; /* file path that we expect */ + int type; /* image type */ + int ret; /* expected function return value */ +} ImageTestData; + +/* check that BKE_copy_images manipulates paths correctly */ +START_TEST(test_copy_images) +{ + char *dest_dir[] = {"/tmp/", "/tmp", NULL}; + char **dir; + ImageTestData *test; + + /* XXX Windows not tested */ +#ifdef WIN32 + static ImageTestData test_data[] = { + {"//bar/image.png", "C:\\Temp\\bar\\image.png"}, + /* TODO add more */ + {NULL, NULL}, + }; + + BLI_strncpy(G.sce, "C:\\Temp\untitled.blend", sizeof(G.sce)); +#else + /* + XXX are these paths possible in image->name?: + + ./foo/image.png + ../foo/image.png + + if so, BKE_copy_images currently doesn't support them! + */ + static ImageTestData test_data[] = { + {"//bar/image.png", "/tmp/bar/image.png", IMA_TYPE_IMAGE, 1}, + {"/foo/bar/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, + {"//image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, + {"//../../../foo/bar/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, + {"//./foo/bar/image.png", "/tmp/foo/bar/image.png", IMA_TYPE_IMAGE, 1}, + {"/tmp/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, + {"//textures/test/foo/bar/image.png", "/tmp/textures/test/foo/bar/image.png", IMA_TYPE_IMAGE, 1}, + {"//textures/test/foo/bar/image.png", "", IMA_TYPE_MULTILAYER, 0}, + {"", "", IMA_TYPE_IMAGE, 0}, + {NULL, NULL}, + }; + + /* substitute G.sce */ + BLI_strncpy(G.sce, "/tmp/foo/bar/untitled.blend", sizeof(G.sce)); +#endif + + for (dir = dest_dir; *dir; dir++) { + for (test= &test_data[0]; test->path; test++) { + Image image; + char path[FILE_MAX]; + int ret; + + BLI_strncpy(image.name, test->path, sizeof(image.name)); + image.type= test->type; + + ret= BKE_export_image(&image, *dest_dir, path, sizeof(path)); + + /* check if we got correct output */ + fail_if(ret != test->ret, "For image with filename %s and type %d, expected %d as return value got %d.", + test->path, test->type, test->ret, ret); + fail_if(strcmp(path, test->expect_path), "For image with filename %s and type %d, expected path '%s' got '%s'.", + test->path, test->type, test->expect_path, path); + } + } +} +END_TEST + +static Suite *image_suite(void) +{ + Suite *s = suite_create("Image"); + + /* Core test case */ + TCase *tc_core = tcase_create("Core"); + tcase_add_test(tc_core, test_copy_images); + suite_add_tcase(s, tc_core); + + return s; +} + +int run_tests() +{ + int totfail; + Suite *s = image_suite(); + SRunner *sr = srunner_create(s); + + /* run tests */ + srunner_run_all(sr, CK_VERBOSE); + + totfail= srunner_ntests_failed(sr); + srunner_free(sr); + + return !totfail ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tools/Blender.py b/tools/Blender.py index 8d213166a4b..c3ba9b2e76d 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -161,6 +161,8 @@ def setup_syslibs(lenv): ] syslibs += Split(lenv['BF_FREETYPE_LIB']) + if lenv['WITH_BF_UNIT_TEST']: + syslibs.append(lenv['BF_CHECK_LIB']) if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']: if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'): syslibs.append(lenv['BF_PYTHON_LIB']+'_d') diff --git a/tools/btools.py b/tools/btools.py index f4d79b1bb24..521596eca97 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -66,7 +66,8 @@ def validate_arguments(args, bc): 'BF_NUMJOBS', 'BF_MSVS', - 'WITH_BF_UNIT_TEST' + 'WITH_BF_UNIT_TEST', + 'BF_CHECK_LIB', ] # Have options here that scons expects to be lists @@ -360,7 +361,8 @@ def read_opts(cfg, args): ('BF_NUMJOBS', 'Number of build processes to spawn', '1'), ('BF_MSVS', 'Generate MSVS project files and solution', False), - (BoolVariable('WITH_BF_UNIT_TEST', 'Build unit tests', False)) + (BoolVariable('WITH_BF_UNIT_TEST', 'Build unit tests', False)), + ('BF_CHECK_LIB', 'Check unit testing framework library', 'check'), ) # end of opts.AddOptions() -- cgit v1.2.3 From d8f4ab2d599956fa4511d4cb8a6b68e613cf239f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 23 Jul 2009 15:57:30 +0000 Subject: API: - freeing strings returned by RNA struct functions in RNA_parameter_list_free Unit tests: - check that BKE_export_image actually creates a file. This test is becoming dangerous: it creates and deletes files under /tmp. Having written this complicated test function I now realize it's much easier to write tests in a scripted language, which gives more freedom in expressions and need not be compiled. --- release/io/export_fbx.py | 56 ++++++++++------- source/blender/blenkernel/intern/image.c | 23 ++++--- source/blender/makesrna/intern/rna_access.c | 9 ++- source/blender/python/intern/bpy_rna.c | 3 +- source/creator/tests/alltest.c | 93 ++++++++++++++++++++++++----- 5 files changed, 129 insertions(+), 55 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index f98cefb076e..b7caf2b24dc 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -237,24 +237,24 @@ def sane_texname(data): return sane_name(data, sane_name_mapping_tex) def sane_takename(data): return sane_name(data, sane_name_mapping_take) def sane_groupname(data): return sane_name(data, sane_name_mapping_group) -def derived_paths(fname_orig, basepath, FORCE_CWD=False): - ''' - fname_orig - blender path, can be relative - basepath - fname_rel will be relative to this - FORCE_CWD - dont use the basepath, just add a ./ to the filename. - use when we know the file will be in the basepath. - ''' - fname = bpy.sys.expandpath(fname_orig) -# fname = Blender.sys.expandpath(fname_orig) - fname_strip = os.path.basename(fname) -# fname_strip = strip_path(fname) - if FORCE_CWD: - fname_rel = '.' + os.sep + fname_strip - else: - fname_rel = bpy.sys.relpath(fname, basepath) -# fname_rel = Blender.sys.relpath(fname, basepath) - if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:] - return fname, fname_strip, fname_rel +# def derived_paths(fname_orig, basepath, FORCE_CWD=False): +# ''' +# fname_orig - blender path, can be relative +# basepath - fname_rel will be relative to this +# FORCE_CWD - dont use the basepath, just add a ./ to the filename. +# use when we know the file will be in the basepath. +# ''' +# fname = bpy.sys.expandpath(fname_orig) +# # fname = Blender.sys.expandpath(fname_orig) +# fname_strip = os.path.basename(fname) +# # fname_strip = strip_path(fname) +# if FORCE_CWD: +# fname_rel = '.' + os.sep + fname_strip +# else: +# fname_rel = bpy.sys.relpath(fname, basepath) +# # fname_rel = Blender.sys.relpath(fname, basepath) +# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:] +# return fname, fname_strip, fname_rel def mat4x4str(mat): @@ -1324,6 +1324,8 @@ def write(filename, batch_objects = None, \ # tex is an Image (Arystan) def write_video(texname, tex): + if not EXP_IMAGE_COPY: return + # Same as texture really! file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) @@ -1335,7 +1337,10 @@ def write(filename, batch_objects = None, \ Property: "Width", "int", "",0 Property: "Height", "int", "",0''') if tex: - fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) + abspath = tex.export(basepath) + fname_rel = os.path.relpath(abspath, basepath) + fname_strip = os.path.basename(abspath) +# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: fname = fname_strip = fname_rel = '' @@ -1361,6 +1366,8 @@ def write(filename, batch_objects = None, \ def write_texture(texname, tex, num): + if not EXP_IMAGE_COPY: return + # if tex == None then this is a dummy tex file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname) file.write('\n\t\tType: "TextureVideoClip"') @@ -1399,7 +1406,10 @@ def write(filename, batch_objects = None, \ file.write('\n\t\tMedia: "Video::%s"' % texname) if tex: - fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) + abspath = tex.export(basepath) + fname_rel = os.path.relpath(abspath, basepath) + fname_strip = os.path.basename(abspath) +# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: fname = fname_strip = fname_rel = '' @@ -3074,9 +3084,9 @@ Takes: {''') # copy images if enabled - if EXP_IMAGE_COPY: -# copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) - bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath) +# if EXP_IMAGE_COPY: +# # copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) +# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath) print('export finished in %.4f sec.' % (bpy.sys.time() - start_time)) # print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index a469752602e..f0b29f766ec 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2160,14 +2160,11 @@ int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_pa /* expand "//" in filename and get absolute path */ BLI_convertstringcode(path, G.sce); - /* in unit tests, we don't want to modify the filesystem */ -#ifndef WITH_UNIT_TEST /* proceed only if image file exists */ if (!BLI_exists(path)) { if (G.f & G_DEBUG) printf("%s doesn't exist\n", path); - goto next; + return 0; } -#endif /* get the directory part */ BLI_split_dirfile_basic(path, dir, base); @@ -2191,10 +2188,8 @@ int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_pa BLI_join_dirfile(dest_path, dest_dir, rel); -#ifndef WITH_UNIT_TEST /* build identical directory structure under dest_dir */ - BLI_make_existing_file(dest_path); -#endif + BLI_recurdir_fileops(dest_path); BLI_join_dirfile(dest_path, dest_path, base); } @@ -2206,14 +2201,18 @@ int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_pa BLI_join_dirfile(dest_path, dest_dir, base); } -#ifndef WITH_UNIT_TEST if (G.f & G_DEBUG) printf("copying %s to %s\n", path, dest_path); - if (BLI_copy_fileops(path, dest_path) != 0) { - if (G.f & G_DEBUG) printf("couldn't copy %s to %s\n", path, dest_path); - return 0; + /* only copy if paths differ */ + if (strcmp(path, dest_path)) { + if (BLI_copy_fileops(path, dest_path) != 0) { + if (G.f & G_DEBUG) printf("couldn't copy %s to %s\n", path, dest_path); + return 0; + } + } + else if (G.f & G_DEBUG){ + printf("%s and %s are the same file\n", path, dest_path); } -#endif BLI_strncpy(out_path, dest_path, out_path_len); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 9c133605f96..c9bf97fd274 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2820,9 +2820,12 @@ void RNA_parameter_list_free(ParameterList *parms) if(parm->type == PROP_COLLECTION) { BLI_freelistN((ListBase*)((char*)parms->data+tot)); } - else if(parm->flag & PROP_DYNAMIC_ARRAY) { - /* for dynamic arrays, data is a pointer to an array */ - MEM_freeN(*(char**)parms->data+tot); + else if(parm == parms->func->ret) { + /* for dynamic arrays and strings, data is a pointer to an array */ + char *ptr= *(char**)((char*)parms->data+tot); + if((parm->flag & PROP_DYNAMIC_ARRAY || parm->type == PROP_STRING) && ptr) { + MEM_freeN(ptr); + } } tot+= rna_parameter_size(parm); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index c7767c6c08e..780c58e2877 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1844,7 +1844,8 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) break; case PROP_STRING: { - ret = PyUnicode_FromString( *(char**)data ); + char *ptr = *(char**)data; + ret = ptr ? PyUnicode_FromString( ptr ) : Py_None; break; } case PROP_ENUM: diff --git a/source/creator/tests/alltest.c b/source/creator/tests/alltest.c index 2173ecd224f..8bb2b1a9bb0 100644 --- a/source/creator/tests/alltest.c +++ b/source/creator/tests/alltest.c @@ -10,6 +10,9 @@ #include "BKE_global.h" #include "BLI_listbase.h" +#include "BLI_util.h" +#include "BLI_fileops.h" +#include "BLI_string.h" #include "DNA_image_types.h" @@ -21,12 +24,31 @@ typedef struct ImageTestData { char *expect_path; /* file path that we expect */ int type; /* image type */ int ret; /* expected function return value */ + int create_file; /* whether the file should be created */ } ImageTestData; +/* recursively deletes a directory only if it is under /tmp */ +static void delete_only_tmp(char *path, int dir) { +#ifdef WIN32 +#else + if (!strncmp(path, "/tmp/", 5) && BLI_exists(path)) { + BLI_delete(path, dir, 1); + } +#endif +} + +static void touch_only_tmp(char *path) { +#ifdef WIN32 +#else + if (!strncmp(path, "/tmp/", 5)) { + BLI_touch(path); + } +#endif +} + /* check that BKE_copy_images manipulates paths correctly */ START_TEST(test_copy_images) { - char *dest_dir[] = {"/tmp/", "/tmp", NULL}; char **dir; ImageTestData *test; @@ -49,38 +71,77 @@ START_TEST(test_copy_images) if so, BKE_copy_images currently doesn't support them! */ static ImageTestData test_data[] = { - {"//bar/image.png", "/tmp/bar/image.png", IMA_TYPE_IMAGE, 1}, - {"/foo/bar/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, - {"//image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, - {"//../../../foo/bar/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, - {"//./foo/bar/image.png", "/tmp/foo/bar/image.png", IMA_TYPE_IMAGE, 1}, - {"/tmp/image.png", "/tmp/image.png", IMA_TYPE_IMAGE, 1}, - {"//textures/test/foo/bar/image.png", "/tmp/textures/test/foo/bar/image.png", IMA_TYPE_IMAGE, 1}, - {"//textures/test/foo/bar/image.png", "", IMA_TYPE_MULTILAYER, 0}, - {"", "", IMA_TYPE_IMAGE, 0}, + {"//bar/image.png", "/tmp/blender/dest/bar/image.png", IMA_TYPE_IMAGE, 1, 1}, + {"//image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, + {"//textures/test/foo/bar/image.png", "/tmp/blender/dest/textures/test/foo/bar/image.png", IMA_TYPE_IMAGE, 1, 1}, + {"//textures/test/foo/bar/image.png", "", IMA_TYPE_MULTILAYER, 0, 1}, + {"//./foo/bar/image.png", "/tmp/blender/dest/foo/bar/image.png", IMA_TYPE_IMAGE, 1, 1}, + {"//../foo/bar/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, + {"/tmp/blender/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, + /* expecting it to return 1 when src and dest are the same file */ + {"/tmp/blender/foo/bar/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, + {"/tmp/blender/dest/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, + /* expecting empty path and 0 return value for non-existing files */ + {"/tmp/blender/src/file-not-created", "", IMA_TYPE_IMAGE, 0, 0}, + {"", "", IMA_TYPE_IMAGE, 0, 0}, {NULL, NULL}, }; + char *dest_dir[] = {"/tmp/blender/dest/", "/tmp/blender/dest", NULL}; + const char *blend_dir = "/tmp/blender/src"; + /* substitute G.sce */ - BLI_strncpy(G.sce, "/tmp/foo/bar/untitled.blend", sizeof(G.sce)); + BLI_snprintf(G.sce, sizeof(G.sce), "%s/untitled.blend", blend_dir); #endif + /* only delete files/directories under /tmp/ ! */ + delete_only_tmp(blend_dir, 1); + + for (dir = dest_dir; *dir; dir++) { + delete_only_tmp(*dir, 1); + } + + /* create files */ + BLI_recurdir_fileops(blend_dir); + + /* create fake empty source files */ + for (test= &test_data[0]; test->path; test++) { + char dir[FILE_MAX]; + char path[FILE_MAX]; + + if (!test->create_file) continue; + + /* expand "//" */ + BLI_strncpy(path, test->path, sizeof(path)); + BLI_convertstringcode(path, G.sce); + + /* create a directory */ + BLI_split_dirfile_basic(path, dir, NULL); + BLI_recurdir_fileops(dir); + + /* create a file */ + touch_only_tmp(path); + } + for (dir = dest_dir; *dir; dir++) { for (test= &test_data[0]; test->path; test++) { Image image; char path[FILE_MAX]; + char part[200]; int ret; BLI_strncpy(image.name, test->path, sizeof(image.name)); image.type= test->type; - ret= BKE_export_image(&image, *dest_dir, path, sizeof(path)); + ret= BKE_export_image(&image, *dir, path, sizeof(path)); /* check if we got correct output */ - fail_if(ret != test->ret, "For image with filename %s and type %d, expected %d as return value got %d.", - test->path, test->type, test->ret, ret); - fail_if(strcmp(path, test->expect_path), "For image with filename %s and type %d, expected path '%s' got '%s'.", - test->path, test->type, test->expect_path, path); + BLI_snprintf(part, sizeof(part), "For image with filename %s and type %d", test->path, test->type); + fail_if(ret != test->ret, "%s, expected %d as return value got %d.", part, test->ret, ret); + fail_if(strcmp(path, test->expect_path), "%s, expected path %s got \"%s\".", part, test->expect_path, path); + if (test->ret == ret && ret == 1) { + fail_if(!BLI_exists(test->expect_path), "%s, expected %s to be created.", part, test->expect_path); + } } } } -- cgit v1.2.3 From d63d703842f62916f6242ac7c9331edd4943dc5e Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 24 Jul 2009 14:26:47 +0000 Subject: - added operator for OBJ importer plus some python 3 conversions --- release/io/export_obj.py | 9 +- release/io/import_obj.py | 144 ++++++++++++++++++++++-------- source/blender/makesrna/intern/rna_pose.c | 7 +- 3 files changed, 112 insertions(+), 48 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index bf3aa4ae819..4d67903c343 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -200,19 +200,16 @@ def copy_images(dest_dir): # XXX not converted def test_nurbs_compat(ob): - if ob.type != 'CURVE': + if ob.type != 'Curve': return False - for nu in ob.data.curves: + for nu in ob.data: if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier return True - -# for nu in ob.data: -# if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier -# return True return False + # XXX not converted def write_nurb(file, ob, ob_mat): tot_verts = 0 diff --git a/release/io/import_obj.py b/release/io/import_obj.py index 659d5207261..a4778ac7790 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -57,7 +57,8 @@ def stripFile(path): lastSlash= max(path.rfind('\\'), path.rfind('/')) if lastSlash != -1: path= path[:lastSlash] - return '%s%s' % (path, sys.sep) + return '%s%s' % (path, os.sep) +# return '%s%s' % (path, sys.sep) def stripPath(path): '''Strips the slashes from the back of a string''' @@ -219,8 +220,9 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ # Add an MTL with the same name as the obj if no MTLs are spesified. temp_mtl= stripExt(stripPath(filepath))+ '.mtl' - - if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: + + if os.path.exists(DIR + temp_mtl) and temp_mtl not in material_libs: +# if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: material_libs.append( temp_mtl ) del temp_mtl @@ -236,7 +238,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ for libname in material_libs: mtlpath= DIR + libname - if not bpy.sys.exists(mtlpath): + if not os.path.exists(mtlpath): # if not sys.exists(mtlpath): #print '\tError Missing MTL: "%s"' % mtlpath pass @@ -247,7 +249,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ for line in mtl: #.xreadlines(): if line.startswith('newmtl'): context_material_name= line_value(line.split()) - if unique_materials.has_key(context_material_name): + if context_material_name in unique_materials: context_material = unique_materials[ context_material_name ] else: context_material = None @@ -377,14 +379,14 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index matname= face[2] - if matname and not unique_materials_split.has_key(matname): + if matname and matname not in unique_materials_split: unique_materials_split[matname] = unique_materials[matname] faces_split.append(face) # remove one of the itemas and reorder - return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.iteritems()] + return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.items()] def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): @@ -397,7 +399,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l if unique_smooth_groups: sharp_edges= {} - smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.iterkeys() ]) + smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.keys() ]) context_smooth_group_old= -1 # Split fgons into tri's @@ -408,7 +410,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l context_object= None # reverse loop through face indicies - for f_idx in xrange(len(faces)-1, -1, -1): + for f_idx in range(len(faces)-1, -1, -1): face_vert_loc_indicies,\ face_vert_tex_indicies,\ @@ -425,7 +427,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l if CREATE_EDGES: # generators are better in python 2.4+ but can't be used in 2.3 # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) ) - edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] ) + edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in range(len_face_vert_loc_indicies-1)] ) faces.pop(f_idx) else: @@ -437,7 +439,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l edge_dict= smooth_group_users[context_smooth_group] context_smooth_group_old= context_smooth_group - for i in xrange(len_face_vert_loc_indicies): + for i in range(len_face_vert_loc_indicies): i1= face_vert_loc_indicies[i] i2= face_vert_loc_indicies[i-1] if i1>i2: i1,i2= i2,i1 @@ -485,8 +487,8 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l # Build sharp edges if unique_smooth_groups: - for edge_dict in smooth_group_users.itervalues(): - for key, users in edge_dict.iteritems(): + for edge_dict in smooth_group_users.values(): + for key, users in edge_dict.items(): if users==1: # This edge is on the boundry of a group sharp_edges[key]= None @@ -496,7 +498,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l materials= [None] * len(unique_materials) - for name, index in material_mapping.iteritems(): + for name, index in material_mapping.items(): materials[index]= unique_materials[name] me= bpy.data.add_mesh(dataname) @@ -639,7 +641,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l # Create the vertex groups. No need to have the flag passed here since we test for the # content of the vertex_groups. If the user selects to NOT have vertex groups saved then # the following test will never run - for group_name, group_indicies in vertex_groups.iteritems(): + for group_name, group_indicies in vertex_groups.items(): group= ob.add_vertex_group(group_name) # me.addVertGroup(group_name) for vertex_index in group_indicies: @@ -660,16 +662,16 @@ def create_nurbs(scn, context_nurbs, vert_loc, new_objects): cstype = context_nurbs.get('cstype', None) if cstype == None: - print '\tWarning, cstype not found' + print('\tWarning, cstype not found') return if cstype != 'bspline': - print '\tWarning, cstype is not supported (only bspline)' + print('\tWarning, cstype is not supported (only bspline)') return if not curv_idx: - print '\tWarning, curv argument empty or not set' + print('\tWarning, curv argument empty or not set') return if len(deg) > 1 or parm_v: - print '\tWarning, surfaces not supported' + print('\tWarning, surfaces not supported') return cu = bpy.data.curves.new(name, 'Curve') @@ -691,7 +693,7 @@ def create_nurbs(scn, context_nurbs, vert_loc, new_objects): # get for endpoint flag from the weighting if curv_range and len(parm_u) > deg[0]+1: do_endpoints = True - for i in xrange(deg[0]+1): + for i in range(deg[0]+1): if abs(parm_u[i]-curv_range[0]) > 0.0001: do_endpoints = False @@ -773,7 +775,7 @@ def load_obj(filepath, This function passes the file and sends the data off to be split into objects and then converted into mesh objects ''' - print '\nimporting obj "%s"' % filepath + print('\nimporting obj "%s"' % filepath) if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: POLYGROUPS = False @@ -816,7 +818,7 @@ def load_obj(filepath, # so we need to know weather context_multi_line= '' - print '\tparsing obj file "%s"...' % filepath, + print('\tparsing obj file "%s"...' % filepath, end=' ') time_sub= bpy.sys.time() # time_sub= sys.time() @@ -1028,31 +1030,31 @@ def load_obj(filepath, file.close() time_new= bpy.sys.time() # time_new= sys.time() - print '%.4f sec' % (time_new-time_sub) + print('%.4f sec' % (time_new-time_sub)) time_sub= time_new - print '\tloading materials and images...', + print('\tloading materials and images...', end=' ') create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) time_new= bpy.sys.time() # time_new= sys.time() - print '%.4f sec' % (time_new-time_sub) + print('%.4f sec' % (time_new-time_sub)) time_sub= time_new if not ROTATE_X90: verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] # deselect all - if context.selected_objects: - bpy.ops.OBJECT_OT_select_all_toggle() +# if context.selected_objects: +# bpy.ops.OBJECT_OT_select_all_toggle() scene = context.scene # scn = bpy.data.scenes.active # scn.objects.selected = [] new_objects= [] # put new objects here - print '\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), + print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), end=' ') # Split the mesh by objects/materials, may if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True else: SPLIT_OB_OR_GROUP = False @@ -1095,8 +1097,8 @@ def load_obj(filepath, time_new= bpy.sys.time() # time_new= sys.time() - print '%.4f sec' % (time_new-time_sub) - print 'finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)) + print('%.4f sec' % (time_new-time_sub)) + print('finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main))) DEBUG= True @@ -1189,14 +1191,14 @@ def load_obj_ui(filepath, BATCH_LOAD= False): def do_help(e,v): url = __url__[0] - print 'Trying to open web browser with documentation at this address...' - print '\t' + url + print('Trying to open web browser with documentation at this address...') + print('\t' + url) try: import webbrowser webbrowser.open(url) except: - print '...could not open a browser window.' + print('...could not open a browser window.') def obj_ui(): ui_x, ui_y = GLOBALS['MOUSE'] @@ -1306,11 +1308,11 @@ def load_obj_ui_batch(file): DEBUG= False -if __name__=='__main__' and not DEBUG: - if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT: - Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '') - else: - Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') +# if __name__=='__main__' and not DEBUG: +# if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT: +# Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '') +# else: +# Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') # For testing compatibility ''' @@ -1340,6 +1342,70 @@ else: #load_obj('/test.obj') #load_obj('/fe/obj/mba1.obj') + + +class IMPORT_OT_obj(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "import.obj" + __label__ = "Import OBJ" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), + + bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True), + bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True), + bpy.props.BoolProperty(attr="CREATE_EDGES", name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True), + bpy.props.BoolProperty(attr="SPLIT_OBJECTS", name="Object", description="Import OBJ Objects into Blender Objects", default= True), + bpy.props.BoolProperty(attr="SPLIT_GROUPS", name="Group", description="Import OBJ Groups into Blender Objects", default= True), + bpy.props.BoolProperty(attr="SPLIT_MATERIALS", name="Material", description="Import each material into a seperate mesh (Avoids > 16 per mesh error)", default= True), + # old comment: only used for user feedback + # disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj + # bpy.props.BoolProperty(attr="KEEP_VERT_ORDER", name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True), + bpy.props.BoolProperty(attr="ROTATE_X90", name="-X90", description="Rotate X 90.", default= True), + bpy.props.FloatProperty(attr="CLAMP_SIZE", name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.01, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0), + bpy.props.BoolProperty(attr="POLYGROUPS", name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True), + bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True), + ] + + def poll(self, context): + print("Poll") + return context.active_object != None + + def execute(self, context): + # print("Selected: " + context.active_object.name) + + if not self.filename: + raise Exception("filename not set") + + load_obj(self.filename, + context, + self.CLAMP_SIZE, + self.CREATE_FGONS, + self.CREATE_SMOOTH_GROUPS, + self.CREATE_EDGES, + self.SPLIT_OBJECTS, + self.SPLIT_GROUPS, + self.SPLIT_MATERIALS, + self.ROTATE_X90, + self.IMAGE_SEARCH, + self.POLYGROUPS) + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + +bpy.ops.add(IMPORT_OT_obj) + + # NOTES (all line numbers refer to 2.4x import_obj.py, not this file) # check later: line 489 # can convert now: edge flags, edges: lines 508-528 @@ -1351,4 +1417,4 @@ else: # replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load) # bitmask won't work? - 132 # uses operator bpy.ops.OBJECT_OT_select_all_toggle() to deselect all (not necessary?) -# uses bpy.sys.exists and bpy.sys.time() +# uses bpy.sys.time() diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index c6f4f430983..ce803aae78a 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -332,10 +332,11 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); /* These three matrix properties await an implementation of the PROP_MATRIX subtype, which currently doesn't exist. */ -/* prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX); - RNA_def_property_struct_type(prop, "chan_mat"); + prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "chan_mat"); + RNA_def_property_array(prop, 16); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");*/ + RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints."); /* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */ prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX); -- cgit v1.2.3 From d1e42cc5f85a6665e85a388763696fd291b86db8 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 24 Jul 2009 15:27:59 +0000 Subject: Forgot to add rna_image_api.c. --- source/blender/makesrna/intern/rna_image_api.c | 73 ++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 source/blender/makesrna/intern/rna_image_api.c diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c new file mode 100644 index 00000000000..42ee2b64c7a --- /dev/null +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -0,0 +1,73 @@ +/** + * + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "DNA_object_types.h" + +#ifdef RNA_RUNTIME + +#include "BKE_utildefines.h" +#include "BKE_image.h" + +static char *rna_Image_export(Image *image, char *dest_dir) +{ + int length = FILE_MAX; + char *path= MEM_callocN(length, "image file path"); + + if (!BKE_export_image(image, dest_dir, path, length)) { + MEM_freeN(path); + return NULL; + } + + return path; +} + +#else + +void RNA_api_image(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "export", "rna_Image_export"); + RNA_def_function_ui_description(func, "Copy image file to a directory rebuilding subdirectory structure."); + parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "path", "", 0, "", "Absolute file path of copied image."); + RNA_def_function_return(func, parm); +} + +#endif + -- cgit v1.2.3 From bee82a360ef250b09f8af3216b1743334fb366b0 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 2 Aug 2009 11:32:03 +0000 Subject: Another quick-fix for background mode --- source/blender/windowmanager/intern/wm_init_exit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 599844f1020..41d35ca9be4 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -228,7 +228,10 @@ void WM_exit(bContext *C) fastshade_free_render(); /* shaded view */ ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */ - wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ + + if(C && CTX_wm_manager(C)) + wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ + free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); free_anim_copybuf(); -- cgit v1.2.3 From 84d86540ddd3ae6b0a23134db7c98bc59698b3cd Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 2 Aug 2009 12:11:14 +0000 Subject: changed to STL sort --- .../render/intern/raytrace/rayobject_rtbuild.cpp | 37 +++++++--------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 86a92417d03..b0ac54bef2c 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "rayobject_rtbuild.h" #include "MEM_guardedalloc.h" @@ -198,34 +199,20 @@ struct CostObject float bb[6]; }; -//Ugly.. but using qsort and no globals its the cleaner I can get -#define costobject_cmp(axis) costobject_cmp##axis -#define define_costobject_cmp(axis) \ -int costobject_cmp(axis)(const CostObject *a, const CostObject *b) \ -{ \ - if(a->bb[axis] < b->bb[axis]) return -1; \ - if(a->bb[axis] > b->bb[axis]) return 1; \ - if(a->obj < b->obj) return -1; \ - if(a->obj > b->obj) return 1; \ - return 0; \ -} - -define_costobject_cmp(0) -define_costobject_cmp(1) -define_costobject_cmp(2) -define_costobject_cmp(3) -define_costobject_cmp(4) -define_costobject_cmp(5) +template +bool obj_bb_compare(const Obj &a, const Obj &b) +{ + if(a.bb[Axis] != b.bb[Axis]) + return a.bb[Axis] < b.bb[Axis]; + return a.obj < b.obj; +} void costobject_sort(CostObject *begin, CostObject *end, int axis) { - //TODO introsort - if(axis == 0) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(0)); - else if(axis == 1) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(1)); - else if(axis == 2) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(2)); - else if(axis == 3) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(3)); - else if(axis == 4) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(4)); - else if(axis == 5) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(5)); + if(axis == 0) return std::sort(begin, end, obj_bb_compare ); + if(axis == 1) return std::sort(begin, end, obj_bb_compare ); + if(axis == 2) return std::sort(begin, end, obj_bb_compare ); + assert(false); } -- cgit v1.2.3 From 4086ca58e275816a49950f6ac0cbffa6cb36a8ad Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 3 Aug 2009 12:02:40 +0000 Subject: - re-wrote image exporting function renaming it from BKE_export_image to BKE_get_image_export_path because now it doesn't copy files but only manipulates paths. It produces both ablsolute and relative paths. COLLADA exporter can now use it. - re-wrote unit test for it, this is now more compact and readable - RNA API Image.get_export_path takes a boolean arg to indicate whether a relative or absolute path should be returned. Python scripts can now use it. --- source/blender/blenkernel/BKE_image.h | 3 +- source/blender/blenkernel/intern/image.c | 77 +++++------ source/blender/makesrna/intern/rna_image_api.c | 12 +- source/creator/tests/alltest.c | 181 +++++++++++++------------ 4 files changed, 136 insertions(+), 137 deletions(-) diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 052f7738f2b..56c58cdc6bf 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -156,8 +156,7 @@ struct Image *BKE_image_copy(struct Image *ima); void BKE_image_merge(struct Image *dest, struct Image *source); /* copy image file to a directory rebuilding subdirectory structure */ -int BKE_export_image(struct Image *im, const char *dest_dir, char *out_path, int out_path_len); - +int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f0b29f766ec..276d79b7e32 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2117,41 +2117,51 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr) } /* - Copy an image to destination directory rebuilding subdirectory structure if needed. - Target image path is written to out_path. - Returns 1 on success, 0 otherwise. + Produce image export path. + + Fails returning 0 if image filename is empty or if destination path + matches image path (i.e. both are the same file). + + Trailing slash in dest_dir is optional. Logic: - - if an image is "below" current .blend file directory, rebuild the same dir structure in dest_dir + - if an image is "below" current .blend file directory, rebuild the + same dir structure in dest_dir - For example //textures/foo/bar.png becomes [dest_dir]/textures/foo/bar.png. + For example //textures/foo/bar.png becomes + [dest_dir]/textures/foo/bar.png. - - if an image is not "below" current .blend file directory, disregard it's path and copy it in the - same directory where 3D file goes. + - if an image is not "below" current .blend file directory, + disregard it's path and copy it in the same directory where 3D file + goes. For example //../foo/bar.png becomes [dest_dir]/bar.png. This logic will help ensure that all image paths are relative and that a user gets his images in one place. It'll also provide consistent behaviour across exporters. - */ -int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_path_len) +int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size) { char path[FILE_MAX]; char dir[FILE_MAX]; char base[FILE_MAX]; char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */ char dest_path[FILE_MAX]; + char rel_dir[FILE_MAX]; int len; - out_path[0]= 0; + if (abs) + abs[0]= 0; + + if (rel) + rel[0]= 0; BLI_split_dirfile_basic(G.sce, blend_dir, NULL); - if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE) { - if (G.f & G_DEBUG) printf("invalid image type\n"); + if (!strlen(im->name)) { + if (G.f & G_DEBUG) printf("Invalid image type.\n"); return 0; } @@ -2160,61 +2170,48 @@ int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_pa /* expand "//" in filename and get absolute path */ BLI_convertstringcode(path, G.sce); - /* proceed only if image file exists */ - if (!BLI_exists(path)) { - if (G.f & G_DEBUG) printf("%s doesn't exist\n", path); - return 0; - } - /* get the directory part */ BLI_split_dirfile_basic(path, dir, base); len= strlen(blend_dir); + rel_dir[0] = 0; + /* if image is "below" current .blend file directory */ if (!strncmp(path, blend_dir, len)) { /* if image is _in_ current .blend file directory */ if (!strcmp(dir, blend_dir)) { - /* copy to dest_dir */ BLI_join_dirfile(dest_path, dest_dir, base); } /* "below" */ else { - char rel[FILE_MAX]; - /* rel = image_path_dir - blend_dir */ - BLI_strncpy(rel, dir + len, sizeof(rel)); - - BLI_join_dirfile(dest_path, dest_dir, rel); - - /* build identical directory structure under dest_dir */ - BLI_recurdir_fileops(dest_path); + BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir)); + BLI_join_dirfile(dest_path, dest_dir, rel_dir); BLI_join_dirfile(dest_path, dest_path, base); } } /* image is out of current directory */ else { - /* copy to dest_dir */ BLI_join_dirfile(dest_path, dest_dir, base); } - if (G.f & G_DEBUG) printf("copying %s to %s\n", path, dest_path); - - /* only copy if paths differ */ - if (strcmp(path, dest_path)) { - if (BLI_copy_fileops(path, dest_path) != 0) { - if (G.f & G_DEBUG) printf("couldn't copy %s to %s\n", path, dest_path); - return 0; - } - } - else if (G.f & G_DEBUG){ - printf("%s and %s are the same file\n", path, dest_path); + /* only return 1 if paths differ */ + if (!strcmp(path, dest_path)) { + if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path); + return 0; } - BLI_strncpy(out_path, dest_path, out_path_len); + if (abs) + BLI_strncpy(abs, dest_path, abs_size); + + if (rel) { + strncat(rel, rel_dir, rel_size); + strncat(rel, base, rel_size); + } return 1; } diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 42ee2b64c7a..20770ef2957 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -41,12 +41,12 @@ #include "BKE_utildefines.h" #include "BKE_image.h" -static char *rna_Image_export(Image *image, char *dest_dir) +static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel) { int length = FILE_MAX; char *path= MEM_callocN(length, "image file path"); - if (!BKE_export_image(image, dest_dir, path, length)) { + if (!BKE_get_image_export_path(image, dest_dir, rel ? NULL : path, length, rel ? path : NULL, length )) { MEM_freeN(path); return NULL; } @@ -61,11 +61,13 @@ void RNA_api_image(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; - func= RNA_def_function(srna, "export", "rna_Image_export"); - RNA_def_function_ui_description(func, "Copy image file to a directory rebuilding subdirectory structure."); + func= RNA_def_function(srna, "export", "rna_Image_get_export_path"); + RNA_def_function_ui_description(func, "Produce image export path."); parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory."); RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "path", "", 0, "", "Absolute file path of copied image."); + parm= RNA_def_boolean(func, "get_rel_path", 1, "", "Return relative path if True."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path."); RNA_def_function_return(func, parm); } diff --git a/source/creator/tests/alltest.c b/source/creator/tests/alltest.c index 8bb2b1a9bb0..99e0d2f5b26 100644 --- a/source/creator/tests/alltest.c +++ b/source/creator/tests/alltest.c @@ -19,48 +19,26 @@ char bprogname[FILE_MAXDIR+FILE_MAXFILE]; char btempdir[FILE_MAXDIR+FILE_MAXFILE]; +typedef struct ImageTestResult { + char *path; + char *rel; + int ret; +} ImageTestResult; + typedef struct ImageTestData { char *path; /* image filename */ - char *expect_path; /* file path that we expect */ - int type; /* image type */ - int ret; /* expected function return value */ - int create_file; /* whether the file should be created */ + ImageTestResult result[10]; } ImageTestData; -/* recursively deletes a directory only if it is under /tmp */ -static void delete_only_tmp(char *path, int dir) { -#ifdef WIN32 -#else - if (!strncmp(path, "/tmp/", 5) && BLI_exists(path)) { - BLI_delete(path, dir, 1); - } -#endif -} - -static void touch_only_tmp(char *path) { -#ifdef WIN32 -#else - if (!strncmp(path, "/tmp/", 5)) { - BLI_touch(path); - } -#endif -} - /* check that BKE_copy_images manipulates paths correctly */ START_TEST(test_copy_images) { char **dir; ImageTestData *test; + int i,j; - /* XXX Windows not tested */ #ifdef WIN32 - static ImageTestData test_data[] = { - {"//bar/image.png", "C:\\Temp\\bar\\image.png"}, - /* TODO add more */ - {NULL, NULL}, - }; - - BLI_strncpy(G.sce, "C:\\Temp\untitled.blend", sizeof(G.sce)); + /* TBD... */ #else /* XXX are these paths possible in image->name?: @@ -70,77 +48,100 @@ START_TEST(test_copy_images) if so, BKE_copy_images currently doesn't support them! */ + + const char *blend_dir = "/home/user/foo"; + char *dest_dir[] = {"/home/user/", "/home/user", "/home/user/export/", "/home/user/foo/", NULL}; + static ImageTestData test_data[] = { - {"//bar/image.png", "/tmp/blender/dest/bar/image.png", IMA_TYPE_IMAGE, 1, 1}, - {"//image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, - {"//textures/test/foo/bar/image.png", "/tmp/blender/dest/textures/test/foo/bar/image.png", IMA_TYPE_IMAGE, 1, 1}, - {"//textures/test/foo/bar/image.png", "", IMA_TYPE_MULTILAYER, 0, 1}, - {"//./foo/bar/image.png", "/tmp/blender/dest/foo/bar/image.png", IMA_TYPE_IMAGE, 1, 1}, - {"//../foo/bar/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, - {"/tmp/blender/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, - /* expecting it to return 1 when src and dest are the same file */ - {"/tmp/blender/foo/bar/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, - {"/tmp/blender/dest/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1}, - /* expecting empty path and 0 return value for non-existing files */ - {"/tmp/blender/src/file-not-created", "", IMA_TYPE_IMAGE, 0, 0}, - {"", "", IMA_TYPE_IMAGE, 0, 0}, - {NULL, NULL}, - }; - char *dest_dir[] = {"/tmp/blender/dest/", "/tmp/blender/dest", NULL}; - const char *blend_dir = "/tmp/blender/src"; + /* image path | [expected output path | corresponding relative path | expected return value] */ + + /* relative, 0 level deep */ + {"//image.png", {{"/home/user/image.png", "image.png", 1}, + {"/home/user/image.png", "image.png", 1}, + {"/home/user/export/image.png", "image.png", 1}, + {"", "", 0},}}, + + /* relative, 1 level deep */ + {"//bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/export/bar/image.png", "bar/image.png", 1}, + {"", "", 0},}}, + + /* relative, 2 level deep */ + {"//bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, + {"", "", 0},}}, + + /* absolute, not under .blend dir */ + {"/home/user/bar/image.png", {{"/home/user/image.png", "image.png", 1}, + {"/home/user/image.png", "image.png", 1}, + {"/home/user/export/image.png", "image.png", 1}, + {"/home/user/foo/image.png", "image.png", 1},}}, + + /* absolute, under .blend dir, 0 level deep */ + {"/home/user/foo/image.png", {{"/home/user/image.png", "image.png", 1}, + {"/home/user/image.png", "image.png", 1}, + {"/home/user/export/image.png", "image.png", 1}, + {"", "", 0},}}, + + /* absolute, under .blend dir, 1 level deep */ + {"/home/user/foo/bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/export/bar/image.png", "bar/image.png", 1}, + {"", "", 0},}}, + + /* absolute, under .blend dir, 2 level deep */ + {"/home/user/foo/bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, + {"", "", 0},}}, + + /* empty image path, don't let these pass! */ + {"", {{"", 0}, + {"", 0}, + {"", 0}}}, + + {NULL}, + }; /* substitute G.sce */ BLI_snprintf(G.sce, sizeof(G.sce), "%s/untitled.blend", blend_dir); #endif - /* only delete files/directories under /tmp/ ! */ - delete_only_tmp(blend_dir, 1); - - for (dir = dest_dir; *dir; dir++) { - delete_only_tmp(*dir, 1); - } - - /* create files */ - BLI_recurdir_fileops(blend_dir); - - /* create fake empty source files */ - for (test= &test_data[0]; test->path; test++) { - char dir[FILE_MAX]; - char path[FILE_MAX]; - - if (!test->create_file) continue; - - /* expand "//" */ - BLI_strncpy(path, test->path, sizeof(path)); - BLI_convertstringcode(path, G.sce); - - /* create a directory */ - BLI_split_dirfile_basic(path, dir, NULL); - BLI_recurdir_fileops(dir); - - /* create a file */ - touch_only_tmp(path); - } - - for (dir = dest_dir; *dir; dir++) { + for (dir= dest_dir, i= 0; *dir; dir++, i++) { for (test= &test_data[0]; test->path; test++) { Image image; char path[FILE_MAX]; + char rel[FILE_MAX]; char part[200]; int ret; BLI_strncpy(image.name, test->path, sizeof(image.name)); - image.type= test->type; - ret= BKE_export_image(&image, *dir, path, sizeof(path)); + /* passing NULL as abs path or rel path or both shouldn't break it */ + int abs_rel_null[][2]= {{0, 0}, {1, 0}, {0, 1}, {1, 1}, {-1}}; + + for (j= 0; abs_rel_null[j][0] != -1; j++) { + + int *is_null= abs_rel_null[j]; + + ret= BKE_get_image_export_path(&image, *dir, + is_null[0] ? NULL : path, sizeof(path), + is_null[1] ? NULL : rel, sizeof(rel)); + + BLI_snprintf(part, sizeof(part), "For image at %s (output abs path is %s, rel path is %s)", + test->path, is_null[0] ? "NULL" : "non-NULL", is_null[1] ? "NULL" : "non-NULL"); + + /* we should get what we expect */ + ImageTestResult *res= &test->result[i]; + fail_if(ret != res->ret, "%s, expected to return %d got %d.", part, res->ret, ret); - /* check if we got correct output */ - BLI_snprintf(part, sizeof(part), "For image with filename %s and type %d", test->path, test->type); - fail_if(ret != test->ret, "%s, expected %d as return value got %d.", part, test->ret, ret); - fail_if(strcmp(path, test->expect_path), "%s, expected path %s got \"%s\".", part, test->expect_path, path); - if (test->ret == ret && ret == 1) { - fail_if(!BLI_exists(test->expect_path), "%s, expected %s to be created.", part, test->expect_path); + if (!is_null[0] && res->path) + fail_if(strcmp(path, res->path), "%s, expected absolute path \"%s\" got \"%s\".", part, res->path, path); + if (!is_null[1] && res->rel) + fail_if(strcmp(rel, res->rel), "%s, expected relative path \"%s\" got \"%s\".", part, res->rel, rel); } } } @@ -149,10 +150,10 @@ END_TEST static Suite *image_suite(void) { - Suite *s = suite_create("Image"); + Suite *s= suite_create("Image"); /* Core test case */ - TCase *tc_core = tcase_create("Core"); + TCase *tc_core= tcase_create("Core"); tcase_add_test(tc_core, test_copy_images); suite_add_tcase(s, tc_core); @@ -162,8 +163,8 @@ static Suite *image_suite(void) int run_tests() { int totfail; - Suite *s = image_suite(); - SRunner *sr = srunner_create(s); + Suite *s= image_suite(); + SRunner *sr= srunner_create(s); /* run tests */ srunner_run_all(sr, CK_VERBOSE); -- cgit v1.2.3 From 29530beb904b9944b5ba0453cb5b5e873701b3db Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 3 Aug 2009 17:56:38 +0000 Subject: NlogN building: sort once select subsets and kept the order (on X, Y and Z) --- .../render/intern/include/rayobject_rtbuild.h | 101 ----- .../render/intern/raytrace/rayobject_bih.cpp | 248 ++++++++++++ .../render/intern/raytrace/rayobject_bvh.cpp | 6 +- .../render/intern/raytrace/rayobject_rtbuild.cpp | 429 +++++++++------------ .../render/intern/raytrace/rayobject_rtbuild.h | 121 ++++++ .../render/intern/raytrace/rayobject_vbvh.cpp | 4 +- .../blender/render/intern/source/rayobject_bih.c | 253 ------------ 7 files changed, 558 insertions(+), 604 deletions(-) delete mode 100644 source/blender/render/intern/include/rayobject_rtbuild.h create mode 100644 source/blender/render/intern/raytrace/rayobject_bih.cpp create mode 100644 source/blender/render/intern/raytrace/rayobject_rtbuild.h delete mode 100644 source/blender/render/intern/source/rayobject_bih.c diff --git a/source/blender/render/intern/include/rayobject_rtbuild.h b/source/blender/render/intern/include/rayobject_rtbuild.h deleted file mode 100644 index ed8560d948a..00000000000 --- a/source/blender/render/intern/include/rayobject_rtbuild.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef RE_RAYOBJECT_RTBUILD_H -#define RE_RAYOBJECT_RTBUILD_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "rayobject.h" - - -/* - * Ray Tree Builder - * this structs helps building any type of tree - * it contains several methods to organiza/split nodes - * allowing to create a given tree on the fly. - * - * Idea is that other trees BVH, BIH can use this code to - * generate with simple calls, and then convert to the theirs - * specific structure on the fly. - */ -#define RTBUILD_MAX_CHILDS 32 -typedef struct RTBuilder -{ - /* list to all primitives in this tree */ - RayObject **begin, **end; - - /* axis used (if any) on the split method */ - int split_axis; - - /* child partitions calculated during splitting */ - int child_offset[RTBUILD_MAX_CHILDS+1]; - - int child_sorted_axis; /* -1 if not sorted */ - - float bb[6]; - -} RTBuilder; - -/* used during creation */ -RTBuilder* rtbuild_create(int size); -void rtbuild_free(RTBuilder *b); -void rtbuild_add(RTBuilder *b, RayObject *o); -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); -int rtbuild_size(RTBuilder *b); - -/* used during tree reorganization */ -RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); - -/* Calculates child partitions and returns number of efectively needed partitions */ -int rtbuild_get_largest_axis(RTBuilder *b); - -//Object partition -int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); -int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); - -int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds); - -//Space partition -int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis); -int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); - - -/* bb utils */ -float bb_area(float *min, float *max); -float bb_volume(float *min, float *max); -int bb_largest_axis(float *min, float *max); -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max); /* only returns 0 if merging inner and outerbox would create a box larger than outer box */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/blender/render/intern/raytrace/rayobject_bih.cpp b/source/blender/render/intern/raytrace/rayobject_bih.cpp new file mode 100644 index 00000000000..102a347b470 --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_bih.cpp @@ -0,0 +1,248 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include +#include + +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "RE_raytrace.h" +#include "rayobject_rtbuild.h" +#include "rayobject.h" + +#define BIH_NCHILDS 4 +typedef struct BIHTree BIHTree; + +static int bih_intersect(BIHTree *obj, Isect *isec); +static void bih_add(BIHTree *o, RayObject *ob); +static void bih_done(BIHTree *o); +static void bih_free(BIHTree *o); +static void bih_bb(BIHTree *o, float *min, float *max); + +static RayObjectAPI bih_api = +{ + (RE_rayobject_raycast_callback) bih_intersect, + (RE_rayobject_add_callback) bih_add, + (RE_rayobject_done_callback) bih_done, + (RE_rayobject_free_callback) bih_free, + (RE_rayobject_merge_bb_callback)bih_bb +}; + +typedef struct BIHNode BIHNode; +struct BIHNode +{ + BIHNode *child[BIH_NCHILDS]; + float bi[BIH_NCHILDS][2]; + int split_axis; +}; + +struct BIHTree +{ + RayObject rayobj; + + BIHNode *root; + + BIHNode *node_alloc, *node_next; + RTBuilder *builder; + + float bb[2][3]; +}; + + +RayObject *RE_rayobject_bih_create(int size) +{ + BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree"); + assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = &bih_api; + obj->root = NULL; + + obj->node_alloc = obj->node_next = NULL; + obj->builder = rtbuild_create( size ); + + return RayObject_unalignRayAPI((RayObject*) obj); +} + +static void bih_free(BIHTree *obj) +{ + if(obj->builder) + rtbuild_free(obj->builder); + + if(obj->node_alloc) + MEM_freeN(obj->node_alloc); + + MEM_freeN(obj); +} + +static void bih_bb(BIHTree *obj, float *min, float *max) +{ + DO_MIN(obj->bb[0], min); + DO_MAX(obj->bb[1], max); +} + +/* + * Tree transverse + */ +static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float tmax) +{ + int i; + int hit = 0; + + const int *const offset = isec->bv_index + node->split_axis*2; + + //TODO diving heuristic + for(i=0; ibi[i][offset[0]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; + float t2 = (node->bi[i][offset[1]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; + + if(t1 < tmin) t1 = tmin; //t1 = MAX2(t1, tmin); + if(t2 > tmax) t2 = tmax; //t2 = MIN2(t2, tmax); + + if(t1 <= t2) + { + if(RayObject_isAligned(node->child[i])) + { + if(node->child[i] == 0) break; + + hit |= dfs_raycast(node->child[i], isec, t1, t2); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + + if(tmax > isec->labda) + tmax = isec->labda; + } + } + + return hit; +} + +static int bih_intersect(BIHTree *obj, Isect *isec) +{ + if(RayObject_isAligned(obj->root)) + return dfs_raycast(obj->root, isec, 0, isec->labda); + else + return RE_rayobject_intersect( (RayObject*)obj->root, isec); +} + + +/* + * Builds a BIH tree from builder object + */ +static void bih_add(BIHTree *obj, RayObject *ob) +{ + rtbuild_add( obj->builder, ob ); +} + +static BIHNode *bih_new_node(BIHTree *tree, int nid) +{ + BIHNode *node = tree->node_alloc + nid - 1; + assert(RayObject_isAligned(node)); + if(node+1 > tree->node_next) + tree->node_next = node+1; + + return node; +} + +static int child_id(int pid, int nchild) +{ + //N child of node A = A * K + (2 - K) + N, (0 <= N < K) + return pid*BIH_NCHILDS+(2-BIH_NCHILDS)+nchild; +} + +static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float *bb) +{ + if(rtbuild_size(builder) == 1) + { + RayObject *child = rtbuild_get_primitive( builder, 0 ); + assert(!RayObject_isAligned(child)); + + INIT_MINMAX(bb, bb+3); + RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3); + + return (BIHNode*)child; + } + else + { + int i; + int nc = rtbuild_mean_split_largest_axis(builder, BIH_NCHILDS); + RTBuilder tmp; + + BIHNode *parent = bih_new_node(tree, nid); + + INIT_MINMAX(bb, bb+3); + parent->split_axis = builder->split_axis; + for(i=0; ichild[i] = bih_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), cbb ); + + parent->bi[i][0] = cbb[parent->split_axis]; + parent->bi[i][1] = cbb[parent->split_axis+3]; + + DO_MIN(cbb , bb); + DO_MAX(cbb+3, bb+3); + } + for(; ibi[i][0] = 1.0; + parent->bi[i][1] = -1.0; + parent->child[i] = 0; + } + + return parent; + } +} + +static void bih_done(BIHTree *obj) +{ + int needed_nodes; + assert(obj->root == NULL && obj->node_alloc == NULL && obj->builder); + + //TODO exact calculate needed nodes + needed_nodes = (rtbuild_size(obj->builder)+1)*2; + assert(needed_nodes > 0); + + obj->node_alloc = (BIHNode*)MEM_mallocN( sizeof(BIHNode)*needed_nodes, "BIHTree.Nodes"); + obj->node_next = obj->node_alloc; + + obj->root = bih_rearrange( obj, obj->builder, 1, (float*)obj->bb ); + + rtbuild_free( obj->builder ); + obj->builder = NULL; + + assert(obj->node_alloc+needed_nodes >= obj->node_next); +} + diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp index 435c49cdc42..48c1ac07cd4 100644 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -115,7 +115,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float if(rtbuild_size(builder) == 1) { - RayObject *child = builder->begin[0]; + RayObject *child = rtbuild_get_primitive( builder, 0 ); if(RayObject_isRayFace(child)) { @@ -127,7 +127,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float for(i=0; i<1; i++) { - parent->child[i] = (BVHNode*)builder->begin[i]; + parent->child[i] = (BVHNode*)rtbuild_get_primitive( builder, i ); bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3); } for(; i diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index b0ac54bef2c..fb2d05a0a14 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -8,21 +8,23 @@ #include "BLI_arithb.h" #include "BKE_utildefines.h" -static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n); -static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis); -static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane); - -static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) +static bool selected_node(RTBuilder::Object *node) { - int i; + return node->selected; +} - b->begin = begin; - b->end = end; - b->split_axis = 0; - b->child_sorted_axis = -1; +static void rtbuild_init(RTBuilder *b) +{ + b->split_axis = -1; + b->primitives.begin = 0; + b->primitives.end = 0; + b->primitives.maxsize = 0; - for(i=0; ichild_offset[i] = 0; + + for(int i=0; i<3; i++) + b->sorted_begin[i] = b->sorted_end[i] = 0; INIT_MINMAX(b->bb, b->bb+3); } @@ -30,60 +32,129 @@ static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end) RTBuilder* rtbuild_create(int size) { RTBuilder *builder = (RTBuilder*) MEM_mallocN( sizeof(RTBuilder), "RTBuilder" ); - RayObject **memblock= (RayObject**)MEM_mallocN( sizeof(RayObject*)*size,"RTBuilder.objects"); - rtbuild_init(builder, memblock, memblock); + RTBuilder::Object *memblock= (RTBuilder::Object*)MEM_mallocN( sizeof(RTBuilder::Object)*size,"RTBuilder.objects"); + + + rtbuild_init(builder); + + builder->primitives.begin = builder->primitives.end = memblock; + builder->primitives.maxsize = size; + + for(int i=0; i<3; i++) + { + builder->sorted_begin[i] = (RTBuilder::Object**)MEM_mallocN( sizeof(RTBuilder::Object*)*size,"RTBuilder.sorted_objects"); + builder->sorted_end[i] = builder->sorted_begin[i]; + } + + return builder; } void rtbuild_free(RTBuilder *b) { - MEM_freeN(b->begin); + if(b->primitives.begin) MEM_freeN(b->primitives.begin); + + for(int i=0; i<3; i++) + if(b->sorted_begin[i]) + MEM_freeN(b->sorted_begin[i]); + MEM_freeN(b); } void rtbuild_add(RTBuilder *b, RayObject *o) { - *(b->end++) = o; -} + assert( b->primitives.begin + b->primitives.maxsize != b->primitives.end ); + + b->primitives.end->obj = o; + b->primitives.end->cost = RE_rayobject_cost(o); -void rtbuild_calc_bb(RTBuilder *b) -{ - if(b->bb[0] == 1.0e30f) + INIT_MINMAX(b->primitives.end->bb, b->primitives.end->bb+3); + RE_rayobject_merge_bb(o, b->primitives.end->bb, b->primitives.end->bb+3); + + for(int i=0; i<3; i++) { - RayObject **index = b->begin; - for(; index != b->end; index++) - RE_rayobject_merge_bb(*index, b->bb, b->bb+3); + *(b->sorted_end[i]) = b->primitives.end; + b->sorted_end[i]++; } + b->primitives.end++; } -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) +int rtbuild_size(RTBuilder *b) { - rtbuild_calc_bb(b); - DO_MIN(b->bb, min); - DO_MAX(b->bb+3, max); + return b->sorted_end[0] - b->sorted_begin[0]; } -int rtbuild_get_largest_axis(RTBuilder *b) + +template +static bool obj_bb_compare(const Obj &a, const Obj &b) { - rtbuild_calc_bb(b); - return bb_largest_axis(b->bb, b->bb+3); + if(a->bb[Axis] != b->bb[Axis]) + return a->bb[Axis] < b->bb[Axis]; + return a->obj < b->obj; } +template +static void object_sort(Item *begin, Item *end, int axis) +{ + if(axis == 0) return std::sort(begin, end, obj_bb_compare ); + if(axis == 1) return std::sort(begin, end, obj_bb_compare ); + if(axis == 2) return std::sort(begin, end, obj_bb_compare ); + assert(false); +} -int rtbuild_size(RTBuilder *b) +void rtbuild_done(RTBuilder *b) { - return b->end - b->begin; + for(int i=0; i<3; i++) + if(b->sorted_begin[i]) + object_sort( b->sorted_begin[i], b->sorted_end[i], i ); } +RayObject* rtbuild_get_primitive(RTBuilder *b, int index) +{ + return b->sorted_begin[0][index]->obj; +} RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) { - rtbuild_init( tmp, b->begin + b->child_offset[child], b->begin + b->child_offset[child+1] ); - tmp->child_sorted_axis = b->child_sorted_axis; + rtbuild_init( tmp ); + + for(int i=0; i<3; i++) + if(b->sorted_begin[i]) + { + tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child ]; + tmp->sorted_end [i] = b->sorted_begin[i] + b->child_offset[child+1]; + } + else + { + tmp->sorted_begin[i] = 0; + tmp->sorted_end [i] = 0; + } + return tmp; } +void rtbuild_calc_bb(RTBuilder *b) +{ + if(b->bb[0] == 1.0e30f) + { + for(RTBuilder::Object **index = b->sorted_begin[0]; index != b->sorted_end[0]; index++) + RE_rayobject_merge_bb( (*index)->obj , b->bb, b->bb+3); + } +} +void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) +{ + rtbuild_calc_bb(b); + DO_MIN(b->bb, min); + DO_MAX(b->bb+3, max); +} + +/* +int rtbuild_get_largest_axis(RTBuilder *b) +{ + rtbuild_calc_bb(b); + return bb_largest_axis(b->bb, b->bb+3); +} //Left balanced tree int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis) @@ -142,11 +213,13 @@ int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds) int axis = rtbuild_get_largest_axis(b); return rtbuild_mean_split(b, nchilds, axis); } +*/ /* * "separators" is an array of dim NCHILDS-1 * and indicates where to cut the childs */ +/* int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis) { int size = rtbuild_size(b); @@ -189,120 +262,84 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds) return rtbuild_median_split(b, separators, nchilds, la); } +*/ //Heuristics Object Splitter -typedef struct CostObject CostObject; -struct CostObject -{ - RayObject *obj; - float cost; - float bb[6]; -}; -template -bool obj_bb_compare(const Obj &a, const Obj &b) -{ - if(a.bb[Axis] != b.bb[Axis]) - return a.bb[Axis] < b.bb[Axis]; - return a.obj < b.obj; -} -void costobject_sort(CostObject *begin, CostObject *end, int axis) +struct SweepCost { - if(axis == 0) return std::sort(begin, end, obj_bb_compare ); - if(axis == 1) return std::sort(begin, end, obj_bb_compare ); - if(axis == 2) return std::sort(begin, end, obj_bb_compare ); - assert(false); -} - - + float bb[6]; + float cost; +}; /* Object Surface Area Heuristic splitter */ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) { int size = rtbuild_size(b); assert(nchilds == 2); + assert(size > 1); + int baxis = -1, boffset = 0; - if(size <= nchilds) - { - return rtbuild_mean_split_largest_axis(b, nchilds); - } - else + if(size > nchilds) { float bcost = FLT_MAX; - float childrens_cost = 0; - int i, axis, baxis = -1, boffset = size/2, k, try_axis[3]; - CostObject *cost = (CostObject*)MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" ); - float *acc_bb = (float*)MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" ); + baxis = -1, boffset = size/2; - for(i=0; ibegin[i]; - INIT_MINMAX(cost[i].bb, cost[i].bb+3); - RE_rayobject_merge_bb(cost[i].obj, cost[i].bb, cost[i].bb+3); - cost[i].cost = RE_rayobject_cost(cost[i].obj); - childrens_cost += cost[i].cost; - } - - if(b->child_sorted_axis >= 0 && b->child_sorted_axis < 3) - { - try_axis[0] = b->child_sorted_axis; - try_axis[1] = (b->child_sorted_axis+1)%3; - try_axis[2] = (b->child_sorted_axis+2)%3; - } - else - { - try_axis[0] = 0; - try_axis[1] = 1; - try_axis[2] = 2; - } + SweepCost *sweep = (SweepCost*)MEM_mallocN( sizeof(SweepCost)*size, "RTBuilder.HeuristicSweep" ); - for(axis=try_axis[k=0]; k<3; axis=try_axis[++k]) + for(int axis=0; axis<3; axis++) { - float left_cost, right_cost; - float other_bb[6]; + SweepCost sweep_left; - - - costobject_sort(cost, cost+size, axis); - for(i=size-1; i>=0; i--) + RTBuilder::Object **obj = b->sorted_begin[axis]; + +// float right_cost = 0; + for(int i=size-1; i>=0; i--) { - float *bb = acc_bb+i*6; if(i == size-1) { - VECCOPY(bb, cost[i].bb); - VECCOPY(bb+3, cost[i].bb+3); + VECCOPY(sweep[i].bb, obj[i]->bb); + VECCOPY(sweep[i].bb+3, obj[i]->bb+3); + sweep[i].cost = obj[i]->cost; } else { - bb[0] = MIN2(cost[i].bb[0], bb[6+0]); - bb[1] = MIN2(cost[i].bb[1], bb[6+1]); - bb[2] = MIN2(cost[i].bb[2], bb[6+2]); - - bb[3] = MAX2(cost[i].bb[3], bb[6+3]); - bb[4] = MAX2(cost[i].bb[4], bb[6+4]); - bb[5] = MAX2(cost[i].bb[5], bb[6+5]); + sweep[i].bb[0] = MIN2(obj[i]->bb[0], sweep[i+1].bb[0]); + sweep[i].bb[1] = MIN2(obj[i]->bb[1], sweep[i+1].bb[1]); + sweep[i].bb[2] = MIN2(obj[i]->bb[2], sweep[i+1].bb[2]); + sweep[i].bb[3] = MAX2(obj[i]->bb[3], sweep[i+1].bb[3]); + sweep[i].bb[4] = MAX2(obj[i]->bb[4], sweep[i+1].bb[4]); + sweep[i].bb[5] = MAX2(obj[i]->bb[5], sweep[i+1].bb[5]); + sweep[i].cost = obj[i]->cost + sweep[i+1].cost; } +// right_cost += obj[i]->cost; } - INIT_MINMAX(other_bb, other_bb+3); - DO_MIN( cost[0].bb, other_bb ); - DO_MAX( cost[0].bb+3, other_bb+3 ); - left_cost = cost[0].cost; - right_cost = childrens_cost-cost[0].cost; - if(right_cost < 0) right_cost = 0; - - for(i=1; ibb[0]; + sweep_left.bb[1] = obj[0]->bb[1]; + sweep_left.bb[2] = obj[0]->bb[2]; + sweep_left.bb[3] = obj[0]->bb[3]; + sweep_left.bb[4] = obj[0]->bb[4]; + sweep_left.bb[5] = obj[0]->bb[5]; + sweep_left.cost = obj[0]->cost; + +// right_cost -= obj[0]->cost; if(right_cost < 0) right_cost = 0; + + for(int i=1; i 0); + assert(right_side > 0); if(left_side > bcost) break; //No way we can find a better heuristic in this axis - hcost = left_side+right_side; assert(hcost >= 0); if( hcost < bcost || (hcost == bcost && axis < baxis)) //this makes sure the tree built is the same whatever is the order of the sorting axis @@ -311,142 +348,51 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) baxis = axis; boffset = i; } - DO_MIN( cost[i].bb, other_bb ); - DO_MAX( cost[i].bb+3, other_bb+3 ); - left_cost += cost[i].cost; - right_cost -= cost[i].cost; - if(right_cost < 0.0f) right_cost = 0.0; - } - - if(baxis == axis) - { - for(i=0; ibegin[i] = cost[i].obj; - b->child_sorted_axis = axis; + DO_MIN( obj[i]->bb, sweep_left.bb ); + DO_MAX( obj[i]->bb+3, sweep_left.bb+3 ); + + sweep_left.cost += obj[i]->cost; +// right_cost -= obj[i]->cost; if(right_cost < 0) right_cost = 0; } assert(baxis >= 0 && baxis < 3); } - b->child_offset[0] = 0; - b->child_offset[1] = boffset; - b->child_offset[2] = size; - MEM_freeN(acc_bb); - MEM_freeN(cost); - return nchilds; + MEM_freeN(sweep); } -} - -/* - * Helper code - * PARTITION code / used on mean-split - * basicly this a std::nth_element (like on C++ STL algorithm) - */ -static void sort_swap(RTBuilder *b, int i, int j) -{ - SWAP(RayObject*, b->begin[i], b->begin[j]); -} - -static float sort_get_value(RTBuilder *b, int i) -{ - float min[3], max[3]; - INIT_MINMAX(min, max); - RE_rayobject_merge_bb(b->begin[i], min, max); - return max[b->split_axis]; -} - -static int medianof3(RTBuilder *d, int a, int b, int c) -{ - float fa = sort_get_value( d, a ); - float fb = sort_get_value( d, b ); - float fc = sort_get_value( d, c ); - - if(fb < fa) + else if(size == 2) { - if(fc < fb) - return b; - else - { - if(fc < fa) - return c; - else - return a; - } + baxis = 0; + boffset = 1; } - else + else if(size == 1) { - if(fc < fb) - { - if(fc < fa) - return a; - else - return c; - } - else - return b; + b->child_offset[0] = 0; + b->child_offset[1] = 1; + return 1; } -} - -static void insertionsort(RTBuilder *b, int lo, int hi) -{ - int i; - for(i=lo; ibegin[i]; - float tv= sort_get_value(b, i); - int j=i; - while( j != lo && tv < sort_get_value(b, j-1)) - { - b->begin[j] = b->begin[j-1]; - j--; - } - b->begin[j] = t; - } -} - -static int partition(RTBuilder *b, int lo, int mid, int hi) -{ - float x = sort_get_value( b, mid ); + b->child_offset[0] = 0; + b->child_offset[1] = boffset; + b->child_offset[2] = size; - int i=lo, j=hi; - while (1) - { - while(sort_get_value(b,i) < x) i++; - j--; - while(x < sort_get_value(b,j)) j--; - if(!(i < j)) - return i; - - sort_swap(b, i, j); - i++; - } -} -// -// PARTITION code / used on mean-split -// basicly this is an adapted std::nth_element (C++ STL ) -// -// after a call to this function you can expect one of: -// every node to left of a[n] are smaller or equal to it -// every node to the right of a[n] are greater or equal to it -static int partition_nth_element(RTBuilder *b, int _begin, int n, int _end) -{ - int begin = _begin, end = _end, cut; - while(end-begin > 3) - { - cut = partition(b, begin, medianof3(b, begin, begin+(end-begin)/2, end-1), end); - if(cut <= n) - begin = cut; - else - end = cut; - } - insertionsort(b, begin, end); + /* Adjust sorted arrays for childs */ + for(int i=0; isorted_begin[baxis][i]->selected = true; + for(int i=boffset; isorted_begin[baxis][i]->selected = false; + for(int i=0; i<3; i++) + std::stable_partition( b->sorted_begin[i], b->sorted_end[i], selected_node ); - return n; + return nchilds; } +/* + * Helper code + * PARTITION code / used on mean-split + * basicly this a std::nth_element (like on C++ STL algorithm) + */ +/* static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) { int i; @@ -456,23 +402,12 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) { assert(nth[i] < nth[i+1] && nth[i+1] < nth[partitions]); - partition_nth_element(b, nth[i], nth[i+1], nth[partitions] ); - } -} - -static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane) -{ - int i; - for(i = begin; i != end; i++) - { - if(sort_get_value(b, i) < plane) - { - sort_swap(b, i, begin); - begin++; - } + if(split_axis == 0) std::nth_element(b, nth[i], nth[i+1], nth[partitions], obj_bb_compare); + if(split_axis == 1) std::nth_element(b, nth[i], nth[i+1], nth[partitions], obj_bb_compare); + if(split_axis == 2) std::nth_element(b, nth[i], nth[i+1], nth[partitions], obj_bb_compare); } - return begin; } +*/ /* * Bounding Box utils diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h new file mode 100644 index 00000000000..8f471f095e2 --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -0,0 +1,121 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYOBJECT_RTBUILD_H +#define RE_RAYOBJECT_RTBUILD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rayobject.h" + + +/* + * Ray Tree Builder + * this structs helps building any type of tree + * it contains several methods to organiza/split nodes + * allowing to create a given tree on the fly. + * + * Idea is that other trees BVH, BIH can use this code to + * generate with simple calls, and then convert to the theirs + * specific structure on the fly. + */ +#define RTBUILD_MAX_CHILDS 32 + + +typedef struct RTBuilder +{ + struct Object + { + RayObject *obj; + float cost; + float bb[6]; + int selected; + }; + + /* list to all primitives added in this tree */ + struct + { + Object *begin, *end; + int maxsize; + } primitives; + + /* sorted list of rayobjects */ + struct Object **sorted_begin[3], **sorted_end[3]; + + /* axis used (if any) on the split method */ + int split_axis; + + /* child partitions calculated during splitting */ + int child_offset[RTBUILD_MAX_CHILDS+1]; + +// int child_sorted_axis; /* -1 if not sorted */ + + float bb[6]; + +} RTBuilder; + +/* used during creation */ +RTBuilder* rtbuild_create(int size); +void rtbuild_free(RTBuilder *b); +void rtbuild_add(RTBuilder *b, RayObject *o); +void rtbuild_done(RTBuilder *b); +void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); +int rtbuild_size(RTBuilder *b); + +RayObject* rtbuild_get_primitive(RTBuilder *b, int offset); + +/* used during tree reorganization */ +RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); + +/* Calculates child partitions and returns number of efectively needed partitions */ +int rtbuild_get_largest_axis(RTBuilder *b); + +//Object partition +int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis); +int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds); + +int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds); + +//Space partition +int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis); +int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); + + +/* bb utils */ +float bb_area(float *min, float *max); +float bb_volume(float *min, float *max); +int bb_largest_axis(float *min, float *max); +int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max); /* only returns 0 if merging inner and outerbox would create a box larger than outer box */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 17ed63e3669..2dde485d3d1 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -235,7 +235,7 @@ Node *bvh_rearrange(Tree *tree, Builder *builder) Node *node = bvh_new_node(tree); INIT_MINMAX(node->bb, node->bb+3); rtbuild_merge_bb(builder, node->bb, node->bb+3); - node->child = (BVHNode*)builder->begin[0]; + node->child = (BVHNode*) rtbuild_get_primitive( builder, 0 ); return node; } else @@ -266,6 +266,8 @@ Node *bvh_rearrange(Tree *tree, Builder *builder) template<> void bvh_done(BVHTree *obj) { + rtbuild_done(obj->builder); + int needed_nodes = (rtbuild_size(obj->builder)+1)*2; if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) needed_nodes = BLI_MEMARENA_STD_BUFSIZE; diff --git a/source/blender/render/intern/source/rayobject_bih.c b/source/blender/render/intern/source/rayobject_bih.c deleted file mode 100644 index e2cb9bad302..00000000000 --- a/source/blender/render/intern/source/rayobject_bih.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include -#include - -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" - -#define BIH_NCHILDS 4 -typedef struct BIHTree BIHTree; - -static int bih_intersect(BIHTree *obj, Isect *isec); -static void bih_add(BIHTree *o, RayObject *ob); -static void bih_done(BIHTree *o); -static void bih_free(BIHTree *o); -static void bih_bb(BIHTree *o, float *min, float *max); - -static RayObjectAPI bih_api = -{ - (RE_rayobject_raycast_callback) bih_intersect, - (RE_rayobject_add_callback) bih_add, - (RE_rayobject_done_callback) bih_done, - (RE_rayobject_free_callback) bih_free, - (RE_rayobject_merge_bb_callback)bih_bb -}; - -typedef struct BIHNode BIHNode; -struct BIHNode -{ - BIHNode *child[BIH_NCHILDS]; - float bi[BIH_NCHILDS][2]; - int split_axis; -}; - -struct BIHTree -{ - RayObject rayobj; - - BIHNode *root; - - BIHNode *node_alloc, *node_next; - RTBuilder *builder; - - float bb[2][3]; -}; - - -RayObject *RE_rayobject_bih_create(int size) -{ - BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bih_api; - obj->root = NULL; - - obj->node_alloc = obj->node_next = NULL; - obj->builder = rtbuild_create( size ); - - return RayObject_unalignRayAPI((RayObject*) obj); -} - -static void bih_free(BIHTree *obj) -{ - if(obj->builder) - rtbuild_free(obj->builder); - - if(obj->node_alloc) - MEM_freeN(obj->node_alloc); - - MEM_freeN(obj); -} - -static void bih_bb(BIHTree *obj, float *min, float *max) -{ - DO_MIN(obj->bb[0], min); - DO_MAX(obj->bb[1], max); -} - -/* - * Tree transverse - */ -static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float tmax) -{ - int i; - int hit = 0; - - const int *const offset = isec->bv_index + node->split_axis*2; - - //TODO diving heuristic - for(i=0; ibi[i][offset[0]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; - float t2 = (node->bi[i][offset[1]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; - - if(t1 < tmin) t1 = tmin; //t1 = MAX2(t1, tmin); - if(t2 > tmax) t2 = tmax; //t2 = MIN2(t2, tmax); - - if(t1 <= t2) - { - if(RayObject_isAligned(node->child[i])) - { - if(node->child[i] == 0) break; - - hit |= dfs_raycast(node->child[i], isec, t1, t2); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - - if(tmax > isec->labda) - tmax = isec->labda; - } - } - - return hit; -} - -static int bih_intersect(BIHTree *obj, Isect *isec) -{ - if(RayObject_isAligned(obj->root)) - return dfs_raycast(obj->root, isec, 0, isec->labda); - else - return RE_rayobject_intersect( (RayObject*)obj->root, isec); -} - - -/* - * Builds a BIH tree from builder object - */ -static void bih_add(BIHTree *obj, RayObject *ob) -{ - rtbuild_add( obj->builder, ob ); -} - -static BIHNode *bih_new_node(BIHTree *tree, int nid) -{ - BIHNode *node = tree->node_alloc + nid - 1; - assert(RayObject_isAligned(node)); - if(node+1 > tree->node_next) - tree->node_next = node+1; - - return node; -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BIH_NCHILDS+(2-BIH_NCHILDS)+nchild; -} - -static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float *bb) -{ - if(rtbuild_size(builder) == 1) - { - RayObject *child = builder->begin[0]; - assert(!RayObject_isAligned(child)); - - INIT_MINMAX(bb, bb+3); - RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3); - - return (BIHNode*)child; - } - else - { - int i; - int nc = rtbuild_mean_split_largest_axis(builder, BIH_NCHILDS); - RTBuilder tmp; - - BIHNode *parent = bih_new_node(tree, nid); - - INIT_MINMAX(bb, bb+3); - parent->split_axis = builder->split_axis; - for(i=0; ichild[i] = bih_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), cbb ); - - parent->bi[i][0] = cbb[parent->split_axis]; - parent->bi[i][1] = cbb[parent->split_axis+3]; - - DO_MIN(cbb , bb); - DO_MAX(cbb+3, bb+3); - } - for(; ibi[i][0] = 1.0; - parent->bi[i][1] = -1.0; - parent->child[i] = 0; - } - - return parent; - } -} - -static void bih_info(BIHTree *obj) -{ - printf("BIH: Used %d nodes\n", obj->node_next - obj->node_alloc); -} - -static void bih_done(BIHTree *obj) -{ - int needed_nodes; - assert(obj->root == NULL && obj->node_alloc == NULL && obj->builder); - - //TODO exact calculate needed nodes - needed_nodes = (rtbuild_size(obj->builder)+1)*2; - assert(needed_nodes > 0); - - obj->node_alloc = (BIHNode*)MEM_mallocN( sizeof(BIHNode)*needed_nodes, "BIHTree.Nodes"); - obj->node_next = obj->node_alloc; - - obj->root = bih_rearrange( obj, obj->builder, 1, (float*)obj->bb ); - - rtbuild_free( obj->builder ); - obj->builder = NULL; - - assert(obj->node_alloc+needed_nodes >= obj->node_next); -} - -- cgit v1.2.3 From eaf232cad9f48dd2aa48ebba7197aee6d5586ec2 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 3 Aug 2009 23:25:38 +0000 Subject: single tree (by default) now that build is nlogn (it should be worth to the tree of trees) --- .../render/intern/raytrace/rayobject_rtbuild.cpp | 4 +- source/blender/render/intern/source/rayshade.c | 56 ++++++++++++++-------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index fb2d05a0a14..238929e1dbb 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -335,8 +335,8 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) right_side= bb_area(sweep[i].bb, sweep[i].bb+3)*(sweep[i].cost+logf(size-i)); hcost = left_side+right_side; - assert(left_side > 0); - assert(right_side > 0); + assert(left_side >= 0); + assert(right_side >= 0); if(left_side > bcost) break; //No way we can find a better heuristic in this axis diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index f6ba45308a5..1df201f7b00 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -308,13 +308,18 @@ static void makeraytree_single(Render *re) ObjectRen *obr = obi->obr; obs++; - assert((obi->flag & R_TRANSFORMED) == 0); //Not suported - - for(v=0;vtotvlak;v++) + if(obi->flag & R_TRANSFORMED) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - if(is_raytraceable_vlr(re, vlr)) - faces++; + faces++; + } + else + { + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + if(is_raytraceable_vlr(re, vlr)) + faces++; + } } } @@ -329,22 +334,30 @@ static void makeraytree_single(Render *re) for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) { - int v; - ObjectRen *obr = obi->obr; - - for(v=0;vtotvlak;v++) + if(obi->flag & R_TRANSFORMED) { - VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - face->v1 = vlr->v1->co; - face->v2 = vlr->v2->co; - face->v3 = vlr->v3->co; - face->v4 = vlr->v4 ? vlr->v4->co : NULL; - - face->ob = obi; - face->face = vlr; - - RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); - face++; + RayObject *obj = makeraytree_object(re, obi); + RE_rayobject_add( re->raytree, obj ); + } + else + { + int v; + ObjectRen *obr = obi->obr; + + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + face->v1 = vlr->v1->co; + face->v2 = vlr->v2->co; + face->v3 = vlr->v3->co; + face->v4 = vlr->v4 ? vlr->v4->co : NULL; + + face->ob = obi; + face->face = vlr; + + RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); + face++; + } } } RE_rayobject_done( raytree ); @@ -356,6 +369,7 @@ void makeraytree(Render *re) int i; const char *tree_type = "Tree(unknown)"; + re->r.raytrace_tree_type = R_RAYSTRUCTURE_SINGLE_BVH; #ifdef RE_RAYCOUNTER if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BVH) tree_type = "BVH"; -- cgit v1.2.3 From 5e21e68f834d80e264e0cb222e65d2767419f046 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 4 Aug 2009 00:00:05 +0000 Subject: (fix) --- source/blender/render/intern/source/rayshade.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 1df201f7b00..58bfa506e2b 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -369,7 +369,7 @@ void makeraytree(Render *re) int i; const char *tree_type = "Tree(unknown)"; - re->r.raytrace_tree_type = R_RAYSTRUCTURE_SINGLE_BVH; + re->r.raystructure = R_RAYSTRUCTURE_SINGLE_BVH; #ifdef RE_RAYCOUNTER if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BVH) tree_type = "BVH"; -- cgit v1.2.3 From 7e9dc51cd1a9c35eb54660ea650570f81d102e2e Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 4 Aug 2009 17:24:49 +0000 Subject: Skip BB tests on primitives the efficiency of this depends on ray-bb and ray-triangle functions efficiency --- source/blender/render/extern/include/RE_raytrace.h | 2 +- .../blender/render/intern/raytrace/rayobject_vbvh.cpp | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index beae1b84b04..864b6124db4 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -37,7 +37,7 @@ extern "C" { #define RE_RAY_LCTS_MAX_SIZE 256 -#define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ +#define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ //#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */ #define RE_RAYCOUNTER diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 2dde485d3d1..774a465092d 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -81,12 +81,23 @@ template inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) { Node *child = node->child; - while(child) + + if(!RayObject_isAligned(child)) { stack[stack_pos++] = child; - if(RayObject_isAligned(child)) + } + else + { + while(child) + { + //Skips BB tests on primitives + if(!RayObject_isAligned(child->child)) + stack[stack_pos++] = child->child; + else + stack[stack_pos++] = child; + child = child->sibling; - else break; + } } } -- cgit v1.2.3 From 2160f36fea5ec0f7cd2747f8889f6005a14d9e6c Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 4 Aug 2009 18:03:04 +0000 Subject: Fix point-hint --- .../render/intern/raytrace/rayobject_vbvh.cpp | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 774a465092d..5c9807baa29 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -345,24 +345,32 @@ void bvh_dfs_make_hint_push_siblings(Node *node, LCTSHint *hint, int reserve_spa bvh_dfs_make_hint_push_siblings(node->sibling, hint, reserve_space+1, min, max); bvh_dfs_make_hint(node, hint, reserve_space, min, max); - } - - + } } template void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max) { - assert( hint->size - reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); + assert( hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); - if(hint->size - reserve_space + 1 == RE_RAY_LCTS_MAX_SIZE || !RayObject_isAligned(node)) + if(!RayObject_isAligned(node)) + { hint->stack[hint->size++] = (RayObject*)node; + } else { - /* We are 100% sure the ray will be pass inside this node */ - if(bb_fits_inside(node->bb, node->bb+3, min, max) ) + int childs = count_childs(node); + if(hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) { - bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, min, max); + /* We are 100% sure the ray will be pass inside this node */ + if(bb_fits_inside(node->bb, node->bb+3, min, max) ) + { + bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, min, max); + } + else + { + hint->stack[hint->size++] = (RayObject*)node; + } } else { -- cgit v1.2.3 From 7586990ace3a988e720397f47bf95b7bc9d7124b Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 5 Aug 2009 07:59:49 +0000 Subject: - modified BKE_get_image_export_path so that it writes relative path if src file = dest file returning 2 in this case - modified unit tests for ^ firstly - incorporated Image.get_export_path into FBX exporter script --- release/io/export_fbx.py | 22 +++++++++++++++------- source/blender/blenkernel/intern/image.c | 12 ++++++------ source/blender/makesrna/intern/rna_image_api.c | 5 +++++ source/creator/tests/alltest.c | 12 ++++++------ 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index a81dea4d909..c50b60fd97e 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -39,6 +39,7 @@ http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx import os import time import math # math.pi +import shutil # for file copying # try: # import time @@ -1324,8 +1325,6 @@ def write(filename, batch_objects = None, \ # tex is an Image (Arystan) def write_video(texname, tex): - if not EXP_IMAGE_COPY: return - # Same as texture really! file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) @@ -1337,9 +1336,15 @@ def write(filename, batch_objects = None, \ Property: "Width", "int", "",0 Property: "Height", "int", "",0''') if tex: - abspath = tex.export(basepath) - fname_rel = os.path.relpath(abspath, basepath) - fname_strip = os.path.basename(abspath) + src = bpy.sys.expandpath(tex.filename) + fname_rel = tex.get_export_path(basepath, True) + fname_abs = tex.get_export_path(basepath, False) + fname_strip = os.path.basename(fname_rel) + + if EXP_IMAGE_COPY: + if !os.path.exists(fname_abs): + shutil.copy(src, fname_abs) + # fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: fname = fname_strip = fname_rel = '' @@ -1404,11 +1409,14 @@ def write(filename, batch_objects = None, \ file.write('\n\t\tMedia: "Video::%s"' % texname) if tex: - fname_rel = tex.get_export_path(relpath, True) + src = bpy.sys.expandpath(tex.filename) + fname_rel = tex.get_export_path(basepath, True) + fname_abs = tex.get_export_path(basepath, False) fname_strip = os.path.basename(fname_rel) if EXP_IMAGE_COPY: - + if !os.path.exists(fname_abs): + shutil.copy(src, fname_abs) # fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index b66213ffbc2..4a355640d8b 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2206,12 +2206,6 @@ int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, BLI_join_dirfile(dest_path, dest_dir, base); } - /* only return 1 if paths differ */ - if (!strcmp(path, dest_path)) { - if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path); - return 0; - } - if (abs) BLI_strncpy(abs, dest_path, abs_size); @@ -2220,5 +2214,11 @@ int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, strncat(rel, base, rel_size); } + /* return 2 if src=dest */ + if (!strcmp(path, dest_path)) { + if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path); + return 2; + } + return 1; } diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 20770ef2957..af059b435b3 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -41,6 +41,11 @@ #include "BKE_utildefines.h" #include "BKE_image.h" +/* + User should check if returned path exists before copying a file there. + + TODO: it would be better to return a (abs, rel) tuple. +*/ static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel) { int length = FILE_MAX; diff --git a/source/creator/tests/alltest.c b/source/creator/tests/alltest.c index 99e0d2f5b26..89a58a08dfd 100644 --- a/source/creator/tests/alltest.c +++ b/source/creator/tests/alltest.c @@ -60,19 +60,19 @@ START_TEST(test_copy_images) {"//image.png", {{"/home/user/image.png", "image.png", 1}, {"/home/user/image.png", "image.png", 1}, {"/home/user/export/image.png", "image.png", 1}, - {"", "", 0},}}, + {"/home/user/foo/image.png", "image.png", 2},}}, /* relative, 1 level deep */ {"//bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, {"/home/user/bar/image.png", "bar/image.png", 1}, {"/home/user/export/bar/image.png", "bar/image.png", 1}, - {"", "", 0},}}, + {"/home/user/foo/bar/image.png", "bar/image.png", 2},}}, /* relative, 2 level deep */ {"//bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, - {"", "", 0},}}, + {"/home/user/foo/bar/foo/image.png", "bar/foo/image.png", 2},}}, /* absolute, not under .blend dir */ {"/home/user/bar/image.png", {{"/home/user/image.png", "image.png", 1}, @@ -84,19 +84,19 @@ START_TEST(test_copy_images) {"/home/user/foo/image.png", {{"/home/user/image.png", "image.png", 1}, {"/home/user/image.png", "image.png", 1}, {"/home/user/export/image.png", "image.png", 1}, - {"", "", 0},}}, + {"/home/user/foo/image.png", "image.png", 2},}}, /* absolute, under .blend dir, 1 level deep */ {"/home/user/foo/bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, {"/home/user/bar/image.png", "bar/image.png", 1}, {"/home/user/export/bar/image.png", "bar/image.png", 1}, - {"", "", 0},}}, + {"/home/user/foo/bar/image.png", "bar/image.png", 2},}}, /* absolute, under .blend dir, 2 level deep */ {"/home/user/foo/bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, - {"", "", 0},}}, + {"/home/user/foo/bar/foo/image.png", "bar/foo/image.png", 2},}}, /* empty image path, don't let these pass! */ {"", {{"", 0}, -- cgit v1.2.3 From bf90970eca5471b86d900daffb2f8eebdf85a673 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 5 Aug 2009 09:49:59 +0000 Subject: - OBJ exporter now copies images - added OBJ, FBX scripts to File -> Export, File -> Import menus --- release/io/export_fbx.py | 33 +++++++++++------------- release/io/export_obj.py | 65 +++++++++++++++++++++++++++++------------------- release/ui/space_info.py | 3 +++ 3 files changed, 58 insertions(+), 43 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index c50b60fd97e..ad9b3caa13a 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -1323,6 +1323,19 @@ def write(filename, batch_objects = None, \ file.write('\n\t\t}') file.write('\n\t}') + def copy_image(image): + + rel = image.get_export_path(basepath, True) + base = os.path.basename(fname_rel) + + if EXP_IMAGE_COPY: + src = bpy.sys.expandpath(image.filename) + absp = image.get_export_path(basepath, False) + if not os.path.exists(absp): + shutil.copy(src, absp) + + return (rel, base) + # tex is an Image (Arystan) def write_video(texname, tex): # Same as texture really! @@ -1336,15 +1349,7 @@ def write(filename, batch_objects = None, \ Property: "Width", "int", "",0 Property: "Height", "int", "",0''') if tex: - src = bpy.sys.expandpath(tex.filename) - fname_rel = tex.get_export_path(basepath, True) - fname_abs = tex.get_export_path(basepath, False) - fname_strip = os.path.basename(fname_rel) - - if EXP_IMAGE_COPY: - if !os.path.exists(fname_abs): - shutil.copy(src, fname_abs) - + fname_rel, fname_strip = copy_image(tex) # fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: fname = fname_strip = fname_rel = '' @@ -1409,15 +1414,7 @@ def write(filename, batch_objects = None, \ file.write('\n\t\tMedia: "Video::%s"' % texname) if tex: - src = bpy.sys.expandpath(tex.filename) - fname_rel = tex.get_export_path(basepath, True) - fname_abs = tex.get_export_path(basepath, False) - fname_strip = os.path.basename(fname_rel) - - if EXP_IMAGE_COPY: - if !os.path.exists(fname_abs): - shutil.copy(src, fname_abs) - + fname_rel, fname_strip = copy_image(tex) # fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: fname = fname_strip = fname_rel = '' diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 4d67903c343..1209e10afe3 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -47,7 +47,7 @@ will be exported as mesh data. # import math and other in functions that use them for the sake of fast Blender startup # import math -import os # os.sep +import os import bpy import Mathutils @@ -83,13 +83,26 @@ def BPySys_cleanName(name): # A Dict of Materials # (material.name, image.name):matname_imagename # matname_imagename has gaps removed. -MTL_DICT = {} +MTL_DICT = {} -def write_mtl(scene, filename): +def write_mtl(scene, filename, copy_images): world = scene.world worldAmb = world.ambient_color + dest_dir = os.path.dirname(filename) + + def copy_image(image): + rel = image.get_export_path(dest_dir, True) + + if copy_images: + abspath = image.get_export_path(dest_dir, False) + if not os.path.exists(abs_path): + shutil.copy(bpy.sys.expandpath(image.filename), abs_path) + + return rel + + file = open(filename, "w") # XXX # file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) @@ -129,13 +142,17 @@ def write_mtl(scene, filename): # Write images! if img: # We have an image on the face! - file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image + # write relative image path + rel = copy_image(img) + file.write('map_Kd %s\n' % rel) # Diffuse mapping image +# file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image elif mat: # No face image. if we havea material search for MTex image. for mtex in mat.textures: if mtex and mtex.texure.type == 'IMAGE': try: - filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1] + filename = copy_image(mtex.texture.image) +# filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1] file.write('map_Kd %s\n' % filename) # Diffuse mapping image break except: @@ -146,6 +163,7 @@ def write_mtl(scene, filename): file.close() +# XXX not used def copy_file(source, dest): file = open(source, 'rb') data = file.read() @@ -156,6 +174,7 @@ def copy_file(source, dest): file.close() +# XXX not used def copy_images(dest_dir): if dest_dir[-1] != os.sep: dest_dir += os.sep @@ -181,7 +200,7 @@ def copy_images(dest_dir): pass # Now copy images -# copyCount = 0 + copyCount = 0 # for bImage in uniqueImages.values(): # image_path = bpy.sys.expandpath(bImage.filename) @@ -193,7 +212,7 @@ def copy_images(dest_dir): # copy_file(image_path, dest_image_path) # copyCount+=1 - paths= bpy.util.copy_images(uniqueImages.values(), dest_dir) +# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir) print('\tCopied %d images' % copyCount) # print('\tCopied %d images' % copyCount) @@ -412,16 +431,11 @@ def write(filename, objects, scene, if ob.type != 'MESH': continue - if EXPORT_APPLY_MODIFIERS: - me = ob.create_mesh('PREVIEW') - else: - me = ob.data.create_copy() + me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW') if EXPORT_ROTX90: - print(ob_mat * mat_xrot90) me.transform(ob_mat * mat_xrot90) else: - print(ob_mat) me.transform(ob_mat) # # Will work for non meshes now! :) @@ -597,7 +611,7 @@ def write(filename, objects, scene, # file.write('vt %.6f %.6f\n' % tuple(uv)) uv_unique_count = len(uv_dict) - del uv, uvkey, uv_dict, f_index, uv_index +# del uv, uvkey, uv_dict, f_index, uv_index # Only need uv_unique_count and uv_face_mapping # NORMAL, Smooth/Non smoothed. @@ -783,16 +797,17 @@ def write(filename, objects, scene, # Now we have all our materials, save them if EXPORT_MTL: - write_mtl(scene, mtlfilename) - if EXPORT_COPY_IMAGES: - dest_dir = filename - # Remove chars until we are just the path. - while dest_dir and dest_dir[-1] not in '\\/': - dest_dir = dest_dir[:-1] - if dest_dir: - copy_images(dest_dir) - else: - print('\tError: "%s" could not be used as a base for an image path.' % filename) + write_mtl(scene, mtlfilename, EXPORT_COPY_IMAGES) +# if EXPORT_COPY_IMAGES: +# dest_dir = os.path.basename(filename) +# # dest_dir = filename +# # # Remove chars until we are just the path. +# # while dest_dir and dest_dir[-1] not in '\\/': +# # dest_dir = dest_dir[:-1] +# if dest_dir: +# copy_images(dest_dir) +# else: +# print('\tError: "%s" could not be used as a base for an image path.' % filename) print("OBJ Export time: %.2f" % (bpy.sys.time() - time1)) # print "OBJ Export time: %.2f" % (sys.time() - time1) @@ -898,7 +913,7 @@ class EXPORT_OT_obj(bpy.types.Operator): bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), # context group - bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= True), + bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False), bpy.props.BoolProperty(attr="use_all_scenes", name="All Scenes", description="", default= False), bpy.props.BoolProperty(attr="use_animation", name="All Animation", description="", default= False), diff --git a/release/ui/space_info.py b/release/ui/space_info.py index 855ce0b4f8f..3ec3bce3d91 100644 --- a/release/ui/space_info.py +++ b/release/ui/space_info.py @@ -74,6 +74,7 @@ class INFO_MT_file_import(bpy.types.Menu): def draw(self, context): layout = self.layout + layout.itemO("import.obj", text="OBJ") class INFO_MT_file_export(bpy.types.Menu): __space_type__ = "USER_PREFERENCES" @@ -82,6 +83,8 @@ class INFO_MT_file_export(bpy.types.Menu): def draw(self, context): layout = self.layout + layout.itemO("export.fbx", text="FBX") + layout.itemO("export.obj", text="OBJ") layout.itemO("export.ply", text="PLY") class INFO_MT_file_external_data(bpy.types.Menu): -- cgit v1.2.3 From 59abddc2024080b3d243d14710d3fb3340766737 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 5 Aug 2009 12:01:42 +0000 Subject: - added Mesh.add_material function - tweaked OBJ importer. It reads primitive files (cube, cone, etc.) --- release/io/import_obj.py | 23 ++++++++++------- source/blender/makesrna/intern/rna_mesh_api.c | 37 ++++++++++++++++++++------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/release/io/import_obj.py b/release/io/import_obj.py index a4778ac7790..2a5d92969af 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -83,9 +83,11 @@ def unpack_list(list_of_tuples): def unpack_face_list(list_of_tuples): l = [] for t in list_of_tuples: - if len(t) == 3: - t += [0] - l.extend(t) + face = [i for i in t] + if len(face) > 4: + raise RuntimeError("More than 4 vertices per face.") + if len(face) == 3: face.append(0) + l.extend(face) return l @@ -163,7 +165,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ # Absolute path - c:\.. etc would work here image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) - has_data = image.has_data + has_data = image.has_data if image else False if image: texture.image = image @@ -503,8 +505,11 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l me= bpy.data.add_mesh(dataname) # me= bpy.data.meshes.new(dataname) - - me.materials= materials[0:16] # make sure the list isnt too big. + + # make sure the list isnt too big + for material in materials[0:16]: + me.add_material(material) +# me.materials= materials[0:16] # make sure the list isnt too big. #me.verts.extend([(0,0,0)]) # dummy vert me.add_geometry(len(verts_loc), 0, len(faces)) @@ -569,7 +574,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l if verts_tex: - blender_tface= me.uv_layers[0].data[i] + blender_tface= me.uv_textures[0].data[i] if context_material: image, has_data= unique_material_images[context_material] @@ -621,7 +626,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l if CREATE_EDGES: - me.add_geometry(0, len(edges)) + me.add_geometry(0, len(edges), 0) # edges should be a list of (a, b) tuples me.edges.foreach_set("verts", unpack_list(edges)) @@ -629,7 +634,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l # del me_edges - me.calc_normals() + me.update() # me.calcNormals() ob= bpy.data.add_object("MESH", "Mesh") diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 9a527948b0f..b50cc678f4f 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -258,6 +258,29 @@ static void rna_Mesh_calc_normals(Mesh *me) mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); } +static void rna_Mesh_add_material(Mesh *me, Material *ma) +{ + int i; + int totcol = me->totcol + 1; + Material **mat; + + /* don't add if mesh already has it */ + for (i = 0; i < me->totcol; i++) + if (me->mat[i] == ma) + return; + + mat= MEM_callocN(sizeof(void*) * totcol, "newmatar"); + + if (me->totcol) memcpy(mat, me->mat, sizeof(void*) * me->totcol); + if (me->mat) MEM_freeN(me->mat); + + me->mat = mat; + me->mat[me->totcol++] = ma; + ma->id.us++; + + test_object_materials((ID*)me); +} + #else void RNA_api_mesh(StructRNA *srna) @@ -289,17 +312,13 @@ void RNA_api_mesh(StructRNA *srna) func= RNA_def_function(srna, "calc_normals", "rna_Mesh_calc_normals"); RNA_def_function_ui_description(func, "Calculate vertex normals."); - /* - func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom"); - RNA_def_function_ui_description(func, "Add geometry data to mesh."); - prop= RNA_def_collection(func, "verts", "?", "", "Vertices."); - RNA_def_property_flag(prop, PROP_REQUIRED); - prop= RNA_def_collection(func, "faces", "?", "", "Faces."); - RNA_def_property_flag(prop, PROP_REQUIRED); - */ - func= RNA_def_function(srna, "update", "rna_Mesh_update"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); + + func= RNA_def_function(srna, "add_material", "rna_Mesh_add_material"); + RNA_def_function_ui_description(func, "Add a new material to Mesh."); + parm= RNA_def_pointer(func, "material", "Material", "", "Material to add."); + RNA_def_property_flag(parm, PROP_REQUIRED); } #endif -- cgit v1.2.3 From bbdba89d06496e1e9a2bc63ce0f70aac8b8cc3f3 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 5 Aug 2009 12:44:11 +0000 Subject: generic hints for raytracer for now only BB hint (i am hoping to find a decent frustum-test) --- .../render/intern/raytrace/rayobject_hint.h | 65 ++++++++++++++++++++++ .../render/intern/raytrace/rayobject_vbvh.cpp | 32 ++++++----- 2 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 source/blender/render/intern/raytrace/rayobject_hint.h diff --git a/source/blender/render/intern/raytrace/rayobject_hint.h b/source/blender/render/intern/raytrace/rayobject_hint.h new file mode 100644 index 00000000000..cc8728a28cb --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_hint.h @@ -0,0 +1,65 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#define HINT_RECURSE 1 +#define HINT_ACCEPT 0 +#define HINT_DISCARD -1 + +struct HintBB +{ + float bb[6]; +}; + +inline int hint_test_bb(HintBB *obj, float *Nmin, float *Nmax) +{ + if(bb_fits_inside( Nmin, Nmax, obj->bb, obj->bb+3 ) ) + return HINT_RECURSE; + else + return HINT_ACCEPT; +} +/* +struct HintFrustum +{ + float co[3]; + float no[4][3]; +}; + +inline int hint_test_bb(HintFrustum &obj, float *Nmin, float *Nmax) +{ + //if frustum inside BB + { + return HINT_RECURSE; + } + //if BB outside frustum + { + return HINT_DISCARD; + } + + return HINT_ACCEPT; +} +*/ diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 5c9807baa29..e8bc59641d7 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -38,6 +38,7 @@ extern "C" #include "rayobject.h" }; +#include "rayobject_hint.h" #include "reorganize.h" #include "bvh.h" #include @@ -331,25 +332,25 @@ int intersect(BVHTree *obj, Isect* isec) } } -template -void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max); +template +void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject); -template -void bvh_dfs_make_hint_push_siblings(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max) +template +void bvh_dfs_make_hint_push_siblings(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) { if(!RayObject_isAligned(node)) hint->stack[hint->size++] = (RayObject*)node; else { if(node->sibling) - bvh_dfs_make_hint_push_siblings(node->sibling, hint, reserve_space+1, min, max); + bvh_dfs_make_hint_push_siblings(node->sibling, hint, reserve_space+1, hintObject); - bvh_dfs_make_hint(node, hint, reserve_space, min, max); + bvh_dfs_make_hint(node, hint, reserve_space, hintObject); } } -template -void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min, float *max) +template +void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) { assert( hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); @@ -362,12 +363,13 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min int childs = count_childs(node); if(hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) { - /* We are 100% sure the ray will be pass inside this node */ - if(bb_fits_inside(node->bb, node->bb+3, min, max) ) + int result = hint_test_bb(hintObject, node->bb, node->bb+3); + if(result == HINT_RECURSE) { - bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, min, max); + /* We are 100% sure the ray will be pass inside this node */ + bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject); } - else + else if(result == HINT_ACCEPT) { hint->stack[hint->size++] = (RayObject*)node; } @@ -382,8 +384,12 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, float *min template void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) { + HintBB bb; + VECCOPY(bb.bb, min); + VECCOPY(bb.bb+3, max); + hint->size = 0; - bvh_dfs_make_hint( tree->root, hint, 0, min, max ); + bvh_dfs_make_hint( tree->root, hint, 0, &bb ); tot_hints++; } -- cgit v1.2.3 From e4e9b569e1b766dc07ae074439a894be8d7cda49 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 5 Aug 2009 14:40:38 +0000 Subject: experiences with memory organization (store the vertexs coords on RayFace) --- source/blender/editors/armature/meshlaplacian.c | 3 +- source/blender/render/intern/include/rayobject.h | 30 ++++- source/blender/render/intern/source/rayobject.c | 33 +++++- .../blender/render/intern/source/rayobject_mesh.c | 132 --------------------- source/blender/render/intern/source/rayshade.c | 26 ++-- 5 files changed, 68 insertions(+), 156 deletions(-) delete mode 100644 source/blender/render/intern/source/rayobject_mesh.c diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 7a0eda16d39..ff3fed6be34 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -401,7 +401,8 @@ static void heat_ray_tree_create(LaplacianSystem *sys) MFace *mface; int a; - sys->heat.raytree = RE_rayobject_mesh_create(me, me); + assert(0); //TODO + //sys->heat.raytree = RE_rayobject_mesh_create(me, me); sys->heat.vface = MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces"); for(a=0, mface=me->mface; atotface; a++, mface++) { diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 6f8debead19..dddeebd5048 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -34,6 +34,7 @@ extern "C" { #endif #include "RE_raytrace.h" +#include "render_types.h" #include @@ -75,16 +76,38 @@ extern "C" { You actually don't need to care about this if you are only using the API described on RE_raytrace.h */ + +/* defines where coordinates of rayface primitives are stored */ +#define RE_RAYFACE_COORDS_LOCAL +//#define RE_RAYFACE_COORDS_POINTER +//#define RE_RAYFACE_COORDS_VLAKREN typedef struct RayFace { +#ifdef RE_RAYFACE_COORDS_LOCAL + float v1[4], v2[4], v3[4], v4[3]; + int quad; + void *ob; + void *face; +#elif defined(RE_RAYFACE_COORDS_POINTER) float *v1, *v2, *v3, *v4; - void *ob; void *face; +#elif defined(RE_RAYFACE_COORDS_VLAKREN) + void *ob; + void *face; +#endif } RayFace; +#ifdef RE_RAYFACE_COORDS_LOCAL +# define RE_rayface_isQuad(a) ((a)->quad) +#elif defined(RE_RAYFACE_COORDS_POINTER) +# define RE_rayface_isQuad(a) ((a)->v4) +#elif defined(RE_RAYFACE_COORDS_VLAKREN) +#endif + + struct RayObject { struct RayObjectAPI *api; @@ -120,6 +143,11 @@ typedef struct RayObjectAPI #define RayObject_isRayFace(o) ((((intptr_t)o)&3) == 1) #define RayObject_isRayAPI(o) ((((intptr_t)o)&3) == 2) +/* + * Loads a VlakRen on a RayFace + */ +void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr); + /* * Extend min/max coords so that the rayobject is inside them */ diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 2e63dc78c0e..c0c2c36fe13 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -165,7 +165,7 @@ static int intersect_rayface(RayFace *face, Isect *is) VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); - if(face->v4) + if(RE_rayface_isQuad(face)) { VECCOPY(co3, face->v4); VECCOPY(co4, face->v3); @@ -219,7 +219,7 @@ static int intersect_rayface(RayFace *face, Isect *is) } } - if(ok==0 && face->v4) { + if(ok==0 && RE_rayface_isQuad(face)) { t20= co3[0]-co4[0]; t21= co3[1]-co4[1]; @@ -297,6 +297,33 @@ static int intersect_rayface(RayFace *face, Isect *is) return 0; } +void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr) +{ +#ifdef RE_RAYFACE_COORDS_LOCAL + VECCOPY(face->v1, vlr->v1->co); + VECCOPY(face->v2, vlr->v2->co); + VECCOPY(face->v3, vlr->v3->co); + if(vlr->v4) + { + VECCOPY(face->v4, vlr->v4->co); + face->quad = 1; + } + else + { + face->quad = 0; + } +#elif defined(RE_RAYFACE_COORDS_POINTER) + face->v1 = vlr->v1->co; + face->v2 = vlr->v2->co; + face->v3 = vlr->v3->co; + face->v4 = vlr->v4 ? vlr->v4->co : NULL; +#elif defined(RE_RAYFACE_COORDS_VLAKREN) +#endif + face->ob = obi; + face->face = vlr; +} + + int RE_rayobject_raycast(RayObject *r, Isect *isec) { int i; @@ -390,7 +417,7 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) DO_MINMAX( face->v1, min, max ); DO_MINMAX( face->v2, min, max ); DO_MINMAX( face->v3, min, max ); - if(face->v4) DO_MINMAX( face->v4, min, max ); + if(RE_rayface_isQuad(face)) DO_MINMAX( face->v4, min, max ); } else if(RayObject_isRayAPI(r)) { diff --git a/source/blender/render/intern/source/rayobject_mesh.c b/source/blender/render/intern/source/rayobject_mesh.c deleted file mode 100644 index 538c245988d..00000000000 --- a/source/blender/render/intern/source/rayobject_mesh.c +++ /dev/null @@ -1,132 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include - -#include "rayobject.h" - -#include "MEM_guardedalloc.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "BKE_utildefines.h" - -typedef struct RayMesh -{ - RayObject rayobj; - - Mesh *mesh; - void *ob; - - RayFace *faces; - int num_faces; - -} RayMesh; - -static int RayObject_mesh_intersect(RayObject *o, Isect *isec); -static void RayObject_mesh_add(RayObject *o, RayObject *ob); -static void RayObject_mesh_done(RayObject *o); -static void RayObject_mesh_free(RayObject *o); -static void RayObject_mesh_bb(RayObject *o, float *min, float *max); - -static RayObjectAPI mesh_api = -{ - RayObject_mesh_intersect, - RayObject_mesh_add, - RayObject_mesh_done, - RayObject_mesh_free, - RayObject_mesh_bb -}; - - -static int RayObject_mesh_intersect(RayObject *o, Isect *isec) -{ - RayMesh *rm= (RayMesh*)o; - int i, hit = 0; - for(i = 0; inum_faces; i++) - if(RE_rayobject_raycast( (RayObject*)rm->faces+i, isec )) - { - hit = 1; - if(isec->mode == RE_RAY_SHADOW) - break; - } - - return hit; -} - -static void RayObject_mesh_add(RayObject *o, RayObject *ob) -{ -} - -static void RayObject_mesh_done(RayObject *o) -{ -} - -static void RayObject_mesh_free(RayObject *o) -{ - RayMesh *rm= (RayMesh*)o; - MEM_freeN( rm->faces ); - MEM_freeN( rm ); -} - -static void RayObject_mesh_bb(RayObject *o, float *min, float *max) -{ - RayMesh *rm= (RayMesh*)o; - int i; - for(i = 0; imesh->totvert; i++) - DO_MINMAX( rm->mesh->mvert[i].co, min, max); -} - -RayObject* RE_rayobject_mesh_create(Mesh *mesh, void *ob) -{ - RayMesh *rm= MEM_callocN(sizeof(RayMesh), "Octree"); - int i; - RayFace *face; - MFace *mface; - - assert( RayObject_isAligned(rm) ); /* RayObject API assumes real data to be 4-byte aligned */ - - rm->rayobj.api = &mesh_api; - rm->mesh = mesh; - rm->faces = MEM_callocN(sizeof(RayFace)*mesh->totface, "octree rayobject nodes"); - rm->num_faces = mesh->totface; - - face = rm->faces; - mface = mesh->mface; - for(i=0; itotface; i++, face++, mface++) - { - face->v1 = mesh->mvert[mface->v1].co; - face->v2 = mesh->mvert[mface->v2].co; - face->v3 = mesh->mvert[mface->v3].co; - face->v4 = mface->v4 ? mesh->mvert[mface->v4].co : NULL; - - face->ob = ob; - face->face = (void*)i; - } - - return RayObject_unalignRayAPI((RayObject*) rm); -} diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 58bfa506e2b..685b82d9da2 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -220,16 +220,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); if(is_raytraceable_vlr(re, vlr)) { - face->v1 = vlr->v1->co; - face->v2 = vlr->v2->co; - face->v3 = vlr->v3->co; - face->v4 = vlr->v4 ? vlr->v4->co : NULL; - - face->ob = obi; - face->face = vlr; - + RE_rayface_from_vlak( face, obi, vlr ); RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); - face++; } } @@ -347,16 +339,12 @@ static void makeraytree_single(Render *re) for(v=0;vtotvlak;v++) { VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); - face->v1 = vlr->v1->co; - face->v2 = vlr->v2->co; - face->v3 = vlr->v3->co; - face->v4 = vlr->v4 ? vlr->v4->co : NULL; - - face->ob = obi; - face->face = vlr; - - RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); - face++; + if(is_raytraceable_vlr(re, vlr)) + { + RE_rayface_from_vlak(face, obi, vlr); + RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); + face++; + } } } } -- cgit v1.2.3 From 9565ef3087a17894fab4847bd5d8d6003e3d2a68 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 5 Aug 2009 15:50:57 +0000 Subject: #define to store coordinates at VlakRen and not at VlakFace adds some additional cost retrieving coords during ray-primitive tests, but reduces some memory usage (4*3floats per face) --- source/blender/render/intern/include/rayobject.h | 6 ++--- source/blender/render/intern/source/rayobject.c | 26 ++++++++++++++++++++++ .../render/intern/source/rayobject_octree.c | 21 ++++++++++++----- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index dddeebd5048..8f0dbed3176 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -78,9 +78,9 @@ extern "C" { */ /* defines where coordinates of rayface primitives are stored */ -#define RE_RAYFACE_COORDS_LOCAL +//#define RE_RAYFACE_COORDS_LOCAL //#define RE_RAYFACE_COORDS_POINTER -//#define RE_RAYFACE_COORDS_VLAKREN +#define RE_RAYFACE_COORDS_VLAKREN typedef struct RayFace { @@ -105,13 +105,13 @@ typedef struct RayFace #elif defined(RE_RAYFACE_COORDS_POINTER) # define RE_rayface_isQuad(a) ((a)->v4) #elif defined(RE_RAYFACE_COORDS_VLAKREN) +# define RE_rayface_isQuad(a) ((((VlakRen*)((a)->face))->v4) != NULL) #endif struct RayObject { struct RayObjectAPI *api; - }; diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index c0c2c36fe13..7316120e477 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -163,6 +163,22 @@ static int intersect_rayface(RayFace *face, Isect *is) RE_RC_COUNT(is->raycounter->faces.test); +#ifdef RE_RAYFACE_COORDS_VLAKREN + { + VlakRen *vlr = (VlakRen*)face->face; + VECCOPY(co1, vlr->v1->co); + VECCOPY(co2, vlr->v2->co); + if(vlr->v4) + { + VECCOPY(co3, vlr->v4->co); + VECCOPY(co4, vlr->v3->co); + } + else + { + VECCOPY(co3, vlr->v3->co); + } + } +#else VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); if(RE_rayface_isQuad(face)) @@ -174,6 +190,7 @@ static int intersect_rayface(RayFace *face, Isect *is) { VECCOPY(co3, face->v3); } +#endif t00= co3[0]-co1[0]; t01= co3[1]-co1[1]; @@ -414,10 +431,19 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) if(RayObject_isRayFace(r)) { RayFace *face = (RayFace*) RayObject_align(r); + +#ifdef RE_RAYFACE_COORDS_VLAKREN + VlakRen *vlr = (VlakRen*)face->face; + DO_MINMAX( vlr->v1->co, min, max ); + DO_MINMAX( vlr->v2->co, min, max ); + DO_MINMAX( vlr->v3->co, min, max ); + if(RE_rayface_isQuad(face)) DO_MINMAX( vlr->v4->co, min, max ); +#else DO_MINMAX( face->v1, min, max ); DO_MINMAX( face->v2, min, max ); DO_MINMAX( face->v3, min, max ); if(RE_rayface_isQuad(face)) DO_MINMAX( face->v4, min, max ); +#endif } else if(RayObject_isRayAPI(r)) { diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index 88ea2bb38ed..da1083a654d 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -489,11 +489,22 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) ocres2= oc->ocres*oc->ocres; +#ifdef RE_RAYFACE_COORDS_VLAKREN + { + VlakRen *vlr = (VlakRen*)face->face; + VECCOPY(co1, vlr->v1->co); + VECCOPY(co2, vlr->v2->co); + VECCOPY(co3, vlr->v3->co); + if(RE_rayface_isQuad(face)) + VECCOPY(co4, vlr->v4->co); + } +#else VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); VECCOPY(co3, face->v3); if(face->v4) VECCOPY(co4, face->v4); +#endif for(c=0;c<3;c++) { rtf[0][c]= (co1[c]-oc->min[c])*ocfac[c] ; @@ -502,7 +513,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) rts[1][c]= (short)rtf[1][c]; rtf[2][c]= (co3[c]-oc->min[c])*ocfac[c] ; rts[2][c]= (short)rtf[2][c]; - if(face->v4) { + if(RE_rayface_isQuad(face)) { rtf[3][c]= (co4[c]-oc->min[c])*ocfac[c] ; rts[3][c]= (short)rtf[3][c]; } @@ -512,7 +523,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) oc1= rts[0][c]; oc2= rts[1][c]; oc3= rts[2][c]; - if(face->v4==NULL) { + if(!RE_rayface_isQuad(face)) { ocmin[c]= MIN3(oc1,oc2,oc3); ocmax[c]= MAX3(oc1,oc2,oc3); } @@ -526,7 +537,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) } if(ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) { - ocwrite(oc, face, (face->v4 != NULL), ocmin[0], ocmin[1], ocmin[2], rtf); + ocwrite(oc, face, RE_rayface_isQuad(face), ocmin[0], ocmin[1], ocmin[2], rtf); } else { @@ -536,7 +547,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) d2dda(oc, 1,2,0,1,ocface+ocres2,rts,rtf); d2dda(oc, 1,2,0,2,ocface,rts,rtf); d2dda(oc, 1,2,1,2,ocface+2*ocres2,rts,rtf); - if(face->v4==NULL) { + if(!RE_rayface_isQuad(face)) { d2dda(oc, 2,0,0,1,ocface+ocres2,rts,rtf); d2dda(oc, 2,0,0,2,ocface,rts,rtf); d2dda(oc, 2,0,1,2,ocface+2*ocres2,rts,rtf); @@ -565,7 +576,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) for(z=ocmin[2];z<=ocmax[2];z++) { if(ocface[b+z] && ocface[a+z]) { if(face_in_node(NULL, x, y, z, rtf)) - ocwrite(oc, face, (face->v4 != NULL), x,y,z, rtf); + ocwrite(oc, face, RE_rayface_isQuad(face), x,y,z, rtf); } } } -- cgit v1.2.3 From f7179efde35689ad915948298fe905e36704c126 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 5 Aug 2009 21:09:41 +0000 Subject: no need to calculate the exact nearest distance if we are not using any heuristic based on that --- source/blender/render/intern/include/rayobject.h | 3 +- source/blender/render/intern/raytrace/bvh.h | 43 +++++++++++++++++++++++- source/blender/render/intern/source/rayobject.c | 22 ++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 8f0dbed3176..2c63c8ceae9 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -164,7 +164,8 @@ int RE_rayobject_intersect(RayObject *r, Isect *i); * Returns distance ray must travel to hit the given bounding box * BB should be in format [2][3] */ -float RE_rayobject_bb_intersect(const Isect *i, const float *bb); +/* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */ +int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */ /* * Returns the expected cost of raycast on this node, primitives have a cost of 1 diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 8f7e6111684..56bb907acfc 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -26,6 +26,47 @@ * * ***** END GPL LICENSE BLOCK ***** */ +/* +template +struct BBGroup +{ + float bb[6][SIZE]; +}; + + +static inline int test_bb_group(BBGroup<4> *bb_group, Isect *isec) +{ + const float *bb = _bb; + __m128 tmin={0}, tmax = {isec->labda}; + + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[0]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[1]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[2]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[3]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[4]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[5]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); + + return _mm_movemask_ps(_mm_cmpge_ps(tmax, tmin)); +} + +static inline int test_bb_group(BBGroup<1> *bb_group, Isect *isec) +{ + float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; + float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; + float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; + float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; + float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; + float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; + + RE_RC_COUNT(isec->raycounter->bb.test); + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; + if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; + if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0; + + RE_RC_COUNT(isec->raycounter->bb.hit); + return 1; +} +*/ /* bvh tree generics */ template static int bvh_intersect(Tree *obj, Isect *isec); @@ -68,7 +109,7 @@ static float bvh_cost(Tree *obj) /* bvh tree nodes generics */ template static inline int bvh_node_hit_test(Node *node, Isect *isec) { - return RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX; + return RE_rayobject_bb_intersect_test(isec, (const float*)node->bb); } diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 7316120e477..5639080c406 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -42,6 +42,7 @@ * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] */ +/* float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb) { const float *bb = _bb; @@ -67,6 +68,27 @@ float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb) if (t1z > dist) dist = t1z; return dist; } +*/ +int RE_rayobject_bb_intersect_test(const Isect *isec, const float *_bb) +{ + const float *bb = _bb; + + float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; + float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; + float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; + float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; + float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; + float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; + + RE_RC_COUNT(isec->raycounter->bb.test); + + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; + if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; + if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0; + RE_RC_COUNT(isec->raycounter->bb.hit); + + return 1; +} /* only for self-intersecting test with current render face (where ray left) */ -- cgit v1.2.3 From 01eedc504656b065dc9d17751016913906afe4d5 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 6 Aug 2009 12:22:50 +0000 Subject: - OBJ importer now reads most of the test files. Had to copy BPyMesh.ngon function to OBJ import code - added MeshEdge.fgon property, not using it yet - fixed in bpy_rna.c to correctly read arrays returned from RNA functions --- release/io/export_fbx.py | 2 +- release/io/export_obj.py | 5 +- release/io/import_obj.py | 311 ++++++++++++++++++++----- source/blender/makesrna/intern/rna_image_api.c | 2 +- source/blender/makesrna/intern/rna_mesh.c | 5 + source/blender/python/intern/bpy_rna.c | 4 + 6 files changed, 273 insertions(+), 56 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index ad9b3caa13a..5bb169a9849 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -1326,7 +1326,7 @@ def write(filename, batch_objects = None, \ def copy_image(image): rel = image.get_export_path(basepath, True) - base = os.path.basename(fname_rel) + base = os.path.basename(rel) if EXP_IMAGE_COPY: src = bpy.sys.expandpath(image.filename) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index 1209e10afe3..fa07c5408a7 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -120,7 +120,10 @@ def write_mtl(scene, filename, copy_images): file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour, file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_reflection for c in mat.diffuse_color]) ) # Diffuse file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_reflection for c in mat.specular_color]) ) # Specular - file.write('Ni %.6f\n' % mat.ior) # Refraction index + if hasattr(mat, "ior"): + file.write('Ni %.6f\n' % mat.ior) # Refraction index + else: + file.write('Ni %.6f\n' % 1.0) file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. diff --git a/release/io/import_obj.py b/release/io/import_obj.py index 2a5d92969af..f064561a512 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -40,9 +40,12 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -import bpy import os +import bpy +import Mathutils +import Geometry + # from Blender import Mesh, Draw, Window, Texture, Material, sys # # import BPyMesh # import BPyImage @@ -84,12 +87,196 @@ def unpack_face_list(list_of_tuples): l = [] for t in list_of_tuples: face = [i for i in t] - if len(face) > 4: - raise RuntimeError("More than 4 vertices per face.") - if len(face) == 3: face.append(0) + if len(face) != 3 and len(face) != 4: + raise RuntimeError("{0} vertices in face.".format(len(face))) + if len(face) == 3: + face.append(0) l.extend(face) return l +def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True): + ''' + Takes a polyline of indices (fgon) + and returns a list of face indicie lists. + Designed to be used for importers that need indices for an fgon to create from existing verts. + + from_data: either a mesh, or a list/tuple of vectors. + indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given. + PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. + ''' + + if not set: # Need sets for this, otherwise do a normal fill. + PREF_FIX_LOOPS= False + + Vector= Mathutils.Vector + if not indices: + return [] + + # return [] + def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6) + def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length + + def vert_treplet(v, i): + return v, rvec(v), i, mlen(v) + + def ed_key_mlen(v1, v2): + if v1[3] > v2[3]: + return v2[1], v1[1] + else: + return v1[1], v2[1] + + + if not PREF_FIX_LOOPS: + ''' + Normal single concave loop filling + ''' + if type(from_data) in (tuple, list): + verts= [Vector(from_data[i]) for ii, i in enumerate(indices)] + else: + verts= [from_data.verts[i].co for ii, i in enumerate(indices)] + + for i in range(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))): + if verts[i][1]==verts[i-1][0]: + verts.pop(i-1) + + fill= Geometry.PolyFill([verts]) + + else: + ''' + Seperate this loop into multiple loops be finding edges that are used twice + This is used by lightwave LWO files a lot + ''' + + if type(from_data) in (tuple, list): + verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)] + else: + verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)] + + edges= [(i, i-1) for i in range(len(verts))] + if edges: + edges[0]= (0,len(verts)-1) + + if not verts: + return [] + + + edges_used= set() + edges_doubles= set() + # We need to check if any edges are used twice location based. + for ed in edges: + edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]]) + if edkey in edges_used: + edges_doubles.add(edkey) + else: + edges_used.add(edkey) + + # Store a list of unconnected loop segments split by double edges. + # will join later + loop_segments= [] + + v_prev= verts[0] + context_loop= [v_prev] + loop_segments= [context_loop] + + for v in verts: + if v!=v_prev: + # Are we crossing an edge we removed? + if ed_key_mlen(v, v_prev) in edges_doubles: + context_loop= [v] + loop_segments.append(context_loop) + else: + if context_loop and context_loop[-1][1]==v[1]: + #raise "as" + pass + else: + context_loop.append(v) + + v_prev= v + # Now join loop segments + + def join_seg(s1,s2): + if s2[-1][1]==s1[0][1]: # + s1,s2= s2,s1 + elif s1[-1][1]==s2[0][1]: + pass + else: + return False + + # If were stuill here s1 and s2 are 2 segments in the same polyline + s1.pop() # remove the last vert from s1 + s1.extend(s2) # add segment 2 to segment 1 + + if s1[0][1]==s1[-1][1]: # remove endpoints double + s1.pop() + + s2[:]= [] # Empty this segment s2 so we dont use it again. + return True + + joining_segments= True + while joining_segments: + joining_segments= False + segcount= len(loop_segments) + + for j in range(segcount-1, -1, -1): #reversed(range(segcount)): + seg_j= loop_segments[j] + if seg_j: + for k in range(j-1, -1, -1): # reversed(range(j)): + if not seg_j: + break + seg_k= loop_segments[k] + + if seg_k and join_seg(seg_j, seg_k): + joining_segments= True + + loop_list= loop_segments + + for verts in loop_list: + while verts and verts[0][1]==verts[-1][1]: + verts.pop() + + loop_list= [verts for verts in loop_list if len(verts)>2] + # DONE DEALING WITH LOOP FIXING + + + # vert mapping + vert_map= [None]*len(indices) + ii=0 + for verts in loop_list: + if len(verts)>2: + for i, vert in enumerate(verts): + vert_map[i+ii]= vert[2] + ii+=len(verts) + + fill= Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ]) + #draw_loops(loop_list) + #raise 'done loop' + # map to original indicies + fill= [[vert_map[i] for i in reversed(f)] for f in fill] + + + if not fill: + print('Warning Cannot scanfill, fallback on a triangle fan.') + fill= [ [0, i-1, i] for i in range(2, len(indices)) ] + else: + # Use real scanfill. + # See if its flipped the wrong way. + flip= None + for fi in fill: + if flip != None: + break + for i, vi in enumerate(fi): + if vi==0 and fi[i-1]==1: + flip= False + break + elif vi==1 and fi[i-1]==0: + flip= True + break + + if not flip: + for i, fi in enumerate(fill): + fill[i]= tuple([ii for ii in reversed(fi)]) + + return fill def line_value(line_split): ''' @@ -388,7 +575,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, # remove one of the itemas and reorder - return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.items()] + return [(value[0], value[1], value[2], key_to_name(key)) for key, value in list(face_split_dict.items())] def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): @@ -401,7 +588,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l if unique_smooth_groups: sharp_edges= {} - smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.keys() ]) + smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in list(unique_smooth_groups.keys()) ]) context_smooth_group_old= -1 # Split fgons into tri's @@ -452,45 +639,45 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l edge_dict[i1,i2]= 1 # FGons into triangles -# if has_ngons and len_face_vert_loc_indicies > 4: + if has_ngons and len_face_vert_loc_indicies > 4: -# ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies) -# faces.extend(\ -# [(\ -# [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ -# [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ -# context_material,\ -# context_smooth_group,\ -# context_object)\ -# for ngon in ngon_face_indices]\ -# ) + ngon_face_indices= BPyMesh_ngon(verts_loc, face_vert_loc_indicies) + faces.extend(\ + [(\ + [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ + [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ + context_material,\ + context_smooth_group,\ + context_object)\ + for ngon in ngon_face_indices]\ + ) -# # edges to make fgons -# if CREATE_FGONS: -# edge_users= {} -# for ngon in ngon_face_indices: -# for i in (0,1,2): -# i1= face_vert_loc_indicies[ngon[i ]] -# i2= face_vert_loc_indicies[ngon[i-1]] -# if i1>i2: i1,i2= i2,i1 + # edges to make fgons + if CREATE_FGONS: + edge_users= {} + for ngon in ngon_face_indices: + for i in (0,1,2): + i1= face_vert_loc_indicies[ngon[i ]] + i2= face_vert_loc_indicies[ngon[i-1]] + if i1>i2: i1,i2= i2,i1 -# try: -# edge_users[i1,i2]+=1 -# except KeyError: -# edge_users[i1,i2]= 1 + try: + edge_users[i1,i2]+=1 + except KeyError: + edge_users[i1,i2]= 1 -# for key, users in edge_users.iteritems(): -# if users>1: -# fgon_edges[key]= None + for key, users in edge_users.items(): + if users>1: + fgon_edges[key]= None -# # remove all after 3, means we dont have to pop this one. -# faces.pop(f_idx) + # remove all after 3, means we dont have to pop this one. + faces.pop(f_idx) # Build sharp edges if unique_smooth_groups: - for edge_dict in smooth_group_users.values(): - for key, users in edge_dict.items(): + for edge_dict in list(smooth_group_users.values()): + for key, users in list(edge_dict.items()): if users==1: # This edge is on the boundry of a group sharp_edges[key]= None @@ -500,7 +687,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l materials= [None] * len(unique_materials) - for name, index in material_mapping.items(): + for name, index in list(material_mapping.items()): materials[index]= unique_materials[name] me= bpy.data.add_mesh(dataname) @@ -607,36 +794,54 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l # uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]] del me_faces # del ALPHA + + if CREATE_EDGES: + + me.add_geometry(0, len(edges), 0) + + # edges should be a list of (a, b) tuples + me.edges.foreach_set("verts", unpack_list(edges)) +# me_edges.extend( edges ) + +# del me_edges # Add edge faces. - me_edges= me.edges +# me_edges= me.edges + + def edges_match(e1, e2): + return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0]) + + # XXX slow +# if CREATE_FGONS and fgon_edges: +# for fgon_edge in fgon_edges.keys(): +# for ed in me.edges: +# if edges_match(fgon_edge, ed.verts): +# ed.fgon = True + # if CREATE_FGONS and fgon_edges: # FGON= Mesh.EdgeFlags.FGON # for ed in me.findEdges( fgon_edges.keys() ): # if ed!=None: # me_edges[ed].flag |= FGON # del FGON - + + # XXX slow +# if unique_smooth_groups and sharp_edges: +# for sharp_edge in sharp_edges.keys(): +# for ed in me.edges: +# if edges_match(sharp_edge, ed.verts): +# ed.sharp = True + # if unique_smooth_groups and sharp_edges: # SHARP= Mesh.EdgeFlags.SHARP # for ed in me.findEdges( sharp_edges.keys() ): # if ed!=None: # me_edges[ed].flag |= SHARP # del SHARP - - if CREATE_EDGES: - - me.add_geometry(0, len(edges), 0) - - # edges should be a list of (a, b) tuples - me.edges.foreach_set("verts", unpack_list(edges)) -# me_edges.extend( edges ) - -# del me_edges me.update() # me.calcNormals() - + ob= bpy.data.add_object("MESH", "Mesh") ob.data= me scn.add_object(ob) @@ -823,7 +1028,7 @@ def load_obj(filepath, # so we need to know weather context_multi_line= '' - print('\tparsing obj file "%s"...' % filepath, end=' ') + print('\tparsing obj file "%s"...' % filepath) time_sub= bpy.sys.time() # time_sub= sys.time() @@ -1039,7 +1244,7 @@ def load_obj(filepath, time_sub= time_new - print('\tloading materials and images...', end=' ') + print('\tloading materials and images...') create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) time_new= bpy.sys.time() @@ -1059,7 +1264,7 @@ def load_obj(filepath, # scn.objects.selected = [] new_objects= [] # put new objects here - print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), end=' ') + print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) )) # Split the mesh by objects/materials, may if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True else: SPLIT_OB_OR_GROUP = False diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index af059b435b3..ccc9846600d 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -66,7 +66,7 @@ void RNA_api_image(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; - func= RNA_def_function(srna, "export", "rna_Image_get_export_path"); + func= RNA_def_function(srna, "get_export_path", "rna_Image_get_export_path"); RNA_def_function_ui_description(func, "Produce image export path."); parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory."); RNA_def_property_flag(parm, PROP_REQUIRED); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index dba5a0622c3..dc953f80804 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -877,6 +877,11 @@ static void rna_def_medge(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_LOOSEEDGE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Loose", "Loose edge"); + + prop= RNA_def_property(srna, "fgon", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FGON); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Fgon", "Fgon edge"); } static void rna_def_mface(BlenderRNA *brna) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 27bfb89b963..ded07d545ef 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1801,6 +1801,10 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) /* resolve the array from a new pytype */ ret = PyTuple_New(len); + /* for return values, data is a pointer to an array, not first element pointer */ + if (prop->flag & PROP_DYNAMIC_ARRAY) + data = *((char**)data) + switch (type) { case PROP_BOOLEAN: for(a=0; a Date: Thu, 6 Aug 2009 17:45:51 +0000 Subject: *Process leafs as soon as found instead of pushing them on stack for later evaluation (leads to early exits) (this is mixed with some simd code commit, althouth no simd is being used up to the moment) --- source/blender/render/intern/raytrace/bvh.h | 144 ++++++++++++++++----- .../render/intern/raytrace/rayobject_vbvh.cpp | 38 +++++- 2 files changed, 145 insertions(+), 37 deletions(-) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 56bb907acfc..0f40ab5a408 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -26,47 +26,24 @@ * * ***** END GPL LICENSE BLOCK ***** */ -/* -template -struct BBGroup -{ - float bb[6][SIZE]; -}; - +#include -static inline int test_bb_group(BBGroup<4> *bb_group, Isect *isec) +inline int test_bb_group4(__m128 *bb_group, Isect *isec) { +/* const float *bb = _bb; __m128 tmin={0}, tmax = {isec->labda}; - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[0]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[1]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[2]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[3]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[4]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( group->bb[isec->bv_index[5]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); - - return _mm_movemask_ps(_mm_cmpge_ps(tmax, tmin)); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[0]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[1]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[2]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[3]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[4]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[5]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); + */ + return 4; //_mm_movemask_ps(_mm_cmpge_ps(tmax, tmin)); } -static inline int test_bb_group(BBGroup<1> *bb_group, Isect *isec) -{ - float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; - float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; - float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; - float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; - float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; - float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; - - RE_RC_COUNT(isec->raycounter->bb.test); - if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; - if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; - if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0; - - RE_RC_COUNT(isec->raycounter->bb.hit); - return 1; -} -*/ /* bvh tree generics */ template static int bvh_intersect(Tree *obj, Isect *isec); @@ -163,9 +140,108 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) } } return hit; +} + + +/* + * Generic SIMD bvh recursion + * this was created to be able to use any simd (with the cost of some memmoves) + * it can take advantage of any SIMD width and doens't needs any special tree care + */ +template +static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) +{ + Node *stack[MAX_STACK_SIZE]; + __m128 t_bb[6]; + Node * t_node[4]; + int hit = 0, stack_pos = 0; + + if(!TEST_ROOT) + { + if(RayObject_isAligned(root)) + { + if(RayObject_isAligned(root->child)) + bvh_node_push_childs(root, isec, stack, stack_pos); + else + return RE_rayobject_intersect( (RayObject*)root->child, isec); + } + else + return RE_rayobject_intersect( (RayObject*)root, isec); + } + else + { + if(RayObject_isAligned(root)) + stack[stack_pos++] = root; + else + return RE_rayobject_intersect( (RayObject*)root, isec); + } + + while(true) + { + //Use SIMD 4 + if(0 && stack_pos >= 4) + { + stack_pos -= 4; + for(int i=0; i<4; i++) + { + Node *t = stack[stack_pos+i]; + assert(RayObject_isAligned(t)); + + float *bb = ((float*)t_bb)+i; + bb[4*0] = t->bb[0]; + bb[4*1] = t->bb[1]; + bb[4*2] = t->bb[2]; + bb[4*3] = t->bb[3]; + bb[4*4] = t->bb[4]; + bb[4*5] = t->bb[5]; + t_node[i] = t->child; + } + int res = test_bb_group4( t_bb, isec ); + + for(int i=0; i<4; i++) + if(res & (1<sibling) + { + assert(stack_pos < MAX_STACK_SIZE); + stack[stack_pos++] = t; + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)t_node[i], isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + } + else if(stack_pos > 0) + { + Node *node = stack[--stack_pos]; + assert(RayObject_isAligned(node)); + + if(bvh_node_hit_test(node,isec)) + { + if(RayObject_isAligned(node->child)) + { + bvh_node_push_childs(node, isec, stack, stack_pos); + assert(stack_pos <= MAX_STACK_SIZE); + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node->child, isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + } + else break; + } + return hit; } + /* * recursively transverse a BVH looking for a rayhit using system stack */ diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index e8bc59641d7..9a67f490aeb 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -48,7 +48,7 @@ extern "C" #define RAY_BB_TEST_COST (0.2f) #define DFS_STACK_SIZE 256 -#define DYNAMIC_ALLOC +//#define DYNAMIC_ALLOC_BB //#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ //#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ @@ -59,7 +59,11 @@ struct BVHNode BVHNode *child; BVHNode *sibling; +#ifdef DYNAMIC_ALLOC_BB + float *bb; +#else float bb[6]; +#endif }; struct BVHTree @@ -92,9 +96,11 @@ inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, i while(child) { //Skips BB tests on primitives +/* if(!RayObject_isAligned(child->child)) stack[stack_pos++] = child->child; else +*/ stack[stack_pos++] = child; child = child->sibling; @@ -111,6 +117,9 @@ static BVHNode *bvh_new_node(BVHTree *tree) node->sibling = NULL; node->child = NULL; +#ifdef DYNAMIC_ALLOC_BB + node->bb = (float*)BLI_memarena_alloc(tree->node_arena, 6*sizeof(float)); +#endif assert(RayObject_isAligned(node)); return node; } @@ -275,6 +284,28 @@ Node *bvh_rearrange(Tree *tree, Builder *builder) } } +template +float bvh_refit(Node *node) +{ + if(RayObject_isAligned(node)) return 0; + if(RayObject_isAligned(node->child)) return 0; + + float total = 0; + + for(Node *child = node->child; RayObject_isAligned(child) && child; child = child->sibling) + total += bvh_refit(child); + + float old_area = bb_area(node->bb, node->bb+3); + INIT_MINMAX(node->bb, node->bb+3); + for(Node *child = node->child; RayObject_isAligned(child) && child; child = child->sibling) + { + DO_MIN(child->bb, node->bb); + DO_MIN(child->bb+3, node->bb+3); + } + total += old_area - bb_area(node->bb, node->bb+3); + return total; +} + template<> void bvh_done(BVHTree *obj) { @@ -292,6 +323,7 @@ void bvh_done(BVHTree *obj) reorganize(obj->root); remove_useless(obj->root, &obj->root); pushup(obj->root); + printf("refit: %f\n", bvh_refit(obj->root) ); pushdown(obj->root); // obj->root = memory_rearrange(obj->root); obj->cost = 1.0; @@ -313,7 +345,7 @@ int intersect(BVHTree *obj, Isect* isec) { BVHNode *node = (BVHNode*)lcts->stack[i]; if(RayObject_isAligned(node)) - hit |= bvh_node_stack_raycast(node, isec); + hit |= bvh_node_stack_raycast_simd(node, isec); else hit |= RE_rayobject_intersect( (RayObject*)node, isec ); @@ -326,7 +358,7 @@ int intersect(BVHTree *obj, Isect* isec) else { if(RayObject_isAligned(obj->root)) - return bvh_node_stack_raycast(obj->root, isec); + return bvh_node_stack_raycast_simd(obj->root, isec); else return RE_rayobject_intersect( (RayObject*) obj->root, isec ); } -- cgit v1.2.3 From 4bc9ebd61f6a05532c59741073d2565fc4d6a8c7 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 6 Aug 2009 20:20:40 +0000 Subject: usage of simd on bb tests --- source/blender/render/intern/raytrace/bvh.h | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 0f40ab5a408..50cdca4193d 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -28,20 +28,20 @@ */ #include -inline int test_bb_group4(__m128 *bb_group, Isect *isec) +inline int test_bb_group4(__m128 *bb_group, __m128 *start, __m128 *idot_axis, Isect *isec) { -/* - const float *bb = _bb; - __m128 tmin={0}, tmax = {isec->labda}; + + __m128 tmin = _mm_setzero_ps(); + __m128 tmax = _mm_load1_ps(&isec->labda); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[0]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[1]], isec->sse_start[0] ), isec->sse_idot_axis[0]) ); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[2]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[3]], isec->sse_start[1] ), isec->sse_idot_axis[1]) ); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[4]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[5]], isec->sse_start[2] ), isec->sse_idot_axis[2]) ); - */ - return 4; //_mm_movemask_ps(_mm_cmpge_ps(tmax, tmin)); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[0]], start[0] ), idot_axis[0]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[1]], start[0] ), idot_axis[0]) ); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[2]], start[1] ), idot_axis[1]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[3]], start[1] ), idot_axis[1]) ); + tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[4]], start[2] ), idot_axis[2]) ); + tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[5]], start[2] ), idot_axis[2]) ); + + return _mm_movemask_ps(_mm_cmpge_ps(tmax, tmin)); } @@ -151,6 +151,9 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) template static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) { + __m128 idot_axis[3] = { _mm_load1_ps(&isec->idot_axis[0]), _mm_load1_ps(&isec->idot_axis[1]), _mm_load1_ps(&isec->idot_axis[2]) }; + __m128 start[3] = { _mm_load1_ps(&isec->start[0]), _mm_load1_ps(&isec->start[1]), _mm_load1_ps(&isec->start[2]) }; + Node *stack[MAX_STACK_SIZE]; __m128 t_bb[6]; Node * t_node[4]; @@ -180,7 +183,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) while(true) { //Use SIMD 4 - if(0 && stack_pos >= 4) + if(stack_pos >= 4) { stack_pos -= 4; for(int i=0; i<4; i++) @@ -197,7 +200,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) bb[4*5] = t->bb[5]; t_node[i] = t->child; } - int res = test_bb_group4( t_bb, isec ); + int res = test_bb_group4( t_bb, start, idot_axis, isec ); for(int i=0; i<4; i++) if(res & (1< Date: Fri, 7 Aug 2009 00:51:41 +0000 Subject: improved SIMD on raytrace (up to the moment support of SIMD is done at dfs and on any type of tree) (it only shows worth on -O3 -msse2) because it seems gcc makes horrible asm code on -O2 --- source/blender/render/intern/raytrace/bvh.h | 56 +++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 50cdca4193d..52d361e707b 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -28,20 +28,20 @@ */ #include -inline int test_bb_group4(__m128 *bb_group, __m128 *start, __m128 *idot_axis, Isect *isec) +inline int test_bb_group4(__m128 *bb_group, __m128 *start, __m128 *idot_axis, const Isect *isec) { - __m128 tmin = _mm_setzero_ps(); - __m128 tmax = _mm_load1_ps(&isec->labda); - - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[0]], start[0] ), idot_axis[0]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[1]], start[0] ), idot_axis[0]) ); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[2]], start[1] ), idot_axis[1]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[3]], start[1] ), idot_axis[1]) ); - tmin = _mm_max_ps(tmin, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[4]], start[2] ), idot_axis[2]) ); - tmax = _mm_min_ps(tmax, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[5]], start[2] ), idot_axis[2]) ); + const __m128 tmin0 = _mm_setzero_ps(); + const __m128 tmax0 = _mm_load1_ps(&isec->labda); + + const __m128 tmin1 = _mm_max_ps(tmin0, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[0]], _mm_load1_ps(&isec->start[0]) ), _mm_load1_ps(&isec->idot_axis[0])) ); + const __m128 tmax1 = _mm_min_ps(tmax0, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[1]], _mm_load1_ps(&isec->start[0]) ), _mm_load1_ps(&isec->idot_axis[0])) ); + const __m128 tmin2 = _mm_max_ps(tmin1, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[2]], _mm_load1_ps(&isec->start[1]) ), _mm_load1_ps(&isec->idot_axis[1])) ); + const __m128 tmax2 = _mm_min_ps(tmax1, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[3]], _mm_load1_ps(&isec->start[1]) ), _mm_load1_ps(&isec->idot_axis[1])) ); + const __m128 tmin3 = _mm_max_ps(tmin2, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[4]], _mm_load1_ps(&isec->start[2]) ), _mm_load1_ps(&isec->idot_axis[2])) ); + const __m128 tmax3 = _mm_min_ps(tmax2, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[5]], _mm_load1_ps(&isec->start[2]) ), _mm_load1_ps(&isec->idot_axis[2])) ); - return _mm_movemask_ps(_mm_cmpge_ps(tmax, tmin)); + return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3)); } @@ -155,8 +155,6 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) __m128 start[3] = { _mm_load1_ps(&isec->start[0]), _mm_load1_ps(&isec->start[1]), _mm_load1_ps(&isec->start[2]) }; Node *stack[MAX_STACK_SIZE]; - __m128 t_bb[6]; - Node * t_node[4]; int hit = 0, stack_pos = 0; @@ -185,8 +183,37 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) //Use SIMD 4 if(stack_pos >= 4) { + __m128 t_bb[6]; + Node * t_node[4]; + stack_pos -= 4; - for(int i=0; i<4; i++) + + t_node[0] = stack[stack_pos+0]->child; + t_node[1] = stack[stack_pos+1]->child; + t_node[2] = stack[stack_pos+2]->child; + t_node[3] = stack[stack_pos+3]->child; + + const float *bb0 = stack[stack_pos+0]->bb; + const float *bb1 = stack[stack_pos+1]->bb; + const float *bb2 = stack[stack_pos+2]->bb; + const float *bb3 = stack[stack_pos+3]->bb; + + const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(0,1,0,1) ); + const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(0,1,0,1) ); + t_bb[0] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(0,2,0,2) ); + t_bb[1] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(1,3,1,3) ); + + const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+2), _mm_loadu_ps(bb1+2), _MM_SHUFFLE(0,1,0,1) ); + const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+2), _mm_loadu_ps(bb3+2), _MM_SHUFFLE(0,1,0,1) ); + t_bb[2] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(0,2,0,2) ); + t_bb[3] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(1,3,1,3) ); + + const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(0,1,0,1) ); + const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(0,1,0,1) ); + t_bb[4] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(0,2,0,2) ); + t_bb[5] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(1,3,1,3) ); + +/* for(int i=0; i<4; i++) { Node *t = stack[stack_pos+i]; assert(RayObject_isAligned(t)); @@ -200,6 +227,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) bb[4*5] = t->bb[5]; t_node[i] = t->child; } + */ int res = test_bb_group4( t_bb, start, idot_axis, isec ); for(int i=0; i<4; i++) -- cgit v1.2.3 From 20c9f2e8abf5d81e5b8a340b12ff8f6f66eee2ca Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 7 Aug 2009 01:42:51 +0000 Subject: Fix _MM_SHUFFLE_ order --- source/blender/render/intern/raytrace/bvh.h | 50 ++++++++++++++++------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 52d361e707b..b17a072f3a6 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -28,7 +28,7 @@ */ #include -inline int test_bb_group4(__m128 *bb_group, __m128 *start, __m128 *idot_axis, const Isect *isec) +inline int test_bb_group4(__m128 *bb_group, const Isect *isec) { const __m128 tmin0 = _mm_setzero_ps(); @@ -151,9 +151,6 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) template static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) { - __m128 idot_axis[3] = { _mm_load1_ps(&isec->idot_axis[0]), _mm_load1_ps(&isec->idot_axis[1]), _mm_load1_ps(&isec->idot_axis[2]) }; - __m128 start[3] = { _mm_load1_ps(&isec->start[0]), _mm_load1_ps(&isec->start[1]), _mm_load1_ps(&isec->start[2]) }; - Node *stack[MAX_STACK_SIZE]; int hit = 0, stack_pos = 0; @@ -187,7 +184,8 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) Node * t_node[4]; stack_pos -= 4; - + + /* prepare the 4BB for SIMD */ t_node[0] = stack[stack_pos+0]->child; t_node[1] = stack[stack_pos+1]->child; t_node[2] = stack[stack_pos+2]->child; @@ -198,22 +196,22 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) const float *bb2 = stack[stack_pos+2]->bb; const float *bb3 = stack[stack_pos+3]->bb; - const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(0,1,0,1) ); - const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(0,1,0,1) ); - t_bb[0] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(0,2,0,2) ); - t_bb[1] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(1,3,1,3) ); - - const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+2), _mm_loadu_ps(bb1+2), _MM_SHUFFLE(0,1,0,1) ); - const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+2), _mm_loadu_ps(bb3+2), _MM_SHUFFLE(0,1,0,1) ); - t_bb[2] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(0,2,0,2) ); - t_bb[3] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(1,3,1,3) ); - - const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(0,1,0,1) ); - const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(0,1,0,1) ); - t_bb[4] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(0,2,0,2) ); - t_bb[5] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(1,3,1,3) ); - -/* for(int i=0; i<4; i++) + const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(1,0,1,0) ); + const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(1,0,1,0) ); + t_bb[0] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ); + t_bb[1] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ); + + const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+2), _mm_loadu_ps(bb1+2), _MM_SHUFFLE(1,0,1,0) ); + const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+2), _mm_loadu_ps(bb3+2), _MM_SHUFFLE(1,0,1,0) ); + t_bb[2] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ); + t_bb[3] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ); + + const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(1,0,1,0) ); + const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(1,0,1,0) ); + t_bb[4] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2,0,2,0) ); + t_bb[5] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3,1,3,1) ); +/* + for(int i=0; i<4; i++) { Node *t = stack[stack_pos+i]; assert(RayObject_isAligned(t)); @@ -227,12 +225,18 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) bb[4*5] = t->bb[5]; t_node[i] = t->child; } - */ - int res = test_bb_group4( t_bb, start, idot_axis, isec ); +*/ + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + + int res = test_bb_group4( t_bb, isec ); for(int i=0; i<4; i++) if(res & (1<raycounter->bb.hit); if(RayObject_isAligned(t_node[i])) { for(Node *t=t_node[i]; t; t=t->sibling) -- cgit v1.2.3 From 3c3f8c3018d369ef72a05c93ed1171f887704c05 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Fri, 7 Aug 2009 13:00:39 +0000 Subject: bpyrna: interpret a tuple of enum items (e1, e2, ...) as a bitmask (e1 | e2 | ...). --- source/blender/python/intern/bpy_rna.c | 63 +++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index ded07d545ef..54d7b812fe1 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -33,6 +33,7 @@ #include "RNA_access.h" #include "RNA_define.h" /* for defining our own rna */ +#include "rna_internal_types.h" #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" @@ -241,6 +242,27 @@ static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) return result; } +static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix) +{ + char *param= _PyUnicode_AsString(item); + + if (param==NULL) { + char *enum_str= pyrna_enum_as_string(ptr, prop); + PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str); + MEM_freeN(enum_str); + return 0; + } else { + if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) { + char *enum_str= pyrna_enum_as_string(ptr, prop); + PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str); + MEM_freeN(enum_str); + return 0; + } + } + + return 1; +} + PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) { PyObject *ret; @@ -641,25 +663,34 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v } case PROP_ENUM: { - char *param = _PyUnicode_AsString(value); - - if (param==NULL) { + int val, i; + + if (PyUnicode_Check(value)) { + if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix)) + return -1; + } + else if (PyTuple_Check(value)) { + /* tuple of enum items, concatenate all values with OR */ + val= 0; + for (i= 0; i < PyTuple_Size(value); i++) { + int tmpval; + + /* PyTuple_GET_ITEM returns a borrowed reference */ + if (!pyrna_string_to_enum(PyTuple_GET_ITEM(value, i), ptr, prop, &tmpval, error_prefix)) + return -1; + + val |= tmpval; + } + } + else { char *enum_str= pyrna_enum_as_string(ptr, prop); - PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str); + PyErr_Format(PyExc_TypeError, "%.200s expected a string enum or a tuple of strings in (%.200s)", error_prefix, enum_str); MEM_freeN(enum_str); return -1; - } else { - int val; - if (RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, &val)) { - if(data) *((int*)data)= val; - else RNA_property_enum_set(ptr, prop, val); - } else { - char *enum_str= pyrna_enum_as_string(ptr, prop); - PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str); - MEM_freeN(enum_str); - return -1; - } } + + if(data) *((int*)data)= val; + else RNA_property_enum_set(ptr, prop, val); break; } @@ -1803,7 +1834,7 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) /* for return values, data is a pointer to an array, not first element pointer */ if (prop->flag & PROP_DYNAMIC_ARRAY) - data = *((char**)data) + data = *(char**)(char*)data; switch (type) { case PROP_BOOLEAN: -- cgit v1.2.3 From 51cad12120a673959abfbb1d4445edb782b5f13b Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 7 Aug 2009 13:49:15 +0000 Subject: *BLI_memarena support for any power of two alignment *some simd stuff on bvh --- source/blender/blenlib/BLI_memarena.h | 2 ++ source/blender/blenlib/intern/BLI_memarena.c | 23 ++++++++++++++++++++-- source/blender/render/intern/raytrace/bvh.h | 12 +++++------ .../render/intern/raytrace/rayobject_vbvh.cpp | 13 +++++++++--- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index 4b955e9fa20..fcf6ae02900 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -57,6 +57,8 @@ void BLI_memarena_free (struct MemArena *ma); void BLI_memarena_use_malloc (struct MemArena *ma); void BLI_memarena_use_calloc (struct MemArena *ma); +void BLI_memarena_use_align(struct MemArena *ma, int align); + void* BLI_memarena_alloc (struct MemArena *ma, int size); #ifdef __cplusplus diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index 6312cbb22ca..275ab12540b 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -45,6 +45,7 @@ struct MemArena { int bufsize, cursize; int use_calloc; + int align; LinkNode *bufs; }; @@ -52,6 +53,7 @@ struct MemArena { MemArena *BLI_memarena_new(int bufsize) { MemArena *ma= MEM_callocN(sizeof(*ma), "memarena"); ma->bufsize= bufsize; + ma->align = 8; return ma; } @@ -64,6 +66,11 @@ void BLI_memarena_use_malloc(MemArena *ma) { ma->use_calloc= 0; } +void BLI_memarena_use_align(struct MemArena *ma, int align) { + /* align should be a power of two */ + ma->align = align; +} + void BLI_memarena_free(MemArena *ma) { BLI_linklist_free(ma->bufs, (void(*)(void*)) MEM_freeN); MEM_freeN(ma); @@ -77,16 +84,28 @@ void *BLI_memarena_alloc(MemArena *ma, int size) { /* ensure proper alignment by rounding * size up to multiple of 8 */ - size= PADUP(size, 8); + size= PADUP(size, ma->align); if (size>ma->cursize) { - ma->cursize= (size>ma->bufsize)?size:ma->bufsize; + unsigned char *tmp; + + if(size > ma->bufsize - (ma->align - 1)) + { + ma->cursize = PADUP(size+1, ma->align); + } + else ma->cursize = ma->bufsize; + if(ma->use_calloc) ma->curbuf= MEM_callocN(ma->cursize, "memarena calloc"); else ma->curbuf= MEM_mallocN(ma->cursize, "memarena malloc"); BLI_linklist_prepend(&ma->bufs, ma->curbuf); + + /* align alloc'ed memory (needed if align > 8) */ + tmp = (unsigned char*)PADUP( (intptr_t) ma->curbuf, ma->align); + ma->cursize -= (tmp - ma->curbuf); + ma->curbuf = tmp; } ptr= ma->curbuf; diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index b17a072f3a6..2d75cd800a7 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -196,18 +196,18 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) const float *bb2 = stack[stack_pos+2]->bb; const float *bb3 = stack[stack_pos+3]->bb; - const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(1,0,1,0) ); - const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(1,0,1,0) ); + const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(1,0,1,0) ); + const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(1,0,1,0) ); t_bb[0] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ); t_bb[1] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ); - const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+2), _mm_loadu_ps(bb1+2), _MM_SHUFFLE(1,0,1,0) ); - const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+2), _mm_loadu_ps(bb3+2), _MM_SHUFFLE(1,0,1,0) ); + const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3,1,3,1) ); + const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3,1,3,1) ); t_bb[2] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ); t_bb[3] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ); - const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(1,0,1,0) ); - const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(1,0,1,0) ); + const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_load_ps(bb0+4), _mm_load_ps(bb1+4), _MM_SHUFFLE(1,0,1,0) ); + const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_load_ps(bb2+4), _mm_load_ps(bb3+4), _MM_SHUFFLE(1,0,1,0) ); t_bb[4] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2,0,2,0) ); t_bb[5] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3,1,3,1) ); /* diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 9a67f490aeb..2f0efa80445 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -56,14 +56,14 @@ extern "C" struct BVHNode { - BVHNode *child; - BVHNode *sibling; - #ifdef DYNAMIC_ALLOC_BB float *bb; #else float bb[6]; #endif + + BVHNode *child; + BVHNode *sibling; }; struct BVHTree @@ -114,6 +114,12 @@ inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, i static BVHNode *bvh_new_node(BVHTree *tree) { BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + + if( (((intptr_t)node) & (0x0f)) != 0 ) + { + puts("WRONG!"); + printf("%08x\n", (intptr_t)node); + } node->sibling = NULL; node->child = NULL; @@ -317,6 +323,7 @@ void bvh_done(BVHTree *obj) obj->node_arena = BLI_memarena_new(needed_nodes); BLI_memarena_use_malloc(obj->node_arena); + BLI_memarena_use_align(obj->node_arena, 16); obj->root = bvh_rearrange( obj, obj->builder ); -- cgit v1.2.3 From b7a696e2ad8cc7d5c2b91d8fa714f3637aee64e3 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Fri, 7 Aug 2009 15:57:02 +0000 Subject: Made -O3 and -msse2 default flags for bf_render_raytrace --- source/blender/render/SConscript | 7 ++++--- source/blender/render/intern/raytrace/bvh.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index fb210afa545..2228ff9ebb9 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,7 +1,8 @@ #!/usr/bin/python Import ('env') -cflags='' +cflags = ['-O3'] +cxxflags = ['-O3','-msse2','-mfpmath=sse'] sources = env.Glob('intern/source/*.c') raysources = env.Glob('intern/raytrace/*.cpp') @@ -22,7 +23,7 @@ if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') if env['OURPLATFORM']=='linux2': - cflags='-pthread' + cflags += ['-pthread'] env.BlenderLib ( libname = 'bf_render', sources = sources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags ) -env.BlenderLib ( libname = 'bf_render_raytrace', sources = raysources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags ) +env.BlenderLib ( libname = 'bf_render_raytrace', sources = raysources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags, cxx_compileflags=cxxflags ) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 2d75cd800a7..f6c12f4b3fb 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -201,8 +201,8 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) t_bb[0] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ); t_bb[1] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ); - const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3,1,3,1) ); - const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3,1,3,1) ); + const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3,2,3,2) ); + const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3,2,3,2) ); t_bb[2] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ); t_bb[3] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ); -- cgit v1.2.3 From 8fa528cef8faa4f5ce2f6ff4f6e2f5b08709d08e Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 8 Aug 2009 11:33:34 +0000 Subject: Added Object.find_armature() to find armature connected to object. Previously this was BPyObject.getObjectArmature() --- release/io/export_fbx.py | 48 ++----------------------- source/blender/editors/include/ED_mesh.h | 3 ++ source/blender/makesrna/intern/rna_object_api.c | 30 ++++++++++++++++ 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 5bb169a9849..2a3ea5fc30e 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -118,26 +118,6 @@ def copy_images(dest_dir, textures): print('\tCopied %d images' % copyCount) -def BPyObject_getObjectArmature(ob): - ''' - This returns the first armature the mesh uses. - remember there can be more then 1 armature but most people dont do that. - ''' - if ob.type != 'MESH': - return None - - arm = ob.parent - if arm and arm.type == 'ARMATURE' and ob.parent_type == 'ARMATURE': - return arm - - for m in ob.modifiers: - if m.type== 'ARMATURE': - arm = m.object - if arm: - return arm - - return None - # I guess FBX uses degrees instead of radians (Arystan). # Call this function just before writing to FBX. def eulerRadToDeg(eul): @@ -298,30 +278,6 @@ def BPyMesh_meshWeight2List(ob): return groupNames, vWeightList - -def BPyMesh_meshWeight2Dict(me, ob): - ''' Takes a mesh and return its group names and a list of dicts, one dict per vertex. - using the group as a key and a float value for the weight. - These 2 lists can be modified and then used with dict2MeshWeight to apply the changes. - ''' - - vWeightDict= [dict() for i in range(len(me.verts))] # Sync with vertlist. - - # Clear the vert group. - groupNames= [g.name for g in ob.vertex_groups] -# groupNames= me.getVertGroupNames() - - for group in groupNames: - for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples. - vWeightDict[vert_index][group]= weight - - # removed this because me may be copying teh vertex groups. - #for group in groupNames: - # me.removeVertGroup(group) - - return groupNames, vWeightDict - - def meshNormalizedWeights(me): try: # account for old bad BPyMesh groupNames, vWeightList = BPyMesh_meshWeight2List(me) @@ -2199,7 +2155,7 @@ def write(filename, batch_objects = None, \ materials[None, None] = None if EXP_ARMATURE: - armob = BPyObject_getObjectArmature(ob) + armob = ob.find_armature() blenParentBoneName = None # parent bone - special case @@ -3482,7 +3438,7 @@ bpy.ops.add(EXPORT_OT_fbx) # - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print # - get rid of cleanName somehow # + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 -# - get rid of BPyObject_getObjectArmature, move it in RNA? +# + get rid of BPyObject_getObjectArmature, move it in RNA? # - BATCH_ENABLE and BATCH_GROUP options: line 327 # - implement all BPyMesh_* used here with RNA # - getDerivedObjects is not fully replicated with .dupli* funcs diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 0face00f82b..cceebeadc96 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -154,6 +154,9 @@ void EM_reveal_mesh(struct EditMesh *em); void EM_select_by_material(struct EditMesh *em, int index); void EM_deselect_by_material(struct EditMesh *em, int index); +/* editmesh_tools.c */ +void convert_to_triface(struct EditMesh *em, int direction); + /* editface.c */ struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 881c2bdf549..8192801d9fb 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -63,6 +63,7 @@ #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" #include "DNA_curve_types.h" +#include "DNA_modifier_types.h" #include "MEM_guardedalloc.h" @@ -309,6 +310,29 @@ static void rna_Object_make_display_list(Object *ob, bContext *C) DAG_object_flush_update(sce, ob, OB_RECALC_DATA); } +static Object *rna_Object_find_armature(Object *ob) +{ + Object *ob_arm = NULL; + + if (ob->type != OB_MESH) return 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 void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int *indices, int totindex, float weight, int assignmode) { @@ -409,6 +433,12 @@ void RNA_api_object(StructRNA *srna) parm= RNA_def_enum(func, "type", assign_mode_items, 0, "", "Vertex assign mode."); RNA_def_property_flag(parm, PROP_REQUIRED); + /* Armature */ + func= RNA_def_function(srna, "find_armature", "rna_Object_find_armature"); + RNA_def_function_ui_description(func, "Find armature influencing this object as a parent or via a modifier."); + parm= RNA_def_pointer(func, "ob_arm", "Object", "", "Armature object influencing this object or NULL."); + RNA_def_function_return(func, parm); + /* DAG */ func= RNA_def_function(srna, "make_display_list", "rna_Object_make_display_list"); RNA_def_function_ui_description(func, "Update object's display data."); /* XXX describe better */ -- cgit v1.2.3 From d1f22f6ce324e465697765221f2f4edf6af65147 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sat, 8 Aug 2009 11:44:56 +0000 Subject: Copied 3DS, X3D scripts to release/io naming them after [import|export]_[format].py scheme. --- release/io/export_3ds.py | 1025 ++++++++++++++++++++++++++++++++++++++++++++ release/io/export_x3d.py | 1051 ++++++++++++++++++++++++++++++++++++++++++++++ release/io/import_3ds.py | 1007 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3083 insertions(+) create mode 100644 release/io/export_3ds.py create mode 100644 release/io/export_x3d.py create mode 100644 release/io/import_3ds.py diff --git a/release/io/export_3ds.py b/release/io/export_3ds.py new file mode 100644 index 00000000000..69b4d00b4d8 --- /dev/null +++ b/release/io/export_3ds.py @@ -0,0 +1,1025 @@ +#!BPY +# coding: utf-8 +""" +Name: '3D Studio (.3ds)...' +Blender: 243 +Group: 'Export' +Tooltip: 'Export to 3DS file format (.3ds).' +""" + +__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] +__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") +__version__ = "0.90a" +__bpydoc__ = """\ + +3ds Exporter + +This script Exports a 3ds file. + +Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information +from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Bob Holcomb +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + +###################################################### +# Importing modules +###################################################### + +import Blender +import bpy +from BPyMesh import getMeshFromObject +from BPyObject import getDerivedObjects +try: + import struct +except: + struct = None + +# So 3ds max can open files, limit names to 12 in length +# this is verry annoying for filenames! +name_unique = [] +name_mapping = {} +def sane_name(name): + name_fixed = name_mapping.get(name) + if name_fixed != None: + return name_fixed + + if len(name) > 12: + new_name = name[:12] + else: + new_name = name + + i = 0 + + while new_name in name_unique: + new_name = new_name[:-4] + '.%.3d' % i + i+=1 + + name_unique.append(new_name) + name_mapping[name] = new_name + return new_name + +###################################################### +# Data Structures +###################################################### + +#Some of the chunks that we will export +#----- Primary Chunk, at the beginning of each file +PRIMARY= long("0x4D4D",16) + +#------ Main Chunks +OBJECTINFO = long("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information +VERSION = long("0x0002",16); #This gives the version of the .3ds file +KFDATA = long("0xB000",16); #This is the header for all of the key frame info + +#------ sub defines of OBJECTINFO +MATERIAL=45055 #0xAFFF // This stored the texture info +OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... + +#>------ sub defines of MATERIAL +MATNAME = long("0xA000",16); # This holds the material name +MATAMBIENT = long("0xA010",16); # Ambient color of the object/material +MATDIFFUSE = long("0xA020",16); # This holds the color of the object/material +MATSPECULAR = long("0xA030",16); # SPecular color of the object/material +MATSHINESS = long("0xA040",16); # ?? +MATMAP = long("0xA200",16); # This is a header for a new material +MATMAPFILE = long("0xA300",16); # This holds the file name of the texture + +RGB1= long("0x0011",16) +RGB2= long("0x0012",16) + +#>------ sub defines of OBJECT +OBJECT_MESH = long("0x4100",16); # This lets us know that we are reading a new object +OBJECT_LIGHT = long("0x4600",16); # This lets un know we are reading a light object +OBJECT_CAMERA= long("0x4700",16); # This lets un know we are reading a camera object + +#>------ sub defines of CAMERA +OBJECT_CAM_RANGES= long("0x4720",16); # The camera range values + +#>------ sub defines of OBJECT_MESH +OBJECT_VERTICES = long("0x4110",16); # The objects vertices +OBJECT_FACES = long("0x4120",16); # The objects faces +OBJECT_MATERIAL = long("0x4130",16); # This is found if the object has a material, either texture map or color +OBJECT_UV = long("0x4140",16); # The UV texture coordinates +OBJECT_TRANS_MATRIX = long("0x4160",16); # The Object Matrix + +#>------ sub defines of KFDATA +KFDATA_KFHDR = long("0xB00A",16); +KFDATA_KFSEG = long("0xB008",16); +KFDATA_KFCURTIME = long("0xB009",16); +KFDATA_OBJECT_NODE_TAG = long("0xB002",16); + +#>------ sub defines of OBJECT_NODE_TAG +OBJECT_NODE_ID = long("0xB030",16); +OBJECT_NODE_HDR = long("0xB010",16); +OBJECT_PIVOT = long("0xB013",16); +OBJECT_INSTANCE_NAME = long("0xB011",16); +POS_TRACK_TAG = long("0xB020",16); +ROT_TRACK_TAG = long("0xB021",16); +SCL_TRACK_TAG = long("0xB022",16); + +def uv_key(uv): + return round(uv.x, 6), round(uv.y, 6) + +# size defines: +SZ_SHORT = 2 +SZ_INT = 4 +SZ_FLOAT = 4 + +class _3ds_short(object): + '''Class representing a short (2-byte integer) for a 3ds file. + *** This looks like an unsigned short H is unsigned from the struct docs - Cam***''' + __slots__ = 'value' + def __init__(self, val=0): + self.value=val + + def get_size(self): + return SZ_SHORT + + def write(self,file): + file.write(struct.pack("= mat_ls_len: + mat_index = f.mat = 0 + mat = mat_ls[mat_index] + if mat: mat_name = mat.name + else: mat_name = None + # else there alredy set to none + + img = f.image + if img: img_name = img.name + else: img_name = None + + materialDict.setdefault((mat_name, img_name), (mat, img) ) + + + else: + for mat in mat_ls: + if mat: # material may be None so check its not. + materialDict.setdefault((mat.name, None), (mat, None) ) + + # Why 0 Why! + for f in data.faces: + if f.mat >= mat_ls_len: + f.mat = 0 + + # Make material chunks for all materials used in the meshes: + for mat_and_image in materialDict.itervalues(): + object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1])) + + # Give all objects a unique ID and build a dictionary from object name to object id: + """ + name_to_id = {} + for ob, data in mesh_objects: + name_to_id[ob.name]= len(name_to_id) + #for ob in empty_objects: + # name_to_id[ob.name]= len(name_to_id) + """ + + # Create object chunks for all meshes: + i = 0 + for ob, blender_mesh in mesh_objects: + # create a new object chunk + object_chunk = _3ds_chunk(OBJECT) + + # set the object name + object_chunk.add_variable("name", _3ds_string(sane_name(ob.name))) + + # make a mesh chunk out of the mesh: + object_chunk.add_subchunk(make_mesh_chunk(blender_mesh, materialDict)) + object_info.add_subchunk(object_chunk) + + ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX + # make a kf object node for the object: + kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) + ''' + blender_mesh.verts = None + i+=i + + # Create chunks for all empties: + ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX + for ob in empty_objects: + # Empties only require a kf object node: + kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) + pass + ''' + + # Add main object info chunk to primary chunk: + primary.add_subchunk(object_info) + + ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX + # Add main keyframe data chunk to primary chunk: + primary.add_subchunk(kfdata) + ''' + + # At this point, the chunk hierarchy is completely built. + + # Check the size: + primary.get_size() + # Open the file for writing: + file = open( filename, 'wb' ) + + # Recursively write the chunks to file: + primary.write(file) + + # Close the file: + file.close() + + # Debugging only: report the exporting time: + Blender.Window.WaitCursor(0) + print "3ds export time: %.2f" % (Blender.sys.time() - time1) + + # Debugging only: dump the chunk hierarchy: + #primary.dump() + + +if __name__=='__main__': + if struct: + Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) + else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") +# save_3ds('/test_b.3ds') diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py new file mode 100644 index 00000000000..b12ff67d8a6 --- /dev/null +++ b/release/io/export_x3d.py @@ -0,0 +1,1051 @@ +#!BPY +""" Registration info for Blender menus: +Name: 'X3D Extensible 3D (.x3d)...' +Blender: 245 +Group: 'Export' +Tooltip: 'Export selection to Extensible 3D file (.x3d)' +""" + +__author__ = ("Bart", "Campbell Barton") +__email__ = ["Bart, bart:neeneenee*de"] +__url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"] +__version__ = "2006/01/17" +__bpydoc__ = """\ +This script exports to X3D format. + +Usage: + +Run this script from "File->Export" menu. A pop-up will ask whether you +want to export only selected or all relevant objects. + +Known issues:
+ Doesn't handle multiple materials (don't use material indices);
+ Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);
+ Can't get the texture array associated with material * not the UV ones; +""" + + +# $Id$ +# +#------------------------------------------------------------------------ +# X3D exporter for blender 2.36 or above +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# + +#################################### +# Library dependancies +#################################### + +import Blender +from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh +from Blender.Scene import Render +import math +import BPyObject +import BPyMesh + +# +DEG2RAD=0.017453292519943295 +MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x') + +#################################### +# Global Variables +#################################### + +filename = Blender.Get('filename') +_safeOverwrite = True + +extension = '' + +########################################################## +# Functions for writing output file +########################################################## + +class x3d_class: + + def __init__(self, filename): + #--- public you can change these --- + self.writingcolor = 0 + self.writingtexture = 0 + self.writingcoords = 0 + self.proto = 1 + self.matonly = 0 + self.share = 0 + self.billnode = 0 + self.halonode = 0 + self.collnode = 0 + self.tilenode = 0 + self.verbose=2 # level of verbosity in console 0-none, 1-some, 2-most + self.cp=3 # decimals for material color values 0.000 - 1.000 + self.vp=3 # decimals for vertex coordinate values 0.000 - n.000 + self.tp=3 # decimals for texture coordinate values 0.000 - 1.000 + self.it=3 + + #--- class private don't touch --- + self.texNames={} # dictionary of textureNames + self.matNames={} # dictionary of materiaNames + self.meshNames={} # dictionary of meshNames + self.indentLevel=0 # keeps track of current indenting + self.filename=filename + self.file = None + if filename.lower().endswith('.x3dz'): + try: + import gzip + self.file = gzip.open(filename, "w") + except: + print "failed to import compression modules, exporting uncompressed" + self.filename = filename[:-1] # remove trailing z + + if self.file == None: + self.file = open(self.filename, "w") + + self.bNav=0 + self.nodeID=0 + self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard", + "BooleanFilter","BooleanSequencer","BooleanToggle","BooleanTrigger","Box","Circle2D", + "Collision","Color","ColorInterpolator","ColorRGBA","component","Cone","connect", + "Contour2D","ContourPolyline2D","Coordinate","CoordinateDouble","CoordinateInterpolator", + "CoordinateInterpolator2D","Cylinder","CylinderSensor","DirectionalLight","Disk2D", + "ElevationGrid","EspduTransform","EXPORT","ExternProtoDeclare","Extrusion","field", + "fieldValue","FillProperties","Fog","FontStyle","GeoCoordinate","GeoElevationGrid", + "GeoLocationLocation","GeoLOD","GeoMetadata","GeoOrigin","GeoPositionInterpolator", + "GeoTouchSensor","GeoViewpoint","Group","HAnimDisplacer","HAnimHumanoid","HAnimJoint", + "HAnimSegment","HAnimSite","head","ImageTexture","IMPORT","IndexedFaceSet", + "IndexedLineSet","IndexedTriangleFanSet","IndexedTriangleSet","IndexedTriangleStripSet", + "Inline","IntegerSequencer","IntegerTrigger","IS","KeySensor","LineProperties","LineSet", + "LoadSensor","LOD","Material","meta","MetadataDouble","MetadataFloat","MetadataInteger", + "MetadataSet","MetadataString","MovieTexture","MultiTexture","MultiTextureCoordinate", + "MultiTextureTransform","NavigationInfo","Normal","NormalInterpolator","NurbsCurve", + "NurbsCurve2D","NurbsOrientationInterpolator","NurbsPatchSurface", + "NurbsPositionInterpolator","NurbsSet","NurbsSurfaceInterpolator","NurbsSweptSurface", + "NurbsSwungSurface","NurbsTextureCoordinate","NurbsTrimmedSurface","OrientationInterpolator", + "PixelTexture","PlaneSensor","PointLight","PointSet","Polyline2D","Polypoint2D", + "PositionInterpolator","PositionInterpolator2D","ProtoBody","ProtoDeclare","ProtoInstance", + "ProtoInterface","ProximitySensor","ReceiverPdu","Rectangle2D","ROUTE","ScalarInterpolator", + "Scene","Script","Shape","SignalPdu","Sound","Sphere","SphereSensor","SpotLight","StaticGroup", + "StringSensor","Switch","Text","TextureBackground","TextureCoordinate","TextureCoordinateGenerator", + "TextureTransform","TimeSensor","TimeTrigger","TouchSensor","Transform","TransmitterPdu", + "TriangleFanSet","TriangleSet","TriangleSet2D","TriangleStripSet","Viewpoint","VisibilitySensor", + "WorldInfo","X3D","XvlShell","VertexShader","FragmentShader","MultiShaderAppearance","ShaderAppearance" ] + self.namesStandard=[ "Empty","Empty.000","Empty.001","Empty.002","Empty.003","Empty.004","Empty.005", + "Empty.006","Empty.007","Empty.008","Empty.009","Empty.010","Empty.011","Empty.012", + "Scene.001","Scene.002","Scene.003","Scene.004","Scene.005","Scene.06","Scene.013", + "Scene.006","Scene.007","Scene.008","Scene.009","Scene.010","Scene.011","Scene.012", + "World","World.000","World.001","World.002","World.003","World.004","World.005" ] + self.namesFog=[ "","LINEAR","EXPONENTIAL","" ] + +########################################################## +# Writing nodes routines +########################################################## + + def writeHeader(self): + #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '<').replace('>', '>') + bfile = self.filename.replace('<', '<').replace('>', '>') # use outfile name + self.file.write("\n") + self.file.write("\n") + self.file.write("\n") + self.file.write("\n") + self.file.write("\t\n" % sys.basename(bfile)) + self.file.write("\t\n" % Blender.Get('version')) + self.file.write("\t\n") + self.file.write("\n") + self.file.write("\n") + + # This functionality is poorly defined, disabling for now - campbell + ''' + def writeInline(self): + inlines = Blender.Scene.Get() + allinlines = len(inlines) + if scene != inlines[0]: + return + else: + for i in xrange(allinlines): + nameinline=inlines[i].name + if (nameinline not in self.namesStandard) and (i > 0): + self.file.write("" % nameinline) + self.file.write("\n\n") + + + def writeScript(self): + textEditor = Blender.Text.Get() + alltext = len(textEditor) + for i in xrange(alltext): + nametext = textEditor[i].name + nlines = textEditor[i].getNLines() + if (self.proto == 1): + if (nametext == "proto" or nametext == "proto.js" or nametext == "proto.txt") and (nlines != None): + nalllines = len(textEditor[i].asLines()) + alllines = textEditor[i].asLines() + for j in xrange(nalllines): + self.writeIndented(alllines[j] + "\n") + elif (self.proto == 0): + if (nametext == "route" or nametext == "route.js" or nametext == "route.txt") and (nlines != None): + nalllines = len(textEditor[i].asLines()) + alllines = textEditor[i].asLines() + for j in xrange(nalllines): + self.writeIndented(alllines[j] + "\n") + self.writeIndented("\n") + ''' + + def writeViewpoint(self, ob, mat, scene): + context = scene.render + ratio = float(context.imageSizeY())/float(context.imageSizeX()) + lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180) + lens = min(lens, math.pi) + + # get the camera location, subtract 90 degress from X to orient like X3D does + # mat = ob.matrixWorld - mat is now passed! + + loc = self.rotatePointForVRML(mat.translationPart()) + rot = mat.toEuler() + rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD) + nRot = self.rotatePointForVRML( rot ) + # convert to Quaternion and to Angle Axis + Q = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2]) + Q1 = self.multiplyQuaternions(Q[0], Q[1]) + Qf = self.multiplyQuaternions(Q1, Q[2]) + angleAxis = self.quaternionToAngleAxis(Qf) + self.file.write("\n\n" % (lens)) + + def writeFog(self, world): + if world: + mtype = world.getMistype() + mparam = world.getMist() + grd = world.getHor() + grd0, grd1, grd2 = grd[0], grd[1], grd[2] + else: + return + if (mtype == 1 or mtype == 2): + self.file.write("\n\n" % round(mparam[2],self.cp)) + else: + return + + def writeNavigationInfo(self, scene): + self.file.write('\n') + + def writeSpotLight(self, ob, mtx, lamp, world): + safeName = self.cleanStr(ob.name) + if world: + ambi = world.amb + ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 + else: + ambi = 0 + ambientIntensity = 0 + + # compute cutoff and beamwidth + intensity=min(lamp.energy/1.75,1.0) + beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; + cutOffAngle=beamWidth*1.3 + + dx,dy,dz=self.computeDirection(mtx) + # note -dx seems to equal om[3][0] + # note -dz seems to equal om[3][1] + # note dy seems to equal om[3][2] + + #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed + location=(mtx*MATWORLD).translationPart() + + radius = lamp.dist*math.cos(beamWidth) + self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) + + + def writeDirectionalLight(self, ob, mtx, lamp, world): + safeName = self.cleanStr(ob.name) + if world: + ambi = world.amb + ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 + else: + ambi = 0 + ambientIntensity = 0 + + intensity=min(lamp.energy/1.75,1.0) + (dx,dy,dz)=self.computeDirection(mtx) + self.file.write("\n\n" % (round(dx,4),round(dy,4),round(dz,4))) + + def writePointLight(self, ob, mtx, lamp, world): + safeName = self.cleanStr(ob.name) + if world: + ambi = world.amb + ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 + else: + ambi = 0 + ambientIntensity = 0 + + # location=(ob.matrixWorld*MATWORLD).translationPart() # now passed + location= (mtx*MATWORLD).translationPart() + + self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) + ''' + def writeNode(self, ob, mtx): + obname=str(ob.name) + if obname in self.namesStandard: + return + else: + dx,dy,dz = self.computeDirection(mtx) + # location=(ob.matrixWorld*MATWORLD).translationPart() + location=(mtx*MATWORLD).translationPart() + self.writeIndented("<%s\n" % obname,1) + self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3))) + self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) + self.writeIndented("/>\n",-1) + self.writeIndented("\n") + ''' + def secureName(self, name): + name = name + str(self.nodeID) + self.nodeID=self.nodeID+1 + if len(name) <= 3: + newname = "_" + str(self.nodeID) + return "%s" % (newname) + else: + for bad in ['"','#',"'",',','.','[','\\',']','{','}']: + name=name.replace(bad,'_') + if name in self.namesReserved: + newname = name[0:3] + "_" + str(self.nodeID) + return "%s" % (newname) + elif name[0].isdigit(): + newname = "_" + name + str(self.nodeID) + return "%s" % (newname) + else: + newname = name + return "%s" % (newname) + + def writeIndexedFaceSet(self, ob, mesh, mtx, world, EXPORT_TRI = False): + imageMap={} # set of used images + sided={} # 'one':cnt , 'two':cnt + vColors={} # 'multi':1 + meshName = self.cleanStr(ob.name) + + meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not + if len(mesh.faces) == 0: return + mode = 0 + if mesh.faceUV: + for face in mesh.faces: + mode |= face.mode + + if mode & Mesh.FaceModes.HALO and self.halonode == 0: + self.writeIndented("\n",1) + self.halonode = 1 + elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0: + self.writeIndented("\n",1) + self.billnode = 1 + elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0: + self.matonly = 1 + elif mode & Mesh.FaceModes.TILES and self.tilenode == 0: + self.tilenode = 1 + elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0: + self.writeIndented("\n",1) + self.collnode = 1 + + nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors) + + if nIFSCnt > 1: + self.writeIndented("\n" % ("G_", meshName),1) + + if sided.has_key('two') and sided['two'] > 0: + bTwoSided=1 + else: + bTwoSided=0 + + # mtx = ob.matrixWorld * MATWORLD # mtx is now passed + mtx = mtx * MATWORLD + + loc= mtx.translationPart() + sca= mtx.scalePart() + quat = mtx.toQuat() + rot= quat.axis + + # self.writeIndented('\n' % (rot[0], rot[1], rot[2], rot[3])) + self.writeIndented('\n' % \ + (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) ) + + self.writeIndented("\n",1) + maters=mesh.materials + hasImageTexture=0 + issmooth=0 + + if len(maters) > 0 or mesh.faceUV: + self.writeIndented("\n", 1) + # right now this script can only handle a single material per mesh. + if len(maters) >= 1: + mat=maters[0] + matFlags = mat.getMode() + if not matFlags & Blender.Material.Modes['TEXFACE']: + self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world) + if len(maters) > 1: + print "Warning: mesh named %s has multiple materials" % meshName + print "Warning: only one material per object handled" + + #-- textures + if mesh.faceUV: + for face in mesh.faces: + if (hasImageTexture == 0) and (face.image): + self.writeImageTexture(face.image) + hasImageTexture=1 # keep track of face texture + if self.tilenode == 1: + self.writeIndented("\n" % (face.image.xrep, face.image.yrep)) + self.tilenode = 0 + self.writeIndented("\n", -1) + + #-- IndexedFaceSet or IndexedLineSet + + # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5 + ifStyle="IndexedFaceSet" + # look up mesh name, use it if available + if self.meshNames.has_key(meshME): + self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1) + self.meshNames[meshME]+=1 + else: + if int(mesh.users) > 1: + self.writeIndented("<%s DEF=\"ME_%s\" " % (ifStyle, meshME), 1) + self.meshNames[meshME]=1 + else: + self.writeIndented("<%s " % ifStyle, 1) + + if bTwoSided == 1: + self.file.write("solid=\"false\" ") + else: + self.file.write("solid=\"true\" ") + + for face in mesh.faces: + if face.smooth: + issmooth=1 + break + if issmooth==1: + creaseAngle=(mesh.degr)*(math.pi/180.0) + self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp))) + + #--- output textureCoordinates if UV texture used + if mesh.faceUV: + if self.matonly == 1 and self.share == 1: + self.writeFaceColors(mesh) + elif hasImageTexture == 1: + self.writeTextureCoordinates(mesh) + #--- output coordinates + self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) + + self.writingcoords = 1 + self.writingtexture = 1 + self.writingcolor = 1 + self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) + + #--- output textureCoordinates if UV texture used + if mesh.faceUV: + if hasImageTexture == 1: + self.writeTextureCoordinates(mesh) + elif self.matonly == 1 and self.share == 1: + self.writeFaceColors(mesh) + #--- output vertexColors + self.matonly = 0 + self.share = 0 + + self.writingcoords = 0 + self.writingtexture = 0 + self.writingcolor = 0 + #--- output closing braces + self.writeIndented("\n" % ifStyle, -1) + self.writeIndented("\n", -1) + self.writeIndented("\n", -1) + + if self.halonode == 1: + self.writeIndented("\n", -1) + self.halonode = 0 + + if self.billnode == 1: + self.writeIndented("\n", -1) + self.billnode = 0 + + if self.collnode == 1: + self.writeIndented("\n", -1) + self.collnode = 0 + + if nIFSCnt > 1: + self.writeIndented("\n", -1) + + self.file.write("\n") + + def writeCoordinates(self, ob, mesh, meshName, EXPORT_TRI = False): + # create vertex list and pre rotate -90 degrees X for VRML + + if self.writingcoords == 0: + self.file.write('coordIndex="') + for face in mesh.faces: + fv = face.v + + if len(face)==3: + self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) + else: + if EXPORT_TRI: + self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) + self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index)) + else: + self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index)) + + self.file.write("\">\n") + else: + #-- vertices + # mesh.transform(ob.matrixWorld) + self.writeIndented("") + self.writeIndented("\n", -1) + + def writeTextureCoordinates(self, mesh): + texCoordList=[] + texIndexList=[] + j=0 + + for face in mesh.faces: + for uv in face.uv: + texIndexList.append(j) + texCoordList.append(uv) + j=j+1 + texIndexList.append(-1) + if self.writingtexture == 0: + self.file.write("\n\t\t\ttexCoordIndex=\"") + texIndxStr="" + for i in xrange(len(texIndexList)): + texIndxStr = texIndxStr + "%d, " % texIndexList[i] + if texIndexList[i]==-1: + self.file.write(texIndxStr) + texIndxStr="" + self.file.write("\"\n\t\t\t") + else: + self.writeIndented("") + self.writeIndented("\n", -1) + + def writeFaceColors(self, mesh): + if self.writingcolor == 0: + self.file.write("colorPerVertex=\"false\" ") + else: + self.writeIndented(" 2: + print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b) + aColor = self.rgbToFS(c) + self.file.write("%s, " % aColor) + self.file.write("\" />") + self.writeIndented("\n",-1) + + def writeMaterial(self, mat, matName, world): + # look up material name, use it if available + if self.matNames.has_key(matName): + self.writeIndented("\n" % matName) + self.matNames[matName]+=1 + return; + + self.matNames[matName]=1 + + ambient = mat.amb/3 + diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] + if world: + ambi = world.getAmb() + ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 + else: + ambi0, ambi1, ambi2 = 0, 0, 0 + emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2 + + shininess = mat.hard/512.0 + specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001)) + specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001)) + specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001)) + transp = 1-mat.alpha + matFlags = mat.getMode() + if matFlags & Blender.Material.Modes['SHADELESS']: + ambient = 1 + shine = 1 + specR = emitR = diffuseR + specG = emitG = diffuseG + specB = emitB = diffuseB + self.writeIndented("" % (round(transp,self.cp))) + self.writeIndented("\n",-1) + + def writeImageTexture(self, image): + name = image.name + filename = image.filename.split('/')[-1].split('\\')[-1] + if self.texNames.has_key(name): + self.writeIndented("\n" % self.cleanStr(name)) + self.texNames[name] += 1 + return + else: + self.writeIndented("" % name) + self.writeIndented("\n",-1) + self.texNames[name] = 1 + + def writeBackground(self, world, alltextures): + if world: worldname = world.name + else: return + blending = world.getSkytype() + grd = world.getHor() + grd0, grd1, grd2 = grd[0], grd[1], grd[2] + sky = world.getZen() + sky0, sky1, sky2 = sky[0], sky[1], sky[2] + mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2] + mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2 + self.file.write("\n\n") + +########################################################## +# export routine +########################################################## + + def export(self, scene, world, alltextures,\ + EXPORT_APPLY_MODIFIERS = False,\ + EXPORT_TRI= False,\ + ): + + print "Info: starting X3D export to " + self.filename + "..." + self.writeHeader() + # self.writeScript() + self.writeNavigationInfo(scene) + self.writeBackground(world, alltextures) + self.writeFog(world) + self.proto = 0 + + + # COPIED FROM OBJ EXPORTER + if EXPORT_APPLY_MODIFIERS: + temp_mesh_name = '~tmp-mesh' + + # Get the container mesh. - used for applying modifiers and non mesh objects. + containerMesh = meshName = tempMesh = None + for meshName in Blender.NMesh.GetNames(): + if meshName.startswith(temp_mesh_name): + tempMesh = Mesh.Get(meshName) + if not tempMesh.users: + containerMesh = tempMesh + if not containerMesh: + containerMesh = Mesh.New(temp_mesh_name) + # -------------------------- + + + for ob_main in scene.objects.context: + for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): + objType=ob.type + objName=ob.name + self.matonly = 0 + if objType == "Camera": + self.writeViewpoint(ob, ob_mat, scene) + elif objType in ("Mesh", "Curve", "Surf", "Text") : + if EXPORT_APPLY_MODIFIERS or objType != 'Mesh': + me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene) + else: + me = ob.getData(mesh=1) + + self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI) + elif objType == "Lamp": + data= ob.data + datatype=data.type + if datatype == Lamp.Types.Lamp: + self.writePointLight(ob, ob_mat, data, world) + elif datatype == Lamp.Types.Spot: + self.writeSpotLight(ob, ob_mat, data, world) + elif datatype == Lamp.Types.Sun: + self.writeDirectionalLight(ob, ob_mat, data, world) + else: + self.writeDirectionalLight(ob, ob_mat, data, world) + # do you think x3d could document what to do with dummy objects? + #elif objType == "Empty" and objName != "Empty": + # self.writeNode(ob, ob_mat) + else: + #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType) + pass + + self.file.write("\n\n") + + if EXPORT_APPLY_MODIFIERS: + if containerMesh: + containerMesh.verts = None + + self.cleanup() + +########################################################## +# Utility methods +########################################################## + + def cleanup(self): + self.file.close() + self.texNames={} + self.matNames={} + self.indentLevel=0 + print "Info: finished X3D export to %s\n" % self.filename + + def cleanStr(self, name, prefix='rsvd_'): + """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name""" + + newName=name[:] + if len(newName) == 0: + self.nNodeID+=1 + return "%s%d" % (prefix, self.nNodeID) + + if newName in self.namesReserved: + newName='%s%s' % (prefix,newName) + + if newName[0].isdigit(): + newName='%s%s' % ('_',newName) + + for bad in [' ','"','#',"'",',','.','[','\\',']','{','}']: + newName=newName.replace(bad,'_') + return newName + + def countIFSSetsNeeded(self, mesh, imageMap, sided, vColors): + """ + countIFFSetsNeeded() - should look at a blender mesh to determine + how many VRML IndexFaceSets or IndexLineSets are needed. A + new mesh created under the following conditions: + + o - split by UV Textures / one per mesh + o - split by face, one sided and two sided + o - split by smooth and flat faces + o - split when faces only have 2 vertices * needs to be an IndexLineSet + """ + + imageNameMap={} + faceMap={} + nFaceIndx=0 + + if mesh.faceUV: + for face in mesh.faces: + sidename=''; + if face.mode & Mesh.FaceModes.TWOSIDE: + sidename='two' + else: + sidename='one' + + if sided.has_key(sidename): + sided[sidename]+=1 + else: + sided[sidename]=1 + + image = face.image + if image: + faceName="%s_%s" % (face.image.name, sidename); + try: + imageMap[faceName].append(face) + except: + imageMap[faceName]=[face.image.name,sidename,face] + + if self.verbose > 2: + for faceName in imageMap.iterkeys(): + ifs=imageMap[faceName] + print "Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \ + (faceName, ifs[0], ifs[1], len(ifs)-2) + + return len(imageMap) + + def faceToString(self,face): + + print "Debug: face.flag=0x%x (bitflags)" % face.flag + if face.sel: + print "Debug: face.sel=true" + + print "Debug: face.mode=0x%x (bitflags)" % face.mode + if face.mode & Mesh.FaceModes.TWOSIDE: + print "Debug: face.mode twosided" + + print "Debug: face.transp=0x%x (enum)" % face.transp + if face.transp == Mesh.FaceTranspModes.SOLID: + print "Debug: face.transp.SOLID" + + if face.image: + print "Debug: face.image=%s" % face.image.name + print "Debug: face.materialIndex=%d" % face.materialIndex + + def getVertexColorByIndx(self, mesh, indx): + c = None + for face in mesh.faces: + j=0 + for vertex in face.v: + if vertex.index == indx: + c=face.col[j] + break + j=j+1 + if c: break + return c + + def meshToString(self,mesh): + print "Debug: mesh.hasVertexUV=%d" % mesh.vertexColors + print "Debug: mesh.faceUV=%d" % mesh.faceUV + print "Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours() + print "Debug: mesh.verts=%d" % len(mesh.verts) + print "Debug: mesh.faces=%d" % len(mesh.faces) + print "Debug: mesh.materials=%d" % len(mesh.materials) + + def rgbToFS(self, c): + s="%s %s %s" % ( + round(c.r/255.0,self.cp), + round(c.g/255.0,self.cp), + round(c.b/255.0,self.cp)) + return s + + def computeDirection(self, mtx): + x,y,z=(0,-1.0,0) # point down + + ax,ay,az = (mtx*MATWORLD).toEuler() + + ax *= DEG2RAD + ay *= DEG2RAD + az *= DEG2RAD + # rot X + x1=x + y1=y*math.cos(ax)-z*math.sin(ax) + z1=y*math.sin(ax)+z*math.cos(ax) + + # rot Y + x2=x1*math.cos(ay)+z1*math.sin(ay) + y2=y1 + z2=z1*math.cos(ay)-x1*math.sin(ay) + + # rot Z + x3=x2*math.cos(az)-y2*math.sin(az) + y3=x2*math.sin(az)+y2*math.cos(az) + z3=z2 + + return [x3,y3,z3] + + + # swap Y and Z to handle axis difference between Blender and VRML + #------------------------------------------------------------------------ + def rotatePointForVRML(self, v): + x = v[0] + y = v[2] + z = -v[1] + + vrmlPoint=[x, y, z] + return vrmlPoint + + # For writing well formed VRML code + #------------------------------------------------------------------------ + def writeIndented(self, s, inc=0): + if inc < 1: + self.indentLevel = self.indentLevel + inc + + spaces="" + for x in xrange(self.indentLevel): + spaces = spaces + "\t" + self.file.write(spaces + s) + + if inc > 0: + self.indentLevel = self.indentLevel + inc + + # Converts a Euler to three new Quaternions + # Angles of Euler are passed in as radians + #------------------------------------------------------------------------ + def eulerToQuaternions(self, x, y, z): + Qx = [math.cos(x/2), math.sin(x/2), 0, 0] + Qy = [math.cos(y/2), 0, math.sin(y/2), 0] + Qz = [math.cos(z/2), 0, 0, math.sin(z/2)] + + quaternionVec=[Qx,Qy,Qz] + return quaternionVec + + # Multiply two Quaternions together to get a new Quaternion + #------------------------------------------------------------------------ + def multiplyQuaternions(self, Q1, Q2): + result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])), + ((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])), + ((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])), + ((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))] + + return result + + # Convert a Quaternion to an Angle Axis (ax, ay, az, angle) + # angle is in radians + #------------------------------------------------------------------------ + def quaternionToAngleAxis(self, Qf): + scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2) + ax = Qf[1] + ay = Qf[2] + az = Qf[3] + + if scale > .0001: + ax/=scale + ay/=scale + az/=scale + + angle = 2 * math.acos(Qf[0]) + + result = [ax, ay, az, angle] + return result + +########################################################## +# Callbacks, needed before Main +########################################################## + +def x3d_export(filename, \ + EXPORT_APPLY_MODIFIERS= False,\ + EXPORT_TRI= False,\ + EXPORT_GZIP= False,\ + ): + + if EXPORT_GZIP: + if not filename.lower().endswith('.x3dz'): + filename = '.'.join(filename.split('.')[:-1]) + '.x3dz' + else: + if not filename.lower().endswith('.x3d'): + filename = '.'.join(filename.split('.')[:-1]) + '.x3d' + + + scene = Blender.Scene.GetCurrent() + world = scene.world + alltextures = Blender.Texture.Get() + + wrlexport=x3d_class(filename) + wrlexport.export(\ + scene,\ + world,\ + alltextures,\ + \ + EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\ + EXPORT_TRI = EXPORT_TRI,\ + ) + + +def x3d_export_ui(filename): + if not filename.endswith(extension): + filename += extension + #if _safeOverwrite and sys.exists(filename): + # result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0") + #if(result != 1): + # return + + # Get user options + EXPORT_APPLY_MODIFIERS = Draw.Create(1) + EXPORT_TRI = Draw.Create(0) + EXPORT_GZIP = Draw.Create( filename.lower().endswith('.x3dz') ) + + # Get USER Options + pup_block = [\ + ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object.'),\ + ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\ + ('Compress', EXPORT_GZIP, 'GZip the resulting file, requires a full python install'),\ + ] + + if not Draw.PupBlock('Export...', pup_block): + return + + Blender.Window.EditMode(0) + Blender.Window.WaitCursor(1) + + x3d_export(filename,\ + EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val,\ + EXPORT_TRI = EXPORT_TRI.val,\ + EXPORT_GZIP = EXPORT_GZIP.val\ + ) + + Blender.Window.WaitCursor(0) + + + +######################################################### +# main routine +######################################################### + + +if __name__ == '__main__': + Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) + + diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py new file mode 100644 index 00000000000..bcde82c4869 --- /dev/null +++ b/release/io/import_3ds.py @@ -0,0 +1,1007 @@ +#!BPY +""" +Name: '3D Studio (.3ds)...' +Blender: 244 +Group: 'Import' +Tooltip: 'Import from 3DS file format (.3ds)' +""" + +__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin'] +__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") +__version__= '0.996' +__bpydoc__= '''\ + +3ds Importer + +This script imports a 3ds file and the materials into Blender for editing. + +Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). + +0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200
+ - Implemented workaround to correct association between name, geometry and materials of + imported meshes. + + Without this patch, version 0.995 of this importer would associate to each mesh object the + geometry and the materials of the previously parsed mesh object. By so, the name of the + first mesh object would be thrown away, and the name of the last mesh object would be + automatically merged with a '.001' at the end. No object would desappear, however object's + names and materials would be completely jumbled. + +0.995 by Campbell Barton
+- workaround for buggy mesh vert delete +- minor tweaks + +0.99 by Bob Holcomb
+- added support for floating point color values that previously broke on import. + +0.98 by Campbell Barton
+- import faces and verts to lists instead of a mesh, convert to a mesh later +- use new index mapping feature of mesh to re-map faces that were not added. + +0.97 by Campbell Barton
+- Strip material names of spaces +- Added import as instance to import the 3ds into its own + scene and add a group instance to the current scene +- New option to scale down imported objects so they are within a limited bounding area. + +0.96 by Campbell Barton
+- Added workaround for bug in setting UV's for Zero vert index UV faces. +- Removed unique name function, let blender make the names unique. + +0.95 by Campbell Barton
+- Removed workarounds for Blender 2.41 +- Mesh objects split by material- many 3ds objects used more then 16 per mesh. +- Removed a lot of unneeded variable creation. + +0.94 by Campbell Barton
+- Face import tested to be about overall 16x speedup over 0.93. +- Material importing speedup. +- Tested with more models. +- Support some corrupt models. + +0.93 by Campbell Barton
+- Tested with 400 3ds files from turbosquid and samples. +- Tactfully ignore faces that used the same verts twice. +- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading. +- Converted from NMesh to Mesh. +- Faster and cleaner new names. +- Use external comprehensive image loader. +- Re intergrated 0.92 and 0.9 changes +- Fixes for 2.41 compat. +- Non textured faces do not use a texture flag. + +0.92
+- Added support for diffuse, alpha, spec, bump maps in a single material + +0.9
+- Reorganized code into object/material block functions
+- Use of Matrix() to copy matrix data
+- added support for material transparency
+ +0.83 2005-08-07: Campell Barton +- Aggressive image finding and case insensitivy for posisx systems. + +0.82a 2005-07-22 +- image texture loading (both for face uv and renderer) + +0.82 - image texture loading (for face uv) + +0.81a (fork- not 0.9) Campbell Barton 2005-06-08 +- Simplified import code +- Never overwrite data +- Faster list handling +- Leaves import selected + +0.81 Damien McGinnes 2005-01-09 +- handle missing images better + +0.8 Damien McGinnes 2005-01-08 +- copies sticky UV coords to face ones +- handles images better +- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script + +''' + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Bob Holcomb +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +# Importing modules + +import Blender +import bpy +from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils +from Blender.Mathutils import Vector +import BPyImage + +import BPyMessages + +try: + from struct import calcsize, unpack +except: + calcsize= unpack= None + + + +# If python version is less than 2.4, try to get set stuff from module +try: + set +except: + from sets import Set as set + +BOUNDS_3DS= [] + + +#this script imports uvcoords as sticky vertex coords +#this parameter enables copying these to face uv coords +#which shold be more useful. + +def createBlenderTexture(material, name, image): + texture= bpy.data.textures.new(name) + texture.setType('Image') + texture.image= image + material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) + + + +###################################################### +# Data Structures +###################################################### + +#Some of the chunks that we will see +#----- Primary Chunk, at the beginning of each file +PRIMARY= long('0x4D4D',16) + +#------ Main Chunks +OBJECTINFO = long('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information +VERSION = long('0x0002',16); #This gives the version of the .3ds file +EDITKEYFRAME= long('0xB000',16); #This is the header for all of the key frame info + +#------ sub defines of OBJECTINFO +MATERIAL=45055 #0xAFFF // This stored the texture info +OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... + +#>------ sub defines of MATERIAL +#------ sub defines of MATERIAL_BLOCK +MAT_NAME = long('0xA000',16) # This holds the material name +MAT_AMBIENT = long('0xA010',16) # Ambient color of the object/material +MAT_DIFFUSE = long('0xA020',16) # This holds the color of the object/material +MAT_SPECULAR = long('0xA030',16) # SPecular color of the object/material +MAT_SHINESS = long('0xA040',16) # ?? +MAT_TRANSPARENCY= long('0xA050',16) # Transparency value of material +MAT_SELF_ILLUM = long('0xA080',16) # Self Illumination value of material +MAT_WIRE = long('0xA085',16) # Only render's wireframe + +MAT_TEXTURE_MAP = long('0xA200',16) # This is a header for a new texture map +MAT_SPECULAR_MAP= long('0xA204',16) # This is a header for a new specular map +MAT_OPACITY_MAP = long('0xA210',16) # This is a header for a new opacity map +MAT_REFLECTION_MAP= long('0xA220',16) # This is a header for a new reflection map +MAT_BUMP_MAP = long('0xA230',16) # This is a header for a new bump map +MAT_MAP_FILENAME = long('0xA300',16) # This holds the file name of the texture + +MAT_FLOAT_COLOR = long ('0x0010', 16) #color defined as 3 floats +MAT_24BIT_COLOR = long ('0x0011', 16) #color defined as 3 bytes + +#>------ sub defines of OBJECT +OBJECT_MESH = long('0x4100',16); # This lets us know that we are reading a new object +OBJECT_LAMP = long('0x4600',16); # This lets un know we are reading a light object +OBJECT_LAMP_SPOT = long('0x4610',16); # The light is a spotloght. +OBJECT_LAMP_OFF = long('0x4620',16); # The light off. +OBJECT_LAMP_ATTENUATE = long('0x4625',16); +OBJECT_LAMP_RAYSHADE = long('0x4627',16); +OBJECT_LAMP_SHADOWED = long('0x4630',16); +OBJECT_LAMP_LOCAL_SHADOW = long('0x4640',16); +OBJECT_LAMP_LOCAL_SHADOW2 = long('0x4641',16); +OBJECT_LAMP_SEE_CONE = long('0x4650',16); +OBJECT_LAMP_SPOT_RECTANGULAR= long('0x4651',16); +OBJECT_LAMP_SPOT_OVERSHOOT= long('0x4652',16); +OBJECT_LAMP_SPOT_PROJECTOR= long('0x4653',16); +OBJECT_LAMP_EXCLUDE= long('0x4654',16); +OBJECT_LAMP_RANGE= long('0x4655',16); +OBJECT_LAMP_ROLL= long('0x4656',16); +OBJECT_LAMP_SPOT_ASPECT= long('0x4657',16); +OBJECT_LAMP_RAY_BIAS= long('0x4658',16); +OBJECT_LAMP_INNER_RANGE= long('0x4659',16); +OBJECT_LAMP_OUTER_RANGE= long('0x465A',16); +OBJECT_LAMP_MULTIPLIER = long('0x465B',16); +OBJECT_LAMP_AMBIENT_LIGHT = long('0x4680',16); + + + +OBJECT_CAMERA= long('0x4700',16); # This lets un know we are reading a camera object + +#>------ sub defines of CAMERA +OBJECT_CAM_RANGES= long('0x4720',16); # The camera range values + +#>------ sub defines of OBJECT_MESH +OBJECT_VERTICES = long('0x4110',16); # The objects vertices +OBJECT_FACES = long('0x4120',16); # The objects faces +OBJECT_MATERIAL = long('0x4130',16); # This is found if the object has a material, either texture map or color +OBJECT_UV = long('0x4140',16); # The UV texture coordinates +OBJECT_TRANS_MATRIX = long('0x4160',16); # The Object Matrix + +global scn +scn= None + +#the chunk class +class chunk: + ID=0 + length=0 + bytes_read=0 + + #we don't read in the bytes_read, we compute that + binary_format='3): + print '\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version + + #is it an object info chunk? + elif (new_chunk.ID==OBJECTINFO): + #print 'elif (new_chunk.ID==OBJECTINFO):' + # print 'found an OBJECTINFO chunk' + process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) + + #keep track of how much we read in the main chunk + new_chunk.bytes_read+=temp_chunk.bytes_read + + #is it an object chunk? + elif (new_chunk.ID==OBJECT): + + if CreateBlenderObject: + putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) + contextMesh_vertls= []; contextMesh_facels= [] + + ## preparando para receber o proximo objeto + contextMeshMaterials= {} # matname:[face_idxs] + contextMeshUV= None + #contextMesh.vertexUV= 1 # Make sticky coords. + # Reset matrix + contextMatrix_rot= None + #contextMatrix_tx= None + + CreateBlenderObject= True + tempName= read_string(file) + contextObName= tempName + new_chunk.bytes_read += len(tempName)+1 + + #is it a material chunk? + elif (new_chunk.ID==MATERIAL): + #print 'elif (new_chunk.ID==MATERIAL):' + contextMaterial= bpy.data.materials.new('Material') + + elif (new_chunk.ID==MAT_NAME): + #print 'elif (new_chunk.ID==MAT_NAME):' + material_name= read_string(file) + + #plus one for the null character that ended the string + new_chunk.bytes_read+= len(material_name)+1 + + contextMaterial.name= material_name.rstrip() # remove trailing whitespace + MATDICT[material_name]= (contextMaterial.name, contextMaterial) + + elif (new_chunk.ID==MAT_AMBIENT): + #print 'elif (new_chunk.ID==MAT_AMBIENT):' + read_chunk(file, temp_chunk) + if (temp_chunk.ID==MAT_FLOAT_COLOR): + temp_data=file.read(calcsize('3f')) + temp_chunk.bytes_read+=12 + contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)] + elif (temp_chunk.ID==MAT_24BIT_COLOR): + temp_data=file.read(calcsize('3B')) + temp_chunk.bytes_read+= 3 + contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb + else: + skip_to_end(file, temp_chunk) + new_chunk.bytes_read+= temp_chunk.bytes_read + + elif (new_chunk.ID==MAT_DIFFUSE): + #print 'elif (new_chunk.ID==MAT_DIFFUSE):' + read_chunk(file, temp_chunk) + if (temp_chunk.ID==MAT_FLOAT_COLOR): + temp_data=file.read(calcsize('3f')) + temp_chunk.bytes_read+=12 + contextMaterial.rgbCol=[float(col) for col in unpack('<3f', temp_data)] + elif (temp_chunk.ID==MAT_24BIT_COLOR): + temp_data=file.read(calcsize('3B')) + temp_chunk.bytes_read+= 3 + contextMaterial.rgbCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb + else: + skip_to_end(file, temp_chunk) + new_chunk.bytes_read+= temp_chunk.bytes_read + + elif (new_chunk.ID==MAT_SPECULAR): + #print 'elif (new_chunk.ID==MAT_SPECULAR):' + read_chunk(file, temp_chunk) + if (temp_chunk.ID==MAT_FLOAT_COLOR): + temp_data=file.read(calcsize('3f')) + temp_chunk.bytes_read+=12 + contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)] + elif (temp_chunk.ID==MAT_24BIT_COLOR): + temp_data=file.read(calcsize('3B')) + temp_chunk.bytes_read+= 3 + contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb + else: + skip_to_end(file, temp_chunk) + new_chunk.bytes_read+= temp_chunk.bytes_read + + elif (new_chunk.ID==MAT_TEXTURE_MAP): + #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):' + new_texture= bpy.data.textures.new('Diffuse') + new_texture.setType('Image') + img = None + while (new_chunk.bytes_read BOUNDS_3DS[i+3]: + BOUNDS_3DS[i+3]= v[i] # min + + # Get the max axis x/y/z + max_axis= max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2]) + # print max_axis + if max_axis < 1<<30: # Should never be false but just make sure. + + # Get a new scale factor if set as an option + SCALE=1.0 + while (max_axis*SCALE) > IMPORT_CONSTRAIN_BOUNDS: + SCALE/=10 + + # SCALE Matrix + SCALE_MAT= Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) + + for ob in importedObjects: + ob.setMatrix(ob.matrixWorld*SCALE_MAT) + + # Done constraining to bounds. + + # Select all new objects. + print 'finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)) + file.close() + Blender.Window.WaitCursor(0) + + +DEBUG= False +if __name__=='__main__' and not DEBUG: + if calcsize==None: + Blender.Draw.PupMenu('Error%t|a full python installation not found') + else: + Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') + +# For testing compatibility +#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False) +#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False) +''' + +else: + import os + # DEBUG ONLY + TIME= Blender.sys.time() + import os + print 'Searching for files' + os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') + # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') + print '...Done' + file= open('/tmp/temp3ds_list', 'r') + lines= file.readlines() + file.close() + # sort by filesize for faster testing + lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] + lines_size.sort() + lines = [f[1] for f in lines_size] + + + def between(v,a,b): + if v <= max(a,b) and v >= min(a,b): + return True + return False + + for i, _3ds in enumerate(lines): + if between(i, 650,800): + #_3ds= _3ds[:-1] + print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines) + _3ds_file= _3ds.split('/')[-1].split('\\')[-1] + newScn= Blender.Scene.New(_3ds_file) + newScn.makeCurrent() + load_3ds(_3ds, False) + + print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) + +''' -- cgit v1.2.3 From 675936b42cc9aa3ea15c1cf4af06790e5b41ecae Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 10 Aug 2009 13:49:55 +0000 Subject: - ran 2to3 on export_3ds.py, import_3ds.py and export_x3d.py - added operators and menu items for ^ --- release/io/export_3ds.py | 164 +++++++++++++++++++++--------------- release/io/export_obj.py | 2 +- release/io/export_x3d.py | 114 ++++++++++++++++--------- release/io/import_3ds.py | 210 +++++++++++++++++++++++++++-------------------- release/ui/space_info.py | 3 + 5 files changed, 296 insertions(+), 197 deletions(-) diff --git a/release/io/export_3ds.py b/release/io/export_3ds.py index 69b4d00b4d8..c4a73a44b0c 100644 --- a/release/io/export_3ds.py +++ b/release/io/export_3ds.py @@ -46,14 +46,17 @@ from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. # Importing modules ###################################################### -import Blender +import struct + import bpy -from BPyMesh import getMeshFromObject -from BPyObject import getDerivedObjects -try: - import struct -except: - struct = None + +# import Blender +# from BPyMesh import getMeshFromObject +# from BPyObject import getDerivedObjects +# try: +# import struct +# except: +# struct = None # So 3ds max can open files, limit names to 12 in length # this is verry annoying for filenames! @@ -85,58 +88,58 @@ def sane_name(name): #Some of the chunks that we will export #----- Primary Chunk, at the beginning of each file -PRIMARY= long("0x4D4D",16) +PRIMARY= int("0x4D4D",16) #------ Main Chunks -OBJECTINFO = long("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information -VERSION = long("0x0002",16); #This gives the version of the .3ds file -KFDATA = long("0xB000",16); #This is the header for all of the key frame info +OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information +VERSION = int("0x0002",16); #This gives the version of the .3ds file +KFDATA = int("0xB000",16); #This is the header for all of the key frame info #------ sub defines of OBJECTINFO MATERIAL=45055 #0xAFFF // This stored the texture info OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... #>------ sub defines of MATERIAL -MATNAME = long("0xA000",16); # This holds the material name -MATAMBIENT = long("0xA010",16); # Ambient color of the object/material -MATDIFFUSE = long("0xA020",16); # This holds the color of the object/material -MATSPECULAR = long("0xA030",16); # SPecular color of the object/material -MATSHINESS = long("0xA040",16); # ?? -MATMAP = long("0xA200",16); # This is a header for a new material -MATMAPFILE = long("0xA300",16); # This holds the file name of the texture +MATNAME = int("0xA000",16); # This holds the material name +MATAMBIENT = int("0xA010",16); # Ambient color of the object/material +MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material +MATSPECULAR = int("0xA030",16); # SPecular color of the object/material +MATSHINESS = int("0xA040",16); # ?? +MATMAP = int("0xA200",16); # This is a header for a new material +MATMAPFILE = int("0xA300",16); # This holds the file name of the texture -RGB1= long("0x0011",16) -RGB2= long("0x0012",16) +RGB1= int("0x0011",16) +RGB2= int("0x0012",16) #>------ sub defines of OBJECT -OBJECT_MESH = long("0x4100",16); # This lets us know that we are reading a new object -OBJECT_LIGHT = long("0x4600",16); # This lets un know we are reading a light object -OBJECT_CAMERA= long("0x4700",16); # This lets un know we are reading a camera object +OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object +OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object +OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object #>------ sub defines of CAMERA -OBJECT_CAM_RANGES= long("0x4720",16); # The camera range values +OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values #>------ sub defines of OBJECT_MESH -OBJECT_VERTICES = long("0x4110",16); # The objects vertices -OBJECT_FACES = long("0x4120",16); # The objects faces -OBJECT_MATERIAL = long("0x4130",16); # This is found if the object has a material, either texture map or color -OBJECT_UV = long("0x4140",16); # The UV texture coordinates -OBJECT_TRANS_MATRIX = long("0x4160",16); # The Object Matrix +OBJECT_VERTICES = int("0x4110",16); # The objects vertices +OBJECT_FACES = int("0x4120",16); # The objects faces +OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color +OBJECT_UV = int("0x4140",16); # The UV texture coordinates +OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix #>------ sub defines of KFDATA -KFDATA_KFHDR = long("0xB00A",16); -KFDATA_KFSEG = long("0xB008",16); -KFDATA_KFCURTIME = long("0xB009",16); -KFDATA_OBJECT_NODE_TAG = long("0xB002",16); +KFDATA_KFHDR = int("0xB00A",16); +KFDATA_KFSEG = int("0xB008",16); +KFDATA_KFCURTIME = int("0xB009",16); +KFDATA_OBJECT_NODE_TAG = int("0xB002",16); #>------ sub defines of OBJECT_NODE_TAG -OBJECT_NODE_ID = long("0xB030",16); -OBJECT_NODE_HDR = long("0xB010",16); -OBJECT_PIVOT = long("0xB013",16); -OBJECT_INSTANCE_NAME = long("0xB011",16); -POS_TRACK_TAG = long("0xB020",16); -ROT_TRACK_TAG = long("0xB021",16); -SCL_TRACK_TAG = long("0xB022",16); +OBJECT_NODE_ID = int("0xB030",16); +OBJECT_NODE_HDR = int("0xB010",16); +OBJECT_PIVOT = int("0xB013",16); +OBJECT_INSTANCE_NAME = int("0xB011",16); +POS_TRACK_TAG = int("0xB020",16); +ROT_TRACK_TAG = int("0xB021",16); +SCL_TRACK_TAG = int("0xB022",16); def uv_key(uv): return round(uv.x, 6), round(uv.y, 6) @@ -343,12 +346,12 @@ class _3ds_named_variable(object): def dump(self,indent): if (self.value!=None): spaces="" - for i in xrange(indent): + for i in range(indent): spaces+=" "; if (self.name!=""): - print spaces, self.name, " = ", self.value + print(spaces, self.name, " = ", self.value) else: - print spaces, "[unnamed]", " = ", self.value + print(spaces, "[unnamed]", " = ", self.value) #the chunk class @@ -408,9 +411,9 @@ class _3ds_chunk(object): Dump is used for debugging purposes, to dump the contents of a chunk to the standard output. Uses the dump function of the named variables and the subchunks to do the actual work.''' spaces="" - for i in xrange(indent): + for i in range(indent): spaces+=" "; - print spaces, "ID=", hex(self.ID.value), "size=", self.get_size() + print(spaces, "ID=", hex(self.ID.value), "size=", self.get_size()) for variable in self.variables: variable.dump(indent+1) for subchunk in self.subchunks: @@ -555,11 +558,11 @@ def remove_face_uv(verts, tri_list): # initialize a list of UniqueLists, one per vertex: #uv_list = [UniqueList() for i in xrange(len(verts))] - unique_uvs= [{} for i in xrange(len(verts))] + unique_uvs= [{} for i in range(len(verts))] # for each face uv coordinate, add it to the UniqueList of the vertex for tri in tri_list: - for i in xrange(3): + for i in range(3): # store the index into the UniqueList for future reference: # offset.append(uv_list[tri.vertex_index[i]].add(_3ds_point_uv(tri.faceuvs[i]))) @@ -589,7 +592,7 @@ def remove_face_uv(verts, tri_list): pt = _3ds_point_3d(vert.co) # reuse, should be ok uvmap = [None] * len(unique_uvs[i]) - for ii, uv_3ds in unique_uvs[i].itervalues(): + for ii, uv_3ds in unique_uvs[i].values(): # add a vertex duplicate to the vertex_array for every uv associated with this vertex: vert_array.add(pt) # add the uv coordinate to the uv array: @@ -607,7 +610,7 @@ def remove_face_uv(verts, tri_list): # Make sure the triangle vertex indices now refer to the new vertex list: for tri in tri_list: - for i in xrange(3): + for i in range(3): tri.offset[i]+=index_list[tri.vertex_index[i]] tri.vertex_index= tri.offset @@ -655,7 +658,7 @@ def make_faces_chunk(tri_list, mesh, materialDict): # obj_material_faces[tri.mat].add(_3ds_short(i)) face_chunk.add_variable("faces", face_list) - for mat_name, mat_faces in unique_mats.itervalues(): + for mat_name, mat_faces in unique_mats.values(): obj_material_chunk=_3ds_chunk(OBJECT_MATERIAL) obj_material_chunk.add_variable("name", mat_name) obj_material_chunk.add_variable("face_list", mat_faces) @@ -677,7 +680,7 @@ def make_faces_chunk(tri_list, mesh, materialDict): obj_material_faces[tri.mat].add(_3ds_short(i)) face_chunk.add_variable("faces", face_list) - for i in xrange(n_materials): + for i in range(n_materials): obj_material_chunk=_3ds_chunk(OBJECT_MATERIAL) obj_material_chunk.add_variable("name", obj_material_names[i]) obj_material_chunk.add_variable("face_list", obj_material_faces[i]) @@ -862,7 +865,7 @@ def make_kf_obj_node(obj, name_to_id): return kf_obj_node """ -import BPyMessages +# import BPyMessages def save_3ds(filename, context): '''Save the Blender scene to a 3ds file.''' # Time the export @@ -871,16 +874,16 @@ def save_3ds(filename, context): filename += '.3ds' # XXX -# if not BPyMessages.Warning_SaveOver(filename): -# return +# if not BPyMessages.Warning_SaveOver(filename): +# return # XXX - time1 = bpy.sys.time() -# time1= Blender.sys.time() -# Blender.Window.WaitCursor(1) + time1 = bpy.sys.time() +# time1= Blender.sys.time() +# Blender.Window.WaitCursor(1) sce = context.scene -# sce= bpy.data.scenes.active +# sce= bpy.data.scenes.active # Initialize the main chunk (primary): primary = _3ds_chunk(PRIMARY) @@ -948,7 +951,7 @@ def save_3ds(filename, context): f.mat = 0 # Make material chunks for all materials used in the meshes: - for mat_and_image in materialDict.itervalues(): + for mat_and_image in materialDict.values(): object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1])) # Give all objects a unique ID and build a dictionary from object name to object id: @@ -1011,15 +1014,44 @@ def save_3ds(filename, context): # Debugging only: report the exporting time: Blender.Window.WaitCursor(0) - print "3ds export time: %.2f" % (Blender.sys.time() - time1) + print("3ds export time: %.2f" % (Blender.sys.time() - time1)) # Debugging only: dump the chunk hierarchy: #primary.dump() -if __name__=='__main__': - if struct: - Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) - else: - Blender.Draw.PupMenu("Error%t|This script requires a full python installation") -# save_3ds('/test_b.3ds') +# if __name__=='__main__': +# if struct: +# Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) +# else: +# Blender.Draw.PupMenu("Error%t|This script requires a full python installation") +# # save_3ds('/test_b.3ds') + +class EXPORT_OT_3ds(bpy.types.Operator): + ''' + 3DS Exporter + ''' + __idname__ = "export.3ds" + __label__ = 'Export 3DS' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""), + ] + + def execute(self, context): + raise Exception("Not doing anything yet.") + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + def poll(self, context): # Poll isnt working yet + print("Poll") + return context.active_object != None + +bpy.ops.add(EXPORT_OT_3ds) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index fa07c5408a7..b2d4af7c517 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -913,7 +913,7 @@ class EXPORT_OT_obj(bpy.types.Operator): # to the class instance from the operator settings before calling. __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the OBJ file", maxlen= 1024, default= ""), # context group bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False), diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py index b12ff67d8a6..b57be2286e9 100644 --- a/release/io/export_x3d.py +++ b/release/io/export_x3d.py @@ -53,22 +53,27 @@ Known issues:
# Library dependancies #################################### -import Blender -from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh -from Blender.Scene import Render import math -import BPyObject -import BPyMesh + +import bpy +import Mathutils + +# import Blender +# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh +# from Blender.Scene import Render +# import BPyObject +# import BPyMesh # DEG2RAD=0.017453292519943295 -MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x') +MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x') #################################### # Global Variables #################################### -filename = Blender.Get('filename') +filename = "" +# filename = Blender.Get('filename') _safeOverwrite = True extension = '' @@ -109,7 +114,7 @@ class x3d_class: import gzip self.file = gzip.open(filename, "w") except: - print "failed to import compression modules, exporting uncompressed" + print("failed to import compression modules, exporting uncompressed") self.filename = filename[:-1] # remove trailing z if self.file == None: @@ -383,7 +388,7 @@ class x3d_class: if nIFSCnt > 1: self.writeIndented("\n" % ("G_", meshName),1) - if sided.has_key('two') and sided['two'] > 0: + if 'two' in sided and sided['two'] > 0: bTwoSided=1 else: bTwoSided=0 @@ -414,8 +419,8 @@ class x3d_class: if not matFlags & Blender.Material.Modes['TEXFACE']: self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world) if len(maters) > 1: - print "Warning: mesh named %s has multiple materials" % meshName - print "Warning: only one material per object handled" + print("Warning: mesh named %s has multiple materials" % meshName) + print("Warning: only one material per object handled") #-- textures if mesh.faceUV: @@ -433,7 +438,7 @@ class x3d_class: # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5 ifStyle="IndexedFaceSet" # look up mesh name, use it if available - if self.meshNames.has_key(meshME): + if meshME in self.meshNames: self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1) self.meshNames[meshME]+=1 else: @@ -547,7 +552,7 @@ class x3d_class: if self.writingtexture == 0: self.file.write("\n\t\t\ttexCoordIndex=\"") texIndxStr="" - for i in xrange(len(texIndexList)): + for i in range(len(texIndexList)): texIndxStr = texIndxStr + "%d, " % texIndexList[i] if texIndexList[i]==-1: self.file.write(texIndxStr) @@ -555,7 +560,7 @@ class x3d_class: self.file.write("\"\n\t\t\t") else: self.writeIndented("") self.writeIndented("\n", -1) @@ -569,7 +574,7 @@ class x3d_class: if face.col: c=face.col[0] if self.verbose > 2: - print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b) + print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) aColor = self.rgbToFS(c) self.file.write("%s, " % aColor) self.file.write("\" />") @@ -577,7 +582,7 @@ class x3d_class: def writeMaterial(self, mat, matName, world): # look up material name, use it if available - if self.matNames.has_key(matName): + if matName in self.matNames: self.writeIndented("\n" % matName) self.matNames[matName]+=1 return; @@ -617,7 +622,7 @@ class x3d_class: def writeImageTexture(self, image): name = image.name filename = image.filename.split('/')[-1].split('\\')[-1] - if self.texNames.has_key(name): + if name in self.texNames: self.writeIndented("\n" % self.cleanStr(name)) self.texNames[name] += 1 return @@ -671,7 +676,7 @@ class x3d_class: self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) alltexture = len(alltextures) - for i in xrange(alltexture): + for i in range(alltexture): namemat = alltextures[i].name pic = alltextures[i].getImage() if (namemat == "back") and (pic != None): @@ -697,7 +702,7 @@ class x3d_class: EXPORT_TRI= False,\ ): - print "Info: starting X3D export to " + self.filename + "..." + print("Info: starting X3D export to " + self.filename + "...") self.writeHeader() # self.writeScript() self.writeNavigationInfo(scene) @@ -771,7 +776,7 @@ class x3d_class: self.texNames={} self.matNames={} self.indentLevel=0 - print "Info: finished X3D export to %s\n" % self.filename + print("Info: finished X3D export to %s\n" % self.filename) def cleanStr(self, name, prefix='rsvd_'): """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name""" @@ -815,7 +820,7 @@ class x3d_class: else: sidename='one' - if sided.has_key(sidename): + if sidename in sided: sided[sidename]+=1 else: sided[sidename]=1 @@ -829,30 +834,30 @@ class x3d_class: imageMap[faceName]=[face.image.name,sidename,face] if self.verbose > 2: - for faceName in imageMap.iterkeys(): + for faceName in imageMap.keys(): ifs=imageMap[faceName] - print "Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \ - (faceName, ifs[0], ifs[1], len(ifs)-2) + print("Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \ + (faceName, ifs[0], ifs[1], len(ifs)-2)) return len(imageMap) def faceToString(self,face): - print "Debug: face.flag=0x%x (bitflags)" % face.flag + print("Debug: face.flag=0x%x (bitflags)" % face.flag) if face.sel: - print "Debug: face.sel=true" + print("Debug: face.sel=true") - print "Debug: face.mode=0x%x (bitflags)" % face.mode + print("Debug: face.mode=0x%x (bitflags)" % face.mode) if face.mode & Mesh.FaceModes.TWOSIDE: - print "Debug: face.mode twosided" + print("Debug: face.mode twosided") - print "Debug: face.transp=0x%x (enum)" % face.transp + print("Debug: face.transp=0x%x (enum)" % face.transp) if face.transp == Mesh.FaceTranspModes.SOLID: - print "Debug: face.transp.SOLID" + print("Debug: face.transp.SOLID") if face.image: - print "Debug: face.image=%s" % face.image.name - print "Debug: face.materialIndex=%d" % face.materialIndex + print("Debug: face.image=%s" % face.image.name) + print("Debug: face.materialIndex=%d" % face.materialIndex) def getVertexColorByIndx(self, mesh, indx): c = None @@ -867,12 +872,12 @@ class x3d_class: return c def meshToString(self,mesh): - print "Debug: mesh.hasVertexUV=%d" % mesh.vertexColors - print "Debug: mesh.faceUV=%d" % mesh.faceUV - print "Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours() - print "Debug: mesh.verts=%d" % len(mesh.verts) - print "Debug: mesh.faces=%d" % len(mesh.faces) - print "Debug: mesh.materials=%d" % len(mesh.materials) + print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors) + print("Debug: mesh.faceUV=%d" % mesh.faceUV) + print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()) + print("Debug: mesh.verts=%d" % len(mesh.verts)) + print("Debug: mesh.faces=%d" % len(mesh.faces)) + print("Debug: mesh.materials=%d" % len(mesh.materials)) def rgbToFS(self, c): s="%s %s %s" % ( @@ -924,7 +929,7 @@ class x3d_class: self.indentLevel = self.indentLevel + inc spaces="" - for x in xrange(self.indentLevel): + for x in range(self.indentLevel): spaces = spaces + "\t" self.file.write(spaces + s) @@ -1045,7 +1050,34 @@ def x3d_export_ui(filename): ######################################################### -if __name__ == '__main__': - Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) +# if __name__ == '__main__': +# Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) + +class EXPORT_OT_x3d(bpy.types.Operator): + ''' + X3D Exporter + ''' + __idname__ = "export.x3d" + __label__ = 'Export X3D' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen= 1024, default= ""), + ] + + def execute(self, context): + raise Exception("Not doing anything yet.") + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + def poll(self, context): # Poll isnt working yet + print("Poll") + return context.active_object != None +bpy.ops.add(EXPORT_OT_x3d) diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py index bcde82c4869..a08fdb8fc85 100644 --- a/release/io/import_3ds.py +++ b/release/io/import_3ds.py @@ -125,26 +125,29 @@ Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). # Importing modules -import Blender +from struct import calcsize, unpack + import bpy -from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils -from Blender.Mathutils import Vector -import BPyImage -import BPyMessages +# import Blender +# from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils +# from Blender.Mathutils import Vector +# import BPyImage + +# import BPyMessages -try: - from struct import calcsize, unpack -except: - calcsize= unpack= None +# try: +# from struct import calcsize, unpack +# except: +# calcsize= unpack= None -# If python version is less than 2.4, try to get set stuff from module -try: - set -except: - from sets import Set as set +# # If python version is less than 2.4, try to get set stuff from module +# try: +# set +# except: +# from sets import Set as set BOUNDS_3DS= [] @@ -167,12 +170,12 @@ def createBlenderTexture(material, name, image): #Some of the chunks that we will see #----- Primary Chunk, at the beginning of each file -PRIMARY= long('0x4D4D',16) +PRIMARY= int('0x4D4D',16) #------ Main Chunks -OBJECTINFO = long('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information -VERSION = long('0x0002',16); #This gives the version of the .3ds file -EDITKEYFRAME= long('0xB000',16); #This is the header for all of the key frame info +OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information +VERSION = int('0x0002',16); #This gives the version of the .3ds file +EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info #------ sub defines of OBJECTINFO MATERIAL=45055 #0xAFFF // This stored the texture info @@ -180,62 +183,62 @@ OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... #>------ sub defines of MATERIAL #------ sub defines of MATERIAL_BLOCK -MAT_NAME = long('0xA000',16) # This holds the material name -MAT_AMBIENT = long('0xA010',16) # Ambient color of the object/material -MAT_DIFFUSE = long('0xA020',16) # This holds the color of the object/material -MAT_SPECULAR = long('0xA030',16) # SPecular color of the object/material -MAT_SHINESS = long('0xA040',16) # ?? -MAT_TRANSPARENCY= long('0xA050',16) # Transparency value of material -MAT_SELF_ILLUM = long('0xA080',16) # Self Illumination value of material -MAT_WIRE = long('0xA085',16) # Only render's wireframe - -MAT_TEXTURE_MAP = long('0xA200',16) # This is a header for a new texture map -MAT_SPECULAR_MAP= long('0xA204',16) # This is a header for a new specular map -MAT_OPACITY_MAP = long('0xA210',16) # This is a header for a new opacity map -MAT_REFLECTION_MAP= long('0xA220',16) # This is a header for a new reflection map -MAT_BUMP_MAP = long('0xA230',16) # This is a header for a new bump map -MAT_MAP_FILENAME = long('0xA300',16) # This holds the file name of the texture - -MAT_FLOAT_COLOR = long ('0x0010', 16) #color defined as 3 floats -MAT_24BIT_COLOR = long ('0x0011', 16) #color defined as 3 bytes +MAT_NAME = int('0xA000',16) # This holds the material name +MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material +MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material +MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material +MAT_SHINESS = int('0xA040',16) # ?? +MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material +MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material +MAT_WIRE = int('0xA085',16) # Only render's wireframe + +MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map +MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map +MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map +MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map +MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map +MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture + +MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats +MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes #>------ sub defines of OBJECT -OBJECT_MESH = long('0x4100',16); # This lets us know that we are reading a new object -OBJECT_LAMP = long('0x4600',16); # This lets un know we are reading a light object -OBJECT_LAMP_SPOT = long('0x4610',16); # The light is a spotloght. -OBJECT_LAMP_OFF = long('0x4620',16); # The light off. -OBJECT_LAMP_ATTENUATE = long('0x4625',16); -OBJECT_LAMP_RAYSHADE = long('0x4627',16); -OBJECT_LAMP_SHADOWED = long('0x4630',16); -OBJECT_LAMP_LOCAL_SHADOW = long('0x4640',16); -OBJECT_LAMP_LOCAL_SHADOW2 = long('0x4641',16); -OBJECT_LAMP_SEE_CONE = long('0x4650',16); -OBJECT_LAMP_SPOT_RECTANGULAR= long('0x4651',16); -OBJECT_LAMP_SPOT_OVERSHOOT= long('0x4652',16); -OBJECT_LAMP_SPOT_PROJECTOR= long('0x4653',16); -OBJECT_LAMP_EXCLUDE= long('0x4654',16); -OBJECT_LAMP_RANGE= long('0x4655',16); -OBJECT_LAMP_ROLL= long('0x4656',16); -OBJECT_LAMP_SPOT_ASPECT= long('0x4657',16); -OBJECT_LAMP_RAY_BIAS= long('0x4658',16); -OBJECT_LAMP_INNER_RANGE= long('0x4659',16); -OBJECT_LAMP_OUTER_RANGE= long('0x465A',16); -OBJECT_LAMP_MULTIPLIER = long('0x465B',16); -OBJECT_LAMP_AMBIENT_LIGHT = long('0x4680',16); - - - -OBJECT_CAMERA= long('0x4700',16); # This lets un know we are reading a camera object +OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object +OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object +OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght. +OBJECT_LAMP_OFF = int('0x4620',16); # The light off. +OBJECT_LAMP_ATTENUATE = int('0x4625',16); +OBJECT_LAMP_RAYSHADE = int('0x4627',16); +OBJECT_LAMP_SHADOWED = int('0x4630',16); +OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16); +OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16); +OBJECT_LAMP_SEE_CONE = int('0x4650',16); +OBJECT_LAMP_SPOT_RECTANGULAR= int('0x4651',16); +OBJECT_LAMP_SPOT_OVERSHOOT= int('0x4652',16); +OBJECT_LAMP_SPOT_PROJECTOR= int('0x4653',16); +OBJECT_LAMP_EXCLUDE= int('0x4654',16); +OBJECT_LAMP_RANGE= int('0x4655',16); +OBJECT_LAMP_ROLL= int('0x4656',16); +OBJECT_LAMP_SPOT_ASPECT= int('0x4657',16); +OBJECT_LAMP_RAY_BIAS= int('0x4658',16); +OBJECT_LAMP_INNER_RANGE= int('0x4659',16); +OBJECT_LAMP_OUTER_RANGE= int('0x465A',16); +OBJECT_LAMP_MULTIPLIER = int('0x465B',16); +OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16); + + + +OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object #>------ sub defines of CAMERA -OBJECT_CAM_RANGES= long('0x4720',16); # The camera range values +OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values #>------ sub defines of OBJECT_MESH -OBJECT_VERTICES = long('0x4110',16); # The objects vertices -OBJECT_FACES = long('0x4120',16); # The objects faces -OBJECT_MATERIAL = long('0x4130',16); # This is found if the object has a material, either texture map or color -OBJECT_UV = long('0x4140',16); # The UV texture coordinates -OBJECT_TRANS_MATRIX = long('0x4160',16); # The Object Matrix +OBJECT_VERTICES = int('0x4110',16); # The objects vertices +OBJECT_FACES = int('0x4120',16); # The objects faces +OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color +OBJECT_UV = int('0x4140',16); # The UV texture coordinates +OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix global scn scn= None @@ -255,10 +258,10 @@ class chunk: self.bytes_read=0 def dump(self): - print 'ID: ', self.ID - print 'ID in hex: ', hex(self.ID) - print 'length: ', self.length - print 'bytes_read: ', self.bytes_read + print('ID: ', self.ID) + print('ID in hex: ', hex(self.ID)) + print('length: ', self.length) + print('bytes_read: ', self.bytes_read) def read_chunk(file, chunk): temp_data=file.read(calcsize(chunk.binary_format)) @@ -309,13 +312,13 @@ def add_texture_to_material(image, texture, material, mapto): elif mapto=='BUMP': map=Texture.MapTo.NOR else: - print '/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name) + print('/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name)) map=Texture.MapTo.COL if image: texture.setImage(image) # double check its an image. free_tex_slots= [i for i, tex in enumerate( material.getTextures() ) if tex==None] if not free_tex_slots: - print '/tError: Cannot add "%s" map. 10 Texture slots alredy used.' % mapto + print('/tError: Cannot add "%s" map. 10 Texture slots alredy used.' % mapto) else: material.setTexture(free_tex_slots[0],texture,Texture.TexCo.UV,map) @@ -374,7 +377,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): myVertMapping = {} vertMappingIndex = 0 - vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]] + vertsToUse = [i for i in range(len(myContextMesh_vertls)) if faceVertUsers[i]] myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] ) tempName= '%s_%s' % (contextObName, matName) # matName may be None. @@ -423,7 +426,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): importedObjects.append(ob) bmesh.calcNormals() - for matName, faces in myContextMeshMaterials.iteritems(): + for matName, faces in myContextMeshMaterials.items(): makeMeshMaterialCopy(matName, faces) if len(materialFaces)!=len(myContextMesh_facels): @@ -455,7 +458,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): new_chunk.bytes_read+= 4 #read the 4 bytes for the version number #this loader works with version 3 and below, but may not with 4 and above if (version>3): - print '\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version + print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) #is it an object info chunk? elif (new_chunk.ID==OBJECTINFO): @@ -684,7 +687,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): return temp_data #contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed. - contextMesh_vertls= [getvert() for i in xrange(num_verts)] + contextMesh_vertls= [getvert() for i in range(num_verts)] #print 'object verts: bytes read: ', new_chunk.bytes_read @@ -702,7 +705,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): v1,v2,v3,dummy= unpack('<4H', temp_data) return v1, v2, v3 - contextMesh_facels= [ getface() for i in xrange(num_faces) ] + contextMesh_facels= [ getface() for i in range(num_faces) ] elif (new_chunk.ID==OBJECT_MATERIAL): @@ -719,7 +722,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT return unpack(' Date: Mon, 10 Aug 2009 21:37:16 +0000 Subject: Ability to disable hints at compile time --- source/blender/render/SConscript | 2 +- .../render/intern/raytrace/rayobject_vbvh.cpp | 37 ++++++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 2228ff9ebb9..9c1dd385635 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,7 +1,7 @@ #!/usr/bin/python Import ('env') -cflags = ['-O3'] +cflags = ['-O3','-msse2','-mfpmath=sse'] cxxflags = ['-O3','-msse2','-mfpmath=sse'] sources = env.Glob('intern/source/*.c') raysources = env.Glob('intern/raytrace/*.cpp') diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 2f0efa80445..834a1286fb8 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -46,6 +46,8 @@ extern "C" #define BVHNode VBVHNode #define BVHTree VBVHTree + +#define RE_DO_HINTS (0) #define RAY_BB_TEST_COST (0.2f) #define DFS_STACK_SIZE 256 //#define DYNAMIC_ALLOC_BB @@ -293,20 +295,20 @@ Node *bvh_rearrange(Tree *tree, Builder *builder) template float bvh_refit(Node *node) { - if(RayObject_isAligned(node)) return 0; - if(RayObject_isAligned(node->child)) return 0; + if(!RayObject_isAligned(node)) return 0; + if(!RayObject_isAligned(node->child)) return 0; float total = 0; - for(Node *child = node->child; RayObject_isAligned(child) && child; child = child->sibling) + for(Node *child = node->child; child; child = child->sibling) total += bvh_refit(child); float old_area = bb_area(node->bb, node->bb+3); INIT_MINMAX(node->bb, node->bb+3); - for(Node *child = node->child; RayObject_isAligned(child) && child; child = child->sibling) + for(Node *child = node->child; child; child = child->sibling) { DO_MIN(child->bb, node->bb); - DO_MIN(child->bb+3, node->bb+3); + DO_MAX(child->bb+3, node->bb+3); } total += old_area - bb_area(node->bb, node->bb+3); return total; @@ -329,8 +331,8 @@ void bvh_done(BVHTree *obj) obj->root = bvh_rearrange( obj, obj->builder ); reorganize(obj->root); remove_useless(obj->root, &obj->root); - pushup(obj->root); printf("refit: %f\n", bvh_refit(obj->root) ); + pushup(obj->root); pushdown(obj->root); // obj->root = memory_rearrange(obj->root); obj->cost = 1.0; @@ -342,7 +344,7 @@ void bvh_done(BVHTree *obj) template int intersect(BVHTree *obj, Isect* isec) { - if(isec->hint) + if(RE_DO_HINTS && isec->hint) { LCTSHint *lcts = (LCTSHint*)isec->hint; isec->hint = 0; @@ -423,13 +425,22 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject template void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) { - HintBB bb; - VECCOPY(bb.bb, min); - VECCOPY(bb.bb+3, max); + if(RE_DO_HINTS) + { + HintBB bb; + VECCOPY(bb.bb, min); + VECCOPY(bb.bb+3, max); - hint->size = 0; - bvh_dfs_make_hint( tree->root, hint, 0, &bb ); - tot_hints++; + hint->size = 0; + bvh_dfs_make_hint( tree->root, hint, 0, &bb ); + tot_hints++; + } + else + { + hint->size = 0; + hint->stack[hint->size++] = (RayObject*)tree->root; + tot_hints++; + } } void bfree(BVHTree *tree) -- cgit v1.2.3 From 5d40c1b59784316473b79d5a61188f3e17f020b7 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 11 Aug 2009 00:33:51 +0000 Subject: *Added a tree structure with a variable number of childs per node, but with groupped childs (for SIMD) *SIMD support for the first 4*N childs of each node *Some bvh code organized --- source/blender/render/intern/raytrace/bvh.h | 41 ++- .../render/intern/raytrace/rayobject_vbvh.cpp | 334 ++++++++++----------- source/blender/render/intern/raytrace/reorganize.h | 108 ++++++- source/blender/render/intern/raytrace/svbvh.h | 230 ++++++++++++++ 4 files changed, 522 insertions(+), 191 deletions(-) create mode 100644 source/blender/render/intern/raytrace/svbvh.h diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index f6c12f4b3fb..8538d9201e0 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -28,6 +28,9 @@ */ #include +#ifndef RE_RAYTRACE_BVH_H +#define RE_RAYTRACE_BVH_H + inline int test_bb_group4(__m128 *bb_group, const Isect *isec) { @@ -53,6 +56,12 @@ template static void bvh_add(Tree *obj, RayObject *ob) rtbuild_add( obj->builder, ob ); } +template +inline bool is_leaf(Node *node) +{ + return !RayObject_isAligned(node); +} + template static void bvh_done(Tree *obj); template @@ -93,14 +102,14 @@ template static inline int bvh_node_hit_test(Node *node, Isect *isec template static void bvh_node_merge_bb(Node *node, float *min, float *max) { - if(RayObject_isAligned(node)) + if(is_leaf(node)) { - DO_MIN(node->bb , min); - DO_MAX(node->bb+3, max); + RE_rayobject_merge_bb( (RayObject*)node, min, max); } else { - RE_rayobject_merge_bb( (RayObject*)node, min, max); + DO_MIN(node->bb , min); + DO_MAX(node->bb+3, max); } } @@ -117,7 +126,7 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) Node *stack[MAX_STACK_SIZE]; int hit = 0, stack_pos = 0; - if(!TEST_ROOT && RayObject_isAligned(root)) + if(!TEST_ROOT && !is_leaf(root)) bvh_node_push_childs(root, isec, stack, stack_pos); else stack[stack_pos++] = root; @@ -125,7 +134,7 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) while(stack_pos) { Node *node = stack[--stack_pos]; - if(RayObject_isAligned(node)) + if(!is_leaf(node)) { if(bvh_node_hit_test(node,isec)) { @@ -157,9 +166,9 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) if(!TEST_ROOT) { - if(RayObject_isAligned(root)) + if(!is_leaf(root)) { - if(RayObject_isAligned(root->child)) + if(!is_leaf(root->child)) bvh_node_push_childs(root, isec, stack, stack_pos); else return RE_rayobject_intersect( (RayObject*)root->child, isec); @@ -169,7 +178,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) } else { - if(RayObject_isAligned(root)) + if(!is_leaf(root)) stack[stack_pos++] = root; else return RE_rayobject_intersect( (RayObject*)root, isec); @@ -214,7 +223,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) for(int i=0; i<4; i++) { Node *t = stack[stack_pos+i]; - assert(RayObject_isAligned(t)); + assert(!is_leaf(t)); float *bb = ((float*)t_bb)+i; bb[4*0] = t->bb[0]; @@ -237,7 +246,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) if(res & (1<raycounter->bb.hit); - if(RayObject_isAligned(t_node[i])) + if(!is_leaf(t_node[i])) { for(Node *t=t_node[i]; t; t=t->sibling) { @@ -255,11 +264,11 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) else if(stack_pos > 0) { Node *node = stack[--stack_pos]; - assert(RayObject_isAligned(node)); + assert(!is_leaf(node)); if(bvh_node_hit_test(node,isec)) { - if(RayObject_isAligned(node->child)) + if(!is_leaf(node->child)) { bvh_node_push_childs(node, isec, stack, stack_pos); assert(stack_pos <= MAX_STACK_SIZE); @@ -291,7 +300,7 @@ static int bvh_node_raycast(Node *node, Isect *isec) { int i; for(i=0; ichild[i])) + if(!is_leaf(node->child[i])) { if(node->child[i] == 0) break; @@ -308,7 +317,7 @@ static int bvh_node_raycast(Node *node, Isect *isec) { int i; for(i=BVH_NCHILDS-1; i>=0; i--) - if(RayObject_isAligned(node->child[i])) + if(!is_leaf(node->child[i])) { if(node->child[i]) { @@ -326,3 +335,5 @@ static int bvh_node_raycast(Node *node, Isect *isec) return hit; } */ + +#endif diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 834a1286fb8..7f990e06152 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -26,6 +26,12 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#define RE_USE_HINT (0) +static int tot_pushup = 0; +static int tot_pushdown = 0; +static int tot_hints = 0; + + extern "C" { #include @@ -41,22 +47,21 @@ extern "C" #include "rayobject_hint.h" #include "reorganize.h" #include "bvh.h" +#include "svbvh.h" #include -#define BVHNode VBVHNode -#define BVHTree VBVHTree - #define RE_DO_HINTS (0) #define RAY_BB_TEST_COST (0.2f) #define DFS_STACK_SIZE 256 //#define DYNAMIC_ALLOC_BB + //#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ //#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ #define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ -struct BVHNode +struct VBVHNode { #ifdef DYNAMIC_ALLOC_BB float *bb; @@ -64,15 +69,15 @@ struct BVHNode float bb[6]; #endif - BVHNode *child; - BVHNode *sibling; + VBVHNode *child; + VBVHNode *sibling; }; -struct BVHTree +struct VBVHTree { RayObject rayobj; - BVHNode *root; + SVBVHNode *root; MemArena *node_arena; @@ -81,6 +86,54 @@ struct BVHTree }; + + +template +struct Reorganize_VBVH +{ + Tree *tree; + + Reorganize_VBVH(Tree *t) + { + tree = t; + } + + VBVHNode *create_node() + { + VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); + return node; + } + + void copy_bb(VBVHNode *node, OldNode *old) + { + std::copy( old->bb, old->bb+6, node->bb ); + } + + VBVHNode *transform(OldNode *old) + { + if(is_leaf(old)) + return (VBVHNode*)old; + + VBVHNode *node = create_node(); + VBVHNode **child_ptr = &node->child; + node->sibling = 0; + + copy_bb(node,old); + + for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) + { + VBVHNode *n_child = transform(o_child); + *child_ptr = n_child; + if(is_leaf(n_child)) return node; + child_ptr = &n_child->sibling; + } + *child_ptr = 0; + + return node; + } +}; + + /* * Push nodes (used on dfs) */ @@ -89,7 +142,7 @@ inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, i { Node *child = node->child; - if(!RayObject_isAligned(child)) + if(is_leaf(child)) { stack[stack_pos++] = child; } @@ -99,7 +152,7 @@ inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, i { //Skips BB tests on primitives /* - if(!RayObject_isAligned(child->child)) + if(is_leaf(child->child)) stack[stack_pos++] = child->child; else */ @@ -113,9 +166,9 @@ inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, i /* * BVH done */ -static BVHNode *bvh_new_node(BVHTree *tree) +static VBVHNode *bvh_new_node(VBVHTree *tree) { - BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); + VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); if( (((intptr_t)node) & (0x0f)) != 0 ) { @@ -132,70 +185,7 @@ static BVHNode *bvh_new_node(BVHTree *tree) return node; } -template -float rtbuild_area(Builder *builder) -{ - float min[3], max[3]; - INIT_MINMAX(min, max); - rtbuild_merge_bb(builder, min, max); - return bb_area(min, max); -} - -template -void bvh_update_bb(Node *node) -{ - INIT_MINMAX(node->bb, node->bb+3); - Node *child = node->child; - - while(child) - { - bvh_node_merge_bb(child, node->bb, node->bb+3); - if(RayObject_isAligned(child)) - child = child->sibling; - else - child = 0; - } -} - -static int tot_pushup = 0; -static int tot_pushdown = 0; -static int tot_hints = 0; - -template -void pushdown(Node *parent) -{ - Node **s_child = &parent->child; - Node * child = parent->child; - - while(child && RayObject_isAligned(child)) - { - Node *next = child->sibling; - Node **next_s_child = &child->sibling; - - //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); - - for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) - if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3) && RayObject_isAligned(i->child)) - { -// todo optimize (should the one with the smallest area?) -// float ia = bb_area(i->bb, i->bb+3) -// if(child->i) - *s_child = child->sibling; - child->sibling = i->child; - i->child = child; - next_s_child = s_child; - - tot_pushdown++; - break; - } - child = next; - s_child = next_s_child; - } - - for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) - pushdown( i ); -} template int count_childs(Node *parent) @@ -204,7 +194,7 @@ int count_childs(Node *parent) for(Node *i = parent->child; i; i = i->sibling) { n++; - if(!RayObject_isAligned(i)) + if(is_leaf(i)) break; } @@ -220,39 +210,6 @@ void append_sibling(Node *node, Node *sibling) node->sibling = sibling; } -template -void pushup(Node *parent) -{ - float p_area = bb_area(parent->bb, parent->bb+3); - Node **prev = &parent->child; - for(Node *child = parent->child; RayObject_isAligned(child) && child; ) - { - float c_area = bb_area(child->bb, child->bb+3) ; - int nchilds = count_childs(child); - float original_cost = (c_area / p_area)*nchilds + 1; - float flatten_cost = nchilds; - if(flatten_cost < original_cost && nchilds >= 2) - { - append_sibling(child, child->child); - child = child->sibling; - *prev = child; - -// *prev = child->child; -// append_sibling( *prev, child->sibling ); -// child = *prev; - tot_pushup++; - } - else - { - *prev = child; - prev = &(*prev)->sibling; - child = *prev; - } - } - - for(Node *child = parent->child; RayObject_isAligned(child) && child; child = child->sibling) - pushup(child); -} template Node *bvh_rearrange(Tree *tree, Builder *builder) @@ -264,7 +221,7 @@ Node *bvh_rearrange(Tree *tree, Builder *builder) Node *node = bvh_new_node(tree); INIT_MINMAX(node->bb, node->bb+3); rtbuild_merge_bb(builder, node->bb, node->bb+3); - node->child = (BVHNode*) rtbuild_get_primitive( builder, 0 ); + node->child = (VBVHNode*) rtbuild_get_primitive( builder, 0 ); return node; } else @@ -292,30 +249,8 @@ Node *bvh_rearrange(Tree *tree, Builder *builder) } } -template -float bvh_refit(Node *node) -{ - if(!RayObject_isAligned(node)) return 0; - if(!RayObject_isAligned(node->child)) return 0; - - float total = 0; - - for(Node *child = node->child; child; child = child->sibling) - total += bvh_refit(child); - - float old_area = bb_area(node->bb, node->bb+3); - INIT_MINMAX(node->bb, node->bb+3); - for(Node *child = node->child; child; child = child->sibling) - { - DO_MIN(child->bb, node->bb); - DO_MAX(child->bb+3, node->bb+3); - } - total += old_area - bb_area(node->bb, node->bb+3); - return total; -} - template<> -void bvh_done(BVHTree *obj) +void bvh_done(VBVHTree *obj) { rtbuild_done(obj->builder); @@ -323,18 +258,47 @@ void bvh_done(BVHTree *obj) if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) needed_nodes = BLI_MEMARENA_STD_BUFSIZE; - obj->node_arena = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(obj->node_arena); - BLI_memarena_use_align(obj->node_arena, 16); + MemArena *arena1 = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(arena1); + BLI_memarena_use_align(arena1, 16); + obj->node_arena = arena1; + + VBVHNode *root = bvh_rearrange( obj, obj->builder ); + reorganize(root); + remove_useless(root, &root); + printf("refit: %f\n", bvh_refit(root) ); + + pushup(root); + pushdown(root); + //Memory re-organize + if(0) + { + MemArena *arena2 = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(arena2); + BLI_memarena_use_align(arena2, 16); + obj->node_arena = arena2; + root = Reorganize_VBVH(obj).transform(root); - obj->root = bvh_rearrange( obj, obj->builder ); - reorganize(obj->root); - remove_useless(obj->root, &obj->root); - printf("refit: %f\n", bvh_refit(obj->root) ); - pushup(obj->root); - pushdown(obj->root); -// obj->root = memory_rearrange(obj->root); + BLI_memarena_free(arena1); + } + + if(1) + { + MemArena *arena2 = BLI_memarena_new(needed_nodes); + BLI_memarena_use_malloc(arena2); + BLI_memarena_use_align(arena2, 16); + obj->node_arena = arena2; + obj->root = Reorganize_SVBVH(obj).transform(root); + + BLI_memarena_free(arena1); + } +/* + { + obj->root = root; + } +*/ + obj->cost = 1.0; rtbuild_free( obj->builder ); @@ -342,8 +306,9 @@ void bvh_done(BVHTree *obj) } template -int intersect(BVHTree *obj, Isect* isec) +int intersect(VBVHTree *obj, Isect* isec) { +/* if(RE_DO_HINTS && isec->hint) { LCTSHint *lcts = (LCTSHint*)isec->hint; @@ -352,9 +317,9 @@ int intersect(BVHTree *obj, Isect* isec) int hit = 0; for(int i=0; isize; i++) { - BVHNode *node = (BVHNode*)lcts->stack[i]; + VBVHNode *node = (VBVHNode*)lcts->stack[i]; if(RayObject_isAligned(node)) - hit |= bvh_node_stack_raycast_simd(node, isec); + hit |= bvh_node_stack_raycast(node, isec); else hit |= RE_rayobject_intersect( (RayObject*)node, isec ); @@ -365,9 +330,10 @@ int intersect(BVHTree *obj, Isect* isec) return hit; } else +*/ { if(RayObject_isAligned(obj->root)) - return bvh_node_stack_raycast_simd(obj->root, isec); + return bvh_node_stack_raycast( obj->root, isec); else return RE_rayobject_intersect( (RayObject*) obj->root, isec ); } @@ -395,7 +361,7 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject { assert( hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); - if(!RayObject_isAligned(node)) + if(is_leaf(node)) { hint->stack[hint->size++] = (RayObject*)node; } @@ -425,25 +391,26 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject template void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) { - if(RE_DO_HINTS) +/* + if(RE_USE_HINT) { HintBB bb; VECCOPY(bb.bb, min); VECCOPY(bb.bb+3, max); - + hint->size = 0; bvh_dfs_make_hint( tree->root, hint, 0, &bb ); tot_hints++; } else +*/ { - hint->size = 0; - hint->stack[hint->size++] = (RayObject*)tree->root; - tot_hints++; + hint->size = 0; + hint->stack[hint->size++] = (RayObject*)tree->root; } } -void bfree(BVHTree *tree) +void bfree(VBVHTree *tree) { if(tot_pushup + tot_pushdown + tot_hints + tot_moves) { @@ -460,47 +427,63 @@ void bfree(BVHTree *tree) } /* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -template +template static RayObjectAPI make_api() { static RayObjectAPI api = { - (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &intersect), - (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), - (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), -// (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), - (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bfree), - (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), - (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost), - (RE_rayobject_hint_bb_callback) ((void(*)(BVHTree*,LCTSHint*,float*,float*)) &bvh_hint_bb) + (RE_rayobject_raycast_callback) ((int(*)(Tree*,Isect*)) &intersect), + (RE_rayobject_add_callback) ((void(*)(Tree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done), +// (RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free), + (RE_rayobject_free_callback) ((void(*)(Tree*)) &bfree), + (RE_rayobject_merge_bb_callback)((void(*)(Tree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost), + (RE_rayobject_hint_bb_callback) ((void(*)(Tree*,LCTSHint*,float*,float*)) &bvh_hint_bb) }; return api; } +template static RayObjectAPI* get_api(int maxstacksize) { -// static RayObjectAPI bvh_api16 = make_api<16>(); -// static RayObjectAPI bvh_api32 = make_api<32>(); -// static RayObjectAPI bvh_api64 = make_api<64>(); - static RayObjectAPI bvh_api128 = make_api<128>(); - static RayObjectAPI bvh_api256 = make_api<256>(); + static RayObjectAPI bvh_api256 = make_api(); -// if(maxstacksize <= 16 ) return &bvh_api16; -// if(maxstacksize <= 32 ) return &bvh_api32; -// if(maxstacksize <= 64 ) return &bvh_api64; - if(maxstacksize <= 128) return &bvh_api128; - if(maxstacksize <= 256) return &bvh_api256; + if(maxstacksize <= 1024) return &bvh_api256; assert(maxstacksize <= 256); return 0; } RayObject *RE_rayobject_vbvh_create(int size) { - BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); + VBVHTree *obj= (VBVHTree*)MEM_callocN(sizeof(VBVHTree), "VBVHTree"); assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - obj->rayobj.api = get_api(DFS_STACK_SIZE); + obj->rayobj.api = get_api(DFS_STACK_SIZE); + obj->root = NULL; + + obj->node_arena = NULL; + obj->builder = rtbuild_create( size ); + + return RayObject_unalignRayAPI((RayObject*) obj); +} + + + +/* SVBVH */ +template +void bvh_dfs_make_hint(VBVHNode *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) +{ + return; +} +/* +RayObject *RE_rayobject_svbvh_create(int size) +{ + SVBVHTree *obj= (SVBVHTree*)MEM_callocN(sizeof(SVBVHTree), "SVBVHTree"); + assert( RayObject_isAligned(obj) ); // RayObject API assumes real data to be 4-byte aligned + + obj->rayobj.api = get_api(DFS_STACK_SIZE); obj->root = NULL; obj->node_arena = NULL; @@ -508,3 +491,4 @@ RayObject *RE_rayobject_vbvh_create(int size) return RayObject_unalignRayAPI((RayObject*) obj); } +*/ \ No newline at end of file diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h index 723c2b77902..2f79b0f6e82 100644 --- a/source/blender/render/intern/raytrace/reorganize.h +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -130,9 +130,115 @@ void remove_useless(Node *node, Node **new_node) } if(node->child) { - if(RayObject_isAligned(node->child) && node->child->child == 0) + if(RayObject_isAligned(node->child) && node->child->sibling == 0) *new_node = node->child; } else if(node->child == 0) *new_node = 0; } + +/* + * Minimizes expected number of BBtest by colapsing nodes + * it uses surface area heuristic for determining whether a node should be colapsed + */ +template +void pushup(Node *parent) +{ + float p_area = bb_area(parent->bb, parent->bb+3); + Node **prev = &parent->child; + for(Node *child = parent->child; RayObject_isAligned(child) && child; ) + { + float c_area = bb_area(child->bb, child->bb+3) ; + int nchilds = count_childs(child); + float original_cost = (c_area / p_area)*nchilds + 1; + float flatten_cost = nchilds; + if(flatten_cost < original_cost && nchilds >= 2) + { + append_sibling(child, child->child); + child = child->sibling; + *prev = child; + +// *prev = child->child; +// append_sibling( *prev, child->sibling ); +// child = *prev; + tot_pushup++; + } + else + { + *prev = child; + prev = &(*prev)->sibling; + child = *prev; + } + } + + for(Node *child = parent->child; RayObject_isAligned(child) && child; child = child->sibling) + pushup(child); +} + + + +/* + * Pushdown + * makes sure no child fits inside any of its sibling + */ +template +void pushdown(Node *parent) +{ + Node **s_child = &parent->child; + Node * child = parent->child; + + while(child && RayObject_isAligned(child)) + { + Node *next = child->sibling; + Node **next_s_child = &child->sibling; + + //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); + + for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) + if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3) && RayObject_isAligned(i->child)) + { +// todo optimize (should the one with the smallest area?) +// float ia = bb_area(i->bb, i->bb+3) +// if(child->i) + *s_child = child->sibling; + child->sibling = i->child; + i->child = child; + next_s_child = s_child; + + tot_pushdown++; + break; + } + child = next; + s_child = next_s_child; + } + + for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) + pushdown( i ); +} + + +/* + * BVH refit + * reajust nodes BB (useful if nodes childs where modified) + */ +template +float bvh_refit(Node *node) +{ + if(is_leaf(node)) return 0; + if(is_leaf(node->child)) return 0; + + float total = 0; + + for(Node *child = node->child; child; child = child->sibling) + total += bvh_refit(child); + + float old_area = bb_area(node->bb, node->bb+3); + INIT_MINMAX(node->bb, node->bb+3); + for(Node *child = node->child; child; child = child->sibling) + { + DO_MIN(child->bb, node->bb); + DO_MAX(child->bb+3, node->bb+3); + } + total += old_area - bb_area(node->bb, node->bb+3); + return total; +} diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h new file mode 100644 index 00000000000..f537aa79dac --- /dev/null +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -0,0 +1,230 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYTRACE_SVBVH_H +#define RE_RAYTRACE_SVBVH_H + +#define SVBVH_SIMD 1 + +#include "bvh.h" +#include + +struct SVBVHNode +{ + int nchilds; + + //Array of bb, array of childs + float *bb; + SVBVHNode **child; +}; + +template<> +inline int bvh_node_hit_test(SVBVHNode *node, Isect *isec) +{ + return 1; +} + +template<> +inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHNode **stack, int &stack_pos) +{ + if(SVBVH_SIMD) + { + int i=0; + while(i+4 <= node->nchilds) + { + int res = test_bb_group4( (__m128*) (node->bb+6*i), isec ); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + + if(res & 1) { stack[stack_pos++] = node->child[i+0]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 2) { stack[stack_pos++] = node->child[i+1]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 4) { stack[stack_pos++] = node->child[i+2]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 8) { stack[stack_pos++] = node->child[i+3]; RE_RC_COUNT(isec->raycounter->bb.hit); } + + i += 4; + } + while(i < node->nchilds) + { + if(RE_rayobject_bb_intersect_test(isec, (const float*)node->bb+6*i)) + stack[stack_pos++] = node->child[i]; + i++; + } + } + else + { + for(int i=0; inchilds; i++) + { + if(RE_rayobject_bb_intersect_test(isec, (const float*)node->bb+6*i)) + stack[stack_pos++] = node->child[i]; + } + } +} + +struct SVBVHTree +{ + RayObject rayobj; + + SVBVHNode *root; + + MemArena *node_arena; + + float cost; + RTBuilder *builder; +}; + + + +template +struct Reorganize_SVBVH +{ + Tree *tree; + + float childs_per_node; + int nodes_with_childs[16]; + int nodes; + + Reorganize_SVBVH(Tree *t) + { + tree = t; + nodes = 0; + childs_per_node = 0; + + for(int i=0; i<16; i++) + nodes_with_childs[i] = 0; + } + + ~Reorganize_SVBVH() + { + printf("%f childs per node\n", childs_per_node / nodes); + for(int i=0; i<16; i++) + printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i]/float(nodes)); + } + + SVBVHNode *create_node(int nchilds) + { + SVBVHNode *node = (SVBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(SVBVHNode)); + node->nchilds = nchilds; + node->bb = (float*)BLI_memarena_alloc(tree->node_arena, sizeof(float)*6*nchilds); + node->child= (SVBVHNode**)BLI_memarena_alloc(tree->node_arena, sizeof(SVBVHNode*)*nchilds); + + return node; + } + + void copy_bb(float *bb, float *old_bb) + { + std::copy( old_bb, old_bb+6, bb ); + } + + void prepare_for_simd(SVBVHNode *node) + { + int i=0; + while(i+4 <= node->nchilds) + { + float vec_tmp[4*6]; + float *res = node->bb+6*i; + std::copy( node->bb+6*i, node->bb+6*(i+4), vec_tmp); + + for(int j=0; j<6; j++) + { + res[4*j+0] = vec_tmp[6*0+j]; + res[4*j+1] = vec_tmp[6*1+j]; + res[4*j+2] = vec_tmp[6*2+j]; + res[4*j+3] = vec_tmp[6*3+j]; + } +/* + const float *bb0 = vec_tmp+6*(i+0); + const float *bb1 = vec_tmp+6*(i+1); + const float *bb2 = vec_tmp+6*(i+2); + const float *bb3 = vec_tmp+6*(i+3); + + //memmoves could be memory alligned + const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(1,0,1,0) ); + const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(1,0,1,0) ); + _mm_store_ps( node->bb+6*i+4*0, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ) ); + _mm_store_ps( node->bb+6*i+4*1, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ) ); + + const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(3,2,3,2) ); + const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(3,2,3,2) ); + _mm_store_ps( node->bb+6*i+4*2, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ) ); + _mm_store_ps( node->bb+6*i+4*3, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ) ); + + const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(1,0,1,0) ); + const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(1,0,1,0) ); + _mm_store_ps( node->bb+6*i+4*4, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2,0,2,0) ) ); + _mm_store_ps( node->bb+6*i+4*5, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3,1,3,1) ) ); + */ + + i += 4; + } + } + + SVBVHNode *transform(OldNode *old) + { + if(is_leaf(old)) + return (SVBVHNode*)old; + if(is_leaf(old->child)) + return (SVBVHNode*)old->child; + + int nchilds = count_childs(old); + SVBVHNode *node = create_node(nchilds); + + childs_per_node += nchilds; + nodes++; + if(nchilds < 16) + nodes_with_childs[nchilds]++; + + int i=nchilds; + for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) + { + i--; + node->child[i] = transform(o_child); + if(is_leaf(o_child)) + { + float bb[6]; + INIT_MINMAX(bb, bb+3); + RE_rayobject_merge_bb( (RayObject*)o_child, bb, bb+3); + copy_bb(node->bb+i*6, bb); + break; + } + else + { + copy_bb(node->bb+i*6, o_child->bb); + } + } + assert( i == 0 ); + + if(SVBVH_SIMD) + prepare_for_simd(node); + + return node; + } +}; + +#endif -- cgit v1.2.3 From 495ef8a6a24f516826175f78cb6cb60facd82592 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 11 Aug 2009 17:28:58 +0000 Subject: fix instance support when using SIMD --- source/blender/render/intern/raytrace/svbvh.h | 69 +++++++++++++++++++++------ 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index f537aa79dac..cc875ad6dba 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -39,7 +39,7 @@ struct SVBVHNode int nchilds; //Array of bb, array of childs - float *bb; + float *child_bb; SVBVHNode **child; }; @@ -57,7 +57,7 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN int i=0; while(i+4 <= node->nchilds) { - int res = test_bb_group4( (__m128*) (node->bb+6*i), isec ); + int res = test_bb_group4( (__m128*) (node->child_bb+6*i), isec ); RE_RC_COUNT(isec->raycounter->bb.test); RE_RC_COUNT(isec->raycounter->bb.test); RE_RC_COUNT(isec->raycounter->bb.test); @@ -72,7 +72,7 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN } while(i < node->nchilds) { - if(RE_rayobject_bb_intersect_test(isec, (const float*)node->bb+6*i)) + if(RE_rayobject_bb_intersect_test(isec, (const float*)node->child_bb+6*i)) stack[stack_pos++] = node->child[i]; i++; } @@ -81,12 +81,51 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN { for(int i=0; inchilds; i++) { - if(RE_rayobject_bb_intersect_test(isec, (const float*)node->bb+6*i)) + if(RE_rayobject_bb_intersect_test(isec, (const float*)node->child_bb+6*i)) stack[stack_pos++] = node->child[i]; } } } +template<> +void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) +{ + if(is_leaf(node)) + { + RE_rayobject_merge_bb( (RayObject*)node, min, max); + } + else + { + int i=0; + while(SVBVH_SIMD && i+4 <= node->nchilds) + { + float *res = node->child_bb + 6*i; + for(int j=0; j<3; j++) + { + min[j] = MIN2(min[j], res[4*j+0]); + min[j] = MIN2(min[j], res[4*j+1]); + min[j] = MIN2(min[j], res[4*j+2]); + min[j] = MIN2(min[j], res[4*j+3]); + } + for(int j=0; j<3; j++) + { + max[j] = MAX2(max[j], res[4*(j+3)+0]); + max[j] = MAX2(max[j], res[4*(j+3)+1]); + max[j] = MAX2(max[j], res[4*(j+3)+2]); + max[j] = MAX2(max[j], res[4*(j+3)+3]); + } + + i += 4; + } + + for(; inchilds; i++) + { + DO_MIN(node->child_bb+6*i , min); + DO_MAX(node->child_bb+3+6*i, max); + } + } +} + struct SVBVHTree { RayObject rayobj; @@ -131,7 +170,7 @@ struct Reorganize_SVBVH { SVBVHNode *node = (SVBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(SVBVHNode)); node->nchilds = nchilds; - node->bb = (float*)BLI_memarena_alloc(tree->node_arena, sizeof(float)*6*nchilds); + node->child_bb = (float*)BLI_memarena_alloc(tree->node_arena, sizeof(float)*6*nchilds); node->child= (SVBVHNode**)BLI_memarena_alloc(tree->node_arena, sizeof(SVBVHNode*)*nchilds); return node; @@ -148,8 +187,8 @@ struct Reorganize_SVBVH while(i+4 <= node->nchilds) { float vec_tmp[4*6]; - float *res = node->bb+6*i; - std::copy( node->bb+6*i, node->bb+6*(i+4), vec_tmp); + float *res = node->child_bb+6*i; + std::copy( res, res+6*4, vec_tmp); for(int j=0; j<6; j++) { @@ -167,18 +206,18 @@ struct Reorganize_SVBVH //memmoves could be memory alligned const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(1,0,1,0) ); const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(1,0,1,0) ); - _mm_store_ps( node->bb+6*i+4*0, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ) ); - _mm_store_ps( node->bb+6*i+4*1, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ) ); + _mm_store_ps( node->child_bb+6*i+4*0, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ) ); + _mm_store_ps( node->child_bb+6*i+4*1, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ) ); const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(3,2,3,2) ); const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(3,2,3,2) ); - _mm_store_ps( node->bb+6*i+4*2, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ) ); - _mm_store_ps( node->bb+6*i+4*3, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ) ); + _mm_store_ps( node->child_bb+6*i+4*2, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ) ); + _mm_store_ps( node->child_bb+6*i+4*3, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ) ); const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(1,0,1,0) ); const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(1,0,1,0) ); - _mm_store_ps( node->bb+6*i+4*4, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2,0,2,0) ) ); - _mm_store_ps( node->bb+6*i+4*5, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3,1,3,1) ) ); + _mm_store_ps( node->child_bb+6*i+4*4, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2,0,2,0) ) ); + _mm_store_ps( node->child_bb+6*i+4*5, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3,1,3,1) ) ); */ i += 4; @@ -210,12 +249,12 @@ struct Reorganize_SVBVH float bb[6]; INIT_MINMAX(bb, bb+3); RE_rayobject_merge_bb( (RayObject*)o_child, bb, bb+3); - copy_bb(node->bb+i*6, bb); + copy_bb(node->child_bb+i*6, bb); break; } else { - copy_bb(node->bb+i*6, o_child->bb); + copy_bb(node->child_bb+i*6, o_child->bb); } } assert( i == 0 ); -- cgit v1.2.3 From eff93b099d5d347b692aa065b93f287baf1055c8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 11 Aug 2009 18:43:55 +0000 Subject: Fix ray_trace_shadow_tra --- source/blender/render/intern/source/rayshade.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 685b82d9da2..a71d45b871c 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1467,6 +1467,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int if it has col[3]>0.0f continue. so exit when alpha is full */ ShadeInput shi; ShadeResult shr; + float initial_labda = is->labda; if(RE_rayobject_raycast(R.raytree, is)) { float d= 1.0f; @@ -1499,7 +1500,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int /* adapt isect struct */ VECCOPY(is->start, shi.co); - + is->labda = initial_labda-is->labda; is->orig.ob = shi.obi; is->orig.face = shi.vlr; -- cgit v1.2.3 From c101d58d42da8b8be77fd9faa58932e781a5a2fd Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Wed, 12 Aug 2009 02:00:44 +0000 Subject: *Instance support is only enabled if target mesh uses more than 4 faces if theres very few faces its not worth it to create a separated tree for beinng reused. should speedup some particle renders. This "fixes" a bug relationed with a arithmetic precision on instances and raytrace of very close objects which usually happens on rendering (almost) overlapping alpha-enabled leafs/feathers --- source/blender/render/intern/include/rayobject.h | 6 +++-- source/blender/render/intern/source/rayobject.c | 1 + source/blender/render/intern/source/rayshade.c | 34 ++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 2c63c8ceae9..b058f260052 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -78,9 +78,11 @@ extern "C" { */ /* defines where coordinates of rayface primitives are stored */ -//#define RE_RAYFACE_COORDS_LOCAL +#define RE_RAYFACE_COORDS_LOCAL + +//(ATM this won't work good with all types of instances) //#define RE_RAYFACE_COORDS_POINTER -#define RE_RAYFACE_COORDS_VLAKREN +//#define RE_RAYFACE_COORDS_VLAKREN typedef struct RayFace { diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 5639080c406..bc98e7e0467 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -188,6 +188,7 @@ static int intersect_rayface(RayFace *face, Isect *is) #ifdef RE_RAYFACE_COORDS_VLAKREN { VlakRen *vlr = (VlakRen*)face->face; + VECCOPY(co1, vlr->v1->co); VECCOPY(co2, vlr->v2->co); if(vlr->v4) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index a71d45b871c..fe76fa07433 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -180,6 +180,7 @@ static int is_raytraceable(Render *re, ObjectInstanceRen *obi) return 0; } + RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) { //TODO @@ -283,6 +284,26 @@ static void makeraytree_hier(Render *re) re->stats_draw(re->sdh, &re->i); } +static int has_special_rayobject(Render *re, ObjectInstanceRen *obi) +{ + if( (obi->flag & R_TRANSFORMED) ) + { + ObjectRen *obr = obi->obr; + int v, faces = 0; + + for(v=0;vtotvlak;v++) + { + VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); + if(is_raytraceable_vlr(re, vlr)) + { + faces++; + if(faces > 4) + return 1; + } + } + } + return 0; +} /* * create a single raytrace structure with all faces */ @@ -300,7 +321,7 @@ static void makeraytree_single(Render *re) ObjectRen *obr = obi->obr; obs++; - if(obi->flag & R_TRANSFORMED) + if(has_special_rayobject(re, obi)) { faces++; } @@ -326,7 +347,7 @@ static void makeraytree_single(Render *re) for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) { - if(obi->flag & R_TRANSFORMED) + if(has_special_rayobject(re, obi)) { RayObject *obj = makeraytree_object(re, obi); RE_rayobject_add( re->raytree, obj ); @@ -342,6 +363,15 @@ static void makeraytree_single(Render *re) if(is_raytraceable_vlr(re, vlr)) { RE_rayface_from_vlak(face, obi, vlr); + if((obi->flag & R_TRANSFORMED)) + { + Mat4MulVecfl(obi->mat, face->v1); + Mat4MulVecfl(obi->mat, face->v2); + Mat4MulVecfl(obi->mat, face->v3); + if(RE_rayface_isQuad(face)) + Mat4MulVecfl(obi->mat, face->v4); + } + RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); face++; } -- cgit v1.2.3 From 6a056e4717c6f194aaac5dabe5c6bc6c8e32006e Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 12 Aug 2009 16:37:05 +0000 Subject: - converted 3ds exporter to 2.5 API - added Object.is_visible() RNA function to determine if an object is on the visible layer of active scene --- release/io/export_3ds.py | 151 ++++++++++++++++-------- source/blender/makesrna/intern/rna_object_api.c | 12 ++ 2 files changed, 117 insertions(+), 46 deletions(-) diff --git a/release/io/export_3ds.py b/release/io/export_3ds.py index c4a73a44b0c..56268b2925a 100644 --- a/release/io/export_3ds.py +++ b/release/io/export_3ds.py @@ -47,6 +47,8 @@ from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. ###################################################### import struct +import os +import time import bpy @@ -142,7 +144,8 @@ ROT_TRACK_TAG = int("0xB021",16); SCL_TRACK_TAG = int("0xB022",16); def uv_key(uv): - return round(uv.x, 6), round(uv.y, 6) + return round(uv[0], 6), round(uv[1], 6) +# return round(uv.x, 6), round(uv.y, 6) # size defines: SZ_SHORT = 2 @@ -275,7 +278,8 @@ class _3ds_rgb_color(object): return 3 def write(self,file): - file.write( struct.pack('<3c', chr(int(255*self.r)), chr(int(255*self.g)), chr(int(255*self.b)) ) ) + file.write( struct.pack('<3B', int(255*self.r), int(255*self.g), int(255*self.b) ) ) +# file.write( struct.pack('<3c', chr(int(255*self.r)), chr(int(255*self.g)), chr(int(255*self.b)) ) ) def __str__(self): return '{%f, %f, %f}' % (self.r, self.g, self.b) @@ -427,14 +431,19 @@ class _3ds_chunk(object): def get_material_images(material): # blender utility func. - images = [] if material: - for mtex in material.getTextures(): - if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: - image = mtex.tex.image - if image: - images.append(image) # maye want to include info like diffuse, spec here. - return images + return [s.texture.image for s in material.textures if s and s.texture.type == 'IMAGE' and s.texture.image] + + return [] +# images = [] +# if material: +# for mtex in material.getTextures(): +# if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: +# image = mtex.tex.image +# if image: +# images.append(image) # maye want to include info like diffuse, spec here. +# return images + def make_material_subchunk(id, color): '''Make a material subchunk. @@ -457,7 +466,8 @@ def make_material_texture_chunk(id, images): mat_sub = _3ds_chunk(id) def add_image(img): - filename = image.filename.split('\\')[-1].split('/')[-1] + filename = os.path.basename(image.filename) +# filename = image.filename.split('\\')[-1].split('/')[-1] mat_sub_file = _3ds_chunk(MATMAPFILE) mat_sub_file.add_variable("mapfile", _3ds_string(sane_name(filename))) mat_sub.add_subchunk(mat_sub_file) @@ -485,9 +495,12 @@ def make_material_chunk(material, image): material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, (1,1,1) )) else: - material_chunk.add_subchunk(make_material_subchunk(MATAMBIENT, [a*material.amb for a in material.rgbCol] )) - material_chunk.add_subchunk(make_material_subchunk(MATDIFFUSE, material.rgbCol)) - material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, material.specCol)) + material_chunk.add_subchunk(make_material_subchunk(MATAMBIENT, [a*material.ambient for a in material.diffuse_color] )) +# material_chunk.add_subchunk(make_material_subchunk(MATAMBIENT, [a*material.amb for a in material.rgbCol] )) + material_chunk.add_subchunk(make_material_subchunk(MATDIFFUSE, material.diffuse_color)) +# material_chunk.add_subchunk(make_material_subchunk(MATDIFFUSE, material.rgbCol)) + material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, material.specular_color)) +# material_chunk.add_subchunk(make_material_subchunk(MATSPECULAR, material.specCol)) images = get_material_images(material) # can be None if image: images.append(image) @@ -516,28 +529,38 @@ def extract_triangles(mesh): If the mesh contains quads, they will be split into triangles.''' tri_list = [] - do_uv = mesh.faceUV + do_uv = len(mesh.uv_textures) +# do_uv = mesh.faceUV - if not do_uv: - face_uv = None +# if not do_uv: +# face_uv = None img = None - for face in mesh.faces: - f_v = face.v + for i, face in enumerate(mesh.faces): + f_v = face.verts +# f_v = face.v + + uf = mesh.active_uv_texture.data[i] if do_uv else None if do_uv: - f_uv = face.uv - img = face.image + f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3) +# f_uv = face.uv + img = uf.image if uf else None +# img = face.image if img: img = img.name - - if len(f_v)==3: - new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img) + + if f_v[3] == 0: + # if len(f_v)==3: + new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img) +# new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img) if (do_uv): new_tri.faceuvs= uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2]) tri_list.append(new_tri) else: #it's a quad - new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img) - new_tri_2 = tri_wrapper((f_v[0].index, f_v[2].index, f_v[3].index), face.mat, img) + new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img) +# new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img) + new_tri_2 = tri_wrapper((f_v[0], f_v[2], f_v[3]), face.material_index, img) +# new_tri_2 = tri_wrapper((f_v[0].index, f_v[2].index, f_v[3].index), face.mat, img) if (do_uv): new_tri.faceuvs= uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2]) @@ -629,7 +652,8 @@ def make_faces_chunk(tri_list, mesh, materialDict): face_list = _3ds_array() - if mesh.faceUV: + if len(mesh.uv_textures): +# if mesh.faceUV: # Gather materials used in this mesh - mat/image pairs unique_mats = {} for i,tri in enumerate(tri_list): @@ -706,7 +730,8 @@ def make_mesh_chunk(mesh, materialDict): # Extract the triangles from the mesh: tri_list = extract_triangles(mesh) - if mesh.faceUV: + if len(mesh.uv_textures): +# if mesh.faceUV: # Remove the face UVs and convert it to vertex UV: vert_array, uv_array, tri_list = remove_face_uv(mesh.verts, tri_list) else: @@ -715,10 +740,13 @@ def make_mesh_chunk(mesh, materialDict): for vert in mesh.verts: vert_array.add(_3ds_point_3d(vert.co)) # If the mesh has vertex UVs, create an array of UVs: - if mesh.vertexUV: + if len(mesh.sticky): +# if mesh.vertexUV: uv_array = _3ds_array() - for vert in mesh.verts: - uv_array.add(_3ds_point_uv(vert.uvco)) + for uv in mesh.sticky: +# for vert in mesh.verts: + uv_array.add(_3ds_point_uv(uv.co)) +# uv_array.add(_3ds_point_uv(vert.uvco)) else: # no UV at all: uv_array = None @@ -878,7 +906,7 @@ def save_3ds(filename, context): # return # XXX - time1 = bpy.sys.time() + time1 = time.clock() # time1= Blender.sys.time() # Blender.Window.WaitCursor(1) @@ -909,31 +937,56 @@ def save_3ds(filename, context): # each material is added once): materialDict = {} mesh_objects = [] - for ob in context.selected_objects: + for ob in [ob for ob in context.scene.objects if ob.is_visible()]: # for ob in sce.objects.context: - for ob_derived, mat in getDerivedObjects(ob, False): - data = getMeshFromObject(ob_derived, None, True, False, sce) + + # get derived objects + derived = [] + + # ignore dupli children + if ob.parent and ob.parent.dupli_type != 'NONE': + continue + + if ob.dupli_type != 'NONE': + ob.create_dupli_list() + derived = [(dob.object, dob.matrix) for dob in ob.dupli_list] + else: + derived = [(ob, ob.matrix)] + + for ob_derived, mat in derived: +# for ob_derived, mat in getDerivedObjects(ob, False): + + if ob.type not in ('MESH', 'CURVE', 'SURFACE', 'TEXT', 'META'): + continue + + data = ob_derived.create_mesh(True, 'PREVIEW') +# data = getMeshFromObject(ob_derived, None, True, False, sce) if data: - data.transform(mat, recalc_normals=False) + data.transform(mat) +# data.transform(mat, recalc_normals=False) mesh_objects.append((ob_derived, data)) mat_ls = data.materials mat_ls_len = len(mat_ls) + # get material/image tuples. - if data.faceUV: + if len(data.uv_textures): +# if data.faceUV: if not mat_ls: mat = mat_name = None - for f in data.faces: + for f, uf in zip(data.faces, data.active_uv_texture.data): if mat_ls: - mat_index = f.mat + mat_index = f.material_index +# mat_index = f.mat if mat_index >= mat_ls_len: mat_index = f.mat = 0 mat = mat_ls[mat_index] if mat: mat_name = mat.name else: mat_name = None # else there alredy set to none - - img = f.image + + img = uf.image +# img = f.image if img: img_name = img.name else: img_name = None @@ -947,8 +1000,10 @@ def save_3ds(filename, context): # Why 0 Why! for f in data.faces: - if f.mat >= mat_ls_len: - f.mat = 0 + if f.material_index >= mat_ls_len: +# if f.mat >= mat_ls_len: + f.material_index = 0 +# f.mat = 0 # Make material chunks for all materials used in the meshes: for mat_and_image in materialDict.values(): @@ -980,7 +1035,10 @@ def save_3ds(filename, context): # make a kf object node for the object: kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) ''' - blender_mesh.verts = None +# if not blender_mesh.users: + bpy.data.remove_mesh(blender_mesh) +# blender_mesh.verts = None + i+=i # Create chunks for all empties: @@ -1013,8 +1071,9 @@ def save_3ds(filename, context): file.close() # Debugging only: report the exporting time: - Blender.Window.WaitCursor(0) - print("3ds export time: %.2f" % (Blender.sys.time() - time1)) +# Blender.Window.WaitCursor(0) + print("3ds export time: %.2f" % (time.clock() - time1)) +# print("3ds export time: %.2f" % (Blender.sys.time() - time1)) # Debugging only: dump the chunk hierarchy: #primary.dump() @@ -1042,7 +1101,7 @@ class EXPORT_OT_3ds(bpy.types.Operator): ] def execute(self, context): - raise Exception("Not doing anything yet.") + save_3ds(self.filename, context) return ('FINISHED',) def invoke(self, context, event): diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 8192801d9fb..f0a42987848 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -333,6 +333,11 @@ static Object *rna_Object_find_armature(Object *ob) return ob_arm; } +int rna_Object_is_visible(Object *ob, bContext *C) +{ + return ob->lay & CTX_data_scene(C)->lay; +} + /* static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int *indices, int totindex, float weight, int assignmode) { @@ -443,6 +448,13 @@ void RNA_api_object(StructRNA *srna) func= RNA_def_function(srna, "make_display_list", "rna_Object_make_display_list"); RNA_def_function_ui_description(func, "Update object's display data."); /* XXX describe better */ RNA_def_function_flag(func, FUNC_USE_CONTEXT); + + /* View */ + func= RNA_def_function(srna, "is_visible", "rna_Object_is_visible"); + RNA_def_function_ui_description(func, "Determine if object is visible in active scene."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm= RNA_def_boolean(func, "is_visible", 0, "", "Object visibility."); + RNA_def_function_return(func, parm); } #endif -- cgit v1.2.3 From 44ddff5c516058a73f0297a94845b2e835307d2f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Thu, 13 Aug 2009 11:14:06 +0000 Subject: - 3ds importer working (without the "scale to size" option) - changing object.matrix now updates object.loc/rot/scale - added bpy.data.add_lamp() --- release/io/import_3ds.py | 886 ++++++++++++---------- release/io/import_obj.py | 15 +- source/blender/makesrna/intern/rna_main_api.c | 27 + source/blender/makesrna/intern/rna_material_api.c | 2 +- source/blender/makesrna/intern/rna_mesh_api.c | 6 +- source/blender/makesrna/intern/rna_object.c | 7 + 6 files changed, 553 insertions(+), 390 deletions(-) diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py index a08fdb8fc85..0269219b63d 100644 --- a/release/io/import_3ds.py +++ b/release/io/import_3ds.py @@ -125,9 +125,14 @@ Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). # Importing modules -from struct import calcsize, unpack +import os +import time +import struct + +from import_obj import unpack_face_list, load_image import bpy +import Mathutils # import Blender # from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils @@ -149,7 +154,7 @@ import bpy # except: # from sets import Set as set -BOUNDS_3DS= [] +BOUNDS_3DS = [] #this script imports uvcoords as sticky vertex coords @@ -157,9 +162,9 @@ BOUNDS_3DS= [] #which shold be more useful. def createBlenderTexture(material, name, image): - texture= bpy.data.textures.new(name) + texture = bpy.data.textures.new(name) texture.setType('Image') - texture.image= image + texture.image = image material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) @@ -170,7 +175,7 @@ def createBlenderTexture(material, name, image): #Some of the chunks that we will see #----- Primary Chunk, at the beginning of each file -PRIMARY= int('0x4D4D',16) +PRIMARY = int('0x4D4D',16) #------ Main Chunks OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information @@ -178,8 +183,8 @@ VERSION = int('0x0002',16); #This gives the version of the .3ds f EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info #------ sub defines of OBJECTINFO -MATERIAL=45055 #0xAFFF // This stored the texture info -OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... +MATERIAL = 45055 #0xAFFF // This stored the texture info +OBJECT = 16384 #0x4000 // This stores the faces, vertices, etc... #>------ sub defines of MATERIAL #------ sub defines of MATERIAL_BLOCK @@ -213,16 +218,16 @@ OBJECT_LAMP_SHADOWED = int('0x4630',16); OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16); OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16); OBJECT_LAMP_SEE_CONE = int('0x4650',16); -OBJECT_LAMP_SPOT_RECTANGULAR= int('0x4651',16); -OBJECT_LAMP_SPOT_OVERSHOOT= int('0x4652',16); -OBJECT_LAMP_SPOT_PROJECTOR= int('0x4653',16); -OBJECT_LAMP_EXCLUDE= int('0x4654',16); -OBJECT_LAMP_RANGE= int('0x4655',16); -OBJECT_LAMP_ROLL= int('0x4656',16); -OBJECT_LAMP_SPOT_ASPECT= int('0x4657',16); -OBJECT_LAMP_RAY_BIAS= int('0x4658',16); -OBJECT_LAMP_INNER_RANGE= int('0x4659',16); -OBJECT_LAMP_OUTER_RANGE= int('0x465A',16); +OBJECT_LAMP_SPOT_RECTANGULAR = int('0x4651',16); +OBJECT_LAMP_SPOT_OVERSHOOT = int('0x4652',16); +OBJECT_LAMP_SPOT_PROJECTOR = int('0x4653',16); +OBJECT_LAMP_EXCLUDE = int('0x4654',16); +OBJECT_LAMP_RANGE = int('0x4655',16); +OBJECT_LAMP_ROLL = int('0x4656',16); +OBJECT_LAMP_SPOT_ASPECT = int('0x4657',16); +OBJECT_LAMP_RAY_BIAS = int('0x4658',16); +OBJECT_LAMP_INNER_RANGE = int('0x4659',16); +OBJECT_LAMP_OUTER_RANGE = int('0x465A',16); OBJECT_LAMP_MULTIPLIER = int('0x465B',16); OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16); @@ -241,21 +246,21 @@ OBJECT_UV = int('0x4140',16); # The UV texture coordinates OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix global scn -scn= None +scn = None #the chunk class class chunk: - ID=0 - length=0 - bytes_read=0 + ID = 0 + length = 0 + bytes_read = 0 #we don't read in the bytes_read, we compute that binary_format='3): + if (version > 3): print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) #is it an object info chunk? - elif (new_chunk.ID==OBJECTINFO): - #print 'elif (new_chunk.ID==OBJECTINFO):' + elif (new_chunk.ID == OBJECTINFO): + #print 'elif (new_chunk.ID == OBJECTINFO):' # print 'found an OBJECTINFO chunk' process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) #keep track of how much we read in the main chunk - new_chunk.bytes_read+=temp_chunk.bytes_read + new_chunk.bytes_read += temp_chunk.bytes_read #is it an object chunk? - elif (new_chunk.ID==OBJECT): + elif (new_chunk.ID == OBJECT): if CreateBlenderObject: putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) - contextMesh_vertls= []; contextMesh_facels= [] + contextMesh_vertls = []; contextMesh_facels = [] ## preparando para receber o proximo objeto - contextMeshMaterials= {} # matname:[face_idxs] - contextMeshUV= None - #contextMesh.vertexUV= 1 # Make sticky coords. + contextMeshMaterials = {} # matname:[face_idxs] + contextMeshUV = None + #contextMesh.vertexUV = 1 # Make sticky coords. # Reset matrix - contextMatrix_rot= None - #contextMatrix_tx= None + contextMatrix_rot = None + #contextMatrix_tx = None - CreateBlenderObject= True - tempName= read_string(file) - contextObName= tempName + CreateBlenderObject = True + tempName = read_string(file) + contextObName = tempName new_chunk.bytes_read += len(tempName)+1 #is it a material chunk? - elif (new_chunk.ID==MATERIAL): - #print 'elif (new_chunk.ID==MATERIAL):' - contextMaterial= bpy.data.materials.new('Material') + elif (new_chunk.ID == MATERIAL): + +# print("read material") + + #print 'elif (new_chunk.ID == MATERIAL):' + contextMaterial = bpy.data.add_material('Material') +# contextMaterial = bpy.data.materials.new('Material') - elif (new_chunk.ID==MAT_NAME): - #print 'elif (new_chunk.ID==MAT_NAME):' - material_name= read_string(file) + elif (new_chunk.ID == MAT_NAME): + #print 'elif (new_chunk.ID == MAT_NAME):' + material_name = read_string(file) + +# print("material name", material_name) #plus one for the null character that ended the string - new_chunk.bytes_read+= len(material_name)+1 + new_chunk.bytes_read += len(material_name)+1 - contextMaterial.name= material_name.rstrip() # remove trailing whitespace + contextMaterial.name = material_name.rstrip() # remove trailing whitespace MATDICT[material_name]= (contextMaterial.name, contextMaterial) - elif (new_chunk.ID==MAT_AMBIENT): - #print 'elif (new_chunk.ID==MAT_AMBIENT):' + elif (new_chunk.ID == MAT_AMBIENT): + #print 'elif (new_chunk.ID == MAT_AMBIENT):' read_chunk(file, temp_chunk) - if (temp_chunk.ID==MAT_FLOAT_COLOR): - temp_data=file.read(calcsize('3f')) - temp_chunk.bytes_read+=12 - contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)] - elif (temp_chunk.ID==MAT_24BIT_COLOR): - temp_data=file.read(calcsize('3B')) - temp_chunk.bytes_read+= 3 - contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb + if (temp_chunk.ID == MAT_FLOAT_COLOR): + contextMaterial.mirror_color = read_float_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3f')) +# temp_chunk.bytes_read += 12 +# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] + elif (temp_chunk.ID == MAT_24BIT_COLOR): + contextMaterial.mirror_color = read_byte_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3B')) +# temp_chunk.bytes_read += 3 +# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb else: skip_to_end(file, temp_chunk) - new_chunk.bytes_read+= temp_chunk.bytes_read + new_chunk.bytes_read += temp_chunk.bytes_read - elif (new_chunk.ID==MAT_DIFFUSE): - #print 'elif (new_chunk.ID==MAT_DIFFUSE):' + elif (new_chunk.ID == MAT_DIFFUSE): + #print 'elif (new_chunk.ID == MAT_DIFFUSE):' read_chunk(file, temp_chunk) - if (temp_chunk.ID==MAT_FLOAT_COLOR): - temp_data=file.read(calcsize('3f')) - temp_chunk.bytes_read+=12 - contextMaterial.rgbCol=[float(col) for col in unpack('<3f', temp_data)] - elif (temp_chunk.ID==MAT_24BIT_COLOR): - temp_data=file.read(calcsize('3B')) - temp_chunk.bytes_read+= 3 - contextMaterial.rgbCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb + if (temp_chunk.ID == MAT_FLOAT_COLOR): + contextMaterial.diffuse_color = read_float_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3f')) +# temp_chunk.bytes_read += 12 +# contextMaterial.rgbCol = [float(col) for col in struct.unpack('<3f', temp_data)] + elif (temp_chunk.ID == MAT_24BIT_COLOR): + contextMaterial.diffuse_color = read_byte_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3B')) +# temp_chunk.bytes_read += 3 +# contextMaterial.rgbCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb else: skip_to_end(file, temp_chunk) - new_chunk.bytes_read+= temp_chunk.bytes_read - elif (new_chunk.ID==MAT_SPECULAR): - #print 'elif (new_chunk.ID==MAT_SPECULAR):' +# print("read material diffuse color", contextMaterial.diffuse_color) + + new_chunk.bytes_read += temp_chunk.bytes_read + + elif (new_chunk.ID == MAT_SPECULAR): + #print 'elif (new_chunk.ID == MAT_SPECULAR):' read_chunk(file, temp_chunk) - if (temp_chunk.ID==MAT_FLOAT_COLOR): - temp_data=file.read(calcsize('3f')) - temp_chunk.bytes_read+=12 - contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)] - elif (temp_chunk.ID==MAT_24BIT_COLOR): - temp_data=file.read(calcsize('3B')) - temp_chunk.bytes_read+= 3 - contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb + if (temp_chunk.ID == MAT_FLOAT_COLOR): + contextMaterial.specular_color = read_float_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3f')) +# temp_chunk.bytes_read += 12 +# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] + elif (temp_chunk.ID == MAT_24BIT_COLOR): + contextMaterial.specular_color = read_byte_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3B')) +# temp_chunk.bytes_read += 3 +# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb else: skip_to_end(file, temp_chunk) - new_chunk.bytes_read+= temp_chunk.bytes_read + new_chunk.bytes_read += temp_chunk.bytes_read - elif (new_chunk.ID==MAT_TEXTURE_MAP): - #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):' - new_texture= bpy.data.textures.new('Diffuse') - new_texture.setType('Image') - img = None - while (new_chunk.bytes_read BOUNDS_3DS[i+3]: - BOUNDS_3DS[i+3]= v[i] # min + if v[i] > BOUNDS_3DS[i + 3]: + BOUNDS_3DS[i + 3]= v[i] # min # Get the max axis x/y/z - max_axis= max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2]) + max_axis = max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2]) # print max_axis - if max_axis < 1<<30: # Should never be false but just make sure. + if max_axis < 1 << 30: # Should never be false but just make sure. # Get a new scale factor if set as an option - SCALE=1.0 - while (max_axis*SCALE) > IMPORT_CONSTRAIN_BOUNDS: + SCALE = 1.0 + while (max_axis * SCALE) > IMPORT_CONSTRAIN_BOUNDS: SCALE/=10 # SCALE Matrix - SCALE_MAT= Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) + SCALE_MAT = Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) +# SCALE_MAT = Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) for ob in importedObjects: - ob.setMatrix(ob.matrixWorld*SCALE_MAT) + ob.setMatrix(ob.matrixWorld * SCALE_MAT) # Done constraining to bounds. # Select all new objects. - print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1))) + print('finished importing: "%s" in %.4f sec.' % (filename, (time.clock()-time1))) +# print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1))) file.close() - Blender.Window.WaitCursor(0) +# Blender.Window.WaitCursor(0) -DEBUG= False +DEBUG = False # if __name__=='__main__' and not DEBUG: -# if calcsize==None: +# if calcsize == None: # Blender.Draw.PupMenu('Error%t|a full python installation not found') # else: # Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') @@ -976,14 +1095,14 @@ DEBUG= False else: import os # DEBUG ONLY - TIME= Blender.sys.time() + TIME = Blender.sys.time() import os print 'Searching for files' os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') print '...Done' - file= open('/tmp/temp3ds_list', 'r') - lines= file.readlines() + file = open('/tmp/temp3ds_list', 'r') + lines = file.readlines() file.close() # sort by filesize for faster testing lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] @@ -1001,7 +1120,7 @@ else: #_3ds= _3ds[:-1] print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines) _3ds_file= _3ds.split('/')[-1].split('\\')[-1] - newScn= Blender.Scene.New(_3ds_file) + newScn = Blender.Scene.New(_3ds_file) newScn.makeCurrent() load_3ds(_3ds, False) @@ -1020,11 +1139,14 @@ class IMPORT_OT_3ds(bpy.types.Operator): # to the class instance from the operator settings before calling. __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen=1024, default= ""), +# bpy.props.FloatProperty(attr="size_constraint", name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0), +# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True), +# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False), ] def execute(self, context): - raise Exception("Not doing anything yet.") + load_3ds(self.filename, context, 0.0, False, False) return ('FINISHED',) def invoke(self, context, event): @@ -1037,3 +1159,7 @@ class IMPORT_OT_3ds(bpy.types.Operator): return context.active_object != None bpy.ops.add(IMPORT_OT_3ds) + +# NOTES: +# why add 1 extra vertex? and remove it when done? +# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time) diff --git a/release/io/import_obj.py b/release/io/import_obj.py index f064561a512..484be6d54b4 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -294,18 +294,21 @@ def line_value(line_split): return ' '.join( line_split[1:] ) # limited replacement for BPyImage.comprehensiveImageLoad -def load_image(imagepath, direc): +def load_image(imagepath, dirname): if os.path.exists(imagepath): return bpy.data.add_image(imagepath) - im_base = os.path.basename(imagepath) + variants = [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))] - tmp = os.path.join(direc, im_base) - if os.path.exists(tmp): - return bpy.data.add_image(tmp) + for path in variants: + if os.path.exists(path): + return bpy.data.add_image(path) + else: + print(path, "doesn't exist") # TODO comprehensiveImageLoad also searched in bpy.config.textureDir + return None def obj_image_load(imagepath, DIR, IMAGE_SEARCH): @@ -387,7 +390,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ # blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API elif type == 'Ks': - blender_material.add_texture(texture, "UV", "SPECULAR") + blender_material.add_texture(texture, "UV", "SPECULARITY") # blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) elif type == 'Bump': diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 17f3800e10e..9d42c473f50 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -44,6 +44,9 @@ #include "BKE_object.h" #include "BKE_material.h" #include "BKE_image.h" +#include "BKE_texture.h" + +#include "DNA_lamp_types.h" static Mesh *rna_Main_add_mesh(Main *main, char *name) { @@ -62,6 +65,23 @@ static void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) /* XXX python now has invalid pointer? */ } +static Lamp *rna_Main_add_lamp(Main *main, char *name) +{ + Lamp *la= add_lamp(name); + la->id.us--; + return la; +} + +/* +static void rna_Main_remove_lamp(Main *main, ReportList *reports, Lamp *la) +{ + if(la->id.us == 0) + free_libblock(&main->lamp, la); + else + BKE_report(reports, RPT_ERROR, "Lamp must have zero users to be removed."); +} +*/ + static Object* rna_Main_add_object(Main *main, int type, char *name) { Object *ob= add_only_object(type, name); @@ -158,6 +178,13 @@ void RNA_api_main(StructRNA *srna) parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove."); RNA_def_property_flag(parm, PROP_REQUIRED); + func= RNA_def_function(srna, "add_lamp", "rna_Main_add_lamp"); + RNA_def_function_ui_description(func, "Add a new lamp."); + parm= RNA_def_string(func, "name", "Lamp", 0, "", "New name for the datablock."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "mesh", "Lamp", "", "New lamp."); + RNA_def_function_return(func, parm); + func= RNA_def_function(srna, "add_material", "rna_Main_add_material"); RNA_def_function_ui_description(func, "Add a new material."); parm= RNA_def_string(func, "name", "Material", 0, "", "New name for the datablock."); /* optional */ diff --git a/source/blender/makesrna/intern/rna_material_api.c b/source/blender/makesrna/intern/rna_material_api.c index e2b47460fdb..aa28b6b923c 100644 --- a/source/blender/makesrna/intern/rna_material_api.c +++ b/source/blender/makesrna/intern/rna_material_api.c @@ -101,7 +101,7 @@ void RNA_api_material(StructRNA *srna) static EnumPropertyItem prop_texture_mapto_items[] = { {MAP_COL, "COLOR", 0, "Color", "Causes the texture to affect basic color of the material"}, {MAP_NORM, "NORMAL", 0, "Normal", "Causes the texture to affect the rendered normal"}, - {MAP_COLSPEC, "SPEC_COLOR", 0, "Specularity Color", "Causes the texture to affect the specularity color"}, + {MAP_COLSPEC, "SPECULAR_COLOR", 0, "Specularity Color", "Causes the texture to affect the specularity color"}, {MAP_COLMIR, "MIRROR", 0, "Mirror", "Causes the texture to affect the mirror color"}, {MAP_REF, "REFLECTION", 0, "Reflection", "Causes the texture to affect the value of the materials reflectivity"}, {MAP_SPEC, "SPECULARITY", 0, "Specularity", "Causes the texture to affect the value of specularity"}, diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index b50cc678f4f..9d4dad1fb5b 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -248,7 +248,7 @@ static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces) rna_Mesh_add_faces(mesh, faces); } -static void rna_Mesh_add_uv_layer(Mesh *me) +static void rna_Mesh_add_uv_texture(Mesh *me) { me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface); } @@ -306,8 +306,8 @@ void RNA_api_mesh(StructRNA *srna) parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh, remove it if it is only used for export."); RNA_def_function_return(func, parm); - func= RNA_def_function(srna, "add_uv_layer", "rna_Mesh_add_uv_layer"); - RNA_def_function_ui_description(func, "Add new UV layer to Mesh."); + func= RNA_def_function(srna, "add_uv_texture", "rna_Mesh_add_uv_texture"); + RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh."); func= RNA_def_function(srna, "calc_normals", "rna_Mesh_calc_normals"); RNA_def_function_ui_description(func, "Calculate vertex normals."); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 6fe254dcb68..32307709387 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -74,6 +74,12 @@ void rna_Object_update(bContext *C, PointerRNA *ptr) DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_OB); } +void rna_Object_matrix_update(bContext *C, PointerRNA *ptr) +{ + ED_object_apply_obmat(ptr->id.data); + rna_Object_update(C, ptr); +} + void rna_Object_update_data(bContext *C, PointerRNA *ptr) { DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA); @@ -1101,6 +1107,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "obmat"); RNA_def_property_array(prop, 16); RNA_def_property_ui_text(prop, "Matrix", "Transformation matrix."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_matrix_update"); /* collections */ prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE); -- cgit v1.2.3 From 7050a4a6a2f20d6ba3f53cc7673bc822d75d8902 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 13 Aug 2009 12:23:21 +0000 Subject: *Bug fix on finding hit on neighbour face (think this is the last know bug) This bug fix makes the "non-smoothed" faces appear again (just like they do in 2.49 and blender2.5) Meaning the "detect neighbour faces" isn't working 100%. --- source/blender/render/intern/source/rayobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index bc98e7e0467..daa6b8d95de 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -306,7 +306,7 @@ static int intersect_rayface(RayFace *face, Isect *is) || a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2 || a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3 || (b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4))) - if(intersection2((VlakRen*)b, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) + if(!intersection2((VlakRen*)a, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) { return 0; } -- cgit v1.2.3 From cb40f0ff804a21a06d4e28ea72b30d7b76ff1d39 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 13 Aug 2009 15:56:24 +0000 Subject: Another tree pass during build to increase the number of nodes that have multipe of 4childs --- .../render/intern/raytrace/rayobject_vbvh.cpp | 1 + source/blender/render/intern/raytrace/reorganize.h | 34 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 7f990e06152..b703e57fdd8 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -270,6 +270,7 @@ void bvh_done(VBVHTree *obj) pushup(root); pushdown(root); + pushup_simd(root); //Memory re-organize if(0) diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h index 2f79b0f6e82..b77a51bbf65 100644 --- a/source/blender/render/intern/raytrace/reorganize.h +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -144,6 +144,8 @@ void remove_useless(Node *node, Node **new_node) template void pushup(Node *parent) { + if(is_leaf(parent)) return; + float p_area = bb_area(parent->bb, parent->bb+3); Node **prev = &parent->child; for(Node *child = parent->child; RayObject_isAligned(child) && child; ) @@ -175,6 +177,38 @@ void pushup(Node *parent) pushup(child); } +/* + * try to optimize number of childs to be a multiple of SSize + */ +template +void pushup_simd(Node *parent) +{ + if(is_leaf(parent)) return; + + int n = count_childs(parent); + + Node **prev = &parent->child; + for(Node *child = parent->child; RayObject_isAligned(child) && child; ) + { + int cn = count_childs(child); + if(cn-1 <= (SSize - (n%SSize) ) % SSize && RayObject_isAligned(child->child) ) + { + n += (cn - 1); + append_sibling(child, child->child); + child = child->sibling; + *prev = child; + } + else + { + *prev = child; + prev = &(*prev)->sibling; + child = *prev; + } + } + + for(Node *child = parent->child; RayObject_isAligned(child) && child; child = child->sibling) + pushup_simd(child); +} /* -- cgit v1.2.3 From cc0dafa627141eb7dcbf014ada58336fa71b50d5 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 13 Aug 2009 20:35:53 +0000 Subject: Addition of some fake nodes to use SIMD even when theres only 3 nodes --- source/blender/render/intern/raytrace/svbvh.h | 29 ++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index cc875ad6dba..95f1c40765e 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -147,6 +147,7 @@ struct Reorganize_SVBVH float childs_per_node; int nodes_with_childs[16]; + int useless_bb; int nodes; Reorganize_SVBVH(Tree *t) @@ -154,6 +155,7 @@ struct Reorganize_SVBVH tree = t; nodes = 0; childs_per_node = 0; + useless_bb = 0; for(int i=0; i<16; i++) nodes_with_childs[i] = 0; @@ -161,7 +163,8 @@ struct Reorganize_SVBVH ~Reorganize_SVBVH() { - printf("%f childs per node\n", childs_per_node / nodes); + printf("%f childs per node\n", childs_per_node / nodes); + printf("%d childs BB are useless\n", useless_bb); for(int i=0; i<16; i++) printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i]/float(nodes)); } @@ -176,7 +179,7 @@ struct Reorganize_SVBVH return node; } - void copy_bb(float *bb, float *old_bb) + void copy_bb(float *bb, const float *old_bb) { std::copy( old_bb, old_bb+6, bb ); } @@ -224,6 +227,12 @@ struct Reorganize_SVBVH } } + /* amt must be power of two */ + inline int padup(int num, int amt) + { + return ((num+(amt-1))&~(amt-1)); + } + SVBVHNode *transform(OldNode *old) { if(is_leaf(old)) @@ -232,13 +241,26 @@ struct Reorganize_SVBVH return (SVBVHNode*)old->child; int nchilds = count_childs(old); - SVBVHNode *node = create_node(nchilds); + int alloc_childs = nchilds; + if(nchilds % 4 > 2) + alloc_childs = padup(nchilds, 4); + + SVBVHNode *node = create_node(alloc_childs); childs_per_node += nchilds; nodes++; if(nchilds < 16) nodes_with_childs[nchilds]++; + useless_bb += alloc_childs-nchilds; + while(alloc_childs > nchilds) + { + const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN }; + alloc_childs--; + node->child[alloc_childs] = 0; + copy_bb(node->child_bb+alloc_childs*6, def_bb); + } + int i=nchilds; for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) { @@ -258,6 +280,7 @@ struct Reorganize_SVBVH } } assert( i == 0 ); + if(SVBVH_SIMD) prepare_for_simd(node); -- cgit v1.2.3 From 09042ce9a507b7f9ea36a63e60bbda6266541579 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 17 Aug 2009 14:29:29 +0000 Subject: Ported X3D exporter. --- release/io/export_3ds.py | 36 ++-- release/io/export_x3d.py | 448 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 326 insertions(+), 158 deletions(-) diff --git a/release/io/export_3ds.py b/release/io/export_3ds.py index 56268b2925a..19c12146769 100644 --- a/release/io/export_3ds.py +++ b/release/io/export_3ds.py @@ -60,6 +60,22 @@ import bpy # except: # struct = None +# also used by X3D exporter +# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects() +def create_derived_objects(ob): + if ob.parent and ob.parent.dupli_type != 'NONE': + return False, None + + if ob.dupli_type != 'NONE': + ob.create_dupli_list() + return True, [(dob.object, dob.matrix) for dob in ob.dupli_list] + else: + return False, [(ob, ob.matrix)] + +# also used by X3D exporter +def free_derived_objects(ob): + ob.free_dupli_list() + # So 3ds max can open files, limit names to 12 in length # this is verry annoying for filenames! name_unique = [] @@ -941,17 +957,9 @@ def save_3ds(filename, context): # for ob in sce.objects.context: # get derived objects - derived = [] + free, derived = create_derived_objects(ob) - # ignore dupli children - if ob.parent and ob.parent.dupli_type != 'NONE': - continue - - if ob.dupli_type != 'NONE': - ob.create_dupli_list() - derived = [(dob.object, dob.matrix) for dob in ob.dupli_list] - else: - derived = [(ob, ob.matrix)] + if derived == None: continue for ob_derived, mat in derived: # for ob_derived, mat in getDerivedObjects(ob, False): @@ -1003,8 +1011,12 @@ def save_3ds(filename, context): if f.material_index >= mat_ls_len: # if f.mat >= mat_ls_len: f.material_index = 0 -# f.mat = 0 - + # f.mat = 0 + + if free: + free_derived_objects(ob) + + # Make material chunks for all materials used in the meshes: for mat_and_image in materialDict.values(): object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1])) diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py index b57be2286e9..30a4b1483b0 100644 --- a/release/io/export_x3d.py +++ b/release/io/export_x3d.py @@ -54,10 +54,13 @@ Known issues:
#################################### import math +import os import bpy import Mathutils +from export_3ds import create_derived_objects, free_derived_objects + # import Blender # from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh # from Blender.Scene import Render @@ -166,8 +169,10 @@ class x3d_class: self.file.write("\n") self.file.write("\n") self.file.write("\n") - self.file.write("\t\n" % sys.basename(bfile)) - self.file.write("\t\n" % Blender.Get('version')) + self.file.write("\t\n" % os.path.basename(bfile)) + # self.file.write("\t\n" % sys.basename(bfile)) + self.file.write("\t\n" % '2.5') + # self.file.write("\t\n" % Blender.Get('version')) self.file.write("\t\n") self.file.write("\n") self.file.write("\n") @@ -211,9 +216,12 @@ class x3d_class: ''' def writeViewpoint(self, ob, mat, scene): - context = scene.render - ratio = float(context.imageSizeY())/float(context.imageSizeX()) - lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180) + context = scene.render_data + # context = scene.render + ratio = float(context.resolution_x)/float(context.resolution_y) + # ratio = float(context.imageSizeY())/float(context.imageSizeX()) + lens = (360* (math.atan(ratio *16 / ob.data.lens) / math.pi))*(math.pi/180) + # lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180) lens = min(lens, math.pi) # get the camera location, subtract 90 degress from X to orient like X3D does @@ -221,7 +229,8 @@ class x3d_class: loc = self.rotatePointForVRML(mat.translationPart()) rot = mat.toEuler() - rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD) + rot = (((rot[0]-90)), rot[1], rot[2]) + # rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD) nRot = self.rotatePointForVRML( rot ) # convert to Quaternion and to Angle Axis Q = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2]) @@ -237,13 +246,18 @@ class x3d_class: def writeFog(self, world): if world: - mtype = world.getMistype() - mparam = world.getMist() - grd = world.getHor() + mtype = world.mist.falloff + # mtype = world.getMistype() + mparam = world.mist + # mparam = world.getMist() + grd = world.horizon_color + # grd = world.getHor() grd0, grd1, grd2 = grd[0], grd[1], grd[2] else: return - if (mtype == 1 or mtype == 2): + if (mtype == 'LINEAR' or mtype == 'INVERSE_QUADRATIC'): + mtype = 1 if mtype == 'LINEAR' else 2 + # if (mtype == 1 or mtype == 2): self.file.write("\n\n" % round(mparam[2],self.cp)) @@ -256,7 +270,8 @@ class x3d_class: def writeSpotLight(self, ob, mtx, lamp, world): safeName = self.cleanStr(ob.name) if world: - ambi = world.amb + ambi = world.ambient_color + # ambi = world.amb ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 else: ambi = 0 @@ -264,7 +279,8 @@ class x3d_class: # compute cutoff and beamwidth intensity=min(lamp.energy/1.75,1.0) - beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; + beamWidth=((lamp.spot_size*math.pi)/180.0)*.37; + # beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; cutOffAngle=beamWidth*1.3 dx,dy,dz=self.computeDirection(mtx) @@ -275,12 +291,14 @@ class x3d_class: #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed location=(mtx*MATWORLD).translationPart() - radius = lamp.dist*math.cos(beamWidth) + radius = lamp.distance*math.cos(beamWidth) + # radius = lamp.dist*math.cos(beamWidth) self.file.write("\n\n" % (round(dx,4),round(dy,4),round(dz,4))) def writePointLight(self, ob, mtx, lamp, world): safeName = self.cleanStr(ob.name) if world: - ambi = world.amb + ambi = world.ambient_color + # ambi = world.amb ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 else: ambi = 0 @@ -318,9 +339,11 @@ class x3d_class: self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) ''' def writeNode(self, ob, mtx): @@ -362,24 +385,41 @@ class x3d_class: vColors={} # 'multi':1 meshName = self.cleanStr(ob.name) - meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not + meshME = self.cleanStr(ob.data.name) # We dont care if its the mesh name or not + # meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not if len(mesh.faces) == 0: return - mode = 0 - if mesh.faceUV: - for face in mesh.faces: - mode |= face.mode + mode = [] + # mode = 0 + if mesh.active_uv_texture: + # if mesh.faceUV: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + if face.halo and 'HALO' not in mode: + mode += ['HALO'] + if face.billboard and 'BILLBOARD' not in mode: + mode += ['BILLBOARD'] + if face.object_color and 'OBJECT_COLOR' not in mode: + mode += ['OBJECT_COLOR'] + if face.collision and 'COLLISION' not in mode: + mode += ['COLLISION'] + # mode |= face.mode - if mode & Mesh.FaceModes.HALO and self.halonode == 0: + if 'HALO' in mode and self.halonode == 0: + # if mode & Mesh.FaceModes.HALO and self.halonode == 0: self.writeIndented("\n",1) self.halonode = 1 - elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0: + elif 'BILLBOARD' in mode and self.billnode == 0: + # elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0: self.writeIndented("\n",1) self.billnode = 1 - elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0: + elif 'OBJECT_COLOR' in mode and self.matonly == 0: + # elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0: self.matonly = 1 - elif mode & Mesh.FaceModes.TILES and self.tilenode == 0: - self.tilenode = 1 - elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0: + # TF_TILES is marked as deprecated in DNA_meshdata_types.h + # elif mode & Mesh.FaceModes.TILES and self.tilenode == 0: + # self.tilenode = 1 + elif 'COLLISION' not in mode and self.collnode == 0: + # elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0: self.writeIndented("\n",1) self.collnode = 1 @@ -401,34 +441,44 @@ class x3d_class: quat = mtx.toQuat() rot= quat.axis - # self.writeIndented('\n' % (rot[0], rot[1], rot[2], rot[3])) self.writeIndented('\n' % \ - (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) ) + (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle) ) + # self.writeIndented('\n' % \ + # (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) ) self.writeIndented("\n",1) maters=mesh.materials hasImageTexture=0 issmooth=0 - if len(maters) > 0 or mesh.faceUV: + if len(maters) > 0 or mesh.active_uv_texture: + # if len(maters) > 0 or mesh.faceUV: self.writeIndented("\n", 1) # right now this script can only handle a single material per mesh. if len(maters) >= 1: mat=maters[0] - matFlags = mat.getMode() - if not matFlags & Blender.Material.Modes['TEXFACE']: - self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world) + # matFlags = mat.getMode() + if not mat.face_texture: + # if not matFlags & Blender.Material.Modes['TEXFACE']: + self.writeMaterial(mat, self.cleanStr(mat.name,''), world) + # self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world) if len(maters) > 1: print("Warning: mesh named %s has multiple materials" % meshName) print("Warning: only one material per object handled") #-- textures - if mesh.faceUV: - for face in mesh.faces: - if (hasImageTexture == 0) and (face.image): + face = None + if mesh.active_uv_texture: + # if mesh.faceUV: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + if face.image: + # if (hasImageTexture == 0) and (face.image): self.writeImageTexture(face.image) - hasImageTexture=1 # keep track of face texture - if self.tilenode == 1: + # hasImageTexture=1 # keep track of face texture + break + if self.tilenode == 1 and face and face.image: + # if self.tilenode == 1: self.writeIndented("\n" % (face.image.xrep, face.image.yrep)) self.tilenode = 0 self.writeIndented("\n", -1) @@ -458,11 +508,13 @@ class x3d_class: issmooth=1 break if issmooth==1: - creaseAngle=(mesh.degr)*(math.pi/180.0) + creaseAngle=(mesh.autosmooth_angle)*(math.pi/180.0) + # creaseAngle=(mesh.degr)*(math.pi/180.0) self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp))) #--- output textureCoordinates if UV texture used - if mesh.faceUV: + if mesh.active_uv_texture: + # if mesh.faceUV: if self.matonly == 1 and self.share == 1: self.writeFaceColors(mesh) elif hasImageTexture == 1: @@ -476,7 +528,8 @@ class x3d_class: self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) #--- output textureCoordinates if UV texture used - if mesh.faceUV: + if mesh.active_uv_texture: + # if mesh.faceUV: if hasImageTexture == 1: self.writeTextureCoordinates(mesh) elif self.matonly == 1 and self.share == 1: @@ -516,16 +569,22 @@ class x3d_class: if self.writingcoords == 0: self.file.write('coordIndex="') for face in mesh.faces: - fv = face.v + fv = face.verts + # fv = face.v - if len(face)==3: - self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) + if len(fv)==3: + # if len(face)==3: + self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2])) + # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) else: if EXPORT_TRI: - self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) - self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index)) + self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2])) + # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) + self.file.write("%i %i %i -1, " % (fv[0], fv[2], fv[3])) + # self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index)) else: - self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index)) + self.file.write("%i %i %i %i -1, " % (fv[0], fv[1], fv[2], fv[3])) + # self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index)) self.file.write("\">\n") else: @@ -543,8 +602,12 @@ class x3d_class: texIndexList=[] j=0 - for face in mesh.faces: - for uv in face.uv: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3] + + for uv in uvs: + # for uv in face.uv: texIndexList.append(j) texCoordList.append(uv) j=j+1 @@ -568,15 +631,24 @@ class x3d_class: def writeFaceColors(self, mesh): if self.writingcolor == 0: self.file.write("colorPerVertex=\"false\" ") - else: + elif mesh.active_vertex_color: + # else: self.writeIndented(" 2: - print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) - aColor = self.rgbToFS(c) - self.file.write("%s, " % aColor) + for face in mesh.active_vertex_color.data: + c = face.color1 + if self.verbose > 2: + print("Debug: face.col r=%d g=%d b=%d" % (c[0], c[1], c[2])) + # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) + aColor = self.rgbToFS(c) + self.file.write("%s, " % aColor) + + # for face in mesh.faces: + # if face.col: + # c=face.col[0] + # if self.verbose > 2: + # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) + # aColor = self.rgbToFS(c) + # self.file.write("%s, " % aColor) self.file.write("\" />") self.writeIndented("\n",-1) @@ -589,22 +661,31 @@ class x3d_class: self.matNames[matName]=1 - ambient = mat.amb/3 - diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] + ambient = mat.ambient/3 + # ambient = mat.amb/3 + diffuseR, diffuseG, diffuseB = tuple(mat.diffuse_color) + # diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] if world: - ambi = world.getAmb() - ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 + ambi = world.ambient_color + # ambi = world.getAmb() + ambi0, ambi1, ambi2 = (ambi[0]*mat.ambient)*2, (ambi[1]*mat.ambient)*2, (ambi[2]*mat.ambient)*2 + # ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 else: ambi0, ambi1, ambi2 = 0, 0, 0 emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2 - shininess = mat.hard/512.0 - specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001)) - specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001)) - specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001)) + shininess = mat.specular_hardness/512.0 + # shininess = mat.hard/512.0 + specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_reflection+0.001)) + # specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001)) + specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_reflection+0.001)) + # specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001)) + specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_reflection+0.001)) + # specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001)) transp = 1-mat.alpha - matFlags = mat.getMode() - if matFlags & Blender.Material.Modes['SHADELESS']: + # matFlags = mat.getMode() + if mat.shadeless: + # if matFlags & Blender.Material.Modes['SHADELESS']: ambient = 1 shine = 1 specR = emitR = diffuseR @@ -635,10 +716,13 @@ class x3d_class: def writeBackground(self, world, alltextures): if world: worldname = world.name else: return - blending = world.getSkytype() - grd = world.getHor() + blending = (world.blend_sky, world.paper_sky, world.real_sky) + # blending = world.getSkytype() + grd = world.horizon_color + # grd = world.getHor() grd0, grd1, grd2 = grd[0], grd[1], grd[2] - sky = world.getZen() + sky = world.zenith_color + # sky = world.getZen() sky0, sky1, sky2 = sky[0], sky[1], sky[2] mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2] mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2 @@ -646,27 +730,32 @@ class x3d_class: if worldname not in self.namesStandard: self.file.write("DEF=\"%s\" " % self.secureName(worldname)) # No Skytype - just Hor color - if blending == 0: + if blending == (0, 0, 0): + # if blending == 0: self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) self.file.write("skyColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) # Blend Gradient - elif blending == 1: + elif blending == (1, 0, 0): + # elif blending == 1: self.file.write("groundColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp))) self.file.write("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp))) # Blend+Real Gradient Inverse - elif blending == 3: + elif blending == (1, 0, 1): + # elif blending == 3: self.file.write("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp))) self.file.write("skyColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp))) # Paper - just Zen Color - elif blending == 4: + elif blending == (0, 0, 1): + # elif blending == 4: self.file.write("groundColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) # Blend+Real+Paper - komplex gradient - elif blending == 7: + elif blending == (1, 1, 1): + # elif blending == 7: self.writeIndented("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) self.writeIndented("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) self.writeIndented("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) @@ -675,22 +764,43 @@ class x3d_class: else: self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp))) + alltexture = len(alltextures) + for i in range(alltexture): - namemat = alltextures[i].name - pic = alltextures[i].getImage() + tex = alltextures[i] + + if tex.type != 'IMAGE': + continue + + namemat = tex.name + # namemat = alltextures[i].name + + pic = tex.image + + # using .expandpath just in case, os.path may not expect // + basename = os.path.basename(bpy.sys.expandpath(pic.filename)) + + pic = alltextures[i].image + # pic = alltextures[i].getImage() if (namemat == "back") and (pic != None): - self.file.write("\n\tbackUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) + self.file.write("\n\tbackUrl=\"%s\" " % basename) + # self.file.write("\n\tbackUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) elif (namemat == "bottom") and (pic != None): - self.writeIndented("bottomUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) + self.writeIndented("bottomUrl=\"%s\" " % basename) + # self.writeIndented("bottomUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) elif (namemat == "front") and (pic != None): - self.writeIndented("frontUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) + self.writeIndented("frontUrl=\"%s\" " % basename) + # self.writeIndented("frontUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) elif (namemat == "left") and (pic != None): - self.writeIndented("leftUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) + self.writeIndented("leftUrl=\"%s\" " % basename) + # self.writeIndented("leftUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) elif (namemat == "right") and (pic != None): - self.writeIndented("rightUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) + self.writeIndented("rightUrl=\"%s\" " % basename) + # self.writeIndented("rightUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) elif (namemat == "top") and (pic != None): - self.writeIndented("topUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) + self.writeIndented("topUrl=\"%s\" " % basename) + # self.writeIndented("topUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1]) self.writeIndented("/>\n\n") ########################################################## @@ -711,44 +821,65 @@ class x3d_class: self.proto = 0 - # COPIED FROM OBJ EXPORTER - if EXPORT_APPLY_MODIFIERS: - temp_mesh_name = '~tmp-mesh' + # # COPIED FROM OBJ EXPORTER + # if EXPORT_APPLY_MODIFIERS: + # temp_mesh_name = '~tmp-mesh' - # Get the container mesh. - used for applying modifiers and non mesh objects. - containerMesh = meshName = tempMesh = None - for meshName in Blender.NMesh.GetNames(): - if meshName.startswith(temp_mesh_name): - tempMesh = Mesh.Get(meshName) - if not tempMesh.users: - containerMesh = tempMesh - if not containerMesh: - containerMesh = Mesh.New(temp_mesh_name) + # # Get the container mesh. - used for applying modifiers and non mesh objects. + # containerMesh = meshName = tempMesh = None + # for meshName in Blender.NMesh.GetNames(): + # if meshName.startswith(temp_mesh_name): + # tempMesh = Mesh.Get(meshName) + # if not tempMesh.users: + # containerMesh = tempMesh + # if not containerMesh: + # containerMesh = Mesh.New(temp_mesh_name) # -------------------------- - for ob_main in scene.objects.context: - for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): + for ob_main in [o for o in scene.objects if o.is_visible()]: + # for ob_main in scene.objects.context: + + free, derived = create_derived_objects(ob_main) + + if derived == None: continue + + for ob, ob_mat in derived: + # for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): objType=ob.type objName=ob.name self.matonly = 0 - if objType == "Camera": + if objType == "CAMERA": + # if objType == "Camera": self.writeViewpoint(ob, ob_mat, scene) - elif objType in ("Mesh", "Curve", "Surf", "Text") : - if EXPORT_APPLY_MODIFIERS or objType != 'Mesh': - me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene) + elif objType in ("MESH", "CURVE", "SURF", "TEXT") : + # elif objType in ("Mesh", "Curve", "Surf", "Text") : + if EXPORT_APPLY_MODIFIERS or objType != 'MESH': + # if EXPORT_APPLY_MODIFIERS or objType != 'Mesh': + me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW') + # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene) else: - me = ob.getData(mesh=1) + me = ob.data + # me = ob.getData(mesh=1) self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI) - elif objType == "Lamp": + + # free mesh created with create_mesh() + if me != ob.data: + bpy.data.remove_mesh(me) + + elif objType == "LAMP": + # elif objType == "Lamp": data= ob.data datatype=data.type - if datatype == Lamp.Types.Lamp: + if datatype == 'POINT': + # if datatype == Lamp.Types.Lamp: self.writePointLight(ob, ob_mat, data, world) - elif datatype == Lamp.Types.Spot: + elif datatype == 'SPOT': + # elif datatype == Lamp.Types.Spot: self.writeSpotLight(ob, ob_mat, data, world) - elif datatype == Lamp.Types.Sun: + elif datatype == 'SUN': + # elif datatype == Lamp.Types.Sun: self.writeDirectionalLight(ob, ob_mat, data, world) else: self.writeDirectionalLight(ob, ob_mat, data, world) @@ -758,12 +889,15 @@ class x3d_class: else: #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType) pass - + + if free: + free_derived_objects(ob_main) + self.file.write("\n\n") - if EXPORT_APPLY_MODIFIERS: - if containerMesh: - containerMesh.verts = None + # if EXPORT_APPLY_MODIFIERS: + # if containerMesh: + # containerMesh.verts = None self.cleanup() @@ -812,10 +946,13 @@ class x3d_class: faceMap={} nFaceIndx=0 - if mesh.faceUV: - for face in mesh.faces: + if mesh.active_uv_texture: + # if mesh.faceUV: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: sidename=''; - if face.mode & Mesh.FaceModes.TWOSIDE: + if face.twoside: + # if face.mode & Mesh.FaceModes.TWOSIDE: sidename='two' else: sidename='one' @@ -859,31 +996,38 @@ class x3d_class: print("Debug: face.image=%s" % face.image.name) print("Debug: face.materialIndex=%d" % face.materialIndex) - def getVertexColorByIndx(self, mesh, indx): - c = None - for face in mesh.faces: - j=0 - for vertex in face.v: - if vertex.index == indx: - c=face.col[j] - break - j=j+1 - if c: break - return c + # XXX not used + # def getVertexColorByIndx(self, mesh, indx): + # c = None + # for face in mesh.faces: + # j=0 + # for vertex in face.v: + # if vertex.index == indx: + # c=face.col[j] + # break + # j=j+1 + # if c: break + # return c def meshToString(self,mesh): - print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors) - print("Debug: mesh.faceUV=%d" % mesh.faceUV) - print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()) + # print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors) + print("Debug: mesh.faceUV=%d" % (len(mesh.uv_textures) > 0)) + # print("Debug: mesh.faceUV=%d" % mesh.faceUV) + print("Debug: mesh.hasVertexColours=%d" % (len(mesh.vertex_colors) > 0)) + # print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()) print("Debug: mesh.verts=%d" % len(mesh.verts)) print("Debug: mesh.faces=%d" % len(mesh.faces)) print("Debug: mesh.materials=%d" % len(mesh.materials)) def rgbToFS(self, c): - s="%s %s %s" % ( - round(c.r/255.0,self.cp), - round(c.g/255.0,self.cp), - round(c.b/255.0,self.cp)) + s="%s %s %s" % (round(c[0]/255.0,self.cp), + round(c[1]/255.0,self.cp), + round(c[2]/255.0,self.cp)) + + # s="%s %s %s" % ( + # round(c.r/255.0,self.cp), + # round(c.g/255.0,self.cp), + # round(c.b/255.0,self.cp)) return s def computeDirection(self, mtx): @@ -891,9 +1035,10 @@ class x3d_class: ax,ay,az = (mtx*MATWORLD).toEuler() - ax *= DEG2RAD - ay *= DEG2RAD - az *= DEG2RAD + # ax *= DEG2RAD + # ay *= DEG2RAD + # az *= DEG2RAD + # rot X x1=x y1=y*math.cos(ax)-z*math.sin(ax) @@ -980,11 +1125,11 @@ class x3d_class: # Callbacks, needed before Main ########################################################## -def x3d_export(filename, \ - EXPORT_APPLY_MODIFIERS= False,\ - EXPORT_TRI= False,\ - EXPORT_GZIP= False,\ - ): +def x3d_export(filename, + context, + EXPORT_APPLY_MODIFIERS=False, + EXPORT_TRI=False, + EXPORT_GZIP=False): if EXPORT_GZIP: if not filename.lower().endswith('.x3dz'): @@ -994,9 +1139,13 @@ def x3d_export(filename, \ filename = '.'.join(filename.split('.')[:-1]) + '.x3d' - scene = Blender.Scene.GetCurrent() + scene = context.scene + # scene = Blender.Scene.GetCurrent() world = scene.world - alltextures = Blender.Texture.Get() + + # XXX these are global textures while .Get() returned only scene's? + alltextures = bpy.data.textures + # alltextures = Blender.Texture.Get() wrlexport=x3d_class(filename) wrlexport.export(\ @@ -1064,11 +1213,15 @@ class EXPORT_OT_x3d(bpy.types.Operator): # to the class instance from the operator settings before calling. __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen=1024, default=""), + + bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True), + bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False), + bpy.props.BoolProperty(attr="compress", name="Compress", description="GZip the resulting file, requires a full python install.", default=False), ] def execute(self, context): - raise Exception("Not doing anything yet.") + x3d_export(self.filename, context, self.apply_modifiers, self.triangulate, self.compress) return ('FINISHED',) def invoke(self, context, event): @@ -1081,3 +1234,6 @@ class EXPORT_OT_x3d(bpy.types.Operator): return context.active_object != None bpy.ops.add(EXPORT_OT_x3d) + +# NOTES +# - blender version is hardcoded -- cgit v1.2.3 From 0e3acbaa386384f1b1d27a2b4e0f0dcd07c0e0e2 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 17 Aug 2009 17:04:58 +0000 Subject: fix raycounters --- source/blender/render/intern/source/rayshade.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index fe76fa07433..071c70ae504 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -785,6 +785,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo else { ray_fadeout_endcolor(col, origshi, &shi, origshr, &isec, vec); } + RE_RC_MERGE(&origshi->raycounter, &shi.raycounter); } /* **************** jitter blocks ********** */ @@ -1536,6 +1537,8 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int ray_trace_shadow_tra(is, origshi, depth-1, traflag | RAY_TRA); } + + RE_RC_MERGE(&origshi->raycounter, &shi.raycounter); } } -- cgit v1.2.3 From 7220792f187f91a2ef3eb0c930a13674b2a8a80a Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Wed, 19 Aug 2009 09:52:13 +0000 Subject: Various fixes in rna_*_api.c files to remove compiler warnings. --- source/blender/editors/include/ED_mesh.h | 1 + source/blender/editors/mesh/editmesh_mods.c | 5 + source/blender/makesrna/intern/rna_action_api.c | 2 + source/blender/makesrna/intern/rna_image_api.c | 2 + source/blender/makesrna/intern/rna_internal.h | 6 +- source/blender/makesrna/intern/rna_mesh_api.c | 3 + source/blender/makesrna/intern/rna_object_api.c | 2 +- source/blender/makesrna/intern/rna_pose_api.c | 4 +- source/blender/makesrna/intern/rna_scene_api.c | 4 + source/blender/python/SConscript | 2 +- source/creator/creator.c | 4 + source/creator/tests/alltest.c | 176 ------------------------ source/creator/tests/test.c | 176 ++++++++++++++++++++++++ source/creator/tests/test.h | 6 + 14 files changed, 211 insertions(+), 182 deletions(-) delete mode 100644 source/creator/tests/alltest.c create mode 100644 source/creator/tests/test.c create mode 100644 source/creator/tests/test.h diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index cceebeadc96..696e8f823eb 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -118,6 +118,7 @@ void EM_select_face(struct EditFace *efa, int sel); void EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val); void EM_select_swap(struct EditMesh *em); void EM_toggle_select_all(struct EditMesh *em); +void EM_select_all(struct EditMesh *em); void EM_selectmode_flush(struct EditMesh *em); void EM_deselect_flush(struct EditMesh *em); void EM_selectmode_set(struct EditMesh *em); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index d27aa3f7e3a..363b6ecc4e4 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -3288,6 +3288,11 @@ void EM_toggle_select_all(EditMesh *em) /* exported for UV */ EM_set_flag_all(em, SELECT); } +void EM_select_all(EditMesh *em) +{ + EM_set_flag_all(em, SELECT); +} + static int toggle_select_all_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c index 2b51a424fcf..11efa6d5f8a 100644 --- a/source/blender/makesrna/intern/rna_action_api.c +++ b/source/blender/makesrna/intern/rna_action_api.c @@ -36,6 +36,8 @@ #ifdef RNA_RUNTIME +#include "BKE_action.h" + #include "DNA_anim_types.h" #include "DNA_curve_types.h" diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index ccc9846600d..fee379cd285 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -41,6 +41,8 @@ #include "BKE_utildefines.h" #include "BKE_image.h" +#include "MEM_guardedalloc.h" + /* User should check if returned path exists before copying a file there. diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index cff77fbb34b..af94f0ccc6f 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -197,13 +197,15 @@ void rna_Object_update_data(struct bContext *C, struct PointerRNA *ptr); /* API functions */ +void RNA_api_action(StructRNA *srna); +void RNA_api_image(struct StructRNA *srna); void RNA_api_main(struct StructRNA *srna); +void RNA_api_material(StructRNA *srna); void RNA_api_mesh(struct StructRNA *srna); void RNA_api_object(struct StructRNA *srna); +void RNA_api_scene(struct StructRNA *srna); void RNA_api_ui_layout(struct StructRNA *srna); void RNA_api_wm(struct StructRNA *srna); -void RNA_api_scene(struct StructRNA *srna); -void RNA_api_material(StructRNA *srna); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 9d4dad1fb5b..1db2f155d14 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -42,6 +42,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_material.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" @@ -52,6 +53,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "MEM_guardedalloc.h" + static void rna_Mesh_calc_edges(Mesh *mesh) { CustomData edata; diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index f0a42987848..3c79c1cbc21 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -273,7 +273,7 @@ static void rna_Object_convert_to_triface(Object *ob, bContext *C, ReportList *r make_editMesh(sce, ob); /* select all */ - EM_set_flag_all(me->edit_mesh, SELECT); + EM_select_all(me->edit_mesh); convert_to_triface(me->edit_mesh, 0); diff --git a/source/blender/makesrna/intern/rna_pose_api.c b/source/blender/makesrna/intern/rna_pose_api.c index 9ac7713b2e9..42bb52d8544 100644 --- a/source/blender/makesrna/intern/rna_pose_api.c +++ b/source/blender/makesrna/intern/rna_pose_api.c @@ -45,8 +45,8 @@ void RNA_api_pose(StructRNA *srna) { - FunctionRNA *func; - PropertyRNA *parm; + /* FunctionRNA *func; */ + /* PropertyRNA *parm; */ } diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index f3cbb630df5..076fe38ed2f 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -38,8 +38,12 @@ #ifdef RNA_RUNTIME #include "BKE_scene.h" +#include "BKE_depsgraph.h" + #include "ED_object.h" +#include "WM_api.h" + static void rna_Scene_add_object(Scene *sce, ReportList *reports, Object *ob) { Base *base= object_in_scene(ob, sce); diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 357d2c99d3b..d44cf762a0f 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. ../editors/include ../makesdna ../makesrna ../makesrna/intern ../blenlib ../blenkernel ../nodes' +incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes' incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager' incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/creator/creator.c b/source/creator/creator.c index e196213c945..6ecde9e5546 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -97,6 +97,10 @@ #include "binreloc.h" #endif +#ifdef WITH_UNIT_TEST +#include "tests/test.h" +#endif + // from buildinfo.c #ifdef BUILD_DATE extern char * build_date; diff --git a/source/creator/tests/alltest.c b/source/creator/tests/alltest.c deleted file mode 100644 index 89a58a08dfd..00000000000 --- a/source/creator/tests/alltest.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BKE_blender.h" -#include "BKE_image.h" -#include "BKE_utildefines.h" -#include "BKE_global.h" - -#include "BLI_listbase.h" -#include "BLI_util.h" -#include "BLI_fileops.h" -#include "BLI_string.h" - -#include "DNA_image_types.h" - -char bprogname[FILE_MAXDIR+FILE_MAXFILE]; -char btempdir[FILE_MAXDIR+FILE_MAXFILE]; - -typedef struct ImageTestResult { - char *path; - char *rel; - int ret; -} ImageTestResult; - -typedef struct ImageTestData { - char *path; /* image filename */ - ImageTestResult result[10]; -} ImageTestData; - -/* check that BKE_copy_images manipulates paths correctly */ -START_TEST(test_copy_images) -{ - char **dir; - ImageTestData *test; - int i,j; - -#ifdef WIN32 - /* TBD... */ -#else - /* - XXX are these paths possible in image->name?: - - ./foo/image.png - ../foo/image.png - - if so, BKE_copy_images currently doesn't support them! - */ - - const char *blend_dir = "/home/user/foo"; - char *dest_dir[] = {"/home/user/", "/home/user", "/home/user/export/", "/home/user/foo/", NULL}; - - static ImageTestData test_data[] = { - - /* image path | [expected output path | corresponding relative path | expected return value] */ - - /* relative, 0 level deep */ - {"//image.png", {{"/home/user/image.png", "image.png", 1}, - {"/home/user/image.png", "image.png", 1}, - {"/home/user/export/image.png", "image.png", 1}, - {"/home/user/foo/image.png", "image.png", 2},}}, - - /* relative, 1 level deep */ - {"//bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, - {"/home/user/bar/image.png", "bar/image.png", 1}, - {"/home/user/export/bar/image.png", "bar/image.png", 1}, - {"/home/user/foo/bar/image.png", "bar/image.png", 2},}}, - - /* relative, 2 level deep */ - {"//bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, - {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, - {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, - {"/home/user/foo/bar/foo/image.png", "bar/foo/image.png", 2},}}, - - /* absolute, not under .blend dir */ - {"/home/user/bar/image.png", {{"/home/user/image.png", "image.png", 1}, - {"/home/user/image.png", "image.png", 1}, - {"/home/user/export/image.png", "image.png", 1}, - {"/home/user/foo/image.png", "image.png", 1},}}, - - /* absolute, under .blend dir, 0 level deep */ - {"/home/user/foo/image.png", {{"/home/user/image.png", "image.png", 1}, - {"/home/user/image.png", "image.png", 1}, - {"/home/user/export/image.png", "image.png", 1}, - {"/home/user/foo/image.png", "image.png", 2},}}, - - /* absolute, under .blend dir, 1 level deep */ - {"/home/user/foo/bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, - {"/home/user/bar/image.png", "bar/image.png", 1}, - {"/home/user/export/bar/image.png", "bar/image.png", 1}, - {"/home/user/foo/bar/image.png", "bar/image.png", 2},}}, - - /* absolute, under .blend dir, 2 level deep */ - {"/home/user/foo/bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, - {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, - {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, - {"/home/user/foo/bar/foo/image.png", "bar/foo/image.png", 2},}}, - - /* empty image path, don't let these pass! */ - {"", {{"", 0}, - {"", 0}, - {"", 0}}}, - - {NULL}, - }; - - /* substitute G.sce */ - BLI_snprintf(G.sce, sizeof(G.sce), "%s/untitled.blend", blend_dir); -#endif - - for (dir= dest_dir, i= 0; *dir; dir++, i++) { - for (test= &test_data[0]; test->path; test++) { - Image image; - char path[FILE_MAX]; - char rel[FILE_MAX]; - char part[200]; - int ret; - - BLI_strncpy(image.name, test->path, sizeof(image.name)); - - /* passing NULL as abs path or rel path or both shouldn't break it */ - int abs_rel_null[][2]= {{0, 0}, {1, 0}, {0, 1}, {1, 1}, {-1}}; - - for (j= 0; abs_rel_null[j][0] != -1; j++) { - - int *is_null= abs_rel_null[j]; - - ret= BKE_get_image_export_path(&image, *dir, - is_null[0] ? NULL : path, sizeof(path), - is_null[1] ? NULL : rel, sizeof(rel)); - - BLI_snprintf(part, sizeof(part), "For image at %s (output abs path is %s, rel path is %s)", - test->path, is_null[0] ? "NULL" : "non-NULL", is_null[1] ? "NULL" : "non-NULL"); - - /* we should get what we expect */ - ImageTestResult *res= &test->result[i]; - fail_if(ret != res->ret, "%s, expected to return %d got %d.", part, res->ret, ret); - - if (!is_null[0] && res->path) - fail_if(strcmp(path, res->path), "%s, expected absolute path \"%s\" got \"%s\".", part, res->path, path); - if (!is_null[1] && res->rel) - fail_if(strcmp(rel, res->rel), "%s, expected relative path \"%s\" got \"%s\".", part, res->rel, rel); - } - } - } -} -END_TEST - -static Suite *image_suite(void) -{ - Suite *s= suite_create("Image"); - - /* Core test case */ - TCase *tc_core= tcase_create("Core"); - tcase_add_test(tc_core, test_copy_images); - suite_add_tcase(s, tc_core); - - return s; -} - -int run_tests() -{ - int totfail; - Suite *s= image_suite(); - SRunner *sr= srunner_create(s); - - /* run tests */ - srunner_run_all(sr, CK_VERBOSE); - - totfail= srunner_ntests_failed(sr); - srunner_free(sr); - - return !totfail ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/source/creator/tests/test.c b/source/creator/tests/test.c new file mode 100644 index 00000000000..89a58a08dfd --- /dev/null +++ b/source/creator/tests/test.c @@ -0,0 +1,176 @@ +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_blender.h" +#include "BKE_image.h" +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "BLI_listbase.h" +#include "BLI_util.h" +#include "BLI_fileops.h" +#include "BLI_string.h" + +#include "DNA_image_types.h" + +char bprogname[FILE_MAXDIR+FILE_MAXFILE]; +char btempdir[FILE_MAXDIR+FILE_MAXFILE]; + +typedef struct ImageTestResult { + char *path; + char *rel; + int ret; +} ImageTestResult; + +typedef struct ImageTestData { + char *path; /* image filename */ + ImageTestResult result[10]; +} ImageTestData; + +/* check that BKE_copy_images manipulates paths correctly */ +START_TEST(test_copy_images) +{ + char **dir; + ImageTestData *test; + int i,j; + +#ifdef WIN32 + /* TBD... */ +#else + /* + XXX are these paths possible in image->name?: + + ./foo/image.png + ../foo/image.png + + if so, BKE_copy_images currently doesn't support them! + */ + + const char *blend_dir = "/home/user/foo"; + char *dest_dir[] = {"/home/user/", "/home/user", "/home/user/export/", "/home/user/foo/", NULL}; + + static ImageTestData test_data[] = { + + /* image path | [expected output path | corresponding relative path | expected return value] */ + + /* relative, 0 level deep */ + {"//image.png", {{"/home/user/image.png", "image.png", 1}, + {"/home/user/image.png", "image.png", 1}, + {"/home/user/export/image.png", "image.png", 1}, + {"/home/user/foo/image.png", "image.png", 2},}}, + + /* relative, 1 level deep */ + {"//bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/export/bar/image.png", "bar/image.png", 1}, + {"/home/user/foo/bar/image.png", "bar/image.png", 2},}}, + + /* relative, 2 level deep */ + {"//bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/foo/bar/foo/image.png", "bar/foo/image.png", 2},}}, + + /* absolute, not under .blend dir */ + {"/home/user/bar/image.png", {{"/home/user/image.png", "image.png", 1}, + {"/home/user/image.png", "image.png", 1}, + {"/home/user/export/image.png", "image.png", 1}, + {"/home/user/foo/image.png", "image.png", 1},}}, + + /* absolute, under .blend dir, 0 level deep */ + {"/home/user/foo/image.png", {{"/home/user/image.png", "image.png", 1}, + {"/home/user/image.png", "image.png", 1}, + {"/home/user/export/image.png", "image.png", 1}, + {"/home/user/foo/image.png", "image.png", 2},}}, + + /* absolute, under .blend dir, 1 level deep */ + {"/home/user/foo/bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/bar/image.png", "bar/image.png", 1}, + {"/home/user/export/bar/image.png", "bar/image.png", 1}, + {"/home/user/foo/bar/image.png", "bar/image.png", 2},}}, + + /* absolute, under .blend dir, 2 level deep */ + {"/home/user/foo/bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1}, + {"/home/user/foo/bar/foo/image.png", "bar/foo/image.png", 2},}}, + + /* empty image path, don't let these pass! */ + {"", {{"", 0}, + {"", 0}, + {"", 0}}}, + + {NULL}, + }; + + /* substitute G.sce */ + BLI_snprintf(G.sce, sizeof(G.sce), "%s/untitled.blend", blend_dir); +#endif + + for (dir= dest_dir, i= 0; *dir; dir++, i++) { + for (test= &test_data[0]; test->path; test++) { + Image image; + char path[FILE_MAX]; + char rel[FILE_MAX]; + char part[200]; + int ret; + + BLI_strncpy(image.name, test->path, sizeof(image.name)); + + /* passing NULL as abs path or rel path or both shouldn't break it */ + int abs_rel_null[][2]= {{0, 0}, {1, 0}, {0, 1}, {1, 1}, {-1}}; + + for (j= 0; abs_rel_null[j][0] != -1; j++) { + + int *is_null= abs_rel_null[j]; + + ret= BKE_get_image_export_path(&image, *dir, + is_null[0] ? NULL : path, sizeof(path), + is_null[1] ? NULL : rel, sizeof(rel)); + + BLI_snprintf(part, sizeof(part), "For image at %s (output abs path is %s, rel path is %s)", + test->path, is_null[0] ? "NULL" : "non-NULL", is_null[1] ? "NULL" : "non-NULL"); + + /* we should get what we expect */ + ImageTestResult *res= &test->result[i]; + fail_if(ret != res->ret, "%s, expected to return %d got %d.", part, res->ret, ret); + + if (!is_null[0] && res->path) + fail_if(strcmp(path, res->path), "%s, expected absolute path \"%s\" got \"%s\".", part, res->path, path); + if (!is_null[1] && res->rel) + fail_if(strcmp(rel, res->rel), "%s, expected relative path \"%s\" got \"%s\".", part, res->rel, rel); + } + } + } +} +END_TEST + +static Suite *image_suite(void) +{ + Suite *s= suite_create("Image"); + + /* Core test case */ + TCase *tc_core= tcase_create("Core"); + tcase_add_test(tc_core, test_copy_images); + suite_add_tcase(s, tc_core); + + return s; +} + +int run_tests() +{ + int totfail; + Suite *s= image_suite(); + SRunner *sr= srunner_create(s); + + /* run tests */ + srunner_run_all(sr, CK_VERBOSE); + + totfail= srunner_ntests_failed(sr); + srunner_free(sr); + + return !totfail ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/source/creator/tests/test.h b/source/creator/tests/test.h new file mode 100644 index 00000000000..37bdab301fc --- /dev/null +++ b/source/creator/tests/test.h @@ -0,0 +1,6 @@ +#ifndef _BF_UNIT_TEST +#define _BF_UNIT_TEST + +int run_tests(); + +#endif /* _BF_UNIT_TEST */ -- cgit v1.2.3 From 9967037e92ad75e76c3536a93a63a7100e4ccdc9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Aug 2009 10:16:39 +0000 Subject: [#19029] Baking selected to active with nearby dupliframes objects crashes blender from Jorge Hodge (watcom) Confirmed the crash. baking didn't account for RE_RAY_TRANSFORM_OFFS in R.objectinstance. --- source/blender/render/intern/source/rendercore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 2793e238dc7..6b6a736a420 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2241,7 +2241,7 @@ static int bake_check_intersect(Isect *is, int ob, RayFace *face) /* no direction checking for now, doesn't always improve the result * (INPR(shi->facenor, bs->dir) > 0.0f); */ - return (R.objectinstance[ob].obr->ob != bs->actob); + return (R.objectinstance[ob & ~RE_RAY_TRANSFORM_OFFS].obr->ob != bs->actob); } static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist) -- cgit v1.2.3 From 9261efa4d6dd59f9284443fea85a24282eb72d27 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Aug 2009 10:37:39 +0000 Subject: [#18936] Particle Related Patch from Alberto Santos (dnakhain) This also adds the option to duplicate a particle system with an object. --- description from the patch submission. This patch includes my latest additions to the Python API developed for my Degree's Project. It includes: - Particle - Vertex group dictionary in doc (to use with setvertexgroup/getvertexgroup) - Particle.New return psys (not specified in doc) - Draw As variable and dict - Strand render toggle - Object - psys variable in duplicate - Material - Strand render variables - Texture - Use colorbands - Lamp - Spot buffer type selection --- source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/python/api2_2x/Lamp.c | 41 +++++- source/blender/python/api2_2x/Material.c | 203 ++++++++++++++++++++++++++ source/blender/python/api2_2x/Object.c | 10 +- source/blender/python/api2_2x/Particle.c | 100 ++++++++++++- source/blender/python/api2_2x/Texture.c | 29 ++++ source/blender/python/api2_2x/doc/Lamp.py | 7 + source/blender/python/api2_2x/doc/Material.py | 18 +++ source/blender/python/api2_2x/doc/Object.py | 5 +- source/blender/python/api2_2x/doc/Particle.py | 32 +++- source/blender/python/api2_2x/doc/Texture.py | 2 + source/blender/src/editobject.c | 11 ++ 12 files changed, 450 insertions(+), 9 deletions(-) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index fbd962f9372..a986f993722 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -313,6 +313,7 @@ extern UserDef U; /* from usiblender.c !!!! */ #define USER_DUP_TEX (1 << 8) #define USER_DUP_ARM (1 << 9) #define USER_DUP_ACT (1 << 10) +#define USER_DUP_PSYS (1 << 11) /* gameflags */ #define USER_DEPRECATED_FLAG 1 diff --git a/source/blender/python/api2_2x/Lamp.c b/source/blender/python/api2_2x/Lamp.c index 3b7a785f32e..d3acc089944 100644 --- a/source/blender/python/api2_2x/Lamp.c +++ b/source/blender/python/api2_2x/Lamp.c @@ -125,6 +125,8 @@ #define EXPP_LAMP_COL_MAX 1.0 #define EXPP_LAMP_FALLOFF_MIN LA_FALLOFF_CONSTANT #define EXPP_LAMP_FALLOFF_MAX LA_FALLOFF_SLIDERS +#define EXPP_LAMP_BUFFERTYPE_MIN LA_SHADBUF_REGULAR +#define EXPP_LAMP_BUFFERTYPE_MAX LA_SHADBUF_HALFWAY /* Raytracing settings */ #define EXPP_LAMP_RAYSAMPLES_MIN 1 @@ -268,6 +270,8 @@ static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args ); static int Lamp_setComponent( BPy_Lamp * self, PyObject * value, void * closure ); static PyObject *Lamp_getFalloffType( BPy_Lamp * self ); static int Lamp_setFalloffType( BPy_Lamp * self, PyObject * value ); +static PyObject *Lamp_getBufferType( BPy_Lamp * self ); +static int Lamp_setBufferType( BPy_Lamp * self, PyObject * value ); /*****************************************************************************/ /* Python BPy_Lamp methods table: */ @@ -489,6 +493,10 @@ static PyGetSetDef BPy_Lamp_getseters[] = { (getter)Lamp_getFalloffType, (setter)Lamp_setFalloffType, "Lamp falloff type", NULL}, + {"bufferType", + (getter)Lamp_getBufferType, (setter)Lamp_setBufferType, + "Lamp buffer type", + NULL}, {"R", (getter)Lamp_getComponent, (setter)Lamp_setComponent, "Lamp color red component", @@ -828,13 +836,31 @@ static PyObject *Lamp_FalloffsDict( void ) return Falloffs; } +static PyObject *Lamp_BufferTypesDict( void ) +{ /* create the Blender.Lamp.BufferTypes constant dict */ + PyObject *Types = PyConstant_New( ); + + if( Types ) { + BPy_constant *c = ( BPy_constant * ) Types; + + PyConstant_Insert( c, "REGULAR", + PyInt_FromLong( LA_SHADBUF_REGULAR ) ); + PyConstant_Insert( c, "IRREGULAR", + PyInt_FromLong( LA_SHADBUF_IRREGULAR ) ); + PyConstant_Insert( c, "HALFWAY", + PyInt_FromLong( LA_SHADBUF_HALFWAY ) ); + } + + return Types; +} + /*****************************************************************************/ /* Function: Lamp_Init */ /*****************************************************************************/ /* Needed by the Blender module, to register the Blender.Lamp submodule */ PyObject *Lamp_Init( void ) { - PyObject *submodule, *Types, *Modes, *Falloffs; + PyObject *submodule, *Types, *Modes, *Falloffs, *BufferTypes; if( PyType_Ready( &Lamp_Type ) < 0) return NULL; @@ -842,6 +868,7 @@ PyObject *Lamp_Init( void ) Types = Lamp_TypesDict( ); Modes = Lamp_ModesDict( ); Falloffs = Lamp_FalloffsDict( ); + BufferTypes = Lamp_BufferTypesDict( ); submodule = Py_InitModule3( "Blender.Lamp", M_Lamp_methods, M_Lamp_doc ); @@ -852,6 +879,8 @@ PyObject *Lamp_Init( void ) PyModule_AddObject( submodule, "Modes", Modes ); if( Falloffs ) PyModule_AddObject( submodule, "Falloffs", Falloffs ); + if( BufferTypes ) + PyModule_AddObject( submodule, "BufferTypes", BufferTypes ); PyModule_AddIntConstant( submodule, "RGB", IPOKEY_RGB ); PyModule_AddIntConstant( submodule, "ENERGY", IPOKEY_ENERGY ); @@ -1029,6 +1058,11 @@ static PyObject *Lamp_getFalloffType( BPy_Lamp * self ) return PyInt_FromLong( (int)self->lamp->falloff_type ); } +static PyObject *Lamp_getBufferType( BPy_Lamp * self ) +{ + return PyInt_FromLong( (int)self->lamp->buftype ); +} + static int Lamp_setType( BPy_Lamp * self, PyObject * value ) { return EXPP_setIValueRange ( value, &self->lamp->type, @@ -1217,6 +1251,11 @@ static int Lamp_setFalloffType( BPy_Lamp * self, PyObject * value ) EXPP_LAMP_FALLOFF_MIN, EXPP_LAMP_FALLOFF_MAX, 'h' ); } +static int Lamp_setBufferType( BPy_Lamp * self, PyObject * value ) +{ + return EXPP_setIValueRange ( value, &self->lamp->buftype, + EXPP_LAMP_BUFFERTYPE_MIN, EXPP_LAMP_BUFFERTYPE_MAX, 'h' ); +} static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure ) { diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c index 50a1be3fa97..cc0dd9ff6a5 100644 --- a/source/blender/python/api2_2x/Material.c +++ b/source/blender/python/api2_2x/Material.c @@ -747,6 +747,26 @@ static PyObject *Material_getColorbandSpecularInput( BPy_Material * self ); static int Material_setColorbandDiffuseInput ( BPy_Material * self, PyObject * value); static int Material_setColorbandSpecularInput ( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandTangentShad( BPy_Material * self ); +static int Material_setStrandTangentShad( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandSurfDiff( BPy_Material * self ); +static int Material_setStrandSurfDiff( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandDist( BPy_Material * self ); +static int Material_setStrandDist( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandBlendUnit( BPy_Material * self ); +static int Material_setStrandBlendUnit( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandStart( BPy_Material * self ); +static int Material_setStrandStart( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandEnd( BPy_Material * self ); +static int Material_setStrandEnd( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandMin( BPy_Material * self ); +static int Material_setStrandMin( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandShape( BPy_Material * self ); +static int Material_setStrandShape( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandWidthFad( BPy_Material * self ); +static int Material_setStrandWidthFad( BPy_Material * self, PyObject * value); +static PyObject *Material_getStrandUV( BPy_Material * self ); +static int Material_setStrandUV( BPy_Material * self, PyObject * value); /*****************************************************************************/ @@ -1313,6 +1333,46 @@ static PyGetSetDef BPy_Material_getseters[] = { (getter)Material_getColorbandDiffuseInput, (setter)Material_setColorbandDiffuseInput, "The diffuse colorband input for this material", NULL}, + {"strandTanShad", + (getter)Material_getStrandTangentShad, (setter)Material_setStrandTangentShad, + "Uses direction of strands as normal for tangent-shading", + NULL}, + {"strandSurfDiff", + (getter)Material_getStrandSurfDiff, (setter)Material_setStrandSurfDiff, + "Make diffuse shading more similar to shading the surface", + NULL}, + {"strandDist", + (getter)Material_getStrandDist, (setter)Material_setStrandDist, + "Distance in Blender units over which to blend in the surface normal", + NULL}, + {"strandBlendUnit", + (getter)Material_getStrandBlendUnit, (setter)Material_setStrandBlendUnit, + "Use actual Blender units for widths instead of pixels", + NULL}, + {"strandStart", + (getter)Material_getStrandStart, (setter)Material_setStrandStart, + "Start size of strands", + NULL}, + {"strandEnd", + (getter)Material_getStrandEnd, (setter)Material_setStrandEnd, + "End size of strands", + NULL}, + {"strandMin", + (getter)Material_getStrandMin, (setter)Material_setStrandMin, + "Minimum size of strands in pixels", + NULL}, + {"strandShape", + (getter)Material_getStrandShape, (setter)Material_setStrandShape, + "Shape of strands, positive value makes it rounder, negative makes it spiky", + NULL}, + {"strandFade", + (getter)Material_getStrandWidthFad, (setter)Material_setStrandWidthFad, + "Transparency along the width of the strand", + NULL}, + {"strandUV", + (getter)Material_getStrandUV, (setter)Material_setStrandUV, + "Set name of UV layer to override", + NULL}, /* SSS settings */ {"enableSSS", @@ -3582,3 +3642,146 @@ static int Material_setColorbandSpecularInput ( BPy_Material * self, PyObject * return EXPP_setIValueClamped(value, &self->material->rampin_spec, MA_RAMP_IN_SHADER, MA_RAMP_IN_RESULT, 'b'); } + +/* Strand */ + +static PyObject *Material_getStrandTangentShad( BPy_Material * self ) +{ + return PyInt_FromLong( ((long)( self->material->mode & MA_TANGENT_STR )) > 0 ); +} + +static int Material_setStrandTangentShad( BPy_Material * self, PyObject * value) +{ + int number; + + if( !PyInt_Check( value ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( value ); + + if (number){ + self->material->mode |= MA_TANGENT_STR; + }else{ + self->material->mode &= ~MA_TANGENT_STR; + } + + return 0; +} + +static PyObject *Material_getStrandSurfDiff( BPy_Material * self ) +{ + return PyInt_FromLong( ((long)( self->material->mode & MA_STR_SURFDIFF )) > 0 ); +} + +static int Material_setStrandSurfDiff( BPy_Material * self, PyObject * value) +{ + int number; + + if( !PyInt_Check( value ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( value ); + + if (number){ + self->material->mode |= MA_STR_SURFDIFF; + }else{ + self->material->mode &= ~MA_STR_SURFDIFF; + } + + return 0; +} + +static PyObject *Material_getStrandDist( BPy_Material * self ) +{ + return PyFloat_FromDouble( ((float)( self->material->strand_surfnor )) ); +} + +static int Material_setStrandDist( BPy_Material * self, PyObject * value) +{ + return EXPP_setFloatRange( value, &self->material->strand_surfnor, 0.0, 10.0 ); +} + +static PyObject *Material_getStrandBlendUnit( BPy_Material * self ) +{ + return PyInt_FromLong( ((long)( self->material->mode & MA_STR_B_UNITS )) > 0 ); +} + +static int Material_setStrandBlendUnit( BPy_Material * self, PyObject * value) +{ + int number; + + if( !PyInt_Check( value ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( value ); + + if (number){ + self->material->mode |= MA_STR_B_UNITS; + }else{ + self->material->mode &= ~MA_STR_B_UNITS; + } + + return 0; +} + +static PyObject *Material_getStrandStart( BPy_Material * self ) +{ + return PyFloat_FromDouble( ((float)( self->material->strand_sta )) ); +} + +static int Material_setStrandStart( BPy_Material * self, PyObject * value) +{ + return EXPP_setFloatRange( value, &self->material->strand_sta, 0.0001, 2.0 ); +} + +static PyObject *Material_getStrandEnd( BPy_Material * self ) +{ + return PyFloat_FromDouble( ((float)( self->material->strand_end )) ); +} + +static int Material_setStrandEnd( BPy_Material * self, PyObject * value) +{ + return EXPP_setFloatRange( value, &self->material->strand_end, 0.0001, 1.0 ); +} + +static PyObject *Material_getStrandMin( BPy_Material * self ) +{ + return PyFloat_FromDouble( ((float)( self->material->strand_min )) ); +} + +static int Material_setStrandMin( BPy_Material * self, PyObject * value) +{ + return EXPP_setFloatRange( value, &self->material->strand_min, 0.0001, 10.0 ); +} + +static PyObject *Material_getStrandShape( BPy_Material * self ) +{ + return PyFloat_FromDouble( ((float)( self->material->strand_ease )) ); +} + +static int Material_setStrandShape( BPy_Material * self, PyObject * value) +{ + return EXPP_setFloatRange( value, &self->material->strand_ease, -0.9, 0.9 ); +} + +static PyObject *Material_getStrandWidthFad( BPy_Material * self ) +{ + return PyFloat_FromDouble( ((float)( self->material->strand_widthfade )) ); +} + +static int Material_setStrandWidthFad( BPy_Material * self, PyObject * value) +{ + return EXPP_setFloatRange( value, &self->material->strand_widthfade, 0.0, 2.0 ); +} + +static PyObject *Material_getStrandUV( BPy_Material * self ) +{ + return EXPP_ReturnPyObjError( PyExc_NotImplementedError, + "Material.strandUV not implemented" ); +} + +static int Material_setStrandUV( BPy_Material * self, PyObject * value) +{ + return EXPP_ReturnPyObjError( PyExc_NotImplementedError, + "Material.strandUV not implemented" ); +} diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index b50b0082bf4..8617491e950 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -1001,9 +1001,10 @@ static PyObject *M_Object_Duplicate( PyObject * self_unused, int material_dupe = 0; int texture_dupe = 0; int ipo_dupe = 0; + int psys_dupe = 0; static char *kwlist[] = {"mesh", "surface", "curve", - "text", "metaball", "armature", "lamp", "material", "texture", "ipo", NULL}; + "text", "metaball", "armature", "lamp", "material", "texture", "ipo", "psys", NULL}; /* duplicating in background causes segfaults */ if( G.background == 1 ) @@ -1011,11 +1012,11 @@ static PyObject *M_Object_Duplicate( PyObject * self_unused, "cannot duplicate objects in background mode" ); - if (!PyArg_ParseTupleAndKeywords(args, kwd, "|iiiiiiiiii", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwd, "|iiiiiiiiiii", kwlist, &mesh_dupe, &surface_dupe, &curve_dupe, &text_dupe, &metaball_dupe, - &armature_dupe, &lamp_dupe, &material_dupe, &texture_dupe, &ipo_dupe)) + &armature_dupe, &lamp_dupe, &material_dupe, &texture_dupe, &ipo_dupe, &psys_dupe)) return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected nothing or bool keywords 'mesh', 'surface', 'curve', 'text', 'metaball', 'armature', 'lamp' 'material', 'texture' and 'ipo' as arguments" ); + "expected nothing or bool keywords 'mesh', 'surface', 'curve', 'text', 'metaball', 'armature', 'lamp' 'material', 'texture', 'ipo' and 'psys' as arguments" ); /* USER_DUP_ACT for actions is not supported in the UI so dont support it here */ if (mesh_dupe) dupflag |= USER_DUP_MESH; @@ -1028,6 +1029,7 @@ static PyObject *M_Object_Duplicate( PyObject * self_unused, if (material_dupe) dupflag |= USER_DUP_MAT; if (texture_dupe) dupflag |= USER_DUP_TEX; if (ipo_dupe) dupflag |= USER_DUP_IPO; + if (psys_dupe) dupflag |= USER_DUP_PSYS; adduplicate(2, dupflag); /* 2 is a mode with no transform and no redraw, Duplicate the current selection, context sensitive */ Py_RETURN_NONE; } diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c index f69cb6a01b9..850100d29a9 100644 --- a/source/blender/python/api2_2x/Particle.c +++ b/source/blender/python/api2_2x/Particle.c @@ -42,6 +42,7 @@ #include "BKE_utildefines.h" #include "BKE_pointcache.h" #include "BKE_DerivedMesh.h" +#include "BKE_library.h" #include "BIF_editparticle.h" #include "BIF_space.h" #include "blendef.h" @@ -70,6 +71,9 @@ static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ); static PyObject *Part_GetVertGroup( BPy_PartSys * self, PyObject * args ); static PyObject *Part_SetVertGroup( BPy_PartSys * self, PyObject * args ); +static int Part_SetName( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_SetNameWithMethod( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_GetName( BPy_PartSys * self, PyObject * args ); static int Part_setSeed( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getSeed( BPy_PartSys * self ); static int Part_setType( BPy_PartSys * self, PyObject * args ); @@ -141,11 +145,16 @@ static int Part_setRenderDied( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getRenderDied( BPy_PartSys * self ); static int Part_setRenderMaterialIndex( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getRenderMaterialIndex( BPy_PartSys * self ); +static int Part_setStrandRender( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getStrandRender( BPy_PartSys * self ); +static int Part_setStrandRenderAn( BPy_PartSys * self, PyObject * args ); +static PyObject *Part_getStrandRenderAn( BPy_PartSys * self ); static int Part_setStep( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getStep( BPy_PartSys * self ); static int Part_setRenderStep( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getRenderStep( BPy_PartSys * self ); static PyObject *Part_getDupOb( BPy_PartSys * self ); +static int Part_setDrawAs( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getDrawAs( BPy_PartSys * self ); static int Part_setPhysType( BPy_PartSys * self, PyObject * args ); static PyObject *Part_getPhysType( BPy_PartSys * self ); @@ -283,6 +292,10 @@ static PyMethodDef BPy_ParticleSys_methods[] = { METH_VARARGS, "() - Get the vertex group which affects a particles attribute"}, {"setVertGroup", ( PyCFunction ) Part_SetVertGroup, METH_VARARGS, "() - Set the vertex group to affect a particles attribute"}, + {"getName", ( PyCFunction ) Part_GetName, METH_NOARGS, + "() - Return particle system's name"}, + {"setName", ( PyCFunction ) Part_SetNameWithMethod, METH_VARARGS, + "(s) - Change particle system's name"}, {NULL, NULL, 0, NULL} }; @@ -430,6 +443,14 @@ static PyGetSetDef BPy_ParticleSys_getseters[] = { (getter)Part_getRenderMaterialIndex, (setter)Part_setRenderMaterialIndex, "Specify material index used for the particles", NULL}, + {"strandRender", + (getter)Part_getStrandRender, (setter)Part_setStrandRender, + "Use the strand primitive to render", + NULL}, + {"strandRenderAngle", + (getter)Part_getStrandRenderAn, (setter)Part_setStrandRenderAn, + "How many degrees path has to curve to make another render segment", + NULL}, {"displayPercentage", (getter)Part_getParticleDisp, (setter)Part_setParticleDisp, "Particle display percentage", @@ -447,8 +468,8 @@ static PyGetSetDef BPy_ParticleSys_getseters[] = { "Get the duplicate ob", NULL}, {"drawAs", - (getter)Part_getDrawAs, NULL, - "Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )", + (getter)Part_getDrawAs, (setter)Part_setDrawAs, + "Draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )", NULL}, /* Newtonian Physics */ {"physics", @@ -2008,6 +2029,33 @@ static PyObject *Part_SetVertGroup( BPy_PartSys * self, PyObject * args ){ Py_RETURN_NONE; } +PyObject *Part_GetName( BPy_PartSys * self, PyObject * args ) +{ + ID *id = (ID*) self->psys->part; + if (!id) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "data has been removed" ) ); + return PyString_FromString( id->name + 2 ); +} + +int Part_SetName( BPy_PartSys * self, PyObject * args ) +{ + ID *id = (ID*) self->psys->part; + char *name = NULL; + if (!id) return ( EXPP_ReturnIntError( PyExc_RuntimeError, "data has been removed" ) ); + + name = PyString_AsString ( args ); + if( !name ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected string argument" ); + + rename_id( id, name ); + + return 0; +} + +PyObject * Part_SetNameWithMethod( BPy_PartSys *self, PyObject *args ) +{ + return EXPP_setterWrapper( (void *)self, args, (setter)Part_SetName ); +} /*****************************************************************************/ /* Function: Set/Get Seed */ @@ -2714,6 +2762,44 @@ static PyObject *Part_getRenderDied( BPy_PartSys * self ) return PyInt_FromLong( ((long)( self->psys->part->flag & PART_DIED )) > 0 ); } +static int Part_setStrandRender( BPy_PartSys * self, PyObject * args ) +{ + int number; + + if( !PyInt_Check( args ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( args ); + + if (number){ + self->psys->part->draw |= PART_DRAW_REN_STRAND; + }else{ + self->psys->part->draw &= ~PART_DRAW_REN_STRAND; + } + + return 0; +} + +static PyObject *Part_getStrandRender( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_REN_STRAND )) > 0 ); +} + +static int Part_setStrandRenderAn( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->adapt_angle, + 0, 45, 'i' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + +static PyObject *Part_getStrandRenderAn( BPy_PartSys * self ) +{ + return PyInt_FromLong( ((int)( self->psys->part->adapt_angle )) ); +} + static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args ) { int res = EXPP_setIValueRange( args, &self->psys->part->disp, @@ -2762,6 +2848,16 @@ static PyObject *Part_getRenderStep( BPy_PartSys * self ) return PyInt_FromLong( ((short)( self->psys->part->ren_step )) ); } +static int Part_setDrawAs( BPy_PartSys * self, PyObject * args ) +{ + int res = EXPP_setIValueRange( args, &self->psys->part->draw_as, + 0, 9, 'h' ); + + psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 ); + + return res; +} + static PyObject *Part_getDrawAs( BPy_PartSys * self ) { return PyInt_FromLong( (long)( self->psys->part->draw_as ) ); diff --git a/source/blender/python/api2_2x/Texture.c b/source/blender/python/api2_2x/Texture.c index 455badef4ad..e9e1c898fca 100644 --- a/source/blender/python/api2_2x/Texture.c +++ b/source/blender/python/api2_2x/Texture.c @@ -511,6 +511,8 @@ static int Texture_setNoiseBasis2( BPy_Texture *self, PyObject *args, static PyObject *Texture_getColorband( BPy_Texture * self); int Texture_setColorband( BPy_Texture * self, PyObject * value); +static PyObject *Texture_getUseColorband( BPy_Texture * self); +int Texture_setUseColorband( BPy_Texture * self, PyObject * value); static PyObject *Texture_evaluate( BPy_Texture *self, PyObject *value ); static PyObject *Texture_copy( BPy_Texture *self ); @@ -791,6 +793,10 @@ static PyGetSetDef BPy_Texture_getseters[] = { (getter)Texture_getColorband, (setter)Texture_setColorband, "The colorband for this texture", NULL}, + {"useColorband", + (getter)Texture_getUseColorband, (setter)Texture_setUseColorband, + "Use colorband for this texture", + NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -2525,6 +2531,29 @@ int Texture_setColorband( BPy_Texture * self, PyObject * value) return EXPP_Colorband_fromPyList( &self->texture->coba, value ); } +static PyObject *Texture_getUseColorband( BPy_Texture * self) +{ + return PyInt_FromLong( ((long)( self->texture->flag & TEX_COLORBAND )) > 0 ); +} + +int Texture_setUseColorband( BPy_Texture * self, PyObject * value) +{ + int number; + + if( !PyInt_Check( value ) ) + return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" ); + + number = PyInt_AS_LONG( value ); + + if (number){ + self->texture->flag |= TEX_COLORBAND; + }else{ + self->texture->flag &= ~TEX_COLORBAND; + } + + return 0; +} + static PyObject *Texture_evaluate( BPy_Texture * self, PyObject * value ) { TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; diff --git a/source/blender/python/api2_2x/doc/Lamp.py b/source/blender/python/api2_2x/doc/Lamp.py index 878ca53bb15..88b1c2cf800 100644 --- a/source/blender/python/api2_2x/doc/Lamp.py +++ b/source/blender/python/api2_2x/doc/Lamp.py @@ -46,6 +46,11 @@ Example:: - 'NoDiffuse' - 'NoSpecular' - 'RayShadow' +@type BufferTypes: read-only dictionary +@var BufferTypes: The lamp shadowbuffer types. + - 'Regular' + - 'Irregular' + - 'Halfway' Example:: from Blender import Lamp, Object @@ -101,6 +106,8 @@ class Lamp: @ivar bufferSize: Lamp shadow buffer size. Value is clamped to the range [512,5120]. @type bufferSize: int + @ivar bufferType: Lamp shadowbuffer type. See L{BufferTypes} for values. + @type bufferType: int @ivar clipEnd: Lamp shadow map clip end. Value is clamped to the range [1.0,5000.0]. @type clipEnd: float diff --git a/source/blender/python/api2_2x/doc/Material.py b/source/blender/python/api2_2x/doc/Material.py index 59ff4bc8503..801bb4cb04d 100644 --- a/source/blender/python/api2_2x/doc/Material.py +++ b/source/blender/python/api2_2x/doc/Material.py @@ -408,6 +408,24 @@ class Material: @type textures: a tuple of Blender MTex objects. @ivar textures: the Material's Texture list. Empty texture channels contains None. + @ivar strandTanShad: Uses direction of strands as normal for tangent-shading + @type strandTanShad: int + @ivar strandSurfDiff: Make diffuse shading more similar to shading the surface + @type strandSurfDiff: int + @ivar strandDist: Distance in Blender units over which to blend in the surface normal + @type strandDist: float + @ivar strandBlendUnit: Use actual Blender units for widths instead of pixels + @type strandBlendUnit: int + @ivar strandStart: Start size of strands + @type strandStart: float + @ivar strandEnd: End size of strands + @type strandEnd: float + @ivar strandMin: Minimum size of strands in pixels + @type strandMin: float + @ivar strandShape: Shape of strands, positive value makes it rounder, negative makes it spiky + @type strandShape: float + @ivar strandFade: Transparency along the width of the strand + @type strandFade: float @ivar enableSSS: If True, subsurface scattering will be rendered on this material. @type enableSSS: bool @ivar sssScale: If True, subsurface scattering will be rendered on this material. diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 212ff95ef74..bd1bd2eb0b3 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -205,7 +205,7 @@ def GetSelected (): """ -def Duplicate (mesh=0, surface=0, curve=0, text=0, metaball=0, armature=0, lamp=0, material=0, texture=0, ipo=0): +def Duplicate (mesh=0, surface=0, curve=0, text=0, metaball=0, armature=0, lamp=0, material=0, texture=0, ipo=0, psys=0): """ Duplicate selected objects on visible layers from Blenders current scene, de-selecting the currently visible, selected objects and making a copy where all new objects are selected. @@ -234,6 +234,8 @@ def Duplicate (mesh=0, surface=0, curve=0, text=0, metaball=0, armature=0, lamp= @param texture: When non-zero, texture data used by the object's materials will be duplicated with the objects. @type ipo: bool @param ipo: When non-zero, Ipo data linked to the object will be duplicated with the objects. + @type psys: bool + @param psys: When non-zero, particle systems used by the object or its object data will be duplicated with the objects. I{B{Example:}} @@ -663,6 +665,7 @@ class Object: particle system with that name exists, it is linked to the object. @type name: string @param name: The name of the requested Particle system (optional). + @return: The particle system linked. """ def addVertexGroupsFromArmature(object): diff --git a/source/blender/python/api2_2x/doc/Particle.py b/source/blender/python/api2_2x/doc/Particle.py index 7193e365536..15481c9dd63 100644 --- a/source/blender/python/api2_2x/doc/Particle.py +++ b/source/blender/python/api2_2x/doc/Particle.py @@ -69,6 +69,20 @@ This module provides access to the B{Particle} in Blender. - NONE: No particle angular velocity - SPIN: Spin particle angular velocity - RANDOM: Random particle angular velocity +@type VERTEXGROUPS: readonly dictionary +@var VERTEXGROUPS: Constant dict used for with L{Particle.VERTEXGROUP} + - DENSITY: VertexGroup affect to particles density + - VELOCITY: VertexGroup affect to particles velocity + - LENGHT: VertexGroup affect to particles lenght + - CLUMP: VertexGroup affect to particles clump + - KINK: VertexGroup affect to particles kink + - ROUGH1: VertexGroup affect to particles rough1 + - ROUGH2: VertexGroup affect to particles rough2 + - ROUGHE: VertexGroup affect to particles roughE + - SIZE: VertexGroup affect to particles size + - TANVEL: VertexGroup affect to particles tangent velocity + - TANROT: VertexGroup affect to particles tangent rotation + - EFFECTOR: VertexGroup affect to particles effector @type CHILDTYPE: readonly dictionary @var CHILDTYPE: Constant dict used for with L{Particle.CHILDTYPE} - NONE: set no children @@ -171,6 +185,10 @@ class Particle: @type renderDied: int @ivar renderMaterial: Specify material used for the particles. @type renderMaterial: int + @ivar strandRender: Use the strand primitive to render. + @type strandRender: int + @ivar strandRenderAngle: How many degrees path has to curve to make another render segment. + @type strandRenderAngle: int @ivar displayPercentage: Particle display percentage. @type displayPercentage: int @ivar hairDisplayStep: How many steps paths are drawn with (power of 2) in visu mode. @@ -179,7 +197,7 @@ class Particle: @type hairRenderStep: int @ivar duplicateObject: Get the duplicate object. @type duplicateObject: Blender Object - @ivar drawAs: Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]). + @ivar drawAs: Draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]). @type drawAs: int @ivar physics: Select particle physics type Particle.PHYSICS([ 'BOIDS' | 'KEYED' | 'NEWTONIAN' | 'NONE' ]) @type physics: int @@ -276,6 +294,18 @@ class Particle: @ivar childBranch: Threshold of branching @type childBranch: float """ + def getName(): + """ + Get the name of this Particle System object. + @rtype: string + """ + + def setName(name): + """ + Set the name of this Particle System object. + @type name: string + @param name: The new name. + """ def freeEdit(): """ diff --git a/source/blender/python/api2_2x/doc/Texture.py b/source/blender/python/api2_2x/doc/Texture.py index ad57c303ed2..3431dceb6cd 100644 --- a/source/blender/python/api2_2x/doc/Texture.py +++ b/source/blender/python/api2_2x/doc/Texture.py @@ -393,6 +393,8 @@ class Texture: each color a list of 5 floats [0 - 1], [r,g,b,a,pos]. The colorband can have between 1 and 31 colors. @type colorband: list + @ivar useColorband: Use colorband for this texture. + @type colorband: int @ivar autoRefresh: Refresh image on frame changes enabled. @type autoRefresh: boolean """ diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index b6b6c3c8df9..801b086f980 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -5185,6 +5185,7 @@ void adduplicate(int mode, int dupflag) Object *ob, *obn; ID *id; int a, didit; + ParticleSystem *psys; if(G.scene->id.lib) return; clear_id_newpoins(); @@ -5260,6 +5261,16 @@ void adduplicate(int mode, int dupflag) } } } + if(dupflag & USER_DUP_PSYS) { + for(psys=obn->particlesystem.first; psys; psys=psys->next) { + id= (ID*) psys->part; + if(id) { + ID_NEW_US(psys->part) + else psys->part= psys_copy_settings(psys->part); + id->us--; + } + } + } id= obn->data; didit= 0; -- cgit v1.2.3 From 819a0d2f773a6db9b4dc6b2490f11d087014b1f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Aug 2009 11:34:48 +0000 Subject: EDL importer for the sequencer. supports... - audio and video edits - fades, wipes, speed changes (video only) - importing from multiple reels example import from final cut pro. http://www.graphicall.org/ftp/ideasman42/edl_in_blender_px.png http://www.graphicall.org/ftp/ideasman42/edl_import_ui.png --- release/scripts/import_edl.py | 961 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 961 insertions(+) create mode 100755 release/scripts/import_edl.py diff --git a/release/scripts/import_edl.py b/release/scripts/import_edl.py new file mode 100755 index 00000000000..8c5d041b34c --- /dev/null +++ b/release/scripts/import_edl.py @@ -0,0 +1,961 @@ +#!BPY + +""" +Name: 'Video Sequence (.edl)...' +Blender: 248 +Group: 'Import' +Tooltip: 'Load a CMX formatted EDL into the sequencer' +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Copyright (C) 2009: Campbell Barton, ideasman42@gmail.com +# +# 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, +# -------------------------------------------------------------------------- + +class TimeCode(object): + ''' + Simple timecode class + also supports conversion from other time strings used by EDL + ''' + def __init__(self, data, fps): + self.fps= fps + if type(data)==str: + self.fromString(data) + frame = self.asFrame() + self.fromFrame(frame) + else: + self.fromFrame(data) + + def fromString(self, text): + # hh:mm:ss:ff + # No dropframe support yet + + if text.lower().endswith('mps'): # 5.2mps + return self.fromFrame( int( float(text[:-3]) * self.fps ) ) + elif text.lower().endswith('s'): # 5.2s + return self.fromFrame( int( float(text[:-1]) * self.fps ) ) + elif text.isdigit(): # 1234 + return self.fromFrame( int(text) ) + elif ':' in text: # hh:mm:ss:ff + text= text.replace(';', ':').replace(',', ':').replace('.', ':') + text= text.split(':') + + self.hours= int(text[0]) + self.minutes= int(text[1]) + self.seconds= int(text[2]) + self.frame= int(text[3]) + return self + else: + print 'ERROR: could not convert this into timecode "%s"' % test + return self + + + def fromFrame(self, frame): + + if frame < 0: + frame = -frame; + neg=True + else: + neg=False + + fpm = 60 * self.fps + fph = 60 * fpm + + if frame < fph: + self.hours= 0 + else: + self.hours= int(frame/fph) + frame = frame % fph + + if frame < fpm: + self.minutes= 0 + else: + self.minutes= int(frame/fpm) + frame = frame % fpm + + if frame < self.fps: + self.seconds= 0 + else: + self.seconds= int(frame/self.fps) + frame = frame % self.fps + + self.frame= frame + + if neg: + self.frame = -self.frame + self.seconds = -self.seconds + self.minutes = -self.minutes + self.hours = -self.hours + + return self + + def asFrame(self): + abs_frame= self.frame + abs_frame += self.seconds * self.fps + abs_frame += self.minutes * 60 * self.fps + abs_frame += self.hours * 60 * 60 * self.fps + + return abs_frame + + def asString(self): + self.fromFrame(int(self)) + return '%.2d:%.2d:%.2d:%.2d' % (self.hours, self.minutes, self.seconds, self.frame) + + def __repr__(self): + return self.asString() + + # Numeric stuff, may as well have this + def __neg__(self): return TimeCode(-int(self), self.fps) + def __int__(self): return self.asFrame() + def __sub__(self, other): return TimeCode(int(self)-int(other), self.fps) + def __add__(self, other): return TimeCode(int(self)+int(other), self.fps) + def __mul__(self, other): return TimeCode(int(self)*int(other), self.fps) + def __div__(self, other): return TimeCode(int(self)/int(other), self.fps) + def __abs__(self): return TimeCode(abs(int(self)), self.fps) + def __iadd__(self, other): return self.fromFrame(int(self)+int(other)) + def __imul__(self, other): return self.fromFrame(int(self)*int(other)) + def __idiv__(self, other): return self.fromFrame(int(self)/int(other)) +# end timecode + + +'''Comments +Comments can appear at the beginning of the EDL file (header) or between the edit lines in the EDL. The first block of comments in the file is defined to be the header comments and they are associated with the EDL as a whole. Subsequent comments in the EDL file are associated with the first edit line that appears after them. +Edit Entries + [num] [duration] [srcIn] [srcOut] [recIn] [recOut] + + * : Filename or tag value. Filename can be for an MPEG file, Image file, or Image file template. Image file templates use the same pattern matching as for command line glob, and can be used to specify images to encode into MPEG. i.e. /usr/data/images/image*.jpg + * : 'V' | 'A' | 'VA' | 'B' | 'v' | 'a' | 'va' | 'b' which equals Video, Audio, Video_Audio edits (note B or b can be used in place of VA or va). + * : 'C' | 'D' | 'E' | 'FI' | 'FO' | 'W' | 'c' | 'd' | 'e' | 'fi' | 'fo' | 'w'. which equals Cut, Dissolve, Effect, FadeIn, FadeOut, Wipe. + * [num]: if TransitionType = Wipe, then a wipe number must be given. At the moment only wipe 'W0' and 'W1' are supported. + * [duration]: if the TransitionType is not equal to Cut, then an effect duration must be given. Duration is in frames. + * [srcIn]: Src in. If no srcIn is given, then it defaults to the first frame of the video or the first frame in the image pattern. If srcIn isn't specified, then srcOut, recIn, recOut can't be specified. + * [srcOut]: Src out. If no srcOut is given, then it defaults to the last frame of the video - or last image in the image pattern. if srcOut isn't given, then recIn and recOut can't be specified. + * [recIn]: Rec in. If no recIn is given, then it is calculated based on its position in the EDL and the length of its input. + [recOut]: Rec out. If no recOut is given, then it is calculated based on its position in the EDL and the length of its input. first frame of the video. + +For srcIn, srcOut, recIn, recOut, the values can be specified as either timecode, frame number, seconds, or mps seconds. i.e. +[tcode | fnum | sec | mps], where: + + * tcode : SMPTE timecode in hh:mm:ss:ff + * fnum : frame number (the first decodable frame in the video is taken to be frame 0). + * sec : seconds with 's' suffix (e.g. 5.2s) + * mps : seconds with 'mps' suffix (e.g. 5.2mps). This corresponds to the 'seconds' value displayed by Windows MediaPlayer. + +More notes, +Key + +''' + +enum= 0 +TRANSITION_UNKNOWN= enum +TRANSITION_CUT= enum; enum+=1 +TRANSITION_DISSOLVE= enum; enum+=1 +TRANSITION_EFFECT= enum; enum+=1 +TRANSITION_FADEIN= enum; enum+=1 +TRANSITION_FADEOUT= enum; enum+=1 +TRANSITION_WIPE= enum; enum+=1 +TRANSITION_KEY= enum; enum+=1 + +TRANSITION_DICT={ \ + 'c':TRANSITION_CUT, + 'd':TRANSITION_DISSOLVE, + 'e':TRANSITION_EFFECT, + 'fi':TRANSITION_FADEIN, + 'fo':TRANSITION_FADEOUT, + 'w':TRANSITION_WIPE, + 'k':TRANSITION_KEY, + } + +enum= 0 +EDIT_UNKNOWN= 1<= 1.0: + mov.endStill = int(mov.length * (scale - 1.0)) + else: + speed.speedEffectGlobalSpeed = 1.0/scale + meta.endOffset = mov.length - int(mov.length*scale) + + speed.update() + meta.update() + return meta + +def apply_dissolve_ipo(mov, blendin): + len_disp = float(mov.endDisp - mov.startDisp) + + if len_disp <= 0.0: + print 'Error, strip is zero length' + return + + mov.ipo= ipo= bpy.data.ipos.new("fade", "Sequence") + icu= ipo.addCurve('Fac') + + icu.interpolation= Blender.IpoCurve.InterpTypes.LINEAR + icu.append((0, 0)) + icu.append(((int(blendin)/len_disp) * 100, 1)) + + if mov.type not in (SEQ_HD_SOUND, SEQ_RAM_SOUND): + mov.blendMode = Blender.Scene.Sequence.BlendModes.ALPHAOVER + + +def replace_ext(path, ext): + return path[:path.rfind('.')+1] + ext + +def load_edl(filename, reel_files, reel_offsets): + ''' + reel_files - key:reel <--> reel:filename + ''' + + # For test file + # frame_offset = -769 + + + sce= bpy.data.scenes.active + fps= sce.render.fps + + elist= EditList() + if not elist.parse(filename, fps): + return 'Unable to parse "%s"' % filename + # elist.clean() + + + seq= sce.sequence + + track= 0 + + edits = elist.edits[:] + # edits.sort(key = lambda edit: int(edit.recIn)) + + prev_edit = None + for edit in edits: + print edit + frame_offset = reel_offsets[edit.reel] + + + src_start= int(edit.srcIn) + frame_offset + src_end= int(edit.srcOut) + frame_offset + src_length= src_end-src_start + + rec_start= int(edit.recIn) + 1 + rec_end= int(edit.recOut) + 1 + rec_length= rec_end-rec_start + + # print src_length, rec_length, src_start + + if edit.m2 != None: scale = fps/float(edit.m2.fps) + else: scale = 1.0 + + unedited_start= rec_start - src_start + offset_start = src_start - int(src_start*scale) # works for scaling up AND down + + if edit.transition_type == TRANSITION_CUT and (not elist.testOverlap(edit)): + track = 1 + + strip= None + final_strips = [] + if edit.reel.lower()=='bw': + strip= seq.new((0,0,0), rec_start, track+1) + strip.length= rec_length # for color its simple + final_strips.append(strip) + else: + + path_full = reel_files[edit.reel] + path_fileonly= path_full.split('/')[-1].split('\\')[-1] # os.path.basename(full) + path_dironly= path_full[:-len(path_fileonly)] # os.path.dirname(full) + + if edit.edit_type & EDIT_VIDEO: #and edit.transition_type == TRANSITION_CUT: + + try: + strip= seq.new((path_fileonly, path_dironly, path_full, 'movie'), unedited_start + offset_start, track+1) + except: + return 'Invalid input for movie' + + # Apply scaled rec in bounds + if scale != 1.0: + meta = scale_meta_speed(seq, strip, scale) + final_strip = meta + else: + final_strip = strip + + + final_strip.update() + final_strip.startOffset= rec_start - final_strip.startDisp + final_strip.endOffset= rec_end- final_strip.endDisp + final_strip.update() + final_strip.endOffset += (final_strip.endDisp - rec_end) + final_strip.update() + + + if edit.transition_duration: + if not prev_edit: + print "Error no previous strip" + else: + new_end = rec_start + int(edit.transition_duration) + for other in prev_edit.custom_data: + if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND: + other.endOffset += (other.endDisp - new_end) + other.update() + + # Apply disolve + if edit.transition_type == TRANSITION_DISSOLVE: + apply_dissolve_ipo(final_strip, edit.transition_duration) + + if edit.transition_type == TRANSITION_WIPE: + other_track = track + 2 + for other in prev_edit.custom_data: + if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND: + + strip_wipe= seq.new((SEQ_WIPE, other, final_strip), 1, other_track) + + if edit.wipe_type == WIPE_0: + strip_wipe.wipeEffectAngle = 90 + else: + strip_wipe.wipeEffectAngle = -90 + + other_track += 1 + + + + # strip.endOffset= strip.length - int(edit.srcOut) + #end_offset= (unedited_start+strip.length) - end + # print start, end, end_offset + #strip.endOffset = end_offset + + # break + # print strip + + final_strips.append(final_strip) + + + if edit.edit_type & (EDIT_AUDIO | EDIT_AUDIO_STEREO | EDIT_VIDEO_AUDIO): + + if scale == 1.0: # TODO - scaled audio + + try: + strip= seq.new((path_fileonly, path_dironly, path_full, 'audio_hd'), unedited_start + offset_start, track+6) + except: + + # See if there is a wave file there + path_full_wav = replace_ext(path_full, 'wav') + path_fileonly_wav = replace_ext(path_fileonly, 'wav') + + #try: + strip= seq.new((path_fileonly_wav, path_dironly, path_full_wav, 'audio_hd'), unedited_start + offset_start, track+6) + #except: + # return 'Invalid input for audio' + + final_strip = strip + + # Copied from above + final_strip.update() + final_strip.startOffset= rec_start - final_strip.startDisp + final_strip.endOffset= rec_end- final_strip.endDisp + final_strip.update() + final_strip.endOffset += (final_strip.endDisp - rec_end) + final_strip.update() + + if edit.transition_type == TRANSITION_DISSOLVE: + apply_dissolve_ipo(final_strip, edit.transition_duration) + + final_strips.append(final_strip) + + # strip= seq.new((0.6, 0.6, 0.6), start, track+1) + + if final_strips: + for strip in final_strips: + # strip.length= length + final_strip.name = edit.asName() + edit.custom_data[:]= final_strips + # track = not track + prev_edit = edit + track += 1 + + #break + + + def recursive_update(s): + s.update(1) + for s_kid in s: + recursive_update(s_kid) + + + for s in seq: + recursive_update(s) + + return '' + + + +#load_edl('/fe/edl/EP30CMXtrk1.edl') # /tmp/test.edl +#load_edl('/fe/edl/EP30CMXtrk2.edl') # /tmp/test.edl +#load_edl('/fe/edl/EP30CMXtrk3.edl') # /tmp/test.edl +#load_edl('/root/vid/rush/blender_edl.edl', ['/root/vid/rush/rushes3.avi',]) # /tmp/test.edl + + + + +# ---------------------- Blender UI part +from Blender import Draw, Window +import BPyWindow + +if 0: + DEFAULT_FILE_EDL = '/root/vid/rush/blender_edl.edl' + DEFAULT_FILE_MEDIA = '/root/vid/rush/rushes3_wav.avi' + DEFAULT_FRAME_OFFSET = -769 +else: + DEFAULT_FILE_EDL = '' + DEFAULT_FILE_MEDIA = '' + DEFAULT_FRAME_OFFSET = 0 + +B_EVENT_IMPORT = 1 +B_EVENT_RELOAD = 2 +B_EVENT_FILESEL_EDL = 3 +B_EVENT_NOP = 4 + +B_EVENT_FILESEL = 100 # or greater + +class ReelItemUI(object): + __slots__ = 'filename_but', 'offset_but', 'ui_text' + def __init__(self): + self.filename_but = Draw.Create(DEFAULT_FILE_MEDIA) + self.offset_but = Draw.Create(DEFAULT_FRAME_OFFSET) + self.ui_text = '' + + + +REEL_UI = {} # reel:ui_string + + +#REEL_FILENAMES = {} # reel:filename +#REEL_OFFSETS = {} # reel:filename + +PREF = {} + +PREF['filename'] = Draw.Create(DEFAULT_FILE_EDL) +PREF['reel_act'] = '' + +def edl_reload(): + Window.WaitCursor(1) + filename = PREF['filename'].val + sce= bpy.data.scenes.active + fps= sce.render.fps + + elist= EditList() + + if filename: + if not elist.parse(filename, fps): + Draw.PupMenu('Error%t|Could not open the file "' + filename + '"') + reels = elist.getReels() + else: + reels = {} + + REEL_UI.clear() + for reel_key, edits in reels.iteritems(): + + if reel_key == 'bw': + continue + + flag = 0 + for edit in edits: + flag |= edit.edit_type + + reel_item = REEL_UI[reel_key] = ReelItemUI() + + reel_item.ui_text = '%s (%s): ' % (reel_key, editFlagsToText(flag)) + + Window.WaitCursor(0) + +def edl_set_path(filename): + PREF['filename'].val = filename + edl_reload() + Draw.Redraw() + +def edl_set_path_reel(filename): + REEL_UI[PREF['reel_act']].filename_but.val = filename + Draw.Redraw() + +def edl_reel_keys(): + reel_keys = REEL_UI.keys() + + if 'bw' in reel_keys: + reel_keys.remove('bw') + + reel_keys.sort() + return reel_keys + +def edl_draw(): + + MARGIN = 4 + rect = BPyWindow.spaceRect() + but_width = int((rect[2]-MARGIN*2)/4.0) # 72 + # Clamp + if but_width>100: but_width = 100 + but_height = 17 + + x=MARGIN + y=rect[3]-but_height-MARGIN + xtmp = x + + + + # ---------- ---------- ---------- ---------- + Blender.Draw.BeginAlign() + PREF['filename'] = Draw.String('edl path: ', B_EVENT_RELOAD, xtmp, y, (but_width*3)-20, but_height, PREF['filename'].val, 256, 'EDL Path'); xtmp += (but_width*3)-20; + Draw.PushButton('..', B_EVENT_FILESEL_EDL, xtmp, y, 20, but_height, 'Select an EDL file'); xtmp += 20; + Blender.Draw.EndAlign() + + Draw.PushButton('Reload', B_EVENT_RELOAD, xtmp + MARGIN, y, but_width - MARGIN, but_height, 'Read the ID Property settings from the active curve object'); xtmp += but_width; + y-=but_height + MARGIN + xtmp = x + # ---------- ---------- ---------- ---------- + + reel_keys = edl_reel_keys() + + + + if reel_keys: text = 'Reel file list...' + elif PREF['filename'].val == '': text = 'No EDL loaded.' + else: text = 'No reels found!' + + Draw.Label(text, xtmp + MARGIN, y, but_width*4, but_height); xtmp += but_width*4; + + y-=but_height + MARGIN + xtmp = x + + # ---------- ---------- ---------- ---------- + + + for i, reel_key in enumerate(reel_keys): + reel_item = REEL_UI[reel_key] + + Blender.Draw.BeginAlign() + REEL_UI[reel_key].filename_but = Draw.String(reel_item.ui_text, B_EVENT_NOP, xtmp, y, (but_width*3)-20, but_height, REEL_UI[reel_key].filename_but.val, 256, 'Select the reel path'); xtmp += (but_width*3)-20; + Draw.PushButton('..', B_EVENT_FILESEL + i, xtmp, y, 20, but_height, 'Media path to use for this reel'); xtmp += 20; + Blender.Draw.EndAlign() + + reel_item.offset_but= Draw.Number('ofs:', B_EVENT_NOP, xtmp + MARGIN, y, but_width - MARGIN, but_height, reel_item.offset_but.val, -100000, 100000, 'Start offset in frames when applying timecode'); xtmp += but_width - MARGIN; + + y-=but_height + MARGIN + xtmp = x + + # ---------- ---------- ---------- ---------- + + Draw.PushButton('Import CMX-EDL Sequencer Strips', B_EVENT_IMPORT, xtmp + MARGIN, MARGIN, but_width*4 - MARGIN, but_height, 'Load the EDL file into the sequencer'); xtmp += but_width*4; + y-=but_height + MARGIN + xtmp = x + + +def edl_event(evt, val): + pass + +def edl_bevent(evt): + + if evt == B_EVENT_NOP: + pass + elif evt == B_EVENT_IMPORT: + ''' + Load the file into blender with UI settings + ''' + filename = PREF['filename'].val + + reel_files = {} + reel_offsets = {} + + for reel_key, reel_item in REEL_UI.iteritems(): + reel_files[reel_key] = reel_item.filename_but.val + reel_offsets[reel_key] = reel_item.offset_but.val + + error = load_edl(filename, reel_files, reel_offsets) + if error != '': + Draw.PupMenu('Error%t|' + error) + else: + Window.RedrawAll() + + elif evt == B_EVENT_RELOAD: + edl_reload() + Draw.Redraw() + + elif evt == B_EVENT_FILESEL_EDL: + filename = PREF['filename'].val + if not filename: filename = Blender.sys.join(Blender.sys.expandpath('//'), '*.edl') + + Window.FileSelector(edl_set_path, 'Select EDL', filename) + + elif evt >= B_EVENT_FILESEL: + reel_keys = edl_reel_keys() + reel_key = reel_keys[evt - B_EVENT_FILESEL] + + filename = REEL_UI[reel_key].filename_but.val + if not filename: filename = Blender.sys.expandpath('//') + + PREF['reel_act'] = reel_key # so file set path knows which one to set + Window.FileSelector(edl_set_path_reel, 'Reel Media', filename) + + + +if __name__ == '__main__': + Draw.Register(edl_draw, edl_event, edl_bevent) + edl_reload() + -- cgit v1.2.3 From 9dff2ad3d043de606dbc744cd13c11e1ef76e00b Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Mon, 24 Aug 2009 23:09:35 +0000 Subject: SVN maintenance. --- release/scripts/import_edl.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 release/scripts/import_edl.py diff --git a/release/scripts/import_edl.py b/release/scripts/import_edl.py old mode 100755 new mode 100644 -- cgit v1.2.3 From 33e2d118bcc8d8301144cd90e7896175ae14d141 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 25 Aug 2009 12:43:25 +0000 Subject: removing GameLogic.EvalExpression(), unlikely anyone will miss it, was only accessible in 2.49, invalid expressions would crash, valid ones leak memory. --- source/gameengine/Ketsji/KX_PythonInit.cpp | 28 ---------------------------- source/gameengine/PyDoc/GameLogic.py | 8 -------- 2 files changed, 36 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index fcada7bfce4..91515587e8d 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -498,33 +498,6 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) Py_RETURN_NONE; } - -static PyObject *gEvalExpression(PyObject*, PyObject* value) -{ - char* txt= PyString_AsString(value); - - if (txt==NULL) { - PyErr_SetString(PyExc_TypeError, "Expression.calc(text): expects a single string argument"); - return NULL; - } - - CParser parser; - CExpression* expr = parser.ProcessText(txt); - CValue* val = expr->Calculate(); - expr->Release(); - - if (val) { - PyObject* pyobj = val->ConvertValueToPython(); - if (pyobj) - return pyobj; - else - return val->GetProxy(); - } - - Py_RETURN_NONE; -} - - static struct PyMethodDef game_methods[] = { {"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (PY_METHODCHAR)gPyExpandPath_doc}, {"sendMessage", (PyCFunction)gPySendMessage, METH_VARARGS, (PY_METHODCHAR)gPySendMessage_doc}, @@ -553,7 +526,6 @@ static struct PyMethodDef game_methods[] = { {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (PY_METHODCHAR)"Gets the estimated average frame rate"}, {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (PY_METHODCHAR)"Gets a list of blend files in the same directory as the current blend file"}, {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (PY_METHODCHAR)"Prints GL Extension Info"}, - {"EvalExpression", (PyCFunction)gEvalExpression, METH_O, (PY_METHODCHAR)"Evaluate a string as a game logic expression"}, {NULL, (PyCFunction) NULL, 0, NULL } }; diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 46f00fa7ea6..5d9b17316be 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -448,14 +448,6 @@ def setPhysicsTicRate(ticrate): @type ticrate: float """ -def EvalExpression(text): - """ - Evaluate the string as an expression, similar to the expression controller logic brick. - @param text: The expression to evaluate. - @type text: string - @return: The result of the expression. The type depends on the expression. - """ - #{ Utility functions def getAverageFrameRate(): """ -- cgit v1.2.3 From aec7f2f2c47d02b08383a4f30c0dd0067830b8c8 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 25 Aug 2009 20:26:50 +0000 Subject: *Changed RayObject_ calls to RE_rayobject to keep consistency on calls *Moved part of counters code to a separated file (rayobject_raycounter.c) --- source/blender/render/intern/include/rayobject.h | 37 +---- source/blender/render/intern/raytrace/bvh.h | 2 +- .../render/intern/raytrace/rayobject_bih.cpp | 12 +- .../render/intern/raytrace/rayobject_bvh.cpp | 10 +- .../render/intern/raytrace/rayobject_vbvh.cpp | 16 +-- source/blender/render/intern/raytrace/reorganize.h | 28 ++-- source/blender/render/intern/source/rayobject.c | 155 +++------------------ .../render/intern/source/rayobject_blibvh.c | 34 ++--- .../render/intern/source/rayobject_instance.c | 32 ++--- .../render/intern/source/rayobject_octree.c | 57 +++----- .../render/intern/source/rayobject_raycounter.c | 77 ++++++++++ source/blender/render/intern/source/rayshade.c | 4 +- 12 files changed, 196 insertions(+), 268 deletions(-) create mode 100644 source/blender/render/intern/source/rayobject_raycounter.c diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index b058f260052..36b0d2692c0 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -77,39 +77,16 @@ extern "C" { described on RE_raytrace.h */ -/* defines where coordinates of rayface primitives are stored */ -#define RE_RAYFACE_COORDS_LOCAL - -//(ATM this won't work good with all types of instances) -//#define RE_RAYFACE_COORDS_POINTER -//#define RE_RAYFACE_COORDS_VLAKREN - typedef struct RayFace { -#ifdef RE_RAYFACE_COORDS_LOCAL float v1[4], v2[4], v3[4], v4[3]; int quad; void *ob; void *face; -#elif defined(RE_RAYFACE_COORDS_POINTER) - float *v1, *v2, *v3, *v4; - void *ob; - void *face; -#elif defined(RE_RAYFACE_COORDS_VLAKREN) - void *ob; - void *face; -#endif } RayFace; -#ifdef RE_RAYFACE_COORDS_LOCAL -# define RE_rayface_isQuad(a) ((a)->quad) -#elif defined(RE_RAYFACE_COORDS_POINTER) -# define RE_rayface_isQuad(a) ((a)->v4) -#elif defined(RE_RAYFACE_COORDS_VLAKREN) -# define RE_rayface_isQuad(a) ((((VlakRen*)((a)->face))->v4) != NULL) -#endif - +#define RE_rayface_isQuad(a) ((a)->quad) struct RayObject { @@ -137,13 +114,13 @@ typedef struct RayObjectAPI } RayObjectAPI; -#define RayObject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) -#define RayObject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) -#define RayObject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) +#define RE_rayobject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) +#define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) +#define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) -#define RayObject_isAligned(o) ((((intptr_t)o)&3) == 0) -#define RayObject_isRayFace(o) ((((intptr_t)o)&3) == 1) -#define RayObject_isRayAPI(o) ((((intptr_t)o)&3) == 2) +#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) +#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) +#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) /* * Loads a VlakRen on a RayFace diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 8538d9201e0..55bed6f0662 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -59,7 +59,7 @@ template static void bvh_add(Tree *obj, RayObject *ob) template inline bool is_leaf(Node *node) { - return !RayObject_isAligned(node); + return !RE_rayobject_isAligned(node); } template static void bvh_done(Tree *obj); diff --git a/source/blender/render/intern/raytrace/rayobject_bih.cpp b/source/blender/render/intern/raytrace/rayobject_bih.cpp index 102a347b470..efbf70616b7 100644 --- a/source/blender/render/intern/raytrace/rayobject_bih.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bih.cpp @@ -78,7 +78,7 @@ struct BIHTree RayObject *RE_rayobject_bih_create(int size) { BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bih_api; obj->root = NULL; @@ -86,7 +86,7 @@ RayObject *RE_rayobject_bih_create(int size) obj->node_alloc = obj->node_next = NULL; obj->builder = rtbuild_create( size ); - return RayObject_unalignRayAPI((RayObject*) obj); + return RE_rayobject_unalignRayAPI((RayObject*) obj); } static void bih_free(BIHTree *obj) @@ -128,7 +128,7 @@ static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float if(t1 <= t2) { - if(RayObject_isAligned(node->child[i])) + if(RE_rayobject_isAligned(node->child[i])) { if(node->child[i] == 0) break; @@ -151,7 +151,7 @@ static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float static int bih_intersect(BIHTree *obj, Isect *isec) { - if(RayObject_isAligned(obj->root)) + if(RE_rayobject_isAligned(obj->root)) return dfs_raycast(obj->root, isec, 0, isec->labda); else return RE_rayobject_intersect( (RayObject*)obj->root, isec); @@ -169,7 +169,7 @@ static void bih_add(BIHTree *obj, RayObject *ob) static BIHNode *bih_new_node(BIHTree *tree, int nid) { BIHNode *node = tree->node_alloc + nid - 1; - assert(RayObject_isAligned(node)); + assert(RE_rayobject_isAligned(node)); if(node+1 > tree->node_next) tree->node_next = node+1; @@ -187,7 +187,7 @@ static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float if(rtbuild_size(builder) == 1) { RayObject *child = rtbuild_get_primitive( builder, 0 ); - assert(!RayObject_isAligned(child)); + assert(!RE_rayobject_isAligned(child)); INIT_MINMAX(bb, bb+3); RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3); diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp index 48c1ac07cd4..bf54f889ebf 100644 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -117,7 +117,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float { RayObject *child = rtbuild_get_primitive( builder, 0 ); - if(RayObject_isRayFace(child)) + if(RE_rayobject_isRayFace(child)) { int i; BVHNode *parent = bvh_new_node(tree, nid); @@ -138,7 +138,7 @@ static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float } else { - assert(!RayObject_isAligned(child)); + assert(!RE_rayobject_isAligned(child)); //Its a sub-raytrace structure, assume it has it own raycast //methods and adding a Bounding Box arround is unnecessary @@ -200,7 +200,7 @@ void bvh_done(BVHTree *obj) template<> int bvh_intersect(BVHTree *obj, Isect* isec) { - if(RayObject_isAligned(obj->root)) + if(RE_rayobject_isAligned(obj->root)) return bvh_node_stack_raycast(obj->root, isec); else return RE_rayobject_intersect( (RayObject*) obj->root, isec ); @@ -222,7 +222,7 @@ static RayObjectAPI bvh_api = RayObject *RE_rayobject_bvh_create(int size) { BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; obj->root = NULL; @@ -230,5 +230,5 @@ RayObject *RE_rayobject_bvh_create(int size) obj->node_arena = NULL; obj->builder = rtbuild_create( size ); - return RayObject_unalignRayAPI((RayObject*) obj); + return RE_rayobject_unalignRayAPI((RayObject*) obj); } diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index b703e57fdd8..6ec8fab15e4 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -181,7 +181,7 @@ static VBVHNode *bvh_new_node(VBVHTree *tree) #ifdef DYNAMIC_ALLOC_BB node->bb = (float*)BLI_memarena_alloc(tree->node_arena, 6*sizeof(float)); #endif - assert(RayObject_isAligned(node)); + assert(RE_rayobject_isAligned(node)); return node; } @@ -319,7 +319,7 @@ int intersect(VBVHTree *obj, Isect* isec) for(int i=0; isize; i++) { VBVHNode *node = (VBVHNode*)lcts->stack[i]; - if(RayObject_isAligned(node)) + if(RE_rayobject_isAligned(node)) hit |= bvh_node_stack_raycast(node, isec); else hit |= RE_rayobject_intersect( (RayObject*)node, isec ); @@ -333,7 +333,7 @@ int intersect(VBVHTree *obj, Isect* isec) else */ { - if(RayObject_isAligned(obj->root)) + if(RE_rayobject_isAligned(obj->root)) return bvh_node_stack_raycast( obj->root, isec); else return RE_rayobject_intersect( (RayObject*) obj->root, isec ); @@ -346,7 +346,7 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject template void bvh_dfs_make_hint_push_siblings(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) { - if(!RayObject_isAligned(node)) + if(!RE_rayobject_isAligned(node)) hint->stack[hint->size++] = (RayObject*)node; else { @@ -459,7 +459,7 @@ static RayObjectAPI* get_api(int maxstacksize) RayObject *RE_rayobject_vbvh_create(int size) { VBVHTree *obj= (VBVHTree*)MEM_callocN(sizeof(VBVHTree), "VBVHTree"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = get_api(DFS_STACK_SIZE); obj->root = NULL; @@ -467,7 +467,7 @@ RayObject *RE_rayobject_vbvh_create(int size) obj->node_arena = NULL; obj->builder = rtbuild_create( size ); - return RayObject_unalignRayAPI((RayObject*) obj); + return RE_rayobject_unalignRayAPI((RayObject*) obj); } @@ -482,7 +482,7 @@ void bvh_dfs_make_hint(VBVHNode *node, LCTSHint *hint, int reserve_space, HintOb RayObject *RE_rayobject_svbvh_create(int size) { SVBVHTree *obj= (SVBVHTree*)MEM_callocN(sizeof(SVBVHTree), "SVBVHTree"); - assert( RayObject_isAligned(obj) ); // RayObject API assumes real data to be 4-byte aligned + assert( RE_rayobject_isAligned(obj) ); // RayObject API assumes real data to be 4-byte aligned obj->rayobj.api = get_api(DFS_STACK_SIZE); obj->root = NULL; @@ -490,6 +490,6 @@ RayObject *RE_rayobject_svbvh_create(int size) obj->node_arena = NULL; obj->builder = rtbuild_create( size ); - return RayObject_unalignRayAPI((RayObject*) obj); + return RE_rayobject_unalignRayAPI((RayObject*) obj); } */ \ No newline at end of file diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h index b77a51bbf65..2494f102003 100644 --- a/source/blender/render/intern/raytrace/reorganize.h +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -47,7 +47,7 @@ void reorganize_find_fittest_parent(Node *tree, Node *node, std::pairchild) ) + if(node_fits_inside(node, parent) && RE_rayobject_isAligned(parent->child) ) { float pcost = bb_area(parent->bb, parent->bb+3); cost = std::min( cost, std::make_pair(pcost,parent) ); @@ -69,11 +69,11 @@ void reorganize(Node *root) Node * node = q.front(); q.pop(); - if( RayObject_isAligned(node->child) ) + if( RE_rayobject_isAligned(node->child) ) { for(Node **prev = &node->child; *prev; ) { - assert( RayObject_isAligned(*prev) ); + assert( RE_rayobject_isAligned(*prev) ); q.push(*prev); std::pair best(FLT_MAX, root); @@ -112,7 +112,7 @@ void reorganize(Node *root) template void remove_useless(Node *node, Node **new_node) { - if( RayObject_isAligned(node->child) ) + if( RE_rayobject_isAligned(node->child) ) { for(Node **prev = &node->child; *prev; ) @@ -130,7 +130,7 @@ void remove_useless(Node *node, Node **new_node) } if(node->child) { - if(RayObject_isAligned(node->child) && node->child->sibling == 0) + if(RE_rayobject_isAligned(node->child) && node->child->sibling == 0) *new_node = node->child; } else if(node->child == 0) @@ -148,7 +148,7 @@ void pushup(Node *parent) float p_area = bb_area(parent->bb, parent->bb+3); Node **prev = &parent->child; - for(Node *child = parent->child; RayObject_isAligned(child) && child; ) + for(Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) { float c_area = bb_area(child->bb, child->bb+3) ; int nchilds = count_childs(child); @@ -173,7 +173,7 @@ void pushup(Node *parent) } } - for(Node *child = parent->child; RayObject_isAligned(child) && child; child = child->sibling) + for(Node *child = parent->child; RE_rayobject_isAligned(child) && child; child = child->sibling) pushup(child); } @@ -188,10 +188,10 @@ void pushup_simd(Node *parent) int n = count_childs(parent); Node **prev = &parent->child; - for(Node *child = parent->child; RayObject_isAligned(child) && child; ) + for(Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) { int cn = count_childs(child); - if(cn-1 <= (SSize - (n%SSize) ) % SSize && RayObject_isAligned(child->child) ) + if(cn-1 <= (SSize - (n%SSize) ) % SSize && RE_rayobject_isAligned(child->child) ) { n += (cn - 1); append_sibling(child, child->child); @@ -206,7 +206,7 @@ void pushup_simd(Node *parent) } } - for(Node *child = parent->child; RayObject_isAligned(child) && child; child = child->sibling) + for(Node *child = parent->child; RE_rayobject_isAligned(child) && child; child = child->sibling) pushup_simd(child); } @@ -221,15 +221,15 @@ void pushdown(Node *parent) Node **s_child = &parent->child; Node * child = parent->child; - while(child && RayObject_isAligned(child)) + while(child && RE_rayobject_isAligned(child)) { Node *next = child->sibling; Node **next_s_child = &child->sibling; //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); - for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) - if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3) && RayObject_isAligned(i->child)) + for(Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling) + if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3) && RE_rayobject_isAligned(i->child)) { // todo optimize (should the one with the smallest area?) // float ia = bb_area(i->bb, i->bb+3) @@ -246,7 +246,7 @@ void pushdown(Node *parent) s_child = next_s_child; } - for(Node *i = parent->child; RayObject_isAligned(i) && i; i = i->sibling) + for(Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling) pushdown( i ); } diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index daa6b8d95de..996be35090e 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -27,7 +27,6 @@ * ***** END GPL LICENSE BLOCK ***** */ #include -#include #include "BKE_utildefines.h" #include "BLI_arithb.h" @@ -42,33 +41,6 @@ * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] */ -/* -float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb) -{ - const float *bb = _bb; - float dist; - - float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; - float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; - float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; - float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; - float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; - float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; - - RE_RC_COUNT(isec->raycounter->bb.test); - - if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return FLT_MAX; - if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return FLT_MAX; - if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return FLT_MAX; - - RE_RC_COUNT(isec->raycounter->bb.hit); - - dist = t1x; - if (t1y > dist) dist = t1y; - if (t1z > dist) dist = t1z; - return dist; -} -*/ int RE_rayobject_bb_intersect_test(const Isect *isec, const float *_bb) { const float *bb = _bb; @@ -185,23 +157,7 @@ static int intersect_rayface(RayFace *face, Isect *is) RE_RC_COUNT(is->raycounter->faces.test); -#ifdef RE_RAYFACE_COORDS_VLAKREN - { - VlakRen *vlr = (VlakRen*)face->face; - - VECCOPY(co1, vlr->v1->co); - VECCOPY(co2, vlr->v2->co); - if(vlr->v4) - { - VECCOPY(co3, vlr->v4->co); - VECCOPY(co4, vlr->v3->co); - } - else - { - VECCOPY(co3, vlr->v3->co); - } - } -#else + //Load coords VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); if(RE_rayface_isQuad(face)) @@ -213,7 +169,6 @@ static int intersect_rayface(RayFace *face, Isect *is) { VECCOPY(co3, face->v3); } -#endif t00= co3[0]-co1[0]; t01= co3[1]-co1[1]; @@ -312,13 +267,6 @@ static int intersect_rayface(RayFace *face, Isect *is) } } } -#if 0 - else if(labda < ISECT_EPSILON) - { - /* too close to origin */ - return 0; - } -#endif RE_RC_COUNT(is->raycounter->faces.hit); @@ -329,7 +277,7 @@ static int intersect_rayface(RayFace *face, Isect *is) is->hit.ob = face->ob; is->hit.face = face->face; #ifdef RT_USE_LAST_HIT - is->last_hit = (RayObject*) RayObject_unalignRayFace(face); + is->last_hit = (RayObject*) RE_rayobject_unalignRayFace(face); #endif return 1; } @@ -339,7 +287,6 @@ static int intersect_rayface(RayFace *face, Isect *is) void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr) { -#ifdef RE_RAYFACE_COORDS_LOCAL VECCOPY(face->v1, vlr->v1->co); VECCOPY(face->v2, vlr->v2->co); VECCOPY(face->v3, vlr->v3->co); @@ -352,13 +299,7 @@ void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr) { face->quad = 0; } -#elif defined(RE_RAYFACE_COORDS_POINTER) - face->v1 = vlr->v1->co; - face->v2 = vlr->v2->co; - face->v3 = vlr->v3->co; - face->v4 = vlr->v4 ? vlr->v4->co : NULL; -#elif defined(RE_RAYFACE_COORDS_VLAKREN) -#endif + face->ob = obi; face->face = vlr; } @@ -405,9 +346,7 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) if(RE_rayobject_intersect(r, isec)) { -#ifdef RE_RAYCOUNTER RE_RC_COUNT(isec->raycounter->raycast.hit); -#endif #ifdef RT_USE_HINT isec->hint = isec->hit_hint; @@ -419,13 +358,13 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) int RE_rayobject_intersect(RayObject *r, Isect *i) { - if(RayObject_isRayFace(r)) + if(RE_rayobject_isRayFace(r)) { - return intersect_rayface( (RayFace*) RayObject_align(r), i); + return intersect_rayface( (RayFace*) RE_rayobject_align(r), i); } - else if(RayObject_isRayAPI(r)) + else if(RE_rayobject_isRayAPI(r)) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); return r->api->raycast( r, i ); } else assert(0); @@ -433,44 +372,36 @@ int RE_rayobject_intersect(RayObject *r, Isect *i) void RE_rayobject_add(RayObject *r, RayObject *o) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); return r->api->add( r, o ); } void RE_rayobject_done(RayObject *r) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); r->api->done( r ); } void RE_rayobject_free(RayObject *r) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); r->api->free( r ); } void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) { - if(RayObject_isRayFace(r)) + if(RE_rayobject_isRayFace(r)) { - RayFace *face = (RayFace*) RayObject_align(r); + RayFace *face = (RayFace*) RE_rayobject_align(r); -#ifdef RE_RAYFACE_COORDS_VLAKREN - VlakRen *vlr = (VlakRen*)face->face; - DO_MINMAX( vlr->v1->co, min, max ); - DO_MINMAX( vlr->v2->co, min, max ); - DO_MINMAX( vlr->v3->co, min, max ); - if(RE_rayface_isQuad(face)) DO_MINMAX( vlr->v4->co, min, max ); -#else DO_MINMAX( face->v1, min, max ); DO_MINMAX( face->v2, min, max ); DO_MINMAX( face->v3, min, max ); if(RE_rayface_isQuad(face)) DO_MINMAX( face->v4, min, max ); -#endif } - else if(RayObject_isRayAPI(r)) + else if(RE_rayobject_isRayAPI(r)) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); r->api->bb( r, min, max ); } else assert(0); @@ -478,13 +409,13 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) float RE_rayobject_cost(RayObject *r) { - if(RayObject_isRayFace(r)) + if(RE_rayobject_isRayFace(r)) { return 1.0; } - else if(RayObject_isRayAPI(r)) + else if(RE_rayobject_isRayAPI(r)) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); return r->api->cost( r ); } else assert(0); @@ -492,61 +423,15 @@ float RE_rayobject_cost(RayObject *r) void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max) { - if(RayObject_isRayFace(r)) + if(RE_rayobject_isRayFace(r)) { return; } - else if(RayObject_isRayAPI(r)) + else if(RE_rayobject_isRayAPI(r)) { - r = RayObject_align( r ); + r = RE_rayobject_align( r ); return r->api->hint_bb( r, hint, min, max ); } else assert(0); } -#ifdef RE_RAYCOUNTER -void RE_RC_INFO(RayCounter *info) -{ - printf("----------- Raycast counter --------\n"); - printf("Rays total: %llu\n", info->raycast.test ); - printf("Rays hit: %llu\n", info->raycast.hit ); - printf("\n"); - printf("BB tests: %llu\n", info->bb.test ); - printf("BB hits: %llu\n", info->bb.hit ); - printf("\n"); - printf("Primitives tests: %llu\n", info->faces.test ); - printf("Primitives hits: %llu\n", info->faces.hit ); - printf("------------------------------------\n"); - printf("Shadow last-hit tests per ray: %f\n", info->rayshadow_last_hit.test / ((float)info->raycast.test) ); - printf("Shadow last-hit hits per ray: %f\n", info->rayshadow_last_hit.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("Hint tests per ray: %f\n", info->raytrace_hint.test / ((float)info->raycast.test) ); - printf("Hint hits per ray: %f\n", info->raytrace_hint.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) ); - printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) ); - printf("\n"); - printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); - printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); - printf("------------------------------------\n"); -} - -void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) -{ - dest->faces.test += tmp->faces.test; - dest->faces.hit += tmp->faces.hit; - - dest->bb.test += tmp->bb.test; - dest->bb.hit += tmp->bb.hit; - - dest->raycast.test += tmp->raycast.test; - dest->raycast.hit += tmp->raycast.hit; - - dest->rayshadow_last_hit.test += tmp->rayshadow_last_hit.test; - dest->rayshadow_last_hit.hit += tmp->rayshadow_last_hit.hit; - - dest->raytrace_hint.test += tmp->raytrace_hint.test; - dest->raytrace_hint.hit += tmp->raytrace_hint.hit; -} - -#endif \ No newline at end of file diff --git a/source/blender/render/intern/source/rayobject_blibvh.c b/source/blender/render/intern/source/rayobject_blibvh.c index 9b872d8f249..6e789862207 100644 --- a/source/blender/render/intern/source/rayobject_blibvh.c +++ b/source/blender/render/intern/source/rayobject_blibvh.c @@ -36,19 +36,19 @@ #include "render_types.h" #include "rayobject.h" -static int RayObject_blibvh_intersect(RayObject *o, Isect *isec); -static void RayObject_blibvh_add(RayObject *o, RayObject *ob); -static void RayObject_blibvh_done(RayObject *o); -static void RayObject_blibvh_free(RayObject *o); -static void RayObject_blibvh_bb(RayObject *o, float *min, float *max); +static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec); +static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob); +static void RE_rayobject_blibvh_done(RayObject *o); +static void RE_rayobject_blibvh_free(RayObject *o); +static void RE_rayobject_blibvh_bb(RayObject *o, float *min, float *max); static RayObjectAPI bvh_api = { - RayObject_blibvh_intersect, - RayObject_blibvh_add, - RayObject_blibvh_done, - RayObject_blibvh_free, - RayObject_blibvh_bb + RE_rayobject_blibvh_intersect, + RE_rayobject_blibvh_add, + RE_rayobject_blibvh_done, + RE_rayobject_blibvh_free, + RE_rayobject_blibvh_bb }; typedef struct BVHObject @@ -63,13 +63,13 @@ typedef struct BVHObject RayObject *RE_rayobject_blibvh_create(int size) { BVHObject *obj= (BVHObject*)MEM_callocN(sizeof(BVHObject), "BVHObject"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &bvh_api; obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6); INIT_MINMAX(obj->bb[0], obj->bb[1]); - return RayObject_unalignRayAPI((RayObject*) obj); + return RE_rayobject_unalignRayAPI((RayObject*) obj); } static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) @@ -88,7 +88,7 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr } } -static int RayObject_blibvh_intersect(RayObject *o, Isect *isec) +static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec) { BVHObject *obj = (BVHObject*)o; BVHTreeRayHit hit; @@ -103,7 +103,7 @@ static int RayObject_blibvh_intersect(RayObject *o, Isect *isec) return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, isec); } -static void RayObject_blibvh_add(RayObject *o, RayObject *ob) +static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob) { BVHObject *obj = (BVHObject*)o; float min_max[6]; @@ -116,13 +116,13 @@ static void RayObject_blibvh_add(RayObject *o, RayObject *ob) BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); } -static void RayObject_blibvh_done(RayObject *o) +static void RE_rayobject_blibvh_done(RayObject *o) { BVHObject *obj = (BVHObject*)o; BLI_bvhtree_balance(obj->bvh); } -static void RayObject_blibvh_free(RayObject *o) +static void RE_rayobject_blibvh_free(RayObject *o) { BVHObject *obj = (BVHObject*)o; @@ -132,7 +132,7 @@ static void RayObject_blibvh_free(RayObject *o) MEM_freeN(obj); } -static void RayObject_blibvh_bb(RayObject *o, float *min, float *max) +static void RE_rayobject_blibvh_bb(RayObject *o, float *min, float *max) { BVHObject *obj = (BVHObject*)o; DO_MIN( obj->bb[0], min ); diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c index 14f333a7f86..9329d110870 100644 --- a/source/blender/render/intern/source/rayobject_instance.c +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -36,19 +36,19 @@ #define RE_COST_INSTANCE (1.0f) -static int RayObject_instance_intersect(RayObject *o, Isect *isec); -static void RayObject_instance_free(RayObject *o); -static void RayObject_instance_bb(RayObject *o, float *min, float *max); -static float RayObject_instance_cost(RayObject *o); +static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec); +static void RE_rayobject_instance_free(RayObject *o); +static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max); +static float RE_rayobject_instance_cost(RayObject *o); static RayObjectAPI instance_api = { - RayObject_instance_intersect, - NULL, //static void RayObject_instance_add(RayObject *o, RayObject *ob); - NULL, //static void RayObject_instance_done(RayObject *o); - RayObject_instance_free, - RayObject_instance_bb, - RayObject_instance_cost + RE_rayobject_instance_intersect, + NULL, //static void RE_rayobject_instance_add(RayObject *o, RayObject *ob); + NULL, //static void RE_rayobject_instance_done(RayObject *o); + RE_rayobject_instance_free, + RE_rayobject_instance_bb, + RE_rayobject_instance_cost }; typedef struct InstanceRayObject @@ -68,7 +68,7 @@ typedef struct InstanceRayObject RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob) { InstanceRayObject *obj= (InstanceRayObject*)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); - assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ obj->rayobj.api = &instance_api; obj->target = target; @@ -78,10 +78,10 @@ RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], Mat4CpyMat4(obj->target2global, transform); Mat4Invert(obj->global2target, obj->target2global); - return RayObject_unalignRayAPI((RayObject*) obj); + return RE_rayobject_unalignRayAPI((RayObject*) obj); } -static int RayObject_instance_intersect(RayObject *o, Isect *isec) +static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec) { //TODO // *there is probably a faster way to convert between coordinates @@ -162,19 +162,19 @@ static int RayObject_instance_intersect(RayObject *o, Isect *isec) return res; } -static void RayObject_instance_free(RayObject *o) +static void RE_rayobject_instance_free(RayObject *o) { InstanceRayObject *obj = (InstanceRayObject*)o; MEM_freeN(obj); } -static float RayObject_instance_cost(RayObject *o) +static float RE_rayobject_instance_cost(RayObject *o) { InstanceRayObject *obj = (InstanceRayObject*)o; return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE; } -static void RayObject_instance_bb(RayObject *o, float *min, float *max) +static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max) { //TODO: // *better bb.. calculated without rotations of bb diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index da1083a654d..4246dd522db 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -84,19 +84,19 @@ typedef struct Octree { } Octree; -static int RayObject_octree_intersect(RayObject *o, Isect *isec); -static void RayObject_octree_add(RayObject *o, RayObject *ob); -static void RayObject_octree_done(RayObject *o); -static void RayObject_octree_free(RayObject *o); -static void RayObject_octree_bb(RayObject *o, float *min, float *max); +static int RE_rayobject_octree_intersect(RayObject *o, Isect *isec); +static void RE_rayobject_octree_add(RayObject *o, RayObject *ob); +static void RE_rayobject_octree_done(RayObject *o); +static void RE_rayobject_octree_free(RayObject *o); +static void RE_rayobject_octree_bb(RayObject *o, float *min, float *max); static RayObjectAPI octree_api = { - RayObject_octree_intersect, - RayObject_octree_add, - RayObject_octree_done, - RayObject_octree_free, - RayObject_octree_bb + RE_rayobject_octree_intersect, + RE_rayobject_octree_add, + RE_rayobject_octree_done, + RE_rayobject_octree_free, + RE_rayobject_octree_bb }; /* **************** ocval method ******************* */ @@ -294,7 +294,7 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short while(no->v[a]!=NULL) a++; } - no->v[a]= (RayFace*) RayObject_align(face); + no->v[a]= (RayFace*) RE_rayobject_align(face); if(quad) calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]); @@ -406,7 +406,7 @@ static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *oc } } -static void RayObject_octree_free(RayObject *tree) +static void RE_rayobject_octree_free(RayObject *tree) { Octree *oc= (Octree*)tree; @@ -450,7 +450,7 @@ static void RayObject_octree_free(RayObject *tree) RayObject *RE_rayobject_octree_create(int ocres, int size) { Octree *oc= MEM_callocN(sizeof(Octree), "Octree"); - assert( RayObject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */ + assert( RE_rayobject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */ oc->rayobj.api = &octree_api; @@ -461,17 +461,17 @@ RayObject *RE_rayobject_octree_create(int ocres, int size) oc->ro_nodes_used = 0; - return RayObject_unalignRayAPI((RayObject*) oc); + return RE_rayobject_unalignRayAPI((RayObject*) oc); } -static void RayObject_octree_add(RayObject *tree, RayObject *node) +static void RE_rayobject_octree_add(RayObject *tree, RayObject *node) { Octree *oc = (Octree*)tree; - assert( RayObject_isRayFace(node) ); + assert( RE_rayobject_isRayFace(node) ); assert( oc->ro_nodes_used < oc->ro_nodes_size ); - oc->ro_nodes[ oc->ro_nodes_used++ ] = (RayFace*)RayObject_align(node); + oc->ro_nodes[ oc->ro_nodes_used++ ] = (RayFace*)RE_rayobject_align(node); } static void octree_fill_rayface(Octree *oc, RayFace *face) @@ -489,22 +489,11 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) ocres2= oc->ocres*oc->ocres; -#ifdef RE_RAYFACE_COORDS_VLAKREN - { - VlakRen *vlr = (VlakRen*)face->face; - VECCOPY(co1, vlr->v1->co); - VECCOPY(co2, vlr->v2->co); - VECCOPY(co3, vlr->v3->co); - if(RE_rayface_isQuad(face)) - VECCOPY(co4, vlr->v4->co); - } -#else VECCOPY(co1, face->v1); VECCOPY(co2, face->v2); VECCOPY(co3, face->v3); if(face->v4) VECCOPY(co4, face->v4); -#endif for(c=0;c<3;c++) { rtf[0][c]= (co1[c]-oc->min[c])*ocfac[c] ; @@ -602,7 +591,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) } } -static void RayObject_octree_done(RayObject *tree) +static void RE_rayobject_octree_done(RayObject *tree) { Octree *oc = (Octree*)tree; int c; @@ -613,7 +602,7 @@ static void RayObject_octree_done(RayObject *tree) /* Calculate Bounding Box */ for(c=0; cro_nodes_used; c++) - RE_rayobject_merge_bb( RayObject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max); + RE_rayobject_merge_bb( RE_rayobject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max); /* Alloc memory */ oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); @@ -656,7 +645,7 @@ static void RayObject_octree_done(RayObject *tree) printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz ); } -static void RayObject_octree_bb(RayObject *tree, float *min, float *max) +static void RE_rayobject_octree_bb(RayObject *tree, float *min, float *max) { Octree *oc = (Octree*)tree; DO_MINMAX(oc->min, min, max); @@ -681,7 +670,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RE_rayobject_intersect( RayObject_unalignRayFace(face),is) ) + if( RE_rayobject_intersect( RE_rayobject_unalignRayFace(face),is) ) return 1; } } @@ -700,7 +689,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval) if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { - if( RE_rayobject_intersect( RayObject_unalignRayFace(face),is) ) + if( RE_rayobject_intersect( RE_rayobject_unalignRayFace(face),is) ) found= 1; } } @@ -828,7 +817,7 @@ static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, i /* return 1: found valid intersection */ /* starts with is->orig.face */ -static int RayObject_octree_intersect(RayObject *tree, Isect *is) +static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) { Octree *oc= (Octree*)tree; Node *no; diff --git a/source/blender/render/intern/source/rayobject_raycounter.c b/source/blender/render/intern/source/rayobject_raycounter.c new file mode 100644 index 00000000000..83ba15602da --- /dev/null +++ b/source/blender/render/intern/source/rayobject_raycounter.c @@ -0,0 +1,77 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include "rayobject.h" + +#ifdef RE_RAYCOUNTER + +void RE_RC_INFO(RayCounter *info) +{ + printf("----------- Raycast counter --------\n"); + printf("Rays total: %llu\n", info->raycast.test ); + printf("Rays hit: %llu\n", info->raycast.hit ); + printf("\n"); + printf("BB tests: %llu\n", info->bb.test ); + printf("BB hits: %llu\n", info->bb.hit ); + printf("\n"); + printf("Primitives tests: %llu\n", info->faces.test ); + printf("Primitives hits: %llu\n", info->faces.hit ); + printf("------------------------------------\n"); + printf("Shadow last-hit tests per ray: %f\n", info->rayshadow_last_hit.test / ((float)info->raycast.test) ); + printf("Shadow last-hit hits per ray: %f\n", info->rayshadow_last_hit.hit / ((float)info->raycast.test) ); + printf("\n"); + printf("Hint tests per ray: %f\n", info->raytrace_hint.test / ((float)info->raycast.test) ); + printf("Hint hits per ray: %f\n", info->raytrace_hint.hit / ((float)info->raycast.test) ); + printf("\n"); + printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) ); + printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) ); + printf("\n"); + printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); + printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); + printf("------------------------------------\n"); +} + +void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) +{ + dest->faces.test += tmp->faces.test; + dest->faces.hit += tmp->faces.hit; + + dest->bb.test += tmp->bb.test; + dest->bb.hit += tmp->bb.hit; + + dest->raycast.test += tmp->raycast.test; + dest->raycast.hit += tmp->raycast.hit; + + dest->rayshadow_last_hit.test += tmp->rayshadow_last_hit.test; + dest->rayshadow_last_hit.hit += tmp->rayshadow_last_hit.hit; + + dest->raytrace_hint.test += tmp->raytrace_hint.test; + dest->raytrace_hint.hit += tmp->raytrace_hint.hit; +} + +#endif diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 05c961d49de..af2c0f99174 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -222,7 +222,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) if(is_raytraceable_vlr(re, vlr)) { RE_rayface_from_vlak( face, obi, vlr ); - RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); + RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) ); face++; } } @@ -372,7 +372,7 @@ static void makeraytree_single(Render *re) Mat4MulVecfl(obi->mat, face->v4); } - RE_rayobject_add( raytree, RayObject_unalignRayFace(face) ); + RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) ); face++; } } -- cgit v1.2.3 From 43422354895bb620d6731f928d121ae6cd06da48 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 26 Aug 2009 06:15:43 +0000 Subject: - Mathutils.Vector assignment wasnt working in the BGE's py api, was using getValue() rather than setValue() - added GPL header to bpy_interface.c from 2.4x's BPY_interface.c - warning fixes --- source/blender/editors/object/object_vgroup.c | 2 +- .../blender/python/generic/bpy_internal_import.h | 9 +++++++ source/blender/python/generic/vector.c | 4 +-- source/blender/python/intern/bpy_interface.c | 31 +++++++++++++++++++++- source/gameengine/Ketsji/KX_PyMath.h | 6 ++--- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 4 +-- 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 154ab14df60..767a04d9170 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1076,7 +1076,7 @@ void vgroup_operation_with_menu(Object *ob) short nr; if (menustr) { -// XXX nr= pupmenu(menustr); + nr= 1; // pupmenu(menustr); // XXX if ((nr >= 1) && (nr <= defCount)) ob->actdef= nr; diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index c93d930dab0..4e761fe8da0 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -31,6 +31,15 @@ #ifndef EXPP_bpy_import_h #define EXPP_bpy_import_h +/* python redefines :/ */ +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#ifdef _XOPEN_SOURCE +#undef _XOPEN_SOURCE +#endif + #include #include "compile.h" /* for the PyCodeObject */ #include "eval.h" /* for PyEval_EvalCode */ diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index 923c4bbe58a..c4a8a37ee05 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -168,7 +168,7 @@ static PyObject *Vector_Resize2D(VectorObject * self) return NULL; } if(self->cb_user) { - PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize a vector that has an owner"); return NULL; } @@ -191,7 +191,7 @@ static PyObject *Vector_Resize3D(VectorObject * self) return NULL; } if(self->cb_user) { - PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize a vector that has an owner"); return NULL; } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 69b733d3fda..43db337c6db 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -1,4 +1,28 @@ - +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney, + * Chris Keith, Chris Want, Ken Hughes, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + #include #include #include @@ -10,6 +34,11 @@ #include "BLI_winstuff.h" #endif +/* grr, python redefines */ +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif + #include #include "compile.h" /* for the PyCodeObject */ #include "eval.h" /* for PyEval_EvalCode */ diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index 9ee11c9e745..a8488e8e60a 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -113,7 +113,7 @@ bool PyVecTo(PyObject* pyval, T& vec) PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", pyvec->size, Size(vec)); return false; } - vec.getValue((float *) pyvec->vec); + vec.setValue((float *) pyvec->vec); return true; } else if(QuaternionObject_Check(pyval)) { @@ -123,7 +123,7 @@ bool PyVecTo(PyObject* pyval, T& vec) return false; } /* xyzw -> wxyz reordering is done by PyQuatTo */ - vec.getValue((float *) pyquat->quat); + vec.setValue((float *) pyquat->quat); return true; } else if(EulerObject_Check(pyval)) { @@ -132,7 +132,7 @@ bool PyVecTo(PyObject* pyval, T& vec) PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 3, Size(vec)); return false; } - vec.getValue((float *) pyeul->eul); + vec.setValue((float *) pyeul->eul); return true; } else #endif diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index bc7ccacc39b..bf28802870a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -327,7 +327,6 @@ CcdPhysicsEnvironment::CcdPhysicsEnvironment(bool useDbvtCulling,btDispatcher* d :m_cullingCache(NULL), m_cullingTree(NULL), m_numIterations(10), -m_scalingPropagated(false), m_numTimeSubSteps(1), m_ccdMode(0), m_solverType(-1), @@ -336,7 +335,8 @@ m_enableSatCollisionDetection(false), m_solver(NULL), m_ownPairCache(NULL), m_filterCallback(NULL), -m_ownDispatcher(NULL) +m_ownDispatcher(NULL), +m_scalingPropagated(false) { for (int i=0;i Date: Wed, 26 Aug 2009 06:17:39 +0000 Subject: * Fix for yesterday's valgrind fix * Fix for plane material preview render. Now, light cache aborts if there isn't enough volume, and falls back on non-cached single scattering. It still doesn't make much sense to render a plane as a volume, but for now in the preview it will shade the region in between the plane and the checker background. --- .../render/intern/include/volume_precache.h | 35 ++ .../blender/render/intern/source/volume_precache.c | 23 +- source/blender/render/intern/source/volumetric.c | 690 +++++++++++++++++++++ 3 files changed, 741 insertions(+), 7 deletions(-) diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index dbd02759a63..93620dc9bf4 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -1,3 +1,37 @@ +<<<<<<< .mine +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Matt Ebb. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +void volume_precache(Render *re); +void free_volume_precache(Render *re); +int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co); + +#define VOL_MS_TIMESTEP 0.1f======= /** * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -32,3 +66,4 @@ int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co); int using_lightcache(Material *ma); #define VOL_MS_TIMESTEP 0.1f +>>>>>>> .r22793 diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 71200aa8b0d..d5a54759332 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -499,8 +499,7 @@ static void precache_init_parts(Render *re, RayTree *tree, ShadeInput *shi, Obje res = vp->res; VecSubf(voxel, bbmax, bbmin); - if ((voxel[0] < FLT_EPSILON) || (voxel[1] < FLT_EPSILON) || (voxel[2] < FLT_EPSILON)) - return; + voxel[0] /= res[0]; voxel[1] /= res[1]; voxel[2] /= res[2]; @@ -564,7 +563,7 @@ static VolPrecachePart *precache_get_new_part(Render *re) return nextpa; } -static void precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, int res) +static int precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, int res) { float dim[3], div; @@ -574,10 +573,15 @@ static void precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, dim[0] /= div; dim[1] /= div; dim[2] /= div; - + vp->res[0] = dim[0] * (float)res; vp->res[1] = dim[1] * (float)res; vp->res[2] = dim[2] * (float)res; + + if ((vp->res[0] < 1) || (vp->res[1] < 1) || (vp->res[2] < 1)) + return 0; + + return 1; } /* Precache a volume into a 3D voxel grid. @@ -608,7 +612,12 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat if (!tree) return; vp = MEM_callocN(sizeof(VolumePrecache), "volume light cache"); - precache_resolution(vp, bbmin, bbmax, ma->vol.precache_resolution); + + if (!precache_resolution(vp, bbmin, bbmax, ma->vol.precache_resolution)) { + MEM_freeN(vp); + vp = NULL; + return; + } vp->data_r = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data red channel"); vp->data_g = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data green channel"); @@ -675,7 +684,7 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat } } -int using_lightcache(Material *ma) +static int using_lightcache(Material *ma) { return (((ma->vol.shadeflag & MA_VOL_PRECACHESHADING) && (ma->vol.shade_type == MA_VOL_SHADE_SINGLE)) || (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SINGLEPLUSMULTIPLE))); @@ -708,10 +717,10 @@ void free_volume_precache(Render *re) for(obi= re->instancetable.first; obi; obi= obi->next) { if (obi->volume_precache != NULL) { - MEM_freeN(obi->volume_precache); MEM_freeN(obi->volume_precache->data_r); MEM_freeN(obi->volume_precache->data_g); MEM_freeN(obi->volume_precache->data_b); + MEM_freeN(obi->volume_precache); obi->volume_precache = NULL; } } diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 13996905437..441237dab79 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -1,3 +1,692 @@ +<<<<<<< .mine +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Matt Ebb, Raul Fernandez Hernandez (Farsthary) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" +#include "BLI_voxel.h" + +#include "RE_shader_ext.h" +#include "RE_raytrace.h" + +#include "DNA_material_types.h" +#include "DNA_group_types.h" +#include "DNA_lamp_types.h" + +#include "BKE_global.h" + +#include "render_types.h" +#include "pixelshading.h" +#include "shading.h" +#include "texture.h" +#include "volumetric.h" +#include "volume_precache.h" + +#if defined( _MSC_VER ) && !defined( __cplusplus ) +# define inline __inline +#endif // defined( _MSC_VER ) && !defined( __cplusplus ) + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ +/* only to be used here in this file, it's for speed */ +extern struct Render R; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + +/* tracing */ + +static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type) +{ + float maxsize = RE_ray_tree_max_size(R.raytree); + + /* XXX TODO - get raytrace max distance from object instance's bounding box */ + /* need to account for scaling only, but keep coords in camera space... + * below code is WIP and doesn't work! + VecSubf(bb_dim, shi->obi->obr->boundbox[1], shi->obi->obr->boundbox[2]); + Mat3MulVecfl(shi->obi->nmat, bb_dim); + maxsize = VecLength(bb_dim); + */ + + VECCOPY(isect->start, co); + isect->end[0] = co[0] + vec[0] * maxsize; + isect->end[1] = co[1] + vec[1] * maxsize; + isect->end[2] = co[2] + vec[2] * maxsize; + + isect->mode= RE_RAY_MIRROR; + isect->oborig= RAY_OBJECT_SET(&R, shi->obi); + isect->face_last= NULL; + isect->ob_last= 0; + isect->lay= -1; + + if (intersect_type == VOL_BOUNDS_DEPTH) isect->faceorig= (RayFace*)shi->vlr; + else if (intersect_type == VOL_BOUNDS_SS) isect->faceorig= NULL; + + if(RE_ray_tree_intersect(R.raytree, isect)) + { + hitco[0] = isect->start[0] + isect->labda*isect->vec[0]; + hitco[1] = isect->start[1] + isect->labda*isect->vec[1]; + hitco[2] = isect->start[2] + isect->labda*isect->vec[2]; + return 1; + } else { + return 0; + } +} + +static void shade_intersection(ShadeInput *shi, float *col, Isect *is) +{ + ShadeInput shi_new; + ShadeResult shr_new; + + memset(&shi_new, 0, sizeof(ShadeInput)); + + shi_new.mask= shi->mask; + shi_new.osatex= shi->osatex; + shi_new.thread= shi->thread; + shi_new.depth = shi->depth + 1; + shi_new.volume_depth= shi->volume_depth + 1; + shi_new.xs= shi->xs; + shi_new.ys= shi->ys; + shi_new.lay= shi->lay; + shi_new.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */ + shi_new.combinedflag= 0xFFFFFF; /* ray trace does all options */ + shi_new.light_override= shi->light_override; + shi_new.mat_override= shi->mat_override; + + VECCOPY(shi_new.camera_co, is->start); + + memset(&shr_new, 0, sizeof(ShadeResult)); + + /* hardcoded limit of 100 for now - prevents problems in weird geometry */ + if (shi->volume_depth < 100) { + shade_ray(is, &shi_new, &shr_new); + } + + VecCopyf(col, shr_new.combined); + col[3] = shr_new.alpha; +} + +static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *col) +{ + Isect isect; + float maxsize = RE_ray_tree_max_size(R.raytree); + + VECCOPY(isect.start, co); + isect.end[0] = isect.start[0] + shi->view[0] * maxsize; + isect.end[1] = isect.start[1] + shi->view[1] * maxsize; + isect.end[2] = isect.start[2] + shi->view[2] * maxsize; + + isect.faceorig= (RayFace *)vlr; + + isect.mode= RE_RAY_MIRROR; + isect.oborig= RAY_OBJECT_SET(&R, shi->obi); + isect.face_last= NULL; + isect.ob_last= 0; + isect.lay= -1; + + /* check to see if there's anything behind the volume, otherwise shade the sky */ + if(RE_ray_tree_intersect(R.raytree, &isect)) { + shade_intersection(shi, col, &isect); + } else { + shadeSkyView(col, co, shi->view, NULL, shi->thread); + shadeSunView(col, shi->view); + } +} + +/* input shader data */ + +float vol_get_stepsize(struct ShadeInput *shi, int context) +{ + if (shi->mat->vol.stepsize_type == MA_VOL_STEP_RANDOMIZED) { + /* range between 0.75 and 1.25 */ + const float rnd = 0.5f * BLI_thread_frand(shi->thread) + 0.75f; + + if (context == STEPSIZE_VIEW) + return shi->mat->vol.stepsize * rnd; + else if (context == STEPSIZE_SHADE) + return shi->mat->vol.shade_stepsize * rnd; + } + else { // MA_VOL_STEP_CONSTANT + + if (context == STEPSIZE_VIEW) + return shi->mat->vol.stepsize; + else if (context == STEPSIZE_SHADE) + return shi->mat->vol.shade_stepsize; + } + + return shi->mat->vol.stepsize; +} + +/* trilinear interpolation */ +static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, float *co) +{ + VolumePrecache *vp = shi->obi->volume_precache; + float bbmin[3], bbmax[3], dim[3]; + float sample_co[3]; + + if (!vp) return; + + /* convert input coords to 0.0, 1.0 */ + VECCOPY(bbmin, shi->obi->obr->boundbox[0]); + VECCOPY(bbmax, shi->obi->obr->boundbox[1]); + VecSubf(dim, bbmax, bbmin); + + sample_co[0] = ((co[0] - bbmin[0]) / dim[0]); + sample_co[1] = ((co[1] - bbmin[1]) / dim[1]); + sample_co[2] = ((co[2] - bbmin[2]) / dim[2]); + + scatter_col[0] = voxel_sample_trilinear(vp->data_r, vp->res, sample_co); + scatter_col[1] = voxel_sample_trilinear(vp->data_g, vp->res, sample_co); + scatter_col[2] = voxel_sample_trilinear(vp->data_b, vp->res, sample_co); +} + +float vol_get_density(struct ShadeInput *shi, float *co) +{ + float density = shi->mat->vol.density; + float density_scale = shi->mat->vol.density_scale; + float col[3] = {0.0, 0.0, 0.0}; + + do_volume_tex(shi, co, MAP_DENSITY, col, &density); + + return density * density_scale; +} + +/* scattering multiplier, values above 1.0 are non-physical, + * but can be useful to tweak lighting */ +float vol_get_scattering_fac(ShadeInput *shi, float *co) +{ + float scatter = shi->mat->vol.scattering; + float col[3] = {0.0, 0.0, 0.0}; + + do_volume_tex(shi, co, MAP_SCATTERING, col, &scatter); + + return scatter; +} + +/* compute emission component, amount of radiance to add per segment + * can be textured with 'emit' */ +void vol_get_emission(ShadeInput *shi, float *emission_col, float *co, float density) +{ + float emission = shi->mat->vol.emission; + VECCOPY(emission_col, shi->mat->vol.emission_col); + + do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission); + + emission_col[0] = emission_col[0] * emission * density; + emission_col[1] = emission_col[1] * emission * density; + emission_col[2] = emission_col[2] * emission * density; +} + +void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co) +{ + float absorption = shi->mat->vol.absorption; + VECCOPY(absorb_col, shi->mat->vol.absorption_col); + + do_volume_tex(shi, co, MAP_ABSORPTION+MAP_ABSORPTION_COL, absorb_col, &absorption); + + absorb_col[0] = (1.0f - absorb_col[0]) * absorption; + absorb_col[1] = (1.0f - absorb_col[1]) * absorption; + absorb_col[2] = (1.0f - absorb_col[2]) * absorption; +} + + +/* phase function - determines in which directions the light + * is scattered in the volume relative to incoming direction + * and view direction */ +float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w, float *wp) +{ + const float costheta = Inpf(w, wp); + const float scale = M_PI; + + /* + * Scale constant is required, since Blender's shading system doesn't normalise for + * energy conservation - eg. scaling by 1/pi for a lambert shader. + * This makes volumes darker than other solid objects, for the same lighting intensity. + * To correct this, scale up the phase function values + * until Blender's shading system supports this better. --matt + */ + + switch (phasefunc_type) { + case MA_VOL_PH_MIEHAZY: + return scale * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f)) / (4.f*M_PI); + case MA_VOL_PH_MIEMURKY: + return scale * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)) / (4.f*M_PI); + case MA_VOL_PH_RAYLEIGH: + return scale * 3.f/(16.f*M_PI) * (1 + costheta * costheta); + case MA_VOL_PH_HG: + return scale * (1.f / (4.f * M_PI) * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f)); + case MA_VOL_PH_SCHLICK: + { + const float k = 1.55f * g - .55f * g * g * g; + const float kcostheta = k * costheta; + return scale * (1.f / (4.f * M_PI) * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta))); + } + case MA_VOL_PH_ISOTROPIC: + default: + return scale * (1.f / (4.f * M_PI)); + } +} + +/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. + * Used in the relationship Transmittance = e^(-attenuation) + */ +void vol_get_attenuation_seg(ShadeInput *shi, float *transmission, float stepsize, float *co, float density) +{ + /* input density = density at co */ + float tau[3] = {0.f, 0.f, 0.f}; + float absorb_col[3]; + + vol_get_absorption(shi, absorb_col, co); + + /* homogenous volume within the sampled distance */ + tau[0] = stepsize * density * absorb_col[0]; + tau[1] = stepsize * density * absorb_col[1]; + tau[2] = stepsize * density * absorb_col[2]; + + transmission[0] *= exp(-tau[0]); + transmission[1] *= exp(-tau[1]); + transmission[2] *= exp(-tau[2]); +} + +/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. + * Used in the relationship Transmittance = e^(-attenuation) + */ +void vol_get_attenuation(ShadeInput *shi, float *transmission, float *co, float *endco, float density, float stepsize) +{ + /* input density = density at co */ + float tau[3] = {0.f, 0.f, 0.f}; + float absorb_col[3]; + int s, nsteps; + float step_vec[3], step_sta[3], step_end[3]; + const float dist = VecLenf(co, endco); + + vol_get_absorption(shi, absorb_col, co); + + nsteps = (int)((dist / stepsize) + 0.5); + + VecSubf(step_vec, endco, co); + VecMulf(step_vec, 1.0f / nsteps); + + VecCopyf(step_sta, co); + VecAddf(step_end, step_sta, step_vec); + + for (s = 0; s < nsteps; s++) { + if (s > 0) + density = vol_get_density(shi, step_sta); + + tau[0] += stepsize * density; + tau[1] += stepsize * density; + tau[2] += stepsize * density; + + if (s < nsteps-1) { + VecCopyf(step_sta, step_end); + VecAddf(step_end, step_end, step_vec); + } + } + VecMulVecf(tau, tau, absorb_col); + + transmission[0] *= exp(-tau[0]); + transmission[1] *= exp(-tau[1]); + transmission[2] *= exp(-tau[2]); +} + +void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol, float stepsize, float density) +{ + float visifac, lv[3], lampdist; + float tr[3]={1.0,1.0,1.0}; + float hitco[3], *atten_co; + float p; + float scatter_fac; + float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE); + + if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return; + if ((lar->lay & shi->lay)==0) return; + if (lar->energy == 0.0) return; + + if ((visifac= lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return; + + VecCopyf(lacol, &lar->r); + + if(lar->mode & LA_TEXTURE) { + shi->osatex= 0; + do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE); + } + + VecMulf(lacol, visifac*lar->energy); + + if (ELEM(lar->type, LA_SUN, LA_HEMI)) + VECCOPY(lv, lar->vec); + VecMulf(lv, -1.0f); + + if (shi->mat->vol.shade_type != MA_VOL_SHADE_NONE) { + Isect is; + + /* find minimum of volume bounds, or lamp coord */ + if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) { + float dist = VecLenf(co, hitco); + VlakRen *vlr = (VlakRen *)is.face; + + /* simple internal shadowing */ + if (vlr->mat->material_type == MA_TYPE_SURFACE) { + lacol[0] = lacol[1] = lacol[2] = 0.0f; + return; + } + + if (ELEM(lar->type, LA_SUN, LA_HEMI)) + /* infinite lights, can never be inside volume */ + atten_co = hitco; + else if ( lampdist < dist ) { + atten_co = lar->co; + } else + atten_co = hitco; + + vol_get_attenuation(shi, tr, co, atten_co, density, shade_stepsize); + + VecMulVecf(lacol, lacol, tr); + } + else { + /* Point is on the outside edge of the volume, + * therefore no attenuation, full transmission. + * Radiance from lamp remains unchanged */ + } + } + + p = vol_get_phasefunc(shi, shi->mat->vol.phasefunc_type, shi->mat->vol.phasefunc_g, shi->view, lv); + VecMulf(lacol, p); + + scatter_fac = vol_get_scattering_fac(shi, co); + VecMulf(lacol, scatter_fac); +} + +/* single scattering only for now */ +void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float stepsize, float density) +{ + ListBase *lights; + GroupObject *go; + LampRen *lar; + + scatter_col[0] = scatter_col[1] = scatter_col[2] = 0.f; + + lights= get_lights(shi); + for(go=lights->first; go; go= go->next) + { + float lacol[3] = {0.f, 0.f, 0.f}; + lar= go->lampren; + + if (lar) { + vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density); + VecAddf(scatter_col, scatter_col, lacol); + } + } +} + + +/* +The main volumetric integrator, using an emission/absorption/scattering model. + +Incoming radiance = + +outgoing radiance from behind surface * beam transmittance/attenuation ++ added radiance from all points along the ray due to participating media + --> radiance for each segment = + (radiance added by scattering + radiance added by emission) * beam transmittance/attenuation +*/ +static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco) +{ + float tr[3] = {1.0f, 1.0f, 1.0f}; + float radiance[3] = {0.f, 0.f, 0.f}, d_radiance[3] = {0.f, 0.f, 0.f}; + float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW); + int nsteps, s; + float emit_col[3], scatter_col[3] = {0.0, 0.0, 0.0}; + float stepvec[3], step_sta[3], step_end[3], step_mid[3]; + float density; + const float depth_cutoff = shi->mat->vol.depth_cutoff; + + /* ray marching */ + nsteps = (int)((VecLenf(co, endco) / stepsize) + 0.5); + + VecSubf(stepvec, endco, co); + VecMulf(stepvec, 1.0f / nsteps); + VecCopyf(step_sta, co); + VecAddf(step_end, step_sta, stepvec); + + /* get radiance from all points along the ray due to participating media */ + for (s = 0; s < nsteps; s++) { + + density = vol_get_density(shi, step_sta); + + /* there's only any use in shading here if there's actually some density to shade! */ + if (density > 0.01f) { + + /* transmittance component (alpha) */ + vol_get_attenuation_seg(shi, tr, stepsize, co, density); + + step_mid[0] = step_sta[0] + (stepvec[0] * 0.5); + step_mid[1] = step_sta[1] + (stepvec[1] * 0.5); + step_mid[2] = step_sta[2] + (stepvec[2] * 0.5); + + /* incoming light via emission or scattering (additive) */ + vol_get_emission(shi, emit_col, step_mid, density); + + if (shi->obi->volume_precache) + vol_get_precached_scattering(shi, scatter_col, step_mid); + else + vol_get_scattering(shi, scatter_col, step_mid, stepsize, density); + + VecMulf(scatter_col, density); + VecAddf(d_radiance, emit_col, scatter_col); + + /* Lv += Tr * (Lve() + Ld) */ + VecMulVecf(d_radiance, tr, d_radiance); + VecMulf(d_radiance, stepsize); + + VecAddf(radiance, radiance, d_radiance); + } + + VecCopyf(step_sta, step_end); + VecAddf(step_end, step_end, stepvec); + + /* luminance rec. 709 */ + if ((0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]) < depth_cutoff) break; + } + + /* multiply original color (behind volume) with beam transmittance over entire distance */ + VecMulVecf(col, tr, col); + VecAddf(col, col, radiance); + + /* alpha <-- transmission luminance */ + col[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]); +} + +/* the main entry point for volume shading */ +static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume) +{ + float hitco[3], col[4] = {0.f,0.f,0.f,0.f}; + float *startco, *endco; + int trace_behind = 1; + const int ztransp= ((shi->depth==0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP)); + Isect is; + + /* check for shading an internal face a volume object directly */ + if (inside_volume == VOL_SHADE_INSIDE) + trace_behind = 0; + else if (inside_volume == VOL_SHADE_OUTSIDE) { + if (shi->flippednor) + inside_volume = VOL_SHADE_INSIDE; + } + + if (ztransp && inside_volume == VOL_SHADE_INSIDE) { + MatInside *mi; + int render_this=0; + + /* don't render the backfaces of ztransp volume materials. + + * volume shading renders the internal volume from between the + * near view intersection of the solid volume to the + * intersection on the other side, as part of the shading of + * the front face. + + * Because ztransp renders both front and back faces independently + * this will double up, so here we prevent rendering the backface as well, + * which would otherwise render the volume in between the camera and the backface + * --matt */ + + for (mi=R.render_volumes_inside.first; mi; mi=mi->next) { + /* weak... */ + if (mi->ma == shi->mat) render_this=1; + } + if (!render_this) return; + } + + + if (inside_volume == VOL_SHADE_INSIDE) + { + startco = shi->camera_co; + endco = shi->co; + + if (trace_behind) { + if (!ztransp) + /* trace behind the volume object */ + vol_trace_behind(shi, shi->vlr, endco, col); + } else { + /* we're tracing through the volume between the camera + * and a solid surface, so use that pre-shaded radiance */ + QUATCOPY(col, shr->combined); + } + + /* shade volume from 'camera' to 1st hit point */ + volumeintegrate(shi, col, startco, endco); + } + /* trace to find a backface, the other side bounds of the volume */ + /* (ray intersect ignores front faces here) */ + else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) + { + VlakRen *vlr = (VlakRen *)is.face; + + startco = shi->co; + endco = hitco; + + if (!ztransp) { + /* if it's another face in the same material */ + if (vlr->mat == shi->mat) { + /* trace behind the 2nd (raytrace) hit point */ + vol_trace_behind(shi, (VlakRen *)is.face, endco, col); + } else { + shade_intersection(shi, col, &is); + } + } + + /* shade volume from 1st hit point to 2nd hit point */ + volumeintegrate(shi, col, startco, endco); + } + + if (ztransp) + col[3] = col[3]>1.f?1.f:col[3]; + else + col[3] = 1.f; + + VecCopyf(shr->combined, col); + shr->alpha = col[3]; + + VECCOPY(shr->diff, shr->combined); +} + +/* Traces a shadow through the object, + * pretty much gets the transmission over a ray path */ +void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is) +{ + float hitco[3]; + float tr[3] = {1.0,1.0,1.0}; + Isect is; + float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE); + float *startco, *endco; + float density=0.f; + + memset(shr, 0, sizeof(ShadeResult)); + + /* if 1st hit normal is facing away from the camera, + * then we're inside the volume already. */ + if (shi->flippednor) { + startco = last_is->start; + endco = shi->co; + } + /* trace to find a backface, the other side bounds of the volume */ + /* (ray intersect ignores front faces here) */ + else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) { + startco = shi->co; + endco = hitco; + } + else { + shr->combined[0] = shr->combined[1] = shr->combined[2] = 0.f; + shr->alpha = shr->combined[3] = 1.f; + return; + } + + density = vol_get_density(shi, startco); + vol_get_attenuation(shi, tr, startco, endco, density, shade_stepsize); + + VecCopyf(shr->combined, tr); + shr->combined[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]); + shr->alpha = shr->combined[3]; +} + + +/* delivers a fully filled in ShadeResult, for all passes */ +void shade_volume_outside(ShadeInput *shi, ShadeResult *shr) +{ + memset(shr, 0, sizeof(ShadeResult)); + volume_trace(shi, shr, VOL_SHADE_OUTSIDE); +} + + +void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) +{ + MatInside *m; + Material *mat_backup; + + //if (BLI_countlist(&R.render_volumes_inside) == 0) return; + + /* XXX: extend to multiple volumes perhaps later */ + mat_backup = shi->mat; + m = R.render_volumes_inside.first; + shi->mat = m->ma; + + volume_trace(shi, shr, VOL_SHADE_INSIDE); + + shi->mat = mat_backup; +}======= /** * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -686,3 +1375,4 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) shi->mat = mat_backup; } +>>>>>>> .r22793 -- cgit v1.2.3 From 740752da12543c5d6183a6956ed4f439693ba288 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 26 Aug 2009 06:51:26 +0000 Subject: * Hopefully fix some weird merging business --- .../render/intern/include/volume_precache.h | 38 +- source/blender/render/intern/source/volumetric.c | 692 +-------------------- 2 files changed, 2 insertions(+), 728 deletions(-) diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index 93620dc9bf4..9d87a219c82 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -1,4 +1,3 @@ -<<<<<<< .mine /** * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -31,39 +30,4 @@ void volume_precache(Render *re); void free_volume_precache(Render *re); int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co); -#define VOL_MS_TIMESTEP 0.1f======= -/** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -void volume_precache(Render *re); -void free_volume_precache(Render *re); -int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co); -int using_lightcache(Material *ma); - -#define VOL_MS_TIMESTEP 0.1f ->>>>>>> .r22793 +#define VOL_MS_TIMESTEP 0.1f \ No newline at end of file diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 441237dab79..046a145e9da 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -1,4 +1,3 @@ -<<<<<<< .mine /** * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -686,693 +685,4 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) volume_trace(shi, shr, VOL_SHADE_INSIDE); shi->mat = mat_backup; -}======= -/** - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Matt Ebb, Raul Fernandez Hernandez (Farsthary) - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_rand.h" -#include "BLI_voxel.h" - -#include "RE_shader_ext.h" -#include "RE_raytrace.h" - -#include "DNA_material_types.h" -#include "DNA_group_types.h" -#include "DNA_lamp_types.h" - -#include "BKE_global.h" - -#include "render_types.h" -#include "pixelshading.h" -#include "shading.h" -#include "texture.h" -#include "volumetric.h" -#include "volume_precache.h" - -#if defined( _MSC_VER ) && !defined( __cplusplus ) -# define inline __inline -#endif // defined( _MSC_VER ) && !defined( __cplusplus ) - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ -/* only to be used here in this file, it's for speed */ -extern struct Render R; -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - -/* tracing */ - -static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type) -{ - float maxsize = RE_ray_tree_max_size(R.raytree); - - /* XXX TODO - get raytrace max distance from object instance's bounding box */ - /* need to account for scaling only, but keep coords in camera space... - * below code is WIP and doesn't work! - VecSubf(bb_dim, shi->obi->obr->boundbox[1], shi->obi->obr->boundbox[2]); - Mat3MulVecfl(shi->obi->nmat, bb_dim); - maxsize = VecLength(bb_dim); - */ - - VECCOPY(isect->start, co); - isect->end[0] = co[0] + vec[0] * maxsize; - isect->end[1] = co[1] + vec[1] * maxsize; - isect->end[2] = co[2] + vec[2] * maxsize; - - isect->mode= RE_RAY_MIRROR; - isect->oborig= RAY_OBJECT_SET(&R, shi->obi); - isect->face_last= NULL; - isect->ob_last= 0; - isect->lay= -1; - - if (intersect_type == VOL_BOUNDS_DEPTH) isect->faceorig= (RayFace*)shi->vlr; - else if (intersect_type == VOL_BOUNDS_SS) isect->faceorig= NULL; - - if(RE_ray_tree_intersect(R.raytree, isect)) - { - hitco[0] = isect->start[0] + isect->labda*isect->vec[0]; - hitco[1] = isect->start[1] + isect->labda*isect->vec[1]; - hitco[2] = isect->start[2] + isect->labda*isect->vec[2]; - return 1; - } else { - return 0; - } -} - -static void shade_intersection(ShadeInput *shi, float *col, Isect *is) -{ - ShadeInput shi_new; - ShadeResult shr_new; - - memset(&shi_new, 0, sizeof(ShadeInput)); - - shi_new.mask= shi->mask; - shi_new.osatex= shi->osatex; - shi_new.thread= shi->thread; - shi_new.depth = shi->depth + 1; - shi_new.volume_depth= shi->volume_depth + 1; - shi_new.xs= shi->xs; - shi_new.ys= shi->ys; - shi_new.lay= shi->lay; - shi_new.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */ - shi_new.combinedflag= 0xFFFFFF; /* ray trace does all options */ - shi_new.light_override= shi->light_override; - shi_new.mat_override= shi->mat_override; - - VECCOPY(shi_new.camera_co, is->start); - - memset(&shr_new, 0, sizeof(ShadeResult)); - - /* hardcoded limit of 100 for now - prevents problems in weird geometry */ - if (shi->volume_depth < 100) { - shade_ray(is, &shi_new, &shr_new); - } - - VecCopyf(col, shr_new.combined); - col[3] = shr_new.alpha; -} - -static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *col) -{ - Isect isect; - float maxsize = RE_ray_tree_max_size(R.raytree); - - VECCOPY(isect.start, co); - isect.end[0] = isect.start[0] + shi->view[0] * maxsize; - isect.end[1] = isect.start[1] + shi->view[1] * maxsize; - isect.end[2] = isect.start[2] + shi->view[2] * maxsize; - - isect.faceorig= (RayFace *)vlr; - - isect.mode= RE_RAY_MIRROR; - isect.oborig= RAY_OBJECT_SET(&R, shi->obi); - isect.face_last= NULL; - isect.ob_last= 0; - isect.lay= -1; - - /* check to see if there's anything behind the volume, otherwise shade the sky */ - if(RE_ray_tree_intersect(R.raytree, &isect)) { - shade_intersection(shi, col, &isect); - } else { - shadeSkyView(col, co, shi->view, NULL, shi->thread); - shadeSunView(col, shi->view); - } -} - -/* input shader data */ - -float vol_get_stepsize(struct ShadeInput *shi, int context) -{ - if (shi->mat->vol.stepsize_type == MA_VOL_STEP_RANDOMIZED) { - /* range between 0.75 and 1.25 */ - const float rnd = 0.5f * BLI_thread_frand(shi->thread) + 0.75f; - - if (context == STEPSIZE_VIEW) - return shi->mat->vol.stepsize * rnd; - else if (context == STEPSIZE_SHADE) - return shi->mat->vol.shade_stepsize * rnd; - } - else { // MA_VOL_STEP_CONSTANT - - if (context == STEPSIZE_VIEW) - return shi->mat->vol.stepsize; - else if (context == STEPSIZE_SHADE) - return shi->mat->vol.shade_stepsize; - } - - return shi->mat->vol.stepsize; -} - -/* trilinear interpolation */ -static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, float *co) -{ - VolumePrecache *vp = shi->obi->volume_precache; - float bbmin[3], bbmax[3], dim[3]; - float sample_co[3]; - - if (!vp) return; - - /* convert input coords to 0.0, 1.0 */ - VECCOPY(bbmin, shi->obi->obr->boundbox[0]); - VECCOPY(bbmax, shi->obi->obr->boundbox[1]); - VecSubf(dim, bbmax, bbmin); - - sample_co[0] = ((co[0] - bbmin[0]) / dim[0]); - sample_co[1] = ((co[1] - bbmin[1]) / dim[1]); - sample_co[2] = ((co[2] - bbmin[2]) / dim[2]); - - scatter_col[0] = voxel_sample_trilinear(vp->data_r, vp->res, sample_co); - scatter_col[1] = voxel_sample_trilinear(vp->data_g, vp->res, sample_co); - scatter_col[2] = voxel_sample_trilinear(vp->data_b, vp->res, sample_co); -} - -float vol_get_density(struct ShadeInput *shi, float *co) -{ - float density = shi->mat->vol.density; - float density_scale = shi->mat->vol.density_scale; - float col[3] = {0.0, 0.0, 0.0}; - - do_volume_tex(shi, co, MAP_DENSITY, col, &density); - - return density * density_scale; -} - -/* scattering multiplier, values above 1.0 are non-physical, - * but can be useful to tweak lighting */ -float vol_get_scattering_fac(ShadeInput *shi, float *co) -{ - float scatter = shi->mat->vol.scattering; - float col[3] = {0.0, 0.0, 0.0}; - - do_volume_tex(shi, co, MAP_SCATTERING, col, &scatter); - - return scatter; -} - -/* compute emission component, amount of radiance to add per segment - * can be textured with 'emit' */ -void vol_get_emission(ShadeInput *shi, float *emission_col, float *co, float density) -{ - float emission = shi->mat->vol.emission; - VECCOPY(emission_col, shi->mat->vol.emission_col); - - do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission); - - emission_col[0] = emission_col[0] * emission * density; - emission_col[1] = emission_col[1] * emission * density; - emission_col[2] = emission_col[2] * emission * density; -} - -void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co) -{ - float absorption = shi->mat->vol.absorption; - VECCOPY(absorb_col, shi->mat->vol.absorption_col); - - do_volume_tex(shi, co, MAP_ABSORPTION+MAP_ABSORPTION_COL, absorb_col, &absorption); - - absorb_col[0] = (1.0f - absorb_col[0]) * absorption; - absorb_col[1] = (1.0f - absorb_col[1]) * absorption; - absorb_col[2] = (1.0f - absorb_col[2]) * absorption; -} - - -/* phase function - determines in which directions the light - * is scattered in the volume relative to incoming direction - * and view direction */ -float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w, float *wp) -{ - const float costheta = Inpf(w, wp); - const float scale = M_PI; - - /* - * Scale constant is required, since Blender's shading system doesn't normalise for - * energy conservation - eg. scaling by 1/pi for a lambert shader. - * This makes volumes darker than other solid objects, for the same lighting intensity. - * To correct this, scale up the phase function values - * until Blender's shading system supports this better. --matt - */ - - switch (phasefunc_type) { - case MA_VOL_PH_MIEHAZY: - return scale * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f)) / (4.f*M_PI); - case MA_VOL_PH_MIEMURKY: - return scale * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)) / (4.f*M_PI); - case MA_VOL_PH_RAYLEIGH: - return scale * 3.f/(16.f*M_PI) * (1 + costheta * costheta); - case MA_VOL_PH_HG: - return scale * (1.f / (4.f * M_PI) * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f)); - case MA_VOL_PH_SCHLICK: - { - const float k = 1.55f * g - .55f * g * g * g; - const float kcostheta = k * costheta; - return scale * (1.f / (4.f * M_PI) * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta))); - } - case MA_VOL_PH_ISOTROPIC: - default: - return scale * (1.f / (4.f * M_PI)); - } -} - -/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. - * Used in the relationship Transmittance = e^(-attenuation) - */ -void vol_get_attenuation_seg(ShadeInput *shi, float *transmission, float stepsize, float *co, float density) -{ - /* input density = density at co */ - float tau[3] = {0.f, 0.f, 0.f}; - float absorb_col[3]; - - vol_get_absorption(shi, absorb_col, co); - - /* homogenous volume within the sampled distance */ - tau[0] = stepsize * density * absorb_col[0]; - tau[1] = stepsize * density * absorb_col[1]; - tau[2] = stepsize * density * absorb_col[2]; - - transmission[0] *= exp(-tau[0]); - transmission[1] *= exp(-tau[1]); - transmission[2] *= exp(-tau[2]); -} - -/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. - * Used in the relationship Transmittance = e^(-attenuation) - */ -void vol_get_attenuation(ShadeInput *shi, float *transmission, float *co, float *endco, float density, float stepsize) -{ - /* input density = density at co */ - float tau[3] = {0.f, 0.f, 0.f}; - float absorb_col[3]; - int s, nsteps; - float step_vec[3], step_sta[3], step_end[3]; - const float dist = VecLenf(co, endco); - - vol_get_absorption(shi, absorb_col, co); - - nsteps = (int)((dist / stepsize) + 0.5); - - VecSubf(step_vec, endco, co); - VecMulf(step_vec, 1.0f / nsteps); - - VecCopyf(step_sta, co); - VecAddf(step_end, step_sta, step_vec); - - for (s = 0; s < nsteps; s++) { - if (s > 0) - density = vol_get_density(shi, step_sta); - - tau[0] += stepsize * density; - tau[1] += stepsize * density; - tau[2] += stepsize * density; - - if (s < nsteps-1) { - VecCopyf(step_sta, step_end); - VecAddf(step_end, step_end, step_vec); - } - } - VecMulVecf(tau, tau, absorb_col); - - transmission[0] *= exp(-tau[0]); - transmission[1] *= exp(-tau[1]); - transmission[2] *= exp(-tau[2]); -} - -void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol, float stepsize, float density) -{ - float visifac, lv[3], lampdist; - float tr[3]={1.0,1.0,1.0}; - float hitco[3], *atten_co; - float p; - float scatter_fac; - float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE); - - if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return; - if ((lar->lay & shi->lay)==0) return; - if (lar->energy == 0.0) return; - - if ((visifac= lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return; - - VecCopyf(lacol, &lar->r); - - if(lar->mode & LA_TEXTURE) { - shi->osatex= 0; - do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE); - } - - VecMulf(lacol, visifac*lar->energy); - - if (ELEM(lar->type, LA_SUN, LA_HEMI)) - VECCOPY(lv, lar->vec); - VecMulf(lv, -1.0f); - - if (shi->mat->vol.shade_type != MA_VOL_SHADE_NONE) { - Isect is; - - /* find minimum of volume bounds, or lamp coord */ - if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) { - float dist = VecLenf(co, hitco); - VlakRen *vlr = (VlakRen *)is.face; - - /* simple internal shadowing */ - if (vlr->mat->material_type == MA_TYPE_SURFACE) { - lacol[0] = lacol[1] = lacol[2] = 0.0f; - return; - } - - if (ELEM(lar->type, LA_SUN, LA_HEMI)) - /* infinite lights, can never be inside volume */ - atten_co = hitco; - else if ( lampdist < dist ) { - atten_co = lar->co; - } else - atten_co = hitco; - - vol_get_attenuation(shi, tr, co, atten_co, density, shade_stepsize); - - VecMulVecf(lacol, lacol, tr); - } - else { - /* Point is on the outside edge of the volume, - * therefore no attenuation, full transmission. - * Radiance from lamp remains unchanged */ - } - } - - p = vol_get_phasefunc(shi, shi->mat->vol.phasefunc_type, shi->mat->vol.phasefunc_g, shi->view, lv); - VecMulf(lacol, p); - - scatter_fac = vol_get_scattering_fac(shi, co); - VecMulf(lacol, scatter_fac); -} - -/* single scattering only for now */ -void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float stepsize, float density) -{ - ListBase *lights; - GroupObject *go; - LampRen *lar; - - scatter_col[0] = scatter_col[1] = scatter_col[2] = 0.f; - - lights= get_lights(shi); - for(go=lights->first; go; go= go->next) - { - float lacol[3] = {0.f, 0.f, 0.f}; - lar= go->lampren; - - if (lar) { - vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density); - VecAddf(scatter_col, scatter_col, lacol); - } - } -} - - -/* -The main volumetric integrator, using an emission/absorption/scattering model. - -Incoming radiance = - -outgoing radiance from behind surface * beam transmittance/attenuation -+ added radiance from all points along the ray due to participating media - --> radiance for each segment = - (radiance added by scattering + radiance added by emission) * beam transmittance/attenuation -*/ -static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco) -{ - float tr[3] = {1.0f, 1.0f, 1.0f}; - float radiance[3] = {0.f, 0.f, 0.f}, d_radiance[3] = {0.f, 0.f, 0.f}; - float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW); - int nsteps, s; - float emit_col[3], scatter_col[3] = {0.0, 0.0, 0.0}; - float stepvec[3], step_sta[3], step_end[3], step_mid[3]; - float density; - const float depth_cutoff = shi->mat->vol.depth_cutoff; - - /* ray marching */ - nsteps = (int)((VecLenf(co, endco) / stepsize) + 0.5); - - VecSubf(stepvec, endco, co); - VecMulf(stepvec, 1.0f / nsteps); - VecCopyf(step_sta, co); - VecAddf(step_end, step_sta, stepvec); - - /* get radiance from all points along the ray due to participating media */ - for (s = 0; s < nsteps; s++) { - - density = vol_get_density(shi, step_sta); - - /* there's only any use in shading here if there's actually some density to shade! */ - if (density > 0.01f) { - - /* transmittance component (alpha) */ - vol_get_attenuation_seg(shi, tr, stepsize, co, density); - - step_mid[0] = step_sta[0] + (stepvec[0] * 0.5); - step_mid[1] = step_sta[1] + (stepvec[1] * 0.5); - step_mid[2] = step_sta[2] + (stepvec[2] * 0.5); - - /* incoming light via emission or scattering (additive) */ - vol_get_emission(shi, emit_col, step_mid, density); - - if (using_lightcache(shi->mat)) { - vol_get_precached_scattering(shi, scatter_col, step_mid); - } else - vol_get_scattering(shi, scatter_col, step_mid, stepsize, density); - - VecMulf(scatter_col, density); - VecAddf(d_radiance, emit_col, scatter_col); - - /* Lv += Tr * (Lve() + Ld) */ - VecMulVecf(d_radiance, tr, d_radiance); - VecMulf(d_radiance, stepsize); - - VecAddf(radiance, radiance, d_radiance); - } - - VecCopyf(step_sta, step_end); - VecAddf(step_end, step_end, stepvec); - - /* luminance rec. 709 */ - if ((0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]) < depth_cutoff) break; - } - - /* multiply original color (behind volume) with beam transmittance over entire distance */ - VecMulVecf(col, tr, col); - VecAddf(col, col, radiance); - - /* alpha <-- transmission luminance */ - col[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]); -} - -/* the main entry point for volume shading */ -static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume) -{ - float hitco[3], col[4] = {0.f,0.f,0.f,0.f}; - float *startco, *endco; - int trace_behind = 1; - const int ztransp= ((shi->depth==0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP)); - Isect is; - - /* check for shading an internal face a volume object directly */ - if (inside_volume == VOL_SHADE_INSIDE) - trace_behind = 0; - else if (inside_volume == VOL_SHADE_OUTSIDE) { - if (shi->flippednor) - inside_volume = VOL_SHADE_INSIDE; - } - - if (ztransp && inside_volume == VOL_SHADE_INSIDE) { - MatInside *mi; - int render_this=0; - - /* don't render the backfaces of ztransp volume materials. - - * volume shading renders the internal volume from between the - * near view intersection of the solid volume to the - * intersection on the other side, as part of the shading of - * the front face. - - * Because ztransp renders both front and back faces independently - * this will double up, so here we prevent rendering the backface as well, - * which would otherwise render the volume in between the camera and the backface - * --matt */ - - for (mi=R.render_volumes_inside.first; mi; mi=mi->next) { - /* weak... */ - if (mi->ma == shi->mat) render_this=1; - } - if (!render_this) return; - } - - - if (inside_volume == VOL_SHADE_INSIDE) - { - startco = shi->camera_co; - endco = shi->co; - - if (trace_behind) { - if (!ztransp) - /* trace behind the volume object */ - vol_trace_behind(shi, shi->vlr, endco, col); - } else { - /* we're tracing through the volume between the camera - * and a solid surface, so use that pre-shaded radiance */ - QUATCOPY(col, shr->combined); - } - - /* shade volume from 'camera' to 1st hit point */ - volumeintegrate(shi, col, startco, endco); - } - /* trace to find a backface, the other side bounds of the volume */ - /* (ray intersect ignores front faces here) */ - else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) - { - VlakRen *vlr = (VlakRen *)is.face; - - startco = shi->co; - endco = hitco; - - if (!ztransp) { - /* if it's another face in the same material */ - if (vlr->mat == shi->mat) { - /* trace behind the 2nd (raytrace) hit point */ - vol_trace_behind(shi, (VlakRen *)is.face, endco, col); - } else { - shade_intersection(shi, col, &is); - } - } - - /* shade volume from 1st hit point to 2nd hit point */ - volumeintegrate(shi, col, startco, endco); - } - - if (ztransp) - col[3] = col[3]>1.f?1.f:col[3]; - else - col[3] = 1.f; - - VecCopyf(shr->combined, col); - shr->alpha = col[3]; - - VECCOPY(shr->diff, shr->combined); -} - -/* Traces a shadow through the object, - * pretty much gets the transmission over a ray path */ -void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is) -{ - float hitco[3]; - float tr[3] = {1.0,1.0,1.0}; - Isect is; - float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE); - float *startco, *endco; - float density=0.f; - - memset(shr, 0, sizeof(ShadeResult)); - - /* if 1st hit normal is facing away from the camera, - * then we're inside the volume already. */ - if (shi->flippednor) { - startco = last_is->start; - endco = shi->co; - } - /* trace to find a backface, the other side bounds of the volume */ - /* (ray intersect ignores front faces here) */ - else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) { - startco = shi->co; - endco = hitco; - } - else { - shr->combined[0] = shr->combined[1] = shr->combined[2] = 0.f; - shr->alpha = shr->combined[3] = 1.f; - return; - } - - density = vol_get_density(shi, startco); - vol_get_attenuation(shi, tr, startco, endco, density, shade_stepsize); - - VecCopyf(shr->combined, tr); - shr->combined[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]); - shr->alpha = shr->combined[3]; -} - - -/* delivers a fully filled in ShadeResult, for all passes */ -void shade_volume_outside(ShadeInput *shi, ShadeResult *shr) -{ - memset(shr, 0, sizeof(ShadeResult)); - volume_trace(shi, shr, VOL_SHADE_OUTSIDE); -} - - -void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) -{ - MatInside *m; - Material *mat_backup; - - //if (BLI_countlist(&R.render_volumes_inside) == 0) return; - - /* XXX: extend to multiple volumes perhaps later */ - mat_backup = shi->mat; - m = R.render_volumes_inside.first; - shi->mat = m->ma; - - volume_trace(shi, shr, VOL_SHADE_INSIDE); - - shi->mat = mat_backup; -} ->>>>>>> .r22793 +} \ No newline at end of file -- cgit v1.2.3 From 7abb8c4bde4973ed84348c96102204abdf353187 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 26 Aug 2009 07:59:58 +0000 Subject: this was causing failed build when the file was missing --- source/creator/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 0d9d0fe8856..f563dec9575 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -139,7 +139,7 @@ IF(WITH_INSTALL) COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/site-packages COMMAND mkdir ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/site-packages # python needs it. - COMMAND rm ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/lib-dynload/_tkinter.so + COMMAND rm -f ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/lib-dynload/_tkinter.so COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "test" -prune -exec rm -rf {} "\;" COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "*.py?" -exec rm -rf {} "\;" COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "*.so"-exec strip -s {} "\;" -- cgit v1.2.3 From 36b85d4508106752b0595fcb5150fd19f90b8739 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Wed, 26 Aug 2009 08:09:29 +0000 Subject: Changed default audio device from SDL to OpenAL after a discussion in IRC, we're testing if OpenAL works flawlessly on all plattforms and if so we'll keep it as default device as it supports 3D Audio for the GE what SDL doesn't. --- source/blender/blenkernel/intern/sound.c | 13 +++---------- source/blender/blenloader/intern/readfile.c | 6 +++--- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index c6f9db6fda9..f6fb1ddcc5a 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -34,7 +34,7 @@ void sound_init() { AUD_Specs specs; - int device, buffersize, success; + int device, buffersize; device = U.audiodevice; buffersize = U.mixbufsize; @@ -54,15 +54,8 @@ void sound_init() if(specs.channels <= AUD_CHANNELS_INVALID) specs.channels = AUD_CHANNELS_STEREO; - if(!AUD_init(device, specs, buffersize)) { - if(device == AUD_SDL_DEVICE) - success= AUD_init(AUD_OPENAL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE*4); - else - success= AUD_init(AUD_SDL_DEVICE, specs, AUD_DEFAULT_BUFFER_SIZE*4); - - if(!success) - AUD_init(AUD_NULL_DEVICE, specs, buffersize); - } + if(!AUD_init(device, specs, buffersize)) + AUD_init(AUD_NULL_DEVICE, specs, buffersize); } void sound_exit() diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index aaba65b21af..877f23aad92 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9675,13 +9675,13 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->user->uifonts.first= bfd->user->uifonts.last= NULL; bfd->user->uistyles.first= bfd->user->uistyles.last= NULL; - // AUD_XXX + // AUD_XXX that's bad because if the user has saved No Audio, it changes to OpenAL always if(bfd->user->audiochannels == 0) bfd->user->audiochannels = 2; if(bfd->user->audiodevice == 0) - bfd->user->audiodevice = 1; + bfd->user->audiodevice = 2; if(bfd->user->audioformat == 0) - bfd->user->audioformat = 0x12; + bfd->user->audioformat = 0x24; if(bfd->user->audiorate == 0) bfd->user->audiorate = 44100; -- cgit v1.2.3 From adcb21b1f4b079f892e259446bab32c1bc74304f Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Wed, 26 Aug 2009 10:02:17 +0000 Subject: Close the old audio device before and not after opening the new. --- intern/audaspace/intern/AUD_C-API.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 9481e2139e8..995d4c5f99e 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -77,6 +77,9 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize) #endif AUD_IDevice* dev = NULL; + if(AUD_device) + AUD_exit(); + try { switch(device) @@ -107,9 +110,6 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize) return false; } - if(AUD_device) - AUD_exit(); - AUD_device = dev; if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE)) AUD_3ddevice = dynamic_cast(AUD_device); -- cgit v1.2.3 From 043ad7bc8e8e32161563798268727c1f42c9b3d6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 26 Aug 2009 12:01:15 +0000 Subject: 2.5 - Grease Pencil Version 2 (Crude rebirth) This commit is the start of the new Grease Pencil implementation. I've just ported the old code to make it work with operators, and to store its data in Grease-Pencil datablocks. However, this is currently still really buggy, with only the barebones of the drawing/creation tools restored (no UI panels, no options). To use (not recommended), use D+S+move_mouse (and click when finished) for now. There are some rather serious event handling errors going on here... --- source/blender/blenloader/intern/readfile.c | 4 + source/blender/editors/gpencil/drawgpencil.c | 9 +- source/blender/editors/gpencil/gpencil_edit.c | 3 + source/blender/editors/gpencil/gpencil_intern.h | 14 +- source/blender/editors/gpencil/gpencil_ops.c | 68 ++ source/blender/editors/gpencil/gpencil_paint.c | 1296 +++++++++++++++++++++ source/blender/editors/include/ED_gpencil.h | 14 +- source/blender/editors/space_api/spacetypes.c | 4 +- source/blender/editors/space_view3d/view3d_draw.c | 5 +- source/blender/editors/space_view3d/view3d_ops.c | 6 +- source/blender/makesdna/DNA_scene_types.h | 4 + 11 files changed, 1415 insertions(+), 12 deletions(-) create mode 100644 source/blender/editors/gpencil/gpencil_ops.c create mode 100644 source/blender/editors/gpencil/gpencil_paint.c diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 877f23aad92..913477198b8 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4042,6 +4042,7 @@ static void lib_link_scene(FileData *fd, Main *main) sce->world= newlibadr_us(fd, sce->id.lib, sce->world); sce->set= newlibadr(fd, sce->id.lib, sce->set); sce->ima= newlibadr_us(fd, sce->id.lib, sce->ima); + sce->gpd= newlibadr_us(fd, sce->id.lib, sce->gpd); link_paint(fd, sce, &sce->toolsettings->sculpt->paint); link_paint(fd, sce, &sce->toolsettings->vpaint->paint); @@ -10547,6 +10548,9 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) if(sce->r.dometext) expand_doit(fd, mainvar, sce->gm.dome.warptext); + + if(sce->gpd) + expand_doit(fd, mainvar, sce->gpd); } static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 735f1ffddb9..242be943507 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -933,7 +933,7 @@ void draw_gpencil_2dimage (bContext *C, ImBuf *ibuf) /* check that we have grease-pencil stuff to draw */ if (ELEM(NULL, sa, ibuf)) return; - gpd= gpencil_data_getactive(sa); + gpd= gpencil_data_getactive(C); if (gpd == NULL) return; /* calculate rect */ @@ -1007,7 +1007,7 @@ void draw_gpencil_2dview (bContext *C, short onlyv2d) /* check that we have grease-pencil stuff to draw */ if (sa == NULL) return; - gpd= gpencil_data_getactive(sa); + gpd= gpencil_data_getactive(C); if (gpd == NULL) return; /* draw it! */ @@ -1020,14 +1020,13 @@ void draw_gpencil_2dview (bContext *C, short onlyv2d) */ void draw_gpencil_3dview (bContext *C, short only3d) { - ScrArea *sa= CTX_wm_area(C); ARegion *ar= CTX_wm_region(C); Scene *scene= CTX_data_scene(C); bGPdata *gpd; int dflag = 0; /* check that we have grease-pencil stuff to draw */ - gpd= gpencil_data_getactive(sa); + gpd= gpencil_data_getactive(C); if (gpd == NULL) return; /* draw it! */ @@ -1047,7 +1046,7 @@ void draw_gpencil_oglrender (bContext *C) /* assume gpencil data comes from v3d */ if (v3d == NULL) return; - gpd= v3d->gpd; + gpd= gpencil_data_getactive(C); if (gpd == NULL) return; /* pass 1: draw 3d-strokes ------------ > */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index ef4e09274f2..4480da45572 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -25,6 +25,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#if 0 // XXX COMPILE GUARDS FOR OLD CODE + #include #include #include @@ -1697,3 +1699,4 @@ short gpencil_do_paint (bContext *C) } /* ************************************************** */ +#endif // XXX COMPILE GUARDS FOR OLD CODE diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 721d8544225..b134328c8a0 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -29,8 +29,20 @@ #define ED_GPENCIL_INTERN_H /* internal exports only */ + + +/* ***************************************************** */ +/* Operator Defines */ + +struct wmOperatorType; + +/* drawing ---------- */ + +void GPENCIL_OT_draw(struct wmOperatorType *ot); + + /******************************************************* */ -/* FILTERED ACTION DATA - TYPES */ +/* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */ /* XXX - TODO: replace this with the modern bAnimListElem... */ /* This struct defines a structure used for quick access */ diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c new file mode 100644 index 00000000000..cb6d66b2fcc --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -0,0 +1,68 @@ +/** + * $Id: gpencil_ops.c 21617 2009-07-16 04:45:52Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "BLI_blenlib.h" + +#include "DNA_windowmanager_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "gpencil_intern.h" + +/* ****************************************** */ +/* Generic Editing Keymap */ + +void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap) +{ + wmKeymapItem *km; + + /* if no keymap provided, use default */ + if (keymap == NULL) + keymap= WM_keymap_listbase(wm, "Grease Pencil Generic", 0, 0); + + /* Draw */ + WM_keymap_add_item(keymap, "GPENCIL_OT_draw", SKEY, KM_PRESS, 0, DKEY); +} + +/* ****************************************** */ + +void ED_operatortypes_gpencil (void) +{ + /* Drawing ----------------------- */ + WM_operatortype_append(GPENCIL_OT_draw); +} + +/* ****************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c new file mode 100644 index 00000000000..dc701924b3e --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -0,0 +1,1296 @@ +/* Grease Pencil - version 2 + * By Joshua Leung + */ + +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "BKE_gpencil.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#include "DNA_gpencil_types.h" +#include "DNA_action_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view2d_types.h" +#include "DNA_view3d_types.h" +#include "DNA_windowmanager_types.h" + +#include "UI_view2d.h" + +#include "ED_armature.h" +#include "ED_gpencil.h" +#include "ED_sequencer.h" +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "gpencil_intern.h" + +/* ******************************************* */ +/* Context Wrangling... */ + +/* Get the active Grease Pencil datablock */ +// TODO: move this to a gpencil_utils.c? +bGPdata *gpencil_data_getactive (bContext *C) +{ + Scene *scene= CTX_data_scene(C); + ScrArea *sa= CTX_wm_area(C); + + /* if there's an active area, check if the particular editor may + * have defined any special Grease Pencil context for editing... + */ + if (sa) { + switch (sa->spacetype) { + case SPACE_VIEW3D: /* 3D-View */ + { + Object *ob= CTX_data_active_object(C); + + /* just in case... */ + if (ob) { + /* depending on the mode of the object, we may be able to get some GP data + * from different elements - i.e. bones... + */ + if (ob->mode & OB_MODE_POSE) { + //bPoseChannel *pchan= CTX_data_active_pchan(C); + + /* if posechannel has GP data, use that... */ + //if (pchan && pchan->gpd) + // return pchan->gpd; + } + + /* still here, so check if active Object has GP data */ + //if (ob->gpd) + // return ob->gpd; + } + } + break; + + case SPACE_NODE: /* Nodes Editor */ + { + //SpaceNode *snode= (SpaceNode *)CTX_wm_space_data(C); + + /* return the GP data for the active node block/node */ + } + break; + + case SPACE_SEQ: /* Sequencer */ + { + //SpaceSeq *sseq= (SpaceSeq *)CTX_wm_space_data(C); + + /* return the GP data for the active strips/image/etc. */ + } + break; + } + } + + /* just fall back on the scene's GP data */ + return (scene) ? scene->gpd : NULL; +} + + +/* check if context is suitable for drawing */ +static int gpencil_draw_poll (bContext *C) +{ + // TODO: must check context for Grease Pencil data... + return 1; +} + +/* ******************************************* */ +/* 'Globals' and Defines */ + +/* Temporary 'Stroke' Operation data */ +typedef struct tGPsdata { + Scene *scene; /* current scene from context */ + ScrArea *sa; /* area where painting originated */ + ARegion *ar; /* region where painting originated */ + View2D *v2d; /* needed for GP_STROKE_2DSPACE */ + +#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 + + bGPdata *gpd; /* gp-datablock layer comes from */ + bGPDlayer *gpl; /* layer we're working on */ + bGPDframe *gpf; /* frame we're working on */ + + short status; /* current status of painting */ + short paintmode; /* mode for painting */ + + int mval[2]; /* current mouse-position */ + int mvalo[2]; /* previous recorded mouse-position */ + + float pressure; /* current stylus pressure */ + float opressure; /* previous stylus pressure */ + + short radius; /* radius of influence for eraser */ + short flags; /* flags that can get set during runtime */ +} tGPsdata; + +/* values for tGPsdata->status */ +enum { + GP_STATUS_NORMAL = 0, /* running normally */ + GP_STATUS_ERROR, /* something wasn't correctly set up */ + GP_STATUS_DONE /* painting done */ +}; + +/* values for tGPsdata->paintmode */ +enum { + GP_PAINTMODE_DRAW = 0, + GP_PAINTMODE_ERASER +}; + +/* Return flags for adding points to stroke buffer */ +enum { + GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */ + GP_STROKEADD_OVERFLOW = -1, /* error occurred - cannot fit any more points */ + GP_STROKEADD_NORMAL, /* point was successfully added */ + GP_STROKEADD_FULL /* cannot add any more points to buffer */ +}; + +/* Runtime flags */ +enum { + GP_PAINTFLAG_FIRSTRUN = (1<<0), /* operator just started */ + GP_PAINTFLAG_STRAIGHTLINES = (1<<1), /* only take the endpoints of a stroke */ +}; + +/* ------ */ + +/* maximum sizes of gp-session buffer */ +#define GP_STROKE_BUFFER_MAX 5000 + +/* Macros for accessing sensitivity thresholds... */ + /* minimum number of pixels mouse should move before new point created */ +#define MIN_MANHATTEN_PX (U.gp_manhattendist) + /* minimum length of new segment before new point can be added */ +#define MIN_EUCLIDEAN_PX (U.gp_euclideandist) + +/* macro to test if only converting endpoints - only for use when converting! */ +// XXX for now, don't test for editpaint too... +//#define GP_BUFFER2STROKE_ENDPOINTS ((gpd->flag & GP_DATA_EDITPAINT) && (p->flags & GP_PAINTFLAG_STRAIGHTLINES)) +#define GP_BUFFER2STROKE_ENDPOINTS ((p->flags & GP_PAINTFLAG_STRAIGHTLINES)) + +/* ------ */ +/* Forward defines for some functions... */ + +static void gp_session_validatebuffer(tGPsdata *p); + +/* ******************************************* */ +/* Calculations/Conversions */ + +/* Stroke Editing ---------------------------- */ + +/* check if the current mouse position is suitable for adding a new point */ +static short gp_stroke_filtermval (tGPsdata *p, int mval[2], int pmval[2]) +{ + int dx= abs(mval[0] - pmval[0]); + int dy= abs(mval[1] - pmval[1]); + + /* check if mouse moved at least certain distance on both axes (best case) */ + if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) + return 1; + + /* check if the distance since the last point is significant enough */ + // future optimisation: sqrt here may be too slow? + else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX) + return 1; + + /* mouse 'didn't move' */ + else + return 0; +} + +/* convert screen-coordinates to buffer-coordinates */ +// XXX this method needs a total overhaul! +static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) +{ + bGPdata *gpd= p->gpd; + + /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ + if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) { + View3D *v3d= p->sa->spacedata.first; + const short mx=mval[0], my=mval[1]; + float *fp= give_cursor(p->scene, v3d); // XXX NULL could be v3d + float dvec[3]; + + /* 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. + * + * TODO: + * - investigate using nearest point(s) on a previous stroke as + * reference point instead or as offset, for easier stroke matching + * - investigate projection onto geometry (ala retopo) + */ + + /* method taken from editview.c - mouse_cursor() */ + project_short_noclip(p->ar, fp, mval); + window_to_3d_delta(p->ar, dvec, mval[0]-mx, mval[1]-my); + VecSubf(out, fp, dvec); + } + + /* 2d - on 'canvas' (assume that p->v2d is set) */ + else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) { + float x, y; + + UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &x, &y); + + out[0]= x; + out[1]= y; + } + +#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 { + out[0] = (float)(mval[0]) / (float)(p->sa->winx) * 1000; + out[1] = (float)(mval[1]) / (float)(p->sa->winy) * 1000; + } +} + +/* add current stroke-point to buffer (returns whether point was successfully added) */ +static short gp_stroke_addpoint (tGPsdata *p, int mval[2], float pressure) +{ + bGPdata *gpd= p->gpd; + tGPspoint *pt; + + /* check if still room in buffer */ + if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX) + return GP_STROKEADD_OVERFLOW; + + /* get pointer to destination point */ + pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size); + + /* store settings */ + pt->x= mval[0]; + pt->y= mval[1]; + pt->pressure= pressure; + + /* increment counters */ + gpd->sbuffer_size++; + + /* check if another operation can still occur */ + if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX) + return GP_STROKEADD_FULL; + else + return GP_STROKEADD_NORMAL; +} + +/* smooth a stroke (in buffer) before storing it */ +static void gp_stroke_smooth (tGPsdata *p) +{ + bGPdata *gpd= p->gpd; + int i=0, cmx=gpd->sbuffer_size; + + /* only smooth if smoothing is enabled, and we're not doing a straight line */ + if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || GP_BUFFER2STROKE_ENDPOINTS) + return; + + /* don't try if less than 2 points in buffer */ + if ((cmx <= 2) || (gpd->sbuffer == NULL)) + return; + + /* apply weighting-average (note doing this along path sequentially does introduce slight error) */ + for (i=0; i < gpd->sbuffer_size; i++) { + tGPspoint *pc= (((tGPspoint *)gpd->sbuffer) + i); + tGPspoint *pb= (i-1 > 0)?(pc-1):(pc); + tGPspoint *pa= (i-2 > 0)?(pc-2):(pb); + tGPspoint *pd= (i+1 < cmx)?(pc+1):(pc); + tGPspoint *pe= (i+2 < cmx)?(pc+2):(pd); + + pc->x= (short)(0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x); + pc->y= (short)(0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y); + } +} + +/* simplify a stroke (in buffer) before storing it + * - applies a reverse Chaikin filter + * - code adapted from etch-a-ton branch (editarmature_sketch.c) + */ +static void gp_stroke_simplify (tGPsdata *p) +{ + bGPdata *gpd= p->gpd; + tGPspoint *old_points= (tGPspoint *)gpd->sbuffer; + short num_points= gpd->sbuffer_size; + short flag= gpd->sbuffer_sflag; + short i, j; + + /* only simplify if simlification is enabled, and we're not doing a straight line */ + if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || GP_BUFFER2STROKE_ENDPOINTS) + return; + + /* don't simplify if less than 4 points in buffer */ + if ((num_points <= 2) || (old_points == NULL)) + return; + + /* clear buffer (but don't free mem yet) so that we can write to it + * - firstly set sbuffer to NULL, so a new one is allocated + * - secondly, reset flag after, as it gets cleared auto + */ + gpd->sbuffer= NULL; + gp_session_validatebuffer(p); + gpd->sbuffer_sflag = flag; + +/* macro used in loop to get position of new point + * - used due to the mixture of datatypes in use here + */ +#define GP_SIMPLIFY_AVPOINT(offs, sfac) \ + { \ + co[0] += (float)(old_points[offs].x * sfac); \ + co[1] += (float)(old_points[offs].y * sfac); \ + pressure += old_points[offs].pressure * sfac; \ + } + + for (i = 0, j = 0; i < num_points; i++) + { + if (i - j == 3) + { + float co[2], pressure; + int mco[2]; + + /* initialise values */ + co[0]= 0; + co[1]= 0; + pressure = 0; + + /* using macro, calculate new point */ + GP_SIMPLIFY_AVPOINT(j, -0.25f); + GP_SIMPLIFY_AVPOINT(j+1, 0.75f); + GP_SIMPLIFY_AVPOINT(j+2, 0.75f); + GP_SIMPLIFY_AVPOINT(j+3, -0.25f); + + /* set values for adding */ + mco[0]= (int)co[0]; + mco[1]= (int)co[1]; + + /* ignore return values on this... assume to be ok for now */ + gp_stroke_addpoint(p, mco, pressure); + + j += 2; + } + } + + /* free old buffer */ + MEM_freeN(old_points); +} + + +/* make a new stroke from the buffer data */ +static void gp_stroke_newfrombuffer (tGPsdata *p) +{ + bGPdata *gpd= p->gpd; + bGPDstroke *gps; + bGPDspoint *pt; + tGPspoint *ptc; + int i, totelem; + + /* get total number of points to allocate space for: + * - in 'Draw Mode', holding the Ctrl-Modifier will only take endpoints + * - otherwise, do whole stroke + */ + if (GP_BUFFER2STROKE_ENDPOINTS) + totelem = (gpd->sbuffer_size >= 2) ? 2: gpd->sbuffer_size; + else + totelem = gpd->sbuffer_size; + + /* exit with error if no valid points from this stroke */ + if (totelem == 0) { + if (G.f & G_DEBUG) + printf("Error: No valid points in stroke buffer to convert (tot=%d) \n", gpd->sbuffer_size); + return; + } + + /* allocate memory for a new stroke */ + gps= MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + + /* allocate enough memory for a continuous array for storage points */ + pt= gps->points= MEM_callocN(sizeof(bGPDspoint)*totelem, "gp_stroke_points"); + + /* copy appropriate settings for stroke */ + gps->totpoints= totelem; + gps->thickness= p->gpl->thickness; + gps->flag= gpd->sbuffer_sflag; + + /* copy points from the buffer to the stroke */ + if (GP_BUFFER2STROKE_ENDPOINTS) { + /* 'Draw Mode' + Ctrl-Modifier - only endpoints */ + { + /* first point */ + ptc= gpd->sbuffer; + + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x); + + /* copy pressure */ + pt->pressure= ptc->pressure; + + pt++; + } + + if (totelem == 2) { + /* last point if applicable */ + ptc= ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1); + + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x); + + /* copy pressure */ + pt->pressure= ptc->pressure; + } + } + else { + /* convert all points (normal behaviour) */ + for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) { + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x); + + /* copy pressure */ + pt->pressure= ptc->pressure; + + pt++; + } + } + + /* add stroke to frame */ + BLI_addtail(&p->gpf->strokes, gps); +} + +/* --- 'Eraser' for 'Paint' Tool ------ */ + +/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */ +static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i) +{ + bGPDspoint *pt_tmp= gps->points; + bGPDstroke *gsn = NULL; + + /* if stroke only had two points, get rid of stroke */ + if (gps->totpoints == 2) { + /* free stroke points, then stroke */ + MEM_freeN(pt_tmp); + BLI_freelinkN(&gpf->strokes, gps); + + /* nothing left in stroke, so stop */ + return 1; + } + + /* if last segment, just remove segment from the stroke */ + else if (i == gps->totpoints - 2) { + /* allocate new points array, and assign most of the old stroke there */ + gps->totpoints--; + gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + /* nothing left in stroke, so stop */ + return 1; + } + + /* if first segment, just remove segment from the stroke */ + else if (i == 0) { + /* allocate new points array, and assign most of the old stroke there */ + gps->totpoints--; + gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + /* no break here, as there might still be stuff to remove in this stroke */ + return 0; + } + + /* segment occurs in 'middle' of stroke, so split */ + else { + /* duplicate stroke, and assign 'later' data to that stroke */ + gsn= MEM_dupallocN(gps); + gsn->prev= gsn->next= NULL; + BLI_insertlinkafter(&gpf->strokes, gps, gsn); + + gsn->totpoints= gps->totpoints - i; + gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points"); + memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints); + + /* adjust existing stroke */ + gps->totpoints= i; + gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + /* nothing left in stroke, so stop */ + return 1; + } +} + +/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */ +static short gp_stroke_eraser_strokeinside (int mval[], int mvalo[], short rad, short x0, short y0, short x1, short y1) +{ + /* simple within-radius check for now */ + if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1)) + return 1; + + /* not inside */ + return 0; +} + +/* eraser tool - evaluation per stroke */ +// TODO: this could really do with some optimisation (KD-Tree/BVH?) +static void gp_stroke_eraser_dostroke (tGPsdata *p, int mval[], int mvalo[], short rad, rcti *rect, bGPDframe *gpf, bGPDstroke *gps) +{ + bGPDspoint *pt1, *pt2; + int x0=0, y0=0, x1=0, y1=0; + short xyval[2]; + int i; + + if (gps->totpoints == 0) { + /* just free stroke */ + if (gps->points) + MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + } + else if (gps->totpoints == 1) { + /* get coordinates */ + if (gps->flag & GP_STROKE_3DSPACE) { + project_short(p->ar, &gps->points->x, xyval); + x0= xyval[0]; + y0= xyval[1]; + } + 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 { + x0= (int)(gps->points->x / 1000 * p->sa->winx); + y0= (int)(gps->points->y / 1000 * p->sa->winy); + } + + /* do boundbox check first */ + if (BLI_in_rcti(rect, x0, y0)) { + /* only check if point is inside */ + if ( ((x0-mval[0])*(x0-mval[0]) + (y0-mval[1])*(y0-mval[1])) <= rad*rad ) { + /* free stroke */ + MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + } + } + } + else { + /* loop over the points in the stroke, checking for intersections + * - an intersection will require the stroke to be split + */ + for (i=0; (i+1) < gps->totpoints; i++) { + /* get points to work with */ + pt1= gps->points + i; + pt2= gps->points + i + 1; + + /* get coordinates */ + if (gps->flag & GP_STROKE_3DSPACE) { + project_short(p->ar, &pt1->x, xyval); + x0= xyval[0]; + y0= xyval[1]; + + project_short(p->ar, &pt2->x, xyval); + x1= xyval[0]; + y1= xyval[1]; + } + else if (gps->flag & GP_STROKE_2DSPACE) { + UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0); + + 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 { + x0= (int)(pt1->x / 1000 * p->sa->winx); + y0= (int)(pt1->y / 1000 * p->sa->winy); + x1= (int)(pt2->x / 1000 * p->sa->winx); + y1= (int)(pt2->y / 1000 * p->sa->winy); + } + + /* check that point segment of the boundbox of the eraser stroke */ + if (BLI_in_rcti(rect, x0, y0) || BLI_in_rcti(rect, x1, y1)) { + /* check if point segment of stroke had anything to do with + * eraser region (either within stroke painted, or on its lines) + * - this assumes that linewidth is irrelevant + */ + if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) { + /* if function returns true, break this loop (as no more point to check) */ + if (gp_stroke_eraser_splitdel(gpf, gps, i)) + break; + } + } + } + } +} + +/* erase strokes which fall under the eraser strokes */ +static void gp_stroke_doeraser (tGPsdata *p) +{ + bGPDframe *gpf= p->gpf; + bGPDstroke *gps, *gpn; + rcti rect; + + /* rect is rectangle of eraser */ + rect.xmin= p->mval[0] - p->radius; + rect.ymin= p->mval[1] - p->radius; + rect.xmax= p->mval[0] + p->radius; + rect.ymax= p->mval[1] + p->radius; + + /* loop over strokes, checking segments for intersections */ + for (gps= gpf->strokes.first; gps; gps= gpn) { + gpn= gps->next; + gp_stroke_eraser_dostroke(p, p->mval, p->mvalo, p->radius, &rect, gpf, gps); + } +} + +/* ******************************************* */ +/* Sketching Operator */ + +/* clear the session buffers (call this before AND after a paint operation) */ +static void gp_session_validatebuffer (tGPsdata *p) +{ + bGPdata *gpd= p->gpd; + + /* clear memory of buffer (or allocate it if starting a new session) */ + if (gpd->sbuffer) + memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX); + else + gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); + + /* reset indices */ + gpd->sbuffer_size = 0; + + /* reset flags */ + gpd->sbuffer_sflag= 0; +} + +/* init new painting session */ +static tGPsdata *gp_session_initpaint (bContext *C) +{ + tGPsdata *p = NULL; + ScrArea *curarea= CTX_wm_area(C); + ARegion *ar= CTX_wm_region(C); + + /* make sure the active view (at the starting time) is a 3d-view */ + if (curarea == NULL) { + if (G.f & G_DEBUG) + printf("Error: No active view for painting \n"); + return NULL; + } + + /* create new context data */ + p= MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data"); + + /* pass on current scene */ + p->scene= CTX_data_scene(C); + + switch (curarea->spacetype) { + /* supported views first */ + case SPACE_VIEW3D: + { + //View3D *v3d= curarea->spacedata.first; + + /* set current area */ + p->sa= curarea; + p->ar= ar; + +#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.f & G_DEBUG) + printf("Error: In active view, Grease Pencil not shown \n"); + return p; + } +#endif + } + break; +#if 0 // XXX these other spaces will come over time... + case SPACE_NODE: + { + SpaceNode *snode= curarea->spacedata.first; + + /* set current area */ + p->sa= curarea; + p->ar= ar; + p->v2d= &ar->v2d; + + /* check that gpencil data is allowed to be drawn */ + if ((snode->flag & SNODE_DISPGP)==0) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: In active view, Grease Pencil not shown \n"); + return; + } + } + break; + case SPACE_SEQ: + { + SpaceSeq *sseq= curarea->spacedata.first; + + /* set current area */ + p->sa= curarea; + p->ar= ar; + p->v2d= &ar->v2d; + + /* check that gpencil data is allowed to be drawn */ + if (sseq->mainb == SEQ_DRAW_SEQUENCE) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil \n"); + return; + } + if ((sseq->flag & SEQ_DRAW_GPENCIL)==0) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: In active view, Grease Pencil not shown \n"); + return; + } + } + break; + case SPACE_IMAGE: + { + SpaceImage *sima= 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); + + /* check that gpencil data is allowed to be drawn */ + if ((sima->flag & SI_DISPGP)==0) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: In active view, Grease Pencil not shown \n"); + return; + } + } + break; +#endif + /* unsupported views */ + default: + { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: Active view not appropriate for Grease Pencil drawing \n"); + return p; + } + break; + } + + /* get gp-data */ + p->gpd= gpencil_data_getactive(C); + if (p->gpd == NULL) { + /* add new GPencil block for the active scene for now... */ + p->gpd= gpencil_data_addnew("GPencil"); + p->scene->gpd= p->gpd; + } + + /* set edit flags */ + G.f |= G_GREASEPENCIL; + + /* set initial run flag */ + p->flags |= GP_PAINTFLAG_FIRSTRUN; + + /* 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 context data for running paint operator */ + return p; +} + +/* cleanup after a painting session */ +static void gp_session_cleanup (tGPsdata *p) +{ + bGPdata *gpd= (p) ? p->gpd : NULL; + + /* error checking */ + if (gpd == NULL) + return; + + /* free stroke buffer */ + if (gpd->sbuffer) { + MEM_freeN(gpd->sbuffer); + gpd->sbuffer= NULL; + } + + /* clear flags */ + gpd->sbuffer_size= 0; + gpd->sbuffer_sflag= 0; +} + +/* init new stroke */ +static void gp_paint_initstroke (tGPsdata *p, short paintmode) +{ + /* get active layer (or add a new one if non-existent) */ + p->gpl= gpencil_layer_getactive(p->gpd); + if (p->gpl == NULL) + p->gpl= gpencil_layer_addnew(p->gpd); + if (p->gpl->flag & GP_LAYER_LOCKED) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: Cannot paint on locked layer \n"); + return; + } + + /* get active frame (add a new one if not matching frame) */ + p->gpf= gpencil_layer_getframe(p->gpl, p->scene->r.cfra, 1); + if (p->gpf == NULL) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: No frame created (gpencil_paint_init) \n"); + return; + } + else + p->gpf->flag |= GP_FRAME_PAINT; + + /* set 'eraser' for this stroke if using eraser */ + p->paintmode= paintmode; + if (p->paintmode == GP_PAINTMODE_ERASER) + p->gpd->sbuffer_sflag |= GP_STROKE_ERASER; + + /* check if points will need to be made in view-aligned space */ + // XXX this should be the default? this is something that needs review + /*if (p->gpd->flag & GP_DATA_VIEWALIGN)*/ { + switch (p->sa->spacetype) { + case SPACE_VIEW3D: + { + View3D *v3d= (View3D *)p->sa->spacedata.first; + RegionView3D *rv3d= p->ar->regiondata; + + // TODO: this should only happen for scene... otherwise use object center! + float *fp= give_cursor(p->scene, v3d); + initgrabz(rv3d, fp[0], fp[1], fp[2]); + + p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE; + } + break; +#if 0 // XXX other spacetypes to be restored in due course + case SPACE_NODE: + { + p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + } + break; + 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 * ((float)p->scene->r.xasp / (float)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); + } + break; + case SPACE_IMAGE: + { + /* check if any ibuf available */ + if (p->ibuf) + p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + } + break; +#endif + } + } +} + +/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */ +static void gp_paint_strokeend (tGPsdata *p) +{ + /* check if doing eraser or not */ + if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) { + /* smooth stroke before transferring? */ + gp_stroke_smooth(p); + + /* simplify stroke before transferring? */ + gp_stroke_simplify(p); + + /* transfer stroke to frame */ + gp_stroke_newfrombuffer(p); + } + + /* clean up buffer now */ + gp_session_validatebuffer(p); +} + +/* finish off stroke painting operation */ +static void gp_paint_cleanup (tGPsdata *p) +{ + /* finish off a stroke */ + gp_paint_strokeend(p); + + /* "unlock" frame */ + p->gpf->flag &= ~GP_FRAME_PAINT; +} + +/* ------------------------------- */ + + +static int gpencil_draw_init (bContext *C, wmOperator *op) +{ + tGPsdata *p; + int paintmode= RNA_enum_get(op->ptr, "mode"); + + /* check context */ + p= op->customdata= gp_session_initpaint(C); + if ((p == NULL) || (p->status == GP_STATUS_ERROR)) { + /* something wasn't set correctly in context */ + gp_session_cleanup(p); + return 0; + } + + /* init painting data */ + gp_paint_initstroke(p, paintmode); + if (p->status == GP_STATUS_ERROR) { + gp_session_cleanup(p); + return 0; + } + + /* radius for eraser circle is defined in userprefs now */ + // TODO: make this more easily tweaked... + p->radius= U.gp_eraser; + + /* everything is now setup ok */ + return 1; +} + +/* ------------------------------- */ + +static void gpencil_draw_exit (bContext *C, wmOperator *op) +{ + tGPsdata *p= op->customdata; + + /* clear edit flags */ + G.f &= ~G_GREASEPENCIL; + + /* restore cursor to indicate end of drawing */ + // XXX (cursor callbacks in regiontype) setcursor_space(p.sa->spacetype, CURSOR_STD); + + /* 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); + } + + /* cleanup */ + gp_paint_cleanup(p); + gp_session_cleanup(p); + + /* finally, free the temp data */ + MEM_freeN(p); + op->customdata= NULL; +} + +static int gpencil_draw_cancel (bContext *C, wmOperator *op) +{ + /* this is just a wrapper around exit() */ + gpencil_draw_exit(C, op); + return OPERATOR_CANCELLED; +} + +/* ------------------------------- */ + +static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *event) +{ + tGPsdata *p= op->customdata; + ARegion *ar= p->ar; + 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... + p->mval[0]= event->x - ar->winrct.xmin + 1; + p->mval[1]= event->y - ar->winrct.ymin + 1; + + /* handle pressure sensitivity (which is supplied by tablets) */ + if (event->custom == EVT_DATA_TABLET) { + wmTabletData *wmtab= event->customdata; + + tablet= (wmtab->Active != EVT_TABLET_NONE); + p->pressure= wmtab->Pressure; + //if (wmtab->Active == EVT_TABLET_ERASER) + // TODO... this should get caught by the keymaps which call drawing in the first place + } + else + p->pressure= 1.0f; + + /* special exception for start of strokes (i.e. maybe for just a dot) */ + if (p->flags & GP_PAINTFLAG_FIRSTRUN) { + p->flags &= ~GP_PAINTFLAG_FIRSTRUN; + + p->mvalo[0]= p->mval[0]; + p->mvalo[1]= p->mval[1]; + p->opressure= p->pressure; + + /* special exception here for too high pressure values on first touch in + * windows for some tablets, then we just skip first touch .. + */ + if (tablet && (p->pressure >= 0.99f)) + return; + } + + + /* handle drawing/erasing -> test for erasing first */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + /* do 'live' erasing now */ + gp_stroke_doeraser(p); + + /* store used values */ + p->mvalo[0]= p->mval[0]; + p->mvalo[1]= p->mval[1]; + p->opressure= p->pressure; + } + /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ + else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { + /* try to add point */ + short ok= gp_stroke_addpoint(p, p->mval, p->pressure); + + /* handle errors while adding point */ + if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { + /* finish off old stroke */ + gp_paint_strokeend(p); + + /* start a new stroke, starting from previous point */ + gp_stroke_addpoint(p, p->mvalo, p->opressure); + ok= gp_stroke_addpoint(p, p->mval, p->pressure); + } + else if (ok == GP_STROKEADD_INVALID) { + /* the painting operation cannot continue... */ + BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke"); + p->status = GP_STATUS_ERROR; + + if (G.f & G_DEBUG) + printf("Error: Grease-Pencil Paint - Add Point Invalid \n"); + // XXX break! + } + + /* store used values */ + p->mvalo[0]= p->mval[0]; + p->mvalo[1]= p->mval[1]; + p->opressure= p->pressure; + } + + /* force refresh */ + ED_area_tag_redraw(p->sa); // XXX this is crude +} + +/* ------------------------------- */ + +static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) +{ + tGPsdata *p = NULL; + + printf("GPencil - Starting Drawing \n"); + + /* try to initialise context data needed while drawing */ + if (!gpencil_draw_init(C, op)) { + if (op->customdata) MEM_freeN(op->customdata); + printf("\tGP - no valid data \n"); + return OPERATOR_CANCELLED; + } + else + p= op->customdata; + + // TODO: set any additional settings that we can take from the events? + // TODO? if tablet is erasing, force eraser to be on? + + /* 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.. + } + + printf("\tGP - set first spot\n"); + + /* handle the initial drawing - i.e. for just doing a simple dot */ + gpencil_draw_apply_event(C, op, event); + + /* add a modal handler for this operator, so that we can then draw continuous strokes */ + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + return OPERATOR_RUNNING_MODAL; +} + +static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) +{ + tGPsdata *p= op->customdata; + + printf("\tGP - handle modal event...\n"); + + switch (event->type) { + /* moving mouse - assumed that mouse button is down */ + case MOUSEMOVE: + /* handle drawing event */ + printf("\t\tGP - add point\n"); + gpencil_draw_apply_event(C, op, event); + + /* finish painting operation if anything went wrong just now */ + if (p->status == GP_STATUS_ERROR) { + printf("\t\t\tGP - error done! \n"); + gpencil_draw_exit(C, op); + return OPERATOR_CANCELLED; + } + break; + + /* end of stroke - i.e. when a mouse-button release occurs */ + case LEFTMOUSE: + case MIDDLEMOUSE: + case RIGHTMOUSE: + printf("\t\tGP - end of stroke \n"); + gpencil_draw_exit(C, op); + return OPERATOR_FINISHED; + + /* scrolling mouse-wheel increases radius of eraser + * - though this is quite a difficult action to perform + */ + case WHEELUPMOUSE: + p->radius += 1.5f; + break; + case WHEELDOWNMOUSE: + p->radius -= 1.5f; + break; + + /* handle ctrl key - used to toggle straight-lines only (for drawing) */ + // XXX hardcoded keymap stuff + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + if (event->val == KM_PRESS) + p->flags |= GP_PAINTFLAG_STRAIGHTLINES; + else if (event->val == KM_RELEASE) + p->flags &= ~GP_PAINTFLAG_STRAIGHTLINES; + break; + + default: + return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +/* ------------------------------- */ + +static EnumPropertyItem prop_gpencil_drawmodes[] = { + {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw", ""}, + {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""}, + {0, NULL, 0, NULL, NULL} +}; + +void GPENCIL_OT_draw (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Grease Pencil Draw"; + ot->idname= "GPENCIL_OT_draw"; + ot->description= "Make annotations on the active data."; + + /* api callbacks */ + //ot->exec= gpencil_draw_exec; + ot->invoke= gpencil_draw_invoke; + ot->modal= gpencil_draw_modal; + ot->cancel= gpencil_draw_cancel; + ot->poll= gpencil_draw_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + /* settings for drawing */ + RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to intepret mouse movements."); +} diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index ad8124c89d7..c1e37ce2e81 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -41,7 +41,7 @@ struct bGPDframe; struct bGPdata; struct uiBlock; struct ImBuf; - +struct wmWindowManager; /* ------------- Grease-Pencil Helpers -------------- */ @@ -52,9 +52,19 @@ typedef struct tGPspoint { float pressure; /* pressure of tablet at this point */ } tGPspoint; +/* ----------- Grease Pencil New Tools ------------- */ + +struct bGPdata *gpencil_data_getactive(struct bContext *C); + +/* ----------- Grease Pencil Operators ------------- */ + +void gpencil_common_keymap(struct wmWindowManager *wm, ListBase *keymap); + +void ED_operatortypes_gpencil(void); + /* ------------ Grease-Pencil Depreceated Stuff ------------------ */ -struct bGPdata *gpencil_data_getactive(struct ScrArea *sa); +//struct bGPdata *gpencil_data_getactive(struct ScrArea *sa); short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd); struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 041e6a09323..61b6fe391ae 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -42,6 +42,7 @@ #include "ED_anim_api.h" #include "ED_armature.h" #include "ED_curve.h" +#include "ED_gpencil.h" #include "ED_markers.h" #include "ED_mesh.h" #include "ED_object.h" @@ -83,7 +84,7 @@ void ED_spacetypes_init(void) /* register operator types for screen and all spaces */ ED_operatortypes_screen(); ED_operatortypes_anim(); - ED_operatortypes_animchannels(); // XXX have this as part of anim() ones instead? + ED_operatortypes_animchannels(); ED_operatortypes_object(); ED_operatortypes_mesh(); ED_operatortypes_sculpt(); @@ -97,6 +98,7 @@ void ED_spacetypes_init(void) ED_operatortypes_fluid(); ED_operatortypes_metaball(); ED_operatortypes_boids(); + ED_operatortypes_gpencil(); ui_view2d_operatortypes(); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 905657910b8..07ffb35f807 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -78,6 +78,7 @@ #include "ED_armature.h" #include "ED_keyframing.h" +#include "ED_gpencil.h" #include "ED_mesh.h" #include "ED_screen.h" #include "ED_space_api.h" @@ -2082,8 +2083,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) } /* draw grease-pencil stuff */ -// if (v3d->flag2 & V3D_DISPGP) -// draw_gpencil_3dview(ar, 1); + //if (v3d->flag2 & V3D_DISPGP) + draw_gpencil_3dview(C, 1); BDR_drawSketch(C); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index e9d1f6406b0..19a70834587 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -52,6 +52,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_gpencil.h" #include "ED_screen.h" #include "ED_transform.h" @@ -131,7 +132,10 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0); km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0); RNA_boolean_set(km->ptr, "snap", 1); - + + /* grease pencil */ + gpencil_common_keymap(wm, keymap); // XXX + WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/ WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 9161157f597..20429120812 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -48,6 +48,7 @@ struct bNodeTree; struct AnimData; struct Editing; struct SceneStats; +struct bGPdata; typedef struct Base { struct Base *next, *prev; @@ -718,6 +719,9 @@ typedef struct Scene { /* Units */ struct UnitSettings unit; + + /* Grease Pencil */ + struct bGPdata *gpd; } Scene; -- cgit v1.2.3 From c97d964064bfb9d64e3f866f62095ccdc32a80fd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 26 Aug 2009 12:51:27 +0000 Subject: - Add remove game properties now possible from the logic space properties panel. - PyDebugLine, utility function to run if the BGE crashes, you can see which python file and line called the C/C++ code. --- release/ui/space_logic.py | 13 +++-- source/blender/editors/object/object_edit.c | 69 ++++++++++++++++++++++++++ source/blender/editors/object/object_intern.h | 3 ++ source/blender/editors/object/object_ops.c | 3 ++ source/gameengine/Expressions/PyObjectPlus.cpp | 68 +++++++++++++------------ 5 files changed, 119 insertions(+), 37 deletions(-) diff --git a/release/ui/space_logic.py b/release/ui/space_logic.py index 68ddceb8534..f9920f78497 100644 --- a/release/ui/space_logic.py +++ b/release/ui/space_logic.py @@ -14,12 +14,17 @@ class LOGIC_PT_properties(bpy.types.Panel): ob = context.active_object game = ob.game - for prop in game.properties: - flow = layout.row() + for i, prop in enumerate(game.properties): + flow = layout.row(align=True) flow.itemR(prop, "name", text="") flow.itemR(prop, "type", text="") flow.itemR(prop, "value", text="") # we dont care about the type. rna will display correctly - flow.itemR(prop, "debug") + flow.itemR(prop, "debug", text="", toggle=True, icon='ICON_INFO') + flow.item_intO("object.game_property_remove", "index", i, text="", icon='ICON_X') + + flow = layout.row() + flow.itemO("object.game_property_new") + + bpy.types.register(LOGIC_PT_properties) - diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 3d2ddba3757..4b7d3474d98 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -7161,3 +7161,72 @@ void ED_object_toggle_modes(bContext *C, int mode) if(mode & OB_MODE_PARTICLE_EDIT) WM_operator_name_call(C, "PARTICLE_OT_particle_edit_toggle", WM_OP_EXEC_REGION_WIN, NULL); } + +/* game property ops */ + +static int game_property_new(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + bProperty *prop; + + if(!ob) + return OPERATOR_CANCELLED; + + prop= new_property(PROP_FLOAT); + BLI_addtail(&ob->prop, prop); + unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name); + + return OPERATOR_FINISHED; +} + + +void OBJECT_OT_game_property_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New Game Property"; + ot->idname= "OBJECT_OT_game_property_new"; + + /* api callbacks */ + ot->exec= game_property_new; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int game_property_remove(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + bProperty *prop; + int index; + + if(!ob) + return OPERATOR_CANCELLED; + + index = RNA_int_get(op->ptr, "index"); + + prop= BLI_findlink(&ob->prop, index); + + if(prop) { + BLI_remlink(&ob->prop, prop); + free_property(prop); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_game_property_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Game Property"; + ot->idname= "OBJECT_OT_game_property_remove"; + + /* api callbacks */ + ot->exec= game_property_remove; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to remove ", 0, INT_MAX); +} diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 2f164102be2..82bbb34f59a 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -147,6 +147,9 @@ void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); +void OBJECT_OT_game_property_new(struct wmOperatorType *ot); +void OBJECT_OT_game_property_remove(struct wmOperatorType *ot); + /* editkey.c */ void OBJECT_OT_shape_key_add(struct wmOperatorType *ot); void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 239b162c14f..73dad7895a1 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -150,6 +150,9 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); WM_operatortype_append(OBJECT_OT_vertex_group_copy); + WM_operatortype_append(OBJECT_OT_game_property_new); + WM_operatortype_append(OBJECT_OT_game_property_remove); + WM_operatortype_append(OBJECT_OT_shape_key_add); WM_operatortype_append(OBJECT_OT_shape_key_remove); diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 5be703f0fa4..99c943d4f24 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -906,45 +906,47 @@ void PyObjectPlus::SetDeprecationWarnings(bool ignoreDeprecationWarnings) m_ignore_deprecation_warnings = ignoreDeprecationWarnings; } -void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* new_way) +void PyDebugLine() { - { - printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way); - - // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno) - - PyObject *getframe, *frame; - PyObject *f_lineno, *f_code, *co_filename; - - getframe = PySys_GetObject((char *)"_getframe"); // borrowed - if (getframe) { - frame = PyObject_CallObject(getframe, NULL); - if (frame) { - f_lineno= PyObject_GetAttrString(frame, "f_lineno"); - f_code= PyObject_GetAttrString(frame, "f_code"); - if (f_lineno && f_code) { - co_filename= PyObject_GetAttrString(f_code, "co_filename"); - if (co_filename) { - - printf("\t%s:%d\n", _PyUnicode_AsString(co_filename), (int)PyLong_AsSsize_t(f_lineno)); - - Py_DECREF(f_lineno); - Py_DECREF(f_code); - Py_DECREF(co_filename); - Py_DECREF(frame); - return; - } + // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno) + + PyObject *getframe, *frame; + PyObject *f_lineno, *f_code, *co_filename; + + getframe = PySys_GetObject((char *)"_getframe"); // borrowed + if (getframe) { + frame = PyObject_CallObject(getframe, NULL); + if (frame) { + f_lineno= PyObject_GetAttrString(frame, "f_lineno"); + f_code= PyObject_GetAttrString(frame, "f_code"); + if (f_lineno && f_code) { + co_filename= PyObject_GetAttrString(f_code, "co_filename"); + if (co_filename) { + + printf("\t%s:%d\n", _PyUnicode_AsString(co_filename), (int)PyLong_AsSsize_t(f_lineno)); + + Py_DECREF(f_lineno); + Py_DECREF(f_code); + Py_DECREF(co_filename); + Py_DECREF(frame); + return; } - - Py_XDECREF(f_lineno); - Py_XDECREF(f_code); - Py_DECREF(frame); } + Py_XDECREF(f_lineno); + Py_XDECREF(f_code); + Py_DECREF(frame); } - PyErr_Clear(); - printf("\tERROR - Could not access sys._getframe(0).f_lineno or sys._getframe().f_code.co_filename\n"); + } + PyErr_Clear(); + printf("\tERROR - Could not access sys._getframe(0).f_lineno or sys._getframe().f_code.co_filename\n"); +} + +void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* new_way) +{ + printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way); + PyDebugLine(); } void PyObjectPlus::ClearDeprecationWarning() -- cgit v1.2.3 From 47ce314bc5be90f63799c43805ef509c22d7fcf2 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Wed, 26 Aug 2009 14:19:29 +0000 Subject: 2.5 Sound: - Cleaned up DNA_sound_types.h, especially the bSound structure. - Fixed a caching bug. --- source/blender/blenkernel/intern/sequence.c | 2 +- source/blender/blenkernel/intern/sound.c | 67 +++++++------ source/blender/blenloader/intern/readfile.c | 8 +- .../editors/space_sequencer/sequencer_add.c | 4 +- .../editors/space_sequencer/sequencer_draw.c | 106 --------------------- source/blender/makesdna/DNA_sound_types.h | 77 +++++++-------- .../gameengine/Converter/KX_ConvertActuators.cpp | 2 +- 7 files changed, 79 insertions(+), 187 deletions(-) diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c index 159a60ad3af..c6b714c3125 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequence.c @@ -570,7 +570,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq) } seq->strip->len = seq->len; } else if (seq->type == SEQ_SOUND) { - seq->len = AUD_getInfo(seq->sound->snd_sound).length * FPS; + seq->len = AUD_getInfo(seq->sound->handle).length * FPS; seq->len -= seq->anim_startofs; seq->len -= seq->anim_endofs; if (seq->len < 0) { diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index f6fb1ddcc5a..070b5786a74 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -79,11 +79,11 @@ struct bSound* sound_new_file(struct Main *main, char* filename) sound = alloc_libblock(&main->sound, ID_SO, filename+len); strcpy(sound->name, filename); - sound->type = SOUND_TYPE_FILE; +// XXX unused currently sound->type = SOUND_TYPE_FILE; sound_load(main, sound); - if(!sound->snd_sound) + if(!sound->handle) { free_libblock(&main->sound, sound); sound = NULL; @@ -109,7 +109,7 @@ struct bSound* sound_new_buffer(struct bContext *C, struct bSound *source) sound_load(CTX_data_main(C), sound); - if(!sound->snd_sound) + if(!sound->handle) { free_libblock(&CTX_data_main(C)->sound, sound); sound = NULL; @@ -135,7 +135,7 @@ struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, floa sound_load(CTX_data_main(C), sound); - if(!sound->snd_sound) + if(!sound->handle) { free_libblock(&CTX_data_main(C)->sound, sound); sound = NULL; @@ -162,22 +162,25 @@ void sound_cache(struct bSound* sound, int ignore) if(sound->cache && !ignore) AUD_unload(sound->cache); - sound->cache = AUD_bufferSound(sound->snd_sound); + sound->cache = AUD_bufferSound(sound->handle); } void sound_load(struct Main *main, struct bSound* sound) { if(sound) { - if(sound->snd_sound) + if(sound->handle) { - AUD_unload(sound->snd_sound); - sound->snd_sound = NULL; + AUD_unload(sound->handle); + sound->handle = NULL; } +// XXX unused currently +#if 0 switch(sound->type) { case SOUND_TYPE_FILE: +#endif { char fullpath[FILE_MAX]; char *path; @@ -197,26 +200,25 @@ void sound_load(struct Main *main, struct bSound* sound) /* but we need a packed file then */ if (pf) - sound->snd_sound = AUD_loadBuffer((unsigned char*) pf->data, pf->size); + sound->handle = AUD_loadBuffer((unsigned char*) pf->data, pf->size); /* or else load it from disk */ else - sound->snd_sound = AUD_load(fullpath); + sound->handle = AUD_load(fullpath); + } // XXX +// XXX unused currently +#if 0 break; } case SOUND_TYPE_BUFFER: - if(sound->child_sound && sound->child_sound->snd_sound) - sound->snd_sound = AUD_bufferSound(sound->child_sound->snd_sound); + if(sound->child_sound && sound->child_sound->handle) + sound->handle = AUD_bufferSound(sound->child_sound->handle); break; case SOUND_TYPE_LIMITER: - if(sound->child_sound && sound->child_sound->snd_sound) - sound->snd_sound = AUD_limitSound(sound->child_sound, sound->start, sound->end); + if(sound->child_sound && sound->child_sound->handle) + sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end); break; } - - if(sound->cache) - { - - } +#endif } } @@ -228,10 +230,10 @@ void sound_free(struct bSound* sound) sound->packedfile = NULL; } - if(sound->snd_sound) + if(sound->handle) { - AUD_unload(sound->snd_sound); - sound->snd_sound = NULL; + AUD_unload(sound->handle); + sound->handle = NULL; } } @@ -241,20 +243,23 @@ void sound_unlink(struct bContext *C, struct bSound* sound) Scene *scene; SoundHandle *handle; +// XXX unused currently +#if 0 for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next) { if(snd->child_sound == sound) { snd->child_sound = NULL; - if(snd->snd_sound) + if(snd->handle) { - AUD_unload(sound->snd_sound); - snd->snd_sound = NULL; + AUD_unload(sound->handle); + snd->handle = NULL; } sound_unlink(C, snd); } } +#endif for(scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next) { @@ -372,9 +377,9 @@ void sound_update_playing(struct bContext *C) { if(handle->state == AUD_STATUS_INVALID) { - if(handle->source && handle->source->snd_sound) + if(handle->source && handle->source->handle) { - AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps); + AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, handle->frameskip / fps, (handle->frameskip + handle->endframe - handle->startframe)/fps); handle->handle = AUD_play(limiter, 1); AUD_unload(limiter); if(handle->handle) @@ -413,10 +418,10 @@ void sound_scrub(struct bContext *C) { if(cfra >= handle->startframe && cfra < handle->endframe && !handle->mute) { - if(handle->source && handle->source->snd_sound) + if(handle->source && handle->source->handle) { int frameskip = handle->frameskip + cfra - handle->startframe; - AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->snd_sound, frameskip / fps, (frameskip + 1)/fps); + AUD_Sound* limiter = AUD_limitSound(handle->source->cache ? handle->source->cache : handle->source->handle, frameskip / fps, (frameskip + 1)/fps); AUD_play(limiter, 0); AUD_unload(limiter); } @@ -439,7 +444,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e for(handle = scene->sound_handles.first; handle; handle = handle->next) { - if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->snd_sound) + if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->handle) { frameskip = handle->frameskip; s = handle->startframe - start; @@ -451,7 +456,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e s = 0; } - limiter = AUD_limitSound(handle->source->snd_sound, frameskip / fps, e / fps); + limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps); delayer = AUD_delaySound(limiter, s / fps); AUD_playDevice(mixdown, delayer); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 913477198b8..6771135a772 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5061,10 +5061,13 @@ static void fix_relpaths_library(const char *basepath, Main *main) static void direct_link_sound(FileData *fd, bSound *sound) { - sound->snd_sound = NULL; + sound->handle = NULL; sound->packedfile = direct_link_packedfile(fd, sound->packedfile); sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile); + + if(sound->cache) + sound_cache(sound, 1); } static void lib_link_sound(FileData *fd, Main *main) @@ -5076,8 +5079,7 @@ static void lib_link_sound(FileData *fd, Main *main) if(sound->id.flag & LIB_NEEDLINK) { sound->id.flag -= LIB_NEEDLINK; sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system - sound->stream = 0; - + sound_load(main, sound); } sound= sound->id.next; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index bdedef4b6c8..e6d50976957 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -242,13 +242,13 @@ static Sequence* sequencer_add_sound_strip(bContext *C, wmOperator *op, int star sound = sound_new_file(CTX_data_main(C), filename); - if (sound==NULL || sound->snd_sound == NULL) { + if (sound==NULL || sound->handle == NULL) { if(op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); return NULL; } - info = AUD_getInfo(sound->snd_sound); + info = AUD_getInfo(sound->handle); if (info.specs.format == AUD_FORMAT_INVALID) { sound_delete(C, sound); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 367bfb68208..76bed3772b1 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -225,108 +225,6 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, } } -static void drawseqwave(Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, int winx) -{ - /* - x1 is the starting x value to draw the wave, - x2 the end x value, same for y1 and y2 - winx is the zoom level. - */ - - float - f, /* floating point value used to store the X draw location for the wave lines when openGL drawing*/ - midy, /* fast access to the middle location (y1+y2)/2 */ - clipxmin, /* the minimum X value, clip this with the window */ - clipxmax, /* the maximum X value, clip this with the window */ - sample_step, /* steps to move per sample, floating value must later translate into an int */ - fsofs, /* steps to move per sample, floating value must later translate into an int */ - feofs_sofs, /* */ - sound_width, /* convenience: x2-x1 */ - wavemulti; /* scale the samples by this value when GL_LINE drawing so it renders the right height */ - - int - offset, /* initial offset value for the wave drawing */ - offset_next, /* when in the wave drawing loop this value is the samples intil the next vert */ - sofs, /* Constrained offset value (~3) for the wave, start */ - eofs, /* ditto, end */ - wavesample, /* inner loop storage if the current wave sample value, used to make the 2 values below */ - wavesamplemin, /* used for finding the min and max wave peaks */ - wavesamplemax, /* ditto */ - subsample_step=4; /* when the sample step is 4 every sample of - the wave is evaluated for min and max values used to draw the wave, - however this is slow ehrn zoomed out so when the sample step is above - 1 (the larger the further out the zoom is) so not evaluate all samples, only some. */ - - signed short* s; - bSound *sound; - uint8_t *stream; - -// XXX audio_makestream(seq->sound); - if(seq->sound==NULL || seq->sound->stream==NULL) return; - - if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0); - - sofs = ((int)( FRA2TIME(seq->startdisp-seq->start+seq->anim_startofs)*(float)scene->r.audio.mixrate*4.0 )) & (~3); - eofs = ((int)( FRA2TIME(seq->enddisp-seq->start+seq->anim_startofs)*(float)scene->r.audio.mixrate*4.0 )) & (~3); - - /* clip the drawing area to the screen bounds to save time */ - sample_step= (v2d->cur.xmax - v2d->cur.xmin)/winx; - clipxmin= MAX2(x1, v2d->cur.xmin); - clipxmax= MIN2(x2, v2d->cur.xmax); - - if (sample_step > 1) - subsample_step= ((int)(subsample_step*sample_step*8)) & (~3); - - /* for speedy access */ - midy = (y1+y2)/2; - fsofs= (float)sofs; - feofs_sofs= (float)(eofs-sofs); - sound_width= x2-x1; - sound = seq->sound; - stream = sound->stream; - wavemulti = (y2-y1)/196605; /*y2-y1 is the height*/ - wavesample=0; - - /* we need to get the starting offset value, excuse the duplicate code */ - f=clipxmin; - offset= (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3); - - /* start the loop, draw a line per sample_step -sample_step is about 1 line drawn per pixel */ - glBegin(GL_LINES); - for (f=x1+sample_step; f<=clipxmax; f+=sample_step) { - - offset_next = (int) (fsofs + ((f-x1)/sound_width) * feofs_sofs) & (~3); - if (f > v2d->cur.xmin) { - /* if this is close to the last sample just exit */ - if (offset_next >= sound->streamlen) break; - - wavesamplemin = 131070; - wavesamplemax = -131070; - - /*find with high and low of the waveform for this draw, - evaluate small samples to find this range */ - while (offset < offset_next) { - s = (signed short*)(stream+offset); - - wavesample = s[0]*2 + s[1]; - if (wavesamplemin>wavesample) - wavesamplemin=wavesample; - if (wavesamplemaxtype == SEQ_SOUND) - drawseqwave(scene, v2d, seq, x1, y1, x2, y2, ar->winx); - if (!is_single_image) draw_seq_extensions(scene, sseq, seq); diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index 5f6ebf60865..55b48e4aacd 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -70,57 +70,59 @@ typedef struct Sound3D typedef struct bSound { ID id; + + /** + * The path to the sound file. + */ char name[160]; - void *stream; // AUD_XXX deprecated - struct PackedFile *packedfile; - struct PackedFile *newpackedfile; // AUD_XXX deprecated - void *snd_sound; // AUD_XXX used for AUD_Sound now - struct Ipo *ipo; // AUD_XXX deprecated - float volume, panning; // AUD_XXX deprecated + /** - * Sets the rollofffactor. The rollofffactor is a per-Source parameter - * the application can use to increase or decrease the range of a source - * by decreasing or increasing the attenuation, respectively. The default - * value is 1. The implementation is free to optimize for a rollofffactor - * value of 0, which indicates that the application does not wish any - * distance attenuation on the respective Source. + * The packed file. */ - float attenuation; // AUD_XXX deprecated - float pitch; // AUD_XXX deprecated + struct PackedFile *packedfile; + /** - * min_gain indicates the minimal gain which is always guaranteed for this sound + * The handle for audaspace. */ - float min_gain; // AUD_XXX deprecated + void *handle; + /** - * max_gain indicates the maximal gain which is always guaranteed for this sound + * Deprecated; used for loading pre 2.5 files. */ - float max_gain; // AUD_XXX deprecated + struct PackedFile *newpackedfile; + struct Ipo *ipo; + float volume; + float attenuation; + float pitch; + float min_gain; + float max_gain; + float distance; + int flags; + +/** currently int type; + struct bSound *child_sound;*/ + /** - * Sets the referencedistance at which the listener will experience gain. + * Whether the sound has been changed and must be restarted if playing. */ - float distance; // AUD_XXX deprecated - int flags; // AUD_XXX deprecated - int streamlen; // AUD_XXX deprecated - char channels; // AUD_XXX deprecated - char highprio; // AUD_XXX deprecated - char pad[10]; // AUD_XXX deprecated - - // AUD_XXX NEW - int type; int changed; - struct bSound *child_sound; + + /** + * The audaspace handle for cache. + */ void *cache; - // SOUND_TYPE_LIMITER - float start, end; +/** XXX unused currently // SOUND_TYPE_LIMITER + float start, end;*/ } bSound; +/* XXX unused currently typedef enum eSound_Type { SOUND_TYPE_INVALID = -1, SOUND_TYPE_FILE = 0, SOUND_TYPE_BUFFER, SOUND_TYPE_LIMITER -} eSound_Type; +} eSound_Type;*/ /* spacesound->flag */ #define SND_DRAWFRAMES 1 @@ -142,18 +144,7 @@ typedef struct SpaceSound { int pad2; } SpaceSound; - -#define SOUND_CHANNELS_STEREO 0 -#define SOUND_CHANNELS_LEFT 1 -#define SOUND_CHANNELS_RIGHT 2 - -#define SOUND_FLAGS_LOOP (1 << 0) -#define SOUND_FLAGS_FIXED_VOLUME (1 << 1) -#define SOUND_FLAGS_FIXED_PANNING (1 << 2) #define SOUND_FLAGS_3D (1 << 3) -#define SOUND_FLAGS_BIDIRECTIONAL_LOOP (1 << 4) -#define SOUND_FLAGS_PRIORITY (1 << 5) -#define SOUND_FLAGS_SEQUENCE (1 << 6) /* to DNA_sound_types.h*/ diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 07f6f628e06..91a39bd7686 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -396,7 +396,7 @@ void BL_ConvertActuators(char* maggiename, "\" has no sound datablock." << std::endl; } else - snd_sound = sound->cache ? sound->cache : sound->snd_sound; + snd_sound = sound->cache ? sound->cache : sound->handle; KX_SoundActuator* tmpsoundact = new KX_SoundActuator(gameobj, snd_sound, -- cgit v1.2.3 From 6badfa583671cea43e6617e5485c56558ff3ec14 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 26 Aug 2009 15:13:58 +0000 Subject: 2.5 Scene RNA: * Added RNA for Render Baking. Missing: Bake Operator and property "Quad Split Order". --- source/blender/makesrna/intern/rna_scene.c | 81 +++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 209c771834d..86ceee55f47 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -32,6 +32,9 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +/* Include for Bake Options */ +#include "RE_pipeline.h" + #ifdef WITH_FFMPEG #include "BKE_writeffmpeg.h" #include @@ -1110,6 +1113,30 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {R_OUTPUT_WINDOW, "WINDOW", 0, "New Window", "Images are rendered in new Window"}, {0, NULL, 0, NULL, NULL}}; + /* Bake */ + static EnumPropertyItem bake_mode_items[] ={ + {RE_BAKE_ALL, "FULL", 0, "Full Render", ""}, + {RE_BAKE_AO, "AO", 0, "Ambient Occlusion", ""}, + {RE_BAKE_SHADOW, "SHADOW", 0, "Shadow", ""}, + {RE_BAKE_NORMALS, "NORMALS", 0, "Normals", ""}, + {RE_BAKE_TEXTURE, "TEXTURE", 0, "Textures", ""}, + {RE_BAKE_DISPLACEMENT, "DISPLACEMENT", 0, "Displacement", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem bake_normal_space_items[] ={ + {R_BAKE_SPACE_CAMERA, "CAMERA", 0, "Camera", ""}, + {R_BAKE_SPACE_WORLD, "WORLD", 0, "World", ""}, + {R_BAKE_SPACE_OBJECT, "OBJECT", 0, "Object", ""}, + {R_BAKE_SPACE_TANGENT, "TANGENT", 0, "Tangent", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem bake_aa_items[] ={ + {5, "AA_5", 0, "5", ""}, + {8, "AA_8", 0, "8", ""}, + {11, "AA_11", 0, "11", ""}, + {16, "AA_16", 0, "16", ""}, + {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem octree_resolution_items[] = { {64, "OCTREE_RES_64", 0, "64", ""}, {128, "OCTREE_RES_128", 0, "128", ""}, @@ -1141,8 +1168,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, "STAMP_FONT_LARGE", 0, "Large", ""}, {4, "STAMP_FONT_EXTRALARGE", 0, "Extra Large", ""}, {0, NULL, 0, NULL, NULL}}; - - + static EnumPropertyItem image_type_items[] = { {0, "", 0, "Image", NULL}, {R_PNG, "PNG", 0, "PNG", ""}, @@ -1707,6 +1733,57 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Output Path", "Directory/name to save animations, # characters defines the position and length of frame numbers."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + /* Bake */ + + prop= RNA_def_property(srna, "bake_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_mode"); + RNA_def_property_enum_items(prop, bake_mode_items); + RNA_def_property_ui_text(prop, "Bake Mode", ""); + + prop= RNA_def_property(srna, "bake_normal_space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_normal_space"); + RNA_def_property_enum_items(prop, bake_normal_space_items); + RNA_def_property_ui_text(prop, "Normal Space", "Choose normal space for baking"); + + prop= RNA_def_property(srna, "bake_aa_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_osa"); + RNA_def_property_enum_items(prop, bake_aa_items); + RNA_def_property_ui_text(prop, "Anti-Aliasing Level", ""); + + prop= RNA_def_property(srna, "bake_active", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_TO_ACTIVE); + RNA_def_property_ui_text(prop, "Selected to Active", "Bake shading on the surface of selected objects to the active object"); + + prop= RNA_def_property(srna, "bake_normalized", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_NORMALIZE); + RNA_def_property_ui_text(prop, "Normalized", ""); + //"Bake ambient occlusion normalized, without taking into acount material settings" + //"Normalized displacement value to fit the 'Dist' range" + // XXX: Need 1 tooltip here... + + prop= RNA_def_property(srna, "bake_clear", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_CLEAR); + RNA_def_property_ui_text(prop, "Clear", "Clear Images before baking"); + + prop= RNA_def_property(srna, "bake_enable_aa", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_OSA); + RNA_def_property_ui_text(prop, "Anti-Aliasing", "Enables Anti-aliasing"); + + prop= RNA_def_property(srna, "bake_margin", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "bake_filter"); + RNA_def_property_range(prop, 0, 32); + RNA_def_property_ui_text(prop, "Margin", "Amount of pixels to extend the baked result with, as post process filter"); + + prop= RNA_def_property(srna, "bake_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "bake_maxdist"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Distance", "Maximum distance from active object to other object (in blender units"); + + prop= RNA_def_property(srna, "bake_bias", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "bake_biasdist"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Bias", "Bias towards faces further away from the object (in blender units)"); + /* stamp */ prop= RNA_def_property(srna, "stamp_time", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From 0db2975ff6cc2592b062f749059e640dc1e2b140 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 26 Aug 2009 16:05:01 +0000 Subject: [#18837] if a sunlamp is set to a too high energy, speculars turn black shr->spec values could be greater then 1.0, causing negative color when using (1.0-shr->spec[i]) as a blending factor. When shr->spec[i] is 1.0 the mircol is ignored, so only mix the mircol when needed (like clamping the spec). --- source/blender/render/intern/source/rayshade.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 75b9557f337..182e60365a6 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1239,15 +1239,18 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) } if(shi->combinedflag & SCE_PASS_REFLECT) { + /* values in shr->spec can be greater then 1.0. + * in the case when it is 1.0 diff */ - f= fr*(1.0f-shr->spec[0]); f1= 1.0f-i; - diff[0]= f*mircol[0] + f1*diff[0]; + f1= 1.0f-i; - f= fg*(1.0f-shr->spec[1]); f1= 1.0f-i; - diff[1]= f*mircol[1] + f1*diff[1]; + diff[0] *= f1; + diff[1] *= f1; + diff[2] *= f1; - f= fb*(1.0f-shr->spec[2]); f1= 1.0f-i; - diff[2]= f*mircol[2] + f1*diff[2]; + if(shr->spec[0]<1.0f) diff[0] += mircol[0] * (fr*(1.0f-shr->spec[0])); + if(shr->spec[1]<1.0f) diff[1] += mircol[1] * (fg*(1.0f-shr->spec[1])); + if(shr->spec[2]<1.0f) diff[2] += mircol[2] * (fb*(1.0f-shr->spec[2])); } } } -- cgit v1.2.3 From 1e50c17f91cbd09929ab9624b045ba2e8ea0f979 Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Wed, 26 Aug 2009 17:13:20 +0000 Subject: Update makefile for libed_gpencil. --- source/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Makefile b/source/Makefile index 93bd2e23903..a13d8bb41d5 100644 --- a/source/Makefile +++ b/source/Makefile @@ -265,6 +265,7 @@ PULIB += $(OCGDIR)/blender/ed_uvedit/$(DEBUG_DIR)libed_uvedit.a PULIB += $(OCGDIR)/blender/ed_screen/$(DEBUG_DIR)libed_screen.a PULIB += $(OCGDIR)/blender/ed_console/$(DEBUG_DIR)libed_console.a PULIB += $(OCGDIR)/blender/ed_userpref/$(DEBUG_DIR)libed_userpref.a +PULIB += $(OCGDIR)/blender/ed_gpencil/$(DEBUG_DIR)libed_gpencil.a PULIB += $(OCGDIR)/blender/windowmanager/$(DEBUG_DIR)libwindowmanager.a PULIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a PULIB += $(OCGDIR)/blender/makesrna/$(DEBUG_DIR)librna.a -- cgit v1.2.3 From c30f54e326aa38c383c24dd288d3e0b8ce07d2d4 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Wed, 26 Aug 2009 18:20:17 +0000 Subject: 2.5 Sound: RNA for bSound. --- source/blender/blenkernel/BKE_sound.h | 2 ++ source/blender/blenkernel/intern/sound.c | 11 +++++++++++ source/blender/makesrna/intern/rna_sound.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 84ecd79a008..e9f6eb21e36 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -54,6 +54,8 @@ void sound_delete(struct bContext *C, struct bSound* sound); void sound_cache(struct bSound* sound, int ignore); +void sound_delete_cache(struct bSound* sound); + void sound_load(struct Main *main, struct bSound* sound); void sound_free(struct bSound* sound); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 070b5786a74..3794fbe90ef 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -163,6 +163,16 @@ void sound_cache(struct bSound* sound, int ignore) AUD_unload(sound->cache); sound->cache = AUD_bufferSound(sound->handle); + sound->changed = TRUE; +} + +void sound_delete_cache(struct bSound* sound) +{ + if(sound->cache) + { + AUD_unload(sound->cache); + sound->cache = NULL; + } } void sound_load(struct Main *main, struct bSound* sound) @@ -219,6 +229,7 @@ void sound_load(struct Main *main, struct bSound* sound) break; } #endif + sound->changed = TRUE; } } diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c index a029ef85544..38e4d850c68 100644 --- a/source/blender/makesrna/intern/rna_sound.c +++ b/source/blender/makesrna/intern/rna_sound.c @@ -34,6 +34,29 @@ #ifdef RNA_RUNTIME +#include "BKE_sound.h" +#include "BKE_context.h" + +static void rna_Sound_filename_update(bContext *C, PointerRNA *ptr) +{ + sound_load(CTX_data_main(C), (bSound*)ptr->data); +} + +static int rna_Sound_caching_get(PointerRNA *ptr) +{ + bSound *sound = (bSound*)(ptr->data); + return sound->cache != NULL; +} + +static void rna_Sound_caching_set(PointerRNA *ptr, const int value) +{ + bSound *sound = (bSound*)(ptr->data); + if(value) + sound_cache(sound, 0); + else + sound_delete_cache(sound); +} + #else static void rna_def_sound(BlenderRNA *brna) @@ -51,10 +74,16 @@ static void rna_def_sound(BlenderRNA *brna) prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Filename", "Sound sample file used by this Sound datablock."); + RNA_def_property_update(prop, 0, "rna_Sound_filename_update"); prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "packedfile"); RNA_def_property_ui_text(prop, "Packed File", ""); + + prop= RNA_def_property(srna, "caching", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_Sound_caching_get", "rna_Sound_caching_set"); + RNA_def_property_ui_text(prop, "Caching", "The sound file is decoded and loaded into RAM."); + RNA_def_property_update(prop, 0, "rna_Sound_filename_update"); } void RNA_def_sound(BlenderRNA *brna) -- cgit v1.2.3 From ae8dcde0e2daa9c74ef6db40abe20256fe5675cb Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Wed, 26 Aug 2009 19:30:02 +0000 Subject: SVN maintenance. --- source/blender/editors/gpencil/gpencil_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index cb6d66b2fcc..c5fa8398cd8 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -1,5 +1,5 @@ /** - * $Id: gpencil_ops.c 21617 2009-07-16 04:45:52Z aligorith $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From a3bc7f3d1d2824a1d05832a4c9186f440fbb91b0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 26 Aug 2009 20:06:16 +0000 Subject: BGE shape key actuator working, though only tried a simple testcase. --- source/blender/blenkernel/intern/sca.c | 2 -- source/gameengine/Converter/BL_ShapeActionActuator.cpp | 12 ++++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 139895bbdaf..e4d73208c64 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -418,12 +418,10 @@ void init_actuator(bActuator *act) act->data= 0; switch(act->type) { -#ifdef __NLA case ACT_ACTION: case ACT_SHAPEACTION: act->data= MEM_callocN(sizeof(bActionActuator), "actionact"); break; -#endif case ACT_SOUND: sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact"); sa->volume = 1.0f; diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 44eb603a940..81ce9ff6154 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -40,6 +40,7 @@ #include "STR_HashedString.h" #include "DNA_nla_types.h" #include "DNA_action_types.h" +#include "DNA_anim_types.h" #include "DNA_scene_types.h" #include "BKE_action.h" #include "DNA_armature_types.h" @@ -51,6 +52,10 @@ #include "FloatValue.h" #include "PyObjectPlus.h" +extern "C" { + #include "BKE_animsys.h" +} + #ifdef HAVE_CONFIG_H #include #endif @@ -370,8 +375,11 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame) m_blendstart = curtime; } // only interested in shape channel - // XXX extract_ipochannels_from_action(&tchanbase, &key->id, m_action, "Shape", m_localtime); - + + // in 2.4x was // extract_ipochannels_from_action(&tchanbase, &key->id, m_action, "Shape", m_localtime); + BKE_animsys_evaluate_animdata(&key->id, key->adt, m_localtime, ADT_RECALC_ANIM); + + // XXX - in 2.5 theres no way to do this. possibly not that important to support - Campbell if (0) { // XXX !execute_ipochannels(&tchanbase)) { // no update, this is possible if action does not match the keys, stop the action keepgoing = false; -- cgit v1.2.3 From 65b7d58fa212377226f9a132cfd274a76328e2a6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 27 Aug 2009 01:01:13 +0000 Subject: Grease Pencil: Bugfixes * Realtime updates now work again * Fixed problems with clicks to start drawing resulting in a stroke being ended. * Changed the hotkeys to Ctrl-Alt-Shift-LMB (draw) and Ctrl-Alt-Shift-RMB (erase). Still very temporary stuff, will probably change these a few more times as I experiment with new approaches. --- source/blender/editors/gpencil/gpencil_ops.c | 8 +++++-- source/blender/editors/gpencil/gpencil_paint.c | 26 +++++++++++++---------- source/blender/editors/space_view3d/view3d_draw.c | 6 +++--- source/blender/windowmanager/WM_types.h | 1 + 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index c5fa8398cd8..c18c7bb3f78 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -47,14 +47,18 @@ void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap) { - wmKeymapItem *km; + wmKeymapItem *kmi; /* if no keymap provided, use default */ if (keymap == NULL) keymap= WM_keymap_listbase(wm, "Grease Pencil Generic", 0, 0); /* Draw */ - WM_keymap_add_item(keymap, "GPENCIL_OT_draw", SKEY, KM_PRESS, 0, DKEY); + /* draw */ + WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0); + /* erase */ + kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0); + RNA_enum_set(kmi->ptr, "mode", 1); // XXX need to make the defines for this public (this is GP_PAINTMODE_ERASER) } /* ****************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index dc701924b3e..059c3417a04 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -859,7 +859,7 @@ static tGPsdata *gp_session_initpaint (bContext *C) p->scene->gpd= p->gpd; } - /* set edit flags */ + /* set edit flags - so that buffer will get drawn */ G.f |= G_GREASEPENCIL; /* set initial run flag */ @@ -1171,7 +1171,7 @@ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *even } /* force refresh */ - ED_area_tag_redraw(p->sa); // XXX this is crude + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! } /* ------------------------------- */ @@ -1216,6 +1216,18 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) printf("\tGP - handle modal event...\n"); switch (event->type) { + /* end of stroke -> ONLY when a mouse-button release occurs + * otherwise, carry on to mouse-move... + */ + case LEFTMOUSE: + case MIDDLEMOUSE: + case RIGHTMOUSE: + if (event->val != KM_PRESS) { + printf("\t\tGP - end of stroke \n"); + gpencil_draw_exit(C, op); + return OPERATOR_FINISHED; + } + /* moving mouse - assumed that mouse button is down */ case MOUSEMOVE: /* handle drawing event */ @@ -1230,14 +1242,6 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) } break; - /* end of stroke - i.e. when a mouse-button release occurs */ - case LEFTMOUSE: - case MIDDLEMOUSE: - case RIGHTMOUSE: - printf("\t\tGP - end of stroke \n"); - gpencil_draw_exit(C, op); - return OPERATOR_FINISHED; - /* scrolling mouse-wheel increases radius of eraser * - though this is quite a difficult action to perform */ @@ -1259,7 +1263,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) break; default: - return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; + printf("\t\tGP unknown event - %d \n", event->type); break; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 07ffb35f807..4ca1f296f15 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2084,7 +2084,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* draw grease-pencil stuff */ //if (v3d->flag2 & V3D_DISPGP) - draw_gpencil_3dview(C, 1); + draw_gpencil_3dview((bContext *)C, 1); BDR_drawSketch(C); @@ -2100,9 +2100,9 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) if(rv3d->persp>1) drawviewborder(scene, ar, v3d); if(rv3d->rflag & RV3D_FLYMODE) drawviewborder_flymode(ar); - /* draw grease-pencil stuff */ + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ // if (v3d->flag2 & V3D_DISPGP) -// draw_gpencil_3dview(ar, 0); + draw_gpencil_3dview((bContext *)C, 0); drawcursor(scene, ar, v3d); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 42ee6e926fc..5687cb565d1 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -149,6 +149,7 @@ typedef struct wmNotifier { #define ND_SCREENDELETE (2<<16) #define ND_SCREENCAST (3<<16) #define ND_ANIMPLAY (4<<16) +#define ND_GPENCIL (5<<16) /* NC_SCENE Scene */ #define ND_SCENEBROWSE (1<<16) -- cgit v1.2.3 From 7994ff39b8acff9a7addbacb97a26387ce181025 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 27 Aug 2009 01:57:09 +0000 Subject: Grease Pencil: Another quick experiment - easier usage * Changed the hotkey to simply be: Hold DKEY, click+drag using Left-Mouse (draw) or Right-Mouse (erase). How to get tablet erasers to work (via keymaps) is on todo... You can simply hold DKEY until you've finished drawing, thanks to the nice way that keymaps can support standard-key modifiers now. * Eraser works now too. --- source/blender/editors/gpencil/gpencil_ops.c | 8 ++++++-- source/blender/editors/gpencil/gpencil_paint.c | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index c18c7bb3f78..347a611ee30 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -55,9 +55,9 @@ void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap) /* Draw */ /* draw */ - WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0); + WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); /* erase */ - kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0); + kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY); RNA_enum_set(kmi->ptr, "mode", 1); // XXX need to make the defines for this public (this is GP_PAINTMODE_ERASER) } @@ -67,6 +67,10 @@ void ED_operatortypes_gpencil (void) { /* Drawing ----------------------- */ WM_operatortype_append(GPENCIL_OT_draw); + + /* Editing (Buttons) ------------ */ + + /* Editing (Time) --------------- */ } /* ****************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 059c3417a04..2f60efb2179 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1030,6 +1030,7 @@ static void gp_paint_cleanup (tGPsdata *p) static int gpencil_draw_init (bContext *C, wmOperator *op) { tGPsdata *p; + wmWindow *win= CTX_wm_window(C); int paintmode= RNA_enum_get(op->ptr, "mode"); /* check context */ @@ -1048,9 +1049,14 @@ static int gpencil_draw_init (bContext *C, wmOperator *op) } /* radius for eraser circle is defined in userprefs now */ - // TODO: make this more easily tweaked... p->radius= U.gp_eraser; + /* set cursor */ + if (p->paintmode == GP_PAINTMODE_ERASER) + WM_cursor_modal(win, BC_CROSSCURSOR); // XXX need a better cursor + else + WM_cursor_modal(win, BC_PAINTBRUSHCURSOR); + /* everything is now setup ok */ return 1; } @@ -1065,7 +1071,7 @@ static void gpencil_draw_exit (bContext *C, wmOperator *op) G.f &= ~G_GREASEPENCIL; /* restore cursor to indicate end of drawing */ - // XXX (cursor callbacks in regiontype) setcursor_space(p.sa->spacetype, CURSOR_STD); + WM_cursor_restore(CTX_wm_window(C)); /* check size of buffer before cleanup, to determine if anything happened here */ if (p->paintmode == GP_PAINTMODE_ERASER) { -- cgit v1.2.3 From fe46d5ba7ac6679121acc08574955b22f7653fc7 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 27 Aug 2009 06:03:41 +0000 Subject: Grease Pencil: RNA Wrapping * Wrapped Grease Pencil datatypes in RNA. * Hooked up Grease Pencil access in RNA (i.e. via Main, ID, and Scene) TODO: Updates to properties are currently lacking property-update calls, since there's no good notifier for this. --- source/blender/makesdna/DNA_gpencil_types.h | 4 +- source/blender/makesrna/RNA_access.h | 5 + source/blender/makesrna/intern/makesrna.c | 1 + source/blender/makesrna/intern/rna_ID.c | 1 + source/blender/makesrna/intern/rna_action.c | 20 +- source/blender/makesrna/intern/rna_animation.c | 3 +- source/blender/makesrna/intern/rna_gpencil.c | 242 +++++++++++++++++++++++++ source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_main.c | 9 +- source/blender/makesrna/intern/rna_scene.c | 8 + 10 files changed, 280 insertions(+), 14 deletions(-) create mode 100644 source/blender/makesrna/intern/rna_gpencil.c diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index ed209a127c7..4bae9935ea7 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -33,7 +33,7 @@ /* Grease-Pencil Annotations - 'Stroke Point' * -> Coordinates may either be 2d or 3d depending on settings at the time * -> Coordinates of point on stroke, in proportions of window size - * (i.e. n/1000). This assumes that the bottom-left corner is (0,0) + * This assumes that the bottom-left corner is (0,0) */ typedef struct bGPDspoint { float x, y, z; /* co-ordinates of point (usually 2d, but can be 3d as well) */ @@ -135,12 +135,14 @@ typedef struct bGPdata { /* bGPdata->flag */ // XXX many of these flags should be depreceated for more general ideas in 2.5 /* don't allow painting to occur at all */ + // XXX is depreceated - not well understood #define GP_DATA_LMBPLOCK (1<<0) /* show debugging info in viewport (i.e. status print) */ #define GP_DATA_DISPINFO (1<<1) /* in Action Editor, show as expanded channel */ #define GP_DATA_EXPAND (1<<2) /* is the block overriding all clicks? */ + // XXX is depreceated - nasty old concept #define GP_DATA_EDITPAINT (1<<3) /* new strokes are added in viewport space */ #define GP_DATA_VIEWALIGN (1<<4) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index ea7451ee77a..98205d17ef3 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -213,6 +213,11 @@ extern StructRNA RNA_GameSoftBodySettings; extern StructRNA RNA_GameStringProperty; extern StructRNA RNA_GameTimerProperty; extern StructRNA RNA_GlowSequence; +extern StructRNA RNA_GreasePencil; +extern StructRNA RNA_GPencilLayer; +extern StructRNA RNA_GPencilFrame; +extern StructRNA RNA_GPencilStroke; +extern StructRNA RNA_GPencilStrokePoint; extern StructRNA RNA_Group; extern StructRNA RNA_Header; extern StructRNA RNA_HemiLamp; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 0c90a28a0e9..bb7b6cbcd37 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1964,6 +1964,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_curve.c", NULL, RNA_def_curve}, {"rna_fcurve.c", NULL, RNA_def_fcurve}, {"rna_fluidsim.c", NULL, RNA_def_fluidsim}, + {"rna_gpencil.c", NULL, RNA_def_gpencil}, {"rna_group.c", NULL, RNA_def_group}, {"rna_image.c", NULL, RNA_def_image}, {"rna_key.c", NULL, RNA_def_key}, diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index f6e0a2468c4..dd26391b11e 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -97,6 +97,7 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_BR: return &RNA_Brush; case ID_CA: return &RNA_Camera; case ID_CU: return &RNA_Curve; + case ID_GD: return &RNA_GreasePencil; case ID_GR: return &RNA_Group; case ID_IM: return &RNA_Image; case ID_KE: return &RNA_Key; diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 3639d6d3fff..e376d3125e3 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -42,15 +42,15 @@ void rna_def_action_group(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + srna= RNA_def_struct(brna, "ActionGroup", NULL); RNA_def_struct_sdna(srna, "bActionGroup"); RNA_def_struct_ui_text(srna, "Action Group", "Groups of F-Curves."); - + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); RNA_def_struct_name_property(srna, prop); - + /* dna warns not to treat the Action Channel listbase in the Action Group struct like a normal listbase. I'll leave this here but comment out, for Joshua to review. He can probably shed some more light on why this is */ @@ -58,19 +58,19 @@ void rna_def_action_group(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "channels", NULL); RNA_def_property_struct_type(prop, "FCurve"); RNA_def_property_ui_text(prop, "Channels", "F-Curves in this group.");*/ - + prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_SELECTED); RNA_def_property_ui_text(prop, "Selected", "Action Group is selected."); - + prop= RNA_def_property(srna, "locked", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_PROTECTED); RNA_def_property_ui_text(prop, "Locked", "Action Group is locked."); - + prop= RNA_def_property(srna, "expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_EXPANDED); RNA_def_property_ui_text(prop, "Expanded", "Action Group is expanded."); - + prop= RNA_def_property(srna, "custom_color", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "customCol"); RNA_def_property_ui_text(prop, "Custom Color", "Index of custom color set."); @@ -85,17 +85,17 @@ void rna_def_action(BlenderRNA *brna) RNA_def_struct_sdna(srna, "bAction"); RNA_def_struct_ui_text(srna, "Action", "A collection of F-Curves for animation."); RNA_def_struct_ui_icon(srna, ICON_ACTION); - + prop= RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "curves", NULL); RNA_def_property_struct_type(prop, "FCurve"); RNA_def_property_ui_text(prop, "F-Curves", "The individual F-Curves that make up the Action."); - + prop= RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "groups", NULL); RNA_def_property_struct_type(prop, "ActionGroup"); RNA_def_property_ui_text(prop, "Groups", "Convenient groupings of F-Curves."); - + prop= RNA_def_property(srna, "pose_markers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "markers", NULL); RNA_def_property_struct_type(prop, "TimelineMarker"); diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 7652987ac86..e4bea893992 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * Contributor(s): Blender Foundation (2008), Roland Hess + * Contributor(s): Blender Foundation (2009), Joshua Leung * * ***** END GPL LICENSE BLOCK ***** */ @@ -157,7 +157,6 @@ void rna_def_keyingset(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_BUILTIN); RNA_def_property_ui_text(prop, "Built-In", "Keying Set is a built-in to Blender."); - /* TODO: for now, this is editable, but do we really want this to happen? */ prop= RNA_def_property(srna, "absolute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_ABSOLUTE); RNA_def_property_ui_text(prop, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)"); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c new file mode 100644 index 00000000000..2ef7d9d2d90 --- /dev/null +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -0,0 +1,242 @@ +/** + * $Id: rna_gpencil.c 22756 2009-08-25 04:05:37Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Blender Foundation (2009), Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "RNA_define.h" +#include "RNA_types.h" +#include "RNA_enum_types.h" + +#include "rna_internal.h" + +#include "DNA_gpencil_types.h" +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#ifdef RNA_RUNTIME + +static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr) +{ + bGPDlayer *gpl= (bGPDlayer *)ptr->data; + + /* surely there must be other criteria too... */ + if (gpl->flag & GP_LAYER_LOCKED) + return 0; + else + return 1; +} + +void rna_GPencilLayer_active_set(PointerRNA *ptr, int value) +{ + bGPdata *gpd= ptr->id.data; + bGPDlayer *gpl= ptr->data; + + /* disabled all other layers anyway */ + if (GS(gpd->id.name) == ID_GD) { + bGPDlayer *gl; + + for (gl= gpd->layers.first; gl; gl= gl->next) + gl->flag &= ~GP_LAYER_ACTIVE; + } + + /* if enabling value, make it active */ + if (value) + gpl->flag |= GP_LAYER_ACTIVE; +} + +#else + +void rna_def_gpencil_stroke_point(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "GPencilStrokePoint", NULL); + RNA_def_struct_sdna(srna, "bGPDspoint"); + RNA_def_struct_ui_text(srna, "Grease Pencil Stroke Point", "Data point for freehand stroke curve."); + + prop= RNA_def_property(srna, "coordinates", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "x"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Coordinates", ""); + + prop= RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "pressure"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it."); +} + +void rna_def_gpencil_stroke(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "GPencilStroke", NULL); + RNA_def_struct_sdna(srna, "bGPDstroke"); + RNA_def_struct_ui_text(srna, "Grease Pencil Stroke", "Freehand curve defining part of a sketch."); + + /* Points */ + prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "points", "totpoints"); + RNA_def_property_struct_type(prop, "GPencilStrokePoint"); + RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points"); + + /* Flags - Readonly type-info really... */ + // TODO... +} + +void rna_def_gpencil_frame(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "GPencilFrame", NULL); + RNA_def_struct_sdna(srna, "bGPDframe"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frame", "Collection of related sketches on a particular frame"); + + /* Strokes */ + prop= RNA_def_property(srna, "strokes", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "strokes", NULL); + RNA_def_property_struct_type(prop, "GPencilStroke"); + RNA_def_property_ui_text(prop, "Strokes", "Freehand curves defining the sketch on this frame."); + + /* Frame Number */ + prop= RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "framenum"); + RNA_def_property_range(prop, MINFRAME, MAXFRAME); // XXX note: this cannot occur on the same frame as another sketch + RNA_def_property_ui_text(prop, "Frame Number", "The frame on which this sketch appears."); + + /* Flags */ + prop= RNA_def_property(srna, "paint_lock", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_PAINT); // XXX should it be editable? + RNA_def_property_ui_text(prop, "Paint Lock", "Frame is being edited (painted on)."); + + prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT); + RNA_def_property_ui_text(prop, "Selected", "Frame is selected for editing in the DopeSheet."); +} + +void rna_def_gpencil_layer(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "GPencilLayer", NULL); + RNA_def_struct_sdna(srna, "bGPDlayer"); + RNA_def_struct_ui_text(srna, "Grease Pencil Layer", "Collection of related sketches"); + + /* Name */ + prop= RNA_def_property(srna, "info", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Info", "Description of layer"); + RNA_def_struct_name_property(srna, prop); + + /* Frames */ + prop= RNA_def_property(srna, "frames", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "frames", NULL); + RNA_def_property_struct_type(prop, "GPencilFrame"); + RNA_def_property_ui_text(prop, "Frames", "Sketches for this layer on different frames."); + + /* Active Frame */ + prop= RNA_def_property(srna, "active_frame", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "actframe"); + RNA_def_property_ui_text(prop, "Active Frame", "Frame currently being displayed for this layer."); + RNA_def_property_editable_func(prop, "rna_GPencilLayer_active_frame_editable"); + + /* Drawing Color */ + prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Color", "Color that all sketches in this layer are drawn with."); + + prop= RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "color[3]"); + RNA_def_property_range(prop, 0.3, 1.0f); + RNA_def_property_ui_text(prop, "Opacity", "Visibility of strokes."); + + /* Line Thickness */ + prop= RNA_def_property(srna, "line_thickness", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "thickness"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)."); + + /* Onion-Skinning */ + prop= RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ONIONSKIN); + RNA_def_property_ui_text(prop, "Use Onion Skinning", "Ghost frames on either side of frame."); + + prop= RNA_def_property(srna, "max_ghost_range", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "gstep"); + RNA_def_property_range(prop, 0, 120); + RNA_def_property_ui_text(prop, "Max Ghost Range", "Maximum number of frames on either side of the active frame to show. (0 = just show the 'first' available sketch on either side)"); + + /* Flags */ + prop= RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE); + RNA_def_property_ui_text(prop, "Hide", "Layer doesn't get drawn."); + + prop= RNA_def_property(srna, "locked", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED); + RNA_def_property_ui_text(prop, "Locked", "Layer is protected from further editing and/or frame changes."); + + prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ACTIVE); + RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencilLayer_active_set"); + RNA_def_property_ui_text(prop, "Active", "Layer is 'active' layer being edited."); + + prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT); + RNA_def_property_ui_text(prop, "Selected", "Layer is selected for editing in the DopeSheet."); + +} + +void rna_def_gpencil_data(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "GreasePencil", "ID"); + RNA_def_struct_sdna(srna, "bGPdata"); + RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook."); + //RNA_def_struct_ui_icon(srna, ICON_GPENCIL); + + /* Layers */ + prop= RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); + RNA_def_property_struct_type(prop, "GPencilLayer"); + RNA_def_property_ui_text(prop, "Layers", "Similar to layers in Photoshop."); +} + +/* --- */ + +void RNA_def_gpencil(BlenderRNA *brna) +{ + rna_def_gpencil_data(brna); + + rna_def_gpencil_layer(brna); + rna_def_gpencil_frame(brna); + rna_def_gpencil_stroke(brna); + rna_def_gpencil_stroke_point(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index bd28085692f..0a9ef9f90d1 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -130,6 +130,7 @@ void RNA_def_curve(struct BlenderRNA *brna); void RNA_def_fluidsim(struct BlenderRNA *brna); void RNA_def_fcurve(struct BlenderRNA *brna); void RNA_def_gameproperty(struct BlenderRNA *brna); +void RNA_def_gpencil(struct BlenderRNA *brna); void RNA_def_group(struct BlenderRNA *brna); void RNA_def_image(struct BlenderRNA *brna); void RNA_def_key(struct BlenderRNA *brna); diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 4a24027f7e9..82e460ea57d 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -207,6 +207,12 @@ static void rna_Main_particle_begin(CollectionPropertyIterator *iter, PointerRNA rna_iterator_listbase_begin(iter, &bmain->particle, NULL); } +static void rna_Main_gpencil_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Main *bmain= (Main*)ptr->data; + rna_iterator_listbase_begin(iter, &bmain->gpencil, NULL); +} + static void rna_Main_wm_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Main *bmain= (Main*)ptr->data; @@ -240,13 +246,14 @@ void RNA_def_main(BlenderRNA *brna) {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks.", NULL, NULL}, {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", NULL, NULL}, {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", NULL, NULL}, - {"keys", "ID", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL, NULL}, + {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL, NULL}, {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks.", NULL, NULL}, {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", NULL, NULL}, {"sounds", "ID", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", NULL, NULL}, {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", NULL, NULL}, {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", NULL, NULL}, {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", NULL, NULL}, + {"gpencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks.", NULL, NULL}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL}}; int i; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 86ceee55f47..2408d9337e1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2067,6 +2067,14 @@ void RNA_def_scene(BlenderRNA *brna) prop= RNA_def_string(func, "statistics", "", 0, "Statistics", ""); RNA_def_function_return(func, prop); + /* 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 Data", "Grease Pencil datablock"); + + /* Nestled Data */ rna_def_tool_settings(brna); rna_def_unit_settings(brna); rna_def_scene_render_data(brna); -- cgit v1.2.3 From 324b3fbe747a6544b60be1eb8a0cb6b01db736de Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Aug 2009 06:55:54 +0000 Subject: - BGE crash fix when casting a ray to the same location as the object from python. - Incorrect Mathutils vector docstrings. - last rayshade commit had an incomplete comment. --- source/blender/python/api2_2x/vector.c | 4 ++-- source/blender/render/intern/source/rayshade.c | 4 +++- source/gameengine/Ketsji/KX_GameObject.cpp | 8 +++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index cb206363dbf..a7e00e2878a 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -58,8 +58,8 @@ struct PyMethodDef Vector_methods[] = { {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc}, {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc}, {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, + {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize3D_doc}, + {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize4D_doc}, {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc}, {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Dot_doc}, diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 182e60365a6..e683a499e17 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1240,7 +1240,9 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) if(shi->combinedflag & SCE_PASS_REFLECT) { /* values in shr->spec can be greater then 1.0. - * in the case when it is 1.0 diff */ + * In this case the mircol uses a zero blending factor, so ignoring it is ok. + * Fixes bug #18837 - when the spec is higher then 1.0, + * diff can become a negative color - Campbell */ f1= 1.0f-i; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index d04174a32aa..ba8905973d5 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -2597,12 +2597,10 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, } } MT_Point3 fromPoint = NodeGetWorldPosition(); + if (dist != 0.0f) - { - MT_Vector3 toDir = toPoint-fromPoint; - toDir.normalize(); - toPoint = fromPoint + (dist) * toDir; - } + toPoint = fromPoint + dist * (toPoint-fromPoint).safe_normalized(); + PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment(); KX_IPhysicsController *spc = GetPhysicsController(); KX_GameObject *parent = GetParent(); -- cgit v1.2.3 From 55f82852ca4a88080bf9928445e52d24330a4889 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 27 Aug 2009 08:46:39 +0000 Subject: Tweaked layout of game properties. The Add button is now at the top, meaning it doesn't move around - this is also more consistent with constraints/modifiers etc. Used the same 'box' layout as constraints/modifiers. Also ported some name changes from the materials UI script to RNA to keep these consistent. Animation editors always show the RNA name after all, so it's good to keep the names similar. --- release/ui/buttons_material.py | 24 ++++++++-------- release/ui/space_logic.py | 21 +++++++------- source/blender/editors/animation/anim_ops.c | 4 +-- source/blender/makesrna/intern/rna_material.c | 40 +++++++++++++-------------- 4 files changed, 44 insertions(+), 45 deletions(-) diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py index 30b107d452f..e7add9c59f3 100644 --- a/release/ui/buttons_material.py +++ b/release/ui/buttons_material.py @@ -130,8 +130,8 @@ class MATERIAL_PT_strand(MaterialButtonsPanel): col = split.column(align=True) col.itemL(text="Size:") - col.itemR(tan, "start_size", text="Root") - col.itemR(tan, "end_size", text="Tip") + col.itemR(tan, "root_size", text="Root") + col.itemR(tan, "tip_size", text="Tip") col.itemR(tan, "min_size", text="Minimum") col.itemR(tan, "blender_units") sub = col.column() @@ -231,7 +231,7 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel): col = split.column() col.itemR(mat, "shadows", text="Receive") - col.itemR(mat, "transparent_shadows", text="Receive Transparent") + col.itemR(mat, "receive_transparent_shadows", text="Receive Transparent") col.itemR(mat, "only_shadow", text="Shadows Only") col.itemR(mat, "cast_shadows_only", text="Cast Only") col.itemR(mat, "shadow_casting_alpha", text="Casting Alpha") @@ -266,7 +266,7 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel): col.itemR(mat, "diffuse_color", text="") sub = col.column() sub.active = (not mat.shadeless) - sub.itemR(mat, "diffuse_reflection", text="Intensity") + sub.itemR(mat, "diffuse_intensity", text="Intensity") col = split.column() col.active = (not mat.shadeless) @@ -320,7 +320,7 @@ class MATERIAL_PT_specular(MaterialButtonsPanel): col = split.column() col.itemR(mat, "specular_color", text="") - col.itemR(mat, "specular_reflection", text="Intensity") + col.itemR(mat, "specular_intensity", text="Intensity") col = split.column() col.itemR(mat, "specular_shader", text="") @@ -426,7 +426,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): split = layout.split() col = split.column() - col.itemR(raym, "reflect", text="Reflectivity") + col.itemR(raym, "reflectivity") col.itemR(mat, "mirror_color", text="") col = split.column() @@ -448,9 +448,9 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): col = split.column() col.itemL(text="Gloss:") - col.itemR(raym, "gloss", text="Amount") + col.itemR(raym, "gloss_amount", text="Amount") sub = col.column() - sub.active = raym.gloss < 1 + sub.active = raym.gloss_amount < 1 sub.itemR(raym, "gloss_threshold", text="Threshold") sub.itemR(raym, "gloss_samples", text="Samples") sub.itemR(raym, "gloss_anisotropic", text="Anisotropic") @@ -511,9 +511,9 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): col = split.column() col.itemL(text="Gloss:") - col.itemR(rayt, "gloss", text="Amount") + col.itemR(rayt, "gloss_amount", text="Amount") sub = col.column() - sub.active = rayt.gloss < 1 + sub.active = rayt.gloss_amount < 1 sub.itemR(rayt, "gloss_threshold", text="Threshold") sub.itemR(rayt, "gloss_samples", text="Samples") @@ -663,8 +663,8 @@ class MATERIAL_PT_halo(MaterialButtonsPanel): col.itemR(halo, "hardness") col.itemR(halo, "add") col.itemL(text="Options:") - col.itemR(halo, "use_texture", text="Texture") - col.itemR(halo, "use_vertex_normal", text="Vertex Normal") + col.itemR(halo, "texture") + col.itemR(halo, "vertex_normal") col.itemR(halo, "xalpha") col.itemR(halo, "shaded") col.itemR(halo, "soft") diff --git a/release/ui/space_logic.py b/release/ui/space_logic.py index f9920f78497..9b0e3dc7f38 100644 --- a/release/ui/space_logic.py +++ b/release/ui/space_logic.py @@ -14,17 +14,16 @@ class LOGIC_PT_properties(bpy.types.Panel): ob = context.active_object game = ob.game + layout.itemO("object.game_property_new", text="Add Game Property") + for i, prop in enumerate(game.properties): - flow = layout.row(align=True) - flow.itemR(prop, "name", text="") - flow.itemR(prop, "type", text="") - flow.itemR(prop, "value", text="") # we dont care about the type. rna will display correctly - flow.itemR(prop, "debug", text="", toggle=True, icon='ICON_INFO') - flow.item_intO("object.game_property_remove", "index", i, text="", icon='ICON_X') - flow = layout.row() - flow.itemO("object.game_property_new") - - - + box = layout.box() + row = box.row() + row.itemR(prop, "name", text="") + row.itemR(prop, "type", text="") + row.itemR(prop, "value", text="") # we dont care about the type. rna will display correctly + row.itemR(prop, "debug", text="", toggle=True, icon='ICON_INFO') + row.item_intO("object.game_property_remove", "index", i, text="", icon='ICON_X') + bpy.types.register(LOGIC_PT_properties) diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 72fee937e25..3d45dcc92ca 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -406,10 +406,10 @@ void ED_keymap_anim(wmWindowManager *wm) /* frame management */ /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */ - WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ANIM_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "ANIM_OT_time_toggle", TKEY, KM_PRESS, KM_CTRL, 0); /* preview range */ - WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_clear", PKEY, KM_PRESS, KM_ALT, 0); } diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index cde65f46e5c..e9970e4391e 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -685,10 +685,10 @@ static void rna_def_material_diffuse(StructRNA *srna) RNA_def_property_ui_text(prop, "Diffuse Shader Model", ""); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "diffuse_reflection", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "diffuse_intensity", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "ref"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Diffuse Reflection", "Amount of diffuse reflection."); + RNA_def_property_ui_text(prop, "Diffuse Intensity", "Amount of diffuse reflection."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL); prop= RNA_def_property(srna, "roughness", PROP_FLOAT, PROP_NONE); @@ -746,10 +746,10 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Enabled", "Enable raytraced reflections."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "reflect", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "reflectivity", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "ray_mirror"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Reflect", "Sets the amount mirror reflection for raytrace."); + RNA_def_property_ui_text(prop, "Reflectivity", "Sets the amount mirror reflection for raytrace."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); prop= RNA_def_property(srna, "fresnel", PROP_FLOAT, PROP_NONE); @@ -764,10 +764,10 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_amount", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "gloss_mir"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss", "The shininess of the reflection. Values < 1.0 give diffuse, blurry reflections."); + RNA_def_property_ui_text(prop, "Gloss Amount", "The shininess of the reflection. Values < 1.0 give diffuse, blurry reflections."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); prop= RNA_def_property(srna, "gloss_anisotropic", PROP_FLOAT, PROP_PERCENTAGE); @@ -835,10 +835,10 @@ static void rna_def_material_raytra(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_amount", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "gloss_tra"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss", "The clarity of the refraction. Values < 1.0 give diffuse, blurry refractions."); + RNA_def_property_ui_text(prop, "Gloss Amount", "The clarity of the refraction. Values < 1.0 give diffuse, blurry refractions."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); prop= RNA_def_property(srna, "gloss_samples", PROP_INT, PROP_NONE); @@ -1133,14 +1133,14 @@ static void rna_def_material_halo(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Star", "Renders halo as a star."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "texture", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALOTEX); - RNA_def_property_ui_text(prop, "Use Texture", "Gives halo a texture."); + RNA_def_property_ui_text(prop, "Texture", "Gives halo a texture."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "use_vertex_normal", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "vertex_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_HALOPUNO); - RNA_def_property_ui_text(prop, "Use Vertex Normal", "Uses the vertex normal to specify the dimension of the halo."); + RNA_def_property_ui_text(prop, "Vertex Normal", "Uses the vertex normal to specify the dimension of the halo."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); prop= RNA_def_property(srna, "xalpha", PROP_BOOLEAN, PROP_NONE); @@ -1247,10 +1247,10 @@ void rna_def_material_specularity(StructRNA *srna) RNA_def_property_ui_text(prop, "Specular Shader Model", ""); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "specular_reflection", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "spec"); RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Specularity Intensity", ""); + RNA_def_property_ui_text(prop, "Specular Intensity", ""); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); /* NOTE: "har", "param", etc are used for multiple purposes depending on @@ -1320,16 +1320,16 @@ void rna_def_material_strand(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Blender Units", "Use Blender units for widths instead of pixels."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "start_size", PROP_FLOAT, PROP_UNSIGNED); + prop= RNA_def_property(srna, "root_size", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "strand_sta"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_MaterialStrand_start_size_range"); - RNA_def_property_ui_text(prop, "Start Size", "Start size of strands in pixels Blender units."); + RNA_def_property_ui_text(prop, "Root Size", "Start size of strands in pixels Blender units."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "end_size", PROP_FLOAT, PROP_UNSIGNED); + prop= RNA_def_property(srna, "tip_size", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "strand_end"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_MaterialStrand_end_size_range"); - RNA_def_property_ui_text(prop, "End Size", "Start size of strands in pixels or Blender units."); + RNA_def_property_ui_text(prop, "Tip Size", "Start size of strands in pixels or Blender units."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); prop= RNA_def_property(srna, "min_size", PROP_FLOAT, PROP_UNSIGNED); @@ -1551,9 +1551,9 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Exclude Mist", "Excludes this material from mist effects (in world settings)"); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "transparent_shadows", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "receive_transparent_shadows", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_SHADOW_TRA); - RNA_def_property_ui_text(prop, "Transparent Shadows", "Allow this object to receive transparent shadows casted through other objects"); + RNA_def_property_ui_text(prop, "Receive Transparent Shadows", "Allow this object to receive transparent shadows casted through other objects"); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); prop= RNA_def_property(srna, "ray_shadow_bias", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From 12a0f2c0987688b2fcf8daf44d9462b524fe139a Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Thu, 27 Aug 2009 09:52:41 +0000 Subject: Fix for sounds with relative paths not being loaded correctly. --- source/blender/blenloader/intern/readblenentry.c | 18 +++--------------- source/blender/blenloader/intern/readfile.c | 7 +++++-- source/blender/blenloader/intern/readfile.h | 2 +- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 1f276913ea8..ac561eb6186 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -331,11 +331,7 @@ BlendFileData *BLO_read_from_file(char *file, ReportList *reports) fd = blo_openblenderfile(file, reports); if (fd) { fd->reports= reports; - bfd= blo_read_file_internal(fd); - if (bfd) { - bfd->type= BLENFILETYPE_BLEND; - strncpy(bfd->main->name, file, sizeof(bfd->main->name)-1); - } + bfd= blo_read_file_internal(fd, file); blo_freefiledata(fd); } @@ -350,11 +346,7 @@ BlendFileData *BLO_read_from_memory(void *mem, int memsize, ReportList *reports) fd = blo_openblendermemory(mem, memsize, reports); if (fd) { fd->reports= reports; - bfd= blo_read_file_internal(fd); - if (bfd) { - bfd->type= BLENFILETYPE_BLEND; - strcpy(bfd->main->name, ""); - } + bfd= blo_read_file_internal(fd, ""); blo_freefiledata(fd); } @@ -383,11 +375,7 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil /* makes lookup of existing images in old main */ blo_make_image_pointer_map(fd, oldmain); - bfd= blo_read_file_internal(fd); - if (bfd) { - bfd->type= BLENFILETYPE_BLEND; - strcpy(bfd->main->name, ""); - } + bfd= blo_read_file_internal(fd, ""); /* ensures relinked images are not freed */ blo_end_image_pointer_map(fd, oldmain); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6771135a772..5d61e3d305e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9700,7 +9700,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) return bhead; } -BlendFileData *blo_read_file_internal(FileData *fd) +BlendFileData *blo_read_file_internal(FileData *fd, char *file) { BHead *bhead= blo_firstbhead(fd); BlendFileData *bfd; @@ -9711,6 +9711,9 @@ BlendFileData *blo_read_file_internal(FileData *fd) bfd->main->versionfile= fd->fileversion; + bfd->type= BLENFILETYPE_BLEND; + strncpy(bfd->main->name, file, sizeof(bfd->main->name)-1); + while(bhead) { switch(bhead->code) { case DATA: @@ -11131,7 +11134,7 @@ BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize, return NULL; fd->reports= reports; - bfd= blo_read_file_internal(fd); + bfd= blo_read_file_internal(fd, ""); blo_freefiledata(fd); return bfd; diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index e39fefa8205..2a0b6c327d3 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -108,7 +108,7 @@ struct Main; void blo_join_main(ListBase *mainlist); void blo_split_main(ListBase *mainlist, struct Main *main); -BlendFileData *blo_read_file_internal(FileData *fd); +BlendFileData *blo_read_file_internal(FileData *fd, char *file); FileData *blo_openblenderfile(char *name, struct ReportList *reports); FileData *blo_openblendermemory(void *buffer, int buffersize, struct ReportList *reports); -- cgit v1.2.3 From 2c7065e541f1ea51dbeea045bc3214ce22d4ca82 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Aug 2009 15:22:41 +0000 Subject: - assigning vectors in the BGE wasn't updating the vector from the callback - Pkey only starts in BGE in Object Mode - warning in readblenentry.c, is silent on 64bit too. --- source/blender/blenloader/intern/readblenentry.c | 2 +- source/blender/editors/space_view3d/view3d_view.c | 7 ++++++- source/gameengine/Ketsji/KX_PyMath.h | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index ac561eb6186..33641a0b004 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -200,7 +200,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) buf[2]= buf[2]?buf[2]:' '; buf[3]= buf[3]?buf[3]:' '; - fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (intptr_t)bhead->len+sizeof(BHead)); + fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (long int)bhead->len+sizeof(BHead)); } } fprintf(fp, "]\n"); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ce7b6ba454d..771c02e95b6 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1444,6 +1444,11 @@ extern void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int always_ #endif // GAMEBLENDER == 1 +int game_engine_poll(bContext *C) +{ + return CTX_data_mode_enum(C)==CTX_MODE_OBJECT ? 1:0; +} + static int game_engine_exec(bContext *C, wmOperator *unused) { #if GAMEBLENDER == 1 @@ -1503,7 +1508,7 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) /* api callbacks */ ot->exec= game_engine_exec; - //ot->poll= ED_operator_view3d_active; + ot->poll= game_engine_poll; } /* ************************************** */ diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index a8488e8e60a..17102905607 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -109,6 +109,7 @@ bool PyVecTo(PyObject* pyval, T& vec) if(VectorObject_Check(pyval)) { VectorObject *pyvec= (VectorObject *)pyval; + BaseMath_ReadCallback(pyvec); if (pyvec->size != Size(vec)) { PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", pyvec->size, Size(vec)); return false; @@ -118,6 +119,7 @@ bool PyVecTo(PyObject* pyval, T& vec) } else if(QuaternionObject_Check(pyval)) { QuaternionObject *pyquat= (QuaternionObject *)pyval; + BaseMath_ReadCallback(pyquat); if (4 != Size(vec)) { PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 4, Size(vec)); return false; @@ -128,6 +130,7 @@ bool PyVecTo(PyObject* pyval, T& vec) } else if(EulerObject_Check(pyval)) { EulerObject *pyeul= (EulerObject *)pyval; + BaseMath_ReadCallback(pyeul); if (3 != Size(vec)) { PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 3, Size(vec)); return false; -- cgit v1.2.3 From 28392eedbefe1bf9322d30d8697128b2dafb55d5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Aug 2009 16:34:13 +0000 Subject: was casting the PyObjectPlus type to a PyObject for new BGE vector and matrix types, need to get its proxy instead. --- source/gameengine/Expressions/PyObjectPlus.h | 5 ++++- source/gameengine/Ketsji/KX_GameObject.cpp | 14 +++++++------- source/gameengine/Ketsji/KX_ObjectActuator.cpp | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index e9e81dddaaa..f9edb7877b0 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -86,7 +86,7 @@ typedef struct { -typedef struct { +typedef struct PyObjectPlus_Proxy { PyObject_HEAD /* required python macro */ class PyObjectPlus *ref; bool py_owns; @@ -99,6 +99,9 @@ typedef struct { /* Note, sometimes we dont care what BGE type this is as long as its a proxy */ #define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc) +/* Opposite of BGE_PROXY_REF */ +#define BGE_PROXY_FROM_REF(_self) (((PyObjectPlus *)_self)->GetProxy()) + // This must be the first line of each // PyC++ class diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 79b110b11ef..91213bee865 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1798,7 +1798,7 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_GLOBAL); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_GLOBAL); #else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetWorldPosition()); @@ -1820,7 +1820,7 @@ int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_D PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL); #else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetLocalPosition()); @@ -1842,7 +1842,7 @@ int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_D PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_INERTIA_LOCAL); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_INERTIA_LOCAL); #else KX_GameObject* self= static_cast(self_v); if (self->GetPhysicsController()) @@ -1854,7 +1854,7 @@ PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIB PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL); + return newMatrixObject_cb(BGE_PROXY_FROM_REF(self_v), 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL); #else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetWorldOrientation()); @@ -1879,7 +1879,7 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL); + return newMatrixObject_cb(BGE_PROXY_FROM_REF(self_v), 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL); #else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetLocalOrientation()); @@ -1903,7 +1903,7 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_GLOBAL); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_GLOBAL); #else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetWorldScaling()); @@ -1913,7 +1913,7 @@ PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIB PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { #ifdef USE_MATHUTILS - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL); #else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetLocalScaling()); diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index 99179c5ed96..2601ced9c38 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -467,7 +467,7 @@ Mathutils_Callback mathutils_obactu_vector_cb = { PyObject* KX_ObjectActuator::pyattr_get_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV); } int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -481,7 +481,7 @@ int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *a PyObject* KX_ObjectActuator::pyattr_get_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { - return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV); + return newVectorObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV); } int KX_ObjectActuator::pyattr_set_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) -- cgit v1.2.3 From 9c1cf53e9ab023e281697e2810ba45031c024101 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 27 Aug 2009 18:24:12 +0000 Subject: 2.5 Volumetric: * Wrapped some missing Point Density RNA and added the options to the UI. * Some UI changes (greying out...) Matt: Please check. :) --- release/ui/buttons_texture.py | 49 ++++++++++++++++++------ source/blender/makesrna/intern/rna_texture.c | 56 ++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index 4827f677336..c9f1585ec81 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -623,6 +623,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel): def draw(self, context): layout = self.layout + tex = context.texture vd = tex.voxeldata @@ -631,12 +632,13 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel): layout.itemR(vd, "source_path") if vd.file_format == 'RAW_8BIT': layout.itemR(vd, "resolution") - if vd.file_format == 'SMOKE': + elif vd.file_format == 'SMOKE': layout.itemR(vd, "domain_object") layout.itemR(vd, "still") - if vd.still: - layout.itemR(vd, "still_frame_number") + row = layout.row() + row.active = vd.still + row.itemR(vd, "still_frame_number") layout.itemR(vd, "interpolation") layout.itemR(vd, "intensity") @@ -651,27 +653,51 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): def draw(self, context): layout = self.layout + tex = context.texture pd = tex.pointdensity + ob = context.object - layout.itemR(pd, "point_source") - layout.itemR(pd, "object") + layout.itemR(pd, "point_source", expand=True) if pd.point_source == 'PARTICLE_SYSTEM': - layout.item_pointerR(pd, "particle_system", pd.object, "particle_systems", text="") + layout.item_pointerR(pd, "particle_system", ob, "particle_systems", text="System") + layout.itemR(pd, "particle_cache", text="Cache") + else: + layout.itemR(pd, "object") + layout.itemR(pd, "vertices_cache", text="Cache") + + layout.itemS() + layout.itemR(pd, "radius") layout.itemR(pd, "falloff") if pd.falloff == 'SOFT': layout.itemR(pd, "falloff_softness") - layout.itemR(pd, "color_source") + + layout.itemS() + layout.itemR(pd, "turbulence") - layout.itemR(pd, "turbulence_size") - layout.itemR(pd, "turbulence_depth") - layout.itemR(pd, "turbulence_influence") + col = layout.column() + col.active = pd.turbulence + sub = col.column_flow() + sub.itemR(pd, "turbulence_size") + sub.itemR(pd, "turbulence_depth") + sub.itemR(pd, "turbulence_strength") + col.itemR(pd, "turbulence_influence", text="Influence") + col.itemR(pd, "noise_basis") + + layout.itemS() + + layout.itemR(pd, "color_source") + if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_VELOCITY'): + layout.itemR(pd, "speed_scale") + if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_AGE'): + layout.template_color_ramp(pd.color_ramp, expand=True) bpy.types.register(TEXTURE_PT_context_texture) bpy.types.register(TEXTURE_PT_preview) -bpy.types.register(TEXTURE_PT_clouds) + +bpy.types.register(TEXTURE_PT_clouds) # Texture Type Panels bpy.types.register(TEXTURE_PT_wood) bpy.types.register(TEXTURE_PT_marble) bpy.types.register(TEXTURE_PT_magic) @@ -687,6 +713,7 @@ bpy.types.register(TEXTURE_PT_voronoi) bpy.types.register(TEXTURE_PT_distortednoise) bpy.types.register(TEXTURE_PT_voxeldata) bpy.types.register(TEXTURE_PT_pointdensity) + bpy.types.register(TEXTURE_PT_colors) bpy.types.register(TEXTURE_PT_mapping) bpy.types.register(TEXTURE_PT_influence) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index a949d26f51a..f899d52543e 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1333,8 +1333,21 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) static EnumPropertyItem point_source_items[] = { {TEX_PD_PSYS, "PARTICLE_SYSTEM", 0, "Particle System", "Generate point density from a particle system"}, {TEX_PD_OBJECT, "OBJECT", 0, "Object Vertices", "Generate point density from an object's vertices"}, + //{TEX_PD_FILE, "FILE", 0 , "File", ""}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem particle_cache_items[] = { + {TEX_PD_OBJECTLOC, "OBJECT_LOCATION", 0, "Emit Object Location", ""}, + {TEX_PD_OBJECTSPACE, "OBJECT_SPACE", 0, "Emit Object Space", ""}, + {TEX_PD_WORLDSPACE, "WORLD_SPACE", 0 , "Global Space", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem vertice_cache_items[] = { + {TEX_PD_OBJECTLOC, "OBJECT_LOCATION", 0, "Object Location", ""}, + {TEX_PD_OBJECTSPACE, "OBJECT_SPACE", 0, "Object Space", ""}, + {TEX_PD_WORLDSPACE, "WORLD_SPACE", 0 , "Global Space", ""}, + {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem falloff_items[] = { {TEX_PD_FALLOFF_STD, "STANDARD", 0, "Standard", ""}, {TEX_PD_FALLOFF_SMOOTH, "SMOOTH", 0, "Smooth", ""}, @@ -1354,7 +1367,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) {TEX_PD_NOISE_STATIC, "STATIC", 0, "Static", "Noise patterns will remain unchanged, faster and suitable for stills"}, {TEX_PD_NOISE_VEL, "PARTICLE_VELOCITY", 0, "Particle Velocity", "Turbulent noise driven by particle velocity"}, {TEX_PD_NOISE_AGE, "PARTICLE_AGE", 0, "Particle Age", "Turbulent noise driven by the particle's age between birth and death"}, - {TEX_PD_NOISE_TIME, "GLOBAL_TIME", 0, "Global Time", "Turbulent noise driven by the global current frame"}, + {TEX_PD_NOISE_TIME, "GLOBAL_TIME", 0, "Global Time", "Turbulent noise driven by the global current frame"}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "PointDensity", NULL); @@ -1380,6 +1393,18 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "particle_cache", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "psys_cache_space"); + RNA_def_property_enum_items(prop, particle_cache_items); + RNA_def_property_ui_text(prop, "Particle Cache", "Co-ordinate system to cache particles in"); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + + prop= RNA_def_property(srna, "vertices_cache", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "ob_cache_space"); + RNA_def_property_enum_items(prop, vertice_cache_items); + RNA_def_property_ui_text(prop, "Vertices Cache", "Co-ordinate system to cache vertices in"); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "radius"); RNA_def_property_range(prop, 0.01, FLT_MAX); @@ -1404,6 +1429,19 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from"); RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "speed_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "speed_scale"); + RNA_def_property_range(prop, 0.001, 100.0); + RNA_def_property_ui_text(prop, "Scale", "Multipler to bring particle speed within an acceptable range"); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + + prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "coba"); + RNA_def_property_struct_type(prop, "ColorRamp"); + RNA_def_property_ui_text(prop, "Color Ramp", ""); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + + /* Turbulence */ prop= RNA_def_property(srna, "turbulence", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_PD_TURBULENCE); RNA_def_property_ui_text(prop, "Turbulence", "Add directed noise to the density at render-time"); @@ -1415,6 +1453,12 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Size", "Scale of the added turbulent noise"); RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "turbulence_strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "noise_fac"); + RNA_def_property_range(prop, 0.01, FLT_MAX); + RNA_def_property_ui_text(prop, "Strength", ""); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "turbulence_depth", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "noise_depth"); RNA_def_property_range(prop, 0, INT_MAX); @@ -1426,9 +1470,14 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) RNA_def_property_enum_items(prop, turbulence_influence_items); RNA_def_property_ui_text(prop, "Turbulence Influence", "Method for driving added turbulent noise"); RNA_def_property_update(prop, NC_TEXTURE, NULL); - - + prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "noise_basis"); + RNA_def_property_enum_items(prop, prop_noise_basis_items); + RNA_def_property_ui_text(prop, "Noise Basis", "Noise formula used for tubulence"); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + + srna= RNA_def_struct(brna, "PointDensityTexture", "Texture"); RNA_def_struct_sdna(srna, "Tex"); RNA_def_struct_ui_text(srna, "Point Density", "Settings for the Point Density texture"); @@ -1454,6 +1503,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) static EnumPropertyItem file_format_items[] = { {TEX_VD_BLENDERVOXEL, "BLENDER_VOXEL", 0, "Blender Voxel", "Default binary voxel file format"}, {TEX_VD_RAW_8BIT, "RAW_8BIT", 0, "8 bit RAW", "8 bit greyscale binary data"}, + //{TEX_VD_RAW_16BIT, "RAW_16BIT", 0, "16 bit RAW", ""}, {TEX_VD_IMAGE_SEQUENCE, "IMAGE_SEQUENCE", 0, "Image Sequence", "Generate voxels from a sequence of image slices"}, {TEX_VD_SMOKE, "SMOKE", 0, "Smoke", "Render voxels from a Blender smoke simulation"}, {0, NULL, 0, NULL, NULL}}; -- cgit v1.2.3 From 590950a0fafb7e56ac32f32f1dff76b5c9cbce81 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 27 Aug 2009 19:10:53 +0000 Subject: 2.5: * Deleted the box layout in logic editor, as discussed in IRC. We need a better solution here, maybe 2 lines? * Typo in Sequencer RNA. --- release/ui/buttons_texture.py | 86 +++++++++++++++++++-------- release/ui/space_logic.py | 14 ++--- source/blender/makesrna/intern/rna_sequence.c | 2 +- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index c9f1585ec81..78d5e6af790 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -657,43 +657,76 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): tex = context.texture pd = tex.pointdensity ob = context.object - + layout.itemR(pd, "point_source", expand=True) + + split = layout.split() + + col = split.column() if pd.point_source == 'PARTICLE_SYSTEM': - layout.item_pointerR(pd, "particle_system", ob, "particle_systems", text="System") - layout.itemR(pd, "particle_cache", text="Cache") + col.itemL(text="System:") + col.item_pointerR(pd, "particle_system", ob, "particle_systems", text="") + col.itemL(text="Cache:") + col.itemR(pd, "particle_cache", text="") else: - layout.itemR(pd, "object") - layout.itemR(pd, "vertices_cache", text="Cache") + col.itemL(text="Object:") + col.itemR(pd, "object", text="") + col.itemL(text="Cache:") + col.itemR(pd, "vertices_cache", text="") - layout.itemS() + sub = split.column() - layout.itemR(pd, "radius") - layout.itemR(pd, "falloff") - if pd.falloff == 'SOFT': - layout.itemR(pd, "falloff_softness") - - layout.itemS() - - layout.itemR(pd, "turbulence") - - col = layout.column() - col.active = pd.turbulence - sub = col.column_flow() - sub.itemR(pd, "turbulence_size") - sub.itemR(pd, "turbulence_depth") - sub.itemR(pd, "turbulence_strength") - col.itemR(pd, "turbulence_influence", text="Influence") - col.itemR(pd, "noise_basis") + sub.itemL() + sub.itemR(pd, "radius") - layout.itemS() + sub.itemL(text="Falloff:") + sub.itemR(pd, "falloff", text="") + if pd.falloff == 'SOFT': + sub.itemR(pd, "falloff_softness") - layout.itemR(pd, "color_source") + col.itemL(text="Color Source:") + col.itemR(pd, "color_source", text="") if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_VELOCITY'): - layout.itemR(pd, "speed_scale") + col.itemR(pd, "speed_scale") if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_AGE'): layout.template_color_ramp(pd.color_ramp, expand=True) +class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel): + __label__ = "Turbulence" + + def poll(self, context): + tex = context.texture + return (tex and tex.type == 'POINT_DENSITY') + + def draw_header(self, context): + layout = self.layout + + tex = context.texture + pd = tex.pointdensity + + layout.itemR(pd, "turbulence", text="") + + def draw(self, context): + layout = self.layout + + tex = context.texture + pd = tex.pointdensity + layout.active = pd.turbulence + + split = layout.split() + + col = split.column() + col.itemL(text="Influence:") + col.itemR(pd, "turbulence_influence", text="") + col.itemL(text="Noise Basis:") + col.itemR(pd, "noise_basis", text="") + + col = split.column() + col.itemL() + col.itemR(pd, "turbulence_size") + col.itemR(pd, "turbulence_depth") + col.itemR(pd, "turbulence_strength") + bpy.types.register(TEXTURE_PT_context_texture) bpy.types.register(TEXTURE_PT_preview) @@ -713,6 +746,7 @@ bpy.types.register(TEXTURE_PT_voronoi) bpy.types.register(TEXTURE_PT_distortednoise) bpy.types.register(TEXTURE_PT_voxeldata) bpy.types.register(TEXTURE_PT_pointdensity) +bpy.types.register(TEXTURE_PT_pointdensity_turbulence) bpy.types.register(TEXTURE_PT_colors) bpy.types.register(TEXTURE_PT_mapping) diff --git a/release/ui/space_logic.py b/release/ui/space_logic.py index 9b0e3dc7f38..5748d15a53a 100644 --- a/release/ui/space_logic.py +++ b/release/ui/space_logic.py @@ -11,19 +11,19 @@ class LOGIC_PT_properties(bpy.types.Panel): def draw(self, context): layout = self.layout + ob = context.active_object game = ob.game layout.itemO("object.game_property_new", text="Add Game Property") - + for i, prop in enumerate(game.properties): - box = layout.box() - row = box.row() - row.itemR(prop, "name", text="") - row.itemR(prop, "type", text="") - row.itemR(prop, "value", text="") # we dont care about the type. rna will display correctly - row.itemR(prop, "debug", text="", toggle=True, icon='ICON_INFO') + row = layout.row(align=True) + row.itemR(prop, "name", text="") + row.itemR(prop, "type", text="") + row.itemR(prop, "value", text="", toggle=True) # we dont care about the type. rna will display correctly + row.itemR(prop, "debug", text="", toggle=True, icon='ICON_INFO') row.item_intO("object.game_property_remove", "index", i, text="", icon='ICON_X') bpy.types.register(LOGIC_PT_properties) diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index 470909f4eff..5d275f7a87c 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -360,7 +360,7 @@ static void rna_def_sequence(BlenderRNA *brna) {SEQ_META, "META", 0, "Meta", ""}, {SEQ_SCENE, "SCENE", 0, "Scene", ""}, {SEQ_MOVIE, "MOVIE", 0, "Movie", ""}, - {SEQ_SOUND, "_SOUND", 0, "Sound", ""}, + {SEQ_SOUND, "SOUND", 0, "Sound", ""}, {SEQ_EFFECT, "REPLACE", 0, "Replace", ""}, {SEQ_CROSS, "CROSS", 0, "Cross", ""}, {SEQ_ADD, "ADD", 0, "Add", ""}, -- cgit v1.2.3 From 9c66deb47a1c2c7330d483090ec715a4c35e3e07 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Thu, 27 Aug 2009 20:37:50 +0000 Subject: SVN maintenance. --- source/blender/makesrna/intern/rna_gpencil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 2ef7d9d2d90..340ba1a0f31 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -1,5 +1,5 @@ /** - * $Id: rna_gpencil.c 22756 2009-08-25 04:05:37Z aligorith $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From d7bf9688ac78169a37fbfc0d3d5bcd5b5be19170 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 27 Aug 2009 23:29:07 +0000 Subject: fix for crash when a parent compound object didn't get a physics controller. also show this in the UI. --- source/blender/src/buttons_logic.c | 22 ++++++++++++++-------- .../Converter/BL_BlenderDataConversion.cpp | 4 +++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 0412aa72b37..6117c10c718 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -3513,14 +3513,20 @@ static void buttons_bullet(uiBlock *block, Object *ob) } if (ob->body_type!=OB_BODY_TYPE_SOFT) { - if (ob->parent) - uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Add to parent", 240,105,110,19, - &ob->gameflag, 0, 0, 0, 0, - "Add this shape to the parent compound shape"); - else - uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 240,105,110,19, - &ob->gameflag, 0, 0, 0, 0, - "Create a compound shape with the children's shape that are tagged for addition"); + if (ob->parent) { + if(ob->parent->gameflag & (OB_DYNAMIC|OB_COLLISION)) { + uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Add to parent", 240,105,110,19, + &ob->gameflag, 0, 0, 0, 0, + "Add this shape to the parent compound shape"); + } + } + else { + if(ob->gameflag & (OB_DYNAMIC|OB_COLLISION)) { + uiDefButBitI(block, TOG, OB_CHILD, B_REDR, "Compound", 240,105,110,19, + &ob->gameflag, 0, 0, 0, 0, + "Create a compound shape with the children's shape that are tagged for addition"); + } + } } } uiBlockEndAlign(block); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d2e6bbb43f7..c2566caba1e 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1381,7 +1381,9 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, bool isCompoundChild = false; bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD); - if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) { + /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller + * and cant be apart of the parents compound shape */ + if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) { if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD)) { -- cgit v1.2.3 From 208f6daa1d2631e0643a97e6d0f456255a0dcde4 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 28 Aug 2009 02:24:14 +0000 Subject: * Tweak texture paint view3d settings, make projection paint options dependent on the tool, rather than (weirdly) the tool's availability dependent on projection paint settings. --- release/ui/space_view3d_toolbar.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index bbca43279a7..0e6dc76d49d 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -362,10 +362,8 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column(align=True) col.item_enumR(settings, "tool", 'DRAW') col.item_enumR(settings, "tool", 'SOFTEN') - if settings.use_projection: - col.item_enumR(settings, "tool", 'CLONE') - else: - col.item_enumR(settings, "tool", 'SMEAR') + col.item_enumR(settings, "tool", 'CLONE') + col.item_enumR(settings, "tool", 'SMEAR') col = layout.column() col.itemR(brush, "color", text="") @@ -540,12 +538,22 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel): # col.itemR(vpaint, "mul", text="") -# ********** default tools for texturepaint **************** +# ********** options for projection paint **************** -class VIEW3D_PT_tools_texturepaint(View3DPanel): +class VIEW3D_PT_tools_projectpaint(View3DPanel): __context__ = "texturepaint" - __label__ = "Options" + __label__ = "Project Paint" + + def poll(self, context): + return context.tool_settings.image_paint.tool != 'SMEAR' + + def draw_header(self, context): + layout = self.layout + + ipaint = context.tool_settings.image_paint + layout.itemR(ipaint, "use_projection", text="") + def draw(self, context): layout = self.layout @@ -554,7 +562,6 @@ class VIEW3D_PT_tools_texturepaint(View3DPanel): use_projection= ipaint.use_projection col = layout.column() - col.itemR(ipaint, "use_projection") sub = col.column() sub.active = use_projection sub.itemR(ipaint, "use_occlude") @@ -631,5 +638,5 @@ bpy.types.register(VIEW3D_PT_tools_brush_curve) bpy.types.register(VIEW3D_PT_sculpt_options) bpy.types.register(VIEW3D_PT_tools_vertexpaint) bpy.types.register(VIEW3D_PT_tools_weightpaint) -bpy.types.register(VIEW3D_PT_tools_texturepaint) +bpy.types.register(VIEW3D_PT_tools_projectpaint) bpy.types.register(VIEW3D_PT_tools_particlemode) -- cgit v1.2.3 From 8794951d9f5b408568ea35d916b6217d165ba440 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 09:38:36 +0000 Subject: A python port of dataoc. --- release/datafiles/datatoc.py | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 release/datafiles/datatoc.py diff --git a/release/datafiles/datatoc.py b/release/datafiles/datatoc.py new file mode 100644 index 00000000000..805d7205651 --- /dev/null +++ b/release/datafiles/datatoc.py @@ -0,0 +1,72 @@ +#!/usr/bin/python3 +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2009 Blender Foundation. +# All rights reserved. +# +# Contributor(s): Jörg Müller +# +# ***** END GPL LICENCE BLOCK ***** + +import sys + +if len(sys.argv) < 2: + print("Usage: datatoc ") + sys.exit(1) + +filename = sys.argv[1] + +try: + fpin = open(filename, "rb"); +except: + print("Unable to open input <{0}>".format(sys.argv[1])) + sys.exit(1) + +size = fpin.seek(0, 2) +fpin.seek(0) + +if filename[0] == ".": + filename = filename[1:] + +cname = filename + ".c" +print("Making C file <{0}>".format(cname)) + +filename = filename.replace(".", "_") + +try: + fpout = open(cname, "w") +except: + print("Unable to open output <{0}>".format(cname)) + sys.exit(1) + +fpout.write("/* DataToC output of file <{0}> */\n\n".format(filename)) +fpout.write("int datatoc_{0}_size= {1};\n".format(filename, size)) + +fpout.write("char datatoc_{0}[]= {{\n".format(filename)) + +while size > 0: + size -= 1 + if size % 32 == 31: + fpout.write("\n") + + fpout.write("{0:3d},".format(ord(fpin.read(1)))) + +fpout.write("\n 0};\n\n") + +fpin.close() +fpout.close() -- cgit v1.2.3 From 3ac11df33bf47d98e1a945beaea99e9a98f716d2 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 11:13:45 +0000 Subject: First try of sound operators, untested. --- source/blender/editors/sound/sound_intern.h | 39 ++++++++++ source/blender/editors/sound/sound_ops.c | 107 ++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 source/blender/editors/sound/sound_intern.h create mode 100644 source/blender/editors/sound/sound_ops.c diff --git a/source/blender/editors/sound/sound_intern.h b/source/blender/editors/sound/sound_intern.h new file mode 100644 index 00000000000..b0d6abb3f00 --- /dev/null +++ b/source/blender/editors/sound/sound_intern.h @@ -0,0 +1,39 @@ +/** + * $Id:$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef ED_SOUND_INTERN_H +#define ED_SOUND_INTERN_H + +struct wmOperatorType; + +void SOUND_OT_open(wmOperatorType *ot); + +void sound_operatortype_init(void); + +#endif /* ED_SOUND_INTERN_H */ + diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c new file mode 100644 index 00000000000..59bb9c5319c --- /dev/null +++ b/source/blender/editors/sound/sound_ops.c @@ -0,0 +1,107 @@ +/** + * $Id:$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_sound_types.h" +#include "DNA_windowmanager_types.h" + +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_sound.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "AUD_C-API.h" + +#include "sound_intern.h" + +/******************** open sound operator ********************/ + +static int open_exec(bContext *C, wmOperator *op) +{ + char filename[FILE_MAX]; + bSound *sound; + AUD_SoundInfo info; + + RNA_string_get(op->ptr, "filename", filename); + + sound = sound_new_file(CTX_data_main(C), filename); + + if (sound==NULL || sound->handle == NULL) { + BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); + return OPERATOR_CANCELLED; + } + + info = AUD_getInfo(sound->handle); + + if (info.specs.format == AUD_FORMAT_INVALID) { + sound_delete(C, sound); + BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return WM_operator_filesel(C, op, event); +} + +void SOUND_OT_open(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Open"; + ot->idname= "SOUND_OT_open"; + ot->description= "Load a sound file into blender"; + + /* api callbacks */ + ot->exec= open_exec; + ot->invoke= open_invoke; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE); +} + +/* ******************************************************* */ + +void sound_operatortype_init(void) +{ + WM_operatortype_append(SOUND_OT_open); +} -- cgit v1.2.3 From 6a8020b9c6693bdb14885914e8688847e2d11629 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 12:27:29 +0000 Subject: First try in sound UI for the sequencer. --- release/ui/space_sequencer.py | 24 ++++++++++++++++++ source/blender/editors/include/ED_sound.h | 35 ++++++++++++++++++++++++++ source/blender/editors/sound/sound_intern.h | 2 -- source/blender/editors/sound/sound_ops.c | 6 +++-- source/blender/editors/space_api/spacetypes.c | 2 ++ source/blender/editors/space_image/image_ops.c | 2 +- 6 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 source/blender/editors/include/ED_sound.h diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index 1498c37d761..6b86ea5dabe 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -455,6 +455,29 @@ class SEQUENCER_PT_input(SequencerButtonsPanel): col.itemR(strip, "animation_start_offset", text="Start") col.itemR(strip, "animation_end_offset", text="End") +class SEQUENCER_PT_sound(SequencerButtonsPanel): + __label__ = "Sound" + + def poll(self, context): + if context.space_data.display_mode != 'SEQUENCER': + return False + + strip = act_strip(context) + if not strip: + return False + + return strip.type in ('SOUND') + + def draw(self, context): + layout = self.layout + + strip = act_strip(context) + + layout.template_ID(strip, "sound", new="sound.open") + + layout.itemR(strip.sound, "filename") + layout.itemR(strip.sound, "caching") + class SEQUENCER_PT_filter(SequencerButtonsPanel): __label__ = "Filter" @@ -558,6 +581,7 @@ bpy.types.register(SEQUENCER_MT_strip) bpy.types.register(SEQUENCER_PT_edit) # sequencer panels bpy.types.register(SEQUENCER_PT_effect) bpy.types.register(SEQUENCER_PT_input) +bpy.types.register(SEQUENCER_PT_sound) bpy.types.register(SEQUENCER_PT_filter) bpy.types.register(SEQUENCER_PT_proxy) diff --git a/source/blender/editors/include/ED_sound.h b/source/blender/editors/include/ED_sound.h new file mode 100644 index 00000000000..584370bc738 --- /dev/null +++ b/source/blender/editors/include/ED_sound.h @@ -0,0 +1,35 @@ +/** + * $Id:$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef ED_SOUND_H +#define ED_SOUND_H + +void ED_operatortypes_sound(void); + +#endif /* ED_SOUND_H */ + diff --git a/source/blender/editors/sound/sound_intern.h b/source/blender/editors/sound/sound_intern.h index b0d6abb3f00..eb793a0b661 100644 --- a/source/blender/editors/sound/sound_intern.h +++ b/source/blender/editors/sound/sound_intern.h @@ -33,7 +33,5 @@ struct wmOperatorType; void SOUND_OT_open(wmOperatorType *ot); -void sound_operatortype_init(void); - #endif /* ED_SOUND_INTERN_H */ diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 59bb9c5319c..a23a28423ef 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -38,6 +38,8 @@ #include "BKE_report.h" #include "BKE_sound.h" +#include "ED_sound.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -84,7 +86,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) void SOUND_OT_open(wmOperatorType *ot) { /* identifiers */ - ot->name= "Open"; + ot->name= "Open Sound"; ot->idname= "SOUND_OT_open"; ot->description= "Load a sound file into blender"; @@ -101,7 +103,7 @@ void SOUND_OT_open(wmOperatorType *ot) /* ******************************************************* */ -void sound_operatortype_init(void) +void ED_operatortypes_sound(void) { WM_operatortype_append(SOUND_OT_open); } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 61b6fe391ae..0d702144959 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -51,6 +51,7 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_space_api.h" +#include "ED_sound.h" #include "ED_uvedit.h" #include "ED_mball.h" @@ -99,6 +100,7 @@ void ED_spacetypes_init(void) ED_operatortypes_metaball(); ED_operatortypes_boids(); ED_operatortypes_gpencil(); + ED_operatortypes_sound(); ui_view2d_operatortypes(); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index d9f02a35142..7a39cd587eb 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -650,7 +650,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) void IMAGE_OT_open(wmOperatorType *ot) { /* identifiers */ - ot->name= "Open"; + ot->name= "Open Image"; ot->idname= "IMAGE_OT_open"; /* api callbacks */ -- cgit v1.2.3 From d7656684e213e4755e6f499d2e3a0734507e803d Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 12:38:59 +0000 Subject: Quick fix for scons (untested though :/). --- source/blender/editors/SConscript | 1 + source/blender/editors/sound/SConscript | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 source/blender/editors/sound/SConscript diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index 05f17dae1a1..ccffbdb15d5 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -15,6 +15,7 @@ SConscript(['datafiles/SConscript', 'gpencil/SConscript', 'physics/SConscript', 'preview/SConscript', + 'sound/SConscript', 'space_buttons/SConscript', 'space_file/SConscript', 'space_image/SConscript', diff --git a/source/blender/editors/sound/SConscript b/source/blender/editors/sound/SConscript new file mode 100644 index 00000000000..7968f4c53a9 --- /dev/null +++ b/source/blender/editors/sound/SConscript @@ -0,0 +1,14 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') + +incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' +incs += ' ../../windowmanager #/intern/guardedalloc' +incs += ' #/intern/guardedalloc' +incs += ' ../../makesrna ../../python' +incs += ' #/intern/audaspace/intern' + +defs = [] + +env.BlenderLib ( 'bf_editors_sound', sources, Split(incs), defs, libtype=['core'], priority=[35] ) -- cgit v1.2.3 From c15db042cc1b1168a9894a7f5848a866e7b3575a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 28 Aug 2009 12:41:45 +0000 Subject: Grease Pencil: WIP Code Reordering + Context Stuff * Shuffled some code around, and renamed some functions used for getting context info - Split UI-buttons into a separate file from stroke-drawing code - Removed some obsolete code (i.e. old paint code that used to be in _edit, but which has been moved to _paint). * Made drawing in 3D-View default to using the active object as the owner of the Grease Pencil data. For now, the drawing code will therefore only show the GP data for the active object only. More work to come on this. * Fixed freeing code for Objects/Scenes with GP data. --- source/blender/blenkernel/intern/object.c | 1 + source/blender/blenkernel/intern/scene.c | 5 + source/blender/blenloader/intern/readfile.c | 4 + source/blender/editors/animation/anim_filter.c | 2 +- source/blender/editors/gpencil/drawgpencil.c | 341 +--- source/blender/editors/gpencil/gpencil_buttons.c | 334 ++++ source/blender/editors/gpencil/gpencil_edit.c | 1636 +------------------- source/blender/editors/gpencil/gpencil_paint.c | 122 +- source/blender/editors/include/ED_gpencil.h | 36 +- .../editors/transform/transform_conversions.c | 2 +- source/blender/makesdna/DNA_object_types.h | 7 +- source/blender/makesrna/intern/rna_object.c | 7 + 12 files changed, 477 insertions(+), 2020 deletions(-) create mode 100644 source/blender/editors/gpencil/gpencil_buttons.c diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5e2a00c219d..6f57a658efa 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -284,6 +284,7 @@ void free_object(Object *ob) if(ob->adt) BKE_free_animdata((ID *)ob); if(ob->poselib) ob->poselib->id.us--; if(ob->dup_group) ob->dup_group->id.us--; + if(ob->gpd) ob->gpd->id.us--; if(ob->defbase.first) BLI_freelistN(&ob->defbase); if(ob->pose) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6dd362d15a8..63dabf18faa 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -245,6 +245,11 @@ void free_scene(Scene *sce) base= base->next; } /* do not free objects! */ + + if(sce->gpd) { + sce->gpd->id.us--; + sce->gpd= NULL; + } BLI_freelistN(&sce->base); seq_free_editing(sce); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5d61e3d305e..1a811ebc08a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3449,6 +3449,8 @@ static void lib_link_object(FileData *fd, Main *main) } for(a=0; atotcol; a++) ob->mat[a]= newlibadr_us(fd, ob->id.lib, ob->mat[a]); + ob->gpd= newlibadr_us(fd, ob->id.lib, ob->gpd); + ob->id.flag -= LIB_NEEDLINK; /* if id.us==0 a new base will be created later on */ @@ -10418,6 +10420,8 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) expand_doit(fd, mainvar, ob->poselib); expand_constraints(fd, mainvar, &ob->constraints); + expand_doit(fd, mainvar, ob->gpd); + // XXX depreceated - old animation system (for version patching only) expand_doit(fd, mainvar, ob->ipo); expand_doit(fd, mainvar, ob->action); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 37c8aeac13a..55fb1ccace0 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -885,7 +885,7 @@ static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter for (sa= sc->areabase.first; sa; sa= sa->next) { /* try to get gp data */ // XXX need to put back grease pencil api... - gpd= gpencil_data_getactive(sa); + gpd= gpencil_data_get_active(sa); if (gpd == NULL) continue; /* add gpd as channel too (if for drawing, and it has layers) */ diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 242be943507..4a48e9a4e3b 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -67,278 +67,11 @@ #include "ED_sequencer.h" #include "ED_util.h" -#include "UI_interface.h" #include "UI_resources.h" #include "UI_view2d.h" #include "gpencil_intern.h" -/* ************************************************** */ -/* GREASE PENCIL PANEL-UI DRAWING */ - -/* Every space which implements Grease-Pencil functionality should have a panel - * for the settings. All of the space-dependent parts should be coded in the panel - * code for that space, but the rest is all handled by generic panel here. - */ - -/* ------- Callbacks ----------- */ -/* These are just 'dummy wrappers' around gpencil api calls */ - -#if 0 -// XXX -/* make layer active one after being clicked on */ -void gp_ui_activelayer_cb (void *gpd, void *gpl) -{ - gpencil_layer_setactive(gpd, gpl); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* rename layer and set active */ -void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg) -{ - bGPdata *gpd= (bGPdata *)gpd_arg; - bGPDlayer *gpl= (bGPDlayer *)gpl_arg; - - BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info[0]), 128); - gpencil_layer_setactive(gpd, gpl); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* add a new layer */ -void gp_ui_addlayer_cb (void *gpd, void *dummy) -{ - gpencil_layer_addnew(gpd); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* delete active layer */ -void gp_ui_dellayer_cb (void *gpd, void *dummy) -{ - gpencil_layer_delactive(gpd); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* delete last stroke of active layer */ -void gp_ui_delstroke_cb (void *gpd, void *gpl) -{ - bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); - - if (gpf) { - if (gpf->framenum != CFRA) return; - - gpencil_layer_setactive(gpd, gpl); - gpencil_frame_delete_laststroke(gpl, gpf); - - scrarea_queue_winredraw(curarea); - } -} - -/* delete active frame of active layer */ -void gp_ui_delframe_cb (void *gpd, void *gpl) -{ - bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); - - gpencil_layer_setactive(gpd, gpl); - gpencil_layer_delframe(gpl, gpf); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* convert the active layer to geometry */ -void gp_ui_convertlayer_cb (void *gpd, void *gpl) -{ - gpencil_layer_setactive(gpd, gpl); - gpencil_convert_menu(); - - scrarea_queue_winredraw(curarea); -} -#endif - -/* ------- Drawing Code ------- */ - -#if 0 -/* XXX */ -/* draw the controls for a given layer */ -static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short *xco, short *yco) -{ - uiBut *but; - short active= (gpl->flag & GP_LAYER_ACTIVE); - short width= 314; - short height; - int rb_col; - - /* unless button has own callback, it adds this callback to button */ - uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl); - - /* draw header */ - { - uiBlockSetEmboss(block, UI_EMBOSSN); - - /* rounded header */ - if (active) uiBlockSetCol(block, TH_BUT_ACTION); - rb_col= (active)?-20:20; - uiDefBut(block, ROUNDBOX, B_REDR, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), ""); - if (active) uiBlockSetCol(block, TH_AUTO); - - /* lock toggle */ - uiDefIconButBitI(block, ICONTOG, GP_LAYER_LOCKED, B_REDR, ICON_UNLOCKED, *xco-7, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Layer cannot be modified"); - } - - /* when layer is locked or hidden, only draw header */ - if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) { - char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */ - - height= 0; - - /* visibility button (only if hidden but not locked!) */ - if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) - uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); - - /* name */ - if (gpl->flag & GP_LAYER_HIDE) - sprintf(name, "%s (Hidden)", gpl->info); - else - sprintf(name, "%s (Locked)", gpl->info); - uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)"); - - /* delete button (only if hidden but not locked!) */ - if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) { - but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); - uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); - } - uiBlockSetEmboss(block, UI_EMBOSS); - } - else { - height= 97; - - /* draw rest of header */ - { - /* visibility button */ - uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); - - uiBlockSetEmboss(block, UI_EMBOSS); - - /* name */ - but= uiDefButC(block, TEX, B_REDR, "Info:", *xco+36, *yco, 240, 19, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)"); - uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl); - - /* delete 'button' */ - uiBlockSetEmboss(block, UI_EMBOSSN); - - but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); - uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); - - uiBlockSetEmboss(block, UI_EMBOSS); - } - - /* draw backdrop */ - if (active) uiBlockSetCol(block, TH_BUT_ACTION); - uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); - if (active) uiBlockSetCol(block, TH_AUTO); - - /* draw settings */ - { - /* color */ - uiBlockBeginAlign(block); - uiDefButF(block, COL, B_REDR, "", *xco, *yco-26, 150, 19, gpl->color, 0, 0, 0, 0, "Color to use for all strokes on this Grease Pencil Layer"); - uiDefButF(block, NUMSLI, B_REDR, "Opacity: ", *xco,*yco-45,150,19, &gpl->color[3], 0.3f, 1.0f, 0, 0, "Visibility of stroke (0.3 to 1.0)"); - uiBlockEndAlign(block); - - /* stroke thickness */ - uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)"); - - /* debugging options */ - if (G.f & G_DEBUG) { - uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes"); - } - - /* onion-skinning */ - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, GP_LAYER_ONIONSKIN, B_REDR, "Onion-Skin", *xco+160, *yco-26, 140, 20, &gpl->flag, 0, 0, 0, 0, "Ghost frames on either side of frame"); - uiDefButS(block, NUMSLI, B_REDR, "GStep:", *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Max number of frames on either side of active frame to show (0 = just 'first' available sketch on either side)"); - uiBlockEndAlign(block); - - /* options */ - uiBlockBeginAlign(block); - if (curarea->spacetype == SPACE_VIEW3D) { - but= uiDefBut(block, BUT, B_REDR, "Convert to...", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Converts this layer's strokes to geometry (Hotkey = Alt-Shift-C)"); - uiButSetFunc(but, gp_ui_convertlayer_cb, gpd, gpl); - } - else { - but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)"); - uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl); - } - - but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)"); - uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl); - uiBlockEndAlign(block); - } - } - - /* adjust height for new to start */ - (*yco) -= (height + 27); -} -#endif -/* Draw the contents for a grease-pencil panel. This assumes several things: - * - that panel has been created, is 318 x 204. max yco is 225 - * - that a toggle for turning on/off gpencil drawing is 150 x 20, starting from (10,225) - * which is basically the top left-hand corner - * It will return the amount of extra space to extend the panel by - */ -short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa) -{ -#if 0 - uiBut *but; - bGPDlayer *gpl; - short xco= 10, yco= 170; - - /* draw gpd settings first */ - { - /* add new layer buttons */ - but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,205,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer"); - uiButSetFunc(but, gp_ui_addlayer_cb, gpd, NULL); - - - /* show override lmb-clicks button + painting lock */ - uiBlockBeginAlign(block); - if ((gpd->flag & GP_DATA_EDITPAINT)==0) { - uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); - - uiBlockSetCol(block, TH_BUT_SETTING); - uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)"); - uiBlockSetCol(block, TH_AUTO); - } - else - uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); - uiBlockEndAlign(block); - - /* 'view align' button (naming depends on context) */ - if (sa->spacetype == SPACE_VIEW3D) - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); - else - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas"); - } - - /* draw for each layer */ - for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { - gp_drawui_layer(block, gpd, gpl, &xco, &yco); - } - - /* return new height if necessary */ - return (yco < 0) ? (204 - yco) : 204; -#endif - return 0; -} - /* ************************************************** */ /* GREASE PENCIL DRAWING */ @@ -432,8 +165,8 @@ static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sfl co[1]= (points->y * winy) + offsy; } else { - co[0]= (points->x / 1000 * winx); - co[1]= (points->y / 1000 * winy); + co[0]= (points->x / 100 * winx); + co[1]= (points->y / 100 * winy); } /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple dot looks ok @@ -525,8 +258,8 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, glVertex2f(x, y); } else { - const float x= (pt->x / 1000 * winx); - const float y= (pt->y / 1000 * winy); + const float x= (pt->x / 100 * winx); + const float y= (pt->y / 100 * winy); glVertex2f(x, y); } @@ -565,10 +298,10 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, s1[1]= (pt2->y * winy) + offsy; } else { - s0[0]= (pt1->x / 1000 * winx); - s0[1]= (pt1->y / 1000 * winy); - s1[0]= (pt2->x / 1000 * winx); - s1[1]= (pt2->y / 1000 * winy); + s0[0]= (pt1->x / 100 * winx); + s0[1]= (pt1->y / 100 * winy); + s1[0]= (pt2->x / 100 * winx); + s1[1]= (pt2->y / 100 * winy); } /* calculate gradient and normal - 'angle'=(ny/nx) */ @@ -713,8 +446,8 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, glVertex2f(x, y); } else { - const float x= (float)(pt->x / 1000 * winx); - const float y= (float)(pt->y / 1000 * winy); + const float x= (float)(pt->x / 100 * winx); + const float y= (float)(pt->y / 100 * winy); glVertex2f(x, y); } @@ -872,47 +605,7 @@ static void gp_draw_data (bGPdata *gpd, int offsx, int offsy, int winx, int winy /* turn off alpha blending, then smooth lines */ glDisable(GL_BLEND); // alpha blending glDisable(GL_LINE_SMOOTH); // smooth lines - - /* show info for debugging the status of gpencil */ -#if 0 - if ( ((dflag & GP_DRAWDATA_NOSTATUS)==0) && (gpd->flag & GP_DATA_DISPINFO) ) { - char printable[256]; - short xmax; - /* get text to display */ - if (actlay) { - if (gpd->flag & GP_DATA_EDITPAINT) - UI_ThemeColor(TH_BONE_POSE); // should be blue-ish - else if (actlay->actframe == NULL) - UI_ThemeColor(TH_REDALERT); - else if (actlay->actframe->framenum == cfra) - UI_ThemeColor(TH_VERTEX_SELECT); // should be yellow - else - UI_ThemeColor(TH_TEXT_HI); - - if (actlay->actframe) { - sprintf(printable, "GPencil: Layer ('%s'), Frame (%d)%s", - actlay->info, actlay->actframe->framenum, - ((gpd->flag & GP_DATA_EDITPAINT)?" , Draw Mode On":"") ); - } - else { - sprintf(printable, "GPencil: Layer ('%s'), Frame %s", - actlay->info, ((gpd->flag & GP_DATA_EDITPAINT)?" , Draw Mode On":"") ); - } - } - else { - UI_ThemeColor(TH_REDALERT); - sprintf(printable, "GPencil: Layer "); - } - xmax= GetButStringLength(printable); - - /* only draw it if view is wide enough (assume padding of 20 is enough for now) */ - if (winx > (xmax + 20)) { - BLF_draw_default(winx-xmax, winy-20, 0.0f, printable); - } - } -#endif - /* restore initial gl conditions */ glLineWidth(1.0); glPointSize(1.0); @@ -921,6 +614,12 @@ static void gp_draw_data (bGPdata *gpd, int offsx, int offsy, int winx, int winy /* ----- Grease Pencil Sketches Drawing API ------ */ +// ............................ +// XXX +// We need to review the calls below, since they may be/are not that suitable for +// the new ways that we intend to be drawing data... +// ............................ + /* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ void draw_gpencil_2dimage (bContext *C, ImBuf *ibuf) { @@ -933,7 +632,7 @@ void draw_gpencil_2dimage (bContext *C, ImBuf *ibuf) /* check that we have grease-pencil stuff to draw */ if (ELEM(NULL, sa, ibuf)) return; - gpd= gpencil_data_getactive(C); + gpd= gpencil_data_get_active(C); // XXX if (gpd == NULL) return; /* calculate rect */ @@ -1007,7 +706,7 @@ void draw_gpencil_2dview (bContext *C, short onlyv2d) /* check that we have grease-pencil stuff to draw */ if (sa == NULL) return; - gpd= gpencil_data_getactive(C); + gpd= gpencil_data_get_active(C); // XXX if (gpd == NULL) return; /* draw it! */ @@ -1026,7 +725,7 @@ void draw_gpencil_3dview (bContext *C, short only3d) int dflag = 0; /* check that we have grease-pencil stuff to draw */ - gpd= gpencil_data_getactive(C); + gpd= gpencil_data_get_active(C); // XXX if (gpd == NULL) return; /* draw it! */ @@ -1046,7 +745,7 @@ void draw_gpencil_oglrender (bContext *C) /* assume gpencil data comes from v3d */ if (v3d == NULL) return; - gpd= gpencil_data_getactive(C); + gpd= gpencil_data_get_active(C); if (gpd == NULL) return; /* pass 1: draw 3d-strokes ------------ > */ diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c new file mode 100644 index 00000000000..87f3b60dcc2 --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -0,0 +1,334 @@ +/** + * $Id: drawgpencil.c 22802 2009-08-26 12:01:15Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "DNA_gpencil_types.h" +#include "DNA_listBase.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_windowmanager_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" +#include "BKE_utildefines.h" + +#include "PIL_time.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "ED_gpencil.h" +#include "ED_sequencer.h" +#include "ED_util.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "gpencil_intern.h" + +/* ************************************************** */ +/* GREASE PENCIL PANEL-UI DRAWING */ + +/* Every space which implements Grease-Pencil functionality should have a panel + * for the settings. All of the space-dependent parts should be coded in the panel + * code for that space, but the rest is all handled by generic panel here. + */ + +/* ------- Callbacks ----------- */ +/* These are just 'dummy wrappers' around gpencil api calls */ + +#if 0 +// XXX +/* make layer active one after being clicked on */ +void gp_ui_activelayer_cb (void *gpd, void *gpl) +{ + gpencil_layer_setactive(gpd, gpl); + + scrarea_queue_winredraw(curarea); + allqueue(REDRAWACTION, 0); +} + +/* rename layer and set active */ +void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg) +{ + bGPdata *gpd= (bGPdata *)gpd_arg; + bGPDlayer *gpl= (bGPDlayer *)gpl_arg; + + BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info[0]), 128); + gpencil_layer_setactive(gpd, gpl); + + scrarea_queue_winredraw(curarea); + allqueue(REDRAWACTION, 0); +} + +/* add a new layer */ +void gp_ui_addlayer_cb (void *gpd, void *dummy) +{ + gpencil_layer_addnew(gpd); + + scrarea_queue_winredraw(curarea); + allqueue(REDRAWACTION, 0); +} + +/* delete active layer */ +void gp_ui_dellayer_cb (void *gpd, void *dummy) +{ + gpencil_layer_delactive(gpd); + + scrarea_queue_winredraw(curarea); + allqueue(REDRAWACTION, 0); +} + +/* delete last stroke of active layer */ +void gp_ui_delstroke_cb (void *gpd, void *gpl) +{ + bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); + + if (gpf) { + if (gpf->framenum != CFRA) return; + + gpencil_layer_setactive(gpd, gpl); + gpencil_frame_delete_laststroke(gpl, gpf); + + scrarea_queue_winredraw(curarea); + } +} + +/* delete active frame of active layer */ +void gp_ui_delframe_cb (void *gpd, void *gpl) +{ + bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); + + gpencil_layer_setactive(gpd, gpl); + gpencil_layer_delframe(gpl, gpf); + + scrarea_queue_winredraw(curarea); + allqueue(REDRAWACTION, 0); +} + +/* convert the active layer to geometry */ +void gp_ui_convertlayer_cb (void *gpd, void *gpl) +{ + gpencil_layer_setactive(gpd, gpl); + gpencil_convert_menu(); + + scrarea_queue_winredraw(curarea); +} +#endif + +/* ------- Drawing Code ------- */ + +#if 0 +/* XXX */ +/* draw the controls for a given layer */ +static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short *xco, short *yco) +{ + uiBut *but; + short active= (gpl->flag & GP_LAYER_ACTIVE); + short width= 314; + short height; + int rb_col; + + /* unless button has own callback, it adds this callback to button */ + uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl); + + /* draw header */ + { + uiBlockSetEmboss(block, UI_EMBOSSN); + + /* rounded header */ + if (active) uiBlockSetCol(block, TH_BUT_ACTION); + rb_col= (active)?-20:20; + uiDefBut(block, ROUNDBOX, B_REDR, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), ""); + if (active) uiBlockSetCol(block, TH_AUTO); + + /* lock toggle */ + uiDefIconButBitI(block, ICONTOG, GP_LAYER_LOCKED, B_REDR, ICON_UNLOCKED, *xco-7, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Layer cannot be modified"); + } + + /* when layer is locked or hidden, only draw header */ + if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) { + char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */ + + height= 0; + + /* visibility button (only if hidden but not locked!) */ + if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) + uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); + + /* name */ + if (gpl->flag & GP_LAYER_HIDE) + sprintf(name, "%s (Hidden)", gpl->info); + else + sprintf(name, "%s (Locked)", gpl->info); + uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)"); + + /* delete button (only if hidden but not locked!) */ + if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) { + but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); + uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); + } + uiBlockSetEmboss(block, UI_EMBOSS); + } + else { + height= 97; + + /* draw rest of header */ + { + /* visibility button */ + uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); + + uiBlockSetEmboss(block, UI_EMBOSS); + + /* name */ + but= uiDefButC(block, TEX, B_REDR, "Info:", *xco+36, *yco, 240, 19, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)"); + uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl); + + /* delete 'button' */ + uiBlockSetEmboss(block, UI_EMBOSSN); + + but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); + uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); + + uiBlockSetEmboss(block, UI_EMBOSS); + } + + /* draw backdrop */ + if (active) uiBlockSetCol(block, TH_BUT_ACTION); + uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); + if (active) uiBlockSetCol(block, TH_AUTO); + + /* draw settings */ + { + /* color */ + uiBlockBeginAlign(block); + uiDefButF(block, COL, B_REDR, "", *xco, *yco-26, 150, 19, gpl->color, 0, 0, 0, 0, "Color to use for all strokes on this Grease Pencil Layer"); + uiDefButF(block, NUMSLI, B_REDR, "Opacity: ", *xco,*yco-45,150,19, &gpl->color[3], 0.3f, 1.0f, 0, 0, "Visibility of stroke (0.3 to 1.0)"); + uiBlockEndAlign(block); + + /* stroke thickness */ + uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)"); + + /* debugging options */ + if (G.f & G_DEBUG) { + uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes"); + } + + /* onion-skinning */ + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, GP_LAYER_ONIONSKIN, B_REDR, "Onion-Skin", *xco+160, *yco-26, 140, 20, &gpl->flag, 0, 0, 0, 0, "Ghost frames on either side of frame"); + uiDefButS(block, NUMSLI, B_REDR, "GStep:", *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Max number of frames on either side of active frame to show (0 = just 'first' available sketch on either side)"); + uiBlockEndAlign(block); + + /* options */ + uiBlockBeginAlign(block); + if (curarea->spacetype == SPACE_VIEW3D) { + but= uiDefBut(block, BUT, B_REDR, "Convert to...", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Converts this layer's strokes to geometry (Hotkey = Alt-Shift-C)"); + uiButSetFunc(but, gp_ui_convertlayer_cb, gpd, gpl); + } + else { + but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)"); + uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl); + } + + but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)"); + uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl); + uiBlockEndAlign(block); + } + } + + /* adjust height for new to start */ + (*yco) -= (height + 27); +} +#endif +/* Draw the contents for a grease-pencil panel. This assumes several things: + * - that panel has been created, is 318 x 204. max yco is 225 + * - that a toggle for turning on/off gpencil drawing is 150 x 20, starting from (10,225) + * which is basically the top left-hand corner + * It will return the amount of extra space to extend the panel by + */ +short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa) +{ +#if 0 + uiBut *but; + bGPDlayer *gpl; + short xco= 10, yco= 170; + + /* draw gpd settings first */ + { + /* add new layer buttons */ + but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,205,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer"); + uiButSetFunc(but, gp_ui_addlayer_cb, gpd, NULL); + + + /* show override lmb-clicks button + painting lock */ + uiBlockBeginAlign(block); + if ((gpd->flag & GP_DATA_EDITPAINT)==0) { + uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); + + uiBlockSetCol(block, TH_BUT_SETTING); + uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)"); + uiBlockSetCol(block, TH_AUTO); + } + else + uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); + uiBlockEndAlign(block); + + /* 'view align' button (naming depends on context) */ + if (sa->spacetype == SPACE_VIEW3D) + uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); + else + uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas"); + } + + /* draw for each layer */ + for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { + gp_drawui_layer(block, gpd, gpl, &xco, &yco); + } + + /* return new height if necessary */ + return (yco < 0) ? (204 - yco) : 204; +#endif + return 0; +} + +/* ************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 4480da45572..3130e190ce2 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * The Original Code is Copyright (C) 2008, Blender Foundation + * The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung * This is a new part of Blender * * Contributor(s): Joshua Leung @@ -25,8 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -#if 0 // XXX COMPILE GUARDS FOR OLD CODE - + #include #include #include @@ -69,6 +68,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "RNA_access.h" + #include "UI_view2d.h" #include "ED_armature.h" @@ -76,1627 +77,70 @@ #include "ED_sequencer.h" #include "ED_view3d.h" -#include "PIL_time.h" /* sleep */ - #include "gpencil_intern.h" -/* XXX */ -static void BIF_undo_push() {} -static void error() {} -static int pupmenu() {return 0;} -static void add_object_draw() {} -static int get_activedevice() {return 0;} -#define L_MOUSE 0 -#define R_MOUSE 0 - -/* ************************************************** */ -/* XXX - OLD DEPRECEATED CODE... */ - -/* ----------- GP-Datablock API ------------- */ - -/* get the appropriate bGPdata from the active/given context */ -// XXX region or region data? -bGPdata *gpencil_data_getactive (ScrArea *sa) -{ - ScrArea *curarea= NULL; // XXX - - /* error checking */ - if ((sa == NULL) && (curarea == NULL)) - return NULL; - if (sa == NULL) - sa= curarea; - - /* handle depending on spacetype */ - switch (sa->spacetype) { - case SPACE_VIEW3D: - { - View3D *v3d= sa->spacedata.first; - return v3d->gpd; - } - break; - case SPACE_NODE: - { - SpaceNode *snode= sa->spacedata.first; - return snode->gpd; - } - break; - case SPACE_SEQ: - { - SpaceSeq *sseq= sa->spacedata.first; - - /* only applicable for image modes */ - if (sseq->mainb != SEQ_DRAW_SEQUENCE) - return sseq->gpd; - } - break; - case SPACE_IMAGE: - { - SpaceImage *sima= sa->spacedata.first; - return sima->gpd; - } - break; - } - - /* nothing found */ - return NULL; -} - -/* set bGPdata for the active/given context, and return success/fail */ -short gpencil_data_setactive (ScrArea *sa, bGPdata *gpd) -{ - ScrArea *curarea= NULL; // XXX - - /* error checking */ - if ((sa == NULL) && (curarea == NULL)) - return 0; - if (gpd == NULL) - return 0; - if (sa == NULL) - sa= curarea; - - /* handle depending on spacetype */ - // TODO: someday we should have multi-user data, so no need to loose old data - switch (sa->spacetype) { - case SPACE_VIEW3D: - { - View3D *v3d= sa->spacedata.first; - - /* free the existing block */ - if (v3d->gpd) - free_gpencil_data(v3d->gpd); - v3d->gpd= gpd; - - return 1; - } - break; - case SPACE_NODE: - { - SpaceNode *snode= sa->spacedata.first; - - /* free the existing block */ - if (snode->gpd) - free_gpencil_data(snode->gpd); - snode->gpd= gpd; - - /* set special settings */ - gpd->flag |= GP_DATA_VIEWALIGN; - - return 1; - } - break; - case SPACE_SEQ: - { - SpaceSeq *sseq= sa->spacedata.first; - - /* only applicable if right mode */ - if (sseq->mainb != SEQ_DRAW_SEQUENCE) { - /* free the existing block */ - if (sseq->gpd) - free_gpencil_data(sseq->gpd); - sseq->gpd= gpd; - - return 1; - } - } - break; - case SPACE_IMAGE: - { - SpaceImage *sima= sa->spacedata.first; - - if (sima->gpd) - free_gpencil_data(sima->gpd); - sima->gpd= gpd; - - return 1; - } - break; - } - - /* failed to add */ - return 0; -} - -/* return the ScrArea that has the given GP-datablock - * - assumes that only searching in current screen - * - is based on GP-datablocks only being able to - * exist for one area at a time (i.e. not multiuser) - */ -ScrArea *gpencil_data_findowner (bGPdata *gpd) -{ - bScreen *curscreen= NULL; // XXX - ScrArea *sa; - - /* error checking */ - if (gpd == NULL) - return NULL; - - /* loop over all scrareas for current screen, and check if that area has this gpd */ - for (sa= curscreen->areabase.first; sa; sa= sa->next) { - /* use get-active func to see if match */ - if (gpencil_data_getactive(sa) == gpd) - return sa; - } - - /* not found */ - return NULL; -} - -/* ************************************************** */ -/* GREASE-PENCIL EDITING - Tools */ - -/* --------- Data Deletion ---------- */ - -/* delete the last stroke on the active layer */ -void gpencil_delete_laststroke (bGPdata *gpd, int cfra) -{ - bGPDlayer *gpl= gpencil_layer_getactive(gpd); - bGPDframe *gpf= gpencil_layer_getframe(gpl, cfra, 0); - - gpencil_frame_delete_laststroke(gpl, gpf); -} - -/* delete the active frame */ -void gpencil_delete_actframe (bGPdata *gpd, int cfra) -{ - bGPDlayer *gpl= gpencil_layer_getactive(gpd); - bGPDframe *gpf= gpencil_layer_getframe(gpl, cfra, 0); - - gpencil_layer_delframe(gpl, gpf); -} - - - -/* delete various grase-pencil elements - * mode: 1 - last stroke - * 2 - active frame - * 3 - active layer - */ -void gpencil_delete_operation (int cfra, short mode) -{ - bGPdata *gpd; - - /* get datablock to work on */ - gpd= gpencil_data_getactive(NULL); - if (gpd == NULL) return; - - switch (mode) { - case 1: /* last stroke */ - gpencil_delete_laststroke(gpd, cfra); - break; - case 2: /* active frame */ - gpencil_delete_actframe(gpd, cfra); - break; - case 3: /* active layer */ - gpencil_layer_delactive(gpd); - break; - } - - /* redraw and undo-push */ - BIF_undo_push("GPencil Delete"); -} - -/* display a menu for deleting different grease-pencil elements */ -void gpencil_delete_menu (void) -{ - bGPdata *gpd= gpencil_data_getactive(NULL); - int cfra= 0; // XXX - short mode; - - /* only show menu if it will be relevant */ - if (gpd == NULL) return; - - mode= pupmenu("Grease Pencil Erase...%t|Last Stroke%x1|Active Frame%x2|Active Layer%x3"); - if (mode <= 0) return; - - gpencil_delete_operation(cfra, mode); -} - -/* --------- Data Conversion ---------- */ - -/* convert the coordinates from the given stroke point into 3d-coordinates */ -static void gp_strokepoint_convertcoords (bGPDstroke *gps, bGPDspoint *pt, float p3d[3]) -{ - ARegion *ar= NULL; // XXX - - if (gps->flag & GP_STROKE_3DSPACE) { - /* directly use 3d-coordinates */ - VecCopyf(p3d, &pt->x); - } - else { - short mval[2]; - int mx=0, my=0; - float *fp= give_cursor(NULL, NULL); // XXX should be scene, v3d - float dvec[3]; - - /* get screen coordinate */ - if (gps->flag & GP_STROKE_2DSPACE) { - // XXX - // View2D *v2d= spacelink_get_view2d(curarea->spacedata.first); - // UI_view2d_view_to_region(v2d, pt->x, pt->y, &mx, &my); - } - else { - // XXX - // mx= (short)(pt->x / 1000 * curarea->winx); - // my= (short)(pt->y / 1000 * curarea->winy); - } - - /* convert screen coordinate to 3d coordinates - * - method taken from editview.c - mouse_cursor() - */ - project_short_noclip(ar, fp, mval); - window_to_3d_delta(ar, dvec, mval[0]-mx, mval[1]-my); - VecSubf(p3d, fp, dvec); - } -} - -/* --- */ +/* ************************************************ */ +/* Context Wrangling... */ -/* convert stroke to 3d path */ -static void gp_stroke_to_path (bGPDlayer *gpl, bGPDstroke *gps, Curve *cu) +/* 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) { - bGPDspoint *pt; - Nurb *nu; - BPoint *bp; - int i; - - /* create new 'nurb' within the curve */ - nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)"); - - nu->pntsu= gps->totpoints; - nu->pntsv= 1; - nu->orderu= gps->totpoints; - nu->flagu= 2; /* endpoint */ - nu->resolu= 32; - - nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*gps->totpoints, "bpoints"); - - /* add points */ - for (i=0, pt=gps->points, bp=nu->bp; i < gps->totpoints; i++, pt++, bp++) { - float p3d[3]; - - /* get coordinates to add at */ - gp_strokepoint_convertcoords(gps, pt, p3d); - VecCopyf(bp->vec, p3d); - - /* set settings */ - bp->f1= SELECT; - bp->radius = bp->weight = pt->pressure * gpl->thickness; - } - - /* add nurb to curve */ - BLI_addtail(&cu->nurb, nu); -} - -/* convert stroke to 3d bezier */ -static void gp_stroke_to_bezier (bGPDlayer *gpl, bGPDstroke *gps, Curve *cu) -{ - bGPDspoint *pt; - Nurb *nu; - BezTriple *bezt; - int i; - - /* create new 'nurb' within the curve */ - nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)"); - - nu->pntsu= gps->totpoints; - nu->resolu= 12; - nu->resolv= 12; - nu->type= CU_BEZIER; - nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints*sizeof(BezTriple), "bezts"); - - /* add points */ - for (i=0, pt=gps->points, bezt=nu->bezt; i < gps->totpoints; i++, pt++, bezt++) { - float p3d[3]; - - /* get coordinates to add at */ - gp_strokepoint_convertcoords(gps, pt, p3d); - - /* TODO: maybe in future the handles shouldn't be in same place */ - VecCopyf(bezt->vec[0], p3d); - VecCopyf(bezt->vec[1], p3d); - VecCopyf(bezt->vec[2], p3d); - - /* 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; - } - - /* must calculate handles or else we crash */ - calchandlesNurb(nu); - - /* add nurb to curve */ - BLI_addtail(&cu->nurb, nu); -} - -/* convert a given grease-pencil layer to a 3d-curve representation (using current view if appropriate) */ -static void gp_layer_to_curve (bGPdata *gpd, bGPDlayer *gpl, Scene *scene, short mode) -{ - bGPDframe *gpf= gpencil_layer_getframe(gpl, scene->r.cfra, 0); - bGPDstroke *gps; - Object *ob; - Curve *cu; - - /* error checking */ - if (ELEM3(NULL, gpd, gpl, gpf)) - return; - - /* only convert if there are any strokes on this layer's frame to convert */ - if (gpf->strokes.first == NULL) - return; + Scene *scene= CTX_data_scene(C); + ScrArea *sa= CTX_wm_area(C); - /* init the curve object (remove rotation and get curve data from it) - * - must clear transforms set on object, as those skew our results + /* if there's an active area, check if the particular editor may + * have defined any special Grease Pencil context for editing... */ - add_object_draw(OB_CURVE); - ob= OBACT; - ob->loc[0]= ob->loc[1]= ob->loc[2]= 0; - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0; - cu= ob->data; - cu->flag |= CU_3D; - - /* rename object and curve to layer name */ - rename_id((ID *)ob, gpl->info); - rename_id((ID *)cu, gpl->info); - - /* add points to curve */ - for (gps= gpf->strokes.first; gps; gps= gps->next) { - switch (mode) { - case 1: - gp_stroke_to_path(gpl, gps, cu); - break; - case 2: - gp_stroke_to_bezier(gpl, gps, cu); - break; - } - } -} - -/* --- */ - -/* convert a stroke to a bone chain */ -static void gp_stroke_to_bonechain (bGPDlayer *gpl, bGPDstroke *gps, bArmature *arm, ListBase *bones) -{ - EditBone *ebo, *prev=NULL; - bGPDspoint *pt, *ptn; - int i; - - /* add each segment separately */ - for (i=0, pt=gps->points, ptn=gps->points+1; i < (gps->totpoints-1); prev=ebo, i++, pt++, ptn++) { - float p3da[3], p3db[3]; - - /* get coordinates to add at */ - gp_strokepoint_convertcoords(gps, pt, p3da); - gp_strokepoint_convertcoords(gps, ptn, p3db); - - /* allocate new bone */ - ebo= MEM_callocN(sizeof(EditBone), "eBone"); - - VecCopyf(ebo->head, p3da); - VecCopyf(ebo->tail, p3db); - - /* add new bone - note: sync with editarmature.c::add_editbone() */ - { - BLI_strncpy(ebo->name, "Stroke", 32); - unique_editbone_name(bones, ebo->name, NULL); - - BLI_addtail(bones, ebo); - - if (i > 0) + if (sa) { + switch (sa->spacetype) { + case SPACE_VIEW3D: /* 3D-View */ { - ebo->flag |= BONE_CONNECTED; - } - ebo->weight= 1.0f; - ebo->dist= 0.25f; - ebo->xwidth= 0.1f; - ebo->zwidth= 0.1f; - ebo->ease1= 1.0f; - ebo->ease2= 1.0f; - ebo->rad_head= pt->pressure * gpl->thickness * 0.1f; - ebo->rad_tail= ptn->pressure * gpl->thickness * 0.1f; - ebo->segments= 1; - ebo->layer= arm->layer; - } - - /* set parenting */ - ebo->parent= prev; - } -} - -/* convert a given grease-pencil layer to a 3d-curve representation (using current view if appropriate) */ -// XXX depreceated... we now have etch-a-ton for this... -static void gp_layer_to_armature (bGPdata *gpd, bGPDlayer *gpl, Scene *scene, View3D *v3d, short mode) -{ - bGPDframe *gpf= gpencil_layer_getframe(gpl, scene->r.cfra, 0); - bGPDstroke *gps; - Object *ob; - bArmature *arm; - - /* error checking */ - if (ELEM3(NULL, gpd, gpl, gpf)) - return; - - /* only convert if there are any strokes on this layer's frame to convert */ - if (gpf->strokes.first == NULL) - return; - - /* init the armature object (remove rotation and assign armature data to it) - * - must clear transforms set on object, as those skew our results - */ - add_object_draw(OB_ARMATURE); - ob= OBACT; - ob->loc[0]= ob->loc[1]= ob->loc[2]= 0; - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0; - arm= ob->data; - - /* rename object and armature to layer name */ - rename_id((ID *)ob, gpl->info); - rename_id((ID *)arm, gpl->info); - - /* this is editmode armature */ - arm->edbo= MEM_callocN(sizeof(ListBase), "arm edbo"); - - /* convert segments to bones, strokes to bone chains */ - for (gps= gpf->strokes.first; gps; gps= gps->next) { - gp_stroke_to_bonechain(gpl, gps, arm, arm->edbo); - } - - /* adjust roll of bones - * - set object as EditMode object, but need to clear afterwards! - * - use 'align to world z-up' option - */ - { - /* set our data as if we're in editmode to fool auto_align_armature() */ - scene->obedit= ob; - - /* WARNING: need to make sure this magic number doesn't change */ - auto_align_armature(scene, v3d, 2); - - scene->obedit= NULL; - } - - /* flush editbones to armature */ - ED_armature_from_edit(scene, ob); - ED_armature_edit_free(ob); -} - -/* --- */ - -/* convert grease-pencil strokes to another representation - * mode: 1 - Active layer to path - * 2 - Active layer to bezier - * 3 - Active layer to armature - */ -void gpencil_convert_operation (short mode) -{ - Scene *scene= NULL; // XXX - View3D *v3d= NULL; // XXX - RegionView3D *rv3d= NULL; // XXX - bGPdata *gpd; - float *fp= give_cursor(scene, v3d); - - /* get datablock to work on */ - gpd= gpencil_data_getactive(NULL); - if (gpd == NULL) return; - - /* initialise 3d-cursor correction globals */ - initgrabz(rv3d, fp[0], fp[1], fp[2]); - - /* handle selection modes */ - switch (mode) { - case 1: /* active layer only (to path) */ - case 2: /* active layer only (to bezier) */ - { - bGPDlayer *gpl= gpencil_layer_getactive(gpd); - gp_layer_to_curve(gpd, gpl, scene, mode); - } - break; - case 3: /* active layer only (to armature) */ - { - bGPDlayer *gpl= gpencil_layer_getactive(gpd); - gp_layer_to_armature(gpd, gpl, scene, v3d, mode); - } - break; - } - - /* redraw and undo-push */ - BIF_undo_push("GPencil Convert"); -} - -/* ************************************************** */ -/* GREASE-PENCIL EDITING MODE - Painting */ - -/* ---------- 'Globals' and Defines ----------------- */ - -/* maximum sizes of gp-session buffer */ -#define GP_STROKE_BUFFER_MAX 5000 - -/* Macros for accessing sensitivity thresholds... */ - /* minimum number of pixels mouse should move before new point created */ -#define MIN_MANHATTEN_PX (U.gp_manhattendist) - /* minimum length of new segment before new point can be added */ -#define MIN_EUCLIDEAN_PX (U.gp_euclideandist) - -/* macro to test if only converting endpoints - only for use when converting! */ -#define GP_BUFFER2STROKE_ENDPOINTS ((gpd->flag & GP_DATA_EDITPAINT) && (ctrl)) - -/* ------ */ - -/* Temporary 'Stroke' Operation data */ -typedef struct tGPsdata { - Scene *scene; /* current scene from context */ - ScrArea *sa; /* area where painting originated */ - ARegion *ar; /* region where painting originated */ - View2D *v2d; /* needed for GP_STROKE_2DSPACE */ - - 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 */ - - bGPdata *gpd; /* gp-datablock layer comes from */ - bGPDlayer *gpl; /* layer we're working on */ - bGPDframe *gpf; /* frame we're working on */ - - short status; /* current status of painting */ - short paintmode; /* mode for painting */ - - short mval[2]; /* current mouse-position */ - short mvalo[2]; /* previous recorded mouse-position */ - - float pressure; /* current stylus pressure */ - float opressure; /* previous stylus pressure */ - - short radius; /* radius of influence for eraser */ -} tGPsdata; - -/* values for tGPsdata->status */ -enum { - GP_STATUS_NORMAL = 0, /* running normally */ - GP_STATUS_ERROR, /* something wasn't correctly set up */ - GP_STATUS_DONE /* painting done */ -}; - -/* values for tGPsdata->paintmode */ -enum { - GP_PAINTMODE_DRAW = 0, - GP_PAINTMODE_ERASER -}; - -/* Return flags for adding points to stroke buffer */ -enum { - GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */ - GP_STROKEADD_OVERFLOW = -1, /* error occurred - cannot fit any more points */ - GP_STROKEADD_NORMAL, /* point was successfully added */ - GP_STROKEADD_FULL /* cannot add any more points to buffer */ -}; - -/* ---------- Stroke Editing ------------ */ - -/* clear the session buffers (call this before AND after a paint operation) */ -static void gp_session_validatebuffer (tGPsdata *p) -{ - bGPdata *gpd= p->gpd; - - /* clear memory of buffer (or allocate it if starting a new session) */ - if (gpd->sbuffer) - memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX); - else - gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); - - /* reset indices */ - gpd->sbuffer_size = 0; - - /* reset flags */ - gpd->sbuffer_sflag= 0; -} - -/* check if the current mouse position is suitable for adding a new point */ -static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2]) -{ - short dx= abs(mval[0] - pmval[0]); - short dy= abs(mval[1] - pmval[1]); - - /* check if mouse moved at least certain distance on both axes (best case) */ - if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) - return 1; - - /* check if the distance since the last point is significant enough */ - // future optimisation: sqrt here may be too slow? - else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX) - return 1; - - /* mouse 'didn't move' */ - else - return 0; -} - -/* convert screen-coordinates to buffer-coordinates */ -static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) -{ - bGPdata *gpd= p->gpd; - - /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ - if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) { - const short mx=mval[0], my=mval[1]; - float *fp= give_cursor(p->scene, NULL); // XXX NULL could be v3d - float dvec[3]; - - /* 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. - * - * TODO: - * - investigate using nearest point(s) on a previous stroke as - * reference point instead or as offset, for easier stroke matching - * - investigate projection onto geometry (ala retopo) - */ - - /* method taken from editview.c - mouse_cursor() */ - project_short_noclip(p->ar, fp, mval); - window_to_3d_delta(p->ar, dvec, mval[0]-mx, mval[1]-my); - VecSubf(out, fp, dvec); - } - - /* 2d - on 'canvas' (assume that p->v2d is set) */ - else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) { - float x, y; - - UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &x, &y); - - out[0]= x; - out[1]= y; - } - - /* 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; - } - - /* 2d - relative to screen (viewport area) */ - else { - out[0] = (float)(mval[0]) / (float)(p->sa->winx) * 1000; - out[1] = (float)(mval[1]) / (float)(p->sa->winy) * 1000; - } -} - -/* add current stroke-point to buffer (returns whether point was successfully added) */ -static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure) -{ - bGPdata *gpd= p->gpd; - tGPspoint *pt; - - /* check if still room in buffer */ - if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX) - return GP_STROKEADD_OVERFLOW; - - /* get pointer to destination point */ - pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size); - - /* store settings */ - pt->x= mval[0]; - pt->y= mval[1]; - pt->pressure= pressure; - - /* increment counters */ - gpd->sbuffer_size++; - - /* check if another operation can still occur */ - if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX) - return GP_STROKEADD_FULL; - else - return GP_STROKEADD_NORMAL; -} - -/* smooth a stroke (in buffer) before storing it */ -static void gp_stroke_smooth (tGPsdata *p) -{ - bGPdata *gpd= p->gpd; - int i=0, cmx=gpd->sbuffer_size; - int ctrl= 0; // XXX - - /* only smooth if smoothing is enabled, and we're not doing a straight line */ - if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || GP_BUFFER2STROKE_ENDPOINTS) - return; - - /* don't try if less than 2 points in buffer */ - if ((cmx <= 2) || (gpd->sbuffer == NULL)) - return; - - /* apply weighting-average (note doing this along path sequentially does introduce slight error) */ - for (i=0; i < gpd->sbuffer_size; i++) { - tGPspoint *pc= (((tGPspoint *)gpd->sbuffer) + i); - tGPspoint *pb= (i-1 > 0)?(pc-1):(pc); - tGPspoint *pa= (i-2 > 0)?(pc-2):(pb); - tGPspoint *pd= (i+1 < cmx)?(pc+1):(pc); - tGPspoint *pe= (i+2 < cmx)?(pc+2):(pd); - - pc->x= (short)(0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x); - pc->y= (short)(0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y); - } -} - -/* simplify a stroke (in buffer) before storing it - * - applies a reverse Chaikin filter - * - code adapted from etch-a-ton branch (editarmature_sketch.c) - */ -static void gp_stroke_simplify (tGPsdata *p) -{ - bGPdata *gpd= p->gpd; - tGPspoint *old_points= (tGPspoint *)gpd->sbuffer; - short num_points= gpd->sbuffer_size; - short flag= gpd->sbuffer_sflag; - short i, j; - int ctrl= 0; // XXX - - /* only simplify if simlification is enabled, and we're not doing a straight line */ - if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || GP_BUFFER2STROKE_ENDPOINTS) - return; - - /* don't simplify if less than 4 points in buffer */ - if ((num_points <= 2) || (old_points == NULL)) - return; - - /* clear buffer (but don't free mem yet) so that we can write to it - * - firstly set sbuffer to NULL, so a new one is allocated - * - secondly, reset flag after, as it gets cleared auto - */ - gpd->sbuffer= NULL; - gp_session_validatebuffer(p); - gpd->sbuffer_sflag = flag; - -/* macro used in loop to get position of new point - * - used due to the mixture of datatypes in use here - */ -#define GP_SIMPLIFY_AVPOINT(offs, sfac) \ - { \ - co[0] += (float)(old_points[offs].x * sfac); \ - co[1] += (float)(old_points[offs].y * sfac); \ - pressure += old_points[offs].pressure * sfac; \ - } - - for (i = 0, j = 0; i < num_points; i++) - { - if (i - j == 3) - { - float co[2], pressure; - short mco[2]; - - /* initialise values */ - co[0]= 0; - co[1]= 0; - pressure = 0; - - /* using macro, calculate new point */ - GP_SIMPLIFY_AVPOINT(j, -0.25f); - GP_SIMPLIFY_AVPOINT(j+1, 0.75f); - GP_SIMPLIFY_AVPOINT(j+2, 0.75f); - GP_SIMPLIFY_AVPOINT(j+3, -0.25f); - - /* set values for adding */ - mco[0]= (short)co[0]; - mco[1]= (short)co[1]; - - /* ignore return values on this... assume to be ok for now */ - gp_stroke_addpoint(p, mco, pressure); - - j += 2; - } - } - - /* free old buffer */ - MEM_freeN(old_points); -} - - -/* make a new stroke from the buffer data */ -static void gp_stroke_newfrombuffer (tGPsdata *p) -{ - bGPdata *gpd= p->gpd; - bGPDstroke *gps; - bGPDspoint *pt; - tGPspoint *ptc; - int i, totelem; - int ctrl= 0; // XXX - - /* get total number of points to allocate space for: - * - in 'Draw Mode', holding the Ctrl-Modifier will only take endpoints - * - otherwise, do whole stroke - */ - if (GP_BUFFER2STROKE_ENDPOINTS) - totelem = (gpd->sbuffer_size >= 2) ? 2: gpd->sbuffer_size; - else - totelem = gpd->sbuffer_size; - - /* exit with error if no valid points from this stroke */ - if (totelem == 0) { - if (G.f & G_DEBUG) - printf("Error: No valid points in stroke buffer to convert (tot=%d) \n", gpd->sbuffer_size); - return; - } - - /* allocate memory for a new stroke */ - gps= MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); - - /* allocate enough memory for a continuous array for storage points */ - pt= gps->points= MEM_callocN(sizeof(bGPDspoint)*totelem, "gp_stroke_points"); - - /* copy appropriate settings for stroke */ - gps->totpoints= totelem; - gps->thickness= p->gpl->thickness; - gps->flag= gpd->sbuffer_sflag; - - /* copy points from the buffer to the stroke */ - if (GP_BUFFER2STROKE_ENDPOINTS) { - /* 'Draw Mode' + Ctrl-Modifier - only endpoints */ - { - /* first point */ - ptc= gpd->sbuffer; - - /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, &ptc->x, &pt->x); - - /* copy pressure */ - pt->pressure= ptc->pressure; - - pt++; - } - - if (totelem == 2) { - /* last point if applicable */ - ptc= ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1); - - /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, &ptc->x, &pt->x); - - /* copy pressure */ - pt->pressure= ptc->pressure; - } - } - else { - /* convert all points (normal behaviour) */ - for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) { - /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, &ptc->x, &pt->x); - - /* copy pressure */ - pt->pressure= ptc->pressure; - - pt++; - } - } - - /* add stroke to frame */ - BLI_addtail(&p->gpf->strokes, gps); -} - -/* --- 'Eraser' for 'Paint' Tool ------ */ - -/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */ -static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i) -{ - bGPDspoint *pt_tmp= gps->points; - bGPDstroke *gsn = NULL; - - /* if stroke only had two points, get rid of stroke */ - if (gps->totpoints == 2) { - /* free stroke points, then stroke */ - MEM_freeN(pt_tmp); - BLI_freelinkN(&gpf->strokes, gps); - - /* nothing left in stroke, so stop */ - return 1; - } - - /* if last segment, just remove segment from the stroke */ - else if (i == gps->totpoints - 2) { - /* allocate new points array, and assign most of the old stroke there */ - gps->totpoints--; - gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); - memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints); - - /* free temp buffer */ - MEM_freeN(pt_tmp); - - /* nothing left in stroke, so stop */ - return 1; - } - - /* if first segment, just remove segment from the stroke */ - else if (i == 0) { - /* allocate new points array, and assign most of the old stroke there */ - gps->totpoints--; - gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); - memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints); - - /* free temp buffer */ - MEM_freeN(pt_tmp); - - /* no break here, as there might still be stuff to remove in this stroke */ - return 0; - } - - /* segment occurs in 'middle' of stroke, so split */ - else { - /* duplicate stroke, and assign 'later' data to that stroke */ - gsn= MEM_dupallocN(gps); - gsn->prev= gsn->next= NULL; - BLI_insertlinkafter(&gpf->strokes, gps, gsn); - - gsn->totpoints= gps->totpoints - i; - gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points"); - memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints); - - /* adjust existing stroke */ - gps->totpoints= i; - gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); - memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i); - - /* free temp buffer */ - MEM_freeN(pt_tmp); - - /* nothing left in stroke, so stop */ - return 1; - } -} - -/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */ -static short gp_stroke_eraser_strokeinside (short mval[], short mvalo[], short rad, short x0, short y0, short x1, short y1) -{ - /* simple within-radius check for now */ - if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1)) - return 1; - - /* not inside */ - return 0; -} - -/* eraser tool - evaluation per stroke */ -static void gp_stroke_eraser_dostroke (tGPsdata *p, short mval[], short mvalo[], short rad, rcti *rect, bGPDframe *gpf, bGPDstroke *gps) -{ - bGPDspoint *pt1, *pt2; - int x0=0, y0=0, x1=0, y1=0; - short xyval[2]; - int i; - - if (gps->totpoints == 0) { - /* just free stroke */ - if (gps->points) - MEM_freeN(gps->points); - BLI_freelinkN(&gpf->strokes, gps); - } - else if (gps->totpoints == 1) { - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - project_short(p->ar, &gps->points->x, xyval); - x0= xyval[0]; - y0= xyval[1]; - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0); - } - 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= (short)((gps->points->x * sizex) + offsx); - y0= (short)((gps->points->y * sizey) + offsy); - } - else { - x0= (short)(gps->points->x / 1000 * p->sa->winx); - y0= (short)(gps->points->y / 1000 * p->sa->winy); - } - - /* do boundbox check first */ - if (BLI_in_rcti(rect, x0, y0)) { - /* only check if point is inside */ - if ( ((x0-mval[0])*(x0-mval[0]) + (y0-mval[1])*(y0-mval[1])) <= rad*rad ) { - /* free stroke */ - MEM_freeN(gps->points); - BLI_freelinkN(&gpf->strokes, gps); - } - } - } - else { - /* loop over the points in the stroke, checking for intersections - * - an intersection will require the stroke to be split - */ - for (i=0; (i+1) < gps->totpoints; i++) { - /* get points to work with */ - pt1= gps->points + i; - pt2= gps->points + i + 1; - - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - project_short(p->ar, &pt1->x, xyval); - x0= xyval[0]; - y0= xyval[1]; - - project_short(p->ar, &pt2->x, xyval); - x1= xyval[0]; - y1= xyval[1]; - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0); - - UI_view2d_view_to_region(p->v2d, pt2->x, pt2->y, &x1, &y1); - } - 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; + Object *ob= CTX_data_active_object(C); - /* calculate new points */ - x0= (short)((pt1->x * sizex) + offsx); - y0= (short)((pt1->y * sizey) + offsy); + // TODO: we can include other data-types such as bones later if need be... - x1= (short)((pt2->x * sizex) + offsx); - y1= (short)((pt2->y * sizey) + offsy); - } - else { - x0= (short)(pt1->x / 1000 * p->sa->winx); - y0= (short)(pt1->y / 1000 * p->sa->winy); - x1= (short)(pt2->x / 1000 * p->sa->winx); - y1= (short)(pt2->y / 1000 * p->sa->winy); - } - - /* check that point segment of the boundbox of the eraser stroke */ - if (BLI_in_rcti(rect, x0, y0) || BLI_in_rcti(rect, x1, y1)) { - /* check if point segment of stroke had anything to do with - * eraser region (either within stroke painted, or on its lines) - * - this assumes that linewidth is irrelevant - */ - if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) { - /* if function returns true, break this loop (as no more point to check) */ - if (gp_stroke_eraser_splitdel(gpf, gps, i)) - break; + /* just in case no active object */ + if (ob) { + /* for now, as long as there's an object, default to using that in 3D-View */ + if (ptr) RNA_id_pointer_create(&ob->id, ptr); + return &ob->gpd; } } - } - } -} - -/* erase strokes which fall under the eraser strokes */ -static void gp_stroke_doeraser (tGPsdata *p) -{ - bGPDframe *gpf= p->gpf; - bGPDstroke *gps, *gpn; - rcti rect; - - /* rect is rectangle of eraser */ - rect.xmin= p->mval[0] - p->radius; - rect.ymin= p->mval[1] - p->radius; - rect.xmax= p->mval[0] + p->radius; - rect.ymax= p->mval[1] + p->radius; - - /* loop over strokes, checking segments for intersections */ - for (gps= gpf->strokes.first; gps; gps= gpn) { - gpn= gps->next; - gp_stroke_eraser_dostroke(p, p->mval, p->mvalo, p->radius, &rect, gpf, gps); - } -} - -/* ---------- 'Paint' Tool ------------ */ - -/* init new painting session */ -static void gp_session_initpaint (bContext *C, tGPsdata *p) -{ - ScrArea *curarea= CTX_wm_area(C); - ARegion *ar= CTX_wm_region(C); - - /* clear previous data (note: is on stack) */ - memset(p, 0, sizeof(tGPsdata)); - - /* make sure the active view (at the starting time) is a 3d-view */ - if (curarea == NULL) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: No active view for painting \n"); - return; - } - - /* pass on current scene */ - p->scene= CTX_data_scene(C); - - switch (curarea->spacetype) { - /* supported views first */ - case SPACE_VIEW3D: - { - View3D *v3d= curarea->spacedata.first; - - /* set current area */ - p->sa= curarea; - p->ar= ar; - - /* check that gpencil data is allowed to be drawn */ - if ((v3d->flag2 & V3D_DISPGP)==0) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown \n"); - return; - } - } - break; - case SPACE_NODE: - { - SpaceNode *snode= curarea->spacedata.first; - - /* set current area */ - p->sa= curarea; - p->ar= ar; - p->v2d= &ar->v2d; - - /* check that gpencil data is allowed to be drawn */ - if ((snode->flag & SNODE_DISPGP)==0) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown \n"); - return; - } - } - break; - case SPACE_SEQ: - { - SpaceSeq *sseq= curarea->spacedata.first; - - /* set current area */ - p->sa= curarea; - p->ar= ar; - p->v2d= &ar->v2d; - - /* check that gpencil data is allowed to be drawn */ - if (sseq->mainb == SEQ_DRAW_SEQUENCE) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil \n"); - return; - } - if ((sseq->flag & SEQ_DRAW_GPENCIL)==0) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown \n"); - return; - } - } - break; - case SPACE_IMAGE: - { - SpaceImage *sima= 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); + break; - /* check that gpencil data is allowed to be drawn */ - if ((sima->flag & SI_DISPGP)==0) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: In active view, Grease Pencil not shown \n"); - return; - } - } - break; - /* unsupported views */ - default: - { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: Active view not appropriate for Grease Pencil drawing \n"); - return; - } - break; - } - - /* get gp-data */ - p->gpd= gpencil_data_getactive(p->sa); - if (p->gpd == NULL) { - short ok; - - p->gpd= gpencil_data_addnew("GPencil"); - ok= gpencil_data_setactive(p->sa, p->gpd); - - /* most of the time, the following check isn't needed */ - if (ok == 0) { - /* free gpencil data as it can't be used */ - free_gpencil_data(p->gpd); - p->gpd= NULL; - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: Could not assign newly created Grease Pencil data to active area \n"); - return; - } - } - - /* set edit flags */ - G.f |= G_GREASEPENCIL; - - /* clear out buffer (stored in gp-data) in case something contaminated it */ - gp_session_validatebuffer(p); - - /* 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; -} - -/* cleanup after a painting session */ -static void gp_session_cleanup (tGPsdata *p) -{ - bGPdata *gpd= p->gpd; - - /* error checking */ - if (gpd == NULL) - return; - - /* free stroke buffer */ - if (gpd->sbuffer) { - MEM_freeN(gpd->sbuffer); - gpd->sbuffer= NULL; - } - - /* clear flags */ - gpd->sbuffer_size= 0; - gpd->sbuffer_sflag= 0; -} - -/* init new stroke */ -static void gp_paint_initstroke (tGPsdata *p, short paintmode) -{ - /* get active layer (or add a new one if non-existent) */ - p->gpl= gpencil_layer_getactive(p->gpd); - if (p->gpl == NULL) - p->gpl= gpencil_layer_addnew(p->gpd); - if (p->gpl->flag & GP_LAYER_LOCKED) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: Cannot paint on locked layer \n"); - return; - } - - /* get active frame (add a new one if not matching frame) */ - p->gpf= gpencil_layer_getframe(p->gpl, p->scene->r.cfra, 1); - if (p->gpf == NULL) { - p->status= GP_STATUS_ERROR; - if (G.f & G_DEBUG) - printf("Error: No frame created (gpencil_paint_init) \n"); - return; - } - else - p->gpf->flag |= GP_FRAME_PAINT; - - /* set 'eraser' for this stroke if using eraser */ - p->paintmode= paintmode; - if (p->paintmode == GP_PAINTMODE_ERASER) - p->gpd->sbuffer_sflag |= GP_STROKE_ERASER; - - /* check if points will need to be made in view-aligned space */ - if (p->gpd->flag & GP_DATA_VIEWALIGN) { - switch (p->sa->spacetype) { - case SPACE_VIEW3D: + case SPACE_NODE: /* Nodes Editor */ { - View3D *v3d= (View3D *)p->sa->spacedata.first; - RegionView3D *rv3d= NULL; // XXX - float *fp= give_cursor(p->scene, v3d); + //SpaceNode *snode= (SpaceNode *)CTX_wm_space_data(C); - initgrabz(rv3d, fp[0], fp[1], fp[2]); - - p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE; + /* return the GP data for the active node block/node */ } break; - case SPACE_NODE: - { - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; - } - break; - 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 * ((float)p->scene->r.xasp / (float)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); - } - break; - case SPACE_IMAGE: + case SPACE_SEQ: /* Sequencer */ { - /* check if any ibuf available */ - if (p->ibuf) - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + //SpaceSeq *sseq= (SpaceSeq *)CTX_wm_space_data(C); + + /* return the GP data for the active strips/image/etc. */ } break; } } -} - -/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */ -static void gp_paint_strokeend (tGPsdata *p) -{ - /* check if doing eraser or not */ - if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) { - /* smooth stroke before transferring? */ - gp_stroke_smooth(p); - - /* simplify stroke before transferring? */ - gp_stroke_simplify(p); - - /* transfer stroke to frame */ - gp_stroke_newfrombuffer(p); - } - /* clean up buffer now */ - gp_session_validatebuffer(p); + /* just fall back on the scene's GP data */ + if (ptr) RNA_id_pointer_create((ID *)scene, ptr); + return (scene) ? &scene->gpd : NULL; } -/* finish off stroke painting operation */ -static void gp_paint_cleanup (tGPsdata *p) +/* Get the active Grease Pencil datablock */ +bGPdata *gpencil_data_get_active (bContext *C) { - /* finish off a stroke */ - gp_paint_strokeend(p); - - /* "unlock" frame */ - p->gpf->flag &= ~GP_FRAME_PAINT; - - /* add undo-push so stroke can be undone */ - /* FIXME: currently disabled, as it's impossible to get this working nice - * as gpenci data is on currently screen-level (which isn't saved to undo files) - */ - //BIF_undo_push("GPencil Stroke"); - - /* force redraw after drawing action */ - // XXX force_draw_plus(SPACE_ACTION, 0); + bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL); + return (gpd_ptr) ? *(gpd_ptr) : NULL; } -/* -------- */ - -/* main call to paint a new stroke */ -// XXX will become modal(), gets event, includes all info! -short gpencil_paint (bContext *C, short paintmode) -{ - tGPsdata p; - short ok = GP_STROKEADD_NORMAL; - - /* init paint-data */ - gp_session_initpaint(C, &p); - if (p.status == GP_STATUS_ERROR) { - gp_session_cleanup(&p); - return 0; - } - gp_paint_initstroke(&p, paintmode); - if (p.status == GP_STATUS_ERROR) { - gp_session_cleanup(&p); - return 0; - } - - /* set cursor to indicate drawing */ - // XXX (cursor callbacks in regiontype) setcursor_space(p.sa->spacetype, CURSOR_VPAINT); - - /* init drawing-device settings */ - // XXX getmouseco_areawin(p.mval); - // XXX p.pressure = get_pressure(); - - p.mvalo[0]= p.mval[0]; - p.mvalo[1]= p.mval[1]; - p.opressure= p.pressure; - - /* radius for eraser circle is defined in userprefs now */ - // TODO: make this more easily tweaked... - p.radius= U.gp_eraser; - - /* start drawing eraser-circle (if applicable) */ - //if (paintmode == GP_PAINTMODE_ERASER) - // XXX draw_sel_circle(p.mval, NULL, p.radius, p.radius, 0); // draws frontbuffer, but sets backbuf again - - /* only allow painting of single 'dots' if: - * - pressure is not excessive (as it can be on some windows tablets) - * - draw-mode for active datablock is turned on - * - not erasing - */ - if (paintmode != GP_PAINTMODE_ERASER) { - if (!(p.pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) { - gp_stroke_addpoint(&p, p.mval, p.pressure); - } - } - - /* XXX paint loop */ - if(0) { - /* get current user input */ - // XXX getmouseco_areawin(p.mval); - // XXX p.pressure = get_pressure(); - - /* only add current point to buffer if mouse moved (otherwise wait until it does) */ - if (paintmode == GP_PAINTMODE_ERASER) { - /* do 'live' erasing now */ - gp_stroke_doeraser(&p); - - // XXX draw_sel_circle(p.mval, p.mvalo, p.radius, p.radius, 0); - // XXX force_draw(0); - - p.mvalo[0]= p.mval[0]; - p.mvalo[1]= p.mval[1]; - p.opressure= p.pressure; - } - else if (gp_stroke_filtermval(&p, p.mval, p.mvalo)) { - /* try to add point */ - ok= gp_stroke_addpoint(&p, p.mval, p.pressure); - - /* handle errors while adding point */ - if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { - /* finish off old stroke */ - gp_paint_strokeend(&p); - - /* start a new stroke, starting from previous point */ - gp_stroke_addpoint(&p, p.mvalo, p.opressure); - ok= gp_stroke_addpoint(&p, p.mval, p.pressure); - } - else if (ok == GP_STROKEADD_INVALID) { - /* the painting operation cannot continue... */ - error("Cannot paint stroke"); - p.status = GP_STATUS_ERROR; - - if (G.f & G_DEBUG) - printf("Error: Grease-Pencil Paint - Add Point Invalid \n"); - // XXX break; - } - // XXX force_draw(0); - - p.mvalo[0]= p.mval[0]; - p.mvalo[1]= p.mval[1]; - p.opressure= p.pressure; - } - - /* do mouse checking at the end, so don't check twice, and potentially - * miss a short tap - */ - } - - /* clear edit flags */ - G.f &= ~G_GREASEPENCIL; - - /* restore cursor to indicate end of drawing */ - // XXX (cursor callbacks in regiontype) setcursor_space(p.sa->spacetype, CURSOR_STD); - - /* check size of buffer before cleanup, to determine if anything happened here */ - if (paintmode == GP_PAINTMODE_ERASER) { - ok= 1; /* assume that we did something... */ - // XXX draw_sel_circle(NULL, p.mvalo, 0, p.radius, 0); - } - else - ok= p.gpd->sbuffer_size; - - /* cleanup */ - gp_paint_cleanup(&p); - gp_session_cleanup(&p); - - /* done! return if a stroke was successfully added */ - return ok; -} +/* ************************************************ */ +/* Panel Operators */ -/* All event (loops) handling checking if stroke drawing should be initiated - * should call this function. - */ -short gpencil_do_paint (bContext *C) -{ - ScrArea *sa= CTX_wm_area(C); - bGPdata *gpd = gpencil_data_getactive(sa); - short retval= 0; - int alt= 0, shift= 0, mbut= 0; // XXX - - /* check if possible to do painting */ - if (gpd == NULL) - return 0; - - /* currently, we will only 'paint' if: - * 1. draw-mode on gpd is set (for accessibility reasons) - * a) single dots are only available by this method if a single click is made - * b) a straight line is drawn if ctrl-modifier is held (check is done when stroke is converted!) - * 2. if shift-modifier is held + lmb -> 'quick paint' - * - * OR - * - * draw eraser stroke if: - * 1. using the eraser on a tablet - * 2. draw-mode on gpd is set (for accessiblity reasons) - * (eraser is mapped to right-mouse) - * 3. Alt + 'select' mouse-button - * i.e. if LMB = select: Alt-LMB - * if RMB = select: Alt-RMB - */ - if (get_activedevice() == 2) { - /* eraser on a tablet - always try to erase strokes */ - retval = gpencil_paint(C, GP_PAINTMODE_ERASER); - } - else if (gpd->flag & GP_DATA_EDITPAINT) { - /* try to paint/erase */ - if (mbut == L_MOUSE) - retval = gpencil_paint(C, GP_PAINTMODE_DRAW); - else if (mbut == R_MOUSE) - retval = gpencil_paint(C, GP_PAINTMODE_ERASER); - } - else if (!(gpd->flag & GP_DATA_LMBPLOCK)) { - /* try to paint/erase as not locked */ - if (shift && (mbut == L_MOUSE)) { - retval = gpencil_paint(C, GP_PAINTMODE_DRAW); - } - else if (alt) { - if ((U.flag & USER_LMOUSESELECT) && (mbut == L_MOUSE)) - retval = gpencil_paint(C, GP_PAINTMODE_ERASER); - else if (!(U.flag & USER_LMOUSESELECT) && (mbut == R_MOUSE)) - retval = gpencil_paint(C, GP_PAINTMODE_ERASER); - } - } - - /* return result of trying to paint */ - return retval; -} -/* ************************************************** */ -#endif // XXX COMPILE GUARDS FOR OLD CODE +/* ************************************************ */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 2f60efb2179..d6bdea2db55 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1,5 +1,28 @@ -/* Grease Pencil - version 2 - * By Joshua Leung +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** */ #include @@ -38,8 +61,8 @@ #include "ED_view3d.h" #include "RNA_access.h" -#include "RNA_define.h" +#include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" @@ -48,65 +71,6 @@ /* ******************************************* */ /* Context Wrangling... */ -/* Get the active Grease Pencil datablock */ -// TODO: move this to a gpencil_utils.c? -bGPdata *gpencil_data_getactive (bContext *C) -{ - Scene *scene= CTX_data_scene(C); - ScrArea *sa= CTX_wm_area(C); - - /* if there's an active area, check if the particular editor may - * have defined any special Grease Pencil context for editing... - */ - if (sa) { - switch (sa->spacetype) { - case SPACE_VIEW3D: /* 3D-View */ - { - Object *ob= CTX_data_active_object(C); - - /* just in case... */ - if (ob) { - /* depending on the mode of the object, we may be able to get some GP data - * from different elements - i.e. bones... - */ - if (ob->mode & OB_MODE_POSE) { - //bPoseChannel *pchan= CTX_data_active_pchan(C); - - /* if posechannel has GP data, use that... */ - //if (pchan && pchan->gpd) - // return pchan->gpd; - } - - /* still here, so check if active Object has GP data */ - //if (ob->gpd) - // return ob->gpd; - } - } - break; - - case SPACE_NODE: /* Nodes Editor */ - { - //SpaceNode *snode= (SpaceNode *)CTX_wm_space_data(C); - - /* return the GP data for the active node block/node */ - } - break; - - case SPACE_SEQ: /* Sequencer */ - { - //SpaceSeq *sseq= (SpaceSeq *)CTX_wm_space_data(C); - - /* return the GP data for the active strips/image/etc. */ - } - break; - } - } - - /* just fall back on the scene's GP data */ - return (scene) ? scene->gpd : NULL; -} - - /* check if context is suitable for drawing */ static int gpencil_draw_poll (bContext *C) { @@ -282,8 +246,8 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) /* 2d - relative to screen (viewport area) */ else { - out[0] = (float)(mval[0]) / (float)(p->sa->winx) * 1000; - out[1] = (float)(mval[1]) / (float)(p->sa->winy) * 1000; + out[0] = (float)(mval[0]) / (float)(p->sa->winx) * 100; + out[1] = (float)(mval[1]) / (float)(p->sa->winy) * 100; } } @@ -616,8 +580,8 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, int mval[], int mvalo[], sho } #endif else { - x0= (int)(gps->points->x / 1000 * p->sa->winx); - y0= (int)(gps->points->y / 1000 * p->sa->winy); + x0= (int)(gps->points->x / 100 * p->sa->winx); + y0= (int)(gps->points->y / 100 * p->sa->winy); } /* do boundbox check first */ @@ -673,10 +637,10 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, int mval[], int mvalo[], sho } #endif else { - x0= (int)(pt1->x / 1000 * p->sa->winx); - y0= (int)(pt1->y / 1000 * p->sa->winy); - x1= (int)(pt2->x / 1000 * p->sa->winx); - y1= (int)(pt2->y / 1000 * p->sa->winy); + x0= (int)(pt1->x / 100 * p->sa->winx); + y0= (int)(pt1->y / 100 * p->sa->winy); + x1= (int)(pt2->x / 100 * p->sa->winx); + y1= (int)(pt2->y / 100 * p->sa->winy); } /* check that point segment of the boundbox of the eraser stroke */ @@ -740,6 +704,7 @@ static void gp_session_validatebuffer (tGPsdata *p) static tGPsdata *gp_session_initpaint (bContext *C) { tGPsdata *p = NULL; + bGPdata **gpd_ptr = NULL; ScrArea *curarea= CTX_wm_area(C); ARegion *ar= CTX_wm_region(C); @@ -852,11 +817,18 @@ static tGPsdata *gp_session_initpaint (bContext *C) } /* get gp-data */ - p->gpd= gpencil_data_getactive(C); - if (p->gpd == NULL) { - /* add new GPencil block for the active scene for now... */ - p->gpd= gpencil_data_addnew("GPencil"); - p->scene->gpd= p->gpd; + gpd_ptr= gpencil_data_get_pointers(C, NULL); + if (gpd_ptr == NULL) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: Current context doesn't allow for any Grease Pencil data \n"); + return p; + } + else { + /* if no existing GPencil block exists, add one */ + if (*gpd_ptr == NULL) + *gpd_ptr= gpencil_data_addnew("GPencil"); + p->gpd= *gpd_ptr; } /* set edit flags - so that buffer will get drawn */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index c1e37ce2e81..25e622d8551 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -38,49 +38,35 @@ struct SpaceSeq; struct bGPdata; struct bGPDlayer; struct bGPDframe; -struct bGPdata; +struct PointerRNA; +struct uiLayout; struct uiBlock; struct ImBuf; struct wmWindowManager; -/* ------------- Grease-Pencil Helpers -------------- */ +/* ------------- Grease-Pencil Helpers ---------------- */ -/* Temporary 'Stroke Point' data */ +/* Temporary 'Stroke Point' data + * + * Used as part of the 'stroke cache' used during drawing of new strokes + */ typedef struct tGPspoint { short x, y; /* x and y coordinates of cursor (in relative to area) */ float pressure; /* pressure of tablet at this point */ } tGPspoint; -/* ----------- Grease Pencil New Tools ------------- */ +/* ----------- Grease Pencil Tools/Context ------------- */ -struct bGPdata *gpencil_data_getactive(struct bContext *C); +struct bGPdata **gpencil_data_get_pointers(struct bContext *C, struct PointerRNA *ptr); +struct bGPdata *gpencil_data_get_active(struct bContext *C); -/* ----------- Grease Pencil Operators ------------- */ +/* ----------- Grease Pencil Operators ----------------- */ void gpencil_common_keymap(struct wmWindowManager *wm, ListBase *keymap); void ED_operatortypes_gpencil(void); -/* ------------ Grease-Pencil Depreceated Stuff ------------------ */ - -//struct bGPdata *gpencil_data_getactive(struct ScrArea *sa); -short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd); -struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd); - -/* ------------ Grease-Pencil Editing API ------------------ */ - -void gpencil_delete_actframe(struct bGPdata *gpd, int cfra); -void gpencil_delete_laststroke(struct bGPdata *gpd, int cfra); - -void gpencil_delete_operation(int cfra, short mode); -void gpencil_delete_menu(void); - -void gpencil_convert_operation(short mode); -void gpencil_convert_menu(void); - -short gpencil_do_paint(struct bContext *C); - /* ------------ Grease-Pencil Drawing API ------------------ */ /* drawgpencil.c */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 48947794620..5c5b7281f20 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4736,7 +4736,7 @@ void special_aftertrans_update(TransInfo *t) * - sync this with actdata_filter_gpencil() in editaction.c */ for (sa= sc->areabase.first; sa; sa= sa->next) { - bGPdata *gpd= gpencil_data_getactive(sa); + bGPdata *gpd= gpencil_data_get_active(sa); if (gpd) posttrans_gpd_clean(gpd); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 25fdf615adb..d1e70c16408 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -54,7 +54,10 @@ struct FluidsimSettings; struct ParticleSystem; struct DerivedMesh; struct SculptSession; +struct bGPdata; + +/* Vertex Groups - Name Info */ typedef struct bDeformGroup { struct bDeformGroup *next, *prev; char name[32]; @@ -110,6 +113,8 @@ typedef struct Object { struct bPose *pose; void *data; + struct bGPdata *gpd; /* Grease Pencil data */ + ListBase constraintChannels; // XXX depreceated... old animation system ListBase effect; ListBase disp; @@ -209,7 +214,7 @@ typedef struct Object { short recalc; /* dependency flag */ float anisotropicFriction[3]; - ListBase constraints; + ListBase constraints; /* object constraints */ ListBase nlastrips; // XXX depreceated... old animation system ListBase hooks; ListBase particlesystem; /* particle systems */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index f0b055bd0e8..cae96b0af4b 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1464,6 +1464,13 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "X-Ray", "Makes the object draw in front of others."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, 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 Data", "Grease Pencil datablock"); + /* pose */ prop= RNA_def_property(srna, "pose_library", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "poselib"); -- cgit v1.2.3 From af85ee01f8b9facf76761e8c3c758ee1ccd18986 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 28 Aug 2009 13:42:58 +0000 Subject: Update MSVC project files. --- intern/audaspace/make/msvc_9_0/audaspace.vcproj | 28 ++++++++++++++++++---- projectfiles_vc9/blender/blender.vcproj | 12 +++++----- .../blender/blenkernel/BKE_blenkernel.vcproj | 16 +++++-------- projectfiles_vc9/blender/editors/ED_editors.vcproj | 28 ++++++++++++++++++++++ projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj | 12 +++++----- .../blender/makesrna/RNA_makesrna.vcproj | 4 ++++ projectfiles_vc9/blender/makesrna/RNA_rna.vcproj | 4 ++++ .../gameengine/videotexture/TEX_Video.vcproj | 4 ++-- 8 files changed, 80 insertions(+), 28 deletions(-) diff --git a/intern/audaspace/make/msvc_9_0/audaspace.vcproj b/intern/audaspace/make/msvc_9_0/audaspace.vcproj index 4c0b26f1c4e..0d8ade43e07 100644 --- a/intern/audaspace/make/msvc_9_0/audaspace.vcproj +++ b/intern/audaspace/make/msvc_9_0/audaspace.vcproj @@ -43,7 +43,7 @@
+ + + + + + + + + + diff --git a/projectfiles_vc9/blender/blender.vcproj b/projectfiles_vc9/blender/blender.vcproj index 7b71ee49870..56913cb8160 100644 --- a/projectfiles_vc9/blender/blender.vcproj +++ b/projectfiles_vc9/blender/blender.vcproj @@ -73,12 +73,12 @@ diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj index 7f0867cc7b6..87f10346726 100644 --- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj +++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj @@ -43,7 +43,7 @@ - - diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index c70e66b6c2b..9f2fc769e49 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -293,6 +293,10 @@ RelativePath="..\..\..\source\blender\editors\include\ED_sequencer.h" > + + @@ -1342,6 +1346,10 @@ RelativePath="..\..\..\source\blender\editors\gpencil\editaction_gpencil.c" > + + @@ -1350,6 +1358,14 @@ RelativePath="..\..\..\source\blender\editors\gpencil\gpencil_intern.h" > + + + + + + + + + + diff --git a/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj b/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj index f9470dcebfe..0e25b26831b 100644 --- a/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj +++ b/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj @@ -43,7 +43,7 @@ + + diff --git a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj index 1d7c3f38581..84359390f41 100644 --- a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj +++ b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj @@ -230,6 +230,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_fluidsim_gen.c" > + + diff --git a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj index e2731cf94e9..94e09303a1b 100644 --- a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj +++ b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj @@ -42,7 +42,7 @@ Date: Fri, 28 Aug 2009 14:25:17 +0000 Subject: - povray and ply work now. Again, please try not to break scripts - at least grep the release dir for the names you change. - rna material property rename gloss_amount -> gloss_factor, since its from 0.0 to 1.0, prefix factor is used on other material settings. reflectivity -> reflect_factor --- release/io/engine_render_pov.py | 17 +++++------------ release/io/export_ply.py | 17 ++++++++--------- release/ui/buttons_material.py | 10 +++++----- release/ui/space_sequencer.py | 2 +- source/blender/makesrna/intern/rna_material.c | 6 +++--- 5 files changed, 22 insertions(+), 30 deletions(-) diff --git a/release/io/engine_render_pov.py b/release/io/engine_render_pov.py index f064add505b..c3165d22540 100644 --- a/release/io/engine_render_pov.py +++ b/release/io/engine_render_pov.py @@ -82,8 +82,8 @@ def write_pov(filename, scene=None, info_callback = None): file.write('#declare %s = finish {\n' % name) if material: - file.write('\tdiffuse %.3g\n' % material.diffuse_reflection) - file.write('\tspecular %.3g\n' % material.specular_reflection) + file.write('\tdiffuse %.3g\n' % material.diffuse_intensity) + file.write('\tspecular %.3g\n' % material.specular_intensity) file.write('\tambient %.3g\n' % material.ambient) #file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value @@ -101,10 +101,10 @@ def write_pov(filename, scene=None, info_callback = None): if material.raytrace_mirror.enabled: raytrace_mirror= material.raytrace_mirror - if raytrace_mirror.reflect: + if raytrace_mirror.reflect_factor: file.write('\treflection {\n') file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color)) - file.write('\t\tfresnel 1 falloff %.3g exponent %.3g metallic %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_fac, raytrace_mirror.reflect)) + file.write('\t\tfresnel 1 falloff %.3g exponent %.3g metallic %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor, raytrace_mirror.reflect_factor)) else: file.write('\tdiffuse 0.8\n') @@ -300,14 +300,7 @@ def write_pov(filename, scene=None, info_callback = None): try: vcol_layer = me.active_vertex_color.data except:vcol_layer = None - - def regular_face(f): - fv = f.verts - if fv[3]== 0: - return fv[0], fv[1], fv[2] - return fv[0], fv[1], fv[2], fv[3] - - faces_verts = [regular_face(f) for f in me.faces] + faces_verts = [f.verts for f in me.faces] faces_normals = [tuple(f.normal) for f in me.faces] verts_normals = [tuple(v.normal) for v in me.verts] diff --git a/release/io/export_ply.py b/release/io/export_ply.py index 3668693db16..c293119d3c8 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -64,7 +64,7 @@ def write(filename, scene, ob, \ raise Exception("Error, Select 1 active object") return - file = open(filename, 'wb') + file = open(filename, 'w') #EXPORT_EDGES = Draw.Create(0) @@ -88,9 +88,9 @@ def write(filename, scene, ob, \ # mesh.transform(ob.matrixWorld) # XXX - faceUV = len(mesh.uv_layers) > 0 + faceUV = len(mesh.uv_textures) > 0 vertexUV = len(mesh.sticky) > 0 - vertexColors = len(mesh.vcol_layers) > 0 + vertexColors = len(mesh.vertex_colors) > 0 if (not faceUV) and (not vertexUV): EXPORT_UV = False if not vertexColors: EXPORT_COLORS = False @@ -100,7 +100,7 @@ def write(filename, scene, ob, \ if faceUV: active_uv_layer = None - for lay in mesh.uv_layers: + for lay in mesh.uv_textures: if lay.active: active_uv_layer= lay.data break @@ -110,7 +110,7 @@ def write(filename, scene, ob, \ if vertexColors: active_col_layer = None - for lay in mesh.vcol_layers: + for lay in mesh.vertex_colors: if lay.active: active_col_layer= lay.data if not active_col_layer: @@ -123,8 +123,8 @@ def write(filename, scene, ob, \ mesh_verts = mesh.verts # save a lookup ply_verts = [] # list of dictionaries # vdict = {} # (index, normal, uv) -> new index - vdict = [{} for i in xrange(len(mesh_verts))] - ply_faces = [[] for f in xrange(len(mesh.faces))] + vdict = [{} for i in range(len(mesh_verts))] + ply_faces = [[] for f in range(len(mesh.faces))] vert_count = 0 for i, f in enumerate(mesh.faces): @@ -141,8 +141,7 @@ def write(filename, scene, ob, \ col = active_col_layer[i] col = col.color1, col.color2, col.color3, col.color4 - f_verts= list(f.verts) - if not f_verts[3]: f_verts.pop() # XXX face length should be 3/4, not always 4 + f_verts= f.verts pf= ply_faces[i] for j, vidx in enumerate(f_verts): diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py index e7add9c59f3..e317d990c39 100644 --- a/release/ui/buttons_material.py +++ b/release/ui/buttons_material.py @@ -426,7 +426,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): split = layout.split() col = split.column() - col.itemR(raym, "reflectivity") + col.itemR(raym, "reflect_factor") col.itemR(mat, "mirror_color", text="") col = split.column() @@ -448,9 +448,9 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): col = split.column() col.itemL(text="Gloss:") - col.itemR(raym, "gloss_amount", text="Amount") + col.itemR(raym, "gloss_factor", text="Amount") sub = col.column() - sub.active = raym.gloss_amount < 1 + sub.active = raym.gloss_factor < 1.0 sub.itemR(raym, "gloss_threshold", text="Threshold") sub.itemR(raym, "gloss_samples", text="Samples") sub.itemR(raym, "gloss_anisotropic", text="Anisotropic") @@ -511,9 +511,9 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): col = split.column() col.itemL(text="Gloss:") - col.itemR(rayt, "gloss_amount", text="Amount") + col.itemR(rayt, "gloss_factor", text="Amount") sub = col.column() - sub.active = rayt.gloss_amount < 1 + sub.active = rayt.gloss_factor < 1.0 sub.itemR(rayt, "gloss_threshold", text="Threshold") sub.itemR(rayt, "gloss_samples", text="Samples") diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index 6b86ea5dabe..de3cfa17987 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -466,7 +466,7 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel): if not strip: return False - return strip.type in ('SOUND') + return strip.type in ('SOUND', ) def draw(self, context): layout = self.layout diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index e9970e4391e..db573f0a666 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -746,7 +746,7 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Enabled", "Enable raytraced reflections."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "reflectivity", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "ray_mirror"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Reflectivity", "Sets the amount mirror reflection for raytrace."); @@ -764,7 +764,7 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_amount", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "gloss_mir"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Amount", "The shininess of the reflection. Values < 1.0 give diffuse, blurry reflections."); @@ -835,7 +835,7 @@ static void rna_def_material_raytra(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_amount", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "gloss_tra"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Amount", "The clarity of the refraction. Values < 1.0 give diffuse, blurry refractions."); -- cgit v1.2.3 From 9e7b276dba2493fe1597fbdb0d906d1bab776fe9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 28 Aug 2009 15:03:49 +0000 Subject: Sequence sound was raising a python exception with crop and offset buttons. renamed RNA properties. x_offset, y_offset -> offset_x, offset_y, this order is more common in rna. render.border -> render.use_border render.placeholders -> render.use_placeholder render.no_overwrite -> render.use_overwrite --- release/ui/buttons_data_text.py | 4 +-- release/ui/buttons_scene.py | 8 +++--- release/ui/space_sequencer.py | 39 +++++++++++++++--------------- release/ui/space_view3d.py | 4 +-- source/blender/makesrna/intern/rna_curve.c | 4 +-- source/blender/makesrna/intern/rna_scene.c | 10 ++++---- source/blender/makesrna/intern/rna_space.c | 8 +++--- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py index 62d4d0a4d21..1abc82cfaa3 100644 --- a/release/ui/buttons_data_text.py +++ b/release/ui/buttons_data_text.py @@ -134,8 +134,8 @@ class DATA_PT_paragraph(DataButtonsPanel): col = split.column(align=True) col.itemL(text="Offset:") - col.itemR(text, "x_offset", text="X") - col.itemR(text, "y_offset", text="Y") + col.itemR(text, "offset_x", text="X") + col.itemR(text, "offset_y", text="Y") #col.itemR(text, "wrap") """ diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index 08eee7ef43a..abd42e32e35 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -222,8 +222,8 @@ class SCENE_PT_output(RenderButtonsPanel): col = split.column() col.itemR(rd, "file_extensions") - col.itemR(rd, "placeholders") - col.itemR(rd, "no_overwrite") + col.itemR(rd, "use_overwrite") + col.itemR(rd, "use_placeholder") if rd.file_format in ('AVIJPEG', 'JPEG'): split = layout.split() @@ -370,9 +370,9 @@ class SCENE_PT_dimensions(RenderButtonsPanel): sub.itemR(rd, "pixel_aspect_y", text="Y") row = col.row() - row.itemR(rd, "border", text="Border") + row.itemR(rd, "use_border", text="Border") rowsub = row.row() - rowsub.active = rd.border + rowsub.active = rd.use_border rowsub.itemR(rd, "crop_to_border", text="Crop") col = split.column(align=True) diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index de3cfa17987..cf9d89edec8 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -434,26 +434,27 @@ class SEQUENCER_PT_input(SequencerButtonsPanel): if elem: col.itemR(elem, "filename", text="") # strip.elements[0] could be a fallback - layout.itemR(strip, "use_translation", text="Image Offset:") - if strip.transform: - col = layout.column(align=True) - col.active = strip.use_translation - col.itemR(strip.transform, "offset_x", text="X") - col.itemR(strip.transform, "offset_y", text="Y") - - layout.itemR(strip, "use_crop", text="Image Crop:") - if strip.crop: + if strip.type != 'SOUND': + layout.itemR(strip, "use_translation", text="Image Offset:") + if strip.transform: + col = layout.column(align=True) + col.active = strip.use_translation + col.itemR(strip.transform, "offset_x", text="X") + col.itemR(strip.transform, "offset_y", text="Y") + + layout.itemR(strip, "use_crop", text="Image Crop:") + if strip.crop: + col = layout.column(align=True) + col.active = strip.use_crop + col.itemR(strip.crop, "top") + col.itemR(strip.crop, "left") + col.itemR(strip.crop, "bottom") + col.itemR(strip.crop, "right") + col = layout.column(align=True) - col.active = strip.use_crop - col.itemR(strip.crop, "top") - col.itemR(strip.crop, "left") - col.itemR(strip.crop, "bottom") - col.itemR(strip.crop, "right") - - col = layout.column(align=True) - col.itemL(text="Trim Duration:") - col.itemR(strip, "animation_start_offset", text="Start") - col.itemR(strip, "animation_end_offset", text="End") + col.itemL(text="Trim Duration:") + col.itemR(strip, "animation_start_offset", text="Start") + col.itemR(strip, "animation_end_offset", text="End") class SEQUENCER_PT_sound(SequencerButtonsPanel): __label__ = "Sound" diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index ae17307080f..5801f9e7941 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -1244,8 +1244,8 @@ class VIEW3D_PT_background_image(bpy.types.Panel): col.itemL(text="Offset:") col = layout.column(align=True) - col.itemR(bg, "x_offset", text="X") - col.itemR(bg, "y_offset", text="Y") + col.itemR(bg, "offset_x", text="X") + col.itemR(bg, "offset_y", text="Y") bpy.types.register(VIEW3D_HT_header) # Header diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 1dd3d0e63c5..bb094eef962 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -401,13 +401,13 @@ static void rna_def_font(BlenderRNA *brna, StructRNA *srna) RNA_def_property_ui_text(prop, "Shear", "Italic angle of the characters"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "x_offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xof"); RNA_def_property_range(prop, -50.0f, 50.0f); RNA_def_property_ui_text(prop, "X Offset", "Horizontal offset from the object center"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "y_offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yof"); RNA_def_property_range(prop, -50.0f, 50.0f); RNA_def_property_ui_text(prop, "Y Offset", "Vertical offset from the object center"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 2408d9337e1..02b891c6cd2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1650,7 +1650,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur (uses number of anti-aliasing samples)."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "border", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER); RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); @@ -1660,14 +1660,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Crop to Border", "Crop the rendered frame to the defined border size."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "placeholders", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_placeholder", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_TOUCH); RNA_def_property_ui_text(prop, "Placeholders", "Create empty placeholder files while rendering frames (similar to Unix 'touch')."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "no_overwrite", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", R_NO_OVERWRITE); - RNA_def_property_ui_text(prop, "No Overwrite", "Skip and don't overwrite existing files while rendering"); + prop= RNA_def_property(srna, "use_overwrite", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", R_NO_OVERWRITE); + RNA_def_property_ui_text(prop, "Overwrite", "Overwrite existing files while rendering."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "use_compositing", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index a754d619741..d6a17526a65 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -493,12 +493,12 @@ static void rna_def_background_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); RNA_def_property_update(prop, NC_WINDOW, NULL); - prop= RNA_def_property(srna, "x_offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xof"); RNA_def_property_ui_text(prop, "X Offset", "Offsets image horizontally from the view center"); RNA_def_property_update(prop, NC_WINDOW, NULL); - prop= RNA_def_property(srna, "y_offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yof"); RNA_def_property_ui_text(prop, "Y Offset", "Offsets image vertically from the view center"); RNA_def_property_update(prop, NC_WINDOW, NULL); @@ -913,11 +913,11 @@ static void rna_def_space_sequencer(BlenderRNA *brna) /* not sure we need rna access to these but adding anyway */ - prop= RNA_def_property(srna, "x_offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xof"); RNA_def_property_ui_text(prop, "X Offset", "Offsets image horizontally from the view center"); - prop= RNA_def_property(srna, "y_offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yof"); RNA_def_property_ui_text(prop, "Y Offset", "Offsets image horizontally from the view center"); -- cgit v1.2.3 From 9781320716c32adec710c3d616685fb4171faa29 Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Fri, 28 Aug 2009 15:54:15 +0000 Subject: Add Makefile for sound ops. --- source/Makefile | 1 + source/blender/editors/Makefile | 1 + source/blender/editors/sound/Makefile | 51 +++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 source/blender/editors/sound/Makefile diff --git a/source/Makefile b/source/Makefile index a13d8bb41d5..d9acd4bf059 100644 --- a/source/Makefile +++ b/source/Makefile @@ -266,6 +266,7 @@ PULIB += $(OCGDIR)/blender/ed_screen/$(DEBUG_DIR)libed_screen.a PULIB += $(OCGDIR)/blender/ed_console/$(DEBUG_DIR)libed_console.a PULIB += $(OCGDIR)/blender/ed_userpref/$(DEBUG_DIR)libed_userpref.a PULIB += $(OCGDIR)/blender/ed_gpencil/$(DEBUG_DIR)libed_gpencil.a +PULIB += $(OCGDIR)/blender/ed_opsound/$(DEBUG_DIR)libed_opsound.a PULIB += $(OCGDIR)/blender/windowmanager/$(DEBUG_DIR)libwindowmanager.a PULIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a PULIB += $(OCGDIR)/blender/makesrna/$(DEBUG_DIR)librna.a diff --git a/source/blender/editors/Makefile b/source/blender/editors/Makefile index bbbb3fb985f..6a9d695ab0e 100644 --- a/source/blender/editors/Makefile +++ b/source/blender/editors/Makefile @@ -66,5 +66,6 @@ DIRS = armature \ space_sequencer \ space_logic \ space_userpref \ + sound include nan_subdirs.mk diff --git a/source/blender/editors/sound/Makefile b/source/blender/editors/sound/Makefile new file mode 100644 index 00000000000..10145035eb4 --- /dev/null +++ b/source/blender/editors/sound/Makefile @@ -0,0 +1,51 @@ +# +# $Id$ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2007 Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL LICENSE BLOCK ***** +# +# Makes module object directory and bounces make to subdirectories. + +LIBNAME = ed_opsound +DIR = $(OCGDIR)/blender/$(LIBNAME) + +include nan_compile.mk + +CFLAGS += $(LEVEL_1_C_WARNINGS) + +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include + +CPPFLAGS += -I../../windowmanager +CPPFLAGS += -I../../blenkernel +CPPFLAGS += -I../../blenloader +CPPFLAGS += -I../../blenlib +CPPFLAGS += -I../../makesdna +CPPFLAGS += -I../../makesrna +CPPFLAGS += -I../../imbuf +CPPFLAGS += -I$(NAN_AUDASPACE)/include + +# own include + +CPPFLAGS += -I../include -- cgit v1.2.3 From a179d16550d15a4543aef940d515ae039ce43e45 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 20:41:12 +0000 Subject: Moved unpack_method_items to the right place. --- source/blender/editors/space_image/image_ops.c | 10 +--------- source/blender/makesrna/RNA_enum_types.h | 2 ++ source/blender/makesrna/intern/rna_packedfile.c | 7 +++++++ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 7a39cd587eb..bee06e6892f 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -61,6 +61,7 @@ #include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "ED_image.h" #include "ED_screen.h" @@ -1166,15 +1167,6 @@ void IMAGE_OT_pack(wmOperatorType *ot) /********************* unpack operator *********************/ -/* XXX move this to some place where it can be reused */ - -const EnumPropertyItem unpack_method_items[] = { - {PF_USE_LOCAL, "USE_LOCAL", 0, "Use Local File", ""}, - {PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write Local File (overwrite existing)", ""}, - {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use Original File", ""}, - {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write Original File (overwrite existing)", ""}, - {0, NULL, 0, NULL, NULL}}; - void unpack_menu(bContext *C, char *opname, char *abs_name, char *folder, PackedFile *pf) { uiPopupMenu *pup; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 06be0e69be5..3bba474677f 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -53,6 +53,8 @@ extern EnumPropertyItem event_type_items[]; extern EnumPropertyItem brush_sculpt_tool_items[]; +extern EnumPropertyItem unpack_method_items[]; + #endif /* RNA_ENUM_TYPES */ diff --git a/source/blender/makesrna/intern/rna_packedfile.c b/source/blender/makesrna/intern/rna_packedfile.c index 6b9a708f555..85918bce05b 100644 --- a/source/blender/makesrna/intern/rna_packedfile.c +++ b/source/blender/makesrna/intern/rna_packedfile.c @@ -31,6 +31,13 @@ #include "DNA_packedFile_types.h" +EnumPropertyItem unpack_method_items[] = { + {PF_USE_LOCAL, "USE_LOCAL", 0, "Use Local File", ""}, + {PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write Local File (overwrite existing)", ""}, + {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use Original File", ""}, + {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write Original File (overwrite existing)", ""}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #else -- cgit v1.2.3 From 6f80bff0e2390f3e93ee31967e7ada417c7ba0c3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 28 Aug 2009 20:51:30 +0000 Subject: 2.5: fix bug in ID property loading, which also loading python RNA collections saves as ID properties. --- source/blender/blenloader/intern/readfile.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1a811ebc08a..89dfa4e2557 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1373,12 +1373,10 @@ static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData prop->totallen = prop->len; prop->data.pointer = newdataadr(fd, prop->data.pointer); - if (switch_endian) { - array= (IDProperty*) prop->data.pointer; + array= (IDProperty*) prop->data.pointer; - for(i=0; ilen; i++) - IDP_DirectLinkProperty(&array[i], switch_endian, fd); - } + for(i=0; ilen; i++) + IDP_DirectLinkProperty(&array[i], switch_endian, fd); } static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd) @@ -1390,19 +1388,22 @@ static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *f prop->totallen = prop->len; prop->data.pointer = newdataadr(fd, prop->data.pointer); - if (switch_endian) { - if(prop->subtype == IDP_GROUP) { - test_pointer_array(fd, prop->data.pointer); - array= prop->data.pointer; + if(prop->subtype == IDP_GROUP) { + test_pointer_array(fd, prop->data.pointer); + array= prop->data.pointer; - for(i=0; ilen; i++) - IDP_DirectLinkProperty(array[i], switch_endian, fd); - } - else if(prop->subtype == IDP_DOUBLE) { + for(i=0; ilen; i++) + IDP_DirectLinkProperty(array[i], switch_endian, fd); + } + else if(prop->subtype == IDP_DOUBLE) { + if (switch_endian) { for (i=0; ilen; i++) { SWITCH_LONGINT(((double*)prop->data.pointer)[i]); } - } else { + } + } + else { + if (switch_endian) { for (i=0; ilen; i++) { SWITCH_INT(((int*)prop->data.pointer)[i]); } -- cgit v1.2.3 From 6f4e0e8e54aba3b674b86dcfb367cceb8619e786 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Fri, 28 Aug 2009 21:07:55 +0000 Subject: 2.5 Paint: * Cleaned up some vertex paint code. Reduces code duplication a bit. --- source/blender/editors/sculpt_paint/paint_vertex.c | 95 +++++++++------------- 1 file changed, 37 insertions(+), 58 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index ee3d9e5baa1..581d10ee883 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1610,13 +1610,13 @@ For future: */ -struct VPaintData { +typedef struct VPaintData { ViewContext vc; unsigned int paintcol; int *indexar; float *vertexcosnos; float vpimat[3][3]; -}; +} VPaintData; static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent *event) { @@ -1655,6 +1655,38 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent return 1; } +static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, int index, float mval[2]) +{ + ViewContext *vc = &vpd->vc; + Mesh *me = get_mesh(ob); + MFace *mface= ((MFace*)me->mface) + index; + unsigned int *mcol= ((unsigned int*)me->mcol) + 4*index; + unsigned int *mcolorig= ((unsigned int*)vp->vpaint_prev) + 4*index; + int alpha, i; + + if((vp->flag & VP_COLINDEX && mface->mat_nr!=ob->actcol-1) || + (G.f & G_FACESELECT && !(mface->flag & ME_FACE_SEL))) + return; + + if(vp->mode==VP_BLUR) { + unsigned int fcol1= mcol_blend( mcol[0], mcol[1], 128); + if(mface->v4) { + unsigned int fcol2= mcol_blend( mcol[2], mcol[3], 128); + vpd->paintcol= mcol_blend( fcol1, fcol2, 128); + } + else { + vpd->paintcol= mcol_blend( mcol[2], fcol1, 170); + } + + } + + for(i = 0; i < (mface->v4 ? 4 : 3); ++i) { + alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i], mval); + if(alpha) + vpaint_blend(vp, mcol+i, mcolorig+i, vpd->paintcol, alpha); + } +} + static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr) { ToolSettings *ts= CTX_data_tool_settings(C); @@ -1694,62 +1726,9 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); - if(vp->flag & VP_COLINDEX) { - for(index=0; indextotface) { - MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); - - if(mface->mat_nr!=ob->actcol-1) { - indexar[index]= 0; - } - } - } - } - if((G.f & G_FACESELECT) && me->mface) { - for(index=0; indextotface) { - MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); - - if((mface->flag & ME_FACE_SEL)==0) - indexar[index]= 0; - } - } - } - - for(index=0; indextotface) { - MFace *mface= ((MFace *)me->mface) + (indexar[index]-1); - unsigned int *mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1); - unsigned int *mcolorig= ( (unsigned int *)vp->vpaint_prev) + 4*(indexar[index]-1); - int alpha; - - if(vp->mode==VP_BLUR) { - unsigned int fcol1= mcol_blend( mcol[0], mcol[1], 128); - if(mface->v4) { - unsigned int fcol2= mcol_blend( mcol[2], mcol[3], 128); - vpd->paintcol= mcol_blend( fcol1, fcol2, 128); - } - else { - vpd->paintcol= mcol_blend( mcol[2], fcol1, 170); - } - - } - - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v1, mval); - if(alpha) vpaint_blend(vp, mcol, mcolorig, vpd->paintcol, alpha); - - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v2, mval); - if(alpha) vpaint_blend(vp, mcol+1, mcolorig+1, vpd->paintcol, alpha); - - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v3, mval); - if(alpha) vpaint_blend(vp, mcol+2, mcolorig+2, vpd->paintcol, alpha); - - if(mface->v4) { - alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*mface->v4, mval); - if(alpha) vpaint_blend(vp, mcol+3, mcolorig+3, vpd->paintcol, alpha); - } - } + for(index=0; indextotface) + vpaint_paint_face(vp, vpd, ob, indexar[index]-1, mval); } MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); -- cgit v1.2.3 From 99eae3d93a8281b7c947ce8a42aafbe8b3c9a706 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 28 Aug 2009 21:31:13 +0000 Subject: SVN maintenance. --- source/blender/editors/gpencil/gpencil_buttons.c | 2 +- source/blender/editors/include/ED_sound.h | 2 +- source/blender/editors/sound/sound_intern.h | 2 +- source/blender/editors/sound/sound_ops.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 87f3b60dcc2..12e987af47b 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -1,5 +1,5 @@ /** - * $Id: drawgpencil.c 22802 2009-08-26 12:01:15Z aligorith $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/include/ED_sound.h b/source/blender/editors/include/ED_sound.h index 584370bc738..afb2752fa6b 100644 --- a/source/blender/editors/include/ED_sound.h +++ b/source/blender/editors/include/ED_sound.h @@ -1,5 +1,5 @@ /** - * $Id:$ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/sound/sound_intern.h b/source/blender/editors/sound/sound_intern.h index eb793a0b661..ec8b0688305 100644 --- a/source/blender/editors/sound/sound_intern.h +++ b/source/blender/editors/sound/sound_intern.h @@ -1,5 +1,5 @@ /** - * $Id:$ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index a23a28423ef..83f83c637bf 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -1,5 +1,5 @@ /** - * $Id:$ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 03b3d2cb794c5fe03fc4c27b006044e24e294cfc Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 21:47:05 +0000 Subject: Sound packing/unpacking operators. --- source/blender/blenkernel/intern/sound.c | 6 +- source/blender/editors/sound/sound_ops.c | 178 +++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 3794fbe90ef..8159f2f8c4c 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -163,7 +163,7 @@ void sound_cache(struct bSound* sound, int ignore) AUD_unload(sound->cache); sound->cache = AUD_bufferSound(sound->handle); - sound->changed = TRUE; + sound->changed++; } void sound_delete_cache(struct bSound* sound) @@ -204,7 +204,7 @@ void sound_load(struct Main *main, struct bSound* sound) if(sound->id.lib) path = sound->id.lib->filename; else - path = main ? main->name : NULL; + path = main ? main->name : G.sce; BLI_convertstringcode(fullpath, path); @@ -229,7 +229,7 @@ void sound_load(struct Main *main, struct bSound* sound) break; } #endif - sound->changed = TRUE; + sound->changed++; } } diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 83f83c637bf..e03d647602e 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -26,22 +26,33 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include +#include #include +#include "DNA_packedFile_types.h" #include "DNA_scene_types.h" #include "DNA_space_types.h" #include "DNA_sound_types.h" +#include "DNA_sequence_types.h" #include "DNA_windowmanager_types.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_main.h" #include "BKE_report.h" +#include "BKE_packedFile.h" #include "BKE_sound.h" +#include "BLI_blenlib.h" + #include "ED_sound.h" #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "UI_interface.h" #include "WM_api.h" #include "WM_types.h" @@ -103,7 +114,174 @@ void SOUND_OT_open(wmOperatorType *ot) /* ******************************************************* */ +static int sound_poll(bContext *C) +{ + Editing* ed = CTX_data_scene(C)->ed; + + if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND || !ed->act_seq->sound) + return 0; + + return 1; +} +/********************* pack operator *********************/ + +static int pack_exec(bContext *C, wmOperator *op) +{ + Editing* ed = CTX_data_scene(C)->ed; + bSound* sound; + + if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + return OPERATOR_CANCELLED; + + sound = ed->act_seq->sound; + + if(!sound || sound->packedfile) + return OPERATOR_CANCELLED; + + sound->packedfile= newPackedFile(op->reports, sound->name); + sound_load(CTX_data_main(C), sound); + + return OPERATOR_FINISHED; +} + +void SOUND_OT_pack(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Pack Sound"; + ot->idname= "SOUND_OT_pack"; + + /* api callbacks */ + ot->exec= pack_exec; + ot->poll= sound_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************* unpack operator *********************/ + +// XXX this function is in image_ops.c too, exactly the same, should be moved to a generally accessible position +void unpack_menu(bContext *C, char *opname, char *abs_name, char *folder, PackedFile *pf) +{ + uiPopupMenu *pup; + uiLayout *layout; + char line[FILE_MAX + 100]; + char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX]; + + strcpy(local_name, abs_name); + BLI_splitdirstring(local_name, fi); + sprintf(local_name, "//%s/%s", folder, fi); + + pup= uiPupMenuBegin(C, "Unpack file", 0); + layout= uiPupMenuLayout(pup); + + uiItemEnumO(layout, "Remove Pack", 0, opname, "method", PF_REMOVE); + + if(strcmp(abs_name, local_name)) { + switch(checkPackedFile(local_name, pf)) { + case PF_NOFILE: + sprintf(line, "Create %s", local_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_LOCAL); + break; + case PF_EQUAL: + sprintf(line, "Use %s (identical)", local_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_USE_LOCAL); + break; + case PF_DIFFERS: + sprintf(line, "Use %s (differs)", local_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_USE_LOCAL); + sprintf(line, "Overwrite %s", local_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_LOCAL); + break; + } + } + + switch(checkPackedFile(abs_name, pf)) { + case PF_NOFILE: + sprintf(line, "Create %s", abs_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_ORIGINAL); + break; + case PF_EQUAL: + sprintf(line, "Use %s (identical)", abs_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_USE_ORIGINAL); + break; + case PF_DIFFERS: + sprintf(line, "Use %s (differs)", local_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_USE_ORIGINAL); + sprintf(line, "Overwrite %s", local_name); + uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_ORIGINAL); + break; + } + + uiPupMenuEnd(C, pup); +} + +static int unpack_exec(bContext *C, wmOperator *op) +{ + int method= RNA_enum_get(op->ptr, "method"); + Editing* ed = CTX_data_scene(C)->ed; + bSound* sound; + + if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + return OPERATOR_CANCELLED; + + sound = ed->act_seq->sound; + + if(!sound || !sound->packedfile) + return OPERATOR_CANCELLED; + + if(G.fileflags & G_AUTOPACK) + BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save."); + + unpackSound(op->reports, sound, method); + + return OPERATOR_FINISHED; +} + +static int unpack_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Editing* ed = CTX_data_scene(C)->ed; + bSound* sound; + + if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + return OPERATOR_CANCELLED; + + sound = ed->act_seq->sound; + + if(!sound || !sound->packedfile) + return OPERATOR_CANCELLED; + + if(G.fileflags & G_AUTOPACK) + BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save."); + + unpack_menu(C, "SOUND_OT_unpack", sound->name, "audio", sound->packedfile); + + return OPERATOR_FINISHED; +} + +void SOUND_OT_unpack(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Unpack Sound"; + ot->idname= "SOUND_OT_unpack"; + + /* api callbacks */ + ot->exec= unpack_exec; + ot->invoke= unpack_invoke; + ot->poll= sound_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "method", unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack."); +} + +/* ******************************************************* */ + void ED_operatortypes_sound(void) { WM_operatortype_append(SOUND_OT_open); + WM_operatortype_append(SOUND_OT_pack); + WM_operatortype_append(SOUND_OT_unpack); } -- cgit v1.2.3 From 77c587a8250cd21c751bbab0c4dd263989d88b9a Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Fri, 28 Aug 2009 21:47:11 +0000 Subject: 2.5 Paint: * Removed the BKE_sculpt file and moved it's contents (basically just the sculpt session struct) to BKE_paint --- source/blender/blenkernel/BKE_paint.h | 39 ++++++++++++ source/blender/blenkernel/BKE_sculpt.h | 72 ---------------------- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 1 - .../blender/editors/sculpt_paint/sculpt_intern.h | 1 - 6 files changed, 41 insertions(+), 76 deletions(-) delete mode 100644 source/blender/blenkernel/BKE_sculpt.h diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4337d275776..7dc9e4499c6 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -29,9 +29,13 @@ #define BKE_PAINT_H struct Brush; +struct MFace; +struct MultireModifierData; +struct MVert; struct Object; struct Paint; struct Scene; +struct StrokeCache; extern const char PAINT_CURSOR_SCULPT[3]; extern const char PAINT_CURSOR_VERTEX_PAINT[3]; @@ -53,4 +57,39 @@ void paint_brush_slot_remove(struct Paint *p); * however hiding faces is useful */ int paint_facesel_test(struct Object *ob); +/* Session data (mode-specific) */ + +typedef struct SculptSession { + struct ProjVert *projverts; + + /* Mesh data (not copied) can come either directly from a Mesh, or from a MultiresDM */ + struct MultiresModifierData *multires; /* Special handling for multires meshes */ + struct MVert *mvert; + struct MFace *mface; + int totvert, totface; + float *face_normals; + + /* Mesh connectivity */ + struct ListBase *fmap; + struct IndexNode *fmap_mem; + int fmap_size; + + /* Used temporarily per-stroke */ + float *vertexcosnos; + ListBase damaged_rects; + ListBase damaged_verts; + + /* Used to cache the render of the active texture */ + unsigned int texcache_side, *texcache, texcache_actual; + + /* Layer brush persistence between strokes */ + float (*mesh_co_orig)[3]; /* Copy of the mesh vertices' locations */ + float *layer_disps; /* Displacements for each vertex */ + + struct SculptStroke *stroke; + struct StrokeCache *cache; +} SculptSession; + +void free_sculptsession(SculptSession **); + #endif diff --git a/source/blender/blenkernel/BKE_sculpt.h b/source/blender/blenkernel/BKE_sculpt.h deleted file mode 100644 index 9e5647a8775..00000000000 --- a/source/blender/blenkernel/BKE_sculpt.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2007 by Nicholas Bishop - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef BKE_SCULPT_H -#define BKE_SCULPT_H - -struct MFace; -struct MultireModifierData; -struct MVert; -struct Object; -struct StrokeCache; - -typedef struct SculptSession { - struct ProjVert *projverts; - - /* Mesh data (not copied) can come either directly from a Mesh, or from a MultiresDM */ - struct MultiresModifierData *multires; /* Special handling for multires meshes */ - struct MVert *mvert; - struct MFace *mface; - int totvert, totface; - float *face_normals; - - /* Mesh connectivity */ - struct ListBase *fmap; - struct IndexNode *fmap_mem; - int fmap_size; - - /* Used temporarily per-stroke */ - float *vertexcosnos; - ListBase damaged_rects; - ListBase damaged_verts; - - /* Used to cache the render of the active texture */ - unsigned int texcache_side, *texcache, texcache_actual; - - /* Layer brush persistence between strokes */ - float (*mesh_co_orig)[3]; /* Copy of the mesh vertices' locations */ - float *layer_disps; /* Displacements for each vertex */ - - struct SculptStroke *stroke; - struct StrokeCache *cache; -} SculptSession; - -void free_sculptsession(SculptSession **); - -#endif diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 6f57a658efa..1cb0abfe21c 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -101,13 +101,13 @@ #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_property.h" #include "BKE_sca.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sculpt.h" #include "BKE_softbody.h" #include "LBM_fluidsim.h" diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 89dfa4e2557..9d5ae3062a1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -135,6 +135,7 @@ #include "BKE_multires.h" #include "BKE_node.h" // for tree type defines #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_property.h" // for get_ob_property @@ -143,7 +144,6 @@ #include "BKE_scene.h" #include "BKE_softbody.h" // sbNew() #include "BKE_bullet.h" // bsbNew() -#include "BKE_sculpt.h" #include "BKE_sequence.h" #include "BKE_texture.h" // for open_plugin_tex #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index adaba804799..b08e8ab5c2b 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -65,7 +65,6 @@ #include "BKE_modifier.h" #include "BKE_multires.h" #include "BKE_paint.h" -#include "BKE_sculpt.h" #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_colortools.h" diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index febca301939..25f97b862e6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -32,7 +32,6 @@ #include "DNA_listBase.h" #include "DNA_vec_types.h" -#include "BKE_sculpt.h" struct Brush; struct Mesh; -- cgit v1.2.3 From 17fc83e537f8bfca643d555b8f5e2d14afebd93d Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 21:54:41 +0000 Subject: Error in last commit. --- source/blender/editors/sound/sound_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index e03d647602e..d8a84611298 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -161,7 +161,7 @@ void SOUND_OT_pack(wmOperatorType *ot) /********************* unpack operator *********************/ // XXX this function is in image_ops.c too, exactly the same, should be moved to a generally accessible position -void unpack_menu(bContext *C, char *opname, char *abs_name, char *folder, PackedFile *pf) +static void unpack_menu(bContext *C, char *opname, char *abs_name, char *folder, PackedFile *pf) { uiPopupMenu *pup; uiLayout *layout; -- cgit v1.2.3 From beee5161a9a48eb1610dcad6d9c136b907b2d8ee Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 28 Aug 2009 22:04:37 +0000 Subject: UI for sound (un)packing. --- release/ui/space_sequencer.py | 7 +++++++ source/blender/editors/sound/sound_ops.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index cf9d89edec8..87111b2925f 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -476,6 +476,13 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel): layout.template_ID(strip, "sound", new="sound.open") + layout.itemS() + + if strip.sound.packed_file: + layout.itemO("sound.unpack") + else: + layout.itemO("sound.pack") + layout.itemR(strip.sound, "filename") layout.itemR(strip.sound, "caching") diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index d8a84611298..75204207284 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -118,7 +118,7 @@ static int sound_poll(bContext *C) { Editing* ed = CTX_data_scene(C)->ed; - if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND || !ed->act_seq->sound) + if(!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) return 0; return 1; -- cgit v1.2.3 From 732844bb28f1ad7b14d91455ad24df3d3be86e0c Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 29 Aug 2009 00:41:14 +0000 Subject: * Fixes for point density texture --- release/ui/buttons_texture.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index 78d5e6af790..ad0542d787a 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -656,7 +656,6 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): tex = context.texture pd = tex.pointdensity - ob = context.object layout.itemR(pd, "point_source", expand=True) @@ -664,8 +663,12 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): col = split.column() if pd.point_source == 'PARTICLE_SYSTEM': + col.itemL(text="Object:") + col.itemR(pd, "object", text="") + col = col.column() + col.enabled = pd.object col.itemL(text="System:") - col.item_pointerR(pd, "particle_system", ob, "particle_systems", text="") + col.item_pointerR(pd, "particle_system", pd.object, "particle_systems", text="") col.itemL(text="Cache:") col.itemR(pd, "particle_cache", text="") else: -- cgit v1.2.3 From f46f6dc7ba32411a8031a243bba635c8cc3ade29 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 29 Aug 2009 01:54:10 +0000 Subject: Grease Pencil: Toolbar Compatability Fixes * When starting Grease Pencil from the toolbar, strokes are now started only when a click-drag begins. * Made the 'straight-lines' option an RNA property for the operator * Added an exec() callback and relevant stroke-collection stuff so that interactive redo/changing settings can work. WARNING: this is highly unstable here - keeps crashing though I cannot determine the cause yet. --- source/blender/editors/gpencil/gpencil_paint.c | 249 ++++++++++++++++------- source/blender/editors/space_view3d/view3d_ops.c | 2 +- 2 files changed, 179 insertions(+), 72 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index d6bdea2db55..445d9ae346d 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -115,7 +115,8 @@ typedef struct tGPsdata { /* values for tGPsdata->status */ enum { - GP_STATUS_NORMAL = 0, /* running normally */ + GP_STATUS_IDLING = 0, /* stroke isn't in progress yet */ + GP_STATUS_PAINTING, /* a stroke is in progress */ GP_STATUS_ERROR, /* something wasn't correctly set up */ GP_STATUS_DONE /* painting done */ }; @@ -196,7 +197,7 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) { View3D *v3d= p->sa->spacedata.first; const short mx=mval[0], my=mval[1]; - float *fp= give_cursor(p->scene, v3d); // XXX NULL could be v3d + float *fp= give_cursor(p->scene, v3d); float dvec[3]; /* Current method just converts each point in screen-coordinates to @@ -727,10 +728,19 @@ static tGPsdata *gp_session_initpaint (bContext *C) { //View3D *v3d= curarea->spacedata.first; - /* set current area */ + /* set current area + * - must verify that region data is 3D-view (and not something else) + */ p->sa= curarea; p->ar= ar; + if (ar->regiondata == NULL) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable \n"); + return p; + } + #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) { @@ -1002,8 +1012,8 @@ static void gp_paint_cleanup (tGPsdata *p) static int gpencil_draw_init (bContext *C, wmOperator *op) { tGPsdata *p; - wmWindow *win= CTX_wm_window(C); int paintmode= RNA_enum_get(op->ptr, "mode"); + int straightLines= RNA_boolean_get(op->ptr, "straight_lines"); /* check context */ p= op->customdata= gp_session_initpaint(C); @@ -1023,11 +1033,9 @@ static int gpencil_draw_init (bContext *C, wmOperator *op) /* radius for eraser circle is defined in userprefs now */ p->radius= U.gp_eraser; - /* set cursor */ - if (p->paintmode == GP_PAINTMODE_ERASER) - WM_cursor_modal(win, BC_CROSSCURSOR); // XXX need a better cursor - else - WM_cursor_modal(win, BC_PAINTBRUSHCURSOR); + /* set line-drawing settings (straight or freehand lines) */ + if (straightLines) + p->flags |= GP_PAINTFLAG_STRAIGHTLINES; /* everything is now setup ok */ return 1; @@ -1069,10 +1077,57 @@ static int gpencil_draw_cancel (bContext *C, wmOperator *op) /* ------------------------------- */ +/* create a new stroke point at the point indicated by the painting context */ +static void gpencil_draw_apply (bContext *C, wmOperator *op, tGPsdata *p) +{ + /* handle drawing/erasing -> test for erasing first */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + /* do 'live' erasing now */ + gp_stroke_doeraser(p); + + /* store used values */ + p->mvalo[0]= p->mval[0]; + p->mvalo[1]= p->mval[1]; + p->opressure= p->pressure; + } + /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ + else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { + /* try to add point */ + short ok= gp_stroke_addpoint(p, p->mval, p->pressure); + + /* handle errors while adding point */ + if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { + /* finish off old stroke */ + gp_paint_strokeend(p); + + /* start a new stroke, starting from previous point */ + gp_stroke_addpoint(p, p->mvalo, p->opressure); + ok= gp_stroke_addpoint(p, p->mval, p->pressure); + } + else if (ok == GP_STROKEADD_INVALID) { + /* the painting operation cannot continue... */ + BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke"); + p->status = GP_STATUS_ERROR; + + if (G.f & G_DEBUG) + printf("Error: Grease-Pencil Paint - Add Point Invalid \n"); + // XXX break! + } + + /* store used values */ + p->mvalo[0]= p->mval[0]; + p->mvalo[1]= p->mval[1]; + p->opressure= p->pressure; + } +} + +/* handle draw event */ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *event) { tGPsdata *p= op->customdata; ARegion *ar= p->ar; + PointerRNA itemptr; + float mousef[2]; int tablet=0; /* convert from window-space to area-space mouse coordintes */ @@ -1107,56 +1162,86 @@ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *even return; } + /* fill in stroke data (not actually used directly by gpencil_draw_apply) */ + RNA_collection_add(op->ptr, "stroke", &itemptr); + + mousef[0]= p->mval[0]; + mousef[1]= p->mval[1]; + RNA_float_set_array(&itemptr, "mouse", mousef); + RNA_float_set(&itemptr, "pressure", p->pressure); - /* handle drawing/erasing -> test for erasing first */ - if (p->paintmode == GP_PAINTMODE_ERASER) { - /* do 'live' erasing now */ - gp_stroke_doeraser(p); - - /* store used values */ - p->mvalo[0]= p->mval[0]; - p->mvalo[1]= p->mval[1]; - p->opressure= p->pressure; + /* apply the current latest drawing point */ + gpencil_draw_apply(C, op, p); + + /* force refresh */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! +} + +/* ------------------------------- */ + +/* operator 'redo' (i.e. after changing some properties) */ +static int gpencil_draw_exec (bContext *C, wmOperator *op) +{ + tGPsdata *p = NULL; + + printf("GPencil - Starting Re-Drawing \n"); + + /* try to initialise context data needed while drawing */ + if (!gpencil_draw_init(C, op)) { + if (op->customdata) MEM_freeN(op->customdata); + printf("\tGP - no valid data \n"); + return OPERATOR_CANCELLED; } - /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ - else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { - /* try to add point */ - short ok= gp_stroke_addpoint(p, p->mval, p->pressure); + else + p= op->customdata; + + printf("\tGP - Start redrawing stroke \n"); + + /* loop over the stroke RNA elements recorded (i.e. progress of mouse movement), + * setting the relevant values in context at each step, then applying + */ + RNA_BEGIN(op->ptr, itemptr, "stroke") + { + float mousef[2]; - /* handle errors while adding point */ - if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { - /* finish off old stroke */ - gp_paint_strokeend(p); - - /* start a new stroke, starting from previous point */ - gp_stroke_addpoint(p, p->mvalo, p->opressure); - ok= gp_stroke_addpoint(p, p->mval, p->pressure); - } - else if (ok == GP_STROKEADD_INVALID) { - /* the painting operation cannot continue... */ - BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke"); - p->status = GP_STATUS_ERROR; + printf("\t\tGP - stroke elem \n"); + + /* get relevant data for this point from stroke */ + RNA_float_get_array(&itemptr, "mouse", mousef); + p->mval[0] = (short)mousef[0]; + p->mval[1] = (short)mousef[1]; + p->pressure= RNA_float_get(&itemptr, "pressure"); + + /* if first run, set previous data too */ + if (p->flags & GP_PAINTFLAG_FIRSTRUN) { + p->flags &= ~GP_PAINTFLAG_FIRSTRUN; - if (G.f & G_DEBUG) - printf("Error: Grease-Pencil Paint - Add Point Invalid \n"); - // XXX break! + p->mvalo[0]= p->mval[0]; + p->mvalo[1]= p->mval[1]; + p->opressure= p->pressure; } - /* store used values */ - p->mvalo[0]= p->mval[0]; - p->mvalo[1]= p->mval[1]; - p->opressure= p->pressure; + /* apply this data as necessary now (as per usual) */ + gpencil_draw_apply(C, op, p); } + RNA_END; - /* force refresh */ - WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + printf("\tGP - done \n"); + + /* cleanup */ + gpencil_draw_exit(C, op); + + /* done */ + return OPERATOR_FINISHED; } /* ------------------------------- */ +/* start of interactive drawing part of operator */ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) { tGPsdata *p = NULL; + wmWindow *win= CTX_wm_window(C); printf("GPencil - Starting Drawing \n"); @@ -1177,16 +1262,35 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) // TODO: this involves mucking around with radial control, so we leave this for now.. } - printf("\tGP - set first spot\n"); + /* set cursor */ + if (p->paintmode == GP_PAINTMODE_ERASER) + WM_cursor_modal(win, BC_CROSSCURSOR); // XXX need a better cursor + else + WM_cursor_modal(win, BC_PAINTBRUSHCURSOR); - /* handle the initial drawing - i.e. for just doing a simple dot */ - gpencil_draw_apply_event(C, op, event); + /* special hack: if there was an initial event, then we were invoked via a hotkey, and + * painting should start immediately. Otherwise, this was called from a toolbar, in which + * case we should wait for the mouse to be clicked. + */ + if (event->type) { + /* hotkey invoked - start drawing */ + printf("\tGP - set first spot\n"); + p->status= GP_STATUS_PAINTING; + + /* handle the initial drawing - i.e. for just doing a simple dot */ + gpencil_draw_apply_event(C, op, event); + } + else { + /* toolbar invoked - don't start drawing yet... */ + printf("\tGP - hotkey invoked... waiting for click-drag\n"); + } /* add a modal handler for this operator, so that we can then draw continuous strokes */ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); return OPERATOR_RUNNING_MODAL; } +/* events handling during interactive drawing part of operator */ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) { tGPsdata *p= op->customdata; @@ -1198,25 +1302,35 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) * otherwise, carry on to mouse-move... */ case LEFTMOUSE: - case MIDDLEMOUSE: case RIGHTMOUSE: - if (event->val != KM_PRESS) { + /* if painting, end stroke */ + if (p->status == GP_STATUS_PAINTING) { + /* basically, this should be mouse-button up */ printf("\t\tGP - end of stroke \n"); gpencil_draw_exit(C, op); return OPERATOR_FINISHED; } + else { + /* not painting, so start stroke (this should be mouse-button down) */ + printf("\t\tGP - start stroke \n"); + p->status= GP_STATUS_PAINTING; + /* no break now, since we should immediately start painting */ + } - /* moving mouse - assumed that mouse button is down */ + /* moving mouse - assumed that mouse button is down if in painting status */ case MOUSEMOVE: - /* handle drawing event */ - printf("\t\tGP - add point\n"); - gpencil_draw_apply_event(C, op, event); - - /* finish painting operation if anything went wrong just now */ - if (p->status == GP_STATUS_ERROR) { - printf("\t\t\tGP - error done! \n"); - gpencil_draw_exit(C, op); - return OPERATOR_CANCELLED; + /* check if we're currently painting */ + if (p->status == GP_STATUS_PAINTING) { + /* handle drawing event */ + printf("\t\tGP - add point\n"); + gpencil_draw_apply_event(C, op, event); + + /* finish painting operation if anything went wrong just now */ + if (p->status == GP_STATUS_ERROR) { + printf("\t\t\tGP - error done! \n"); + gpencil_draw_exit(C, op); + return OPERATOR_CANCELLED; + } } break; @@ -1229,17 +1343,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) case WHEELDOWNMOUSE: p->radius -= 1.5f; break; - - /* handle ctrl key - used to toggle straight-lines only (for drawing) */ - // XXX hardcoded keymap stuff - case LEFTCTRLKEY: - case RIGHTCTRLKEY: - if (event->val == KM_PRESS) - p->flags |= GP_PAINTFLAG_STRAIGHTLINES; - else if (event->val == KM_RELEASE) - p->flags &= ~GP_PAINTFLAG_STRAIGHTLINES; - break; - + default: printf("\t\tGP unknown event - %d \n", event->type); break; @@ -1264,7 +1368,7 @@ void GPENCIL_OT_draw (wmOperatorType *ot) ot->description= "Make annotations on the active data."; /* api callbacks */ - //ot->exec= gpencil_draw_exec; + ot->exec= gpencil_draw_exec; ot->invoke= gpencil_draw_invoke; ot->modal= gpencil_draw_modal; ot->cancel= gpencil_draw_cancel; @@ -1275,4 +1379,7 @@ void GPENCIL_OT_draw (wmOperatorType *ot) /* settings for drawing */ RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to intepret mouse movements."); + RNA_def_boolean(ot->srna, "straight_lines", 0, "Straight Lines", "Only take the endpoints of the strokes, so that straight lines can be drawn."); + + RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); } diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 19a70834587..f4e1e008099 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -134,7 +134,7 @@ void view3d_keymap(wmWindowManager *wm) RNA_boolean_set(km->ptr, "snap", 1); /* grease pencil */ - gpencil_common_keymap(wm, keymap); // XXX + gpencil_common_keymap(wm, keymap); WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/ -- cgit v1.2.3 From 8930a4fd332e69442b4de2efe42019bf5a41c946 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 29 Aug 2009 06:50:32 +0000 Subject: Grease Pencil: UI (i.e. Panel) for Settings Restored the UI for access to the GP layers. There are still a few minor bugs here: * Wrong icons on the toggles - even when they're enabled, they only show a single state * The ID-template doesn't seem to be showing up. Dunno what's going wrong there... --- source/blender/editors/gpencil/gpencil_buttons.c | 336 +++++++++------------ source/blender/editors/gpencil/gpencil_edit.c | 126 ++++++++ source/blender/editors/gpencil/gpencil_intern.h | 7 + source/blender/editors/gpencil/gpencil_ops.c | 6 + source/blender/editors/gpencil/gpencil_paint.c | 5 +- source/blender/editors/include/ED_gpencil.h | 5 +- .../blender/editors/space_view3d/view3d_buttons.c | 35 +-- 7 files changed, 290 insertions(+), 230 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 12e987af47b..b572cd6916a 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -47,11 +47,11 @@ #include "BKE_gpencil.h" #include "BKE_utildefines.h" -#include "PIL_time.h" - #include "WM_api.h" #include "WM_types.h" +#include "RNA_access.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -76,259 +76,195 @@ /* ------- Callbacks ----------- */ /* These are just 'dummy wrappers' around gpencil api calls */ -#if 0 -// XXX -/* make layer active one after being clicked on */ -void gp_ui_activelayer_cb (void *gpd, void *gpl) -{ - gpencil_layer_setactive(gpd, gpl); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} -/* rename layer and set active */ -void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg) +/* make layer active one after being clicked on */ +void gp_ui_activelayer_cb (bContext *C, void *gpd, void *gpl) { - bGPdata *gpd= (bGPdata *)gpd_arg; - bGPDlayer *gpl= (bGPDlayer *)gpl_arg; - - BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info[0]), 128); gpencil_layer_setactive(gpd, gpl); - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* add a new layer */ -void gp_ui_addlayer_cb (void *gpd, void *dummy) -{ - gpencil_layer_addnew(gpd); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! } -/* delete active layer */ -void gp_ui_dellayer_cb (void *gpd, void *dummy) +/* delete 'active' layer */ +void gp_ui_dellayer_cb (bContext *C, void *gpd, void *gpl) { + /* make sure the layer we want to remove is the active one */ + gpencil_layer_setactive(gpd, gpl); gpencil_layer_delactive(gpd); - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! } -/* delete last stroke of active layer */ -void gp_ui_delstroke_cb (void *gpd, void *gpl) -{ - bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); - - if (gpf) { - if (gpf->framenum != CFRA) return; - - gpencil_layer_setactive(gpd, gpl); - gpencil_frame_delete_laststroke(gpl, gpf); - - scrarea_queue_winredraw(curarea); - } -} - -/* delete active frame of active layer */ -void gp_ui_delframe_cb (void *gpd, void *gpl) -{ - bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); - - gpencil_layer_setactive(gpd, gpl); - gpencil_layer_delframe(gpl, gpf); - - scrarea_queue_winredraw(curarea); - allqueue(REDRAWACTION, 0); -} - -/* convert the active layer to geometry */ -void gp_ui_convertlayer_cb (void *gpd, void *gpl) -{ - gpencil_layer_setactive(gpd, gpl); - gpencil_convert_menu(); - - scrarea_queue_winredraw(curarea); -} -#endif - /* ------- Drawing Code ------- */ -#if 0 -/* XXX */ /* draw the controls for a given layer */ -static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short *xco, short *yco) +static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) { + uiLayout *box=NULL, *split=NULL; + uiLayout *col=NULL, *subcol=NULL; + uiLayout *row=NULL, *subrow=NULL; + uiBlock *block; uiBut *but; - short active= (gpl->flag & GP_LAYER_ACTIVE); - short width= 314; - short height; - int rb_col; + PointerRNA ptr; + + /* make pointer to layer data */ + RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr); /* unless button has own callback, it adds this callback to button */ + block= uiLayoutGetBlock(layout); uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl); - /* draw header */ - { - uiBlockSetEmboss(block, UI_EMBOSSN); - - /* rounded header */ - if (active) uiBlockSetCol(block, TH_BUT_ACTION); - rb_col= (active)?-20:20; - uiDefBut(block, ROUNDBOX, B_REDR, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), ""); - if (active) uiBlockSetCol(block, TH_AUTO); - - /* lock toggle */ - uiDefIconButBitI(block, ICONTOG, GP_LAYER_LOCKED, B_REDR, ICON_UNLOCKED, *xco-7, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Layer cannot be modified"); - } + /* draw header ---------------------------------- */ + /* get layout-row + UI-block for header */ + box= uiLayoutBox(layout); + + row= uiLayoutRow(box, 0); + block= uiLayoutGetBlock(row); // err... + + uiBlockSetEmboss(block, UI_EMBOSSN); + + /* left-align ............................... */ + subrow= uiLayoutRow(row, 1); + uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT); + + /* active */ + uiItemR(subrow, "", ICON_RADIOBUT_OFF, &ptr, "active", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon + + /* locked */ + uiItemR(subrow, "", ICON_UNLOCKED, &ptr, "locked", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon /* when layer is locked or hidden, only draw header */ if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) { char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */ - height= 0; - /* visibility button (only if hidden but not locked!) */ if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) - uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); + uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon /* name */ if (gpl->flag & GP_LAYER_HIDE) sprintf(name, "%s (Hidden)", gpl->info); else sprintf(name, "%s (Locked)", gpl->info); - uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)"); + uiItemL(subrow, name, 0); /* delete button (only if hidden but not locked!) */ if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) { - but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); - uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); + /* right-align ............................... */ + subrow= uiLayoutRow(row, 1); + uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT); + block= uiLayoutGetBlock(subrow); // XXX... err... + + but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); + uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl); } uiBlockSetEmboss(block, UI_EMBOSS); } else { - height= 97; + /* draw rest of header -------------------------------- */ + /* visibility button */ + uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon - /* draw rest of header */ - { - /* visibility button */ - uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); - - uiBlockSetEmboss(block, UI_EMBOSS); - - /* name */ - but= uiDefButC(block, TEX, B_REDR, "Info:", *xco+36, *yco, 240, 19, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)"); - uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl); - - /* delete 'button' */ - uiBlockSetEmboss(block, UI_EMBOSSN); - - but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); - uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); - - uiBlockSetEmboss(block, UI_EMBOSS); - } + uiBlockSetEmboss(block, UI_EMBOSS); - /* draw backdrop */ - if (active) uiBlockSetCol(block, TH_BUT_ACTION); - uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); - if (active) uiBlockSetCol(block, TH_AUTO); + /* name */ + uiItemR(subrow, "", 0, &ptr, "info", 0); - /* draw settings */ - { - /* color */ - uiBlockBeginAlign(block); - uiDefButF(block, COL, B_REDR, "", *xco, *yco-26, 150, 19, gpl->color, 0, 0, 0, 0, "Color to use for all strokes on this Grease Pencil Layer"); - uiDefButF(block, NUMSLI, B_REDR, "Opacity: ", *xco,*yco-45,150,19, &gpl->color[3], 0.3f, 1.0f, 0, 0, "Visibility of stroke (0.3 to 1.0)"); - uiBlockEndAlign(block); - - /* stroke thickness */ - uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)"); - - /* debugging options */ - if (G.f & G_DEBUG) { - uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes"); - } + /* delete 'button' */ + uiBlockSetEmboss(block, UI_EMBOSSN); + /* right-align ............................... */ + subrow= uiLayoutRow(row, 1); + uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT); + block= uiLayoutGetBlock(subrow); // XXX... err... - /* onion-skinning */ - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, GP_LAYER_ONIONSKIN, B_REDR, "Onion-Skin", *xco+160, *yco-26, 140, 20, &gpl->flag, 0, 0, 0, 0, "Ghost frames on either side of frame"); - uiDefButS(block, NUMSLI, B_REDR, "GStep:", *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Max number of frames on either side of active frame to show (0 = just 'first' available sketch on either side)"); - uiBlockEndAlign(block); + but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); + uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl); + uiBlockSetEmboss(block, UI_EMBOSS); + + + /* new backdrop ----------------------------------- */ + box= uiLayoutBox(layout); + split= uiLayoutSplit(box, 0.5f); + + + /* draw settings ---------------------------------- */ + /* left column ..................... */ + col= uiLayoutColumn(split, 0); + + /* color */ + subcol= uiLayoutColumn(col, 1); + uiItemR(subcol, "", 0, &ptr, "color", 0); + uiItemR(subcol, NULL, 0, &ptr, "opacity", UI_ITEM_R_SLIDER); - /* options */ - uiBlockBeginAlign(block); - if (curarea->spacetype == SPACE_VIEW3D) { - but= uiDefBut(block, BUT, B_REDR, "Convert to...", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Converts this layer's strokes to geometry (Hotkey = Alt-Shift-C)"); - uiButSetFunc(but, gp_ui_convertlayer_cb, gpd, gpl); - } - else { - but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)"); - uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl); - } - - but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)"); - uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl); - uiBlockEndAlign(block); + /* stroke thickness */ + subcol= uiLayoutColumn(col, 1); + uiItemR(subcol, NULL, 0, &ptr, "line_thickness", UI_ITEM_R_SLIDER); + + /* debugging options */ + if (G.f & G_DEBUG) { + // XXX this option hasn't been wrapped yet... since it's just debug + //subcol= uiLayoutColumn(col, 1); + // uiItemR(subrow, NULL, 0, &ptr, "show_points", 0); } + + /* right column ................... */ + col= uiLayoutColumn(split, 0); + + /* onion-skinning */ + subcol= uiLayoutColumn(col, 1); + uiItemR(subcol, "Onion Skinning", 0, &ptr, "use_onion_skinning", 0); + uiItemR(subcol, "GStep", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep) + + /* additional options... */ + // None at the moment... } - - /* adjust height for new to start */ - (*yco) -= (height + 27); } -#endif -/* Draw the contents for a grease-pencil panel. This assumes several things: - * - that panel has been created, is 318 x 204. max yco is 225 - * - that a toggle for turning on/off gpencil drawing is 150 x 20, starting from (10,225) - * which is basically the top left-hand corner - * It will return the amount of extra space to extend the panel by - */ -short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa) + +/* Draw the contents for a grease-pencil panel*/ +static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr) { -#if 0 - uiBut *but; bGPDlayer *gpl; - short xco= 10, yco= 170; + uiLayout *col; - /* draw gpd settings first */ - { - /* add new layer buttons */ - but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,205,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer"); - uiButSetFunc(but, gp_ui_addlayer_cb, gpd, NULL); + /* draw gpd settings first ------------------------------------- */ + col= uiLayoutColumn(layout, 1); + /* current Grease Pencil block */ + // TODO: show some info about who owns this? + // XXX: this template doesn't show up! + uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink"); - - /* show override lmb-clicks button + painting lock */ - uiBlockBeginAlign(block); - if ((gpd->flag & GP_DATA_EDITPAINT)==0) { - uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); - - uiBlockSetCol(block, TH_BUT_SETTING); - uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)"); - uiBlockSetCol(block, TH_AUTO); - } - else - uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); - uiBlockEndAlign(block); - - /* 'view align' button (naming depends on context) */ - if (sa->spacetype == SPACE_VIEW3D) - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); - else - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas"); - } + /* add new layer button */ + uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add"); - /* draw for each layer */ + /* 'view align' button (naming depends on context) */ +#if 0 // XXX for now, this is enabled by default anyways + if (sa->spacetype == SPACE_VIEW3D) + uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); + else + uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas"); +#endif + + /* draw each layer --------------------------------------------- */ for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { - gp_drawui_layer(block, gpd, gpl, &xco, &yco); + col= uiLayoutColumn(layout, 1); + gp_drawui_layer(col, gpd, gpl); } - - /* return new height if necessary */ - return (yco < 0) ? (204 - yco) : 204; -#endif - return 0; } + +/* Standard panel to be included whereever Grease Pencil is used... */ +void gpencil_panel_standard(const bContext *C, Panel *pa) +{ + bGPdata **gpd_ptr = NULL; + PointerRNA ptr; + + //if (v3d->flag2 & V3D_DISPGP)... etc. + + /* get pointer to Grease Pencil Data */ + gpd_ptr= gpencil_data_get_pointers((bContext *)C, &ptr); + + if (gpd_ptr && *gpd_ptr) + draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr); +} + /* ************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 3130e190ce2..2faf3ccbbda 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -60,6 +60,7 @@ #include "BKE_gpencil.h" #include "BKE_image.h" #include "BKE_library.h" +#include "BKE_report.h" #include "BKE_utildefines.h" #include "BIF_gl.h" @@ -123,6 +124,9 @@ bGPdata **gpencil_data_get_pointers (bContext *C, PointerRNA *ptr) /* return the GP data for the active strips/image/etc. */ } break; + + default: /* unsupported space */ + return NULL; } } @@ -141,6 +145,128 @@ bGPdata *gpencil_data_get_active (bContext *C) /* ************************************************ */ /* Panel Operators */ +/* poll callback for adding data/layers - special */ +static int gp_add_poll (bContext *C) +{ + /* the base line we have is that we have somewhere to add Grease Pencil data */ + return gpencil_data_get_pointers(C, NULL) != NULL; +} + +/* ******************* Add New Data ************************ */ + +/* add new datablock - wrapper around API */ +static int gp_data_add_exec (bContext *C, wmOperator *op) +{ + bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL); + + if (gpd_ptr == NULL) { + BKE_report(op->reports, RPT_ERROR, "Nowhere for Grease Pencil data to go"); + return OPERATOR_CANCELLED; + } + else { + /* just add new datablock now */ + *gpd_ptr= gpencil_data_addnew("GPencil"); + } + + /* notifiers */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + + return OPERATOR_FINISHED; +} +void GPENCIL_OT_data_add (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Grease Pencil Add New"; + ot->idname= "GPENCIL_OT_data_add"; + ot->description= "Add new Grease Pencil datablock."; + + /* callbacks */ + ot->exec= gp_data_add_exec; + ot->poll= gp_add_poll; +} + +/* ******************* Unlink Data ************************ */ + +/* poll callback for adding data/layers - special */ +static int gp_data_unlink_poll (bContext *C) +{ + bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL); + + /* if we have access to some active data, make sure there's a datablock before enabling this */ + return (gpd_ptr && *gpd_ptr); +} + + +/* unlink datablock - wrapper around API */ +static int gp_data_unlink_exec (bContext *C, wmOperator *op) +{ + bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL); + + if (gpd_ptr == NULL) { + BKE_report(op->reports, RPT_ERROR, "Nowhere for Grease Pencil data to go"); + return OPERATOR_CANCELLED; + } + else { + /* just unlink datablock now, decreasing its user count */ + bGPdata *gpd= (*gpd_ptr); + + gpd->id.us--; + *gpd_ptr= NULL; + } + + /* notifiers */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_data_unlink (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Grease Pencil Unlink"; + ot->idname= "GPENCIL_OT_data_unlink"; + ot->description= "Unlink active Grease Pencil datablock."; + + /* callbacks */ + ot->exec= gp_data_unlink_exec; + ot->poll= gp_data_unlink_poll; +} + +/* ******************* Add New Layer ************************ */ + +/* add new layer - wrapper around API */ +static int gp_layer_add_exec (bContext *C, wmOperator *op) +{ + bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL); + + /* if there's no existing Grease-Pencil data there, add some */ + if (gpd_ptr == NULL) { + BKE_report(op->reports, RPT_ERROR, "Nowhere for Grease Pencil data to go"); + return OPERATOR_CANCELLED; + } + if (*gpd_ptr == NULL) + *gpd_ptr= gpencil_data_addnew("GPencil"); + + /* add new layer now */ + gpencil_layer_addnew(*gpd_ptr); + + /* notifiers */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_layer_add (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add New Layer"; + ot->idname= "GPENCIL_OT_layer_add"; + ot->description= "Add new Grease Pencil layer for the active Grease Pencil datablock."; + + /* callbacks */ + ot->exec= gp_layer_add_exec; + ot->poll= gp_add_poll; +} /* ************************************************ */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index b134328c8a0..cc98d491f7a 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -40,6 +40,13 @@ struct wmOperatorType; void GPENCIL_OT_draw(struct wmOperatorType *ot); +/* buttons editing --- */ + +void GPENCIL_OT_data_add(struct wmOperatorType *ot); +void GPENCIL_OT_data_unlink(struct wmOperatorType *ot); + +void GPENCIL_OT_layer_add(struct wmOperatorType *ot); + /******************************************************* */ /* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */ diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 347a611ee30..364b27b61b0 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -66,10 +66,16 @@ void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap) void ED_operatortypes_gpencil (void) { /* Drawing ----------------------- */ + WM_operatortype_append(GPENCIL_OT_draw); /* Editing (Buttons) ------------ */ + WM_operatortype_append(GPENCIL_OT_data_add); + WM_operatortype_append(GPENCIL_OT_data_unlink); + + WM_operatortype_append(GPENCIL_OT_layer_add); + /* Editing (Time) --------------- */ } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 445d9ae346d..82dc76a2152 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -919,7 +919,7 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode) View3D *v3d= (View3D *)p->sa->spacedata.first; RegionView3D *rv3d= p->ar->regiondata; - // TODO: this should only happen for scene... otherwise use object center! + // TODO: this should only happen for scene... otherwise apply correction for object center! float *fp= give_cursor(p->scene, v3d); initgrabz(rv3d, fp[0], fp[1], fp[2]); @@ -1231,6 +1231,9 @@ static int gpencil_draw_exec (bContext *C, wmOperator *op) /* cleanup */ gpencil_draw_exit(C, op); + /* refreshes */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + /* done */ return OPERATOR_FINISHED; } diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 25e622d8551..ba60211ef3f 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -39,8 +39,7 @@ struct bGPdata; struct bGPDlayer; struct bGPDframe; struct PointerRNA; -struct uiLayout; -struct uiBlock; +struct Panel; struct ImBuf; struct wmWindowManager; @@ -75,5 +74,7 @@ void draw_gpencil_2dview(struct bContext *C, short onlyv2d); void draw_gpencil_3dview(struct bContext *C, short only3d); void draw_gpencil_oglrender(struct bContext *C); +void gpencil_panel_standard(const struct bContext *C, struct Panel *pa); + #endif /* ED_GPENCIL_H */ diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 9b05f5b25b2..2fbe7e5db79 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -36,6 +36,7 @@ #include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_camera_types.h" +#include "DNA_gpencil_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_meta_types.h" @@ -81,6 +82,7 @@ #include "ED_armature.h" #include "ED_curve.h" #include "ED_image.h" +#include "ED_gpencil.h" #include "ED_keyframing.h" #include "ED_mesh.h" #include "ED_object.h" @@ -1199,33 +1201,6 @@ static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3 } #endif -#if 0 -static void view3d_panel_gpencil(const bContext *C, Panel *pa) -{ - View3D *v3d= CTX_wm_view3d(C); - uiBlock *block; - - block= uiLayoutFreeBlock(pa->layout); - - /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */ - if (v3d->flag2 & V3D_DISPGP) { -// if (v3d->gpd == NULL) -// XXX gpencil_data_setactive(ar, gpencil_data_addnew()); - } - - if (v3d->flag2 & V3D_DISPGP) { -// XXX bGPdata *gpd= v3d->gpd; - - /* draw button for showing gpencil settings and drawings */ - uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)"); - } - else { - uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View"); - uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); - } -} -#endif - static void delete_sketch_armature(bContext *C, void *arg1, void *arg2) { BIF_deleteSketch(C); @@ -1416,6 +1391,12 @@ void view3d_buttons_register(ARegionType *art) strcpy(pt->label, "Transform"); pt->draw= view3d_panel_object; BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); + strcpy(pt->idname, "VIEW3D_PT_gpencil"); + strcpy(pt->label, "Grease Pencil"); + pt->draw= gpencil_panel_standard; + BLI_addtail(&art->paneltypes, pt); /* pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel properties"); strcpy(pt->idname, "VIEW3D_PT_properties"); -- cgit v1.2.3 From e055bb7f7d35d36be7083c637fb90d1ef9f10fd7 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 29 Aug 2009 07:44:21 +0000 Subject: ui layout tweaks --- release/ui/buttons_data_armature.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index 3a1de0d5f0b..f207b556a6d 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -40,6 +40,12 @@ class DATA_PT_skeleton(DataButtonsPanel): split = layout.split() + col = split.column() + col.itemL(text="Layers:") + col.template_layers(arm, "layer") + col.itemL(text="Protected Layers:") + col.template_layers(arm, "layer_protection") + col = split.column() col.itemR(arm, "rest_position") col.itemL(text="Deform:") @@ -49,13 +55,7 @@ class DATA_PT_skeleton(DataButtonsPanel): col.itemR(arm, "deform_bbone_rest", text="B-Bones Rest") #col.itemR(arm, "x_axis_mirror") #col.itemR(arm, "auto_ik") - - col = split.column() - col.itemL(text="Layers:") - col.template_layers(arm, "layer") - col.itemL(text="Protected Layers:") - col.template_layers(arm, "layer_protection") - + class DATA_PT_display(DataButtonsPanel): __label__ = "Display" @@ -154,7 +154,7 @@ class DATA_PT_ghost(DataButtonsPanel): split = layout.split() col = split.column() - col.itemR(arm, "ghost_type", text="Scope") + col.itemR(arm, "ghost_type", text="") sub = col.column(align=True) if arm.ghost_type == 'RANGE': -- cgit v1.2.3 From a9947b33b23a3b0d53ad0451c35996daec14b8ae Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 29 Aug 2009 10:34:31 +0000 Subject: minor tweaks --- release/ui/buttons_physics_fluid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/ui/buttons_physics_fluid.py b/release/ui/buttons_physics_fluid.py index 1d0a64c517a..5af63bdc3ba 100644 --- a/release/ui/buttons_physics_fluid.py +++ b/release/ui/buttons_physics_fluid.py @@ -46,7 +46,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel): layout.itemR(fluid, "type") if fluid.type == 'DOMAIN': - layout.itemO("fluid.bake", text="BAKE") + layout.itemO("fluid.bake", text="Bake Fluid Simulation", icon='ICON_MOD_FLUIDSIM') split = layout.split() col = split.column() -- cgit v1.2.3 From 3080a6273325bdfcde3d1898334e3749aa2f9b2d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 29 Aug 2009 11:48:38 +0000 Subject: Grease Pencil UI - Small fixes for the toggles (icons working correctly now) --- source/blender/editors/gpencil/gpencil_buttons.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index b572cd6916a..954f6c7e61e 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -76,7 +76,6 @@ /* ------- Callbacks ----------- */ /* These are just 'dummy wrappers' around gpencil api calls */ - /* make layer active one after being clicked on */ void gp_ui_activelayer_cb (bContext *C, void *gpd, void *gpl) { @@ -106,6 +105,7 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) uiBlock *block; uiBut *but; PointerRNA ptr; + int icon; /* make pointer to layer data */ RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr); @@ -128,10 +128,12 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT); /* active */ - uiItemR(subrow, "", ICON_RADIOBUT_OFF, &ptr, "active", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon + icon= (gpl->flag & GP_LAYER_ACTIVE) ? ICON_RADIOBUT_ON : ICON_RADIOBUT_OFF; + uiItemR(subrow, "", icon, &ptr, "active", 0); /* locked */ - uiItemR(subrow, "", ICON_UNLOCKED, &ptr, "locked", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon + icon= (gpl->flag & GP_LAYER_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED; + uiItemR(subrow, "", icon, &ptr, "locked", 0); /* when layer is locked or hidden, only draw header */ if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) { @@ -139,7 +141,8 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) /* visibility button (only if hidden but not locked!) */ if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) - uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon + uiItemR(subrow, "", ICON_RESTRICT_VIEW_ON, &ptr, "hide", 0); + /* name */ if (gpl->flag & GP_LAYER_HIDE) @@ -163,7 +166,7 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) else { /* draw rest of header -------------------------------- */ /* visibility button */ - uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon + uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", 0); uiBlockSetEmboss(block, UI_EMBOSS); @@ -227,10 +230,9 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi uiLayout *col; /* draw gpd settings first ------------------------------------- */ - col= uiLayoutColumn(layout, 1); + col= uiLayoutColumn(layout, 0); /* current Grease Pencil block */ // TODO: show some info about who owns this? - // XXX: this template doesn't show up! uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink"); /* add new layer button */ -- cgit v1.2.3 From c03004f93eb94d4af10acaf0b7e8ca7adb097dd0 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sat, 29 Aug 2009 14:53:00 +0000 Subject: 2.5: Added some sound actuator UI to reveal its real power, check it out! :) --- source/blender/editors/sound/sound_ops.c | 6 ++++++ source/blender/editors/space_logic/logic_window.c | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 75204207284..303ca0eaefd 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -43,6 +43,7 @@ #include "BKE_report.h" #include "BKE_packedFile.h" #include "BKE_sound.h" +#include "BKE_utildefines.h" #include "BLI_blenlib.h" @@ -86,6 +87,10 @@ static int open_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + if (RNA_boolean_get(op->ptr, "cache")) { + sound_cache(sound, 0); + } + return OPERATOR_FINISHED; } @@ -110,6 +115,7 @@ void SOUND_OT_open(wmOperatorType *ot) /* properties */ WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE); + RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory."); } /* ******************************************************* */ diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 06bd95f060f..d4475527058 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1990,7 +1990,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh sa->sndnr = 0; if(sa->flag & ACT_SND_3D_SOUND) - ysize = 114; + ysize = 180; else ysize = 92; @@ -2003,24 +2003,31 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh /* reset this value, it is for handling the event */ sa->sndnr = 0; uiDefButS(block, MENU, B_SOUNDACT_BROWSE, str, xco+10,yco-22,20,19, &(sa->sndnr), 0, 0, 0, 0, ""); + uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+wval+10, yco-22, wval, 19, "Load a sound file. Remember to set caching on for small sounds that are played often."); if(sa->sound) { char dummy_str[] = "Sound mode %t|Play Stop %x0|Play End %x1|Loop Stop %x2|Loop End %x3|Loop Ping Pong Stop %x5|Loop Ping Pong %x4"; - uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,width-40,19, sa->sound->id.name+2, 0.0, 21.0, 0, 0, ""); + uiDefBut(block, TEX, B_IDNAME, "SO:",xco+30,yco-22,wval-20,19, sa->sound->id.name+2, 0.0, 21.0, 0, 0, ""); uiDefButS(block, MENU, 1, dummy_str,xco+10,yco-44,width-20, 19, &sa->type, 0.0, 0.0, 0, 0, ""); uiDefButF(block, NUM, 0, "Volume:", xco+10,yco-66,wval, 19, &sa->volume, 0.0, 1.0, 0, 0, "Sets the volume of this sound"); uiDefButF(block, NUM, 0, "Pitch:",xco+wval+10,yco-66,wval, 19, &sa->pitch,-12.0, 12.0, 0, 0, "Sets the pitch of this sound"); uiDefButS(block, TOG | BIT, 0, "3D Sound", xco+10, yco-88, width-20, 19, &sa->flag, 0.0, 1.0, 0.0, 0.0, "Plays the sound positioned in 3D space."); if(sa->flag & ACT_SND_3D_SOUND) { - uiDefButF(block, NUM, 0, "Rolloff: ", xco+10, yco-110, wval, 19, &sa->sound3D.rolloff_factor, 0.0, 5.0, 0.0, 0.0, "The rolloff factor defines the influence factor on volume depending on distance."); - uiDefButF(block, NUM, 0, "Reference distance: ", xco+wval+10, yco-110, wval, 19, &sa->sound3D.reference_distance, 0.0, 1000.0, 0.0, 0.0, "The reference distance is the distance where the sound has a gain of 1.0."); + uiDefButF(block, NUM, 0, "Minimum Gain: ", xco+10, yco-110, wval, 19, &sa->sound3D.min_gain, 0.0, 1.0, 0.0, 0.0, "The minimum gain of the sound, no matter how far it is away."); + uiDefButF(block, NUM, 0, "Maximum Gain: ", xco+10, yco-132, wval, 19, &sa->sound3D.max_gain, 0.0, 1.0, 0.0, 0.0, "The maximum gain of the sound, no matter how near it is.."); + uiDefButF(block, NUM, 0, "Reference Distance: ", xco+10, yco-154, wval, 19, &sa->sound3D.reference_distance, 0.0, 1000.0, 0.0, 0.0, "The reference distance is the distance where the sound has a gain of 1.0."); + uiDefButF(block, NUM, 0, "Maximum Distance: ", xco+10, yco-176, wval, 19, &sa->sound3D.max_distance, 0.0, 1000.0, 0.0, 0.0, "The maximum distance at which you can hear the sound."); + uiDefButF(block, NUM, 0, "Rolloff: ", xco+wval+10, yco-110, wval, 19, &sa->sound3D.rolloff_factor, 0.0, 5.0, 0.0, 0.0, "The rolloff factor defines the influence factor on volume depending on distance."); + uiDefButF(block, NUM, 0, "Cone Outer Gain: ", xco+wval+10, yco-132, wval, 19, &sa->sound3D.cone_outer_gain, 0.0, 1.0, 0.0, 0.0, "The gain outside the outer cone. The gain in the outer cone will be interpolated between this value und the normal gain in the inner cone."); + uiDefButF(block, NUM, 0, "Cone Outer Angle: ", xco+wval+10, yco-154, wval, 19, &sa->sound3D.cone_outer_angle, 0.0, 360.0, 0.0, 0.0, "The angle of the outer cone."); + uiDefButF(block, NUM, 0, "Cone Inner Angle: ", xco+wval+10, yco-176, wval, 19, &sa->sound3D.cone_inner_angle, 0.0, 360.0, 0.0, 0.0, "The angle of the inner cone."); } } MEM_freeN(str); } else { - uiDefBut(block, LABEL, 0, "Use Sound window (F10) to load samples", xco, yco-24, width, 19, NULL, 0, 0, 0, 0, ""); + uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+10, yco-22, width-20, 19, "Load a sound file."); } yco-= ysize; -- cgit v1.2.3 From 874d38eeb401a75f849cc36c7d7b911129c3aa75 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Sat, 29 Aug 2009 15:20:36 +0000 Subject: Point cache editing: - Baked point caches for particles, cloth and softbody can now be edited in particle mode. * This overwrites the old cloth/sb cache editmode editing. * The type of editable system is chosen from a menu. * For particles the current particle system and it's current cache are used. - Currently this only works for caches that are in memory, but some automatic conversion from disk to memory and back can be implemented later. - All tools from hair editing can't be applied to point caches and are hidden in the tool panel and specials menu. Some functionality like subdividing paths can be later implemented in a slightly different way from how it works for hair. - Code is not yet optimized for speed, so editing might be slow sometimes. Known issues: - Cloth doesn't update properly while in particle mode, due to the way cloth modifier currently works. Daniel can you check on this? - As "particle mode" is not only for particles any more some other name would be in place? - Better icons are needed for the path, point, and tip-modes as the current icons from mesh edit mode are quite misleading. - Direct editing of point velocities is not yet implemented, but will be in the future. Other changes: - Hair editing doesn't require a "make editable" button press any more. - Multiple caches in single particle system disables changing emission properties. - Unified ui code for all point cache panels. * Defined in buttons_particle.py and imported for cloth, smoke & softbody. - Proper disabling of properties in ui after baking point caches. (Daniel could you please make needed disable code for smoke panels as their functionality is not familiar to me.) - Hair weight brush has been removed. Once hair dynamics is re-implemented I'll code a more useable alternative to the functionality. Bug fixes: - Unlinking particle settings crashed. - Deleting the active object with particles in the scene crashed. - Softbody didn't write point caches correctly on save. --- release/ui/buttons_particle.py | 157 +- release/ui/buttons_physics_cloth.py | 64 +- release/ui/buttons_physics_smoke.py | 46 +- release/ui/buttons_physics_softbody.py | 64 +- release/ui/space_view3d_toolbar.py | 81 +- source/blender/blenkernel/BKE_particle.h | 50 +- source/blender/blenkernel/BKE_pointcache.h | 78 +- source/blender/blenkernel/intern/cloth.c | 2 +- source/blender/blenkernel/intern/particle.c | 426 ++-- source/blender/blenkernel/intern/particle_system.c | 49 +- source/blender/blenkernel/intern/pointcache.c | 63 +- source/blender/blenkernel/intern/scene.c | 4 +- source/blender/blenloader/intern/readfile.c | 6 +- source/blender/blenloader/intern/writefile.c | 2 +- source/blender/editors/include/ED_particle.h | 10 +- source/blender/editors/mesh/editmesh.c | 156 +- source/blender/editors/physics/ed_pointcache.c | 13 +- source/blender/editors/physics/editparticle.c | 2154 ++++++++++---------- source/blender/editors/space_outliner/outliner.c | 2 - source/blender/editors/space_view3d/drawobject.c | 195 +- .../blender/editors/space_view3d/view3d_header.c | 6 +- .../editors/transform/transform_conversions.c | 96 +- .../editors/transform/transform_manipulator.c | 18 +- source/blender/makesdna/DNA_object_force.h | 9 +- source/blender/makesdna/DNA_particle_types.h | 12 +- source/blender/makesdna/DNA_scene_types.h | 26 +- source/blender/makesrna/intern/rna_particle.c | 62 +- source/blender/makesrna/intern/rna_sculpt_paint.c | 158 +- 28 files changed, 2064 insertions(+), 1945 deletions(-) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index 0454f2a4023..0b18b7c2072 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -2,13 +2,79 @@ import bpy def particle_panel_enabled(psys): - return psys.point_cache.baked==False and psys.editable==False + return psys.point_cache.baked==False and psys.edited==False def particle_panel_poll(context): psys = context.particle_system if psys==None: return False if psys.settings==None: return False return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR') + +def point_cache_ui(self, cache, enabled, particles, smoke): + layout = self.layout + layout.set_context_pointer("PointCache", cache) + + row = layout.row() + row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 ) + col = row.column(align=True) + col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") + col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") + + row = layout.row() + row.itemL(text="File Name:") + if particles: + row.itemR(cache, "external") + + if cache.external: + split = layout.split(percentage=0.80) + split.itemR(cache, "name", text="") + split.itemR(cache, "index", text="") + + layout.itemL(text="File Path:") + layout.itemR(cache, "filepath", text="") + + layout.itemL(text=cache.info) + else: + layout.itemR(cache, "name", text="") + + if not particles: + row = layout.row() + row.enabled = enabled + row.itemR(cache, "start_frame") + row.itemR(cache, "end_frame") + + row = layout.row() + + if cache.baked == True: + row.itemO("ptcache.free_bake", text="Free Bake") + else: + row.item_booleanO("ptcache.bake", "bake", True, text="Bake") + + sub = row.row() + sub.enabled = (cache.frames_skipped or cache.outdated) and enabled + sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") + + row = layout.row() + row.enabled = enabled + row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") + row.itemR(cache, "step"); + + if not smoke: + row = layout.row() + sub = row.row() + sub.enabled = enabled + sub.itemR(cache, "quick_cache") + row.itemR(cache, "disk_cache") + + layout.itemL(text=cache.info) + + layout.itemS() + + row = layout.row() + row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") + row.itemO("ptcache.free_bake_all", text="Free All Bakes") + layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") + class ParticleButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' @@ -38,7 +104,16 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): col.itemO("object.particle_system_add", icon='ICON_ZOOMIN', text="") col.itemO("object.particle_system_remove", icon='ICON_ZOOMOUT', text="") - if psys: + if psys and not psys.settings: + split = layout.split(percentage=0.32) + col = split.column() + col.itemL(text="Name:") + col.itemL(text="Settings:") + + col = split.column() + col.itemR(psys, "name", text="") + col.template_ID(psys, "settings", new="particle.new") + elif psys: part = psys.settings split = layout.split(percentage=0.32) @@ -69,10 +144,10 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): split = layout.split(percentage=0.65) if part.type=='HAIR': - if psys.editable==True: - split.itemO("particle.editable_set", text="Free Edit") + if psys.edited==True: + split.itemO("particle.edited_clear", text="Free Edit") else: - split.itemO("particle.editable_set", text="Make Editable") + split.itemL(text="") row = split.row() row.enabled = particle_panel_enabled(psys) row.itemR(part, "hair_step") @@ -96,7 +171,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) + layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches row = layout.row() row.itemR(part, "amount") @@ -149,76 +224,8 @@ class PARTICLE_PT_cache(ParticleButtonsPanel): layout = self.layout psys = context.particle_system - part = psys.settings - cache = psys.point_cache - layout.set_context_pointer("PointCache", cache) - - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 ) - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - - row = layout.row() - row.itemL(text="File Name:") - row.itemR(cache, "external") - - if cache.external: - split = layout.split(percentage=0.80) - split.itemR(cache, "name", text="") - split.itemR(cache, "index", text="") - - layout.itemL(text="File Path:") - layout.itemR(cache, "filepath", text="") - - layout.itemL(text=cache.info) - - #split = layout.split() - - #col = split.column(align=True) - #col.itemR(part, "start") - #col.itemR(part, "end") - - #col = split.column(align=True) - #col.itemR(part, "lifetime") - #col.itemR(part, "random_lifetime", slider=True) - else: - layout.itemR(cache, "name", text="") - - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - - subrow = row.row() - subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys) - subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") - - row = layout.row() - row.enabled = particle_panel_enabled(psys) - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - row.itemR(cache, "step"); - - row = layout.row() - subrow = row.row() - subrow.enabled = particle_panel_enabled(psys) - subrow.itemR(cache, "quick_cache") - row.itemR(cache, "disk_cache") - - layout.itemL(text=cache.info) - - layout.itemS() - - row = layout.row() - row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") - # for particles these are figured out automatically - #row.itemR(cache, "start_frame") - #row.itemR(cache, "end_frame") + point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), 1, 0) class PARTICLE_PT_initial(ParticleButtonsPanel): __label__ = "Velocity" diff --git a/release/ui/buttons_physics_cloth.py b/release/ui/buttons_physics_cloth.py index 9ddf03e3d4d..9399d557a51 100644 --- a/release/ui/buttons_physics_cloth.py +++ b/release/ui/buttons_physics_cloth.py @@ -1,6 +1,11 @@ import bpy +from buttons_particle import point_cache_ui + +def cloth_panel_enabled(md): + return md.point_cache.baked==False + class PhysicButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -41,6 +46,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel): split = layout.split() + split.active = cloth_panel_enabled(md) + col = split.column() col.itemL(text="Quality:") col.itemR(cloth, "quality", text="Steps",slider=True) @@ -85,53 +92,8 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel): return (context.cloth != None) def draw(self, context): - layout = self.layout - - cache = context.cloth.point_cache - layout.set_context_pointer("PointCache", cache) - - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2) - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - - row = layout.row() - row.itemR(cache, "name") - - row = layout.row() - row.itemR(cache, "start_frame") - row.itemR(cache, "end_frame") - - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - - subrow = row.row() - subrow.enabled = cache.frames_skipped or cache.outdated - subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") - - row = layout.row() - #row.enabled = particle_panel_enabled(psys) - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - row.itemR(cache, "step"); - - row = layout.row() - #row.enabled = particle_panel_enabled(psys) - row.itemR(cache, "quick_cache") - row.itemR(cache, "disk_cache") - - layout.itemL(text=cache.info) - - layout.itemS() - - row = layout.row() - row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") + md = context.cloth + point_cache_ui(self, md.point_cache, cloth_panel_enabled(md), 0, 0) class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): __label__ = "Cloth Collision" @@ -143,7 +105,8 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): def draw_header(self, context): layout = self.layout cloth = context.cloth.collision_settings - + + layout.active = cloth_panel_enabled(context.cloth) layout.itemR(cloth, "enable_collision", text="") def draw(self, context): @@ -151,7 +114,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): cloth = context.cloth.collision_settings split = layout.split() - layout.active = cloth.enable_collision + layout.active = cloth.enable_collision and cloth_panel_enabled(md) col = split.column() col.itemR(cloth, "collision_quality", slider=True, text="Quality") @@ -176,6 +139,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): layout = self.layout cloth = context.cloth.settings + layout.active = cloth_panel_enabled(context.cloth) layout.itemR(cloth, "stiffness_scaling", text="") def draw(self, context): @@ -183,7 +147,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): ob = context.object cloth = context.cloth.settings - layout.active = cloth.stiffness_scaling + layout.active = cloth.stiffness_scaling and cloth_panel_enabled(md) split = layout.split() diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py index 3cfba0f9df9..d7313632638 100644 --- a/release/ui/buttons_physics_smoke.py +++ b/release/ui/buttons_physics_smoke.py @@ -1,6 +1,8 @@ import bpy +from buttons_particle import point_cache_ui + def smoke_panel_enabled_low(smd): if smd.smoke_type == 'TYPE_DOMAIN': return smd.domain.point_cache.baked==False @@ -139,48 +141,8 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel): domain = md.domain_settings cache = domain.point_cache - layout.set_context_pointer("PointCache", cache) - - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index") - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - - row = layout.row() - row.itemR(cache, "name") - - row = layout.row() - row.itemR(cache, "start_frame") - row.itemR(cache, "end_frame") - - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - - subrow = row.row() - subrow.enabled = cache.frames_skipped or cache.outdated - subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") - - row = layout.row() - #row.enabled = smoke_panel_enabled(psys) - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - - row = layout.row() - #row.enabled = smoke_panel_enabled(psys) - - layout.itemL(text=cache.info) - - layout.itemS() - - row = layout.row() - row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") - + point_cache_ui(self, cache, cache.baked==False, 0, 1) + class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): __label__ = "Smoke High Resolution" __default_closed__ = True diff --git a/release/ui/buttons_physics_softbody.py b/release/ui/buttons_physics_softbody.py index 2beba8c95a0..3d3c3c23faf 100644 --- a/release/ui/buttons_physics_softbody.py +++ b/release/ui/buttons_physics_softbody.py @@ -1,6 +1,11 @@ import bpy +from buttons_particle import point_cache_ui + +def softbody_panel_enabled(md): + return md.point_cache.baked==False + class PhysicButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -41,6 +46,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel): # General split = layout.split() + split.enabled = softbody_panel_enabled(md) col = split.column() col.itemL(text="Object:") @@ -60,52 +66,9 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel): return (context.soft_body) def draw(self, context): - layout = self.layout - - cache = context.soft_body.point_cache - layout.set_context_pointer("PointCache", cache) - - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2) - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - - row = layout.row() - row.itemR(cache, "name") - - row = layout.row() - row.itemR(cache, "start_frame") - row.itemR(cache, "end_frame") - - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - - sub = row.row() - sub.enabled = cache.frames_skipped or cache.outdated - sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") + md = context.soft_body + point_cache_ui(self, md.point_cache, softbody_panel_enabled(md), 0, 0) - row = layout.row() - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - row.itemR(cache, "step"); - - row = layout.row() - row.itemR(cache, "quick_cache") - row.itemR(cache, "disk_cache") - - layout.itemL(text=cache.info) - - layout.itemS() - - row = layout.row() - row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") - class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): __label__ = "Soft Body Goal" @@ -117,6 +80,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): softbody = context.soft_body.settings + layout.active = softbody_panel_enabled(context.soft_body) layout.itemR(softbody, "use_goal", text="") def draw(self, context): @@ -129,7 +93,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): if md: softbody = md.settings - layout.active = softbody.use_goal + layout.active = softbody.use_goal and softbody_panel_enabled(md) # Goal split = layout.split() @@ -159,6 +123,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel): softbody = context.soft_body.settings + layout.active = softbody_panel_enabled(context.soft_body) layout.itemR(softbody, "use_edges", text="") def draw(self, context): @@ -170,7 +135,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel): if md: softbody = md.settings - layout.active = softbody.use_edges + layout.active = softbody.use_edges and softbody_panel_enabled(md) split = layout.split() @@ -209,6 +174,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel): softbody = context.soft_body.settings + layout.active = softbody_panel_enabled(context.soft_body) layout.itemR(softbody, "self_collision", text="") def draw(self, context): @@ -220,7 +186,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel): if md: softbody = md.settings - layout.active = softbody.self_collision + layout.active = softbody.self_collision and softbody_panel_enabled(md) layout.itemL(text="Collision Type:") layout.itemR(softbody, "collision_type", expand=True) @@ -245,6 +211,8 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel): if md: softbody = md.settings + + layout.active = softbody_panel_enabled(md) # Solver split = layout.split() diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 0e6dc76d49d..517571e1b09 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -362,8 +362,10 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column(align=True) col.item_enumR(settings, "tool", 'DRAW') col.item_enumR(settings, "tool", 'SOFTEN') - col.item_enumR(settings, "tool", 'CLONE') - col.item_enumR(settings, "tool", 'SMEAR') + if settings.use_projection: + col.item_enumR(settings, "tool", 'CLONE') + else: + col.item_enumR(settings, "tool", 'SMEAR') col = layout.column() col.itemR(brush, "color", text="") @@ -426,9 +428,9 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel): if not texture_paint: layout.itemR(brush, "smooth_stroke") col = layout.column() - col.active = brush.smooth_stroke - col.itemR(brush, "smooth_stroke_radius", text="Radius", slider=True) - col.itemR(brush, "smooth_stroke_factor", text="Factor", slider=True) + col.itemR(brush, "airbrush") + col.itemR(brush, "anchored") + col.itemR(brush, "rake") layout.itemR(brush, "space") row = layout.row(align=True) @@ -538,22 +540,12 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel): # col.itemR(vpaint, "mul", text="") -# ********** options for projection paint **************** +# ********** default tools for texturepaint **************** -class VIEW3D_PT_tools_projectpaint(View3DPanel): +class VIEW3D_PT_tools_texturepaint(View3DPanel): __context__ = "texturepaint" - __label__ = "Project Paint" - - def poll(self, context): - return context.tool_settings.image_paint.tool != 'SMEAR' - - def draw_header(self, context): - layout = self.layout - - ipaint = context.tool_settings.image_paint + __label__ = "Options" - layout.itemR(ipaint, "use_projection", text="") - def draw(self, context): layout = self.layout @@ -562,6 +554,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel): use_projection= ipaint.use_projection col = layout.column() + col.itemR(ipaint, "use_projection") sub = col.column() sub.active = use_projection sub.itemR(ipaint, "use_occlude") @@ -606,22 +599,58 @@ class VIEW3D_PT_tools_particlemode(View3DPanel): def draw(self, context): layout = self.layout pe = context.tool_settings.particle_edit + ob = pe.object + row = layout.row() + row.itemL(text="Edit:") + row.itemR(pe, "type", text="") + + if pe.type == 'PARTICLES': + if ob.particle_systems: + if len(ob.particle_systems) > 1: + layout.template_list(ob, "particle_systems", ob, "active_particle_system_index", type='ICONS') + + ptcache = ob.particle_systems[ob.active_particle_system_index].point_cache + else: + for md in ob.modifiers: + if md.type==pe.type: + ptcache = md.point_cache + + if ptcache and len(ptcache.point_cache_list) > 1: + layout.template_list(ptcache, "point_cache_list", ptcache, "active_point_cache_index", type='ICONS') + + + if not pe.editable: + layout.itemL(text="Point cache must be baked") + layout.itemL(text="to enable editing!") + col = layout.column(align=True) - col.itemR(pe, "emitter_deflect", text="Deflect") - sub = col.row() - sub.active = pe.emitter_deflect - sub.itemR(pe, "emitter_distance", text="Distance") + if pe.hair: + col.active = pe.editable + col.itemR(pe, "emitter_deflect", text="Deflect emitter") + sub = col.row() + sub.active = pe.emitter_deflect + sub.itemR(pe, "emitter_distance", text="Distance") col = layout.column(align=True) + col.active = pe.editable col.itemL(text="Keep:") col.itemR(pe, "keep_lengths", text="Lenghts") col.itemR(pe, "keep_root", text="Root") + if not pe.hair: + col.itemL(text="Correct:") + col.itemR(pe, "auto_velocity", text="Velocity") col = layout.column(align=True) - col.itemL(text="Display:") - col.itemR(pe, "show_time", text="Time") - col.itemR(pe, "show_children", text="Children") + col.active = pe.editable + col.itemL(text="Draw:") + col.itemR(pe, "draw_step", text="Path Steps") + if pe.type == 'PARTICLES': + col.itemR(pe, "draw_particles", text="Particles") + col.itemR(pe, "fade_time") + sub = col.row() + sub.active = pe.fade_time + sub.itemR(pe, "fade_frames", slider=True) bpy.types.register(VIEW3D_PT_tools_objectmode) bpy.types.register(VIEW3D_PT_tools_meshedit) @@ -638,5 +667,5 @@ bpy.types.register(VIEW3D_PT_tools_brush_curve) bpy.types.register(VIEW3D_PT_sculpt_options) bpy.types.register(VIEW3D_PT_tools_vertexpaint) bpy.types.register(VIEW3D_PT_tools_weightpaint) -bpy.types.register(VIEW3D_PT_tools_projectpaint) +bpy.types.register(VIEW3D_PT_tools_texturepaint) bpy.types.register(VIEW3D_PT_tools_particlemode) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index cf02efc34ac..e24114cd219 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -109,46 +109,10 @@ typedef struct ParticleCacheKey{ float vel[3]; float rot[4]; float col[3]; + float time; int steps; } ParticleCacheKey; -typedef struct ParticleEditKey{ - float *co; - float *vel; - float *rot; - float *time; - - float world_co[3]; - float length; - short flag; -} ParticleEditKey; - -typedef struct ParticleUndo { - struct ParticleUndo *next, *prev; - struct ParticleEditKey **keys; - struct KDTree *emitter_field; - struct ParticleData *particles; - float *emitter_cosnos; - int totpart, totkeys; - char name[64]; -} ParticleUndo; - -typedef struct ParticleEdit { - ListBase undo; - struct ParticleUndo *curundo; - - ParticleEditKey **keys; - int totkeys; - - int *mirror_cache; - - struct KDTree *emitter_field; - float *emitter_cosnos; - - char sel_col[3]; - char nosel_col[3]; -} ParticleEdit; - typedef struct ParticleThreadContext { /* shared */ struct Scene *scene; @@ -240,7 +204,7 @@ int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys); void psys_free_boid_rules(struct ListBase *list); void psys_free_settings(struct ParticleSettings *part); void free_child_path_cache(struct ParticleSystem *psys); -void psys_free_path_cache(struct ParticleSystem *psys); +void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); void free_hair(struct ParticleSystem *psys, int softbody); void free_keyed_keys(struct ParticleSystem *psys); void psys_free(struct Object * ob, struct ParticleSystem * psys); @@ -271,9 +235,9 @@ void psys_reset(struct ParticleSystem *psys, int mode); void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys); -void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate); +void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra); +void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra); void psys_cache_child_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate); -void psys_update_world_cos(struct Object *ob, struct ParticleSystem *psys); int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb); float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size); float psys_get_timestep(struct ParticleSettings *part); @@ -359,12 +323,6 @@ void reset_particle(struct Scene *scene, struct ParticleData *pa, struct Particl #define PSYS_EC_PARTICLE 4 #define PSYS_EC_REACTOR 8 -/* ParticleEditKey->flag */ -#define PEK_SELECT 1 -#define PEK_TO_SELECT 2 -#define PEK_TAG 4 -#define PEK_HIDE 8 - /* index_dmcache */ #define DMCACHE_NOTFOUND -1 #define DMCACHE_ISCHILD -2 diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 531487549da..9ba34091064 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -101,6 +101,8 @@ typedef struct PTCacheFile { void *cur[BPHYS_TOT_DATA]; } PTCacheFile; +#define PTCACHE_VEL_PER_SEC 1 + typedef struct PTCacheID { struct PTCacheID *next, *prev; @@ -109,6 +111,7 @@ typedef struct PTCacheID { void *calldata; int type; int stack_index; + int flag; /* flags defined in DNA_object_force.h */ unsigned int data_types, info_types; @@ -151,6 +154,75 @@ typedef struct PTCacheBaker { void *progresscontext; } PTCacheBaker; +/* PTCacheEditKey->flag */ +#define PEK_SELECT 1 +#define PEK_TAG 2 +#define PEK_HIDE 4 +#define PEK_USE_WCO 8 + +typedef struct PTCacheEditKey{ + float *co; + float *vel; + float *rot; + float *time; + + float world_co[3]; + float ftime; + float length; + short flag; +} PTCacheEditKey; + +/* PTCacheEditPoint->flag */ +#define PEP_TAG 1 +#define PEP_EDIT_RECALC 2 +#define PEP_TRANSFORM 4 +#define PEP_HIDE 8 + +typedef struct PTCacheEditPoint { + struct PTCacheEditKey *keys; + int totkey; + short flag; +} PTCacheEditPoint; + +typedef struct PTCacheUndo { + struct PTCacheUndo *next, *prev; + struct PTCacheEditPoint *points; + + /* particles stuff */ + struct ParticleData *particles; + struct KDTree *emitter_field; + float *emitter_cosnos; + + /* cache stuff */ + struct ListBase mem_cache; + + int totpoint; + char name[64]; +} PTCacheUndo; + +typedef struct PTCacheEdit { + ListBase undo; + struct PTCacheUndo *curundo; + PTCacheEditPoint *points; + + struct PTCacheID pid; + + /* particles stuff */ + struct ParticleSystem *psys; + struct ParticleData *particles; + struct KDTree *emitter_field; + float *emitter_cosnos; + int *mirror_cache; + + struct ParticleCacheKey **pathcache; /* path cache (runtime) */ + ListBase pathcachebufs; + + int totpoint, totframes, totcached, edited; + + char sel_col[3]; + char nosel_col[3]; +} PTCacheEdit; + /* Particle functions */ void BKE_ptcache_make_particle_key(struct ParticleKey *key, int index, void **data, float time); @@ -179,6 +251,10 @@ void BKE_ptcache_update_info(PTCacheID *pid); /* Size of cache data type. */ int BKE_ptcache_data_size(int data_type); +/* Memory cache read/write helpers. */ +void BKE_ptcache_mem_init_pointers(struct PTCacheMem *pm); +void BKE_ptcache_mem_incr_pointers(struct PTCacheMem *pm); + /* Copy a specific data type from cache data to point data. */ void BKE_ptcache_data_get(void **data, int type, int index, void *to); @@ -197,7 +273,7 @@ int BKE_ptcache_get_continue_physics(void); /******************* Allocate & free ***************/ struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches); -void BKE_ptache_free_mem(struct PointCache *cache); +void BKE_ptcache_free_mem(struct ListBase *mem_cache); void BKE_ptcache_free(struct PointCache *cache); void BKE_ptcache_free_list(struct ListBase *ptcaches); struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, struct ListBase *ptcaches_old); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 3acaaecb1e8..eafd9eb01fe 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -347,7 +347,7 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) BKE_ptcache_id_from_cloth(&pid, ob, clmd); // don't do anything as long as we're in editmode! - if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE) + if(pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT) return; BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e1987d34a6c..18e3512967a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -321,7 +321,7 @@ int psys_ob_has_hair(Object *ob) } int psys_in_edit_mode(Scene *scene, ParticleSystem *psys) { - return ((scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && psys->edit); + return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit)); } int psys_check_enabled(Object *ob, ParticleSystem *psys) { @@ -406,13 +406,20 @@ void free_child_path_cache(ParticleSystem *psys) psys->childcache = NULL; psys->totchildcache = 0; } -void psys_free_path_cache(ParticleSystem *psys) +void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit) { - psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs); - psys->pathcache= NULL; - psys->totcached= 0; + if(edit) { + psys_free_path_cache_buffers(edit->pathcache, &edit->pathcachebufs); + edit->pathcache= NULL; + edit->totcached= 0; + } + else { + psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs); + psys->pathcache= NULL; + psys->totcached= 0; - free_child_path_cache(psys); + free_child_path_cache(psys); + } } void psys_free_children(ParticleSystem *psys) { @@ -431,14 +438,14 @@ void psys_free(Object *ob, ParticleSystem * psys) int nr = 0; ParticleSystem * tpsys; - psys_free_path_cache(psys); + psys_free_path_cache(psys, NULL); free_hair(psys, 1); free_keyed_keys(psys); if(psys->edit && psys->free_edit) - psys->free_edit(psys); + psys->free_edit(psys->edit); if(psys->particles){ if(psys->particles->boid) @@ -645,7 +652,7 @@ void psys_render_restore(Object *ob, ParticleSystem *psys) psmd->dm->release(psmd->dm); } - psys_free_path_cache(psys); + psys_free_path_cache(psys, NULL); if(psys->child){ MEM_freeN(psys->child); @@ -953,17 +960,25 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic typedef struct ParticleInterpolationData { - ParticleKey *kkey[2]; HairKey *hkey[2]; - BodyPoint *bp[2]; + + int keyed; + ParticleKey *kkey[2]; + SoftBody *soft; - int keyed, cached; + BodyPoint *bp[2]; + + PointCache *cache; + + PTCacheEditPoint *epoint; + PTCacheEditKey *ekey[2]; + float birthtime, dietime; + int bspline; } ParticleInterpolationData; /* Assumes pointcache->mem_cache exists, so for disk cached particles call psys_make_temp_pointcache() before use */ -static void get_pointcache_keys_for_time(Object *ob, ParticleSystem *psys, int index, float t, ParticleKey *key1, ParticleKey *key2) +static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, int index, float t, ParticleKey *key1, ParticleKey *key2) { - PointCache *cache = psys->pointcache; static PTCacheMem *pm = NULL; /* not thread safe */ if(index < 0) { /* initialize */ @@ -990,22 +1005,27 @@ static void get_pointcache_keys_for_time(Object *ob, ParticleSystem *psys, int i static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind) { - if(pind->keyed) { - pind->kkey[0] = pa->keys; + if(pind->epoint) { + PTCacheEditPoint *point = pind->epoint; - if(pa->totkey > 1) - pind->kkey[1] = pa->keys + 1; - else - pind->kkey[1] = NULL; + pind->ekey[0] = point->keys; + pind->ekey[1] = point->totkey > 1 ? point->keys + 1 : NULL; + + pind->birthtime = *(point->keys->time); + pind->dietime = *((point->keys + point->totkey - 1)->time); + } + else if(pind->keyed) { + pind->kkey[0] = pa->keys; + pind->kkey[1] = pa->totkey > 1 ? pa->keys + 1 : NULL; pind->birthtime = pa->keys->time; pind->dietime = (pa->keys + pa->totkey - 1)->time; } - else if(pind->cached) { - get_pointcache_keys_for_time(ob, psys, -1, 0.0f, NULL, NULL); + else if(pind->cache) { + get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL); - pind->birthtime = pa->time; - pind->dietime = pa->dietime; + pind->birthtime = pa ? pa->time : pind->cache->startframe; + pind->dietime = pa ? pa->dietime : pind->cache->endframe; } else { pind->hkey[0] = pa->hair; @@ -1020,6 +1040,14 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->bp[1] = pind->soft->bpoint + pa->bpi + 1; } } +static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey) +{ + VECCOPY(key->co, ekey->co); + if(ekey->vel) { + VECCOPY(key->vel, ekey->vel); + } + key->time = *(ekey->time); +} static void hair_to_particle(ParticleKey *key, HairKey *hkey) { VECCOPY(key->co, hkey->co); @@ -1033,11 +1061,24 @@ static void bp_to_particle(ParticleKey *key, BodyPoint *bp, HairKey *hkey) static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData *pa, float t, float frs_sec, ParticleInterpolationData *pind, ParticleKey *result) { + PTCacheEditPoint *point = pind->epoint; ParticleKey keys[4]; + int point_vel = (point && point->keys->vel); float real_t, dfra, keytime; /* interpret timing and find keys */ - if(pind->keyed) { + if(point) { + if(result->time < 0.0f) + real_t = -result->time; + else + real_t = *(pind->ekey[0]->time) + t * (*(pind->ekey[0][point->totkey-1].time) - *(pind->ekey[0]->time)); + + while(*(pind->ekey[1]->time) < real_t) + pind->ekey[1]++; + + pind->ekey[0] = pind->ekey[1] - 1; + } + else if(pind->keyed) { /* we have only one key, so let's use that */ if(pind->kkey[1]==NULL) { copy_particle_key(result, pind->kkey[0], 1); @@ -1074,7 +1115,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData pind->kkey[0] = pind->kkey[1] - 1; } - else if(pind->cached) { + else if(pind->cache) { if(result->time < 0.0f) /* flag for time in frames */ real_t = -result->time; else @@ -1095,7 +1136,11 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData } /* set actual interpolation keys */ - if(pind->soft) { + if(point) { + edit_to_particle(keys + 1, pind->ekey[0]); + edit_to_particle(keys + 2, pind->ekey[1]); + } + else if(pind->soft) { pind->bp[0] = pind->bp[1] - 1; bp_to_particle(keys + 1, pind->bp[0], pind->hkey[0]); bp_to_particle(keys + 2, pind->bp[1], pind->hkey[1]); @@ -1104,8 +1149,8 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData memcpy(keys + 1, pind->kkey[0], sizeof(ParticleKey)); memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey)); } - else if(pind->cached) { - get_pointcache_keys_for_time(NULL, psys, p, real_t, keys+1, keys+2); + else if(pind->cache) { + get_pointcache_keys_for_time(NULL, pind->cache, p, real_t, keys+1, keys+2); } else { hair_to_particle(keys + 1, pind->hkey[0]); @@ -1113,8 +1158,14 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData } /* set secondary interpolation keys for hair */ - if(!pind->keyed && !pind->cached) { - if(pind->soft) { + if(!pind->keyed && !pind->cache && !point_vel) { + if(point) { + if(pind->ekey[0] != point->keys) + edit_to_particle(keys, pind->ekey[0] - 1); + else + edit_to_particle(keys, pind->ekey[0]); + } + else if(pind->soft) { if(pind->hkey[0] != pa->hair) bp_to_particle(keys, pind->bp[0] - 1, pind->hkey[0] - 1); else @@ -1127,7 +1178,13 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData hair_to_particle(keys, pind->hkey[0]); } - if(pind->soft) { + if(point) { + if(pind->ekey[1] != point->keys + point->totkey - 1) + edit_to_particle(keys + 3, pind->ekey[1] + 1); + else + edit_to_particle(keys + 3, pind->ekey[1]); + } + else if(pind->soft) { if(pind->hkey[1] != pa->hair + pa->totkey - 1) bp_to_particle(keys + 3, pind->bp[1] + 1, pind->hkey[1] + 1); else @@ -1145,19 +1202,19 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData keytime = (real_t - keys[1].time) / dfra; /* convert velocity to timestep size */ - if(pind->keyed || pind->cached){ + if(pind->keyed || pind->cache || point_vel){ VecMulf(keys[1].vel, dfra / frs_sec); VecMulf(keys[2].vel, dfra / frs_sec); QuatInterpol(result->rot,keys[1].rot,keys[2].rot,keytime); } /* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/ - psys_interpolate_particle((pind->keyed || pind->cached) ? -1 /* signal for cubic interpolation */ - : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL) + psys_interpolate_particle((pind->keyed || pind->cache || point_vel) ? -1 /* signal for cubic interpolation */ + : (pind->bspline ? KEY_BSPLINE : KEY_CARDINAL) ,keys, keytime, result, 1); /* the velocity needs to be converted back from cubic interpolation */ - if(pind->keyed || pind->cached) + if(pind->keyed || pind->cache || point_vel) VecMulf(result->vel, frs_sec / dfra); } /************************************************/ @@ -1610,7 +1667,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) } } } - return 0; + return NULL; } /************************************************/ /* Particles on a shape */ @@ -2129,7 +2186,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in /*---start figuring out what is actually wanted---*/ if(psys_in_edit_mode(scene, psys)) - if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_SHOW_CHILD)==0) + if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0) totchild=0; if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ @@ -2245,7 +2302,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, needupdate= 0; w= 0; while(w<4 && cpa->pa[w]>=0) { - if(psys->particles[cpa->pa[w]].flag & PARS_EDIT_RECALC) { + if(psys->edit->points[cpa->pa[w]].flag & PEP_EDIT_RECALC) { needupdate= 1; break; } @@ -2288,7 +2345,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, } else{ if(ctx->editupdate && !(part->flag & PART_BRANCHING)) { - if(!(psys->particles[cpa->parent].flag & PARS_EDIT_RECALC)) + if(!(psys->edit->points[cpa->parent].flag & PEP_EDIT_RECALC)) return; memset(keys, 0, sizeof(*keys)*(ctx->steps+1)); @@ -2557,24 +2614,20 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa /* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */ /* -Makes child strands possible and creates them too into the cache. */ /* -Cached path data is also used to determine cut position for the editmode tool. */ -void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate) +void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra) { - ParticleCacheKey *ca, **cache=psys->pathcache; + ParticleCacheKey *ca, **cache= psys->pathcache; ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); - ParticleEditSettings *pset = &scene->toolsettings->particle; ParticleSettings *part = psys->part; + ParticleEditSettings *pset = &scene->toolsettings->particle; - ParticleData *pa; + ParticleData *pa = psys->particles; ParticleKey result; - ParticleEdit *edit = 0; - ParticleEditKey *ekey = 0; - - SoftBody *soft = 0; + SoftBody *soft = NULL; BodyPoint *bp[2] = {NULL, NULL}; Material *ma; - ParticleInterpolationData pind; float birthtime = 0.0, dietime = 0.0; @@ -2583,132 +2636,98 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra float prev_tangent[3], hairmat[4][4]; float rotmat[3][3]; int k,i; - int steps = (int)pow(2.0, (double)psys->part->draw_step); + int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step)); int totpart = psys->totpart; - float sel_col[3]; - float nosel_col[3]; float length, vec[3]; float *vg_effector= NULL, effector=0.0f; float *vg_length= NULL, pa_length=1.0f; int keyed, baked; /* we don't have anything valid to create paths from so let's quit here */ - if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0 && (psys->pointcache->flag & PTCACHE_BAKED)==0) + if(!(psys->flag & PSYS_HAIR_DONE) && !(psys->flag & PSYS_KEYED) && !(psys->pointcache->flag & PTCACHE_BAKED)) return; + if(psys_in_edit_mode(scene, psys)) + if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0) + return; + BLI_srandom(psys->seed); keyed = psys->flag & PSYS_KEYED; baked = psys->pointcache->flag & PTCACHE_BAKED; - if(psys->renderdata) { - steps = (int)pow(2.0, (double)psys->part->ren_step); - } - else if(psys_in_edit_mode(scene, psys)) { - edit=psys->edit; - - //timed = edit->draw_timed; - - if(pset->brushtype == PE_BRUSH_WEIGHT) { - sel_col[0] = sel_col[1] = sel_col[2] = 1.0f; - nosel_col[0] = nosel_col[1] = nosel_col[2] = 0.0f; - } - else{ - sel_col[0] = (float)edit->sel_col[0] / 255.0f; - sel_col[1] = (float)edit->sel_col[1] / 255.0f; - sel_col[2] = (float)edit->sel_col[2] / 255.0f; - nosel_col[0] = (float)edit->nosel_col[0] / 255.0f; - nosel_col[1] = (float)edit->nosel_col[1] / 255.0f; - nosel_col[2] = (float)edit->nosel_col[2] / 255.0f; - } - } - - if(editupdate && psys->pathcache && totpart == psys->totcached) { - cache = psys->pathcache; - } - else { - /* clear out old and create new empty path cache */ - psys_free_path_cache(psys); - cache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1); - psys->pathcache= cache; - } + /* clear out old and create new empty path cache */ + psys_free_path_cache(psys, NULL); + cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1); - if(edit==NULL && psys->soft && psys->softflag & OB_SB_ENABLE) { + if(psys->soft && psys->softflag & OB_SB_ENABLE) { soft = psys->soft; if(!soft->bpoint) soft= NULL; } - + psys->lattice = psys_get_lattice(scene, ob, psys); ma= give_current_material(ob, psys->part->omat); if(ma && (psys->part->draw & PART_DRAW_MAT_COL)) VECCOPY(col, &ma->r) - + if(psys->part->from!=PART_FROM_PARTICLE) { if(!(psys->part->flag & PART_CHILD_EFFECT)) vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR); - if(!edit && !psys->totchild) + if(!psys->totchild) vg_length = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_LENGTH); } /*---first main loop: create all actual particles' paths---*/ - for(i=0,pa=psys->particles; iflag & PARS_NO_DISP || pa->flag & PARS_UNEXIST)) { + for(i=0; iflag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) { if(soft) bp[0] += pa->totkey; /* TODO use of initialized value? */ continue; } - if(editupdate && !(pa->flag & PARS_EDIT_RECALC)) continue; - else memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); - - if(!edit && !psys->totchild) { + if(!psys->totchild) { pa_length = 1.0f - part->randlength * 0.5 * (1.0f + pa->r_ave[0]); if(vg_length) pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length); } - cache[i]->steps = steps; + pind.keyed = keyed; + pind.cache = baked ? psys->pointcache : NULL; + pind.soft = soft; + pind.epoint = NULL; + pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); + + memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); - if(edit) - ekey = edit->keys[i]; + cache[i]->steps = steps; /*--get the first data points--*/ - pind.keyed = keyed; - pind.cached = baked; - pind.soft = soft; init_particle_interpolation(ob, psys, pa, &pind); - /* hairmat is needed for for non-hair particle too so we get proper rotations */ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); VECCOPY(rotmat[0], hairmat[2]); VECCOPY(rotmat[1], hairmat[1]); VECCOPY(rotmat[2], hairmat[0]); - if(!edit) { - if(part->draw & PART_ABS_PATH_TIME) { - birthtime = MAX2(pind.birthtime, part->path_start); - dietime = MIN2(pind.dietime, part->path_end); - } - else { - float tb = pind.birthtime; - birthtime = tb + part->path_start * (pind.dietime - tb); - dietime = tb + part->path_end * (pind.dietime - tb); - } - - if(birthtime >= dietime) { - cache[i]->steps = -1; - continue; - } + if(part->draw & PART_ABS_PATH_TIME) { + birthtime = MAX2(pind.birthtime, part->path_start); + dietime = MIN2(pind.dietime, part->path_end); + } + else { + float tb = pind.birthtime; + birthtime = tb + part->path_start * (pind.dietime - tb); + dietime = tb + part->path_end * (pind.dietime - tb); + } - dietime = birthtime + pa_length * (dietime - birthtime); + if(birthtime >= dietime) { + cache[i]->steps = -1; + continue; } - else - /* XXX brecht: don't know if this code from 2.4 is correct - * still, but makes hair appear again in particle mode */ - dietime= pind.hkey[0][pa->totkey-1].time; + + dietime = birthtime + pa_length * (dietime - birthtime); /*--interpolate actual path from data points--*/ for(k=0, ca=cache[i]; k<=steps; k++, ca++){ @@ -2726,40 +2745,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra } VECCOPY(ca->co, result.co); - - /* selection coloring in edit mode */ - if(edit){ - if(pset->brushtype==PE_BRUSH_WEIGHT){ - if(k==steps) - VecLerpf(ca->col, nosel_col, sel_col, pind.hkey[0]->weight); - else - VecLerpf(ca->col, nosel_col, sel_col, - (1.0f - keytime) * pind.hkey[0]->weight + keytime * pind.hkey[1]->weight); - } - else{ - if((ekey + (pind.hkey[0] - pa->hair))->flag & PEK_SELECT){ - if((ekey + (pind.hkey[1] - pa->hair))->flag & PEK_SELECT){ - VECCOPY(ca->col, sel_col); - } - else{ - VecLerpf(ca->col, sel_col, nosel_col, keytime); - } - } - else{ - if((ekey + (pind.hkey[1] - pa->hair))->flag & PEK_SELECT){ - VecLerpf(ca->col, nosel_col, sel_col, keytime); - } - else{ - VECCOPY(ca->col, nosel_col); - } - } - } - } - else{ - VECCOPY(ca->col, col); - } + VECCOPY(ca->col, col); } - /*--modify paths and calculate rotation & velocity--*/ @@ -2772,16 +2759,16 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra for(k=0, ca=cache[i]; k<=steps; k++, ca++) { /* apply effectors */ - if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k) + if(!(psys->part->flag & PART_CHILD_EFFECT) && k) do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec); /* apply guide curves to path data */ - if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0) + if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0) /* ca is safe to cast, since only co and vel are used */ do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors); /* apply lattice */ - if(psys->lattice && edit==0) + if(psys->lattice) calc_latt_deform(psys->lattice, ca->co, 1.0f); /* figure out rotation */ @@ -2810,8 +2797,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra cosangle= Inpf(tangent, prev_tangent); /* note we do the comparison on cosangle instead of - * angle, since floating point accuracy makes it give - * different results across platforms */ + * angle, since floating point accuracy makes it give + * different results across platforms */ if(cosangle > 0.999999f) { QUATCOPY((ca - 1)->rot, (ca - 2)->rot); } @@ -2856,6 +2843,124 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra if(vg_length) MEM_freeN(vg_length); } +void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cfra) +{ + ParticleCacheKey *ca, **cache= edit->pathcache; + ParticleEditSettings *pset = &scene->toolsettings->particle; + + PTCacheEditPoint *point = edit->points; + PTCacheEditKey *ekey = NULL; + + ParticleSystem *psys = edit->psys; + ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); + ParticleSettings *part = psys ? psys->part : NULL; + ParticleData *pa = psys ? psys->particles : NULL; + + ParticleInterpolationData pind; + ParticleKey result; + + float birthtime = 0.0, dietime = 0.0; + float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec; + float hairmat[4][4]; + int k,i; + int steps = (int)pow(2.0, (double)pset->draw_step); + int totpart = edit->totpoint; + float sel_col[3]; + float nosel_col[3]; + + steps = MAX2(steps, 4); + + if(!cache || edit->totpoint != edit->totcached) { + /* clear out old and create new empty path cache */ + psys_free_path_cache(NULL, edit); + cache= edit->pathcache= psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, steps+1); + } + + frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.0f; + + sel_col[0] = (float)edit->sel_col[0] / 255.0f; + sel_col[1] = (float)edit->sel_col[1] / 255.0f; + sel_col[2] = (float)edit->sel_col[2] / 255.0f; + nosel_col[0] = (float)edit->nosel_col[0] / 255.0f; + nosel_col[1] = (float)edit->nosel_col[1] / 255.0f; + nosel_col[2] = (float)edit->nosel_col[2] / 255.0f; + + /*---first main loop: create all actual particles' paths---*/ + for(i=0; itotcached && !(point->flag & PEP_EDIT_RECALC)) + continue; + + ekey = point->keys; + + pind.keyed = 0; + pind.cache = NULL; + pind.soft = NULL; + pind.epoint = point; + pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0; + + memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); + + cache[i]->steps = steps; + + /*--get the first data points--*/ + init_particle_interpolation(ob, psys, pa, &pind); + + if(psys) + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + + birthtime = pind.birthtime; + dietime = pind.dietime; + + if(birthtime >= dietime) { + cache[i]->steps = -1; + continue; + } + + /*--interpolate actual path from data points--*/ + for(k=0, ca=cache[i]; k<=steps; k++, ca++){ + time = (float)k / (float)steps; + + t = birthtime + time * (dietime - birthtime); + + result.time = -t; + + do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); + + /* non-hair points are allready in global space */ + if(psys) + Mat4MulVecfl(hairmat, result.co); + + VECCOPY(ca->co, result.co); + + ca->vel[0] = ca->vel[1] = 0.0f; + ca->vel[1] = 1.0f; + + /* selection coloring in edit mode */ + if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){ + if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ + VECCOPY(ca->col, sel_col); + } + else{ + keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); + VecLerpf(ca->col, sel_col, nosel_col, keytime); + } + } + else{ + if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ + keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); + VecLerpf(ca->col, nosel_col, sel_col, keytime); + } + else{ + VECCOPY(ca->col, nosel_col); + } + } + + ca->time = t; + } + } + + edit->totcached = totpart; +} /************************************************/ /* Particle Key handling */ /************************************************/ @@ -3663,8 +3768,9 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i } pind.keyed = keyed; - pind.cached = cached; + pind.cache = cached ? psys->pointcache : NULL; pind.soft = NULL; + pind.epoint = NULL; init_particle_interpolation(ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index bf642a14a49..0f72c1c5866 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -127,7 +127,7 @@ void psys_reset(ParticleSystem *psys, int mode) int i; if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) { - if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->flag & PSYS_EDITED))) { + if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->edit && psys->edit->edited))) { if(psys->particles) { if(psys->particles->keys) MEM_freeN(psys->particles->keys); @@ -145,6 +145,12 @@ void psys_reset(ParticleSystem *psys, int mode) if(psys->reactevents.first) BLI_freelistN(&psys->reactevents); + + if(psys->edit && psys->free_edit) { + psys->free_edit(psys->edit); + psys->edit = NULL; + psys->free_edit = NULL; + } } } else if(mode == PSYS_RESET_CACHE_MISS) { @@ -165,7 +171,7 @@ void psys_reset(ParticleSystem *psys, int mode) psys->totchild= 0; /* reset path cache */ - psys_free_path_cache(psys); + psys_free_path_cache(psys, NULL); /* reset point cache */ psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID; @@ -2274,7 +2280,7 @@ void psys_clear_temp_pointcache(ParticleSystem *psys) if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0) return; - BKE_ptache_free_mem(psys->pointcache); + BKE_ptcache_free_mem(&psys->pointcache->mem_cache); } void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra) { @@ -3747,41 +3753,17 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR || (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){ - psys_cache_paths(scene, ob, psys, cfra, 0); + psys_cache_paths(scene, ob, psys, cfra); /* for render, child particle paths are computed on the fly */ if(part->childtype) { - if(((psys->totchild!=0)) || (psys_in_edit_mode(scene, psys) && (pset->flag&PE_SHOW_CHILD))) + if(((psys->totchild!=0)) || (psys_in_edit_mode(scene, psys) && (pset->flag&PE_DRAW_PART))) if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) psys_cache_child_paths(scene, ob, psys, cfra, 0); } } else if(psys->pathcache) - psys_free_path_cache(psys); -} - -/* calculate and store key locations in world coordinates */ -void psys_update_world_cos(Object *ob, ParticleSystem *psys) -{ - ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); - ParticleData *pa; - ParticleEditKey *key; - int i, k, totpart; - float hairmat[4][4]; - - if(psys==0 || psys->edit==0) - return; - - totpart= psys->totpart; - - for(i=0, pa=psys->particles; idm, psys->part->from, pa, hairmat); - - for(k=0, key=psys->edit->keys[i]; ktotkey; k++, key++) { - VECCOPY(key->world_co,key->co); - Mat4MulVecfl(hairmat, key->world_co); - } - } + psys_free_path_cache(psys, NULL); } static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) @@ -3808,9 +3790,6 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd psys_init_effectors(scene, ob, part->eff_group, psys); if(psys->effectors.first) precalc_effectors(scene, ob,psys,psmd,cfra); - - if(psys_in_edit_mode(scene, psys)) - psys_update_world_cos(ob, psys); psys_update_path_cache(scene, ob,psmd,psys,cfra); } @@ -4339,7 +4318,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle psys_update_path_cache(scene, ob, psmd, psys,(int)cfra); } else if(psys->pathcache) - psys_free_path_cache(psys); + psys_free_path_cache(psys, NULL); /* cleanup */ if(vg_vel) MEM_freeN(vg_vel); @@ -4385,7 +4364,7 @@ static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys) static int hair_needs_recalc(ParticleSystem *psys) { - if((psys->flag & PSYS_EDITED)==0 && + if((!psys->edit || !psys->edit->edited) && ((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET)) { return 1; } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 69da8f19d8c..c0223d1690c 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -434,6 +434,8 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p pid->cache_ptr= &psys->pointcache; pid->ptcaches= &psys->ptcaches; + pid->flag |= PTCACHE_VEL_PER_SEC; + pid->write_elem= ptcache_write_particle; pid->write_stream = NULL; pid->read_stream = NULL; @@ -800,14 +802,16 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) } for(psys=ob->particlesystem.first; psys; psys=psys->next) { - pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); - BKE_ptcache_id_from_particles(pid, ob, psys); - BLI_addtail(lb, pid); - - if(psys->soft) { + if(psys->part) { pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); - BKE_ptcache_id_from_softbody(pid, ob, psys->soft); + BKE_ptcache_id_from_particles(pid, ob, psys); BLI_addtail(lb, pid); + + if(psys->soft) { + pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); + BKE_ptcache_id_from_softbody(pid, ob, psys->soft); + BLI_addtail(lb, pid); + } } } @@ -1087,7 +1091,7 @@ static void ptcache_file_init_pointers(PTCacheFile *pf) pf->cur[BPHYS_DATA_BOIDS] = data_types & (1<data.boids : NULL; } -static void ptcache_mem_init_pointers(PTCacheMem *pm) +void BKE_ptcache_mem_init_pointers(PTCacheMem *pm) { int data_types = pm->data_types; int i; @@ -1096,7 +1100,7 @@ static void ptcache_mem_init_pointers(PTCacheMem *pm) pm->cur[i] = data_types & (1<data[i] : NULL; } -static void ptcache_mem_incr_pointers(PTCacheMem *pm) +void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm) { int i; @@ -1249,12 +1253,12 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec) return 0; if(pm) { - ptcache_mem_init_pointers(pm); + BKE_ptcache_mem_init_pointers(pm); totpoint = pm->totpoint; index = pm->data_types & (1<cur[BPHYS_DATA_INDEX] : &i; } if(pm2) { - ptcache_mem_init_pointers(pm2); + BKE_ptcache_mem_init_pointers(pm2); totpoint2 = pm2->totpoint; index2 = pm2->data_types & (1<cur[BPHYS_DATA_INDEX] : &i; } @@ -1336,7 +1340,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec) } if(pm) { - ptcache_mem_incr_pointers(pm); + BKE_ptcache_mem_incr_pointers(pm); index = pm->data_types & (1<cur[BPHYS_DATA_INDEX] : &i; } } @@ -1387,7 +1391,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec) } if(pm2) { - ptcache_mem_incr_pointers(pm2); + BKE_ptcache_mem_incr_pointers(pm2); index2 = pm2->data_types & (1<cur[BPHYS_DATA_INDEX] : &i; } } @@ -1559,11 +1563,11 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra) pm->data_types = cfra ? pid->data_types : pid->info_types; ptcache_alloc_data(pm); - ptcache_mem_init_pointers(pm); + BKE_ptcache_mem_init_pointers(pm); for(i=0; iwrite_elem && pid->write_elem(i, pid->calldata, pm->cur)) - ptcache_mem_incr_pointers(pm); + BKE_ptcache_mem_incr_pointers(pm); } //ptcache_make_index_array(pm, pid->totpoint(pid->calldata)); @@ -1664,6 +1668,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra) PTCacheMem *pm= pid->cache->mem_cache.first; PTCacheMem *link= NULL; + pm= pid->cache->mem_cache.first; + if(mode == PTCACHE_CLEAR_ALL) { pid->cache->last_exact = 0; for(; pm; pm=pm->next) @@ -1863,7 +1869,7 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode) else if(psys->recalc & PSYS_RECALC_REDO || psys->recalc & PSYS_RECALC_CHILD) skip = 1; - if(skip == 0) { + if(skip == 0 && psys->part) { BKE_ptcache_id_from_particles(&pid, ob, psys); reset |= BKE_ptcache_id_reset(scene, &pid, mode); } @@ -1968,9 +1974,9 @@ PointCache *BKE_ptcache_add(ListBase *ptcaches) return cache; } -void BKE_ptache_free_mem(PointCache *cache) +void BKE_ptcache_free_mem(ListBase *mem_cache) { - PTCacheMem *pm = cache->mem_cache.first; + PTCacheMem *pm = mem_cache->first; if(pm) { for(; pm; pm=pm->next) { @@ -1979,22 +1985,25 @@ void BKE_ptache_free_mem(PointCache *cache) MEM_freeN(pm->index_array); } - BLI_freelistN(&cache->mem_cache); + BLI_freelistN(mem_cache); } } void BKE_ptcache_free(PointCache *cache) { - BKE_ptache_free_mem(cache); + BKE_ptcache_free_mem(&cache->mem_cache); + if(cache->edit && cache->free_edit) + cache->free_edit(cache->edit); MEM_freeN(cache); } void BKE_ptcache_free_list(ListBase *ptcaches) { PointCache *cache = ptcaches->first; - for(; cache; cache=cache->next) - BKE_ptache_free_mem(cache); - - BLI_freelistN(ptcaches); + while(cache) { + BLI_remlink(ptcaches, cache); + BKE_ptcache_free(cache); + cache = ptcaches->first; + } } static PointCache *ptcache_copy(PointCache *cache) @@ -2258,7 +2267,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid) pm->frame = cfra; ptcache_alloc_data(pm); - ptcache_mem_init_pointers(pm); + BKE_ptcache_mem_init_pointers(pm); ptcache_file_init_pointers(pf); for(i=0; itotpoint; i++) { @@ -2274,7 +2283,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid) return; } ptcache_copy_data(pf->cur, pm->cur); - ptcache_mem_incr_pointers(pm); + BKE_ptcache_mem_incr_pointers(pm); } //ptcache_make_index_array(pm, pid->totpoint(pid->calldata)); @@ -2305,7 +2314,7 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid) pf->totpoint = pm->totpoint; pf->type = pid->type; - ptcache_mem_init_pointers(pm); + BKE_ptcache_mem_init_pointers(pm); ptcache_file_init_pointers(pf); if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) { @@ -2325,7 +2334,7 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid) ptcache_file_close(pf); return; } - ptcache_mem_incr_pointers(pm); + BKE_ptcache_mem_incr_pointers(pm); } ptcache_file_close(pf); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 63dabf18faa..10f6a8cf47c 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -404,11 +404,13 @@ Scene *add_scene(char *name) sce->unit.scale_length = 1.0f; pset= &sce->toolsettings->particle; - pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER; + pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER|PE_AUTO_VELOCITY; pset->emitterdist= 0.25f; pset->totrekey= 5; pset->totaddkey= 5; pset->brushtype= PE_BRUSH_NONE; + pset->draw_step= 2; + pset->fade_frames= 2; for(a=0; abrush[a].strength= 50; pset->brush[a].size= 50; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9d5ae3062a1..070c873686c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2963,8 +2963,10 @@ static void direct_link_pointcache(FileData *fd, PointCache *cache) else cache->mem_cache.first = cache->mem_cache.last = NULL; - cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE); + cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; + cache->edit= NULL; + cache->free_edit= NULL; } static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache) @@ -3137,7 +3139,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) link_list(fd, &psys->targets); - psys->edit = 0; + psys->edit = NULL; psys->free_edit = NULL; psys->pathcache = 0; psys->childcache = 0; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 26fd0cf6af6..88c6f205d15 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1208,7 +1208,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "PartDeflect", 1, ob->pd); writestruct(wd, DATA, "SoftBody", 1, ob->soft); - if(ob->soft) writestruct(wd, DATA, "PointCache", 1, ob->soft->pointcache); + if(ob->soft) write_pointcaches(wd, &ob->soft->ptcaches); writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft); write_particlesystems(wd, &ob->particlesystem); diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index 43cb5053f48..dcac51928a3 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -39,18 +39,16 @@ struct rcti; struct wmWindowManager; /* particle edit mode */ -void PE_change_act(void *ob_v, void *act_v); -void PE_change_act_psys(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys); -int PE_can_edit(struct ParticleSystem *psys); +void PE_free_ptcache_edit(struct PTCacheEdit *edit); +int PE_start_edit(struct PTCacheEdit *edit); /* access */ -struct ParticleSystem *PE_get_current(struct Scene *scene, struct Object *ob); -short PE_get_current_num(struct Object *ob); +struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob); int PE_minmax(struct Scene *scene, float *min, float *max); struct ParticleEditSettings *PE_settings(Scene *scene); /* update calls */ -void PE_hide_keys_time(struct Scene *scene, struct ParticleSystem *psys, float cfra); +void PE_hide_keys_time(struct Scene *scene, struct PTCacheEdit *edit, float cfra); void PE_update_object(struct Scene *scene, struct Object *ob, int useflag); /* selection tools */ diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 17838d6042c..c3f1637d3af 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -743,78 +743,6 @@ static void edge_drawflags(Mesh *me, EditMesh *em) } } -static int editmesh_pointcache_edit(Scene *scene, Object *ob, int totvert, PTCacheID *pid_p, float mat[][4], int load) -{ - Cloth *cloth; - SoftBody *sb; - ClothModifierData *clmd; - PTCacheID pid, tmpid; - int cfra= (int)scene->r.cfra, found= 0; - - pid.cache= NULL; - - /* check for cloth */ - if(modifiers_isClothEnabled(ob)) { - clmd= (ClothModifierData*)modifiers_findByType(ob, eModifierType_Cloth); - cloth= clmd->clothObject; - - BKE_ptcache_id_from_cloth(&tmpid, ob, clmd); - - /* verify vertex count and baked status */ - if(cloth && (totvert == cloth->numverts)) { - if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) { - pid= tmpid; - - if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)) - found= 1; - } - } - } - - /* check for softbody */ - if(!found && ob->soft) { - sb= ob->soft; - - BKE_ptcache_id_from_softbody(&tmpid, ob, sb); - - /* verify vertex count and baked status */ - if(sb->bpoint && (totvert == sb->totpoint)) { - if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) { - pid= tmpid; - - if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)) - found= 1; - } - } - } - - /* if not making editmesh verify editing was active for this point cache */ - if(load) { - if(found) - pid.cache->flag &= ~PTCACHE_BAKE_EDIT_ACTIVE; - else - return 0; - } - - /* check if we have cache for this frame */ - if(pid.cache && BKE_ptcache_id_exist(&pid, cfra)) { - *pid_p = pid; - - if(load) { - Mat4CpyMat4(mat, ob->obmat); - } - else { - pid.cache->editframe= cfra; - pid.cache->flag |= PTCACHE_BAKE_EDIT_ACTIVE; - Mat4Invert(mat, ob->obmat); /* ob->imat is not up to date */ - } - - return 1; - } - - return 0; -} - /* turns Mesh into editmesh */ void make_editMesh(Scene *scene, Object *ob) { @@ -828,11 +756,8 @@ void make_editMesh(Scene *scene, Object *ob) EditFace *efa; EditEdge *eed; EditSelection *ese; - PTCacheID pid; - Cloth *cloth; - SoftBody *sb; - float cacheco[3], cachemat[4][4], *co; - int tot, a, cacheedit= 0, eekadoodle= 0; + float *co; + int tot, a, eekadoodle= 0; if(me->edit_mesh==NULL) me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh"); @@ -867,26 +792,10 @@ void make_editMesh(Scene *scene, Object *ob) CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); mvert= me->mvert; - cacheedit= editmesh_pointcache_edit(scene, ob, tot, &pid, cachemat, 0); - evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist"); for(a=0; aclothObject; - VECCOPY(cacheco, cloth->verts[a].x) - } - else if(pid.type == PTCACHE_TYPE_SOFTBODY) { - sb= (SoftBody*)pid.calldata; - VECCOPY(cacheco, sb->bpoint[a].pos) - } - - Mat4MulVecfl(cachemat, cacheco); - co= cacheco; - } - else - co= mvert->co; + co= mvert->co; eve= addvertlist(em, co, NULL); evlist[a]= eve; @@ -1011,11 +920,6 @@ void make_editMesh(Scene *scene, Object *ob) if (EM_get_actFace(em, 0)==NULL) { EM_set_actFace(em, em->faces.first ); /* will use the first face, this is so we alwats have an active face */ } - - /* vertex coordinates change with cache edit, need to recalc */ - if(cacheedit) - recalc_editnormals(em); - } /* makes Mesh out of editmesh */ @@ -1031,12 +935,8 @@ void load_editMesh(Scene *scene, Object *ob) EditFace *efa, *efa_act; EditEdge *eed; EditSelection *ese; - SoftBody *sb; - Cloth *cloth; - ClothModifierData *clmd; - PTCacheID pid; - float *fp, *newkey, *oldkey, nor[3], cacheco[3], cachemat[4][4]; - int i, a, ototvert, cacheedit= 0; + float *fp, *newkey, *oldkey, nor[3]; + int i, a, ototvert; /* this one also tests of edges are not in faces: */ /* eed->f2==0: not in face, f2==1: draw it */ @@ -1090,48 +990,8 @@ void load_editMesh(Scene *scene, Object *ob) eve= em->verts.first; a= 0; - /* check for point cache editing */ - cacheedit= editmesh_pointcache_edit(scene, ob, em->totvert, &pid, cachemat, 1); - while(eve) { - if(cacheedit) { - if(pid.type == PTCACHE_TYPE_CLOTH) { - clmd= (ClothModifierData*)pid.calldata; - cloth= clmd->clothObject; - - /* assign position */ - VECCOPY(cacheco, cloth->verts[a].x) - VECCOPY(cloth->verts[a].x, eve->co); - Mat4MulVecfl(cachemat, cloth->verts[a].x); - - /* find plausible velocity, not physical correct but gives - * nicer results when commented */ - VECSUB(cacheco, cloth->verts[a].x, cacheco); - VecMulf(cacheco, clmd->sim_parms->stepsPerFrame*10.0f); - VECADD(cloth->verts[a].v, cloth->verts[a].v, cacheco); - } - else if(pid.type == PTCACHE_TYPE_SOFTBODY) { - sb= (SoftBody*)pid.calldata; - - /* assign position */ - VECCOPY(cacheco, sb->bpoint[a].pos) - VECCOPY(sb->bpoint[a].pos, eve->co); - Mat4MulVecfl(cachemat, sb->bpoint[a].pos); - - /* changing velocity for softbody doesn't seem to give - * good results? */ -#if 0 - VECSUB(cacheco, sb->bpoint[a].pos, cacheco); - VecMulf(cacheco, sb->minloops*10.0f); - VECADD(sb->bpoint[a].vec, sb->bpoint[a].pos, cacheco); -#endif - } - - if(oldverts) - VECCOPY(mvert->co, oldverts[a].co) - } - else - VECCOPY(mvert->co, eve->co); + VECCOPY(mvert->co, eve->co); mvert->mat_nr= 32767; /* what was this for, halos? */ @@ -1155,10 +1015,6 @@ void load_editMesh(Scene *scene, Object *ob) eve= eve->next; mvert++; } - - /* write changes to cache */ - if(cacheedit) - BKE_ptcache_write_cache(&pid, pid.cache->editframe); /* the edges */ a= 0; diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c index 917e2b40d72..68e0c28e9c1 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/ed_pointcache.c @@ -46,6 +46,7 @@ #include "ED_screen.h" #include "ED_physics.h" +#include "ED_particle.h" #include "UI_interface.h" #include "UI_resources.h" @@ -184,8 +185,16 @@ static int ptcache_free_bake_exec(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache); PointCache *cache= ptr.data; - - cache->flag &= ~PTCACHE_BAKED; + + if(cache->edit) { + if(!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) { + PE_free_ptcache_edit(cache->edit); + cache->edit = NULL; + cache->flag &= ~PTCACHE_BAKED; + } + } + else + cache->flag &= ~PTCACHE_BAKED; return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index b92632b45af..dbb11f72890 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -57,7 +57,8 @@ #include "BKE_particle.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_utildefines.h" +#include "BKE_utildefines.h" +#include "BKE_pointcache.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -85,11 +86,25 @@ #include "physics_intern.h" -static void PE_create_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys); -static void ParticleUndo_clear(ParticleSystem *psys); +static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys); +static void PTCacheUndo_clear(PTCacheEdit *edit); -#define LOOP_PARTICLES(i, pa) for(i=0, pa=psys->particles; iedit)for(k=0, key=psys->edit->keys[i]; ktotkey; k++, key++) +#define KEY_K PTCacheEditKey *key; int k +#define POINT_P PTCacheEditPoint *point; int p +#define LOOP_POINTS for(p=0, point=edit->points; ptotpoint; p++, point++) +#define LOOP_VISIBLE_POINTS for(p=0, point=edit->points; ptotpoint; p++, point++) if(!(point->flag & PEP_HIDE)) +#define LOOP_SELECTED_POINTS for(p=0, point=edit->points; ptotpoint; p++, point++) if(point_is_selected(point)) +#define LOOP_UNSELECTED_POINTS for(p=0, point=edit->points; ptotpoint; p++, point++) if(!point_is_selected(point)) +#define LOOP_EDITED_POINTS for(p=0, point=edit->points; ptotpoint; p++, point++) if(point->flag & PEP_EDIT_RECALC) +#define LOOP_TAGGED_POINTS for(p=0, point=edit->points; ptotpoint; p++, point++) if(point->flag & PEP_TAG) +#define LOOP_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) +#define LOOP_VISIBLE_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if(!(key->flag & PEK_HIDE)) +#define LOOP_SELECTED_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE)) +#define LOOP_TAGGED_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if(key->flag & PEK_TAG) + +#define LOOP_PARTICLES(i, pa) for(i=0, pa=psys->particles; itotpart; i++, pa++) + +#define KEY_WCO (key->flag & PEK_USE_WCO ? key->world_co : key->co) /**************************** utilities *******************************/ @@ -97,14 +112,14 @@ static int PE_poll(bContext *C) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys; + PTCacheEdit *edit; if(!scene || !ob) return 0; - psys= PE_get_current(scene, ob); + edit= PE_get_current(scene, ob); - return (psys && psys->edit && (ob && ob->mode & OB_MODE_PARTICLE_EDIT)); + return (edit && (ob->mode & OB_MODE_PARTICLE_EDIT)); } static int PE_poll_3dview(bContext *C) @@ -113,22 +128,21 @@ static int PE_poll_3dview(bContext *C) CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW; } -static void PE_free_particle_edit(ParticleSystem *psys) +void PE_free_ptcache_edit(PTCacheEdit *edit) { - ParticleEdit *edit= psys->edit; - int i, totpart= psys->totpart; + POINT_P; if(edit==0) return; - ParticleUndo_clear(psys); + PTCacheUndo_clear(edit); - if(edit->keys) { - for(i=0; ikeys[i]) - MEM_freeN(edit->keys[i]); + if(edit->points) { + LOOP_POINTS { + if(point->keys) + MEM_freeN(point->keys); } - MEM_freeN(edit->keys); + MEM_freeN(edit->points); } if(edit->mirror_cache) @@ -144,19 +158,23 @@ static void PE_free_particle_edit(ParticleSystem *psys) edit->emitter_field= 0; } - MEM_freeN(edit); + psys_free_path_cache(NULL, edit); - psys->edit= NULL; - psys->free_edit= NULL; + MEM_freeN(edit); } /************************************************/ /* Edit Mode Helpers */ /************************************************/ -int PE_can_edit(ParticleSystem *psys) +int PE_start_edit(PTCacheEdit *edit) { - return (psys && psys->edit); + if(edit) { + edit->edited = 1; + return 1; + } + + return 0; } ParticleEditSettings *PE_settings(Scene *scene) @@ -165,73 +183,99 @@ ParticleEditSettings *PE_settings(Scene *scene) } /* always gets atleast the first particlesystem even if PSYS_CURRENT flag is not set */ -ParticleSystem *PE_get_current(Scene *scene, Object *ob) +PTCacheEdit *PE_get_current(Scene *scene, Object *ob) { - ParticleSystem *psys; + ParticleEditSettings *pset= PE_settings(scene); + PTCacheEdit *edit = NULL; + ListBase pidlist; + PTCacheID *pid; + + pset->scene = scene; + pset->object = ob; if(ob==NULL) return NULL; - psys= ob->particlesystem.first; - while(psys) { - if(psys->flag & PSYS_CURRENT) - break; - psys=psys->next; - } + BKE_ptcache_ids_from_object(&pidlist, ob); - if(psys==NULL && ob->particlesystem.first) { - psys=ob->particlesystem.first; - psys->flag |= PSYS_CURRENT; + /* in the case of only one editable thing, set pset->edittype accordingly */ + if(pidlist.first == pidlist.last) { + pid = pidlist.first; + switch(pid->type) { + case PTCACHE_TYPE_PARTICLES: + pset->edittype = PE_TYPE_PARTICLES; + break; + case PTCACHE_TYPE_SOFTBODY: + pset->edittype = PE_TYPE_SOFTBODY; + break; + case PTCACHE_TYPE_CLOTH: + pset->edittype = PE_TYPE_CLOTH; + break; + } } - /* this happens when Blender is started with particle - * edit mode enabled XXX there's a draw error then? */ - if(psys && psys_check_enabled(ob, psys) && (ob == OBACT) && (ob->mode & OB_MODE_PARTICLE_EDIT)) - if(psys->part->type == PART_HAIR && psys->flag & PSYS_EDITED) - if(psys->edit == NULL) - PE_create_particle_edit(scene, ob, psys); - - return psys; -} + for(pid=pidlist.first; pid; pid=pid->next) { + if(pset->edittype == PE_TYPE_PARTICLES && pid->type == PTCACHE_TYPE_PARTICLES) { + ParticleSystem *psys = pid->calldata; -/* returns -1 if no system has PSYS_CURRENT flag */ -short PE_get_current_num(Object *ob) -{ - short num=0; - ParticleSystem *psys= ob->particlesystem.first; + if(psys->flag & PSYS_CURRENT) { + if(psys->part && psys->part->type == PART_HAIR) { + if(!psys->edit && psys->flag & PSYS_HAIR_DONE) + PE_create_particle_edit(scene, ob, NULL, psys); + edit = psys->edit; + } + else { + if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + PE_create_particle_edit(scene, ob, pid->cache, psys); + edit = pid->cache->edit; + } - while(psys) { - if(psys->flag & PSYS_CURRENT) - return num; - num++; - psys=psys->next; + break; + } + } + else if(pset->edittype == PE_TYPE_SOFTBODY && pid->type == PTCACHE_TYPE_SOFTBODY) { + if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + PE_create_particle_edit(scene, ob, pid->cache, NULL); + edit = pid->cache->edit; + break; + } + else if(pset->edittype == PE_TYPE_CLOTH && pid->type == PTCACHE_TYPE_CLOTH) { + if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + PE_create_particle_edit(scene, ob, pid->cache, NULL); + edit = pid->cache->edit; + break; + } } - return -1; + if(edit) + edit->pid = *pid; + + BLI_freelistN(&pidlist); + + return edit; } -void PE_hide_keys_time(Scene *scene, ParticleSystem *psys, float cfra) +void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra) { - ParticleData *pa; - ParticleEditKey *key; ParticleEditSettings *pset=PE_settings(scene); - int i, k, totpart= psys->totpart; + POINT_P; KEY_K; - if(pset->draw_timed && pset->selectmode==SCE_SELECT_POINT) { - LOOP_PARTICLES(i, pa) { - LOOP_KEYS(k, key) { - if(fabs(cfra-*key->time) < pset->draw_timed) + + if(pset->flag & PE_FADE_TIME && pset->selectmode==SCE_SELECT_POINT) { + LOOP_POINTS { + LOOP_KEYS { + if(fabs(cfra-*key->time) < pset->fade_frames) key->flag &= ~PEK_HIDE; else { key->flag |= PEK_HIDE; - key->flag &= ~PEK_SELECT; + //key->flag &= ~PEK_SELECT; } } } } else { - LOOP_PARTICLES(i, pa) { - LOOP_KEYS(k, key) { + LOOP_POINTS { + LOOP_KEYS { key->flag &= ~PEK_HIDE; } } @@ -247,7 +291,7 @@ typedef struct PEData { Scene *scene; Object *ob; DerivedMesh *dm; - ParticleSystem *psys; + PTCacheEdit *edit; short *mval; rcti *rect; @@ -276,7 +320,7 @@ static void PE_set_data(bContext *C, PEData *data) data->scene= CTX_data_scene(C); data->ob= CTX_data_active_object(C); - data->psys= PE_get_current(data->scene, data->ob); + data->edit= PE_get_current(data->scene, data->ob); } static void PE_set_view3d_data(bContext *C, PEData *data) @@ -388,121 +432,103 @@ static int key_inside_test(PEData *data, float co[3]) return key_inside_rect(data, co); } -static int particle_is_selected(ParticleSystem *psys, ParticleData *pa) +static int point_is_selected(PTCacheEditPoint *point) { - ParticleEditKey *key; - int sel, i, k; + KEY_K; + int sel; - if(pa->flag & PARS_HIDE) + if(point->flag & PEP_HIDE) return 0; sel= 0; - i= pa - psys->particles; - LOOP_KEYS(k, key) - if(key->flag & PEK_SELECT) - return 1; + LOOP_SELECTED_KEYS { + return 1; + } return 0; } /*************************** iterators *******************************/ -typedef void (*ForParticleFunc)(PEData *data, int pa_index); -typedef void (*ForKeyFunc)(PEData *data, int pa_index, int key_index); -typedef void (*ForKeyMatFunc)(PEData *data, float mat[][4], float imat[][4], int pa_index, int key_index); +typedef void (*ForPointFunc)(PEData *data, int point_index); +typedef void (*ForKeyFunc)(PEData *data, int point_index, int key_index); +typedef void (*ForKeyMatFunc)(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key); static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest) { - ParticleSystem *psys= data->psys; - ParticleEdit *edit= psys->edit; - ParticleData *pa; - ParticleEditKey *key; ParticleEditSettings *pset= PE_settings(data->scene); - int i, k, totpart, nearest_pa, nearest_key; + PTCacheEdit *edit= data->edit; + POINT_P; KEY_K; + int nearest_point, nearest_key; float dist= data->rad; /* in path select mode we have no keys */ if(pset->selectmode==SCE_SELECT_PATH) return; - totpart= psys->totpart; - nearest_pa= -1; + nearest_point= -1; nearest_key= -1; - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - + LOOP_VISIBLE_POINTS { if(pset->selectmode == SCE_SELECT_END) { /* only do end keys */ - key= edit->keys[i] + pa->totkey-1; + key= point->keys + point->totkey-1; if(nearest) { - if(key_inside_circle(data, dist, key->world_co, &dist)) { - nearest_pa= i; - nearest_key= pa->totkey-1; + if(key_inside_circle(data, dist, KEY_WCO, &dist)) { + nearest_point= p; + nearest_key= point->totkey-1; } } - else if(key_inside_test(data, key->world_co)) - func(data, i, pa->totkey-1); + else if(key_inside_test(data, KEY_WCO)) + func(data, p, point->totkey-1); } else { /* do all keys */ - key= edit->keys[i]; - - LOOP_KEYS(k, key) { - if(key->flag & PEK_HIDE) continue; - + LOOP_VISIBLE_KEYS { if(nearest) { - if(key_inside_circle(data, dist, key->world_co, &dist)) { - nearest_pa= i; + if(key_inside_circle(data, dist, KEY_WCO, &dist)) { + nearest_point= p; nearest_key= k; } } - else if(key_inside_test(data, key->world_co)) - func(data, i, k); + else if(key_inside_test(data, KEY_WCO)) + func(data, p, k); } } } /* do nearest only */ - if(nearest && nearest_pa > -1) - func(data, nearest_pa, nearest_key); + if(nearest && nearest_point > -1) + func(data, nearest_point, nearest_key); } -static void foreach_mouse_hit_particle(PEData *data, ForParticleFunc func, int selected) +static void foreach_mouse_hit_point(PEData *data, ForPointFunc func, int selected) { - ParticleSystem *psys= data->psys; - ParticleData *pa; - ParticleEditKey *key; ParticleEditSettings *pset= PE_settings(data->scene); - int i, k, totpart; - - totpart= psys->totpart; + PTCacheEdit *edit= data->edit; + POINT_P; KEY_K; /* all is selected in path mode */ if(pset->selectmode==SCE_SELECT_PATH) selected=0; - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - + LOOP_VISIBLE_POINTS { if(pset->selectmode==SCE_SELECT_END) { /* only do end keys */ - key= psys->edit->keys[i] + pa->totkey-1; + key= point->keys + point->totkey - 1; if(selected==0 || key->flag & PEK_SELECT) - if(key_inside_circle(data, data->rad, key->world_co, &data->dist)) - func(data, i); + if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) + func(data, p); } else { /* do all keys */ - LOOP_KEYS(k, key) { - if(key->flag & PEK_HIDE) continue; - + LOOP_VISIBLE_KEYS { if(selected==0 || key->flag & PEK_SELECT) { - if(key_inside_circle(data, data->rad, key->world_co, &data->dist)) { - func(data, i); + if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) { + func(data, p); break; } } @@ -513,16 +539,15 @@ static void foreach_mouse_hit_particle(PEData *data, ForParticleFunc func, int s static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected) { - ParticleSystem *psys= data->psys; - ParticleData *pa; - ParticleEditKey *key; - ParticleSystemModifierData *psmd=0; + PTCacheEdit *edit = data->edit; + ParticleSystem *psys = edit->psys; + ParticleSystemModifierData *psmd = NULL; ParticleEditSettings *pset= PE_settings(data->scene); - int i, k, totpart; + POINT_P; KEY_K; float mat[4][4], imat[4][4]; - psmd= psys_get_modifier(data->ob,psys); - totpart= psys->totpart; + if(edit->psys) + psmd= psys_get_modifier(data->ob, edit->psys); /* all is selected in path mode */ if(pset->selectmode==SCE_SELECT_PATH) @@ -531,99 +556,77 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected Mat4One(imat); Mat4One(mat); - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - - psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, pa, mat); - Mat4Invert(imat,mat); + LOOP_VISIBLE_POINTS { + if(edit->psys) { + psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat); + Mat4Invert(imat,mat); + } if(pset->selectmode==SCE_SELECT_END) { /* only do end keys */ - key= psys->edit->keys[i] + pa->totkey-1; + key= point->keys + point->totkey-1; if(selected==0 || key->flag & PEK_SELECT) - if(key_inside_circle(data, data->rad, key->world_co, &data->dist)) - func(data, mat, imat, i, pa->totkey-1); + if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) + func(data, mat, imat, p, point->totkey-1, key); } else { /* do all keys */ - LOOP_KEYS(k, key) { - if(key->flag&PEK_HIDE) continue; - + LOOP_VISIBLE_KEYS { if(selected==0 || key->flag & PEK_SELECT) - if(key_inside_circle(data, data->rad, key->world_co, &data->dist)) - func(data, mat, imat, i, k); + if(key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) + func(data, mat, imat, p, k, key); } } } } -static void foreach_selected_particle(PEData *data, ForParticleFunc func) +static void foreach_selected_point(PEData *data, ForPointFunc func) { - ParticleSystem *psys= data->psys; - ParticleData *pa; - int i, totpart; - - totpart= psys->totpart; + PTCacheEdit *edit = data->edit; + POINT_P; - LOOP_PARTICLES(i, pa) - if(particle_is_selected(psys, pa)) - func(data, i); + LOOP_SELECTED_POINTS { + func(data, p); + } } static void foreach_selected_key(PEData *data, ForKeyFunc func) { - ParticleSystem *psys= data->psys; - ParticleData *pa; - ParticleEditKey *key; - int i, k, totpart; - - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - - key= psys->edit->keys[i]; + PTCacheEdit *edit = data->edit; + POINT_P; KEY_K; - LOOP_KEYS(k, key) - if(key->flag & PEK_SELECT) - func(data, i, k); + LOOP_VISIBLE_POINTS { + LOOP_SELECTED_KEYS { + func(data, p, k); + } } } -void PE_foreach_particle(PEData *data, ForParticleFunc func) +static void foreach_point(PEData *data, ForPointFunc func) { - ParticleSystem *psys= data->psys; - int i, totpart; + PTCacheEdit *edit = data->edit; + POINT_P; - totpart= psys->totpart; - - for(i=0; itotpart; - - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - - key= psys->edit->keys[i]; + POINT_P; KEY_K; + int sel= 0; + LOOP_VISIBLE_POINTS { if(pset->selectmode==SCE_SELECT_POINT) { - for(k=0; ktotkey; k++,key++) - if(key->flag & PEK_SELECT) - sel++; + LOOP_SELECTED_KEYS { + sel++; + } } else if(pset->selectmode==SCE_SELECT_END) { - key += pa->totkey-1; - + key = point->keys + point->totkey - 1; if(key->flag & PEK_SELECT) sel++; } @@ -638,7 +641,7 @@ static int count_selected_keys(Scene *scene, ParticleSystem *psys) static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) { - ParticleEdit *edit; + PTCacheEdit *edit; ParticleData *pa; ParticleSystemModifierData *psmd; KDTree *tree; @@ -696,8 +699,9 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa) { HairKey *hkey, *mhkey; - ParticleEditKey *key, *mkey; - ParticleEdit *edit; + PTCacheEditPoint *point, *mpoint; + PTCacheEditKey *key, *mkey; + PTCacheEdit *edit; float mat[4][4], mmat[4][4], immat[4][4]; int i, mi, k; @@ -717,17 +721,20 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys else mi= mpa - psys->particles; + point = edit->points + i; + mpoint = edit->points + mi; + /* make sure they have the same amount of keys */ if(pa->totkey != mpa->totkey) { if(mpa->hair) MEM_freeN(mpa->hair); - if(edit->keys[mi]) MEM_freeN(edit->keys[mi]); + if(mpoint->keys) MEM_freeN(mpoint->keys); mpa->hair= MEM_dupallocN(pa->hair); - edit->keys[mi]= MEM_dupallocN(edit->keys[i]); - mpa->totkey= pa->totkey; + mpoint->keys= MEM_dupallocN(point->keys); + mpoint->totkey= point->totkey; mhkey= mpa->hair; - mkey= edit->keys[mi]; + mkey= mpoint->keys; for(k=0; ktotkey; k++, mkey++, mhkey++) { mkey->co= mhkey->co; mkey->time= &mhkey->time; @@ -742,8 +749,8 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys hkey=pa->hair; mhkey=mpa->hair; - key= edit->keys[i]; - mkey= edit->keys[mi]; + key= point->keys; + mkey= mpoint->keys; for(k=0; ktotkey; k++, hkey++, mhkey++, key++, mkey++) { VECCOPY(mhkey->co, hkey->co); Mat4MulVecfl(mat, mhkey->co); @@ -754,199 +761,172 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys mkey->flag |= PEK_TAG; } - if(pa->flag & PARS_TAG) - mpa->flag |= PARS_TAG; - if(pa->flag & PARS_EDIT_RECALC) - mpa->flag |= PARS_EDIT_RECALC; + if(point->flag & PEP_TAG) + mpoint->flag |= PEP_TAG; + if(point->flag & PEP_EDIT_RECALC) + mpoint->flag |= PEP_EDIT_RECALC; } static void PE_apply_mirror(Object *ob, ParticleSystem *psys) { - ParticleEdit *edit; - ParticleData *pa; + PTCacheEdit *edit; ParticleSystemModifierData *psmd; - int i, totpart; + POINT_P; + + if(!psys) + return; edit= psys->edit; psmd= psys_get_modifier(ob, psys); - totpart= psys->totpart; /* we delay settings the PARS_EDIT_RECALC for mirrored particles * to avoid doing mirror twice */ - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_EDIT_RECALC) { - PE_mirror_particle(ob, psmd->dm, psys, pa, NULL); + LOOP_POINTS { + if(point->flag & PEP_EDIT_RECALC) { + PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL); - if(edit->mirror_cache[i] != -1) - psys->particles[edit->mirror_cache[i]].flag &= ~PARS_EDIT_RECALC; + if(edit->mirror_cache[p] != -1) + edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; } } - LOOP_PARTICLES(i, pa) - if(pa->flag & PARS_EDIT_RECALC) - if(edit->mirror_cache[i] != -1) - psys->particles[edit->mirror_cache[i]].flag |= PARS_EDIT_RECALC; - - edit->totkeys= psys_count_keys(psys); + LOOP_POINTS { + if(point->flag & PEP_EDIT_RECALC) + if(edit->mirror_cache[p] != -1) + edit->points[edit->mirror_cache[p]].flag |= PEP_EDIT_RECALC; + } } /************************************************/ /* Edit Calculation */ /************************************************/ /* tries to stop edited particles from going through the emitter's surface */ -static void pe_deflect_emitter(Scene *scene, Object *ob, ParticleSystem *psys) +static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) { - ParticleEdit *edit; - ParticleData *pa; - ParticleEditKey *key; ParticleEditSettings *pset= PE_settings(scene); - ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys); - int i, k, totpart,index; + ParticleSystem *psys; + ParticleSystemModifierData *psmd; + POINT_P; KEY_K; + int index; float *vec, *nor, dvec[3], dot, dist_1st; float hairimat[4][4], hairmat[4][4]; - if(psys==0) + if(edit==NULL || edit->psys==NULL || (pset->flag & PE_DEFLECT_EMITTER)==0) return; - if((pset->flag & PE_DEFLECT_EMITTER)==0) - return; + psys = edit->psys; + psmd = psys_get_modifier(ob,psys); - edit= psys->edit; - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(!(pa->flag & PARS_EDIT_RECALC)) - continue; - - psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat); - - LOOP_KEYS(k, key) { + LOOP_EDITED_POINTS { + psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles + p, hairmat); + + LOOP_KEYS { Mat4MulVecfl(hairmat, key->co); } - //} - - //LOOP_PARTICLES(i, pa) { - key=psys->edit->keys[i]+1; - - dist_1st=VecLenf((key-1)->co,key->co); - dist_1st*=0.75f*pset->emitterdist; - for(k=1; ktotkey; k++, key++) { - index= BLI_kdtree_find_nearest(edit->emitter_field,key->co,NULL,NULL); - - vec=edit->emitter_cosnos +index*6; - nor=vec+3; + LOOP_KEYS { + if(k==0) { + dist_1st = VecLenf((key+1)->co, key->co); + dist_1st *= 0.75f * pset->emitterdist; + } + else { + index= BLI_kdtree_find_nearest(edit->emitter_field,key->co,NULL,NULL); + + vec=edit->emitter_cosnos +index*6; + nor=vec+3; - VecSubf(dvec, key->co, vec); + VecSubf(dvec, key->co, vec); - dot=Inpf(dvec,nor); - VECCOPY(dvec,nor); + dot=Inpf(dvec,nor); + VECCOPY(dvec,nor); - if(dot>0.0f) { - if(dot0.0f) { + if(dotco,key->co,dvec); + } + } + else { Normalize(dvec); VecMulf(dvec,dist_1st-dot); VecAddf(key->co,key->co,dvec); } + if(k==1) + dist_1st*=1.3333f; } - else { - Normalize(dvec); - VecMulf(dvec,dist_1st-dot); - VecAddf(key->co,key->co,dvec); - } - if(k==1) - dist_1st*=1.3333f; } - //} - - //LOOP_PARTICLES(i, pa) { Mat4Invert(hairimat,hairmat); - LOOP_KEYS(k, key) { + LOOP_KEYS { Mat4MulVecfl(hairimat, key->co); } } } /* force set distances between neighbouring keys */ -void PE_apply_lengths(Scene *scene, ParticleSystem *psys) +void PE_apply_lengths(Scene *scene, PTCacheEdit *edit) { - ParticleEdit *edit; - ParticleData *pa; - ParticleEditKey *key; + ParticleEditSettings *pset=PE_settings(scene); - int i, k, totpart; + POINT_P; KEY_K; float dv1[3]; - if(psys==0) - return; - - if((pset->flag & PE_KEEP_LENGTHS)==0) + if(edit==0 || (pset->flag & PE_KEEP_LENGTHS)==0) return; - edit= psys->edit; - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(!(pa->flag & PARS_EDIT_RECALC)) - continue; - - for(k=1, key=edit->keys[i] + 1; ktotkey; k++, key++) { - VecSubf(dv1, key->co, (key - 1)->co); - Normalize(dv1); - VecMulf(dv1, (key - 1)->length); - VecAddf(key->co, (key - 1)->co, dv1); + LOOP_EDITED_POINTS { + LOOP_KEYS { + if(k) { + VecSubf(dv1, key->co, (key - 1)->co); + Normalize(dv1); + VecMulf(dv1, (key - 1)->length); + VecAddf(key->co, (key - 1)->co, dv1); + } } } } /* try to find a nice solution to keep distances between neighbouring keys */ -static void pe_iterate_lengths(Scene *scene, ParticleSystem *psys) +static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit) { - ParticleEdit *edit; - ParticleData *pa; - ParticleEditKey *key; ParticleEditSettings *pset=PE_settings(scene); - int i, j, k, totpart; + POINT_P; + PTCacheEditKey *key; + int j, k; float tlen; float dv0[3]= {0.0f, 0.0f, 0.0f}; float dv1[3]= {0.0f, 0.0f, 0.0f}; float dv2[3]= {0.0f, 0.0f, 0.0f}; - if(psys==0) + if(edit==0) return; if((pset->flag & PE_KEEP_LENGTHS)==0) return; - edit= psys->edit; - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(!(pa->flag & PARS_EDIT_RECALC)) - continue; - - for(j=1; jtotkey; j++) { - float mul= 1.0f / (float)pa->totkey; + LOOP_EDITED_POINTS { + for(j=1; jtotkey; j++) { + float mul= 1.0f / (float)point->totkey; if(pset->flag & PE_LOCK_FIRST) { - key= edit->keys[i] + 1; + key= point->keys + 1; k= 1; dv1[0]= dv1[1]= dv1[2]= 0.0; } else { - key= edit->keys[i]; + key= point->keys; k= 0; dv0[0]= dv0[1]= dv0[2]= 0.0; } - for(; ktotkey; k++, key++) { + for(; ktotkey; k++, key++) { if(k) { VecSubf(dv0, (key - 1)->co, key->co); tlen= Normalize(dv0); VecMulf(dv0, (mul * (tlen - (key - 1)->length))); } - if(k < pa->totkey - 1) { + if(k < point->totkey - 1) { VecSubf(dv2, (key + 1)->co, key->co); tlen= Normalize(dv2); VecMulf(dv2, mul * (tlen - key->length)); @@ -962,20 +942,16 @@ static void pe_iterate_lengths(Scene *scene, ParticleSystem *psys) } } /* set current distances to be kept between neighbouting keys */ -static void recalc_lengths(ParticleSystem *psys) +static void recalc_lengths(PTCacheEdit *edit) { - ParticleData *pa; - ParticleEditKey *key; - int i, k, totpart; + POINT_P; KEY_K; - if(psys==0) + if(edit==0) return; - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - key= psys->edit->keys[i]; - for(k=0; ktotkey-1; k++, key++) { + LOOP_EDITED_POINTS { + key= point->keys; + for(k=0; ktotkey-1; k++, key++) { key->length= VecLenf(key->co, (key + 1)->co); } } @@ -985,7 +961,7 @@ static void recalc_lengths(ParticleSystem *psys) static void recalc_emitter_field(Object *ob, ParticleSystem *psys) { DerivedMesh *dm=psys_get_modifier(ob,psys)->dm; - ParticleEdit *edit= psys->edit; + PTCacheEdit *edit= psys->edit; MFace *mface; MVert *mvert; float *vec, *nor; @@ -1042,74 +1018,145 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys) static void PE_update_selection(Scene *scene, Object *ob, int useflag) { - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit= psys->edit; ParticleEditSettings *pset= PE_settings(scene); - ParticleSettings *part= psys->part; - ParticleData *pa; + PTCacheEdit *edit= PE_get_current(scene, ob); HairKey *hkey; - ParticleEditKey *key; - float cfra= CFRA; - int i, k, totpart; - - totpart= psys->totpart; + POINT_P; KEY_K; /* flag all particles to be updated if not using flag */ if(!useflag) - LOOP_PARTICLES(i, pa) - pa->flag |= PARS_EDIT_RECALC; + LOOP_POINTS + point->flag |= PEP_EDIT_RECALC; /* flush edit key flag to hair key flag to preserve selection * on save */ - LOOP_PARTICLES(i, pa) { - key= edit->keys[i]; - - for(k=0, hkey=pa->hair; ktotkey; k++, hkey++, key++) + if(edit->psys) LOOP_POINTS { + hkey = edit->psys->particles[p].hair; + LOOP_KEYS { hkey->editflag= key->flag; + hkey++; + } } - psys_cache_paths(scene, ob, psys, CFRA, 1); + psys_cache_edit_paths(scene, ob, edit, CFRA); - if(part->childtype && (pset->flag & PE_SHOW_CHILD)) - psys_cache_child_paths(scene, ob, psys, cfra, 1); /* disable update flag */ - LOOP_PARTICLES(i, pa) - pa->flag &= ~PARS_EDIT_RECALC; + LOOP_POINTS + point->flag &= ~PEP_EDIT_RECALC; } +static void update_world_cos(Object *ob, PTCacheEdit *edit) +{ + ParticleSystem *psys = edit->psys; + ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); + POINT_P; KEY_K; + float hairmat[4][4]; + + if(psys==0 || psys->edit==0) + return; + + LOOP_POINTS { + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, hairmat); + + LOOP_KEYS { + VECCOPY(key->world_co,key->co); + Mat4MulVecfl(hairmat, key->world_co); + } + } +} +static void update_velocities(Object *ob, PTCacheEdit *edit) +{ + /*TODO: get frs_sec properly */ + float vec1[3], vec2[3], frs_sec, dfra; + POINT_P; KEY_K; + + /* hair doesn't use velocities */ + if(edit->psys || !edit->points || !edit->points->keys->vel) + return; + + frs_sec = edit->pid.flag & PTCACHE_VEL_PER_SEC ? 25.0f : 1.0f; + + LOOP_EDITED_POINTS { + LOOP_KEYS { + if(k==0) { + dfra = *(key+1)->time - *key->time; + + if(dfra <= 0.0f) + continue; + + VECSUB(key->vel, (key+1)->co, key->co); + + if(point->totkey>2) { + VECSUB(vec1, (key+1)->co, (key+2)->co); + Projf(vec2, vec1, key->vel); + VECSUB(vec2, vec1, vec2); + VECADDFAC(key->vel, key->vel, vec2, 0.5f); + } + } + else if(k==point->totkey-1) { + dfra = *key->time - *(key-1)->time; + + if(dfra <= 0.0f) + continue; + + VECSUB(key->vel, key->co, (key-1)->co); + + if(point->totkey>2) { + VECSUB(vec1, (key-2)->co, (key-1)->co); + Projf(vec2, vec1, key->vel); + VECSUB(vec2, vec1, vec2); + VECADDFAC(key->vel, key->vel, vec2, 0.5f); + } + } + else { + dfra = *(key+1)->time - *(key-1)->time; + + if(dfra <= 0.0f) + continue; + + VECSUB(key->vel, (key+1)->co, (key-1)->co); + } + VecMulf(key->vel, frs_sec/dfra); + } + } +} void PE_update_object(Scene *scene, Object *ob, int useflag) { - ParticleSystem *psys= PE_get_current(scene, ob); ParticleEditSettings *pset= PE_settings(scene); - ParticleSettings *part= psys->part; - ParticleData *pa; - float cfra= CFRA; - int i, totpart= psys->totpart; + PTCacheEdit *edit = PE_get_current(scene, ob); + POINT_P; + + if(!edit) + return; /* flag all particles to be updated if not using flag */ if(!useflag) - LOOP_PARTICLES(i, pa) - pa->flag |= PARS_EDIT_RECALC; + LOOP_POINTS { + point->flag |= PEP_EDIT_RECALC; + } /* do post process on particle edit keys */ - pe_iterate_lengths(scene, psys); - pe_deflect_emitter(scene, ob, psys); - PE_apply_lengths(scene, psys); + pe_iterate_lengths(scene, edit); + pe_deflect_emitter(scene, ob, edit); + PE_apply_lengths(scene, edit); if(pset->flag & PE_X_MIRROR) - PE_apply_mirror(ob,psys); - psys_update_world_cos(ob,psys); - PE_hide_keys_time(scene, psys, cfra); + PE_apply_mirror(ob,edit->psys); + if(edit->psys) + update_world_cos(ob, edit); + if(pset->flag & PE_AUTO_VELOCITY) + update_velocities(ob, edit); + PE_hide_keys_time(scene, edit, CFRA); /* regenerate path caches */ - psys_cache_paths(scene, ob, psys, cfra, 1); - - if(part->childtype && (pset->flag & PE_SHOW_CHILD)) - psys_cache_child_paths(scene, ob, psys, cfra, 1); + psys_cache_edit_paths(scene, ob, edit, CFRA); /* disable update flag */ - LOOP_PARTICLES(i, pa) - pa->flag &= ~PARS_EDIT_RECALC; + LOOP_POINTS { + point->flag &= ~PEP_EDIT_RECALC; + } + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); } /************************************************/ @@ -1118,48 +1165,44 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) /*-----selection callbacks-----*/ -static void select_key(PEData *data, int pa_index, int key_index) +static void select_key(PEData *data, int point_index, int key_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= psys->particles + pa_index; - ParticleEditKey *key= psys->edit->keys[pa_index] + key_index; + PTCacheEdit *edit = data->edit; + PTCacheEditPoint *point = edit->points + point_index; + PTCacheEditKey *key = point->keys + key_index; if(data->select) key->flag |= PEK_SELECT; else key->flag &= ~PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } -static void select_keys(PEData *data, int pa_index, int key_index) +static void select_keys(PEData *data, int point_index, int key_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= psys->particles + pa_index; - ParticleEditKey *key= psys->edit->keys[pa_index]; - int k; + PTCacheEdit *edit = data->edit; + PTCacheEditPoint *point = edit->points + point_index; + KEY_K; - for(k=0; ktotkey; k++,key++) { + LOOP_KEYS { if(data->select) key->flag |= PEK_SELECT; else key->flag &= ~PEK_SELECT; } - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } -static void toggle_key_select(PEData *data, int pa_index, int key_index) +static void toggle_key_select(PEData *data, int point_index, int key_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= psys->particles + pa_index; + PTCacheEdit *edit = data->edit; + PTCacheEditPoint *point = edit->points + point_index; + PTCacheEditKey *key = point->keys + key_index; - if(psys->edit->keys[pa_index][key_index].flag&PEK_SELECT) - psys->edit->keys[pa_index][key_index].flag &= ~PEK_SELECT; - else - psys->edit->keys[pa_index][key_index].flag |= PEK_SELECT; - - pa->flag |= PARS_EDIT_RECALC; + key->flag ^= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; } /************************ de select all operator ************************/ @@ -1168,33 +1211,24 @@ static int de_select_all_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit= 0; - ParticleData *pa; - ParticleEditKey *key; - int i, k, totpart, sel= 0; + PTCacheEdit *edit= PE_get_current(scene, ob); + POINT_P; KEY_K; + int sel= 0; - edit= psys->edit; - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - LOOP_KEYS(k, key) { - if(key->flag & PEK_SELECT) { - sel= 1; - key->flag &= ~PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; - } + LOOP_VISIBLE_POINTS { + LOOP_SELECTED_KEYS { + sel= 1; + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; } } if(sel==0) { - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - LOOP_KEYS(k, key) { + LOOP_VISIBLE_POINTS { + LOOP_KEYS { if(!(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } } } @@ -1227,26 +1261,17 @@ int PE_mouse_particles(bContext *C, short *mval, int extend) PEData data; Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit= 0; - ParticleData *pa; - ParticleEditKey *key; - int i, k, totpart; + PTCacheEdit *edit= PE_get_current(scene, ob); + POINT_P; KEY_K; - if(!PE_can_edit(psys)) + if(!PE_start_edit(edit)) return OPERATOR_CANCELLED; - edit= psys->edit; - totpart= psys->totpart; - if(!extend) { - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - LOOP_KEYS(k, key) { - if(key->flag & PEK_SELECT) { - key->flag &= ~PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; - } + LOOP_VISIBLE_POINTS { + LOOP_SELECTED_KEYS { + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; } } } @@ -1265,11 +1290,9 @@ int PE_mouse_particles(bContext *C, short *mval, int extend) /************************ select first operator ************************/ -static void select_root(PEData *data, int pa_index) +static void select_root(PEData *data, int point_index) { - ParticleSystem *psys= data->psys; - - psys->edit->keys[pa_index]->flag |= PEK_SELECT; + data->edit->points[point_index].keys->flag |= PEK_SELECT; } static int select_first_exec(bContext *C, wmOperator *op) @@ -1277,7 +1300,7 @@ static int select_first_exec(bContext *C, wmOperator *op) PEData data; PE_set_data(C, &data); - PE_foreach_particle(&data, select_root); + foreach_point(&data, select_root); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); return OPERATOR_FINISHED; @@ -1299,13 +1322,10 @@ void PARTICLE_OT_select_first(wmOperatorType *ot) /************************ select last operator ************************/ -static void select_tip(PEData *data, int pa_index) +static void select_tip(PEData *data, int point_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= psys->particles + pa_index; - ParticleEditKey *key= psys->edit->keys[pa_index] + pa->totkey-1; - - key->flag |= PEK_SELECT; + PTCacheEditPoint *point = data->edit->points + point_index; + point->keys[point->totkey - 1].flag |= PEK_SELECT; } static int select_last_exec(bContext *C, wmOperator *op) @@ -1313,7 +1333,7 @@ static int select_last_exec(bContext *C, wmOperator *op) PEData data; PE_set_data(C, &data); - PE_foreach_particle(&data, select_tip); + foreach_point(&data, select_tip); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); return OPERATOR_FINISHED; @@ -1396,10 +1416,10 @@ int PE_border_select(bContext *C, rcti *rect, int select) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); PEData data; - if(!PE_can_edit(psys)) + if(!PE_start_edit(edit)) return OPERATOR_CANCELLED; PE_set_view3d_data(C, &data); @@ -1420,10 +1440,10 @@ int PE_circle_select(bContext *C, int selecting, short *mval, float rad) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); PEData data; - if(!PE_can_edit(psys)) + if(!PE_start_edit(edit)) return OPERATOR_FINISHED; PE_set_view3d_data(C, &data); @@ -1446,47 +1466,42 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select) Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); ARegion *ar= CTX_wm_region(C); - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleSystemModifierData *psmd; - ParticleEdit *edit; - ParticleData *pa; - ParticleEditKey *key; ParticleEditSettings *pset= PE_settings(scene); + PTCacheEdit *edit = PE_get_current(scene, ob); + ParticleSystem *psys = edit->psys; + ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); + POINT_P; KEY_K; float co[3], mat[4][4]; short vertco[2]; - int i, k, totpart; - if(!PE_can_edit(psys)) + if(!PE_start_edit(edit)) return OPERATOR_CANCELLED; - psmd= psys_get_modifier(ob, psys); - edit= psys->edit; - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; + Mat4One(mat); - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat); + LOOP_VISIBLE_POINTS { + if(edit->psys) + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + p, mat); if(pset->selectmode==SCE_SELECT_POINT) { - LOOP_KEYS(k, key) { + LOOP_KEYS { VECCOPY(co, key->co); Mat4MulVecfl(mat, co); project_short(ar, co, vertco); if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1])) { if(select && !(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } else if(key->flag & PEK_SELECT) { key->flag &= ~PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } } } } else if(pset->selectmode==SCE_SELECT_END) { - key= edit->keys[i] + pa->totkey - 1; + key= point->keys + point->totkey - 1; VECCOPY(co, key->co); Mat4MulVecfl(mat, co); @@ -1494,11 +1509,11 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select) if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1])) { if(select && !(key->flag & PEK_SELECT)) { key->flag |= PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } else if(key->flag & PEK_SELECT) { key->flag &= ~PEK_SELECT; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } } } @@ -1516,35 +1531,25 @@ static int hide_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit; - ParticleEditKey *key; - ParticleData *pa; - int i, k, totpart; - - edit= psys->edit; - totpart= psys->totpart; + PTCacheEdit *edit= PE_get_current(scene, ob); + POINT_P; KEY_K; if(RNA_enum_get(op->ptr, "unselected")) { - LOOP_PARTICLES(i, pa) { - if(!particle_is_selected(psys, pa)) { - pa->flag |= PARS_HIDE; - pa->flag |= PARS_EDIT_RECALC; + LOOP_UNSELECTED_POINTS { + point->flag |= PEP_HIDE; + point->flag |= PEP_EDIT_RECALC; - LOOP_KEYS(k, key) - key->flag &= ~PEK_SELECT; - } + LOOP_KEYS + key->flag &= ~PEK_SELECT; } } else { - LOOP_PARTICLES(i, pa) { - if(particle_is_selected(psys, pa)) { - pa->flag |= PARS_HIDE; - pa->flag |= PARS_EDIT_RECALC; + LOOP_SELECTED_POINTS { + point->flag |= PEP_HIDE; + point->flag |= PEP_EDIT_RECALC; - LOOP_KEYS(k, key) - key->flag &= ~PEK_SELECT; - } + LOOP_KEYS + key->flag &= ~PEK_SELECT; } } @@ -1577,21 +1582,15 @@ static int reveal_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit; - ParticleEditKey *key; - ParticleData *pa; - int i, k, totpart; - - edit= psys->edit; - totpart= psys->totpart; + PTCacheEdit *edit= PE_get_current(scene, ob); + POINT_P; KEY_K; - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) { - pa->flag &= ~PARS_HIDE; - pa->flag |= PARS_EDIT_RECALC; + LOOP_POINTS { + if(point->flag & PEP_HIDE) { + point->flag &= ~PEP_HIDE; + point->flag |= PEP_EDIT_RECALC; - LOOP_KEYS(k, key) + LOOP_KEYS key->flag |= PEK_SELECT; } } @@ -1618,34 +1617,30 @@ void PARTICLE_OT_reveal(wmOperatorType *ot) /************************ select less operator ************************/ -static void select_less_keys(PEData *data, int pa_index) +static void select_less_keys(PEData *data, int point_index) { - ParticleSystem *psys= data->psys; - ParticleEdit *edit= psys->edit; - ParticleData *pa= &psys->particles[pa_index]; - ParticleEditKey *key; - int k; - - for(k=0,key=edit->keys[pa_index]; ktotkey; k++,key++) { - if((key->flag & PEK_SELECT)==0) continue; + PTCacheEdit *edit= data->edit; + PTCacheEditPoint *point = edit->points + point_index; + KEY_K; + LOOP_SELECTED_KEYS { if(k==0) { if(((key+1)->flag&PEK_SELECT)==0) - key->flag |= PEK_TO_SELECT; + key->flag |= PEK_TAG; } - else if(k==pa->totkey-1) { + else if(k==point->totkey-1) { if(((key-1)->flag&PEK_SELECT)==0) - key->flag |= PEK_TO_SELECT; + key->flag |= PEK_TAG; } else { if((((key-1)->flag & (key+1)->flag) & PEK_SELECT)==0) - key->flag |= PEK_TO_SELECT; + key->flag |= PEK_TAG; } } - for(k=0,key=edit->keys[pa_index]; ktotkey; k++,key++) { - if(key->flag&PEK_TO_SELECT) - key->flag &= ~(PEK_TO_SELECT|PEK_SELECT); + LOOP_KEYS { + if(key->flag&PEK_TAG) + key->flag &= ~(PEK_TAG|PEK_SELECT); } } @@ -1654,7 +1649,7 @@ static int select_less_exec(bContext *C, wmOperator *op) PEData data; PE_set_data(C, &data); - PE_foreach_particle(&data, select_less_keys); + foreach_point(&data, select_less_keys); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); return OPERATOR_FINISHED; @@ -1676,34 +1671,32 @@ void PARTICLE_OT_select_less(wmOperatorType *ot) /************************ select more operator ************************/ -static void select_more_keys(PEData *data, int pa_index) +static void select_more_keys(PEData *data, int point_index) { - ParticleSystem *psys= data->psys; - ParticleEdit *edit= psys->edit; - ParticleData *pa= &psys->particles[pa_index]; - ParticleEditKey *key; - int k; + PTCacheEdit *edit= data->edit; + PTCacheEditPoint *point = edit->points + point_index; + KEY_K; - for(k=0,key=edit->keys[pa_index]; ktotkey; k++,key++) { + LOOP_KEYS { if(key->flag & PEK_SELECT) continue; if(k==0) { if((key+1)->flag&PEK_SELECT) - key->flag |= PEK_TO_SELECT; + key->flag |= PEK_TAG; } - else if(k==pa->totkey-1) { + else if(k==point->totkey-1) { if((key-1)->flag&PEK_SELECT) - key->flag |= PEK_TO_SELECT; + key->flag |= PEK_TAG; } else { if(((key-1)->flag | (key+1)->flag) & PEK_SELECT) - key->flag |= PEK_TO_SELECT; + key->flag |= PEK_TAG; } } - for(k=0,key=edit->keys[pa_index]; ktotkey; k++,key++) { - if(key->flag&PEK_TO_SELECT) { - key->flag &= ~PEK_TO_SELECT; + LOOP_KEYS { + if(key->flag&PEK_TAG) { + key->flag &= ~PEK_TAG; key->flag |= PEK_SELECT; } } @@ -1714,7 +1707,7 @@ static int select_more_exec(bContext *C, wmOperator *op) PEData data; PE_set_data(C, &data); - PE_foreach_particle(&data, select_more_keys); + foreach_point(&data, select_more_keys); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); return OPERATOR_FINISHED; @@ -1738,12 +1731,13 @@ void PARTICLE_OT_select_more(wmOperatorType *ot) static void rekey_particle(PEData *data, int pa_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= &psys->particles[pa_index]; - ParticleEdit *edit= psys->edit; + PTCacheEdit *edit= data->edit; + ParticleSystem *psys= edit->psys; + ParticleData *pa= psys->particles + pa_index; + PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; HairKey *key, *new_keys; - ParticleEditKey *ekey; + PTCacheEditKey *ekey; float dval, sta, end; int k; @@ -1772,19 +1766,21 @@ static void rekey_particle(PEData *data, int pa_index) MEM_freeN(pa->hair); pa->hair= new_keys; - pa->totkey=data->totrekey; + point->totkey=pa->totkey=data->totrekey; - if(edit->keys[pa_index]) - MEM_freeN(edit->keys[pa_index]); - ekey= edit->keys[pa_index]= MEM_callocN(pa->totkey * sizeof(ParticleEditKey),"Hair re-key edit keys"); + + if(point->keys) + MEM_freeN(point->keys); + ekey= point->keys= MEM_callocN(pa->totkey * sizeof(PTCacheEditKey),"Hair re-key edit keys"); for(k=0, key=pa->hair; ktotkey; k++, key++, ekey++) { ekey->co= key->co; ekey->time= &key->time; + ekey->flag |= PEK_USE_WCO; } pa->flag &= ~PARS_REKEY; - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } static int rekey_exec(bContext *C, wmOperator *op) @@ -1796,11 +1792,9 @@ static int rekey_exec(bContext *C, wmOperator *op) data.dval= 1.0f / (float)(data.totrekey-1); data.totrekey= RNA_int_get(op->ptr, "keys"); - foreach_selected_particle(&data, rekey_particle); - - data.psys->edit->totkeys= psys_count_keys(data.psys); - recalc_lengths(data.psys); + foreach_selected_point(&data, rekey_particle); + recalc_lengths(data.edit); PE_update_object(data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, data.ob); @@ -1827,19 +1821,19 @@ void PARTICLE_OT_rekey(wmOperatorType *ot) static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float path_time) { - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit=0; + PTCacheEdit *edit= PE_get_current(scene, ob); + ParticleSystem *psys; ParticleData *pa; ParticleKey state; HairKey *new_keys, *key; - ParticleEditKey *ekey; + PTCacheEditKey *ekey; int k; - if(psys==0) return; + if(!edit || !edit->psys) return; - edit= psys->edit; + psys = edit->psys; - pa= &psys->particles[pa_index]; + pa= psys->particles + pa_index; pa->flag |= PARS_REKEY; @@ -1858,7 +1852,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float pa->hair= new_keys; /* update edit pointers */ - for(k=0, key=pa->hair, ekey=edit->keys[pa_index]; ktotkey; k++, key++, ekey++) { + for(k=0, key=pa->hair, ekey=edit->points[pa_index].keys; ktotkey; k++, key++, ekey++) { ekey->co= key->co; ekey->time= &key->time; } @@ -1870,10 +1864,11 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float static int remove_tagged_particles(Scene *scene, Object *ob, ParticleSystem *psys) { - ParticleEdit *edit= psys->edit; + PTCacheEdit *edit = psys->edit; ParticleEditSettings *pset= PE_settings(scene); ParticleData *pa, *npa=0, *new_pars=0; - ParticleEditKey **key, **nkey=0, **new_keys=0; + POINT_P; + PTCacheEditPoint *npoint=0, *new_points=0; ParticleSystemModifierData *psmd; int i, totpart, new_totpart= psys->totpart, removed= 0; @@ -1882,55 +1877,51 @@ static int remove_tagged_particles(Scene *scene, Object *ob, ParticleSystem *psy psmd= psys_get_modifier(ob, psys); totpart= psys->totpart; - LOOP_PARTICLES(i, pa) - if(pa->flag & PARS_TAG) - PE_mirror_particle(ob, psmd->dm, psys, pa, NULL); + LOOP_TAGGED_POINTS { + PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL); + } } - for(i=0, pa=psys->particles; itotpart; i++, pa++) { - if(pa->flag & PARS_TAG) { - new_totpart--; - removed++; - } + LOOP_TAGGED_POINTS { + new_totpart--; + removed++; } if(new_totpart != psys->totpart) { if(new_totpart) { npa= new_pars= MEM_callocN(new_totpart * sizeof(ParticleData), "ParticleData array"); - nkey= new_keys= MEM_callocN(new_totpart * sizeof(ParticleEditKey *), "ParticleEditKey array"); + npoint= new_points= MEM_callocN(new_totpart * sizeof(PTCacheEditPoint), "PTCacheEditKey array"); } pa= psys->particles; - key= edit->keys; - for(i=0; itotpart; i++, pa++, key++) { - if(pa->flag & PARS_TAG) { - if(*key) - MEM_freeN(*key); + point= edit->points; + for(i=0; itotpart; i++, pa++, point++) { + if(point->flag & PEP_TAG) { + if(point->keys) + MEM_freeN(point->keys); if(pa->hair) MEM_freeN(pa->hair); } else { memcpy(npa, pa, sizeof(ParticleData)); - memcpy(nkey, key, sizeof(ParticleEditKey*)); + memcpy(npoint, point, sizeof(PTCacheEditPoint)); npa++; - nkey++; + npoint++; } } if(psys->particles) MEM_freeN(psys->particles); psys->particles= new_pars; - if(edit->keys) MEM_freeN(edit->keys); - edit->keys= new_keys; + if(edit->points) MEM_freeN(edit->points); + edit->points= new_points; if(edit->mirror_cache) { MEM_freeN(edit->mirror_cache); edit->mirror_cache= NULL; } - psys->totpart= new_totpart; - - edit->totkeys= psys_count_keys(psys); + edit->totpoint= psys->totpart= new_totpart; } return removed; @@ -1938,84 +1929,82 @@ static int remove_tagged_particles(Scene *scene, Object *ob, ParticleSystem *psy static void remove_tagged_keys(Scene *scene, Object *ob, ParticleSystem *psys) { - ParticleEdit *edit= psys->edit; + PTCacheEdit *edit= psys->edit; ParticleEditSettings *pset= PE_settings(scene); ParticleData *pa; - HairKey *key, *nkey, *new_keys=0; - ParticleEditKey *ekey; + HairKey *hkey, *nhkey, *new_hkeys=0; + POINT_P; KEY_K; ParticleSystemModifierData *psmd; - int i, k, totpart= psys->totpart; short new_totkey; if(pset->flag & PE_X_MIRROR) { /* mirror key tags */ psmd= psys_get_modifier(ob, psys); - LOOP_PARTICLES(i, pa) { - LOOP_KEYS(k,ekey) { - if(ekey->flag & PEK_TAG) { - PE_mirror_particle(ob, psmd->dm, psys, pa, NULL); - break; - } + LOOP_POINTS { + LOOP_TAGGED_KEYS { + PE_mirror_particle(ob, psmd->dm, psys, psys->particles + p, NULL); + break; } } } - LOOP_PARTICLES(i, pa) { - new_totkey= pa->totkey; - LOOP_KEYS(k,ekey) { - if(ekey->flag & PEK_TAG) - new_totkey--; + LOOP_POINTS { + new_totkey= point->totkey; + LOOP_TAGGED_KEYS { + new_totkey--; } /* we can't have elements with less than two keys*/ if(new_totkey < 2) - pa->flag |= PARS_TAG; + point->flag |= PEP_TAG; } remove_tagged_particles(scene, ob, psys); - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { + LOOP_POINTS { + pa = psys->particles + p; new_totkey= pa->totkey; - LOOP_KEYS(k,ekey) { - if(ekey->flag & PEK_TAG) - new_totkey--; + + LOOP_TAGGED_KEYS { + new_totkey--; } + if(new_totkey != pa->totkey) { - key= pa->hair; - nkey= new_keys= MEM_callocN(new_totkey*sizeof(HairKey), "HairKeys"); + hkey= pa->hair; + nhkey= new_hkeys= MEM_callocN(new_totkey*sizeof(HairKey), "HairKeys"); - for(k=0, ekey=edit->keys[i]; kflag & PEK_TAG && key < pa->hair + pa->totkey) { + LOOP_KEYS { + while(key->flag & PEK_TAG && hkey < pa->hair + pa->totkey) { key++; - ekey++; + hkey++; } - if(key < pa->hair + pa->totkey) { - VECCOPY(nkey->co, key->co); - nkey->time= key->time; - nkey->weight= key->weight; + if(hkey < pa->hair + pa->totkey) { + VECCOPY(nhkey->co, hkey->co); + nhkey->time= hkey->time; + nhkey->weight= hkey->weight; } + hkey++; + nhkey++; } if(pa->hair) MEM_freeN(pa->hair); - pa->hair= new_keys; + pa->hair= new_hkeys; - pa->totkey=new_totkey; + point->totkey= pa->totkey= new_totkey; - if(edit->keys[i]) - MEM_freeN(edit->keys[i]); - ekey= edit->keys[i]= MEM_callocN(new_totkey*sizeof(ParticleEditKey), "particle edit keys"); + if(point->keys) + MEM_freeN(point->keys); + key= point->keys= MEM_callocN(new_totkey*sizeof(PTCacheEditKey), "particle edit keys"); - for(k=0, key=pa->hair; ktotkey; k++, key++, ekey++) { - ekey->co= key->co; - ekey->time= &key->time; + hkey = pa->hair; + LOOP_KEYS { + key->co= hkey->co; + key->time= &hkey->time; + hkey++; } } } - - edit->totkeys= psys_count_keys(psys); } /************************ subdivide opertor *********************/ @@ -2023,19 +2012,19 @@ static void remove_tagged_keys(Scene *scene, Object *ob, ParticleSystem *psys) /* works like normal edit mode subdivide, inserts keys between neighbouring selected keys */ static void subdivide_particle(PEData *data, int pa_index) { - ParticleSystem *psys= data->psys; - ParticleEdit *edit= psys->edit; - ParticleData *pa= &psys->particles[pa_index]; - + PTCacheEdit *edit= data->edit; + ParticleSystem *psys= edit->psys; + ParticleData *pa= psys->particles + pa_index; + PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; HairKey *key, *nkey, *new_keys; - ParticleEditKey *ekey, *nekey, *new_ekeys; + PTCacheEditKey *ekey, *nekey, *new_ekeys; int k; short totnewkey=0; float endtime; - for(k=0, ekey=edit->keys[pa_index]; ktotkey-1; k++,ekey++) { + for(k=0, ekey=point->keys; ktotkey-1; k++,ekey++) { if(ekey->flag&PEK_SELECT && (ekey+1)->flag&PEK_SELECT) totnewkey++; } @@ -2045,13 +2034,13 @@ static void subdivide_particle(PEData *data, int pa_index) pa->flag |= PARS_REKEY; nkey= new_keys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(HairKey)),"Hair subdivide keys"); - nekey= new_ekeys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(ParticleEditKey)),"Hair subdivide edit keys"); + nekey= new_ekeys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(PTCacheEditKey)),"Hair subdivide edit keys"); endtime= pa->hair[pa->totkey-1].time; - for(k=0, key=pa->hair, ekey=edit->keys[pa_index]; ktotkey-1; k++, key++, ekey++) { + for(k=0, key=pa->hair, ekey=point->keys; ktotkey-1; k++, key++, ekey++) { memcpy(nkey,key,sizeof(HairKey)); - memcpy(nekey,ekey,sizeof(ParticleEditKey)); + memcpy(nekey,ekey,sizeof(PTCacheEditKey)); nekey->co= nkey->co; nekey->time= &nkey->time; @@ -2067,7 +2056,7 @@ static void subdivide_particle(PEData *data, int pa_index) nekey->co= nkey->co; nekey->time= &nkey->time; - nekey->flag |= PEK_SELECT; + nekey->flag |= (PEK_SELECT|PEK_USE_WCO); nekey++; nkey++; @@ -2075,7 +2064,7 @@ static void subdivide_particle(PEData *data, int pa_index) } /*tip still not copied*/ memcpy(nkey,key,sizeof(HairKey)); - memcpy(nekey,ekey,sizeof(ParticleEditKey)); + memcpy(nekey,ekey,sizeof(PTCacheEditKey)); nekey->co= nkey->co; nekey->time= &nkey->time; @@ -2084,13 +2073,12 @@ static void subdivide_particle(PEData *data, int pa_index) MEM_freeN(pa->hair); pa->hair= new_keys; - if(edit->keys[pa_index]) - MEM_freeN(edit->keys[pa_index]); + if(point->keys) + MEM_freeN(point->keys); + point->keys= new_ekeys; - edit->keys[pa_index]= new_ekeys; - - pa->totkey += totnewkey; - pa->flag |= PARS_EDIT_RECALC; + point->totkey = pa->totkey = pa->totkey + totnewkey; + point->flag |= PEP_EDIT_RECALC; pa->flag &= ~PARS_REKEY; } @@ -2099,13 +2087,9 @@ static int subdivide_exec(bContext *C, wmOperator *op) PEData data; PE_set_data(C, &data); - PE_foreach_particle(&data, subdivide_particle); - - data.psys->edit->totkeys= psys_count_keys(data.psys); + foreach_point(&data, subdivide_particle); - recalc_lengths(data.psys); - psys_update_world_cos(data.ob, data.psys); - + recalc_lengths(data.edit); PE_update_object(data.scene, data.ob, 1); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, data.ob); @@ -2132,15 +2116,15 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); ParticleEditSettings *pset=PE_settings(scene); - ParticleData *pa; - ParticleEdit *edit; + PTCacheEdit *edit= PE_get_current(scene, ob); + ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd; KDTree *tree; KDTreeNearest nearest[10]; + POINT_P; float mat[4][4], co[3], threshold= RNA_float_get(op->ptr, "threshold"); - int i, n, totn, removed, totpart, flag, totremoved; + int n, totn, removed, flag, totremoved; edit= psys->edit; psmd= psys_get_modifier(ob, psys); @@ -2149,37 +2133,32 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) do { removed= 0; - totpart= psys->totpart; - tree=BLI_kdtree_new(totpart); + tree=BLI_kdtree_new(psys->totpart); /* insert particles into kd tree */ - LOOP_PARTICLES(i, pa) { - if(particle_is_selected(psys, pa)) { - psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, pa->hair[0].co); - Mat4MulVecfl(mat, co); - BLI_kdtree_insert(tree, i, co, NULL); - } + LOOP_SELECTED_POINTS { + psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat); + VECCOPY(co, point->keys->co); + Mat4MulVecfl(mat, co); + BLI_kdtree_insert(tree, p, co, NULL); } BLI_kdtree_balance(tree); /* tag particles to be removed */ - LOOP_PARTICLES(i, pa) { - if(particle_is_selected(psys, pa)) { - psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, pa->hair[0].co); - Mat4MulVecfl(mat, co); + LOOP_SELECTED_POINTS { + psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat); + VECCOPY(co, point->keys->co); + Mat4MulVecfl(mat, co); - totn= BLI_kdtree_find_n_nearest(tree,10,co,NULL,nearest); + totn= BLI_kdtree_find_n_nearest(tree,10,co,NULL,nearest); - for(n=0; n i && nearest[n].dist < threshold) { - if(!(pa->flag & PARS_TAG)) { - pa->flag |= PARS_TAG; - removed++; - } + for(n=0; n p && nearest[n].dist < threshold) { + if(!(point->flag & PEP_TAG)) { + point->flag |= PEP_TAG; + removed++; } } } @@ -2200,7 +2179,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) BKE_reportf(op->reports, RPT_INFO, "Remove %d double particles.", totremoved); - psys_update_world_cos(ob, psys); + PE_update_object(scene, ob, 0); DAG_object_flush_update(scene, ob, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); @@ -2347,16 +2326,16 @@ static EnumPropertyItem delete_type_items[]= { static void set_delete_particle(PEData *data, int pa_index) { - ParticleSystem *psys= data->psys; + PTCacheEdit *edit= data->edit; - psys->particles[pa_index].flag |= PARS_TAG; + edit->points[pa_index].flag |= PEP_TAG; } static void set_delete_particle_key(PEData *data, int pa_index, int key_index) { - ParticleSystem *psys= data->psys; + PTCacheEdit *edit= data->edit; - psys->edit->keys[pa_index][key_index].flag |= PEK_TAG; + edit->points[pa_index].keys[key_index].flag |= PEK_TAG; } static int delete_exec(bContext *C, wmOperator *op) @@ -2368,15 +2347,17 @@ static int delete_exec(bContext *C, wmOperator *op) if(type == DEL_KEY) { foreach_selected_key(&data, set_delete_particle_key); - remove_tagged_keys(data.scene, data.ob, data.psys); - recalc_lengths(data.psys); + remove_tagged_keys(data.scene, data.ob, data.edit->psys); + recalc_lengths(data.edit); } else if(type == DEL_PARTICLE) { - foreach_selected_particle(&data, set_delete_particle); - remove_tagged_particles(data.scene, data.ob, data.psys); - recalc_lengths(data.psys); + foreach_selected_point(&data, set_delete_particle); + remove_tagged_particles(data.scene, data.ob, data.edit->psys); + recalc_lengths(data.edit); } + PE_update_object(data.scene, data.ob, 0); + DAG_object_flush_update(data.scene, data.ob, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, data.ob); @@ -2407,15 +2388,15 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) { Mesh *me= (Mesh*)(ob->data); ParticleSystemModifierData *psmd; - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit; + PTCacheEdit *edit= PE_get_current(scene, ob); + ParticleSystem *psys = edit->psys; ParticleData *pa, *newpa, *new_pars; - ParticleEditKey *ekey, **newkey, **key, **new_keys; + PTCacheEditPoint *newpoint, *new_points; + POINT_P; KEY_K; HairKey *hkey; int *mirrorfaces; - int i, k, rotation, totpart, newtotpart; + int rotation, totpart, newtotpart; - edit= psys->edit; psmd= psys_get_modifier(ob, psys); mirrorfaces= mesh_get_x_mirror_faces(ob, NULL); @@ -2425,29 +2406,28 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) totpart= psys->totpart; newtotpart= psys->totpart; - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; - + LOOP_VISIBLE_POINTS { + pa = psys->particles + p; if(!tagged) { - if(particle_is_selected(psys, pa)) { - if(edit->mirror_cache[i] != -1) { + if(point_is_selected(point)) { + if(edit->mirror_cache[p] != -1) { /* already has a mirror, don't need to duplicate */ PE_mirror_particle(ob, psmd->dm, psys, pa, NULL); continue; } else - pa->flag |= PARS_TAG; + point->flag |= PEP_TAG; } } - if((pa->flag & PARS_TAG) && mirrorfaces[pa->num*2] != -1) + if((point->flag & PEP_TAG) && mirrorfaces[pa->num*2] != -1) newtotpart++; } if(newtotpart != psys->totpart) { /* allocate new arrays and copy existing */ new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new"); - new_keys= MEM_callocN(newtotpart*sizeof(ParticleEditKey*), "ParticleEditKey new"); + new_points= MEM_callocN(newtotpart*sizeof(PTCacheEditPoint), "PTCacheEditPoint new"); if(psys->particles) { memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData)); @@ -2455,36 +2435,35 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } psys->particles= new_pars; - if(edit->keys) { - memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*)); - MEM_freeN(edit->keys); + if(edit->points) { + memcpy(new_points, edit->points, totpart*sizeof(PTCacheEditPoint)); + MEM_freeN(edit->points); } - edit->keys= new_keys; + edit->points= new_points; if(edit->mirror_cache) { MEM_freeN(edit->mirror_cache); edit->mirror_cache= NULL; } - psys->totpart= newtotpart; + edit->totpoint= psys->totpart= newtotpart; /* create new elements */ - pa= psys->particles; newpa= psys->particles + totpart; - key= edit->keys; - newkey= edit->keys + totpart; + newpoint= edit->points + totpart; - for(i=0; iflag & PARS_HIDE) continue; + LOOP_VISIBLE_POINTS { + pa = psys->particles + p; - if(!(pa->flag & PARS_TAG) || mirrorfaces[pa->num*2] == -1) + if(!(point->flag & PEP_TAG) || mirrorfaces[pa->num*2] == -1) continue; /* duplicate */ *newpa= *pa; + *newpoint= *point; if(pa->hair) newpa->hair= MEM_dupallocN(pa->hair); if(pa->keys) newpa->keys= MEM_dupallocN(pa->keys); - if(*key) *newkey= MEM_dupallocN(*key); + if(point->keys) newpoint->keys= MEM_dupallocN(point->keys); /* rotate weights according to vertex index rotation */ rotation= mirrorfaces[pa->num*2+1]; @@ -2503,24 +2482,23 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) newpa->num_dmcache= psys_particle_dm_face_lookup(ob,psmd->dm,newpa->num,newpa->fuv, NULL); /* update edit key pointers */ - ekey= *newkey; - for(k=0, hkey=newpa->hair; ktotkey; k++, hkey++, ekey++) { - ekey->co= hkey->co; - ekey->time= &hkey->time; + key= newpoint->keys; + for(k=0, hkey=newpa->hair; ktotkey; k++, hkey++, key++) { + key->co= hkey->co; + key->time= &hkey->time; } /* map key positions as mirror over x axis */ PE_mirror_particle(ob, psmd->dm, psys, pa, newpa); newpa++; - newkey++; + newpoint++; } - - edit->totkeys= psys_count_keys(psys); } - for(pa=psys->particles, i=0; itotpart; i++, pa++) - pa->flag &= ~PARS_TAG; + LOOP_POINTS { + point->flag &= ~PEP_TAG; + } MEM_freeN(mirrorfaces); } @@ -2529,11 +2507,11 @@ static int mirror_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); + PTCacheEdit *edit= PE_get_current(scene, ob); PE_mirror_x(scene, ob, 0); - psys_update_world_cos(ob, psys); + update_world_cos(ob, edit); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); DAG_object_flush_update(scene, ob, OB_RECALC_DATA); @@ -2560,7 +2538,6 @@ static EnumPropertyItem brush_type_items[]= { {PE_BRUSH_NONE, "NONE", 0, "None", ""}, {PE_BRUSH_COMB, "COMB", 0, "Comb", ""}, {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", ""}, - {PE_BRUSH_WEIGHT, "WEIGHT", 0, "Weight", ""}, {PE_BRUSH_ADD, "ADD", 0, "Add", ""}, {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", ""}, {PE_BRUSH_PUFF, "PUFF", 0, "Puff", ""}, @@ -2593,14 +2570,46 @@ void PARTICLE_OT_brush_set(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", brush_type_items, PE_BRUSH_NONE, "Type", "Brush type to select for editing."); } + +/*********************** set mode operator **********************/ + +static EnumPropertyItem edit_type_items[]= { + {PE_TYPE_PARTICLES, "PARTICLES", 0, "Particles", ""}, + {PE_TYPE_SOFTBODY, "SOFTBODY", 0, "Soft body", ""}, + {PE_TYPE_CLOTH, "CLOTH", 0, "Cloth", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int set_edit_mode_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + ParticleEditSettings *pset= PE_settings(scene); + + pset->edittype= RNA_enum_get(op->ptr, "type"); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_edit_type_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Brush"; + ot->idname= "PARTICLE_OT_edit_type_set"; + + /* api callbacks */ + ot->exec= set_brush_exec; + ot->invoke= WM_menu_invoke; + ot->poll= PE_poll; + + /* properties */ + RNA_def_enum(ot->srna, "type", edit_type_items, PE_TYPE_PARTICLES, "Type", "Edit type to select for editing."); +} + /************************* brush edit callbacks ********************/ -static void brush_comb(PEData *data, float mat[][4], float imat[][4], int pa_index, int key_index) +static void brush_comb(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key) { - ParticleSystem *psys= data->psys; - ParticleData *pa= &psys->particles[pa_index]; ParticleEditSettings *pset= PE_settings(data->scene); - HairKey *key= pa->hair + key_index; float cvec[3], fac; if(pset->flag & PE_LOCK_FIRST && key_index == 0) return; @@ -2612,19 +2621,21 @@ static void brush_comb(PEData *data, float mat[][4], float imat[][4], int pa_ind VecMulf(cvec, fac); VECADD(key->co, key->co, cvec); - pa->flag |= PARS_EDIT_RECALC; + (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; } static void brush_cut(PEData *data, int pa_index) { - ParticleSystem *psys= data->psys; + PTCacheEdit *edit = data->edit; + ParticleSystem *psys= edit->psys; ARegion *ar= data->vc.ar; Object *ob= data->ob; + ParticleEditSettings *pset= PE_settings(data->scene); ParticleData *pa= &psys->particles[pa_index]; - ParticleCacheKey *key= psys->pathcache[pa_index]; + ParticleCacheKey *key= edit->pathcache[pa_index]; float rad2, cut_time= 1.0; float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv; - int k, cut, keys= (int)pow(2.0, (double)psys->part->draw_step); + int k, cut, keys= (int)pow(2.0, (double)pset->draw_step); short vertco[2]; /* blunt scissors */ @@ -2699,93 +2710,97 @@ static void brush_cut(PEData *data, int pa_index) if(cut) { if(cut_time < 0.0f) { - pa->flag |= PARS_TAG; + edit->points[pa_index].flag |= PEP_TAG; } else { rekey_particle_to_time(data->scene, ob, pa_index, cut_time); - pa->flag |= PARS_EDIT_RECALC; + edit->points[pa_index].flag |= PEP_EDIT_RECALC; } } } -static void brush_length(PEData *data, int pa_index) +static void brush_length(PEData *data, int point_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= &psys->particles[pa_index]; - HairKey *key; + PTCacheEdit *edit= data->edit; + PTCacheEditPoint *point = edit->points + point_index; + KEY_K; float dvec[3],pvec[3]; - int k; - key= pa->hair; - VECCOPY(pvec,key->co); - - for(k=1, key++; ktotkey; k++,key++) { - VECSUB(dvec,key->co,pvec); - VECCOPY(pvec,key->co); - VecMulf(dvec,data->growfac); - VECADD(key->co,(key-1)->co,dvec); + LOOP_KEYS { + if(k==0) { + VECCOPY(pvec,key->co); + } + else { + VECSUB(dvec,key->co,pvec); + VECCOPY(pvec,key->co); + VecMulf(dvec,data->growfac); + VECADD(key->co,(key-1)->co,dvec); + } } - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } -static void brush_puff(PEData *data, int pa_index) +static void brush_puff(PEData *data, int point_index) { - ParticleSystem *psys= data->psys; - ParticleData *pa= &psys->particles[pa_index]; - ParticleEdit *edit= psys->edit; - HairKey *key; + PTCacheEdit *edit = data->edit; + ParticleSystem *psys = edit->psys; + PTCacheEditPoint *point = edit->points + point_index; + KEY_K; float mat[4][4], imat[4][4]; float lastco[3], rootco[3], co[3], nor[3], kco[3], dco[3], fac, length; - int k; - - psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, pa, mat); - Mat4Invert(imat,mat); - /* find root coordinate and normal on emitter */ - key= pa->hair; - VECCOPY(co, key->co); - Mat4MulVecfl(mat, co); + if(psys) { + psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat); + Mat4Invert(imat,mat); + } + else { + Mat4One(mat); + Mat4One(imat); + } - pa_index= BLI_kdtree_find_nearest(edit->emitter_field, co, NULL, NULL); - if(pa_index == -1) return; + LOOP_KEYS { + if(k==0) { + /* find root coordinate and normal on emitter */ + VECCOPY(co, key->co); + Mat4MulVecfl(mat, co); - VECCOPY(rootco, co); - VecCopyf(nor, &psys->edit->emitter_cosnos[pa_index*6+3]); - Normalize(nor); - length= 0.0f; + point_index= BLI_kdtree_find_nearest(edit->emitter_field, co, NULL, NULL); + if(point_index == -1) return; - fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac); - fac *= 0.025f; - if(data->invert) - fac= -fac; + VECCOPY(rootco, co); + VecCopyf(nor, &edit->emitter_cosnos[point_index*6+3]); + Normalize(nor); + length= 0.0f; - for(k=1, key++; ktotkey; k++, key++) { - /* compute position as if hair was standing up straight */ - VECCOPY(lastco, co); - VECCOPY(co, key->co); - Mat4MulVecfl(mat, co); - length += VecLenf(lastco, co); + fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac); + fac *= 0.025f; + if(data->invert) + fac= -fac; + } + else { + /* compute position as if hair was standing up straight */ + VECCOPY(lastco, co); + VECCOPY(co, key->co); + Mat4MulVecfl(mat, co); + length += VecLenf(lastco, co); - VECADDFAC(kco, rootco, nor, length); + VECADDFAC(kco, rootco, nor, length); - /* blend between the current and straight position */ - VECSUB(dco, kco, co); - VECADDFAC(co, co, dco, fac); + /* blend between the current and straight position */ + VECSUB(dco, kco, co); + VECADDFAC(co, co, dco, fac); - VECCOPY(key->co, co); - Mat4MulVecfl(imat, key->co); + VECCOPY(key->co, co); + Mat4MulVecfl(imat, key->co); + } } - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; } -static void brush_smooth_get(PEData *data, float mat[][4], float imat[][4], int pa_index, int key_index) -{ - ParticleSystem *psys= data->psys; - ParticleData *pa= &psys->particles[pa_index]; - HairKey *key= pa->hair + key_index; - +static void brush_smooth_get(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key) +{ if(key_index) { float dvec[3]; @@ -2796,11 +2811,8 @@ static void brush_smooth_get(PEData *data, float mat[][4], float imat[][4], int } } -static void brush_smooth_do(PEData *data, float mat[][4], float imat[][4], int pa_index, int key_index) +static void brush_smooth_do(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key) { - ParticleSystem *psys= data->psys; - ParticleData *pa= &psys->particles[pa_index]; - HairKey *key= pa->hair + key_index; float vec[3], dvec[3]; if(key_index) { @@ -2815,18 +2827,18 @@ static void brush_smooth_do(PEData *data, float mat[][4], float imat[][4], int p VECADD(key->co,key->co,dvec); } - pa->flag |= PARS_EDIT_RECALC; + (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; } static void brush_add(PEData *data, short number) { Scene *scene= data->scene; Object *ob= data->ob; - ParticleSystem *psys= data->psys; + PTCacheEdit *edit = data->edit; + ParticleSystem *psys= edit->psys; ParticleData *add_pars= MEM_callocN(number*sizeof(ParticleData),"ParticleData add"); ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys); ParticleEditSettings *pset= PE_settings(scene); - ParticleEdit *edit= psys->edit; int i, k, n= 0, totpart= psys->totpart; short mco[2]; short dmx= 0, dmy= 0; @@ -2873,19 +2885,20 @@ static void brush_add(PEData *data, short number) float hairmat[4][4], cur_co[3]; KDTree *tree=0; ParticleData *pa, *new_pars= MEM_callocN(newtotpart*sizeof(ParticleData),"ParticleData new"); - ParticleEditKey *ekey, **key, **new_keys= MEM_callocN(newtotpart*sizeof(ParticleEditKey *),"ParticleEditKey array new"); + PTCacheEditPoint *point, *new_points= MEM_callocN(newtotpart*sizeof(PTCacheEditPoint),"PTCacheEditPoint array new"); + PTCacheEditKey *key; HairKey *hkey; /* save existing elements */ memcpy(new_pars, psys->particles, totpart * sizeof(ParticleData)); - memcpy(new_keys, edit->keys, totpart * sizeof(ParticleEditKey*)); + memcpy(new_points, edit->points, totpart * sizeof(PTCacheEditPoint)); /* change old arrays to new ones */ if(psys->particles) MEM_freeN(psys->particles); psys->particles= new_pars; - if(edit->keys) MEM_freeN(edit->keys); - edit->keys= new_keys; + if(edit->points) MEM_freeN(edit->points); + edit->points= new_points; if(edit->mirror_cache) { MEM_freeN(edit->mirror_cache); @@ -2904,29 +2917,29 @@ static void brush_add(PEData *data, short number) BLI_kdtree_balance(tree); } - psys->totpart= newtotpart; + edit->totpoint= psys->totpart= newtotpart; /* create new elements */ pa= psys->particles + totpart; - key= edit->keys + totpart; + point= edit->points + totpart; - for(i=totpart; ihair= MEM_callocN(pset->totaddkey * sizeof(HairKey), "BakeKey key add"); - ekey= *key= MEM_callocN(pset->totaddkey * sizeof(ParticleEditKey), "ParticleEditKey add"); - pa->totkey= pset->totaddkey; + key= point->keys= MEM_callocN(pset->totaddkey * sizeof(PTCacheEditKey), "PTCacheEditKey add"); + point->totkey= pa->totkey= pset->totaddkey; - for(k=0, hkey=pa->hair; ktotkey; k++, hkey++, ekey++) { - ekey->co= hkey->co; - ekey->time= &hkey->time; + for(k=0, hkey=pa->hair; ktotkey; k++, hkey++, key++) { + key->co= hkey->co; + key->time= &hkey->time; } pa->size= 1.0f; initialize_particle(pa,i,ob,psys,psmd); reset_particle(scene, pa,psys,psmd,ob,0.0,1.0,0,0,0); - pa->flag |= PARS_EDIT_RECALC; + point->flag |= PEP_EDIT_RECALC; if(pset->flag & PE_X_MIRROR) - pa->flag |= PARS_TAG; /* signal for duplicate */ + point->flag |= PEP_TAG; /* signal for duplicate */ framestep= pa->lifetime/(float)(pset->totaddkey-1); @@ -2997,7 +3010,6 @@ static void brush_add(PEData *data, short number) Mat4MulVecfl(imat, hkey->co); } } - edit->totkeys= psys_count_keys(psys); if(tree) BLI_kdtree_free(tree); @@ -3009,25 +3021,12 @@ static void brush_add(PEData *data, short number) dm->release(dm); } -static void brush_weight(PEData *data, float mat[][4], float imat[][4], int pa_index, int key_index) -{ - ParticleSystem *psys= data->psys; - ParticleData *pa; - - /* roots have full weight allways */ - if(key_index) { - pa= &psys->particles[pa_index]; - pa->hair[key_index].weight= data->weightfac; - pa->flag |= PARS_EDIT_RECALC; - } -} - /************************* brush edit operator ********************/ typedef struct BrushEdit { Scene *scene; Object *ob; - ParticleSystem *psys; + PTCacheEdit *edit; int first; int lastmouse[2]; @@ -3037,8 +3036,8 @@ static int brush_edit_init(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); ParticleEditSettings *pset= PE_settings(scene); + PTCacheEdit *edit= PE_get_current(scene, ob); ARegion *ar= CTX_wm_region(C); BrushEdit *bedit; @@ -3053,7 +3052,7 @@ static int brush_edit_init(bContext *C, wmOperator *op) bedit->scene= scene; bedit->ob= ob; - bedit->psys= psys; + bedit->edit= edit; return 1; } @@ -3063,15 +3062,18 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) BrushEdit *bedit= op->customdata; Scene *scene= bedit->scene; Object *ob= bedit->ob; - ParticleSystem *psys= bedit->psys; + PTCacheEdit *edit= bedit->edit; ParticleEditSettings *pset= PE_settings(scene); - ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys); + ParticleSystemModifierData *psmd= edit->psys ? psys_get_modifier(ob, edit->psys) : NULL; ParticleBrushData *brush= &pset->brush[pset->brushtype]; ARegion *ar= CTX_wm_region(C); - float vec1[3], vec2[3], mousef[2]; + float vec[3], mousef[2]; short mval[2], mvalo[2]; int flip, mouse[2], dx, dy, removed= 0, selected= 0; + if(!PE_start_edit(edit)) + return; + RNA_float_get_array(itemptr, "mouse", mousef); mouse[0] = mousef[0]; mouse[1] = mousef[1]; @@ -3096,7 +3098,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) || bedit->first) { view3d_operator_needs_opengl(C); - selected= (short)count_selected_keys(scene, psys); + selected= (short)count_selected_keys(scene, edit); switch(pset->brushtype) { case PE_BRUSH_COMB: @@ -3115,10 +3117,8 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) Mat4Invert(ob->imat, ob->obmat); - window_to_3d(ar, vec1, mvalo[0], mvalo[1]); - window_to_3d(ar, vec2, mval[0], mval[1]); - VECSUB(vec1, vec2, vec1); - data.dvec= vec1; + window_to_3d_delta(ar, vec, dx, dy); + data.dvec= vec; foreach_mouse_hit_key(&data, brush_comb, selected); break; @@ -3126,20 +3126,22 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_CUT: { PEData data; + + if(edit->psys && edit->pathcache) { + PE_set_view3d_data(C, &data); + data.mval= mval; + data.rad= (float)brush->size; + data.cutfac= (float)(brush->strength / 100.0f); - PE_set_view3d_data(C, &data); - data.mval= mval; - data.rad= (float)brush->size; - data.cutfac= (float)(brush->strength / 100.0f); - - if(selected) - foreach_selected_particle(&data, brush_cut); - else - PE_foreach_particle(&data, brush_cut); + if(selected) + foreach_selected_point(&data, brush_cut); + else + foreach_point(&data, brush_cut); - removed= remove_tagged_particles(scene, ob, psys); - if(pset->flag & PE_KEEP_LENGTHS) - recalc_lengths(psys); + removed= remove_tagged_particles(scene, ob, edit->psys); + if(pset->flag & PE_KEEP_LENGTHS) + recalc_lengths(edit); + } break; } case PE_BRUSH_LENGTH: @@ -3157,61 +3159,50 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) else data.growfac= 1.0f + data.growfac; - foreach_mouse_hit_particle(&data, brush_length, selected); + foreach_mouse_hit_point(&data, brush_length, selected); if(pset->flag & PE_KEEP_LENGTHS) - recalc_lengths(psys); + recalc_lengths(edit); break; } case PE_BRUSH_PUFF: { PEData data; - PE_set_view3d_data(C, &data); - data.dm= psmd->dm; - data.mval= mval; - data.rad= (float)brush->size; + if(edit->psys) { + PE_set_view3d_data(C, &data); + data.dm= psmd->dm; + data.mval= mval; + data.rad= (float)brush->size; - data.pufffac= (float)(brush->strength - 50) / 50.0f; - if(data.pufffac < 0.0f) - data.pufffac= 1.0f - 9.0f * data.pufffac; - else - data.pufffac= 1.0f - data.pufffac; + data.pufffac= (float)(brush->strength - 50) / 50.0f; + if(data.pufffac < 0.0f) + data.pufffac= 1.0f - 9.0f * data.pufffac; + else + data.pufffac= 1.0f - data.pufffac; - data.invert= (brush->invert ^ flip); - Mat4Invert(ob->imat, ob->obmat); + data.invert= (brush->invert ^ flip); + Mat4Invert(ob->imat, ob->obmat); - foreach_mouse_hit_particle(&data, brush_puff, selected); + foreach_mouse_hit_point(&data, brush_puff, selected); + } break; } case PE_BRUSH_ADD: { PEData data; - if(psys->part->from==PART_FROM_FACE) { + if(edit->psys && edit->psys->part->from==PART_FROM_FACE) { PE_set_view3d_data(C, &data); data.mval= mval; brush_add(&data, brush->strength); if(pset->flag & PE_KEEP_LENGTHS) - recalc_lengths(psys); + recalc_lengths(edit); } break; } - case PE_BRUSH_WEIGHT: - { - PEData data; - - PE_set_view3d_data(C, &data); - data.mval= mval; - data.rad= (float)brush->size; - - data.weightfac= (float)(brush->strength / 100.0f); - - foreach_mouse_hit_key(&data, brush_weight, selected); - break; - } case PE_BRUSH_SMOOTH: { PEData data; @@ -3238,14 +3229,14 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } } if((pset->flag & PE_KEEP_LENGTHS)==0) - recalc_lengths(psys); + recalc_lengths(edit); if(pset->brushtype == PE_BRUSH_ADD || removed) { if(pset->brushtype == PE_BRUSH_ADD && (pset->flag & PE_X_MIRROR)) PE_mirror_x(scene, ob, 1); - psys_update_world_cos(ob,psys); - psys_free_path_cache(psys); + update_world_cos(ob,edit); + psys_free_path_cache(NULL, edit); DAG_object_flush_update(scene, ob, OB_RECALC_DATA); } else @@ -3357,104 +3348,157 @@ void PARTICLE_OT_brush_edit(wmOperatorType *ot) /*********************** undo ***************************/ -static void free_ParticleUndo(ParticleUndo *undo) +static void free_PTCacheUndo(PTCacheUndo *undo) { - ParticleData *pa; + PTCacheEditPoint *point; int i; - for(i=0, pa=undo->particles; itotpart; i++, pa++) { - if(pa->hair) - MEM_freeN(pa->hair); - if(undo->keys[i]) - MEM_freeN(undo->keys[i]); + for(i=0, point=undo->points; itotpoint; i++, point++) { + if(undo->particles && (undo->particles + i)->hair) + MEM_freeN((undo->particles + i)->hair); + if(point->keys) + MEM_freeN(point->keys); } - if(undo->keys) - MEM_freeN(undo->keys); + if(undo->points) + MEM_freeN(undo->points); if(undo->particles) MEM_freeN(undo->particles); - //if(undo->emitter_cosnos) - // MEM_freeN(undo->emitter_cosnos); + BKE_ptcache_free_mem(&undo->mem_cache); } -static void make_ParticleUndo(ParticleSystem *psys, ParticleUndo *undo) +static void make_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) { - ParticleData *pa,*upa; + PTCacheEditPoint *point; int i; - undo->totpart= psys->totpart; - undo->totkeys= psys->edit->totkeys; + undo->totpoint= edit->totpoint; - upa= undo->particles= MEM_dupallocN(psys->particles); - undo->keys= MEM_dupallocN(psys->edit->keys); - - for(i=0, pa=psys->particles; itotpart; i++, pa++, upa++) { - upa->hair= MEM_dupallocN(pa->hair); - undo->keys[i]= MEM_dupallocN(psys->edit->keys[i]); + if(edit->psys) { + ParticleData *pa; + + pa= undo->particles= MEM_dupallocN(edit->psys->particles); + + for(i=0; itotpoint; i++, pa++) + pa->hair= MEM_dupallocN(pa->hair); + } + else { + PTCacheMem *pm; + + BLI_duplicatelist(&undo->mem_cache, &edit->pid.cache->mem_cache); + pm = undo->mem_cache.first; + + for(; pm; pm=pm->next) { + for(i=0; idata[i] = MEM_dupallocN(pm->data[i]); + } + } + + point= undo->points = MEM_dupallocN(edit->points); + undo->totpoint = edit->totpoint; + + for(i=0; itotpoint; i++, point++) { + point->keys= MEM_dupallocN(point->keys); /* no need to update edit key->co & key->time pointers here */ } } -static void get_ParticleUndo(ParticleSystem *psys, ParticleUndo *undo) +static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) { - ParticleData *pa, *upa; - ParticleEditKey *key; + ParticleSystem *psys = edit->psys; + ParticleData *pa; HairKey *hkey; - int i, k, totpart= psys->totpart; + POINT_P; KEY_K; - LOOP_PARTICLES(i, pa) { - if(pa->hair) - MEM_freeN(pa->hair); + LOOP_POINTS { + if(psys && psys->particles[p].hair) + MEM_freeN(psys->particles[p].hair); - if(psys->edit->keys[i]) - MEM_freeN(psys->edit->keys[i]); + if(point->keys) + MEM_freeN(point->keys); } - if(psys->particles) + if(psys && psys->particles) MEM_freeN(psys->particles); - if(psys->edit->keys) - MEM_freeN(psys->edit->keys); - if(psys->edit->mirror_cache) { - MEM_freeN(psys->edit->mirror_cache); - psys->edit->mirror_cache= NULL; + if(edit->points) + MEM_freeN(edit->points); + if(edit->mirror_cache) { + MEM_freeN(edit->mirror_cache); + edit->mirror_cache= NULL; } - pa= psys->particles= MEM_dupallocN(undo->particles); - psys->edit->keys= MEM_dupallocN(undo->keys); + edit->points= MEM_dupallocN(undo->points); + edit->totpoint = undo->totpoint; - for(i=0,upa=undo->particles; itotpart; i++, upa++, pa++) { - hkey= pa->hair= MEM_dupallocN(upa->hair); - key= psys->edit->keys[i]= MEM_dupallocN(undo->keys[i]); - for(k=0; ktotkey; k++, hkey++, key++) { - key->co= hkey->co; - key->time= &hkey->time; + LOOP_POINTS { + point->keys= MEM_dupallocN(point->keys); + } + + if(psys) { + psys->particles= MEM_dupallocN(undo->particles); + + psys->totpart= undo->totpoint; + + LOOP_POINTS { + pa = psys->particles + p; + hkey= pa->hair = MEM_dupallocN(pa->hair); + + LOOP_KEYS { + key->co= hkey->co; + key->time= &hkey->time; + hkey++; + } } } + else { + PTCacheMem *pm; + int i; + + BKE_ptcache_free_mem(&edit->pid.cache->mem_cache); + + BLI_duplicatelist(&edit->pid.cache->mem_cache, &undo->mem_cache); + + pm = edit->pid.cache->mem_cache.first; - psys->totpart= undo->totpart; - psys->edit->totkeys= undo->totkeys; + for(; pm; pm=pm->next) { + for(i=0; idata[i] = MEM_dupallocN(pm->data[i]); + + BKE_ptcache_mem_init_pointers(pm); + + LOOP_POINTS { + LOOP_KEYS { + if((int)key->ftime == pm->frame) { + key->co = pm->cur[BPHYS_DATA_LOCATION]; + key->vel = pm->cur[BPHYS_DATA_VELOCITY]; + key->rot = pm->cur[BPHYS_DATA_ROTATION]; + key->time = &key->ftime; + } + } + BKE_ptcache_mem_incr_pointers(pm); + } + } + } } void PE_undo_push(Scene *scene, char *str) { - ParticleSystem *psys= PE_get_current(scene, OBACT); - ParticleEdit *edit= 0; - ParticleUndo *undo; + PTCacheEdit *edit= PE_get_current(scene, OBACT); + PTCacheUndo *undo; int nr; - if(!PE_can_edit(psys)) return; - edit= psys->edit; + if(!edit) return; /* remove all undos after (also when curundo==NULL) */ while(edit->undo.last != edit->curundo) { undo= edit->undo.last; BLI_remlink(&edit->undo, undo); - free_ParticleUndo(undo); + free_PTCacheUndo(undo); MEM_freeN(undo); } /* make new */ - edit->curundo= undo= MEM_callocN(sizeof(ParticleUndo), "particle undo file"); + edit->curundo= undo= MEM_callocN(sizeof(PTCacheUndo), "particle undo file"); strncpy(undo->name, str, 64-1); BLI_addtail(&edit->undo, undo); @@ -3468,27 +3512,25 @@ void PE_undo_push(Scene *scene, char *str) } if(undo) { while(edit->undo.first!=undo) { - ParticleUndo *first= edit->undo.first; + PTCacheUndo *first= edit->undo.first; BLI_remlink(&edit->undo, first); - free_ParticleUndo(first); + free_PTCacheUndo(first); MEM_freeN(first); } } /* copy */ - make_ParticleUndo(psys,edit->curundo); + make_PTCacheUndo(edit,edit->curundo); } void PE_undo_step(Scene *scene, int step) { - ParticleSystem *psys= PE_get_current(scene, OBACT); - ParticleEdit *edit= 0; + PTCacheEdit *edit= PE_get_current(scene, OBACT); - if(!PE_can_edit(psys)) return; - edit= psys->edit; + if(!edit) return; if(step==0) { - get_ParticleUndo(psys,edit->curundo); + get_PTCacheUndo(edit,edit->curundo); } else if(step==1) { @@ -3496,7 +3538,7 @@ void PE_undo_step(Scene *scene, int step) else { if(G.f & G_DEBUG) printf("undo %s\n", edit->curundo->name); edit->curundo= edit->curundo->prev; - get_ParticleUndo(psys, edit->curundo); + get_PTCacheUndo(edit, edit->curundo); } } else { @@ -3504,18 +3546,19 @@ void PE_undo_step(Scene *scene, int step) if(edit->curundo==NULL || edit->curundo->next==NULL); else { - get_ParticleUndo(psys, edit->curundo->next); + get_PTCacheUndo(edit, edit->curundo->next); edit->curundo= edit->curundo->next; if(G.f & G_DEBUG) printf("redo %s\n", edit->curundo->name); } } + PE_update_object(scene, OBACT, 0); DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); } -static void ParticleUndo_number(Scene *scene, ParticleEdit *edit, int nr) +static void PTCacheUndo_number(Scene *scene, PTCacheEdit *edit, int nr) { - ParticleUndo *undo; + PTCacheUndo *undo; int a=1; for(undo= edit->undo.first; undo; undo= undo->next, a++) { @@ -3525,20 +3568,15 @@ static void ParticleUndo_number(Scene *scene, ParticleEdit *edit, int nr) PE_undo_step(scene, 0); } -static void ParticleUndo_clear(ParticleSystem *psys) +static void PTCacheUndo_clear(PTCacheEdit *edit) { - ParticleUndo *undo; - ParticleEdit *edit; - - if(psys==0) return; - - edit= psys->edit; + PTCacheUndo *undo; if(edit==0) return; undo= edit->undo.first; while(undo) { - free_ParticleUndo(undo); + free_PTCacheUndo(undo); undo= undo->next; } BLI_freelistN(&edit->undo); @@ -3557,15 +3595,13 @@ void PE_redo(Scene *scene) void PE_undo_menu(Scene *scene, Object *ob) { - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleEdit *edit= 0; - ParticleUndo *undo; + PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheUndo *undo; DynStr *ds; short event=0; char *menu; - if(!PE_can_edit(psys)) return; - edit= psys->edit; + if(!edit) return; ds= BLI_dynstr_new(); @@ -3582,7 +3618,7 @@ void PE_undo_menu(Scene *scene, Object *ob) // XXX event= pupmenu_col(menu, 20); MEM_freeN(menu); - if(event>0) ParticleUndo_number(scene, edit,event); + if(event>0) PTCacheUndo_number(scene, edit, event); } /************************ utilities ******************************/ @@ -3590,30 +3626,29 @@ void PE_undo_menu(Scene *scene, Object *ob) int PE_minmax(Scene *scene, float *min, float *max) { Object *ob= OBACT; - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleSystemModifierData *psmd; - ParticleData *pa; - ParticleEditKey *key; + PTCacheEdit *edit= PE_get_current(scene, ob); + ParticleSystem *psys = edit->psys; + ParticleSystemModifierData *psmd = NULL; + POINT_P; KEY_K; float co[3], mat[4][4]; - int i, k, totpart, ok= 0; + int ok= 0; - if(!PE_can_edit(psys)) return ok; + if(!edit) return ok; - psmd= psys_get_modifier(ob, psys); - totpart= psys->totpart; - - LOOP_PARTICLES(i, pa) { - if(pa->flag & PARS_HIDE) continue; + if(psys) + psmd= psys_get_modifier(ob, psys); + else + Mat4One(mat); - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat); + LOOP_VISIBLE_POINTS { + if(psys) + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, mat); - LOOP_KEYS(k, key) { - if(key->flag & PEK_SELECT) { - VECCOPY(co, key->co); - Mat4MulVecfl(mat, co); - DO_MINMAX(co, min, max); - ok= 1; - } + LOOP_SELECTED_KEYS { + VECCOPY(co, key->co); + Mat4MulVecfl(mat, co); + DO_MINMAX(co, min, max); + ok= 1; } } @@ -3628,56 +3663,106 @@ int PE_minmax(Scene *scene, float *min, float *max) /************************ particle edit toggle operator ************************/ /* initialize needed data for bake edit */ -static void PE_create_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys) +static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys) { - ParticleEdit *edit= psys->edit; - ParticleData *pa; - ParticleEditKey *key; + PTCacheEdit *edit= psys ? psys->edit : cache->edit; + POINT_P; KEY_K; + ParticleData *pa = NULL; HairKey *hkey; - int i, k, totpart= psys->totpart, alloc=1; + int totpoint; - if((psys->flag & PSYS_EDITED)==0) + if(!psys && !cache) return; - if(edit) { - int newtotkeys= psys_count_keys(psys); + if(cache && cache->flag & PTCACHE_DISK_CACHE) + return; - if(newtotkeys == edit->totkeys) - alloc=0; - } + if(!edit) { + totpoint = psys ? psys->totpart : ((PTCacheMem*)cache->mem_cache.first)->totpoint; - if(alloc) { - if(edit) { - printf("ParticleEdit exists already! Poke jahka!"); - PE_free_particle_edit(psys); - } + edit= MEM_callocN(sizeof(PTCacheEdit), "PE_create_particle_edit"); + edit->points=MEM_callocN(totpoint*sizeof(PTCacheEditPoint),"PTCacheEditPoints"); + edit->totpoint = totpoint; - edit= psys->edit=MEM_callocN(sizeof(ParticleEdit), "PE_create_particle_edit"); - psys->free_edit= PE_free_particle_edit; + if(psys && !cache) { + psys->edit= edit; + edit->psys = psys; - edit->keys=MEM_callocN(totpart*sizeof(ParticleEditKey*),"ParticleEditKey array"); + psys->free_edit= PE_free_ptcache_edit; - LOOP_PARTICLES(i, pa) { - key= edit->keys[i]= MEM_callocN(pa->totkey*sizeof(ParticleEditKey),"ParticleEditKeys"); - for(k=0, hkey=pa->hair; ktotkey; k++, hkey++, key++) { - key->co= hkey->co; - key->time= &hkey->time; - key->flag= hkey->editflag; + edit->pathcache = NULL; + edit->pathcachebufs.first = edit->pathcachebufs.last = NULL; + + pa = psys->particles; + LOOP_POINTS { + point->totkey = pa->totkey; + point->keys= MEM_callocN(point->totkey*sizeof(PTCacheEditKey),"ParticleEditKeys"); + point->flag |= PEP_EDIT_RECALC; + + hkey = pa->hair; + LOOP_KEYS { + key->co= hkey->co; + key->time= &hkey->time; + key->flag= hkey->editflag; + key->flag |= PEK_USE_WCO; + hkey++; + } + pa++; } } + else { + PTCacheMem *pm; + int totframe=0; + + cache->edit= edit; + cache->free_edit= PE_free_ptcache_edit; + edit->psys = NULL; + + for(pm=cache->mem_cache.first; pm; pm=pm->next) + totframe++; + + for(pm=cache->mem_cache.first; pm; pm=pm->next) { + BKE_ptcache_mem_init_pointers(pm); + + LOOP_POINTS { + if(psys) { + pa = psys->particles + p; + if((pm->next && pm->next->frame < pa->time) + || (pm->prev && pm->prev->frame >= pa->dietime)) { + BKE_ptcache_mem_incr_pointers(pm); + continue; + } + } + + if(!point->totkey) { + key = point->keys = MEM_callocN(totframe*sizeof(PTCacheEditKey),"ParticleEditKeys"); + point->flag |= PEP_EDIT_RECALC; + } + else + key = point->keys + point->totkey; - edit->totkeys= psys_count_keys(psys); + key->co = pm->cur[BPHYS_DATA_LOCATION]; + key->vel = pm->cur[BPHYS_DATA_VELOCITY]; + key->rot = pm->cur[BPHYS_DATA_ROTATION]; + key->ftime = (float)pm->frame; + key->time = &key->ftime; + BKE_ptcache_mem_incr_pointers(pm); + + point->totkey++; + } + } + psys = NULL; + } UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col); UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col); - } - recalc_lengths(psys); - recalc_emitter_field(ob, psys); - psys_update_world_cos(ob, psys); + recalc_lengths(edit); + if(psys && !cache) + recalc_emitter_field(ob, psys); + PE_update_object(scene, ob, 1); - if(alloc) { - ParticleUndo_clear(psys); + PTCacheUndo_clear(edit); PE_undo_push(scene, "Original"); } } @@ -3690,30 +3775,16 @@ static int particle_edit_toggle_poll(bContext *C) if(!scene || !ob || ob->id.lib) return 0; - return (ob->particlesystem.first != NULL); + return (ob->particlesystem.first || modifiers_findByType(ob, eModifierType_Cloth) || modifiers_findByType(ob, eModifierType_Softbody)); } static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); - - if(psys==NULL) { - psys= ob->particlesystem.first; - psys->flag |= PSYS_CURRENT; - } + PTCacheEdit *edit= PE_get_current(scene, ob, PE_settings(scene)->edittype); if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { - if(psys && psys->part->type == PART_HAIR && psys->flag & PSYS_EDITED) { - if(psys_check_enabled(ob, psys)) { - if(psys->edit==NULL) - PE_create_particle_edit(scene, ob, psys); - - psys_update_world_cos(ob, psys); - } - } - ob->mode |= OB_MODE_PARTICLE_EDIT; toggle_particle_cursor(C, 1); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL); @@ -3746,112 +3817,65 @@ void PARTICLE_OT_particle_edit_toggle(wmOperatorType *ot) /************************ set editable operator ************************/ -static int set_editable_exec(bContext *C, wmOperator *op) +static int clear_edited_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - ParticleSystem *psys= PE_get_current(scene, ob); + ParticleSystem *psys = psys_get_current(ob); - if(psys->flag & PSYS_EDITED) { - if(1) { // XXX okee("Lose changes done in particle mode?")) { - if(psys->edit) - PE_free_particle_edit(psys); + if(psys->edit) { + if(psys->edit->edited || 1) { // XXX okee("Lose changes done in particle mode?")) + PE_free_ptcache_edit(psys->edit); + + psys->edit = NULL; + psys->free_edit = NULL; - psys->flag &= ~PSYS_EDITED; psys->recalc |= PSYS_RECALC_RESET; + psys_reset(psys, PSYS_RESET_DEPSGRAPH); DAG_object_flush_update(scene, ob, OB_RECALC_DATA); } } - else { - if(psys_check_enabled(ob, psys)) { - psys->flag |= PSYS_EDITED; - - if(ob->mode & OB_MODE_PARTICLE_EDIT) - PE_create_particle_edit(scene, ob, psys); - } - else - BKE_report(op->reports, RPT_ERROR, "Particle system not enabled, skipping set editable"); - } return OPERATOR_FINISHED; } -void PARTICLE_OT_editable_set(wmOperatorType *ot) +void PARTICLE_OT_edited_clear(wmOperatorType *ot) { /* identifiers */ - ot->name= "Set Editable"; - ot->idname= "PARTICLE_OT_editable_set"; + ot->name= "Clear Edited"; + ot->idname= "PARTICLE_OT_edited_clear"; /* api callbacks */ - ot->exec= set_editable_exec; + ot->exec= clear_edited_exec; ot->poll= particle_edit_toggle_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/*********************** change active **************************/ - -void PE_change_act(void *ob_v, void *act_v) -{ - Scene *scene= NULL; // XXX - Object *ob= ob_v; - ParticleSystem *psys; - short act= *((short*)act_v) - 1; - - if((psys=psys_get_current(ob))) - psys->flag &= ~PSYS_CURRENT; - - if(act>=0) { - if((psys=BLI_findlink(&ob->particlesystem,act))) { - psys->flag |= PSYS_CURRENT; - - if(psys_check_enabled(ob, psys)) { - if(ob->mode & OB_MODE_PARTICLE_EDIT && !psys->edit) - PE_create_particle_edit(scene, ob, psys); - psys_update_world_cos(ob, psys); - } - } - } -} - -void PE_change_act_psys(Scene *scene, Object *ob, ParticleSystem *psys) -{ - ParticleSystem *p; - - if((p=psys_get_current(ob))) - p->flag &= ~PSYS_CURRENT; - - psys->flag |= PSYS_CURRENT; - - if(psys_check_enabled(ob, psys)) { - if(ob->mode & OB_MODE_PARTICLE_EDIT && !psys->edit) - PE_create_particle_edit(scene, ob, psys); - - psys_update_world_cos(ob, psys); - } -} - /*********************** specials menu **************************/ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) { Scene *scene= CTX_data_scene(C); ParticleEditSettings *pset=PE_settings(scene); + PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C)); uiPopupMenu *pup; uiLayout *layout; pup= uiPupMenuBegin(C, "Specials", 0); layout= uiPupMenuLayout(pup); - uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); - if(pset->selectmode & SCE_SELECT_POINT) { - uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide"); - uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first"); - uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last"); + if(edit->psys) { + uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); + if(pset->selectmode & SCE_SELECT_POINT) { + uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide"); + uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first"); + uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last"); + } + uiItemO(layout, NULL, 0, "PARTICLE_OT_remove_doubles"); } - uiItemO(layout, NULL, 0, "PARTICLE_OT_remove_doubles"); uiPupMenuEnd(C, pup); @@ -3896,7 +3920,7 @@ void ED_operatortypes_particle(void) WM_operatortype_append(PARTICLE_OT_specials_menu); WM_operatortype_append(PARTICLE_OT_particle_edit_toggle); - WM_operatortype_append(PARTICLE_OT_editable_set); + WM_operatortype_append(PARTICLE_OT_edited_clear); } void ED_keymap_particle(wmWindowManager *wm) diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index fca5b0cc59a..e6cd9c0e448 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -2120,9 +2120,7 @@ static int tree_element_active_psys(bContext *C, Scene *scene, TreeElement *te, { if(set) { Object *ob= (Object *)tselem->id; - ParticleSystem *psys= te->directdata; - PE_change_act_psys(scene, ob, psys); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); // XXX extern_set_butspace(F7KEY, 0); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6cf229ead31..e49616fc740 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -89,6 +89,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_property.h" #include "BKE_smoke.h" #include "BKE_unit.h" @@ -3138,6 +3139,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv { Object *ob=base->object; ParticleSystemModifierData *psmd; + ParticleEditSettings *pset = PE_settings(scene); ParticleSettings *part; ParticleData *pars, *pa; ParticleKey state, *states=0; @@ -3166,9 +3168,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(pars==0) return; - // XXX what logic is this? - if(!scene->obedit && psys_in_edit_mode(scene, psys) - && psys->flag & PSYS_HAIR_DONE && part->draw_as==PART_DRAW_PATH) + /* don't draw normal paths in edit mode */ + if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0) return; if(part->draw_as==PART_DRAW_NOT) return; @@ -3709,33 +3710,27 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv wmLoadMatrix(rv3d->viewmat); } -static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, ParticleSystem *psys, int dt) +static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, PTCacheEdit *edit, int dt) { - ParticleEdit *edit = psys->edit; - ParticleData *pa; - ParticleCacheKey **path; - ParticleEditKey *key; + ParticleCacheKey **cache, *path, *pkey; + PTCacheEditPoint *point; + PTCacheEditKey *key; ParticleEditSettings *pset = PE_settings(scene); - int i, k, totpart = psys->totpart, totchild=0, timed = pset->draw_timed; + int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ? pset->fade_frames : 0; + int steps; char nosel[4], sel[4]; float sel_col[3]; float nosel_col[3]; - char val[32]; + float *pathcol = NULL, *pcol; /* create path and child path cache if it doesn't exist already */ - if(psys->pathcache==0){ - PE_hide_keys_time(scene, psys,CFRA); - psys_cache_paths(scene, ob, psys, CFRA,0); - } - if(psys->pathcache==0) + if(edit->pathcache==0) + psys_cache_edit_paths(scene, ob, edit, CFRA); + + if(edit->pathcache==0) return; - if(pset->flag & PE_SHOW_CHILD && psys->part->draw_as == PART_DRAW_PATH) { - if(psys->childcache==0) - psys_cache_child_paths(scene, ob, psys, CFRA, 0); - } - else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache) - free_child_path_cache(psys); + PE_hide_keys_time(scene, edit, CFRA); /* opengl setup */ if((v3d->flag & V3D_ZBUF_SELECT)==0) @@ -3751,65 +3746,50 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob nosel_col[1]=(float)nosel[1]/255.0f; nosel_col[2]=(float)nosel[2]/255.0f; - if(psys->childcache) - totchild = psys->totchildcache; /* draw paths */ - if(timed) + if(timed) { glEnable(GL_BLEND); + steps = (*edit->pathcache)->steps + 1; + pathcol = MEM_callocN(steps*4*sizeof(float), "particle path color data"); + } glEnableClientState(GL_VERTEX_ARRAY); - if(dt > OB_WIRE) { - /* solid shaded with lighting */ - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + /* solid shaded with lighting */ + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - } - else { - /* flat wire color */ - glDisableClientState(GL_NORMAL_ARRAY); - glDisable(GL_LIGHTING); - UI_ThemeColor(TH_WIRE); - } + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); /* only draw child paths with lighting */ if(dt > OB_WIRE) glEnable(GL_LIGHTING); - if(psys->part->draw_as == PART_DRAW_PATH) { - for(i=0, path=psys->childcache; ico); - if(dt > OB_WIRE) { - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + /* draw paths without lighting */ + cache=edit->pathcache; + for(i=0; ico); + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); + + if(timed) { + for(k=0, pcol=pathcol, pkey=path; kcol); + pcol[3] = 1.0f - fabs((float)CFRA - pkey->time)/(float)pset->fade_frames; } - glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); + glColorPointer(4, GL_FLOAT, 4*sizeof(float), pathcol); } - } - - if(dt > OB_WIRE) - glDisable(GL_LIGHTING); + else + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); - if(pset->brushtype == PE_BRUSH_WEIGHT) { - glLineWidth(2.0f); - glEnableClientState(GL_COLOR_ARRAY); - glDisable(GL_LIGHTING); + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } - /* draw parents last without lighting */ - for(i=0, pa=psys->particles, path = psys->pathcache; ico); - if(dt > OB_WIRE) - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - if(dt > OB_WIRE || pset->brushtype == PE_BRUSH_WEIGHT) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + if(pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; } - glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); - } /* draw edit vertices */ if(pset->selectmode!=SCE_SELECT_PATH){ @@ -3819,61 +3799,74 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); if(pset->selectmode==SCE_SELECT_POINT){ + float *pd=0,*pdata=0; float *cd=0,*cdata=0; - cd=cdata=MEM_callocN(edit->totkeys*(timed?4:3)*sizeof(float), "particle edit color data"); + int totkeys = 0; + + for (i=0, point=edit->points; iflag & PEP_HIDE)) + totkeys += point->totkey; + + if(!edit->psys) + pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data"); + cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data"); + + for(i=0, point=edit->points; iflag & PEP_HIDE) + continue; + + for(k=0, key=point->keys; ktotkey; k++, key++){ + if(pd) { + VECCOPY(pd, key->co); + pd += 3; + } - for(i=0, pa=psys->particles; ikeys[i]; ktotkey; k++, key++){ if(key->flag&PEK_SELECT){ VECCOPY(cd,sel_col); } else{ VECCOPY(cd,nosel_col); } + if(timed) - *(cd+3) = (key->flag&PEK_HIDE)?0.0f:1.0f; + *(cd+3) = 1.0f - fabs((float)CFRA - *key->time)/(float)pset->fade_frames; + cd += (timed?4:3); } } cd=cdata; - for(i=0, pa=psys->particles; iflag & PARS_HIDE)==0){ - glVertexPointer(3, GL_FLOAT, sizeof(ParticleEditKey), edit->keys[i]->world_co); - glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd); - glDrawArrays(GL_POINTS, 0, pa->totkey); - } - cd += (timed?4:3) * pa->totkey; + pd=pdata; + for(i=0, point=edit->points; iflag & PEP_HIDE) + continue; - if((pset->flag&PE_SHOW_TIME) && (pa->flag&PARS_HIDE)==0 && !(G.f & G_RENDER_SHADOW)){ - for(k=0, key=edit->keys[i]+k; ktotkey; k++, key++){ - if(key->flag & PEK_HIDE) continue; + if(edit->psys) + glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co); + else + glVertexPointer(3, GL_FLOAT, 3*sizeof(float), pd); - sprintf(val," %.1f",*key->time); - view3d_particle_text_draw_add(key->world_co[0], key->world_co[1], key->world_co[2], val, 0); - } - } + glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd); + + glDrawArrays(GL_POINTS, 0, point->totkey); + + pd += pd ? 3 * point->totkey : 0; + cd += (timed?4:3) * point->totkey; } - if(cdata) - MEM_freeN(cdata); - cd=cdata=0; + if(pdata) { MEM_freeN(pdata); pd=pdata=0; } + if(cdata) { MEM_freeN(cdata); cd=cdata=0; } } else if(pset->selectmode == SCE_SELECT_END){ - for(i=0, pa=psys->particles; iflag & PARS_HIDE)==0){ - key = edit->keys[i] + pa->totkey - 1; + for(i=0, point=edit->points; iflag & PEP_HIDE)==0){ + key = point->keys + point->totkey - 1; if(key->flag & PEK_SELECT) glColor3fv(sel_col); else glColor3fv(nosel_col); /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/ glBegin(GL_POINTS); - glVertex3fv(key->world_co); + glVertex3fv(key->flag & PEK_USE_WCO ? key->world_co : key->co); glEnd(); - - if((pset->flag & PE_SHOW_TIME) && !(G.f & G_RENDER_SHADOW)){ - sprintf(val," %.1f",*key->time); - view3d_particle_text_draw_add(key->world_co[0], key->world_co[1], key->world_co[2], val, 0); - } } } } @@ -5298,11 +5291,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) for(psys=ob->particlesystem.first; psys; psys=psys->next) draw_new_particle_system(scene, v3d, rv3d, base, psys, dt); - if(ob->mode & OB_MODE_PARTICLE_EDIT && ob==OBACT) { - psys= PE_get_current(scene, ob); - if(psys && !scene->obedit && psys_in_edit_mode(scene, psys)) - draw_particle_edit(scene, v3d, rv3d, ob, psys, dt); - } view3d_particle_text_draw(v3d, ar); wmMultMatrix(ob->obmat); @@ -5310,6 +5298,21 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) //glDepthMask(GL_TRUE); if(col) cpack(col); } + + if( (warning_recursive==0) && + (flag & DRAW_PICKING)==0 && + (!scene->obedit) + ) { + + if(ob->mode & OB_MODE_PARTICLE_EDIT && ob==OBACT) { + PTCacheEdit *edit = PE_get_current(scene, ob); + if(edit) { + wmLoadMatrix(rv3d->viewmat); + draw_ptcache_edit(scene, v3d, rv3d, ob, edit, dt); + wmMultMatrix(ob->obmat); + } + } + } /* draw code for smoke */ { diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index eee85f21798..305b6956037 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1571,7 +1571,7 @@ static char *view3d_modeselect_pup(Scene *scene) str += sprintf(str, formatstr, "Pose Mode", OB_MODE_POSE, ICON_POSE_HLT); } - if (ob->particlesystem.first) { + if (ob->particlesystem.first || modifiers_findByType(ob, eModifierType_Cloth) || modifiers_findByType(ob, eModifierType_Softbody)) { str += sprintf(str, formatstr, "Particle Mode", OB_MODE_PARTICLE_EDIT, ICON_PARTICLEMODE); } @@ -1661,6 +1661,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) ScrArea *sa= CTX_wm_area(C); View3D *v3d= sa->spacedata.first; Object *obedit = CTX_data_edit_object(C); + Object *ob = CTX_data_active_object(C); EditMesh *em= NULL; int bit, ctrl= win->eventstate->ctrl, shift= win->eventstate->shift; PointerRNA props_ptr; @@ -1759,14 +1760,17 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) case B_SEL_PATH: ts->particle.selectmode= SCE_SELECT_PATH; + WM_event_add_notifier(C, NC_OBJECT, ob); ED_undo_push(C, "Selectmode Set: Path"); break; case B_SEL_POINT: ts->particle.selectmode = SCE_SELECT_POINT; + WM_event_add_notifier(C, NC_OBJECT, ob); ED_undo_push(C, "Selectmode Set: Point"); break; case B_SEL_END: ts->particle.selectmode = SCE_SELECT_END; + WM_event_add_notifier(C, NC_OBJECT, ob); ED_undo_push(C, "Selectmode Set: End point"); break; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 5c5b7281f20..aaede541b76 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1617,31 +1617,32 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) TransDataExtension *tx; Base *base = CTX_data_active_base(C); Object *ob = CTX_data_active_object(C); - ParticleSystem *psys = PE_get_current(t->scene, ob); - ParticleSystemModifierData *psmd = NULL; ParticleEditSettings *pset = PE_settings(t->scene); - ParticleData *pa = NULL; - ParticleEdit *edit; - ParticleEditKey *key; + PTCacheEdit *edit = PE_get_current(t->scene, ob); + ParticleSystem *psys = NULL; + ParticleSystemModifierData *psmd = NULL; + PTCacheEditPoint *point; + PTCacheEditKey *key; float mat[4][4]; - int i,k, totpart, transformparticle; + int i,k, transformparticle; int count = 0, hasselected = 0; int propmode = t->flag & T_PROP_EDIT; - if(psys==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return; + if(edit==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return; - psmd = psys_get_modifier(ob,psys); + psys = edit->psys; + + if(psys) + psmd = psys_get_modifier(ob,psys); - edit = psys->edit; - totpart = psys->totpart; base->flag |= BA_HAS_RECALC_DATA; - for(i=0, pa=psys->particles; iflag &= ~PARS_TRANSFORM; + for(i=0, point=edit->points; itotpoint; i++, point++) { + point->flag &= ~PEP_TRANSFORM; transformparticle= 0; - if((pa->flag & PARS_HIDE)==0) { - for(k=0, key=edit->keys[i]; ktotkey; k++, key++) { + 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; @@ -1654,8 +1655,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) } if(transformparticle) { - count += pa->totkey; - pa->flag |= PARS_TRANSFORM; + count += point->totkey; + point->flag |= PEP_TRANSFORM; } } @@ -1674,18 +1675,23 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) Mat4Invert(ob->imat,ob->obmat); - for(i=0, pa=psys->particles; ipoints; itotpoint; i++, point++) { TransData *head, *tail; head = tail = td; - if(!(pa->flag & PARS_TRANSFORM)) continue; + if(!(point->flag & PEP_TRANSFORM)) continue; - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat); + if(psys) + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat); - for(k=0, key=edit->keys[i]; ktotkey; k++, key++) { - VECCOPY(key->world_co, key->co); - Mat4MulVecfl(mat, key->world_co); - td->loc = key->world_co; + for(k=0, key=point->keys; ktotkey; k++, key++) { + if(psys) { + VECCOPY(key->world_co, key->co); + Mat4MulVecfl(mat, key->world_co); + td->loc = key->world_co; + } + else + td->loc = key->co; VECCOPY(td->iloc, td->loc); VECCOPY(td->center, td->loc); @@ -1713,7 +1719,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if(k==0) tx->size = 0; else tx->size = (key - 1)->time; - if(k == pa->totkey - 1) tx->quat = 0; + if(k == point->totkey - 1) tx->quat = 0; else tx->quat = (key + 1)->time; } @@ -1731,35 +1737,42 @@ void flushTransParticles(TransInfo *t) { Scene *scene = t->scene; Object *ob = OBACT; - ParticleSystem *psys = PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); + ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd; - ParticleData *pa; - ParticleEditKey *key; + PTCacheEditPoint *point; + PTCacheEditKey *key; TransData *td; float mat[4][4], imat[4][4], co[3]; int i, k, propmode = t->flag & T_PROP_EDIT; - psmd = psys_get_modifier(ob, psys); + if(psys) + psmd = psys_get_modifier(ob, psys); /* we do transform in world space, so flush world space position - * back to particle local space */ + * back to particle local space (only for hair particles) */ td= t->data; - for(i=0, pa=psys->particles; itotpart; i++, pa++, td++) { - if(!(pa->flag & PARS_TRANSFORM)) continue; + for(i=0, point=edit->points; itotpoint; i++, point++, td++) { + if(!(point->flag & PEP_TRANSFORM)) continue; + + if(psys) { + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat); + Mat4Invert(imat,mat); - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat); - Mat4Invert(imat,mat); + for(k=0, key=point->keys; ktotkey; k++, key++) { + VECCOPY(co, key->world_co); + Mat4MulVecfl(imat, co); - for(k=0, key=psys->edit->keys[i]; ktotkey; k++, key++) { - VECCOPY(co, key->world_co); - Mat4MulVecfl(imat, co); - /* optimization for proportional edit */ - if(!propmode || !FloatCompare(key->co, co, 0.0001f)) { - VECCOPY(key->co, co); - pa->flag |= PARS_EDIT_RECALC; + /* optimization for proportional edit */ + if(!propmode || !FloatCompare(key->co, co, 0.0001f)) { + VECCOPY(key->co, co); + point->flag |= PEP_EDIT_RECALC; + } } } + else + point->flag |= PEP_EDIT_RECALC; } PE_update_object(scene, OBACT, 1); @@ -5256,7 +5269,8 @@ void createTransData(bContext *C, TransInfo *t) } CTX_DATA_END; } - else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_can_edit(PE_get_current(scene, ob))) { + else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) + && PE_start_edit(PE_get_current(scene, ob))) { createTransParticleVerts(C, t); if(t->data && t->flag & T_PROP_EDIT) { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 37fd79e38e1..e4ec43a8f38 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -62,6 +62,7 @@ #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_utildefines.h" #include "BLI_arithb.h" @@ -362,18 +363,19 @@ int calc_manipulator_stats(const bContext *C) ; } else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) { - ParticleSystem *psys= PE_get_current(scene, ob); - ParticleData *pa = psys->particles; - ParticleEditKey *ek; + PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEditPoint *point; + PTCacheEditKey *ek; int k; - if(psys->edit) { - for(a=0; atotpart; a++,pa++) { - if(pa->flag & PARS_HIDE) continue; + if(edit) { + point = edit->points; + for(a=0; atotpoint; a++,point++) { + if(point->flag & PEP_HIDE) continue; - for(k=0, ek=psys->edit->keys[a]; ktotkey; k++, ek++) { + for(k=0, ek=point->keys; ktotkey; k++, ek++) { if(ek->flag & PEK_SELECT) { - calc_tw_center(scene, ek->world_co); + calc_tw_center(scene, ek->flag & PEK_USE_WCO ? ek->world_co : ek->co); totsel++; } } diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 625864c4888..5696f82ab0d 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -95,7 +95,7 @@ typedef struct PartDeflect { typedef struct PTCacheMem { struct PTCacheMem *next, *prev; int frame, totpoint; - unsigned int data_types, rt; + unsigned int data_types, flag; int *index_array; /* quick access to stored points with index */ void *data[8]; /* BPHYS_TOT_DATA */ @@ -121,6 +121,9 @@ typedef struct PointCache { char info[64]; char path[240]; /* file path */ struct ListBase mem_cache; + + struct PTCacheEdit *edit; + void (*free_edit)(struct PTCacheEdit *edit); /* free callback */ } PointCache; typedef struct SBVertex { @@ -300,8 +303,8 @@ typedef struct SoftBody { #define PTCACHE_OUTDATED 2 #define PTCACHE_SIMULATION_VALID 4 #define PTCACHE_BAKING 8 -#define PTCACHE_BAKE_EDIT 16 -#define PTCACHE_BAKE_EDIT_ACTIVE 32 +//#define PTCACHE_BAKE_EDIT 16 +//#define PTCACHE_BAKE_EDIT_ACTIVE 32 #define PTCACHE_DISK_CACHE 64 #define PTCACHE_QUICK_CACHE 128 #define PTCACHE_FRAMES_SKIPPED 256 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 925fd31328d..12c253a7cb8 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -194,8 +194,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in ParticleData *particles; /* (parent) particles */ ChildParticle *child; /* child particles */ - struct ParticleEdit *edit; /* particle editmode (runtime) */ - void (*free_edit)(struct ParticleSystem *sys); /* free callback */ + struct PTCacheEdit *edit; /* particle editmode (runtime) */ + void (*free_edit)(struct PTCacheEdit *edit); /* free callback */ struct ParticleCacheKey **pathcache; /* path cache (runtime) */ struct ParticleCacheKey **childcache; /* child cache (runtime) */ @@ -419,7 +419,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PSYS_DELETE 256 /* remove particlesystem as soon as possible */ #define PSYS_HAIR_DONE 512 #define PSYS_KEYED 1024 -#define PSYS_EDITED 2048 +//#define PSYS_EDITED 2048 //#define PSYS_PROTECT_CACHE 4096 #define PSYS_DISABLED 8192 @@ -427,11 +427,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PARS_UNEXIST 1 #define PARS_NO_DISP 2 #define PARS_STICKY 4 -#define PARS_TRANSFORM 8 -#define PARS_HIDE 16 -#define PARS_TAG 32 -#define PARS_REKEY 64 -#define PARS_EDIT_RECALC 128 +#define PARS_REKEY 8 /* pars->alive */ #define PARS_KILLED 0 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 20429120812..73afc3d1a53 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -488,10 +488,15 @@ typedef struct ParticleEditSettings { ParticleBrushData brush[7]; /* 7 = PE_TOT_BRUSH */ void *paintcursor; /* runtime */ - float emitterdist; - int draw_timed; + float emitterdist, rt; - int selectmode, pad; + int selectmode; + int edittype; + + int draw_step, fade_frames; + + struct Scene *scene; + struct Object *object; } ParticleEditSettings; typedef struct TransformOrientation { @@ -1042,9 +1047,10 @@ typedef enum SculptFlags { #define PE_LOCK_FIRST 2 #define PE_DEFLECT_EMITTER 4 #define PE_INTERPOLATE_ADDED 8 -#define PE_SHOW_CHILD 16 -#define PE_SHOW_TIME 32 +#define PE_DRAW_PART 16 #define PE_X_MIRROR 64 +#define PE_FADE_TIME 128 +#define PE_AUTO_VELOCITY 256 /* toolsetting->particle brushtype */ #define PE_BRUSH_NONE -1 @@ -1053,11 +1059,15 @@ typedef enum SculptFlags { #define PE_BRUSH_LENGTH 2 #define PE_BRUSH_PUFF 3 #define PE_BRUSH_ADD 4 -#define PE_BRUSH_WEIGHT 5 -#define PE_BRUSH_SMOOTH 6 +#define PE_BRUSH_SMOOTH 5 /* this must equal ParticleEditSettings.brush array size */ -#define PE_TOT_BRUSH 7 +#define PE_TOT_BRUSH 6 + +/* tooksettings->particle edittype */ +#define PE_TYPE_PARTICLES 0 +#define PE_TYPE_SOFTBODY 1 +#define PE_TYPE_CLOTH 2 /* toolsettings->retopo_mode */ #define RETOPO 1 diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index e0dbc232e06..a1f35eca3c2 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -98,6 +98,7 @@ EnumPropertyItem part_hair_ren_as_items[] = { #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BLI_arithb.h" @@ -436,7 +437,30 @@ static void rna_ParticleTarget_name_get(PointerRNA *ptr, char *str) else strcpy(str, "Invalid target!"); } +static int rna_ParticleSystem_multiple_caches_get(PointerRNA *ptr) +{ + ParticleSystem *psys= (ParticleSystem*)ptr->data; + + return (psys->ptcaches.first != psys->ptcaches.last); +} +static int rna_ParticleSystem_editable_get(PointerRNA *ptr) +{ + ParticleSystem *psys= (ParticleSystem*)ptr->data; + + if(psys->part && psys->part->type==PART_HAIR) + return (psys->flag & PSYS_HAIR_DONE); + else + return (psys->pointcache->flag & PTCACHE_BAKED); +} +static int rna_ParticleSystem_edited_get(PointerRNA *ptr) +{ + ParticleSystem *psys= (ParticleSystem*)ptr->data; + if(psys->part && psys->part->type==PART_HAIR) + return (psys->edit && psys->edit->edited); + else + return (psys->pointcache->edit && psys->pointcache->edit->edited); +} EnumPropertyItem from_items[] = { {PART_FROM_VERT, "VERT", 0, "Vertexes", ""}, {PART_FROM_FACE, "FACE", 0, "Faces", ""}, @@ -725,27 +749,10 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_STICKY); RNA_def_property_ui_text(prop, "sticky", ""); - prop= RNA_def_property(srna, "transform", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_TRANSFORM); - RNA_def_property_ui_text(prop, "transform", ""); - - prop= RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_HIDE); - RNA_def_property_ui_text(prop, "hide", ""); - - prop= RNA_def_property(srna, "tag", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_TAG); - RNA_def_property_ui_text(prop, "tag", ""); - prop= RNA_def_property(srna, "rekey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_REKEY); RNA_def_property_ui_text(prop, "rekey", ""); - prop= RNA_def_property(srna, "edit_recalc", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_EDIT_RECALC); - RNA_def_property_ui_text(prop, "edit_recalc", ""); - - prop= RNA_def_property(srna, "alive_state", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "alive"); RNA_def_property_enum_items(prop, alive_items); @@ -1907,11 +1914,6 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "softflag", OB_SB_ENABLE); RNA_def_property_ui_text(prop, "Use Soft Body", "Enable use of soft body for hair physics simulation."); - prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_EDITED); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* various checks needed */ - RNA_def_property_ui_text(prop, "Editable", "For hair particle systems, finalize the hair to enable editing."); - /* reactor */ prop= RNA_def_property(srna, "reactor_target_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "target_ob"); @@ -2089,12 +2091,28 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_struct_type(prop, "PointCache"); RNA_def_property_ui_text(prop, "Point Cache", ""); + prop= RNA_def_property(srna, "multiple_caches", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ParticleSystem_multiple_caches_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Multiple Caches", "Particle system has multiple point caches"); + /* offset ob */ prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "parent"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Parent", "Use this object's coordinate system instead of global coordinate system."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + + /* hair or cache editing */ + prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ParticleSystem_editable_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Editable", "Particle system can be edited in particle mode"); + + prop= RNA_def_property(srna, "edited", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ParticleSystem_edited_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Edited", "Particle system has been edited in particle mode"); } void RNA_def_particle(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index c2c906e38f2..fabe0b647ea 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -33,8 +33,34 @@ #include "BKE_paint.h" +#include "WM_types.h" + +static EnumPropertyItem particle_edit_hair_brush_items[] = { + {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush."}, + {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs."}, + {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs."}, + {PE_BRUSH_ADD, "ADD", 0, "Add", "Add hairs."}, + {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", "Make hairs longer or shorter."}, + {PE_BRUSH_PUFF, "PUFF", 0, "Puff", "Make hairs stand up."}, + {PE_BRUSH_CUT, "CUT", 0, "Cut", "Cut hairs."}, + {0, NULL, 0, NULL, NULL}}; + +static EnumPropertyItem particle_edit_cache_brush_items[] = { + {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush."}, + {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb paths."}, + {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth paths."}, + {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", "Make paths longer or shorter."}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME +#include "BKE_context.h" +#include "BKE_pointcache.h" +#include "BKE_particle.h" +#include "BKE_depsgraph.h" + +#include "ED_particle.h" + static PointerRNA rna_ParticleEdit_brush_get(PointerRNA *ptr) { ParticleEditSettings *pset= (ParticleEditSettings*)ptr->data; @@ -46,6 +72,7 @@ static PointerRNA rna_ParticleEdit_brush_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_ParticleBrush, brush); } + static PointerRNA rna_ParticleBrush_curve_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_CurveMapping, NULL); @@ -74,6 +101,65 @@ static void rna_Paint_active_brush_set(PointerRNA *ptr, PointerRNA value) paint_brush_set(ptr->data, value.data); } +static void rna_ParticleEdit_redo(bContext *C, PointerRNA *ptr) +{ + PTCacheEdit *edit = PE_get_current(CTX_data_scene(C), CTX_data_active_object(C)); + + if(!edit) + return; + + psys_free_path_cache(NULL, edit); +} + +static void rna_ParticleEdit_update(bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + + if(ob) + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); +} + +static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Scene *scene= CTX_data_scene(C); + PTCacheEdit *edit; + + if(C==NULL) { + EnumPropertyItem *item= NULL; + int totitem= 0; + + /* needed for doc generation */ + RNA_enum_items_add(&item, &totitem, particle_edit_hair_brush_items); + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; + } + + edit = PE_get_current(scene, CTX_data_active_object(C)); + + if(edit && edit->psys) + return particle_edit_hair_brush_items; + + return particle_edit_cache_brush_items; +} + +static int rna_ParticleEdit_editable_get(PointerRNA *ptr) +{ + ParticleEditSettings *pset= (ParticleEditSettings*)ptr->data; + + return (pset->object && PE_get_current(pset->scene, pset->object)); +} +static int rna_ParticleEdit_hair_get(PointerRNA *ptr) +{ + ParticleEditSettings *pset= (ParticleEditSettings*)ptr->data; + + PTCacheEdit *edit = PE_get_current(pset->scene, pset->object); + + return (edit && edit->psys); +} #else static void rna_def_paint(BlenderRNA *brna) @@ -266,17 +352,6 @@ static void rna_def_particle_edit(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem tool_items[] = { - {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush."}, - {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs."}, - {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs."}, - {PE_BRUSH_WEIGHT, "WEIGHT", 0, "Weight", "Assign weight to hairs."}, - {PE_BRUSH_ADD, "ADD", 0, "Add", "Add hairs."}, - {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", "Make hairs longer or shorter."}, - {PE_BRUSH_PUFF, "PUFF", 0, "Puff", "Make hairs stand up."}, - {PE_BRUSH_CUT, "CUT", 0, "Cut", "Cut hairs."}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem select_mode_items[] = { {SCE_SELECT_PATH, "PATH", ICON_EDGESEL, "Path", ""}, // XXX icon {SCE_SELECT_POINT, "POINT", ICON_VERTEXSEL, "Point", ""}, // XXX icon @@ -293,6 +368,14 @@ static void rna_def_particle_edit(BlenderRNA *brna) {1, "SHRINK", 0, "Shrink", "Make hairs shorter."}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem edit_type_items[]= { + {PE_TYPE_PARTICLES, "PARTICLES", 0, "Particles", ""}, + {PE_TYPE_SOFTBODY, "SOFT_BODY", 0, "Soft body", ""}, + {PE_TYPE_CLOTH, "CLOTH", 0, "Cloth", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* edit */ srna= RNA_def_struct(brna, "ParticleEdit", NULL); @@ -301,13 +384,15 @@ static void rna_def_particle_edit(BlenderRNA *brna) prop= RNA_def_property(srna, "tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "brushtype"); - RNA_def_property_enum_items(prop, tool_items); + RNA_def_property_enum_items(prop, particle_edit_hair_brush_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_ParticleEdit_tool_itemf"); RNA_def_property_ui_text(prop, "Tool", ""); prop= RNA_def_property(srna, "selection_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "selectmode"); RNA_def_property_enum_items(prop, select_mode_items); RNA_def_property_ui_text(prop, "Selection Mode", "Particle select and display mode."); + RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_update"); prop= RNA_def_property(srna, "keep_lengths", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_KEEP_LENGTHS); @@ -326,13 +411,19 @@ static void rna_def_particle_edit(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0f, 10.0f, 10, 3); RNA_def_property_ui_text(prop, "Emitter Distance", "Distance to keep particles away from the emitter."); - prop= RNA_def_property(srna, "show_time", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_SHOW_TIME); - RNA_def_property_ui_text(prop, "Show Time", "Show time values of the baked keys."); + prop= RNA_def_property(srna, "fade_time", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_FADE_TIME); + RNA_def_property_ui_text(prop, "Fade Time", "Fade paths and keys further away from current frame."); + RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_update"); - prop= RNA_def_property(srna, "show_children", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_SHOW_CHILD); - RNA_def_property_ui_text(prop, "Show Children", "Show child particles."); + prop= RNA_def_property(srna, "auto_velocity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_AUTO_VELOCITY); + RNA_def_property_ui_text(prop, "Auto Velocity", "Calculate point velocities automatically."); + + prop= RNA_def_property(srna, "draw_particles", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_DRAW_PART); + RNA_def_property_ui_text(prop, "Draw Particles", "Draw actual particles."); + RNA_def_property_update(prop, NC_OBJECT, NULL); prop= RNA_def_property(srna, "mirror_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_X_MIRROR); @@ -353,6 +444,37 @@ static void rna_def_particle_edit(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_ParticleEdit_brush_get", NULL, NULL); RNA_def_property_ui_text(prop, "Brush", ""); + prop= RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 2, 10); + RNA_def_property_ui_text(prop, "Steps", "How many steps to draw the path with."); + RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_redo"); + + prop= RNA_def_property(srna, "fade_frames", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 2, 100); + RNA_def_property_ui_text(prop, "Frames", "How many frames to fade."); + RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_update"); + + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "edittype"); + RNA_def_property_enum_items(prop, edit_type_items); + RNA_def_property_ui_text(prop, "Type", ""); + RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_redo"); + + prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ParticleEdit_editable_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Editable", "A valid edit mode exists"); + + prop= RNA_def_property(srna, "hair", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_ParticleEdit_hair_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Hair", "Editing hair"); + + prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Object", "The edited object"); + + /* brush */ srna= RNA_def_struct(brna, "ParticleBrush", NULL); -- cgit v1.2.3 From c9041b61c5a9d98cb0880301ded867f495145366 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 29 Aug 2009 15:46:38 +0000 Subject: fix for problem building --- source/blender/editors/physics/editparticle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index dbb11f72890..c0b600edf36 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -3782,7 +3782,7 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob, PE_settings(scene)->edittype); + PTCacheEdit *edit= PE_get_current(scene, ob); if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { ob->mode |= OB_MODE_PARTICLE_EDIT; -- cgit v1.2.3 From e6f2f4db285be1ccdc9c9871171afb1f9e2a4f6c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 29 Aug 2009 17:13:06 +0000 Subject: default length for shape key list, so it looks good when empty --- release/ui/buttons_data_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py index f91d706ead7..42b637e1f9d 100644 --- a/release/ui/buttons_data_mesh.py +++ b/release/ui/buttons_data_mesh.py @@ -102,7 +102,7 @@ class DATA_PT_shape_keys(DataButtonsPanel): kb = ob.active_shape_key row = layout.row() - row.template_list(key, "keys", ob, "active_shape_key_index") + row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) col = row.column() -- cgit v1.2.3 From ea18c6ef0abcdd5841d77175a67e2611dce446b5 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sat, 29 Aug 2009 17:24:45 +0000 Subject: Code reorganization -separated vbvh, svbvh, qbvh in diferent files (before the only way to switch between them was at compile time) --- source/blender/render/extern/include/RE_raytrace.h | 2 + source/blender/render/intern/raytrace/bvh.h | 59 ++- source/blender/render/intern/raytrace/qbvh.h | 0 .../render/intern/raytrace/rayobject_hint.h | 5 + .../render/intern/raytrace/rayobject_qbvh.cpp | 100 +++++ .../render/intern/raytrace/rayobject_svbvh.cpp | 104 ++++++ .../render/intern/raytrace/rayobject_vbvh.cpp | 401 ++------------------- source/blender/render/intern/raytrace/reorganize.h | 3 + source/blender/render/intern/raytrace/svbvh.h | 108 ++---- source/blender/render/intern/raytrace/vbvh.h | 186 ++++++++++ source/blender/render/intern/source/rayshade.c | 2 +- 11 files changed, 523 insertions(+), 447 deletions(-) create mode 100644 source/blender/render/intern/raytrace/qbvh.h create mode 100644 source/blender/render/intern/raytrace/rayobject_qbvh.cpp create mode 100644 source/blender/render/intern/raytrace/rayobject_svbvh.cpp create mode 100644 source/blender/render/intern/raytrace/vbvh.h diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 864b6124db4..01b64c15058 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -102,6 +102,8 @@ RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_bvh_create(int size); /* raytrace/rayobject_bvh.c */ RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ +RayObject* RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_vbvh.c */ +RayObject* RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_vbvh.c */ RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ typedef struct LCTSHint LCTSHint; diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 55bed6f0662..21234a40673 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -26,6 +26,12 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#include "rayobject.h" +#include "MEM_guardedalloc.h" +#include "rayobject_rtbuild.h" +#include "rayobject_hint.h" + +#include #include #ifndef RE_RAYTRACE_BVH_H @@ -285,7 +291,6 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) return hit; } - /* * recursively transverse a BVH looking for a rayhit using system stack */ @@ -336,4 +341,56 @@ static int bvh_node_raycast(Node *node, Isect *isec) } */ +template +void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) +{ + assert( hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); + + if(is_leaf(node)) + { + hint->stack[hint->size++] = (RayObject*)node; + } + else + { + int childs = count_childs(node); + if(hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) + { + int result = hint_test_bb(hintObject, node->bb, node->bb+3); + if(result == HINT_RECURSE) + { + /* We are 100% sure the ray will be pass inside this node */ + bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject); + } + else if(result == HINT_ACCEPT) + { + hint->stack[hint->size++] = (RayObject*)node; + } + } + else + { + hint->stack[hint->size++] = (RayObject*)node; + } + } +} + + +template +static RayObjectAPI* bvh_get_api(int maxstacksize); + + +template +static inline RayObject *bvh_create_tree(int size) +{ + Tree *obj= (Tree*)MEM_callocN(sizeof(Tree), "BVHTree" ); + assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ + + obj->rayobj.api = bvh_get_api(DFS_STACK_SIZE); + obj->root = NULL; + + obj->node_arena = NULL; + obj->builder = rtbuild_create( size ); + + return RE_rayobject_unalignRayAPI((RayObject*) obj); +} + #endif diff --git a/source/blender/render/intern/raytrace/qbvh.h b/source/blender/render/intern/raytrace/qbvh.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/source/blender/render/intern/raytrace/rayobject_hint.h b/source/blender/render/intern/raytrace/rayobject_hint.h index cc8728a28cb..d85465aec66 100644 --- a/source/blender/render/intern/raytrace/rayobject_hint.h +++ b/source/blender/render/intern/raytrace/rayobject_hint.h @@ -26,6 +26,9 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#ifndef RE_RAYTRACE_RAYOBJECT_HINT_H +#define RE_RAYTRACE_RAYOBJECT_HINT_H + #define HINT_RECURSE 1 #define HINT_ACCEPT 0 #define HINT_DISCARD -1 @@ -63,3 +66,5 @@ inline int hint_test_bb(HintFrustum &obj, float *Nmin, float *Nmax) return HINT_ACCEPT; } */ + +#endif diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp new file mode 100644 index 00000000000..e3a15b5d7f3 --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -0,0 +1,100 @@ +#include "vbvh.h" +#include "svbvh.h" +#include "qbvh.h" +#include "reorganize.h" + +#define DFS_STACK_SIZE 256 + +struct QBVHTree +{ + RayObject rayobj; + + SVBVHNode *root; + MemArena *node_arena; + + float cost; + RTBuilder *builder; +}; + + +template<> +void bvh_done(QBVHTree *obj) +{ + rtbuild_done(obj->builder); + + //TODO find a away to exactly calculate the needed memory + MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena1); + + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena2); + BLI_memarena_use_align(arena2, 16); + + //Build and optimize the tree + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + pushup_simd(root); + obj->root = Reorganize_SVBVH(arena2).transform(root); + + //Cleanup + BLI_memarena_free(arena1); + + rtbuild_free( obj->builder ); + obj->builder = NULL; + + obj->node_arena = arena2; + obj->cost = 1.0; +} + + +template +int intersect(QBVHTree *obj, Isect* isec) +{ + //TODO renable hint support + if(RE_rayobject_isAligned(obj->root)) + return bvh_node_stack_raycast( obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); +} + +template +void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) +{ + //TODO renable hint support + { + hint->size = 0; + hint->stack[hint->size++] = (RayObject*)tree->root; + } +} +/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ +template +RayObjectAPI make_api() +{ + static RayObjectAPI api = + { + (RE_rayobject_raycast_callback) ((int(*)(Tree*,Isect*)) &intersect), + (RE_rayobject_add_callback) ((void(*)(Tree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done), + (RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free), + (RE_rayobject_merge_bb_callback)((void(*)(Tree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost), + (RE_rayobject_hint_bb_callback) ((void(*)(Tree*,LCTSHint*,float*,float*)) &bvh_hint_bb) + }; + + return api; +} + +template +RayObjectAPI* bvh_get_api(int maxstacksize) +{ + static RayObjectAPI bvh_api256 = make_api(); + + if(maxstacksize <= 1024) return &bvh_api256; + assert(maxstacksize <= 256); + return 0; +} + + +RayObject *RE_rayobject_qbvh_create(int size) +{ + return bvh_create_tree(size); +} diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp new file mode 100644 index 00000000000..df033901526 --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -0,0 +1,104 @@ +#include "vbvh.h" +#include "svbvh.h" +#include "reorganize.h" + +#define DFS_STACK_SIZE 256 + +struct SVBVHTree +{ + RayObject rayobj; + + SVBVHNode *root; + MemArena *node_arena; + + float cost; + RTBuilder *builder; +}; + + +template<> +void bvh_done(SVBVHTree *obj) +{ + rtbuild_done(obj->builder); + + //TODO find a away to exactly calculate the needed memory + MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena1); + + //Build and optimize the tree + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + + reorganize(root); + remove_useless(root, &root); + bvh_refit(root); + + pushup(root); + pushdown(root); + pushup_simd(root); + + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena2); + BLI_memarena_use_align(arena2, 16); + obj->root = Reorganize_SVBVH(arena2).transform(root); + + BLI_memarena_free(arena1); + + obj->node_arena = arena2; + obj->cost = 1.0; + + + rtbuild_free( obj->builder ); + obj->builder = NULL; +} + +template +int intersect(SVBVHTree *obj, Isect* isec) +{ + //TODO renable hint support + if(RE_rayobject_isAligned(obj->root)) + return bvh_node_stack_raycast( obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); +} + +template +void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) +{ + //TODO renable hint support + { + hint->size = 0; + hint->stack[hint->size++] = (RayObject*)tree->root; + } +} +/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ +template +RayObjectAPI make_api() +{ + static RayObjectAPI api = + { + (RE_rayobject_raycast_callback) ((int(*)(Tree*,Isect*)) &intersect), + (RE_rayobject_add_callback) ((void(*)(Tree*,RayObject*)) &bvh_add), + (RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done), + (RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free), + (RE_rayobject_merge_bb_callback)((void(*)(Tree*,float*,float*)) &bvh_bb), + (RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost), + (RE_rayobject_hint_bb_callback) ((void(*)(Tree*,LCTSHint*,float*,float*)) &bvh_hint_bb) + }; + + return api; +} + +template +RayObjectAPI* bvh_get_api(int maxstacksize) +{ + static RayObjectAPI bvh_api256 = make_api(); + + if(maxstacksize <= 1024) return &bvh_api256; + assert(maxstacksize <= 256); + return 0; +} + +RayObject *RE_rayobject_svbvh_create(int size) +{ + return bvh_create_tree(size); +} diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 6ec8fab15e4..f81ca1e5d1b 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -26,385 +26,82 @@ * * ***** END GPL LICENSE BLOCK ***** */ -#define RE_USE_HINT (0) -static int tot_pushup = 0; -static int tot_pushdown = 0; -static int tot_hints = 0; +int tot_pushup = 0; +int tot_pushdown = 0; +int tot_hints = 0; -extern "C" -{ #include +#include "rayobject.h" +#include "rayobject_rtbuild.h" +#include "RE_raytrace.h" +#include "BLI_memarena.h" #include "MEM_guardedalloc.h" #include "BKE_utildefines.h" #include "BLI_arithb.h" -#include "BLI_memarena.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" -}; -#include "rayobject_hint.h" #include "reorganize.h" #include "bvh.h" +#include "vbvh.h" #include "svbvh.h" #include +#include - -#define RE_DO_HINTS (0) -#define RAY_BB_TEST_COST (0.2f) #define DFS_STACK_SIZE 256 -//#define DYNAMIC_ALLOC_BB - - -//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ -//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ -#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ - -struct VBVHNode -{ -#ifdef DYNAMIC_ALLOC_BB - float *bb; -#else - float bb[6]; -#endif - - VBVHNode *child; - VBVHNode *sibling; -}; struct VBVHTree { RayObject rayobj; - - SVBVHNode *root; - + VBVHNode *root; MemArena *node_arena; - float cost; RTBuilder *builder; }; - - -template -struct Reorganize_VBVH -{ - Tree *tree; - - Reorganize_VBVH(Tree *t) - { - tree = t; - } - - VBVHNode *create_node() - { - VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); - return node; - } - - void copy_bb(VBVHNode *node, OldNode *old) - { - std::copy( old->bb, old->bb+6, node->bb ); - } - - VBVHNode *transform(OldNode *old) - { - if(is_leaf(old)) - return (VBVHNode*)old; - - VBVHNode *node = create_node(); - VBVHNode **child_ptr = &node->child; - node->sibling = 0; - - copy_bb(node,old); - - for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) - { - VBVHNode *n_child = transform(o_child); - *child_ptr = n_child; - if(is_leaf(n_child)) return node; - child_ptr = &n_child->sibling; - } - *child_ptr = 0; - - return node; - } -}; - - -/* - * Push nodes (used on dfs) - */ -template -inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) -{ - Node *child = node->child; - - if(is_leaf(child)) - { - stack[stack_pos++] = child; - } - else - { - while(child) - { - //Skips BB tests on primitives -/* - if(is_leaf(child->child)) - stack[stack_pos++] = child->child; - else -*/ - stack[stack_pos++] = child; - - child = child->sibling; - } - } -} - -/* - * BVH done - */ -static VBVHNode *bvh_new_node(VBVHTree *tree) -{ - VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); - - if( (((intptr_t)node) & (0x0f)) != 0 ) - { - puts("WRONG!"); - printf("%08x\n", (intptr_t)node); - } - node->sibling = NULL; - node->child = NULL; - -#ifdef DYNAMIC_ALLOC_BB - node->bb = (float*)BLI_memarena_alloc(tree->node_arena, 6*sizeof(float)); -#endif - assert(RE_rayobject_isAligned(node)); - return node; -} - - - -template -int count_childs(Node *parent) -{ - int n = 0; - for(Node *i = parent->child; i; i = i->sibling) - { - n++; - if(is_leaf(i)) - break; - } - - return n; -} - -template -void append_sibling(Node *node, Node *sibling) -{ - while(node->sibling) - node = node->sibling; - - node->sibling = sibling; -} - - -template -Node *bvh_rearrange(Tree *tree, Builder *builder) -{ - - int size = rtbuild_size(builder); - if(size == 1) - { - Node *node = bvh_new_node(tree); - INIT_MINMAX(node->bb, node->bb+3); - rtbuild_merge_bb(builder, node->bb, node->bb+3); - node->child = (VBVHNode*) rtbuild_get_primitive( builder, 0 ); - return node; - } - else - { - Node *node = bvh_new_node(tree); - - INIT_MINMAX(node->bb, node->bb+3); - rtbuild_merge_bb(builder, node->bb, node->bb+3); - - Node **child = &node->child; - - int nc = rtbuild_split(builder, 2); - assert(nc == 2); - for(int i=0; i(tree, &tmp); - child = &((*child)->sibling); - } - - *child = 0; - return node; - } -} - template<> void bvh_done(VBVHTree *obj) { rtbuild_done(obj->builder); - int needed_nodes = (rtbuild_size(obj->builder)+1)*2; - if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) - needed_nodes = BLI_MEMARENA_STD_BUFSIZE; + //TODO find a away to exactly calculate the needed memory + MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena1); - MemArena *arena1 = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(arena1); - BLI_memarena_use_align(arena1, 16); - obj->node_arena = arena1; - VBVHNode *root = bvh_rearrange( obj, obj->builder ); + //Build and optimize the tree + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + reorganize(root); remove_useless(root, &root); - printf("refit: %f\n", bvh_refit(root) ); + bvh_refit(root); pushup(root); pushdown(root); - pushup_simd(root); - //Memory re-organize - if(0) - { - MemArena *arena2 = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(arena2); - BLI_memarena_use_align(arena2, 16); - obj->node_arena = arena2; - root = Reorganize_VBVH(obj).transform(root); - - BLI_memarena_free(arena1); - } - - if(1) - { - MemArena *arena2 = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(arena2); - BLI_memarena_use_align(arena2, 16); - obj->node_arena = arena2; - obj->root = Reorganize_SVBVH(obj).transform(root); - - BLI_memarena_free(arena1); - } -/* - { - obj->root = root; - } -*/ - - obj->cost = 1.0; - + //Cleanup rtbuild_free( obj->builder ); obj->builder = NULL; + + obj->node_arena = arena1; + obj->root = root; + obj->cost = 1.0; } template int intersect(VBVHTree *obj, Isect* isec) { -/* - if(RE_DO_HINTS && isec->hint) - { - LCTSHint *lcts = (LCTSHint*)isec->hint; - isec->hint = 0; - - int hit = 0; - for(int i=0; isize; i++) - { - VBVHNode *node = (VBVHNode*)lcts->stack[i]; - if(RE_rayobject_isAligned(node)) - hit |= bvh_node_stack_raycast(node, isec); - else - hit |= RE_rayobject_intersect( (RayObject*)node, isec ); - - if(hit && isec->mode == RE_RAY_SHADOW) - break; - } - isec->hint = (RayHint*)lcts; - return hit; - } - else -*/ - { - if(RE_rayobject_isAligned(obj->root)) - return bvh_node_stack_raycast( obj->root, isec); - else - return RE_rayobject_intersect( (RayObject*) obj->root, isec ); - } -} - -template -void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject); - -template -void bvh_dfs_make_hint_push_siblings(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) -{ - if(!RE_rayobject_isAligned(node)) - hint->stack[hint->size++] = (RayObject*)node; + //TODO renable hint support + if(RE_rayobject_isAligned(obj->root)) + return bvh_node_stack_raycast( obj->root, isec); else - { - if(node->sibling) - bvh_dfs_make_hint_push_siblings(node->sibling, hint, reserve_space+1, hintObject); - - bvh_dfs_make_hint(node, hint, reserve_space, hintObject); - } -} - -template -void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) -{ - assert( hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE ); - - if(is_leaf(node)) - { - hint->stack[hint->size++] = (RayObject*)node; - } - else - { - int childs = count_childs(node); - if(hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) - { - int result = hint_test_bb(hintObject, node->bb, node->bb+3); - if(result == HINT_RECURSE) - { - /* We are 100% sure the ray will be pass inside this node */ - bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject); - } - else if(result == HINT_ACCEPT) - { - hint->stack[hint->size++] = (RayObject*)node; - } - } - else - { - hint->stack[hint->size++] = (RayObject*)node; - } - } + return RE_rayobject_intersect( (RayObject*) obj->root, isec ); } template void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *min, float *max) { -/* - if(RE_USE_HINT) - { - HintBB bb; - VECCOPY(bb.bb, min); - VECCOPY(bb.bb+3, max); - - hint->size = 0; - bvh_dfs_make_hint( tree->root, hint, 0, &bb ); - tot_hints++; - } - else -*/ + //TODO renable hint support { hint->size = 0; hint->stack[hint->size++] = (RayObject*)tree->root; @@ -428,16 +125,15 @@ void bfree(VBVHTree *tree) } /* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -template -static RayObjectAPI make_api() +template +RayObjectAPI make_api() { static RayObjectAPI api = { (RE_rayobject_raycast_callback) ((int(*)(Tree*,Isect*)) &intersect), (RE_rayobject_add_callback) ((void(*)(Tree*,RayObject*)) &bvh_add), (RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done), -// (RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free), - (RE_rayobject_free_callback) ((void(*)(Tree*)) &bfree), + (RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free), (RE_rayobject_merge_bb_callback)((void(*)(Tree*,float*,float*)) &bvh_bb), (RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost), (RE_rayobject_hint_bb_callback) ((void(*)(Tree*,LCTSHint*,float*,float*)) &bvh_hint_bb) @@ -447,7 +143,7 @@ static RayObjectAPI make_api() } template -static RayObjectAPI* get_api(int maxstacksize) +RayObjectAPI* bvh_get_api(int maxstacksize) { static RayObjectAPI bvh_api256 = make_api(); @@ -458,38 +154,5 @@ static RayObjectAPI* get_api(int maxstacksize) RayObject *RE_rayobject_vbvh_create(int size) { - VBVHTree *obj= (VBVHTree*)MEM_callocN(sizeof(VBVHTree), "VBVHTree"); - assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = get_api(DFS_STACK_SIZE); - obj->root = NULL; - - obj->node_arena = NULL; - obj->builder = rtbuild_create( size ); - - return RE_rayobject_unalignRayAPI((RayObject*) obj); -} - - - -/* SVBVH */ -template -void bvh_dfs_make_hint(VBVHNode *node, LCTSHint *hint, int reserve_space, HintObject *hintObject) -{ - return; -} -/* -RayObject *RE_rayobject_svbvh_create(int size) -{ - SVBVHTree *obj= (SVBVHTree*)MEM_callocN(sizeof(SVBVHTree), "SVBVHTree"); - assert( RE_rayobject_isAligned(obj) ); // RayObject API assumes real data to be 4-byte aligned - - obj->rayobj.api = get_api(DFS_STACK_SIZE); - obj->root = NULL; - - obj->node_arena = NULL; - obj->builder = rtbuild_create( size ); - - return RE_rayobject_unalignRayAPI((RayObject*) obj); + return bvh_create_tree(size); } -*/ \ No newline at end of file diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h index 2494f102003..712221fb739 100644 --- a/source/blender/render/intern/raytrace/reorganize.h +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -29,6 +29,9 @@ #include #include +extern int tot_pushup; +extern int tot_pushdown; + template bool node_fits_inside(Node *a, Node *b) { diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 95f1c40765e..b243e91d381 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -29,10 +29,10 @@ #ifndef RE_RAYTRACE_SVBVH_H #define RE_RAYTRACE_SVBVH_H -#define SVBVH_SIMD 1 - #include "bvh.h" +#include "BLI_memarena.h" #include +#include struct SVBVHNode { @@ -52,38 +52,27 @@ inline int bvh_node_hit_test(SVBVHNode *node, Isect *isec) template<> inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHNode **stack, int &stack_pos) { - if(SVBVH_SIMD) + int i=0; + while(i+4 <= node->nchilds) { - int i=0; - while(i+4 <= node->nchilds) - { - int res = test_bb_group4( (__m128*) (node->child_bb+6*i), isec ); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - - if(res & 1) { stack[stack_pos++] = node->child[i+0]; RE_RC_COUNT(isec->raycounter->bb.hit); } - if(res & 2) { stack[stack_pos++] = node->child[i+1]; RE_RC_COUNT(isec->raycounter->bb.hit); } - if(res & 4) { stack[stack_pos++] = node->child[i+2]; RE_RC_COUNT(isec->raycounter->bb.hit); } - if(res & 8) { stack[stack_pos++] = node->child[i+3]; RE_RC_COUNT(isec->raycounter->bb.hit); } - - i += 4; - } - while(i < node->nchilds) - { - if(RE_rayobject_bb_intersect_test(isec, (const float*)node->child_bb+6*i)) - stack[stack_pos++] = node->child[i]; - i++; - } + int res = test_bb_group4( (__m128*) (node->child_bb+6*i), isec ); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->bb.test); + + if(res & 1) { stack[stack_pos++] = node->child[i+0]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 2) { stack[stack_pos++] = node->child[i+1]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 4) { stack[stack_pos++] = node->child[i+2]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 8) { stack[stack_pos++] = node->child[i+3]; RE_RC_COUNT(isec->raycounter->bb.hit); } + + i += 4; } - else + while(i < node->nchilds) { - for(int i=0; inchilds; i++) - { - if(RE_rayobject_bb_intersect_test(isec, (const float*)node->child_bb+6*i)) - stack[stack_pos++] = node->child[i]; - } + if(RE_rayobject_bb_intersect_test(isec, (const float*)node->child_bb+6*i)) + stack[stack_pos++] = node->child[i]; + i++; } } @@ -97,7 +86,7 @@ void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) else { int i=0; - while(SVBVH_SIMD && i+4 <= node->nchilds) + while(i+4 <= node->nchilds) { float *res = node->child_bb + 6*i; for(int j=0; j<3; j++) @@ -126,33 +115,24 @@ void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) } } -struct SVBVHTree -{ - RayObject rayobj; - - SVBVHNode *root; - - MemArena *node_arena; - - float cost; - RTBuilder *builder; -}; - -template +/* + * Builds a SVBVH tree form a VBVHTree + */ +template struct Reorganize_SVBVH { - Tree *tree; + MemArena *arena; float childs_per_node; int nodes_with_childs[16]; int useless_bb; int nodes; - Reorganize_SVBVH(Tree *t) + Reorganize_SVBVH(MemArena *a) { - tree = t; + arena = a; nodes = 0; childs_per_node = 0; useless_bb = 0; @@ -171,10 +151,10 @@ struct Reorganize_SVBVH SVBVHNode *create_node(int nchilds) { - SVBVHNode *node = (SVBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(SVBVHNode)); + SVBVHNode *node = (SVBVHNode*)BLI_memarena_alloc(arena, sizeof(SVBVHNode)); node->nchilds = nchilds; - node->child_bb = (float*)BLI_memarena_alloc(tree->node_arena, sizeof(float)*6*nchilds); - node->child= (SVBVHNode**)BLI_memarena_alloc(tree->node_arena, sizeof(SVBVHNode*)*nchilds); + node->child_bb = (float*)BLI_memarena_alloc(arena, sizeof(float)*6*nchilds); + node->child= (SVBVHNode**)BLI_memarena_alloc(arena, sizeof(SVBVHNode*)*nchilds); return node; } @@ -200,29 +180,7 @@ struct Reorganize_SVBVH res[4*j+2] = vec_tmp[6*2+j]; res[4*j+3] = vec_tmp[6*3+j]; } -/* - const float *bb0 = vec_tmp+6*(i+0); - const float *bb1 = vec_tmp+6*(i+1); - const float *bb2 = vec_tmp+6*(i+2); - const float *bb3 = vec_tmp+6*(i+3); - - //memmoves could be memory alligned - const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(1,0,1,0) ); - const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(1,0,1,0) ); - _mm_store_ps( node->child_bb+6*i+4*0, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2,0,2,0) ) ); - _mm_store_ps( node->child_bb+6*i+4*1, _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3,1,3,1) ) ); - - const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_loadu_ps(bb0), _mm_loadu_ps(bb1), _MM_SHUFFLE(3,2,3,2) ); - const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_loadu_ps(bb2), _mm_loadu_ps(bb3), _MM_SHUFFLE(3,2,3,2) ); - _mm_store_ps( node->child_bb+6*i+4*2, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2,0,2,0) ) ); - _mm_store_ps( node->child_bb+6*i+4*3, _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3,1,3,1) ) ); - const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_loadu_ps(bb0+4), _mm_loadu_ps(bb1+4), _MM_SHUFFLE(1,0,1,0) ); - const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_loadu_ps(bb2+4), _mm_loadu_ps(bb3+4), _MM_SHUFFLE(1,0,1,0) ); - _mm_store_ps( node->child_bb+6*i+4*4, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2,0,2,0) ) ); - _mm_store_ps( node->child_bb+6*i+4*5, _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3,1,3,1) ) ); - */ - i += 4; } } @@ -280,10 +238,8 @@ struct Reorganize_SVBVH } } assert( i == 0 ); - - if(SVBVH_SIMD) - prepare_for_simd(node); + prepare_for_simd(node); return node; } diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h new file mode 100644 index 00000000000..7c07bd9ded0 --- /dev/null +++ b/source/blender/render/intern/raytrace/vbvh.h @@ -0,0 +1,186 @@ +#include + +#include +#include "rayobject_rtbuild.h" +#include "BLI_memarena.h" + + +/* + * VBVHNode represents a BVHNode with support for a variable number of childrens + */ +struct VBVHNode +{ + float bb[6]; + + VBVHNode *child; + VBVHNode *sibling; +}; + + +/* + * Push nodes (used on dfs) + */ +template +inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) +{ + Node *child = node->child; + + if(is_leaf(child)) + { + stack[stack_pos++] = child; + } + else + { + while(child) + { + //Skips BB tests on primitives +/* + if(is_leaf(child->child)) + stack[stack_pos++] = child->child; + else +*/ + stack[stack_pos++] = child; + + child = child->sibling; + } + } +} + + +template +int count_childs(Node *parent) +{ + int n = 0; + for(Node *i = parent->child; i; i = i->sibling) + { + n++; + if(is_leaf(i)) + break; + } + + return n; +} + + +template +void append_sibling(Node *node, Node *sibling) +{ + while(node->sibling) + node = node->sibling; + + node->sibling = sibling; +} + + +/* + * Builds a binary VBVH from a rtbuild + */ +struct BuildBinaryVBVH +{ + MemArena *arena; + + BuildBinaryVBVH(MemArena *a) + { + arena = a; + } + + VBVHNode *create_node() + { + VBVHNode *node = (VBVHNode*)BLI_memarena_alloc( arena, sizeof(VBVHNode) ); + assert( RE_rayobject_isAligned(node) ); + + node->sibling = NULL; + node->child = NULL; + + return node; + } + + int rtbuild_split(RTBuilder *builder) + { + return ::rtbuild_heuristic_object_split(builder, 2); + } + + VBVHNode *transform(RTBuilder *builder) + { + + int size = rtbuild_size(builder); + if(size == 1) + { + VBVHNode *node = create_node(); + INIT_MINMAX(node->bb, node->bb+3); + rtbuild_merge_bb(builder, node->bb, node->bb+3); + node->child = (VBVHNode*) rtbuild_get_primitive( builder, 0 ); + return node; + } + else + { + VBVHNode *node = create_node(); + + INIT_MINMAX(node->bb, node->bb+3); + rtbuild_merge_bb(builder, node->bb, node->bb+3); + + VBVHNode **child = &node->child; + + int nc = rtbuild_split(builder); + assert(nc == 2); + for(int i=0; isibling); + } + + *child = 0; + return node; + } + } +}; + +/* +template +struct Reorganize_VBVH +{ + Tree *tree; + + Reorganize_VBVH(Tree *t) + { + tree = t; + } + + VBVHNode *create_node() + { + VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); + return node; + } + + void copy_bb(VBVHNode *node, OldNode *old) + { + std::copy( old->bb, old->bb+6, node->bb ); + } + + VBVHNode *transform(OldNode *old) + { + if(is_leaf(old)) + return (VBVHNode*)old; + + VBVHNode *node = create_node(); + VBVHNode **child_ptr = &node->child; + node->sibling = 0; + + copy_bb(node,old); + + for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) + { + VBVHNode *n_child = transform(o_child); + *child_ptr = n_child; + if(is_leaf(n_child)) return node; + child_ptr = &n_child->sibling; + } + *child_ptr = 0; + + return node; + } +}; +*/ \ No newline at end of file diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index af2c0f99174..928083620e1 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -75,7 +75,7 @@ RayObject * RE_rayobject_tree_create(int type, int size) __attribute__((noinlin RayObject * RE_rayobject_tree_create(int type, int size) { // if(type == R_RAYTRACE_TREE_BIH) - return RE_rayobject_vbvh_create(size); + return RE_rayobject_svbvh_create(size); if(type == R_RAYTRACE_TREE_BVH) return RE_rayobject_bvh_create(size); -- cgit v1.2.3 From afee963155a2776066d377ed590e755217948d0f Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 29 Aug 2009 17:25:22 +0000 Subject: First commit draft for network rendering. Docs are here: http://wiki.blender.org/index.php/User:Theeth/netrender Should be easy to test if people want too, just follow the instructions on wiki Code is still very much in flux, so I'd like if people would refrain from making changes (send patches directly to me if you must). The UI side is very crap, it's basically there just to get things testable. See wiki for known bugs. --- release/io/netrender/__init__.py | 9 + release/io/netrender/client.py | 87 ++++++ release/io/netrender/master.py | 546 ++++++++++++++++++++++++++++++++++++++ release/io/netrender/model.py | 150 +++++++++++ release/io/netrender/operators.py | 238 +++++++++++++++++ release/io/netrender/slave.py | 147 ++++++++++ release/io/netrender/ui.py | 290 ++++++++++++++++++++ release/io/netrender/utils.py | 80 ++++++ 8 files changed, 1547 insertions(+) create mode 100644 release/io/netrender/__init__.py create mode 100644 release/io/netrender/client.py create mode 100644 release/io/netrender/master.py create mode 100644 release/io/netrender/model.py create mode 100644 release/io/netrender/operators.py create mode 100644 release/io/netrender/slave.py create mode 100644 release/io/netrender/ui.py create mode 100644 release/io/netrender/utils.py diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py new file mode 100644 index 00000000000..e0de2726a55 --- /dev/null +++ b/release/io/netrender/__init__.py @@ -0,0 +1,9 @@ +# This directory is a Python package. + +import model +import operators +import client +import slave +import master +import utils +import ui diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py new file mode 100644 index 00000000000..90039a3273a --- /dev/null +++ b/release/io/netrender/client.py @@ -0,0 +1,87 @@ +import bpy +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +import netrender.slave as slave +import netrender.master as master +from netrender.utils import * + +class NetworkRenderEngine(bpy.types.RenderEngine): + __idname__ = 'NET_RENDER' + __label__ = "Network Render" + def render(self, scene): + if scene.network_render.mode == "RENDER_CLIENT": + self.render_client(scene) + elif scene.network_render.mode == "RENDER_SLAVE": + self.render_slave(scene) + elif scene.network_render.mode == "RENDER_MASTER": + self.render_master(scene) + else: + print("UNKNOWN OPERATION MODE") + + def render_master(self, scene): + server_address = (scene.network_render.server_address, scene.network_render.server_port) + httpd = master.RenderMasterServer(server_address, master.RenderHandler) + httpd.timeout = 1 + httpd.stats = self.update_stats + while not self.test_break(): + httpd.handle_request() + + def render_slave(self, scene): + slave.render_slave(self, scene) + + def render_client(self, scene): + self.update_stats("", "Network render client initiation") + + conn = clientConnection(scene) + + if conn: + # Sending file + + self.update_stats("", "Network render exporting") + + job_id = scene.network_render.job_id + + # reading back result + + self.update_stats("", "Network render waiting for results") + + clientRequestResult(conn, scene, job_id) + response = conn.getresponse() + + if response.status == http.client.NO_CONTENT: + scene.network_render.job_id = clientSendJob(conn, scene) + clientRequestResult(conn, scene, job_id) + + while response.status == http.client.PROCESSING and not self.test_break(): + print("waiting") + time.sleep(1) + clientRequestResult(conn, scene, job_id) + response = conn.getresponse() + + if response.status != http.client.OK: + conn.close() + return + + r = scene.render_data + x= int(r.resolution_x*r.resolution_percentage*0.01) + y= int(r.resolution_y*r.resolution_percentage*0.01) + + f = open(PATH_PREFIX + "output.exr", "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + result = self.begin_result(0, 0, x, y) + result.load_from_file(PATH_PREFIX + "output.exr", 0, 0) + self.end_result(result) + + conn.close() + +bpy.types.register(NetworkRenderEngine) + diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py new file mode 100644 index 00000000000..5a62ef1a8bf --- /dev/null +++ b/release/io/netrender/master.py @@ -0,0 +1,546 @@ +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +from netrender.utils import * +import netrender.model + + +class MRenderSlave(netrender.model.RenderSlave): + def __init__(self, name, adress, stats): + super().__init__() + self.id = hashlib.md5(bytes(repr(name) + repr(adress), encoding='utf8')).hexdigest() + self.name = name + self.adress = adress + self.stats = stats + self.last_seen = time.time() + + self.job = None + self.frame = None + + netrender.model.RenderSlave._slave_map[self.id] = self + + def seen(self): + self.last_seen = time.time() + +# sorting key for jobs +def groupKey(job): + return (job.framesLeft() > 0, job.priority, job.credits) + +class MRenderJob(netrender.model.RenderJob): + def __init__(self, job_id, name, path, chunks = 1, priority = 1, credits = 100.0, blacklist = []): + super().__init__() + self.id = job_id + self.name = name + self.path = path + self.frames = [] + self.chunks = chunks + self.priority = priority + self.credits = credits + self.blacklist = blacklist + self.last_dispatched = time.time() + + def update(self): + self.credits -= 5 # cost of one frame + self.credits += (time.time() - self.last_dispatched) / 60 + self.last_dispatched = time.time() + + def addFrame(self, frame_number): + frame = MRenderFrame(frame_number) + self.frames.append(frame) + return frame + + def framesLeft(self): + total = 0 + for j in self.frames: + if j.status == QUEUED: + total += 1 + + return total + + def reset(self, all): + for f in self.frames: + f.reset(all) + + def getFrames(self): + frames = [] + for f in self.frames: + if f.status == QUEUED: + self.update() + frames.append(f) + if len(frames) == self.chunks: + break + + return frames + +class MRenderFrame(netrender.model.RenderFrame): + def __init__(self, frame): + super().__init__() + self.number = frame + self.slave = None + self.time = 0 + self.status = QUEUED + + def reset(self, all): + if all or self.status == ERROR: + self.slave = None + self.time = 0 + self.status = QUEUED + + +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +class RenderHandler(http.server.BaseHTTPRequestHandler): + def send_head(self, code = http.client.OK, headers = {}): + self.send_response(code) + self.send_header("Content-type", "application/octet-stream") + + for key, value in headers.items(): + self.send_header(key, value) + + self.end_headers() + + def do_HEAD(self): + print(self.path) + + if self.path == "status": + job_id = self.headers.get('job-id', "") + job_frame = int(self.headers.get('job-frame', -1)) + + if job_id: + print("status:", job_id, "\n") + + job = self.server.getJobByID(job_id) + if job: + if job_frame != -1: + frame = job[frame] + + if not frame: + # no such frame + self.send_heat(http.client.NOT_FOUND) + return + else: + # no such job id + self.send_head(http.client.NOT_FOUND) + return + + self.send_head() + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + def do_GET(self): + print(self.path) + + if self.path == "version": + self.send_head() + self.server.stats("", "New client connection") + self.wfile.write(VERSION) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "render": + job_id = self.headers['job-id'] + job_frame = int(self.headers['job-frame']) + print("render:", job_id, job_frame) + + job = self.server.getJobByID(job_id) + + if job: + frame = job[job_frame] + + if frame: + if frame.status in (QUEUED, DISPATCHED): + self.send_head(http.client.PROCESSING) + elif frame.status == DONE: + self.server.stats("", "Sending result back to client") + f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".exr", 'rb') + + self.send_head() + + shutil.copyfileobj(f, self.wfile) + + f.close() + elif frame.status == ERROR: + self.send_head(http.client.NO_CONTENT) + else: + # no such frame + self.send_head(http.client.NOT_FOUND) + else: + # no such job id + self.send_head(http.client.NOT_FOUND) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "log": + job_id = self.headers['job-id'] + job_frame = int(self.headers['job-frame']) + print("log:", job_id, job_frame) + + job = self.server.getJobByID(job_id) + + if job: + frame = job[job_frame] + + if frame: + if frame.status in (QUEUED, DISPATCHED): + self.send_head(http.client.PROCESSING) + elif frame.status == DONE: + self.server.stats("", "Sending log back to client") + f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".log", 'rb') + + self.send_head() + + shutil.copyfileobj(f, self.wfile) + + f.close() + elif frame.status == ERROR: + self.send_head(http.client.NO_CONTENT) + else: + # no such frame + self.send_head(http.client.NOT_FOUND) + else: + # no such job id + self.send_head(http.client.NOT_FOUND) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "status": + job_id = self.headers.get('job-id', "") + job_frame = int(self.headers.get('job-frame', -1)) + + if job_id: + print("status:", job_id, "\n") + + job = self.server.getJobByID(job_id) + if job: + if job_frame != -1: + frame = job[frame] + + if frame: + message = frame.serialize() + else: + # no such frame + self.send_heat(http.client.NOT_FOUND) + return + else: + message = job.serialize() + else: + # no such job id + self.send_head(http.client.NOT_FOUND) + return + else: # status of all jobs + message = [] + + for job in self.server: + results = job.status() + + message.append(job.serialize()) + + self.send_head() + self.wfile.write(bytes(repr(message), encoding='utf8')) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "job": + self.server.update() + + slave_id = self.headers['slave-id'] + + print("slave-id", slave_id) + + self.server.getSlave(slave_id) + + slave = self.server.updateSlave(slave_id) + + if slave: # only if slave id is valid + job, frames = self.server.getNewJob(slave_id) + + if job and frames: + for f in frames: + f.status = DISPATCHED + f.slave = slave + + self.send_head(headers={"job-id": job.id}) + + message = job.serialize(frames) + + self.wfile.write(bytes(repr(message), encoding='utf8')) + + self.server.stats("", "Sending job frame to render node") + else: + # no job available, return error code + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id + self.send_head(http.client.NOT_FOUND) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "file": + job_id = self.headers['job-id'] + print("file:", job_id, "\n") + + job = self.server.getJobByID(job_id) + + if job: + self.send_head(headers={"job-id": job.id}) + + self.server.stats("", "Sending file to render node") + f = open(PATH_PREFIX + job.id + ".blend", 'rb') + + shutil.copyfileobj(f, self.wfile) + + f.close() + else: + # no such job id + self.send_head(http.client.NOT_FOUND) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "slave": + message = [] + + for slave in self.server.slaves: + message.append(slave.serialize()) + + self.send_head() + + self.wfile.write(bytes(repr(message), encoding='utf8')) + + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + def do_POST(self): + print(self.path) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + if self.path == "job": + print("posting job info") + self.server.stats("", "Receiving job") + + length = int(self.headers['content-length']) + job_frame_string = self.headers['job-frame'] + job_name = self.headers.get('job-name', "") + job_chunks = int(self.headers.get('job-chunks', "1")) + blacklist = self.headers.get('slave-blacklist', '').split() + + print("blacklist", blacklist) + + job_path = str(self.rfile.read(length), encoding='utf8') + + if os.path.exists(job_path): + f = open(job_path, "rb") + buf = f.read() + f.close() + + job_id = hashlib.md5(buf).hexdigest() + + del buf + + job = self.server.getJobByID(job_id) + + if job == None: + job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) + self.server.addJob(job) + + if ":" in job_frame_string: + frame_start, frame_end = [int(x) for x in job_frame_string.split(":")] + + for job_frame in range(frame_start, frame_end + 1): + frame = job.addFrame(job_frame) + else: + job_frame = int(job_frame_string) + frame = job.addFrame(job_frame) + + self.send_head(headers={"job-id": job_id}) + else: + self.send_head(http.client.NOT_FOUND) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "cancel": + job_id = self.headers.get('job-id', "") + if job_id: + print("cancel:", job_id, "\n") + self.server.removeJob(job_id) + else: # cancel all jobs + self.server.clear() + + self.send_head() + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "reset": + job_id = self.headers.get('job-id', "") + job_frame = int(self.headers.get('job-frame', "-1")) + all = bool(self.headers.get('reset-all', "False")) + + job = self.server.getJobByID(job_id) + + if job: + if job_frame != -1: + job[job_frame].reset(all) + else: + job.reset(all) + + self.send_head() + else: # job not found + self.send_head(http.client.NOT_FOUND) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "slave": + length = int(self.headers['content-length']) + job_frame_string = self.headers['job-frame'] + + name, stats = eval(str(self.rfile.read(length), encoding='utf8')) + + slave_id = self.server.addSlave(name, self.client_address, stats) + + self.send_head(headers = {"slave-id": slave_id}) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + def do_PUT(self): + print(self.path) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + if self.path == "file": + print("writing blend file") + self.server.stats("", "Receiving job") + + length = int(self.headers['content-length']) + job_frame_string = self.headers['job-frame'] + job_name = self.headers.get('job-name', "") + job_chunks = int(self.headers.get('job-chunks', "1")) + blacklist = self.headers.get('slave-blacklist', '').split() + + buf = self.rfile.read(length) + + job_id = hashlib.md5(buf).hexdigest() + + job_path = job_id + ".blend" + + f = open(PATH_PREFIX + job_path, "wb") + f.write(buf) + f.close() + + del buf + + job = self.server.getJobByID(job_id) + + if job == None: + job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) + self.server.addJob(job) + + if ":" in job_frame_string: + frame_start, frame_end = [int(x) for x in job_frame_string.split(":")] + + for job_frame in range(frame_start, frame_end + 1): + frame = job.addFrame(job_frame) + else: + job_frame = int(job_frame_string) + frame = job.addFrame(job_frame) + + self.send_head(headers={"job-id": job_id}) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "render": + print("writing result file") + self.server.stats("", "Receiving render result") + + job_id = self.headers['job-id'] + job_frame = int(self.headers['job-frame']) + job_result = int(self.headers['job-result']) + job_time = float(self.headers['job-time']) + + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() + + del buf + + job = self.server.getJobByID(job_id) + frame = job[job_frame] + frame.status = job_result + frame.time = job_time + + self.server.updateSlave(self.headers['slave-id']) + + self.send_head() + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "log": + print("writing log file") + self.server.stats("", "Receiving log file") + + length = int(self.headers['content-length']) + job_id = self.headers['job-id'] + job_frame = int(self.headers['job-frame']) + + print("log length:", length) + + buf = self.rfile.read(length) + f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".log", 'wb') + f.write(buf) + f.close() + + del buf + + self.server.updateSlave(self.headers['slave-id']) + + self.send_head() + + +class RenderMasterServer(http.server.HTTPServer): + def __init__(self, address, handler_class): + super().__init__(address, handler_class) + self.jobs = [] + self.jobs_map = {} + self.slaves = [] + self.slaves_map = {} + + def addSlave(self, name, adress, stats): + slave = MRenderSlave(name, adress, stats) + self.slaves.append(slave) + self.slaves_map[slave.id] = slave + + return slave.id + + def getSlave(self, slave_id): + return self.slaves_map.get(slave_id, None) + + def updateSlave(self, slave_id): + slave = self.getSlave(slave_id) + if slave: + slave.seen() + + return slave + + def clear(self): + self.jobs_map = {} + self.jobs = [] + + def update(self): + self.jobs.sort(key = groupKey) + + def removeJob(self, id): + job = self.jobs_map.pop(id) + + if job: + self.jobs.remove(job) + + def addJob(self, job): + self.jobs.append(job) + self.jobs_map[job.id] = job + + def getJobByID(self, id): + return self.jobs_map.get(id, None) + + def __iter__(self): + for job in self.jobs: + yield job + + def getNewJob(self, slave_id): + if self.jobs: + for job in reversed(self.jobs): + if job.framesLeft() > 0 and slave_id not in job.blacklist: + return job, job.getFrames() + + return None, None diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py new file mode 100644 index 00000000000..6e68929d340 --- /dev/null +++ b/release/io/netrender/model.py @@ -0,0 +1,150 @@ +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +from netrender.utils import * + +class RenderSlave: + _slave_map = {} + + def __init__(self): + self.id = "" + self.name = "" + self.adress = (0,0) + self.stats = "" + self.total_done = 0 + self.total_error = 0 + self.last_seen = 0.0 + + def serialize(self): + return { + "id": self.id, + "name": self.name, + "adress": self.adress, + "stats": self.stats, + "total_done": self.total_done, + "total_error": self.total_error, + "last_seen": self.last_seen + } + + @staticmethod + def materialize(data): + if not data: + return None + + slave_id = data["id"] + + if slave_id in RenderSlave._slave_map: + return RenderSlave._slave_map[slave_id] + else: + slave = RenderSlave() + slave.id = slave_id + slave.name = data["name"] + slave.adress = data["adress"] + slave.stats = data["stats"] + slave.total_done = data["total_done"] + slave.total_error = data["total_error"] + slave.last_seen = data["last_seen"] + + RenderSlave._slave_map[slave_id] = slave + + return slave + +class RenderJob: + def __init__(self): + self.id = "" + self.name = "" + self.path = "" + self.frames = [] + self.chunks = 0 + self.priority = 0 + self.credits = 0 + self.blacklist = [] + self.last_dispatched = 0.0 + + def __len__(self): + return len(self.frames) + + def status(self): + results = { + QUEUED: 0, + DISPATCHED: 0, + DONE: 0, + ERROR: 0 + } + + for frame in self.frames: + results[frame.status] += 1 + + return results + + def __contains__(self, frame_number): + for f in self.frames: + if f.number == frame_number: + return True + else: + return False + + def __getitem__(self, frame_number): + for f in self.frames: + if f.number == frame_number: + return f + else: + return None + + def serialize(self, frames = None): + return { + "id": self.id, + "name": self.name, + "path": self.path, + "frames": [f.serialize() for f in self.frames if not frames or f in frames], + "priority": self.priority, + "credits": self.credits, + "blacklist": self.blacklist, + "last_dispatched": self.last_dispatched + } + + @staticmethod + def materialize(data): + if not data: + return None + + job = RenderJob() + job.id = data["id"] + job.name = data["name"] + job.path = data["path"] + job.frames = [RenderFrame.materialize(f) for f in data["frames"]] + job.priority = data["priority"] + job.credits = data["credits"] + job.blacklist = data["blacklist"] + job.last_dispatched = data["last_dispatched"] + + return job + +class RenderFrame: + def __init__(self): + self.number = 0 + self.time = 0 + self.status = QUEUED + self.slave = None + + def serialize(self): + return { + "number": self.number, + "time": self.time, + "status": self.status, + "slave": None if not self.slave else self.slave.serialize() + } + + @staticmethod + def materialize(data): + if not data: + return None + + frame = RenderFrame() + frame.number = data["number"] + frame.time = data["time"] + frame.status = data["status"] + frame.slave = RenderSlave.materialize(data["slave"]) + + return frame diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py new file mode 100644 index 00000000000..3355c3d1a0b --- /dev/null +++ b/release/io/netrender/operators.py @@ -0,0 +1,238 @@ +import bpy +import sys, os +import http, http.client, http.server, urllib + +from netrender.utils import * +import netrender.model + +class RENDER_OT_netclientsend(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "render.netclientsend" + __label__ = "Net Render Client Send" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + scene = context.scene + + conn = clientConnection(scene) + + if conn: + # Sending file + scene.network_render.job_id = clientSendJob(conn, scene, True) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +class RENDER_OT_netclientstatus(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientstatus" + __label__ = "Net Render Client Status" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netprops = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + conn.request("GET", "status") + + response = conn.getresponse() + print( response.status, response.reason ) + + jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8'))) + + while(len(netprops.jobs) > 0): + netprops.jobs.remove(0) + + for j in jobs: + netprops.jobs.add() + job = netprops.jobs[-1] + + job_results = j.status() + + job.id = j.id + job.name = j.name + job.length = len(j) + job.done = job_results[DONE] + job.error = job_results[ERROR] + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +class RENDER_OT_netclientblacklistslave(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientblacklistslave" + __label__ = "Net Render Client Blacklist Slave" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netprops = context.scene.network_render + + if netprops.active_slave_index >= 0: + + slave = netrender.slaves[netprops.active_slave_index] + + netprops.slaves_blacklist.add() + + netprops.slaves_blacklist[-1].id = slave.id + netprops.slaves_blacklist[-1].name = slave.name + netprops.slaves_blacklist[-1].adress = slave.adress + netprops.slaves_blacklist[-1].last_seen = slave.last_seen + netprops.slaves_blacklist[-1].stats = slave.stats + + netprops.slaves.remove(netprops.active_slave_index) + netprops.active_slave_index = -1 + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientwhitelistslave" + __label__ = "Net Render Client Whitelist Slave" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netprops = context.scene.network_render + + if netprops.active_blacklisted_slave_index >= 0: + + slave = netprops.slaves_blacklist[netprops.active_blacklisted_slave_index] + + netprops.slaves.add() + + netprops.slaves[-1].id = slave.id + netprops.slaves[-1].name = slave.name + netprops.slaves[-1].adress = slave.adress + netprops.slaves[-1].last_seen = slave.last_seen + netprops.slaves[-1].stats = slave.stats + + netprops.slaves_blacklist.remove(netprops.active_blacklisted_slave_index) + netprops.active_blacklisted_slave_index = -1 + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + + +class RENDER_OT_netclientslaves(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientslaves" + __label__ = "Net Render Client Slaves" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netprops = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + conn.request("GET", "slave") + + response = conn.getresponse() + print( response.status, response.reason ) + + slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8'))) + + while(len(netprops.slaves) > 0): + netprops.slaves.remove(0) + + for s in slaves: + for slave in netprops.slaves_blacklist: + if slave.id == s.id: + break + + netprops.slaves.add() + slave = netprops.slaves[-1] + + slave.id = s.id + slave.name = s.name + slave.stats = s.stats + slave.adress = s.adress[0] + slave.last_seen = time.ctime(s.last_seen) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +class RENDER_OT_netclientcancel(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientcancel" + __label__ = "Net Render Client Cancel" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + netrender = scene.network_render + return netrender.active_job_index >= 0 and len(netrender.jobs) > 0 + + def execute(self, context): + netprops = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + job = netprops.jobs[netrender.active_job_index] + + conn.request("POST", "cancel", headers={"job-id":job.id}) + + response = conn.getresponse() + print( response.status, response.reason ) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +bpy.ops.add(RENDER_OT_netclientsend) +bpy.ops.add(RENDER_OT_netclientstatus) +bpy.ops.add(RENDER_OT_netclientslaves) +bpy.ops.add(RENDER_OT_netclientblacklistslave) +bpy.ops.add(RENDER_OT_netclientwhitelistslave) +bpy.ops.add(RENDER_OT_netclientcancel) \ No newline at end of file diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py new file mode 100644 index 00000000000..03c6803955e --- /dev/null +++ b/release/io/netrender/slave.py @@ -0,0 +1,147 @@ +import sys, os +import http, http.client, http.server, urllib +import subprocess, time + +from netrender.utils import * +import netrender.model + +CANCEL_POLL_SPEED = 2 +MAX_TIMEOUT = 10 +INCREMENT_TIMEOUT = 1 + +def slave_Info(): + sysname, nodename, release, version, machine = os.uname() + return (nodename, sysname + " " + release + " " + machine) + +def testCancel(conn, job_id): + conn.request("HEAD", "status", headers={"job-id":job_id}) + response = conn.getresponse() + + # cancelled if job isn't found anymore + if response.status == http.client.NOT_FOUND: + return True + else: + return False + +def render_slave(engine, scene): + NODE_PREFIX = PATH_PREFIX + "node" + os.sep + timeout = 1 + + if not os.path.exists(NODE_PREFIX): + os.mkdir(NODE_PREFIX) + + engine.update_stats("", "Network render node initiation") + + conn = clientConnection(scene) + + if conn: + conn.request("POST", "slave", repr(slave_Info())) + response = conn.getresponse() + + slave_id = response.getheader("slave-id") + + while not engine.test_break(): + + conn.request("GET", "job", headers={"slave-id":slave_id}) + response = conn.getresponse() + + if response.status == http.client.OK: + timeout = 1 # reset timeout on new job + + job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8'))) + + print("File:", job.path) + engine.update_stats("", "Render File", job.path, "for job", job.id) + + if os.path.isabs(job.path): + # if an absolute path, make sure path exists, if it doesn't, use relative local path + job_full_path = job.path + if not os.path.exists(job_full_path): + job_full_path = NODE_PREFIX + job.id + ".blend" + else: + job_full_path = NODE_PREFIX + job.path + + if not os.path.exists(job_full_path): + conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id}) + response = conn.getresponse() + + if response.status != http.client.OK: + break # file for job not returned by server, need to return an error code to server + + f = open(job_full_path, "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + frame_args = [] + + for frame in job.frames: + frame_args += ["-f", str(frame.number)] + + start_t = time.time() + + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", NODE_PREFIX + job.id, "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + cancelled = False + stdout = bytes() + run_t = time.time() + while process.poll() == None and not cancelled: + stdout += process.stdout.read(32) + current_t = time.time() + cancelled = engine.test_break() + if current_t - run_t > CANCEL_POLL_SPEED: + if testCancel(conn, job.id): + cancelled = True + else: + run_t = current_t + + if cancelled: + continue # to next frame + + total_t = time.time() - start_t + + avg_t = total_t / len(job.frames) + + status = process.returncode + + print("status", status) + + headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} + + if status == 0: # non zero status is error + headers["job-result"] = str(DONE) + for frame in job.frames: + headers["job-frame"] = str(frame.number) + # send result back to server + f = open(NODE_PREFIX + job.id + "%04d" % frame.number + ".exr", 'rb') + conn.request("PUT", "render", f, headers=headers) + f.close() + response = conn.getresponse() + else: + headers["job-result"] = str(ERROR) + for frame in job.frames: + headers["job-frame"] = str(frame.number) + # send error result back to server + conn.request("PUT", "render", headers=headers) + response = conn.getresponse() + + for frame in job.frames: + headers["job-frame"] = str(frame.number) + # send log in any case + conn.request("PUT", "log", stdout, headers=headers) + response = conn.getresponse() + else: + if timeout < MAX_TIMEOUT: + timeout += INCREMENT_TIMEOUT + + for i in range(timeout): + time.sleep(1) + if engine.test_break(): + conn.close() + return + + conn.close() diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py new file mode 100644 index 00000000000..2fd2b9a317f --- /dev/null +++ b/release/io/netrender/ui.py @@ -0,0 +1,290 @@ +import bpy +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +import netrender.slave as slave +import netrender.master as master + +VERSION = b"0.3" + +PATH_PREFIX = "/tmp/" + +QUEUED = 0 +DISPATCHED = 1 +DONE = 2 +ERROR = 3 + +class RenderButtonsPanel(bpy.types.Panel): + __space_type__ = "PROPERTIES" + __region_type__ = "WINDOW" + __context__ = "scene" + # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here + + def poll(self, context): + rd = context.scene.render_data + return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) + +# Setting panel, use in the scene for now. +class SCENE_PT_network_settings(RenderButtonsPanel): + __label__ = "Network Settings" + COMPAT_ENGINES = set(['NET_RENDER']) + + def draw_header(self, context): + layout = self.layout + scene = context.scene + + def draw(self, context): + layout = self.layout + scene = context.scene + rd = scene.render_data + + layout.active = True + + split = layout.split() + + col = split.column() + + col.itemR(scene.network_render, "mode") + col.itemR(scene.network_render, "server_address") + col.itemR(scene.network_render, "server_port") + + if scene.network_render.mode == "RENDER_CLIENT": + col.itemR(scene.network_render, "chunks") + col.itemR(scene.network_render, "job_name") + col.itemO("render.netclientsend", text="send job to server") +bpy.types.register(SCENE_PT_network_settings) + +class SCENE_PT_network_slaves(RenderButtonsPanel): + __label__ = "Slaves Status" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + netrender = scene.network_render + + row = layout.row() + row.template_list(netrender, "slaves", netrender, "active_slave_index", rows=2) + + col = row.column() + + subcol = col.column(align=True) + subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") + subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") + + if netrender.active_slave_index >= 0 and len(netrender.slaves) > 0: + layout.itemS() + + slave = netrender.slaves[netrender.active_slave_index] + + layout.itemL(text="Name: " + slave.name) + layout.itemL(text="Adress: " + slave.adress) + layout.itemL(text="Seen: " + slave.last_seen) + layout.itemL(text="Stats: " + slave.stats) + +bpy.types.register(SCENE_PT_network_slaves) + +class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): + __label__ = "Slaves Blacklist" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + netrender = scene.network_render + + row = layout.row() + row.template_list(netrender, "slaves_blacklist", netrender, "active_blacklisted_slave_index", rows=2) + + col = row.column() + + subcol = col.column(align=True) + subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") + + + if netrender.active_blacklisted_slave_index >= 0 and len(netrender.slaves_blacklist) > 0: + layout.itemS() + + slave = netrender.slaves_blacklist[netrender.active_blacklisted_slave_index] + + layout.itemL(text="Name: " + slave.name) + layout.itemL(text="Adress: " + slave.adress) + layout.itemL(text="Seen: " + slave.last_seen) + layout.itemL(text="Stats: " + slave.stats) + +bpy.types.register(SCENE_PT_network_slaves_blacklist) + +class SCENE_PT_network_jobs(RenderButtonsPanel): + __label__ = "Jobs" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + netrender = scene.network_render + + row = layout.row() + row.template_list(netrender, "jobs", netrender, "active_job_index", rows=2) + + col = row.column() + + subcol = col.column(align=True) + subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") + subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + + + if netrender.active_job_index >= 0 and len(netrender.jobs) > 0: + layout.itemS() + + job = netrender.jobs[netrender.active_job_index] + + layout.itemL(text="Name: %s" % job.name) + layout.itemL(text="Length: %04i" % job.length) + layout.itemL(text="Done: %04i" % job.done) + layout.itemL(text="Error: %04i" % job.error) + +bpy.types.register(SCENE_PT_network_jobs) + +class NetRenderSettings(bpy.types.IDPropertyGroup): + pass + +class NetRenderSlave(bpy.types.IDPropertyGroup): + pass + +class NetRenderJob(bpy.types.IDPropertyGroup): + pass + +bpy.types.register(NetRenderSettings) +bpy.types.register(NetRenderSlave) +bpy.types.register(NetRenderJob) + +bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings") + +NetRenderSettings.StringProperty( attr="server_address", + name="Server address", + description="IP or name of the master render server", + maxlen = 128, + default = "127.0.0.1") + +NetRenderSettings.IntProperty( attr="server_port", + name="Server port", + description="port of the master render server", + default = 8000, + min=1, + max=65535) + +NetRenderSettings.StringProperty( attr="job_name", + name="Job name", + description="Name of the job", + maxlen = 128, + default = "[default]") + +NetRenderSettings.IntProperty( attr="chunks", + name="Chunks", + description="Number of frame to dispatch to each slave in one chunk", + default = 5, + min=1, + max=65535) + +NetRenderSettings.StringProperty( attr="job_id", + name="Network job id", + description="id of the last sent render job", + maxlen = 64, + default = "") + +NetRenderSettings.IntProperty( attr="active_slave_index", + name="Index of the active slave", + description="", + default = -1, + min= -1, + max=65535) + +NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index", + name="Index of the active slave", + description="", + default = -1, + min= -1, + max=65535) + +NetRenderSettings.IntProperty( attr="active_job_index", + name="Index of the active job", + description="", + default = -1, + min= -1, + max=65535) + +NetRenderSettings.EnumProperty(attr="mode", + items=( + ("RENDER_CLIENT", "Client", "Act as render client"), + ("RENDER_MASTER", "Master", "Act as render master"), + ("RENDER_SLAVE", "Slave", "Act as render slave"), + ), + name="network mode", + description="mode of operation of this instance", + default="RENDER_CLIENT") + +NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="") +NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="") +NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="") + +NetRenderSlave.StringProperty( attr="name", + name="Name of the slave", + description="", + maxlen = 64, + default = "") + +NetRenderSlave.StringProperty( attr="adress", + name="Adress of the slave", + description="", + maxlen = 64, + default = "") + +NetRenderJob.StringProperty( attr="id", + name="ID of the job", + description="", + maxlen = 64, + default = "") + + +NetRenderJob.StringProperty( attr="name", + name="Name of the job", + description="", + maxlen = 128, + default = "") + +NetRenderJob.IntProperty( attr="length", + name="Number of frames", + description="", + default = 0, + min= 0, + max=65535) + +NetRenderJob.IntProperty( attr="done", + name="Number of frames rendered", + description="", + default = 0, + min= 0, + max=65535) + +NetRenderJob.IntProperty( attr="error", + name="Number of frames in error", + description="", + default = 0, + min= 0, + max=65535) diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py new file mode 100644 index 00000000000..c158ff115fa --- /dev/null +++ b/release/io/netrender/utils.py @@ -0,0 +1,80 @@ +import bpy +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +VERSION = b"0.3" + +PATH_PREFIX = "/tmp/" + +QUEUED = 0 +DISPATCHED = 1 +DONE = 2 +ERROR = 3 + +def clientConnection(scene): + netrender = scene.network_render + + conn = http.client.HTTPConnection(netrender.server_address, netrender.server_port) + + if clientVerifyVersion(conn): + return conn + else: + conn.close() + return None + +def clientVerifyVersion(conn): + conn.request("GET", "version") + response = conn.getresponse() + + if response.status != http.client.OK: + conn.close() + return False + + server_version = response.read() + + if server_version != VERSION: + print("Incorrect server version!") + print("expected", VERSION, "received", server_version) + return False + + return True + +def clientSendJob(conn, scene, anim = False, chunks = 5): + + if anim: + job_frame = "%i:%i" % (scene.start_frame, scene.end_frame) + else: + job_frame = "%i" % (scene.current_frame, ) + + blacklist = [] + + filename = bpy.data.filename + + name = scene.network_render.job_name + + if name == "[default]": + path, name = os.path.split(filename) + + for slave in scene.network_render.slaves_blacklist: + blacklist.append(slave.id) + + blacklist = " ".join(blacklist) + + headers = {"job-frame":job_frame, "job-name":name, "job-chunks": str(chunks), "slave-blacklist": blacklist} + + # try to send path first + conn.request("POST", "job", filename, headers=headers) + response = conn.getresponse() + + # if not found, send whole file + if response.status == http.client.NOT_FOUND: + f = open(bpy.data.filename, "rb") + conn.request("PUT", "file", f, headers=headers) + f.close() + response = conn.getresponse() + + return response.getheader("job-id") + +def clientRequestResult(conn, scene, job_id): + conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) -- cgit v1.2.3 From 47190b2009f528df4050ac8ac0216990d5e12a53 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Sat, 29 Aug 2009 17:25:26 +0000 Subject: Missing null check in particle edit code caused a crash when using search boxes. --- source/blender/editors/physics/editparticle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index c0b600edf36..220928cb79c 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -199,7 +199,7 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) BKE_ptcache_ids_from_object(&pidlist, ob); /* in the case of only one editable thing, set pset->edittype accordingly */ - if(pidlist.first == pidlist.last) { + if(pidlist.first && pidlist.first == pidlist.last) { pid = pidlist.first; switch(pid->type) { case PTCACHE_TYPE_PARTICLES: -- cgit v1.2.3 From a261330d5c5622701a46d0ce2da95929ece89406 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 29 Aug 2009 18:02:37 +0000 Subject: 2.5: Bugfix: Preview-Render didn't update when changing material/texture id block/slot. --- source/blender/makesrna/intern/rna_material.c | 2 ++ source/blender/makesrna/intern/rna_object.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index db573f0a666..9d51c687d09 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1658,11 +1658,13 @@ void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeg RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, activeget, activeset, NULL); RNA_def_property_ui_text(prop, "Active Texture", "Active texture slot being displayed."); + RNA_def_property_update(prop, NC_TEXTURE|ND_SHADING_DRAW, NULL); prop= RNA_def_property(srna, "active_texture_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "texact"); RNA_def_property_range(prop, 0, MAX_MTEX-1); RNA_def_property_ui_text(prop, "Active Texture Index", "Index of active texture slot."); + RNA_def_property_update(prop, NC_TEXTURE|ND_SHADING_DRAW, NULL); } #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index cae96b0af4b..0535ae131bc 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1141,7 +1141,8 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "actcol"); RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set", "rna_Object_active_material_index_range"); RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot."); - + RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, NULL); + /* transform */ prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); -- cgit v1.2.3 From 5ab556e0668ef7811e2ac69121813e16bce10146 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 29 Aug 2009 20:29:29 +0000 Subject: bugfix: on windows, it wouldn't correctly recognize directories and import python modules on load. BLI_exist vs BLI_exists (fun times were had by all) --- source/blender/python/intern/bpy_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 43db337c6db..ac8acc2c07c 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -618,7 +618,7 @@ void BPY_run_ui_scripts(bContext *C, int reload) } } #ifndef __linux__ - else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exists(path))) { + else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) { #else else if(de->d_type==DT_DIR) { BLI_join_dirfile(path, dirname, de->d_name); -- cgit v1.2.3 From 7a562283434ea143cd6ec26b529dd3ea33047aa4 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 29 Aug 2009 21:51:58 +0000 Subject: 2.5 Paint: * Don't do shared vertex colors for every vpaint dot. Profiling on a large mesh showed vpaint spent about 65% of the time in this function, but most of the time no difference will be apparent in the result. (Could make an operator so the user can force this operation after doing some painting.) TODO: Profiling now shows most time spent in drawing the mesh. (This is done twice for vpaint, the first time for finding backbuf sampling.) --- source/blender/editors/sculpt_paint/paint_vertex.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 581d10ee883..f66a9fbc1ed 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1733,8 +1733,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); - do_shared_vertexcol(me); - ED_region_tag_redraw(vc->ar); DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA); -- cgit v1.2.3 From c6ccf5fd2e9ff8a0bfe045c85e4675b3a8940255 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Sat, 29 Aug 2009 21:52:57 +0000 Subject: Cloth didn't update properly in particle mode. Don't understand why the particle mode check was there to begin with, but if removing it causes trouble later on some other solution can be figured out. --- source/blender/blenkernel/intern/DerivedMesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 84cccd8b939..43b9a63a2c1 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2077,7 +2077,7 @@ static void clear_mesh_caches(Object *ob) static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) { Object *obact = scene->basact?scene->basact->object:NULL; - int editing = paint_facesel_test(ob)|(ob && ob->mode & OB_MODE_PARTICLE_EDIT); + int editing = paint_facesel_test(ob); int needMapping = editing && (ob==obact); float min[3], max[3]; -- cgit v1.2.3 From 530deb73a988a2adfc8add73b842507b68254812 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 29 Aug 2009 23:05:46 +0000 Subject: Workarounds for 2 rna bugs. - mesh face properties that have no data are tested for length. - the rawtype of MFace.verts is not set, defaulting to CHAR, meaning only verts with 256 verts could be added from python. temp workaround by making PROP_RAW_INT the first in the enum. For some reason makesrna.c doesn't set the raw type MFace.verts at all. --- source/blender/makesrna/RNA_types.h | 8 ++++---- source/blender/makesrna/intern/rna_mesh.c | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 1acbfb21385..b57cbc3aa2c 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -176,11 +176,11 @@ typedef struct CollectionPointerLink { } CollectionPointerLink; typedef enum RawPropertyType { - PROP_RAW_CHAR, + PROP_RAW_INT, // XXX - abused for types that are not set, eg. MFace.verts, needs fixing. PROP_RAW_SHORT, - PROP_RAW_INT, - PROP_RAW_FLOAT, - PROP_RAW_DOUBLE + PROP_RAW_CHAR, + PROP_RAW_DOUBLE, + PROP_RAW_FLOAT } RawPropertyType; typedef struct RawArray { diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 4d53986be4f..edecfc8cdb0 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -708,7 +708,10 @@ static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value) static int rna_MeshFace_verts_get_length(PointerRNA *ptr) { MFace *face= (MFace*)ptr->data; - return face->v4 ? 4 : 3; + if(face) + return face->v4 ? 4 : 3; + else + return 4; // XXX rna_raw_access wants the length of a dummy face. this needs fixing. - Campbell } static int rna_MeshFace_verts_set_length(PointerRNA *ptr, int length) -- cgit v1.2.3 From 371c3bcf7a34c980c99829f2507b56f76d1b481a Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sat, 29 Aug 2009 23:13:27 +0000 Subject: 2.5 Sound: Bugfixes. --- source/blender/blenloader/intern/readfile.c | 6 +++--- source/blender/editors/space_logic/logic_window.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 070c873686c..64fabc825bc 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5070,9 +5070,6 @@ static void direct_link_sound(FileData *fd, bSound *sound) sound->packedfile = direct_link_packedfile(fd, sound->packedfile); sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile); - - if(sound->cache) - sound_cache(sound, 1); } static void lib_link_sound(FileData *fd, Main *main) @@ -5086,6 +5083,9 @@ static void lib_link_sound(FileData *fd, Main *main) sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system sound_load(main, sound); + + if(sound->cache) + sound_cache(sound, 1); } sound= sound->id.next; } diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index d4475527058..118bcaa0cf4 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -28,6 +28,7 @@ #include #include +#include #include "DNA_actuator_types.h" #include "DNA_controller_types.h" @@ -2016,8 +2017,8 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh { uiDefButF(block, NUM, 0, "Minimum Gain: ", xco+10, yco-110, wval, 19, &sa->sound3D.min_gain, 0.0, 1.0, 0.0, 0.0, "The minimum gain of the sound, no matter how far it is away."); uiDefButF(block, NUM, 0, "Maximum Gain: ", xco+10, yco-132, wval, 19, &sa->sound3D.max_gain, 0.0, 1.0, 0.0, 0.0, "The maximum gain of the sound, no matter how near it is.."); - uiDefButF(block, NUM, 0, "Reference Distance: ", xco+10, yco-154, wval, 19, &sa->sound3D.reference_distance, 0.0, 1000.0, 0.0, 0.0, "The reference distance is the distance where the sound has a gain of 1.0."); - uiDefButF(block, NUM, 0, "Maximum Distance: ", xco+10, yco-176, wval, 19, &sa->sound3D.max_distance, 0.0, 1000.0, 0.0, 0.0, "The maximum distance at which you can hear the sound."); + uiDefButF(block, NUM, 0, "Reference Distance: ", xco+10, yco-154, wval, 19, &sa->sound3D.reference_distance, 0.0, FLT_MAX, 0.0, 0.0, "The reference distance is the distance where the sound has a gain of 1.0."); + uiDefButF(block, NUM, 0, "Maximum Distance: ", xco+10, yco-176, wval, 19, &sa->sound3D.max_distance, 0.0, FLT_MAX, 0.0, 0.0, "The maximum distance at which you can hear the sound."); uiDefButF(block, NUM, 0, "Rolloff: ", xco+wval+10, yco-110, wval, 19, &sa->sound3D.rolloff_factor, 0.0, 5.0, 0.0, 0.0, "The rolloff factor defines the influence factor on volume depending on distance."); uiDefButF(block, NUM, 0, "Cone Outer Gain: ", xco+wval+10, yco-132, wval, 19, &sa->sound3D.cone_outer_gain, 0.0, 1.0, 0.0, 0.0, "The gain outside the outer cone. The gain in the outer cone will be interpolated between this value und the normal gain in the inner cone."); uiDefButF(block, NUM, 0, "Cone Outer Angle: ", xco+wval+10, yco-154, wval, 19, &sa->sound3D.cone_outer_angle, 0.0, 360.0, 0.0, 0.0, "The angle of the outer cone."); -- cgit v1.2.3 From c2696ae63182da338d69a5127f03b1ad8b88f6c9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 29 Aug 2009 23:35:13 +0000 Subject: quiet warnings --- source/blender/editors/include/ED_particle.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index dcac51928a3..28807caa255 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -37,6 +37,7 @@ struct ParticleSystem; struct RadialControl; struct rcti; struct wmWindowManager; +struct PTCacheEdit; /* particle edit mode */ void PE_free_ptcache_edit(struct PTCacheEdit *edit); -- cgit v1.2.3 From 2cb6078900c0083a6b64b5644af50d44a7fbeb8f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 30 Aug 2009 02:09:57 +0000 Subject: was crashing when joining in-link to in-link for the logic buttons. --- source/blender/editors/interface/interface_handlers.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b69e8319956..79c707f5535 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -678,7 +678,11 @@ static void ui_add_link(uiBut *from, uiBut *to) return; } - if (from->type==LINK && to->type==INLINK) { + if (from->type==INLINK && to->type==INLINK) { + printf("cannot link\n"); + return; + } + else if (from->type==LINK && to->type==INLINK) { if( from->link->tocode != (int)to->hardmin ) { printf("cannot link\n"); return; -- cgit v1.2.3 From c9d2a1b71bd8a2155b94f9c00631e526a7be8778 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 30 Aug 2009 02:40:42 +0000 Subject: bug fixes and small changes --- release/io/netrender/master.py | 57 +++++++++++++++++++-------------------- release/io/netrender/model.py | 2 +- release/io/netrender/operators.py | 8 +++--- release/io/netrender/slave.py | 7 +++-- release/io/netrender/ui.py | 12 +++++++++ 5 files changed, 50 insertions(+), 36 deletions(-) diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 5a62ef1a8bf..daca3bcf653 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -5,7 +5,10 @@ import subprocess, shutil, time, hashlib from netrender.utils import * import netrender.model - +JOB_WAITING = 0 # before all data has been entered +JOB_PAUSED = 1 # paused by user +JOB_QUEUED = 2 # ready to be dispatched + class MRenderSlave(netrender.model.RenderSlave): def __init__(self, name, adress, stats): super().__init__() @@ -25,7 +28,7 @@ class MRenderSlave(netrender.model.RenderSlave): # sorting key for jobs def groupKey(job): - return (job.framesLeft() > 0, job.priority, job.credits) + return (job.status, job.framesLeft() > 0, job.priority, job.credits) class MRenderJob(netrender.model.RenderJob): def __init__(self, job_id, name, path, chunks = 1, priority = 1, credits = 100.0, blacklist = []): @@ -33,6 +36,7 @@ class MRenderJob(netrender.model.RenderJob): self.id = job_id self.name = name self.path = path + self.status = JOB_WAITING self.frames = [] self.chunks = chunks self.priority = priority @@ -40,6 +44,9 @@ class MRenderJob(netrender.model.RenderJob): self.blacklist = blacklist self.last_dispatched = time.time() + def start(self): + self.status = JOB_QUEUED + def update(self): self.credits -= 5 # cost of one frame self.credits += (time.time() - self.last_dispatched) / 60 @@ -233,8 +240,6 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): message = [] for job in self.server: - results = job.status() - message.append(job.serialize()) self.send_head() @@ -322,25 +327,14 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_chunks = int(self.headers.get('job-chunks', "1")) blacklist = self.headers.get('slave-blacklist', '').split() - print("blacklist", blacklist) - job_path = str(self.rfile.read(length), encoding='utf8') if os.path.exists(job_path): - f = open(job_path, "rb") - buf = f.read() - f.close() + job_id = self.server.nextJobID() - job_id = hashlib.md5(buf).hexdigest() - - del buf - - job = self.server.getJobByID(job_id) + job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) + self.server.addJob(job) - if job == None: - job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) - self.server.addJob(job) - if ":" in job_frame_string: frame_start, frame_end = [int(x) for x in job_frame_string.split(":")] @@ -349,6 +343,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: job_frame = int(job_frame_string) frame = job.addFrame(job_frame) + + job.start() self.send_head(headers={"job-id": job_id}) else: @@ -385,9 +381,9 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): length = int(self.headers['content-length']) job_frame_string = self.headers['job-frame'] - name, stats = eval(str(self.rfile.read(length), encoding='utf8')) + slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - slave_id = self.server.addSlave(name, self.client_address, stats) + slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) self.send_head(headers = {"slave-id": slave_id}) @@ -410,23 +406,19 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_chunks = int(self.headers.get('job-chunks', "1")) blacklist = self.headers.get('slave-blacklist', '').split() - buf = self.rfile.read(length) + job_id = self.server.nextJobID() - job_id = hashlib.md5(buf).hexdigest() + buf = self.rfile.read(length) job_path = job_id + ".blend" f = open(PATH_PREFIX + job_path, "wb") f.write(buf) f.close() - del buf - job = self.server.getJobByID(job_id) - - if job == None: - job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) - self.server.addJob(job) + job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) + self.server.addJob(job) if ":" in job_frame_string: frame_start, frame_end = [int(x) for x in job_frame_string.split(":")] @@ -437,6 +429,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_frame = int(job_frame_string) frame = job.addFrame(job_frame) + job.start() + self.send_head(headers={"job-id": job_id}) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "render": @@ -495,6 +489,11 @@ class RenderMasterServer(http.server.HTTPServer): self.jobs_map = {} self.slaves = [] self.slaves_map = {} + self.job_id = 0 + + def nextJobID(self): + self.job_id += 1 + return str(self.job_id) def addSlave(self, name, adress, stats): slave = MRenderSlave(name, adress, stats) @@ -540,7 +539,7 @@ class RenderMasterServer(http.server.HTTPServer): def getNewJob(self, slave_id): if self.jobs: for job in reversed(self.jobs): - if job.framesLeft() > 0 and slave_id not in job.blacklist: + if job.status == JOB_QUEUED and job.framesLeft() > 0 and slave_id not in job.blacklist: return job, job.getFrames() return None, None diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 6e68929d340..98866ff1dfc 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -65,7 +65,7 @@ class RenderJob: def __len__(self): return len(self.frames) - def status(self): + def framesStatus(self): results = { QUEUED: 0, DISPATCHED: 0, diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 3355c3d1a0b..8df662b6b52 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -66,7 +66,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): netprops.jobs.add() job = netprops.jobs[-1] - job_results = j.status() + job_results = j.framesStatus() job.id = j.id job.name = j.name @@ -210,15 +210,15 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): __props__ = [] def poll(self, context): - netrender = scene.network_render - return netrender.active_job_index >= 0 and len(netrender.jobs) > 0 + netprops = context.scene.network_render + return netprops.active_job_index >= 0 and len(netprops.jobs) > 0 def execute(self, context): netprops = context.scene.network_render conn = clientConnection(context.scene) if conn: - job = netprops.jobs[netrender.active_job_index] + job = netprops.jobs[netprops.active_job_index] conn.request("POST", "cancel", headers={"job-id":job.id}) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 03c6803955e..59c474293b3 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -11,7 +11,10 @@ INCREMENT_TIMEOUT = 1 def slave_Info(): sysname, nodename, release, version, machine = os.uname() - return (nodename, sysname + " " + release + " " + machine) + slave = netrender.model.RenderSlave() + slave.name = nodename + slave.stats = sysname + " " + release + " " + machine + return slave def testCancel(conn, job_id): conn.request("HEAD", "status", headers={"job-id":job_id}) @@ -35,7 +38,7 @@ def render_slave(engine, scene): conn = clientConnection(scene) if conn: - conn.request("POST", "slave", repr(slave_Info())) + conn.request("POST", "slave", repr(slave_Info().serialize())) response = conn.getresponse() slave_id = response.getheader("slave-id") diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 2fd2b9a317f..71b013c5a63 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -255,6 +255,18 @@ NetRenderSlave.StringProperty( attr="adress", maxlen = 64, default = "") +NetRenderSlave.StringProperty( attr="last_seen", + name="Last time slave was seen by server", + description="", + maxlen = 64, + default = "") + +NetRenderSlave.StringProperty( attr="stats", + name="Hardware stats of the slave", + description="", + maxlen = 128, + default = "") + NetRenderJob.StringProperty( attr="id", name="ID of the job", description="", -- cgit v1.2.3 From 4b206c675c21322cf98700dddfc0d0485b3d6ffc Mon Sep 17 00:00:00 2001 From: Tom Musgrove Date: Sun, 30 Aug 2009 03:10:03 +0000 Subject: just some comment fixes --- source/blender/blenkernel/BKE_shrinkwrap.h | 4 ++-- source/blender/blenkernel/intern/shrinkwrap.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index eb0e3c4ef00..5b413ae4e44 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -115,9 +115,9 @@ typedef struct ShrinkwrapCalcData int vgroup; //Vertex group num struct DerivedMesh *target; //mesh we are shrinking to - SpaceTransform local2target; //transform to move bettwem local and target space + SpaceTransform local2target; //transform to move between local and target space - float keepDist; //Distance to kept from target (units are in local space) + float keepDist; //Distance to keep above target surface (units are in local space) } ShrinkwrapCalcData; diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 27357d92aae..efb7db04029 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -574,7 +574,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object } } - //Just to make sure we are not letting any memory behind + //Just to make sure we are not leaving any memory behind assert(ssmd.emCache == NULL); assert(ssmd.mCache == NULL); } -- cgit v1.2.3 From e104b429295766f9276ea854e02f085cf65e623f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Aug 2009 04:48:34 +0000 Subject: Grease Pencil: Drawing Improvements * Smooth strokes can now be drawn again, with normal (i.e. reasonably speedy feedback again). Previously slow drawing was caused by a bad notifier being used - the full screen was redrawn each time instead of just the relevant region. Now, only the relevant region is redrawn while drawing, and a proper flush is done for the rest of the screen at the end. * Made drawing straight lines a proper drawing 'mode' for Grease Pencil now. Use the Ctrl-D-LMB hotkey to draw straight lines in this way. The (buffer) line drawn now will accurately represent the final straight line instead of drawing the freehand path taken as before. --- source/blender/editors/gpencil/gpencil_edit.c | 4 +- source/blender/editors/gpencil/gpencil_intern.h | 7 ++ source/blender/editors/gpencil/gpencil_ops.c | 5 +- source/blender/editors/gpencil/gpencil_paint.c | 153 ++++++++++++++---------- 4 files changed, 105 insertions(+), 64 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 2faf3ccbbda..b2228134750 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -169,7 +169,7 @@ static int gp_data_add_exec (bContext *C, wmOperator *op) } /* notifiers */ - WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX need a nicer one that will work return OPERATOR_FINISHED; } @@ -216,7 +216,7 @@ static int gp_data_unlink_exec (bContext *C, wmOperator *op) } /* notifiers */ - WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX need a nicer one that will work return OPERATOR_FINISHED; } diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index cc98d491f7a..2c7bf9156c3 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -40,6 +40,13 @@ struct wmOperatorType; void GPENCIL_OT_draw(struct wmOperatorType *ot); +/* Paint Modes for operator*/ +typedef enum eGPencil_PaintModes { + GP_PAINTMODE_DRAW = 0, + GP_PAINTMODE_ERASER, + GP_PAINTMODE_DRAW_STRAIGHT, +} eGPencil_PaintModes; + /* buttons editing --- */ void GPENCIL_OT_data_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 364b27b61b0..2d23a331211 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -56,9 +56,12 @@ void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap) /* Draw */ /* draw */ WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); + /* draw - straight lines */ + kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT); /* erase */ kmi=WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY); - RNA_enum_set(kmi->ptr, "mode", 1); // XXX need to make the defines for this public (this is GP_PAINTMODE_ERASER) + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); } /* ****************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 82dc76a2152..9cf6f3d751f 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -68,16 +68,6 @@ #include "gpencil_intern.h" -/* ******************************************* */ -/* Context Wrangling... */ - -/* check if context is suitable for drawing */ -static int gpencil_draw_poll (bContext *C) -{ - // TODO: must check context for Grease Pencil data... - return 1; -} - /* ******************************************* */ /* 'Globals' and Defines */ @@ -121,12 +111,6 @@ enum { GP_STATUS_DONE /* painting done */ }; -/* values for tGPsdata->paintmode */ -enum { - GP_PAINTMODE_DRAW = 0, - GP_PAINTMODE_ERASER -}; - /* Return flags for adding points to stroke buffer */ enum { GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */ @@ -138,7 +122,6 @@ enum { /* Runtime flags */ enum { GP_PAINTFLAG_FIRSTRUN = (1<<0), /* operator just started */ - GP_PAINTFLAG_STRAIGHTLINES = (1<<1), /* only take the endpoints of a stroke */ }; /* ------ */ @@ -152,16 +135,21 @@ enum { /* minimum length of new segment before new point can be added */ #define MIN_EUCLIDEAN_PX (U.gp_euclideandist) -/* macro to test if only converting endpoints - only for use when converting! */ -// XXX for now, don't test for editpaint too... -//#define GP_BUFFER2STROKE_ENDPOINTS ((gpd->flag & GP_DATA_EDITPAINT) && (p->flags & GP_PAINTFLAG_STRAIGHTLINES)) -#define GP_BUFFER2STROKE_ENDPOINTS ((p->flags & GP_PAINTFLAG_STRAIGHTLINES)) - /* ------ */ /* Forward defines for some functions... */ static void gp_session_validatebuffer(tGPsdata *p); +/* ******************************************* */ +/* Context Wrangling... */ + +/* check if context is suitable for drawing */ +static int gpencil_draw_poll (bContext *C) +{ + /* check if current context can support GPencil data */ + return (gpencil_data_get_pointers(C, NULL) != NULL); +} + /* ******************************************* */ /* Calculations/Conversions */ @@ -258,26 +246,68 @@ static short gp_stroke_addpoint (tGPsdata *p, int mval[2], float pressure) bGPdata *gpd= p->gpd; tGPspoint *pt; - /* check if still room in buffer */ - if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX) - return GP_STROKEADD_OVERFLOW; - - /* get pointer to destination point */ - pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size); - - /* store settings */ - pt->x= mval[0]; - pt->y= mval[1]; - pt->pressure= pressure; - - /* increment counters */ - gpd->sbuffer_size++; - - /* check if another operation can still occur */ - if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX) - return GP_STROKEADD_FULL; - else + /* check painting mode */ + if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { + /* straight lines only - i.e. only store start and end point in buffer */ + if (gpd->sbuffer_size == 0) { + /* first point in buffer (start point) */ + pt= (tGPspoint *)(gpd->sbuffer); + + /* store settings */ + pt->x= mval[0]; + pt->y= mval[1]; + pt->pressure= pressure; + + /* increment buffer size */ + gpd->sbuffer_size++; + } + else { + /* normally, we just reset the endpoint to the latest value + * - assume that pointers for this are always valid... + */ + pt= ((tGPspoint *)(gpd->sbuffer) + 1); + + /* store settings */ + pt->x= mval[0]; + pt->y= mval[1]; + pt->pressure= pressure; + + /* if this is just the second point we've added, increment the buffer size + * so that it will be drawn properly... + * otherwise, just leave it alone, otherwise we get problems + */ + if (gpd->sbuffer_size != 2) + gpd->sbuffer_size= 2; + } + + /* can keep carrying on this way :) */ return GP_STROKEADD_NORMAL; + } + else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */ + /* check if still room in buffer */ + if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX) + return GP_STROKEADD_OVERFLOW; + + /* get pointer to destination point */ + pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size); + + /* store settings */ + pt->x= mval[0]; + pt->y= mval[1]; + pt->pressure= pressure; + + /* increment counters */ + gpd->sbuffer_size++; + + /* check if another operation can still occur */ + if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX) + return GP_STROKEADD_FULL; + else + return GP_STROKEADD_NORMAL; + } + + /* just say it's normal for now, since we don't have another state... */ + return GP_STROKEADD_NORMAL; } /* smooth a stroke (in buffer) before storing it */ @@ -287,7 +317,7 @@ static void gp_stroke_smooth (tGPsdata *p) int i=0, cmx=gpd->sbuffer_size; /* only smooth if smoothing is enabled, and we're not doing a straight line */ - if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || GP_BUFFER2STROKE_ENDPOINTS) + if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT)) return; /* don't try if less than 2 points in buffer */ @@ -320,7 +350,7 @@ static void gp_stroke_simplify (tGPsdata *p) short i, j; /* only simplify if simlification is enabled, and we're not doing a straight line */ - if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || GP_BUFFER2STROKE_ENDPOINTS) + if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT)) return; /* don't simplify if less than 4 points in buffer */ @@ -388,11 +418,10 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) tGPspoint *ptc; int i, totelem; - /* get total number of points to allocate space for: - * - in 'Draw Mode', holding the Ctrl-Modifier will only take endpoints - * - otherwise, do whole stroke + /* get total number of points to allocate space for + * - drawing straight-lines only requires the endpoints */ - if (GP_BUFFER2STROKE_ENDPOINTS) + if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) totelem = (gpd->sbuffer_size >= 2) ? 2: gpd->sbuffer_size; else totelem = gpd->sbuffer_size; @@ -416,8 +445,8 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) gps->flag= gpd->sbuffer_sflag; /* copy points from the buffer to the stroke */ - if (GP_BUFFER2STROKE_ENDPOINTS) { - /* 'Draw Mode' + Ctrl-Modifier - only endpoints */ + if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { + /* straight lines only -> only endpoints */ { /* first point */ ptc= gpd->sbuffer; @@ -1013,7 +1042,6 @@ static int gpencil_draw_init (bContext *C, wmOperator *op) { tGPsdata *p; int paintmode= RNA_enum_get(op->ptr, "mode"); - int straightLines= RNA_boolean_get(op->ptr, "straight_lines"); /* check context */ p= op->customdata= gp_session_initpaint(C); @@ -1033,10 +1061,6 @@ static int gpencil_draw_init (bContext *C, wmOperator *op) /* radius for eraser circle is defined in userprefs now */ p->radius= U.gp_eraser; - /* set line-drawing settings (straight or freehand lines) */ - if (straightLines) - p->flags |= GP_PAINTFLAG_STRAIGHTLINES; - /* everything is now setup ok */ return 1; } @@ -1126,8 +1150,8 @@ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *even { tGPsdata *p= op->customdata; ARegion *ar= p->ar; - PointerRNA itemptr; - float mousef[2]; + //PointerRNA itemptr; + //float mousef[2]; int tablet=0; /* convert from window-space to area-space mouse coordintes */ @@ -1162,6 +1186,7 @@ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *even return; } +#if 0 // NOTE: disabled for now, since creating this data is currently useless anyways (and slows things down) /* fill in stroke data (not actually used directly by gpencil_draw_apply) */ RNA_collection_add(op->ptr, "stroke", &itemptr); @@ -1169,12 +1194,13 @@ static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *even mousef[1]= p->mval[1]; RNA_float_set_array(&itemptr, "mouse", mousef); RNA_float_set(&itemptr, "pressure", p->pressure); +#endif /* apply the current latest drawing point */ gpencil_draw_apply(C, op, p); /* force refresh */ - WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ } /* ------------------------------- */ @@ -1232,7 +1258,7 @@ static int gpencil_draw_exec (bContext *C, wmOperator *op) gpencil_draw_exit(C, op); /* refreshes */ - WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX need a nicer one that will work /* done */ return OPERATOR_FINISHED; @@ -1311,6 +1337,10 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* basically, this should be mouse-button up */ printf("\t\tGP - end of stroke \n"); gpencil_draw_exit(C, op); + + /* one last flush before we're done */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX need a nicer one that will work + return OPERATOR_FINISHED; } else { @@ -1340,6 +1370,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* scrolling mouse-wheel increases radius of eraser * - though this is quite a difficult action to perform */ + // XXX this stuff doesn't work case WHEELUPMOUSE: p->radius += 1.5f; break; @@ -1358,7 +1389,8 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* ------------------------------- */ static EnumPropertyItem prop_gpencil_drawmodes[] = { - {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw", ""}, + {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", ""}, + {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", ""}, {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1382,7 +1414,6 @@ void GPENCIL_OT_draw (wmOperatorType *ot) /* settings for drawing */ RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to intepret mouse movements."); - RNA_def_boolean(ot->srna, "straight_lines", 0, "Straight Lines", "Only take the endpoints of the strokes, so that straight lines can be drawn."); - + // xxx the stuff below is used only for redo operator, but is not really working RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); } -- cgit v1.2.3 From 05ebac71ca72966efd2d5d8692f5959c33a9d621 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Aug 2009 05:54:27 +0000 Subject: Grease Pencil: Bugfix (Dots) + RNA Wrapping * Making single dots should be possible again. * Wrapped the debug option, 'Show Points', for layers, which makes all the points on the layer get drawn with dots indicating positions of stroke points. --- source/blender/editors/gpencil/gpencil_buttons.c | 14 +++++++------- source/blender/editors/gpencil/gpencil_paint.c | 6 +++++- source/blender/makesrna/intern/rna_gpencil.c | 4 ++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 954f6c7e61e..f29d37311fb 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -203,13 +203,6 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) subcol= uiLayoutColumn(col, 1); uiItemR(subcol, NULL, 0, &ptr, "line_thickness", UI_ITEM_R_SLIDER); - /* debugging options */ - if (G.f & G_DEBUG) { - // XXX this option hasn't been wrapped yet... since it's just debug - //subcol= uiLayoutColumn(col, 1); - // uiItemR(subrow, NULL, 0, &ptr, "show_points", 0); - } - /* right column ................... */ col= uiLayoutColumn(split, 0); @@ -218,6 +211,13 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) uiItemR(subcol, "Onion Skinning", 0, &ptr, "use_onion_skinning", 0); uiItemR(subcol, "GStep", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep) + /* debugging options */ + // XXX re-enable the debug-only checks later + //if (G.f & G_DEBUG) { + subcol= uiLayoutColumn(col, 1); + uiItemR(subcol, NULL, 0, &ptr, "show_points", 0); + //} + /* additional options... */ // None at the moment... } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 9cf6f3d751f..c18a807f9d4 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -161,8 +161,12 @@ static short gp_stroke_filtermval (tGPsdata *p, int mval[2], int pmval[2]) int dx= abs(mval[0] - pmval[0]); int dy= abs(mval[1] - pmval[1]); + /* if buffer is empty, just let this go through (i.e. so that dots will work) */ + if (p->gpd->sbuffer_size == 0) + return 1; + /* check if mouse moved at least certain distance on both axes (best case) */ - if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) + else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) return 1; /* check if the distance since the last point is significant enough */ diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 340ba1a0f31..e025aca010c 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -208,6 +208,10 @@ void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT); RNA_def_property_ui_text(prop, "Selected", "Layer is selected for editing in the DopeSheet."); + prop= RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_DRAWDEBUG); + RNA_def_property_ui_text(prop, "Show Points", "Draw the points which make up the strokes (for debugging purposes)."); + } void rna_def_gpencil_data(BlenderRNA *brna) -- cgit v1.2.3 From 46ba8b6edb242b5cf7605cf04c79c85159eb222c Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Aug 2009 06:10:38 +0000 Subject: Grease Pencil: Hacky fix for "broken strokes" bug (pun intended) ;) For the strokes drawn using OpenGL lines, moderately-sized changes in the pressure between two points could result in the stroke being disjointed, since a new GL_LINE_STRIP would need to be created with the new line thickness due to the new pressure value. (In reference to the summary of this commit, this bug was noticed by Matt Ebb (broken). This bug is also in 2.4x, but was suprisingly not really noticed.) --- source/blender/editors/gpencil/drawgpencil.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 4a48e9a4e3b..a89a038d760 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -122,11 +122,21 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick glBegin(GL_LINE_STRIP); for (i=0, pt=points; i < totpoints && pt; i++, pt++) { + /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, + * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) + */ if (fabs(pt->pressure - oldpressure) > 0.2f) { glEnd(); glLineWidth(pt->pressure * thickness); glBegin(GL_LINE_STRIP); + /* need to roll-back one point to ensure that there are no gaps in the stroke */ + if (i != 0) { + pt--; + glVertex2f(pt->x, pt->y); + pt++; + } + /* now the point we want... */ glVertex2f(pt->x, pt->y); oldpressure = pt->pressure; @@ -206,11 +216,21 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes /* draw stroke curve */ glBegin(GL_LINE_STRIP); for (i=0, pt=points; i < totpoints && pt; i++, pt++) { + /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, + * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) + */ if (fabs(pt->pressure - oldpressure) > 0.2f) { glEnd(); glLineWidth(pt->pressure * thickness); glBegin(GL_LINE_STRIP); + /* need to roll-back one point to ensure that there are no gaps in the stroke */ + if (i != 0) { + pt--; + glVertex3f(pt->x, pt->y, pt->z); + pt++; + } + /* now the point we want... */ glVertex3f(pt->x, pt->y, pt->z); oldpressure = pt->pressure; -- cgit v1.2.3 From 466d59461d060b291dc1df8bd8b26fcd8d59ca1d Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sun, 30 Aug 2009 06:42:53 +0000 Subject: * Limit available texture coordinate types when using volume materials --- source/blender/makesrna/intern/rna_material.c | 68 ++++++++++++++++++++------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 9d51c687d09..651aeae217e 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -35,6 +35,20 @@ #include "WM_types.h" +static EnumPropertyItem prop_texture_coordinates_items[] = { +{TEXCO_GLOB, "GLOBAL", 0, "Global", "Uses global coordinates for the texture coordinates."}, +{TEXCO_OBJECT, "OBJECT", 0, "Object", "Uses linked object's coordinates for texture coordinates."}, +{TEXCO_UV, "UV", 0, "UV", "Uses UV coordinates for texture coordinates."}, +{TEXCO_ORCO, "ORCO", 0, "Generated", "Uses the original undeformed coordinates of the object."}, +{TEXCO_STRAND, "STRAND", 0, "Strand", "Uses normalized strand texture coordinate (1D)."}, +{TEXCO_STICKY, "STICKY", 0, "Sticky", "Uses mesh's sticky coordinates for the texture coordinates."}, +{TEXCO_WINDOW, "WINDOW", 0, "Window", "Uses screen coordinates as texture coordinates."}, +{TEXCO_NORM, "NORMAL", 0, "Normal", "Uses normal vector as texture coordinates."}, +{TEXCO_REFL, "REFLECTION", 0, "Reflection", "Uses reflection vector as texture coordinates."}, +{TEXCO_STRESS, "STRESS", 0, "Stress", "Uses the difference of edge lengths compared to original coordinates of the mesh."}, +{TEXCO_TANGENT, "TANGENT", 0, "Tangent", "Uses the optional tangent vector as texture coordinates."}, +{0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -207,6 +221,42 @@ void rna_Material_use_nodes_set(PointerRNA *ptr, int value) ED_node_shader_default(ma); } +static EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Material *ma= (Material*)ptr->id.data; + EnumPropertyItem *item= NULL; + int totitem= 0; + + if(C==NULL) { + return prop_texture_coordinates_items; + } + + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_GLOB); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_OBJECT); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_ORCO); + + if(ma->material_type == MA_TYPE_VOLUME) { + + } + else if (ELEM3(ma->material_type, MA_TYPE_SURFACE, MA_TYPE_HALO, MA_TYPE_WIRE)) { + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_UV); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_STRAND); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_STICKY); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_WINDOW); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_NORM); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_REFL); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_STRESS); + RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_TANGENT); + } + + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; +} + + #else static void rna_def_material_mtex(BlenderRNA *brna) @@ -214,21 +264,6 @@ static void rna_def_material_mtex(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_texture_coordinates_items[] = { - {TEXCO_GLOB, "GLOBAL", 0, "Global", "Uses global coordinates for the texture coordinates."}, - {TEXCO_OBJECT, "OBJECT", 0, "Object", "Uses linked object's coordinates for texture coordinates."}, - {TEXCO_UV, "UV", 0, "UV", "Uses UV coordinates for texture coordinates."}, - {TEXCO_ORCO, "ORCO", 0, "Generated", "Uses the original undeformed coordinates of the object."}, - {TEXCO_STRAND, "STRAND", 0, "Strand", "Uses normalized strand texture coordinate (1D)."}, - {TEXCO_STICKY, "STICKY", 0, "Sticky", "Uses mesh's sticky coordinates for the texture coordinates."}, - {TEXCO_WINDOW, "WINDOW", 0, "Window", "Uses screen coordinates as texture coordinates."}, - {TEXCO_NORM, "NORMAL", 0, "Normal", "Uses normal vector as texture coordinates."}, - {TEXCO_REFL, "REFLECTION", 0, "Reflection", "Uses reflection vector as texture coordinates."}, - {TEXCO_STRESS, "STRESS", 0, "Stress", "Uses the difference of edge lengths compared to original coordinates of the mesh."}, - {TEXCO_TANGENT, "TANGENT", 0, "Tangent", "Uses the optional tangent vector as texture coordinates."}, - - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem prop_mapping_items[] = { {MTEX_FLAT, "FLAT", 0, "Flat", "Maps X and Y coordinates directly."}, {MTEX_CUBE, "CUBE", 0, "Cube", "Maps using the normal vector."}, @@ -271,9 +306,10 @@ static void rna_def_material_mtex(BlenderRNA *brna) prop= RNA_def_property(srna, "texture_coordinates", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "texco"); RNA_def_property_enum_items(prop, prop_texture_coordinates_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Material_texture_coordinates_itemf"); RNA_def_property_ui_text(prop, "Texture Coordinates", ""); RNA_def_property_update(prop, NC_TEXTURE, NULL); - + prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "object"); RNA_def_property_struct_type(prop, "Object"); -- cgit v1.2.3 From 970c9214b543c95921dbb51a681457b5d6597133 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sun, 30 Aug 2009 07:07:02 +0000 Subject: * Fixes for shading objects inside volumes --- source/blender/render/intern/include/render_types.h | 1 + source/blender/render/intern/source/convertblender.c | 1 + source/blender/render/intern/source/volumetric.c | 12 +++++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index c4910f7733d..e50e498228d 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -419,6 +419,7 @@ typedef struct VolumeOb typedef struct MatInside { struct MatInside *next, *prev; struct Material *ma; + struct ObjectInstanceRen *obi; } MatInside; typedef struct VolPrecachePart diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index e486daf2585..cf6246e3641 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2999,6 +2999,7 @@ static void init_camera_inside_volumes(Render *re) mi = MEM_mallocN(sizeof(MatInside), "camera inside material"); mi->ma = vo->ma; + mi->obi = obi; BLI_addtail(&(re->render_volumes_inside), mi); } diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 046a145e9da..4fa31674bbe 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -674,15 +674,25 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) { MatInside *m; Material *mat_backup; + ObjectInstanceRen *obi_backup; + float prev_alpha = shr->alpha; //if (BLI_countlist(&R.render_volumes_inside) == 0) return; /* XXX: extend to multiple volumes perhaps later */ mat_backup = shi->mat; + obi_backup = shi->obi; + m = R.render_volumes_inside.first; shi->mat = m->ma; + shi->obi = m->obi; + shi->obr = m->obi->obr; volume_trace(shi, shr, VOL_SHADE_INSIDE); - + shr->alpha += prev_alpha; + CLAMP(shr->alpha, 0.f, 1.f); + shi->mat = mat_backup; + shi->obi = obi_backup; + shi->obr = obi_backup->obr; } \ No newline at end of file -- cgit v1.2.3 From c34d49cc5b2d3bdd72f44b77b85c12e7b1717c17 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 30 Aug 2009 09:10:31 +0000 Subject: Fix for libsndfile in mingw scons config. --- config/win32-mingw-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 26fa0835255..e3834c41a81 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -35,7 +35,7 @@ BF_JACK_LIBPATH = '${BF_JACK}/lib' WITH_BF_SNDFILE = False BF_SNDFILE = LIBDIR + '/sndfile' BF_SNDFILE_INC = '${BF_SNDFILE}/include' -BF_SNDFILE_LIB = 'libsndfile' +BF_SNDFILE_LIB = 'libsndfile-1' BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib' WITH_BF_SDL = True -- cgit v1.2.3 From b9b30e2032a7f5ebcf87a22ad4ab8d66194d6125 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 30 Aug 2009 09:11:24 +0000 Subject: Same fix for libsndfile in cmake. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1e18723f5d..a92099698c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,7 @@ IF(WIN32) IF(WITH_SNDFILE) SET(SNDFILE ${LIBDIR}/sndfile) SET(SNDFILE_INC ${SNDFILE}/include) - SET(SNDFILE_LIB sndfile) + SET(SNDFILE_LIB sndfile-1) SET(SNDFILE_LIBPATH ${SNDFILE}/lib) ENDIF(WITH_SNDFILE) -- cgit v1.2.3 From d4d520c9a2312e1b03872f92b1e9be1150d167d5 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Aug 2009 11:37:29 +0000 Subject: Grease Pencil: Various Drawing Fixes * Restored option to have strokes aligned to screen space. By default, this is not enabled (the setting for view-space is the default instead). * Fixed bugs related to drawing/erasing in screen space. --- source/blender/blenkernel/intern/gpencil.c | 5 +++++ source/blender/editors/gpencil/drawgpencil.c | 2 +- source/blender/editors/gpencil/gpencil_buttons.c | 20 ++++++++++------- source/blender/editors/gpencil/gpencil_paint.c | 28 ++++++++++++------------ source/blender/makesrna/intern/rna_gpencil.c | 6 +++++ 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index dd8f44c71d5..b02128c3c68 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -214,6 +214,11 @@ bGPdata *gpencil_data_addnew (char name[]) /* initial settings */ gpd->flag = (GP_DATA_DISPINFO|GP_DATA_EXPAND); + /* for now, stick to view is also enabled by default + * since this is more useful... + */ + gpd->flag |= GP_DATA_VIEWALIGN; + return gpd; } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index a89a038d760..d6678b50d7b 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -773,7 +773,7 @@ void draw_gpencil_oglrender (bContext *C) /* pass 2: draw 2d-strokes ------------ > */ /* adjust view matrices */ - wmOrtho2(-0.375f, (float)(ar->winx)-0.375f, -0.375f, (float)(ar->winy)-0.375f); + wmOrtho2(-0.375f, (float)(ar->winx)-0.375f, -0.375f, (float)(ar->winy)-0.375f); // XXX may not be correct anymore glLoadIdentity(); /* draw it! */ diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index f29d37311fb..774f7b7162b 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -226,9 +226,13 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) /* Draw the contents for a grease-pencil panel*/ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr) { + PointerRNA gpd_ptr; bGPDlayer *gpl; uiLayout *col; + /* make new PointerRNA for Grease Pencil block */ + RNA_id_pointer_create((ID *)gpd, &gpd_ptr); + /* draw gpd settings first ------------------------------------- */ col= uiLayoutColumn(layout, 0); /* current Grease Pencil block */ @@ -238,19 +242,19 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi /* add new layer button */ uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add"); - /* 'view align' button (naming depends on context) */ -#if 0 // XXX for now, this is enabled by default anyways - if (sa->spacetype == SPACE_VIEW3D) - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); - else - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas"); -#endif - /* draw each layer --------------------------------------------- */ for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { col= uiLayoutColumn(layout, 1); gp_drawui_layer(col, gpd, gpl); } + + /* draw gpd drawing settings first ------------------------------------- */ + col= uiLayoutColumn(layout, 0); + /* label */ + uiItemL(col, "Drawing Settings:", 0); + + /* 'stick to view' option */ + uiItemR(col, NULL, 0, &gpd_ptr, "view_space_draw", 0); } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index c18a807f9d4..b5d25ce651f 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -239,8 +239,8 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) /* 2d - relative to screen (viewport area) */ else { - out[0] = (float)(mval[0]) / (float)(p->sa->winx) * 100; - out[1] = (float)(mval[1]) / (float)(p->sa->winy) * 100; + out[0] = (float)(mval[0]) / (float)(p->ar->winx) * 100; + out[1] = (float)(mval[1]) / (float)(p->ar->winy) * 100; } } @@ -310,8 +310,8 @@ static short gp_stroke_addpoint (tGPsdata *p, int mval[2], float pressure) return GP_STROKEADD_NORMAL; } - /* just say it's normal for now, since we don't have another state... */ - return GP_STROKEADD_NORMAL; + /* return invalid state for now... */ + return GP_STROKEADD_INVALID; } /* smooth a stroke (in buffer) before storing it */ @@ -614,8 +614,8 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, int mval[], int mvalo[], sho } #endif else { - x0= (int)(gps->points->x / 100 * p->sa->winx); - y0= (int)(gps->points->y / 100 * p->sa->winy); + x0= (int)(gps->points->x / 100 * p->ar->winx); + y0= (int)(gps->points->y / 100 * p->ar->winy); } /* do boundbox check first */ @@ -671,10 +671,10 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, int mval[], int mvalo[], sho } #endif else { - x0= (int)(pt1->x / 100 * p->sa->winx); - y0= (int)(pt1->y / 100 * p->sa->winy); - x1= (int)(pt2->x / 100 * p->sa->winx); - y1= (int)(pt2->y / 100 * p->sa->winy); + x0= (int)(pt1->x / 100 * p->ar->winx); + y0= (int)(pt1->y / 100 * p->ar->winy); + x1= (int)(pt2->x / 100 * p->ar->winx); + y1= (int)(pt2->y / 100 * p->ar->winy); } /* check that point segment of the boundbox of the eraser stroke */ @@ -944,15 +944,15 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode) p->gpd->sbuffer_sflag |= GP_STROKE_ERASER; /* check if points will need to be made in view-aligned space */ - // XXX this should be the default? this is something that needs review - /*if (p->gpd->flag & GP_DATA_VIEWALIGN)*/ { + if (p->gpd->flag & GP_DATA_VIEWALIGN) { switch (p->sa->spacetype) { case SPACE_VIEW3D: { View3D *v3d= (View3D *)p->sa->spacedata.first; RegionView3D *rv3d= p->ar->regiondata; - // TODO: this should only happen for scene... otherwise apply correction for object center! + // TODO 1: when using objects, make the data stick to the object centers? + // TODO 2: what happens when cursor is behind view-camera plane? float *fp= give_cursor(p->scene, v3d); initgrabz(rv3d, fp[0], fp[1], fp[2]); @@ -1139,7 +1139,7 @@ static void gpencil_draw_apply (bContext *C, wmOperator *op, tGPsdata *p) if (G.f & G_DEBUG) printf("Error: Grease-Pencil Paint - Add Point Invalid \n"); - // XXX break! + return; } /* store used values */ diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index e025aca010c..df0e5ae6703 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -208,6 +208,7 @@ void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT); RNA_def_property_ui_text(prop, "Selected", "Layer is selected for editing in the DopeSheet."); + // XXX keep this option? prop= RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_DRAWDEBUG); RNA_def_property_ui_text(prop, "Show Points", "Draw the points which make up the strokes (for debugging purposes)."); @@ -229,6 +230,11 @@ void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); RNA_def_property_struct_type(prop, "GPencilLayer"); RNA_def_property_ui_text(prop, "Layers", "Similar to layers in Photoshop."); + + /* Flags */ + prop= RNA_def_property(srna, "view_space_draw", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN); + RNA_def_property_ui_text(prop, "Stick to View", "Newly drawn strokes get added in view space (i.e. sketches stick to data when view is manipulated)."); } /* --- */ -- cgit v1.2.3 From 7df39b5ea2bd8bfd0c5a2a08aa2c52d051aa5fd5 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 30 Aug 2009 13:32:08 +0000 Subject: Grease Pencil: Basic Support for Image Editor Again * Grease Pencil works again from Image Editor now. For now, the GPencil datablock is linked to the Image Editor space, but this can be changed if need be. * Made Grease Pencil hotkeys into a separate Grease Pencil keymap, which can get included automagically like for frames/ui/v2d/etc. by supplying ED_KEYMAP_GPENCIL as part of st->keymapflag * Temporarily restored the nasty hack to make View2D-aligned sketches in Image Editor to use OpenGL lines only. I still dunno why this doesn't work normally. (Probably related is that strokes are not visible when there's no image visible atm). --- source/blender/editors/gpencil/drawgpencil.c | 17 +++++++--- source/blender/editors/gpencil/gpencil_edit.c | 11 ++++++ source/blender/editors/gpencil/gpencil_ops.c | 7 ++-- source/blender/editors/gpencil/gpencil_paint.c | 15 +++++---- source/blender/editors/include/ED_gpencil.h | 3 +- source/blender/editors/include/ED_screen.h | 2 +- source/blender/editors/screen/area.c | 4 +++ source/blender/editors/space_api/spacetypes.c | 3 +- source/blender/editors/space_image/image_buttons.c | 7 ++++ source/blender/editors/space_image/image_draw.c | 39 ++++++++++++---------- source/blender/editors/space_image/image_intern.h | 1 + source/blender/editors/space_image/space_image.c | 16 ++++++--- source/blender/editors/space_view3d/space_view3d.c | 2 +- source/blender/editors/space_view3d/view3d_ops.c | 4 --- 14 files changed, 82 insertions(+), 49 deletions(-) diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index d6678b50d7b..81ee2378717 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -83,6 +83,7 @@ enum { GP_DRAWDATA_ONLY3D = (1<<1), /* only draw 3d-strokes */ GP_DRAWDATA_ONLYV2D = (1<<2), /* only draw 'canvas' strokes */ GP_DRAWDATA_ONLYI2D = (1<<3), /* only draw 'image' strokes */ + GP_DRAWDATA_IEDITHACK = (1<<4), /* special hack for drawing strokes in Image Editor (weird coordinates) */ }; /* thickness above which we should use special drawing */ @@ -254,14 +255,12 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes /* draw a given stroke in 2d */ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int offsx, int offsy, int winx, int winy) -{ - int spacetype= 0; // XXX make local gpencil state var? - +{ /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better * - 'smooth' opengl lines are also required if Image Editor 'image-based' stroke */ if ( (thickness < GP_DRAWTHICKNESS_SPECIAL) || - ((spacetype==SPACE_IMAGE) && (dflag & GP_DRAWDATA_ONLYV2D)) ) + ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) ) { bGPDspoint *pt; int i; @@ -519,6 +518,9 @@ static void gp_draw_data (bGPdata *gpd, int offsx, int offsy, int winx, int winy { bGPDlayer *gpl, *actlay=NULL; + /* reset line drawing style (in case previous user didn't reset) */ + setlinestyle(0); + /* turn on smooth lines (i.e. anti-aliasing) */ glEnable(GL_LINE_SMOOTH); @@ -669,7 +671,7 @@ void draw_gpencil_2dimage (bContext *C, ImBuf *ibuf) wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax); - dflag |= GP_DRAWDATA_ONLYV2D; + dflag |= GP_DRAWDATA_ONLYV2D|GP_DRAWDATA_IEDITHACK; } break; @@ -729,6 +731,11 @@ void draw_gpencil_2dview (bContext *C, short onlyv2d) gpd= gpencil_data_get_active(C); // XXX if (gpd == NULL) return; + /* special hack for Image Editor */ + // FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled + if (sa->spacetype == SPACE_IMAGE) + dflag |= GP_DRAWDATA_IEDITHACK; + /* draw it! */ if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D|GP_DRAWDATA_NOSTATUS); gp_draw_data(gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag); diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index b2228134750..74fbe250d37 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -125,6 +125,17 @@ bGPdata **gpencil_data_get_pointers (bContext *C, PointerRNA *ptr) } break; + case SPACE_IMAGE: /* Image/UV Editor */ + { + SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); + + /* 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); + return &sima->gpd; + } + break; + default: /* unsupported space */ return NULL; } diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 2d23a331211..3acbded0bf8 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -45,14 +45,11 @@ /* ****************************************** */ /* Generic Editing Keymap */ -void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap) +void ED_keymap_gpencil(wmWindowManager *wm) { + ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0); wmKeymapItem *kmi; - /* if no keymap provided, use default */ - if (keymap == NULL) - keymap= WM_keymap_listbase(wm, "Grease Pencil Generic", 0, 0); - /* Draw */ /* draw */ WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index b5d25ce651f..67bf2951bf8 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -828,6 +828,7 @@ static tGPsdata *gp_session_initpaint (bContext *C) } } break; +#endif case SPACE_IMAGE: { SpaceImage *sima= curarea->spacedata.first; @@ -836,18 +837,20 @@ static tGPsdata *gp_session_initpaint (bContext *C) p->sa= curarea; p->ar= ar; p->v2d= &ar->v2d; - p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser); + //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.f & G_DEBUG) printf("Error: In active view, Grease Pencil not shown \n"); - return; + return p; } +#endif } break; -#endif + /* unsupported views */ default: { @@ -998,14 +1001,12 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode) p->im2d_settings.offsy= (int)((p->sa->winy-p->im2d_settings.sizey)/2 + sseq->yof); } break; +#endif case SPACE_IMAGE: { - /* check if any ibuf available */ - if (p->ibuf) - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; } break; -#endif } } } diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index ba60211ef3f..388da9a2acc 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -62,8 +62,7 @@ struct bGPdata *gpencil_data_get_active(struct bContext *C); /* ----------- Grease Pencil Operators ----------------- */ -void gpencil_common_keymap(struct wmWindowManager *wm, ListBase *keymap); - +void ED_keymap_gpencil(struct wmWindowManager *wm); void ED_operatortypes_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 22a3e737277..0153b3c9bdb 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -150,7 +150,7 @@ int ED_operator_posemode(struct bContext *C); #define ED_KEYMAP_MARKERS 4 #define ED_KEYMAP_ANIMATION 8 #define ED_KEYMAP_FRAMES 16 - +#define ED_KEYMAP_GPENCIL 32 #endif /* ED_SCREEN_H */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f714a291bd7..8c55cccd6b0 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -797,6 +797,10 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla ListBase *keymap= WM_keymap_listbase(wm, "Frames", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } + if(flag & ED_KEYMAP_GPENCIL) { + ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 0d702144959..edd5da44526 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -86,6 +86,7 @@ void ED_spacetypes_init(void) ED_operatortypes_screen(); ED_operatortypes_anim(); ED_operatortypes_animchannels(); + ED_operatortypes_gpencil(); ED_operatortypes_object(); ED_operatortypes_mesh(); ED_operatortypes_sculpt(); @@ -99,7 +100,6 @@ void ED_spacetypes_init(void) ED_operatortypes_fluid(); ED_operatortypes_metaball(); ED_operatortypes_boids(); - ED_operatortypes_gpencil(); ED_operatortypes_sound(); ui_view2d_operatortypes(); @@ -121,6 +121,7 @@ void ED_spacetypes_keymap(wmWindowManager *wm) ED_keymap_screen(wm); ED_keymap_anim(wm); ED_keymap_animchannels(wm); + ED_keymap_gpencil(wm); ED_keymap_object(wm); ED_keymap_mesh(wm); ED_keymap_uvedit(wm); diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index ac0a5c7f53a..2eb070e0e6d 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -67,6 +67,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "ED_gpencil.h" #include "ED_image.h" #include "ED_mesh.h" #include "ED_space_api.h" @@ -1438,6 +1439,12 @@ void image_buttons_register(ARegionType *art) strcpy(pt->label, "Curves"); pt->draw= image_panel_curves; BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); + strcpy(pt->idname, "IMAGE_PT_gpencil"); + strcpy(pt->label, "Grease Pencil"); + pt->draw= gpencil_panel_standard; + BLI_addtail(&art->paneltypes, pt); } static int image_properties(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 2f5fc805367..cf9bac1ebee 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -44,6 +44,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "BKE_context.h" #include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_image.h" @@ -53,6 +54,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "ED_gpencil.h" #include "ED_image.h" #include "ED_screen.h" @@ -525,22 +527,26 @@ static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *sce /* draw uv edit */ /* draw grease pencil */ - -static void draw_image_grease_pencil(SpaceImage *sima, ImBuf *ibuf) +void draw_image_grease_pencil(bContext *C, short onlyv2d) { - /* XXX bring back */ - /* draw grease-pencil ('image' strokes) */ - if (sima->flag & SI_DISPGP) - ; // XXX draw_gpencil_2dimage(sa, ibuf); - -#if 0 - mywinset(sa->win); /* restore scissor after gla call... */ - wmOrtho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375); -#endif - - /* draw grease-pencil (screen strokes) */ - if (sima->flag & SI_DISPGP) - ; // XXX draw_gpencil_2dview(sa, NULL); + /* draw in View2D space? */ + if (onlyv2d) { + /* assume that UI_view2d_ortho(C) has been called... */ + SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); + ImBuf *ibuf= ED_space_image_buffer(sima); + + /* draw grease-pencil ('image' strokes) */ + //if (sima->flag & SI_DISPGP) + draw_gpencil_2dimage(C, ibuf); + } + else { + /* assume that UI_view2d_restore(C) has been called... */ + SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); + + /* draw grease-pencil ('screen' strokes) */ + //if (sima->flag & SI_DISPGP) + draw_gpencil_2dview(C, 0); + } } /* XXX becomes WM paint cursor */ @@ -689,9 +695,6 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) else draw_image_buffer(sima, ar, scene, ima, ibuf, 0.0f, 0.0f, zoomx, zoomy); - /* grease pencil */ - draw_image_grease_pencil(sima, ibuf); - /* paint helpers */ draw_image_paint_helpers(sima, ar, scene, zoomx, zoomy); diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index aa97e339c68..a33475c1213 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -53,6 +53,7 @@ void IMAGE_OT_toolbox(struct wmOperatorType *ot); /* image_draw.c */ void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); void draw_image_info(struct ARegion *ar, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf); +void draw_image_grease_pencil(struct bContext *C, short onlyv2d); /* image_ops.c */ int space_image_main_area_poll(struct bContext *C); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 1506df89c45..bb647e68917 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -54,6 +54,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "ED_gpencil.h" #include "ED_image.h" #include "ED_mesh.h" #include "ED_space_api.h" @@ -430,16 +431,22 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) /* we set view2d from own zoom and offset each time */ image_main_area_set_view2d(sima, ar, scene); - + /* we draw image in pixelspace */ draw_image_main(sima, ar, scene); /* and uvs in 0.0-1.0 space */ UI_view2d_view_ortho(C, v2d); - draw_uvedit_main(sima, ar, scene, obedit); - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST); + draw_uvedit_main(sima, ar, scene, obedit); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST); + + /* Grease Pencil too (in addition to UV's) */ + draw_image_grease_pencil((bContext *)C, 1); UI_view2d_view_restore(C); + /* draw Grease Pencil - screen space only */ + draw_image_grease_pencil((bContext *)C, 0); + /* scrollers? */ /*scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); UI_view2d_scrollers_draw(C, v2d, scrollers); @@ -558,11 +565,10 @@ void ED_spacetype_image(void) /* regions: main window */ art= MEM_callocN(sizeof(ARegionType), "spacetype image region"); art->regionid = RGN_TYPE_WINDOW; - art->keymapflag= ED_KEYMAP_FRAMES; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL; art->init= image_main_area_init; art->draw= image_main_area_draw; art->listener= image_main_area_listener; - art->keymapflag= 0; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 3dd65a6f796..97c5549e1ea 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -871,7 +871,7 @@ void ED_spacetype_view3d(void) /* regions: main window */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_WINDOW; - art->keymapflag= ED_KEYMAP_FRAMES; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL; art->draw= view3d_main_area_draw; art->init= view3d_main_area_init; art->free= view3d_main_area_free; diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index f4e1e008099..7da2e591b10 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -52,7 +52,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_gpencil.h" #include "ED_screen.h" #include "ED_transform.h" @@ -133,9 +132,6 @@ void view3d_keymap(wmWindowManager *wm) km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0); RNA_boolean_set(km->ptr, "snap", 1); - /* grease pencil */ - gpencil_common_keymap(wm, keymap); - WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/ WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); -- cgit v1.2.3 From 257ad93e6deb3e69198bd7c52fa9b44e4093746e Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 30 Aug 2009 15:00:42 +0000 Subject: Removing old datatoc C source code; use the python version now! --- release/datafiles/datatoc.c | 102 -------------------------------------------- 1 file changed, 102 deletions(-) delete mode 100644 release/datafiles/datatoc.c diff --git a/release/datafiles/datatoc.c b/release/datafiles/datatoc.c deleted file mode 100644 index 46b935c7fd6..00000000000 --- a/release/datafiles/datatoc.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include -#include - -int main(int argc, char**argv) { - FILE *fpin, *fpout; - char cname[256]; - char sizest[256]; - size_t size; - int i; - - if (argc<1) { - printf ("Usage: datatoc \n"); - exit(1); - } - - fpin= fopen(argv[1], "rb"); - if (!fpin) { - printf ("Unable to open input <%s>\n", argv[1]); - exit(1); - } - - fseek (fpin, 0L, SEEK_END); - size= ftell(fpin); - fseek (fpin, 0L, SEEK_SET); - - if (argv[1][0]=='.') argv[1]++; - - sprintf(cname, "%s.c", argv[1]); - printf ("Making C file <%s>\n", cname); - - for (i=0; i < (int)strlen(argv[1]); i++) - if (argv[1][i]=='.') argv[1][i]='_'; - - sprintf(sizest, "%d", (int)size); - printf ("Input filesize is %ld, Output size should be %ld\n", size, ((int)size)*4 + strlen("/* DataToC output of file <> */\n\n") + strlen("char datatoc_[]= {\"") + strlen ("\"};\n") + (strlen(argv[1])*3) + strlen(sizest) + strlen("int datatoc__size= ;\n") +(((int)(size/256)+1)*5)); - - fpout= fopen(cname, "w"); - if (!fpout) { - printf ("Unable to open output <%s>\n", cname); - exit(1); - } - - fprintf (fpout, "/* DataToC output of file <%s> */\n\n",argv[1]); - fprintf (fpout, "int datatoc_%s_size= %s;\n", argv[1], sizest); - /* - fprintf (fpout, "char datatoc_%s[]= {\"", argv[1]); - - while (size--) { - if(size%256==0) - fprintf(fpout, "\" \\\n\""); - - fprintf (fpout, "\\x%02x", getc(fpin)); - } - - fprintf (fpout, "\"};\n"); - */ - - fprintf (fpout, "char datatoc_%s[]= {\n", argv[1]); - while (size--) { - if(size%32==31) - fprintf(fpout, "\n"); - - /* fprintf (fpout, "\\x%02x", getc(fpin)); */ - fprintf (fpout, "%3d,", getc(fpin)); - } - /* null terminate for the case it is a string */ - fprintf (fpout, "\n 0};\n\n"); - - fclose(fpin); - fclose(fpout); - return 0; -} -- cgit v1.2.3 From 557cf2906befb77eae15a96a385b0d92d563c31e Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 30 Aug 2009 16:18:05 +0000 Subject: 2.5 Sound: * Updated UserDef RNA so that only compiled in audio drivers are displayed. (Missing definitions in Makefiles, someone fix please!) * Fixed libsndfile and ffmpeg building with CMake with msvc. --- CMakeLists.txt | 4 ++-- source/blender/makesrna/intern/CMakeLists.txt | 12 ++++++++++++ source/blender/makesrna/intern/SConscript | 9 +++++++++ source/blender/makesrna/intern/rna_userdef.c | 6 ++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a92099698c6..1921ef65017 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,7 @@ IF(WIN32) IF(WITH_SNDFILE) SET(SNDFILE ${LIBDIR}/sndfile) SET(SNDFILE_INC ${SNDFILE}/include) - SET(SNDFILE_LIB sndfile-1) + SET(SNDFILE_LIB libsndfile-1) SET(SNDFILE_LIBPATH ${SNDFILE}/lib) ENDIF(WITH_SNDFILE) @@ -329,7 +329,7 @@ IF(WIN32) SET(QUICKTIME_LIBPATH ${QUICKTIME}/Libraries) SET(FFMPEG ${LIBDIR}/ffmpeg) - SET(FFMPEG_INC ${FFMPEG}/include) + SET(FFMPEG_INC ${FFMPEG}/include ${FFMPEG}/include/msvc) SET(FFMPEG_LIB avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0) SET(FFMPEG_LIBPATH ${FFMPEG}/lib) diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 152f4031b91..a1f42fbccb3 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -75,6 +75,18 @@ IF(WITH_FFTW3) ADD_DEFINITIONS(-DFFTW3=1) ENDIF(WITH_FFTW3) +IF(WITH_SDL) + ADD_DEFINITIONS(-DWITH_SDL) +ENDIF(WITH_SDL) + +IF(WITH_OPENAL) + ADD_DEFINITIONS(-DWITH_OPENAL) +ENDIF(WITH_OPENAL) + +IF(WITH_JACK) + ADD_DEFINITIONS(-DWITH_JACK) +ENDIF(WITH_JACK) + # Build makesrna executable ADD_EXECUTABLE(makesrna ${SRC} ${INC_FILES}) TARGET_LINK_LIBRARIES(makesrna bf_dna) diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 1a3687af51e..a24c25b8b95 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -62,6 +62,15 @@ if env['WITH_BF_GAMEENGINE']: if env['WITH_BF_FFTW3']: defs.append('FFTW3=1') +if env['WITH_BF_SDL']: + defs.append('WITH_SDL') + +if env['WITH_BF_OPENAL']: + defs.append('WITH_OPENAL') + +if env['WITH_BF_JACK']: + defs.append('WITH_JACK') + makesrna_tool.Append(CPPDEFINES=defs) makesrna_tool.Append (CPPPATH = Split(incs)) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ba980d4caf4..a0716cc7dc7 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2021,9 +2021,15 @@ static void rna_def_userdef_system(BlenderRNA *brna) static EnumPropertyItem audio_device_items[] = { {0, "AUDIO_DEVICE_NULL", 0, "No Audio", "Null device - there will be no audio output."}, +#ifdef WITH_SDL {1, "AUDIO_DEVICE_SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage."}, +#endif +#ifdef WITH_OPENAL {2, "AUDIO_DEVICE_OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage."}, +#endif +#ifdef WITH_JACK {3, "AUDIO_DEVICE_JACK", 0, "Jack", "Jack device - open source pro audio, recommended for pro audio users."}, +#endif {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem audio_rate_items[] = { -- cgit v1.2.3 From fee715f8a99c38df08942f39769e7bc520d848da Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sun, 30 Aug 2009 17:34:04 +0000 Subject: Make file directly executable. --- release/datafiles/datatoc.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 release/datafiles/datatoc.py diff --git a/release/datafiles/datatoc.py b/release/datafiles/datatoc.py old mode 100644 new mode 100755 -- cgit v1.2.3 From fa68f7ff76cea0fa8b818d332da3ec2213623b35 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 30 Aug 2009 19:02:48 +0000 Subject: made python 2.x and 3.x compatible. --- release/datafiles/datatoc.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/release/datafiles/datatoc.py b/release/datafiles/datatoc.py index 805d7205651..ea72870f2a0 100755 --- a/release/datafiles/datatoc.py +++ b/release/datafiles/datatoc.py @@ -1,5 +1,6 @@ -#!/usr/bin/python3 -# +#!/usr/bin/python +# -*- coding: utf-8 -*- + # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or @@ -23,10 +24,10 @@ # # ***** END GPL LICENCE BLOCK ***** -import sys +import sys, os if len(sys.argv) < 2: - print("Usage: datatoc ") + sys.stdout.write("Usage: datatoc \n") sys.exit(1) filename = sys.argv[1] @@ -34,37 +35,38 @@ filename = sys.argv[1] try: fpin = open(filename, "rb"); except: - print("Unable to open input <{0}>".format(sys.argv[1])) + sys.stdout.write("Unable to open input %s\n" % sys.argv[1]) sys.exit(1) -size = fpin.seek(0, 2) +fpin.seek(0, os.SEEK_END) +size = fpin.tell() fpin.seek(0) if filename[0] == ".": filename = filename[1:] cname = filename + ".c" -print("Making C file <{0}>".format(cname)) +sys.stdout.write("Making C file <%s>\n" % cname) filename = filename.replace(".", "_") - +sys.stdout.write(str(size)) try: fpout = open(cname, "w") except: - print("Unable to open output <{0}>".format(cname)) + sys.stdout.write("Unable to open output %s\n" % cname) sys.exit(1) -fpout.write("/* DataToC output of file <{0}> */\n\n".format(filename)) -fpout.write("int datatoc_{0}_size= {1};\n".format(filename, size)) +fpout.write("/* DataToC output of file <%s> */\n\n" % filename) +fpout.write("int datatoc_%s_size= %d;\n" % (filename, size)) -fpout.write("char datatoc_{0}[]= {{\n".format(filename)) +fpout.write("char datatoc_%s[]= {\n" % filename) while size > 0: size -= 1 if size % 32 == 31: fpout.write("\n") - fpout.write("{0:3d},".format(ord(fpin.read(1)))) + fpout.write("%.2d," % ord(fpin.read(1))) fpout.write("\n 0};\n\n") -- cgit v1.2.3 From 9abfb508de3c62e72473871b80878a280cbb282a Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 30 Aug 2009 19:26:18 +0000 Subject: 2.5 Mist/Camera: Changing Mist values didn't update the mist camera drawing in 3D View, when enabled. Bug reported by Julian|H. Thanks! --- source/blender/makesrna/intern/rna_world.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 525a4446932..0ed5016ccd2 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -324,12 +324,14 @@ static void rna_def_world_mist(BlenderRNA *brna) RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 10000, 10, 2); RNA_def_property_ui_text(prop, "Start", "Starting distance of the mist, measured from the camera"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); prop= RNA_def_property(srna, "depth", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "mistdist"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 10000, 10, 2); RNA_def_property_ui_text(prop, "Depth", "The distance over which the mist effect fades in"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); prop= RNA_def_property(srna, "height", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "misthi"); -- cgit v1.2.3 From ca96a75af49910340540960e7dbc797be9b01caf Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 30 Aug 2009 19:38:22 +0000 Subject: == Sequencer == Fixed hddaudio for sample formats other than 16 bit (8 bit e.g.) --- source/blender/src/hddaudio.c | 66 ++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/source/blender/src/hddaudio.c b/source/blender/src/hddaudio.c index 2aa434e4ac7..be5e07929bf 100644 --- a/source/blender/src/hddaudio.c +++ b/source/blender/src/hddaudio.c @@ -68,14 +68,15 @@ struct hdaudio { int frame_alloc_duration; int decode_pos; int frame_size; - short * decode_cache; - short * decode_cache_zero; + unsigned char * decode_cache; + unsigned char * decode_cache_zero; short * resample_cache; int decode_cache_size; int target_channels; int target_rate; int resample_samples_written; int resample_samples_in; + int decode_sample_format_size; ReSampleContext *resampler; #else @@ -178,9 +179,13 @@ struct hdaudio * sound_open_hdaudio(char * filename) (long long) rval->sample_rate * rval->channels * rval->frame_alloc_duration / AV_TIME_BASE * 2; + rval->decode_sample_format_size + = av_get_bits_per_sample_format(rval->pCodecCtx->sample_fmt) + / 8; - rval->decode_cache = (short*) MEM_mallocN( - rval->decode_cache_size * sizeof(short) + rval->decode_cache = (unsigned char*) MEM_mallocN( + rval->decode_cache_size + * rval->decode_sample_format_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, "hdaudio decode cache"); rval->decode_cache_zero = rval->decode_cache; @@ -191,6 +196,7 @@ struct hdaudio * sound_open_hdaudio(char * filename) rval->resample_cache = 0; rval->resample_samples_written = 0; rval->resample_samples_in = 0; + return rval; #else return 0; @@ -260,7 +266,8 @@ static void sound_hdaudio_run_resampler_continue( = audio_resample( hdaudio->resampler, hdaudio->resample_cache + reuse_tgt, - hdaudio->decode_cache_zero + reuse_src, + hdaudio->decode_cache_zero + + reuse_src * hdaudio->decode_sample_format_size, next_samples_in) + reuse_tgt / target_channels; @@ -285,7 +292,7 @@ static void sound_hdaudio_init_resampler( hdaudio->resampler = av_audio_resample_init( target_channels, hdaudio->channels, target_rate, hdaudio->sample_rate, - SAMPLE_FMT_S16, SAMPLE_FMT_S16, + SAMPLE_FMT_S16, hdaudio->pCodecCtx->sample_fmt, 16, 10, 0, 0.8); hdaudio->target_rate = target_rate; hdaudio->target_channels = target_channels; @@ -327,7 +334,8 @@ static void sound_hdaudio_extract_small_block( * hdaudio->frame_duration / AV_TIME_BASE; rate_conversion = (target_rate != hdaudio->sample_rate) - || (target_channels != hdaudio->channels); + || (target_channels != hdaudio->channels) + || (hdaudio->pCodecCtx->sample_fmt != SAMPLE_FMT_S16); sample_ofs = target_channels * (sample_position % frame_size); frame_position = sample_position / frame_size; @@ -346,15 +354,20 @@ static void sound_hdaudio_extract_small_block( hdaudio->frame_position = frame_position; memmove(hdaudio->decode_cache, - hdaudio->decode_cache + bl_size, - (decode_pos - bl_size) * sizeof(short)); + hdaudio->decode_cache + bl_size + * hdaudio->decode_sample_format_size, + (decode_pos - bl_size) + * hdaudio->decode_sample_format_size); decode_pos -= bl_size; if (decode_pos < hdaudio->decode_cache_size) { - memset(hdaudio->decode_cache + decode_pos, 0, + memset(hdaudio->decode_cache + + decode_pos + * hdaudio->decode_sample_format_size, + 0, (hdaudio->decode_cache_size - decode_pos) - * sizeof(short)); + * hdaudio->decode_sample_format_size); while(av_read_frame( hdaudio->pFormatCtx, &packet) >= 0) { @@ -377,7 +390,8 @@ static void sound_hdaudio_extract_small_block( len = avcodec_decode_audio2( hdaudio->pCodecCtx, hdaudio->decode_cache - + decode_pos, + + decode_pos + * hdaudio->decode_sample_format_size, &data_size, audio_pkt_data, audio_pkt_size); @@ -393,16 +407,17 @@ static void sound_hdaudio_extract_small_block( continue; } - decode_pos += data_size / sizeof(short); + decode_pos += data_size + / hdaudio->decode_sample_format_size; if (decode_pos + data_size - / sizeof(short) + / hdaudio->decode_sample_format_size > hdaudio->decode_cache_size) { break; } } av_free_packet(&packet); - if (decode_pos + data_size / sizeof(short) + if (decode_pos + data_size / hdaudio->decode_sample_format_size > hdaudio->decode_cache_size) { break; } @@ -455,7 +470,8 @@ static void sound_hdaudio_extract_small_block( avcodec_flush_buffers(hdaudio->pCodecCtx); memset(hdaudio->decode_cache, 0, - hdaudio->decode_cache_size * sizeof(short)); + hdaudio->decode_cache_size + * hdaudio->decode_sample_format_size); hdaudio->decode_cache_zero = hdaudio->decode_cache; @@ -512,7 +528,9 @@ static void sound_hdaudio_extract_small_block( } hdaudio->decode_cache_zero - = hdaudio->decode_cache + diff; + = hdaudio->decode_cache + + diff + * hdaudio->decode_sample_format_size; decode_cache_zero_init = 1; } @@ -521,7 +539,8 @@ static void sound_hdaudio_extract_small_block( len = avcodec_decode_audio2( hdaudio->pCodecCtx, hdaudio->decode_cache - + decode_pos, + + decode_pos + * hdaudio->decode_sample_format_size, &data_size, audio_pkt_data, audio_pkt_size); @@ -537,9 +556,10 @@ static void sound_hdaudio_extract_small_block( continue; } - decode_pos += data_size / sizeof(short); + decode_pos += data_size + / hdaudio->decode_sample_format_size; if (decode_pos + data_size - / sizeof(short) + / hdaudio->decode_sample_format_size > hdaudio->decode_cache_size) { break; } @@ -547,7 +567,8 @@ static void sound_hdaudio_extract_small_block( av_free_packet(&packet); - if (decode_pos + data_size / sizeof(short) + if (decode_pos + data_size + / hdaudio->decode_sample_format_size > hdaudio->decode_cache_size) { break; } @@ -561,7 +582,8 @@ static void sound_hdaudio_extract_small_block( memcpy(target_buffer, (rate_conversion ? hdaudio->resample_cache - : hdaudio->decode_cache_zero) + sample_ofs, + : (short*) + hdaudio->decode_cache_zero) + sample_ofs, nb_samples * target_channels * sizeof(short)); } -- cgit v1.2.3 From 6422d335cab87242aa2bf34290817ca96d11e464 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 30 Aug 2009 20:03:47 +0000 Subject: bugfix of the bugfix --- release/datafiles/datatoc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release/datafiles/datatoc.py b/release/datafiles/datatoc.py index ea72870f2a0..362d4ddc126 100755 --- a/release/datafiles/datatoc.py +++ b/release/datafiles/datatoc.py @@ -50,6 +50,7 @@ sys.stdout.write("Making C file <%s>\n" % cname) filename = filename.replace(".", "_") sys.stdout.write(str(size)) +sys.stdout.write("\n") try: fpout = open(cname, "w") except: @@ -66,7 +67,7 @@ while size > 0: if size % 32 == 31: fpout.write("\n") - fpout.write("%.2d," % ord(fpin.read(1))) + fpout.write("%3d," % ord(fpin.read(1))) fpout.write("\n 0};\n\n") -- cgit v1.2.3 From a7689e9b60ef6dbe720a13abddb47f5137fc222d Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 30 Aug 2009 21:00:26 +0000 Subject: 2.5 Physic Buttons: * Some Panels missed the "md" context declaration for the new cloth_panel_enabled(md) check. * Code Cleanup. --- release/ui/buttons_physics_cloth.py | 23 +++-- release/ui/buttons_physics_fluid.py | 20 +---- release/ui/buttons_physics_softbody.py | 151 ++++++++++++++++----------------- 3 files changed, 92 insertions(+), 102 deletions(-) diff --git a/release/ui/buttons_physics_cloth.py b/release/ui/buttons_physics_cloth.py index 9399d557a51..a1978f44c18 100644 --- a/release/ui/buttons_physics_cloth.py +++ b/release/ui/buttons_physics_cloth.py @@ -43,11 +43,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel): if md: cloth = md.settings + + layout.active = cloth_panel_enabled(md) split = layout.split() - split.active = cloth_panel_enabled(md) - col = split.column() col.itemL(text="Quality:") col.itemR(cloth, "quality", text="Steps",slider=True) @@ -89,7 +89,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.cloth != None) + return (context.cloth) def draw(self, context): md = context.cloth @@ -100,7 +100,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.cloth != None) + return (context.cloth) def draw_header(self, context): layout = self.layout @@ -111,11 +111,14 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): def draw(self, context): layout = self.layout + cloth = context.cloth.collision_settings - split = layout.split() + md = context.cloth layout.active = cloth.enable_collision and cloth_panel_enabled(md) + split = layout.split() + col = split.column() col.itemR(cloth, "collision_quality", slider=True, text="Quality") col.itemR(cloth, "min_distance", slider=True, text="Distance") @@ -123,10 +126,10 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): col = split.column() col.itemR(cloth, "enable_self_collision", text="Self Collision") - col = col.column() - col.active = cloth.enable_self_collision - col.itemR(cloth, "self_collision_quality", slider=True, text="Quality") - col.itemR(cloth, "self_min_distance", slider=True, text="Distance") + sub = col.column() + sub.active = cloth.enable_self_collision + sub.itemR(cloth, "self_collision_quality", slider=True, text="Quality") + sub.itemR(cloth, "self_min_distance", slider=True, text="Distance") class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): __label__ = "Cloth Stiffness Scaling" @@ -144,6 +147,8 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): def draw(self, context): layout = self.layout + + md = context.cloth ob = context.object cloth = context.cloth.settings diff --git a/release/ui/buttons_physics_fluid.py b/release/ui/buttons_physics_fluid.py index 5af63bdc3ba..fe15e22f0b9 100644 --- a/release/ui/buttons_physics_fluid.py +++ b/release/ui/buttons_physics_fluid.py @@ -175,11 +175,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel): def poll(self, context): md = context.fluid if md: - settings = md.settings - if settings: - return (settings.type == 'DOMAIN') - - return False + return (md.settings.type == 'DOMAIN') def draw(self, context): layout = self.layout @@ -218,11 +214,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel): def poll(self, context): md = context.fluid if md: - settings = md.settings - if settings: - return (settings.type == 'DOMAIN') - - return False + return (md.settings.type == 'DOMAIN') def draw(self, context): layout = self.layout @@ -251,12 +243,8 @@ class PHYSICS_PT_domain_particles(PhysicButtonsPanel): def poll(self, context): md = context.fluid if md: - settings = md.settings - if settings: - return (settings.type == 'DOMAIN') - - return False - + return (md.settings.type == 'DOMAIN') + def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_physics_softbody.py b/release/ui/buttons_physics_softbody.py index 3d3c3c23faf..73eb15d2212 100644 --- a/release/ui/buttons_physics_softbody.py +++ b/release/ui/buttons_physics_softbody.py @@ -71,6 +71,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel): class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): __label__ = "Soft Body Goal" + __default_closed__ = True def poll(self, context): return (context.soft_body) @@ -87,39 +88,39 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): layout = self.layout md = context.soft_body + softbody = md.settings ob = context.object + + layout.active = softbody.use_goal and softbody_panel_enabled(md) split = layout.split() - - if md: - softbody = md.settings - layout.active = softbody.use_goal and softbody_panel_enabled(md) - # Goal - split = layout.split() + # Goal + split = layout.split() - col = split.column() - col.itemL(text="Goal Strengths:") - col.itemR(softbody, "goal_default", text="Default") - sub = col.column(align=True) - sub.itemR(softbody, "goal_min", text="Minimum") - sub.itemR(softbody, "goal_max", text="Maximum") + col = split.column() + col.itemL(text="Goal Strengths:") + col.itemR(softbody, "goal_default", text="Default") + sub = col.column(align=True) + sub.itemR(softbody, "goal_min", text="Minimum") + sub.itemR(softbody, "goal_max", text="Maximum") - col = split.column() - col.itemL(text="Goal Settings:") - col.itemR(softbody, "goal_spring", text="Stiffness") - col.itemR(softbody, "goal_friction", text="Damping") + col = split.column() + col.itemL(text="Goal Settings:") + col.itemR(softbody, "goal_spring", text="Stiffness") + col.itemR(softbody, "goal_friction", text="Damping") - layout.item_pointerR(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group") + layout.item_pointerR(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group") class PHYSICS_PT_softbody_edge(PhysicButtonsPanel): __label__ = "Soft Body Edges" + __default_closed__ = True def poll(self, context): return (context.soft_body) def draw_header(self, context): - layout = self.layout + #layout = self.layout softbody = context.soft_body.settings @@ -130,41 +131,40 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel): layout = self.layout md = context.soft_body + softbody = md.settings ob = context.object + + layout.active = softbody.use_edges and softbody_panel_enabled(md) - if md: - softbody = md.settings - - layout.active = softbody.use_edges and softbody_panel_enabled(md) - - split = layout.split() - - col = split.column() - col.itemL(text="Springs:") - col.itemR(softbody, "pull") - col.itemR(softbody, "push") - col.itemR(softbody, "damp") - col.itemR(softbody, "plastic") - col.itemR(softbody, "bending") - col.itemR(softbody, "spring_length", text="Length") - - col = split.column() - col.itemR(softbody, "stiff_quads") - sub = col.column() - sub.active = softbody.stiff_quads - sub.itemR(softbody, "shear") + split = layout.split() - col.itemR(softbody, "new_aero", text="Aero") - sub = col.column() - sub.enabled = softbody.new_aero - sub.itemR(softbody, "aero", text="Factor") - - col.itemL(text="Collision:") - col.itemR(softbody, "edge_collision", text="Edge") - col.itemR(softbody, "face_collision", text="Face") + col = split.column() + col.itemL(text="Springs:") + col.itemR(softbody, "pull") + col.itemR(softbody, "push") + col.itemR(softbody, "damp") + col.itemR(softbody, "plastic") + col.itemR(softbody, "bending") + col.itemR(softbody, "spring_length", text="Length") + + col = split.column() + col.itemR(softbody, "stiff_quads") + sub = col.column() + sub.active = softbody.stiff_quads + sub.itemR(softbody, "shear") + + col.itemR(softbody, "new_aero", text="Aero") + sub = col.column() + sub.enabled = softbody.new_aero + sub.itemR(softbody, "aero", text="Factor") + + col.itemL(text="Collision:") + col.itemR(softbody, "edge_collision", text="Edge") + col.itemR(softbody, "face_collision", text="Face") class PHYSICS_PT_softbody_collision(PhysicButtonsPanel): __label__ = "Soft Body Collision" + __default_closed__ = True def poll(self, context): return (context.soft_body) @@ -181,24 +181,23 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel): layout = self.layout md = context.soft_body + softbody = md.settings ob = context.object - - if md: - softbody = md.settings - layout.active = softbody.self_collision and softbody_panel_enabled(md) + layout.active = softbody.self_collision and softbody_panel_enabled(md) - layout.itemL(text="Collision Type:") - layout.itemR(softbody, "collision_type", expand=True) + layout.itemL(text="Collision Type:") + layout.itemR(softbody, "collision_type", expand=True) - col = layout.column(align=True) - col.itemL(text="Ball:") - col.itemR(softbody, "ball_size", text="Size") - col.itemR(softbody, "ball_stiff", text="Stiffness") - col.itemR(softbody, "ball_damp", text="Dampening") + col = layout.column(align=True) + col.itemL(text="Ball:") + col.itemR(softbody, "ball_size", text="Size") + col.itemR(softbody, "ball_stiff", text="Stiffness") + col.itemR(softbody, "ball_damp", text="Dampening") class PHYSICS_PT_softbody_solver(PhysicButtonsPanel): __label__ = "Soft Body Solver" + __default_closed__ = True def poll(self, context): return (context.soft_body) @@ -207,30 +206,28 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel): layout = self.layout md = context.soft_body + softbody = md.settings ob = context.object - - if md: - softbody = md.settings - - layout.active = softbody_panel_enabled(md) - # Solver - split = layout.split() + layout.active = softbody_panel_enabled(md) + + # Solver + split = layout.split() - col = split.column(align=True) - col.itemL(text="Step Size:") - col.itemR(softbody, "minstep") - col.itemR(softbody, "maxstep") - col.itemR(softbody, "auto_step", text="Auto-Step") + col = split.column(align=True) + col.itemL(text="Step Size:") + col.itemR(softbody, "minstep") + col.itemR(softbody, "maxstep") + col.itemR(softbody, "auto_step", text="Auto-Step") - col = split.column() - col.itemR(softbody, "error_limit") - col.itemL(text="Helpers:") - col.itemR(softbody, "choke") - col.itemR(softbody, "fuzzy") + col = split.column() + col.itemR(softbody, "error_limit") + col.itemL(text="Helpers:") + col.itemR(softbody, "choke") + col.itemR(softbody, "fuzzy") - layout.itemL(text="Diagnostics:") - layout.itemR(softbody, "diagnose") + layout.itemL(text="Diagnostics:") + layout.itemR(softbody, "diagnose") bpy.types.register(PHYSICS_PT_softbody) bpy.types.register(PHYSICS_PT_softbody_cache) -- cgit v1.2.3 From 1a968f64dcb706b90a877a1196d0b70a3c57fcff Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 30 Aug 2009 21:57:10 +0000 Subject: Fix crash reported by DingTo with camera transform in camera view. --- source/blender/editors/transform/transform_conversions.c | 2 +- source/blender/editors/transform/transform_generics.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index aaede541b76..86d3af31c85 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5289,7 +5289,7 @@ void createTransData(bContext *C, TransInfo *t) if (t->ar->regiontype == RGN_TYPE_WINDOW) { View3D *v3d = t->view; - RegionView3D *rv3d = t->ar->regiondata; + RegionView3D *rv3d = CTX_wm_region_view3d(C); if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) { t->flag |= T_CAMERA; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index edcbd858e37..0f715f1d35a 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1323,7 +1323,7 @@ void calculateCenter(TransInfo *t) /* voor panning from cameraview */ if(t->flag & T_OBJECT) { - if(t->spacetype==SPACE_VIEW3D) + if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) { View3D *v3d = t->view; Scene *scene = t->scene; -- cgit v1.2.3 From 3fa51df744ea5c4585e4cb53a207a0f106ec2032 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 31 Aug 2009 01:58:11 +0000 Subject: Grease Pencil: Restored some editing operators (convert and delete active frame) * Convert operator - can currently be used to convert active Grease Pencil layer to curves. I had a look at making this part of a special "curve sketching" macro, though it seems that we cannot have modal operators coming first in a macro (and also cannot specify operator calling modes) * Delete Active Frame operator - does what its name say it does. It deletes the active frame for the active layer of Grease Pencil sketches. --- source/blender/blenkernel/intern/gpencil.c | 2 +- source/blender/editors/gpencil/gpencil_buttons.c | 20 +- source/blender/editors/gpencil/gpencil_edit.c | 304 +++++++++++++++++++++++ source/blender/editors/gpencil/gpencil_intern.h | 4 + source/blender/editors/gpencil/gpencil_ops.c | 4 + 5 files changed, 324 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index b02128c3c68..43c4137e73e 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -313,7 +313,7 @@ bGPdata *gpencil_data_duplicate (bGPdata *src) void gpencil_frame_delete_laststroke (bGPDlayer *gpl, bGPDframe *gpf) { bGPDstroke *gps= (gpf) ? gpf->strokes.last : NULL; - int cfra = 1; // XXX FIXME!!! + int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */ /* error checking */ if (ELEM(NULL, gpf, gps)) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 774f7b7162b..c3f779b59b8 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -203,6 +203,12 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) subcol= uiLayoutColumn(col, 1); uiItemR(subcol, NULL, 0, &ptr, "line_thickness", UI_ITEM_R_SLIDER); + /* debugging options */ + if (G.f & G_DEBUG) { + subcol= uiLayoutColumn(col, 1); + uiItemR(subcol, NULL, 0, &ptr, "show_points", 0); + } + /* right column ................... */ col= uiLayoutColumn(split, 0); @@ -211,15 +217,10 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) uiItemR(subcol, "Onion Skinning", 0, &ptr, "use_onion_skinning", 0); uiItemR(subcol, "GStep", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep) - /* debugging options */ - // XXX re-enable the debug-only checks later - //if (G.f & G_DEBUG) { - subcol= uiLayoutColumn(col, 1); - uiItemR(subcol, NULL, 0, &ptr, "show_points", 0); - //} - /* additional options... */ - // None at the moment... + subcol= uiLayoutColumn(col, 1); + uiItemO(subcol, "Delete Frame", 0, "GPENCIL_OT_active_frame_delete"); + uiItemO(subcol, "Convert...", 0, "GPENCIL_OT_convert"); } } @@ -237,7 +238,8 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi col= uiLayoutColumn(layout, 0); /* current Grease Pencil block */ // TODO: show some info about who owns this? - uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink"); + //uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink"); // XXX not working + uiItemR(col, NULL, 0, ctx_ptr, "grease_pencil", 0); // XXX this will have to do for now... /* add new layer button */ uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add"); diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 74fbe250d37..8cf1affa8c6 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -60,6 +60,7 @@ #include "BKE_gpencil.h" #include "BKE_image.h" #include "BKE_library.h" +#include "BKE_object.h" #include "BKE_report.h" #include "BKE_utildefines.h" @@ -70,6 +71,7 @@ #include "WM_types.h" #include "RNA_access.h" +#include "RNA_define.h" #include "UI_view2d.h" @@ -280,4 +282,306 @@ void GPENCIL_OT_layer_add (wmOperatorType *ot) ot->poll= gp_add_poll; } +/* ******************* Delete Active Frame ************************ */ + +static int gp_actframe_delete_poll (bContext *C) +{ + bGPdata *gpd= gpencil_data_get_active(C); + bGPDlayer *gpl= gpencil_layer_getactive(gpd); + + /* only if there's an active layer with an active frame */ + return (gpl && gpl->actframe); +} + +/* delete active frame - wrapper around API calls */ +static int gp_actframe_delete_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + bGPdata *gpd= gpencil_data_get_active(C); + bGPDlayer *gpl= gpencil_layer_getactive(gpd); + bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); + + /* if there's no existing Grease-Pencil data there, add some */ + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); + return OPERATOR_CANCELLED; + } + if ELEM(NULL, gpl, gpf) { + BKE_report(op->reports, RPT_ERROR, "No active frame to delete"); + return OPERATOR_CANCELLED; + } + + /* delete it... */ + gpencil_layer_delframe(gpl, gpf); + + /* notifiers */ + WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work! + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_active_frame_delete (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Active Frame"; + ot->idname= "GPENCIL_OT_active_frame_delete"; + ot->description= "Delete the active frame for the active Grease Pencil datablock."; + + /* callbacks */ + ot->exec= gp_actframe_delete_exec; + ot->poll= gp_actframe_delete_poll; +} + +/* ************************************************ */ +/* Grease Pencil to Data Operator */ + +/* defines for possible modes */ +enum { + GP_STROKECONVERT_PATH = 1, + GP_STROKECONVERT_CURVE, +}; + +/* RNA enum define */ +static EnumPropertyItem prop_gpencil_convertmodes[] = { + {GP_STROKECONVERT_PATH, "PATH", 0, "Path", ""}, + {GP_STROKECONVERT_CURVE, "CURVE", 0, "Bezier Curve", ""}, + {0, NULL, 0, NULL, NULL} +}; + +/* --- */ + +/* convert the coordinates from the given stroke point into 3d-coordinates + * - assumes that the active space is the 3D-View + */ +static void gp_strokepoint_convertcoords (bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3]) +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + ARegion *ar= CTX_wm_region(C); + + if (gps->flag & GP_STROKE_3DSPACE) { + /* directly use 3d-coordinates */ + VecCopyf(p3d, &pt->x); + } + else { + float *fp= give_cursor(scene, v3d); + float dvec[3]; + short mval[2]; + int mx, my; + + /* get screen coordinate */ + if (gps->flag & GP_STROKE_2DSPACE) { + View2D *v2d= &ar->v2d; + UI_view2d_view_to_region(v2d, pt->x, pt->y, &mx, &my); + } + else { + mx= (int)(pt->x / 100 * ar->winx); + my= (int)(pt->y / 100 * ar->winy); + } + mval[0]= (short)mx; + mval[1]= (short)my; + + /* convert screen coordinate to 3d coordinates + * - method taken from editview.c - mouse_cursor() + */ + project_short_noclip(ar, fp, mval); + window_to_3d(ar, dvec, mval[0]-mx, mval[1]-my); + VecSubf(p3d, fp, dvec); + } +} + +/* --- */ + +/* convert stroke to 3d path */ +static void gp_stroke_to_path (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu) +{ + bGPDspoint *pt; + Nurb *nu; + BPoint *bp; + int i; + + /* create new 'nurb' within the curve */ + nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)"); + + nu->pntsu= gps->totpoints; + nu->pntsv= 1; + nu->orderu= gps->totpoints; + nu->flagu= 2; /* endpoint */ + nu->resolu= 32; + + nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*gps->totpoints, "bpoints"); + + /* add points */ + for (i=0, pt=gps->points, bp=nu->bp; i < gps->totpoints; i++, pt++, bp++) { + float p3d[3]; + + /* get coordinates to add at */ + gp_strokepoint_convertcoords(C, gps, pt, p3d); + VecCopyf(bp->vec, p3d); + + /* set settings */ + bp->f1= SELECT; + bp->radius = bp->weight = pt->pressure * gpl->thickness; + } + + /* add nurb to curve */ + BLI_addtail(&cu->nurb, nu); +} + +/* convert stroke to 3d bezier */ +static void gp_stroke_to_bezier (bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu) +{ + bGPDspoint *pt; + Nurb *nu; + BezTriple *bezt; + int i; + + /* create new 'nurb' within the curve */ + nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)"); + + nu->pntsu= gps->totpoints; + nu->resolu= 12; + nu->resolv= 12; + nu->type= CU_BEZIER; + nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints*sizeof(BezTriple), "bezts"); + + /* add points */ + for (i=0, pt=gps->points, bezt=nu->bezt; i < gps->totpoints; i++, pt++, bezt++) { + float p3d[3]; + + /* get coordinates to add at */ + gp_strokepoint_convertcoords(C, gps, pt, p3d); + + /* TODO: maybe in future the handles shouldn't be in same place */ + VecCopyf(bezt->vec[0], p3d); + VecCopyf(bezt->vec[1], p3d); + VecCopyf(bezt->vec[2], p3d); + + /* 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; + } + + /* must calculate handles or else we crash */ + calchandlesNurb(nu); + + /* add nurb to curve */ + BLI_addtail(&cu->nurb, nu); +} + +/* convert a given grease-pencil layer to a 3d-curve representation (using current view if appropriate) */ +static void gp_layer_to_curve (bContext *C, bGPdata *gpd, bGPDlayer *gpl, short mode) +{ + Scene *scene= CTX_data_scene(C); + bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); + bGPDstroke *gps; + Base *base= BASACT; + Object *ob; + Curve *cu; + + /* error checking */ + if (ELEM3(NULL, gpd, gpl, gpf)) + return; + + /* only convert if there are any strokes on this layer's frame to convert */ + if (gpf->strokes.first == NULL) + return; + + /* init the curve object (remove rotation and get curve data from it) + * - must clear transforms set on object, as those skew our results + */ + ob= add_object(scene, OB_CURVE); + ob->loc[0]= ob->loc[1]= ob->loc[2]= 0; + ob->rot[0]= ob->rot[1]= ob->rot[2]= 0; + cu= ob->data; + cu->flag |= CU_3D; + + /* rename object and curve to layer name */ + rename_id((ID *)ob, gpl->info); + rename_id((ID *)cu, gpl->info); + + /* add points to curve */ + for (gps= gpf->strokes.first; gps; gps= gps->next) { + switch (mode) { + case GP_STROKECONVERT_PATH: + gp_stroke_to_path(C, gpl, gps, cu); + break; + case GP_STROKECONVERT_CURVE: + gp_stroke_to_bezier(C, gpl, gps, cu); + break; + } + } + + /* restore old active object */ + BASACT= base; +} + +/* --- */ + +static int gp_convert_poll (bContext *C) +{ + bGPdata *gpd= gpencil_data_get_active(C); + ScrArea *sa= CTX_wm_area(C); + + /* only if there's valid data, and the current view is 3D View */ + return ((sa->spacetype == SPACE_VIEW3D) && gpencil_layer_getactive(gpd)); +} + +static int gp_convert_layer_exec (bContext *C, wmOperator *op) +{ + bGPdata *gpd= gpencil_data_get_active(C); + bGPDlayer *gpl= gpencil_layer_getactive(gpd); + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + float *fp= give_cursor(scene, v3d); + int mode= RNA_enum_get(op->ptr, "type"); + + /* check if there's data to work with */ + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on."); + return OPERATOR_CANCELLED; + } + + /* initialise 3d-cursor correction globals */ + initgrabz(CTX_wm_region_view3d(C), fp[0], fp[1], fp[2]); + + /* handle conversion modes */ + switch (mode) { + case GP_STROKECONVERT_PATH: + case GP_STROKECONVERT_CURVE: + gp_layer_to_curve(C, gpd, gpl, mode); + break; + + default: /* unsupoorted */ + BKE_report(op->reports, RPT_ERROR, "Unknown conversion option."); + return OPERATOR_CANCELLED; + } + + /* notifiers */ + WM_event_add_notifier(C, NC_OBJECT|NA_ADDED, NULL); + + /* done */ + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_convert (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Convert Grease Pencil"; + ot->idname= "GPENCIL_OT_convert"; + ot->description= "Convert the active Grease Pencil layer to a new Object."; + + /* callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= gp_convert_layer_exec; + ot->poll= gp_convert_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", ""); +} + /* ************************************************ */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 2c7bf9156c3..57e8c882d20 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -54,6 +54,10 @@ void GPENCIL_OT_data_unlink(struct wmOperatorType *ot); void GPENCIL_OT_layer_add(struct wmOperatorType *ot); +void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot); + +void GPENCIL_OT_convert(struct wmOperatorType *ot); + /******************************************************* */ /* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */ diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 3acbded0bf8..d33ad16dfb1 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -76,6 +76,10 @@ void ED_operatortypes_gpencil (void) WM_operatortype_append(GPENCIL_OT_layer_add); + WM_operatortype_append(GPENCIL_OT_active_frame_delete); + + WM_operatortype_append(GPENCIL_OT_convert); + /* Editing (Time) --------------- */ } -- cgit v1.2.3 From 6b3351c327771c6572ddfb3677db087b15bf06d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Aug 2009 03:36:02 +0000 Subject: bugfix [#19254] KX_PolyProxy returns improper VertexIndex with triangles, using .getVertexIndex() and .v1, .v2, etc. Surprising this wasn't noticed before. Any mix of quads/tris caused the face verts of either quads/tries (whichever comes last). Tested by exporting the KX_MeshProxy and re-importing as an OBJ. This fix assumes there are only 2 m_darray's per face array which is currently true, but wont be if edge support is added back. --- source/gameengine/Ketsji/KX_PolyProxy.cpp | 10 +++++----- source/gameengine/Rasterizer/RAS_MaterialBucket.h | 3 +++ source/gameengine/Rasterizer/RAS_Polygon.cpp | 15 +++++++++++++++ source/gameengine/Rasterizer/RAS_Polygon.h | 1 + 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index b56b5500c39..66457f46deb 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -140,19 +140,19 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr) } if (!strcmp(attr_str, "v1")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(0)); + return PyInt_FromLong(m_polygon->GetVertexOffsetAbs(m_mesh, 0)); } if (!strcmp(attr_str, "v2")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(1)); + return PyInt_FromLong(m_polygon->GetVertexOffsetAbs(m_mesh, 1)); } if (!strcmp(attr_str, "v3")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(2)); + return PyInt_FromLong(m_polygon->GetVertexOffsetAbs(m_mesh, 2)); } if (!strcmp(attr_str, "v4")) { - return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0)); + return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffsetAbs(m_mesh, 3):0)); } if (!strcmp(attr_str, "visible")) { @@ -255,7 +255,7 @@ KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex, } if (index < m_polygon->VertexCount()) { - return PyInt_FromLong(m_polygon->GetVertexOffset(index)); + return PyInt_FromLong(m_polygon->GetVertexOffsetAbs(m_mesh, index)); } return PyInt_FromLong(0); } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 8db75b8b735..49837652483 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -79,8 +79,11 @@ class RAS_DisplayArray public: vector m_vertex; vector m_index; + /* LINE currently isnt used */ enum { LINE = 2, TRIANGLE = 3, QUAD = 4 } m_type; //RAS_MeshSlot *m_origSlot; + + /* Number of RAS_MeshSlot using this array */ int m_users; enum { BUCKET_MAX_INDEX = 65535 }; diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp index eacc1285166..87c5118c5fb 100644 --- a/source/gameengine/Rasterizer/RAS_Polygon.cpp +++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp @@ -31,6 +31,7 @@ #endif #include "RAS_Polygon.h" +#include "RAS_MeshObject.h" /* only for GetVertexOffsetAbs */ RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket, RAS_DisplayArray *darray, int numvert) { @@ -63,6 +64,20 @@ int RAS_Polygon::GetVertexOffset(int i) return m_offset[i]; } +int RAS_Polygon::GetVertexOffsetAbs(RAS_MeshObject *mesh, int i) +{ + /* hack that only works because there can only ever be 2 different + * GetDisplayArray's per mesh. if this uses a different display array to the first + * then its incices are offset. + * if support for edges is added back this would need to be changed. */ + RAS_DisplayArray* darray= mesh->GetPolygon(0)->GetDisplayArray(); + + if(m_darray != darray) + return m_offset[i] + darray->m_vertex.size(); + + return m_offset[i]; +} + /* int RAS_Polygon::GetEdgeCode() { diff --git a/source/gameengine/Rasterizer/RAS_Polygon.h b/source/gameengine/Rasterizer/RAS_Polygon.h index 41eaa6bdd4a..188390f1c6b 100644 --- a/source/gameengine/Rasterizer/RAS_Polygon.h +++ b/source/gameengine/Rasterizer/RAS_Polygon.h @@ -68,6 +68,7 @@ public: void SetVertexOffset(int i, unsigned short offset); int GetVertexOffset(int i); + int GetVertexOffsetAbs(RAS_MeshObject *mesh, int i); /* accounts for quad and tri arrays, slower, for python */ // each bit is for a visible edge, starting with bit 1 for the first edge, bit 2 for second etc. // - Not used yet! -- cgit v1.2.3 From 7ad4386653ad916a97f3054cab46350ea90fcc54 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 31 Aug 2009 04:24:28 +0000 Subject: Grease Pencil: Cleanup Work + Bugfixes * Disabled temporary debugging prints, since event handling now seems stable * Modified the initgrabz() code so that when the cursor is behind the viewplane, the z-factor is calculated as if the cursor was on the other side of the view plane. This seems to work well, and doesn't seem to have any negative side-effects (yet). --- source/blender/editors/gpencil/gpencil_paint.c | 84 +++++++++++++---------- source/blender/editors/space_view3d/view3d_view.c | 5 +- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 67bf2951bf8..99b85d62026 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -86,6 +86,7 @@ typedef struct tGPsdata { } 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 */ bGPDframe *gpf; /* frame we're working on */ @@ -153,6 +154,29 @@ static int gpencil_draw_poll (bContext *C) /* ******************************************* */ /* Calculations/Conversions */ +/* Utilities --------------------------------- */ + +/* get the reference point for stroke-point conversions */ +static void gp_get_3d_reference (tGPsdata *p, float *vec) +{ + View3D *v3d= p->sa->spacedata.first; + float *fp= give_cursor(p->scene, v3d); + + /* the reference point used depends on the owner... */ + if (p->ownerPtr.type == &RNA_Object) { + Object *ob= (Object *)p->ownerPtr.data; + + /* active Object + * - use relative distance of 3D-cursor from object center + */ + VecSubf(vec, fp, ob->loc); + } + else { + /* use 3D-cursor */ + VecCopyf(vec, fp); + } +} + /* Stroke Editing ---------------------------- */ /* check if the current mouse position is suitable for adding a new point */ @@ -187,10 +211,8 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) { - View3D *v3d= p->sa->spacedata.first; const short mx=mval[0], my=mval[1]; - float *fp= give_cursor(p->scene, v3d); - float dvec[3]; + float rvec[3], dvec[3]; /* Current method just converts each point in screen-coordinates to * 3D-coordinates using the 3D-cursor as reference. In general, this @@ -201,11 +223,12 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) * reference point instead or as offset, for easier stroke matching * - investigate projection onto geometry (ala retopo) */ + gp_get_3d_reference(p, rvec); /* method taken from editview.c - mouse_cursor() */ - project_short_noclip(p->ar, fp, mval); + project_short_noclip(p->ar, rvec, mval); window_to_3d_delta(p->ar, dvec, mval[0]-mx, mval[1]-my); - VecSubf(out, fp, dvec); + VecSubf(out, rvec, dvec); } /* 2d - on 'canvas' (assume that p->v2d is set) */ @@ -831,7 +854,7 @@ static tGPsdata *gp_session_initpaint (bContext *C) #endif case SPACE_IMAGE: { - SpaceImage *sima= curarea->spacedata.first; + //SpaceImage *sima= curarea->spacedata.first; /* set the current area */ p->sa= curarea; @@ -863,7 +886,7 @@ static tGPsdata *gp_session_initpaint (bContext *C) } /* get gp-data */ - gpd_ptr= gpencil_data_get_pointers(C, NULL); + gpd_ptr= gpencil_data_get_pointers(C, &p->ownerPtr); if (gpd_ptr == NULL) { p->status= GP_STATUS_ERROR; if (G.f & G_DEBUG) @@ -951,13 +974,11 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode) switch (p->sa->spacetype) { case SPACE_VIEW3D: { - View3D *v3d= (View3D *)p->sa->spacedata.first; RegionView3D *rv3d= p->ar->regiondata; + float rvec[3]; - // TODO 1: when using objects, make the data stick to the object centers? - // TODO 2: what happens when cursor is behind view-camera plane? - float *fp= give_cursor(p->scene, v3d); - initgrabz(rv3d, fp[0], fp[1], fp[2]); + gp_get_3d_reference(p, rvec); + initgrabz(rv3d, rvec[0], rvec[1], rvec[2]); p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE; } @@ -1215,18 +1236,18 @@ static int gpencil_draw_exec (bContext *C, wmOperator *op) { tGPsdata *p = NULL; - printf("GPencil - Starting Re-Drawing \n"); + //printf("GPencil - Starting Re-Drawing \n"); /* try to initialise context data needed while drawing */ if (!gpencil_draw_init(C, op)) { if (op->customdata) MEM_freeN(op->customdata); - printf("\tGP - no valid data \n"); + //printf("\tGP - no valid data \n"); return OPERATOR_CANCELLED; } else p= op->customdata; - printf("\tGP - Start redrawing stroke \n"); + //printf("\tGP - Start redrawing stroke \n"); /* loop over the stroke RNA elements recorded (i.e. progress of mouse movement), * setting the relevant values in context at each step, then applying @@ -1235,7 +1256,7 @@ static int gpencil_draw_exec (bContext *C, wmOperator *op) { float mousef[2]; - printf("\t\tGP - stroke elem \n"); + //printf("\t\tGP - stroke elem \n"); /* get relevant data for this point from stroke */ RNA_float_get_array(&itemptr, "mouse", mousef); @@ -1257,7 +1278,7 @@ static int gpencil_draw_exec (bContext *C, wmOperator *op) } RNA_END; - printf("\tGP - done \n"); + //printf("\tGP - done \n"); /* cleanup */ gpencil_draw_exit(C, op); @@ -1277,7 +1298,7 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) tGPsdata *p = NULL; wmWindow *win= CTX_wm_window(C); - printf("GPencil - Starting Drawing \n"); + //printf("GPencil - Starting Drawing \n"); /* try to initialise context data needed while drawing */ if (!gpencil_draw_init(C, op)) { @@ -1308,7 +1329,7 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) */ if (event->type) { /* hotkey invoked - start drawing */ - printf("\tGP - set first spot\n"); + //printf("\tGP - set first spot\n"); p->status= GP_STATUS_PAINTING; /* handle the initial drawing - i.e. for just doing a simple dot */ @@ -1316,7 +1337,7 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) } else { /* toolbar invoked - don't start drawing yet... */ - printf("\tGP - hotkey invoked... waiting for click-drag\n"); + //printf("\tGP - hotkey invoked... waiting for click-drag\n"); } /* add a modal handler for this operator, so that we can then draw continuous strokes */ @@ -1329,7 +1350,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) { tGPsdata *p= op->customdata; - printf("\tGP - handle modal event...\n"); + //printf("\tGP - handle modal event...\n"); switch (event->type) { /* end of stroke -> ONLY when a mouse-button release occurs @@ -1340,7 +1361,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* if painting, end stroke */ if (p->status == GP_STATUS_PAINTING) { /* basically, this should be mouse-button up */ - printf("\t\tGP - end of stroke \n"); + //printf("\t\tGP - end of stroke \n"); gpencil_draw_exit(C, op); /* one last flush before we're done */ @@ -1350,7 +1371,7 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) } else { /* not painting, so start stroke (this should be mouse-button down) */ - printf("\t\tGP - start stroke \n"); + //printf("\t\tGP - start stroke \n"); p->status= GP_STATUS_PAINTING; /* no break now, since we should immediately start painting */ } @@ -1360,31 +1381,20 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* check if we're currently painting */ if (p->status == GP_STATUS_PAINTING) { /* handle drawing event */ - printf("\t\tGP - add point\n"); + //printf("\t\tGP - add point\n"); gpencil_draw_apply_event(C, op, event); /* finish painting operation if anything went wrong just now */ if (p->status == GP_STATUS_ERROR) { - printf("\t\t\tGP - error done! \n"); + //printf("\t\t\tGP - error done! \n"); gpencil_draw_exit(C, op); return OPERATOR_CANCELLED; } } break; - /* scrolling mouse-wheel increases radius of eraser - * - though this is quite a difficult action to perform - */ - // XXX this stuff doesn't work - case WHEELUPMOUSE: - p->radius += 1.5f; - break; - case WHEELDOWNMOUSE: - p->radius -= 1.5f; - break; - default: - printf("\t\tGP unknown event - %d \n", event->type); + //printf("\t\tGP unknown event - %d \n", event->type); break; } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 771c02e95b6..c61b2f0f31d 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -482,7 +482,10 @@ void initgrabz(RegionView3D *rv3d, float x, float y, float z) /* Negative zfac means x, y, z was behind the camera (in perspective). * This gives flipped directions, so revert back to ok default case. */ - if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; + // NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok + // -- Aligorith, 2009Aug31 + //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; + if (rv3d->zfac < 0.0f) rv3d->zfac= -rv3d->zfac; } /* always call initgrabz */ -- cgit v1.2.3 From 07abbaa9d722115ec7899cef22862232c37f66d2 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 31 Aug 2009 04:39:08 +0000 Subject: 2.5 - Datatype defines for MotionPaths and Visualisation Settings --- source/blender/makesdna/DNA_action_types.h | 50 ++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 6f097ea3882..c9d75d5c262 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -40,6 +40,54 @@ struct SpaceLink; struct Object; +/* ************************************************ */ +/* Visualisation */ + +/* Motion Paths ------------------------------------ */ +/* (used for Pose Channels and Objects) */ + +/* Data point for motion path */ +typedef struct bMotionPathVert { + float co[3]; /* coordinates of point in 3D-space */ + int flag; /* quick settings */ +} bMotionPathVert; + +/* Motion Path data cache - for elements providing transforms (i.e. Objects or PoseChannels) */ +typedef struct bMotionPath { + bMotionPathVert *points; /* path samples */ + int length; /* the number of cached verts */ + + int start_frame; /* for drawing paths, the start frame number */ + int end_frame; /* for drawing paths, the end frame number */ + + int flag; /* extra settings */ +} bMotionPath; + + + +/* Animation Visualisation Settings - for Objects or Armatures (not PoseChannels) */ +typedef struct bAnimVizSettings { + int pad; + int pathflag; /* eMotionPath_Settings */ + + int pathsf, pathef; /* start and end frames of path-calculation range */ + int pathbc, pathac; /* number of frames before/after current frame of path-calculation */ +} bAnimVizSettings; + +/* bMotionPathSettings->flag */ +typedef enum eMotionPath_Settings { + /* show frames on path */ + MOTIONPATH_FLAG_FNUMS = (1<<0), + /* show keyframes on path */ + MOTIONPATH_FLAG_KFRAS = (1<<1), + /* for bones - calculate head-points for curves instead of tips */ + MOTIONPATH_FLAG_HEADS = (1<<2), + /* show path around current frame */ + MOTIONPATH_FLAG_ACFRA = (1<<3), + /* show keyframe/frame numbers */ + MOTIONPATH_FLAG_KFNOS = (1<<4) +} eMotionPath_Settings; + /* ************************************************ */ /* Poses */ @@ -438,5 +486,3 @@ typedef enum ACHAN_FLAG { #endif - - -- cgit v1.2.3 From 043641de72d7c9b6d27d92ccc3c64dc784450b11 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Aug 2009 13:03:38 +0000 Subject: corrections to epydocs --- source/blender/python/api2_2x/doc/Particle.py | 16 ++++++++-------- source/blender/python/api2_2x/doc/Texture.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/python/api2_2x/doc/Particle.py b/source/blender/python/api2_2x/doc/Particle.py index 15481c9dd63..b8e263f948f 100644 --- a/source/blender/python/api2_2x/doc/Particle.py +++ b/source/blender/python/api2_2x/doc/Particle.py @@ -70,7 +70,7 @@ This module provides access to the B{Particle} in Blender. - SPIN: Spin particle angular velocity - RANDOM: Random particle angular velocity @type VERTEXGROUPS: readonly dictionary -@var VERTEXGROUPS: Constant dict used for with L{Particle.VERTEXGROUP} +@var VERTEXGROUPS: Constant dict used for with L{Particle.getVertGroup} and L{Particle.setVertGroup} - DENSITY: VertexGroup affect to particles density - VELOCITY: VertexGroup affect to particles velocity - LENGHT: VertexGroup affect to particles lenght @@ -106,7 +106,7 @@ def New(object): """ Create a new particle system applied to L{object} @type object: string or L{Blender.Object.Object} - @param name: The name of an existing object. + @param object: The existing object to add the particle system to. @rtype: L{Particle} @return: a new Particle system. """ @@ -287,12 +287,12 @@ class Particle: @type childKinkAmp: float @ivar childBranch: Branch child paths from eachother @type childBranch: int - @ivar childBranch: Animate branching - @type childBranch: int - @ivar childBranch: Start and end points are the same - @type childBranch: int - @ivar childBranch: Threshold of branching - @type childBranch: float + @ivar childBranchAnim: Animate branching + @type childBranchAnim: int + @ivar childBranchSymm: Start and end points are the same + @type childBranchSymm: int + @ivar childBranchThre: Threshold of branching + @type childBranchThre: float """ def getName(): """ diff --git a/source/blender/python/api2_2x/doc/Texture.py b/source/blender/python/api2_2x/doc/Texture.py index 3431dceb6cd..b9a65d3017a 100644 --- a/source/blender/python/api2_2x/doc/Texture.py +++ b/source/blender/python/api2_2x/doc/Texture.py @@ -394,7 +394,7 @@ class Texture: The colorband can have between 1 and 31 colors. @type colorband: list @ivar useColorband: Use colorband for this texture. - @type colorband: int + @type useColorband: int @ivar autoRefresh: Refresh image on frame changes enabled. @type autoRefresh: boolean """ -- cgit v1.2.3 From bd5bab6b86163ddcd44bababee421b9dd4bf1b1e Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 31 Aug 2009 13:56:21 +0000 Subject: Win64: We need manifest if openmp is enabled --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1921ef65017..529d65b0dfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,7 +377,7 @@ IF(WIN32) SET(WINTAB_INC ${LIBDIR}/wintab/include) IF(CMAKE_CL_64) - SET(PLATFORM_LINKFLAGS "/MANIFEST:NO /MANIFESTUAC:NO /MACHINE:X64 /NODEFAULTLIB:libc.lib;MSVCRT.lib ") + SET(PLATFORM_LINKFLAGS "/MACHINE:X64 /NODEFAULTLIB:libc.lib;MSVCRT.lib ") ELSE(CMAKE_CL_64) SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib ") ENDIF(CMAKE_CL_64) -- cgit v1.2.3 From dfef0746e49844c217d515f487886805e2ef4684 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 31 Aug 2009 14:25:39 +0000 Subject: Update MSVC project files. --- projectfiles_vc9/blender/BPY_python/BPY_python.vcproj | 9 +++++---- projectfiles_vc9/blender/blender.vcproj | 10 +++++----- projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj | 13 +++++++------ projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj | 12 ++++++------ projectfiles_vc9/blender/loader/BLO_loader.vcproj | 9 +++++---- projectfiles_vc9/blender/nodes/nodes.vcproj | 8 ++++---- projectfiles_vc9/blender/src/BL_src.vcproj | 4 ++-- .../gameengine/blenderhook/KX_blenderhook.vcproj | 4 ++-- projectfiles_vc9/gameengine/converter/KX_converter.vcproj | 13 +++++++------ .../gameengine/expression/EXP_expressions.vcproj | 12 ++++++------ projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj | 12 ++++++------ .../gameengine/gameplayer/common/GP_common.vcproj | 9 +++++---- .../gameengine/gameplayer/ghost/GP_ghost.vcproj | 4 ++-- projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj | 13 +++++++------ .../gameengine/ketsji/network/KX_network.vcproj | 12 ++++++------ .../physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj | 12 ++++++------ .../gameengine/rasterizer/RAS_rasterizer.vcproj | 12 ++++++------ projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj | 4 ++-- projectfiles_vc9/kernel/system/SYS_system.vcproj | 5 +++-- 19 files changed, 92 insertions(+), 85 deletions(-) diff --git a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj index 55ef074178b..306bf4fecfd 100644 --- a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj +++ b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="BPY_python" ProjectGUID="{5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}" + RootNamespace="BPY_python" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj index 3cc89a17f1e..197f4050d6f 100644 --- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj +++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="BKE_blenkernel" ProjectGUID="{CAE37E91-6570-43AC-A4B4-7A37A4B0FC94}" + RootNamespace="BKE_blenkernel" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ @@ -117,7 +118,7 @@ @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ Date: Mon, 31 Aug 2009 15:28:43 +0000 Subject: BGE bug #18963: obj.sendMessage() with 4 arguments crashes Blender. --- source/gameengine/Ketsji/KX_GameObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index ba8905973d5..bfafce1dd40 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -2793,7 +2793,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage, char* to = (char *)""; const STR_String& from = GetName(); - if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to)) + if (!PyArg_ParseTuple(args, "s|ss:sendMessage", &subject, &body, &to)) return NULL; scene->GetNetworkScene()->SendMessage(to, from, subject, body); -- cgit v1.2.3 From 0b968bcbd99b140c2d9d6fd231edb68172d4dfc8 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 31 Aug 2009 15:54:56 +0000 Subject: BGE bug #19020: The GE Torque actuator x -& y-axis do not work in 2.49a (winxp) --- source/gameengine/Physics/Bullet/CcdPhysicsController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 20e830c9dc3..7f84b06cc3c 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1073,7 +1073,7 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque //workaround for incompatibility between 'DYNAMIC' game object, and angular factor //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque const btVector3& angFac = body->getAngularFactor(); - btVector3 tmpFac(0,0,1); + btVector3 tmpFac(1,1,1); body->setAngularFactor(tmpFac); body->applyTorque(torque); body->setAngularFactor(angFac); -- cgit v1.2.3 From 8b18843b98b300a14558f5b04c8bf995f8973da0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Aug 2009 16:36:02 +0000 Subject: remove "_amount" from rna names, its not helpful. --- release/ui/buttons_physics_fluid.py | 4 ++-- release/ui/buttons_texture.py | 2 +- source/blender/makesrna/intern/rna_fluidsim.c | 2 +- source/blender/makesrna/intern/rna_texture.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/release/ui/buttons_physics_fluid.py b/release/ui/buttons_physics_fluid.py index fe15e22f0b9..6f7a97ff793 100644 --- a/release/ui/buttons_physics_fluid.py +++ b/release/ui/buttons_physics_fluid.py @@ -94,7 +94,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel): col.itemL(text="Slip Type:") col.itemR(fluid, "slip_type", text="") if fluid.slip_type == 'PARTIALSLIP': - col.itemR(fluid, "partial_slip_amount", slider=True, text="Amount") + col.itemR(fluid, "partial_slip_factor", slider=True, text="Amount") col.itemL(text="Impact:") col.itemR(fluid, "impact_factor", text="Factor") @@ -228,7 +228,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel): sub = col.column(align=True) sub.itemR(fluid, "slip_type", text="") if fluid.slip_type == 'PARTIALSLIP': - sub.itemR(fluid, "partial_slip_amount", slider=True, text="Amount") + sub.itemR(fluid, "partial_slip_factor", slider=True, text="Amount") col = split.column() col.itemL(text="Surface:") diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index ad0542d787a..ee3f85e15ef 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -609,7 +609,7 @@ class TEXTURE_PT_distortednoise(TextureTypePanel): layout.itemR(tex, "noise_basis", text="Basis") flow = layout.column_flow() - flow.itemR(tex, "distortion_amount", text="Distortion") + flow.itemR(tex, "distortion", text="Distortion") flow.itemR(tex, "noise_size", text="Size") flow.itemR(tex, "nabla") diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index 936e1700ed7..dda21f63528 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -162,7 +162,7 @@ static void rna_def_fluidsim_slip(StructRNA *srna) RNA_def_property_enum_items(prop, slip_items); RNA_def_property_ui_text(prop, "Slip Type", ""); - prop= RNA_def_property(srna, "partial_slip_amount", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "partial_slip_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "partSlipValue"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Partial Slip Amount", "Amount of mixing between no- and free-slip, 0 is no slip and 1 is free slip."); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index f899d52543e..6de0be9b19c 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1293,7 +1293,7 @@ static void rna_def_texture_distorted_noise(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Distorted Noise", "Procedural distorted noise texture."); RNA_def_struct_sdna(srna, "Tex"); - prop= RNA_def_property(srna, "distortion_amount", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "distortion", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "dist_amount"); RNA_def_property_range(prop, 0, 10); RNA_def_property_ui_text(prop, "Distortion Amount", ""); -- cgit v1.2.3 From 7fccc53fc671aaa3e1e7b7d7e923f197792dc563 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 31 Aug 2009 17:00:03 +0000 Subject: More MSVC project file update (don't propagate those changes to 2.5). --- projectfiles_vc9/blender/blender.vcproj | 6 +++--- projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/projectfiles_vc9/blender/blender.vcproj b/projectfiles_vc9/blender/blender.vcproj index 80f39be2a59..0ffbcd9aa67 100644 --- a/projectfiles_vc9/blender/blender.vcproj +++ b/projectfiles_vc9/blender/blender.vcproj @@ -73,12 +73,12 @@ -- cgit v1.2.3 From 15f81f4b03692691cee123e9094c92378658d8bb Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 31 Aug 2009 18:16:18 +0000 Subject: Part 1 of the 2.49b commit --- release/VERSION | 2 +- release/datafiles/splash.jpg | Bin 197158 -> 197165 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/release/VERSION b/release/VERSION index 3046e7afa7d..1ec4cde4e46 100644 --- a/release/VERSION +++ b/release/VERSION @@ -1 +1 @@ -2.49a +2.49b diff --git a/release/datafiles/splash.jpg b/release/datafiles/splash.jpg index 1c34cf36f75..e35a26a2c23 100644 Binary files a/release/datafiles/splash.jpg and b/release/datafiles/splash.jpg differ -- cgit v1.2.3 From 959757c2d7bdfe7955e2c645a511ac450a607c47 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 31 Aug 2009 18:17:06 +0000 Subject: Part 2 of the 2.49b commit. We now should freeze and tag! --- source/blender/src/splash.jpg.c | 12322 +++++++++++++++++++------------------- 1 file changed, 6161 insertions(+), 6161 deletions(-) diff --git a/source/blender/src/splash.jpg.c b/source/blender/src/splash.jpg.c index 547b23b40db..58dba6b1c4c 100644 --- a/source/blender/src/splash.jpg.c +++ b/source/blender/src/splash.jpg.c @@ -1,6167 +1,6167 @@ /* DataToC output of file */ -int datatoc_splash_jpg_size= 197158; +int datatoc_splash_jpg_size= 197165; char datatoc_splash_jpg[]= { -137, 80, 78, 71, 13, 10, - 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 1,245, 0, 0, 1, 26, 8, 2, 0, 0, 0,135, 56, 89, 17, 0, 0, 0, 9,112, - 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 4,103, 65, 77, 65, 0, 0,174,211,164,123,114, 68, - 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,110, 39, 0, 0,115,175, 0, 0,246,112, 0, 0,129,232, 0, 0,107,215, 0, 0,226,170, - 0, 0, 48,131, 0, 0, 21, 42,251,118,133,113, 0, 3, 1,156, 73, 68, 65, 84,120,218, 98,252,255,255, 63,195, 40, 24, 5,163, - 96, 20,140,130, 97, 7, 0, 2,136,133,138,102,253,249,249,253,223,203,235,127, 63, 63, 99,150, 50,102, 19,148, 28, 13,220, 81, - 48, 10, 70,193, 40, 24, 64, 0, 16, 64,140,212,106,191,255,249,241,237,247,230,124,150,143, 55,128,236,255, 12,204,127, 52, 35, -217,204, 18, 89, 88,217, 70,131,120, 20,140,130, 81, 48, 10, 6, 4, 0, 4, 16, 19,181, 12,250,255,242, 26,164,112, 7, 85, 26, - 12,127, 89,174, 45,249,190,171,121, 52,124, 71,193, 40, 24, 5,163, 96,160, 0, 64, 0, 81,173,124,255, 39,168,248,155,153, 7, -216, 25, 0, 35, 16,193,246,116,255,151,205,165,127,190,127, 30, 13,229, 81, 48, 10, 70,193, 40,160, 63, 0, 8, 32, 70, 42,206, -175,254,120,126,243,239,193, 54,150, 79,119, 17,141,122, 6,134,191,156,162, 76,206,237,156, 82, 26,163, 97, 61, 10, 70,193, 40, - 24, 5,244, 4, 0, 1,196, 72,245,245, 51,159,143,205, 99,189, 50,159,225,255, 63, 68,211,158,145,229,183,106, 16,183, 69, 50, - 11, 39,207,104,136,143,130, 81, 48, 10, 70, 1,125, 0, 64, 0, 49,210, 98,125,228,143, 59,135,255,238,111, 96,250,247, 3,218, -134, 7,227, 63,156, 18, 44,110,237,156,146,234,163,129, 62, 10, 70,193, 40, 24, 5,116, 0, 0, 1,196, 72,163,245,239,223, 95, -221,251,191,187,138,225,243, 35,132,208,127,134,191, 76,236, 76, 86, 37,220,186,222,163,225, 62, 10, 70,193, 40, 24, 5,180, 6, - 0, 1, 68, 84,249,254,237,195,235, 63,119, 14,253,120,126,249,255,159, 95,196, 27,205,252,235, 51,215,251,179,176, 38, 60,130, -248, 99, 90,194,111, 18, 60, 26,244,163, 96, 20,140,130, 81, 0, 7,255,254,253,251,254,253,251, 71, 48, 0, 50, 88, 88, 88,254, -252,249,195,205,205, 45, 36, 36,244,245,235, 87, 70, 70,198, 31, 63,126,124,251,246, 13, 82, 98, 75, 72, 72, 8, 11, 11,179,179, -179,227, 55, 19, 32,128, 8,151,239, 31, 46,237, 96, 58,209,195,252,247, 27, 68, 61,156, 96, 64,110,153, 99, 99,162, 9, 33,217, -243,255,175, 94, 18,191, 77,218,104,140,142,130, 81, 48, 10, 70, 1, 16, 0,203,244,135, 15, 31,242,241,241,241,242,242,242,240, -240,176,177,177, 1, 11,244,143, 31, 63, 29, 63,126, 76, 89, 89, 89, 76, 76,140,131,131,131,133,133, 21, 40,200,196,196,248,239, -223,255, 47, 95,190, 60,124,248, 0, 88,244, 75, 73, 73, 1, 5,113, 25, 11, 16, 64, 4,202,247, 95, 63,127,124, 91,224,203,242, -247, 43, 3, 35,169, 14,254,143, 89,214,255, 71,106,201,255,145, 48,231,245,106, 97,225,228, 29,141, 90,234, 2,120,132,226,137, -245,145,224,134, 81, 48, 10,134, 74,179,253,237,219,183, 79,158, 60, 49, 48, 48, 0,230, 23, 96,217,253,251,207,223,175,223,126, -222,185,255,114,223,190,189, 26,106, 10,110, 46,118,236,108,172, 64,193,191,255,254,255,252,249,231,219,143, 95, 63,126,254,225, -229, 98, 23, 18,228,190,127,239,174,176,176, 16,176, 33,143,203,112,128, 0, 98, 33, 42,183, 34, 10,107,244,236,202,136,209,110, -255,143,213, 0,140,246, 60,243,243, 19,159,151,199, 50, 59,212,240, 41,153,140,198, 49,229,229, 41, 16,124,248,250,227,194,131, -215,144,178, 85, 79, 78, 88,128,155,131, 9, 88,215,195, 0, 29,138,111,136, 51, 46, 60,120,245,225,235, 79, 32,131,166,110, 24, - 5,163, 96, 24,128, 63,127,254, 60,120,240,128,149,149, 85, 87, 87, 23,152, 65,158,191,250,120,227,206,139, 7,143,223, 60,124, -244,252,209,131, 91, 92, 60, 2,191,152,127, 10, 8, 63,248,249,235,239,171,183,159,190,125,255,245,251,247,223, 63,192, 98,254, -255,127, 54, 86, 22, 89, 25, 17, 1,142,239,114,114,114,120,204, 7, 8, 32,194,227, 51,223, 30, 95,250,115,105,197,175,175, 31, -153, 88, 89,177, 20,240,159,158,177,124,125,140,117,180,230, 55,155,240,127, 1, 57, 14,126,201,127,191, 62,253,120,243,148,237, -219, 35,198,255,127,224,101, 61,220,214,127,186, 73,130,246,233,104,166, 94,186,241, 96,235,249,187, 14,186,138,198,106,178,108, -108,172, 67, 40,182,110, 61,120,190,243,226,125, 75, 85,105, 11, 61,101,186,213,255,139, 14, 93,155,186,235,226,165, 71,111,145, -197,229,132,121, 34,173,212,178, 93,245,132,120, 57,153,153,153,169, 82,194, 66,138,239,210,165, 71, 58, 35,173,244,229, 69,153, -192, 0, 34, 14,172, 93, 74,150, 28,222,124,238,222,199,111,191,144,221,144,238,172,147,235,174, 15,116, 0, 92,241, 40, 24, 5, -163, 0,152,101,222,189,123,247,250,245,107,110,110,110, 89, 89, 89, 96,153,125,226,236,189,157, 7, 46,189,127,243,250,243,231, -215, 92,220,252, 95, 62,127,144, 85,212,178, 50, 86, 97, 98,102,190,126,251, 57,166, 9,192,220,244,246,213, 51, 39, 71, 43, 27, - 19, 5, 22, 22,236, 57, 11, 32,128, 40, 90, 63,243,238,236, 70,166, 83,253, 76,255,126, 34, 23,237,255, 25,152,126, 75,219,115, - 24,132,115,202,232, 48,179, 32,250, 7,127,190,127,249,126,125,231,239,115, 11,152,127,188,130,171,133,216,253, 95, 59, 86,208, - 41, 23,217,228,221, 71, 47,120, 78,218, 1, 84, 35,192,198,116,170, 45, 86, 73,142,192,105,101,249,147, 86,223,253, 8,114,134, -151,158, 98,150,191,245,128, 68,216,179, 23,175,108,107,150, 62,253,250, 27, 88, 7,206,138,177,143,243, 50,167,138,177,223,190, -255,216,126,241, 1,144, 33,203,207, 97,166,169,112,238,230, 35, 35,117, 68,141,253,254,203,119,183,182,245,151, 30,189,193,165, -157,143,147,109, 83,145,151,145,146, 56, 11, 48, 9,128,155,210,148, 56,230,222,203, 15, 22,181, 43,128, 37,248,166, 34, 79,123, - 45, 89,160,153,192,130, 27, 40, 14, 44,244,221,219,215, 35,151,236,200, 64, 71, 70,104,115,177,183, 8, 63, 55,196, 13,163,121, -123, 20,140,240,146,253, 45, 24,176,177,177, 1, 73,126,126,254, 63,127,254,157,188,240,224,232,241,211,156,236,156,255, 25, 25, -248,248,132,128,170, 24,153, 89,228, 36,249,213,212,213, 46, 93,127,241,247,239, 95,244,130, 27, 12, 94,191,122, 42, 38, 38,157, - 20, 97,205,195,141,125,162, 21, 32,128,200, 60, 63,242,231,151, 15, 95,143,204, 96,190,179, 1,109, 64,230, 55,135, 4,139,117, -177,136,166, 45, 22,155, 56,121,120,141,130,255,104,186,127, 62, 56,137,241,246, 6,148,246,254,149,197,159,132,228,248, 12,252, - 81, 4,193,133,255,135, 95,127,127,252, 36,188,104,231,196,205,167,103, 94,129,102,128, 21, 5, 7,108, 64,255,223,191,255, 79, -128,133, 59,246, 33, 42,242, 1, 23, 39,135, 36,203, 95, 96, 92, 78,221,124,156,155,153,177,107,193,246, 21,237, 25,240,132, 18, - 58, 97, 43,114,225,174, 41,201,207,199,201,250,233,251,239,235,207, 63, 66,251, 87,223,127,249,245,109,219, 80,224,110,162, 34, - 5, 47,142,201, 3,192,186, 36,124,226, 86, 72, 33,254,235, 23,176,171,248, 27, 98,218,131,215, 31,145, 11,119, 62, 14, 86, 77, - 41,126, 32,227,228, 61,168,195,174, 60,121,231,211,179,229, 96, 77, 0, 40, 25,140, 22,241,195, 11,124,249,250,243,238,253,215, -112,174,178,162, 40,176,172,217,181,239,218,177, 83,119,173,204,148,221,156,180, 72, 50,141, 72,141,104,150, 74,136,241,137,139, -241,145,231,254,187, 15, 94, 47, 94,113,162,161,194, 23,191, 93,250, 58, 50,212, 10,177, 7, 15, 30, 0,179,143,146,146, 18, 48, - 47,112,115,113,223,186,125,107,253,150,163, 60,252, 18,146,114, 26,192,252,241,255, 31,168,248,224,229,227, 84,146,224,224,224, -226,218,176,105,167,172,130, 38, 19, 19, 51,184, 76,135,244,128,255,255,254,253,243,199,143,111,111, 95, 61, 23, 17,147,150,145, - 20,192, 85,184, 3, 1, 64, 0,145, 83,190,127,123,245,240,235,166, 34,182, 31, 79,209,196,127,113,201,243, 4, 77,229, 20, 16, -129,150,245,191,127,239, 61,121,109,203,165,251,130,220,156,206, 26,210,214, 70,234,172,172,172,192, 82, 94,208,163,234,237,215, -183,204,207, 14, 51, 32,141,204,255, 62, 54,225,151,134, 43, 27, 7,215, 80,175,155, 25, 24,168, 63,202,204,195,195, 13, 36,181, -100,132, 22,108, 59,166, 41,129,168,192,128, 5,235,225, 27,207, 32,108,115, 37,145,206, 96, 35, 57, 17, 94,200, 80, 12,176,180, -109,220,120,110,205,153,135,144, 34,190,115,243,185, 37, 89,194,224,201,119, 50,155,240,255,254,253, 75,153,181, 7, 62, 4,244, -231,207, 95,160, 8,100,192,189,100,201, 97,120,225,158,235,172,145,239,162, 9, 25,141, 1, 86, 51,115, 15,221,156,176,251, 26, - 80,252,234,211,247,109, 27,207,212, 4,154,193,135,227, 71, 75,198,225, 1,128,101, 95, 67,199, 38, 68, 90,229,102, 47,201,117, -255,242,237,231,197, 43,143,245, 72, 47, 19,137,212, 8,177, 84, 95, 71, 22,194, 37,163, 34, 65,216,248, 5,100, 35,166,248,186, - 45,231, 47, 93,121, 2, 44,247, 33,118,173, 95,146, 69,149,150,251,163, 71,160, 45, 65,106,106,106,192, 44,240,225,195,167,109, -219,182,187,123,122, 91,218,114, 94,185,245, 76,132,159, 75, 84,136, 71, 94, 86, 68, 86, 74, 72, 12,152,145,153,152,158, 60,121, -250,248,169,230,227,167,207,249,248,133,254,254,253, 3, 90,237,242,229,211,175, 95, 63,216, 56, 56,129, 36,232,156, 94, 22, 38, -125, 29,124,227,239, 0, 1, 68,114,249,254,233,206,201,159,123, 27, 89,126,189,133,159, 63, 0,201,169,255,152, 56,184,220, 26, -224,133,251,142,227,151,171,150, 29,188,250,250, 43,164,204,235,220,126, 65, 73,248, 64, 95,180,189,151,149, 46, 80,132,223,179, -238,203,202,184,255,159,159,195, 87,212, 48,254,254,242,253,226, 6, 54,243, 40,244,226, 18, 44,255,236,229,155, 77, 39,110, 60, -124,253,241,195,247, 63,192, 48,146, 17,226,246, 48, 86, 53,209, 84, 64, 81,248,255, 63, 90,211,249,205,187,143,107, 14, 94,220, -113,249,193,213, 7,175,222,126,251,197,201,194,172, 32,193,239,162,167,152,236,106, 44, 39, 41,130,203,131,251,207, 92,223,116, -234,214,201,187,207, 56,216,217, 12, 20, 36, 2,205, 84,109, 13,212,208,212,220,188,247,116,221,137,235, 79,222,125,251,241,239, -191, 32, 59,179,162,164,160,135,129, 18, 59, 11, 19, 3,194, 9, 8,135,188,251,240,105,241,222, 11,155,207,220,186,251,242,227, -151, 95,127,217,153,153,100,132,185,237,117,149, 18,157, 13, 52,228,196,177,186,225,240,133, 91,221, 27,142,223,124,242, 6, 24, -201,103,102, 22,114,115,178,255,255,255, 79, 78,148,159,143,157, 77,150,159, 3,174, 76, 78,152,247,112, 93,144,119,247, 22, 55, -109,169,238, 48, 19, 96,115, 0, 84,131,130, 27,200, 92, 92,255,166,196,219,157,184,183,238,201, 59, 80, 20,236,188,242,244,205, -199, 47,146,172,172,204, 96, 64, 70,186, 44, 89,114,104,203,185,251,136,226,254, 63,180,112,191,255,234, 35, 92, 60,200, 72,182, -192, 85,139,157,157, 29,216,241, 4,218,194,195,195, 80,233,111,242,236,227,143, 85,167,238, 1,101,231, 28,188, 81,234, 5, 29, -136, 31, 45,223,135, 31,104,168,240,155, 62,239,192,203, 87,159,128, 45, 98,204, 38, 57,164,105, 31,232, 99,120,236,228, 93, 96, - 33, 14, 26,235,187,255, 26,216, 52,118,115,212,178, 50, 87, 6,106, 89,191,249, 60,144,251,229,235, 15,252, 26,149, 21, 68,129, -138, 25,161, 54,250,162, 41, 6,214, 46,174,142, 90,192,230,252,209, 83,119,131,124, 12, 33,226,192,166, 61, 68, 4,200, 5, 22, -217, 64,110,102,146, 61,208,174, 93,251,175, 1,185,112, 19, 22,175, 60, 1,233, 19, 0,107, 23,160, 94,160,212,139, 87, 31,129, -165, 60, 15, 23,123,108,132, 37, 80,252,226,149, 39,187,247, 95, 3,106,132, 84, 39, 64,147,129,238,129,248, 2,232, 60, 98, 26, -248,207,159, 63,255,251,247,175,162,162, 34, 48,253,191,123,247,121,203,230,205, 22,150,182, 92,156, 60, 62, 46,122,198,186,114, -194, 66, 60,156,236,108,192, 60,138,200,224,114, 50, 1, 30, 44,187, 15,177,158, 61,127,233,223,191,191,156,156,188, 28,220,220, -188, 2,194,156, 92, 60,204,204, 44, 64, 67,190,125,122, 46,196,139,175, 12, 7, 8, 32,210,202,247,183, 71, 23, 49,156,155,197, -252,255,247,127,120,201,206, 8, 45,201,254,233,196,112,203,104, 66,148,205,219,124, 36,119,217,209, 63,255, 81,230, 82,239,189, -249, 18, 48,113,107,223,235, 15, 57,254,182, 44, 92,252, 76,214,229,127,182,231, 35,183,123,127,156, 91,204,143, 92,190,195,116, - 55,175, 60,184,229,234,211,111,127,144,202,205,255, 12,245, 27, 78,133,153, 40,205,206, 13,224,225,230,100,192, 54, 38,178,225, -224,185,180, 57,187,223,124,255, 3, 23,249,240,231,207,139, 7,111, 79, 60,120,219,189,229,108,178,163,118,103,130, 59, 23, 39, -199,149, 91,143,138,151,236,131, 40,200,182,215,156,184,227,252,193, 7,239,224, 21,215,161, 59, 47, 39,237,185, 20,107,174, 50, - 51, 55, 0, 50,205,251,237,251,143,210,153,155,231,159,184,251,231, 63, 74, 83,189,112,233,225, 72, 3, 89, 72,117,196,136,228, -156, 61,167,174,166,204,218,249,252, 11,210, 16,211,159,127,175,159,125, 60,255,236,252,148, 93,231,107,253, 76, 43, 34,157,129, - 98,215,110, 63,154,180,227, 60, 68,222, 68,134,175,120,245,201,239,127, 65, 70,136,177,130,134, 50,148,229, 65,211, 15, 42, 10, -210,152, 99,112, 6, 10, 98,155,138, 60, 37,249,216, 57, 57,217,129, 37, 59,164, 96,133, 53,177,255,120,235,203,207,220,127, 13, -194,189,244,232,141,168, 0, 47, 43, 43, 43, 25,133,251,194,131, 87,167,238,186,132, 85,118,211, 89,196,113,114,121,206,154, 64, - 7,112,112,112,192,157, 1, 76,205, 21,126,198,144,242, 29,216,156,223,114,254, 65,144,185,218,232, 16,205,240,108,200, 63,120, -253,245, 43,168,224,134, 20,193,240, 66,115,221,230,115,144,193, 19, 96, 51, 25, 88,250, 3, 75, 67,228,246, 50,144, 61, 67, 49, -166,161,125, 19, 80, 28, 88,142,127,249,250,147, 24,141,174, 14, 90,144, 2, 23,194, 5,202, 46, 94,121, 60, 54,220, 18, 88,224, - 2,219,218, 5,153, 46,139, 87, 28,135,148,239,192, 66, 31,210, 27, 0,137,248, 26, 1,171, 19, 96, 37, 4,113,225,221,251,175, -130,124,140,128, 12,136,177,144,202, 6,200, 0, 42, 0,150,233,112, 23, 2,221, 48,189, 99,147,181,153, 50,208,100, 96, 65, 15, -148, 2,218, 5, 49, 25, 88, 1,196,133, 91, 94,188,250, 4,168,101, 70, 95, 12,254,240,249,241,227,199,151, 47, 95,128, 45,119, - 96,201,241,225,227,247,189,123,246,106,104,104, 9,139,138, 3,115, 3, 7, 59,171,162,156, 40,214,172,247,239,239, 95, 29, 85, - 33, 6, 70,147, 55, 31,190,113,114,112,178,179, 51,179,179,177,240,114,177, 11, 10,112,241,242,112,178,177,168, 61,125,250,148, -143,143, 23, 87,163, 13, 32,128,136, 45,223,255,124,255,252,102,107, 51,235,179, 3,200, 99, 16,240,214,234, 95,102, 94, 94,195, - 16,136,202,107,119, 30, 23, 44, 63,250,251,223,127,140,129, 11, 16, 40, 91,126,196,217, 80, 77, 83, 78,156, 79,205,234,205, 9, -117,198,247, 55,225, 6,177,252,124,253,245,209,101,110, 57, 93, 84, 61,255, 87, 93,124,140,106, 6, 20,172, 58,115,239, 85,219, -242,189,173, 73,152,174,221,114,248, 66,228,212,237, 63, 65,110, 96,100,103, 98,140,183, 86, 51, 82,149,254,246,227,215,154, 99, - 55,142, 61,120, 3, 20,159,182,247,202,155, 79,223,151,151, 71,124,250,246,115,207,181,167, 16,255,156,186,253,252,211,159,127, -140, 12,140, 98,236,192, 70, 38,227,115,104,221,240,127,241,201,219,156,140,235,166, 21,133, 3, 57,153, 19,214, 46, 59, 15, 63, -116,225, 63,114, 51,116,249, 5,136, 56, 35,220,153,199, 47,221, 9,155,180,245,235,239,127,224, 81,105,230, 76, 7, 29, 69, 25, -145,175,223,126,110, 63,123,103,207,205,231,127,192,181,148, 0, 47, 87,134,143,229,235,119, 31,230, 31,185, 6,209,184,140,137, -241,199,223,127, 88,189,140, 89,190, 3,227,213, 88, 89, 18, 88,140, 66,216,144,214, 49, 92, 86,128,135, 3,121,122, 0, 14,136, -111, 62, 67, 22,204,164,207,217,135, 75,246, 8,108,128, 72, 90,144, 75, 78,132,151, 13, 12,128,181, 8,196, 25, 64, 82, 69, 82, - 72, 86,152,231,241,219, 47,160, 0,185,253,194,207, 88, 9,232, 90,200, 32,210,104,153, 56,156, 0,176, 0,133, 23,244, 72,205, -234,171, 64,210,218, 92, 5, 52,226,177,249,220,209,147,119, 32,131, 42,153, 73, 14,192,102,123, 73,237,106, 96,209, 12,108, 89, - 3,203, 86,160,154,146, 92, 55, 96,123, 25, 98, 14, 46,141,192, 18, 22, 88, 58,127,248,248,109,247,129,107,235,183,156,135, 91, -228,230,164, 13, 25,162, 57,118,242,206,213,235,207,176,186, 48, 54,220, 2,100,242,126, 80,187, 27,168, 12, 88, 31, 0,221,192, -205,205, 14, 52, 31, 50,200,115,233,234, 19, 72, 19, 30,168, 0, 84, 43, 92, 97, 0, 86, 18,144, 90, 4,232, 72, 96,245, 3,169, - 51, 94,190,254, 4,233, 88, 0, 45,133,152, 0,113, 45,126,112,251,246,109, 89, 89, 89, 72, 69,178,103,239, 30,126,126,126, 57, - 5,101,118, 86,102, 46, 46,156, 77,174, 47,159, 63,127,253,250, 85, 94, 94, 86, 67,147,247,193,227,183,192, 86,211,207, 95,127, -190,127,251,253,233,235,143, 79,159,127,188,125,247, 21,216, 8, 20,230,251,251,236,217, 51, 25, 25, 25,172, 25, 10, 32,128,136, - 42,223,191, 62,190,250,121, 71, 45,203,183, 39,240,102, 59,122,225, 45,166,195,193, 39, 8, 97, 47,216,119, 1, 81, 60,161, 15, -180, 48, 0, 91,254, 51,183,159,158,144,238, 3, 50, 71,222,238,255,187, 27, 40, 85,220,211,139,176,242,253, 63,242,102,168, 24, - 51,165, 66, 31,115, 5, 41,225,223,127,254,158,190,253,172,124,201,129,171, 47, 63,128,198, 82,110, 62, 91,115,232, 66,136,157, - 1, 82, 89,248,255,231,207, 95,213, 75, 15,252,132, 86, 48,255,235,253,140, 43, 98, 60, 32,230,231,248, 89, 59, 87,205, 59,124, -239, 21,208, 11,171, 78,223, 73, 63,123,131, 13, 82,239,129,213,126,250,253,207, 65, 73,164, 38,204,206,214, 64, 21,216,198,220, -118,236,138, 95,255, 38,136,236,146, 83,247,250,126,252, 60,113,245,254,178,243, 15,161,243, 72, 2, 92,221, 49,246,198,106,210, -188,220, 92, 79, 94,189,159,186,227,236,172,131,215, 81,154,238, 12, 12,213, 75,246,126,249, 13,154,248,102,101,100, 92, 91,224, -103,103, 8, 61, 91, 45,199,223, 38,162, 99,197,186,243,160, 97,141,170, 21,135,162, 29,244, 25,144, 22,149,255,248,251, 63, 88, - 95,182, 60,208, 90, 78, 82, 8,127, 33, 8, 31, 79,135, 47,127, 68, 83, 15, 41, 85,225,229, 47,164,112, 39, 41,211,222,127, 5, -154, 59,133,176, 53, 37,249,225,211,182,240,242,253,195, 55,104,131, 75, 70,128,139, 25, 6,224,117, 12,144, 1,228,202,193,202, -247,171,207, 62, 0, 11,119, 82,235,152, 81, 48, 36,192,250, 37, 89,187,246, 93, 3,182,100,129, 5, 52,100, 64, 3, 82,150, 65, -134,203,129, 36,124,184, 28,210, 40,230,225,102,151, 16,227, 7,150,239, 16, 17, 37, 69,148, 6, 44, 46,141,192,194, 93, 95, 71, - 6, 82,230,194,199,103, 26, 58, 54,115,195,230, 24,121,184, 57,136, 26,118,255,250, 19,121, 74,246,216,201,187,221,147,119, 2, - 27,248,129, 62,134,144,230, 57,150,105, 48,152,201,220,220,236,164, 6, 14, 36,217,115,113,113,253,248,249,231,204,153,179,191, -127,124, 55,178,119, 2,230, 90, 62, 62, 14, 60, 90, 94,189,126,253,235,247,111, 97, 97,225,119, 31,190, 61,120,242,246,227,167, -239,127,254,252, 67,148, 48,224,130,248, 31, 3,247,159,219,247, 69, 68, 68, 56, 57, 57, 49, 13, 1, 8, 32,194,229,251,155, 83, -235,254,158,232,103,254,247, 3,169,112, 71,202,153, 96, 38,139, 0, 98, 40,252,244,189, 23,200,187,157, 48,139,147,211,183,161, -237, 95, 86, 65,201, 95,168, 42,152, 62,191,196,104,241, 51,184,169, 75,204, 45, 10,101,129, 45,181,244, 18, 17,210,146, 23, 87, -207,159, 9,110, 22, 51,172, 58,122, 29, 84,190,255, 71,140,123, 95,189,251,228,242,107, 68,185,166, 34, 33,188,251, 20,162, 22, -209,148, 20, 4,150,239, 16,181,235, 78,221,138,176,212,132,219,228,168, 34,177,165, 33,134,131, 3, 26,226, 94, 86, 58,102,107, - 14,157,122,252, 30, 52, 44,243,247, 63, 48,184, 87, 31,191,254, 31,230,249,133,121,190,230, 58,208, 21,238,154,188, 60, 83,178, -101,223,126,249,177,230,236, 61,120,208,220,121,248,244,200, 3,232,108,164,180, 0,199,207, 63, 12,187, 79,223,132, 59, 67, 70, -136, 7,226,243, 47,191,254,110, 63,115, 75,156, 19, 62, 94,241, 63, 88, 79,110,113,121, 36, 11, 11, 81, 85, 47,254,185,202, 35, - 55,159, 35, 26,215,194, 60,164,238, 51, 66, 94, 48, 3, 44,220, 23,167, 88,155, 52,111,195,172,185, 49,235, 27,116, 23,194, 18, -204,147,247,223,128,193, 8,153,152, 29, 45, 16,135, 25, 0,150,185,144,150, 59,242,114, 14, 96,155, 23, 88, 70, 67,134,197,129, - 69, 57,176,129, 12, 31,129, 65,148,155,224,193, 16, 96, 19, 24, 88,118,195, 7,196,137,209,136, 92, 91, 0, 53, 2, 27,215,224, -181, 46,175,228,100,132,224, 53, 4,242,128, 62,154, 22,160,107,129, 85, 5,100, 76,233,197,235, 79, 64, 27,129, 13,124,100, 91, -144,245, 2, 29, 9, 52, 25, 40, 11,116, 18,100, 16, 31, 94, 51, 17, 3,126,252,248,241,230,205,155,237,219,119, 8,139, 72,190, -121,245, 74,223,192, 24,152, 79,248,120,241, 21,238, 79, 30, 63, 6,146, 26, 26, 26, 95,191,253, 58,124,242, 22,176,193,142,200, - 52,192, 28,197, 8,109, 52,255,254,245,235,238,203,247,198, 70,191,177,150,239, 0, 1,132,175, 16,249,253,243,199,139,173, 93, - 28,143, 54, 51,161,103,103,216, 40, 51, 60,123, 35,229,104, 14,118, 86,164,145, 27, 44,128, 29,118, 41,235,223, 63,127,208,178, - 57,211,223,175,152, 99, 0, 33,150, 26,104,133,157,130,148,168,145,172,208,201,135,160,129,242,235, 15,208, 87,254,159,190,255, - 2,153, 27, 54,125, 39,142,162,145,225,202,227, 87, 12,150,154, 8,149,150,234,240,194, 29, 2, 4,249,121, 24,192,229, 59, 52, - 5, 63,120, 1,174,143, 24, 85, 5,216,225,133, 59, 28, 68,217,106, 3,203,119,248,224,213,211,183, 8,191, 60,120,255,221,187, -123, 45,174,112,190,247,236,181,184,146, 56, 60,104, 35, 28,244,137, 44,220, 9,228,183,135,175, 31,189,133, 94,158,229,170, 41, - 9,105, 74, 19, 95,184, 35, 47,152,225,227,100,237, 10, 53, 17,230,197,183,186,233,201,135,111,184,164, 62,126,135, 78, 63, 60, -125,255, 13, 62, 70, 52, 90, 32, 14, 51, 0, 95, 69, 3, 25, 7,135,176, 51,147, 29,186, 39,237, 60,122,242, 14, 16, 65,138,126, -101, 69, 49,140,118, 49, 59,164, 52, 71, 94,135, 67,140, 70, 56, 0,150,236,245, 29,155, 50,138,150,124, 5, 13,226,139,133, 5, -154,236, 63,124,163,164,118, 53,104,236, 1, 71,173, 16,228, 99, 4,236,106, 0, 75,106, 96,169, 13,238, 34,200,172,223,124, 14, - 50, 94, 4,239, 40, 0, 59, 34,192,158, 1,100,248,222,205, 73,235,216,169,187,153, 69, 75, 32,141,247,204, 36,251,233,243, 14, - 18, 31, 56,175, 95,191, 22, 19, 19, 99,102,102, 83, 82, 82,253,249,243,199,215,175,159,248,248, 20,129, 29, 93, 92,195,158,111, -223,190,101,102, 97, 17,229,227, 7,230,217,107,183,158, 2, 11,119,112, 83, 9, 60,223,249, 15,178,156, 4,218,120,250,246,237, - 51, 80,246,225,211, 79,130, 2, 88, 86,136, 2, 4, 16,206,114,228,199,135,215,239,183,212,176,189, 62,251, 15, 92, 91, 32,236, -102, 98,255, 39,105,206,252,244, 16,114,193,254,255,251, 59,184, 2, 11, 21,169, 61,144,241,175,255, 88,134,144,129, 28, 7, 45, -104,111,235,239,183, 79,255, 81,135,111,254, 51, 48, 97,182, 12,181,101,177, 44, 50,225,231, 1,150, 53,160,162,231,215,159,191, - 48,197, 80,245,159,191,126, 39,106, 9,250,127, 96,220,127,135,116, 49, 32,190,208,149,151, 64,175, 2,152, 64,251,191,224,103, -170,253,248, 5, 29,145, 23,192, 86,241, 42,139,242, 51,192,215,240,252,255,127,239,237,199,255,255,255,163,173,150,100,196,114, - 42, 15,195,183,159,191,145,122, 58,255, 85,196,248, 41,207,108, 64,171,167,236,188, 8,231, 38,216,168, 64, 22,191, 19, 57,177, - 9,212,158, 58,107, 15,124, 97,204,210, 84, 91, 61, 57, 97,172,115,179,214,234,146, 71,110, 61,135,148,221,192,234, 68,131,139, - 11,173,236,254,240,245,199,229,199,111,145,171,141,209,194,125, 56, 1, 96,209,220, 80,225,135,204, 5,150,197,192, 82, 18, 88, - 62, 66,150,165,207,232,139, 1,182,148,191,124,249, 9, 41, 70,129,236,192, 47,134,202,224,209,152,216, 8, 11, 8,219,202, 92, - 25, 50,228, 2,212,242,226,213, 39,130, 26,209, 44,133, 40, 6,154,192,195,195, 14,180, 23, 40, 50, 29,168,247,254,107,160, 57, -192,154, 6,216,244, 6, 22,202,112,245, 64, 75,129, 34, 64, 45,202, 74,162, 64,195, 33, 85, 11, 80, 87, 79,115, 40,196,106,136, - 22,136,153, 64, 17,160, 2,136,153,160,181,146, 96,247, 64,150,202, 64,204,193,116, 12, 38,248,254,253,251,159, 63,127,128, 45, -241,159, 63,255,255,254,253, 91, 86, 70,230,253,187,215,192,182, 22, 46,245,159, 63,129, 0, 48,183, 10, 10, 10, 60, 3,173, 71, -122,133,104,174, 3, 75, 20, 38,164, 65,239,255,255,158, 63,125, 32, 35,171,242,230, 45,246,107, 80, 1, 2, 8,123,249,254,241, -246,201, 47, 59,235,153,127,189,249, 15, 29,144,129,102,200,191,108,130, 60,158,237,204, 76,140, 95,159, 30, 68, 46,131,127, 61, - 60,129,168,120, 61, 77,167,238,190,240,254,251,111,172,253,120, 1, 14,150,100, 55,232,129, 51,191, 31,159,102, 70,205,235,127, -153,185, 49,138,247,255,143,223,127,177,192,112,225,171,119,208,129, 96, 78, 54, 52, 47,252, 23,224, 67,220, 18, 37,207,195, 86, - 21,110,135, 43, 28,133,161, 29, 73,232, 82, 24,110, 14, 22, 28, 21, 1,116,149, 16, 23,176,107, 2,118,239,171, 79, 88, 58,125, -159, 80,123,130,178, 66,252,112, 95,152, 43,137, 39, 56,232,224,114,134,142,172,232,207, 47, 95,225, 5, 60, 55, 39, 27,229,185, -238,194,131, 87, 75,143, 66,135,131,130,140,228, 20, 68,249, 32,115,158,196,180,223, 33, 11,102,150, 28,129, 14,106,117,134, 24, -235,201,137,128,143,175, 99,193, 28, 29,242, 49, 84,232, 4, 79, 79, 1, 65,211,198, 11,139, 50,156,129,157, 74,228,115, 11, 38, - 35, 85, 51,163, 96,248, 1, 96,105,142,185, 52, 80, 28,117,195, 17,164,124,196,207,134, 27, 66,140, 70,172,150, 34,139,192, 21, -136, 99,200,194,205,129, 51,160, 42, 97,110, 22,199,240, 5,166, 94,100, 54, 86,199,160,140,115,190,127, 47, 36, 36,196,204,204, -242,231,239,143, 79, 95,126,126, 2,118, 98, 25, 89,190,126,253,202,195,195,131,150,239,128,213,192,215,175, 95, 62,188, 7, 77, - 46, 42, 40, 40,124,254,242,243,224,177,155,127,129, 77,162,127,240, 28, 7,106,191, 67, 51, 49, 35,195,199,247,239,132,132,196, - 57, 56, 57,180,213,165,176, 90, 13, 16, 64, 88, 74,180, 87,135, 23,253, 57, 61,141, 9,180, 8,146,145, 17,105, 44,230, 47,191, -170,128,127, 47,183,136,212,231,151, 15,209,199, 85,126,189,255,116,105, 27,159,158, 23,144, 45, 38, 34,184,182, 40, 48,160,123, -237, 39,112,107, 23, 89, 37, 15, 27,243,226, 12, 15,105,113,208,105,103, 31,159,220,100,124,126, 10,237, 88,178,255, 60, 98,152, -237,247, 89, 59, 79,135, 58, 24, 32, 91,183,255,204,181, 11,207, 63, 65,218,201, 38, 42, 82,240,186, 12, 58,140,174, 33, 3,103, -191,252,250,203,215, 84, 93, 66, 84, 8, 89,175,190,138,140, 16,172, 47,115,236,194,109, 44,189, 12,228,233, 3, 72,147, 28, 28, -162,182, 26,114,199,238,131,246,100, 62,252,240,125,243,145,139,190, 54,250,200,106, 39,111, 61, 9,107,236,131,128,129,130, 24, - 59, 19, 3,100,154,247,237,199, 47, 41,158, 40,149,212,241, 75,183,101,197,132,100, 36,160, 7,191, 29, 60,113, 9,201, 9,148, - 54,111,129,109,228,180,217,123, 32,108, 62, 14,214, 60, 23, 77,200,186,120, 98,198,103,128, 94, 56,112,237, 49,124,193, 76,181, -143,110,184,185, 18, 59, 24, 96,234, 5,138,232,203,139,234,200, 8, 93,121, 2,234,192,237,186,250, 44,119,209,145,246, 8, 75, - 49, 1,232,130,173,201, 59, 47,180,111, 60, 3, 87, 15,116,204,104,129, 56, 10, 70, 26,120,249,242,165,190,190,254,171, 55, 95, -158, 62,127, 15,204, 66,204,204,108,175, 63,126,253,248,241, 35, 48,143,252,255,247,239,215,239,223, 31, 63,126,248,252,249, 51, - 48,223,127,255,241, 3,152, 79, 37, 36, 36,126,124,252,248,237,219,247,139,160,147, 9,254,193,198, 18, 16, 99, 50,224,113, 0, -208,208,194,143, 31, 95, 36,164, 20,197,132,121,132,133,184,177, 90, 13, 16, 64,232,189,245,151,135, 22,252, 57, 57,145,225, 31, -100,133, 59,164,120, 3,141,150,254,149,115, 19,139,158, 3, 44,220,129,162,188,226,242,191, 56,164,254,195,198, 68, 32,232,235, -145, 73,127,190, 66,219,212,182, 6,170,167, 58, 18, 61,181,100,224,181, 7, 59, 19,163,151,182,212,177,166, 24, 79,107, 80,153, -248,231,247,175,175,251,251, 24,254,255,133, 89, 0, 41,158,255,115,202, 24, 98,182,157,247,222,122,145,216,179,242,210,205,135, -111,222,190,127,240,248,249,170,221,167,226, 39,109, 2,251, 21,228,198, 72, 91,109,244, 14,163,130,180, 55,172, 58,253,241,239, -127, 80,199,202,243,183, 64,139, 94, 62,127,254,178,124,215, 73,191,238,117,170,217, 83,235, 23,238,120,242,226, 45,162, 98,248, -255,159, 64,169, 10, 14,218,104,103,163,255, 48,197, 9,211,183,205,221,118,226,201,179,151,175,223,188,187,118,251, 81,214,164, -181, 43,193, 75,107, 96, 6,253, 23, 17, 22,136,180, 80,131, 24,124,231,205,151,212, 9,107,222,125, 0, 13,237,125,255,241,115, -237,190, 51,190,157,107,244,139,102,181, 47,219, 3,228,194, 45,248,255,159,129,242,161, 11,160, 11, 39,237, 56, 15,223,104, 26, -111,173,172, 40,198,207,198,198, 70,204,170,115,200,106,200,240,137,208, 73,212, 96, 99,185, 20, 59,117, 72,225,206, 10,222, 27, -133,169, 5, 40, 56, 53, 1,209, 67, 90,125,250,190, 81,205, 26,143,142,141,110,109,235,185, 19,166, 85, 44, 63,134,172, 88, 67, -146,111,116,243,234, 40,160, 22, 0,175,136,127,130, 44, 2,228,226,153,134,197, 4,164,170, 39, 15, 72, 74, 73,253,250,253,247, -197,139, 15,144,116, 15,204,134,108,236,188,215,174,223,184,116,233,226,181,235,215, 95,189,122, 5, 44,180, 5, 4, 4, 21, 20, - 21,245,244,244,116,116,116,128, 69,191,136,136,200,250,205,187,158, 60,127,135,220,108,135,150, 44,160, 85,241,160,124,247,224, -238, 53,126, 65, 81, 96, 13,161,173, 38,197,198,138,125,236, 1, 32,128, 80, 68,191,191,123,241,251,244, 12, 70,212,145, 98,208, - 57, 55,166, 89, 98, 86, 49,200,135,133,177,235, 71,254, 61,209,131, 58,200,244,250,213,186, 98,225,192, 62,118, 30, 80,211, 88, - 89, 86,124, 83, 99,194,155,119, 31, 30, 61,127, 11, 44, 24,164,197, 5,132, 4, 5, 16, 29,150,125, 83, 24, 95,157,249,143,122, - 49,200, 31, 14, 9, 14, 73, 21,228,178, 6,194, 96,101,100, 88,120,236, 38, 16, 97,186, 62,220, 72,222,217, 76, 7,101,244, 29, - 76,205,202, 13,180,175,154,127, 27,178,230,250,254,107,163,138,133,138,188,108,239,190,255,249, 4, 90, 93,196,240,245,247,191, -230,141,167, 36,249, 57, 51, 2,236, 49,122, 11, 56,134,103,192, 64, 75, 65,162,208, 85,191,127,247, 69,160,216,135, 31,127,210, -231,238, 70, 87,139, 90,112,245,166,120, 93,126,244,250, 12,120,244,121,254,145,235,203,142,221,144,228,102,125,251,253,207,103, -160, 51,192,214,117,109, 62,229,160,171, 96,169,171,194,192,192,192, 64,165, 81,233,251,175, 62,182,109, 56, 13, 97,107, 74,242, - 23,184,106, 65, 22,164, 19,211,120,255,240,245, 7,176,225, 15, 89, 48, 99,174, 36,218, 29,102, 10,212, 11,223,143,138,235,144, - 35, 35, 37,137, 73,177,214, 53,107, 78,125, 2, 15,202,125,250,254,235,216,237, 23, 88,205,215,146, 20, 24, 61,159, 96, 20, 80, - 11, 96,158, 28, 0,228, 54, 84,248, 17,127, 86, 12,169,234,201, 3, 76,140, 76,175,223,124,254, 7, 89,120,248,159,225,247,239, - 95, 15,239,223,150,150, 18, 51, 52, 52, 70, 62, 28, 23, 88, 0, 0,123,222,191,255,252, 21, 19,151,254,248,225, 29, 23,183,216, -211,151, 47, 4,133,196, 64,197, 57,120, 44,133,145,137, 9, 88,154,255,249,243,235,215,207, 31, 31, 63,189, 19, 16, 18,227,230, -226, 85, 83, 6,205,115,224,178, 26, 32,128, 80,202,247,191,239, 30, 50,252,251,245, 31,105,133,251, 95, 78, 9,110,231,106, 97, - 77,244, 19, 25, 5,205,130, 95, 94, 88,204,244,253, 37,114,177,198,248,234,252,235,249, 65,188, 78,149,252,218,206, 16,113, 17, - 33, 1, 32, 66,214,248,227,211,251, 55, 59,218,153, 31,237,193, 44, 68, 89,212, 60, 89, 88,177, 12, 61, 79, 12,183,108,217,118, -254, 25, 98,200, 27, 90, 14, 38,152, 41, 77,206, 11, 65, 8,254, 71,108,112,149, 20, 21, 60,209,157, 86, 50,119,235,242, 99, 55, -127,128, 71, 72,238,127,250, 9,113, 37, 27, 35,163,171,150, 84, 85,160,149,149,145, 22,102, 9,142,165,108, 71, 93, 10,212,150, -228, 9, 36,167,236,185,248,251, 63,202,106, 37,113, 46,214,106,111,131,188,213,167,145,117,243,241,114,239,106,138,175, 91,178, -123,222,129,171,223,254,252,253,249,247,255,131, 79,136,198,130,189,146, 72, 71,162,187,169,150, 50,102, 71,129,194,145, 25,248, -105, 48,157, 33, 70,144, 13, 71,196, 52,222,129,122,193,167,149,189,133, 84, 12,211, 99,205,129,101, 58,164, 98, 0,181, 24,254, -253, 67, 41,223,193, 34, 64, 0,153,179,141,179,211,178, 82, 17,239,220,114, 30,216,126, 71, 54, 51,200, 8,116, 56,198,186,115, -208, 21,177,102, 74, 34,163,231, 19,140, 2,208,102, 84,240, 73, 3,144,197, 42,144,165,138, 60, 92,236,152,130, 12,224,243, 97, -128,229, 47,176,149,253,242,245, 39,136, 44, 68, 25,114, 27, 28,162, 29,249, 8, 26,200,225, 1, 18,162,124,144,153, 91, 30, 30, -118, 72, 75,223,205, 81,139,135,155, 29,190,148, 19,222, 15,216, 5,222,230, 13,180, 8,104, 50, 80, 22, 50,233, 10,153,230,133, -203,194,151,222,195,101, 95,192, 14, 99, 0, 74, 65, 38,150,177,250,247,205,155, 55, 12,204,252,144, 82,132,137,153,249,225,195, -123,160,205, 63, 74, 26,255,254, 51,126,255,241,251,251,247,223, 64,167,126,251,254,243,231,239,191, 63,190,253,254,245,251, 15, - 80,150,149,233,139,140, 4,251,155,247,140, 31,222,191, 17, 18, 22, 7,230,182,159,192, 50,253,195,155,111, 95,190,112,112,113, -241,240,242,139,139,203, 0,115,167,144, 0,151,158, 6,190,202, 9, 32,128, 80,206, 7,254,249,249,253,235,153,110, 12,255,255, - 66,138,236, 63,130, 58,162,161, 19,184,248,133,176,234,124,125,112,214,239,211, 51,177,155,170, 21, 41,230,154,207,130,177,220, -226,243,227, 27, 31, 54,149, 48,127,199,178,187,236, 63, 35, 43,127,252, 6, 30, 17, 73, 88, 10,120,123,233, 22,180, 80, 48, 1, -175, 68,108, 89,178,107,231,185,187,215, 62,252, 16,101,103, 54,144, 17,204,243, 54,247,118, 64, 92, 12,114,236,204,149,175,224, - 69,120,146, 98, 66, 58,234, 10,112,241,143,159, 62,175,218,127, 97,243,201,107,111, 62,126,101,103,101, 81,147, 22,206,244, 50, - 55,208, 70,244, 18,222,127,248,116,230,202, 29,152, 69, 42,104,107,140, 46,221,184,255,242,205, 7, 8,219,193, 92, 7,190,128, -228,212,149,187,141, 75,119, 95,120,244,238,203,239,127,178, 60,108,182, 90,210, 13,241, 30,252,188, 60,135,207, 64, 15, 3, 80, - 83,144,146,151, 65, 44,251,121,250,252,213,188, 61,231,143, 94,190,243,225,243, 79,110, 78, 22, 85, 41,145,120, 39, 3, 75, 68, - 5,195,240,250,237,251, 11,215, 31, 64, 42, 18, 75, 67, 13, 30,110,114,206, 89, 3, 70,229,196,237,231,202,151, 29,133,112,115, -157, 53,138, 61,116, 57,193, 0,190,161, 20,143,222,148,153,187,225,115,170,144,115, 40,129,237, 14, 70, 80, 81,204, 4, 61,136, -226,255,255,163,183, 94,192, 21, 8,112,179,235,203,137,118, 69,219, 64,198,109,254,128,218, 21,160, 67, 37, 15,223,124,246, 15, - 60,104,104,161, 44, 10,108,209,219,118,108,131,180,235,165, 5,184, 14, 87,122,114,115,115,115,113,113, 1,187, 80,135,111, 60, -189,244, 16, 52,153, 33, 39,194,231,103,162, 36,192,197, 62, 90,240,141, 16, 0, 44,124, 23,175, 60,190,120,102,114,207,228, 93, - 64,110, 73,174, 91,108,250,220,216,112, 75,172,130,211,231, 29,232,105, 9, 5,150,170,235, 55,159,131,200,114,115,179,103, 38, -217, 67, 74,118,200, 41, 99,192,178,117,221,230,115,153, 73, 14, 64,197,192,246,248,250, 45,231,191,124,253, 1, 20,223,181,239, - 42,196, 4, 96,201, 27,232,107, 4, 52,193,202, 92,197, 10,124,210,128,155,147, 54,216, 37, 87, 75,115,221,129, 10,128,138, 33, -219, 80,103,244,197,100, 20, 45,129, 44,199,132,156, 51, 3, 89,103, 9, 84, 0,180, 2,168,184,123,242, 78,136,172,156,140,208, -230, 29, 23,225,230,224,233, 7,156, 60,121,138,131, 71,252,255, 63,102, 96, 38, 2,150,223,103, 78, 31,211, 55, 48, 17, 23, 23, -254,250,245,199,179,151,159,254, 35, 95,117, 7,107, 89,243,240,114, 11,243,253,126,250,236,229,249,203,143, 88, 88,216,127,253, - 2, 54, 83,255,243, 11, 8,241,242, 9, 49, 51, 49, 3,219, 85,192, 12,205,193,198,106,102,168, 32, 37, 33,128, 39,168, 1, 2, - 8,165,253,206,206, 43,200,233, 88,245,249,240, 52,166,191, 63, 25,229, 44,197, 61, 42, 57,120,113,106, 22, 48, 9,123,113, 97, - 25,211,175, 79,152,227, 18, 12,215,150, 61,191,187,155, 85,209,134, 77, 82,155,131, 87,240,231,215, 79,191,222, 61,253,253,236, - 34,195,171,139, 76,224,254, 1,150,242, 69,217, 3, 94,184,131,107,111, 97, 87, 49,148, 75,167,122,115, 66,122,113,123,195,202, - 4,251,234, 20,126, 62,222, 84,127, 91, 32,194,165, 17, 88,160,187,218, 24,225,146,213,211, 80,196, 42,110,166,163,188,181, 29, -203,245, 29,174, 54,134, 88,213, 75, 75,138,213,198,186, 51, 48,184,227,178, 72, 84, 88,208,213, 70,144,138, 35, 51,210,130, 92, - 73, 54,170,196, 55,222,129,101, 55,188,112, 7, 2,180,125,170,152, 0,174, 0, 88,166,179,179,179, 67, 90,250, 64, 91,128,164, -139,158, 34,124, 17,228,212,253,231, 63,193, 86, 82, 5, 25,129,206,139,135, 56,102,243,217,187,169,179, 16,163, 91,165, 75,216, -103,167,187,248, 25, 43,143,150,125, 35, 1, 0,203,193,233,243,126, 2, 91,226, 23,175, 60, 6,182,142, 33,187,138,112, 9,130, - 26,242,247, 94, 67,142,241, 58,118, 18,116,228,139,155, 35,202,148, 27,100, 23, 43, 72, 22,124,102, 0,228, 60, 25, 96, 89, 15, -217,130, 4, 17, 44,201,117,135, 20,190,151,192,103,132, 1, 11,101, 72, 13, 1, 44,151, 95,188, 6,149, 96,174,142,144, 3,109, - 30, 67,142, 33,131, 28,159, 0, 49, 13,216, 84, 7, 22,250,144,134,252, 49, 36, 89, 96, 77,131,108, 14, 30,255,138,138,138, 92, -188,114, 75, 72, 88,130,139,147,231,194,133, 83,162,226, 18,130,130,252,192,236,242,242,205,103,196, 18,106, 70,164,189, 68,255, - 25,190,124,254,250,255, 31, 43, 47, 23,187,187,179,249,133,235,207,129,237, 95, 38, 38, 22,200,250,119, 1,126, 14, 73, 49,126, -113, 81, 62,208,237,104,132, 22, 44, 0, 4, 16,250,168,188,176,113, 32, 16, 17, 19, 73,172,220,192,162,177,254,243,214, 98,228, -193,107,120, 57,207,244,227,245,223,235,235,191, 3, 17,246,161,105,148, 65,143,191,220,178,146, 30,165,163,233, 30, 94,212,146, - 49,124,129, 62, 50, 19,108, 36,204,199,133,124, 20, 12, 65, 75,201,115, 42,100, 63, 42,164,212,134,108,161,130,239, 96,186,240, -224, 85,207,118,232,169,100,124, 28,172, 73,182,106,240,227, 45,237, 53,165,107,131,204,237, 52, 65, 39,166, 77,222,113,113,211, -217,187, 37, 75, 14,143,150,239, 35, 4, 64,214, 29,238,218,127, 13,114,240,192,186, 45,231, 33, 34, 88, 5,129,220,151,175, 65, -133,126,108, 4,232, 36, 47,208, 81,236,185, 50, 88,205,132, 12,236, 64,134,110, 32, 5, 49, 3,120,113, 58,218,241,191,192, 98, - 26,237, 44, 4, 32,128, 28,101, 35, 33,198, 15, 89,210, 14, 63,129, 0,178,250, 30,186,110, 18,188, 75, 22, 46,139,213, 28,172, - 64, 86, 86,246,215, 95,142,107, 87,111,188,250,247,252,231,207, 31, 10,242, 74,162,194, 60, 87,111, 62, 7, 31, 54,128,122,224, -236,127,232, 58, 25, 38, 38,198,103,207, 94, 8,242,115,152,154, 42,254,250,195,114,247,193, 43, 46,110, 54, 89, 73, 33, 89, 41, - 65, 33, 1,110, 38, 38, 98,203, 7,128, 0,162,104,159, 36,191,150,227,143,183, 5,191,143, 79,192, 82,102,227, 40,202, 49,193, - 95, 14, 49,225,160,137,172,156, 60,163,233,254,204,189,151,247, 94,126, 8, 49, 87,101, 32,241,102,106,200,154, 25,248, 89,240, - 9, 86,202,214,106, 18,240,121, 81, 34,141,250, 56, 39,237,199,143, 31,192,246, 56,124,156, 29, 77, 35,176, 28, 87, 44, 91, 3, - 97, 47, 76,180, 4, 90, 1, 52, 31,121, 48, 29,114, 18, 14,196, 61,239,191,124,143,158,134,104,161,231, 56,171, 11,241,114,194, -167,121,229, 69,249,106,130,204, 63,124,251,121,233,225,235, 92, 15,125, 96,249,254,240,245, 39, 32, 2,138,143, 38,131,145,209, -132,151,133,140,168, 48,128,142,138, 60,110, 5, 62, 71, 12,171, 32,176,188,158, 62,239, 0,176,165,108,109, 6, 58,143, 12, 82, -232, 67, 6,220, 81,134, 82,193,103, 6, 64, 6,247,129, 36,252,192, 94, 96,147, 31,179, 38,128, 31,102,192, 0, 59, 29,161, 36, -215,141,135,155, 29,249,218, 16,200, 64,191, 4,244, 0,203, 39, 64,211,224, 86, 64, 0,228,160, 2,184, 57,248,154,194,172,172, - 98, 34,252,127, 53,181,128, 5,186,128,160,200,239, 95, 95,159,191, 98,251,246,253, 23,142,188, 12,218, 86,249,250,245,139,159, - 63,191, 11, 8,136, 92,187,245, 66, 79, 75, 90, 77, 73,140,155, 11,216, 17, 39,249,100,111,128, 0,162,116, 31,188,184,109,220, - 59, 46,190, 47,251,218, 24,255,255, 38, 67,251, 95, 81, 19, 17,207, 42, 30, 9,197, 97,214, 0,199, 47, 8, 44,224, 48,213, 0, - 69,238, 60,127,127,239,213, 71,200,254, 32,200, 34, 19,136, 50, 72, 1,138,118,171, 53,114,225,139, 54, 50,147, 15, 94, 51,131, -171,112, 71, 62, 33, 0,126, 34, 13,208, 70, 96,203,154, 3,216,223, 99,101, 5,150,227,184,186, 8,112, 54, 19, 51, 19,252, 40, - 96,160, 70,204,139,182, 83,103,239,125,244, 6,186,167, 78, 83,146, 47,217, 86, 13,222,153, 0, 42,190,248,240, 53,176,193,126, -232, 58,202,226,182,135,111, 70,203,247,145, 2, 32,173,108,200, 24, 8,228,192, 94, 92,130,144, 98, 90, 95, 91, 6, 82,178, 67, - 78, 41, 88,188,226,132, 30,120, 46, 20,200,206, 40, 90,194, 0, 62,135, 32, 51,201,126,215,190,171, 64, 53,192,150, 62,100, 92, -254,238,253, 87,200,103,147, 65,128,155,147, 86, 67,251, 38, 96, 85, 1, 41,151, 33,102,102, 22, 45, 1,146,144, 94, 2, 68,217, -209, 83,119, 33,247,123, 0,171,150,158,201, 59, 33,253,131,216, 8, 11,248, 80,140,171,163, 22, 80, 28,110, 14,126, 32, 36,200, -205,207,199,249,225,227,119, 65,126,174,123,247,110,191,123,250,151,153,153, 21,114, 85, 19,228, 48, 25,208,242, 71, 38,208,170, - 69, 96, 86,252,248,225,237,159, 95,191,100,101,149,255,255,255, 39, 45,201,207,206,198,194,206, 70,102, 65, 13, 16, 64,140, 84, -217, 44,254,229,201,181,247, 59,154,254,191,189, 73, 66, 33,200, 46,200,101, 91, 36,106,236, 51,252, 70, 87,210,103,239,113,210, -150, 13, 49, 87, 89,115,242,206,222,171,143,167, 37, 58,172, 61,117,103,246,190,171,130,220,236, 41,142, 90, 64, 41,175,206, 77, - 10,162,188,247, 95,127,154,154,232,176,238,212,221,189, 87,159, 40,137,241, 1,217,158,157, 27, 13,229, 69,155, 67, 65, 11, 87, -122,182,158,223,119,229,177,162, 24, 95, 75,152,165, 16, 15,135,103,199, 70, 32, 27, 88,250, 7,155,169,164, 58,233, 64, 6, 67, - 32,165, 42,176,216,117,107, 91, 7,111,188, 79,139, 54,243, 54, 84,224,226,226,130,236, 56,197, 44,121, 75,151, 28,158,178,235, - 34, 63, 23, 91, 91,152, 69,172,173, 38,252, 94, 86,200, 34, 25, 60,233,225,207,159, 63,252, 41,179, 32,236,165,169,182, 78,186, -242,156,156,156,104, 77,120, 6,140,169, 90, 62, 14,214, 37,169, 54,134,138,226, 16, 39, 1,189,246,241,251, 47,245,130, 5,192, -198, 59,176, 52,143,179,213, 4, 50, 38,239,184, 0, 84,185,187, 58,200, 78, 83,102,180,236, 27, 9, 0,249,210, 59,200,138, 20, -120,243, 25, 77, 16,153, 13,105,182,195,219,239,220, 64,145,251,175,121,120,216, 33,199, 12, 64, 22,198,192, 15, 72,120,241,234, - 19,228,184, 2,100, 65,248, 18, 29,200,193, 3,160,147, 9, 96, 38, 3, 13,129, 44,152,129,168, 7, 86, 24,240,133, 58, 16, 89, - 52, 43, 32,109,252, 23,224,238, 2,176, 58,233,105, 9, 69, 94,213,131, 7,188,125,255,117,253,166,125,252,252,194,188,252, 2, -136, 49,119,208,176, 59,104,180,243,253,219, 55, 63,127,254,144,146,150,103,102,102,210, 84,149,144,149,166,104, 90, 14, 32,128, - 24,169,117, 24,200,159,223,191,223,238,155,246,243,210, 82,134,127,132, 27,242,127, 37,172,197,124,235,184,133,196,134, 95,194, - 5,134,231,204,221, 23,187, 54,159,189,210, 25,169, 83,190,188,200,203, 64, 81,148, 47,102,218,238,137,177, 54, 15, 94,127,234, -223,113,233, 82,123,152, 92,254,226, 4, 59,141, 36, 59,141, 15,223, 64,151,163,110, 42, 2,237,251,117,210,150,201, 91,116,248, -254,171, 79,155,138,189, 38,236,184, 52,239,224,245, 73,113,182,235, 78,223,125,240,230,243,150, 18, 31,238,164,153,133, 30,250, - 10, 34, 60,249, 75,142, 30,174, 11, 50, 83,145,132,156,196,139,182,102, 70, 67,130,175,198, 71, 15, 62,173, 10, 90,253,130, 52, -241, 1, 44,211,183,156,127,128,188,161,116,125,129,187,147,142, 60,174,189, 75,152,229, 59,119,194, 52, 8,123, 89,186,157,179, - 46,168, 22, 1,234, 69, 43,220, 39,110, 59, 87,190,252, 40, 92,164, 35,216, 48,210, 82, 21, 88, 19, 64, 58, 7,192,202, 0, 88, -154,151, 44, 57, 4, 44,220, 79,181, 70, 66,150,205,176,199, 76, 26, 45,223, 71,193,208, 2,192,130, 30,216,201,144, 16,227, 7, -246, 18,172,204, 85, 32, 19,173, 68, 22, 17,192, 92,125,224,208, 73, 96,131,138, 9,116, 13, 19, 19,184, 16,254,247,251,247,175, -159, 63,126,138,136,136,137,136, 74, 2, 91, 90,154,106, 18,242, 50, 66, 20,174, 36, 6, 8, 32, 22,106,249,150,133,149, 85,220, - 61,255,135,101,220,143,123, 71,191,221, 62,240,227,233,101,230,159, 47, 81,124,197,196,241,151, 71,134, 83,222,140, 75,221,133, - 87, 94,143,153,133,101,184, 70,124,178,163,118,229,202, 99, 61, 91,206,189,255,250, 51,214, 74,101,226,206,203, 64,193,121, 7, - 65, 75, 39,129,109,213, 51,119, 65,193,226,103, 32,167, 39, 43, 4, 44,236, 10, 61,245,129,197,122,130,157,186,189,134,164,188, - 8, 15,100,124, 6,216,234, 7,138,216,169, 75, 0,139,212,192,137, 59,127,255, 6, 85,153,118,234,226,118,234,146,192,242,253, -237,167,111, 64,113,160, 94,200,245,120,240,145, 25, 32,184,241,226, 83,204,156, 35,184, 28,102,173, 42,129, 86,153, 31,186,254, -212, 86, 93,138, 90,107,210,129,238, 41, 94,124, 16,249,166, 39, 96,225, 30,110,174, 12,217, 1, 11, 95,198,243, 17,124,184, 32, -176,100,135, 20,238, 15, 95,127, 26, 45, 44, 70,193,144, 3,192,126, 6,100,170, 0,126,168, 25,177,109,106, 70, 70, 21, 69,209, -159,191,140, 31, 63,123,251, 23,233,170, 12, 38,208, 40, 41,168,197, 6,204, 37,106, 42, 18, 10,178,194,148, 59, 18, 32,128,168, - 92,200,114,240, 9,114, 24,248, 8, 24,128, 70, 93,190,125,250,240,251,243,123,134, 63, 63, 24,152, 89, 25, 88,216,216,249,132, - 57,184,184, 71, 66,196, 3,227,175,216,203,160,118,245,201,186, 0, 99, 96, 97, 13,108, 53, 11,112,177,245, 70, 88,240,114,176, -124,250,254, 91, 65, 20,116, 65, 54,228,196, 32,160,202, 36,123,205, 56,107, 85,195,154, 53,250,178, 66,208, 43,100,255,255, 87, - 16,225, 61,255,224, 13,176, 14, 63,255,240, 13,144, 13,153,240,252, 7,187, 18,235, 63,248,238, 83,160, 44, 48, 57, 32,175,153, - 33,220,109,250,247, 87, 22,245,156, 10, 41,126, 14,106, 29,232, 8, 52, 36,180,127,203,102,164, 59, 90, 33,133, 59,176,217,142, - 92,184,131, 42, 42,240,178,153,139, 15, 95,167,206,218, 45, 47,194,183,232,240,117,136,248,131,215,159,237, 52, 71,203,141, 81, - 48,148,138,120,178,245,170, 43,139, 51, 51, 49, 62,126,241,158,225, 31, 98,136, 6,216,206,226,226, 96,147,147, 22,194,179, 37, -149, 36, 0, 16, 64, 52,108, 68,115,241, 9, 48,240, 9,140,180, 40,135,204, 85,166, 56,234,204, 61,112, 45,209, 78, 3,216, 52, - 78,118,208,122,240,230,179, 73, 3,232, 22,164,250, 64,227, 2,119, 61, 32,131, 25,180,146,144,249,209,187,175,182,205,235, 63, -124,253,233,160, 41,165, 47, 39,114,241, 49,232,184, 9,160,246,166, 16,179,184, 25,123, 5, 51,230, 3, 11,247,249,105,142,144, -150, 53,100,245, 33,216, 10,104, 65,121,224,218, 99,248,176, 59,113,101, 48, 67,173,175,193,213,167, 31,174, 61, 3,109,218, 10, - 50,146, 11, 51, 83, 34,175,217,206, 12, 59, 33, 18, 25, 84,250,155, 0, 59, 4, 31,191,255,210,146,226,135,156, 58, 9,105,185, -163,205,244,218,105,202,228,122, 24, 76,222,113, 97,209, 33, 80,201,174, 47, 47,106,111,167, 9,100, 79,217,121, 33,110,180,128, - 31, 5, 35, 3, 0, 27, 60, 26,170, 18, 64, 68, 83, 91, 0, 2,136,113,244, 48,110,170, 3,200,170,240, 63,127,254,192, 79,202, - 5,138,252,254,253, 27,216, 82, 70,190,225, 8, 50, 42, 2, 57, 20, 20,210, 66,135, 47,155,129,207,118, 66,180, 96, 30,216, 2, -212, 11, 57,173, 23,168,247,231,207,159,191,126,253, 2, 50, 8, 23,202, 96, 0, 52,234,200,205,231, 60,236, 44,218,210, 2,104, -215, 97, 19,104,254,255,253, 11,244,197,247,239,223, 33,254,130,107,132, 47,239, 1,138,159,185,243,236,205,199,175,102,138,194, - 64, 65,248, 93,172, 88,151,241,128, 22, 68,190,249,196,207,197, 14, 44,223,193, 35, 69, 79,128,109,249,209,245, 51,163, 96, 20, - 80, 17, 0, 4,208,104,249, 78, 19, 0, 41,154, 33, 59,149,208,150,166,192, 11,107,172, 82,152,226,200, 37, 62,242, 74,115, 72, -243,249, 47, 12,224, 90,212,136,220,177,128,235,130,219, 8,217, 80, 74,228, 26,121,120,189, 5,169,117, 48, 47, 12,129,184, 4, - 88, 7,128,199, 16,153,224, 10, 70, 79,155, 25, 5,163, 96, 64, 0, 64, 0,141,150,239, 52,108,197,163,113,177, 46, 96,199, 37, -142, 44,133,245,224,117,100, 53, 68, 70, 34,178, 46,228,122,130,248,242, 23, 82,235, 32, 87, 24,104,139,103,224, 10,144,171,147, - 81, 48, 10, 70,193,128, 0,128, 0, 26, 45,223, 71,193, 40, 24, 5,163, 96,120, 2,128, 0, 26,109, 94,141,130, 81, 48, 10, 70, -193,240, 4, 0, 1, 52, 90,190,143,130, 81, 48, 10, 70,193,240, 4, 0, 1, 52, 90,190,143,130, 81, 48, 10, 70,193,240, 4, 0, - 1, 52, 90,190,143,130, 81, 48, 10, 70,193,240, 4, 0, 1, 88,187,186,220,168,129, 24,108,143,103, 9,213, 2,106,133,212,138, - 71,144,122,135, 62,115,128, 94,184, 18, 47, 28,163, 7, 0,196, 3, 85,219,221,109,230,207,248, 39, 19,178, 93, 81, 85,208,149, -118,146,108, 38, 30,219,177,163,149,242,217, 31, 30, 65,220, 65,145,241,197, 36,246,134, 39,214,167, 30, 35, 58,119,224,116,102, -160, 85, 46, 69, 91,213, 51, 58,200, 34, 76, 99, 8,145,172, 66, 55,200,168,184, 58, 36,227, 14, 10,104, 40, 15,230, 98, 28,124, - 92,149,188,180, 25, 63,236,196,123,226,205,121, 20, 6,194, 20,128, 85, 8,160, 8, 32,221,129,128, 17, 8,168, 49, 98, 36,149, -165,136, 61, 50, 78, 62,153,160,179, 64, 54,170, 15, 30,116, 85,110, 85,230,213,211,119,167,155,116,127,183,221,184,101,222, 44, -162, 91, 75,184,111, 53, 67,251,120,246,233,250,219,181, 40, 93,148, 80,177, 52,209, 89, 36,121,209, 41,116,176,139, 28,162, 19, -118,169,129,221, 6,101, 69,143, 49,124, 56,167,187,109,218,140,188, 73,109,151,107,170, 45, 23,181, 87, 76, 36,230,147,245,219, -203,207, 23, 95,174,190,238, 26,140,169,222, 62,236, 30, 98,205,204, 57,226,155,245, 16,197, 94,241, 56,139,102, 20,181, 18,138, -229,218, 82, 43, 23, 22, 51,197,112,241,140, 56, 66,157,107,236, 76, 0,180,205, 41,165, 54,254,252, 37,247,164,100, 3, 91,234, -151,101, 48, 92,102, 51, 58, 94,167,153, 89,190,142,255,179,207, 11,250,219, 71,239,235, 7, 26, 26,151,220,234,211, 97, 35,107, - 28,209,235,204,185,246,153,252,220,120,155,117,128,227,225,248,102,188, 57, 4, 3,253, 27,132, 64,107,208, 32,164,150, 95,209, -234,100,253,254,199,237,247,176, 88,180,175,130,216,205,239, 49,192,139,130, 68,168,207,208, 31,247,108,193, 71,251, 78,252, 32, - 33,252, 52, 71, 48,204,249,176, 47, 30,193,195,154, 15,156,134,243, 98,142,130, 10,150,176,136,222,132, 28, 15,111,208,242,255, -160,101,165, 95,104, 28, 95,115, 46, 3, 91,253, 29,226, 18,239,235, 27,159, 51, 37, 53, 25,122, 86,134,168,165, 28,180,210, 49, -174, 26,131, 28,228,146,139, 2,113,115,146,112, 44,121, 76,185,180, 84,107,209, 98,145,166,233,111, 41, 53,251, 91,212,226,133, -106,254, 99,141, 52,140,117,180,123,227, 73,215,244, 25,224,209, 60,185,171,245, 60, 70, 61,235, 79, 41,110, 54, 97,122,190,116, -218,207, 41,212,101,109,252, 75,156,255,207,135,247,163, 20, 95, 78,248,111, 1, 88, 59,183,165, 6, 97, 32, 12,103, 19, 40,142, - 85, 59,125, 1,223,255,201,156, 81,199,241,194,169,165, 57,173,255, 46, 9,165,165,104,103, 44, 23, 20, 8,228,176,252,251,237, - 94,208,132,254, 67,118,158,244,106, 52, 54,169,161,201,212, 87, 90,225, 46,164,208, 82, 71, 85, 1, 21,238, 70,177,174, 43, 68, - 0,180, 78,254, 15, 35,224, 5,136,149,248,196, 40, 12, 33,128,214, 49, 10,123,240,138,114,138,168, 15,106, 64, 41,101,149, 24, -240,103,132, 90,104, 4, 92, 19,150, 77,248,222, 74,219,109,171,218,213,235, 82,239,128, 56, 13, 6, 40,112,134,100, 10, 0, 42, -243,247,142, 8, 75, 89,158,197,175,220,159, 47, 89, 94,230,245,164, 34,147,200, 9,138,245, 33,160, 34,232, 49, 11, 34,129, 86, -116, 58,113,145,197,233,138,174, 52,217, 59,141, 81,206,108,159,233,245,179,223,121,246, 57, 31, 32,245,204,192,119, 14, 24, 39, -120, 33,211, 18,108,182,143, 47,239, 31,232, 49,117,246,190,115,155,117,183, 93,183, 79, 15,238,174, 67,136, 48, 62,144,239,109, - 47,164, 22, 27, 55, 78, 2, 85, 74, 1, 3, 96,244, 39, 75, 68,129,138,123,184, 80, 26, 62,129,167,125,244,253,219, 87,191,247, - 81, 98, 73, 98,229,187,126, 37,207, 53,164,161,105, 24, 55,209, 49,184, 93,224,251, 25,209,120, 70,225, 63, 41, 79, 87,115,153, -150, 33, 78,183,224,251,220,211, 70,132,184,227, 98, 59,180, 60, 16, 30, 13,194, 11, 70, 56,133, 59, 45,242,215, 56,186, 98, 16, - 73,252,107,122, 27, 78, 27,186, 64,246, 66,195,234,177,240,144, 97, 13, 98,171,103,120,173,206, 46,187,188, 53, 21,234, 18, 13, -108,113, 97,245, 31,146,116,199,142,185, 91,161, 1, 29, 9,160,233, 21, 6,211, 32,123,115,173, 96, 29, 76,215,109,133, 3,215, -172, 4,252,221,202, 31,246, 1, 46,148,162, 7,219, 65,247,228,133,248,184, 0, 93, 66,156,146, 45, 77, 71, 90,114,179, 26,101, -101, 39,115,121,112, 42,249, 20, 13,124,231,225, 56,107,114, 56,170, 23,222,218, 82,187, 59,124,147,248,132,218, 65, 23, 85,170, -126,122,142,248, 95, 82,153, 37,137,218, 89,152,156,107,146,111,148,148,156,109, 63, 2,208,118,118,187,109,195, 48, 20,150,104, -217, 10,150,166,104, 46,138,162,215,125,255, 39, 91,209, 98, 75,139,194,113, 36,245, 28, 82,114,188, 37, 46, 54, 12, 3,114, 97, - 4,209,143, 77,242,240,147, 17,137,255,138,237, 48,213, 38,196,247,233,253,138,184,183,147,141,169,177, 86,254,219,190,161, 41, -248,105,155, 53,121,152,120,160, 91,152,184, 67,216,131,116,161,135, 7, 12,116, 6, 2, 61,127,210, 65,211,233, 68, 46,107, 22, - 13, 32,249, 78, 83, 70,177,108,235,234,127,173, 69,150,186,178, 68,174,236, 92, 67,116,185, 8, 98, 41,146,203,195,221,227,243, -207,239,169, 18,152,113,186,173, 32,114, 18, 58, 62,188,213, 36,158, 91,120,172, 23, 46, 25,154,241, 50,159, 0, 38,230,170,115, - 35,117, 80, 91,157,222,179,241,175, 78,246, 76,251, 53,196, 43,191,179, 12, 23,197, 99,242,161,184,219,161, 76,222,189, 8,251, -193,232, 57,133, 97, 40,183, 60, 99, 23, 13, 79,247, 79,123, 60, 52,100,142, 62,186,221,183,208, 15, 93, 12,204, 93,232,127,139, - 73,238, 48,175, 30, 61,142,163,127,251, 40,167, 99,250, 24, 5,243, 2,165,116, 89, 7,241, 18,153, 53, 83, 62,129,153,221,136, -124, 20, 52,229, 9,159,177,230,178, 68,170, 57, 43,130, 21,150,241,229,186,227,249,185, 18,185, 95,240,200,126,179, 63,140, 7, -172, 29,190,246,162, 40,155, 41,143, 51, 28, 93,101,243,175,197,125, 54,233,174,191, 57,168, 55,194, 58, 39,205, 70,127,245,178, - 18,242,146,126,101,110,191, 62, 98, 91,152,174,189,247, 52, 6,228,245, 93,220,191,142,175,229, 15,196,221, 47, 70, 91, 19,247, - 53,190,163,225,106,171,172,225,208,249,235,216, 62,111,147,211, 21,118,211,251,102, 89,185,144,152, 26, 69, 85,167, 69,183,175, -217,198, 59,213,121,177,202, 46,174,210,156,208,143,237,142,164, 38,185,138,240,206, 86,231,122,208, 6,120, 46,244,208,214,126, - 24,250, 13,183, 57,199,136,107,120,240,118,123,115,120,251, 49, 5, 8,251,145,237,178, 41, 46, 17,137,157, 5, 22,117,247, 37, - 47,151, 40,179,192,115,238,234, 70,136,101, 68,101, 98,176,229, 6,239, 21,203, 41, 73,224,253,108, 83,203,220, 61,142,240,210, -111, 98,136,104,125, 76, 71, 87,170,168,144,132,172,246,176,182,107,125,148,115,118, 92, 87,118,185, 0,243,223,220,169,252, 31, -102, 95,142,242, 41, 0,105, 87,215,219, 32, 12, 3, 99,135, 16,232,180, 73,235,255,255,131,211, 94,214,170, 27,133, 66,178,179, - 29, 88, 87, 86, 52,109,111,124, 4, 2,137,115,190, 59, 41,201,127,241, 29, 67,247,253, 50,206,189, 95,246, 97, 46,253,106,216, - 46,191, 41,211, 92, 74,127,147,102, 91, 93, 67,197,168, 61,240,132,115, 49,102, 42,157, 64, 47,232, 46,235, 81, 1,111, 2, 94, - 20, 67,131,231,198, 52, 14, 93, 7,212, 83, 26, 60,130,133,226,173,160,152,162,204, 40, 89, 46,201,234,176,240, 29, 74,165, 0, -159,215,119,243, 12,183,232,200, 67,119,156,100,237, 47,195,226,180, 76, 24, 77,150,185,146,246,179,149,102,183,139,187,243,216, - 41,203,157,117, 52,235,202, 97,242,152,174,221,175,145,144,253, 44,157, 53,232, 69, 32,178,237,169, 75,197,221, 33, 75, 98,230, - 22,225,199,166,215,254,227,101, 28, 78, 41,131,225, 52,109,243,212, 4,164,137, 64,244,208,186, 32, 30, 11,141, 98,247, 36,105, - 41, 79,117,237,235, 40,252,105, 2, 49, 23,181, 32,190,140, 84,147, 24,100, 28,167, 53,209, 5,199, 67, 62, 15,147,215,252, 55, - 73,141,162, 22,106,246,146,159, 64,117, 80,186,142, 57,247,162, 81, 22, 69,205,137,149,243,144,126,177, 54, 32, 90,120,226, 66, - 67,190, 98,178,252,220, 85,136,218,209,225,252,182, 70,237,200,113,144,109,120,175, 54,118, 79,231,141, 40,199,149,157,111,187, -169, 91,242,199, 90, 25, 44, 85, 28, 47,167, 27, 46,188,126, 97,244,205, 48,245,235, 68,149,140, 4,255,150,212, 91,194,219, 98, -241, 52,251, 90, 0,247,245,103,111,128,251, 92,152,188,227,181,216,219,200,124,222,184,105, 33,224,247, 61,153, 98,194, 20, 33, - 98,206,140, 86,156,221,204,147, 10, 85,191, 98,161,166, 82, 73,124, 62, 42,186, 92,149,184,138,108,219,135,157, 52,165,176, 13, - 5, 87, 80,126,153,131,237,213,139, 20,239,181,226, 32,190,140,175, 67, 21,154, 10,216,222,196,166, 13,177,133,222,125,222,239, -251,190, 7,189,119, 22,197,184,132,240, 68,196, 87,178,106,170, 56,190,164, 70,139, 32,180,168,119,167,102,175,129,124,105, 2, -113, 86, 83, 6,128, 92, 0, 20,148,116,202, 29,207,126,139,124, 15, 46,145,179, 41,225,156, 13,199,125, 2,156,136, 99,147,165, -164,221,211, 1,204,133,144,217, 78,169,217,125,135,120, 27, 11,249, 39,100,207,247, 53,208, 99,124, 4,239,161, 77, 91,230,111, -136,127, 19,136,159, 2,144,118,109, 59,106,195, 80,208,231,216,216,161, 41, 44,171,221,125,104, 87,253,157, 85,255,255, 1, 9, -245, 15, 42, 30,118,165, 0, 1,199,113,207,197,129,208, 80,161,182, 8,129,100, 7, 80,236, 57,227,153,177, 18,104, 20,241,127, - 86,137,194,209,131, 46,214, 5,210, 26,205, 61, 48,248, 57,153, 46, 98, 15, 57, 0,135, 60,196,104,175,192, 66, 98,114,177,109, +137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, + 72, 68, 82, 0, 0, 1,245, 0, 0, 1, 26, 8, 2, 0, 0, 0,135, 56, 89, 17, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, + 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 4,103, 65, 77, 65, 0, 0,174,211,164,123,114, 68, 0, 0, 0, 32, 99, 72, 82, + 77, 0, 0,110, 39, 0, 0,115,175, 0, 0,246,112, 0, 0,129,232, 0, 0,107,215, 0, 0,226,170, 0, 0, 48,131, 0, 0, 21, + 42,251,118,133,113, 0, 3, 1,163, 73, 68, 65, 84,120,218, 98,252,255,255, 63,195, 40, 24, 5,163, 96, 20,140,130, 97, 7, 0, + 2,136,133,138,102,253,249,249,253,223,203,235,127, 63, 63, 99,150, 50,102, 19,148, 28, 13,220, 81, 48, 10, 70,193, 40, 24, 64, + 0, 16, 64,140,212,106,191,255,249,241,237,247,230,124,150,143, 55,128,236,255, 12,204,127, 52, 35,217,204, 18, 89, 88,217, 70, +131,120, 20,140,130, 81, 48, 10, 6, 4, 0, 4, 16, 19,181, 12,250,255,242, 26,164,112, 7, 85, 26, 12,127, 89,174, 45,249,190, +171,121, 52,124, 71,193, 40, 24, 5,163, 96,160, 0, 64, 0, 81,173,124,255, 39,168,248,155,153, 7,216, 25, 0, 35, 16,193,246, +116,255,151,205,165,127,190,127, 30, 13,229, 81, 48, 10, 70,193, 40,160, 63, 0, 8, 32, 70, 42,206,175,254,120,126,243,239,193, + 54,150, 79,119, 17,141,122, 6,134,191,156,162, 76,206,237,156, 82, 26,163, 97, 61, 10, 70,193, 40, 24, 5,244, 4, 0, 1,196, + 72,245,245, 51,159,143,205, 99,189, 50,159,225,255, 63, 68,211,158,145,229,183,106, 16,183, 69, 50, 11, 39,207,104,136,143,130, + 81, 48, 10, 70, 1,125, 0, 64, 0, 49,210, 98,125,228,143, 59,135,255,238,111, 96,250,247, 3,218,134, 7,227, 63,156, 18, 44, +110,237,156,146,234,163,129, 62, 10, 70,193, 40, 24, 5,116, 0, 0, 1,196, 72,163,245,239,223, 95,221,251,191,187,138,225,243, + 35,132,208,127,134,191, 76,236, 76, 86, 37,220,186,222,163,225, 62, 10, 70,193, 40, 24, 5,180, 6, 0, 1, 68, 84,249,254,237, +195,235, 63,119, 14,253,120,126,249,255,159, 95,196, 27,205,252,235, 51,215,251,179,176, 38, 60,130,248, 99, 90,194,111, 18, 60, + 26,244,163, 96, 20,140,130, 81, 0, 7,255,254,253,251,254,253,251, 71, 48, 0, 50, 88, 88, 88,254,252,249,195,205,205, 45, 36, + 36,244,245,235, 87, 70, 70,198, 31, 63,126,124,251,246, 13, 82, 98, 75, 72, 72, 8, 11, 11,179,179,179,227, 55, 19, 32,128, 8, +151,239, 31, 46,237, 96, 58,209,195,252,247, 27, 68, 61,156, 96, 64,110,153, 99, 99,162, 9, 33,217,243,255,175, 94, 18,191, 77, +218,104,140,142,130, 81, 48, 10, 70, 1, 16, 0,203,244,135, 15, 31,242,241,241,241,242,242,242,240,240,176,177,177, 1, 11,244, +143, 31, 63, 29, 63,126, 76, 89, 89, 89, 76, 76,140,131,131,131,133,133, 21, 40,200,196,196,248,239,223,255, 47, 95,190, 60,124, +248, 0, 88,244, 75, 73, 73, 1, 5,113, 25, 11, 16, 64, 4,202,247, 95, 63,127,124, 91,224,203,242,247, 43, 3, 35,169, 14,254, +143, 89,214,255, 71,106,201,255,145, 48,231,245,106, 97,225,228, 29,141, 90,234, 2,120,132,226,137,245,145,224,134, 81, 48, 10, +134, 74,179,253,237,219,183, 79,158, 60, 49, 48, 48, 0,230, 23, 96,217,253,251,207,223,175,223,126,222,185,255,114,223,190,189, + 26,106, 10,110, 46,118,236,108,172, 64,193,191,255,254,255,252,249,231,219,143, 95, 63,126,254,225,229, 98, 23, 18,228,190,127, +239,174,176,176, 16,176, 33,143,203,112,128, 0, 98, 33, 42,183, 34, 10,107,244,236,202,136,209,110,255,143,213, 0,140,246, 60, +243,243, 19,159,151,199, 50, 59,212,240, 41,153,140,198, 49,229,229, 41, 16,124,248,250,227,194,131,215,144,178, 85, 79, 78, 88, +128,155,131, 9, 88,215,195, 0, 29,138,111,136, 51, 46, 60,120,245,225,235, 79, 32,131,166,110, 24, 5,163, 96, 24,128, 63,127, +254, 60,120,240,128,149,149, 85, 87, 87, 23,152, 65,158,191,250,120,227,206,139, 7,143,223, 60,124,244,252,209,131, 91, 92, 60, + 2,191,152,127, 10, 8, 63,248,249,235,239,171,183,159,190,125,255,245,251,247,223, 63,192, 98,254,255,127, 54, 86, 22, 89, 25, + 17, 1,142,239,114,114,114,120,204, 7, 8, 32,194,227, 51,223, 30, 95,250,115,105,197,175,175, 31,153, 88, 89,177, 20,240,159, +158,177,124,125,140,117,180,230, 55,155,240,127, 1, 57, 14,126,201,127,191, 62,253,120,243,148,237,219, 35,198,255,127,224,101, + 61,220,214,127,186, 73,130,246,233,104,166, 94,186,241, 96,235,249,187, 14,186,138,198,106,178,108,108,172, 67, 40,182,110, 61, +120,190,243,226,125, 75, 85,105, 11, 61,101,186,213,255,139, 14, 93,155,186,235,226,165, 71,111,145,197,229,132,121, 34,173,212, +178, 93,245,132,120, 57,153,153,153,169, 82,194, 66,138,239,210,165, 71, 58, 35,173,244,229, 69,153,192, 0, 34, 14,172, 93, 74, +150, 28,222,124,238,222,199,111,191,144,221,144,238,172,147,235,174, 15,116, 0, 92,241, 40, 24, 5,163, 0,152,101,222,189,123, +247,250,245,107,110,110,110, 89, 89, 89, 96,153,125,226,236,189,157, 7, 46,189,127,243,250,243,231,215, 92,220,252, 95, 62,127, +144, 85,212,178, 50, 86, 97, 98,102,190,126,251, 57,166, 9,192,220,244,246,213, 51, 39, 71, 43, 27, 19, 5, 22, 22,236, 57, 11, + 32,128, 40, 90, 63,243,238,236, 70,166, 83,253, 76,255,126, 34, 23,237,255, 25,152,126, 75,219,115, 24,132,115,202,232, 48,179, + 32,250, 7,127,190,127,249,126,125,231,239,115, 11,152,127,188,130,171,133,216,253, 95, 59, 86,208, 41, 23,217,228,221, 71, 47, +120, 78,218, 1, 84, 35,192,198,116,170, 45, 86, 73,142,192,105,101,249,147, 86,223,253, 8,114,134,151,158, 98,150,191,245,128, + 68,216,179, 23,175,108,107,150, 62,253,250, 27, 88, 7,206,138,177,143,243, 50,167,138,177,223,190,255,216,126,241, 1,144, 33, +203,207, 97,166,169,112,238,230, 35, 35,117, 68,141,253,254,203,119,183,182,245,151, 30,189,193,165,157,143,147,109, 83,145,151, +145,146, 56, 11, 48, 9,128,155,210,148, 56,230,222,203, 15, 22,181, 43,128, 37,248,166, 34, 79,123, 45, 89,160,153,192,130, 27, + 40, 14, 44,244,221,219,215, 35,151,236,200, 64, 71, 70,104,115,177,183, 8, 63, 55,196, 13,163,121,123, 20,140,240,146,253, 45, + 24,176,177,177, 1, 73,126,126,254, 63,127,254,157,188,240,224,232,241,211,156,236,156,255, 25, 25,248,248,132,128,170, 24,153, + 89,228, 36,249,213,212,213, 46, 93,127,241,247,239, 95,244,130, 27, 12, 94,191,122, 42, 38, 38,157, 20, 97,205,195,141,125,162, + 21, 32,128,200, 60, 63,242,231,151, 15, 95,143,204, 96,190,179, 1,109, 64,230, 55,135, 4,139,117,177,136,166, 45, 22,155, 56, +121,120,141,130,255,104,186,127, 62, 56,137,241,246, 6,148,246,254,149,197,159,132,228,248, 12,252, 81, 4,193,133,255,135, 95, +127,127,252, 36,188,104,231,196,205,167,103, 94,129,102,128, 21, 5, 7,108, 64,255,223,191,255, 79,128,133, 59,246, 33, 42,242, + 1, 23, 39,135, 36,203, 95, 96, 92, 78,221,124,156,155,153,177,107,193,246, 21,237, 25,240,132, 18, 58, 97, 43,114,225,174, 41, +201,207,199,201,250,233,251,239,235,207, 63, 66,251, 87,223,127,249,245,109,219, 80,224,110,162, 34, 5, 47,142,201, 3,192,186, + 36,124,226, 86, 72, 33,254,235, 23,176,171,248, 27, 98,218,131,215, 31,145, 11,119, 62, 14, 86, 77, 41,126, 32,227,228, 61,168, +195,174, 60,121,231,211,179,229, 96, 77, 0, 40, 25,140, 22,241,195, 11,124,249,250,243,238,253,215,112,174,178,162, 40,176,172, +217,181,239,218,177, 83,119,173,204,148,221,156,180, 72, 50,141, 72,141,104,150, 74,136,241,137,139,241,145,231,254,187, 15, 94, + 47, 94,113,162,161,194, 23,191, 93,250, 58, 50,212, 10,177, 7, 15, 30, 0,179,143,146,146, 18, 48, 47,112,115,113,223,186,125, +107,253,150,163, 60,252, 18,146,114, 26,192,252,241,255, 31,168,248,224,229,227, 84,146,224,224,224,226,218,176,105,167,172,130, + 38, 19, 19, 51,184, 76,135,244,128,255,255,254,253,243,199,143,111,111, 95, 61, 23, 17,147,150,145, 20,192, 85,184, 3, 1, 64, + 0,145, 83,190,127,123,245,240,235,166, 34,182, 31, 79,209,196,127,113,201,243, 4, 77,229, 20, 16,129,150,245,191,127,239, 61, +121,109,203,165,251,130,220,156,206, 26,210,214, 70,234,172,172,172,192, 82, 94,208,163,234,237,215,183,204,207, 14, 51, 32,141, +204,255, 62, 54,225,151,134, 43, 27, 7,215, 80,175,155, 25, 24,168, 63,202,204,195,195, 13, 36,181,100,132, 22,108, 59,166, 41, +129,168,192,128, 5,235,225, 27,207, 32,108,115, 37,145,206, 96, 35, 57, 17, 94,200, 80, 12,176,180,109,220,120,110,205,153,135, +144, 34,190,115,243,185, 37, 89,194,224,201,119, 50,155,240,255,254,253, 75,153,181, 7, 62, 4,244,231,207, 95,160, 8,100,192, +189,100,201, 97,120,225,158,235,172,145,239,162, 9, 25,141, 1, 86, 51,115, 15,221,156,176,251, 26, 80,252,234,211,247,109, 27, +207,212, 4,154,193,135,227, 71, 75,198,225, 1,128,101, 95, 67,199, 38, 68, 90,229,102, 47,201,117,255,242,237,231,197, 43,143, +245, 72, 47, 19,137,212, 8,177, 84, 95, 71, 22,194, 37,163, 34, 65,216,248, 5,100, 35,166,248,186, 45,231, 47, 93,121, 2, 44, +247, 33,118,173, 95,146, 69,149,150,251,163, 71,160, 45, 65,106,106,106,192, 44,240,225,195,167,109,219,182,187,123,122, 91,218, +114, 94,185,245, 76,132,159, 75, 84,136, 71, 94, 86, 68, 86, 74, 72, 12,152,145,153,152,158, 60,121,250,248,169,230,227,167,207, +249,248,133,254,254,253, 3, 90,237,242,229,211,175, 95, 63,216, 56, 56,129, 36,232,156, 94, 22, 38,125, 29,124,227,239, 0, 1, + 68,114,249,254,233,206,201,159,123, 27, 89,126,189,133,159, 63, 0,201,169,255,152, 56,184,220, 26,224,133,251,142,227,151,171, +150, 29,188,250,250, 43,164,204,235,220,126, 65, 73,248, 64, 95,180,189,151,149, 46, 80,132,223,179,238,203,202,184,255,159,159, +195, 87,212, 48,254,254,242,253,226, 6, 54,243, 40,244,226, 18, 44,255,236,229,155, 77, 39,110, 60,124,253,241,195,247, 63,192, + 48,146, 17,226,246, 48, 86, 53,209, 84, 64, 81,248,255, 63, 90,211,249,205,187,143,107, 14, 94,220,113,249,193,213, 7,175,222, +126,251,197,201,194,172, 32,193,239,162,167,152,236,106, 44, 39, 41,130,203,131,251,207, 92,223,116,234,214,201,187,207, 56,216, +217, 12, 20, 36, 2,205, 84,109, 13,212,208,212,220,188,247,116,221,137,235, 79,222,125,251,241,239,191, 32, 59,179,162,164,160, +135,129, 18, 59, 11, 19, 3,194, 9, 8,135,188,251,240,105,241,222, 11,155,207,220,186,251,242,227,151, 95,127,217,153,153,100, +132,185,237,117,149, 18,157, 13, 52,228,196,177,186,225,240,133, 91,221, 27,142,223,124,242, 6, 24,201,103,102, 22,114,115,178, +255,255,255, 79, 78,148,159,143,157, 77,150,159, 3,174, 76, 78,152,247,112, 93,144,119,247, 22, 55,109,169,238, 48, 19, 96,115, + 0, 84,131,130, 27,200, 92, 92,255,166,196,219,157,184,183,238,201, 59, 80, 20,236,188,242,244,205,199, 47,146,172,172,204, 96, + 64, 70,186, 44, 89,114,104,203,185,251,136,226,254, 63,180,112,191,255,234, 35, 92, 60,200, 72,182,192, 85,139,157,157, 29,216, +241, 4,218,194,195,195, 80,233,111,242,236,227,143, 85,167,238, 1,101,231, 28,188, 81,234, 5, 29,136, 31, 45,223,135, 31,104, +168,240,155, 62,239,192,203, 87,159,128, 45, 98,204, 38, 57,164,105, 31,232, 99,120,236,228, 93, 96, 33, 14, 26,235,187,255, 26, +216, 52,118,115,212,178, 50, 87, 6,106, 89,191,249, 60,144,251,229,235, 15,252, 26,149, 21, 68,129,138, 25,161, 54,250,162, 41, + 6,214, 46,174,142, 90,192,230,252,209, 83,119,131,124, 12, 33,226,192,166, 61, 68, 4,200, 5, 22,217, 64,110,102,146, 61,208, +174, 93,251,175, 1,185,112, 19, 22,175, 60, 1,233, 19, 0,107, 23,160, 94,160,212,139, 87, 31,129,165, 60, 15, 23,123,108,132, + 37, 80,252,226,149, 39,187,247, 95, 3,106,132, 84, 39, 64,147,129,238,129,248, 2,232, 60, 98, 26,248,207,159, 63,255,251,247, +175,162,162, 34, 48,253,191,123,247,121,203,230,205, 22,150,182, 92,156, 60, 62, 46,122,198,186,114,194, 66, 60,156,236,108,192, + 60,138,200,224,114, 50, 1, 30, 44,187, 15,177,158, 61,127,233,223,191,191,156,156,188, 28,220,220,188, 2,194,156, 92, 60,204, +204, 44, 64, 67,190,125,122, 46,196,139,175, 12, 7, 8, 32,210,202,247,183, 71, 23, 49,156,155,197,252,255,247,127,120,201,206, + 8, 45,201,254,233,196,112,203,104, 66,148,205,219,124, 36,119,217,209, 63,255, 81,230, 82,239,189,249, 18, 48,113,107,223,235, + 15, 57,254,182, 44, 92,252, 76,214,229,127,182,231, 35,183,123,127,156, 91,204,143, 92,190,195,116, 55,175, 60,184,229,234,211, +111,127,144,202,205,255, 12,245, 27, 78,133,153, 40,205,206, 13,224,225,230,100,192, 54, 38,178,225,224,185,180, 57,187,223,124, +255, 3, 23,249,240,231,207,139, 7,111, 79, 60,120,219,189,229,108,178,163,118,103,130, 59, 23, 39,199,149, 91,143,138,151,236, +131, 40,200,182,215,156,184,227,252,193, 7,239,224, 21,215,161, 59, 47, 39,237,185, 20,107,174, 50, 51, 55, 0, 50,205,251,237, +251,143,210,153,155,231,159,184,251,231, 63, 74, 83,189,112,233,225, 72, 3, 89, 72,117,196,136,228,156, 61,167,174,166,204,218, +249,252, 11,210, 16,211,159,127,175,159,125, 60,255,236,252,148, 93,231,107,253, 76, 43, 34,157,129, 98,215,110, 63,154,180,227, + 60, 68,222, 68,134,175,120,245,201,239,127, 65, 70,136,177,130,134, 50,148,229, 65,211, 15, 42, 10,210,152, 99,112, 6, 10, 98, +155,138, 60, 37,249,216, 57, 57,217,129, 37, 59,164, 96,133, 53,177,255,120,235,203,207,220,127, 13,194,189,244,232,141,168, 0, + 47, 43, 43, 43, 25,133,251,194,131, 87,167,238,186,132, 85,118,211, 89,196,113,114,121,206,154, 64, 7,112,112,112,192,157, 1, + 76,205, 21,126,198,144,242, 29,216,156,223,114,254, 65,144,185,218,232, 16,205,240,108,200, 63,120,253,245, 43,168,224,134, 20, +193,240, 66,115,221,230,115,144,193, 19, 96, 51, 25, 88,250, 3, 75, 67,228,246, 50,144, 61, 67, 49,166,161,125, 19, 80, 28, 88, +142,127,249,250,147, 24,141,174, 14, 90,144, 2, 23,194, 5,202, 46, 94,121, 60, 54,220, 18, 88,224, 2,219,218, 5,153, 46,139, + 87, 28,135,148,239,192, 66, 31,210, 27, 0,137,248, 26, 1,171, 19, 96, 37, 4,113,225,221,251,175,130,124,140,128, 12,136,177, +144,202, 6,200, 0, 42, 0,150,233,112, 23, 2,221, 48,189, 99,147,181,153, 50,208,100, 96, 65, 15,148, 2,218, 5, 49, 25, 88, + 1,196,133, 91, 94,188,250, 4,168,101, 70, 95, 12,254,240,249,241,227,199,151, 47, 95,128, 45,119, 96,201,241,225,227,247,189, +123,246,106,104,104, 9,139,138, 3,115, 3, 7, 59,171,162,156, 40,214,172,247,239,239, 95, 29, 85, 33, 6, 70,147, 55, 31,190, +113,114,112,178,179, 51,179,179,177,240,114,177, 11, 10,112,241,242,112,178,177,168, 61,125,250,148,143,143, 23, 87,163, 13, 32, +128,136, 45,223,255,124,255,252,102,107, 51,235,179, 3,200, 99, 16,240,214,234, 95,102, 94, 94,195, 16,136,202,107,119, 30, 23, + 44, 63,250,251,223,127,140,129, 11, 16, 40, 91,126,196,217, 80, 77, 83, 78,156, 79,205,234,205, 9,117,198,247, 55,225, 6,177, +252,124,253,245,209,101,110, 57, 93, 84, 61,255, 87, 93,124,140,106, 6, 20,172, 58,115,239, 85,219,242,189,173, 73,152,174,221, +114,248, 66,228,212,237, 63, 65,110, 96,100,103, 98,140,183, 86, 51, 82,149,254,246,227,215,154, 99, 55,142, 61,120, 3, 20,159, +182,247,202,155, 79,223,151,151, 71,124,250,246,115,207,181,167, 16,255,156,186,253,252,211,159,127,140, 12,140, 98,236,192, 70, + 38,227,115,104,221,240,127,241,201,219,156,140,235,166, 21,133, 3, 57,153, 19,214, 46, 59, 15, 63,116,225, 63,114, 51,116,249, + 5,136, 56, 35,220,153,199, 47,221, 9,155,180,245,235,239,127,224, 81,105,230, 76, 7, 29, 69, 25,145,175,223,126,110, 63,123, +103,207,205,231,127,192,181,148, 0, 47, 87,134,143,229,235,119, 31,230, 31,185, 6,209,184,140,137,241,199,223,127, 88,189,140, + 89,190, 3,227,213, 88, 89, 18, 88,140, 66,216,144,214, 49, 92, 86,128,135, 3,121,122, 0, 14,136,111, 62, 67, 22,204,164,207, +217,135, 75,246, 8,108,128, 72, 90,144, 75, 78,132,151, 13, 12,128,181, 8,196, 25, 64, 82, 69, 82, 72, 86,152,231,241,219, 47, +160, 0,185,253,194,207, 88, 9,232, 90,200, 32,210,104,153, 56,156, 0,176, 0,133, 23,244, 72,205,234,171, 64,210,218, 92, 5, + 52,226,177,249,220,209,147,119, 32,131, 42,153, 73, 14,192,102,123, 73,237,106, 96,209, 12,108, 89, 3,203, 86,160,154,146, 92, + 55, 96,123, 25, 98, 14, 46,141,192, 18, 22, 88, 58,127,248,248,109,247,129,107,235,183,156,135, 91,228,230,164, 13, 25,162, 57, +118,242,206,213,235,207,176,186, 48, 54,220, 2,100,242,126, 80,187, 27,168, 12, 88, 31, 0,221,192,205,205, 14, 52, 31, 50,200, +115,233,234, 19, 72, 19, 30,168, 0, 84, 43, 92, 97, 0, 86, 18,144, 90, 4,232, 72, 96,245, 3,169, 51, 94,190,254, 4,233, 88, + 0, 45,133,152, 0,113, 45,126,112,251,246,109, 89, 89, 89, 72, 69,178,103,239, 30,126,126,126, 57, 5,101,118, 86,102, 46, 46, +156, 77,174, 47,159, 63,127,253,250, 85, 94, 94, 86, 67,147,247,193,227,183,192, 86,211,207, 95,127,190,127,251,253,233,235,143, + 79,159,127,188,125,247, 21,216, 8, 20,230,251,251,236,217, 51, 25, 25, 25,172, 25, 10, 32,128,136, 42,223,191, 62,190,250,121, + 71, 45,203,183, 39,240,102, 59,122,225, 45,166,195,193, 39, 8, 97, 47,216,119, 1, 81, 60,161, 15,180, 48, 0, 91,254, 51,183, +159,158,144,238, 3, 50, 71,222,238,255,187, 27, 40, 85,220,211,139,176,242,253, 63,242,102,168, 24, 51,165, 66, 31,115, 5, 41, +225,223,127,254,158,190,253,172,124,201,129,171, 47, 63,128,198, 82,110, 62, 91,115,232, 66,136,157, 1, 82, 89,248,255,231,207, + 95,213, 75, 15,252,132, 86, 48,255,235,253,140, 43, 98, 60, 32,230,231,248, 89, 59, 87,205, 59,124,239, 21,208, 11,171, 78,223, + 73, 63,123,131, 13, 82,239,129,213,126,250,253,207, 65, 73,164, 38,204,206,214, 64, 21,216,198,220,118,236,138, 95,255, 38,136, +236,146, 83,247,250,126,252, 60,113,245,254,178,243, 15,161,243, 72, 2, 92,221, 49,246,198,106,210,188,220, 92, 79, 94,189,159, +186,227,236,172,131,215, 81,154,238, 12, 12,213, 75,246,126,249, 13,154,248,102,101,100, 92, 91,224,103,103, 8, 61, 91, 45,199, +223, 38,162, 99,197,186,243,160, 97,141,170, 21,135,162, 29,244, 25,144, 22,149,255,248,251, 63, 88, 95,182, 60,208, 90, 78, 82, + 8,127, 33, 8, 31, 79,135, 47,127, 68, 83, 15, 41, 85,225,229, 47,164,112, 39, 41,211,222,127, 5,154, 59,133,176, 53, 37,249, +225,211,182,240,242,253,195, 55,104,131, 75, 70,128,139, 25, 6,224,117, 12,144, 1,228,202,193,202,247,171,207, 62, 0, 11,119, + 82,235,152, 81, 48, 36,192,250, 37, 89,187,246, 93, 3,182,100,129, 5, 52,100, 64, 3, 82,150, 65,134,203,129, 36,124,184, 28, +210, 40,230,225,102,151, 16,227, 7,150,239, 16, 17, 37, 69,148, 6, 44, 46,141,192,194, 93, 95, 71, 6, 82,230,194,199,103, 26, + 58, 54,115,195,230, 24,121,184, 57,136, 26,118,255,250, 19,121, 74,246,216,201,187,221,147,119, 2, 27,248,129, 62,134,144,230, + 57,150,105, 48,152,201,220,220,236,164, 6, 14, 36,217,115,113,113,253,248,249,231,204,153,179,191,127,124, 55,178,119, 2,230, + 90, 62, 62, 14, 60, 90, 94,189,126,253,235,247,111, 97, 97,225,119, 31,190, 61,120,242,246,227,167,239,127,254,252, 67,148, 48, +224,130,248, 31, 3,247,159,219,247, 69, 68, 68, 56, 57, 57, 49, 13, 1, 8, 32,194,229,251,155, 83,235,254,158,232,103,254,247, + 3,169,112, 71,202,153, 96, 38,139, 0, 98, 40,252,244,189, 23,200,187,157, 48,139,147,211,183,161,237, 95, 86, 65,201, 95,168, + 42,152, 62,191,196,104,241, 51,184,169, 75,204, 45, 10,101,129, 45,181,244, 18, 17,210,146, 23, 87,207,159, 9,110, 22, 51,172, + 58,122, 29, 84,190,255, 71,140,123, 95,189,251,228,242,107, 68,185,166, 34, 33,188,251, 20,162, 22,209,148, 20, 4,150,239, 16, +181,235, 78,221,138,176,212,132,219,228,168, 34,177,165, 33,134,131, 3, 26,226, 94, 86, 58,102,107, 14,157,122,252, 30, 52, 44, +243,247, 63, 48,184, 87, 31,191,254, 31,230,249,133,121,190,230, 58,208, 21,238,154,188, 60, 83,178,101,223,126,249,177,230,236, + 61,120,208,220,121,248,244,200, 3,232,108,164,180, 0,199,207, 63, 12,187, 79,223,132, 59, 67, 70,136, 7,226,243, 47,191,254, +110, 63,115, 75,156, 19, 62, 94,241, 63, 88, 79,110,113,121, 36, 11, 11, 81, 85, 47,254,185,202, 35, 55,159, 35, 26,215,194, 60, +164,238, 51, 66, 94, 48, 3, 44,220, 23,167, 88,155, 52,111,195,172,185, 49,235, 27,116, 23,194, 18,204,147,247,223,128,193, 8, +153,152, 29, 45, 16,135, 25, 0,150,185,144,150, 59,242,114, 14, 96,155, 23, 88, 70, 67,134,197,129, 69, 57,176,129, 12, 31,129, + 65,148,155,224,193, 16, 96, 19, 24, 88,118,195, 7,196,137,209,136, 92, 91, 0, 53, 2, 27,215,224,181, 46,175,228,100,132,224, + 53, 4,242,128, 62,154, 22,160,107,129, 85, 5,100, 76,233,197,235, 79, 64, 27,129, 13,124,100, 91,144,245, 2, 29, 9, 52, 25, + 40, 11,116, 18,100, 16, 31, 94, 51, 17, 3,126,252,248,241,230,205,155,237,219,119, 8,139, 72,190,121,245, 74,223,192, 24,152, + 79,248,120,241, 21,238, 79, 30, 63, 6,146, 26, 26, 26, 95,191,253, 58,124,242, 22,176,193,142,200, 52,192, 28,197, 8,109, 52, +255,254,245,235,238,203,247,198, 70,191,177,150,239, 0, 1,132,175, 16,249,253,243,199,139,173, 93, 28,143, 54, 51,161,103,103, +216, 40, 51, 60,123, 35,229,104, 14,118, 86,164,145, 27, 44,128, 29,118, 41,235,223, 63,127,208,178, 57,211,223,175,152, 99, 0, + 33,150, 26,104,133,157,130,148,168,145,172,208,201,135,160,129,242,235, 15,208, 87,254,159,190,255, 2,153, 27, 54,125, 39,142, +162,145,225,202,227, 87, 12,150,154, 8,149,150,234,240,194, 29, 2, 4,249,121, 24,192,229, 59, 52, 5, 63,120, 1,174,143, 24, + 85, 5,216,225,133, 59, 28, 68,217,106, 3,203,119,248,224,213,211,183, 8,191, 60,120,255,221,187,123, 45,174,112,190,247,236, +181,184,146, 56, 60,104, 35, 28,244,137, 44,220, 9,228,183,135,175, 31,189,133, 94,158,229,170, 41, 9,105, 74, 19, 95,184, 35, + 47,152,225,227,100,237, 10, 53, 17,230,197,183,186,233,201,135,111,184,164, 62,126,135, 78, 63, 60,125,255, 13, 62, 70, 52, 90, + 32, 14, 51, 0, 95, 69, 3, 25, 7,135,176, 51,147, 29,186, 39,237, 60,122,242, 14, 16, 65,138,126,101, 69, 49,140,118, 49, 59, +164, 52, 71, 94,135, 67,140, 70, 56, 0,150,236,245, 29,155, 50,138,150,124, 5, 13,226,139,133, 5,154,236, 63,124,163,164,118, + 53,104,236, 1, 71,173, 16,228, 99, 4,236,106, 0, 75,106, 96,169, 13,238, 34,200,172,223,124, 14, 50, 94, 4,239, 40, 0, 59, + 34,192,158, 1,100,248,222,205, 73,235,216,169,187,153, 69, 75, 32,141,247,204, 36,251,233,243, 14, 18, 31, 56,175, 95,191, 22, + 19, 19, 99,102,102, 83, 82, 82,253,249,243,199,215,175,159,248,248, 20,129, 29, 93, 92,195,158,111,223,190,101,102, 97, 17,229, +227, 7,230,217,107,183,158, 2, 11,119,112, 83, 9, 60,223,249, 15,178,156, 4,218,120,250,246,237, 51, 80,246,225,211, 79,130, + 2, 88, 86,136, 2, 4, 16,206,114,228,199,135,215,239,183,212,176,189, 62,251, 15, 92, 91, 32,236,102, 98,255, 39,105,206,252, +244, 16,114,193,254,255,251, 59,184, 2, 11, 21,169, 61,144,241,175,255, 88,134,144,129, 28, 7, 45,104,111,235,239,183, 79,255, + 81,135,111,254, 51, 48, 97,182, 12,181,101,177, 44, 50,225,231, 1,150, 53,160,162,231,215,159,191, 48,197, 80,245,159,191,126, + 39,106, 9,250,127, 96,220,127,135,116, 49, 32,190,208,149,151, 64,175, 2,152, 64,251,191,224,103,170,253,248, 5, 29,145, 23, +192, 86,241, 42,139,242, 51,192,215,240,252,255,127,239,237,199,255,255,255,163,173,150,100,196,114, 42, 15,195,183,159,191,145, +122, 58,255, 85,196,248, 41,207,108, 64,171,167,236,188, 8,231, 38,216,168, 64, 22,191, 19, 57,177, 9,212,158, 58,107, 15,124, + 97,204,210, 84, 91, 61, 57, 97,172,115,179,214,234,146, 71,110, 61,135,148,221,192,234, 68,131,139, 11,173,236,254,240,245,199, +229,199,111,145,171,141,209,194,125, 56, 1, 96,209,220, 80,225,135,204, 5,150,197,192, 82, 18, 88, 62, 66,150,165,207,232,139, + 1,182,148,191,124,249, 9, 41, 70,129,236,192, 47,134,202,224,209,152,216, 8, 11, 8,219,202, 92, 25, 50,228, 2,212,242,226, +213, 39,130, 26,209, 44,133, 40, 6,154,192,195,195, 14,180, 23, 40, 50, 29,168,247,254,107,160, 57,192,154, 6,216,244, 6, 22, +202,112,245, 64, 75,129, 34, 64, 45,202, 74,162, 64,195, 33, 85, 11, 80, 87, 79,115, 40,196,106,136, 22,136,153, 64, 17,160, 2, +136,153,160,181,146, 96,247, 64,150,202, 64,204,193,116, 12, 38,248,254,253,251,159, 63,127,128, 45,241,159, 63,255,255,254,253, + 91, 86, 70,230,253,187,215,192,182, 22, 46,245,159, 63,129, 0, 48,183, 10, 10, 10, 60, 3,173, 71,122,133,104,174, 3, 75, 20, + 38,164, 65,239,255,255,158, 63,125, 32, 35,171,242,230, 45,246,107, 80, 1, 2, 8,123,249,254,241,246,201, 47, 59,235,153,127, +189,249, 15, 29,144,129,102,200,191,108,130, 60,158,237,204, 76,140, 95,159, 30, 68, 46,131,127, 61, 60,129,168,120, 61, 77,167, +238,190,240,254,251,111,172,253,120, 1, 14,150,100, 55,232,129, 51,191, 31,159,102, 70,205,235,127,153,185, 49,138,247,255,143, +223,127,177,192,112,225,171,119,208,129, 96, 78, 54, 52, 47,252, 23,224, 67,220, 18, 37,207,195, 86, 21,110,135, 43, 28,133,161, + 29, 73,232, 82, 24,110, 14, 22, 28, 21, 1,116,149, 16, 23,176,107, 2,118,239,171, 79, 88, 58,125,159, 80,123,130,178, 66,252, +112, 95,152, 43,137, 39, 56,232,224,114,134,142,172,232,207, 47, 95,225, 5, 60, 55, 39, 27,229,185,238,194,131, 87, 75,143, 66, +135,131,130,140,228, 20, 68,249, 32,115,158,196,180,223, 33, 11,102,150, 28,129, 14,106,117,134, 24,235,201,137,128,143,175, 99, +193, 28, 29,242, 49, 84,232, 4, 79, 79, 1, 65,211,198, 11,139, 50,156,129,157, 74,228,115, 11, 38, 35, 85, 51,163, 96,248, 1, + 96,105,142,185, 52, 80, 28,117,195, 17,164,124,196,207,134, 27, 66,140, 70,172,150, 34,139,192, 21,136, 99,200,194,205,129, 51, +160, 42, 97,110, 22,199,240, 5,166, 94,100, 54, 86,199,160,140,115,190,127, 47, 36, 36,196,204,204,242,231,239,143, 79, 95,126, +126, 2,118, 98, 25, 89,190,126,253,202,195,195,131,150,239,128,213,192,215,175, 95, 62,188, 7, 77, 46, 42, 40, 40,124,254,242, +243,224,177,155,127,129, 77,162,127,240, 28, 7,106,191, 67, 51, 49, 35,195,199,247,239,132,132,196, 57, 56, 57,180,213,165,176, + 90, 13, 16, 64, 88, 74,180, 87,135, 23,253, 57, 61,141, 9,180, 8,146,145, 17,105, 44,230, 47,191,170,128,127, 47,183,136,212, +231,151, 15,209,199, 85,126,189,255,116,105, 27,159,158, 23,144, 45, 38, 34,184,182, 40, 48,160,123,237, 39,112,107, 23, 89, 37, + 15, 27,243,226, 12, 15,105,113,208,105,103, 31,159,220,100,124,126, 10,237, 88,178,255, 60, 98,152,237,247, 89, 59, 79,135, 58, + 24, 32, 91,183,255,204,181, 11,207, 63, 65,218,201, 38, 42, 82,240,186, 12, 58,140,174, 33, 3,103,191,252,250,203,215, 84, 93, + 66, 84, 8, 89,175,190,138,140, 16,172, 47,115,236,194,109, 44,189, 12,228,233, 3, 72,147, 28, 28,162,182, 26,114,199,238,131, +246,100, 62,252,240,125,243,145,139,190, 54,250,200,106, 39,111, 61, 9,107,236,131,128,129,130, 24, 59, 19, 3,100,154,247,237, +199, 47, 41,158, 40,149,212,241, 75,183,101,197,132,100, 36,160, 7,191, 29, 60,113, 9,201, 9,148, 54,111,129,109,228,180,217, +123, 32,108, 62, 14,214, 60, 23, 77,200,186,120, 98,198,103,128, 94, 56,112,237, 49,124,193, 76,181,143,110,184,185, 18, 59, 24, + 96,234, 5,138,232,203,139,234,200, 8, 93,121, 2,234,192,237,186,250, 44,119,209,145,246, 8, 75, 49, 1,232,130,173,201, 59, + 47,180,111, 60, 3, 87, 15,116, 12,172, 81,255,243,224,141,251, 70,138, 98,138,212,232,172,140,130, 81, 48,152,193,203,151, 47, +245,245,245, 95,189,249,242,244,249,123, 96, 22, 98,102,102,123,253,241,235,199,143, 31,129,121,228,255,191,127,191,126,255,254, +248,241,195,231,207,159,129,249,254,251,143, 31,192,124, 42, 33, 33,241,227,227,199,111,223,190, 95, 4,157, 76,240, 15, 54,150, +128, 24,147, 1,143, 3,128,134, 22,126,252,248, 34, 33,165, 40, 38,204, 35, 44,196,141,213,106,128, 0, 66,239,173,191, 60,180, +224,207,201,137, 12,255, 32, 43,220, 33,197, 27,104,180,244,175,156,155, 88,244, 28, 96,225, 14, 20,229, 21,151,255,197, 33,245, + 31, 54, 38, 2, 65, 95,143, 76,250,243, 21,218,166,182, 53, 80, 61,213,145,232,169, 37, 3,175, 61,216,153, 24,189,180,165,142, + 53,197,120, 90,131,202,196, 63,191,127,125,221,223,199,240,255, 47,204, 2, 72,241,252,159, 83,198, 16,179,237,188,247,214,139, +196,158,149,151,110, 62,124,243,246,253,131,199,207, 87,237, 62, 21, 63,105, 19,216,175, 32, 55, 70,218,106,163,119, 24, 21,164, +189, 97,213,233,143,127,255,131, 58, 86,158,191, 5, 90,244,242,249,243,151,229,187, 78,250,117,175, 83,205,158, 90,191,112,199, +147, 23,111, 17, 21,195,255,255, 4, 74, 85,112,208, 70, 59, 27,253,135, 41, 78,152,190,109,238,182, 19, 79,158,189,124,253,230, +221,181,219,143,178, 38,173, 93, 9, 94, 90, 3, 51,232,191,136,176, 64,164,133, 26,196,224, 59,111,190,164, 78, 88,243,238, 3, +104,104,239,251,143,159,107,247,157,241,237, 92,163, 95, 52,171,125,217, 30, 32, 23,110,193,255,255, 12,148, 15, 93, 0, 93, 56, +105,199,121,248, 70,211,120,107,101, 96, 25,202,198,198, 70,204,170,115,200,106,200,240,137,208, 73,212, 96, 99,185, 20, 59,117, + 72,225,206, 10,222, 27,133,169, 5, 40, 56, 53, 1,209, 67, 90,125,250,190, 81,205, 26,143,142,141,110,109,235,185, 19,166, 85, + 44, 63,134,172, 88, 67,146, 15, 50,193, 43,157, 61, 55,106,242,246,251,164,204, 80,141,130, 81,128, 6,192, 43,226,159, 32,139, + 0,185,120,166, 97, 49, 1,169,234,201, 3,146, 82, 82,191,126,255,125,241,226, 3,164,125, 4,204,134,108,236,188,215,174,223, +184,116,233,226,181,235,215, 95,189,122, 5, 44,180, 5, 4, 4, 21, 20, 21,245,244,244,116,116,116,128, 69,191,136,136,200,250, +205,187,158, 60,127,135,220,108,135,150, 44,160, 85,241,160,124,247,224,238, 53,126, 65, 81, 96, 13,161,173, 38,197,198,138,125, +236, 1, 32,128, 80, 68,191,191,123,241,251,244, 12, 70,212,145, 98,208, 57, 55,166, 89, 98, 86, 49,200,135,133,177,235, 71,254, + 61,209,131, 58,200,244,250,213,186, 98,225,192, 62,118, 30, 80,211, 88, 89, 86,124, 83, 99,194,155,119, 31, 30, 61,127, 11, 44, + 24,164,197, 5,132, 4, 5, 16, 29,150,125, 83, 24, 95,157,249,143,122, 49,200, 31, 14, 9, 14, 73, 21,228,178, 6,194, 96,101, +100, 88,120,236, 38, 16, 97,186, 62,220, 72,222,217, 76, 7,101,244, 29, 76,205,202, 13,180,175,154,127, 27,178,230,250,254,107, +163,138,133,138,188,108,239,190,255,249, 4, 90, 93,196,240,245,247,191,230,141,167, 36,249, 57, 51, 2,236, 49,122, 11, 56,134, +103,192, 64, 75, 65,162,208, 85,191,127,247, 69,160,216,135, 31,127,210,231,238, 70, 87,139,218,192,237, 77,241,186,252,232,245, + 25,240,232,243,252, 35,215,151, 29,187, 33,201,205,250,246,251,159,207, 64,103,128,173,235,218,124,202, 65, 87,193, 82, 87,133, +129,129,129,129, 74,163,210,247, 95,125,108,219,112, 26,194,214,148,228, 47,112,213,130, 44, 72, 39,166,241,254,225,235, 15, 96, +195, 31,178, 96,198, 92, 73,180, 59,204, 20,168, 23,190, 31, 21,215, 33, 71, 70, 74, 18,147, 98,173,107,214,156,250, 4, 30,148, +251,244,253,215,177,219, 47,176,154,175, 37, 41, 48,186,121,117, 20, 80, 11, 96,158, 28, 0,228, 54, 84,248, 17,127, 86, 12,169, +234,201, 3, 76,140, 76,175,223,124,254, 7, 89,120,248,159,225,247,239, 95, 15,239,223,150,150, 18, 51, 52, 52, 70, 62, 28, 23, + 88, 0, 0,123,222,191,255,252, 21, 19,151,254,248,225, 29, 23,183,216,211,151, 47, 4,133,196, 64,197, 57,120, 44,133,145,137, + 9, 88,154,255,249,243,235,215,207, 31, 31, 63,189, 19, 16, 18,227,230,226, 85, 83, 6,205,115,224,178, 26, 32,128, 80,202,247, +191,239, 30, 50,252,251,245, 31,105,133,251, 95, 78, 9,110,231,106, 97, 77,244, 19, 25, 5,205,130, 95, 94, 88,204,244,253, 37, +114,177,198,248,234,252,235,249, 65,188, 78,149,252,218,206, 16,113, 17, 33, 1, 32, 66,214,248,227,211,251, 55, 59,218,153, 31, +237,193, 44, 68, 89,212, 60, 89, 88,177, 12, 61, 79, 12,183,108,217,118,254, 25, 98,200, 27, 90, 14, 38,152, 41, 77,206, 11, 65, + 8,254, 71,108,112,149, 20, 21, 60,209,157, 86, 50,119,235,242, 99, 55,127,128, 71, 72,238,127,250, 9,113, 37, 27, 35,163,171, +150, 84, 85,160,149,149,145, 22,102, 9,142,165,108, 71, 93, 10,212,150,228, 9, 36,167,236,185,248,251, 63,202,106, 37,113, 46, +214,106,111,131,188,213,167,145,117,243,241,114,239,106,138,175, 91,178,123,222,129,171,223,254,252,253,249,247,255,131, 79,136, +198,130,189,146, 72, 71,162,187,169,150, 50,102, 71,129,194,145, 25,248,105, 48,157, 33, 70,144, 13, 71,196, 52,222,129,122,193, +167,149,189,133, 84, 12,211, 99,205,129,101, 58,164, 98, 0,181, 24,254,253, 67, 41,223,193, 34, 64, 0,153,179,141,179,211,178, + 82, 17,239,220,114, 30,216,126, 71, 54, 51,200, 8,116, 56,198,186,115,208, 21,177,102, 74, 34, 16, 51, 71,203,166, 17, 61, 94, +241,234, 19,228,164, 1,200, 98, 21,200, 82, 69, 30, 46,118, 76, 65, 6,240,249, 48,192,242, 23,216,202,126,249,250, 19, 68, 22, +162, 12,185, 13, 14,209,142,124, 4, 13,228,240, 0, 9, 81, 62,200,204, 45, 15, 15, 59,164,165,239,230,168,197,195,205, 14, 95, +202, 9,239, 7,236, 2,111,243, 6, 90, 4, 52, 25, 40, 11,153,116,133, 76,243,194,101,225, 75,239,225,178, 47, 96,135, 49, 0, +165, 32, 19,203, 88,253,251,230,205, 27, 6,102,126, 72, 41,194,196,204,252,240,225, 61,208,230, 31, 37,141,127,255, 25,191,255, +248,253,253,251,111,160, 83,191,125,255,249,243,247,223, 31,223,126,255,250,253, 7, 40,203,202,244, 69, 70,130,253,205,123,198, + 15,239,223, 8, 9,139, 3,115,219, 79, 96,153,254,225,205,183, 47, 95, 56,184,184,120,120,249,197,197,101,128, 57, 73, 72,128, + 75, 79, 3, 95,229, 4, 16, 64, 40,231, 3,255,252,252,254,245, 76, 55,134,255,127, 33, 69,246, 31, 65, 29,209,208, 9, 92,252, + 66, 88,117,190, 62, 56,235,247,233,153,216, 77,213,138, 20,115,205,103,193,200,198,159, 31,223,248,176,169,132,249, 59,150,221, +101,255, 25, 89,249,227, 55,240,136, 72,194, 82,192,219, 75,183,160,133,130, 9,120, 37, 98,203,146, 93, 59,207,221,189,246,225, +135, 40, 59,179,129,140, 96,158,183,185,183, 3,226, 98,144, 99,103,174,124, 5, 47,194,147, 20, 19,210, 81, 87,128,139,127,252, +244,121,213,254, 11,155, 79, 94,123,243,241, 43, 59, 43,139,154,180,112,166,151,185,129, 54,162,151,240,254,195,167, 51, 87,238, +192, 44, 82, 65, 91, 99,116,233,198,253,151,111, 62, 64,216, 14,230, 58,240,130,233,212,149,187,141, 75,119, 95,120,244,238,203, +239,127,178, 60,108,182, 90,210, 13,241, 30,252,188, 60,135,207, 64, 15, 3, 80, 83,144,146,151, 65, 44,251,121,250,252,213,188, + 61,231,143, 94,190,243,225,243, 79,110, 78, 22, 85, 41,145,120, 39, 3, 75, 68, 5,195,240,250,237,251, 11,215, 31, 64, 42, 18, + 75, 67, 13, 30,110,114,206, 89, 3, 70,229,196,237,231,202,151, 29,133,112,115,157, 53,138, 61,116, 57,193, 0,190,161, 20,143, +222,148,153,187,225,115,170,144,115, 40,129,237, 14, 70, 80,107,155, 9,122, 16,197,255,255, 71,111,189,128, 43, 16,224,102,215, +151, 19,237,138,182,129,140,219,252, 1,181, 43, 64,135, 74, 30,190,249,236, 31,120,208,208, 66, 89, 20,216,162,183,237,216, 6, +105,215, 75, 11,112, 29,174,244,228,230,230, 22, 16, 16, 96,143,153, 4, 20,153,154,228,244, 1,220, 59, 86, 20,227,115,210,145, + 19, 36,125,219,200, 40, 24,138, 0, 88,248, 46, 94,121,124,241,204,228,158,201,187,128,220,146, 92,183,216,244,185,177,225,150, + 88, 5,167,207, 59,208,211, 18, 10, 44, 85,215,111, 62, 7,145,229,230,102,207, 76,178,135,148,236,144, 83,198,128,101,235,186, +205,231, 50,147, 28,128,138,129,237,241,245, 91,206,127,249,250, 3, 40,190,107,223, 85,136, 9,192,146, 55,208,215, 8,104,130, +149,185,138, 21,248,164, 1, 55, 39,109,176, 75,174,150,230,186, 3, 21, 0, 21, 67,182,161,206,232,139,201, 40, 90, 2, 89,142, + 9, 57,103, 6,178,206, 18,168, 0,104, 5, 80,113,247,228,157, 16, 89, 57, 25,161,205, 59, 46,194,205,193,211, 15, 56,121,242, + 20, 7,143,248,255,127,204,192, 76, 4, 44,191,207,156, 62,166,111, 96, 34, 46, 46,252,245,235,143,103, 47, 63,253, 71,190,234, + 14,214,178,230,225,229, 22,230,251,253,244,217,203,243,151, 31,177,176,176,255,250, 5,108,166,254,231, 23, 16,226,229, 19, 98, +102, 98, 6,182,171,128, 25,154,131,141,213,204, 80, 65, 74, 66, 0, 79, 80, 3, 4, 16, 74,251,157,157, 87,144,211,177,234,243, +225,105, 76,127,127, 50,202, 89,138,123, 84,114,240,226,212, 44, 96, 18,246,226,194, 50,166, 95,159, 48,199, 37, 24,174, 45,123, +126,119, 55,171,162, 13,155,164, 54, 7,175,224,207,175,159,126,189,123,250,251,217, 69,134, 87, 23,153,192,253, 3, 44,229,139, +178, 7,188,112, 7,215,222,194,174, 98, 40,151, 78,245,230,132,244,226,246,134,149, 9,246,213, 41,252,124,188,169,254,182, 64, +132, 75, 35,176, 64,119,181, 49,194, 37,171,167,161,136, 85,220, 76, 71,121,107, 59,150,235, 59, 92,109, 12,177,170,151,150, 20, +171,141,117,103, 96,112,199,101,145,168,176,160,171,141, 32, 21, 71,102,164, 5,185,146,108, 84,137,111,188, 3,203,110,120,225, + 14, 4,104,251, 84, 49, 1, 92, 1,176, 76,103,103,103,135,180,202,129,182, 0, 73, 23, 61, 69,248, 34,200,169,251,207,127,130, +173,164, 10, 50, 2,157, 23,143,188, 8, 39,123, 30,226,216, 3, 96,225,190,173, 34,208, 8,247, 26,231, 81, 48,108, 0,176, 28, +156, 62,239, 39,176, 37,126,241,202, 99, 96,235, 24,178,171, 8,151, 32,168, 33,127,239, 53,228, 24,175, 99, 39, 65, 71,190,184, + 57,162, 76,185, 65,118,177,130,100,193,103, 6, 64,206,147, 1,150,245,144, 45, 72, 16,193,146, 92,119, 72,225,123, 9,124, 70, + 24,176, 80,134,212, 16,192,114,249,197,107, 80, 9,230,234, 8, 57,208,230, 49,228, 24, 50,200,241, 9, 16,211,128, 77,117, 96, +161, 15,105,200, 31, 67,146, 5,214, 52,200,230,224,241,175,168,168,200,197, 43,183,132,132, 37,184, 56,121, 46, 92, 56, 37, 42, + 46, 33, 40,200, 15,204, 46, 47,223,124, 70, 44,161,102, 68,218, 75,244,159,225,203,231,175,255,255,177,242,114,177,187, 59,155, + 95,184,254, 28,216,254,101, 98, 98,129,172,127, 23,224,231,144, 20,227, 23, 23,229, 3,221,142,198, 65,160, 43, 12, 16, 64,232, +163,242,194,198,129, 64, 68, 76, 36,177,114, 3,139,198,250,207, 91,139,145, 7,175,225,229, 60,211,143,215,127,175,175,255, 14, + 68,216,135,166, 81, 6, 61,254,114,203, 74,122,148,142,166,123,120, 81, 75,198, 8, 53,250,200, 76,176,145, 48, 31, 23,242, 81, + 48, 4, 45, 37,207,169,144,253,168,144, 42, 4,178,133, 10,190,131,233,194,131, 87, 61,219,161,167,146,241,113,176, 38,217,170, + 65,150,241,192,181, 7,155,171,166, 56,234,188,255,250, 99,206,254, 43,251,174, 60,246,234, 88,127,189, 47, 97,180, 21, 63,236, + 1,100,221,225,174,253,215, 32, 7, 15,172,219,114, 30, 34,130, 85, 16,200,125,249, 26, 84,232,199, 70,128, 78,242, 2, 29,197, +158, 43,131,213, 76,200,192, 14,100,232, 6, 82, 16, 51,128, 23,167,163, 29,255, 11, 44,166,209,206, 66, 0, 2,200, 81, 54, 18, + 98,252,144, 37,237,240, 19, 8, 32,171,239,161,235, 38,193,187,100,225,178, 88,205,193, 10,100,101,101,127,253,229,184,118,245, +198,171,127,207,127,254,252,161, 32,175, 36, 42,204,115,245,230,115,240, 97, 3,168, 7,206,254,135,174,147, 97, 98, 98,124,246, +236,133, 32, 63,135,169,169,226,175, 63, 44,119, 31,188,226,226,102,147,149, 20,146,149, 18, 20, 18,224,102, 98, 34,182,124, 0, + 8, 32,138,246, 73,242,107, 57,254,120, 91,240,251,248, 4, 44,101, 54,142,162, 28, 19,252,229, 16, 19, 14,154,200,202,201, 51, +154,238,207,220,123,121,239,229,135, 16,115, 85, 6, 18,111,166,134,172,153,129,159, 5,159, 96,165,108,173, 38, 1,159, 23, 37, +210,168,143,115,210,126,252,248, 1,108,143,195,199,217,209, 52, 2,203,113,197,178, 53, 16,246,194, 68, 75,160, 21, 64,243,145, +231, 75, 33, 39,225, 64,220,243,254,203,247,232,105,136,249,231, 28,103,117, 33, 94, 78,180, 69, 56,192,194,221, 9,156,153,129, + 5,189, 70,209, 66, 96,255, 99,238,190, 43, 37,190,198,163, 41, 97, 4, 52,225,101, 33, 35, 42, 12,160,163, 34,143, 91,129,207, + 17,195, 42, 8, 44,175,167,207, 59, 0,108, 41, 91,155,129,206, 35,131, 20,250,144, 1,119,148,161, 84,240,153, 1,144,193,125, + 32, 9, 63,176, 23,216,228,199,172, 9,224,135, 25, 48,192, 78, 71, 40,201,117,227,225,102, 71,190, 54, 4, 50,208, 47, 1, 61, +192,242, 9,208, 52,184, 21, 16, 0, 57,168, 0,110, 14,190,166, 48, 43,171,152, 8,255, 95, 77, 45, 96,129, 46, 32, 40,242,251, +215,215,231,175,216,190,125,255,133, 35, 47,131,182, 85,190,126,253,226,231,207,239, 2, 2, 34,215,110,189,208,211,146, 86, 83, + 18,227,230, 2,118,196, 73, 62,217, 27, 32,128, 40,221, 7, 47,110, 27,247,142,139,239,203,190, 54,198,255,191,201,208,254, 87, +212, 68,196,179,138, 71, 66,113,152, 53,192,241, 11, 2,203, 65, 76, 53, 64,145, 59,207,223,223,123,245, 17,178, 63, 8,178, 52, + 5,162, 12, 82,128,162,221,106,141, 92,248,162,141,204,228,131,215,204,224, 42,220,145, 79, 8,128,159, 72, 3,180, 17,216,178, +230, 0,246,247, 88, 89,129,229, 56,174, 46, 2,156,205,196,204, 4, 63, 10, 24,168, 17,243,162,237,212,217,123, 31,189,129,238, +169,211,148,228, 75,182, 85,195,223,153, 0,150,245,213, 43,143,238,189,250,104,180,124, 31, 9, 0,210,202,134,140,129, 64, 14, +236,197, 37, 8, 41,166,245,181,101, 32, 37, 59,228,148,130,197, 43, 78,232,129,231, 66,129,236,140,162, 37, 12,224,115, 8, 50, +147,236,119,237,187, 10, 84, 3,108,233, 67,198,229,239,222,127,133,124, 54, 25, 4,184, 57,105, 53,180,111, 2, 86, 21,144,114, + 25, 98,102,102,209, 18, 32, 9,233, 37, 64,148, 29, 61,117, 23,114,191, 7,176,106,233,153,188, 19,210, 63,136,141,176,128, 15, +197,184, 58,106, 1,197,225,230,224, 7, 66,130,220,252,124,156, 31, 62,126, 23,228,231,186,119,239,246,187,167,127,153,153, 89, + 33, 87, 53, 65, 14,147, 1, 45,127,100, 2,173, 90, 4,102,197,143, 31,222,254,249,245, 75, 86, 86,249,255,255,127,210,146,252, +236,108, 44,236,108,100, 22,212, 0, 1,196, 72,149,205,226, 95,158, 92,123,191,163,233,255,219,155, 36, 20,130,236,130, 92,182, + 69,162,198, 62,195,111,116, 37,125,246, 30, 39,109,217, 16,115,149, 53, 39,239,236,189,250,120, 90,162,195,218, 83,119,102,239, +187, 42,200,205,158,226,168, 5,148,242,234,220,164, 32,202,123,255,245,167,169,137, 14,235, 78,221,221,123,245,137,146, 24, 31, +144,237,217,185,209, 80, 94,180, 57, 20,180,112,165,103,235,249,125, 87, 30, 43,138,241,181,132, 89, 10,241,112,120,118,108, 4, +178,129,165,127,176,153, 74,170,147, 14,100, 48, 4, 82,170, 2,139, 93,183,182,117,240,198,251,180,104, 51,111, 67, 5, 46, 46, + 46,200,142, 83,204,146,183,116,201,225, 41,187, 46,242,115,177,181,133, 89,196,218,106,194,239,101,133, 44,146,193,147, 30,254, +252,249,195,159, 50, 11,194, 94,154,106,235,164, 43,207,201,201,137,214,132,103,192,152,170,229,227, 96, 93,146,106, 99,168, 40, + 14,113, 18,164,202,129,204,175,110,175, 8,116,130,101,191,158,205,103,129,229, 59,144, 11, 20, 28, 45,254,134, 61, 64,190,244, + 14,178, 34, 5,222,124, 70, 19, 68,102, 67,154,237,240,246, 59, 55, 80,228,254,107, 30, 30,118,200, 49, 3,144,133, 49,240, 3, + 18, 94,188,250, 4, 57,174, 0, 89, 16,190, 68, 7,114,240, 0,232,100, 2,152,201, 64, 67, 32, 11,102, 32,234,129, 21, 6,124, +161, 14, 68, 22,205, 10, 72, 27,255, 5,184,187, 0,172, 78,122, 90, 66,145, 87,245,224, 1,111,223,127, 93,191,105, 31, 63,191, + 48, 47,191, 0, 98,204, 29, 52,236, 14, 26,237,124,255,246,205,207,159, 63,164,164,229,153,153,153, 52, 85, 37,100,165, 41,154, +150, 3, 8, 32, 22,170,196, 22,143,140, 22, 71,252,226,183,251,166,253,188,180,148,225, 31,225,134,252, 95, 9,107, 49,223, 58, +110,161,225, 57,153,102,164, 32, 90,181,226,168,159,161, 28,144, 44,242, 50,216,117,241, 65,230,220,253, 19, 99,109, 30,188,254, + 20, 57,121,231,165,246, 48, 96,161,159, 96,167,209, 16,104,114,251,217,187,234, 85,199, 55, 21,129,246,253,254,254,253, 91, 65, +132,247,220,253, 87,192, 56,238,221,122,126,222,193,235,147,226,108,215,157,190, 27, 57,121,251,150, 18, 31,160,150, 66, 89,125, +127, 67,249,236,249, 7,244,100,133,204, 84, 64,115,209,144,193,110,228,145, 25, 13, 9, 62, 62, 78,182,147,247,222, 64,155,213, + 76,140,200,103, 7, 1,203,244, 45,231, 31, 0, 11,119,208,104,204,183, 95,217, 11, 14, 73, 9,112, 58,233,200,195, 87,199, 19, +127,181, 19,104,101, 13,120,180, 29,179,112,159,184,237, 28,242, 84,109,149,183,142,190,188, 40,100,135, 20,158,197,239,247, 95, +131, 38,108,149, 70,183,179,142, 12,128,188,167, 31,206,192, 42,200, 64,196,209, 2,152, 42,145, 15, 72, 64, 17, 68,149,197,122, +240, 0, 68, 16,232, 24,113,212,222, 6,154,105,192,130, 30,216,201,144, 16,227, 7,246, 18,128,109,124, 34, 11,119, 80, 91, 94, +128,203,193,206,226,192,161,147, 31, 62,188, 97, 2, 93,195,196, 4,110, 84,253,251,253,251,215,207, 31, 63, 69, 68,196,100,100, + 65, 43, 20,212,148,197,100,164, 4, 40, 12,103,128, 0, 98,161, 86,132,177,176,178,138,187,231,255,176,140,251,113,239,232,183, +219, 7,126, 60,189,204,252,243, 37, 74,203,145,137,227, 47,143, 12,167,188, 25,151,186, 11,175,188, 30, 51, 11,203,112, 77,187, +201,142,218,149, 43,143,245,108, 57,247,254,235,207, 88, 43,149,137, 59, 47, 3, 5,231, 29, 4, 45,157,252,240,237,231,153,187, +160, 96,241, 51,144, 3, 22,211,192,242,174,208, 83, 63,111,209,225, 4, 59,117,123, 13, 73,121, 17, 30,200,248, 12,184, 2, 80, +183, 83,151, 0, 54,153, 3, 39,238, 4, 22,253, 64, 45,118,234,226,118,234,146,249, 75,142,190,253,244, 13, 40, 14,212, 11,185, + 30, 15, 62, 50, 3, 4, 55, 94,124,138,153,115, 4,151,195,172, 85, 37,208, 26,231,135,174, 63,181, 85,151,162,214,157,121, 64, +247, 20, 47, 62,136,124,211, 83, 71,176, 97,184,185, 50,100, 7, 44,158,101, 60,192,128, 90,123, 18,116, 80,132,161,194,232,250, +153, 81, 48, 52, 0,176,160,135, 76, 21,192, 15, 53, 35,182,109,196,200,168,162, 40,250,243,151,241,227,103,111,255, 34, 93,149, + 1,105, 50, 1, 51, 17, 48,151,168,169, 72, 40,200, 10, 83,238, 72,128, 0,162,114, 33,203,193, 39,200, 97,224, 35, 96, 0, 26, +117,249,246,233,195,239,207,239, 25,254,252, 96, 96,102,101, 96, 97, 99,231, 19,230,224,226, 30, 9, 17, 15,140,191, 98, 47,131, +218,213, 39,235, 2,140,129,133, 53,176,213, 44,192,197,214, 27, 97,193,203,193,242,233,251,111, 5, 81,208, 5,217,144, 19,131, +128, 42,147,236, 53,227,172, 85, 13,107,214,232,203, 10, 65,175,144,253,255, 31,216,144, 63,255,224, 13,176, 14, 63,255,240, 13, +144, 13,153,240,252, 7,187, 18,235, 63,248,238, 83,160, 44, 48, 57, 32,175,153, 33,220,109,250,247, 87, 22,245,156, 10, 41,126, + 14,106, 29,232, 8, 52, 36,180,127,203,102,164, 59, 90, 33,133, 59, 7, 7, 7,174,194,189,122,229,209,224,251,170,239,191,253, +152,187,239, 10,176,136,119,210,145, 77,113,210, 25, 45, 56, 70,193, 16, 42,226,201,214,171,174, 44,206,204,196,248,248,197,123, +134,127,136, 33, 26, 96, 59,139,139,131, 77, 78, 90, 8,207,150, 84,146, 0, 64, 0,209,176, 17,205,197, 39,192,192, 39, 48,210, +162, 28, 50, 87,153,226,168, 51,247,192,181, 68, 59, 13, 96,211, 56,217, 65,235,193,155,207, 38, 13,160, 91,144,234, 3,141, 11, +220,245, 64, 67, 43,160,177, 13,230, 71,239,190,218, 54,175,255,240,245,167,131,166,148,190,156,200,197,199,160,227, 38,128,218, +155, 66,204,226,102,236, 21,204,152, 15, 44,220,231,167, 57, 66, 90,214,144,241, 16,176, 21,208,130,242,192,181,199,240,145, 25, +226,202, 96,134, 90, 95,131,171, 79, 63, 92,123, 6,218,180, 21,100, 36, 23,102,166, 68, 94,179,157, 25,118, 66, 36, 50,168,244, + 55, 1,118, 8, 62,126,255,165, 37,197, 15, 57,117, 18,210,114,199, 58,211,171, 40,198, 15,236,124, 0,139,120, 8, 23, 88,178, +183,132, 91,143, 22, 25,163, 96,132, 0, 96,131, 71, 67, 85, 2,136,104,106, 11, 64, 0, 49,142, 30,198, 77,117, 0, 89, 21,254, +231,207, 31,248, 73,185, 64,145,223,191,127, 3, 91,202,200, 55, 28, 65, 70, 69, 32,135,130, 66, 90,232,240,101, 51,240,217, 78, +136, 22,204, 75,151,128,122, 33, 11,201,129,122,127,254,252,249,235,215, 47, 32,131,112,161, 12, 6, 64,163,142,220,124,206,195, +206,162, 45, 45,128,118, 29, 54,129,230,255,223,191, 64, 95,124,255,254, 29,226, 47,184, 70,248,242, 30,160,248,153, 59,207,222, +124,252,106,166, 40, 12, 20,132,223,197,138, 89,184,239,187,242,216, 80, 81, 76,144,155,125, 31,120,109, 50,132, 61,154,114, 70, +193, 40,160, 46, 0, 8,160,209,242,157, 38, 0, 82, 52, 67,118, 42,161, 45, 77,129, 23,214, 88,165, 48,197,145, 75,124,228,149, +230,144,230,243, 95, 24,192,181,168, 17,185, 99, 1,215, 5,183, 17,178,161,148,200, 53,242,240,122, 11, 82,235, 96, 94, 24, 2, +113, 9,176, 14, 0,143, 33, 50,193, 21,140, 30, 40, 54, 10, 70,193,128, 0,128, 0, 26, 45,223,105,216,138, 71,227, 98, 93,192, +142, 75, 28, 89, 10,235,193,235,200,106,136,140, 68,100, 93,200,245, 4,241,229, 47,164,214, 65,174, 48,208, 22,207,192, 21, 32, + 87, 39,163, 96, 20,140,130, 1, 1, 0, 1, 52, 90,190,143,130, 81, 48, 10, 70,193,240, 4, 0, 1, 52,218,188, 26, 5,163, 96, + 20,140,130,225, 9, 0, 2,104,180,124, 31, 5,163, 96, 20,140,130,225, 9, 0, 2,104,180,124, 31, 5,163, 96, 20,140,130,225, + 9, 0, 2,104,180,124, 31, 5,163, 96, 20,140,130,225, 9, 0, 2,176,118,117,185, 81, 3, 49,216, 30,207, 18,170, 5,212, 10, +169, 21,143, 32,245, 14,125,230, 0,189,112, 37, 94, 56, 70, 15, 0,136, 7,170,182,187,219,204,159,241, 79, 38,100,187,162,170, +160, 43,237, 36,217, 76, 60,182, 99, 71, 43,229,179, 63, 60,130,184,131, 34,227,139, 73,236, 13, 79,172, 79, 61, 70,116,238,192, +233,204, 64,171, 92,138,182,170,103,116,144, 69,152,198, 16, 34, 89,133,110,144, 81,113,117, 72,198, 29, 20,208, 80, 30,204,197, + 56,248,184, 42,121,105, 51,126,216,137,247,196,155,243, 40, 12,132, 41, 0,171, 16, 64, 17, 64,186, 3, 1, 35, 16, 80, 99,196, + 72, 42, 75, 17,123,100,156,124, 50, 65,103,129,108, 84, 31, 60,232,170,220,170,204,171,167,239, 78, 55,233,254,110,187,113,203, +188, 89, 68,183,150,112,223,106,134,246,241,236,211,245,183,107, 81,186, 40,161, 98,105,162,179, 72,242,162, 83,232, 96, 23, 57, + 68, 39,236, 82, 3,187, 13,202,138, 30, 99,248,112, 78,119,219,180, 25,121,147,218, 46,215, 84, 91, 46,106,175,152, 72,204, 39, +235,183,151,159, 47,190, 92,125,221, 53, 24, 83,189,125,216, 61,196,154,153,115,196, 55,235, 33,138,189,226,113, 22,205, 40,106, + 37, 20,203,181,165, 86, 46, 44,102,138,225,226, 25,113,132, 58,215,216,153, 0,104,155, 83, 74,109,252,249, 75,238, 73,201, 6, +182,212, 47,203, 96,184,204,102,116,188, 78, 51,179,124, 29,255,103,159, 23,244,183,143,222,215, 15, 52, 52, 46,185,213,167,195, + 70,214, 56,162,215,153,115,237, 51,249,185,241, 54,235, 0,199,195,241,205,120,115, 8, 6,250, 55, 8,129,214,160, 65, 72, 45, +191,162,213,201,250,253,143,219,239, 97,177,104, 95, 5,177,155,223, 99,128, 23, 5,137, 80,159,161, 63,238,217,130,143,246,157, +248, 65, 66,248,105,142, 96,152,243, 97, 95, 60,130,135, 53, 31, 56, 13,231,197, 28, 5, 21, 44, 97, 17,189, 9, 57, 30,222,160, +229,255, 65,203, 74,191,208, 56,190,230, 92, 6,182,250, 59,196, 37,222,215, 55, 62,103, 74,106, 50,244,172, 12, 81, 75, 57,104, +165, 99, 92, 53, 6, 57,200, 37, 23, 5,226,230, 36,225, 88,242,152,114,105,169,214,162,197, 34, 77,211,223, 82,106,246,183,168, +197, 11,213,252,199, 26,105, 24,235,104,247,198,147,174,233, 51,192,163,121,114, 87,235,121,140,122,214,159, 82,220,108,194,244, +124,233,180,159, 83,168,203,218,248,151, 56,255,159, 15,239, 71, 41,190,156,240,223, 2,176,118,110, 75, 13,194, 64, 24,206, 38, + 80, 28,171,118,250, 2,190,255,147, 57,163,142,227,133, 83, 75,115, 90,255, 93, 18, 74, 75,209,206, 88, 46, 40, 16,200, 97,249, +247,219,189,160, 9,253,135,236, 60,233,213,104,108, 82, 67,147,169,175,180,194, 93, 72,161,165,142,170, 2, 42,220,141, 98, 93, + 87,136, 0,104,157,252, 31, 70,192, 11, 16, 43,241,137, 81, 24, 66, 0,173, 99, 20,246,224, 21,229, 20, 81, 31,212,128, 82,202, + 42, 49,224,207, 8,181,208, 8,184, 38, 44,155,240,189,149,182,219, 86,181,171,215,165,222, 1,113, 26, 12, 80,224, 12,201, 20, + 0, 84,230,239, 29, 17,150,178, 60,139, 95,185, 63, 95,178,188,204,235, 73, 69, 38,145, 19, 20,235, 67, 64, 69,208, 99, 22, 68, + 2,173,232,116,226, 34,139,211, 21, 93,105,178,119, 26,163,156,217, 62,211,235,103,191,243,236,115, 62, 64,234,153,129,239, 28, + 48, 78,240, 66,166, 37,216,108, 31, 95,222, 63,208, 99,234,236,125,231, 54,235,110,187,110,159, 30,220, 93,135, 16, 97,124, 32, +223,219, 94, 72, 45, 54,110,156, 4,170,148, 2, 6,192,232, 79,150,136, 2, 21,247,112,161, 52,124, 2, 79,251,232,251,183,175, +126,239,163,196,146,196,202,119,253, 74,158,107, 72, 67,211, 48,110,162, 99,112,187,192,247, 51,162,241,140,194,127, 82,158,174, +230, 50, 45, 67,156,110,193,247,185,167,141, 8,113,199,197,118,104,121, 32, 60, 26,132, 23,140,112, 10,119, 90,228,175,113,116, +197, 32,146,248,215,244, 54,156, 54,116,129,236,133,134,213, 99,225, 33,195, 26,196, 86,207,240, 90,157, 93,118,121,107, 42,212, + 37, 26,216,226,194,234, 63, 36,233,142, 29,115,183, 66, 3, 58, 18, 64,211, 43, 12,166, 65,246,230, 90,193, 58,152,174,219, 10, + 7,174, 89, 9,248,187,149, 63,236, 3, 92, 40, 69, 15,182,131,238,201, 11,241,113, 1,186,132, 56, 37, 91,154,142,180,228,102, + 53,202,202, 78,230,242,224, 84,242, 41, 26,248,206,195,113,214,228,112, 84, 47,188,181,165,118,119,248, 38,241, 9,181,131, 46, +170, 84,253,244, 28,241,191,164, 50, 75, 18,181,179, 48, 57,215, 36,223, 40, 41, 57,219,126, 4,160,237,220,118, 26,134, 97, 48, +156,184,105, 83,177,131,232, 5, 66, 92,243,254, 79, 6, 98,130,110,154,122, 72,130,255, 56,233, 10,107, 39, 16, 66,218,197, 84, + 45,135,214,246,239,207,213,146,252, 21,219,217, 84,181,177,167,225,180, 32,238,121,103, 99,104,172, 28,255, 45, 87, 96, 10,124, +242, 98, 77,108, 38,110,224, 22, 34,238, 44,236,134, 10, 83,178, 7, 84,112, 6, 0, 61,126, 82,176,166,195,137,148,143, 89,212, + 48,201, 23, 49,101, 4,201,182, 42,253,215,154,104,174, 43,115,228,242, 74,101, 68,167,171, 32,166, 64, 62, 60,222, 63,189,126, +188,184, 68, 96,194,233, 82, 65,120, 71,112,124,246, 86,145,120, 44,225,145, 94, 80, 50,100,227,121, 60, 1,158,152, 74,206,205, +169, 3,218,170,226, 61, 11,255,198,201, 94,104, 63,133,120,226,119, 28,195, 5,241, 24,180, 9,106, 95,133, 65,171, 55, 66, 63, + 60,186,119,166,170,194, 30,123,236,114,195,241,225,185,225,135,198,153,163,180,106,119,103,202,170,176, 6,185,139,251,223,240, + 36,119, 60,175,146,123,236, 58,125, 60,135,177,119,231,142,120, 94, 76, 41,133,143,131,104,178,200,154,206,143,204,204,170,227, +124,100, 98,202, 35, 60,227,152,203, 28,168,230,162, 8,114,176,140, 14,203,142,167,167,147,200,245,140, 71,154,186,105,187,150, +107,135,219, 94,100,169, 30,124, 55,193,209, 34,155,223, 22,247,201,164,187,114,219, 70,111,100,235,140, 49, 27,253,234,101, 37, +203,139,251,202,220,122,125,196, 92,152,174,189,247, 20, 6,196,247,123,219, 28,186, 67,248,129,184,235,217,104,107,226,190,198, +119, 48, 92,106,229, 99, 56, 20,122, 25,219,167,101,114,177,194,206,122,159, 45, 75, 87, 18,147,162, 40,233, 52,197,229,107,178, +240, 46,234, 60,201,201, 46, 42,209, 28,193,143,229,142, 40, 37,185,132,240, 74,170,115,217,120,212,144, 41, 89, 91,203,170, 42, +107, 44,115,198, 14,163, 21,123,240,102,179,109,143,239,131, 97, 97,239,209,206,139,226, 2,145,208,153,193,161,238, 58,248,121, +137, 50, 9, 60,230, 30,221,136, 99,153,163,210, 33,216,124,134,247,132,229,144, 36,230,125, 47, 83,243, 88, 61,206,225, 21,175, + 88, 99,185,117,239,122, 21,146,168,128,132,228,236,225,216, 46,247, 17, 46,217,113, 93,217,233, 10,204,191,185, 83,248, 31,102, +159,143,242, 41, 0,105, 87,215,219, 32, 12, 3, 99,135, 16,232,180, 73,235,255,255,131,211, 94,214,170, 27,133, 66,178,179, 29, + 88, 87, 86, 52,109,111,124, 4, 2,137,115,190, 59, 41,201,127,241, 29, 67,247,253, 50,206,189, 95,246, 97, 46,253,106,216, 46, +191, 41,211, 92, 74,127,147,102, 91, 93, 67,197,168, 61,240,132,115, 49,102, 42,157, 64, 47,232, 46,235, 81, 1,111, 2, 94, 20, + 67,131,231,198, 52, 14, 93, 7,212, 83, 26, 60,130,133,226,173,160,152,162,204, 40, 89, 46,201,234,176,240, 29, 74,165, 0,159, +215,119,243, 12,183,232,200, 67,119,156,100,237, 47,195,226,180, 76, 24, 77,150,185,146,246,179,149,102,183,139,187,243,216, 41, +203,157,117, 52,235,202, 97,242,152,174,221,175,145,144,253, 44,157, 53,232, 69, 32,178,237,169, 75,197,221, 33, 75, 98,230, 22, +225,199,166,215,254,227,101, 28, 78, 41,131,225, 52,109,243,212, 4,164,137, 64,244,208,186, 32, 30, 11,141, 98,247, 36,105, 41, + 79,117,237,235, 40,252,105, 2, 49, 23,181, 32,190,140, 84,147, 24,100, 28,167, 53,209, 5,199, 67, 62, 15,147,215,252, 55, 73, +141,162, 22,106,246,146,159, 64,117, 80,186,142, 57,247,162, 81, 22, 69,205,137,149,243,144,126,177, 54, 32, 90,120,226, 66, 67, +190, 98,178,252,220, 85,136,218,209,225,252,182, 70,237,200,113,144,109,120,175, 54,118, 79,231,141, 40,199,149,157,111,187,169, + 91,242,199, 90, 25, 44, 85, 28, 47,167, 27, 46,188,126, 97,244,205, 48,245,235, 68,149,140, 4,255,150,212, 91,194,219, 98,241, + 52,251, 90, 0,247,245,103,111,128,251, 92,152,188,227,181,216,219,200,124,222,184,105, 33,224,247, 61,153, 98,194, 20, 33, 98, +206,140, 86,156,221,204,147, 10, 85,191, 98,161,166, 82, 73,124, 62, 42,186, 92,149,184,138,108,219,135,157, 52,165,176, 13, 5, + 87, 80,126,153,131,237,213,139, 20,239,181,226, 32,190,140,175, 67, 21,154, 10,216,222,196,166, 13,177,133,222,125,222,239,251, +190, 7,189,119, 22,197,184,132,240, 68,196, 87,178,106,170, 56,190,164, 70,139, 32,180,168,119,167,102,175,129,124,105, 2,113, + 86, 83, 6,128, 92, 0, 20,148,116,202, 29,207,126,139,124, 15, 46,145,179, 41,225,156, 13,199,125, 2,156,136, 99,147,165,164, +221,211, 1,204,133,144,217, 78,169,217,125,135,120, 27, 11,249, 39,100,207,247, 53,208, 99,124, 4,239,161, 77, 91,230,111,136, +127, 19,136,159, 2,144,118,109, 59,106,195, 80,208,231,216,216,161, 41, 44,171,221,125,104, 87,253,157, 85,255,255, 1, 9,245, + 15, 42, 30,118,165, 0, 1,199,113,207,197,129,208, 80,161,182, 40, 2,100, 7,161,196,115,198, 51, 99, 37,161,179,136,255, 51, + 75, 20,142, 30,116,177, 78,144, 86,111, 15,110, 48,248, 57,153, 46, 98, 15,217, 1,135, 60,196,104,175,192, 66, 98,114,177,109, 18,199,204,248,126, 37,190,170,124,240,161,154, 17,111,229,188, 88,174,168,141,200, 61, 43,211, 22,245,156,213,134,205, 8, 39, -224,101,190, 52, 3,210, 76, 89, 84, 4,104, 8,104, 69,126,156,175,182, 84, 32, 94, 46,191,148,120, 8,100, 30,137, 55,163,168, - 5,179,170,151,192,180,216, 9, 64, 53,185,147,243, 84,181,142,138,161, 78,230, 28, 7, 4, 8,251, 64,153,111,182, 40,210,205, - 69,193,156,175, 54, 70,126,215,218,231,197,203, 33,238,131,115,252,180, 44,161,222,227, 97, 27,119, 63,154,237,166,253,248,217, -146,212,166, 46, 26, 62, 95,161, 3,130, 94,194, 67,155,154, 93,223, 52,121,215,230, 83, 4,217,131, 64,194,109, 60, 82, 87,238, +224,101,188, 52, 3,210, 76, 89, 84, 4,104, 8,104, 69,126,156,175,182, 84, 32, 94, 46,191,148,120, 8,100, 28,137, 55,163,168, + 5,179,170,151,192,180,216, 9, 64, 53,185,147,227, 84,181,142,138,161, 78,198, 28, 7, 4, 8,251, 64, 25,111,182, 40,210,205, + 69,193,156,175, 54, 70,254,215,218,231,197,203, 33,238,131,115,188, 89,150, 80,239,241,176,141,187, 31,205,118,211,126,252,108, + 73,106, 83, 23,157, 62, 95,161, 3,130, 94,194, 67,155,154, 93,223, 52,121,215,230, 83, 4, 89,131, 64,194,109, 60, 82, 87,238, 34,166,196,233, 58, 39, 73,157, 61, 29, 33, 70, 72,137,149, 82, 8,102,181,192,199, 21,124,174,241,233,193, 61, 62,216,101, 13, - 21,169,119,167,251, 30,198,123, 87, 5,110,217,127,236,105, 48, 82,241,178, 26,183,159,105, 33,155,137, 92,157,208, 77,121,255, -178,252,218, 12,240,189,193,124,188,246,229,187,121,244,248,136, 40, 14, 96,204,137, 52,230,180, 78,116, 57, 77, 35,236, 79, 88, - 81,123,207,245,255, 71, 81,242, 15,213, 2,163,112,198, 12,132, 88,219, 58,177,203,130,177, 13,155,178, 42,140, 42, 31, 39,238, -113,164,214, 97,116,240, 85, 8, 14,131,114,186,118,124, 25,110, 77, 10,220, 62,145, 51,185, 51,230,237,165, 11,207, 58, 88, 13, -174, 50,123, 9, 86,108, 73, 44,133, 15, 97,248, 91, 25,208,186,226,167,113,178,207,131, 86,233, 91,234, 79, 98,154, 66,250, 42, - 93, 36, 13,149,143,136, 65,119, 84,234,150,184,221, 83,165, 83,205, 59,122,181,129,164,205,235,235,183,183,183,239,155,245,250, -120, 60,152,225, 62,169, 89, 19, 89,170,113, 22, 93,189,236,198,177, 26,226,101,134,190,138,227, 85,137,241,213,244,147, 58,180, - 86,229, 35,151, 50, 23,164,238,172, 41, 27, 40,142,113,238,234, 96, 61,169, 70, 77, 28,132,199,137,224, 59, 73,126, 46, 50, 2, - 46, 22,187, 31,227, 31,202, 58,250,251,180,226, 61,190, 84,207,215,115,242,159,224, 90,230,155, 91,224,209, 22,242,193,109,215, -254, 45,185,211,227,151, 0,164, 93, 77, 79,219, 64, 16,245,172,189, 14, 95, 38,141, 34, 46, 52,151,246, 80,245, 31, 20, 1,226, -183, 32,113,172,196, 95,224, 71,246, 4, 71, 80, 15, 85,148, 22, 9,133,160,205,218,203,188,153, 93,219, 68, 4,130,154, 68,209, - 42,182, 44,239,238,236,155, 55,239, 69,235,255,194,119, 21,100, 90,218, 46,237, 96, 84,141, 81,155, 6,211, 19, 36, 82, 21,205, -129,144,144,187, 37,126, 36, 8,248, 43, 47,185, 80, 51,150,212, 88,149,233, 41,203,173,106,111,127, 88,125,218, 30,236,158,159, - 95,220,220, 92,207, 31, 31, 73,183,213, 77,240,163, 3, 47,106,124, 29, 3, 93,102, 48,143,187,119, 21,219,118,143, 75,173, 60, - 25, 59, 9,220,131, 34, 62, 37, 93, 80, 75,104,189,201,228,215, 54, 12, 40,203,122,217,210, 82,204,138, 60, 64, 43,180,142, 46, -100,255,160,181, 60, 40,170,193,252,195,250, 17,146, 19,100, 32, 32,252, 41,190, 75,207,225,120, 26, 14,106,178,198, 28, 12,198, -191,231,211,153, 91,220, 46,254,254,154,255,185,243, 15,179,108,241,100,195,206,112,235,112, 92, 29,142,118,135, 3,203,185, 49, - 23,179, 84,222,146, 55, 24,212,114, 51,176, 92,220,112,199,137, 65,252,137,177,222,145,115, 92,113,114,225,138,129, 53, 16,220, -169,180, 96,250, 73, 36, 37, 91, 6,190, 22, 7,115, 0, 93,225, 40, 54,206,161,130,229,217,225,234, 43,151,228,229,188,207,162, -137, 37,175, 90,108,171,206,236, 36, 69,204,144, 25,234,106, 30,234, 19,106,145,216, 10, 62,141,193,253, 93, 55,233,221,163, 6, - 76,223,250, 94, 37,190, 34,205, 43,184,127, 25,127,189, 95,252,235, 31,242,193, 55, 27, 43,254, 89,180, 46, 55, 5,119,122, 41, - 89, 44, 1,238,217, 10,236, 70,232,237, 89, 83,235,148,156, 20, 96,175, 10,238, 43, 75,140,214, 11,248, 68, 29, 34,173,235, 72, - 31,220,251,186, 48,165,172,210,221,185, 73, 25, 64,101, 85, 44,141, 16, 55,178, 48,210, 6, 47, 83, 14, 39,191,198, 6,165, 6, - 2,175, 48, 45,119,146,162, 26,200, 30,148,195,241, 42, 96, 80, 22,209,221,130,199, 85, 59,213,104,116,240,121, 50,249,113,116, -244,243,234,242,251,241,183,211,147,179,251,233, 3,159,198,248,225,156, 7,236,214,117,218,135, 3,196, 26,213, 39, 47,113, 2, - 86, 48,172, 27,136,247,120,118,187,248,181, 86, 76,167, 2, 12, 8,230, 93, 19,123, 76,237,158, 28, 8,223,101,195,215,245,226, -179,225, 56,103, 41, 89,203,212,161,109,202,179, 60,143, 5,238,100,149,226,232,200, 88, 99,235,208,188,229, 85,116,159, 94, 90, -142,238,112,167, 22,191,237, 84,121,252,171,164,249, 40,184,243,235, 89, 0,202,174,102,199,105, 24, 8,123,236,216, 38,217,203, -118,247,194,162, 10, 33, 14,188, 2, 44,111, 3,119, 94,139, 27,112,131,231, 64,236,133, 27, 72, 92,144, 88, 85,148,230,255,199, - 59, 63,118, 27,186,109, 5,109, 21, 69, 74,212,196,246,204, 55,223,204, 55, 74,142,226, 59,156,250, 69,155,131,200,235, 4,211, -133,221, 38, 98,206,206, 78,128,141, 75,171, 76,178, 0, 90, 92,193, 32, 18, 57,131,145, 66, 48, 68, 78, 64,169, 23, 5, 96,138, - 0,210, 75, 99,158,191,120,249,250,205,171,143, 31, 62,225, 74,140,152,116,225, 90,171,180,210,137, 97, 10,200, 68,107,138,178, - 45,101,153,206,100,200,199, 77,170,243,135, 88, 40,100,230, 33,193, 29, 84,110,243,229,229,114, 93,175,101,210,165,230,206, 22, - 16,101,244,232, 99, 26,230,243,100,168,151, 69, 63, 90, 92, 85, 77,117,253,236,250,219,175,239, 19, 91,202,227,139,101, 73,101, - 21,234,141, 9, 81,248,161,193, 33,160, 35, 86, 55,211,240,123, 36,146,254,181,252,121,211,252,184,213,155,210, 14,202,234, 51, -239,115,239, 11,231,115, 36,236, 20,234, 8,214, 45,186, 3,231,162,214,106, 71, 58,148,118,214, 60,200,120, 95,131,227, 30,152, -220, 89,159, 41,103, 69,138, 6,159, 25,188, 94,219,171,178, 10,235, 50,180, 29,244, 67,232,123,133,212,126, 83, 77,117,173,171, -122,106,234,208, 52,208,182, 35, 14,111, 24, 85,211, 78, 53, 63,122, 18,239,184, 65,254, 63,144,136, 37,178,106,136,143, 32,155, - 56, 76, 7,188,212,121,113, 81,117,165, 20,223,112, 94,144,112,209, 73,169,143, 33,196,158, 10, 73,156,255,227,131, 52,124, 12, -127, 85, 69,158, 92, 62, 93, 49,100,143,241, 13,149, 72,147,139,132,164,251,246,137,224,158,132,235, 93,164,249,199, 27,240,198, -115,120, 62,144, 79,236, 21, 64,238,147,247,148,188, 2, 28,240,160,136,185,206,228,152, 43, 36,223,134,131,202,252,125,154,191, -109,149,217,186,216, 9,151,156,245,201,192, 17,248,159,169,169,187,126, 7,149,216, 12,215,100, 16,180,183,242, 24,163, 29,164, - 33,232, 16, 41,187, 48,250, 29,136,179, 91,101,178,207,164, 74, 83,131,154, 22,158,196, 95,165,211, 81,218, 6, 9, 6,210, 56, -193, 5, 88,147, 57, 4,120, 98,240,222,163,189,131,174,202,170,176,103, 80,171,247,111,223,221,124,249,188, 90,221,254, 41, 55, - 93, 91, 15,212,212, 53,136,220, 47,165, 93, 97,130,154, 55,148, 5, 24,214,104, 51,116, 17,227,241, 31,109, 78,148, 37,192,195, -197,213,186,222,128,146,182,137,153,128, 15, 97, 81,156,119,125,199,192, 17, 44, 50, 76,227,250,177, 99, 76,144, 10, 85,152, 83, -120,244, 54, 54,145,105, 15, 72,121,226, 96, 94,129,220,195,244,211, 80, 12, 51, 9, 71, 31,207,192, 82, 60, 56,101,213,199, 14, -221, 9,192,218,181,237,180, 13, 4,209,181,215, 38, 38, 80, 8,173, 42, 85, 34,130,143, 64, 8, 85,234,255,191,240,128, 80, 21, -149, 87, 30,122, 81, 73,161,133,196,187,107,123,119,153, 51, 99,147,139,176,197, 67, 35, 69,137,180,137,175,179,103,207,156, 57, - 26,191,226,159, 73,182, 86,160,161,141,138,212,254, 18,136, 45,125,110, 9,123, 39,236,169, 54,113, 99, 78, 32,208, 47,141,113, -117,219, 15,151,105,188,172,252,154,208, 43,195,125, 34, 24,219,161, 95, 94,124,254, 66, 67,223,102, 51, 34,178,214, 26, 83,150, -166, 42,125, 93,163,139, 33,241,107,206,115,216,221,196,234, 79, 71, 46,248,152, 96,194, 84,128, 72,160, 94,198,131,153,144, 17, -225, 26,178,115,150,222, 52, 52, 69,173,226,128,121, 35,248,149, 42, 42, 42, 39, 32,165, 6, 59, 80,211,163,233, 94,177, 59,251, -126, 67, 39,196, 82,148,232,142, 80,162,156,119,127, 27,123,239,203,185,114, 77, 26,170,224,137,216, 28, 32, 4, 83, 34,167, 68, - 50,154,192, 24, 25,184,140, 3,218,163,153,219,100,180, 56, 73, 52,179,194, 20, 9,187,139, 29,250, 3,157,111,115,252,233, 35, - 69,252,221,159,251, 81, 54, 42, 29, 93, 7, 2,241,184,168, 66,202, 89,170, 6,209,135,127,128, 83, 96, 92, 10, 90, 9,248,113, - 34,209,213, 97,105,234,192, 8, 14, 29,159, 11,112, 62, 38, 85,132, 39,135, 70,242, 96,231, 63, 23,180,142, 86,168,187,114, 83, - 74,238,131, 73,111, 58,176,201,254,251,223,143,191, 34, 44, 25,210,205, 88, 67, 28,229, 34,214,166,251, 37, 14,187, 11,246, 71, - 7, 75,247,212, 39,209,208, 70,248, 54,165,235,117,206,208,239, 63,145,209,179,211,243,171,219,203, 55, 58, 19,214,220, 1,154, -229, 26,236,232,112,247,232,159,121, 40,242,194,214,118, 43, 12, 10,141, 80, 52,222,166,155, 64, 60,160,188,119, 14,203,220, 7, -183, 30, 86, 47,190,154,216, 3,238, 82, 77, 21,206,180,101,150, 28, 56,159,248,186, 5,105, 53,127,183,172, 50,155,130,251,202, -227,187,146,213,145,124,138,127, 54,109,157, 2, 73,135, 89, 73,139,230,252, 93,103,252, 33, 19,153, 37,122,217,133,176, 44, 14, -224,216,242,255, 68, 68, 27, 84,217,152,102, 19, 48,103,163, 28,109,166,137,222,208, 7,113,155,124, 50,249, 48, 61,153, 94,127, -189,174,240,172, 58, 99,172, 89,150, 4,241,206, 53,174,198,172,175, 16,142, 9, 46, 14,191, 52, 19, 65, 56,111,104,182,195, 18, - 28, 99, 49, 30,191, 27, 31,222,205,127, 44, 76, 73,196,223, 82,162, 26,144,139, 99,129, 80,158, 59,167,122, 49,191,214, 68,112, -112,173,145,237,181,254, 26,197, 62, 57,134,108, 41,156,116, 20, 7,115, 74, 49,200,134, 13, 47,141,250, 47,157, 81,251, 60, 57, -241,205,233,111,223, 97, 60, 11,192,217,181,237, 54, 17, 3, 81,123,214,217, 77, 90, 42, 65,185, 60, 32,158,203,191, 35, 30,248, - 17,126, 0,165,188,161, 86, 8,181,106,146,110,178, 27,219,195, 25,143,157,221, 92, 74,129,215, 72,118,178,235,241,153,153,115, -142, 99,247,119,198,220,147,179, 12,125, 71,182,217,230, 36,159, 99, 71,180,113,106,106, 43, 66, 10,218, 31, 18,220, 65,151, 21, -188,145,110, 75,147,176, 75, 43,165,156, 9, 23,176, 55,202, 13, 68,239,166,231,243,249,183,197,253, 29, 70, 97, 66, 44,209, 89, - 61,235,250, 77,200,178,198, 78,222,200,197, 80,150,118, 14,203,157,252, 25,233,186,144,125,249,226,213, 67,123,207,153, 47, 35, -189, 60, 67,201,253, 16, 89, 13,188, 57,124,135,119, 10,176,206, 85, 0, 37,189, 40, 89,204,217,137,177, 62,172,250, 37, 30,138, -146, 40,220, 24, 84,205,225, 33,108, 86,161,255, 25, 86, 43,183,237, 45,207,206, 38, 51,170,109, 32,249,231,116, 54,181,181,141, - 5, 56,218,118,157,200,155,100,180,158, 74,212,227,125,137,199,113, 54,113,129,226,212, 85,205, 68, 93,234,149, 17,245, 39, 96, - 91,116,221,246,195,251, 55, 31,175,174, 62,125,254, 2,220,197, 43, 14, 98,122,140,216, 66,120, 28,167, 44, 16, 91,113,100,250, -126, 98,209, 32, 48,170,117,252,182, 40, 55,129, 97, 23,208, 90,156,154,188,245,114,255, 83,116,146, 10,132,221,228, 8,168,115, - 77,205,104, 90,243,121, 0, 41,101,148, 50, 20, 34, 34,250,101,187,220,117,185,156,110,131,202,170,219,126,164, 98,171, 33, 57, -208,211, 74,229, 99,183,248, 3,127, 82, 80, 97, 47,144,233, 57, 86,231,107, 2,119, 58, 84,168,212, 39,241,228,216,113,223, 0, -112, 47,238,231,195,173, 11, 80, 64,135, 67, 35, 74, 42,229, 54, 79,207,113,155, 65,238, 34,206,116,150, 57,162, 68, 78,234,177, -169, 90,172,244, 75,101,160, 84,214,172,209,201,214,158, 26,201,166,172, 17,159, 40, 4,205, 88, 80,117,131,163, 99, 15,220, 7, -215,163,186, 26,185,144, 49,106,116, 43,200, 94, 12,205, 10,252, 90,204, 25, 21,207, 18,128,139, 7,173,216,227,180, 43, 72,188, -119,186,188, 93,242,150,213,163, 38, 84, 44,243, 41, 49,196,116, 96, 32, 17,236, 38, 86,221,186,253,126, 61, 71, 1,135,240, 21, -251,174,247,169,141,140, 73, 8,146, 78,241,162, 57,127,236, 90,173, 5, 17,222, 78, 5, 59,185,215,183,186,188,120,123,183,248, -117,249,250,221,205,237, 15, 12,168,235,186,223, 50,146,137,151,234, 4,104,132,152, 15, 40,156,250,126,131,185, 48,125,145, 76, - 7, 53, 91, 1,226, 40, 94,104,103,123, 99, 51,230,120,254,167,160, 62,198,241, 17,121,196,138,104, 97,127,146,157,134,143, 69, -193,166,179,255,226, 60,254, 45, 0,101, 87,176, 27, 53, 12, 68,109, 39, 78,154, 84,187, 61,160, 86, 72, 84, 85,191,128, 3, 23, - 16,136, 79,129, 35, 18,135,254, 19, 20,248, 27, 78, 85, 47, 69,170, 68,165, 10, 36,164,165, 91,218, 77,154, 56,246,116,102,236, -120,183,219, 77, 36,118,175,217,200, 78,236, 55,111,222,188, 89, 15,145,119, 57,240, 99, 25, 89,193,170,241,177,111,109, 96, 93, - 68,232, 34,205, 83,145,102, 50, 11,124, 2,168, 2,162, 5,190,132, 4,159, 47, 49, 83, 33, 42, 87, 45, 92,133, 57, 17,225, 27, - 35,106,176, 87,122, 58,216,117, 32, 52,110,182,235,127, 87,136, 44, 8, 86,123,211,167,191,103,151,136,114,157, 49,108, 11,113, -129, 10,201,104,204,164, 4, 46,100, 86, 58, 81,176, 50, 96,213, 71, 92, 78, 27, 48, 33,188,169,149, 47,189,120,101,155,190,132, -113,176,187,179,187, 83, 76,127,254,185, 88,119,186, 57,231, 99,137,227, 96,196,115,226,196,129, 45, 95, 55,205,237, 45,166,129, -210,206,237,226, 87, 59,175,210,174, 77,187, 98, 74,190,151, 39,248, 16,172,230, 27,128,177,164, 45, 41,202, 7, 37, 14, 16,233, - 49, 0,139,218, 4,165, 50,215, 42,203,147, 2,193,189, 80,185, 38,176, 37,207,188,147, 77, 3,228, 97,166,130, 33,188,126,254, -226,236,199,249,197,229,236,253,187,183,167, 39,103,223, 79, 78,203,188,160,200,147,192, 36,211,142,196, 45,242,194, 28,238, 63, - 91,212,213,236,234,250,232,227, 7,164, 63,159,190, 28,103, 91, 10,227, 12, 18,149,132, 52, 43, 71, 70, 73,107,239,112, 64, 13, -205, 11, 3, 23,238,149,132, 92,240,248,146, 52,238, 45,239, 9, 5, 31, 61,105,197,209,134,108,186,154,197,247, 65,196,236, 47, - 87,246,161, 81,114,147,232, 60,186,250, 1,236,163,232, 32, 55, 17,243,100,192,165, 6,203,252, 82,140, 91,217, 74, 93,214,166, -242,195,199,187, 53,180, 32,113,249,232,214,154, 56,169, 14, 58, 16, 75,145,190, 55,196,170,135,100, 7,209, 51, 53,176,241,112, -121, 41, 5,192,168, 56,174, 86, 28,232,225, 15,150,251,124, 14, 23,199,100,107, 50,175,255,174,116, 30,172,223,128, 53, 50,136, - 40, 31,249,160, 18,177,179, 80, 70,207,190,234,221, 80,177,154,154,242,187,246, 6, 20,217,115,243, 77,200,238,121, 92, 26, 88, -188, 8, 64,239,189,146,193, 49,217,195, 58,243,117,240, 13,128, 50, 54, 55,177,145, 46,229,168, 64,193,128,160, 27,159, 46,178, - 25,211,146, 3,152, 42,161, 29,230,231,200,216,219,198,208,169, 53,134, 15,202,161, 92,210,215,250, 19, 50,135, 49,233, 97, 99, - 52,201,191, 73, 86,230,219,101,185,141, 87,188,124,245,102,255,224,224,219,215,207, 8,252,116,102, 78,223,128,227,243, 96, 96, -247, 28,207,146,229, 22,185, 14,229, 94, 99,196, 8,100,216, 14,109,255,167, 55, 98,173,212, 49, 78,187,131,202,205, 76, 8,150, - 5, 27, 31, 96,104,165,185, 1, 4,135, 71,134,177,241,207,189, 0,172, 93,203,110, 19, 49, 20,245,245, 60,243, 40, 1, 65, 75, -131,202, 18,254, 2, 22,192,138,175, 66, 17, 95,128,202, 31, 32,193, 55,240, 88, 34,216,178, 66,160, 82, 42,218, 72, 93, 16, 74, - 90,230,145,241,216,230,222,107,155,132, 52, 21,173,196,172,178,136,228, 25,207,125, 28,159,123,142, 38, 62, 87,113,247,226,145, - 69, 36,229,124,113, 16,172,110,254, 28,151, 11, 66,159, 26, 95,144,104,107, 59,115,194, 35,178,173,106, 34, 28, 16,135,198, 42, - 74,100,146,198, 89, 55,238,174,119,174, 25,208, 19,117,244,171, 45, 37,201,153, 18,159,148,152,222,244, 42, 68, 85, 22, 73,154, - 81, 51, 23,102, 60,217,227,207, 28,181,204,154,145,136, 17,152,135,119,140,153, 87,176, 72,121,123,120,107,247,112,199, 73, 48, -157,236, 92, 88, 31,121,158,234, 2, 91,171, 38,149,169,178,196,190, 13,122,151,143,171, 19, 31,245, 26,209,193,165, 47,135,187, - 60, 34,146,139, 10, 85,139,201, 11, 45, 25,173, 44,163,120,230,220,172,147,232, 64, 52,209,211, 49,124,175, 69,219, 68,186, 63, -200, 7, 73,214,203,251,189, 78, 42,120,224,239, 38,190, 86,243,172, 83,104, 82,131, 74,145, 33,118,214,116,243,137,251,112, 18, -199, 61,139,108, 48,234,201,108, 27,133,169, 2, 30, 87,134, 91,195,106,166,191, 29,236,111,172,223,180,162,243,234,205,235,162, - 50,247, 31, 60,252,240,113,239,199, 20, 59, 85,164, 12, 57,119, 89,129, 44,174, 94, 25, 60, 26,141,118,119,190, 62,121,186,125, -231,238, 61,132,153,207,158,191, 64,252, 73,116, 54,107, 54,179, 52,174,105,131, 33,227,180,166,245,129,122,175,182, 80, 26,189, -214, 77,142, 78, 76, 18,101,184,219,210,106, 61, 15, 44, 19,166,255,127,125, 73,196, 4, 38,193, 4, 34, 94, 17,104,245, 98, 81, - 45,254,195, 69,250,200,180, 87, 52,133, 60,165, 47, 12,220,247, 10,203,107, 39,202, 43, 93,195,191, 32, 85,201,197, 29, 60, 5, - 23, 68, 80,164, 47, 84,171,156, 77,110,158,140,157, 82,211, 73,137,243,243, 15,234, 49, 96,206,110, 93, 0, 75,190,182, 83, 44, -191,157, 7,156,175, 18,180,227,100,229,177,211,234,167, 61,251, 17,194, 49, 22,124,149,231,187,196, 29,171, 84,197, 67, 42, 71, -172,207,197,237,193,246,237, 51,130,114,103, 94,220,101, 20,124,172,129,142,151,115,104, 79,148, 30,184, 94,192, 53, 54, 90, 54, -175, 46, 92,210,149,120,167, 54,112,162, 7,112, 58,131,152, 85, 55,188, 26,235, 99, 48,169, 65,209, 79,172,242, 24, 69,141, 34, - 38,134, 61, 77,216,100,149,109,219,235,107,155,227,201,190,155,186,225, 33, 82,184, 42,109, 89, 71,131,207,141, 77, 0,255,105, -178, 60,239,143,182, 31,191,123,251,126,227,229,102, 81, 28,227,242, 55,250, 91,159, 15, 62,225,106, 70, 33,190,106,112, 71, 27, - 86,209,231,105,183,158,149, 54,164, 55, 5,106, 8, 86,158,150,165,170, 41,207,163,146,133, 11, 64,246, 21,228, 98, 14, 89, 77, -203,234, 69, 58,126, 65,176,189, 20, 45,182, 53, 23,206,167,223, 2,176,118,237,186, 77, 4, 81,116, 94,158,245,174,147,181,113, -131, 40, 81,226,130, 18, 33,209,162,252,101, 42, 36,126, 0, 41, 74, 73, 65,133, 27, 26, 36, 10, 20, 18,137, 2,137, 42, 56, 33, -224,172,247, 53,195,125,204,190,156, 88,128,132, 27,219,251, 28,237,206,222, 61,247,158,115,102, 6,252,170,188, 27,220, 27,187, -177,238,122, 82,112, 42,112,101, 70, 99,210,135,183, 57,146,128, 36, 99,237,117,225,242, 10, 16,143,168,136,182, 18, 42,120, 75, -241, 57, 96,226,209,241, 61, 65, 35, 26,100,184,230,209,228, 97,106,211,181,207, 96,123,213,184,154, 49, 30,146,165,129,228,175, - 56,179, 29,124,161,224,210, 68,155, 98,237, 89,123,232,194, 40, 5, 45,196,128, 37,215,191, 86,212,251,176,164, 30, 20,153, 70, - 6,134, 39,112,176, 42, 47,115,216, 25, 41, 26, 47, 11,114, 48, 55,242,124,113,149,253, 80,140, 95,216, 31,215,210,184,222,135, - 89, 79,169,112, 1,255, 35,107,241,138,139,250,194,125,187,140, 87,241,196,236, 69, 49, 92, 4, 11,221, 67,152,186,134,252, 93, - 59,108, 48,164, 44, 58, 26,153, 73,162,246, 19,148, 42, 38,214, 24, 4, 46, 42, 47, 92, 89, 74, 88,121,117,157, 81,185, 27, 0, - 3, 44,148, 27, 52,250,168,178,226, 98,150,252,153,229,207,159, 62,123,178, 56,120,255,225,227,131,217,124,113,184,120,243,118, -121,248,248, 32, 77,167,145,141,206, 47, 62, 71,227, 81, 28,137,201,216, 64, 6,192, 29,246,232,197, 17, 36,247,175, 79, 78,207, -206, 62, 45,151,239,206,191,124,245, 78,195, 1, 21, 14, 63,128,141, 55, 90, 89, 43,103,177,153,166,122,111,162, 99, 27,138,189, - 21,146,170, 46,167,230, 16,155,133, 55,160,181, 8,180, 41,228,214, 16, 5, 35,109, 21,170, 42,235, 33,167,244, 63,231,108,154, - 39,243, 28,210,106, 14, 94,131,176,232,119, 74, 45,253, 95,121,200,239,165,173,106, 2,236, 4,127, 66,245, 73,111, 57,125, 24, -246,162, 25,202,169, 94, 99,228,159, 78,117,135, 29,237,234, 3,196,134,136,206, 33,200,210,242,198, 88,178, 99, 14,150, 46,116, -203,208,200,224, 48, 65, 96, 72, 85,112, 61,120, 69,169, 62, 96, 83,162,167,125, 20,236, 45, 85, 12,219,169, 8, 73,250, 8, 25, - 84, 50,244, 27,171,237,196,184,242, 8, 23,130,105, 51,211,215,207, 16, 54,106, 87, 49, 21,138, 59,208,217,227, 81, 34, 26, 73, - 43,114,163,180,141,119, 65,241,204,227, 98, 20,101,134, 94,213,138,194, 60,253,184,185, 93, 97,104,195, 96,206,108, 29, 19,108, - 72, 54,225,254, 24,132, 20,196,147,205, 38,219,151,233,171,227,151,168, 54,241,162, 40,242,239, 55,151, 53, 57,222, 49,128,160, -202,217, 83,122, 84, 79,227,217,109,190,238,112,115,128,149,225,137,175, 32,135,195, 11,224,188,148, 61, 74, 67,222,247,118,222, -166,186,225, 48, 99, 36,213,235, 93,130, 39, 49, 20,122,121,236, 63,126, 75, 70,133, 93, 11,130,147,239,251,195,133, 97, 7,217, - 63,126,126, 11, 64,217,213,244, 54, 13, 4, 81,207,174,237,236, 58,105, 82, 26, 72,133,138, 80,251, 11,128, 11, 7, 78,253, 27, - 72, 28,248,171, 5,132,132,224,128, 4, 72,168,151,138, 67, 69, 19,218, 40,105,172, 56,254,102,102,118, 29,187, 14, 70, 16,229, -148, 83,188,158,121, 51,243,230,205,236,159,241, 29,234,230, 81,211, 62,106,249,140,228, 13, 46,130, 91,116, 70, 51,163,132,198, -147,203,202,196, 44,134,104, 48,183, 86,162,235,242, 65,129,233, 97,112,166,154,155,212,162,112,134,106,255,190, 26, 47,146,101, - 73, 4,139,224,169, 3,160, 78, 8,191,140,170,195, 87, 96,148,222, 36, 28,117,205,245,114, 22,220,183,236, 33, 25,203, 72,143, -184, 83, 90, 52, 92,131,228, 59,102, 63,141, 1,122,171,230, 97, 22, 21, 31, 66,186, 54, 92, 25, 37,151,242, 20, 97,173,132,129, -222,195, 31,134,122,116,114,120,124,125,123, 83,201,233,201,105, 48,233, 62, 57, 56,254,186,184,184, 16, 51,232, 23, 67, 95,251, - 64, 82,127,229,187,218,119, 77,102,212,243,188,128,184, 65,215, 88,176,239,122,129, 30,253,154,133, 73, 38, 16,184,139, 12,242, -212,121, 56,153,188,126,245,178, 31,168,233,244,102,181, 90,227,169,184, 76,184, 35,254,210, 25, 56, 50, 38,138,166,236, 73,249, -236,201,211, 15, 31, 63, 33,232,158,190,120,254,229,219,231,123,195, 32,205,163, 71, 71,135,241,122,177, 92, 94,247,148,139,118, -178,142,203, 40,202,166,243,240,237,217,251,179, 55,239,230,171,245,213,108,254,227,242, 10, 95, 19,134,140, 56, 43, 34,202,135, -242, 36,227, 14, 43,134, 32, 32, 57,231, 38, 46,241, 27, 39,104,214, 24,117, 11,223, 21,225, 18,243, 62,200,183,183, 6, 86, 43, - 57,140,114,116,119,255, 12, 77,141, 91,167,109,241,195, 0, 59, 43, 7,186,168, 67,163,144,233, 50, 83, 76,222,161,115,116,182, -157, 35,181,228,137,237,110,204,191, 33,190, 73,138, 93,225,149,101,185, 51,118, 68,180,192, 65, 48, 94,167,161,216,137,100,176, -211, 52, 3, 7,254, 2, 10,119,135, 84,109,235, 1,192,113, 58,135, 99,133,168,165, 59, 78, 83,198,179,141,127, 21,112, 55,131, -173,104, 4, 25, 75,187,195, 86,118,102,166, 50,106,184,167, 34, 18,179, 31, 97,197,109,194,106,222,152, 71,149,194,150,183, 18, -120,130,194, 80, 52,204,189,152,190, 43,203,100,141,188,133,156,142,228, 50,142,240,165,223, 87,253,201,222,131, 52, 79, 31,143, -143,176,130,143,179,141,168, 31,150,200, 85, 74,114,208,205,227,152,111,129, 76, 18,170,215,121,192,154,144,128,231, 87, 33,175, -134,228, 75, 15, 93,133, 10,119,201,139, 77,168, 77,161,148, 62, 63,255,254,115,122,137,169, 0, 70,133, 77, 28,241, 50, 19, 90, -211, 97, 22,110,216, 13, 5,224, 12,244, 48,140,110,225, 46,190, 23,150,122, 7,133,238, 44, 37,201,163, 1,170,247, 8,205, 56, -218,213, 55, 98,116,160, 97,124, 86,238,130,104, 78,170,119, 27,155,246, 6,105,145,180,140, 68,139, 32, 99,119, 48,200,142,127, - 93,123,154, 43,227,255,251,252, 22,128,178,171,107,109, 34,136,162,221,217,217,236,102,179, 77,104, 49,248,160, 16,161,148, 66, - 5,171,130,244,165, 66, 31, 90,255,175, 63,162,250,160,111, 45, 82, 10, 62, 41,212, 34,178,105,154,237,126,206,140,247, 99,102, -179,109, 99, 84, 72, 32,217,144,100,179, 51,115,230,220,123,207,185, 89,133,239,182, 4,222,154,215, 58, 53,213,245,120, 4, 99, - 32,108,247, 47,217,247, 96,203,194, 75,105, 92, 33,162, 35,251,247, 90,131, 59,219,223,148,173,199, 91, 7, 4, 87, 56, 55,163, -141,113,252,232, 71,126, 69,223, 73,208,206, 12,158, 17, 30, 71, 95,187, 30, 18,246, 1, 1,140,118,118, 38, 59, 83, 97, 92, 97, - 39,224, 46, 99,112,112,231,201,206,236,246,154, 20, 50,108,222,104, 85,186, 46, 80,240, 52,213,126, 91,153,151,152,140,159,165, - 89,234,211, 14, 14, 63, 42, 43,111,211,155, 95,198, 18, 40, 36,239,163,254,176, 39,123,239, 47, 79,190,153,105, 36, 48,189, 94, - 85,216,242,165,204, 77,133,105, 16, 44,234,199,125, 25, 5, 1,144,119, 20,240,248, 16, 30,170,189,221,237,163,195,131,139,175, -103,195, 68, 14, 32, 48, 11, 97,255, 88, 43,234,249,108,150,190,124,181,123,124,248,118, 16,247,210,233, 79,224, 32, 33, 42,136, -200,202,138,125, 58,124,137,227,211,236,191,217, 59,191,248, 82,213,217,235, 23,207, 47,175,190,231, 69,182,189, 53, 57,249,240, -241,221,209,241,167,207,167,117,165, 40,142,198,107, 25, 72, 89,212,117,217, 52, 73, 63,164, 6, 31,232, 79,237,209, 26, 0, 90, - 19,160,101, 80, 12,128, 99, 68,184, 58, 97,182, 23,133, 46, 43, 84, 23,107,110,123, 6,139, 27,157, 73, 13,174, 53, 99, 87, 22, -227,251, 61, 39,170,233,168,128,187,204,221,216,134, 79,248,122,228,199,218,113,225,213, 81,235, 10,112, 95,138,215,255, 30, 6, -143,147,199,154,178,183,247,206,255, 79, 89, 82,209,201, 70,146,184,169,229,197, 11,162, 3, 39, 83, 96, 98, 7, 14,202,135,190, - 22,183,145,152,167,163,201, 53,246, 59,195,103, 81, 16,115, 50,231,225,217, 82,191, 23,227, 10,194, 84, 45,242,196,178,216, 98, -201,191, 29, 46, 60, 22,119,199,194,101, 77, 23, 67,227,121,173, 20,210,182,240,112, 66,175,133, 43,144,153, 59,242, 54,235, 18, - 17,164,144, 97,200,102,197, 10, 78, 51,201, 26,104,227,154, 56, 9,209,138, 38, 89,250,236,183,111, 97,118, 79,215, 7,104,245, -188,184, 1, 24,207,242,121,222, 20, 62,187,142, 48,156, 39,119, 34, 53,180, 3, 20,169, 53,166, 97,233,134,104,175,200,171, 77, -190,117, 86,181,216,179,222, 72, 54,169,197,147,226,169, 65,186,122,191,168, 74,160,128, 0, 2, 73,184, 62,157,167,180, 79,240, -231, 32,132,192,236, 86,120, 55,101,157, 27,215,104,204,176,223,188,227, 79, 5, 24,133,184,129, 11,218,157,237,217,235,244,218, -178,162,112,227, 80,142,145,157, 95, 34, 69, 44, 50,128, 36, 76, 74, 85,255,141, 85,224,134,163,141,186,139,239,128,164, 85,199, -236, 58, 44, 21,208,179,122,237,255, 29,173,191, 5, 96,237,122,126,147, 8,162,240,204,236, 44, 12, 11, 68, 8,120,106, 15,246, -100,107, 77,154, 26, 15, 38, 30, 60,217,164,241, 63, 53,241,234,255,160, 94, 26, 53,169,246, 82, 26,127,245, 96,164, 33,192, 44, - 11, 51,248,190, 55,179, 43, 16,154,104,226,158, 96, 67,178,187,240,222,247,126,125,223, 99, 11,190, 87,127,225,156,108,130,123, -160,189,195,118,220,130,231,162,252,240,153,202,148, 71,173,161, 56,217,119,101,255, 72,135,182,135,136,201, 66,153, 63,248,104, -143, 4,186, 60,109, 7,132,161, 53,175,238,102,189,209, 98,106, 41, 39,146,137,227, 29,141,232,234, 44, 93,196,116,142,239,176, -133,184,133, 49,182,171,152,184, 91, 41,152,160,153, 34, 92, 36,252,109,155, 59, 51,151, 83,248,207,231, 57,236, 79, 48,143,119, -169,162, 69, 34, 42,234,195,221,131,225,120,168,130,158,159,231,102,116,133,145, 29,134,132,196,121,215,111,245,181,214,118, 62, - 11,141,102,193, 69, 41,153,223,251,233, 96, 36,139, 76,153,208,220,247,172,166, 35,184, 52, 90, 19,188, 66,138, 7,113, 30, 42, -133,176, 58,141,204,235,225,193,225,243,147,147, 15,103,111,109, 62,165,104,131, 89,171,199,179,255,184,254,249,230,221,217,224, -234,235,163,163,163, 23,167,167,189, 94,239,203,213,247,225,104,170,181,104,103,105, 43,147,141, 58, 65,112,254,248,248,120,112, -121,249,107,120,179,119,111,207,249,244,252,243,224,233,147,103, 47, 95,189,222,223,127,208,239,116, 63,158, 95,104, 92,143,110, - 45,144, 44,224, 96,208,140,165,146, 98, 73, 90, 19, 13, 35, 90, 70, 53, 51,217, 54, 9,133, 22,122,222,177, 5, 61,129,252,216, -164,244, 49,193,126,139, 47,212, 82,105,155,219, 25,146, 37,193,229,114, 57,240, 91, 95, 66,232, 87, 40, 0,235, 68, 35,252, 48, - 77,141,148,132, 43,208,249,191,118, 37,255,227,145,138,148,170,114, 91, 76, 28, 56,112,232,219, 25, 72, 91, 23, 89,218,168,167, -141, 2,124,231, 45, 73,125,215,116,103, 43, 90,193,106,147, 76,249, 86,149, 72, 26, 53, 17,183,173, 40, 72,101,109,130, 38,239, -130,119, 22, 81,192, 44, 8,226, 9, 59, 42, 95, 88, 1,119, 95, 17,210, 4, 15, 27,120,236,182,113,111,145, 58, 16, 57,123, 81, - 70,136,206,135, 73,140, 7,235, 41, 74,244,101,149,186, 71,116, 47, 79,138,128,236,242, 79,201, 27, 21, 76, 48,210, 68, 68, 81, -119,212,175, 36,225, 5,232,182, 82, 4, 98,123, 18, 84,122,124,146, 61, 23,169, 93, 37,121,137,236,120,100,250, 28, 3,130,186, - 85,198, 26, 0,171, 52,106,188,122,132,204, 77,225,173, 10, 99,222,221,222,142, 45,108, 88,179, 74, 41,221, 28, 78, 63,143, 61, - 21,224,242, 34,184,124,128, 0, 89,237,181, 1, 11,203,118,154, 29,170, 3,200,193, 59, 89,167, 86,111,140, 39, 55,132,236, 90, -213,238,239, 28, 92,124,251,196,180, 72,135,120,193, 18, 88,136,103, 48, 16,243,220,199,141,179,144,150,105,242, 37,150,213,254, -129, 13,246,247,173,115, 75,169, 57, 96,207,228,138,196,172, 93,111, 85,162,117, 80,212, 92,225,183, 20,181,107, 69, 44, 68,145, - 43,181,239, 70,137, 23,220,142,192, 93,254,133, 48,112,235,241, 91, 0,206,174,166,183,105, 32,136,122,119,227,245, 71, 62, 74, - 19, 74, 17,170, 90, 5, 10,244,128, 64, 28,225,192,129, 3, 18, 55, 36, 46,252, 91, 46, 72,220,138, 42,132, 16,208, 86, 10, 80, - 53, 16,210,212,137,235,196,137,237,101,102,118,215, 73,160, 5, 68, 14,150,229, 72,107,217, 94,207,206,188,121,239,249, 79,241, -157,255,162,131, 64,219, 32,221, 55, 39,195, 47,218, 74, 22,192, 91,148, 19, 59,156,230, 49, 61, 96,220,138,178, 82,180, 42, 81, -150, 57, 38,205,230,166,112, 65,136, 15, 10, 55,137, 12, 86, 89,147,193,101,127,245, 75,124, 68, 39,194, 8,143,172,109,109, 9, - 65, 25,187,137, 41, 74,179,113,137, 6,107, 18, 18,237, 47, 68,180, 92, 2,252, 96, 46, 76,166, 19,152, 89,176,132, 78,179,244, -230,250,246,105, 50,228,165, 86,154,105,163,187,162, 31, 15,144, 52, 75,186, 90, 24,105,115,109, 43, 73,207,132,197,111,224, 82, -147, 89, 66, 43,185,186,127,253,222,143,168,135,128,148, 18,189, 98,216,147,163,102, 24, 54,170, 94,232, 85,234,129,223, 92,113, -155,117,185, 90,247, 27, 97, 5,242,226,208,199, 96, 43,189,138, 47, 93,218, 81, 82, 20,119,239,220,114, 24,118,134, 15, 14, 58, - 14,247, 54,174,110,118,190,126, 83,232, 77,227,194,204,143, 70,209,251, 15,239, 14, 59,251,219,237,173,167, 79, 30,111, 92, 91, -239, 30,119,123,131, 97, 28,163, 47, 88,255,116,178,115,123,231, 36, 26,125, 62, 58,190,212, 88,185,209,110,191,124,245,250,209, -195, 7, 31,247, 63,237,238,189,125,241,252,217,238,155,189,110,247,123,158, 59,213,208, 79,211, 12, 86, 28,100,172,209,194,136, - 93,142, 28, 15, 40, 14, 37, 45, 11, 3, 71,184, 72, 26,131, 91,232, 10, 86,149,162, 22,242, 0, 86, 17,201,124, 15,202, 50,238, - 74, 6,201, 3,148,182,196, 22,206,202,248, 94,218,165,150,220, 69,152,226,158,235,101, 75, 57, 41,254,213, 10,175, 64,124,156, -169, 44, 16, 65, 70,234, 30,126,177,185,227,127,199,119,233,200,156,188,136,216, 95,116,176,170,130, 64,173,171, 8, 18,165,150, - 15,214, 38, 68,220, 58, 31,189,209, 66,240, 5,168,199, 80,108,225,114,200, 91,171,176,111, 35, 35,240,189,208,214,163, 11,160, - 78,249,234, 22,133, 21, 7,232,113,242, 98,182,220, 60, 96,220,102,238,205,176, 53,153,141,169, 93,137,196, 83,221,168, 21,206, - 57, 12, 81,216, 86,189, 26, 61, 16,194, 10, 9, 60, 43, 84,153, 74,114,182, 44, 73, 81, 86, 57,191, 16,217,109,112, 87, 6,153, -177, 9,254, 92,193,164, 73, 42, 21, 45,227, 64,182,172, 96,198,106, 70, 24, 17, 56,210, 45, 17,177,209,150, 82, 20,226, 29,163, - 86, 44,173, 11, 48,123,131, 90,148,147,210, 2, 71,160,125, 81, 46, 6,112,206, 56,141,117,219, 48,215, 22, 96,216,248,209,182, - 4,112, 19, 72,205, 88, 24,185, 58,132, 65, 75, 81, 84,250,187,237,227,105, 2,193, 29,107, 78,206,171,178, 22, 37,131, 86,109, -109,116, 22,157,196,253,113,154, 80,233, 79, 21,129,197,223,169,105,103,104, 0,122, 30,167,179,180, 88,206,223,157,185,147, 18, -215, 86,207,150,160,199,200,124,201, 28,128, 97, 8, 84,113,202, 16, 71, 98,151,169, 86,228, 89,201,177,113,187, 42,230,235, 5, -251,157,174,179, 92,251, 58,206,130,237,232,191,171,190, 47,250,253, 20,128,180,107,105,109, 34,138,194,247,220,185, 51,147,116, - 82,234, 19,171,213,180, 32, 10, 10, 46,170, 46,164, 80, 23,130,238,138, 43,187,115,161, 43,197,255, 39,184,180, 96,125, 81, 53, - 8, 69, 20,139, 15, 84, 12,149, 54,113, 38, 51,153,201,204,245,158,115,238, 76,166, 82,171, 96,146, 85, 18,134, 9,185,247, 60, -190,239, 59,223,253,123,124, 31,255,102, 75,248, 0,207,166, 81,191, 6,129,211, 26,145, 52,132,224,120,139,123, 56,214,142, 6, -192,142, 93, 73,130, 59,120, 68,159, 85, 83, 68,190, 75,107, 91,225, 41,183,233, 54, 38, 92,127,210,159,252, 62,248, 49,202,135, - 12,149,229, 58, 47,255, 89, 59,112, 64, 49,159,215,129,144, 5,151, 30, 22,104,151,246, 37,120, 94,186,225,122,243,237,249,141, -205,247,102, 73,245,162,109,193, 44, 15,173, 93,199, 58,191, 43,170,176, 29, 42, 58,144,223, 55,205, 29, 32,199,203,170, 49,210, -201, 72,224, 64,217,139,250, 67,157, 81, 77, 3, 95, 27,221, 86,160, 14,152, 14, 48, 80, 65, 67,237,159, 82, 19, 77,197,222, 26, - 26,229, 14,114,148, 33, 11,145,164,168, 62, 65,161,116, 14, 89, 10, 11,151, 22,159,175,117,206,156, 58,183,246,242,205,209, 35, - 51,183,111,222,186,255, 96, 37, 74,244,144,224,239, 36,209,113, 92,124,249,182,249,248,105,231,197,171,245, 99,211,199,151,150, -174,207,206,204,126,252,220,221,250, 25,154, 28,115,178,125,162,213,244,223,190,251, 96,186,215, 11,231, 47, 62,124,244,100,174, - 61,231,122,141,149,213,103,158,231,223,187,115,247,242,194,226,242,141,229,171, 87,174,117, 94,175,111,124,234,198, 72,115,235, -193,176, 8, 7,163,126,156,135, 81,214,139,178, 56,214,209, 64,152,196, 71,195,222,133, 66,245,142,192,250, 93,177,252, 66,166, - 41,122, 73,166,195,180,223, 79,152,243,200, 11,224,248,110,250, 18,211, 18,113, 12, 18,214, 90, 19,247, 34, 47, 60, 79,250,128, - 41, 23, 87, 44, 38, 69,106, 81, 71,214, 52, 6,246,192,184,119,117, 11,128,127,240, 48, 48, 13,146,175, 80,104, 90,252, 65,198, - 38,109, 73,181,207,196,235,242, 59, 21, 39,100,247,149, 35,148,222, 57,124,168, 76,250,115,124, 78, 3, 78, 13,174,212,140,213, -212,130, 59, 51, 81,167,167,207,134, 73, 72,170,100,248, 93,107,179,103,223,162, 5, 11,151,236,205,164, 25,138,205,120,130,131, -189, 10, 97,199,133,228, 24, 71, 7,145,161,168,166,168,200, 94,141, 35,103,210,212, 18, 4,153,214, 7,107,199, 24,125,233,159, - 96, 7,145, 68, 25,220, 53,219,184,142,139,119,230, 72, 89, 54, 67,254, 46,244,169,164,100, 67, 85,145,182, 46, 74,146,119,158, - 77,127,170,218,121, 92,194,147, 83, 5,159,225, 64,136, 13,153, 8,160, 42,216,113,129, 15,118,176,222,147,108,255,104,163, 95, -101,141,129,153,145,180, 91,100,241, 75,207,220,250,196, 86,132,116, 73, 27,160,227, 99,150,108,135, 91,166, 56,207,112,218, 53, -137,147,216, 92,131,207, 49, 32,157, 0, 30,127, 96, 79,115, 16,197, 88,185, 75,244, 16, 0,212, 20,135,182,240, 68, 60,130, 2, - 14,128, 20,181, 28, 95,212,103,193,240, 13,167,178, 4, 98,157,255,161,224,112,156,197,146,225,232, 18,203, 49, 61,243, 84,112, -112,144,134,117,159, 11,189,219,100, 31,212, 6,157,254, 63,184,155,199, 47, 1, 24,187,154,214,182,129, 32,186,210,234,203, 73, -145, 27,219, 13,105,192, 7, 67,211, 30, 2,133, 66,207,201,239,235, 31,233,181,244,152, 67,161,237, 31,104, 15,166,105, 74,105, -112,161,216,212,137, 99,203,118, 34, 75,187,154,238,204,172,100,153,226, 16, 48, 6, 99, 35,100,118,244,102,118,230,189,183,222, -195,233,201, 80,243,251, 37,242,147,201,225,190, 7,178,160, 13,160,164,186,195, 68,131, 98,103, 45, 1, 10,117, 52,142,103,112, -216,186,107,218,168,173, 44, 76,217,197, 51, 51, 47,110,183, 23, 38, 1, 22,157, 40,190,204, 19, 84,151,101, 43,218, 22,107,238, -206, 17,151, 3, 47,107, 74,114, 95,202,228,118, 6,188, 58, 46,115,174,241, 77, 21,108, 45,160, 76, 60,165, 69,250,245,247, 23, - 50, 73,244, 41, 40, 75,255, 25, 76,215, 68, 9, 43, 27,241, 30, 11,170, 77,105,142,165, 40, 71,188,219, 8,221,222,147,222,249, -240, 66,160, 16,212,203,117,142,210, 90, 71, 14,228, 72,161, 45,175,143,169, 0,141,244, 32, 87, 78, 88,181,240, 37, 54, 46, 19, - 3,171,202,252, 53,103,169,116, 16,160, 5,166,193,140, 56,110,245,251, 63,143,158, 29,191, 56, 58, 62,251,244,121, 48,120, 51, -153, 47, 27, 65, 96,110, 55,144, 94,216, 8, 59,237,199,251,157,118,183,219, 61, 60,124,218,106,239, 53,227,189,211,147,158, 73, - 21,111,223,189, 79, 22,233,143, 95,127, 94,191,122,153,220,102,233,229, 48, 75,179,131, 78,167,127,254,237,121,175, 23,133,193, -217,135,143, 6, 18,174, 38,215,227,241,228, 38,153,253,189,158,174,104, 60, 26, 40, 29,250, 62,243,125,232, 73, 70,175, 30,178, -164, 71,248,114,136,200,126,151,225,174,149, 79, 55, 48, 32,152,229,197, 42,215,145,217,146, 9,174,162,112,162, 65, 58, 50, 64, -197,176,158,214, 35, 4,214,194, 82,145,217,201,143,243,191,180,186,176, 3,246,173, 4,112, 42,126, 93,125, 47,151, 50, 14,227, -249,166,228, 53,215,169, 73,162,174,216, 16,185,193,134, 80, 8, 63,206, 87,211,234,113,170, 44, 21, 13,208,104, 50, 32, 67,189, - 49, 90,200,173,205, 47,145,143,173, 51,185,118, 92,168,136, 49,214, 45,182,228, 4,219, 38,236,197,232,187,192, 42,222,173,137, -105,161, 6,206, 5,125,235, 25,188,168,192, 28,172, 73,157, 45,199,203, 38, 15, 48,216,133,126,164, 85,206,167, 5,212,208, 29, -202, 3, 68,236,149, 93,123,135,182,217,200, 64, 78,199, 24,108,223, 17,185, 53,105, 19,107, 63, 80, 66,110,231,186,124,176, 7, -111,173,203,172, 0, 22,130,209,197, 5,128,127,192, 5, 59,233, 17,133,205, 67, 64,211, 77, 97,135,174, 22,220, 93,182, 30,177, - 12, 28,233,121,108,207,135,245, 82, 57,201,164, 73, 26, 93, 83, 10, 81,121, 98, 32,166,187, 2, 79, 46,144,230, 73,118,168, 75, - 3,150, 38,183,214, 71,144,108, 3, 53,127, 10,203,196,253,214, 65,228,239, 12,174, 6,139,124, 73,220,101,104,238,182,198,179, - 17,119,116, 89,143,136,202, 37, 75,122,135, 50,128,177, 5, 0,101,198,167, 52, 67,138, 56, 1, 59,225,163,184,209, 28,221, 12, - 65,108, 88, 95, 75,100,255, 84,139, 75, 22, 83,181, 2, 31,185,103, 58, 37,127, 75,187, 12,187,232, 19, 57,205,116,122,183, 88, - 57,150, 77,178,149, 62, 95,151,107, 20, 15, 6,247,251,133, 78,255, 4,160,236, 90,122,155, 6,130,176,119,237,120, 19,215, 10, -162, 84,161,129,166, 7,144,106,169, 84, 92, 56,113, 64,192,129, 43, 66,156,185,112,224, 7,113, 68,252, 20, 46,168,160,138, 22, - 81,169, 17, 72,125,241,136, 8,105, 21,104, 20,226,168,241,123,217,153,221,181,157,166, 66,224, 75, 14,113,226, 56,222,121,236, - 55,223,124,243,143,250,192,124,182,155, 67,172, 13, 96,159, 64, 64,198, 7, 6,125,240, 38, 16, 96, 16, 74,193,126, 63,194,149, - 51,151,136, 59,205,139,111,100,138,112, 4,227, 47, 66, 16, 9,227,176,161, 35, 85,225, 37,151, 23, 90, 7,189,189, 20, 54, 65, -169,132,222, 21,133, 22,154,236, 39, 81, 66, 16, 78, 53, 36, 39, 82, 87,254,193,151,123,139,222,110,111,119,117,121,229,176,119, - 32, 41, 49, 69,217, 76, 5, 24,243,250,226,181,238, 73,151,114,153,206, 64,248, 49,181,178,130,183,228, 29, 13,142,253, 96, 20, -165,233,254,209, 33,108, 75, 77,132,251,169, 97, 19,115,144,140,125, 55,166, 17, 19,190,225, 84,220,225, 36,101,160,115,154, 37, -140, 34,197, 11,110,222,177, 45,241,250,236,233, 19,167,230, 62,127,241, 50, 20,238,223,160,243, 23,234,226,253,147,225,112,115, -243,195,131,123,119, 95,189, 94,111, 52,175, 92, 92,104,188,223,110, 95,170,187,247,239,220,126,252,232,225,234,205,181,126,191, -255,110,227,237, 78,187,253,249,107,103, 52,246, 39, 65, 28,194, 64, 35, 94,173, 88,189,227,174, 91,187,213,152,119, 87, 60,175, -213,186,218,108, 94,222,249,248,169,243,189, 51,231, 50, 70,233,250,198,155, 56, 78,196, 82,141, 50,226,176, 74, 77, 50, 25,208, -200,170, 34, 29,181,192, 22, 19,240,134, 4,201, 4,233,169,248, 85,156, 8,151, 45, 44, 72,228,239,226,100,102, 19,219, 52,156, - 10,169,215, 88,154, 88,223,116, 42,133, 90,170,168,193,167,140,111,234, 16,151, 10,227, 64,230,113,252,108,243, 77,177,128, 25, - 76,210, 9,104, 17,218,103, 23,104,241,217,115, 29,253, 40, 28,205,122, 42,146, 59,171, 66, 48,139,231,222,156, 23, 50, 0, 70, -217, 33, 50, 64,171,161,211, 12,139,200,128,210, 88,212,134,109, 59, 48,122,121, 73,113,174, 64, 81,132,207,154, 3, 77,133,223, - 88, 73,226, 58, 78,128,116,162,252,238, 28, 11, 34,170, 57,133,151, 38, 58,153,153,100,220,232, 54, 82, 90, 50, 73, 82,234, 63, -146, 23, 78,147, 80,206, 55, 40, 39,239, 18, 32,214,120,139,162,121, 72, 44, 38, 7,110, 68,252, 37,249, 93,254,205, 19, 20,130, - 98, 84,170,249, 42, 70,178,230,216, 80, 45,246, 46, 21,116,177, 39,144,230, 32, 50, 85,163, 0, 48,143, 87,173,221,170, 48,203, - 13,165, 82,160, 88,146,134,170,181, 82,220, 49,235,202, 23,197,123, 73,193,110, 49, 41,203,228,102,159,160, 36,175, 56, 19,135, -216, 64, 75, 95, 34,123,196,157, 74,245,198,210,218,214,151, 45, 85, 3,204, 52,136,193,101, 44, 5,248,246,199,175, 46, 69,238, - 62, 46, 88,152,241, 52,240,127,170, 65, 96, 74, 97, 56,195, 11,234,198, 93,165,151,199,165, 0, 31, 87,172, 95,116, 39, 8,253, - 70, 81, 52,204,134, 58, 54,168,193, 68,242,153,154,231,185, 92,205,106, 37,227,192,159, 98, 13, 36, 33, 81, 79, 9,254,201,108, -202, 2, 10,147, 57,179,199,205,254, 51,115, 23, 75, 58, 45, 13, 62, 43, 31,127, 4,224,236,234, 86,155, 8,162,240,206,206,236, -236, 38,187,217, 36,196,132,210, 90, 66,241, 5,188,243, 7,139, 88,181,224,155,136, 23,190,152,130, 47,160, 86, 8, 18,170,130, - 5,175, 68, 47,138, 52, 87, 90, 77, 91, 55,217,236,236,116,157,115,102,102,119,155, 6, 5, 33, 55, 73, 8,204,110,118,206,153, -115,190,159,179,236, 47, 70,106, 62,115,110,137,208, 91,144,213, 38,118, 36,119, 32, 15, 53, 98,109,141, 1,115,224, 74, 50,102, - 79,201, 6, 92, 46, 92, 35,255,119, 76,254,198, 42,198,213, 90, 36,149,224, 57,229, 30,229, 13,198,219, 60,140,253, 6,103, 92, - 56, 98,114,118, 52,253,125, 2,152, 24,146, 4,119,175, 63,250, 50,249, 12, 40, 37,230, 93,236, 27,200,192, 15, 49,199, 72, 35, -150, 70, 61,155,198, 1,225,184, 45,212, 25,119,129, 98, 57,128, 73,241,156, 80, 48,108,172,171,213,156,130,206, 30,222, 82,195, -234, 37,215, 6, 91,105,150,170, 63,115,154,252,210, 54, 67, 84,115,108,105,109,192, 84,225,188, 91, 28,249,140,171, 12,158,195, -164, 28, 85,188,184, 1,119,213, 7,170,246,108, 6,196, 99,240,192, 10,225,100,153,124,242,248,233,173,237,157,231,207, 94, 44, -178, 76,229,186,173,225,230,230,213,141,189,209, 88, 45, 97,247,193,253,151,123,111,239,221,217, 94, 95,223,120, 61, 26,171,107, -250,122,248,109,188,191,127,240,225,227,241,247, 31,113,220,234, 15,186, 30, 7, 39,131,217, 60, 97, 84, 70, 45, 96,188, 20, 50, -127,184,115,247,246,141,155,107,253,181, 87,111, 70,239, 15, 62,165,153,152,165, 51,220,143,160,119,189,210,241,186, 29, 63, 14, - 73,212,228,145, 15,144, 41,100,172, 2,220,199, 60, 36, 64,120,142,209,202, 2, 68, 12,155, 10,238,138,200,114,154, 23, 42, 31, - 12, 88,163, 31,168,208, 78, 58, 14, 61,156,156, 30,159,205,181, 41,252,185, 22,155, 97, 85, 27,250, 33, 98,146,117,131, 34,176, -247, 81, 55, 72,174,246, 20, 51,207,146,118,247,229,110,128,199,168, 98,165, 86,251,178,245, 45,249, 55, 99,157, 44, 49, 17,151, -126, 23,249,177,148, 34, 10, 98,145, 11,189, 63,177,172,204,173,103,142, 90, 60,131,138, 19, 24, 62,210,128,254,166,103, 74, 72, -197, 63,129, 21, 11,148,179, 94,148,109, 47,203, 17, 75, 54,176, 38,236,167, 32, 47, 34,151,201,234, 23, 42, 12, 82, 13,129,211, -188,144,115,123, 89,180,174, 72, 34,213, 32, 24, 29,220,169,101, 46, 87,244,152,234, 69,254,250,114,172, 25, 12, 49, 12, 5,109, - 32, 99, 92,218, 13, 24,165, 71,118, 96,153, 75,173,111, 1, 88, 79,187,214,128,213,152, 12,150, 45,123,235, 34,137,109,119,116, - 11, 35,204, 4,119, 2,222,176, 84, 99,170, 46,154,168,226,222,234, 69,221,184,217, 74, 22, 73, 57, 57,170, 82, 51,104, 74,188, -163, 79,136,249,207,228, 4, 3, 37,177,214,189, 22,193, 36, 78,101, 28,139, 90, 39, 61,160,169, 48,148, 47,120, 48,144,100, 45, -135,189,225,116, 54,181,129, 92,215, 34, 54,170, 90, 27,217, 82, 17,169,167,248,169,184, 17,135,237, 76,136, 74, 25,233,144, 85, -221,141, 50, 23,219, 26,139,144, 26,155, 88,150,210,145, 78,163,151,230,243,229, 89, 8,208, 12,148,182,231, 73,254, 15,142, 50, -161,114,213, 87,127, 4,160,236, 90, 86,163, 8,162,104, 85, 63,167,199,113, 34, 38, 8,130,171,184, 15,113,103,240, 15, 92,184, -208, 32,248, 77, 46,197,191, 48,130,139,136, 10, 42,146,133, 15, 4,191, 64,197, 4, 12,102,200, 76,102,210,239,169,135,247,222, -170,234,238, 25,135,128, 3,153,197, 16,154,238,174,170,123,111,157,186,231,156,139,234,247,166,115, 57,137,250,200, 43,195,158, - 25,243,124,232,241,166, 57,145,200,185,234, 5,189, 26,229,247,101,128,172,203,144,153, 78, 38,174, 98,205, 37,183, 14,111,164, - 34,217, 24,149,105,114,123,241,125,119,126, 15, 99,112, 46,196, 80,177, 53, 4, 37, 67, 58, 62,241,123,113,127, 86,206,160,198, -124,243,237,149,116,173,238, 38,183,225, 0, 16,184,166,152,229, 59, 80,192,194,180, 50,201, 78,225, 6,171, 26, 89,157,166,171, - 53,240,195,135,119,238, 63, 59,216,179,144,171,103,142,125,232,196,137,166, 35,252,215,225,232, 16,141, 50,144,189, 97,183,216, -232, 89,199,120, 14,227,193,233,208, 88,243, 99, 57, 85, 49,131, 90, 56, 78, 2,152,185,146, 98, 37, 10,235,248,150,200,139,168, - 78,130, 9,173,200,216,147,167,143,175, 94,217, 72,179, 73, 24, 33,161,227,250,181,245,233,217, 4, 98,205,246,214,214,207, 95, - 71, 89,145, 62,223,127,249,224,222,221, 65, 63,129,199,170,231,242,232,247,232,207,241,201,135,143,159,214,215, 46,223,220,188, -177,179,115,123,119,247, 81, 58,157,190,123,255,250,237,193,103, 33,234,188,202,247, 94,236, 79,102, 41,148,246, 85, 53, 39,247, - 19, 68,246,153,135,175, 29,222, 88,154,169,192, 83,144,143,162,144,104,101, 10,226, 41,228, 91, 40,177,145,252,129, 6, 41,154, -197, 86,160,217, 27,134, 65, 31, 22,161,102,121, 84, 68,138,165, 98,254,227,100,156, 9,113, 86,148, 92,198,165,200, 48, 14, 10, -179, 95, 54,101, 15,254,201, 5,226, 42, 29, 48, 34,208, 19,117, 17,240,127, 90,221, 27,224, 82,215,170,236,134,197, 37,249,108, -125, 97, 63,251,170, 13,105,151, 94,205, 33,148, 23, 85,102,142,115, 27,170,145, 81, 49,115, 58,207, 36, 28,196,120, 18, 67, 76, - 73, 57,133, 16,231, 82,210, 26,239,194, 32, 14,162, 97,138,168,142, 37, 59,120, 11,161,185,173,184, 23,246, 40,244,117, 41, 76, - 74,130, 86,224,194,147,124,220,110,227,219, 50,205,235, 70, 4,186, 22,102,147,237,205, 91, 95,191,127,241,169,150,165,200,165, - 58,188, 1,131,100, 64, 52,220, 24,167, 35, 31,125,189, 8,185,215,206, 19,210,196, 29, 82, 5, 88,189,128, 81, 38,215, 61,156, - 43, 28, 29, 94,172, 29, 73,213, 5,107,235,214,106, 49, 26,191, 43, 28,168,173,209,129, 1, 56, 60,214, 58, 16,154,174, 22, 67, -101,167, 61,177, 54,230,201,102,173,249,198,176,201, 44,186,118,208,160,130, 17,140,182,236, 4,180, 98, 96,198,115, 92,101,186, - 37,240, 82,146,160, 82,200,188,213, 60,199, 90, 77,178, 70, 9, 82, 35, 89, 87, 17,174,104,154, 61,181, 39, 57,189,101, 82,237, - 81,186,241,103, 54, 57, 12,126,136, 3,116,149, 25, 4,253, 82, 84, 66,214,218,154,112, 26,185, 29, 88,228,176,140,148, 57,100, - 37,246, 33,246,188, 65,238,161,170,146, 55, 16,143, 3, 33,148,131, 37,218,148, 13,183, 61,128,169, 85,158,115,238,242,144,155, -252,116, 23,106, 90,156,106,171,189,138,115, 47, 32,121,190,149, 34, 75, 75, 18, 52,255,229, 82,185,244,249, 43, 0, 99,215,247, - 26, 53, 16,132, 47,155,236, 93,146,163, 45,180, 22, 65, 31, 44,138,130, 79, 22, 65,255,231, 82,241,185,248,238,155, 8,138, 15, -214,135,226,111,148,114,245,106,239,146,236,109,178,235,124, 51,187,185, 84,165,250,124,129,228,102,119,103,103,190,153,249,190, -127,227, 51,244, 41,166,109, 88,160, 2,114, 62, 50, 55,223,162, 18, 5,196,112,110,127,220, 40,110, 82,188, 88,117, 43,197,249, - 60,121, 13, 76,177,122,225, 85,160,235, 26,198, 97,214,124,153,191, 16,126,138,152,200,121,105, 86,201, 88,243, 26,129,192,194, - 86, 12,186,216,173,124,251,188,153,167, 48,112,167,177,173,125,164,106,193, 65,109, 16, 72,122,110,161,117,220, 4, 31,176,200, - 80,112,141, 60, 73,180, 44,109,107,158, 60,127, 10,156,141,247, 13, 87,168,240, 88,161, 39,166, 53,120,119,172,245,210,178,129, -111, 29, 6,237,182,203, 45,157, 77, 62,206, 62,241,233, 65,103,216,153, 94, 92, 27,231,101,174,167,185,206, 50,112, 49, 82, 98, -160,179,145,214, 94,234, 83,194,251,135, 96, 87,233,151,175,143, 91,123,108,186, 36, 33,103,108,205,116,115,247,253,231,211,177, -206, 31,237, 63, 60, 56, 60,228,217, 44,119,119,111,239,250,206, 70,219, 89, 58, 1,150,243, 66,138,180,239,221,191,243,248,193, -254,102, 89, 60, 59, 58,122,251,238,228,235,183, 47,203,186, 86,172, 83,243,226,213, 27,107,219, 44, 77,139,137,134, 74,170,197, -220, 7,153,162,162,171,148,199,229, 40,104, 42,114,120, 9,178,201,100,130, 48,205, 41, 7,246,224, 17,192,165,105, 73, 49,125, -210, 53,160, 54,155, 45,205,247,179,249,210,218,139,202, 53,116,237,120, 19,244,207,224,170,171,160,171,192,192, 49,164, 48, 48, - 39, 12,243,214,180, 52,131,122,163,156, 28,233, 91, 87,127,236,185,114,188,177, 88,253,228,174,131, 36,137, 34, 56,195, 73,253, -161,142,135, 28,218, 20,115, 28,174, 15,240, 19,198, 82, 88,182,201, 95,177,165,195,149, 12,209,182,140,125,107, 44, 48,242, 5, -239,124,107,108, 19, 14, 32,162, 72,189,162,196, 46, 34, 48, 62,206, 82,174,133,233,188,187, 96, 28,166,135,128,200, 47,180, 80, - 47,247,129, 70, 38, 73,134,194,238, 17,200,192, 5, 86,217,154,219, 34,179,206,247,189, 24, 65,154,252,214,238,237, 15,167, 39, -201,192, 35, 4,174, 12,156,120,103, 76,163,250, 62, 98, 50,233,101, 14,215,222,110,185, 46, 40,156, 76,179,224,126,163,103, 87, -204,228,242,183,249,128,161,170,158,188, 76,242, 36, 21,137,195,124,164,124, 20,137,157, 72, 62,163, 2,243, 6,167,217, 12, 81, - 11,237,159,156, 88, 63, 28,158,146, 11, 42, 94, 6,146,133, 72, 0,171,250, 89, 39, 81, 85, 14, 67, 81, 1,131, 86,169,175, 87, - 21, 45, 54,204, 5, 14, 83, 32, 51, 50,191,158,178,139,167,232,130,158, 7,102,203,136, 14,192, 24, 32,169, 42,254, 77, 39, 18, -125,208, 24,115,191,229,112,177,112, 42, 83,178, 10, 73,254,124, 49,227,166,254, 81,189,170, 71,131,165, 12,252,239,120,154, 55, -185,139,145, 58,212, 58,153,139,132,139, 15,252,179, 68,150,108,180, 75, 13,174,241,133, 80, 83,112,235,142,193,100,157,169,246, -233,102, 6,199,141, 41,114, 97, 54,228, 38, 28, 59, 12,110,122, 21,192,244, 74, 23,255,255,178,198,191, 4, 32,236,138,149,155, -136,129,168,180,146,238,236, 11, 38,182, 19,146, 20,161,130, 6, 26, 10, 26, 10,126,129,142, 79,165,226, 15, 24, 10, 40, 24,140, - 73, 1, 4, 38,133,141,157,140,115,246,157,101,233, 14,237,174,238,198, 14, 36,148, 25, 79,206,231,145,180,218,125,251,246, 61, -125, 27, 82, 39,121,186,185,125, 81,130, 52, 57,188, 74, 46, 43, 41, 92, 91, 97,167,235,201,105,247, 20,205,143, 92,101,145,150, - 15, 56, 82, 83,193, 58,196,122,146, 82,161, 54, 40, 86, 95,113, 7,240, 16, 41,230,239,216, 79,215, 66,167,160,187,152, 77,194, - 34, 36,170,110, 25, 54, 3, 10,239,209,152, 43,181, 91,248,126,175,137, 42,172,144,144,199, 84,223, 8,163,197, 83, 70,241,136, -155, 62,209,124,151, 55,226,126, 54, 48, 74, 47,109, 78, 50,103,200,180, 15, 15, 78, 64, 31,247,143,174,242,203,199, 39,143,190, - 94,140, 13,232,167, 15,159,140,206, 71, 40,216,111, 76,168, 84,166,215,179, 40, 26, 73, 73,205,247,114, 34, 31,248,161, 73, 19, - 45,162, 75, 13, 96, 67, 50, 60,115,109, 81,209, 34, 81,194,201,202,109, 4,170, 14,160,122,151,162,217,140,176,226, 54, 51,112, - 52, 28,156,157,141, 95, 60,127,118,112,120,239,228, 56,123,253,234,165,119,240,101,252,201, 58,151, 11, 10,200,116,233,148,249, -234,205,187,247,111, 63,126, 8,101,192,226,186,180,133,239,119, 59,189, 44,237,117,196, 96, 79,163,121,119,165,195,109,134, 24, - 58,202,175,129, 13,129,199, 85,138, 86,198,160,252, 36, 46,193, 6,199,107,235,174,134,251, 29,147,105,133, 87,152, 7,239,212, -197,100,177, 40,221,108, 89, 22,228, 80,140,181, 21,225,129,180, 41, 43,182,245,168,176, 34, 72,216,197, 24,175, 58,217, 30, 5, - 33,119,161,143, 91, 68,142, 98,156,180,194,167,149,223,136, 58,109, 20,162,183,133, 13, 16,182, 6,236,198,223,176,231,230,153, - 17,215,148,121,225,207,194,175,254,254,158,104,181, 67,231,141,141, 98,194, 66,172,108, 30, 94, 56, 51,189, 21,249,243,181, 34, - 77,219,236,227,176, 61,200,113, 92,208,128,133,223,125,110, 88,193,148,208, 39, 78, 82,235, 80,246, 57,239,104,132, 85, 59,132, -119,120,214, 2,143,101, 55,233, 28,244, 14,127,206,206,135,123,195,249,114, 78, 84, 81,131, 17, 73, 18,140,143, 26, 69,208, 6, - 83, 38,126,253,152,126,131, 45,165,248, 86, 8,146,210, 19, 57,250,245, 25,120,190,187,174,254, 45,220, 38,229, 60,255, 13,209, -187,152,121, 47,117, 36,177, 72,214, 97,128,255, 74,182, 17,155,221,132,116,135,178,102,252,141, 10,154,115,132,205, 76,150,233, -150, 45, 21,141,187,107,130,236, 30, 5,121,192, 68,147, 51, 30, 26,151,244, 17, 11,191,138, 70, 51, 82,110, 11,209,196,129, 65, - 77,112,188,102,202,188,108,129,139,240,207,137,167,121, 35,230,240,132, 99,190,159,246, 47,139,121,164,173, 73,236, 90, 35, 56, - 72, 81, 24, 26, 7,212,104,125,215,100,199,138,248,219,254,134, 80, 11,215,102, 53,229,247, 4,165,150,155, 50,234,145, 83, 80, - 81,100,185,141, 48, 29, 71,143, 10, 65, 8, 80, 73,190, 94,196,160,143,139, 26, 50,158,216,165, 15,231, 4,193, 73,183,193, 9, - 82, 41,118, 49, 70,140,233,252, 62,133, 45,183, 17,184, 8,237,183,228,242,168,117, 19, 94, 14,145, 92,234,253,200,182,174,106, - 62, 21,173,109,239,221, 33,222,128,225, 89,138,187,173,137,255, 8,192,215,149,244, 54, 13, 68, 97,207, 56,246, 56,206,158, 84, - 74,171, 10,184,114,226,132,196,161, 55,254, 9, 23,126, 44, 18, 87, 4, 42, 84, 72, 20, 16, 75, 40,181,147,184,118,102, 50,204, -247,222,120, 73,160, 72, 81, 14,145, 21,203,242,204,155,183,124, 11,250,239,150, 78,230,206, 68,168,145,207,105,246,134, 20, 29, - 77,157,186, 83,201, 48,242, 80, 91,151,222, 84,139,100,206,121, 48,113,137,224,187,205, 13, 60, 62, 31,120,117,112,202, 14, 27, -103,204, 98,161,244,174,100, 28, 71, 42,141,210, 65,148, 74,138,189, 95, 54,159,239, 76,225,118,108, 86,100,154,165, 65,131,218, -183, 37,176,131,100,224, 34,152,173,149,237, 60,158,158,210, 6,166,194, 6,108, 82, 93,219, 66,162, 53,108, 32, 63,196,163,252, -105, 58, 9, 97,182, 33,220,171,221, 22, 27,139,239,173,133,184,144,184,113, 39, 60, 26,244,246,116,118,166, 65,130, 53, 76,225, -230,123,185,199,201,195,141,118, 49,209,132,112,163, 46, 3, 99, 2, 66,198, 0, 93, 94,149,200,113, 93, 52,143, 99,184,147, 40, - 21, 70, 42, 80,177,132, 98, 65, 34, 93,128,126,246,244,201,155,119,111, 31,158,159, 47,151,167,147,209,116, 62, 63,153, 79, 96, - 50,121,121,245, 17,204, 59,204,164, 65,229,194, 66,223,139,108, 13, 91,225, 65, 26, 71,253, 36,211,230,199,122,123,125,179, 89, -229,229,186,218,233, 18,185,142, 36,209,117, 88,209,146,121, 21, 50, 44, 23,158,132,232, 7,114, 40,197, 44, 82,203, 56,237,237, -100,158,217,252, 54,122,255,253,246,242,107,241, 97,245,251,215,182,202, 81,116,112,131,141,137,193,150, 16, 53,123,230,247, 97, -148,109, 2, 56,163, 2, 78,230, 74,147,196,157,115, 26, 94,225, 94, 70,245,255,149, 34,222,142, 26,239,140,230,193,209,139,231, - 47, 95, 95,189, 26,134, 35,109,171, 46, 66,192,214,225,230,232, 76, 24,170, 49,177,138,188, 72, 89, 36, 34,235, 71,244,226,144, - 52,107, 85,216, 7,238, 5,166,143,238, 21, 69,194, 59,158,227,166,186, 81,251,162, 82,170,209,198, 96,101, 17, 18, 68, 34,199, -230,127, 24,238, 72,183,195, 53,217, 49, 34,240,185,216, 19,246, 8,245,104,199,201,180,216,173,217, 42,215,101,117,253, 56,117, -203,252,103,254,141, 64,141,119,188, 55,112,177,239,156, 11,234,174, 88, 91,215,232, 15,102,143, 92,205, 46, 15, 72,164,194,182, -156,215, 22,126, 94, 23, 25, 45,253,187,245,169,111,194,174,119,222, 0,138,116,212, 31,185, 5,225, 5, 26,239, 17,187,105, 0, -146, 33,205,169, 84, 47, 50,123, 77, 30,188,196,234,103,200, 23, 42, 63,172,253,152, 61,144, 41, 22,247,200, 64,134, 54,169,100, - 73, 15,154, 86, 5, 94,116, 0,215, 32,238, 75,214,122, 10,188,105, 19,245,217,201,247,195, 91,206,132, 4,145, 36, 75, 62, 22, -130,146, 33, 15,183,124,235,143,119,183,167,145,138,147,201, 60, 43,114, 26, 71, 16, 20,213, 75,182,225, 33,106, 1,185,189,111, -189, 81, 25, 64,136, 22,140,200,204,161, 44,146,187,239, 98,184,216,148,107,247, 47, 23,143, 47, 62,173,174, 73,192,152,139,175, -125, 67, 76, 13, 61,131, 19, 63, 67,234,201, 84,169, 74, 49,166,110,112, 58,146, 7, 1, 72, 43, 71,201,212, 69,255,218,152,184, - 99,238, 25,136,229,228,108, 91,174, 91, 29,159,131,105,102,171, 27,212,164, 26, 44, 6,119,196,123, 18,199,230,127,226,111,166, - 72,247,147,200,216,116, 76, 43,239,155, 90,253, 17,128,175, 43,219,109, 27, 6,130,162, 72,137,162,175,216, 70,144, 62, 52, 65, -209,255,255,148,246, 19, 10,180, 64, 31,130, 4,177,128,196,178, 36,235, 32,187, 59, 43, 9, 82,147,246,217, 48, 45,209, 60,102, -103,119,103,216,223,131,102,108,159, 29, 41, 44,197,158,137,231,169,177, 89,115,202,148,133,144, 78, 7, 5,156,174,216,108, 46, - 64,127,198,100,247,235,123, 40,118,181,172,165, 31,112,246, 40,238,144,129, 13, 71, 0,153, 16, 65, 90, 11,107, 45,214, 86, 67, - 16, 87,219, 93,182,221,103, 59,199,230,229,254,251,243,183, 62,234, 26,198,190, 45,247,161,128,205, 4, 19,220, 79,161,133, 28, -220,147, 21, 1,132, 50,144,186, 9, 70,132,141,104,244,100,112,171,134, 46, 15,114, 59,116,139,208, 32,244,233,193,221,212, 77, -201,105, 31, 10,215,227, 20, 18,163,154,215, 61, 10,155, 52,159,177, 1,228, 50, 55, 53,247,104,160,166,191,248,180,125,174,215, - 77,172, 18,103, 76,221, 5,155,208, 87, 2, 16, 52,243, 36,146,104,200, 44, 1, 67,159,104,100,175,184, 61,151,181,143,104, 26, - 30, 62,223, 61, 62,229,116, 13,212,157,151,140, 13, 65,100,163,141,115, 54, 47, 61, 65,254, 26, 71,233,149,213,191,212,107,213, -208,156, 58,155, 90,107, 44,133,175,198,191,149,109, 93, 53, 4,219,185, 86, 81, 43,199,170, 40,126, 3,173,121,231,227, 93, 98, -191,108,217,123,254,173, 13,165,239, 79, 85,115,174, 56,132,152, 28, 84, 99,184, 24,166,202, 93,186, 98,144,242,241, 52, 83,174, -234, 74, 15,215, 3, 54, 26,100, 49,226, 8, 6, 8, 17,123, 80, 66,142, 24, 90,123, 1, 88, 71, 14, 29,238,118,218,218,155, 75, -115, 94, 30,208,129,121, 97,138,166,253,224, 68,218, 70,189,102, 36,238,211,153, 12,145, 44, 40,163,109, 75,247,247,200,205, 76, -171,235,225,248,245,119,254,107, 28,208,187,100, 83,183,151,127,213,206,251,143, 64, 13, 97,133,214, 95,163,209, 79,113,149,174, -233, 85,235,174,148, 75,154, 2, 39,130,192,152,145,247, 85, 60, 65, 20, 2,194,232, 36,204,250,192,190,137, 39,251,217,104,112, - 9,160,183, 70,221,189, 45,175,151,165,224,215,224,246, 37, 15,150,178, 45,148,111, 7, 86,103,150,195, 27, 31, 27, 43,109,241, -251,116,153,187,212, 21,213,235, 84, 25, 57,223,119,178,218,193,108,134,209,158, 94,161,115,105, 97, 23,255,183, 75,247,180,109, -199,234, 28, 65,215, 26,201, 84,233, 7, 84,122, 70,164, 8, 42,130,252, 60, 24,115,105, 50, 71, 41, 49, 10, 64,164,226, 12, 14, -212, 67, 86, 98,176, 73, 8,232, 34,225, 19, 92,206,113,236, 56,165, 82,190, 44,164,103, 85,220,227,227, 65, 67,152, 43,151,252, -221,254,147, 49,250,199,211, 79,176,154, 93,195, 40,131, 21, 65, 58,223, 31,118,199,151, 34,175,155,107, 23,196, 90,155,161, 71, - 63,181,176,131,172,103, 86, 93,168,153, 56,204,149, 27, 2,103,197,244,202,110,242,203,233,184,190,165,120,174,168, 10,122, 27, - 10,221,232, 70,164,167,200,207, 47,172, 37,207,110,150,134, 34,182, 17, 98,243, 88,116, 22, 49,129, 3,210, 74,170,199,104, 13, - 31, 86, 7, 86, 45, 84, 44,169, 45, 1,148,159,229, 38,233, 89,204,187,191,120, 94, 3, 19,162, 5,162, 25,185,123, 9, 11,134, -251, 38, 90,106,139, 74,234, 32, 6,223,168,102, 94, 34, 31,142,255,255,110,139, 63, 2,240,117, 45,187, 77, 3, 81,116, 60,182, -199, 14,129, 86, 34,128, 64,233, 2,248, 17,126,130, 29, 95,216, 21, 63,193, 63, 32,177,132,118,209, 82, 81, 22,113,236,218, 51, - 30,238, 57,119,156,216, 41,170, 20,101, 97, 37,118, 50,190,190,115, 95,231,156,228,223,103, 37, 59,187,180,149, 44, 91,154,218, -161, 67,204, 66, 5,172,130,204,225,240,171,133, 41,222,173,182, 46, 43, 64,224, 16, 21,112,172,149, 92,210,155,192,107, 74, 22, -140, 13, 92,182, 72,112,193,231,245,202,186,202, 33,120, 7,131,115, 81,221,117, 55, 63,238,191,139,113,180,192,164,120, 14, 7, -166, 30,184,188,175,171, 23,237, 67, 67,144, 50, 91,248, 58, 12,144,240,168,150, 84, 32, 12,169,153,222,129,167,203, 22, 32, 2, -123,243,241,234,246,151,203,179,237,203,139,191,205,189, 60, 88, 98,130, 23,155,237,186, 94, 93,223, 93,193,191,211,226,229,247, -125,249,244,249,242,219,215, 68,140, 0,155, 19,119,138, 89,171,145, 69,154,177,236,111, 95,223,236,154, 92,146,129,169,238,104, -148,217, 82,123,119,112,154, 5,180, 54, 12,212,248,144,220,186, 18, 40, 91,128,128,108, 9,104, 4,131, 8,185,220,186,198,122, -185,210,122,111,127,239,123,201, 68,247,131,111,186, 97,215,246, 64,156,154, 80,178,186, 66, 9, 97, 88,110,219,245,100,152, 65, -174,208,245, 99, 94,149, 76,228,229, 97, 24,100,183, 40,188, 57, 71, 61,223,189, 61, 63,115,220, 91,236, 88,180,161, 1, 69, 39, - 71,195,216,197,135,200, 1,177,218, 98,142, 85, 23,154, 64,212,163, 55, 42, 94,108, 24,204,147,205, 3,119, 75, 99,171,200,129, -171,132,137, 15,201, 75, 4,179, 16, 33, 74,131,224,207,235, 51, 89, 15,137,152,100,155,223, 15,205, 20, 73,132, 19, 84,222,161, -180,114, 16, 62,204,141,243,102,224, 64,186,231,241,196,120, 46,247,238, 33,180, 75, 92,223,255, 51,208, 25,217, 81,174,103, 32, -162,164, 22, 39,211, 66, 77, 80,255, 66, 60, 70, 44,167, 34, 57,137,218,250, 48, 32, 63,255,176,205,236,226,114,241,216, 60,120, -106,216, 65, 69,127, 40,217,123,162,165,164, 61, 58, 87,148,226,197,178, 41,141,160,162,104, 78, 64, 79,124,196, 19, 57,137, 99, -164, 40, 62,110,158,189,218,117,205, 24,147,114,200,130,249,108,233,214,167, 98,191, 86,217, 25,151,197,152, 4, 48, 41,180,145, - 27,173,140, 27,198,215,169, 13,138, 96, 28,232,115,245,216,200,134, 77, 42,191, 43,249,132, 50,100,179, 17,154,150, 74, 25, 28, - 57, 80, 23,121, 6,176,228,193,173,163, 28,202, 27, 10,124,211, 76,113, 59,163,144, 14, 94, 25,199,117,201, 92, 45, 6,224,105, -133, 18, 29,202,201, 58,223, 13,163,135, 86, 1, 81,202,100, 10, 99, 97, 17, 90, 54,248, 46,103, 25,151,108,165, 90, 91, 96, 89, - 53, 16, 6,233, 74, 39, 87,223,245,123,157,197,128,135,198,211,224, 45, 16, 45,189, 4,151, 32,157,198, 84,101, 96, 15,118,212, -253, 91,142, 52,125,171, 1,246, 72,249, 86, 9, 54,181,195,145, 41,194,109,210,114,154, 89,224,163, 17,129, 84,155,209,148, 49, -139,203,164, 53,206,104,247,226, 17, 54, 49,111,183,152,170,172, 90,194, 9,227,169,247, 79,254,253,253,230,195,245,159,159,225, - 73,154,250,127, 2, 16,118,109, 59, 78,195, 64,212,174,237, 56,105,170,180, 32,202, 10, 16, 66, 60, 33,241,255, 63,194,242,130, -128, 71,164,221,133,210,221, 54,105,220, 92, 28,239,204,216, 73,154,150, 10,245, 37, 82,147, 38,109,199,227,185,156, 57,103,162, -207,199, 47, 4,189, 60,215,156,156, 10,151, 4, 41, 22, 22,166,144, 73, 82, 21, 3,121, 63,234,118, 19,191, 94,170, 85, 94,151, -198, 54, 2, 29, 58, 26,132,151,125, 0,207, 53,115,100, 86,142,118,120,165, 33,210,209, 50, 73,163, 52,149,177, 96,221,151,237, -173,105,242, 44, 93,110, 14,155,198, 86,216,117, 68, 25, 27,218, 59, 7,113, 26, 62, 14, 85,207, 66, 71,104,212,246,197,220,208, -145,101,249, 66, 16,231,177,136, 16,203, 8, 54, 7, 47,170,224,135,224, 2,249,116,185,198, 32,158,202, 56,109,183, 72,230,135, -170,132,119, 73,172,221,145,106, 79,187,154,191,220,150,143,144, 73,128,147,110,162,226, 94,237,143,152,155,144,196, 7,181,248, -153,243,131,114,129, 23,147,178, 90,169, 53,143, 53,238, 61,200,203,216, 33,229, 58,124,207, 8, 37,196, 33,198,103, 11,141,237, -155,166,226,251,131,200,177,232,131, 59, 9,184, 83, 83, 53,149,109, 43,107,231, 90,164, 26,233, 61, 32,133, 1, 51, 47, 13,234, -139,193,229,240, 76,166,129,205, 2, 83,135, 22, 9,147, 61, 5, 54,228, 16,181,169,170, 34, 71,182,157, 84,105,184,118,165,147, - 37,164, 70, 56,110,198,149,211,198, 22, 84,135, 65,216, 17,119, 18,178, 8,239,190, 61,145,155, 96,210,116,198,179, 54, 99,148, -110,109,170,179,178, 46,224, 99,125,244,238, 60,190, 97,226,170,130,236,100,162, 18,162, 80, 15,118, 47, 66,179,116, 50, 95,237, -174, 96,121, 41,240, 87, 62,205,100, 39,188, 40, 33, 48, 98,161,169,197,123, 85, 69, 92,126, 92,213,174, 98, 35,204, 27,159, 65, -226,109, 85, 18,197,121,181, 63,163,153,188,166,122,218, 99, 90,102,108,196,128, 96,131,253,102,249,246, 97,119,151,197, 43,136, - 6,190,223,125, 59,197, 34,123,122, 57, 37,117,211, 30,217, 80, 70, 57, 89, 25,252, 95,248,229,115, 82, 26,161, 8,120,218, 12, -133, 89,223, 70,186,246, 19, 81,251,115,226,223, 49,191,116,164, 55,217,251,119,242,190, 51,162, 92,237,219,203,189,220, 7, 21, - 80, 92,104,108,162, 2, 9, 85, 84,169,112,138,225, 24, 4, 34,196,191, 40, 57, 30, 83,176, 45, 40,157, 13, 50, 23, 30, 21, 41, - 66, 77, 91,216, 0,101, 69,228, 10, 24,114,221, 30, 3, 44,177,235,229,250, 24, 5,239,195, 2,100,130, 4,244, 2, 68, 50, 12, -195,178,224,235, 96,237,120, 62,106,138,205, 49,131,108, 41,120,111,104,229,225, 65,231,222,175, 63,252,188,255, 1,183,163,172, -119, 6, 89, 46,182,146,209,136,113,103, 16,164,205,212, 19, 12,162,153, 46,226, 20,124, 58,220,238, 97,247,135, 35,242,213,174, -211,181,233,142,187,242,105, 49,207,108, 93,195,147,230,102,255, 42, 91,111,138,223,159,222,124,254,250,235,214, 35,185, 41, 81, -109,223,189,248,248,104,254,250, 81,252,109,249,212,147,177,187, 46, 72,123,143,168,251,179, 17, 36, 62,120,224,222, 12,224,124, -200, 33,164,140, 48,166,228, 3, 87,245, 37, 60,120,252,235, 79,164,181,252, 8, 4, 27, 52,181,221,133,194,251,127, 49,242,254, -180,103, 1,248,186,186,222,166,129, 32,104,159,125,113,156,164, 38, 69,162, 68,240, 80,120, 71,202,255,255, 17,133, 63,128, 16, - 66,160,170,129,126,208,226,218,103,159,239,216,217,189, 75, 28, 19, 33, 85,121,105, 20,199,206,222,222,236,222,206,204, 36,191, -167,255,212,122,233,100,130, 45,180, 68,163,153,181, 98, 80,202,251, 51,143, 60, 50,122,174,242,179, 77,177,161,188,211, 88,116, -124,153,194, 58, 32,142,240,224, 40,145, 83, 0, 80, 18,166, 80, 40, 10, 13,215,104,141, 70,141,250,246,244,249,230,249, 6, 12, -143, 4,178,111,200, 96,162,255,239,133, 88, 44, 49, 23,197, 84,185,133, 34,174, 1, 8, 37, 31,108,124,233,123,129, 0,157, 99, -106, 81,242, 56,220, 76,149, 90,149,171, 55,213,235, 31,247,215,180, 11,109, 47,183,119,143,183,247,127,110, 81,130, 72, 33,138, -195,167, 96,234,200, 84, 32, 80, 60, 59, 10, 55, 69,153,110, 85,247,181,112,113, 81, 80,229,174,173,234,199,153,193,125,131, 50, -157, 74, 51,138,226,147, 22,133,220, 44,215,155,142,125, 59,216,196, 3, 2,102,153,164,167,129,221, 75, 9, 19,100,202,149, 69, - 65, 43,175,133, 58,198, 48,131, 10, 15, 18,107,231,187,214, 58,186, 77,237,117, 59,164,176,144,244,137,177,157, 49,150, 62,162, -200, 17,141,142,189,227,251,158, 96,142,167, 61,138, 30, 87,223,117, 4, 89, 58,139,191,166,177,191,155,190, 54, 24, 62,211,202, - 87, 89,161,172,158,165,233,122, 14, 52, 35,165,137,101,117,112,110,202,176, 36,153, 19,213, 15,244,110,224,181,141,142, 26, 85, -208, 92,197,138, 7,165, 15, 94,148, 46, 18,255,170,121, 85,155,122,143, 29,210, 41,229,122, 56,182, 33, 62, 13,113, 5,254, 45, -195,192,226,120,243,240,204,252,246,235,197,249,187,139,247, 31,191, 94,209, 79,127,177,124,245,179,222,149,122,201,160, 38,100, - 26,218, 30, 8, 31,212,124,166, 26,101, 73,255, 47,216, 55, 29, 61, 24,203,120,241, 17,253,254, 32,234,128,223,195,129, 45, 15, -104,231,121, 78,193,137,131,154,196,211,165, 91,251,188, 44, 94,208,243, 30,159,140,142,148,129,125, 50,181,234,150, 81,118, 92, -229, 37,143, 60,166,251, 53, 61,253,134, 42,168, 45, 5, 77, 63,117,240, 63,245,194, 97,136, 30, 26,225, 46,124,180,254,101,127, - 61,153, 87,247,172, 18, 32, 22, 14, 89,166,217,149, 24,152, 58,135,124, 16,189, 2,247,100,180,235,228,130, 75,152,189,138, 33, -201, 18,239, 21,123, 28,149,196, 10,128,214,138, 97, 31, 83,108,250, 3, 55,195,161,200,193, 77,116,172,143, 44,227, 73, 1, 57, - 77,197,231,241,210,204,246, 44,167, 56, 73, 46, 41,211, 50,177,130,235, 54,129,231, 78,154, 51, 22,138, 95, 3,122,179, 56,223, -132, 36, 36, 93,142, 0,206,135,203,237,167, 47, 87, 92, 21,137,130,129,223,172,223, 94,223,125, 23,114, 64,140, 64,148,163, 82, -113, 84,229,250,201,212,221,208, 10,129,137,109, 85,157,214, 5, 97, 56,110, 53,130,195,221,195,150, 82, 28, 42,177,102,233,169, -157,205, 43, 2, 10,187,135, 29,225,177,186,111,147, 48,225, 29, 49,206,209,239,235,198, 77,194,133, 94,152,193, 12,135, 48,144, -229,130, 65,206, 64, 22, 30, 3, 29,127, 76, 56,147,238,103,168,107, 93, 18,185, 26,242,239,170, 60,127,104,126, 73,247, 47, 61, -205,174, 58,209,177,145, 55,253, 21,128,176,107,217,109, 34, 8,130, 51,179,111, 59,107,227, 56, 78,148,228,150, 19, 23, 68,196, -129, 3, 95,207,129, 63, 64,144, 27, 8, 4, 66, 65,198, 78,252, 90,143,247, 49,116,117,143,119, 45,108,137, 40,135, 40,209, 90, -206,120,166,167,250, 81, 85, 93,124,215, 39,101,172,247,160, 36, 56,216,160,218, 59,163,225,135,144,217, 10, 98,178, 14, 70,131, -227,113, 67, 67, 65, 37,186,205,110,179, 48, 45,189, 8,156, 52, 99,205, 94, 24, 58, 25,196, 73,233,162, 60, 77,123, 38,161, 29, -243,105,246,176,114,139, 48, 8,231,235, 25,238,115, 10,241, 4,235,188,214,123, 51,204, 70, 5, 84,255,109,171, 85,205,172, 66, -109,188,142,159, 84, 14,213,184,127, 94, 55,118,187, 43, 81,242, 3, 12, 49,160,151,250,150, 17,229, 93,200, 25, 67,214,119,166, -213, 64,232, 55,241,155,187, 87,159,191, 63, 68, 38,124,247,242,237,251,143, 31, 0,222,121,152,243,254,238,245,183,223, 63,158, -182, 11,168,139,112, 89,181,226,171, 91, 20, 44, 85, 80,149,163, 98,169,232,141,195, 32,187,172, 42, 90,130, 4,189, 8,216,177, - 2, 89,163, 24,205, 57, 71,173,138,186, 9,124, 43, 90,179,157, 36,140,100,105, 85,110, 38, 23, 17,197, 91, 84,114, 32, 86, 83, - 20,205,218,110,215,187, 29,237,210,188, 31, 77,242, 44,146,113,117,180,112,107,187,173,144, 71,243,175,214,150, 80, 72, 92,112, - 31,148, 2, 62,189,154,181,150, 94,102, 67, 55, 18, 4, 31,161,243, 14,136,131,115,172,210,164, 49,177,219,172,213,124, 85, 85, -182,201, 84, 48, 8,240,239,247, 76, 72, 23, 12,125,128, 27, 87,128, 37, 92,107,152,224,224,216,225,217, 26, 14, 9,248, 24, 36, - 33,246, 21, 50,134,146,245,190,136,145,133,153,148, 47, 83, 78, 36, 91,181,247, 99,113,164,182,128,184,199,227, 74, 31,149, 13, - 15,131, 32, 4,146, 53, 93,111, 5,159, 16, 63,155,145,198, 61,187,243,134, 68,251, 32,222, 82,138,252,182, 36,196,196,124,153, -147, 52,111,105, 91,185, 28,148,241,101, 75,198, 20, 35,239, 28,244,212, 69, 28,166,121, 50,156,173,167, 29,185,175, 19, 81,192, -245, 28,199,177, 24,206,180, 51,162,142, 25, 21,236,149,170, 15,135, 85,134,189, 23,207,197,147, 62,146, 25,233,132,142,165,142, -208,130, 54,119,196, 74,119, 18, 89,221,120,112, 57, 95,254,209,135,241,157,151,250,106,112, 61, 93, 61,118, 28, 2,237, 9, 83, -236,103, 35, 7, 83,115, 47,193,136,200,111,196,156,210, 40, 12, 35,238, 60, 81, 58, 24,195,149,212,247, 66, 83, 8, 81,235,145, -137, 46,243,228,162, 31, 76,206,226, 44, 2,183, 3,224,200, 40,200, 25,237,234, 85, 81, 63,111,213,220,186,231, 66, 79, 45,134, -106,185,157,206, 80,156,237,105, 27,241, 74, 83,222,164,201, 19, 89,157,145,152,208,142,187, 9, 94,166, 63,222,140,174,191, 60, -126, 85, 92,231,196,174, 83, 28,223, 57,202, 75, 65,166,100, 29, 25, 91,239,232,219,155, 67,104,137,184,194, 74,197,242,157,101, - 57,101, 69,115,192,228, 46, 19, 18,149,217, 70,180, 82,184,100, 14, 29, 90,140,157,241, 4,179, 86,251,168, 45,129,187,153, 12, -174, 86,118,185,177, 27, 86,174, 69, 73, 21,251,173, 44,248, 89,233,150,243,196, 55, 83, 90,219, 34,138,211, 93,222,121,132,179, - 93,135, 57,124,182, 40,144,252, 95, 71, 4,145,105,162,163, 65,112,225,188, 55,254,181,248,201, 85,181, 64,204,190,157,127,202, -157,116,177,255,239,215, 95, 1, 24,187,154,222,166,129, 32,234,181,189,235,196,105,154,180,165, 34, 10,109,175, 61, 32, 33, 33, -241, 19, 16, 7, 78,252,205, 30, 56,240, 39, 56,113, 65,170, 4, 7,132, 56,160,138,150, 32,112, 29, 39,177,119,237,101,222,140, -183,233,135,144, 80, 47,109,213, 86,105,108,207,190,153,121, 31,125,125,127,216,198, 42,117, 31,230,132, 41, 77,220,115,149,250, -129, 90, 34,197,158,153, 90,106, 58, 58, 88,173, 74,222,189,163,203,153,234,221,163,209, 28,166,172, 45,112,161, 97,142, 59, 29, -140,131, 4,105,210, 17, 50, 49,116,101,175, 63, 46,206, 55,160, 57, 71,214, 55,147,157,131, 69,113,229,162, 70, 8, 78, 62,164, -174,136,122, 34,238, 37, 33, 76,153, 98,226, 47,138, 55, 11, 16, 38,217,110,194,238, 22,224,115,211,177, 76, 53, 34, 65,135, 72, -197, 66, 83,113,167,219,154, 62,225, 61,254, 36,223,157,237, 61,254,126, 9, 77,211,132,112,104, 83,209,177,148,153,193,186, 94, -159, 30,157,254, 40,174,126, 45, 23,142, 53,217, 98, 26,205, 89,191,214, 98,139,132,145, 56,221, 88,179,233,188,172,139,206,212, -101, 86,194,176,203,182,138,165, 10,141,197, 25, 76,101,118,152,197,153,166,202, 11,173,228, 10, 57, 5, 62,136,103, 9, 83,227, -156, 27, 38,201,163,124,120,213, 53, 29, 91,245,121, 24,243,182, 21,189,148, 6, 69,150,106,251,124,154, 79,198, 73,170, 65, 96, -183,206, 91, 36, 5,131,224,149,153,132, 30,165,198, 69,229,146,192,135,134,138,149,110,195,149,229,119, 28,220, 26,234,142,168, - 58,215,206,215,120, 68, 34,109, 34,234, 19,172,133, 0,138,142,168, 77,221,137, 85, 22, 53, 86,206, 54,166, 77,119,210, 56, 79, - 77,110,140, 28, 84,141,229,176,121, 54,225, 70,149,119, 24,200, 99,158,150,152,181, 68,222,120,153,156, 80, 5, 73,157,119, 15, - 55,159,130, 69,238,102, 57,133,145, 98, 58,156, 77,143,191, 46, 62,211, 69, 28,233,113,101, 75,245, 79,251, 35, 21,132, 33,219, -205, 16, 19, 96,224,194, 90,246,120, 95,221,171,155,108,245,140, 45,107,134,144, 22,188,253, 58,201,109,187,209,160,226, 57, 94, - 93,246, 57,186, 55, 97, 70, 80,108, 36,250,201,254,201,183,159, 95, 66,204, 75,226,239,206, 52,251, 16, 59,129,182, 91,168, 20, -223, 78,252,136, 2,241,151, 67,115, 25,179, 9, 92, 21, 81,129, 16,232,152, 97,153,233, 12,142, 61, 16,100,222,156,124,173, 10, -222, 10,106,107,160,102,232,123,176,127, 8,143,216, 54,139, 67,162,211,120,144, 24,135, 45, 84,212, 7, 27, 97, 0,154,242,215, -146,177,164,241,136, 0,173, 19, 78, 55, 88, 55, 17,246,130,122,143, 49,123,108,148,222,215,233,108,172, 79,166,249,241,161, 57, -152,100, 8,113,230,177, 51,195,100, 40, 93,188,200,152,101, 76, 17,177, 23, 99, 27, 93, 47,221,197,159,238,178,208,139, 58, 90, -212, 54,230,145,178,239, 67, 2,197,147, 56, 22,230, 5,107, 86,227, 48,184,216, 74,142,195,130, 78,208,127, 39,195,119,180,237, -124,165,128,226,209, 95, 90, 42,253,185, 25,190,124,254,234,236,253,153,247,194,122, 8,101, 1,155,216,195,162, 42, 28,156,120, -149, 80,163,100,101, 73, 63,178, 55,222,255, 93, 21, 72,127, 99,186, 24,253,226,208,140,186,214,174,152, 33,218,219,140,243,255, - 40, 83, 23,134, 18,160,193, 83, 47, 77,231,222,198,210, 99, 93,247,163,155, 48,158,244,210, 54,121, 69,127,106,221,172, 6,233, -160,106,150,183,147, 15, 8,235,108, 44,174,172,209, 3, 58,213,170, 62,231,175,227, 15,246, 91, 84,234,254,116,197,119,175, 95, -188,121,247,225, 45,245, 84, 46,114, 79,231,207, 62, 93,156,135, 56,239,109, 60, 89,191,116, 69, 25,102, 77,238,255, 85,249,191, - 2,208,117, 45,203, 73, 4, 81,180,231, 61,204, 16, 36, 60, 12, 65, 99, 54,198,111, 72,249,225, 86,185,114,161, 11,183,254,128, - 86,202,128, 4, 34, 33,192,192, 60,122,166,189,231,118,143, 76,208,164, 42, 83, 44, 72,120,116,207,125,156, 62,247,156,255,196, -119,235, 25,111,109,167, 57, 58,136, 30,205,137,130,150,107,187,155,221, 26,157,157, 18,124,182,231,131, 36, 35,128, 35,116,227, - 46, 76, 14,149,104,123,237,113, 60,166, 43, 85,124,190,237,107, 59, 37,122,151,203,244,254, 87,114,255,152, 62,224,126,224, 49, -113,179,180, 16, 13,231, 86, 75,135, 11,165, 77,216,235,217,107,206,210,157, 86, 7,116, 37,248,126,241,102,174,212,184, 63, 78, -246,155, 28,130,250, 40,168,152,233, 5, 33,120, 14,235, 80, 51,134, 14,175,227,250,240,203, 67, 57,175,105,185, 20, 44, 4,244, -231, 64, 73,172,248,175, 36,163,130, 5,164, 93,165, 70, 39,138,170,120, 51,184,184, 58,191,250,240,237,163,235,121, 37, 78,122, -219, 89,153,166, 50,167,125,219,234,200,120, 72, 91, 38,203,115,181,195,185,178, 74,169,172,149, 10, 64, 38,196, 0, 4,100,175, - 97,118,234,122,244,176,210,248, 38,171,247, 8,251,211, 98,234,250, 62, 64, 78,174,117, 50, 89, 20, 96, 31,149,113,232,157,117, -163, 86,232,176, 33, 22,107, 86, 11, 25,120,118, 59, 10,109, 20,212,249,104, 52,186,126,127, 61,236,247, 62,127,249, 74,153,232, -251,205,207,201,237,173,235,249,236,155, 93,166,153, 76,246, 50,231,122, 39, 8,172, 0,100, 77,106,207,149,231, 9,106, 15, 50, - 41,182,137,216,236, 42, 45,110,179,167,140, 66,159,182,144,177,235,132, 20, 14, 88,120, 13,148, 82,250,133, 16,183, 98, 80,158, - 79,166,204, 4,185, 48,162,205, 13, 10, 23,147, 35, 79,178,124, 71, 29, 4, 5,141,113,119,116,179,252, 97, 31, 23,233, 70, 59, -196, 50, 7,179,205,112,166,142, 88, 98,161, 23,165,197,142, 94,162, 19,210, 66,211, 46, 42,105,231, 12, 78, 6,147,199,137, 14, - 21,212,123, 81, 59,172,229,201, 84, 61, 0,113, 26,245,182,251, 21,103, 29,214,221,109, 30, 59,170,227, 66, 94, 99, 47,244,159, - 41,232,229, 90,185,247,232, 52, 85,136, 90, 11,204,152, 52,214, 44,141,102,100,175,201, 27, 22,243,227,169,196,137,250, 20,121, -127,111,230,134,255, 12,144,171,188, 28,188,157, 61, 78, 51,185,167, 64,113,222,125, 53, 91, 78,109, 30,123,160,180, 25,123,241, - 58, 93, 61, 85, 15,212, 35,166,214, 97,232, 74,212, 34, 47, 6,159, 81,168,197,117,190, 81, 44,236,197,101,187, 62, 44,165, 54, - 15, 1, 29,165, 57,117, 66, 84,170,195,227,133, 74, 43, 40, 85, 88,116,165, 93,232,209,173, 58, 10,252,215, 47,226,119,103,225, -197, 48, 14, 2, 71, 3, 9, 88, 33, 13,248,224,194, 19,166,156,171, 24,247,192,169, 20, 93,169, 44, 0,150, 34, 43,125,157,175, -197,221,202,157, 37,238,170,168,114, 89,154,169, 81, 80,126,209, 64,170,167,210, 8,127, 23,220,240,157,193,138,212,233, 3, 38, -156,146, 5,125, 1,207, 50, 68, 72, 15,227, 8,140,219,197,122, 94,177,149, 27, 27, 82, 27,167, 61,131,209,152,142, 16,111,218, -228,100,134, 81,244,189,204, 42,114,120,206,105,171,191, 74, 31, 10,170,146, 44,227, 99,195, 1,187,172,145,247, 67,214, 6, 39, - 19,141, 15, 14, 14,168,224,211,238,101,165, 6,213,240,210,156, 62, 12,203, 18, 22,131,204, 37, 62,140,119,196, 65,156,164, 9, -127, 79,104,112,217,126,173,210,110, 83,148, 98,169, 63, 16,199,208, 61, 16,170, 94,251,229, 98,123,231, 90,154, 55,161, 63, 17, -194, 45, 27,132, 55,201,253, 21,173, 36, 20, 49,255, 97, 46, 60,247,243, 71, 0,186,174,118,181,137, 32,138,238,236,247,110,178, -177,177, 73,105, 10,165, 21,170,224,143,130, 84, 65,240, 13,196,135, 16,244,101,212, 39,210,103, 80,139,136, 63, 4, 21,173,162, - 41, 38, 45,113,235,102,191,103,188,247,204,238,166, 68,154,127, 33, 63,118,118, 51,123,231,220,123,207, 61, 71,243,103,140, 75, - 70, 89,226, 74,129, 49,213,158, 24,130, 69,219, 9, 34,197, 25,139,170,211,253,223,191,245,224,237,151,215, 22,236,119, 27, 27, - 23,101,134,174, 95,115,247,195,132, 36,155, 9, 16,237,176, 94, 23, 14,109, 46,109,104, 93, 50,232,202, 48, 88, 20,186, 38,163, - 26,193,119,217, 48,136, 34,127, 16,231,177, 45, 86,117,127,126,255,109,111,216, 31,158, 46,166, 30,187,114,107, 98, 45, 23, 15, -209, 44,226,201,139, 59,251,135,159,167,159,108,197, 48,126,224, 69,163,104,115,107, 48,250, 49, 63,161, 77,227,192,185,209,129, -240,251,181, 96,192, 98,241,152,204,212, 90,115,144, 51, 83, 93, 65,144,241,187,170,233,114, 55,119, 14,142,191,189,103, 51, 38, - 52,238, 37, 15, 13,138, 73,180,243,245,236, 4, 42, 5, 20,176,165, 77, 97,212, 46,135,155,130,107, 68,138,123, 74,113, 44,138, -210,170, 10,147,144, 61,225, 58, 2,205,227,254,228, 87, 50, 45, 25, 90, 90, 51,107, 97, 6,174,118,118,103, 41, 77,138,201, 70, -157,148,116, 57,107,123, 35,194,216, 17,102, 79,108,139, 18,212,144, 9,245,188,159,238,221, 61,122,252,228,233,222,237, 67, 66, -129,179,239, 31,199,147,221,139,249,236,197,179,231,111,222,125,168, 42, 43, 7,250,206,153,157, 87, 51,131, 21,181, 43,186, 37, -122,244, 97,207, 8, 61, 58,220, 84,186, 52,210, 76, 36, 25,203, 75, 20,218,105, 85, 1,245, 23,180, 64, 66, 56,101,104,112,183, -156,190, 86,156,185, 72,102,193, 55, 32, 8, 53,249, 70, 10, 4,213, 51,163, 83,203,230, 62,117, 5,153,117,199,246,179, 42, 53, -175,156,176, 91,119,154,166,135,124, 61, 28,157, 47,231,173, 70, 57,255,155,190, 19, 84, 85,222,243, 35,204,250, 11,185,114,216, - 64,207,159, 19,193,160,157,102,106,162, 6,165,134,116,232,238,141,111,156,255,153, 17,188, 18, 45, 65,160, 91,135,239,248, 73, -153,232,197,123,182, 7, 29,202,252,127,247, 37, 93,104, 53, 47, 85, 53,105, 1,174,235,177,108, 45,143,165,116,210, 90,188, 20, -130,255, 21, 76, 60,154,246, 25, 88,219, 24,219,213,244, 69,110,123,134, 94,148,149, 9,197, 78,215,113,105,123,107,207, 25, 46, -249, 97,116,187,172,203,203,109,225,182, 1, 96,174,113,111,186,248,206, 45, 83,200,110,210, 3,167, 91,150,117,129, 54,166,112, - 48,245,206,190, 46, 22,247,156,251,126,100,170,148,118,172, 11,173, 94, 78,153, 77,123,199,119,119, 55,130,131,173,222,254,118, -223,113, 91, 1, 62,126, 75,160,207,167,133,185,185, 31,229, 56,126,224, 6,125,179,215,183,109, 95,216,158,130, 37, 41,119,233, - 41, 75, 45,242, 34, 91, 38,113,156,254, 93,164,201, 69,150,167,241,133,250,121,230,253, 94, 6,211,172,176, 0, 86, 25,203, 27, - 22,142, 45,161,203,208, 58,198,180,249, 25,216,142, 40, 4,104,182,123,169,221,150,101,157,195,142,131, 47,196, 41,152, 4,175, - 70, 65,140,186,227,207,192, 91, 22, 30,241,162,105,236, 55,255,111,221, 78,234,210,111,219, 27,147,233,226,148, 19, 14, 12, 60, -176, 92,153, 38,209,104, 90,165, 46,181,180,141, 81, 29, 85,101,187, 93,192,204,215,236, 96,133, 1,230,170, 66,164, 38,216, 78, -137, 23, 24, 62,205,100,178,212,144, 92,182, 20, 75,240, 53,233, 46, 30, 30, 61,122,117,252,178,161, 91, 1,113, 11,185,146,134, - 88, 27, 61,107, 7,182, 68,215,129, 85,221, 41,216,141,115,173, 94, 22,185,238,168,115,245,231,159, 0,140, 93,203, 78,220, 48, - 20,181, 29, 59,113,156,100, 2, 12, 47, 1, 66,106, 65, 21, 21,234,170, 31,192, 15,148,191,232,162, 82,255,148,101,145,250, 5, -244, 65, 41, 12,204,123, 38,177,211,123,175,237,233,136,178,232, 46, 11,132, 50,227, 59,215,247,113, 30, 65, 95, 44, 9, 74, 74, - 33,200,252,228, 46, 89, 19,234,243, 10, 74, 89, 90, 88,219, 32, 85, 21,190,122,106, 48,189, 7,250,205,253, 13,186,159, 19,177, -121,101, 50,131, 30,205,254, 58,141, 74,143, 56, 30,134,211, 98, 86,103, 25, 57,110, 59, 58, 47,235, 37,159, 16,220,225,161,137, -212,122,249,106,198,232, 98,218,206,188,189,117,196,188, 7,235,212,147,189,211, 95,195,159,185, 42, 32,229, 17, 51,205,251,123, - 4, 43,153,251,209, 29,252,122, 20,173,239,225, 64, 23,243,233,254,230,238,116, 62,133,170, 0, 26, 11, 17,153,180,232,223,197, - 90, 82,226, 8,195, 59,223,135,186,224,207,192, 40,169, 89,232,185,190, 61,254,240,132, 65, 17,171,204, 58,175,111,135,183,116, -156,110,110,219,201,194,142,103,237,112,204,187,105, 53, 24,240,135, 65,119, 55,224,138,239,253, 30,141,151,150, 52,161,164, 90, -218,249,176,121,132, 23,128,242,159, 59,161,170,101, 94, 17,119, 36, 65,109, 54,194,145,177, 84, 66,115,151,244,140,210,248,246, - 82,103,210,228, 41, 71, 88,125,183,179,213,187,188,252,240,241,211,103,104, 39,220,252, 59,103,139,167,135,219,175,215, 87,199, - 39,167,189, 66, 95,127,185,170,123,186, 44, 36,250,124, 43,218, 58, 19, 55,203,181,190,152,146,172,147,200,207,106, 92, 42,187, -178,128, 46, 4,125,166, 74,109,222,159,191, 77, 92,247,240, 52, 18, 76, 65,107,106, 12, 52,167, 75,133, 24,141,196,155,162,101, - 8,255,193,200,134,103,200, 26,112,244,129,245, 72,133,118,131,176,141, 96,192,226, 35,143, 54, 46, 44, 87,166,117,110,141,109, -131,114,169, 43,133, 50,190, 6,109,244, 17,211, 34, 87,123,133, 98,196,139, 6, 2,102,209, 44, 68,180,164,128,144, 36,169,188, -150,210, 61,220, 98,173, 95,124,194,231, 48, 16, 6,110, 25, 44, 6, 33, 7,183, 51,137, 13,155,116,168, 89, 13, 79,146,192,252, - 40, 19,214,203, 55,160, 57,161,178, 2, 99,239,217,164, 61,200,145, 48,151,169,212, 51,104, 14,183,143,209,171, 19, 23,154, 24, - 11, 98, 45,185,123,201,189,158,169, 59,114,160, 21, 44,250, 60,118,236,236,240,124, 4,213, 15,114, 89,177, 14, 32, 52, 32,150, -181, 40,209, 46, 72,165, 48, 16, 19,162, 74,231, 90,157, 11, 89, 24,233,148,130,121, 60, 76,247, 87,104, 0, 51,187, 74, 82, 98, -237, 34, 9, 83,146, 3,178,196,117, 23, 86,232,154,188,195,140,228, 38, 85,149,130,102, 57,209, 10,158, 69,153,164, 7,133,121, -183, 83, 95,188,234, 95,156,245,223, 28,150, 91, 53,166,118,248,109, 40,232,104,179, 52, 77,113, 86,147,224, 2, 13,190,202,170, -216, 59, 42,247, 95,235,221, 35, 81,244,109, 82,206,108, 50,111,216, 24,154,194,165, 67,171, 94, 43, 27,161,121, 86,101, 27, 59, - 69,255,160,218, 62, 50,213,150,214,108, 35,159,212,106,150, 58,221,118, 26, 7,241,194, 15,187, 2,180, 38, 90,114,174,216, 92, -248, 7,219,101,127, 74,250, 98, 43, 85,181, 54, 56,233,185, 56,160, 96,177, 57,163,217, 16, 11,132, 12, 23,175, 87,254,162,144, - 17,101,235,241,108,226,109,130, 56,143,183,181,175,157, 57,135, 24, 38,136,101,199, 86,222,226,193, 23, 37, 12,213,144,201,134, - 46,164,155, 56, 87,192,169,189,243, 14, 32,148,214, 26,207, 73,166, 85,170, 37,120, 81, 80, 94,164,149, 96,208,198,128,226,178, - 69,241,226,240,239,130,185, 7,127, 65,106, 41,210,164,248,191, 32,153,240,186,207,137, 78,221,255, 43,145,253, 17,128,174,115, -233,109, 26, 8,226,184,189,118,214,113,146,186, 4,218, 34,218,170, 45, 80, 82, 64,156, 80,203,153, 15,194, 1,238,136, 3, 7, - 36,248, 52, 72,240, 81,144,184, 34, 40,162,168,226, 37,181, 73, 43, 26, 82,242,178,227, 93,239, 50, 15, 59,113, 42,113, 76,164, - 88,138,189,158,199,127,102,126,227, 59, 51,200, 39,158, 51,158,224,194, 36,201,157, 86, 83,205, 52, 9,208,248,223,152,121,145, -255, 4, 79,105, 33,174,161,104, 71, 45, 37,140,161,208,232,201, 52,102,184, 88,151,134,224,149,170,253,198,109, 70, 75,195,241, - 16, 37, 51, 75, 29,134,180,160,153, 17,254, 25, 59,208,249, 21,223,110,209, 1,102,139,110, 48,120,188, 96, 38,190,159, 28, 70, - 97, 19,194,159,132, 76,128, 51,227,249,208,123, 70,189,183, 46,227,104,172,217, 94,107,253, 56,253, 9,241, 96,213,151,216,222, - 72, 35,181,197,138,119,148, 11,203,107, 66, 77, 49,105,201,208, 27,120,156,173,213,157,147, 94,167, 26, 52,192,163, 48,239, 19, -158,253,210,242,106,162,179, 65,220,131, 11,172, 47,174, 55,130,232,160,179,191, 18, 93,237,141,112,221, 59,152,101, 8,178,186, -163, 14, 78,126, 99,248, 28, 66, 98, 91,245, 66, 72,163, 53, 70,247, 30,133,240,110,189,238,234, 64,192, 31, 79, 38, 36, 41,146, -189, 9, 36, 26,104, 42, 79,161, 39, 83, 42,131, 67,116,175,181,253,232,201,227,187,123, 15, 29, 71,170, 81,231,243,135,143,155, -215,183,222,188,126, 27, 86,131,243, 94,188,187,251, 32,106,212, 48,210,137, 29,130, 71, 98, 40, 35, 20,247,171,139,156,177, 13, -183, 59,213, 91,155, 27,119, 90,107, 25, 46, 48,178, 7,135,223, 50, 43,159, 63,125, 6, 15,253,197,171,151,221,126, 31,163,157, - 44,141, 26, 98,240, 39, 17,113, 69,138,104, 96,255,210,174,227, 9,121, 79, 56, 1, 90, 86,106,169,138,249, 30, 17, 63, 29, 45, -123,232,215, 99, 61,114, 75,143, 1,236,107,234,148,123,126,193,183, 35, 90,125,106,242, 43, 66,104,147,115,138, 98, 29,135,124, -217,153,116,131, 74,168, 38,127,128,205, 42,200, 34,142, 33,116, 44, 96, 97,130,224,218,125,100,211, 99, 59,157,102,195,236, 81, -187, 27,166,231, 62,231,208,166, 22, 46, 12,226,190,193,138,186, 79,105,138, 42,191, 91, 60,128, 93,102, 82, 26, 71,213,228, 2, -250,126,212, 9, 69,187,123,124, 81,144,177,188,118, 24,133, 27,200, 70, 39,184, 94,206,136,124, 74,223, 74, 95,194,231,118,247, - 8,220,161, 71, 43,169,121,233, 0,169, 85, 52,143, 79,141, 73,188, 69, 50,113, 98,194,127,137, 18,104, 10, 5,104, 26, 27,190, -136,109, 23, 57,196,199,184,204, 99,167, 81,113,143, 0, 74, 1,110,189,115, 67, 31, 28, 54,248, 6,132,185,162, 46, 9, 89,145, - 12, 55, 22,195,219, 43, 11, 55,174,213, 49,209, 37, 61, 36,205,140, 20,184, 8, 30,205, 58,214,164, 40,170,131, 76, 59, 8, 43, -205, 85,175,118, 73, 57, 98,156,232,164, 63,156, 76,224, 92, 40,159, 40, 0, 88,162,204,243, 90,139, 38,130,151, 54,129,135,128, - 75, 4,151, 27,107,205,112,105,220, 56, 63,141,126, 31,175,180,213,209,121,212, 78, 82,120,209,152,234,202,179, 0,198,206,153, - 40,184, 17,103,163, 51, 46,232,161,240, 65, 21,139, 48,168,238, 44,111,126,250,181, 79, 6,126, 74, 98,180,249,140,250, 28, 60, -154,251, 8,139, 88,129, 43,159,197, 52,154, 71, 97, 37,216,135,238,184, 71, 6,151, 97,192,180,160,195,152,113, 50,180,110, 49, - 5,235,206,198, 26, 24,205,233, 17,229, 94,185, 42, 85, 9,118,180, 89,155, 43, 86, 8,136, 10,182,174,220, 60, 56,254, 34,253, -202,253, 91,123,239,191,190,163,239, 13,175, 96,204,101, 39,107,193, 67,103, 25,210, 73,225,230, 40,157,149,209,217,246,127,131, -224,184, 36, 57,160,108,242, 34, 67,136, 44,109,198,178,142, 20, 21, 26,210,206,230,125,193,127, 67,248,127, 2, 48,118, 53,189, - 77, 3, 65,212,107,123,237, 56,205, 7, 85,147,166, 45, 18, 5,209, 11, 39,196,133, 11, 31, 23, 36,144, 80, 41,170, 56,194,165, - 18,252, 16, 16,167, 30, 57,128,248, 45, 8, 9, 10,173, 4, 72,112, 65, 66, 69, 72,136,168, 77, 73,218,144,218, 77,253,177,235, -120,153,217, 93,187, 41,112,224,220,216, 73,181,179, 59,111,103,222,188,103, 23,149,123,201,131, 70,230,221,200, 72,149, 30,172, - 33,142, 13,216,218,148, 70, 92,171,212, 75,137,144,204, 60, 74,152, 34, 47, 25,170, 27, 79, 38, 36,191, 77,213,208, 49, 58, 50, -162,134, 58,225, 99, 93,191, 3, 40, 44,197,111, 25, 21,228, 82,213, 58, 27, 55, 28, 87, 25, 15, 47,224,210, 72, 41,211, 83,232, -136,120, 32, 36,167,234,173,148, 39,232,249,160,205, 43,132,162,212, 25, 99,218, 85,154,141, 37,171,138,205, 90, 99,215,239, 33, -119,192, 48, 35, 22,203, 38,167, 37, 5, 21,180,193,223,108,125,118,123,208, 49,244,212,134, 72, 53, 51, 16, 11,105,117,183,190, - 27,236, 81,219,241,163,253,249,214,217,158,223, 5,200,116,239,238,253, 75, 75,215,158, 60, 90,221,120,255, 18, 82,250,118,127, -219,163,131,153,218,201, 83,141,211, 91,251,175, 97,115,193,182, 7,152, 32, 19, 30,166, 46,156,153,174,205,180,247,183, 8,225, -112,170,160,255, 39, 27, 14, 6,217, 46,231,120,117, 49, 72,204, 0,171, 50,204,100,200, 76,147,243,163,132,205,181,154,221,189, - 48,137,147, 7, 43, 43,183,150,239, 56,181, 22,252,119, 59,223, 63,183,191,109, 78,207,181, 96,251,181,219,221,135,143, 87,223, -174,189,162,116,170,223, 31, 1, 18, 27,198, 7, 16,124, 14, 4,130,237,216, 28, 61, 94, 57,195, 54,116,217, 41,253, 10,124,198, -140,197,235, 55, 23,111, 47, 5,131, 1,172,224,179,231, 79, 63,124,252,212,235,117,174,220, 88,190,120,225,252,139, 55,235,176, - 97, 57,150,109,204, 74,149, 4, 60,132,107, 51,188, 77,170,231,142, 36, 52,182,120, 22,219,196, 45,204,216,177,220,147, 9, 38, - 82,215, 1, 16, 73, 66,118, 88,196,221, 65, 50, 28,143, 62,215,114, 50, 77,236, 37,133, 21,154,137,109, 64,170,212,119, 73,118, -196, 73,151,219,217,130, 44, 94,176,119, 83, 45, 95, 90, 24,164,137, 67, 60,220, 21,242, 25, 81,203,101,249,249,145,240, 16, 30, -230,114, 62, 0,254, 10, 43, 50, 57, 49,185,254,101, 77,153, 60,160,112,244,216, 57,131,148,167, 81,150,195, 62,217,192, 23,228, -242,185,171,239,190,110, 8,110,152,228, 88,145, 4, 86, 7, 11,172,236, 80,169, 40,154, 40,119,101,225,158, 20,218, 44, 90,206, -103, 81, 74,120,200, 66, 19,229,164, 16,163, 87,221,154, 31,251,176, 28,112,106, 19, 44,208, 53,127, 6, 59,200, 74, 2,180, 97, -185,145,145,144,140,140,205,161,234,154, 73,150,123, 99, 41, 42,141,124,153,212, 73,148, 32, 8,229, 78,177, 9, 97,187,182,233, - 2,114, 71,159, 76,234, 89, 40,137, 1,192, 0, 86,226, 76,165,188,208,152, 88,152,173,158,168, 80,164, 27,194,157, 37, 54,100, - 33, 17, 49,126,201,177, 61,116,143,196,186,142, 46, 13,212,155, 20,246, 20,113,194,152,197, 33,147,109,126, 1, 31,163, 37,183, -228,202, 25, 17,116,119,192, 68,202, 18, 22, 50, 30,134, 44,226,105,156, 36,145,136,145,134, 3,167, 3,165,246,212,124,163, 58, -237,213,219,229, 31,125,103,167,212, 70, 35, 35,169,223,157, 42, 93, 72,229,233,161,133,119,244,112, 52, 81,242, 23, 90, 21,142, -113,182,217,217, 20,249,248, 40, 57,154, 14,250,163,131,130,139,166,156,208,243,137,100, 1,104,192,115,189, 0,205,218, 20,225, - 25,147,104,173, 84, 29, 66, 28, 10,197,110,149,142,158,150,148,199, 82, 77,240,124, 24,162, 82,170, 65,158, 9, 66, 31,158,245, - 28, 15,249, 57, 44,195,196, 9,143, 71, 67,249, 3,113, 39,195,253, 91, 94,254,164,158,136, 50, 95,149,173, 32,136, 1, 75, 90, - 65,195,218, 76, 56,101,248,133,177,136,144,158,240, 87, 45, 6,194, 0,222,144,171, 1,140,241,125,254, 49, 56, 33,198,205, 77, - 85, 44, 41, 6,154,249,223,142, 78,191, 5,160,236, 90, 86,163, 8,162,104, 87,119,245,187,123,222,154,193, 36,154, 4,130, 70, - 5, 7, 55,110, 92,136, 43,113,233, 66,252, 10,247,174, 4,245, 11, 92,185,240, 43,116,163, 1, 81, 4, 81, 17, 3, 42,130,142, - 16,117, 34, 62,152, 36,164,147,121,244,187,189,247, 86,101,166, 3,110, 36,139, 64, 32, 73,247,116,215,169,123,110,157,123,142, -244,159,105,185,135,200, 76, 3,110, 32,206,169,181, 84,179,155,150,110, 0,207,157, 20, 16, 80, 28, 52,136, 79, 49, 86, 62, 88, - 43,203,125,166, 3,213, 82,198, 60, 29,110,167, 18, 93, 28, 91, 51, 5,138, 65, 44, 75,179,116,223,170, 25,191,219,134,203, 80, - 66,158,238,235, 20, 4,173,195,167,224, 59, 85,162, 87,197,145,218,124,140,218, 16, 92, 63, 81, 58,166, 65, 71, 68,228,154,219, -200, 41, 89, 69,198, 90,208,194, 20,163, 76, 42,222, 75,165,215,223,200,179, 12,223,103,166,121,192,230, 1,179,208, 5, 10,171, -124,177, 99, 53,253,214,246, 96, 7,174,198,181,221, 68,132,123, 17, 35, 17,185, 22,195,112, 24, 68,195, 40,142,146, 20, 64, 21, -170,200,162,115,250,236, 66,103,101,237,197,171,222,198, 87,172,253, 25, 80,138,104,103,180,219,219,234, 17,162, 1, 77,118,108, -195, 27,132, 3,192,192,166, 63,179,185,135, 10,214, 81, 60, 64,249,121,145,140,105, 56, 51, 86,146, 17,203, 19, 58, 71, 14, 83, -145, 42,140, 79, 58,134,191,151,113,248, 79,183,110,222,134,210,206,180,172,235, 55,238,236,110,247,187,239,223,182,143, 46,125, -120,253,188,125,108,105,241,228, 57,175,222, 90,125,248, 96, 97,113,121,179,191, 61, 59,191,144,196,217,149,171,215,186,159,214, - 53,102,247, 55, 3,219,178,195, 16, 94,178, 34,142,243,163,115,243,157, 51,157,119, 31,187, 73,146,158, 58,177,252,232,241,147, -187,247,238,175, 62,125,246,249,203,143,173, 96, 84,179,253,243, 23, 47,107,217,120,237,205,203,122,197, 85,177,148, 80,224,170, - 96,145,196, 97,138, 41,155,138,104,157, 73, 91, 57,138,172, 44,228,177, 27, 86, 19, 8, 69, 97, 50,130,125, 14,224, 37, 47,166, - 67, 73,130,101,155,154, 41,247,224,124,210,139, 16,111, 3,234, 70, 84, 85,167,105, 76, 18,174,149,130,144, 44,221,204,243,164, - 60, 73, 77,137,198, 9, 59, 96, 66,169,202,227, 78, 50,114, 21,111, 42,160,158, 24,148,109,120,141, 40, 13,127, 7,191, 54,250, -223, 8, 83, 56,245, 33,139,162,152, 58,165,203, 14, 18,245,244,180,253,236,135,239,127,214,163, 34, 33,221, 56,181,157, 5,238, -107,162,199,138, 48, 65, 90, 67,244,122, 67,242, 74,243, 67,162,237, 10, 4, 55, 70,184, 87, 72,238,173,136, 79, 75, 24,107,103, -121,102, 25, 22, 92,240, 94, 24, 48, 1,227, 12,176,152,227, 61,170,236,128, 93,140, 24, 34,162,193, 83,241, 35, 49, 41,142,164, -147, 56,157,142,238, 78,176,141,112, 11, 88,161,174,185, 38,118, 99, 60,203,228,154, 93, 53,216,146,239, 93, 58, 62,115, 97,229, -240, 92,203,130,181, 28, 66,213,128, 29,134,130,196,145,170,197, 53, 76,128,177,116,196,110,110,136,112, 37,189, 57,167,213,103, -211, 76, 29,143,194,241, 16,222, 17,160,104,186,231, 89, 85,223,182,171, 14,247, 29,213,179, 85,215, 6,210,202, 61,199,172,121, - 30,108,152, 64, 96, 43,182, 1,181, 43,186,107, 96, 36,182,248, 66,245,128,211,244,234,158,203,119,148, 1, 15,168, 29, 37,238, -175, 96,147, 60, 91,196,109, 83, 55,155,126, 3, 71, 31,232,227,203, 41, 81,171,144,180,153,181,129, 73,168,108, 24,141,101,191, -116, 34,224, 17,152, 50, 73,213, 42,225, 15, 71,250, 98,133,232, 13, 46,107, 80, 32,124,138,140,133,192, 99,103, 88,245, 89,145, -106,168,122,224,132, 27, 76,149, 22, 52,204, 49,108,156, 89, 69, 90, 15,171, 47, 77, 72, 29,111,104,186,161, 91, 81, 18, 74, 35, - 20,218, 96,131, 17,122, 71,207, 84,218,221,159, 93, 81,214, 59,134, 75, 9, 7, 18,139,227, 12,224, 33,145,101,175, 72,242, 46, -121, 18,192, 67, 43, 79,156,194,239,114,110,160,119, 49,101,183,178,127,105,134,203,186,163,172,248,191,168,190,191, 2,240,117, -109, 61, 77, 4, 81,120,102,119,246,210,118,235, 22,196, 10,197, 18, 52, 88, 20, 10,104,228, 47, 24, 12, 33, 49, 49,250, 67,245, -193, 72,188,189, 27,162, 49, 81, 98, 20,125,192, 11,198, 64, 40,176,165,123, 31,207,101,183,133,196,152, 52,125,105, 31,166,157, -157, 57,223,156,249, 46,197,254,158,211, 49,164, 12,191,134,167,211,114,108,183,106,123, 39,131, 64, 24,236,149, 36,163, 60, 34, - 29,138,148, 82,254,147, 93, 47,135,237, 13,201,241,216, 20,230, 36,203, 42, 37, 69,153,145,141,157, 43, 91,185,196,219, 32,219, - 2, 38, 30, 81, 35,190, 76, 11, 51, 88,217, 97, 74,107,110,114,238, 79,239, 55,251, 97,193, 96, 96,245, 98,181, 36, 82,175, 81, -144,208,196,204,197,153, 94,191, 71, 70,102, 69,120, 36,251,213, 17,157, 64, 66, 89, 26, 68,167, 72,126,167, 60,248, 49,175, 1, - 43, 45,166, 0, 16,147,233,105, 34, 59, 12,122,100, 29, 99, 55, 27,151,131, 65, 63, 66,250, 9, 37,243,106,180,192,165,149, 44, -218,151,174, 4, 73, 24, 38,232,186,181,253,249,227,235,199, 79, 63,237,108,135, 81, 80,252, 72,205, 93,124, 19, 48,255,114,123, -121, 63,216, 63, 30, 28,205,183, 58, 63, 15,247, 0, 83,107,140, 3, 30, 48,189, 18,190, 8,143,142,239, 52, 18, 51, 54,171,121, - 5,158,116, 83, 21,106, 35,116,157,196,107,243, 26,192, 43, 33, 30, 61,124, 0,187,125,119,121,161, 98, 38, 47,159, 61,137,195, -190, 50, 68,119,101,117,124,234, 26, 12,252,203,251, 55,155,155,207,183,182,182,150,186, 93,248,165,107, 27,247,167,231, 22,155, -126,101,118,182, 5,245,104,125,125, 13,198, 84,173,168,197,249, 25,219,201,219,237,171,111,223,125,136,242,108,117,229,214,183, -221,221,237,157,175,105,146, 57,182, 85, 7, 32,167,242,245,141,187,190, 87,125,245,226, 41,192,207, 48, 33,197, 83,204,153,139, -104,191, 70,144,155, 71,174,203, 36, 50,132,175, 24, 38,135,119, 77, 60, 97, 70, 9,204,243, 51,213,223, 24, 66, 36, 71,185, 9, -121,230, 13,183,120,110, 46,103,212, 6, 97,137,133, 49,202, 76, 48, 81,217, 40, 50, 0, 86,176, 63,178,167, 35,165, 37,160,215, - 77, 86,250, 16,140, 90,114, 35, 98,165, 1,147,107, 81,164,162,166,232, 2, 56,207, 34,187, 19,131, 89, 50,118,186, 69, 12,171, - 20, 28,210,136, 50,160, 45,148,162,229,178,100,105, 81, 4, 52,142,186, 89,111,194,209,201,228, 14, 94, 25,177,196, 82, 68,234, - 84, 43, 98,116,240,177,148,185, 51,250,246,236,157, 78,171,243,227,224, 59, 35, 20, 34,176, 23, 14,188,136, 0, 41, 79,184, 8, -210, 32,104, 68, 87, 8,134, 60,231, 88, 53,178,174, 50,138,151, 38,230,130, 34,255,106, 66, 40,134,116, 77,147, 0,187,233,217, -118,221,181,107,174,242,108,167,229,170,141, 27,147,247,150,166,198, 60,213,143, 1, 1, 37,164,183,200,137,102,134,244, 54,199, - 82, 48,227,104,233,135,234,109,164,191,227, 18, 25,159, 22,141,150, 72,242,232, 52,138, 66,108, 46,163, 91, 72,205,129,119,168, -168,152, 33,160, 72, 39, 96, 83,125,115,149,112,109, 81,117,197,132,103, 54, 27,181,201,177, 9,191,230, 43, 43,134,135, 59, 74, - 57, 9, 6,139, 56, 28, 15,124,191,166,250,250,196, 60, 78,217,128,184, 20,158,143,174, 5, 51,100,104,165, 41,212,153,148,194, - 86,175, 79,117,246,131, 3,116,251,202,243,163, 62, 6, 6,243,174,206, 78, 80,186,188,173, 96,218,180,214,229, 69,141, 46,112, - 1,172,202, 83,228, 35, 22,158,246, 60, 49, 44, 26,130, 25,135,138, 69,219, 40,254,225,112,214, 36, 59,185,136, 26, 92, 70,189, -114, 1,138, 46, 59,132,139, 17,161, 83, 16,176, 59, 33,174, 21,123,147, 23, 34, 98,248, 51,240,124, 70, 69,250,230,244,194,175, -195,189,242, 3,118,215, 44,148, 25,178, 96, 49, 14,245,103,184,119,197,105,120,198,245, 22, 80, 20, 89, 88, 97,226,180,148,231, -179,183,228,168,247, 34,207,182, 61,245,121,218,130,254,175,156,239,175, 0,140, 93,201,110,211, 80, 20,245,248, 18, 59,118,156, -193,233, 64, 43, 64, 45,131, 0,169,106, 10, 8, 9,186,168, 90,186,228, 15, 16,226, 95,216,176,227, 39,128,111,232,166, 11, 36, - 86, 72, 44,168,132, 68, 37, 88,160,210,162,182,193,113, 28,215, 99,108,115,239,125,118, 27,132,144,144,178, 74, 34,103,240,123, -231,157, 59,157, 83,213, 87,185, 11,102, 89,219,194,108, 96,148, 4,126,232, 81,142, 14,245,175, 69,174,229, 94,221,160,243, 50, - 73,241,183,107,142, 80,186,214,218,230, 44,108, 15, 88,160,216, 96, 64, 5, 55,174, 80, 84, 22,211,176,183, 52, 23,203,156,204, -121,120, 82, 94,150,138,120,212,179, 40,192,157,118, 39,213,108,129,169,153, 97, 18, 1, 31,132, 5,193,235, 54, 84,184, 21,221, -179, 97, 75,179,128, 92, 75, 92,136,134, 18,235,212, 4,169,204,181,231, 78,220,227,181,165, 62, 64,150,161, 97, 94,213, 79,252, - 52, 70,213,117,174,173, 4, 31, 8, 7, 0, 80, 9, 55,244,250,203,125,199,119,142,221, 83, 86,211, 44,195,242,130, 49,217,152, - 80,212,159,165,163,112,100, 27, 51,227,112, 12,200, 7, 91, 1,226, 65,216,123, 1, 74, 85,240, 17, 91, 62, 4, 4,135,132,106, -104, 6, 4, 0,240,146,213,232,232,106,253,230,226,237,159,163, 35,248,185,247,150,239, 59,103,110,152, 6,176,216, 6,129,211, -108,234,114,115,162, 49,153,167,101, 17,216, 43, 75, 42, 93, 81,234, 76, 62,248,190,127,120,184,191,214, 95,125,243,250,173,221, -187,180,190,177,253,233,227,135, 27,253, 71,116,148, 71,175, 94,190, 24, 7,190, 84,164,207,158, 63,125,183,187,179,186,118, 55, -141, 71,186,166, 38,201,216, 25, 28,109,109, 63,190,126,109,185,213,106,110,110,110,237,237,237,205,218,115, 95,246, 63, 3,174, -245, 87,238, 4,254, 40,142, 71, 51,109,211,106,170,122, 93,142,130,248,225,131,117,251,202,173,247,187, 59,142,231,118, 44, 3, -192, 65, 17, 80, 77,190,161, 75, 65,152,194,230, 98,162, 70,165, 81, 60,189,177,247, 75,109,224,234, 76, 19, 85,209,138,202,109, -167,154,222, 40, 11,105, 85, 97, 16, 97, 58,175,196, 29,187,122, 47,158,196,121, 41,207, 61,109, 6,205, 27, 16,120,195,175,196, -112, 6,153, 1, 29,182,141, 30,156,142,231,221,244,200,170, 20,134, 68,185, 10, 14,184,104,140, 74, 79,210,142, 19,179, 12,135, -234,100, 76,238,103,216, 38, 11, 33, 69, 54, 1,194,202,109,164,132,202,232,147, 28,246,100,173,166,203, 34, 35,169, 72, 30,111, - 10,220,180,136,186,102, 35,184,155, 76,174,243,236, 46, 60,141,221, 41,112, 53,236,222, 65, 79, 44,178,141, 36, 28,166,239, 1, - 59,229,151, 63,248,118,242,181,210, 38,156,206,159, 22,127,228, 75, 17, 11,184, 20,228,185, 39,218,244,163, 16, 47,140,153, 74, -179,162, 92,196, 1,105,198,106, 36, 87, 9, 72, 13,135, 24,107, 48,217,212,128,137,171,109,133,109, 44, 46, 60, 89,233, 46,205, -155, 62,220,188,100, 66, 99,209, 57,183,154, 64,230,142,105, 25,212,189, 65,152, 3,114,129,231, 29,213,167,172,158,208,187,140, - 17, 37, 4,167, 17, 34, 49,146, 73,248,179, 84, 5, 3,150, 32, 18,156,177, 48,112,131, 35,207, 57, 24,185,135,158,247,195,207, -156, 64,139, 98, 52,236,209, 84,193,214,133,133, 14,155,239,216,245,154, 41,136,152,216,153,228,229, 70,151,228,122,203,210,196, -196, 27,230, 97,158, 75, 23, 70, 73, 85,214,148,204, 18, 32,196,190,108, 95, 29, 18, 57, 27,250,195,172, 44, 79, 20,220,198,144, -219,210,182, 77,251, 44,242,121,114, 47, 47, 23, 27,149,204, 8,244, 49,124,215, 77, 98,127, 69,163,102, 88, 70, 51, 66,148, 47, -120, 66,131,143,184,235, 53, 29, 32,126, 28,122, 18,217,130, 67,208, 25,103, 9, 80, 7, 96,234,212, 54, 36,195,101,103,155,243, - 0, 44,140,161,255, 45,149, 55,228, 58, 42,214,165, 93,163, 27,145,251,121,133, 94, 82,165,158,139,221,246,167,227, 19,248, 26, - 52,235, 7, 52, 66,202,121, 30,178,200, 43,213,160, 11,171, 87, 20,158, 83,107, 41,188, 13,226,203, 34, 23,196, 41,161, 21, 81, - 44,254,229,127, 38, 76,185, 65, 77,185, 81,138,255, 39, 1,255, 91, 0,198,206,164,183,105, 40,136,227,246,179,227, 37,117,235, -132, 44, 77, 55, 90, 84,169, 21,235, 1, 33,129,202, 9, 14, 32,132, 42, 56,241,213,144,224, 67,112,129, 11, 66,226,140,212, 3, - 42, 65, 52, 85,213,210,146,116, 73,147,198, 89,237,231, 56, 54, 51,243,236,164, 66, 61,112,141,100, 71,137,236,121,255,153,249, -207,111,198,254, 25,229, 18,163, 64,142, 81,190,180,119, 13, 43,209,114,248,207, 36,158,170,196,184,106, 73,150,175,162, 62,225, - 93, 6,195, 1,202, 94, 28, 45, 82, 99, 84,241,216,255,195, 88, 2,205,145,199,168,225, 9,238, 46, 2, 49, 17,136, 30, 90, 50, -206, 36, 61, 90,123,124,210,172,121,129, 23,137,249, 28, 9,233, 19,228,114,197, 75, 44, 99,138, 64, 48, 88,218, 86, 89, 66, 62, - 35,222, 5,100, 94, 46,119, 59,125,103, 54, 3,114,172,239, 15, 57,162,210,201,102, 3,239, 63,220, 4,164, 58,220,214, 50,172, -243, 78, 19,210,183,163, 70, 13,233, 22, 81,224,113,200, 59,197, 18, 35, 1,174,139,110, 47,223,173,212, 42,161, 28,143, 80,246, -120,183,135,213, 42,101,172, 90,196, 79,152,207,149, 64, 58,129,120, 15, 81,140, 7,231,221,198,169,115, 28,146,109,238,164,115, - 54, 99,102,114,211,249,141,245,135,191, 78,118,153, 49,226,136,249, 84, 48,213,193,213, 75,146,161, 43,166,198, 32,176, 90, 70, - 74, 55,244,118,187,123, 90,239, 28,236, 31, 86,246,246, 7, 3,126, 81,175,183,157,214,253,141, 39,194,211,246,229,211, 7,167, -221, 43, 20,231, 95,110,190,126,247,246,253,139,205, 87, 67,223,203, 46,172, 76,167,205,175,159, 63,110,255, 40,247,123,254,159, -218, 25, 72,205,218,241, 94,105, 46, 83,171, 30,104,134,116,107,237, 70,179,229,212, 27, 77, 72,240, 57,247,175, 47, 46,204,151, - 74,154,102,174,222,188,247,123,247,167,211,108, 61,127,246,116,107,171,140,190, 15, 72,162,117,197,227,240,192, 75,126,196, 9, -202,131,199, 34, 57,213, 2,194,233, 97, 48, 37,129, 17, 87,213,229,100,147, 45, 99, 41, 56,170,204,148, 9,239,210,114,110, 21, -153,113, 4, 75,114, 19, 88, 13, 2,172,105,208,225, 18,195, 35, 90,204, 94,199,214, 29,217, 81, 4,151, 70, 44,180,156,108, 40, - 69, 91,220, 40,138,167,230, 89,178, 57, 36, 42, 76, 23, 33,185, 84,153, 54, 99,218, 28, 43,164,194, 27, 30,101,204, 92,159,247, - 9, 24, 33, 17,124, 34,156, 49,179, 62,106,139, 72,140, 44, 65, 20,164,122, 40, 62,151,240,160, 46,229, 86, 58,184,200,141,116, - 50, 33, 37, 44,221,178,244, 41, 50, 23, 4, 98,113, 40,161,182, 34, 60, 48, 70, 65, 60, 53, 42, 69,134,154,134,131, 12,146, 6, -248, 92, 24, 39,199, 82, 85, 68,119,154, 71,101, 73, 81, 33, 97, 77,210,208,158, 52, 17,240, 44,246, 82, 48,150,204, 45,210,229, -140,184, 31, 68,229, 83, 48,190,227, 67, 98,233,170,165,107,102, 74,205,107,250,155, 59, 75,155, 15, 74, 16,114, 61, 78,150, 66, - 58,194, 68,135, 0,137, 76,170,162, 67, 6,131,226,157,120,191, 12,155,162,232, 63,208,116, 9, 18,193, 84, 90,242, 64, 26, 5, - 56,117, 10,233,155,134,219,245,224,111, 30, 52, 47,142, 42,213,157,250,232,187,155, 63, 84,230,170,172,112,172,228,106,145,189, -231,234,229,179,112,123,199, 41,127,171,246, 42,141,130,235,171,203, 25,105,189,104, 44,229,138, 18, 11, 58,156, 15,195, 40, 22, -176,178,153, 49, 13,207,109,117,112,221,128, 28, 51,139, 40,217,139,231,145, 48,146, 59,189,139,164,135, 42,254, 39,225, 97, 35, -219, 52, 98,102, 66, 62,130, 76, 4,215, 7,219,166,237,250,131,104, 82,177,144,243, 86,126,224,247,177, 53, 68, 77, 44, 92, 12, -130, 85,111,252,242,140,149,245,136, 90, 67,149, 45, 28,120, 20,182, 76, 65,172,162,205, 45, 6,154, 0,113,199, 58,170, 51,184, -143,157,182, 61,180, 63, 98,176,154, 49,236, 46,239,225,254, 28,164,186, 71,217,169,107, 40,180, 19,220, 35,109,130, 83, 33,182, -136,224, 48,107,207,181, 93, 7, 46,193, 78, 18,102, 1,104,213,215, 21,209, 11,141, 53, 56,186, 27, 48,123, 64,100, 83, 64, 46, -196,164,240, 78,238,160,113, 0,148,175,216, 70,153,176,239, 89, 74,209,169,152, 41,255,167,132,255, 43, 0, 93,215,210,155, 68, - 20,133,231,201, 12, 51, 64, 7,164,148, 86,173,173, 15,108,163,137,141,233,162,169,198,196,212,141, 59,211, 95,225,210,196,255, -224,175, 48,241,145,184, 53, 26, 95, 91,163,155,218,196,104,173, 93,105, 42,165, 47,154, 82,160,148,121, 0,243,240, 60, 40,165, - 54, 18, 22, 64, 96, 2,151,123,239,249,238, 57,223,249, 62,233,196,243, 99,111,134,144, 15,235,176,187, 49,247,189, 13,150,132, - 78, 8, 78,252,159,171, 95,183,231, 84,244,131,182,237, 58, 17,121,160, 70, 98, 64,191,132,130, 52,114,117, 82,172, 36,193, 73, -183,160, 75,141, 12,123, 34,150,166,110,226,177,154, 24,215,139,191, 23, 88, 87,216,208,226,152,239,142,196, 76,252,148,124,120, - 4,114, 90,142,139,213, 60,177,123, 26,161,115, 45, 15, 15,128, 2,184,248,160, 53, 84,220, 89, 59, 0, 36, 72, 76, 74, 31,233, -119,161,161,155, 15,238,222, 87,208, 57, 85, 54,245, 4,124,237,137,211,133,164,145, 32, 6, 81,232, 97, 45, 59,100,170,126, 64, - 59,196, 82,113, 57,107,229, 24,183, 90,102, 26,130, 54, 96,251,148,150, 76, 25, 41, 6,158,176,130, 0, 72,110, 84,182,202,245, - 77, 64,169, 1, 37,238, 73,161,135,232,166,232, 82,171, 86,155,149,134,211,120,185,248, 26,214,122,203,139,154, 54,210, 0, 89, -147, 68,228, 44, 21,137, 51,144,225, 6,185, 19,132,114,177, 84,134, 63, 98,173,180,250,230,221, 43,215,110,210, 24,119, 4, 42, -131,195,131,233,235, 87,139,171,191,170,213,157,150,103,195,254,211,216, 94,219, 44,150,182, 43, 7,223,151, 86,222,127,120,251, -233,243,199,199, 79,159,249, 62,236,203, 26,106,153, 42,200,160, 87,100,169,237,133,182, 19, 56, 94, 56, 59,115, 99,126,254,222, -202,207, 69, 24,165,203,147,163,215,166,198,231,238,220, 86, 20,173,213, 10,235, 13,127,125,219, 13, 40,115,162,138, 0,248, 20, - 77,137,241,185, 55, 38,233, 61,207,160,120, 44,193,122,181,114, 87,198, 22, 59,196,136,247, 2,251,134, 11, 35,179,103, 87,236, -214, 65, 31, 33, 10,179,111, 99,185,243, 50, 61,142,161,205, 11, 54,199,195,211,173,218,186,231, 55,169,148, 34, 81, 79, 3,146, -160,146,241,116,207,127,148,142, 14, 6,202,131, 10, 18,172,174,222,244, 43,239,239,240, 22,188,239, 86,249,224,140,100,115, 69, -247, 58, 54,173,109,245,194,240,132,143,150,131, 66,195,171, 41,120, 54, 50,176,120, 67, 99, 78,204,125,204,151,103, 18,131,165, -202, 31,248, 41, 3,134,149, 77, 12, 89, 70, 6,253,158, 2,175,102,215,186, 96, 36,146,184,248, 0, 23,130, 41, 39,247,120,108, -146,232,249,142, 79, 74,162,128,226,217, 92,250,200,163,154, 12, 32,224, 21,216,250, 21,204, 8, 70, 49, 69,206,152, 25,142, 64, -221, 18, 33, 75, 29,144,102, 11, 92, 36,109,100, 44,195, 50, 84,236,188,199,175, 70, 77,124,228, 39,140, 84,224, 68,220,210, 20, - 53,174,106,178, 20,203,203,218,195,155,147,115,211,163, 29, 68,235,184,125,211,189,167,251, 27,193,200,170,128,202,145, 46,137, -227,204,221, 65, 1,123,190, 38, 7, 4, 51,133,231, 43, 33, 84,185,159, 85,145,201,134, 44,172,151,119,191, 46,111,252,240,207, -250,227, 51,198,224,152, 28, 51,209, 54, 70, 80,117, 89,131,128,151,206,230,206, 92, 44, 12, 95,153,170, 14,140,191, 88,112,159, - 63,250, 82,124,242, 13, 32,128,112,235,210,185,217,194,104, 30, 89,109,228,118,135,124,149,124, 33, 55, 18,215, 67, 10,184, 40, - 91,175, 91,128,136,201, 79,132, 85, 59,216,232,155, 8, 20, 76, 60, 15,176,201,145,188,235,152,116, 36,118,200,227, 12,167, 83, -219, 59, 12,132,252,241,104,207,221,165, 74, 42, 6, 39, 36, 75,160,100, 66,135,173,178, 53,228,253,115,133, 28,161,190,221,110, -142,164,243,221, 26, 12, 85,110,147,122,146,164,114,144,102, 74, 42, 14, 81,245, 96, 15, 46,145, 49,178, 2,170,128,236,179,200, - 22,123,205,214,109, 20, 25,148,250,234, 67, 0, 92, 0,194,146,113,138,146, 79,159,133,127, 86,215,205,128,168, 92,148,156,246, -221,118,171,207,160,229,136,231,232, 96,125,254,232,102,234, 41, 69, 82,254, 37, 76,242,196,225, 76,148,192,173, 66, 56,249,219, - 39,218, 53, 4,225,184, 72,244,241,216,240, 87, 0,178,174,228, 53,141, 40,140,207,162,227,140, 70,141, 53,141,137, 86,163,198, -132,210,157,210, 82, 40,129, 4, 90, 10, 33,135, 94,122,232,161,127, 77,255,157,210, 67,105,146, 83,104, 74, 67,160,189,180,144, -165,144,224, 37, 80, 4, 99,181, 46, 51,206,230,204,235,247,125,239, 25, 19,130, 50, 23, 69,103,121,239,125,203,251, 45, 87,243, -119,121,226, 52, 41,140, 75,194,209,180,129,198, 11,236, 98,119,100,252,198,158,137,176,200,146,175,123,250,200, 99,183, 60,241, - 57, 71,119,134, 68,203,146,132,155,170, 55,114, 99,154,158,138,103, 2,241, 83,114,113,166, 4,211,134,231, 86,240,242,124,143, - 48, 54,138, 58, 81,211, 71,174, 41,246, 74, 89, 0, 15, 44, 20, 2,150, 60, 32, 35,156,129,103,253,170, 50, 54, 47, 64,254, 8, - 74,176,191,126,182,209,234,181, 28, 50, 66, 35,165, 35,105, 38,153, 77,233,137,237, 95, 59,212, 23,129,105,169,245,135,131,223, -141,211,119,171,111, 15,206, 14,124, 18,214, 37, 29, 46,177,237, 67,247,120,100,185,118, 62,147,239, 88,109, 93, 51,218,102, 7, -241, 24,254,208,246,108,184,158, 82,182,104,186, 38,228,112, 40,136,192,148,245, 39,175,234,141, 58,156, 65, 24,202, 58,121, 1, -194, 29, 91,156,171,253,233, 54,112,220, 35,147, 21,149, 9,156,104,128,243, 78,133,204,157, 25,186,130,251,190, 24, 39, 20, 67, - 67,141,191,137, 33, 71,200,213, 25,195,133,114,225,254,237,165,159,251, 59, 78,255,124,111,111, 23, 6,211,218,234,243,135,143, - 30,231,114,179,229,234,226,247,111, 95, 62,125,252,176,181,185,105, 15, 77, 67,143,226,218, 37, 69, 44,199,143, 27,233,106,165, -182,255,227, 96, 48,148,138,249, 37,219,147, 15, 79,234,228, 20, 18,190, 88, 91,153, 47, 20,190,238,238,190,220,120, 3, 85,249, -241,225,113,181,186,252,121,107, 27, 81,228,126,104,251, 35, 40, 42, 97,226,187,142,203, 41,131, 16,149, 29,207,154, 77,231,135, -152, 23, 99,218,129,186, 54,132,131, 32,141, 17, 46,116,133, 15, 94, 83, 53,238, 29,140,201, 97, 24, 36,180, 41, 42,227, 68,244, -239,152,109, 56,166,180, 36, 58,240, 49,118,169, 7, 13, 11,247, 20,172,170, 23,185, 9,214,203,151, 90,130, 83,122,210,242, 48, - 90,140, 56,234, 70,226,174,208,116, 84,196, 54, 0, 82,220, 24,155,207,150,168,186,194, 62,111,207,250,103,104, 6, 85,120,168, - 59, 68,200,174, 64, 88,145, 41,220, 18, 73,177, 93,139, 35,216,161,158,139,107,241,142,213, 34,192, 67,140,176,164, 18,212,248, - 70, 12, 53, 73, 74,217, 5,211,238, 94,182,122,224,103,197, 41,239, 36,186, 25,142,249,186, 98,228, 32,111, 32,158,244,125,168, - 8,177,195, 11, 53,177,139,142, 66, 72,237,142, 69, 99, 2,178, 73,112, 45,126, 69,112,111, 29, 15, 69, 95,164,177,172,129, 66, - 17, 79, 37,201,235,168, 26, 38, 96,125,215,212,164, 36,191,127,179, 82, 94,127, 32,153,110, 4, 45,183, 8,232, 72,233,187, 68, -234, 44, 10,174,202, 8,154,140, 35, 8, 6,241,101,136, 95, 64,144, 32, 4,191,136,148, 43, 74,201, 12,249, 37,135, 4,182, 39, - 53,199, 32,176,122,189,147,122,163,159,188,151,175, 44, 15, 45,207,243,177,165, 0,213,158, 74,233, 61,196,220, 80,142, 56, 30, -170,195,148, 42,165, 66, 49, 55,117, 35,115,212,244,142,118, 78, 43, 42,211,158,222, 50,210,137, 68,223,181,134, 14,105,235, 49, - 21,242, 85, 95,110,118, 60,126,195,225,194,113,228, 48,193,232,226, 29,117,206, 50, 89,202,215, 98, 81,189, 99,118,239,150,238, -184, 35,223,166, 98,125,236,205,194, 72,243, 78,228,230,194,241, 85, 22, 46,202, 66,193, 94, 52, 30, 4,226, 30,183,187,232, 99, -152, 66,181,185, 69, 8, 24,205,238,185,224,166, 42,145,116, 34,221, 30, 52,209,163, 65,184,165,203,240,215,229,217,242, 95,179, -133,144,124,174,177,133, 36,187,248,205,212,220,192,235,139,209, 71,221, 35,142,236, 25,255,157,164,107,137, 70,231, 12,226,254, -208, 49,209, 30, 0, 30, 40,234,131,146, 24,133,204,216,196, 67, 94,172,171, 73, 35, 77,186,184, 1, 95, 99,145, 77, 66, 85, 5, -155,176,123, 25,124,135, 64,101,220, 63,164, 48, 29,207, 32,163, 28, 3,140,116,209, 51,185, 42, 7, 41,179,107,126, 32,112,248, - 47, 0, 85,215,177,219, 68, 20, 69,167,188, 41,111,154,187,211,228, 20, 22,192, 34, 8, 80, 0, 9, 33,144, 88,129,196, 47,240, - 79, 17, 31, 66, 22, 72,240, 7, 72,148, 77,136, 16, 82, 18,146, 40, 74, 66,138, 33,138,199,246, 84,123,204,189,247, 61, 59,206, - 42, 11,199,214, 88,190,229,220,118,206, 84,124,151, 37,176,108,137,142,198, 60, 94,177, 28, 8, 72,154, 54,120, 94,131, 54,105, -209,166, 77,143, 84, 29, 6,234, 77, 70,236,177, 54,252, 13,141, 18,117, 50, 64, 71, 38,128,129,207, 3,108, 95, 12,242,140,100, - 24,197, 91,179, 28, 23,110,133, 84,176,236, 63, 78, 95, 68,200, 79,197,152,238,219,149, 18, 15,226, 65,164, 93,255,162, 74,171, -186, 8, 16, 9, 50, 4,129, 29, 69,112,153,137,114,106,251,120,167,159, 70, 79,111, 63,250, 19,182, 53,170,202,163, 44, 10,227, - 30,182,103,153, 14,104,189, 18, 84,227, 44,169,184,149,157,211, 3,176,224, 94, 26, 97,229, 94,228,220,116,163, 44, 22,164, 66, -200,174, 49, 26,118,163,238,210,204,114, 39,234,180,106,139,144, 78, 83,100, 61,195,132,211,137,123, 67,154,101,141,242,162,222, -108,213,131,230,214,254, 22, 20,187,120, 91,111,216,115,213, 5, 72, 48,150,105,173, 46,174,238,253,221, 35, 98,213, 33, 56,139, -226, 22,182, 65, 96, 11, 69, 30, 84,206, 21,238, 64,172, 87,109,166,187,142, 26,184,154,239,168, 16,247,137, 98,167,176,172,145, -161, 15,118,183,127,110,108,124,216,220,220,132, 4,228,123,154,109,107, 15,158,189, 89,185,179,182,179,245,237,221,250,250,225, -241, 41,248,134, 97, 34,193, 89,150, 22, 73, 50,236,246,210,114,165,244,240,222,253,207, 95,190,130,193,207,207, 54,203,229,224, - 96,127,191, 90,230, 22, 67, 13, 69, 29,101, 88,210, 39,207, 95,159, 29,254,250,244,241,125,251,226,252,228,228,196, 50, 69,107, - 25, 80,144,222,108, 84,123,189, 56,203, 48,114, 1,250,112,205,210, 69,183, 93, 16,201,204,245, 81,130, 60, 27, 44, 0,206, 15, -105,220,130, 93, 56,186,228, 17, 56, 22,237,117, 50,191, 25,111,139, 32, 43, 8,158, 65, 13,166,183,120, 71,196, 0,209, 8,102, -194, 56,212,212, 27, 99, 57,139, 33,151, 25, 33,154,169,177,228,136,116, 76,201,159,176, 86, 34,241,116,176,174,171,254,101,154, -246,225, 17, 25, 51, 36, 69, 38,145,149, 17,181,137,100,206, 41,243,138,205,156, 44, 23, 29, 27,141,184, 34,112,119,220,212, 89, -134,205, 89, 44,252, 39,219, 19, 73,134, 27,159, 61,242,255,170, 91,131, 39,209,198,148, 5, 3,114, 63, 97,245,166, 97, 58,150, - 7,240, 5, 10,130,146, 87,129, 58, 93, 56, 17,157, 71, 73, 69,120,145, 2,179, 2,143, 65,133,109,207, 85, 22, 24, 51, 1, 75, -137,107,187,185,242,124,156,198,210,182,233, 15, 29, 35, 51,219, 64, 25, 38,207,178,116,221,121,181,178,244,242,237, 11, 37,112, -148,186,171,132,125,150, 15, 10,161, 3, 70,164,112, 66,106,213,102,204,133,188,100,155,168,177,158, 35, 3, 6, 49,131,170, 28, -170,214,214, 45,197,247, 48, 98,228,200,154,148,227,107, 16, 86,147,163,131,227, 43, 99,101,249,238, 90,146, 0,174,231,220,230, -196, 69,137,235, 8,196,245,129,149, 28,238,222,104,140,251,190, 19,148, 44,238,207,206,212,152, 31,124,255,113,198,127,159, 85, - 31,207, 91,117, 15, 66,124,183,159,224, 90,189,162, 6, 53,214, 63, 74, 46,243, 76,151,250,210, 98, 21,125,228,154,220,179,189, - 8,225,145,210, 40, 55,118, 79,247, 28, 30,128, 99, 94,116,218,200, 78, 74, 67, 87,169,142, 61,158,153, 59,182,143,146,181,130, - 46,163,144,225, 97, 60,201,152,240, 75,139,112, 38,210, 61,166,250, 90, 80, 3, 64,150,102,169, 24, 2, 33, 15,168,198, 28,203, - 69, 24, 65,244,192,240,143,240,213,195,184, 3, 32, 0,188, 49,224,165, 8, 27, 65,104,145,255,194,243,225,120, 53, 11, 2,149, -107,187, 0,199,134,242,166,143,150,192,200,176, 73, 83, 16,219, 63, 56,177,195,187, 57, 60, 57, 1,243, 7,224, 88,226,229, 56, -239, 79, 36,136,177,178, 47,134,144, 9,228,208, 72,232,181, 76, 29,147,210, 10, 74, 46,217, 16,112,207,184, 19, 38, 29,186, 34, - 20, 2,175,163,107,106,232,155, 33,126,210, 69,215,198, 13,156,255, 2, 80,117, 45, 61, 77, 68, 81,120, 94,157, 14,211,161, 51, - 29,166, 60,154,130, 13, 2, 38, 4, 23, 24, 23,254, 8, 13, 63,207, 45, 59, 23,238,220, 24, 18, 18, 37, 81,211,152, 24, 69, 13, -186, 48,172,160,133, 54,165,143,233,188, 95,158,115,238,157,162, 59, 10,233, 45,153,158,123,158,223,247,157,210,191,203, 18,255, - 21,141,152,114,132, 34,231, 78,173,137,210,222, 52,238,175, 86, 80, 75, 65,226,203, 99,114, 54, 19,101,156, 32,200, 7,170,178, - 70,251, 72,243,197,138, 88,118, 43,153, 58,155,248, 79,255,148,253, 13,158,201,147,237,103, 35,119,144,145,116, 52, 35,172,102, - 8,170,169, 48,217,126,169, 44,123,139,114,135, 33,161,212,216, 10,107,129,140, 56, 33, 12, 99, 86,174,204,198,119, 64,196, 14, -162,185,109,216,224,148, 19, 52, 38, 74,225, 69,113,103, 99, 7,202, 43,120, 57,241,221,148,184,139,237,149, 86,203,218, 24,123, -119, 40,236,130,169,122, 62,114,239,252, 36,130, 28, 13, 78,235,143,251,164,127,148,153, 53,107,197,116,252, 8,105, 53,105,193, - 24,204,152, 68,192,105, 65, 24, 52,106,182, 85,107, 64, 84,128,160,194, 58, 75,144, 20,128,125,232,186,121,252,229,245,166,186, -117,250,254,109,203, 90, 31,249, 99, 36,139, 4,115,248,247,163, 52,190,188,185,132,195, 15,218, 7, 61,247,198,174, 54, 2,213, - 71, 6,109, 6,198, 32,197, 81, 49,243,178,152, 72, 65,138, 88,137,147, 34, 77,149, 32, 68,209, 37, 28, 83, 43,185,166, 22,211, -153,119,213, 27,160, 47,193,105,172, 50,115,179,159,231,191,150,228,236,209,254,222,171,227,151,215,189, 30, 92, 63, 47, 72, 61, - 47,245, 33,250,225,110, 88, 28, 86,218,150,177,187,179,253,233,115, 23,108,126,217, 48, 58,157,205,139,139, 11, 73, 86,133, 66, -190,190, 25,126, 59,255,254,226,249, 81,103,239,113,247,236,164,219,253,216, 31,222,249,126, 22,135,121,152,176,237, 78,121,211, - 90,134, 16, 53, 24,142,209,157,229, 50, 34,214,147, 64, 16, 74,114, 57,223, 83, 92, 84,229, 42, 60, 31, 42, 33, 69, 85, 89,130, -152,193,208,193, 82, 57,114, 95,176,213,196,210, 55, 83,230, 66, 82, 89,121, 78, 87,171, 82, 80,243, 13,156, 35, 78,195,248, 34, -198,123,217,108,214, 92,150, 22, 61,107,178, 49, 68,250, 43, 10, 4, 23,200, 20,249,104,178, 64, 13,242,195,206,211,137, 63,134, -139,141,108, 85, 74,165, 37,198,233,160,238,246,138,225,192,169,144,115, 33, 17, 73,128, 60, 23,238, 97, 35,205, 99, 36, 82,197, - 62, 38,143,164, 81,195,171, 79, 82,162,226,224, 91,145, 87,202, 5,159, 21, 18, 84, 20,157,136, 99, 27, 14,100, 12, 33,194, 80, -210, 76, 72,161, 32,152, 7, 51, 12, 3,100,161, 4,140, 42,235, 95,248, 34, 52, 51,198,245,184,188,135,239,134, 51,194,252,240, -137,171,135, 43,223,242,114, 38,201,156, 59, 87,146,129, 50, 75, 87,225, 71,225,104,183,253, 64, 40,134, 95,167,170, 82,151, 91, -138, 48,245, 37,184, 22,216, 94,196, 72, 43,227, 86, 94,105, 9, 66, 77, 77,175,168, 50, 56,255, 0, 61, 28,238,236, 69,255, 94, - 85,229,173,135, 66, 77, 67,155,142,146, 34,140,162, 36,142,130,200,157, 78, 7,179, 74,173,185,255,238,195,233,201,217,155,243, - 31,159, 6,183,125,203,112,108,219, 97,200, 21,108,225,224,234, 28, 72,140,144,254,106, 53, 77,236,114, 40, 90,173,110,218, 78, -227,207,173,159,253,190,106, 30,174,169,203,186, 50, 14,230, 81, 12, 15,172,162,169,226, 60,191, 28,185,124, 88, 65,243, 42,188, - 74, 80, 35, 98, 59, 38,101,116,135, 48,142, 32,119, 78,200,119,171,106,181,105,174, 87, 85,213, 3,207, 40,146, 52, 21,162,150, - 83, 40,223, 83,234, 54, 66, 96, 70,165, 54, 18,106,133, 0, 80,215,234,200, 48, 72, 83, 83,183, 16, 68, 75,245, 59, 91, 97, 8, -207,144, 42,134, 98,205, 92,243, 98, 15, 18,175, 57,124,233, 89, 2, 65, 29, 62,182,174,155, 34,117, 35, 36,154,216,194, 13,133, - 67, 2,130,238,172, 90,171,179,208,109, 59,155,182,222,152,248, 83,198,244, 68, 9, 62,244,123, 5, 19,144,208, 53,131,218,111, - 60, 20,149,176,125,174,234,175, 98,241,151,192,135,114, 55,197,242, 83, 50, 95,211,176,253,112, 86,220,247, 63,184,160,191, 84, -202, 7, 72, 92, 14,169,100, 1,163, 80,176,217,178, 90, 99,127, 34, 46,118,247,114,183, 94,252, 79, 8,189,119,250,127, 5,160, -235,234, 90,155, 6,163,112,146, 53, 73,211, 52,237,218,178, 58,252,152,236, 3,101, 42, 50,189, 28,234,127,240, 70,216, 31, 16, -188,244,239, 8, 94, 8,187, 16, 84, 6, 42,138,119, 34,130, 58, 81, 68,111, 68,102,157, 48,221,218,181,179,109,154,143, 38, 75, -235,115,206,105, 90, 21,100,151, 13,109,150,188,239, 57,207,121,207,115,158,103, 20,223,153, 50, 60,114, 90, 45, 59,101, 59,227, -232,170,209,139,220,146, 83, 9,185, 33,150, 40, 99,109, 40,222, 59, 36, 65,167,135, 84, 89,196,216, 15,120,166, 61,190, 87,246, - 42, 36, 13,175,132,135,213,139,185,146, 73, 72,200, 32,135,226, 84,251, 78, 82, 20,192,172,232, 67,201, 46, 63,117,244, 12,246, - 97,215,239, 8,149, 50,245,153,165,227,111, 84,190,216,255,196, 72, 37, 90,113,134, 39,108, 99,201, 46,211, 68,112,238, 75, 77, -205, 67,219,131, 74,190, 10,244,196,102,170, 44, 95,167,202, 57, 15,173,122,210,225, 75, 14, 89, 25,123,216, 13,220,253,222, 1, -175, 12,148, 66, 78,217,169,116,124,220,255,208, 13,122,109,191, 43,230,118,248, 20,144,191,225, 54, 81, 81, 38,169, 10, 58,143, -218,170,121, 43,223, 79,162,182,223,166, 59, 97, 50,237,220,204,201, 70,187,137,149, 26,162, 44,112,221, 76,221,184,183,177, 94, -111,238, 90,166,133, 82,160, 90,156,105,123, 29,238,149, 17, 18, 75,212, 33, 18,242,133,133,149, 90,125, 43,178,176,210,105,239, -225,139,145, 67,188,144, 4,182,113,141,141, 74, 88,215,178, 68,117, 80, 1,217,144, 91,189, 0,245,189,202, 74, 48,138, 8,124, -227,135,251, 97,191, 90,157,189,126,227,230,179,199, 79,214,239, 62,192, 83, 7,176, 35,124,195,170, 70, 60,207,130,208,128,202, -192, 92, 93,189,188,245,117,135,189,113,244,133,249,165,215,111,223,163, 14,203, 89,122, 54,163,160,116,191,182,182,230,148,103, - 31,221,191,221,216,111, 33, 50,116,123, 73,183, 23, 70, 17, 21,249, 22,130, 71,222, 88, 92,152,255,240,233, 51,112, 64,194,174, - 80,150, 89, 20,235, 86,153, 36,207,154, 54,118, 5, 96, 98,217,153,161, 38, 7, 53,168,227, 73,181, 57,233,249,255,229, 19, 41, - 56,100, 32, 38, 46, 10, 13,130,179, 42,183,216, 5,169, 98, 72, 45, 4, 88,178,234,165,115,140,196, 78,137, 85,227,118, 43, 77, - 80,170,153,132, 22,152, 66,186,111, 52,177,161,176, 83,133, 65, 66,164,124,152,203,173,176, 92,116, 24, 24, 70, 14,152,202, 64, - 77, 66,163, 88, 1, 2,129, 54,106,182,209,239, 16,124,165,217,209, 4,185, 65,130,175,154,154, 36,171,130, 54, 82,105, 89,236, - 23,199,204,115,107,142,240, 96,201,174,224,186, 32, 14,125,252,177, 40, 21,183,118, 75,204,145, 31,233, 67, 13,184,198, 24,243, - 70,241, 37,209,160,159,254, 35, 44,234,198,210, 76,127, 24,119, 78,196, 74,166, 70, 7, 79,196,243,211,169, 11,162,103,117, 29, -217,244,234,233,227,166, 57,253, 42,156,251, 94,143, 23, 47,218, 74,167,163,133,132,209,145,254, 85,166, 23, 91,186,225,216,150, -157, 55, 73,167, 58,138, 67,132, 52,242,193, 35, 64,131,135,144, 61, 54,175, 20, 44,186,155, 48, 74,188,176, 23,246,125,207,111, -181,218, 47, 63,110,223,121,120,235,233,230,243,189,221, 90,237, 71,109,243,203,187, 23,111, 54, 14,189,120,121,233,188, 97,232, -196,109,193, 93,200,112,201, 84,166, 92, 41,169,136, 6,212,151,193,109, 25,197, 66,113,123,207, 53,190,253,156, 94, 57, 98,105, - 83, 81,211, 3,198,192,165,150,161, 53,118,251, 1,123, 22,138,254,199,200,226, 99, 16,139,241, 99, 16,251, 41,151,122, 40,103, -238,110, 64,220, 68,108, 49, 89,237,162,159,114,233,220,149,157,214, 14, 22, 6, 5, 31,130,203, 3,233,177, 47,159, 56,219, 34, - 25, 50,138, 24,220, 68, 37,242, 52,242, 61,106, 89,141, 84,187,135,128,170,109,175, 13,208, 22,240, 9,240, 24, 53, 32,171, 33, -110,224, 77, 97,169, 32, 67, 88,166, 77, 39,108,204,199, 79, 72,232, 34, 6, 2, 16, 23,117,141,181,214,228,112, 95, 56,227,248, - 90, 92,204, 42, 81,244, 2, 11, 86, 1, 72, 78,180,235,228, 37,227, 33, 75,183,120,236,186, 58,177, 99, 69, 76,227,236,174, 77, -240,203, 80,253,151, 75,165, 49,209,106,180,102, 80,219,253,242, 15, 82,163,246, 33,183, 52, 84,146,199, 25, 12,254,215, 95,253, - 45, 0, 91,215,178,211, 68, 20,134,207, 76,219,105, 75,111,216, 78,161, 84, 48,186, 48, 49, 49, 17, 47,137,241, 9,136,134,141, -137,225, 5, 76,186,144,119, 33, 62,128,110,124, 12, 93,187,193,133, 27,118, 32, 81, 20, 2, 8, 21, 74,103, 58, 51,103,152,142, -255,247,157,105, 33,198, 46,155, 52,211,158,211,243,159,255,242, 93, 12,254, 93,153, 6,191,249,222,242, 31,157,107,116, 64,215, - 28,253, 9, 48,208, 32, 19, 40,243,163,202,198,185, 82, 31, 45,180,150,238, 47, 45,239,159,238,201,189,234, 99,201,240,164, 60, -175, 80,248, 51,113,198, 51,140,134,212,233, 45, 68,242, 87,206, 8,126, 89,107,222,168, 57,155,179, 44,191,174,239,157,122,193, -192,154,168,229, 25, 38,140,100, 85,247, 22, 31, 92,140,206,225,219, 66,109,104,227,209, 8, 89, 84, 40, 29, 88, 22, 37,202,167, - 64, 73,115,198,194, 48,160, 80,176,233,203,243, 34, 77,104,137,113, 5, 80,176, 13, 43,177, 62, 83,239, 54,187,251,253,131, 1, - 92,125, 19, 26,202,208,124,212,200, 27,209, 97,221, 24,253, 38,134,153, 67,252,109,215, 93, 58, 30, 28,117,111, 44,202, 69,120, -120,126, 12,194, 23,215, 80,202, 40,121, 88,171,218,246,227,225,183,221,237,195,147, 3,137,251, 26,210,213, 81, 2,175, 63, 73, -203,199,121, 9, 82, 16, 70,141,229, 77, 29, 75,126,237,231,170,182, 28,185, 32,196,193,139,233,194, 42,143, 44,231, 10,118, 98, - 7, 33,228, 64, 57,124,178,128,196, 4,233, 41, 37, 95, 73,210,153,148,182,150, 8,253,189, 94, 79, 54,112, 99,227,237,147,229, - 71,191,143, 14,201, 0,130,203,153, 20,129,177,134, 72,164, 68,105, 41,111,215,223,172,175, 60, 95, 89,123,245,114,117,245,197, -101,228,111,126,217, 44, 21,161,206, 51, 10,244, 66,123,126,237,117, 79, 37,241,135,119,239, 79,135, 17, 85, 79, 18,199,130, 24, -153,241,139,174,151,202,161,175,191, 31, 28, 23,114, 69,148,240,105, 18, 74,112,164,143, 95, 14,116, 4, 77,214,122, 42, 1, 81, -174,121,123, 10,250, 82,214,191,147,159,204,228,224,202, 31,198,192,113, 51,128, 57, 73,105,166,151,106, 3,162, 78,169, 25,179, -137, 6, 27, 55, 54,140,132, 12, 43, 60,197,212,160, 41,202,130,156,220, 78,142, 1, 82, 66, 52, 50, 16, 13,246, 78,226, 8,249, - 35,220, 77,148,249, 85, 30, 17, 36, 90, 21,140,197, 40,201,207, 44,204, 48,230, 32,182,147,217,174, 90,116,161,201,163, 17,127, -169,221,198, 28,218,244,224, 76,200,218, 70, 68,118,167,161, 14,169,152,143, 4,144, 13, 93,204, 10, 37,127,143,129,180, 67, 98, -212,153, 93, 64, 32, 32, 5,111,210,116,204,148,148,166,120, 72, 18,169, 82,183,214,146, 7, 73,224,148,115, 84, 42,204, 84, 74, - 85,246, 63,199,236, 26, 35,121, 7,210, 81,174, 43,201,175,108,251,161,235,198,243, 79,207, 84,209,243,245,173,162,237,180, 19, -213,247,168, 47,135,122, 82,118,183, 38,159,111, 53, 85,165,146, 4,129, 47,233,177,134,205, 41,192,147,168, 8,243,141,206, 45, -244,118,242,240, 31, 72, 36,181,241, 61,111, 56,218,218,222,253,248,249,211, 88,123,119,171,234, 78, 69,117,203,170,229, 40, 73, -112,190,238,108, 73,110,255,120,249,153, 83,130,164,129, 83,148, 98,187,224, 20, 11,205, 78,211, 98, 3,128,195, 76, 48,167,235, -179,245, 95,251,231,183, 93, 75,221,172, 58,253, 81, 16,201, 37,170, 74,229,220,143,157,179,129, 84,207,144, 44,118,100,131,185, -224, 0,202, 38,202,116,255,233, 34, 73,198, 56,213, 18,128, 54,208,252, 41,182, 17, 49, 0,222, 48,255,243,100, 15, 23, 48, 61, -161,212,181,204,225,228,236,136,132, 60,182,118,105, 53,104,131, 13, 27,101,211, 32,139,218, 88, 84, 43, 54, 81, 72,130,146,172, - 13, 74,135, 52,113, 0, 69,206, 55, 43,238, 69,116, 17, 73,196,179,149, 91,107,123,145,135, 54,163,201,200, 51, 88,223,148,170, -111,160,125,120,181,171,109,169,251,107,165, 26, 88,108,146,140,150, 27,218, 56,184, 18, 17,163, 97,173, 48,213, 80,176,174,187, -125, 1,128, 48,137,230,178,255, 82, 34,132,144, 0, 73, 51, 31, 44,149, 9,215,167,147,238,228, 4,212, 56,149,202,176, 56,135, -111, 5,122,100,228,122,254, 27,226,255, 10,192,214,213,244, 38, 17, 69,209,199, 99,152, 25,102,166,237,240, 85, 10, 72,211,104, -109, 34,213, 6, 77, 12, 11, 87,238, 93,152,184,241, 71,152, 24,127,143, 27, 87,254, 19, 93, 24,173,105, 45, 77, 26,235, 23, 77, -106,169, 22, 10, 76,203,192,192,140,231,222, 55,208, 46,220, 17, 8,240, 6,222,220,123,206,125,247,158, 19,207, 55, 33,207,112, -250, 96,115,250,132,252,227,181,251,195,158, 58,135,140,213, 63, 52,147,115,140,106, 91,166,196, 5, 18,250,243,244, 80, 29, 80, -171,240, 58,101,117, 79, 41, 84, 75, 12, 21, 55,168,201, 86,211, 61, 53,176, 39,174,154, 60,227,143,157,147, 79,174,162, 72,169, -252, 51,137,187,221, 91,171,255,237,181,241,201,167,131,147,113,232, 43, 29,253,220, 98, 97,189,184,129, 8, 18,198,197,211, 4, - 31,223,113,247,177,144,197,133,101, 80,102,134, 99,177, 53,176,178,159, 76,198,254,145,241,148,138,154, 84,164,128, 64, 71,233, - 58, 82,250,152,109, 70,241, 63, 24,134,149,100, 26,192,163,138, 20,154,149,230, 6, 16, 19,126,229, 9, 55,182,112, 8, 64,132, - 5, 3, 31,113,121,135,156, 28, 26,183, 31,238, 29,237,227,211,203,185, 74,110, 49,215,241,186,212, 24, 46,249,240,134, 97,105, -192,210, 87, 92, 22, 8,129, 35,106,229,187,157, 33, 21,109, 82, 66,115,114,164,252,103,235, 41,215,214,236,180,102,232,132,139, - 10,142,225,166, 53, 51,157, 0,118,214,212, 16,165, 70, 23,162,235, 9,220,250,166, 46, 12,242,167, 18,195,203, 73,227, 65,227, -233,179,231, 88,210,239,214,225,171,151, 47, 62,125,120,223,233,246, 16, 16, 72,124, 36, 68,124,167,190,206, 0,228, 59, 24,127, -255,214,220,254,248,238,243,246,135,253,189,221,157,221,157,211,179, 19, 16,237, 96, 18, 13, 46,253,251,245,173, 71,143,159,180, -190, 54, 95,191,121, 43,166, 64,232, 92,225, 4,145, 31, 81, 36, 0, 17, 95,118,237,131, 31,199,158,231,211, 57, 24, 85, 6,217, -127,155,147,244,205,149,141,206,224,204, 49, 23,167, 12,171,231,243,214,242,154, 81,217,204,215,151,182,103,198, 2,229, 26,202, -196, 92, 73,140,138,205, 69,183,132,219, 3,248, 32, 98, 87, 78,229,141,200,123, 41,153,152, 43, 51,177, 62, 23, 16, 58,169,181, -196, 30, 61, 4,106, 73, 48,148, 70, 58,117, 45, 73, 7,161,105,178,213,166, 18, 52,187,204,197, 58, 7,116,187, 77, 65,150, 53, - 94, 54,189, 19,168,141, 68,160,121, 55, 7,108, 9,135,213,108,173,214,219,231,237,153, 73,232, 12,107,241,210, 65,215, 44, 61, -141, 8, 73, 83,199, 92,111, 85,206,156, 82, 41,103, 51,135,198,119,229,173,172, 31, 12,101,220,225,174, 84,241, 4,113, 14,164, -243, 9, 77,201,129,164, 98,169, 97, 24,196,253, 93,156,236,150, 28, 55, 8, 64,133,101, 37, 87,233,121, 61, 32, 6, 42, 60, 74, -234,208,224,163, 93,130,126, 43,153,138,239, 95,232,196, 75, 36,246, 0, 53, 70,138,177,105,151,138, 27, 13, 37, 85,116,116,212, -189,117,199, 17,157, 46,217, 60, 78,148,195,184,182, 84,200,139,181,117, 97,101,162, 62, 88,101,159,218, 32, 3,206, 99, 4, 88, -228,114,161, 44,220, 5,108, 38, 92,222,228,220,235,116,189, 78,175,255,165,185, 47,123,199, 85, 83, 20,117,225, 36, 69, 54, 41, - 50, 41,225,104,212,173,213,108, 29,172,230,171,155,155,117,252,228,166, 97, 24,184, 24, 51,149, 47,231, 1, 52, 72,133, 38, 69, -146,196,120,160,102,191, 47, 90,199,217,218,162,230,135, 65,159,240,141,233,164,100, 91,254,234,247,163,248,223,157,112,189,133, -198,197, 71,220, 18,139, 39,107,213, 77,188,234, 13, 47, 74,217,146, 31,248,216,101,213,236, 13,203,196,117,232, 35,242, 80,141, -240, 24,223, 80, 91,173,245, 46,187, 4, 53,176, 89,147,164,114, 95,114,203, 0, 28, 58, 18,135, 72, 84,178, 85,106, 90,227,193, -220,180,158,118,237,204,130,237, 34, 91, 91,186, 99, 27, 22,194,183,242, 97, 99, 87, 18, 26,168, 12,249,228, 31,132, 30,193, 61, -226,141,133,149,120, 99,143, 89, 91, 34,140,253,249,226, 99, 33,133, 51, 98, 13,101, 46,193, 96,157,120, 29,247, 87,126,169, 48, - 24,158,143,198, 35,197,240,184,120, 19,205, 20, 76,163,217,140,147,140,174,244,165,229,117, 46, 27,132,129, 18, 98,153,113, 87, -122, 15, 13, 62,178,110,249,245,182,201,185,124, 0,151,233,137,113,206, 10, 50,255, 9,241,255, 4, 96,235, 90,122,155,184,162, -240,153,183, 61,143,248,145,132,152,150,132,128, 64,162,139, 10,241, 43, 42, 36, 22,253, 3,253,109,221,116, 83,169, 59,118,168, -170, 20,117,209,150, 69, 11, 34,230, 41, 82,176,101,130,237, 56,241,140, 61, 30,103,158,156,239, 92,187,166, 85,189,178,172,235, -177, 53,247,206,121,126,231,251,214,252, 98,218, 74, 60, 62,205,151, 45,127,219, 47,125,180,182,208,208, 80, 37,148, 10,220,226, - 50,107,135, 38,184, 56, 84, 94, 41, 62, 91,203,133,251,102, 3,164, 65, 14,160,127,117,237,235,215,167, 47, 16,122, 8,191,154, -177,118,128, 13,175, 29, 45, 38, 21, 41,198,171,255,145,112,187,218,190, 54, 56,239,191, 27,157,240,207,240, 86, 13,206,122,120, -114, 96, 28,203,113, 52,154, 45, 34,133, 33, 53,244,141, 19,147, 70,165, 51,156, 13, 17,224,136, 65, 80, 14, 87, 40,176, 57,237, -202,116, 3,255,186,144,144, 64,244,187, 56,170,130, 68,134, 95, 11,112,140, 80,222, 38, 17, 93, 2, 56, 45, 92,134,142,225, 34, - 24, 44, 69,196,136, 13,122,134,154,187, 40,217,149,157,230, 23,163,240, 99, 14, 74,180, 84,117,210, 56,118, 59,122,126,132,129, - 26,195,232,157,245,250,147,190, 48,103,150, 55,246, 14,199,209, 25, 31,181, 74, 95,211, 76, 20,165, 93,119,111,236,221,124,125, -250, 82,147,146, 42, 95, 62,240, 12,243,146, 68,169, 68, 7,245,245, 82,207, 80,106, 16, 29, 87,228,227,160, 8,215, 68, 51, 4, -236,175, 96,165,162,178, 48,160,212,148, 19,199,223,247, 31, 60,160, 45,239,233,207, 15, 79, 94, 29,255,248,195,247, 81,120,110, - 3,208,130, 0,159,192,112, 84, 74,178,194, 54, 76,123,252,184,155,229, 32, 92,229,200,143, 31, 75,203, 66, 63,210, 52,203, 86, -160,221,187,123,155, 40,239,254,245, 71,221, 46,154, 13, 11,221,164, 74,155, 67,162, 16,105,104,163,110,245,250,227,225, 89,200, -187,205, 15,132, 99,250,109, 63, 56, 61, 31,168,253, 58, 25,190,212, 81,115, 95,174, 25, 11, 96, 37,159,245,158, 40,203,206,105, - 92, 94,165,174,229, 9, 93, 48, 76,121,203,223, 13, 69,106,135,189,139,239, 52,166, 9,208,171,192,210, 96,212,133,143, 74,173, -200,147,253,246, 65, 80,247,187,131,174, 2,183,215,141, 58, 27, 77, 9, 7,140,120, 57,175, 86,165,124, 67,249,240, 18,168,249, -235,156, 81,225, 24,152,142,107,187,188,184,225,181, 72,106,169, 2,112,230, 36, 58,187,221,185,243,118,248, 70, 0,136, 74, 19, -186,248,178,121,208,159,188,247,164,250,135,185,243,100,122, 17, 79, 68, 2,253, 51, 4,130,156, 47,148, 33,202, 34, 78,102,174, -227,214, 44,182,242,139,255,232, 79,241,157,228,235,164, 89,202, 79,169, 9,254, 32,170,100,172, 87,104,167,116,161, 72, 84,122, - 76, 58,116,110,104, 69,202, 7,234,205, 44,117,157,122, 14,241, 24,164, 17,152,230,204, 82, 83,215, 55, 96, 58, 9,204, 76,205, - 78,146,153,174,138,178, 82,219, 5,205,181, 94,117,246,239, 81,174,255,246,251,163, 95,255,124,244,247, 96,112,119,251,187, 43, -157, 70,117, 49,229, 45,183, 73, 11,124,143,110,221,161,189,171, 20, 46,200,241, 96, 85, 75, 33, 8,147,243, 89, 85,201,108, 26, - 6,241, 21, 10, 28, 32,234, 13, 61, 77,243,139,249,101,153, 68,135, 46,141, 82,234,198, 20,151,212,177,232,192,161, 67,116,103, -105,113, 78,191, 28,253,116,255,155,111,125, 15,134,220, 48, 76,155, 3, 95,223, 50, 50,225, 1, 70,106,101,207, 38,209,114, 30, -183,118,154,227,161, 77,227, 57, 53,157,173,173, 90, 25,177,187, 37,203, 45,149,228,119,170, 88,126,149,199, 22,182, 78, 69,120, -213,237, 31, 3,183, 74, 36,243,234, 48,118, 31, 46, 62,168,145,105,222,130,253,221,235,156, 3,157,140,223, 61,123,127, 28,184, -190, 18, 85,226,251, 80,233, 43,249, 4,126,241, 13, 76,210,152, 67,177, 93,111, 39,185, 68,173,140,111,126,219,223, 6,174,151, -170,105, 28, 42, 41, 50, 53,175,146,175, 52,227, 53, 33, 20,194,229,148, 18,200, 74,230, 64,202, 65, 90,241,143,106, 55,222,112, -140,143,193,207,203,197, 26, 61,130, 66,193, 86,176, 51,137, 70,242, 21, 54,167,197,110, 99,239,227,244,116, 61, 19,162, 72,136, -181,122,205, 91,136,106, 24,175,106,123, 45,213,249,251, 76,113, 67, 83, 56,185,127, 11, 33,168, 15,149,177, 84,195, 37,213, 58, - 36, 80,227, 20, 24,127, 5,102,118, 67, 19,191, 89,163, 94,159, 4,160,234, 90,122,154,136,162,240,237, 76,231,209, 41,109,105, - 74,107, 65,229, 97, 68,141, 4, 99, 98,226, 3, 3, 11,227, 6,137,137,137, 75,127,154, 91, 23,186, 48, 1, 99,112,103,162, 63, -194,133,137, 65,147, 22, 44, 76,233,116,218, 78,103, 58, 47,207,119,238,180, 8, 27, 22,148, 73,239,220,123,207,249,206,235,251, - 50,252, 78,176, 93, 14,127,211,250,200, 19,250,177,143,230,110,230,158,167,207, 26,104,200,167, 72,105,194,164,111,201,227,219, - 91, 4, 34, 48,198, 57, 43,248, 94,200, 17,100, 25,118, 66,223, 9, 84,173, 85,182, 47, 76, 91,194,242, 71, 1, 93,212,156,178, - 90,191, 49, 10,134,146,106, 40,155,231,133, 30, 16, 92,174,235, 57,244, 48, 30,100,167, 99,233,192, 2, 22, 42, 32, 60,136, 88, - 64, 81,234, 36,193,149, 34, 70,155, 50,131,228,150, 23, 86,200,212,210,247, 96,111, 6, 11,144,231,191,114,165, 27,217, 37, 3, -100, 38, 82,249, 25, 70,103,235,214,163, 32,153, 52,231,155,246,160, 23,160, 15, 16,166,149,110, 90,199, 57, 77,153,196,124,128, -121, 57,209,172, 54,251, 35, 55, 68,150, 64,177, 10,112, 6,244,114, 26,213, 38, 61,170, 86,170, 51,215,138, 32, 88,199, 35,172, -170,152, 82,178,208,187,122,189,251,230,220,182,187,131,110,200,106, 33,153, 18, 1,194,207, 4,132,230, 35, 71, 58,105,144,198, -165,232, 83,177,242,202, 92, 33, 87,182,212,154,165, 47, 20,180, 18, 69,190, 41, 65,112, 12,216,168,240, 52,105, 48,193,237, 25, -251,160,113,244,104,123,124, 8,165, 18,110, 91,106,212,191,125, 62,124,255,225, 99,223,241,143,126,183, 66,127,162,147, 49,200, - 35, 10, 34,148,153,196, 41,173, 13, 97,153,174, 21, 12, 3,225,148,150,183, 12, 77,103,189, 77,203, 80, 44, 83, 41, 22,180,251, -155,247,170,229,226,167,131,253,191, 39,103,113,146, 27,143,195,209, 8,216, 17, 12,180,116, 6,130,228,248,212, 5, 91, 3,146, -217,113,192,149,207,116, 38,139,192,105, 81,110, 10, 39, 11, 85,166,168,147,252, 95, 86,153,100,117, 14, 58,130,139,243,139,174, -215, 39,180, 71, 43,237, 14,207,184,236,141,127, 65, 14,132,209, 77, 38, 16, 4,168,130,152,221,241,122,184, 48,220, 2,175, 43, -122,146, 37,214,125, 54,163,115, 96,240,144,188,248,104,229, 50, 36, 86, 30,195,238,139,122,165, 49,244, 7, 49,243, 40,140,193, -240,149, 99, 90, 18,141, 94,252,205,107,119,219,246,159,114, 1, 80, 78,206, 25, 81,204,225, 7, 94,173,212,112,189,158,204,198, -128, 70, 98, 54, 80,152,165, 80,176,167, 58,122, 69,244,136, 37,160,125,104,182,229,166, 51, 39,211,116,186,130,246, 19, 68, 54, -105,202,242, 76,224,248,157,196, 81, 78, 92,232, 91,200,144, 37,143, 78,127, 69, 2, 57, 40,190, 32, 60, 34,136,128,134, 28, 93, -213, 70,193, 32,149,220, 73,233,180,109,128,175, 50, 65,126, 19, 84, 16,161, 76,202,233, 80,193,142,150, 42, 75,207,158,190,218, -255,242,246,240,235, 59,225,245,162, 73,188,110, 36,235, 79, 54,195,147, 30,189, 78,180,217,172,174,137,245, 59,130, 27, 15, 82, -119,208,183, 59, 4,236,113,212,163,204,208,155,197, 74,165, 60, 47,202,166,208,243,138, 51, 62,181,123,173,174,227,157, 28,133, - 99,247,192, 22,223,135,226,103, 32,218, 62,240,251, 50,133,140,170,240, 83,209,234,217,207,183,247,174, 92, 93, 68,125,195,212, -138,229,185,124,211, 18, 90, 78,152, 8, 97, 98,119,228,245, 6,180,141,186, 6,242,134,138,223, 81,139,134, 58,142,100,134,217, - 63, 15,127, 28,119,185,217,151,171,103,204, 54, 70, 33, 81, 44, 36, 64, 69,159, 12,178,139,216, 88, 28,158, 90,169, 74,223,183, - 81,110, 68, 44,229, 68,183, 79, 87, 13,242,217, 47, 30,236,182,237,118, 16, 6, 38,129, 78,110, 45,245, 2,207,204,235, 43,245, - 53,119,232,188,124,184,215,168, 52,126,117,142,232, 41, 59, 27,219, 69, 3,253,111,116,138,182, 55,118, 90,231,199,180, 35,215, - 23, 86,233,242, 96, 82, 50,139,160, 16, 71,200, 44, 12,109,118,213,170,134,172,254, 42,164,223,225, 44, 95,214,148,137,217,139, - 2,185,240, 8,245,219, 12,177, 66, 14, 51,242,232, 23,104,106, 0,240, 85,200, 15, 12,186, 88, 14,127,130,211,110,152,165, 98, -197, 46,156, 40, 83, 55,104, 45,134,102,114,253, 38, 17,211, 68,165,108, 22,160,141,142, 80, 44, 20,178,145,132, 29,141, 52,240, -233, 37, 20, 63,203,131, 92,110, 76, 23,255, 37,131,232,231,159, 0, 92, 93, 89, 79, 19, 81, 24,189,157,153,118, 58, 91, 59,180, - 69, 54, 13, 9,196, 37, 16,183,132, 24,141,137,154,232, 79,244,151,248,194,139,137,190,251, 98, 12,196, 0, 69,192,165,180, 80, -232, 50,211,118,246,241,124,223, 29,132,248,212,151,166,203,189,243,237,231, 59,231,202,191,107, 85,216,216,106,107, 13,254,183, -204, 36,139,220,206, 15, 37, 49, 47,172, 40, 76,166, 78,197, 65, 21,217,170, 45, 28,119,219,231, 94,159,178,173, 92,240, 76, 95, -143,210, 98, 82, 36, 65,163, 5, 18,185,164,192,171,200,200,194,156, 54,106,221,116, 81, 31,193, 90, 46,198,231, 87,197, 43, 25, - 49,203,167, 81,122,141,212, 50,229,102,191,236,183,193,162, 86,154, 52, 47,150, 91,103,168,182, 36, 85,211,250,226, 61, 4, 64, -201,235, 33,101,122,134, 62,222, 35, 92,226,107, 38,145, 57,187,106, 61,187,251,226,232,252,135,100,236,207,105,213,165, 44,137, -155,121,179, 33,179, 13,203, 11, 38, 62, 21,101,190,107,207, 85,136,251,174,234, 5,211, 40, 67,246, 4,243,169,112,121,152,122, -179, 9,173,170,243,225,227, 86,166, 72, 13,242,204,159,142,240,107,253,112, 2,107, 68,249, 12,195, 70, 34,147,114, 86,132, 63, -100, 27, 52,142,255,186,247, 37, 8, 67, 98, 19, 75,115,124,151,212,178,102,126, 81, 82,185, 51,116,130,106,241, 19,162,168,153, -237,143,130, 44, 80,179,137,154, 76,212, 60, 82, 45,197,116,205,106,203, 49, 92,211,152,183,107, 78,217,212, 51,205, 86,213,154, - 80,107,154,102,106, 42, 62, 83, 45,104, 29,196,225, 65,251,251,254, 30,254,163, 91,211,203,196,228,152,149,137,105, 43,139,225, - 14,241,203, 34, 82, 41,102,188, 68, 49,214, 64, 16,173,106,112,196,138, 67, 70, 77,145,195,247,146,221,157,131,207, 31, 63,237, -183,143,240, 92, 33,132, 48,191, 78,174, 43,121,211,212, 42,229,236, 87, 55,154,193,171,167, 44, 58, 94, 8, 86,146,159,194,249, -192,237, 82, 3, 7,101, 18,107,136, 80,181,199,119,162, 22, 59,220,130, 56,224, 74, 57, 13,202,132, 48,170,136, 44,196,163,196, -249,114, 9,238,149,248, 50,185,218,125,188,250,164, 55,234, 20, 59,229,255,120,155, 81,178,113, 76,185,229, 46,195,181,193, 32, - 41,204,227,196,137, 8,143, 0,115, 18,152, 75,232,143, 40,176,141, 26, 78,120,117,126,173, 59,232,144,110, 23,140, 36,142,173, -138,133,175, 35, 86,169, 44,237,141, 78,241,116,109,222,126,212, 27,116,184,129, 71,235,199, 72,198,135,147,129,132, 21, 80, 95, - 91,211,241,153,142,110,195,252,175,155, 75, 10,171, 63,167,180,234,188,212, 88,246, 3, 95, 33,233, 12,130, 63, 74,250, 35,198, - 99,210, 68, 7,167, 65,194, 6, 44, 79,129,108,131, 33,204, 33,183,248,133, 82, 76, 35,148, 43, 86,115,193,171,176,196,186, 17, - 51, 36,159,205, 36,171,104, 58, 7, 74, 10,236, 26,245,237,200,168, 73,203,155, 26, 26, 49,109, 42, 33,101,230, 37, 38, 60, 4, -175, 54, 95, 39,105,240, 97,251,253,134, 45, 30,184,162, 89, 22, 90, 52,219,122,251, 50,235,245,225, 84,108,199, 18, 79,183, 68, -189, 78, 28, 3,211, 36,243,252, 97,255, 52, 40,240,145, 82, 87, 61, 43,149,141, 70,173,161,154,134,168,155,196,186,121, 54, 58, -236,245,199, 23,221,163,254,112,123, 44, 36,250,218,227,154,253,161, 37, 44, 85, 76, 51,209,241,196,155,231,239,214, 55,238,163, - 54,212,225,162, 22,234, 98,142,123, 0,227, 40,185, 28, 39, 81, 72,224, 10,106,195, 83, 4,170, 14, 79, 52,199, 32,224, 47,110, - 28,153,245, 32,252,118,220, 87,120, 11,137, 1, 0,178,213, 94, 72, 40, 73,253,106,137, 84,194,233,161, 4,165, 27,135,239,142, - 9, 40,169,112,166,184,212, 92,232,123, 23, 97, 24, 12,166, 3, 83,183,150, 26, 75, 81, 20, 54,237,230, 74,243, 14, 30, 66,127, -230, 91,186,121,124,118,178,220, 92,254,115,254, 19,151,181,223,105, 95,248,253,197,250,194,165, 63,216,253,189,131,144,128, 20, -196,181,221, 9,117,123, 74, 50, 54,200, 68,197, 50,236,132, 17,180,179,100,134, 0, 40, 73,102,184,113, 75,190,145,100,102,217, - 91, 33,105,136,210, 88, 41,238, 83, 58,102, 38, 24, 82, 72,123, 50,205,227,149,198,237,131,238, 30,197, 95, 81,172, 31,203,209, -122, 76, 83,220, 2, 71, 24, 16,110,135,217, 21,210, 92,118,241,243, 27, 35,213,150,211,154,240, 72,175,116,205,110,159,219,122, -141, 1, 96,133, 90,138,114, 53,138,189, 1,145, 44,253,231,226,229,203, 95, 1,152,186,146,222,182,141, 48, 58, 28,145, 34, 69, - 73,150,183, 36,181,108, 56, 73,235, 0, 69,155, 30,122,110,255,115, 15,237, 33,183,244,210, 91,129,102,113, 27, 35, 8,144, 52, -150, 45, 57,182, 37, 75,162,196,109, 56,236,123,223,136, 70,111,130,109, 88,228,172,223,242, 22,255,222, 29, 6, 75,244,223,233, - 39, 54, 78,119, 15,175,238, 46,164,166,194,168, 28, 33,115, 90, 82, 86, 44, 41, 86,216,185,123,253,221,130, 26,121,149,183,145, -223, 51,186,165, 15,182, 14,191, 44, 39,172,203,184,116, 66,109, 40,235, 30,221,151,104, 88,140,207,113,212, 69,254,139,189,189, -211,221,191,169, 39,149,232,235, 75,130, 19, 96,110, 10, 98, 66, 17,209,229,174,142,217, 64,127,212,247,199, 63,142,254,250,173, - 22,250,213,178, 22,151, 28,107, 63, 76,222, 75, 30, 98,181, 72, 2,187,161,198, 51, 93,207, 39,178,122,188, 69,186,248,253,239, -151, 72,157, 42, 10, 66, 80, 39,100, 69, 80, 60, 9,216,157, 40,194,125,254,234,211, 91,105,198, 40, 76, 54,222,232,244,243, 59, -217,111, 92,100,156,123,199,175, 85,206, 68,178,133,207,200, 54, 10, 49, 71,167, 17, 90, 16, 74,185,134,245,156,162,174,188, 42, -143, 91, 49, 62,159, 12,159,141,167, 19,156, 77,248,159,233, 44,237,197,125,250, 91,181, 60, 28,212, 73,126,193, 92,208, 86,157, -118,247,122,113,245,108,248,205, 44,153,183, 21, 98,234,248,167,111,127,126,241,234,215,101,166, 22, 89,201,177,104,145,227,152, -124,190, 57,218, 57, 89,155, 91,227, 77,135,251,241,195,237,184, 31,245, 25, 67, 82, 80, 92, 27, 67, 74,148,248, 2, 33, 27,173, -214,189,160, 50, 56,254, 12,226,110,155, 83,190,110, 69,156, 27,226, 73, 47,167,195,158, 71, 85,100,202,184,213,129,182, 33, 30, -200,110, 68,102,241, 83, 54,202, 34,109,108,138,156,173,139, 16, 72,216, 31,149, 37, 33,192,171,116, 47,168,223,143,210,146,165, -161,128,130,107, 84, 13,176,120,193,188,202,145, 1, 96,215, 37,212,155,163,237, 60,121,138, 2, 10,230, 3, 18, 2,108, 28, 95, - 81, 38,200,115,218,166,171,108, 37,138, 61, 4, 95, 25,178,251,210,163,221,195,241,221, 37,198,249,108,116, 42,185,138,252,161, -246,113, 64, 19,123,174,105,187,252,252,233, 15,167, 31, 95,183,233, 68,165,165,217,197, 97,199,201,128,179,165,168,112, 7, 91, - 95,104,138,113,216,195, 97,122,118,254,198,121,102,224, 16, 92,107, 27,132,237,176, 14,211, 60, 21, 22, 2,139,149,255,140,222, - 96, 52,152,228,121,222, 86, 56,200,202, 85, 24, 4,248,206,146, 22, 72,190,132,210, 89,106,138,189,173,131,105,130, 16,196,123, -188,127,140, 36,140,200, 72,202,196, 75, 13, 93, 25,191,102, 29,127, 43,218, 94,102,139,134,171,193,146, 11,169,243,165, 21, 85, - 3, 43,220,189, 18,239, 18, 82, 3, 69,115,203,208,117,128,104, 83,182,254, 52,194,133, 30,174, 37,135, 16,195, 3, 15,186, 59, -201,122,145, 23,105, 99, 83,225, 9, 11,181, 46,234, 76, 17,126, 34,246,100, 90,164, 10, 36,252,193, 65,125,244,224,248,143, 63, -127, 57,110,177, 5, 58,175, 84,132,247, 40, 19, 69,209, 8,221,193,168, 15,135,234,224,145, 42,156,218, 55,219,179,174, 10,114, -239, 59, 74, 88, 68,178,152,206,150, 95,221,116,212, 94,172,118,251, 59,131, 24, 65,140,241, 59, 51,171,141,178,129, 16,193,113, -196,206, 69, 13,188,235,171, 46, 46, 24,114,218,173,223,143,124,228,143,237,128, 18, 52,120,137,235, 84,153, 82,208, 21,156, 51, - 42, 52, 98, 85, 44, 91,200,170,112,172,171, 40,196, 21,209, 46, 75,172,180,237, 40, 90,152,116,163, 7, 86,253, 79,145, 80, 36, -197,197,188,116,141, 95, 98,181, 99, 34, 16, 59,102, 6,249, 40,150,131,254,250,209,201,229,108, 60,186, 62,247, 85,128,200, 44, -208, 65, 86,172,199,179,201,147, 7, 79, 61,178,198,219, 87,243, 9, 29, 5,130,240,203,108, 60, 79,238, 30,110, 99, 6,167,131, -206,224,249,147,239, 46,110, 47, 17,228,176, 93,111,171, 85,182, 60, 27, 77, 49,230,123,253,253,236,110, 93,107,103, 96, 67,156, -140, 83, 8,108,104,210,174, 47, 40, 66,231, 72,179,136, 6,118, 21,104,223, 39,216,103,211, 2,181,247,204, 37, 98,187,233, 85, -112,121,123,142, 0, 92, 82,246,194, 85,250, 58, 65,188, 34,202,220, 33,110,154,118,176,251,150,166, 66,173,155,170,140,150, 93, -237,188,126, 55, 80, 94,185, 37,210,124,105, 93,203, 82, 10, 53,181,128,106,170, 13,243, 67, 53,248, 72,175,110,140, 43,238,153, - 82,255, 9,192,213,181,236, 54, 13, 68,209, 25,219,177,199,118,211,216,105, 30, 45, 45,173, 2,168,106, 23, 32, 4,136, 10,137, - 71, 43, 86,240, 7,176, 97, 1, 72,124, 26, 95,193,130, 13, 66,168,162, 69, 32, 80, 21,104, 69,219, 52,105,146,230, 81,219,117, - 98,199,230,222, 59,166, 84,172,179,137, 61, 51,215,231,220, 57,247, 28,137,223, 19,129,182, 6,140,108,234, 82, 50, 59, 36, 65, - 18,187, 48,138, 66, 5, 85,232,226,240,228, 16,155, 62, 92,254,165, 68, 33,163,165, 65,128,115, 40, 42,203, 68,250, 26, 87,209, -157, 3,157, 16,227, 98,190,232, 97,235, 80, 93,172,212, 6,193, 9,177, 96,207,214,167,224, 49,150,231, 87,209,157, 7,243, 25, -162,236,166, 42, 83,137, 82,179, 73, 65, 41, 94,253,104,135, 76,198, 51,134, 98,225, 85, 85,132,185,149, 82, 30,207,101, 3, 79, -177,117,115,161, 84, 91,191,190,222,234,183,147, 73, 36, 12, 43, 70, 31, 31,245,188,149, 85,154,174, 4, 33, 48,235,164, 90,168, -158,134, 94,150,243,196,161,112, 7,205,193,241, 36, 51,173,207,156,232,101,242, 58,206, 55, 77,226,194,148,211,247,251,240, 59, - 16, 23,140,118,131,195,163,219,152, 64,141,178, 45, 92,175, 91, 87,110, 11, 67,248,161, 55,235, 94, 66, 9,144,170, 30,118, 15, -224,201, 37,104, 5, 32, 25,132, 62,249,130, 26,240,164, 64,226, 96, 31,220,185,186,182,211,252, 81, 48,221,238,217,201, 94,123, - 47, 78,198,183,107,119,201,255,168,111,229,140,162,229,194,235,191, 86,173, 89,194,106,244,246,161,102,124,233,215, 63,214,119, - 63,212,247,182,127, 31,236, 52,143,182,142,154, 63, 59,157,250,113,155,161, 12, 30, 96, 72,194, 13,107, 28, 33,208, 40, 8, 99, -198,178, 22,167,167,203,192, 0, 76, 81,177,196,172,101, 94,118,236,146,101, 20,128,205,106,128, 50, 82,224, 72,176,204, 80,169, -130, 16,209,125,140,205, 12,142,206,177, 42, 23, 34, 45, 76,165,121, 19, 0, 84,202,199,172,209, 8, 14,186, 1, 74,128,128, 14, - 72, 3, 39, 12, 42, 17,142,233,222, 91,126,208, 26, 30, 83,170, 6, 55, 48, 56, 8,248, 58, 42,204,132,102,234,134, 25,199,145, -146, 89, 68,100, 83,158,138,212,165, 2,199, 50, 29, 77, 81, 80,139,166,106,116, 25,133,213, 80, 0, 71,209, 40, 57, 80,198, 45, -164, 50, 64, 30,129,252,147,181,167,219,245, 45,132,173,210, 48, 68,242,119,248,119,201, 8, 77,190,209,114, 75, 0, 22,132,115, -235, 78,205, 0, 74,130,117,133, 37,155,115, 47,119,134, 45,168,170, 47, 30,191,250,252,107, 19,165,218, 36, 92,159, 45, 46,148, -243,101, 47,240,201,154, 10, 83, 76,201,199, 52,148,151,104, 99, 12,212,197,171, 88,160,113,168,201, 73, 83,192,248, 40,234,192, -182, 17,198,155,204, 57,243, 80,119,112,252, 2,239,181, 34,158,254,157,166,145, 54,146,132, 76,128,230, 78,178,192,102, 84, 34, -186,246,140, 15,251,159,168,245,195,213,141, 32,196, 56,116,248,150, 88, 57, 75,106, 1, 97, 63,220, 88,186,185, 79,190, 8,179, -206, 2,214, 5,169, 30, 73, 1, 13,152,110,190, 4,251, 7,205,242, 80, 74,133,167, 21,133,145, 60,209, 57,127,180,114,239,211, -230,219, 57, 45,122,239,177,119,125,214, 28,177,121, 53,221,120,184,150, 14, 60,213,208,249,173,155,172, 84, 70,240,126, 54,102, -240,141, 30,156,246,218,141, 48,194, 68,221, 88,134, 36,209,110,215,109,199,210,114, 57,219,128,253, 13,252,180,121,216,110, 14, -189, 97,183,253,221,147,221,105,116,217, 93,214,217,125,151, 9,133,181, 70,172, 23,178,231,207, 94, 58, 43, 53, 6,165,220, 52, -228,140, 22,250,202, 27, 80,120, 21, 60,151, 26, 78, 20, 41,182, 8,142, 26, 90,111, 55, 87, 41, 49, 91,199,209,242,201, 36,232, -120,187,251,167,222, 4, 35,222, 51,143,132, 36,141, 57,221,183, 82, 45,115,109,199, 31,157, 17,156,242, 1, 36,189,126,242, 6, -222, 67,103,208,133,165,104,245,154,176,154,139,213,165, 83,168, 78,105,188, 80, 90,204,155,121, 0,248,237, 65,203, 15,209, 16, -184, 63,236,214, 42,181,185, 98, 85,211, 69,111,208, 1,140, 12, 31, 6, 91,183,190,254,254, 6, 44, 92,182, 89,228, 29, 15, 89, -144, 34,201,132,195, 8,199,124, 38, 95, 70,217,251, 56, 76, 50, 40, 47, 91, 53, 36, 73, 33,209,220,136,122, 6, 23, 47, 47,149, -127,137,234, 50,172, 0, 13, 62,131,216, 39,175,211, 40,205,230,150,101,131,135, 3,230, 82,168,255,192,206,189,145,201,172,132, -114,125, 21,118,161,178, 75,213,172, 28,187, 85,169,115, 66,166, 73,156,166, 55,210,127, 22,123,231,142,117, 23,144,250,127,205, -153,243,159,255, 8,192,213,181,180, 54, 17, 69,225, 59,115,103, 38,147, 73, 38, 77,155,180, 53,161, 85,172, 21, 31, 85, 68, 65, - 16,193,149, 27,193,189, 11, 93,248, 19,220, 8,254, 45, 65,252, 1,226, 66,161,180, 82,138, 45,138, 36,109,146, 54,109,146,102, - 30,201,100, 50,153,151,231,156, 59, 81,113,215,210, 69,195,220,155, 51,223, 57,231,123,100,243,153,130,106, 66, 67,132,240, 10, -211,236, 98, 97,149, 41,205, 95, 80, 98,214, 3, 87, 98,227,210, 13, 63,152, 8, 26, 89, 49,103,112,142, 17,104, 70, 46,143,242, - 63,241,104, 24,198,218, 38,164,224,162,193,142, 54, 13,200, 79, 74, 74,201, 5,144,211, 71, 79, 81, 6, 39,241,158,211,229,169, - 60,103, 50,207,243, 59,232,157,137, 61,157,162, 39, 25, 47, 88, 22,246, 6,197,188,137,201,135, 12, 0, 65,142,156,166,255,104, -155,208, 33,104,224,244, 26,103, 13, 56, 39,184,174,183,234,183,186,118, 87,180,183, 34,192, 30,157, 3,104, 71,226,248,163, 36, - 27, 0,226,170,117,158, 5,137, 71, 66,251,244,152,220,232,177, 37, 71, 3, 67, 13, 10,247, 8,199,127,178, 4,197, 87, 81,160, - 37,213, 28,207,169, 87,214,205, 66,121,132,146, 7,118, 58, 60,233,187, 3,180, 73,242,156,139,241, 5, 46, 84,147, 20,176, 60, - 42, 53,200, 22, 59, 68,177,114, 44,252,109, 48,121, 59,138, 26,131, 6,124,164, 90,185,238,250, 14, 2, 94, 18,122,244, 0,201, -166,233,213,213, 77,119, 58,130, 94,175, 53,108,182,172,134,156,170, 27,181,245, 68,179,224,171, 3,255, 27,218, 17, 55, 9,220, -153,119,238, 89, 77,123,184,123,218,249,212,104,236,180,218, 65,196,172, 89,120, 58,154,254,178,172,207, 71,157,253,238,217,135, -195,230,215,102,103,187, 55,248,230,218,251, 67,203, 10,166,143,215,107,245,165,210,162,174, 47,231,243, 38,207, 25,146,106, 72, -202,162,170, 20,101, 94,214,184, 1,125,134,170,192,119, 88,215,152,174,240,145, 29, 29, 54,236,142,237,139,117, 92, 44, 2,237, -105, 76,142,235, 95,153, 31,116,246,208,198,139,238, 17,102, 46,162,199, 41,190,240,176,240, 9,126,250, 60, 81,145,252, 84,196, - 24, 13, 41,107, 24,118,136, 18, 77,148,198,196, 44, 89, 49,151,225, 88,252,153, 23, 39,161,208, 4,102, 42,229,108,190, 45,237, -254,220, 33, 58,138, 12,224,174,190,184,102, 67, 47, 72, 60, 74,209,216, 98,114, 12, 14, 79, 19,168,146,208,170, 19,184, 97,208, - 95,235, 90, 1, 10,129,202,181,239, 71,251, 80,136, 85,232, 85, 8, 65, 89,227,225,221, 43,119,131, 40, 64, 77,147,196,171,197, - 42,224,113,210,197,204, 4,193, 92, 68, 62,160,130, 31, 3, 45,112, 73,130,162, 45,218, 20, 93, 91,221, 60,185,104, 11,129, 85, - 6,230,228,108,251,144,215, 13,130, 35, 72,244, 68, 54, 78,154,148, 40,137, 16,211,180, 2,143,148, 48, 88, 92,218, 23, 45, 51, - 87,240,195, 41,224, 83,232,146,123, 0, 57, 49,216, 44, 57,119,187, 18, 6,224,112, 64, 66, 81, 6, 34,201,138, 35, 10,253, 96, -140, 30,190,232,231,194,137, 25, 38, 43, 72,214,150, 75,154,246,232,250,131,230,222,199,169,196,222,219,108,152,178,179,152,221, - 54,249,243,103, 79,216,112, 44,175, 84,216,131,251,248,212,189,144, 77,124, 54, 9,103,174,227,246,219, 33,113, 91,133,159,167, - 80,108, 41,186,161,104,133, 18, 28,100,181,200, 76, 67,237,187,205,190, 19,185,125,107, 60,233,147,241,208, 37,206,158, 47,178, -173, 34,194,244,230,152,229, 75,213,215,111,222,177,229, 5, 44,232,240, 86,128,174, 1,126,200,113, 28,193,115, 92, 47,100,230, - 79,138,100,111,127, 41,234, 51,190, 86, 97, 57,149,168, 30,177,119,108,255,232, 56, 19,228, 17, 49, 50, 1, 67,164,170,202, 74, - 25,122, 23,108, 92, 72,210, 69,109, 95,189, 82,235,219,253,175, 7, 95, 90,131, 86,217, 92,184,115,249,102,173,178, 2,135,178, - 82,172,246,144, 86,199, 1, 35, 98,178, 2,149,187, 87, 79, 95,250,161,223, 30,156, 12, 39,184, 75,187,119,231, 97,247,180, 13, -183, 14, 30,242,234,210,234,185,221,123,247,226,237,205,181,173,227,222,209, 36,244, 1, 89, 6,209, 20,110,186, 23,192, 75,151, -195, 97, 77,102, 30, 57,188,139,100, 23, 86, 54,150, 34,180, 98,143, 5,191, 29, 58,108, 54,207,100, 22,244,113,150,254,111, 0, - 6,191,151, 75,213, 32,240,209,112, 70, 34,211,168,108, 65,147, 9, 77,179, 33, 27, 19,228, 89, 66, 61, 8,166, 21,168, 52, 26, -154, 71,168,100,178, 61,119, 31,158, 19,183, 36, 10, 94, 35,183, 55, 57, 77, 98,246,215,150, 78,146,255, 41,203,255, 44,105,255, -248,244,253,253,195,111, 1,184,186,150,222,166,177, 40,124,253,186,182,155,212, 9, 41, 41,180,208,150, 1,169,170, 40, 98, 1, - 93, 32,182,108, 88, 0,107,164,153,221,252, 71,196, 14,137, 5, 8, 86,136, 5, 26,164, 78, 59,130,180, 73,154, 87,237,216,142, - 29,199, 54,231, 59,215, 46,210, 72,221,181, 77,147,250,220,123, 94,223,163,186,223,153, 6, 70,205,124, 2, 73, 85, 16,180,157, -188,150, 10,209, 43,111,109, 92,224,211, 16, 34, 59, 26,215,197, 43,142, 17,199,180,125, 42, 90,117,136,141,108, 95,219, 9,147, -192,145,107,149,141, 3,221, 92,106,177,200,250,195,244,103, 61,215,227,186, 6, 47,213,110,118, 18, 96,149, 84, 6, 3,196,248, -134,183, 21, 38, 62,128, 50, 80,129, 87,174,123,122,109,233,141,212, 6,251,233, 34, 99,171,245, 92,109,172,202, 10,116, 8, 0, - 15, 34,159, 89, 9,244,204,206,103,231, 53,253, 69,165, 41,109,187,179, 29, 81, 12,149, 42,141,227,135,119,186,123,195, 96, 64, -133,182,180, 36,150,151,140,110,239, 52,174,251, 88, 30, 2,249,174,160,214,138, 89,174,176,112, 60,185,162, 54, 80,167, 75,124, - 6,223, 47,165,238,141,149, 3,189,103, 58,207,149,243,142, 40, 93,185, 22, 47, 99,166,152, 98, 9,238,185,237,136,171,248, 44, -163, 6,190, 92,163,239,166,201,206,198,238, 69,112,209,144, 13, 6,240,161, 20, 48,117,155,222,249,193,237, 7,223,206,190,222, -233,238, 7, 73,208,148,157,225,124, 56,142, 23,203,172,176,216, 15,213,150,194,146,176, 75, 86,126,155, 82,152,174, 97, 5,154, -248,114,252,223,201,176,255,243, 98,236,227,148, 20,185,101, 59,158,103, 83, 78, 0,197, 70, 27,132,139,143,199,103,147,176, 60, - 29,173,250, 1,203,125,165, 69,184, 2, 64, 38,165, 30, 60, 55, 50, 16, 64,202, 36, 41,253,203, 98,116,145,159,244,210, 97, 16, -177,114,139,178,110, 64,177,107,234, 20,136,121,211,245, 40, 85,115, 69,105,176,200, 70,169,118,146,182,229,218,216,119,173,116, - 69,133,214, 43, 3, 6, 54,200,194,120,193,212,192, 81,162,180,103, 96,252,178, 84,150, 14, 57, 79,150,213, 63, 77, 26, 78,229, - 29, 82, 55,142, 74,175,149, 94, 66,234, 14,157,225, 73, 56,186,138, 99, 77,201, 17,176,203, 54,176,204,114,141,167,171, 13,165, -230, 31,196,190,174,244,126, 5, 70, 70, 2, 87,240, 58, 53, 76,113,186,232, 79,123, 11, 42, 18,161,140,190, 74,243,213, 50, 77, - 33, 39,171,213,210,142, 56,124, 57, 6, 78,101,237, 37, 12,230,176,148,134, 69, 13, 1,147,233,240,153,154,204,231,186,146,203, -110,187,173,104, 17,138,223, 26, 82,152, 22, 98,250,169, 91,135,123, 15,199,254,200,115,240, 44, 74, 22, 41,212,117,115,153, 37, -211, 96,164,240,157, 90,181,108,192, 66,130, 5,103,216, 11,138,167,172,183, 55,118, 98, 40,226,105,138,188, 1,225, 48,129, 25, - 29,252, 61, 74,241,240,214,254,229,233,123,234,136, 63,197,162,193,130,115,143, 91,222,139,103, 79,180,249, 92,220, 63, 16,119, -239,138, 36, 19,139, 20,245,123,146, 37,179,145, 63, 25,100,106, 83, 89,172, 42, 73, 63, 96, 30, 76,171,209,150,101, 97, 83, 98, -191,217,110, 9,109,220,155,142,163,240,145,225,123,162,120,188,174,253,121,179,124,218,194,103,234, 45,196,247,137,120,249,252, -245,225,223,127, 9,232,106, 72,212, 2,166, 86,125,169,226, 93, 71,193, 41, 28,163,152, 77,198, 31,222, 93,223,223, 18,221, 54, - 18, 0, 75,194, 70, 39,211,247,199,231, 70,237,112, 93,178,154,222, 10,138, 23, 49,147,117, 42,192, 52, 29,240, 52,203, 54, 91, -155,116,183,186,146, 74, 14,115, 30,207,255, 29,156, 70, 73, 76,213,247, 56,154,189, 58,122,217,159,246,215,157,230,102,123,235, - 50,156,132,241, 98, 48, 57,167,180, 77,177,103, 11,217, 59,251, 33,184,144,178,165,123,111,235, 15,122,112,111, 62,191,253,222, -251,103,204,115,182,189,238,238, 52,156, 58,172,121, 78, 45, 66,156,198, 71,247,142, 40, 90, 50, 80, 38, 17, 57, 32,255, 50,190, - 86,209,160,121,166, 85,220,234,236, 94, 70, 51, 85, 47,182, 26,215, 82, 40,100, 80, 35,203,156, 80,248,179, 80,209, 29, 66, 60, - 18, 78,105,248,213,117,135, 50,166, 14,214, 78,205,237,110, 57,157, 20, 52,230,154,243, 33,196, 70,179, 11, 99, 43,116,192,162, -168,128, 51,229,255,188, 53, 40, 2, 93,179, 1,210, 75,101, 99,121,197,249,168, 54, 57,218,239, 37,235, 21,120, 70, 65,143,213, -148, 91,252, 18,128,173,107,233,109, 26,139,194,247,166,118,252,138,157,184,105, 83, 53, 64,105, 21,205, 84, 8, 10,165, 48, 84, - 3,236, 24,254, 0, 27,118,136,223,128,208,252,142, 89,240,111, 16,136,213,108, 25,141, 6, 88,192,204,208,210, 14,105,226,198, -118,252,182, 99,123,206, 57, 55,225, 37,164,170,139, 72,173, 31, 57,207,123,190,239, 59,130,191, 90, 27,138,217,111,247,109, 99, - 25,194, 22, 18,190,185, 4,241, 93,140, 38,145,132, 76,146,176,170,140,194,141, 13,244, 40,133,104,123, 8, 13, 33, 60, 12, 39, - 40,122, 49, 77, 61,129, 11,174, 4, 32,130,162,252,185,149, 77, 63,158,128, 77,195,159, 67, 45, 44,214, 16, 67, 13,180,214, 89, - 7,135, 39,114, 44,210, 65, 33,252, 33, 80, 31, 59, 3,174, 54,181, 27,131,155, 31, 78, 15, 62,157,109,126, 18, 96,227,115, 58, - 50, 26,136,132,106,203,124, 89,183, 85,197, 88,177, 86, 17,144, 67, 42,125,155,171,131, 24, 69,101,249,154,189, 30,162,215, 97, -109, 14,206, 79,196,208,185,140, 83, 75,183,252,208,219,221,218,131,155, 63,211,221, 24,186, 31, 69, 52,191,188,117,245,253,232, -111,120,174,157,243, 87, 62,226,135, 69, 27,101, 70,178, 26,207, 51, 10, 47,154, 72,146,108,234, 86, 10,169,162, 98,150, 97,151, -228, 47,219,103, 47,185, 52,116, 21,249,189, 99,118,135,254, 49,201,173,212, 98,229,138,174,234,121, 89,128,193, 65,209,241,211, -224,198,195,187, 15,158,253,249, 12,190, 8, 8,179, 96, 10, 89,153, 83, 49, 66,192,123, 73,238, 89,107, 89, 89, 52, 27, 77,168, - 64,211, 25, 34,186, 78,162, 56,137, 43, 63, 46,131,136,133, 97, 29, 69,117,154, 67,232,173,147, 12,121,219,141,154, 59,211, 16, - 92,161,183,172,217,109,195,130,126, 74, 85, 33, 48, 26,170, 44,163,188, 14, 54, 89,154,140, 90, 24, 27, 22, 92, 43,134,212,146, -196,178, 27, 20, 78, 48,117,220,120, 56,137,142,198,254,209, 56, 56, 26, 77, 15, 71,254,193, 56, 56,158,248, 97,154, 67,153,131, -104, 61, 92, 46,197, 69,154,166, 58,126, 70,164, 30,156, 40,146, 2, 45, 47, 27,115,133,114,184,207, 21,163,135, 74, 76,104, 97, - 75, 96,238, 89,153,217, 70, 55, 39,178,177, 56,104, 70, 72,126, 89,252,122,239,241,171,247,175,107,154,168,227,198, 55,146, 87, -133, 26,106, 86,101,221, 86, 79,150, 36,104,207,161, 92,104, 54, 21, 40,117,193, 15,117,165,149,206,226,182,218, 1, 39,132, 10, -182,165,154, 25, 2,111, 24,137,223, 98,139,143,164,237,196,173,197, 68,133, 45, 73, 40,158,165, 64,169, 11,191,123,118,191,163, -119,112,133,192,172, 72,139,196,110,117,224,114,152, 6, 80, 88,177, 9,126, 14, 6,188, 98,174, 34, 65,175,174, 84, 73, 39, 44, - 92,181,179,113,237,116, 58, 86,112,135,157, 6,161, 89, 83, 52, 63,114,119, 54,175, 66,235,166,171,184,103,124, 46,152, 35, 30, - 29, 81, 97, 41,251, 82,183,157,207, 81, 6,240,206,156,192, 33,224, 52,228,255,156, 0,163,156,126,112,122, 10,207, 69, 51,158, - 82, 80,210, 33,235,236,110,236,121,225, 68,148,138, 68,155, 74,224,219, 21,138,146, 84, 19, 83,219, 75,234,214,208,165,220,190, -176, 31,252,243, 28,226,223,239,152, 89, 48,190,223, 31,244,111,253,124,137, 21, 57,187,118,133, 89, 54, 30,206, 68, 57,139, 51, - 6,175,111,244, 95,232,141,102, 52, 40, 38,129,135,133, 30,125, 85, 42,134,197,151,224, 86, 16,187,202,206,116,251,105,241,118, - 24,200,153,123,183,149, 93,110,213, 23, 45,156,158,255,155,214,127, 57,172,221,238, 61,250,237, 9, 27,172, 99,124,111,200,223, -209,162,149, 72, 64, 80,145, 39, 79, 95,168,217, 88,191,184,201,108, 13, 63,164,173,190,241,155,209, 31, 71, 30,237, 28, 71,229, -252, 5, 19, 84,140, 56,185, 80,238,162,131, 8,102,106,173,211,216, 75,178, 56, 47, 10,200,235, 96, 6,120, 58,215,212, 58,166, -237,120, 14,116,161, 40,206, 82,205, 78,220, 19,134, 7, 86,208, 59,240,177,239,252,178,119,231,229,187,151,219,103,127,220,223, -222, 63, 28,125,176,116,115,120,122,226,134, 30,252,135,235, 63, 92,135,250, 29, 46,177,190,124, 14, 26,110,108, 22,107, 22, 36, - 83,120, 33,120,154,138,253, 57, 35, 2, 93, 13,205,132,161, 91, 21, 70, 54,132, 84,161,252, 53,175, 53, 4, 95,132,243, 5, 28, -245,124,147, 1, 20,178,186,106,153, 40,152, 19,193, 35,224,136,133, 68,162,192, 40,210, 44,105, 32,171, 93, 76,122, 48, 8,164, - 72,171,230, 95,108,190,131,114, 42, 69,225,154,197, 26, 66, 48, 6,154,249,149,223,192, 97,138, 10,183,180, 44, 22,194,240,197, - 66,108,254, 85,136,255,172,208, 52,135,118,241,133, 4,205,255, 2,208,117, 45,187,109, 27, 81,116, 40,206, 80, 18,101,138,182, - 30,136, 20, 59,178, 93,195, 85,144, 54, 73, 19, 7,136,211, 46,130, 34, 8,144, 44,188,200, 42,139,254, 74,209,125,255,160,191, - 80,160, 63,208, 93, 23,221,116,215, 38, 14,210, 2,181, 27,203,174,100,209,178,100, 61, 76, 82,124,230,158, 25,202, 13, 16,244, - 3,108,105, 70,119,238,156,123,231,220,115,178,249, 85,134,186, 59,162, 88,172, 89, 53, 41, 45,206,101,155, 27,109,234,162, 40, - 65,198, 75,211,175, 87, 90, 83,202,224, 82, 3, 68,232, 98,185, 84,129,229,152,160, 51, 80,144, 10,218,186,105,148,148,146,178, -208, 33, 52,253,242,241, 55,251, 71,175,232,252, 16,188,122,248,233,163,238,224, 36,235,228,235, 20, 0,133,243,153, 19, 64, 25, - 23,255, 33, 82, 3, 41, 57,189, 92,180, 61,120, 40,207,193,127, 79, 23, 66, 5, 90, 38,184,172,120,169, 20,161,123,143, 94,244, -135, 61,169, 17,175,209,198,209, 47, 33, 11,219,104,181,178, 38,132,209, 25,188, 83,157, 77,217,248, 78, 50, 72, 38,169, 31,153, - 41, 59, 76, 57, 92,250,160,238,168,231, 71,243,195,254,225,103,173,219,206,164, 31,196,241,240,114, 84, 70,146,180,157,177, 67, - 81,101,230, 45,219,180, 47, 32, 15,155,214,202, 13,169, 19,153,206, 99, 47,149,198,204,141,229,166, 23,186, 62,158, 54, 35,130, -165,224,198,196,208, 47,245,231, 46, 1,119,203, 92,206,131,139,237,211,229,188, 90,105, 16, 24,113, 70,125, 90,227,147,187, 79, -127,252,245,167,178, 89,222,172,111,210, 81,165, 84, 78,193,212,170,110,160,117, 35, 29, 29, 59,131, 3, 47,240, 39,254,136,238, - 45,218, 10,171,104, 5,220, 71,181,164,167,130, 99, 97, 33,196,119,210, 32,132,241, 30,213,185,148,190,133,224,117,171,100, 24, -194, 52,140, 21,194, 60, 5,221, 40,242,178, 52,216, 44, 9,141,146, 59, 28,127,120,174,160, 9, 12,228, 83, 89,138, 22, 65,217, -151, 2,144,208, 6, 72,165,254, 66,162,138, 75, 74, 40, 34,196,156, 99,114,127,243,171,206,217,209, 21, 97, 88, 48, 81, 54, 87, -148,255,153,218, 76,138, 13,202, 23, 69, 65, 16, 27,102,117, 50,208, 19,218, 52,229,238, 45,135, 66,233,146, 75,120,142,111, 55, -111, 17,120,167, 11, 30,179,199, 76,252,213,125,203,113, 44, 21,197,149,209, 77, 6,171, 0, 76,108, 7, 65, 56,191,211,186, 55, -113, 39,170, 61, 74,223,137,138, 42,170, 24,230,145, 43, 79, 96,156,231, 5, 24, 50,196, 49, 91,196, 4, 90,127,137,154, 40,193, - 58,224, 72,147,134,237,213,118,119,120,226,122,147,177,127,209,168,172,230,128,149, 48,185, 73, 43,161, 26,220, 20,166, 23,121, -161,236,179,211, 61, 68,139,191,179,190, 67, 23, 3, 33,104,250, 2,253,241, 41,100, 26,133, 65,105,135,192,157,139, 81,198,184, - 63,234,129, 24,131,103, 52, 28, 13,216,140,164, 0, 61, 75,104,185, 64,104,140, 67,154, 87,207,104,108, 25,205, 82,151, 54, 99, -224,215, 23,242, 69,202,249,166,177,148, 61, 68,107, 84,161,250, 85,171,174,170, 88,217,116, 74,157,233,169,244, 36,145, 47, 75, - 80,234,101, 28,200, 29,189,172, 21,179, 26,196, 30,231,204,160, 35,105,216,113,228,127,253,249,151,163,222,235,182, 54,253, 39, -226,199, 1, 43,176,244,187,221,246,218,118,139, 45,153,236,254, 14,146, 0,129,119, 36,119, 66,241,151,147,127, 15, 93,247,146, - 45,172,116, 64,133, 72,149,222, 48, 90,210,162,100,231,146,164, 72, 27,218,180,141,134,109, 13,252,223,135,243,233,197,184,192, -216,225,101,242,247, 44,218, 63, 35,188,106,126,251,253, 15,230,222, 19,217,203,230,255, 51, 15,143,159, 52,252,227, 77,247,151, -159,111,220,251,132,109,214,152,105,224,212, 71, 0, 72,231,191, 29,239, 15,102, 58,210,187,244,153, 75,149,159, 75,230,189, 71, - 91,189,126,109, 99,134, 51,155, 98,142, 44,205,230,219,149,181,179,224,249,173,230, 86,239,252,148,246,102,247,139,199,185, 56, -126,123,242,103,213,174,231,228, 16,211,133, 59,162,163,212, 57, 59,166, 63, 63, 29, 59, 7,221,131,218, 74,253,120,208,161, 88, -213,225, 32,110, 52,110,172,131, 66, 39,237, 20, 9,191, 43,225, 35, 10,248,231, 15,158,117,156, 35, 53,105, 68,159,187,221,188, - 57,241,166,195,217, 64, 66,230,248,230,218,237,193,216, 73, 37, 65, 94, 1,103, 16,226,101, 99, 67,234,229,193,207, 14, 20, 3, - 40,215,224,129, 48, 89, 52,101,212,235, 75, 40,221, 37, 53, 41, 34,148, 53, 44,217,194, 87, 80, 81,184,254, 51,216, 5,159, 8, - 19,234, 31,232, 15, 47, 28,130,241,218,100,153, 22, 76, 3,175,104,145, 87,216, 93,145,178, 22,131, 84, 31,101,121,237,189, 0, -124, 93,219, 78, 26, 81, 20,157,155,140, 48, 80,174,138,130, 10,216, 24, 77,107,171,166,233, 83,147,190, 52,105,210,183, 62,250, - 5,253,137,254, 68, 95,251, 5,237, 87,244, 23,154,104,236,139, 87, 82,111, 48, 32, 50, 48,204,192, 92, 78,247,218, 7,232, 75, -211, 55, 35,193,113,102,206,217,123,237,125,246, 90,107,198, 95,197, 80,193,152,128, 26, 45,110, 40,217,134,115,241,144, 88,122, - 31, 91, 11,105, 90,116,158,239,210,114,165, 7, 10, 17,125, 66,144, 20,218, 68,136,112, 16,249, 76, 33,231,188,204, 14, 59,180, - 57, 79,154,199,244, 3, 79, 98, 41,118,255, 14,131,243, 59,111, 59,131, 86, 44,217,254,236,235,196, 34, 12, 19, 30,116, 3,185, -192, 52, 48,152,200,231,162,234, 94,253,160,235,118, 21, 49, 55,190, 65,185, 77,137, 97, 57, 87,253,213, 60, 26,142,134,134,206, - 10, 24,124,225,181, 66,109,132, 14,123,252,234,233,235,148,145,236,129,222, 70, 41,198, 96,254,177,144,178,110,202, 76,144, 52, - 22, 76,181,101,251,189,144,103,180,232,165,250,193,100, 37, 87,233, 14, 59, 56, 57,141,198,142,231,208, 95,160,128,110,247,219, - 82,197, 12,193, 75,210, 28,152,158,155, 79, 23,237, 65,155,222,226,179,141,221,253,250,254,233,253,233,251,131, 15,231,183,103, -132, 88,185, 16, 17,235,197, 42, 86,158,219,163,183, 66,181,161, 51, 26,108, 85,112,158,124,210, 60,114,188, 62,219,216, 26, 93, -167, 77,153,166,144, 46,150,243,101,186, 23,123, 96, 47,101, 43, 24,191, 33,236,160,197,148, 47,253,136, 98,144, 43, 12, 17,224, -116, 83, 13, 89,249,158,161,179, 66, 33, 30, 20, 79,140,212,243,147, 84, 12,140,150, 8, 61, 73,128, 38,101,104,166,158, 0, 69, - 91, 24, 60, 68, 77, 32,121, 65, 19,102,100,249, 2, 93,163, 32,138, 60,223, 99, 30, 59,224, 99,222,170, 82,141,133,186, 20,109, -169, 48,101,192, 83,152, 62,251,221,185,138,226,233, 48, 20, 45, 35,180,216, 35,246, 87, 97,238, 69,122,241,137,199, 70, 57, 82, -160, 13,225, 62,145,202, 89,185,161,215,135,107, 37, 26,220, 82,125, 2,180,100,186,211,164,105,161, 57,163,234,148,189, 8, 2, -163,189, 51, 99, 16,233, 51, 67, 58,214,237, 10, 30,220,142, 23,184, 89,171, 32, 71, 33,105, 11,241,222,192,167,249, 84,142, 82, - 50,253,158,160, 7, 93,165,154, 91,163,250, 0, 68,237,116,137, 0,148, 14,239, 61,170, 53, 3, 80,121, 34,216,111, 38, 88, 35, -158,246,121, 42,145, 66,129,175,225, 0,192,133, 49, 11,232, 23,244, 47, 45, 64, 18, 29,242,212,132,241,109,231,158, 71,241,208, -231,166,219,132,238, 2, 38,145, 1,128,234,229,205,250,114,195,118,108, 86, 71, 16, 84,194, 98,122,138,219, 8, 84,198, 61, 14, -187, 58, 14,249, 45,202,250, 44,124, 63,133, 38, 66,157,219, 99,171,114,236, 24,103,185, 49,212, 49, 49,241, 22,133,132, 36,122, -195,110, 66,151, 2,162, 82, 57, 67,155, 14, 68, 67, 23, 91,147, 29,163,132,110,122,147, 65, 33,179, 36,130, 0, 30,147, 90,168, -138,201, 94,125,103,109,185, 60,190,252,249,166,164, 21, 13,237,133, 22,127, 58,124,167, 36,211, 74,109, 69,217,218, 70, 91,102, - 20,240,225,234, 68,244,122,253,219, 75, 60, 17,110,188, 51,120, 23,154, 36,236,227, 77, 6,139, 86,198, 72, 36, 19,113,108, 24, -186,178, 94, 42,173,230,115, 78,112,220,143,154,237,199,150, 23,157, 57, 97,163,241,242,243,151,175,217,195,143,156,185,245,255, -185, 6, 93,223,156,126,251, 94,105,228,204,253, 6,198,114, 76, 93,170,107, 42,254,248,250, 71,243,220,245, 52, 54,243,101,249, - 15,236, 73, 20,151,102, 42, 36,240,203, 70, 31, 17,219,102,203,248,128,230, 8,243,252, 27,229,198,205,195,221,102,185,118,217, -106,210,151, 78, 46,142,111, 58,183,207,107,187,244, 45,122, 68, 84,247,108, 44,213,250,238,195, 0,103,236,121,136, 17,137,152, - 96, 56,165, 82,104,100, 65,135, 89, 45, 81,149,236,142, 46, 90,231,178,251,186,181,186, 77,105, 59,155,204, 94,180,174, 64, 64, -229,203, 24,134, 73,145,221,101, 50, 26,197, 20, 42,239,168,128, 24, 7, 35,200,239,207, 92,152, 88, 51, 21,152, 81, 58,207,201, -172, 44,203, 33,169,219, 50,111,140,139,185,238,169,208,132, 50,247,209,198, 98,207,152, 25,130,103,210,122,138,150, 1, 27,234, -154,233,197,180, 23,248,255,118,232,136,149, 49, 11,180,104,127,161,253, 92, 1, 68,204,162,188, 58, 83,113,157,118,121, 36,243, -226,143, 0,116, 93, 75,107,212, 80, 24,205,123,146,105, 50,201, 56,118, 30,125, 76, 75,165,138,197, 10, 22, 92, 8, 5, 65, 11, -186,171, 11, 69, 55, 46,221,184,112,225, 47,114,225,218, 63, 32,184,243, 15,136, 20, 65,173, 20,235,224,212, 62, 38,147, 52,147, -100,242,240, 59,223, 77,109, 55,194,108,135,188,238,253,238,249, 30,231,156, 42,190, 19, 44,224, 86,164, 82, 86, 28, 89,108, 39, -208, 97, 20, 93,168,118,208,162, 10,147,128,121,186, 37, 55, 12, 41,184, 76,103, 44,135, 29,108, 75, 2,170, 66, 4, 78, 85,141, - 54,225, 92, 22, 23,172, 67, 17,187,160,176, 85,131, 79, 55, 24,151, 65, 52, 10, 98, 95,147, 49,220,170, 67,128,206,192,160, 27, -165,210,220, 97, 48,107,117,250, 99,158, 87, 90, 47, 67,127, 40,132, 55,207, 77,165,164,210,212,105, 25,154, 56, 66,140, 26,133, - 89, 3, 82,203, 5,235, 95,106, 4,199,226, 36, 62,244,135,132,202,255,153,154,168,112,222,202, 77,179,158, 36,137,152,202, 97, -252, 94,232,186,185,117,115,139,194, 40,229,104,244,188, 20,170, 34, 10, 40,150, 77, 7, 50,161, 63,215,110,158, 68, 20,223,245, -203, 94,119, 99,229,118, 38,101,112, 17,226,119, 72,169, 70,191,189, 76,185,203, 40,162,181, 8, 97,113, 74,122,104,209,252, 30, - 13,119,135,223,114,204,154,103, 42,189, 52, 57,163,213,230, 57, 45,194,161, 78,205, 78,203,233, 92,115,126,112,178, 47,196, 46, - 88,230, 1, 68, 89,102, 63,129, 11, 59, 28, 15,101, 69, 59,157, 96, 10,147,194,144,109, 57, 86,205, 58,142, 14,184, 89,157, 19, - 96,101,243,109,142, 67,133, 80, 53, 18,198,148, 66, 78,218,104, 57,152,108,131,142, 60,171, 53,164,185, 50, 74,202,105, 34, 39, -116, 97,136,102, 9,113,227,228,146, 68,183,237,107, 18, 52,237, 42,143, 31,230, 52, 50, 62,149,166,194,223, 27, 42,219,152, 58, -151, 43, 77, 44, 88,224, 2, 47,103,153,138, 1,251, 92,150,171,150,145,161, 26,144,138, 84, 96, 72, 38,180,243, 10,158, 42,161, -116,141, 80,194,172,219,133, 27,131,196,213,111, 89,157,117,219,227, 9,129, 44, 5, 2, 29,232,163, 20,103, 78,236, 24,193, 42, -170,166, 98,201,130,145,104,123,210, 74, 64, 17, 70,168, 12, 87,131,107,248,120,108, 20,128,174, 56,106,189, 69, 30,103, 17,221, - 70,198,202, 61,204,168, 42,233,186, 43,221, 85, 33, 53,213,241,122,132,124, 99,150,125,190,214, 95,255,117,184,215,107, 46,208, -255,231, 91, 11,126, 56,178, 96,190, 67, 56, 37,231,141,170,210,163, 17, 74, 90,106, 47, 31, 7,199, 42, 6,192, 12, 65,209,160, -253,229,212, 27, 1, 96,221,145,112, 40,196, 9, 11,249,148,172,144,139,134,229,249,225, 81,194, 45,101, 12, 90, 64,205,194,164, -207, 7,229, 19,133, 14,188,153,174, 75, 73, 94,216,107,206, 99, 9, 49,133, 85,229,202,236,105, 18,205,152,245,205,181,205,175, -131,239, 66,220,128, 34, 47,219,196,227,112,106, 55, 58, 17, 59,127,170, 60, 76,105,215,108, 77, 85,226, 52, 84, 68,218, 15,183, - 15,213,211,236,167,143,159,191,255,240,174,175,197,183, 60,125,206, 80,174,110, 63,196, 40,203,245, 43, 82,171, 67,167,162,148, -164,248, 69,113,186,191, 27,142,254,160, 54,147,229, 66,219, 85, 45,217,224, 12,149, 34,180,175, 96, 46,232,184,116, 45,147, 9, -123,210, 98,179,211,241,186,153, 54, 72, 37,221,110,191,120,242,106,251,229,107,125,109, 85,202, 38, 18,232,165,181,255, 6,247, -221,189, 47,111,222,182,156,188,121,119, 93, 90,242, 36,219, 96, 15,223, 76, 34,232, 57, 60, 24,124,140,246,146,128,128, 46,115, - 21, 97,222, 66,200, 58,206, 83,209, 15,144, 49,221,212,227,112,140,157, 75, 49,253, 36,244,209,114,208,106,254,233,248,193,198, - 61, 74,190, 32, 20,200,100,195,197,214,130,219,239,169, 5, 68,108, 54,111,220,249,244,227, 51,136,205,121,249,232,254,179, 69, -175,179,243,115, 39,136,198,163,137, 79,239, 45, 76, 67, 90, 50, 33,108,118, 84, 10,160,168,191, 7, 71,104,131,151, 41, 65, 46, - 56, 91, 8,202, 61,114,140, 76,168, 16, 54,234,222,132, 89,108, 83,238,144, 87,122, 3,149,155, 77,233, 88,205, 9, 4, 54, 36, -250, 16,148,146, 78,167, 25,184, 75,152,134,148, 47,216,149,158,219, 16,139,149, 75,177, 20, 35,124,132,234, 64,149, 71, 63,203, - 53, 93, 7,149,198, 56, 69,101, 50, 19,149,106,174,204, 21, 23, 13, 87,133, 41,240, 69, 71, 99,249,220,227, 81, 62,147, 50,170, - 60,125,105,235, 85,112,190,172,204, 98,255, 10, 64,213,245,253, 38, 13, 70,209, 22, 90,104,161,116, 10, 12,152,147,196,172, 35, - 44, 51,209,105,226,140, 15,250,104,226,163, 62,152,204,127,207,196,127,192, 23, 19,223,124, 52,234,156,209, 23,151,109,137,211, -169,211,209, 82, 40, 45,237, 87,234, 61,247, 43,184,237,185, 11,133,246,187,247,220, 31,231,156, 60,190,179,225,228, 98,155, 51, -183, 74,165, 7,144,160,114,103, 6, 23,151, 83,213, 82,165, 92,170,114, 29, 13,252, 78, 25,146,142, 43,160, 16,216,249, 26, 70, -100,154, 17, 74,143, 11,102,156,214, 76, 43,156, 70, 20,170,232,122, 41,219,164,162,186, 52, 8,121,209, 79, 63, 12,128,178,209, - 96, 73,169, 28,131, 12,136, 16,226, 90,199,241,121,159, 76, 71,125,170, 54,237, 14, 86,227, 97,213,134, 59,160, 3, 70, 79, 14, -113,132, 11, 8,198,238,232,157, 65,211, 7, 93, 37, 74, 67, 37, 86,191, 78,206,235,130, 81,146,108, 82,124,153,120,115,153,125, -164,168,253,159,251,116,104,165, 79, 12,108,134,216,224,107, 28, 79, 40,190,255, 30,158, 90,104,135,165,167,222,175,195,211,131, - 49,229,124,153, 28, 88,143,226,254,245, 7,239,246,223,234, 26,239, 26,113, 43, 17,252,172, 52,109, 45,181,235,118,211, 11, 60, -250, 34, 4, 73, 8, 51, 18,232,142,227, 92, 32,158,222, 95, 86, 22, 84, 55,187, 55,220,224,108,187,183,237,141,135, 59,247,119, -190, 15, 78,160,213,197,218, 89,116,219,183,123,119, 70,129, 31,196,163,141,238,230, 15,247,248,182,115,247,123,248,181,140,101, - 83, 1, 57, 86, 93,146,118,185, 83, 40,139, 90,202,234,197,172, 89, 51,235,181,242,165, 90,201,208, 41, 22, 20,133, 90,140,102, -153, 92, 72,164, 75, 52,132,101, 42,182,146,167,143,159, 29, 30, 30, 37, 49, 60, 39,145, 87, 4, 52,150, 85, 86,237,107, 88, 45, - 58, 33,151, 43, 77,200, 42, 97,185, 33,149,154, 21,237,165, 43,163,200,111, 84, 26, 65, 18,106,232,138,228,179, 16,137, 79, 11, - 28, 22, 51,101, 49, 74,165,136,102,201, 31, 57, 4,137,159, 0,178, 41,113, 26,193, 34, 28,155, 40, 34, 84, 62,157, 78,232, 37, -180, 13, 91, 10,180,214,209,163, 8,121, 49, 33,119,178,131,193, 13, 47, 26,208,127, 90,229,154,228, 36,207,201, 65,179,220,243, - 8,156, 34, 41,184,152, 73,229, 41, 13, 34, 15, 8, 91,163,201, 40,134, 49, 34,246, 0,131,208, 47,194,173, 55,254,246,231, 72, -210,251, 77,195,116, 71,131,181,182, 99,148, 76,170, 71, 69,154,107,132, 73, 50, 97, 34,166,216, 11,226,217,175,148, 12, 76,249, -243,224, 4,157,138, 75, 80,132,174, 83, 24,176, 43,168, 93, 88,199,134,234,160,168,160,204,221,146,120,155,104,198,219, 33,154, - 92, 6, 67,175, 55, 97,161,177, 76,135, 87,101, 41,138, 41,111,165,171,141, 85, 89, 92,250,227,161,101, 84,153, 53,163,174, 54, -186, 3, 31, 11, 66,203,118,187, 97, 47, 19, 56,224,153,182,144, 6, 41,224,121,209,103, 65,159, 11, 13,208, 51,247,228,222,214, - 93,231,230,246,203,215,175,188, 73,218,176,235,235, 79, 30,226, 39,234,247,149,138,133,181, 25,128,119,161, 12,254, 76,142, 15, -232, 6, 42,205,213,140, 50,107, 50,101, 87,208, 76,227,204, 91,212, 88,234, 99,150,130,217,108,217, 58,157,122, 58, 16,150, 73, - 33,190,209,109,245, 53,211,143,162,227,179,191,250,116,118, 57, 46, 20,166,116,210, 20, 80, 85,117,109, 65,155,201,255,194,177, -255,250,205,222,139,231,173,150,222,126,116, 75,217,104, 43, 37, 99,110,198,156, 18,100, 80, 62, 29,124,120, 63, 26,204, 66,172, - 34,164,169,211,219,234, 44,119,161,134, 10, 86, 55, 87,128, 10, 61,172, 64,240,161,166, 7,231, 49,119,157, 21,208,209, 73,217, - 61,220,115, 86,214,126,184,191, 64, 12,196,100,197,216, 94,191,245,241,235,174,231,187,244,106,249,147,241, 70,183, 79,117, 54, - 21,208,159,143,190,196,169,112,218,107,220, 0, 44, 82,173,108,155,182,211,113,220,192, 29,134,163, 37,163, 70, 96,208, 13, 60, -171, 12,205,140,205,171,215,185,100, 20,240,246, 82, 21,103,165, 71, 53, 52,211, 51, 11,232, 43,168,105,169,160, 17, 78,197,124, - 37,239, 18, 35, 10,136, 89,204,179, 87, 30,242,171,153,105, 84,232,205, 19,121,168,252,223, 96, 89,116, 78, 84,166, 55,134, 32, -139,240,176,156,135, 20,244,130,197,224,131, 39,114, 61, 82, 74,210,131, 41,153,137,115,172,212, 5,188,157,219,214, 94, 80, 41, -187,160,252,174,230, 42, 77,153,188,162, 90,182, 9,247,252, 19,128,170,107, 91,106, 26,138,162, 39,151, 38,105,146,150, 6, 40, - 45,133,222,184, 15,131,162,142, 51,242,232,163,175,254,143,126,142, 15,126,132,175,206,160, 3,204, 0, 62,136, 92, 68, 6, 42, -104,105,154,166,105,154, 75,227,222,251, 36, 3,242, 88,232, 76, 90,206,217,151,181,215, 94, 43,157,175,170,170, 65,178, 77, 9, - 49,181,101, 46,162, 3, 85,249, 4,189,231,101,126,202, 75,186, 5,141, 45,221, 91, 54, 83,156,221,168,109,117, 7,127,122, 72, -105, 16,147,204,170, 13,154,110, 66, 60, 82, 78,157, 31, 6, 16,205, 33,196, 19, 43,130, 28,115,104, 45,118, 66,155,238, 11,179, -245,158,123, 15,223, 41, 68, 25, 20,221,142,124,200, 63,112, 7,188,145, 75, 53,154, 64, 54,202, 49,129, 15, 16,184,101, 26,104, -224,116, 75, 65, 49,250, 8, 55,215, 89, 76,227,236,113, 74, 85,163, 85, 38, 83, 43,172,215, 54,161, 63,128,184, 44,144,116,233, -192,183, 33,120,197,156,152, 65,231, 5,158,182,168, 79,241,189, 42,153,200, 29,104, 19, 52,129, 64, 89,222,217,124,133,164,142, - 40, 32,199,202, 92,132,106, 39, 34,183,227, 34, 56,100, 98,230,139, 56, 52,131,120,141, 60, 63, 92, 61,129,124, 14,117,248,180, - 57,115,217,253,217,152, 89,182,189, 46, 28,216, 28, 77, 87, 40, 76, 8,188,222,212, 84,220,222,132,166,210,241, 7, 55,247,157, - 81,228, 75,146, 4, 41,164, 62,215,116, 61,167, 98,213,170,214, 2, 4, 23,232, 12, 66, 33, 90,156, 89,104,204, 46, 13,195,193, - 32,188, 22, 69,197,113,131, 49, 41,243, 6,120, 61,210,233, 53, 5, 52, 84,152,180, 76, 93, 35,109, 50, 77, 19, 13, 36,171,137, -130, 34, 20, 13, 73, 87,224, 22, 35,210, 26, 96,175, 17, 31,238,237, 17, 67, 60,135, 68, 41, 44,230, 16, 97,132, 32, 2,231, 12, -174, 13,138,198,163,195,159,160,228,116,196,205,137,177,138,190,198, 73,130, 11, 26,116, 34, 11,198, 20,177,197, 5, 77,214, 84, - 37, 47,164, 36, 1,220, 48, 39,210,135, 72, 86,236, 28,207, 97,229,169,121,204, 25,166,133,108,153, 73, 82, 41, 85,116, 85,119, - 32,255, 77, 66, 46, 86, 19,227,106,179,224,141, 28,120, 61,224,202,192, 9,231, 81, 74, 98,230, 90, 73, 37,115,194,221,112,200, - 89, 27,143, 89,201,180,160,159,165, 41, 22,129,212,162,108,228, 13, 20,171, 82,161,145,209, 71,193,240,105,243,185,161,234,148, -116,171,228,228,142, 39, 19,130,153,133, 82, 83, 97,165, 52,119,121,119, 78,224,143, 48,109, 78,243,101, 84, 14,222,135, 56,160, -120,248, 73, 72,205,168, 85, 94,129,199,134,192, 42,203,232,209, 12,229, 11,109,177,138, 60,223,103,157,114,138,185, 35, 38, 25, - 71,216,180,200,136, 51,228,208, 76, 57, 78, 29, 12,176, 99,138,182, 26, 79,182,219,207, 92,207,117, 70, 54,220, 5, 44, 2, 16, -110,194,143,107,187, 61,190, 22,230,249, 14,178,140,226,177,150, 83,161,146,230,250,184,227,208, 75,200, 49,184,100,148, 17,197, - 78, 38,253,206,205,155,119,239,219,229,149,131,227,179,205,213,122,237,245, 54,211,100,214,106, 49, 89, 65,228,125, 20,179,193, -144, 93,124,247,237,110, 34,229,244,242,226,120,216,143,224,254,146,112,160,196,253, 15,113,219, 10,106,254, 24, 81, 26, 21,250, -141, 2, 23,146, 69,122, 12, 84, 13,173,242,102,117, 78, 9,252,111, 39, 71, 95,246,191,254,254,113,166,216, 67,189, 31, 72,142, -207,238, 6,172,219,103,118, 63,186,186,178, 63,127, 57,254,240,177,115,180,187,241, 98,169,252,246, 37,107,215,224,128,100, 78, -112, 68,198,116, 29,246,233,116,247,210, 11,177,172, 96,245, 82,189,247,183,115,126,117, 98, 15,123, 70,222,132,236, 5, 21, 12, -132, 20,168,178, 57,180,204,165, 1,139,186, 53, 10,135, 88, 17,170,198,250,194, 26, 36,216, 95,119,151,203,181, 53, 56, 99,144, - 50,175,161, 81,119,123,205,106,243,188,115,209,110,172,206, 87, 26, 5, 53,127,120,113,104, 21,167,225,183, 16, 46,122,110,247, -214,190,133,127, 7,252,217,206,198,206,254,233, 1, 28,120,232, 95, 85, 69,131, 34, 6, 7, 99,140, 65, 37, 7,133,149,129, 81, - 5,151,182,225, 45, 18,147,114,138, 58, 14,112,141, 95, 87, 77,207,247,176, 73,205, 64,151,152, 10,127, 90,197,225, 42, 64, 40, - 50, 59, 14, 67,120,126,138, 66, 73, 6,146, 60, 90, 46,165,207, 3, 61,125,170,152,155,249,169, 18, 73, 36, 78, 50, 77, 96,202, -184, 18,201, 20, 7,255, 59,226, 61,112,100,146, 7, 65,130, 84,225, 56,147,218,226,203, 83,236,145, 16, 55,227,195,234,127, 2, - 48,117,101, 61, 77,132, 81,116,182, 78,167, 29,134, 78,103,170, 84, 44, 66, 93, 16,121,112, 11, 18,226,155, 47, 62, 26, 19, 19, -125, 48,254, 80,159, 93,131,146,248,162, 9, 81, 43, 46,128, 5,161,204, 66,103,159,122,207,253, 6,241, 21, 18, 38,204,124,223, -185,219,185,231, 84,250,239, 37,243, 43, 39,220,158, 43,202,170, 69,159, 11,117,108, 86, 61,165, 99, 74,111,132, 32,204,177, 58, -244,190, 34,138,153,209,136, 46,124, 82,164,103,172, 25,194,253, 58,107,190,243,124, 21, 79, 94,158,187,217,115,251, 20, 33,177, - 35,143,120,112,246,194,204,194,193,104,159,253, 84,148,214,148, 19,198, 71, 65, 28,208,237, 53,116, 3, 10,232,138, 58, 78,177, -249,237,143, 61,246,230, 17,145, 8, 13,119,104, 85,230, 17,111, 27, 97,246,197,170,192, 25,179,224, 77, 58, 25, 4,163, 20, 93, - 5,193, 80,228,156, 81, 18, 13,253,161, 15,170, 37, 22,255, 96,243,132,158,154, 82,237,204, 11, 55, 76, 76,227, 84,166, 19,100, -244, 61,177, 49, 44, 43, 5, 62, 85,188,249,107,115,207, 27,210,215,162,138, 73, 48,156,132, 15,115,183,221,187,117,105,117,232, -237,252, 9, 14, 93,211, 45,132, 74,178, 4,195, 38,161, 50, 74, 64,137,181, 53,185,212, 52, 52, 40, 40,126, 16, 10,180, 76,251, -193,218,195,193,239, 65,152,120,192, 62, 69,165,103, 81, 22, 78,135,140,170, 31,148,252,101,222,172,155,245,122, 3, 66, 25, 25, -248,191, 16, 78, 81, 48,128,162, 87,241,105,248, 94,146, 53,219, 50,100, 37, 3,255, 19,136, 83, 80,242, 4,174,164,204,222,111, -136,155,229,172,109, 73,152,215,201,208,196, 46,149,184,144, 48, 1, 40,149, 44,153, 4,227, 44,103,112, 39, 96,108, 72,186,170, -213,112,197,208, 1, 69,170,233, 90,103,254,120,251,231,157, 57,186, 72, 89,154,222,190,180,182, 51,218,166,204,133,251, 90,213, -184, 72, 40,218,169,156, 27,208,123,166, 35,222,162,212,187, 72,162,108, 12,249,176, 34,235,119, 23,109,179, 29,199, 49, 11,180, -202, 76, 29,211, 5,245, 91, 97, 14,229, 82,111, 57,140, 60,138,229,112,194,226,142,182,176, 90,102,225,150, 9, 21,115,142,233, - 6,148,221, 16,130,215,160,144, 88,176, 72, 39, 68, 69,171,224, 88,157,115,180,137,184, 57, 35,216, 80,211,141, 22, 93, 6,170, - 42,166, 26, 54, 36,233,117, 42, 19, 99, 48,103, 20, 93,215, 52, 66,112, 58, 54, 80,155,226,166, 10,132,240, 64,191,145,207,217, -221,237,131, 95,220, 76,197, 31,143, 88,130, 74,158,156,234,138,157, 40,194,115,117, 36,149, 70,173, 65, 39, 51,157,164,244,242, - 9,139,155,122,179,215,185,224, 69,135,178,208, 21,228,243, 33,164,198,121,238, 42, 9,123, 79,238, 75,169,236,100, 93, 67, 98, -161, 96,119, 75,229,235,189,239, 15,193,229,144, 74,138, 79,113, 26, 11,211, 53,181,242,153,171,244,145,193,164,204,177,244, 72, -191,245,209, 66, 4,253,136, 16,208, 64,232, 77,203, 50,210, 20,185,174,235,126, 48,186,109,117,123,207, 30,223, 93, 92,155,189, -222,145, 26,153, 52,101, 64, 80,172,102, 80, 41,138,245,209,239, 95, 39,187,223, 9,128,232, 36, 39,222, 97, 30,135, 98,213, 70, - 80, 50,161, 59, 13,116,135, 1, 49,197, 11,185, 72, 40,131,210, 27, 83,146,176,192, 54, 84,232, 22,204, 58,157,171,115,203, 87, - 22,250, 29,171, 76,194,157,237, 47,159, 63,110, 12, 54,222,109,190,121,245,115, 99,253,199,235, 23, 91,111, 95, 30,239,125,235, - 95,155, 89,122,180,214,184,127, 83,178, 28, 9, 91,174,202, 73, 39, 32,151,168, 94,220,218, 28, 61,247,215,143, 66,157,203, 79, - 47, 14, 34,244,175, 40, 35, 49, 40,184, 30, 6, 71, 4, 53, 97, 60, 62, 33, 66, 87,171,253,170,166,197,108,118, 72, 21,143, 59, -237, 14,189,223,199,105, 84, 87,245, 32, 10, 41,127,114, 44,187,109, 58,244,127,121,199,254,222,209,126, 28,141,159,222,123,210, -235,244,118, 15,160, 51,232, 88,238,157,203, 43,243,221, 5,199,116, 6,195,193,234,226,202,198,215, 15, 55, 46, 94,223, 29,237, - 82,128,111, 91,109, 42,208, 49, 61,146,145, 64, 96, 82, 87,171, 55,107,205, 32, 14, 39,172, 70,199,208, 91,176,213, 85,121,170, -173,197, 67, 38, 6, 78,241,147,178,202,231,153, 3, 13,171, 18, 64, 12,230, 19, 21,196, 87, 90, 70, 18, 85, 99,182, 73,104,224, -255, 51,227,146,254,209,220, 43,157, 1,174, 76,241,208, 92,158, 40, 39,230, 8,255,103,241,242, 41, 51,166, 82, 10, 86, 41,167, -201,203,100,190,211, 39, 40,158, 54, 90, 41,187,213,139,102, 13,161,162,109,185, 81, 50,254, 43, 0, 87, 87,211,219,182, 21, 4, -159,248, 37,138,148,104, 90,178, 28, 69,178,227,196,150,213, 26, 72,130, 32, 78,155,246, 84,244, 28, 20,232,169,127,177, 64,127, - 65,211, 99, 47, 45, 2,228,208, 91, 99, 35, 40,106,197, 78, 12,249,155,166,196, 47,145,157,217, 39, 25, 65, 1,223,100, 80, 34, - 31,223,238,236,190,157,153, 69,124, 39,163,188,202,132,107,163,187, 52,170,110,186,130,240, 74,223,243,165, 41,198,168,143,251, -111,185, 1,181, 76, 85,153, 34, 50,214,172,188,204,182,123,187, 0,161, 36,205, 48, 55, 44,164, 51, 39,215,167,215,241, 37, 48, - 47,137, 39, 85, 14,192,117, 60, 25,203,221,112, 75,144,163, 37,237,108,135, 24,217,205,242,140,178, 83,228,178, 87, 90, 49,172, - 18,158,174,215,240,241, 21,200,165,213,242, 8,110,249,212,176, 85,108,215,146,249,185, 18, 27,207, 0,102, 7, 14,193, 98,111, -117, 31, 32,128, 86, 68,181,166, 12,107, 34,100,167,150,233,104,195,159,185,152, 76,154, 34, 63, 93,178,231, 37,149,181,201, 94, -170,158,110, 67,188,188,215,238, 19,101,115,244,155,235,172, 22, 46,183,234, 42,190, 24,159, 29,101, 98,195, 38, 67, 59, 73,179, - 65, 22, 53, 86, 5,155,119,181,217, 6,214,230,240, 76, 49,171, 83,174, 39,225,117, 77, 19,175,200,187,241,223,253,246, 96,183, -255,229,199,203,147, 21, 47,160, 84,105, 61,160, 44,190,141,215,119,134,136,121,155, 69, 97,179,141,208, 54,137,206, 95,142,190, - 9, 90,193,197, 20,225,163,218, 88,223,152,213, 62,184,142,213, 9,235,165,153, 81,191, 92,196,121, 68, 4, 83,149,213, 66,217, -124,150,148,247, 2,207,114,172, 6, 13, 93,137,221,115, 36,137,178, 18, 58,127,141,193, 93, 12,127, 29, 75, 53, 42,207,170, 57, - 41,253, 78,101, 28,205,176,166, 73, 28,103, 81, 52,139, 72, 14,170, 56,249, 19,167, 83, 92,100,165,177,154, 20,169, 46, 92,238, -175, 14,166, 66, 63,193, 74,181, 91, 93, 60,183,105, 22, 3,188,183,220, 80, 36,241,212, 85,116,113, 25,159, 55,189,144,225,213, -118,189,122, 43,203,103, 40,254, 80, 23,127, 49,216, 59, 62,251,247,226,102, 18,250,107,248, 25, 90,204, 94, 31, 18,152,166,141, -252,228, 59, 13,172, 8,243, 40, 45,146,145,144,109, 14, 59, 21, 44, 32, 7,157, 77,241,231, 99, 95,202, 18,239,231, 52, 7, 34, - 45,155,245,128, 13, 49,146,170, 82,154,214,137, 22, 56,246,100,224,175, 32,226,239,220, 31,253,115,122,176, 22,172, 35,119,216, -156,202,245,113, 77,158, 92,168,106,173,217, 29,109,238, 89,134,115, 27, 71,226,127, 65,193, 34, 44, 95,191,189, 49, 37, 57,101, -186,217,217, 66, 57,207,211,126, 93,200,178,142,224, 79,214,212, 92,219, 48, 57,181,105,219,231, 55,103,115, 17,150, 98, 23,165, -217,185,161,111,129, 18,190,180,248,125, 26, 86, 83,135,200,178,212,141, 31,147,162, 81, 78, 41,227,155, 60,142,178, 40, 90, 27, - 37,184, 53, 99,179,187,245, 98,103,255,104,114,100,104, 58,149,170, 33,205, 3,208,219,164,148, 6,216,128,190,227,225,106, 8, -100,168, 27, 82,122, 27,165,162, 42,138,119,139,114, 0,136,227, 39,135,135,251,225,186,181,214, 81,205,177, 50, 10,148, 54,202, - 71, 30,247,216,159, 25,143,213,209,161, 74,102, 60,150,231, 51,205,131,222, 67,182, 10,242, 84, 58,239, 74, 15,107, 50,190,115, - 12,158, 33,222, 0,222,242,188,154, 47,162,240,148,229,179,148,103,169,176,161, 30,132,238,168,223,123,190,243,232,249,112,247, -201,195,225,211,193,246,227,193,214,179,141, 71,223, 14,183, 95,237, 15,126,124,233,125,245, 84,117,123, 10, 16,130,189,135,106, -217,127,166,157,151, 58, 30,171,223, 15,254,248, 75, 93,169,212,183, 60,154, 75, 9,149, 20,183, 70, 37,159,134, 95,210,248, 48, - 85,139,145,150, 82, 51, 12,139, 90,153,229,121, 37,100,178,121,141, 74, 80, 89,177, 96,164,183,188, 0,127,192,133,173, 32,124, -127,250,126,167, 55,196, 59, 14, 48,244,235,219,215,199,103, 31,247,247,190, 62,248,112, 0,164,127,157,196,111,222,253, 25, 77, -111,127,120,245,211, 47,191,253, 60, 26, 12, 79,206, 63,137,237,237, 28,245, 98,148, 78, 83,250, 47,210,123, 93,143,193,124,247, -248,251,211, 43,252, 67,134, 20, 62,231, 1,161,131,199, 82, 72,173,169,229,113, 76,170, 3, 21,255,159, 81, 95,234,244, 98, 77, -215,131,222,165,200, 25, 25,159,217,148,225, 99, 84,177,145,200,127,222,185,119, 85, 36, 3,133, 58,236,220,105,208,125,102,100, -186,240,110, 82,119, 33,125,169,207,107, 46, 38,112,137,180, 92,195, 77, 10,164,202, 27,253, 81, 69,127, 61,205, 94, 37,158,168, - 91, 54,162,211,127, 2,112,117, 37,187, 77, 4, 81,176,199, 61,251,120, 73,108,131,226,108, 4, 20, 41, 72, 64,196,118,224,200, - 5,129,196, 71,115,130, 3,119, 14, 44, 74, 32,193, 68,206, 98, 71,241,140, 61,227,217,168,122,109, 3, 66,242,193, 7, 59,206, -244,188,121,175, 94,191,234,170, 85,126, 87, 13,128,184,173,238,157,132,181, 49, 23,213, 61, 79,152, 51, 21,137,116,249, 76, 36, -131, 40,209, 37,123,214, 37,201, 15, 85,229,161,145,201, 83, 52, 53, 64,132,166,201, 50,205,133,177, 21,171,164,148,161,233, 0, -214, 11,156,136, 46, 72, 50, 53,175, 87,206,108, 66,143,179, 60, 27, 25,193,155,102, 55,127,212,248, 68,127,161, 16,133,191, 22, -138, 30, 77,118, 12,173,114,121,192, 85, 84, 99, 43, 74, 70,136, 90,139, 47,155, 21,165,137,139,131, 77, 64,197, 56,149,177,137, -181,210,237,163, 57,131,101,227,215,118,123,123,147,217,132, 36, 1, 75,137,138, 55,133,224, 75, 97,218, 25,146, 12, 30, 66,228, - 50, 50,229, 85,253,250,233,235,190,136,185, 55,148,109,228,188,128,118, 53, 85, 29, 1,107,250,179, 60,193,178, 20,244,113, 77, -128,121,146, 92,216, 53,210,161, 33, 51,182,131,245,100, 17,251, 66, 31, 18,231,144,234,232,226, 8, 23, 12,180, 2, 80,207,237, - 8, 10,158,144, 39,183, 63, 56, 64, 74, 26,142, 79,145,229, 17, 85,168,115,103,215, 67,132,111,169,138,209, 12, 40, 47, 71, 66, - 9, 92,103,194, 35, 78,108, 19, 22, 21,105,239,233, 2,232,184, 90, 0, 85,210,118,183, 28, 32,179,121, 78, 20,104,223, 83,116, -237,224,161,144,170, 25,232, 78,212,192,211,234, 59, 86,232, 42,223, 87,141,204, 77,242,152,105,167,178,178, 50,147, 77,199, 66, - 43,215,112, 66, 16,193, 40,132,156, 22, 52,172, 84,152,160,156, 58,138,190, 18,214, 83,104,211,220,110,106,133,107, 40,207, 77, -183, 57, 69, 42,164, 53, 18,249,217,154, 99,149, 64,116,105, 60, 20,179,181,104, 13,183, 27,145,135,194,207,148,166,157,132,130, -218,181, 88, 74,217,190, 77, 23, 61,143, 36,171,185, 88,253,229,102,110,185,228,137,113,248, 92, 71, 97,187,139,228,171,234,140, - 34, 51, 66,226,108,168,151, 15, 94,205,178,120, 58,187, 14,253,136,189,147,162,143, 16,131,157,171, 92,118,194,110,156,221, 92, - 78,175, 88,147,122,219, 72,169,123,131,253,179,241,137,205,233, 8,174,185, 70, 61, 94,143,214, 63,126,126, 15,228,139,178,167, -151,222,169, 53, 25, 44,182,189, 57,216,126,243,240,149,239,186, 39,151,167, 79,239, 62, 79, 50,142,133, 68, 78,167, 54,221,140, -184,209,233,192,139,226,249, 84,172, 54,235,157,254,238, 85,124, 41,103,244,168, 63,133, 15,136,150, 53, 15, 63,122, 20,182, 68, - 42, 55, 38,159, 11, 99, 37, 97, 60,223,165,163, 79, 35,158,144,226,185,135,227,243, 99,145,214,177, 54, 58, 27, 21,165, 16, 19, - 81,169, 85, 18,208, 37,190,139,213, 6,196,161,250, 7,139,153,177, 50,224, 47,105, 71,251,174,149,214,243,243,163,111,247,219, - 29,231, 64, 30, 56,228, 98, 96,152,121,166,126,158,168,147, 99, 53,157, 34, 98, 24, 35, 69,142, 2, 18,246, 55,203, 52, 41,209, - 87, 73,195,107, 91,130,220,241,215, 28,238,202,186, 26,152,160,208,101,170, 61, 95, 53,219,168,111,203,151, 43,130, 32,174,195, -202,209,109,171,193, 45,181, 51,104,236,237,232,221,109,107,176,165, 58, 61,165, 91,130,217,245,106,103, 88,220, 77,248,202,213, -104,168,190,124, 42, 63, 44,222,157,161, 73, 42,218,228, 92,205,113, 41,121, 94, 4,126,136, 4, 20,103, 73, 59,104, 2,110,227, - 65,107,134,205, 94,171,143, 55, 27,221,173, 89, 58,163,103,167,197,125,212,200,141,112,103, 81,194, 17, 45,104,136,199,241, 24, -139, 15,176, 21,182, 58,248,255,198,215, 23,111, 95,188,229,249,137,186,140,231,201,225,254,227, 31,163,239, 89,177,104, 2,152, - 46,230,168,148,163,225,176,215,185,253,232,238,225,175,241, 16, 17,131,152,199,199, 80, 30,162, 32,196,155,181,168,203,164,111, -213, 95,127,125,193, 77, 65,195,199, 70, 16, 88, 68,187,244,191,149,178, 19, 5,132,101,232,228,204, 17,107,101,253, 47,227,101, -142,127, 94, 39,147, 39,247,158,141,111,198,106, 53,222, 20, 30,181,146, 77, 48,203,168,164, 27,147, 33,163,240, 44,204, 27,155, -251,160,255, 56,169, 46,197,121,172,122,133,244,113,215, 61,102, 39,227,247,241,143,210, 36,207,208, 53,150,230, 70,226,215,246, -183,168,176,233, 41, 56, 31,250, 45, 0, 89,215,178,219, 52, 16, 69,199,175,216, 78,226,150, 52, 37,109, 90, 74, 42,181,129, 22, -129, 42,177, 96,129, 4, 11, 88, 3, 66, 98,197,159, 32,190, 7,246, 44,144, 16, 63,192,130, 34, 64, 72, 44, 16,143,242,104, 27, -154,151, 19,199,175,113,236,112,238,181, 83,144,144,178, 72,164,214,137, 61, 51,231,158, 59,115,239, 57, 5,190,131,236,208,106, - 28,119, 0,208, 42,167, 12,100, 68,105,150,145, 56,247,198,191,137, 77,147, 55, 78, 2, 12,153, 9,154,166, 28,214,178, 51,213, - 58, 82,215,194,154,149,109, 58,178,124,127, 84,136,181,122, 43,163,186, 46, 35,162, 35, 99,133, 85, 91,147,138,233, 88,164,148, - 18,177,244,229,108,177,122, 6,243,206, 39,125,184,105,204, 2, 76,133,206, 98, 30,142,184, 63, 59,101,161, 78,117,158,165,207, -184, 97, 20,137,219,220,213, 25, 83,137,253,184,115, 13, 43, 85,249,213,255,137,159,180, 96, 46,112,211, 63, 2,128,206,158,235, - 34,162,234,242,212, 54, 45,208,240,140,170, 12, 51,245,212, 60,135,142, 97,201,165, 15, 68,117, 28,186,121,122,216, 92,218,120, -255,245,109,103,212, 5,147, 13,147, 32, 23, 33, 1, 30,153,166, 69,109,168,105, 76,144, 68, 34,183,179,189,221,171,143, 30, 62, -126,246,234, 25,160,159, 28,232,185,111, 19, 28, 52,175,179,196, 79,141,211,105,144,132,200, 99, 72,252,207,176,183, 87,218,199, -227, 99,204, 63, 76,220, 97,224, 14, 2,215, 13,250, 24, 67, 64,207,245, 75, 55,239,221,122,240,238,243,155, 85, 80,230, 20, 49, - 21, 97, 70,242,237,170,131,113, 52,137,178, 88,178,198, 29, 31, 64,197,128, 31,228, 80, 9,153, 77,213,202,101,252,153, 81, 66, -224, 81,184, 4, 80, 11, 83,164,153, 10,213, 59, 34, 47,147, 41,130, 1, 65, 96,168,211,150, 20,167,159,120,148,119,174,221, 63, -232,124, 35,116,162, 75,106,101,171,204,102,226,126, 17,124, 69, 33,149, 65,226,171, 6,181, 11,173, 45,157, 15,177, 26, 43, 53, -215,239,227,153,128,224,204, 10,135, 97, 58,215, 4,136,128, 47, 3,197,194,200,239, 79,250,105,154, 44, 57, 13,201,140,126, 99, -169, 69,165,149, 92, 61, 86, 49,171,151, 91,123,248,136, 75, 97, 65,182,155,187,185, 76,216,245,157, 27,199,195, 78,126,132,131, -111,111, 56,141, 31,189,131, 40, 10, 73, 32, 77,136,197,106, 13, 43,188, 59, 58,241, 98,111,107,109,167,235,158,144,239, 37,149, -198,159,157, 38, 9, 30,215,102, 99,243,242,230, 94,207, 61,153,178, 62,229,208,235,130,101,119,134,135, 69,206,203, 3,237, 71, -222, 81,255, 16, 1,102,189,126, 94,202, 8,228,128,133,127, 85,140,212, 86,227,194, 86,123,251,233,203, 39,135,189, 95, 24,165, -178,105, 15,125, 82,161, 2,154,147,223, 17, 50, 95, 10,117, 25,130, 31,240, 23, 40, 91, 41,145,101,199,112, 50, 96,157, 3,245, -172,179,194, 97,190, 90,210,180,220,175, 7,255, 91, 54,172, 69,167, 6, 44,139,231,106,148, 26,232,142,174, 43,124, 10,188, 94, - 91,151,108, 22,154, 36, 81, 73,165, 86,117,214, 41, 21,245,234,242,149,214,149,145, 63, 74,167,210, 52,204,187,215,238, 2,119, - 72,151,128, 56,217, 76,201, 69, 19, 8,147, 41,163,197,250, 50, 45,211,155, 70, 85,183,211,186,189, 77, 59,174,128,224, 84, 10, -215, 21,221,174,240, 2, 17, 99,248,177,182,100,166, 25,186,237,196,227,190,244,186,185,190, 43, 27, 96,208,229, 12,141,106, 25, -168,154,141,230,168,106,224,102,147, 0, 75, 87, 56, 14, 41,204, 32,239, 35, 23,130, 92,139, 80,227,215,233, 27,173,184,173, 98, -223, 51,155, 35,123,254, 38, 17,195, 35,241,241,157,248,228,237,191, 54,212,202,106, 69,183, 6,147,158,174, 24,237,181,139, 39, - 30, 89, 39,174,214,154,157,193,239, 17,213, 83, 32,139, 13,164,148,236,119,122, 46, 78,146,120, 26, 86,172,133,148,229,202,195, - 56,194,141,111, 55,219,152,162,147,200,183, 13, 27, 75, 62,150,177,231,143, 12,234,145,140,119, 54,118,158,239,191,176, 12, 11, -121,192,199,239, 31, 6,193,208, 52,192, 30,192,141,108, 47,158,248,210,239,123,189, 47,199, 95,232,216, 76,204,144, 95,130,175, -172,212,155,203,206,242, 17,137,130, 80, 63, 60,119,202, 41, 44,254, 44,162, 68,166,133, 9, 10, 89, 3,230,251,230, 8,144,160, -179,114, 94,252, 42,138,186,252, 83, 31, 46, 54,239, 83, 85, 76, 57,139,244, 7, 83,106, 47, 96,254,202,155,196,212, 27,193, 54, -120,122,174, 21, 73,135,157, 84,130,137, 25, 88,116,146,254,107,144,109, 83, 89, 96,170, 83, 87, 60, 97, 73,197,102, 77, 5,173, -100, 82,165, 64,114,170,100,240,215,208,248,255, 87,110,224, 42,148, 63, 2, 80,117, 45,189,141, 83, 97,244,198,118,236,196,143, - 56, 15, 79,136,250, 24,202, 8, 49, 29,141, 4, 2,177, 65,176, 69, 72,108,249, 35,176, 65, 98,195, 47, 67,131,152, 1,137, 21, - 12, 66, 5, 22, 21,243,162, 77,155,166,173, 19,199,174, 29,199, 54,231,124,119, 50, 12, 82, 23,145, 90,165,137,124,191,115,191, -199,249,206, 33,190,203, 75, 75,147, 57,101,233, 78,203,151, 81,139,185,169,185, 65,235, 57, 46,139,101,221, 95, 86, 77,219,176, - 17,219, 56,217, 25,219,121,172, 76, 45, 41,171,181,221,182, 72,108, 35,233, 72,168,233, 88,174,197,171,143,190, 20,111,239,222, - 67,249, 3,160, 23, 9,111, 91,102, 32,109,113,178, 47,115, 25, 77,244,220,254,167,239,125,254,231,233,145,105,188,188,207, 28, -209, 13,150, 45,171,214,150,197,196, 4, 48,232, 4,196, 32,250, 12,105,102, 93, 99,201,138,191,205,101, 19, 63, 10,199,227,112, -188, 31,209,243,193,239,134,105,145,118, 44, 7,159,182,109, 57,113,118,141,136, 58,120,227, 96,142, 59, 86, 90,192,122, 31, 26, - 23, 15,206,246,233,226,212,161,202, 11,157, 76,104,170, 39,172,147, 5,178, 84,132, 26, 62,173, 97, 68,189,201, 60,157,149,178, -150, 69,139, 35, 42,222,217,201,114,245,232,241,195,178, 41, 43,131,238,160,100,170, 50,126,172,142,205, 44,149,124, 30,145, 35, - 23,155,210,102, 85,166,243,228, 2,215,140,109, 57, 31, 29,126,242,245, 23, 95,254,248,215,207,200, 10,129,122,166,221, 94,230, -203, 31,126,123, 48, 12,199, 81, 24, 93,165,115,211, 44, 0, 23, 0,247,190,111, 86, 98,218,129, 83, 67,205,182,170, 1, 6,118, - 58, 6,146, 87,214,232,166,186, 61,234,181, 72, 97, 52, 54, 69,109, 74,232, 39, 21, 69, 28, 80,162,228,235,106,177, 44,243,124, -131,199,137,242, 29,152, 66, 79, 72,202, 30,213,199,211, 99,218,217, 40,189,136,208,202, 40,177,105,104,169,103,124,214,144,221, -237, 74,211, 48,163,254,248,112,247,254, 31,255, 28,225,183, 52,218,149,148,182, 33, 93,218,246,108,159, 51, 38, 54,145, 91, 78, -219,213,219, 5,131,110,148,109,178,192,241, 20, 25, 53,238, 89,124,194, 89,142, 44, 46, 2, 76, 81, 74,207,226,115,139,195,210, -234, 50, 57, 71, 58,143,100,237,197,252,153,232, 12,115,247, 21,223,244,134,229,160,227, 5,254, 55, 95,125,251,224,209,119,123, -209,237,140,171,200, 52,210, 76, 86,177,177,229, 16,148,180, 68,103,114, 23,103,241,244,226,133,239,134,148,212,183, 28, 1, 46, -163,239,141,122,204,188, 88,255,225,113, 32,102,145, 86, 35, 67,156, 45,207,241,175,251,110, 31,127,121,157, 92,118,109,231,228, -234,228,201,243,227,161, 63, 34, 83,208,104, 47,210, 37, 96,189,145,113, 49,141,179,131, 8,160,140, 43,109,103,184,143,107, 9, -199,140, 27,149,173, 86,224,134,210, 89, 66, 45,149, 73,135,156,147,111,129, 77, 67,251,182,227,194,195,151,181, 90,214,173,112, - 92, 0,100,233, 69, 95,105, 25, 19,224, 84,199,212,236,236, 90, 40,167, 84,211,195,209, 90, 21,171,211,235,233,222, 96,103,145, - 47, 7,221,193,147,217, 83, 0, 25,240,183,223, 29,176,230,227, 58,180, 54,172,111,104, 95,131, 50,220,164,134,195,189,176,183, -255,217,161,146, 62,166,196,117, 91,197, 9,247, 87,139, 66,229,192,120,229,239,223,245, 38,111,118,130, 81,149,173,170,117, 42, - 21, 23, 25,126, 22,251, 51, 36, 92, 18,217,219,114,253,224, 60, 33,103,202, 19,181,201,149,239, 41,183, 75,182,140,165,254,111, - 50,247,122,135,226, 85,182,190,217,190,192,207,141, 58,255, 91, 29,253,174,210,164,250,101,242,253,201,101,150, 95, 33, 22,104, - 1, 91,111,230,241, 37, 21,104,170, 58, 78, 23,195, 96,232,119,189,139,100,174,123,209, 53, 85, 82, 74, 60, 77,217,200,103,195, - 70,167,125,111, 77,238,156, 93, 79,113, 83,205, 22,179,130, 73,131,147,228, 9,130,125, 24, 68,136,220,244, 38, 43,235,245, 59, - 59,119,251,193,208,179, 93,139, 3, 24, 7,239,214, 35,129, 59, 91, 23,197,110,180,135, 55,161,204, 47, 64,105,179,246,188,225, -135,239,127,252,211,175, 15,119, 6,147,148, 91,178,133,112,117,234,173, 10, 77,109, 41,243,221,131, 15,206,226,169, 94,228,235, - 88, 46, 50,165,162, 44,180,238, 17,146, 6,139,198,170,210, 3, 85,173,173,160, 87, 45, 2,121,146,161,106, 67,108, 67, 79, 49, - 58,136,110,156,132,178, 41,180, 46,168, 54, 14, 21,218,175, 90,203, 56,234,213, 10,170, 30, 59,142,122,183,214, 84,183,247,202, - 42,119,108,215, 22,185,242,151, 34,210, 91, 35,199, 45,176,191,254, 44,244,104,241, 63,155, 39,252,226, 95, 1,152,186,150,221, -166,129, 40, 58,158,216,206,251,209, 66, 31,160,166,144,166, 8, 74,161, 84,165, 84,128,144, 16, 18, 18, 98,193,215,192,158,111, - 96,219, 37, 18,252, 6, 98,129, 0, 33,186,131,150,151,196, 43,144, 38,196,105, 18,191,234,177, 61,220, 51,227, 10, 22,149,170, - 74,141, 29,251,206,157, 59,247,156,123,206, 81,127, 70,149,108, 10, 19,209,222,234,101,112,242, 18,176,178, 0,103,197, 98,236, - 30, 72,157, 74, 17,197,162, 57,187, 52,156, 56,218, 75,158,101,237,150, 12,201,213, 96,163,158, 5, 0,201, 18,134, 57,244,100, - 35,103,242,231, 82,107,131, 94, 82,163, 84,215,240,148,128,189, 78, 4, 29, 6,116, 75, 34,138,227,111,131,111, 2, 18,193, 74, -245, 87,106, 25, 54, 68,162,118,151,162, 63, 0,173,146, 9, 21, 95,104,198,168,172,191,218, 92, 31, 7, 35,186, 86,165, 88,107, - 78, 53,251,147, 30,157,146,246, 71,189,254,164,175,142,183,244,230,228,181,179, 55,122,195, 46, 69,140,197,243,148, 14,168, 70, -147, 74,226,198,228,102,163, 6, 70, 32,157,220,105,111,207,155,246,196,159, 44,204,182,194,195, 16,251, 74,170,188, 87, 12,118, -243,226,237,217,250,204,143,193,119, 74,250,116,243, 2,172, 24, 0, 42,166,109,135, 18,189,254,128, 10,244, 84,107, 73, 51,136, - 55,176,212,178,204,233,210,148, 43,124, 63, 9,212, 40, 68,170,236,149, 57, 45, 34,202,187,181, 82,213,224,214,206,215, 55,148, -124, 63,237,127,180, 11,249, 90,185,190,214, 90,163,231,121,230,212,217, 92,129,159,107,175, 72,102,246,157, 46,231,232, 75, 22, -243,182, 51,241, 1, 41, 42,135, 74,197,125,151,154, 5, 79,193, 31, 28,138,230, 84, 77, 57, 74, 43,113,102,105,248, 34, 55,160, - 31,136,208, 26, 22, 54,112,105,153,105, 41, 79,107, 13,214,122,237,153,115, 65,228,195,135, 58,213, 99,244, 72,250,154, 4, 75, -139, 36,211,241, 87, 35, 96, 84,216, 1, 61,150, 73,115,166,181,243,249, 53, 50, 23,207, 21,236, 82, 12, 20, 8,170, 44,180, 20, -195,228,240, 68,125,126,174,113,114,132, 73,174,148,110, 2,250,174,197, 26,165,236,205,165,173,189,206,238, 70,251,234,196,167, -106, 52,206, 25, 48,107,164,189,109,101, 97,181, 51,128, 45,151, 9, 20, 4, 30,155,232,174, 67, 36, 15,117, 95,181,220, 64, 31, -132,115, 42,220, 92,207,123,254,226, 25, 93,215,131, 56, 29,122, 8, 32,101,114, 67,131,151,182,105, 25, 74, 89,151,254,151,146, - 35, 60,132, 37, 91,156, 89, 92, 93,188,208, 31,247, 48,234,141, 10,215, 70,186,194,196, 19, 45, 63,227,210,210,101, 47,244,195, -200,227,202, 28, 58, 18,130,190,197,218,233,245,253,131, 95,148,229,168,200,105, 20,107,110,224,106,218,189, 82,111, 85,170,223, -161, 79,149, 38,154,236,177,160,156, 24,198,129,169, 42, 39,250,204,233,114,157,118,116, 58,252, 81,213, 15,150, 48,167, 71,102, - 22,193, 70,147,202, 7, 28, 87,161,120,160,223,143, 87,166, 87, 22,206, 15, 92,135,206,196,245, 66,173,154,175,140,129, 94, 36, -186,105,147, 83, 75,137,194, 27, 35, 90, 6, 87, 98,124,128,254,128,117,231, 76,166,193, 55,109, 58, 33,229,213, 51,215, 21,207, -199,166,109,218, 2, 33,158, 69,145,184, 82,169,178,229, 99, 72, 0, 96, 26, 21,153,227, 48, 55,160,228,158,134,161, 81, 40, 91, -179, 77,192,130,176, 55,147,225,168, 7,104, 8,253,119, 12,201, 2,217, 64,239, 9,238,174,104,187, 91, 28,138, 96, 38, 45,123, -143,121, 99, 36,235, 98,137, 81,244,252,175,106,149,101,147,244,191,154, 61, 57, 2, 84, 5,147, 3,246,101,151,125,250,192, 18, -159,237,230,223,188,141,251,177, 79, 31, 15,141, 70,213,149, 85, 78, 26,217, 80,180, 23,249,180,213, 37, 90, 27, 26,132, 35, 8, -180,101,216, 59, 71,221,163,197, 9, 14, 92,138,174,228,222,214,221,119, 63,222,183,230,218, 94,128, 57,149,237,135, 79, 59,191, -191,190,218,123,233,139,112,228, 58,221,131,110,231,207,247,129,231,140,189, 49,135,147,132,216, 31,118,161,246,154,130,230, 65, - 33,148, 3,207,170, 66, 57,225,198,173, 59,247,183, 31, 60,121,244,120,126,122,190, 51,248, 69, 95,236,242,242,230, 79,136,199, -197, 74, 45, 24,245,202,208, 27, 10, 52, 90,235,244, 22, 34,133, 56,130,127,130, 54,157, 73,183, 63, 87,135, 39,129,208,186, 96, - 70,214,103,159,170, 28, 59, 20,161,169,203,100, 40, 98,225, 36, 10,241, 97,184, 51,134, 22,248,126, 76, 67, 8, 50,205, 68, 35, -245, 89, 74,121, 61,254,211,235, 85,163,154, 73,172,164, 82, 83, 41, 64,238,210, 13,160,244,200,187,248, 8,136,204, 20, 50,180, -233, 47,207,136,203,149, 66, 85,141, 6,131,172,249, 87, 0,166,174,101,183,105, 32,138,142, 29,231,225,184, 73,156, 54, 9, 21, - 40, 52, 17, 80,136,160,188, 4, 82, 17,170, 88,176,101, 1, 95,192, 15, 32, 62,131, 37, 31,193,146, 63, 96, 5, 59, 22,172, 64, -168, 1,245, 69, 66,161, 78,168, 29,146, 56,142,199, 79,238,153, 73, 42,150, 81,163,218,153,153,123,230, 62,207, 57,195,119, 77, -112, 82, 23,165, 32,159,148,139, 92,106, 80, 33,219, 31, 11, 97, 17, 76,112,136,107, 99,228,218,132, 0,203, 14,157,116,201, 85, -137,191,209,225, 38,255,119,107,227, 54, 20, 91, 2,126,189,117,179, 81, 65,222,131,254,225,137,243, 43, 2,169,147,159,198, 8, -121,144, 77, 43,154,232,151, 32,127, 57, 8, 22,165,134,255,154,251,171,197, 53, 32, 14,108,141, 0, 19, 68,196, 20, 91,133,232, -117, 73,165,168,166,146,102, 78, 39, 22,237, 95, 85,176,190, 89, 99,139,236,220, 92,169,105, 11, 26, 31, 89,249, 70,170, 46, 76, - 99,193,213, 23, 19,136,211,145, 50, 13,179,164,155, 51, 62, 41,229,202, 46,199,152,131,174, 21, 30, 92,123,184,111,237, 61,190, -245,248,219,113,215, 67, 71, 96, 74,190,124,217,168,238,246,191,246,237, 94,197, 88,149,114,219,117,115,221,241, 29,224, 66,243, -230,151,225,238, 32, 30, 57,170,231,169,115, 59,153, 56,161, 59,139, 60, 13, 6,153,246,157, 99, 29,137,112,168,187,145,137, 26, -121,163,179,222,177, 92,139,214,155, 54,128,222,132, 39,225, 52,240,200, 55,124,182,253, 52, 82,194,189,225,145, 23,251,149,178, -169, 23,140,238, 97,119,231,222,206,249,246,165, 94,255,251,170,153,230,114, 44, 84,253, 88, 17,221, 84,226,134,150, 50, 98, 97, -156, 4, 60, 13,230, 97, 93, 47,145,255,149,207,130, 25, 61,147,128,122,204, 75, 34,180, 88,160, 36, 72, 6, 75,239, 64, 54,155, - 76,108,242,225, 51,246,248,143, 23,204, 64,146,158, 45, 68, 81,172,193,219, 85, 86, 75,146,192, 7,213, 68,169, 4,134, 4, 23, -200,253, 21, 90,153,193,248, 36,131,177,100, 77,214,198, 49,159,188, 24, 62,194, 62,145, 67,100,187, 67,220, 67,133, 21,218,136, - 57,159,211,105,166, 61,221,190,182,189,219,251,218,172,183,134, 99, 11,227, 17,105,124,239,242,253,195,223,123,228, 44,147,113, -134,162,167,184, 81, 89,199, 73, 99,104, 43,164,243, 94,210, 43,244,160, 5,107, 69, 28,147, 53,202,168, 13,140,240,228, 80, 75, -230,107,224,161, 40,161, 96, 4, 47,127,229, 66, 39,138, 56,121, 21,175,158,191,254,126,220, 29,207,198,135, 39,135, 92, 72,232, -145, 5, 18,250, 19,132,249, 28,158,215, 86,235, 78,127,216, 3, 15, 40, 65,185,146,217,218,184,209, 27, 30,132, 9,121, 47, 20, -110,250,232,135,203, 25, 20, 66, 81, 92,184,148, 20,150,211, 35,216, 64,242,253, 41,168,162, 15, 77, 72,143,205, 64, 69, 32,100, - 76,232,182,128, 16,143,176, 3, 25,196, 8,228, 74, 95, 60,121,121, 52,232, 7, 17,146, 93, 20,254,238,116, 30,217, 19, 7, 21, -102,166,153, 43,149,159,118,111, 6, 82, 45, 73, 44,151,145, 98, 38,180,158,205,213,139, 30, 66, 1, 38,200,121,132,226,156,160, -158, 84,165,134,167,162,108,212, 90, 19,239,175, 53,250, 61, 7, 21, 4,129, 59, 22, 35,175,101,167, 73,224, 30,216,157,205, 58, -171, 27, 0,143, 57,103,163, 41,240,157,243,148, 7,140,162,195,242, 26,126, 23,208,221,227, 66, 99, 22, 52,174,170, 42,241, 61, -135, 78, 26, 13, 73,246,172,186,204,185,171, 72,203,196, 1,115, 71,204,117,208, 3, 67,103, 57,151, 95,230,100,206,202,167, 18, -229, 37,220,251, 44, 61,101,214, 62,219,237,178,129,133,158,106, 87,115,222,235, 31, 28,167, 32,238, 67,201,155, 46,244,198,229, -117,133,161,124, 65, 54, 40,238, 47,193, 78, 47, 73, 94, 41,144,242, 56, 47, 22,138,180,212, 66,129, 15,182, 76,151,113,183,255, -141,190, 64,184, 33,170, 59,211,183,239,222,252,176,126, 20, 33,155,172,110,158,223,244, 67,174,231,244, 86,163, 53,153, 79,174, - 94,216,164, 61, 93, 51,106,110,224, 6, 96, 82,226, 12,227,102,250,216,251, 11,150, 45,103, 84,210,171,159, 63,126, 58, 62,237, -209, 51,107, 43,141,163,225, 17,221, 43,173,115,237,118,173, 13,117, 61, 69,169, 26, 85,215,119, 35,201,107,178,108,121,161,151, -187,221,190,235,205,103,127,166, 3,176, 33, 9, 47,252, 76, 47, 61,155,201,161,139, 47, 17,212,169,106,166, 92, 48, 35, 49,175, - 32, 82, 46,197,139,141,141,177, 7,190, 88, 58, 34,157,230,117,182,240, 95, 83,122,144, 47, 84,237,196,104,137,100, 76,148,254, -191, 68, 95, 89, 68,100, 11,202, 84, 38, 84,251, 82, 41,139,141, 79,245, 82, 13,178, 1, 75, 10,121, 76, 41,229, 81,184, 14,196, -204,221, 63, 1,120, 58,151,222, 38,174, 40,142,207,120,222,143,140, 61,198, 15,220, 36, 78, 0,131, 40, 68, 74, 40,233, 38,176, - 4, 85,173,212, 86, 85,213, 5, 59,250, 21,186,235, 87, 97, 5,203, 74, 5,193,162, 69,162, 32, 4, 98,209,138,240, 16,160,138, -146, 56,224, 70,121,186, 78,108,103,198,177,227,121,244,127,206,117,216, 57, 94, 68,215,115,207, 61,247,252,207,156,243, 59,178, - 69, 47, 15,241, 0, 53,132,180,182,230, 12,168,146,142,206,155,107,102, 67,106,218, 28, 13,198,214, 84,163, 90,168,133,131, 14, -247,235, 71,169,232,168, 26, 97,240, 25, 2, 66,225,176, 44, 70,141,208,116,218,152, 2,111,108, 87,193, 43,117,123, 59,216,200, - 49,211,135,213,246,162, 96,166,250,217,235,247,207,196,216, 99,238,122,133,106,118,250,132,184,201, 8,242,176, 60, 2, 9, 36, -146,104, 90,225,216,210,210,168, 35,220, 49, 29, 92,233, 56, 30,204,153, 78, 29,221, 41,122, 69, 4,131,142,238,134, 81,120,110, -250,243,149,141,101,124, 3, 79,180,180,249,142,239, 79,146, 75,162,251,134,171,131,224,178, 41,135, 67,129,231, 48,132, 5,240, -241, 85,121,217, 99,176, 27, 28, 87,194, 10, 30,236,127, 90, 61,107, 27,238,171, 15, 47,225,142,109,221,222,227,120, 42,101,224, - 55,254, 73, 57, 59, 49,225,143,183,204,222,195,165,199, 8, 73,217,227,136, 81,131,137, 52, 2,243, 81,174,156,202, 77,241, 44, -201, 14, 76, 59,163,209, 27,200,193,192,200,168,167, 10,199,176,248, 97, 26,125, 51,251, 85,163,189, 6, 7,209,216,253,119,190, -118,126,225,252,194,165,159,190, 16,251,244,219,181,223,183, 26,155,191,222,191,113,188,116,208,143,210, 87,141,102,187,215, 15, -136, 63, 41,176,198,196, 18,160,202,130, 4,167,120,255,226,116,197,181, 13,248,129,193, 1,229, 4,178,174,181,210,239, 15,225, -187,105, 22, 43, 37,220, 97,117,182,154,234,225,196,106,247,131, 68, 57, 55,218,192,169,226,137,229,245,183, 34,124,240, 76, 31, - 7,227,117,227,165,152, 34,161,168, 90,193, 59,186, 27,108,199,113, 12,197,147,115,243,120,230,220,245,147, 32,216,255,126,225, -135, 59,127,221,130,181, 16, 2,151, 83,249, 89,215, 31,247,171,111, 86, 95, 40,204,191, 82,101,213, 52,236, 78,184, 51,126,100, -170,236,151, 94,212, 23, 33,251, 39, 75, 83,239,183,235, 80, 48,134,110,230,189,210, 17,215, 95,172, 63, 53, 53, 85, 36,129,152, -251, 16,215, 42,167,151, 55,222,137,160, 6,207, 31,122,156, 56, 45, 81,255,187,133, 43,191, 60,186,254,229,252,183,143,223,220, -135, 22,132, 94, 70, 76,100,168, 22, 67,110, 18,147, 91,154, 53, 69,155, 59, 54, 15,123,153, 61, 62,247,224,249, 31, 51,211, 51, - 79,254,126, 66, 51, 8,228,184,228,149,119,130, 22, 60,187,165,185, 16, 46, 30,219, 54, 68, 12,226,110,162, 0,166, 82, 48,232, - 50,202,144, 65, 60,212,104,150,112,226,149,156, 44, 33,163,211, 4,247, 68,135,185, 37,130, 33, 92,206,150,119,122,187,220,190, - 20, 49, 76, 68,177, 85, 27,151, 14,252, 21,150,221,108,175,121, 86, 14, 46, 56, 71, 9,156, 24, 49,184,202,136,176,172, 69,204, -181, 74,238,104,179,211,172, 22,170,141,102, 67, 85,148,176, 31,178,106, 39, 36, 53,214, 25, 30,236,205, 85,103,219,251, 93, 92, - 84, 91,221,173,136, 32,204, 42,214,217,234,182,176, 58,242,199, 4, 67,198,237, 34,235,154,108,106, 4,206,119, 73,195,103, 46, -158,253,186,216,252,243,194,207,151,165,162, 45,117, 2,105,179, 41, 53,219, 82,123, 47,234, 6,177, 57,102, 76,158, 97, 4,153, - 28,172,254, 19,174,175, 40, 60, 96, 73, 33, 31,158,209, 84,162,255, 51,195, 93,163,248, 93,215,216,197,243, 55,172,151, 40,231, -131, 63, 45, 71,202,251, 82, 33, 47,249, 57,250,156, 49, 15,251,155, 34, 41, 25, 72, 65, 71,250,175, 37,181,218, 84,183, 19, 69, - 98, 12, 68,122,219,188,249,182, 59, 80,169, 96, 60, 30,245, 28, 70,124, 72,136,198, 5,211,201,218, 89,252,244,245, 54,105,235, - 33, 95,144, 56,171, 8,216,161,182, 38, 11,213,181,214, 42, 12,213,177, 28, 60, 29, 28,226, 33, 77,231, 8,248, 62,137, 15, 89, - 46,202,143,151,175,222, 93,188,231,123,121,216, 82,173,114,178,190, 81,231, 20, 66,172, 27, 54,118, 18,183,117,204,112, 8,102, -126, 83,242,199,181,115,216, 35, 74, 69, 18,221, 54, 30,115, 33,220,183, 41,227,192,181,236, 2,154,132,231, 12, 1, 89,114, 43, -187,253, 14,171, 82,241,142,137,204, 84, 64,178,169,121,141,232, 26,212,145, 68,232, 8,238, 14,129, 9, 67, 43,200,212, 44,217, -203,200,135,153,249, 36,169,125,114,186,190,185,244,241,205, 41,205,215,225,153,124, 17,165,113,100,146, 10, 36, 91, 18,158, 47, -148,240, 0,155,143,158,149,194,117, 67, 51, 82, 30,254, 71,181, 27,105, 4,247,165,103,104,162, 39,162, 49, 46,106, 23, 27, 32, -216, 75, 92, 66, 44,170,144, 14,171, 75,254, 23,128,169,171,233,113,155,138,162,207,118,236, 73, 50,147,169, 67,154,143, 78, 51, - 73,153, 1, 81, 80,171, 82,129, 16,234,134, 5,236,134, 13, 98,199, 95,232,239, 67, 66, 72, 84,106, 23,172, 16, 21, 51,162, 85, -129,142,210,137,243, 49,137, 19,219,177,227,239,216,220,115,237, 65, 72,179,138, 38, 31,239,249,221,247,206,185,239,222,115, 74, -252,206,130,192, 16,196, 33, 88,138, 72,203,119, 1,228,156, 82,230,167, 56,162,226, 44, 93,185, 11,162,141, 53,173,206,151, 12, -255, 83,187, 87,160,154, 84,211,170,232, 17,151, 37, 22,239,149,245,253,230,131,193,163,153, 53,237, 53,143,232,108,128,215,101, - 26,108, 1, 27,179,165, 53,227,154,210,178,157,165,148, 52,230, 19,252,191,194, 35, 26,102, 99, 79,167,233, 81,113, 86, 71, 68, - 46,224,219, 39, 67, 52, 24,110, 80,172,169,122, 88,215,189,173,211,111, 15, 93,223,102, 81,242,124, 97, 95, 19, 18,167,184,245, -160, 12, 87, 42,135,220,110,180, 63, 61,249,204,143,130, 4, 86,244, 96,205, 57,107,177,118,110,117, 30,159,126,113,121,253, 55, -219,168,226,234,140, 34,159, 86, 17, 5, 11, 33,104,250, 49, 65, 26,194,112, 89, 72,133, 36, 50, 17,234, 12,202,245,114, 38, 11, - 63,113, 70,249,165, 17, 27,135,245,250,126, 77,227,108,175,132,128, 0,209,102,165, 84, 73, 99,108, 69,155,109, 37, 87, 17, 54, -177,148,250,187, 32,202, 19, 63,246,198,182, 49,182, 38,147,245,236,217,219, 95, 47,230,127, 93,174, 71,116,172, 94,217,198, 38, -116,166,231,198,171, 23, 23,123, 52,238,141,250,106,244,231, 59,211, 80,115,249,195,110,117,234, 58,180,186,144,156, 86,216, 86, -134, 45, 32,138, 42,114, 26,227,160, 81,239,213,106,132,239,181, 84,168,137, 80,133,100,135,169, 21,196,174, 31, 67,125,141,198, - 22, 38, 7,185,114,237,109, 10,224,207, 88,105,103,109, 33, 91,127, 71,239,123,129, 67,255,178,112,103,123,184,185,130,243, 49, - 55,106,163,211, 16,224,118, 23,219,222,154, 14, 39, 58,134,233, 17, 60, 28, 60,254,229,226,167,246, 65,175, 84, 5,128, 8, 16, -130, 3,174,214,117,189,219, 60, 98, 21, 1,120,210, 19,164,154,172,141,249,122,138,185,145,101,218,238,251,239, 13,118,136,174, -173,229, 66,157,113, 27,123, 68,136, 43, 10,244,233, 14,107, 77,122,197,246,215,180, 14, 32,225,128,242, 0, 46, 61,202,176, 63, - 78, 87,227, 77,232, 62,188,247,136,160, 43,205,106, 91,239,210, 97, 71, 76,145, 88,209,247, 79,126,184, 90,142, 52, 78,143,152, -206, 98,188,184,210, 20,184,249,152,206,202,245, 55, 79,207,158, 62, 63,127,190,163, 51, 22,125,155,210,105,239,116, 97, 79, 63, - 25, 62,248,250,171,111,206, 95,255, 65, 1, 63,104, 15,233, 71, 10,248,226,222, 42, 68,144, 42, 44,143,122,210,125,159, 98, 91, -223,111,133, 81,112,246,249,183, 10, 42, 95,163,219, 7, 45,244,196,101, 9,109,211,119,155,119, 29, 52, 61, 33,225,205,141, 42, - 89, 16,194,181,150,120, 9,124,221,165,188, 81,109, 4, 73,116,220, 58,118,139, 42, 79, 5, 82, 75,117,173, 26,224,214,216,183, - 3,155,102,251, 94,119,184,114, 77,133,137,186, 42, 85, 2,126, 92, 51,107, 62,181, 38, 26,179, 64,220,232,196, 33,173,106,232, - 28, 68, 94,171,209, 78,160,196, 80,106,224, 43,220,162, 84,211, 26,114, 22,153,155,145,153, 68,119,222,184,205, 39, 67,132,188, -181, 21, 27,159,240,123,130,247,251, 10,193,163,138, 26,175, 22,222,252, 31,214, 17,225, 26, 59,118,166,174, 48,219, 69,146,189, - 16,112,215,248,175, 34,151,187, 60, 17, 64,108,244, 20,159,137,216,110,133,101, 9,115, 9,120,190,156,136,229, 84, 44, 12, 49, - 55,196,248,157,152,205,133,227,138, 56, 42,197,199,104, 75,253, 89,251,241,220, 87,235,149,211,131,214,190,162,234,106,245,254, -209,253,181,183, 78,185,107,145,150,223,160,221,167,145,110,184,129,238,198,129, 23,224,158,102,239,187, 47,207,126,123,251, 50, -193, 77, 53,209,143,136,192,175, 5,109,247,168,236,146,206,196,199,199, 31, 93, 59, 75, 10,204,223, 47, 95, 46,157, 57, 65,123, - 38,236, 40, 18, 33, 96, 10,117, 13, 41, 11,147,176,163,119,130,208, 39, 84,190,114,204,147,222, 7, 65,228, 15, 59, 67,211, 49, -137, 25,208,148,210,119, 82,124,208,135,167,220,214,192,250, 31,196,122, 97, 35,234, 5,158, 75, 65, 17, 71,226,102,235,204, 10, -227, 51,174,132,161, 7,135,173,185,176, 67,224,166,135,226,134,144,208, 92,209,229, 7, 90, 6,255, 82,192,110,199,183,224,132, -161,224, 14,155,243,142,200,135,241,180,171, 85,181,138,108, 7,225,191, 66, 16, 58,191,241,219, 45, 43, 12,101, 38, 61,184,126, -208,160,150, 1,156,122,164,247, 77,119, 73,171, 93,211,106, 49, 26,247,164, 2,115,148,178,195, 55,217,247, 34, 83, 68, 47,253, - 43, 0, 77,215,210,218, 68, 24, 69,103,146, 73,102,166, 73,154, 52,237,180,241,217, 90, 31,104,209,138,182, 98,197,199, 82, 92, -232, 78,244, 71, 8,254, 20, 23,254, 1, 17,220, 42, 72,193, 74, 65, 16,220,169, 84, 67, 45, 72,209,182, 65,211,152, 38, 77, 39, -153,204, 43,243,136,231,222,111, 10,217, 4,194,132,153,185,223,125,158,123,206, 33,126,102, 40, 52,233,233,114,172, 66,226, 79, - 21,166,230,167, 23, 26,157,186, 36,224, 59,169, 68,111,214, 9,237,132,228, 42,225,180,161,242, 5, 49, 47, 35,103, 7,177,207, -101, 31, 87,129,129,215, 48,235, 98, 10,102, 58, 7,182,107,193, 5, 20,114,163, 48,127, 30, 42, 19,203,144,145,159,204,102,116, - 46, 72, 99,209,218, 23, 45, 26,214, 90, 35,152, 57,142,193,189,171, 15,182, 16,253,184,247, 7, 83,198,125,162, 52, 30,146, 54, - 47,114,127,255,220,209,243,219,205, 95,212, 5, 75,137,174,172,160,103, 34,222,109,102, 2, 34,109, 15,188,251, 70,103,215,246, -122,130,148,158, 84,168, 50, 90, 24, 7, 77,179,209, 52, 73, 20, 70,180, 60,202,196, 3,236,150,115,134,237,117,253,192,117, 17, -141,252,126,200, 11,210, 36,110, 17, 5, 94,236, 69,130,128,152,206,134,220,215,144,130, 51, 35,183, 88,102,227, 57, 65, 74,192, -187,197,178,136, 24,170,146, 66, 16, 45,166, 49,240, 71,161, 61, 33,114,247,170,164,107, 4, 78,200,164,241, 19, 59,114, 90,254, - 65,221,106,124,217,169, 46,175,189, 95, 94, 91,121,177,252,106,181,186, 82,221,169,186,129, 77,115,213,161, 95,239,218, 50,243, -146, 43, 25, 28, 0,158,120,193, 35, 40, 44, 94, 30, 75, 89, 41,117,249,184, 49, 99, 20,141,113, 36,115, 8,239,202,184,138,240, -136,171,135,163, 48,179, 1,109, 65,247, 41,181, 87, 35,102, 71,147, 19,152, 21, 44, 85,211, 24, 51,131,154, 70, 44, 55,139,252, - 97,218,152,237,186,102, 24,210,210, 16, 28, 58, 92,127,165,120,180,109,183, 17, 71,247,237, 22, 35, 64, 82, 99,249, 49,155,200, -220,229, 4, 24, 71, 88,251,176,160,229, 81,235,224, 1,226, 9,239,117,155, 52,123, 79,192, 78,212, 58,116, 6, 14,203,168,146, - 21,227,180,215, 90, 59, 55,230,238,184,196,229,233, 60,188,245,240,219,214, 87, 45,147,227,148,153, 6, 54,188,136,143,226, 82, - 42, 21,198, 81, 83,247, 29,107,163,182, 14,135,142,183,223,195,153,145, 83,186, 66, 37, 66,173,185, 61,136, 8,110,120,164,124, -252,201,253,167, 11,119, 23,191,127,254, 54, 64, 74, 22, 6,112,184, 87,238, 47,238,254,220,245, 3,167, 88, 16,187, 48, 38,238, -255,212,228,236,219,143,175,241, 66,166,167, 78, 35,116,225, 69, 95, 59,115,125,223,106,177,162,108, 78, 75,171,112,138,136, 52, - 49,175,248,193, 26, 97, 39, 45, 22,171, 34, 63,194,189,146,146, 62,102,249, 93,121, 40, 11,153,179, 74,169,114,241,196, 60,114, -154,158,211,211,179, 42, 27, 4,101,236,249,172,190,215,221,155, 49,102,104,249, 37,142, 74,185, 18,141,235, 89, 63,137,182,246, - 6,110,219,218,231,205,172,145, 20, 75, 11,113, 29,169,223,186,112,179,113,208, 16,112, 64, 78,105, 67,252, 17,210, 2,158, 55, -210, 70, 55,123,118, 70,219,137,102,102, 52, 80, 85,125, 60,111,248,177,183, 99,185, 75,161, 34,205, 77, 72, 29, 75,178,250,146, - 71,228, 8, 3,207,117,205,150,211,110, 56,157, 58, 9,201,202, 98,194,119,168,114, 75,151, 99, 4,164,194,254,157, 62, 44,217, - 65, 94, 62,147, 80,254, 50, 60,147,239,137,233,193, 80, 17,194,247,121,158,228,249, 52,194, 13,121, 19,121,200,236,182,105, 94, -181,248, 84,144, 59, 23,163, 98,225,229,247,119,207,215, 63, 60,171,174,190,169,109,252,104,254, 62, 63, 90, 41,169, 57, 63, 70, - 25, 26,247,136,195, 46,228, 5,147, 33,203, 65, 14, 43, 99, 71, 96, 60,184,235,127,230,158,217, 55,231, 78, 94, 66, 46, 76,211, - 84, 86,239, 66,154, 72,174,144,207, 35,158, 85,121,164,140,212,194,243,188, 71,183, 31,255,109,255, 69, 44,135, 21, 45,157, 93, -154, 42, 79,214, 90,127,136,112, 62, 12, 28,215, 62,102,156,216,220,221, 52,138, 19, 77,147, 58, 42,125,175, 15,123, 19, 92,140, - 18,139,214, 32,240, 19,253, 3,117, 18, 34, 61,163,195,113,249,204, 29,116, 40,209,116,216, 44, 30,198, 66,164,134,248,113,105, -210, 67,168,247,188,158,143,121,225,153,201,124,184,153, 38, 37,205, 12,122, 90, 52,124, 68, 66,152, 86,216,161,115, 71, 90, 81, - 24, 76, 35,190,198, 44,126,144, 22,184, 22,142, 17,236, 80,185, 25,195, 21,237,136,170, 9,160, 29,179,151,208,108,181,231,246, - 16, 28,131,200,247, 19, 4,179,128,242, 36,126, 29,199, 10,102,128,180, 73, 78, 49,224, 91,146,254, 11,192,211,181,244, 54,113, - 70,209,177, 61,227,177, 61,227,137, 51,113, 66, 18, 59, 33,180, 38, 64, 27, 96, 1, 8,209, 69,133,120,108,187,105, 89,177, 9, -191,134,127,208,127,208, 93, 85,169,221,244, 23, 84,168,106, 21, 85, 77, 91, 90,136, 16,113,130,157, 24,219,243,126,120, 30,158, -222,115, 63,131,228, 85,236,248, 49,115,239,253,238,227,220,115, 4,126,166, 36,186, 63, 2, 44,136,147, 13,156, 12,179,137, 63, -142, 65,180,141, 15,107,214, 76,242, 34, 10, 81, 87, 54,175,223,249,244,206,209,217, 43, 70,148,163, 26, 96, 33, 41, 44,155, 49, - 75, 12,200,129,121,138, 34,173,183, 54, 88,191, 41, 96, 78, 36,132,221,132,181, 50, 4,147,113, 1,240, 89,195,139, 93, 25, 52, -249,216,120,204, 88, 31,131,254, 61, 73,163, 26, 31,170,100,206,166,214, 62,157,190,173, 48,155, 94,190, 16,139, 78, 69,241, 3, - 6, 78,186,133, 73, 44,139, 82, 4,113, 22, 53,150, 86,173, 3,255, 46,232,179,138,162, 81,215,233, 7,164,120,166,208,235, 6, -253, 21,155,129,176,103,153,106, 97, 70, 43,161,147, 56, 3,174,142,234,131, 40,227,169,170,144, 45,226, 54, 44,174,109,199,220, - 94,210, 90,222,204,226, 29,196, 82, 42, 23, 88,228,159, 87,120, 14, 73,133, 30,133, 54, 28,114, 20,139,139, 76, 48,224, 23,224, - 4,228,101, 72,177,147,204,106, 86,101, 40,156,226, 6,151, 22, 51, 22,152,140,112, 52,212,192,144,109,200,149,249,188,156, 36, -146, 19, 5, 86,224, 14, 93,251,141, 55,254,227,108, 52,240, 2, 59, 73,173,217,204, 73,178, 32,161,220,132, 30,168, 67,233,149, -210,188,100,133,137, 27, 37,178,218,252,253, 36,248,119,234,244,125,255, 52,136,198, 81,220, 49,174, 13, 66,200,155,125,185,251, -184, 82, 82, 71,225, 80, 41, 55, 4,210, 9,196,145,204,227, 50, 75, 3, 64, 31, 10,244, 1,200,145, 90,250, 10, 0, 12,209,148, -215, 64,180, 52,203,206, 28,138, 53,160, 75,219, 93,191,138,192, 45,229, 77,181, 25, 1,131,161,136,210,135, 87, 48,208, 91,227, -182,105, 72,247,244,230,206,173,219,189,187, 47,251,127,105, 53, 3, 29,253,178, 76,206,147, 64, 75,179, 74, 49,136,145, 26,234, -155,243, 87,148,236,255,115,242, 39,165,243,148, 38,255,118,244, 43, 93,148, 85, 99,237,233,131,125,242,134,222,250, 46,160, 50, -177,141,128, 91,173,187,129,189,255,213,126,255,236,152,206, 99,224, 70, 42, 42, 61,168,222,234, 46,119,111,239,222, 61,159,158, -147,245, 83,128,126,241,247, 47, 86,127,162,200,178,217, 92,177, 3,251,193,253, 71, 63,124,247,189,174, 25,189,238,229, 43,155, - 61,203,157,108,183, 47, 57,177, 59,152,244,233,135,127,243,197,147,145, 61, 26,217, 67,144,149, 94,186,177,183,179,247,242,221, -127,126,226,197,204,192, 81, 85, 26,116,114,146,145,212,149, 26,172, 34,205,186, 43, 59,144, 3,193,249,132,145, 67,206,151,144, -236,136,210, 5, 63, 10, 78,198,199,150, 55, 98, 30,214, 68, 90,180,101, 1,159,165,200, 2,195, 40, 50,178,240,182,209, 38,171, -190,190,189, 71,102,252,248,198,163, 38,172, 17,117,207,179,135,207, 14,143, 15,123,107,159,116,204,141,177, 75, 87,190,240, 66, - 7,172,218, 56,117, 0, 44,185,208,186,192,209,181, 2, 82,238, 60, 99, 33,160, 98,169,177, 76, 17,106,195,188, 24,165, 62,185, -167, 12, 78,161, 40, 45, 23,242, 32,216,186,183, 37,249, 1,227, 35, 99,138,238, 32,148, 6,243, 91,194,162,193,112,148,178,160, -235, 4,136,175, 36,218,255, 11,224,141,252, 97,196, 74,201,187,250, 1,255, 14,124,100,193, 47,224,150,140, 32,143, 40,125,100, - 35, 95,104, 65, 73,156,104, 32,125, 57, 88,237, 31, 84,191, 61,252,249,235, 31,159, 31,188,127,235,132, 65, 91,169,191,143,166, - 71,246,233, 79,195, 35,163,166,247,244, 54, 57, 87,204,189, 89,209,112, 23,196,174, 78,232,177,223,101, 97, 2, 64,157,229, 79, -187,171,157,137,107, 69, 89,210,210, 12,202, 39, 38,254, 84,164,154,110,232,213, 85,232, 73, 80,248,123, 61,120,221, 80, 41, 77, -196,200,135, 2, 55, 29,198,168,254,107,205,173,181, 29,214, 83,243,175,110, 94,163,119,160, 42,191, 4,114,148, 84, 8,249,210, -183,133, 2, 33,184, 17,213,100,158,127,182,245,249,185, 51, 36,243,195,100,155,251, 10, 24, 56,169,106,202, 39,186, 16,167, 3, -138,102, 14, 89,224,156,151, 11,153,141, 35,231, 62, 51, 93,157, 50,125, 7,208, 41, 86,170,166,102,154,250,114,138,245, 64,222, -216,131,191, 51,228, 15,141, 46,232, 88,154,186, 73,102,176,210,108, 23,210, 98, 61, 91, 96, 44,121,120, 83,112,177, 43,233,170, -214,168,130,147,191,179,188, 65,111, 64,213, 94,133, 43, 54,186, 99,138,172, 24,245, 37, 58,135,218, 75,235, 64, 76, 22, 41,152, -218, 20, 64, 39, 85, 69,141,243,136,155,210,115, 49,129,253, 95, 0,166,174,165,183,141, 42,140,122,124,231,101,143, 61,227,177, - 29,187,149,157, 72,233, 67, 8, 68, 35, 36,132,196, 6, 33,177, 64,149,186,175,138, 64,252, 1,246, 72,176,231, 31,240, 71,186, -100,195,170, 45,168, 42, 72, 8,137,166,109, 2, 21, 73,112,130,243,168, 61,158,151,237,241,112,206,119,109,137, 77,148, 44,236, -220,185,247,206,247, 60,223, 57, 27,126, 2, 13,209,151, 69,175, 91,186,228, 90, 90, 15,188,210, 10, 44, 83,161, 12, 89,141,163, - 81,148, 70,179, 60, 98, 76,186, 66,136,232,192, 22,207,151,169, 36,254,172, 7,213,145,146,153, 38,110, 19,162,194, 57,156,140, - 65, 62,124, 67, 42,110, 48,112, 28,108, 33, 50,103,209,160,141, 72,179, 69, 12, 3, 87, 72,137,243,122, 56,208,164, 66,184,217, - 53,219,131,155,245,107,254,201,229,209,114,195, 89,136,199, 39, 95,246, 34,213,157, 92, 24, 92,169,255, 22,125,191,135,188,140, - 51,171,202,218,221,218,197, 3,167,121,140,163,138,178,217,205,254,173,176,222,198,145,227, 17, 91,245,246, 36,165,254,148, 83, -117, 74, 82, 36, 22,210,143,174, 12, 66, 78, 45,138,186, 54, 11, 83,134,142,111, 55, 35,201,228, 78, 64, 38,101,187,199,151, 71, -204,186,216,229, 53, 60, 95, 5, 29, 43,128, 39,177, 77,215, 85,174, 83, 69,200,226,218,100, 90,175,187,172,213,152, 2, 86, 86, -178,108, 67,190, 79,216,190, 86,107,205, 92,163, 90,209, 2,222,133, 6, 45,233, 9, 57, 46, 71,113,234, 82,201,255, 81, 50,194, - 98, 58,146, 1, 88, 50,179,168, 36, 59, 18, 45, 78,228,177,180,172,133, 65,133,111,188,193,167,113,242,250,252, 77,160, 66,219, - 96,247,208, 67, 10,105, 84,242, 50,199,234,146, 69,226, 59,173,195,241, 33,252, 2,226,148,142,215, 93,224,125, 95,201, 53,144, - 99, 47, 68, 43,252,157,225,157,209, 20,241, 93,217,109,118,113,220,184, 94, 8,183, 75,241,165, 8, 88, 62,251,232,203,195,179, -131,243,232,188, 20,194, 44, 44, 6, 78, 2, 55, 4, 59,179, 34, 68,157, 72, 21, 98,135,200, 99,182,192,126,142, 46,142,216, 66, - 20,101, 21,223, 11,194,102,123,203,239, 15,187, 59, 12,243, 17, 51, 45, 51,199,106,124,112,251,195, 36, 79,187,205,142,235,212, -242,121, 70, 16,116, 62,251,121,255,209,241,248,111, 36,242,167, 87, 39,120, 35, 8,177, 16,238,160,103,251, 79,115,145, 77, 16, -157,144, 66, 52,126,157,150,215, 61, 26,255,137, 47,220,237,221,188,255,201,131,192, 13,226,121,124, 37,132,142,142, 66, 30,163, -166, 17,161,208,179,108,226,152,222,171,127, 94,126,251,197, 55,143,127,123,132,152,174,237,133,207,143,255, 64, 40,253,246,173, -119,183,251, 59, 63, 61,127,114, 48, 58, 32,156, 70,169, 45,255, 58, 59,168,156,127, 46, 61,171,129, 23, 9,238, 39, 89,206,236, - 42,213,159, 53, 65, 30, 76, 73, 80, 35,146, 74,233,204, 81,225,241, 21, 34,253,126, 56,192,142, 94,107,245,226, 52, 25,178, 50, -195,126,154,204,142,146, 39,117, 16, 14, 9,240,152,142,211, 60,123, 53,122,137,157,204, 68,143,247, 98,122, 25,103, 49, 78,119, -146, 76,122, 65,127, 26, 79, 4,241, 93,193,110,227, 14,239,116,118,206, 72, 92,204, 73,228, 65,123, 27, 70,173, 89,107, 18,230, - 47,220,168, 41,231, 96,113, 9,178,162,200, 56,134,106,170, 56, 91,190,191, 55,168,152, 75,132,240,101,146,206,231,243, 5,217, - 71,215, 93, 40, 17, 22,221,168, 70, 85, 52,150, 19, 23,142, 23, 84,195,181,105,205,181, 77,119, 76,145,223,147,114,141,210,253, -236,234,255, 32,121,107,162, 59,249,201,226,113,165,134,207,122,149, 31,234, 47,158, 46,190,223,255,241,187, 95, 31,246,172,230, -215,239,221,251,106,239,211,207,223,250,248,238,224,142, 85, 26,191, 95, 28,252,114,246,162,168, 90,123,173, 33, 13,149,105,167, - 50,109, 46,185, 53,109,253,141,107, 55,224, 44, 11, 50, 97, 24,112,204,216, 70,130,167,233, 67, 12, 88,127,100,147,182, 34,245, -180,196,182,158, 86,197,105,184,245,134,237, 33,126, 23, 81,102, 58,214,116,153,199,121, 52,158,252,139,191,122,205,222,235,241, - 95,176, 51, 88,169, 95,247,225, 0,132, 85, 38,150,145, 55,188,153,132,111,193,167,156, 77, 78,169, 45, 32, 53,106, 13, 42,135, -165, 14,235,161, 52,222,248,212,248, 29,151, 10,182,142,243,234, 90,156, 81,102,151,164, 61,206,220,130, 98,245, 85, 85,200,185, -164, 57,135,179,130, 90,232,185, 53, 68, 54, 38,211,247, 82, 9,185,150,197,100,222, 66,146,221,246, 59,211, 52, 82,236, 49,218, -122, 34,105,131,144,100, 30, 13,195,189,221,221, 62,125,115,114,133, 48, 47, 79, 45,137, 21,197,118,240, 24, 97, 24, 97, 60,147, - 60,210, 5, 76, 25,255, 91,227, 35,215,130, 33, 27,254,247,255, 4, 32,234,106,122,154,136,162,232,124,182,157,105, 25, 75, 74, -181, 45, 37, 49, 80, 32,196, 4,163, 49, 42, 42, 9,137, 27,127,129,113,165,254, 17, 99, 92,185,244, 31,248, 31, 92,155, 16, 55, -186, 34, 16, 23,106, 92,152, 54,138,148, 22,134, 97, 58,175,211,249,232,180,158,123, 95,193, 93, 67,210, 50,243,222,187,247,157, -251,117,206,229,124,211, 20,240,132, 85, 29,168, 57,137, 6, 49, 72, 30, 51,187,236,217,185, 80,187,164,139, 31, 24,205,212,114, - 82,102, 90, 42, 46,225,176, 44,215, 90,103,193,105, 99,190,233,141,188, 52,163, 70, 2,169, 12, 43, 19, 73,175,222,188,254,180, -187,171,177, 13,164,140,114,105,166,127,174,162,147,102, 27, 73,175,193,156,176,214, 49, 17,111,210,202,177,222,252,152,187, 27, -169, 75,167, 88,152,195,243, 0, 50,145,148, 26,223,122,120,195, 32, 12,100, 88, 88,159,111, 54, 42,139,158,192,221, 48,246,132, - 71,217, 55, 77,135,115, 89, 95,220, 16, 35,193,116, 46, 58,182,156,152,209,166,114, 12, 74,231,227, 62,145, 1, 14,254, 23,124, - 16,162, 30,160,123,146,134,224,106,203,132,199,172, 56,160,161,125, 26,166, 66,145, 98,155, 76, 98, 88,169, 91, 90, 78,161,237, - 2, 52, 85,103,127,134,179,140,163, 41,157,199, 81, 26, 37, 99,169,133, 70,200,141,117, 46,166,146, 13,111, 74,110, 3, 95,180, -115,134,109, 25,150,109,206, 1,160,194, 97,228,141,130,101,218,128,130, 54, 93, 24, 84,253, 50,184, 82,105, 50,251, 19, 61,176, -154,142, 85,196,214,184, 43,177,186, 9, 98,152, 12,230,173,101, 50,237,163, 25, 83, 77,199,249,235, 6,253, 35,225, 29, 5,193, -209,192, 63,241, 7, 81, 28,157, 71,126, 50, 73,143, 7,221, 76, 73,136,144, 89, 83, 99,196, 42, 56,209,234,164, 81, 94,194,123, -217,164,126,181,112,103,245,222,215,206, 62, 23,254, 73, 13, 21,241,126,194,236, 67,119, 87,238,247,252, 30, 78, 46,224, 48,238, -218, 98,190,244,124,231,229, 65,123,223,164, 9, 74,131,185,189,114,210,119, 0, 46,225, 93,225,139,137,158,124,146,193, 8,231, - 9,206, 15, 75,182, 3,216,235, 13,253,190,127, 44, 34, 30,250,229,229,192,254,118,122,191, 40,161,169, 27,216, 38,149, 28,119, - 86, 43, 55,184,138,163, 61,190,249,228,119,191,189,185,124,187,127,126,140,179, 95,117,170, 81, 28, 94,175,181,198, 60,242, 86, - 42, 56, 0,245,113, 18,250,163, 65,171,222, 10,163,200, 23,110,217, 42,227,181,168,102,206, 34, 12,176, 76,199, 40, 13,105, 12, -114,122, 46,220, 51,225,226,195,193,207, 61,119,224,194,173,215, 43,141, 83,166,204,253,219,237, 28,246, 14,111, 44,109,226, 62, -192,147,135, 81, 24,166, 68,186, 48, 81,169, 89, 62,161, 73,184, 20,251,131, 95,182,114,121, 74,100,115,171, 51,156,114,129, 10, -254, 82, 35,147, 32,139, 70,212,243, 70,154,140, 72,100,220,204,115,157, 45,102, 14, 83,226,145,103,228, 24,211,108, 29, 86, 12, -119,182, 73,119, 33,126, 41, 78, 19,203,204,227,217,176,139, 52, 5, 29,139, 81, 60,122,180,241, 16,215,143,136, 67,234,234, 97, - 51,241, 2, 87,106,206,134,145,144,210,228,196, 83, 79,205,238,154, 83,112,184,126,150,135, 69,100, 68, 28, 68,147, 51, 91,107, -215, 20,199, 80,220,129, 26,197, 70,165,142,219, 49, 37,118,226,255, 52,104, 26, 83,208, 72,162, 29,109,102,171, 76,176,175,177, -128,170,105, 40,150,174, 88, 57,197, 50, 56, 21,200,137,120,153,126, 80, 24,191,207,132,161,217,254,164,178, 74, 81, 85,198, 5, -229, 99, 57,232,214,222,183, 63,191,221,251,176,122,165,241,110,231,197,246,245, 77, 55, 14, 69,154, 32, 56,188, 85, 93, 89, 46, - 86,191,244, 59, 63,206,218,216,172, 53,231, 42,172, 50, 33, 14, 39,202,115,225,249,225,127,251,131, 83, 73,198,201, 19,136,170, - 63, 12,152,215, 65,221, 90,127,128, 19,211, 15, 78,224, 83,113, 24,224,205, 19,174,200,202,126, 42,160, 4, 41,116, 7,192,199, -148, 33,204, 95,164,235,136,189,112,122,101, 98, 89, 82,189,192,216,177, 29,205,133, 38,224, 63,246, 90,162,218,153,147, 34,117, -151, 84,146,202,169,172,213,199, 73,133,152,211, 98, 83,217,152, 79, 21, 86, 38, 82,151,163,241,154,122,225,231,201,186,179,103, -219, 79,191,255,249, 38,167, 49,121,174,158,134, 28,225, 33, 76,102, 42,204, 3,246, 98,231, 17,194,235,170, 85, 40,205,217,165, - 48,164, 62, 93,167, 88,166, 38, 87,117,198, 54, 42,123,114, 97, 5, 34, 17,196,227,196,125,189,179,114, 41,251,238,140, 51,123, -188,104, 26,187, 21,110,115,100,108, 61,145,129,197, 69,113,212,206, 21,255, 9, 64,212,181,244, 54,113,133,209,153,241,188, 60, -246,100,236,144,196,164, 65, 14, 46, 50,132,150, 5, 42, 74,211,254, 7,150,252, 17, 86, 93,117, 85,126, 13, 91,196,130, 21, 66, - 2,117,219, 69, 82,216, 32,133, 68, 81, 98,226,120, 50, 99,143,231,229, 25,115,206,119, 29,144, 34,111, 98, 89,247,249,221,243, -189,206, 89,217,119,122,232,139, 34,165,153, 91,189,206,170,118, 71, 19,109, 1,197,212,184,210, 21,103, 5, 36, 83,172, 98,196, -197,246, 11,131,182,231,120,209,252, 26,139,107,139,176, 4, 95,185, 21,207,146, 89,150,249,135,119,239,201,157,194,246, 9, 30, -116,140, 27,158,190, 80, 29,148, 34,211,195,175,165,228, 23, 51,180, 85, 54, 89, 31,244,134,211,244, 90,180, 71,168,234, 73,137, - 40,245,196, 73, 0,148, 75, 79,225, 67,109,119,243,238,201,248, 11,217,130,216, 7, 91,171,126, 11,153,103, 61,142, 47, 99, 41, - 1,138,179,184,101,147, 77, 80,161,209, 74, 20,144, 43, 50,250,227,158,144, 6,235,225,157, 95,175,102,151,128,255,105,206,251, - 3,152,153, 20, 51,233,183,212,164, 89,180,192,124, 25, 11,214,151,107,110,215,192,105,239,224,102,178,123,136,198, 85,170, 15, -165,178, 70,136,210,201, 10,205,109,100, 11,147,213,104, 1,223,226,246,219,100, 11,113,128, 33, 93,219, 35,222,135,113,183,252, -182, 21,120,214, 90,139,134, 94, 25,119,147,230,220, 96,184, 30,183,193,178,220,166,217,246,204,166,203, 85,115, 76,162, 29, 83, -234,150,225,181, 45, 43,172,176, 94, 43,202,116, 38, 30,168,193,172, 3, 8, 88,246, 82,181,236,139,222, 88, 82,102, 73, 89,204, -230, 89,156,230, 81,150,133, 73, 18,211, 64, 84,216,120,211, 48,162, 52,218, 31,252,142,197,137,178,232, 60, 60,207,181, 2, 70, -167, 92, 46, 60,215,127,184,243,203,233,228, 11,236,108,152, 76,112,208, 3, 39,152, 48, 25, 91, 97,152, 71, 39, 71,240, 3, 56, - 68,195, 98,149,238,146,138, 80,152,156,239,182, 73,234,217,112, 50, 41,157, 84,202,142,212, 42, 99,206,144,181, 68, 42, 70,199, - 54, 19,194, 94, 22, 2,219, 34,143, 7, 59,248,116,255,233,255,167,135, 42, 44, 73, 50,187,134,153, 23,249,101, 52, 26,199, 35, -120,105, 73, 62, 31,108, 15,147,116, 6, 96,190,168, 84, 81,154,222,147,232, 31, 28, 97,156,237, 40, 9,241,187,247,122,247,186, -190,127, 60, 58,198, 73,243,155,237,205,206,102, 56, 13, 31,221,127,212,239,247,207,207, 47, 26,178,184,179, 36,249,251,249, 63, -111,222,190,102,193,101, 93,176, 80,157,105, 12, 11,179, 56,187, 58, 83, 66,151, 58, 53, 78,177, 69,182,244, 34, 47,200, 90,106, -183,218,174, 31,120,157, 36,157,118, 73,209, 94, 99,120,130, 43,165,177, 78, 55, 91,142,199,165, 96, 82,154, 76,223, 77,211,158, -165, 83,219,180,240,215,235,246,120, 74, 55,118,139, 69, 62,252,105,136, 85, 2, 4,105,176, 28, 89,131,205,218,191,255,228,240, -248,136,154, 68,123,127, 0, 12,116,154,116,106,129, 55, 47,174, 47, 56,170,186,252,237,231,199,211,249, 44,240,218,212,144,173, -181,117, 63, 0, 22,161, 66, 8, 19, 39, 94, 94,165,174,105, 19, 30,194, 63,144,210,154,157,205,189, 34,155,252,185,187,161,247, - 28,237,234, 26, 19, 50,182,135,203, 50,207,162,177,160,118,222, 46,213,233,173,204,181, 33,124,181,186, 18,115, 82,248, 29,159, -142,232,172,183, 93,114,193, 59,148,140, 18, 92,175,254,251, 61, 56, 76,231,113,213, 81,133,183,228,204,169, 95,181, 62,124,154, -127,206,199,127,253,251,178,163,187, 47, 14,158,221, 14,182,194, 60,139,231,115,204,101,171,179, 17,151, 89,191,181,213,247,186, -239, 71, 31,255,187, 58,221,187,117,119,221,242, 22, 26, 67,223, 15,118, 30, 76,179,100,146,132, 79, 6,143,199, 73,168, 16,128, -240,163, 44,215,219,235,216,187,195,147, 35, 28, 84, 9, 88, 47, 6,189,193, 87, 42,243, 1,144,249,112, 89,130,230, 26,188,189, - 94,192, 22, 98,197, 71, 2,152, 79, 59, 94,151, 7,195, 3,160, 64, 33,214, 32, 92, 83, 13,237, 77,145,234, 5,242,184, 97,197, -248,193,174,174,171,128, 17,150,136,129, 6, 67,249,175,240,119, 41,144, 64,115,239,212,210, 30,212,208, 45,156,156,134,176,234, -242,230, 73,122, 19, 95, 24, 77, 70, 64, 0,188,235,124, 46,196, 56,240,212,153,242, 9,228,110,109,223,218, 41,107, 88, 18, 27, -155, 71, 49,122,114, 22, 25, 66,101,152,227,216, 4, 94,160, 8,183, 53, 9,163, 85,213,141, 87,175, 64,165,228, 82, 49,101,178, -126,145, 74, 76, 1,116,237, 70,186, 79,213, 83,254, 16,255, 54,132, 13,236,155, 0, 60, 93,203,110, 27,101, 24,181,231,226,185, -218,227,113,210, 88, 77,220,210,139, 90, 42, 72, 55,128, 20,177, 65,162,155, 46,186, 70,130, 61,240, 16, 44,216,240, 24, 60, 66, - 95,129, 23, 96,129, 68,165,170, 18, 36, 21, 84, 69,113,236,248,146,177,231,226,185,247,156,111,198,108, 44,217, 25,219,147,223, -255,255,125,231,187,157,211,218,119, 60,149, 9,157,122,127, 5,105,119,164,154, 72,218,251,186,157,220, 33,255, 12,150,207,119, - 14,162,116, 35, 41, 99,121,167, 80, 76, 70,100, 89, 82, 27,237, 49,233,209,172, 96,214, 40,103,161, 26,136,190, 11,194,159,158, -240, 5, 50,151,126,228,221, 14, 17, 87,114,147,105, 66,234, 85, 54,148,129,101,213,228,204,249, 10, 64, 77, 41,161, 16,252, 31, - 59,243,186,245,126,104,139,158, 12,135, 83,164, 58,106, 32,161, 40,222, 44,162,101, 83,179,253,127,246, 2,247, 68, 58, 89,206, -236,228, 61,218, 76, 61,151, 82, 6,126,227,106, 47,148,169,200,255,120,124, 48,169,229,160,222,196, 65,243,102,216, 74, 81, 28, -132, 1,101,110,139,205, 42,244, 59, 44, 65,231,157, 84, 51,235, 74,215,163,184, 74,243, 58,217,149,187,180,146,108, 33,214, 71, - 53, 12,160, 48,197,160, 40,186,210, 20, 85, 0,240, 13,162,117, 34,113,211, 64,248,210,117, 96,208, 97, 60,122,226,247,169, 19, -212, 21,234, 46, 38,121,100,128, 16, 27,129,253,200,236, 74,169, 26,178,191,174,136, 89, 43,182,193,107,240,216,119, 53,215,213, -134, 3,221,181,117,215,209, 44,184, 7, 83,241, 92,205, 48, 85, 11, 95, 1,235, 2,103, 66,249,109,178,243,232,134, 74,213, 62, -216, 49,155, 3, 44,149, 10,252,158, 7,217, 54,200, 67, 0,132,191, 23,255,174, 83,233, 53, 82,107, 93,167,138,244,189,195,251, -216,247,179,237,204,232, 89, 35,107,132,237, 8,107,206, 59,237,106,247,142, 30, 46,194,153,129,224, 82,248,182,112,171, 4,239, -100, 53,194, 82,155, 48,178,192,158, 64,166,156,238,211,200, 43, 73, 94, 79,230,179,212,170,219,232,161, 75,121,174,165, 32, 82, - 88,244,128, 47,233,185,128,225,255, 45, 47,129,227,109,211,109,114,223, 34,199,173,103, 34,118, 8, 75, 77, 26, 78,171, 15,115, -207,140, 36, 63,160, 56,242,199,240,102,235,237,170, 18, 88,149,229,201,243,179, 23,239,102,239, 16,240, 94,223, 44,190,255,230, -135,215,127,189,178, 40,216, 20,205, 22,243,197,226, 26,152,163,161, 11, 62,116, 15,159,124,242,233, 31,127,254,142,191, 2, 16, -192, 82, 23, 66,150,121,236, 31,207, 54, 87, 88, 72,199,116,216, 53, 81, 87, 63,125,247,243, 63,151,231, 20, 6, 96, 61, 52, 7, -112,198,142,197,149,158,227, 1,217,124,125,250, 85,156,238, 96,118,119, 89,170, 74,193,172, 35, 65,198,100, 52,241,156, 1, 2, -240, 82,132,175,176, 43, 54, 73,112, 96, 15,167,171, 41, 34,158,233,250,234,236,209, 23,231,211, 11,133, 85, 46,198, 52, 23,211, -183, 73,186,195, 58, 46,183, 43,192,180, 53,229, 33,217, 50, 40,167,189, 31,198,225, 60,152, 11, 31,122,225,112, 76, 55,108,169, - 82,187,106,217, 41,238,248, 19,128,135, 91,222, 45,120,122, 93, 81,198,163,147,112,183, 76, 51,106,138,126,126,226, 27,119, 29, -218,247, 52,133,247,143,215,179,124, 23, 43, 45,215,101, 75, 30,217,114, 85,182, 40,190,101, 54,164, 49,208,133, 54,242,163,131, -206,157, 81,103, 96, 19,197,247,164,202,170,236,231,155,234, 61, 19, 45, 14,146,165, 16,233,191,241, 47, 94,166,175, 55,122,173, -196, 63,254,246,235,229,118,249,203,217,183,143, 15, 39,215,113,136,239,203,178,204,239,251,215,193, 42, 2,182, 46,203, 7,222, - 56, 76,118,231,219,247,239,147,248,217,237, 39, 64, 45, 81, 18,127,249,241,103,219, 36,154,223,204,129,201, 40,219, 73,138, 55, - 41,229, 10, 31, 20, 96,248,120, 56,206,138, 66, 40, 59,171,171,213,229,208,133, 9, 74, 92,203, 5, 62, 96, 12,100, 90, 8,131, -130,120, 3, 79,220,212,135,226, 60,134,189, 88,134,171, 56,143,196, 34,119,164,243,133, 89,242,211,187, 79,223, 94, 93,136,194, - 65,221, 78,101, 74,178, 90, 82,165,213,241,232,100, 60, 60,202,139,162,111, 57,194, 63,216, 9,226,224,244,254,211,213,102,221, -112,163,106, 36,173,227,124,108, 41, 44, 85, 66,158,207, 12, 44,176,145,239,248, 73, 78, 69, 64, 44,210,192, 30,226,104,176,184, -202, 51,173,249, 3,191, 97, 6,179, 77, 59,175, 75,207, 27, 50, 77,157,241,128,224,174, 60,211, 29,245,125, 32, 12,236,229, 38, -171, 32,109, 43,178,196, 34, 17, 5, 76,216,200, 71, 83, 10,187, 72,107,209,246, 2, 4,132, 15,108, 6,165,100, 24,168,101,174, -217,243,152,241,247,250, 32, 0, 81,215,178,219,182, 17, 69, 71,124,191, 68,201, 15, 49,134,242,176,156, 54, 6,156, 86,155, 32, - 64, 17, 32, 11,163,155, 22, 8, 16,160,219,126, 87,191,163,139,238,138, 46,218,117, 22,105, 80, 20,233,170, 73, 29,199, 85, 28, - 75,178, 40, 81,148, 70, 18,197,158,115, 73, 55,240,202, 0, 77, 15,201, 59,247, 53,231,158,243,191,127,175,251, 53,234, 19,205, - 77, 53,144,166,170, 2, 14,158,199,179, 5, 84, 68, 32,227,102, 93, 65, 70, 9,164, 65,230, 30, 86,114,227,176,182, 10, 58, 25, -122, 28, 18, 11,220, 8, 81,212,227, 70,202,241,106, 66,188,116, 61, 71,122,216,137,110,253,123,125, 81,177,168, 22,212,150, 99, -179,222,117, 2, 24, 14, 62,207, 97,114, 68, 22,102, 6, 69,193,180,172,114,114, 65,136,192,115,213,131,151,163,106,147, 3, 18, -194,205, 11, 91, 95, 23,250,203,187,125, 92,149,147,171, 40,246, 41,173,169,229,216,218, 89,175,180, 44,222,205,121,204, 75, 20, -109, 28,197,142,205, 3, 88, 85, 83, 93, 98, 83,141,144,165,194, 17,146, 39, 68, 40,198,150,122,190, 41,138,138,189, 19,238, 76, - 85,120, 68,197, 59,226,233,218,113,100,134,248,165,108,162, 6,115, 76,159,222,220,108,250,150,235,163,156,181, 44, 81,225,116, -237, 6,220, 52, 60,190,131,117,152, 50,193,194, 76, 95,232,204, 40,119,106, 20, 36, 28, 64, 21, 70,118,144,154,158,110, 91, 34, -193,119, 73,137, 98, 89, 53, 31, 17,163,161,165,234,157, 87,200,228, 76,131,168, 18,220,223,240,108, 65, 46,211,128,100,154, 83, - 74,230,138,204,153, 68,187, 38,175,193,218,130,208, 12, 35, 4, 0,150, 20,176, 51,105, 38,162, 16,177, 72,121,111, 72,166, 79, -136, 17, 60, 71, 62, 93,100,227,108,246, 62, 29, 76,151,233,110,208,110,251, 49,178,206, 69,177,204, 86,243,110,124, 27,235, 24, -164, 23,194,215,171, 28,199,197, 6, 56,104,119,239, 38,189,124,193, 17,158,141,212, 50,194, 99, 67, 81, 27,138,209,224, 81, 77, - 43, 14,154,148, 84, 21,154,101, 34,207,216,118,152,213,131,103,162,166, 5, 35,193, 71,132,243,197,218,180,214, 8,145,120, 24, - 17, 99, 50,201, 42,181,200, 28,219, 67,176,239,118,238, 32,101,219,109,182,241, 71,199,221, 99,252,119,234, 91,205,174, 42,194, - 50,189, 89,127,243,228,219,151,127,189,124,216, 59, 89,174, 86,233,120,130, 91,141,102, 35,230,227,101,177,223,222,199,222, 70, - 20,153, 47,103,147,252,250,247, 87, 47,226, 48,134,219, 69,185,237,187, 94,130, 52, 63,155, 92, 77, 47,159,127,245,221,249,240, -124, 55,222, 75,179, 9,156,236, 79, 47,126,108,249,173,241,116,184, 23, 39,196, 86, 26,102,132,210,139,187,154, 42, 32,177, 23, -191,249,248,247, 81,114,127,146,141, 45,182,236, 59,156,152,207, 83,248, 2, 84,165, 83, 36, 10, 20, 13, 79, 12,121, 51, 77,175, -233, 57, 46,202,240,105, 62,129, 47, 59,104,223, 58,190,253,240,195,104, 16,133, 77,178, 23, 80,199,166, 92,173,116,119,247, 96, -182,200, 34,152, 81,169,216, 70, 95,228, 21, 44,186,127,216, 63,187,250, 7,134,189, 21,221, 52,177, 13, 98,201, 16,138,200,241, -199,234, 86, 35,172, 94, 79, 63,208, 48, 44,194,249,251, 7,251,205,207, 2, 53, 76,183, 90, 47,210,161,206,166, 50,215, 44,184, -174,106, 6,255, 6, 84, 71,250, 16, 37, 63,156, 53, 23,204,251, 78,168,176, 6,195, 83,157,150, 74, 58, 42,138, 84,100,124,162, -211, 42,148,170, 85,160, 77, 21, 89,188,236, 23,127,252,234,206,159,185,238,198,209, 15,127,252,252,219,197,235,239, 31,156, 62, -191,255,248,114,145, 19,236,192, 83, 80,114, 18,248,142, 27,248,193, 12, 9, 17,158,104,167,247,235,251,215,151,249,224,100,175, -119,250,249,227, 65, 58, 66, 77,255,118,112,134, 12,224,235, 71,167,203,165, 70,210,109,144,110,196,129,103, 39,252,167,208, 40, -158,216,169, 51, 42, 36, 72,121,152,220, 27,206,174, 8, 72,223,108,119,130, 24,185,127,210, 74,240,113, 67,199,155, 47,115, 10, -234,202,161,221,154,115,203, 5, 2, 54, 69,230, 37, 12,163,118,124,115,249, 86,221, 32,196,101,248,198, 45, 27, 85,202, 39, 39, -101,196, 57, 56, 8,171,182,176, 71, 16,159,186,214, 79,251,167,231, 31,207,214,172,216, 56, 36,197, 81, 46, 42,178,154,244, 33, - 6, 7,185,159, 61,122,246,110,120,206, 49, 37,214, 67,116, 94,251,113,178,212, 11, 27,207, 64, 70, 85,191,197,185,247,109, 24, -134,129, 31,126,209, 59,233,221, 59, 66, 18, 59,154,140,109,242,117, 19,156,157,206,211, 27,234,120,130,171,152, 39, 21, 53,166, -145, 71,187, 54,197,148, 35, 47,188,153,150, 96, 80,193,189,145,179, 34, 96, 16,148, 40,121, 96, 89,183,240,203,186, 11,223,104, -252, 39, 0, 77, 87,211,219, 56, 21, 69,109,191,196,118, 29,199, 78,227, 38,109,153,182,204, 48, 29,205, 20, 10, 72, 51, 12, 18, -130, 34,132, 16, 43, 70,108, 17,140, 96,193, 18,126, 2,127,130, 37, 63,128, 13, 11,118,136,245, 72,108, 16, 31, 3, 83,164, 50, -180,106,160,153,180, 77,219, 73,210, 36,254,136,253,108,115,238,125,153, 93,148,200, 73,236,247,238,231, 59,247,156,185,190, 7, - 35, 97,230,141, 27,230, 5,179,230, 74, 57,207,112,249,112,193,113, 30,171, 81,142,181,224,133, 48, 33,238,192,187, 55,222,194, -182,235,143,122, 60,157, 72, 44, 46, 74, 39, 65, 50,119, 4, 11, 99, 82, 42, 7, 11,135,235,111,184, 77,236,117,155, 78, 95,171, -140,132,201,149,174,167,154,105, 34,150,159, 12,142, 96,118,206,125, 82, 77,249,217, 44,153,207, 87,113,101,169, 38,173,168, 32, - 98, 94, 26,124,207,214,149,109, 88, 38, 62,198,218, 99,211,101,212,246, 77, 73, 44,141,156,169, 96, 9, 39,185,181,246,106,111, -208,229, 35,204,226,206,230,235,167,131, 83, 86, 74, 99,153, 24, 26,103,201,177,238,205,218, 82,221, 33, 99,131, 79, 81,106,229, -108, 72, 85, 58,162,148, 4,139, 52,212,188,108,133, 79,210, 28,189, 98, 11,236, 31,179,170, 47,192,188, 42,186,101,226,125,252, - 60, 85,208,179, 84,163,140, 55, 85,203, 68,218,100, 40, 66,114,210, 2, 45, 73,172, 86,178,102, 94, 81,102,153,158,102,153, 99, -153,247,222,127,239,179,143, 62,217,121,227,205, 89, 90, 28, 28, 30,199, 49, 42,208, 10,211, 73,171,197,230,172,131, 65, 59, 12, -188, 21,136, 40,248, 23, 52,180, 67, 21,141, 80,117, 28, 53, 11,115,141,135, 84,141,186, 45, 92,108, 7,139, 49,213,120, 15,129, -137,200,225, 8,172,201, 88, 39,195,180,104, 30,157, 81,161,138,180,145,177,113,186,201, 28,129,162,176,244,204,208,206,211,209, - 73,116,126,112,113,128, 80,183,230,175,225, 46,131,122,112,153,140,137,182, 41, 79,171,204,189,188,228, 7,117,211,199,198, 24, - 70, 3, 24, 67,173, 90,115,109,239,254,187,159,254,121,248, 59, 12, 82, 16, 11, 51,235, 59,106,250, 76,198,184,124, 18,143, 81, -231, 50, 69,174,128, 81, 81, 7,143,230, 66,169, 65,153,164, 48,234,168,238,120, 46,201,116, 80,163, 51, 39,143,224, 44,186,193, - 70,123, 67, 74,217, 57,254, 71,176,185,194, 17,193, 77,195,239,243, 12, 55, 73, 34, 52,156, 6,150,182,211,237,196,179,233,209, - 89, 39, 74, 38,255,157,116, 94,185,113,251,124,208,231, 3,116, 18, 29,243, 60,191,144, 5, 50, 68,131, 32,161, 11, 95,126,248, -197,195,253, 95, 97, 84,171,139,207,181, 23,219,189,139, 99,164, 35,143,187,123, 40, 74, 38,225,152, 64, 95, 50, 22, 90,229,238, -230, 29,148,116,184,164,110,211, 19, 69,146,136, 84, 49,112, 3,152, 43,162,176,193,147,244,185,204,153,205,180,164,214,188,161, -175, 7, 27,184,133,132,100, 82, 52,226,221, 99,250, 26, 73, 99, 41, 22,252,209,214,149,155, 47,109,108, 63,121,218, 27, 69, 35, -196,185, 52, 75,174,175,110, 50, 29, 66,241,193,107,247, 30,117, 30, 5,245,165,254,101, 63,165,180,209, 88,176, 29,220, 32,105, - 89,240,126, 70, 40,178, 42,182,204,102,220, 87,169,172,120,237, 48,157,142,195,225, 36, 25, 75,162, 79,145,130,230, 39, 17,236, -137, 74,240,118,219,243,110,249,240,239,132,251, 39,249,179,242, 25,150,174,228,108,189,156,167,237,138,153,143,117, 56, 4,159, -185, 82, 79,102,152,126,251,205, 79, 15,127,216, 77,126,220,155, 62,216, 15,112,201,173,235,196, 5,159,243,208,123,206, 45, 10, -179, 66, 26, 79,163, 88,251, 46,125,240, 75,249,199,229,209, 74,163,113,112,118,248,213,207,223,175, 46, 44,127,253,246,231,151, - 50,137,114,233,219, 86,191,119, 81,141,244,108,162,153,169, 24,140, 46,146, 50, 11,252,197,165, 90, 3, 85,228,111,195,253,163, - 40,250,248,197,157, 39,195, 19, 58, 59,181,136,144,252,223,179, 46,226, 43,171, 78, 80,195,139,180, 53, 52, 37, 15, 42, 34, 30, -242, 84, 88, 29,215,114,175,181,175, 33,220,134, 89, 24,198, 33, 76,155,116, 87, 10,141,105,166,204, 22,124,253,116, 88,232,115, -224,160, 87,243,223,217,222,249,187,251, 24,143,130, 41,251,241,247,171,140, 43, 39,156,234,178,215, 74,137,113, 79, 42,102, 24, - 60,240, 48,158,224,245, 50, 81, 6,197,240,111, 73, 26,239, 29,253,133, 61, 41,120, 74,141,132,193, 40,102, 35, 77, 20, 52, 93, -143,140,173,148,157,211, 67, 69,187, 59, 39,146,211, 5,146, 90,162, 65,181, 93,199,116,214, 91,207, 15,194,167,200, 72,182,214, -111, 34, 73, 95,105,172, 52,151, 91, 47, 95,221,222,221,223, 21, 74,213, 78,157,174,170,182, 38,219,164,111, 53, 80,154,148, 74, - 34,173, 44, 16, 84, 38,201, 20,123,172,224, 27, 80, 16, 32, 20,163, 72,164,154,110,107,146,142,169, 87,145, 23,198, 28,193, 74, -188,170, 77,167,137,120,243,191, 0, 68, 93, 75,111, 27,101, 20,245,120,198,158,151,103,198,241, 43, 78,129, 58, 86, 92, 33, 64, -180, 68,188, 68, 37, 88, 80, 40, 98,197,166,101,197, 14,169, 66, 2,169,155,138, 95,192,154,159,193,142, 13,107, 22, 84, 44, 10, - 2, 33,136, 16, 2,210, 68,169, 99, 50,142, 31,241,216,227,121,207,216,156,123,199,106,178,139,100,203,154,249,238,119,239, 57, -223,119,239, 57, 27,252, 46, 82, 31,247,165,235, 19, 34, 18, 4, 4,128, 37, 78,163, 75, 27, 64,118,242, 75,201,137,120,202, 42, - 99,165,254,244,120,226,130, 63,146,227, 54,181,100, 82,240, 21, 11,185, 41,156, 80,228,163, 34, 82,101,194, 50,128,122, 3, 35, - 99,159,211,148, 83,224,146,170, 3,171, 72,226,153, 85,154,154, 17,144, 11,232,200,133, 66,110,117,217,114,202, 38, 15,134,106, -241, 5,101,150,207,238,242, 76, 51,181, 0, 99,109,198,124,235,141,231, 85, 21,157, 66, 84,216, 44, 30,254,176, 96,248,149, 69, -232,130, 13,208,253, 37,121, 78, 75,231,243, 17,248, 26,157,111,139, 98,174,249,144,107,196,251,177,231,250, 78,198, 32, 61,203, -205,183,240,128,212,204, 72, 3, 1,192,152,217, 58, 33, 40,205,197, 81,213,164,170, 85, 2,129,193, 2,151,203, 66, 69, 19,149, - 18,235,172,242,156,119,153, 14, 36,214,248, 15,164, 45, 78,185, 15,139,140,176,217, 88,183, 40,233,114, 25, 80,218, 80,149, 74, -133,228, 88,239,127,246,233, 59,111,189,250,232,231, 31,183, 76,249,147,187, 31, 55, 76,253,232,248, 8, 8, 12, 65,161,240,229, -237, 6,100, 49, 29, 43,229,115, 17, 84, 56,114,161, 32, 30, 39,229,203,115, 58, 61, 65,246,151,153, 55, 72,200, 5, 4, 87,240, - 89, 93,149, 44, 67, 50,117,145,124,156,196, 34,115, 18,230,231,148,160, 89, 51,176,132, 82, 46,211,177,142, 76,101, 10,239, 73, - 4,145,193,130,169,200, 72, 82, 81, 19, 11, 58, 82,157, 7, 68, 63,152, 12,240, 2,119,235,221, 78,109, 87, 83,116,228,154,199, -246,191,246,220,126,239,250,237, 69, 48,163, 54, 50, 81,156, 46, 39, 23,174,131,200,243, 67, 98,108,216, 54, 65, 20, 4,137,119, -181,214, 33, 85, 53, 50,119, 84, 42,170, 25, 69,161, 76, 1, 19,119, 91,123, 4,117,185,239, 30,197,169,109, 93,145,117,217,247, -188,118,237,153,185,239,196, 89,224, 6,206,104, 62, 68,150,143,211, 16,101, 8,155,202, 80, 13, 63,166,249,192,102,165,201, 61, -154, 34,133, 34,221, 71,211,245, 38, 66, 28,216, 28,193,114,255,203, 7,206,204, 25, 15,135, 8,176,115,199,158,204,198,216, 27, - 85,189,122,109,167,135,252,251,235,225, 47, 9, 17, 91, 1,108,250,200,126, 12, 66,128,132,139, 87, 14,114,137, 58,228, 5, 75, -242,143, 42,172,251,211,211, 21, 91,209,146,119,157, 36,133,129,183, 99, 93,161,228, 88, 88,219, 23,131,155, 47,222, 60, 29,247, -121, 65,214,117,171, 69,157, 12, 89,134,215,210,107,245,226, 44,121,243,249,215,158,216, 39,220, 18,135, 28,155, 6, 73,184,165, - 85,203, 98,249,224,228, 96, 30, 44,194,216,223,239,238, 15,103,231,128,252,212,127, 25,121, 79, 70,131,134, 81, 95,250, 11, 26, -254,101,115,194,109,179,165,148,228, 32,242,168, 1, 73,181,240, 73,112, 80,214,155, 37,181,158, 32, 14,106,218,150, 38,107,187, -205,174, 27,204,121, 24, 66,108, 88,237, 36, 38,147,228,151,141, 74,237,149, 90, 97,234, 8,132,153, 88,165,104, 19,237,249,245, - 97, 46,191,192,163, 26, 79,109, 40,176,139,228, 18,138,210, 55,223,253,209,247, 19,171,101,156, 37,241,201,217,100,167, 63, 53, -159,171, 23,158,173,211,189,107,146, 50,108, 87, 8,182, 63,234, 31,125,251,219,106,214,251, 61,138, 64, 19, 27,197,242,215, 7, -223, 31, 58,131, 7, 55,238, 52,117,211,118,166, 98, 92,232,136,221, 15,239,125,113,253,171,143,110,124,126,251,133,187,239,238, -183,223,206,254, 94,252, 53,252,211, 73,150, 47, 85,187, 15,207,254,177,253,255, 26, 69,171, 46,107, 72, 5, 53,179,234,199,228, -190, 77,136, 70, 40,110, 52, 16,217,139, 7, 17, 21, 68, 97,158,136,176, 16, 40,123, 51,111, 54, 93, 76,105,212,145, 4,170,196, -124,154,149,233, 8, 89, 81,215, 64,149, 66,247,218,118,143, 84,243, 66,191,179,221,233,143, 78,187,237,189,241, 98,148, 11, 21, - 26,106, 69, 43,145, 79,139,227, 94,168,248,117,210,157, 73,115, 1, 0,190,221,165,252, 3, 20,216, 52,119, 38,203, 17, 49,112, -234,219, 46,231,105, 80,100,189, 32,210,170, 76,227, 45,114,152, 10,174,182,186, 62,137,219,208,248,210, 27,123,175,219, 51,155, -143, 87, 9,155,145,179, 71,197, 84,100,197, 15,189,117,113,237,120, 11,124,253,116, 56,184,245,254,173,135, 63,253,176,112, 93, - 93,171,208, 69, 11,213,140,220,167, 33,159,147,205,176,214,204,113, 87,168, 16, 6,203,153,160,204,148,201, 53,250,131,227,243, -195, 92, 98,108, 25, 81, 97,243, 64,136, 5, 26,141, 70,106,101, 95,160, 85, 9,216, 63, 77,169, 71, 92, 16,254, 23,128,169,171, -233,109,163,138,162, 51,227, 25,127,127, 55,198,205, 36, 49, 41,150, 34,144,144,160, 69, 72, 32, 85,145, 88, 33, 33,181, 32, 85, - 66, 2, 22, 84, 44, 88,128,132,196,130, 21, 66, 98, 83, 86, 44,186, 65,226, 71,176, 41,252, 3, 16,180, 5, 81, 8, 80,167,180, - 77, 93,130, 90,215,113,252, 17,143,237,241,204, 60,123, 56,231,190, 32,216, 38, 25,231,205,243,187, 31,231,190,123,207, 57,246, -239, 74, 42, 4,255,159, 74, 69, 56,162,194,195,127, 21, 27, 83,199, 0,105,210,212, 12,102,250, 85,109, 56,119,100, 94,106,177, -132, 17,228,146,128, 51,200,214, 41,123, 29, 8,231, 3,165,108,151, 36,226, 73, 89, 73, 37, 9,207, 74,113,101, 52, 27,196,162, -144,128,189,131,195,245,213, 12, 79,105, 25, 89,225,122, 12,165,190, 71,124, 1,131, 17,218, 97,118,152,193,101, 57, 78, 10,222, - 18,159, 10,220,196, 43, 86, 17,219,197,145, 85,138,247,189,248,166,115, 78, 86, 36,191, 57, 4, 65,245,168,197,194,113,210, 88, - 38, 0, 7,220, 13,146,113,242,110, 47,244,152,177, 20,223, 98, 77, 79,121,220,153, 84,204, 20,240, 96, 42,153, 19,245, 22,130, - 59,209,212, 14,205, 99,234,133,130, 50, 84, 62,155, 46,159,160, 25,102, 83,240,239,236, 97,112, 28,185, 89,229, 23,202, 38,118, -199,193,242,168,254,152,118, 12,199,177,121,161,154,182,138,120, 56,235,228,179, 70, 41, 23,215, 42,137, 98,222, 40, 22,146, 31, -126,240,254,231,151, 47,127,119,237,167, 27, 59,191,239,239,223,127,237,252, 43,181, 74,254,230,110, 75,111, 44, 35,245,146, 6, -157,182,109, 64, 4, 38, 23, 42, 14, 2,195,135,255, 8,204, 89, 40,116,236,172,218, 24, 73, 96, 16,135, 23, 36, 41, 22,255,132, -175, 53,182,148,178,224,196,252, 57,173,210,224, 80,139, 84,119,180, 30, 27,103,233, 18,188, 7, 78, 57, 5, 4, 88, 44, 44,147, -200,164,157, 98,150,241, 32,159,195,154,245, 45, 2, 67,128,178,226,185, 21,204, 44, 5, 20, 76,238,198,216,216,235,239, 77, 66, - 32,104,211,173,184,215,238,124,239,249, 19,150,209,163, 57,142,232,197,151,222,254,250,199, 43, 88,255,201,106, 67,234,108,172, - 10, 30,249,195, 5,201,153, 51, 75,161, 90,100,242,107,153, 56,127,227,233, 81, 17,185,117,166, 52,241, 61, 30, 33,181, 60,247, -250,185,206, 30,160,152,194, 79, 52,127, 45,142,201, 4, 86, 97, 51, 96, 35, 39, 96,131, 26, 9,230, 40,159, 22, 17, 62,231, 51, -164,167, 15, 42,185,218,246,211,219,183, 31,222,178, 69, 86,237,207, 95, 90,215,119,174,158,217,122,190, 59,236, 52,221, 45,216, -253,152, 26,141,211,238,176, 91,202,149,120,165,143,239, 23, 7, 92, 56,184, 61,146,241, 70,235, 43,143, 15, 61,226,229, 96, 25, -212,114, 53,153, 99, 44, 5, 1,114, 70,188,230, 73, 21,145,234, 11,182,180, 88, 70, 72, 56,206, 62,121,118, 48,238,123, 51, 15, -200,102,181,234,158,114,159,104,212, 27,253,225, 1,206,221,126,175,141, 88, 2, 36,129, 3,230, 80,219,210,130,121,191,185,125, - 97,231,222, 31,216, 52, 78, 2, 38,136,207,240,250,171,213, 53,236,216,179,205, 51, 65, 24, 33, 86,193,128,181,134, 39,233,231, - 98,179,239, 29, 78, 3,223, 74, 8,247,142, 10,240,223,221, 74,157,146,144, 72,167,156, 20, 54,208, 15,103,210, 38,192,116, 18, -161,183,152, 46,227, 87,107,181,141,209,116,248, 76,185, 80, 61, 93, 49,122,163, 24, 88,146,140, 35, 11,105, 33,145,180, 88,192, -169, 80, 13, 91,186, 80,115,204, 3,141,135,243,169, 86,171,123,229,215,125,192, 46,165, 34,132,163,167,214,203,141,122, 33,137, - 51,132, 44, 42, 45,211,121, 11,219,248,225,239,221, 47,191,253,249,234,221,208,180,123, 97,195,139,252, 76, 34,209,155,120,159, -221,248,102, 45,179,250,197,203,239,221,234,220, 75,206,138,111,124,114,201,253,244, 57,115,148,190,254,209,205,223, 62,190,221, -254,234, 96,195, 61,181,249,206,233, 23, 42,175,246,255,106, 41,123, 30, 43, 99,103,120, 23,135,238,197,122, 19, 43, 27, 76,143, - 76,173,235,168, 29,142,232,223, 46,164,160,164,133,180, 96,212, 54,199,154, 24, 6,240,119,110,117, 93, 72,144, 76,227,223, 78, - 16, 77,109,178,148, 62,200,121, 16,172,158,112,219, 7,247, 97,194,135,227,193,104, 58,232,141,123, 82, 3,224,137,194, 54,206, -163, 96, 60, 27, 25, 34,221,204,170, 50,245, 78,132,110,207, 48, 31, 43,212, 57,229, 78,102,236,177, 80, 66,114, 13,165, 76,153, -126, 38,214, 51, 49,134,248, 40, 50,134,114, 8, 22,190,155,141,100, 36,180,120, 48,120,168,123,106, 86, 10,188, 87,247, 2,111, - 50,159, 30, 77,198,176, 57, 96, 95, 96,148, 82,169,186,217,216,124,235,210,187,221,221,206,160,215,155, 71,225,204,159, 34, 61, -218, 90,219,122,116,216, 97,145,129,165, 78,139, 44,211,194, 52, 0, 12,129,228,184, 89,111,118, 71,143,144,108,180, 15,218,164, - 89,100,147,133, 16, 49,105,221, 95,195, 98, 2, 36,132,137,240, 4, 27,216,153,101,168,181,212,255, 17,128,170,235,249,109,155, - 12,195,254, 18,219,113, 28,219,177,157, 31,237,166, 36, 48,212, 13,117,233, 86, 74, 39,164,110,244, 0,154, 54, 52,117, 8,109, - 7,196, 14, 72,149,118,225, 47, 96,103, 46, 99, 39,196,133, 3, 92, 16,112, 67, 28, 24, 32, 14, 28,144, 2, 8, 52, 4,108, 29, - 37,210,196, 58,154,210,161, 38, 77,210,216, 78,108,199,177,189,247,125,221, 78, 67,170,170, 42,178,170,124,142,243,124,207,243, -126,239,251, 60, 9,190, 31,140,183, 62,225, 59,169,203, 5, 0,202,255, 87,228,163,199, 23, 60, 54, 44, 70, 23, 95, 94,234, 59, -187,240,219, 71,163,148, 0,214,156, 21, 49,205,131,237,147, 76,236,217,135,187,172,169,218,202,217,139,119,239,221, 1,213,117, -176,153, 96,181, 10, 52, 14, 69,112,164, 19, 53, 77,217,226,241,241,202,201,174,213, 33,108,157, 96,209, 31, 79, 47, 1,166,209, -135,129, 75,162, 11, 67,180,235,196, 58, 26, 33, 8, 67, 47, 80, 13,187, 39, 73,127, 82, 40, 4, 96,115, 8,248,114,162,182, 0, - 95, 57, 46,181,111, 42,143,168,141, 35,156,248,130,140, 25,187, 1, 25, 61, 80,124, 56, 23, 15,199,174,161,154,123,163,126,242, -194,129, 93, 27,126, 53,114,162, 82, 54,167, 16, 89, 50,113, 94, 23, 39,212,105, 20, 6, 12, 0,119,100,115,131, 97, 60,116,162, -129, 19, 58, 78, 52, 28, 69,174,139, 94, 4, 64,180, 99,156,118, 67,117, 41,138, 64,243, 99, 89, 18, 46,189,122,121,249,197,243, -141,159,238,200,146,249,230,149,213, 15, 62,252, 56,136,132, 40, 22,239,111,108,111, 63,236, 94, 93,125,203,119,195,159,111,253, -193,161, 46, 3,128,142,210, 17,141, 63,115, 88,102,161,222,128,148,134, 93,149, 44, 39, 49, 17,235,239, 44, 35,128, 84, 74,131, -116,128,165, 4, 88,214, 79,177,144,209,113, 46, 47,225,164, 29, 21, 68, 0,245,113,106, 28,241, 90,206,166,241, 96, 86, 22,114, - 50, 15,128, 14,114, 36,135,244, 29,229, 2,151,140,137, 69,200,133,147, 52,162, 56,196,233, 45,127,156, 10, 97,183, 96,177,195, -252,206,176,147, 99,146,153, 43,218,129,149,227, 85,216,188, 41,203, 2,207,177, 97,181,151,206, 92,254,161,217, 40,105,229,122, -181, 14,212, 24, 22,110,168, 37,248,136, 96,247, 29,147, 93, 40,242, 11,158, 31,250, 35,158,246,126,219,179, 46,156, 90, 25, 7, - 0,112, 30, 60,202,235,183,215,139,218, 84,215,238,228,209, 48, 46,162, 72, 94,126,218,172,216, 78,143, 10,241,209,200,119,128, - 61, 0,213,128,235, 83,228, 95, 4, 16,170,201,121, 80,243,235,173, 63, 61,223, 61, 59,127,254,229,231,150, 27,119, 27,167,235, - 75,205, 86, 51,138, 2,216,215, 71,190,109, 40,230,213,115,171,107,255,172, 47,227,116,232, 54,176, 63, 74, 93, 64, 75, 34, 12, - 6,241,236,246, 96, 7,158, 25, 32,197,150,103, 81,199, 33,166,130, 44, 28,153, 31,142, 71,189, 65, 47,136, 38,207, 76, 31, 1, -166,143,190, 49, 59, 27,237, 65,119,171,219,154,210,203,240,255,187,131, 46, 31,177,221,126,123,224,237, 37, 50,119,233,217, 37, -144, 26,165,124,145,230,110,108, 88,114,115,243,158,161,234, 56, 33, 18, 79,230,106,115,160,214,125,223,239,219,253, 11,167,206, -173, 61, 88, 51, 21, 3,176, 6, 89,152,156,159, 96,231,190, 48, 91,153, 85,164,156,237, 90, 25,148, 94,130, 42, 41, 5,173,248, -218, 11, 23,111,111,192,197, 58,112, 32,157,218,138, 78, 84,235, 15,123,255,149,180, 18,104, 26,216, 50,128,149,217, 78,135,227, -179,117, 65, 40, 62, 95,224,122, 22, 27,251,216,210,157,228, 8, 50,202,113, 72,186,182, 41, 80,252,192,179,144, 70,245,104,214, -242,102,227,190,158, 17, 22, 15,231,159, 46,104, 37, 37,107, 72,146,145, 3,170, 10,132, 93,228,188, 52,247, 99,235,183,247,190, -251,252,139, 91,127, 15, 28, 81, 19,242, 98,158,177,163,138, 90, 92,156,158,185,254,235, 87,205,254,131,107,243, 87,210,176,185, - 57,236,141, 79,222,225,102,185,239,143,254,242,238,251,215, 23,221,147,243,167,231, 38,125,255,237, 79,111,124,246,209,183,175, -191,244,202,204,177, 51,131,205,191,132, 84,248,205,191,191,183, 92,107,165,178, 48, 10,104,242,145,138, 21,112, 19, 76, 85,183, - 92, 27,222,165,174, 24, 79,149,170,112,223,224, 15,248, 92, 0, 13,108,207, 73,106,229,128, 39,158, 71,157, 57, 90,153,145, 83, - 55,186, 31,114,152,104,136,241,170, 19,127, 7,123,108,176,144, 93,198,211, 17,137, 38, 6,112,221,138,164, 84,139, 53,184,225, - 66, 42,153,120,199,220,203,162,106, 6,232, 70,133,146, 6, 54,206, 41,227, 16,136,170,140, 32,213, 10,181, 61,119, 79,226,129, - 98, 9, 56,163,176,239, 7, 64, 14, 4, 44, 1, 89,126,223,165, 5,229, 3, 74,162,138, 89,133,165,120,120,192,139,177,163, 25, - 49, 35,101,240, 71, 6, 2,197,139, 0, 32,157,221, 78, 33,206,127,125,243,203,225,112,132,163, 63, 84,240,105,247,219, 64,169, - 75,106, 25,158, 34, 34,219,220,204,225, 99, 32,136,179,188, 12, 79,205, 86,103, 51, 38,239, 73,244,130, 77, 75,101,253, 16,232, - 57,246,132, 9, 60, 29,125, 97,233,162,168,150,182,122, 45,154,174,194, 55,250, 72, 0,170,174,174,183,109, 50, 10,219, 78,147, -216, 78, 98, 55,109,178,166, 13, 97,237,214,178, 45,157,134,128,176,105, 18,140, 1,210, 16,162,160,169,119, 92, 34,174,198, 5, - 84, 8, 36,238, 16,183,252, 9,110,166,113,135, 4, 72,252, 0, 42,168, 80,165,106, 76,221,186,118, 75,187,245, 35, 29,142,243, -225,196,241, 71,252,241,114,206,121,211, 33,174, 45, 37,214,107,251,156,231,156,243,156,231,193,248,206,215,154, 68,145,157, 88, -226, 34,118,198, 85, 14, 64,159, 18,234,241,138,255,147,123, 30,117,136, 70,169,159, 9, 68, 26, 69,199, 15, 56,107,137, 73, 80, -239,160,197, 48, 11,184,156,165,112, 98,184, 7, 37,240,230,246,223, 36,185, 46, 17, 79, 81, 34,114,126, 48, 51, 81,177,108,130, -243,226,127, 5, 4, 4,119,236,243,177,145, 16, 38, 57,210, 1, 80, 9,166,180,178, 19,216,124, 65, 20,202,118,116, 74,146, 53, -200, 16, 99, 82,146,118, 79,176,180,243,136, 1,173,171,227,254, 16, 37, 76, 26,237, 67,118, 50,120,124,126,227, 34,119,185, 35, -183,216,116, 18,112,106, 2,125,118, 2,236,204, 12,220,193,220,212, 89, 44, 44,112,132, 2, 24, 92,165,113,177, 3,181, 2, 78, - 23,112,204,202, 20, 85,182, 61, 40,198,165, 36,106,236, 73, 67,146,194,227, 19, 99, 28,178, 71,156,111,139, 7,203, 53, 0,185, -101, 22, 96,145,107,111,188,185,242,205,247,231, 22, 95, 49,143,235, 90, 54,187,120,241,226, 15,183,239, 16,166, 16, 33,242, 61, -170, 63,105,153,198,151, 95,124,190,179, 83,223,217,221,195, 81, 43,122, 99, 98,125,152, 83,164,172,154,208,179,146,154,150, 50, -170, 72,139,195,212,202,162,237, 18,132,161,113, 2,206,207, 67, 59, 81,119, 56,244, 1,159, 12, 0,109,218, 1,128,119,136,251, -142,203, 28, 7,141, 62, 80,250, 35, 70, 70, 96, 70,133,176, 40,170,138,168,202, 34,109,159, 82, 62, 68,201,120,162, 64, 83, 64, -192,173,241,136, 13, 67,226, 98,146,220, 2, 74,187, 42, 98,164, 64, 32,237,159,155,168,190,125,233,218,221,253, 13,200,172,101, -189,108,121, 86, 86,209,122, 3,231,176,181, 63,157, 47,175, 63, 94, 75,167, 32, 34, 51,122, 94,132, 69,208,124, 46,167,200, 50, -110,253,197,209,116,190,226, 96, 63,145, 65, 64, 55, 44,163, 82,152,245, 67,215, 13,156, 86,239, 31, 9,149,123,253,235,151,222, -178,250, 86,140,194, 71,166,158,157,128,192, 7,207, 11, 48, 47, 0, 55,163,211, 72,208,126,254, 24,154,160,203,190,239, 37,136, -172,121,243,234, 71,107, 15,255, 52,187, 29,192, 1, 7,173,195, 16,221,168,169,148, 30,186,114, 82, 89,189,191, 90,173,156, 95, -221, 90, 69,123,172, 48,210, 85,173, 54,127,229,168,125,212,119,173, 79, 63,188,181,177,253,215,187,175,222, 88, 88, 56,191, 83, -223,132, 3, 9,224,255, 66,239,184,221,128, 24, 90,212, 38,219,125, 83,147,245, 71, 71, 15, 27,237, 70, 33, 87,168, 86, 94,170, -205,215,234,141,199, 3,215,158,204,141, 39,144,124,213, 5,236,180, 84, 91, 50,186,207, 14,154, 7,182,107, 85, 95,188, 0,239, - 12,142, 10, 73,155, 98,110,234, 12, 74,217,188,190,180,249,244,126,128,164, 82,177,148, 47,193,221, 50, 52,179,124,134,190, 26, - 66,252,193,107,239,195, 63,250, 81,208,236, 26, 25, 57, 3,192, 16,158, 22, 68,127, 27, 71,223,237,123,123,119, 35, 98,197,122, - 80,154,198, 65, 38,165,238,155, 79,199, 18,252,197, 38,123, 16, 49,158,155,169, 66, 28, 92, 84,132,226,213, 83, 66,183, 39,132, - 67, 17, 73,105,225,115,191, 22, 44,146, 73, 84,129, 19,234,185, 39, 80,132, 20,126,201, 50, 3,167, 29,159,157,204,235,105, 72, -253,114,110, 76,157,204, 77,104, 47,204, 8,133,130, 96, 56,127,220,254,253,206,111,235, 91,221,190,151,134, 58, 90, 82, 32,240, -136, 90, 16,149,154, 78,183,101, 53,191, 93,255,165,144, 42,174, 84,223,235,244,226,143,127,250, 78,128, 76,119,157, 29,219, 79, - 62,251,241, 86,249,171,105,101, 62, 85, 90, 46, 44,127,114,227,193,207,247,222,249,117,121,101,225,235,133,151,175,152, 71, 27, -107,199,219, 45,207,188, 60, 85,205, 37, 83,112, 38,156, 62,235,134, 46, 84,111,124,173,156, 74, 46, 3,190,196,130, 94,236,185, - 61,200,175,144,234,224,211,134, 40,111, 59,125,168,224,243,185,252,229, 11,181, 7,251, 91,200, 0,140, 2,184,164, 36,229,217, - 83,167, 59,118, 39,226, 98,113, 44,234,251,240, 25, 12, 71,233, 12,181,148,253, 46, 18,106,137, 81,195,189,178, 4,134, 14, 89, - 35,197, 78, 68,197, 54,185, 1,147,212, 92,224,249, 30,173, 2, 6, 39,206,188,188,157, 21,243,194,129,111,253,143,103,199, 81, -200, 4, 27,160, 12,117, 23, 56,243,114,180, 2, 36,208,142, 35,106, 58, 97,151,153,177,211,229,217,180,172,236,238,237, 10, 68, - 58, 15, 3,236,204,208,213,200,114,104,209, 82, 64,193, 25,211,106, 82,125,192,184,191, 38,218, 39,208,143, 2, 68, 0, 56, 82, -210,103,236,192,230, 70, 79,240,230,228, 20,173, 82,156,107,246, 12, 36,233, 99,214, 73,168,104,120, 16,253, 43, 0, 81,215,243, -219, 54, 25,134,227,216, 77,236,216,233,226, 52,212, 9,237,250, 51, 73, 87,180,193, 90, 13,181, 18,211, 0, 9,184,236, 48, 64, -156, 55, 14, 28, 57, 84, 72,156,224, 80, 33,132,224,200,223, 48, 1, 23,142, 8, 49,168, 16,168,155, 0, 49,212,195,196,143,178, - 54,144,174,105,179,252,182, 19, 59,113,220, 56, 60,239,235, 68,220, 29, 59,246,247,125,239,251,124,239,247,188,207, 51,174,191, - 83,163,121,224, 46, 55, 18,232,197,142,155,100,246,250,157,168,164,156,249,212,254, 35,145,124, 74,224,144, 57, 36,169,108,182, - 40, 11,196, 35, 3,137, 48,214, 54,161,178, 76,143, 72, 47,126, 64,185, 34,205,225,179,190, 79,134,236, 10, 17, 18,165,200, 92, -106,161,238, 52,184,171,149,162,138,229,152,116, 96,202,174, 26,227, 67, 84,250, 3,236,134,229, 13,199,158,224, 65, 83, 89, 68, -146,169,109, 21,187,233,228,108,217,122, 44, 50,207,140,109, 36,169, 3,126,200, 84,182, 41,205,192, 59,117,221,182, 47,248,225, - 81,193,145, 61, 75, 4, 31,155, 18,143,141,132, 70,188, 87,202, 61,248,153,215,231,202, 23,117,129,177,232,166,101,155,182,219, - 65,174, 2,164, 97, 54,183, 79,187,215,192, 31, 83, 28,138, 98, 40,243,164, 66, 38, 27,228, 73, 54, 68, 82,139, 70, 68,160,233, -152, 18, 6, 52,166, 19, 87, 98,182,144, 45, 14,155, 91, 50,175,152, 44, 46, 9, 52, 25, 73,237,249,171,235, 3,215,250,252,179, -219,139,243,243,186,158,248,118,103, 71, 85, 21, 53, 42,105,114, 68, 85, 34,133, 98, 65,153, 16, 95,191,113,125,247,238,143,248, -109, 52, 42,113,136, 23, 88,226,141, 78,107, 17,175,123,110,168,109,251, 64,102,129, 14, 68,128,235,113, 49,130,250, 51,171, 79, -125,242,225, 7,239,110,109,189,241,234,141, 43,107,235, 64, 13, 71,197, 99,199,233, 17,213, 28,201,154,106,183,146,166, 72, 9, -172, 93,146,240, 18,144, 10,113,183,174, 27,194,252,247,104,114, 10,140, 49,199,254, 47, 44,245, 7,180, 44, 71,200,255,129,234, -156, 68,131,230,126,102,209,251,183,126, 84, 56, 57, 64, 80,203,167, 87,123, 3, 7, 57, 6, 1,186, 88, 59,224,206, 58, 39,117, - 46,101,118, 90,172,160, 66, 91, 77,224, 29, 36,126,210,119, 35, 81,137,254, 48,140,231,246,130,157, 23,144, 72,173, 93,109,118, -170, 24,214,185,212,124,221,174,147,244, 82, 84, 41, 86,138,216, 72,229, 50, 23, 42, 86,153,123, 71,109, 22,137,237, 55, 59,245, - 1,101, 51, 34,234, 44,165,115,221,158,131,168,221,238,118, 76,187, 85, 56, 57,196,216,173,231,215, 45,199, 90, 76, 47,166, 19, - 6,182,171,236,180, 46, 36,227, 58,114, 6,230,135,233, 52,103,146, 51,237,110, 59, 63,179,178,119,120, 31, 49, 2,219,249,251, -251,191, 0, 80,151, 42,165, 82,185, 68,140, 41, 62, 81,199, 76,195, 34, 41, 19,169,241, 89, 64,105, 35,149,206,157, 95,209, 36, -185, 63,240, 74,181,163, 92, 38,187,127,188,143,248,187,253,214, 71, 63, 63,216, 93, 91,186,140, 5,121, 92,125,132,172,186,145, -187,178,148,201,255,245,232,143, 73, 57,238,244, 28,108,150, 55,243, 27, 88,123,149, 86,229,225,233, 67,187, 71,129, 9, 55, 71, -120,217, 88,217, 92, 54,178,166, 99,225,179, 96,136, 30, 55, 79,237,190,189, 58,147, 39, 78,180,235,144,248, 59, 23,127, 49,210, -248,236,215, 46, 93,173,182,170,200,197,146, 64,238,193, 73, 45,169,107, 9, 46,221,186,212, 66, 73,254, 51, 79,212,154,135,115, -153,167,215,212,116,236,162, 31,178, 58, 33,207, 19, 16, 63,184,214, 65,157,171, 76, 62, 37,238, 2,147,178, 70, 42,133, 12,122, -136,132,236,198,100, 53,166, 77,170,138, 22, 79, 38,245,132,174,199, 85,185, 85,173,223,249,238,183, 59,191,254,249,119,211,242, - 36, 9,105,196,101,107, 68, 57, 34,197,194, 10,226,123, 68, 20,126, 58,249,231,135,211,189,155,203, 47, 45, 74, 83,175,109,191, -143,155, 87,111,153,234,150,124,254,203,121,251,251,198,206,246,167,223,124,117,187,240,245,238,165,206, 11, 47,126,124,173,244, -197,241,155,247,222,121,239,185,183,179, 98,250, 65, 99,111,175,126, 48, 61, 57,123, 81,159,118,128, 44,168,228,225, 47, 27, 11, - 38, 75,240,231, 51,203,140,109,196,204,212, 44, 66, 10,198, 23, 89,214,236, 90,212, 83, 74,205,117, 84,226, 75,159, 51,238,254, -126,143,196, 61, 38, 34, 24,151,190, 7,136,224, 86,205, 26, 86,243, 43,151, 95, 46,213,203,186,170, 51,161,221, 15,143,107,235, -184,115,214,200,226, 59,211,135, 24, 14, 16, 25, 47,204,174, 52, 58, 45, 60, 59, 16,119, 70, 48,153, 16,194,201,120, 10,176, 90, -215,244,185,233,133,166,213, 24,121, 31,177, 12, 37,235, 67, 72,134,110, 32,187,111,102, 55, 75,205, 83,159,164, 17,252,192,218, - 9,215,197,228, 56, 57,184,134,165,132, 70, 38,215,252, 18,129, 45, 31, 85, 30,168, 59, 41, 36,212,106, 21, 22,149,161,222, 30, -170,160,113,147, 51,251,153,144,206, 38,181, 61,159, 13,104,169,249, 28, 95,249,198,255, 27,119, 8, 67,155,138, 66,140,146,249, - 34, 76,158,154, 89, 9, 5,200,159, 95,146, 37, 10, 66,255, 9, 64,212,181,244,182, 81,133,209,241, 99,102,252,152,241,196, 37, -113, 29,135,218, 74, 8, 14, 36, 21,164, 64,216, 20,168,154,150,170,170, 80,164, 22, 85, 44,186, 98, 1,252, 1, 54, 72,221,176, - 70,176, 67,160,246, 15, 32, 33, 86, 72,168, 72, 44, 42, 89, 66,170, 2, 82, 90,129, 80,226,144, 98,108,167,118, 98,123,252,152, -241,188,239,240,157, 59,137,144,178,115,252,184,119,238,247,188,231,156,239,196,191,199, 49,246, 87, 98, 39,218,146, 49,110,135, - 62,151,144, 4,194,120, 38, 51, 75,137, 21,215, 83, 1,143, 75,224,192,126,198,201, 99,112,112, 49, 17, 25,174,231,112, 1, 99, - 33,186,192, 17,254,247,160,140,235,149,211,217,144,150,139, 85, 58,229, 83, 27,140, 3,250,132, 87, 22,214, 59,195, 78, 2,187, - 76,107,242,163,227, 23,240, 27,122, 8,224, 48,191,144,155,167,100, 28, 14,221,181, 5, 78,204,112, 92,211,180, 38,244,227, 71, -214,136, 27, 97,130, 79, 28,225,115,203, 89,176, 84,172,234,211, 30, 21,245,208,227,143,100,122,195, 8, 20, 26, 33,134, 80, 52, - 49,193, 87,229, 28,218,172, 16,243,163,162, 73, 21,133,100,192,131,228,169,194, 62,111, 27, 97,216, 94,152,146,210, 92, 78, 4, - 55, 29,232,205, 37, 96,102, 73,150,149,164,132,229, 50, 74,138,205, 41, 5, 93,148,102,252, 98, 18,115, 44,165, 36,121,121, 65, - 73, 39,146, 18,224,137,228,154,193, 30,196,136, 7,232,189, 60,109,182,127,173,213, 30, 60,248,233,247,157, 63,175,108, 94,214, - 20,229, 97,237,161,150,149,101, 41,158, 74, 37, 84, 14,141,111, 55,159, 94,187,122,105,106,140,159,117,218, 20,215, 47,172,174, -140,199, 35,242, 76,241, 16,108, 44, 50, 88,211,246, 13,139,162,104,232,121,161,227,241,203, 91, 62,193,253,140,154,187,247,205, -215,163,145,113,239,254,253, 90,173, 70,155,250,254,214,123,119, 62,184,217,106,213, 13,163,175, 41, 41,144,187,229,184,132,137, - 23,244,255, 81,229, 65,158, 61,180, 93,144, 40, 40, 98, 75,224, 80,199,114, 89, 42, 23,146,106,134, 74, 75, 0,243, 57,253, 0, -120, 51, 31,153, 32,190, 46,112,153, 53,101,174, 31,234,150, 41, 81,197, 19, 12, 7,211,190,195,156,130, 82,180,124,183, 90,122, -121, 72,233, 38,212,228, 97, 6,224, 98,112,174,176,152, 16,125, 15, 67,180, 41,114,159, 50,100, 80, 60, 41, 41,176,198, 67, 46, - 9,174,155,131,226, 76,233,195,119, 63,254,183,219, 32,231, 69,133, 20, 57, 86,221,232,173,148, 86,245, 73,159,234,131,197,194, - 11,244,112, 69, 62, 21,107,233,236,242, 65,103, 95, 83,242, 22, 40,139,126, 86,202,221,186,121, 91,239,235,173,227, 67, 19,218, - 24, 78,185,112,174, 63, 58,122,123,237,157,158,126, 68, 81, 71, 77,101,185,178,154,160,202,234,139,229,234,246,222, 35,122,120, -100,192,182,239,154,182,129, 64, 26, 3,203, 47, 4, 45, 5,140,167, 84, 82, 22,144, 66, 26,231, 43,231,159, 28, 60,198,208, 90, -199,238, 13,143,201, 62, 65,169, 85,103,139,149,202,160,215,221,254,235,209,209,176,123,241,165,141,189,214,223, 20,209,181,140, -150, 87,206,212, 15,119, 95, 91,186,112, 54, 95, 24,154, 67,242, 2,229,185,115,187,173,122, 18, 56,165,176, 60, 87,145,161, 73, -208, 31, 27,163,253,195,221, 70,183,241,198,242,235,237, 94,147, 22,117, 99,227, 58,185, 18,203,177, 75,249,121, 9, 84,246,164, -229,152,182,231,192,230,129,185,114, 0, 8, 99,236, 57,117,150, 2,128, 97, 27,185,180,170,102, 20,202,118,149,116,150, 22, 75, -251,237,186,147,137,211,123, 94, 96,133, 13, 77,176,166,130,103, 11,152, 21,199, 56,125, 36, 34,102, 70,112,180, 56,239, 71, 10, -145, 86, 9,109,139, 66,241,215, 91,136,251, 9, 89,200, 21,210,197,209,180,115,240, 79,231,183,253,230, 78,179,123,236, 56, 46, - 20, 41,169, 36, 15, 44, 68,113, 92, 74, 41, 41,113, 94,153,125,115,249,246,100,220,251,242,241,207, 71,182,254,233,210,214,197, -203,119,178,159, 20,238, 46,126,190, 94, 89,213,190,213,186, 63, 52,190,251,234, 11, 91, 9,210,170, 18,230, 98, 79,246,127,121, - 53,190,185,245,209,141,187,223,127,214,254, 35,216,186,114,171,219,216,254,241,112, 39, 72,200,215,231, 87, 12, 15, 98,141, 65, - 44, 92, 44,148, 59, 3,242,203, 51,150,109,210,186,144, 77, 91,147,180,152, 94, 43,175, 61,211, 59,192,248, 70, 8,111, 14,105, -187,180,250,214,110,187, 46,138,128,149,229, 51,218,196, 53,231,120, 89, 79, 25, 64,253,176, 30,128, 85, 71,111, 71, 25,196, 25, - 63, 96,159,210,145,211,178, 90,127,124, 44,162,101, 73,217, 73,181,222,222, 11, 4,159,242,177,171,235,155, 84,207, 1,201, 19, -130,128, 77,167,118, 98,143,209, 75,240,121,234, 25, 48, 73,146,171, 37, 10, 6, 3,142, 18, 4, 56, 53,186,192, 71,163,143,159, -105,170, 30, 24,212, 84,125,158, 39,129,164, 29,139, 18,248, 72, 8, 78,160,167, 95,198,196, 36,207, 38,163, 6, 20,199,227,127, -148,116, 6,124,126, 23,218, 75,140,130,150,142,219, 8,118,170,203,119,210, 35,143, 11,241, 19,254, 82, 24, 49,120,240, 26,228, - 70, 2,191,148, 95, 24, 65,176, 26,190,151, 15, 76,245,121, 71, 46,246,159, 0, 68, 93, 75,111, 27, 85, 24, 29,219,243,244, 99, - 60,118, 28, 39,105,235,164,105, 2,132, 60,160,152, 68, 36, 36, 69, 52, 34,145,216,181, 18,236,144,248, 3,108, 64,130,101,196, -178, 98,197,130, 13,187, 10, 36,144, 64,236,232, 2,164,174, 10, 2, 9, 36, 54,109, 48, 84,173, 99, 7, 59,126, 76, 38,142,237, -120,158, 30,115,190,123, 19, 88,121, 54, 51,158,185,143,239,126,231,187,231,158,243,127,124, 15,152,223, 99,136,145,116,174, 0, -198, 43,236, 84,108, 96, 92, 31,225, 66, 70, 72,184,240,233,162, 71,227, 87, 18,149,190,219,139,147, 55, 8,167,114,115,187,165, -115, 36,128, 79, 32, 19,134,169, 5,179,219,110,116,234,200,130,137, 61, 25,178,201,108,211,113, 68, 77, 73,226,223, 73,195,132, -241,131,144,161, 63, 51,185,160, 72, 42,224, 88, 16,184, 62,242, 84,198,180,193, 99, 53, 89,225,252,107,182,126, 18,212, 82,165, -248,112,196,111, 68,203,106,167,103, 22, 89, 41, 50, 53,206, 64, 24,146,149,179,164,121, 8,208, 92,232,146, 31, 60,102,177, 6, -119,225,133, 85, 5,216,194,183,221, 62,169,243, 8,172, 11, 89,145, 69,147,147, 36,192, 54,164,193,193, 77, 27,216,167, 80,245, - 71,162, 98,142, 66, 28, 87,137,196,233, 85,137,118, 62, 73,177, 17,125,230, 8, 14, 98, 46,214, 41, 63,106, 59, 64,124,100, 2, - 79,198, 52,177, 8,185,151,138, 17,153,184,174,209,141, 87, 54, 86, 95, 90,251,233,151,223, 95, 46, 22,103,174,206,127,243,221, - 61, 63,140,133, 67, 49, 28,146, 25, 67, 48, 20,155,173, 78,241,197,162,174, 27, 15,126,254,117, 44,155,249,228,206,157,118,243, -168, 82,173,196,227, 50,219,119,229,108,122, 18,161,193,133,134, 38, 0,122,192, 27, 8,195,245,181,235, 55, 54, 55,246,246, 62, - 42,151, 75,182, 99, 85, 42,127,253,120,255,123, 4,244,183,110,191, 89, 42,253, 22, 87, 71, 89, 67, 82, 20,188, 51,219,219,103, - 71, 69,201,180, 71,140,158, 43, 73,176,116,142,163, 13,102, 83, 16, 9, 25, 92, 64,118, 65, 42,129,148,118, 83, 25,138,232,152, -204, 59,139,100,241, 36,113, 16,161,157,156,148,164,166, 36,221, 11,221,148,146, 44,155,143,105,223,151, 54,176,135, 76,138,150, -136,170, 88,233, 0,137,182,175,223, 44, 55,171,140,154, 70, 71,234,209,182,151,178, 87,108,111,144, 84, 18,104,224,237, 23,118, -240, 72,179,107,150,170,251,164,171, 69,110,150, 71,205, 78, 61,157, 52,204, 78, 3,235,132, 24,147, 79,186, 38,211,121, 38, 10, - 17, 0,143,235,145,155, 74,167,127,252,236,229,133, 74,243,192, 58, 49, 35, 62,117, 25,102, 17, 38,106,223,177, 55,151,214,231, - 46,205,233, 73, 3, 8,228,105,171,204, 60, 2, 71,173,147, 6,226,230,250,115, 27,200, 30,242,153, 92,181, 85, 81, 21,126, 66, - 0,171,149, 80,200, 77, 99, 4,203, 49, 25, 15,105, 88,245,173,229, 45, 77, 82,254, 49,107,249,204, 68,111,208, 69, 3,220, 88, -217,180, 78, 45,164, 29,245, 86, 61, 36,131, 61,225,181,165,173,102,167,129, 52, 60,167,143,249,158, 91, 51,235,152,171,142,231, - 30, 52, 42,125, 7, 95, 71,192,165,107,159, 98, 44,208,129, 91,118, 86, 20,128,117,101,118, 25,216,108,113,122,241,207,195,125, - 12,201,164,146,106,119, 90, 3,187,135,183, 42,140, 95, 57,104, 30,120, 46,109, 89,239,174,237,174,206,175, 62, 61,122, 2, 76, -152,215,199, 0,225,185, 53, 51,134, 50, 66,127,143,114,127, 62,161,252,158,125, 76,199,218,226,227, 51,130, 55,245,234, 56,201, -249,250,110, 4,195, 56, 18,158, 91,113,252,231,178,199,102,118,200, 78, 93, 80,135,162,139,172,185,253, 35,227,193, 97,187,212, -246, 13, 63,226, 71,219, 21,171,215, 15, 2,155,204, 41, 17,211,113, 65, 26,152, 72, 39, 92,230, 65,152, 82,100,160,202,154, 25, -109,245,172,207, 75, 63,172,167, 87,222,155,127,187,112,247,230,221, 55,190,253,234,241,151, 31,126,253,129, 48, 38,220,123,247, - 83, 53,163, 21,244, 73, 45, 38, 27,162,222, 25,245, 74,143,238, 47,239,236,108,246,183,223,255,227,157,189,233,143,175, 26,217, -207, 30,125, 97,133,225,173, 66,209, 29, 57, 76,198, 53,125, 54,232,219,158,155,142, 39,207, 92, 7,171, 35,176, 32,226, 53,121, - 58, 50,231, 9, 78, 91,103,100,111,170,175, 30, 30,215, 60, 4, 46, 81,101, 38,221,153,116,220,168, 35,155, 38,109, 3, 2,206, -207, 95, 94,244, 3,119,105,102, 9, 17,185, 56, 95,236,219,131,180,166,207, 77, 92, 35,136,233,217,164, 58,142,108,218, 31, 32, -149, 4, 36,202, 27, 19, 15,171, 15, 89,181,134,204,153,153,241, 56,242, 51,113, 50, 61,133, 60,224,245, 91,187, 79, 74,127,103, -211,185,250,113,205,245,108,180,153, 79,210,179, 68,141, 61, 99,132, 46, 46,226,133, 81,193,214, 99, 98,103, 25,137,236,132,145, - 23, 70,140,231, 77, 36, 17,146, 43, 33,178,242, 8, 19,202,197,170,159, 75,229,128, 62, 73,171,142,196,133, 2, 22,187, 72,251, -143, 68, 34,169,116, 17, 17,248,246, 50,247, 61, 26, 93,132, 95,198,129, 51, 18, 70, 38,145,117, 2,155,251, 66,159, 14, 58,124, -229,158,205,207, 2,232, 80,122, 58, 26,106,114,226, 95, 1,168,186,150, 30,183,169, 40, 28,191,237, 56,177,227, 73, 38,175,105, -103,162, 36,109,209,244,161, 14,163,182, 44,202, 2,209,194, 2, 85, 45,136, 5, 18,130, 10,132,202, 15, 96,129, 64, 98, 7, 93, -177,103, 9,127, 0,216, 32,209, 5, 35,218, 25, 80,233, 6,177, 64,213,116, 74,105, 75,160, 73,243,118,252, 72, 98,199, 9,223, -185,206, 2,164, 40,155, 56, 81,124,143,239, 57,223, 57,247,156,239,227,255,163, 4, 30,167,231, 76,250, 97,249, 48,208,125, 82, -111, 72,226,127, 66,174, 49,242,130,223, 31,120, 3, 55, 28, 33,162, 99,169,131,104, 18, 67,247, 36,213, 97, 88, 14, 67,127, 8, - 96, 60, 42,103,203,127,247,254, 66, 48, 19,168, 82, 76,117, 20,153, 26, 0,120, 82, 24, 73,240,254,212, 13,130,113,204,156,192, - 10,214,194,126,243,238,208,235,199, 76, 57,172,204, 26, 31,113, 34,175,153, 2, 77, 11,130, 72, 29,147,132, 72, 18,126,232, 81, -189,133, 84, 61, 41,222, 2,136,225,223,198,211,173, 36,252, 22, 6, 20,153, 24,105,126,196, 86, 6, 43,194, 40,252, 67,210,247, - 8,124,199,183, 1,133, 42,133,163,140,112,156, 53,145,179, 97,170,128,209,112, 51, 81, 2, 58,123, 32, 4,203,210,100,226,198, -154,133, 27,185, 10, 16, 28,144,174, 42,176,161, 83,145, 7,182, 37,150,164, 57, 77, 54, 49, 11, 45, 82, 26,151, 73, 9,166,129, - 28, 95,200,232,184,140, 35, 90,126, 17,119, 23,181,155,173, 11, 47, 94,200, 91,230,238,238, 94,185,144, 63, 86, 41,233,248, 84, - 97,225,157,138,113, 33, 86, 98,181, 80,226, 56,101, 48,244, 95,189,124, 37,119,184,122,233,149,215, 16, 74,166,126, 4,207, 12, - 88, 7, 24,110,234, 98,126, 69, 41,231,213,114, 86, 62,132,247,162, 92, 92, 85, 74,133,180,109,119,224,149,107,149,242,199, 31, -126,112,253,250,103,231,158, 61,117,235,199, 27, 88,236,173,147,199, 3,114,211, 92, 20,136,211, 41,117, 88, 34,192,135, 84, 97, -103,240,159, 6,197, 56, 85,150, 0,202, 52, 69,164,102, 59,129, 87,197, 5,178, 10, 93, 21,140,164,104,165,196,140, 46,153, 41, - 41, 5,144,172,203,102, 90,206,173, 40, 57, 75, 51,224,186,146, 74,164,205,135,115,219,159, 57,147,249,248,169,247,143,169,102, -144, 30,105,178,198,113, 66,181, 80,195,151, 4,198,233, 10,123,181,250,109,198,177, 57, 79, 39,211, 73, 37, 41,203, 90,223,237, -193, 82, 93,183,139,165,222,189,123,179, 61,108,107,138,238, 79, 61,160,230, 83, 27,155, 72,122, 17, 84, 21, 49, 9,231,126, 40, -187, 65,253,191,164, 38, 17,169,162,186,125,228, 76,163,247,152, 14,220,124,219,210,179,219,181,109, 92,249,180,221,196, 79,193, -147,194, 76,200,175,177,101,190,187,115, 35,148,136, 94,175,227,116, 11,153, 66,189, 80,129,125,129,194,116, 89,191,189,127,251, -113,251,209,195,214, 35,142, 29, 79,241,188, 68,195,144,211, 49,130, 10, 18, 2,215,119, 44,221,128,215, 56,104,220,191,245,251, - 94,173, 88, 71,134, 22, 4,158, 70, 99,194, 74, 49, 83, 0,188,242, 70,253, 21, 35,135,212,250,196,250, 49, 0, 47, 62,138,224, -145,115,134,181,185, 94,175, 23,171,139,249,172,158,223,224, 23,209, 51,107, 71,158,244,155,185, 84, 22, 48,224,234,203,111, 87, -139,235,237, 1,178, 88,239,183,251,191,218,126, 31, 16,222, 76, 26,212,140,187, 88,156, 57,126, 86, 97,179,154, 7,141,123, 69, -115,117,173,180,126,118,235,249,131,198,254,215,123,223,192, 83,192,143, 20,173, 50,220, 83, 56,139,181, 13,248,146, 85, 92,203, -173,189,116,250, 34, 41,231, 76,124,182,245,231,164,220,129,221, 41, 38, 24,199,175, 24, 83,199,136, 82, 66, 16, 99, 78,224, 37, - 4,100,119, 77, 12,115,176, 7, 63, 91,252,209,117,127,110, 63,112,230,212,226, 51, 36,160,150,240,231, 64,235, 36, 15,131,236, - 46, 88,176,200, 30,197, 10,145, 36, 72, 13,168,137,133,200,202,242, 78,243, 30,126,237, 82,254,116,237,218,235,209,157,196, 59, - 59,111,188,123,254,253,196,249,196,206,229, 47, 37, 67,233, 5,147,143,126,249,234,205, 31, 62,127,239,230, 23, 13,199, 15,164, -168,245,237, 79, 23, 63,121, 78, 78,100,175,125,255,105,238,232,185,138,150,159,250, 61,123, 22,170,188, 12,159,236, 76,156,225, -100, 36, 73,194,136, 68,183,105,170, 60,107, 88,105, 69, 87, 4, 25, 15,204, 86,245, 36,205,242,113, 36,180,192,196, 50, 40,150, -203,108, 88,186, 51,234,226,229, 77,189, 88,145,132, 81, 47,136,205,193,147,158, 59,128, 65,177, 97, 31,182, 30,132,164,131, 48, -110, 13,137,247, 34,155, 92,169, 23,235,212, 35, 59,153,136,172,110,227,250,182,169, 26, 18,155,184, 94,246,165, 80, 65,134, 26, - 37,105,200,227,207, 22,182, 73,223,233,225, 81,217, 60,124,226,234, 11,111, 1,148, 32,105, 24, 17,179, 35,143,231, 57, 37,167, -225,213,219,195, 14, 86, 53,111,228,177, 96,125,167,139, 28,162,227,118,136,163,153,209, 14,215,242,245,142,221, 30,186,182,231, - 59,240, 65,182, 75, 7, 69,192, 43,228,116,168,239, 99,102,105, 25, 25,240,113, 1, 16,166,148,204,210,210, 57,179, 88,158, 84, - 52, 93, 51,168,189, 74, 49,102,164,107, 56,118,199, 35,137, 83,150,245, 18, 54, 94, 12, 27, 33,188, 5,100,174,121,140,132,255, - 21,128,168,115,137,109,163,138,194,240,120,102, 60, 51,182,199,111,198,142, 83, 39,177, 13,184,233, 67,105, 19,161, 54,180, 85, - 89,176, 97,209,125, 43, 36, 4, 75,246, 72,236, 80, 97,133, 16, 66,108,144, 64,236, 42,182,116,129, 64, 44, 64, 65,130,164, 16, - 9,132,170,134, 87,139, 20, 72,147, 38,177, 61,113,198, 30, 63,199,158, 49,231, 63, 55, 9, 91, 43,138, 61,115,239, 61,231,220, -243,248,254,147,248, 29,249, 56,178, 47, 25, 51, 43, 51,169, 74, 69,155, 45, 79, 1,160, 34,227,255, 95, 93,149,196,236, 33, 28, -138, 21,207,211, 69, 88,131,166,104,224, 31,137,244, 65,127,149,167, 61,133, 34,171,194, 67,186, 90,163, 83,231, 66,160,224,128, - 2, 34, 17,136,142,126,209,211, 47, 29,195, 20, 36, 48, 25,208, 17, 44,244,213,142,175, 11,104, 63, 82,194,185,212, 84,148, 15, -191,112,222, 50,183, 58,197,116,115, 26,149, 58,151,177, 98,200, 4,176,138, 94,144,139, 79,129, 71,113,226,187,216, 1,122, 99, -192, 51,227,209, 52, 19, 17, 16,243, 28,118,155,205,110,131,161,228, 82, 68, 53,170,197,121,122,107, 71, 40, 73,238, 47, 63,150, - 58,132,227,129,116,184,223,115, 6, 54,121,254, 66, 62,134, 36,123, 24, 26,167,138, 76,151, 53, 89,128, 4, 56,150,226,177,166, -137, 64,196, 76, 88, 62, 1,221, 47, 67,174,208,180,218,205,115,103,171,197,233,252,202,119,223, 94,122,110, 81, 11, 43, 15, 31, - 61, 18, 3,171, 18, 24,212,163,133,115,243,183,110,222,252,242,139,187,253,174,123,251,157,219, 31,125,240,254,229,229,229,218, -222,222,230,227,109, 21, 96, 0, 31, 86,111,226,105,106, 96,104,129, 6,129, 43,116,220,211, 89,142, 24,234,149,107,215,239,173, -221, 51,140,200,171,175,189, 94,168, 44,207,156, 74,174,172,124,115,186,122,222, 48,204,181,245,251,126, 16, 30,141, 5,201, 85, -230, 73, 88, 52,147, 49,240, 7,115,139, 60, 1,139, 60, 15,126,191, 63,241, 70,194, 10,156, 80, 99,209,122, 25,213, 21,114, 93, - 98,122, 22,221, 59,225,144, 25,149,227,166,172,199, 67,180,103,129,166,151, 21,140,165, 76,252, 84, 36,211,245, 92, 10, 37, 48, - 84,130,250,178,108,198, 18,118,251, 96, 76, 49,190,145, 52, 52,253,160, 85,215,128,228,209, 98,168,152, 37, 41,138,167, 69,135, - 27, 13,133,210,241, 52,133,165,244,191,154,110, 83, 83,148,238,208,165, 35,173,201,250,112,220, 35, 7, 4,249,133, 65,103,206, - 42,237, 29, 62,161,131,120, 42, 91,220,111,213,154, 29,135,246, 33, 35,188,163,100,178,200, 61, 84, 10,229,234,236,153,243,103, - 23,103,175,156,249,113,117,149, 30,216,118,234,170, 26,110,182, 15, 83,102,114,199,222,245,198, 67, 58,135,182,107, 83,184, 64, - 63,114, 46, 87,202,167,115,123,135,251,244,118,102,159,154,163, 79,104,177,208,173,129,130,249,104,204,202,215,134, 28,161, 0, -112, 99,115,195, 74,100,182, 26,219,180, 81,233,235,158,153, 42,175,255,181,206,205, 27, 48,130,233, 72,154,204,183,149,200, 38, - 99, 73,178, 56, 75,149,133, 6,148, 70, 90,165,153,106,127,212,255,249,207, 95,218,253,206,229,211,151,232, 90,227,116, 28, 5, -164, 38,223,237,117,232,235, 10,169, 92,189,181,111, 59,141,165,242, 5,238,135, 25,215, 15,118,123,237,246, 8,186,193,170, 3, - 62,244, 48, 99,166,154, 93,135, 30,159,243,230,126, 84, 55, 94,186,248,226,247,191,255, 64,207, 66,215, 14, 90,174,100, 36, 69, - 49, 93, 53,170,231,175, 77, 73,253,190,228,121, 56, 16, 33,102, 70,138,145,247,224,136,206, 45,210,160, 62,199,239, 19, 95,217, -111, 36,106,222,144,108,155,231,135,210,122, 34,162,217,143, 29,151,236,251, 0,184, 80, 16, 3,134,244, 22, 24,175, 37,230, 18, -233, 47,162,134,108, 41, 51, 31,110,172, 30,122,238, 39, 23,222,200,190,183,248,242,210, 43,187,189,230,231,119,239,116, 62,253, -109,115,235,254,103, 59,171,119,254,248,234,121,171,116, 99,246,162,239,247, 63,126,248,117, 33, 93, 76, 59,157,167,111,188, 16, -255, 53,243,238,223,111,190,125,253,173,157, 39,255,172,217, 63, 45,230, 23,114, 58, 45,223, 68, 57,226,117, 9,197,139, 80, 50, -158, 48,181, 72,207, 27,248,128,149,122,117,231, 64,216, 93, 81,137,189, 58,127,149, 94, 11, 93,119, 56,152,148,172,132, 69,139, -130, 99, 8, 29, 45,137,174,251, 40,173, 15,122, 61,138,148, 19,217,128, 83,221,244,240, 67,192,195, 37,238,202, 11,158,205, 87, - 40,144, 31, 51, 7,148,182, 34,172, 7,186, 15, 1,133,246,241, 97,136, 35,226, 18, 5, 13,245, 90, 45,101,162, 30,163,134,195, - 20,194, 63,248,247,129,174, 27, 19, 48,207,135,130,193, 0,249, 17,145, 51,225,110,149, 1, 72, 18, 2, 10,128, 10, 92, 4,129, - 80,116,171,190, 5,113, 40, 58, 35,156,147, 25, 12,250,160,164, 5,220, 65,131,180,155, 69,215, 86,216, 40, 9, 24, 21,161,134, -196, 60,102, 85,197,204,221, 0,154,239, 12,139,166,168, 72, 76,210,186, 16,168,242,201,215, 77,103,139,110, 31,187,162,146, 43, -207, 89,229, 93,123, 91, 69,207,139,255,159, 0, 92, 93, 75,111, 27, 85, 20,158, 25,199, 51, 30,103,252, 24,199,174,237,144, 52, -161, 41, 1, 53, 41, 78, 19, 12, 45, 47,169,145, 88, 65, 75,149,240,144, 88,128,216,241, 11, 16, 27, 88, 68, 2,177, 66,108,216, - 34, 30, 18, 20, 9, 36,246, 64, 68, 87,172, 72, 42,213,105,147, 10,147,166, 36,105, 82, 26, 63,198,206,204,120,230,142,205,249, -206, 56,141,132,151,246,104, 60,154,123,239, 57,223,121,125,223, 49, 63, 1,211,164, 5, 54,228, 10,189, 48, 32, 96, 36, 47,254, -215, 23,143, 17, 3, 20, 90,209,189,142,220,179,172,116, 2, 95, 58,134,246,204,238,197,114, 76,180, 41, 7, 85,157,238, 6,110, -128,176,158,115, 20, 44,244,152, 26, 43,252, 80, 28,144, 49,114,244, 58, 98,170,238, 35, 93,133,178, 38,115, 2,247, 95,151,212, -239,134, 21,150,107,177, 70, 40, 86, 42, 84, 32, 7, 72, 23,174, 17, 79, 90,118,163,159, 77,228,198,198,168, 18,229,170, 90,191, - 84,219, 87, 39, 15,205, 21,134,191,209, 42,200, 50,231, 48,189, 20,220, 13, 49,113, 57,197,116,105, 61, 93,183,235,126, 23,244, -197,160,153, 12, 4,217,202, 99,121, 25, 78, 87, 82,200, 70,187, 32,107, 26, 61, 84,204,209,142,226, 7, 82, 56,193,196,188,119, -189,136, 20, 50,202, 65, 16,141, 44,182,237,118, 15, 15, 9, 94, 1,185,130,168, 36, 16,219,119,255,126,245,242, 43,169,164,118, -107,227,250,115,207,206, 85, 55,174, 15, 68,187,244, 75, 33,151,121, 99,113,225,237,119,222, 93, 89, 89,185,122,245,135,215, 22, -174, 60, 50, 50,182,180,244,113,177, 56, 60,123,238,220,175,191, 45,147,231, 84,186,242,220,204,204,216, 8,133,182, 67,166,145, - 73, 39,211,169,244, 16, 25, 74, 85, 29,116,237,222,197,249,151,111,175, 87,215, 42, 27,186,166, 78, 78,140,110,254,117,103,249, -151,223,203, 79,157,167, 96,227,218,181, 63, 6, 20,205,131,152, 37, 11,232, 69,250,226,218,132, 92, 5, 70,177,144, 79,167, 99, -236,249,136,219, 21,176,248, 50, 21, 65, 84,137,199, 36, 67,135,202,143, 22, 37,251,174,128, 18, 28, 44, 12, 72,127,106,228,222, -116, 89,143,225,237,210, 86,176,218, 78, 76,142,130,210, 79, 82, 90,157, 38,185, 63,193, 83,202, 40, 92, 48,159,115,222, 44, 96, - 56, 80,142, 16, 38, 34, 83, 27,101, 38, 6,250,219,189,250, 94, 54, 85,160, 11,146,144, 25, 81,118,107, 56,165, 22,184, 3, 5, -156, 8,235,199,147,161,247,124,159,118,151,105,152,167,242,167, 86,171,127,134, 19, 24,116,108, 36,112,236, 1,148,208,153, 36, -132,219,114, 44, 58, 84, 19,197,199,111,110,173,217,162,115,101, 97,241, 96,235,193,173,234, 13,120,238,160, 75, 16,207, 34, 91, - 41,220,100, 44,209, 68,206, 4,222,220, 21,182, 11,245,143, 58,173, 90, 66, 55, 48,117, 37,201,205,118, 99, 40,153,163,213, 36, -124, 61,108, 22,204,184, 73, 16,175, 52, 93, 58,243,194,108,176,111,215, 90,117,250,178,104,230,125,225,154,208,225, 11,201,170, -122,100, 26,138,233, 66, 49, 83,168,108, 85,200,136, 86,239,111, 90,110, 27, 82,112,116,147,116,161,237, 52, 71,179, 35,166,145, -170,220,169,144, 99, 59,123,114,106,251,254,246,139,103,159, 47,141, 77,217,126,167,222,120,240,228,163,165,213,205, 85,109, 64, -107,216, 22, 40,177,208,181,229,122, 61, 65, 80,157,182,168,166,197,201, 63,209,235, 31, 63, 49, 78, 75,176, 83,191,119,115,231, -182,227, 30,146,191,108,161,169,151,108,181, 77, 72,100, 44, 18, 27,190,144,165,136, 87, 66,155,118,192, 44,190,253,158, 2,150, -144, 12, 5,223, 37,142,222,144,114,145,125,245,159, 90,170, 73, 7,185,171, 76,142,206,136,246,110, 68, 61,216,181, 92,116,181, - 6,221, 78, 0, 86, 20, 92,204,237,222, 62, 87, 33, 19,154,154,212,212,123,174,245,245,122,165,172,142,126,240,249,151,206,158, -120,235,139,215,191, 90,248,126,250,210, 99,203,159,126,251,201,250, 79,107,181,205, 15,203,111,150,242,167, 83,131,137,103,242, -147, 19,241,252,103, 55,126, 44,106,217,151,158, 88, 44, 63, 61,183,244,243, 71,239, 37,223, 79,100,229,111, 54,190, 59,147,159, -158, 74,145,103, 18,202,195,166, 63, 60,104, 55, 54,160, 57, 62,132,229, 67,181,104,229,161,166, 50, 83, 11,236, 32, 85,226,106, - 81,149, 80, 41,172, 60,186, 18, 29,136,167,113,103, 75,198,200,112,158, 0, 92,140,134,158, 40,159,158,181, 64,104, 8, 92, 23, -150, 31,200, 46,253,219, 58, 32,104, 45,129, 61, 70,167,205,232,116,192, 95,203,124,100,130, 21,229,144,190,106,195,215,162,135, - 65,141,170,180, 4, 1,235, 56,162, 5, 62,160, 7,243,122, 71,147,152, 97, 2, 91,102,223, 9, 14, 56, 25,148,139,185,196,137, - 54, 43, 11,121, 20,218,121,157,249,210,124,117,191,170,160,136, 5,152, 6, 40, 69,182,253,104,146,214,233,216, 2,105,153,144, -240, 44,100,115,236, 73,253,204, 48, 82,179,190,239, 13,234,137,241,220,248, 78,109, 91,230,233, 60, 8, 48,176,240, 29,178,127, -140,220, 14,157,246,126,131, 51, 84,172, 59,241,159, 0, 84, 93, 75, 76, 27, 87, 20,157,241,119,108,143, 33,224, 4, 25, 2, 73, -156, 15, 42,136,162,198,142, 13, 89,144,152, 46,250, 17, 69, 68, 73,182, 81,149,125,151,149, 74, 54,169, 88,118,213, 5,234,170, - 89,147, 42,202, 34, 74,212, 42,171, 86, 40, 11, 20,201,136, 32,146,242,181, 45,138, 1,127,176, 61,129,241,252, 60, 51,238,189, -247, 77, 34,199, 43, 75,150,173,241,155, 55,231,222,251,238,185,231, 56,254, 30,204,218,137,145, 23, 57,206, 25, 39,192,177, 39, -142,227, 63,113, 76,167, 17, 50,122,134, 1, 25, 76,154,176,193,201,183, 54,244, 71, 13, 29,191,136, 86, 80,104,182,104, 57,126, -130,237,252, 74,174, 61, 28,224,185,200,249, 72,172,114,130, 10,215,236, 67,122,211,150,121, 59,232,236,248,203,178,126, 5, 99, - 62, 49,248,134,228, 8,254, 34,224, 99, 88,232,208, 49, 91,180,131,222,160, 24,232, 48, 12,149,241,245,105,209, 49, 41,104,209, - 65, 1, 20, 1, 72,181,105,153,196,111, 65,169, 3,108, 70,147, 15, 92, 25,109,122,240, 84, 10,253,131,120,180, 10, 51,144,113, -143, 34, 57, 16, 96,162,167,206,226,240,164,139,247,187, 67,126, 18,100,135,251, 14,121,174, 6,185,141,193,153, 38,175,104,216, - 3,211,154,166,162, 90,186,134,247,191,161, 89,104,153, 10, 33,135,200,148, 36,187,224, 58, 40,214,182,183,243, 83,223,124,119, -225,252,224,200,104, 34,191,179,155,205,239,193, 79,141, 12,141,140,143,141,191,120,254,124,225,143, 39,128,161,179, 15,102,159, - 61, 93,200,230,183,234,213,202,244,204,244,230,191,239,228, 19,169, 83, 20,239,204, 76, 79,166,211,241,209,209, 84,106, 44,149, - 74, 78, 76, 76,164,211, 95, 38,175, 37,110,220,156,140,246, 70,107,149,210,242,202,242,234,155,213,151,127,254,245,106,113,241, -189, 44,223,190,117,251,168, 90,126,247,118, 45, 36,250,125, 30,100,194, 64,222,109,163,112, 95, 11, 37, 18,109, 64, 73,216,223, - 44, 0,243,164,159, 67, 18, 63,228, 90, 73,242, 73, 60,169,190, 65,205, 8, 91,156, 11, 10,124, 56,200, 9, 66, 11, 50,247,206, -176, 75, 0, 68,247, 33,132, 83,230,131, 26,155, 46, 11,155,208, 77,124,138,220,140, 79, 11,181,148,106, 42,210,113, 13, 42,101, - 30, 73,253, 72,206,133, 72, 49,121,245,171,157,131, 45, 64,237,238,112, 4,214,185, 43,212,157, 43,229, 80, 74,222,227,135,245, -199,206, 39, 41,126,232,166,122, 49,122, 25,194,176,224,243,194, 74, 14,246, 13,102, 15,178,201,228,248, 97, 97,223,230, 97, 67, - 55,206, 70, 6,246,235, 5, 26,229,199, 84, 67, 55, 84, 49, 40, 86,234,149,225,161,225,245,141,181,163, 92,105, 99,103,237, 88, -174,163,255,223,113, 53,253,121,186, 88, 47, 37,174, 92,157, 74,125,155,217, 90, 33,107,121,148,147, 51, 81,125, 90,247, 83, 75, -211,166, 42,134, 4, 89,105, 3,243, 28,212,203,215,135,198,142,164,170,169, 24,153,215, 75, 0,175, 69,233,240,116, 71,183, 36, -215, 1,253,206,245, 95,210, 27,120,110, 78,182, 54,103, 78,133, 58,214, 11, 27, 3,145, 62,184,126, 69, 83, 99, 61, 3, 53, 5, -202, 11, 55,100,103, 62, 4, 44,237, 77,110, 21, 77, 14,188, 94,168,235,225,201,221, 45,237,254, 87,217, 43, 86, 15,227,151,227, -213,247, 21, 21, 47,195, 75, 46,222, 30, 0,119, 64,183,216,153, 11,101,169, 12, 87, 24,242, 7, 12,114,182,170,201,117, 5, 21, - 17,220,128,115, 16, 45, 6, 78,199,234,114,217, 67,250, 4, 46,206,114,107,218,208,205, 94,136, 14,136,239,200,118,177, 63, 48, -118,217, 88,135, 99,237,140, 85, 26, 65, 24,103,136,171, 37,184,101, 56, 46, 84,150, 42,227, 61,209,162,190,123,212,128,184,130, -167,159, 38, 89,211,178, 41,216, 38,125, 17,150, 38,232,241,118, 6,130, 93,130,235,159,124,241,167,216,189,248,252,215,223, 39, -238,101,213,253,199,153, 71, 39,243,153,159,255,254, 45, 35,231, 30,198,239,134, 4,159,212, 60, 1,104, 83, 57,253, 11, 0, 38, -169,182, 80, 88,186,239, 79,118,253,120,233,215, 95,126,151,100,207, 15,137,251,115,203,115,253,221, 87, 38, 35,231, 36,171,193, -115, 31,133,206,240,140, 2, 42, 45, 8,237,168, 27, 67,174, 38, 22,181,136, 93, 45,206,225,119, 18, 31, 8,176, 24, 29, 2, 90, - 40,166, 79,138,100,142,237, 18,228,191, 33, 1, 69,229,116,203,144, 21,185,183,171,103,125,111,147,228,180, 92,108, 30, 42,128, -202,220, 1,114,112, 67,238, 53,211,129,104,199, 42, 0,135,207,250, 7, 81,252,142,119, 59, 41,175,109, 17,166, 97,173,192, 35, -107,185, 83,113, 20,203,201, 41,130, 65,189,211,226, 0, 76,111,202, 90,131,177, 63, 16, 76,173,102,174,152,163,192,218, 34,239, - 32, 14,118, 62, 49, 90,108, 38, 19,105, 51, 66,185,131,144,204,182,156, 20,249,108, 8,177,144,113,138,128, 46, 90, 83, 41,212, -246,169,201,137,169,111, 24, 71,240, 52,219, 57, 81,199,195, 12, 40, 20, 20,181,129,146, 84,244,250, 95, 0,178,206, 45,198,137, - 50,138,227,211,206,116, 58,211,105,103,182,180,179,237,238,178,247,134,203,118, 23,221,184,139,132,136,160, 98, 98, 98, 98, 98, -130, 62,193, 3, 36,132, 23,158, 73,240,141, 24, 19, 19,195, 3,111, 10, 24,125,215,144, 37,236, 62, 0,137, 15, 96,150, 68,225, - 5, 84, 86,151, 66,157,189,245,126,153,157, 94,102, 58, 23,207,249,190,182, 49,154,244,161,153,135,185,126,223,249,254,231,124, -231,252, 78,159,255, 78, 91,161,122,253,224, 59,109,151,215,195,191,211, 44, 20,150, 34, 97, 93,198,241,122,182,222,235, 53,217, -253,151, 69,118, 97, 8,162,233,103,104,214, 51,243,159,223,255,109,125,209, 40,146,154, 5,182, 15, 63, 67,124, 7, 43,146,147, -208,237, 5,166, 47,195, 89,196, 58,139,150,107, 83,219,129, 81, 3, 66, 89, 99,104,223, 7,215, 30,218, 51, 90, 54, 10,232,225, - 82,162,154,231, 5, 56,129,210, 78,226, 17, 85,149,147, 53,163,226, 58, 52, 33, 18, 70,140, 77,140, 63, 66,130, 38, 7,167, 73, -250, 16, 12,104, 11, 89, 5, 20, 13,129,115, 8,243,155,224,211,130,115, 67,202, 33, 88,208,183, 97, 65, 84, 20,220,127,231,112, -147,147, 85,194,136, 24, 19, 48, 37, 30,198, 37,162, 34, 21, 41, 16,149, 56, 37,204,201, 97, 78,137, 4,224,143, 24,192, 86, 47, - 60,239, 23, 5,127,173, 94,126,252,228, 87,215,178, 36, 41, 82,171, 26,207,215,214,193,170,110,109,111, 60,252,249, 97, 38,147, -129,103, 76, 77,143,207,165,103,111,220,252,118,104, 80,133,155,159,157, 57, 48, 50,172,254,241,252,105,179,109, 62, 88,125,244, -195,173,165, 91, 75, 43,203,203,119,239,220,185,123,255,222,253,229,219, 75,173,134, 49, 54, 49,137, 45, 32,246,142, 45,188,177, -152,218, 55, 99, 89, 78,181,102,140,143, 78,156, 57,123,254,250,215,223,253,246,103,182,186,219,105, 17,165,106,163,201,238, 49, -125, 24, 18, 85,193,184, 8, 2, 24, 88, 68, 76,250, 9,207, 13,151,109,236,180, 20,244, 73, 2, 27, 18, 60, 57,226,151, 66,140, - 36, 98, 47, 11,144,206,176, 78,240, 65,134,236, 73,248, 44, 11,253,122, 28,114,188,195,154,193,132, 52, 28, 10, 72,245,102, 25, - 92, 75, 58,248,100,113,192,236,180,143, 30,125,107, 44, 53,170,101, 55,224,130,224,111,110, 21, 54,193, 2,137, 1, 73,111, 86, - 64,191,111, 85, 52, 7,121,188,130, 31, 19, 12,204, 78,199,129, 11,193, 23, 28,129,153,111, 84, 75,122, 49,185,103, 8,190,241, -139,220, 11,129, 21,230, 23,231,243, 90, 62, 38,199, 91,166,161,155, 58,213,242,176,114,165,199,211,185, 90, 1, 70,136, 24, 8, -197,135, 85, 77,203,194,193,169,196,228,102, 65,107, 88,134, 44, 41, 37,189, 4,162,117,109,251,175,213,223, 87, 65,209, 95,248, -224, 92,102,231,101, 7, 35, 86, 20, 72,138,210, 9,201,152, 88,146,206,189, 61,119,108,125,107, 61, 41, 39, 54,138, 27,207, 94, - 61,179, 9,206, 9,236, 78,122, 98,230,239, 92, 22, 44,172,196,135,242,181,252,107,233,197,151,218,186,196, 11, 45,187, 13, 70, - 92, 8, 74,170, 28,215, 74,155,224,209, 31, 62,184,240,254,235,199, 87,215,126,217, 27, 27, 43,212,243,224,200,130, 15, 26,226, - 96, 34, 74,213,102, 29,204, 4, 92, 5,116,217,187, 39, 62, 42,230, 54,171,141, 42,234, 9, 31, 51,168,196,131, 28, 47,240,161, -143,223,251,212, 51,173,242,110,197,104, 27,162, 32,165,134,167,178, 5,141,212, 95,227,108,133,119, 5, 38, 12,188,141, 58, 2, -242, 56, 85, 73, 88,118,195,207,249, 84,134,219,255,206, 40,195, 97,118, 20,145,106,148, 21,136,154, 13,247,151,187, 32, 25,207, - 38, 49,117,108,152,220,138,242,145, 35,160, 69,109,167,101, 57, 94,148,109, 21,172,109, 29,183,212, 61, 11, 57,189, 46,209,106, -164, 6, 5,167, 12, 70,245,144,116,196,243, 97,129, 63, 20, 11,159, 62,247,121,112, 36,113,234,139, 83,223,188,121,115,126,118, -238,251,171, 95, 94,203,174,124,118,248,147,168, 32,236, 98, 17, 9,237, 11,130,233, 55, 11,177,169, 31,179, 63, 69,235,225,227, -151, 63,124,114,253,233,202,206,242,165, 19, 23,175, 60,250,106, 64, 30, 60, 25,159,172,217, 77, 90,142,137, 11, 43, 38,253, 96, -155,198,122,187,129,247,225,103,122,157,158,186, 54,132,166, 82, 83, 24, 11,152, 14,158,231, 65, 16,195,219,136, 41,113,189,165, -211,248,240,190,228,116, 38,151,193, 22,213, 62,111,187,188, 67,192,153,221, 19, 81,154,155,213,193, 76,155,228, 64, 18,180, 48, -211,107, 96, 71, 74, 29, 29,212,118,142, 89,174,151, 7, 66, 81,240,142, 97,241, 8, 32, 52,137,202,109,111,215,212, 77,155,176, -205,145, 34,201,208, 76,101,143, 38,197,147,187,131, 35,132, 70,215,233,149,130,118,155,171, 18,114,170, 27,100,131, 9, 57, 9, - 14, 34, 46, 71, 4, 47, 79,131, 15,221,135,235, 23, 87, 50,221,251, 33, 5, 83,109,234,218,168,114, 2,247, 23, 17,130, 45,131, - 31, 76,178,189,253,211,201, 84, 69, 47,185,216,208,205,162,137, 82,212,192,254, 35, 0, 89,215,210,219,196, 25, 69,103,198,243, -242, 99, 98,143, 1,199,128, 18, 71, 8,147,130,148,178,224, 89,169,155, 46,168,132,144,248, 21,172, 88,241, 11,104, 37,216,118, - 83,241, 18,168,170,170,110, 88,118,137, 42,177,168,130, 32,130,240,134,162, 4,168, 72,128,188, 60,118,252,152,204,196,246,120, - 62,206,189,223,152,148,214,202,194,177,199,246,188,190,123,207,125,157,163,166,169, 16,147,232, 55, 41, 91,212,159, 91,110, 36, -161,142,255,242,145, 48, 3, 15,211, 39, 95, 90,121, 85,249, 15, 98,255, 76, 39,243,191, 23, 5,205,214, 27,196,218, 19, 71, 91, -249,125,149,201, 97,146, 79,197,204, 49, 34,249, 44, 57, 71, 60, 12, 0, 52,206, 40,194, 3, 3, 55,241, 13, 68, 94, 95, 48,221, -189, 66, 2, 70, 89,203,180,136, 25, 92,229, 68,132, 80, 16,128,167, 20,109,212,221,217,242,215,153, 49,110,248, 53,236,135,178, -150,163, 27,102,203,111,224, 37,156, 65,156,187,183,203,115, 9, 9,147,194,230, 15,161,183,229, 8,165,167, 83,197,217,192,253, -125,236, 96, 89,183,180,129,208,194, 94, 44,197, 19,164,238, 76,208,143,104,176,154,233,177,177,153, 97, 10,182,131,228, 70,168, -185,144,148, 58,128, 23, 52,146,125,236,119, 45,152, 73,221,128,217,165,225,111,234,173, 37,177, 36, 34, 1, 84,181, 29,133, 17, -236,216,207, 87,174,122,158, 7, 40,247,242,217,139, 27,191,253, 26,132, 93,106, 89,165,161, 8, 34,212, 52,137,110, 12, 75,161, -127,233,242,229,191, 95,190,154,254,235,142, 91,220, 54, 14, 75,191,119, 79,165, 82,209, 17,106,165, 51, 15,103,238,157,191,112, - 17,171,229,251, 19,223, 29, 57,116,120,118,246,225,244,189,187, 41,226,241,192,122, 30,116, 35,209,167, 2, 15,214,146, 48,216, -135,115,175, 46,129, 10, 74,178, 99,231,201,234, 19,138,147,250, 96,172,122, 13,232, 65,247, 80,164, 14,240, 36,236, 10,132, 41, - 1,188, 58,119,152,227,240,202,113,126, 95,105,234,201,135, 71,248, 52,183,106,209,184, 25, 76,188,155,113,231, 62,190, 66, 96, -131, 72, 11, 17, 37,139, 42,232, 92, 15, 76,186,155,220, 76,209,107,175,193,215,178,152,198, 38, 11,169, 11, 93, 49,199,118,140, -175, 53, 87,176,206, 77,221, 60, 92, 61,242,104,126,118,188, 52,209,232,120,176,236, 68,176,159,178,195, 94, 72,249,116,183,220, -232,212,178,182,147,179,115,245,118,125,106, 98, 10,231,109,126,105,142,146,114,164,147,162,150,183,151,219,237,118,221,247,138, - 57,247,192,216,228,211,119,207,221,116, 62,236,245,154,155,141,141, 96, 67,176,238, 21,220, 0, 54,182, 82,166,147,118, 16,234, -173, 52, 62,192,106,184, 89, 55, 37, 16,183,233,114,106,241,192,238,234,219,229,215, 92,231, 84,129,144, 38, 74, 21,195, 52,222, -215, 22, 1, 2, 13,221,128, 87,184,253,228, 54,245, 50, 10, 92, 98, 10,223, 38,119,239,107, 5,205, 90,103, 29,219, 23,156,162, - 99,229, 70, 50,206,204,252,125,156,235,180,157, 65, 0, 10, 27,132,163, 35, 18,127, 88,237,148,133,155,137,169,159, 8, 99,246, -185, 31, 3,191,235,228,242,171,141,101, 30,149, 84, 71, 11,165, 77, 46, 2, 19, 49,145, 74,228, 51, 88, 41,142,157,141, 69,160, - 27,218, 87,131,212,169,139,199, 21, 61, 80, 26, 77,165, 27,208,196,132,252,235, 15, 20, 34,115, 4,174,232,135,196,130, 55, 32, -121, 83,160,153,166,251,216, 43, 91,233,130, 31, 52, 96,195, 38, 11,254,139,245,215,173,144, 26, 59,122,220, 63,195,186, 63, 48, - 42, 36,139, 12, 51,141, 43,154, 79,155,149,252,136,155,201, 25, 74,116,116,255,233, 63, 31, 7,231,166,127, 18, 15,132,247,251, -173,111,175,157, 25,117, 71,207,126,125, 34, 80,162, 78,224,235,178,233,139,218,205,244, 9,167,244,227,253, 63,222,173, 46, 45, -204, 45,222,250, 97,230,228,205,111,196, 89, 49,246, 75, 53,179,173,120,253,208,233,197,176, 38, 89,109,113,188,182,157,238,248, - 29,248, 18,211,178,125,191, 29,145,158, 53,183,136, 83,174,137, 88,176, 72,219,154, 64,155,106,155,217, 40, 34,130,129,186, 95, -199, 46,239,221, 85,125,179,252, 15,163, 55,170,177,215, 58,181,227,213, 99, 43,173,149,133,181,247,178,164,204, 98, 83, 49,219, - 98,141,175, 81, 47, 41, 12,254, 27, 59,139,184, 90,174, 46,120, 11,146,172, 16,239, 3,221, 3,173,227, 39,168,233, 80, 51, 55, -200, 31, 8,230,147,144,253,120, 9, 56,166,124,192,128, 26,137, 1, 46,183, 59,178,217, 41,150, 68, 16,169,132,231, 39, 49,154, -154, 38,251, 12,165,140,238,240, 27,152,253,149, 70,117, 88,138, 0,232,145, 52,165, 98, 26, 79,147,111, 69,146, 60, 56,102,117, -231, 88,184,217,130,223,221, 32,205, 72,250, 95, 12, 67,147, 33, 91,131,166,125, 18,128,177,179,233,109,163,138,194,240,157, 79, -207, 56, 83, 39,113,155, 56, 56,196,168, 13,109,196,135,132, 16, 44, 16, 82, 5, 98, 81,118,116,129,216,193, 15, 64, 72,176, 40, - 66, 72,101,131,216, 33,254, 68,133,144, 42, 85, 44,186,128, 61,155,210, 64, 22, 96,154, 52,106, 72, 34,218, 20,236,120,236,177, -199, 30,207,120,230,206, 29,206,123,239,184, 91,240,214,214,100,124,125,115,230, 61,247,156,243,188,102, 25, 68, 89, 57,164,250, -127,130,251,147,119,243,146,163,206,180,185,202,214,231,111, 22,236, 63, 94,115,116, 33, 69,118,249,192,153, 99,232, 97,164, 11, - 98,184,145,137, 68, 29, 22,145, 22,163,223,149,116,103, 73, 28, 99,186, 3, 2,109,172, 34, 2,230,212,225,240,137, 26, 58,250, -242, 81,236, 44,148,237,225, 48, 26,168,108, 64, 57,223, 57,150,251,201,213,143,190,254,254, 27,202,145, 13, 12,151, 50, 89,190, -200,231,220, 83, 49,141, 6, 76,166, 79,221,225,227, 94,216,149, 94,136, 42, 1,192, 39,161,106, 37,255, 18, 92,126,116,236, 88, -191,237, 14,158,223, 92,209, 44, 10,197, 66,218,221,225,249, 12, 37, 88, 86,151, 53,145,241, 81,156,151,127,159,149, 60,100, 52, -147, 40, 50, 36,206,247,237, 41,252,189, 57,134,155, 13, 33, 63,165,225,164, 32, 7,176,225,159,211, 96,101,121, 41,141,249,103, -215, 62, 31,134, 99,196, 65,189, 0, 69,192, 32,245,100,200,161, 69, 73, 10, 34,149, 54,227,253, 94, 16,244,253, 95,119,182, 81, -150,128, 47,184,112, 42,206, 83,107,141,245,141, 86,251,143,123, 85,219,186,180,217,188,254,229, 23,204,108,188,241,230,229,135, - 31, 31,159, 6, 62,221, 66, 52,205,149, 53,176, 65, 97, 20,103,234,232,234,197,190,130, 1,167,129,210, 49, 60,224,138, 56,197, - 92,107,197,102,174, 3, 63,147, 25,114,117,220, 42, 23,168, 33,147, 34,194,253,160,118, 2,153,146,240, 98,148, 71,251,157,223, -233,199,171, 56,149, 56,201,159, 93,219, 58,238, 30, 69, 73, 68,129, 44,133,147, 28, 39,193,174,108, 11, 92,138,157,210,228, 33, -156, 12,117,221, 28, 76,124,250,103, 33, 81, 60,138, 3, 90,126,199, 6,255,108,198,209, 5,136,250,191, 16, 31,188,245,254,237, -187,183, 87,235,171, 71,189,131, 37, 24,144,178,179,222,185,238,176,243,238,235,239,125,247,211,183, 54,170,187,130,100,145, 14, -219, 54,207,115,189, 61, 32, 10, 56,105,231,120, 54, 13,163,209, 52,137,159,107, 93,218, 57,152,156,248, 39, 36,232,234,181,122, -251,209,189, 70,173,209, 11,251,158,189, 16, 3,107, 12, 86, 31, 73,236, 23, 91, 47,220,127,180,103,234, 6, 93,100,193,114, 40, -238,147,226,166,212,141,196, 65, 14,168, 97,145,114,110, 90, 22,143,147,141, 70,171, 55,246, 73,176,175,215, 55,232,145, 99,154, - 86,251,176,189,232,158, 73, 41,229, 47, 50, 90,132,115, 75,107,195, 40,240, 3,159,118,132,231, 46, 95, 88,125,122,231,176, 77, -123,248,237, 87,175,132,201,248,238,238,118, 21,180, 53,240,121,178, 44, 51,165,189,139,231,156, 33,245,119,232, 31,231,209,200, -171, 46,218,172, 24, 70,180, 36,113,179,190,238,143,251,156, 39,157,160, 35,251,117, 11, 73,109, 42,108,203, 73, 51,202, 78,234, - 97,148,200, 35, 8, 89, 22,167,109,238,152, 20,115,228, 17,188,146,221, 12,204, 39,198,141, 92,130, 11,159,180, 30,104,250,140, - 79, 70,131, 32, 21,250,249, 5,207,207, 78, 73,157,206,184, 58,147, 41,241, 46, 66,169,219,210, 60,153,182, 68, 17, 38,169,109, - 1,127,255,243,254, 15,181, 42,187,245,242, 87,236, 21,118,227,195, 31,255,202, 6,215,182,174,246,211, 97,154,171, 62,159,121, -207,182, 38, 6,124,244,206,198, 75,159,118,183,217, 29,113,229,242,107,236, 38, 99, 61,246, 76,117,115, 63,125, 24, 9, 73,247, -147,156, 75, 56,188,175,157,223, 61,108, 83, 82,213, 58,219,220,139, 39, 74,184,107, 10, 3,171, 6,113,241,204,208,234,176,205, -227,203,181,149, 7,221, 63,155,203,235, 39,131,199,199,157, 35, 6, 75, 60,147, 52, 63, 45, 59,173,255, 47, 7, 59, 10,155, 93, -182, 0, 50,165,181,153, 99,161,207, 61, 75,102,106,212, 75, 70, 48,213,245,129,175,124,255,239,125,183, 2, 63,122, 64,144,228, -252,232, 86,243,226,157, 7,125, 90,202, 69,135,182, 74, 44,202,222, 22, 57, 21, 34,175,206,193,130,136,233, 18,166,129,208,221, - 11,123, 50,173, 4, 0, 18,140, 22,137, 75,171,227,196, 41,171,185, 30, 37, 25,121,150, 43,115,236,121,141, 19, 58, 84,181,167, -171, 64,183,232,214,102, 89, 58,129,167,246,220,238, 91,113, 98, 52,181, 2, 69,128,186, 35,116,182,144,195,178, 42,178,146, 78, - 37, 57,114, 58, 70,178,248,175, 0,132, 93,201,110,211, 80, 20,181,147, 56, 99, 83, 59,166, 77,210,132,161, 5, 85,180, 42, 66, -101, 6, 9,104,133,144, 0,193, 2,137, 37,136, 61, 18, 31,192,150,223, 64, 44,216,178,101, 11,130, 14, 8,150,136,161, 42,106, - 81, 11,129,130,154,198,129,212,177, 99, 63, 79,220,243,158, 91, 84, 88,144,172, 18, 69,242, 16,191,251,206, 61,247,222,115, 98, -254, 61,220,201,157, 68, 59,164, 8,254,255,218,210,135,150,165,191,168,250,127, 94,219, 94,188,242,142, 76, 96,187,246, 26, 31, - 81, 47,232, 61,102, 19,204,193, 76, 26, 64, 3,163,148, 92, 24, 42,161,198,205, 61, 18,163,152,152,199,161,124,174,247, 27,241, - 62, 21,174, 4, 16,186,129, 27,223,177,120,159,194, 72,216,252,194, 75,104, 62,114, 15, 79,250,134, 34,160, 22, 87, 86, 19, 62, -186,170,165,248, 46, 65,134, 66,138, 69,236, 68,137, 35, 1,155,196, 32,164, 69,237,236, 29, 24,193,156, 20,220,247, 2,215,246, - 39,119, 15,168, 16, 98, 6, 10, 38,132,232,241,134, 77,250,227,184,146,105,130, 62, 50, 58, 21,134,160,201,160,129, 22, 49, 46, -102, 47,182,228,228,150, 68, 47,116, 80,124,153,193, 60, 28, 68, 1,191, 77, 49, 48,152,158, 58,251,124,230, 5, 97, 38,184,215, -242,132, 20,250,195, 78,224,185,161, 7, 53, 23,176,130,174,235, 53, 86, 86,141, 86,171,103, 89,197,190, 66,158,146,145, 98, 54, -151, 77,210,154,239, 89,235,125,121, 41,147,199,233,239,175,215,250,251,146,175,230,102,230,230, 95, 59,110,228,123,176, 24,142, -120,206, 65,215,153, 67, 95, 60, 88,142, 44, 4,109, 48,179,154, 81, 32,235, 72,135,240, 56,217,198,221, 38, 65,197,248, 62, 72, - 93,151, 1,185, 67, 82, 16, 11,141, 43,209, 11,135, 72, 60,245,161, 18,160, 72,131,166,121,207,105,163, 69,140,206, 53, 40, 96, - 30, 71, 37,228, 78,113,187, 82,170, 81, 84, 50,186, 77,173,176,203,216,108,166,211,153,138, 54,148, 77,101,221,128, 13,233,149, -195,195,147, 63,218,223,185,175, 58,182,216,225,193, 17, 10,109,195,213,125, 31, 86,223,127,105,126,246, 96,196,163, 12,151, 71, -218,102,115,114,255, 17, 10,223,179, 11,179,140, 57, 90, 65, 63, 58,122,242,214,133,155,239, 86,223,209, 46,249,173,245, 53, 8, - 2,181, 79, 39, 24,149,150, 21,130, 57, 63, 77, 99,177,177,168, 23,117,199,181, 8, 56, 91, 14, 42,174, 87, 79, 94, 54, 58, 29, -173,168,209,205, 82,243,253, 7,106,163,191, 76,200, 19,210,147, 48, 88, 44,159, 30, 59,245,195, 88,211, 74,131, 73, 69, 89,249, -182, 20, 32,102,165,234,165,218,245,211, 87, 10,123,170,165, 40,243,101,163, 65,143, 19,236,244, 48,113,234,210,137, 53, 59,173, - 51,227,167,166, 39,167, 58,129,223,220,248, 94,213,202,131,106,153, 64,232,212,237, 27,198,210,218,250,230, 70, 2,174, 61,142, -101,155, 31, 27, 75,180,248,134,244, 58, 37,142,163, 67, 7, 44,215, 46, 23, 7, 40,170,182, 58,173,146,170,195, 83, 34,153,236, -185,189, 74,169,138,102, 56, 69,161,236, 91, 43,150,218,102, 27, 22,199,129, 79,169,219,120,125,188,109, 26,188, 82, 77,121,100, - 7,234,147, 9,121, 76,201,237,190, 88,131,219, 53, 34,187, 96, 50, 57,142, 17,224, 46, 12,147,113,113, 21,133, 75,194,227,178, -151,238, 70,227, 25, 37, 87, 85,164, 98,170,181,108,174,109,246,208,142,237,137,198, 2,196,135,128,203,149,242,137, 22,161, 47, - 46, 67,237, 43, 37,166, 58, 40,135,145, 37, 59,253,166,249,248,201,131,183,207,142, 85, 15,141,237,170,119, 24,119, 20,145,132, -113, 55,252, 9,184, 82,135, 60,166,238,121,180,252,244,218,190,227,245, 75, 7,239, 63,188,127,183,114,239,229,175,217, 69,246, -233,206,196, 52,101, 30,166,211,147,185,227,207,198,207,117,112,214,114,136,158, 43,148, 16, 34, 78, 51,133,116,201, 21,173, 74, -113, 77, 56, 1,117,153,109, 58,166,209,109,211,111, 44, 6,217, 6, 17, 25,250, 11, 42,242, 63,192, 55,137,114,181, 92, 42, 99, - 49, 59, 20,243, 27, 82,200, 69,252, 9,254,123, 92,219,174, 43,197, 87, 36, 24,100, 17,228, 1,174, 79,140, 66,190,130,227,106, - 16, 89, 13, 99,173, 63,175, 18, 10, 65, 29, 94, 22,230,179, 80,206,175,234,117,211,234,136,240,119,110,226,252,231,230,138,208, -192,220,106,110, 12,163,120, 32, 28, 7,112,225, 60,234, 89,172, 23,242, 22,146, 63, 64, 90,138,253,153,163,173,177, 76,122,219, -158,141,190, 44, 72,150, 74,193,182,183,202, 14, 54,132,239,206, 65, 36,140,186,249, 90, 65, 43, 10,212,225,225, 61,161,252, 22, -128,172,107,233,105,227, 10,163,243,240, 60, 60, 99,140, 31,137, 49,193, 38, 74, 42,161, 42, 69,149, 18, 54,109,164,168,149,218, - 69, 23,149,154,110,194, 47,232,162, 93, 85, 73,254, 64,164,254,151,172,179,200, 31,168, 80, 90, 26, 22,125, 36, 4,136,192,194, - 56,197,140,103,240,216, 51,158,183,125,251,125,223, 29, 83,148,176, 2, 3,134,153,123,231,220,243,189,206,201,241, 61, 19,254, - 23,153, 97,151,232,187, 42,104,211,121,115, 36,251, 32, 63,243, 30,154,179,203,128,253,193,207, 94,204, 97,173, 45,223,178, 49, -225, 46,136,239,191,141, 56, 15, 38,102,176,108, 5, 81, 73,178,100,150,167, 80, 16,193,231,137, 32,222,157,137, 44, 30, 2,243, - 4, 75,216, 44, 23, 25,227,234, 50, 84, 26, 43,208,222, 67,192,101,228,152,142,119,109, 70, 98,234, 98, 74,211,101,168, 14,150, - 77,195,200,159,205, 39, 7,216,165, 43,231,132, 37, 47, 61, 11,172, 92,172,197,104, 4, 35,233,154,233,248, 3, 69,194, 71,167, -108,212,135,193,104,183,103, 15,189,212, 20, 10, 21, 85,185, 89, 45, 27,178, 82, 45,168,166, 68,114, 94,196,127, 82, 66,106,120, -138,100,106,251, 50, 20, 25,101,191,240, 80, 39, 96,229,127, 12,130, 56, 52,252, 20, 84, 89, 84,200,173,163, 8,220,171, 40, 1, -102,245, 58, 29,199, 57,167,137, 9,248,146, 37,209, 20,194,234, 48,201, 66,248,135,162,116, 18,199,158,159,165,217,244,204,114, -123,167, 22, 28, 36, 64,255,163, 24, 14, 0, 68,127,145, 21,208,244,134,187,230, 6,209,206,246,139,231,207,159,109,239,108,107, - 42, 43, 25, 36, 88, 64,223, 35, 93, 55, 70,210, 52,124,142,130, 41,138,204, 37,248,177, 13, 21,182, 1, 78,160, 97,155, 16,132, - 38, 8,247, 92,113,126,134, 50, 75, 69, 21,189, 68,203, 26,106,100, 26,154, 84, 82,209,213, 4, 54, 85,232,163,108,220,106,253, - 6, 80,239, 90,169, 41, 98,107, 93, 54, 10, 92,108,110,161, 37,138,210, 8, 66,233,113,128,122,235,147,208,103,100,118,227,134, - 35, 67,209,173,161,101,251,206,181,202,242, 8, 13,136,101,136,204,206, 39, 67, 47,112,179, 41, 59, 30,116,238,223,253, 14, 7, -208,103,204,241,172,143,154, 31,119,250,157,191,187,127, 37,179,184,128,162,152,234, 97,255,237,239,251,219, 73, 18, 55,171, 77, -165,160,160,161,146,177,112,116,122, 8, 20,161, 93,191,254,227,253,159,182,254,249, 21,229, 71, 68, 73, 47, 20, 57, 39,220, 61, -126, 3,159, 12,253, 1, 92,120,156,134, 3,183, 95, 47,227,220, 41,192, 0,240,241,206,233, 81, 24, 5,186,172,106,240, 43,178, - 14, 44,161,125,101, 5,222,124,235,213,214,105,247, 24,216,189, 53,178,214, 90,107,155,247,190, 63,248,247,109, 99,177, 17, 37, - 97,101,161,246,199,193,142,237, 88,214,160,183, 82,111,117,237,222,167,119, 62,239,159,189,211,237,108,239,221, 94, 66,204, 24, -150,236,250,210, 42,128,227, 56,242,191, 90,255,226,117,119, 23,238,177,235,187,186,102,216, 99,187,177,120, 53,202,146, 40,141, -151, 22,151, 32,228,183,198,103,240,250,230,183, 63,172,148,106, 47, 15,118,106, 11,245,199, 15, 30,253,246,234, 5,128, 58,185, -205, 69, 11,232, 36,229,163,105, 11, 4, 92,146,240,153, 97, 86,190,105,230,153, 87,192,119,105, 94,174, 99,100,205, 65, 52, 73, -164, 81,181,148,164,147,208,115, 62, 84,154,250,185,199,142,118,221, 19,123, 18,163, 76, 32, 25,111, 50, 74, 53, 8,185,164,176, - 64,237,231,136,236, 36,133, 45,163,235, 36, 58,222,201, 10,138,114,235,153,146,110,180, 43,183,107,141, 44,213,134,113,114,165, -114, 53,142, 35,116, 42, 39, 51,111,172,100, 9, 98, 85, 55,158,238,191,108,148,155, 95, 62,252,250,201, 47, 79, 54,107, 63,159, - 76,247,183,130, 63, 31, 92,219,232,163,151, 3,117,115, 75,121, 18, 22,207, 34,210,122,169,150,170,139,102,197, 15,124,192, 41, -224, 10,176,119,111, 46,223, 56,115, 29, 78, 90,205, 98, 73,215, 52, 63,158,112, 58,134,182,227, 9,214, 90, 97,197,225, 26,198, -161,231,197,147, 86,189,101, 20,205, 32, 9,111,181, 62,193,137,185, 17,218,131,164, 44,195,249, 71,137, 59,155,210,230, 23,115, -187,123,184, 43, 93,187,139, 58, 43,116,171, 40,135,131,221,122, 49,245,219, 80, 22,152, 11, 46, 78,201,211, 21, 94, 68, 99, 16, -199, 27,134, 73, 72, 39, 25, 14, 8,182,235,109,110,104, 51,227,165, 69,146,114, 35,151, 91,129,123, 52,241, 15,137, 55, 21,210, -202,148,180,146, 89, 52,225, 80,207, 93,175,243, 49,124,222, 83, 78,205, 63,146,116,129,197,162,144, 87,156,197,139,210, 37, 62, -211,128, 33,234,250,234,186,227, 57,255, 9,192,214,149,244, 54, 13, 6, 81,219,177, 63,175,177,147, 38, 93, 40,208, 37, 8, 65, - 11, 20, 84,202,165,136, 11, 66, 85,225,192, 25,113,225,128,132,132, 56,240, 27,250, 7,248, 41, 72,220,185, 85, 85,145, 56,128, - 64,136,110,162,123,146,182,113,221, 44,118, 18,215,142,153, 25,219, 21, 21, 85, 43,245,146, 58,222,190, 55, 51,223,188, 55, 47, -193,247, 48, 37, 65,158, 65, 28,169,105,185, 11,193,253, 66,136,135, 51, 27,210, 6,220, 83, 28,177, 38, 9, 50, 77, 37,251,135, - 37,147,162, 57, 28, 14,240,113,192, 24,242,252, 86,124,217,255,101,250,105,164, 75,168,153,220,249,238,108,207,148, 45,159,114, -109, 52,103, 73, 43, 42,244,233, 22, 25,118,138,226,123,164, 24, 5, 3, 13, 37, 70,250, 75,142,103, 39,140, 43, 20,108,226,204, - 27,200, 28,209, 75,179,211, 64,162, 44,128, 23,209,252,179,170,233, 39, 13,116,254, 92, 11,129, 79,100,173, 52,100, 85, 32,193, - 49,206,198,241,195, 46, 14,107,141,248,137,225,153,178,115, 84,110,184, 91, 71,206,239, 74,115,223,110, 4, 0, 19, 93, 56,199, -208,100,170, 37, 10,151,116,101, 56,171,228, 69,169,136,174,139, 2,173, 42,142, 33,109, 3,190,191,151,193, 45, 23, 28,123, 0, - 39,174, 50,136, 31,156,138,187,175, 17,110,124, 3,196, 75,194, 73,253, 56,150,177,201, 0,250, 74,148,213,112, 76,183, 46, 73, - 89, 69,210,228,140,169,200, 56, 81, 82,103,150,206,250, 76,156, 45,163, 67, 97, 15,255, 27,139,110,105,122, 18, 73, 94, 57,116, -209,149,201,168, 16,126,120, 17, 89,207, 1,117,216, 2, 84,131,136, 52,158, 3,160, 89, 81,120, 93,147, 24,185, 80, 97,173,135, - 74, 75, 78, 86, 4, 93,133, 95,236,170,105,170, 96, 89, 66,222,144, 52, 61, 99,232,162,174, 98,152,232,161,118,191,231,119,184, -118,187, 23,249, 92,208, 60,141,181,114, 94, 27,197,135,110,167,105,106, 57, 67,205,118,124, 87, 72, 88, 15,128, 14,106,213, 41, -247,155, 3, 7,199,229,216, 54, 51,118, 13,131, 63,147, 35, 83, 76,144,118,237, 77,133, 41, 40,107,136,162,183, 79,223, 45,175, - 44,121,167,174,198,180,141,189,117, 72,130, 0, 88, 35, 36,123, 84,225,152,128,119,163,197,146,221,172,121, 62,206,252,131,207, - 0,128, 2, 74, 14, 23, 46,223, 29,191, 13, 75,189,225, 54,187, 65,183,234, 84, 62, 45,125,156,155,158,223, 58,220,154,189, 49, -187, 93, 67, 79, 6, 83,193, 91,136,202, 38,114, 79,133, 24,163, 48,180, 10,184, 54, 56,254,230,233,235,149,157,213,233,235, 51, -168,201, 96, 50, 20,226,240, 21,144, 41,247,155, 5,183, 83,135,115,131,195, 86,235, 21,120,217,246,237,242,222,225, 46,164,237, -213,147, 3, 72,244,160,188,187, 95,186, 7,151,147, 51,172, 19,180,115,106,172,173,253,124,246, 96,110,121,245, 43, 4,232,137, -145, 91, 99,197, 49,200, 58,247,236,138,135,218,153,128,137,162,227,214,115,122,126,180,120,165,152, 43,148,237, 50,156,179, 79, - 76,176,150,219,108, 7, 29, 40,209, 96,197, 46,126,251, 12,161, 8,110, 95,171,211,250,254,231, 7, 10, 30,225,181, 12,130,201, -145,155,187,181, 29,120,141,135,242, 87,187, 65, 29, 39,127, 24, 3,214,227, 34, 39,161, 48, 53,182, 92, 74, 55, 80, 9,226,169, - 92,207, 16,134, 97, 50, 11, 1,155, 63, 93,117,182,126, 57,219, 27,142, 83,111, 7, 1, 70, 1,106,225,162,104,143,192,153, 56, -233,240,242, 48, 68,118, 81, 99,146,193, 68, 67,150,117,198,208, 10, 0,138, 67,242, 39,160, 96, 18,182,184,154,192, 59, 83,197, - 41,171,111,252,192,222, 70, 30, 44,174,180,120,112, 58, 63,168, 90, 75,219,107, 30,207,191,124,255, 98, 97,225,195, 67,253,121, -157,223, 92,116,191,188, 42, 61,106,135, 45, 62, 29, 89, 76, 25,107, 47,103,228, 36,156, 21,138,114, 83,184,234,128, 10, 91,120, -148,134, 98, 66,241, 80,107,213, 34,116, 85, 13,243,217, 62,120, 22, 62, 18,181, 41, 19,167,156, 16,214,235,177,123, 12,145, 47, - 68, 10, 91,128, 29, 26,220,235,240,202, 39,251,181,102, 13,175, 13,189, 37,178, 94,183,157,216, 29,113,177,134,171, 71, 91, 36, - 66,226, 88, 40,196,174, 40,200,218, 58,106, 30,242, 81, 38,222, 56, 72,186,213,116,103,195,152,212, 72,148,113,226,239, 97,251, -138,156,176, 57,175,221, 34, 3,203,116,255, 57,158, 58,150, 12, 65,193,111, 41,104,125,216,218,229,207, 30, 15, 36,218, 33, 36, - 0, 1, 45,132, 94, 58,154, 82, 99, 6,148, 64, 79,238,204,175, 87,214,104, 30,112,218,120,229, 18,123,166, 51,116, 71, 78, 36, -178,242,253,125,123, 15,162,194, 95, 1,232,186,150,158, 38,162, 40, 60,247,222, 97,166,143, 97,250, 16, 16,144, 90,197, 16,208, - 64, 66, 64,220,232,198,141,107,247,174, 92,153,248, 23,220,186,208,157,191,194,196,157,137, 27, 55, 26,216,104, 66, 92,160, 18, -162, 64,128, 86, 69,104, 43,175, 9,125,204,148,185,158,239,220, 22, 95, 49, 97,217,208,219,121,220,123,206,249, 94,192, 87, 33, -248,180, 76, 95,243,171,252, 63,249,115,239, 62,221,239,244,127,134, 51,250,159,177,140,248, 27,140, 61, 61,147,255, 48, 57,248, -189, 9,144,191,225,174,242, 63,179,160,238, 34,165,236, 2, 6,178, 11, 0, 72,115,217, 48, 8,199, 15,118,109,218, 18, 17,146, -171,184,108,215,124, 25, 88,187, 12,185,141,161,239, 97,118,169, 28, 47,153,173, 81,137, 4,182,126,147, 1,180, 95,122, 43,101, - 78, 75, 41,115,112,173, 3, 90, 66, 47, 82, 91, 68,105, 59,145,114,211,105, 55, 77, 15, 37,109,216,142,114,135, 50,133,111,193, - 6, 61,199,218,128, 28, 28,153, 64,207, 53, 85, 72,147,131, 87, 43,193,186,109, 71,249, 84, 10, 27,186,208,169,164,114,225, 57, -140,178, 40,160,211, 0, 78,246,192,101, 34,234,224, 0,103,177, 83, 6,187,116, 59,204, 54, 87, 74,133,237,152,253, 75, 37,214, -224, 0,235, 84, 72,151,101,160,133,107,158,216,106,155,213, 82,125,173,184,155,238, 56, 19, 73,173,108,201, 30,116,130,117,184, -104, 99, 16, 13,200,243, 25,227,172, 13, 43,107,205,140, 95,205,201,215, 14,140,116,192,141, 4, 68,204, 68, 73, 54, 91,118, 57, -143,153,185,186,241,113,221,170,115,230, 57, 27, 64,139,136,195,143, 29, 97, 57, 90, 7,123,170, 25, 91,251,152, 63,210, 57,228, - 83,121, 30, 35,219,190, 1, 65, 50, 22,209,211, 62,105, 9,182, 10, 72, 56,238, 96,118,248,107,173, 84,232, 43, 86,131,154,197, -100,204,132,219, 27,134,245,172,151,163, 51, 96, 63,168,156,241,251,169, 9,136, 57,140,184, 7,140,102, 53,146, 59,151,114, 83, -229,106,169,109,233,115,185,225,245,237, 85, 90,195,232,208,120, 24, 53,168, 4,166, 15,123,137,116,189, 85, 47, 12, 92,220,218, -133,172,127,170, 56, 21, 52,130,126,191,239,250,229,185,167,243,207,252,148,255,165, 90,166, 42,137, 94,104,186, 22,103,179, 3, -212, 39, 69, 58, 62, 60,218, 67, 57,118, 18,209, 77,188,123,251,222,252,219,151, 74, 11,140,221,165,172, 28,236,230,146,153, 76, -218,223,253,241,157,238,198,236,165,105,218,206, 60, 55,181,184,246,110,180,191,184,189,183,227, 39, 61,186,216,183,102,110,190, - 89, 89,220,216,217,240,210,112, 22,227,216,101, 70,202, 80, 22,168,190, 76,159, 99,187,165,234, 6,221,181,185,177,233,149,210, -106,216,166, 39,167, 39,231,101,242,153,129,229,210,135,153,209,217,247,165,143, 55,174, 92,123,181,180,192,121,114, 54, 85,215, - 73,142,228,166,155,113,225,108,113,115,119,107, 98,100, 98,109,251,179, 45, 93, 86, 26, 65, 12,236, 33, 49, 46,118, 16,174, 39, -243,126,246,160, 85,187,147,191,112,254,225,152,229, 9,248,207, 28, 55,172,136, 33,214, 70, 4, 39,185, 70,136,191,227,208,170, - 71,113, 51,132,162,164,133, 32,154,231, 75,229, 74, 0,176,200,184, 12, 73, 46, 47,149, 0,225,146,179, 96, 56, 60, 23,246,130, - 32, 26, 8,142, 14, 6,115,204, 68, 71,219,194, 24,129, 1, 13,130, 18,138, 90,199, 86, 94, 14,215,131,243,251,113, 59,193,105, -196,112,219,131, 67,159, 24,239, 45, 60, 90,124,177, 89,139,151,154, 11,131, 98,236,254,200,195,186,251,233,241,246,147,215,183, - 30,212, 26, 85,163, 99, 55,185, 53, 33, 67,249,204,206,196,219,224, 37,122,171, 65,213, 48,225,169,165, 99, 29, 33,102, 31,144, - 10,129,243,118, 98, 90, 13, 38,163,232,216, 48, 14, 45,118,136,229,241, 55, 91, 55,114, 47,194,196,106,102, 88,199,186,131,141, -117, 4, 83,173,168, 53, 89,156, 92, 46,175, 80,127, 96,144, 80,124, 7,254,137,149,113,253, 35, 36,105,168, 22, 52,146,172, 13, -138,145,138,102,190,202,140, 83,248,132, 48, 99, 20,102,181,136,174, 97,173,109,113,186,104, 39, 71,197,184, 16,119, 74, 71, 45, - 79, 67,248, 76,198, 22,143,244, 5,255, 52,214,232,243,190,230, 8,247,176,121, 64,101, 25, 32, 13,197,240, 30,215,182,116, 62, - 29, 53, 64, 30, 75, 67,214,103, 1, 64, 50,195, 38,169,169,252, 11,163,230, 79, 1,216,186,150,157,166,162, 40,218,123, 79,239, -243,180,189, 5,164,136,162, 1,140, 70,226, 35, 26,140, 26, 7,134,200,192, 31,112, 96,140, 81, 7, 78,253, 0,227, 68,127, 67, - 63, 8, 13, 17, 38,198, 0, 21,131,202, 35,165, 64, 95,247,253,116,239,125, 14, 84, 19,146, 14, 58,104,111,155,123,207, 89,103, -237,215, 90,146,191, 39,146, 41,159, 2,238,134,106, 96,105,177, 24,126,192,196,181,133,119,229,234,217, 57, 56, 66,149, 33, 88, -255,247, 58,181, 36,171, 74,134, 14,172,217,204,255,175,221, 42,195, 19,162, 40,147,100,110,113, 90,153, 86,156, 83,101, 85,230, -174, 79, 20,234,149,147,120, 70,100,190,168,130, 14,108, 2,194,186, 8,130,181, 92,198, 67, 98, 92, 87, 92, 25,150, 40,144, 47, - 63,242,178, 60,134, 19, 18, 8,102, 16,249, 98, 62, 14,104,160, 16,203, 71, 69, 4,140,119, 52,199, 26, 65, 99, 63,165,244,246, -201,187,230,206, 38, 73, 35,164,186, 6, 55, 71, 11,224, 10,192, 85,227,192,100, 53,224, 89, 98, 54, 75, 65,147, 83,184,136, 6, - 60,185,227, 29, 28,185,221, 94, 16,236,118,221, 67, 47,109,187,236,119,103,240,171,235,109,180,188,221,158,246,167,219,119, 35, - 64,198, 10,203,185,215, 15,181,172, 52,194,180,134,165, 3,188, 85,138, 18, 7,174, 29,167, 26,101, 1, 45,134,118,134,104, 84, -174,146,173, 67,138,105, 81,192,187,106, 69, 1,226,143, 54,129,212, 44,134,242, 38,122, 78,201,244, 66,163,153, 16, 83,101,176, - 69, 18,216,201, 17, 58, 18, 98,155, 56, 57,246,145, 11, 47, 22, 87,147,172,132,231, 18,170,249,203,222,170, 56, 37,157,153, 18, -139, 16,202, 83,223, 47, 69, 94, 30, 70,121, 16,230, 97,136, 46,131, 88,196,198, 60, 24, 54,140, 2,178,192, 15,217,170, 50,201, -141, 65, 55,235, 6,106, 63, 56,194,158,156, 20,157, 43, 80, 64,148,122,106, 85, 86, 46,104,152, 0,162,155,138, 85,195,145,141, - 52, 9,147,216,177, 71, 15, 7,109,161,149,103,106, 28, 78, 97,199,174,145,118, 5,240,113,195,210,172,170,229, 88,166,141, 79, - 42, 77,159, 45, 60,229, 58,255,178,177,124,127,238, 1, 96, 34, 28, 89,110,216, 55, 13, 27,246, 63,112, 49,122,154,217,243, 23, - 47,191,174, 44,163, 75, 3,134, 75, 41,160,179,161,235,223,183,191, 45,173,125, 38,113,240, 16,246, 38,144, 78,136,225,252,208, -197,226,103,255, 64, 43, 27,131,160, 7,207,113,166, 49, 29,198,225,214,206,143,137,234,248, 86,107, 11,162, 64, 13, 91, 84, 20, - 8,255,227, 56, 0, 52, 49,116, 0, 44, 6,212, 30,147, 75, 10,155,158,184, 8, 31, 3, 22,230, 6,110, 19,190, 53, 50,177,223, -111,199,121, 74,129,118, 5,246, 9, 64, 70,171,187,111, 24, 16,190,153,119,175,220, 89,223, 94,135,213,117,126,108,170,110, 59, -135, 88, 79, 46,194, 36, 0,110,184,120,125, 97,115,175, 25, 70, 65,171,179,255,248,246, 34, 64, 57,122,149,152,252,230,244, 13, -248,255,176,216,184,201, 97, 51, 3, 80,194,249,132, 74, 56,121, 10,119,105,166, 49,147, 36, 49,154, 38,178,178,195, 71,235,124, - 60, 76,221,249, 51,243,252, 94, 86,114, 24,197,110,249,241,158, 44,228, 27, 17,211, 17,184, 41,164,100, 99,233,108,109,167,215, - 11, 18, 89,125, 68, 94,129,235, 10, 3, 61,134,115, 27, 56, 54, 65, 14, 89,186,138,247,162,140, 10,193,104, 63,160, 51,114, 14, -192, 30,174, 82, 89,145, 78, 74,148,226, 83, 19,165, 55,105, 55,120,245,178, 27,116, 24,105,172, 11, 35, 67,174, 27,205,206,222, -207,182,247,230,253,235,143, 31, 62, 77,153,215, 10,173,191,228,175,188,186,244, 48,201, 61, 49,226, 34, 89,156,212,177, 34,145, - 19, 20,138, 73,102,207,205,246,252, 1,205,150, 23,244,223, 17,135,184, 89,197,220, 58,193, 69, 42,114, 25, 2,116, 73,166, 80, - 0, 56,185, 65, 8, 74,141,124,176,144, 25, 89,156, 98,167, 94,154, 66,136,144,215,237,250,163, 91, 11,171,155,171,138, 42,155, -101,143,105,107,225, 69, 62,121, 13,145, 70,173,136,140,137,193,115,189, 18,147, 36,175,204,224,203, 42, 71,241, 47, 22,138,172, -128,236,245, 64,155,160, 26, 94, 36,207,167,198, 46,120,241, 64, 80, 95,135, 59, 38, 51, 13, 3,187, 1, 17,184,237, 42, 22, 5, -233,183, 50,108, 97,138,105,168, 74,149,103,132, 50, 12,198,196,140, 43,185, 6,162, 66, 34, 32, 21, 90,120,167, 9, 90,215,102, -201, 95, 1,248,186,150,213, 38,162, 48, 60,247,204, 37,153,180,147, 72, 59,109,189,208, 88, 11,138,224,198,133,160,130,130, 11, - 31, 65,151,174,117,229, 78,112,227, 83,184,240, 21, 92,248, 8,162,104, 81, 80, 20,169, 86,109,189,165,182,166, 77,167,185, 76, -230,146,153, 51,254,223, 57, 73, 13,130,118,213, 66, 18,210,228,156,239,252,231,255,191,203, 65,255,157,201, 19,125,231,201,202, - 61,195, 14, 97,147,245,120,198, 37,202,244, 67,224,254,159,142,205, 63,170,239,131,122,255, 96, 38, 60,217,184,151, 71, 67, 2, - 60,138, 77,246,195,229,191, 26, 56, 66, 41, 54,158, 59, 23, 19,183,129,145, 80,149, 43, 32,192, 0,132,235, 50, 70,150,182, 81, - 65, 40,183,196,120,120, 22,166, 61,150,102, 14,134, 49,125,172, 73, 30,211,195, 0,223,252, 93,129,250,194,114,186,167, 35,206, - 9,236, 36, 44, 3, 2, 14, 25,168,154, 61, 89,125,220,139,193,250,162,149, 79, 79, 49, 53, 83,146, 52, 7,103, 67, 95, 83, 75, -237,254, 14,173,255, 20,145,152, 80,193,193,252, 72,117,145,215,147, 70,183,174,223,121,249,246,185,141,111, 55,201,216,128, 49, -157, 22,200,145,250,137,173,206,102,111, 56,252,213, 31,108,133,221, 66, 63,212, 28,236,181,210,172, 25,198, 63,187, 9,196,233, - 4,121,146, 82,146,101,215, 80,235,166, 94,183, 74,117,179, 52, 69,191,219,165, 74, 73,153,114, 84,203, 40, 12,218,196,130, 28, -193,253, 6, 50, 80,216,152,136,113, 40,113, 31, 52, 78, 49, 42,168,234,183, 45,197,113,232, 90, 42, 91,150, 98,232,146,165,171, - 54,154, 66,136,244,171,152,138, 37, 20,165, 84, 96,243, 44,113, 80,129,248, 49, 25,209,193, 16,179, 36,205,251, 4, 99, 97,158, -166,176,174,148,184,205,189,165, 41, 86, 73,166,178,189,108, 72, 71, 29,107,189,185,255, 37,232,197, 89,136,203, 8,207, 38, 84, - 97, 27,128,238,161, 12,238, 16, 29,126,153,239,205,215,221,218, 78,176,205, 10,161, 70, 41, 16, 71,160, 80, 49, 50,165,242, 45, - 48, 28, 70,170,106, 92,187,124,109,101,245,169,176, 33, 11,122, 59,220, 21, 86,166,143,116,101,109,133,243, 57,243,173, 96, 51, - 73, 98, 42,183, 79, 29, 59,189,219,105,193,100, 56,220, 3,134,228, 57,129,187,107, 87,227,116,112,172,209,184,112,246,210,250, -215, 79,180, 96, 42,102,149, 54,120,173,236, 65,100,148,192,185, 8,101, 47, 29, 30,244,200, 44,158,247,252,253,238, 46, 33, 17, -225, 5,189, 14,221, 57, 90,221, 22,253,239, 75,115,141,153,105,127,121,126,233,219,246, 23, 93, 85, 47,158,188,112,216,155,249, -240, 99,205,208, 84,191,234,151, 45,155, 78,110, 91,183,206,159,187,186,241,109, 53,197, 24, 92, 63, 90, 63,178,219,105,195,226, - 49,234, 17,142,127,220, 90,243,167,231,250, 81,247,202,153, 75, 15,159, 61,162, 3,137, 10,255,160,191,135, 60,153, 40,164,226, -189, 86,169,237,238,183, 61,215,251,177,211,164, 55, 25, 13,195,101,200,106, 54, 5, 40,181,123,129, 72, 64,147, 49,242,113,105, -159,119,224,132,126,188,106, 87,185,175,242,190,166,169,174, 89,161,186, 50,207,163,120, 24, 88,186,195,122,219,139,151,103,165, -186,129,109, 36, 8, 44, 92,231, 62, 82,223, 40, 2, 64,177, 98,180, 34, 39, 92, 46, 59,246,251,239,193, 94,156, 42,130,104,204, -103,161, 58,214, 12,106, 28, 56, 67,195, 7, 74, 85,228,226, 32, 3, 72,225,105, 18,101, 77,243, 44,243,240,244, 20,183, 82, 47, -116, 30, 80, 44,122,194,244, 69,184, 48,204,156, 15,144, 33,174, 21,104,182, 84,233,169,141,217,133,215,205,141, 55,237,205,219, -119,111,222,191,247, 96,193, 60, 41,235,221, 23,233,187, 27,139,231,233,134, 55,110, 95, 40,226,150,207, 68,117, 44,177, 25,111, -182, 19, 98,120,147,194, 14, 77,168,206,160,104,241, 61,159, 22, 6, 79,239,227, 96, 15, 35, 44,206, 31,102, 60,150,152,241, 81, -155, 84,140,212,231,227,142, 55, 23,142, 22,130,235,177,188,176,220,131,174, 21,182,225, 97, 26,190,250,252, 6, 74, 28,196, 54, -229,185,224,170,112,236,161,162,111,113,166,241, 51,104, 74,220,163,176, 24, 67,165,101, 56, 81, 6,238,188,235, 84, 19,110,252, - 59,166,209,255,233, 77,112,215,241,113, 3,133,176,219,172,208,141,132, 94,173,213,161,141, 14, 27, 12,198,219, 96, 97, 18, 70, - 80, 75, 65,152, 66,112, 1,146,187,196,201,222,133,236, 85,106, 81, 26,249,222, 92,151,118,193,159, 9,171, 44,236,126, 21,105, -100,153,131,238, 59, 21,173, 40,243, 49, 18,160,191,127, 11, 64,216,181,244, 52, 17, 69,225,123,231,213, 78, 95, 67,167,229, 41, - 40, 96,108, 98, 76, 52, 81, 2, 97,225,194,184, 52,110, 12, 46,140, 27,253, 1,238,220,155,248, 35,140,191,200, 24, 23, 18, 34, -132, 4, 36, 66,132, 2,182,165,180, 50,239, 41,245, 59,231,182,162,209,232,174, 77, 38, 51,153,185,231,241,125,231,158,251,157, -139,250,187,246,199,249,163,254,223,240,248,127,113,250,191,203,244,234,182,166,180,168,206,192, 60, 65,210,104, 43,224, 2,110, -148, 30, 38, 38, 30,226,203,250,177,186,141, 47, 56,104,110,185,184,195,111,187,185,220, 11, 54,216,129,254,117,188, 20,155, 8, -105, 24,224,253, 0,109, 60,154,200,172,196, 51,240,248, 76, 66,167,241,177,132,100, 46,249, 76,129, 84, 41,184, 30,162,150,130, - 13, 37,130,233,144,196,152,198,163, 93,233,118, 36,179, 78,202, 60,131,126,123, 3,225,251,225,226,163,181,189, 85, 18, 33, 34, -153,142,120,178, 60,221,236, 28,243, 30, 61, 8,102,148, 82, 10, 78,253,196, 79,146,228,253,250, 59, 56, 97, 2, 32, 2,251, 19, - 44, 59,209,139,143,187,251,150, 94,140,123,161, 99, 87, 76,195, 58,241,143,168,198,135,128,174,185,254,185,151, 10,189, 19,247, -190,197,113,195, 55,142, 67, 26,229,213,134, 11,203, 62,216, 99, 78, 51, 93, 51, 51, 90,200, 59,166, 89, 50,178,217,190, 81,144, - 32,234, 38,126,216,186, 73, 70,153,202,148,166,247,200, 40,232, 81,199, 75, 66,111, 59, 16,163,227, 70,107, 66, 94, 86,159,181, -221, 69, 33,139,208,143,160, 47, 73, 64,216, 32,163, 34, 85, 46, 22,106,202,153, 70,206, 2, 70, 35,141,154, 10,176, 71,222,116, -138,134,155,183, 74,182, 81,176,145, 33,100, 86,147, 96, 27,142, 52, 63,237,181,118,219, 30, 11, 12,113, 15, 27,187,208,148, 59, -227,100,203,176,221,197,218,242,206,241, 54, 62, 45, 28, 21, 17, 42,151,161, 73,123, 83,229,153,162, 77, 20, 10,107, 1,152, 60, - 57, 50, 13,192,110, 25,182, 31,123,173,110, 11,142, 71,161, 95,104, 83,213, 75, 9, 9,241,171, 18,129, 94,201, 87,252,216,183, -179,118,109,250,122,215,239, 32,140, 34,127,172,220,123, 92,181,171,251,173,125,138, 74, 6, 76, 60, 90,170, 45,175,109,174,110, -110,111, 8,154, 67, 96,193,123, 29, 58,112, 24,146,146, 19,119, 18,227,134,160,180,112, 75, 93, 13,129, 35,158, 74,237, 49, 88, -199, 92, 38,255,236,254, 83,207, 63,107,122,237,175,141,189,207,245,173,170, 51, 54, 51,126, 69,246,210,179,192,135, 45,141, 59, - 99, 7,237,195,152, 69, 53,225,177,219, 59,235,120,202,157,107,183,247,155, 7, 65, 20,129, 29,193, 30,138,118,105,194, 29, 59, -104, 29,157, 69,223,253, 48,108,158,157,176, 94, 96, 52, 63, 57,219,234,144,198,172, 31, 69, 32,170,174, 59,177,242,224,201,238, -151,109,188,212,168, 83,165, 66, 1,225, 47, 27,215,243, 8, 26,129, 28, 54, 63, 62, 71, 5,232, 94, 58, 85,153,196,211,235,167, -117,228, 54, 36,146, 83,191, 13,124,135, 7, 5, 44,149, 3, 19, 54, 45, 83, 15,253, 27,119, 47,139, 57,155,157,173, 47, 84,227, -149,236, 15,230,247, 12, 0,160, 2,202, 18,224, 92, 88,230,135,245,195, 48, 61, 87,212, 77,137,192,240, 97, 55,146,140, 86, 85, -133, 30,103,107,174, 78, 83,125,218,194, 39,149, 70, 33, 99,205, 84, 70,140,172,113, 18,146,214, 83,134,107, 48, 63, 69,163, 82, - 17,232,158,221, 78,224,239, 26, 40,203,114,109, 97,175,113, 16, 4,254,206,105, 99,163,217,120,249,234,197,155,215,111,175, 22, - 22,132,209,253,152,108, 61,159, 93,138,250, 30,247, 55,255, 12,161,130,155,250, 75,220,179, 46, 3, 82,140,225,115, 37,180,115, - 68,242, 57, 97,156,130, 66, 69, 9, 89,183,194,236, 10,143,223,156,189, 85,111,215,129, 85,202,165, 81,164, 85,158,238,163, 36, -201,197,224,168, 40,137, 80,141, 80, 48, 21,231,141, 78,147, 14,223,168,173, 73,169,151,139,101, 22,181,181,227, 56, 1,101, 39, - 72,199,227, 53,224,206,141,110, 75, 92,244,175, 43, 41, 71, 96, 17, 18, 63,136, 82,240, 39, 43, 78, 67,197,146, 88,254,224,162, -161,133,255,171,137, 10,244,233,129,208,177,172, 39, 94,203,205,187, 81, 28, 43,186, 1,196, 45,135,114, 79,170, 79,105,216, 91, - 71,244,194,208, 76, 47, 14, 34,154,249,144, 14,234, 19,218,144,143,105, 98,120, 48, 72, 93,222,163,156,161,162,162, 20, 63, 4, - 96,236,218,122,162,134,130,112,123,122, 78,111,219,101, 23,150,203,162, 18,162,129,152,152, 16,223,140, 60, 24, 30,124, 50,254, - 5,253,111,196, 7,227, 31,192,240,164,137, 9,241, 1, 68,137,107, 36,220,228,190,184, 23,216,238,173,237,182,123,234,204,180, -236,106, 2,137,240, 68,114, 18,218,133, 51,243,205,204, 55,223,199, 7, 56,253,166,205,210, 91,127, 84,149,255,253,138,111, 58, -223, 35,175,150, 97,115, 31,227, 93, 52, 56,163,171, 8,108,225, 6,194, 83, 6,125, 47,192,172,254, 79,167, 94,189,149,126,121, -157,150,136, 77, 19,167,155,183,177,197,109, 20,213,145, 73, 46,102, 16,178,187, 81, 7, 5, 37, 52, 1,225,183,199,250, 72,230, - 75, 68, 42, 83,199,131,164,193, 66, 19,255, 24,251,248,232, 34,162,200,156, 51,218,104, 55, 98,106,158, 49, 84,240,244,225,175, -254,246,211, 27, 56, 9, 53, 17, 57,214,250, 7,149,125, 20,192, 81,217,136,149,175,119,107, 40,190, 22,226,180, 68, 69,161, 21, -169, 49, 40,241,116, 15,157,112, 73,155,142,218,228,174,143, 75, 88,101,247,156, 28, 92,113,225, 19,210,111, 55, 66,125, 34, 0, -109,156, 22,142, 66,165,211,239,107,165,166,123,116,217,242, 37,246,224, 56,150,201,202,136,101,230, 76, 49,155,205, 78,103, 51, -182,109, 27, 76,155, 48,140,122,208,131,187,101,197,220,128,135, 87, 80,232, 18, 66,118, 43,162,220,226, 73,168,255, 66, 17, 26, - 38,215, 5, 62, 0, 71,147, 18, 20,237,176,109,178, 47,135,215,136, 88, 15,192, 67,136,220, 47, 63, 68, 6, 3,128, 1,168,202, - 61,244, 6,163,143, 38,130,192,132,112, 18,158, 48,111,235, 83,142, 81,107,120,235, 7, 87, 80,223, 67,121, 48, 61, 54,179,125, - 94, 34,132,132, 89,238,176,122,128,251, 71,161,247,227,248,251,157,177,123,245,102, 53, 70, 57, 86,120,120,221,151,126,189, 83, - 53,152, 97,162,245,182,177, 48,243,104,251,228, 39,192,103,210,228,227, 87,205, 58, 45,175,121, 89, 43, 7,255,228, 16,253,209, - 76,145, 46,231,126,101, 15, 45, 85, 59,205,202,213,111, 67, 88,168,193,107, 90,203,171,203, 15,138,115, 77,175, 9, 32, 23, 53, -177,226,112,235,104, 75, 55, 76,146, 24,212,225,216,104,166, 32, 4,191,186,104,248, 97,240,250,249,171,195,243, 67,244, 9, 97, -234,198,238, 6,220,234, 54, 90, 36,115, 71,100,187,136, 3,160,224, 8, 87, 54, 86, 91,109, 23, 18,207, 92,241,190,161,242, 66, - 97,106,105, 97,233,107,105,237,164,126, 22,248,190,103, 6, 0, 96,159, 62,124, 18,244,123, 27, 59,155,142,229,232, 81,124, 92, - 57, 53, 13, 59,177, 31,122,185,248, 98,229,243,251,189,139,195, 98,190, 8,183, 15, 18,188, 11,245, 25, 83,230,139,243,139,143, -151,206, 62,188,131, 95, 87,112, 70,243,179, 83,141,179,203, 94,167,229,152, 25, 72, 63,229,122, 25, 34, 81,185, 86,206, 59, 89, -157,241, 92, 38,235,133,189, 46, 57,132, 65,110, 40,228, 10,141, 22, 6,116,174, 48, 72, 96, 71,181, 35,194,133,172,227,183, 38, -199,238, 78, 76, 77,255,218, 95,135, 26,179,195, 45,101,199, 85,158,141, 35, 72,239,235, 24,223, 53, 28,125, 32,163,134, 15, 92, -218,168, 91, 32,208,187,160,245,173, 10,149,153,174,177,144, 66,188,140,211, 89, 29,163,149, 61, 85,202,248,239,139, 15, 48, 71, - 83, 45, 33,144, 80, 43,180,227,142,219,172,123,128,123, 50, 56,177,193,111,193, 18, 64,164, 10, 17, 77, 10,211, 31,159,189, 60, -221,133, 79,233, 99,105,141, 1,134, 50, 16, 73,154,138,141, 35, 80, 37,118,120,182,133,218,165, 38, 81,246, 73, 69, 21,105, 7, -100, 77,134, 36, 98,110, 25,166,223, 15, 0, 16, 36, 46, 2, 50,101,127,168,100, 38, 76,251,180,105,224, 70,194, 50, 25,189,245, -191,236,109, 10,206,161, 36,247,221,138, 76, 54,252, 83,216,174,164,158, 68,112, 24,201, 20,177, 36, 23,176,235, 81, 31,213,192, -114,184,246,216, 14,154,196,140,148,113, 58,104, 37,147,185,129,179, 68, 98,108,136, 7,112, 10, 66,137, 4,121, 53,137,235,133, - 58,232,134, 37,246,158, 41,103, 63,145,245, 75, 24, 66, 18, 96, 31, 73,184, 74, 84,117,228, 90,197,173,106,228,164,118,205,230, - 75,138, 13,124, 1,183,235,226,204, 76,134, 67,138,100, 60,236,104,171,169,250,128,146,152, 99, 3, 16,129, 87,169,161,249,184, -250, 71, 0,202,174,165,181,137, 40,140,206,220, 59, 51, 73,166, 77,155,198,166, 47, 40,182, 69, 20, 41, 45, 86,197,125, 65, 10, -110,252, 3, 93,250, 59, 4,255,136, 8,234, 90, 16, 92,117, 33, 8,182,116,161,162,216,151, 85, 90,232, 51,105,210, 71, 94,243, -200, 60,226,119,190, 59,169,173,136,232, 50,179,153,201,204,189,231,126,143,243,157, 99,156,147, 41,245,127, 67,246,191,211,219, -255, 19,246, 47, 65,127, 71, 69, 18,232, 15,113, 2, 12,254,234,237, 63,116, 95,127,235,238, 94,100, 54,234,234,220, 76,244,116, - 58,126, 84, 62,122,102, 33,152, 93,204, 11, 99,149, 5,224,143,219,246,240,222, 99, 65, 59, 39, 17, 89, 22, 74, 69, 63, 78, 91, - 89,168, 20,176, 56, 92,135,171, 36, 78,170,229,233,137, 59,223,247,214, 41,188,130,124,165, 48,184,223,132,187, 56,129,203, 69, -125,157, 82,129,166, 95,247,131, 86, 41, 56, 68,212, 35, 2,197,138, 66, 1, 83,147,240,196,198, 58,132,166, 31,146,142, 48,209, -151,227, 46,168,174, 38,212,132, 30, 73,184,174, 70,104, 0, 72,124,126,201,114,214,109, 17,229,109,208, 85,107,173,152,110, 64, -225,161, 19, 68, 4, 70,197, 88,251, 22, 86,212,105, 78, 72, 57, 53,152,163,135,215, 51, 22,129,171, 1,163,119,105,185, 96,168, -217, 66,246,102, 82,215,179, 89,148,191, 53, 12, 56, 35,194, 38,220,129, 52,154, 17,186,113,213, 67,248,227,129,148, 36,130, 64, -227, 85,205, 99,117, 44, 70, 5, 50, 89, 11, 77, 84, 83,189, 36, 93,235,183, 83, 61,166,229,250,241,210,218,209, 81,195,151, 50, -109,155, 86,165, 94,220, 60,128, 64, 57,116,174, 1, 11, 2, 24,237, 57,182, 97, 55,252, 70, 29,190, 60, 33,157,124,116,100,214, -188, 26, 12,117, 91, 94,166,203,110, 56, 85, 10,207,221,192,107, 6, 14,101,160, 41, 97,206,205,204, 45,111, 44,209, 21,101,178, - 83,172, 30, 58,158,123,110,131,206, 81,188, 18, 31, 69, 96, 70,177,121,221,107,218, 86,247,252,236,252,147, 23,143, 39,175, 78, - 18,100,247,103, 11, 20,254, 83,254, 34, 89, 94,166, 84, 45, 18,238, 31,211, 22,130, 44,157,246,116,225,153,196,208,131, 63, 90, - 24,203,160, 94, 25, 58,190,211,215,149, 31,238, 27,222,220,223,192,234, 49,204,226, 89, 41, 99,164, 7,115, 67, 3, 61, 67,235, -187, 43,187,229,157,175,155, 31, 70,114, 35,174,239,216,102,250,238,181,153,197,213,197,207, 91, 95, 70,251, 71,233, 39,140,112, - 83,221,133,158, 43,180,254,106, 78,157,190,203,199,141, 79,150,105,165, 77, 43,214,194,253,242, 33,180,196,233,169, 53,153, 77, -117,191,126,247,138, 94,187, 97,203,253,242,193,120,215,141,237,202,202,203, 55,207,239, 79,207, 26, 56,141,130,158, 76,246,168, - 86, 49,205,212,195,123, 15,222,175, 45,123, 94, 53,103,247, 86,106,229,219, 19,183,118, 43,123,148,181, 80,252, 78,193, 94,119, - 10,121,143,100, 36,225, 4,168, 85, 24, 24,226, 90,115,219, 51,187,182, 23,246,198, 31,221,212, 8, 76,163, 38,143,213,241, 2, - 23, 28,194,163, 73, 15,195, 39,173,215, 68, 53,122,245,244,237,242, 14, 92, 19, 52, 5,125, 29, 22, 56, 55, 32, 47,214,107, 21, - 87, 15,150,150, 82,228,179,182, 76,155,167,174, 19,226,236,151, 60,120,139,204,141,123,249,172,104,203, 62,238,174, 91,206,217, - 83, 21,168, 13, 10,102,172,200,136,163,108,181,239,155, 90, 96,105,198,158,183, 19,177, 72,142, 96,167, 42,157,187,160,122, 28, - 33,157,142,180,227,250, 49,109, 24,250,155,161, 16,227,249,177, 31,165, 45, 31,213,107,216,128,133, 24,225, 64, 17, 38, 86,170, - 11, 24,239,132,203, 39,187, 73,130,179,223,142,227,115,148, 76,130,110,229,112, 68,223, 8,252, 61,202, 91, 12, 10,138,149,171, - 55,183, 76, 53,204,117,133, 97, 35,170,227, 9,184,181,250,139,163,216, 78, 74, 58,237,196, 56, 45,177,245,166, 60, 0, 10,174, - 32,248, 26,249,108, 63, 45, 27, 27, 35,114, 77, 53,219,101, 36,190, 75, 42, 55, 18,106, 44,134,153, 32,186,227, 53, 85, 81, 58, - 82, 46,129,160, 84,176,121, 26, 71, 49,231,108,252,142,229, 18,159,182,151,133, 0,196, 5,189,155,196,208,186, 29,159, 53, 79, -184,185,130, 75, 63, 5, 96,237, 90,118,155,134,130,232,181,175,157,216,206,195, 73, 31,105, 80,131,154, 86, 32, 1, 43, 22,172, -248, 4, 36, 86,252, 0,159,198, 23,176, 64, 8, 9, 16, 91,132,218, 74, 81, 23,133,180,106,105,211,144, 71,243,110, 28,199,241, -155,153,185, 78, 10,130, 13, 18, 63, 96, 39,215,115,207,156,121,157, 81,216,191,208,246,255, 10,241,191,189, 34,205, 81, 17,222, -193,141,222, 50, 85,167, 67,150, 40,157,161,157, 8, 93,255,232,111, 16, 31, 51,101, 37,112,150,213,242, 0,149,168, 28,249, 43, -149,167,227, 18, 45,240,120, 80,145, 80,184,136, 33,132, 15,195,112, 89,225, 70,227,132, 11,143,197,138, 16,117, 53,237,200, 18, - 57,152,162,110,166, 84,189, 63,189,102,180,171,226,232,162, 6,112,179,179, 89,109, 14,154,194,105,210, 24,161,236,163, 33,168, -240,182,201, 98, 76,141,126,162, 29, 83, 42,231,203,224, 30, 40,145,238,145,168,134, 68,173, 20, 76,252, 29,145, 90, 10,104, 88, - 25,235,154,136,226,212,106, 12, 96,192,248, 94,225, 81,115,122,142,138,147, 44,224, 1,188, 2,119,122,147,144,122,164,208, 98, - 6, 46,150,204,211,244, 61,231,162,190, 20,214,135, 99,157,187, 56,201, 73, 15, 70, 70, 35, 99, 15, 7,248, 55,136, 12, 0,251, -239, 23,139,213,124,174,128,213,133,172, 41, 97,238, 5,184, 60,202,241,179, 96,230,120,150, 20,207,177,139, 40,160, 44, 17,205, - 94,225,117,197,205, 3,161, 1,220,139,131,155,202,166, 56,240, 71,219,241,247,191,247,135, 22, 56, 79,135, 75, 41,207,179,103, -254, 68, 87,115, 70, 42,215, 26, 93,193, 89,107,170, 54,119,157,192, 95, 0,192, 25, 90, 1, 44, 30,127, 18,118,172,240,201,108, - 36, 43, 10,249, 98,184,155,108,183,188,119, 61,238, 30,158, 29,192,101,184, 83,168, 56,254,252, 99,237,253,220,155, 11,233,130, -129,213,167, 50,154, 14,174,138,246,107,235, 54,106,146, 68,128,203,224,228, 12, 45,219,191,233,192, 39, 72,105,250,219,253, 55, - 27,197,173, 77,179,132, 66, 28,161,159,104,177, 70,129,170, 26, 41, 73,129,248, 54,159, 89, 91,120,118, 74, 81,192,210, 30,222, -125, 80,111,124,157,204,134, 94, 64,221,156, 44, 28, 90, 3, 96,217,102,166,104, 57,211,242, 90,165, 51,104, 64,232,109,187,211, -211,246,137, 71,219,111,224,215,204, 92, 91,227,234, 78,185,218,232, 54, 56,231, 47,158, 62,127,253,249, 93, 49, 95,116, 93,183, - 51,110,183,111,186,178,136,252, 36,185, 53,234,160,170,109,228,111,100,214,225,154,162,228,108,236,101,211,102,123,212,133, 88, -161,144, 41, 0, 97,223, 45, 85, 43,114,241, 8, 69,221,248,151,179,131, 74,105,103,100,141, 33, 20,240,176,234,236, 52,122, 87, - 99,123, 2,254, 24,224, 27,190,254,143, 65, 11,231,221, 89,132,132,131, 73,134,106, 80,151,119, 36,166,223,195,192,175,159, 30, - 42, 16,234,225, 68, 72,175, 57,140,182, 95,125, 74,189,124,198,208,148, 38, 76, 33,188,224,148,217, 70, 34, 0,120,158, 97,181, -238,197,135,243,163,122,111,232,184,192, 3,176,170, 65,122, 65,161, 47,224, 33,105,193, 90, 13, 30, 82,186, 19, 55,243, 85, 54, -242, 11, 57,154, 90, 22,224, 42, 64,164,138, 0, 25, 11, 49, 54,209,166, 6,102,167,144, 85,166, 21, 47,154, 89, 88, 92,209,140, -249,194,131,155,165,201,105,207, 11, 53, 29,119, 99, 77,216,108, 91,171,236,207, 61, 51,157, 15, 34, 23, 23,213, 98,224,155, 55, -141,204, 73,231, 50,183, 94,158,143,250, 56, 68, 43, 56,123, 20, 97, 69,132,252,206,147,123,143,107,151,199,112,229,182,204,210, -113,235, 27,201,193,209,190,164,128, 4,234,101, 22, 96, 54,143,248,124,156,164,115,197, 16,110,124,219,142, 1,161,155, 98,166, -205,190,219,139,150,248,200,101,196, 16,148, 21,210,178, 16, 1, 12,103, 55,178, 20,175,100,105,111,153,181, 40,252,210,202,177, -164,163,143,142, 11, 30,152, 73,227,144,115, 90,209,108,215, 17, 44, 19,248, 13, 88,160, 31,186,162, 60, 26, 75, 75,233,175,213, - 80,167,196,198,214,152, 45, 55,160, 51, 49,251,200,150, 98, 5, 2, 4, 89,162, 72,243, 71,203, 73, 34, 7, 41, 37,195,255,232, - 29, 40,114, 78,116, 24,127, 10,192,216,149,236, 54, 17, 4,209,158,221,179,197,139,108, 39, 81, 18, 5, 36,132, 64, 66, 66,226, - 0,124, 2,119, 62,129, 11, 7,238,124, 4,191,192, 31, 32,113, 65, 8, 78,112, 68, 17, 10,203,129,147, 67,130, 9,177,177, 51, - 30,143,103,245,108, 61, 84,117,143,147, 0, 18,226,226,147, 61, 35,207, 84,191,126,213,245,234,149,252, 15, 40,255,159,230, 85, -156, 19,200, 84,231,255,127,254,254,247, 23,152,221, 32, 78,153,101, 41, 6, 68, 88, 86, 15,168, 37, 92, 9, 43,150, 23,132,152, - 23,175,202, 44,201,170,213,201,187, 20,227, 76,194, 66, 60,187, 39, 31, 12, 91,137,188, 83,105,213, 14, 80,101, 40, 31,169, 84, -217,100, 83,119,249,115,225,174, 97,104,136,178,219,189, 52,241,198,188,208, 1,241,234,198,128,215, 30,238, 19, 98, 37,227,148, - 87,184,190,216,182, 58,144, 26, 83, 28,104,167, 82,108,239, 76,241, 61,139,133, 34, 41, 16,140,138,214,192, 74, 11,170, 22,133, -177, 55, 34, 76, 74,203, 38,165, 0,234, 2,140,102,220,142,129, 59,160,178,212,183, 4, 18,177,196, 90, 36,106,209,105, 90, 27, -183, 30,120, 78, 33,164,170,100,224,122,198, 51,198, 85,133, 68,252,109,251,230, 4, 11,123,230,177,148, 65,194,146,132,114, 90, -179,174,242,194, 91, 68,202, 38, 4, 89,116, 12,219,123, 6,172,131,137,208,141, 6,112,240, 94,115,109,221, 48,182, 76,243,198, -102,207, 54,180,158,161, 1,222, 51,179, 70, 33,197,181, 78,225,237,160,199,125, 65, 1,111, 7,163,224,240,196,119, 22,212,141, - 2, 77,182,238,221,188,255,106,255, 25,192,159, 34, 26, 64,226, 32, 24,166,139, 73,201,206, 59,113,124, 54, 22,169, 84, 8,186, - 28,235, 16,153, 36,194,227,202,253,216, 55,117, 59, 78, 22,186,102, 3, 93,157,199,174,143,233, 39,202,171,225,153, 76, 23, 35, -156, 67, 96,182,104,161,181,205,182, 23,123,144, 74, 3,137, 14,146,133,199,186, 22, 27,170,201, 88, 42,214,209, 0,172, 41,237, -192, 79,117,205, 4,208,220, 31,188,191,186,125,125,127,240, 65,150,181, 56,241, 37, 73,211,117, 99,137,201, 89, 21,101, 81,219, -110,103,217, 82,194,119,132, 11,182,189,214,209, 26, 22,182,125, 66, 24,224,216,188,203,227,217,177,138, 61, 2, 74,150,103,195, -201,183,142,221,156, 7, 46,236,187,170,165,154, 13, 28, 49, 97,169,141,187,215,238,188,253,244,230,116, 49,105, 27, 77,216,192, -158,191,123, 57,243, 79, 45,228,221,101,183,217, 3,120,193,164, 1,101, 75, 82,202, 78, 81,202,130,246, 59,253,131,233,119, 67, -213,156, 48,172, 42, 31,190,163,169,154,166,232, 39, 14,142,145, 98, 22, 81,152,177,165,105, 50,113,126, 0,154,227,144,101, 65, - 60, 93, 56,128, 47,216, 97,202, 82, 22,184,160, 27,185, 16, 48,139,208,195,126, 70, 96, 18,177,135,119,201, 75,180,243,224, 1, - 76, 10,219,232,123,201,228,246,198, 21, 55,220,123,244,248,197,195, 47, 71,183,158, 60, 32,100,131,136, 30, 49, 34,162,138, 4, -246,231, 38, 35, 81,175, 7,123, 79,247,135, 65, 90, 66,230,161, 43, 73,176,156,204,253, 52,203, 53, 85,150,108, 11,197,245,244, -188,138, 40,176,121,158, 0,226, 59,173,230,102,207, 74,242,116, 25, 23, 18,202,204,240,120, 94, 98, 13,242, 84,170,164,146,249, - 68,113,175, 21,180,143, 22,229,170, 60, 25, 13, 41,149, 32,187, 74,210, 57, 44,114, 83, 54,188, 52,106,239,172, 65, 72, 6,196, -237, 55,208,245,190,101,217, 93,187, 53,244, 66, 72, 84,225,239,207,162,185, 46, 43,157,238,166, 73,201,177, 59, 70,165, 12, 83, - 61, 71,105,204,138,138,213,200,157, 70, 89,178,204,178,153,239,228,204,243, 11, 79,116,105,105, 26,214,238,250,238,199,163,207, - 34,225,224, 94,159,227, 51,190,125, 54,252,141,174,116, 34,249, 52,156, 10,228,156,138,195, 39, 50, 57, 1, 21, 77, 73,221,198, - 68,254, 4,119,254,123,190, 95, 16, 97,187,187,229,248, 14,132, 58,252,107,224,254, 95,127, 30, 66,108,178, 6,186,122,217,197, -121,196,189,126,185,157, 31,183, 46,129, 61,177,224,210, 77, 6, 83, 72,161, 8, 63, 24, 67, 18, 42, 67, 4,150, 75,194,148,199, - 53,200, 87, 85,237,255,200,180,151,186,162, 39, 69, 34,212, 98,148,149, 50,165,190, 35, 79, 17,106,128,252, 37, 0, 97,215,178, -219, 52, 20, 68,239,245,243,218,113,156, 71,211, 54,141,170,162,130, 0, 9, 65,197, 2, 36, 36, 36,190,128, 37, 43, 22,124, 13, - 43,182,236,248, 1, 96, 77,197,170,176, 42,130, 86, 64,161, 72, 5,148, 66, 95,132,208, 36, 77,155,167, 19, 59,182,153,153,235, - 20,138,132,234,110,235,186,190, 55,153,123,102,230,204, 57,218, 41,213,147,211, 46, 29,107,229,209,127,136,140,167, 95,242,228, - 17,186, 13, 1, 77,186, 0,134,236, 79,100,151, 87,128, 6,123,127,167, 11,199,146,238, 10,145,223,229,236, 0, 39, 83, 57,146, -213, 59,249,100,203, 72,245,253,110, 98,103, 34,123,167,180,239,144,101, 39, 92, 81, 58,126, 53,236,233,117, 13,213,218,252, 85, - 30, 43, 80,199, 74,210, 31,145,150, 38, 49,149,140,226,201,204,244,198,222, 6,209, 75, 61, 31, 66,223,184, 17, 2, 59, 51, 12, - 81, 40,219, 27, 14,114,206, 68,123,208,142,227, 17,209, 21,185,180,155, 9,240, 7, 94, 38, 12, 56,121,139, 51,210, 42, 80,152, -176,153, 78,211, 68,148,254,161,124,141,142, 14,221, 58,245, 17, 44,164, 37,132,130, 39,234,134,124, 52, 66,154, 35,202, 97,146, -246,150, 92, 14, 85, 77,114, 20,148,135,151, 13, 40, 64,227, 36,209,203, 36, 97, 88, 46, 88, 4,187, 69,236,119,161, 70, 26,182, -168,252, 48,110, 68, 65,163, 90,255, 28,132,232,197, 7,191,108,232,182, 45, 82,186,238, 10,211,113,236,172,208, 75,134,221,244, -130, 86,111, 56, 12, 2, 26, 13,198,190,141,202, 76,120,100,111,208,124,182,242,152, 18, 11,184,187, 55,240, 3,200, 3, 12, 93, -120, 72,195, 68,226, 90,103,208,134,127, 51,227,228, 33,200, 66,158,128, 77, 36, 92,215,168,235, 1, 50, 66,240, 53,244, 7,181, -206,126,162,227, 70,118,222, 16, 73, 1,233,207,228,103, 43, 7, 63, 32,137, 22,166,232, 99,175, 59,112,237,172, 23, 12,108,145, -129,133,149, 69,212,180, 72,123,104,204,139,204,234,142,119, 8,135,199,116,118, 6,112,116,237,168,106,153,118,193,157,220,174, -109, 69,104,215,160,194,241, 25,196,193,185,226,249, 55, 95, 95, 21,243,165,102,171, 33,132,120,249,225, 69,222, 41,104,232, 44, - 15,169,149,178,189,255, 45,109, 58,128, 16,133,106,112,156, 69, 84, 90,189,150,134, 75,140, 1,119,126,242,204,141, 11,215, 23, - 87, 23,151,222, 47, 77,103, 10,185, 84,214,181,221, 90,171, 6,231, 22,108,195,181,133,155,147,169,236,242,250, 50,108, 86,187, -210,129,187, 92, 52,247, 56, 64, 34, 34,142, 43,155, 25,203,129,151,130, 87,176, 12,177,127,180,143,181,133,144,188,179, 85,245, -234,217,133,225,200,127, 91,126,167,113, 99,110, 98,246,211,238, 23,115, 20, 66,148,167, 33,122, 31, 43,116,244, 33, 71, 74, 99, - 52, 66, 90, 48, 9, 43,162, 51, 37, 11, 51,182,155, 36, 67, 10, 10, 96,193,247, 32,109,185, 5, 43,227,140,182, 86, 90, 59,123, -186,250,224,225,243, 59, 79, 95,223,190,127, 87,220,187,197, 88,137,105, 3, 20, 29, 99,189,224,209,234,242,147, 53, 56, 84, 13, -161,123, 97, 88,175,181, 87,215,183,123,140, 77, 51,150, 99,204,184, 98,198,145,116,240, 76,198, 94, 1,109,216,154,118,169, 52, - 97, 9,181,221, 71,223, 9, 19,141, 80,105, 98,137, 37, 66,189, 84, 10, 1, 56,128,176, 29, 33, 27,231,112,139, 57,162, 4, 90, - 97,213,195, 42,102, 53,140,103, 29,183,225, 29, 21,231, 47, 51,236,200,118,115, 70,174, 30,212, 75,234, 69,141,113,159, 84, 35, - 73, 75,139,101,221,124,115,119,179,118, 88, 15, 20, 78,114, 2, 81, 72,243,180, 40,238,193,248, 78, 99, 23,162, 58, 67,255,166, - 56,159,206,195,199, 3,178,174,242,207, 50,236,212,218,247,143,136,220, 73, 52, 38,102, 73,201,125, 92,188, 77, 2, 78, 49, 87, -130,189,195, 42, 60, 4,131,113, 56,156,114,167,106,221,134, 20, 39, 32, 2,190, 36,175, 68, 73,124, 79,116,119,144, 97,201,147, -224,142,111, 92,105, 86, 66,137,151,153,252, 2, 34,208, 36,221, 2,137,169, 20,105,237, 9,171, 52, 87,152,219,171,239,106,154, - 6, 57, 34,192,124,196, 1,244,103,121,242,252, 40, 30,203, 87,218,134,240,123,125,206,147, 20,255, 24,182, 31,171, 83,186,169, -172,215,242,216, 9, 70,140,242, 15, 29, 81, 94,191, 5, 96,236, 90,118,155, 6,162,232,140,199, 99, 39, 77,157,244, 9, 10,109, - 72,165,150,242,168,170,118,133, 64,128,212, 47, 64,236, 16, 27,182,252, 2, 44,187,224, 7, 96,201, 15,176, 64,192, 55, 32,181, - 21, 84, 44,144,138, 4,148,135, 72,165, 16,151, 54,143,214, 77,236,216,227,225,222,107,167, 88, 80, 9,164,174,170, 72,150,103, -146, 51,247,220, 57,247,156, 19,244,239,255, 15,238,232, 14,166,163, 19, 27, 53,252, 95,152,206,211, 37,192, 15,162,206, 36, 14, - 51, 98,118,254,247,199,141, 63,193, 29, 22, 49, 78,156,100,120,234,200,147, 20, 28,212,130,231,233,133, 3, 67, 51,176,136, 80, - 62, 15,248, 18, 81, 20,137,206, 88,208, 83,121, 66,113,227, 40,209,209, 52,238,156,140, 17,101, 77,234, 7,151,187,116, 39,138, -167,162, 16,150,149,139,209,160, 35,164,155,216,248,216, 51,130,178, 9, 99, 64, 34, 4, 90,172, 98,144,127, 64,237,221,210, 0, - 75,129, 39, 85,144, 99,145, 68,221,184, 70, 41,147,101,161,132,222, 6,110,160, 67,169, 35, 11, 7, 87,185,141,166,144,202, 84, -202, 4,240,183, 12,155, 52,224, 86,206,132,202, 74, 22,242,214, 88, 73,150, 74, 98,196, 17,163, 37,233, 12,227,248,168,193, 4, -176,102, 0, 50,165, 4,182, 49, 25,169, 55,113, 48,197,224,192, 51, 81,168, 76,234,100,148,189,113,146,231, 99, 94, 0, 60, 31, - 42,117,248,179, 36, 62, 0,158,131,129, 76,166, 0,122,223, 99,170, 19,246,221,158,247,253,160,233,121,129,101, 90,120,162, 36, -209,204,100, 73,146,100,181,161, 11, 13,118,249,101,159,162,159,177,167, 44,236,195, 46, 14, 92, 40,186,255,130, 77,232, 5,222, -245,139, 43, 36, 75,199,178, 72,160,114, 90,164, 78,170, 90, 79, 56, 19, 80,255,226,116,174,204, 17,104,171,233,177, 42,172, 94, -212, 71, 99, 91, 32,100,240, 14,176, 66, 29,175, 83, 30, 47,187,173, 31,152, 13,133,186,253, 68,195, 26, 47, 86, 23,127,182, 93, - 88,240,133,202,210,254,225,254,217,211,213,237,250, 71, 88,137, 32,236,211,149, 56, 7,182,110,153, 54,252,180,234,205, 58,217, -209,132,240,187, 18,134,188, 60,127, 21, 56,248,129,223, 17,192, 29, 21, 26, 2, 43,218,205,196, 44, 69, 81, 44, 9, 96, 49, 37, - 68,114,103,104,120,102,114,102,253,195, 6,166,193, 72,121,228,119,225,104, 25, 41, 56,231,202,179,161,138,108, 83,110,188, 95, -223,113,107,203,115,203, 95,220,111,192,181,225,197,209,248, 27, 77,232,112,160,209,243,189,202,248, 84,163,189, 11,236, 1,222, - 40,111, 13, 9, 46,128, 25, 0, 42,193, 78,212,118,107, 23,166,206,215,118,119, 34,173, 90, 94,123,190, 60,215,104,187,125, 88, -129, 24,155, 75,240,229,129,175, 8, 28, 60,213, 73,116, 49, 99,169, 11,109, 12, 7, 76, 28, 71,194, 52,155, 94, 19, 74,129, 75, -103, 23,128, 3, 97, 14, 7,172, 96,239, 96,116,168,254,186,225, 66, 49,124,171, 27, 57,123,221,181,151,155,141,213,103,123,111, -182, 42, 97,208,122,254,142, 61,253,180,246,106,187,103, 99,211, 60,196, 84, 85, 93,109,118,239,239,119,238, 48,118,147,177, 77, -198,222, 74,227, 76,193,246, 9,183, 20,176, 55,160, 32,195,249,165,202,164, 50, 96, 71,250,210,228,142,105,230,164,137, 65, 2, -100,141, 72,161,189,169, 42,153, 19, 96, 2,226, 91,166, 81,202,219, 54,179,106,123,133, 8, 77,107,204, 36,134,193,136,140, 71, - 91, 47,110,175,220,189, 49,123,101,245,201,234,189,169, 7,143,221,135,213, 82,229, 90,241, 84, 27,205,132,121, 63, 68,211,132, - 14, 94,119, 11, 63, 82,227,197, 81, 32, 85, 45,212,167,197, 73, 52, 88, 68,165, 58,206,115,192,118,234,104,122,162,242,185,241, -149,200, 77,146, 84, 71,118, 37,177,206,160, 93,156,133, 18,248, 23,112,166,100, 74, 53, 51,180, 31, 31, 6, 71, 44, 53, 33, 75, -134, 4,126, 79,224,232,129, 35,187, 30,116,122,116,154, 44,193, 83,169, 36, 31,152, 75,167, 70,108,199,226, 67, 62, 16,149,242, -174,143,102,159,197, 66,209, 15,125, 84,194,164,142,109, 73,229,153,130,123, 34,210, 15,194,128,242,245,120,166,120,103,199,217, - 91,176,251, 30, 53,238,105, 80,199, 48,178,163, 63,196, 15,178, 96,251, 75, 0,206,174,101, 55,137, 40, 12,159, 57,115,165,204, - 48, 12, 32,180, 67,211,212, 40,144,168, 81, 55,198,244, 9,234,194,173, 11,223,192,173,111,226,198,173,235,190, 65, 19, 99,188, - 36,221, 20,141,177,105,172,212,218,212, 88, 13,148, 22,152, 50, 3,204,133,153,241,255, 15, 67, 29, 19, 99,140, 27, 66,200,228, -204, 97, 46,223,127,255, 62,225,255,220,246,191,224,120,218, 78,200,188, 18,132, 46,249, 61,187, 18,167,134, 84,255,229,164,233, -185,214,121,143, 60,199, 68,130,184,170,177,114,220,251,202,165, 38, 97, 85, 69, 3, 68, 5, 28,193, 81, 99,180, 25, 51,118,207, -120,226, 79, 18,132, 38,100, 65,202,250,168,176, 30, 94,116,227, 48,182, 32,180,177, 33, 83,240,194, 56, 96,222,117, 52,171,224, - 37,235, 99,115, 18,117,189, 17, 56, 84, 57, 94, 84, 51, 57,111,120, 6,102, 10, 34,196,156,146,183,253,243, 89,170, 47, 35,169, - 24, 94, 33, 37, 36,106,161,192,151,129, 16,198,156,196,104, 26, 49,208,102,140,242, 44,121, 2,107, 3,246,179,187, 41,240,216, -132, 78,177,175,142,195, 30, 2,102,190, 51,178,160,100, 4,198,215, 2, 49, 29,132,195,177, 40, 19,145, 70,163, 49, 4,230, 49, - 19,106,167,138, 4, 70, 0,183, 6, 0, 42,241,140, 70,117,202,158, 79,137, 17,255, 98,183, 3, 97,180,245,248,140, 4, 72,237, -139,106, 71,178, 12,192,129,219,112, 93, 14,121,202, 88,165, 90, 4,219,130, 68,186,176, 19, 26, 96,202,140,165, 26,167, 76,218, - 44, 64, 94, 11,166,125,129,253, 8,178,136, 61, 97,170,146,207,202, 26, 64,213, 82, 97, 21,204,231, 97,187, 5,255,125, 60,177, - 99, 86,225, 96,137, 17,244, 33,182, 62,190, 6,239, 85, 66,234, 75,202,230, 26, 66,184, 39,224,161,123,161,215,106,127, 42,169, - 37,128,188,190,115, 26, 49,106,184,190,115, 38,112,130, 53,177, 20, 65, 1,200, 91, 42, 46, 3,234, 85, 75, 70,235,251, 62, 90, - 43, 81,138, 81,233, 16,130, 83,136, 30,236,183, 7, 77,128,251, 59,181,181,158,115,106,168, 70,167,223, 6,171, 5, 17,155, 63, -182,192,174, 0, 76,148,115,149,238,240, 4,142, 84, 51, 11, 19,215,163,130, 16, 6, 65, 78,215, 94,237, 60,135,139, 0,126, 80, -103,216, 17,147,153, 28, 46, 35,168,166,177, 8,239,225,192,233,151, 13, 83,161,226,153,221, 1, 43,102,141,206,155, 7,205,181, -198,221,189,163, 93, 31,173, 46,191,190,118,111,227,197, 6,156,162, 81,173,235, 56,166, 52,184,106,214, 44,215, 46,235,165,147, - 65, 23, 59,154, 73,124,227,242, 77,123,100, 45, 26,139,123,199,251,102,201, 4, 12,242,167, 62,141, 99,184, 20,171,149,149,129, - 67, 43,122,165,168, 21,183, 63,111,191,220,125, 3,207,106, 73, 45,130,157, 61, 60, 57, 4,231,174,172, 27,148,138, 96,138,126, - 88,109,215,245,134,209, 16,169,140, 48, 17, 10,246, 95, 41, 40,133,142,213,129,139,105,187, 78, 62,171,215,205,198,251, 47,239, -242,154, 30,132, 28,236,164, 86,208, 58,129,133,210, 17,224, 44,139,242,125, 44,195,144,199,132, 60,217,220, 89,223,106, 61,186, -213,184,189, 84, 55,151, 11,199,182,131,141,162, 24, 10,146, 77, 23, 37,236,193,121,127, 70,200, 83, 56,186, 61,184,166,103, 33, - 14,244,167, 88, 51,188,110, 22,203,122,102,236,121, 18, 79, 12, 77, 86,100,158, 17, 23, 33,244,135, 33,135,140,193,209, 76, 31, - 34,201, 99,227,227, 77,169, 34,136,133,236,130,139, 33, 47,242,148,193, 39,143, 69,222, 88, 36,162, 77, 38, 15,107, 15,200, 7, -124,195, 12, 33, 31,120,195, 2, 54,222, 83, 8,103,235,213, 43,142, 55, 57,234,126,131, 21,123, 99,108, 75,239, 58, 61,207, 7, -204, 7, 15, 2,171,246, 62,130,252,148, 41,189, 79, 97, 3, 37,237, 18, 74, 42, 38, 18, 26, 28, 19,151,140,231,234,163,105,122, - 68,238, 98, 12,127, 46, 16,146,128, 82,152,252, 74,211,181,189, 40,230, 82,189, 29, 23,191,113,243,101,162,185,224, 93,196,198, -175, 80, 55, 40,250,165, 68,148,102,221,154,101,213, 89,163, 28, 43, 86,247,135,125, 3, 11, 60, 54,211, 9, 9,231,251,156,213, - 9, 18,249,167,138, 97,182,251,237, 56,201,200,179,204,123, 2,238,113,210, 10,153, 84, 16,102, 85,188,100, 20,246,143, 24,252, - 83, 0,214,174,166,167,137, 40,138,206, 71,223,155,233, 76,235, 88,104,139,130, 20, 2, 41, 98, 52,129, 64, 72,140,137, 43,163, -254, 3, 99, 98, 98,226,202,191,224,207,240, 71,184,214, 5, 27, 89,168, 44, 52, 36, 38,178, 49,209, 5, 31,242, 93, 10, 45,181, - 67,203,204,155,143, 62,239,125,111,166, 34,186, 52,108, 8,105, 74,166, 51, 61,247,220,251,206, 57, 23,243, 9,224,229, 93, 37, - 84,254, 43,184,203,223,169, 70,229,116,229, 66,230,123, 86,183, 88,236,241, 52,110, 62, 75,108, 85, 14,170,254,218,244,116, 1, -217,229,225,178, 56,254, 79, 3, 75,147, 34,121, 62, 23, 77,150,102, 85,237,135, 21,167, 55, 58, 17, 40, 37,252,253,247,220,141, - 64, 31,137,252, 29,161, 28, 64,216, 38,240, 52,119,164, 13, 36,221, 6,134, 49,228,106,255,108, 31,227,130,117, 49, 78, 80,203, -206,200,161,187,107, 17, 11,104, 38,238,117,195,105, 9,202,169,165,149, 27,240, 50,180,161,197,150,128,157, 17, 4, 90, 77,189, -213,194,186, 30,163, 2,221, 36,128,239, 40, 29,214, 51, 98,145,183,200,147, 71,177, 5,213,156, 60,112,118, 65, 20, 52, 30,137, -200, 70,177, 31, 53, 14,165,133, 3,111,190,230,121,226, 97,137,162, 0,153, 65, 8, 77, 60,116,198,184,119, 24,111, 1, 74, 77, -100, 31, 8,111, 28,192,231, 46, 44, 31,148, 34,193,135,247, 10, 98, 25,243, 12, 28, 86, 33,186, 2,127, 54, 13,124,101,140, 2, -121, 14, 95,221,179, 70,116,153,228,124, 22, 15,231, 42, 65,236,237,159,236,141,151,171,199, 39,117,184, 95, 10,210, 40,244,215, -217,120, 62,134,174,111, 47,196, 9, 21,209,141,128,121,162, 27, 74,154, 26, 77,168, 6,180,148, 29, 3,180, 29,181,235,102,198, - 48,168,229, 7, 29,184,162,153,241, 89,104,153,129,140,231,178, 54, 26, 20,116,114, 10,160, 76,115, 29,168,166,170, 50,228,148, -218, 93, 23, 96, 93, 16,106,185,145,134, 27,212, 24,204,193,215,123, 31,157,126, 60, 30, 30, 24, 61,114, 15,101,118, 28,124,136, - 66, 37, 37,131, 1,228,214, 47,252,185, 55,123,127,113,229, 13, 69,137,184, 41, 98, 67,112,146,141,147, 6, 33,107,147,162, 5, -185,144, 0,218,158, 75,102, 14,202,107,193,114,226, 8,104,122, 8,148,217, 34,134, 69, 76, 32,213, 7,205, 3,130, 13, 17,116, - 84,154, 72,134,192,249,129,220, 49, 52, 86, 30,107,184,205,133,169,249, 72, 83,150,191,188, 7, 40,156,171, 46,140, 15,141,190, - 93, 93, 42,228, 7,136, 74,214,107,107,112, 9, 69,167,236,250, 46, 99,190,136, 85, 84, 43,165,202, 94, 3,247,242,220,158,158, -251,113,184,221, 60,109,193, 21, 64, 3, 1, 8,158,207,230,197, 65,136,127,227,218,212,215,237,239, 35, 80,129, 66,175,254,243, -120,172, 92,129, 43,219,168,173,217,134, 21,246,152,158,136,191, 50,143,167, 7,151, 15, 62,125,222,111,212, 24,219,241,109,239, -204,175, 41, 12,167, 55,126,116,167, 88,120,245,224, 73,219, 39, 35,197,173,111,205, 22, 0,124, 23,250,156, 40,126,189,229,126, -108,251, 81,134,251,204,103,103,221, 40,100,207, 39,175, 0,213,176, 40,157,175, 20,117,138,137, 26, 5,155,230,105, 70, 90, 63, - 68,254, 41, 60,111,106,200,161, 92,114, 15,131, 85,197, 9, 84, 98,121,213, 1,220,203, 78,222, 80,244,189,102,171, 86,191,190, -203, 34,138, 57, 40, 40, 3,152, 48, 71, 31, 46,189,224,239,248,206, 98,115,242,229,204,135,185,149,187,171,149,167, 55, 31, 61, -155,184,181,217,105, 20,115, 78,196,163, 86,199, 85, 48,241, 73,166, 20,160,125,181,228,148,215,235,219,248,239,224, 78, 96,170, - 62,218, 74, 0, 54, 3, 20, 37, 51, 46,250, 12,220,224,142,103,170,194,254, 36, 37, 43, 80,135,120, 31,220, 37,150,196, 23, 44, - 62, 92,225,253, 33,206,111, 44,239, 37,150, 40, 53,149, 42,246,100, 94,165, 96, 90, 60, 57,109,198,210, 0, 37,217, 99, 94,245, -106,117,163,190, 41,166, 58,242,192,130, 11,245, 50, 90,181, 77, 98, 66, 69, 47,229, 75, 64,186, 89,232,159, 55,240,240,115, 51, - 25,158,172,205,139,165, 72,179,151,134,175,136,109, 11,189,100,113,181,250, 7,140,202,206, 73, 52, 76, 82, 91,255, 15,170,252, - 75, 0,210,174,156,183,137, 32, 10,123, 79,239,250,218,245,149, 40,241, 38, 8,145, 68, 65, 38, 8,129, 16, 5,135, 20, 34,148, - 34, 63, 3,137,146,130,142, 46,127,128,154,158,154, 38,226, 71, 80,128,148,138, 2, 69, 20, 78, 72,156,216,137,143,189,103,175, -225,189, 25, 95,208, 34,165,112, 20,219, 89,123,230,189,121,239,237,119,204,231, 51,255,153,220,255,153,170,240,212,188,160, 64, -176, 56,120,161, 9,157,132, 22,255, 61, 65,190, 89,188, 8,114,167, 51,144,110,142,163, 71, 57,235, 14,189, 47, 32, 66, 24, 40, - 84, 96, 19, 30,137,235,218,149, 53, 35, 97,139, 50, 81, 18, 91, 52,123,101,149,105,189,188,228, 67,247, 55, 99,247, 78, 25, 20, -240,208,208, 77,254, 39,126,158,151, 52,195,157,144,196,184,226,134,168, 72,200,189,226,220, 95,120,205,253,219, 15,221,192,206, - 43, 5,248, 63,176, 97,189,200, 65,190, 28, 26,101,224,226, 97,233, 34,114,179, 22, 42, 22, 21, 27, 98, 38,202, 16,183, 77,153, - 68, 42,142, 32, 37,164,119, 75,178,174, 41, 69,200, 22,178,204, 36, 61, 36, 4,201,163,139, 1, 62, 1,182, 73, 20,198, 77,163, - 82,200,171,246,216, 97, 30,221, 90, 6,241,135,247,180, 36,180,250, 99, 82,190,172, 85,148,117, 89,170,154,121, 67,167,138,152, - 30,188,124,241,254,221,219, 87,207,159,246,122, 87,221,254, 80, 65,244,136,192, 38,154, 40, 87,131,168,115,252, 56,136, 6,103, -201,150,162,111,132,132, 53, 59, 78,133,100,252,129,182,154,239, 58,120, 50,137, 51, 47,164,196,131,224, 84,226,148,220, 56, 55, -182,103, 67, 0,105, 82,161,111,247, 56,137, 88, 87,208,223,220,137, 60, 18, 65, 51,157,114,101, 42, 85,206,227,167,160, 81, 54, -151, 64,194,114,131,205,132,160,250, 83, 16,179, 8, 7, 42,134, 37,156, 13, 37, 88,253,238,240,226,205,254,235,111, 39,223,211, - 44,137, 82,210, 44, 47,147, 24,201, 98,240,146,136,132,112,213,144,238,239,172,108, 13,156, 62,101,249, 29,243,106, 78, 26,249, -131, 28, 19,101,224,246, 17, 16,131,123, 15,246,127, 15, 78, 55, 87,183,123,163,139,138, 94,133, 69,209, 20, 29, 85,159, 24,220, -175,168, 22,221,208,151, 36, 57,136,124,230,226, 43, 48,209,157, 52,206, 18, 21, 37, 71,144,165, 9,173, 24, 28, 36,144, 40, 21, - 89,113,252,177,200, 60, 77,242,170, 58,246, 6, 30,241, 29,223, 30,184, 3, 88,221,157,245, 54,100,127, 55,116,217,240,149, 66, -171,106, 53,172, 74, 1, 54,143, 7, 13,199,217,245,121,231,178, 99,213,215,116, 93,235,217,215,199,191,142,225,204,131,239,186, -172, 85,158, 61,222, 51,107,203, 39,167, 63,225,208,106,175,181, 55, 90, 27,171,181, 86,189, 82,133, 47,115,169,218,128,205,118, - 57,236, 71,232, 77, 97,194, 91, 5, 49,129,190, 4,109, 35,147,168, 59,186,130,210,117,232,141, 93,196, 17,208,161, 55, 26,162, -221, 4, 58,139, 65,195, 32,178,155,119, 26, 85,118,183,114,199,151,231,231, 78,224,199,241,118, 97,197, 50,205,166,166,149,100, - 1, 78, 5, 69,212,119,215,219, 25, 13,134, 89,207,142, 99, 77,146,145,213,142, 96, 35,209,144,245, 38, 52,134, 36,116, 9,148, -245,217, 78,189,244,168,213,188,219, 50,203, 5,209, 50, 85,171, 90,168,149,212,162, 46,162,240,156, 44, 48, 71, 51, 30,174, 34, - 35,162,115, 41,109, 28, 63,195, 74,168,130, 92, 43,106,107,117,227, 71,167,239,103, 36,159,214,186, 33, 83,184,197,186, 76,118, - 3,242,229,236,235,225,199,195, 79, 31,142,186, 29,123,179,214, 58, 26,125, 62,176,158,200, 66, 18,160,161, 93,128,126,167, 40, -222,139, 23, 70,178, 40, 78,211, 48,141,161, 47, 65, 3, 99, 40, 97,104, 18,162,187, 77,100, 84,234,118,224,196, 40,115, 73, 25, - 25,146,194,209, 83,212,208,175, 14, 22,228,222,173, 54,108, 87, 12,113, 94,217,207,241, 6,139, 52, 26,220,172,185,108, 38, 42, -240,215,109,202, 85,115,197, 70, 31,115, 58, 85,247,157,235, 37,208, 41,158, 40, 67,173,167, 88, 83,242, 14,241,195,136,176,156, -148, 88,181, 53, 23, 77,134,217,240, 30, 97, 0,184,207, 57,154, 83,149,212, 70,185,225, 48,123,116, 94,219, 79, 51, 59,157, 64, - 34,179,201,192,158,161, 56, 83,166,157,144, 78, 46,143,185,100,230,152, 30,191, 48,225,116,114, 76,253, 76, 12, 81,156, 41,220, -207, 82,223, 31, 1, 88,187,114,222, 38,130, 40,188,179,183,119,189,137,131, 19,146,128, 19,142, 24, 17, 2, 2, 20, 34, 26, 16, - 66, 28, 66, 52,252, 3, 10,132, 16, 8, 36,132,132,232,104, 41,105,248, 15,208,240, 19,104, 41,104,136, 16,132, 16, 33, 14, 67, - 78,199, 78,178,182,247,240,236,201,123,207,187,193, 18, 45,157, 37,219,205,211,204,187,230, 59,254, 79,126,255, 55,215, 75,125, - 92, 83, 49,151,100,220, 53, 3, 97, 25,195,153,245, 25,242,253,117,230,203,183, 45, 44,255,175,184,251, 85,254,108, 77, 27, 63, -104,142, 85, 19, 90, 96,145, 60, 24, 33, 26,210, 95,118, 89,127,189,193,224, 81,145,239, 51, 10, 39,176,168,165, 23,187, 81, 64, -252,180, 4, 50, 8,109,240,147, 46,250,151,167, 61, 31,200,172,150,231,164,183, 4, 33,177,241,250,206, 10, 92,108, 47,114, 85, - 89,245,208,198, 37, 38,206, 2,185, 15,136,153, 66, 39,100,156,202,222, 97,102, 18, 5, 87,150, 36,150,225, 40, 33,183, 22, 13, -197, 42,224,214, 27, 65, 42,112, 47,227, 20,237,147,209,164, 5,107, 54,138,237,137, 12,154,243, 27,215, 47,191,126,245,242,246, -157,123, 51,213,234,194,194,151,141, 6,170, 11,225, 82, 69, 79,160, 69,130, 27,205,185, 8,253,162,174, 74,134, 33,115, 30, 59, - 78,124,247,214,221,135, 15,158,236,236,116, 70, 71,199, 32,184,139, 75, 95,116, 53,181,160,132,104,130, 89, 80,112,163,143,104, - 7,129, 7, 33, 20, 24,175, 11, 53,135, 13, 15, 21, 93,199,197, 37, 78, 42,133,248,120,140,142,225, 65,128, 90,127, 48, 76,147, -196,134,160, 68,154, 33,233, 66, 36,106,146, 65,110, 27,126, 27, 13,172,113, 75,163,203,150,219,117,224, 84,181, 60, 4, 12, 16, - 25,152,141, 88, 99, 14,239, 4, 84,194,201,138, 25,167, 17, 67, 53, 85, 85, 71,234, 16, 46,124, 3, 68, 34, 33, 50, 93,204, 64, -197, 66,172, 48,249, 99,237, 83, 24,241, 98, 97,224, 88,229, 56,252,102,187,211,180, 61,155,135, 30,244,233, 60,116, 33,195, 4, -100,109, 60, 96, 88,221,192,131,243,110, 42,134,174, 24, 3,186, 69,230,218, 62, 36, 80,200,191,245,118,189,227,182,182,218,155, -112,242, 35, 84, 66, 76,160, 18,107, 10,105, 77, 39,136,134, 34,165,226,224,226,201,171,136,232, 71, 61, 55,244, 21, 52,212,162, -165, 89, 62,162,200, 35, 36,213, 11,233,185,153, 11,123,138, 37, 30, 5, 72,221,101,108,223,208, 62,215,247, 6,205,193,179,213, - 51,227,165,177,179, 71,230,126, 53,151, 75, 70,113,203,181, 77,221,156, 26, 61,220,236,108, 79, 12,239,111,116, 26,231,103, 47, - 45,253, 94, 20,101, 41, 65, 34, 50, 90,180,107,178,234, 67,142, 34, 62,203,186,189,254,181,182,184,178, 94,131,134, 26, 46,238, -233,195,167,230,127,124,248,177,241,253,103,189,102,123,173,205, 22, 84, 47,182,229,108, 83,235,200,102,171,179,171,219,107,211, - 19, 71, 57, 15, 52,136, 30,106,163, 35,146, 86,200,149,105,119,101, 77, 42,229,131,189, 55, 91, 93, 96,215, 78, 20, 62,172,110, -214,125,223, 14,184, 41,153, 80,205, 97,248,244,163,168,205,187,203,142,123,121, 66, 88,234,124,123,191,182,241,166,182, 12,127, - 24,179, 44, 89, 76,187, 49,251,102,243, 38,247, 86,218,157,118,200,203,162,120,127,174, 58, 61,110, 76,150,213,201, 61,133,242, -128, 6,129,134, 81, 37,243,119,237,249,138,244,166, 97,252,128, 74, 6,138, 44,193, 81, 52, 53,217, 82,148,189,165,194,244,161, -145,182,195, 63,175, 54,177,215,143,138,107, 62, 52,239,201,232,224,184,156,136, 11,205,229,249,198,206,211,103,143,159, 63,122, - 49,103, 94,217,146,107,111,221,119, 55,167, 46, 76,237,175,172, 52, 54, 18,194,176,147,190, 6, 17,174, 19,116,169,134,132, 24, -166, 9,196,217, 9, 92,212,224,139,131,145,210,120,195,110,194, 76,131, 23,146,176, 50, 49, 57,163,226,164, 69, 2,153,117, 4, -161,155, 97, 28,103, 76,221,204,118,148,245,203,167, 83,239,153, 26, 10, 10, 76, 66,106, 24, 50,134, 16,159,157,231,119,135, 59, -112,174, 38,135, 39,219,112,102, 8,202, 65, 6,160, 73,254,104,151, 77,144, 80,177,160, 43, 71,227, 95,145, 28,104, 34, 68,208, - 67,187, 32,102,162, 6,189, 77,130, 72,171, 24, 18,230, 11,221, 36,205,120, 86,121,102,239, 77, 2,140,229, 15,218,164, 9,132, - 29, 89,165,124,192,118, 91, 36,233, 30,247, 28,117,122,137, 48,217, 5,143,167,100,152,158, 17,248,255,213, 31, 72,255, 8,192, -217,181,180, 54, 17, 69,225,153,201,244,206,100, 38,175, 54, 73,155, 62,172,210, 46, 68,164,136, 40, 86, 91, 16,235,171,116,171, -155,138, 5, 21,252, 1,226,198, 86, 10, 82,172,160, 86,220,248, 27,220, 11, 86, 20, 4,139,219, 34,138, 82,211,151,109,218,216, - 87,250,176, 73,218,100,222, 19,207,185,119,210,135,232,198, 77, 8,116,146, 78,102,230,158,251,157,243,157,243,125,255, 25,223, -249,127, 56,239, 9,123, 34,251,222,106,212, 95,177,190, 39,215,190, 59, 43,189,251,215,242, 54, 32,240,229, 16,143, 52, 61,199, -108,105, 4,193,155,208, 96,196,132,195,166,126, 89, 9,131,130, 24, 68,207,180, 47,194, 41,255, 39,129,178,166,251,115, 12,108, -148, 52,118,206,162,172, 69,204,197, 2,113, 34,202, 58, 34,184, 29, 3, 17,220, 66,227,161,154, 34, 64, 63, 74, 36, 1,178, 67, - 80,142,217,150,187,171, 91, 15, 96, 86,244,151,112, 14, 3,235,140,126, 73,210,121, 72,120,241, 38, 19, 34,134, 20, 18,196,230, -112, 81,146, 81,170, 9,246, 96, 3,141,210, 56, 17, 69,180, 5, 63, 28, 16, 32, 17, 85,174, 10, 34, 74,106,168,142, 12,244,223, - 31, 30,126,253,246,205,240,249,142,142,174,206,206,201,201,241,133,165, 21, 1,123,251,124, 84,234, 13, 35, 53,173,227,251,116, -195,222,202, 27, 55,186,187,123,186,175, 61,126,254,244,209,208,208,135,145,145,169, 31,211,182,165,117,180,181,222,234,185,198, -217,230,207,116, 58, 18, 9, 61, 25, 24,236,186,120,105,108,236, 91, 65,211,164, 10,241,225,189,187, 15,250,122, 57,199, 72, 78, - 36, 67, 42,241,188, 8, 75, 28, 65,214, 12,246, 24,188,173,176,158, 81,227, 69,179, 32, 38, 66,120,210, 45,131, 10,231,243,140, -151,134, 69, 24, 11,196,242, 58,132,123,116,224, 43, 26,133,198,104,211, 90, 46, 3,231, 5, 24,156, 47,211, 22,138, 28,160,182, -233, 16,158,173,171,237,221,233, 76, 10,155,172,233,252, 20,128,146, 88,184, 26, 94,233,253,226,240, 61,199,165, 50,179, 91,219, -185, 10,145, 68, 3,113, 42,186,109, 50,201,126,248,126,148,196,227,113, 38, 5, 30, 1, 52,176,183,117,205, 49, 32, 4,155,182, - 85, 27,169, 93,207,175,162, 90,128, 63, 44, 19, 63, 44, 78,139,142,167, 1,212,132,227, 67,106, 68,183,182, 96, 37,147, 10, 9, -226,254,244,226, 56,108, 3,186,165,159,104, 62,181,176, 49, 7, 33,163,104, 98,251,150, 76,148, 11,199,206, 37,231,191,103, 11, -155,139,107,105,147, 85,122, 57, 62,167,109, 82,114, 30, 18,154,226,252,234,124,162,178,246,203,236, 87,120, 78,178,133, 44,124, -231,218,246, 90,193,208,224,226,152,142,253,105, 98,244, 64,188, 17,178, 4, 88,146,137, 72,117, 75,235,217,185,212,148, 97, 25, - 76, 75, 69, 33, 74,208, 31,146,136, 2,207, 85,219,145,211, 99,115,201,165,236, 50,205,123,152,156, 56,118,175, 67,176,160, 63, - 86,155,207,164,117,219, 90,220, 88,130,220, 37,172, 70, 26,226,141, 40,108, 75, 47,100, 93, 52, 1, 25,131, 95,194,193,108,212, - 97, 54,114, 2,103, 43,129,202, 88,201, 62,217, 94,189,178,188,158,213,140, 77,200, 28, 93, 94,179,177, 91,182,232,152,155,122, - 81,179,220,203,245,137, 90, 85,106, 73,168, 65,128, 7, 14, 87,163,194,201,248, 98,138,242,126, 38, 51,147,203, 42,190,210,205, -195, 13,207, 58,143,158,105,130,156, 66,174, 10,201,168,255, 12, 64, 6,213,129,217,172, 39,239,185, 53, 83,106,145, 9,204, 65, - 54, 8, 73,100, 64, 34, 97, 69,172, 9, 41,245,135,162,156, 74, 62,142,206,234,148,191,241,185, 34, 17, 14,174,195,213,182,173, - 0,239,127,151,250, 28,115,155,111,247, 95, 31,236,123,113,167,185,247, 85,246,229,172, 61,119, 37,113, 60, 83,252,149,215, 10, - 46, 85,130,100,244, 41,188,162, 69, 53,186,166, 56,176, 86,240,242,226,142,237, 26,244,128,130,169, 37,170,234,242,216,133,226, - 6,229, 32, 85,185, 40,178,201, 91, 22, 51, 72, 5,129,207,209, 58,134, 87,142,103,182,209, 46,245,231,115,153,215, 52, 50, 82, - 6, 45, 94,194,175,144,116,175,126,226,201,199, 64,220,205, 1, 18,199,134, 26, 44,139,215, 71,235,225,131,134,101,122,229,120, - 10, 95, 28, 44, 97,122,166,121, 20, 42, 32, 1,230,141,222, 9, 30,127,139,131, 87,216, 1,196, 10, 12,229,160, 78, 43, 60,212, -118,133, 41,101,120, 69, 33,183, 76,223, 66,106,178,165,229,177,167,205, 41,253, 97,121, 90, 78, 53,184,168, 26, 21,125,196,116, -116, 70, 42,236,139,238, 52,167,249, 45, 0,105,215,242,211, 68, 28,132,187,175,110,183,187,219,165,143, 32,149,130, 16,208, 72, - 12, 42, 33, 18,245, 34, 32, 70,241,113, 50,122,225,100, 60,249, 8, 68,188,105, 60,152,104, 34,122,241,194,159,224,149,120, 48, - 38, 30, 37,162, 72, 66,124,159,136, 81, 81, 35,150,176,180,108,187,191,118,183,219,117,102,182, 69,144,163,215, 77,147,118,183, - 59, 51,223,252,230,155,239,251,223,252, 30, 36,119, 5,138, 55, 82, 89, 42,155, 85,192,184,205, 25,253, 95,132, 78, 35, 12, 94, - 14, 41, 17, 94, 47,227, 42, 41,191,126, 61, 84,199,236,245,210, 20,152,244, 2, 50, 14,254, 61,158, 56, 24,124, 82, 75, 65,223, - 26, 72, 40,173,215, 9, 63, 20,156,186,113, 94,221,180,132, 11,109,221,210,173,229,110,110, 75, 1, 2, 12,192, 92, 91, 37,129, -233,186, 61,174,223,104,164,179,249, 95,129,112, 82,109, 99,130,216, 58,104,245,199, 9,244, 49,156,190, 16,119,203, 23,112,251, -199,143,235,178,162,225,192,148,167, 61, 84,145,134,221, 72, 56, 65,177, 57,158, 28,156, 81,123, 0,229,218,101, 30,176, 15,128, -122, 69,174,170, 74,200, 41, 21,134,143, 15, 52,103,210,247, 38, 30,204,205,191,155,121, 53,123,168,239,224,224,145,254,143,159, -222, 88,107,102, 88,146,170, 85,161, 66,179, 30, 40, 54,142,235, 47,175, 20,206,157, 57, 53, 54, 58,126,119,226,254,212,147,103, -208, 81, 71, 20, 81, 18,253, 84, 66, 29,189,114,121, 96,240, 68,123,199,206,169,199, 79,251,122,251, 46, 93,187,222,190,171,107, -105,241,219,235,249,183,137,134,228,248,216,104, 75, 91,107, 92,147,167,167,159,151,113, 41, 16, 33,138, 16,152,156, 19, 29, 19, -210, 14,114,112, 28,223,119,185,136,168, 58,110,153,136, 70, 53,250, 47, 46, 14, 34,129,193,133, 20, 67,146, 70,104,213,228, 97, - 28, 66,152,121, 81, 57,134,218,156,142, 29,204, 88, 92,244, 29,193, 46,229, 75,246, 51,115,138, 56,120,230, 67,186, 28, 67, 7, - 90, 49,108, 57, 22, 32, 47,192,206,165,114, 17,174,192, 3,147,194, 18, 29,220,121,221, 59,246,114,156,176,198,114,212, 71,121, - 36,165,128, 99, 12, 37, 28, 65,195, 82, 98, 74,192,251,221,160,198, 85, 89, 63,127,113,100,238,229, 44,148, 76,228,158,186,142, - 22,213,237, 50,148,191,114, 58,217,156, 47,172, 0,242,221, 22,111,206,219,104,220,129, 13, 10,249, 88,194,215,193,239, 73,234, - 88, 87, 82,177, 70, 8, 91, 40, 15,191,204,159, 56, 6,193,150,139, 30, 7,134,174,215,209,212, 97,163,136, 96,216, 33, 14, 79, -111,231, 62, 69,138,124, 55,127,144,239, 46,110, 31, 66, 55,153,212,227, 69,167, 4,245, 38,207,114,112,227, 75,185,236,194,194, -251, 98,137, 65,246,129,231,131, 38,200,118, 14,146, 53,244, 49, 78,213,205,230,150, 1,158,227, 90,130, 20,214, 85, 3, 85,230, -229,232,106,209,130,103, 11, 21,162,232, 22,144, 49,197, 11,201, 88, 98,141, 21,172, 18,160,251, 44,137,195, 8,109, 77,237, 75, -230,111, 0,155,128, 31, 49,120,189,146, 72,227,248,168,210,176,163, 90,233, 58,214,108,152, 5,168, 46,174,235, 21, 42,206,226, - 90, 97,209,178, 76,219, 94, 97,120,112, 49,178,187,101,127, 90, 75,104, 34, 99, 94, 90,143,115,130,200, 92,167, 65, 84, 62,254, - 48, 47,244,100, 30,158,238, 62,123,184, 45,189, 93,147, 99, 34, 30, 29, 18,199, 70,172,233,241,109, 32,147, 5, 1, 41, 32,103, - 0,128,130, 42, 3,114,151, 12, 53,156,130,122,208,146, 12,181,166, 62,188, 88,248,178,108, 1,218,135, 52, 13,193,104,218, 6, -243,188,161,158,129,182,120,230,206,204,163,225,254,147,195, 7,134,110, 79, 78,222,234,188,122,243,235,141,164, 22,235, 51, 50, - 89, 27,217,253, 14, 49,179, 16,191, 35, 57,160,130, 30, 35, 94, 37, 44,171,144, 97,161,224,185, 53,137,118, 31,250,102, 72,245, -171, 44, 31,140, 31,109,136, 25, 86,164, 12, 30, 80,200, 81,137,132, 58, 36, 66, 35, 53,130,164,175,202,170, 22,137,176, 82, 73, -226,197, 61,153, 61, 57,203,164, 93,214,154, 64, 47, 36,247, 32,231, 24, 81,131,149,109, 67, 49,112, 30,190,126,219,104,196, 87, -101, 21, 22,236, 52,209, 98, 9,130,106,200, 56, 9, 53, 85, 44, 91,180,148, 80,221,232,199,244,215, 72, 2,194, 72, 20,143,118, - 15, 65, 13, 13,104,240,117,106, 62, 2,156, 42,157, 16,214, 53,203,124, 61, 98,144,155,185, 75,188,143,128, 14, 90, 35,231,111, -112,203,224, 2, 60, 0, 97, 5,239,213,250,122,110,136,175,111, 3,213,147,253, 31, 1, 72,187,158,159,166,225, 40,222,118,221, -218,110, 93, 7, 99, 3, 7,168, 35, 1, 61, 24,163, 96, 60,112, 83, 19, 61,120, 81, 76,188,121, 86, 99, 36,222, 77,140,241, 47, -144,139, 7,163, 71, 98,162,241,230, 69, 61, 24, 19, 18, 2,152,120, 81, 8,200,175, 0, 3, 54,112,172,108, 93,215,118,237,183, -190,247,190,131, 96,226,205, 11,151,166, 25,109,250,125,239,243,222,251,188,207, 71,254,255,177, 42,201,126, 50, 55,244,196,127, -169,183,139,255,238,223,224,125,100, 29,214,148,132,136, 33,118,184, 2, 46,230, 29, 49,214, 16, 15, 57, 49,137,104,210, 70,219, - 16,190,205, 68,242,225,168, 27,227,193,179,152,214,158,200,165,211, 48,157, 74, 36,123, 26,240,109,130, 16,151, 60,249, 98, 20, - 3,196, 7, 87,136,124,253,151, 51, 96,120,100,166, 34, 30,200, 78,162,109, 8,122,198,187,180, 6,134,241, 13, 2, 90,201, 44, -228, 59,251,215,118, 87, 67,242,107,245, 57, 41, 8, 59, 18,126,200,142, 40, 18, 75,129,196,163, 35, 41,100, 39, 84, 56, 30, 33, -149, 79,200,209,246, 14,228,162,209,205,142, 80, 15,170, 56,201,188, 85,133,116, 63,128,242,183,111,142,192,197,203, 87, 46,189, - 25, 31,135, 7,235,201,101, 45,107,247,249,216,179,209,135,247, 31, 61,184,243,226,229,171,205,173,114, 40, 40,136, 75, 68,185, - 14,176,173, 90, 59,119,230,236,147,199, 79,223,189,127,251,249,203,215,118, 35, 30,141,224,108,212,107, 50,148,231,142, 39,165, -152,114,172,179,219,208, 53,145,121, 77,171, 34,163,156,124, 0,181,130,174, 6,229,210,122, 79,111,166,110,253, 78, 37,177,194, -128,127, 12,238,162, 70, 23,186,176,210, 9, 9,229,152, 16, 85,133,170, 21,216, 94,149, 43,241,225,204, 62, 8, 91,219,196, 98, -232,186, 13, 17,149, 49, 80,137, 23,146,110,189, 81,203,182,231, 74,149, 77,203,173,122,126,204,136,183,153,246, 30, 30, 88,252, -170,177,192,199, 49, 6, 42,136,161,130,163, 43, 57, 2,138,246,217, 90, 52,225,250, 13, 37, 18, 59, 92,130, 71,221, 20,198,178, - 70,219, 74,113,137,183, 35, 3, 34, 27,196,225,168,135, 68, 13,151, 88, 20, 48,191,172,192, 25, 27,204, 15,253, 92,255,177, 82, -252,181, 52, 54, 15,111, 19,210, 76, 66, 51, 6, 79, 95,152, 90,152,132,252,122,190,239,226,236,198, 44,224, 98, 72,178, 0,136, -180,168,230,133, 46, 45, 91, 69, 80,105,144,161,189,215,190, 85,129, 74, 8,155,233,204,255,182, 56, 5, 40,158, 83,229,250,115, - 3, 59,102, 17,242,141,174,104, 52, 58, 11,211,201, 14,199,109, 44,151, 86, 11,229,109,172, 81,136, 2,197,181, 77,160,204, 41, -154,174,235, 57,149,208,116,124, 63, 66, 86,218,105,221,216,183, 45, 27,144,169, 8,225,190,228,120, 46, 60, 87, 91, 34, 5, 81, -222,180,171, 97, 68, 66, 55, 71,230,236,163,100,141, 32, 57, 82, 54,149, 85,100,117,163, 92,240,253,166, 97,164, 0, 53,171, 49, - 93,139,153, 39,114,125,197,221,109, 72, 27,112,248, 23, 10,243,183,134, 71, 22,183,150,230, 54,230, 18, 74, 92,143, 27,158,103, -225,251,141,168,125, 70, 32,244,180,119, 13,157,188,209,155, 28, 92, 75,127, 47,236, 76,174,149, 38, 54,253,229, 74, 75,244,117, -187,102,159,234,200, 47, 20,119,218, 81,146, 16,208, 61,228,193, 32,147,145, 95,223, 27, 78,247, 27,200,112,193,158, 21,195,191, - 62, 58,156,161,182, 1,162,137, 64, 66,225, 53, 40, 30,169,145,142,118, 29, 98,139,120, 32,241,166,124, 68,210, 84, 33,103, 8, -221,153,181, 79,115, 51, 11, 91,138,170,194, 87,228,161, 37,135,237,251,141,122,179,241, 97,230,227,128,158, 55,133,202,232,213, -187,194,132,160, 11,153,206,148,188,227,172, 92, 63,126, 13, 78,145,195,184, 9, 31, 25,146, 96,194,100, 70,220,128, 32,110,122, -251, 77, 76,135, 62,149,187,248, 85, 16, 83,140,117,165,115,155,149, 45,194,251, 76,100,173,110,110, 92, 81,242,153,252,108, 97, -150, 52,142, 15,212,106, 14,120, 28, 62,223,254,134,194, 61,240, 86,118, 87,155, 45, 46, 59,141,214, 25,141,255, 69,142,221, 68, - 53,170,229,210, 61,181,109,139, 70, 50, 2, 13,143, 5,139,246,245,196, 86, 31,133,219,193, 98, 85, 86,169,149,201, 30,190,229, -249,160,107, 41, 8,247,212,206, 33, 47, 9,137,155, 36,251,211,139,211,156,204, 77,216, 8, 95, 93,192, 91,248,232, 63,101,192, -215, 85,119,170,240,187,166, 93, 38,142, 6, 22, 31,212,147,105,105,221, 28,238, 24,113,131, 86,106, 58, 64, 76, 67, 87, 6,244, -159,226,215,217, 17,123, 38,186,243,143, 0,156, 93,219,107,211,112, 20, 78,154,164,205,173, 77, 91,186, 91,101, 43, 78,145,213, - 61,120,163, 40, 34, 27,226,188,224,196,127,194, 63,100, 47,162, 8, 42, 40, 40,190,249,162,224,133,233, 94, 28,226,152, 47, 62, -137, 56,134,224,132,137, 91, 59,183, 98,183,118, 77,219,180, 77,155,180,241,156,147,164, 19,246,230, 75,161, 16,146, 38,205,239, -252,190,115,206,119,190,239,127,240, 59,187, 79,177,221,217,163,207,239,171,240,251,223,124,143, 86,206, 7,233, 52, 44,205, 8, - 26, 27,107,195,173, 49, 77,234, 61,246, 84, 52,123, 72, 63, 64, 18, 4, 33,142,145, 5, 70, 20, 80, 87, 69, 86, 5, 45, 4, 25, - 33,206, 82,211, 92, 27, 2, 45,100,124,243, 68,211, 96,123,181,122,183,199, 75,236, 26, 34,175, 8,182,231,121,184, 55, 0, 27, -150, 53, 52,249, 35,175,122,111,138,138,142,128,213,238, 16,133, 69,224,120, 11,123,242,108,165, 94,166,135, 27, 96,124, 45, 62, -108,109, 3, 34,101, 93,114, 33,235,139,163, 16, 86,103,152,152, 38, 75,146, 64,234,149, 88, 49,162,233, 63,135,166, 52,145,125, -168, 72,108, 88,229, 21,137, 83, 69,116,182,163, 9, 79,136,239,194,149, 11,151,175, 78, 95, 91,254,186,244,236,197,107,164,129, -144, 53, 73,126,167,242,115, 53,123,126,242,226,225,131,233,149, 31,171,186,174,135,130,128,218,172,174,109, 77,156,201,220,191, -125,115,113,113,225,222,163,199, 8,169,120, 1,155, 50, 29,167,101,117, 43,134,153, 74, 14,167,199,198,231,231,223,189, 95,248, -216,172, 55, 70, 83,131, 27,185, 95,115,115,111,224,106, 1,206, 54, 42,250,238, 78,225,213,236,236,250,198,182,101,115,173, 22, - 90,117, 3,100,178,108,200, 33, 0, 74, 59,144,222,227,124,178,217, 65, 54, 63,122, 31,119, 92,224, 65, 8,222,115,156,233,146, - 89,172, 87,152,164,182, 80,221,172,187,253,126,216, 41,169,114,210,130, 40, 79, 7,119,130, 60,198, 77, 27, 13,117, 81,164,129, - 92,195, 24,148,120,179, 77, 77,142,163,137,146,133,188, 96,215, 29, 13,226, 30, 60,173,146, 94, 4,196, 61,220,151,210, 27, 58, - 44,120,139, 36,151,109,172,179, 90, 17, 41,170, 73,145,114,189, 12, 40, 24,128, 12, 18,144, 56, 78, 10, 41, 2, 36, 4,205,106, -185,182,139,226,218,172, 19, 87, 19,219,149, 60, 97, 7, 14, 48, 93,211, 52, 68, 81,137, 40, 17,145, 23,189,177, 17,248,111, 56, - 30,192, 50,121,221, 53,176,245, 29,148,162, 74,220, 68,181, 12, 22,221,141,109, 43, 38, 71,221,146,238, 86,121,203, 34, 78, 78, - 88, 14, 91, 22,252, 66, 38,213,119,144,135,109,208,233,106,138, 86,208,113,128,126, 40,145,204,140,101,178,127, 54, 84, 81,134, -203, 2, 24,207,109,163, 71,235,120, 42,189, 94,200,186, 12, 43, 41,168, 84,205, 90,127,100, 0, 93, 35, 2,206,161,228,145,146, - 81,134, 0, 4,155, 4,132, 25, 3,133,122,112, 93, 67,240,202,239,230, 91,182, 85,107, 84,225,133,135,128,114,244, 64,122,179, -148,223,169,149, 54, 75, 91,154,170,169, 18,228, 85, 77,155,100,126, 97, 21,159,148,248,196,244, 8,106, 70,198,130, 90, 50, 50, - 54, 20,205, 36,212,201, 99,167,238, 62,125, 50,115,253,236,183,207,203, 95,114,197, 27, 19,167,203,213,182,137,141,150, 54, 60, -142, 19,163, 67,233, 75,105, 41, 29,103, 20,142, 9,161,188, 31, 42, 9,243,110,131, 44,224, 17,160,112,242, 8,189, 89, 56, 28, -219,192,128, 30, 20,224, 81,195,171, 43,132, 68,129, 87, 69, 86,147,152, 84,130, 73,245, 23, 62,124,127,185,176,226,208,120, 5, -102,171, 88,123,178, 98,252, 72,169,141, 1, 0, 18,238,183,107,159, 30,222,122,176,244, 60,187,182,250,123,106,112,234, 78,110, -230,220,192,113, 53,192, 26,216,162, 64, 62, 25,124,138, 33,153, 74,112, 40,156,105,218,109, 49, 40,193,182,106,180,234, 54, 89, -121, 96,175, 10, 64, 27,238,214, 6, 41,176,203, 49, 37, 10,233, 78,135, 56, 14, 5,200,114, 28,223,231,211, 21, 1, 38, 61, 1, -154, 51,183, 90, 88, 96,196,184,130, 19, 27,254,112,235,158,224,172,103,145,138, 6,138,197, 90,145,241,116,194,240, 29,137, 72, -154,141,132,225,142,219, 79,234, 73,128,209, 75,220,237, 21,191, 59,100,225, 68,140,199,128, 87, 80, 32, 68,228, 96, 97,199,244, - 9,239, 84,177,241, 8, 58, 24,242, 97,141,144,162,120, 39, 10,183,105, 26,112, 18, 76,151,233,114,190,115, 72,175, 1, 28,248, -167,195,232, 1,203,174, 55,200,229,247, 5, 60, 34, 61,158,255,175, 0,148, 93,203,107, 19, 65, 24,159,221,205,206,100, 51,102, -179,105,154,182,150, 90,170,130, 10, 85, 65, 65,188, 41,234,217,139,130, 21, 4, 81,161,244, 15,208, 83, 47, 94,196,179, 55, 79, - 30, 68,252, 11,172,130,224, 77,188,212, 23,130,158,108,141,212,119, 95, 73, 54,187,217,157,221,201,174,223, 55,155, 71,149, 34, - 8, 33,228,144, 77, 54,155,157,153,239,247,205,239,241,127,252, 72, 78,185,162,150, 39,127,133,172, 26,100, 11,229,112,187,201, -189,247, 90,223,210, 35,234, 86,249, 6,140, 58,212,172,234,221, 93,120,178,181,161,141, 6,230,153, 38, 44,147,170,102,125, 24, -170,153, 5,152,229, 25,210,215,154,114,179, 37, 93, 45,235, 95,170, 36, 81,100, 41,169,107,154,100,206,253,136, 18,176,249, 14, -227, 25, 89,240,218,192, 91, 24,109, 66,243, 37, 79, 52,179,139, 88, 46, 12,213,219,155,138,249, 66, 80,209,131,253,129,200, 32, - 57, 12,237,213,254,165,198, 85, 10,218,180, 43,230, 35,186, 73, 13,184, 3,166, 70, 43,188,196,189, 40, 74,115, 68, 17, 7,160, - 16, 67,171,244, 60,211,113,151, 80, 89,206, 40, 72,130, 40, 69, 68,169,140, 83, 17, 68, 38, 51,170,206,208,218,198,166, 16,210, - 48, 77,197,230, 68,144, 22, 75,113,236,200,129,185,217, 57,198,172,133,133,167, 47, 94,191,161, 6, 61,115,250,212,204,249,243, -139, 47, 23,111,222,186, 29,202,152, 82, 83,185, 63,198, 57,244,251, 79,124, 95, 88,140,237,157,156,168,125,253,134,109, 16,211, -112,138,220, 48, 18, 41, 5,165, 84, 68,157, 32, 4, 4,172, 5,161, 76,240,236, 50, 86, 32, 34, 33,169,220,181,177,120,128,251, -214, 76, 98, 47, 14, 93,101,133, 45, 59, 73, 95,169,221,231,162,162,216,154, 97, 29,156,116,254,216,139, 81,188, 14,135, 87,220, -112, 19,254, 9, 10, 64,197, 4,144,128, 18, 51, 24,165,217,134,103,182, 27, 93,182,202,110, 80,135,226,221,230, 14,207,243,149, -245, 21,180,165,213,153,129, 84, 31,230,161, 90,149,156, 56,120,230,249,251,103,197,130,221, 10,176,125, 49, 98,143,192,145,117, -127, 3, 64,116, 61,168,219,121, 7,144, 28,148,177, 1, 64, 1,106,185,200,155,150,147,163,187, 97,150, 10,164,175,230, 74,173, - 98, 87, 83,140,200,176,106, 63, 63,193, 7,195, 82,177,230,174, 14, 23,171,240,206,118,232, 41,211,177, 68, 79,117,228,164, 26, -180,128, 94, 49, 18, 78,137,211, 29,109,225,193, 42,197,114,152, 98,229, 20, 74, 20, 87,208, 8,138, 95,101, 92,172,181,195, 32, -111,154, 65, 20,194,225, 83,163, 83, 75, 63, 62,162, 98, 86,203,149,237,138,219,118, 67,108, 88,117, 42,246, 48,103,214,151,245, -239,251,199,247,173, 53, 87,225,132, 97, 38, 26,117,198,154, 42,108,182,238, 53,213, 64, 36,147,149,137, 80, 10, 76,214,182,203, - 81, 36,224, 47,203,226,182,212,221, 8, 95,129, 19, 36, 38,202, 14,239,218,104,173, 21, 25,255,222,248,165, 8, 5, 68, 17, 91, - 17, 14,134, 29,121,173, 90,157,190,115,156, 52, 91, 68,248, 68,198,164, 17, 18,215, 39, 95, 55,200,236, 13, 50, 50,253,224,202, -165,203,247, 31, 79,151,121,153,210, 49,110, 13,197,226,250,185, 11,251, 46, 30, 37,162, 70,178, 93, 91, 25, 1,252,193, 71,140, -124, 74,124,192,130, 31, 41, 97,115,156,116, 83, 27,244,222,208, 52,149,196, 35,111, 16,187, 64,118, 58,240,188,252,240,213,189, - 39,239, 12,150, 43,193, 15,134,107,134,196, 92,184,163,224,240, 61,203, 13, 86, 54,249,226,234,231, 71, 43, 31,226,165,245,249, -147,119,247,179, 67, 86,169, 49,243,246,236,252,225,171, 2, 80, 28,218,131,171, 30,117,154, 20, 57,247, 3,159, 50, 6,232, 80, -166,178,104,149, 90,194, 11, 35,152,239, 84, 46, 70,182, 1,139,145,197, 26,114,156, 66, 15,170, 52,228, 43,147, 78,211,111, 64, - 5, 6, 75,117,128,205,150,190, 16,105,187, 73, 73,207, 98,171, 7, 42,168, 44,251, 71, 51,250,138,161,158, 33,153,146, 83,193, -202, 4, 21, 70,208, 9, 49, 77,138,200,204,155, 62,233,217,201, 15,120, 53, 90, 58, 86,218,169,212, 9,105,223,231,182,155, 61, -217,255,162, 4,150, 63, 88, 29, 45,192,112,217,231,119, 20, 18,130,197,205, 52,204, 49,103,188,182,190,172, 39, 0,169, 11,126, -164, 18,101,211,191, 90,235,106, 27,164, 27, 27, 58, 32,252,104, 3, 21,171,214, 11,207, 32,191, 5,160,236,106,122,154,136,162, -232,155, 78,167, 51,237, 76,237,148, 82,138, 16, 52, 6,197,165, 26,191,162,198,133, 11,221,224, 82,113,239, 15,208,149, 27, 99, -226,206,165, 27,227,210, 16, 19,130, 97,161, 38,184, 55,193,152, 72, 52,113, 65, 98, 74, 0, 45, 33, 64,161, 80,166, 31,211,233, -124,143,247,222,215, 22, 48, 38,198,132,174, 40, 83,242,122,223,189,231,221,119,238, 57,255,151,223,117, 5, 22,186,201,243,187, -240, 39, 51,242,159,201,157, 31, 96,176, 91, 18, 68, 61,187,215,168,215, 26, 23, 89,236,128,158, 48,158, 58, 36,148, 46, 97, 97, - 71,155,158, 58, 81,212,124, 39, 3,106,140,175,132, 40,231,149,188,156, 16, 43,237, 77,178, 49,100,212,207, 66, 2, 17,108, 66, -159,243, 86,121,138,199,137,106,156,143,143,132,253,166, 76,216,241, 45,161, 91,145, 40, 28, 56, 50, 88,105,108,198,208, 77,139, -127,217, 17, 59,124,175,241, 87,137, 30,236, 14,193, 73, 34,112,137, 25,137,220,204,209,194,216,234,222,207,211, 67,185,225,163, -250,142, 5, 56,137,137,113, 8, 68,128,237,130,170, 98, 71,215, 48,253, 54, 10, 35,138, 0,130,208,172, 74,194, 67,162,135,238, -105, 0,101, 1,193,161,151,120, 66,194,154, 37,137,164, 85, 0, 27, 88,198, 98,211,223, 55, 48,113,231,238,245,171, 55, 72,142, - 44,130, 44,240,126,118,118,122,230, 29,228, 2, 77, 69, 52,234,121,161,105, 57,212,191, 12,249, 34,194,195, 69,186,117, 70, 70, - 27,164, 96,228, 67, 98,101,133,189,226,194, 27,209, 98, 76, 16, 37, 12, 32,248, 43, 84, 36, 38,157,108, 8, 9,128, 74,142,135, -123, 40,176,156,168, 77,194, 34,216, 41,100, 8,161, 16,214,113,114, 13,242, 10, 52, 73,115,176,217,139, 33, 4,169, 16,254, 55, - 7,105, 69,184,188,253, 90,206,104,213, 97,227, 13,103,143, 3, 12,183,156, 6,252, 86, 22,225, 52, 47,183, 61,147, 68,171,209, - 4,110, 95,224,148,114, 7,234, 82, 73, 10, 50, 19, 92, 62,132, 29,144,188,119,128,164,118,234,155, 15,102, 10, 53,106,163, 43, - 36,221, 60,210,127,252,220,216,153,111,197,239, 91,245,245,184, 24,111, 57,173, 39, 19, 79,167,230,166, 74, 91, 37,188,100,243, -160,242, 37, 56,234,191, 56,118,121,161,180, 64, 30, 32,168,255,142, 83, 39,177, 48,167, 14,192, 39, 86,205,157,219, 23,198,171, - 53, 99,169,188,168,167,178,199,242, 35,139,107,197,209,194,137,181,202,234, 96, 95, 97, 99,103, 93,142,163,155,226,217,209,243, -203,107, 63,224, 57, 95,138,159,179,233, 62,203,177,168, 11, 32,168, 74,202,245,189,177,161, 83,155, 70,217,180, 91, 50, 30, 92, - 92, 45,165,193, 34, 25,102, 45,151,214, 93,156, 18, 80,171,102,213,178, 45,212, 83,171,111, 3, 82,133,122,102,187,166,139,197, -209,215, 85,125,215,172,202,177,120, 38,173,251,190,103, 90,200,177, 67,251, 59, 65,208,147, 58, 0,216, 82,101, 5, 22, 31,135, - 3, 18,138, 26, 79,214,237, 58,178, 89,176,116,229,154,237, 93, 69,140, 65, 5,184, 21,215,110,190,188,198, 60,147,193,210,193, - 55,101,217,172,217, 14,139, 43,243, 75,236,237,122,253,249,167,175, 7,163, 55,207, 88,197,217,102, 9,131,205, 79, 50, 49,129, - 26,100,112,136,131,228,110,187,204,241,240,199,134, 92,143,184,151, 91,192,247,114, 11,102,118,136, 99, 25, 39,238, 88, 86, 5, -216,206,170,173,185, 23, 31, 95,207, 21,149,148, 12, 85, 90,146,196, 40,140, 53, 60,191,108,186,203,181,230,162,209,130, 8,130, -122,233, 4,238,196,240,253,153, 15,175,238, 93,122, 60,121,229,217,131, 95, 15,223,212,166, 31,157, 28, 47,219,123,252,198,146, -252, 37, 67,174,247, 11,197,219,116,224, 25, 72,241, 13,136,164, 70, 19,172,232,183,227,147,250, 16, 66,142,174, 79, 19, 64,207, -148,146, 46, 27,101, 44,136,252, 52, 73,183,164, 20,165,225, 1, 13,166, 14, 89,183, 75,253,232, 56,163,194, 91,149,132, 34,139, -201,166, 83,239,136, 10,116,211, 59, 32,131,141,189, 45,220, 26, 2,119, 1,100, 92, 6, 63,136, 56,163,166, 35, 42,201,122,183, -115,221,100,152, 73,101,146, 82,114,187, 1,101,152, 16, 62,137,167,116, 7,116,104,136, 70,224, 2,136, 29,179, 61,222,136, 39, -129, 25,120,146,168,201, 42, 32,128,110,146,140, 14,245,195,187, 89,139, 26,200,135,140,143,216,254,212, 15,190,126, 11,192,217, -181,180, 54, 17, 69,225, 59,175, 36, 51,147, 71, 77, 72,155,151,182,180,181,136, 80, 5,119,174,220, 20, 92,136,123, 65,252, 9, - 46,220,232,202,157, 27, 65,253, 25, 22,244, 23, 8,174, 20, 20, 69,169, 84, 93,105, 91,219,218,230,157,102, 50, 73,230,102,102, - 50,227, 57,231, 78,108,213, 34,232, 46,144, 48,147,185,115,239,121,124,231,156,239,251,159,249,166, 99,131,247,240,144, 66,224, - 79,227,142,191,194, 6, 85,106,101,201,153,249,102,191, 38,253,202, 5, 25, 34,206,110, 14,125, 71, 10, 35,166, 8,141,233,212, -237,137,129, 69,192, 38,202,170,148,246,136,230, 72, 5,191, 81,116, 69, 79, 39, 50,121, 61,215,116,170,237, 81,155, 81,183, 55, - 82, 81,250, 67, 74,243,253,137, 15, 15, 5,190,255,179,193, 62,192,206, 69, 8, 49, 98, 96,116, 8,225,157, 12, 49, 75,242, 63, -209, 95, 82,255,139,194,125,135,106, 80,248, 88, 56,243,162, 72,149,108,102,121,161,208,224,156,123,216,212, 26, 83, 21,161,183, - 24, 79,224,174,131,131,131,140,197, 72,210, 24,198, 49,184,149, 57, 15, 69,155, 8,198,194, 72, 75, 19,249, 98,132,194,145,242, - 20,199,157, 32,202, 76, 38,148,202,201, 82, 97,186, 56,242,188,173,173,221,189,106, 35, 80,112, 50, 20,118, 31,202, 84, 6,224, - 39,112,178, 63,169,203, 38,216, 24, 77, 4, 6, 76, 64, 72, 40, 51,140,125,139,130, 72, 91,242,105,115,146,140, 3, 46, 40,134, -237,112,192, 93, 76, 56, 61, 44,134,226,123,208, 98,140, 31,112, 23,135,170, 16, 39, 54, 19, 25,172,121, 8,115, 28, 9, 68, 68, -224,166, 36,171, 36, 4, 43, 5,145,166, 37, 35, 79,137,144,142,170, 65,204, 59, 54, 98,166,130, 28, 76, 14,158,159, 64,210, 19, - 70,159, 91, 56, 75,140, 44,111,178,194,162,108,152, 46,171,248, 99,183,146,175,236,183,246,117, 20,203,246, 52, 89, 93, 44,158, -174, 29, 84,185,203, 33, 7, 23,181, 44,200,189,178,169,108,189, 91,133,149,135,172, 22,110,167,131,221, 83, 20,107, 96, 33,158, - 99,183,251,238,208,136, 25,144, 47, 35, 37, 14, 31,192,177, 4,247, 3,239, 87,160, 67,196,214,137, 71,189,148, 41, 15,220,190, -237,244,242,169,105,172, 7,140, 6,217,228, 9, 85, 86, 91,221,198,169,153,138,101, 91, 55, 46, 93,127,252,114,181,148, 41,192, -114, 45,205,157,125,179,254, 34, 17, 55,102,210,249,134, 85,203,165,242,125,199,134,184,123,177,184,176, 89,221,128, 85,130,152, - 67, 85, 85,176, 62,197, 92,113,202, 72,127,218,254,236, 33,107,174,152,185, 9,231, 11,243, 95,246, 55, 97,123,204,230,102, 55, -234, 27,229, 92,105,175, 3,207,104,122,196, 15, 7,246,107, 74, 79,117,135, 61, 13,103,221,176, 53, 16,252,147, 25, 55,224,191, - 65, 40, 63,112,236,165,210,210,247,214, 46, 60, 20,164, 41,117,171, 86,206,150,155,118, 29, 59,148,226, 49,124,189,114, 80, 26, - 73,183, 30,172,176,156,203,236, 30, 36,113,204,225,172,207,217,118,227,222,234,235,187, 31,170,191,237,221,219, 23, 47,220,127, -245, 30, 63,109, 63, 98,221, 62,150,171,124, 82,103, 5, 43, 15, 27,116, 36, 34,119,212, 64,139,252, 47, 73, 62,146,252,163,138, -198,221,208, 89, 33,195,210,201,206,211,181,203,119,158,188,227, 56, 40,171, 17, 61,128, 31,252,109, 44,253, 90,246,102,167,171, - 61,187,250,240,252,243,149,177, 94,191, 82, 92,182,252,225,185,185, 51,111,191,174, 9, 74, 37,138,174,144, 31,212,245, 70,142, -195,167,103, 43,245,111, 59, 16,236, 80,171, 10, 78, 45,197,180,120,199,110, 11, 74, 93, 2, 97,200, 55, 72,146, 75, 26,117, 82, - 68, 28, 45, 8,198,177,140, 6,107, 56, 64, 46,101, 37, 42,119, 70,108,238, 68, 82, 35, 71,245, 66,210,134,160,130, 2,218, 26, - 26, 15,161,126, 13,200,186,214,119, 62, 34, 71, 44, 41,217,141, 73,114, 37, 8, 35,236, 71, 0, 40,224,233, 91,189,230, 17,142, -128, 8, 48, 39, 0, 62, 20,245,232, 9,211, 25, 11, 15,253, 1,201, 80, 17,113,141,132, 42, 46,190,168,154,134, 82, 56, 17,174, -154, 76, 66, 29,129,207, 35,240, 58,234, 40,153,180,230, 31,199, 8, 3,247,248, 33, 0,101,215,178,219, 52, 16, 69, 61,169,227, - 87,156,164, 33, 73,213,138, 86,148, 34,209, 5,176, 67, 98,129,212, 74,116, 13,191,192, 15,240, 51,172,216,243, 1,252, 1, 44, - 88,118, 11, 8, 16,106,213, 71,154,180, 77,154, 38,245, 43, 25,199, 30,238, 99,156,242, 18, 8, 41, 82,148, 40,158,204,216,115, -239,156,185,115,239, 57,255, 23,127, 23,127,146,207, 46, 21,117,255,127,113,238, 5,133, 47,206,241, 88,134, 63,119, 72,183, 10, -131,132,181, 89, 48, 67, 15, 34,119,116,108, 38, 93, 75, 21,150,138,235, 17, 4,113, 66,102,186,108, 21,143,200, 36,198,182,243, -182,187, 12,118, 21,165, 33,107,158, 8,241, 11,237, 78,190, 64, 45,207, 67, 10,152,124, 50, 35,162, 74, 22, 20, 43, 66,255,191, - 33,245, 66,197, 91, 19, 17,253, 88, 56, 69,170, 2,164,157,134,202, 57, 44, 1,164, 88,194, 26, 60,142, 84,178, 84, 54,173, 73, -138,105, 69, 11,120, 24, 8, 40, 30,128, 57, 38,150,163, 34,169,129,106, 80, 40, 92,137, 43, 3,172, 19,128, 32, 8,100, 43, 84, -191,155,162,179,103, 25, 49, 74,159,226, 61, 28,137,233,244,135,225,151,189,206,254, 65,119, 20, 74,240,157, 14,138,154,102,148, - 99, 71,138,193,120,123, 48, 90, 10, 95, 72,104, 39,133, 61, 45, 2,115, 42,136,194, 9,149, 81,158, 12,248,122, 19,249, 12, 74, - 22, 50,210,224,132,180, 22, 68,153, 35, 76,168,168, 37,240,112, 88, 41, 19, 64,116, 36, 73,237,207,130,193, 53,253, 38,192,240, -154,131,213,170,122,154, 10,146,218, 18,112,185,141,207,131, 43,150,169,196, 12,190, 97,180, 82,119, 26, 6,114,242, 36, 44,151, - 6,127, 98,219,158,111, 87,199, 81, 0,216, 51,150, 19, 54, 19,226,112,102, 90, 13,124,127,250,240,217,167,227,207,142,101,101, - 89,234,216,149,222,101, 55,145, 9, 27, 3,116,183,226,214,162, 73, 8,174,156, 45,129,161, 61, 60, 13,128,243,112,241, 85,124, -201, 18, 72,148,225,158,243,209,122,195,111,221, 94,186, 51, 8,206,215,155,235,163,104,196, 50,197,101,203, 89,116,145, 18, 4, -182, 2,139,126,125,189,189, 49, 8, 6, 83, 57,169,186,181,105, 58,217,126,176,125,120,118,116, 60, 56,129,177, 67,107,176, 80, -118, 78,143,224, 94,194,114, 62,197,147, 82,133,225, 29,132,240, 42,140,163, 18, 49, 78,123,174,231, 58,200, 38,214, 15,134,157, -126,215,115,253, 25, 49,254, 83,118,116, 62,142,175, 50, 26, 66, 63,232,111,222,188,123,120,222,105, 85,155, 65, 60,246,108,151, - 8,110,115,219,242, 80, 57, 38,199,236,148,138,227, 95,132, 67,192,251,146, 84,231,192,234,107,149, 69,179, 84, 6,215, 6,187, -165,118,189,125, 17, 12,224, 55,211, 52,134,181,215,130,254,123,205,147,112,248,216,176,236,157,101, 84,211,102, 77, 27,112,111, -117,119,107, 99,105,181,118,175, 59, 10,122,193,216,130,141, 56,202, 23,171,163, 78,239,197,253,229,210,106,205,200,122,134,144, -232,205, 85,174, 73, 87,216, 26, 48,255, 81,160, 55,119,193,155, 91, 70, 21, 94,182,209,240,140, 27,190,177,214, 50, 54, 87, 12, -105,188,124,254,250,201,171,119,221, 89, 62,151,235,201,255, 69, 57,242, 49,217,221, 83,187,111, 14,222,127, 72,222,214, 77,123, -205,109,197, 89,114, 56,232,224,105, 22, 2, 14, 51, 85,210, 54,221,181,230, 45,152, 87, 65, 28, 60,218,217,218,255,250, 13, 48, - 0,226, 31,170,101, 73,228, 36, 19, 60, 5,117,166, 35, 41, 2,169, 86,117, 41,154, 94,229, 44,236,103,232,116, 67,248,176,210, - 88, 25,134, 35,109,252, 90,206, 73, 11,111, 87,172, 42,152,223,140,248, 5,132, 46,122, 98, 75,194,240, 36,220,231,211,241, 25, -135,178,241, 96,220,111, 80,176, 84, 82,251,121, 94,248, 98,228,174, 17,215, 5,177,154,253, 80, 92, 7,154,153,195,114,110, 50, -106,206, 87, 73,201,155,224, 37,224,241,193, 36,212, 25,241,220, 11, 62, 19, 96, 90,130, 95, 4,243,114,237,224, 11,233, 11, 67, - 15,170, 96, 28,155, 3,254,239, 2,144,118,237,186, 81, 67, 65,244,250,113,109,239,203,187, 49,217,144,132, 37, 68,162, 64, 10, - 66, 10,162,163, 68, 32, 90,106,248, 17, 42, 10,254,131, 26, 33, 26, 58,126, 2, 65, 17, 68,151, 68, 9, 81, 72,236, 60,216, 93, - 59, 94,175, 95,204,153,107,111, 18,146, 6,177,173, 31,242,250, 94,207,156,153, 57,115,230,223,240,187,118, 29,138,159,101, 87, - 56,145,162, 95, 57,185,202,204, 24,151,111,112, 65,217,231,175,147, 9,211, 90, 44, 31,150,213,242,183, 74,103,161,150, 34,192, -142,195,220, 33, 83,152,142, 38, 75, 97,180, 12,155, 98,231,142,213,241,154,222,209, 36,216,139,246,208, 34,203,133,127,238,122, -200,234, 60, 90,161, 22,143,126,110,163, 55,138, 79,217, 43, 93,171,125, 89,218,210, 70, 95, 95,158,213,117, 12,205,177, 26,113, - 18, 41, 67,159, 99, 48,134,198,196,218,226,193,202,195,141,221,111,232,202, 38,123,109, 19,112, 75, 13,221, 64, 83,170,174,119, - 28,107,185,223, 51, 28, 11,225, 55, 90,153, 9,215, 16, 42, 98,237, 12, 81, 54,154, 86,167,101, 66, 74, 29, 9, 37,248, 54,213, -126, 75, 27,136,176, 57,109, 96,189,146,182,224,119,170, 17,222,215, 98,178,180, 88,127,205,132,234, 0,220,131, 45, 53,213, 36, -148, 36, 5,135,249,168,165, 27, 34,183,145, 27,197, 33, 71,106,182,196,112,135, 36,193, 63,157, 80,128,159,235, 0, 33,162,112, - 44, 52,155,131, 92,156, 0,249, 75, 93,183,108,116, 85,167, 60, 0,237,108,138,179,218, 13,121, 24, 12,163, 4, 68, 33,164,103, - 17, 39,151, 74,161,159, 11,164, 23, 87,180, 44,138,243, 56,145, 63, 33,118,137,172, 3,174,234,222,220,139, 95,245, 13,211, 81, -211, 48, 91,178, 73,183,155, 64,157, 6, 74,106,147, 52, 18, 24,247,220,228,198,116,178,185, 13,168,155,228, 24,153,203,196,107, - 93, 73, 2, 41,238,130, 3,131, 91, 48,153, 38,183, 76,153,178,224, 42, 43, 20,162, 52, 74,139,101,154, 22,178, 25, 38, 36,207, - 20, 11,128,174,238, 52,221, 48, 26,151, 74, 70, 66,148,203,189,129, 63,220,167, 77,229,182,186,210,208, 70,209,152,124,225,218, -202,125, 2,227,203,222,210,142,191, 99,131,245, 35, 25,228, 9,242, 73,244, 90,201,244, 47,205,245,105, 15,254,248,249,125,174, -133,178,240,157,249,213,109,127,155, 30,213,107,121,228,114, 40, 80, 88,156, 91, 8, 70,199,243, 40,237, 30, 12,110,172,108,249, -155, 11,189,155, 39,225,137, 98, 63,208, 29, 32,115,102,200, 48, 30,153, 60, 21,146, 2, 17,186,208, 37,167, 21,135,228, 15, 64, -177,101,138,249,192, 27, 4, 67,159,219,231, 10,242, 79,152,238, 91,150,171,139,119, 41,138,154,230,152,173,149,165, 83,112, 0, -116,225, 72,163,221,112,143, 66,255,105,247,214,139,183,235, 98,189, 43,252, 99, 49, 26,139,233, 20,160,187,204,126,125, 58,125, -254,238,243, 70,176,127,117,187,127,121,249,228,209,155,103, 98, 18, 11,131, 43,236,180, 91,167, 41, 96,123,174,248, 26, 58, 15, -126, 2, 54, 17,182, 37,188, 38, 96,251,110,248,225,245,199, 87,239,191,230,255, 61, 1,226,158,123,251,113,127, 45,202, 98, 90, - 92,138,156,188,102,111, 51,216,154,205,216, 22, 44,246,230,152,178,221,118, 15,126, 7,130, 9, 51,220,219, 9, 46, 77,109,223, -233,209,156,104, 50, 70,223,134,202,186,114,246, 67,229,174,153, 28,163,230, 14, 26, 85, 71, 88,133,128, 75,122, 99, 82,151, 13, -105, 19,106, 1,124,230, 29, 66,159, 36,249,209,163,161,207, 3, 33,200,103,244, 15, 67, 12,127, 71, 88,141,132, 64,218,118,186, -103,147, 48, 41, 50, 37,153, 89,212, 86,123, 38,130,192,100,233,138, 68, 58,203, 23, 92,196,236, 74,177,184,146, 37, 20, 74,199, -141, 77,116,165, 77, 89,115,102,202,234,146, 90,244, 70, 87,130, 4,181, 85, 85, 10,126,231, 37,215, 75,201,100, 38,128,253, 17, -128,180,107,215,141, 26,136,162,126,172,215,175,141,157, 23, 73, 72, 32,209, 70, 68, 17, 17, 13, 73, 77, 69,197, 79,240, 1, 72, - 72,124, 7, 21, 13, 8, 36, 26, 90, 74, 42,132,160,164,130,150,130, 20, 8, 82, 36, 33,171, 40,251,178,119,237,241,120,184,231, -206, 44,187, 10, 52, 8,105, 27,239, 67,178,175,118,102,206,189,247,220,115,254, 25,191, 91,127, 20,103,208,147,176,156,208,141, -217, 64,245, 18,138,119, 77,154, 48,227, 8, 50, 3,147,103,207, 36,211,110, 69,114,110,121,236, 77,129, 18,138,152,156, 67,142, -225,191,187, 46,190, 64,127,127,126, 49, 55,215,195,244,156,167,251,200, 75,241, 21,161,196, 72,228,174,129,241, 6,193, 43,211, - 76, 81, 60,173, 84,131, 52,106,169, 75, 93,211,217,206, 47,179, 68,166,109, 19,148,182,241, 19,220,234, 74,186,158,151,153, 7, -229,119, 0, 8, 90,192,122, 75, 3,147, 4,137,191,163,197,150, 8,134, 86, 74,246, 71,227,229,208,107, 95,155,243, 60, 2, 64, -141,200,131,187,105,218,106, 38, 45, 55,246,161,120,206, 2,165,182,199,233, 11, 10, 41,178, 70,161,102, 12,207,175, 74,212,190, -227,134, 32,202, 99,166,116, 60, 42,179, 81, 69,161, 14, 60, 39,246,189,216, 3,174, 98,157, 39,184,219, 4,174,138, 2,130, 86, -110, 74,199,157,139, 71,107,178,100, 31,123,116, 57, 90,238,216,150,108, 95,102,201, 70,195,105, 5, 20, 55,102, 23,163, 5,168, - 34,122,199,199, 32,162, 35,161, 14, 56, 31, 82,166, 1,143,156,254, 96, 60, 24, 10,109,205, 51, 89,112,186, 48, 99,155,240,240, - 53,179,142,167,195, 13,136, 7, 24, 55, 42,137, 22,139,106,148,132, 11, 76,119,148, 90, 19,137, 66, 23, 54,131,170,170,208,213, -100,153,248, 86,144,212, 76,126,208, 13,244, 38, 90,115, 13, 33,170,246,218,118,203,143, 25, 92, 7, 2,131,202, 6, 92,194,163, - 18,211, 85, 96,178, 46,196, 4,169, 64,147,167,208,101, 69, 78,171, 38,231,137, 24,197, 79, 71,216, 31,188,102, 45,181, 7,127, -234,116, 84,230, 13,156,191,158, 2, 87, 78, 97, 76,145,253,148, 65,215, 81, 96, 52, 18,120,239,244, 59,148,216,109, 44,173, 99, - 96, 19, 76, 53, 61, 6, 97,173, 38,171,205,166,127,218, 61, 62,235,158, 83, 14,118,176,189,255,163,115,148, 23,217,193,206,254, -225,241, 97,228, 69, 89, 57, 44,235,146,242,155,139,188, 95,138,113, 33,138, 48,108,165, 81,178,185,220,190,200,128,196, 41, 14, -173, 48,165,141,126,119, 99,183,151,247,246, 54,247, 78,186, 63, 33, 29, 46,198,124,170, 73,122, 28,186, 37,205,144,174, 42,217, -205,187, 82, 49,156,183,161,154,199, 58, 19, 96,115,150, 85, 65,187,210,141,181,157,206,224,148,157,240, 26,244,105, 94, 12,111, -111, 29,124, 62,249,250,224,241,139,187,178,185,178,117,213, 90, 72,129,151,190,103,249,187,111,119,158,188,254, 50,232,253,117, - 93, 63,127,120,207,110, 19,138, 23,140,214, 21,116,136, 2,122,249,214,156, 7,223,116,194,236, 73,104,205,211,182,158, 88,215, - 41, 51,168,223, 63,122,115,235,254,203, 15, 71,254,167,183, 31,159,190,122,246,159,251, 59,109,232, 55, 23,183,122,197, 48,142, -230,206,123,103,112,178, 36,156, 94,171, 41, 88,112,108,202, 66,135,227,140, 48, 36, 33,244,222,104, 0, 22,167,100, 46,188,226, - 12, 5,132,102,161,171,177,181, 86, 17,182,141,241, 81, 61,153, 90,101,216, 44,185,116,206, 46,174,188,248,203,162,204,171, 28, -106, 95, 82,166,209, 92, 41, 74, 94,233, 85, 14,105, 60, 91,178, 96,217, 16, 30, 3,178, 54,181, 20,108,190,148,113, 86,154,177, -206,194, 78,202,158,114, 92,112,133, 27,170,229,196, 69,149, 25,152, 90,158,163,158,209,174, 49,153, 69,173,117,199,204,244,142, - 41,221,176,235, 20,179, 98,108, 93,141, 55, 5,240,217,202, 58,183, 7, 39, 14, 79,245,239, 1, 81,101, 84,198,185,150, 64,171, -230,151, 0,156, 93,203,110,211, 80, 16,245,181,125,175,237, 36,110, 66,154, 56,105, 17,108,138, 88, 84,106,197, 7, 84,170, 64, -234, 79,177,229, 15, 88,243, 21,136, 13, 11, 64,149,186,164, 2, 9, 85, 72, 21,221, 20, 74,223, 37,177,147,216,142,147,152, 57, -115,109,210,168, 43,170, 86,173,186,168,228, 56,206,204,153, 59,231,113, 79,252,190, 8,222,121, 80, 48,204,146, 1, 89,124, 6, -111,113, 34, 23,202,119, 25, 7, 35,110,251,253, 90,172,186, 38, 12,203,249, 30,197,249,148, 70,238,146,179,197, 74,217, 42, 85, - 43, 91, 47,165,149, 80, 10, 90, 34,219, 1, 89, 75, 41, 75, 42, 83, 58, 56,228, 85, 71,209,129,114,100,148, 32, 60, 19,167,210, -156, 12,172, 27, 0,149, 53, 42, 68, 85,199, 39, 40,164,201,168,119,138,123,185, 34, 89, 80,213,150,233,181,229,245,139,194,217, -102,126, 28,165, 67, 95, 17, 21,143,104, 24,147,208, 58,225,120,201, 74,219, 78,195,219,218,236,180,154,222,112, 60, 73,198, 70, - 24,103,244, 51,138,167,233, 76,164,208,202,240,202, 10, 40, 44, 87, 18, 55,147,166,113,170, 13,212, 40, 36,234,191,192,210,149, -186, 86, 54,165,114, 14, 61,161, 77, 31, 0,122, 10,241,130, 76, 62, 47,100, 94, 45, 26,140, 99, 9,216, 98, 27, 56,120,193,125, -227, 9,155,240,187,109, 9, 42,134,244, 55, 56,247, 56, 37,200,134,227,108,148,106,144, 35,198, 19, 24, 68,166,250, 27,190,124, -216, 34,229,115,211, 58,141,183, 33,113, 10,147,158,224,216, 3, 61,187,248, 80,130,196, 19,164,164,221,118, 97, 45,222, 89,253, - 88,243, 47, 12, 61,193,210, 42, 93, 45,181, 67,141,197,181, 65,159,153,107,219, 12, 11,110,251, 26,155, 20,145, 43, 38,103,215, - 3,177,208, 44,213,173,175,252,188, 57, 46, 5,177,128, 97,158, 83,179, 77, 59,130,143, 60,219,249,178,104,176, 66,205, 96, 10, -133,109,219,111, 93, 70, 23,154,183, 48, 43,104,178,133,224,161,234,214,134,201,208,100,162,132,163, 28,223, 5,235, 38,155,192, - 25,216, 18,114,194, 65,113, 82,202,205, 71,155, 55,209,159, 40,238,209,197, 38, 48,192, 1, 59,106,173,251,228,199,217,161, 52, -237,192, 15, 58,205,224,240,228,144,110,237, 32, 30,112, 98,187,170, 85, 42, 73, 58,166,214, 65, 29,197, 81, 30, 1,127,101,187, -167,215,191, 30,182, 30, 35,155,151, 77, 95, 7, 73, 68,115,198,243,141, 23, 95,142,246,175, 7,224,255,140, 16,123, 0,236,209, -240, 26,253,164,199, 89,193, 80, 87,208, 72,234, 42,119,107, 99, 43,171,138,221, 79,239,233,146,248,154, 69,123, 41, 56, 11,207, -151, 28,122, 21,132,244,179,237,245,237,253,163,207,116,235, 58,141,110,156,246,236, 60,125,253,245, 67, 63, 75,255, 47, 67,109, -239,149,241,212, 55, 70, 3,206, 98, 49,176,104,141, 50,227, 38, 1, 45,185,234, 2,176,215, 61,195,168, 24,151,253,221,151,239, -118,222,124,212,197,226,129,215, 60,120,187,183,186,179,126,239,202,174, 12,187, 41,107,207,150,215, 28, 41,105,106, 88,174, 52, - 17,195, 82,173, 95,133, 87, 88, 97, 21,231, 68,232,229, 12, 47,102,144,103,228,211,166,223, 58,239,157,210, 51,216,174, 7, 97, - 28,246,227,176,216,176, 17,188,171,211,192,116,209, 1,131,229,183, 6,120,255,142,176,129, 72,196,172,237, 7,221,198,202,247, -147,111,204,183, 97,145, 96,169,111,202,203,178,101,137, 57,175,134,255, 75, 43, 75,217, 75, 70,235, 48,244, 2, 75,103, 70, 21, -100,244,114,118, 53, 96,155, 65,143, 60, 53,123,192,187, 97, 79,136,185, 5,177, 35,193,234,230,252, 22,189,177,158,186,210, 5, - 25, 34,211,188, 15,157, 49,133, 47,191,210, 24,101,131, 9,250, 77,129,222, 23, 11,175, 57,215, 9, 21, 9, 78,119,222,211, 28, -214,224,127, 5,224,236,220,117,155,136,130, 48,124,246,230,245,122,189,190, 96,156,152, 68, 8, 9, 36, 26,138, 20, 64, 65, 17, - 10, 90,122, 16, 60, 3, 13,143,192, 11,240, 24,116, 72,116,180,145, 66,137, 72,138, 8, 36,138,196, 9, 36,142,157,196, 27,249, -146,141,119,189,103,153,127,102, 29,115, 17, 66,161,179, 92, 29,175,207,206,204,153,243,207,247, 95, 34,190,255,217,156, 1, 39, - 75, 57,177, 62,191,152, 86,101, 4, 88,129,113, 46, 22, 95, 25,253, 98,187, 52,199,168, 43,134, 23,226,144, 53,253,173, 75, 99, - 40, 59,225,197,152,185, 16, 94,140, 35, 51, 27,235, 20,155,112,155,245, 51,108, 47,160,108,207,118, 81,206,155, 78,201, 65, 28, - 51, 12,183,225,215,218,163,157,126,212,163,231, 15, 67, 13,248, 14,225,141, 69,249,163,114,252,155,133, 86,177, 29,243,248,242, -197,211,151,234, 48, 3,233,191,213, 27,116, 76,101,254,155, 88, 60, 87,162,242, 21,188,227, 37,105, 84, 46,214,198,201,152,193, -141, 10,115,170,150, 16,207,204, 7,183, 23,105,129, 17, 5, 81,180,190,169, 18,115,130,160,104, 50, 85, 1, 66, 55, 80, 38,212, - 36,129,200, 19,112,165,120,234,160, 12,215, 22, 83, 23,224,228, 13,224,161,129, 70, 46,247, 58, 74,150,229, 83, 80,193,241, 5, -231, 23, 76, 51,185, 24,235,213, 19,125, 58,161,116, 0, 57,177,107,155,113,166, 41, 3, 78,210, 20,198,128,153,209,170, 7,235, - 91,187, 83,200, 36,161,250,202,205,225,181,140,253,113, 52, 79, 69,193, 37,192,188, 84,170, 20,116,106,116, 22, 20,235,244,250, - 97, 21,185,223, 45,187, 38,202,155,163, 24,180, 0, 2,204,112, 54,224,102, 74,134, 20,137,130,220, 36,184,208,137, 51, 25, 57, -239,117, 74, 2,202,152,232, 96,112, 58, 82,126, 33,128,204, 6,130, 31,155,221,204,232,253, 42, 20,221, 34, 85,226,205,202, 98, -146,196, 71, 35,168, 3,105,121,208, 50,107,208,135,132,247,125,247,230,189, 79,237,143,180,180,107,181, 86,127,116,114,198, 66, -114, 14,241,115, 99,199,140, 61,211,175, 4,141,211, 81, 8,155,111, 12,222,195, 57,147,242,242, 82,125,105,247,104,231,197,211, -151,239,215,222,125,239,239,219,220,111,164,205, 92, 46,250,103, 73,228, 57,176, 88,161, 13, 69, 95,174,220, 88,217,220,222, 92, -189,243,112,231,112,155, 74,164, 86,163,121, 24,246, 6,227,129,235, 20,170,165,234,222,113,187,228,248,244,135, 80,193, 30,120, -149, 24,252,247,168, 86,170,140, 99,248, 20, 6, 94, 21,189,183,132, 18,134, 85,246,168, 96,140,104,207,132,103, 33, 6, 43, 44, -179, 84,224,171, 84,101, 80,140,131,147,209,240,148, 78, 9,180,137, 10,224, 84,242, 4, 52,253,253,166,144, 72, 1,132,160,180, -196,150, 70,169,197, 94,192,215,107,139,111,191,172,109,132,223, 46, 27,103,223, 60,190,255,236,245,115, 21, 24, 80,221,156, 12, - 85,120,174,122, 19,245,181,175, 6,147,141,118,103,235, 96,176,208,170,238, 31,143, 94,125,248,188,167,230,103,116, 87,185, 39, -235,219,229,213,229,255,142,239, 79,110, 61,162, 68,181, 80,111,118, 7,221, 78,191,203,231, 57,237,187, 30,253,198,113, 4,107, - 89,105, 43,171,153, 91, 93,202, 19, 39,144,206, 24,122, 10, 56, 13,182, 85,179,210,164,143, 32, 55,112,177, 54,133,206,213, 16, - 27,169,108, 54, 64, 36,215, 58, 18, 62,225, 51,147, 38,128,134,178,111,210,108,138, 29, 5,246,114, 99,249, 32,236,228, 29,144, - 92, 58, 32, 55,180, 90, 10,157, 41,183, 84, 68, 33, 76,203,104, 4, 13, 58,138,165,220,162,241, 93, 31, 74,220,124,210, 41,147, -110,164, 49,131,147, 49, 84, 59, 71,138,101,185,110, 30,178,190,171, 65,171, 59,236,228,167, 97, 45,205,119, 97, 21,104, 49, 2, -204,235, 71,253,151,169,162,159, 84,139, 38,119,151,102,185, 32,215,171,255, 16,128,179,107,217,109, 26,136,162,158, 25, 63,242, -170,211, 54, 81,157,150,130, 74, 10, 66,145,144,120, 75,172,216,240, 1,124, 1, 95,196,103,240, 3,108, 89,179,232, 10, 80, 87, -136, 86, 2,162,136, 52, 52, 38,143, 38, 78,108, 39, 30,115,239,157,177,155, 20, 22,168,202, 67, 81, 54,137,147,153, 51,247,113, -238, 57,255,139,239,127,131,123,154, 49,103,152,134, 93,165, 55, 64, 77, 60, 42,148, 74, 99,213, 75, 41,199, 68,192, 2, 81,192, - 90,116,177, 32, 42,112,153,163,101, 79,234, 22, 29,177,136, 12, 22, 25, 11,161,105,234,168,158,158,106,241, 25,161, 36,218,225, - 68,177,232,120,128, 69,238,112,184, 91, 38,160, 28,250,130, 98,149,198, 17,118,181,224,250, 97,191, 51,251, 14,167, 37, 4, 68, - 18,217, 84, 72,142, 12, 84, 95, 55,213,157, 20, 60, 72,210, 40, 95, 62,121,240, 14, 91, 90,146,180,244,170, 2,244,191,216,239, -153,208, 25,189,230, 26,198, 56, 25, 11, 83,205,138, 6,203,224, 58, 81, 13,219, 82, 46, 80,120,167,173, 72, 26,217, 36,168,163, -103,143,101,222, 14, 70, 37, 22,210,117,196, 82, 56,185,250,145, 85,135, 96, 14, 26,105,226, 68,120,173, 88, 50,172,229,121, 48, -159,202,120, 24, 69,144,244, 4, 81, 50, 10,162,139,105,104,104,197,198,149,242, 89,217,121,241,228,113, 56, 25,110,152,124,183, -134,126, 63, 71,199,200,163, 72,176,235,151,208,184, 8, 49, 34,209,246, 73,245,157,180,211, 60,101,178, 89,161,202, 96,213,242, -246,239, 73, 95,169,106,100,131,191,105,110,222, 38,117,183, 8, 87, 57,122,149,161,195,136,185, 36,135, 29,116,248,162,188,184, -185,115, 8, 65, 24,192, 31, 67, 95, 67, 81,119,189,254,184, 87, 45,111,141,130,129,154, 14, 35, 59, 46,124, 60, 61,124,246,249, -219, 71, 83,213,160,177, 77,197, 93,199,157,196, 0,250, 24,170,147,105,138,166, 95, 41,190,172, 45,236, 80,249,126,232,146, 27, -110,200,187,123,247, 78,187, 39, 36,235,125,185, 7, 72, 38, 68, 66,208, 20, 37,113,195,221,157, 97,234,141,135, 40,100, 3,240, -243,254, 26,247, 60,183,113,179,126,235,184,253, 9, 62,164,117,163,117, 54,252,137, 46, 74, 36, 66,105, 98,223,101, 9,207, 7, - 94,115, 26,160, 61,239,217, 8,149,199, 61,183, 6, 95,243,254,126,235, 75,247,171, 63,246, 85, 78, 7,239,108,149, 54, 7,193, -240,246,206,193,143,243, 54, 64, 63,170, 26, 16,105,181, 92,132,101,111, 64, 78, 64,196,161, 20, 86, 47,192, 13,113,242,210, 74, - 97, 3, 37, 83,184, 88,162,132, 63,220, 18,170,173,113,117,185, 0,100,131,139,225,126,125, 15,101,238, 57, 55, 45, 65,176,145, -164,122,212, 12,254,252,197,219,147, 15,215,131,218,151,110,229,205,171,231,143, 30, 52,141, 5, 51,186,112,252,205, 94,191, 63, -122,215,247,175,204,170,151,108,200, 78,116,137,187,106,215, 70,145, 15, 11, 83, 26,241,245, 62,244,225,246, 29,175, 80,157,203, - 24, 14, 39,136,207, 18,136, 66,184,174,146,195, 90, 2,180,109,247,219, 28, 19,208, 34,108,225,121,172, 24,113, 58,112,198, 95, -126,179,209,241, 59, 82,149,104,116, 79, 19, 57, 92, 73, 22,164,208,191,159,147, 42,180,177, 53,231,138,193,145, 42,157, 89,114, - 63, 83,138, 95,210,182,156,104, 17,115,182,174,103,206, 46,185, 50, 18,253, 26, 36, 69,216,137,146,131, 87,253, 90,128, 99, 91, -148,144, 22,156,179,209,211,149, 81,210,156, 99,198, 50,199, 38, 93,161,129,235, 21,228, 57,193, 51,100,167, 26, 14,203,171, 32, -138,230,103, 71,113,184,234,114,177,102,174,205,214,224,245, 74, 51,241,143, 0,148, 93,203,110,211, 64, 20,245,140,103,108, 39, -105,156,132,180,165, 60,186, 64,170, 16, 72,221,161,126, 1,159, 1,124, 7, 11, 22,124, 34, 98,129, 4,155,194,142, 71, 32,194, -137, 29,219, 99,123,134,251, 24, 91,105, 41, 2,164,202,139, 42,113, 38,206,204,157,115,239,156,123,206, 63,197,247, 27,229, 5, - 60,161,109,112, 15,241,127,222,172, 36,248,205, 5,150, 47,216,223, 21,224,172,229,234,113,170,142, 74,151,149, 93,206, 41, 42, - 17, 99,144, 96, 42,252, 38,225,195,186, 38,192, 46,201, 42, 24,175, 68,244,128,121,160,165,142, 49, 0, 42,120, 77, 18,198,137, -198, 42,205, 36, 62,200, 76,118,153,125,224,254, 55, 60, 20,116,116,202,234,122, 77, 31, 50, 44, 23,156,244,249,244, 71,244,167, -255, 88, 73,176,222, 84,229,138, 87,137, 12,174,113,107, 28,203,224,180,174,193, 92, 64,162,202,143,244, 34, 7, 36, 15, 76,155, -157, 66,240,142,216,150,228, 76,232, 13,248, 15,233, 72, 63,158,235, 23,210,195,127,185,215, 82, 49,208,172,156,167,247, 32,199, - 70, 97,213, 66,226, 38, 29,141,162,213,174, 96, 73, 23,184,212, 6, 59,243, 60,143, 64, 50,205, 23, 62, 83, 77, 81,182, 81, 63, -189,120, 82,149,133,104,118,182,203,179,181,249,188, 70, 94, 14, 9,244, 5,228,196,212, 27, 22,116,130,200, 73,142, 9,142, 54, - 96,205, 58,158,191, 93,172,199, 40,167,181, 91, 99, 28, 70,159, 19, 49,132,248,129,108, 11,119, 98, 5, 2,180,214, 66,151, 62, -116, 96,139,112,191,164,250,152,179, 76, 0,162,197,101,181,210, 29,105, 3,208,147,196,132, 10, 6, 1,169,119, 93, 23, 85, 11, - 79, 50,140,117,220, 52,245,124,188,220,214,153, 24,152,103, 65, 95,193,241,205, 35, 34, 86,201,113,122,184,202, 86,117, 91, 15, -142,148, 44,214, 13,113, 92,135,186,168,115,223,133, 72,197,107,248, 98,179,233, 60,223,229,233, 40,133, 17,194,108, 41, 77,169, - 81,202, 61,201,107,116,104, 81, 74,157,159,158,191,189,124,115,119,126,250,163, 88,245,100, 80, 71, 20, 41, 57, 63, 88,196, 48, -242,182,131,219,158, 44,238,124, 93,127, 9, 81, 45,206,141, 34, 0, 16, 5,121,248, 74,254, 17,225, 62, 6, 25, 17, 34, 29,205, -115, 52,107,196,159, 49, 77, 14, 96,107,105,219, 6, 6,134,134,148, 2,123,101,201,171,164,232,229, 72,236,225,116,105,172, 1, - 68, 82,153,146, 8,209,193,189,197,125,216, 5,209,137, 11, 55, 3, 3,137, 11,158,231,239,157,222,177, 17, 11,236,253,239,190, -191, 79,148,130, 39,148,163, 65,128,205,155,186,234,154,109, 99,118,228,143, 97,237,223, 45,124,206,162,164, 13,237,170, 50, 5, -189, 54, 86,104,239,133,245,103,148,217,193,133, 99, 76,203, 40,113, 44,210,194,102, 15,111, 63,126,246,226,249,235,151,175,196, -177,248,223,248,190,140,166, 23, 71,143, 16,207, 57, 57, 27, 77, 55,213,150,136, 94, 33,246,169, 32,210,210,212, 42, 12,107, 5, -109,218,106,212,192, 8,184, 72,194,229, 17, 24, 82, 67, 36,114,152,111,144,250, 0,124, 14,168,129, 3,150,251,131,147,179, 79, -223, 62,178,125, 27, 67, 22, 64, 18,232,227, 88,253,148,126,133, 56,127,208,218,247,157,223, 68, 49,116, 67,139, 19,227,118,206, - 24,110,165, 75, 0,105,128,244, 81, 14,133,211, 95,193,138, 84, 66,252, 33,114,134,216, 32,157,108,202,141, 87,148,239,173, 92, -221,128,217,251, 69, 55,141,103,133,217,176,144, 14,155, 66,141,162, 73,222, 22, 19, 53, 46,174, 58,100,244, 22, 37,215,135,109, -247, 74, 58,191, 4,224,236, 90,118,155, 6,162,168,199,227,216, 73, 28,229,213,208, 80, 16, 66, 66, 66, 98,139, 84, 22,124, 60, - 72,136, 47, 96,193,174,136, 8, 40, 37, 36, 77,136,227,183,199, 30,238,185, 99,187,142,218, 13, 72,221, 85,137,237,241,228, 62, -206,156,123,142,243, 79,176, 76, 23,121,215,141,231,134,213, 81, 20,192, 65,182,116,205,152,227,131,133, 47,175,163,107,238, 41, -181,212,136,135,214,244,201,132, 84, 91, 74, 11,115,163,178,185,132,236, 40, 71,114, 28,150, 40,141,249, 15,138, 84,224, 31,130, -106, 72,223,152,177,207,167,104,160,183,182,125,233,170,255,220,167,242,151,166,189,208,218,122,232, 61,181,159,116,192,162,165, - 82, 46,111, 83, 0,178, 58,108, 76,184, 98, 96,116, 26,140, 24, 4, 58,118, 71, 54,110, 95,150,237,209, 47, 7,232, 70, 69,109, -168, 80,236, 54,105,219,141, 64,134,161,134,212, 1,126,226, 45, 14,217,150, 23,148, 91, 2,100,121, 0, 56,149,131,143, 10,135, -194, 4,101, 7, 47,164, 98, 67,137, 93,148, 83,201, 34, 7,162, 44, 89,220,197,238, 77,198, 30,212,105,139,114,234, 15,166,190, - 95,168,236, 98,121,190,249,177, 10,246,234,215, 14, 92,122, 85,128, 37,161, 89,210, 5, 92,202,186, 55, 68,222,227, 39, 48,214, - 49, 44,112, 43,152,112, 36, 36, 5, 35, 10, 55,245, 11,178,165,174,202,142, 90, 54,183,209,182,227, 58,189,180, 76, 12,208, 77, -181,204,194, 95,110,195,117, 65,249, 15,121,141,193, 18,221, 64, 89, 66, 40,120, 9, 10,109,170, 83,148, 45, 72,127,127,194,173, -105,111, 92,199,165,232,140, 35, 74,149, 24,181,119,115,186, 53,116,168,185, 86,204, 63,170, 55, 97,156,135,223,182,241,168, 63, -234, 58, 55, 48,193,185,234, 99, 8,153, 27,112,141,230,142,246, 73,174,114, 28, 28,128, 41,193, 60, 55,152,125,239,206,198,203, -221,113,227,247,125,145, 0,124, 85,133, 10,162, 80,233,114, 27,173,217,200, 5,158,160,203,217,147, 40, 13,169,140,154, 14,199, -171,205, 87, 7, 86, 45,242,152, 4,158,219, 75, 97, 37,104, 69,105,162, 97,196,136,200,195, 45, 3,174, 69,139,226, 97, 4,247, - 96, 90, 33,102,248, 21, 73, 22,211,190, 85, 54, 88,179, 51,127,118,136,246,103,227, 5, 69,180, 36, 75,158,206,159,209,243, 70, - 89, 92,162,185,194,217, 33,173,198,227,233,249,207,253, 53,122,142,188, 80, 50,159, 13,166, 81, 26,163, 31,108, 16, 27,174, 39, -141,239, 52, 93,110,112,155, 30,251, 56,139,178,125, 33, 39,125, 15,225,222,194, 17, 45,108, 69, 5,189,151,220,233,249,175, 94, - 60,255,240,249, 83,146, 38, 18,148, 98,232,217, 30, 85,145,194,233, 69, 95,229,233,137,193, 27, 70,142,149,129, 22, 80, 13,168, -187,113,161, 88, 7,193,234,176, 57,220,190,251,248,254,237,235, 55,255, 81,191,103,149, 26, 13,253, 52,130,109, 58,237, 46, 99, - 93, 13,153, 66,214,143, 59, 38,140,245,105,106,124,138,146,241, 16,102,140, 72, 85,101,230,126,120,242,137,145, 19, 65,219, 32, - 51,113,179,103,203, 71,243,139, 47, 55, 87,244, 63, 46,213,245,229,203,203,155,253,250,122,247,189,198, 12,153, 9,209, 6,116, -155,195, 50,211,225,106,146,119,213, 29, 3, 53, 7,114,134,163, 44,140, 72,184,254, 29,172,185,108,183,235, 6, 87,212,102,172, -214, 9, 79,253,132, 93, 77, 11,151,232,180,210, 13, 8,108, 30, 85, 48, 53, 65,212,136,143,249,142,176, 8, 40,169, 79,134,115, -150,168, 67,196,143, 88, 82, 24,148,144,234,142,247,221, 70,164,242, 94,196,239, 26, 87,253, 21,128,179, 43,217,109, 26,138,162, -126,207,142, 29, 39,206,156,166, 32, 90, 90,129, 84, 36, 36, 86,236, 89,194,138,191,224,227,248, 4,118, 44,145,250, 1, 72,116, -133, 82,134,210,212,153,236, 56,158,205, 61,247,121, 72, 89, 85,100,153, 73,201,243,245, 29,207, 61,199,248, 15,121, 38,113,111, -103, 85,145,247, 22,149,164,170, 81, 98,225,121,236, 93, 52, 99,138,166, 69,196, 8,111,128,100, 76,198,201,128,220,178,121, 93, - 24, 0,243,136,186,203,160,151,221,118, 69, 14,204,141, 93,164, 81,104,184, 75,166, 44, 5,219, 11, 68,140,209,122,103,180,140, - 48, 53, 61, 42,118, 18,172, 64, 21, 75, 68,229,221,107,165, 46, 89, 99,143,170,228, 61,123,128, 32,120, 69,224,163,246,105,217, -226, 81,205,150,140, 88,252,243,200, 3,243,178, 62, 82, 94,202, 59, 10,163,101,145, 29, 82, 69, 75,190, 44, 13, 67,150,167,148, -172,173,205,138, 96, 89, 86, 31, 76, 37,101, 12,151,190, 72,254,148,145,153, 35, 1,125, 42,229, 62, 49, 14, 65,151,148,167, 82, - 89, 66, 57, 47,221, 0,155,253, 62, 73,149, 86,148,180, 90,200,182,218,166,121, 52,104, 71, 1,157, 97,114, 58, 61,190, 56,127, -220, 31, 58,102,203, 8,109,251,187,231, 50,128, 12,112, 0,172,123,169, 44,151, 87, 67, 40, 69,146,220,147, 1,151, 3,255, 23, - 86, 83, 83, 84,121, 5, 24,203, 48, 47, 41,213,172,232,195,142, 61, 96,230,128,162,225, 3,197, 55,165,162,198,147,106,210,110, -219,210, 23,149,137,151, 11, 3,150,217,181,117, 11,139,121,226,223, 10,143,215,252, 48, 17, 24, 59, 83,242,122,144,204, 53,200, -169,237,135,189,177, 23,120, 26, 35,147,168, 40,161,194,227,116,116,246, 99,121, 77, 46,111,214, 63,158, 67,160, 81,163,108,186, -228,219, 46, 45, 7,179,153,148,135, 94,234,230, 45,233,176, 52, 6,231, 72, 83,104, 65,144,236,216,144,116, 6,175,138,136, 28, -132, 16, 23,179, 23,223,126,127,165,232,242,236,232,249, 54,218,110,253, 53,218,109, 20,174,210,184,215, 25,108,130, 13, 88, 98, -210, 66, 55,129,113,116,253, 59,141, 91, 0, 74,175,142, 14, 99,208, 25,144, 69, 46,214,139,118,155,106,106,236, 1,100,153,207, -213, 23, 40, 43,116,230,228, 25, 57,227,165,239, 38, 9, 40,226,188,112, 67,207,108,130,173, 0,195, 32,232,207, 82,228,199, 49, -253,226, 56, 15,135,206,196, 11, 86, 63, 87,191,232,210,196, 73, 36,233,210,199, 69,127, 50, 60,153,158,204,111,175,193,190,194, -132,173,148,217,244, 76, 42,173, 86,100, 23, 79,156, 71, 87,203, 27,214,114,145, 42,193,129,150, 10,244, 2,121, 27, 80, 10,138, -142,175,158,158,125,120,255,238,229,249,236,227,167,207, 19,211, 54,208,244, 3,160, 23, 43,120,236,120,226, 44,119,147, 56, 76, -211, 47,139,155, 24,187, 29, 90, 3,215, 19,135,120, 98,163, 63, 26,144,125,116,133,253,246,245,155,131, 44,234,161, 15, 63,221, -123,209,110,214,155,144, 37,135, 57, 64, 74,170, 59, 97, 74,157,206,132,243, 62, 53, 1,130,165,182, 76,203,177,250,183,254, 45, -147,189,227, 70, 33,115, 29, 58, 99,170,219,130,112, 71, 69,172, 10,115, 20, 41,231,119,115,186, 61,122,237,238, 62, 10,233,109, -151, 87,151, 12,255,208, 11,113,160,205,161, 18, 39,158,200,140, 58,163,245,206, 21, 8,207,247,244,170,181,106,114,169,250,150, - 37,237, 12,187,147,170,144, 40,212,119,228, 53,144, 81,171,157,138,104,242,105,141,183,196, 48, 62,227,254, 96,227,217, 21,199, - 65,165,191,170, 24,100, 0, 29,202, 93,223, 85, 10,171,138,189,148, 14, 38,206, 34,181, 32,217,144,136,149,126,163,217,110,205, -235,136, 82,117,135,254, 10,192,216,181,244, 54, 17, 3, 97,239,203,187,117, 18, 30,109, 41,165,165,173,160, 74, 91, 14,220,144, -144,248,183,252, 11, 78,156, 81,185,241, 16, 15,169, 52,106, 90, 9, 74,178, 73,154,100,211,236,174,109,230,225,236,166, 8,164, - 74, 57, 68, 81,228,172, 29,123,102, 60,243,205,247,133,183, 49,235,226, 95,108, 4,139,154, 42, 39,199, 61,199, 14, 70, 56, 65, - 12,231,109,224, 45,227,101, 28, 23, 0,166, 39, 16,175,140, 45, 53, 24,130,149,122,110,107,120, 3, 47, 76, 64,222, 85, 56,121, -166,154,255, 29, 89,119,177, 5,135,196, 68, 49, 61,205,146, 25,150,168, 78, 40,198, 37,189, 66, 36, 63, 24, 35,177, 20,198,112, -173,184, 53,200, 82, 81,211, 80, 44,209, 77,220,112,176,203,117, 2, 62, 11,246,127, 62,143,242,213,186,158, 88,189,208,248,202, -137, 37,220,181,107, 81, 79,154, 21,132,100,247,104, 82,134, 21,254,108, 18,169, 18,155, 86, 52, 39,181,204,242,190, 98,136, 55, -210,118, 80, 55,174, 71,106,127, 96,233, 53, 73, 22, 97,113, 56,204,230,229,215,225, 4,174,222, 94, 20,123,216, 87, 4,187, 57, -184,171,164, 68,102, 6,175,225,135, 74, 69, 66,202,231, 7, 79, 35,169,227,192, 7,163, 63, 31, 93, 79,103, 37,222, 60, 92,194, - 22,172,177,149, 86, 53,131,102,232, 39, 9,217, 1,159, 10, 92, 87,229, 32,205,251,196,163, 18,104,199,211,131,156,126, 84, 44, -176,142,132, 89,211,149,148,242,155,180,255, 80,186,214,242, 63,207, 96, 93,171,187,189,206, 74,184,130,121,103,207, 86, 80,171, -235, 60, 43, 60,132,226,135,156,240,112,183, 85, 74,105,209,252,247, 55,246,187,189, 51, 24,112, 58,155,160, 89,180, 84, 73,195, -226,128,175,226, 70, 73,236, 82,231,253, 14,140, 56,203, 39,195, 44,226, 77,182,179,190, 11, 22,159, 58, 6,145, 84, 18,140, 53, - 12,199,114,104, 44,116,131,204,225, 30,220,234, 48,151, 50,198,108, 9, 22,102,225,199, 11, 91,142,178, 33,124,105,154, 79, 96, - 89,206, 7,231,176,235, 58,189, 78, 64,201, 28, 48, 46,202,151,115,115, 13, 33,219,131,230, 26, 60,237,225,246,225,241,247,119, -176,135, 7,227, 20,158,229,101,251,197,241,201,123,240, 7, 84,210, 40,145,191, 72, 4,237,199,109, 37,213,233,229, 41,132,228, - 79, 54, 14,190, 92,124, 54, 84, 74,201,209,129, 22, 5, 74, 24,218,149, 72,129, 93, 6, 23,130,202,148,216, 19, 31, 17, 67,225, - 21, 27, 16, 44, 43, 51,254, 65, 32,157, 4,248,140,205,123, 15,127,141, 80,136,252,132, 8, 53, 81, 59,204,115, 92,165,196,161, - 88, 82,129,222, 68,129, 92,141,239,156, 77,251, 16,194, 27,214,180,168,161, 0,120, 38, 97, 29,126, 92, 94,124,235,116, 63, 93, -254,252, 48,248,189, 41, 27,177,143,138, 96, 42,138,154,161,108, 37, 50, 14,240, 42,188, 5,239, 67,217, 43,242,143, 61,164,207, -244,168, 13, 71,219, 27, 50,118, 82,196,162, 41,118,182,183, 76,168,197, 81, 2,159,188,125,253,230, 81,123,247,217,171,163,219, -155,120, 3, 43, 95,102, 37,241,118,193, 82, 20,212,160,159,163,104, 78, 21,158, 17,106, 69,160,180, 20, 65,101, 48,148, 34,202, - 95,132,191,130,219, 43,117,161,133, 94, 42,246,113, 85,148, 96, 96, 6,183,149, 13, 22,120, 56,193, 46,128, 2, 1, 35, 22,168, - 66,131, 25, 51,171, 3,215, 27, 90, 33,229, 42,117,110,235, 8, 42,249,236, 18,255, 29,216, 96,149, 40,120,128,140,246, 24, 12, -118,191,177,150,142,241,206,189,214, 90, 79,167,169,173,200, 8,248, 18,224,210, 25,102, 65,238,104, 88, 87, 96,225, 18,248,100, - 85, 72, 13,127,111,117,239, 44, 61,117,173, 80, 92, 30, 96, 43,102,106, 93,210,133, 68,201, 95, 86,154, 51,252,110, 22,127, 4, -160,236, 74,122,148, 8,194,104,117, 55, 13,205, 54,192, 32,203, 56,204,104, 60,248,123,253, 47,158,188, 27, 19, 15, 30,212,152, - 49, 49,144, 89, 18,134,129,129,102,105,104,122,171,242, 91,170, 88, 34,154, 8, 55, 72,122,171,174,111,125,223,123,185,127,155, -245,191, 25,119,195,242,200,236,200, 36, 88,164, 5,106, 73,231, 82,232,214,133,109, 10,239,216, 53,112,248,209, 96, 36, 75,163, -170, 60,138,206,232, 78,219, 44,129, 67, 23,141, 4,238,182, 33, 36,179, 52,150,134, 71, 67, 24,176, 65, 39,194,252, 20,118,128, -179, 70,158,104, 81,116,145,252, 4,182,194, 44, 94, 38, 18,147, 53,204,133,147,144, 43, 16, 7, 64,191,211, 1,134, 50,158, 80, - 25, 29, 47,221, 46,166,161, 28, 56,148,117, 34, 15, 58,234, 54, 27,148,134,230,180, 97,101, 93,102,118,102,178, 82, 45,189, 34, -109, 30,106, 96,121,201, 67, 32,169, 38,121,150, 34, 19, 90,216, 91, 34,230,175,184, 77, 2, 7,252,162,147,229,133, 39,101, 12, -113,224, 83, 28, 85,107,197,235, 74, 13,130, 97,240,123,176, 43, 54, 81,226, 74, 71, 69,118,185, 96, 85,243, 56,246,133,162, 25, - 56,127,151, 21,171,213,237, 42,254,214,127,132, 39,150,226, 39, 70, 56, 86,230,149,212,153,107,229, 80,166, 68, 46, 3,216, 5, - 16,149, 34, 50,189,220,241,122, 23,197,203, 95,193,207, 40, 11,193,216,161,245,176,144,221, 63,219, 61,122, 11, 76,103,232,240, - 53,146, 63,175,151,207,225,247,121, 48, 37,170,235, 2, 77, 5, 83,161, 29,156,110,150,149,220, 42,118,115,137,174, 29,190, 16, -133, 5,161,143, 98,217,185, 28, 21, 76, 84,171,218,158,111, 22, 44, 99,115, 59, 25, 48,203,147,133,136, 32, 79,133,184,115,214, -209, 10, 78,214,169,181, 71,254, 35,164, 71, 30,162, 96,237, 48, 89, 47,195, 5,118, 91,149,122,120,190, 51,124,122, 72, 86,110, -241,240,160,165,185,151, 25,190, 11,171, 81,204,151,192,154, 95,158,247,102,235, 41, 34, 35,147, 77,194, 19,237, 74,119,210,130, - 45, 98,207,131,112,197, 47, 4,166, 75, 68,202, 3,119, 9,145, 59, 44,200,167,155,143, 68,147,130,122,187,105,148, 14,231, 99, - 92, 97, 34, 12,225,169, 55,199,113,225,249,222, 60,124,201, 57,232,156,186,141,118,170,146,193,104, 32,205,102,164, 82,137, 32, -186, 30, 30, 40,176,225, 54,123,141,235,219,231, 62,242,236, 88,170, 91,127,233, 47,167,112,180, 49, 77, 54,213, 75,205,229,102, - 62,244,135,229, 66, 57,198,206, 4, 78, 53,216,182,126, 63,109, 65, 67,103,106, 11, 57, 4,146,156,101,233,219,230, 21,216,247, - 20,217,105,181, 6, 52,201,134,226, 29, 38,168,155,154,125,157, 12,222,189,255,240,249,254, 7,218,104, 88, 91, 8,222,113,168, -194, 41,216,110, 35,242, 94, 84, 32, 54,200, 19, 0, 69,189,170,212,190, 79, 70,166,209,119, 28,187,195,121, 69, 12,111,199,235, -171,107, 77, 61, 44,172, 32, 88,189,233, 94,252, 87,137,102,186,242, 59,103,205,221,240, 96, 62,231,182,106,173,254, 83, 31,197, -235,227,109,130, 53, 46,193,250,105,146, 25,144, 48,207,197,233,188,130,227,165, 89, 56,223, 46,148,201,158,143,180, 47,176,112, - 23,238,229,220,132, 78,183,181, 9, 76,181,219, 35,178, 26,177, 8,125, 66, 71, 72,166, 88, 63, 4,206, 33,214, 14,108,140, 52, - 42,110, 24,113,235, 62,134, 46, 31,113,119, 70,234,158, 40,252, 49, 94, 78,132,250, 3, 91,205,158,132,162,111, 29,207,217, 16, -144,213,252,245,108,231, 50,229, 94,155, 91,221,207,238, 36, 21,128, 12, 95,150, 98, 80,166,117, 58,240, 52, 71, 80,123,132, 60, -175,213,111, 1, 40,187,186,214,166,161, 48,156,156,124,158, 52, 93,167, 93, 55, 5,189, 80,135,130,168, 56, 17,241, 70,255,133, -255,192, 75,127,151, 55,130,224, 47,112, 12, 20, 68, 4,175,100,140, 93,140,185, 41,155,149,174,105,147, 38,105,147,227,251,188, -111, 50,170,187, 18, 66, 97,109,215,143,211,243,126, 63,231,121,212,127, 17, 18,180,214,109,206,157, 59,221,186,140,102, 1,140, -193, 10, 59, 42,142, 85, 55, 82,221,142,211,141, 28,237,131, 86,203,245, 12,237, 23,159,254,244,128,117,241, 92,186, 81, 30,116, -120,109,233,199,128, 78,247,156, 78,129,174,128, 50, 79, 76,125, 93, 3,119,239, 72,101,192,132, 51,192,161, 48,253, 46,163, 74, - 28, 24, 54,159,243, 71, 58,221, 72,183, 24, 27,157,107,238,226,245, 87,214,133, 11,174,129,193, 90,194,252,127,113,109, 80,245, - 47, 47, 19,101,253,190, 19,202, 42,185,224, 50,116, 47,180,226, 47, 94,141, 90,235, 90, 60, 88,134,160,154,166,128, 99,230,119, - 52, 84,109,249, 48,105,145, 66, 21, 68, 34, 59,207,231,155, 75,148, 3,248, 46, 25, 77,164,101, 34,240, 91, 3,204,123, 41,219, - 43,116,221, 65,164,181,227,155,185, 59,207,157,122,230,155, 50, 72,210, 58, 70, 13, 27,240, 30,178, 41,234,157,156, 14, 33, 39, - 59, 74,118, 62,124, 54,140, 40, 39,111,126,255,218,163,171,209,102,183,234, 21,243, 98, 92, 36,179,138,234,128,140, 2,225,172, -154,229,139, 44, 43,167,227, 98, 20, 40,255,118,239, 14, 18,108,200, 79, 43,218,136, 18,178,123,225,138, 66,111, 77,218,233, 88, - 90, 46,114,173,113, 54, 34,143,105,184,251,230,129,132,145,235, 12, 11, 58, 38, 32,214, 40,161,157,201, 28, 27,248,110, 89, 49, - 97,193,109,104,107,112, 82,164,126,165,195,154,169,162, 4, 72,202,169, 60, 86, 44,159, 23,148,132,157,140,143,121, 64,106, 40, -117,125,112,227, 33,243,180,148,244, 10,171,157,190, 76, 89, 90,205, 93,133,204,142, 66, 93,153, 9, 15, 22,228, 6,193, 13, 0, -244, 14, 3, 52,225, 62,158,221,125, 94,128,186, 82, 77,138, 73,201,115,206, 86,183,184, 81, 48, 14,124, 48,181, 61,222,124, 18, - 6,154,226,241, 36,159, 96, 70,199,182,163, 32, 11,230, 14,122, 27,244, 35, 92,138,215, 60,207, 63,252,125,136,162,204,182,103, -249, 84,123,218, 6,187,108, 78,233,255,198,234, 21,223,163, 45,164,182,191,109,239,253,216,147, 57, 59, 5,170,200,215,229,162, -160,112,200,178, 12, 24,129, 80,184, 13, 92,189,123,188, 75, 91,142,108,131, 62,249, 89,122, 22,133, 49,251,111, 59,214,241,156, -115,115,178,175, 56,136,201,104, 98,221,145,105, 4, 79,121, 80, 5, 27,196, 12, 83,178,151,165, 72, 31,248,157,235,157, 62,216, -195,129, 63,198,150, 2, 61, 2,115, 63,131,211,221, 54,244, 30, 9, 72, 28, 40, 1,183, 10, 3, 70,135,108, 81,156, 21,249, 48, - 79,143,210,228,231, 52, 97,145,116, 83, 44, 22,235, 94,184, 18,117, 68,242, 89,253,229, 73, 56, 5,181,230, 7, 95,246,135,211, -209,247,211,227,163,175, 7,244,216,251,143, 59,175,223,189,165,135,182,182,158,134,122,181,197, 97,252,147, 58,186,145, 30,220, -186,121,239,229,139, 87, 59,111, 62,245,245,101, 7,195,109,159, 27,151, 56, 49,130,189, 1,167,128, 49, 12,115, 93,227, 16, 94, - 9, 13, 61,244,229, 41, 88, 86,236,235, 51, 64,117, 25, 43, 89,155, 22,144,222, 30, 8,109,245, 52,205,178,101, 53,137,176, 32, -226,219,210,160, 18,195,106, 44, 78,134, 12,205,177,169,246,255, 61, 5, 16,109, 37,160, 97, 6, 72,214,208,249,210, 13,118,165, - 81, 22,182,134,147,211,186,109, 43,183, 76, 4,102,233,221,107,102, 27, 65,100,170, 4, 69, 98,192,118, 41,113,183,110,248,125, -228, 60,150, 48,127, 52, 20,145,109,104, 18, 46,131,165, 52,148,193,162, 75, 95,154,239,177,106,115, 78,232,204, 79,254, 35, 0, - 95,215,210,218, 68, 20,133,231,206, 35,243, 72,211, 73, 76,169, 77, 83, 75,105, 5, 45, 46, 44,186, 22,193,181, 75, 87,234,162, -136,184, 18,127,162, 75, 95,136, 40, 21,164, 18, 41,181, 32, 36, 41,109,211,121,221,121,220,185,158,115,238,204, 52, 85, 49, 12, -100, 51, 33,115,239,156,115,238,121,124,231,124,250,255, 45, 59, 57,176,170,189,104,222,184, 27,236, 34, 57,131, 12,215,224,229, -185,204, 51, 53, 11, 34,157,160, 8,130, 98,134,152,132,210, 29,122,107,125,183,111,226,204,115,203,179, 61,100, 15, 5, 71, 65, -218, 45, 13, 65,141, 38, 78, 65, 36,208, 31,166, 32, 12,197, 88, 88,179, 56, 89, 42,151,100, 82, 54,159, 50, 22, 42, 42,192,176, -148,170,140, 90,149,202, 38,167,194,160, 41,228,240,168,169,136,195,252, 84, 16,162, 96, 18,254, 42, 74, 53, 76,188,238, 25, 83, - 36,135,151, 42, 16, 20,105,154,206,252,210, 81,243, 41,113, 4,135, 19, 23,121,148, 39,108,222,107,249,183,125,151,196,205, 46, -198,225, 84,252,137,163,172,135,239,211,168, 10,196,202, 10,166, 53, 36, 46,229,165, 11, 75, 96,245, 71,145,207,148,178, 78,110, - 35, 25,152, 80,118, 22,188, 74,158,139, 40,198, 43,137, 33,116,149, 57,135,136,148,117, 28,208,127,211,177, 53,216,107,183, 5, - 86, 69, 11,206, 38,223,190,142,162, 56, 53, 88,213,167,241,113,255,203,201,241, 44, 42, 56, 50,153,148,160,202,130, 4, 16,191, -114, 77,164, 34,229, 5,172, 63,232, 89,189, 69,179, 71, 79,205, 56,150, 4,209, 39,206,178,148,232, 4,212, 36,103,166,160, 64, -142, 97,227,104,123,124, 57,224,236,151, 25, 22,202, 52,226,168,106,129,235,143, 99,144,117,194, 66, 17, 89,138, 78, 80, 98,250, -185,126,165,189, 68, 0, 65, 93,117,216,234,106,124,100, 29, 3,193, 14,224, 96, 31,157,217,134,109,235,246, 85,127, 0,174,241, -135,239,239, 36, 97, 74,121, 22,130, 87,251,151,208,234, 75,157,190,161, 53, 8, 55,217,245,186,219,195,237,237,225, 77, 73, 72, -158, 92,164, 63,198, 35,240,215,176,158, 75, 34,224,210,216,156,198, 50,192, 50, 61,203,131,195,230,112,122,144,166, 73,157,142, - 66, 46, 26,234, 6, 40,121,154, 77,102, 99,208,210,159,199,135,109,167, 77, 61, 0,186,215,106,131, 64, 70, 89, 72, 19,148, 81, - 53, 64,230,179, 60, 67,254, 39, 16,126,211,116, 44, 7,100, 9, 14,245,245,165,245, 69,215,223, 90,217,244,189, 69,158, 39, 29, -223,127,244,240,201,116, 54, 69, 63, 17,222,105,138, 7, 94,150,167,231,124,134, 8, 93,166,135,113, 20, 37,193,160,191, 2, 97, -218, 36, 64, 78,243,128, 39, 92, 80,129,145,114,182, 11,118, 27,179, 67,148, 18, 43,201,129,140,139,236, 90,119, 85, 96, 38, 90, - 86,194,143,164,166, 76,157, 81, 52,251, 25,124,219, 76,217,234, 2,137, 60,132,160, 12, 15, 28, 99,113,202,199, 97, 52, 1,113, -145, 96, 79,241,246, 59,253,101,234,101,107,184,238,101, 51,110,106,224, 14, 54,238, 94,223, 25,110,221,222,188,177,182,179,177, -236,173, 62,184,127,111,247,229, 46,108,200,167,247,111, 95, 61,126, 81,223,137, 12,111,252,156,127,126,189,183,214,185, 21, 29, - 68, 81, 60, 25,189,217,123,254,244,217,209,254, 17,196,100,240, 38, 64,197,176, 50,164,149, 60,231,103, 88,122,113, 78,162, 83, -108, 28,101, 10,117,142,129,160,239,246,156,150, 35, 36, 25,125,202,110, 40,170,210,234, 12, 80, 6,180,177,203,149, 14,177, 11, -253,172,202,154, 13, 2,184,186,167,129, 62, 10, 20, 54, 11,115,250,110, 79,181,229, 41,128, 27, 28, 36, 9,132,184,132,142,196, -122, 46,185,100,158,211,174, 49,151,180,195,130,254,130,169,127,199,205,204,101, 65,120, 88,217, 92,213,243,168,100,189, 84, 29, -170,196, 81, 73,150,189,113, 27,225,237, 44, 56, 29,165, 4,216, 36, 36,217,124,135, 14,173,163,154, 28,175, 88, 97,155,171,172, -167,154,149,115,182,255,183, 0,132, 93,203,110,211, 64, 20,245,140,147, 58, 73,235, 80,212, 22,181, 85,186,233, 6,181,176, 97, -193,227, 15, 88, 32,241, 53,176,228,123, 16, 27,118,252, 0, 18, 18,160, 74, 93,176, 0, 9, 81, 41, 33, 73,227,198,169,155,120, -108,199,175, 49,247, 97, 59, 45, 15,145, 69, 36,203,146,101,143, 61,247,125,206,249,127,253,189,221,176, 20, 66,236, 42, 94,145, -178, 38, 83, 6,212, 68,138, 40,187,166,141, 2,205, 34,169, 90, 12, 16,123, 38,110,234,154,161, 56,222, 62, 50,108,227,204, 63, - 83,137,178, 36, 70, 70,185,196,105, 69,236, 40,195, 39,141, 92,200, 57,226,230, 11,238, 38,240, 28, 56, 24, 50,109, 33, 11, 77, -205, 2, 79, 30,128,251,139, 52,178,202, 25,120,132,192,250, 6,241, 32,173,109, 52,219,176,136,125,117,150, 19,119,168,166, 65, - 24, 8, 47,117,206, 34, 40, 90,148,171, 80, 38, 47,162,214,243, 32, 45, 93,227,183, 86, 48,181, 14, 33,158,202,210,236, 79, 42, -180,127, 20,120, 74,135, 46,145,136, 79,139,107,156,107,152,222, 23,200,107, 1, 15,145,162,231, 16, 37,192,161,242,177,178,170, -213,233,170, 83, 80, 9,196,176, 85,198,101,110, 72,184, 50,206,180,192,195,111,117, 91, 4,158, 38,129,195, 38,146,253,118, 52, -108, 96,179, 99,129,133, 77, 45,115,109,127,111,215, 95,132,219,182,173, 46,166, 3,199, 73,225, 44,198,100, 56, 43,218,149,183, -177,185,132, 50, 76,102,202,112,104, 66, 85, 83, 17, 93, 35, 1, 58,188,190, 28,165, 47,123,118,239,171,231, 34,159, 51, 33,114, -137, 76, 38,167, 80,153,132,180, 5,231,171,162,179,190,145,248, 9,223,117, 65,185, 14, 87,229,145,109, 33,203, 89,178, 83,144, -182, 9, 1, 29,120,102, 8,147, 96, 63,154, 35,145, 92, 81,201, 40, 74,142, 39,164,161,117, 13, 9,198, 66,252, 82,193,225, 84, - 77,236,150, 29, 70,138, 24, 25, 52,121,223,154, 44, 97,245,131, 52,226,250,208,216, 60,154,123,161,135, 89, 8, 82, 64,103, 73, -172,195,116,218, 16, 66, 84, 45,114,180,107, 16, 65,175, 89, 45,179,189,136, 17, 92,234, 42, 23, 46, 16, 36, 17,111, 21, 73, 38, - 3,251,186, 69,218,105,172, 47,145,135, 93,146,160,128,118,253, 41,135, 62,142,239, 48, 90, 23, 22,170, 73, 53,162,177, 55,134, - 19,150,176,112,200, 93, 8, 21,242,109, 47,251, 23, 3,136,129, 38,222, 68, 45, 3, 88,246, 43,239,242,237,187,215,132,131, 48, - 14,119, 15, 79,127,156, 50,133, 38, 15,239,181,173, 22, 35,147, 71,179,177, 73, 80,222, 56,139,239, 29, 28,143,103,163, 40, 9, - 25,192,131,242, 32, 20,232,101, 84,128,134, 27,133,135, 61,218,189,219,159, 59,253,197, 68,211,112, 84,110,172, 0,238, 76, 21, -117, 25,135, 21,212, 28, 95,138,198, 22,145, 36,160,191,240,147,120,162, 22, 12,179, 8,179,108,143,148,108,145, 28,159,112, 85, - 44,105, 12,129, 67,158,230,152, 64, 27,198,119,103,208, 92,111, 25,161, 17,132,193,167,147,147,157,222, 62,124,197,206,183, 33, -239,187, 39,247, 31,125,252,242,225,217,195,167,167,111, 62,159,159, 95,189,122,249, 98,116, 53, 82,239,131,173,238,230,227,231, - 15,126, 14, 33,251, 49,238,108,236, 92,168, 41,236, 88,240, 54, 16,164,131,101, 71, 22, 96, 10, 31,240, 34, 40,227,131,114, 46, - 81,180, 36,144,156,193, 84,187,186,226,100,212, 43,193,162,178,193, 88,150,219,152,136,171,184,209,246,173, 43, 52, 55, 48,149, -213,193,173,206,230,185, 23,204,130, 25,141,115,153, 55, 10,176, 5,227, 34,113,210, 57,208,241, 20,133, 92,114,174,160,144, 31, - 64,197,199, 20, 25,164,152,249, 92,244,182, 14,134,238,160,248,123, 27, 79,212,230, 90,214,213,121, 81,218, 2,248, 35,153, 10, - 60,132,108, 15, 94,116,182, 66,134,179,133, 40,171,244,245,131,107, 99,213, 97,212,171, 41, 24,244,255,191, 4,160,235,218,118, -155, 6,130,168,215,123,177, 19, 59,206,165,137, 41, 72,129, 22,209, 86,226, 82,169, 72, 72,252, 0,223,193,115, 95,248, 6, 36, - 62, 2, 1,253, 7, 94,248, 0, 30,144,144,144, 80, 37, 30, 64, 8, 21,149,182, 20,209,166,165,181, 19,219,185,216,203,206,236, -198, 73,139,136,242,150,200,241,122, 99,207,153,153, 51,231,216,255,171,198,204,122,220,227,196,158, 35,236, 19, 67, 85, 52, 51, - 77,192,144,181, 61, 79, 4,129,240,125, 86, 19,196,197,186, 10,224,250, 5,214, 12,189,144,131,242, 87,112, 63,220,184,217, 88, - 81, 87, 7,212,124,168, 83, 1,239,151,138, 67,132, 32,142,144, 66,221, 6, 42,113,166, 80,189, 97, 54, 88,215, 49, 44,236,168, -252, 81,184,196,229, 68, 48, 32,188,131,102,170,186,173, 0,137, 0, 77, 5,196,103, 80,197,139, 84,152,240, 84, 78,109,147,221, -120,103, 92,100,208, 56,132,148, 20,186,151,197, 68, 79,141, 21, 40,162,175, 81,188,197, 84,182,193, 43,179, 74,190,233, 21,203, -127, 76, 59,172,236, 2,114,159, 53, 98,103,238, 45,151, 63,149, 56,160,236,217,243,114,254,198, 57, 0, 52,188, 0, 50,207, 49, -232, 75,107,247, 98,174,225, 91, 38,116,101, 45, 17, 68, 8,138,153,129, 44, 40,161, 19, 89,243, 88, 43,176,175,182, 89,187,201, - 59, 77,218,172,211, 70,128,155, 94,216,119,215,214,174,180, 59,205, 90,157,244,211,189,159, 7,100, 24,209,225,159, 73,122, 58, - 72, 78,162,228,244,112,244,173, 71,190,166,116,199,117,247,124,183, 39, 88,106, 3,181,131,169, 31,225, 24,182, 1,213,163,129, - 61, 7,205, 72,163,153,109,172,205,137,197,128,187,230, 9,206, 75,255,224,104,112,106,193,156,130, 61, 29, 73, 53, 54,126, 30, -247,169,150, 76, 6, 17, 5, 10, 24,214,162, 18, 89,240, 0,245,129, 29, 74,253,170,135,157,116, 20,132,197, 45,241,157, 26,103, -206,229,176, 9,129, 68, 70, 89,156,227,184,192,234,181, 85, 50,189, 86, 56, 37,144, 19,227,194,163, 53, 94,117, 14,132, 26,203, -104,127, 11,195, 18, 24,109,253,106,128, 49, 19,228, 4, 58,181, 14, 4, 12, 32,161,203,245,238,122,148,157, 33,115, 14,158,135, - 97, 61, 92,240, 91,184,146,226,193,234, 67,117, 22,130, 59, 75,225,173, 59,221,117, 5,237,113,124,166, 80,160, 92,251, 34,163, - 4,172, 94,115,174, 14,219, 93, 88,170,185, 1, 38,253,178, 21,180, 45,115, 57,128,196,168, 22,156,140,210, 28, 8, 30, 63,112, - 66,199, 18,142,195, 57, 95,108, 45,170,239,124,252,190,173, 85, 31,140, 34, 56,145,113, 26, 39,105,210,207, 84, 90,128,122, 58, -136,245, 62, 31,124, 81, 65,139,115,209,242, 27, 48, 43,142, 86,144, 14,227,129, 2,242, 92,168,189, 59, 78,250,111,119,183,119, -146,227,216, 26, 69, 50,139, 45,245, 44, 31,166,214, 40,195,247,208, 82, 11,102,241, 0, 82,159, 17,234,176, 26,113, 92,221,177, -132,146, 78,126,158,101,189,193, 32, 27,143, 85,152, 23,148, 46,249,117,105,166, 41,209, 12, 13, 77,205,136,205,195, 0, 42, 48, -189,253,163,252, 4, 38,213, 7,214,121, 64,157,246, 4, 26,197,242, 56,246,169,120,182,249,244,253,167,119,203,141,181, 55, 31, - 94,223,126,116, 79,172,240, 62,235, 63,127,245,114,243,241,147, 27, 27, 93,117,222, 47,182,182,234, 85,239,119,255,200,116,176, - 12, 88, 37,184, 13, 5, 12, 99,195,223,165,168, 56, 85, 68,173, 68,115,100, 11, 67,107,209, 35,159,185,174,170,228,210, 80,193, -116,138, 50, 5,239,134,244,162,199,248,180, 12,248, 69, 28, 47,141,210, 0, 90, 68,252, 58, 59, 84,167,113,189,179, 76,136,117, - 1,118,227,216,176,195,170, 10,149,143, 39,168,134,143,118,128, 82,215,229, 33,201,206,107,149, 6,148, 51, 11, 67, 36,221,239, -237,202, 18,188, 23,211, 99,153,119, 65,244, 29, 15,222,111,198, 78,212,184,150, 35,160,203, 49,138,170, 87,156, 69,216, 57,159, -181, 12, 75,205,167,146,126, 62,153, 62,220,229, 28, 75, 77, 78, 5, 96,254, 10, 64,216,185,245, 52, 17, 68,113,124,103,187,219, -217, 75,233,133,109,161,128, 33, 24, 1,225, 65, 69, 19,149, 68, 31,252, 0,198,248,137,124, 49,126, 6,159,253, 2, 62,249,102, -252, 2,146, 64, 64,193,128,165,133,162,216,218, 45,183,109,187,221,219,140,115,102,118, 75, 11,137,164,111,125,106,103,207,158, -219,156,243,255,221,112,191, 42,143,234, 0,163, 24,123, 45, 37, 99,145, 50,150,245, 18, 46, 78,103,102, 60, 18,116, 65, 36, 83, -214, 72,218,144, 53, 83,205, 26,204,224,128,237, 29, 34, 20,104, 40, 61, 99, 78,143,227,226,193,249, 79,135,246,212, 8,152, 22, - 68,134, 61,180,128, 15,235,177,195, 85, 96,107, 84, 78,234, 24,168,214,129, 77, 14,138,210, 32,144, 14, 20, 10,216,142, 17, 44, - 62, 8, 0, 33, 40,208,166, 13,149,133, 10,181, 27,116,107,157, 35, 63,236, 83, 78,113,138, 72, 96,229,203,127, 78,127, 67, 75, - 67,204,103, 72,177,106,155,128,201, 5, 65,128,110,158,135,252,207, 36, 17,205,107,227,110,224,250, 81,255,186,139,119,184, 70, -241, 32, 26,168, 41,204, 75,182, 72,166,116, 88, 56,243, 42,230, 80,196, 99, 30,155,153, 31,217, 57,218,140,175,213, 99,253, 10, - 34, 18, 97, 41, 22,174,148, 35,102,107, 0,149,133, 30, 14, 59, 23, 16,125, 68, 48, 88, 20, 6, 44,138,234,219, 59, 63, 88,141, -215,180, 91,223,107, 77,204, 51, 11,143, 80,150, 99,247,227, 85, 38,169, 3, 7, 75, 20,169,175,227,126,222,132,254, 74,232,103, - 72, 84, 80,144,134, 88,184, 69, 26,139,169, 93,210,135, 74, 12, 0,136,116, 32,172, 74, 96,189,192,161, 60, 35,134, 27, 69, 94, -188, 11, 34, 55, 95,194, 19,246,202,147, 50,167,161,200,170,200,166, 12,172, 49, 87, 53, 63,181, 88,105,236,113,116, 43,236, 7, - 48, 95,201,188, 60, 16, 79, 40,177, 50, 48, 36,231, 71,158,227,158, 74, 98,221, 73,220, 88, 39, 39, 69, 57,236,155,242,218,104, -239,120,119, 96,244,115,197, 57,187,123,210, 77, 72, 8, 40, 57,195, 98,110,162,125,222, 18,196, 84,167,231, 68, 81,128, 6, 37, - 18,149, 92,226,246,206, 92, 19,155, 42, 64, 39,220,181,234, 90, 58,165, 90,217,146,101,150,182,234,235,130,100, 45, 46, 48,107, -141, 42, 59,124,215,235,217, 23, 45, 4,215,248, 6,236,184, 99,204, 82,242,114,161,108, 59, 54,212, 40,220, 94,217, 31,233, 5, -110,165,185,203, 2,249,234,226,234,254,113,229,151,125, 40,226,202, 45,107,182,113,222,240,189,126,138, 75, 66, 83,206,176,101, - 79,124,229,246,189,141,131,173,147, 78, 91, 72,173,101,245, 28,123,165,173,177,226, 5,123,177,225,230, 25, 25,186, 49,149,157, -100,143,245,176, 89, 23,228,222,156,153,191,232, 57, 88,209,125,152, 88,247,244,148, 50, 57, 86,250, 92,251,186,214,174, 92,179, -213,212,208, 96, 23,138,251, 49,146,224, 5,197, 27,167,193,232, 8, 6,159,101,136, 20,137,180,221,142,166, 40, 22,136, 68,163, - 7,133, 98, 29,116,152, 17,151,130, 8, 89, 44,193, 74,154,197,254,217,217,153,250,102,245,209,202,125, 63, 37,187,127,237,187, -185,133,249,133, 59, 62,150,202, 82,105,125,111,123,107,227,219,199,245, 79,111,222,191,101,238,207, 66, 19, 99,216, 90, 90, 94, -126,242,252,241,210,195,197, 87,175, 95,190,120,250, 76,202, 72,205,205,230,151,119, 31, 42,103, 7, 10, 31,100,135,174, 11,124, - 66,222,124,138,124,232,118, 65, 60,117, 89,217,197,123,155, 56,109,244,196,182, 26,141, 21,195, 97, 10,150, 7, 41, 51,109,250, - 33, 32,238,146,212, 74,128,181,227, 38,134,192,146, 20,244,130,221,105,211,161,188, 42,238, 4, 74,137,182, 55,183,242,106,115, - 31, 10, 77, 52,186,154,206,126, 8,176,114, 73,188, 52,194,227,182,134,181,174,215, 33,252,229,180, 59, 45,222, 49,139, 17,174, - 34,147, 79,132,204, 57,224, 80,112,232, 46,137,128, 8,230,128, 70,156,140,144,243,144, 7,170, 88,220, 84,120, 27, 98,184,189, - 32,198,128, 46,203,145, 43,144,170,129,180, 23,124,253, 79, 0,186,174,100,183,105, 32, 12,207,120, 79,236, 56,141, 67,105, 27, - 53,168, 66,138, 84, 33, 42, 78,112,224, 1,122,231,204,137,247,224,194, 43,240, 22,220,184,192, 17, 9,169,112, 64, 72,112,105, - 43, 33, 84, 82, 90,209, 84,105,130,155,216,177, 29, 47,195,252,255,216,142,211,208, 91,148, 40,113,188,204,252,219,183, 44,248, -171,255,237,196, 47, 27,239, 65,109, 39,231,147, 85, 84,128, 1,107,236,134, 93,115, 44,181, 57,139,125, 47,118,249, 46,175, 17, - 89,151,116, 67,209, 85, 5,146,116, 71,183, 52,205,192,236,155,134, 73,166, 0, 16,120, 62,156, 13,231, 89,112, 61,231,229,112, - 44, 21,211,121,184,189, 36, 45,180,192,196, 56, 65,172, 49,168,244,192,189, 1, 60,200,116, 13,144,239,138,198,119,120,120, 63, - 29,207, 39,243,116, 70,208, 90, 2, 25,148, 34, 7,137, 83,148,192, 45,200,243,108,181,233,206,150,176,146,116, 5,107,148,159, -125,117, 70,145, 45,208, 50, 66,233,129,221, 18, 36,228,197,196,117,113, 32, 73, 90, 9, 25,180, 34,191,198, 72,178,115,167,215, - 31,157, 20,135,195, 60, 23,100, 89,176, 21, 6, 83,108, 80,153,209, 97, 58, 77, 55, 58, 14,200,254,202, 84, 85,129,254,165, 40, -116, 30,131, 65,145,201,148,200, 79,236,154, 86,203,210, 6,203,222,126, 61, 86, 10, 28, 85,138,255, 63,174, 16,181,228,202,139, - 4,219, 29,186, 74, 76,149, 56, 90,219,150,183,187,230,174, 47, 69,191,220, 35, 47,116,145,106,150, 21,181, 8,102, 35,128, 4, -130,164,200, 54, 29, 94, 66,250,225, 12,117,113, 4, 85, 9, 90,201,155,173,173,179,209,111, 65,187,167,185,100, 19,172,203,186, -209,104,153,173, 32,242,175,131, 9,255,108,115,109,235,210,189,192,141, 11,246, 71, 67, 49, 64, 3,178,100, 69,231, 16, 38, 88, -252,150,110,133, 73,136,152,198,210,179, 6,211, 49,138,109,187,156, 39, 69,240,130, 65,140,209, 20, 3,132,186,160,117,139, 1, - 5,105,201,237,186,227,130, 5, 35,146, 51, 42,246,109,194,192,139,159,161,109, 53,199,211,145,208, 12, 42,101,107, 48,114,178, -194, 56, 29,178, 28,219,108, 78,130,137, 44,218,113, 84,218, 89,191,223, 31,158,200, 8, 26,227,153, 53,191, 4, 29,167, 59,158, - 94,249, 81, 14,241,228,135,217,127,180,127,112,124,192,127,141,127,215,157,140,227, 52,126,216,221, 59, 60, 63,148, 80,189, 18, -159, 36,214,219,232,157,143,206, 96,176,156,132,173,250, 26,143,136, 25, 21,100,106,160,237,160,139, 34,132, 85,129, 39,229,133, -137, 46, 41, 87,147,191,239, 7,223,138,167, 46, 37,139, 87, 43, 80, 11,184,211, 26, 96,127,153, 84,180,124, 83,188,243,113,153, - 32, 86,225,235, 38,145,214,116,163,107, 53,119,157,245,143,195,139, 51,111,154,128, 77, 49, 91,145,233, 96,238,233,240,233,131, -199, 71,126,255,243,155,119, 31, 62,125,121,249,250,213,205, 5, 49, 35, 63,190,255, 60,253,115,202, 31, 97, 99, 80,115, 7,110, -114, 55,118, 58,237, 39,219,123, 47,158, 63,187, 98, 30, 47, 79,163, 56,106,168,246,229,116,128, 30,172,177, 44,235, 81, 6,246, - 12, 8,138,207,176, 27,153,116,218,247,206, 1, 59, 75, 74, 78, 17,203, 81, 39, 2,126,205, 36, 74, 87,233,139,164,220,116,137, - 32,158, 80, 86,194,105,150, 25,246,101,223,142, 84, 4, 19,151,101,101, 51,171,222,244, 2, 15, 13,165, 0,135, 47,248,229, 98, -183, 18, 74,197, 2,175,116,195,116,163, 0,164,195, 2, 50, 84,147, 1, 95, 41,188, 37,169,132, 88,211,168, 89, 65, 20,128, 32, -102, 49, 47,204,114,248, 79, 42,128,120, 89, 30,153, 22,201,123,129,160, 41,217,154, 16, 1,255, 9,192,215,181,244, 52, 17,133, -209,219,185, 51,183, 51,125, 17, 4, 75,136, 9,109,116, 67,194,142,173, 91, 98, 98,252, 19, 44,140, 11,119,110,140,127,193,133, -104, 26,140,137,143,224, 74, 97,171,127, 66,183,136,184, 33, 85,144, 20,104, 59,165,244, 53,109,231,229,247,125,119,230, 50, 20, -100,215, 69,155,102,230,206,156,239,121,206,185, 14,223, 19,183, 73,233,250,114, 57,237,228, 56,209,212, 76,200,245,136,107, 46, - 49,148,132,162, 33, 43,212, 77,205,204, 25, 25, 72, 49,242, 70, 46, 45, 44, 75, 55, 77,221,194, 62,126,224,121,216, 15,247,161, -242,202,234, 6,252,164, 53,234, 56, 94, 23, 98,131,227, 57, 3,183, 71,246,230,100,164,129,100,181, 8, 81,177, 80, 8,137, 21, -207,208,126,113, 97,174,116, 64,204,227, 20,229,125, 4, 53,148, 9, 10,225,224,100,207,165,242,204,163,102, 34, 83,224,158,140, -112,225, 5,181,158,255,225,123,106,194, 43,252,210,226,252, 53,140,168, 40, 48,240, 9,139,214,232,175, 89,164,153,200,148,181, - 34, 2,150, 41,178,144, 78,182,122,245, 88,181, 24,129, 61, 96,158, 68, 46, 64,117,142,195, 58,158, 22, 40, 60, 80,152,205,251, - 92, 55,160,126, 65,233, 29, 72,182, 53,199,115, 29,215,207, 5,122, 14,105,221,126,105, 42,251,125,239,224,219,159,147, 76,220, -161,243,227, 37, 78,249,222, 27,244,102, 75, 8,163,151,158, 41,251,212, 44,199,185,118, 65,160, 76,108,232,139, 52, 79,251, 76, - 27, 32,205, 37,178, 56,137,237, 17,144, 65,134,193,131,172,226,105, 48,140,143,184,224, 22,156,166,244, 38, 40, 21,239, 28,159, -214,176,118,161,218, 56,150,221,150,131, 84,110, 25, 98,136, 74,135,225,121,174,164,105,116,242, 42,159,144, 13, 16,100,132, 45, - 20,203,251,245,223,144,254,226,151, 34, 26, 95, 42,149, 48,210,140, 59,234, 72,242,227, 90,180,194, 43, 12, 1, 25,247,217,160, -205,137, 85,102,144,253,136,210,133,150, 38,112,195,241, 0, 42,195,209,120,132,122,244,102, 86,154,104, 23, 11,115,141,110, 61, -150, 98,101, 58, 23, 83,217,130,221,179,105, 99, 63,138, 37,114,171, 7, 82, 13, 40, 83, 80,110,158, 58,212,202,165, 13, 66, 87, -163,115, 82,190, 89,254,219, 60, 4, 52,135,179, 3, 56,192,117, 50,120,242,209,245,109, 22, 2, 64, 24,250, 28, 93,174,104,204, - 18, 70, 23, 14,215, 55, 63, 61,127,100,215, 72,163, 74, 42, 58,104, 51,249,105,187,111,235, 76,202, 29,226,244, 73,195,234,205, -173,186,157,245,103,111,107,131,102,181, 86,189,127,119,229,195,151,141,202,167,151, 9,172,222, 96,139,171,172,121,200,154, 80, -241,236, 51, 6, 57,254, 14, 99,191, 24, 59,102,172,151, 64,183, 52,129,190,203, 18,242, 97,231, 54,126, 86, 1,110,232,153,235, -142, 70,253,215, 79,158, 63, 94,123,202, 26,142, 99,183,225,106,237,214,169, 27, 4,159, 55,183, 94,172, 87,118,127,108, 63, 92, -125,116,100, 55, 55,223,191,187,183,242,160,242,106,109,113,121,233,246,242, 82,208,238,107,183,242,242, 60,107, 63,107, 59,123, -187,253,225,112,176,221,133,248, 36, 58,238,199,175,111,198, 80,204,120,168,175, 9,183, 0, 55,166,176,223,225, 81, 77, 31,107, - 3, 72,165, 35,185,189,136,213,164,172, 35, 99, 53,141,104,232, 40, 29,152,162, 15, 60,193, 0, 10,175,216, 37,148,154, 75,151, -244, 90, 66, 45, 22, 35, 11,175,170,227,229,154, 77,188,228, 24, 89, 3, 50,149,182, 43,100,151, 44,164, 32,161,211, 18,198,139, -186, 55, 50, 51, 72,106, 11,189,148, 84,124,189, 96,187,167,246,184,112, 44, 79,157,153, 64, 6, 44, 41,152,166, 84, 13, 84,168, - 8,148,102,252, 36,115, 53, 69, 28, 29,246, 79, 0,194,174, 29,182,137, 32,136,238,222,207,118,236, 32, 39,113,164, 40, 63,133, - 52, 40, 18, 13, 40, 66, 52, 17, 10, 66,136, 2, 81, 81, 35,122, 4,164,164,160,160,161,162, 0, 41, 5, 5, 61, 5, 5, 20,208, - 19, 20, 66,151, 10, 68, 67, 67, 76,226,252,176,227,207,217,190,187,245,238, 50, 59,187,123,118, 12, 18,246, 73,150, 44,203,247, -217,187,153, 55, 51,111,222,120,255,101, 70, 74, 59,145,218,180,162, 96,138,198,162, 78, 21,157,219,185,119,210,181, 6, 66,141, -129, 19,137, 47,124,136, 31,123, 76, 53,226,199, 92,116, 57,135,200, 46, 75,131,196, 77,192,249,197,138, 15,199,193, 19,128,237, -159,202, 77,194,217, 53, 88,164, 24,205,172, 30,241, 40,166, 29,236,148,119, 77,175,130,237, 65,117,125,126, 80,219, 67, 70,170, -242, 96, 28,125, 39,147, 74, 7, 60, 78, 18, 97, 84, 34,184, 48,158, 93,232,188,232, 64,192, 34,254,174, 50,208, 62, 18, 79,161, -173, 35, 45, 1,127, 8,236, 83, 98,221,142, 49,137,255, 44,158, 72,103, 72, 97, 50, 5,130,132,204, 20,231,142,154,251, 58,253, -170,136, 5, 65, 14, 46, 87,134, 6, 81,210,142,149, 2,154,193,244,170,101, 41, 87,104,130, 97,178, 10, 66, 88,162,196, 28,141, -148,190,154,243,231, 49,148, 59, 2,187,207,152,236, 70,162, 19,241,209, 17,103, 34,155, 25,203,101,191, 84, 42, 74, 16, 27,227, -112,119, 64,153, 33, 77,210, 37,182,189, 77, 34,126,227,182,210,155, 69,207,229,217, 74,156,112,146, 46, 77, 50,174, 51,161,172, - 62,137,185, 27,208, 32,236,210, 24,201, 90,190,171, 82, 52, 68,177,126, 76, 7,151, 82,143, 51, 53,112,176,251, 78,173, 89,237, -113,166,169,180, 0,108,225,150, 5,195,148, 13,212, 92, 39,156,175,237, 82, 67, 81, 79,217,255,210, 25, 32, 50,251,110, 0,123, -197, 70,127,121, 80,175, 96, 98, 42,157,159,216,199, 73,122,162, 44,183,107, 52, 51, 54, 29,198,237, 48, 14,225,239,206,140, 20, -213, 84, 13, 91,225, 80,196,252, 84, 89, 3, 87, 19,108,110, 12, 71,136,178,101, 61,222,107,118, 26,205,168, 5, 33,120,204, 34, - 8, 40,139,249, 98, 39, 9,153,226, 25,178, 70,187, 14,159,227,163,227, 77, 8,201,213, 33, 41,206,214, 66,105,161, 92, 43,195, - 29,168,102, 39,226,140, 19,227,200, 5,169,156,236,251,158,251,187, 85, 75, 0,124, 96,177, 78, 79,134, 17, 0,220, 36, 61,170, - 31, 98,165, 26, 41,206,234, 14,119, 32,118,241,125,191, 19,181,225,196, 14, 27,135,165,226,100,193,203,237,158, 84,116, 25, 24, -194, 5,116,163,154,211, 65,116,231, 72, 36,249,205, 75,183, 86,214,174, 74,213, 18, 68, 30,173,147, 55, 47, 94, 47,158, 93, 95, -123,122, 31, 61,120, 76, 46,223, 37,175, 8,201,204, 18, 54, 75, 26,132,212,208,194,255,196,173, 12,219, 14,169,126, 37,114,139, -136,103,136,248,115,196,212, 98, 81,121,198,245, 98,149, 42,129, 69, 79,192, 47,234,203,254,237,199,119, 82,105,236,237,252,154, - 89, 90, 32,197,194, 52,153,130, 47,111, 84, 87,120, 24,110,111,126, 90, 93, 94, 30,159, 44, 46, 94, 60,127,251,193,157, 11, 87, -150, 51, 94,230,229,147,231, 91,155,219,247, 30, 63, 44, 87,118,151,230,207,205, 79,207, 93, 95,189, 70, 90,100,131,125,126,251, -254,221,199,141, 15,115, 99,165, 30,235,101,188,108, 35,106,233,241,166, 92,191, 41,210,204,169,126,198, 52, 28, 50,157, 53,136, -216,133,150,181,112, 81,242,212,146, 71, 76,239,157,153,174, 33, 77,229,210, 25,120,176, 69,202,104,163,131,214,112,192, 42,246, -205,228, 41,205,174, 52,178,193, 74, 80, 10, 25,105, 62,200, 3,172, 68, 17,114, 43,245,142,252,124,218, 87,106,239,155, 30,248, -201,113, 88,213,200,128,158,230,174, 59, 92,207, 48,213,109, 13, 18,158,145, 66, 80,170,181,143, 19,193,134, 98,126, 21,106, 34, -194,128, 5, 27,205,230,155, 74,177,117,184, 64,152,190,254, 8,192,216,181,235, 56, 13, 68,209,241,216,142, 95, 9,155, 21, 65, - 74, 4,226, 81, 32, 88, 10, 42, 10, 68, 69, 15,162,129,150,138, 79,160,164, 4, 33, 42,168,144,248, 6,126, 1, 9, 81, 65,177, - 43, 10,164,149, 22,216, 37,130,108, 36,164, 93, 32, 15,109, 28, 39, 99, 15,247,220,241,100, 13, 10,143, 20, 86,138, 56,137,157, -155,153,115, 31,231,156, 63,226,119,183,194, 20, 88,152,114, 24,194,162,203,167, 56,240,124, 14, 52,219,238,114,143, 75,153, 39, - 62, 43, 10, 4, 50,136,253, 56,244,104, 21,138,235, 94, 2,233, 21, 12,194, 65, 78, 0, 14,118, 82, 68, 30, 58,116,147, 60, 43, -208, 45,116, 14,102,233, 28,122,200,176, 8,165,192,165,133,126,172,198, 5,247, 68,141,163, 57,215,100,121, 2, 21, 87,167,176, - 57,176,189, 3,172,233,116, 9, 37,153, 50,204,254,183,165, 34,179, 46, 14,141,188,139,191, 80,184,116,133,218, 43,150,173,236, -116, 92,141,142,130, 7,241,203, 41,191,147,165,164, 88, 42,198, 92,110,222,132,212,148,163,172, 21,139, 25,126, 98, 9,154, 2, - 71,140, 40, 56,101,219, 72,114,227,223,101,228,202, 22,126, 16,118, 15, 60, 13, 53, 74,151,226,219, 95, 59,219, 46,226, 40,163, -187,133,145,108, 61, 87,122,146, 21,147, 84,117,146, 96,173,222,120,241,233,243,120,174, 78,120, 65,191,191, 11,213, 67,198, 66, -116, 91,211, 74,161,198,100,230,139,210,172,172,148,107, 98, 83,184,117,216, 63, 89,138, 49, 35,129,186, 15,221,155,154, 43,147, - 64, 30,107,200,154,215,217,236, 13, 10,171,200,154,179,197, 7, 74, 99,166,116,200,146, 30, 20,235, 4, 87, 67, 63, 84,180,198, - 19,106,150,172, 0,236, 56,148, 96,240,212, 78,110,186, 34,142, 29,129, 41, 12,142,213,165,190, 39,255,131,160, 60,193,157, 24, -165,173,175,165,100, 62, 47,189, 46,170, 37,245,176,145,205,210,209,116,100,140, 46, 91,141,214, 30,108, 48,173,151, 60, 4,241, - 33,200,101,185,177, 8, 36,147,201,139, 82,183, 85,235,101,110, 98,204, 96, 66,197,213,119,131, 56,136,211,108, 58, 87, 83, 32, - 10,237,212,188,144, 71,245, 41, 53, 57,213,251,214, 51, 13, 18,171, 24,110,102, 71, 17,125,148, 89,213, 67,108,207, 14, 44, 36, -115,163, 96, 69, 31,140,166,168,235,179,204, 36, 79, 71,129, 15, 5, 89, 0,152, 53,242, 48, 26,104,100, 28, 33, 81,152,208,213, -166,115,246,245, 5, 41,172, 1,146,151,116,173, 79, 40, 0,255,185,211, 23, 94,246,223,173,239,108, 84,163,237,203,171,238,201, -171,103,248,233, 17,113,109, 40,158, 90,164,190,194,187,183,131,202, 11,126,239,125, 33, 40,156,105,113,120, 46,196,147,187, 66, - 60, 6,243, 68,155, 26, 30, 30,161,244, 40,251,222, 79, 39, 1,101,219, 81,156, 82,252,100, 7,119,110,220,190,255,236,209,248, -199, 48,159, 21,205, 90, 4,126,111, 28, 53, 87,155,223,187,187, 23, 47, 95,121,179,254,250,120,187,163, 92, 49, 87,138,224,254, - 72,101, 15,239, 61,216,122,251,241,214,245,155,155, 31,182,222,119,183,183,191,238,244,247,186, 11, 96,116,169,125,126, 37,105, - 76,178,180, 25,172, 12, 38, 67,218,146,145,224, 11,101, 18, 65, 90, 14, 86,147,214, 96, 58, 50, 42, 19, 96,218,224,232, 86,144, -152,102,207, 24,101, 29,250,138, 74, 63, 85,148, 54,212, 86, 1,111,177, 64, 35,194, 88,222,192, 10, 75,230,149,153,150,255,208, -202,183,111,173,173, 39, 28,127, 9,109,180, 2, 13,202,174, 14,234,252,171,159, 87, 81,214, 53, 33,105,141, 63, 3, 55,202, 25, -185, 90,133, 59, 51,219,122,232,238, 7, 47, 67,233,129, 30, 81,169, 2, 47,144,168,169,207,252, 20,128,175,171,215,109, 34, 8, -194,187,123,183,190, 59, 59,142, 67,108, 67, 10, 66,148,136,164,161, 64,188, 0,143,192, 11,240, 22,148, 20, 20, 20,148,212, 52, - 52, 20, 60, 0, 84, 80, 33, 65, 79, 17, 33, 37, 10, 34, 9, 17, 86,112,126,128,216, 57,123,111,111,111,153,153,221,117, 44,217, -138,101, 89,246,234,206,119,167,217,157,153,157,249,230,155,152, 93, 23,118,159, 56,239,254,211,117,131, 10, 16,154, 40,212, 74, -217,144,177,117, 10,143,176, 86,132, 21,225, 37,200,164, 84,162, 16, 85, 84, 19,200,227,138, 45,227,104, 42,151, 70,101,181,122, -198, 83,228, 49, 68,102, 6,112,232,244,101, 49,204, 11,164, 15, 28,153, 17,174, 34, 18, 26,108,227,186,245,118, 34,107, 3, 61, -168,225,223,192,241, 22,171,247, 49,148,239, 26,145, 27,235, 41,248,173, 15, 29, 48,207,152, 53,181,110,249,245,137,212,104,134, - 92, 51,104,118,214, 74, 91, 23,227,127, 65,185, 79,186, 80,177,104,198, 90,206, 43, 46,179, 19,255,180,100, 37,220,171,140,147, -245,155,155,187,189,237, 80, 78,224,220, 55, 35, 38,180, 15,204,222,238,172,255, 58,251, 33,137, 50, 23,156,202,200, 86,157, 68, -140, 64,156,134, 55, 98,145, 38, 38, 46, 47, 65, 15, 15, 20,236,103, 75, 95, 58,141, 80,110,190,154, 53,190,236,247,246,207,135, -224,194, 39, 77,254, 96, 99,177, 80,216,105, 15,153, 38,181, 81,154,172, 98, 89,141,180,205, 13,230, 90,243, 16,124,215,129,141, - 8,190,255,165,136,141, 68, 50,122,180,228, 77,201, 64, 60,170,196,250,190, 68,162,155,126,116,110,215,187,199, 27, 93,249, 29, -155,237, 32,162,134,246,169,200, 85, 47, 92,173, 8,197, 95, 4,197,226,137, 11,144,114,241,150,165, 50, 3,103, 86,161,194,197, - 88,181, 20,241,106,103,245,240,244, 0, 78,110, 55,150, 79,135, 39,160, 79,101, 20, 99, 35, 74,202,119,193, 65,237, 70,251,247, -176,207,201, 4, 58,153, 84, 46, 29,195,108, 62,198,217,178, 84, 95,202,100,134, 52,100, 8, 56, 25, 58, 62, 97,183,138,155,105, - 75, 97,239,145, 64, 53,201, 28,185,171, 93,235,172, 33,118,141,134,107, 34,166,240,110, 53,205, 54,225,249, 52,184, 24, 87,133, -206, 11, 39,169,110,235, 86, 67, 54, 14, 79, 14,168,135, 56,219,239, 31, 10,170,248,119,213, 44, 20,165, 55,174,212, 5,129,140, - 90, 41, 93, 56,160,168,240,237,216,240,122, 35,149,231, 84,206,158,197,217,221,149,205,111, 63,183, 23,147, 58, 50, 49, 8, 10, -230, 50,222, 93, 88,134,135,186,211, 89,219, 59,222,131,217, 1,115, 47, 73,146, 63,131, 51,227, 97,211, 54,160, 39,162, 81,165, -106,150,237, 30,237,120,102,220,112,239, 31,190,126,124,254,228,197,179,151, 79, 25,235,178, 54, 99, 77, 18,243, 5, 99,155, 36, - 87, 19,126,246,200,146,131, 33,216,130,147, 86, 60,227, 0,215, 20,165,193,215,184, 42, 83, 24, 17, 17,149,143,144,225, 17,241, -235,119,111,224, 45,105,194, 60,126,248,168,217, 90,120,245,254,237, 34, 75, 96, 49, 94,216,124,235,254,189, 98, 30, 19,237,231, -157, 79,179,131, 32,232,246,194, 13,216,105,105,173,251, 69, 31,185,170, 81,197,152,122, 84, 87, 48, 85, 13,184,125, 18, 91, 53, - 9,106, 56, 18, 81, 19,152, 56, 70,139, 47, 66, 61, 59,102,219, 65,243,104,244,238,132, 38,120,191, 33,112, 53,207,210, 52, 87, - 3,206, 38,219,114, 59,191, 83,155,243, 34, 60, 28,197, 4,155,192,175,163,160,242, 89,168, 64, 19,198,188,135,226, 3,228, 1, -235,200,167, 1, 65, 87,196,142,115,148, 4, 65,247,132,211,174,240, 4, 17, 93, 31, 73, 52, 43, 53, 29,195,183,158, 13,219, 49, -202,147, 11,143,219, 65,195,175,152, 92, 29,184,209,231, 87,105,193,153,255, 2,240,117, 53,189, 77, 3, 65,116,119,189,235, 56, -113, 74, 62, 26, 65,219, 11, 82, 1, 9,206, 28, 56,243,243,144, 16,127,129, 27,127,168, 23, 40, 18, 31, 85,211,202,137, 83,183, -177,157,216,177,119,151,153,217,216,109, 34, 90, 41,183, 68,142,188, 31,111,223,204,190,121, 35,159, 0,247,182,107,182,216, 62, -154, 18,129,204, 37, 12,208, 13, 70, 52, 7,177,187,201, 20,174, 53, 45, 98, 4, 38, 6, 56,154, 57,139,218, 2,182,168, 74,215, -146, 99, 63,184, 14, 87, 48,166,119,171, 5,108, 72, 29, 12,200, 28, 85,146,151,140,116,122,117, 18,231,107, 13, 40, 0,123,129, - 1, 21,224, 67,222, 61, 9,143, 39,253,241, 52,187,158,175,103,138, 75,236,198,105, 96, 62, 75,109, 60,202,237,218,193,193, 36, - 45,150,212,255,204,180,221, 7,237,206,196,218,189,102, 35,251,158,154,255,155, 84,223, 11, 56, 30, 60,155, 7,246,161,156,237, - 36,214,158, 56, 51, 90, 83,225,251,171,239,103,221,113,178,142,191, 95,157,181,238, 11, 15, 34, 36,214,212,145,217, 56,185,132, -201, 89,193,209,104,109,159,102,228,119,134,213,137, 93, 97,147,181,145, 94, 29,229,241,199, 15,199, 54,196, 78, 79,204,211, 36, -159, 23,188, 20, 23,139,228, 44,158, 5, 82, 5, 74,172,138, 18,139, 22, 13,223,160,170, 29,251,104,247, 20, 64, 8, 74, 5,138, -138,109, 42, 93,104,188, 15, 41, 53, 91, 35,101,194,140,141,223, 84,112, 5, 13,157, 23,180,244, 36, 9,111,106,205,209, 19, 14, -155,113,242, 60, 99,175, 94,112,169,194,159, 81,129,192, 78, 29, 60, 48, 8,240, 59, 61,127,144,100, 49,173, 58,132,121,224,238, -200,111,209, 35,194,137,255,244,168, 55, 56, 26,158,252,138,206,225,255, 47,226,191,110,172,136,250, 19, 45, 96,117, 59, 27,240, -131,104, 25, 49,215,251,111, 27, 83,243,131,238, 8, 48, 29,104,251, 44, 69,220, 95,228,139, 64,118,169, 12, 80,224, 5,172,107, -109,195,209,160, 24, 16, 19,224,217,247, 58, 97, 16,222,230,137, 83,236,143,123,147,139,248,143,181,174, 12, 29, 8, 18,119, 23, - 72,173,123,199,214, 9,132,146, 39,206,149,145, 78, 96,115,125, 27,145, 49, 36,198, 15,192, 50,164, 84,101,185, 86, 42, 40,171, -181,161,125, 23,248, 93,120, 67, 64,118, 18,237, 49,222, 48, 70, 20,161, 11,138, 75, 4, 79,203,220,163,103,231, 69,126,126,245, - 3, 56, 62,121, 8,147,208,158,194,137,121,118, 3,124,112,154, 92, 34,179,193,106,166, 20, 77,101,129,130,111,210,109,177,110, -211, 88, 18,198,252,229,112,114, 50, 24, 47,231,153, 47, 85,141, 85,151,104, 79,117, 53,157,158,158,190,113,133,216, 0,188,248, - 25, 51,246,174,185, 51,218, 16,226,195,103, 65,115,236, 17,220, 55, 89,144, 61,239, 14,120,211,215,135,207,103,119,137, 59,192, -128, 99,105,163,134, 29, 31,182,237,242, 38,249,252,229,211,209,251,183, 95,249,183,254,104,104,224, 11,219,169,106,237, 91,159, -236, 84,201, 42, 65,215,143,249, 56,161, 86, 85,246, 22,233, 77, 90,172,250,157, 48,202,110, 11,106,153, 93,234, 10, 54,120, 97, -170, 18,109, 71, 49,102, 15,213,179, 97, 56,130, 21,141,171, 68,250, 2, 25,158,228,216,251,157, 52, 85,166,230, 90, 89,114,233, - 6,114,129, 75,176, 22,189, 0,157, 75,248, 70,108,157, 39,184, 59,100,205,110,190,196,237,123, 99, 27,158, 15,163,119,120,112, - 24,223,205,133, 16,108, 39,159,243,144,125,155, 54, 13,239, 50,101, 14,217,141,171,145,218,138, 94, 88, 35, 15,225,251, 74, 10, -187,195, 33,154, 74, 17,183,192,141, 67,121, 56, 77, 41, 70,123, 76,187,113, 79, 42, 27,197, 60, 5,226, 24,238, 99,248,168, 91, -125, 14, 1,253, 63, 1,248, 58,183,221,166,129, 32, 12,251,136, 93,187,164,117,105, 67, 43, 36, 42, 46,144, 16, 55, 84,189, 2, -137,151, 65,125, 30,174,184,229,105,184, 45, 15,128, 4, 8, 21,165, 74, 75, 91, 39, 78,136,215,235,236,129,153, 89,175, 15, 13, - 16, 89,185,201, 65,150,189,158,157,253,119,230,251,131,127, 7,247,110,115,181,101,187, 27,241,157,228, 84, 66, 32,145, 0, 78, -242, 46,206, 21,173,174,175,140,131,148, 54,172, 71,220, 15,140,224,157, 44, 48,203,186,204,171,188,228, 72,106, 46,234, 5, 85, -190,163,119, 56, 85,136,192,212, 28,166, 15, 82, 88,191,103,241, 8, 27,130, 2,200, 94, 30,238, 39, 89, 18,198,107,165,198,241, -227,216, 75,174,216, 20, 30,162,144,156, 63, 32,197,132,185, 29,198,117,142, 9,142, 41,141, 50,128,181,205,120,237,221,115, 10, -236,135,117, 11, 97,234,255,202, 8,193,184, 56,226, 24, 53,250,255,230,185,131,223,246, 63,235,255,121, 83, 41, 31,208,242, 93, - 18,136,102,201,102,132,115,104,245, 95,213, 82, 68, 58,216, 27,202,220,213,146,162, 78, 98,215,214, 1, 93,231, 64, 97,120,133, -209,155,186,242,234,226,251,209,254,225,193,163,189, 91, 94, 75,161, 18,207,255,116,113,249,245, 46, 79, 2, 63,245,181, 91,253, -102,176, 42,162,166, 20,114, 35, 86, 1,109,224, 68, 40,248,232, 16, 46, 93, 20, 86,144, 33, 72,103,197,229, 54, 54,163,171,165, -162,155,103,250,173,236, 1,185,119, 73, 72,249, 45,204,159,144, 42,150, 66,200, 38, 50,106,197,213,211,140,255,248, 37, 20, 21, -151,248, 68, 90,149,162, 46,228, 77, 87,255, 66,145, 50,242,225,201,175, 73, 91,112,210,104,167, 96,115,134,253, 53,174,173,118, -192,161,141,125,100,164,230, 75, 41,108, 17,132, 99,116, 21,109, 83, 7,114,125, 81,197,106,110, 40,222, 16,115, 95, 63,127,115, -254,237, 92,202,182, 7, 77, 91,140, 19,220,181,154, 64,102, 46, 36,131,117, 89, 27, 59, 1,120,104,114,118,107,160,146,186,249, -166, 28, 84, 58,120,222,222, 86, 22, 71,241,228,110, 98,111,175, 74,163,148,218,214, 33,153,231, 84,164, 37, 97,160, 18,150, 49, -220, 73,119,167,121, 73, 6, 17,166,215, 6,207,147,252, 16,145, 89,100, 73,117,176, 22,117, 70,233,168, 40, 11,236,192, 68, 50, - 1,178,145,217,154, 35, 95,197, 35,222, 3, 86,142,153, 86,112, 13,179,241,138, 33,102, 89, 53,235,101,131, 93,106,104, 77,190, -149,110, 33,204,193, 73,190, 61,126,249,229,230, 39,162,247,252,166, 43,245,236,236,221,135,247, 31,141,196,226,108,147, 14, 15, - 99,104, 66,178, 12,156, 77,235,182,244,130, 86,106, 48,147, 51,199,250, 40,123,253, 62,144, 56, 12, 78,143,158,204, 42,180, 40, - 92,235,174,233, 78,144, 12, 2,139,209, 93,234, 84,227, 6,230,229, 32,216, 72, 25,163, 47,114, 31, 37,111,250,255,189,102,124, -241,249,122,241,183, 79,154,218, 77,215,143, 33, 9,153,215,115, 56, 14,178, 87,135,227,147,181,204,165,184,246,201,168,208, 15, - 35,136,105,232,217, 39,152,192,165,146,167,201,154, 67,106, 81, 66, 66,166, 24,206, 1,202,194,184,104,135,195,163,208,116, 79, - 48, 81, 86,196,193,161, 32,132,217, 51,183, 38, 74,142, 53,215, 83,125, 22, 97, 19,171,141, 35,171,106, 30, 97, 56,142,199,207, -166,249,101, 45,185,171,221,225,246,158,163,135,121,251,128, 45,217,213, 70, 54, 72,250,141, 16,239, 54, 33, 74,110,204, 11,221, - 78, 58, 66,192,176, 60, 65,202,222, 70,162,251, 71, 0,194,174,101,183,105, 32,138,206,195,246, 56,205, 67,128,132, 88, 0, 10, -170,132,232, 14,177,169,248, 13,216,241, 29,124, 69,249, 6,254,132, 21,251,178, 64, 98, 3,164, 72,105, 43, 65, 28,218, 82,227, -196,246,100, 60,195,220,123, 29,103,210, 32,200, 34,203,200, 73,198,215,231,158,123,238, 57, 17,219,192,198,173, 89, 51,223, 10, -184,104,163,147, 17,188,183, 37,222,215, 16,141,200,125, 45,182,119,120,147, 3,111,227, 65,158,111, 63,251,178,223, 79,246,148, -236,245, 35, 37, 32, 12,207, 63,207,139, 92,255, 6, 7, 65,223, 3, 90,160,162,181,135, 59, 43,248, 88,180,241,146, 74,198, 35, -217, 19,201, 80, 65,168,121, 47,137, 19,143, 43, 35,153,104,107,177, 63,147,189,120,248, 68,141,178,122, 54, 95,204, 98, 22, 59, - 65, 6,249, 30, 34, 10,215, 78, 48,204,206, 87, 97, 97,101,119, 91,142,248,124,205, 65,217, 0, 79,111,132,166,104, 2, 69,174, -179, 60,232,206,194,145,233,223, 20,143,161,182,157,188,160, 48,144, 75,116,202,152,205, 4,155,119, 62,156,172,157, 94,216,210, -217,148, 1, 87,174, 9, 90, 81, 51,139,205,244,157,152,221, 30,196,163, 84, 14,192, 28,221, 28,127,152,156,251,206, 52,138,174, -181, 94, 0, 79, 3, 88,205, 65,148, 43,228, 70, 25, 37, 93, 4,155, 18,181,245,109,147, 72, 37, 43,160,145,133, 74, 13, 62,156, -144,164, 8,190,224,154,201, 85,227,171,189, 76,208,137,186, 4,133,147,173,160, 79,100,123, 2,160,189,194, 7,154,241,141, 20, -238,151,233, 6, 40,248, 97, 34,141, 71, 76, 13,191,119, 43,250,113,109, 99,170,210,156,173,208, 5,198, 74, 52, 44,160,153,134, -100,160,192,193,196, 6, 96, 45,116, 69,174,220,219, 35,105, 87, 80,186, 86,183, 65,230,130, 31, 16, 41,121, 9, 34, 35,178,211, -164,179, 15,248,122, 50,155,144, 78,128, 5,109,172,104,119,172, 4,170,225,160,213, 29,168, 65,109,106, 68,247,187, 41, 92, 78, - 69, 10, 90, 52,186,149,173,187, 92, 92,142,123,227,224,137,141,131, 3, 0,224,218,241,118, 54, 91,154,178,130,157,117,247, 29, -247, 84, 45, 54,232,139,154,254, 46,174,141,233,110, 33,211,106, 93, 45,114,235,118,144,142,242,229,175, 52, 86,144,227,108,180, -182, 70, 52,162,145, 60, 1,255, 78,244,233,236,216, 86, 82, 65, 99, 96, 34, 17, 18,162, 11,132,167,240, 7,206, 78, 47,178,215, - 47, 95, 77,231,231,239,166,159,232,106, 15,247,159,222, 63,120,116,244,246, 8,155,177, 4, 14, 13,193,135, 37,190, 63, 91,127, -171, 51,198, 50, 36,103,192,131,134,181, 7, 13,236, 37, 54,199,121,148,164,159,127,102,121, 85,170, 88, 25,204, 40, 2,124, 8, -114, 45,137, 26, 39,155, 62,222,159,190, 63, 38, 87, 39,114,161,199, 72,250, 6,180, 47,214,164, 50,170,254, 87,226,255,253,122, -112,247,160, 40,178,139, 2,146, 84,231, 87, 31,251,227, 23, 15,159,191,169,243, 47, 98,113, 2, 75,144,254, 40,206,207, 76,149, -187,252,132,149, 95, 33,176,198, 95, 21, 4,175, 53,130,182,157,200,225,144,217,142, 49,185, 41,150,105,133, 33,118,109,211,200, -175,150,232, 86, 6,131, 48,219,202,216,131,106,192,185,235, 88,188, 78,146,231, 58,207, 71,230, 78,179,111,150,250, 66,190,197, - 12,220, 48,238,177,129,246, 46,192,131,107, 33, 76, 88,226, 69,192, 65,216, 29, 86,103,251,161,209,128, 15,121, 71, 72,181,213, -251,143, 0,148, 93,191,139, 19, 65, 20,158,153,157,157,205,230,199, 37,103, 17,229, 56,173,188,127,192, 66, 4,209,194, 66, 56, -176,177,187, 70,193,255,192,194,202,198,206, 82, 44,172,173,180,184, 78, 14,177,176, 23, 27, 57,131, 34, 8,130,228, 68, 65,115, -254, 72,118, 55,183,217,205,206,140,243,222,204, 38,187,145, 43,108, 66,216,133, 13, 76,118,190,247,190,121,223,251, 30,175,246, - 49,173,128,123, 21,217, 43,197, 85, 28,135, 12,128, 3, 17, 67, 17, 23, 34, 13,107,231,132, 11,194, 13, 80,132, 44, 4, 49,128, -199, 53,101, 57, 88, 90,105,157, 3, 9, 13, 25,215, 8, 91,185,243, 34, 52,185, 19,179, 37,251, 57, 1,163, 65, 64,107,110, 80, -213,100,251,254, 26,209, 61,248, 73,223, 92, 52,105,152, 79,189, 38, 21, 13, 95, 29,169,226, 84,184,209,100,225, 48, 57,240, 21, - 7, 8,147,216,155, 79,114, 84, 81, 50, 85, 95, 9, 90,211, 59, 58, 31,249,210, 86, 44, 64, 99, 72,123, 14, 81,242, 26, 70, 23, - 59,136, 45, 44, 59,255,213,171,147, 99,168,103, 29,225,129,224,163, 85,134, 87,119,245, 1,169,169, 91, 55, 59, 79, 21,190,135, - 12, 42,119,102,123,140,235,207, 22,192,176,105,191, 73,214, 91,188, 19,240, 66,179, 44, 83,227, 92, 69,153, 9,153, 50, 53,224, -132, 1, 64, 99, 12,232, 10, 47, 20,134, 9, 65, 50, 6,147, 94,225,180, 82,181,209, 36, 41, 80,122, 38, 73, 92, 64,148, 22,158, -110,121, 38,211, 87, 1,116,235,171, 89, 1,183,124,170, 27,146, 8,170,103,115, 0, 52,159, 88,221, 40,172,171,249,236,162, 73, -150,240, 88,219, 32, 34,230, 66, 73, 74, 78,119,197, 40,202, 8, 52, 43,121,118,251, 27, 86, 30,240, 86,156,199, 56, 85,150, 34, -240,197,118,205, 59,141, 78,191,119,242,219,175,175, 74, 21,245, 26, 5,165, 43,246,205,213,110, 13, 76,179, 12,201,195,134,100, - 32, 37, 78,129, 70, 1,139, 81,154,178,154, 46, 45,118, 24, 84,165,148,156,102, 83,147, 56,195,155, 71,193,220, 35,158,197,216, - 47,193,172, 22,130, 35,190,187, 14, 50, 68,225,225,207,225,146, 99, 81, 61,153, 77,136, 43,250, 86, 12,114,209, 64, 92, 90, 73, -157, 46, 79,248,137, 94, 22,234,244,114, 88,132,185,243, 59, 25,155, 43,135,209, 8,114, 16,179, 68, 66, 96, 59,143,186,118,238, -234,171,143,175,231, 96, 31, 1,143, 17, 76, 88,179, 44,106,223, 73,102,183, 61,179,210, 10,133,116,208,100, 75, 39,194, 94,146, - 37,135,105,252,248,197,222,147,187,247,245,102,111,247,217,243,237, 27,215,183, 46, 93,216, 62,127, 5,194, 10,109, 64, 88, 44, - 48,194, 72, 60, 47,159,150,209,230, 51, 33, 63,240, 93, 97,165,118, 10,242,252,133, 64,142, 90,161, 42,144, 11, 41,185, 97, 42, -196,227, 74, 54, 61, 80,106,194, 36,123, 47, 40,228,188, 31,174,147, 54,127, 63,120,235, 76, 0, 80, 35,205,192,205,198, 9,214, -206,246,186, 95,162,116,231,242,206,102,255,204,238,155,189, 15,159,246,255, 23,223, 15,190, 15, 30,221,121,122,251,193, 45, 28, -158, 67,134,131,135, 91, 55,239,173,109,244,139,232, 34,201,226, 34, 75,130,228, 15,105, 53,149,151,167,239, 94,202,209,208, 22, -103,212,209, 84,195,228,202, 84, 78, 35, 53, 25, 21,121, 44, 77, 22,131,200, 44,181,166,213,201, 61,238,207,164,139,157,239, 6, -184, 81,185,172, 85, 86,206,104,172,223,178,174,251, 28,184,126,163,242, 52,134,209, 99, 78,110, 93, 67, 21, 78,235, 94, 22,115, -237, 85, 91, 38,176,178,142, 58,196, 91,231, 14, 86, 58,144,213,242,146,154,223, 97,101, 62, 82, 77, 20,250, 87, 0,202,174, 93, -183,137, 32,138,206,204,206, 62,252, 72, 44, 39,136, 40, 6, 98, 68,135,160, 8, 82, 10,132, 4,174, 40,248, 24,126,130,130,191, - 65,136,135, 82,240, 40,104,137,144, 18, 9,138, 20,177,100,160,192, 73, 76,236,245, 99,189,235,121, 48,247,206,142,189,113, 34, - 16,165, 37,123, 37,239,206,222, 57,115,238,185,231,240, 37, 78,167, 8,111, 93, 72, 30,155,187, 1, 35,163,138, 99,171, 52,180, - 67,180, 17,184,196, 0,168,226,224, 39,101, 80, 35, 36,109, 4,168, 47, 76,149, 8, 52, 18, 74,152,231,225, 83, 58, 49,197,148, -234,208,163, 17,171,128,177, 31,210, 86,156,120,214, 57,192,131, 34, 2, 98, 74, 40,125,138, 14,101,198,102,190, 41,103, 67, 64, - 67, 44,132,214, 10, 43, 49,131,124,188,177,200, 54,171, 27,230, 39,157, 97,155, 83, 30,152, 51,137,103,118,111,206, 96,107,192, -220, 33,186, 24,230, 47, 84, 92,183, 81,217,180, 22,165,202,126,101,164, 98, 43,154, 94,124, 95,233, 66, 85,167,243, 13,150,157, -211, 87,208,191,180,108,233, 37, 99,192,204, 97, 0,141,158,139,112, 79, 61,231,165,108,221,210,124,169, 98,161,198, 78,185, 56, -127, 60,117, 66,174, 24,216,110,110,153,169,196,166, 86,102,224,136,104,254,100, 50,163, 97, 68, 54,148,151,162,184,196,192, 99, -207, 35,181, 16, 98,131, 65,182,136,107, 7, 34,132,113, 99, 30,207,108, 71,139, 78, 4, 56,201,184, 65, 6, 3,168,225,113, 6, -104,181, 92,166, 0,213, 45, 95, 33,128,145,167, 83,224, 51,105, 9, 19, 42, 51, 73,202, 33, 45,161, 66,179, 22, 81, 3,146, 60, - 48,138,100,245, 26, 59, 60,102,137,176, 19, 40, 10,105, 40, 54, 21, 9,115, 55, 30, 89, 17,107, 88, 68,198,211,209,247,227, 73, - 65,240,126,177, 7, 50, 23,247,146, 66,216, 30, 32,177, 4,188, 34, 64,194,194,205,126, 14, 40,146,160, 31,143, 35,146,244,178, - 22,181, 8,117,132, 18,163,233,200,154, 77,197,201,217,181,181, 27,221, 65, 23,229, 23,186,121,245, 86,251,228,200,174,106,199, -190,177, 69,131, 93,219,227, 55, 6, 37,229, 10, 55,247,106, 40, 55,211,192,242,121,245,156,162,212,203,127, 74,218,218, 96, 74, - 54,178,240,104, 79,164,147,108,186,181,222,236,156,116,222,239,127, 0,127, 27, 16, 10,193,117, 3,238,103,208, 19,118,166,164, -202,242,237,208, 71,241, 2,223, 20, 86,136, 42,227, 60, 78,227, 74, 84, 53, 23,111,247,123, 79,159, 61,223,217,190,221,120,112, -231,221,238,238,195, 71,173, 46,201,106,193,250, 64,140, 0, 57,217,250,110,158,107, 3, 23,147,125,221,215, 16,188,167,144,160, -230,232,144, 94, 46,119, 6,218, 10,166,163, 34, 22,174,132, 33,182, 31,224,168,110,192, 56,158, 30,112, 4,131, 49,243, 70,214, - 74, 32,105,127,249,230,109, 25, 42,128, 93,198,112, 72,225, 32,252,162, 82,146,214,214, 93,189,210, 60,234,253,232,205,250, 95, - 63,125,217,255,118,112,239,241,246,255,150,248,189,195,189,214,206,147,143,159, 95,225,167,126, 60,254,121,243,254,117,115,125, -241,123, 85, 7,171,213,122, 35, 77,193,126, 33,218, 36,201,235, 23,242,236, 84, 12, 78,211,179, 95,114,216,203, 38,177, 52, 7, - 44,228, 23,236, 97, 8,188, 79,152,159,202, 68,234, 60, 89, 25,214, 43,130,119, 39, 31,183, 90, 21, 97, 5,168, 26, 15, 95,104, -234,120,206,223,230, 66, 89,255,183,118,195,202, 91,130,160,146, 66, 98, 37, 93,106,250, 97,208, 88, 5, 98, 18,180, 44,160,120, -106,161, 21,135, 49,170,124,151, 41, 24,187, 43,103, 96,174, 23, 83,172,151,229,205,253, 17,128,178,107,217,109, 26,136,162,115, - 39,227, 56,105, 18,218,208,240, 16, 45,138,132,216, 0, 18, 59,254,130,175, 64, 66,221,246, 83,216, 35,129, 4,124, 1, 18, 75, - 88,177,160, 11, 84,177,161,136, 74, 77,121,180,170,168,154,164,117,226,196, 30,199,102,206,157,177,227, 68,101, 65, 86,177,228, - 88, 73,102,124,125,230,204,185,231, 44,249, 19,148,146,136,221, 38,172,162, 57, 51,199,253,115, 2,137,201,136, 79, 98,123, 51, -118,127, 20, 92,172, 80,160, 49,250, 86,189,198, 70,105, 58,179,205, 30, 4, 19,113,233, 34, 85, 11, 69,170,226,248, 8, 43,188, -241,216,182, 91,216, 40,105,169,120,186,171, 42,239,116, 92,171,174,128,186, 81, 6, 24,226,153, 81, 55,245, 60,131, 84,121,213, -111,175,198, 87,135, 81, 31,158,173,160,157,144,206,107,112,164,118,190,111, 84,180,234, 82,209,122,205, 24,173,233,183,146, 68, -143,211, 16, 9, 68,214, 35,156,172,185, 82,230, 8,183, 18, 79,159,111, 72, 72,186,132, 62,155,231, 28, 46, 62, 55,203,241, 94, -197,234,206,254,221,184,126,171,217,158, 78, 7, 21,178,135,179, 36,155,173,171,138, 25,204,126,174, 67,135,173, 27, 99,170, 6, -137,117, 31, 38,187, 28, 74,153, 14, 19,208,180, 54,222, 80, 66,113, 1, 95,102,179,138,106, 72,212,119, 85,201,124,225,188, 26, -235,158,181, 22, 55,147, 90,172, 41,165,243,224, 29,240, 48, 4, 5,171,253, 13, 13, 79,132,137,192,242, 72, 66,230,104,206, 74, - 82,105,128,121,187,110,238, 90, 25, 96,109, 99, 32, 27,252,203, 90, 62, 70,221, 12, 81,195,175, 84,125, 17, 39, 24,175,102, 77, -174,120, 85, 79,197,241, 76,122,196,211,145, 72,179,167,155,205,142, 95,128,228,172,116, 79, 11, 86, 29,114,126,151,151,189,224, - 30, 43, 85,221,175, 7,147, 11, 40,157, 83,219, 21, 43,109,137,103,195,110,121,187,211,253,117,250, 67,228, 88, 43,101,216, 72, - 84,118,131,114, 57, 36, 37,161, 49,149,154,141,233,168,127,108, 48,244,205,181,141, 88,235,131, 63, 61, 34, 71,232,165, 57, 40, - 42, 74,252,245,214,141, 65,116,161,227,200,222, 90,190,103, 30,112, 42,136, 70,178,124, 19,229,121, 58, 36,255,177,115,207, 63, -119,179,211, 29, 4,103, 97, 52,225, 4, 20,208,138, 63,207, 14,217, 82, 73, 72,154,227,182, 32, 30, 97, 89,225,114,202,138, 20, - 33,124,200,172,126,206,199,195, 24,177, 48,230, 1, 71,211,112, 84, 53, 51,163,230,103,169,247,101,239,240,243,238,247, 32, 25, - 63,218,120,216,238,116, 69,173,253,122,231, 37, 72,247, 61, 33,122, 66,108,114,125, 47,218,237,174, 8,241,128,201,119,139,235, -181,227,103, 96,116,159, 99, 33,243,197, 60, 54,154,199, 59,105, 27,126,157, 99, 43, 92, 45,147,240,222,221, 59,230,188,227,253, - 94,163,230, 67,131, 91,145,200, 24,195,238, 38,135, 69, 9,250, 54, 12,223,239,190,114,151,187,133,176,165,231,207, 94, 60,221, -126,242, 95,245,253,237,135, 55, 91,143,183,243,250, 46, 78,247,222,221,239,110, 33, 17,101, 96, 14,134,122,255, 60, 59, 57,145, - 71,191,167, 59, 31,131,175,159,226, 36,156,161,137, 91,155,233, 7, 70,184,214,156, 68,163, 44,143, 60, 98, 95,191,204,229,236, -217,216,120,235, 64,149, 35, 10, 87,242,157,179, 31,254, 28, 70,207, 89, 65,160,147, 19,205, 23,242,138, 98,106,177,154, 69, 94, -154,192,106, 47, 46,121,101,161, 51, 7,148,203, 1,203,128,230, 81,194,209,125, 14,245,216,137, 58, 99, 87, 92,145,148,176,119, -169,219,148,114, 85,203,210,182,192,242,235,175, 0,148, 93, 75,143,211, 48, 16, 30, 59,206,171,105, 75,150, 45, 15,237, 97, 1, -113, 64, 28,184,112, 88,137, 43, 71,126, 9,191,137, 59,191,132,223,128,184,237,242, 16, 90,218,125,182,105,218,188,108,227, 25, -219,105, 90, 78,244, 80,169,138,210, 72,150, 51, 51,158,249, 30, 98,200,206,133,195,230,187,243,203,118, 14, 74, 88,227,216, 19, -122,162, 73, 96,205,148,222, 88,117, 88, 14, 18, 15,188,232,177, 41,236,113,212,217, 96,242, 65, 83, 84,178,110,182, 98,135,218, - 11,168,104,159,124, 80,212, 87, 16,137, 93,147, 43, 19,138,139,153,228,193,131, 52,136,243,120, 68, 22, 77, 40, 65, 94, 52,109, - 22,134,153,121, 52,218,200,176, 45,162,169,244,201,248,180,168,151,102,245, 58, 45, 20,166, 58,213, 40, 28, 12,144, 61,135,222, - 9, 49,128,195, 27, 36,108, 50, 13,166, 38, 40,197, 73,180, 86,229, 98,251,187, 37, 75, 57, 23,123,152, 18, 0, 3,107, 64, 71, -109,165, 68, 33,165, 19, 84, 99,251, 16, 74,118, 56,218,222, 45,182, 30,246,247, 25,248,217, 5,131,174, 94,198,228,211,186,238, -154, 22,225, 93,240,148,124, 48, 82,143,104, 48,159, 25,135,113,196,183,146,149,192, 71, 36,113,132,112, 24,134,176, 69,242,119, -181,134,118,176,238, 0,251,182,100,140, 18,227,234, 17, 70,158,163, 84,219,116, 20,230, 35,196, 12,175,106,244,242,100, 86, 40, - 70,152, 76,169, 27,165, 43,218,237, 38, 13,228,204,108, 47, 85,118, 56,231, 51,123, 44,137, 88, 45,149, 9,211,230, 89, 73,100, - 34, 59,203, 66,222,144, 53, 22,102,123, 97,214,142,155, 91,179, 84, 4,228,135,155, 63,128,204,220,210, 2, 9,139,155,236,138, -157, 40, 79, 47, 29, 42, 66,168, 56, 28,163,199,216,192,226,249,152, 52,106,122,242,157,205,138,166,214, 46,235,210,108,245, 60, -203,111,139,219, 93,199,133,182,189,201, 7, 63, 23, 23,180,178,193, 30,135,117, 88,163,208, 31,205,198,143,110,202, 27,171,255, -106,143,108,218, 69,124, 2,170, 48, 62, 95,254, 65,126, 40,217,171,152,107,105,156,109,154,242,197,236,229,143,235, 11, 15,233, -129,171,226, 74,121,253, 18,108,187,183, 91, 42, 8,117,175,197, 72, 72, 80,139,145,212,100, 95,106,181, 85,249, 30, 44,142, 60, -230,190,207,207,177,244, 37,185,130, 36, 74,147, 32, 41,171,194, 73,161,225,183, 36,183, 3,138, 64,220, 28,112,211,163,113,142, -178,148,244,146,147, 95, 37,130, 8,208,182,201,225,231,156,242, 27, 78,188,132,152, 76,143,214,205, 38, 19, 79, 4,139, 58, 22, -164, 97, 50, 73, 30, 70,176, 57,254,242,241,246,236,195, 50,123,222,158,188,129,215, 12, 94, 1,188, 5, 48,145,249, 20,224,153, -163,176, 81, 81,223, 90,190,180,196, 89,175, 0, 85, 5,181, 46,234,251, 21, 2,176,136,190,139, 77, 66,238,157,212,216, 22,154, -247,103,239,204,109, 95,127,157, 23, 80, 22, 85, 25, 34,132, 81,108,229, 70,246,241,164,218, 32, 43, 91, 36, 45,114,217,170, 89, -248,248, 90, 46,254, 55,190,223,149,215,147, 81,214,255,172, 22,223,196, 29, 52,151,178,250,244,185,185,186,212,171,251,182,188, -107, 55,203,117, 49,175, 24, 66,195, 20, 35, 3,102, 9, 85,215,144, 69,176,114,104,105,171,179, 46,109, 45,143, 72, 86,233, 32, - 89,253, 59, 78,196, 84, 38,123,133, 23,175,180,222, 87,199,222, 9,219,199, 70,229,182,178,173,238,213, 40,154,172,171,146,239, - 53, 29,121, 31,129, 56, 19,230,216,141,163,116,255,192,158,174,204, 28,218,134,237,164,150, 92,203,210,247, 38, 15, 97, 63,157, -246, 52, 40, 6, 67,183, 62,248,183,132,255, 43, 0,101, 87,206,219, 68, 16,133,103,246,240, 58, 62,194,122, 77,228, 68,138,114, - 72,225, 8, 5,162, 2,126, 2, 29, 13, 21, 53, 18,145, 40, 64, 66,226, 23, 64, 1, 61, 69, 36, 26,122,154,136,134, 2,132, 68, -149, 50, 29, 33, 2,161, 16, 18,156,196,142,177,119,215,246, 94, 51,188,247,102,214,177, 81,132, 68,231, 98,189,247,206, 59,190, -239,125,159,117,150,114, 36,159,164,205, 48, 18,121, 39,124, 22,229,215,173, 2,183, 96, 73,181,181,225,181, 73,136, 51,162,106, - 52,170,163,166,138, 24,105, 21,144, 32, 45,214, 56,152,235, 33, 41,158,235,174,162,154,113,183,104,184, 67,161,196,169, 50,211, -160,109,224,202,171,216,190,231,126, 18, 35, 81, 1,142,147, 98,163, 51, 72,211,105,244,218,176, 42,248, 33, 20, 6, 73, 2, 39, -211,168, 44, 31,248, 95, 33,131,136,145, 24,130, 45, 95,140, 52,244,248,198, 16, 5, 78,222,209, 70, 40, 7,131,116, 88, 76, 11, -142, 81,242, 10,238,114,245,226,247,222, 14, 10, 6,229, 19, 49,114,204,120,111, 68,107,161,186,212,241,170,245, 86,239,144,159, -129,167,202, 51,167, 21, 70, 24,142,169,201,118, 74,133, 17, 81, 77, 8,137, 3,116,231, 67, 34, 55,188,188, 75,174, 85, 55,172, -163, 76,204, 8,194, 98, 57,175,218, 12, 2,103,130, 67, 47,216,149,131,236, 49,206, 88,152,226,237, 46,144,109, 82,130,107, 13, -110,237,153, 52,178,148, 49, 7,249,167, 18,237,172, 76,195, 45,218,110,197, 30, 70, 98,103,191,127,220,141, 59,201, 41,232, 12, - 5, 65,173, 98, 45,214,167, 22, 27, 83,126, 38,187, 1,153,246,162, 72, 11,122,146, 38,232,178, 5, 43,172,225, 19,193,175,132, - 85,149, 17, 9,218,173, 1, 97,128,135,130,187, 4, 23,167, 92,150,139, 70, 42,120,194,165, 91,230,200,218, 20,152,185, 23,157, - 18, 68,145, 65, 20,162, 7,163, 82,107,209,227, 8,240, 38,196, 72, 93,167,167, 98,163,255,156,108,118,247,103,166,103,187, 65, - 59,206,129,171,124,210, 2, 75,176,142,127, 98,232, 86, 24,161,100, 80,239, 73,229,226, 55,106, 37,234, 90,144, 50, 34,253,133, -112, 83,143,169,183,125, 88,220,179,115,229, 90, 15,221,248, 84,254, 61, 49,205,164, 75,114, 74,225,188, 74,227, 36,108,193, 62, -246,218, 63,104,133, 53, 72, 78, 11,235,119,111,202, 59, 65,139, 71,126,234,158,156, 41, 24,146,234, 81, 4, 87, 88, 70,122, 53, -182,101, 46,212,150,154, 65,115, 48, 12,181, 18, 79, 62,251,125,121,126,245,243,254, 54, 33,111,216,215,233, 71,195, 8,217, 9, - 16,173,145, 24, 42,201, 37,133,220,103, 17,222,154,171,205,199,105,212,242, 91,216,243,226,248,148, 77,166,108, 26,117, 76, 83, -244,126,178, 65, 81, 30, 2, 44,236,247,168,252,165, 25, 67,120, 5, 68,124, 99,225,234,251,157, 15,237,225, 58,227,235,165,161, - 51,247,107,222, 61, 94, 9,223,186, 34,187, 38,140,155,129,221,232,212, 27, 98,209, 99, 87, 24,219,132, 93,110, 33,156,102,162, - 97, 48,153,157,137,246,246, 55,227,210,236,196,171,126,216,219, 59, 56,232, 5, 62, 92,241,239, 44,120,253,124,253, 33,119,234, -188,242,241,211, 59,248,235,227,187,107, 91,187, 95,158,174, 61,185,126,231, 22,220,222, 42,179,158,221,127, 84,182,138, 38, 36, -120,180, 80,180,211, 99,216,199,131,219,247, 94,110,188,250,175, 37,126,245,194,202,232,183,115,180,219,125,241, 38,106,254,236, -108,109, 74,147,100, 98,147, 40,142,250, 73, 28,210, 28,125,134, 90,241,153,194, 4, 5,217, 49,168, 27,164,101, 32,115,210, 75, -110,186, 51,154,113, 33,183, 73,149, 56,241, 73, 93, 41, 49,166,202, 59, 6, 79, 74,241,247,146,202, 33, 90, 43,102,157, 60, 85, -178,193,100,226,124,185,222, 10,142, 84,122,167, 9,149, 84,233,169,208,174, 13,169,198, 14,103,141, 58,197,234, 44,115,162,189, -170, 69,149,254,204,120,242, 46,255,137, 6,254, 17,128,177,107,231,109, 26,138,194,190,215,143,184,137,221, 52,105, 43,167, 74, - 4, 42,229, 81, 84,216,248, 13,252, 4, 70, 38, 6,216, 89, 96,228,223, 32,132,196, 14, 44,136,133, 1, 49, 48,208,161, 84, 13, -165,208, 71, 30, 36,182,227,231,245,229,156,115, 99,167, 18, 20,177, 69,201, 18,251,218,231,245,157,239,251,140, 11,192, 65, 86, - 25, 42,169,246,145,188, 23, 16,224,183,141, 58, 87,102, 13,115, 50, 25, 47, 84,147,140,173, 61,122, 5,240,243,125, 42, 22,238, -166,165,155, 16,166,107,220, 52,185, 13, 41,118,146, 4, 2,101,197,224,220, 81, 6, 12,199, 49, 40, 89,195, 99,242, 70,128,234, -179,166, 35,165,194,101, 70,202,164,205, 49,192,195, 21, 54,184, 65, 84, 70,220,246,139, 10, 9,241, 14,178, 88, 82, 36,174,229, -224,156,135, 25, 70, 65,254,111, 5,177, 27,231,222, 39, 74, 71, 28, 94, 26,136,149,112,214, 17,125, 70,253,210,164,192, 5,136, -142,182,222,117, 46,245,131,125, 86,178,219,168, 92, 18, 21,254, 33,203, 36, 12, 87, 54, 68,181,144,185,128, 81,213,254,147, 5, - 26,251, 43, 33, 77, 45,100,145,188, 21,237,138, 34,251, 71, 51, 9, 86, 77,211, 36,150,184,153,214,173,179,205,181, 6,180, 65, -126,144, 56, 75, 40,246,170,148, 9, 8,133,198,205,244,188, 60, 52, 28,191,208, 79, 57,101,109, 65,230,180, 8,208, 25, 8, 6, -145,235, 42,230,209,164,224, 94,173,182,234, 24,253, 65,120, 48, 74,252, 76, 6,212,123,103,231,197, 19,252,252,179,239,111, 30, -250,183, 47,215,175,245, 92, 40,121,194, 40,254, 21,138, 52,199,123,183,100,105,245, 28, 58,169, 98, 28,107,179,140,242,147,197, -212,220,106,173,206, 66,129, 19,124,219, 68, 50, 62, 35, 20,225,116,154,111,117,204,195, 1, 58,136, 27,120, 46, 81,154, 87, 23, -161,214,186,185,218, 65, 65, 9,123,195,240, 90, 27, 71,131, 67,165, 26,228, 45,119, 79,166, 63,169, 76, 41,103,223,154, 92,180, -184,188, 98,132, 48,185,240,232,197, 39,187,116,168, 85, 34, 81,146,145,247, 99,187,177, 50,141,124, 21,232, 85, 89,142,117, 90, - 46,220,154, 51,133, 74, 25,129,124,182,222, 36,130, 43, 29,146,183,178, 17,165,161, 31, 5,142,237, 98, 97, 78,194, 34,185,204, -106,102, 13, 27, 5,145,171,253, 9,244,210, 44, 27, 51,220,233, 50,204, 8, 2, 74,142, 75, 34, 16, 16, 91, 78,123, 48, 25,232, -196,115,129, 27,184,127,182,135,214,113, 28,138, 93,150,137,197, 50,202,238,209,151, 57,107, 82, 96,170, 71, 51, 3,221,146,130, -152, 95,178,216,242,110, 28,156,237,145, 17, 7,226, 30,253, 65,159,225,180, 77,119,109,183, 64, 72, 60,146,243,213,116,174,210, -157, 50, 69, 80,110,101,205,250,114, 46,224,223,100, 92,249, 57, 18,102, 32,178,248,217,189, 71,175,239,190,122,240,228,241,199, -239,123,199,193, 48,138,229,183,241, 7, 26,202, 60,215,236, 70,199,237,222,146,142,247,163, 59,222, 77, 5,227,161,151,126,245, -123, 22, 52,109, 58,190,175,144,200,219,219,215, 45, 45,135,122,171,203, 58, 55,175,108,237,236,108,247,122, 94,251,206, 85,125, -181, 9,165,192,106,171,181,230,117, 58,205,238,134,211,134, 12,154,103, 25, 60, 38, 38,116, 29,204,130,252,112,252,254,211,201, -100,214, 16,122,219,114, 82,106, 93,109,211,138,130,217,187,151,111,239, 63,125, 72,241,253,127,109,184, 91,141, 86, 60, 26, 45, - 26,190, 60, 57,125,243, 34, 8, 38,153, 22, 35,189, 17,110, 96, 33,112,164, 8,239,126, 50, 67,236, 72,166, 90, 65,164, 15, 82, - 41, 36,164,154, 2, 98,233,234,164,205, 53,169,170,183,152, 28,248,184,177,100,187, 83,114, 14,128, 35, 14,179,240, 66, 7, 60, -237,207, 77,150, 69, 73, 92, 6,247, 57,188, 68,114, 26, 98, 20, 14,209,251,178,164,166,206, 37,114,164, 90,124, 85, 69, 7, 43, - 42, 59, 10, 66,249, 89,165, 19, 69,196, 50,248,162, 97, 59, 16, 66,199,179,225, 57, 56,191,212,204,146,242, 31,171, 30,191, 5, - 96,236,220, 90,155, 8,162, 56, 62,183,221, 77,179,109,218, 36, 53,241,210, 22,131, 98,209, 42, 34, 85, 31,124,240,193,175,224, -103,240,195,249,224,171, 15, 94, 80,144,162, 47, 34,130,208, 34, 18,173,109, 68, 98, 75,154, 38,217,203,236,206,140,115,206,236, -166, 13,125, 41, 44,228, 6,217,100, 47, 51,103,206,249,159,255, 15,252, 9, 40,116,173, 41,122, 70, 13,137, 47, 57,178,117,184, - 7, 30,133,240,164, 33, 26,104,186, 45, 28,222,155, 57,217, 1, 36, 86,237,116,170,156,200, 95, 35,153, 4,137, 16, 96, 20,141, -246,201,144,109,183, 91, 43,108,217, 25, 98,127,244,219, 6,236, 30,168,241,153,143,139, 86,252,187, 60, 4,227,111, 1,214, 5, -220, 7,174, 40, 97, 1,199,120,151,177,208,131,136,222, 94,140, 21,193, 35,176, 46,161,169,202,142,210, 72, 48,113,152,236,253, -141,250,169, 74, 18,149, 72,157,100,174, 33,214, 20,161, 25, 30, 0,158, 3,180, 55, 71, 45,138,253, 94,129,191,159,135, 44,188, - 88,109,119,199, 59,133,203,205,137,165, 59,210,150, 28, 37,174,108,239,154, 86, 36, 92,245, 26,144, 61,154, 36,106, 50, 99, 18, - 52,227, 22,132,237,154,121, 98,255, 61,100,201, 17, 50,235, 51,154,164,177,157,159,154,132,220, 88,246,175, 93, 90, 24, 68,170, - 63,204, 38, 82,123,220,216,205,158,234, 49,212,251, 97, 64, 71,172,156, 35,187, 64, 80, 34,128,181,130,197, 47,156,225,236,168, -230, 99,120,235,161,250, 90,129, 38,152, 52,171, 65,167,238,245, 14,226,159, 71, 73,132,213,181, 8,245,205, 73, 25,191,187, 27, -203,199,146,219, 60, 33,151, 23,249,253,235, 75, 43,237,208, 70, 65,253, 35, 57,156, 40,208,200, 64,245,143,198,216, 79,169, 96, -167,104, 96,201,104,189, 10,168,103,251, 34, 55,224,212,220,168,242,192,158, 66,193,171, 1,253,184, 19,255, 27, 67, 8, 37, 21, - 76, 75,153, 2, 3,254, 86,109,181, 55,216, 43,108, 81, 81, 38,164, 93, 87, 42, 10,215,156,171, 35, 65, 29,203,172, 85, 91, 65, - 44,183,227,172,171,169,150, 89,110,205,202, 60, 98,169, 43,133,143, 26,243,205, 68,142, 37,240,255, 32,114, 7, 94,106,217, 75, - 98, 10, 71, 61,220, 47,117,151,165, 59,209,110,233, 91,172,208,209,159,206,108,172,222,234,246,187,247, 58, 15,182,119,191, 78, -228,164, 0, 15, 81, 90,245,231,143,227,129,179, 82,112, 28, 83,160, 92,228,106,109,185,211, 27,236, 99, 18,160,144,211, 27, 28, -184,237,163, 71, 5, 68,143, 58,115,247,185, 42, 59,197,174, 52, 87,123, 7,187,149, 74, 40,101, 66,241,142,192,226,186, 1,211, - 14,232,211,134, 67, 95,175,212, 83, 35,179, 44,117,166,149, 69, 20,229,120,136,184,134, 6,129, 26,120, 14,113, 7,149,244, 33, - 35,206,124, 4, 86,182, 23, 91,135,209, 16,186, 96,153,104, 55, 91,154,138,227, 40, 75,153,157,146,234, 27,181,155,207,238, 62, - 37, 75,228,195,214,151,231,159, 95,190,238,111,253,136,190,195,117,153, 31,216, 47,173, 5,115, 74,231, 30,149,128, 89, 64, 23, -204, 80, 47,248, 62,220,124, 40,108, 3,213, 3,207,149,111,215,145, 18, 38, 66,152,124, 42,190, 8,188, 40,142, 71,163,161,141, -153,189,192, 19,130, 13, 39,195, 49,166,242,231, 72,240,184,221, 25,169,244, 16,186, 16, 32,204,250, 53,248,243,233,197, 27,118, -181,254,112,115, 19, 83, 64,231,146, 78,222, 94,217,104, 47, 92,120,187,253, 30, 29,128,107,235,107,119, 36,138, 48, 41, 34, 21, - 40,146,147,114,153, 60, 89,127,244,234,219, 59, 88, 11, 1,239, 1,105, 78,170,228,129,231,174,128,170,205,233,206,196, 19,117, -163,113,173,252, 12,157,136,220,165,133,230,192,116,234, 52,224,128,204,211, 78, 84,122, 42,133,123,118, 68,117,110,169,166,208, - 53, 20,224,200,147, 86, 36, 61, 69,133,144,146,208,102, 74,251, 73, 83,162,191,137,153,173,231,153, 66,246,195,176,203,157,234, -115, 13,238,197,123,255, 5,160,236, 90,114,163, 6,130,104,219,237,111,198, 73,156, 47,201, 16, 5,144, 16, 74, 4, 75, 36,110, -144, 5, 18, 43,118,220,129, 53,119, 96,205, 29,184, 3,123,144, 16, 18, 2, 33, 36, 68, 80, 64, 40, 65,129, 76,102, 50,227,177, -221,110,127,154,170,234,246,196, 9,217, 48,139, 89, 89,182,218,174,238,250,189,122, 15,207,119, 90, 97,221,242, 97,154,251,159, - 43,104, 91, 40,233,227,144,146,181,203,131,136,245, 42, 28, 67,229,196,152, 97, 11, 4,115, 52,164,163,138,175,201,224,144,144, - 90, 68,117, 72,200, 52, 47, 22, 70, 85, 43,193,146, 13, 39,114,118, 74,196,120,184, 21, 93,226,194,195,220,144,129, 57, 57,120, - 87, 8,225,109, 47, 66,147,113, 21,150,240,124,184, 18, 44,216,113,120,173, 12,114,168,166, 34,208,168, 16,162, 42,100,147, 29, -166,223,202, 90,138,186,192,201,102,156,192,175,244, 76, 25, 21, 81, 49, 0,175, 16,130, 89, 17, 32, 20,158,225,114, 34,201, 9, -172, 96, 99,110,227,168, 56,148, 85,170,176, 45, 84,119, 1,175,151,121, 33,206, 9,222, 88, 39,211,103,236,202,161, 99,173, 61, -100,107, 69, 42, 36,154,193,202,184,231,135,220,155, 78, 78, 66,219,186,187, 25,110,175,247,166,162, 62, 30,201,145, 0, 55,167, - 34, 27,139,127, 96,150, 73,219,192,135, 96, 31, 25, 53, 9, 4,208,104, 82, 92, 42,187,187,182, 46,215, 98, 54,144, 85,232,101, -165,178, 28,174,150, 61,190,187, 58, 55, 74,228,247, 97, 54, 65,241, 99,100,143,129,197,143, 21,194, 35,244,177,174,217, 34, 67, - 50, 14,135,202, 53,155,177,189,123, 35,222,185, 21, 15,198, 69,154,229, 73, 94, 79, 10, 52,165, 84, 42, 65,166, 20, 82,230, 6, -193,109, 28,240,158,143,159, 39,111, 44,209,128, 55,226,107,145, 13,135, 62,216,136,172,212,155, 47,133,144, 8, 62, 40, 80, 34, -147,149,200, 21,165,109,214,240,222,195,223, 66,176,152,203,156,166, 10, 44,126,145, 98,233,210, 64,154, 25, 71, 50,216,228,127, - 24, 84,153,225, 27, 38,148, 14,182,112, 72, 71,132, 20,125,219, 17,109,172,111, 90, 84, 13, 33,184,189, 22, 87, 83,157,150, 9, - 92,228,186,224,233,185,172,203,126,220, 31,166,131, 52, 75, 80, 0,196,178,100, 41, 72, 82,197,184, 7,184,121,232,247, 38,233, -168, 86, 90,168, 14, 86, 84,185,142, 87,150,101, 59,129,165,137,135,148,207,125, 8,165, 97,113,113, 24, 83, 86,110,177,182, 27, - 1, 15,246,137,189, 50, 10, 22,132, 76,117, 66,108, 99,211,137,228,196,181,215, 67, 16,148, 75,229, 78,157, 59,107, 70, 16,174, -233, 28,112, 84, 16, 3, 46,184, 2, 82, 97,112,172, 28, 92,194,131,219,247, 63,254,248,164,249,183,112,138, 21,183,158, 67,123, -207, 5,147,129, 87, 80, 90, 16,220, 56, 57, 54, 62, 87, 30,109,237, 61,190,179,231,111,218,172, 96,227, 15,205,207, 45,251,245, -111,246,238,215,225,254,112,127, 40, 6,220,143,220,181,123,121, 19,156, 14,191,202,233,113,149, 79, 84, 50,184,193,231, 31, 46, -250,235,243, 78,146,177,131, 60,121, 59,126, 85,177,113, 38, 79,242,242,172,193, 56,164, 49,157, 57,139,175,122,219,152,118,216, -243,215,120, 63,112,214,206,228,251,229,165,163, 97, 33, 51,171,153, 10,113, 64,141,150,151,207, 95, 60,121,246,212,131,184,167, -188,154,171,178,251,153, 33,172,222, 89,189,249,249,207, 62,182,132,221,168, 31, 95, 87,142,219, 38,131,166,137,142,252,240,149, - 64, 78, 90, 26,159,166,147,189, 50,146, 62, 38,100,175,205,118,234,128,162,148,154,129,217, 88,109, 6,120,148,186, 32, 41,131, -165,248,106,134,106,236,156,239, 93,142,151, 75, 49,157,197,102, 85, 20, 2,164,112, 91, 67, 77, 52, 97, 70,155,137,178,115,129, - 17,173,126,174,169, 5,140,254, 67,203,107, 53, 43, 25, 95, 28, 56,253,175,195, 29,126,127, 5,160,235, 90,122,162,134,162,240, -185,125, 13,237, 76,103, 24,134, 71, 0, 19, 55, 6, 68,194,130,173,137,174,253, 11,254, 7,215,186,214,191,224,194,189, 11, 19, - 55,252, 15, 55,248, 72, 52, 38,188, 66, 98,120, 9, 2, 45,109,153,222,222,214,251,157,219,130, 3,152, 89, 53, 51,233,180,183, -189,231,124,231,245,125,181,125,191,185,125,106, 66, 2,132,212, 40,224,176, 76,182,190,236,174, 24,183, 25,134,107,252,160,208, -183, 0, 97, 95,112,254, 9, 22,141, 64,154, 23,174,162, 96, 85, 29, 54, 66, 44, 82, 3,156, 2, 87,209,246,218,158, 53,150,200, - 11, 36, 82,109,115,102, 13, 16,176, 8, 45, 80, 96,163,173,190,163,113,186, 3,176, 27, 8,207,247, 90, 2, 82, 30,122,219, 90, - 46, 3, 23,188, 73, 70,166,153,157,184,118, 36, 7,105, 52, 44,139,221,243, 31,146,100, 86, 36, 89,161, 77,205,144, 89,136,139, - 74, 92,201,157,192,202,228, 36, 57, 14, 2,133,189, 75, 46,215,139,220, 73,127,230, 92, 29, 39, 69,204,149, 23,230,125, 19,215, -186,227, 55, 44,251,255,155, 34, 71, 83,240,205,159, 98,251,242, 35, 69,188,192,148,249,142,146, 94, 89, 46,207, 6,253,158,159, -100,114, 63,202, 53,224,213,183, 27,194,179,209, 73, 94,230,224, 99,132,139, 86, 28,106,162, 43,168, 38, 0,175,165, 10, 48, 38, - 46,160,123,162, 15, 19,197, 10,143, 36,186,142,152,240,172,241,150,221,113,188,245,163, 36, 1,103, 3, 50, 77,147,129, 53, 21, -184, 81, 82,110,167,210,116, 60, 7, 60,177, 24, 32,150, 32, 29, 84,107,172, 21,186, 52,219,243, 86, 23,122, 51, 83,225,175,223, - 26,239,229,167,105,145,230,168, 57,166, 60, 94,174,157,161,203, 38, 94,191, 1, 93, 95,187, 89,145, 42, 35,130,132,130,120, 11, -192, 81, 76,133, 86,148,169,207, 27,242, 18,162, 45, 64,241,185, 68, 42,137,137,129, 12, 57,145,201, 62,226, 51,232, 76, 30,199, - 39,246,104,223,204,200,140, 32,221, 90,206,106,164,147,216, 40,136,153,141,132,125, 36, 76, 18,172, 70, 76,250,199,131,238, 32, - 78,163,249,254,252, 14, 20, 54, 56,203, 14, 78, 62, 63,205,181, 99, 42,170, 70,162,141,203, 66,152,137,129,194,148,176,199, 92, -175,237,119,143,163, 67,139,223, 88, 85, 72,212,155, 0, 1,209, 38, 7, 9, 42,175, 61, 8,251, 27,135,155,216,185,170,110,225, -188, 26,156,227, 44,186,109, 53,179, 47, 26,157, 44,206, 45,125,219,253,210,239, 76,100, 82,102, 50,117,174, 61, 1, 82,210,184, -114,163, 42,205,183, 96, 82,182,136, 1,248,107,108, 64,163, 55,222, 28, 57,220,108,224,176,190,141, 11,176,133, 73,175, 78,203, -151,170,240,108,104,159,241,234, 90, 70,202, 19, 92,163, 8, 91,133,190,230, 56,151,165,176,115, 97, 15,201,150,149,123, 63, 92, - 88, 26, 44, 62,246, 87, 87, 94, 77,211, 10, 95,211, 17, 8,131, 55,247,104,251,140,214,247,105,253,130, 34,165,209, 22, 61,152, -163,135,211,244,180, 79,203, 19,244,103,155,214,190,210,251,159,180,151, 82, 28, 75,153,159, 85, 5,152,217,203, 98, 40,100,105, -229, 39,190, 19,248, 82,106,244, 96,171, 44, 59,255,158, 29,188,123,243,236,201,199, 79,107, 59,167, 7,123,116,249,250,249,139, -151, 31,222, 62,234,222,219,138, 15, 93,215,203,193, 36,168,110,209,111, 85,198, 50,114,159, 38, 2,187,208, 25,211, 11, 11,165, - 32,207,135,187,178,140, 26, 66, 77,193,101,168,193,160, 0,162, 12, 77,117,201,234, 17,172, 5,162, 12, 21, 85, 77, 28, 76, 85, - 85,221,162, 30, 65,226,171,233,142, 25,153,184, 96,115, 43, 76, 35, 71,205, 39, 83,209, 63,167, 16, 84,149,119,241,182,155, 7, -107,210,218,104, 59, 66,221,220, 2,155, 66, 77, 16,212, 40, 41,179,152, 84,101, 4,189,185, 76,203,184, 82,137, 70,167,217,111, - 5,217,104, 39,229, 85, 51,222,245, 52,236, 29,198,253, 14,146,149,191, 2,208,117, 37,187, 81, 3, 65,180,187,221,118,123,236, - 25,156,132,132, 75, 16, 72, 4,144,136, 0,113, 64,130, 3, 7, 46,112,201, 95, 32,241, 53,220, 56,241, 1,156,248, 2,206, 8, -174,108, 18, 72, 17, 72, 64, 16, 4, 80, 50,100,108,143,215,105, 55, 85,213, 61, 75, 22,164, 57,204,209,234,165,186,234,213,171, -247,228, 73,146, 41, 83,252,157, 78, 63,197, 37, 4,251, 20, 15,108, 41,109,179, 33, 27, 8, 3,207, 81,187, 38,132,162,114, 50, - 69,243,167, 94, 98, 40,112,194, 32, 91,243, 20,247, 67,137, 94, 78,121, 59, 68,168, 7,170, 82,124,112,177,199, 68,156, 75, 11, - 40, 11,235,101, 38, 89, 64, 34, 72,232, 96, 19, 32, 5,135, 43, 43,157, 41,156,166,127,163, 59,159,194, 60, 84, 12,131, 64,201, - 9,214, 24, 28,203, 97,178, 88,232,132,107,151, 31,162,185, 64,133, 17, 76, 40,101, 32,214, 17,134, 29, 73, 95,137,210,134,211, -121,120, 71, 93,194,220,159,152, 96, 22, 8,152,169,141,147,244,184, 57,241,233,238,152, 19,172,135, 21, 16,172,175,150,198,232, -247,134,224, 20,167,169, 95, 90, 39,214,247,229,165, 85,213,143,189, 81, 86,167,181,134, 60, 55,144, 60,242,189, 88, 26,200,184, -123, 74, 42,164,144,243, 18, 59,175,148,128, 81, 96, 68,231,107,186,181, 13,157, 91,109,211, 9,195, 26,114,207, 20,136,254,242, -172, 33,232,166,110,172,219,125,205, 80,219, 19, 54,108, 99,189,199,117,160,183, 15, 10, 52, 14, 69, 88, 38, 98,114, 61, 12,140, -175,191, 20,117,169,113,173,199, 85,251,125,183, 24,196, 97, 18,203,220,180,170,230,181, 48, 49,148, 57, 8,130, 33, 23,126, 76, - 26,159,202, 99, 7,117,183,194, 69,213, 64,177,236,102,240, 52,245,126,139,170, 27,132,222,181, 13,254,230, 51, 4,118, 36,116, -118,182,105, 64,179,151, 29,233, 76,118,142, 6,216, 33, 34,121, 84, 93,143,219, 89,187,238, 48,184, 57,179,116,159,169,128, 82, -229,187, 64,140, 50,118, 92,205,193, 45,112, 80, 79,247,151,135,249, 94, 81,229,145,138,118,134, 59,168,203, 65, 73, 21,124,103, -213, 20,198,121, 77,205,199, 5,113,223, 32, 96,146, 77, 7,242,178,234,124,117,176, 54,204,135,244, 60,123,119, 54,111,191,248, -240,146, 26,156,136, 68,142,171, 17, 60, 15,144,134,247,194,126, 6,251,171,157,187,150, 13,238,130, 40,100,142,152,204, 77,221, - 54,239,191,189,131,237, 72,139, 17, 60,210, 82,240, 25,255, 88, 88, 77, 41,171, 17, 19, 38,227, 42,101,142,138,231,185, 46,132, -237, 72,184, 63,179,142,220,220,209,193,222, 85,184, 50, 80, 12, 89, 33, 82,242,156,193, 27, 4, 71, 34,137,146, 20, 91,220, 16, - 61,116, 20,242,162,107,225,203,224, 48,196,152,250,171,180,253,249,122,191,185,123,246,214,211, 63,108,119,159,141, 2,166,206, -176,115, 9,187,121,157,221,227,236,254,108,245,245, 33, 7,131,149, 43,236,193, 22,219,220,102,239, 63,177,189,191,126, 90,172, -101, 37, 75, 26,182, 60, 97, 89, 10,165,244,249,116,140, 54,128,240,235,213, 90,132,113, 89,189,189, 26,110, 61,124,245,104,251, -227,243, 11, 27, 23,253, 27,151,159, 61,126,242, 53,251,177,212, 75, 90,114,139,176, 52, 38,107,196, 4,239, 92,228, 99, 99, 76, - 33,125, 14, 75, 20,136,216, 40, 71, 72,112,132, 10,162, 83,189,228,215,232, 55, 22, 85, 11, 99, 17, 46, 75, 39, 99, 8, 82,128, -177, 70,120,211,164,120, 10,198,177,249,160,233,188, 39, 89,180, 37, 81,111,245,145,254, 25, 58,195,248, 97, 32,101, 86,229,226, - 63,137,186, 57, 54, 11, 43,156,136,141,103,220,251, 36,132,113,101, 13,209, 14,185,243, 76,192,144,170,148, 23, 18, 3, 5,174, - 63, 38, 66,149, 41,105, 53,224,128,208,220, 45,227,165, 29,132, 94,212,172,153, 50,121,244, 2,242,104,216, 49, 38,253,177,100, -243,159, 0,124,157,203,138, 19, 65, 20,134,171,170,171, 47, 73, 67, 50, 56,227, 5, 7, 28,193, 69, 64,131, 10, 46,196,149,111, -224,194, 7,112,229, 59,248, 0,190,133,111,227,194,149,162,120,193,157, 73, 64, 68,103, 24, 52, 49,157,164,187,171,171,202,250, - 79, 85,103,210, 50,186,155, 33, 36, 36,157,212,233,115,249,207,247,203,238, 98,230,174, 44, 50,112,222,195,128,149,241, 92,244, - 27,235, 81,128,129,214, 0,208,151, 21, 13,244, 39,212, 21, 34,209,125,100, 36,109,134,251,201, 38,120,131,254,151,170, 44, 81, - 6,232,128,234,214, 96,182,225,152,175,122,170, 57,156, 42, 16,175, 64, 5,112,127,186, 51, 93, 69, 24,250,149, 48,129,108,100, - 36,123, 90,247,177,216,141, 87,207,132,168,208,135, 33,221, 33, 69,117,113, 6,201,225,222,238,193,108, 55,156, 8, 95, 76,109, -153,140, 80, 90,158, 39, 5,241,190,187,211,128, 9,206, 59,116,208, 97,126,160,234, 77,165, 55,237,156, 4, 99, 82,201,125,219, -143,241,191, 23,104,188,235, 64,123, 13, 93,117,108, 53, 60,143, 60,101, 55,228, 99, 20,226, 25,223,203,101,154,138,239,115,213, -167, 40,213, 75,196,126,159, 19,161,135, 95,196,204,210,210,230,139,117,159,180, 82,182,108, 40,201,209, 64,251,186, 7,170,150, -187,133, 5, 59, 99, 55, 36,187,133, 2,199,128,235,170, 49, 3,230,191, 26,235, 1,128,158,109, 96, 10, 45, 38,197,237,163,225, -248, 48,159, 79,245,130,233,156, 69, 87,226,228,250,165,116,246,123, 93,211, 12, 30,216,153,181, 29, 46,235,227,147, 85,158, 67, -117,227,222, 89, 46, 80, 64,148,202,100, 17,174,154, 38, 2,107, 67,221,138, 90, 24,220,212,221,183,160, 33,236,145,134, 37,177, - 11,157, 56, 86,195, 30,191,119, 35,121, 59,169, 85, 35,124,130,138, 26, 33,104,144,192, 1,117,255, 40,226, 99,248, 75, 72,249, - 65, 74,188,142, 51, 61,105,212, 69, 59,153, 80, 74,154,118, 8,210, 49,214, 33,201, 30,190,144,200,134,228, 29, 7, 91,192,179, -205,212, 27, 65, 11, 0,136,189, 26,203, 26,174,206,148,194,106,107,119,247,249,194,134, 6,133,137, 10,190,198,124, 77, 79,244, - 15,159, 46,127, 26,132,102,218,116, 37, 83,239, 74,149,185, 11,238,155,185,148, 9, 42,248, 48, 34,179,100, 75,222,153, 96,181, -210, 75, 49, 62,186,243,126,246, 46,200,224,183,119,168, 22, 75, 1,103,193, 72,240,109,187, 54,124,160, 80,157, 8,242, 46,161, -170,210, 71,120, 78,125,101,200, 61, 48,158,163, 50,122,208,239,187,252,189, 40, 87,212,137,116,209, 48,155,151, 11,122,174, 59, - 80,122, 63, 31,156, 46, 23,169,132, 89,113,105,244,229, 94,242,109, 83, 63,146, 15, 71, 98,239,106,205, 94, 78,217,231, 30,171, -110,178,105,198,190, 16, 45,184,166,246, 29, 88, 53, 17,170,189, 49,131,196,198, 43,119, 93,110,126,127,196, 30,140,232,240,108, - 47,162, 33,190, 77, 65, 57,197,138,140, 67, 78,162,201,135, 91, 95,223, 60,158, 29,255,248,244,236,197,181,187, 50, 91,170,231, - 79,158,190,250,248,250, 48, 27, 42,208,193, 85,140,172, 49, 78, 56,246, 92, 82,224,218, 92,145, 30, 43, 79, 39,164,198,158,196, -162,145, 70, 89, 99, 69, 81, 46,139,178,240,227, 64, 15, 2,163,155,180,239,144, 19, 12, 92, 83,243,205, 67,130,184,207,235,121, -107,217, 22,124, 52,232,110,176, 53, 46, 53, 1, 71,113, 94, 57,158, 3,197, 92,252, 19, 58,184,179, 44,105, 58, 91, 47,225,247, - 73,125, 25,238,213,228, 84, 89, 74,228, 39, 92, 14,178, 11,123,233, 65, 34,226,178,174,138,102, 93, 53, 42,134,142,164,233, 69, -106,173, 87,149, 94,121,170, 57, 25,157, 91,182,141,145,188,243, 54,248, 57,105,187,253, 15,220,248,143, 0,124, 93, 93,111,211, - 48, 20,117,226,196, 77,214,177,129, 52,109,226, 1, 77,108, 19,111,136, 23,126, 2,255,147, 63,128,120,229, 63,240,196,135, 4, - 67,211,180, 7,208,144, 6,235,218, 46,109,147,216,177,185,231, 94,123, 42, 99, 76,170, 86,173,138,218, 40,177,111,142,143,207, - 61,167,184, 75, 57, 35,187,243, 98, 2,140,179,164, 15,232, 30, 56, 70, 66, 70, 99, 98,211, 69, 52,249,136,159, 0, 4,235, 52, -100, 61,126,112,185,131,210, 2, 16,215,243,217,121,195,122, 74, 31, 99,204,178, 68, 78, 97, 13, 57,112,228, 88,193,107, 79, 54, -134,135, 1,161, 5,238, 65,249,166,194,109, 0,154, 6,232, 70, 57,204,169, 2,122, 54,243,190,227,220,159,210, 6, 95,193,217, -149,192,101, 70,139,184, 34,211, 78,190, 58,228,241,103,130, 74,237, 84, 46,245,237, 57, 46,194,101,224, 18,159,113, 47,248,108, -152,250,192, 46,175, 73, 54, 67,175,235,197, 68,113, 36,116,242, 17,194, 4, 79,182, 98,225,150,195,123,106,161,186,105,112,147, - 53,154, 15,114, 42,252,108, 47, 68, 28, 73, 35, 58, 15, 87,141,221, 38, 20,149, 67,126,177,243,160,220,218, 40, 45,108,153,194, -114,128,145, 67, 7,191, 77,220,195, 81,129, 10, 65,151,120, 97,217,249, 63,120, 60, 43,121,163,103,133,176,148,232,102, 37,112, -110,225,248,175,149,205,162,200,117, 56,182,128,253, 49,119,199,159, 47,247,170,188, 46, 51, 3,254, 50, 52,218,189,191,104, 39, -173,159, 37, 11,120, 42,244,213,181,175, 39,118, 95, 3, 84, 16, 24,130, 44, 31,168, 74, 53, 61,218, 19,107,118,246,106, 3, 97, - 82,125, 62, 64, 63,243,104,164, 30,110,132,153, 85,139,158,254,213, 21,213, 14,208,238, 97, 92,231,207, 15,138,143,167,136, 64, - 15, 26, 23,129,217, 80,108,177, 12, 1,196,116, 89,104,132,223, 70,186, 57, 43,139,178,231, 12,182, 91,172,102, 88,107, 13, 12, -127,201,119,243,152, 40,154,173, 73,188,132, 45,226, 9, 59, 91,205,139,120,140,207,226,138, 1,220, 51,186,223,100,116, 10,116, - 22,207,125, 28,163,107, 51, 90,181, 43, 21,251, 84, 51, 2,143, 30,142, 15,248,234,227,239,223, 16,152, 42, 59,178,160, 10,101, - 23, 14,225,120,101, 14,197,150,232, 63, 77,102,164, 63,110, 77,139, 31,195,153,233,211, 79,103, 31,114, 81, 90,137,233, 30, 21, - 78, 31, 27,207, 53,147, 53, 90, 58,156,100,234,177,190, 51, 82, 79,124, 76, 5,139,202, 54,154,177,241, 16, 61,220, 59,152, 54, -151, 75,136,176,132, 96, 14,150,227, 92,229,225, 65,235, 6,157,228,190, 52,202,123,219,141,203,162,115, 29, 12,100,244,104, 58, -111, 54,199,249,139,221,125,154, 19,211,215,234,229,161, 58,175,213,245, 23,213, 31,169,230,153,234,198, 49,239,229, 34,121,150, -156, 40,245, 38, 37, 59, 10,110, 16, 55,105,241,195,216,132, 77,188, 58,220, 82,175,182, 56,218,247,167,250,117,162, 78,207,212, -238,111, 53, 50,171,183, 87,239,134,211,165,254,218, 5,215,244,253,226,233,147, 35,235, 44,161, 60,199,119,130,174,228,134, 25, - 95,181,115, 78,205,246,157,100,243,164, 40, 38, 47, 65, 72, 40,196, 24,135,177, 16, 51,177, 97, 76,133,224,251, 72,153, 8,128, -247, 9,201,199,183,104,200, 46,212, 96, 44,235,126,173, 57,229,158,142,211,108,182,156, 12,116,142,255,245,154, 85,255,246,252, - 39, 77, 10,111, 88,202,131, 23,197,189, 16,154,122,219,236,236,214,143,105,176, 35,128,206,182,160, 63,135, 30, 13,171, 42,226, - 55,154,106, 6,251,154,237,160,108,218,216,203,125,138,140,190,209, 13,223,225,116,172,194,253,182,245,127, 4, 32,236, 90, 91, -155, 8,162,232,204,236, 78,118, 19, 93, 83,124,180,241,139, 34, 42, 8,130,159,252, 46,254,118, 17,196, 63,224, 19, 65,164,172, -134, 66,140, 49,251,152,199,142,247, 53, 49, 69,138, 80, 74, 33,133,116,155,185,119,206,189,247,156,123, 32,105,152,203,219,196, - 8, 8,107,177,207, 22, 77,147,129,244,218, 24,214,175, 34, 95, 17, 71, 59,180,126, 29, 94, 2, 92, 48,171,225,171,172, 0,139, - 33,161,157, 37,110, 52, 55,230,200, 44,116,182,163,147, 90, 27, 31,136,229,182,240, 22,216, 85,228,247,213,218, 67, 77,128,227, - 32, 28,124,215, 84,163, 97,150,197,161, 19, 90, 77, 98,111, 19,215, 86, 26, 75,235, 56,160,158,129, 67,237, 38, 15, 17,216,238, -191,251, 68,222, 32,152,241,197,191, 41,223,222,135,253,105,178,130,108,134, 41,222, 0,130,128, 66,105, 31,127, 41, 41,178, 15, -130, 85,190,124,115,159,138, 56, 17, 58, 95,210, 82,209,104,157,101,186,250, 56, 22,153, 23,200, 63, 48,225, 29, 25,197, 44, 68, - 73,234,100,174, 1, 14, 47, 74, 61,183,133,173,237,181, 69, 9,224,235,124, 51,158,111,250,118,235,215, 59,239, 6, 63, 58,136, -128, 56,194, 83,121,188,188,230, 6,242,163,174,140,106,102, 26, 32,127,133, 13, 19,228,127,193,179,243, 10, 95, 77, 45,151,142, -162,110, 71, 41,165,204,201,189,207,248, 2, 94, 93,135,212, 78, 9,176,232, 58,166, 54,196, 54, 32,111,210,101,132, 82,146,117, - 76, 99,141,213,105,187,143,189,159, 28,249,224,250,144, 48,107, 79,178,181,162,214,105, 94,164,170, 32,201, 43,234,161,212,173, - 26,211,209, 0, 88, 57,170,166,134,207, 72,117, 46,141,147, 94,157,152,139,109, 68,213,189,214,182,184,206, 22,126,116,156,224, -128,216,229,226, 38,113,254,240, 95,229, 41, 69, 74,118,251,171,184, 32, 22, 74,129,160,115, 18,111, 63, 3, 21,186,247, 3, 65, - 98, 33,236, 42,246,114,196,243,195, 88, 21, 49,110,145,152,128,200,178, 35, 69,238,119,104,112,122,182, 92, 33, 6, 20,162, 35, - 85, 84,134, 44, 31, 83,112,112,175,202,208, 5, 63,105, 56,105,148,196,249,131,199, 63,168,178,117, 0,244, 98,224,114,170,198, - 48,208, 70,123, 28,228,113,211, 28, 93, 68,202,138,251,115, 71,207, 32,223, 78,151,171,193,119, 60,138,129,155, 67, 17,170, 48, - 25,130, 24,202,241, 40, 43, 97, 11, 89,195, 45,120,195, 81,195,113, 52, 43,102, 36, 88, 85, 70, 22,107, 40, 23,198, 30, 50,190, - 18, 53, 0,156, 8, 23, 66, 65,157,201, 66, 31,153, 83, 81, 90,220,245,187,128, 34, 97, 67, 75,101, 48,233,184,104,182,126,124, -254,242,217,141,199,106,243, 65,217,119,234,238,103,101,222,171,211,175,234,206, 79,245,227, 66, 13, 22, 19,125,175, 17,145, 31, - 76,104, 75, 58,105,117, 38, 95, 29, 56,124,240, 59,155,111,170,125,171, 62,190,158,202, 79,254, 97,103,158, 46,244,147,141,122, -113,255,209,171, 47,111,116,225, 12, 84,244,117, 5,101, 96,180, 54, 26,148, 65, 69,114,102,135, 51,182,168,155,110,232,120,179, -189,244,218, 18,167, 54, 81, 2, 78, 83,238,179, 8, 17, 14, 67, 27,128, 10,238,221,156,100,233,122, 98,229,121,158, 88, 38,177, -164,151,246,141, 44, 9,253,223, 22,129,203,219,216,137,186, 52, 93, 53,188,204,220, 10,125,105, 73, 23,145, 34,249, 28,162, 8, -191,196,126, 11,102,190,219,243,179,123,205,131,170,180, 67,112,123,223,255, 14, 3,178, 63,208,225, 14,162,220, 65,168, 57,156, - 85,185, 40, 27, 70, 10,150,205,106,113,230, 70,146, 85,101,231,145,246,250,252,211,109,191,138,199,115,176,237, 81,127, 4, 96, -235,218,121,155, 8,130,240,238,222,249, 30, 62, 91,128,133,132,132,162,132, 10,201, 29,162,165,231, 55,240, 99,248, 81, 72, 20, - 72, 52, 20, 52, 32,129,160,129,130, 84, 20,128,148, 0, 9,246,197,247,216,221, 57,230,177,123,190, 40,110, 83,228, 44,159,119, -246,155,153,239,113,200,159, 64,143, 68,159, 16,151,153,224,245,194, 58, 35,109, 40, 47,141,196,168, 32, 65, 64, 67,226, 89,250, -196,219,158, 14,160, 84, 51, 48,206,224,237, 4,157,132, 20, 89,162, 19, 76,101,234, 66, 79,231, 73,171,180,121, 52,166, 31, 82, - 78,112,200, 85,226,200,124, 48,164, 25, 34, 72,199,135,101, 52, 30, 53,142,102, 42, 46,211,249, 42, 47, 27,246, 46,167,190,158, - 53,153,151, 29, 86, 33, 55,165, 47, 78, 59, 18, 19,214,107, 49, 18,136,134, 13,192,148,158,140,138, 59,205,143, 32, 10, 92,163, - 93,160, 30,151,171,225,123, 8,152,125,255, 74,135,225,186,115,217,168,103,228, 97,172, 24,187,114,125, 31, 84, 81, 84, 0,112, - 43,107,150,233,176,154,153, 69, 69, 38,107, 23,141,109, 26,191,237,220,214, 14, 41,107, 85, 16,212,209, 25, 50,170,177, 52, 88, - 39, 88,141, 63,231, 12,107,186,233, 41, 35,141, 73, 27, 92,152,114, 46,128, 0,129, 29,223,196, 16, 62, 9,102,234,246,203,225, - 16, 33, 56,254, 8,236, 13, 14,175,143, 7, 21,129, 81,221,248, 63, 26,191, 88,252,244,252, 10,248, 41, 88,199,243, 20,145, 42, -137, 27,182, 94,223, 46, 13, 62,253, 14, 37,126,168,186, 5,196,245,228, 44,143, 37,190,247,155, 6, 11, 28, 45,205,157,211,121, -153, 60, 89,155,183, 95, 58, 34,193,170,142, 52,108, 41,121,146,144,213,149,239,234,182, 23,119, 26, 90,128,192, 62,199, 94, 79, -187, 72, 74,110,176, 62,106,182,241,195,212,221, 70,120, 19,139,124,222,180, 59,185,100,197, 25, 67,130,173, 53,111, 32,215, 71, - 15,191,253, 60, 29, 13, 6, 16,125, 0,157, 39,199,106,213, 73,151, 69,118,246,158, 11,110,146, 33, 48,207,230,255,176,105, 99, -174, 62, 93, 57,172, 46, 38,134,146, 73,251,193,150,121, 73, 38,239,224,218,222,153,144,208,148,112, 67,199, 51,100,128,142,124, -131, 37, 84, 86,134, 43, 32, 28, 56,188, 36, 47, 54,231, 82,114,103,132,254,169, 33,199,218,148,176,140, 77,226, 90, 89, 51, 40, -198,242,100,162,167, 24,219, 74,207, 48,207,138,166,239, 16,128, 39,102,156,151,146,225, 88,107, 91, 82,185,177,103,170, 54, 97, -252, 37,196, 77,230, 27,153, 56,110,212,162,169,209,194,206,160,197, 20, 94,150, 62, 55,217,167,205,199,151,175,214, 79,159, 63, - 62,126,166,142,191, 43,245, 90,189,120,163, 62,191,227,130,142,255,112,169,138,133,218,174, 84,117,164,202, 19, 53,127,160,182, - 11,108,198,213, 37,113,116, 84, 13, 49,228,225,183,114,103,244, 6,253,169,239,206,161,180,253,153, 69, 68,162, 30,221,243,191, -190,102,239,127,124, 40, 22,197, 5,158, 76, 60,168, 80,247,118,103,177,144,121, 70,240,131, 4,240,169,191, 49,225, 86,143,129, - 29, 49, 7,107, 8,128, 59, 76, 87,116,236, 53, 7,218, 78, 93, 9,155, 89,200,237,210, 37,197, 32,242, 24, 82, 26, 56, 9,135, -113,174, 62,108, 22,181,183, 78, 23,163,108, 61,209, 55, 77, 39, 57, 21,167,134,249, 16,252, 36,100, 72, 22, 88,211,125,111,120, -109,201,247,185,214,203,236,238,253,234, 36,211, 9,162,207,153,209, 85,146,144,194,111,240, 68,230,118, 59, 75,140, 15,218, 80, - 66, 92,154,230,204,102, 0,250,123,120, 30, 37,255, 89,128, 64,139,191,102,187,119, 99, 37, 16,147,225, 38,190, 5,255, 5,224, -235, 90, 86,156, 8,162,232,173,234,238, 60,122, 18,144,204,198,133,130, 4,193,197,224, 70, 65,220,234, 94,152,127, 17,252, 14, -119,126,131, 11, 23,254,130, 75,113, 20, 65, 97, 80, 70, 6, 97, 28,145,153, 73, 38,147,126,164, 83, 93,229, 61,183,170, 59,137, - 70,201, 46,105,146, 78,119,245,173, 83,183,206, 35,166,191, 93,210,155, 22, 77, 3,186, 93, 26, 13,187, 49,131, 14, 6, 83,203, -162, 46,197,255,200,200,192, 1,104, 40,109,175,167,227, 94,156, 38,120,210,133, 13,136,188,142,218, 66, 69, 90, 25,207, 37,111, - 44,188, 49, 66,240,181, 81,226, 1,176,164, 30, 11,193,159, 98,184, 47, 71, 93, 10,230, 36, 18, 84,198,232,207, 74,135,196,122, -170, 27,191,242,202,248, 22,102, 4,241, 43,186,158,147, 69,230, 54,205,251,125,198, 94,173,214,148, 0, 1, 5,168, 70,142,134, -203,234, 86,214, 58,237,237, 14, 2,166,166, 67, 21, 70, 94, 83,217,131,165,148,218,140,231, 94,171, 78,174,141,247,211, 33, 14, - 14, 98,206,221, 30, 93, 79, 9, 4,231, 4,148,228, 73,102,166,133, 49,181,203,192,220, 80, 48,232,211, 56,155,203, 37,218, 47, - 89,141,154,149, 51,250,229,127, 87,171, 42,170,241,142, 86,253,136,209, 46, 72,147,252, 49, 79,247,115, 73,228,168,164,136,123, - 19,192,214, 5, 86, 55,254, 10,186,177, 8,252,207, 34, 78, 55, 96,255, 44,135,141,140,197, 46, 28, 87,109, 73,110, 39,149, 9, -189,177,146, 53, 14, 95,234,105,225,134, 29,189,211, 81,131, 24,241, 45,217,210,117,156, 29,116,181, 88,159, 33, 72,132,239, 13, - 15,198,188,176,163,145,126,124, 55,121,251,117, 56, 43,231,125,225,120, 44, 84, 45,100, 1, 37,102,191,178, 38,146,134,130, 76, - 38,130,177,108,112,140,177,255, 60, 85, 40,236,138,170,224,113,151,118, 83, 7,162,125,165,125,164,181, 14,185, 10, 71,167, 71, -218,107, 61,229,161, 52, 72,114, 68,215, 54,152, 20,160,119,235,100,212, 65,159,209, 73, 0,165,231,197, 85,206,103,167,188,120, - 28,119, 62,214,137, 17,196,132,246, 81,101,166,243, 11,191, 16,148,164, 72,132, 5,138,152, 8,125, 67,158,108,224,125,182, 40, -219,168, 48, 64, 56, 30,203, 36,178, 51,172, 30,208,156,226,131,211, 36,157,139, 33, 65, 36,156, 28, 97, 36, 97,153,168,209,165, -140, 37,138,146,248, 66,241,105,150,139, 66, 54,226,212,104,176,251,243,242, 84, 41,106, 76,224,189,160, 78,249,205,100,217, 18, -208,146,137,162,107, 37,154, 47, 45,182,152,145,109,118, 44,162, 77,115,108,159,100,204,243,218, 98, 28,221,126, 50,190,247,225, - 13,125,124,109,110,237,197,119, 30,208,254, 67,218, 79,168,252, 70, 7,239,233,213, 33, 29, 28,211,143, 79,120, 72,246,174,209, -211,251,244,104, 76,135,223,233,249,103,250, 82,208,172,192,245,236,197,212, 79,104,236,104,160, 41,203, 34, 83,218, 19,115,126, - 76,179,151,147,119,153, 57,121, 49,126,118, 69,191, 46,204,153,227, 90, 1, 99,120,232,193, 80,212,141,241,180,101,116,165, 64, - 65,242, 26, 31, 87,251,226,110, 55, 28,211,197, 90, 77,114,115,125,204, 89,107,232, 40,104, 29,100, 25, 79,115,241,234, 83,111, -243, 64, 33,196, 45, 8,152,212,118, 61,146, 91,181,204,183,229, 58,217,149, 99,151,106, 81,208,218,129, 34, 85, 13,254,119, 42, - 4, 46,181,253, 25,111,229,130,165,117, 39,234,223,220,185,129,192, 57, 91, 79, 75,174, 91, 80,231,100,139, 44, 55,121,238, 10, - 33, 46,152, 37,180,231, 66,161, 8,191,204,136,174,195,223,105,169,157, 60,148,253, 51,242,211,109,146, 71, 60,183,195,110, 53, - 55,252, 45, 0, 95,231,146,219, 68, 16,132,225,234,199, 76,252,148,101,130,132,226, 72, 94,192, 22, 4,217,103,137,114, 4, 86, - 92,134,179,112, 0,118, 92, 1, 22,236, 88,176,204,138, 40,130,216,137, 31, 99,143,103,166,167,233,191,170,103,236, 24,132, 87, - 30,203,146,109,185,167,186,186,234,175,239,183, 71, 63,207, 71, 52, 90,155,234, 32,121, 31,216, 65,216,120,243,114, 1,105, 57, - 48, 27,117,107,156,105,248,120, 88,106,179,171,138,212,118,134, 73,207, 96, 76, 41, 9,217,120,120,101,227,193, 29, 66, 71, 8, - 84,104, 22, 8,162, 33, 39,179,219, 53,202, 78,142,149,145, 94, 85,141,155, 74,146, 96,241, 87,174, 8,203,247, 4,166, 67,186, -163,108,184, 15, 19, 99,251,166, 27,222,182,227, 33,210, 62, 56, 89,102,227,114, 2,254,208,153,104,194,232, 91,224, 87,131,203, -111,170, 51,109,215, 57,114, 27, 26,204,153,218, 11,217,155,251, 59,158,179, 77,140, 63,113,144,166, 73,160,188,214, 7,234,247, -122, 79, 46,219,127, 14,107, 70, 90, 99,128,113,151,158,117,117,199,232, 69,238,110,102,171,144, 55,174, 10,212,178, 75,209,164, - 43,186, 47,217, 38,137,239,200, 16, 85, 55, 62,174, 41,136,136, 42, 58,133, 48, 21, 60,128, 45,111,169, 80,179,192,181, 38, 82, - 65,164, 48,154, 55,127,159, 36, 29,169,240, 68,154, 75,245,223,248, 46, 35,209, 25, 43, 9,104, 7,242,251,210, 80, 71, 99,215, -233, 89,175,156, 94,131,230, 22, 46,125,138,110, 17,109, 11, 28,177, 84, 2, 57, 77, 5, 91, 87, 93,186,144,117,232, 36,129, 22, -104, 9,191, 10,212,212,126, 45,234,233, 19,243,250,121,246,229,135,115,245, 14,186,251, 16, 93, 25,157, 88,201,152,158,178, 33, - 81, 48, 90,108,139, 84,170, 77,191, 55,156,111, 30,184,108,254, 15,141,164,150,218,132, 97, 51, 17, 79,224,200, 67, 60,142,238, -181,230,163,165, 22, 12, 70,164,126, 55,246, 99,142,131,187,143,113,145,129,214,120, 22, 62,119,212, 27,205, 86,115, 9,184,164, -246, 66, 99,244,129,234,104, 49, 17,238,201,253, 72,149,215, 39,108, 30, 4,121, 3, 31, 10,207,199,103,243,213, 61,138, 71, 81, - 72, 43,217,187,151,110, 83,212, 51, 71, 93,187,103, 56,137,146, 88, 21,171,123, 70,139,213,154,139,128, 3,202,118,219,144,179, -135,213,142, 42,163,247,191,151,183,162,176, 85, 58, 30,166,149,111,109, 10,100,127,196, 16, 92,154, 26,152, 89, 26,150,125, 73, - 17,211, 71,206,181,111,199,235,165, 33,138,189, 0,245,209,183,250,138,102,116,241,138,108,101,127,222,249,207,107,160,151,244, - 5, 77,222, 81,239,138,222,111,233, 67,202, 76,201, 59, 26, 78,136, 94,176, 29,200, 55,186,252, 72,167, 55,244, 80, 80,153, 35, - 36, 91, 75, 83, 69,231, 3,178, 57, 77,234,228,205,120, 58,122, 74, 52,122, 25,150,227,247,235,219, 79,215, 95,179, 44, 3, 78, -168,230,137, 20, 87,150,200,182, 49,127, 36, 96,123, 68, 98,102, 79, 71,128,107,140,209,141,114, 93, 78,192,218, 14, 59,195, 25, -250, 97,237,100,144,244, 53,112,209, 77,251,121,201, 34,222, 56, 43, 20,133,125,190,229,254,213,135, 74, 19,181,239,133,186, 8, -103,105,211,224, 67,194,139, 8,243,212, 95,147, 77,109, 49, 70, 61, 18,206,196,175,202, 39, 49, 47,101,109,110,219,155,179,222, -180,107,187,185, 43,138, 98,147, 87,235,109,145,101,229, 6, 51,152, 97, 89,161,231, 5,171, 50,201, 3, 90, 48, 23,107,163, 43, -127, 80,134,240,143, 74,253,199,210,123,137,120,234, 72, 68,121,240,248, 35, 0, 93,231,178,219, 68, 16, 68,209,234,121,216,158, -241, 35, 9,196, 73, 88, 0, 17, 98, 3, 10, 31,193,255,177,231,127, 96,201,138, 5, 66, 66,138, 16, 34, 68,150, 2,241,120,108, -247,188,186,167,232,170,238,121, 56, 3, 81,150,177, 21,121,218,213,221,183,110,221, 19, 12, 14,239, 94,211,194,114, 61,253, 56, -152, 22, 74,238,171, 61, 79, 83, 90,126, 45, 79,220, 56,194, 17, 67,175, 53, 5, 1, 82, 99,142,176,176, 35,235,118,207, 73,149, -117,202, 26,185, 11,188,150, 70,142, 77, 51,147,222, 81, 83,176,175,121, 19, 58, 47,133,140,208, 38, 44,186,176,177,101,212, 56, -154, 5,164, 59, 7, 4,156, 84, 71,227,216, 92,140,205,106,217, 85,245, 34, 52, 95,138, 96,234,121, 63,170,212,154, 93, 69, 51, -208,142,131, 52, 71,236,170,153,223,195, 25,246,104, 27, 77,113, 71, 43,125,130,227,160,137,214, 45,234, 6,191,156, 65,146, 47, -225,194,229, 57, 91,158,123, 43,208, 67,151,153, 18,143,240,217, 66, 76, 60,248,147,228, 55, 91,149,113,240,185,165,164, 77,248, - 5,155,230,252, 79, 70,148,166, 94,171,134,147,103,202, 81,198,248,112,159, 82,127,237, 7,194,102, 32,254,203,178,249,231,245, -161,234,146,247, 30,182, 24,132,251, 63,248, 81,141,198, 90,240,238, 18, 1, 36, 26, 30,213, 24, 33,175, 62,129, 19, 64,105,238, - 25,218,147,140,127, 50, 85,126, 20,212,177, 22, 82, 96, 37,188,199, 17,173,208, 66,195,220, 39,171,138,141,133, 48, 87,180, 92, -193,237, 6, 79,102,222,219, 55,163,143, 95, 84,161,131,128,164,113,254,173,105,110,121,121,252,100,117,127, 59,157, 28,165, 89, -194,110,242,122,155,167,180, 47,114,160,150,195, 21,187,117, 79, 61,126, 55,130,128, 22,220,205,183, 96,119, 25,246,220,108,167, -176, 57,135,100, 84, 55, 7, 5, 31,152, 5,203,186, 85,155,148,135, 76, 51,231, 48, 41, 92,239,214,190,232,228,234, 38,110,136, -182,139,120, 20,203, 66,154,131, 75, 20,206,164, 57,165, 8,103, 73,204,171,194,226, 48, 60,182,162,167,251, 77, 20,142,101,185, -243,221,142, 36, 58, 12, 88,237, 82,161,173, 95,207,111,146, 5, 68,219, 28,182,173, 3,171, 1, 90,181,133, 45, 55,230,100,195, - 87, 83,122,110,243,201,172,160, 12,246, 10, 90, 65, 31, 6,174,104,194, 6, 61,191,249,253,179,205,238,235,172, 28,221,115,103, -122, 42,178,238,128, 20, 54,247,226,229,133,252, 5, 95,223,235,232,210, 95, 94, 42,121, 28,222, 7,112,183,130, 15,159, 9,186, - 11,175,204,170, 3,125, 14,245, 25, 25, 99,174,114, 90, 9,103, 87,112,241, 14, 94,155,154,180,135, 83, 9,170, 36,154,237,108, - 13,227, 5, 92, 38,240,244,132,156, 51,184,130,235,111,240,233, 59,158,167,243,165,127,122,231, 93,151,149, 57, 17,170,138, 56, - 5,154,109, 19, 84,215,231,241,194,124,146, 50,219, 90,143,170,179, 51,218, 22,169,211,226,221,144, 39,237, 12, 89,210, 80, 82, - 29,128,150,211,242,232, 9,234,106, 91,215,181,227,109, 56, 20, 42, 98,191, 47, 57, 56,246,214, 46, 45,177, 59,254,160,120, 72, - 90, 82,221,119,231, 96,108, 21,224,127, 49, 47,158,235, 31, 33,139, 52,172,173, 77,195,197, 60,152,234,186,148, 69,154,100,233, -190,218, 81,101,199,162, 36, 31,156,230,178,174,173,234,208,203,131, 4,238, 56,176,238, 77,245, 64, 33,252, 3, 72,210,155, 23, - 65,113, 72, 76, 24,230,208,252, 21,128,178,107,233,109, 26, 8,194,251,242, 35, 78,221,180, 21, 41,149, 42,161, 10, 9,169, 82, - 43, 14,220,144, 64,226,206, 25,113,226, 15,240, 7,249, 3, 21,226, 12, 10, 39,132,132, 74,120, 84,180,228,213, 36,235,120,119, -217,153,241,250, 1,185, 16,229, 18, 71,137,237,181, 53,158,249,102,190,239,171,248, 77, 45, 19, 15, 78,216,165, 79,180, 1, 76, - 98, 42,151, 57, 72,110, 58,131,123, 3, 77,159,218,240, 40, 84, 37, 2,199, 63, 1,199,236,171, 52, 18, 73, 36,208,159, 12, 18, -116, 91,216,114,229, 54,132,110,163, 25, 49,179, 85, 27,144, 8, 29, 8,136, 56,232,251,144,206, 61,114,243,176, 59, 33, 68, 95, -166, 42,138,123, 34,246,233,205, 32,206, 82,149,237, 37,253, 8,237,230,111, 13, 16,149, 11, 87,104,107, 63,220,188, 47,204,122, - 89,222,234, 82,175, 0,153, 55,144, 86, 34, 58,103, 2,205,173,117,117, 36,103,141, 72, 68,117,214, 33,184, 55,189,190,144,182, - 11, 66, 89, 29,239,120,124,252,205,203, 40, 89, 77,108,174, 22, 29, 6, 45,252,179,232,225, 29,238, 15,241,219,111, 61, 54, 96, -151, 75, 9,117,138, 63,200,241,227,154, 85, 26,221,181,160,112,132, 9,120,129, 95,213,116, 83,213, 66, 90, 92,144,148,137,112, -227, 52,232, 0,186,182,129,215,255,188,232,234, 36,181,231, 42,190,115, 95,131,227,201,204,144,190, 29,225,186,244, 36, 31,166, - 50, 6, 90, 14, 14, 7, 72, 31, 10, 65,131, 56,142,212, 78,204,178,158,152,104,174,173, 75, 99, 95,243, 73,205, 92, 22,241,187, - 3,185,210,246,237,200, 87,100,160, 66,105,161, 26,128,157,228,217,193,213,244, 39,225,150,120, 75,216, 88, 38, 2,169, 84,126, -229, 23,122,134,245, 83, 71,211,148, 28,203,176,131,170, 80,207,142,147, 27, 42,167,224, 46, 73,140,139,159, 29,159,143, 46, 63, -162, 98, 0, 36,136, 0,121,155,194,146, 94, 5, 22, 95, 36, 92, 97,183, 8, 59, 7, 89, 18,206, 78,143, 79, 71,151, 35,137, 67, -241, 4,236, 82, 23, 7,203, 8, 74,191, 57, 65,219,232,106, 70, 86,112, 45,179, 95,244,172,107, 28,127, 88,139,201,170,176, 5, - 21, 44, 94,169,121, 32, 43, 13, 62,108,178, 10,138,251,142, 55,246, 3, 21, 62, 67, 81, 4,236, 22,170,126, 3,202,248, 75,152, -146,136, 21, 24, 79, 71,161, 21,129,143, 28,212,234,195,192,230, 35,235,209,193,209,247,155, 95, 82,166, 43,107,158,236, 63,125, -245,252,181,251,204, 46,222,177,235,229,156,239,138,249, 94,210,123,172, 62,221, 99,203, 67, 54,190,207,174,177, 59, 34,115, 8, - 69,114, 7,219,127, 37,219,160,169, 75, 89,130, 16,133,209,240,176,200,190,192,159, 31, 94,176,225,143,133, 92, 78, 30, 13,216, -179,221,225,208, 36,241, 21,139,246,217,139, 55, 47, 65,143,200, 44,180, 1,143,247,141, 89,131, 41,171, 5, 37, 9, 31,240, 9, - 37, 67,241, 18, 10,238,150,162,105, 69,223,175, 6, 71, 92, 67,248,108, 88,141,238,100,120, 50,158,124, 21, 78,173, 54,203,192, - 99,114, 33,198, 59,190, 77, 34, 70,116, 3,180,170,103, 10,107,223, 54,195, 90,252, 2, 22, 84,189,254, 21, 36,104, 10,120,214, -153,106,133, 50, 18,102,102,240, 38,125,176,123,214,147,241, 84,207,166,235,201,180,152,195,116, 56,172, 28, 42,119, 96,100, 55, - 44,136,206, 55, 14, 80,162, 70,128,125, 49,108, 27, 96,213,117,113,224,250, 32, 93, 55,103,223, 66,103,253, 35, 0, 95, 87,176, -219, 52, 16, 68,103,215,142, 93,167, 77,169, 21,135, 20, 80,149, 83, 17,112,225,196, 55,240,183,112,226,198, 13,196, 1, 14, 21, -202,161, 21, 42, 32,164, 52, 41, 77,169,147,208,216, 74,156,236,178, 51,179,187, 78,105,213,168,167,180,117,172,205,238,120,102, -222,155,247,106,254, 12, 71, 58,238,185,135,228, 63,193,228, 25,107, 10,110,233, 40,106,211, 68,109, 83,180,138,144, 46,179, 53, - 27, 52,118,231,122,222, 84, 49,161,234, 63,237,224, 21, 33,132,188, 70, 75,138,117, 33, 35, 65,206,244, 59,180,235, 69, 19,231, -152,127,145,105,169, 68,247,178, 4, 61,163,163,144,158, 28, 38,215,155,175,150, 91, 33,234, 25,148,235,242,252,122,168,184,207, -167,205, 15,238,147, 53, 79,197,107,223, 93, 81, 27,208,157,244,152,136, 77,166,172,176,155,176, 16,184,251,206,164, 29, 42, 9, - 92,105,204,164,102,247,107, 78,184, 44,139, 42,224,176, 46,157,222,152,249,228, 56,208,175, 58, 98, 90, 84,167, 87,139,145, 70, -191,189, 45, 96, 59, 76,209,134,160, 13,225, 62,132, 49, 4, 68,131,209,129,163, 17, 43, 79, 93,119, 91,142,109, 24,184,160,100, -130,218,194, 57, 84,202,155, 1, 93,222,219,135,185,255,165, 28,250,234,165, 2, 52,216, 66,145,116,234,233, 96,155,236, 94,154, -237, 73, 24,175, 52,185,149, 9,229,212,190, 87,176, 29,225, 90, 87, 90,180, 34, 73, 65, 28,235,237,164,129,146,147,121,169,155, - 81,112,248, 56, 24,140, 77,129,142,122,210,152,173, 35,217,124, 78,203, 37, 56, 81,226, 1, 16,115, 12,144,160,178, 94, 48,161, - 84,187, 89,113,106,168,155, 11,198,113,152, 40,212,243,225,206,181,228,225, 9, 14,238,146,220,102, 91,201,131,243,124, 68,253, -104,193,225,213, 92, 55,221,222,123,126,240,194,148, 11, 36, 48,170, 54, 75,245,219,128, 60,171, 26,140, 9, 23, 69,156,204, 73, - 36, 52,204, 14,140, 19, 4,137, 36,251, 96,240, 0,139,211,236,182,169,129,240,104, 59, 55,141, 89, 67,202,182,112, 36, 75, 93, -129,253,103, 54, 89,145, 76,181,178, 85, 8,210,105,124,200,224, 99, 40,253, 96, 10, 61,161,236, 31,144,195, 9,217,174,226, 68, - 43,251, 91,210,170,216,158,144,174, 19, 21, 4, 57,180,106,239,118,166,197,108, 55,105, 85,171,245,183,242, 71,255,244,164,247, -168,247,242,245,222,179, 44, 62, 25,142,222,124,125,127,212,239,158,125,108, 22, 31,160,251, 25, 14,143,224,233,119,232, 14,160, - 56,134,230, 0,228, 37, 60,201, 33,155,194,254, 12,228, 16,210, 28,218, 51,200,254,192,195, 51,104,149,208,253, 53,203,254, 14, -210,101,209, 42,163,106, 2, 89,183,217,255,164,222, 30,191,251, 9, 95,204, 87, 89,225, 16, 75,165,212,194,228,240, 7,157,222, -100,126,101, 83,113,176, 41, 59, 41,162,113, 91, 94,123,185, 68,237, 50,110, 59,192,196,201, 59,238, 44,108, 82, 79,138,124,185, - 50, 71,126,105, 35, 59,189,175,107,110,184,118,101,180,226,131, 41,106,165,110,155, 45, 43, 15,173,121, 98,196,205,224,238,188, -157, 68,109,206,100, 47, 79,247, 46,100,221, 37, 19,172,227, 34,157,155, 36,236, 68,233, 78, 35,253, 61,191,188, 40,199,197,234, - 26, 39,234, 49,172,163, 40, 34, 11,229,174,111,129,189,158,130,231,106,205,224,174,135,212,127,170,150,155, 55,126,247,217,255, - 39, 0,105,215,178, 26, 69, 16, 69,171,186,186,166,123, 30, 61,142, 49, 19,178, 24, 33,154,149,136, 27, 63, 64,197, 95,115,239, - 23, 8, 34,238, 93,186,114,109,192,133,139, 8,234, 66, 80,130,198,134, 73,130, 78,232,103, 85, 87, 89,247,214,163,123, 2,186, - 49,129,132, 12, 51, 19, 58,233,190,125,238,185,231,158,179,133,223, 35,103,107, 9,227,209, 8,241,251,136,166,145,221, 47, 71, -113,146,118, 29,140, 14,148, 86,136, 1, 25, 25,252, 30, 27,228, 14, 99, 88, 48,122,196,173, 17,208, 1,193,162,140, 68, 7, 24, -136,222, 5,140,101, 23,143, 96,107,159,113,188,133, 88, 67,206,208,101,131,221, 13,131,144, 26,131,226, 57,136, 33,249, 78, 50, -203,120, 58, 51,159,241,184,233, 64, 70, 52, 97,113, 33, 65, 50,251,117,115,242,179,248,209,144,170, 16,149, 85,149, 34,120,239, - 44,126, 87,161,165, 25, 88,195, 6,203, 48, 91,209, 93, 70,149,213, 50, 88,213, 16, 37,195,125, 19, 22, 28,121,182,187, 52,234, -205,171,124,119,101, 61,100,157,232,251,222,117,125, 89,182,223, 74, 48,163, 19,136,193,111,192, 87, 54,161,124,202,216, 50,225, -217,136,225, 38, 42,169, 68,183, 46,235, 83, 85,175, 17,140, 75, 79,156, 41,175,128,212, 65,197,232, 79, 77,203,221, 39, 94, 10, - 25,248,250,255,255,176, 16,126,230,205,163, 37, 62,146,250, 65,174,198, 12,216, 57, 76,126,105, 10,178, 24,164,233,147, 40, 75, -227, 66, 27, 20,207,204,127, 72,226,216, 29,184, 51, 74,175,141,233, 70, 0,242,221,203, 56, 39,234,232,163, 44, 90,142, 91,185, -216,136,194, 61, 67, 47, 38,187,235,223, 57,154,244,224, 61,191,159,106,192, 95,127, 49,221, 61, 47,206, 24, 86, 99,120, 87,141, -133,156,134,218, 26, 49, 71,158, 69, 62, 1,152, 88,248,107, 5, 44, 18, 7,113,230,100, 48, 53,176,105, 43, 76, 41,112, 48,241, - 31,161, 91, 22,221,107,159,229,224, 20,200, 17, 26, 85, 6,211, 0,255,139, 66,108, 8,118, 11,168,172,236,173, 9, 7, 58, 43, -124,185,249,249, 46,120, 5,127, 98,254, 16,230,105, 86,180, 37,179,199,130, 92, 83,236,168,243, 64, 9,134, 48, 53,208, 84, 91, -119, 84, 68,253, 4,219, 92,224,114, 98,140, 69, 77, 32,245, 27, 88,157, 36, 30,153,170, 90, 54, 21,144, 24,170, 19,246,180,132, -231,196, 6, 75, 40,115,197, 49, 62,231, 75,193,179,157,197,193,195,213,131,251,183,111,141, 47, 41, 89,145,207, 57,121,125, 68, -222,124, 39,239,214,228,188,129,145,201,163,125,242,226, 49,217, 63, 36,199,199,228,233, 23,146, 11,216,129, 74,113,110,100,240, -123,181,145, 52,142,243,211,103, 93,253,158, 74,105,122,212, 92,159,220, 36,171,231,135, 47, 95,137, 39, 31,200,219, 78, 54,141, -170,164,170,219, 78, 72, 92, 20,151,144,179, 65, 61,141,110,215,244,157, 24,198, 87,246, 1,114, 87, 22, 0, 64, 5, 71,127, 79, -189,205,194, 99,101, 87,116,160,161, 84,131,185,234, 21,123, 71,119,221,135,155,186, 85,253, 14,178,120,244,128,229,240,189,196, - 80,186, 67, 8, 76,245, 65, 46, 85, 71, 61,195, 27, 81, 95,223,205,247,229,116,239,162,184, 56,200,238, 84, 77,253,171, 61, 19, -210, 84,118,129,176, 29, 8, 25,137,145, 90,180,119, 58,235,101, 57,180,119, 27,183,179, 22, 80,162, 93, 97, 11, 2,132,239,122, -193,232,223, 84,240, 46,116,246,143, 0,164, 93, 61,143,211, 64, 16,221, 93,175,147, 56,137, 34, 43,225,164, 35, 28, 18,232,160, - 57,157,160, 65,162,228,127,208, 82,241,127,248, 11,212,208, 81,210, 82, 81, 1,210, 73, 64,115, 10, 81,114,119,185, 64,176,207, -246,122,119,241,204,236, 58,107,233, 58,154, 52,150,236,141, 63,102,103,222,188,121, 79, 6,232,189,123,233,133, 91, 52, 98, 83, - 70,160, 58,130,155,137, 14, 34,187, 65, 36,139, 38,128,232,163,138, 64, 19,195,130,153, 82, 12,224, 17,152,221, 26, 44, 67, 92, -197,100,140,244, 47,108,237, 71,111,177,245, 90, 99,139, 47,130, 70,129,129,214, 93,179,254,230, 51,214, 90, 11,116, 54,238,113, -148,152,176, 38,175, 84,243,106, 54, 85,124, 81,171, 36, 2,199,190,178,174, 47,202, 53,228, 91,218,201, 57,180, 35,238,109, 56, - 23, 84,137, 7,162,179,220,209, 28, 24,120,176, 55,103,171,110,240, 99,185, 37,184,139,125, 78, 22,234,134,219,253,147,160, 91, - 88,239, 69,227,133,144, 73,146,206,163,149, 84,245,143, 92, 93, 32,192, 66,153,251,144,197,105, 36,167,177, 28,245,123,163, 88, -222, 25,247,134, 61, 57, 25, 66,105,210,108,125, 63, 87,219, 15,139,229,159, 46, 6, 68,105,123,236,151,173,125,150, 29,226, 57, - 54,232,163,178,255, 72,225, 67,187, 87,229, 65,121,186, 74,133,151, 24, 80,121, 81,179, 27,180,162, 3, 76,183, 41,177,141,200, -149,109,182,168,126,143,165,125,160, 65, 38,131, 88,128, 5, 51,155,142, 64, 21,224,104,194,183,153,217, 21,230, 94, 26,189,120, -194, 63,157,169,171,157, 68,206, 55, 38,199,202,140, 7,163,205, 14,179, 57,164,147, 90,186,173, 40,134, 14, 72, 84,145,113, 24, - 64,195, 98,143,145,127,238, 62,184, 11, 31,220,169,159,121,122,116,114,190, 89,208,240, 97,216, 16, 3,126,173,174, 34,100,194, - 90,118,155, 37,101,183,152, 49,172,213, 56, 10, 36,165, 44, 82,123,144,243,206,253, 26, 72, 66,149,100,165, 52, 78, 56, 69, 52, - 93,234,100,114, 90, 90, 27,250, 29,192,175,254,186,248,198,189,247, 51,168, 53,151,153,116, 12, 25, 39,240,231, 5,196,189, 98, -143, 15, 79,130, 88,149,180,189,128, 82,166,104,179,209,227,131,135,191,174,151,212,131, 44,170, 34, 47,115,106, 52, 55,231,159, - 79,239, 42,163,179, 34,223,230,187,154,163,176,133,176,135,233,172,200, 84, 44,212,239,106,253,126,253,241, 93,121, 54,152, 60, -234,157, 60,126,250,154,189,100,236, 85,243, 32, 22,172, 56,103,213,134,205, 31,224, 0,107,243,244,223,176,241,138, 21, 75, 86, - 22, 44, 83,176, 55, 39,208,226,144,135, 9, 43,185,152,142,198,243,209,193,241,240,254,243,217, 51, 33,213,151,236,237,247,235, -207, 53,128,239, 77, 88, 87, 26,247, 89, 0, 37,106,147,142,103, 23,127, 47,105,102,152, 72,235,198, 77,162, 82, 6, 73, 7,184, -155,212, 4, 60,143, 34,120,139,210, 80,223,142, 52,127,129, 58, 67,182,177,156,196, 73,187,246,199,182, 51,226,233,109,249, 88, - 71, 9,210, 4,161,175, 11,187, 59, 3, 13,189,247,245,176, 57, 50,103, 24, 42, 68,242,253,148, 65, 43,145,193,174,118,151,227, -126,154,240,120,167, 47, 65,136, 11, 73, 50,218, 49,247, 91, 66,178, 13, 29,160,130, 77, 5,196,218, 36,194,146,222,119,213,134, -255,134,116,180, 72,183,194, 6,213,123, 87,187,184,227, 25,248, 79, 0,214,206,101,183,105, 32, 10,195,115,177, 61,142,157,196, - 45, 20, 74, 17, 66,125, 6, 22, 93,240, 50,188, 22, 75,222,136, 69,145, 64, 72, 84,130,148, 5,174,162,144,230,210,196,246,216, -156,219, 56, 9, 41, 59,162, 74,105,147, 72, 81,237,196,243,159,115,254,249,126,212,239, 29,111,234, 17,185, 74, 92, 34,105,190, - 27,167, 7, 45, 81,170, 61,245, 16,120, 94, 74,107,145,233, 13,242,248, 50, 21,167,212,121,199,220, 62,144,222,157,174, 65, 68, -227,196,149, 4,132,226,147, 65, 60, 33,141,251, 51, 13,243, 88,100,191, 30, 45, 53, 90,240, 89, 17,246, 86,109,106,156,197,221, -155, 14,132,188, 53,160, 53,242,177,203, 65, 42, 92,228,197,200,101, 85, 75,166,208, 78,207,170,249,245,244, 26,254, 90, 55,171, - 13,242, 35, 97, 5,128,199, 41,217, 21, 15,187,103,194,217, 81, 56,161, 22, 79, 29,214, 16,166,237,187,240,127, 93,220, 3,230, - 73,237, 22,234,174,151,119, 59,100,115,168, 29,185,112,171,125,247, 60,173, 95, 71,254,227,239,122, 66, 79,231, 74,157, 96,230, -101, 52, 84,118,152, 36,167, 14, 33,226,163, 52,126,146,185, 19,103,179, 20,170,158, 40,113,113,238,220,167, 31,229,251,207,223, -110, 67, 67,188,217,113, 69, 15,144,161,126,239,247, 86,253,231,155, 9,133, 66, 31, 79,232,195,199, 37, 15, 19,221, 51,234, 44, -192, 97, 34,222, 27,122, 87,243,196, 22,169, 69,192,127, 26,189, 56,141,135,121,146,103, 80,109,233,186,229,121,151,191,157, 99, - 5,253,108,100, 19,211,125,191,219,126,153,168,135, 10, 59, 10,240,221, 77,162,124,185, 89,192,217,244,173,196,110,117, 34, 87, -131, 19, 36,180, 13, 13,211,184, 12,239,188, 35, 90,164,214,193, 13,105,104, 75, 84,220, 96, 82,118, 48,132, 83,196, 76,248,105, - 24,180, 77,236, 81, 29, 74, 46,243,216, 52, 66, 54,223,237,139, 34,120,121, 54,192,188, 55,138,170,165,222, 16, 35, 2, 57, 84, -196, 4,211, 53,172, 0,158, 6, 64, 82, 64,244,228, 99,246,197, 19,130, 12,133, 60, 39, 71,241, 58,193,174,105,102,149, 40,254, -191, 12, 67,133, 4,131, 76,221, 28, 33,134, 51,138, 3, 43,102,220, 12,163,237,121,113, 62, 93,148, 49, 5,170,199,216,167,137, - 4, 23, 69,227, 10,208, 69, 24,160, 16,197,171,237,186,242, 76, 45,194,160, 27, 88, 29,178,120,100,211, 66, 15,198, 23,103,151, -211, 65, 97,135,151,203,119,111,186, 43, 60,251, 25,249,101,249,208,240, 64,249, 45, 45,249, 47,149,186,167,116,191,113, 40,236, -182, 55, 74,151,234,235,135,153, 93,252, 44, 23,147,233,114,178, 90,253, 42,151, 55,213,102,254, 80,223,107,116, 70, 98,183,173, - 65,110, 30,190, 63,136, 57,107,109, 5, 18, 94,156,140, 7,178,189, 13, 56,127,145,224,173,160, 36, 2,243,145,243,112, 25, 19, -194,119,221,254, 20,148, 39, 96,199,159,231, 3,141, 44, 74, 94,155,127,238, 74,237,250,226,139, 47,238,143,226, 34,123,207,180, -230, 16, 83, 60, 41, 72, 35,128,235,248, 83,247, 42, 82,110,182,190,171,208,118,208,144,147, 94,224,181,210, 10, 57,176,123, 8, - 81,210, 8,190,130,107,116,234,189, 97,150,134,228,255, 29,155, 35, 61, 95, 84,247, 40,199,199, 41,172,112,251, 35, 0,105,231, -179, 27, 69, 12,131,241,216,153, 63, 45,173,160, 42, 72, 8, 36,184,112, 65,130,247,224, 69,121, 31, 84,245,136, 56, 0, 7, 68, - 69,183, 18, 67,119,102,118,146,152,216,142,179,179, 98,225, 66,143, 43,117,119,181, 73, 60, 95,236,207, 63, 55,107,184, 37, 88, - 61,185, 36, 13,217,171,222,141, 46, 36,251,127, 42,106,221, 27,217,201,201, 56,175,124,174,187,190,201,146,186,109,152,118,229, -151,124,174,101, 54,252,162,105,131, 2,180,151, 67,150,196,193, 93,190,166,118,168,129, 57, 92,100,125,153,178,227, 98,150,240, - 9, 34, 70,228,217, 65, 69,179,156,179,237,146,134,101,110,145, 95,235, 61, 12,236,111, 99,143,141,148,103, 8, 86,207,174,114, - 71,150,134, 48,114, 5,154,140,251,222, 45, 58,245,125,116,236,203,245, 88, 11,170,102,180,208,105, 20,222,213, 70, 68,176,170, - 3, 88,147, 22,172, 17,110,160,179,121, 57, 43,116,222,210,171, 19,186,186, 93,190, 28,102,183, 83,193, 74,129, 26, 45,117,133, -162,248,100,167,196,232,203,252, 43,191,126,254,228,221,102,120,255,253,102,249,251, 60,129,248,239, 57, 3,255,253,167, 5, 0, - 52, 21, 79,182,231,180,145, 74, 90, 48,184,251, 98,148,102,172,224, 21,127, 70,119, 51, 27,205, 47, 31,240, 46, 26,126,186, 97, - 8, 9, 71, 94,110,112,125,231,159, 62,244,103,190,219, 57,156, 2,116, 29, 62,123,220,131,159,191,110,166,124, 21,152,230,184, - 44, 83,219, 49, 27,112, 12, 89,101,179,253, 49,173, 64, 73, 88,129, 25, 98,249, 83,243, 52, 15, 98, 99,206, 15,152, 74, 21, 97, -194, 45, 81, 60,130, 55, 7,129, 55, 47,222, 94,127,190, 62,114,210,181,197,161,128,232,143, 6,119,161,159, 56, 87,159, 50, 26, -108, 16, 20, 85,227, 53,178,139,127,198,148,180, 0, 54, 34,131, 29, 60, 40,192,204,215,114,107,117, 85, 41, 12,137,155,129, 30, -157, 92,108,203, 13, 3, 43, 60, 68,119,144, 52,229,138, 4,179, 73,158, 8,229,233, 1,234, 4,149,186,145,186,119,116,222,206, - 52,223,171, 26,107, 80,177, 39, 82,190, 69,175,214,223, 4, 56,135, 37,236,238,149, 51, 74,114,201, 72, 44,201,220, 64,219, 54, - 97,147,154, 31,241,110,199,233,208,109,190,160,181, 18,220, 47,100,149,131,101, 8,243, 78,248, 32, 53,161, 58,174, 53, 89,157, -102,126,233,126,221,184,203,240,177,161, 79,113,249, 70,211,109,154, 55,103,158,207, 63, 67,242,185,154, 50, 50,183, 34, 50,168, - 39,241,237, 33, 71,250, 32,180, 71, 41,171,238, 71, 43, 69, 49,248,168, 44, 47,244, 24,170,225,207, 2,110, 82, 3, 37,152,224, - 55, 58,250, 58,204,253,185,159,221, 62,255, 94,220,162, 98, 48, 63,242,108,167,125,204, 37, 99,240,214, 55, 77,100,238,231,202, -124, 33, 51,218, 41,172, 95,110, 23, 57, 54,157, 78, 60,218, 59, 74,246, 34,153,244,166,106,128, 89, 37, 7,177,182, 71,162,193, - 39, 68,242, 22,255,187, 73,126, 52, 31,127, 25,233,103,244,236, 67, 20,240,225,128,104,253,224,223, 2,176,118, 53, 61, 78,196, - 48, 52, 31,211,204,116, 74,187,156, 22, 46,192, 34, 14,252, 6,126, 58,191, 3, 33,237,101, 57,176,172, 16, 5,164, 45,171,118, - 62, 18,219, 36,118, 50, 51,101,185, 32,113,232,181,157,180,169,253,108,191,247, 92, 61,202,108, 18,110,141,168,122, 35, 32, 26, -209, 98,218, 12,139, 50, 69, 20,146, 38,227,149,100,180, 91,169,120, 51,234,218, 56, 89,186,205,116,120,144,228, 28, 18,129, 32, -161, 38,118, 95, 74,137, 87,151, 5, 61, 17,221,115, 47, 21,179, 57, 50, 80,134,199, 90, 75,141, 22,195,195, 42, 13,226, 76, 4, -133,235,170,113,220,210,119, 54, 62, 9, 30,124,215, 84,110,235, 86, 29,132,175,167, 61,167,142,212,225,225,219, 67,103, 20, 6, - 33,189,243,210, 12,171,244, 12,215,120, 48, 53,178, 76, 81,130,187,154, 73,238,204,101,152, 24, 79,243,164,235,108,173,118,153, -171, 64,193, 6,140,248, 72, 59, 11,111, 91,186,187,247,159,104,110,103, 51,251, 69,167,209, 40,210,137,130,245, 28, 96,226,113, -124, 72,230, 74,171, 85,235,210,180,198,115,147,233,221,203,103,239,191,237,239,202,207, 67,255,142,190,241, 63, 69,121, 95,212, -231,211,117,116,124,215,186,242, 63,143,231,170, 97, 6,168, 15,125,170,235,234, 1,186,228,112, 0, 3, 51,225, 70,165,159, 88, -115, 3,120, 4,186,216,185,171, 23,187,234,114,227,146, 91, 0,253,234,225,199,125, 15,105,239,122,207, 40, 31,217,215,188, 25, -135, 45, 46,132,132,114, 43,145, 85,205, 98,171,251,234,242,234,246,251,103, 45, 78, 21,182, 10,224,207,157,228,211,235,195,237, - 71,154, 22,220,211, 92,126, 75,129, 78,150,227, 7,106,165,254,148,142, 48, 27,153,118,155,167,167,177,243, 97, 88, 22,248,201, -243,196,136, 38,137, 87,207,242,124, 87,232,251, 17,212,167, 30, 35, 79,246, 89,217,158, 63, 39,171,114, 64,154,233, 25,101, 34, - 77, 82,148,105,146,173,120,209,149,128, 71,195,130, 64, 18,143, 73, 18,228, 30, 63,145,138, 89,181,212, 48, 42,115,226,215, 77, -219,135,158, 13,141,149, 76,152,211, 3,138,237,108,238,103,224,118,125, 17, 47,250,254,240, 51, 94,176,166,110, 31,250, 94,242, -144, 15, 71, 3,214,251,181,209,155,214,134,174,201,222, 3, 83, 4,167, 66,220,114, 37,223,135, 34,147,150, 51, 28, 42,229, 35, -190, 83, 61, 37,129,249, 0,116,140,239, 25,171, 28, 15,199, 1, 7,196,152,193,253,155,231,175,175,191, 92, 75,116, 70, 81,242, -112, 47, 29, 10,164,227,249,170,200,182,164,203, 42,130, 29,157,213,168,106, 17,220, 5, 38,194, 76,170,153,128, 54,254, 61,153, -207,177,175, 72,158, 38, 93,146, 94,134,248, 50,177,164,105,181, 41, 46,172, 8,104,177, 75,153,178,134,209,100, 23,225,162,120, - 40,117, 70, 60, 26,240,126,185,164, 19,146,157, 91,158,123,212,144, 27, 30,106,225, 71,143,165,223,162,202, 16,143, 10,141, 28, - 75, 84, 54, 69,210,203, 14, 28,179,114,126,225,125,254, 40, 75, 77,223,198,111, 1,120,187,178, 21, 39,162, 32,218,251,205,196, -238,100, 70,153,121, 19,212, 39,241, 93,152,255,255, 5, 17, 70, 65, 68, 4,133,152,201,144,142,189,222,165,188, 85,117,171, 23, -193, 87,243, 20,210,157,164, 55,234,158, 58, 85,231,148,204,215,158,155,177,196, 5,141, 0,172,255,164,202,158, 53,186,165, 41, -145, 76,250,112, 6,129,113, 80, 77,193, 61,219,228,168, 71, 3, 28,150,229,159, 29,141,204, 59,171,137, 45, 71,120, 54, 69, 35, - 31,109, 28, 57, 36,240,218,138,207, 35,175,136, 25,254,127, 78,174, 11,232, 25,162,144, 31,247,201, 65,238, 35, 66, 66, 60,146, -255,181, 34, 65,213,147,255,206,161,125, 28, 81, 31,107,200, 85, 51, 56,131, 46,132,168,100,234, 24,217,137,119,115,233, 60, 70, -124,209, 2,196, 61, 73, 2, 18,169,119, 53,148,208, 22,193,125,182, 46,140, 22,134,116,139,203, 11, 40, 55,133,183,149,133, 1, - 62, 24, 55,113, 26,185, 92,115, 29,145, 81, 3,113, 46, 62,227,232,208, 58,217, 52,163,118,160,246, 70, 93,169, 66,229, 73,159, - 66,181,219,190,201,175,142,186,211,235,251,244,223, 94,201, 44,134,153, 15, 0,132, 23, 98, 46,126,148,247,220,216,163,104,235, -147,137, 60, 74,220,246,232,106,213,113,109, 39,137,238, 95, 85,175,171,221,151,239,245,195,169,249,124, 28, 62, 30,127,189,127, -217,221,191,123,161,114,117, 91, 58,221,155,199,139, 25, 70,232,125, 26,143,218,137,168, 84,205,245,198,135,133,189,157, 33, 9, -222,166,187,234,174,110,209,202,209, 67,220,111,135,175,164, 15,196,134,150,178, 40,159,186,147,244, 6, 67,165,202, 86,119, 84, -227, 68,144,111,157,147, 18, 39, 4, 91,246,128,186, 82,172,219,101,244,144, 58,145,192, 83,192,197, 14,156,237,243,223,221,121, -208,122,210, 89,197,161, 28,207, 18,170,152, 53,167, 41, 70,247,148,114,233,148, 1, 22, 13, 13, 66, 75, 94,220,213,227,146,188, -168,187,115, 44, 43, 76,236,130,178,249,210, 93, 82,170,247, 56, 38,200, 19,153,239,192,154, 88, 30, 30, 68,236,127,200, 18,169, -103, 4, 9,247, 52,140, 1,161,177, 17, 89,208,167,160, 85, 66, 32,121, 84, 86,248,195,210,214,176, 49,203, 77,121,125, 56,163, -209,241,185,189,120, 16,141, 3, 73,204,224,195,199,237,238,230,103,125, 66, 23, 40,212,217,250,221,235,184, 47,204,102, 15,251, -112,151,157,148,235,167,210, 61,200,162,238,100,171,147, 58, 16,106,217,243,198,233, 97, 72,252, 58,221,235,184, 55,208,140, 88, - 83, 29, 81,135,111,221,195,143, 79,150,202,213,228, 2,230,129, 41,202, 77,173,180,198, 64,152, 91, 40, 45,142, 17,231,111, 49, -172,195, 43,129,116, 39,200,125, 21,220,225,111,129,105, 12,139,134, 72, 88,184,144,174, 9,249,176,220,139, 59, 21, 76,220, 53, - 91, 9,185,127, 76,119,136,201,206,136, 44,209, 66,181, 55, 88, 22,115,110,129,231,131,131,147, 77, 8,196,116,114,228, 10,153, - 82,136,135, 85,177, 52, 73, 22,245, 0, 81, 29, 49,120,143, 23,158, 49, 65, 89, 73,169, 92,194, 12,249, 84, 81,148,181, 7, 4, -119,174,130,198, 31, 1, 72,187,150, 93, 39, 98, 24,154,215, 60,218, 10,170,123, 97,129,196,243, 19, 16, 44, 88,242,227,252, 4, -232,238, 17, 98, 9,151,150, 62,102,154, 38, 25, 19,219, 73, 38, 3, 98,129,216,116,211, 86,154,167,125,108, 31,159, 99,106,212, - 35, 19,126, 79,180, 66, 69,251, 5,141, 94,109,219, 7, 3, 70, 28, 15, 89,215, 20, 89, 46,218,180, 42, 86,219,125,139, 90, 99, -138, 30, 77, 36,204, 0, 37,103,143,245, 23,222, 97, 15, 92, 74,132, 36,164,202, 81,191, 26,104,192,108,150,140,101, 37, 2,110, - 84, 41,107,123,179,106,117,103,116, 12,124, 45, 90,214,144,154, 88,188,195, 78, 56,239,166, 78,244,187,203,142,183,224, 98, 82, -193, 55, 89,134, 37,223, 31,235,131, 32,231,105,134,170,231,212, 76,132,200, 93,169,156,210, 48, 49,235, 34,121,146,124, 88,150, -190, 77, 66,214,195,106,186, 98, 19, 41, 80, 78, 47, 55,174, 7,121,119,188,158,150,137,148, 25,238, 29,109, 33,155, 88, 80, 35, -147, 32,214, 34, 38,158,198,217,234,221,217,118,141, 89,119,230,166,239,111, 55,246,249,118,253,244,225, 90,220,143,101,200,249, -175,184,251,255,145,251,159, 15, 53,135,251, 43,125,118, 4,234,141,152, 21, 33, 44, 29, 42,211,231, 15,180, 81, 52, 82, 98,123, - 52,137,119, 47, 30, 15,123,169, 39,221, 75,109, 32,124, 19,226,195,215,147, 10,254,253,155,103, 79,182,189, 14,206, 89,255,249, - 30,187,179,158, 96,207,136,139,145, 99,211,160,181, 20, 84, 52,220,239, 71,156,200, 17,106, 38,148,138, 24,121,186,216,193, 94, - 25, 83,211, 78, 98, 8,146, 36, 33, 65, 38, 54, 47,224, 96, 96, 67,187,163, 39, 72, 20,150,244, 98, 18, 58,214,248, 71, 67, 70, -246,180,146, 52, 17, 97,252, 56, 28,251,110,229,124,152,210,146, 54, 80, 91,156, 89,139,188,110,165, 76,131,142, 55,220,254,111, -176,109, 24, 98,172, 31, 47, 35,131,251, 64,190,160,167,209, 18,173, 0, 50,245, 93, 38, 19,112,194, 56,164,112, 19,144, 63,144, -215, 84,216, 79, 18,213,242, 89, 18,152, 13, 35, 41,253,188,125,245,250,227,151, 79,140, 51, 88,210,140,221,193,226,133,216, 15, -123,106, 87, 98,187,134,108,203,240,152,136, 10, 34,209,241,131, 25, 64,164,234, 71,159,176, 59,255, 8,131,194, 29, 97,204, 70, - 78, 1,249,175, 41,112,210,202,110,110,188,248, 42,187,135,106,212, 95,190, 10, 69, 78,210,136, 65, 28,226,101,187,186,159,222, - 31,192, 71, 8,127, 65, 54,228,132,211, 69,122, 43,233,132,242, 40, 53,153,161,254, 22,220, 37,164,190,204,108,161,151,240, 41, -112,235, 83,134,188,143,154, 88,215,117, 23, 69, 46,122, 51,201,150,186,200,198,150,106,169,130,240,149,131, 93,233,201,228, 72, -176, 4,239, 51,197,165, 18, 98, 15, 69, 38, 39, 31, 6,143,224,240,151, 99, 56,172,213,141,102, 83, 40,194, 75,172,196, 1,243, - 52, 11,202, 42, 92,217,125,103,235, 33,138, 72, 97,233,139,192,199,138,150,168, 52,149,193, 32,172, 18,107, 83,102,233,202,191, -170, 72,254, 18,128,182,107,217,109, 27, 6,130, 92, 74, 10, 77, 59, 78, 91, 24,237,161, 64, 62,160,151,254, 63,208,143, 40,252, - 5, 65, 2, 36, 65,147,131, 83, 36,122,152,226,163,220, 7,101, 41, 70,209, 83,125,178, 13,195,150, 96,114, 57,187, 59, 59, 51, -213,103,116, 58, 13,255,208,242, 66, 22,191,204,136, 52,250, 98,107,234,188,127, 8,197, 71,154,158,192,100, 26,144,205, 82,123, -108, 93,249,134, 38, 3,105, 16, 17, 23,174,135,192, 7, 88,145, 67,129,197,152,176,152, 13,198,169, 97, 72, 91, 5,117, 0, 27, -149, 97,187,185,172,236,166, 54,182, 89,229,159,174, 1,149,203,134,228,107,224, 40, 30,243,109,134,209,117,161, 39,193,231, 64, -248,166, 16,244,229,216,208,172,201, 78,126,245, 90,205, 20, 77, 64,168,239,124,234, 44,229, 7, 64,195, 52,177, 48,169, 73, 72, -207, 93,195,137,177, 2, 37, 79,146,244,241, 2,210,215,205,104, 80,152, 34,222,156,157,246, 90,136, 74,168,226,210,163,122, 37, -166,168, 70,141,237,168,200, 43, 84, 91,164,123, 86, 79,117,123,213, 84,207,135, 28, 89,188,249,151,119,217,255,126,132,153,130, - 77,152,225,181,170, 68,121, 40,251, 92,151, 75,237,104, 59,241,253, 14,244, 50, 63,191,127,232,238, 30,221,205,107,247, 75,141, -109,129,252, 63, 30,134,205,250,249,251,183,207,198,152, 47, 91,119,123,112, 43, 64,187, 87, 71,107,162,243,234, 42,189,110,109, -142,203,198,249,161,162,177, 64, 36,114,165, 50, 15, 10,172,235,144,225,108,149,115, 32,154, 69,103,130,141,186,222, 93,239,239, -246, 84, 58, 99,212, 30,223,250, 28,217, 99,142,116, 94,192, 97,250,184,254,116,232, 95,242, 2,198,230,187,112,226, 2,185,176, - 72, 49,103, 12,206,245, 71,170,208, 11, 21,146, 85,227,200, 66,171, 70, 59,120,148,245,133,181, 93, 71, 42, 69, 90,107,243, 23, -229,224,142,176, 78, 76,239,229,211, 49,166, 9, 80,241,200, 59,123,112,106,214, 83, 97, 25, 61,153,165, 79, 90, 38,245, 57,132, -177,156,130,172,231,159,183,123, 93,122,237,197, 2,142,252,179,148,150,117, 43, 89,125,204,120,136,106,223,249, 34,194,227,239, - 39, 34, 26,224,125,230, 32,222, 30,251,196, 14,143,192,131,138,129,120,103, 36, 24, 17,199,252, 95,132, 25, 54, 79, 51,228, 59, -241,172,195,242,205, 48, 5,125,141,226, 37, 62, 30,131,114, 21, 50, 12, 48,171, 38,176, 23, 56,175,150,218, 12,117,224,130,112, - 73, 99,137,232, 73,148, 73,168, 27,119,134,220, 9, 74, 67,148,150,249,201,159, 67,130, 90,124, 31,220, 23,116,153,185,114,250, - 28,194, 47, 66,124, 90, 52, 96,207, 58,180,239,230, 69,185, 68,163,138, 9,182, 46,133,121, 62,177, 50,158,132,214,183, 31, 86, -187,202,153, 17, 37, 72, 88, 93,135,157, 38,167,163, 28, 10,139, 47,138, 39, 27, 69,152,138,232, 99,203, 36, 67, 82,200,203,102, -103, 97, 75,171, 11,173,137,222,194,203, 64, 6, 16, 48,141, 31,253,229,241, 71, 0,214,206,101,183,109, 24,136,162,164, 30,180, - 37, 71,129,209, 6,249,134,108,251,255,251,162,203,246, 3,218, 77,186, 73, 22,173,109,200,122, 81, 36,203, 59, 67, 74,148,211, - 2, 5,218,172,156, 69, 0,191, 66,206,220,185,115,110,145,108, 4, 72,185,136, 16, 33,195, 82,206,114, 62,136,189,118, 70,201, - 98, 87,150, 54, 74, 68,124,221,149, 20, 73,209, 67,130, 67,206, 0, 66,231,121, 77,144, 32, 12, 70,204, 40,173, 76, 78,154,251, -170, 86, 27, 42,120,151,131, 56,227, 21, 70,178,185,230, 88,195, 83,224,176,150, 59,127,212, 35,146, 58,167,164, 52,103,125, 71, - 61,103, 54,102,222,226, 25,118,186,133,200, 5,179, 2, 52, 47,222,108,222,138,110,146,171,153, 13,122, 45,122, 52,221,154,154, -205,254,247, 0,142,143,156,250, 69,199,161,166,130, 75,120,231, 54, 18, 55, 13,197,234,114, 84, 86,251, 70,215,223, 67,223,199, -121,250, 3,172, 83,135,178,215,209, 80,218, 92, 45,167, 10,101, 59, 49, 95,140,172,197, 12, 2,129,144,223, 46,125, 1,121,247, -255,152,217,255,253,148, 55, 91,194,129, 76, 60, 60,115,114,129,185,132,151,176, 72,159, 39, 33, 62, 62,255,108,123,247, 34,208, -211,244,188,218, 79, 15, 62,125,189,124,120,122,120,215,168,174, 83,119, 10,153,133,221,132,191,186, 82, 31,112, 30,196,251,195, - 84,169,199,215,235, 24,129,251, 81,178, 4, 63, 11, 39,226,190,170,253,215,239,236, 11, 70, 23,208,152,254, 27,249,249,249, 11, - 1, 6,150,222, 25,142, 70, 80, 45, 11,165, 39, 22, 24,229,160, 59,127,172, 53,213,177,215,253, 96,135,186,172, 15,251,230,220, -157,136,144, 30,208,178,113,148, 38, 57,135, 27,197, 54,138,253,224, 42,160, 13,211, 92, 27,125,223, 28, 47,167, 31,213,225,174, -239, 7,231,174,228,114, 9, 99,158, 0, 54,164,209,129, 11, 26, 13,211, 60, 88,227, 35,133,157,137,183, 72,253,201,248, 87,127, - 34,150, 89, 30,165,138,240,146,201, 4,202,105,134,246, 22,255,154,108,188, 24, 74,251, 43,242,157, 54,173,163,244, 21,186,188, - 28,229,146,132,173,127, 34, 1, 24,194, 21,102, 14,214,103, 36, 31,161,111, 18, 19,222,181, 78,100, 71, 52, 94,118, 3,164, 74, - 76,199,111,142,126, 60,246, 45, 23, 6,231, 8,242,242, 53,251, 8,112, 44, 22, 25,225, 8,148, 4, 18,112,108,186, 35,166,242, -178,145,186,106,214, 33,196,137, 53,119,123, 51, 50, 36, 61, 27,209,159,113,156,104,227,220,194, 46,136,129,191, 30, 82,201,180, - 24,119,191,249, 63,181,183, 27,161,226, 13,117, 50,204,102,243,181,102,181,209, 48, 17, 62, 53,127, 89,190, 78, 47,181,186,183, -211,168, 93, 8, 58, 94,173,150,193,171,194, 71, 80,190,104,238,164, 63,251,151,169, 69,130,161, 96, 7,109,153, 87, 77,241,216, -250, 27, 20,236, 10,168,127,165, 47, 8,133,106,177, 45, 99,156, 72,199,189,183, 63,191, 4, 32,238,106, 86,219, 6,130,240,174, - 37,217, 22,177,155, 6, 66, 66, 79,125,129,210,119,104, 79,125,140, 92,250,186,121,134, 64, 33, 52,144, 56,137,229, 88,218,255, -238,124,179, 90,109,144, 33,199, 10, 29,180,146, 48, 88,178,103,103,103,190,159,197,124,166,202,214, 97, 21,245, 57, 53,234, 93, -210, 8,107,104,118, 34, 39,188,248, 29, 52,189, 72,115,176,186,247,166, 33, 45,245, 5,152, 58,210,251, 4, 70,101,236, 26,145, - 41,168,145,146,138,158, 48,255,134,113,122, 66,182,161,121, 36,128,200,149,146,100, 90,235,117,187,104,183,171,179, 77, 67,150, - 52,168, 55,145,221,235,146,204,132, 5, 99,104, 3, 57,141,213,189,125,213, 88, 3, 66,244,198,242,172,226,115, 41, 77,134, 28, -159,229,164,163,192, 41,121,200, 26,238,156,197, 51, 76,141,194,110,146,130,202, 76, 68,230,124, 5,212, 92, 1,151,168, 70,124, - 17,187,112,145,185,239,206, 13,199, 64, 11, 99,169,156,188,183,238,100,163, 82,143,109, 73,133,196,182,195,219, 37, 89, 96,244, -243,148,112,123, 65, 82,123,127,131,185,179,131,243,102, 93,168,131,253,247,173, 76,220,108,177,151, 87,253,251, 97,222,110, 7, -245, 38,205, 61,140,129, 44,126,175, 45,118, 82,199,180,102,219,214, 95, 62,175, 63,173, 23,175,154, 84,125, 24,151,169, 64,242, -250,243,188,123,238, 30,170, 66, 86,122,194,135,225,255, 29, 35,242,211, 97,199, 46,234,105, 1, 39,211, 53,100,141,153, 41, 67, -169,211, 96,226,227, 15,117, 67, 6, 82,189, 81,223,190,126,239,205, 49, 30,144,150,122,112,187,238, 49,198,250,196,163,134, 41, -150, 44,168, 46, 19, 50,181,170, 47,183, 87,172,186,206, 88, 21,109,245,143,159,191,110,110,126,147, 60, 55,180,206, 70,241,122, -207,206,111, 20, 94,169, 30,159,124, 65, 49, 28, 61,229,200,171, 0, 83, 14, 69, 61, 11,111,175, 11,238, 36,143,113, 57,184,162, -244, 12,184,131,204,220,142,192,106, 97, 35, 75, 51, 13,131,223, 15,157,113,126, 89, 45,235,166,137, 31,109, 81,238, 70,205,212, -115, 46, 31,111,189,222, 94,129, 25, 78,231,207, 36,117,133,145, 38, 13,254, 33, 45,188,202, 38,170,127, 31,223, 67,113, 62, 37, -251, 7, 1, 5, 49,237, 98,132,136,207,129,192,108, 4,141, 6,103, 69,128, 97,232,144,208,161, 55, 49, 73, 64,240,242, 62, 39, -239,101,117, 60,132, 73,198,177, 40, 68,251, 19,181, 68,249, 81, 51,105,118,191,156,171,164,203,145,167, 90, 4,247, 48,231,191, -225,249, 87, 51,186, 68, 82, 42, 29, 81,210,116,168,204, 65,217,110, 83,157, 55, 98,213, 0,135, 82,161,165, 8,223, 21,214, 82, -100, 46, 7,226, 27,209,200, 26,184, 89,154,162,206,145, 93, 43, 40, 53,222,196,220,218, 41, 21,142,131,232,223,194,113, 31, 94, -180, 80, 43,209, 74,145,197,106, 79,219,145,252, 19,128,186, 43,107,113, 34, 8,194,213,221,115,244,132,136, 32, 46, 44,174,136, - 15,174,178,255,255,111,232,155,248, 38, 98, 64,214, 69, 86,204, 53, 87,166,187,237,170,234,154,195, 77,126,128, 97, 30, 2,147, -132, 48, 83,211, 85, 93,245, 29,179,254,140, 18,142,108, 82,211,197, 35, 22,212, 45,116,207,245, 58, 73, 54,227,234,150,199,120, - 42,113,188, 51, 37, 78,190, 19, 93, 64,209,221,194,152, 12,167,233, 96, 85,142,145, 77,223,113, 28,175, 62,149,195, 84,179,103, - 34, 3, 68,122, 26, 70, 87,198,218, 44, 30,149, 53, 69,188, 72,241, 9, 90, 23,101,102, 84,139, 52, 1, 53,102,252,248, 97,155, -233,111,191, 55,168,163, 60, 36, 82,155, 99, 77, 0,234,244, 41,207,219,223,160, 22, 67,151, 5, 73,113,164,141,176,203, 2, 83, -140,101,176,174,103, 92,161, 52,112,101,243, 68, 80,178, 25,162, 30, 79,221,238, 27, 7, 57,106,166,168, 19, 1,104, 30,207, 1, -201,221,140, 43,148,205, 60,189,134,244,132, 4, 22,109, 23,239, 61,108,145,185,153, 36,228,127,253,218, 5,120, 6,225, 53,192, -131,200,218,172, 41,225,197,235,112,168,221,203, 43, 19,171,240,187,235,106,127, 28,154,254, 84,251, 52,185, 69,255, 32, 15, 47, -194, 73,163,243, 32,140, 93,141, 17,168, 70, 96, 20, 20,241, 23, 7,122,218,240, 10,164, 77,141, 90,208,169, 85,135,111,170,194, -190,191,185,251,244,245, 99,124,255,101,243,217, 75,226,119, 88,182, 19,159,138,135,177, 19, 70, 98,233, 34, 0, 84,247,146,120, - 48, 67,179,200,156, 82,221,190,187,125,251,230, 38,102, 14,213,182,140,193,247, 41,169, 16, 6, 48, 41, 33, 38, 50, 33,181,221, -185,227, 16,202,220,174,202, 88,196,148,219,250, 17, 51,129, 27, 30,182,191,140, 73, 14,131,169, 83, 33,136, 17,226,111, 42,152, -118, 49, 76,221,196,176,229,113, 99, 22, 82,181,206, 85,250,182,219, 35,241, 4, 60, 18,140, 52,244,200, 96,213,228,179,128,245, -240,253,246, 62,137,238, 57,183, 27, 26, 29, 44,158,113,157,255,225,224,131,113, 43, 18,206,148, 5,113, 28,177,122,201,220, 66, - 98,167, 83,127, 32,252,140,245, 77,237, 93, 31,152,199,132, 24, 34, 36,191,197, 69,157,188, 34,240,129,178,121,222,244,199,144, -110,141,228,206, 52,206,188, 20,227,106,137,230, 62, 67,193,215,151,182,185, 10, 46,149,245,158,132, 0, 1,254,213, 19,159,180, -129,101, 12, 32,224,197, 73,105,221,204, 23,221, 39,168,121, 53,234, 34,144, 89,233,193,237,122,221, 85,102,237,124,222,162,131, - 71, 71,191,134, 75,188,230, 14, 8,205,246, 8, 87, 19,151,205, 78,193, 34,199, 5,193,142,199,232,109,252,193,135,254,213,234, -122,115,252,126,196,254, 37,198,203, 0, 67, 1,250,220, 63, 89,204,145,255, 10,192,220,213,244, 54, 13, 4,209,157,253,176,221, - 56,193,161,149, 42,209,194, 33, 18,247,170, 23,254,255, 29,238,237,161,145, 56,128, 4, 20,148,202, 10,113,253,177,187,236,204, -236, 58, 73, 99,169, 87,172, 61, 56,137, 98, 89,142, 51,126,243,230,205, 27, 57, 85, 36, 30,205, 46, 60,205,116,222,113,234, 36, -163, 51, 43,183,179, 34, 42, 25,123,123,216,180, 32, 3,148, 57,107,208,185,162, 13, 84,142,236,121,198, 45, 33, 90,202, 66,103, -103, 38, 47, 77, 94,200, 76, 5,224,160,168,103, 37,100,207, 40,149, 41,138,240, 57,240, 87, 53,134,119, 29, 64,186, 99,221,110, -135, 82,122, 44,169, 21,218, 44,178,236,110,115, 95,247, 53, 97, 34, 75, 35,250, 28,136, 84, 9,247,123,253, 59,241,167,105,145, -178, 51,226,110, 17, 57, 75,148, 71,122, 44, 78,209,255,138,185,119, 5,204,207,211,107, 26,151, 43, 33, 25, 70, 74,127, 32, 29, -117,253,147,229,209,121,225,201, 43,123,139,245,170,126, 10,249, 66,138,245, 25,237,228,180,211,166,171,223, 81, 56,107,146,178, -120,137,115,101, 93,251,154,105,251,255,191,141,119,222,119, 42,234,124, 42,244, 77,105,110,230,102, 53,215,111, 13,153,134,247, -126,251, 28, 50, 31,121, 94, 21, 1,200,191, 49,146,177,198,216,160,219,225,208, 12,153,134,107,129, 56,162, 72,221,204,204, 46, - 22, 23, 54, 85,233,152,101,230, 53, 68,116,130, 64, 24, 7, 92, 98,159,157,173,159,183,159,215, 95,176, 54,133,169,152, 82,228, - 75, 70, 61, 25,192,141, 50, 87,203, 43, 15,163,170,250, 8,185, 71, 28, 9,254, 79,253, 88,149, 75,102, 92,195,145,119,109,243, -238,253,245,221,253, 90, 43, 67,181, 77,203,121, 3,159,149,143,112,253,160,152, 24, 91, 98,241,142,108,135,118,179,221,252,218, -254, 28, 28, 3,118,226,112,173,224,129, 68, 46,242, 42,222, 69,234, 58, 74, 47,246,121, 73,156, 25,107,185,104, 57, 68, 67, 14, -182, 31, 68, 32,101,201, 32,221, 74,119,187,186, 37,207,125,108,252,195,166, 20,150, 76,198,135, 32,237, 5,148, 68, 38,143,238, -113, 51,172,227, 48,128, 62, 45,155,224,252,232,123,186, 87, 73,134, 72,243, 32,196,143,111,168,162,104, 81,215, 14,200,149,198, -138, 24, 0, 57, 85,162,229,148,109, 80, 15,126,120, 73, 15,100, 36,172, 25, 61,177,136,152, 12,252,147,225,236,229,187, 48, 13, -222, 95, 54,163, 76,128,253,232,168,124,125,254, 65,236, 67,167,132, 19,174,245, 52,184, 39,215, 4, 38,217,121, 72,103, 72, 13, -155,218,254,222,249, 39, 5, 33, 79,154, 87,178, 90,136, 42, 71,219,252, 51,156, 28, 35, 84, 47,186, 78, 52, 78, 14, 26,251, 21, -192,139, 99,125,119,122,154,135, 19,251,250,247,161, 44,202,213,226,227,165,188,156,161,239, 95,248, 9,186, 86,116,246,181, 32, -241, 79, 0,234,206,109,183,105, 32, 8,195,123,116, 99, 27, 18, 85, 45, 23, 84,168,125, 0,120,123,110, 16,239,129,122,131, 72, -165, 30, 36,160, 32, 66, 19, 31,210, 61,176, 51,227, 89,219, 81,196,125,111,146,171, 72,182, 99,143,103,103,255,255,251,129, 47, - 6, 14,120,173,243,220, 29, 49,143, 40,220, 98,219, 96,250,187, 74, 93, 77,231,113, 16,175,131, 57, 82,145, 82,116, 80,188,138, - 42, 70,229, 64,142,160, 37,187,198,113,188,168, 23,208,239, 23,150, 60, 26, 48,188, 1,215, 17,225,144, 10, 80, 64,130,194, 50, - 53, 65, 11, 11, 45,124,101,139,218,218, 62, 45, 51,141, 70, 10, 41, 60, 19,233, 18,148,186,232,195,238,118,183,110,124,131,247, -171,243, 48, 53,114, 56,221, 11,188,150,205,153, 47, 74,204,160,251,156, 88, 66,242, 97, 60,185, 1, 50, 43, 73,126,196,188, 89, - 46,238, 67, 10, 31,187,212,196, 68, 14,169, 33,218, 98,251, 61,184,116, 81, 86,232,181, 95, 26,249,215,249,135,153,180,102,240, -127, 90,254,180,172, 34,207,100,171,220,164, 91, 86,218, 92, 24,253,228,253,227, 49,148,243,203, 42,238,138,105, 57, 10, 77,143, -157, 11,151, 75,243,225,170,126, 93,153,189,243,181,150,239, 47,207, 34, 56, 53, 69,101,245,207, 63,251,190,117, 77,106, 37,184, -190,167, 31,190,213,126,181,124, 71,233,231,248, 63, 18,133,151,226, 46, 98,234, 73,155,126, 39, 14, 61,196,244,140,141,189, 27, -137,202,207, 94,157,167,239,211,250,180,217,111,229, 96,112,202,195, 30,146,159,139, 77,247,228, 67,224,241,129,228, 10, 17,137, - 51, 10,211, 25,154,203, 96, 52,168, 66,207,172, 81,246,102,253,237,211,231,143,198,154, 14,244,242,192,242,117,152,134, 78, 19, - 10, 2, 20, 77,140,176, 50,107,105, 80,193,128,243,125,142,125,226,221,255,204,137, 36, 71,215, 56, 90, 36, 70,178,228,253,161, -193, 94,157,129,130,195,198, 97,196, 48,118, 26,197, 64,150,199,237,175, 59,138,157, 78,135, 95,158,212,173,235, 35,109,211, 18, -223, 1, 80,173, 39,202, 20,182, 92,250,234, 66,233, 55,230, 10, 44,139,110,178,209,154,139,187,231,142,158, 74,228,243,189,112, - 95,132, 95, 95,171,205,215,231,205,111,209,108, 3,204, 42, 91, 76, 72,115,204, 11, 33,178, 67,156, 48, 24,163,156, 88, 3,197, -160,132, 57,200, 39,154,246,239,114, 14, 64,159,241, 13, 15,233,189,114,148, 72,234,255, 44, 13,142,229, 34,120,134, 14,181,253, - 22,161, 44,211,248,189,163, 78,168, 40,197, 1,185, 68,142,183, 94,204, 71, 18,176, 22,239,186,216,182,144,103,220,123,200, 89, -109, 9, 1, 79,155,195,104,242,159,213,117, 57,127,241,164,119,230, 99,247,195,168,114, 85,164, 55,196, 34, 85, 84, 92, 7,200, - 48,110,136, 28, 63,215,127, 2, 80,119,109, 59,109, 3, 65,116,111,118,154,208, 16,120,160, 85, 37,196, 51,255,255, 19,253,134, -138,138, 39, 20, 17, 72, 64, 65, 77,109,108,239,110,247,204,204,198,155, 80, 36, 94,121,140,148, 68, 78,236,157,157, 61,115, 46, -238, 13,148, 37,206, 42, 70, 56, 61, 96,159,244,177,125,241,219, 83,187,160,206, 32,144,129,160,175,180,128, 62, 54, 26,180,244, -232,146, 32, 28,153,218,180, 53, 65,223, 8, 70, 35, 76, 75,208,201,211,183,225,158,155,170,230,129,250, 68,213, 76,103, 78, 47, - 42,112, 33, 82,149,159,164,245, 83,187, 42,104, 11,121,180,115, 3, 73, 54, 28, 84,236,125, 31,155,135,230, 41, 93, 73, 15,222, - 21, 19,222, 7,202,206, 38,232, 85,198,210, 18,171, 77, 79,190,240, 18,116, 78,241,224, 35,188,225, 97,174,218,175,169,194, 16, -248, 64,118,204, 22,145, 70,240,248, 66, 33, 22, 41,135,246,185,111,184,106, 59,208,249, 99,234,223,239,195,113, 22, 76,225, 44, - 33, 99,150,147,140,213,232, 92,254,108,230,155,123, 0,211,200,180,125, 65, 94,210, 39, 46,238,123,190,188, 43, 78,181, 59,165, -126,110,186, 95,155,110,102, 17,244,122,253,109,126,118, 90,239,134,110, 49,119,149,117, 87, 23,211,229,186,213, 56,114, 70,198, -232,177, 62, 13,184,217,150,145, 49,214, 7,141,231, 51, 61,178,127, 67,252, 47,201,147,173, 0, 88,212,188,249,243,104,180, 59, -115,245,172,254,218,244,187,192,106, 12, 38, 83,107,225,110,164,247,205, 38,211,116,199,255,182,187, 98, 81,200, 19,129, 41,146, -199, 6,221,246,173,113,150, 60,217,253,151,249,236, 97,189, 74,197,180,123,125,253,126,254,227,118,249,219,211,240,210,135, 12, - 56,179, 83,138,246,194, 20,203, 30,199,120,240,113,109,164,104, 78, 31,177, 86,194, 71,163, 52,113, 65,179, 24, 27,143, 54,217, -109,198,116,210,244,152, 83,209, 36,149,230,177,150, 90, 31, 75,251, 25, 23,250, 94, 12, 88, 96,181,206,237,127,254,171, 96,197, - 58,248,208,182,157, 22,101,168,101,147,239, 8, 6, 35,168,169,112,193,218, 62,153,229,179, 90,159, 15,151,227, 41, 74, 21,204, -200, 82, 62,141, 90,127,163,194,106,169,182, 43,213,180,169, 19, 69,164,104,250, 45, 67,246, 85, 99, 28,138,119,210,176,119, 91, - 19,183,238, 24, 70, 96, 61,126, 32,133, 38,195, 49, 58, 91,175, 68,147,151,146,223, 99,227, 69,141,119,239,247,254,161, 48, 73, -125,251, 6, 10, 92, 17,113, 89,113, 73, 90, 31, 68,244,241, 68, 84,135, 35,202, 78,142, 71, 26,229, 84, 7,238, 70,177,224,224, -155, 67, 90,206,232,113,171,199,205,195,100,227, 1,116,171,169,145,189,107,110,136, 71, 15,175,238, 1,205,187, 32, 40,161, 8, -123, 56,234, 11,255, 9, 64,221,181,245, 52, 8, 67, 97, 90, 96,192,166,211, 68, 19, 19,159,124,247,255,255, 29,223,124, 80, 71, - 22, 7, 78, 24,180,181,231, 86, 10, 91,246,238,235, 50,146,149,193,215,211,115,190, 75,118,214, 69, 34,241, 54,187,116, 90,234, -253, 41,191,227,120,204,105,182,233, 54,133, 15, 13, 30,169,168,238,128,123, 13,158,189,192,114, 1,243, 11,244,206,240, 80,157, -146,123, 1, 21, 75,189,223, 15,146,188, 34,190, 34, 71, 85,186,206,217, 28, 76, 6, 1,151, 75, 72,194,204, 42, 52, 56, 56, 89, - 91,164,217, 77, 94,140,254,188,167,237, 73,251,210,168,133, 80, 99, 8, 17, 1,255,125,191,212, 1, 40,152,142, 75, 47, 53, 17, - 90, 0, 40, 45,223, 70,182, 82,118,129, 19,201, 29,116,205,169, 96,188, 51, 7, 9,154, 24,126, 42,146, 27, 79,224,174, 35, 95, - 78,141,246,196, 6, 4,230, 57,226,181,255,197, 72,222, 88,186,241, 43, 65,183, 82,194,230, 11,105, 46, 99,172, 32, 60, 2,107, - 33,185,119,248,133, 39,165, 63,177,120,255,215,224, 30,191, 54, 43, 1,250, 82,164,188,149,209,207,219,242,245,229,225,208, 3, -215,182,237,108,145,167,155, 77,241,120, 87,117,189,205,218,225,152, 88,106, 97,221, 87,235,195,240, 75, 71, 46,151,136, 5,191, -158,153,120,186,137, 73, 49,179, 98, 10,208,143, 8, 15,151,123,188,171,155,186,200, 86,110, 36, 37,169,194, 44, 59, 44, 54,248, - 77,132,228, 63,217,251,163,229, 96, 33,140,154, 80, 40,178,192,208,202,168, 17,124, 84,138,159,166,201, 87,185, 25,204,126,168, -119,135, 26,148, 45,214, 67, 28, 12,252,145, 25,137,166,183, 16,200, 35,141,115, 45,177, 64,138, 7, 58, 2,241,168,240,118, 65, -140,167, 92,228,148, 75,179, 39,131,228, 99, 69,228, 7,104, 14,105,246,210, 81, 98, 74,173, 89,248, 62,249,118, 33, 83,217, 95, -199, 88, 47, 1,119,196, 18,194, 1, 6, 6, 82, 24,171,199, 17, 82,184,154,125, 82,239,220, 59,224,251, 24,181, 50,212,124,220, -106,131,159,221, 91,159,124,125,232,227,183,237, 79,208,105, 24,205,109,146,181,176, 26,195,135, 40,203, 60, 70,106, 75, 45, 42, -219, 96, 6, 96,121,188,121,101,226,228, 2,159,196, 92, 22,107,171,248,255,159,185, 0,206,219, 50, 81, 84,225,149,103,215, 45, - 52, 80,103,141, 26,181, 24,247,134, 83,133,147,120,168,101,181,145, 68,167,172, 8,148,131,128, 58,230,142, 19, 11, 86, 2,148, - 98,178,146,198,198, 99,239,102,110,198,156, 92,120,113, 65,127, 2, 48,119, 45,201, 77, 3, 65,116, 62,146,108,227, 56, 78, 88, -192, 34, 85, 57, 2,247,191, 10, 39,128, 4, 87, 17, 27,108, 9,105,102, 26,189,238,233,201,200, 20, 84,150,120, 47,149, 74,178, -158,250,243, 62, 5,223,147,130, 97, 38,229,168,155, 79,100,162, 56,226, 55, 6,100, 47,199, 59,127,187,161, 22, 84,197,104, 36, -153, 90,246,152, 29,212,117, 44,223,214,174,143,243, 32,249, 70,192,150,212, 75, 38,161,211,184, 83,178,126,231,221,150, 99, 93, -187,166,217, 52,107,216,127, 59,186,184, 33,117,128,132,193,143, 56,113,227,226, 57,192,205, 27,243,212, 20,213,105, 19,181, 5, -132, 32,148,141, 8, 72,199, 85,160,186,112, 59,152, 88,227, 40,208,236,138, 6, 53,231,104,231, 4, 75,230, 8, 25, 87,109,213, -157,145,198, 69,183,108,172, 4, 39,103, 95,123, 28,154,191, 72,167,208,199,162, 86, 0, 49,219, 94,185, 53,123,229,138,136,188, -155, 35,226,120,191,234,180,231,205,254, 34,153, 18, 53,159,103,107,237,252,181,248,130,162,236, 13,181,204,255,253,115, 58, 73, - 95,105, 62,201, 59, 80,239, 16, 82,184,223,174, 62, 61,190,191,187,191,249,124,248,190, 1,159, 37, 53, 13,117, 93,123,127,211, -245, 63,167, 25, 37,218, 24,215,214, 62,236,218,113,181,239, 71, 79, 89,234,140,122, 53, 43, 87, 56,180, 61,147, 21,153,115,159, - 21,196,105,129, 15, 60,117,227,198, 13, 32, 10, 44, 7, 33,114,234, 1,167, 24,235, 71,141,140, 16,241, 36,143, 8,172, 53,246, -143, 36,102, 82,123, 60, 16,218,121, 70, 46,239,115, 0, 91,236, 87, 24, 3, 12,248, 8, 9, 69,240,230, 0, 43, 38,240, 24, 54, - 48,128,191, 70, 0, 45,210,128,149,249, 44, 65,151, 78, 93, 51,115,253, 78,106,212,129,191, 50, 91,251, 9, 66, 38,246,219, 39, - 94, 80, 75,246, 31,125,220,127,120, 58, 30,124,246,170, 22,255, 3,161, 33,130,177, 12,222,187, 13,146,193, 32,146,209, 66,254, - 21,167, 49,203, 57, 23, 77, 52,126,140,205,229,236, 79, 47,116,136,193,248,146, 97, 20,171, 66, 62,213,136, 63, 95,214,215,111, -230,229,217,156,143,102,232,109,152, 76, 8, 63,166, 75, 10, 33, 47,152,229, 62,137, 45,137,205,147,175,252,160, 84, 99,175,133, -110,161,189, 47,136, 43,105, 49, 75,191,222,175,254,131,244, 77, 75,182,143,173, 29, 90,232,175,243,253,186, 70,128,200,193,185, -105, 26,205,155, 95,198,165, 27,204,213, 65, 84,187, 1, 23,135,250,202,186,157, 90,219,174,186, 53, 66,228,249,238,138,137,111, - 37,118,149,245, 97, 82,164, 47,114,170, 84,134, 92,183,235,221,124,236,113, 56,213, 87,245, 91, 0,230,174,102, 55,109, 32, 8, -207,216, 94,131,237, 72, 41, 36,170, 84,169, 15,208,103,168,250,246, 81, 31, 33,135,230,212, 75, 42,161,166,150, 82,129, 13,172, -189, 27,207, 31,182, 41,228, 92, 78, 62, 96, 64, 88, 59,251,237,204,247,147,205,127,156,112,125,162, 56, 26, 69,245,112,233,101, - 3, 74,145,168,136,117,172,171,180, 42,161, 98,125,182,248,234, 16,192,234,213, 70, 63, 99,150, 63,228,236,117,154,202,224, 50, - 74,226, 37, 53,223,135, 82,233,144,162, 83,129,108, 6, 92,154,102,148,238, 6,135,215,190, 14, 11, 50,112,201,217,248,189, 44, -110,138,170, 92,221,173,158, 30, 31,201, 36,156, 76, 10,131, 76,204, 88,229,220,139, 21,165,185,134,169, 97, 56, 70,115,150,224, -152,159, 9, 79,198,188, 59,140, 32,164,209, 28,201, 73,180, 54,238,157,167, 28, 31,110, 42, 9, 52, 82,176,159,208,241,152, 70, -195,127,232,140, 79,232,219,145, 40,139, 60,239, 11,156,129,214,133, 33,247,130,233, 56, 44, 67,166,172,229,148,166, 46,244,233, - 13, 95,123,230,171, 57,126,231,199, 4, 54,125,104,223, 97, 5,252,247,176, 61,254,179,108, 58, 62,226, 0,253, 33,248,193,101, -183, 85,254,249,254,102,189,174,126,189, 54,219,198,123,143, 89,135,153,235,139,133,251,180, 94,116,219,163,247, 80, 98, 92,149, -174,129,252,231, 62, 79, 88,210,162,186,146,128, 39,113,198, 0, 23,190,126,249,246,253,199, 3,152, 18, 58,206, 18,230, 45, 5, - 40,170,152, 4, 53,153,205,104,121,106,182, 1, 98, 70,168,188, 9,121,248,225,226,122,230,242, 78,220,139, 1,216,164,234,205, - 16,250, 97, 9, 28, 59,145,101, 6,146,107,114,159, 91, 46,152, 90, 30,130,170,123, 64,246, 38,161,121,171,143, 62, 26,207, 70, -120,104,195, 91, 51,177, 26,198, 41,118,179,134,134,176, 24, 24,200,160,118,179,101,136,208,250, 67,136,221,136, 60,163,105,166, -134, 83,182, 40,190,197,143,144,138,131, 23,110, 15,232,112, 1, 43,183,100,222, 59, 81,206,232,158,227, 14,254,190,224,239,163, -135, 34, 26, 67, 38,204, 57,145, 99,127, 99, 3,248,242, 12,187, 58, 57,236,186,253, 14,134,103, 57,156,168, 67,212,156,171, 56, - 33, 28, 6, 21,189,155,169, 64, 82, 44,151,109,187,149, 52,186, 32,225,234, 48,109,201, 95,158,166,226,245,242,121,165,218, 78, - 17,241,165,240,186, 75,183, 40,167, 93,114,255,240,140,156, 27, 39,187,206,251,204,204,120,230,217, 91,184,178,241, 91, 28,247, -173,217, 90,161, 28,174, 36,181,226,110, 66, 93,115,110,157,104,254,199,141, 79,153, 82,246, 93,100, 21,213,181,134, 25,198,215, -155, 0,188, 93,201,110,219, 48, 16,229,144, 20, 45,185,182, 83, 56,135,162,189,164,183, 34, 64,190, 36,200,175, 5, 5,250, 79, -237,189,183, 30,138, 0, 65,210, 5,133, 99, 52, 86, 36, 75,150, 56,172,103, 72, 90, 75,146, 91,208,163, 15, 50,180,206, 12, 31, -223,162,123,189,141, 70, 94, 25, 32, 26, 95, 61, 67,202,168, 23,124,147, 77, 24, 63,163,188,201, 75,216, 78, 84,182,144, 51,205, -202,237, 16,140, 2,222,177, 78, 25,246,201,176,206,231, 49, 9,173,217,183, 90, 42, 50,121, 39,216, 67,177,114,121,183,170,239, - 11,100,186,173,150,251, 9, 46,181,217, 92, 47,142,142,151, 31, 78, 79,207, 47,206, 79,206, 78,174,190, 94,125,186,252,184,250, -243,139,130,153, 4, 90,194,133,226,203,195,142, 84,146,233, 78,145,193,228, 23,183,210, 5, 58,205,192,215, 55, 90,173,198,237, -211, 67,154,199, 96,251,116,244,140,194, 33,190, 49,184,176,148,167, 53,205,134,203,247,140,111,112,105,133,113,110,162, 33,235, -193,205,138,171, 63,176, 51,124,202,209,131,146,245,240, 10,200,186,194,208,119, 64,229,126,255,193, 25,110,156, 9,192,173, 21, - 15,164,113,253,223, 64,138,123,161,191,146,157,195,104, 71,202,245,123,200,192,148,255,172,197,153,195, 45,218,155,191,155,245, -174,109,144,194,156,108,219, 22, 21, 76, 83,125, 60,159,148,139,221,155,105, 98, 84,114, 93,232,159, 27,222,118,100,187,245,249, -228, 53, 33,248,117,249,246,232,221,143,245, 13, 48,131,248,243,183, 47, 36,123,150, 46,248,250,197,175,206,245,153,111,135, 53, -115,180,240,237, 77,210, 81, 50,121,224,182,116,129,175,189, 44, 24,209,137, 41,209, 79,163,138,104,143,232,109,237,180,114, 17, -105,103, 76, 70,120, 31,211, 32, 41,138,230, 55,190, 97,171, 16,230,196, 45,196, 99,223, 32, 14, 43, 15,144, 16,165, 59, 24,252, -125,145,166,184, 32,236, 87, 97,174,199, 8,175,112,134, 12,181,189, 85,126,199,115,136, 72,148,105,108,144,104, 97,240, 73,163, - 95,211,244,213,195,182, 96,117, 57,171,132, 8,186,215,196, 72, 80,146,174,134, 77,245,161,169,150,119,249,172,170,151, 80, 84, -239,219,239,113,247, 40,233, 25,209, 52, 67, 21,171,250, 45, 76,190,222, 86,247,162, 46,113, 87,179,201, 57,249,177, 6,130, 40, -118, 66,215, 8,188, 96, 64,147, 97,191,192,105,209, 35, 95, 46,226,218,110, 4, 47, 64,140,138,243,135, 63,201,116, 31,251,201, - 12,171,244, 8, 13, 26,189,231, 56,114,255,151,148,100,208,179,105,241,244,171, 1,219,146,206, 54, 51,233,254,236, 27,182, 76, -127,166, 73,140, 34, 82,195,178,205,131,116, 30, 51, 54, 82, 53, 68,145,131, 94,248, 30,153, 3,192, 83,117,200,117,133,222,142, -208, 33, 16,131,188,170,186,109,221,163,219,244, 79, 0,222,206,152,183,109, 24,136,194, 34, 69, 82, 86,156, 32, 54,138, 2, 93, -147, 37,104,182,110,221,251,231, 59, 20,237,223, 72,236,216,112, 91, 91,162,104,137, 87,222,241,200, 80, 77, 80, 20, 29,234, 65, - 35, 33, 89, 18,121, 58,126,239, 61,206,231, 83, 84,238,230, 14,117,146, 79,229,115,245,177, 6,135, 2, 72,114,225,198,134,119, - 19,108, 20, 64,161,112,187,146,170, 54,206,123, 35, 52, 26, 24, 72,133,213,189,212, 8,231, 16,167, 98,225,252, 52,236, 55,253, -118,227,182, 59,187,237,167, 19,102, 12,202,152, 38, 79,245,194, 52,246,182,239,186,227,251,251,251,219,143, 55,111,154,245,169, -179,135,239,135,193,145,133,244, 24,126,142, 62,127,145,120,227, 66, 44,189,197, 62,109,138, 38, 71, 30, 44, 91,128,189,121, 4, - 65, 47, 57,142,153, 81, 25, 37,162,113, 71,180,244,136, 29,247, 58, 73,155, 56, 3, 57, 27,245, 17, 55, 9,225, 90,142,231,211, -102,180, 45, 5,168, 26, 90, 47, 44,238, 69, 32,137,188,195, 62, 42, 55,154,175, 73,186,160,233, 51,199, 24,121,161,165,166,172, - 29,202,167,166,176, 80,236, 13,251, 86, 9, 13,114, 63,249,167,255,232, 73, 32,210,218, 94,182, 45,103,177, 0,255, 52,191, 87, - 5, 54,147,199,247,207,108, 40,160, 39,104,141,194,234,227,224,240,195,189,198,244, 57,173,196,114,161, 46, 23,250,170, 22, 3, - 52,159, 31,228,214, 74,222,210,194,255,181,110,212,197,201, 30, 67,105,252,211,254, 16, 73, 25, 71,247, 24,215, 0,173,154,240, - 72,196, 29,148,252,180, 67, 66, 36,184,121,151, 13,247, 50,103, 19,129,199,228, 95,200,152,185,103, 2,122,189, 92, 89,231,138, -240,237, 52, 43,248,204,219, 68,209, 80, 84,242,144,190, 13,143, 17, 74,164,224, 95,198,134,139, 20,136,228, 22,149,151, 35,246, -132, 77, 27,252,172,157,206,177, 33, 85,162,183, 4,167,139,177, 91, 53, 27, 41,224, 97,181, 92,133,145, 29,198, 35,123, 74, 62, -168, 50,159, 55, 33, 49,143,167, 99, 48, 1,188, 35, 47, 6,110, 12,133,151,209,168,230,178,189,114,161,106,146,106, 33,234, 15, -114,125,171,222, 65,101,204,249,220,189,189,123,252,212, 66,146,230,101,161,178, 44,228, 78,120, 49, 95, 43,245,237,139,181,187, -170,223,251,254,224,135, 30,156,133,209, 17, 31, 73,139,130,231, 25, 99,222, 90,161, 68,136,137,205, 7,161,156,227,210,163,228, -203,100,209,194, 47, 11,196,115, 83,102, 62, 44,252,185, 72,249,109,102,135, 23,192, 77,100,145,242, 18, 35,210, 22,254, 76, 41, - 12,213,117,187,114, 24, 55, 56,138, 89,148,219, 43, 35, 71, 2, 53,199, 4, 34,116, 68, 22,188, 34,161, 94, 83, 73,216,252,197, -235,149,118,144, 69, 25, 69,242,162,213,243,202, 80,191, 4,224,237, 74,118, 26,134,129,168,151, 56, 93, 40, 32, 56,241, 17,252, - 60, 32, 85,124, 3,127,192,137, 3,162, 7,150, 54, 52,221,210,196, 30, 60, 51,182,147,148, 10,193,133,123,218, 52,174,227, 89, -222, 50, 89, 47,236, 0,189,115,169,122,196,136,226,128, 93,203,249,239, 34,196, 6, 15, 39,204,157, 49,187,168,154,122,111, 11, - 58, 61,177,195,174, 53, 54, 6, 87, 77,142, 34, 90,165,136,167,133, 59,163,114,181,197,182,161, 83, 76,155, 36,208,146,116, 79, -254,138,218,135,244,204, 17,117,210,223,177,129,217,236,249,238,230,246,126, 58,253,248,152,175,215,203,114, 83,146,127, 52,189, - 21, 62,136, 88,134,218,210,192, 36, 65,174, 15, 16,189, 27, 72, 94,208,161, 85,169,196, 33, 96,178,153,162, 49, 17,146,169,238, -192,164, 87, 5,161,174,113,242, 80,158,150,220,199,168,106,240,143,167, 22,232,184, 45, 40, 91,151, 6,225,108,174,176,224,220, - 63, 62, 82,195, 90, 55,130,177, 86,147, 1,218, 97,249, 2,102,100,160, 33,171,192, 17,154,152, 59,237, 19,117, 3,198,154,177, -133,199,170,121,255,223, 46, 10, 68,190,230, 46,138,176, 76,199, 65,204,246,123, 68,191, 7, 3,184,112,209, 29,151,130,109, 88, -168,112,174,150, 62, 62,175,213,196, 53, 89, 78,125,185, 90,141,140, 67,207, 6,233, 78, 7,217,195,139,126,154,147,252, 26, 55, - 6,194,245,180, 13, 93,185, 41,104,240,139,108,241, 49, 25,100,155,128, 70,142,166, 66,121,170, 98, 88,156, 57, 27,162,203, 70, -128,232, 41, 71, 44,219, 6,101,122, 41, 47,143, 92,242,190,220,197,152,161, 82, 75, 1,201,141, 67,196,249, 29,112,146,157,249, - 96,131,194, 9,210,168, 65,236, 4, 81,206,106,233,171,108, 28, 63, 20, 71,135,137,128, 67,201, 40,153,161,196, 89,131,107,227, -199,113, 65, 74,248,148, 14,162, 58,118, 28,195,126, 60,123,144,193,124,181, 72, 37,166, 75,191, 50, 12,198,224, 58, 66, 20,235, - 2,130,225, 41,123, 15,227, 66,161, 37,252,182,212,122,232,175,186,206,175, 46,178,201,235,166,216,229, 53,212,106,191, 42, 27, -113,233,183, 2,228, 61, 9,107, 59,239,138,237,110,223,150,149,253,148,126,229,235,202, 17,221, 33,206,106, 99, 98, 18, 25,142, -200, 35, 84, 21,150,255,164,246, 49,167,241,157,156, 61,158,137,136, 28,132,110, 16,180, 61, 11, 56,146,189,195,239, 79,246,227, -181,186, 99,159,199, 30, 5,243, 27, 62, 43,196,114, 91, 68,122,221, 33,188, 43, 90,194, 76,104,157,245,156, 19,105,203, 14,117, -190,181, 21,221,238,175,253,215, 67,236,180, 11, 20,255,196,142, 20,226, 75, 0,222,174,100,167, 97, 24,136,122, 73,210,166, 20, -196,133, 35,226,255,191,132, 95, 64, 8, 9, 36, 4, 82, 1,161, 86,165,212,141, 99, 27,207, 98,199, 9, 8, 16, 7,122,171,170, -110, 25,103,214, 55,239, 85, 57,123, 75, 10, 83, 33,209, 19, 75, 30, 71, 56,236, 92, 18, 45, 41, 53,203,160,193, 14,103, 83,195, -224,209, 19, 84, 8, 48, 97,202, 3, 25,183,144, 86, 26,184, 53,123,210,204, 28, 52, 83,144, 72, 2, 22,146, 8,164,136, 42,197, - 26,209,243,218,185, 6,240, 1, 42,196,210,173,109,218,235,219,171,195,187,129, 13, 85, 7,234, 29,189,235,172,141, 21, 76, 7, -130, 48,129,214, 62, 66,169,109, 20, 24, 18,204,216, 35, 95,164,147, 36,116, 70, 73, 58,126,163, 98,146, 85, 18,184, 76, 84,192, -100, 46, 94, 80,151,195,212,155,195,131,103,104, 91,140,108,207,190, 35,209,131, 58,218, 76, 5, 11, 74,105, 96,177, 19, 13,138, - 33, 54,205, 84, 23,149,156, 53, 32,116,116, 52, 35,253,103,113,210, 64,242,110,192, 9,200,249, 92,180, 33,220, 63,153,155,253, -255, 57,247,236, 62,234,244, 35,151,233,169, 78,192,243, 67, 33,250,170, 11, 30,177,223,132,141,252,198, 62, 77, 32,150, 9,169, -214,147,122,184,245, 94,247,209, 95, 45,145, 82,173,149,125,163, 85, 52,175,233,236,229,195,238,238, 53,212, 53, 83, 92,228, 28, -133, 82, 1,199,164, 70,163, 67, 14,114, 31,152,183,150,104,201,162,192, 31,116,229, 21,203, 64,200,172,237, 33, 50,136, 32,165, -237,197,240, 37,172,214, 43,149,239,100, 63, 26,160,181,179,197,198,108, 96, 37, 36,201, 63,208, 98, 11,179,219, 16, 86, 23,229, -158,179,140,108,136,181,121,168, 82, 57, 77,199, 78, 78,192, 23, 42, 67, 49, 19, 87,110,242,244,146, 88, 45, 99,222, 5,113, 23, -232, 30, 53, 28, 84,133,171, 83,130,169,160,216,149,208, 52, 25, 95,169,170,198,216,131,202,163,189, 4, 87, 33,216, 37,212,174, -160,124,227,207,235,227,179,250,244,241,237,165,195,223, 96,118,214,238,214,189,184, 80,110,216, 89,157,116,189, 29,114, 2,201, -237, 86,185,189,112, 6, 25,108,122,146, 69,161,182, 85,198,254,112,163, 88,142,252, 84, 6,144, 88,100, 97,100,218, 56,134,192, -227,190, 59, 54,169,146, 1,229, 96,207,144,131, 5,163,110, 10, 57,236,239, 31, 35,207,142, 77,106, 63, 57,189, 24,199,191,220, - 78, 37,178, 70, 33, 63,129,224,253,244,243,133, 99,138,180,210, 29,231,162, 32,232,186,137,151,235,111,140, 35,197,133, 8,101, -145,237,127,250,239, 31, 2,144,118, 62,189, 9,195, 48, 20,175,147, 0,101, 69, 59, 76,187,177,227,190,255,215,217,101,211,110, -108,210,164,178, 13, 74, 75,219, 36,171,237,164, 73, 90,246, 71, 26,226,128,144, 64,136, 10,243,108,191,252,158,138, 95, 15,158, -111,207,215, 71, 4,104,176,117, 52, 83,143,228,226,145, 10,159, 74, 0,199,138, 7, 38, 95,243, 51, 52, 9,167,244, 25, 43,162, -160, 17,186, 48,152,168,237,230, 64,114,232, 2, 52,233, 89,252,188,104,219, 69, 47,185, 82,229,254, 77,210,250, 22, 25,116, 6, - 79, 32,226,112, 70,247,134,234,187, 75,206,246, 97,134,222,215, 25, 74,188,244, 74,193,245,193, 48, 6,155, 57,132, 55,128,203, - 88, 3, 27, 2, 86, 93, 25,144,236, 62, 22,209,172,139,186, 26, 34,252,213,180,158,222, 96,125,199, 14,186, 50,132,171,183,136, - 86,202,115, 85,180, 80,145,102, 91,146,222, 92, 43,200,135, 78, 24,129,105,156, 6, 1, 8,179,207,196, 26,236,161,108, 30,118, -167,103,109,154, 75,110, 72, 21,133,243,253,255,166,252,251, 72, 63, 42,145,254,190,164,178,219,210,182,160,160,162, 60,206, 85, -154, 31,117, 65, 22,177,198, 76, 42, 60, 69, 20, 46, 56,130,133,181,191, 40,173,238,101,167,142,162,199,234,220,192, 25,244,237, -240, 69,214,125, 89,101,184,129,199, 29, 40,163,132,146, 10, 40,201,253, 62, 87,186, 74,168, 98, 85,236,117,203, 73, 2,224,225, - 85, 48,209, 56,238,145, 25,254, 92, 5,140,235,173, 32,219, 83, 97, 40, 0, 18, 63, 69, 8, 69,179,217,235,251,206, 98,147, 73, -219, 94,195,121,161,134, 57, 98, 44, 3, 50, 50, 0, 67,208, 86,174,253,141,143,201,120,200, 88, 52, 12, 99,116, 48,121,194,242, -197, 74, 72, 57, 52,198,180, 16, 38,204, 17,233, 18,146,225, 68,102,160,136,101,114, 38,143,179, 11,103, 31,114,123, 65,128,235, -171, 77,189,175, 52,136, 9,113,207, 53, 22, 25,112, 49,190, 47,182,239, 93, 85,214,159, 56, 56,236, 13, 52,205,137, 74, 2,146, - 70, 52,255, 44,211, 85, 32,163,108, 7, 45,240,113,192,115, 26, 67,101,239, 58, 10,226,212,208, 35, 52,150,176, 8, 38,173,110, -169,121,207,184,197,234,221,205,118,181,204,159, 94, 30,249,112,140, 39, 36,135,178,158, 64,135,204,152,103, 17, 34, 56,236,239, -179,153,233, 63,140,159, 85, 92,184,173, 22,235,115,215,204, 37, 60,119, 16, 52,160,119,164,247, 89,151, 0,190,169,212,209,215, -101, 39, 11,250, 99,234,108, 49,223,159,176,157,235,244,249,170,217,252,205, 69,253, 37, 0,105,231,182,147, 48, 16,132,225,206, -178, 20,202, 33, 65,111,188,243,253, 31, 73,111,213, 24, 49, 4, 35,104,169, 61,236,216, 57, 45, 45,173, 49, 70, 30,128,208,102, -153,221,157,249,255,239,247,231,247,103,177, 38, 40,248, 11, 91, 25,120, 30, 67, 4,185, 48,115,226, 82,156, 61, 10,141,213, 5, - 73, 53,228, 12, 51, 13,176,150, 61,248,130,145,192,101, 57, 72,130,134,163,120, 39,231, 93, 80, 27, 22,179,208, 28,212,249,129, -155,226, 19, 25, 27, 19,168,168, 38, 86, 53,153, 71, 80,105, 73,236, 66, 48,181,140, 10, 49,241, 98,155, 53,155,146,153, 86,209, -242, 25,192,145, 78, 95,112,173,110,114,174,239, 18,179, 64, 7,164, 58,178,156,204, 50, 72, 79,210, 86,233,143, 42, 95,179,220, -133, 1,211, 16,103,137, 12,215,128, 91,159, 30,235, 47,207, 21,237, 80, 6,151,250, 44, 77,230, 51,191,206,166,155,165, 95,164, -190, 41,195,118,119,186,127, 56,222, 21,213,110,172,101,230,109,163,117, 29,244,238,255,207,236,181,161,111,166,220, 48, 33, 97, - 15, 37,120,210,193,100,237,208, 19, 15,142, 44,105,159, 37,215,125,126,248,212,124,234,222, 92,139,195,121,108, 55,254,102, 50, - 88,151, 96, 59,135, 52,172,218,141,100, 14, 56,229, 11,122,213, 64, 81,135, 50,161, 84,148, 67, 1,126, 14, 55, 27,255,178,163, -145, 68,195,165, 7,122, 82, 93,229,161,219,203, 54,126, 6,119,187, 37, 67,131,156,117, 65, 4, 95,244, 79,140, 39, 90,236, 29, -114,116,145,244, 69,114,248,235,165,216,208, 99,200,114, 30, 16,181, 65, 80, 46,185,178,189, 18,229,103,157,145, 42, 96,238, 89, - 48,231, 11, 67,100, 34, 10,170,179, 80, 45, 11,251,106,121, 93,135,170, 40, 10,199, 81, 8,164,143, 52, 47, 45,131,117,157,208, -196, 39,252,119,229,120,206,168, 26,151,197, 75, 5,102,149,173, 14,249,251,243,126,107, 67, 57,215,243,131, 42,128,189,189,109, - 55,237,193, 99,230,230,111,249,107,213,222,143,177,164,134, 81,145,151,139, 84, 31, 92,250, 48, 94,199,130,242, 69,140,167,229, - 59,193, 49, 15, 77, 69,205, 25, 36,122, 8,187, 27,137,222, 45, 3, 94,148,136,114,189,215, 4,161,229,216, 49, 87,243, 84,158, -246,143, 90, 81, 20,233,142, 99, 45, 20, 84, 9, 41,106, 22,182, 29,222, 67, 23, 35,156,252, 48,131,197,177,110, 76,211,215, 49, -199,207,169, 58,185, 97,123, 76, 6,244,128, 89,186, 34,123,132,198, 57, 71,142, 44,152,242,138, 12, 48, 16,165,186, 35, 53, 26, -134,194, 30, 28, 11,119,191,252, 1, 3,222,120,248,139, 63,230, 91, 0,210,174,100,167, 97, 24,136,218, 78,186, 35, 65, 17,119, -132,196,255,127, 18, 92, 16,170, 4, 69, 41,197,105,227,216, 30, 60,139, 83,119, 65, 2,209, 67, 15, 61,116,137, 58,206,204,155, -183, 20,252, 72, 49, 69, 6,115,154, 98, 33,109, 92,192,191, 87,142,138,164,176, 5,186,190, 38, 53,224,233,127,101, 6, 58, 57, -137, 47,180,224,150, 70, 21, 90,239,161,215,168,128,210,173,188,174, 42,196,241, 13, 43, 53,200,120, 19,173,128,243, 10, 84,214, - 65, 74, 12,240,208,226, 44, 50, 39, 63,200, 12,203,196, 77,131, 98, 39,137,229, 56,248, 50, 19,144, 87, 73,148, 44, 99,238,124, -184, 83,168,154,180,239,210,194, 35,196,130, 74,143, 64, 44,103, 80,181, 76,200, 66,182, 20,170,110,250,136,137,107,111, 72,104, - 26,101,233, 37,227, 89, 7,241,221,249,199,217,164,217,246,107,234,123, 58, 80,141,117,115, 8, 83, 5,187,157,223,173,245,106, -235, 94, 54,221,107,230, 36,152, 34, 23,233, 28, 49, 28,101, 88,227,159, 93,124,149, 77,111,248,206,113,171,212,117,205, 22,136, -122, 62,194,245,241, 30,210,156, 97, 22,228,246,230,131,234, 61,236,251,176,117, 48,216,220,237,133,224, 40, 64, 13, 28,221,169, -143,202,166, 46,248, 21,124,123,136,217, 54,242,138,206,122, 75, 54,136,181,199, 37,196, 24, 51, 3,234, 49,170, 35, 96,211,134, -229,162, 55,156,213, 61,128,133,121, 66, 56,248, 10, 29,237, 59, 53,133,210,113, 56, 24,241, 17,217, 57, 72,224, 23,230,203,168, - 83,236,229, 98,151, 84, 74,166,224,135,200,109,140, 14,211, 49, 79,136, 65,146,110,132,123,147,179, 58, 65,252,109,233, 86, 36, -226,111, 93, 86, 56,148,184, 46, 43,171,135, 61,107,122,222,216,198,176, 97,182, 62,128,165,185, 54, 13,131, 62,186,196,159,128, -175,188, 40,254,217,201,172,249,106,132, 26,156,253,201,179, 78,139, 12,148, 42,161,108,166,183, 91, 84,179,214,187,143,189,237, - 67,111,157,117,126,181,244, 51,111, 81,190, 11,115, 46,102,217, 18, 70, 80, 89,106, 66, 86,177, 81,121,251, 9,193,141, 83, 37, - 6,109,177,252,240, 53,177, 34, 8,146,192,193, 35,251,253,221,195,243,219,211,180,158,180,233,124,100,125, 21, 85,100,197,254, - 63, 74,182,220,170,112,242, 58, 76, 93,113,160, 10,130, 62,111,222,143,219,137,223,151,201,121,167,162, 47,137,162,160,152, 35, -112,233, 82,156,134,211,209,184,235, 59,254,206,233,135,164, 70,174,237,183,229,225,142,217,241,145,119,152,167, 64, 38, 20, 54, -150,229, 41, 95,112,122, 46,172, 94,255,122,178,243,227, 91, 0,210,174,100,167, 97, 24,136,198, 75, 8,165, 11, 66, 2,241, 5, - 92,248,255,239,224,192, 7, 32, 4,226,214, 10,148,180,205,230, 5,207,120,198,113,170, 74, 8,144,122,232,161,106,149, 38,126, - 30,207,188, 69,207,174,214,179, 83, 61,255,128,156, 65,115, 46,155, 66,143,109, 26,132,192, 23, 24,212,213, 1, 30, 89, 20,228, -197, 14,189,244,140,239, 54,181, 76, 36, 84, 25, 96, 61,128, 99,141, 36,232, 80,241,217, 55,206, 98,242, 24, 48,231,227, 36,128, -156,148, 92, 18,229,193,189,182,222,103,235, 16,104,244,208,228,156,198, 34,248,228,232,168,248,139,229, 17,181,218, 1,221, 33, - 87, 3, 94, 26,219,158,212,143,247,104,148, 16,182, 15, 25,101,129, 0, 25,177, 85, 21,151,161, 4,106,156, 88, 45,111,198,195, - 78, 99,222,102,143,127, 77, 0,226, 65, 20,247,112, 59,205,232, 47, 30, 23,171,167,182,142,150, 97, 97, 55,122,217,219,113,223, - 14, 28,114,164,241,243,130, 59, 48, 42,175, 72, 51, 33, 71,210,149,196, 79,142,255,168,220,147,251, 77,120,127, 43,196,117,233, -123, 33,199, 66, 84, 74, 44, 74, 89,234,112, 35,101,165,125, 87,200,149, 22, 11,136, 99,118,119, 90, 31, 59,183, 61,152,175, 22, -198,227, 29, 43,111,139,159,116,228,105, 68, 21,169, 23,138, 77,225, 21,199,248,193,196, 21, 26,187,190, 9,101,186,212, 75,232, - 45,131,243,102, 89,218, 99, 37,202, 74,116, 93,101,109, 36,165, 75,194,118,155, 98,176, 85, 78, 39,136,203, 0, 28, 10,217, 5, -154, 86, 14,249,154,250, 60, 30,236, 60,184, 19,242, 98,152, 53,247,152,208, 17,131, 79, 11,137,182,129, 1,161, 73,252,100, 25, -211, 19,247,198,209, 88,205, 39,238,197,180, 34, 85, 50,196,247, 83,241, 78,251,164, 87, 51,160,225, 60,200,100,170,131,147, 47, -210,184, 66,154,177,114, 28, 8,196,250,124,114, 77,117,130,216,254, 19,177, 4, 11,127, 57,133, 87, 80,230, 5, 52,112,128,156, - 99,193,204, 64,194,179, 14, 59,177, 31,141,115,173, 25,142,159, 31,235,182, 54, 53,184,186, 23, 27, 56,232,137,148, 84,132, 87, -165, 85,209,135,155, 22,206, 98,205,246,225,114,243,188,123, 31,135, 26, 25,163,152, 20, 98,209,222, 44,209, 76,241, 52,252,182, -125,133,234,216,116, 36,101,197, 46, 82,134,164,152,159,133, 14,239, 19,200, 48,152,241,233,139,185, 51,180,101,159, 20,239,194, -255,114, 81,156,116, 20,207,215,205, 51,186,165, 56, 97,223, 35,184,211,121, 4,134,203, 99,227,178, 28, 37, 76, 35, 60,123,246, -246,149,186,234,108,139,206,145,238,100,124,149,163,249,178, 90, 31,250, 38,231,182,253, 77, 19,243, 45, 0,103, 87,178,211, 48, - 12, 68,189, 80,210,210, 66,165, 8,245, 31,248,255,255,224, 3,144,184,114, 97, 19, 5,154,132,120,108, 60,155,235, 54, 69, 8, -110,189, 53, 78,236, 25,207,204, 91,206,234, 85,241, 91,131,106, 72, 12, 71,131,132,170,205,111,247,194,105,114,228,162,248,220, - 88,167,100,236,124,173,151,162,154,139,107,199,154, 31, 20, 81,233,170, 22,133,164, 68, 91, 1,215,140,224, 0, 52,223,246, 0, - 50, 13,227,209, 10, 85,194,156,231, 69,252,181,136, 95,179, 52,164,207,119,238, 61,107,152, 14,170, 73,166,242, 80,165, 22,141, -165,139,188, 33, 58,129,160, 37,115, 34,161, 51,104, 73,223, 3,167,183,108,230,144,162, 4, 40,178,211,213, 22,191, 95, 92,183, -225,109,139,253, 87,119,110,177,253, 8,196,172,204, 73, 3,192, 62,247,195, 77,187,238,195,242,126,220, 81, 89,137, 60,166, 94, - 49,130, 77,165,211,228,170, 64, 57, 83,101, 62,175, 49,108,166,183,224,255,181,104, 10, 90,145, 7,158, 13,245,100,150,206,109, - 26, 27,156,107,145, 91,102,182,144,235,106, 19,144,146,146,134,100,219, 57,194,230,208, 35,162,153,173, 22,126,125, 1,120, 99, - 75, 99,142,199, 86,229,139,253,164,188, 61,250,199,178, 29,125,245,131,245, 9, 64, 7,176, 51,250, 48, 99,180,195,200, 45, 87, - 67, 38, 68,230, 99, 59,172,175, 98,215,249,203,197,102,247,245, 14,199, 74,250,238, 20,237, 69,166, 68,130, 50,206,223, 51,152, -244,155,103,153,180, 4,232, 8,242,224, 44,105,141,102,120,211, 6,195,218, 48, 82,127,178,154,140,122,223,104,191,196,136,211, - 92,241,171,152, 4, 25, 43, 38,108, 54, 85,130, 57, 74, 46,146, 61,153,184, 13,138, 27,113,218,101,213,181, 72,226, 82,174, 39, -235,113, 56, 6, 2, 36,205, 44, 7,150,211, 7,200, 16,145, 51,227, 52, 71,154,180, 17, 73, 42, 22, 3,250,128,248,183, 24,122, - 66, 31, 51, 21, 42,245,159,241, 1,175, 39, 54, 71,249, 57, 10, 69, 33,125,214,201,235, 14,163,129, 23, 19,159,114,136,127,188, -125,189,131,177, 67,173, 16, 44,172, 25,113, 15,236,147, 42, 15, 20,147, 19,114,140, 43,154,145, 21,151, 80, 86,165,210,246, 21, -199, 41,150, 2,177,166,239,199,164, 46, 22,211,217,230,159, 78,135, 63, 13, 51, 23,250,220, 20, 58,147, 78,247,238,236,190,120, -170, 18, 64, 65,166,215,207, 89, 96, 32, 61,236, 42, 8,205,143, 79,222,161, 0, 74,142,242,171, 49,228,114, 58,252,155,240,248, - 45, 0,101,215,182,147, 48, 16, 68,119,182, 69,138, 4,163, 6,131, 47,242, 9,254,255,191,248,194,139, 26, 37, 26,229,106,235, - 94,236,220,150, 45,162, 34, 73, 19,194, 3, 45,203,118, 58,115,102,206, 57, 29,254, 42,152,253,142,252,161,167, 27, 72, 63,167, -203, 16, 83,104, 45, 48, 7, 80,209,107,118,170,229,158, 14,178, 46,168,205, 73, 67, 6, 44,185,206, 34, 74, 1,209,118,146, 59, - 69, 77,111, 71,174, 59,132,216,105, 26, 69, 61, 14, 38,187,217,192,159,202, 65, 4, 13,241,171,223, 43,189, 68, 58, 38,170, 22, -159,186,118, 88,177,107, 2, 2,130, 76, 41,110, 89, 40, 19,214,158,127, 80, 86,219,102, 27,196,228,129,122, 88,193, 39, 50, 10, - 26, 8, 14,175,123,203, 39,234,185,226,209,238,175,145,165,164,198,192,135,243,119,139,245,237,120,100,231,230,217, 53,168,140, -106,194, 50,211, 68,220,208,155, 74, 35, 38,227, 24, 28,238,171,172, 4, 75, 51, 39,246,255, 21, 89,218,103,125,106,153,242,120, -226,168,236,157,151,208, 39, 44,213,123,255,222,192,107, 27,218,105,161,122,133,233, 91,216, 52, 5,205,161, 23, 23, 67, 92,159, -209,176,127, 67,182,186, 69,216,218, 58,222,107,181,225, 85,234,210,127,203,121, 82, 99,211,239,132,159,228,121,224,148, 9,201, -224,126,237,218,103, 94,172,192, 87,193, 44, 29, 70, 80, 98, 18,152,222,192, 77, 46,235,135,249, 27,138,147, 82,178, 24,147,185, - 5,116,116,101,114,160, 51,118, 25, 44, 60, 32,169, 82,233,251,235, 71,120, 27,143,102,235,238,236,214, 79, 2,181, 71,121,114, -160, 10, 6,192,116, 60,157,189,204, 64, 0,201,148, 72,170,132, 72, 72,100,123,200,207,163,154, 24,137,120,165,211,145, 28,206, -147,144, 53, 21, 28, 54,118, 46,129,178, 6, 10,199, 44, 6,137,116,108, 28,194, 50, 2,252, 0, 13,210,196, 68,249,244, 73,182, -107, 55, 78,194, 77, 98,233,168,101,248, 47, 50, 2,209,170,182, 60, 89,185,245, 39,249,142,212, 36, 30,204, 63,197,111, 87,241, - 17, 55,168, 95,153, 80,161,119, 79,251,183,177, 14, 32,113, 96, 77,177, 49, 97,110,160, 89, 89, 28,124,104,111, 14,204, 95,137, - 6,192,237,102, 47,102,231, 42,223, 38,177, 36,166, 22, 89,200,220, 66, 66,220, 57,217,196, 92,151,121,103,119, 45, 11,236, 19, - 50,147,153,163,154, 35,130, 59,252, 49,144,162,175,171,179,201,124,241,148,161,222,240,251, 40,142, 94, 97,220, 87,140,212,224, -238,178,175,144,123,188, 56,173,253,230,167, 90, 33, 31,143,225, 93,141,162,249,241,176,207,207,145,145,225, 75, 0,202,174,100, - 55, 97, 24,136,218, 38, 64,145,104, 65,133, 3, 82,213, 75,213, 99,255,255, 99,122,224,210, 30,168, 18, 9,164, 36, 52, 78,188, - 52, 51, 99, 59,118, 9, 93, 56, 67, 20, 32, 30,143,223,188, 37,240,103, 40,143,148, 71,141,249, 15,184,127,156,128, 48, 28,100, - 3,233,132, 15, 1,135, 54, 36,157,249, 97, 4,244,194, 96,147, 72,214,222,228,210, 72,103, 46,139, 13,149, 6, 42,189, 75,181, - 87,156,199, 41,132,100,246,228, 83, 72, 92,201, 54,158,232,115,137,166,121,124, 51,108, 0,104,253, 56,129,100, 40, 64,149, 0, -135,207,156,188, 10,230,173, 40, 78, 4, 23,119,132,254, 9,111, 36,204, 83, 60,239,158,246, 31,175,148,107, 60,155,173,186, 73, - 1,155,129, 1,144,183,195,227, 38, 39,179, 17, 33, 78, 77,187, 47, 63, 95,118,235,195,177,206,207, 77,101,245,138,153,150, 25, -233,108, 67,220,157, 18, 62,211, 70,118,146, 34, 66,180, 67,207,222,253,147,129,206, 34, 73, 6,209,120,238, 0, 9, 20,155,153, -200, 50,216, 34,219,206,212, 74,183, 56, 34,171, 72,151,136,153,135,247, 82,109,167,236, 44,245, 82,216, 82,131,173,203,118,189, - 0,249, 81,103,143,178,153,226,111, 44, 35,133,250,181,177,149, 25, 97,143,185, 47,136,154, 56, 54,199, 39,231, 6, 15,122,125, -253, 94, 96,207, 87, 54,128,194,207, 57, 91,221,170, 34,107, 27,149, 81,210,180,178,108,179,220,156,170, 19, 77, 23,163, 34, 21, -246,115,107,198, 78,215,225,153, 4,221,166,137,215, 52, 9, 57, 92,148, 15,247,183,105,198,214,153,211, 64, 89,147, 87,185, 67, - 60, 6, 74, 70,194,109,196,178, 37,162,245,192,157,236,194, 65, 73, 19,175,160,230, 72,228,199,243,170,240,147, 33,150,144,105, -188, 85,149,197,104, 12,144,118,244, 23,127,220, 62,188, 21,239,152, 70,208, 47, 29,225,127,109,107, 19,140,200, 49,223, 67,175, - 46,124, 18,165, 95,173,168,226,193,204, 32, 4,189,117, 3, 31,233,251,119,210,100, 25, 66,157,140,172,117, 14,161, 98, 56, 16, - 7, 66, 27,140, 57, 50,167,194, 4, 7,168,146,241,162,148,245, 65,183, 74,107,105,192, 16, 89,163,253,190, 66, 22, 17, 35,171, -122, 30,249, 52, 71,206,230, 1,210,143, 8, 57, 60,197,152, 71,138,187,203,207,160,196,209,168,222,253,146,224,196,147,209,230, -112, 61,195, 4,191,224, 85,246,197, 61,197,100,236, 24,155, 62,252, 75,196, 30, 28,108,100,190,209,102, 46,239, 12,226,219,146, -226, 30,191,127, 56,111,242, 4,170,183,246,250, 6,245,151,215,151, 0,148, 93, 77, 79,195, 48, 12,181,147,142,109, 32, 62, 37, - 38, 33, 78, 92,198,145, 35,255,159,191,129,196, 17,161,137, 9,237,131,118, 75,210,154, 36,118,210,140, 49, 4,189, 79,237,154, -218,137,159,253,222, 99,254, 42, 19,154, 17,123,117, 62, 60,252,202, 14,221,177, 60, 4,225,119,101, 32, 94,178,116, 10,235,164, -231,218,253,180,129,177,183, 89,203,128, 15, 43,136, 37,198,202, 46,144,154,112,202, 60, 78,156,149,178,129, 71, 13, 72,164, 5, -132, 26,136, 42,202,225,196, 6, 86,164,170,106, 97,168, 42,177,135, 66, 41, 36,243,234,168, 36, 68,230, 67,192, 26,227,139, 90, - 29, 21, 36, 93, 91, 15, 32,184, 96, 71,229, 72,108,136,101, 49, 99,244, 2,205,141, 59,169,212,253,245, 89, 24,248,115, 97, 24, -212,223, 96, 20,234, 3, 25, 60,135, 2,132,201,122, 36,153,249,137, 69, 91, 53, 15, 81,225, 1,111,129,253,107,144,222,249, 37, -192, 4,212,213,160, 58, 27,235,145,166,181,131,218,118,111,166,125, 33,120,143,237,129,161, 52, 3, 84, 3,180, 0,152,181,176, -178, 84,217,208,195,190, 61,173, 38, 23,199, 90,235,247,133,125,251,220,186,162,183,211,254,115,155,129, 68,167, 26, 37, 92,158, - 39, 47,143, 66,229, 68, 71,138,137,196, 9,155,246, 53,196, 88,125,172, 42,118, 85,233, 98, 95,196, 6,238, 31,246,192, 38,100, -195,140,172,250,223,215,195, 28, 40,148, 5,225, 74,156, 6, 69,148, 32, 53,108,251,189, 1,233, 27, 70,143, 25, 47,241,143, 96, -172, 67,164, 50, 93, 21, 65, 34,240,159,226,224, 73, 14, 50,226,226, 43,242, 24,197,113, 4,164, 3, 20,233,169, 26, 11,179,236, -164,249,158,124,129,123,181,248,240,104, 91,103,167,183,211,249,114, 30,244,243,178,207,148, 80,171,178,245,199, 78,206,202, 57, -213,255,205,243,227,139, 46,232, 2, 56, 16,170, 56,135, 22, 13, 66, 35, 70, 45, 55,171, 64, 82,242,223,184,173,135, 55, 15,246, -238, 17,214, 13,109,116,176, 21,218, 4, 44,222,159,229,125,237,169,106, 48, 75,112,139,186,155,189,182,207, 79,214, 54, 93, 83, - 59,215,128,241,191, 54, 44, 27,201, 35,240,152, 52, 31, 10,148, 60, 97,185, 72, 59,174,135, 88,156,193,177, 24,163,254,249,212, - 92,146, 88,255, 64,251,148,182,171, 18,185,111,204,107,129,189,164,197, 94,234,248, 3,143, 79,170, 37,218, 77,238,165,232,193, - 33,115, 18, 93,168,134,133,104,213,213,184, 26,219,206,112,166, 26,234, 81, 75,142,126, 47, 52,254,115,125, 9, 64,217,153,236, - 52, 12, 3, 97,216,158,164, 75, 90, 16,251, 34, 33, 16, 39, 36,182, 3, 18,226,253,159,128,135, 64,244, 64,217, 10,148,144,197, -206, 96,143,215, 4,138, 74, 15, 61, 68, 85, 85, 53,246,239,120,252,207,247, 91,125,247, 22,225,134, 45, 90, 49,186,210,207, 23, - 31, 74,252,166,242,145,149,142,199, 53,252,184,188,229, 1,120,100, 52, 51,115,177, 49,130, 15,254,244,168, 53, 30,204,157,130, -214,124,128,224, 7, 51,166,120, 63,139,192,101,119,160, 41,190, 43,129, 79, 77, 14, 61, 79,110, 78,174, 39,207, 19,160,208,134, -198,150,248,173,107, 84, 93,172, 69,101,168,100,200,169,109, 23, 37,200,188,166,237,101,138, 68, 98, 38,112, 24,161,254, 64,189, -207,190,234, 82,202,211,157,181,195,141,113,150, 38,234,150,169, 73,217, 67,194,170,145,214,147,211,156, 39,238,184,181, 31,193, - 61, 58, 29, 37,240,159,135,119,112,167,154, 35,198,182,148,196, 39, 73,111, 0,195, 20,222,106, 53, 7,229,189,144, 15,132, 85, - 56,207, 6,151,155,131,227,245,236,104,181,127,182, 49,188, 88,205,174,198,217,150,132,169,168, 39, 66, 61,187,201, 17,192,241, -254,104,115, 37,251,154, 21, 79,111,213,148, 54, 31, 16,145,249,150,119, 41,248, 97, 42,162, 50,142,182,219,115,109,221,209,101, - 49,221, 58,161, 83,190,164, 14,234, 98,107,227,244,241, 61,181, 57, 27, 12,116,125,216, 25,120,177, 21,153,233,156,187,104,129, -233, 58,159,183,173, 29,248, 83,223,165,113,232,132,176, 77,196,214,252,100,109,250, 32,178,120,204, 53,172, 11,174,178, 91, 73, - 8,226, 17,100, 34,112, 46,130,184, 27,208,151,158,113,196,197,166,132, 61,238,152, 24, 33, 53, 50,198,220,234,139,149,172,212, - 31,240,242,249,194, 44, 40,213,246,128,217,190, 89,134, 46, 48,202, 60, 31, 53,166,244,196,125, 1, 1,213, 78,191, 16,212,158, - 66, 30, 27, 91,249, 39, 27, 61,238,245,183, 63,170, 60,151, 69, 41,107, 41,138,108,247,178, 60, 56,229,249, 92, 51,159,212,127, -175, 22,255, 82, 31,178,243,156,179, 28,139,247,215,102, 62,227,211, 59,121,119, 43,170,188,169,231, 88, 22, 58,140, 89, 19, 86, - 4,242, 40,248, 54,238, 60, 10,112, 72, 83,109, 15, 3, 22,221, 30,159,117, 8,238,173,135,119, 95, 21, 96,177,231,253,111, 42, - 1,183,196, 65,240,172, 17,174, 25, 42,137, 91,159,187, 18,191,156,178, 7,124, 2, 46,104, 46, 93, 40,136,109, 27,149,127, 9, - 10,180, 48, 31, 22, 40,226,160,143, 97,111, 68,139,120, 19,127,237,120,176,162,198,195,146,191,251, 91, 0,202,206,103,181,109, - 32, 8,227,187,179,146, 45, 69,142,131, 75, 3, 14, 61, 22, 31,122,239, 11, 20,250,254,135, 66, 31,160,180, 77, 28,136, 77,155, -198,146,119,165,157,169,246,175, 86, 82, 19, 82,227,131, 49, 24, 86, 94,239, 88, 51,243,205,239, 19,214, 26,219,185, 56, 14,183, -138,255, 92,112, 8,253,192, 95, 60,203,124,222,128, 78,154,207, 16, 44,117, 25, 79,232,248,144,142, 30,187,210,104,212,135,225, -168,209,203, 35, 19, 18, 18,119, 14,107,219,225, 78, 26,196, 6,124,156,114, 2, 7,121,119,138, 44,239,218,196,172, 16,158, 9, -127, 56, 73,223, 30,238, 76,163, 86, 8,141, 8, 65, 17,233,106,247,233,222, 44,179, 92,235,254,239,161,203,241, 17, 45,111, 64, - 18, 74, 91, 77,106, 25,151,150,235,148, 25,125, 1,237,165,250,126, 60,181, 29,110, 87,229,187,171,213,118, 85, 92, 45, 22, 21, -100, 43,130,140,160, 48,133,124,158, 71,219, 85,123, 87,219, 37, 94, 31, 81,113,168,103,228,188,231,110,147, 89,146, 7,188, 53, -241, 93,108,138,188, 90,230, 79, 45,237, 27,245,128,120,199,216,199, 98,249,233,253, 70, 84, 92,103,253,106,177,214, 84, 91, 77, -146,200, 97,119,189,254,252,102,243,229,240,251, 39,177,203,142,118,219,245,205,166,220,223,159,190, 29,207,143, 54, 95,199,153, - 68,242,127, 14,134,215, 2,137,144,193, 24,109,143, 53, 51, 93, 8,232,159,203,220,120, 57,246, 25, 79,145,139,227, 73,152, 82, -153,143, 4, 78, 26, 50, 46,192,167,254,215, 46,156, 88,164, 73,192,159,242,164,190,146,198,119,154, 12, 73, 57,207, 85,228,124, -106,139, 54,187, 76,156,166,236, 78,221, 62, 8,138,210,112,207,189, 85,187,215, 62,198,224,206,201,199,114,128, 32,235, 98,177, -253, 31,108,153,134,154, 39, 70, 80,141,117, 76,240,126,100,253,245, 20,139, 82,219, 64,144,152,255,185, 23,122, 92, 67, 48,111, - 95,150,235,218, 80,145, 45, 68,158,249,193, 80,230,201,149,188, 65,117,145,149,253,119,166, 58,101,176, 89, 40,171,235, 15,237, -205,142, 53, 79,172,213,164,206,198,122,168,105, 80,158, 65, 74, 89,255,234,234, 3,171,255,232,135, 31,250,254, 43,170,254,211, -103, 84, 70,255, 78, 90, 89, 88,102, 23, 23,197,130, 17, 46,122, 48, 3, 13, 45, 85, 22,183,148, 66,178, 20,230,191, 96, 4,179, -165, 49,151,244,133,226,140,158, 38,184,224,237, 2, 2,117,138, 59,156, 32, 4,184, 69,152,121, 79,149,238,248,124,221, 61,128, -113,112,172,173,156,208,140,135,159, 87, 37, 46, 90,106,231, 71,117,114,122, 40,100,155, 52, 99,200,152, 77, 23,102,130,127,146, -175,100,144,117,142,143,253,138,199, 95, 1, 56,187,154,221,182, 97, 24, 44, 74,142, 98,180,193,134, 2,197, 78,219, 83, 12, 24, -176,199,232,179,246, 65, 58, 96,247,222, 10, 12, 40,154, 37, 93,147,198,150, 69,150,164, 36, 71,118,186,162,104,144,131, 79,134, -109, 17, 20, 73,125, 63, 77,253,120, 53,105,208,190,170,143,172,170, 52,152,103,141,167,137,158, 74,243, 90,142,169,178,103, 70, - 34,231,165,101, 44,170,249,170,115, 39,202,169,162,216, 97, 84, 97, 18, 21,168,146, 5,133,139,220,154, 73,220, 64, 55,222, 24, -147, 20,248, 64,133, 72, 69, 88, 76,148, 39, 88,139,124,252,149,132,187,203,133,205,217, 64,237,111,116, 70, 40,176,226, 6,146, - 14,141,203,228, 11, 13, 3,103,155,117,183,246,226, 32,184,146,154, 71, 60,112, 82,198, 64, 4, 15, 50, 75,144,119, 88,170,162, -205, 94, 66, 91,152,242, 54, 9,105,105,186,255, 71,241,215,102,123,179,217,122, 99, 47,151,203,139, 70, 48,232,173,151, 45,245, -121, 64,136,161, 83,200, 16, 77,225,234,105, 98,163, 36,112, 19,166,192, 88, 91, 54, 0,156, 6,125,157,250, 99, 65,173,180,156, - 55, 23,174, 35, 90,119,113, 75,200,149,251,119,239,175,126,126,251,253,240, 55, 6, 35, 78,153, 34, 93, 41,239,207, 27,218,227, -129,219,235,253,234,211,234,135, 63,191,238,119,161,195,214,185,231,206,254,121, 12,187, 10,234,245, 97,227,145,166,122,181,182, -180,220,252,247,234, 33,192,171,114, 8,226, 61,252,217,155, 51,207, 23, 92,199, 52, 89, 17,169, 50,188,166,209,240, 13,138,109, - 83,233,234, 72,193, 88, 73,154, 72, 71,236,169,230,201,162,128,211,167,207, 44, 36, 78,238,103,237,121, 24,130,120,215,208, 76, -172, 10,102, 85,216, 52,186,170,111, 63, 66,100,202, 22, 2,199,206,225,104, 9,116,180,123,172,134, 0, 71, 58, 60,166,179,100, - 61,216,133,140, 24,182, 74,229,133, 26, 35,237,242,176, 70,225,144,137, 55, 59, 73,238,177, 70,219,143,188, 51,183,160, 36, 28, - 79, 5,168, 32,245,156, 37,212,211,110,176,183,187,187,175,254,203,210,249,206,245, 3, 56,174,202,105,179, 70,236,193, 31,184, - 20, 49, 11,111, 29, 7, 46, 4, 75,189, 0, 41,159,144,195,118,123,207,105,125,224,174, 34, 4, 33, 30,114,224,199,212, 72, 24, - 26,185, 74,134, 98, 85,143,205,102, 1, 66, 74,204, 31,218,166, 83,185, 52, 1,131, 2,235,196,255,160, 6,224,181, 82,135, 42, -218, 11,204,161, 50,185,125,194,136,126,209, 14, 40,157, 16, 20,169,253,113, 65, 11, 58, 96,228, 43,157,150, 83, 8,115, 56, 13, -213,179,157,250,145,249,142, 79,113, 47, 5,141,181, 3,162,125,107,219,120,171, 23,233, 67,127, 90, 71, 31, 4,155,247,222,223, -139, 0,180, 93, 75, 78, 2, 65, 16,237,238,249, 0, 26, 48,134, 27,152,152,184,240, 12,238,117,229, 33,188,165,137,137, 43,143, -224,194, 11,160,160, 32,195,175,153,233,110,187,170,250, 55, 12,113, 99, 92,178, 1, 38,208, 85,175, 94,191,122, 47,111,239, 31, -198, 22,162,143,205,254, 38, 94,159, 50, 50,166,233,182, 0,225,234,190,241,183,181, 78, 42,233,126,111, 82, 79, 58, 47, 0,207, -152,210, 16,162,120, 82,229, 41, 20,155,211,134, 20, 10, 10, 88,230, 15,132,161, 38,224,136, 84, 18, 69, 56,132, 7,127,100,161, -125, 45,128,247,202,130,152, 33,113, 95, 18,148, 78,137, 11,199,232, 45, 36, 50,231, 29, 8, 90,104,228,124,245,203,251,235,188, -222, 94,142,216,245,249,197, 90, 14,137, 37,175, 27,137, 22, 11, 57, 36,250,160,231,253,158,105, 59,197, 74,128,237,134,240,248, - 55,234,178, 75, 76,234,176,149, 99, 13, 15,171,166,178,182,128, 89,146, 94,222,107,225,201,149, 37,221,113, 48,201,203,116,135, -136,119,120,131, 84, 19, 30,192, 11, 85,246, 51,184, 86,229, 61,145, 13,138,188,218, 53,187, 6, 28,224,236,199, 61,220, 92, 77, -120,133, 30,104, 64, 84, 8, 28,161,106, 16,189,105,123,128, 55,210,188,205,150,243, 6, 64,199,184, 44,202,188,183, 88, 55,213, - 78,135, 93,255,191,120, 23,107,127,252,104, 76, 25,146,111, 1,249,165,122, 79,187, 28, 90,169, 56, 41, 66,242, 38, 6,184,184, - 42, 38,188,254,143, 37, 6, 50,222, 96,144,123,184,232, 9, 27,199, 95,112,157, 52, 0, 84, 66, 57,135, 16,146,135,243,149, 92, -185, 53,156,196,233, 48, 61,110,162, 35,123,228, 44, 86, 45,222,189,117,243,160, 39,114, 43, 65, 14, 0, 42, 25,113, 24,159, 76, -245,216,249, 23,208,162,159,119, 75,231,174,202,187, 4, 16, 58, 3, 88,216, 55,245,202,181,180,200, 4, 43,191,229,212, 30,255, -141,153, 45, 63, 98,138, 91, 12,181,134,197, 36,163,234, 44,231, 59,214, 76,213, 98, 92,158, 74,251, 71,182, 5, 93, 73, 83,125, - 89,240, 97,202,141,206, 75,244,136,234, 83,140,154,210,123, 86, 35, 27, 83,125, 42, 11,216,247, 53,216,255, 40, 72, 8, 71,221, - 38,169,120, 76,216,195,234,114,229,233,253,120, 26,120,148, 9,174,194,238, 23,106,134, 68,170,225,248, 85,171,232, 39, 29,125, -164,145, 80, 46, 6,126,151,126,127,116,123,119,255,252,244, 56, 95, 76,136,140, 71,224,119,128,190,117,248,221, 33,168,205, 52, - 7,101,153,183,237,136, 76, 11, 57, 68,240, 94,102, 5,131, 4, 71,186,200, 70, 66,178, 24,108,237, 20,197,248,209,199,248,191, - 48,159, 31, 1, 88,187,154,158,132,129, 32,186, 31, 96,193, 0,234,193,196,191,224,111,240, 98, 60,248,255,175,198,187, 38, 96, - 64,160,133, 66,187, 51,238,206,236,108,151,143, 72, 76, 36, 27, 66,202,161,165, 41,179, 51,111,222,188,103,206,157, 3, 79,150, -244,182, 78, 18,198,195,197,209,220,145,197, 82, 55,252,149,164,232,121,103,119, 89,103, 76,228,183, 29,166,166,153,203,186, 70, -193,199, 67,154,103,114, 80, 37,173,123, 4,232,138, 65, 76, 64, 93,244, 1,161, 22,126, 76, 0, 49,218,207,179, 21, 3,191, 3, - 70,185,110,226,153, 5, 83, 6, 94, 64, 87,179,105, 54,139,160, 74,168,222, 87,170, 63,152,186,128, 68, 50,233,147,246, 48,180, -156,111,248, 45,174, 71, 76,155, 1,113,250, 84, 55,212,131, 59,138,236, 58,196, 50,125, 67, 62, 57, 78, 10, 76, 36,245,224, 49, - 25, 54,177, 2, 87, 34, 68,178,105,253,254, 87, 56,207,100,121, 10,156,128,197, 38, 14,172,218,241, 85, 32,247,239, 29, 33,168, - 74, 61, 13,175,239,238,251, 31,139,106,179, 3,206, 19,235, 6,119,196,155,240,165,181, 79,198,160,117,179,245,246,205, 23,236, - 74, 61, 62, 76, 70,195, 98,185,170,155,186,105,255,227, 17,196, 44, 93,189,202,166,189, 90,178,234,245,183,205,177,116, 39, 6, - 21, 19,112, 86,119,141, 26, 45,234,219,192,158, 75, 52,209, 28, 9, 31,254,115, 75,194,233, 16,231,223, 84,148, 93,231,135, 72, - 96,191,136, 80, 67,130,116, 82,170,206,234,187,242,188, 5,231, 69, 76, 11, 29,101,165, 73,102,242,104, 22, 41,195,100,165, 59, -103,108,174,180, 44,136,186,128, 75,166,163,179,131, 76,148, 82,113, 42, 58,137,173,235,120,159,236,223, 23,181,235, 19,253, 49, -236, 74, 78,247,109, 49, 25,222,242, 81,217,245,180,142,123, 20,230, 94,122, 65,146,213,240,223, 15,200,205,132,188, 3, 3,227, - 55,148,111,141, 2, 82, 54,110,190,221,246,179, 45,173,233,107,219, 3, 87, 67, 57, 87,213,194, 84, 43, 91, 46, 77,185,106,171, - 89,189,157, 54,213, 28,203, 57,172,191,252,183,184,157, 7,183, 85, 22,235,246,217, 17,147, 35,147,182, 88,188, 3,128,135,158, - 26, 38,246,198,180,104, 37, 24, 1,164,105, 6, 0,141, 78,206,121,250, 36, 60,101, 73,231, 81,194, 75,191,253, 50,112,104,173, -125,126,121, 29,141,199,199, 58,117, 93,230,158,115, 55, 12,205, 48,234,163, 56,120, 54,184, 99, 7, 35,203,185, 76,193,219,126, - 27,167,116,212,176, 24, 37,130,141,175,135, 80, 93,134,254,207,132,224,191,191,126, 4,160,237, 90,114, 26,134,129,104,198,113, -170,148,150,130,144, 88,177, 64,226, 18, 44, 56, 19, 7, 64,226,176,192, 54,162, 63,154,230,227,218,131, 61, 99, 59, 78,105, 37, - 36, 68,151, 85, 85,165,141, 51,126, 51,126, 31,121,114, 27,129,211,155, 38,252,166, 73, 23,225,103, 80, 62, 65,148, 54, 64,202, -175,207, 60, 74,129, 16,192,228,227, 40,227, 76, 11,194, 77,119,243, 39,160,248,225,232, 6, 65, 45, 48,137,250, 2,193, 32,156, -146,129,111,239,194,165, 50, 61,135, 20,128,210,179,242, 93, 69, 96,254,179, 91,145,188,103,107,111,219,199,222,130, 12,159,166, -114,250, 52,191,221,214,213, 7,102,179, 12,106,233,242,135,229, 64,137,179,171, 49,183,235, 90,138,172, 81, 38,167, 73, 83, 48, - 5, 67, 62, 35,157, 4,143, 70, 17,254, 52,242,126,129, 89,158, 47, 74,105, 75,106,213,171, 70, 15, 54, 94,234,204,102, 14,199, -171,121, 96,151, 67, 82,208, 35,179,133,237,195, 90, 74, 64,164,146,103,155,103,119,199,238,111, 46,222, 62,183, 93,167,156,114, -140, 69, 92, 20,246, 0, 46,114, 8,237, 71,119, 10,223, 27, 85,101,217,163,144, 15,119,215, 22,122,172,150,173,235,194,147,212, - 14,243,135,250, 14, 73,176,184,167,132,146,192,109, 65,103,142,179, 2, 72,254,239,250, 34,165,115, 49,246, 12, 96,229, 61,115, -225, 77, 8,221, 66, 76, 41, 85, 30,140,113, 16, 92,170,223, 96,155,162,171,242,178,238,234,144,204, 16,153,214,225,187,217,167, -118,116,222, 15, 3, 51,135, 38,244, 62,182,213,143, 13, 13,131,106,244, 19,185,180,232,192, 56, 18, 44,234,111, 41, 63, 7, 7, -129,181, 97, 78, 45, 61, 5,192,109,136, 56,144,166, 84, 32,219, 25,198, 89,166, 27, 71,121,238,135,237, 30, 59,213,245, 22,101, -123, 61, 45, 99, 23, 31,114,165,131, 51,207,104,168, 0, 3, 93, 31, 7,141,151, 5,229,206, 82,128,198, 8,121, 45,117,175,117, -153, 79, 10, 40,116, 87,211, 94,160, 15, 34,235,165, 65, 41, 15, 28, 71,101,145,187, 33,147,247,253,214, 56, 91,224, 30,221,200, -158, 5, 5, 22,151,105,131,105, 50, 81, 58,109,254,145,174, 74, 46, 65,188,197,114,110,142,112, 25,112, 34, 66,120,206, 36,135, -179,132, 64,147,148,163,136,220,237, 85,178, 70, 32,161,197, 4,155,229,118,255,245,250,242,188,217,172, 89, 49, 51, 62,210, 57, -190, 66, 11, 37, 90,173,225,124,251,128,199,111,141,158,218,134, 26,172,244,181,220, 85,113,227,159, 23,243,181, 94, 37,199,232, -248,127, 16,254, 91, 0,210,206,166, 41, 97, 24, 8,195,187,105,164, 69, 20,245,230,232,140,122,242,175,248,255,143, 30,213,131, - 7, 29,133,161, 64, 63,146,172,201,110, 66, 91, 42,142,163,192,133,143, 67, 25,218,101, 63,222,125, 31,253,109, 64, 63, 64,201, -250,213, 49,184, 68,194,253, 85,148,151, 19,182,175,169, 79,230, 81,206,199,245,136,103,176, 82,193, 71, 50, 2,243,226,105, 52, -129, 65,134,204, 35,238,171,196, 36, 28, 90, 94,176, 10,173, 48,246, 15,179, 93,173,138, 28,231,217,158,138,196,173,131,243,122, -192,211,179,155,243,139,219,235,122,243,182,242, 63,118,161,209,118, 73,156,179, 13,111, 41,241,193,171,138,201, 56, 98,177, 43, -208,237, 15, 22, 32, 2, 11, 69, 32, 98,181,105, 14,234,106,150,171,137,122, 47,155,167,182,221, 14,253, 87,241,176,166, 74,165, -143,225,104,232,212, 79,231, 39,233,173,130, 27, 32,167, 58, 43, 50, 61,195,152,174, 44,170,250,241,229,115, 93, 53,219,154,182, - 97, 95, 17,142,132,218,108, 72, 19,110,106,251,218,218, 39,128, 59,128,135,251,203,233,201,148,154,106,181, 90, 47,201,150, 73, -178,249, 79,234,247,174,197,100,248, 8,253, 35, 71, 60, 86,225,225,239,211, 76,149,190,212,112, 56, 15,187,203, 24,154,198, 41, - 27,149,201,160, 4, 68, 38, 80,167,142,179, 4, 71, 55,196, 44, 65,199, 69,138,248, 32, 22, 61,136, 13, 58, 37, 80, 66, 92,154, - 22,216, 66, 76, 10, 36, 44,246, 43,232, 48,183,167,110,155, 42, 57,240,237, 58,237, 72,123,147,170,196,223, 0, 24, 83,220,162, - 49, 43,198,150,145,236, 88,197,149,212,164, 1, 8, 72, 14,127, 26, 26,197, 81, 30,146,250, 37,218,103, 72, 41,194, 35,218,221, - 52,170,131,151,237,130,187,165, 52, 7, 32, 1, 19, 59,193, 91,227,224,143,143,159,152, 80,137, 6,223,165, 76,129,105,117, 97, -230,147, 90,149, 80, 62,131,210,254, 53,151,229, 96, 56, 7, 16,253,165,109,157,217,250,176, 14,213,194,180, 85,240, 56, 48,161, -238,139, 22,154,221, 2,174,219,155, 69,143, 45, 27,211,213,167,242, 34,223, 84, 27,105,185, 7,203, 89,180,244,221,181,224,160, -231,114, 60,212,161,227, 96,209, 63, 53,106,133,199,200, 98,124, 25,169,250,111,185, 46,151, 90,199, 2,170,183,123, 47, 42,185, -177, 56,138,126,104,151,255,160, 95,196,225, 96, 64, 13, 58,175,188,212, 98, 27, 29,253, 80, 35,158, 48, 37, 79, 68,135, 19,187, - 63,100, 84,254,246, 37, 0,105,231,214,147, 48, 16, 68,225,157,109, 45,197,219,147, 81,140,250,143,252,249, 62,251, 98, 8, 49, -209, 24, 81,161,116,219, 93, 59,183,221,173,162, 96,124, 36,133, 0, 73, 51,221,153, 57,231, 59, 57, 31, 56,216,237, 1, 81,187, -123,137,241,123,194, 31,170,188, 18,237,184, 63,146, 77,135,225, 60, 59, 67,117, 61,200, 70,211, 66, 72,188,226,148,140, 24, 25, -111, 88,164, 9,106, 48,170,235,202,111, 22, 95, 40, 57,187,129, 99,138,217, 98, 71, 90, 73,126, 1, 99, 26, 95,135,147,104, 84, - 60,116,232, 20,233, 16,124, 19, 40,111, 94,158,183, 37,243, 79,142, 75, 3,173,101,133,201,134, 46,149,202,104,108,117,214, 60, -252, 54,103,224,234,168,174, 38,246,254,117,245, 64, 88,224, 94, 33, 98,253, 30, 14, 38, 24,183,105,249, 98,190,211, 41,252, 84, - 61, 83, 75, 18,191, 91,223,159, 86,211,139,250, 96,222,192,220,132,187,231,183,235,110, 61, 28,111,214, 67, 53,199, 94, 36,180, - 40, 63,196, 7,233,178, 53, 11,122, 32,157, 27,115,123,115, 57,155,157, 12,101,115,241,248,254,250,210,172,200,115,235,254, 93, -220, 77,150,235, 36,173, 6,198,240,218,154, 52, 51,135,214, 56, 15,165,133,179, 73,217, 58, 10, 84,228, 60, 55, 47,157, 60, 19, - 9,149,140, 78,227,245,144, 4, 49, 92,167,163, 87,137, 89, 49, 73,244, 98,162,213,200,235,221,152, 14,239, 94,145,143,194,111, -207, 4, 18,228, 93,142, 44, 85, 73,218, 6,157,123,131, 74, 62,252, 54, 51,123, 48,169,210, 71,139,131,100,109, 11, 33, 71, 54, -124,236,124,194,243,185, 21,192, 36, 7, 47, 33, 24,136,170, 60,200,163,136,195,194,169, 63, 20, 85,142,132, 70,198,200, 2,136, - 3, 76,208, 97,187,103, 90, 49, 72,134, 96, 18,146,163, 74,193,210,215,210,130,223,225,191,194, 5, 88,213,187, 15,223, 60, 97, -112, 95, 81,247,136,104, 26,238, 17,160, 49, 18,133,203, 14,125, 3,230,211,173,240,132, 19, 40,147, 8, 5, 30,212, 21,139, 65, -213, 87,182,114,157,139, 30,246,252,222, 1, 58,170,216,116, 33,108,218,141,205,214, 29, 63,202,179,199,118,160,108,240,237,225, -171,204,143,143,240,178,174,165,251,162, 47,120,252,195,154,109, 47, 40,171, 12,247,246, 13, 42,186,131,140, 93,196,233, 19,108, - 89,246,134, 92, 20,142,123,113,192,192,172, 70,231,239,141, 91,199,179, 89,161,168, 3, 97,173,103, 80,123,179, 71,225,253,101, -221,197, 31,252, 20,128,180,179,201,105, 24, 6,162,240,216, 77, 83, 40, 85,133,216,128,196,158, 67,112, 7,110,205, 21,216,118, - 7,170,186,169,248, 41, 16, 39,246,224,249,115,146,182, 82, 43, 33,117, 87, 41,149,210,228,121,230,205,243,231,106,172, 32,216, -187, 98,103,168, 60,158, 80,121,151,206,116,108, 84,229,157, 43,187,207,237, 28, 96,157,166, 91, 35,220,255, 84,226,155,172,184, - 71, 69,249, 37,216, 75, 59,243, 55, 29, 47,228,244, 82,249, 88, 88,122, 34, 22, 60,189,139, 46, 85, 26,160,242,242, 56,216,185, -246, 54, 79,163,235,250,137,185,127,118,250, 59,153,104,191, 58,209,133,138,137, 18,215,224,126,248, 12,213,153, 33, 7, 2,125, -232, 62,220,215,245,205,213,244,121,243,241, 54,184,109,237, 25,157,145, 31, 27,145,105, 16, 21,152, 14,241,175,134,175,233, 44, -131,184,107,225, 46,255,238,226,114,251, 25,214,241,123, 5,176,125,239,114, 63,177,228,247,169, 97,139, 97,199,173, 70,195,215, -124,116,245,211,195,109,189,188,184,170,225,183,105, 86,175,187,117, 67, 16,227,214, 90,132,255, 72,188,183,224,166,236,240,154, -131,191,240,176,156,230,178,189,202,234,249,149, 5,169,131,121,237, 23,115,255,178,113, 6,237, 19,191,141, 97,117, 32,167, 86, -160, 56,108,138, 64,212, 20, 13,255,133,195,170,201, 33, 30, 9,224, 75,102, 70, 23,117,173,226, 5,134, 5,234,189,187, 49,134, - 16, 75,149, 80,178, 94,252,224,165, 74,206,184, 86,169, 47, 17, 63,181, 27,176,140, 94,123,229,239,250,188, 55,225,204,148,254, -107,116, 92,139, 11,187,126, 15,143,184, 54,162,242,140,228,152,240,149, 69,226,185,211, 76,208, 83,242,205,153,113,160,120, 47, - 97,218, 50, 71,219,148, 93, 6,206, 38,101,194,221,160,237,189, 81,104,101,158, 66, 82,109,202,173,109, 75,232, 25, 10,241, 86, - 77,126,234, 35, 83, 66,232,126, 19,153,187, 77, 41, 96, 12, 24,118,194, 36,200, 69, 63,155,102, 81,241,106, 60,243,106, 83, 56, - 92,245,156, 69,244,198, 79,133,152, 51,238, 88,140, 99,191, 58, 78, 7,242,133,165, 85, 27, 15,192, 35,136,163,139,104,108,102, -250,115,163, 47, 75, 2, 98,105,101, 68,136, 98,234, 75,111,196,211,165,113, 60, 54,179, 4,167, 59, 54,225, 50, 47,141, 64, 88, -243, 9,209, 79, 28, 25, 91,109,152,236,167,123,112, 70,121,158,220, 73, 7,232,189,154,164,112,139,131,114,254,252, 62,185,242, - 85, 72, 42, 45,127, 2,144,118,237, 58, 13,195, 80,212,118,156,166, 52, 45, 45, 15,129, 84,193, 15,176, 32,177,244,199,249, 6, -118, 6, 70, 88, 0,137,231, 80, 41, 37,117,147,216,216,247, 94, 39, 78, 72,165, 72,180, 91,171, 14,174,227,227,251, 58,231,116, -235, 51, 67, 80,158, 13,141,229, 61, 95, 41,104,198,214, 40,143,204,181, 54,202,211,128, 77, 19,200,123,243, 87, 82,158, 67, 61, - 60, 30,152, 88,178,112,142,130,155, 62, 33, 57,252,149,243, 67, 64, 16, 16,154, 60,230, 73,154,207,190,101,133,130,148,166, 36, -137, 16, 34,204,249,249, 45, 55, 76,233,218,225, 32, 22,108,162,218,142, 25,164,192, 37, 32,159,132,248,119,141, 70,183, 4, 97, - 36,253,104, 79, 92,202,228, 50, 77,238,191,127,222,152,185,100,124, 53,153,223, 92,156,174,115,117,251,252,242,176,255, 79, 13, - 36,222, 8, 31,171, 96,207, 76,251,243,145,239, 88, 26,114, 80, 50, 69, 81,170,109,113,190,152, 92,157, 29,142, 62,205, 93,153, -191, 91,136,103,236, 85,183,246,210, 70,253, 43, 46,174,143,231,203,147, 89, 58,139,182, 54,156,207,244,211,199,230,241,107,179, -134,137,160, 49, 44,237, 63,245, 65, 78,118, 87, 4,238, 83, 38,142,132,152, 39,241, 34,137, 15, 98, 23, 30,218,172,217, 6,129, - 0, 21, 60, 87, 49, 36,175,188,110, 90,113,116, 53, 5,248, 8,192,221, 53, 11, 73,213,145,155,254,202, 40,111, 39, 64, 32,147, -145, 38,211, 76,101,168,135,209, 1,247, 46,255,211,235, 6, 58, 21,116, 3,243, 20, 38, 34,161,111, 97,176,126, 12,135, 81,248, - 58, 18,134, 32,120,121, 32,206,227, 68, 77,200, 79, 1, 78, 52, 76,108,145,151,142,241,158,170,160,236,216, 80,186, 49,231,128, -197,114,233,115, 89,195,125, 97,136,251, 10, 20,247,143, 35,116,156,177, 59, 5, 44,221,160,150,213,120, 16, 54, 28, 66, 22,145, -215,131,251, 26, 56,147, 54, 30, 23, 44, 42,149, 22,153,221, 49,163,119,218,201,222,184,190, 4, 92,174,206,125,161,178,231,192, -194,119,169, 44,202, 59, 66,147,123,186, 49,224,161,219,205,249, 16,247,197,157,184,105,154,234, 33,251,130, 0, 83,181, 61,129, -131, 57,231, 30,110,217,159,224,189,169,210,160,152, 57,233, 9,195, 50,117, 32, 69,215,158,224,116,205,151,195,241, 66, 21,249, -174,218, 14, 87, 43,235,212,242,164, 24, 89,172, 6,175, 18,166, 64,175, 92,114, 9, 12, 77,116,184,195, 75,181, 86,163,128,154, -109, 81, 96, 13,128,211, 90,112, 4,131, 6, 82,106, 21, 22, 61,232,202,105,178,135, 26,220,237,235, 87, 0,210,174,174,167,109, - 24,138,250,171,105, 74, 33,168,108,171, 54,132,196,222,224,157,255,192,191,231, 47,236, 5,169,211, 52, 9,150,174,105,155,196, -246,157,125,237,235, 56,140, 48,164,229,169,170,170, 42, 77,210,235,235,115,206, 61,103,192,103,212, 75,239,249,201, 42,255,126, - 62, 45,127, 57,214,255,249,182, 44,239,229,121,102, 96,105,147,127, 55, 12, 26,171,244, 63,230,177,107,183, 36,107, 23,100, 53, - 6, 83, 62,161,192, 82, 60, 56, 71, 4, 23, 45, 3,193,206,229, 12, 76, 95,235,205,170,100,243, 98,185, 63, 92,120, 13, 91,212, -185,164,171, 17, 74,138,160,216,141,168,100,112,103, 94, 42,249,179, 51,167, 50,122, 52,182,113,123, 5,123,170,101,120, 63,185, - 91,157, 63, 23,242,168,251, 71,211,175, 25,191, 59, 61,191,189,250,176, 92,205, 69, 39,239,229,101,249,248,227,193,232,169,107, - 40,147,123,119,134,207,244, 25,184,166,136,177,228,212, 32,135, 15, 55,204,238, 52, 60, 29,250,147,162, 95,159,151,235,101,113, -179,109,191,213,187, 77,219, 54, 62, 97, 13,206, 24, 95,201,217, 69, 81,124,169, 22,159,170,194, 42, 63,245, 94,239,187,162, 84, -155,103,253,244,220,212, 90, 55, 36,233, 49,236,191,142, 32,126, 63, 65,168,106,193,228,215,170,188,174, 22, 87, 31, 43, 37,196, -247,250,184,237, 52,104,243,203,232,101,201, 90,171,182, 7, 36,222, 57, 75, 3,154,233,246, 89, 54, 20,119,163,195,134, 47,133, -248,188,161,165, 27,170,131,251, 33,191,251, 38,230,100,199,225, 78, 75,226, 19,128,191,240, 48, 30,107,181, 31, 0, 68, 79, 36, - 95, 55,130,216, 3,200,219, 40,102, 62, 68, 76, 30,178,200, 51,150, 97, 20, 99, 30, 15, 45,213,209,248, 34, 22,230,208,125,200, - 49, 89, 71,172,148,240,163,185,194,213, 9,145,204,187,227,163,150,156,208,121, 76,209, 72,152, 76, 76, 53,195,206, 52,240,210, -144,130,134, 80,111, 26, 54, 63, 97,219, 16, 18,169, 36,215,174,201,181,252, 8,157, 0,217,185, 55,208, 34,200, 79,108, 35, 92, -102,113, 29, 12,110,145, 45, 78,148,245,184,107,182,196,100,240, 23,195, 28, 57, 92, 21, 10, 24, 36, 6,132, 27,138, 70,252,167, -140, 36,222,101, 24,131, 51, 48, 81,220,137,130, 49, 48,180,148,156,216,143,209,196,114, 64,126,195,183,238,218, 45, 3,251,234, -217,216, 9,224, 58,159, 40,196, 53, 85,227, 2,143, 99, 73,120,127, 92, 31,237,214, 67,116,161, 72, 35,205,131,175, 23,117,105, -150,152,124,223,207, 40, 62, 51, 30,245,114,207,153, 18,100,197,145,153,114,195,123,146, 50,243,227,143, 0,164, 93,203, 78,195, - 48, 16,204,230,161,182,162, 1,218,130, 16, 23,224, 6, 31,192,255,255, 6, 8,241, 3, 21,130, 22, 72,147, 54,137,189,120,237, - 93,199,105,194,169,183, 86,141, 34,185,137,199,246,236,236, 76,234,223,101, 53,232,134,135, 99,219,204, 83,212,113,157,188, 9, -130,155,107,235, 76,199, 62,213,178,145, 7, 91, 70,227,222, 67,153,196,244, 10,106,204,136,145,100,190, 21,181, 51,212, 19,111, -180, 99, 51, 57, 63, 73, 92,218,171,103,126, 93,142, 27,165,193,237,234,242,117, 71,142,113,179, 34,122, 90,149, 87,115,245, 93, - 44, 41, 93,202,167,108,163,152, 87,240,114,234,182, 40,172,194,155,232,160, 75, 30,162,204, 30,224,107, 89, 41,189,251, 35, 5, -242,197,241, 91,185, 55,159,111, 33, 51, 3,126,255,218,190,124, 98,213,144, 50,125,145,164, 55,170, 93,255,255,168,112,160, 30, -192,128,177, 81,129,130, 42, 13,200,156,134,234, 1,170,168,218, 77, 70, 49,182, 25,164,121, 62,125,190,152, 30, 40,206,214, 28, -179,241, 44,163,252,166, 6,205,106,143, 31,123,131, 31,102, 37, 32,235,126,243, 79,237,126,155,245, 79, 93, 71, 84, 36, 56,156, - 12,238,206,128, 33, 35,124,135,187,217,236,241, 58,191, 95,206,231,233,228, 97,149,147,169,108, 83,108,203,109,101,205, 1, 23, -211,108, 83, 0,109, 26, 19,135,229, 94, 71,235,233, 5, 62, 79,163,115, 32, 13, 12, 78,134,198, 9,113,119,218,239,204, 90,233, - 6,173,200,114, 1, 5,135, 3, 43, 44, 1, 34,231,103,141, 30,229, 65, 10,219,174, 97,202,193, 19,198, 46,152, 72,138,174, 74, - 32,153,121, 27,232,171,209,161,147, 86,162,223,239,200, 22,222, 49, 42, 4,188,113,239, 65,179,126,134, 26,130,168, 19,141, 72, -121,118,183, 18,223, 4, 91,119,102, 75, 87,123,204,229,196, 12,106,107,234,182,237, 28,132,100, 6,151,164,137,134,214, 78, 52, - 54,201, 57, 79, 46, 19,171, 40, 51,235,214,158, 98, 12, 42,208, 54, 48,214,198,110,162,226, 14, 97, 36, 61,184,185,170,198,134, -148, 51,246, 7, 91,150, 98,224, 81, 60, 70, 31,136,173, 3, 9, 19,116,168, 26, 1, 31,199,198,218,177, 17, 7, 50,115,125,172, -151,128, 97, 97, 19, 71,186, 50, 49, 12, 72,234, 7,130, 56,162, 74,123,123,119, 39,161,234,183,134, 33,244, 97,208, 23,134, 67, -202, 84, 72, 8, 22,200,198, 82, 47,141,172, 73, 98,106, 59,228,233, 75,156,138, 25, 89, 28, 46,226,174,165,173,147,133,219, 16, -120, 81,132,120,209, 9,138, 54,223, 49,120,168,199, 84,118,163,208,255, 39, 0,109, 87,179,147, 48, 16,132,103,183, 11,133,136, - 74,122, 50,241,228,193,151,240,253, 31,193, 39, 48,145, 72, 8, 65, 12,208, 82,186,179,238,204,236, 79, 41,226,197,200,133, 75, - 19,104,187,157,206,126,243,253, 12,249,145,182,231, 30,254, 15,133,126, 72,229,150, 7, 41, 86,121, 21,115, 95, 85,148,174,102, - 64,221,133, 4,108, 12,102, 96,116, 69,196,190, 3, 92,182,137, 86, 63,201,193,172,228,246,201,243,102,152,139, 65,166,228, 78, -191, 29, 54,114, 92, 13,240,186,134,151,201, 87,161,238,142, 86,142, 69, 70, 75, 57,102, 48, 80,251, 67,114, 39,113,250, 56, 0, - 88,128,117,196, 92, 97, 59,200,249,218,178,177,154,128, 54,180, 83,115, 11,139, 55,244,163,184,170,143,216,184, 3,118, 59,196, -134,132, 33, 68,154,148, 63, 92,244,200,148,182, 7,206, 92, 67,198, 84,207, 35, 62,177, 15, 77, 92,229, 91,232, 84, 7,229,190, -168,237,241,126, 68, 4, 32,195,171,137, 99,196,220,186,197,154,134,107, 84, 84,182, 29, 76,199,186,245, 39,110,116,219,158, 62, - 62,155,213,169,219,178, 62,203,254, 13,118,159, 50,193,223, 23,247, 74,153,231,249,236,105, 62, 45, 17, 22,203,189,133,195,251, -154,180, 69,123,219,249,247,156,175, 88, 51, 3,183, 19,127, 23,180, 88, 46, 39, 55, 68, 23,243, 93, 92,138, 4, 66, 81, 32, 14, -138,251, 64,222, 34,105, 69,189, 69, 16,198,143,156, 13, 3,177,121, 15,118, 99,217,188, 47,117,133, 42,242,111, 66,243, 17,251, -242, 80,227, 57, 89, 94,112, 36,129,157,197,207, 58,116,214,204,155,231,245,108,147,147,140, 74, 60,235, 24,148, 70, 70,243, 38, -181,240, 18,108, 68,136, 31,106,117,193, 54, 86, 17,221,214, 65,239,213,239,100,149,203,172,156,248,141,105,252, 10, 17,106, 20, -225,135,128,196, 40,246, 51,244,202, 40, 97, 92,156,236,158,135,126,190, 15,168,166, 85, 61, 46,118, 20, 85,203, 99,135,112,121, -165,198,251,235,197, 42, 17, 39,200,140, 13, 19, 99, 39,211,230,152,195,132,125,213,239, 57,108,166, 88,173, 46, 39,147, 97,116, -200,239, 3, 21, 29,132,127,225,167, 92,208,102,220, 21, 18,165,206,118, 53,131, 97, 0,158,111,172,134, 83, 93,119,105,198,127, -101,111, 65,149, 68,151, 35, 85, 52,182, 45, 98,101,247,157,129,113,162,145,114, 15,213,227,122,179,212,161,190, 27,149,188,244, -201,150, 99,212, 28, 27,201,182,102, 50, 27,211, 6, 53, 25,200, 33, 19,137,104, 58, 2,156, 88,153,189,148,208, 70, 93, 46,230, - 25,225,213,207,183, 0,164,157,205, 78,195, 48, 16,132,189,150, 19,104, 90,126, 36, 36,206, 8, 46,188,255, 3,193,165, 18, 7, -138, 34, 90,112, 27,199,246,226,245,218,137, 3,105, 85, 9,181,135,168, 61, 52,117, 35,119,119, 51,243, 77,226,207,244,211,102, - 7,127,197, 24,255,169, 40,225,140, 91,187,112,242, 5,152, 59,134,209,213, 13,165,137, 4, 51,169, 35,194,100,210,131,237, 16, - 40, 74,115,194, 9, 55, 64,246, 88, 37, 25,142,212,110,255, 78, 19,136,241,202,184, 23,254,122,185,248, 54, 99, 39,151,140,181, - 30,135, 20,169, 52, 51,138,227,252, 90,104, 71,214,108, 66,236, 70,217,159,236,104, 67, 7,150,186, 99, 74, 31,149, 13,233,208, -253,139,119,113,126, 18,118, 85,219, 58,187,241,126, 75,249,196,162,150,100,128,218,228, 49, 75, 21, 71,213,254,200,165, 61,243, -149,242, 2, 86, 83, 4,199, 48, 37,112, 57,238, 56,156,164, 54,222, 56,223,153,190, 53, 94,247,182,183,132,253,166, 68,113, 8, - 37,153,248,114,206, 56,177,219,155,245,206,188, 9, 90, 26,243,143,225, 12,135, 2, 54,145,132,243,188,104,158,110, 86,173,182, -235, 86,127,106, 99,173, 59, 80, 10,160, 57,244,246, 67,155,112,220,121,119,219,200,122, 81,191,182,138,221, 63,209, 13,153, 76, -112,254, 87,241,158,194, 61, 5,140, 96,210,249,139, 13,166, 88,164,177,106,202,118,161,162, 65,158,148,108,232, 75, 5,204, 96, -163,199, 81,232, 56,196,186,179,246, 92, 22,101, 69,230, 52,225, 16,121, 90,120,170, 10,124, 1,187,170, 51,100, 38, 7, 25, 99, -166,162, 74, 28,186,197,169,244,174,120,114, 95,201, 3,112, 70, 95, 37,143, 23, 20,160,122,166,114, 59,206, 76,130,196, 81, 41, - 2,226, 34,230,168, 38,241, 35,218,131,235, 28,241,220,113, 9,170, 67, 67,218, 71,154,198,216,104,247,234,137, 51, 99, 13,109, -238, 68,188,118, 20,219, 4,252, 81,158, 93,132, 69,135, 94,118, 46,144, 19, 63,211,210, 96,185,236, 88,202,131,161,248, 63, 24, - 12,183, 32,102,252,101,120,206, 77,193, 51,222,194, 57,157,200, 41,237,140,156,108,238,200,105,184, 52, 76,136, 64, 80, 9,170, - 34,237,145, 82,149,170,136, 80, 91,153,174, 83, 82,133,215,227,255,105,188, 91,157,230,169,212,170,133, 22, 54,148,246,225,135, -111, 46, 87, 97,217, 21, 19,110,145,211, 73,225,162,106, 32, 69, 17,224, 80,254, 62,220, 61,110,247, 45,111,142, 87,213, 85,228, - 77, 30, 61,225, 31, 1, 24,187,142,165,134, 97, 32,170,234, 16, 19,202,112,224,200, 39,240,255, 23,254,133,129, 11, 12,101,128, - 16,136,139, 86,104,139,100,197, 3, 36,158,220,237,216,210,106,203, 43,110,111,207,254,143,190,205,127, 66,193, 7,102,241,102, - 78, 19,136, 21, 35,129, 13,116,162,158,204,148,233, 95, 34, 22,222, 48, 72,129, 41, 78,210,157,141,145,231, 41,251,138,134,204, - 88, 65,126, 62,171,196, 76,215, 85,219, 60,246, 62, 45, 94, 71, 96,235,108,198,137,234, 68,144,251, 51,154,157,183, 36,147, 51, -167, 86, 63,245,146,122, 3,234,207,136, 0,100,157,197,123,163, 58, 52,165, 67,160,225, 67,213, 13,243,100,114,221,166, 67,188, - 71,178, 73,172,104, 80,182,122, 51,225,183,208, 9,179, 73, 83, 5,141,103, 13, 94, 66,172,199, 53,230,224,195,102,192,254,237, -210,165,227, 36,158,145, 24,239, 38, 0,201,123,161,219,170,183,168, 19, 48,104, 56,247,102,211,245,235,174,223,144,115,115,200, -110, 83,123,107,192, 95,131,251,146,126,151,202, 92,159,158,124, 3,220, 60,191,166,231,185, 80,118, 12, 38, 4,135,228,120,210, -218, 90,208, 32,233,216,171,179,133,191,127,115,221,168,210, 10, 7,202, 15, 41, 86,177, 85,118, 44,184, 38,238,187,234,162, 81, -149,211,177,154,124,103,230,159,189,132, 18,110,197,228, 4, 83,103, 41,186, 88,250, 38, 50,254, 43, 65, 54, 76, 53,121,101,197, - 83,146,125,157,203, 70, 16, 47, 39,109, 76,156,240,221,145, 21,232, 72, 29,172, 88, 8, 74,108,207,133, 0,173,102, 44, 68,153, -168,100, 35, 55, 0,180, 52,245, 77,156,111,222, 88, 81,151, 69, 6, 89,192,238, 32,222, 23,187,248, 34,140,236, 34,118, 22,119, -219, 32, 70, 96,151, 38,244,122,187,178, 43,213,125,245, 56,154, 24,186,254, 99, 28,155,246,104,241,174,183,192,195, 85,226,188, -210,215,160, 61, 8,196, 37,214,108,199, 6,188,159,138,155, 26, 76,211,105,144,182,135,154,168,169,197, 35,187, 82, 15,150,178, - 9,114, 6, 22, 97, 58,146,243, 80,182, 78,231,119, 96,172, 7, 35, 63,244,255, 52,165, 67,130,187,174,210,118, 37,227, 67, 77, -192, 24, 4, 65,226,208,221, 56,111, 44, 42, 85,162,230, 2, 38,163, 77,179, 48, 96,143, 92,211,186,182,181,173,183, 13,194, 2, -152, 67,165,144, 33,214,141, 91,156,136,162,188, 79, 58, 59, 81,105, 63,216,180, 18, 92,170,245,129,244,103, 60,114,227,229, 40, - 79, 55,191,123,185,197,187,209,171,248, 28,214,122,151, 25, 51,187,126, 4, 96,236, 90,118, 26,134,129,160,215, 78, 83,104, 11, -170, 56,130, 16, 71, 78,252,255, 55,112,231, 31, 56,241, 16, 42, 77, 19, 63, 22,239,174,237, 56,164, 45,156,171, 70, 81, 90, 79, -118,103,118,103,154,249,187, 14,142,129,227, 28,229,195,233, 4,144,255, 11,208,179,167, 94, 32, 30, 96,108,147, 48, 41,243,217, -237, 84,139, 77, 24,228,108, 46, 93,204,152,181,202,185,172,161,222,149, 43, 75,167,133,244,138,101,114,179,120, 10,151,235, 96, -173,194, 3,226,182, 93,188,251,235,207,222,113,120,172,198,178,115,160,146, 10, 86, 48,148,130,159,148, 22, 3, 63,195, 5, 56, -209,238, 33, 81,225,236,120, 51,242, 36, 3,119,157, 13,227,165,103,183,153, 38,155,161,175, 77, 4,247,230,126,179,124,251,136, -199, 42, 73,178,109, 54, 23,131,211,196, 72,152,182, 89,237, 52, 27, 79,190,216,229,185,154,129,212, 84,154,115,191, 10,216, 54, -122, 96,169, 48, 62,184, 29,239, 29,182,100,117, 24, 91, 71, 88,106, 8,206,247,214,117,206,147, 54,155,241, 29, 43,190, 46,252, -227, 0,201,205,172,216, 3,231,193,152,199,237,230,101,223, 63,119,135,144, 62,242, 20, 32,225,136,182,234,185,209,105, 21,182, - 0, 27, 99, 60,224,235,142,126, 99,207, 68,178, 56, 75, 72,165, 94, 91,195, 96, 80, 56,179, 71,146, 23,253,175,225,209,217,155, - 29, 36,236, 56, 77, 89,170, 90, 78,195,217, 41, 14,117, 87, 32,245, 3,105,170, 90,193,164,173, 31,249,229, 2,244,213, 18, 85, -252,203,165, 69, 58,204,105,216, 96,138, 56,200, 82,146,188, 22,216, 79,203,199,203,179,241,157,164,116, 67, 90,207, 57, 54,138, - 50,189,185, 82,222,162,112,241,169,108,167, 44, 99,201, 73, 3,133,211, 22,135, 19,160, 10,101,229,212, 62,118,179, 26,175,150, -107,176,148,115,211, 68,200,215, 97,231,190, 61, 72,149,131,217,130,216,103,131, 25, 79, 60, 31,207, 29,166,198, 24,106, 94,184, -120, 65,148,121,211,128,170,230,169, 96,220, 46,202,224,238, 43,187,250, 92,188,143,115,144,117, 90, 19,158, 0,119,252,187,164, - 60, 15, 71,231, 57,153, 26,220,147,207,191,204, 78,113,234,103,195,206,254, 82,179,115, 40, 28,241, 54,139,213,226,226,110,117, -187,109,111,180,214,131,179, 61,109,197,198,246,149, 20, 84,195, 12,215,165,185,184, 89,109, 35,244,199, 11,117,155,225, 16,186, -222,245, 95,246,171,179,253,183,219, 91,127,176, 20,141,203, 46,140,217, 60, 14,210,198,178,230,131,233,100, 2,103,244,187,158, -222,244,143, 0,148, 93, 93, 79,227, 48, 16,180,215,113,154, 22,161, 10,113,119,226,245,196, 11,255,255,153,255,129,196, 47, 0, - 33,116, 39, 33, 53,132,218,235,219, 15,111, 29, 82, 40, 92, 31, 83,169, 82,154,120, 61,158,157,157,233, 78,255, 13,254,168,202, -135,165, 2,210,127,135,103,255, 38, 29,239,170,211,153, 55, 58, 5, 76, 22,111, 16,190, 78, 92,103,218, 30, 45, 20, 19, 61,214, -209, 5,206,223,244,144, 62, 74, 78, 57, 36,103,214, 25, 12, 96,201,194,159,254,140,222,149, 31,145,190, 10,143,180,184, 38,122, - 74,217, 55,102,176,102, 6,233,225, 23,172, 31,207, 83, 39, 2,140,222,228,202,224,107, 19,178,179,172, 81,181,226,210, 68,105, -241, 90,193, 11,215,137,192,134, 63,189,148,191, 1,220, 54,194,213,121,252,189,137,247, 79,187, 94, 10, 98,154,205, 43, 77,182, - 51,229,175, 21, 81,245,184, 16,108,217,107,107,119,108, 81, 33,101,164, 59,166, 27, 78,101, 15, 33, 6,214,116,174,144, 7, 3, -214,220,181, 22, 57,136, 75,187,132,227, 91,254,235,178,102,198,238,222,187,158,157,134,240,222,148,154, 74,203,208,189,220,196, -225,250, 98,125,251,252,114, 39,234, 32, 61, 42,189,200, 94, 76, 91,206,192, 34,187, 66,160,101,237,202,166,248, 75, 7, 15, 83, -255,154, 25,243, 72,241, 0,105,169,112,121, 82,120,120, 32,103,230,149,202,207,130,231, 45, 73,233,227,183,174, 14,205, 41,119, -130,206,189,239,172, 30,203,180,221,146, 26, 22,192,205, 59, 99, 93, 87,138, 49,218, 28, 83,147,122, 89,138,118,157,246,241, 85, -112, 5,154,162, 83, 66,245,201,115, 26,255,165, 22,145,152, 51, 97, 62,121,145,169,186,107, 16, 29, 20,143,159,105, 67,102, 21, -179,117,167, 26,251,174,176,221,124,146,209, 53, 85,127, 89,246,189, 88,144, 41,225,221,110, 76,227, 4, 19, 1, 23,246, 72,103, - 63, 23,212, 60, 39,253,139,100, 10, 84,171,188, 56,253, 8,144, 71,165,229,237,215,173, 27, 44,218,131, 10,213,209, 28, 68,252, -130, 11,177,114,143, 85,229, 83, 74,139,163,106,110,239,166, 14,154, 25,123, 90,107,249, 20,193,242,255, 64,179,124, 21,158,115, -156, 32,196, 87,162,108,215,244, 68,135,126, 64, 68,166,101, 36, 1, 8,124,247,107,184,252,185,185, 90,193,138, 30,244, 72, 71, -232,156,247,108, 93, 89, 14,153,146,123, 36,224,149,164,125,135, 84,250, 99, 8, 66,179, 65,135,113, 11,219,117, 55,249, 28, 75, - 88,141,233,117,244, 28, 23,154, 92, 18,120,164,224,199,206,106, 46,168,220, 4, 44, 9,118,177, 66,255, 9,192,216,181,237,182, - 13,195, 80, 81, 78, 29, 39, 43,234,118,216,211,222, 7, 12,216,190,123,255,213, 14,123, 40, 90, 20,201, 46,137, 44, 75,226, 68, - 82,183,214,109,210, 32, 15,129,145,216,130, 29, 81,212,225,225, 57,175,227,239, 39,246, 54,248, 18,145,135,119, 67,240,240,158, -175, 65, 3, 52, 66,193, 38, 23, 23,203,123,232,106,188, 42, 49,119,221,175,227, 50, 9, 0, 13,232, 89,223, 40,219, 93,144, 84, -159,126,100, 64,239, 60, 24,241,152,140, 15, 74,103,218, 3,168,106,243,153,167, 84,154, 81,108, 59, 25, 31,213,160,237, 58,196, - 21, 89,246,209, 20,194, 36,239, 62,102,152,165,207,132,214,173,238, 98,194,126,159, 51, 47,202,250, 81,141, 29,140,208,253,218, -217,159,222,247, 28,247, 47, 73, 17,158,134,110, 50, 31,166,123,142,213,188, 85, 98,109,197, 35,229,181,205, 49,119,197,103,222, - 8,187, 22,195, 62, 40,195, 93, 49, 27,238,174,235,180,196, 71,176, 14, 31,103,255,164,220, 31,110,127,157,242, 34,209,202,197, -168,215, 36,170, 11, 73,102, 96, 64,166,103, 95,145,239,253,240,229,227,135, 31, 15, 79,183,188, 61,239,154,191,157,232, 19, 76, - 10,127,243, 28,118,212, 28,128,159,175,135, 59,179,241, 34, 3,135, 82,255, 67, 46, 99,251, 84, 47, 44,168, 71,110, 67, 66,213, - 98,200,181, 73, 6,159,235,128,135, 66, 8,148,254,166,202, 51, 89,222, 85, 72,138,147,112, 34, 31,132, 66, 91, 76,107, 3,234, -134,150,171,219,112, 83,196,194, 11, 82,159, 10,176,161,248, 88,230, 96, 1,201,134,140,174,173,235, 60, 43,190, 79,141,152,109, - 51,118, 57, 92,108, 47, 42, 73,198,167, 76,168,202,126,156, 1,162,169, 69,143, 3,178, 39,160,208, 57,174,106, 39, 96,157, 79, - 72,155,157,192,210,170, 12,238,139, 72, 31,134,134,112,153, 32, 39,121, 94,170, 34,241,184,100,245, 65,161,133,168,100,114,142, - 89, 25,158,201,150,170,154, 82, 97,181, 69, 44,193,221,171,183,189, 53,194,185, 80,223,212, 14, 49,156, 13, 76,139,224,174,114, -206,222, 17,142, 72, 61,190, 49, 85,143,161,121,220,220,132,217, 93, 16,123, 67,143,195,213,183,241,235,205,250,211, 63,107,246, - 36,121, 52, 89,111,231, 48, 31, 98,234, 78,164, 16, 25,165,103,249,231, 36,191, 19,239,230,193, 91,235,103,235,166, 57,196,204, -253,120,244,230,175, 59, 24, 55,237,113,103,212,129, 72,125, 68,187, 92,101,190,124,167, 26, 27,153,101, 15, 83,249,252, 95, 0, -206,174,101,167, 97, 24, 8,174,157, 71, 31,128, 56, 84,149, 64,226,140,196, 63,243, 73,252, 2, 7,196,137, 3, 2, 81,148, 54, - 73, 99,227, 89,175,157, 77, 91, 16, 32, 85, 61,229,208,196,174, 51, 59, 59, 59, 83,254, 67,244,162, 81,188,159,196, 10,255,140, -205,127,203,215, 43, 8, 47, 21,172, 77,254, 27, 82,213, 70, 23,118, 49,213, 48, 98, 99,195, 21,247,250,242,250,169,125, 28,212, -192,179,190,121,235, 84, 63, 22, 9,217, 16,127,149, 81, 90,195,185, 75,252, 54,133,120,182,176,131,115, 88, 60,107,147,123, 60, - 73,161, 59, 68, 26,136, 93,104,248, 15,138,249,201, 93,154,166,171, 24,249,118,156,242,193, 3,174, 46,212, 86,225, 21,114, 91, -207,235,174,125, 64,155, 19, 7, 40, 34,167, 91,247,220,130,184, 56,195,249,104,150,248,148, 27,218,119,200,172,151,148,143,236, -202,235,191,193,206, 58, 22,160, 77,115,179, 46, 14,214,166, 14,103,197, 35,237,225,225, 45,200, 46,249,233, 6,204,190, 67,119, -215,118,172,169,168,201,127, 58,122,167,253, 22, 89,108, 18, 42, 66,202,107, 62,207, 33,231, 18,193, 43,133,126,173,186,169,231, - 68,119,243,229,234,162,186,127,121,221, 40, 90,176, 87, 37, 96,147, 94, 60,251,148, 17,216,216,121, 51, 32,210,200,187, 76,194, - 74,248,173,216,196,104,219,148,163,134,192, 49,132,215,120,210,144, 75,230, 91,222,103, 30, 24,104,116,156, 31, 29,249, 39, 67, - 39, 71, 19,143,133, 19,194, 98, 35, 38, 53,101, 85, 48, 92,159,202, 55, 18, 5,193,163, 70,177,208,196,241, 30, 81,188,140,122, -112,184, 54,108,144, 92, 0,207,236, 78, 29,211, 89, 99,198,170,112, 99, 94, 43,226,105, 34,145, 83,172, 35, 66,172,134,145,222, -159,248,172,153,113, 41,157, 30,180,225, 43,123,246,246, 50,121,229,193,177,251,104, 12, 98, 76, 50,119,195, 72, 25, 73, 7, 55, -194,118,177,250, 75,220,134, 31,233,148,131,147, 93, 91,208, 36,185, 42,187,252,229, 56, 39, 81,210,171,195,221,100, 65, 78,146, -193, 28, 32,119,255, 55, 12,174,183,140,167,223, 54, 15, 79, 28,238, 22,117,102, 17, 51,161, 10, 91,133,239,221,182, 9,152,221, -216,242,106,113,179, 94,172, 62,250,221,166,125, 99,195,100,106,120,101,227,190, 46,216,151, 48, 41, 98,113,195,192,228, 97,221, - 13,156,219,194, 85, 85, 1,122,184,167,161, 67,146,162,169,108, 93,187, 89,231,187,129,250,158,250,176,105,102, 84,151, 16, 80, - 34, 7,151, 17, 70, 97, 68, 81,227,104,250, 88,226,207,254, 18,128,178,107,233, 73, 32, 6,194,211,238, 11, 65, 30, 27, 19, 19, - 36, 94,188, 17,163,255,217, 31,231,193, 11,106, 34,226,190, 58,210,153,206,108, 23, 1,245,194,149,165,192,244,235,215,239,209, -227,247, 63, 8, 96,142,139, 94,224, 55, 57,205,121, 20,127,234, 93, 34, 71, 0,183,115,170,165,195,246,137,107,214,105,168, 20, - 71,240,189,110, 55,230,192,218, 26,253,166,226, 31,123, 18, 50, 91,195,105,157, 60,146, 56, 27,185,229,188, 94,149,245,114,222, - 45, 22, 30,232,110,119, 22, 76,175,131,224,141,225,106,122,221, 52,141,117,159, 85,211, 2, 91, 69,232,143, 88,203,245, 38,134, - 81, 27,136, 0,218, 57,204, 93, 49, 90,103, 69,213,182,111,148, 97,192, 72,118, 1,176,132,244,214,100, 55,105,182,127,168,212, -251, 2,123,195, 12,246,181,141,231, 98, 66, 19,153,191,181,100,156,153, 72, 49,169, 76,122, 27,132,222,248, 69,146,139, 10,221, -206,171, 38,252,181, 78, 5,221, 22,112, 35,148,142, 22,127, 39,194, 82, 41,251,148, 10,107,164,168,252,130, 62,236,140,144,251, -227,120,178, 42,243,167,151,247,143, 40,216,242, 32,252,210,201, 42,213,244,168, 15,227,236, 25,167, 45, 95,147,107,204,180,106, - 31,195, 4,225,111, 48,160,235,232,212,114, 4,194, 71,182, 38, 68,173,107,160, 74, 95,132,152, 3,136,205, 68,161,244, 3, 15, -183, 81, 28,240,154,118,208,152,101,142,128,122,217,113, 84,223, 3, 86, 19, 7, 6,199,222, 30,197,171, 89,149, 78,152, 22, 85, -137, 76,123, 2,234,178,196, 80,125,112, 19,104,100, 22, 58,148, 80, 73,136,250, 44,251,101, 87, 87,100,204,129,200,117, 40,175, -149, 67,166, 12, 66, 63,109,120,117, 68,155,249,136, 97,177, 20,243,137, 66,244,169, 76,227,196,101,124, 56,156,194, 76,200, 27, - 85,184,163, 92, 86,128,184,200, 36, 17, 70,239, 71, 56, 78, 62, 30,238,186, 48,208, 13, 50, 12,240, 64, 98,112,234,206,223,252, - 91, 16,242,115,184,115,245,155,151,185,164, 38,219,227,247, 61,102,207,124,152, 19, 92,230,211,117,121, 95, 22,115,154,223, 48, - 41,198, 69,146,102,150, 25, 28,207,108,101,164,105,167,246, 68,103,101,154,176,246,198,121, 13,155,201,165,226,164,193, 46,152, -111, 61, 90, 79,118,190, 32, 17,153,238,239, 72, 49,153, 67,238, 9,106,194,193,234, 12,141,242,195,141,146,152,223, 2, 48,118, - 53, 61, 9, 3, 65,116,167, 31, 43, 8, 42, 9,225,134,137,158,253, 27,254, 67,127,159, 7, 79,106, 2,137, 81,160,197,118,118, -220,153,221,217, 22, 10,234,149,164, 41,109,183,179,175,111,222,155,247,183,126, 6, 78,225,113, 26,144, 54,166,119,247,135, 3, -151,206,161,248,127,132,139,170,146, 1, 66,189, 16,159,116, 84, 63, 7,250, 67,222,130, 76,125,124, 17,155, 17,100,112,194, 56, -145,246, 13, 33,177, 56,186, 40,247, 55,206, 58,196,155, 49,221,206,154,134,218,106,135,239, 91,243,213,154,137,109,150, 11,115, - 51, 42,158, 95, 17,212,157, 16,190, 67, 87,159,111,254,208,107,112, 50,167,131,113,225, 78,242, 61, 2, 52, 26, 75,129,254,142, -111, 40,171,156, 61,178,174,233,187,222,227, 44,183,143,179,249,196,218,157,195, 85,181, 71,164,105, 9, 83, 91,248, 43,250,172, -247,213,110,255, 33, 34,156, 86, 61, 29,141,174,203,223,239, 82, 26, 61,159,247, 50,198,242,158,216,198, 9, 37, 82, 27,248, 50, -110,100,224, 90,126,110,181,159, 21,236,196, 86,202,116, 43,252, 82,217,155, 24,147, 56, 34,167,103, 65,169,233,133, 98,249,137, -214,247,135,241,228,126, 49,122,122, 89,111,180, 15,225,206,116,101,211,229,248,147,214,229,101,133,156,181,157, 76,238, 49, 60, - 58,146,185, 9,136, 75, 28,203,209,202, 57,134,240,169,241, 40,164,110,170, 92, 24,205,147,166,155, 61, 73,135,101,232,104, 20, - 45,116,181,169,111,157, 58,148, 19,233, 71, 98,162, 65,210,131,194, 48,132,140,185,155,204,245,124, 48,221,236, 13, 65,241,134, - 95, 82,202, 29,132, 4, 39, 94,188, 33,132, 73,251, 0,240,155,186, 67, 85,237,226, 45, 5,205,167,232, 20, 9,166,203,135,137, - 60,184, 51,208,183, 21,165, 63, 60,112,207, 57, 74, 91, 72,232,118,118, 44, 82,148, 96,106, 54,134, 59, 8, 27, 63,133,217, 41, -226,244,168,197, 59,240, 31, 5,178, 34, 53, 84, 13, 82, 34,122,122,197, 29, 99,177,139, 71,181,157,130, 40,109,124,103, 87,154, - 25, 60, 58, 24,200,190,233,239,226, 78,226, 93,226, 46,138, 20,119, 78,110, 46, 88,211,110, 51,150, 90,208,237,213,114, 57,189, -187,128,108,211,122,204, 87,215, 18, 72,235,235,108,145,151,182, 44,243,166,222, 82,229,152,209,149, 57,150, 20,108, 51,113, 51, - 67,199, 11, 53,231, 14,140,216, 37, 4, 13,162,218,147,125, 41, 95,192,124, 77,235,214, 96, 41,121,107,193,192, 80,154,139,113, -230,203,200, 6,120,216, 14, 99, 48,212,136, 18,229,112,248, 52, 63, 2,112,118,109,173, 9,195, 96,180, 95,162,173,171, 55, 38, -142,237, 97,131, 33,178,151,189,236, 23,239,207, 13,198, 16,209, 33, 86,147,182, 73,150,219,151,166,213,141, 50,159, 68, 68, 45, -109,191, 28, 79,206,229, 47,252,222, 27,185,247, 18,200, 67, 15, 34,190,109, 28,104, 21,159,130, 87,193, 55,188, 16,222, 96,161, -228, 0,111, 35, 18, 94,247,106, 43,213,138,233,199,197,193,154, 8,244,200,200,179,250,126, 94, 79,210,170,100, 66, 79, 38, 19, -132, 34,146, 67, 45, 79,165,100, 60,121, 88, 82, 81,209, 35,119, 46,110, 63,124, 76, 96, 5, 85, 55, 9,231, 85,194, 76,204,146, -241,139,214,134,121, 80, 34, 98,171,105, 36,231,200,236, 85,114, 84,114,195,216,103,193, 38,131,193,235,221,116,189,156, 45, 38, -122,196, 37,187,130,127,159,248, 94,214,133,109, 87, 42, 45,137, 17,178, 1,122,154,140,104,100,113, 74,162,248,154, 80, 77,144, -162,251, 78,224, 28,183, 16, 64, 89,179,171,249, 82, 71,253,199,104, 93,226, 19,138,224, 61, 0,240, 12, 35, 7,198,118, 67,245, -113, 56,122,123,154,191,127,108,191,164,225,226,225, 23,203, 73,231,177, 2, 56, 15,111,125,239, 33, 1,159,172, 98,213,124, 38, -207,202,172,219,194,166, 11,133,152, 63,247,201, 77, 64, 81,167,238, 14, 71,140,196, 69,221,115, 11,246,196,139,208,240,215, 25, -238, 77, 15, 88,196, 0,168,164, 95,183,130,106,208, 61,180,185, 80,229,212, 93, 16,109, 30,121, 50,208, 92,223,190, 6,155, 56, -251, 29,174, 42,128,138, 79, 66,174,150,237, 66,104,145, 53,182,152,160, 68,108,156,159,113,201, 44,234,122,189,121, 20, 90, 12, -173,186,162, 3, 82, 46,231, 32,194,203, 16, 68,243, 49, 61,162,218,139, 76, 71,188,225,233,117,107, 82,181,187,179,173,200,100, - 21, 74,113,149,108,224, 57,120, 75,113, 7,185,131,112,125, 91, 23,204,131,138,182, 19,255, 97,193,187,172,206, 32, 23, 35, 8, -255, 20, 26,145, 59,177, 19, 73,143,117,170, 97, 59,161, 67,162, 97,123, 58, 48,231, 72,173,231, 47,171,217,179, 62,218,253,105, -183, 57,110,182,167,237,129, 31,206,101,193,196,153,215,140,137,146, 0, 25,209, 76,255,252,179,172,109, 68, 40,238, 18,251, 61, - 6, 83,210, 41,124,127,141,139,106,147,149, 6,241,216, 45, 67, 9, 25, 37,121,101,149, 16,122,220,231, 48,158, 12,166,139,116, -150,147, 92,191,159,171, 18, 43,243, 26,215, 11,162, 9,248, 17,128,181,171,233, 73, 24, 8,162,187, 45,109,193, 30,138,146,200, -193,131, 55,227,221,255, 31,239,254, 11, 15, 68, 37,193, 16,144, 82,186, 95,238,236,204,108, 63, 48,193, 24,111, 28,104,105,182, -203,236,155, 55,243,222,252,133,127, 31,161,248,228,167,174, 27,199, 67,248,206, 71, 89,254,134,136, 39,163,130,142, 31,164,217, -140,134,166, 89, 58,215,171,209, 72,114, 88, 74, 80, 47,152, 24,150,143, 16,123,137,163,159, 44, 76,211, 78, 28,146, 98,216,102, - 55,159,185, 5, 44,145,109, 26, 32,160, 81, 46,233, 79,222,214,136, 90,133,184, 38,245,234,179,189, 95,230,111, 91,155,102, 20, - 46,131, 47,132,191, 75,123, 80,226, 8,170, 37,216,251, 13,106,191, 25,116,231, 61,244,141, 75,124, 8, 36,120, 38,204, 86,164, -141, 56,189,239,212,203,110, 59, 7,117,171,191, 22,209, 39, 60, 84,139,202,247, 80,174,172,135,235,124,209, 64,216, 50,109,130, -179, 91,163, 84, 42,102,166,138, 90,169,224, 97,142,193,130, 70, 7,166,168, 13, 61,157, 1,227,195,239, 90, 14,253,121,207,212, - 87, 51, 81, 51,227,188,207, 49,138,247, 9,193, 82, 76,158,238,170,231,205,238, 85,187,156,183,132,190,100, 60,233,175, 45,167, -229,222,248, 29, 76,212,173, 9,135,184, 63,114,246,106, 83,235,227,162, 40, 13,152,114,178,158,117, 56, 97,121,212,216,195,237, -178, 76,221, 98, 93, 80,146, 1, 87,200,130,165, 27,119, 94,139,104, 72,192, 36,183, 29,160, 91, 27, 3,165, 27, 41, 92,236, 48, - 40, 36, 72,195, 81, 47,145,235,193,121, 77,185,181, 32,238, 36,136, 66,193,104, 64, 82, 78, 72,142, 82, 82, 50,102,193,201,113, -218, 98, 14,138,254,253, 1,239, 89,164,195, 7,197, 5, 84,125, 70,110,132,249, 36, 77,180, 13, 75,249,221, 88, 21, 55,250,195, - 98, 26,192,230,125,182,243,200,103, 11,179,174, 73,129,168,162, 17, 3, 46,123,101, 85,199,152, 29, 1,187,236,163,117, 97,105, - 81, 59,160,214,205, 68,103,209,114, 23,220,205,185,245, 74,132,237,246, 63,108,171,227, 82, 68,159,237,248,150, 29, 36,229, 73, -104,126,146, 76,203, 32,108,135,248,158,192,100,133,244, 97,254,120, 59,189, 81,230,180,218,125,172,235,245,151,170, 29, 24,200, -184, 76,230,133, 3, 51,146, 73, 98,148,105,253,247,139,116,118, 53,201,253,103,144,222,115,107, 16,206, 21, 11,201,166, 38, 31, - 81,168, 19, 65,232,215,192, 83,160, 47,132, 77, 69,122, 35,171, 70,168, 76, 22,101, 81, 93, 23, 85, 57,153,130,220,172,246,177, -171,209, 66,133, 38,109, 92, 19,139,181, 29,124, 89,223, 2,144,118, 62, 59,109,196, 64, 24,247,216,251, 47, 1,132, 82, 81,169, -226,202, 1, 9,222,255, 37,120, 6, 14, 61, 21, 65, 43, 82, 68, 67,214, 89,219,211,157,177,199,235,221, 72, 20,212, 91, 14, 81, - 86,177,189,159, 71,223,204,252,166,250,255,165,241, 69,133,156, 58,170,165,195,130,206,243, 25,137,199,163,219, 69,226, 15, 86, -121, 62,114,122, 58, 89, 98, 78, 38,126, 44, 83,160,200, 47, 35, 91, 39,108,221,254, 91,171, 78, 76,187,181,164, 36, 14,160, 49, -227,173, 75,109,147,207,175,212, 25, 92,177, 77,246, 76,140,119, 2,189,143,155, 73, 68,114, 36, 72,135,183,238,226, 84, 95,126, -241,143,191, 85,109, 18, 18,103,240,254,188,117, 63,246, 99,180, 11,107,214, 74,224,218,246, 92, 35,216,139, 65, 17,175, 4,155, -156,113,100, 22, 60,161, 61, 28,131, 22,182,244,121,148,123,215,114, 37, 73, 4,218,237, 37,148,206, 13, 7,248,153,141, 8, 69, - 1,184, 22,129, 94, 21, 12,247, 21,239,200,129, 30, 68,217,224, 54,157,102,158,173,192, 66,191,227,239, 7,225, 95, 70,193,107, -197,223,143,170, 29,165, 63, 22,204,108,148,185,186, 88,217, 14,239,190,191,113, 58,119, 54,183,228,157, 55,240,218, 40,171, 79, - 2,143,223, 20,183,152,196,253,165,127,184,183,244,111,234,195,174, 89,175, 53, 84,115,183, 97,209,190,136, 83,110, 20,197, 8, - 78, 87,120,193,222,146, 89,119,165,178,163, 52, 9,197, 9,190,101, 47,107,254, 81, 92, 86, 70, 47,162,200, 73, 50,117, 20,133, - 88, 69, 98,100,252, 94,194, 40, 9,118, 70, 37,147,149,110, 98,140,220, 95,206,108,194,212, 20,175, 51,126, 24,229, 76,164, 93, -128,194,226,159,229, 42, 75,194, 26, 63, 63,148,202, 62,119, 71,151, 67, 36, 66,226,231,138,140,179, 39, 22,225, 99, 71, 76, 43, - 88, 90,255, 83,226, 84, 0, 80, 65,189,163,236,229, 98,102,101,207,163,125,242,180, 92, 76,197,145, 30,114, 35,171, 40,251, 24, - 59, 67,224,130,158,127, 25, 44, 52, 53,211,116,189,239, 63,104,187,195,188,112,128,223, 62,157,135, 68, 82,111,170,166,130,153, - 10,234, 90,215, 21,245, 33,193,205,230,118,211,156, 31,130,255,249,250,235,105,247,240, 50,252, 25,148, 77, 94, 50, 66, 3, 45, -196,110, 25,196,222, 29, 44,169,124,219,128,217,171, 56, 18,148,247, 66,168, 65, 9,138,206, 65,122, 26, 35, 10, 9,236, 28,208, - 57, 94,138, 14,234,211,230,108,211,125,237,170,174, 54,218, 14,126,112,142,211,173, 30,151, 9,137,132,233,250, 43, 0,101, 87, -211,147, 48, 16, 68,103,233, 82,208,164, 96, 15, 24, 19, 79,198,120,240,226,255,255, 13,254, 15, 14, 26, 67,160, 86,186,173,237, -142, 59, 59,251, 85, 44, 26,184, 2,129,126,189,157,125,243,230, 61,121, 17,148,139,243, 82,152, 20,232, 97, 60,113,147,106,108, -254,198,117,140,156, 12, 21,197,242, 52,240, 24,163, 51,147,243,248,141, 60,108,204, 54,242,149,133, 5,122, 80, 3, 73, 86,182, - 45,188, 20,196,125,153,211, 87, 74,188, 93,232, 67,213, 31, 7,171, 60, 66, 88, 72,194,181,198,154,198,206,169,115, 65,155,168, -206,118,169,235, 14,190, 58,253,124,191,217,238,222,100,198,191,107,106,118, 61,124,235,154, 34, 39,221, 56, 99,155,140,251,178, - 86, 68, 89, 76,204, 60,179,129, 78, 23, 72, 19, 61, 33, 33, 83, 17,197, 49,228,177,200, 37, 44, 96,167,223,254,242, 84,188,147, - 68, 39, 57,230,109, 2, 11, 57,112,118, 18,196,104,192,156, 37,146,128, 87,190,108,233,147, 43,213, 36,177, 80,215,246,143,133, -180, 88,179,219, 40, 40,113, 80,222,109,138,215,170, 42,103, 54,252,214,174, 16,169,106,115, 82,194, 95, 2,172,151,229,142,204, -196,180,107,220,216, 71,191,109,247, 12,238, 79,166,186,151,179, 86,100,152,108,168,197,212,241, 58, 15, 85,107,244, 29,217,118, -215, 54, 15,108,195,104, 90, 50, 48,226,236, 37, 25,108, 14, 48,189, 19, 53, 8,136,222, 70,255,178,151,236, 7, 50,243,126,193, - 12, 92, 97,143,143,232,114, 75,156, 45,152,224,197,198,198,210,216, 65,143,224, 96,230, 88,106, 79, 70,226,175,153, 75,156,150, -244,132,101,128,137,166, 19,100, 23,167, 62, 93,254,188,185, 34,217,151,147,144,246, 39,226,232,193,196, 65,135,213, 81, 7, 88, -135, 1, 68, 34,120, 79, 26, 24, 56,170,187, 81, 36,200,238,167, 93, 48, 44, 39,190,217, 11,169, 51,140,247,195, 28,112, 34, 30, -111,250,213, 97,123,174,149,120, 78,185,151,176,243,110, 47,120,179, 92, 53,170,177,106, 25,105,202,100, 6,119, 3,247, 15,171, -199, 85, 94,152, 15,212,234,240,126,252,168, 8,220, 21, 71, 79, 51,124,153,175,204, 37, 45, 6, 54,236,153,228,143,104,158, 57, - 82, 74, 11, 50,126, 16,206,163,136, 37,121, 44,244,234,237, 96, 4,207,169, 57, 47, 31,212,222,165,163,175,177, 83,170,169,219, -125,145,175, 77,233,217,233,230,216,127,154,183, 22, 98,217, 96, 99,171,180, 12,252, 48, 49,223,120, 63, 2,144,118, 45, 59, 13, -195, 64,208,107, 59, 15,210,180, 32, 33,149, 59,156,249, 5,254,255, 11,248, 5, 4, 18,162, 45, 41, 37, 36,177,241,174,189, 78, -210, 52, 21,143,107, 14,137,228, 36,179,163,157,157, 89,253, 31,230, 14,243, 40,211,141,213,234, 83, 16, 63, 13,253, 81,114,192, - 65, 60, 13, 98,193, 86,194,200, 22, 49,105, 29,114,190, 51,111,234,233,105, 70, 38,146, 75,129, 75,129, 94, 62,240,180,220,155, -129,182,121,252,180,190, 5, 81, 16, 0,109,219, 94, 66,204, 58, 7,100, 86, 41,156, 79,207, 53,148, 18, 72, 56,221,181,164,121, -248,148, 15, 45,131,153,204, 67,243,158, 39,223, 59, 70,195,132,219,220, 12, 93,120,165,101,254, 75, 67,223, 72,153, 51,254, 33, -188,179,169,230,137,195, 88, 18,254, 16,255, 98, 7,174, 31,201,147,233, 30,103,243, 32,172,195,123, 96,223,104,196,165,146,131, -223,182, 14,121, 26,238,209, 80, 11, 83, 11,168,232, 72,243,176, 49, 60, 52,229,253, 23,148,209, 83, 86,184, 55, 92, 94, 93,232, -108, 5,251,237,215, 77, 41,171,218, 85, 68,147,216,161,243,232,180,173,238, 62, 79, 95,109,142,192,167, 56,115, 9,203,166, 88, - 8,251,160,224, 58, 77, 43, 80, 79, 80,146,150,110, 58,238,108, 31,121,158,173, 29,202,131, 71, 19,238, 28,198,210,115,246, 0, - 73,161,123,192,156,120,212, 29,142, 41, 49,221,143, 44,187,103, 80,158,151, 52,197,105, 31,114,192,200,216, 89, 12,163,146,220, - 62,140,190, 39,223,125,247,219, 94,163,227, 36, 50, 92, 1,179,193, 68,131,125, 82, 33, 96,198, 76, 85, 2,123, 22,220, 25, 88, - 97, 2,235, 48, 6, 65, 70,118, 98, 66,132,240, 67, 31,213, 72, 62,141,249,127,208,151,159, 16,125,111, 24,217,205, 40,196, 48, -166,205,216,227, 92,160,153,157, 66,179,163,144,198,194,239, 29,151, 81, 7, 33, 68, 18, 53,238,113, 67, 77, 53, 1,157, 74,237, -248,187,146,234,110,121,187, 94,172,107,199,159, 69,251,124,120,219, 54,187, 3, 50,119,195, 44,196,239,233, 82,153, 46, 50,108, -236, 26,104,101, 99,155, 6,215,154, 87,121, 82,116, 74, 53,109, 19,227,173, 99, 76, 63,101, 73, 96, 0, 10,165,224, 89, 19,162, -152, 12,249,160, 48,241,199,253,152,123,123,216,212, 27,170,152,238,214,120,224,133, 40,151, 42,173,186, 13,201,150,202,203, 72, -254, 24,191, 5, 32,237,218,118, 19,134, 97,104,156,164,148, 10, 52, 6, 47,155,180,111,216,255,127,214,152, 16,183,146,203,108, - 39, 78,211,174, 12,105, 60, 34,129, 84,154,228,216,177,143,207,177,207, 96,250,163,100,124,148,200,207,102,241,149,150, 63,192, - 84, 73, 53, 29,128, 44, 23,115,231,164,129,174,122,220,177, 74, 55,140,232,197, 19,225, 26, 8,193,248,230, 3,171,232,246, 62, -238, 43,186, 69, 24, 47, 44,137,177, 32,114, 97,184,212,152, 92,145,242,195, 82,235, 64, 51,252,224,179,175,179,114,153, 15,169, -148,184,105,167, 63,117,169,140, 82, 45,127, 52, 34, 53, 99,100,168, 53, 97,119,207,155,123,193,143,109,164,230,206,139, 1,204, -157,167,159,244, 18,114,250,255,140,228,141, 22,226, 34, 1, 6,223,201, 41, 51,220, 73,251,181,104,246,120, 42, 52, 41,238, 16, - 36, 64,215, 92, 76, 78, 98,186, 84,163,239, 68, 52,173,100,229, 24, 6, 22,140,239,155,181, 93,190, 52, 31,187, 37, 21,255,130, -191,122,178,109,246, 82,222, 81,115, 90,166,159, 6,142,205, 22,191,136,113,148,166,254,117,102,201, 97,240, 61, 97,110,210,116, -123, 12, 60,209,178,241, 91, 8, 85,198, 58,203,124, 29,198, 97,146,220,100, 77,146, 73,226,190,133,192,151,204, 93, 96,226,144, - 26,213,184, 38, 35,245,231,135, 51,235,127,161,124, 5,241,226,200, 1, 73,253, 52, 20, 21, 73,102,208,224,145, 54, 89, 61,193, - 12,228,236, 8, 37, 38,137,238,240,164,124, 52,211,180, 42,103, 33,252, 46,197,204,236, 16, 40, 19, 88,197,234,111, 84,194, 10, -131, 76,227, 72,237, 67, 21,100, 47, 97,114,140,236,249, 32,186,116, 29,137, 85,247,207,199, 56, 72, 14,148,241, 37, 97,126,210, - 68,219,164,224, 30,239,128,251,147, 51,171,241, 1,217, 35,102,245, 88,242, 98,241,164, 26, 6,214,168,198,234, 22,119,245, 91, -247,254,218,238,156, 15, 11, 99,190,206,135,254,118, 2, 74,143,232,117,185, 65, 11, 29, 23,208, 24,109, 17,226,153, 76,105,157, -187, 30,195,249,130,151,254,254,220, 54, 93, 50, 21, 48,114,245, 84,236,135,209,146, 27, 34, 91,107, 74,205, 57,228, 22, 8,177, -169, 33,119, 86, 18,118, 3,107,220, 83, 30,232,226,109, 13, 43,176,155,131,251,230,118,160,225, 39, 39,158,235,143, 0,164,157, -209,110,194, 48, 12, 69,227,144, 82, 84,152,152,216,195,164,241, 7,251,255, 31,154,144,246,138, 38, 86, 85, 91, 27,103,177, 19, - 39, 33,172,168, 18,125,167, 15,180,189,113,156,235,115,205,131,101,251,253,191,201,213, 80,195,122, 24,170,168, 68,106,171,164, -150,153,142,251,143, 65, 94, 2,235, 74,255, 2,211, 53, 33,145,254, 10,244,182,223,189, 95,102,130, 76, 83,105, 73, 75, 2,211, -194, 58, 10,238, 83,198,152,143,243,175,150,118, 33,153, 79,144, 80,186, 91, 78,227, 75, 55,255, 17, 69, 86,210,182, 78,185,216, -201,122,104, 11,255,162,102,191,141, 97,113, 15,147,174, 46,206,130, 66,203,207, 85,240, 6, 17,255,187,220, 39,144,178, 62,198, - 98, 3,209,210,109,189, 28, 3, 51, 51,129, 3,149,160,216,100,184,158,135,188,154,108,182, 81,111,164,236, 56,208,172,169, 11, -241,205, 77,236,224,211,167,216,178,102,245,254,135,180, 97, 89, 31,246, 29,142, 72, 44, 53, 7, 23,231, 58,171,190,110, 8,101, -225,122,215,234,176, 59,124,162,175,131,144,166,199,116, 38,124, 5,100,249,224,154,240,198, 39,138,216,220,108,151,176,117,227, - 9, 44,138, 5, 18,139,178, 61,226, 83,184,159,236,114, 44,179,168, 57,206,157, 84,231,121,153,229, 85,188,174,250,218, 74,186, - 75,209, 53,147, 75,120,149, 8, 99, 33,182, 8, 86,170,148,120, 33, 12, 95, 35, 21,211,201,110, 21, 64, 8,215, 1,142,184, 36, - 5,130, 62,198, 73,197, 8, 3, 8,125,172,122,175,147, 34,179, 49, 47,116,144,143,165,255, 81,246,108, 59, 18, 62,189, 43,118, -222,149,184,231,110,123, 50,224,223,138,187,154,169,220, 31,188, 52,232,227,243,241,116, 62,205, 72,156, 14,132, 25, 30,101, 50, -212,147,209,190,120,167, 48,201, 93,179,127,217,188, 14,104,159, 12, 13,228,197,116, 61, 66,136,154,112, 96,144,231, 47,192, 87, -251,190, 56,108, 90,227,133, 94,247, 99,223, 79,131,197,105,208, 19, 37,168, 19, 86,118,178, 57, 97, 19,164,125, 70, 0, 20,180, - 43,206,140, 11,111, 50,209, 84,195,201,180,229,101,128,181,145,189, 59, 76,106, 97,216,197,184,214,155,173,113,131,253,230, 40, -199, 21,251, 83,240, 79, 0,214,206,101,167, 97, 32,134,162,227,153,116,134,208, 22, 1, 18, 44,202,130,255,255, 39,214, 8, 33, - 1, 27,164,150,100, 30,196,246, 56,153, 60, 8, 32,232,186,149,146,168,113,236,235,220,115,171,255,186, 94,235,120, 50, 53, 43, -241,191, 37, 80,166,181,177, 12,138, 85,219, 4, 47, 63, 27, 46,211,200, 46, 63,255,120, 17,172,183, 72,137,129,155,218,237,157, -123,120,122, 67,238, 34, 51, 65, 8, 62,242, 18,171, 67, 21, 30,125,243, 46,122,212,164,101,246,194,236,229, 22,254, 36, 71,102, - 37,166, 78, 73, 92,106, 51, 84,228,174,236, 98,227,188,203, 8, 33, 44,172, 86,170,144,255,193,139,240,186,208,223,217, 89,186, -165,243, 39,120, 0,166, 13,216,204,150,194,209,129, 70,132,116,142,190,103,174, 49,186,143, 47,136,196, 77,219,196,112, 84,166, - 85,241, 82,214,241,158, 78, 4,114,204, 51, 22,102, 36, 95,123,100,132,221, 93,215, 77,211, 34,161,236, 35,188,158, 16, 47, 3, -178,107, 45,143,249, 94,169,219,250,226, 57,109, 43,202,173, 46, 28,164,189,145,105,168,231, 69,100, 79, 20, 89, 67,151, 42, 1, -100,167, 77,200,239,253,178, 61, 34, 59,214,164,106, 68,177, 8, 73,146,209,224,138,249,154, 94, 2, 69,255, 1,211, 85,177, 94, - 89, 32,149, 70,168,108,123, 78, 57,129, 38,101, 95, 83,159, 9,207, 49,171,228,214, 6, 9, 11, 13,156, 39,169, 10,210,232,183, - 55,197,218,215, 96,185,121, 31, 43, 51, 81,114,183,199, 43,138, 52,200, 47,179,167,234,100,246,153, 20,247, 28,228,145,219,187, - 56,238,220, 97,188, 74, 29,107, 50, 11,178,204, 34,107,239, 79,244, 90,138, 41, 89, 44,238, 42, 15,181,154, 37,108,252,139, 34, -232, 84, 27,176, 70,119,247,132,189,114, 7,103, 92,119,125, 44,152, 54,122, 74, 55, 1, 99, 42,135, 72,153, 54, 18, 20, 31,250, -167, 31,254, 28,223, 93,112,230,108,131, 38,154,110,244,247,164,210,168,189,221,243,142, 21,114, 43,216,251,117, 19,167, 77,160, - 54,132,206,167, 72, 77, 18,103, 99, 5,222, 54, 83,227,207, 11,240,108, 34, 12, 40,237,180,221, 17,214,102,119,244, 71,195,160, - 59, 5,159, 2,144,118,101, 59, 13,195, 64,208,187,235, 92, 84, 5, 85, 2,196, 3,255,255,111,240, 80,169, 28,109,115,216, 38, -187, 62,226, 64,210, 10,168,250, 80, 85,173,242, 16,123, 60,217,157,157,209,127,131,242,171,101, 25, 88,255,114, 41,239, 10, 46, -244, 58,212,117,163, 56,151, 41,218,212, 20, 13,146,106,209,217, 4,186,232,253,175,152,237,180, 81,235, 93, 34,222,111,170,110, -160,151,247,174, 41, 10, 27,100,100,124,129,189, 29,111,184,222, 26,123,116,131, 7,178,243, 15,205, 89,234, 82,154, 88,169,167, -232, 11,159,102, 92, 75, 33,239, 82,118,103,190, 32,194, 74,172,249,234, 35,152, 14,173, 74,182,148,215, 89,100,130,245, 74,222, - 91, 41,184, 83, 40, 4,225,201,103, 17,196, 56,145, 27,206,225,133,130,103, 46,112, 68,231, 94,186,127,103, 49,168,109, 52,183, -154,181,194, 70, 83, 59,152,218,130, 80, 9, 94,110, 31,108,183,224,197, 51,100,228,153, 99, 92,179,189,115,135,207,254,246,161, -220,109,202,215,125, 71,100, 26,226,166,182,206,162, 4,253,235, 81,169,231,102,123, 40,238,128,141, 38, 32,151, 83,101,211,152, -168,220, 76,122, 30,213, 20,179, 74,126, 72,149,136, 42, 11,246, 92,145, 24, 28, 23, 12, 87, 2,106,152,248,215,144, 81,103,191, - 41,237, 46, 69,198, 71,100, 79,150, 52,176, 72, 47, 96,246, 41, 58, 14,196,147, 50, 36, 51,216,137,194,131,210, 46,154,232,196, -136, 56, 20, 35, 0, 29,114,101,157,242, 34,105,192,204,103,195,174, 33, 55,224, 26,223, 89,139,238,228, 89,177, 9,220, 65,228, -152,110,178,206, 78,134,142,242,187, 5, 16,255,117, 66,105, 98,114, 94, 23,104, 39, 46,230,199,151, 12,100, 6,104,110,190,169, - 23,159,159, 52, 82,103,255, 21, 44, 6, 43, 59,200,197,219,167,133,227, 35,151,221,185,161, 90,112, 64, 7,236,154, 39, 2, 26, -161,180, 30, 9, 61,211,108,111,105, 69, 53, 86,133,170, 13, 90, 53,188,157, 85, 39,236,199,250, 32,111, 49,154,229, 70,151,207, - 35, 55,194,193, 79,174,173,134,146,104, 60, 33,122, 49,150,113,113,143,243,137, 1,222,150,142,211,179,180, 88,160,251, 1, 56, -132,172,255, 98,195,162,176, 41,217,130,201,162, 53, 5,150,142,160, 55, 71,239,106,254, 37, 0,105, 87,178,211, 48, 12, 68,227, - 37,105, 73,211, 74,244,128,184,113,232,255,255, 1,159,194,149, 30,128, 82,164, 22,234, 44,182,153,197,142,211,116, 65, 64,143, - 81,101, 69,206,120, 60,203,123,111,254, 24,191,255,216,143, 62,203,125,205, 82,173,230, 82,153, 39, 89, 96,175,168,224,175,121, -246,209,226,254,216, 11, 36,196,102,127, 6,118,240,145,104,135,246,151, 95, 94,179, 8,162, 86,119,213,116,117, 95, 61, 62,125, - 40,198, 68,248,212,153,134,213, 94,157,124,200, 85,219,216, 77, 28,117,116,118, 7,248, 11,212,177, 30,205, 50,100, 12, 49,100, - 6, 19, 53, 84, 17, 43,167, 41,148,158,101,114, 81, 96, 38,232, 80, 16,186,221,211,203, 28,174,106, 73, 14,143, 19, 83, 73, 23, -153, 88,160, 11, 81,198,163, 76, 35, 59,122,176,164,165, 18,168, 98, 39,213,156,218, 9,141,132,219, 5, 21, 49, 32, 83,153, 41, -100, 72,131, 41,149, 74,108,105,150,100, 33,188,173,101,109,186, 46,130, 32,192,237,195,197, 64,162, 58, 24,251, 99, 18, 32, 69, -215,185,183,237,161,168, 84,153,107, 10,118,176, 62,242, 25, 89, 84,252,131, 52, 98, 5,201, 80,181,220,138, 57, 24,163, 70,177, - 93,141,213, 25,140, 16,137, 11,233,109,194,201, 4,128, 69, 24,162,196,205,213,177,210, 99,136,247,201, 19,217, 48,108,111,200, -154, 15,206, 61, 42, 29,244, 84,154, 33, 90, 92,248,163, 85, 3,248, 59, 75, 10,211,126,128, 18, 16,151,187,217, 35,176, 34,225, - 99,152,185, 36, 36, 75, 70,147,112, 24,139,225, 57,126, 58,232, 61,113, 8,239, 33, 80, 64,117, 2,217,167, 1,246,202, 16, 0, -186, 51,240,175,178,159, 87,156,204,192, 31,159,155, 81, 73,212,133, 0, 39,114,140, 92,172,204,196,129, 39, 81,208,209,157,212, - 94,126,219, 4,242,105, 44, 98,144,254,117,125,205,125,192, 77, 61, 5, 98,142,250,192, 39, 73,246,255,156, 59, 4,224,173,173, -207,229, 4,204, 73, 8,194,122,132,121, 71, 78, 19,241, 84,117,169,110,167,186,116,116,239, 78,144,183,142,223, 25, 92,127,153, -231, 38, 43, 32, 38, 95,200,217, 84,223,172,205,186,205, 12,236,113,227,218, 46,115, 19,176,115,239,159,191, 94, 54,230,125,103, - 15, 4,160, 4, 87, 96, 27,103,224,192, 89,196, 78,117,112, 30, 73, 47, 84,208,100, 44,223,235,127,176, 68, 82,145,229,144, 43, -183, 56, 69, 2,252, 3, 31,135, 32,166, 42,144, 0,237,136, 6,205, 90,148,136, 47, 42,212, 68, 73, 81, 91, 83,200,226, 91, 0, -210,174,100, 55, 97, 24,136,218, 78,156, 5, 82,150, 3,234,169,135,138,255,255,158,222,122,163, 85,165,170, 5, 90,182,196,246, -212, 51,118,140, 19,150,110, 17, 39, 14,200, 24, 60,158,229, 45,255,234,207,252, 4,196,126, 54,196, 71, 18, 34,225,215,237,228, - 82,170, 47,241,220, 47, 3,205, 25, 73, 75, 30, 69,121,222,107,254,235, 54,189,253, 96,226, 14,247, 14,255, 31,117,171, 4,208, -123, 72,202,145, 77,115, 57,159, 85,139,149,121,120,222,230, 82,104, 39,168,215, 30, 5,142,113, 19, 30, 77,122, 47,129, 55,205, -147,151,232,188,216, 86, 10, 26, 91,166,205,226,155, 22, 39, 78,152, 72, 68,233,164, 24, 55, 69,149,224,176,126, 80, 8, 3,106, - 85,171, 61,131, 95, 25,107,220,208,107,156,242, 81, 38, 53,136, 66, 3,162, 33, 65,172,200,178,183,146, 72,217,205, 19,168, 73, -101,108,146,162, 42,190, 20, 54, 73, 65, 87, 49,138, 53,124, 39,108,105,130,132,142, 50, 1,155,140, 15, 82,190,174,147,181,210, - 27,131,224,150,224, 54,153,146,116,187,221,192,141,134,197,219, 97, 88, 37, 53,168, 12, 39,179, 88,251,187,203,172, 36,132,210, -173, 93, 82, 49,130,124,252,142,193,159, 73, 78,138,237,110, 0, 46, 64, 24, 97, 58,146,141,134, 69, 6, 90,218, 83, 51, 79,231, -156, 38,208, 53, 91, 61,119, 8, 78,170,208, 54,220, 91,200, 95,128, 81, 7,100,222,177, 12, 8, 28,227, 48,159,143, 64, 20,158, -209,202,174, 10,155,196,249, 31, 68,130,138,168, 61, 71, 66, 71,224,141,231,224,180, 69,195,157,215, 3, 53,124,157, 27, 6,247, - 46, 6,112, 53,253,196, 47,161,233, 62,114,195,105,211,133, 46,134, 80,222,191,132,120,156, 38,119,228,120, 33, 96, 16,161, 55, -155, 5,246,167,252,253, 4,219,195,163, 38,140, 97, 71,166, 37, 59,165, 47,177,203,201,251,249,121,221,119, 15, 85,156,254,128, - 30,244,225,114, 70,239,147,119,244,235,112,108, 85,228, 52,225, 27,211, 98,134,125, 16, 80, 58,229,123,174,101,234, 49, 66,104, -235,129,245, 54,242,140, 38,217,168, 76,230,235,102,185, 83,187,161, 44,171, 36,203, 81,122,100,249,250,249,178,213,136,142,119, - 45, 0,100, 62, 66, 83,104,108,217,107, 77,186,153,104, 35,132,253, 24, 25, 66, 22,216,162, 89,187,125,161,197,231,132,252,240, -237,120, 26,215,208, 58, 61,187, 28, 39,242,246,116, 41,251,225, 74,229, 50, 19, 8,242,131, 47, 1, 88,187,150,222,182, 97, 24, -108, 82,150,156,174,201,218, 98, 75,215,245,178,251,246,255,129,253,145, 29,119,111, 47, 69,209,184,141, 31,178, 56,146,146, 18, -187,246,130, 12,216, 49,135,196, 9, 34, 81,159,200,239,241, 31,244, 77,255, 4,228,231,222,241, 99,106, 84,180, 92,162,172, 39, - 92, 76, 13,159, 27,197,189, 19, 82, 77,196, 80,163,176,133,195,189,239,161,128, 59,112, 63, 10,218,145,103,232, 93,143, 38,159, - 81,239,243,169, 40,238, 93,245,253,238, 6,172,251,249, 75,105,239,154,139,169,115,107,204,252, 48,249, 88,126,227,239, 96,191, -149,197,173,239, 25,207, 62,159, 49,217, 31, 70,118, 49,229,145, 82, 73,122, 98, 83,108,217, 95, 25,220,126,168,154,174,247, 25, -227,159, 67,193, 54,185,223,205,175, 54,149,187, 93, 91, 36,190, 57, 66,223,209, 83, 75,107,229,138,181, 0,107, 71,215,150,107, -177,132,108,240,178,226,101,186,177,178,166,157,193,171,170,188,180, 42,209, 67, 6, 29, 12, 1, 68, 76,242,184,107,234,183,166, -110,253, 83,231,187, 65, 22,208, 10,112, 39, 36,162, 3, 79, 88, 66,106,235, 23,207,128,197,246,225, 99,192,173,129,141,167,149, -129,237,202, 52,102,179, 51,151,123, 81,243,104, 36,130,110,115,136,225, 13, 74,152, 33, 76, 41,114, 89,117, 15,195,177,133, 75, - 89,112,191,208,103,200,158, 90,169,237, 78, 71, 11,174,216,188,201,212,179,169,189, 73, 44, 52, 97, 90, 55, 96,108,219, 53, 89, -189, 11, 93, 2,252, 43, 85, 41,140, 74, 15,230, 84, 26, 97, 9,197,200,177, 67, 14,188,148,111,173,242,202,129, 3,117,204,160, -144, 34, 35,162, 21,151, 63,245, 95, 99, 34, 79, 38, 27,119, 2,156,126, 9,130,145,240,105, 54, 58,206, 55,228,144,131,253,142, -116,163, 89,113, 39,154,237, 94, 56, 53,107,155, 52,208,166, 7, 74, 62,110, 40,167,108, 39, 82,211,100,131,191, 11, 62, 93, 4, -239, 14,173, 4, 30, 45,135,179,156,216,119,195, 57,144, 52, 67, 11, 6,212, 12,170,133, 19,105, 36, 15,181,248,124,113, 47,233, - 51,161, 3, 44,187,224, 93, 97, 92, 16,251,200,146, 33,144, 49,168, 49, 5, 77,223,180,190, 69,116, 55,213,245,215,139, 47,252, -251,158, 95, 31,222,250,215,189,248,207,212, 94, 24,124, 62,106,230, 52, 51,121,104,169,147, 39, 37,230, 32,132, 1, 53,200, 77, - 26, 59, 54,186, 26,165,217, 82,186,255,148, 69,169,112, 80, 3, 63, 82,147,163, 52,122,207, 72, 22,111,217,130,139, 15, 13, 62, -153, 90,218,255, 17,128,181,171,233,105, 35, 6,162,182,199,206,238, 38,219, 18, 1, 61, 20, 9,245,196,145,127,222,255,210,115, - 15, 21, 18, 72,244,128, 16,129, 18, 54,201,218, 51,245,216, 94,199,155, 4,104, 37,142,137,162,100,181, 89, 63,143,103,222,199, -199,204, 87,255,171,144,207,162, 36, 89,122, 15, 36,158,131, 19,187,214, 37,180, 19,136,126,208,253,134,198, 66,170, 60,188,197, -108,174, 55, 80,107,194,157,165,107,162,169, 84, 23,166, 62, 39,229,255,173, 5,250, 50,217,227,172,155,177,247,150,254,210, 54, -151,223,230, 87, 93,255,253,199,111,143,117, 0, 60,179,115,168, 98, 44, 96,241,212,179,213,141,255,182, 95,168, 79, 65,124,117, -220,109, 94,139, 20,247,241, 46, 28,187,145, 38,133,219, 29,129, 49, 66, 75, 7,159,172,107,141,158, 55,149,234, 58, 26,136, 52, -254, 51,199, 66,156,115, 77, 33, 59,222,107,196,189,192, 27, 65, 47,137,117,147,238, 42, 55,130, 0,206, 90,125, 58,159, 26, 96, - 21,243,195,210, 35,171,245, 71,182,154, 69, 91,196,249, 50,192, 46, 14,134, 73, 64,202,195,186,209,234,164,153,180, 19,121, 50, - 99, 83,107, 14,132,212,166,169,180,169,140, 1,120, 92,116,143,127, 86, 87,247,207,243,101,247,208,173, 87,142, 52,135,254,240, - 10, 51, 64,179, 9,156,125,134,163,102, 82,129,156,214, 76, 14,126,105,235,159, 79,114,229,212,157,173,110,109, 32,119,250, 31, -141,198, 3,145,145, 27,165, 60,254,140,106,101,142, 81,194,130,161, 24,229, 64,219,222,202,152, 46,130,197, 56, 6,179,125,225, -144, 68,145, 18,221,112, 24,230, 97, 46, 8, 74,242, 6,101,224, 56,160, 22, 26,197, 12, 28,232, 80, 56, 49, 42, 82, 74, 19,142, -194,186, 0, 83,159,133, 82,180,187,139, 70, 98,177,132,103,242,173, 30,120,147, 36,182,153,125, 52,140,140,246, 55, 17, 85,208, -186,163, 97,143, 30,196, 65,228,228,187,148,132, 2,159, 25,217,115,200,117,206,162,221, 1,119,218,222,163,177, 81,122,106, 32, -189,177,238,101,106, 12,203,237,178,149,135,104,187,184,119,121, 84,180, 80,154,181,235,112, 92,176,199,151, 17,220,247, 39,225, -255,120,184,160, 87,183,166,120,194,240,181,186, 12,197,187,228,181,192,207,171,168,161,109,116,235,220,198, 98, 40,185, 1,131, - 96,148,181,145,126, 19,208,214,215, 67, 30,226, 85, 47,108, 79,254,234, 86,207,253, 2, 25,203,112,195,166,190, 12,107, 61,219, -249,166, 92,178, 56, 23, 13,111, 90, 54,131, 36,110,237, 67,120, 30, 40,101, 5,132, 64,149,208, 29, 50, 66,111,130,130, 57,236, -253, 42,116, 89, 77, 62,191,138, 36, 18, 10, 82, 78, 14, 5, 76, 37, 99,244,167,172, 84,253, 87, 0,214,206,109,167,109, 32, 8, -195,179, 7,175,109,154,164,196,149,138, 16, 69, 61, 75, 60, 1, 79,205, 61, 15,193, 93,239, 43, 85, 69,173, 26, 32, 96, 5,145, -216,241,102,167,158, 61, 56,107, 19, 4,149,250, 2,145,172,140,102,103,255,249,247,251,255,155,127,230,159,206, 0, 19,181, 99, -140,130,120, 30,157,219,187,111,109, 59, 11,143,245,206,127,183,127,216, 74,123,204,205, 83,193,252, 36, 8,232,184,249, 70, 47, - 91,249,231, 60,121, 43,210, 66,138, 84, 8, 37, 25, 79,146, 18,244,217,143,219,249,114,173,200,215, 4, 30, 75,109, 45,151, 33, -254, 15,183, 42, 17, 17,156,217, 31,224, 99,150,126, 65, 61, 3,189, 12,225, 71,171,231,138,204, 68,130, 41,247,166, 11, 51,135, - 58, 95,155,114,177,154,230,202,109,131,167,132, 17, 22,167,211,226,228,120,255, 98,118,125, 62, 43,231,182,227, 79, 0, 62, 2, - 47, 64,126,135,230,222,159,240,208,142, 13,239,149,156,188, 74,223, 29,140,243,118,246,168,116,145,233,117,157, 52, 68,184, 48, -141,230, 85, 59,170,115,154, 30,115, 50,245,194, 72, 74, 37,249, 40,149, 89,202, 95,103, 42,203, 85, 99,232,125,221,229,109,117, -245,243,250,242,102, 81, 46,235, 55, 35,117,124, 80,124, 61, 58,188,186, 91,174,234,166, 45,231, 84,182,149,141,163, 4,239,106, - 92, 32,215, 40,126,223,235, 95, 15, 88, 82, 61, 19, 27,137,130,152, 54,132, 81, 36, 17, 26,132,165,108,177,128, 20, 18,206,113, -215,125, 59, 6,217,221, 11, 40, 93, 95,232,232,192,189, 4, 11,239,216, 11, 34,178,195, 15,192, 83,195, 59, 11, 70,120,216,186, - 53,192, 68,205,100,216,222,241, 89,115,116,220, 44,123, 83,191, 69, 16,179,136,186,211, 49,103, 34, 42, 47,115,204, 45, 35,208, -113,225,185,143,111,103,172,147,209,177,167,169,176,248,130,225,192, 99,246, 35, 53, 5,195, 57, 17,190,191,239,217, 61,251, 58, -240, 0,108, 99,243, 66,115,199, 97,115,119, 9,168,102,248, 19, 60, 72,230, 62, 47,110,151, 4,139, 79,174, 88, 89,255,225,210, -112,120, 31, 28,179,149,109,238, 47, 17,106,186,238,159,139,236, 97, 83,189,220,186, 13,143,146,106,152, 7, 52, 58, 12, 57, 79, -236, 95,146,138,201,135,241,167, 21, 61, 71, 34,193,173, 49, 88,235,106, 79, 40,186,231, 58,172,166,141,195, 38,191,128,161,133, -184,161, 61, 42,197, 45,217,143,213,218,122, 28, 67,124,167,231, 85, 88, 3, 12,218, 59,176, 53,169,182,151, 86, 10, 18, 96,206, - 1, 32,109,249,216, 76, 15, 52, 17, 5, 79,135,181,188,203,230,113, 16, 82,247,218,156,116,121, 90,196, 36,130, 17, 51,135,246, -190, 68,153,100,127, 5,160,237, 90,114,219,134,129, 40, 73, 81,150,140, 70, 77,224, 24, 48,208, 58, 40,178,233,166,232, 5,178, -207, 5,114,190, 94,162,219,228, 4, 89,101, 93,160, 72,186, 40,208,124,225, 56,136,109, 72,161,134, 25,206,144, 50,105, 59,159, - 77,189,242, 66,254,209,212,112,222,204,155,247,244,255, 8,223,111, 94,179, 82,165,177,221,148,115,178,250,155, 81,155,125,129, - 44, 37, 18,245,202, 46,145,183, 41,213,109,217,137,205, 28, 93,201,224, 70,190, 88, 52,191,249, 48, 96, 23, 54,252,163, 0,178, - 76, 99, 22, 76,198, 7,190,214, 25,110,124,163, 60,116,178, 81,231,205,125,193,169,128, 71,169,247,156, 47,139,249, 75,189, 14, - 29,198, 89,197,250,108,248,166,148,176,161,200,119, 79, 35, 77,242, 94,140, 91, 49, 46,202, 89,189, 40,132, 29,170,178,206,196, -241,159,171,211,135,135,187,112,241, 45, 93,124, 88,228, 71,101,117, 50,157,204, 5, 20, 66,238,200, 60, 47,123,251,159,119, 15, -190,142, 38, 55,139,169,168,235,166, 86, 37,232, 22,182, 20,158,106, 98,160,112,103,102,185, 82, 79, 68, 80,252,136,251,183,175, -203, 18, 1,169,184,156,214,231, 23,183,215,147,199, 27,204,217,155, 22,119,115,213, 47,190,143,182,191,141, 7, 63,127,253,251, -113,118,126, 37, 28,221,119,232,166, 79,243,221,157,193,157,249, 48,135,220,201, 1,184,186, 61, 34,132,182,199,205, 81,124,102, -217,105, 90,197,116,111, 34, 1,208,200, 53,139,122, 73, 43,211, 50, 2, 79,236, 69,213, 18,176, 81,150,205, 47,130, 16,134,227, - 10,242,114, 94, 70,120,177,220,144, 32,218,200,208, 57,148,125,108,204,211,128,117, 57,235,181,124,227,221,148,140,224,167,100, - 92, 69, 86, 70,240, 20, 44,183, 93,172, 23, 66,229,138,156,244,133, 26, 21,140, 76,130,144,142,220,156, 98, 42,209,177, 70, 21, -207,182, 51,123, 6, 2, 36,102,105,176,224,106,157,190,137, 93, 46,116,167, 26,214, 29, 36,177, 67, 94,199, 63,106, 83,136, 12, -221,136, 73, 18,226,229,170, 2, 94,164,235, 32,151, 43, 12, 54,105,250, 66,154,232, 36, 84,200,119,202, 9,240, 35, 87,185,163, -157,184,193,186,122,197, 40,120,180,245,233,122,118,153,106,213,188, 22,159, 66,126,141, 89,157,170,122,149, 49, 24,127,179,189, -234, 75,137, 16,158, 44,197,230,160,102, 6,115,164,198,210, 39, 2, 97,101,141,177, 2, 52,121,125,200,150,112, 17, 89, 20, 2, - 83,104,232,160,236,130,187,151,116, 39,188, 14,116, 32,200, 76, 56, 98,158,113, 33, 94,182, 94,189,221,211,150, 24,103,105, 86, -224,244, 85, 55,246,128,107, 3,129,132,219,248,248, 11, 57,208, 35,128,112,243,137,238,174, 3,215, 22,120, 22,128,180,107,107, - 73, 32, 8,163, 51,187,234,238,154, 21,164,221, 40, 9,242,193, 30,138,138,192,168,254,113,127, 34,232,177,199,232, 37,130,162, -204, 36,211, 50, 75,215,205,157,253,154,251,206,152, 69,145, 44, 34,226,138,224, 55, 51,231,187,156,115,126,210, 7,206,231,243, -181, 90,173, 94,175,255,103,228, 72, 63,170,213,106, 24,210, 83,112, 52,246, 90,103,195,229,114,121,105,121,169,211,105,127,233, - 76,194,228,113,133,239,127, 3, 88, 75, 68,179,141,229,138,221, 63, 58,220,220,221,110,212,239, 56, 69,152, 49, 83, 57,193, 76, - 62,179, 78,163, 43,236,202, 28, 17,161,124,247, 18,101, 92,172, 42, 0,104,239, 96,127, 99,103,171,121,223,136,233,151, 64,106, - 59,240,204,192,187, 91,100,176, 90,230,178,218,226,142,252,174, 81, 33,244, 9,250, 8,162,143,100,193,243,135, 36,121, 5, 66, -175,135, 65,120, 21, 13,219, 95,240, 81, 68,226, 18, 56, 31,132,129,130, 21, 39,187, 94, 12,118, 43,165,181,153,169,110,123,120, -251, 52,232,209,251, 49, 42,228,104,128,186,121, 63, 67,113,250,180,151, 97,117,155, 28, 14, 60,119, 54,112,131, 44,238, 13,162, -235, 70,247,236,242,241,228,178,117,209,234, 62,244,195,155, 56,234, 64,236, 51, 18, 19, 58,127,121, 59,190,105,158,190, 15, 66, - 4, 69,132, 42,222,212,114, 97, 21,251,243,221,164,192,148, 31, 29,148, 17, 69,117,169,116,202,132, 58,137,132,212,216,192,146, - 2,233, 40, 77, 20,144,154,159,114, 56, 93, 34, 88, 85, 98, 1, 0, 75,200,209, 96,191,152, 35,116,120, 92,204, 93,107,134, 40, -139, 32,221, 69, 52,188, 49, 82, 64,148,128, 9,221,172,235,247,209, 14, 19, 45,107,164,100,120,106,188, 32, 60, 98,112, 26,144, -216, 86,220,144,241,137,127, 94, 80, 32,141, 64,148,152,123, 42,207,155,164,200, 39, 29,251,193, 86,122,148, 38, 75,200,224, 49, - 73,201, 70,211,254, 52, 49,106,232,137, 65, 90, 86, 64, 9, 59, 86,101, 10,198,167,223, 45, 40,110,217,163,219,159,154,208, 30, -248,235, 88, 76, 98, 52,137, 77,192,158,229,202,250,225,168,175,114,150,201,127, 42,182,138, 51, 72,208,222, 89,113,134, 99, 56, -186, 51, 46, 6,171, 37,127,142,190, 19,141,132,239, 14,248,174,224,198,195,136, 8, 21, 33,186,209,199, 52,223,165, 27, 52, 33, -204,124,131, 99, 20,193, 75, 66,138, 25,166,189, 13, 24,193,144,159,211,142, 74, 98, 88,110,235, 34,172, 93, 65,185,116,187,244, -255,136,145,112,251, 17, 46,181,250,152, 50, 93, 9, 44,149, 77,126, 59,159,184, 87,147,132,159, 2, 80,118, 62, 63, 77, 4, 81, - 28,159,217,182,233, 15,106, 77, 17, 12,138,198, 11,145, 4, 8,176, 23, 8, 49, 49,254, 13,198,164,234, 65,210,163,246,223,211, -171,103, 19, 15, 74,194,209, 8,129,132, 96, 33,128,110,177,203,238,206, 60,231,189,249,177,211,101,149,184,153, 52,123,216, 54, -147,217,238,219, 55, 51,239,251,249,254, 43, 73, 81, 1,183,223,239, 23, 34,126,175,215,187,126,126,227, 17,134,225,187,193, 64, -119,103, 61, 12,223, 14, 6,126,117,179, 62,125,241,178,183,176,248,184, 0,101,246,133,233, 55, 6,119, 31,123, 80, 40,189,113, -240,210,205, 39, 91,175,250,111, 86,194,117,107, 34,193, 28,237,203, 64,111, 8, 66,134,159,232,181, 0, 66, 43, 35,169, 6, 21, -140,151, 60, 11,183, 54,159,111,191, 94, 90, 91,149,148, 42, 57, 68, 59, 55,170, 81,248,129,139,227,213,121, 86, 91, 96,193, 12, -225,209, 59, 84,147, 83,179,230, 74,165,135,214, 58, 37,230, 68,158,178,228, 40, 30,223,175, 55,239,176,218, 5, 19,223,153, 56, - 41,251,214, 25,131, 47,201,229, 24,141, 59,106, 15,167,219,203,247,110,159,159,167, 31,119,135,159, 15, 84,250,158,168,192,222, -170, 98, 25, 71,163,202,218,117,149, 43,242, 20,120,119,138,119,154, 60,205,196,183,227,232,253,206,209,135,175,135,159,246, 78, -134,163,232, 64,140,135, 12, 25,244,179, 65,208,101,108, 4,217,126, 18,255, 20,233, 92,181,249,108,234,238,211,233,149,197,217, -141, 86,123,141,215,231,126, 67,147,198, 71, 18, 79, 13, 41, 14, 25,137,179,213,112,161, 38,143, 48, 75,153,182,110,176,110, 64, -210,240,197,193, 49,198,201,151,194, 88, 92,105,219,107,193, 93, 48,178, 97,159, 89, 48,138, 21,220,219, 34,113,145,111, 15,230, -187,118,148,188,219,188, 29,174, 45, 20,216,224,110, 20,222,110, 57, 94,119,217,107, 96, 23, 19, 56,252, 37,238,219,126,114,207, -227, 87, 22,100, 26,153, 87,142,227,108,137,192, 81,188, 56,152,170, 83, 13, 12, 52,165, 17, 78,177,203,161,216,152, 53, 58,114, -154,126, 13,159,202,175, 17,166, 6,209,252, 20,247, 90,224, 46,115,219, 26,134,138, 60, 17,220,221,154,190,118,125,225,212,220, - 63,159, 25,105, 27, 88,187, 14,207, 22,150,231,193, 93, 78,218,134,240,124,168, 39, 30,121,240, 54, 84,254, 43,184,107,137,226, -131,238,163, 22, 26,215,151,152,233,102, 70,252,140, 93,104, 4,245,178, 27, 87,190,200,131,242,142, 74,227, 86,163, 67, 21,168, - 65, 5, 25,144, 16,227,132, 30,179, 24, 53, 86,227, 76, 92,166, 87,163,248, 87,148, 92, 68, 87, 81,156,198, 82, 79,250, 89,133, -144, 20, 1, 38,242,170, 33,122,131,131,161,248,107, 66, 40,102,226,210, 56,143, 11, 59,182, 6,162, 46,201,193, 28,101, 74, 32, - 80, 3, 5,234,125,146, 17, 90, 26,163, 11, 61,104, 32, 29,235,148,130, 62, 89,244,232,123,228, 76,207,232,197, 3, 34, 33,148, -188,154, 97,252, 17,128,177,107,235,109, 26,134,194,177,211,180, 73, 53, 96, 33,169,132, 88, 25, 66, 43,237,107, 95,120,226, 97, - 18,208, 31, 59, 9,129,144,248, 31, 45, 55, 65,138, 64,226, 58, 36,210, 78,108, 74,154, 56,137,141,125,124,105,154, 70,130, 60, -197,169,123,108, 89,206,201,241,231,207,223,249, 55, 62, 19,134, 97, 16, 4, 81, 20, 73, 55, 61,155,205, 22,139,197,106,181,226, - 49,184,185,247, 60,143,199,227,188, 94,204, 11,113, 44,189, 63,255,151,137,253,167,211,233, 98, 62, 79,211,180,113, 31,132,225, - 0,170,201,162,185,134,119,134,110,191,255, 17, 26,229,166,110, 6, 65, 2,246,121, 55, 2,232, 80,164,127,226, 31, 33,211,104, -253, 26, 77, 38, 89,186,233,131, 17,131,201,248,225,224,244,201,163, 55,243,197,243,179,167,252,225,201,100,124, 17,175,253, 48, -248, 28, 45,121,241,104, 56,228,245, 63, 45,151, 90, 20, 18,157,140, 70,155, 52,251,249,237,135,122, 67,225,203,120, 56,240, 31, - 62, 62,125,247,234,245,203,179,103,124, 72,239,141,239,175,227, 88, 24,249,176,212,204,100, 81,245,210, 98,188, 28,226,206, 17, -104,188,254,134, 37,149, 81, 94,204,106,251,171,141,120,164, 4,193, 50, 56,119, 74,215, 52,239,229,116,236,121,135, 37,126, 91, -112,231,219,178,206,146, 31,167, 91,118,119,226, 31, 36,118,249,226,253,249,245,174,243,224,110,232,247, 61, 23, 35,238,211,133, -210,189, 43,114, 54,254, 33, 20, 59,120, 83,208,175,151,213,175,171,138, 18, 98, 51,114,124,195,113,110,123,209, 58, 59,191,178, -143, 15,122,174, 16,202, 32, 93, 65,254, 44, 51,138, 9,238,244,186,126,137, 6, 5,115,115,193,183, 97,132, 7,232, 37,111,241, -154, 72, 21, 73,147, 78,153, 80,107, 3, 2, 89, 74,208, 73, 98,136, 50, 95,173,150, 20, 21,179, 23,192,196, 29,180,128, 33,164, -168, 47, 72,121,125,164, 1, 71,195, 82,167,160,250,175,197, 88, 24,128,200, 10, 32,109,136,185, 43,148, 15, 81,166,115, 13, 41, -218,140, 38,211, 86,245, 40,216, 50,120, 79,107, 42, 78, 19,227, 87,187,200, 47,210,106,119,172,109,237,101,152,150, 91, 15,173, -179,129,107, 1, 88, 5,208,195, 3,153,125, 12,215, 19,115, 72,254, 61, 70,109, 26, 3,250,228, 84,205, 85, 34,180, 31, 2,179, -157,240,166,169,196,199,182,104, 56,133,227,169,180,225,220,181,228, 67,147,248,134,244,206,129, 86, 65, 1,111, 86,115,241,251, -114,202, 58, 31,142,162,189, 91,109,129,188, 89,238,252,191,115, 55,125,250,126,241,197,106,203, 63,209,104, 32,163, 77, 54,164, -231,184,121,145,237,153,197, 74, 8,158,150,164, 34, 24, 72,229,210,219, 50,214, 73, 74, 98, 83, 33,197, 46, 68,132, 24,127, 11, -138,156,228,204, 74,186,216,225, 35,217, 17, 42,132, 72,242, 88,248,146,182,162, 24,180,133,177,173,194, 27,216,130,170,161,126, - 84,197,227,216, 86, 28, 16,138,213,233,113, 86,110, 19,119,241,161, 46, 37, 63, 88, 37,124, 22, 42, 5, 88, 51,180, 37,167,150, - 22,218, 8, 51, 42,125, 48, 7, 10,152,122,127, 5,160,236,106, 94,155, 8,162,248,204,236,210,213, 82, 37, 32, 88, 73,147,155, - 39, 61, 22,141,110,143,246, 38, 4, 47,226, 81, 3, 85, 80, 16, 41, 53,208, 96,109, 73, 41, 37,144, 66,175,189,197,139,224, 57, -249, 27, 90,132,254, 3,126, 43, 38,149,210,143, 88, 53,105, 62,118,119,198, 55,243,118,246, 35,161, 21,151, 37, 76,150,100, 50, - 73,102,127,243,230,253,222,251,189,127,227,123,169, 84,130, 71,128,224, 98,177,104,219, 54,180,243,249,124,181, 90, 5,124,143, -182,241, 41, 28, 91,155,155,149, 74,229,214,244,116, 54,155,125, 56, 51,131, 40,108, 79, 77,173,149,203, 3,237, 7,185, 28,180, -177,243,213, 98, 49, 48,216,239,231,114, 55,245,245,245,114,121, 34,157, 6,123, 31,222, 8, 87, 0,199, 1,223,241, 83,106,181, -218,203,197, 69,188, 94,152,159, 71,136,199, 91,249,197,210, 18,224,190,122,253,225,234,242,114, 71, 46, 30,242,198,201,216, 25, -232, 13,206, 70,189,241,249,253,199, 39,207,103, 59,199,146, 4, 93, 41, 44,220,185,119,247,154,125, 3,218, 59,245,198,198,218, - 58,244,242,120,110, 54,153, 78,193,149,237,173,183,111, 94,189, 86,247,150,220,161, 77,102,174, 39, 83, 19,112,254,248,190,243, -229,195,167, 71,115, 79,177,147, 82, 97, 1, 22, 3,164,214,168, 74, 82,132, 99,151, 11, 24,214,101,195,188, 66,172,175,158, 3, -102,248,177,154,235, 99,218, 78, 55, 20,214, 19, 13,253,209,156,207,132,154,244, 7,220, 61,232,180, 83, 35,214,237,115,137,189, -158, 83,119, 97, 98,122,109,206, 45,198, 18, 66,156, 17,116,140, 26, 46,163,223, 68,127,187,185,127,200,197, 69, 66,158, 93,189, - 52,153,188,176,251,167,187,215,118,127,123,228,221, 81,175,213,147,140,255,175,174, 39, 9, 29, 69,207, 48,233,116,146, 36,132, - 36,144,127, 50,193, 71, 45,211, 0,128, 5,168,230,108,180,231,151, 25, 50, 93,110,185, 60,209,247, 88,215,107, 41, 19, 20, 5, -186,132,116,252,201, 4, 88,243,172, 53,206, 68,183,213,223,135,229, 2,195,216,185,230, 55,181, 28,135,239,143,229,148,210,129, - 58,141,194,247,123, 41,205,126,206,197,128,241,142,229,203, 98, 50,238, 58,234, 67,139, 36,198,196, 82,136, 23, 68,159,115, 17, - 45, 49, 26,238, 3,194,160, 24, 26, 12,111, 56, 8,143, 13, 37,178, 70,113, 95, 9, 68, 27,244, 52, 93,131, 72, 76,151, 95,152, - 61,132,120, 21, 20,175,215, 0,141,242, 58, 65, 29, 99,225, 60, 47, 66, 0,224,255, 21,232,213, 68,192, 40, 22, 87, 26, 87,170, - 57,209,205, 35,124, 7,174,192, 52, 89, 95,144,158,135, 57, 71, 65,206, 87,196, 33, 64,152,118,233, 80,130, 69,181,104,144,154, -203,196, 64, 42, 95, 84,222, 93,136,144, 89,141, 9, 66,136,161, 28,168,255,139,165,143,239,167, 24,150, 37,144, 51,210,116, 60, -231,116, 31,151, 74,251,231,228,228,108, 53,192,244,190,211,183,204, 17, 9,218, 96, 99,181,155,169,243, 41,139,145,102,231, 8, -126, 48,248,190,142,220, 59,114, 85, 97, 76, 70,169,187, 88,118, 28,235,225, 73,157, 48,102,200,221, 63, 53,116,189, 16,195, 31, -182,161,138,145, 17,165, 65,134,224, 75,209,204,247,217, 20,157,152, 74, 53,117,193, 2,169, 50, 69,225,168,184, 26, 46, 66, 90, - 49, 36,171, 13,148,192,241,131,224,229,244,128,129,193,150,227,175, 0,140, 93, 65,107, 19, 65, 20,222,153, 77,210,184,233,161, - 69,193, 67,171,160,146,174,135, 66, 91,132, 98,205,143,240, 34,226, 73, 60,120, 16,133, 34,158,114, 11,197,171, 7, 47, 27, 3, - 34,226,177, 30,155, 66, 40,105, 61,120,242,228,189,177,189,180, 24, 65,193,160, 33,164,187,217,157,241,205,123,179,179,155, 53, - 68,115,154, 12,155,217,205, 50,251,205, 55,111,223,247,189,127,227,123,181, 90, 5,122, 94,171,213, 0,193, 1,202, 1,208, 31, - 34,106,195, 87,211,134, 70,187,221,126,191,189, 77,113,152,157,102,243, 96,127, 31, 72, 58,141, 0, 32, 14,224, 75,140,219,180, -161,177,186,182,246,124,107, 11, 64, 28,134, 50,171, 55,245, 55, 60, 15, 46, 29,128,254,102,165,114,122,114, 2, 32,254,116,115, -115,201,117, 97,112,128,114, 56, 30,214, 6, 56, 5,244,215, 61,207,156,136, 62,112, 24,128,251, 51,117,252,245, 71, 79, 30, 15, -227,157, 1,220,184,214,206,110,217,117,143, 14, 59,212,128,206, 55, 94,227,248,176,179, 94,217, 88, 94, 93,121, 91,111,192, 13, -186,247,224,254,141, 91, 27, 11,151, 22,225, 2,234, 47, 94, 46, 92, 94,188,125,247,206,199,131, 15,223, 78,187, 52,239,247,154, -173,171, 75,229,227,206,151,118,179,117,205, 45, 67,207,187, 87,175, 97,144,196, 54,195, 74,120, 60, 37,164, 31, 69,225,119,203, -159,177,236, 43,202, 9, 70,252, 80,134,140,178,103,201, 62, 34,120, 9, 33, 62, 22, 28,235,125, 62,229,197,251,232, 36, 12,139, - 65, 15,232,130, 84, 5,212, 87, 28, 39,143,165, 2, 97,246,157, 69,209, 94,255, 87, 87, 70,105,242,179, 60,239,124, 29,200, 79, -159,187,253, 80, 14, 66,216, 87,242,188,218, 48, 42,183, 82, 11,117, 26,168, 12,102,232, 50,135,133, 24,148, 56, 93,209,146, 97, - 36,244, 44,194,210,120,202, 89, 41, 87,178,217, 92, 16, 6,204,242,185, 12, 41,132,128,211, 16,149,150, 66,248,114,248, 91,248, -179, 5,231, 92,254, 98,127, 4,107,153,175,253,188,208, 40, 44,225,118,152, 33,194,180,104, 71, 51, 24,237,223,192, 8,220, 35, -138,216,136, 24,106, 8,226, 69,172,107,210, 48,111, 37,242,178,191, 45,127, 19, 42,202,146,180, 72, 19,198, 23,227,228, 93,253, -133,248,197,238,196, 93,212,244,160, 45,252,220, 78, 87,251,153,154,103,144,134,120,110,197,152, 28, 19,121,141,242, 36,168,224, - 9, 87, 78,138,222,177,140, 5, 61, 22,187,226,134,224,243,241, 55, 83, 44, 35, 1,203,104,155, 98,111,228, 56,149, 72, 98,186, -181,137,201, 36,133,209,178, 9,111,105,145, 56, 45, 81, 76,243, 77,125, 5,209, 88, 38,131, 76, 45,167,198, 86,200,196,111,228, -255, 72,103,114,220,158,168, 83, 45,168, 23,146,163,140,216,149, 79, 13,219,230, 44,202, 80,215,167, 27, 69,129, 24,207,187, 75, -165,196,161,111, 23,211, 37, 89,124, 1,220, 37, 56,239, 92,152, 43, 20,207,236,194, 32, 26, 2,184, 3,151, 87, 58, 99, 84, 85, - 7, 10,222,113, 56, 38, 48, 42, 2,207, 14,101, 79, 82,218, 12,249,250, 74, 99,215, 28,226, 62, 30,205, 72,114,182, 46,166, 74, - 94,138, 90,198,140, 8,174,156,197, 8, 64, 48,208,196,152,206,131,156, 44,227,199,135,130,147,181, 73,137, 59,179, 51,243,197, -124, 81, 68,163,159,126,239,143, 0,148, 93,203, 74,195, 64, 20,157,153, 38,213, 84, 69,180,130,130, 32,168,223,225,194, 7, 46, - 68,221,246, 59, 92,248, 21,214,159, 18,116,235,214, 23,130,214,199,166, 69,138,210,154,182, 51,227,125,204, 76, 30,181,136, 89, - 72,168,100,154,152,120,115,238,189,231,158,243,119,124,111,143,149, 62,126,221,250,125,196,176,215, 20,106,177,126,210,110,135, -146, 11,160,254,203,171,171,210, 62, 87,111,158, 91, 45, 56,117, 14,253,124,219, 23,234,117,248,185,189,183,199,248, 61, 44, 2, - 59, 28,169,225,124,224, 88,216,129, 99,207,207,206, 14,143,143, 27,141, 70,179,217,100,252, 14,183,249,165,133,219,201,233,105, - 45,169,221,209,202,121,130,188, 40,170,217,220,223, 98, 81,101,161,142,221,208,173,221, 29,194,239, 45,248, 34,248, 36,169, 37, -251, 71, 7,112, 28, 32,125,199, 83,102,169,144,156,202, 49, 47,117,119,123,147,235,255, 59,178,154,115,100,203,146, 38,219, 21, -186, 99,123,171, 42, 90,143, 18, 72,225,158,204, 32, 17,134,121,141,108,170, 23,166, 91,131,165,181,240, 37,251, 24,249, 83,136, - 99, 59,163,193,116, 69, 37, 21, 53,180, 88,245,254, 40, 63,250,226, 35, 85, 23,239, 95, 40, 85, 22,161,200, 1,230,140, 56,244, -204,202,171,238, 31,193, 83,149, 36,143, 64,230,216,166, 50,244,250,140,154,171,138,217,116,212,131, 92, 21, 45, 12, 53,242,195, - 98,180,141,131,228, 20, 18, 88, 65,118,148, 50,181,195,239, 81,127,166, 58, 51, 31, 45,119,134,175, 26,126,201,120, 77, 58,238, -138, 51,186,205,154,128,186, 80, 73,176,236,156,231,131, 59, 65,116, 54, 77, 29,177, 57,134,155,219,144, 99,186,228, 69, 49,119, -105, 66, 43,149,201,143,129, 22, 41, 69,222,176,194,120,142,154, 20,101,189, 54, 59, 9,131,255, 49,181, 90,156,126,252,157, 48, - 70, 33, 62,144, 38,149,147, 19, 67, 44,156,161,124,230, 87,134,241, 83,223,131, 43, 1,115,186,101,194, 75, 85,227,248,175,156, -204,122,151, 36,135,224,184, 24,129, 37,233, 94, 34, 86,152,188, 84,128, 9,154,236, 1,137,231,255, 36,210, 99,118, 21,108,230, - 61, 25,116,156,189, 86,202,171,188, 12,142, 21, 19,223,151,255,216,136, 75, 46,162,226,114, 8,225,173, 29, 7,239,138, 94, 18, - 33,184,179,155, 38, 37,202,114,109,105,243,177,253, 80,116,115,197,235,170, 96,141, 37, 70, 55, 84, 25,117, 7,157,165,169,149, -215,207,183,217,197, 13, 88, 43, 86,106, 96,236, 20, 9, 61, 99,233, 70,107, 38,131,193,101,166, 84, 33, 39, 29, 36, 77,142, 75, - 44,177, 97,121, 18,194,100, 29, 17,126,246, 56,100,147,169, 13,245,107,181,111, 70,216,204, 88,152,200,150,244,196, 50,227,118, - 72, 33, 94,121, 75,128,240,222,213,190, 55, 83,149,149, 90, 60, 7,153,125, 47,237,246,245, 55,156,205,143, 0,156, 93, 77,111, -218, 64, 20,220, 93,203,124, 88,145, 74, 3,167, 40,185,181,106,110, 37,215,252, 8,254, 29,127,132,228, 70, 34,164, 86, 54, 85, - 20,169, 85,111,189,181,193,199,128, 26, 34, 57,216, 94,239,102,223,123,222, 93,187, 77,168, 84, 14,200, 32,100,175,204, 50, 59, -204,190, 55,243, 63,245,145,134,164, 59,216,117,199,134, 50, 27, 90, 61, 30,143, 9,151,225,229,233,233,213,124,126,130,143,233, -116, 74,159,113,199, 6,133, 39,147, 9,209,249,225,104,180,140, 99, 58, 33, 73,246,203, 36,161,247,147, 56, 38,229,231, 69,158, -213,143,162,203,217, 12,116,158,243,115,195,226,205, 21, 23,243,185, 27, 91,186,186,187,156, 93,152,131,143,103,103,230,249,251, -215,111,234,175, 31, 1, 98,132, 72, 87,169, 57,190, 73,190,108,238,215,135,163,225,109,178, 60, 58, 57, 54, 39,255,124,189,128, -165, 43,219,165,119,169, 97,244,239, 62,188,255,116,181, 96, 53, 79,196, 40, 87,154, 55,237, 38,199,166,125, 85, 96, 39, 95,198, -194,183,156, 29, 64,181, 9,104,202,199,135,253, 65,222,219,100,187,123,179,204, 50,208, 62,120,131, 4, 5, 54,230,180,135,253, - 83,230, 75,122, 64, 99,226, 30,218,233, 70,129,232,118,130, 65, 20, 14,251,221,248,199,239,159,141, 27,114, 36,184,196,244, 69, - 51, 73, 75, 67, 28, 20,231,126,182,184,226, 49,202, 66, 33,172,247,126, 43,184, 23,164,145,161, 43, 46, 14, 66, 21,109,139,237, - 83,241, 36,153,130, 74, 82,228,249, 5,238,222,228, 74,134, 80, 67,102,240, 61, 16,224, 99,195, 74, 85,200,240, 77, 55, 24, 60, -154, 63, 42,220,109, 18,106, 15,227,120,122,225, 37, 87,236, 32, 69,124,169, 24,101, 46,161,246,206,236,238, 43,247, 97, 66,186, -237,236,255, 10,178, 59,192,242,108,180,225, 83,235,212,129, 86, 55,140,218,215, 12,180,135, 15,106,225,215,223, 38,184,243,125, - 53,193, 80,175, 94,167, 59,169,150, 97, 82,237, 69, 70,235,162,112,163,172,112,237,117, 67,111, 68, 10,121,127, 77, 40,154,102, - 86, 78, 17,236,133,238, 33,109,163,156,124,121,127,189,234, 54,179,173,181,203, 47,108, 53, 7,252, 81, 25, 67,233,199,202,195, -184,211,154, 90, 85,148, 46,152, 68,187,160, 20,237, 59, 24, 96,207,163,118,189,251,135, 56,179,199,100,134, 91,135, 22,253,186, -170,102,223,108,251,134, 64, 54,103, 39,151,185,185,244,106,243,171,217, 56,101,203, 93,120,169,193, 23, 0,218,254, 96,128,149, -100,229,227,110,187,206,134, 81,167,187, 99, 25,246, 50, 9, 69,230, 70, 72,141, 48,208, 25,124,128,112,222, 74, 85,223,224, 74, -214,232,204, 44,172, 11, 2,119, 1,102, 3, 26,245, 25,216,149, 13,172, 65,139,110, 71,235, 85, 62,208,151, 98,133, 20,217,144, - 97,180,167, 32, 88, 64,238, 79,105,171, 10,189, 11,228, 67,177, 93,231,165, 4,179, 4, 80, 17,159, 5,224,236,106,122,154, 8, -194,240,204,108,105,187, 5,138, 4,185,146, 24,117,241, 39,168,191,193, 61,120, 16, 19, 46,198,147,137,253, 23, 28,252, 27, 61, -155,120, 33,122, 48, 33, 49,225,208, 26, 18,146, 70, 60, 53,241, 15,128,144,136, 1,180,116,222, 29,159,153,121,103, 63,202,130, -209, 61,109,218,221,110,187,157,125,230,153,247,227,121,254, 13,223,199,110,235,245,122,224,233,128,233,124,223,135,107,128,245, - 0,229,126,191, 15,132, 5,112,167,105, 10,124, 7,242,226, 48, 79,174,203,251, 56, 11,239,130,122,119, 58, 29,236, 3,199,241, -122,226, 66, 64, 73,146,108,132,215, 7,131,193,117, 79,158, 47,224,193, 28,128, 41, 97, 56, 28,226,234, 79,210,244,211,206, 78, - 94,252,131, 13, 31,248,102,107,235,225,227, 71,184, 75,192,247, 58, 73, 51,251,168, 28,140, 70,247,146,228,233,243,103,224,236, - 95, 71, 95,246, 6,159, 63,190,255,176,185,242,226,229,235, 87, 56, 98,251,237,187,111,227,241,221,245, 4,116,126, 23,248, 30, - 28, 34, 66, 65, 68, 33,111, 59,251,108, 7,134,230, 51,130, 39, 86,146,204, 78, 6, 36,244,222,241,121, 83,137,174,148,107,173, -118,151,244,161,158,158, 90, 10,207,249,200,166, 51,217,152,216,240, 78, 20, 91, 42,109, 71, 5,184,195,173,150,237, 46, 93,136, -163, 7,171,113,220,105,239,127,191,192, 96, 93,203,232,216,117,184,117, 69,212,142, 90,191, 50, 91, 99,110, 19, 49,202,214,183, - 27, 79,224,133, 12,225, 84, 47, 74,152,183,125,249,149,134,114,207, 40, 57,201, 95,156,160, 90, 96,238,244, 27,196, 92, 91,141, - 36,155,142,119,171, 78, 98,218, 43,157,147,135,150,164,180, 71, 32,202,162, 51,115,186, 58,127, 91,202, 57,109,173,159, 76,232, - 70,102,171, 50,229, 28,105,104,118, 81,201, 21, 37, 65, 65,192,187,146,113,200, 61,239, 71, 45, 57,166, 6,178, 89,139,236, 69, -171,106, 8,254,154,146, 96,225,127, 21,247,214, 86, 40, 70, 53,224,110,110, 20, 13, 14,161, 0,227,123, 77,165, 44,164, 37,243, -128,140, 97, 31, 31, 46, 62,244,243,110,225, 42, 14,106, 47, 69, 85,117, 64, 85, 90,177,242,116, 66,221, 8, 23, 85, 19,212, 89, -111,107, 81,200,246, 94,215, 28, 16,236,142, 57,110, 17,214,169,165,111, 30, 38,166, 34,118,111,174,232, 0,123,199,172,134,205, - 64, 10,170,239,186, 45,123,159,254,229,127,163,170,242,189,169,159, 36,166,229,187, 64, 38, 91,110, 47, 78,206, 38,110,208, 78, -175,248,191, 23, 49, 86, 95,205,162, 84,227,199,229,201,124,115,233,232,252,240,126,124, 71,131,202, 16, 87,102,133, 74, 38,146, -156, 68,117,209, 47,155,216, 36,239,204,165, 66, 67,172,187,138,201, 88, 72,192,174,222, 26,156,162,231,176,187, 14,101,148,196, -110, 30,188,254,207, 11,174, 50,215, 9, 85,237, 20,227,159,111, 74,234,155, 36, 46, 47,178,159, 4,186,197, 44,196,252, 17,128, -183,107,201,105, 24, 6,162, 30,199, 73,212, 66, 81,145, 42,144, 16, 44, 89,113, 21,212,115, 32,216,210, 3,148, 5,199, 97, 81, - 46,195, 1,144, 88, 32,177, 8, 45,109,113,226,224, 25,127,226,196, 65,252, 36,178,104,187,168, 26, 37,241, 76,223, 60,207,123, - 3, 3,116,157,130, 85,207,160,139, 31,108,103, 95,207,102, 58,113,223, 47, 22,236,223, 15,136,250,142,245,113, 62,157, 26, 72, -126,113,117,121, 59,191, 49,159,161, 33,227,146,186,199,177,178,137, 82, 79, 94,240, 0,248,120,144, 27, 11, 30,193,238, 89,245, - 64, 9,143,156,131, 87,176, 98, 41,122,216,250,237, 48, 17,167, 2, 10, 41,159, 74,181,164,167,149, 19, 41, 95,144, 63,220, 24, - 69,105, 92, 47,180, 73,150, 76,134,217,193, 40, 61, 59,218,121,220,168,187,135,151,231,183,119,236,196,210, 24,154, 54,126,149, -105,191, 64,209, 18,138,171, 77, 87, 58,152,140,199,129,181,123,189,237, 56, 20,110, 50,138, 5, 23, 40,188, 81, 60,231, 35,168, -242,149,124,221,234,122,183, 42,201, 16,163, 44,221, 72, 54, 3,243, 13,253,154,216,107, 65, 21,133, 72,210,241, 96,191,100,171, -165, 44,168,209, 66, 5, 55,207,174,215, 14, 10,166, 16,117,176,157, 8,123,231,241,107,154, 7,163, 33, 15, 10, 92,113, 16, 72, -156, 2,204, 30,147,191,161,166,169,227, 54,254, 37, 51, 16,167, 75,238,136,157,246,119,224, 55, 43,214, 49, 97,188, 75, 12, 5, -162,185,198, 20, 18,250,108, 57, 0,194,105,161, 53,251,204,237,184, 14, 8,151, 56,179,123, 78,166,106, 81, 50,145, 95,167,189, -177, 54, 64,204,185,221,249,121,221,169,204, 2,189,113,159,201,187, 33,141,160, 1,248,140,125, 83,119,250,119, 25,166,255,241, -156,107, 48,180, 13, 3,131,219, 70, 23,192,242,148,137, 76,164, 41,100, 25, 78, 85, 18,195,100,239,120,247,100, 43,215,172,218, -172,229,134, 16,143,196, 30,196,218,224, 30, 70,254, 84, 72, 48, 74, 29, 44,232, 9,108,179,179,112,140,144,207, 48,138,100, 77, -110, 3, 64,213, 22,167, 43,151,181, 91,253,225, 30,135, 85,110,140, 23, 55,244,105,147,115,176, 20, 72,137,175, 34, 22, 8,221, -178, 52, 38,163,191, 16,254, 33, 0,115, 87,207,211, 48, 12, 68,115,118,146, 34, 49,128,196, 74,197, 0,252,255,133, 13,196, 31, -224, 79, 48,192,130,152, 90,145,164,181,125, 71,252,113,246, 57,165, 66, 2, 6,170,110,169, 84,201,114,158,207,239,222,123,215, -254, 33,188,254,147,207, 92,215, 95,174,215, 51,196,143,195,240,120,255,240,226, 9,159, 42, 3, 54,220, 92, 22, 87, 90, 97, 29, -207,145, 9,228, 41, 96,197,111, 32, 3, 1, 30, 36,131,208,145, 6, 93,137, 54,203,189, 83,136, 58, 9, 15,186,109,100,250,230, -167,111, 14,223,109,115,187,234,111, 90,220,236,221,132, 46,252, 88,157, 6,146,241,172, 85, 93,231, 67,112,174,207,187,171,139, - 19, 88,245,119,207, 31, 79,175, 27, 31, 90,170,253, 69,207, 98,148,193, 38, 20,208, 84, 52, 12, 74, 30,107, 69, 12, 17, 71,124, - 4,179,156,203, 53, 32, 66,202,116, 68,227, 96,178,219, 29,142,214,185,125,179, 67, 30,143,133,204,208,199,175, 14, 99,192,216, -127, 15,243,238,158,246, 67,223,181, 20, 18,112, 65, 22,130,144,163,155, 43,124,199,148,208, 91, 56, 25, 34, 22,116,167, 70, 31, - 38,133, 54, 84,220,113, 54,208,215, 83,155,115,186, 1, 44,242, 10,240, 8,253,114, 76, 4, 77, 95, 33,187,170,159,124, 91,182, -215,245,175,172, 16,149,196, 94, 39,160, 26, 14,188, 65,149,178, 3,202,160, 31, 85,124, 91, 92,218, 67, 17, 79, 46,137,109,177, - 80,114,182,117, 94, 97, 89,104,243, 31,167, 21,167,210,153, 81, 25,107,168,225,140,254,212, 55,198,133,213, 28,133,143,140,106, - 15, 14,167,222,255,100,246,225,239,128,106,121, 0,142, 66, 55,153,153, 68,240,177,238,193,248,217,173,172, 49, 74,251,105,147, - 10,245, 8, 91, 75,166,211,253,224,118,254, 62,237,226, 52,241,116,104, 25,178,202, 43,107, 48, 22,112,243,241, 96,155,168, 47, -104, 12, 39,114, 72, 2,205,178, 48, 55,120, 92,163, 3, 35,210, 50,114,195, 96, 8,142, 79,125, 44,100,179,100,216, 51, 46, 28, - 18, 81, 92,159,166, 32,176,137,199,132,148, 5,178,205,124, 59,209,159, 2, 16,119, 5, 57, 13,195, 64,208, 94,219, 73,219,208, -114, 67,220,144,144,248,255, 27,248, 10, 7, 14,192,161, 20,137,146,196,177,137,215, 94,199,155, 40, 82, 17, 72, 60,160, 81, 21, -199,235,153,245,204,236,111,241,251,191,215,119,201, 93, 15,158, 91, 42,202,198,232,218, 96, 41,200, 96,125,194, 32, 62, 79,244, -206, 55, 75, 63,235,209, 22,112,134,163,120, 25,105,129, 36,233,178,162, 53, 27,183,200, 78,195, 67,173,239, 13,188,156,237,219, - 48, 52, 10,174,181,220,111,225,170, 54, 55,135, 74, 86,230,185,117,143, 79,167,241, 12,208, 10, 16, 59, 4,173, 85,238, 80, 71, -237, 8,249,223,165, 66, 95, 41,200,156,238, 35,153,253, 43, 21, 12,164,144, 65, 91,131, 62, 93,172, 99,198, 30,142,253,177,243, - 45,178,206,222,166, 78, 75, 34, 36,136,217,149, 72, 70, 59, 21,249, 16,150,123,221,152,109, 83,239,222,187,215, 24,252, 91,140, - 51,154,163, 80, 10,150,241,148, 1, 25,255,191,115,101,222,128, 35,201, 12,109,205,201,120,239,153,206,218,229, 65, 28, 84,217, - 75, 32, 25,117,147,156, 10,208,240,162, 11, 86, 17,248,183,113,113,101, 23,107,249,233,203,159,207, 24,129,228,137,243,192, 89, - 35,117,228, 65, 20, 37,159, 78, 32,177,140,123,244,108, 62,245,196,108,216, 85,106,209,147, 41, 94,145, 19, 60, 23, 36, 26, 47, -179,143,166,220, 35,121,109, 75,169, 76,134, 77,195, 98,170, 42,163, 86,235,135,238, 95,149,151,125,125,248,104, 79, 73,131, 0, -117,135,149,125,166,146,146,169,249, 22,190,104,236,168, 40, 45,180, 86,186, 2, 83,137,141, 9, 49, 77,155,219,250,174,181,103, - 63,180,118,232,191,198, 66, 31, 48,251,200,113,253,231,136,218,241, 90, 14,247,130,119,168,112,181, 73,228,238, 32,105,216,163, -146,108,240, 83, 86, 65,232,209,219,201, 74, 70,119,194, 66, 59,186,151,206, 99,211,105,114, 83, 98,183,244,204, 48, 5,192, 5, -192, 10,212,138,116, 72, 26,180, 21,221,248,156,111, 1, 88, 59,191,214, 6, 97, 40,138,231, 36,138,179,202, 30,199,158, 10,123, - 89,191,255,231,232, 23,217, 63, 24,180,107,161,218,220,204,228, 38, 26,163,182,165, 91, 31,164, 80,168, 65,244,103,238, 73,238, - 57,127,226,251,221, 87,223,220,246,183, 55,218, 78, 99,162,207,204,242,253,178, 97,116,191, 36, 61, 53, 54, 72, 40, 47, 46,197, -229,248,223,163,247, 1, 34,166, 74,197,190,224, 65,217, 64,132,126, 9,222, 18, 40, 87, 10,155,149,122,173,139,151, 58,203,114, -245,213,154,143, 86,191,157,104,251,254, 35, 29,175,237,106, 39, 55,214,186,163, 47,235,172,191, 9,114, 41,158, 30,101, 85,226, -212,154,221,209,124, 31,164,245,146, 87,190, 33, 72, 16,104,184, 26,224,148, 9,247,160, 42, 47,225, 89,213, 62, 23, 77,190,167, -131,203, 19,224,224, 71,238,231,228,232, 3,184,162, 79,245, 1,149,241,151, 42,171, 59,196,239,232, 51, 20,236,110,104,114, 84, -232, 35,137,198, 14,221,152, 9,220,181, 9,206,224, 60,118, 26,192, 67, 99,207,222,113,196,210,160, 36, 80,114,150, 68,234,153, -107,122,156,187, 31, 36,238, 33,123, 58,253,190,118,171, 47,224, 30,169, 19,205,132,245,125, 12,244,132,242,161, 11, 41, 42,225, - 76, 26,191, 23, 73, 40, 34,133,251, 25, 11, 15,156,153, 80, 94,204,231,158,143,164,176, 89,184,139,107,169,217, 88,136,174,250, -175, 79,230, 88, 63,230, 59,156, 69,140, 69,188, 66, 7,247, 7,101,167, 51, 69, 97, 83,206,196,115,181, 46, 81, 30,155, 61,233, -166,227,187,182,226,140,245,128,212, 90,115, 35,240,217,205, 37, 66, 32, 35,245,237,205,142,242, 66, 15,106, 12, 23,151,134, 35, - 85,225, 11,154,120, 82,130,104,113,134,119,200,240, 59,192,239,150, 13, 57,154,253,244, 13,193,181,130,194,248,109,143,235,175, - 0,172, 93, 91,110, 2, 49, 12,204,132, 68,104,171, 34, 85, 85,239,127,177, 94,128, 27, 64,187, 73,220,152,196, 33, 47,162, 86, - 69,124, 0, 31, 88,139, 49, 19,175,237, 25, 51,190,243,173,202, 82,111,250,137,248,254,255, 37,185,248, 11,190, 15, 53,205,223, -216, 71, 7,241,237, 19, 48, 59,132, 70, 45, 66,221,126, 78, 8,105,201,122,206,223,123,136,215, 73, 69, 18, 49,164, 44,212,145, - 41,209, 42,137, 37, 20,109,161,212,157, 79,224, 30,168, 44, 95,143,177, 72, 71,195,115, 96,241, 47,253, 98,240,182, 29, 62, 94, -109,180,244,121,166,221, 21,189, 64,116,126,146,111,154,103,182,110,145, 99,188,195, 53, 92,118, 17, 26,240, 85,242,158, 55, 14, - 55,176, 14, 1,125,179,197,199, 1, 59, 93,132,225, 20, 72,245, 94,184,207, 11,102, 94,249, 4,220,131,104,214, 18, 53,139,220, - 84,159,152,214,249,226, 67, 96,109, 53,103,106, 69,210, 85,237, 93,207,165, 96,176,168,206,119,239,104,104, 54, 12, 19,223,120, - 28,204, 88, 99,125, 19,156,183,243, 26, 19, 51,212, 94, 64,241,186, 90,130,123, 7,202,243, 43, 68,213,138, 64,123,118,215,220, - 37,181, 4,119, 53, 96, 55, 61, 41,137,228, 56,214,214,179, 4,216,234,116,208,204, 35, 8,149,174, 73,226,160, 82,122,193,228, - 35, 29, 35,154,247,107,243,237,179,182,155, 61,157,204,251,183,187, 58,247,229,253, 30,210,192, 59, 15,170,177, 30, 0,171, 8, -228,238, 17,213,110,151, 61, 43,121,157, 94,184,187,151, 10, 11, 76,126, 73, 72,103, 85, 87,138,155,185, 32, 83, 75,116,160,167, - 60, 64,106, 53,217,108,202,232,127, 4, 24, 0, 58, 21,119, 57, 95, 10,227, 13, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, + 21,169,119,167,235, 30,198,123, 87, 5,110,217,127,236,233,100,164,226,101, 53,110, 63,211, 66, 54, 19,185, 58,161,155,242,249, +101,249,181, 25,224,123,131,249,120,238,203,119,243,232,241, 30, 81, 28,192,152, 19,233,156,211, 60,209,229, 52,141,176, 63, 97, + 69,237, 61,215,255, 31, 69,201, 63, 84, 11,140,194, 25, 51, 16, 98,109,235,196, 46, 11,198, 54,108,202,170, 48,170,124,156,184, +199,145, 90,135,209,206, 87, 33, 56, 12,202,233,218,241,101,184, 53, 40,112,251, 64,206,228,206,152,183,151, 46, 60,235, 96, 53, +184,202,236, 37, 88,177, 37,177, 20, 62,132,225,177, 50,160,117,197,155,113,178,206,131, 86,233, 91,234, 79, 98,154, 66,250, 42, + 93, 36, 13,149,159,136, 65,119, 84,234,150,184,221, 83,165, 83,205, 59,122,183,129,164,205,235,235,183,183,183,239,155,245,250, +120, 60,152,225, 62,169, 89, 19, 89,170,113, 22, 93,189,172,198,177, 26,146, 71, 22, 16,138,233,139,196,248,106,250, 73, 29, 90, +171,242,145, 75,153, 11, 82, 87,214,148, 13, 20,199, 56,119,117,176,158, 84,163, 38, 14,194,227, 68,240,157, 36, 63, 23, 25, 1, + 23,139,221,143,241, 15,101, 30,253,125, 88,241, 30, 95,170,231,235, 57,249, 79,112, 45,243,205, 45,240,104, 11,249,224,182,107, +255,150,220,233,245, 75, 0,210,174,166,167,109, 32,136,122,214, 94,135, 47,147, 70, 17, 23,154, 75,123,168,250, 15,138, 0,241, + 91,144, 56, 86,226, 47,240, 35,123,130, 35,168,135, 42, 74,139,132, 66,208,102,237,101,222,204,174,109, 34, 2, 65, 77,162,104, + 21, 91,150,119,119,246,205,155,247,162,245,127,225,187, 10, 50, 45,109,151,118, 48,170,198,168, 77,131,233, 9, 18,169,138,230, + 64, 72,200,221, 18, 63, 18, 4,252,149,151, 92,168, 25, 75,106,172,202,244,148,229, 86,181,183, 63,172, 62,109, 15,118,207,207, + 47,110,110,174,231,143,143,164,219,234, 38,248,209,129, 23, 53,190,142,129, 46, 51,152,199,221,187,138,109,187,199,165, 86,158, +140,157, 4,238, 65, 17,159,146, 46,168, 37,180,222,100,242,107, 27, 6,148,101,189,108,105, 41,102, 69, 30,160, 21, 90, 71, 23, +178,127,208, 90, 30, 20,213, 96,254, 97,253, 8,201, 9, 50, 16, 16,254, 20,223,165,231,112, 60, 13, 7, 53, 89, 99, 14, 6,227, +223,243,233,204, 45,110, 23,127,127,205,255,220,249,135, 89,182,120,178, 97,103,184,117, 56,174, 14, 71,187,195,129,229,220,152, +139, 89, 42,111,201, 27, 12,106,185, 25, 88, 46,110,184,227,196, 32,254,196, 88,239,200, 57,174, 56,185,112,197,192, 26, 8,238, + 84, 90, 48,253, 36,146,146, 45, 3, 95,139,131, 57,128,174,112, 20, 27,231, 80,193,242,236,112,245,149, 75,242,114,222,103,209, +196,146, 87, 45,182, 85,103,118,146, 34,102,200, 12,117, 53, 15,245, 9,181, 72,108, 5,159,198,224,254,174,155,244,238, 81, 3, +166,111,125,175, 18, 95,145,230, 21,220,191,140,191,222, 47,254,245, 15,249,224,155,141, 21,255, 44, 90,151,155,130, 59,189,148, + 44,150, 0,247,108, 5,118, 35,244,246,172,169,117, 74, 78, 10,176, 87, 5,247,149, 37, 70,235, 5,124,162, 14,145,214,117,164, + 15,238,125, 93,152, 82, 86,233,238,220,164, 12,160,178, 42,150, 70,136, 27, 89, 24,105,131,151, 41,135,147, 95, 99,131, 82, 3, +129, 87,152,150, 59, 73, 81, 13,100, 15,202,225,120, 21, 48, 40,139,232,110,193,227,170,157,106, 52, 58,248, 60,153,252, 56, 58, +250,121,117,249,253,248,219,233,201,217,253,244,129, 79, 99,252,112,206, 3,118,235, 58,237,195, 1, 98,141,234,147,151, 56, 1, + 43, 24,214, 13,196,123, 60,187, 93,252, 90, 43,166, 83, 1, 6, 4,243,174,137, 61,166,118, 79, 14,132,239,178,225,235,122,241, +217,112,156,179,148,172,101,234,208, 54,229, 89,158,199, 2,119,178, 74,113,116,100,172,177,117,104,222,242, 42,186, 79, 47, 45, + 71,119,184, 83,139,223,118,170, 60,254, 85,210,124, 20,220,249,245, 44, 0,101, 87,179,227, 52, 12,132, 61,118,108,147,236,101, +187,123, 97, 81,133, 16, 7, 94, 1,150,183,129, 59,175,197, 13,184,193,115, 32,246,194, 13, 36, 46, 72,172, 42, 74,243,255,227, +157, 31,187, 13,221,182,130,182,138, 34, 37,106, 98,123,230,155,111,230, 27, 37, 71,241, 29, 78,253,162,205, 65,228,117,130,233, +194,110, 19, 49,103,103, 39,192,198,165, 85, 38, 89, 0, 45,174, 96, 16,137,156,193, 72, 33, 24, 34, 39,160,212,139, 2, 48, 69, + 0,233,165, 49,207, 95,188,124,253,230,213,199, 15,159,112, 37, 70, 76,186,112,173, 85, 90,233,196, 48, 5,100,162, 53, 69,217, +150,178, 76,103, 50,228,227, 38,213,249, 67, 44, 20, 50,243,144,224, 14, 42,183,249,242,114,185,174,215, 50,233, 82,115,103, 11, +136, 50,122,244, 49, 13,243,121, 50,212,203,162, 31, 45,174,170,166,186,126,118,253,237,215,247,137, 45,229,241,197,178,164,178, + 10,245,198,132, 40,252,208,224, 16,208, 17,171,155,105,248, 61, 18, 73,255, 90,254,188,105,126,220,234, 77,105, 7,101,245,153, +247,185,247,133,243, 57, 18,118, 10,117, 4,235, 22,221,129,115, 81,107,181, 35, 29, 74, 59,107, 30,100,188,175,193,113, 15, 76, +238,172,207,148,179, 34, 69,131,207, 12, 94,175,237, 85, 89,133,117, 25,218, 14,250, 33,244,189, 66,106,191,169,166,186,214, 85, + 61, 53,117,104, 26,104,219, 17,135, 55,140,170,105,167,154, 31, 61,137,119,220, 32,255, 31, 72,196, 18, 89, 53,196, 71,144, 77, + 28,166, 3, 94,234,188,184,168,186, 82,138,111, 56, 47, 72,184,232,164,212,199, 16, 98, 79,133, 36,206,255,241, 65, 26, 62,134, +191,170, 34, 79, 46,159,174, 24,178,199,248,134, 74,164,201, 69, 66,210,125,251, 68,112, 79,194,245, 46,210,252,227, 13,120,227, + 57, 60, 31,200, 39,246, 10, 32,247,201,123, 74, 94, 1, 14,120, 80,196, 92,103,114,204, 21,146,111,195, 65,101,254, 62,205,223, +182,202,108, 93,236,132, 75,206,250,100,224, 8,252,207,212,212, 93,191,131, 74,108,134,107, 50, 8,218, 91,121,140,209, 14,210, + 16,116,136,148, 93, 24,253, 14,196,217,173, 50,217,103, 82,165,169, 65, 77, 11, 79,226,175,210,233, 40,109,131, 4, 3,105,156, +224, 2,172,201, 28, 2, 60, 49,120,239,209,222, 65, 87,101, 85,216, 51,168,213,251,183,239,110,190,124, 94,173,110,255,148,155, +174,173, 7,106,234, 26, 68,238,151,210,174, 48, 65,205, 27,202, 2, 12,107,180, 25,186,136,241,248,143, 54, 39,202, 18,224,225, +226,106, 93,111, 64, 73,219,196, 76,192,135,176, 40,206,187,190, 99,224, 8, 22, 25,166,113,253,216, 49, 38, 72,133, 42,204, 41, + 60,122, 27,155,200,180, 7,164, 60,113, 48,175, 64,238, 97,250,105, 40,134,153,132,163,143,103, 96, 41, 30,156,178,234, 99,135, +238, 4, 96,237,218,118,218, 6,130,232,218,107, 19, 19, 40,132, 86,149, 42, 17,193, 71, 32,132, 42,245,255, 95,120, 64,168,138, +202, 43, 15,189,168,164,208, 66,226,221,181,189,187,204,153,177,201, 69,216,226,161,145,162, 68,218,196,215,217,179,103,206, 28, +141, 95,241,207, 36, 91, 43,208,208, 70, 69,106,127, 9,196,150, 62,183,132,189, 19,246, 84,155,184, 49, 39, 16,232,151,198,184, +186,237,135,203, 52, 94, 86,126, 77,232,149,225, 62, 17,140,237,208, 47, 47, 62,127,161,161,111,179, 25, 17, 89,107,141, 41, 75, + 83,149,190,174,209,197,144,248, 53,231, 57,236,110, 98,245,167, 35, 23,124, 76, 48, 97, 42, 64, 36, 80, 47,227,193, 76,200,136, +112, 13,217, 57, 75,111, 26,154,162, 86,113,192,188, 17,252, 74, 21, 21,149, 19,144, 82,131, 29,168,233,209,116,175,216,157,125, +191,161, 19, 98, 41, 74,116, 71, 40, 81,206,187,191,141,189,247,229, 92,185, 38, 13, 85,240, 68,108, 14, 16,130, 41,145, 83, 34, + 25, 77, 96,140, 12, 92,198, 1,237,209,204,109, 50, 90,156, 36,154, 89, 97,138,132,221,197, 14,253,129,206,183, 57,254,244,145, + 34,254,238,207,253, 40, 27,149,142,174, 3,129,120, 92, 84, 33,229, 44, 85,131,232,195, 63,192, 41, 48, 46, 5,173, 4,252, 56, +145,232,234,176, 52,117, 96, 4,135,142,207, 5, 56, 31,147, 42,194,147, 67, 35,121,176,243,159, 11, 90, 71, 43,212, 93,185, 41, + 37,247,193,164, 55, 29,216,100,255,253,239,199, 95, 17,150, 12,233,102,172, 33,142,114, 17,107,211,253, 18,135,221, 5,251,163, +131,165,123,234,147,104,104, 35,124,155,210,245, 58,103,232,247,159,200,232,217,233,249,213,237,229, 27,157, 9,107,238, 0,205, +114, 13,118,116,184,123,244,207, 60, 20,121, 97,107,187, 21, 6,133, 70, 40, 26,111,211, 77, 32, 30, 80,222, 59,135,101,238,131, + 91, 15,171, 23, 95, 77,236, 1,119,169,166, 10,103,218, 50, 75, 14,156, 79,124,221,130,180,154,191, 91, 86,153, 77,193,125,229, +241, 93,201,234, 72, 62,197, 63,155,182, 78,129,164,195,172,164, 69,115,254,174, 51,254,144,137,204, 18,189,236, 66, 88, 22, 7, +112,108,249,127, 34,162, 13,170,108, 76,179, 9,152,179, 81,142, 54,211, 68,111,232,131,184, 77, 62,153,124,152,158, 76,175,191, + 94, 87,120, 86,157, 49,214, 44, 75,130,120,231, 26, 87, 99,214, 87, 8,199, 4, 23,135, 95,154,137, 32,156, 55, 52,219, 97, 9, +142,177, 24,143,223,141, 15,239,230, 63, 22,166, 36,226,111, 41, 81, 13,200,197,177, 64, 40,207,157, 83,189,152, 95,107, 34, 56, +184,214,200,246, 90,127,141, 98,159, 28, 67,182, 20, 78, 58,138,131, 57,165, 24,100,195,134,151, 70,253,151,206,168,125,158,156, +248,230,244,183,239, 48,158, 5,224,236,218,118,155,136,129,168, 61,235,236, 38, 45,149,160, 92, 30, 16,207,229,223, 17, 15,252, + 8, 63,128, 82,222, 80, 43,132, 90, 53, 73, 55,217,141,237,225,140,199,206,110, 46,165,192,107, 36, 59,217,245,248,204,204, 57, +199,177,251, 59, 99,238,201, 89,134,190, 35,219,108,115,146,207,177, 35,218, 56, 53,181, 21, 33, 5,237, 15, 9,238,160,203, 10, +222, 72,183,165, 73,216,165,149, 82,206,132, 11,216, 27,229, 6,162,119,211,243,249,252,219,226,254, 14,163, 48, 33,150,232,172, +158,117,253, 38,100, 89, 99, 39,111,228, 98, 40, 75, 59,135,229, 78,254,140,116, 93,200,190,124,241,234,161,189,231,204,151,145, + 94,158,161,228,126,136,172, 6,222, 28,190,195, 59, 5, 88,231, 42,128,146, 94,148, 44,230,236,196, 88, 31, 86,253, 18, 15, 69, + 73, 20,110, 12,170,230,240, 16, 54,171,208,255, 12,171,149,219,246,150,103,103,147, 25,213, 54,144,252,115, 58,155,218,218,198, + 2, 28,109,187, 78,228, 77, 50, 90, 79, 37,234,241,190,196,227, 56,155,184, 64,113,234,170,102,162, 46,245,202,136,250, 19,176, + 45,186,110,251,225,253,155,143, 87, 87,159, 62,127, 1,238,226, 21, 7, 49, 61, 70,108, 33, 60,142, 83, 22,136,173, 56, 50,125, + 63,177,104, 16, 24,213, 58,126, 91,148,155,192,176, 11,104, 45, 78, 77,222,122,185,255, 41, 58, 73, 5,194,110,114, 4,212,185, +166,102, 52,173,249, 60,128,148, 50, 74, 25, 10, 17, 17,253,178, 93,238,186, 92, 78,183, 65,101,213,109, 63, 82,177,213,144, 28, +232,105,165,242,177, 91,252,129, 63, 41,168,176, 23,200,244, 28,171,243, 53,129, 59, 29, 42, 84,234,147,120,114,236,184,111, 0, +184, 23,247,243,225,214, 5, 40,160,195,161, 17, 37,149,114,155,167,231,184,205, 32,119, 17,103, 58,203, 28, 81, 34, 39,245,216, + 84, 45, 86,250,165, 50, 80, 42,107,214,232,100,107, 79,141,100, 83,214,136, 79, 20,130,102, 44,168,186,193,209,177, 7,238,131, +235, 81, 93,141, 92,200, 24, 53,186, 21,100, 47,134,102, 5,126, 45,230,140,138,103, 9,192,197,131, 86,236,113,218, 21, 36,222, + 59, 93,222, 46,121,203,234, 81, 19, 42,150,249,148, 24, 98, 58, 48,144, 8,118, 19,171,110,221,126,191,158,163,128, 67,248,138, +125,215,251,212, 70,198, 36, 4, 73,167,120,209,156, 63,118,173,214,130, 8,111,167,130,157, 92,237, 91, 93, 94,188,189, 91,252, +186,124,253,238,230,246, 7, 6,212,117,221,111, 25,201,196, 75,117, 2, 52, 66,204, 7, 20, 78,125,191,193, 92,152,190, 72,166, +131,154,173, 0,113, 20, 47,180,179,189,177, 25,115, 60,255, 83, 80, 31,227,248,136, 60, 98, 69,180,176, 63,201, 78,195,199,162, + 96,211,217,127,113, 30,255, 22,128,178, 43,216,141, 26, 6,162,182, 19, 39, 77,170,221, 30, 80, 43, 36,170,170, 95,192,129, 11, + 8,196,167,192, 17,137, 67,255, 9, 10,252, 13,167,170,151, 34, 85,162, 82, 5, 18,210,210, 45,237, 38, 77, 28,123, 58, 51,118, +188,219,237, 38, 18,187,215,108,100, 39,246,155, 55,111,222,172,135,200,187, 28,248,177,140,172, 96,213,248,216,183, 54,176, 46, + 34,116,145,230,169, 72, 51,153, 5, 62, 1, 84, 1,209, 2, 95, 66,130,207,151,152,169, 16,149,171, 22,174,194,156,136,240,141, + 17, 53,216, 43, 61, 29,236, 58, 16, 26, 55,219,245,191, 43, 68, 22, 4,171,189,233,211,223,179, 75, 68,185,206, 24,182,133,184, + 64,133,100, 52,102, 82, 2, 23, 50, 43,157, 40, 88, 25,176,234, 35, 46,167, 13,152, 16,222,212,202,151, 94,188,178, 77, 95,194, + 56,216,221,217,221, 41,166, 63,255, 92,172, 59,221,156,243,177,196,113, 48,226, 57,113,226,192,150,175,155,230,246, 22,211, 64, +105,231,118,241,171,157, 87,105,215,166, 93, 49, 37,223,203, 19,124, 8, 86,243, 13,192, 88,210,150, 20,229,131, 18, 7,136,244, + 24,128, 69,109,130, 82,153,107,149,229, 73,129,224, 94,168, 92, 19,216,146,103,222,201,166, 1,242, 48, 83,193, 16, 94, 63,127, +113,246,227,252,226,114,246,254,221,219,211,147,179,239, 39,167,101, 94, 80,228, 73, 96,146,105, 71,226, 22,121, 97, 14,247,159, + 45,234,106,118,117,125,244,241, 3,210,159, 79, 95,142,179, 45,133,113, 6,137, 74, 66,154,149, 35,163,164,181,119, 56,160,134, +230,133,129, 11,247, 74, 66, 46,120,124, 73, 26,247,150,247,132,130,143,158,180,226,104, 67, 54, 93,205,226,251, 32, 98,246,151, + 43,251,208, 40,185, 73,116, 30, 93,253, 0,246, 81,116,144,155,136,121, 50,224, 82,131,101,126, 41,198,173,108,165, 46,107, 83, +249,225,227,221, 26, 90,144,184,124,116,107, 77,156, 84, 7, 29,136,165, 72,223, 27, 98,213, 67,178,131,232,153, 26,216,120,184, +188,148, 2, 96, 84, 28, 87, 43, 14,244,240, 7,203,125, 62,135,139, 99,178, 53,153,215,127, 87, 58, 15,214,111,192, 26, 25, 68, +148,143,124, 80,137,216, 89, 40,163,103, 95,245,110,168, 88, 77, 77,249, 93,123, 3,138,236,185,249, 38,100,247, 60, 46, 13, 44, + 94, 4,160,247, 94,201,224,152,236, 97,157,249, 58,248, 6, 64, 25,155,155,216, 72,151,114, 84,160, 96, 64,208,141, 79, 23,217, +140,105,201, 1, 76,149,208, 14,243,115,100,236,109, 99,232,212, 26,195, 7,229, 80, 46,233,107,253, 9,153,195,152,244,176, 49, +154,228,223, 36, 43,243,237,178,220,198, 43, 94,190,122,179,127,112,240,237,235,103, 4,126, 58, 51,167,111,192,241,121, 48,176, +123,142,103,201,114,139, 92,135,114,175, 49, 98, 4, 50,108,135,182,255,211, 27,177, 86,234, 24,167,221, 65,229,102, 38, 4,203, +130,141, 15, 48,180,210,220, 0,130,195, 35,195,216,248,231, 94, 0,214,174,101,183,137, 24,138,250,122,158,121,148,128,160,165, + 65,101, 9,127, 1, 11, 96,197, 87,161,136, 47, 64,229, 15,144,224, 27,120, 44, 17,108, 89, 33, 80, 41, 21,109,164, 46, 8, 37, + 45,243,200,120,108,115,239,181, 77, 66,154,138, 86, 98, 86, 89, 68,242,140,231, 62,142,207, 61, 71, 19,159,171,184,123,241,200, + 34,146,114,190, 56, 8, 86, 55,127,142,203, 5,161, 79,141, 47, 72,180,181,157, 57,225, 17,217, 86, 53, 17, 14,136, 67, 99, 21, + 37, 50, 73,227,172, 27,119,215, 59,215, 12,232,137, 58,250,213,150,146,228, 76,137, 79, 74, 76,111,122, 21,162, 42,139, 36,205, +168,153, 11, 51,158,236,241,103,142, 90,102,205, 72,196, 8,204,195, 59,198,204, 43, 88,164,188, 61,188,181,123,184,227, 36,152, + 78,118, 46,172,143, 60, 79,117,129,173, 85,147,202, 84, 89, 98,223, 6,189,203,199,213,137,143,122,141,232,224,210,151,195, 93, + 30, 17,201, 69,133,170,197,228,133,150,140, 86,150, 81, 60,115,110,214, 73,116, 32,154,232,233, 24,190,215,162,109, 34,221, 31, +228,131, 36,235,229,253, 94, 39, 21, 60,240,119, 19, 95,171,121,214, 41, 52,169, 65,165,200, 16, 59,107,186,249,196,125, 56,137, +227,158, 69, 54, 24,245,100,182,141,194, 84, 1,143, 43,195,173, 97, 53,211,223, 14,246, 55,214,111, 90,209,121,245,230,117, 81, +153,251, 15, 30,126,248,184,247, 99,138,157, 42, 82,134,156,187,172, 64, 22, 87,175, 12, 30,141, 70,187, 59, 95,159, 60,221,190, +115,247, 30,194,204,103,207, 95, 32,254, 36, 58,155, 53,155, 89, 26,215,180,193,144,113, 90,211,250, 64,189, 87, 91, 40,141, 94, +235, 38, 71, 39, 38,137, 50,220,109,105,181,158, 7,150, 9,211,255,191,190, 36, 98, 2,147, 96, 2, 17,175, 8,180,122,177,168, + 22,255,225, 34,125,100,218, 43,154, 66,158,210, 23, 6,238,123,133,229,181, 19,229,149,174,225, 95,144,170,228,226, 14,158,130, + 11, 34, 40,210, 23,170, 85,206, 38, 55, 79,198, 78,169,233,164,196,249,249, 7,245, 24, 48,103,183, 46,128, 37, 95,219, 41,150, +223,206, 3,206, 87, 9,218,113,178,242,216,105,245,211,158,253, 8,225, 24, 11,190,202,243, 93,226,142, 85,170,226, 33,149, 35, +214,231,226,246, 96,251,246, 25, 65,185, 51, 47,238, 50, 10, 62,214, 64,199,203, 57,180, 39, 74, 15, 92, 47,224, 26, 27, 45,155, + 87, 23, 46,233, 74,188, 83, 27, 56,209, 3, 56,157, 65,204,170, 27, 94,141,245, 49,152,212,160,232, 39, 86,121,140,162, 70, 17, + 19,195,158, 38,108,178,202,182,237,245,181,205,241,100,223, 77,221,240, 16, 41, 92,149,182,172,163,193,231,198, 38,128,255, 52, + 89,158,247, 71,219,143,223,189,125,191,241,114,179, 40,142,113,249, 27,253,173,207, 7,159,112, 53,163, 16, 95, 53,184,163, 13, +171,232,243,180, 91,207, 74, 27,210,155, 2, 53, 4, 43, 79,203, 82,213,148,231, 81,201,194, 5, 32,251, 10,114, 49,135,172,166, +101,245, 34, 29,191, 32,216, 94,138, 22,219,154, 11,231,211,111, 1, 88,187,118,221, 38,130, 40, 58, 47,207,122,215,201,218,184, + 65,148, 40,113, 65,137,144,104, 81,254, 50, 21, 18, 63,128, 20,165,164,160,194, 13, 13, 18, 5, 10,137, 68,129, 68, 21,156, 16, +112,214,251,154,225, 62,102, 95, 78, 44, 64,194,141,237,125,142,118,103,239,158,123,207, 57, 51, 3,126, 85,222, 13,238,141,221, + 88,119, 61, 41, 56, 21,184, 50,163, 49,233,195,219, 28, 73, 64,146,177,246,186,112,121, 5,136, 71, 84, 68, 91, 9, 21,188,165, +248, 28, 48,241,232,248,158,160, 17, 13, 50, 92,243,104,242, 48,181,233,218,103,176,189,106, 92,205, 24, 15,201,210, 64,242, 87, +156,217, 14,190, 80,112,105,162, 77,177,246,172, 61,116, 97,148,130, 22, 98,192,146,235, 95, 43,234,125, 88, 82, 15,138, 76, 35, + 3,195, 19, 56, 88,149,151, 57,236,140, 20,141,151, 5, 57,152, 27,121,190,184,202,126, 40,198, 47,236,143,107,105, 92,239,195, +172,167, 84,184,128,255,145,181,120,197, 69,125,225,190, 93,198,171,120, 98,246,162, 24, 46,130,133,238, 33, 76, 93, 67,254,174, + 29, 54, 24, 82, 22, 29,141,204, 36, 81,251, 9, 74, 21, 19,107, 12, 2, 23,149, 23,174, 44, 37,172,188,186,206,168,220, 13,128, + 1, 22,202, 13, 26,125, 84, 89,113, 49, 75,254,204,242,231, 79,159, 61, 89, 28,188,255,240,241,193,108,190, 56, 92,188,121,187, + 60,124,124,144,166,211,200, 70,231, 23,159,163,241, 40,142,196,100,108, 32, 3,224, 14,123,244,226, 8,146,251,215, 39,167,103, +103,159,150,203,119,231, 95,190,122,167,225,128, 10,135, 31,192,198, 27,173,172,149,179,216, 76, 83,189, 55,209,177, 13,197,222, + 10, 73, 85,151, 83,115,136,205,194, 27,208, 90, 4,218, 20,114,107,136,130,145,182, 10, 85,149,245,144, 83,250,159,115, 54,205, +147,121, 14,105, 53, 7,175, 65, 88,244, 59,165,150,254,175, 60,228,247,210, 86, 53, 1,118,130, 63,161,250,164,183,156, 62, 12, +123,209, 12,229, 84,175, 49,242, 79,167,186,195,142,118,245, 1, 98, 67, 68,231, 16,100,105,121, 99, 44,217, 49, 7, 75, 23,186, +101,104,100,112,152, 32, 48,164, 42,184, 30,188,162, 84, 31,176, 41,209,211, 62, 10,246,150, 42,134,237, 84,132, 36,125,132, 12, + 42, 25,250,141,213,118, 98, 92,121,132, 11,193,180,153,233,235,103, 8, 27,181,171,152, 10,197, 29,232,236,241, 40, 17,141,164, + 21,185, 81,218,198,187,160,120,230,113, 49,138, 50, 67,175,106, 69, 97,158,126,220,220,174, 48,180, 97, 48,103,182,142, 9, 54, + 36,155,112,127, 12, 66, 10,226,201,102,147,237,203,244,213,241, 75, 84,155,120, 81, 20,249,247,155,203,154, 28,239, 24, 64, 80, +229,236, 41, 61,170,167,241,236, 54, 95,119,184, 57,192,202,240,196, 87,144,195,225, 5,112, 94,202, 30,165, 33,239,123, 59,111, + 83,221,112,152, 49,146,234,245, 46,193,147, 24, 10,189, 60,246, 31,191, 37,163,194,174, 5,193,201,247,253,225,194,176,131,236, + 31, 63,191, 5,160,236,106,122,155, 6,130,168,103,215,118,118,157, 52, 41, 13,164, 66, 69,168,253, 5,192,133, 3,167,254, 13, + 36, 14,252,213, 2, 66, 66,112, 64, 2, 36,212, 75,197,161,162, 9,109,148, 52, 86, 28,127, 51, 51,187,142, 93, 7, 35,136,114, +202, 41, 94,207,188,153,121,243,102,246,207,248, 14,117,243,168,105, 31,181,124, 70,242, 6, 23,193, 45, 58,163,153, 81, 66,227, +201,101,101, 98, 22, 67, 52,152, 91, 43,209,117,249,160,192,244, 48, 56, 83,205, 77,106, 81, 56, 67,181,127, 95,141, 23,201,178, + 36,130, 69,240,212, 1, 80, 39,132, 95, 70,213,225, 43, 48, 74,111, 18,142,186,230,122, 57, 11,238, 91,246,144,140,101,164, 71, +220, 41, 45, 26,174, 65,242, 29,179,159,198, 0,189, 85,243, 48,139,138, 15, 33, 93, 27,174,140,146, 75,121,138,176, 86,194, 64, +239,225, 15, 67, 61, 58, 57, 60,190,190,189,169,228,244,228, 52,152,116,159, 28, 28,127, 93, 92, 92,136, 25,244,139,161,175,125, + 32,169,191,242, 93,237,187, 38, 51,234,121, 94, 64,220,160,107, 44,216,119,189, 64,143,126,205,194, 36, 19, 8,220, 69, 6,121, +234, 60,156, 76, 94,191,122,217, 15,212,116,122,179, 90,173,241, 84, 92, 38,220, 17,127,233, 12, 28, 25, 19, 69, 83,246,164,124, +246,228,233,135,143,159, 16,116, 79, 95, 60,255,242,237,243,189, 97,144,230,209,163,163,195,120,189, 88, 46,175,123,202, 69, 59, + 89,199,101, 20,101,211,121,248,246,236,253,217,155,119,243,213,250,106, 54,255,113,121,133,175, 9, 67, 70,156, 21, 17,229, 67, +121,146,113,135, 21, 67, 16,144,156,115, 19,151,248,141, 19, 52,107,140,186,133,239,138,112,137,121, 31,228,219, 91, 3,171,149, + 28, 70, 57,186,187,127,134,166,198,173,211,182,248, 97,128,157,149, 3, 93,212,161, 81,200,116,153, 41, 38,239,208, 57, 58,219, +206,145, 90,242,196,118, 55,230,223, 16,223, 36,197,174,240,202,178,220, 25, 59, 34, 90,224, 32, 24,175,211, 80,236, 68, 50,216, +105,154,129, 3,127, 1,133,187, 67,170,182,245, 0,224, 56,157,195,177, 66,212,210, 29,167, 41,227,217,198,191, 10,184,155,193, + 86, 52,130,140,165,221, 97, 43, 59, 51, 83, 25, 53,220, 83, 17,137,217,143,176,226, 54, 97, 53,111,204,163, 74, 97,203, 91, 9, + 60, 65, 97, 40, 26,230, 94, 76,223,149,101,178, 70,222, 66, 78, 71,114, 25, 71,248,210,239,171,254,100,239, 65,154,167,143,199, + 71, 88,193,199,217, 70,212, 15, 75,228, 42, 37, 57,232,230,113,204,183, 64, 38, 9,213,235, 60, 96, 77, 72,192,243,171,144, 87, + 67,242,165,135,174, 66,133,187,228,197, 38,212,166, 80, 74,159,159,127,255, 57,189,196, 84, 0,163,194, 38,142,120,153, 9,173, +233, 48, 11, 55,236,134, 2,112, 6,122, 24, 70,183,112, 23,223, 11, 75,189,131, 66,119,150,146,228,209, 0,213,123,132,102, 28, +237,234, 27, 49, 58,208, 48, 62, 43,119, 65, 52, 39,213,187,141, 77,123,131,180, 72, 90, 70,162, 69,144,177, 59, 24,100,199,191, +174, 61,205,149,241,255,125,126, 11, 64,217,213,181, 54, 17, 68,209,238,236,108,118,179,217, 38,180, 24,124, 80,136, 80, 74,161, +130, 85, 65,250, 82,161, 15,173,255,215, 31, 81,125,208,183, 22, 41, 5,159, 20,106, 17,217, 52,205,118, 63,103,198,251, 49,179, +217,182, 49, 42, 36,144,108, 72,178,217,153, 57,115,238,189,231,220,172,194,119, 91, 2,111,205,107,157,154,234,122, 60,130, 49, + 16,182,251,151,236,123,176,101,225,165, 52,174, 16,209,145,253,123,173,193,157,237,111,202,214,227,173, 3,130, 43,156,155,209, +198, 56,126,244, 35,191,162,239, 36,104,103, 6,207, 8,143,163,175, 93, 15, 9,251,128, 0, 70, 59, 59,147,157,169, 48,174,176, + 19,112,151, 49, 56,184,243,100,103,118,123, 77, 10, 25, 54,111,180, 42, 93, 23, 40,120,154,106,191,173,204, 75, 76,198,207,210, + 44,245,105, 7,135, 31,149,149,183,233,205, 47, 99, 9, 20,146,247, 81,127,216,147,189,247,151, 39,223,204, 52, 18,152, 94,175, + 42,108,249, 82,230,166,194, 52, 8, 22,245,227,190,140,130, 0,200, 59, 10,120,124, 8, 15,213,222,238,246,209,225,193,197,215, +179, 97, 34, 7, 16,152,133,176,127,172, 21,245,124, 54, 75, 95,190,218, 61, 62,124, 59,136,123,233,244, 39,112,144, 16, 21, 68, +100,101,197, 62, 29,190,196,241,105,246,223,236,157, 95,124,169,234,236,245,139,231,151, 87,223,243, 34,219,222,154,156,124,248, +248,238,232,248,211,231,211,186, 82, 20, 71,227,181, 12,164, 44,234,186,108,154,164, 31, 82,131, 15,244,167,246,104, 13, 0,173, + 9,208, 50, 40, 6,192, 49, 34, 92,157, 48,219,139, 66,151, 21,170,139, 53,183, 61,131,197,141,206,164, 6,215,154,177, 43,139, +241,253,158, 19,213,116, 84,192, 93,230,110,108,195, 39,124, 61,242, 99,237,184,240,234,168,117, 5,184, 47,197,235,127, 15,131, +199,201, 99, 77,217,219,123,231,255,167, 44,169,232,100, 35, 73,220,212,242,226, 5,209,129,147, 41, 48,177, 3, 7,229, 67, 95, +139,219, 72,204,211,209,228, 26,251,157,225,179, 40,136, 57,153,243,240,108,169,223,139,113, 5, 97,170, 22,121, 98, 89,108,177, +228,223, 14, 23, 30,139,187, 99,225,178,166,139,161,241,188, 86, 10,105, 91,120, 56,161,215,194, 21,200,204, 29,121,155,117,137, + 8, 82,200, 48,100,179, 98, 5,167,153,100, 13,180,113, 77,156,132,104, 69,147, 44,125,246,219,183, 48,187,167,235, 3,180,122, + 94,220, 0,140,103,249, 60,111, 10,159, 93, 71, 24,206,147, 59,145, 26,218, 1,138,212, 26,211,176,116, 67,180, 87,228,213, 38, +223, 58,171, 90,236, 89,111, 36,155,212,226, 73,241,212, 32, 93,189, 95, 84, 37, 80, 64, 0,129, 36, 92,159,206, 83,218, 39,248, +115, 16, 66, 96,118, 43,188,155,178,206,141,107, 52,102,216,111,222,241,167, 2,140, 66,220,192, 5,237,206,246,236,117,122,109, + 89, 81,184,113, 40,199,200,206, 47,145, 34, 22, 25, 64, 18, 38,165,170,255,198, 42,112,195,209, 70,221,197,119, 64,210,170, 99, +118, 29,150, 10,232, 89,189,246,255,142,214,223, 2,176,118, 61,191, 73, 4, 81,120,102,118, 22,134, 5, 34, 4, 60,181, 7,123, +178,181, 38, 77,141, 7, 19, 15,158,108,210,248,159,154,120,245,127, 80, 47,141,154, 84,123, 41,141,191,122, 48,210, 16, 96,150, +133, 25,124,223,155,217, 21, 8, 77, 52,113, 79,176, 33,217, 93,120,239,123,191,190,239,177, 5,223,171,191,112, 78, 54,193, 61, +208,222, 97, 59,110,193,115, 81,126,248, 76,101,202,163,214, 80,156,236,187,178,127,164, 67,219, 67,196,100,161,204, 31,124,180, + 71, 2, 93,158,182, 3,194,208,154, 87,119,179,222,104, 49,181,148, 19,201,196,241,142, 70,116,117,150, 46, 98, 58,199,119,216, + 66,220,194, 24,219, 85, 76,220,173, 20, 76,208, 76, 17, 46, 18,254,182,205,157,153,203, 41,252,231,243, 28,246, 39,152,199,187, + 84,209, 34, 17, 21,245,225,238,193,112, 60, 84, 65,207,207,115, 51,186,194,200, 14, 67, 66,226,188,235,183,250, 90,107, 59,159, +133, 70,179,224,162,148,204,239,253,116, 48,146, 69,166, 76,104,238,123, 86,211, 17, 92, 26,173, 9, 94, 33,197,131, 56, 15,149, + 66, 88,157, 70,230,245,240,224,240,249,201,201,135,179,183, 54,159, 82,180,193,172,213,227,217,127, 92,255,124,243,238,108,112, +245,245,209,209,209,139,211,211, 94,175,247,229,234,251,112, 52,213, 90,180,179,180,149,201, 70,157, 32, 56,127,124,124, 60,184, +188,252, 53,188,217,187,183,231,124,122,254,121,240,244,201,179,151,175, 94,239,239, 63,232,119,186, 31,207, 47, 52,174, 71,183, + 22, 72, 22,112, 48,104,198, 82, 73,177, 36,173,137,134, 17, 45,163,154,153,108,155,132, 66, 11, 61,239,216,130,158, 64,126,108, + 82,250,152, 96,191,197, 23,106,169,180,205,237, 12,201,146,224,114,185, 28,248,173, 47, 33,244, 43, 20,128,117,162, 17,126,152, +166, 70, 74,194, 21,232,252, 95,187,146,255,241, 72, 69, 74, 85,185, 45, 38, 14, 28, 56,244,237, 12,164,173,139, 44,109,212,211, + 70, 1,190,243,150,164,190,107,186,179, 21,173, 96,181, 73,166,124,171, 74, 36,141,154,136,219, 86, 20,164,178, 54, 65,147,119, +193, 59,139, 40, 96, 22, 4,241,132, 29,149, 47,172,128,187,175, 8,105,130,135, 13, 60,118,219,184,183, 72, 29,136,156,189, 40, + 35, 68,231,195, 36,198,131,245, 20, 37,250,178, 74,221, 35,186,151, 39, 69, 64,118,249,167,228,141, 10, 38, 24,105, 34,162,168, + 59,234, 87,146,240, 2,116, 91, 41, 2,177, 61, 9, 42, 61, 62,201,158,139,212,174,146,188, 68,118, 60, 50,125,142, 1, 65,221, + 42, 99, 13,128, 85, 26, 53, 94, 61, 66,230,166,240, 86,133, 49,239,110,111,199, 22, 54,172, 89,165,148,110, 14,167,159,199,158, + 10,112,121, 17, 92, 62, 64,128,172,246,218,128,133,101, 59,205, 14,213, 1,228,224,157,172, 83,171, 55,198,147, 27, 66,118,173, +106,247,119, 14, 46,190,125, 98, 90,164, 67,188, 96, 9, 44,196, 51, 24,136,121,238,227,198, 89, 72,203, 52,249, 18,203,106,255, +192, 6,251,251,214,185,165,212, 28,176,103,114, 69, 98,214,174,183, 42,209, 58, 40,106,174,240, 91,138,218,181, 34, 22,162,200, +149,218,119,163,196, 11,110, 71,224, 46,255, 66, 24,184,245,248, 45, 0,103, 87,211,219, 52, 16, 68,189,187,241,250, 35, 31,165, + 9,165, 8, 85,173, 2, 5,122, 64, 32,142,112,224,192, 1,137, 27, 18, 23,254, 45, 23, 36,110, 69, 21, 66, 8,104, 43, 5,168, + 26, 8,105,234,196,117,226,196,246, 50, 51,187,235, 36,208, 2, 34, 7,203,114,164,181,108,175,103,103,222,188,247,252,167,248, +206,127,209, 65,160,109,144,238,155,147,225, 23,109, 37, 11,224, 45,202,137, 29, 78,243,152, 30, 48,110, 69, 89, 41, 90,149, 40, +203, 28,147,102,115, 83,184, 32,196, 7,133,155, 68, 6,171,172,201,224,178,191,250, 37, 62,162, 19, 97,132, 71,214,182,182,132, +160,140,221,196, 20,165,217,184, 68,131, 53, 9,137,246, 23, 34, 90, 46, 1,126, 48, 23, 38,211, 9,204, 44, 88, 66,167, 89,122, +115,125,251, 52, 25,242, 82, 43,205,180,209, 93,209,143, 7, 72,154, 37, 93, 45,140,180,185,182,149,164,103,194,226, 55,112,169, +201, 44,161,149, 92,221,191,126,239, 71,212, 67, 64, 74,137, 94, 49,236,201, 81, 51, 12, 27, 85, 47,244, 42,245,192,111,174,184, +205,186, 92,173,251,141,176, 2,121,113,232, 99,176,149, 94,197,151, 46,237, 40, 41,138,187,119,110, 57, 12, 59,195, 7, 7, 29, +135,123, 27, 87, 55, 59, 95,191, 41,244,166,113, 97,230, 71,163,232,253,135,119,135,157,253,237,246,214,211, 39,143, 55,174,173, +119,143,187,189,193, 48,142,209, 23,172,127, 58,217,185,189,115, 18,141, 62, 31, 29, 95,106,172,220,104,183, 95,190,122,253,232, +225,131,143,251,159,118,247,222,190,120,254,108,247,205, 94,183,251, 61,207,157,106,232,167,105, 6, 43, 14, 50,214,104, 97,196, + 46, 71,142, 7, 20,135,146,150,133,129, 35, 92, 36,141,193, 45,116, 5,171, 74, 81, 11,121, 0,171,136,100,190, 7,101, 25,119, + 37,131,228, 1, 74, 91, 98, 11,103,101,124, 47,237, 82, 75,238, 34, 76,113,207,245,178,165,156, 20,255,106,133, 87, 32, 62,206, + 84, 22,136, 32, 35,117, 15,191,216,220,241,191,227,187,116,100, 78, 94, 68,236, 47, 58, 88, 85, 65,160,214, 85, 4,137, 82,203, + 7,107, 19, 34,110,157,143,222,104, 33,248, 2,212, 99, 40,182,112, 57,228,173, 85,216,183,145, 17,248, 94,104,235,209, 5, 80, +167,124,117,139,194,138, 3,244, 56,121, 49, 91,110, 30, 48,110, 51,247,102,216,154,204,198,212,174, 68,226,169,110,212, 10,231, + 28,134, 40,108,171, 94,141, 30, 8, 97,133, 4,158, 21,170, 76, 37, 57, 91,150,164, 40,171,156, 95,136,236, 54,184, 43,131,204, +216, 4,127,174, 96,210, 36,149,138,150,113, 32, 91, 86, 48, 99, 53, 35,140, 8, 28,233,150,136,216,104, 75, 41, 10,241,142, 81, + 43,150,214, 5,152,189, 65, 45,202, 73,105,129, 35,208,190, 40, 23, 3, 56,103,156,198,186,109,152,107, 11, 48,108,252,104, 91, + 2,184, 9,164,102, 44,140, 92, 29,194,160,165, 40, 42,253,221,246,241, 52,129,224,142, 53, 39,231, 85, 89,139,146, 65,171,182, + 54, 58,139, 78,226,254, 56, 77,168,244,167,138,192,226,239,212,180, 51, 52, 0, 61,143,211, 89, 90, 44,231,239,206,220, 73,137, +107,171,103, 75,208, 99,100,190,100, 14,192, 48, 4,170, 56,101,136, 35,177,203, 84, 43,242,172,228,216,184, 93, 21,243,245,130, +253, 78,215, 89,174,125, 29,103,193,118,244,223, 85,223, 23,253,126, 10, 64,218,181,180, 54, 17, 69,225,123,238,220,153, 73, 58, + 41,245,137,213,106, 90, 16, 5, 5, 23, 85, 23, 82,168, 11, 65,119,197,149,221,185,208,149,226,255, 19, 92, 90,176,190,168, 26, +132, 34,138,197, 7, 42,134, 74,155, 56,147,153,204,100,230,122,207, 57,119, 38, 83,169, 85, 48,201, 42, 9,195,132,220,123, 30, +223,247,157,239,254, 61,190,143,127,179, 37,124,128,103,211,168, 95,131,192,105,141, 72, 26, 66,112,188,197, 61, 28,107, 71, 3, + 96,199,174, 36,193, 29, 60,162,207,170, 41, 34,223,165,181,173,240,148,219,116, 27, 19,174, 63,233, 79,126, 31,252, 24,229, 67, +134,202,114,157,151,255,172, 29, 56,160,152,207,235, 64,200,130, 75, 15, 11,180, 75,251, 18, 60, 47,221,112,189,249,246,252,198, +230,123,179,164,122,209,182, 96,150,135,214,174, 99,157,223, 21, 85,216, 14, 21, 29,200,239,155,230, 14,144,227,101,213, 24,233, +100, 36,112,160,236, 69,253,161,206,168,166,129,175,141,110, 43, 80, 7, 76, 7, 24,168,160,161,246, 79,169,137,166, 98,111, 13, +141,114, 7, 57,202,144,133, 72, 82, 84,159,160, 80, 58,135, 44,133,133, 75,139,207,215, 58,103, 78,157, 91,123,249,230,232,145, +153,219, 55,111,221,127,176, 18, 37,122, 72,240,119,146,232, 56, 46,190,124,219,124,252,180,243,226,213,250,177,233,227, 75, 75, +215,103,103,102, 63,126,238,110,253, 12, 77,142, 57,217, 62,209,106,250,111,223,125, 48,221,235,133,243, 23, 31, 62,122, 50,215, +158,115,189,198,202,234, 51,207,243,239,221,185,123,121, 97,113,249,198,242,213, 43,215, 58,175,215, 55, 62,117, 99,164,185,245, + 96, 88,132,131, 81, 63,206,195, 40,235, 69, 89, 28,235,104, 32, 76,226,163, 97,239, 66,161,122, 71, 96,253,174, 88,126, 33,211, + 20,189, 36,211, 97,218,239, 39,204,121,228, 5,112,124, 55,125,137,105,137, 56, 6, 9,107,173,137,123,145, 23,158, 39,125,192, +148,139, 43, 22,147, 34,181,168, 35,107, 26, 3,123, 96,220,187,186, 5,192, 63,120, 24,152, 6,201, 87, 40, 52, 45,254, 32, 99, +147,182,164,218,103,226,117,249,157,138, 19,178,251,202, 17, 74,239, 28, 62, 84, 38,253, 57, 62,167, 1,167, 6, 87,106,198,106, +106,193,157,153,168,211,211,103,195, 36, 36, 85, 50,252,174,181,217,179,111,209,130,133, 75,246,102,210, 12,197,102, 60,193,193, + 94,133,176,227, 66,114,140,163,131,200, 80, 84, 83, 84,100,175,198,145, 51,105,106, 9,130, 76,235,131,181, 99,140,190,244, 79, +176,131, 72,162, 12,238,154,109, 92,199,197, 59,115,164, 44,155, 33,127, 23,250, 84, 82,178,161,170, 72, 91, 23, 37,201, 59,207, +166, 63, 85,237, 60, 46,225,201,169,130,207,112, 32,196,134, 76, 4, 80, 21,236,184,192, 7, 59, 88,239, 73,182,127,180,209,175, +178,198,192,204, 72,218, 45,178,248,165,103,110,125, 98, 43, 66,186,164, 13,208,241, 49, 75,182,195, 45, 83,156,103, 56,237,154, +196, 73,108,174,193,231, 24,144, 78, 0,143, 63,176,167, 57,136, 98,172,220, 37,122, 8, 0,106,138, 67, 91,120, 34, 30, 65, 1, + 7, 64,138, 90,142, 47,234,179, 96,248,134, 83, 89, 2,177,206,255, 80,112, 56,206, 98,201,112,116,137,229,152,158,121, 42, 56, + 56, 72,195,186,207,133,222,109,178, 15,106,131, 78,255, 31,220,205,227,151, 0,140, 93, 77,107,219, 64, 16, 93,105,245,229,164, +200,141,237,134, 52,224,131,161,105, 15,129, 66,161,231,228,247,245,143,244, 90,122,204,161,208,246, 15,180, 7,211, 52,165, 52, +184, 80,108,234,196,177,101, 59,145,165, 93, 77,119,102, 86,178, 76,113, 8, 24,131,177, 17, 50, 59,122, 51, 59,243,222, 91,239, +225,244,100,168,249,253, 18,249,201,228,112,223, 3, 89,208, 6, 80, 82,221, 97,162, 65,177,179,150, 0,133, 58, 26,199, 51, 56, +108,221, 53,109,212, 86, 22,166,236,226,153,153, 23,183,219, 11,147, 0,139, 78, 20, 95,230, 9,170,203,178, 21,109,139, 53,119, +231,136,203,129,151, 53, 37,185, 47,101,114, 59, 3, 94, 29,151, 57,215,248,166, 10,182, 22, 80, 38,158,210, 34,253,250,251, 11, +153, 36,250, 20,148,165,255, 12,166,107,162,132,149,141,120,143, 5,213,166, 52,199, 82,148, 35,222,109,132,110,239, 73,239,124, +120, 33, 80, 8,234,229, 58, 71,105,173, 35, 7,114,164,208,150,215,199, 84,128, 70,122,144, 43, 39,172, 90,248, 18, 27,151,137, +129, 85,101,254,154,179, 84, 58, 8,208, 2,211, 96, 70, 28,183,250,253,159, 71,207,142, 95, 28, 29,159,125,250, 60, 24,188,153, +204,151,141, 32, 48,183, 27, 72, 47,108,132,157,246,227,253, 78,187,219,237, 30, 30, 62,109,181,247,154,241,222,233, 73,207,164, +138,183,239,222, 39,139,244,199,175, 63,175, 95,189, 76,110,179,244,114,152,165,217, 65,167,211, 63,255,246,188,215,139,194,224, +236,195, 71, 3, 9, 87,147,235,241,120,114,147,204,254, 94, 79, 87, 52, 30, 13,148, 14,125,159,249, 62,244, 36,163, 87, 15, 89, +210, 35,124, 57, 68,100,191,203,112,215,202,167, 27, 24, 16,204,242, 98,149,235,200,108,201, 4, 87, 81, 56,209, 32, 29, 25,160, + 98, 88, 79,235, 17, 2,107, 97,169,200,236,228,199,249, 95, 90, 93,216, 1,251, 86, 2, 56, 21,191,174,190,151, 75, 25,135,241, +124, 83,242,154,235,212, 36, 81, 87,108,136,220, 96, 67, 40,132, 31,231,171,105,245, 56, 85,150,138, 6,104, 52, 25,144,161,222, + 24, 45,228,214,230,151,200,199,214,153, 92, 59, 46, 84,196, 24,235, 22, 91,114,130,109, 19,246, 98,244, 93, 96, 21,239,214,196, +180, 80, 3,231,130,190,245, 12, 94, 84, 96, 14,214,164,206,150,227,101,147, 7, 24,236, 66, 63,210, 42,231,211, 2,106,232, 14, +229, 1, 34,246,202,174,189, 67,219,108,100, 32,167, 99, 12,182,239,136,220,154,180,137,181, 31, 40, 33,183,115, 93, 62,216,131, +183,214,101, 86, 0, 11,193,232,226, 2,192, 63,224,130,157,244,136,194,230, 33,160,233,166,176, 67, 87, 11,238, 46, 91,143, 88, + 6,142,244, 60,182,231,195,122,169,156,100,210, 36,141,174, 41,133,168, 60, 49, 16,211, 93,129, 39, 23, 72,243, 36, 59,212,165, + 1, 75,147, 91,235, 35, 72,182,129,154, 63,133,101,226,126,235, 32,242,119, 6, 87,131, 69,190, 36,238, 50, 52,119, 91,227,217, +136, 59,186,172, 71, 68,229,146, 37,189, 67, 25,192,216, 2,128, 50,227, 83,154, 33, 69,156,128,157,240, 81,220,104,142,110,134, + 32, 54,172,175, 37,178,127,170,197, 37,139,169, 90,129,143,220, 51,157,146,191,165, 93,134, 93,244,137,156,102, 58,189, 91,172, + 28,203, 38,217, 74,159,175,203, 53,138, 7,131,251,253, 66,167,127, 2, 80,118, 45,189, 77, 3, 65,216,187,118,188,137,107, 5, + 81,170,208, 64,211, 3, 72,181, 84, 42, 46,156, 56, 32,224,192, 21, 33,206, 92, 56,240,131, 56, 34,126, 10, 23, 84, 80, 69,139, +168,212, 8,164,190,120, 68,132,180, 10, 52, 10,113,212,248,189,236,204,238,218, 78, 83, 33,240, 37,135, 56,113, 28,239, 60,246, +155,111,190,249, 71,125, 96, 62,219,205, 33,214, 6,176, 79, 32, 32,227, 3,131, 62,120, 19, 8, 48, 8,165, 96,191, 31,225,202, +153, 75,196,157,230,197, 55, 50, 69, 56,130,241, 23, 33,136,132,113,216,208,145,170,240,146,203, 11,173,131,222, 94, 10,155,160, + 84, 66,239,138, 66, 11, 77,246,147, 40, 33, 8,167, 26,146, 19,169, 43,255,224,203,189, 69,111,183,183,187,186,188,114,216, 59, +144,148,152,162,108,166, 2,140,121,125,241, 90,247,164, 75,185, 76,103, 32,252,152, 90, 89,193, 91,242,142, 6,199,126, 48,138, +210,116,255,232, 16,182,165, 38,194,253,212,176,137, 57, 72,198,190, 27,211,136, 9,223,112, 42,238,112,146, 50,208, 57,205, 18, + 70,145,226, 5, 55,239,216,150,120,125,246,244,137, 83,115,159,191,120, 25, 10,247,111,208,249, 11,117,241,254,201,112,184,185, +249,225,193,189,187,175, 94,175, 55,154, 87, 46, 46, 52,222,111,183, 47,213,221,251,119,110, 63,126,244,112,245,230, 90,191,223, +127,183,241,118,167,221,254,252,181, 51, 26,251,147, 32, 14, 97,160, 17,175, 86,172,222,113,215,173,221,106,204,187, 43,158,215, +106, 93,109, 54, 47,239,124,252,212,249,222,153,115, 25,163,116,125,227, 77, 28, 39, 98,169, 70, 25,113, 88,165, 38,153, 12,104, +100, 85,145,142, 90, 96,139, 9,120, 67,130,100,130,244, 84,252, 42, 78,132,203, 22, 22, 36,242,119,113, 50,179,137,109, 26, 78, +133,212,107, 44, 77,172,111, 58,149, 66, 45, 85,212,224, 83,198, 55,117,136, 75,133,113, 32,243, 56,126,182,249,166, 88,192, 12, + 38,233, 4,180, 8,237,179, 11,180,248,236,185,142,126, 20,142,102, 61, 21,201,157, 85, 33,152,197,115,111,206, 11, 25, 0,163, +236, 16, 25,160,213,208,105,134, 69,100, 64,105, 44,106,195,182, 29, 24,189,188,164, 56, 87,160, 40,194,103,205,129,166,194,111, +172, 36,113, 29, 39, 64, 58, 81,126,119,142, 5, 17,213,156,194, 75, 19,157,204, 76, 50,110,116, 27, 41, 45,153, 36, 41,245, 31, +201, 11,167, 73, 40,231, 27,148,147,119, 9, 16,107,188, 69,209, 60, 36, 22,147, 3, 55, 34,254,146,252, 46,255,230, 9, 10, 65, + 49, 42,213,124, 21, 35, 89,115,108,168, 22,123,151, 10,186,216, 19, 72,115, 16,153,170, 81, 0,152,199,171,214,110, 85,152,229, +134, 82, 41, 80, 44, 73, 67,213, 90, 41,238,152,117,229,139,226,189,164, 96,183,152,148,101,114,179, 79, 80,146, 87,156,137, 67, +108,160,165, 47,145, 61,226, 78,165,122, 99,105,109,235,203,150,170, 1,102, 26,196,224, 50,150, 2,124,251,227, 87,151, 34,119, + 31, 23, 44,204,120, 26,248, 63,213, 32, 48,165, 48,156,225, 5,117,227,174,210,203,227, 82,128,143, 43,214, 47,186, 19,132,126, +163, 40, 26,102, 67, 29, 27,212, 96, 34,249, 76,205,243, 92,174,102,181,146,113,224, 79,177, 6,146,144,168,167, 4,255,100, 54, +101, 1,133,201,156,217,227,102,255,153,185,139, 37,157,150, 6,159,149,143, 63, 2,112,118,117,171, 77, 4, 81,120,103,103,118, +118,147,221,108, 18, 98, 66,105, 45,161,248, 2,222,249,131, 69,172, 90,240, 77,196, 11, 95, 76,193, 23, 80, 43, 4, 9, 85,193, +130, 87,162, 23, 69,154, 43,173,166,173,155,108,118,118,186,206, 57, 51,179,187, 77,131,130,144,155, 36, 4,102, 55, 59,231,204, + 57,223,207, 89,246, 23, 35, 53,159, 57,183, 68,232, 45,200,106, 19, 59,146, 59,144,135, 26,177,182,198,128, 57,112, 37, 25,179, +167,100, 3, 46, 23,174,145,255, 59, 38,127, 99, 21,227,106, 45,146, 74,240,156,114,143,242, 6,227,109, 30,198,126,131, 51, 46, + 28, 49, 57, 59,154,254, 62, 1, 76, 12, 73,130,187,215, 31,125,153,124, 6,148, 18,243, 46,246, 13,100,224,135,152, 99,164, 17, + 75,163,158, 77,227,128,112,220, 22,234,140,187, 64,177, 28,192,164,120, 78, 40, 24, 54,214,213,106, 78, 65,103, 15,111,169, 97, +245,146,107,131,173, 52, 75,213,159, 57, 77,126,105,155, 33,170, 57,182,180, 54, 96,170,112,222, 45,142,124,198, 85, 6,207, 97, + 82,142, 42, 94,220,128,187,234, 3, 85,123, 54, 3,226, 49,120, 96,133,112,178, 76, 62,121,252,244,214,246,206,243,103, 47, 22, + 89,166,114,221,214,112,115,243,234,198,222,104,172,150,176,251,224,254,203,189,183,247,238,108,175,175,111,188, 30,141,213, 53, +125, 61,252, 54,222,223, 63,248,240,241,248,251,143, 56,110,245, 7, 93,143,131,147,193,108,158, 48, 42,163, 22, 48, 94, 10,153, + 63,220,185,123,251,198,205,181,254,218,171, 55,163,247, 7,159,210, 76,204,210, 25,238, 71,208,187, 94,233,120,221,142, 31,135, + 36,106,242,200, 7,200, 20, 50, 86, 1,238, 99, 30, 18, 32, 60,199,104,101, 1, 34,134, 77, 5,119, 69,100, 57,205, 11,149, 15, + 6,172,209, 15, 84,104, 39, 29,135, 30, 78, 78,143,207,230,218, 20,254, 92,139,205,176,170, 13,253, 16, 49,201,186, 65, 17,216, +251,168, 27, 36, 87,123,138,153,103, 73,187,251,114, 55,192, 99, 84,177, 82,171,125,217,250,150,252,155,177, 78,150,152,136, 75, +191,139,252, 88, 74, 17, 5,177,200,133,222,159, 88, 86,230,214, 51, 71, 45,158, 65,197, 9, 12, 31,105, 64,127,211, 51, 37,164, +226,159,192,138, 5,202, 89, 47,202,182,151,229,136, 37, 27, 88, 19,246, 83,144, 23,145,203,100,245, 11, 21, 6,169,134,192,105, + 94,200,185,189, 44, 90, 87, 36,145,106, 16,140, 14,238,212, 50,151, 43,122, 76,245, 34,127,125, 57,214, 12,134, 24,134,130, 54, +144, 49, 46,237, 6,140,210, 35, 59,176,204,165,214,183, 0,172,167, 93,107,192,106, 76, 6,203,150,189,117,145,196,182, 59,186, +133, 17,102,130, 59, 1,111, 88,170, 49, 85, 23, 77, 84,113,111,245,162,110,220,108, 37,139,164,156, 28, 85,169, 25, 52, 37,222, +209, 39,196,252,103,114,130,129,146, 88,235, 94,139, 96, 18,167, 50,142, 69,173,147, 30,208, 84, 24,202, 23, 60, 24, 72,178,150, +195,222,112, 58,155,218, 64,174,107, 17, 27, 85,173,141,108,169,136,212, 83,252, 84,220,136,195,118, 38, 68,165,140,116,200,170, +238, 70,153,139,109,141, 69, 72,141, 77, 44, 75,233, 72,167,209, 75,243,249,242, 44, 4,104, 6, 74,219,243, 36,255, 7, 71,153, + 80,185,234,171, 63, 2, 80,118, 45,171, 81, 4, 81,180,170,159,211,227, 56, 17, 19, 4,193, 85,220,135,184, 51,248, 7, 46, 92, +104, 16,252, 38,151,226, 95, 24,193, 69, 68, 5, 21,201,194, 7,130, 95,160, 98, 2, 6, 51,100, 38, 51,233,247,212,195,123,111, + 85,117,247,140, 67,192,129,204, 98, 8, 77,119, 87,213,189,183, 78,221,115,206, 69,245,123,211,185,156, 68,125,228,149, 97,207, +140,121, 62,244,120,211,156, 72,228, 92,245,130, 94,141,242,251, 50, 64,214,101,200, 76, 39, 19, 87,177,230,146, 91,135, 55, 82, +145,108,140,202, 52,185,189,248,190, 59,191,135, 49, 56, 23, 98,168,216, 26,130,146, 33, 29,159,248,189,184, 63, 43,103, 80, 99, +190,249,246, 74,186, 86,119,147,219,112, 0, 8, 92, 83,204,242, 29, 40, 96, 97, 90,153,100,167,112,131, 85,141,172, 78,211,213, + 26,248,225,195, 59,247,159, 29,236, 89,200,213, 51,199, 62,116,226, 68,211, 17,254,235,112,116,136, 70, 25,200,222,176, 91,108, +244,172, 99, 60,135,241,224,116,104,172,249,177,156,170,152, 65, 45, 28, 39, 1,204, 92, 73,177, 18,133,117,124, 75,228, 69, 84, + 39,193,132, 86,100,236,201,211,199, 87,175,108,164,217, 36,140,144,208,113,253,218,250,244,108, 2,177,102,123,107,235,231,175, +163,172, 72,159,239,191,124,112,239,238,160,159,192, 99,213,115,121,244,123,244,231,248,228,195,199, 79,235,107,151,111,110,222, +216,217,185,189,187,251, 40,157, 78,223,189,127,253,246,224,179, 16,117, 94,229,123, 47,246, 39,179, 20, 74,251,170,154,147,251, + 9, 34,251,204,195,215, 14,111, 44,205, 84,224, 41,200, 71, 81, 72,180, 50, 5,241, 20,242, 45,148,216, 72,254, 64,131, 20,205, + 98, 43,208,236, 13,195,160, 15,139, 80,179, 60, 42, 34,197, 82, 49,255,113, 50,206,132, 56, 43, 74, 46,227, 82,100, 24, 7,133, +217, 47,155,178, 7,255,228, 2,113,149, 14, 24, 17,232,137,186, 8,248, 63,173,238, 13,112,169,107, 85,118,195,226,146,124,182, +190,176,159,125,213,134,180, 75,175,230, 16,202,139, 42, 51,199,185, 13,213,200,168,152, 57,157,103, 18, 14, 98, 60,137, 33,166, +164,156, 66,136,115, 41,105,141,119, 97, 16, 7,209, 48, 69, 84,199,146, 29,188,133,208,220, 86,220, 11,123, 20,250,186, 20, 38, + 37, 65, 43,112,225, 73, 62,110,183,241,109,153,230,117, 35, 2, 93, 11,179,201,246,230,173,175,223,191,248, 84,203, 82,228, 82, + 29,222,128, 65, 50, 32, 26,110,140,211,145,143,190, 94,132,220,107,231, 9,105,226, 14,169, 2,172, 94,192, 40,147,235, 30,206, + 21,142, 14, 47,214,142,164,234,130,181,117,107,181, 24,141,223, 21, 14,212,214,232,192, 0, 28, 30,107, 29, 8, 77, 87,139,161, +178,211,158, 88, 27,243,100,179,214,124, 99,216,100, 22, 93, 59,104, 80,193, 8, 70, 91,118, 2, 90, 49, 48,227, 57,174, 50,221, + 18,120, 41, 73, 80, 41,100,222,106,158, 99,173, 38, 89,163, 4,169,145,172,171, 8, 87, 52,205,158,218,147,156,222, 50,169,246, + 40,221,248, 51,155, 28, 6, 63,196, 1,186,202, 12,130,126, 41, 42, 33,107,109, 77, 56,141,220, 14, 44,114, 88, 70,202, 28,178, + 18,251, 16,123,222, 32,247, 80, 85,201, 27,136,199,129, 16,202,193, 18,109,202,134,219, 30,192,212, 42,207, 57,119,121,200, 77, +126,186, 11, 53, 45, 78,181,213, 94,197,185, 23,144, 60,223, 74,145,165, 37, 9,154,255,114,169, 92,250,252, 21,128,177,235,123, +141, 26, 8,194,151, 77,246, 46,201,209, 22, 90,139,160, 15, 22, 69,193, 39,139,160,255,115,169,248, 92,124,247, 77, 4,197, 7, +235, 67,241, 55, 74,185,122,181,119, 73,246, 54,217,117,190,153,221, 92,170, 82,125,190, 64,114,179,187,179, 51,223,204,124,223, +191,241, 25,250, 20,211, 54, 44, 80, 1, 57, 31,153,155,111, 81,137, 2, 98, 56,183, 63,110, 20, 55, 41, 94,172,186,149,226,124, +158,188, 6,166, 88,189,240, 42,208,117, 13,227, 48,107,190,204, 95, 8, 63, 69, 76,228,188, 52,171,100,172,121,141, 64, 96, 97, + 43, 6, 93,236, 86,190,125,222,204, 83, 24,184,211,216,214, 62, 82,181,224,160, 54, 8, 36, 61,183,208, 58,110,130, 15, 88,100, + 40,184, 70,158, 36, 90,150,182, 53, 79,158, 63, 5,206,198,251,134, 43, 84,120,172,208, 19,211, 26,188, 59,214,122,105,217,192, +183, 14,131,118,219,229,150,206, 38, 31,103,159,248,244,160, 51,236, 76, 47,174,141,243, 50,215,211, 92,103, 25,184, 24, 41, 49, +208,217, 72,107, 47,245, 41,225,253, 67,176,171,244,203,215,199,173, 61, 54, 93,146,144, 51,182,102,186,185,251,254,243,233, 88, +231,143,246, 31, 30, 28, 30,242,108,150,187,187,183,119,125,103,163,237, 44,157, 0,203,121, 33, 69,218,247,238,223,121,252, 96, +127,179, 44,158, 29, 29,189,125,119,242,245,219,151,101, 93, 43,214,169,121,241,234,141,181,109,150,166,197, 68, 67, 37,213, 98, +238,131, 76, 81,209, 85,202,227,114, 20, 52, 21, 57,188, 4,217,100, 50, 65,152,230,148, 3,123,240, 8,224,210,180,164,152, 62, +233, 26, 80,155,205,150,230,251,217,124,105,237, 69,229, 26,186,118,188, 9,250,103,112,213, 85,208, 85, 96,224, 24, 82, 24,152, + 19,134,121,107, 90,154, 65,189, 81, 78,142,244,173,171, 63,246, 92, 57,222, 88,172,126,114,215, 65,146, 68, 17,156,225,164,254, + 80,199, 67, 14,109,138, 57, 14,215, 7,248, 9, 99, 41, 44,219,228,175,216,210,225, 74,134,104, 91,198,190, 53, 22, 24,249,130, +119,190, 53,182, 9, 7, 16, 81,164, 94, 81, 98, 23, 17, 24, 31,103, 41,215,194,116,222, 93, 48, 14,211, 67, 64,228, 23, 90,168, +151,251, 64, 35,147, 36, 67, 97,247, 8,100,224, 2,171,108,205,109,145, 89,231,251, 94,140, 32, 77,126,107,247,246,135,211,147, +100,224, 17, 2, 87, 6, 78,188, 51,166, 81,125, 31, 49,153,244, 50,135,107,111,183, 92, 23, 20, 78,166, 89,112,191,209,179, 43, +102,114,249,219,124,192, 80, 85, 79, 94, 38,121,146,138,196, 97, 62, 82, 62,138,196, 78, 36,159, 81,129,121,131,211,108,134,168, +133,246, 79, 78,172, 31, 14, 79,201, 5, 21, 47, 3,201, 66, 36,128, 85,253,172,147,168, 42,135,161,168,128, 65,171,212,215,171, +138, 22, 27,230, 2,135, 41,144, 25,153, 95, 79,217,197, 83,116, 65,207, 3,179,101, 68, 7, 96, 12,144, 84, 21,255,166, 19,137, + 62,104,140,185,223,114,184, 88, 56,149, 41, 89,133, 36,127,190,152,113, 83,255,168, 94,213,163,193, 82, 6,254,119, 60,205,155, +220,197, 72, 29,106,157,204, 69,194,197, 7,254, 89, 34, 75, 54,218,165, 6,215,248, 66,168, 41,184,117,199, 96,178,206, 84,251, +116, 51,131,227,198, 20,185, 48, 27,114, 19,142, 29, 6, 55,189, 10, 96,122,165,139,255,127, 89,227, 95, 2, 16,118,197,202, 77, +196, 64, 84, 90, 73,119,246, 5, 19,219, 9, 73,138, 80, 65, 3, 13, 5, 13, 5,191, 64,199,167, 82,241, 7, 12, 5, 20, 12,198, +164, 0, 2,147,194,198, 78,198, 57,251,206,178,116,135,118, 87,119, 99, 7, 18,202,140, 39,231,243, 72, 90,237,190,125,251,158, +190, 13,169,147, 60,221,220,190, 40, 65,154, 28, 94, 37,151,149, 20,174,173,176,211,245,228,180,123,138,230, 71,174,178, 72,203, + 7, 28,169,169, 96, 29, 98, 61, 73,169, 80, 27, 20,171,175,184, 3,120,136, 20,243,119,236,167,107,161, 83,208, 93,204, 38, 97, + 17, 18, 85,183, 12,155, 1,133,247,104,204,149,218, 45,124,191,215, 68, 21, 86, 72,200, 99,170,111,132,209,226, 41,163,120,196, + 77,159,104,190,203, 27,113, 63, 27, 24,165,151, 54, 39,153, 51,100,218,135, 7, 39,160,143,251, 71, 87,249,229,227,147, 71, 95, + 47,198, 6,244,211,135, 79, 70,231, 35, 20,236, 55, 38, 84, 42,211,235, 89, 20,141,164,164,230,123, 57,145, 15,252,208,164,137, + 22,209,165, 6,176, 33, 25,158,185,182,168,104,145, 40,225,100,229, 54, 2, 85, 7, 80,189, 75,209,108, 70, 88,113,155, 25, 56, + 26, 14,206,206,198, 47,158, 63, 59, 56,188,119,114,156,189,126,245,210, 59,248, 50,254,100,157,203, 5, 5,100,186,116,202,124, +245,230,221,251,183, 31, 63,132, 50, 96,113, 93,218,194,247,187,157, 94,150,246, 58, 98,176,167,209,188,187,210,225, 54, 67, 12, + 29,229,215,192,134,192,227, 42, 69, 43, 99, 80,126, 18,151, 96,131,227,181,117, 87,195,253,142,201,180,194, 43,204,131,119,234, + 98,178, 88,148,110,182, 44, 11,114, 40,198,218,138,240, 64,218,148, 21,219,122, 84, 88, 17, 36,236, 98,140, 87,157,108,143,130, +144,187,208,199, 45, 34, 71, 49, 78, 90,225,211,202,111, 68,157, 54, 10,209,219,194, 6, 8, 91, 3,118,227,111,216,115,243,204, +136,107,202,188,240,103,225, 87,127,127, 79,180,218,161,243,198, 70, 49, 97, 33, 86, 54, 15, 47,156,153,222,138,252,249, 90,145, +166,109,246,113,216, 30,228, 56, 46,104,192,194,239, 62, 55,172, 96, 74,232, 19, 39,169,117, 40,251,156,119, 52,194,170, 29,194, + 59, 60,107,129,199,178,155,116, 14,122,135, 63,103,231,195,189,225,124, 57, 39,170,168,193,136, 36, 9,198, 71,141, 34,104,131, + 41, 19,191,126, 76,191,193,150, 82,124, 43, 4, 73,233,137, 28,253,250, 12, 60,223, 93, 87,255, 22,110,147,114,158,255,134,232, + 93,204,188,151, 58,146, 88, 36,235, 48,192,127, 37,219,136,205,110, 66,186, 67, 89, 51,254, 70, 5,205, 57,194,102, 38,203,116, +203,150,138,198,221, 53, 65,118,143,130, 60, 96,162,201, 25, 15,141, 75,250,136,133, 95, 69,163, 25, 41,183,133,104,226,192,160, + 38, 56, 94, 51,101, 94,182,192, 69,248,231,196,211,188, 17,115,120,194, 49,223, 79,251,151,197, 60,210,214, 36,118,173, 17, 28, +164, 40, 12,141, 3,106,180,190,107,178, 99, 69,252,109,127, 67,168,133,107,179,154,242,123,130, 82,203, 77, 25,245,200, 41,168, + 40,178,220, 70,152,142,163, 71,133, 32, 4,168, 36, 95, 47, 98,208,199, 69, 13, 25, 79,236,210,135,115,130,224,164,219,224, 4, +169, 20,187, 24, 35,198,116,126,159,194,150,219, 8, 92,132,246, 91,114,121,212,186, 9, 47,135, 72, 46,245,126,100, 91, 87, 53, +159,138,214,182,247,238, 16,111,192,240, 44,197,221,214,196,127, 4,224,235, 74,122,155, 6,162,176,103, 28,123, 28,103, 79, 42, +165, 85, 5, 92, 57,113, 66,226,208, 27,255,132, 11, 63, 22,137, 43, 2, 21, 42, 36, 10,136, 37,148,218, 73, 92, 59, 51, 25,230, +123,111,188, 36, 80,164, 40,135,200,138,101,121,230,205, 91,190, 5,253,119, 75, 39,115,103, 34,212,200,231, 52,123, 67,138,142, +166, 78,221,169,100, 24,121,168,173, 75,111,170, 69, 50,231, 60,152,184, 68,240,221,230, 6, 30,159, 15,188, 58, 56,101,135,141, + 51,102,177, 80,122, 87, 50,142, 35,149, 70,233, 32, 74, 37,197,222, 47,155,207,119,166,112, 59, 54, 43, 50,205,210,160, 65,237, +219, 18,216, 65, 50,112, 17,204,214,202,118, 30, 79, 79,105, 3, 83, 97, 3, 54,169,174,109, 33,209, 26, 54,144, 31,226, 81,254, + 52,157,132, 48,219, 16,238,213,110,139,141,197,247,214, 66, 92, 72,220,184, 19, 30, 13,122,123, 58, 59,211, 32,193, 26,166,112, +243,189,220,227,228,225, 70,187,152,104, 66,184, 81,151,129, 49, 1, 33, 99,128, 46,175, 74,228,184, 46,154,199, 49,220, 73,148, + 10, 35, 21,168, 88, 66,177, 32,145, 46, 64, 63,123,250,228,205,187,183, 15,207,207,151,203,211,201,104, 58,159,159,204, 39, 48, +153,188,188,250, 8,230, 29,102,210,160,114, 97,161,239, 69,182,134,173,240, 32,141,163,126,146,105,243, 99,189,189,190,217,172, +242,114, 93,237,116,137, 92, 71,146,232, 58,172,104,201,188, 10, 25,150, 11, 79, 66,244, 3, 57,148, 98, 22,169,101,156,246,118, + 50,207,108,126, 27,189,255,126,123,249,181,248,176,250,253,107, 91,229, 40, 58,184,193,198,196, 96, 75,136,154, 61,243,251, 48, +202, 54, 1,156, 81, 1, 39,115,165, 73,226,206, 57, 13,175,112, 47,163,250,255, 74, 17,111, 71,141,119, 70,243,224,232,197,243, +151,175,175, 94, 13,195,145,182, 85, 23, 33, 96,235,112,115,116, 38, 12,213,152, 88, 69, 94,164, 44, 18,145,245, 35,122,113, 72, +154,181, 42,236, 3,247, 2,211, 71,247,138, 34,225, 29,207,113, 83,221,168,125, 81, 41,213,104, 99,176,178, 8, 9, 34,145, 99, +243, 63, 12,119,164,219,225,154,236, 24, 17,248, 92,236, 9,123,132,122,180,227,100, 90,236,214,108,149,235,178,186,126,156,186, +101,254, 51,255, 70,160,198, 59,222, 27,184,216,119,206, 5,117, 87,172,173,107,244, 7,179, 71,174,102,151, 7, 36, 82, 97, 91, +206,107, 11, 63,175,139,140,150,254,221,250,212, 55, 97,215, 59,111, 0, 69, 58,234,143,220,130,240, 2,141,247,136,221, 52, 0, +201,144,230, 84,170, 23,153,189, 38, 15, 94, 98,245, 51,228, 11,149, 31,214,126,204, 30,200, 20,139,123,100, 32, 67,155, 84,178, +164, 7, 77,171, 2, 47, 58,128,107, 16,247, 37,107, 61, 5,222,180,137,250,236,228,251,225, 45,103, 66,130, 72,146, 37, 31, 11, + 65,201,144,135, 91,190,245,199,187,219,211, 72,197,201,100,158, 21, 57,141, 35, 8,138,234, 37,219,240, 16,181,128,220,222,183, +222,168, 12, 32, 68, 11, 70,100,230, 80, 22,201,221,119, 49, 92,108,202,181,251,151,139,199, 23,159, 86,215, 36, 96,204,197,215, +190, 33,166,134,158,193,137,159, 33,245,100,170, 84,165, 24, 83, 55, 56, 29,201,131, 0,164,149,163,100,234,162,127,109, 76,220, + 49,247, 12,196,114,114,182, 45,215,173,142,207,193, 52,179,213, 13,106, 82, 13, 22,131, 59,226, 61,137, 99,243, 63,241, 55, 83, +164,251, 73,100,108, 58,166,149,247, 77,173,254, 8,192,215,149,237,182, 13, 3, 65, 81,164, 68,209, 87,108, 35, 72, 31,154,160, +232,255,127, 74,251, 9, 5, 90,160, 15, 65,130, 88, 64, 98, 89,146,117,144,221,157,149, 4,169, 73,251,108,152,150,104, 30,179, +179,187, 51,236,239, 65, 51,182,207,142, 20,150, 98,207,196,243,212,216,172, 57,101,202, 66, 72,167,131, 2, 78, 87,108, 54, 23, +160, 63, 99,178,251,245, 61, 20,187, 90,214,210, 15, 56,123, 20,119,200,192,134, 35,128, 76,136, 32,173,133,181, 22,107,171, 33, +136,171,237, 46,219,238,179,157, 99,243,114,255,253,249, 91, 31,117, 13, 99,223,150,251, 80,192,102,130, 9,238,167,208, 66, 14, +238,201,138, 0, 66, 25, 72,221, 4, 35,194, 70, 52,122, 50,184, 85, 67,151, 7,185, 29,186, 69,104, 16,250,244,224,110,234,166, +228,180, 15,133,235,113, 10,137, 81,205,235, 30,133, 77,154,207,216, 0,114,153,155,154,123, 52, 80,211, 95,124,218, 62,215,235, + 38, 86,137, 51,166,238,130, 77,232, 43, 1, 8,154,121, 18, 73, 52,100,150,128,161, 79, 52,178, 87,220,158,203,218, 71, 52, 13, + 15,159,239, 30,159,114,186, 6,234,206, 75,198,134, 32,178,209,198, 57,155,151,158, 32,127,141,163,244,202,234, 95,234,181,106, +104, 78,157, 77,173, 53,150,194, 87,227,223,202,182,174, 26,130,237, 92,171,168,149, 99, 85, 20,191,129,214,188,243,241, 46,177, + 95,182,236, 61,255,214,134,210,247,167,170, 57, 87, 28, 66, 76, 14,170, 49, 92, 12, 83,229, 46, 93, 49, 72,249,120,154, 41, 87, +117,165,135,235, 1, 27, 13,178, 24,113, 4, 3,132,136, 61, 40, 33, 71, 12,173,189, 0,172, 35,135, 14,119, 59,109,237,205,165, + 57, 47, 15,232,192,188, 48, 69,211,126,112, 34,109,163, 94, 51, 18,247,233, 76,134, 72, 22,148,209,182,165,251,123,228,102,166, +213,245,112,252,250, 59,255, 53, 14,232, 93,178,169,219,203,191,106,231,253, 71,160,134,176, 66,235,175,209,232,167,184, 74,215, +244,170,117, 87,202, 37, 77,129, 19, 65, 96,204,200,251, 42,158, 32, 10, 1, 97,116, 18,102,125, 96,223,196,147,253,108, 52,184, + 4,208, 91,163,238,222,150,215,203, 82,240,107,112,251,146, 7, 75,217, 22,202,183, 3,171, 51,203,225,141,143,141,149,182,248, +125,186,204, 93,234,138,234,117,170,140,156,239, 59, 89,237, 96, 54,195,104, 79,175,208,185,180,176,139,255,219,165,123,218,182, + 99,117,142,160,107,141,100,170,244, 3, 42, 61, 35, 82, 4, 21, 65,126, 30,140,185, 52,153,163,148, 24, 5, 32, 82,113, 6, 7, +234, 33, 43, 49,216, 36, 4,116,145,240, 9, 46,231, 56,118,156, 82, 41, 95, 22,210,179, 42,238,241,241,160, 33,204,149, 75,254, +110,255,201, 24,253,227,233, 39, 88,205,174, 97,148,193,138, 32,157,239, 15,187,227, 75,145,215,205,181, 11, 98,173,205,208,163, +159, 90,216, 65,214, 51,171, 46,212, 76, 28,230,202, 13,129,179, 98,122,101, 55,249,229,116, 92,223, 82, 60, 87, 84, 5,189, 13, +133,110,116, 35,210, 83,228,231, 23,214,146,103, 55, 75, 67, 17,219, 8,177,121, 44, 58,139,152,192, 1,105, 37,213, 99,180,134, + 15,171, 3,171, 22, 42,150,212,150, 0,202,207,114,147,244, 44,230,221, 95, 60,175,129, 9,209, 2,209,140,220,189,132, 5,195, +125, 19, 45,181, 69, 37,117, 16,131,111, 84, 51, 47,145, 15,199,255,127,183,197, 31, 1,248,186,150,221,166,129, 40, 58, 30,219, + 99,135, 64, 43, 17, 64,160,116, 1,252, 8, 63,193,142, 47,236,138,159,224, 31,144, 88, 66,187,104,169, 40,139, 56,118,237, 25, + 15,247,156, 59, 78,236, 20, 85,138,178,176, 18, 59, 25, 95,223,185,175,115, 78,242,239,179,146,157, 93,218, 74,150, 45, 77,237, +208, 33,102,161, 2, 86, 65,230,112,248,213,194, 20,239, 86, 91,151, 21, 32,112,136, 10, 56,214, 74, 46,233, 77,224, 53, 37, 11, +198, 6, 46, 91, 36,184,224,243,122,101, 93,229, 16,188,131,193,185,168,238,186,155, 31,247,223,197, 56, 90, 96, 82, 60,135, 3, + 83, 15, 92,222,215,213,139,246,161, 33, 72,153, 45,124, 29, 6, 72,120, 84, 75, 42, 16,134,212, 76,239,192,211,101, 11, 16,129, +189,249,120,117,251,203,229,217,246,229,197,223,230, 94, 30, 44, 49,193,139,205,118, 93,175,174,239,174,224,223,105,241,242,251, +190,124,250,124,249,237,107, 34, 70,128,205,137, 59,197,172,213,200, 34,205, 88,246,183,175,111,118, 77, 46,201,192, 84,119, 52, +202,108,169,189, 59, 56,205, 2, 90, 27, 6,106,124, 72,110, 93, 9,148, 45, 64, 64,182, 4, 52,130, 65,132, 92,110, 93, 99,189, + 92,105,189,183,191,247,189,100,162,251,193, 55,221,176,107,123, 32, 78, 77, 40, 89, 93,161,132, 48, 44,183,237,122, 50,204, 32, + 87,232,250, 49,175, 74, 38,242,242, 48, 12,178, 91, 20,222,156,163,158,239,222,158,159, 57,238, 45,118, 44,218,208,128,162,147, +163, 97,236,226, 67,228,128, 88,109, 49,199,170, 11, 77, 32,234,209, 27, 21, 47, 54, 12,230,201,230,129,187,165,177, 85,228,192, + 85,194,196,135,228, 37,130, 89,136, 16,165, 65,240,231,245,153,172,135, 68, 76,178,205,239,135,102,138, 36,194, 9, 42,239, 80, + 90, 57, 8, 31,230,198,121, 51,112, 32,221,243,120, 98, 60,151,123,247, 16,218, 37,174,239,255, 25,232,140,236, 40,215, 51, 16, + 81, 82,139,147,105,161, 38,168,127, 33, 30, 35,150, 83,145,156, 68,109,125, 24,144,159,127,216,102,118,113,185,120,108, 30, 60, + 53,236,160,162, 63,148,236, 61,209, 82,210, 30,157, 43, 74,241, 98,217,148, 70, 80, 81, 52, 39,160, 39, 62,226,137,156,196, 49, + 82, 20, 31, 55,207, 94,237,186,102,140, 73, 57,100,193,124,182,116,235, 83,177, 95,171,236,140,203, 98, 76, 2,152, 20,218,200, +141, 86,198, 13,227,235,212, 6, 69, 48, 14,244,185,122,108,100,195, 38,149,223,149,124, 66, 25,178,217, 8, 77, 75,165, 12,142, + 28,168,139, 60, 3, 88,242,224,214, 81, 14,229, 13, 5,190,105,166,184,157, 81, 72, 7,175,140,227,186,100,174, 22, 3,240,180, + 66,137, 14,229,100,157,239,134,209, 67,171,128, 40,101, 50,133,177,176, 8, 45, 27,124,151,179,140, 75,182, 82,173, 45,176,172, + 26, 8,131,116,165,147,171,239,250,189,206, 98,192, 67,227,105,240, 22,136,150, 94,130, 75,144, 78, 99,170, 50,176, 7, 59,234, +254, 45, 71,154,190,213, 0,123,164,124,171, 4,155,218,225,200, 20,225, 54,105, 57,205, 44,240,209,136, 64,170,205,104,202,152, +197,101,210, 26,103,180,123,241, 8,155,152,183, 91, 76, 85, 86, 45,225,132,241,212,251, 39,255,254,126,243,225,250,207,207,240, + 36, 77,253, 63, 1, 8,187,182, 29,167, 97, 32,106,215,118,156, 52, 85, 90, 16,101, 5, 8, 33,158,144,248,255, 31, 97,121, 65, +192, 35,210,238, 66,233,110,155, 52,110, 46,142,119,102,236, 36, 77, 75,133,250, 18,169, 73,147,182,227,241, 92,206,156, 51,209, +231,227, 23,130, 94,158,107, 78, 78,133, 75,130, 20, 11, 11, 83,200, 36,169,138,129,188, 31,117,187,137, 95, 47,213, 42,175, 75, + 99, 27,129, 14, 29, 13,194,203, 62,128,231,154, 57, 50, 43, 71, 59,188,210, 16,233,104,153,164, 81,154,202, 88,176,238,203,246, +214, 52,121,150, 46, 55,135, 77, 99, 43,236, 58,162,140, 13,237,157,131, 56, 13, 31,135,170,103,161, 35, 52,106,251, 98,110,232, +200,178,124, 33,136,243, 88, 68,136,101, 4,155,131, 23, 85,240, 67,112,129,124,186, 92, 99, 16, 79,101,156,182, 91, 36,243, 67, + 85,194,187, 36,214,238, 72,181,167, 93,205, 95,110,203, 71,200, 36,192, 73, 55, 81,113,175,246, 71,204, 77, 72,226,131, 90,252, +204,249, 65,185,192,139, 73, 89,173,212,154,199, 26,247, 30,228,101,236,144,114, 29,190,103,132, 18,226, 16,227,179,133,198,246, + 77, 83,241,253, 65,228, 88,244,193,157, 4,220,169,169,154,202,182,149,181,115, 45, 82,141,244, 30,144,194,128,153,151, 6,245, +197,224,114,120, 38,211,192,102,129,169, 67,139,132,201,158, 2, 27,114,136,218, 84, 85,145, 35,219, 78,170, 52, 92,187,210,201, + 18, 82, 35, 28, 55,227,202,105, 99, 11,170,195, 32,236,136, 59, 9, 89,132,119,223,158,200, 77, 48,105, 58,227, 89,155, 49, 74, +183, 54,213, 89, 89, 23,240,177, 62,122,119, 30,223, 48,113, 85, 65,118, 50, 81, 9, 81,168, 7,187, 23,161, 89, 58,153,175,118, + 87,176,188, 20,248, 43,159,102,178, 19, 94,148, 16, 24,177,208,212,226,189,170, 34, 46, 63,174,106, 87,177, 17,230,141,207, 32, +241,182, 42,137,226,188,218,159,209, 76, 94, 83, 61,237, 49, 45, 51, 54, 98, 64,176,193,126,179,124,251,176,187,203,226, 21, 68, + 3,223,239,190,157, 98,145, 61,189,156,146,186,105,143,108, 40,163,156,172, 12,254, 47,252,242, 57, 41,141, 80, 4, 60,109,134, +194,172,111, 35, 93,251,137,168,253, 57,241,239,152, 95, 58,210,155,236,253, 59,121,223, 25, 81,174,246,237,229, 94,238,131, 10, + 40, 46, 52, 54, 81,129,132, 42,170, 84, 56,197,112, 12, 2, 17,226, 95,148, 28,143, 41,216, 22,148,206, 6,153, 11,143,138, 20, +161,166, 45,108,128,178, 34,114, 5, 12,185,110,143, 1,150,216,245,114,125,140,130,247, 97, 1, 50, 65, 2,122, 1, 34, 25,134, + 97, 89,240,117,176,118, 60, 31, 53,197,230,152, 65,182, 20,188, 55,180,242,240,160,115,239,215, 31,126,222,255,128,219, 81,214, + 59,131, 44, 23, 91,201,104,196,184, 51, 8,210,102,234, 9, 6,209, 76, 23,113, 10, 62, 29,110,247,176,251,195, 17,249,106,215, +233,218,116,199, 93,249,180,152,103,182,174,225, 73,115,179,127,149,173, 55,197,239, 79,111, 62,127,253,117,235,145,220,148,168, +182,239, 94,124,124, 52,127,253, 40,254,182,124,234,201,216, 93, 23,164,189, 71,212,253,217, 8, 18, 31, 60,112,111, 6,112, 62, +228, 16, 82, 70, 24, 83,242,129,171,250, 18, 30, 60,254,245, 39,210, 90,126, 4,130, 13,154,218,238, 66,225,253,191, 24,121,127, +218,179, 0,124, 93, 93,111,211, 64, 16,180,207,190, 56, 78, 82,147, 34, 81, 34,120, 40,188, 35,229,255,255,136,194, 31, 64, 8, + 33, 80,213, 64, 63,104,113,237,179,207,119,236,236,222, 37,142,137,144,170,188, 52,138, 99,103,111,111,118,111,103,102,146,223, +211,127,106,189,116, 50,193, 22, 90,162,209,204, 90, 49, 40,229,253,153, 71, 30, 25, 61, 87,249,217,166,216, 80,222,105, 44, 58, +190, 76, 97, 29, 16, 71,120,112,148,200, 41, 0, 40, 9, 83, 40, 20,133,134,107,180, 70,163, 70,125,123,250,124,243,124, 3,134, + 71, 2,217, 55,100, 48,209,255,247, 66, 44,150,152,139, 98,170,220, 66, 17,215, 0,132,146, 15, 54,190,244,189, 64,128,206, 49, +181, 40,121, 28,110,166, 74,173,202,213,155,234,245,143,251,107,218,133,182,151,219,187,199,219,251, 63,183, 40, 65,164, 16,197, +225, 83, 48,117,100, 42, 16, 40,158, 29,133,155,162, 76,183,170,251, 90,184,184, 40,168,114,215, 86,245,227,204,224,190, 65,153, + 78,165, 25, 69,241, 73,139, 66,110,150,235, 77,199,190, 29,108,226, 1, 1,179, 76,210,211,192,238,165,132, 9, 50,229,202,162, +160,149,215, 66, 29, 99,152, 65,133, 7,137,181,243, 93,107, 29,221,166,246,186, 29, 82, 88, 72,250,196,216,206, 24, 75, 31, 81, +228,136, 70,199,222,241,125, 79, 48,199,211, 30, 69,143,171,239, 58,130, 44,157,197, 95,211,216,223, 77, 95, 27, 12,159,105,229, +171,172, 80, 86,207,210,116, 61, 7,154,145,210,196,178, 58, 56, 55,101, 88,146,204,137,234, 7,122, 55,240,218, 70, 71,141, 42, +104,174, 98,197,131,210, 7, 47, 74, 23,137,127,213,188,170, 77,189,199, 14,233,148,114, 61, 28,219, 16,159,134,184, 2,255,150, + 97, 96,113,188,121,120,102,126,251,245,226,252,221,197,251,143, 95,175,232,167,191, 88,190,250, 89,239, 74,189,100, 80, 19, 50, + 13,109, 15,132, 15,106, 62, 83,141,178,164,255, 23,236,155,142, 30,140,101,188,248,136,126,127, 16,117,192,239,225,192,150, 7, +180,243, 60,167,224,196, 65, 77,226,233,210,173,125, 94, 22, 47,232,121,143, 79, 70, 71,202,192, 62,153, 90,117,203, 40, 59,174, +242,146, 71, 30,211,253,154,158,126, 67, 21,212,150,130,166,159, 58,248,159,122,225, 48, 68, 15,141,112, 23, 62, 90,255,178,191, +158,204,171,123, 86, 9, 16, 11,135, 44,211,236, 74, 12, 76,157, 67, 62,136, 94,129,123, 50,218,117,114,193, 37,204, 94,197,144, +100,137,247,138, 61,142, 74, 98, 5, 64,107,197,176,143, 41, 54,253,129,155,225, 80,228,224, 38, 58,214, 71,150,241,164,128,156, +166,226,243,120,105,102,123,150, 83,156, 36,151,148,105,153, 88,193,117,155,192,115, 39,205, 25, 11,197,175, 1,189, 89,156,111, + 66, 18,146, 46, 71, 0,231,195,229,246,211,151, 43,174,138, 68,193,192,111,214,111,175,239,190, 11, 57, 32, 70, 32,202, 81,169, + 56,170,114,253,100,234,110,104,133,192,196,182,170, 78,235,130, 48, 28,183, 26,193,225,238, 97, 75, 41, 14,149, 88,179,244,212, +206,230, 21, 1,133,221,195,142,240, 88,221,183, 73,152,240,142, 24,231,232,247,117,227, 38,225, 66, 47,204, 96,134, 67, 24,200, +114,193, 32,103, 32, 11,143,129,142, 63, 38,156, 73,247, 51,212,181, 46,137, 92, 13,249,119, 85,158, 63, 52,191,164,251,151,158, +102, 87,157,232,216,200,155,254, 10, 64,216,181,236, 54, 17, 4,193,153,217,183,157,181,113, 28, 39, 74,114,203,137, 11, 34,226, +192,129,175,231,192, 31, 32,200, 13, 4, 2,161, 32, 99, 39,126,173,199,251, 24,186,186,199,187, 22,182, 68,148, 67,148,104, 45, +103, 60,211, 83,253,168,170, 46,190,235,147, 50,214,123, 80, 18, 28,108, 80,237,157,209,240, 67,200,108, 5, 49, 89, 7,163,193, +241,184,161,161,160, 18,221,102,183, 89,152,150, 94, 4, 78,154,177,102, 47, 12,157, 12,226,164,116, 81,158,166, 61,147,208,142, +249, 52,123, 88,185, 69, 24,132,243,245, 12,247, 57,133,120,130,117, 94,235,189, 25,102,163, 2,170,255,182,213,170,102, 86,161, + 54, 94,199, 79, 42,135,106,220, 63,175, 27,187,221,149, 40,249, 1,134, 24,208, 75,125,203,136,242, 46,228,140, 33,235, 59,211, +106, 32,244,155,248,205,221,171,207,223, 31, 34, 19,190,123,249,246,253,199, 15, 0,239, 60,204,121,127,247,250,219,239, 31, 79, +219, 5,212, 69,184,172, 90,241,213, 45, 10,150, 42,168,202, 81,177, 84,244,198, 97,144, 93, 86, 21, 45, 65,130, 94, 4,236, 88, +129,172, 81,140,230,156,163, 86, 69,221, 4,190, 21,173,217, 78, 18, 70,178,180, 42, 55,147,139,136,226, 45, 42, 57, 16,171, 41, +138,102,109,183,235,221,142,118,105,222,143, 38,121, 22,201,184, 58, 90,184,181,221, 86,200,163,249, 87,107, 75, 40, 36, 46,184, + 15, 74, 1,159, 94,205, 90, 75, 47,179,161, 27, 9,130,143,208,121, 7,196,193, 57, 86,105,210,152,216,109,214,106,190,170, 42, +219,100, 42, 24, 4,248,247,123, 38,164, 11,134, 62,192,141, 43,192, 18,174, 53, 76,112,112,236,240,108, 13,135, 4,124, 12,146, + 16,251, 10, 25, 67,201,122, 95,196,200,194, 76,202,151, 41, 39,146,173,218,251,177, 56, 82, 91, 64,220,227,113,165,143,202,134, +135, 65, 16, 2,201,154,174,183,130, 79,136,159,205, 72,227,158,221,121, 67,162,125, 16,111, 41, 69,126, 91, 18, 98, 98,190,204, + 73,154,183,180,173, 92, 14,202,248,178, 37, 99,138,145,119, 14,122,234, 34, 14,211, 60, 25,206,214,211,142,220,215,137, 40,224, +122,142,227, 88, 12,103,218, 25, 81,199,140, 10,246, 74,213,135,195, 42,195,222,139,231,226, 73, 31,201,140,116, 66,199, 82, 71, +104, 65,155, 59, 98,165, 59,137,172,110, 60,184,156, 47,255,232,195,248,206, 75,125, 53,184,158,174, 30, 59, 14,129,246,132, 41, +246,179,145,131,169,185,151, 96, 68,228, 55, 98, 78,105, 20,134, 17,119,158, 40, 29,140,225, 74,234,123,161, 41,132,168,245,200, + 68,151,121,114,209, 15, 38,103,113, 22,129,219, 1,112,100, 20,228,140,118,245,170,168,159,183,106,110,221,115,161,167, 22, 67, +181,220, 78,103, 40,206,246,180,141,120,165, 41,111,210,228,137,172,206, 72, 76,104,199,221, 4, 47,211, 31,111, 70,215, 95, 30, +191, 42,174,115, 98,215, 41,142,239, 28,229,165, 32, 83,178,142,140,173,119,244,237,205, 33,180, 68, 92, 97,165, 98,249,206,178, +156,178,162, 57, 96,114,151, 9,137,202,108, 35, 90, 41, 92, 50,135, 14, 45,198,206,120,130, 89,171,125,212,150,192,221, 76, 6, + 87, 43,187,220,216, 13, 43,215,162,164,138,253, 86, 22,252,172,116,203,121,226,155, 41,173,109, 17,197,233, 46,239, 60,194,217, +174,195, 28, 62, 91, 20, 72,254,175, 35,130,200, 52,209,209, 32,184,112,222, 27,255, 90,252,228,170, 90, 32,102,223,206, 63,229, + 78,186,216,255,247,235,175, 0,140, 93, 77,111,211, 64, 16,245,218,222,117,226, 52, 77,218, 82, 17,133,182,215, 30,144,144,144, +248, 9,136, 3, 39,254,102, 15, 28,248, 19,156,184, 32, 85,130, 3, 66, 28, 80, 69, 75, 16,184,142,147,216,187,246, 50,111,198, +219,244, 67, 72,168,151,182,106,171, 52,182,103,223,204,188,143,190,190, 63,108, 99,149,186, 15,115,194,148, 38,238,185, 74,253, + 64, 45,145, 98,207, 76, 45, 53, 29, 29,172, 86, 37,239,222,209,229, 76,245,238,209,104, 14, 83,214, 22,184,208, 48,199,157, 14, +198, 65,130, 52,233, 8,153, 24,186,178,215, 31, 23,231, 27,208,156, 35,235,155,201,206,193,162,184,114, 81, 35, 4, 39, 31, 82, + 87, 68, 61, 17,247,146, 16,166, 76, 49,241, 23,197,155, 5, 8,147,108, 55, 97,119, 11,240,185,233, 88,166, 26,145,160, 67,164, + 98,161,169,184,211,109, 77,159,240, 30,127,146,239,206,246, 30,127,191,132,166,105, 66, 56,180,169,232, 88,202,204, 96, 93,175, + 79,143, 78,127, 20, 87,191,150, 11,199,154,108, 49,141,230,172, 95,107,177, 69,194, 72,156,110,172,217,116, 94,214, 69,103,234, + 50, 43, 97,216,101, 91,197, 82,133,198,226, 12,166, 50, 59,204,226, 76, 83,229,133, 86,114,133,156, 2, 31,196,179,132,169,113, +206, 13,147,228, 81, 62,188,234,154,142,173,250, 60,140,121,219,138, 94, 74,131, 34, 75,181,125, 62,205, 39,227, 36,213, 32,176, + 91,231, 45,146,130, 65,240,202, 76, 66,143, 82,227,162,114, 73,224, 67, 67,197, 74,183,225,202,242, 59, 14,110, 13,117, 71, 84, +157,107,231,107, 60, 34,145, 54, 17,245, 9,214, 66, 0, 69, 71,212,166,238,196, 42,139, 26, 43,103, 27,211,166, 59,105,156,167, + 38, 55, 70, 14,170,198,114,216, 60,155,112,163,202, 59, 12,228, 49, 79, 75,204, 90, 34,111,188, 76, 78,168,130,164,206,187,135, +155, 79,193, 34,119,179,156,194, 72, 49, 29,206,166,199, 95, 23,159,233, 34,142,244,184,178,165,250,167,253,145, 10,194,144,237, +102,136, 9, 48,112, 97, 45,123,188,175,238,213, 77,182,122,198,150, 53, 67, 72, 11,222,126,157,228,182,221,104, 80,241, 28,175, + 46,251, 28,221,155, 48, 35, 40, 54, 18,253,100,255,228,219,207, 47, 33,230, 37,241,119,103,154,125,136,157, 64,219, 45, 84,138, +111, 39,126, 68,129,248,203,161,185,140,217, 4,174,138,168, 64, 8,116,204,176,204,116, 6,199, 30, 8, 50,111, 78,190, 86, 5, +111, 5,181, 53, 80, 51,244, 61,216, 63,132, 71,108,155,197, 33,209,105, 60, 72,140,195, 22, 42,234,131,141, 48, 0, 77,249,107, +201, 88,210,120, 68,128,214, 9,167, 27,172,155, 8,123, 65,189,199,152, 61, 54, 74,239,235,116, 54,214, 39,211,252,248,208, 28, + 76, 50,132, 56,243,216,153, 97, 50,148, 46, 94,100,204, 50,166,136,216,139,177,141,174,151,238,226, 79,119, 89,232, 69, 29, 45, +106, 27,243, 72,217,247, 33,129,226, 73, 28, 11,243,130, 53,171,113, 24, 92,108, 37,199, 97, 65, 39,232,191,147,225, 59,218,118, +190, 82, 64,241,232, 47, 45,149,254,220, 12, 95, 62,127,117,246,254,204,123, 97, 61,132,178,128, 77,236, 97, 81, 21, 14, 78,188, + 74,168, 81,178,178,164, 31,217, 27,239,255,174, 10,164,191, 49, 93,140,126,113,104, 70, 93,107, 87,204, 16,237,109,198,249,127, +148,169, 11, 67, 9,208,224,169,151,166,115,111, 99,233,177,174,251,209, 77, 24, 79,122,105,155,188,162, 63,181,110, 86,131,116, + 80, 53,203,219,201, 7,132,117, 54, 22, 87,214,232, 1,157,106, 85,159,243,215,241, 7,251, 45, 42,117,127,186,226,187,215, 47, +222,188,251,240,150,122, 42, 23,185,167,243,103,159, 46,206, 67,156,247, 54,158,172, 95,186,162, 12,179, 38,247,255,170,252, 95, + 1,232,186,150,229, 36,130, 40,218,243, 30,102, 8, 18, 30,134,160, 49, 27,227, 55,164,252,112,171, 92,185,208,133, 91,127, 64, + 43,101, 64, 2,145, 16, 96, 96, 30, 61,211,222,115,187, 71, 38,104, 82,149, 41, 22, 36, 60,186,231, 62, 78,159,123,206,127,226, +187,245,140,183,182,211, 28, 29, 68,143,230, 68, 65,203,181,221,205,110,141,206, 78, 9, 62,219,243, 65,146, 17,192, 17,186,113, + 23, 38,135, 74,180,189,246, 56, 30,211,149, 42, 62,223,246,181,157, 18,189,203,101,122,255, 43,185,127, 76, 31,112, 63,240,152, +184, 89, 90,136,134,115,171,165,195,133,210, 38,236,245,236, 53,103,233, 78,171, 3,186, 18,124,191,120, 51, 87,106,220, 31, 39, +251, 77, 14, 65,125, 20, 84,204,244,130, 16, 60,135,117,168, 25, 67,135,215,113,125,248,229,161,156,215,180, 92, 10, 22, 2,250, +115,160, 36, 86,252, 87,146, 81,193, 2,210,174, 82,163, 19, 69, 85,188, 25, 92, 92,157, 95,125,248,246,209,245,188, 18, 39,189, +237,172, 76, 83,153,211,190,109,117,100, 60,164, 45,147,229,185,218,225, 92, 89,165, 84,214, 74, 5, 32, 19, 98, 0, 2,178,215, + 48, 59,117, 61,122, 88,105,124,147,213,123,132,253,105, 49,117,125, 31, 32, 39,215, 58,153, 44, 10,176,143,202, 56,244,206,186, + 81, 43,116,216, 16,139, 53,171,133, 12, 60,187, 29,133, 54, 10,234,124, 52, 26, 93,191,191, 30,246,123,159,191,124,165, 76,244, +253,230,231,228,246,214,245,124,246,205, 46,211, 76, 38,123,153,115,189, 19, 4, 86, 0,178, 38,181,231,202,243, 4,181, 7,153, + 20,219, 68,108,118,149, 22,183,217, 83, 70,161, 79, 91,200,216,117, 66, 10, 7, 44,188, 6, 74, 41,253, 66,136, 91, 49, 40,207, + 39, 83,102,130, 92, 24,209,230, 6,133,139,201,145, 39, 89,190,163, 14,130,130,198,184, 59,186, 89,254,176,143,139,116,163, 29, + 98,153,131,217,102, 56, 83, 71, 44,177,208,139,210, 98, 71, 47,209, 9,105,161,105, 23,149,180,115, 6, 39,131,201,227, 68,135, + 10,234,189,168, 29,214,242,100,170, 30,128, 56,141,122,219,253,138,179, 14,235,238, 54,143, 29,213,113, 33,175,177, 23,250,207, + 20,244,114,173,220,123,116,154, 42, 68,173, 5,102, 76, 26,107,150, 70, 51,178,215,228, 13,139,249,241, 84,226, 68,125,138,188, +191, 55,115,195,127, 6,200, 85, 94, 14,222,206, 30,167,153,220, 83,160, 56,239,190,154, 45,167, 54,143, 61, 80,218,140,189,120, +157,174,158,170, 7,234, 17, 83,235, 48,116, 37,106,145, 23,131,207, 40,212,226, 58,223, 40, 22,246,226,178, 93, 31,150, 82,155, +135,128,142,210,156, 58, 33, 42,213,225,241, 66,165, 21,148, 42, 44,186,210, 46,244,232, 86, 29, 5,254,235, 23,241,187,179,240, + 98, 24, 7,129,163,129, 4,172,144, 6,124,112,225, 9, 83,206, 85,140,123,224, 84,138,174, 84, 22, 0, 75,145,149,190,206,215, +226,110,229,206, 18,119, 85, 84,185, 44,205,212, 40, 40,191,104, 32,213, 83,105,132,191, 11,110,248,206, 96, 69,234,244, 1, 19, + 78,201,130,190,128,103, 25, 34,164,135,113, 4,198,237, 98, 61,175,216,202,141, 13,169,141,211,158,193,104, 76, 71,136, 55,109, +114, 50,195, 40,250, 94,102, 21, 57, 60,231,180,213, 95,165, 15, 5, 85, 73,150,241,177,225,128, 93,214,200,251, 33,107,131,147, +137,198, 7, 7, 7, 84,240,105,247,178, 82,131,106,120,105, 78, 31,134,101, 9,139, 65,230, 18, 31,198, 59,226, 32, 78,210,132, +191, 39, 52,184,108,191, 86,105,183, 41, 74,177,212, 31,136, 99,232, 30, 8, 85,175,253,114,177,189,115, 45,205,155,208,159, 8, +225,150, 13,194,155,228,254,138, 86, 18,138,152,255, 48, 23,158,251,249, 35, 0, 93, 87,187,218, 68, 16, 69,119,246,123, 55,217, +216,216,164, 52,133,210, 10, 85,240, 71, 65,170, 32,248, 6,226, 67, 8,250, 50,234, 19,233, 51,168, 69,196, 31,130,138, 86,209, + 20,147,150,184,117,179,223, 51,222,123,102,119, 83, 34,205,191,144, 31, 59,187,153,189,115,238,189,231,158,163,249, 51,198, 37, +163, 44,113,165,192,152,106, 79, 12,193,162,237, 4,145,226,140, 69,213,233,254,239,223,122,240,246,203,107, 11,246,187,141,141, +139, 50, 67,215,175,185,251, 97, 66,146,205, 4,136,118, 88,175, 11,135, 54,151, 54,180, 46, 25,116,101, 24, 44, 10, 93,147, 81, +141,224,187,108, 24, 68,145, 63,136,243,216, 22,171,186, 63,191,255,182, 55,236, 15, 79, 23, 83,143, 93,185, 53,177,150,139,135, +104, 22,241,228,197,157,253,195,207,211, 79,182, 98, 24, 63,240,162, 81,180,185, 53, 24,253,152,159,208,166,113,224,220,232, 64, +248,253, 90, 48, 96,177,120, 76,102,106,173, 57,200,153,169,174, 32,200,248, 93,213,116,185,155, 59, 7,199,223,222,179, 25, 19, + 26,247,146,135, 6,197, 36,218,249,122,118, 2,149, 2, 10,216,210,166, 48,106,151,195, 77,193, 53, 34,197, 61,165, 56, 22, 69, +105, 85,133, 73,200,158,112, 29,129,230,113,127,242, 43,153,150, 12, 45,173,153,181, 48, 3, 87, 59,187,179,148, 38,197,100,163, + 78, 74,186,156,181,189, 17, 97,236, 8,179, 39,182, 69, 9,106,200,132,122,222, 79,247,238, 30, 61,126,242,116,239,246, 33,161, +192,217,247,143,227,201,238,197,124,246,226,217,243, 55,239, 62, 84,149,149, 3,125,231,204,206,171,153,193,138,218, 21,221, 18, + 61,250,176,103,132, 30, 29,110, 42, 93, 26,105, 38,146,140,229, 37, 10,237,180,170,128,250, 11, 90, 32, 33,156, 50, 52,184, 91, + 78, 95, 43,206, 92, 36,179,224, 27, 16,132,154,124, 35, 5,130,234,153,209,169,101,115,159,186,130,204,186, 99,251, 89,149,154, + 87, 78,216,173, 59, 77,211, 67,190, 30,142,206,151,243, 86,163,156,255, 77,223, 9,170, 42,239,249, 17,102,253,133, 92, 57,108, +160,231,207,137, 96,208, 78, 51, 53, 81,131, 82, 67, 58,116,247,198, 55,206,255,204, 8, 94,137,150, 32,208,173,195,119,252,164, + 76,244,226, 61,219,131, 14,101,254,191,251,146, 46,180,154,151,170,154,180, 0,215,245, 88,182,150,199, 82, 58,105, 45, 94, 10, +193,255, 10, 38, 30, 77,251, 12,172,109,140,237,106,250, 34,183, 61, 67, 47,202,202,132, 98,167,235,184,180,189,181,231, 12,151, +252, 48,186, 93,214,229,229,182,112,219, 0, 48,215,184, 55, 93,124,231,150, 41,100, 55,233,129,211, 45,203,186, 64, 27, 83, 56, +152,122,103, 95, 23,139,123,206,125, 63, 50, 85, 74, 59,214,133, 86, 47,167,204,166,189,227,187,187, 27,193,193, 86,111,127,187, +239,184,173, 0, 31,191, 37,208,231,211,194,220,220,143,114, 28, 63,112,131,190,217,235,219,182, 47,108, 79,193,146,148,187,244, +148,165, 22,121,145, 45,147, 56, 78,255, 46,210,228, 34,203,211,248, 66,253, 60,243,126, 47,131,105, 86, 88, 0,171,140,229, 13, + 11,199,150,208,101,104, 29, 99,218,252, 12,108, 71, 20, 2, 52,219,189,212,110,203,178,206, 97,199,193, 23,226, 20, 76,130, 87, +163, 32, 70,221,241,103,224, 45, 11,143,120,209, 52,246,155,255,183,110, 39,117,233,183,237,141,201,116,113,202, 9, 7, 6, 30, + 88,174, 76,147,104, 52,173, 82,151, 90,218,198,168,142,170,178,221, 46, 96,230,107,118,176,194, 0,115, 85, 33, 82, 19,108,167, +196, 11, 12,159,102, 50, 89,106, 72, 46, 91,138, 37,248,154,116, 23, 15,143, 30,189, 58,126,217,208,173,128,184,133, 92, 73, 67, +172,141,158,181, 3, 91,162,235,192,170,238, 20,236,198,185, 86, 47,139, 92,119,212,185,250,243, 79, 0,198,174,101, 39,110, 24, +138,218,142,157, 56, 78, 50, 1,134,151, 0, 33,181,160,138, 10,117,213, 15,224, 7,202, 95,116, 81,169,127,202,178, 72,253, 2, +250,160, 20, 6,230, 61,147,216,233,189,215,246,116, 68, 89,116,151, 5, 66,153,241,157,235,251, 56,143,160, 47,150, 4, 37,165, + 16,100,126,114,151,172, 9,245,121, 5,165, 44, 45,172,109,144,170, 10, 95, 61, 53,152,222, 3,253,230,254, 6,221,207,137,216, +188, 50,153, 65,143,102,127,157, 70,165, 71, 28, 15,195,105, 49,171,179,140, 28,183, 29,157,151,245,146, 79, 8,238,240,208, 68, +106,189,124, 53, 99,116, 49,109,103,222,222, 58, 98,222,131,117,234,201,222,233,175,225,207, 92, 21,144,242,136,153,230,253, 61, +130,149,204,253,232, 14,126, 61,138,214,247,112,160,139,249,116,127,115,119, 58,159, 66, 85, 0,141,133,136, 76, 90,244,239, 98, + 45, 41,113,132,225,157,239, 67, 93,240,103, 96,148,212, 44,244, 92,223, 30,127,120,194,160,136, 85,102,157,215,183,195, 91, 58, + 78, 55,183,237,100, 97,199,179,118, 56,230,221,180, 26, 12,248,195,160,187, 27,112,197,247,126,143,198, 75, 75,154, 80, 82, 45, +237,124,216, 60,194, 11, 64,249,207,157, 80,213, 50,175,136, 59,146,160, 54, 27,225,200, 88, 42,161,185, 75,122, 70,105,124,123, +169, 51,105,242,148, 35,172,190,219,217,234, 93, 94,126,248,248,233, 51,180, 19,110,254,157,179,197,211,195,237,215,235,171,227, +147,211, 94,161,175,191, 92,213, 61, 93, 22, 18,125,190, 21,109,157,137,155,229, 90, 95, 76, 73,214, 73,228,103, 53, 46,149, 93, + 89, 64, 23,130, 62, 83,165, 54,239,207,223, 38,174,123,120, 26, 9,166,160, 53, 53, 6,154,211,165, 66,140, 70,226, 77,209, 50, +132,255, 96,100,195, 51,100, 13, 56,250,192,122,164, 66,187, 65,216, 70, 48, 96,241,145, 71, 27, 23,150, 43,211, 58,183,198,182, + 65,185,212,149, 66, 25, 95,131, 54,250,136,105,145,171,189, 66, 49,226, 69, 3, 1,179,104, 22, 34, 90, 82, 64, 72,146, 84, 94, + 75,233, 30,110,177,214, 47, 62,225,115, 24, 8, 3,183, 12, 22,131,144,131,219,153,196,134, 77, 58,212,172,134, 39, 73, 96,126, +148, 9,235,229, 27,208,156, 80, 89,129,177,247,108,210, 30,228, 72,152,203, 84,234, 25, 52,135,219,199,232,213,137, 11, 77,140, + 5,177,150,220,189,228, 94,207,212, 29, 57,208, 10, 22,125, 30, 59,118,118,120, 62,130,234, 7,185,172, 88, 7, 16, 26, 16,203, + 90,148,104, 23,164, 82, 24,136, 9, 81,165,115,173,206,133, 44,140,116, 74,193, 60, 30,166,251, 43, 52,128,153, 93, 37, 41,177, +118,145,132, 41,201, 1, 89,226,186, 11, 43,116, 77,222, 97, 70,114,147,170, 74, 65,179,156,104, 5,207,162, 76,210,131,194,188, +219,169, 47, 94,245, 47,206,250,111, 14,203,173, 26, 83, 59,252, 54, 20,116,180, 89,154,166, 56,171, 73,112,129, 6, 95,101, 85, +236, 29,149,251,175,245,238,145, 40,250, 54, 41,103, 54,153, 55,108, 12, 77,225,210,161, 85,175,149,141,208, 60,171,178,141,157, +162,127, 80,109, 31,153,106, 75,107,182,145, 79,106, 53, 75,157,110, 59,141,131,120,225,135, 93, 1, 90, 19, 45, 57, 87,108, 46, +252,131,237,178, 63, 37,125,177,149,170, 90, 27,156,244, 92, 28, 80,176,216,156,209,108,136, 5, 66,134,139,215, 43,127, 81,200, +136,178,245,120, 54,241, 54, 65,156,199,219,218,215,206,156, 67, 12, 19,196,178, 99, 43,111,241,224,139, 18,134,106,200,100, 67, + 23,210, 77,156, 43,224,212,222,121, 7, 16, 74,107,141,231, 36,211, 42,213, 18,188, 40, 40, 47,210, 74, 48,104, 99, 64,113,217, +162,120,113,248,119,193,220,131,191, 32,181, 20,105, 82,252, 95,144, 76,120,221,231, 68,167,238,255,149,200,254, 8, 64,215,185, +244, 54, 13, 4,113,220, 94, 59,235, 56, 73, 93, 2,109, 17,109,213, 22, 40, 41, 32, 78,168,229,204, 7,225, 0,119,196,129, 3, + 18,124, 26, 36,248, 40, 72, 92, 17, 20, 81, 84,241,146,218,164, 21, 13, 41,121,217,241,174,119,153,135,157, 56,149, 56, 38, 82, + 44,197, 94,207,227, 63, 51,191,241,157, 25,228, 19,207, 25, 79,112, 97,146,228, 78,171,169,102,154, 4,104,252,111,204,188,200, +127,130,167,180, 16,215, 80,180,163,150, 18,198, 80,104,244,100, 26, 51, 92,172, 75, 67,240, 74,213,126,227, 54,163,165,225,120, +136,146,153,165, 14, 67, 90,208,204, 8,255,140, 29,232,252,138,111,183,232, 0,179, 69, 55, 24, 60, 94, 48, 19,223, 79, 14,163, +176, 9,225, 79, 66, 38,192,153,241,124,232, 61,163,222, 91,151,113, 52,214,108,175,181,126,156,254,132,120,176,234, 75,108,111, +164,145,218, 98,197, 59,202,133,229, 53,161,166,152,180,100,232, 13, 60,206,214,234,206, 73,175, 83, 13, 26,224, 81,152,247, 9, +207,126,105,121, 53,209,217, 32,238,193, 5,214, 23,215, 27, 65,116,208,217, 95,137,174,246, 70,184,238, 29,204, 50, 4, 89,221, + 81, 7, 39,191, 49,124, 14, 33,177,173,122, 33,164,209, 26,163,123,143, 66,120,183, 94,119,117, 32,224,143, 39, 19,146, 20,201, +222, 4, 18, 13, 52,149,167,208,147, 41,149,193, 33,186,215,218,126,244,228,241,221,189,135,142, 35,213,168,243,249,195,199,205, +235, 91,111, 94,191, 13,171,193,121, 47,222,221,125, 16, 53,106, 24,233,196, 14,193, 35, 49,148, 17,138,251,213, 69,206,216,134, +219,157,234,173,205,141, 59,173,181, 12, 23, 24,217,131,195,111,153,149,207,159, 62,131,135,254,226,213,203,110,191,143,209, 78, +150, 70, 13, 49,248,147,136,184, 34, 69, 52,176,127,105,215,241,132,188, 39,156, 0, 45, 43,181, 84,197,124,143,136,159,142,150, + 61,244,235,177, 30,185,165,199, 0,246, 53,117,202, 61,191,224,219, 17,173, 62, 53,249, 21, 33,180,201, 57, 69,177,142, 67,190, +236, 76,186, 65, 37, 84,147, 63,192,102, 21,100, 17,199, 16, 58, 22,176, 48, 65,112,237, 62,178,233,177,157, 78,179, 97,246,168, +221, 13,211,115,159,115,104, 83, 11, 23, 6,113,223, 96, 69,221,167, 52, 69,149,223, 45, 30,192, 46, 51, 41,141,163,106,114, 1, +125, 63,234,132,162,221, 61,190, 40,200, 88, 94, 59,140,194, 13,100,163, 19, 92, 47,103, 68, 62,165,111,165, 47,225,115,187,123, + 4,238,208,163,149,212,188,116,128,212, 42,154,199,167,198, 36,222, 34,153, 56, 49,225,191, 68, 9, 52,133, 2, 52,141, 13, 95, +196,182,139, 28,226, 99, 92,230,177,211,168,184, 71, 0,165, 0,183,222,185,161, 15, 14, 27,124, 3,194, 92, 81,151,132,172, 72, +134, 27,139,225,237,149,133, 27,215,234,152,232,146, 30,146,102, 70, 10, 92, 4,143,102, 29,107, 82, 20,213, 65,166, 29,132,149, +230,170, 87,187,164, 28, 49, 78,116,210, 31, 78, 38,112, 46,148, 79, 20, 0, 44, 81,230,121,173, 69, 19,193, 75,155,192, 67,192, + 37,130,203,141,181,102,184, 52,110,156,159, 70,191,143, 87,218,234,232, 60,106, 39, 41,188,104, 76,117,229, 89, 0, 99,231, 76, + 20,220,136,179,209, 25, 23,244, 80,248,160,138, 69, 24, 84,119,150, 55, 63,253,218, 39, 3, 63, 37, 49,218,124, 70,125, 14, 30, +205,125,132, 69,172,192,149,207, 98, 26,205,163,176, 18,236, 67,119,220, 35,131,203, 48, 96, 90,208, 97,204, 56, 25, 90,183,152, +130,117,103, 99, 13,140,230,244,136,114,175, 92,149,170, 4, 59,218,172,205, 21, 43, 4, 68, 5, 91, 87,110, 30, 28,127,145,126, +229,254,173,189,247, 95,223,209,247,134, 87, 48,230,178,147,181,224,161,179, 12,233,164,112,115,148,206,202,232,108,251,191, 65, +112, 92,146, 28, 80, 54,121,145, 33, 68,150, 54, 99, 89, 71,138, 10, 13,105,103,243,190,224,191, 33,252, 63, 1, 24,187,154,222, +166,129, 32,234,181,189,118,156,230,131,170, 73,211, 22,137,130,232,133, 19,226,194,133,143, 11, 18, 72,168, 20, 85, 28,225, 82, + 9,126, 8,136, 83,143, 28, 64,252, 22,132, 4,133, 86, 2, 36,184, 32,161, 34, 36, 68,212,166, 36,109, 72,237,166,254,216,117, +188,204,236,174,221, 20, 56,112,110,236,164,218,217,157,183, 51,111,222,179,139,202,189,228, 65, 35,243,110,100,164, 74, 15,214, + 16,199, 6,108,109, 74, 35,174, 85,234,165, 68, 72,102, 30, 37, 76,145,151, 12,213,141, 39, 19,146,223,166,106,232, 24, 29, 25, + 81, 67,157,240,177,174,223, 1, 20,150,226,183,140, 10,114,169,106,157,141, 27,142,171,140,135, 23,112,105,164,148,233, 41,116, + 68, 60, 16,146, 83,245, 86,202, 19,244,124,208,230, 21, 66, 81,234,140, 49,237, 42,205,198,146, 85,197,102,173,177,235,247,144, + 59, 96,152, 17,139,101,147,211,146,130, 10,218,224,111,182, 62,187, 61,232, 24,122,106, 67,164,154, 25,136,133,180,186, 91,223, + 13,246,168,237,248,209,254,124,235,108,207,239, 2,100,186,119,247,254,165,165,107, 79, 30,173,110,188,127, 9, 41,125,187,191, +237,209,193, 76,237,228,169,198,233,173,253,215,176,185, 96,219, 3, 76,144, 9, 15, 83, 23,206, 76,215,102,218,251, 91,132,112, + 56, 85,208,255,147, 13, 7,131,108,151,115,188,186, 24, 36,102,128, 85, 25,102, 50,100,166,201,249, 81,194,230, 90,205,238, 94, +152,196,201,131,149,149, 91,203,119,156, 90, 11,254,187,157,239,159,219,223, 54,167,231, 90,176,253,218,237,238,195,199,171,111, +215, 94, 81, 58,213,239,143, 0,137, 13,227, 3, 8, 62, 7, 2,193,118,108,142, 30,175,156, 97, 27,186,236,148,126, 5, 62, 99, +198,226,245,155,139,183,151,130,193, 0, 86,240,217,243,167, 31, 62,126,234,245, 58, 87,110, 44, 95,188,112,254,197,155,117,216, +176, 28,203, 54,102,165, 74, 2, 30,194,181, 25,222, 38,213,115, 71, 18, 26, 91, 60,139,109,226, 22,102,236, 88,238,201, 4, 19, +169,235, 0,136, 36, 33, 59, 44,226,238, 32, 25,142, 71,159,107, 57,153, 38,246,146,194, 10,205,196, 54, 32, 85,234,187, 36, 59, +226,164,203,237,108, 65, 22, 47,216,187,169,150, 47, 45, 12,210,196, 33, 30,238, 10,249,140,168,229,178,252,252, 72,120, 8, 15, +115, 57, 31, 0,127,133, 21,153,156,152, 92,255,178,166, 76, 30, 80, 56,122,236,156, 65,202,211, 40,203, 97,159,108,224, 11,114, +249,220,213,119, 95, 55, 4, 55, 76,114,172, 72, 2,171,131, 5, 86,118,168, 84, 20, 77,148,187,178,112, 79, 10,109, 22, 45,231, +179, 40, 37, 60,100,161,137,114, 82,136,209,171,110,205,143,125, 88, 14, 56,181, 9, 22,232,154, 63,131, 29,100, 37, 1,218,176, +220,200, 72, 72, 70,198,230, 80,117,205, 36,203,189,177, 20,149, 70,190, 76,234, 36, 74, 16,132,114,167,216,132,176, 93,219,116, + 1,185,163, 79, 38,245, 44,148,196, 0, 96, 0, 43,113,166, 82, 94,104, 76, 44,204, 86, 79, 84, 40,210, 13,225,206, 18, 27,178, +144,136, 24,191,228,216, 30,186, 71, 98, 93, 71,151, 6,234, 77, 10,123,138, 56, 97,204,226,144,201, 54,191,128,143,209,146, 91, +114,229,140, 8,186, 59, 96, 34,101, 9, 11, 25, 15, 67, 22,241, 52, 78,146, 72,196, 72,195,129,211,129, 82,123,106,190, 81,157, +246,234,237,242,143,190,179, 83,106,163,145,145,212,239, 78,149, 46,164,242,244,208,194, 59,122, 56,154, 40,249, 11,173, 10,199, + 56,219,236,108,138,124,124,148, 28, 77, 7,253,209, 65,193, 69, 83, 78,232,249, 68,178, 0, 52,224,185, 94,128,102,109,138,240, +140, 73,180, 86,170, 14, 33, 14,133, 98,183, 74, 71, 79, 75,202, 99,169, 38,120, 62, 12, 81, 41,213, 32,207, 4,161, 15,207,122, +142,135,252, 28,150, 97,226,132,199,163,161,252,129,184,147,225,254, 45, 47,127, 82, 79, 68,153,175,202, 86, 16,196,128, 37,173, +160, 97,109, 38,156, 50,252,194, 88, 68, 72, 79,248,171, 22, 3, 97, 0,111,200,213, 0,198,248, 62,255, 24,156, 16,227,230,166, + 42,150, 20, 3,205,252,111, 71,167,223, 2, 80,118, 45,171, 81, 4, 81,180,171,187,250,221, 61,111,205, 96, 18, 77, 2, 65,163, +130,131, 27, 55, 46,196,149,184,116, 33,126,133,123, 87,130,250, 5,174, 92,248, 21,186,209,128, 40,130,168,136, 1, 21, 65, 71, +136, 58, 17, 31, 76, 18,210,201, 60,250,221,222,123,171, 50,211, 1, 55,146, 69, 32,144,164,123,186,235,212, 61,183,206, 61, 71, +250,207,180,220, 67,100,166, 1, 55, 16,231,212, 90,170,217, 77, 75, 55,128,231, 78, 10, 8, 40, 14, 26,196,167, 24, 43, 31,172, +149,229, 62,211,129,106, 41, 99,158, 14,183, 83,137, 46,142,173,153, 2,197, 32,150,165, 89,186,111,213,140,223,109,195,101, 40, + 33, 79,247,117, 10,130,214,225, 83,240,157, 42,209,171,226, 72,109, 62, 70,109, 8,174,159, 40, 29,211,160, 35, 34,114,205,109, +228,148,172, 34, 99, 45,104, 97,138, 81, 38, 21,239,165,210,235,111,228, 89,134,239, 51,211, 60, 96,243,128, 89,232, 2,133, 85, +190,216,177,154,126,107,123,176, 3, 87,227,218,110, 34,194,189,136,145,136, 92,139, 97, 56, 12,162, 97, 20, 71, 73, 10,160, 10, + 85,100,209, 57,125,118,161,179,178,246,226, 85,111,227, 43,214,254, 12, 40, 69,180, 51,218,237,109,245, 8,209,128, 38, 59,182, +225, 13,194, 1, 96, 96,211,159,217,220, 67, 5,235, 40, 30,160,252,188, 72,198, 52,156, 25, 43,201,136,229, 9,157, 35,135,169, + 72, 21,198, 39, 29,195,223,203, 56,252,167, 91, 55,111, 67,105,103, 90,214,245, 27,119,118,183,251,221,247,111,219, 71,151, 62, +188,126,222, 62,182,180,120,242,156, 87,111,173, 62,124,176,176,184,188,217,223,158,157, 95, 72,226,236,202,213,107,221, 79,235, + 26,179,251,155,129,109,217, 97, 8, 47, 89, 17,199,249,209,185,249,206,153,206,187,143,221, 36, 73, 79,157, 88,126,244,248,201, +221,123,247, 87,159, 62,251,252,229,199, 86, 48,170,217,254,249,139,151,181,108,188,246,230,101,189,226,170, 88, 74, 40,112, 85, +176, 72,226, 48,197,148, 77, 69,180,206,164,173, 28, 69, 86, 22,242,216, 13,171, 9,132,162, 48, 25,193, 62, 7,240,146, 23,211, +161, 36,193,178, 77,205,148,123,112, 62,233, 69,136,183, 1,117, 35,170,170,211, 52, 38, 9,215, 74, 65, 72,150,110,230,121, 82, +158,164,166, 68,227,132, 29, 48,161, 84,229,113, 39, 25,185,138, 55, 21, 80, 79, 12,202, 54,188, 70,148,134,191,131, 95, 27,253, +111,132, 41,156,250,144, 69, 81, 76,157,210,101, 7,137,122,122,218,126,246,195,247, 63,235, 81,145,144,110,156,218,206, 2,247, + 53,209, 99, 69,152, 32,173, 33,122,189, 33,121,165,249, 33,209,118, 5,130, 27, 35,220, 43, 36,247, 86,196,167, 37,140,181,179, + 60,179, 12, 11, 46,120, 47, 12,152,128,113, 6, 88,204,241, 30, 85,118,192, 46, 70, 12, 17,209,224,169,248,145,152, 20, 71,210, + 73,156, 78, 71,119, 39,216, 70,184, 5,172, 80,215, 92, 19,187, 49,158,101,114,205,174, 26,108,201,247, 46, 29,159,185,176,114, +120,174,101,193, 90, 14,161,106,192, 14, 67, 65,226, 72,213,226, 26, 38,192, 88, 58, 98, 55, 55, 68,184,146,222,156,211,234,179, +105,166,142, 71,225,120, 8,239, 8, 80, 52,221,243,172,170,111,219, 85,135,251,142,234,217,170,107, 3,105,229,158, 99,214, 60, + 15, 54, 76, 32,176, 21,219,128,218, 21,221, 53, 48, 18, 91,124,161,122,192,105,122,117,207,229, 59,202,128, 7,212,142, 18,247, + 87,176, 73,158, 45,226,182,169,155, 77,191,129,163, 15,244,241,229,148,168, 85, 72,218,204,218,192, 36, 84, 54,140,198,178, 95, + 58, 17,240, 8, 76,153,164,106,149,240,135, 35,125,177, 66,244, 6,151, 53, 40, 16, 62, 69,198, 66,224,177, 51,172,250,172, 72, + 53, 84, 61,112,194, 13,166, 74, 11, 26,230, 24, 54,206,172, 34,173,135,213,151, 38,164,142, 55, 52,221,208,173, 40, 9,165, 17, + 10,109,176,193, 8,189,163,103, 42,237,238,207,174, 40,235, 29,195,165,132, 3,137,197,113, 6,240,144,200,178, 87, 36,121,151, + 60, 9,224,161,149, 39, 78,225,119, 57, 55,208,187,152,178, 91,217,191, 52,195,101,221, 81, 86,252, 95, 84,223, 95, 1,248,186, +182,158, 38,130, 40, 60,179, 59,123,105,187,117, 11, 98,133, 98, 9, 26, 44, 10, 5, 52,242, 23, 12,134,144,152, 24,253,161,250, + 96, 36,222,222, 13,209,152, 40, 49,138, 62,224, 5, 99, 32, 20,216,210,189,143,231,178,219, 66, 98, 76,154,190,180, 15,211,206, +206,156,111,206,124,151, 98,127,207,233, 24, 82,134, 95,195,211,105, 57,182, 91,181,189,147, 65, 32, 12,246, 74,146, 81, 30,145, + 14, 69, 74, 41,255,201,174,151,195,246,134,228,120,108, 10,115,146,101,149,146,162,204,200,198,206,149,173, 92,226,109,144,109, + 1, 19,143,168, 17, 95,166,133, 25,172,236, 48,165, 53, 55, 57,247,167,247,155,253,176, 96, 48,176,122,177, 90, 18,169,215, 40, + 72,104, 98,230,226, 76,175,223, 35, 35,179, 34, 60,146,253,234,136, 78, 32,161, 44, 13,162, 83, 36,191, 83, 30,252,152,215,128, +149, 22, 83, 0,136,201,244, 52,145, 29, 6, 61,178,142,177,155,141,203,193,160, 31, 33,253,132,146,121, 53, 90,224,210, 74, 22, +237, 75, 87,130, 36, 12, 19,116,221,218,254,252,241,245,227,167,159,118,182,195, 40, 40,126,164,230, 46,190, 9,152,127,185,189, +188, 31,236, 31, 15,142,230, 91,157,159,135,123,128,169, 53,198, 1, 15,152, 94, 9, 95,132, 71,199,119, 26,137, 25,155,213,188, + 2, 79,186,169, 10,181, 17,186, 78,226,181,121, 13,224,149, 16,143, 30, 62,128,221,190,187,188, 80, 49,147,151,207,158,196, 97, + 95, 25,162,187,178, 58, 62,117, 13, 6,254,229,253,155,205,205,231, 91, 91, 91, 75,221, 46,252,210,181,141,251,211,115,139, 77, +191, 50, 59,219,130,122,180,190,190, 6, 99,170, 86,212,226,252,140,237,228,237,246,213,183,239, 62, 68,121,182,186,114,235,219, +238,238,246,206,215, 52,201, 28,219,170, 3,144, 83,249,250,198, 93,223,171,190,122,241, 20,224,103,152,144,226, 41,230,204, 69, +180, 95, 35,200,205, 35,215,101, 18, 25,194, 87, 12,147,195,187, 38,158, 48,163, 4,230,249,153,234,111, 12, 33,146,163,220,132, + 60,243,134, 91, 60, 55,151, 51,106,131,176,196,194, 24,101, 38,152,168,108, 20, 25, 0, 43,216, 31,217,211,145,210, 18,208,235, + 38, 43,125, 8, 70, 45,185, 17,177,210,128,201,181, 40, 82, 81, 83,116, 1,156,103,145,221,137,193, 44, 25, 59,221, 34,134, 85, + 10, 14,105, 68, 25,208, 22, 74,209,114, 89,178,180, 40, 2, 26, 71,221,172, 55,225,232,100,114, 7,175,140, 88, 98, 41, 34,117, +170, 21, 49, 58,248, 88,202,220, 25,125,123,246, 78,167,213,249,113,240,157, 17, 10, 17,216, 11, 7, 94, 68,128,148, 39, 92, 4, +105, 16, 52,162, 43, 4, 67,158,115,172, 26, 89, 87, 25,197, 75, 19,115, 65,145,127, 53, 33, 20, 67,186,166, 73,128,221,244,108, +187,238,218, 53, 87,121,182,211,114,213,198,141,201,123, 75, 83, 99,158,234,199,128,128, 18,210, 91,228, 68, 51, 67,122,155, 99, + 41,152,113,180,244, 67,245, 54,210,223,113,137,140, 79,139, 70, 75, 36,121,116, 26, 69, 33, 54,151,209, 45,164,230,192, 59, 84, + 84,204, 16, 80,164, 19,176,169,190,185, 74,184,182,168,186, 98,194, 51,155,141,218,228,216,132, 95,243,149, 21,195,195, 29,165, +156, 4,131, 69, 28,142, 7,190, 95, 83,125,125, 98, 30,167,108, 64, 92, 10,207, 71,215,130, 25, 50,180,210, 20,234, 76, 74, 97, +171,215,167, 58,251,193, 1,186,125,229,249, 81, 31, 3,131,121, 87,103, 39, 40, 93,222, 86, 48,109, 90,235,242,162, 70, 23,184, + 0, 86,229, 41,242, 17, 11, 79,123,158, 24, 22, 13,193,140, 67,197,162,109, 20,255,112, 56,107,146,157, 92, 68, 13, 46,163, 94, +185, 0, 69,151, 29,194,197,136,208, 41, 8,216,157, 16,215,138,189,201, 11, 17, 49,252, 25,120, 62,163, 34,125,115,122,225,215, +225, 94,249, 1,187,107, 22,202, 12, 89,176, 24,135,250, 51,220,187,226, 52, 60,227,122, 11, 40,138, 44,172, 48,113, 90,202,243, +217, 91,114,212,123,145,103,219,158,250, 60,109, 65,255, 87,206,247, 87, 0,198,174,100,183,105, 40,138,122,124,137, 29, 59,206, +224,116,160, 21,160,150, 65,128, 84, 53, 5,132, 4, 93, 84, 45, 93,242, 7, 8,241, 47,108,216,241, 19,192, 55,116,211, 5, 18, + 43, 36, 22, 84, 66,162, 18, 44, 80,105, 81,219,224, 56,142,235, 49,182,185,247, 62,187, 13, 66, 72, 72, 89, 37,145, 51,248,189, +243,206,157,206,169,234,171,220, 5,179,172,109, 97, 54, 48, 74, 2, 63,244, 40, 71,135,250,215, 34,215,114,175,110,208,121,153, +164,248,219, 53, 71, 40, 93,107,109,115, 22,182, 7, 44, 80,108, 48,160,130, 27, 87, 40, 42,139,105,216, 91,154,139,101, 78,230, + 60, 60, 41, 47, 75, 69, 60,234, 89, 20,224, 78,187,147,106,182,192,212,204, 48,137,128, 15,194,130,224,117, 27, 42,220,138,238, +217,176,165, 89, 64,174, 37, 46, 68, 67,137,117,106,130, 84,230,218,115, 39,238,241,218, 82, 31, 32,203,208, 48,175,234, 39,126, + 26,163,234, 58,215, 86,130, 15,132, 3, 0,168,132, 27,122,253,229,190,227, 59,199,238, 41,171,105,150, 97,121,193,152,108, 76, + 40,234,207,210, 81, 56,178,141,153,113, 56, 6,228,131,173, 0,241, 32,236,189, 0,165, 42,248,136, 45, 31, 2,130, 67, 66, 53, + 52, 3, 2, 0,120,201,106,116,116,181,126,115,241,246,207,209, 17,252,220,123,203,247,157, 51, 55, 76, 3, 88,108,131,192,105, + 54,117,185, 57,209,152,204,211,178, 8,236,149, 37,149,174, 40,117, 38, 31,124,223, 63, 60,220, 95,235,175,190,121,253,214,238, + 93, 90,223,216,254,244,241,195,141,254, 35, 58,202,163, 87, 47, 95,140, 3, 95, 42,210,103,207,159,190,219,221, 89, 93,187,155, +198, 35, 93, 83,147,100,236, 12,142,182,182, 31, 95,191,182,220,106, 53, 55, 55,183,246,246,246,102,237,185, 47,251,159, 1,215, +250, 43,119, 2,127, 20,199,163,153,182,105, 53, 85,189, 46, 71, 65,252,240,193,186,125,229,214,251,221, 29,199,115, 59,150, 1, +224,160, 8,168, 38,223,208,165, 32, 76, 97,115, 49, 81,163,210, 40,158,222,216,251,165, 54,112,117,166,137,170,104, 69,229,182, + 83, 77,111,148,133,180,170, 48,136, 48,157, 87,226,142, 93,189, 23, 79,226,188,148,231,158, 54,131,230, 13, 8,188,225, 87, 98, + 56,131,204,128, 14,219, 70, 15, 78,199,243,110,122,100, 85, 10, 67,162, 92, 5, 7, 92, 52, 70,165, 39,105,199,137, 89,134, 67, +117, 50, 38,247, 51,108,147,133,144, 34,155, 0, 97,229, 54, 82, 66,101,244, 73, 14,123,178, 86,211,101,145,145, 84, 36,143, 55, + 5,110, 90, 68, 93,179, 17,220, 77, 38,215,121,118, 23,158,198,238, 20,184, 26,118,239,160, 39, 22,217, 70, 18, 14,211,247,128, +157,242,203, 31,124, 59,249, 90,105, 19, 78,231, 79,139, 63,242,165,136, 5, 92, 10,242,220, 19,109,250, 81,136, 23,198, 76,165, + 89, 81, 46,226,128, 52, 99, 53,146,171, 4,164,134, 67,140, 53,152,108,106,192,196,213,182,194, 54, 22, 23,158,172,116,151,230, + 77, 31,110, 94, 50,161,177,232,156, 91, 77, 32,115,199,180, 12,234,222, 32,204, 1,185,192,243,142,234, 83, 86, 79,232, 93,198, +136, 18,130,211, 8,145, 24,201, 36,252, 89,170,130, 1, 75, 16, 9,206, 88, 24,184,193,145,231, 28,140,220, 67,207,251,225,103, + 78,160, 69, 49, 26,246,104,170, 96,235,194, 66,135,205,119,236,122,205, 20, 68, 76,236, 76,242,114,163, 75,114,189,101,105, 98, +226, 13,243, 48,207,165, 11,163,164, 42,107, 74,102, 9, 16, 98, 95,182,175, 14,137,156, 13,253, 97, 86,150, 39, 10,110, 99,200, +109,105,219,166,125, 22,249, 60,185,151,151,139,141, 74,102, 4,250, 24,190,235, 38,177,191,162, 81, 51, 44,163, 25, 33,202, 23, + 60,161,193, 71,220,245,154, 14, 16, 63, 14, 61,137,108,193, 33,232,140,179, 4,168, 3, 48,117,106, 27,146,225,178,179,205,121, + 0, 22,198,208,255,150,202, 27,114, 29, 21,235,210,174,209,141,200,253,188, 66, 47,169, 82,207,197,110,251,211,241, 9,124, 13, +154,245, 3, 26, 33,229, 60, 15, 89,228,149,106,208,133,213, 43, 10,207,169,181, 20,222, 6,241,101,145, 11,226,148,208,138, 40, + 22,255,242, 63, 19,166,220,160,166,220, 40,197,255,147,128,255, 45, 0, 99,103,210,219, 52, 20,196,113,251,217,241,146,186,117, + 66,150,166, 27, 45,170,212,138,245,128,144, 64,229, 4, 7, 16, 66, 21,156,248,106, 72,240, 33,184,192, 5, 33,113, 70,234, 1, +149, 32,154,170,106,105, 73,186,164, 73,227,172,246,115, 28,155,153,121,118, 82,161, 30,184, 70,178,163, 68,246,188,255,204,252, +231, 55, 99,255,140,114,137, 81, 32,199, 40, 95,218,187,134,149,104, 57,252,103, 18, 79, 85, 98, 92,181, 36,203, 87, 81,159,240, + 46,131,225, 0,101, 47,142, 22,169, 49,170,120,236,255, 97, 44,129,230,200, 99,212,240, 4,119, 23,129,152, 8, 68, 15, 45, 25, +103,146, 30,173, 61, 62,105,214,188,192,139,196,124,142,132,244, 9,114,185,226, 37,150, 49, 69, 32, 24, 44,109,171, 44, 33,159, + 17,239, 2, 50, 47,151,187,157,190, 51,155, 1, 57,214,247,135, 28, 81,233,100,179,129,247, 31,110, 2, 82, 29,110,107, 25,214, +121,167, 9,233,219, 81,163,134,116,139, 40,240, 56,228,157, 98,137,145, 0,215, 69,183,151,239, 86,106,149, 80,142, 71, 40,123, +188,219,195,106,149, 50, 86, 45,226, 39,204,231, 74, 32,157, 64,188,135, 40,198,131,243,110,227,212, 57, 14,201, 54,119,210, 57, +155, 49, 51,185,233,252,198,250,195, 95, 39,187,204, 24,113,196,124, 42,152,234,224,234, 37,201,208, 21, 83, 99, 16, 88, 45, 35, +165, 27,122,187,221, 61,173,119, 14,246, 15, 43,123,251,131, 1,191,168,215,219, 78,235,254,198, 19,225,105,251,242,233,131,211, +238, 21,138,243, 47, 55, 95,191,123,251,254,197,230,171,161,239,101, 23, 86,166,211,230,215,207, 31,183,127,148,251, 61,255, 79, +237, 12,164,102,237,120,175, 52,151,169, 85, 15, 52, 67,186,181,118,163,217,114,234,141, 38, 36,248,156,251,215, 23, 23,230, 75, + 37, 77, 51, 87,111,222,251,189,251,211,105,182,158, 63,123,186,181, 85, 70,223, 7, 36,209,186,226,113,120,224, 37, 63,226, 4, +229,193, 99,145,156,106, 1,225,244, 48,152,146,192,136,171,234,114,178,201,150,177, 20, 28, 85,102,202,132,119,105, 57,183,138, +204, 56,130, 37,185, 9,172, 6, 1,214, 52,232,112,137,225, 17, 45,102,175, 99,235,142,236, 40,130, 75, 35, 22, 90, 78, 54,148, +162, 45,110, 20,197, 83,243, 44,217, 28, 18, 21,166,139,144, 92,170, 76,155, 49,109,142, 21, 82,225, 13,143, 50,102,174,207,251, + 4,140,144, 8, 62, 17,206,152, 89, 31,181, 69, 36, 70,150, 32, 10, 82, 61, 20,159, 75,120, 80,151,114, 43, 29, 92,228, 70, 58, +153,144, 18,150,110, 89,250, 20,153, 11, 2,177, 56,148, 80, 91, 17, 30, 24,163, 32,158, 26,149, 34, 67, 77,195, 65, 6, 73, 3, +124, 46,140,147, 99,169, 42,162, 59,205,163,178,164,168,144,176, 38,105,104, 79,154, 8,120, 22,123, 41, 24, 75,230, 22,233,114, + 70,220, 15,162,242, 41, 24,223,241, 33,177,116,213,210, 53, 51,165,230, 53,253,205,157,165,205, 7, 37, 8,185, 30, 39, 75, 33, + 29, 97,162, 67,128, 68, 38, 85,209, 33,131, 65,241, 78,188, 95,134, 77, 81,244, 31,104,186, 4,137, 96, 42, 45,121, 32,141, 2, +156, 58,133,244, 77,195,237,122,240, 55, 15,154, 23, 71,149,234, 78,125,244,221,205, 31, 42,115, 85, 86, 56, 86,114,181,200,222, +115,245,242, 89,184,189,227,148,191, 85,123,149, 70,193,245,213,229,140,180, 94, 52,150,114, 69,137, 5, 29,206,135, 97, 20, 11, + 88,217,204,152,134,231,182, 58,184,110, 64,142,153, 69,148,236,197,243, 72, 24,201,157,222, 69,210, 67, 21,255,147,240,176,145, +109, 26, 49, 51, 33, 31, 65, 38,130,235,131,109,211,118,253, 65, 52,169, 88,200,121, 43, 63,240,251,216, 26,162, 38, 22, 46, 6, +193,170, 55,126,121,198,202,122, 68,173,161,202, 22, 14, 60, 10, 91,166, 32, 86,209,230, 22, 3, 77,128,184, 99, 29,213, 25,220, +199, 78,219, 30,218, 31, 49, 88,205, 24,118,151,247,112,127, 14, 82,221,163,236,212, 53, 20,218, 9,238,145, 54,193,169, 16, 91, + 68,112,152,181,231,218,174, 3,151, 96, 39, 9,179, 0,180,234,235,138,232,133,198, 26, 28,221, 13,152, 61, 32,178, 41, 32, 23, + 98, 82,120, 39,119,208, 56, 0,202, 87,108,163, 76,216,247, 44,165,232, 84,204,148,255, 83,194,255, 21,128,174,107,233, 77, 34, +138,194,243,100,134, 25,160, 3, 82, 74,171,214,214, 7,182,209,196,198,116,209, 84, 99, 98,234,198,157,233,175,112,105,226,127, +240, 87,152,248, 72,220, 26,141,175,173,209, 77,109, 98,180,214,174, 52,149,210, 23, 77, 41, 80,202, 60,128,121,120, 30,148, 82, + 27, 9, 11, 32, 48,129,203,189,247,124,247,156,239,124,159,116,226,249,177, 55, 67,200,135,117,216,221,152,251,222, 6, 75, 66, + 39, 4, 39,254,207,213,175,219,115, 42,250, 65,219,118,157,136, 60, 80, 35, 49,160, 95, 66, 65, 26,185, 58, 41, 86,146,224,164, + 91,208,165, 70,134, 61, 17, 75, 83, 55,241, 88, 77,140,235,197,223, 11,172, 43,108,104,113,204,119, 71, 98, 38,126, 74, 62, 60, + 2, 57, 45,199,197,106,158,216, 61,141,208,185,150,135, 7, 64, 1, 92,124,208, 26, 42,238,172, 29, 0, 18, 36, 38,165,143,244, +187,208,208,205, 7,119,239, 43,232,156, 42,155,122, 2,190,246,196,233, 66,210, 72, 16,131, 40,244,176,150, 29, 50, 85, 63,160, + 29, 98,169,184,156,181,114,140, 91, 45, 51, 13, 65, 27,176,125, 74, 75,166,140, 20, 3, 79, 88, 65, 0, 36, 55, 42, 91,229,250, + 38,160,212,128, 18,247,164,208, 67,116, 83,116,169, 85,171,205, 74,195,105,188, 92,124, 13,107,189,229, 69, 77, 27,105,128,172, + 73, 34,114,150,138,196, 25,200,112,131,220, 9, 66,185, 88, 42,195, 31,177, 86, 90,125,243,238,149,107, 55,105,140, 59, 2,149, +193,225,193,244,245,171,197,213, 95,213,234, 78,203,179, 97,255,105,108,175,109, 22, 75,219,149,131,239, 75, 43,239, 63,188,253, +244,249,227,227,167,207,124, 31,246,101, 13,181, 76, 21,100,208, 43,178,212,246, 66,219, 9, 28, 47,156,157,185, 49, 63,127,111, +229,231, 34,140,210,229,201,209,107, 83,227,115,119,110, 43,138,214,106,133,245,134,191,190,237, 6,148, 57, 81, 69, 0,124,138, +166,196,248,220, 27,147,244,158,103, 80, 60,150, 96,189, 90,185, 43, 99,139, 29, 98,196,123,129,125,195,133,145,217,179, 43,118, +235,160,143, 16,133,217,183,177,220,121,153, 30,199,208,230, 5,155,227,225,233, 86,109,221,243,155, 84, 74,145,168,167, 1, 73, + 80,201,120,186,231, 63, 74, 71, 7, 3,229, 65, 5, 9, 86, 87,111,250,149,247,119,120, 11,222,119,171,124,112, 70,178,185,162, +123, 29,155,214,182,122, 97,120,194, 71,203, 65,161,225,213, 20, 60, 27, 25, 88,188,161, 49, 39,230, 62,230,203, 51,137,193, 82, +229, 15,252,148, 1,195,202, 38,134, 44, 35,131,126, 79,129, 87,179,107, 93, 48, 18, 73, 92,124,128, 11,193,148,147,123, 60, 54, + 73,244,124,199, 39, 37, 81, 64,241,108, 46,125,228, 81, 77, 6, 16,240, 10,108,253, 10,102, 4,163,152, 34,103,204, 12, 71,160, +110,137,144,165, 14, 72,179, 5, 46,146, 54, 50,150, 97, 25, 42,118,222,227, 87,163, 38, 62,242, 19, 70, 42,112, 34,110,105,138, + 26, 87, 53, 89,138,229,101,237,225,205,201,185,233,209, 14,162,117,220,190,233,222,211,253,141, 96,100, 85, 64,229, 72,151,196, +113,230,238,160,128, 61, 95,147, 3,130,153,194,243,149, 16,170,220,207,170,200,100, 67, 22,214,203,187, 95,151, 55,126,248,103, +253,241, 25, 99,112, 76,142,153,104, 27, 35,168,186,172, 65,192, 75,103,115,103, 46, 22,134,175, 76, 85, 7,198, 95, 44,184,207, + 31,125, 41, 62,249, 6, 16, 64,184,117,233,220,108, 97, 52,143,172, 54,114,187, 67,190, 74,190,144, 27,137,235, 33, 5, 92,148, +173,215, 45, 64,196,228, 39,194,170, 29,108,244, 77, 4, 10, 38,158, 7,216,228, 72,222,117, 76, 58, 18, 59,228,113,134,211,169, +237, 29, 6, 66,254,120,180,231,238, 82, 37, 21,131, 19,146, 37, 80, 50,161,195, 86,217, 26,242,254,185, 66,142, 80,223,110, 55, + 71,210,249,110, 13,134, 42,183, 73, 61, 73, 82, 57, 72, 51, 37, 21,135,168,122,176, 7,151,200, 24, 89, 1, 85, 64,246, 89,100, +139,189,102,235, 54,138, 12, 74,125,245, 33, 0, 46, 0, 97,201, 56, 69,201,167,207,194, 63,171,235,102, 64, 84, 46, 74, 78,251, +110,187,213,103,208,114,196,115,116,176, 62,127,116, 51,245,148, 34, 41,255, 18, 38,121,226,112, 38, 74,224, 86, 33,156,252,237, + 19,237, 26,130,112, 92, 36,250,120,108,248, 43, 0, 89, 87,242,154, 70, 20,198,103,209,113, 70,163,198,154,198, 68,171, 81, 99, + 66,233, 78,105, 41,148, 64, 2, 45,133,144, 67, 47, 61,244,208,191,166,255, 78,233,161, 52,201, 41, 52,165, 33,208, 94, 90,200, + 82, 72,240, 18, 40,130,177, 90,151, 25,103,115,230,245,251,190,247,140, 9, 65,153,139,162,179,188,247,190,229,253,150,171,249, +187, 60,113,154, 20,198, 37,225,104,218, 64,227, 5,118,177, 59, 50,126, 99,207, 68, 88,100,201,215, 61,125,228,177, 91,158,248, +156,163, 59, 67,162,101, 73,194, 77,213, 27,185, 49, 77, 79,197, 51,129,248, 41,185, 56, 83,130,105,195,115, 43,120,121,190, 71, + 24, 27, 69,157,168,233, 35,215, 20,123,165, 44,128, 7, 22, 10, 1, 75, 30,144, 17,206,192,179,126, 85, 25,155, 23, 32,127, 4, + 37,216, 95, 63,219,104,245, 90, 14, 25,161,145,210,145, 52,147,204,166,244,196,246,175, 29,234,139,192,180,212,250,195,193,239, +198,233,187,213,183, 7,103, 7, 62, 9,235,146, 14,151,216,246,161,123, 60,178, 92, 59,159,201,119,172,182,174, 25,109,179,131, +120, 12,127,104,123, 54, 92, 79, 41, 91, 52, 93, 19,114, 56, 20, 68, 96,202,250,147, 87,245, 70, 29,206, 32, 12,101,157,188, 0, +225,142, 45,206,213,254,116, 27, 56,238,145,201,138,202, 4, 78, 52,192,121,167, 66,230,206, 12, 93,193,125, 95,140, 19,138,161, +161,198,223,196,144, 35,228,234,140,225, 66,185,112,255,246,210,207,253, 29,167,127,190,183,183, 11,131,105,109,245,249,195, 71, +143,115,185,217,114,117,241,251,183, 47,159, 62,126,216,218,220,180,135,166,161, 71,113,237,146, 34,150,227,199,141,116,181, 82, +219,255,113, 48, 24, 74,197,252,146,237,201,135, 39,117,114, 10, 9, 95,172,173,204, 23, 10, 95,119,119, 95,110,188,129,170,252, +248,240,184, 90, 93,254,188,181,141, 40,114, 63,180,253, 17, 20,149, 48,241, 93,199,229,148, 65,136,202,142,103,205,166,243, 67, +204,139, 49,237, 64, 93, 27,194, 65,144,198, 8, 23,186,194, 7,175,169, 26,247, 14,198,228, 48, 12, 18,218, 20,149,113, 34,250, +119,204, 54, 28, 83, 90, 18, 29,248, 24,187,212,131,134,133,123, 10, 86,213,139,220, 4,235,229, 75, 45,193, 41, 61,105,121, 24, + 45, 70, 28,117, 35,113, 87,104, 58, 42, 98, 27, 0, 41,110,140,205,103, 75, 84, 93, 97,159,183,103,253, 51, 52,131, 42, 60,212, + 29, 34,100, 87, 32,172,200, 20,110,137,164,216,174,197, 17,236, 80,207,197,181,120,199,106, 17,224, 33, 70, 88, 82, 9,106,124, + 35,134,154, 36,165,236,130,105,119, 47, 91, 61,240,179,226,148,119, 18,221, 12,199,124, 93, 49,114,144, 55, 16, 79,250, 62, 84, +132,216,225,133,154,216, 69, 71, 33,164,118,199,162, 49, 1,217, 36,184, 22,191, 34,184,183,142,135,162, 47,210, 88,214, 64,161, +136,167,146,228,117, 84, 13, 19,176,190,107,106, 82,146,223,191, 89, 41,175, 63,144, 76, 55,130,150, 91, 4,116,164,244, 93, 34, +117, 22, 5, 87,101, 4, 77,198, 17, 4,131,248, 50,196, 47, 32, 72, 16,130, 95, 68,202, 21,165,100,134,252,146, 67, 2,219,147, +154, 99, 16, 88,189,222, 73,189,209, 79,222,203, 87,150,135,150,231,249,216, 82,128,106, 79,165,244, 30, 98,110, 40, 71, 28, 15, +213, 97, 74,149, 82,161,152,155,186,145, 57,106,122, 71, 59,167, 21,149,105, 79,111, 25,233, 68,162,239, 90, 67,135,180,245,152, + 10,249,170, 47, 55, 59, 30,191,225,112,225, 56,114,152, 96,116,241,142, 58,103,153, 44,229,107,177,168,222, 49,187,119, 75,119, +220,145,111, 83,177, 62,246,102, 97,164,121, 39,114,115,225,248, 42, 11, 23,101,161, 96, 47, 26, 15, 2,113,143,219, 93,244, 49, + 76,161,218,220, 34, 4,140,102,247, 92,112, 83,149, 72, 58,145,110, 15,154,232,209, 32,220,210,101,248,235,242,108,249,175,217, + 66, 72, 62,215,216, 66,146, 93,252,102,106,110,224,245,197,232,163,238, 17, 71,246,140,255, 78,210,181, 68,163,115, 6,113,127, +232,152,104, 15, 0, 15, 20,245, 65, 73,140, 66,102,108,226, 33, 47,214,213,164,145, 38, 93,220,128,175,177,200, 38,161,170,130, + 77,216,189, 12,190, 67,160, 50,238, 31, 82,152,142,103,144, 81,142, 1, 70,186,232,153, 92,149,131,148,217, 53, 63, 16, 56,252, + 23,128,170,235,216,109, 34,138,162, 83,222,148, 55,205,221,105,114, 10, 11, 96, 17, 4, 40,128,132, 16, 72,172, 64,226, 23,248, +167,136, 15, 33, 11, 36,248, 3, 36,202, 38, 68, 8, 41, 9, 73, 20, 37, 33,197, 16,197, 99,123,170, 61,230,222,251,158, 29,103, +149,133, 99,107, 44,223,114,110, 59,103, 42,190,203, 18, 88,182, 68, 71, 99, 30,175, 88, 14, 4, 36, 77, 27, 60,175, 65,155,180, +104,211,166, 71,170, 14, 3,245, 38, 35,246, 88, 27,254,134, 70,137, 58, 25,160, 35, 19,192,192,231, 1,182, 47, 6,121, 70, 50, +140,226,173, 89,142, 11,183, 66, 42, 88,246, 31,167, 47, 34,228,167, 98, 76,247,237, 74,137, 7,241, 32,210,174,127, 81,165, 85, + 93, 4,136, 4, 25,130,192,142, 34,184,204, 68, 57,181,125,188,211, 79,163,167,183, 31,253, 9,219, 26, 85,229, 81, 22,133,113, + 15,219,179, 76, 7,180, 94, 9,170,113,150, 84,220,202,206,233, 1, 88,112, 47,141,176,114, 47,114,110,186, 81, 22, 11, 82, 33, +100,215, 24, 13,187, 81,119,105,102,185, 19,117, 90,181, 69, 72,167, 41,178,158, 97,194,233,196,189, 33,205,178, 70,121, 81,111, +182,234, 65,115,107,127, 11,138, 93,188,173, 55,236,185,234, 2, 36, 24,203,180, 86, 23, 87,247,254,238, 17,177,234, 16,156, 69, +113, 11,219, 32,176,133, 34, 15, 42,231, 10,119, 32,214,171, 54,211, 93, 71, 13, 92,205,119, 84,136,251, 68,177, 83, 88,214,200, +208, 7,187,219, 63, 55, 54, 62,108,110,110, 66, 2,242, 61,205,182,181, 7,207,222,172,220, 89,219,217,250,246,110,125,253,240, +248, 20,124,195, 48,145,224, 44, 75,139, 36, 25,118,123,105,185, 82,122,120,239,254,231, 47, 95,193,224,231,103,155,229,114,112, +176,191, 95, 45,115,139,161,134,162,142, 50, 44,233,147,231,175,207, 14,127,125,250,248,190,125,113,126,114,114, 98,153,162,181, + 12, 40, 72,111, 54,170,189, 94,156,101, 24,185, 0,125,184,102,233,162,219, 46,136,100,230,250, 40, 65,158, 13, 22, 0,231,135, + 52,110,193, 46, 28, 93,242, 8, 28,139,246, 58,153,223,140,183, 69,144, 21, 4,207,160, 6,211, 91,188, 35, 98,128,104, 4, 51, + 97, 28,106,234,141,177,156,197,144,203,140, 16,205,212, 88,114, 68, 58,166,228, 79, 88, 43,145,120, 58, 88,215, 85,255, 50, 77, +251,240,136,140, 25,146, 34,147,200,202,136,218, 68, 50,231,148,121,197,102, 78,150,139,142,141, 70, 92, 17,184, 59,110,234, 44, +195,230, 44, 22,254,147,237,137, 36,195,141,207, 30,249,127,213,173,193,147,104, 99,202,130, 1,185,159,176,122,211, 48, 29,203, + 3,248, 2, 5, 65,201,171, 64,157, 46,156,136,206,163,164, 34,188, 72,129, 89,129,199,160,194,182,231, 42, 11,140,153,128,165, +196,181,221, 92,121, 62, 78, 99,105,219,244,135,142,145,153,109,160, 12,147,103, 89,186,238,188, 90, 89,122,249,246,133, 18, 56, + 74,221, 85,194, 62,203, 7,133,208, 1, 35, 82, 56, 33,181,106, 51,230, 66, 94,178, 77,212, 88,207,145, 1,131,152, 65, 85, 14, + 85,107,235,150,226,123, 24, 49,114,100, 77,202,241, 53, 8,171,201,209,193,241,149,177,178,124,119, 45, 73, 0,215,115,110,115, +226,162,196,117, 4,226,250,192, 74, 14,119,111, 52,198,125,223, 9, 74, 22,247,103,103,106,204, 15,190,255, 56,227,191,207,170, +143,231,173,186, 7, 33,190,219, 79,112,173, 94, 81,131, 26,235, 31, 37,151,121,166, 75,125,105,177,138, 62,114, 77,238,217, 94, +132,240, 72,105,148, 27,187,167,123, 14, 15,192, 49, 47, 58,109,100, 39,165,161,171, 84,199, 30,207,204, 29,219, 71,201, 90, 65, +151, 81,200,240, 48,158,100, 76,248,165, 69, 56, 19,233, 30, 83,125, 45,168, 1, 32, 75,179, 84, 12,129,144, 7, 84, 99,142,229, + 34,140, 32,122, 96,248, 71,248,234, 97,220, 1, 16, 0,222, 24,240, 82,132,141, 32,180,200,127,225,249,112,188,154, 5,129,202, +181, 93,128, 99, 67,121,211, 71, 75, 96,100,216,164, 41,136,237, 31,156,216,225,221, 28,158,156,128,249, 3,112, 44,241,114,156, +247, 39, 18,196, 88,217, 23, 67,200, 4,114,104, 36,244, 90,166,142, 73,105, 5, 37,151,108, 8,184,103,220, 9,147, 14, 93, 17, + 10,129,215,209, 53, 53,244,205, 16, 63,233,162,107,227, 6,206,127, 1,168,186,150,158, 38,162, 40, 60,175, 78,135,233,208,153, + 14, 83, 30, 77,193, 6, 1, 19,130, 11,140, 11,127,132,134,159,231,150,157, 11,119,110, 12, 9,137,146,168,105, 76,140,162, 6, + 93, 24, 86,208, 66,155,210,199,116,222, 47,207, 57,247, 78,209, 29,133,244,150, 76,207, 61,207,239,251, 78,233,223,101,137,255, +138, 70, 76, 57, 66,145,115,167,214, 68,105,111, 26,247, 87, 43,168,165, 32,241,229, 49, 57,155,137, 50, 78, 16,228, 3, 85, 89, +163,125,164,249, 98, 69, 44,187,149, 76,157, 77,252,167,127,202,254, 6,207,228,201,246,179,145, 59,200, 72, 58,154, 17, 86, 51, + 4,213, 84,152,108,191, 84,150,189, 69,185,195,144, 80,106,108,133,181, 64, 70,156, 16,134, 49, 43, 87,102,227, 59, 32, 98, 7, +209,220, 54,108,112,202, 9, 26, 19,165,240,162,184,179,177, 3,229, 21,188,156,248,110, 74,220,197,246, 74,171,101,109,140,189, + 59, 20,118,193, 84, 61, 31,185,119,126, 18, 65,142, 6,167,245,199,125,210, 63,202,204,154,181, 98, 58,126,132,180,154,180, 96, + 12,102, 76, 34,224,180, 32, 12, 26, 53,219,170, 53, 32, 42, 64, 80, 97,157, 37, 72, 10,192, 62,116,221, 60,254,242,122, 83,221, + 58,125,255,182,101,173,143,252, 49,146, 69,130, 57,252,251, 81, 26, 95,222, 92,194,225, 7,237,131,158,123, 99, 87, 27,129,234, + 35,131, 54, 3, 99,144,226,168,152,121, 89, 76,164, 32, 69,172,196, 73,145,166, 74, 16,162,232, 18,142,169,149, 92, 83,139,233, +204,187,234, 13,208,151,224, 52, 86,153,185,217,207,243, 95, 75,114,246,104,127,239,213,241,203,235, 94, 15,174,159, 23,164,158, +151,250, 16,253,112, 55, 44, 14, 43,109,203,216,221,217,254,244,185, 11, 54,191,108, 24,157,206,230,197,197,133, 36,171, 66, 33, + 95,223, 12,191,157,127,127,241,252,168,179,247,184,123,118,210,237,126,236, 15,239,124, 63,139,195, 60, 76,216,118,167,188,105, + 45, 67,136, 26, 12,199,232,206,114, 25, 17,235, 73, 32, 8, 37,185,156,239, 41, 46,170,114, 21,158, 15,149,144,162,170, 44, 65, +204, 96,232, 96,169, 28,185, 47,216,106, 98,233,155, 41,115, 33,169,172, 60,167,171, 85, 41,168,249, 6,206, 17,167, 97,124, 17, +227,189,108, 54,107, 46, 75,139,158, 53,217, 24, 34,253, 21, 5,130, 11,100,138,124, 52, 89,160, 6,249, 97,231,233,196, 31,195, +197, 70,182, 42,165,210, 18,227,116, 80,119,123,197,112,224, 84,200,185,144,136, 36, 64,158, 11,247,176,145,230, 49, 18,169, 98, + 31,147, 71,210,168,225,213, 39, 41, 81,113,240,173,200, 43,229,130,207, 10, 9, 42,138, 78,196,177, 13, 7, 50,134, 16, 97, 40, +105, 38,164, 80, 16,204,131, 25,134, 1,178, 80, 2, 70,149,245, 47,124, 17,154, 25,227,122, 92,222,195,119,195, 25, 97,126,248, +196,213,195,149,111,121, 57,147,100,206,157, 43,201, 64,153,165,171,240,163,112,180,219,126, 32, 20,195,175, 83, 85,169,203, 45, + 69,152,250, 18, 92, 11,108, 47, 98,164,149,113, 43,175,180, 4,161,166,166, 87, 84, 25,156,127,128, 30, 14,119,246,162,127,175, +170,242,214, 67,161,166,161, 77, 71, 73, 17, 70, 81, 18, 71, 65,228, 78,167,131, 89,165,214,220,127,247,225,244,228,236,205,249, +143, 79,131,219,190,101, 56,182,237, 48,228, 10,182,112,112,117, 14, 36, 70, 72,127,181,154, 38,118, 57, 20,173, 86, 55,109,167, +241,231,214,207,126, 95, 53, 15,215,212,101, 93, 25, 7,243, 40,134, 7, 86,209, 84,113,158, 95,142, 92, 62,172,160,121, 21, 94, + 37,168, 17,177, 29,147, 50,186, 67, 24, 71,144, 59, 39,228,187, 85,181,218, 52,215,171,170,234,129,103, 20, 73,154, 10, 81,203, + 41,148,239, 41,117, 27, 33, 48,163, 82, 27, 9,181, 66, 0,168,107,117,100, 24,164,169,169, 91, 8,162,165,250,157,173, 48,132, +103, 72, 21, 67,177,102,174,121,177, 7,137,215, 28,190,244, 44,129,160, 14, 31, 91,215, 77,145,186, 17, 18, 77,108,225,134,194, + 33, 1, 65,119, 86,173,213, 89,232,182,157, 77, 91,111, 76,252, 41, 99,122,162, 4, 31,250,189,130, 9, 72,232,154, 65,237, 55, + 30,138, 74,216, 62, 87,245, 87,177,248, 75,224, 67,185,155, 98,249, 41,153,175,105,216,126, 56, 43,238,251, 31, 92,208, 95, 42, +229, 3, 36, 46,135, 84,178,128, 81, 40,216,108, 89,173,177, 63, 17, 23,187,123,185, 91, 47,254, 39,132,222, 59,253,191, 2,208, +117,117,173, 77,131, 81, 56,201,154,164,105,154,118,109, 89, 29,126, 76,246,129, 50, 21,153, 94, 14,245, 63,120, 35,236, 15, 8, + 94,250,119, 4, 47,132, 93, 8, 42, 3, 21,197, 59, 17, 65,157, 40,162, 55, 34,179, 78,152,110,237,218,217, 54,205, 71,147,165, +245, 57,231, 52,173, 10,178,203,134, 54, 75,222,247,156,231,188,231, 57,207, 51,138,239, 76, 25, 30, 57,173,150,157,178,157,113, +116,213,232, 69,110,201,169,132,220, 16, 75,148,177, 54, 20,239, 29,146,160,211, 67,170, 44, 98,236, 7, 60,211, 30,223, 43,123, + 21,146,134, 87,194,195,234,197, 92,201, 36, 36,100,144, 67,113,170,125, 39, 41, 10, 96, 86,244,161,100,151,159, 58,122, 6,251, +176,235,119,132, 74,153,250,204,210,241, 55, 42, 95,236,127, 98,164, 18,173, 56,195, 19,182,177,100,151,105, 34, 56,247,165,166, +230,161,237, 65, 37, 95, 5,122, 98, 51, 85,150,175, 83,229,156,135, 86, 61,233,240, 37,135,172,140, 61,236, 6,238,126,239,128, + 87, 6, 74, 33,167,236, 84, 58, 62,238,127,232, 6,189,182,223, 21,115, 59,124, 10,200,223,112,155,168, 40,147, 84, 5,157, 71, +109,213,188,149,239, 39, 81,219,111,211,157, 48,153,118,110,230,100,163,221,196, 74, 13, 81, 22,184,110,166,110,220,219, 88,175, + 55,119, 45,211, 66, 41, 80, 45,206,180,189, 14,247,202, 8,137, 37,234, 16, 9,249,194,194, 74,173,190, 21, 89, 88,233,180,247, +240,197,200, 33, 94, 72, 2,219,184,198, 70, 37,172,107, 89,162, 58,168,128,108,200,173, 94,128,250, 94,101, 37, 24, 69, 4,190, +241,195,253,176, 95,173,206, 94,191,113,243,217,227, 39,235,119, 31,224,169, 3,216, 17,190, 97, 85, 35,158,103, 65,104, 64,101, + 96,174,174, 94,222,250,186,195,222, 56,250,194,252,210,235,183,239, 81,135,229, 44, 61,155, 81, 80,186, 95, 91, 91,115,202,179, +143,238,223,110,236,183, 16, 25,186,189,164,219, 11,163,136,138,124, 11,193, 35,111, 44, 46,204,127,248,244, 25, 56, 32, 97, 87, + 40,203, 44,138,117,171, 76,146,103, 77, 27,187, 2, 48,177,236,204, 80,147,131, 26,212,241,164,218,156,244,252,255,242,137, 20, + 28, 50, 16, 19, 23,133, 6,193, 89,149, 91,236,130, 84, 49,164, 22, 2, 44, 89,245,210, 57, 70, 98,167,196,170,113,187,149, 38, + 40,213, 76, 66, 11, 76, 33,221, 55,154,216, 80,216,169,194, 32, 33, 82, 62,204,229, 86, 88, 46, 58, 12, 12, 35, 7, 76,101,160, + 38,161, 81,172, 0,129, 64, 27, 53,219,232,119, 8,190,210,236,104,130,220, 32,193, 87, 77, 77,146, 85, 65, 27,169,180, 44,246, +139, 99,230,185, 53, 71,120,176,100, 87,112, 93, 16,135, 62,254, 88,148,138, 91,187, 37,230,200,143,244,161, 6, 92, 99,140,121, +163,248,146,104,208, 79,255, 17, 22,117, 99,105,166, 63,140, 59, 39, 98, 37, 83,163,131, 39,226,249,233,212, 5,209,179,186,142, +108,122,245,244,113,211,156,126, 21,206,125,175,199,139, 23,109,165,211,209, 66,194,232, 72,255, 42,211,139, 45,221,112,108,203, +206,155,164, 83, 29,197, 33, 66, 26,249,224, 17,160,193, 67,200, 30,155, 87, 10, 22,221, 77, 24, 37, 94,216, 11,251,190,231,183, + 90,237,151, 31,183,239, 60,188,245,116,243,249,222,110,173,246,163,182,249,229,221,139, 55, 27,135, 94,188,188,116,222, 48,116, +226,182,224, 46,100,184,100, 42, 83,174,148, 84, 68, 3,234,203,224,182,140, 98,161,184,189,231, 26,223,126, 78,175, 28,177,180, +169,168,233, 1, 99,224, 82,203,208, 26,187,253,128, 61, 11, 69,255, 99,100,241, 49,136,197,248, 49,136,253,148, 75, 61,148, 51, +119, 55, 32,110, 34,182,152,172,118,209, 79,185,116,238,202, 78,107, 7, 11,131,130, 15,193,229,129,244,216,151, 79,156,109,145, + 12, 25, 69, 12,110,162, 18,121, 26,249, 30,181,172, 70,170,221, 67, 64,213,182,215, 6,104, 11,248, 4,120,140, 26,144,213, 16, + 55,240,166,176, 84,144, 33, 44,211,166, 19, 54,230,227, 39, 36,116, 17, 3, 1,136,139,186,198, 90,107,114,184, 47,156,113,124, + 45, 46,102,149, 40,122,129, 5,171, 0, 36, 39,218,117,242,146,241,144,165, 91, 60,118, 93,157,216,177, 34,166,113,118,215, 38, +248,101,168,254,203,165,210,152,104, 53, 90, 51,168,237,126,249, 7,169, 81,251,144, 91, 26, 42,201,227, 12, 6,255,235,175,254, + 22,128,173,107,217,105, 34, 10,195,103,166,237,180,165, 55,108,167, 80, 42, 24, 93,152,152,152,136,151,196,248, 4, 68,195,198, +196,240, 2, 38, 93,200,187, 16, 31, 64, 55, 62,134,174,221,224,194, 13, 59,144, 40, 10, 1,132, 10,165, 51,157,153, 51, 76,199, +255,251,206,180, 16, 99,151, 77,154,105,207,233,249,207,127,249, 46, 6,255,174, 76,131,223,124,111,249,143,206, 53, 58,160,107, +142,254, 4, 24,104,144, 9,148,249, 81,101,227, 92,169,143, 22, 90, 75,247,151,150,247, 79,247,228, 94,245,177,100,120, 82,158, + 87, 40,252,153, 56,227, 25, 70, 67,234,244, 22, 34,249, 43,103, 4,191,172, 53,111,212,156,205, 89,150, 95,215,247, 78,189, 96, + 96, 77,212,242, 12, 19, 70,178,170,123,139, 15, 46, 70,231,240,109,161, 54,180,241,104,132, 44, 42,148, 14, 44,139, 18,229, 83, +160,164, 57, 99, 97, 24, 80, 40,216,244,229,121,145, 38,180,196,184, 2, 40,216,134,149, 88,159,169,119,155,221,253,254,193, 0, +174,190, 9, 13,101,104, 62,106,228,141,232,176,110,140,126, 19,195,204, 33,254,182,235, 46, 29, 15,142,186, 55, 22,229, 34, 60, + 60, 63, 6,225,139,107, 40,101,148, 60,172, 85,109,251,241,240,219,238,246,225,201,129,196,125, 13,233,234, 40,129,215,159,164, +229,227,188, 4, 41, 8,163,198,242,166,142, 37,191,246,115, 85, 91,142, 92, 16,226,224,197,116, 97,149, 71,150,115, 5, 59,177, +131, 16,114,160, 28, 62, 89, 64, 98,130,244,148,146,175, 36,233, 76, 74, 91, 75,132,254, 94,175, 39, 27,184,177,241,246,201,242, +163,223, 71,135,100, 0,193,229, 76,138,192, 88, 67, 36, 82,162,180,148,183,235,111,214, 87,158,175,172,189,122,185,186,250,226, + 50,242, 55,191,108,150,138, 80,231, 25, 5,122,161, 61,191,246,186,167,146,248,195,187,247,167,195,136,170, 39,137, 99, 65,140, +204,248, 69,215, 75,229,208,215,223, 15,142, 11,185, 34, 74,248, 52, 9, 37, 56,210,199, 47, 7, 58,130, 38,107, 61,149,128, 40, +215,188, 61, 5,125, 41,235,223,201, 79,102,114,112,229, 15, 99,224,184, 25,192,156,164, 52,211, 75,181, 1, 81,167,212,140,217, + 68,131,141, 27, 27, 70, 66,134, 21,158, 98,106,208, 20,101, 65, 78,110, 39,199, 0, 41, 33, 26, 25,136, 6,123, 39,113,132,252, + 17,238, 38,202,252, 42,143, 8, 18,173, 10,198, 98,148,228,103, 22,102, 24,115, 16,219,201,108, 87, 45,186,208,228,209,136,191, +212,110, 99, 14,109,122,112, 38,100,109, 35, 34,187,211, 80,135, 84,204, 71, 2,200,134, 46,102,133,146,191,199, 64,218, 33, 49, +234,204, 46, 32, 16,144,130, 55,105, 58,102, 74, 74, 83, 60, 36,137, 84,169, 91,107,201,131, 36,112,202, 57, 42, 21,102, 42,165, + 42,251,159, 99,118,141,145,188, 3,233, 40,215,149,228, 87,182,253,208,117,227,249,167,103,170,232,249,250, 86,209,118,218,137, +234,123,212,151, 67, 61, 41,187, 91,147,207,183,154,170, 82, 73,130,192,151,244, 88,195,230, 20,224, 73, 84,132,249, 70,231, 22, +122, 59,121,248, 15, 36,146,218,248,158, 55, 28,109,109,239,126,252,252,105,172,189,187, 85,117,167,162,186,101,213,114,148, 36, + 56, 95,119,182, 36,183,127,188,252,204, 41, 65,210,192, 41, 74,177, 93,112,138,133,102,167,105,177, 1,192, 97, 38,152,211,245, +217,250,175,253,243,219,174,165,110, 86,157,254, 40,136,228, 18, 85,165,114,238,199,206,217, 64,170,103, 72, 22, 59,178,193, 92, +112, 0,101, 19,101,186,255,116,145, 36, 99,156,106, 9, 64, 27,104,254, 20,219,136, 24, 0,111,152,255,121,178,135, 11,152,158, + 80,234, 90,230,112,114,118, 68, 66, 30, 91,187,180, 26,180,193,134,141,178,105,144, 69,109, 44,170, 21,155, 40, 36, 65, 73,214, + 6,165, 67,154, 56,128, 34,231,155, 21,247, 34,186,136, 36,226,217,202,173,181,189,200, 67,155,209,100,228, 25,172,111, 74,213, + 55,208, 62,188,218,213,182,212,253,181, 82, 13, 44, 54, 73, 70,203, 13,109, 28, 92,137,136,209,176, 86,152,106, 40, 88,215,221, +190, 0, 64,152, 68,115,217,127, 41, 17, 66, 72,128,164,153, 15,150,202,132,235,211, 73,119,114, 2,106,156, 74,101, 88,156,195, +183, 2, 61, 50,114, 61,255, 13,241,127, 5, 96,235,106,122,147,136,162,232,227, 49,204, 12, 51,211,118,248, 42, 5,164,105,180, + 54,145,106,131, 38,134,133, 43,247, 46, 76,220,248, 35, 76,140,191,199,141, 43,255,137, 46,140,214,180,150, 38,141,245,139, 38, +181, 84, 11, 5,166,101, 96, 96,198,115,239, 27,104, 23,238, 8, 4,120, 3,111,238, 61,231,190,123,207,137,231,155,144,103, 56, +125,176, 57,125, 66,254,241,218,253, 97, 79,157, 67,198,234, 31,154,201, 57, 70,181, 45, 83,226, 2, 9,253,121,122,168, 14,168, + 85,120,157,178,186,167, 20,170, 37,134,138, 27,212,100,171,233,158, 26,216, 19, 87, 77,158,241,199,206,201, 39, 87, 81,164, 84, +254,153,196,221,238,173,213,255,246,218,248,228,211,193,201, 56,244,149,142,126,110,177,176, 94,220, 64, 4, 9,227,226,105,130, +143,239,184,251, 88,200,226,194, 50, 40, 51,195,177,216, 26, 88,217, 79, 38, 99,255,200,120, 74, 69, 77, 42, 82, 64,160,163,116, + 29, 41,125,204, 54,163,248, 31, 12,195, 74, 50, 13,224, 81, 69, 10,205, 74,115, 3,136, 9,191,242,132, 27, 91, 56, 4, 32,194, +130,129,143,184,188, 67, 78, 14,141,219, 15,247,142,246,241,233,229, 92, 37,183,152,235,120, 93,106, 12,151,124,120,195,176, 52, + 96,233, 43, 46, 11,132,192, 17,181,242,221,206,144,138, 54, 41,161, 57, 57, 82,254,179,245,148,107,107,118, 90, 51,116,194, 69, + 5,199,112,211,154,153, 78, 0, 59,107,106,136, 82,163, 11,209,245, 4,110,125, 83, 23, 6,249, 83,137,225,229,164,241,160,241, +244,217,115, 44,233,119,235,240,213,203, 23,159, 62,188,239,116,123, 8, 8, 36, 62, 18, 34,190, 83, 95,103, 0,242, 29,140,191, +127,107,110,127,124,247,121,251,195,254,222,238,206,238,206,233,217, 9,136,118, 48,137, 6,151,254,253,250,214,163,199, 79, 90, + 95,155,175,223,188, 21, 83, 32,116,174,112,130,200,143, 40, 18,128,136, 47,187,246,193,143, 99,207,243,233, 28,140, 42,131,236, +191,205, 73,250,230,202, 70,103,112,230,152,139, 83,134,213,243,121,107,121,205,168,108,230,235, 75,219, 51, 99,129,114, 13,101, + 98,174, 36, 70,197,230,162, 91,194,237, 1,124, 16,177, 43,167,242, 70,228,189,148, 76,204,149,153, 88,159, 11, 8,157,212, 90, + 98,143, 30, 2,181, 36, 24, 74, 35,157,186,150,164,131,208, 52,217,106, 83, 9,154, 93,230, 98,157, 3,186,221,166, 32,203, 26, + 47,155,222, 9,212, 70, 34,208,188,155, 3,182,132,195,106,182, 86,235,237,243,246,204, 36,116,134,181,120,233,160,107,150,158, + 70,132,164,169, 99,174,183, 42,103, 78,169,148,179,153, 67,227,187,242, 86,214, 15,134, 50,238,112, 87,170,120,130, 56, 7,210, +249,132,166,228, 64, 82,177,212, 48, 12,226,254, 46, 78,118, 75,142, 27, 4,160,194,178,146,171,244,188, 30, 16, 3, 21, 30, 37, +117,104,240,209, 46, 65,191,149, 76,197,247, 47,116,226, 37, 18,123,128, 26, 35,197,216,180, 75,197,141,134,146, 42, 58, 58,234, +222,186,227,136, 78,151,108, 30, 39,202, 97, 92, 91, 42,228,197,218,186,176, 50, 81, 31,172,178, 79,109,144, 1,231, 49, 2, 44, +114,185, 80, 22,238, 2, 54, 19, 46,111,114,238,117,186, 94,167,215,255,210,220,151,189,227,170, 41,138,186,112,146, 34,155, 20, +153,148,112, 52,234,214,106,182, 14, 86,243,213,205,205, 58,126,114,211, 48, 12, 92,140,153,202,151,243, 0, 26,164, 66,147, 34, + 73, 98, 60, 80,179,223, 23,173,227,108,109, 81,243,195,160, 79,248,198,116, 82,178, 45,127,245,251, 81,252,239, 78,184,222, 66, +227,226, 35,110,137,197,147,181,234, 38, 94,245,134, 23,165,108,201, 15,124,236,178,106,246,134,101,226, 58,244, 17,121,168, 70, +120,140,111,168,173,214,122,151, 93,130, 26,216,172, 73, 82,185, 47,185,101, 0, 14, 29,137, 67, 36, 42,217, 42, 53,173,241, 96, +110, 90, 79,187,118,102,193,118,145,173, 45,221,177, 13, 11,225, 91,249,176,177, 43, 9, 13, 84,134,124,242, 15, 66,143,224, 30, +241,198,194, 74,188,177,199,172, 45, 17,198,254,124,241,177,144,194, 25,177,134, 50,151, 96,176, 78,188,142,251, 43,191, 84, 24, + 12,207, 71,227,145, 98,120, 92,188,137,102, 10,166,209,108,198, 73, 70, 87,250,210,242, 58,151, 13,194, 64, 9,177,204,184, 43, +189,135, 6, 31, 89,183,252,122,219,228, 92, 62,128,203,244,196, 56,103, 5,153,255,132,248,127, 2,176,117, 45,189, 77, 92, 81, +248,204,219,158, 71,252, 72, 66, 76, 75, 66, 64, 32,209, 69,133,248, 21, 21, 18,139,254,129,254,182,110,186,169,212, 29, 59, 84, + 85,138,186,104,203,162, 5, 17,243, 20, 41,216, 50,193,118,156,120,198, 30,143, 51, 79,206,119,174, 93,211,170, 94, 89,214,245, +216,154,123,231, 60,191,243,125,107,126, 49,109, 37, 30,159,230,203,150,191,237,151, 62, 90, 91,104,104,168, 18, 74, 5,110,113, +153,181, 67, 19, 92, 28, 42,175, 20,159,173,229,194,125,179, 1,210, 32, 7,208,191,186,246,245,235,211, 23, 8, 61,132, 95,205, + 88, 59,192,134,215,142, 22,147,138, 20,227,213,255, 72,184, 93,109, 95, 27,156,247,223,141, 78,248,103,120,171, 6,103, 61, 60, + 57, 48,142,229, 56, 26,205, 22,145,194,144, 26,250,198,137, 73,163,210, 25,206,134, 8,112,196, 32, 40,135, 43, 20,216,156,118, +101,186,129,127, 93, 72, 72, 32,250, 93, 28, 85, 65, 34,195,175, 5, 56, 70, 40,111,147,136, 46, 1,156, 22, 46, 67,199,112, 17, + 12,150, 34, 98,196, 6, 61, 67,205, 93,148,236,202, 78,243,139, 81,248, 49, 7, 37, 90,170, 58,105, 28,187, 29, 61, 63,194, 64, +141, 97,244,206,122,253, 73, 95,152, 51,203, 27,123,135,227,232,140,143, 90,165,175,105, 38,138,210,174,187, 55,246,110,190, 62, +125,169, 73, 73,149, 47, 31,120,134,121, 73,162, 84,162,131,250,122,169,103, 40, 53,136,142, 43,242,113, 80,132,107,162, 25, 2, +246, 87,176, 82, 81, 89, 24, 80,106,202,137,227,239,251, 15, 30,208,150,247,244,231,135, 39,175,142,127,252,225,251, 40, 60,183, + 1,104, 65,128, 79, 96, 56, 42, 37, 89, 97, 27,166, 61,126,220,205,114, 16,174,114,228,199,143,165,101,161, 31,105,154,101, 43, +208,238,221,189, 77,148,119,255,250,163,110, 23,205,134,133,110, 82,165,205, 33, 81,136, 52,180, 81,183,122,253,241,240, 44,228, +221,230, 7,194, 49,253,182, 31,156,158, 15,212,126,157, 12, 95,234,168,185, 47,215,140, 5,176,146,207,122, 79,148,101,231, 52, + 46,175, 82,215,242,132, 46, 24,166,188,229,239,134, 34,181,195,222,197,119, 26,211, 4,232, 85, 96,105, 48,234,194, 71,165, 86, +228,201,126,251, 32,168,251,221, 65, 87,129,219,235, 70,157,141,166,132, 3, 70,188,156, 87,171, 82,190,161,124,120, 9,212,252, +117,206,168,112, 12, 76,199,181, 93, 94,220,240, 90, 36,181, 84, 1, 56,115, 18,157,221,238,220,121, 59,124, 35, 0, 68,165, 9, + 93,124,217, 60,232, 79,222,123, 82,253,195,220,121, 50,189,136, 39, 34,129,254, 25, 2, 65,206, 23,202, 16,101, 17, 39, 51,215, +113,107, 22, 91,249,197,127,244,167,248, 78,242,117,210, 44,229,167,212, 4,127, 16, 85, 50,214, 43,180, 83,186, 80, 36, 42, 61, + 38, 29, 58, 55,180, 34,229, 3,245,102,150,186, 78, 61,135,120, 12,210, 8, 76,115,102,169,169,235, 27, 48,157, 4,102,166,102, + 39,201, 76, 87, 69, 89,169,237,130,230, 90,175, 58,251,247, 40,215,127,251,253,209,175,127, 62,250,123, 48,184,187,253,221,149, + 78,163,186,152,242,150,219,164, 5,190, 71,183,238,208,222, 85, 10, 23,228,120,176,170,165, 16,132,201,249,172,170,100, 54, 13, +131,248, 10, 5, 14, 16,245,134,158,166,249,197,252,178, 76,162, 67,151, 70, 41,117, 99,138, 75,234, 88,116,224,208, 33,186,179, +180, 56,167, 95,142,126,186,255,205,183,190, 7, 67,110, 24,166,205,129,175,111, 25,153,240, 0, 35,181,178,103,147,104, 57,143, + 91, 59,205,241,208,166,241,156,154,206,214, 86,173,140,216,221,146,229,150, 74,242, 59, 85, 44,191,202, 99, 11, 91,167, 34,188, +234,246,143,129, 91, 37,146,121,117, 24,187, 15, 23, 31,212,200, 52,111,193,254,238,117,206,129, 78,198,239,158,189, 63, 14, 92, + 95,137, 42,241,125,168,244,149,124, 2,191,248, 6, 38,105,204,161,216,174,183,147, 92,162, 86,198, 55,191,237,111, 3,215, 75, +213, 52, 14,149, 20,153,154, 87,201, 87,154,241,154, 16, 10,225,114, 74, 9,100, 37,115, 32,229, 32,173,248, 71,181, 27,111, 56, +198,199,224,231,229, 98,141, 30, 65,161, 96, 43,216,153, 68, 35,249, 10,155,211, 98,183,177,247,113,122,186,158, 9, 81, 36,196, + 90,189,230, 45, 68, 53,140, 87,181,189,150,234,252,125,166,184,161, 41,156,220,191,133, 16,212,135,202, 88,170,225,146,106, 29, + 18,168,113, 10,140,191, 2, 51,187,161,137,223,172, 81,175, 79, 2, 80,117, 45, 61, 77, 68, 81,248,118,166,243,232,148,182, 52, +165,181,160,242, 48,162, 70,130, 49, 49,241,129,129,133,113,131,196,196,196,165, 63,205,173, 11, 93,152,128, 49,184, 51,209, 31, +225,194,196,160, 73, 11, 22,166,116, 58,109,167, 51,157,151,231, 59,119, 90,132, 13, 11,202,164,119,238,189,231,124,231,245,125, + 25,126, 39,216, 46,135,191,105,125,228, 9,253,216, 71,115, 55,115,207,211,103, 13, 52,228, 83,164, 52, 97,210,183,228,241,237, + 45, 2, 17, 24,227,156, 21,124, 47,228, 8,178, 12, 59,161,239, 4,170,214, 42,219, 23,166, 45, 97,249,163,128, 46,106, 78, 89, +173,223, 24, 5, 67, 73, 53,148,205,243, 66, 15, 8, 46,215,245, 28,122, 24, 15,178,211,177,116, 96, 1, 11, 21, 16, 30, 68, 44, +160, 40,117,146,224, 74, 17,163, 77,153, 65,114,203, 11, 43,100,106,233,123,176, 55,131, 5,200,243, 95,185,210,141,236,146, 1, + 50, 19,169,252, 12,163,179,117,235, 81,144, 76,154,243, 77,123,208, 11,208, 7, 8,211, 74, 55,173,227,156,166, 76, 98, 62,192, +188,156,104, 86,155,253,145, 27, 34, 75,160, 88, 5, 56, 3,122, 57,141,106,147, 30, 85, 43,213,153,107, 69, 16,172,227, 17, 86, + 85, 76, 41, 89,232, 93,189,222,125,115,110,219,221, 65, 55,100,181,144, 76,137, 0,225,103, 2, 66,243,145, 35,157, 52, 72,227, + 82,244,169, 88,121,101,174,144, 43, 91,106,205,210, 23, 10, 90,137, 34,223,148, 32, 56, 6,108, 84,120,154, 52,152,224,246,140, +125,208, 56,122,180, 61, 62,132, 82, 9,183, 45, 53,234,223, 62, 31,190,255,240,177,239,248, 71,191, 91,161, 63,209,201, 24,228, + 17, 5, 17,202, 76,226,148,214,134,176, 76,215, 10,134,129,112, 74,203, 91,134,166,179,222,166,101, 40,150,169, 20, 11,218,253, +205,123,213,114,241,211,193,254,223,147,179, 56,201,141,199,225,104, 4,236, 8, 6, 90, 58, 3, 65,114,124,234,130,173, 1,201, +236, 56,224,202,103, 58,147, 69,224,180, 40, 55,133,147,133, 42, 83,212, 73,254, 47,171, 76,178, 58, 7, 29,193,197,249, 69,215, +235, 19,218,163,149,118,135,103, 92,246,198,191, 32, 7,194,232, 38, 19, 8, 2, 84, 65,204,238,120, 61, 92, 24,110,129,215, 21, + 61,201, 18,235, 62,155,209, 57, 48,120, 72, 94,124,180,114, 25, 18, 43,143, 97,247, 69,189,210, 24,250,131,152,121, 20,198, 96, +248,202, 49, 45,137, 70, 47,254,230,181,187,109,251, 79,185, 0, 40, 39,231,140, 40,230,240, 3,175, 86,106,184, 94, 79,102, 99, + 64, 35, 49, 27, 40,204, 82, 40,216, 83, 29,189, 34,122,196, 18,208, 62, 52,219,114,211,153,147,105, 58, 93, 65,251, 9, 34,155, + 52,101,121, 38,112,252, 78,226, 40, 39, 46,244, 45,100,200,146, 71,167,191, 34,129, 28, 20, 95, 16, 30, 17, 68, 64, 67,142,174, +106,163, 96,144, 74,238,164,116,218, 54,192, 87,153, 32,191, 9, 42,136, 80, 38,229,116,168, 96, 71, 75,149,165,103, 79, 95,237, +127,121,123,248,245,157,240,122,209, 36, 94, 55,146,245, 39,155,225, 73,143, 94, 39,218,108, 86,215,196,250, 29,193,141, 7,169, + 59,232,219, 29, 2,246, 56,234, 81,102,232,205, 98,165, 82,158, 23,101, 83,232,121,197, 25,159,218,189, 86,215,241, 78,142,194, +177,123, 96,139,239, 67,241, 51, 16,109, 31,248,125,153, 66, 70, 85,248,169,104,245,236,231,219,123, 87,174, 46,162,190, 97,106, +197,242, 92,190,105, 9, 45, 39, 76,132, 48,177, 59,242,122, 3,218, 70, 93, 3,121, 67,197,239,168, 69, 67, 29, 71, 50,195,236, +159,135, 63,142,187,220,236,203,213, 51,102, 27,163,144, 40, 22, 18,160,162, 79, 6,217, 69,108, 44, 14, 79,173, 84,165,239,219, + 40, 55, 34,150,114,162,219,167,171, 6,249,236, 23, 15,118,219,118, 59, 8, 3,147, 64, 39,183,150,122,129,103,230,245,149,250, +154, 59,116, 94, 62,220,107, 84, 26,191, 58, 71,244,148,157,141,237,162,129,254, 55, 58, 69,219, 27, 59,173,243, 99,218,145,235, + 11,171,116,121, 48, 41,153, 69, 80,136, 35,100, 22,134, 54,187,106, 85, 67, 86,127, 21,210,239,112,150, 47,107,202,196,236, 69, +129, 92,120,132,250,109,134, 88, 33,135, 25,121,244, 11, 52, 53, 0,248, 42,228, 7, 6, 93, 44,135, 63,193,105, 55,204, 82,177, + 98, 23, 78,148,169, 27,180, 22, 67, 51,185,126,147,136,105,162, 82, 54, 11,208, 70, 71, 40, 22, 10,217, 72,194,142, 70, 26,248, +244, 18,138,159,229, 65, 46, 55,166,139,255,146, 65,244,243, 79, 0,174,174,172,167,137, 40,140,222,206, 76, 59,157,173, 29,218, + 34,155,134, 4,226, 18,136, 91, 66,140,198, 68, 77,244, 39,250, 75,124,225,197, 68,223,125, 49, 6, 98,128, 34,224, 82, 90, 40, +116,153,105, 59,251,120,190,239, 14, 66,124,234, 75,211,229,222,249,246,243,157,115,229,223,181, 42,108,108,181,181, 6,255, 91, +102,146, 69,110,231,135,146,152, 23, 86, 20, 38, 83,167,226,160,138,108,213, 22,142,187,237,115,175, 79,217, 86, 46,120,166,175, + 71,105, 49, 41,146,160,209, 2,137, 92, 82,224, 85,100,100, 97, 78, 27,181,110,186,168,143, 96, 45, 23,227,243,171,226,149,140, +152,229,211, 40,189, 70,106,153,114,179, 95,246,219, 96, 81, 43, 77,154, 23,203,173, 51, 84, 91,146,170,105,125,241, 30, 2,160, +228,245,144, 50, 61, 67, 31,239, 17, 46,241, 53,147,200,156, 93,181,158,221,125,113,116,254, 67, 50,246,231,180,234, 82,150,196, +205,188,217,144,217,134,229, 5, 19,159,138, 50,223,181,231, 42,196,125, 87,245,130,105,148, 33,123,130,249, 84,184, 60, 76,189, +217,132, 86,213,249,240,113, 43, 83,164, 6,121,230, 79, 71,248,181,126, 56,129, 53,162,124,134, 97, 35,145, 73, 57, 43,194, 31, +178, 13, 26,199,127,221,251, 18,132, 33,177,137,165, 57,190, 75,106, 89, 51,191, 40,169,220, 25, 58, 65,181,248, 9, 81,212,204, +246, 71, 65, 22,168,217, 68, 77, 38,106, 30,169,150, 98,186,102,181,229, 24,174,105,204,219, 53,167,108,234,153,102,171,106, 77, +168, 53, 77, 51, 53, 21,159,169, 22,180, 14,226,240,160,253,125,127, 15,255,209,173,233,101, 98,114,204,202,196,180,149,197,112, +135,248,101, 17,169, 20, 51, 94,162, 24,107, 32,136, 86, 53, 56, 98,197, 33,163,166,200,225,123,201,238,206,193,231,143,159,246, +219, 71,120,174, 16, 66,152, 95, 39,215,149,188,105,106,149,114,246,171, 27,205,224,213, 83, 22, 29, 47, 4, 43,201, 79,225,124, +224,118,169,129,131, 50,137, 53, 68,168,218,227, 59, 81,139, 29,110, 65, 28,112,165,156, 6,101, 66, 24, 85, 68, 22,226, 81,226, +124,185, 4,247, 74,124,153, 92,237, 62, 94,125,210, 27,117,138,157,242,127,188,205, 40,217, 56,166,220,114,151,225,218, 96,144, + 20,230,113,226, 68,132, 71,128, 57, 9,204, 37,244, 71, 20,216, 70, 13, 39,188, 58,191,214, 29,116, 72,183, 11, 70, 18,199, 86, +197,194,215, 17,171, 84,150,246, 70,167,120,186, 54,111, 63,234, 13, 58,220,192,163,245, 99, 36,227,195,201, 64,194, 10,168,175, +173,233,248, 76, 71,183, 97,254,215,205, 37,133,213,159, 83, 90,117, 94,106, 44,251,129,175,144,116, 6,193, 31, 37,253, 17,227, + 49,105,162,131,211, 32, 97, 3,150,167, 64,182,193, 16,230,144, 91,252, 66, 41,166, 17,202, 21,171,185,224, 85, 88, 98,221,136, + 25,146,207,102,146, 85, 52,157, 3, 37, 5,118,141,250,118,100,212,164,229, 77, 13,141,152, 54,149,144, 50,243, 18, 19, 30,130, + 87,155,175,147, 52,248,176,253,126,195, 22, 15, 92,209, 44, 11, 45,154,109,189,125,153,245,250,112, 42,182, 99,137,167, 91,162, + 94, 39,142,129,105,146,121,254,176,127, 26, 20,248, 72,169,171,158,149,202, 70,163,214, 80, 77, 67,212, 77, 98,221, 60, 27, 29, +246,250,227,139,238, 81,127,184, 61, 22, 18,125,237,113,205,254,208, 18,150, 42,166,153,232,120,226,205,243,119,235, 27,247, 81, + 27,234,112, 81, 11,117, 49,199, 61,128,113,148, 92,142,147, 40, 36,112, 5,181,225, 41, 2, 85,135, 39,154, 99, 16,240, 23, 55, +142,204,122, 16,126, 59,238, 43,188,133,196, 0, 0,217,106, 47, 36,148,164,126,181, 68, 42,225,244, 80,130,210,141,195,119,199, + 4,148, 84, 56, 83, 92,106, 46,244,189,139, 48, 12, 6,211,129,169, 91, 75,141,165, 40, 10,155,118,115,165,121, 7, 15,161, 63, +243, 45,221, 60, 62, 59, 89,110, 46,255, 57,255,137,203,218,239,180, 47,252,254, 98,125,225,210, 31,236,254,222, 65, 72, 64, 10, +226,218,238,132,186, 61, 37, 25, 27,100,162, 98, 25,118,194, 8,218, 89, 50, 67, 0,148, 36, 51,220,184, 37,223, 72, 50,179,236, +173,144, 52, 68,105,172, 20,247, 41, 29, 51, 19, 12, 41,164, 61,153,230,241, 74,227,246, 65,119,143,226,175, 40,214,143,229,104, + 61,166, 41,110,129, 35, 12, 8,183,195,236, 10,105, 46,187,248,249,141,145,106,203,105, 77,120,164, 87,186,102,183,207,109,189, +198, 0,176, 66, 45, 69,185, 26,197,222,128, 72,150,254,115,241,242,229,175, 0, 76, 93, 73,111,219, 70, 24, 29,142, 72,145,162, + 36,203, 91,146, 90, 54,156,164,117,128,162, 77, 15, 61,183,255,185,135,246,144, 91,122,233,173, 64,179,184,141, 17, 4, 72, 26, +203,150, 28,219,146, 37, 81,226, 54, 28,246,189,111, 68,163, 55,193, 54, 44,114,214,111,121,139,127,239, 14,131, 37,250,239,244, + 19, 27,167,187,135, 87,119, 23, 82, 83, 97, 84,142,144, 57, 45, 41, 43,150, 20, 43,236,220,189,254,110, 65,141,188,202,219,200, +239, 25,221,210, 7, 91,135, 95,150, 19,214,101, 92, 58,161, 54,148,117,143,238, 75, 52, 44,198,231, 56,234, 34,255,197,222,222, +233,238,223,212,147, 74,244,245, 37,193, 9, 48, 55, 5, 49,161,136,232,114, 87,199,108,160, 63,234,251,227, 31, 71,127,253, 86, + 11,253,106, 89,139, 75,142,181, 31, 38,239, 37, 15,177, 90, 36,129,221, 80,227,153,174,231, 19, 89, 61,222, 34, 93,252,254,247, + 75,164, 78, 21, 5, 33,168, 19,178, 34, 40,158, 4,236, 78, 20,225, 62,127,245,233,173, 52, 99, 20, 38, 27,111,116,250,249,157, +236, 55, 46, 50,206,189,227,215, 42,103, 34,217,194,103,100, 27,133,152,163,211, 8, 45, 8,165, 92,195,122, 78, 81, 87, 94,149, +199,173, 24,159, 79,134,207,198,211, 9,206, 38,252,207,116,150,246,226, 62,253,173, 90, 30, 14,234, 36,191, 96, 46,104,171, 78, +187,123,189,184,122, 54,252,102,150,204,219, 10, 49,117,252,211,183, 63,191,120,245,235, 50, 83,139,172,228, 88,180,200,113, 76, + 62,223, 28,237,156,172,205,173,241,166,195,253,248,225,118,220,143,250,140, 33, 41, 40,174,141, 33, 37, 74,124,129,144,141, 86, +235, 94, 80, 25, 28,127, 6,113,183,205, 41, 95,183, 34,206, 13,241,164,151,211, 97,207,163, 42, 50,101,220,234, 64,219, 16, 15, +100, 55, 34,179,248, 41, 27,101,145, 54, 54, 69,206,214, 69, 8, 36,236,143,202,146, 16,224, 85,186, 23,212,239, 71,105,201,210, + 80, 64,193, 53,170, 6, 88,188, 96, 94,229,200, 0,176,235, 18,234,205,209,118,158, 60, 69, 1, 5,243, 1, 9, 1, 54,142,175, + 40, 19,228, 57,109,211, 85,182, 18,197, 30,130,175, 12,217,125,233,209,238,225,248,238, 18,227,124, 54, 58,149, 92, 69,254, 80, +251, 56,160,137, 61,215,180, 93,126,254,244,135,211,143,175,219,116,162,210,210,236,226,176,227,100,192,217, 82, 84,184,131,173, + 47, 52,197, 56,236,225, 48, 61, 59,127,227, 60, 51,112, 8,174,181, 13,194,118, 88,135,105,158, 10, 11,129,197,202,127, 70,111, + 48, 26, 76,242, 60,111, 43, 28,100,229, 42, 12, 2,124,103, 73, 11, 36, 95, 66,233, 44, 53,197,222,214,193, 52, 65, 8,226, 61, +222, 63, 70, 18, 70,100, 36,101,226,165,134,174,140, 95,179,142,191, 21,109, 47,179, 69,195,213, 96,201,133,212,249,210,138,170, +129, 21,238, 94,137,119, 9,169,129,162,185,101,232, 58, 64,180, 41, 91,127, 26,225, 66, 15,215,146, 67,136,225,129, 7,221,157, +100,189,200,139,180,177,169,240,132,133, 90, 23,117,166, 8, 63, 17,123, 50, 45, 82, 5, 18,254,224,160, 62,122,112,252,199,159, +191, 28,183,216, 2,157, 87, 42,194,123,148,137,162,104,132,238, 96,212,135, 67,117,240, 72, 21, 78,237,155,237, 89, 87, 5,185, +247, 29, 37, 44, 34, 89, 76,103,203,175,110, 58,106, 47, 86,187,253,157, 65,140, 32,198,248,157,153,213, 70,217, 64,136,224, 56, + 98,231,162, 6,222,245, 85, 23, 23, 12, 57,237,214,239, 71, 62,242,199,118, 64, 9, 26,188,196,117,170, 76, 41,232, 10,206, 25, + 21, 26,177, 42,150, 45,100, 85, 56,214, 85, 20,226,138,104,151, 37, 86,218,118, 20, 45, 76,186,209, 3,171,254,167, 72, 40,146, +226, 98, 94,186,198, 47,177,218, 49, 17,136, 29, 51,131,124, 20,203, 65,127,253,232,228,114, 54, 30, 93,159,251, 42, 64,100, 22, +232, 32, 43,214,227,217,228,201,131,167, 30, 89,227,237,171,249,132,142, 2, 65,248,101, 54,158, 39,119, 15,183, 49,131,211, 65, +103,240,252,201,119, 23,183,151, 8,114,216,174,183,213, 42, 91,158,141,166, 24,243,189,254,126,118,183,174,181, 51,176, 33, 78, +198, 41, 4, 54, 52,105,215, 23, 20,161,115,164, 89, 68, 3,187, 10,180,239, 19,236,179,105,129,218,123,230, 18,177,221,244, 42, +184,188, 61, 71, 0, 46, 41,123,225, 42,125,157, 32, 94, 17,101,238, 16, 55, 77, 59,216,125, 75, 83,161,214, 77, 85, 70,203,174, +118, 94,191, 27, 40,175,220, 18,105,190,180,174,101, 41,133,154, 90, 64, 53,213,134,249,161, 26,124,164, 87, 55,198, 21,247, 76, +169,255, 4,224,234, 90,118,155, 6,162,232,140,237,216, 99,187,105,236, 52,143,150,150, 86, 1, 84,181, 11, 16, 2, 68,133,196, +163, 21, 43,248, 3,216,176, 0, 36, 62,141,175, 96,193, 6, 33, 84,209, 34, 16,168, 10,180,162,109,154, 52, 73,243,168,237, 58, +177, 99,115,239, 29, 83, 42,214,217,196,158,153,235,115,238,156,123,142,196,239,137, 64, 91, 3, 70, 54,117, 41,153, 29,146, 32, +137, 93, 24, 69,161,130, 42,116,113,120,114,136, 77, 31, 46,255, 82,162,144,209,210, 32,192, 57, 20,149,101, 34,125,141,171,232, +206,129, 78,136,113, 49, 95,244,176,117,168, 46, 86,106,131,224,132, 88,176,103,235, 83,240, 24,203,243,171,232,206,131,249, 12, + 81,118, 83,149,169, 68,169,217,164,160, 20,175,126,180, 67, 38,227, 25, 67,177,240,170, 42,194,220, 74, 41,143,231,178,129,167, +216,186,185, 80,170,173, 95, 95,111,245,219,201, 36, 18,134, 21,163,143,143,122,222,202, 42, 77, 87,130, 16,152,117, 82, 45, 84, + 79, 67, 47,203,121,226, 80,184,131,230,224,120,146,153,214,103, 78,244, 50,121, 29,231,155, 38,113, 97,202,233,251,125,248, 29, +136, 11, 70,187,193,225,209,109, 76,160, 70,217, 22,174,215,173, 43,183,133, 33,252,208,155,117, 47,161, 4, 72, 85, 15,187, 7, +240,228, 18,180, 2,144, 12, 66,159,124, 65, 13,120, 82, 32,113,176, 15,238, 92, 93,219,105,254, 40,152,110,247,236,100,175,189, + 23, 39,227,219,181,187,228,127,212,183,114, 70,209,114,225,245, 95,171,214, 44, 97, 53,122,251, 80, 51,190,244,235, 31,235,187, + 31,234,123,219,191, 15,118,154, 71, 91, 71,205,159,157, 78,253,184,205, 80, 6, 15, 48, 36,225,134, 53,142, 16,104, 20,132, 49, + 99, 89,139,211,211,101, 96, 0,166,168, 88, 98,214, 50, 47, 59,118,201, 50, 10,192,102, 53, 64, 25, 41,112, 36, 88,102,168, 84, + 65,136,232, 62,198,102, 6, 71,231, 88,149, 11,145, 22,166,210,188, 9, 0, 42,229, 99,214,104, 4, 7,221, 0, 37, 64, 64, 7, +164,129, 19, 6,149, 8,199,116,239, 45, 63,104, 13,143, 41, 85,131, 27, 24, 28, 4,124, 29, 21,102, 66, 51,117,195,140,227, 72, +201, 44, 34,178, 41, 79, 69,234, 82,129, 99,153,142,166, 40,168, 69, 83, 53,186,140,194,106, 40,128,163,104,148, 28, 40,227, 22, + 82, 25, 32,143, 64,254,201,218,211,237,250, 22,194, 86,105, 24, 34,249, 59,252,187,100,132, 38,223,104,185, 37, 0, 11,194,185, +117,167,102, 0, 37,193,186,194,146,205,185,151, 59,195, 22, 84,213, 23,143, 95,125,254,181,137, 82,109, 18,174,207, 22, 23,202, +249,178, 23,248,100, 77,133, 41,166,228, 99, 26,202, 75,180, 49, 6,234,226, 85, 44,208, 56,212,228,164, 41, 96,124, 20,117, 96, +219, 8,227, 77,230,156,121,168, 59, 56,126,129,247, 90, 17, 79,255, 78,211, 72, 27, 73, 66, 38, 64,115, 39, 89, 96, 51, 42, 17, + 93,123,198,135,253, 79,212,250,225,234, 70, 16, 98, 28, 58,124, 75,172,156, 37,181,128,176, 31,110, 44,221,220, 39, 95,132, 89, +103, 1,235,130, 84,143,164,128, 6, 76, 55, 95,130,253,131,102,121, 40,165,194,211,138,194, 72,158,232,156, 63, 90,185,247,105, +243,237,156, 22,189,247,216,187, 62,107,142,216,188,154,110, 60, 92, 75, 7,158,106,232,252,214, 77, 86, 42, 35,120, 63, 27, 51, +248, 70, 15, 78,123,237, 70, 24, 97,162,110, 44, 67,146,104,183,235,182, 99,105,185,156,109,192,254, 6,126,218, 60,108, 55,135, +222,176,219,254,238,201,238, 52,186,236, 46,235,236,190,203,132,194, 90, 35,214, 11,217,243,103, 47,157,149, 26,131, 82,110, 26, +114, 70, 11,125,229, 13, 40,188, 10,158, 75, 13, 39,138, 20, 91, 4, 71, 13,173,183,155,171,148,152,173,227,104,249,100, 18,116, +188,221,253, 83,111,130, 17,239,153, 71, 66,146,198,156,238, 91,169,150,185,182,227,143,206, 8, 78,249, 0,146, 94, 63,121, 3, +239,161, 51,232,194, 82,180,122, 77, 88,205,197,234,210, 41, 84,167, 52, 94, 40, 45,230,205, 60, 0,252,246,160,229,135,104, 8, +220, 31,118,107,149,218, 92,177,170,233,162, 55,232, 0, 70,134, 15,131,173, 91, 95,127,127, 3, 22, 46,219, 44,242,142,135, 44, + 72,145,100,194, 97,132, 99, 62,147, 47,163,236,125, 28, 38, 25,148,151,173, 26,146,164,144,104,110, 68, 61,131,139,151,151,202, +191, 68,117, 25, 86,128, 6,159, 65,236,147,215,105,148,102,115,203,178,193,195, 1,115, 41,212,127, 96,231,222,200,100, 86, 66, +185,190, 10,187, 80,217,165,106, 86,142,221,170,212, 57, 33,211, 36, 78,211, 27,233, 63,139,189,115,199,186, 11, 72,253,191,230, +204,249,207,127, 4,224,234, 90, 90,155,136,162,240,157,185, 51,147,201, 36,147,166, 77,218,154,208, 42,214,138,143, 42,162, 32, +136,224,202,141,224,222,133, 46,252, 9,110, 4,255,150, 32,254, 0,113,161, 80, 90, 41,197, 22, 69,146, 54, 73,155, 54, 73, 51, +143,100, 50,153,204,203,115,206,157,168,184,107,233,162, 97,238,205,153,239,156,243, 61,178,249, 76, 65, 53,161, 33, 66,120,133, +105,118,177,176,202,148,230, 47, 40, 49,235,129, 43,177,113,233,134, 31, 76, 4,141,172,152, 51, 56,199, 8, 52, 35,151, 71,249, +159,120, 52, 12, 99,109, 19, 82,112,209, 96, 71,155, 6,228, 39, 37,165,228, 2,200,233,163,167, 40,131,147,120,207,233,242, 84, +158, 51,153,231,249, 29,244,206,196,158, 78,209,147,140, 23, 44, 11,123,131, 98,222,196,228, 67, 6,128, 32, 71, 78,211,127,180, + 77,232, 16, 52,112,122,141,179, 6,156, 19, 92,215, 91,245, 91, 93,187, 43,218, 91, 17, 96,143,206, 1,180, 35,113,252, 81,146, + 13, 0,113,213, 58,207,130,196, 35,161,125,122, 76,110,244,216,146,163,129,161, 6,133,123,132,227, 63, 89,130,226,171, 40,208, +146,106,142,231,212, 43,235,102,161, 60, 66,201, 3, 59, 29,158,244,221, 1,218, 36,121,206,197,248, 2, 23,170, 73, 10, 88, 30, +149, 26,100,139, 29,162, 88, 57, 22,254, 54,152,188, 29, 69,141, 65, 3, 62, 82,173, 92,119,125, 7, 1, 47, 9, 61,122,128,100, +211,244,234,234,166, 59, 29, 65,175,215, 26, 54, 91, 86, 67, 78,213,141,218,122,162, 89,240,213,129,255, 13,237,136,155, 4,238, +204, 59,247,172,166, 61,220, 61,237,124,106, 52,118, 90,237, 32, 98,214, 44, 60, 29, 77,127, 89,214,231,163,206,126,247,236,195, + 97,243,107,179,179,221, 27,124,115,237,253,161,101, 5,211,199,235,181,250, 82,105, 81,215,151,243,121,147,231, 12, 73, 53, 36, +101, 81, 85,138, 50, 47,107,220,128, 62, 67, 85,224, 59,172,107, 76, 87,248,200,142, 14, 27,118,199,246,197, 58, 46, 22,129,246, + 52, 38,199,245,175,204, 15, 58,123,104,227, 69,247, 8, 51, 23,209,227, 20, 95,120, 88,248, 4, 63,125,158,168, 72,126, 42, 98, +140,134,148, 53, 12, 59, 68,137, 38, 74, 99, 98,150,172,152,203,112, 44,254,204,139,147, 80,104, 2, 51,149,114, 54,223,150,118, +127,238, 16, 29, 69, 6,112, 87, 95, 92,179,161, 23, 36, 30,165,104,108, 49, 57, 6,135,167, 9, 84, 73,104,213, 9,220, 48,232, +175,117,173, 0,133, 64,229,218,247,163,125, 40,196, 42,244, 42,132,160,172,241,240,238,149,187, 65, 20,160,166, 73,226,213, 98, + 21,240, 56,233, 98,102,130, 96, 46, 34, 31, 80,193,143,129, 22,184, 36, 65,209, 22,109,138,174,173,110,158, 92,180,133,192, 42, + 3,115,114,182,125,200,235, 6,193, 17, 36,122, 34, 27, 39, 77, 74,148, 68,136,105, 90,129, 71, 74, 24, 44, 46,237,139,150,153, + 43,248,225, 20,240, 41,116,201, 61,128,156, 24,108,150,156,187, 93, 9, 3,112, 56, 32,161, 40, 3,145,100,197, 17,133,126, 48, + 70, 15, 95,244,115,225,196, 12,147, 21, 36,107,203, 37, 77,123,116,253, 65,115,239,227, 84, 98,239,109, 54, 76,217, 89,204,110, +155,252,249,179, 39,108, 56,150, 87, 42,236,193,125,124,234, 94,200, 38, 62,155,132, 51,215,113,251,237,144,184,173,194,207, 83, + 40,182, 20,221, 80,180, 66, 9, 14,178, 90,100,166,161,246,221,102,223,137,220,190, 53,158,244,201,120,232, 18,103,207, 23,217, + 86, 17, 97,122,115,204,242,165,234,235, 55,239,216,242, 2, 22,116,120, 43, 64,215, 0, 63,228, 56,142,224, 57,174, 23, 50,243, + 39, 69,178,183,191, 20,245, 25, 95,171,176,156, 74, 84,143,216, 59,182,127,116,156, 9,242,136, 24,153,128, 33, 82, 85,101,165, + 12,189, 11, 54, 46, 36,233,162,182,175, 94,169,245,237,254,215,131, 47,173, 65,171,108, 46,220,185,124,179, 86, 89,129, 67, 89, + 41, 86,123, 72,171,227,128, 17, 49, 89,129,202,221,171,167, 47,253,208,111, 15, 78,134, 19,220,165,221,187,243,176,123,218,134, + 91, 7, 15,121,117,105,245,220,238,189,123,241,246,230,218,214,113,239,104, 18,250,128, 44,131,104, 10, 55,221, 11,224,165,203, +225,176, 38, 51,143, 28,222, 69,178, 11, 43, 27, 75, 17, 90,177,199,130,223, 14, 29, 54,155,103, 50, 11,250, 56, 75,255, 55, 0, +131,223,203,165,106, 16,248,104, 56, 35,145,105, 84,182,160,201,132,166,217,144,141, 9,242, 44,161, 30, 4,211, 10, 84, 26, 13, +205, 35, 84, 50,217,158,187, 15,207,137, 91, 18, 5,175,145,219,155,156, 38, 49,251,107, 75, 39,201,255,148,229,127,150,180,127, +124,250,254,254,225,183, 0, 92, 93, 75,111,211, 88, 20,190,126, 93,219, 77,234,132,148, 20, 90,104,203,128, 84, 85, 20,177,128, + 46, 16, 91, 54, 44,128, 53,210,204,110,254, 35, 98,135,196, 2, 4, 43,196, 2, 13, 82,167, 29, 65,218, 36,205,171,118,108,199, +142, 99,155,243,157,107, 23,105,164,238,218,166, 73,125,238, 61,175,239, 81,221,239, 76, 3,163,102, 62,129,164, 42, 8,218, 78, + 94, 75,133,232,149,183, 54, 46,240,105, 8,145, 29,141,235,226, 21,199,136, 99,218, 62, 21,173, 58,196, 70,182,175,237,132, 73, +224,200,181,202,198,129,110, 46,181, 88,100,253, 97,250,179,158,235,113, 93,131,151,106, 55, 59, 9,176, 74, 42,131, 1, 98,124, +195,219, 10, 19, 31, 64, 25,168,192, 43,215, 61,189,182,244, 70,106,131,253,116,145,177,213,122,174, 54, 86,101, 5, 58, 4,128, + 7,145,207,172, 4,122,102,231,179,243,154,254,162,210,148,182,221,217,142, 40,134, 74,149,198,241,195, 59,221,189, 97, 48,160, + 66, 91, 90, 18,203, 75, 70,183,119, 26,215,125, 44, 15,129,124, 87, 80,107,197, 44, 87, 88, 56,158, 92, 81, 27,168,211, 37, 62, +131,239,151, 82,247,198,202,129,222, 51,157,231,202,121, 71,148,174, 92,139,151, 49, 83, 76,177, 4,247,220,118,196, 85,124,150, + 81, 3, 95,174,209,119,211,100,103, 99,247, 34,184,104,200, 6, 3,248, 80, 10,152,186, 77,239,252,224,246,131,111,103, 95,239, +116,247,131, 36,104,202,206,112, 62, 28,199,139,101, 86, 88,236,135,106, 75, 97, 73,216, 37, 43,191, 77, 41, 76,215,176, 2, 77, +124, 57,254,239,100,216,255,121, 49,246,113, 74,138,220,178, 29,207,179, 41, 39,128, 98,163, 13,194,197,199,227,179, 73, 88,158, +142, 86,253,128,229,190,210, 34, 92, 1, 32,147, 82, 15,158, 27, 25, 8, 32,101,146,148,254,101, 49,186,200, 79,122,233, 48,136, + 88,185, 69, 89, 55,160,216, 53,117, 10,196,188,233,122,148,170,185,162, 52, 88,100,163, 84, 59, 73,219,114,109,236,187, 86,186, +162, 66,235,149, 1, 3, 27,100, 97,188, 96,106,224, 40, 81,218, 51, 48,126, 89, 42, 75,135,156, 39,203,234,159, 38, 13,167,242, + 14,169, 27, 71,165,215, 74, 47, 33,117,135,206,240, 36, 28, 93,197,177,166,228, 8,216,101, 27, 88,102,185,198,211,213,134, 82, +243, 15, 98, 95, 87,122,191, 2, 35, 35,129, 43,120,157, 26,166, 56, 93,244,167,189, 5, 21,137, 80, 70, 95,165,249,106,153,166, +144,147,213,106,105, 71, 28,190, 28, 3,167,178,246, 18, 6,115, 88, 74,195,162,134,128,201,116,248, 76, 77,230,115, 93,201,101, +183,221, 86,180, 8,197,111, 13, 41, 76, 11, 49,253,212,173,195,189,135, 99,127,228, 57,120, 22, 37,139, 20,234,186,185,204,146, +105, 48, 82,248, 78,173, 90, 54, 96, 33,193,130, 51,236, 5,197, 83,214,219, 27, 59, 49, 20,241, 52, 69,222,128,112,152,192,140, + 14,254, 30,165,120,120,107,255,242,244, 61,117,196,159, 98,209, 96,193,185,199, 45,239,197,179, 39,218,124, 46,238, 31,136,187, +119, 69,146,137, 69,138,250, 61,201,146,217,200,159, 12, 50,181,169, 44, 86,149,164, 31, 48, 15,166,213,104,203,178,176, 41,177, +223,108,183,132, 54,238, 77,199, 81,248,200,240, 61, 81, 60, 94,215,254,188, 89, 62,109,225, 51,245, 22,226,251, 68,188,124,254, +250,240,239,191, 4,116, 53, 36,106, 1, 83,171,190, 84,241,174,163,224, 20,142, 81,204, 38,227, 15,239,174,239,111,137,110, 27, + 9,128, 37, 97,163,147,233,251,227,115,163,118,184, 46, 89, 77,111, 5,197,139,152,201, 58, 21, 96,154, 14,120,154,101,155,173, + 77,186, 91, 93, 73, 37,135, 57,143,231,255, 14, 78,163, 36,166,234,123, 28,205, 94, 29,189,236, 79,251,235, 78,115,179,189,117, + 25, 78,194,120, 49,152,156, 83,218,166,216,179,133,236,157,253, 16, 92, 72,217,210,189,183,245, 7, 61,184, 55,159,223,126,239, +253, 51,230, 57,219, 94,119,119, 26, 78, 29,214, 60,167, 22, 33, 78,227,163,123, 71, 20, 45, 25, 40,147,136, 28,144,127, 25, 95, +171,104,208, 60,211, 42,110,117,118, 47,163,153,170, 23, 91,141,107, 41, 20, 50,168,145,101, 78, 40,252, 89,168,232, 14, 33, 30, + 9,167, 52,252,234,186, 67, 25, 83, 7,107,167,230,118,183,156, 78, 10, 26,115,205,249, 16, 98,163,217,133,177, 21, 58, 96, 81, + 84,192,153,242,127,222, 26, 20,129,174,217, 0,233,165,178,177,188,226,124, 84,155, 28,237,247,146,245, 10, 60,163,160,199,106, +202, 45,126, 9,192,214,181,244, 54,141, 69,225,123, 83, 59,126,197, 78,220,180,169, 26,160,180,138,102, 42, 4,133, 82, 24,170, + 1,118, 12,127,128, 13, 59,196,111, 64,104,126,199, 44,248, 55, 8,196,106,182,140, 70, 3, 44, 96,102,104,105,135, 52,113, 99, + 59,126,219,177, 61,231,156,155,240, 18, 82,213, 69,164,214,143,156,231, 61,223,247, 29,193, 95,173, 13,197,236,183,251,182,177, + 12, 97, 11, 9,223, 92,130,248, 46, 70,147, 72, 66, 38, 73, 88, 85, 70,225,198, 6,122,148, 66,180, 61,132,134, 16, 30,134, 19, + 20,189,152,166,158,192, 5, 87, 2, 16, 65, 81,254,220,202,166, 31, 79,192,166,225,207,161, 22, 22,107,136,161, 6, 90,235,172, +131,195, 19, 57, 22,233,160, 16,254, 16,168,143,157, 1, 87,155,218,141,193,205, 15,167, 7,159,206, 54, 63, 9,176,241, 57, 29, + 25, 13, 68, 66,181,101,190,172,219,170, 98,172, 88,171, 8,200, 33,149,190,205,213, 65,140,162,178,124,205, 94, 15,209,235,176, + 54, 7,231, 39, 98,232, 92,198,169,165, 91,126,232,237,110,237,193,205,159,233,110, 12,221,143, 34,154, 95,222,186,250,126,244, + 55, 60,215,206,249, 43, 31,241,195,162,141, 50, 35, 89,141,231, 25,133, 23, 77, 36, 73, 54,117, 43,133, 84, 81, 49,203,176, 75, +242,151,237,179,151, 92, 26,186,138,252,222, 49,187, 67,255,152,228, 86,106,177,114, 69, 87,245,188, 44,192,224,160,232,248,105, +112,227,225,221, 7,207,254,124, 6, 95, 4,132, 89, 48,133,172,204,169, 24, 33,224,189, 36,247,172,181,172, 44,154,141, 38, 84, +160,233, 12, 17, 93, 39, 81,156,196,149, 31,151, 65,196,194,176,142,162, 58,205, 33,244,214, 73,134,188,237, 70,205,157,105, 8, +174,208, 91,214,236,182, 97, 65, 63,165,170, 16, 24, 13, 85,150, 81, 94, 7,155, 44, 77, 70, 45,140, 13, 11,174, 21, 67,106, 73, + 98,217, 13, 10, 39,152, 58,110, 60,156, 68, 71, 99,255,104, 28, 28,141,166,135, 35,255, 96, 28, 28, 79,252, 48,205,161,204, 65, +180, 30, 46,151,226, 34, 77, 83, 29, 63, 35, 82, 15, 78, 20, 73,129,150,151,141,185, 66, 57,220,231,138,209, 67, 37, 38,180,176, + 37, 48,247,172,204,108,163,155, 19,217, 88, 28, 52, 35, 36,191, 44,126,189,247,248,213,251,215, 53, 77,212,113,227, 27,201,171, + 66, 13, 53,171,178,110,171, 39, 75, 18,180,231, 80, 46, 52,155, 10,148,186,224,135,186,210, 74,103,113, 91,237,128, 19, 66, 5, +219, 82,205, 12,129, 55,140,196,111,177,197, 71,210,118,226,214, 98,162,194,150, 36, 20,207, 82,160,212,133,223, 61,187,223,209, + 59,184, 66, 96, 86,164, 69, 98,183, 58,112, 57, 76, 3, 40,172,216, 4, 63, 7, 3, 94, 49, 87,145,160, 87, 87,170,164, 19, 22, +174,218,217,184,118, 58, 29, 43,184,195, 78,131,208,172, 41,154, 31,185, 59,155, 87,161,117,211, 85,220, 51, 62, 23,204, 17,143, +142,168,176,148,125,169,219,206,231, 40, 3,120,103, 78,224, 16,112, 26,242,127, 78,128, 81, 78, 63, 56, 61,133,231,162, 25, 79, + 41, 40,233,144,117,118, 55,246,188,112, 34, 74, 69,162, 77, 37,240,237, 10, 69, 73,170,137,169,237, 37,117,107,232, 82,110, 95, +216, 15,254,121, 14,241,239,119,204, 44, 24,223,239, 15,250,183,126,190,196,138,156, 93,187,194, 44, 27, 15,103,162,156,197, 25, +131,215, 55,250, 47,244, 70, 51, 26, 20,147,192,195, 66,143,190, 42, 21,195,226, 75,112, 43,136, 93,101,103,186,253,180,120, 59, + 12,228,204,189,219,202, 46,183,234,139, 22, 78,207,255, 77,235,191, 28,214,110,247, 30,253,246,132, 13,214, 49,190, 55,228,239, +104,209, 74, 36, 32,168,200,147,167, 47,212,108,172, 95,220,100,182,134, 31,210, 86,223,248,205,232,143, 35,143,118,142,163,114, +254,130, 9, 42, 70,156, 92, 40,119,209, 65, 4, 51,181,214,105,236, 37, 89,156, 23, 5,228,117, 48, 3, 60,157,107,106, 29,211, +118, 60, 7,186, 80, 20,103,169,102, 39,238, 9,195, 3, 43,232, 29,248,216,119,126,217,187,243,242,221,203,237,179, 63,238,111, +239, 31,142, 62, 88,186, 57, 60, 61,113, 67, 15,254,195,245, 31,174, 67,253, 14,151, 88, 95, 62, 7, 13, 55, 54,139, 53, 11,146, + 41,188, 16, 60, 77,197,254,156, 17,129,174,134,102,194,208,173, 10, 35, 27, 66,170, 80,254,154,215, 26,130, 47,194,249, 2,142, +122,190,201, 0, 10, 89, 93,181, 76, 20,204,137,224, 17,112,196, 66, 34, 81, 96, 20,105,150, 52,144,213, 46, 38, 61, 24, 4, 82, +164, 85,243, 47, 54,223, 65, 57,149,162,112,205, 98, 13, 33, 24, 3,205,252,202,111,224, 48, 69,133, 91, 90, 22, 11, 97,248, 98, + 33, 54,255, 42,196,127, 86,104,154, 67,187,248, 66,130,230,127, 1,232,186,150,221,182,141, 40, 58, 20,103, 40,137, 50, 69, 91, + 15, 68,138, 29,217,174,225, 42, 72,155,164,137, 3,196,105, 23, 65, 17, 4, 72, 22, 94,100,149, 69,127,165,232,190,127,208, 95, + 40,208, 31,232,174,139,110,186,107, 19, 7,105,129,218,141,101, 87,178,104, 89,178, 30, 38, 41, 62,115,207, 12,229, 6, 8,250, + 1,182, 52,163, 59,119,206,189,115,238, 57,217,252, 42, 67,221, 29, 81, 44,214,172,154,148, 22,231,178,205,141, 54,117, 81,148, + 32,227,165,233,215, 43,173, 41,101,112,169, 1, 34,116,177, 92,170,192,114, 76,208, 25, 40, 72, 5,109,221, 52, 74, 74, 73, 89, +232, 16,154,126,249,248,155,253,163, 87,116,126, 8, 94, 61,252,244, 81,119,112,146,117,242,117, 10,128,194,249,204, 9,160,140, +139,255, 16,169,129,148,156, 94, 46,218, 30, 60,148,231,224,191,167, 11,161, 2, 45, 19, 92, 86,188, 84,138,208,189, 71, 47,250, +195,158,212,136,215,104,227,232,151,144,133,109,180, 90, 89, 19,194,232, 12,222,169,206,166,108,124, 39, 25, 36,147,212,143,204, +148, 29,166, 28, 46,125, 80,119,212,243,163,249, 97,255,240,179,214,109,103,210, 15,226,120,120, 57, 42, 35, 73,218,206,216,161, +168, 50,243,150,109,218, 23,144,135, 77,107,229,134,212,137, 76,231,177,151, 74, 99,230,198,114,211, 11, 93, 31, 79,155, 17,193, + 82,112, 99, 98,232,151,250,115,151,128,187,101, 46,231,193,197,246,233,114, 94,173, 52, 8,140, 56,163, 62,173,241,201,221,167, + 63,254,250, 83,217, 44,111,214, 55,233,168, 82, 42,167, 96,106, 85, 55,208,186,145,142,142,157,193,129, 23,248, 19,127, 68,247, + 22,109,133, 85,180, 2,238,163, 90,210, 83,193,177,176, 16,226, 59,105, 16,194,120,143,234, 92, 74,223, 66,240,186, 85, 50, 12, + 97, 26,198, 10, 97,158,130,110, 20,121, 89, 26,108,150,132, 70,201, 29,142, 63, 60, 87,208, 4, 6,242,169, 44, 69,139,160,236, + 75, 1, 72,104, 3,164, 82,127, 33, 81,197, 37, 37, 20, 17, 98,206, 49,185,191,249, 85,231,236,232,138, 48, 44,152, 40,155, 43, +202,255, 76,109, 38,197, 6,229,139,162, 32,136, 13,179, 58, 25,232, 9,109,154,114,247,150, 67,161,116,201, 37, 60,199,183,155, +183, 8,188,211, 5,143,217, 99, 38,254,234,190,229, 56,150,138,226,202,232, 38,131, 85, 0, 38,182,131, 32,156,223,105,221,155, +184, 19,213, 30,165,239, 68, 69, 21, 85, 12,243,200,149, 39, 48,206,243, 2, 12, 25,226,152, 45, 98, 2,173,191, 68, 77,148, 96, + 29,112,164, 73,195,246,106,187, 59, 60,113,189,201,216,191,104, 84, 86,115,192, 74,152,220,164,149, 80, 13,110, 10,211,139,188, + 80,246,217,233, 30,162,197,223, 89,223,161,139,129, 16, 52,125,129,254,248, 20, 50,141,194,160,180, 67,224,206,197, 40, 99,220, + 31,245, 64,140,193, 51, 26,142, 6,108, 70, 82,128,158, 37,180, 92, 32, 52,198, 33,205,171,103, 52,182,140,102,169, 75,155, 49, +240,235, 11,249, 34,229,124,211, 88,202, 30,162, 53,170, 80,253,170, 85, 87, 85,172,108, 58,165,206,244, 84,122,146,200,151, 37, + 40,245, 50, 14,228,142, 94,214,138, 89, 13, 98,143,115,102,208,145, 52,236, 56,242,191,254,252,203, 81,239,117, 91,155,254, 19, +241,227,128, 21, 88,250,221,110,123,109,187,197,150, 76,118,127, 7, 73,128,192, 59,146, 59,161,248,203,201,191,135,174,123,201, + 22, 86, 58,160, 66,164, 74,111, 24, 45,105, 81,178,115, 73, 82,164, 13,109,218, 70,195,182, 6,254,239,195,249,244, 98, 92, 96, +236,240, 50,249,123, 22,237,159, 17, 94, 53,191,253,254, 7,115,239,137,236,101,243,255,153,135,199, 79, 26,254,241,166,251,203, +207, 55,238,125,194, 54,107,204, 52,112,234, 35, 0,164,243,223,142,247, 7, 51, 29,233, 93,250,204,165,202,207, 37,243,222,163, +173, 94,191,182, 49,195,153, 77, 49, 71,150,102,243,237,202,218, 89,240,252, 86,115,171,119,126, 74,123,179,251,197,227, 92, 28, +191, 61,249,179,106,215,115,114,136,233,194, 29,209, 81,234,156, 29,211,159,159,142,157,131,238, 65,109,165,126, 60,232, 80,172, +234,112, 16, 55, 26, 55,214, 65,161,147,118,138,132,223,149,240, 17, 5,252,243, 7,207, 58,206,145,154, 52,162,207,221,110,222, +156,120,211,225,108, 32, 33,115,124,115,237,246, 96,236,164,146, 32,175,128, 51, 8,241,178,177, 33,245,242,224,103, 7,138, 1, +148,107,240, 64,152, 44,154, 50,234,245, 37,148,238,146,154, 20, 17,202, 26,150,108,225, 43,168, 40, 92,255, 25,236,130, 79,132, + 9,245, 15,244,135, 23, 14,193,120,109,178, 76, 11,166,129, 87,180,200, 43,236,174, 72, 89,139, 65,170,143,178,188,246, 94, 0, +190,174,109, 39,141, 40,138,206, 77, 70, 24, 40, 87, 69, 65, 5,108,140,166,181, 85,211,244,169, 73, 95,154, 52,233, 91, 31,253, +130,254, 68,127,162,175,253,130,246, 43,250, 11, 77, 52,246,197, 43,169, 55, 24, 16, 25, 24,102, 96, 46,167,123,237, 3,244,165, +233,155,145,224, 56, 51,231,236,189,246, 62,123,173, 53,227,175, 98,168, 96, 76, 64,141, 22, 55,148,108,195,185,120, 72, 44,189, +143,173,133, 52, 45, 58,207,119,105,185,210, 3,133,136, 62, 33, 72, 10,109, 34, 68, 56,136,124,166,144,115, 94,102,135, 29,218, +156, 39,205, 99,250,129, 39,177, 20,187,127,135,193,249,157,183,157, 65, 43,150,108,127,246,117, 98, 17,134, 9, 15,186,129, 92, + 96, 26, 24, 76,228,115, 81,117,175,126,208,117,187,138,152, 27,223,160,220,166,196,176,156,171,254,106, 30, 13, 71, 67, 67,103, + 5, 12,190,240, 90,161, 54, 66,135, 61,126,245,244,117,202, 72,246, 64,111,163, 20, 99, 48,255, 88, 72, 89, 55,101, 38, 72, 26, + 11,166,218,178,253, 94,200, 51, 90,244, 82,253, 96,178,146,171,116,135, 29,156,156, 70, 99,199,115,232, 47, 80, 64,183,251,109, +169, 98,134,224, 37,105, 14, 76,207,205,167,139,246,160, 77,111,241,217,198,238,126,125,255,244,254,244,253,193,135,243,219, 51, + 66,172, 92,136,136,245, 98, 21, 43,207,237,209, 91,161,218,208, 25, 13,182, 42, 56, 79, 62,105, 30, 57, 94,159,109,108,141,174, +211,166, 76, 83, 72, 23,203,249, 50,221,139, 61,176,151,178, 21,140,223, 16,118,208, 98,202,151,126, 68, 49,200, 21,134, 8,112, +186,169,134,172,124,207,208, 89,161, 16, 15,138, 39, 70,234,249, 73, 42, 6, 70, 75,132,158, 36, 64,147, 50, 52, 83, 79,128,162, + 45, 12, 30,162, 38,144,188,160, 9, 51,178,124,129,174, 81, 16, 69,158,239, 49,143, 29,240, 49,111, 85,169,198, 66, 93,138,182, + 84,152, 50,224, 41, 76,159,253,238, 92, 69,241,116, 24,138,150, 17, 90,236, 17,251,171, 48,247, 34,189,248,196, 99,163, 28, 41, +208,134,112,159, 72,229,172,220,208,235,195,181, 18, 13,110,169, 62, 1, 90, 50,221,105,210,180,208,156, 81,117,202, 94, 4,129, +209,222,153, 49,136,244,153, 33, 29,235,118, 5, 15,110,199, 11,220,172, 85,144,163,144,180,133,120,111,224,211,124, 42, 71, 41, +153,126, 79,208,131,174, 82,205,173, 81,125, 0,162,118,186, 68, 0, 74,135,247, 30,213,154, 1,168, 60, 17,236, 55, 19,172, 17, + 79,251, 60,149, 72,161,192,215,112, 0,224,194,152, 5,244, 11,250,151, 22, 32,137, 14,121,106,194,248,182,115,207,163,120,232, +115,211,109, 66,119, 1,147,200, 0, 64,245,242,102,125,185, 97, 59, 54,171, 35, 8, 42, 97, 49, 61,197,109, 4, 42,227, 30,135, + 93, 29,135,252, 22,101,125, 22,190,159, 66, 19,161,206,237,177, 85, 57,118,140,179,220, 24,234,152,152,120,139, 66, 66, 18,189, + 97, 55,161, 75, 1, 81,169,156,161, 77, 7,162,161,139,173,201,142, 81, 66, 55,189,201,160,144, 89, 18, 65, 0,143, 73, 45, 84, +197,100,175,190,179,182, 92, 30, 95,254,124, 83,210,138,134,246, 66,139, 63, 29,190, 83,146,105,165,182,162,108,109,163, 45, 51, + 10,248,112,117, 34,122,189,254,237, 37,158, 8, 55,222, 25,188, 11, 77, 18,246,241, 38,131, 69, 43, 99, 36,146,137, 56, 54, 12, + 93, 89, 47,149, 86,243, 57, 39, 56,238, 71,205,246, 99,203,139,206,156,176,209,120,249,249,203,215,236,225, 71,206,220,250,255, + 92,131,174,111, 78,191,125,175, 52,114,230,126, 3, 99, 57,166, 46,213, 53, 21,127,124,253,163,121,238,122, 26,155,249,178,252, + 7,246, 36,138, 75, 51, 21, 18,248,101,163,143,136,109,179,101,124, 64,115,132,121,254,141,114,227,230,225,110,179, 92,187,108, + 53,233, 75, 39, 23,199, 55,157,219,231,181, 93,250, 22, 61, 34,170,123, 54,150,106,125,247, 97,128, 51,246, 60,196,136, 68, 76, + 48,156, 82, 41, 52,178,160,195,172,150,168, 74,118, 71, 23,173,115,217,125,221, 90,221,166,180,157, 77,102, 47, 90, 87, 32,160, +242,101, 12,195,164,200,238, 50, 25,141, 98, 10,149,119, 84, 64,140,131, 17,228,247,103, 46, 76,172,153, 10,204, 40,157,231,100, + 86,150,229,144,212,109,153, 55,198,197, 92,247, 84,104, 66,153,251,104, 99,177,103,204, 12,193, 51,105, 61, 69,203,128, 13,117, +205,244, 98,218, 11,252,127, 59,116,196,202,152, 5, 90,180,191,208,126,174, 0, 34,102, 81, 94,157,169,184, 78,187, 60,146,121, +241, 71, 0,186,174,165, 53,106, 40,140,230, 61,201, 52,153,100, 28, 59,143, 62,166,165, 82,197, 98, 5, 11, 46,132,130,160, 5, +221,213,133,162, 27,151,110, 92,184,240, 23,185,112,237, 31, 16,220,249, 7, 68,138,160, 86,138,117,112,106, 31,147, 73,154, 73, + 50,121,248,157,239,166,182, 27, 97,182, 67, 94,247,126,247,124,143,115, 78, 21,223, 9, 22,112, 43, 82, 41, 43,142, 44,182, 19, +232, 48,138, 46, 84, 59,104, 81,133, 73,192, 60,221,146, 27,134, 20, 92,166, 51,150,195, 14,182, 37, 1, 85, 33, 2,167,170, 70, +155,112, 46,139, 11,214,161,136, 93, 80,216,170,193,167, 27,140,203, 32, 26, 5,177,175,201, 24,110,213, 33, 64,103, 96,208,141, + 82,105,238, 48,152,181, 58,253, 49,207, 43,173,151,161, 63, 20,194,155,231,166, 82, 82,105,234,180, 12, 77, 28, 33, 70,141,194, +172, 1,169,229,130,245, 47, 53,130, 99,113, 18, 31,250, 67, 66,229,255, 76, 77, 84, 56,111,229,166, 89, 79,146, 68, 76,229, 48, +126, 47,116,221,220,186,185, 69, 97,148,114, 52,122, 94, 10, 85, 17, 5, 20,203,166, 3,153,208,159,107, 55, 79, 34,138,239,250, +101,175,187,177,114, 59,147, 50,184, 8,241, 59,164, 84,163,223, 94,166,220,101, 20,209, 90,132,176, 56, 37, 61,180,104,126,143, +134,187,195,111, 57,102,205, 51,149, 94,154,156,209,106,243,156, 22,225, 80,167,102,167,229,116,174, 57, 63, 56,217, 23, 98, 23, + 44,243, 0,162, 44,179,159,192,133, 29,142,135,178,162,157, 78, 48,133, 73, 97,200,182, 28,171,102, 29, 71, 7,220,172,206, 9, +176,178,249, 54,199,161, 66,168, 26, 9, 99, 74, 33, 39,109,180, 28, 76,182, 65, 71,158,213, 26,210, 92, 25, 37,229, 52,145, 19, +186, 48, 68,179,132,184,113,114, 73,162,219,246, 53, 9,154,118,149,199, 15,115, 26, 25,159, 74, 83,225,239, 13,149,109, 76,157, +203,149, 38, 22, 44,112,129,151,179, 76,197,128,125, 46,203, 85,203,200, 80, 13, 72, 69, 42, 48, 36, 19,218,121, 5, 79,149, 80, +186, 70, 40, 97,214,237,194,141, 65,226,234,183,172,206,186,237,241,132, 64,150, 2,129, 14,244, 81,138, 51, 39,118,140, 96, 21, + 85, 83,177,100,193, 72,180, 61,105, 37,160, 8, 35, 84,134,171,193, 53,124, 60, 54, 10, 64, 87, 28,181,222, 34,143,179,136,110, + 35, 99,229, 30,102, 84,149,116,221,149,238,170,144,154,234,120, 61, 66,190, 49,203, 62, 95,235,175,255, 58,220,235, 53, 23,232, +255,243,173, 5, 63, 28, 89, 48,223, 33,156,146,243, 70, 85,233,209, 8, 37, 45,181,151,143,131, 99, 21, 3, 96,134,160,104,208, +254,114,234,141, 0,176,238, 72, 56, 20,226,132,133,124, 74, 86,200, 69,195,242,252,240, 40,225,150, 50, 6, 45,160,102, 97,210, +231,131,242,137, 66, 7,222, 76,215,165, 36, 47,236, 53,231,177,132,152,194,170,114,101,246, 52,137,102,204,250,230,218,230,215, +193,119, 33,110, 64,145,151,109,226,113, 56,181, 27,157,136,157, 63, 85, 30,166,180,107,182,166, 42,113, 26, 42, 34,237,135,219, +135,234,105,246,211,199,207,223,127,120,215,215,226, 91,158, 62,103, 40, 87,183, 31, 98,148,229,250, 21,169,213,161, 83, 81, 74, + 82,252,162, 56,221,223, 13, 71,127, 80,155,201,114,161,237,170,150,108,112,134, 74, 17,218, 87, 48, 23,116, 92,186,150,201,132, + 61,105,177,217,233,120,221, 76, 27,164,146,110,183, 95, 60,121,181,253,242,181,190,182, 42,101, 19, 9,244,210,218,127,131,251, +238,222,151, 55,111, 91, 78,222,188,187, 46, 45,121,146,109,176,135,111, 38, 17,244, 28, 30, 12, 62, 70,123, 73, 64, 64,151,185, +138, 48,111, 33,100, 29,231,169,232, 7,200,152,110,234,113, 56,198,206,165,152,126, 18,250,104, 57,104, 53,255,116,252, 96,227, + 30, 37, 95, 16, 10,100,178,225, 98,107,193,237,247,212, 2, 34, 54,155, 55,238,124,250,241, 25,196,230,188,124,116,255,217,162, +215,217,249,185, 19, 68,227,209,196,167,247, 22,166, 33, 45,153, 16, 54, 59, 42, 5, 80,212,223,131, 35,180,193,203,148, 32, 23, +156, 45, 4,229, 30, 57, 70, 38, 84, 8, 27,117,111,194, 44,182, 41,119,200, 43,189,129,202,205,166,116,172,230, 4, 2, 27, 18, +125, 8, 74, 73,167,211, 12,220, 37, 76, 67,202, 23,236, 74,207,109,136,197,202,165, 88,138, 17, 62, 66,117,160,202,163,159,229, +154,174,131, 74, 99,156,162, 50,153,137, 74, 53, 87,230,138,139,134,171,194, 20,248,162,163,177,124,238,241, 40,159, 73, 25, 85, +158,190,180,245, 42, 56, 95, 86,102,177,127, 5,160,234,250,126,147, 6,163,104, 11, 45,180, 80, 58, 5, 6,204, 73, 98,214, 17, +150,153,232, 52,113,198, 7,125, 52,241, 81, 31, 76,230,191,103,226, 63,224,139,137,111, 62, 26,117,206,232,139,203,182,196,233, +212,233,104, 41,148,150,246, 43,245,158,251, 21,220,246,220,133, 66,251,221,123,238,143,115, 78, 30,223,217,112,114,177,205,153, + 91,165,210, 3, 72, 80,185, 51,131,139,203,169,106,169, 82, 46, 85,185,142, 6,126,167, 12, 73,199, 21, 80, 8,236,124, 13, 35, + 50,205, 8,165,199, 5, 51, 78,107,166, 21, 78, 35, 10, 85,116,189,148,109, 82, 81, 93, 26,132,188,232,167, 31, 6, 64,217,104, +176,164, 84,142, 65, 6, 68, 8,113,173,227,248,188, 79,166,163, 62, 85,155,118, 7,171,241,176,106,195, 29,208, 1,163, 39,135, + 56,194, 5, 4, 99,119,244,206,160,233,131,174, 18,165,161, 18,171, 95, 39,231,117,193, 40, 73, 54, 41,190, 76,188,185,204, 62, + 82,212,254,207,125, 58,180,210, 39, 6, 54, 67,108,240, 53,142, 39, 20,223,127, 15, 79, 45,180,195,210, 83,239,215,225,233,193, +152,114,190, 76, 14,172, 71,113,255,250,131,119,251,111,117,141,119,141,184,149, 8,126, 86,154,182,150,218,117,187,233, 5, 30, +125, 17,130, 36,132, 25, 9,116,199,113, 46, 16, 79,239, 47, 43, 11,170,155,221, 27,110,112,182,221,219,246,198,195,157,251, 59, +223, 7, 39,208,234, 98,237, 44,186,237,219,189, 59,163,192, 15,226,209, 70,119,243,135,123,124,219,185,251, 61,252, 90,198,178, +169,128, 28,171, 46, 73,187,220, 41,148, 69, 45,101,245, 98,214,172,153,245, 90,249, 82,173,100,232, 20, 11,138, 66, 45, 70,179, + 76, 46, 36,210, 37, 26,194, 50, 21, 91,201,211,199,207, 14, 15,143,146, 24,158,147,200, 43, 2, 26,203, 42,171,246, 53,172, 22, +157,144,203,149, 38,100,149,176,220,144, 74,205,138,246,210,149, 81,228, 55, 42,141, 32, 9, 53,116, 69,242, 89,136,196,167, 5, + 14,139,153,178, 24,165, 82, 68,179,228,143, 28,130,196, 79, 0,217,148, 56,141, 96, 17,142, 77, 20, 17, 42,159, 78, 39,244, 18, +218,134, 45, 5, 90,235,232, 81,132,188,152,144, 59,217,193,224,134, 23, 13,232, 63,173,114, 77,114,146,231,228,160, 89,238,121, + 4, 78,145, 20, 92,204,164,242,148, 6,145, 7,132,173,209,100, 20,195, 24, 17,123,128, 65,232, 23,225,214, 27,127,251,115, 36, +233,253,166, 97,186,163,193, 90,219, 49, 74, 38,213,163, 34,205, 53,194, 36,153, 48, 17, 83,236, 5,241,236, 87, 74, 6,166,252, +121,112,130, 78,197, 37, 40, 66,215, 41, 12,216, 21,212, 46,172, 99, 67,117, 80, 84, 80,230,110, 73,188, 77, 52,227,237, 16, 77, + 46,131,161,215,155,176,208, 88,166,195,171,178, 20,197,148,183,210,213,198,170, 44, 46,253,241,208, 50,170,204,154, 81, 87, 27, +221,129,143, 5,161,101,187,221,176,151, 9, 28,240, 76, 91, 72,131, 20,240,188,232,179,160,207,133, 6,232,153,123,114,111,235, +174,115,115,251,229,235, 87,222, 36,109,216,245,245, 39, 15,241, 19,245,251, 74,197,194,218, 12,192,187, 80, 6,127, 38,199, 7, +116, 3,149,230,106, 70,153, 53,153,178, 43,104,166,113,230, 45,106, 44,245, 49, 75,193,108,182,108,157, 78, 61, 29, 8,203,164, + 16,223,232,182,250,154,233, 71,209,241,217, 95,125, 58,187, 28, 23, 10, 83, 58,105, 10,168,170,186,182,160,205,228,127,225,216, +127,253,102,239,197,243, 86, 75,111, 63,186,165,108,180,149,146, 49, 55, 99, 78, 9, 50, 40,159, 14, 62,188, 31, 13,102, 33, 86, + 17,210,212,233,109,117,150,187, 80, 67, 5,171,155, 43, 64,133, 30, 86, 32,248, 80,211,131,243,152,187,206, 10,232,232,164,236, + 30,238, 57, 43,107, 63,220, 95, 32, 6, 98,178, 98,108,175,223,250,248,117,215,243, 93,122,181,252,201,120,163,219,167, 58,155, + 10,232,207, 71, 95,226, 84, 56,237, 53,110, 0, 22,169, 86,182, 77,219,233, 56,110,224, 14,195,209,146, 81, 35, 48,232, 6,158, + 85,134,102,198,230,213,235, 92, 50, 10,120,123,169,138,179,210,163, 26,154,233,153, 5,244, 21,212,180, 84,208, 8,167, 98,190, +146,119,137, 17, 5,196, 44,230,217, 43, 15,249,213,204, 52, 42,244,230,137, 60, 84,254,111,176, 44, 58, 39, 42,211, 27, 67,144, + 69,120, 88,206, 67, 10,122,193, 98,240,193, 19,185, 30, 41, 37,233,193,148,204,196, 57, 86,234, 2,222,206,109,107, 47,168,148, + 93, 80,126, 87,115,149,166, 76, 94, 81, 45,219,132,123,254, 9, 64,213,181, 45, 53, 13, 69,209,147, 75,147, 52, 73, 75, 3,148, +150, 66,111,220,135, 65, 81,199, 25,121,244,209, 87,255, 71, 63,199, 7, 63,194, 87,103,208, 1,102, 0, 31, 68, 46, 34, 3, 21, +180, 52, 77,211, 52,205,165,113,239,125,146, 1,121, 44,116, 38, 45,231,236,203,218,107,175,149,206, 87, 85,213, 32,217,166,132, +152,218, 50, 23,209,129,170,124,130,222,243, 50, 63,229, 37,221,130,198,150,238, 45,155, 41,206,110,212,182,186,131, 63, 61,164, + 52,136, 73,102,213, 6, 77, 55, 33, 30, 41,167,206, 15, 3,136,230, 16,226,137, 21, 65,142, 57,180, 22, 59,161, 77,247,133,217, +122,207,189,135,239, 20,162, 12,138,110, 71, 62,228, 31,184, 3,222,200,165, 26, 77, 32, 27,229,152,192, 7, 8,220, 50, 13, 52, +112,186,165,160, 24,125,132,155,235, 44,166,113,246, 56,165,170,209, 42,147,169, 21,214,107,155,208, 31, 64, 92, 22, 72,186,116, +224,219, 16,188, 98, 78,204,160,243, 2, 79, 91,212,167,248, 94,149, 76,228, 14,180, 9,154, 64,160, 44,239,108,190, 66, 82, 71, + 20,144, 99,101, 46, 66,181, 19,145,219,113, 17, 28, 50, 49,243, 69, 28,154, 65,188, 70,158, 31,174,158, 64, 62,135, 58,124,218, +156,185,236,254,108,204, 44,219, 94, 23, 14,108,142,166, 43, 20, 38, 4, 94,111,106, 42,110,111, 66, 83,233,248,131,155,251,206, + 40,242, 37, 73,130, 20, 82,159,107,186,158, 83,177,106, 85,107, 1,130, 11,116, 6,161, 16, 45,206, 44, 52,102,151,134,225, 96, + 16, 94,139,162,226,184,193,152,148,121, 3,188, 30,233,244,154, 2, 26, 42, 76, 90,166,174,145, 54,153,166,137, 6,146,213, 68, + 65, 17,138,134,164, 43,112,139, 17,105, 13,176,215,136, 15,247,246,136, 33,158, 67,162, 20, 22,115,136, 48, 66, 16,129,115, 6, +215, 6, 69,227,209,225, 79, 80,114, 58,226,230,196, 88, 69, 95,227, 36,193, 5, 13, 58,145, 5, 99,138,216,226,130, 38,107,170, +146, 23, 82,146, 0,110,152, 19,233, 67, 36, 43,118,142,231,176,242,212, 60,230, 12,211, 66,182,204, 36,169,148, 42,186,170, 59, +144,255, 38, 33, 23,171,137,113,181, 89,240, 70, 14,188, 30,112,101,224,132,243, 40, 37, 49,115,173,164,146, 57,225,110, 56,228, +172,141,199,172,100, 90,208,207,210, 20,139, 64,106, 81, 54,242, 6,138, 85,169,208,200,232,163, 96,248,180,249,220, 80,117, 74, +186, 85,114,114,199,147, 9,193,204, 66,169,169,176, 82,154,187,188, 59, 39,240, 71,152, 54,167,249, 50, 42, 7,239, 67, 28, 80, + 60,252, 36,164,102,212, 42,175,192, 99, 67, 96,149,101,244,104,134,242,133,182, 88, 69,158,239,179, 78, 57,197,220, 17,147,140, + 35,108, 90,100,196, 25,114,104,166, 28,167, 14, 6,216, 49, 69, 91,141, 39,219,237,103,174,231, 58, 35, 27,238, 2, 22, 1, 8, + 55,225,199,181,221, 30, 95, 11,243,124, 7, 89, 70,241, 88,203,169, 80, 73,115,125,220,113,232, 37,228, 24, 92, 50,202,136, 98, + 39,147,126,231,230,205,187,247,237,242,202,193,241,217,230,106,189,246,122,155,105, 50,107,181,152,172, 32,242, 62,138,217, 96, +200, 46,190,251,118, 55,145,114,122,121,113, 60,236, 71,112,127, 73, 56, 80,226,254,135,184,109, 5, 53,127,140, 40,141, 10,253, + 70,129, 11,201, 34, 61, 6,170,134, 86,121,179, 58,167, 4,254,183,147,163, 47,251, 95,127,255, 56, 83,236,161,222, 15, 36,199, +103,119, 3,214,237, 51,187, 31, 93, 93,217,159,191, 28,127,248,216, 57,218,221,120,177, 84,126,251,146,181,107,112, 64, 50, 39, + 56, 34, 99,186, 14,251,116,186,123,233,133, 88, 86,176,122,169,222,251,219, 57,191, 58,177,135, 61, 35,111, 66,246,130, 10, 6, + 66, 10, 84,217, 28, 90,230,210,128, 69,221, 26,133, 67,172, 8, 85, 99,125, 97, 13, 18,236,175,187,203,229,218, 26,156, 49, 72, +153,215,208,168,187,189,102,181,121,222,185,104, 55, 86,231, 43,141,130,154, 63,188, 56,180,138,211,240, 91, 8, 23, 61,183,123, +107,223,194,191, 3,254,108,103, 99,103,255,244, 0, 14, 60,244,175,170,162, 65, 17,131,131, 49,198,160,146,131,194,202,192,168, +130, 75,219,240, 22,137, 73, 57, 69, 29, 7,184,198,175,171,166,231,123,216,164,102,160, 75, 76,133, 63,173,226,112, 21, 32, 20, +153, 29,135, 33, 60, 63, 69,161, 36, 3, 73, 30, 45,151,210,231,129,158, 62, 85,204,205,252, 84,137, 36, 18, 39,153, 38, 48,101, + 92,137,100,138,131,255, 29,241, 30, 56, 50,201,131, 32, 65,170,112,156, 73,109,241,229, 41,246, 72,136,155,241, 97,245, 63, 1, +152,186,178,158, 38,194, 40, 58, 91,167,211, 14, 67,167, 51, 85, 42, 22,161, 46,136, 60,184, 5, 9,241,205, 23, 31,141,137,137, + 62, 24,127,168,207,174, 65, 73,124,209,132,168, 21, 23,192,130, 80,102,161,179, 79,189,231,126,131,248, 10, 9, 19,102,190,239, +220,237,220,115, 42,253,247,146,249,149, 19,110,207, 21,101,213,162,207,133, 58, 54,171,158,210, 49,165, 55, 66, 16,230, 88, 29, +122, 95, 17,197,204,104, 68, 23, 62, 41,210, 51,214, 12,225,126,157, 53,223,121,190,138, 39, 47,207,221,236,185,125,138,144,216, +145, 71, 60, 56,123, 97,102,225, 96,180,207,126, 42, 74,107,202, 9,227,163, 32, 14,232,246, 26,186, 1, 5,116, 69, 29,167,216, +252,246,199, 30,123,243,136, 72,132,134, 59,180, 42,243,136,183,141, 48,251, 98, 85,224,140, 89,240, 38,157, 12,130, 81,138,174, +130, 96, 40,114,206, 40,137,134,254,208, 7,213, 18,139,127,176,121, 66, 79, 77,169,118,230,133, 27, 38,166,113, 42,211, 9, 50, +250,158,216, 24,150,149, 2,159, 42,222,252,181,185,231, 13,233,107, 81,197, 36, 24, 78,194,135,185,219,238,221,186,180, 58,244, +118,254, 4,135,174,233, 22, 66, 37, 89,130, 97,147, 80, 25, 37,160,196,218,154, 92,106, 26, 26, 20, 20, 63, 8, 5, 90,166,253, + 96,237,225,224,247, 32, 76, 60, 96,159,162,210,179, 40, 11,167, 67, 70,213, 15, 74,254, 50,111,214,205,122,189, 1,161,140, 12, +252, 95, 8,167, 40, 24, 64,209,171,248, 52,124, 47,201,154,109, 25,178,146,129,255, 9,196, 41, 40,121, 2, 87, 82,102,239, 55, +196,205,114,214,182, 36,204,235,100,104, 98,151, 74, 92, 72,152, 0,148, 74,150, 76,130,113,150, 51,184, 19, 48, 54, 36, 93,213, +106,184, 98,232,128, 34,213,116,173, 51,127,188,253,243,206, 28, 93,164, 44, 77,111, 95, 90,219, 25,109, 83,230,194,125,173,106, + 92, 36, 20,237, 84,206, 13,232, 61,211, 17,111, 81,234, 93, 36, 81, 54,134,124, 88,145,245,187,139,182,217,142,227,152, 5, 90, +101,166,142,233,130,250,173, 48,135,114,169,183, 28, 70, 30,197,114, 56, 97,113, 71, 91, 88, 45,179,112,203,132,138, 57,199,116, + 3,202,110, 8,193,107, 80, 72, 44, 88,164, 19,162,162, 85,112,172,206, 57,218, 68,220,156, 17,108,168,233, 70,139, 46, 3, 85, + 21, 83, 13, 27,146,244, 58,149,137, 49,152, 51,138,174,107, 26, 33, 56, 29, 27,168, 77,113, 83, 5, 66,120,160,223,200,231,236, +238,246,193, 47,110,166,226,143, 71, 44, 65, 37, 79, 78,117,197, 78, 20,225,185, 58,146, 74,163,214,160,147,153, 78, 82,122,249, +132,197, 77,189,217,235, 92,240,162, 67, 89,232, 10,242,249, 16, 82,227, 60,119,149,132,189, 39,247,165, 84,118,178,174, 33,177, + 80,176,187,165,242,245,222,247,135,224,114, 72, 37,197,167, 56,141,133,233,154, 90,249,204, 85,250,200, 96, 82,230, 88,122,164, +223,250,104, 33,130,126, 68, 8,104, 32,244,166,101, 25,105,138, 92,215,117, 63, 24,221,182,186,189,103,143,239, 46,174,205, 94, +239, 72,141, 76,154, 50, 32, 40, 86, 51,168, 20,197,250,232,247,175,147,221,239, 4, 64,116,146, 19,239, 48,143, 67,177,106, 35, + 40,153,208,157, 6,186,195,128,152,226,133, 92, 36,148, 65,233,141, 41, 73, 88, 96, 27, 42,116, 11,102,157,206,213,185,229, 43, + 11,253,142, 85, 38,225,206,246,151,207, 31, 55, 6, 27,239, 54,223,188,250,185,177,254,227,245,139,173,183, 47,143,247,190,245, +175,205, 44, 61, 90,107,220,191, 41, 89,142,132, 45, 87,229,164, 19,144, 75, 84, 47,110,109,142,158,251,235, 71,161,206,229,167, + 23, 7, 17,250, 87,148,145, 24, 20, 92, 15,131, 35,130,154, 48, 30,159, 16,161,171,213,126, 85,211, 98, 54, 59,164,138,199,157, +118,135,222,239,227, 52,170,171,122, 16,133,148, 63, 57,150,221, 54, 29,250,191,188, 99,127,239,104, 63,142,198, 79,239, 61,233, +117,122,187, 7,208, 25,116, 44,247,206,229,149,249,238,130, 99, 58,131,225, 96,117,113,101,227,235,135, 27, 23,175,239,142,118, + 41,192,183,173, 54, 21,232,152, 30,201, 72, 32, 48,169,171,213,155,181,102, 16,135, 19, 86,163, 99,232, 45,216,234,170, 60,213, +214,226, 33, 19, 3,167,248, 73, 89,229,243,204,129,134, 85, 9, 32, 6,243,137, 10,226, 43, 45, 35,137,170, 49,219, 36, 52,240, +255,153,113, 73,255,104,238,149,206, 0, 87,166,120,104, 46, 79,148, 19,115,132,255,179,120,249,148, 25, 83, 41, 5,171,148,211, +228,101, 50,223,233, 19, 20, 79, 27,173,148,221,234, 69,179,134, 80,209,182,220, 40, 25,255, 21,128,171,171,233,109,219, 10,130, + 79,252, 18, 69, 74, 52, 45, 89,142, 34,217,113, 98,203,106, 13, 36, 65, 16,167, 77,123, 42,122, 14, 10,244,212,191, 88,160,191, +160,233,177,151, 22, 1,114,232,173,177, 17, 20,181, 98, 39,134,252, 77, 83,226,151,200,206,236,147,140,160,128,111, 50, 40,145, +143,111,119,118,223,206,204, 34,190,147, 81, 94,101,194,181,209, 93, 26, 85, 55, 93, 65,120,165,239,249,210, 20, 99,212,199,253, +183,220,128, 90,166,170, 76, 17, 25,107, 86, 94,102,219,189, 93,128, 80,146,102,152, 27, 22,210,153,147,235,211,235,248, 18,152, +151,196,147, 42, 7,224, 58,158,140,229,110,184, 37,200,209,146,118,182, 67,140,236,102,121, 70,217, 41,114,217, 43,173, 24, 86, + 9, 79,215,107,248,248, 10,228,210,106,121, 4,183,124,106,216, 42,182,107,201,252, 92,137,141,103, 0,179, 3,135, 96,177,183, +186, 15, 16, 64, 43,162, 90, 83,134, 53, 17,178, 83,203,116,180,225,207, 92, 76, 38, 77,145,159, 46,217,243,146,202,218,100, 47, + 85, 79,183, 33, 94,222,107,247,137,178, 57,250,205,117, 86, 11,151, 91,117, 21, 95,140,207,142, 50,177, 97,147,161,157,164,217, + 32,139, 26,171,130,205,187,218,108, 3,107,115,120,166,152,213, 41,215,147,240,186,166,137, 87,228,221,248,239,126,123,176,219, +255,242,227,229,201,138, 23, 80,170,180, 30, 80, 22,223,198,235, 59, 67,196,188,205,162,176,217, 70,104,155, 68,231, 47, 71,223, + 4,173,224, 98,138,240, 81,109,172,111,204,106, 31, 92,199,234,132,245,210,204,168, 95, 46,226, 60, 34,130,169,202,106,161,108, + 62, 75,202,123,129,103, 57, 86,131,134,174,196,238, 57,146, 68, 89, 9,157,191,198,224, 46,134,191,142,165, 26,149,103,213,156, +148,126,167, 50,142,102, 88,211, 36,142,179, 40,154, 69, 36, 7, 85,156,252,137,211, 41, 46,178,210, 88, 77,138, 84, 23, 46,247, + 87, 7, 83,161,159, 96,165,218,173, 46,158,219, 52,139, 1,222, 91,110, 40,146,120,234, 42,186,184,140,207,155, 94,200,240,106, +187, 94,189,149,229, 51, 20,127,168,139,191, 24,236, 29,159,253,123,113, 51, 9,253, 53,252, 12, 45,102,175, 15, 9, 76,211, 70, +126,242,157, 6, 86,132,121,148, 22,201, 72,200, 54,135,157, 10, 22,144,131,206,166,248,243,177, 47,101,137,247,115,154, 3,145, +150,205,122,192,134, 24, 73, 85, 41, 77,235, 68, 11, 28,123, 50,240, 87, 16,241,119,238,143,254, 57, 61, 88, 11,214,145, 59,108, + 78,229,250,184, 38, 79, 46, 84,181,214,236,142, 54,247, 44,195,185,141, 35,241,191,160, 96, 17,150,175,223,222,152,146,156, 50, +221,236,108,161,156,231,105,191, 46,100, 89, 71,240, 39,107,106,174,109,152,156,218,180,237,243,155,179,185, 8, 75,177,139,210, +236,220,208,183, 64, 9, 95, 90,252, 62, 13,171,169, 67,100, 89,234,198,143, 73,209, 40,167,148,241, 77, 30, 71, 89, 20,173,141, + 18,220,154,177,217,221,122,177,179,127, 52, 57, 50, 52,157, 74,213,144,230, 1,232,109, 82, 74, 3,108, 64,223,241,112, 53, 4, + 50,212, 13, 41,189,141, 82, 81, 21,197,187, 69, 57, 0,196,241,147,195,195,253,112,221, 90,235,168,230, 88, 25, 5, 74, 27,229, + 35,143,123,236,207,140,199,234,232, 80, 37, 51, 30,203,243,153,230, 65,239, 33, 91, 5,121, 42,157,119,165,135, 53, 25,223, 57, + 6,207, 16,111, 0,111,121, 94,205, 23, 81,120,202,242, 89,202,179, 84,216, 80, 15, 66,119,212,239, 61,223,121,244,124,184,251, +228,225,240,233, 96,251,241, 96,235,217,198,163,111,135,219,175,246, 7, 63,190,244,190,122,170,186, 61, 5, 8,193,222, 67,181, +236, 63,211,206, 75, 29,143,213,239, 7,127,252,165,174, 84,234, 91, 30,205,165,132, 74,138, 91,163,146, 79,195, 47,105,124,152, +170,197, 72, 75,169, 25,134, 69,173,204,242,188, 18, 50,217,188, 70, 37,168,172, 88, 48,210, 91, 94,128, 63,224,194, 86, 16,190, + 63,125,191,211, 27,226, 29, 7, 24,250,245,237,235,227,179,143,251,123, 95, 31,124, 56, 0,210,191, 78,226, 55,239,254,140,166, +183, 63,188,250,233,151,223,126, 30, 13,134, 39,231,159,196,246,118,142,122, 49, 74,167, 41,253, 23,233,189,174,199, 96,190,123, +252,253,233, 21,254, 33, 67, 10,159,243,128,208,193, 99, 41,164,214,212,242, 56, 38,213,129,138,255,207,168, 47,117,122,177,166, +235, 65,239, 82,228,140,140,207,108,202,240, 49,170,216, 72,228, 63,239,220,187, 42,146,129, 66, 29,118,238, 52,232, 62, 51, 50, + 93,120, 55,169,187,144,190,212,231, 53, 23, 19,184, 68, 90,174,225, 38, 5, 82,229,141,254,168,162,191,158,102,175, 18, 79,212, + 45, 27,209,233, 63, 1,184,186,146,221, 38,130, 40,216,227,158,125,188, 36,182, 65,113, 54, 2,138, 20, 36, 32, 98, 59,112,228, +130, 64,226,163, 57,193,129, 59, 7, 22, 37,144, 96, 34,103,177,163,120,198,158,241,108, 84,189,182, 1, 33,249,224,131, 29,103, +122,222,188, 87,175, 95,117,213, 42,191,171, 6, 64,220, 86,247, 78,194,218,152,139,234,158, 39,204,153,138, 68,186,124, 38,146, + 65,148,232,146, 61,235,146,228,135,170,242,208,200,228, 41,154, 26, 32, 66,211,100,153,230,194,216,138, 85, 82,202,208,116, 0, +235, 5, 78, 68, 23, 36,153,154,215, 43,103, 54,161,199, 89,158,141,140,224, 77,179,155, 63,106,124,162,191, 80,136,194, 95, 11, + 69,143, 38, 59,134, 86,185, 60,224, 42,170,177, 21, 37, 35, 68,173,197,151,205,138,210,196,197,193, 38,160, 98,156,202,216,196, + 90,233,246,209,156,193,178,241,107,187,189,189,201,108, 66,146,128,165, 68,197,155, 66,240,165, 48,237, 12, 73, 6, 15, 33,114, + 25,153,242,170,126,253,244,117, 95,196,220, 27,202, 54,114, 94, 64,187,154,170,142,128, 53,253, 89,158, 96, 89, 10,250,184, 38, +192, 60, 73, 46,236, 26,233,208,144, 25,219,193,122,178,136,125,161, 15,137,115, 72,117,116,113,132, 11, 6, 90, 1,168,231,118, + 4, 5, 79,200,147,219, 31, 28, 32, 37, 13,199,167,200,242,136, 42,212,185,179,235, 33,194,183, 84,197,104, 6,148,151, 35,161, + 4,174, 51,225, 17, 39,182, 9,139,138,180,247,116, 1,116, 92, 45,128, 42,105,187, 91, 14,144,217, 60, 39, 10,180,239, 41,186, +118,240, 80, 72,213, 12,116, 39,106,224,105,245, 29, 43,116,149,239,171, 70,230, 38,121,204,180, 83, 89, 89,153,201,166, 99,161, +149,107, 56, 33,136, 96, 20, 66, 78, 11, 26, 86, 42, 76, 80, 78, 29, 69, 95, 9,235, 41,180,105,110, 55,181,194, 53,148,231,166, +219,156, 34, 21,210, 26,137,252,108,205,177, 74, 32,186, 52, 30,138,217, 90,180,134,219,141,200, 67,225,103, 74,211, 78, 66, 65, +237, 90, 44,165,108,223,166,139,158, 71,146,213, 92,172,254,114, 51,183, 92,242,196, 56,124,174,163,176,221, 69,242, 85,117, 70, +145, 25, 33,113, 54,212,203, 7,175,102, 89, 60,157, 93,135,126,196,222, 73,209, 71,136,193,206, 85, 46, 59, 97, 55,206,110, 46, +167, 87,172, 73,189,109,164,212,189,193,254,217,248,196,230,116, 4,215, 92,163, 30,175, 71,235, 31, 63,191, 7,242, 69,217,211, + 75,239,212,154, 12, 22,219,222, 28,108,191,121,248,202,119,221,147,203,211,167,119,159, 39, 25,199, 66, 34,167, 83,155,110, 70, +220,232,116,224, 69,241,124, 42, 86,155,245, 78,127,247, 42,190,148, 51,122,212,159,194, 7, 68,203,154,135, 31, 61, 10, 91, 34, +149, 27,147,207,133,177,146, 48,158,239,210,209,167, 17, 79, 72,241,220,195,241,249,177, 72,235, 88, 27,157,141,138, 82,136,137, +168,212, 42, 9,232, 18,223,197,106, 3,226, 80,253,131,197,204, 88, 25,240,151,180,163,125,215, 74,235,249,249,209,183,251,237, +142,115, 32, 15, 28,114, 49, 48,204, 60, 83, 63, 79,212,201,177,154, 78, 17, 49,140,145, 34, 71, 1, 9,251,155,101,154,148,232, +171,164,225,181, 45, 65,238,248,107, 14,119,101, 93, 13, 76, 80,232, 50,213,158,175,154,109,212,183,229,203, 21, 65, 16,215, 97, +229,232,182,213,224,150,218, 25, 52,246,118,244,238,182, 53,216, 82,157,158,210, 45,193,236,122,181, 51, 44,238, 38,124,229,106, + 52, 84, 95, 62,149, 31, 22,239,206,208, 36, 21,109,114,174,230,184,148, 60, 47, 2, 63, 68, 2,138,179,164, 29, 52, 1,183,241, +160, 53,195,102,175,213,199,155,141,238,214, 44,157,209,179,211,226, 62,106,228, 70,184,179, 40,225,136, 22, 52,196,227,120,140, +197, 7,216, 10, 91, 29,252,127,227,235,139,183, 47,222,242,252, 68, 93,198,243,228,112,255,241,143,209,247,172, 88, 52, 1, 76, + 23,115, 84,202,209,112,216,235,220,126,116,247,240,215,120,136,136, 65,204,227, 99, 40, 15, 81, 16,226,205, 90,212,101,210,183, +234,175,191,190,224,166,160,225, 99, 35, 8, 44,162, 93,250,223, 74,217,137, 2,194, 50,116,114,230,136,181,178,254,151,241, 50, +199, 63,175,147,201,147,123,207,198, 55, 99,181, 26,111, 10,143, 90,201, 38,152,101, 84,210,141,201,144, 81,120, 22,230,141,205, +125,208,127,156, 84,151,226, 60, 86,189, 66,250,184,235, 30,179,147,241,251,248, 71,105,146,103,232, 26, 75,115, 35,241,107,251, + 91, 84,216,244, 20,156, 15,253, 22,128,172,107,217,109, 26,136,162,227, 87,108, 39,113, 75,154,146, 54, 45, 37,149,218, 64,139, + 64,149, 88,176, 64,130, 5,172, 1, 33,177,226, 79, 16,223, 3,123, 22, 72,136, 31, 96, 65, 17, 32, 36, 22,136, 71,121,180, 13, +205,203,137,227,215, 56,118, 56,247,218, 41, 72, 72, 89, 36, 82,235,196,158,153,115,207,157,185,247,156, 2,223, 65,118,104, 53, +142, 59, 0,104,149, 83, 6, 50,162, 52,203, 72,156,123,227,223,196,166,201, 27, 39, 1,134,204, 4, 77, 83, 14,107,217,153,106, + 29,169,107, 97,205,202, 54, 29, 89,190, 63, 42,196, 90,189,149, 81, 93,151, 17,209,145,177,194,170,173, 73,197,116, 44, 82, 74, +137, 88,250,114,182, 88, 61,131,121,231,147, 62,220, 52,102, 1,166, 66,103, 49, 15, 71,220,159,157,178, 80,167, 58,207,210,103, +220, 48,138,196,109,238,234,140,169,196,126,220,185,134,149,170,252,234,255,196, 79, 90, 48, 23,184,233, 31, 1, 64,103,207,117, + 17, 81,117,121,106,155, 22,104,120, 70, 85,134,153,122,106,158, 67,199,176,228,210, 7,162, 58, 14,221, 60, 61,108, 46,109,188, +255,250,182, 51,234,130,201,134, 73,144,139,144, 0,143, 76,211,162, 54,212, 52, 38, 72, 34,145,219,217,222,238,213, 71, 15, 31, + 63,123,245, 12,208, 79, 14,244,220,183, 9, 14,154,215, 89,226,167,198,233, 52, 72, 66,228, 49, 36,254,103,216,219, 43,237,227, +241, 49,230, 31, 38,238, 48,112, 7,129,235, 6,125,140, 33,160,231,250,165,155,247,110, 61,120,247,249,205, 42, 40,115,138,152, +138, 48, 35,249,118,213,193, 56,154, 68, 89, 44, 89,227,142, 15,160, 98,192, 15,114,168,132,204,166,106,229, 50,254,204, 40, 33, +240, 40, 92, 2,168,133, 41,210, 76,133,234, 29,145,151,201, 20,193,128, 32, 48,212,105, 75,138,211, 79, 60,202, 59,215,238, 31, +116,190, 17, 58,209, 37,181,178, 85,102, 51,113,191, 8,190,162,144,202, 32,241, 85,131,218,133,214,150,206,135, 88,141,149,154, +235,247,241, 76, 64,112,102,133,195, 48,157,107, 2, 68,192,151,129, 98, 97,228,247, 39,253, 52, 77,150,156,134,100, 70,191,177, +212,162,210, 74,174, 30,171,152,213,203,173, 61,124,196,165,176, 32,219,205,221, 92, 38,236,250,206,141,227, 97, 39, 63,194,193, +183, 55,156,198,143,222, 65, 20,133, 36,144, 38,196, 98,181,134, 21,222, 29,157,120,177,183,181,182,211,117, 79,200,247,146, 74, +227,207, 78,147, 4,143,107,179,177,121,121,115,175,231,158, 76, 89,159,114,232,117,193,178, 59,195,195, 34,231,229,129,246, 35, +239,168,127,136, 0,179, 94, 63, 47,101, 4,114,192,194,191, 42, 70,106,171,113, 97,171,189,253,244,229,147,195,222, 47,140, 82, +217,180,135, 62,169, 80, 1,205,201,239, 8,153, 47,133,186, 12,193, 15,248, 11,148,173,148,200,178, 99, 56, 25,176,206,129,122, +214, 89,225, 48, 95, 45,105, 90,238,215,131,255, 45, 27,214,162, 83, 3,150,197,115, 53, 74, 13,116, 71,215, 21, 62, 5, 94,175, +173, 75, 54, 11, 77,146,168,164, 82,171, 58,235,148,138,122,117,249, 74,235,202,200, 31,165, 83,105, 26,230,221,107,119,129, 59, +164, 75, 64,156,108,166,228,162, 9,132,201,148,209, 98,125,153,150,233, 77,163,170,219,105,221,222,166, 29, 87, 64,112, 42,133, +235,138,110, 87,120,129,136, 49,252, 88, 91, 50,211, 12,221,118,226,113, 95,122,221, 92,223,149, 13, 48,232,114,134, 70,181, 12, + 84,205, 70,115, 84, 53,112,179, 73,128,165, 43, 28,135, 20,102,144,247,145, 11, 65,174, 69,168,241,235,244,141, 86,220, 86,177, +239,153,205,145, 61,127,147,136,225,145,248,248, 78,124,242,246, 95, 27,106,101,181,162, 91,131, 73, 79, 87,140,246,218,197, 19, +143,172, 19, 87,107,205,206,224,247,136,234, 41,144,197, 6, 82, 74,246, 59, 61, 23, 39, 73, 60, 13, 43,214, 66,202,114,229, 97, + 28,225,198,183,155,109, 76,209, 73,228,219,134,141, 37, 31,203,216,243, 71, 6,245, 72,198, 59, 27, 59,207,247, 95, 88,134,133, + 60,224,227,247, 15,131, 96,104, 26, 96, 15,224, 70,182, 23, 79,124,233,247,189,222,151,227, 47,116,108, 38,102,200, 47,193, 87, + 86,234,205,101,103,249,136, 68, 65,168, 31,158, 59,229, 20, 22,127, 22, 81, 34,211,194, 4,133,172, 1,243,125,115, 4, 72,208, + 89, 57, 47,126, 21, 69, 93,254,169, 15, 23,155,247,169, 42,166,156, 69,250,131, 41,181, 23, 48,127,229, 77, 98,234,141, 96, 27, + 60, 61,215,138,164,195, 78, 42,193,196, 12, 44, 58, 73,255, 53,200,182,169, 44, 48,213,169, 43,158,176,164, 98,179,166,130, 86, + 50,169, 82, 32, 57, 85, 50,248,107,104,252,255, 43, 55,112, 21,202, 31, 1,168,186,150,222,198,169, 48,122, 99, 59,118,226, 71, +156,135, 39, 68,125, 12,101,132,152,142, 70, 2,129,216, 32,216, 34, 36,182,252, 17,216, 32,177,225,151,161, 65,204,128,196, 10, + 6,161, 2,139,138,121,209,166, 77,211,214,137, 99,215,142, 99,155,115,190, 59, 25, 6,169,139, 72,173,210, 68,190,223,185,223, +227,124,231, 16,223,229,165,165,201,156,178,116,167,229,203,168,197,220,212,220,160,245, 28,151,197,178,238, 47,171,166,109,216, +136,109,156,236,140,237, 60, 86,166,150,148,213,218,110, 91, 36,182,145,116, 36,212,116, 44,215,226,213, 71, 95,138,183,119,239, +161,252, 1,208,139,132,183, 45, 51,144,182, 56,217,151,185,140, 38,122,110,255,211,247, 62,255,243,244,200, 52, 94,222,103,142, +232, 6,203,150, 85,107,203, 98, 98, 2, 24,116, 2, 98, 16,125,134, 52,179,174,177,100,197,223,230,178,137, 31,133,227,113, 56, +222,143,232,249,224,119,195,180, 72, 59,150,131, 79,219,182,156, 56,187, 70, 68, 29,188,113, 48,199, 29, 43, 45, 96,189, 15,141, +139, 7,103,251,116,113,234, 80,229,133, 78, 38, 52,213, 19,214,201, 2, 89, 42, 66, 13,159,214, 48,162,222,100,158,206, 74, 89, +203,162,197, 17, 21,239,236,100,185,122,244,248, 97,217,148,149, 65,119, 80, 50, 85, 25, 63, 86,199,102,150, 74, 62,143,200,145, +139, 77,105,179, 42,211,121,114,129,107,198,182,156,143, 14, 63,249,250,139, 47,127,252,235,103,100,133, 64, 61,211,110, 47,243, +229, 15,191, 61, 24,134,227, 40,140,174,210,185,105, 22,128, 11,128,123,223, 55, 43, 49,237,192,169,161,102, 91,213, 0, 3, 59, + 29, 3,201, 43,107,116, 83,221, 30,245, 90,164, 48, 26,155,162, 54, 37,244,147,138, 34, 14, 40, 81,242,117,181, 88,150,121,190, +193,227, 68,249, 14, 76,161, 39, 36,101,143,234,227,233, 49,237,108,148, 94, 68,104,101,148,216, 52,180,212, 51, 62,107,200,238, +118,165,105,152, 81,127,124,184,123,255,143,127,142,240, 91, 26,237, 74, 74,219,144, 46,109,123,182,207, 25, 19,155,200, 45,167, +237,234,237,130, 65, 55,202, 54, 89,224,120,138,140, 26,247, 44, 62,225, 44, 71, 22, 23, 1,166, 40,165,103,241,185,197, 97,105, +117,153,156, 35,157, 71,178,246, 98,254, 76,116,134,185,251,138,111,122,195,114,208,241, 2,255,155,175,190,125,240,232,187,189, +232,118,198, 85,100, 26,105, 38,171,216,216,114, 8, 74, 90,162, 51,185,139,179,120,122,241,194,119, 67, 74,234, 91,142, 0,151, +209,247, 70, 61,102, 94,172,255,240, 56, 16,179, 72,171,145, 33,206,150,231,248,215,125,183,143,191,188, 78, 46,187,182,115,114, +117,242,228,249,241,208, 31,145, 41,104,180, 23,233, 18,176,222,200,184,152,198,217, 65, 4, 80,198,149,182, 51,220,199,181,132, + 99,198,141,202, 86, 43,112, 67,233, 44,161,150,202,164, 67,206,201,183,192,166,161,125,219,113,225,225,203, 90, 45,235, 86, 56, + 46, 0,178,244,162,175,180,140, 9,112,170, 99,106,118,118, 45,148, 83,170,233,225,104,173,138,213,233,245,116,111,176,179,200, +151,131,238,224,201,236, 41,128, 12,248,219,239, 14, 88,243,113, 29, 90, 27,214, 55,180,175, 65, 25,110, 82,195,225, 94,216,219, +255,236, 80, 73, 31, 83,226,186,173,226,132,251,171, 69,161,114, 96,188,242,247,239,122,147, 55, 59,193,168,202, 86,213, 58,149, +138,139, 12, 63,139,253, 25, 18, 46,137,236,109,185,126,112,158,144, 51,229,137,218,228,202,247,148,219, 37, 91,198, 82,255, 55, +153,123,189, 67,241, 42, 91,223,108, 95,224,231, 70,157,255,173,142,126, 87,105, 82,253, 50,249,254,228, 50,203,175, 16, 11,180, +128,173, 55,243,248,146, 10, 52, 85, 29,167,139, 97, 48,244,187,222, 69, 50,215,189,232,154, 42, 41, 37,158,166,108,228,179, 97, +163,211,190,183, 38,119,206,174,167,184,169,102,139, 89,193,164,193, 73,242, 4,193, 62, 12, 34, 68,110,122,147,149,245,250,157, +157,187,253, 96,232,217,174,197, 1,140,131,119,235,145,192,157,173,139, 98, 55,218,195,155, 80,230, 23,160,180, 89,123,222,240, +195,247, 63,254,233,215,135, 59,131, 73,202, 45,217, 66,184, 58,245, 86,133,166,182,148,249,238,193, 7,103,241, 84, 47,242,117, + 44, 23,153, 82, 81, 22, 90,247, 8, 73,131, 69, 99, 85,233,129,170,214, 86,208,171, 22,129, 60,201, 80,181, 33,182,161,167, 24, + 29, 68, 55, 78, 66,217, 20, 90, 23, 84, 27,135, 10,237, 87,173,101, 28,245,106, 5, 85,143, 29, 71,189, 91,107,170,219,123,101, +149, 59,182,107,139, 92,249, 75, 17,233,173,145,227, 22,216, 95,127, 22,122,180,248,159,205, 19,126,241,175, 0, 76, 93,203,110, +211, 64, 20, 29, 79,108,231,253,104,161, 15, 80, 83, 72, 83, 4,165, 80,170, 82, 42, 64, 72, 8, 9, 9,177,224,107, 96,207, 55, +176,237, 18, 9,126, 3,177, 64,128, 16,221, 65,203, 75,226, 21, 72, 19,226, 52,137, 95,245,216, 30,238,153,113, 5,139, 74, 85, +165,198,142,125,231,206,157,123,206, 61,231,168, 63,163, 74, 54,133,137,104,111,245, 50, 56,121, 9, 88, 89,128,179, 98, 49,118, + 15,164, 78,165,136, 98,209,156, 93, 26, 78, 28,237, 37,207,178,118, 75,134,228,106,176, 81,207, 2,128,100, 9,195, 28,122,178, +145, 51,249,115,169,181, 65, 47,169, 81,170,107,120, 74,192, 94, 39,130, 14, 3,186, 37, 17,197,241,183,193, 55, 1,137, 96,165, +250, 43,181, 12, 27, 34, 81,187, 75,209, 31,128, 86,201,132,138, 47, 52, 99, 84,214, 95,109,174,143,131, 17, 93,171, 82,172, 53, +167,154,253, 73,143, 78, 73,251,163, 94,127,210, 87,199, 91,122,115,242,218,217, 27,189, 97,151, 34,198,226,121, 74, 7, 84,163, + 73, 37,113, 99,114,179, 81, 3, 35,144, 78,238,180,183,231, 77,123,226, 79, 22,102, 91,225, 97,136,125, 37, 85,222, 43, 6,187, +121,241,246,108,125,230,199,224, 59, 37,125,186,121, 1, 86, 12, 0, 21,211,182, 67,137, 94,127, 64, 5,122,170,181,164, 25,196, + 27, 88,106, 89,230,116,105,202, 21,190,159, 4,106, 20, 34, 85,246,202,156, 22, 17,229,221, 90,169,106,112,107,231,235, 27, 74, +190,159,246, 63,218,133,124,173, 92, 95,107,173,209,243, 60,115,234,108,174,192,207,181, 87, 36, 51,251, 78,151,115,244, 37,139, +121,219,153,248,128, 20,149, 67,165,226,190, 75,205,130,167,224, 15, 14, 69,115,170,166, 28,165,149, 56,179, 52,124,145, 27,208, + 15, 68,104, 13, 11, 27,184,180,204,180,148,167,181, 6,107,189,246,204,185, 32,242,225, 67,157,234, 49,122, 36,125, 77,130,165, + 69,146,233,248,171, 17, 48, 42,236,128, 30,203,164, 57,211,218,249,252, 26,153,139,231, 10,118, 41, 6, 10, 4, 85, 22, 90,138, + 97,114,120,162, 62, 63,215, 56, 57,194, 36, 87, 74, 55, 1,125,215, 98,141, 82,246,230,210,214, 94,103,119,163,125,117,226, 83, + 53, 26,231, 12,152, 53,210,222,182,178,176,218, 25,192,150,203, 4, 10, 2,143, 77,116,215, 33,146,135,186,175, 90,110,160, 15, +194, 57, 21,110,174,231, 61,127,241,140,174,235, 65,156, 14, 61, 4,144, 50,185,161,193, 75,219,180, 12,165,172, 75,255, 75,201, + 17, 30,194,146, 45,206, 44,174, 46, 94,232,143,123, 24,245, 70,133,107, 35, 93, 97,226,137,150,159,113,105,233,178, 23,250, 97, +228,113,101, 14, 29, 9, 65,223, 98,237,244,250,254,193, 47,202,114, 84,228, 52,138, 53, 55,112, 53,237, 94,169,183, 42,213,239, +208,167, 74, 19, 77,246, 88, 80, 78, 12,227,192, 84,149, 19,125,230,116,185, 78, 59, 58, 29,254,168,234, 7, 75,152,211, 35, 51, +139, 96,163, 73,229, 3,142,171, 80, 60,208,239,199, 43,211, 43, 11,231, 7,174, 67,103,226,122,161, 86,205, 87,198, 64, 47, 18, +221,180,201,169,165, 68,225,141, 17, 45,131, 43, 49, 62, 64,127,192,186,115, 38,211,224,155, 54,157,144,242,234,153,235,138,231, + 99,211, 54,109,129, 16,207,162, 72, 92,169, 84,217,242, 49, 36, 0, 48,141,138,204,113,152, 27, 80,114, 79,195,208, 40,148,173, +217, 38, 96, 65,216,155,201,112,212, 3, 52,132,254, 59,134,100,129,108,160,247, 4,119, 87,180,221, 45, 14, 69, 48,147,150,189, +199,188, 49,146,117,177,196, 40,122,254, 87,181,202,178, 73,250, 95,205,158, 28, 1,170,130,201, 1,251,178,203, 62,125, 96,137, +207,118,243,111,222,198,253,216,167,143,135, 70,163,234,202, 42, 39,141,108, 40,218,139,124,218,234, 18,173, 13, 13,194, 17, 4, +218, 50,236,157,163,238,209,226, 4, 7, 46, 69, 87,114,111,235,238,187, 31,239, 91,115,109, 47,192,156,202,246,195,167,157,223, + 95, 95,237,189,244, 69, 56,114,157,238, 65,183,243,231,251,192,115,198,222,152,195, 73, 66,236, 15,187, 80,123, 77, 65,243,160, + 16,202,129,103, 85,161,156,112,227,214,157,251,219, 15,158, 60,122, 60, 63, 61,223, 25,252,162, 47,118,121,121,243, 39,196,227, + 98,165, 22,140,122,101,232, 13, 5, 26,173,117,122, 11,145, 66, 28,193, 63, 65,155,206,164,219,159,171,195,147, 64,104, 93, 48, + 35,235,179, 79, 85,142, 29,138,208,212,101, 50, 20,177,112, 18,133,248, 48,220, 25, 67, 11,124, 63,166, 33, 4,153,102,162,145, +250, 44,165,188, 30,255,233,245,170, 81,205, 36, 86, 82,169,169, 20, 32,119,233, 6, 80,122,228, 93,124, 4, 68,102, 10, 25,218, +244,151,103,196,229, 74,161,170, 70,131, 65,214,252, 43, 0, 83,215,178,219, 52, 16, 69,199,142,243,112,220, 36, 78,155,132, 10, + 20,154, 8, 40, 68, 80, 94, 2,169, 8, 85, 44,216,178,128, 47,224, 7, 16,159,193,146,143, 96,201, 31,176,130, 29, 11, 86, 32, +212,128,250, 34,161, 80, 39,212, 14, 73, 28,199,227, 39,247,204, 36, 21,203,168, 81,237,204,204, 61,115,159,231,156,225,187, 38, + 56,169,139, 82,144, 79,202, 69, 46, 53,168,144,237,143,133,176, 8, 38, 56,196,181, 49,114,109, 66,128,101,135, 78,186,228,170, +196,223,232,112,147,255,187,181,113, 27,138, 45, 1,191,222,186,217,168, 32,239, 65,255,240,196,249, 21,129,212,201, 79, 99,132, + 60,200,166, 21, 77,244, 75,144,191, 28, 4,139, 82,195,127,205,253,213,226, 26, 16, 7,182, 70,128, 9, 34, 98,138,173, 66,244, +186,164, 82, 84, 83, 73, 51,167, 19,139,246,175, 42, 88,223,172,177, 69,118,110,174,212,180, 5,141,143,172,124, 35, 85, 23,166, +177,224,234,139, 9,196,233, 72,153,134, 89,210,205, 25,159,148,114,101,151, 99,204, 65,215, 10, 15,174, 61,220,183,246, 30,223, +122,252,237,184,235,161, 35, 48, 37, 95,190,108, 84,119,251, 95,251,118,175, 98,172, 74,185,237,186,185,238,248, 14,112,161,121, +243,203,112,119, 16,143, 28,213,243,212,185,157, 76,156,208,157, 69,158, 6,131, 76,251,206,177,142, 68, 56,212,221,200, 68,141, +188,209, 89,239, 88,174, 69,235, 77, 27, 64,111,194,147,112, 26,120,228, 27, 62,219,126, 26, 41,225,222,240,200,139,253, 74,217, +212, 11, 70,247,176,187,115,111,231,124,251, 82,175,255,125,213, 76,115, 57, 22,170,126,172,136,110, 42,113, 67, 75, 25,177, 48, + 78, 2,158, 6,243,176,174,151,200,255,202,103,193,140,158, 73, 64, 61,230, 37, 17, 90, 44, 80, 18, 36,131,165,119, 32,155, 77, + 38, 54,249,240, 25,123,252,199, 11,102, 32, 73,207, 22,162, 40,214,224,237, 42,171, 37, 73,224,131,106,162, 84, 2, 67,130, 11, +228,254, 10,173,204, 96,124,146,193, 88,178, 38,107,227,152, 79, 94, 12, 31, 97,159,200, 33,178,221, 33,238,161,194, 10,109,196, +156,207,233, 52,211,158,110, 95,219,222,237,125,109,214, 91,195,177,133,241,136, 52,190,119,249,254,225,239, 61,114,150,201, 56, + 67,209, 83,220,168,172,227,164, 49,180, 21,210,121, 47,233, 21,122,208,130,181, 34,142,201, 26,101,212, 6, 70,120,114,168, 37, +243, 53,240, 80,148, 80, 48,130,151,191,114,161, 19, 69,156,188,138, 87,207, 95,127, 63,238,142,103,227,195,147, 67, 46, 36,244, +200, 2, 9,253, 9,194,124, 14,207,107,171,117,167, 63,236,129, 7,148,160, 92,201,108,109,220,232, 13, 15,194,132,188, 23, 10, + 55,125,244,195,229, 12, 10,161, 40, 46, 92, 74, 10,203,233, 17,108, 32,249,254, 20, 84,209,135, 38,164,199,102,160, 34, 16, 50, + 38,116, 91, 64,136, 71,216,129, 12, 98, 4,114,165, 47,158,188, 60, 26,244,131, 8,201, 46, 10,127,119, 58,143,236,137,131, 10, + 51,211,204,149,202, 79,187, 55, 3,169,150, 36,150,203, 72, 49, 19, 90,207,230,234, 69, 15,161, 0, 19,228, 60, 66,113, 78, 80, + 79,170, 82,195, 83, 81, 54,106,173,137,247,215, 26,253,158,131, 10,130,192, 29,139,145,215,178,211, 36,112, 15,236,206,102,157, +213, 13,128,199,156,179,209, 20,248,206,121,202, 3, 70,209, 97,121, 13,191, 11,232,238,113,161, 49, 11, 26, 87, 85,149,248,158, + 67, 39,141,134, 36,123, 86, 93,230,220, 85,164,101,226,128,185, 35,230, 58,232,129,161,179,156,203, 47,115, 50,103,229, 83,137, +242, 18,238,125,150,158, 50,107,159,237,118,217,192, 66, 79,181,171, 57,239,245, 15,142, 83, 16,247,161,228, 77, 23,122,227,242, +186,194, 80,190, 32, 27, 20,247,151, 96,167,151, 36,175, 20, 72,121,156, 23, 11, 69, 90,106,161,192, 7, 91,166,203,184,219,255, + 70, 95, 32,220, 16,213,157,233,219,119,111,126, 88, 63,138,144, 77, 86, 55,207,111,250, 33,215,115,122,171,209,154,204, 39, 87, + 47,108,210,158,174, 25, 53, 55,112, 3, 48, 41,113,134,113, 51,125,236,253, 5,203,150, 51, 42,233,213,207, 31, 63, 29,159,246, +232,153,181,149,198,209,240,136,238,149,214,185,118,187,214,134,186,158,162, 84,141,170,235,187,145,228, 53, 89,182,188,208,203, +221,110,223,245,230,179, 63,211, 1,216,144,132, 23,126,166,151,158,205,228,208,197,151, 8,234, 84, 53, 83, 46,152,145,152, 87, + 16, 41,151,226,197,198,198,216, 3, 95, 44, 29,145, 78,243, 58, 91,248,175, 41, 61,200, 23,170,118, 98,180, 68, 50, 38, 74,255, + 95,162,175, 44, 34,178, 5,101, 42, 19,170,125,169,148,197,198,167,122,169, 6,217,128, 37,133, 60,166,148,242, 40, 92, 7, 98, +230,238,159, 0, 60,157, 75,111, 19, 87, 20,199,103, 60,239, 71,198, 30,227, 7,110, 18, 39,128, 65, 20, 34, 37,148,116, 19, 88, +130,170, 86,106,171,170,234,130, 29,253, 10,221,245,171,176,130,101,165,130, 96,209, 34, 81, 16, 2,177,104, 69,120, 8, 80, 69, + 73, 28,112,163, 60, 93, 39,182, 51,227,216,241, 60,250, 63,231, 58,236, 28, 47,162,235,185,231,158,123,254,103,206,249, 29,217, +162,151,135,120,128, 26, 66, 90, 91,115, 6, 84, 73, 71,231,205, 53,179, 33, 53,109,142, 6, 99,107,170, 81, 45,212,194, 65,135, +251,245,163, 84,116, 84,141, 48,248, 12, 1,161,112, 88, 22,163, 70,104, 58,109, 76,129, 55,182,171,224,149,186,189, 29,108,228, +152,233,195,106,123, 81, 48, 83,253,236,245,251,103, 98,236, 49,119,189, 66, 53, 59,125, 66,220,100, 4,121, 88, 30,129, 4, 18, + 73, 52,173,112,108,105,105,212, 17,238,152, 14,174,116, 28, 15,230, 76,167,142,238, 20,189, 34,130, 65, 71,119,195, 40, 60, 55, +253,249,202,198, 50,190,129, 39, 90,218,124,199,247, 39,201, 37,209,125,195,213, 65,112,217,148,195,161,192,115, 24,194, 2,248, +248,170,188,236, 49,216, 13,142, 43, 97, 5, 15,246, 63,173,158,181, 13,247,213,135,151,112,199,182,110,239,113, 60,149, 50,240, + 27,255,164,156,157,152,240,199, 91,102,239,225,210, 99,132,164,236,113,196,168,193, 68, 26,129,249, 40, 87, 78,229,166,120,150, +100, 7,166,157,209,232, 13,228, 96, 96,100,212, 83,133, 99, 88,252, 48,141,190,153,253,170,209, 94,131,131,104,236,254, 59, 95, + 59,191,112,126,225,210, 79, 95,136,125,250,237,218,239, 91,141,205, 95,239,223, 56, 94, 58,232, 71,233,171, 70,179,221,235, 7, +196,159, 20, 88, 99, 98, 9, 80,101, 65,130, 83,188,127,113,186,226,218, 6,252,192,224,128,114, 2, 89,215, 90,233,247,135,240, +221, 52,139,149, 18,238,176, 58, 91, 77,245,112, 98,181,251, 65,162,156, 27,109,224, 84,241,196,242,250, 91, 17, 62,120,166,143, +131,241,186,241, 82, 76,145, 80, 84,173,224, 29,221, 13,182,227, 56,134,226,201,185,121, 60,115,238,250, 73, 16,236,127,191,240, +195,157,191,110,193, 90, 8,129,203,169,252,172,235,143,251,213, 55,171, 47, 20,230, 95,169,178,106, 26,118, 39,220, 25, 63, 50, + 85,246, 75, 47,234,139,144,253,147,165,169,247,219,117, 40, 24, 67, 55,243, 94,233,136,235, 47,214,159,154,154, 42,146, 64,204, +125,136,107,149,211,203, 27,239, 68, 80,131,231, 15, 61, 78,156,150,168,255,221,194,149, 95, 30, 93,255,114,254,219,199,111,238, + 67, 11, 66, 47, 35, 38, 50, 84,139, 33, 55,137,201, 45,205,154,162,205, 29,155,135,189,204, 30,159,123,240,252,143,153,233,153, + 39,127, 63,161, 25, 4,114, 92,242,202, 59, 65, 11,158,221,210, 92, 8, 23,143,109, 27, 34, 6,113, 55, 81, 0, 83, 41, 24,116, + 25,101,200, 32, 30,106, 52, 75, 56,241, 74, 78,150,144,209,105,130,123,162,195,220, 18,193, 16, 46,103,203, 59,189, 93,110, 95, +138, 24, 38,162,216,170,141, 75, 7,254, 10,203,110,182,215, 60, 43, 7, 23,156,163, 4, 78,140, 24, 92,101, 68, 88,214, 34,230, + 90, 37,119,180,217,105, 86, 11,213, 70,179,161, 42, 74,216, 15, 89,181, 19,146, 26,235, 12, 15,246,230,170,179,237,253, 46, 46, +170,173,238, 86, 68, 16,102, 21,235,108,117, 91, 88, 29,249, 99,130, 33,227,118,145,117, 77, 54, 53, 2,231,187,164,225, 51, 23, +207,126, 93,108,254,121,225,231,203, 82,209,150, 58,129,180,217,148,154,109,169,189, 23,117,131,216, 28, 51, 38,207, 48,130, 76, + 14, 86,255, 9,215, 87, 20, 30,176,164,144, 15,207,104, 42,209,255,153,225,174, 81,252,174,107,236,226,249, 27,214, 75,148,243, +193,159,150, 35,229,125,169,144,151,252, 28,125,206,152,135,253, 77,145,148, 12,164,160, 35,253,215,146, 90,109,170,219,137, 34, + 49, 6, 34,189,109,222,124,219, 29,168, 84, 48, 30,143,122, 14, 35, 62, 36, 68,227,130,233,100,237, 44,126,250,122,155,180,245, +144, 47, 72,156, 85, 4,236, 80, 91,147,133,234, 90,107, 21,134,234, 88, 14,158, 14, 14,241,144,166,115, 4,124,159,196,135, 44, + 23,229,199,203, 87,239, 46,222,243,189, 60,108,169, 86, 57, 89,223,168,115, 10, 33,214, 13, 27, 59,137,219, 58,102, 56, 4, 51, +191, 41,249,227,218, 57,236, 17,165, 34,137,110, 27,143,185, 16,238,219,148,113,224, 90,118, 1, 77,194,115,134,128, 44,185,149, +221,126,135, 85,169,120,199, 68,102, 42, 32,217,212,188, 70,116, 13,234, 72, 34,116, 4,119,135,192,132,161, 21,100,106,150,236, +101,228,195,204,124,146,212, 62, 57, 93,223, 92,250,248,230,148,230,235,240, 76,190,136,210, 56, 50, 73, 5,146, 45, 9,207, 23, + 74,120,128,205, 71,207, 74,225,186,161, 25, 41, 15,255,163,218,141, 52,130,251,210, 51, 52,209, 19,209, 24, 23,181,139, 13, 16, +236, 37, 46, 33, 22, 85, 72,135,213, 37,255, 11,192,212,213,244,184, 77, 69,209,103, 59,246, 36,153,201,212, 33,205, 71,167,153, +164,204,128, 40,168, 85,169, 64, 8,117,195, 2,118,195, 6,177,227, 47,244,247, 33, 33, 36, 42,181, 11, 86,136,138, 25,209,170, + 64, 71,233,196,249,152,196,137,237,216,241,119,108,238,185,246, 32,164, 89, 69,147,143,247,252,238,123,231,220,119,239, 57, 37, +126,103, 65, 96, 8,226, 16, 44, 69,164,229,187, 0,114, 78, 41,243, 83, 28, 81,113,150,174,220, 5,209,198,154, 86,231, 75,134, +255,169,221, 43, 80, 77,170,105, 85,244,136,203, 18,139,247,202,250,126,243,193,224,209,204,154,246,154, 71,116, 54,192,235, 50, + 13,182,128,141,217,210,154,113, 77,105,217,206, 82, 74, 26,243, 9,254, 95,225, 17, 13,179,177,167,211,244,168, 56,171, 35, 34, + 23,240,237,147, 33, 26, 12, 55, 40,214, 84, 61,172,235,222,214,233,183,135,174,111,179, 40,121,190,176,175, 9,137, 83,220,122, + 80,134, 43,149, 67,110, 55,218,159,158,124,230, 71, 65, 2, 43,122,176,230,156,181, 88, 59,183, 58,143, 79,191,184,188,254,155, +109, 84,113,117, 70,145, 79,171,136,130,133, 16, 52,253,152, 32, 13, 97,184, 44,164, 66, 18,153, 8,117, 6,229,122, 57,147,133, +159, 56,163,252,210,136,141,195,122,125,191,166,113,182, 87, 66, 64,128,104,179, 82,170,164, 49,182,162,205,182,146,171, 8,155, + 88, 74,253, 93, 16,229,137, 31,123, 99,219, 24, 91,147,201,122,246,236,237,175, 23,243,191, 46,215, 35, 58, 86,175,108, 99, 19, + 58,211,115,227,213,139,139, 61, 26,247, 70,125, 53,250,243,157,105,168,185,252, 97,183, 58,117, 29, 90, 93, 72, 78, 43,108, 43, +195, 22, 16, 69, 21, 57,141,113,208,168,247,106, 53,194,247, 90, 42,212, 68,168, 66,178,195,212, 10, 98,215,143,161,190, 70, 99, + 11,147,131, 92,185,246, 54, 5,240,103,172,180,179,182,144,173,191,163,247,189,192,161,127, 89,184,179, 61,220, 92,193,249,152, + 27,181,209,105, 8,112,187,139,109,111, 77,135, 19, 29,195,244, 8, 30, 14, 30,255,114,241, 83,251,160, 87,170, 2, 64, 4, 8, +193, 1, 87,235,186,222,109, 30,177,138, 0, 60,233, 9, 82, 77,214,198,124, 61,197,220,200, 50,109,247,253,247, 6, 59, 68,215, +214,114,161,206,184,141, 61, 34,196, 21, 5,250,116,135,181, 38,189, 98,251,107, 90, 7,144,112, 64,121, 0,151, 30,101,216, 31, +167,171,241, 38,116, 31,222,123, 68,208,149,102,181,173,119,233,176, 35,166, 72,172,232,251, 39, 63, 92, 45, 71, 26,167, 71, 76, +103, 49, 94, 92,105, 10,220,124, 76,103,229,250,155,167,103, 79,159,159, 63,223,209, 25,139,190, 77,233,180,119,186,176,167,159, + 12, 31,124,253,213, 55,231,175,255,160,128, 31,180,135,244, 35, 5,124,113,111, 21, 34, 72, 21,150, 71, 61,233,190, 79,177,173, +239,183,194, 40, 56,251,252, 91, 5,149,175,209,237,131, 22,122,226,178,132,182,233,187,205,187, 14,154,158,144,240,230, 70,149, + 44, 8,225, 90, 75,188, 4,190,238, 82,222,168, 54,130, 36, 58,110, 29,187, 69,149,167, 2,169,165,186, 86, 13,112,107,236,219, +129, 77,179,125,175, 59, 92,185,166,194, 68, 93,149, 42, 1, 63,174,153, 53,159, 90, 19,141, 89, 32,110,116,226,144, 86, 53,116, + 14, 34,175,213,104, 39, 80, 98, 40, 53,240, 21,110, 81,170,105, 13, 57,139,204,205,200, 76,162, 59,111,220,230,147, 33, 66,222, +218,138,141, 79,248, 61,193,251,125,133,224, 81, 69,141, 87, 11,111,254, 15,235,136,112,141, 29, 59, 83, 87,152,237, 34,201, 94, + 8,184,107,252, 87,145,203, 93,158, 8, 32, 54,122,138,207, 68,108,183,194,178,132,185, 4, 60, 95, 78,196,114, 42, 22,134,152, + 27, 98,252, 78,204,230,194,113, 69, 28,149,226, 99,180,165,254,172,253,120,238,171,245,202,233, 65,107, 95, 81,117,181,122,255, +232,254,218, 91,167,220,181, 72,203,111,208,238,211, 72, 55,220, 64,119,227,192, 11,112, 79,179,247,221,151,103,191,189,125,153, +224,166,154,232, 71, 68,224,215,130,182,123, 84,118, 73,103,226,227,227,143,174,157, 37, 5,230,239,151, 47,151,206,156,160, 61, + 19,118, 20,137, 16, 48,133,186,134,148,133, 73,216,209, 59, 65,232, 19, 42, 95, 57,230, 73,239,131, 32,242,135,157,161,233,152, +196, 12,104, 74,233, 59, 41, 62,232,195, 83,110,107, 96,253, 15, 98,189,176, 17,245, 2,207,165,160,136, 35,113,179,117,102,133, +241, 25, 87,194,208,131,195,214, 92,216, 33,112,211, 67,113, 67, 72,104,174,232,242, 3, 45,131,127, 41, 96,183,227, 91,112,194, + 80,112,135,205,121, 71,228,195,120,218,213,170, 90, 69,182,131,240, 95, 33, 8,157,223,248,237,150, 21,134, 50,147, 30, 92, 63, +104, 80,203, 0, 78, 61,210,251,166,187,164,213,174,105,181, 24,141,123, 82,129, 57, 74,217,225,155,236,123,145, 41,162,151,254, + 21,128,166,107,105,109, 34,140,162, 51,201, 36, 51,211, 36, 77,154,118,218,248,108,173, 15,180,104, 69, 91,177,226, 99, 41, 46, +116, 39,250, 35, 4,127,138, 11,255,128, 8,110, 21,164, 96,165, 32, 8,238, 84,170,161, 22,164,104,219,160,105, 76,147,166,147, + 76,230,149,121,196,115,239, 55,133,108, 2, 97,194,204,220,239, 62,207, 61,231, 16, 63, 51, 20,154,244,116, 57, 86, 33,241,167, + 10, 83,243,211, 11,141, 78, 93, 18,240,157, 84,162, 55,235,132,118, 66,114,149,112,218, 80,249,130,152,151,145,179,131,216,231, +178,143,171,192,192,107,152,117, 49, 5, 51,157, 3,219,181,224, 2, 10,185, 81,152, 63, 15,149,137,101,200,200, 79,102, 51, 58, + 23,164,177,104,237,139, 22, 13,107,173, 17,204, 28,199,224,222,213, 7, 91,136,126,220,251,131, 41,227, 62, 81, 26, 15, 73,155, + 23,185,191,127,238,232,249,237,230, 47,234,130,165, 68, 87, 86,208, 51, 17,239, 54, 51, 1,145,182, 7,222,125,163,179,107,123, + 61, 65, 74, 79, 42, 84, 25, 45,140,131,166,217,104,154, 36, 10, 35, 90, 30,101,226, 1,118,203, 57,195,246,186,126,224,186,136, + 70,126, 63,228, 5,105, 18,183,136, 2, 47,246, 34, 65, 64, 76,103, 67,238,107, 72,193,153,145, 91, 44,179,241,156, 32, 37,224, +221, 98, 89, 68, 12, 85, 73, 33,136, 22,211, 24,248,163,208,158, 16,185,123, 85,210, 53, 2, 39,100,210,248,137, 29, 57, 45,255, +160,110, 53,190,236, 84,151,215,222, 47,175,173,188, 88,126,181, 90, 93,169,238, 84,221,192,166,185,234,208,175,119,109,153,121, +201,149, 12, 14, 0, 79,188,224, 17, 20, 22, 47,143,165,172,148,186,124,220,152, 49,138,198, 56,146, 57,132,119,101, 92, 69,120, +196,213,195, 81,152,217,128,182,160,251,148,218,171, 17,179,163,201, 9,204, 10,150,170,105,140,153, 65, 77, 35,150,155, 69,254, + 48,109,204,118, 93, 51, 12,105,105, 8, 14, 29,174,191, 82, 60,218,182,219,136,163,251,118,139, 17, 32,169,177,252,152, 77,100, +238,114, 2,140, 35,172,125, 88,208,242,168,117,240, 0,241,132,247,186, 77,154,189, 39, 96, 39,106, 29, 58, 3,135,101, 84,201, +138,113,218,107,173,157, 27,115,119, 92,226,242,116, 30,222,122,248,109,235,171,150,201,113,202, 76, 3, 27, 94,196, 71,113, 41, +149, 10,227,168,169,251,142,181, 81, 91,135, 67,199,219,239,225,204,200, 41, 93,161, 18,161,214,220, 30, 68, 4, 55, 60, 82, 62, +254,228,254,211,133,187,139,223, 63,127, 27, 32, 37, 11, 3, 56,220, 43,247, 23,119,127,238,250,129, 83, 44,136, 93, 24, 19,247, +127,106,114,246,237,199,215,120, 33,211, 83,167, 17,186,240,162,175,157,185,190,111,181, 88, 81, 54,167,165, 85, 56, 69, 68,154, +152, 87,252, 96,141,176,147, 22,139, 85,145, 31,225, 94, 73, 73, 31,179,252,174, 60,148,133,204, 89,165, 84,185,120, 98, 30, 57, + 77,207,233,233, 89,149, 13,130, 50,246,124, 86,223,235,238,205, 24, 51,180,252, 18, 71,165, 92,137,198,245,172,159, 68, 91,123, + 3,183,109,237,243,102,214, 72,138,165,133,184,142,212,111, 93,184,217, 56,104, 8, 56, 32,167,180, 33,254, 8,105, 1,207, 27, +105,163,155, 61, 59,163,237, 68, 51, 51, 26,168,170, 62,158, 55,252,216,219,177,220,165, 80,145,230, 38,164,142, 37, 89,125,201, + 35,114,132,129,231,186,102,203,105, 55,156, 78,157,132,100,101, 49,225, 59, 84,185,165,203, 49, 2, 82, 97,255, 78, 31,150,236, + 32, 47,159, 73, 40,127, 25,158,201,247,196,244, 96,168, 8,225,251, 60, 79,242,124, 26,225,134,188,137, 60,100,118,219, 52,175, + 90,124, 42,200,157,139, 81,177,240,242,251,187,231,235, 31,158, 85, 87,223,212, 54,126, 52,127,159, 31,173,148,212,156, 31,163, + 12,141,123,196, 97, 23,242,130,201,144,229, 32,135,149,177, 35, 48, 30,220,245, 63,115,207,236,155,115, 39, 47, 33, 23,166,105, + 42,171,119, 33, 77, 36, 87,200,231, 17,207,170, 60, 82, 70,106,225,121,222,163,219,143,255,182,255, 34,150,195,138,150,206, 46, + 77,149, 39,107,173, 63, 68, 56, 31, 6,142,107, 31, 51, 78,108,238,110, 26,197,137,166, 73, 29,149,190,215,135,189, 9, 46, 70, +137, 69,107, 16,248,137,254,129, 58, 9,145,158,209,225,184,124,230, 14, 58,148,104, 58,108, 22, 15, 99, 33, 82, 67,252,184, 52, +233, 33,212,123, 94,207,199,188,240,204,100, 62,220, 76,147,146,102, 6, 61, 45, 26, 62, 34, 33, 76, 43,236,208,185, 35,173, 40, + 12,166, 17, 95, 99, 22, 63, 72, 11, 92, 11,199, 8,118,168,220,140,225,138,118, 68,213, 4,208,142,217, 75,104,182,218,115,123, + 8,142, 65,228,251, 9,130, 89, 64,121, 18,191,142, 99, 5, 51, 64,218, 36,167, 24,240, 45, 73,255, 5,224,233, 90,122,155, 56, +163,232,216,158,241,216,158,241,196,153, 56, 33,137,157, 16, 90, 19,160, 13,176, 0,132,232,162, 66, 60,182,221,180,172,216,132, + 95,195, 63,232, 63,232,174,170,212,110,250, 11, 42, 84,181,138,170,166, 45, 45, 68,136, 56,193, 78,140,237,121, 63, 60, 15, 79, +239,185,159, 65,242, 42,118,252,152,185,247,126,247,113,238, 57, 2, 63, 83, 18,221, 31, 1, 22,196,201, 6, 78,134,217,196, 31, +199, 32,218,198,135, 53,107, 38,121, 17,133,168, 43,155,215,239,124,122,231,232,236, 21, 35,202, 81, 13,176,144, 20,150,205,152, + 37, 6,228,192, 60, 69,145,214, 91, 27,172,223, 20, 48, 39, 18,194,110,194, 90, 25,130,201,184, 0,248,172,225,197,174, 12,154, +124,108, 60,102,172,143, 65,255,158,164, 81,141, 15, 85, 50,103, 83,107,159, 78,223, 86,152, 77, 47, 95,136, 69,167,162,248, 1, + 3, 39,221,194, 36,150, 69, 41,130, 56,139, 26, 75,171,214,129,127, 23,244, 89, 69,209,168,235,244, 3, 82, 60, 83,232,117,131, +254,138,205, 64,216,179, 76,181, 48,163,149,208, 73,156, 1, 87, 71,245, 65,148,241, 84, 85,200, 22,113, 27, 22,215,182, 99,110, + 47,105, 45,111,102,241, 14, 98, 41,149, 11, 44,242,207, 43, 60,135,164, 66,143, 66, 27, 14, 57,138,197, 69, 38, 24,240, 11,112, + 2,242, 50,164,216, 73,102, 53,171, 50, 20, 78,113,131, 75,139, 25, 11, 76, 70, 56, 26,106, 96,200, 54,228,202,124, 94, 78, 18, +201,137, 2, 43,112,135,174,253,198, 27,255,113, 54, 26,120,129,157,164,214,108,230, 36, 89,144, 80,110, 66, 15,212,161,244, 74, +105, 94,178,194,196,141, 18, 89,109,254,126, 18,252, 59,117,250,190,127, 26, 68,227, 40,238, 24,215, 6, 33,228,205,190,220,125, + 92, 41,169,163,112,168,148, 27, 2,233, 4,226, 72,230,113,153,165, 1,160, 15, 5,250, 0,228, 72, 45,125, 5, 0,134,104,202, +107, 32, 90,154,101,103, 14,197, 26,208,165,237,174, 95, 69,224,150,242,166,218,140,128,193, 80, 68,233,195, 43, 24,232,173,113, +219, 52,164,123,122,115,231,214,237,222,221,151,253,191,180,154,129,142,126, 89, 38,231, 73,160,165, 89,165, 24,196, 72, 13,245, +205,249, 43, 74,246,255, 57,249,147,210,121, 74,147,127, 59,250,149, 46,202,170,177,246,244,193, 62,121, 67,111,125, 23, 80,153, +216, 70,192,173,214,221,192,222,255,106,191,127,118, 76,231, 49,112, 35, 21,149, 30, 84,111,117,151,187,183,119,239,158, 79,207, +201,250, 41, 64,191,248,251, 23,171, 63, 81,100,217,108,174,216,129,253,224,254,163, 31,190,251, 94,215,140, 94,247,242,149,205, +158,229, 78,182,219,151,156,216, 29, 76,250,244,195,191,249,226,201,200, 30,141,236, 33,200, 74, 47,221,216,219,217,123,249,238, + 63, 63,241, 98,102,224,168, 42, 13, 58, 57,201, 72,234, 74, 13, 86,145,102,221,149, 29,200,129,224,124,194,200, 33,231, 75, 72, +118, 68,233,130, 31, 5, 39,227, 99,203, 27, 49, 15,107, 34, 45,218,178,128,207, 82,100,129, 97, 20, 25, 89,120,219,104,147, 85, + 95,223,222, 35, 51,126,124,227, 81, 19,214,136,186,231,217,195,103,135,199,135,189,181, 79, 58,230,198,216,165, 43, 95,120,161, + 3, 86,109,156, 58, 0,150, 92,104, 93,224,232, 90, 1, 41,119,158,177, 16, 80,177,212, 88,166, 8,181, 97, 94,140, 82,159,220, + 83, 6,167, 80,148,150, 11,121, 16,108,221,219,146,252,128,241,145, 49, 69,119, 16, 74,131,249, 45, 97,209, 96, 56, 74, 89,208, +117, 2,196, 87, 18,237,255, 5,240, 70,254, 48, 98,165,228, 93,253,128,127, 7, 62,178,224, 23,112, 75, 70,144, 71,148, 62,178, +145, 47,180,160, 36, 78, 52,144,190, 28,172,246, 15,170,223, 30,254,252,245,143,207, 15,222,191,117,194,160,173,212,223, 71,211, + 35,251,244,167,225,145, 81,211,123,122,155,156, 43,230,222,172,104,184, 11, 98, 87, 39,244,216,239,178, 48, 1,160,206,242,167, +221,213,206,196,181,162, 44,105,105, 6,229, 19, 19,127, 42, 82, 77, 55,244,234, 42,244, 36, 40,252,189, 30,188,110,168,148, 38, + 98,228, 67,129,155, 14, 99, 84,255,181,230,214,218, 14,235,169,249, 87, 55,175,209, 59, 80,149, 95, 2, 57, 74, 42,132,124,233, +219, 66,129, 16,220,136,106, 50,207, 63,219,250,252,220, 25,146,249, 97,178,205,125, 5, 12,156, 84, 53,229, 19, 93,136,211, 1, + 69, 51,135, 44,112,206,203,133,204,198,145,115,159,153,174, 78,153,190, 3,232, 20, 43, 85, 83, 51, 77,125, 57,197,122, 32,111, +236,193,223, 25,242,135, 70, 23,116, 44, 77,221, 36, 51, 88,105,182, 11,105,177,158, 45, 48,150, 60,188, 41,184,216,149,116, 85, +107, 84,193,201,223, 89,222,160, 55,160,106,175,194, 21, 27,221, 49, 69, 86,140,250, 18,157, 67,237,165,117, 32, 38,139, 20, 76, +109, 10,160,147,170,162,198,121,196, 77,233,185,152,192,254, 47, 0, 83,215,210,219, 70, 21, 70, 61,190,243,178,199,158,241,216, +142,221,202, 78,164,244, 33, 4,162, 17, 18, 66, 98,131,144, 88,160, 74,221, 87, 69, 32,254, 0,123, 36,216,243, 15,248, 35, 93, +178, 97,213, 22, 84, 21, 36,132, 68,211, 54,129,138, 36, 56,193,121,212, 30,207,203,246,120, 56,231,187,182,196, 38, 74, 22,118, +238,220,123,231,123,158,239,156, 13, 63,129,134,232,203,162,215, 45, 93,114, 45,173, 7, 94,105, 5,150,169, 80,134,172,198,209, + 40, 74,163, 89, 30, 49, 38, 93, 33, 68,116, 96,139,231,203, 84, 18,127,214,131,234, 72,201, 76, 19,183, 9, 81,225, 28, 78,198, + 32, 31,190, 33, 21, 55, 24, 56, 14,182, 16,153,179,104,208, 70,164,217, 34,134,129, 43,164,196,121, 61, 28,104, 82, 33,220,236, +154,237,193,205,250, 53,255,228,242,104,185,225, 44,196,227,147, 47,123,145,234, 78, 46, 12,174,212,127,139,190,223, 67, 94,198, +153, 85,101,237,110,237,226,129,211, 60,198, 81, 69,217,236,102,255, 86, 88,111,227,200,241,136,173,122,123,146, 82,127,202,169, + 58, 37, 41, 18, 11,233, 71, 87, 6, 33,167, 22, 69, 93,155,133, 41, 67,199,183,155,145,100,114, 39, 32,147,178,221,227,203, 35, +102, 93,236,242, 26,158,175,130,142, 21,192,147,216,166,235, 42,215,169, 34,100,113,109, 50,173,215, 93,214,106, 76, 1, 43, 43, + 89,182, 33,223, 39,108, 95,171,181,102,174, 81,173,104, 1,239, 66,131,150,244,132, 28,151,163, 56,117,169,228,255, 40, 25, 97, + 49, 29,201, 0, 44,153, 89, 84,146, 29,137, 22, 39,242, 88, 90,214,194,160,194, 55,222,224,211, 56,121,125,254, 38, 80,161,109, +176,123,232, 33,133, 52, 42,121,153, 99,117,201, 34,241,157,214,225,248, 16,126, 1,113, 74,199,235, 46,240,190,175,228, 26,200, +177, 23,162, 21,254,206,240,206,104,138,248,174,236, 54,187, 56,110, 92, 47,132,219,165,248, 82, 4, 44,159,125,244,229,225,217, +193,121,116, 94, 10, 97, 22, 22, 3, 39,129, 27,130,157, 89, 17,162, 78,164, 10,177, 67,228, 49, 91, 96, 63, 71, 23, 71,108, 33, +138,178,138,239, 5, 97,179,189,229,247,135,221, 29,134,249,136,153,150,153, 99, 53, 62,184,253, 97,146,167,221,102,199,117,106, +249, 60, 35, 8, 58,159,253,188,255,232,120,252, 55, 18,249,211,171, 19,188, 17,132, 88, 8,119,208,179,253,167,185,200, 38,136, + 78, 72, 33, 26,191, 78,203,235, 30,141,255,196, 23,238,246,110,222,255,228, 65,224, 6,241, 60,190, 18, 66, 71, 71, 33,143, 81, +211,136, 80,232, 89, 54,113, 76,239,213, 63, 47,191,253,226,155,199,191, 61, 66, 76,215,246,194,231,199,127, 32,148,126,251,214, +187,219,253,157,159,158, 63, 57, 24, 29, 16, 78,163,212,150,127,157, 29, 84,206, 63,151,158,213,192,139, 4,247,147, 44,103,118, +149,234,207,154, 32, 15,166, 36,168, 17, 73,165,116,230,168,240,248, 10,145,126, 63, 28, 96, 71,175,181,122,113,154, 12, 89,153, + 97, 63, 77,102, 71,201,147, 58, 8,135, 4,120, 76,199,105,158,189, 26,189,196, 78,102,162,199,123, 49,189,140,179, 24,167, 59, + 73, 38,189,160, 63,141, 39,130,248,174, 96,183,113,135,119, 58, 59,103, 36, 46,230, 36,242,160,189, 13,163,214,172, 53, 9,243, + 23,110,212,148,115,176,184, 4, 89, 81,100, 28, 67, 53, 85,156, 45,223,223, 27, 84,204, 37, 66,248, 50, 73,231,243,249,130,236, +163,235, 46,148, 8,139,110, 84,163, 42, 26,203,137, 11,199, 11,170,225,218,180,230,218,166, 59,166,200,239, 73,185, 70,233,126, +118,245,127,144,188, 53,209,157,252,100,241,184, 82,195,103,189,202, 15,245, 23, 79, 23,223,239,255,248,221,175, 15,123, 86,243, +235,247,238,125,181,247,233,231,111,125,124,119,112,199, 42,141,223, 47, 14,126, 57,123, 81, 84,173,189,214,144,134,202,180, 83, +153, 54,151,220,154,182,254,198,181, 27,112,150, 5,153, 48, 12, 56,102,108, 35,193,211,244, 33, 6,172, 63,178, 73, 91,145,122, + 90, 98, 91, 79,171,226, 52,220,122,195,246, 16,191,139, 40, 51, 29,107,186,204,227, 60, 26, 79,254,197, 95,189,102,239,245,248, + 47,216, 25,172,212,175,251,112, 0,194, 42, 19,203,200, 27,222, 76,194,183,224, 83,206, 38,167,212, 22,144, 26,181, 6,149,195, + 82,135,245, 80, 26,111,124,106,252,142, 75, 5, 91,199,121,117, 45,206, 40,179, 75,210, 30,103,110, 65,177,250,170, 42,228, 92, +210,156,195, 89, 65, 45,244,220, 26, 34, 27,147,233,123,169,132, 92,203, 98, 50,111, 33,201,110,251,157,105, 26, 41,246, 24,109, + 61,145,180, 65, 72, 50,143,134,225,222,238,110,159,190, 57,185, 66,152,151,167,150,196,138, 98, 59,120,140, 48,140, 48,158, 73, + 30,233, 2,166,140,255,173,241,145,107,193,144, 13,255,251,127, 2, 16,117, 53, 61, 77, 68, 81,116, 62,219,206,180,140, 37,165, +218,150,146, 24, 40, 16, 98,130,209, 24, 21,149,132,196,141,191,192,184, 82,255,136, 49,174, 92,250, 15,252, 15,174, 77,136, 27, + 93, 17,136, 11, 53, 46, 76, 27, 69, 74, 11,195, 48,157,215,233,124,116, 90,207,189,175,224,174, 33,105,153,121,239,221,251,206, +253, 58,231,114,190,105, 10,120,194,170, 14,212,156, 68,131, 24, 36,143,153, 93,246,236, 92,168, 93,210,197, 15,140,102,106, 57, + 41, 51, 45, 21,151,112, 88,150,107,173,179,224,180, 49,223,244, 70, 94,154, 81, 35,129, 84,134,149,137,164, 87,111, 94,127,218, +221,213,216, 6, 82, 70,185, 52,211, 63, 87,209, 73,179,141,164,215, 96, 78, 88,235,152,136, 55,105,229, 88,111,126,204,221,141, +212,165, 83, 44,204,225,121, 0,153, 72, 74,141,111, 61,188, 97, 16, 6, 50, 44,172,207, 55, 27,149, 69, 79,224,110, 24,123,194, +163,236,155,166,195,185,172, 47,110,136,145, 96, 58, 23, 29, 91, 78,204,104, 83, 57, 6,165,243,113,159,200, 0, 7,255, 11, 62, + 8, 81, 15,208, 61, 73, 67,112,181,101,194, 99, 86, 28,208,208, 62, 13, 83,161, 72,177, 77, 38, 49,172,212, 45, 45,167,208,118, + 1,154,170,179, 63,195, 89,198,209,148,206,227, 40,141,146,177,212, 66, 35,228,198, 58, 23, 83,201,134, 55, 37,183,129, 47,218, + 57,195,182, 12,203, 54,231, 0, 80,225, 48,242, 70,193, 50,109, 64, 65,155, 46, 12,170,126, 25, 92,169, 52,153,253,137, 30, 88, + 77,199, 42, 98,107,220,149, 88,221, 4, 49, 76, 6,243,214, 50,153,246,209,140,169,166,227,252,117,131,254,145,240,142,130,224, +104,224,159,248,131, 40,142,206, 35, 63,153,164,199,131,110,166, 36, 68,200,172,169, 49, 98, 21,156,104,117,210, 40, 47,225,189, +108, 82,191, 90,184,179,122,239,107,103,159, 11,255,164,134,138,120, 63, 97,246,161,187, 43,247,123,126, 15, 39, 23,112, 24,119, +109, 49, 95,122,190,243,242,160,189,111,210, 4,165,193,220, 94, 57,233, 59, 0,151,240,174,240,197, 68, 79, 62,201, 96,132,243, + 4,231,135, 37,219, 1,236,245,134,126,223, 63, 22, 17, 15,253,242,114, 96,127, 59,189, 95,148,208,212, 13,108,147, 74,142, 59, +171,149, 27, 92,197,209, 30,223,124,242,187,223,222, 92,190,221, 63, 63,198,217,175, 58,213, 40, 14,175,215, 90, 99, 30,121, 43, + 21, 28,128,250, 56, 9,253,209,160, 85,111,133, 81,228, 11,183,108,149,241, 90, 84, 51,103, 17, 6, 88,166, 99,148,134, 52, 6, + 57, 61, 23,238,153,112,241,225,224,231,158, 59,112,225,214,235,149,198, 41, 83,230,254,237,118, 14,123,135, 55,150, 54,113, 31, +224,201,195, 40, 12, 83, 34, 93,152,168,212, 44,159,208, 36, 92,138,253,193, 47, 91,185, 60, 37,178,185,213, 25, 78,185, 64, 5, +127,169,145, 73,144, 69, 35,234,121, 35, 77, 70, 36, 50,110,230,185,206, 22, 51,135, 41,241,200, 51,114,140,105,182, 14, 43,134, + 59,219,164,187, 16,191, 20,167,137,101,230,241,108,216, 69,154,130,142,197, 40, 30, 61,218,120,136,235, 71,196, 33,117,245,176, +153,120,129, 43, 53,103,195, 72, 72,105,114,226,169,167,102,119,205, 41, 56, 92, 63,203,195, 34, 50, 34, 14,162,201,153,173,181, +107,138, 99, 40,238, 64,141, 98,163, 82,199,237,152, 18, 59,241,127, 26, 52,141, 41,104, 36,209,142, 54,179, 85, 38,216,215, 88, + 64,213, 52, 20, 75, 87,172,156, 98, 25,156, 10,228, 68,188, 76, 63, 40,140,223,103,194,208,108,127, 82, 89,165,168, 42,227,130, +242,177, 28,116,107,239,219,159,223,238,125, 88,189,210,120,183,243, 98,251,250,166, 27,135, 34, 77, 16, 28,222,170,174, 44, 23, +171, 95,250,157, 31,103,109,108,214,154,115, 21, 86,153, 16,135, 19,229,185,240,252,240,191,253,193,169, 36,227,228, 9, 68,213, + 31, 6,204,235,160,110,173, 63,192,137,233, 7, 39,240,169, 56, 12,240,230, 9, 87,100,101, 63, 21, 80,130, 20,186, 3,224, 99, +202, 16,230, 47,210,117,196, 94, 56,189, 50,177, 44,169, 94, 96,236,216,142,230, 66, 19,240, 31,123, 45, 81,237,204, 73,145,186, + 75, 42, 73,229, 84,214,234,227,164, 66,204,105,177,169,108,204,167, 10, 43, 19,169,203,209,120, 77,189,240,243,100,221,217,179, +237,167,223,255,124,147,211,152, 60, 87, 79, 67,142,240, 16, 38, 51, 21,230, 1,123,177,243, 8,225,117,213, 42,148,230,236, 82, + 24, 82,159,174, 83, 44, 83,147,171, 58, 99, 27,149, 61,185,176, 2,145, 8,226,113,226,190,222, 89,185,148,125,119,198,153, 61, + 94, 52,141,221, 10,183, 57, 50,182,158,200,192,226,162, 56,106,231,138,255, 4, 32,234, 90,122,155,184,194,232,204,120, 94, 30, +123, 50,118, 72, 98,210, 32, 7, 23, 25, 66,203, 2, 21,165,105,255, 3, 75,254, 8,171,174,186, 42,191,134, 45, 98,193, 10, 33, +129,186,237, 34, 41,108,144, 66,162, 40, 49,113, 60,153,177,199,243,242,140, 57,231,187, 14, 72,145, 55,177,172,251,252,238,249, + 94,231,172,236, 59, 61,244, 69,145,210,204,173, 94,103, 85,187,163,137,182,128, 98,106, 92,233,138,179, 2,146, 41, 86, 49,226, + 98,251,133, 65,219,115,188,104,126,141,197,181, 69, 88,130,175,220,138,103,201, 44,203,252,195,187,247,228, 78, 97,251, 4, 15, + 58,198, 13, 79, 95,168, 14, 74,145,233,225,215, 82,242,139, 25,218, 42,155,172, 15,122,195,105,122, 45,218, 35, 84,245,164, 68, +148,122,226, 36, 0,202,165,167,240,161,182,187,121,247,100,252,133,108, 65,236,131,173, 85,191,133,204,179, 30,199,151,177,148, + 0,197, 89,220,178,201, 38,168,208,104, 37, 10,200, 21, 25,253,113, 79, 72,131,245,240,206,175, 87,179, 75,192,255, 52,231,253, + 1,204, 76,138,153,244, 91,106,210, 44, 90, 96,190,140, 5,235,203, 53,183,107,224,180,119,112, 51,217, 61, 68,227, 42,213,135, + 82, 89, 35, 68,233,100,133,230, 54,178,133,201,106,180,128,111,113,251,109,178,133, 56,192,144,174,237, 17,239,195,184, 91,126, +219, 10, 60,107,173, 69, 67,175,140,187, 73,115,110, 48, 92,143,219, 96, 89,110,211,108,123,102,211,229,170, 57, 38,209,142, 41, +117,203,240,218,150, 21, 86, 88,175, 21,101, 58, 19, 15,212, 96,214, 1, 4, 44,123,169, 90,246, 69,111, 44, 41,179,164, 44,102, +243, 44, 78,243, 40,203,194, 36,137,105, 32, 42,108,188,105, 24, 81, 26,237, 15,126,199,226, 68, 89,116, 30,158,231, 90, 1,163, + 83, 46, 23,158,235, 63,220,249,229,116,242, 5,118, 54, 76, 38, 56,232,129, 19, 76,152,140,173, 48,204,163,147, 35,248, 1, 28, +162, 97,177, 74,119, 73, 69, 40, 76,206,119,219, 36,245,108, 56,153,148, 78, 42,101, 71,106,149, 49,103,200, 90, 34, 21,163, 99, +155, 9, 97, 47, 11,129,109,145,199,131, 29,124,186,255,244,255,211, 67, 21,150, 36,153, 93,195,204,139,252, 50, 26,141,227, 17, +188,180, 36,159, 15,182,135, 73, 58, 3, 48, 95, 84,170, 40, 77,239, 73,244, 15,142, 48,206,118,148,132,248,221,123,189,123, 93, +223, 63, 30, 29,227,164,249,205,246,102,103, 51,156,134,143,238, 63,234,247,251,231,231, 23, 13, 89,220, 89,146,252,253,252,159, + 55,111, 95,179,224,178, 46, 88,168,206, 52,134,133, 89,156, 93,157, 41,161, 75,157, 26,167,216, 34, 91,122,145, 23,100, 45,181, + 91,109,215, 15,188, 78,146, 78,187,164,104,175, 49, 60,193,149,210, 88,167,155, 45,199,227, 82, 48, 41, 77,166,239,166,105,207, +210,169,109, 90,248,235,117,123, 60,165, 27,187,197, 34, 31,254, 52,196, 42, 1,130, 52, 88,142,172,193,102,237,223,127,114,120, +124, 68, 77,162,189, 63, 0, 6, 58, 77, 58,181,192,155, 23,215, 23, 28, 85, 93,254,246,243,227,233,124, 22,120,109,106,200,214, +218,186, 31, 0,139, 80, 33,132,137, 19, 47,175, 82,215,180, 9, 15,225, 31, 72,105,205,206,230, 94,145, 77,254,220,221,208,123, +142,118,117,141, 9, 25,219,195,101,153,103,209, 88, 80, 59,111,151,234,244, 86,230,218, 16,190, 90, 93,137, 57, 41,252,142, 79, + 71,116,214,219, 46,185,224, 29, 74, 70, 9,174, 87,255,253, 30, 28,166,243,184,234,168,194, 91,114,230,212,175, 90, 31, 62,205, + 63,231,227,191,254,125,217,209,221, 23, 7,207,110, 7, 91, 97,158,197,243, 57,230,178,213,217,136,203,172,223,218,234,123,221, +247,163,143,255, 93,157,238,221,186,187,110,121, 11,141,161,239, 7, 59, 15,166, 89, 50, 73,194, 39,131,199,227, 36, 84, 8, 64, +248, 81,150,235,237,117,236,221,225,201, 17, 14,170, 4,172, 23,131,222,224, 43,149,249, 0,200,124,184, 44, 65,115, 13,222, 94, + 47, 96, 11,177,226, 35, 1,204,167, 29,175,203,131,225, 1, 80,160, 16,107, 16,174,169,134,246,166, 72,245, 2,121,220,176, 98, +252, 96, 87,215, 85,192, 8, 75,196, 64,131,161,252, 87,248,187, 20, 72,160,185,119,106,105, 15,106,232, 22, 78, 78, 67, 88,117, +121,243, 36,189,137, 47,140, 38, 35, 32, 0,222,117, 62, 23, 98, 28,120,234, 76,249, 4,114,183,182,111,237,148, 53, 44,137,141, +205,163, 24, 61, 57,139, 12,161, 50,204,113,108, 2, 47, 80,132,219,154,132,209,170,234,198,171, 87,160, 82,114,169,152, 50, 89, +191, 72, 37,166, 0,186,118, 35,221,167,234, 41,127,136,127, 27,194, 6,246, 77, 0,158,174,101,183,141, 50,140,218,115,241, 92, +237,241, 56,105,172, 38,110,233, 69, 45, 21,164, 27, 64,138,216, 32,209, 77, 23, 93, 35,193, 30,120, 8, 22,108,120, 12, 30,161, +175,192, 11,176, 64,162, 82, 85, 9,146, 10,170,162, 56,118,124,201,216,115,241,220,123,206, 55, 99, 54,150,236,140,237,201,239, +255,255,190,243,221,206,105,237, 59,158,202,132, 78,189,191,130,180, 59, 82, 77, 36,237,125,221, 78,238,144,127, 6,203,231, 59, + 7, 81,186,145,148,177,188, 83, 40, 38, 35,178, 44,169,141,246,152,244,104, 86, 48,107,148,179, 80, 13, 68,223, 5,225, 79, 79, +248, 2,153, 75, 63,242,110,135,136, 43,185,201, 52, 33,245, 42, 27,202,192,178,106,114,230,124, 5,160,166,148, 80, 8,254,143, +157,121,221,122, 63,180, 69, 79,134,195, 41, 82, 29, 53,144, 80, 20,111, 22,209,178,169,217,254, 63,123,129,123, 34,157, 44,103, +118,242, 30,109,166,158, 75, 41, 3,191,113,181, 23,202, 84,228,127, 60, 62,152,212,114, 80,111,226,160,121, 51,108,165, 40, 14, +194,128, 50,183,197,102, 21,250, 29,150,160,243, 78,170,153,117,165,235, 81, 92,165,121,157,236,202, 93, 90, 73,182, 16,235,163, + 26, 6, 80,152, 98, 80, 20, 93,105,138, 42, 0,248, 6,209, 58,145,184,105, 32,124,233, 58, 48,232, 48, 30, 61,241,251,212, 9, +234, 10,117, 23,147, 60, 50, 64,136,141,192,126,100,118,165, 84, 13,217, 95, 87,196,172, 21,219,224, 53,120,236,187,154,235,106, +195,129,238,218,186,235,104, 22,220,131,169,120,174,102,152,170,133,175,128,117,129, 51,161,252, 54,217,121,116, 67,165,106, 31, +236,152,205, 1,150, 74, 5,126,207,131,108, 27,228, 33, 0,194,223,139,127,215,169,244, 26,169,181,174, 83, 69,250,222,225,125, +236,251,217,118,102,244,172,145, 53,194,118,132, 53,231,157,118,181,123, 71, 15, 23,225,204, 64,112, 41,124, 91,184, 85,130,119, +178, 26, 97,169, 77, 24, 89, 96, 79, 32, 83, 78,247,105,228,149, 36,175, 39,243, 89,106,213,109,244,208,165, 60,215, 82, 16, 41, + 44,122,192,151,244, 92,192,240,255,150,151,192,241,182,233, 54,185,111,145,227,214, 51, 17, 59,132,165, 38, 13,167,213,135,185, +103, 70,146, 31, 80, 28,249, 99,120,179,245,118, 85, 9,172,202,242,228,249,217,139,119,179,119, 8,120,175,111, 22,223,127,243, +195,235,191, 94, 89, 20,108,138,102,139,249, 98,113, 13,204,209,208, 5, 31,186,135, 79, 62,249,244,143, 63,127,199, 95, 1, 8, + 96,169, 11, 33,203, 60,246,143,103,155, 43, 44,164, 99, 58,236,154,168,171,159,190,251,249,159,203,115, 10, 3,176, 30,154, 3, + 56, 99,199,226, 74,207,241,128,108,190, 62,253, 42, 78,119, 48,187,187, 44, 85,165, 96,214,145, 32, 99, 50,154,120,206, 0, 1, +120, 41,194, 87,216, 21,155, 36, 56,176,135,211,213, 20, 17,207,116,125,117,246,232,139,243,233,133,194, 42, 23, 99,154,139,233, +219, 36,221, 97, 29,151,219, 21, 96,218,154,242,144,108, 25,148,211,222, 15,227,112, 30,204,133, 15,189,112, 56,166, 27,182, 84, +169, 93,181,236, 20,119,252, 9,192,195, 45,239, 22, 60,189,174, 40,227,209, 73,184, 91,166, 25, 53, 69, 63, 63,241,141,187, 14, +237,123,154,194,251,199,235, 89,190,139,149,150,235,178, 37,143,108,185, 42, 91, 20,223, 50, 27,210, 24,232, 66, 27,249,209, 65, +231,206,168, 51,176,137,226,123, 82,101, 85,246,243, 77,245,158,137, 22, 7,201, 82,136,244,223,248, 23, 47,211,215, 27,189, 86, +226, 31,127,251,245,114,187,252,229,236,219,199,135,147,235, 56,196,247,101, 89,230,247,253,235, 96, 21, 1, 91,151,229, 3,111, + 28, 38,187,243,237,251,247, 73,252,236,246, 19,160,150, 40,137,191,252,248,179,109, 18,205,111,230,192,100,148,237, 36,197,155, +148,114,133, 15, 10, 48,124, 60, 28,103, 69, 33,148,157,213,213,234,114,232,194, 4, 37,174,229, 2, 31, 48, 6, 50, 45,132, 65, + 65,188,129, 39,110,234, 67,113, 30,195, 94, 44,195, 85,156, 71, 98,145, 59,210,249,194, 44,249,233,221,167,111,175, 46, 68,225, +160,110,167, 50, 37, 89, 45,169,210,234,120,116, 50, 30, 30,229, 69,209,183, 28,225, 31,236, 4,113,112,122,255,233,106,179,110, +184, 81, 53,146,214,113, 62,182, 20,150, 42, 33,207,103, 6, 22,216,200,119,252, 36,167, 34, 32, 22,105, 96, 15,113, 52, 88, 92, +229,153,214,252,129,223, 48,131,217,166,157,215,165,231, 13,153,166,206,120, 64,112, 87,158,233,142,250, 62, 16, 6,246,114,147, + 85,144,182, 21, 89, 98,145,136, 2, 38,108,228,163, 41,133, 93,164,181,104,123, 1, 2,194, 7, 54,131, 82, 50, 12,212, 50,215, +236,121,204,248,123,125, 16,128,168,107,217,109,219,136,162, 35,190, 95,162,228,135, 24, 67,121, 88, 78, 27, 3, 78,171, 77, 16, +160, 8,144,133,209, 77, 11, 4, 8,208,109,191,171,223,209, 69,119, 69, 23,237, 58,139, 52, 40,138,116,213,164,142,227, 42,142, + 37, 89,148, 40, 74, 35,137, 98,207,185,164, 27,120,101,128,166,135,228,157,251,154,115,207,249,223,191,215,253, 26,245,137,230, +166, 26, 72, 83, 85, 1, 7,207,227,217, 2, 42, 34,144,113,179,174, 32,163, 4,210, 32,115, 15, 43,185,113, 88, 91, 5,157, 12, + 61, 14,137, 5,110,132, 40,234,113, 35,229,120, 53, 33, 94,186,158, 35, 61,236, 68,183,254,189,190,168, 88, 84, 11,106,203,177, + 89,239, 58, 1, 12, 7,159,231, 48, 57, 34, 11, 51,131,162, 96, 90, 86, 57,185, 32, 68,224,185,234,193,203, 81,181,201, 1, 9, +225,230,133,173,175, 11,253,229,221, 62,174,202,201, 85, 20,251,148,214,212,114,108,237,172, 87, 90, 22,239,230, 60,230, 37,138, + 54,142, 98,199,230, 1,172,170,169, 46,177,169, 70,200, 82,225, 8,201, 19, 34, 20, 99, 75, 61,223, 20, 69,197,222, 9,119,166, + 42, 60,162,226, 29,241,116,237, 56, 50, 67,252, 82, 54, 81,131, 57,166, 79,111,110, 54,125,203,245, 81,206, 90,150,168,112,186, +118, 3,110, 26, 30,223,193, 58, 76,153, 96, 97,166, 47,116,102,148, 59, 53, 10, 18, 14,160, 10, 35, 59, 72, 77, 79,183, 45,145, +224,187,164, 68,177,172,154,143,136,209,208, 82,245,206, 43,100,114,166, 65, 84, 9,238,111,120,182, 32,151,105, 64, 50,205, 41, + 37,115, 69,230, 76,162, 93,147,215, 96,109, 65,104,134, 17, 2, 0, 75, 10,216,153, 52, 19, 81,136, 88,164,188, 55, 36,211, 39, +196, 8,158, 35,159, 46,178,113, 54,123,159, 14,166,203,116, 55,104,183,253, 24, 89,231,162, 88,102,171,121, 55,190,141,117, 12, +210, 11,225,235, 85,142,227, 98, 3, 28,180,187,119,147, 94,190,224, 8,207, 70,106, 25,225,177,161,168, 13,197,104,240,168,166, + 21, 7, 77, 74,170, 10,205, 50,145,103,108, 59,204,234,193, 51, 81,211,130,145,224, 35,194,249, 98,109, 90,107,132, 72, 60,140, +136, 49,153,100,149, 90,100,142,237, 33,216,119, 59,119,144,178,237, 54,219,248,163,227,238, 49,254, 59,245,173,102, 87, 21, 97, +153,222,172,191,121,242,237,203,191, 94, 62,236,157, 44, 87,171,116, 60,193,173, 70,179, 17,243,241,178,216,111,239, 99,111, 35, +138,204,151,179, 73,126,253,251,171, 23,113, 24,195,237,162,220,246, 93, 47, 65,154,159, 77,174,166,151,207,191,250,238,124,120, +190, 27,239,165,217, 4, 78,246,167, 23, 63,182,252,214,120, 58,220,139, 19, 98, 43, 13, 51, 66,233,197, 93, 77, 21,144,216,139, +223,124,252,251, 40,185, 63,201,198, 22, 91,246, 29, 78,204,231, 41,124, 1,170,210, 41, 18, 5,138,134, 39,134,188,153,166,215, +244, 28, 23,101,248, 52,159,192,151, 29,180,111, 29,223,126,248, 97, 52,136,194, 38,217, 11,168, 99, 83,174, 86,186,187,123, 48, + 91,100, 17,204,168, 84,108,163, 47,242, 10, 22,221, 63,236,159, 93,253, 3,195,222,138,110,154,216, 6,177,100, 8, 69,228,248, + 99,117,171, 17, 86,175,167, 31,104, 24, 22,225,252,253,131,253,230,103,129, 26,166, 91,173, 23,233, 80,103, 83,153,107, 22, 92, + 87, 53,131,127, 3,170, 35,125,136,146, 31,206,154, 11,230,125, 39, 84, 88,131,225,169, 78, 75, 37, 29, 21, 69, 42, 50, 62,209, +105, 21, 74,213, 42,208,166,138, 44, 94,246,139, 63,126,117,231,207, 92,119,227,232,135, 63,126,254,237,226,245,247, 15, 78,159, +223,127,124,185,200, 9,118,224, 41, 40, 57, 9,124,199, 13,252, 96,134,132, 8, 79,180,211,251,245,253,235,203,124,112,178,215, + 59,253,252,241, 32, 29,161,166,127, 59, 56, 67, 6,240,245,163,211,229, 82, 35,233, 54, 72, 55,226,192,179, 19,254, 83,104, 20, + 79,236,212, 25, 21, 18,164, 60, 76,238, 13,103, 87, 4,164,111,182, 59, 65,140,220, 63,105, 37,248,184,161,227,205,151, 57, 5, +117,229,208,110,205,185,229, 2, 1,155, 34,243, 18,134, 81, 59,190,185,124,171,110, 16,226, 50,124,227,150,141, 42,229,147,147, + 50,226, 28, 28,132, 85, 91,216, 35,136, 79, 93,235,167,253,211,243,143,103,107, 86,108, 28,146,226, 40, 23, 21, 89, 77,250, 16, +131,131,220,207, 30, 61,123, 55, 60,231,152, 18,235, 33, 58,175,253, 56, 89,234,133,141,103, 32,163,170,223,226,220,251, 54, 12, +195,192, 15,191,232,157,244,238, 29, 33,137, 29, 77,198, 54,249,186, 9,206, 78,231,233, 13,117, 60,193, 85,204,147,138, 26,211, +200,163, 93,155, 98,202,145, 23,222, 76, 75, 48,168,224,222,200, 89, 17, 48, 8, 74,148, 60,176,172, 91,248,101,221,133,111, 52, +254, 19,128,166,171,233,109,156,138,162,182, 95, 98,187,142, 99,167,113,147,182, 76, 91,102,152,142,102, 10, 5,164, 25, 6, 9, + 65, 17, 66,136, 21, 35,182, 8, 70,176, 96, 9, 63,129, 63,193,146, 31,192,134, 5, 59,196,122, 36, 54,136,143,129, 41, 82, 25, + 90, 53,208, 76,218,166,237, 36,105, 18,127,196,126,182, 57,247,190,204, 46, 74,228, 36,246,123,247,243,157,123,206, 92,223,131, +145, 48,243,198, 13,243,130, 89,115,165,156,103,184,124,184,224, 56,143,213, 40,199, 90,240, 66,152, 16,119,224,221, 27,111, 97, +219,245, 71, 61,158, 78, 36, 22, 23,165,147, 32,153, 59,130,133, 49, 41,149,131,133,195,245, 55,220, 38,246,186, 77,167,175, 85, + 70,194,228, 74,215, 83,205, 52, 17,203, 79, 6, 71, 48, 59,231, 62,169,166,252,108,150,204,231,171,184,178, 84,147, 86, 84, 16, + 49, 47, 13,190,103,235,202, 54, 44, 19, 31, 99,237,177,233, 50,106,251,166, 36,150, 70,206, 84,176,132,147,220, 90,123,181, 55, +232,242, 17,102,113,103,243,245,211,193, 41, 43,165,177, 76, 12,141,179,228, 88,247,102,109,169,238,144,177,193,167, 40,181,114, + 54,164, 42, 29, 81, 74,130, 69, 26,106, 94,182,194, 39,105,142, 94,177, 5,246,143, 89,213, 23, 96, 94, 21,221, 50,241, 62,126, +158, 42,232, 89,170, 81,198,155,170,101, 34,109, 50, 20, 33, 57,105,129,150, 36, 86, 43, 89, 51,175, 40,179, 76, 79,179,204,177, +204,123,239,191,247,217, 71,159,236,188,241,230, 44, 45, 14, 14,143,227, 24, 21,104,133,233,164,213, 98,115,214,193,160, 29, 6, +222, 10, 68, 20,252, 11, 26,218,161,138, 70,168, 58,142,154,133,185,198, 67,170, 70,221, 22, 46,182,131,197,152,106,188,135,192, + 68,228,112, 4,214,100,172,147, 97, 90, 52,143,206,168, 80, 69,218,200,216, 56,221,100,142, 64, 81, 88,122,102,104,231,233,232, + 36, 58, 63,184, 56, 64,168, 91,243,215,112,151, 65, 61,184, 76,198, 68,219,148,167, 85,230, 94, 94,242,131,186,233, 99, 99, 12, +163, 1,140,161, 86,173,185,182,119,255,221, 79,255, 60,252, 29, 6, 41,136,133,153,245, 29, 53,125, 38, 99, 92, 62,137,199,168, +115,153, 34, 87,192,168,168,131, 71,115,161,212,160, 76, 82, 24,117, 84,119, 60,151,100, 58,168,209,153,147, 71,112, 22,221, 96, +163,189, 33,165,236, 28,255, 35,216, 92,225,136,224,166,225,247,121,134,155, 36, 17, 26, 78, 3, 75,219,233,118,226,217,244,232, +172, 19, 37,147,255, 78, 58,175,220,184,125, 62,232,243, 1, 58,137,142,121,158, 95,200, 2, 25,162, 65,144,208,133, 47, 63,252, +226,225,254,175, 48,170,213,197,231,218,139,237,222,197, 49,210,145,199,221, 61, 20, 37,147,112, 76,160, 47, 25, 11,173,114,119, +243, 14, 74, 58, 92, 82,183,233,137, 34, 73, 68,170, 24,184, 1,204, 21, 81,216,224, 73,250, 92,230,204,102, 90, 82,107,222,208, +215,131, 13,220, 66, 66, 50, 41, 26,241,238, 49,125,141,164,177, 20, 11,254,104,235,202,205,151, 54,182,159, 60,237,141,162, 17, +226, 92,154, 37,215, 87, 55,153, 14,161,248,224,181,123,143, 58,143,130,250, 82,255,178,159, 82,218,104, 44,216, 14,110,144,180, + 44,120, 63, 35, 20, 89, 21, 91,102, 51,238,171, 84, 86,188,118,152, 78,199,225,112,146,140, 37,209,167, 72, 65,243,147, 8,246, + 68, 37,120,187,237,121,183,124,248,119,194,253,147,252, 89,249, 12, 75, 87,114,182, 94,206,211,118,197,204,199, 58, 28,130,207, + 92,169, 39, 51, 76,191,253,230,167,135, 63,236, 38, 63,238, 77, 31,236, 7,184,228,214,117,226,130,207,121,232, 61,231, 22,133, + 89, 33,141,167, 81,172,125,151, 62,248,165,252,227,242,104,165,209, 56, 56, 59,252,234,231,239, 87, 23,150,191,126,251,243, 75, +153, 68,185,244,109,171,223,187,168, 70,122, 54,209,204, 84, 12, 70, 23, 73,153, 5,254,226, 82,173,129, 42,242,183,225,254, 81, + 20,125,252,226,206,147,225, 9,157,157, 90, 68, 72,254,239, 89, 23,241,149, 85, 39,168,225, 69,218, 26,154,146, 7, 21, 17, 15, +121, 42,172,142,107,185,215,218,215, 16,110,195, 44, 12,227, 16,166, 77,186, 43,133,198, 52, 83,102, 11,190,126, 58, 44,244, 57, +112,208,171,249,239,108,239,252,221,125,140, 71,193,148,253,248,251, 85,198,149, 19, 78,117,217,107,165,196,184, 39, 21, 51, 12, + 30,120, 24, 79,240,122,153, 40,131, 98,248,183, 36,141,247,142,254,194,158, 20, 60,165, 70,194, 96, 20,179,145, 38, 10,154,174, + 71,198, 86,202,206,233,161,162,221,157, 19,201,233, 2, 73, 45,209,160,218,174, 99, 58,235,173,231, 7,225, 83,100, 36, 91,235, + 55,145,164,175, 52, 86,154,203,173,151,175,110,239,238,239, 10,165,106,167, 78, 87, 85, 91,147,109,210,183, 26, 40, 77, 74, 37, +145, 86, 22, 8, 42,147,100,138, 61, 86,240, 13, 40, 8, 16,138, 81, 36, 82, 77,183, 53, 73,199,212,171,200, 11, 99,142, 96, 37, + 94,213,166,211, 68,188,249, 95, 0,162,174,165,183,141, 50,138,122, 60, 99,207,203, 51,227,248, 21,167, 64, 29, 43,174, 16, 32, + 90, 34, 94,162, 18, 44, 40, 20,177, 98,211,178, 98,135, 84, 33,129,212, 77,197, 47, 96,205,207, 96,199,134, 53, 11, 42, 22, 5, +129, 16, 68, 8, 1,105,162,212, 49, 25,199,143,120,236,241,188,103,108,206,189, 99, 53,217, 69,178,101,205,124,247,187,247,156, +239,187,247,156, 13,126, 23,169,143,251,210,245, 9, 17, 9, 2, 2,192, 18,167,209,165, 13, 32, 59,249,165,228, 68, 60,101,149, +177, 82,127,122, 60,113,193, 31,201,113,155, 90, 50, 41,248,138,133,220, 20, 78, 40,242, 81, 17,169, 50, 97, 25, 64,189,129,145, +177,207,105,202, 41,112, 73,213,129, 85, 36,241,204, 42, 77,205, 8,200, 5,116,228, 66, 33,183,186,108, 57,101,147, 7, 67,181, +248,130, 50,203,103,119,121,166,153, 90,128,177, 54, 99,190,245,198,243,170,138, 78, 33, 42,108, 22, 15,127, 88, 48,252,202, 34, +116,193, 6,232,254,146, 60,167,165,243,249, 8,124,141,206,183, 69, 49,215,124,200, 53,226,253,216,115,125, 39, 99,144,158,229, +230, 91,120, 64,106,102,164,129, 0, 96,204,108,157, 16,148,230,226,168,106, 82,213, 42,129,192, 96,129,203,101,161,162,137, 74, +137,117, 86,121,206,187, 76, 7, 18,107,252, 7,210, 22,167,220,135, 69, 70,216,108,172, 91,148,116,185, 12, 40,109,168, 74,165, + 66,114,172,247, 63,251,244,157,183, 94,125,244,243,143, 91,166,252,201,221,143, 27,166,126,116,124, 4, 4,134,160, 80,248,242, +118, 3,178,152,142,149,242,185, 8, 42, 28,185, 80, 16,143,147,242,229, 57,157,158, 32,251,203,204, 27, 36,228, 2,130, 43,248, +172,174, 74,150, 33,153,186, 72, 62, 78, 98,145, 57, 9,243,115, 74,208,172, 25, 88, 66, 41,151,233, 88, 71,166, 50,133,247, 36, +130,200, 96,193, 84,100, 36,169,168,137, 5, 29,169,206, 3,162, 31, 76, 6,120,129,187,245,110,167,182,171, 41, 58,114,205, 99, +251, 95,123,110,191,119,253,246, 34,152, 81, 27,153, 40, 78,151,147, 11,215, 65,228,249, 33, 49, 54,108,155, 32, 10,130,196,187, + 90,235,144,170, 26,153, 59, 42, 21,213,140,162, 80,166,128,137,187,173, 61,130,186,220,119,143,226,212,182,174,200,186,236,123, + 94,187,246,204,220,119,226, 44,112, 3,103, 52, 31, 34,203,199,105,136, 50,132, 77,101,168,134, 31,211,124, 96,179,210,228, 30, + 77,145, 66,145,238,163,233,122, 19, 33, 14,108,142, 96,185,255,229, 3,103,230,140,135, 67, 4,216,185, 99, 79,102, 99,236,141, +170, 94,189,182,211, 67,254,253,245,240,151,132,136,173, 0, 54,125,100, 63, 6, 33, 64,194,197, 43, 7,185, 68, 29,242,130, 37, +249, 71, 21,214,253,233,233,138,173,104,201,187, 78,146,194,192,219,177,174, 80,114, 44,172,237,139,193,205, 23,111,158,142,251, +188, 32,235,186,213,162, 78,134, 44,195,107,233,181,122,113,150,188,249,252,107, 79,236, 19,110,137, 67,142, 77,131, 36,220,210, +170,101,177,124,112,114, 48, 15, 22, 97,236,239,119,247,135,179,115, 64,126,234,191,140,188, 39,163, 65,195,168, 47,253, 5, 13, +255,178, 57,225,182,217, 82, 74,114, 16,121,212,128,164, 90,248, 36, 56, 40,235,205,146, 90, 79, 16, 7, 53,109, 75,147,181,221, +102,215, 13,230, 60, 12, 33, 54,172,118, 18,147, 73,242,203, 70,165,246, 74,173, 48,117, 4,194, 76,172, 82,180,137,246,252,250, + 48,151, 95,224, 81,141,167, 54, 20,216, 69,114, 9, 69,233,155,239,254,232,251,137,213, 50,206,146,248,228,108,178,211,159,154, +207,213, 11,207,214,233,222, 53, 73, 25,182, 43, 4,219, 31,245,143,190,253,109, 53,235,253, 30, 69,160,137,141, 98,249,235,131, +239, 15,157,193,131, 27,119,154,186,105, 59, 83, 49, 46,116,196,238,135,247,190,184,254,213, 71, 55, 62,191,253,194,221,119,247, +219,111,103,127, 47,254, 26,254,233, 36,203,151,170,221,135,103,255,216,254,127,141,162, 85,151, 53,164,130,154, 89,245, 99,114, +223, 38, 68, 35, 20, 55, 26,136,236,197,131,136, 10,162, 48, 79, 68, 88, 8,148,189,153, 55,155, 46,166, 52,234, 72, 2, 85, 98, + 62,205,202,116,132,172,168,107,160, 74,161,123,109,187, 71,170,121,161,223,217,238,244, 71,167,221,246,222,120, 49,202,133, 10, + 13,181,162,149,200,167,197,113, 47, 84,252, 58,233,206,164,185, 0, 0,223,238, 82,254, 1, 10,108,154, 59,147,229,136, 24, 56, +245,109,151,243, 52, 40,178, 94, 16,105, 85,166,241, 22, 57, 76, 5, 87, 91, 93,159,196,109,104,124,233,141,189,215,237,153,205, +199,171,132,205,200,217,163, 98, 42,178,226,135,222,186,184,118,188, 5,190,126, 58, 28,220,122,255,214,195,159,126, 88,184,174, +174, 85,232,162,133,106, 70,238,211,144,207,201,102, 88,107,230,184, 43, 84, 8,131,229, 76, 80,102,202,228, 26,253,193,241,249, + 97, 46, 49,182,140,168,176,121, 32,196, 2,141, 70, 35,181,178, 47,208,170, 4,236,159,166,212, 35, 46, 8,255, 11,192,212,213, +244,182, 81, 69,209,153,241,140,191,191, 27,227,102,146,152, 20, 75, 17, 72, 72,208, 34, 36,144,170, 72,172,144,144, 90,144, 42, + 33, 1, 11, 42, 22, 44, 64, 66, 98,193, 10, 33,177, 41, 43, 22,221, 32,241, 35,216, 20,254, 1, 8,218,130, 40, 4,168, 83,218, +166, 46, 65,173,235, 56,254,136,199,246,120,102,158, 61,156,115, 95, 16,108,147,140,243,230,249,221,143,115,223,189,231, 28,251, +119, 37, 21,130,255, 79,165, 34, 28, 81,225,225,191,138,141,169, 99,128, 52,105,106, 6, 51,253,170, 54,156, 59, 50, 47,181, 88, +194, 8,114, 73,192, 25,100,235,148,189, 14,132,243,129, 82,182, 75, 18,241,164,172,164,146,132,103,165,184, 50,154, 13, 98, 81, + 72,192,222,193,225,250,106,134,167,180,140,172,112, 61,134, 82,223, 35,190,128,193, 8,237, 48, 59,204,224,178, 28, 39, 5,111, +137, 79, 5,110,226, 21,171,136,237,226,200, 42,197,251, 94,124,211, 57, 39, 43,146,223, 28,130,160,122,212, 98,225, 56,105, 44, + 19,128, 3,238, 6,201, 56,121,183, 23,122,204, 88,138,111,177,166,167, 60,238, 76, 42,102, 10,120, 48,149,204,137,122, 11,193, +157,104,106,135,230, 49,245, 66, 65, 25, 42,159, 77,151, 79,208, 12,179, 41,248,119,246, 48, 56,142,220,172,242, 11,101, 19,187, +227, 96,121, 84,127, 76, 59,134,227,216,188, 80, 77, 91, 69, 60,156,117,242, 89,163,148,139,107,149, 68, 49,111, 20, 11,201, 15, + 63,120,255,243,203,151,191,187,246,211,141,157,223,247,247,239,191,118,254,149, 90, 37,127,115,183,165, 55,150,145,122, 73,131, + 78,219, 54, 32, 2,147, 11, 21, 7,129,225,195,127, 4,230, 44, 20, 58,118, 86,109,140, 36, 48,136,195, 11,146, 20,139,127,194, +215, 26, 91, 74, 89,112, 98,254,156, 86,105,112,168, 69,170, 59, 90,143,141,179,116, 9,222, 3,167,156, 2, 2, 44, 22,150, 73, +100,210, 78, 49,203,120,144,207, 97,205,250, 22,129, 33, 64, 89,241,220, 10,102,150, 2, 10, 38,119, 99,108,236,245,247, 38, 33, + 16,180,233, 86,220,107,119,190,247,252, 9,203,232,209, 28, 71,244,226, 75,111,127,253,227, 21,172,255,100,181, 33,117, 54, 86, + 5,143,252,225,130,228,204,153,165, 80, 45, 50,249,181, 76,156,191,241,244,168,136,220, 58, 83,154,248, 30,143,144, 90,158,123, +253, 92,103, 15, 80, 76,225, 39,154,191, 22,199,100, 2,171,176, 25,176,145, 19,176, 65,141, 4,115,148, 79,139, 8,159,243, 25, +210,211, 7,149, 92,109,251,233,237,219, 15,111,217, 34,171,246,231, 47,173,235, 59, 87,207,108, 61,223, 29,118,154,238, 22,236, +126, 76,141,198,105,119,216, 45,229, 74,188,210,199,247,139, 3, 46, 28,220, 30,201,120,163,245,149,199,135, 30,241,114,176, 12, +106,185,154,204, 49,150,130, 0, 57, 35, 94,243,164,138, 72,245, 5, 91, 90, 44, 35, 36, 28,103,159, 60, 59, 24,247,189,153, 7, +100,179, 90,117, 79,185, 79, 52,234,141,254,240, 0,231,110,191,215, 70, 44, 1,146,192, 1,115,168,109,105,193,188,223,220,190, +176,115,239, 15,108, 26, 39, 1, 19,196,103,120,253,213,234, 26,118,236,217,230,153, 32,140, 16,171, 96,192, 90,195,147,244,115, +177,217,247, 14,167,129,111, 37,132,123, 71, 5,248,239,110,165, 78, 73, 72,164, 83, 78, 10, 27,232,135, 51,105, 19, 96, 58,137, +208, 91, 76,151,241,171,181,218,198,104, 58,124,166, 92,168,158,174, 24,189, 81, 12, 44, 73,198,145,133,180,144, 72, 90, 44,224, + 84,168,134, 45, 93,168, 57,230,129,198,195,249, 84,171,213,189,242,235, 62, 96,151, 82, 17,194,209, 83,235,229, 70,189,144,196, + 25, 66, 22,149,150,233,188,133,109,252,240,247,238,151,223,254,124,245,110,104,218,189,176,225, 69,126, 38,145,232, 77,188,207, +110,124,179,150, 89,253,226,229,247,110,117,238, 37,103,197, 55, 62,185,228,126,250,156, 57, 74, 95,255,232,230,111, 31,223,110, +127,117,176,225,158,218,124,231,244, 11,149, 87,251,127,181,148, 61,143,149,177, 51,188,139, 67,247, 98,189,137,149, 13,166, 71, +166,214,117,212, 14, 71,244,111, 23, 82, 80,210, 66, 90, 48,106,155, 99, 77, 12, 3,248, 59,183,186, 46, 36, 72,166,241,111, 39, +136,166, 54, 89, 74, 31,228, 60, 8, 86, 79,184,237,131,251, 48,225,195,241, 96, 52, 29,244,198, 61,169, 1,240, 68, 97, 27,231, + 81, 48,158,141, 12,145,110,102, 85,153,122, 39, 66,183,103,152,143, 21,234,156,114, 39, 51,246, 88, 40, 33,185,134, 82,166, 76, + 63, 19,235,153, 24, 67,124, 20, 25, 67, 57, 4, 11,223,205, 70, 50, 18, 90, 60, 24, 60,212, 61, 53, 43, 5,222,171,123,129, 55, +153, 79,143, 38, 99,216, 28,176, 47, 48, 74,169, 84,221,108,108,190,117,233,221,238,110,103,208,235,205,163,112,230, 79,145, 30, +109,173,109, 61, 58,236,176,200,192, 82,167, 69,150,105, 97, 26, 0,134, 64,114,220,172, 55,187,163, 71, 72, 54,218, 7,109,210, + 44,178,201, 66,136,152,180,238,175, 97, 49, 1, 18,194, 68,120,130, 13,236,204, 50,212, 90,234,255, 8, 64,213,245,252,182, 77, +134, 97,127,137,237, 56,142,237,216,206,143,118, 83, 18, 24,234,134,186,116, 43,165, 19, 82, 55,122, 0, 77, 27,154, 58,132,182, + 3, 98, 7,164, 74,187,240, 23,176, 51,151,177, 19,226,194, 1, 46, 8,184, 33, 14, 12, 16, 7, 14, 72, 1, 4, 26, 2,182,142, + 18,105, 98, 29, 77,233, 80,147, 38,105,108, 39,182,227,216,222,251,190,110,167, 33, 85, 85, 21, 89, 85, 62,199,121,190,231,121, +191,247,125,158, 4,223, 15,198, 91,159,240,157,212,229, 2, 0,229,255, 43,242,209,227, 11, 30, 27, 22,163,139, 47, 47,245,157, + 93,248,237,163, 81, 74, 0,107,206,138,152,230,193,246, 73, 38,246,236,195, 93,214, 84,109,229,236,197,187,247,238,128,234, 58, +216, 76,176, 90, 5, 26,135, 34, 56,210,137,154,166,108,241,248,120,229,100,215,234, 16,182, 78,176,232,143,167,151, 0,211,232, +195,192, 37,209,133, 33,218,117, 98, 29,141, 16,132,161, 23,168,134,221,147,164, 63, 41, 20, 2,176, 57, 4,124, 57, 81, 91,128, +175, 28,151,218, 55,149, 71,212,198, 17, 78,124, 65,198,140,221,128,140, 30, 40, 62,156,139,135, 99,215, 80,205,189, 81, 63,121, +225,192,174, 13,191, 26, 57, 81, 41,155, 83,136, 44,153, 56,175,139, 19,234, 52, 10, 3, 6,128, 59,178,185,193, 48, 30, 58,209, +192, 9, 29, 39, 26,142, 34,215, 69, 47, 2, 32,218, 49, 78,187,161,186, 20, 69,160,249,177, 44, 9,151, 94,189,188,252,226,249, +198, 79,119,100,201,124,243,202,234, 7, 31,126, 28, 68, 66, 20,139,247, 55,182,183, 31,118,175,174,190,229,187,225,207,183,254, +224, 80,151, 1, 64, 71,233,136,198,159, 57, 44,179, 80,111, 64, 74,195,174, 74,150,147,152,136,245,119,150, 17, 64, 42,165, 65, + 58,192, 82, 2, 44,235,167, 88,200,232, 56,151,151,112,210,142, 10, 34,128,250, 56, 53,142,120, 45,103,211,120, 48, 43, 11, 57, +153, 7, 64, 7, 57,146, 67,250,142,114,129, 75,198,196, 34,228,194, 73, 26, 81, 28,226,244,150, 63, 78,133,176, 91,176,216, 97, +126,103,216,201, 49,201,204, 21,237,192,202,241, 42,108,222,148,101,129,231,216,176,218, 75,103, 46,255,208,108,148,180,114,189, + 90, 7,106, 12, 11, 55,212, 18,124, 68,176,251,142,201, 46, 20,249, 5,207, 15,253, 17, 79,123,191,237, 89, 23, 78,173,140, 3, + 0, 56, 15, 30,229,245,219,235, 69,109,170,107,119,242,104, 24, 23, 81, 36, 47, 63,109, 86,108,167, 71,133,248,104,228, 59,192, + 30,128,106,192,245, 41,242, 47, 2, 8,213,228, 60,168,249,245,214,159,158,239,158,157, 63,255,242,115,203,141,187,141,211,245, +165,102,171, 25, 69, 1,236,235, 35,223, 54, 20,243,234,185,213,181,127,214,151,113, 58,116, 27,216, 31,165, 46,160, 37, 17, 6, +131,120,118,123,176, 3,207, 12,144, 98,203,179,168,227, 16, 83, 65, 22,142,204, 15,199,163,222,160, 23, 68,147,103,166,143, 0, +211, 71,223,152,157,141,246,160,187,213,109, 77,233,101,248,255,221, 65,151,143,216,110,191, 61,240,246, 18,153,187,244,236, 18, + 72,141, 82,190, 72,115, 55, 54, 44,185,185,121,207, 80,117,156, 16,137, 39,115,181, 57, 80,235,190,239,247,237,254,133, 83,231, +214, 30,172,153,138, 1, 88,131, 44, 76,206, 79,176,115, 95,152,173,204, 42, 82,206,118,173, 12, 74, 47, 65,149,148,130, 86,124, +237,133,139,183, 55,224, 98, 29, 56,144, 78,109, 69, 39,170,245,135,189,255, 74, 90, 9, 52, 13,108, 25,192,202,108,167,195,241, +217,186, 32, 20,159, 47,112, 61,139,141,125,108,233, 78,114, 4, 25,229, 56, 36, 93,219, 20, 40,126,224, 89, 72,163,122, 52,107, +121,179,113, 95,207, 8,139,135,243, 79, 23,180,146,146, 53, 36,201,200, 1, 85, 5,194, 46,114, 94,154,251,177,245,219,123,223, +125,254,197,173,191, 7,142,168, 9,121, 49,207,216, 81, 69, 45, 46, 78,207, 92,255,245,171,102,255,193,181,249, 43,105,216,220, + 28,246,198, 39,239,112,179,220,247, 71,127,121,247,253,235,139,238,201,249,211,115,147,190,255,246,167, 55, 62,251,232,219,215, + 95,122,101,230,216,153,193,230, 95, 66, 42,252,230,223,223, 91,174,181, 82, 89, 24, 5, 52,249, 72,197, 10,184, 9,166,170, 91, +174, 13,239, 82, 87,140,167, 74, 85,184,111,240, 7,124, 46,128, 6,182,231, 36,181,114,192, 19,207,163,206, 28,173,204,200,169, + 27,221, 15, 57, 76, 52,196,120,213,137,191,131, 61, 54, 88,200, 46,227,233,136, 68, 19, 3,184,110, 69, 82,170,197, 26,220,112, + 33,149, 76,188, 99,238,101, 81, 53, 3,116,163, 66, 73, 3, 27,231,148,113, 8, 68, 85, 70,144,106,133,218,158,187, 39,241, 64, +177, 4,156, 81,216,247, 3, 32, 7, 2,150,128, 44,191,239,210,130,242, 1, 37, 81,197,172,194, 82, 60, 60,224,197,216,209,140, +152,145, 50,248, 35, 3,129,226, 69, 0,144,206,110,167, 16,231,191,190,249,229,112, 56,194,209, 31, 42,248,180,251,109,160,212, + 37,181, 12, 79, 17,145,109,110,230,240, 49, 16,196, 89, 94,134,167,102,171,179, 25,147,247, 36,122,193,166,165,178,126, 8,244, + 28,123,194, 4,158,142,190,176,116, 81, 84, 75, 91,189, 22, 77, 87,225, 27,125, 36, 0, 85, 87,215,219, 54, 25,133,109,167, 73, +108, 39,177,155, 54, 89,211,134,176,118,107,217,150, 78, 67, 64,216, 52, 9,198, 0,105, 8, 81,208,212, 59, 46, 17, 87,227, 2, + 42, 4, 18,119,136, 91,254, 4, 55,211,184, 67, 2, 36,126, 0, 21, 84,168, 82, 53,166,110, 93,187,165,221,250,145, 14,199,249, +112,226,248, 35,254,120, 57,231,188,233, 16,215,150, 18,235,181,125,206,115,206,121,206,243, 96,124,231,107, 77,162,200, 78, 44, +113, 17, 59,227, 42, 7,160, 79, 9,245,120,197,255,201, 61,143, 58, 68,163,212,207, 4, 34,141,162,227, 7,156,181,196, 36,168, +119,208, 98,152, 5, 92,206, 82, 56, 49,220,131, 18,120,115,251,111,146, 92,151,136,167, 40, 17, 57, 63,152,153,168, 88, 54,193, +121,241,191, 2, 2,130, 59,246,249,216, 72, 8,147, 28,233, 0,168, 4, 83, 90,217, 9,108,190, 32, 10,101, 59, 58, 37,201, 26, +100,136, 49, 41, 73,187, 39, 88,218,121,196,128,214,213,113,127,136, 18, 38,141,246, 33, 59, 25, 60, 62,191,113,145,187,220,145, + 91,108, 58, 9, 56, 53,129, 62, 59, 1,118,102, 6,238, 96,110,234, 44, 22, 22, 56, 66, 1, 12,174,210,184,216,129, 90, 1,167, + 11, 56,102,101,138, 42,219, 30, 20,227, 82, 18, 53,246,164, 33, 73,225,241,137, 49, 14,217, 35,206,183,197,131,229, 26,128,220, + 50, 11,176,200,181, 55,222, 92,249,230,251,115,139,175,152,199,117, 45,155, 93,188,120,241,135,219,119, 8, 83,136, 16,249, 30, +213,159,180, 76,227,203, 47, 62,223,217,169,239,236,238,225,168, 21,189, 49,177, 62,204, 41, 82, 86, 77,232, 89, 73, 77, 75, 25, + 85,164,197, 97,106,101,209,118, 9,194,208, 56, 1,231,231,161,157,168, 59, 28,250,128, 79, 6,128, 54,237, 0,192, 59,196,125, +199,101,142,131, 70, 31, 40,253, 17, 35, 35, 48,163, 66, 88, 20, 85, 69, 84,101,145,182, 79, 41, 31,162,100, 60, 81,160, 41, 32, +224,214,120,196,134, 33,113, 49, 73,110, 1,165, 93, 21, 49, 82, 32,144,246,207, 77, 84,223,190,116,237,238,254, 6,100,214,178, + 94,182, 60, 43,171,104,189,129,115,216,218,159,206,151,215, 31,175,165, 83, 16,145, 25, 61, 47,194, 34,104, 62,151, 83,100, 25, +183,254,226,104, 58, 95,113,176,159,200, 32,160, 27,150, 81, 41,204,250,161,235, 6, 78,171,247,143,132,202,189,254,245, 75,111, + 89,125, 43, 70,225, 35, 83,207, 78, 64,224,131,231, 5,152, 23,128,155,209,105, 36,104, 63,127, 12, 77,208,101,223,247, 18, 68, +214,188,121,245,163,181,135,127,154,221, 14,224,128,131,214, 97,136,110,212, 84, 74, 15, 93, 57,169,172,222, 95,173, 86,206,175, +110,173,162, 61, 86, 24,233,170, 86,155,191,114,212, 62,234,187,214,167, 31,222,218,216,254,235,221, 87,111, 44, 44,156,223,169, +111,194,129, 4,240,127,161,119,220,110, 64, 12, 45,106,147,237,190,169,201,250,163,163,135,141,118,163,144, 43, 84, 43, 47,213, +230,107,245,198,227,129,107, 79,230,198, 19, 72,190,234, 2,118, 90,170, 45, 25,221,103, 7,205, 3,219,181,170, 47, 94,128,119, + 6, 71,133,164, 77, 49, 55,117, 6,165,108, 94, 95,218,124,122, 63, 64, 82,169, 88,202,151,224,110, 25,154, 89, 62, 67, 95, 13, + 33,254,224,181,247,225, 31,253, 40,104,118,141,140,156, 1, 96, 8, 79, 11,162,191,141,163,239,246,189,189,187, 17,177, 98, 61, + 40, 77,227, 32,147, 82,247,205,167, 99, 9,254, 98,147, 61,136, 24,207,205, 84, 33, 14, 46, 42, 66,241,234, 41,161,219, 19,194, +161,136,164,180,240,185, 95, 11, 22,201, 36,170,192, 9,245,220, 19, 40, 66, 10,191,100,153,129,211,142,207, 78,230,245, 52,164, +126, 57, 55,166, 78,230, 38,180, 23,102,132, 66, 65, 48,156, 63,110,255,126,231,183,245,173,110,223, 75, 67, 29, 45, 41, 16,120, + 68, 45,136, 74, 77,167,219,178,154,223,174,255, 82, 72, 21, 87,170,239,117,122,241,199, 63,125, 39, 64,166,187,206,142,237, 39, +159,253,120,171,252,213,180, 50,159, 42, 45, 23,150, 63,185,241,224,231,123,239,252,186,188,178,240,245,194,203, 87,204,163,141, +181,227,237,150,103, 94,158,170,230,146, 41, 56, 19, 78,159,117, 67, 23,170, 55,190, 86, 78, 37,151, 1, 95, 98, 65, 47,246,220, + 30,228, 87, 72,117,240,105, 67,148,183,157, 62, 84,240,249, 92,254,242,133,218,131,253, 45,100, 0, 70, 1, 92, 82,146,242,236, +169,211, 29,187, 19,113,177, 56, 22,245,125,248, 12,134,163,116,134, 90,202,126, 23, 9,181,196,168,225, 94, 89, 2, 67,135,172, +145, 98, 39,162, 98,155,220,128, 73,106, 46,240,124,143, 86, 1,131, 19,103, 94,222,206,138,121,225,192,183,254,199,179,227, 40, +100,130, 13, 80,134,186, 11,156,121, 57, 90, 1, 18,104,199, 17, 53,157,176,203,204,216,233,242,108, 90, 86,118,247,118, 5, 34, +157,135, 1,118,102,232,106,100, 57,180,104, 41,160,224,140,105, 53,169, 62, 96,220, 95, 19,237, 19,232, 71, 1, 34, 0, 28, 41, +233, 51,118, 96,115,163, 39,120,115,114,138, 86, 41,206, 53,123, 6,146,244, 49,235, 36, 84, 52, 60,136,254, 21,128,168,235,249, +109,155, 12,195,113,236, 38,118,236,116,113, 26,234,132,118,253,153,164, 43,218, 96,173,134, 90,137,105,128, 4, 92,118, 24, 32, +206, 27, 7,142, 28, 42, 36, 78,112,168, 16, 66,112,228,111,152,128, 11, 71,132, 24, 84, 8,212, 77,128, 24,234, 97,226, 71, 89, + 27, 72,215,180, 89,126,219,137,157, 56,110, 28,158,247,117, 34,238,142, 29,251,251,190,247,125,190,247,123,222,231, 25,215,223, +169,209, 60,112,151, 27, 9,244, 98,199, 77, 50,123,253, 78, 84, 82,206,124,106,255,145, 72, 62, 37,112,200, 28,146, 84, 54, 91, +148, 5,226,145,129, 68, 24,107,155, 80, 89,166, 71,164, 23, 63,160, 92,145,230,240, 89,223, 39, 67,118,133, 8,137, 82,100, 46, +181, 80,119, 26,220,213, 74, 81,197,114, 76, 58, 48,101, 87,141,241, 33, 42,253, 1,118,195,242,134, 99, 79,240,160,169, 44, 34, +201,212,182,138,221,116,114,182,108, 61, 22,153,103,198, 54,146,212, 1, 63,100, 42,219,148,102,224,157,186,110,219, 23,252,240, +168,224,200,158, 37,130,143, 77,137,199, 70, 66, 35,222, 43,229, 30,252,204,235,115,229,139,186,192, 88,116,211,178, 77,219,237, + 32, 87, 1,210, 48,155,219,167,221,107,224,143, 41, 14, 69, 49,148,121, 82, 33,147, 13,242, 36, 27, 34,169, 69, 35, 34,208,116, + 76, 9, 3, 26,211,137, 43, 49, 91,200, 22,135,205, 45,153, 87, 76, 22,151, 4,154,140,164,246,252,213,245,129,107,125,254,217, +237,197,249,121, 93, 79,124,187,179,163,170,138, 26,149, 52, 57,162, 42,145, 66,177,160, 76,136,175,223,184,190,123,247, 71,252, + 54, 26,149, 56,196, 11, 44,241, 70,167,181,136,215, 61, 55,212,182,125, 32,179, 64, 7, 34,192,245,184, 24, 65,253,153,213,167, + 62,249,240,131,119,183,182,222,120,245,198,149,181,117,160,134,163,226,177,227,244,136,106,142,100, 77,181, 91, 73, 83,164, 4, +214, 46, 73,120, 9, 72,133,184, 91,215, 13, 97,254,123, 52, 57, 5,198,152, 99,255, 23,150,250, 3, 90,150, 35,228,255, 64,117, + 78,162, 65,115, 63,179,232,253, 91, 63, 42,156, 28, 32,168,229,211,171,189,129,131, 28,131, 0, 93,172, 29,112,103,157,147, 58, +151, 50, 59, 45, 86, 80,161,173, 38,240, 14, 18, 63,233,187,145,168, 68,127, 24,198,115,123,193,206, 11, 72,164,214,174, 54, 59, + 85, 12,235, 92,106,190,110,215, 73,122, 41,170, 20, 43, 69,108,164,114,153, 11, 21,171,204,189,163, 54,139,196,246,155,157,250, +128,178, 25, 17,117,150,210,185,110,207, 65,212,110,119, 59,166,221, 42,156, 28, 98,236,214,243,235,150, 99, 45,166, 23,211, 9, + 3,219, 85,118, 90, 23,146,113, 29, 57, 3,243,195,116,154, 51,201,153,118,183,157,159, 89,217, 59,188,143, 24,129,237,252,253, +253, 95, 0,168, 75,149, 82,169, 92, 34,198, 20,159,168, 99,166, 97,145,148,137,212,248, 44,160,180,145, 74,231,206,175,104,146, +220, 31,120,165,218, 81, 46,147,221, 63,222, 71,252,221,126,235,163,159, 31,236,174, 45, 93,198,130, 60,174, 62, 66, 86,221,200, + 93, 89,202,228,255,122,244,199,164, 28,119,122, 14, 54,203,155,249, 13,172,189, 74,171,242,240,244,161,221,163,192,132,155, 35, +188,108,172,108, 46, 27, 89,211,177,240, 89, 48, 68,143,155,167,118,223, 94,157,201, 19, 39,218,117, 72,252,157,139,191, 24,105, +124,246,107,151,174, 86, 91, 85,228, 98, 73, 32,247,224,164,150,212,181, 4,151,110, 93,106,161, 36,255,153, 39,106,205,195,185, +204,211,107,106, 58,118,209, 15, 89,157,144,231, 9,136, 31, 92,235,160,206, 85, 38,159, 18,119,129, 73, 89, 35,149, 66, 6, 61, + 68, 66,118, 99,178, 26,211, 38, 85, 69,139, 39,147,122, 66,215,227,170,220,170,214,239,124,247,219,157, 95,255,252,187,105,121, +146,132, 52,226,178, 53,162, 28,145, 98, 97, 5,241, 61, 34, 10, 63,157,252,243,195,233,222,205,229,151, 22,165,169,215,182,223, +199,205,171,183, 76,117, 75, 62,255,229,188,253,125, 99,103,251,211,111,190,186, 93,248,122,247, 82,231,133, 23, 63,190, 86,250, +226,248,205,123,239,188,247,220,219, 89, 49,253,160,177,183, 87, 63,152,158,156,189,168, 79, 59, 64, 22, 84,242,240,151,141, 5, +147, 37,248,243,153,101,198, 54, 98,102,106, 22, 33, 5,227,139, 44,107,118, 45,234, 41,165,230, 58, 42,241,165,207, 25,119,127, +191, 71,226, 30, 19, 17,140, 75,223, 3, 68,112,171,102, 13,171,249,149,203, 47,151,234,101, 93,213,153,208,238,135,199,181,117, +220, 57,107,100,241,157,233, 67, 12, 7,136,140, 23,102, 87, 26,157, 22,158, 29,136, 59, 35,152, 76, 8,225,100, 60, 5, 88,173, +107,250,220,244, 66,211,106,140,188,143, 88,134,146,245, 33, 36, 67, 55,144,221, 55,179,155,165,230,169, 79,210, 8,126, 96,237, +132,235, 98,114,156, 28, 92,195, 82, 66, 35,147,107,126,137,192,150,143, 42, 15,212,157, 20, 18,106,181, 10,139,202, 80,111, 15, + 85,208,184,201,153,253, 76, 72,103,147,218,158,207, 6,180,212,124,142,175,124,227,255,141, 59,132,161, 77, 69, 33, 70,201,124, + 17, 38, 79,205,172,132, 2,228,207, 47,201, 18, 5,161,255, 4, 32,234, 90,122,219,168,194,232,248, 49, 51,126,204,120,226,146, +184,142, 67,109, 37, 4, 7,146, 10, 82, 32,108, 10, 84, 77, 75, 85, 85, 40, 82,139, 42, 22, 93,177, 0,254, 0, 27,164,110, 88, + 35,216, 33, 80,251, 7,144, 16, 43, 36, 84, 36, 22,149, 44, 33, 85, 1, 41,173, 64, 40,113, 72, 49,182, 83, 59,177, 61,126,204, +120,222,119,248,206,157, 68, 72,217, 57,126,220, 59,247,123,222,115,206,119,226,223,227, 24,251, 43,177, 19,109,201, 24,183, 67, +159, 75, 72, 2, 97, 60,147,153,165,196,138,235,169,128,199, 37,112, 96, 63,227,228, 49, 56,184,152,136, 12,215,115,184,128,177, + 16, 93,224, 8,255,123, 80,198,245,202,233,108, 72,203,197, 42,157,242,169, 13,198, 1,125,194, 43, 11,235,157, 97, 39,129, 93, +166, 53,249,209,241, 11,248, 13, 61, 4,112,152, 95,200,205, 83, 50, 14,135,238,218, 2, 39,102, 56,174,105, 90, 19,250,241, 35, +107,196,141, 48,193, 39,142,240,185,229, 44, 88, 42, 86,245,105,143,138,122,232,241, 71, 50,189, 97, 4, 10,141, 16, 67, 40,154, +152,224,171,114, 14,109, 86,136,249, 81,209,164,138, 66, 50,224, 65,242, 84, 97,159,183,141, 48,108, 47, 76, 73,105, 46, 39,130, +155, 14,244,230, 18, 48,179, 36,203, 74, 82,194,114, 25, 37,197,230,148,130, 46, 74, 51,126, 49,137, 57,150, 82,146,188,188,160, +164, 19, 73, 9,240, 68,114,205, 96, 15, 98,196, 3,244, 94,158, 54,219,191,214,106, 15, 30,252,244,251,206,159, 87, 54, 47,107, +138,242,176,246, 80,203,202,178, 20, 79,165, 18, 42,135,198,183,155, 79,175, 93,189, 52, 53,198,207, 58,109,138,235, 23, 86, 87, +198,227, 17,121,166,120, 8, 54, 22, 25,172,105,251,134, 69, 81, 52,244,188,208,241,248,229, 45,159,224,126, 70,205,221,251,230, +235,209,200,184,119,255,126,173, 86,163, 77,125,127,235,189, 59, 31,220,108,181,234,134,209,215,148, 20,200,221,114, 92,194,196, + 11,250,255,168,242, 32,207, 30,218, 46, 72, 20, 20,177, 37,112,168, 99,185, 44,149, 11, 73, 53, 67,165, 37,128,249,156,126, 0, +188,153,143, 76, 16, 95, 23,184,204,154, 50,215, 15,117,203,148,168,226, 9,134,131,105,223, 97, 78, 65, 41, 90,190, 91, 45,189, + 60,164,116, 19,106,242, 48, 3,112, 49, 56, 87, 88, 76,136,190,135, 33,218, 20,185, 79, 25, 50, 40,158,148, 20, 88,227, 33,151, + 4,215,205, 65,113,166,244,225,187, 31,255,219,109,144,243,162, 66,138, 28,171,110,244, 86, 74,171,250,164, 79,245,193, 98,225, + 5,122,184, 34,159,138,181,116,118,249,160,179,175, 41,121, 11,148, 69, 63, 43,229,110,221,188,173,247,245,214,241,161, 9,109, + 12,167, 92, 56,215, 31, 29,189,189,246, 78, 79, 63,162,168,163,166,178, 92, 89, 77, 80,101,245,197,114,117,123,239, 17, 61, 60, + 50, 96,219,119, 77,219, 64, 32,141,129,229, 23,130,150, 2,198, 83, 42, 41, 11, 72, 33,141,243,149,243, 79, 14, 30, 99,104,173, + 99,247,134,199,100,159,160,212,170,179,197, 74,101,208,235,110,255,245,232,104,216,189,248,210,198, 94,235,111,138,232, 90, 70, +203, 43,103,234,135,187,175, 45, 93, 56,155, 47, 12,205, 33,121,129,242,220,185,221, 86, 61, 9,156, 82, 88,158,171,200,208, 36, +232,143,141,209,254,225,110,163,219,120, 99,249,245,118,175, 73,139,186,177,113,157, 92,137,229,216,165,252,188, 4, 42,123,210, +114, 76,219,115, 96,243,192, 92, 57, 0,132, 49,246,156, 58, 75, 1,192,176,141, 92, 90, 85, 51, 10,101,187, 74, 58, 75,139,165, +253,118,221,201,196,233, 61, 47,176,194,134, 38, 88, 83,193,179, 5,204,138, 99,156, 62, 18, 17, 51, 35, 56, 90,156,247, 35,133, + 72,171,132,182, 69,161,248,235, 45,196,253,132, 44,228, 10,233,226,104,218, 57,248,167,243,219,126,115,167,217, 61,118, 28, 23, +138,148, 84,146, 7, 22,162, 56, 46,165,148,148, 56,175,204,190,185,124,123, 50,238,125,249,248,231, 35, 91,255,116,105,235,226, +229, 59,217, 79, 10,119, 23, 63, 95,175,172,106,223,106,221, 31, 26,223,125,245,133,173, 4,105, 85, 9,115,177, 39,251,191,188, + 26,223,220,250,232,198,221,239, 63,107,255, 17,108, 93,185,213,109,108,255,120,184, 19, 36,228,235,243, 43,134, 7,177,198, 32, + 22, 46, 22,202,157, 1,249,229, 25,203, 54,105, 93,200,166,173, 73, 90, 76,175,149,215,158,233, 29, 96,124, 35,132, 55,135,180, + 93, 90,125,107,183, 93, 23, 69,192,202,242, 25,109,226,154,115,188,172,167, 12,160,126, 88, 15,192,170,163,183,163, 12,226,140, + 31,176, 79,233,200,105, 89,173, 63, 62, 22,209,178,164,236,164, 90,111,239, 5,130, 79,249,216,213,245, 77,170,231,128,228, 9, + 65,192,166, 83, 59,177,199,232, 37,248, 60,245, 12,152, 36,201,213, 18, 5,131, 1, 71, 9, 2,156, 26, 93,224,163,209,199,207, + 52, 85, 15, 12,106,170, 62,207,147, 64,210,142, 69, 9,124, 36, 4, 39,208,211, 47, 99, 98,146,103,147, 81, 3,138,227,241, 63, + 74, 58, 3, 62,191, 11,237, 37, 70, 65, 75,199,109, 4, 59,213,229, 59,233,145,199,133,248, 9,127, 41,140, 24, 60,120, 13,114, + 35,129, 95,202, 47,140, 32, 88, 13,223,203, 7,166,250,188, 35, 23,251, 79, 0,162,174,165,183,141, 42,140,142,237,121,250, 49, + 30, 59,142,147,180,117,210, 52, 1, 66, 30, 80, 76, 34, 18,146, 34, 26,145, 72,236, 90, 9,118, 72,252, 1, 54, 32,193, 50, 98, + 89,177, 98,193,134, 93, 5, 18, 72, 32,118,116, 1, 82, 87, 5,129, 4, 18,155, 54, 24,170,214,177,131, 29, 63, 38, 19,199,118, + 60, 79,143, 57,223,189, 9,172, 60,155, 25,207,220,199,119,191,243,221,115,207,249, 63,190, 7,204,239, 49,196, 72, 58, 87, 0, +227, 21,118, 42, 54, 48,174,143,112, 33, 35, 36, 92,248,116,209,163,241, 43,137, 74,223,237,197,201, 27,132, 83,185,185,221,210, + 57, 18,192, 39,144, 9,195,212,130,217,109, 55, 58,117,100,193,196,158, 12,217,100,182,233, 56,162,166, 36,241,239,164, 97,194, +248, 65,200,208,159,153, 92, 80, 36, 21,112, 44, 8, 92, 31,121, 42, 99,218,224,177,154,172,112,254, 53, 91, 63, 9,106,169, 82, +124, 56,226, 55,162,101,181,211, 51,139,172, 20,153, 26,103, 32, 12,201,202, 89,210, 60, 4,104, 46,116,201, 15, 30,179, 88,131, +187,240,194,170, 2,108,225,219,110,159,212,121, 4,214,133,172,200,162,201, 73, 18, 96, 27,210,224,224,166, 13,236, 83,168,250, + 35, 81, 49, 71, 33,142,171, 68,226,244,170, 68, 59,159,164,216,136, 62,115, 4, 7, 49, 23,235,148, 31,181, 29, 32, 62, 50,129, + 39, 99,154, 88,132,220, 75,197,136, 76, 92,215,232,198, 43, 27,171, 47,173,253,244,203,239, 47, 23,139, 51, 87,231,191,249,238, +158, 31,198,194,161, 24, 14,201,140, 33, 24,138,205, 86,167,248, 98, 81,215,141, 7, 63,255, 58,150,205,124,114,231, 78,187,121, + 84,169, 86,226,113,153,237,187,114, 54, 61,137,208,224, 66, 67, 19, 0, 61,224, 13,132,225,250,218,245, 27,155, 27,123,123, 31, +149,203, 37,219,177, 42,149,191,126,188,255, 61, 2,250, 91,183,223, 44,149,126,139,171,163,172, 33, 41, 10,222,153,237,237,179, +163,162,100,218, 35, 70,207,149, 36, 88, 58,199,209, 6,179, 41,136,132, 12, 46, 32,187, 32,149, 64, 74,187,169, 12, 69,116, 76, +230,157, 69,178,120,146, 56,136,208, 78, 78, 74, 82, 83,146,238,133,110, 74, 73,150,205,199,180,239, 75, 27,216, 67, 38, 69, 75, + 68, 85,172,116,128, 68,219,215,111,150,155, 85, 70, 77,163, 35,245,104,219, 75,217, 43,182, 55, 72, 42, 9, 52,240,246, 11, 59, +120,164,217, 53, 75,213,125,210,213, 34, 55,203,163,102,167,158, 78, 26,102,167,129,117, 66,140,201, 39, 93,147,233, 60, 19,133, + 8,128,199,245,200, 77,165,211, 63,126,246,242, 66,165,121, 96,157,152, 17,159,186, 12,179, 8, 19,181,239,216,155, 75,235,115, +151,230,244,164, 1, 4,242,180, 85,102, 30,129,163,214, 73, 3,113,115,253,185, 13,100, 15,249, 76,174,218,170,168, 10, 63, 33, +128,213, 74, 40,228,166, 49,130,229,152,140,135, 52,172,250,214,242,150, 38, 41,255,152,181,124,102,162, 55,232,162, 1,110,172, +108, 90,167, 22,210,142,122,171, 30,146,193,158,240,218,210, 86,179,211, 64, 26,158,211,199,124,207,173,153,117,204, 85,199,115, + 15, 26,149,190,131,175, 35,224,210,181, 79, 49, 22,232,192, 45, 59, 43, 10,192,186, 50,187, 12,108,182, 56,189,248,231,225, 62, +134,100, 82, 73,181, 59,173,129,221,195, 91, 21,198,175, 28, 52, 15, 60,151,182,172,119,215,118, 87,231, 87,159, 30, 61, 1, 38, +204,235, 99,128,240,220,154, 25, 67, 25,161,191, 71,185, 63,159, 80,126,207, 62,166, 99,109,241,241, 25,193,155,122,117,156,228, +124,125, 55,130, 97, 28, 9,207,173, 56,254,115,217, 99, 51, 59,100,167, 46,168, 67,209, 69,214,220,254,145,241,224,176, 93,106, +251,134, 31,241,163,237,138,213,235, 7,129, 77,230,148,136,233,184, 32, 13, 76,164, 19, 46,243, 32, 76, 41, 50, 80,101,205,140, +182,122,214,231,165, 31,214,211, 43,239,205,191, 93,184,123,243,238, 27,223,126,245,248,203, 15,191,254, 64, 24, 19,238,189,251, +169,154,209, 10,250,164, 22,147, 13, 81,239,140,122,165, 71,247,151,119,118, 54,251,219,239,255,241,206,222,244,199, 87,141,236, +103,143,190,176,194,240, 86,161,232,142, 28, 38,227,154, 62, 27,244,109,207, 77,199,147,103,174,131,213, 17, 88, 16,241,154, 60, + 29,153,243, 4,167,173, 51,178, 55,213, 87, 15,143,107, 30, 2,151,168, 50,147,238, 76, 58,110,212,145, 77,147,182, 1, 1,231, +231, 47, 47,250,129,187, 52,179,132,136, 92,156, 47,246,237, 65, 90,211,231, 38,174, 17,196,244,108, 82, 29, 71, 54,237, 15,144, + 74, 2, 18,229,141,137,135,213,135,172, 90, 67,230,204,204,120, 28,249,153, 56,153,158, 66, 30,240,250,173,221, 39,165,191,179, +233, 92,253,184,230,122, 54,218,204, 39,233, 89,162,198,158, 49, 66, 23, 23,241,194,168, 96,235, 49,177,179,140, 68,118,194,200, + 11, 35,198,243, 38,146, 8,201,149, 16, 89,121,132, 9,229, 98,213,207,165,114, 64,159,164, 85, 71,226, 66, 1,139, 93,164,253, + 71, 34,145, 84,186,136, 8,124,123,153,251, 30,141, 46,194, 47,227,192, 25, 9, 35,147,200, 58,129,205,125,161, 79, 7, 29,190, +114,207,230,103, 1,116, 40, 61, 29, 13, 53, 57,241,175, 0, 84, 93, 75,143,219, 84, 20,142,223,118,156,216,241, 36,147,215,180, + 51, 81,146,182,104,250, 80,135, 81, 91, 22,101,129,104, 97,129,170, 22,196, 2, 9, 65, 5, 66,229, 7,176, 64, 32,177,131,174, +216,179,132, 63, 0,108,144,232,130, 17,237, 12,168,116,131, 88,160,106, 58,165,180, 37,208,164,121, 59,126, 36,177,227,132,239, + 92,103, 1, 82,148, 77,156, 40,190,199,247,156,239,156,123,206,247,241,255, 81, 2,143,211,115, 38,253,176,124, 24,232, 62,169, + 55, 36,241, 63, 33,215, 24,121,193,239, 15,188,129, 27,142, 16,209,177,212, 65, 52,137,161,123,146,234, 48, 44,135,161, 63, 4, + 48, 30,149,179,229,191,123,127, 33,152, 9, 84, 41,166, 58,138, 76, 13, 0, 60, 41,140, 36,120,127,234, 6,193, 56,102, 78, 96, + 5,107, 97,191,121,119,232,245, 99,166, 28, 86,102,141,143, 56,145,215, 76,129,166, 5, 65,164,142, 73, 66, 36, 9, 63,244,168, +222, 66,170,158, 20,111, 1,196,240,111,227,233, 86, 18,126, 11, 3,138, 76,140, 52, 63, 98, 43,131, 21, 97, 20,254, 33,233,123, + 4,190,227,219,128, 66,149,194, 81, 70, 56,206,154,200,217, 48, 85,192,104,184,153, 40, 1,157, 61, 16,130,101,105, 50,113, 99, +205,194,141, 92, 5, 8, 14, 72, 87, 21,216,208,169,200, 3,219, 18, 75,210,156, 38,155,152,133, 22, 41,141,203,164, 4,211, 64, +142, 47,100,116, 92,198, 17, 45,191,136,187,139,218,205,214,133, 23, 47,228, 45,115,119,119,175, 92,200, 31,171,148,116,124,170, +176,240, 78,197,184, 16, 43,177, 90, 40,113,156, 50, 24,250,175, 94,190,146, 59, 92,189,244,202,107, 8, 37, 83, 63,130,103, 6, +172, 3, 12, 55,117, 49,191,162,148,243,106, 57, 43, 31,194,123, 81, 46,174, 42,165, 66,218,182, 59,240,202,181, 74,249,227, 15, + 63,184,126,253,179,115,207,158,186,245,227, 13, 44,246,214,201,227, 1,185,105, 46, 10,196,233,148, 58, 44, 17,224, 67,170,176, + 51,248, 79,131, 98,156, 42, 75, 0,101,154, 34, 82,179,157,192,171,226, 2, 89,133,174, 10, 70, 82,180, 82, 98, 70,151,204,148, +148, 2, 72,214,101, 51, 45,231, 86,148,156,165, 25,112, 93, 73, 37,210,230,195,185,237,207,156,201,124,252,212,251,199, 84, 51, + 72,143, 52, 89,227, 56,161, 90,168,225, 75, 2,227,116,133,189, 90,253, 54,227,216,156,167,147,233,164,146,148,101,173,239,246, + 96,169,174,219,197, 82,239,222,189,217, 30,182, 53, 69,247,167, 30, 80,243,169,141, 77, 36,189, 8,170,138,152,132,115, 63,148, +221,160,254, 95, 82,147,136, 84, 81,221, 62,114,166,209,123, 76, 7,110,190,109,233,217,237,218, 54,174,124,218,110,226,167,224, + 73, 97, 38,228,215,216, 50,223,221,185, 17, 74, 68,175,215,113,186,133, 76,161, 94,168,192,190, 64, 97,186,172,223,222,191,253, +184,253,232, 97,235, 17,199,142,167,120, 94,162, 97,200,233, 24, 65, 5, 9,129,235, 59,150,110,192,107, 28, 52,238,223,250,125, +175, 86,172, 35, 67, 11, 2, 79,163, 49, 97,165,152, 41, 0, 94,121,163,254,138,145, 67,106,125, 98,253, 24,128, 23, 31, 69,240, +200, 57,195,218, 92,175,215,139,213,197,124, 86,207,111,240,139,232,153,181, 35, 79,250,205, 92, 42, 11, 24,112,245,229,183,171, +197,245,246, 0, 89,172,247,219,253, 95,109,191, 15, 8,111, 38, 13,106,198, 93, 44,206, 28, 63,171,176, 89,205,131,198,189,162, +185,186, 86, 90, 63,187,245,252, 65, 99,255,235,189,111,224, 41,224, 71,138, 86, 25,238, 41,156,197,218, 6,124,201, 42,174,229, +214, 94, 58,125,145,148,115, 38, 62,219,250,115, 82,238,192,238, 20, 19,140,227, 87,140,169, 99, 68, 41, 33,136, 49, 39,240, 18, + 2,178,187, 38,134, 57,216,131,159, 45,254,232,186, 63,183, 31, 56,115,106,241, 25, 18, 80, 75,248,115,160,117,146,135, 65,118, + 23, 44, 88,100,143, 98,133, 72, 18,164, 6,212,196, 66,100,101,121,167,121, 15,191,118, 41,127,186,118,237,245,232, 78,226,157, +157, 55,222, 61,255,126,226,124, 98,231,242,151,146,161,244,130,201, 71,191,124,245,230, 15,159,191,119,243,139,134,227, 7, 82, +212,250,246,167,139,159, 60, 39, 39,178,215,190,255, 52,119,244, 92, 69,203, 79,253,158, 61, 11, 85, 94,134, 79,118, 38,206,112, + 50,146, 36, 97, 68,162,219, 52, 85,158, 53,172,180,162, 43,130,140, 7,102,171,122,146,102,249, 56, 18, 90, 96, 98, 25, 20,203, +101, 54, 44,221, 25,117,241,242,166, 94,172, 72,194,168, 23,196,230,224, 73,207, 29,192,160,216,176, 15, 91, 15, 66,210, 65, 24, +183,134,196,123,145, 77,174,212,139,117,234,145,157, 76, 68, 86,183,113,125,219, 84, 13,137, 77, 92, 47,251, 82,168, 32, 67,141, +146, 52,228,241,103, 11,219,164,239,244,240,168,108, 30, 62,113,245,133,183, 0, 74,144, 52,140,136,217,145,199,243,156,146,211, +240,234,237, 97, 7,171,154, 55,242, 88,176,190,211, 69, 14,209,113, 59,196,209,204,104,135,107,249,122,199,110, 15, 93,219,243, + 29,248, 32,219,165,131, 34,224, 21,114, 58,212,247, 49,179,180,140, 12,248,184, 0, 8, 83, 74,102,105,233,156, 89, 44, 79, 42, +154,174, 25,212, 94,165, 24, 51,210, 53, 28,187,227,145,196, 41,203,122, 9, 27, 47,134,141, 16,222, 2, 50,215, 60, 70,194,255, + 10, 64,212,185,196,182, 81, 69, 97,120, 60, 51,158, 25,219,227, 55, 99,199,169,147,216, 6,220,244,161,180,137, 80, 27,218,170, + 44,216,176,232,190, 21, 18,130, 37,123, 36,118,168,176, 66, 8, 33, 54, 72, 32,118, 21, 91,186, 64, 32, 22,160, 32, 65, 82,136, + 4, 66, 85,195,171, 69, 10,164, 73,147,216,158, 56, 99,143,159, 99,207,152,243,159,155,132,173, 21,197,158,185,247,158,115,238, +121,124,255, 73,252,142,124, 28,217,151,140,153,149,153, 84,165,162,205,150,167, 0, 80,145,241,255,175,174, 74, 98,246, 16, 14, +197,138,231,233, 34,172, 65, 83, 52,240,143, 68,250,160,191,202,211,158, 66,145, 85,225, 33, 93,173,209,169,115, 33, 80,112, 64, + 1,145, 8, 68, 71,191,232,233,151,142, 97, 10, 18,152, 12,232, 8, 22,250,106,199,215, 5,180, 31, 41,225, 92,106, 42,202,135, + 95, 56,111,153, 91,157, 98,186, 57,141, 74,157,203, 88, 49,100, 2, 88, 69, 47,200,197,167,192,163, 56,241, 93,236, 0,189, 49, +224,153,241,104,154,137, 8,136,121, 14,187,205,102,183,193, 80,114, 41,162, 26,213,226, 60,189,181, 35,148, 36,247,151, 31, 75, + 29,194,241, 64, 58,220,239, 57, 3,155, 60,127, 33, 31, 67,146, 61, 12,141, 83, 69,166,203,154, 44, 64, 2, 28, 75,241, 88,211, + 68, 32, 98, 38, 44,159,128,238,151, 33, 87,104, 90,237,230,185,179,213,226,116,126,229,187,111, 47, 61,183,168,133,149,135,143, + 30,137,129, 85, 9, 12,234,209,194,185,249, 91, 55,111,126,249,197,221,126,215,189,253,206,237,143, 62,120,255,242,242,114,109, +111,111,243,241,182, 10, 48,128, 15,171, 55,241, 52, 53, 48,180, 64,131,192, 21, 58,238,233, 44, 71, 12,245,202,181,235,247,214, +238, 25, 70,228,213,215, 94, 47, 84,150,103, 78, 37, 87, 86,190, 57, 93, 61,111, 24,230,218,250,125, 63, 8,143,198,130,228, 42, +243, 36, 44,154,201, 24,248,131,185, 69,158,128, 69,158, 7,191,223,159,120, 35, 97, 5, 78,168,177,104,189,140,234, 10,185, 46, + 49, 61,139,238,157,112,200,140,202,113, 83,214,227, 33,218,179, 64,211,203, 10,198, 82, 38,126, 42,146,233,122, 46,133, 18, 24, + 42, 65,125, 89, 54, 99, 9,187,125, 48,166, 24,223, 72, 26,154,126,208,170,107, 64,242,104, 49, 84,204,146, 20,197,211,162,195, +141,134, 66,233,120,154,194, 82,250, 95, 77,183,169, 41, 74,119,232,210,145,214,100,125, 56,238,145, 3,130,252,194,160, 51,103, +149,246, 14,159,208, 65, 60,149, 45,238,183,106,205,142, 67,251,144, 17,222, 81, 50, 89,228, 30, 42,133,114,117,246,204,249,179, +139,179, 87,206,252,184,186, 74, 15,108, 59,117, 85, 13, 55,219,135, 41, 51,185, 99,239,122,227, 33,157, 67,219,181, 41, 92,160, + 31, 57,151, 43,229,211,185,189,195,125,122, 59,179, 79,205,209, 39,180, 88,232,214, 64,193,124, 52,102,229,107, 67,142, 80, 0, +184,177,185, 97, 37, 50, 91,141,109,218,168,244,117,207, 76,149,215,255, 90,231,230, 13, 24,193,116, 36, 77,230,219, 74,100,147, +177, 36, 89,156,165,202, 66, 3, 74, 35,173,210, 76,181, 63,234,255,252,231, 47,237,126,231,242,233, 75,116,173,113, 58,142, 2, + 82,147,239,246, 58,244,117,133, 84,174,222,218,183,157,198, 82,249, 2,247,195,140,235, 7,187,189,118,123, 4,221, 96,213, 1, + 31,122,152, 49, 83,205,174, 67,143,207,121,115, 63,170, 27, 47, 93,124,241,251,223,127,160,103,161,107, 7, 45, 87, 50,146,162, +152,174, 26,213,243,215,166,164,126, 95,242, 60, 28,136, 16, 51, 35,197,200,123,112, 68,231, 22,105, 80,159,227,247,137,175,236, + 55, 18, 53,111, 72,182,205,243, 67,105, 61, 17,209,236,199,142, 75,246,125, 0, 92, 40,136, 1, 67,122, 11,140,215, 18,115,137, +244, 23, 81, 67,182,148,153, 15, 55, 86, 15, 61,247,147, 11,111,100,223, 91,124,121,233,149,221, 94,243,243,187,119, 58,159,254, +182,185,117,255,179,157,213, 59,127,124,245,188, 85,186, 49,123,209,247,251, 31, 63,252,186,144, 46,166,157,206,211, 55, 94,136, +255,154,121,247,239, 55,223,190,254,214,206,147,127,214,236,159, 22,243, 11, 57,157,150,111,162, 28,241,186,132,226, 69, 40, 25, + 79,152, 90,164,231, 13,124,192, 74,189,186,115, 32,236,174,168,196, 94,157,191, 74,175,133,174, 59, 28, 76, 74, 86,194,162, 69, +193, 49,132,142,150, 68,215,125,148,214, 7,189, 30, 69,202,137,108,192,169,110,122,248, 33,224,225, 18,119,229, 5,207,230, 43, + 20,200,143,153, 3, 74, 91, 17,214, 3,221,135,128, 66,251,248, 48,196, 17,113,137,130,134,122,173,150, 50, 81,143, 81,195, 97, + 10,225, 31,252,251, 64,215,141, 9,152,231, 67,193, 96,128,252,136,200,153,112,183,202, 0, 36, 9, 1, 5, 64, 5, 46,130, 64, + 40,186, 85,223,130, 56, 20,157, 17,206,201, 12, 6,125, 80,210, 2,238,160, 65,218,205,162,107, 43,108,148, 4,140,138, 80, 67, + 98, 30,179,170, 98,230,110, 0,205,119,134, 69, 83, 84, 36, 38,105, 93, 8, 84,249,228,235,166,179, 69,183,143, 93, 81,201,149, +231,172,242,174,189,173,162,231,197,255, 79, 0,174,174,165,183,141, 42, 10,207,140,227, 25,143, 51,126,140, 99,215,118, 72,154, +208,148,128,154, 20,167, 9,134,150,151,212, 72,172,160,165, 74,120, 72, 44, 64,236,248, 5,136, 13, 44, 34,129, 88, 33, 54,108, + 17, 15, 9,138, 4, 18,123, 32,162, 43, 86, 36,149,234,180, 73,133, 73, 83,146, 52, 41,141, 31, 99,103,102, 60,115,199,230,124, +103,156, 70,194, 75,123, 52, 30,205,189,247,156,239,188,190,239,152,159,128,105,210, 2, 27,114,133, 94, 24, 16, 48,146, 23,255, +235,139,199,136, 1, 10,173,232, 94, 71,238, 89, 86, 58,129, 47, 29, 67,123,102,247, 98, 57, 38,218,148,131,170, 78,119, 3, 55, + 64, 88,207, 57, 10, 22,122, 76,141, 21,126, 40, 14,200, 24, 57,122, 29, 49, 85,247,145,174, 66, 89,147, 57,129,251,175, 75,234, +119,195, 10,203,181, 88, 35, 20, 43, 21, 42,144, 3,164, 11,215,136, 39, 45,187,209,207, 38,114, 99, 99, 84,137,114, 85,173, 95, +170,237,171,147,135,230, 10,195,223,104, 21,100,153,115,152, 94, 10,238,134,152,184,156, 98,186,180,158,174,219,117,191, 11,250, + 98,208, 76, 6,130,108,229,177,188, 12,167, 43, 41,100,163, 93,144, 53,141, 30, 42,230,104, 71,241, 3, 41,156, 96, 98,222,187, + 94, 68, 10, 25,229, 32,136, 70, 22,219,118,187,135,135, 4,175,128, 92, 65, 84, 18,136,237,187,127,191,122,249,149, 84, 82,187, +181,113,253,185,103,231,170, 27,215, 7,162, 93,250,165,144,203,188,177,184,240,246, 59,239,174,172,172, 92,189,250,195,107, 11, + 87, 30, 25, 25, 91, 90,250,184, 88, 28,158, 61,119,238,215,223,150,201,115, 42, 93,121,110,102,102,108,132, 66,219, 33,211,200, +164,147,233, 84,122,136, 12,165,170, 14,186,118,239,226,252,203,183,215,171,107,149, 13, 93, 83, 39, 39, 70, 55,255,186,179,252, +203,239,229,167,206, 83,176,113,237,218, 31, 3,138,230, 65,204,146, 5,244, 34,125,113,109, 66,174, 2,163, 88,200,167,211, 49, +246,124,196,237, 10, 88,124,153,138, 32,170,196, 99,146,161, 67,229, 71,139,146,125, 87, 64, 9, 14, 22, 6,164, 63, 53,114,111, +186,172,199,240,118,105, 43, 88,109, 39, 38, 71, 65,233, 39, 41,173, 78,147,220,159,224, 41,101, 20, 46,152,207, 57,111, 22, 48, + 28, 40, 71, 8, 19,145,169,141, 50, 19, 3,253,237, 94,125, 47,155, 42,208, 5, 73,200,140, 40,187, 53,156, 82, 11,220,129, 2, + 78,132,245,227,201,208,123,190, 79,187,203, 52,204, 83,249, 83,171,213, 63,195, 9, 12, 58, 54, 18, 56,246, 0, 74,232, 76, 18, +194,109, 57, 22, 29,170,137,226,227, 55,183,214,108,209,185,178,176,120,176,245,224, 86,245, 6, 60,119,208, 37,136,103,145,173, + 20,110, 50,150,104, 34,103, 2,111,238, 10,219,133,250, 71,157, 86, 45,161, 27,152,186,146,228,102,187, 49,148,204,209,106, 18, +190, 30, 54, 11,102,220, 36,136, 87,154, 46,157,121, 97, 54,216,183,107,173, 58,125, 89, 52,243,190,112, 77,232,240,133,100, 85, + 61, 50, 13,197,116,161,152, 41, 84,182, 42,100, 68,171,247, 55, 45,183, 13, 41, 56,186, 73,186,208,118,154,163,217, 17,211, 72, + 85,238, 84,200,177,157, 61, 57,181,125,127,251,197,179,207,151,198,166,108,191, 83,111, 60,120,242,209,210,234,230,170, 54,160, + 53,108, 11,148, 88,232,218,114,189,158, 32,168, 78, 91, 84,211,226,228,159,232,245,143,159, 24,167, 37,216,169,223,187,185,115, +219,113, 15,201, 95,182,208,212, 75,182,218, 38, 36, 50, 22,137, 13, 95,200, 82,196, 43,161, 77, 59, 96, 22,223,126, 79, 1, 75, + 72,134,130,239, 18, 71,111, 72,185,200,190,250, 79, 45,213,164,131,220, 85, 38, 71,103, 68,123, 55,162, 30,236, 90, 46,186, 90, +131,110, 39, 0, 43, 10, 46,230,118,111,159,171,144, 9, 77, 77,106,234, 61,215,250,122,189, 82, 86, 71, 63,248,252, 75,103, 79, +188,245,197,235, 95, 45,124, 63,125,233,177,229, 79,191,253,100,253,167,181,218,230,135,229, 55, 75,249,211,169,193,196, 51,249, +201,137,120,254,179, 27, 63, 22,181,236, 75, 79, 44,150,159,158, 91,250,249,163,247,146,239, 39,178,242, 55, 27,223,157,201, 79, + 79,165,200, 51, 9,229, 97,211, 31, 30,180, 27, 27,208, 28, 31,194,242,161, 90,180,242, 80, 83,153,169, 5,118,144, 42,113,181, +168, 74,168, 20, 86, 30, 93,137, 14,196,211,184,179, 37, 99,100, 56, 79, 0, 46, 70, 67, 79,148, 79,207, 90, 32, 52, 4,174, 11, +203, 15,100,151,254,109, 29, 16,180,150,192, 30,163,211,102,116, 58,224,175,101, 62, 50,193,138,114, 72, 95,181,225,107,209,195, +160, 70, 85, 90,130,128,117, 28,209, 2, 31,208,131,121,189,163, 73,204, 48,129, 45,179,239, 4, 7,156, 12,202,197, 92,226, 68, +155,149,133, 60, 10,237,188,206,124,105,190,186, 95, 85, 80,196, 2, 76, 3,148, 34,219,126, 52, 73,235,116,108,129,180, 76, 72, +120, 22,178, 57,246,164,126,102, 24,169, 89,223,247, 6,245,196,120,110,124,167,182, 45,243,116, 30, 4, 24, 88,248, 14,217, 63, + 70,110,135, 78,123,191,193, 25, 42,214,157,248, 79, 0,170,174, 37,166,141, 43,138,206,248, 59,182,199, 16,112,130, 12,129, 36, +206, 7, 21, 68, 81, 99,199,134, 44, 72, 76, 23,253,136, 34,162, 36,219,168,202,190,203, 74, 37,155, 84, 44,187,234, 2,117,213, +172, 73, 21,101, 17, 37,106,149, 85, 43,148, 5,138,100, 68, 16, 73,249,218, 22,197,128, 63,216,158,192,120,126,158, 25,247,222, +251, 38,145,227,149, 37,203,214,248,205,155,115,239,125,247,220,115, 28,127, 15,102,237,196,200,139, 28,231,140, 19,224,216, 19, +199,241,159, 56,166,211, 8, 25, 61,195,128, 12, 38, 77,216,224,228, 91, 27,250,163,134,142, 95, 68, 43, 40, 52, 91,180, 28, 63, +193,118,126, 37,215, 30, 14,240, 92,228,124, 36, 86, 57, 65,133,107,246, 33,189,105,203,188, 29,116,118,252,101, 89,191,130, 49, +159, 24,124, 67,114, 4,127, 17,240, 49, 44,116,232,152, 45,218, 65,111, 80, 12,116, 24,134,202,248,250,180,232,152, 20,180,232, +160, 0,138, 0,164,218,180, 76,226,183,160,212, 1, 54,163,201, 7,174,140, 54, 61,120, 42,133,254, 65, 60, 90,133, 25,200,184, + 71,145, 28, 8, 48,209, 83,103,113,120,210,197,251,221, 33, 63, 9,178,195,125,135, 60, 87,131,220,198,224, 76,147, 87, 52,236, +129,105, 77, 83, 81, 45, 93,195,251,223,208, 44,180, 76,133,144, 67,100, 74,146, 93,112, 29, 20,107,219,219,249,169,111,190,187, +112,126,112,100, 52,145,223,217,205,230,247,224,167, 70,134, 70,198,199,198, 95, 60,127,190,240,199, 19,192,208,217, 7,179,207, +158, 46,100,243, 91,245,106,101,122,102,122,243,223,119,242,137,212, 41,138,119,102,166, 39,211,233,248,232,104, 42, 53,150, 74, + 37, 39, 38, 38,210,233, 47,147,215, 18, 55,110, 78, 70,123,163,181, 74,105,121,101,121,245,205,234,203, 63,255,122,181,184,248, + 94,150,111,223,186,125, 84, 45,191,123,187, 22, 18,253, 62, 15, 50, 97, 32,239,182, 81,184,175,133, 18,137, 54,160, 36,236,111, + 22,128,121,210,207, 33,137, 31,114,173, 36,249, 36,158, 84,223,160,102,132, 45,206, 5, 5, 62, 28,228, 4,161, 5,153,123,103, +216, 37, 0,162,251, 16,194, 41,243, 65,141, 77,151,133, 77,232, 38, 62, 69,110,198,167,133, 90, 74, 53, 21,233,184, 6,149, 50, +143,164,126, 36,231, 66,164,152,188,250,213,206,193, 22,160,118,119, 56, 2,235,220, 21,234,206,149,114, 40, 37,239,241,195,250, + 99,231,147, 20, 63,116, 83,189, 24,189, 12, 97, 88,240,121, 97, 37, 7,251, 6,179, 7,217,100,114,252,176,176,111,243,176,161, + 27,103, 35, 3,251,245, 2,141,242, 99,170,161, 27,170, 24, 20, 43,245,202,240,208,240,250,198,218, 81,174,180,177,179,118, 44, +215,209,255,239,184,154,254, 60, 93,172,151, 18, 87,174, 78,165,190,205,108,173,144,181, 60,202,201,153,168, 62,173,251,169,165, +105, 83, 21, 67,130,172,180,129,121, 14,234,229,235, 67, 99, 71, 82,213, 84,140,204,235, 37,128,215,162,116,120,186,163, 91,146, +235,128,126,231,250, 47,233, 13, 60, 55, 39, 91,155, 51,167, 66, 29,235,133,141,129, 72, 31, 92,191,162,169,177,158,129,154, 2, +229,133, 27,178, 51, 31, 2,150,246, 38,183,138, 38, 7, 94, 47,212,245,240,228,238,150,118,255,171,236, 21,171,135,241,203,241, +234,251,138,138,151,225, 37, 23,111, 15,128, 59,160, 91,236,204,133,178, 84,134, 43, 12,249, 3, 6, 57, 91,213,228,186,130,138, + 8,110,192, 57,136, 22, 3,167, 99,117,185,236, 33,125, 2, 23,103,185, 53,109,232,102, 47, 68, 7,196,119,100,187,216, 31, 24, +187,108,172,195,177,118,198, 42,141, 32,140, 51,196,213, 18,220, 50, 28, 23, 42, 75,149,241,158,104, 81,223, 61,106, 64, 92,193, +211, 79,147,172,105,217, 20,108,147,190, 8, 75, 19,244,120, 59, 3,193, 46,193,245, 79,190,248, 83,236, 94,124,254,235,239, 19, +247,178,234,254,227,204,163,147,249,204,207,127,255,150,145,115, 15,227,119, 67,130, 79,106,158, 0,180,169,156,254, 5, 0,147, + 84, 91, 40, 44,221,247, 39,187,126,188,244,235, 47,191, 75,178,231,135,196,253,185,229,185,254,238, 43,147,145,115,146,213,224, +185,143, 66,103,120, 70, 1,149, 22,132,118,212,141, 33, 87, 19,139, 90,196,174, 22,231,240, 59,137, 15, 4, 88,140, 14, 1, 45, + 20,211, 39, 69, 50,199,118, 9,242,223,144,128,162,114,186,101,200,138,220,219,213,179,190,183, 73,114, 90, 46, 54, 15, 21, 64, +101,238, 0, 57,184, 33,247,154,233, 64,180, 99, 21,128,195,103,253,131, 40,126,199,187,157,148,215,182, 8,211,176, 86,224,145, +181,220,169, 56,138,229,228, 20,193,160,222,105,113, 0,166, 55,101,173,193,216, 31, 8,166, 86, 51, 87,204, 81, 96,109,145,119, + 16, 7, 59,159, 24, 45, 54,147,137,180, 25,161,220, 65, 72,102, 91, 78,138,124, 54,132, 88,200, 56, 69, 64, 23,173,169, 20,106, +251,212,228,196,212, 55,140, 35,120,154,237,156,168,227, 97, 6, 20, 10,138,218, 64, 73, 42,122,253, 47, 0, 89,231, 22,227, 68, + 25,197,241,105,103, 58,157,233,180, 51, 91,218,217,118,119,217,123,195,101,187,139,110,220, 69, 66, 68, 80, 49, 49, 49, 49, 49, + 65,159,224, 1, 18,194, 11,207, 36,248, 70,140,137,137,225,129, 55, 5,140,190,107,200, 18,118, 31,128,196, 7, 48, 75,162,240, + 2, 42,171, 75,161,206,222,122,191,204, 78, 47, 51,157,139,231,124, 95,219, 24, 77,250,208,204,195, 92,191,239,124,255,115,190, +115,126,167,207,127,167,173, 80,189,126,240,157,182,203,235,225,223,105, 22, 10, 75,145,176, 46,227,120, 61, 91,239,245,154,236, +254,203, 34,187, 48, 4,209,244, 51, 52,235,153,249,207,239,255,182,190,104, 20, 73,205, 2,219,135,159, 33,190,131, 21,201, 73, +232,246, 2,211,151,225, 44, 98,157, 69,203,181,169,237,192,168, 1,161,172, 49,180,239,131,107, 15,237, 25, 45, 27, 5,244,112, + 41, 81,205,243, 2,156, 64,105, 39,241,136,170,202,201,154, 81,113, 29,154, 16, 9, 35,198, 38,198, 31, 33, 65,147,131,211, 36, +125, 8, 6,180,133,172, 2,138,134,192, 57,132,249, 77,240,105,193,185, 33,229, 16, 44,232,219,176, 32, 42, 10,238,191,115,184, +201,201, 42, 97, 68,140, 9,152, 18, 15,227, 18, 81,145,138, 20,136, 74,156, 18,230,228, 48,167, 68, 2,240, 71, 12, 96,171, 23, +158,247,139,130,191, 86, 47, 63,126,242,171,107, 89,146, 20,169, 85,141,231,107,235, 96, 85,183,182, 55, 30,254,252, 48,147,201, +192, 51,166,166,199,231,210,179, 55,110,126, 59, 52,168,194,205,207,206, 28, 24, 25, 86,255,120,254,180,217, 54, 31,172, 62,250, +225,214,210,173,165,149,229,229,187,119,238,220,189,127,239,254,242,237,165, 86,195, 24,155,152,196, 22, 16,123,199, 22,222, 88, + 76,237,155,177, 44,167, 90, 51,198, 71, 39,206,156, 61,127,253,235,239,126,251, 51, 91,221,237,180,136, 82,181,209,100,247,152, + 62, 12,137,170, 96, 92, 4, 1, 12, 44, 34, 38,253,132,231,134,203, 54,118, 90, 10,250, 36,129, 13, 9,158, 28,241, 75, 33, 70, + 18,177,151, 5, 72,103, 88, 39,248, 32, 67,246, 36,124,150,133,126, 61, 14, 57,222, 97,205, 96, 66, 26, 14, 5,164,122,179, 12, +174, 37, 29,124,178, 56, 96,118,218, 71,143,190, 53,150, 26,213,178, 27,112, 65,240, 55,183, 10,155, 96,129,196,128,164, 55, 43, +160,223,183, 42,154,131, 60, 94,193,143, 9, 6,102,167,227,192,133,224, 11,142,192,204, 55,170, 37,189,152,220, 51, 4,223,248, + 69,238,133,192, 10,243,139,243,121, 45, 31,147,227, 45,211,208, 77,157,106,121, 88,185,210,227,233, 92,173, 0, 35, 68, 12,132, +226,195,170,166,101,225,224, 84, 98,114,179,160, 53, 44, 67,150,148,146, 94, 2,209,186,182,253,215,234,239,171,160,232, 47,124, +112, 46,179,243,178,131, 17, 43, 10, 36, 69,233,132,100, 76, 44, 73,231,222,158, 59,182,190,181,158,148, 19, 27,197,141,103,175, +158,217, 4,231, 4,118, 39, 61, 49,243,119, 46, 11, 22, 86,226, 67,249, 90,254,181,244,226, 75,109, 93,226,133,150,221, 6, 35, + 46, 4, 37, 85,142,107,165, 77,240,232, 15, 31, 92,120,255,245,227,171,107,191,236,141,141, 21,234,121,112,100,193, 7, 13,113, + 48, 17,165,106,179, 14,102, 2,174, 2,186,236,221, 19, 31, 21,115,155,213, 70, 21,245,132,143, 25, 84,226, 65,142, 23,248,208, +199,239,125,234,153, 86,121,183, 98,180, 13, 81,144, 82,195, 83,217,130, 70,234,175,113,182,194,187, 2, 19, 6,222, 70, 29, 1, +121,156,170, 36, 44,187,225,231,124, 42,195,237,127,103,148,225, 48, 59,138, 72, 53,202, 10, 68,205,134,251,203, 93,144,140,103, +147,152, 58, 54, 76,110, 69,249,200, 17,208,162,182,211,178, 28, 47,202,182, 10,214,182,142, 91,234,158,133,156, 94,151,104, 53, + 82,131,130, 83, 6,163,122, 72, 58,226,249,176,192, 31,138,133, 79,159,251, 60, 56,146, 56,245,197,169,111,222,188, 57, 63, 59, +247,253,213, 47,175,101, 87, 62, 59,252, 73, 84, 16,118,177,136,132,246, 5,193,244,155,133,216,212,143,217,159,162,245,240,241, +203, 31, 62,185,254,116,101,103,249,210,137,139, 87, 30,125, 53, 32, 15,158,140, 79,214,236, 38, 45,199,196,133, 21,147,126,176, + 77, 99,189,221,192,251,240, 51,189, 78, 79, 93, 27, 66, 83,169, 41,140, 5, 76, 7,207,243, 32,136,225,109,196,148,184,222,210, +105,124,120, 95,114, 58,147,203, 96,139,106,159,183, 93,222, 33,224,204,238,137, 40,205,205,234, 96,166, 77,114, 32, 9, 90,152, +233, 53,176, 35,165,142, 14,106, 59,199, 44,215,203, 3,161, 40,120,199,176,120, 4, 16,154, 68,229,182,183,107,234,166, 77,216, +230, 72,145,100,104,166,178, 71,147,226,201,221,193, 17, 66,163,235,244, 74, 65,187,205, 85, 9, 57,213, 13,178,193,132,156, 4, + 7, 17,151, 35,130,151,167,193,135,238,195,245,139, 43,153,238,253,144,130,169, 54,117,109, 84, 57,129,251,139, 8,193,150,193, + 15, 38,217,222,254,233,100,170,162,151, 92,108,232,102,209, 68, 41,106, 96,255, 17,128,172,107,233,109,226,140,162, 51,227,121, +249, 49,177,199,128, 99, 64,137, 35,132, 73, 65, 74, 89,240,172,212, 77, 23, 84, 66, 72,252, 10, 86,172,248, 5,180, 18,108,187, +169,120, 9, 84, 85, 85, 55, 44,187, 68,149, 88, 84, 65, 16, 65,120, 67, 81, 2, 84, 36, 64, 94, 30, 59,126, 76,102, 98,123, 60, + 31,231,222,111, 76, 74,107,101,225,216, 99,123, 94,223,189,231,190,206, 81,211, 84,136, 73,244,155,148, 45,234,207, 45, 55,146, + 80,199,127,249, 72,152,129,135,233,147, 47,173,188,170,252, 7,177,127,166,147,249,223,139,130,102,235, 13, 98,237,137,163,173, +252,190,202,228, 48,201,167, 98,230, 24,145,124,150,156, 35, 30, 6, 0, 26,103, 20,225,129,129,155,248, 6, 34,175, 47,152,238, + 94, 33, 1,163,172,101, 90,196, 12,174,114, 34, 66, 40, 8,192, 83,138, 54,234,238,108,249,235,204, 24, 55,252, 26,246, 67, 89, +203,209, 13,179,229, 55,240, 18,206, 32,206,221,219,229,185,132,132, 73, 97,243,135,208,219,114,132,210,211,169,226,108,224,254, + 62,118,176,172, 91,218, 64,104, 97, 47,150,226, 9, 82,119, 38,232, 71, 52, 88,205,244,216,216,204, 48, 5,219, 65,114, 35,212, + 92, 72, 74, 29,192, 11, 26,201, 62,246,187, 22,204,164,110,192,236,210,240, 55,245,214,146, 88, 18,145, 0,170,218,142,194, 8, +118,236,231, 43, 87, 61,207, 3,148,123,249,236,197,141,223,126, 13,194, 46,181,172,210, 80, 4, 17,106,154, 68, 55,134,165,208, +191,116,249,242,223, 47, 95, 77,255,117,199, 45,110, 27,135,165,223,187,167, 82,169,232, 8,181,210,153,135, 51,247,206, 95,184, +136,213,242,253,137,239,142, 28, 58, 60, 59,251,112,250,222,221, 20,241,120, 96, 61, 15,186,145,232, 83,129, 7,107, 73, 24,236, +195,185, 87,151, 64, 5, 37,217,177,243,100,245, 9,197, 73,125, 48, 86,189, 6,244,160,123, 40, 82, 7,120, 18,118, 5,194,148, + 0, 94,157, 59,204,113,120,229, 56,191,175, 52,245,228,195, 35,124,154, 91,181,104,220, 12, 38,222,205,184,115, 31, 95, 33,176, + 65,164,133,136,146, 69, 21,116,174, 7, 38,221, 77,110,166,232,181,215,224,107, 89, 76, 99,147,133,212,133,174,152, 99, 59,198, +215,154, 43, 88,231,166,110, 30,174, 30,121, 52, 63, 59, 94,154,104,116, 60, 88,118, 34,216, 79,217, 97, 47,164,124,186, 91,110, +116,106, 89,219,201,217,185,122,187, 62, 53, 49,133,243, 54,191, 52, 71, 73, 57,210, 73, 81,203,219,203,237,118,187,238,123,197, +156,123, 96,108,242,233,187,231,110, 58, 31,246,122,205,205,198, 70,176, 33, 88,247, 10,110, 0, 27, 91, 41,211, 73, 59, 8,245, + 86, 26, 31, 96, 53,220,172,155, 18,136,219,116, 57,181,120, 96,119,245,237,242,107,174,115,170, 64, 72, 19,165,138, 97, 26,239, +107,139, 0,129,134,110,192, 43,220,126,114,155,122, 25, 5, 46, 49,133,111,147,187,247,181,130,102,173,179,142,237, 11, 78,209, +177,114, 35, 25,103,102,254, 62,206,117,218,206, 32, 0,133, 13,194,209, 17,137, 63,172,118,202,194,205,196,212, 79,132, 49,251, +220,143,129,223,117,114,249,213,198, 50,143, 74,170,163,133,210, 38, 23,129,137,152, 72, 37,242, 25,172, 20,199,206,198, 34,208, + 13,237,171, 65,234,212,197,227,138, 30, 40,141,166,210, 13,104, 98, 66,254,245, 7, 10,145, 57, 2, 87,244, 67, 98,193, 27,144, +188, 41,208, 76,211,125,236,149,173,116,193, 15, 26,176, 97,147, 5,255,197,250,235, 86, 72,141, 29, 61,238,159, 97,221, 31, 24, + 21,146, 69,134,153,198, 21,205,167,205, 74,126,196,205,228, 12, 37, 58,186,255,244,159,143,131,115,211, 63,137, 7,194,251,253, +214,183,215,206,140,186,163,103,191, 62, 17, 40, 81, 39,240,117,217,244, 69,237,102,250,132, 83,250,241,254, 31,239, 86,151, 22, +230, 22,111,253, 48,115,242,230, 55,226,172, 24,251,165,154,217, 86,188,126,232,244, 98, 88,147,172,182, 56, 94,219, 78,119,252, + 14,124,137,105,217,190,223,142, 72,207,154, 91,196, 41,215, 68, 44, 88,164,109, 77,160, 77,181,205,108, 20, 17,193, 64,221,175, + 99,151,247,238,170,190, 89,254,135,209, 27,213,216,107,157,218,241,234,177,149,214,202,194,218,123, 89, 82,102,177,169,152,109, +177,198,215,168,151, 20, 6,255,141,157, 69, 92, 45, 87, 23,188, 5, 73, 86,136,247,129,238,129,214,241, 19,212,116,168,153, 27, +228, 15, 4,243, 73,200,126,188, 4, 28, 83, 62, 96, 64,141,196, 0,151,219, 29,217,236, 20, 75, 34,136, 84,194,243,147, 24, 77, + 77,147,125,134, 82, 70,119,248, 13,204,254, 74,163, 58, 44, 69, 0,244, 72,154, 82, 49,141,167,201,183, 34, 73, 30, 28,179,186, +115, 44,220,108,193,239,110,144,102, 36,253, 47,134,161,201,144,173, 65,211, 62, 9,192,216,217,244,182, 81, 69, 97,248,206,167, +103,156,169,147,184, 77, 28, 28, 98,212,134, 54,226, 67, 66, 8, 22, 8,169, 2,177, 40, 59,186, 64,236,224, 7, 32, 36, 88, 20, + 33,164,178, 65,236, 16,127,162, 66, 72,149, 42, 22, 93,192,158, 77,105, 32, 11, 48, 77, 26, 53, 36, 17,109, 10,118, 60,246,216, + 99,143,103, 60,115,231, 14,231,189,119,220, 45,120,107,107, 50,190,190, 57,243,158,123,206,121, 94,179, 12,162,172, 28, 82,253, + 63,193,253,201,187,121,201, 81,103,218, 92,101,235,243, 55, 11,246, 31,175, 57,186,144, 34,187,124,224,204, 49,244, 48,210, 5, + 49,220,200, 68,162, 14,139, 72,139,209,239, 74,186,179, 36,142, 49,221, 1,129, 54, 86, 17, 1,115,234,112,248, 68, 13, 29,125, +249, 40,118, 22,202,246,112, 24, 13, 84, 54,160,156,239, 28,203,253,228,234, 71, 95,127,255, 13,229,200, 6,134, 75,153, 44, 95, +228,115,238,169,152, 70, 3, 38,211,167,238,240,113, 47,236, 74, 47, 68,149, 0,224,147, 80,181,146,127, 9, 46, 63, 58,118,172, +223,118, 7,207,111,174,104, 22,133, 98, 33,237,238,240,124,134, 18, 44,171,203,154,200,248, 40,206,203,191,207, 74, 30, 50,154, + 73, 20, 25, 18,231,251,246, 20,254,222, 28,195,205,134,144,159,210,112, 82,144, 3,216,240,207,105,176,178,188,148,198,252,179, +107,159, 15,195, 49,226,160, 94,128, 34, 96,144,122, 50,228,208,162, 36, 5,145, 74,155,241,126, 47, 8,250,254,175, 59,219, 40, + 75,192, 23, 92, 56, 21,231,169,181,198,250, 70,171,253,199,189,170,109, 93,218,108, 94,255,242, 11,102, 54,222,120,243,242,195, +143,143, 79, 3,159,110, 33,154,230,202, 26,216,160, 48,138, 51,117,116,245, 98, 95,193,128,211, 64,233, 24, 30,112, 69,156, 98, +174,181, 98, 51,215,129,159,201, 12,185, 58,110,149, 11,212,144, 73, 17,225,126, 80, 59,129, 76, 73,120, 49,202,163,253,206,239, +244,227, 85,156, 74,156,228,207,174,109, 29,119,143,162, 36,162, 64,150,194, 73,142,147, 96, 87,182, 5, 46,197, 78,105,242, 16, + 78,134,186,110, 14, 38, 62,253,179,144, 40, 30,197, 1, 45,191, 99,131,127, 54,227,232, 2, 68,253, 95,136, 15,222,122,255,246, +221,219,171,245,213,163,222,193, 18, 12, 72,217, 89,239, 92,119,216,121,247,245,247,190,251,233, 91, 27,213, 93, 65,178, 72,135, +109,155,231,185,222, 30, 16, 5,156,180,115, 60,155,134,209,104,154,196,207,181, 46,237, 28, 76, 78,252, 19, 18,116,245, 90,189, +253,232, 94,163,214,232,133,125,207, 94,136,129, 53, 6,171,143, 36,246,139,173, 23,238, 63,218, 51,117,131, 46,178, 96, 57, 20, +247, 73,113, 83,234, 70,226, 32, 7,212,176, 72, 57, 55, 45,139,199,201, 70,163,213, 27,251, 36,216,215,235, 27,244,200, 49, 77, +171,125,216, 94,116,207,164,148,242, 23, 25, 45,194,185,165,181, 97, 20,248,129, 79, 59,194,115,151, 47,172, 62,189,115,216,166, + 61,252,246,171, 87,194,100,124,119,119,187, 10,218, 26,248, 60, 89,150,153,210,222,197,115,206,144,250, 59,244,143,243,104,228, + 85, 23,109, 86, 12, 35, 90,146,184, 89, 95,247,199,125,206,147, 78,208,145,253,186,133,164, 54, 21,182,229,164, 25,101, 39,245, + 48, 74,228, 17,132, 44,139,211, 54,119, 76,138, 57,242, 8, 94,201,110, 6,230, 19,227, 70, 46,193,133, 79, 90, 15, 52,125,198, + 39,163, 65,144, 10,253,252,130,231,103,167,164, 78,103, 92,157,201,148,120, 23,161,212,109,105,158, 76, 91,162, 8,147,212,182, +128,191,255,121,255,135, 90,149,221,122,249, 43,246, 10,187,241,225,143,127,101,131,107, 91, 87,251,233, 48,205, 85,159,207,188, +103, 91, 19, 3, 62,122,103,227,165, 79,187,219,236,142,184,114,249, 53,118,147,177, 30,123,166,186,185,159, 62,140,132,164,251, + 73,206, 37, 28,222,215,206,239, 30,182, 41,169,106,157,109,238,197, 19, 37,220, 53,133,129, 85,131,184,120,102,104,117,216,230, +241,229,218,202,131,238,159,205,229,245,147,193,227,227,206, 17,131, 37,158, 73,154,159,150,157,214,255,151,131, 29,133,205, 46, + 91, 0,153,210,218,204,177,208,231,158, 37, 51, 53,234, 37, 35,152,234,250,192, 87,190,255,247,190, 91,129, 31, 61, 32, 72,114, +126,116,171,121,241,206,131, 62, 45,229,162, 67, 91, 37, 22,101,111,139,156, 10,145, 87,231, 96, 65,196,116, 9,211, 64,232,238, +133, 61,153, 86, 2, 0, 9, 70,139,196,165,213,113,226,148,213, 92,143,146,140, 60,203,149, 57,246,188,198, 9, 29,170,218,211, + 85,160, 91,116,107,179, 44,157,192, 83,123,110,247,173, 56, 49,154, 90,129, 34, 64,221, 17, 58, 91,200, 97, 89, 21, 89, 73,167, +146, 28, 57, 29, 35, 89,252, 87, 0,194,174,100,183,105, 40,138,218, 73,156,177,169, 29,211, 38,105,194,208,130, 42, 90, 21,161, + 50,131, 4,180, 66, 72,128, 96,129,196, 18,196, 30,137, 15, 96,203,111, 32, 22,108,217,178, 5, 65, 7, 4, 75,196, 80, 21,181, +168,133, 64, 65, 77,227, 64,234,216,177,159, 39,238,121,207, 45, 42, 44, 72, 86,137, 34,121,136,223,125,231,158,123,239, 57, 49, +255, 30,238,228, 78,162, 29, 82, 4,255,127,109,233, 67,203,210, 95, 84,253, 63,175,109, 47, 94,121, 71, 38,176, 93,123,141,143, +168, 23,244, 30,179, 9,230, 96, 38, 13,160,129, 81, 74, 46, 12,149, 80,227,230, 30,137, 81, 76,204,227, 80, 62,215,251,141,120, +159, 10, 87, 2, 8,221,192,141,239, 88,188, 79, 97, 36,108,126,225, 37, 52, 31,185,135, 39,125, 67, 17, 80,139, 43,171, 9, 31, + 93,213, 82,124,151, 32, 67, 33,197, 34,118,162,196,145,128, 77, 98, 16,210,162,118,246, 14,140, 96, 78, 10,238,123,129,107,251, +147,187, 7, 84, 8, 49, 3, 5, 19, 66,244,120,195, 38,253,113, 92,201, 52, 65, 31, 25,157, 10, 67,208,100,208, 64,139, 24, 23, +179, 23, 91,114,114, 75,162, 23, 58, 40,190,204, 96, 30, 14,162,128,223,166, 24, 24, 76, 79,157,125, 62,243,130, 48, 19,220,107, +121, 66, 10,253, 97, 39,240,220,208,131,154, 11, 88, 65,215,245, 26, 43,171, 70,171,213,179,172, 98, 95, 33, 79,201, 72, 49,155, +203, 38,105,205,247,172,245,190,188,148,201,227,244,247,215,107,253,125,201, 87,115, 51,115,243,175, 29, 55,242, 61, 88, 12, 71, + 60,231,160,235,204,161, 47, 30, 44, 71, 22,130, 54,152, 89,205, 40,144,117,164, 67,120,156,108,227,110,147,160, 98,124, 31,164, +174,203,128,220, 33, 41,136,133,198,149,232,133, 67, 36,158,250, 80, 9, 80,164, 65,211,188,231,180,209, 34, 70,231, 26, 20, 48, +143,163, 18,114,167,184, 93, 41,213, 40, 42, 25,221,166, 86,216,101,108, 54,211,233, 76, 69, 27,202,166,178,110,192,134,244,202, +225,225,201, 31,237,239,220, 87, 29, 91,236,240,224, 8,133,182,225,234,190, 15,171,239,191, 52, 63,123, 48,226, 81,134,203, 35, +109,179, 57,185,255, 8,133,239,217,133, 89,198, 28,173,160, 31, 29, 61,121,235,194,205,119,171,239,104,151,252,214,250, 26, 4, +129,218,167, 19,140, 74,203, 10,193,156,159,166,177,216, 88,212,139,186,227, 90, 4,156, 45, 7, 21,215,171, 39, 47, 27,157,142, + 86,212,232,102,169,249,254, 3,181,209, 95, 38,228, 9,233, 73, 24, 44,150, 79,143,157,250, 97,172,105,165,193,164,162,172,124, + 91, 10, 16,179, 82,245, 82,237,250,233, 43,133, 61,213, 82,148,249,178,209,160,199, 9,118,122,152, 56,117,233,196,154,157,214, +153,241, 83,211,147, 83,157,192,111,110,124,175,106,229, 65,181, 76, 32,116,234,246, 13, 99,105,109,125,115, 35, 1,215, 30,199, +178,205,143,141, 37, 90,124, 67,122,157, 18,199,209,161, 3,150,107,151,139, 3, 20, 85, 91,157, 86, 73,213,225, 41,145, 76,246, +220, 94,165, 84, 69, 51,156,162, 80,246,173, 21, 75,109,179, 13,139,227,192,167,212,109,188, 62,222, 54, 13, 94,169,166, 60,178, + 3,245,201,132, 60,166,228,118, 95,172,193,237, 26,145, 93, 48,153, 28,199, 8,112, 23,134,201,184,184,138,194, 37,225,113,217, + 75,119,163,241,140,146,171, 42, 82, 49,213, 90, 54,215, 54,123,104,199,246, 68, 99, 1,226, 67,192,229, 74,249, 68,139,208, 23, +151,161,246,149, 18, 83, 29,148,195,200,146,157,126,211,124,252,228,193,219,103,199,170,135,198,118,213, 59,140, 59,138, 72,194, +184, 27,254, 4, 92,169, 67, 30, 83,247, 60, 90,126,122,109,223,241,250,165,131,247, 31,222,191, 91,185,247,242,215,236, 34,251, +116,103, 98,154, 50, 15,211,233,201,220,241,103,227,231, 58, 56,107, 57, 68,207, 21, 74, 8, 17,167,153, 66,186,228,138, 86,165, +184, 38,156,128,186,204, 54, 29,211,232,182,233, 55, 22,131,108,131,136, 12,253, 5, 21,249, 31,224,155, 68,185, 90, 46,149,177, +152, 29,138,249, 13, 41,228, 34,254, 4,255, 61,174,109,215,149,226, 43, 18, 12,178, 8,242, 0,215, 39, 70, 33, 95,193,113, 53, +136,172,134,177,214,159, 87, 9,133,160, 14, 47, 11,243, 89, 40,231, 87,245,186,105,117, 68,248, 59, 55,113,254,115,115, 69,104, + 96,110, 53, 55,134, 81, 60, 16,142, 3,184,112, 30,245, 44,214, 11,121, 11,201, 31, 32, 45,197,254,204,209,214, 88, 38,189,109, +207, 70, 95, 22, 36, 75,165, 96,219, 91,101, 7, 27,194,119,231, 32, 18, 70,221,124,173,160, 21, 5,234,240,240,158, 80,126, 11, + 64,214,181,244,180,113,133,209,121,120, 30,158, 49,198,143,196,152, 96, 19, 37,149, 80,149,162, 74, 9,155, 54, 82,212, 74,237, +162,139, 74, 77, 55,225, 23,116,209,174,170, 36,127, 32, 82,255, 75,214, 89,228, 15, 84, 40, 45, 13,139, 62, 18, 2, 68, 96, 97, +156, 98,198, 51,120,236, 25,207,219,190,253,190,239,142, 41, 74, 88,129, 1,195,204,189,115,238,249, 94,231,228,248,158, 9,255, +139,204,176, 75,244, 93, 21,180,233,188, 57,146,125,144,159,121, 15,205,217,101,192,254,224,103, 47,230,176,214,150,111,217,152, +112, 23,196,247,223, 70,156, 7, 19, 51, 88,182,130,168, 36, 89, 50,203, 83, 40,136,224,243, 68, 16,239,206, 68, 22, 15,129,121, +130, 37,108,150,139,140,113,117, 25, 42,141, 21,104,239, 33,224, 50,114, 76,199,187, 54, 35, 49,117, 49,165,233, 50, 84, 7,203, +166, 97,228,207,230,147, 3,236,210,149,115,194,146,151,158, 5, 86, 46,214, 98, 52,130,145,116,205,116,252,129, 34,225,163, 83, + 54,234,195, 96,180,219,179,135, 94,106, 10,133,138,170,220,172,150, 13, 89,169, 22, 84, 83, 34, 57, 47,226, 63, 41, 33, 53, 60, + 69, 50,181,125, 25,138,140,178, 95,120,168, 19,176,242, 63, 6, 65, 28, 26,126, 10,170, 44, 42,228,214, 81, 4,238, 85,148, 0, +179,122,157,142,227,156,211,196, 4,124,201,146,104, 10, 97,117,152,100, 33,252, 67, 81, 58,137, 99,207,207,210,108,122,102,185, +189, 83, 11, 14, 18,160,255, 81, 12, 7, 0,162,191,200, 10,104,122,195, 93,115,131,104,103,251,197,243,231,207,182,119,182, 53, +149,149, 12, 18, 44,160,239,145,174, 27, 35,105, 26, 62, 71,193, 20, 69,230, 18,252,216,134, 10,219, 0, 39,208,176, 77, 8, 66, + 19,132,123,174, 56, 63, 67,153,165,162,138, 94,162,101, 13, 53, 50, 13, 77, 42,169,232,106, 2,155, 42,244, 81, 54,110,181,126, + 3,168,119,173,212, 20,177,181, 46, 27, 5, 46, 54,183,208, 18, 69,105, 4,161,244, 56, 64,189,245, 73,232, 51, 50,187,113,195, +145,161,232,214,208,178,125,231, 90,101,121,132, 6,196, 50, 68,102,231,147,161, 23,184,217,148, 29, 15, 58,247,239,126,135, 3, +232, 51,230,120,214, 71,205,143, 59,253,206,223,221,191,146, 89, 92, 64, 81, 76,245,176,255,246,247,253,237, 36,137,155,213,166, + 82, 80,208, 80,201, 88, 56, 58, 61, 4,138,208,174, 95,255,241,254, 79, 91,255,252,138,242, 35,162,164, 23,138,156, 19,238, 30, +191,129, 79,134,254, 0, 46, 60, 78,195,129,219,175,151,113,238, 20, 96, 0,248,120,231,244, 40,140, 2, 93, 86, 53,248, 21, 89, + 7,150,208,190,178, 2,111,190,245,106,235,180,123, 12,236,222, 26, 89,107,173,181,205,123,223, 31,252,251,182,177,216,136,146, +176,178, 80,251,227, 96,199,118, 44,107,208, 91,169,183,186,118,239,211, 59,159,247,207,222,233,118,182,247,110, 47, 33,102, 12, + 75,118,125,105, 21,192,113, 28,249, 95,173,127,241,186,187, 11,247,216,245, 93, 93, 51,236,177,221, 88,188, 26,101, 73,148,198, + 75,139, 75, 16,242, 91,227, 51,120,125,243,219, 31, 86, 74,181,151, 7, 59,181,133,250,227, 7,143,126,123,245, 2, 64,157,220, +230,162, 5,116,146,242,209,180, 5, 2, 46, 73,248,204, 48, 43,223, 52,243,204, 43,224,187, 52, 47,215, 49,178,230, 32,154, 36, +210,168, 90, 74,210, 73,232, 57, 31, 42, 77,253,220, 99, 71,187,238,137, 61,137, 81, 38,144,140, 55, 25,165, 26,132, 92, 82, 88, +160,246,115, 68,118,146,194,150,209,117, 18, 29,239,100, 5, 69,185,245, 76, 73, 55,218,149,219,181, 70,150,106,195, 56,185, 82, +185, 26,199, 17, 58,149,147,153, 55, 86,178, 4,177,170, 27, 79,247, 95, 54,202,205, 47, 31,126,253,228,151, 39,155,181,159, 79, +166,251, 91,193,159, 15,174,109,244,209,203,129,186,185,165, 60, 9,139,103, 17,105,189, 84, 75,213, 69,179,226, 7, 62,224, 20, +112, 5,216,187, 55,151,111,156,185, 14, 39,173,102,177,164,107,154, 31, 79, 56, 29, 67,219,241, 4,107,173,176,226,112, 13,227, +208,243,226, 73,171,222, 50,138,102,144,132,183, 90,159,224,196,220, 8,237, 65, 82,150,225,252,163,196,157, 77,105,243,139,185, +221, 61,220,149,174,221, 69,157, 21,186, 85,148,195,193,110,189,152,250,109, 40, 11,204, 5, 23,167,228,233, 10, 47,162, 49,136, +227, 13,195, 36,164,147, 12, 7, 4,219,245, 54, 55,180,153,241,210, 34, 73,185,145,203,173,192, 61,154,248,135,196,155, 10,105, +101, 74, 90,201, 44,154,112,168,231,174,215,249, 24, 62,239, 41,167,230, 31, 73,186,192, 98, 81,200, 43,206,226, 69,233, 18,159, +105,192, 16,117,125,117,221,241,156,255, 4, 96,235, 74,122,155, 6,131,168,237,216,159,215,216, 73,147, 46, 20,232, 18,132,160, + 5, 10, 42,229, 82,196, 5,161,170,112,224,140,184,112, 64, 66, 66, 28,248, 13,253, 3,252, 20, 36,238,220,170,170, 72, 28, 64, + 32, 68, 55,209, 61, 73,219,184,110, 22, 59,137,107,199,204,140,237,138,138,170,149,122, 73, 29,111,223,155,153,111,222,155,151, +224,123,152,146, 32,207, 32,142,212,180,220,133,224,126, 33,196,195,153, 13,105, 3,238, 41,142, 88,147, 4,153,166,146,253,195, +146, 73,209, 28, 14, 7,248, 56, 96, 12,121,126, 43,190,236,255, 50,253, 52,210, 37,212, 76,238,124,119,182,103,202,150, 79,185, + 54,154,179,164, 21, 21,250,116,139, 12, 59, 69,241, 61, 82,140,130,129,134, 18, 35,253, 37,199,179, 19,198, 21, 10, 54,113,230, + 13,100,142,232,165,217,105, 32, 81, 22,192,139,104,254, 89,213,244,147, 6, 58,127,174,133,192, 39,178, 86, 26,178, 42,144,224, + 24,103,227,248, 97, 23,135,181, 70,252,196,240, 76,217, 57, 42, 55,220,173, 35,231,119,165,185,111, 55, 2,128,137, 46,156, 99, +104, 50,213, 18,133, 75,186, 50,156, 85,242,162, 84, 68,215, 69,129, 86, 21,199,144,182, 1,223,223,203,224,150, 11,142, 61,128, + 19, 87, 25,196, 15, 78,197,221,215, 8, 55,190, 1,226, 37,225,164,126, 28,203,216,100, 0,125, 37,202,106, 56,166, 91,151,164, +172, 34,105,114,198, 84,100,156, 40,169, 51, 75,103,125, 38,206,150,209,161,176,135,255,141, 69,183, 52, 61,137, 36,175, 28,186, +232,202,100, 84, 8, 63,188,136,172,231,128, 58,108, 1,170, 65, 68, 26,207, 1,208,172, 40,188,174, 73,140, 92,168,176,214, 67, +165, 37, 39, 43,130,174,194, 47,118,213, 52, 85,176, 44, 33,111, 72,154,158, 49,116, 81, 87, 49, 76,244, 80,187,223,243, 59, 92, +187,221,139,124, 46,104,158,198, 90, 57,175,141,226, 67,183,211, 52,181,156,161,102, 59,190, 43, 36,172, 7, 64, 7,181,234,148, +251,205,129,131,227,114,108,155, 25,187,134,193,159,201,145, 41, 38, 72,187,246,166,194, 20,148, 53, 68,209,219,167,239,150, 87, +150,188, 83, 87, 99,218,198,222, 58, 36, 65, 0,172, 17,146, 61,170,112, 76,192,187,209, 98,201,110,214, 60, 31,103,254,193,103, + 0, 64, 1, 37,135, 11,151,239,142,223,134,165,222,112,155,221,160, 91,117, 42,159,150, 62,206, 77,207,111, 29,110,205,222,152, +221,174,161, 39,131,169,224, 45, 68,101, 19,185,167, 66,140, 81, 24, 90, 5, 92, 27, 28,127,243,244,245,202,206,234,244,245, 25, +212,100, 48, 25, 10,113,248, 10,200,148,251,205,130,219,169,195,185,193, 97,171,245, 10,188,108,251,118,121,239,112, 23,210,246, +234,201, 1, 36,122, 80,222,221, 47,221,131,203,201, 25,214, 9,218, 57, 53,214,214,126, 62,123, 48,183,188,250, 21, 2,244,196, +200,173,177,226, 24,100,157,123,118,197, 67,237, 76,192, 68,209,113,235, 57, 61, 63, 90,188, 82,204, 21,202,118, 25,206,217, 39, + 38, 88,203,109,182,131, 14,148,104,176, 98, 23,191,125,134, 80, 4,183,175,213,105,125,255,243, 3, 5,143,240, 90, 6,193,228, +200,205,221,218, 14,188,198, 67,249,171,221,160,142,147, 63,140, 1,235,113,145,147, 80,152, 26, 91, 46,165, 27,168, 4,241, 84, +174,103, 8,195, 48,153,133,128,205,159,174, 58, 91,191,156,237, 13,199,169,183,131, 0,163, 0,181,112, 81,180, 71,224, 76,156, +116,120,121, 24, 34,187,168, 49,201, 96,162, 33,203, 58, 99,104, 5, 0,197, 33,249, 19, 80, 48, 9, 91, 92, 77,224,157,169,226, +148,213, 55,126, 96,111, 35, 15, 22, 87, 90, 60, 56,157, 31, 84,173,165,237, 53,143,231, 95,190,127,177,176,240,225,161,254,188, +206,111, 46,186, 95, 94,149, 30,181,195, 22,159,142, 44,166,140,181,151, 51,114, 18,206, 10, 69,185, 41, 92,117, 64,133, 45, 60, + 74, 67, 49,161,120,168,181,106, 17,186,170,134,249,108, 31, 60, 11, 31,137,218,148,137, 83, 78, 8,235,245,216, 61,134,200, 23, + 34,133, 45,192, 14, 13,238,117,120,229,147,253, 90,179,134,215,134,222, 18, 89,175,219, 78,236,142,184, 88,195,213,163, 45, 18, + 33,113, 44, 20, 98, 87, 20,100,109, 29, 53, 15,249, 40, 19,111, 28, 36,221,106,186,179, 97, 76,106, 36,202, 56,241,247,176,125, + 69, 78,216,156,215,110,145,129,101,186,255, 28, 79, 29, 75,134,160,224,183, 20,180, 62,108,237,242,103,143, 7, 18,237, 16, 18, +128,128, 22, 66, 47, 29, 77,169, 49, 3, 74,160, 39,119,230,215, 43,107, 52, 15, 56,109,188,114,137, 61,211, 25,186, 35, 39, 18, + 89,249,254,190,189, 7, 81,225,175, 0,116, 93, 75, 79, 19, 81, 20,158,123,239, 48,211,199, 48,125, 8, 8, 72,173, 98, 8,104, + 32, 33, 32,110,116,227,198,181,123, 87,174, 76,252, 11,110, 93,232,206, 95, 97,226,206,196,141, 27, 13,108, 52, 33, 46, 80, 9, + 81, 32, 64,171, 34,180,149,215,132, 62,102,202, 92,207,119,110,139,175,152,176,108,232,237, 60,238, 61,231,124, 47,224,171, 16, +124, 90,166,175,249, 85,254,159,252,185,119,159,238,119,250, 63,195, 25,253,207, 88, 70,252, 13,198,158,158,201,127,152, 28,252, +222, 4,200,223,112, 87,249,159, 89, 80,119,145, 82,118, 1, 3,217, 5, 0,164,185,108, 24,132,227, 7,187, 54,109,137, 8,201, + 85, 92,182,107,190, 12,172, 93,134,220,198,208,247, 48,187, 84,142,151,204,214,168, 68, 2, 91,191,201, 0,218, 47,189,149, 50, +167,165,148, 57,184,214, 1, 45,161, 23,169, 45,162,180,157, 72,185,233,180,155,166,135,146, 54,108, 71,185, 67,153,194,183, 96, +131,158, 99,109, 64, 14,142, 76,160,231,154, 42,164,201,193,171,149, 96,221,182,163,124, 42,133, 13, 93,232, 84, 82,185,240, 28, + 70, 89, 20,208,105, 0, 39,123,224, 50, 17,117,112,128,179,216, 41,131, 93,186, 29,102,155, 43,165,194,118,204,254,165, 18,107, +112,128,117, 42,164,203, 50,208,194, 53, 79,108,181,205,106,169,190, 86,220, 77,119,156,137,164, 86,182,100, 15, 58,193, 58, 92, +180, 49,136, 6,228,249,140,113,214,134,149,181,102,198,175,230,228,107, 7, 70, 58,224, 70, 2, 34,102,162, 36,155, 45,187,156, +199,204, 92,221,248,184,110,213, 57,243,156, 13,160, 69,196,225,199,142,176, 28,173,131, 61,213,140,173,125,204, 31,233, 28,242, +169, 60,143,145,109,223,128, 32, 25,139,232,105,159,180, 4, 91, 5, 36, 28,119, 48, 59,252,181, 86, 42,244, 21,171, 65,205, 98, + 50,102,194,237, 13,195,122,214,203,209, 25,176, 31, 84,206,248,253,212, 4,196, 28, 70,220, 3, 70,179, 26,201,157, 75,185,169, +114,181,212,182,244,185,220,240,250,246, 42,173, 97,116,104, 60,140, 26, 84, 2,211,135,189, 68,186,222,170, 23, 6, 46,110,237, + 66,214, 63, 85,156, 10, 26, 65,191,223,119,253,242,220,211,249,103,126,202,255, 82, 45, 83,149, 68, 47, 52, 93,139,179,217, 1, +234,147, 34, 29, 31, 30,237,161, 28, 59,137,232, 38,222,189,125,111,254,237, 75,165, 5,198,238, 82, 86, 14,118,115,201, 76, 38, +237,239,254,248, 78,119, 99,246,210, 52,109,103,158,155, 90, 92,123, 55,218, 95,220,222,219,241,147, 30, 93,236, 91, 51, 55,223, +172, 44,110,236,108,120,105, 56,139,113,236, 50, 35,101, 40, 11, 84, 95,166,207,177,221, 82,117,131,238,218,220,216,244, 74,105, + 53,108,211,147,211,147,243, 50,249,204,192,114,233,195,204,232,236,251,210,199, 27, 87,174,189, 90, 90,224, 60, 57,155,170,235, + 36, 71,114,211,205,184,112,182,184,185,187, 53, 49, 50,177,182,253,217,150, 46, 43,141, 32, 6,246,144, 24, 23, 59, 8,215,147, +121, 63,123,208,170,221,201, 95, 56,255,112,204,242, 4,252,103,142, 27, 86,196, 16,107, 35,130,147, 92, 35,196,223,113,104,213, +163,184, 25, 66, 81,210, 66, 16,205,243,165,114, 37, 0, 88,100, 92,134, 36,151,151, 74,128,112,201, 89, 48, 28,158, 11,123, 65, + 16, 13, 4, 71, 7,131, 57,102,162,163,109, 97,140,192,128, 6, 65, 9, 69,173, 99, 43, 47,135,235,193,249,253,184,157,224, 52, + 98,184,237,193,161, 79,140,247, 22, 30, 45,190,216,172,197, 75,205,133, 65, 49,118,127,228, 97,221,253,244,120,251,201,235, 91, + 15,106,141,170,209,177,155,220,154,144,161,124,102,103,226,109,240, 18,189,213,160,106,152,240,212,210,177,142, 16,179, 15, 72, +133,192,121, 59, 49,173, 6,147, 81,116,108, 24,135, 22, 59,196,242,248,155,173, 27,185, 23, 97, 98, 53, 51,172, 99,221,193,198, + 58,130,169, 86,212,154, 44, 78, 46,151, 87,168, 63, 48, 72, 40,190, 3,255,196,202,184,254, 17,146, 52, 84, 11, 26, 73,214, 6, +197, 72, 69, 51, 95,101,198, 41,124, 66,152, 49, 10,179, 90, 68,215,176,214,182, 56, 93,180,147,163, 98, 92,136, 59,165,163,150, +167, 33,124, 38, 99,139, 71,250,130,127, 26,107,244,121, 95,115,132,123,216, 60,160,178, 12,144,134, 98,120,143,107, 91, 58,159, +142, 26, 32,143,165, 33,235,179, 0, 32,153, 97,147,212, 84,254,133, 81,243,167, 0,108, 93,203, 78, 83, 81, 20,237,189,167,247, +121,218,222, 2, 82, 68,209, 0, 70, 35,241, 17, 13, 70,141, 3, 67,100,224, 15, 56, 48,198,168, 3,167,126,128,113,162,191,161, + 31,132,134, 8, 19, 99,128,138, 65,229,145, 82,160,175,251,126,186,247, 62, 7,170, 9, 73, 7, 29,180,183,205,189,231,172,179, +246,107, 45,201,223, 19,201,148, 79, 1,119, 67, 53,176,180, 88, 12, 63, 96,226,218,194,187,114,245,236, 28, 28,161,202, 16,172, +255,123,157, 90,146, 85, 37, 67, 7,214,108,230,255,215,110,149,225, 9, 81,148, 73, 50,183, 56,173, 76, 43,206,169,178, 42,115, +215, 39, 10,245,202, 73, 60, 35, 50, 95, 84, 65, 7, 54, 1, 97, 93, 4,193, 90, 46,227, 33, 49,174, 43,174, 12, 75, 20,200,151, + 31,121, 89, 30,195, 9, 9, 4, 51,136,124, 49, 31, 7, 52, 80,136,229,163, 34, 2,198, 59,154, 99,141,160,177,159, 82,122,251, +228, 93,115,103,147,164, 17, 82, 93,131,155,163, 5,112, 5,224,170,113, 96,178, 26,240, 44, 49,155,165,160,201, 41, 92, 68, 3, +158,220,241, 14,142,220,110, 47, 8,118,187,238,161,151,182, 93,246,187, 51,248,213,245, 54, 90,222,110, 79,251,211,237,187, 17, + 32, 99,133,229,220,235,135, 90, 86, 26, 97, 90,195,210, 1,222, 42, 69,137, 3,215,142, 83,141,178,128, 22, 67, 59, 67, 52, 42, + 87,201,214, 33,197,180, 40,224, 93,181,162, 0,241, 71,155, 64,106, 22, 67,121, 19, 61,167,100,122,161,209, 76,136,169, 50,216, + 34, 9,236,228, 8, 29, 9,177, 77,156, 28,251,200,133, 23,139,171, 73, 86,194,115, 9,213,252,101,111, 85,156,146,206, 76,137, + 69, 8,229,169,239,151, 34, 47, 15,163, 60, 8,243, 48, 68,151, 65, 44, 98, 99, 30, 12, 27, 70, 1, 89,224,135,108, 85,153,228, +198,160,155,117, 3,181, 31, 28, 97, 79, 78,138,206, 21, 40, 32, 74, 61,181, 42, 43, 23, 52, 76, 0,209, 77,197,170,225,200, 70, +154,132, 73,236,216,163,135,131,182,208,202, 51, 53, 14,167,176, 99,215, 72,187, 2,248,184, 97,105, 86,213,114, 44,211,198, 39, +149,166,207, 22,158,114,157,127,217, 88,190, 63,247, 0, 48, 17,142, 44, 55,236,155,134, 13,251, 31,184, 24, 61,205,236,249,139, +151, 95, 87,150,209,165, 1,195,165, 20,208,217,208,245,239,219,223,150,214, 62,147, 56,120, 8,123, 19, 72, 39,196,112,126,232, + 98,241,179,127,160,149,141, 65,208,131,231, 56,211,152, 14,227,112,107,231,199, 68,117,124,171,181, 5, 81,160,134, 45, 42, 10, +132,255,113, 28, 0,154, 24, 58, 0, 22, 3,106,143,201, 37,133, 77, 79, 92,132,143, 1, 11,115, 3,183, 9,223, 26,153,216,239, +183,227, 60,165, 64,187, 2,251, 4, 32,163,213,221, 55, 12, 8,223,204,187, 87,238,172,111,175,195,234, 58, 63, 54, 85,183,157, + 67,172, 39, 23, 97, 18, 0, 55, 92,188,190,176,185,215, 12,163,160,213,217,127,124,123, 17,160, 28,189, 74, 76,126,115,250, 6, +252,127, 88,108,220,228,176,153, 1, 40,225,124, 66, 37,156, 60,133,187, 52,211,152, 73,146, 24, 77, 19, 89,217,225,163,117, 62, + 30,166,238,252,153,121,126, 47, 43, 57,140, 98,183,252,120, 79, 22,242,141,136,233, 8,220, 20, 82,178,177,116,182,182,211,235, + 5,137,172, 62, 34,175,192,117,133,129, 30,195,185, 13, 28,155, 32,135, 44, 93,197,123, 81, 70,133, 96,180, 31,208, 25, 57, 7, + 96, 15, 87,169,172, 72, 39, 37, 74,241,169,137,210,155,180, 27,188,122,217, 13, 58,140, 52,214,133,145, 33,215,141,102,103,239, +103,219,123,243,254,245,199, 15,159,166,204,107,133,214, 95,242, 87, 94, 93,122,152,228,158, 24,113,145, 44, 78,234, 88,145,200, + 9, 10,197, 36,179,231,102,123,254,128,102,203, 11,250,239,136, 67,220,172, 98,110,157,224, 34, 21,185, 12, 1,186, 36, 83, 40, + 0,156,220, 32, 4,165, 70, 62, 88,200,140, 44, 78,177, 83, 47, 77, 33, 68,200,235,118,253,209,173,133,213,205, 85, 69,149,205, +178,199,180,181,240, 34,159,188,134, 72,163, 86, 68,198,196,224,185, 94,137, 73,146, 87,102,240,101,149,163,248, 23, 11, 69, 86, + 64,246,122,160, 77, 80, 13, 47,146,231, 83, 99, 23,188,120, 32,168,175,195, 29,147,153,134,129,221,128, 8,220,118, 21,139,130, +244, 91, 25,182, 48,197, 52, 84,165,202, 51, 66, 25, 6, 99, 98,198,149, 92, 3, 81, 33, 17,144, 10, 45,188,211, 4,173,107,179, +228,175, 0,124, 93,203,106, 19, 81, 24,158,123,230,146, 76,218, 73,164,157,182, 94,104,172, 5, 69,112,227, 66, 80, 65,193,133, +143,160, 75,215,186,114, 39,184,241, 41, 92,248, 10, 46,124, 4, 81,180, 40, 40,138, 84,171,182,222, 82, 91,211,166,211, 92, 38, +115,201,204, 25,255,239,156,164, 6, 65,187,106, 33, 9,105,114,206,119,254,243,255,223,229,160,255,206,228,137,190,243,100,229, +158, 97,135,176,201,122, 60,227, 18,101,250, 33,112,255, 79,199,230, 31,213,247, 65,189,127, 48, 19,158,108,220,203,163, 33, 1, + 30,197, 38,251,225,242, 95, 13, 28,161, 20, 27,207,157,139,137,219,192, 72,168,202, 21, 16, 96, 0,194,117, 25, 35, 75,219,168, + 32,148, 91, 98, 60, 60, 11,211, 30, 75, 51, 7,195,152, 62,214, 36,143,233, 97,128,111,254,174, 64,125, 97, 57,221,211, 17,231, + 4,118, 18,150, 1, 1,135, 12, 84,205,158,172, 62,238,197, 96,125,209,202,167,167,152,154, 41, 73,154,131,179,161,175,169,165, +118,127,135,214,127,138, 72, 76,168,224, 96,126,164,186,200,235, 73,163, 91,215,239,188,124,251,220,198,183,155,100,108,192,152, + 78, 11,228, 72,253,196, 86,103,179, 55, 28,254,234, 15,182,194,110,161, 31,106, 14,246, 90,105,214, 12,227,159,221, 4,226,116, +130, 60, 73, 41,201,178,107,168,117, 83,175, 91,165,186, 89,154,162,223,237, 82,165,164, 76, 57,170,101, 20, 6,109, 98, 65,142, +224,126, 3, 25, 40,108, 76,196, 56,148,184, 15, 26,167, 24, 21, 84,245,219,150,226, 56,116, 45,149, 45, 75, 49,116,201,210, 85, + 27, 77, 33, 68,250, 85, 76,197, 18,138, 82, 42,176,121,150, 56,168, 64,252,152,140,232, 96,136, 89,146,230,125,130,177, 48, 79, + 83, 88, 87, 74,220,230,222,210, 20,171, 36, 83,217, 94, 54,164,163,142,181,222,220,255, 18,244,226, 44,196,101,132,103, 19,170, +176, 13, 64,247, 80, 6,119,136, 14,191,204,247,230,235,110,109, 39,216,102,133, 80,163, 20,136, 35, 80,168, 24,153, 82,249, 22, + 24, 14, 35, 85, 53,174, 93,190,182,178,250, 84,216,144, 5,189, 29,238, 10, 43,211, 71,186,178,182,194,249,156,249, 86,176,153, + 36, 49,149,219,167,142,157,222,237,180, 96, 50, 28,238, 1, 67,242,156,192,221,181,171,113, 58, 56,214,104, 92, 56,123,105,253, +235, 39, 90, 48, 21,179, 74, 27,188, 86,246, 32, 50, 74,224, 92,132,178,151, 14, 15,122,100, 22,207,123,254,126,119,151,144,136, +240,130, 94,135,238, 28,173,110,139,254,247,165,185,198,204,180,191, 60,191,244,109,251,139,174,170, 23, 79, 94, 56,236,205,124, +248,177,102,104,170, 95,245,203,150, 77, 39,183,173, 91,231,207, 93,221,248,182,154, 98, 12,174, 31,173, 31,217,237,180, 97,241, + 24,245, 8,199, 63,110,173,249,211,115,253,168,123,229,204,165,135,207, 30,209,129, 68,133,127,208,223, 67,158, 76, 20, 82,241, + 94,171,212,118,247,219,158,235,253,216,105,210,155,140,134,225, 50,100, 53,155, 2,148,218,189, 64, 36,160,201, 24,249,184,180, +207, 59,112, 66, 63, 94,181,171,220, 87,121, 95,211, 84,215,172, 80, 93,153,231, 81, 60, 12, 44,221, 97,189,237,197,203,179, 82, +221,192, 54, 18, 4, 22,174,115, 31,169,111, 20, 1,160, 88, 49, 90,145, 19, 46,151, 29,251,253,247, 96, 47, 78, 21, 65, 52,230, +179, 80, 29,107, 6, 53, 14,156,161,225, 3,165, 42,114,113,144, 1,164,240, 52,137,178,166,121,150,121,120,122,138, 91,169, 23, + 58, 15, 40, 22, 61, 97,250, 34, 92, 24,102,206, 7,200, 16,215, 10, 52, 91,170,244,212,198,236,194,235,230,198,155,246,230,237, +187, 55,239,223,123,176, 96,158,148,245,238,139,244,221,141,197,243,116,195, 27,183, 47, 20,113,203,103,162, 58,150,216,140, 55, +219, 9, 49,188, 73, 97,135, 38, 84,103, 80,180,248,158, 79, 11,131,167,247,113,176,135, 17, 22,231, 15, 51, 30, 75,204,248,168, + 77, 42, 70,234,243,113,199,155, 11, 71, 11,193,245, 88, 94, 88,238, 65,215, 10,219,240, 48, 13, 95,125,126, 3, 37, 14, 98,155, +242, 92,112, 85, 56,246, 80,209,183, 56,211,248, 25, 52, 37,238, 81, 88,140,161,210, 50,156, 40, 3,119,222,117,170, 9, 55,254, + 29,211,232,255,244, 38,184,235,248,184,129, 66,216,109, 86,232, 70, 66,175,214,234,208, 70,135, 13, 6,227,109,176, 48, 9, 35, +168,165, 32, 76, 33,184, 0,201, 93,226,100,239, 66,246, 42,181, 40,141,124,111,174, 75,187,224,207,132, 85, 22,118,191,138, 52, +178,204, 65,247,157,138, 86,148,249, 24, 9,208,223,191, 5, 32,236, 90,122,154,136,162,240,189,243,106,167,175,161,211,242, 20, + 20, 48, 54, 49, 38,154, 40,129,176,112, 97, 92, 26, 55, 6, 23,198,141,254, 0,119,238, 77,252, 17,198, 95,100,140, 11, 9, 17, + 66, 2, 18, 33, 66, 1,219, 82, 90,153,247,148,250,157,115, 91,209,104,116,215, 38,147,153,204,220,243,248,190,115,207,253,206, + 69,253, 93,251,227,252, 81,255,111,120,252,191, 56,253,223,101,122,117, 91, 83, 90, 84,103, 96,158, 32,105,180, 21,112, 1, 55, + 74, 15, 19, 19, 15,241,101,253, 88,221,198, 23, 28, 52,183, 92,220,225,183,221, 92,238, 5, 27,236, 64,255, 58, 94,138, 77,132, + 52, 12,240,126,128, 54, 30, 77,100, 86,226, 25,120,124, 38,161,211,248, 88, 66, 50,151,124,166, 64,170, 20, 92, 15, 81, 75,193, +134, 18,193,116, 72, 98, 76,227,209,174,116, 59,146, 89, 39,101,158, 65,191,189,129,240,253,112,241,209,218,222, 42,137, 16,145, + 76, 71, 60, 89,158,110,118,142,121,143, 30, 4, 51, 74, 41, 5,167,126,226, 39, 73,242,126,253, 29,156, 48, 1, 16,129,253, 9, +150,157,232,197,199,221,125, 75, 47,198,189,208,177, 43,166, 97,157,248, 71, 84,227, 67, 64,215, 92,255,220, 75,133,222,137,123, +223,226,184,225, 27,199, 33,141,242,106,195,133,101, 31,236, 49,167,153,174,153, 25, 45,228, 29,211, 44, 25,217,108,223, 40, 72, + 16,117, 19, 63,108,221, 36,163, 76,101, 74,211,123,100, 20,244,168,227, 37,161,183, 29,136,209,113,163, 53, 33, 47,171,207,218, +238,162,144, 69,232, 71,208,151, 36, 32,108,144, 81,145, 42, 23, 11, 53,229, 76, 35,103, 1,163,145, 70, 77, 5,216, 35,111, 58, + 69,195,205, 91, 37,219, 40,216,200, 16, 50,171, 73,176, 13, 71,154,159,246, 90,187,109,143, 5,134,184,135,141, 93,104,202,157, +113,178,101,216,238, 98,109,121,231,120, 27,159, 22,142,138, 8,149,203,208,164,189,169,242, 76,209, 38, 10,133,181, 0, 76,158, + 28,153, 6, 96,183, 12,219,143,189, 86,183, 5,199,163,208, 47,180,169,234,165,132,132,248, 85,137, 64,175,228, 43,126,236,219, + 89,187, 54,125,189,235,119, 16, 70,145, 63, 86,238, 61,174,218,213,253,214, 62, 69, 37, 3, 38, 30, 45,213,150,215, 54, 87, 55, +183, 55, 4,205, 33,176,224,189, 14, 29, 56, 12, 73,201,137, 59,137,113, 67, 80, 90,184,165,174,134,192, 17, 79,165,246, 24,172, + 99, 46,147,127,118,255,169,231,159, 53,189,246,215,198,222,231,250, 86,213, 25,155, 25,191, 34,123,233, 89,224,195,150,198,157, +177,131,246, 97,204,162,154,240,216,237,157,117, 60,229,206,181,219,251,205,131, 32,138,192,142, 96, 15, 69,187, 52,225,142, 29, +180,142,206,162,239,126, 24, 54,207, 78, 88, 47, 48,154,159,156,109,117, 72, 99,214,143, 34, 16, 85,215,157, 88,121,240,100,247, +203, 54, 94,106,212,169, 82,161,128,240,151,141,235,121, 4,141, 64, 14,155, 31,159,163, 2,116, 47,157,170, 76,226,233,245,211, + 58,114, 27, 18,201,169,223, 6,190,195,131, 2,150,202,129, 9,155,150,169,135,254,141,187,151,197,156,205,206,214, 23,170,241, + 74,246, 7,243,123, 6, 0, 80, 1,101, 9,112, 46, 44,243,195,250, 97,152,158, 43,234,166, 68, 96,248,176, 27, 73, 70,171,170, + 66,143,179, 53, 87,167,169, 62,109,225,147, 74,163,144,177,102, 42, 35, 70,214, 56, 9, 73,235, 41,195, 53,152,159,162, 81,169, + 8,116,207,110, 39,240,119, 13,148,101,185,182,176,215, 56, 8, 2,127,231,180,177,209,108,188,124,245,226,205,235,183, 87, 11, + 11,194,232,126, 76,182,158,207, 46, 69,125,143,251,155,127,134, 80,193, 77,253, 37,238, 89,151, 1, 41,198,240,185, 18,218, 57, + 34,249,156, 48, 78, 65,161,162,132,172, 91, 97,118,133,199,111,206,222,170,183,235,192, 42,229,210, 40,210, 42, 79,247, 81,146, +228, 98,112, 84,148, 68,168, 70, 40,152,138,243, 70,167, 73,135,111,212,214,164,212,203,197, 50,139,218,218,113,156,128,178, 19, +164,227,241, 26,112,231, 70,183, 37, 46,250,215,149,148, 35,176, 8,137, 31, 68, 41,248,147, 21,167,161, 98, 73, 44,127,112,209, +208,194,255,213, 68, 5,250,244, 64,232, 88,214, 19,175,229,230,221, 40,142, 21,221, 0,226,150, 67,185, 39,213,167, 52,236,173, + 35,122, 97,104,166, 23, 7, 17,205,124, 72, 7,245, 9,109,200,199, 52, 49, 60, 24,164, 46,239, 81,206, 80, 81, 81,138, 31, 2, + 48,118,109, 61, 81, 67, 65,184, 61, 61,167,183,237,178, 11,203,101, 81, 9,209, 64, 76, 76,136,111, 70, 30, 12, 15, 62, 25,255, +130,254, 55,226,131,241, 15, 96,120,210,196,132,248, 0,162,196, 53, 18,110,114, 95,220, 11,108,247,214,118,219, 61,117,102, 90, +118, 53,129, 68,120, 34, 57, 9,237,194,153,249,102,230,155,239,227, 3,156,126,211,102,233,173, 63,170,202,255,126,197, 55,157, +239,145, 87,203,176,185,143,241, 46, 26,156,209, 85, 4,182,112, 3,225, 41,131,190, 23, 96, 86,255,167, 83,175,222, 74,191,188, + 78, 75,196,166,137,211,205,219,216,226, 54,138,234,200, 36, 23, 51, 8,217,221,168,131,130, 18,154,128,240,219, 99,125, 36,243, + 37, 34,149,169,227, 65,210, 96,161,137,127,140,125,124,116, 17, 81,100,206, 25,109,180, 27, 49, 53,207, 24, 42,120,250,240, 87, +127,251,233, 13,156,132,154,136, 28,107,253,131,202, 62, 10,224,168,108,196,202,215,187, 53, 20, 95, 11,113, 90,162,162,208,138, +212, 24,148,120,186,135, 78,184,164, 77, 71,109,114,215,199, 37,172,178,123, 78, 14,174,184,240, 9,233,183, 27,161, 62, 17,128, + 54, 78, 11, 71,161,210,233,247,181, 82,211, 61,186,108,249, 18,123,112, 28,203,100,101,196, 50,115,166,152,205,102,167,179, 25, +219,182, 13,166, 77, 24, 70, 61,232,193,221,178, 98,110,192,195, 43, 40,116, 9, 33,187, 21, 81,110,241, 36,212,127,161, 8, 13, +147,235, 2, 31,128,163, 73, 9,138,118,216, 54,217,151,195,107, 68,172, 7,224, 33, 68,238,151, 31, 34,131, 1,192, 0, 84,229, + 30,122,131,209, 71, 19, 65, 96, 66, 56, 9, 79,152,183,245, 41,199,168, 53,188,245,131, 43,168,239,161, 60,152, 30,155,217, 62, + 47, 17, 66,194, 44,119, 88, 61,192,253,163,208,251,113,252,253,206,216,189,122,179, 26,163, 28, 43, 60,188,238, 75,191,222,169, + 26,204, 48,209,122,219, 88,152,121,180,125,242, 19,224, 51,105,242,241,171,102,157,150,215,188,172,149,131,127,114,136,254,104, +166, 72,151,115,191,178,135,150,170,157,102,229,234,183, 33, 44,212,224, 53,173,229,213,229, 7,197,185,166,215, 4,144,139,154, + 88,113,184,117,180,165, 27, 38, 73, 12,234,112,108, 52, 83, 16,130, 95, 93, 52,252, 48,120,253,252,213,225,249, 33,250,132, 48, +117, 99,119, 3,110,117, 27, 45,146,185, 35,178, 93,196, 1, 80,112,132, 43, 27,171,173,182, 11,137,103,174,120,223, 80,121,161, + 48,181,180,176,244,181,180,118, 82, 63, 11,124,223, 51, 3, 0,176, 79, 31, 62, 9,250,189,141,157, 77,199,114,244, 40, 62,174, +156,154,134,157,216, 15,189, 92,124,177,242,249,253,222,197, 97, 49, 95,132,219, 7, 9,222,133,250,140, 41,243,197,249,197,199, + 75,103, 31,222,193,175, 43, 56,163,249,217,169,198,217,101,175,211,114,204, 12,164,159,114,189, 12,145,168, 92, 43,231,157,172, +206,120, 46,147,245,194, 94,151, 28,194, 32, 55, 20,114,133, 70, 11, 3, 58, 87, 24, 36,176,163,218, 17,225, 66,214,241, 91,147, + 99,119, 39,166,166,127,237,175, 67,141,217,225,150,178,227, 42,207,198, 17,164,247,117,140,239, 26,142, 62,144, 81,195, 7, 46, +109,212, 45, 16,232, 93,208,250, 86,133,202, 76,215, 88, 72, 33, 94,198,233,172,142,209,202,158, 42,101,252,247,197, 7,152,163, +169,150, 16, 72,168, 21,218,113,199,109,214, 61,192, 61, 25,156,216,224,183, 96, 9, 32, 82,133,136, 38,133,233,143,207, 94,158, +238,194,167,244,177,180,198, 0, 67, 25,136, 36, 77,197,198, 17,168, 18, 59, 60,219, 66,237, 82,147, 40,251,164,162,138,180, 3, +178, 38, 67, 18, 49,183, 12,211,239, 7, 0, 8, 18, 23, 1,153,178, 63, 84, 50, 19,166,125,218, 52,112, 35, 97,153,140,222,250, + 95,246, 54, 5,231, 80,146,251,110, 69, 38, 27,254, 41,108, 87, 82, 79, 34, 56,140,100,138, 88,146, 11,216,245,168,143,106, 96, + 57, 92,123,108, 7, 77, 98, 70,202, 56, 29,180,146,201,220,192, 89, 34, 49, 54,196, 3, 56, 5,161, 68,130,188,154,196,245, 66, + 29,116,195, 18,123,207,148,179,159,200,250, 37, 12, 33, 9,176,143, 36, 92, 37,170, 58,114,173,226, 86, 53,114, 82,187,102,243, + 37,197, 6,190,128,219,117,113,102, 38,195, 33, 69, 50, 30,118,180,213, 84,125, 64, 73,204,177, 1,136,192,171,212,208,124, 92, +253, 35, 0,101,215,210,218, 68, 20, 70,103,238,157,153, 36,211,166, 77, 99,211, 23, 20,219, 34,138,148, 22,171,226,190, 32, 5, + 55,254,129, 46,253, 29,130,127, 68, 4,117, 45, 8,174,186, 16, 4, 91,186, 80, 81,236,203, 42, 45,244,153, 52,233, 35,175,121, +100, 30,241, 59,223,157,212, 86, 68,116,153,217,204,100,230,222,115,191,199,249,206, 49,206,201,148,250,191, 33,251,223,233,237, +255, 9,251,151,160,191,163, 34, 9,244,135, 56, 1, 6,127,245,246, 31,186,175,191,117,119, 47, 50, 27,117,117,110, 38,122, 58, + 29, 63, 42, 31, 61,179, 16,204, 46,230,133,177,202, 2,240,199,109,123,120,239,177,160,157,147,136, 44, 11,165,162, 31,167,173, + 44, 84, 10, 88, 28,174,195, 85, 18, 39,213,242,244,196,157,239,123,235, 20, 94, 65,190, 82, 24,220,111,194, 93,156,192,229,162, +190, 78,169, 64,211,175,251, 65,171, 20, 28, 34,234, 17,129, 98, 69,161,128,169, 73,120, 98, 99, 29, 66,211, 15, 73, 71,152,232, +203,113, 23, 84, 87, 19,106, 66,143, 36, 92, 87, 35, 52, 0, 36, 62,191,100, 57,235,182,136,242, 54,232,170,181, 86, 76, 55,160, +240,208, 9, 34, 2,163, 98,172,125, 11, 43,234, 52, 39,164,156, 26,204,209,195,235, 25,139,192,213,128,209,187,180, 92, 48,212, +108, 33,123, 51,169,235,217, 44,202,223, 26, 6,156, 17, 97, 19,238, 64, 26,205, 8,221,184,234, 33,252,241, 64, 74, 18, 65,160, +241,170,230,177, 58, 22,163, 2,153,172,133, 38,170,169, 94,146,174,245,219,169, 30,211,114,253,120,105,237,232,168,225, 75,153, +182, 77,171, 82, 47,110, 30, 64,160, 28, 58,215,128, 5, 1,140,246, 28,219,176, 27,126,163, 14, 95,158,144, 78, 62, 58, 50,107, + 94, 13,134,186, 45, 47,211,101, 55,156, 42,133,231,110,224, 53, 3,135, 50,208,148, 48,231,102,230,150, 55,150,232,138, 50,217, + 41, 86, 15, 29,207, 61,183, 65,231, 40, 94,137,143, 34, 48,163,216,188,238, 53,109,171,123,126,118,254,201,139,199,147, 87, 39, + 9,178,251,179, 5, 10,255, 41,127,145, 44, 47, 83,170, 22, 9,247,143,105, 11, 65,150, 78,123,186,240, 76, 98,232,193, 31, 45, +140,101, 80,175, 12, 29,223,233,235,202, 15,247, 13,111,238,111, 96,245, 24,102,241,172,148, 49,210,131,185,161,129,158,161,245, +221,149,221,242,206,215,205, 15, 35,185, 17,215,119,108, 51,125,247,218,204,226,234,226,231,173, 47,163,253,163,244, 19, 70,184, +169,238, 66,207, 21, 90,127, 53,167, 78,223,229,227,198, 39,203,180,210,166, 21,107,225,126,249, 16, 90,226,244,212,154,204,166, +186, 95,191,123, 69,175,221,176,229,126,249, 96,188,235,198,118,101,229,229,155,231,247,167,103, 13,156, 70, 65, 79, 38,123, 84, +171,152,102,234,225,189, 7,239,215,150, 61,175,154,179,123, 43,181,242,237,137, 91,187,149, 61,202, 90, 40,126,167, 96,175, 59, +133,188, 71, 50,146,112, 2,212, 42, 12, 12,113,173,185,237,153, 93,219, 11,123,227,143,110,106, 4,166, 81,147,199,234,120,129, + 11, 14,225,209,164,135,225,147,214,107,162, 26,189,122,250,118,121, 7,174, 9,154,130,190, 14, 11,156, 27,144, 23,235,181,138, +171, 7, 75, 75, 41,242, 89, 91,166,205, 83,215, 9,113,246, 75, 30,188, 69,230,198,189,124, 86,180,101, 31,119,215, 45,231,236, +169, 10,212, 6, 5, 51, 86,100,196, 81,182,218,247, 77, 45,176, 52, 99,207,219,137, 88, 36, 71,176, 83,149,206, 93, 80, 61,142, +144, 78, 71,218,113,253,152, 54, 12,253,205, 80,136,241,252,216,143,210,150,143,234, 53,108,192, 66,140,112,160, 8, 19, 43,213, + 5,140,119,194,229,147,221, 36,193,217,111,199,241, 57, 74, 38, 65,183,114, 56,162,111, 4,254, 30,229, 45, 6, 5,197,202,213, +155, 91,166, 26,230,186,194,176, 17,213,241, 4,220, 90,253,197, 81,108, 39, 37,157,118, 98,156,150,216,122, 83, 30, 0, 5, 87, + 16,124,141,124,182,159,150,141,141, 17,185,166,154,237, 50, 18,223, 37,149, 27, 9, 53, 22,195, 76, 16,221,241,154,170, 40, 29, + 41,151, 64, 80, 42,216, 60,141,163,152,115, 54,126,199,114,137, 79,219,203, 66, 0,226,130,222, 77, 98,104,221,142,207,154, 39, +220, 92,193,165,159, 2,176,118, 45,187, 77, 67, 65,244,218,215, 78,108,231,225,164,143, 52,168, 65, 77, 43,144,128, 21, 11, 86, +124, 2, 18, 43,126,128, 79,227, 11, 88, 32,132, 4,136, 45, 66,109,165,168,139, 66, 90,181,180,105,200,163,121, 55,142,227,248, +205,204, 92, 39, 5,193, 6,137, 31,176,147,235,185,103,206,188,206, 40,236, 95,104,251,127,133,248,223, 94,145,230,168, 8,239, +224, 70,111,153,170,211, 33, 75,148,206,208, 78,132,174,127,244, 55,136,143,153,178, 18, 56,203,106,121,128, 74, 84,142,252,149, +202,211,113,137, 22,120, 60,168, 72, 40, 92,196, 16,194,135, 97,184,172,112,163,113,194,133,199, 98, 69,136,186,154,118,100,137, + 28, 76, 81, 55, 83,170,222,159, 94, 51,218, 85,113,116, 81, 3,184,217,217,172, 54, 7, 77,225, 52,105,140, 80,246,209, 16, 84, +120,219,100, 49,166, 70, 63,209,142, 41,149,243,101,112, 15,148, 72,247, 72, 84, 67,162, 86, 10, 38,254,142, 72, 45, 5, 52,172, +140,117, 77, 68,113,106, 53, 6, 48, 96,124,175,240,168, 57, 61, 71,197, 73, 22,240, 0, 94,129, 59,189, 73, 72, 61, 82,104, 49, + 3, 23, 75,230,105,250,158,115, 81, 95, 10,235,195,177,206, 93,156,228,164, 7, 35,163,145,177,135, 3,252, 27, 68, 6,128,253, +247,139,197,106, 62, 87,192,234, 66,214,148, 48,247, 2, 92, 30,229,248, 89, 48,115, 60, 75,138,231,216, 69, 20, 80,150,136,102, +175,240,186,226,230,129,208, 0,238,197,193, 77,101, 83, 28,248,163,237,248,251,223,251, 67, 11,156,167,195,165,148,231,217, 51, +127,162,171, 57, 35,149,107,141,174,224,172, 53, 85,155,187, 78,224, 47, 0,224, 12,173, 0, 22,143, 63, 9, 59, 86,248,100, 54, +146, 21,133,124, 49,220, 77,182, 91,222,187, 30,119, 15,207, 14,224, 50,220, 41, 84, 28,127,254,177,246,126,238,205,133,116,193, +192,234, 83, 25, 77, 7, 87, 69,251,181,117, 27, 53, 73, 34,192,101,112,114,134,150,237,223,116,224, 19,164, 52,253,237,254,155, +141,226,214,166, 89, 66, 33,142,208, 79,180, 88,163, 64, 85,141,148,164, 64,124,155,207,172, 45, 60, 59,165, 40, 96,105, 15,239, + 62,168, 55,190, 78,102, 67, 47,160,110, 78, 22, 14,173, 1,176,108, 51, 83,180,156,105,121,173,210, 25, 52, 32,244,182,221,233, +105,251,196,163,237, 55,240,107,102,174,173,113,117,167, 92,109,116, 27,156,243, 23, 79,159,191,254,252,174,152, 47,186,174,219, + 25,183,219, 55, 93, 89, 68,126,146,220, 26,117, 80,213, 54,242, 55, 50,235,112, 77, 81,114, 54,246,178,105,179, 61,234, 66,172, + 80,200, 20,128,176,239,150,170, 21,185,120,132,162,110,252,203,217, 65,165,180, 51,178,198, 16, 10,120, 88,117,118, 26,189,171, +177, 61, 1,127, 12,240, 13, 95,255,199,160,133,243,238, 44, 66,194,193, 36, 67, 53,168,203, 59, 18,211,239, 97,224,215, 79, 15, + 21, 8,245,112, 34,164,215, 28, 70,219,175, 62,165, 94, 62, 99,104, 74, 19,166, 16, 94,112,202,108, 35, 17, 0, 60,207,176, 90, +247,226,195,249, 81,189, 55,116, 92,224, 1, 88,213, 32,189,160,208, 23,240,144,180, 96,173, 6, 15, 41,221,137,155,249, 42, 27, +249,133, 28, 77, 45, 11,112, 21, 32, 82, 69,128,140,133, 24,155,104, 83, 3,179, 83,200, 42,211,138, 23,205, 44, 44,174,104,198, +124,225,193,205,210,228,180,231,133,154,142,187,177, 38,108,182,173, 85,246,231,158,153,206, 7,145,139,139,106, 49,240,205,155, + 70,230,164,115,153, 91, 47,207, 71,125, 28,162, 21,156, 61,138,176, 34, 66,126,231,201,189,199,181,203, 99,184,114, 91,102,233, +184,245,141,228,224,104, 95, 82, 64, 2,245, 50, 11, 48,155, 71,124, 62, 78,210,185, 98, 8, 55,190,109,199,128,208, 77, 49,211, +102,223,237, 69, 75,124,228, 50, 98, 8,202, 10,105, 89,136, 0,134,179, 27, 89,138, 87,178,180,183,204, 90, 20,126,105,229, 88, +210,209, 71,199, 5, 15,204,164,113,200, 57,173,104,182,235, 8,150, 9,252, 6, 44,208, 15, 93, 81, 30,141,165,165,244,215,106, +168, 83, 98, 99,107,204,150, 27,208,153,152,125,100, 75,177, 2, 1,130, 44, 81,164,249,163,229, 36,145,131,148,146,225,127,244, + 14, 20, 57, 39, 58,140, 63, 5, 96,236, 74,118,155, 8,130,104,207,238,217,226, 69,182,147, 40,137, 2, 18, 66, 32, 33, 33,113, + 0, 62,129, 59,159,192,133, 3,119, 62,130, 95,224, 15,144,184, 32, 4, 39, 56,162, 8,133,229,192,201, 33,193,132,216,216, 25, +143,199,179,122,182, 30,170,186,199, 73, 0, 9,113,241,201,158,145,103,170, 95,191,234,122,245, 74,254, 7,148,255, 79,243, 42, +206, 9,100,170,243,255, 63,127,255,251, 11,204,110, 16,167,204,178, 20, 3, 34, 44,171, 7,212, 18,174,132, 21,203, 11, 66,204, +139, 87,101,150,100,213,234,228, 93,138,113, 38, 97, 33,158,221,147, 15,134,173, 68,222,169,180,106, 7,168, 50,148,143, 84,170, +108,178,169,187,252,185,112,215, 48, 52, 68,217,237, 94,154,120, 99, 94,232,128,120,117, 99,192,107, 15,247, 9,177,146,113,202, + 43, 92, 95,108, 91, 29, 72,141, 41, 14,180, 83, 41,182,119,166,248,158,197, 66,145, 20, 8, 70, 69,107, 96,165, 5, 85,139,194, +216, 27, 17, 38,165,101,147, 82, 0,117, 1, 70, 51,110,199,192, 29, 80, 89,234, 91, 2,137, 88, 98, 45, 18,181,232, 52,173,141, + 91, 15, 60,167, 16, 82, 85, 50,112, 61,227, 25,227,170, 66, 34,254,182,125,115,130,133, 61,243, 88,202, 32, 97, 73, 66, 57,173, + 89, 87,121,225, 45, 34,101, 19,130, 44, 58,134,237, 61, 3,214,193, 68,232, 70, 3, 56,120,175,185,182,110, 24, 91,166,121, 99, +179,103, 27, 90,207,208, 0,239,153, 89,163,144,226, 90,167,240,118,208,227,190,160,128,183,131, 81,112,120,226, 59, 11,234, 70, +129, 38, 91,247,110,222,127,181,255, 12,224, 79, 17, 13, 32,113, 16, 12,211,197,164,100,231,157, 56, 62, 27,139, 84, 42, 4, 93, +142,117,136, 76, 18,225,113,229,126,236,155,186, 29, 39, 11, 93,179,129,174,206, 99,215,199,244, 19,229,213,240, 76,166,139, 17, +206, 33, 48, 91,180,208,218,102,219,139, 61, 72,165,129, 68, 7,201,194, 99, 93,139, 13,213,100, 44, 21,235,104, 0,214,148,118, +224,167,186,102, 2,104,238, 15,222, 95,221,190,190, 63,248, 32,203, 90,156,248,146,164,233,186,177,196,228,172,138,178,168,109, +183,179,108, 41,225, 59,194, 5,219, 94,235,104, 13, 11,219, 62, 33, 12,112,108,222,229,241,236, 88,197, 30, 1, 37,203,179,225, +228, 91,199,110,206, 3, 23,246, 93,213, 82,205, 6,142,152,176,212,198,221,107,119,222,126,122,115,186,152,180,141, 38,108, 96, +207,223,189,156,249,167, 22,242,238,178,219,236, 1,188, 96,210,128,178, 37, 41,101,167, 40,101, 65,251,157,254,193,244,187,161, +106, 78, 24, 86,149, 15,223,209, 84, 77, 83,244, 19, 7,199, 72, 49,139, 40,204,216,210, 52,153, 56, 63, 0,205,113,200,178, 32, +158, 46, 28,192, 23,236, 48,101, 41, 11, 92,208,141, 92, 8,152, 69,232, 97, 63, 35, 48,137,216,195,187,228, 37,218,121,240, 0, + 38,133,109,244,189,100,114,123,227,138, 27,238, 61,122,252,226,225,151,163, 91, 79, 30, 16,178, 65, 68,143, 24, 17, 81, 69, 2, +251,115,147,145,168,215,131,189,167,251,195, 32, 45, 33,243,208,149, 36, 88, 78,230,126,154,229,154, 42, 75,182,133,226,122,122, + 94, 69, 20,216, 60, 79, 0,241,157, 86,115,179,103, 37,121,186,140, 11, 9,101,102,120, 60, 47,177, 6,121, 42, 85, 82,201,124, +162,184,215, 10,218, 71,139,114, 85,158,140,134,148, 74,144, 93, 37,233, 28, 22,185, 41, 27, 94, 26,181,119,214, 32, 36, 3,226, +246, 27,232,122,223,178,236,174,221, 26,122, 33, 36,170,240,247,103,209, 92,151,149, 78,119,211,164,228,216, 29,163, 82,134,169, +158,163, 52,102, 69,197,106,228, 78,163, 44, 89,102,217,204,119,114,230,249,133, 39,186,180, 52, 13,107,119,125,247,227,209,103, +145,112,112,175,207,241, 25,223, 62, 27,254, 70, 87, 58,145,124, 26, 78, 5,114, 78,197,225, 19,153,156,128,138,166,164,110, 99, + 34,127,130, 59,255, 61,223, 47,136,176,221,221,114,124, 7, 66, 29,254, 53,112,255,175, 63, 15, 33, 54, 89, 3, 93,189,236,226, + 60,226, 94,191,220,206,143, 91,151,192,158, 88,112,233, 38,131, 41,164, 80,132, 31,140, 33, 9,149, 33, 2,203, 37, 97,202,227, + 26,228,171,170,246,127,100,218, 75, 93,209,147, 34, 17,106, 49,202, 74,153, 82,223,145,167, 8, 53, 64,254, 18,128,176,107,217, +109, 26, 10,162,247,250,121,237, 56,206,163,105,155, 70, 85, 81, 65,128,132,160, 98, 1, 18, 18, 18, 95,192,146, 21, 11,190,134, + 21, 91,118,252, 0,176,166, 98, 85, 88, 21, 65, 43,160, 80,164, 2, 74,161, 47, 66,104,146,166,205,211,137, 29,219,204,204,117, + 10, 69, 66,117,183,117, 93,223,155,204, 61, 51,115,230, 28,237,148,234,201,105,151,142,181,242,232, 63, 68,198,211, 47,121,242, + 8,221,134,128, 38, 93, 0, 67,246, 39,178,203, 43, 64,131,189,191,211,133, 99, 73,119,133,200,239,114,118,128,147,169, 28,201, +234,157,124,178,101,164,250,126, 55,177, 51,145,189, 83,218,119,200,178, 19,174, 40, 29,191, 26,246,244,186,134,106,109,254, 42, +143, 21,168, 99, 37,233,143, 72, 75,147,152, 74, 70,241,100,102,122, 99,111,131,232,165,158, 15,161,111,220, 8,129,157, 25,134, + 40,148,237, 13, 7, 57,103,162, 61,104,199,241,136,232,138, 92,218,205, 4,248, 3, 47, 19, 6,156,188,197, 25,105, 21, 40, 76, +216, 76,167,105, 34, 74,255, 80,190, 70, 71,135,110,157,250, 8, 22,210, 18, 66,193, 19,117, 67, 62, 26, 33,205, 17,229, 48, 73, +123, 75, 46,135,170, 38, 57, 10,202,195,203, 6, 20,160,113,146,232,101,146, 48, 44, 23, 44,130,221, 34,246,187, 80, 35, 13, 91, + 84,126, 24, 55,162,160, 81,173,127, 14, 66,244,226,131, 95, 54,116,219, 22, 41, 93,119,133,233, 56,118, 86,232, 37,195,110,122, + 65,171, 55, 28, 6, 1,141, 6, 99,223, 70,101, 38, 60,178, 55,104, 62, 91,121, 76,137, 5,220,221, 27,248, 1,228, 1,134, 46, + 60,164, 97, 34,113,173, 51,104,195,191,153,113,242, 16,100, 33, 79,192, 38, 18,174,107,212,245, 0, 25, 33,248, 26,250,131, 90, +103, 63,209,113, 35, 59,111,136,164,128,244,103,242,179,149,131, 31,144, 68, 11, 83,244,177,215, 29,184,118,214, 11, 6,182,200, +192,194,202, 34,106, 90,164, 61, 52,230, 69,102,117,199, 59,132,195, 99, 58, 59, 3, 56,186,118, 84,181, 76,187,224, 78,110,215, +182, 34,180,107, 80,225,248, 12,226,224, 92,241,252,155,175,175,138,249, 82,179,213, 16, 66,188,252,240, 34,239, 20, 52,116,150, +135,212, 74,217,222,255,150, 54, 29, 64,136, 66, 53, 56,206, 34, 42,173, 94, 75,195, 37,198,128, 59, 63,121,230,198,133,235,139, +171,139, 75,239,151,166, 51,133, 92, 42,235,218,110,173, 85,131,115, 11,182,225,218,194,205,201, 84,118,121,125, 25, 54,171, 93, +233,192, 93, 46,154,123, 28, 32, 17, 17,199,149,205,140,229,192, 75,193, 43, 88,134,216, 63,218,199,218, 66, 72,222,217,170,122, +245,236,194,112,228,191, 45,191,211,184, 49, 55, 49,251,105,247,139, 57, 10, 33,202,211, 16,189,143, 21, 58,250,144, 35,165, 49, + 26, 33, 45,152,132, 21,209,153,146,133, 25,219, 77,146, 33, 5, 5,176,224,123,144,182,220,130,149,113, 70, 91, 43,173,157, 61, + 93,125,240,240,249,157,167,175,111,223,191, 43,238,221, 98,172,196,180, 1,138,142,177, 94,240,104,117,249,201, 26, 28,170,134, +208,189, 48,172,215,218,171,235,219, 61,198,166, 25,203, 49,102, 92, 49,227, 72, 58,120, 38, 99,175,128, 54,108, 77,187, 84,154, +176,132,218,238,163,239,132,137, 70,168, 52,177,196, 18,161, 94, 42,133, 0, 28, 64,216,142,144,141,115,184,197, 28, 81, 2,173, +176,234, 97, 21,179, 26,198,179,142,219,240,142,138,243,151, 25,118,100,187, 57, 35, 87, 15,234, 37,245,162,198,184, 79,170,145, +164,165,197,178,110,190,185,187, 89, 59,172, 7, 10, 39, 57,129, 40,164,121, 90, 20,247, 96,124,167,177, 11, 81,157,161,127, 83, +156, 79,231,225,227, 1, 89, 87,249,103, 25,118,106,237,251, 71, 68,238, 36, 26, 19,179,164,228, 62, 46,222, 38, 1,167,152, 43, +193,222, 97, 21, 30,130,193, 56, 28, 78,185, 83,181,110, 67,138, 19, 16, 1, 95,146, 87,162, 36,190, 39,186, 59,200,176,228, 73, +112,199, 55,174, 52, 43,161,196,203, 76,126, 1, 17,104,146,110,129,196, 84,138,180,246,132, 85,154, 43,204,237,213,119, 53, 77, +131, 28, 17, 96, 62,226, 0,250,179, 60,121,126, 20,143,229, 43,109, 67,248,189, 62,231, 73,138,127, 12,219,143,213, 41,221, 84, +214,107,121,236, 4, 35, 70,249,135,142, 40,175,223, 2, 48,118, 45,187, 77, 3, 81,116,198,227,177,147,166, 78,250, 4,133, 54, +164, 82, 75,121, 84, 85,187, 66, 32, 64,234, 23, 32,118,136, 13, 91,126, 1,150, 93,240, 3,176,228, 7, 88, 32,224, 27,144,218, + 10, 42, 22, 72, 69, 2,202, 67,164, 82,136, 75,155, 71,235, 38,118,236,241,112,239,181, 83, 44,168, 4, 82, 87, 85, 36,203, 51, +201,153,123,238,156,123,206, 9,250,247,255, 7,119,116, 7,211,209,137,141, 26,254, 47, 76,231,233, 18,224, 7, 81,103, 18,135, + 25, 49, 59,255,251,227,198,159,224, 14,139, 24, 39, 78, 50, 60,117,228, 73, 10, 14,106,193,243,244,194,129,161, 25, 88, 68, 40, +159, 7,124,137, 40,138, 68,103, 44,232,169, 60,161,184,113,148,232,104, 26,119, 78,198,136,178, 38,245,131,203, 93,186, 19,197, + 83, 81, 8,203,202,197,104,208, 17,210, 77,108,124,236, 25, 65,217,132, 49, 32, 17, 2, 45, 86, 49,200, 63,160,246,110,105,128, +165,192,147, 42,200,177, 72,162,110, 92,163,148,201,178, 80, 66,111, 3, 55,208,161,212,145,133,131,171,220, 70, 83, 72,101, 42, +101, 2,248, 91,134, 77, 26,112, 43,103, 66,101, 37, 11,121,107,172, 36, 75, 37, 49,226,136,209,146,116,134,113,124,212, 96, 2, + 88, 51, 0,153, 82, 2,219,152,140,212,155, 56,152, 98,112,224,153, 40, 84, 38,117, 50,202,222, 56,201,243, 49, 47, 0,158, 15, +149, 58,252, 89, 18, 31, 0,207,193, 64, 38, 83, 0,189,239, 49,213, 9,251,110,207,251,126,208,244,188,192, 50, 45, 60, 81,146, +104,102,178, 36, 73,178,218,208,133, 6,187,252,178, 79,209,207,216, 83, 22,246, 97, 23, 7, 46, 20,221,127,193, 38,244, 2,239, +250,197, 21,146,165, 99, 89, 36, 80, 57, 45, 82, 39, 85,173, 39,156, 9,168,127,113, 58, 87,230, 8,180,213,244, 88, 21, 86, 47, +234,163,177, 45, 16, 50,120, 7, 88,161,142,215, 41,143,151,221,214, 15,204,134, 66,221,126,162, 97,141, 23,171,139, 63,219, 46, + 44,248, 66,101,105,255,112,255,236,233,234,118,253, 35,172, 68, 16,246,233, 74,156, 3, 91,183, 76, 27,126, 90,245,102,157,236, +104, 66,248, 93, 9, 67, 94,158,191, 10, 28,252,192,239, 8,224,142, 10, 13,129, 21,237,102, 98,150,162, 40,150, 4,176,152, 18, + 34,185, 51, 52, 60, 51, 57,179,254, 97, 3,211, 96,164, 60,242,187,112,180,140, 20,156,115,229,217, 80, 69,182, 41, 55,222,175, +239,184,181,229,185,229, 47,238, 55,224,218,240,226,104,252,141, 38,116, 56,208,232,249, 94,101,124,170,209,222, 5,246, 0,111, +148,183,134, 4, 23,192, 12, 0,149, 96, 39,106,187,181, 11, 83,231,107,187, 59,145, 86, 45,175, 61, 95,158,107,180,221, 62,172, + 64,140,205, 37,248,242,192, 87, 4, 14,158,234, 36,186,152,177,212,133, 54,134, 3, 38,142, 35, 97,154, 77,175, 9,165,192,165, +179, 11,192,129, 48,135, 3, 86,176,119, 48, 58, 84,127,221,112,161, 24,190,213,141,156,189,238,218,203,205,198,234,179,189, 55, + 91,149, 48,104, 61,127,199,158,126, 90,123,181,221,179,177,105, 30, 98,170,170,174, 54,187,247,247, 59,119, 24,187,201,216, 38, + 99,111,165,113,166, 96,251,132, 91, 10,216, 27, 80,144,225,252, 82,101, 82, 25,176, 35,125,105,114,199, 52,115,210,196, 32, 1, +178, 70,164,208,222, 84,149,204, 9, 48, 1,241, 45,211, 40,229,109,155, 89,181,189, 66,132,166, 53,102, 18,195, 96, 68,198,163, +173, 23,183, 87,238,222,152,189,178,250,100,245,222,212,131,199,238,195,106,169,114,173,120,170,141,102,194,188, 31,162,105, 66, + 7,175,187,133, 31,169,241,226, 40,144,170, 22,234,211,226, 36, 26, 44,162, 82, 29,231, 57, 96, 59,117, 52, 61, 81,249,220,248, + 74,228, 38, 73,170, 35,187,146, 88,103,208, 46,206, 66, 9,252, 11, 56, 83, 50,165,154, 25,218,143, 15,131, 35,150,154,144, 37, + 67, 2,191, 39,112,244,192,145, 93, 15, 58, 61, 58, 77,150,224,169, 84,146, 15,204,165, 83, 35,182, 99,241, 33, 31,136, 74,121, +215, 71,179,207, 98,161,232,135, 62, 42, 97, 82,199,182,164,242, 76,193, 61, 17,233, 7, 97, 64,249,122, 60, 83,188,179,227,236, + 45,216,125,143, 26,247, 52,168, 99, 24,217,209, 31,226, 7, 89,176,253, 37, 0,103,215,178,155, 68, 20,134,207,156,185, 82,102, + 24, 6, 16,218,161,105,106, 20, 72,212,168, 27, 99,250, 4,117,225,214,133,111,224,214, 55,113,227,214,117,223,160,137, 49, 94, +146,110,138,198,216, 52, 86,106,109,106,172, 6, 74, 11, 76,153, 1,230,194,204,248,255,135,161,142,137, 49,198, 13, 33,100,114, +230, 48,151,239,191,127,159,240,127,110,251, 95,112, 60,109, 39,100, 94, 9, 66,151,252,158, 93,137, 83, 67,170,255,114,210,244, + 92,235,188, 71,158, 99, 34, 65, 92,213, 88, 57,238,125,229, 82,147,176,170,162, 1,162, 2,142,224,168, 49,218,140, 25,187,103, + 60,241, 39, 9, 66, 19,178, 32,101,125, 84, 88, 15, 47,186,113, 24, 91, 16,218,216,144, 41,120, 97, 28, 48,239, 58,154, 85,240, +146,245,177, 57,137,186,222, 8, 28,170, 28, 47,170,153,156, 55, 60, 3, 51, 5, 17, 98, 78,201,219,254,249, 44,213,151,145, 84, + 12,175,144, 18, 18,181, 80,224,203, 64, 8, 99, 78, 98, 52,141, 24,104, 51, 70,121,150, 60,129,181, 1,251,217,221, 20,120,108, + 66,167,216, 87,199, 97, 15, 1, 51,223, 25, 89, 80, 50, 2,227,107,129,152, 14,194,225, 88,148,137, 72,163,209, 24, 2,243,152, + 9,181, 83, 69, 2, 35,128, 91, 3, 0,149,120, 70,163, 58,101,207,167,196,136,127,177,219,129, 48,218,122,124, 70, 2,164,246, + 69,181, 35, 89, 6,224,192,109,184, 46,135, 60,101,172, 82, 45,130,109, 65, 34, 93,216, 9, 13, 48,101,198, 82,141, 83, 38,109, + 22, 32,175, 5,211,190,192,126, 4, 89,196,158, 48, 85,201,103,101, 13,160,106,169,176, 10,230,243,176,221,130,255, 62,158,216, + 49,171,112,176,196, 8,250, 16, 91, 31, 95,131,247, 42, 33,245, 37,101,115, 13, 33,220, 19,240,208,189,208,107,181, 63,149,212, + 18, 64, 94,223, 57,141, 24, 53, 92,223, 57, 19, 56,193,154, 88,138,160, 0,228, 45, 21,151, 1,245,170, 37,163,245,125, 31,173, +149, 40,197,168,116, 8,193, 41, 68, 15,246,219,131, 38,192,253,157,218, 90,207, 57, 53, 84,163,211,111,131,213,130,136,205, 31, + 91, 96, 87, 0, 38,202,185, 74,119,120, 2, 71,170,153,133,137,235, 81, 65, 8,131, 32,167,107,175,118,158,195, 69, 0, 63,168, + 51,236,136,201, 76, 14,151, 17, 84,211, 88,132,247,112,224,244,203,134,169, 80,241,204,238,128, 21,179, 70,231,205,131,230, 90, +227,238,222,209,174,143, 86,151, 95, 95,187,183,241, 98, 3, 78,209,168,214,117, 28, 83, 26, 92, 53,107,150,107,151,245,210,201, +160,139, 29,205, 36,190,113,249,166, 61,178, 22,141,197,189,227,125,179,100, 2, 6,249, 83,159,198, 49, 92,138,213,202,202,192, +161, 21,189, 82,212,138,219,159,183, 95,238,190,129,103,181,164, 22,193,206, 30,158, 28,130,115, 87,214, 13, 74, 69, 48, 69, 63, +172,182,235,122,195,104,136, 84, 70,152, 8, 5,251,175, 20,148, 66,199,234,192,197,180, 93, 39,159,213,235,102,227,253,151,119, +121, 77, 15, 66, 14,118, 82, 43,104,157,192, 66,233, 8,112,150, 69,249, 62,150, 97,200, 99, 66,158,108,238,172,111,181, 30,221, +106,220, 94,170,155,203,133, 99,219,193, 70, 81, 12, 5,201,166,139, 18,246,224,188, 63, 35,228, 41, 28,221, 30, 92,211,179, 16, + 7,250, 83,172, 25, 94, 55,139,101, 61, 51,246, 60,137, 39,134, 38, 43, 50,207,136,139, 16,250,195,144, 67,198,224,104,166, 15, +145,228,177,241,241,166, 84, 17,196, 66,118,193,197,144, 23,121,202,224,147,199, 34,111, 44, 18,209, 38,147,135,181, 7,228, 3, +190, 97,134,144, 15,188, 97, 1, 27,239, 41,132,179,245,234, 21,199,155, 28,117,191,193,138,189, 49,182,165,119,157,158,231, 3, +230,131, 7,129, 85,123, 31, 65,126,202,148,222,167,176,129,146,118, 9, 37, 21, 19, 9, 13,142,137, 75,198,115,245,209, 52, 61, + 34,119, 49,134, 63, 23, 8, 73, 64, 41, 76,126,165,233,218, 94, 20,115,169,222,142,139,223,184,249, 50,209, 92,240, 46, 98,227, + 87,168, 27, 20,253, 82, 34, 74,179,110,205,178,234,172, 81,142, 21,171,251,195,190,129, 5, 30,155,233,132,132,243,125,206,234, + 4,137,252, 83,197, 48,219,253,118,156,100,228, 89,230, 61, 1,247, 56,105,133, 76, 42, 8,179, 42, 94, 50, 10,251, 71, 12,254, + 41, 0,107, 87,211,211, 68, 20, 69,231,163,239,205,116,166,117, 44,180, 69, 65, 10,129, 20, 49,154, 64, 32, 36,198,196,149, 81, +255,129, 49, 49, 49,113,229, 95,240,103,248, 35, 92,235,130,141, 44, 84, 22, 26, 18, 19,217,152,232,130, 15,249, 46,133,150,218, +161,101,230,205, 71,159,247,190, 55, 83, 17, 93, 26, 54,132, 52, 37,211,153,158,123,238,125,231,156,139,249, 4,240,242,174, 18, + 42,255, 21,220,229,239, 84,163,114,186,114, 33,243, 61,171, 91, 44,246,120, 26, 55,159, 37,182, 42, 7, 85,127,109,122,186,128, +236,242,112, 89, 28,255,167,129,165, 73,145, 60,159,139, 38, 75,179,170,246,195,138,211, 27,157, 8,148, 18,254,254,123,238, 70, +160,143, 68,254,142, 80, 14, 32,108, 19,120,154, 59,210, 6,146,110, 3,195, 24,114,181,127,182,143,113,193,186, 24, 39,168,101, +103,228,208,221,181,136, 5, 52, 19,247,186,225,180, 4,229,212,210,202, 13,120, 25,218,208, 98, 75,192,206, 8, 2,173,166,222, +106, 97, 93,143, 81,129,110, 18,192,119,148, 14,235, 25,177,200, 91,228,201,163,216,130,106, 78, 30, 56,187, 32, 10, 26,143, 68, +100,163,216,143, 26,135,210,194,129, 55, 95,243, 60,241,176, 68, 81,128,204, 32,132, 38, 30, 58, 99,220, 59,140,183, 0,165, 38, +178, 15,132, 55, 14,224,115, 23,150, 15, 74,145,224,195,123, 5,177,140,121, 6, 14,171, 16, 93,129, 63,155, 6,190, 50, 70,129, + 60,135,175,238, 89, 35,186, 76,114, 62,139,135,115,149, 32,246,246, 79,246,198,203,213,227,147, 58,220, 47, 5,105, 20,250,235, +108, 60, 31, 67,215,183, 23,226,132,138,232, 70,192, 60,209, 13, 37, 77,141, 38, 84, 3, 90,202,142, 1,218,142,218,117, 51, 99, + 24,212,242,131, 14, 92,209,204,248, 44,180,204, 64,198,115, 89, 27, 13, 10, 58, 57, 5, 80,166,185, 14, 84, 83, 85, 25,114, 74, +237,174, 11,176, 46, 8,181,220, 72,195, 13,106, 12,230,224,235,189,143, 78, 63, 30, 15, 15,140, 30,185,135, 50, 59, 14, 62, 68, +161,146,146,193, 0,114,235, 23,254,220,155,189,191,184,242,134,162, 68,220, 20,177, 33, 56,201,198, 73,131,144,181, 73,209,130, + 92, 72, 0,109,207, 37, 51, 7,229,181, 96, 57,113, 4, 52, 61, 4,202,108, 17,195, 34, 38,144,234,131,230, 1,193,134, 8, 58, + 42, 77, 36, 67,224,252, 64,238, 24, 26, 43,143, 53,220,230,194,212,124,164, 41,203, 95,222, 3, 20,206, 85, 23,198,135, 70,223, +174, 46, 21,242, 3, 68, 37,235,181, 53,184,132,162, 83,118,125,151, 49, 95,196, 42,170,149, 82,101,175,129,123,121,110, 79,207, +253, 56,220,110,158,182,224, 10,160,129, 0, 4,207,103,243,226, 32,196,191,113,109,234,235,246,247, 17,168, 64,161, 87,255,121, + 60, 86,174,192,149,109,212,214,108,195, 10,123, 76, 79,196, 95,153,199,211,131,203, 7,159, 62,239, 55,106,140,237,248,182,119, +230,215, 20,134,211, 27, 63,186, 83, 44,188,122,240,164,237,147,145,226,214,183,102, 11, 0,190, 11,125, 78, 20,191,222,114, 63, +182,253, 40,195,125,230,179,179,110, 20,178,231,147, 87,128,106, 88,148,206, 87,138, 58,197, 68,141,130, 77,243, 52, 35,173, 31, + 34,255, 20,158, 55, 53,228, 80, 46,185,135,193,170,226, 4, 42,177,188,234, 0,238,101, 39,111, 40,250, 94,179, 85,171, 95,223, +101, 17,197, 28, 20,148, 1, 76,152,163, 15,151, 94,240,119,124,103,177, 57,249,114,230,195,220,202,221,213,202,211,155,143,158, + 77,220,218,236, 52,138, 57, 39,226, 81,171,227, 42,152,248, 36, 83, 10,208,190, 90,114,202,235,245,109,252,119,112, 39, 48, 85, + 31,109, 37, 0,155, 1,138,146, 25, 23,125, 6,110,112,199, 51, 85, 97,127,146,146, 21,168, 67,188, 15,238, 18, 75,226, 11, 22, + 31,174,240,254, 16,231, 55,150,247, 18, 75,148,154, 74, 21,123, 50,175, 82, 48, 45,158,156, 54, 99,105,128,146,236, 49,175,122, +181,186, 81,223, 20, 83, 29,121, 96,193,133,122, 25,173,218, 38, 49,161,162,151,242, 37, 32,221, 44,244,207, 27,120,248,185,153, + 12, 79,214,230,197, 82,164,217, 75,195, 87,196,182,133, 94,178,184, 90,253, 3, 70,101,231, 36, 26, 38,169,173,255, 7, 85,254, + 37, 0,105, 87,206,219, 68, 16,133,189,167,119,125,237,250, 74,148,120, 19,132, 72,162, 32, 19,132, 64,136,130, 67, 10, 17, 74, +145,159,129, 68, 73, 65, 71,151, 63, 64, 77, 79, 77, 19,241, 35, 40, 64, 74, 69,129, 34, 10, 39, 36, 78,236,196,199,222,179,215, +240,222,140, 47,104,145, 82, 56,138,237,172, 61,243,222,188,247,246, 59,230,243,153,255, 76,238,255, 76, 85,120,106, 94, 80, 32, + 88, 28,188,208,132, 78, 66,139,255,158, 32,223, 44, 94, 4,185,211, 25, 72, 55,199,209,163,156,117,135,222, 23, 16, 33, 12, 20, + 42,176, 9,143,196,117,237,202,154,145,176, 69,153, 40,137, 45,154,189,178,202,180, 94, 94,242,161,251,155,177,123,167, 12, 10, +120,104,232, 38,255, 19, 63,207, 75,154,225, 78, 72, 98, 92,113, 67, 84, 36,228, 94,113,238, 47,188,230,254,237,135,110, 96,231, +149, 2,252, 31,216,176, 94,228, 32, 95, 14,141, 50,112,241,176,116, 17,185, 89, 11, 21,139,138, 13, 49, 19,101,136,219,166, 76, + 34, 21, 71,144, 18,210,187, 37, 89,215,148, 34,100, 11, 89,102,146, 30, 18,130,228,209,197, 0,159, 0,219, 36, 10,227,166, 81, + 41,228, 85,123,236, 48,143,110, 45,131,248,195,123, 90, 18, 90,253, 49, 41, 95,214, 42,202,186, 44, 85,205,188,161, 83, 69, 76, + 15, 94,190,120,255,238,237,171,231, 79,123,189,171,110,127,168, 32,122, 68, 96, 19, 77,148,171, 65,212, 57,126, 28, 68,131,179, +100, 75,209, 55, 66,194,154, 29,167, 66, 50,254, 64, 91,205,119, 29, 60,153,196,153, 23, 82,226, 65,112, 42,113, 74,110,156, 27, +219,179, 33,128, 52,169,208,183,123,156, 68,172, 43,232,111,238, 68, 30,137,160,153, 78,185, 50,149, 42,231,241, 83,208, 40,155, + 75, 32, 97,185,193,102, 66, 80,253, 41,136, 89,132, 3, 21,195, 18,206,134, 18,172,126,119,120,241,102,255,245,183,147,239,105, +150, 68, 41,105,150,151, 73,140,100, 49,120, 73, 68, 66,184,106, 72,247,119, 86,182, 6, 78,159,178,252,142,121, 53, 39,141,252, + 65,142,137, 50,112,251, 8,136,193,189, 7,251,191, 7,167,155,171,219,189,209, 69, 69,175,194,162,104,138,142,170, 79, 12,238, + 87, 84,139,110,232, 75,146, 28, 68, 62,115,241, 21,152,232, 78, 26,103,137,138,146, 35,200,210,132, 86, 12, 14, 18, 72,148,138, +172, 56,254, 88,100,158, 38,121, 85, 29,123, 3,143,248,142,111, 15,220, 1,172,238,206,122, 27,178,191, 27,186,108,248, 74,161, + 85,181, 26, 86,165, 0,155,199,131,134,227,236,250,188,115,217,177,234,107,186,174,245,236,235,227, 95,199,112,230,193,119, 93, +214, 42,207, 30,239,153,181,229,147,211,159,112,104,181,215,218, 27,173,141,213, 90,171, 94,169,194,151,185, 84,109,192,102,187, + 28,246, 35,244,166, 48,225,173,130,152, 64, 95,130,182,145, 73,212, 29, 93, 65,233, 58,244,198, 46,226, 8,232,208, 27, 13,209, +110, 2,157,197,160, 97, 16,217,205, 59,141, 42,187, 91,185,227,203,243,115, 39,240,227,120,187,176, 98,153,102, 83,211, 74,178, + 0,167,130, 34,234,187,235,237,140, 6,195,172,103,199,177, 38,201,200,106, 71,176,145,104,200,122, 19, 26, 67, 18,186, 4,202, +250,108,167, 94,122,212,106,222,109,153,229,130,104,153,170, 85, 45,212, 74,106, 81, 23, 81,120, 78, 22,152,163, 25, 15, 87,145, + 17,209,185,148, 54,142,159, 97, 37, 84, 65,174, 21,181,181,186,241,163,211,247, 51,146, 79,107,221,144, 41,220, 98, 93, 38,187, + 1,249,114,246,245,240,227,225,167, 15, 71,221,142,189, 89,107, 29,141, 62, 31, 88, 79,100, 33, 9,208,208, 46, 64,191, 83, 20, +239,197, 11, 35, 89, 20,167,105,152,198,208,151,160,129, 49,148, 48, 52, 9,209,221, 38, 50, 42,117, 59,112, 98,148,185,164,140, + 12, 73,225,232, 41,106,232, 87, 7, 11,114,239, 86, 27,182, 43,134, 56,175,236,231,120,131, 69, 26, 13,110,214, 92, 54, 19, 21, +248,235, 54,229,170,185, 98,163,143, 57,157,170,251,206,245, 18,232, 20, 79,148,161,214, 83,172, 41,121,135,248, 97, 68, 88, 78, + 74,172,218,154,139, 38,195,108,120,143, 48, 0,220,231, 28,205,169, 74,106,163,220,112,152, 61, 58,175,237,167,153,157, 78, 32, +145,217,100, 96,207, 80,156, 41,211, 78, 72, 39,151,199, 92, 50,115, 76,143, 95,152,112, 58, 57,166,126, 38,134, 40,206, 20,238, +103,169,239,143, 0,172, 93, 57,111, 19, 65, 20,222,217,219,187,222,196,193, 9, 73,192, 9, 71,140, 8, 1, 1, 10, 17, 13, 8, + 33, 14, 33, 26,254, 1, 5, 66, 8, 4, 18, 66, 66,116,180,148, 52,252, 7,104,248, 9,180, 20, 52, 68, 8, 66,136, 16,135, 33, +167, 99, 39, 89,219,123,120,246,228,189,231,221, 96,137,150,206,146,237,230,105,230, 93,243, 29,255, 39,191,255,155,235,165, 62, +174,169,152, 75, 50,238,154,129,176,140,225,204,250, 12,249,254, 58,243,229,219, 22,150,255, 87,220,253, 42,127,182,166,141, 31, + 52,199,170, 9, 45,176, 72, 30,140, 16, 13,233, 47,187,172,191,222, 96,240,168,200,247, 25,133, 19, 88,212,210,139,221, 40, 32, +126, 90, 2, 25,132, 54,248, 73, 23,253,203,211,158, 15,100, 86,203,115,210, 91,130,144,216,120,125,103, 5, 46,182, 23,185,170, +172,122,104,227, 18, 19,103,129,220, 7,196, 76,161, 19, 50, 78,101,239, 48, 51,137,130, 43, 75, 18,203,112,148,144, 91,139,134, + 98, 21,112,235,141, 32, 21,184,151,113,138,246,201,104,210,130, 53, 27,197,246, 68, 6,205,249,141,235,151, 95,191,122,121,251, +206,189,153,106,117, 97,225,203, 70, 3,213,133,112,169,162, 39,208, 34,193,141,230, 92,132,126, 81, 87, 37,195,144, 57,143, 29, + 39,190,123,235,238,195, 7, 79,118,118, 58,163,163, 99, 16,220,197,165, 47,186,154, 90, 80, 66, 52,193, 44, 40,184,209, 71,180, +131,192,131, 16, 10,140,215,133,154,195,134,135,138,174,227,226, 18, 39,149, 66,124, 60, 70,199,240, 32, 64,173, 63, 24,166, 73, + 98, 67, 80, 34,205,144,116, 33, 18, 53,201, 32,183, 13,191,141, 6,214,184,165,209,101,203,237, 58,112,170, 90, 30, 2, 6,136, + 12,204, 70,172, 49,135,119, 2, 42,225,100,197,140,211,136,161,154,170,170, 35,117, 8, 23,190, 1, 34,145, 16,153, 46,102,160, + 98, 33, 86,152,252,177,246, 41,140,120,177, 48,112,172,114, 28,126,179,221,105,218,158,205, 67, 15,250,116, 30,186,144, 97, 2, +178, 54, 30, 48,172,110,224,193,121, 55, 21, 67, 87,140, 1,221, 34,115,109, 31, 18, 40,228,223,122,187,222,113, 91, 91,237, 77, + 56,249, 17, 42, 33, 38, 80,137, 53,133,180,166, 19, 68, 67,145, 82,113,112,241,228, 85, 68,244,163,158, 27,250, 10, 26,106,209, +210, 44, 31, 81,228, 17,146,234,133,244,220,204,133, 61,197, 18,143, 2,164,238, 50,182,111,104,159,235,123,131,230,224,217,234, +153,241,210,216,217, 35,115,191,154,203, 37,163,184,229,218,166,110, 78,141, 30,110,118,182, 39,134,247, 55, 58,141,243,179,151, +150,126, 47,138,178,148, 32, 17, 25, 45,218, 53, 89,245, 33, 71, 17,159,101,221, 94,255, 90, 91, 92, 89,175, 65, 67, 13, 23,247, +244,225, 83,243, 63, 62,252,216,248,254,179, 94,179,189,214,102, 11,170, 23,219,114,182,169,117,100,179,213,217,213,237,181,233, +137,163,156, 7, 26, 68, 15,181,209, 17, 73, 43,228,202,180,187,178, 38,149,242,193,222,155,173, 46,176,107, 39, 10, 31, 86, 55, +235,190,111, 7,220,148, 76,168,230, 48,124,250, 81,212,230,221,101,199,189, 60, 33, 44,117,190,189, 95,219,120, 83, 91,134, 63, +140, 89,150, 44,166,221,152,125,179,121,147,123, 43,237, 78, 59,228,101, 81,188, 63, 87,157, 30, 55, 38,203,234,228,158, 66,121, + 64,131, 64,195,168,146,249,187,246,124, 69,122,211, 48,126, 64, 37, 3, 69,150,224, 40,154,154,108, 41,202,222, 82, 97,250,208, + 72,219,225,159, 87,155,216,235, 71,197, 53, 31,154,247,100,116,112, 92, 78,196,133,230,242,124, 99,231,233,179,199,207, 31,189, +152, 51,175,108,201,181,183,238,187,155, 83, 23,166,246, 87, 86, 26, 27, 9, 97,216, 73, 95,131, 8,215, 9,186, 84, 67, 66, 12, +211, 4,226,236, 4, 46,106,240,197,193, 72,105,188, 97, 55, 97,166,193, 11, 73, 88,153,152,156, 81,113,210, 34,129,204, 58,130, +208,205, 48,142, 51,166,110,102, 59,202,250,229,211,169,247, 76, 13, 5, 5, 38, 33, 53, 12, 25, 67,136,207,206,243,187,195, 29, + 56, 87,147,195,147,109, 56, 51, 4,229, 32, 3,208, 36,127,180,203, 38, 72,168, 88,208,149,163,241,175, 72, 14, 52, 17, 34,232, +161, 93, 16, 51, 81,131,222, 38, 65,164, 85, 12, 9,243,133,110,146,102, 60,171, 60,179,247, 38, 1,198,242, 7,109,210, 4,194, +142,172, 82, 62, 96,187, 45,146,116,143,123,142, 58,189, 68,152,236,130,199, 83, 50, 76,207, 8,252,255,234, 15,164,127, 4,224, +236, 90, 90,155,136,162,240,204,100,122,103, 50,147, 87,155,164, 77, 31, 86,105, 23, 34, 82, 68, 20,171, 45,136,245, 85,186,213, + 77,197,130, 10,254, 0,113, 99, 43, 5, 41, 86, 80, 43,110,252, 13,238, 5, 43, 10,130,197,109, 17, 69,169,233,203, 54,109,236, + 43,125,216, 36,109, 50,239,137,231,220, 59,233, 67,116,227, 38, 4, 58, 73, 39, 51,115,207,253,206,249,206,249,190,255,140,239, +252, 63,156,247,132, 61,145,125,111, 53,234,175, 88,223,147,107,223,157,149,222,253,107,121, 27, 16,248,114,136, 71,154,158, 99, +182, 52,130,224, 77,104, 48, 98,194, 97, 83,191,172,132, 65, 65, 12,162,103,218, 23,225,148,255,147, 64, 89,211,253, 57, 6, 54, + 74, 26, 59,103, 81,214, 34,230, 98,129, 56, 17,101, 29, 17,220,142,129, 8,110,161,241, 80, 77, 17,160, 31, 37,146, 0,217, 33, + 40,199,108,203,221,213,173, 7, 48, 43,250, 75, 56,135,129,117, 70,191, 36,233, 60, 36,188,120,147, 9, 17, 67, 10, 9, 98,115, +184, 40,201, 40,213, 4,123,176,129, 70,105,156,136, 34,218,130, 31, 14, 8,144,136, 42, 87, 5, 17, 37, 53, 84, 71, 6,250,239, + 15, 15,191,126,251,102,248,124, 71, 71, 87,103,231,228,228,248,194,210,138,128,189,125, 62, 42,245,134,145,154,214,241,125,186, + 97,111,229,141, 27,221,221, 61,221,215, 30, 63,127,250,104,104,232,195,200,200,212,143,105,219,210, 58,218, 90,111,245, 92,227, +108,243,103, 58, 29,137,132,158, 12, 12,118, 93,188, 52, 54,246,173,160,105, 82,133,248,240,222,221, 7,125,189,156, 99, 36, 39, +146, 33,149,120, 94,132, 37,142, 32,107, 6,123, 12,222, 86, 88,207,168,241,162, 89, 16, 19, 33, 60,233,150, 65,133,243,121,198, + 75,195, 34,140, 5, 98,121, 29,194, 61, 58,240, 21,141, 66, 99,180,105, 45,151,129,243, 2, 12,206,151,105, 11, 69, 14, 80,219, +116, 8,207,214,213,246,238,116, 38,133, 77,214,116,126, 10, 64, 73, 44, 92, 13,175,244,126,113,248,158,227, 82,153,217,173,237, + 92,133, 72,162,129, 56, 21,221, 54,153,100, 63,124, 63, 74,226,241, 56,147, 2,143, 0, 26,216,219,186,230, 24, 16,130, 77,219, +170,141,212,174,231, 87, 81, 45,192, 31,150,137, 31, 22,167, 69,199,211, 0,106,194,241, 33, 53,162, 91, 91,176,146, 73,133, 4, +113,127,122,113, 28,182, 1,221,210, 79, 52,159, 90,216,152,131,144, 81, 52,177,125, 75, 38,202,133, 99,231,146,243,223,179,133, +205,197,181,180,201, 42,189, 28,159,211, 54, 41, 57, 15, 9, 77,113,126,117, 62, 81, 89,251,101,246, 43, 60, 39,217, 66, 22,190, +115,109,123,173, 96,104,112,113, 76,199,254, 52, 49,122, 32,222, 8, 89, 2, 44,201, 68,164,186,165,245,236, 92,106,202,176, 12, +166,165,162, 16, 37,232, 15, 73, 68,129,231,170,237,200,233,177,185,228, 82,118,153,230, 61, 76, 78, 28,187,215, 33, 88,208, 31, +171,205,103,210,186,109, 45,110, 44, 65,238, 18, 86, 35, 13,241, 70, 20,182,165, 23,178, 46,154,128,140,193, 47,225, 96, 54,234, + 48, 27, 57,129,179,149, 64,101,172,100,159,108,175, 94, 89, 94,207,106,198, 38,100,142, 46,175,217,216, 45, 91,116,204, 77,189, +168, 89,238,229,250, 68,173, 42,181, 36,212, 32,192, 3,135,171, 81,225,100,124, 49, 69,121, 63,147,153,201,101, 21, 95,233,230, +225,134,103,157, 71,207, 52, 65, 78, 33, 87,133,100,212,127, 6, 32,131,234,192,108,214,147,247,220,154, 41,181,200, 4,230, 32, + 27,132, 36, 50, 32,145,176, 34,214,132,148,250, 67, 81, 78, 37, 31, 71,103,117,202,223,248, 92,145, 8, 7,215,225,106,219, 86, +128,247,191, 75,125,142,185,205,183,251,175, 15,246,189,184,211,220,251, 42,251,114,214,158,187,146, 56,158, 41,254,202,107, 5, +151, 42, 65, 50,250, 20, 94,209,162, 26, 93, 83, 28, 88, 43,120,121,113,199,118, 13,122, 64,193,212, 18, 85,117,121,236, 66,113, +131,114,144,170, 92, 20,217,228, 45,139, 25,164,130,192,231,104, 29,195, 43,199, 51,219,104,151,250,243,185,204,107, 26, 25, 41, +131, 22, 47,225, 87, 72,186, 87, 63,241,228, 99, 32,238,230, 0,137, 99, 67, 13,150,197,235,163,245,240, 65,195, 50,189,114, 60, +133, 47, 14,150, 48, 61,211, 60, 10, 21,144, 0,243, 70,239, 4,143,191,197,193, 43,236, 0, 98, 5,134,114, 80,167, 21, 30,106, +187,194,148, 50,188,162,144, 91,166,111, 33, 53,217,210,242,216,211,230,148,254,176, 60, 45,167, 26, 92, 84,141,138, 62, 98, 58, + 58, 35, 21,246, 69,119,154,211,252, 22,128,180,107,249,105, 34, 14,194,221, 87,183,219,221,237,210, 71,144, 74, 65, 8,104, 36, + 6,149, 16,137,122, 17, 16,163,248, 56, 25,189,112, 50,158,124, 4, 34,222, 52, 30, 76, 52, 17,189,120,225, 79,240, 74, 60, 24, + 19,143, 18, 81, 36, 33,190, 79,196,168,168, 17, 75, 88, 90,182,221, 95,187,219,237, 58, 51,219, 34,200,209,235,166, 73,187,219, +157,153,111,126,243,205,247,253,111,126, 15,146,187, 2,197, 27,169, 44,149,205, 42, 96,220,230,140,254, 47, 66,167, 17, 6, 47, +135,148, 8,175,151,113,149,148, 95,191, 30,170, 99,246,122,105, 10, 76,122, 1, 25, 7,255, 30, 79, 28, 12, 62,169,165,160,111, + 13, 36,148,214,235,132, 31, 10, 78,221, 56,175,110, 90,194,133,182,110,233,214,114, 55,183,165, 0, 1, 6, 96,174,173,146,192, +116,221, 30,215,111, 52,210,217,252,175, 64, 56,169,182, 49, 65,108, 29,180,250,227, 4,250, 24, 78, 95,136,187,229, 11,184,253, +227,199,117, 89,209,112, 96,202,211, 30,170, 72,195,110, 36,156,160,216, 28, 79, 14,206,168, 61,128,114,237, 50, 15,216, 7, 64, +189, 34, 87, 85, 37,228,148, 10,195,199, 7,154, 51,233,123, 19, 15,230,230,223,205,188,154, 61,212,119,112,240, 72,255,199, 79, +111,172, 53, 51, 44, 73,213,170, 80,161, 89, 15, 20, 27,199,245,151, 87, 10,231,206,156, 26, 27, 29,191, 59,113,127,234,201, 51, +232,168, 35,138, 40,137,126, 42,161,142, 94,185, 60, 48,120,162,189, 99,231,212,227,167,125,189,125,151,174, 93,111,223,213,181, +180,248,237,245,252,219, 68, 67,114,124,108,180,165,173, 53,174,201,211,211,207,203,184, 20,136, 16, 69, 8, 76,206,137,142, 9, +105, 7, 57, 56,142,239,187, 92, 68, 84, 29,183, 76, 68,163, 26,253, 23, 23, 7,145,192,224, 66,138, 33, 73, 35,180,106,242, 48, + 14, 33,204,188,168, 28, 67,109, 78,199, 14,102, 44, 46,250,142, 96,151,242, 37,251,153, 57, 69, 28, 60,243, 33, 93,142,161, 3, +173, 24,182, 28, 11,144, 23, 96,231, 82,185, 8, 87,224,129, 73, 97,137, 14,238,188,238, 29,123, 57, 78, 88, 99, 57,234,163, 60, +146, 82,192, 49,134, 18,142,160, 97, 41, 49, 37,224,253,110, 80,227,170,172,159,191, 56, 50,247,114, 22, 74, 38,114, 79, 93, 71, +139,234,118, 25,202, 95, 57,157,108,206, 23, 86, 0,249,110,139, 55,231,109, 52,238,192, 6,133,124, 44,225,235,224,247, 36,117, +172, 43,169, 88, 35,132, 45,148,135, 95,230, 79, 28,131, 96,203, 69,143, 3, 67,215,235,104,234,176, 81, 68, 48,236, 16,135,167, +183,115,159, 34, 69,190,155, 63,200,119, 23,183, 15,161,155, 76,234,241,162, 83,130,122,147,103, 57,184,241,165, 92,118, 97,225, +125,177,196, 32,251,192,243, 65, 19,100, 59, 7,201, 26,250, 24,167,234,102,115,203, 0,207,113, 45, 65, 10,235,170,129, 42,243, +114,116,181,104,193,179,133, 10, 81,116, 11,200,152,226,133,100, 44,177,198, 10, 86, 9,208,125,150,196, 97,132,182,166,246, 37, +243, 55,128, 77,192,143, 24,188, 94, 73,164,113,124, 84,105,216, 81,173,116, 29,107, 54,204, 2, 84, 23,215,245, 10, 21,103,113, +173,176,104, 89,166,109,175, 48, 60,184, 24,217,221,178, 63,173, 37, 52,145, 49, 47,173,199, 57, 65,100,174,211, 32, 42, 31,127, +152, 23,122, 50, 15, 79,119,159, 61,220,150,222,174,201, 49, 17,143, 14,137, 99, 35,214,244,248, 54,144,201,130,128, 20,144, 51, + 0, 64, 65,149, 1,185, 75,134, 26, 78, 65, 61,104, 73,134, 90, 83, 31, 94, 44,124, 89,182, 0,237, 67,154,134, 96, 52,109,131, +121,222, 80,207, 64, 91, 60,115,103,230,209,112,255,201,225, 3, 67,183, 39, 39,111,117, 94,189,249,245, 70, 82,139,245, 25,153, +172,141,236,126,135,152, 89,136,223,145, 28, 80, 65,143, 17,175, 18,150, 85,200,176, 80,240,220,154, 68,187, 15,125, 51,164,250, + 85,150, 15,198,143, 54,196, 12, 43, 82, 6, 15, 40,228,168, 68, 66, 29, 18,161,145, 26, 65,210, 87,101, 85,139, 68, 88,169, 36, +241,226,158,204,158,156,101,210, 46,107, 77,160, 23,146,123,144,115,140,168,193,202,182,161, 24, 56, 15, 95,191,109, 52,226,171, +178, 10, 11,118,154,104,177, 4, 65, 53,100,156,132,154, 42,150, 45, 90, 74,168,110,244, 99,250,107, 36, 1, 97, 36,138, 71,187, +135,160,134, 6, 52,248, 58, 53, 31, 1, 78,149, 78, 8,235,154,101,190, 30, 49,200,205,220, 37,222, 71, 64, 7,173,145,243, 55, +184,101,112, 1, 30,128,176,130,247,106,125, 61, 55,196,215,183,129,234,201,254,143, 0,164, 93,207, 79,211,112, 20,111,187,110, +109,183,174,131,177,129, 3,212,145,128, 30,140, 81, 48, 30,184,169,137, 30,188, 40, 38,222, 60,171, 49, 18,239, 38,198,248, 23, +200,197,131,209, 35, 49,209,120,243,162, 30,140, 9, 9, 1, 76,188, 40, 4,228, 87,128, 1, 27, 56, 86,182,174,107,187,246, 91, +223,123,223, 65, 48,241,230,133, 75,211,140, 54,253,190,247,121,239,125,222,231, 35,255,255, 88,149,100, 63,153, 27,122,226,191, +212,219,197,127,247,111,240, 62,178, 14,107, 74, 66,196, 16, 59, 92, 1, 23,243,142, 24,107,136,135,156,152, 68, 52,105,163,109, + 8,223,102, 34,249,112,212,141,241,224, 89, 76,107, 79,228,210,105,152, 78, 37,146, 61, 13,248, 54, 65,136, 75,158,124, 49,138, + 1,226,131, 43, 68,190,254,203, 25, 48, 60, 50, 83, 17, 15,100, 39,209, 54, 4, 61,227, 93, 90, 3,195,248, 6, 1,173,100, 22, +242,157,253,107,187,171, 33,249,181,250,156, 20,132, 29, 9, 63,100, 71, 20,137,165, 64,226,209,145, 20,178, 19, 42, 28,143,144, +202, 39,228,104,123, 7,114,209,232,102, 71,168, 7, 85,156,100,222,170, 66,186, 31, 64,249,219, 55, 71,224,226,229, 43,151,222, +140,143,195,131,245,228,178,150,181,251,124,236,217,232,195,251,143, 30,220,121,241,242,213,230, 86, 57, 20, 20,196, 37,162, 92, + 7,216, 86,173,157, 59,115,246,201,227,167,239,222,191,253,252,229,107,187, 17,143, 70,112, 54,234, 53, 25,202,115,199,147, 82, + 76, 57,214,217,109,232,154,200,188,166, 85,145, 81, 78, 62,128, 90, 65, 87,131,114,105,189,167, 55, 83,183,126,167,146, 88, 97, +192, 63, 6,119, 81,163, 11, 93, 88,233,132,132,114, 76,136,170, 66,213, 10,108,175,202,149,248,112,102, 31,132,173,109, 98, 49, +116,221,134,136,202, 24,168,196, 11, 73,183,222,168,101,219,115,165,202,166,229, 86, 61, 63,102,196,219, 76,123, 15, 15, 44,126, +213, 88,224,227, 24, 3, 21,196, 80,193,209,149, 28, 1, 69,251,108, 45,154,112,253,134, 18,137, 29, 46,193,163,110, 10, 99, 89, +163,109,165,184,196,219,145, 1,145, 13,226,112,212, 67,162,134, 75, 44, 10,152, 95, 86,224,140, 13,230,135,126,174,255, 88, 41, +254, 90, 26,155,135,183, 9,105, 38,161, 25,131,167, 47, 76, 45, 76, 66,126, 61,223,119,113,118, 99, 22,112, 49, 36, 89, 0, 68, + 90, 84,243, 66,151,150,173, 34,168, 52,200,208,222,107,223,170, 64, 37,132,205,116,230,127, 91,156, 2, 20,207,169,114,253,185, +129, 29,179, 8,249, 70, 87, 52, 26,157,133,233,100,135,227, 54,150, 75,171,133,242, 54,214, 40, 68,129,226,218, 38, 80,230, 20, + 77,215,245,156, 74,104, 58,190, 31, 33, 43,237,180,110,236,219,150, 13,200, 84,132,112, 95,114, 60, 23,158,171, 45,145,130, 40, +111,218,213, 48, 34,161,155, 35,115,246, 81,178, 70,144, 28, 41,155,202, 42,178,186, 81, 46,248,126,211, 48, 82,128,154,213,152, +174,197,204, 19,185,190,226,238, 54,164, 13, 56,252, 11,133,249, 91,195, 35,139, 91, 75,115, 27,115, 9, 37,174,199, 13,207,179, +240,253, 70,212, 62, 35, 16,122,218,187,134, 78,222,232, 77, 14,174,165,191, 23,118, 38,215, 74, 19,155,254,114,165, 37,250,186, + 93,179, 79,117,228, 23,138, 59,237, 40, 73, 8,232, 30,242, 96,144,201,200,175,239, 13,167,251, 13,100,184, 96,207,138,225, 95, + 31, 29,206, 80,219, 0,209, 68, 32,161,240, 26, 20,143,212, 72, 71,187, 14,177, 69, 60,144,120, 83, 62, 34,105,170,144, 51,132, +238,204,218,167,185,153,133, 45, 69, 85,225, 43,242,208,146,195,246,253, 70,189,217,248, 48,243,113, 64,207,155, 66,101,244,234, + 93, 97, 66,208,133, 76,103, 74,222,113, 86,174, 31,191, 6,167,200, 97,220,132,143, 12, 73, 48, 97, 50, 35,110, 64, 16, 55,189, +253, 38,166, 67,159,202, 93,252, 42,136, 41,198,186,210,185,205,202, 22,225,125, 38,178, 86, 55, 55,174, 40,249, 76,126,182, 48, + 75, 26,199, 7,106, 53, 7, 60, 14,159,111,127, 67,225, 30,120, 43,187,171,205, 22,151,157, 70,235,140,198,255, 34,199,110,162, + 26,213,114,233,158,218,182, 69, 35, 25,129,134,199,130, 69,251,122, 98,171,143,194,237, 96,177, 42,171,212,202,100, 15,223,242, +124,208,181, 20,132,123,106,231,144,151,132,196, 77,146,253,233,197,105, 78,230, 38,108,132,175, 46,224, 45,124,244,159, 50,224, +235,170, 59, 85,248, 93,211, 46, 19, 71, 3,139, 15,234,201,180,180,110, 14,119,140,184, 65, 43, 53, 29, 32,166,161, 43, 3,250, + 79,241,235,236,136, 61, 19,221,249, 71, 0,206,174,237,181,105, 56, 10, 39, 77,210,230,214,166, 45,221,173,178, 21,167,200,234, + 30,188, 81, 20,145, 13,113, 94,112,226, 63,225, 31,178, 23, 81, 4, 21, 20, 20,223,124, 81,240,194,116, 47, 14,113,204, 23,159, + 68, 28, 67,112,194,196,173,157, 91,177, 91,187,166,109,218,166, 77,218,120,206, 73,210, 9,123,243,165, 80, 8, 73,147,230,119, +126,223, 57,231, 59,223,247, 63,248,157,221,167,216,238,236,209,231,247, 85,248,253,111,190, 71, 43,231,131,116, 26,150,102, 4, +141,141,181,225,214,152, 38,245, 30,123, 42,154, 61,164, 31, 32, 9,130, 16,199,200, 2, 35, 10,168,171, 34,171,130, 22,130,140, + 16,103,169,105,174, 13,129, 22, 50,190,121,162,105,176,189, 90,189,219,227, 37,118, 13,145, 87, 4,219,243, 60,220, 27,128, 13, +203, 26,154,252,145, 87,189, 55, 69, 69, 71,192,106,119,136,194, 34,112,188,133, 61,121,182, 82, 47,211,195, 13, 48,190, 22, 31, +182,182, 1,145,178, 46,185,144,245,197, 81, 8,171, 51, 76, 76,147, 37, 73, 32,245, 74,172, 24,209,244,159, 67, 83,154,200, 62, + 84, 36, 54,172,242,138,196,169, 34, 58,219,209,132, 39,196,119,225,202,133,203, 87,167,175, 45,127, 93,122,246,226, 53,210, 64, +200,154, 36,191, 83,249,185,154, 61, 63,121,241,240,193,244,202,143, 85, 93,215, 67, 65, 64,109, 86,215,182, 38,206,100,238,223, +190,185,184,184,112,239,209, 99,132, 84,188,128, 77,153,142,211,178,186, 21,195, 76, 37,135,211, 99,227,243,243,239,222, 47,124, +108,214, 27,163,169,193,141,220,175,185,185, 55,112,181, 0,103, 27, 21,125,119,167,240,106,118,118,125, 99,219,178,185, 86, 11, +173,186, 1, 50, 89, 54,228, 16, 0,165, 29, 72,239,113, 62,217,236, 32,155, 31,189,143, 59, 46,240, 32, 4,239, 57,206,116,201, + 44,214, 43, 76, 82, 91,168,110,214,221,126, 63,236,148, 84, 57,105, 65,148,167,131, 59, 65, 30,227,166,141,134,186, 40,210, 64, +174, 97, 12, 74,188,217,166, 38,199,209, 68,201, 66, 94,176,235,142, 6,113, 15,158, 86, 73, 47, 2,226, 30,238, 75,233, 13, 29, + 22,188, 69,146,203, 54,214, 89,173,136, 20,213,164, 72,185, 94, 6, 20, 12, 64, 6, 9, 72, 28, 39,133, 20, 1, 18,130,102,181, + 92,219, 69,113,109,214,137,171,137,237, 74,158,176, 3, 7,152,174,105, 26,162,168, 68,148,136,200,139,222,216, 8,252, 55, 28, + 15, 96,153,188,238, 26,216,250, 14, 74, 81, 37,110,162, 90, 6,139,238,198,182, 21,147,163,110, 73,119,171,188,101, 17, 39, 39, + 44,135, 45, 11,126, 33,147,234, 59,200,195, 54,232,116, 53, 69, 43,232, 56, 64, 63,148, 72,102,198, 50,217, 63, 27,170, 40,195, +101, 1,140,231,182,209,163,117, 60,149, 94, 47,100, 93,134,149, 20, 84,170,102,173, 63, 50,128,174, 17, 1,231, 80,242, 72,201, + 40, 67, 0,130, 77, 2,194,140,129, 66, 61,184,174, 33,120,229,119,243, 45,219,170, 53,170,240,194, 67, 64, 57,122, 32,189, 89, +202,239,212, 74,155,165, 45, 77,213, 84, 9,242,170,166, 77, 50,191,176,138, 79, 74,124, 98,122, 4, 53, 35, 99, 65, 45, 25, 25, + 27,138,102, 18,234,228,177, 83,119,159, 62,153,185,126,246,219,231,229, 47,185,226,141,137,211,229,106,219,196, 70, 75, 27, 30, +199,137,209,161,244,165,180,148,142, 51, 10,199,132, 80,222, 15,149,132,121,183, 65, 22,240, 8, 80, 56,121,132,222, 44, 28,142, +109, 96, 64, 15, 10,240,168,225,213, 21, 66,162,192,171, 34,171, 73, 76, 42,193,164,250, 11, 31,190,191, 92, 88,113,104,188, 2, +179, 85,172, 61, 89, 49,126,164,212,198, 0, 0, 9,247,219,181, 79, 15,111, 61, 88,122,158, 93, 91,253, 61, 53, 56,117, 39, 55, +115,110,224,184, 26, 96, 13,108, 81, 32,159, 12, 62,197,144, 76, 37, 56, 20,206, 52,237,182, 24,148, 96, 91, 53, 90,117,155,172, + 60,176, 87, 5,160, 13,119,107,131, 20,216,229,152, 18,133,116,167, 67, 28,135, 2,100, 57,142,239,243,233,138, 0,147,158, 0, +205,153, 91, 45, 44, 48, 98, 92,193,137, 13,127,184,117, 79,112,214,179, 72, 69, 3,197, 98,173,200,120, 58, 97,248,142, 68, 36, +205, 70,194,112,199,237, 39,245, 36,192,232, 37,238,246,138,223, 29,178,112, 34,198, 99,192, 43, 40, 16, 34,114,176,176, 99,250, +132,119,170,216,120, 4, 29, 12,249,176, 70, 72, 81,188, 19,133,219, 52, 13, 56, 9,166,203,116, 57,223, 57,164,215, 0, 14,252, +211, 97,244,128,101,215, 27,228,242,251, 2, 30,145, 30,207,255, 87, 0,202,174,229,181,137, 32,140,207,238,102,103,178, 25,179, +217, 52, 77, 91, 75, 45, 85, 65,133,170,160, 32,222, 20,245,236, 69,193, 10,130,168, 80,250, 7,232,169, 23, 47,226,217,155, 39, + 15, 34,254, 5, 86, 65,240, 38, 94,234, 11, 65, 79,182, 70,234,187,175, 36,155,221,236,206,238,100,215,239,155,205,163, 74, 17, +132, 16,114,200, 38,155,205,206,204,247,251,230,247,248, 63,126, 36,167, 92, 81,203,147,191, 66, 86, 13,178,133,114,184,221,228, +222,123,173,111,233, 17,117,171,124, 3, 70, 29,106, 86,245,238, 46, 60,217,218,208, 70, 3,243, 76, 19,150, 73, 85,179, 62, 12, +213,204, 2,204,242, 12,233,107, 77,185,217,146,174,150,245, 47, 85,146, 40,178,148,212, 53, 77, 50,231,126, 68, 9,216,124,135, +241,140, 44,120,109,224, 45,140, 54,161,249,146, 39,154,217, 69, 44, 23,134,234,237, 77,197,124, 33,168,232,193,254, 64,100,144, + 28,134,246,106,255, 82,227, 42, 5,109,218, 21,243, 17,221,164, 6,220, 1, 83,163, 21, 94,226, 94, 20,165, 57,162,136, 3, 80, +136,161, 85,122,158,233,184, 75,168, 44,103, 20, 36, 65,148, 34,162, 84,198,169, 8, 34,147, 25, 85,103,104,109, 99, 83, 8,105, +152,166, 98,115, 34, 72,139,165, 56,118,228,192,220,236, 28, 99,214,194,194,211, 23,175,223, 80,131,158, 57,125,106,230,252,249, +197,151,139, 55,111,221, 14,101, 76,169,169,220, 31,227, 28,250,253, 39,190, 47, 44,198,246, 78, 78,212,190,126,195, 54,136,105, + 56, 69,110, 24,137,148,130, 82, 42,162, 78, 16, 2, 2,214,130, 80, 38,120,118, 25, 43, 16,145,144, 84,238,218, 88, 60,192,125, +107, 38,177, 23,135,174,178,194,150,157,164,175,212,238,115, 81, 81,108,205,176, 14, 78, 58,127,236,197, 40, 94,135,195, 43,110, +184, 9,255, 4, 5,160, 98, 2, 72, 64,137, 25,140,210,108,195, 51,219,141, 46, 91,101, 55,168, 67,241,110,115,135,231,249,202, +250, 10,218,210,234,204, 64,170, 15,243, 80,173, 74, 78, 28, 60,243,252,253,179, 98,193,110, 5,216,190, 24,177, 71,224,200,186, +191, 1, 32,186, 30,212,237,188, 3, 72, 14,202,216, 0,160, 0,181, 92,228, 77,203,201,209,221, 48, 75, 5,210, 87,115,165, 86, +177,171, 41, 70,100, 88,181,159,159,224,131, 97,169, 88,115, 87,135,139, 85,120,103, 59,244,148,233, 88,162,167, 58,114, 82, 13, + 90, 64,175, 24, 9,167,196,233,142,182,240, 96,149, 98, 57, 76,177,114, 10, 37,138, 43,104, 4,197,175, 50, 46,214,218, 97,144, + 55,205, 32, 10,225,240,169,209,169,165, 31, 31, 81, 49,171,229,202,118,197,109,187, 33, 54,172, 58, 21,123,152, 51,235,203,250, +247,253,227,251,214,154,171,112,194, 48, 19,141, 58, 99, 77, 21, 54, 91,247,154,106, 32,146,201,202, 68, 40, 5, 38,107,219,229, + 40, 18,240,151,101,113, 91,234,110,132,175,192, 9, 18, 19,101,135,119,109,180,214,138,140,127,111,252, 82,132, 2,162,136,173, + 8, 7,195,142,188, 86,173, 78,223, 57, 78,154, 45, 34,124, 34, 99,210, 8,137,235,147,175, 27,100,246, 6, 25,153,126,112,229, +210,229,251,143,167,203,188, 76,233, 24,183,134, 98,113,253,220,133,125, 23,143, 18, 81, 35,217,174,173,140, 0,254,224, 35, 70, + 62, 37, 62, 96,193,143,148,176, 57, 78,186,169, 13,122,111,104,154, 74,226,145, 55,136, 93, 32, 59, 29,120, 94,126,248,234,222, +147,119, 6,203,149,224, 7,195, 53, 67, 98, 46,220, 81,112,248,158,229, 6, 43,155,124,113,245,243,163,149, 15,241,210,250,252, +201,187,251,217, 33,171,212,152,121,123,118,254,240, 85, 1, 40, 14,237,193, 85,143, 58, 77,138,156,251,129, 79, 25, 3,116, 40, + 83, 89,180, 74, 45,225,133, 17,204,119, 42, 23, 35,219,128,197,200, 98, 13, 57, 78,161, 7, 85, 26,242,149, 73,167,233, 55,160, + 2,131,165, 58,192,102, 75, 95,136,180,221,164,164,103,177,213, 3, 21, 84,150,253,163, 25,125,197, 80,207,144, 76,201,169, 96, +101,130, 10, 35,232,132,152, 38, 69,100,230, 77,159,244,236,228, 7,188, 26, 45, 29, 43,237, 84,234,132,180,239,115,219,205,158, +236,127, 81, 2,203, 31,172,142, 22, 96,184,236,243, 59, 10, 9,193,226,102, 26,230,152, 51, 94, 91, 95,214, 19,128,212, 5, 63, + 82,137,178,233, 95,173,117,181, 13,210,141, 13, 29, 16,126,180,129,138, 85,235,133,103,144,223, 2, 80,118, 53, 61, 77, 68, 81, +244, 77,167,211,153,118,166,118, 74, 41, 69, 8, 26,131,226, 82,141, 95, 81,227,194,133,110,112,169,184,247, 7,232,202,141, 49, +113,231,210,141,113,105,136, 9,193,176, 80, 19,220,155, 96, 76, 36,154,184, 32, 49, 37,128,150, 16,160, 80, 40,211,143,233,116, +190,199,123,239,107, 11, 24, 19, 99, 66, 87,148, 41,121,189,239,222,243,238, 59,247,156,255,203,239,186, 2, 11,221,228,249, 93, +248,147, 25,249,207,228,206, 15, 48,216, 45, 9,162,158,221,107,212,107,141,139, 44,118, 64, 79, 24, 79, 29, 18, 74,151,176,176, +163, 77, 79,157, 40,106,190,147, 1, 53,198, 87, 66,148,243, 74, 94, 78,136,149,246, 38,217, 24, 50,234,103, 33,129, 8, 54,161, +207,121,171, 60,197,227, 68, 53,206,199, 71,194,126, 83, 38,236,248,150,208,173, 72, 20, 14, 28, 25,172, 52, 54, 99,232,166,197, +191,236,136, 29,190,215,248,171, 68, 15,118,135,224, 36, 17,184,196,140, 68,110,230,104, 97,108,117,239,231,233,161,220,240, 81, +125,199, 2,156,196,196, 56, 4, 34,192,118, 65, 85,177,163,107,152,126, 27,133, 17, 69, 0, 65,104, 86, 37,225, 33,209, 67,247, + 52,128,178,128,224,208, 75, 60, 33, 97,205,146, 68,210, 42,128, 13, 44, 99,177,233,239, 27,152,184,115,247,250,213, 27, 36, 71, + 22, 65, 22,120, 63, 59, 59, 61,243, 14,114,129,166, 34, 26,245,188,208,180, 28,234, 95,134,124, 17,225,225, 34,221, 58, 35,163, + 13, 82, 48,242, 33,177,178,194, 94,113,225,141,104, 49, 38,136, 18, 6, 16,252, 21, 42, 18,147, 78, 54,132, 4, 64, 37,199,195, + 61, 20, 88, 78,212, 38, 97, 17,236, 20, 50,132, 80, 8,235, 56,185, 6,121, 5,154,164, 57,216,236,197, 16,130, 84, 8,255,155, +131,180, 34, 92,222,126, 45,103,180,234,176,241,134,179,199, 1,134, 91, 78, 3,126, 43,139,112,154,151,219,158, 73,162,213,104, + 2,183, 47,112, 74,185, 3,117,169, 36, 5,153, 9, 46, 31,194, 14, 72,222, 59, 64, 82, 59,245,205, 7, 51,133, 26,181,209, 21, +146,110, 30,233, 63,126,110,236,204,183,226,247,173,250,122, 92,140,183,156,214,147,137,167, 83,115, 83,165,173, 18, 94,178,121, + 80,249, 18, 28,245, 95, 28,187,188, 80, 90, 32, 15, 16,212,127,199,169,147, 88,152, 83, 7,224, 19,171,230,206,237, 11,227,213, +154,177, 84, 94,212, 83,217, 99,249,145,197,181,226,104,225,196, 90,101,117,176,175,176,177,179, 46,199,209, 77,241,236,232,249, +229,181, 31,240,156, 47,197,207,217,116,159,229, 88,212, 5, 16, 84, 37,229,250,222,216,208,169, 77,163,108,218, 45, 25, 15, 46, +174,150,210, 96,145, 12,179,150, 75,235, 46, 78, 9,168, 85,179,106,217, 22,234,169,213,183, 1,169, 66, 61,179, 93,211,197,226, +232,235,170,190,107, 86,229, 88, 60,147,214,125,223, 51, 45,228,216,161,253,157, 32,232, 73, 29, 0,108,169,178, 2,139,143,195, + 1, 9, 69,141, 39,235,118, 29,217, 44, 88,186,114,205,246,174, 34,198,160, 2,220,138,107, 55, 95, 94, 99,158,201, 96,233,224, +155,178,108,214,108,135,197,149,249, 37,246,118,189,254,252,211,215,131,209,155,103,172,226,108,179,132,193,230, 39,153,152, 64, + 13, 50, 56,196, 65,114,183, 93,230,120,248, 99, 67,174, 71,220,203, 45,224,123,185, 5, 51, 59,196,177,140, 19,119, 44,171, 2, +108,103,213,214,220,139,143,175,231,138, 74, 74,134, 42, 45, 73, 98, 20,198, 26,158, 95, 54,221,229, 90,115,209,104, 65, 4, 65, +189,116, 2,119, 98,248,254,204,135, 87,247, 46, 61,158,188,242,236,193,175,135,111,106,211,143, 78,142,151,237, 61,126, 99, 73, +254,146, 33,215,251,133,226,109, 58,240, 12,164,248, 6, 68, 82,163, 9, 86,244,219,241, 73,125, 8, 33, 71,215,167, 9,160,103, + 74, 73,151,141, 50, 22, 68,126,154,164, 91, 82,138,210,240,128, 6, 83,135,172,219,165,126,116,156, 81,225,173, 74, 66,145,197, +100,211,169,119, 68, 5,186,233, 29,144,193,198,222, 22,110, 13,129,187, 0, 50, 46,131, 31, 68,156, 81,211, 17,149,100,189,219, +185,110, 50,204,164, 50, 73, 41,185,221,128, 50, 76, 8,159,196, 83,186, 3, 58, 52, 68, 35,112, 1,196,142,217, 30,111,196,147, +192, 12, 60, 73,212,100, 21, 16, 64, 55, 73, 70,135,250,225,221,172, 69, 13,228, 67,198, 71,108,127,234, 7, 95,191, 5,224,236, + 90, 90,155,136,162,240,157, 87,146,153,201,163, 38,164,205, 75, 91,218, 90, 68,168,130, 59, 87,110, 10, 46,196,189, 32,254, 4, + 23,110,116,229,206,141,160,254, 12, 11,250, 11, 4, 87, 10,138,162, 84,170,174,180,173,109,109,243, 78, 51,153, 36,115, 51, 51, +153,241,156,115, 39,182,106, 17,116, 23, 72,152,201,220,185,247, 60,190,115,206,247,253,207,124,211,177,193,123,120, 72, 33,240, +167,113,199, 95, 97,131, 42,181,178,228,204,124,179, 95,147,126,229,130, 12, 17,103, 55,135,190, 35,133, 17, 83,132,198,116,234, +246,196,192, 34, 96, 19,101, 85, 74,123, 68,115,164,130,223, 40,186,162,167, 19,153,188,158,107, 58,213,246,168,205,168,219, 27, +169, 40,253, 33,165,249,254,196,135,135, 2,223,255,217, 96, 31, 96,231, 34,132, 24, 49, 48, 58,132,240, 78,134,152, 37,249,159, +232, 47,169,255, 69,225,190, 67, 53, 40,124, 44,156,121, 81,164, 74, 54,179,188, 80,104,112,206, 61,108,106,141,169,138,208, 91, +140, 39,112,215,193,193, 65,198, 98, 36,105, 12,227, 24,220,202,156,135,162, 77, 4, 99, 97,164,165,137,124, 49, 66,225, 72,121, +138,227, 78, 16,101, 38, 19, 74,229,100,169, 48, 93, 28,121,222,214,214,238, 94,181, 17, 40, 56, 25, 10,187, 15,101, 42, 3,240, + 19, 56,217,159,212,101, 19,108,140, 38, 2, 3, 38, 32, 36,148, 25,198,190, 69, 65,164, 45,249,180, 57, 73,198, 1, 23, 20,195, +118, 56,224, 46, 38,156, 30, 22, 67,241, 61,104, 49,198, 15,184,139, 67, 85,136, 19,155,137, 12,214, 60,132, 57,142, 4, 34, 34, +112, 83,146, 85, 18,130,149,130, 72,211,146,145,167, 68, 72, 71,213, 32,230, 29, 27, 49, 83, 65, 14, 38, 7,207, 79, 32,233, 9, +163,207, 45,156, 37, 70,150, 55, 89, 97, 81, 54, 76,151, 85,252,177, 91,201, 87,246, 91,251, 58,138,101,123,154,172, 46, 22, 79, +215, 14,170,220,229,144,131,139, 90, 22,228, 94,217, 84,182,222,173,194,202, 67, 86, 11,183,211,193,238, 41,138, 53,176, 16,207, +177,219,125,119,104,196, 12,200,151,145, 18,135, 15,224, 88,130,251,129,247, 43,208, 33, 98,235,196,163, 94,202,148, 7,110,223, +118,122,249,212, 52,214, 3, 70,131,108,242,132, 42,171,173,110,227,212, 76,197,178,173, 27,151,174, 63,126,185, 90,202, 20, 96, +185,150,230,206,190, 89,127,145,136, 27, 51,233,124,195,170,229, 82,249,190, 99, 67,220,189, 88, 92,216,172,110,192, 42, 65,204, +161,170, 42, 88,159, 98,174, 56,101,164, 63,109,127,246,144, 53, 87,204,220,132,243,133,249, 47,251,155,176, 61,102,115,179, 27, +245,141,114,174,180,215,129,103, 52, 61,226,135, 3,251, 53,165,167,186,195,158,134,179,110,216, 26, 8,254,201,140, 27,240,223, + 32,148, 31, 56,246, 82,105,233,123,107, 23, 30, 10,210,148,186, 85, 43,103,203, 77,187,142, 29, 74,241, 24,190, 94, 57, 40,141, +164, 91, 15, 86, 88,206,101,118, 15,146, 56,230,112,214,231,108,187,113,111,245,245,221, 15,213,223,246,238,237,139, 23,238,191, +122,143,159,182, 31,177,110, 31,203, 85, 62,169,179,130,149,135, 13, 58, 18,145, 59,106,160, 69,254,151, 36, 31, 73,254, 81, 69, +227,110,232,172,144, 97,233,100,231,233,218,229, 59, 79,222,113, 28,148,213,136, 30,192, 15,254, 54,150,126, 45,123,179,211,213, +158, 93,125,120,254,249,202, 88,175, 95, 41, 46, 91,254,240,220,220,153,183, 95,215, 4,165, 18, 69, 87,200, 15,234,122, 35,199, +225,211,179,149,250,183, 29, 8,118,168, 85, 5,167,150, 98, 90,188, 99,183, 5,165, 46,129, 48,228, 27, 36,201, 37,141, 58, 41, + 34,142, 22, 4,227, 88, 70,131, 53, 28, 32,151,178, 18,149, 59, 35, 54,119, 34,169,145,163,122, 33,105, 67, 80, 65, 1,109, 13, +141,135, 80,191, 6,100, 93,235, 59, 31,145, 35,150,148,236,198, 36,185, 18,132, 17,246, 35, 0, 20,240,244,173, 94,243, 8, 71, + 64, 4,152, 19, 0, 31,138,122,244,132,233,140,133,135,254,128,100,168,136,184, 70, 66, 21, 23, 95, 84, 77, 67, 41,156, 8, 87, + 77, 38,161,142,192,231, 17,120, 29,117,148, 76, 90,243,143, 99,132,129,123,252, 16,128,178,107,217,109, 26,136,162,158,212,241, + 43, 78,210,144,164,106, 69, 43, 74,145,232, 2,216, 33,177, 64,106, 37,186,134, 95,224, 7,248, 25, 86,236,249, 0,254, 0, 22, + 44,187, 5, 4, 8,181,234, 35, 77,218, 38, 77,147,250,149,140, 99, 15,247, 49, 78,121, 9,132, 20, 41, 74, 20, 79,102,236,185, +119,206,220,185,247,156,255,139,191,139, 63,201,103,151,138,186,255,191, 56,247,130,194, 23,231,120, 44,195,159, 59,164, 91,133, + 65,194,218, 44,152,161, 7,145, 59, 58, 54,147,174,165, 10, 75,197,245, 8,130, 56, 33, 51, 93,182,138, 71,100, 18, 99,219,121, +219, 93, 6,187,138,210,144, 53, 79,132,248,133,118, 39, 95,160,150,231, 33, 5, 76, 62,153, 17, 81, 37, 11,138, 21,161,255,223, +144,122,161,226,173,137,136,126, 44,156, 34, 85, 1,210, 78, 67,229, 28,150, 0, 82, 44, 97, 13, 30, 71, 42, 89, 42,155,214, 36, +197,180,162, 5, 60, 12, 4, 20, 15,192, 28, 19,203, 81,145,212, 64, 53, 40, 20,174,196,149, 1,214, 9, 64, 16, 4,178, 21,170, +223, 77,209,217,179,140, 24,165, 79,241, 30,142,196,116,250,195,240,203, 94,103,255,160, 59, 10, 37,248, 78, 7, 69, 77, 51,202, +177, 35,197, 96,188, 61, 24, 45,133, 47, 36,180,147,194,158, 22,129, 57, 21, 68,225,132,202, 40, 79, 6,124,189,137,124, 6, 37, + 11, 25,105,112, 66, 90, 11,162,204, 17, 38, 84,212, 18,120, 56,172,148, 9, 32, 58,146,164,246,103,193,224,154,126, 19, 96,120, +205,193,106, 85, 61, 77, 5, 73,109, 9,184,220,198,231,193, 21,203, 84, 98, 6,223, 48, 90,169, 59, 13, 3, 57,121, 18,150, 75, +131, 63,177,109,207,183,171,227, 40, 0,236, 25,203, 9,155, 9,113, 56, 51,173, 6,190, 63,125,248,236,211,241,103,199,178,178, + 44,117,236, 74,239,178,155,200,132,141, 1,186, 91,113,107,209, 36, 4, 87,206,150,192,208, 30,158, 6,192,121,184,248, 42,190, +100, 9, 36,202,112,207,249,104,189,225,183,110, 47,221, 25, 4,231,235,205,245, 81, 52, 98,153,226,178,229, 44,186, 72, 9, 2, + 91,129, 69,191,190,222,222, 24, 4,131,169,156, 84,221,218, 52,157,108, 63,216, 62, 60, 59, 58, 30,156,192,216,161, 53, 88, 40, + 59,167, 71,112, 47, 97, 57,159,226, 73,169,194,240, 14, 66,120, 21,198, 81,137, 24,167, 61,215,115, 29,100, 19,235, 7,195, 78, +191,235,185,254,140, 24,255, 41, 59, 58, 31,199, 87, 25, 13,161, 31,244, 55,111,222, 61, 60,239,180,170,205, 32, 30,123,182, 75, + 4,183,185,109,121,168, 28,147, 99,118, 74,197,241, 47,194, 33,224,125, 73,170,115, 96,245,181,202,162, 89, 42,131,107,131,221, + 82,187,222,190, 8, 6,240,155,105, 26,195,218,107, 65,255,189,230, 73, 56,124,108, 88,246,206, 50,170,105,179,166, 13,184,183, +186,187,181,177,180, 90,187,215, 29, 5,189, 96,108,193, 70, 28,229,139,213, 81,167,247,226,254,114,105,181,102,100, 61, 67, 72, +244,230, 42,215,164, 43,108, 13,152,255, 40,208,155,187,224,205, 45,163, 10, 47,219,104,120,198, 13,223, 88,107, 25,155, 43,134, + 52, 94, 62,127,253,228,213,187,238, 44,159,203,245,228,255,162, 28,249,152,236,238,169,221, 55, 7,239, 63, 36,111,235,166,189, +230,182,226, 44, 57, 28,116,240, 52, 11, 1,135,153, 42,105,155,238, 90,243, 22,204,171, 32, 14, 30,237,108,237,127,253, 6, 24, + 0,241, 15,213,178, 36,114,146, 9,158,130, 58,211,145, 20,129, 84,171,186, 20, 77,175,114, 22,246, 51,116,186, 33,124, 88,105, +172, 12,195,145, 54,126, 45,231,164,133,183, 43, 86, 21,204,111, 70,252, 2, 66, 23, 61,177, 37, 97,120, 18,238,243,233,248,140, + 67,217,120, 48,238, 55, 40, 88, 42,169,253, 60, 47,124, 49,114,215,136,235,130, 88,205,126, 40,174, 3,205,204, 97, 57, 55, 25, + 53,231,171,164,228, 77,240, 18,240,248, 96, 18,234,140,120,238, 5,159, 9, 48, 45,193, 47,130,121,185,118,240,133,244,133,161, + 7, 85, 48,142,205, 1,255,119, 1, 72,187,118,221,168,161, 32,122,253,184,182,247,229,221,152,108, 72,194, 18, 34, 81, 32, 5, + 33, 5,209, 81, 34, 16, 45, 53,252, 8, 21, 5,255, 65,141, 16, 13, 29, 63,129,160, 8,162, 75,162,132, 40, 36,118, 30,236,174, + 29,175,215, 47,230,204,181, 55, 9, 73,131,216,214, 15,121,125,175,103,206,204,156, 57,243,111,248, 93,187, 14,197,207,178, 43, +156, 72,209,175,156, 92,101,102,140,203, 55,184,160,236,243,215,201,132,105, 45,150, 15,203,106,249, 91,165,179, 80, 75, 17, 96, +199, 97,238,144, 41, 76, 71,147,165, 48, 90,134, 77,177,115,199,234,120, 77,239,104, 18,236, 69,123,104,145,229,194, 63,119, 61, +100,117, 30,173, 80,139, 71, 63,183,209, 27,197,167,236,149,174,213,190, 44,109,105,163,175, 47,207,234, 58,134,230, 88,141, 56, +137,148,161,207, 49, 24, 67, 99, 98,109,241, 96,229,225,198,238, 55,116,101,147,189,182, 9,184,165,134,110,160, 41, 85,215, 59, +142,181,220,239, 25,142,133,240, 27,173,204,132,107, 8, 21,177,118,134, 40, 27, 77,171,211, 50, 33,165,142,132, 18,124,155,106, +191,165, 13, 68,216,156, 54,176, 94, 73, 91,240, 59,213, 8,239,107, 49, 89, 90,172,191,102, 66,117, 0,238,193,150,154,106, 18, + 74,146,130,195,124,212,210, 13,145,219,200,141,226,144, 35, 53, 91, 98,184, 67,146,224,159, 78, 40,192,207,117,128, 16, 81, 56, + 22,154,205, 65, 46, 78,128,252,165,174, 91, 54,186,170, 83, 30,128,118, 54,197, 89,237,134, 60, 12,134, 81, 2,162, 16,210,179, +136,147, 75,165,208,207, 5,210,139, 43, 90, 22,197,121,156,200,159, 16,187, 68,214, 1, 87,117,111,238,197,175,250,134,233,168, +105,152, 45,217,164,219, 77,160, 78, 3, 37,181, 73, 26, 9,140,123,110,114, 99, 58,217,220, 6,212, 77,114,140,204,101,226,181, +174, 36,129, 20,119,193,129,193, 45,152, 76,147, 91,166, 76, 89,112,149, 21, 10, 81, 26,165,197, 50, 77, 11,217, 12, 19,146,103, +138, 5, 64, 87,119,154,110, 24,141, 75, 37, 35, 33,202,229,222,192, 31,238,211,166,114, 91, 93,105,104,163,104, 76,190,112,109, +229, 62,129,241,101,111,105,199,223,177,193,250,145, 12,242, 4,249, 36,122,173,100,250,151,230,250,180, 7,127,252,252, 62,215, + 66, 89,248,206,252,234,182,191, 77,143,234,181, 60,114, 57, 20, 40, 44,206, 45, 4,163,227,121,148,118, 15, 6, 55, 86,182,252, +205,133,222,205,147,240, 68,177, 31,232, 14,144, 57, 51,100, 24,143, 76,158, 10, 73,129, 8, 93,232,146,211,138, 67,242, 7,160, +216, 50,197,124,224, 13,130,161,207,237,115, 5,249, 39, 76,247, 45,203,213,197,187, 20, 69, 77,115,204,214,202,210, 41, 56, 0, +186,112,164,209,110,184, 71,161,255,180,123,235,197,219,117,177,222, 21,254,177, 24,141,197,116, 10,208, 93,102,191, 62,157, 62, +127,247,121, 35,216,191,186,221,191,188,124,242,232,205, 51, 49,137,133,193, 21,118,218,173,211, 20,176, 61, 87,124, 13,157, 7, + 63, 1,155, 8,219, 18, 94, 19,176,125, 55,252,240,250,227,171,247, 95,243,255,158, 0,113,207,189,253,184,191, 22,101, 49, 45, + 46, 69, 78, 94,179,183, 25,108,205,102,108, 11, 22,123,115, 76,217,110,187, 7,191, 3,193,132, 25,238,237, 4,151,166,182,239, +244,104, 78, 52, 25,163,111, 67,101, 93, 57,251,161,114,215, 76,142, 81,115, 7,141,170, 35,172, 66,192, 37,189, 49,169,203,134, +180, 9,181, 0, 62,243, 14,161, 79,146,252,232,209,208,231,129, 16,228, 51,250,135, 33,134,191, 35,172, 70, 66, 32,109, 59,221, +179, 73,152, 20,153,146,204, 44,106,171, 61, 19, 65, 96,178,116, 69, 34,157,229, 11, 46, 98,118,165, 88, 92,201, 18, 10,165,227, +198, 38,186,210,166,172, 57, 51,101,117, 73, 45,122,163, 43, 65,130,218,170, 42, 5,191,243,146,235,165,100, 50, 19,192,254, 8, + 64,218,181,235, 70, 13, 68, 81, 63,214,235,215,198,206,139, 36, 36,144,104, 35,162,136,136,134,164,166,162,226, 39,248, 0, 36, + 36,190,131,138, 6, 4, 18, 13, 45, 37, 21, 66, 80, 82, 65, 75, 65, 10, 4, 41,146,144, 85,148,125,217,187,246,120, 60,220,115, +103,150, 93, 5, 26,132,180,141,247, 33,217, 87, 59, 51,231,222,123,238, 57,255,140,223,173, 63,138, 51,232, 73, 88, 78,232,198, +108,160,122, 9,197,187, 38, 77,152,113, 4,153,129,201,179,103,146,105,183, 34, 57,183, 60,246,166, 64, 9, 69, 76,206, 33,199, +240,223, 93, 23, 95,160,191, 63,191,152,155,235, 97,122,206,211,125,228,165,248,138, 80, 98, 36,114,215,192,120,131,224,149,105, +166, 40,158, 86,170, 65, 26,181,212,165,174,233,108,231,151, 89, 34,211,182, 9, 74,219,248, 9,110,117, 37, 93,207,203,204,131, +242, 59, 0, 4, 45, 96,189,165,129, 73,130,196,223,209, 98, 75, 4, 67, 43, 37,251,163,241,114,232,181,175,205,121, 30, 1,160, + 70,228,193,221, 52,109, 53,147,150, 27,251, 80, 60,103,129, 82,219,227,244, 5,133, 20, 89,163, 80, 51,134,231, 87, 37,106,223, +113, 67, 16,229, 49, 83, 58, 30,149,217,168,162, 80, 7,158, 19,251, 94,236, 1, 87,177,206, 19,220,109, 2, 87, 69, 1, 65, 43, + 55,165,227,206,197,163, 53, 89,178,143, 61,186, 28, 45,119,108, 75,182, 47,179,100,163,225,180, 2,138, 27,179,139,209, 2, 84, + 17,189,227, 99, 16,209,145, 80, 7,156, 15, 41,211,128, 71, 78,127, 48, 30, 12,133,182,230,153, 44, 56, 93,152,177, 77,120,248, +154, 89,199,211,225, 6,196, 3,140, 27,149, 68,139, 69, 53, 74,194, 5,166, 59, 74,173,137, 68,161, 11,155, 65, 85, 85,232,106, +178, 76,124, 43, 72,106, 38, 63,232, 6,122, 19,173,185,134, 16, 85,123,109,187,229,199, 12,174, 3,129, 65,101, 3, 46,225, 81, +137,233, 42, 48, 89, 23, 98,130, 84,160,201, 83,232,178, 34,167, 85,147,243, 68,140,226,167, 35,236, 15, 94,179,150,218,131, 63, +117, 58, 42,243, 6,206, 95, 79,129, 43,167, 48,166,200,126,202,160,235, 40, 48, 26, 9,188,119,250, 29, 74,236, 54,150,214, 49, +176, 9,166,154, 30,131,176, 86,147,213,102,211, 63,237, 30,159,117,207, 41, 7, 59,216,222,255,209, 57,202,139,236, 96,103,255, +240,248, 48,242,162,172, 28,150,117, 73,249,205, 69,222, 47,197,184, 16, 69, 24,182,210, 40,217, 92,110, 95,100, 64,226, 20,135, + 86,152,210, 70,191,187,177,219,203,123,123,155,123, 39,221,159,144, 14, 23, 99, 62,213, 36, 61, 14,221,146,102, 72, 87,149,236, +230, 93,169, 24,206,219, 80,205, 99,157, 9,176, 57,203,170,160, 93,233,198,218, 78,103,112,202, 78,120, 13,250, 52, 47,134,183, +183, 14, 62,159,124,125,240,248,197, 93,217, 92,217,186,106, 45,164,192, 75,223,179,252,221,183, 59, 79, 94,127, 25,244,254,186, +174,159, 63,188,103,183, 9,197, 11, 70,235, 10, 58, 68, 1,189,124,107,206,131,111, 58, 97,246, 36,180,230,105, 91, 79,172,235, +148, 25,212,239, 31,189,185,117,255,229,135, 35,255,211,219,143, 79, 95, 61,251,207,253,157, 54,244,155,139, 91,189, 98, 24, 71, +115,231,189, 51, 56, 89, 18, 78,175,213, 20, 44, 56, 54,101,161,195,113, 70, 24,146, 16,122,111, 52, 0,139, 83, 50, 23, 94,113, +134, 2, 66,179,208,213,216, 90,171, 8,219,198,248,168,158, 76,173, 50,108,150, 92, 58,103, 23, 87, 94,252,101, 81,230, 85, 14, +181, 47, 41,211,104,174, 20, 37,175,244, 42,135, 52,158, 45, 89,176,108, 8,143, 1, 89,155, 90, 10, 54, 95,202, 56, 43,205, 88, +103, 97, 39,101, 79, 57, 46,184,194, 13,213,114,226,162,202, 12, 76, 45,207, 81,207,104,215,152,204,162,214,186, 99,102,122,199, +148,110,216,117,138, 89, 49,182,174,198,155, 2,248,108,101,157,219,131, 19,135,167,250,247,128,168, 50, 42,227, 92, 75,160, 85, +243, 75, 0,206,174,101,183,105, 40,136,250,218,190,215,118, 18, 55, 33, 77,156,180, 8, 54, 69, 44, 42,181,226, 3, 42, 85, 32, +245,167,216,242, 7,172,249, 10,196,134, 5,160, 74, 93, 82,129,132, 42,164,138,110, 10,165,239,146,216, 73,108,199, 73,204,156, +185, 54,105,212, 21, 85,171, 86, 93, 84,114, 28,103,230,204,157,243,184, 39,126, 95, 4,239, 60, 40, 24,102,201,128, 44, 62,131, +183, 56,145, 11,229,187,140,131, 17,183,253,126, 45, 86, 93, 19,134,229,124,143,226,124, 74, 35,119,201,217, 98,165,108,149,170, +149,173,151,210, 74, 40, 5, 45,145,237,128,172,165,148, 37,149, 41, 29, 28,242,170,163,232, 64, 57, 50, 74, 16,158,137, 83,105, + 78, 6,214, 13,128,202, 26, 21,162,170,227, 19, 20,210,100,212, 59,197,189, 92,145, 44,168,106,203,244,218,242,250, 69,225,108, + 51, 63,142,210,161,175,136,138, 71, 52,140, 73,104,157,112,188,100,165,109,167,225,109,109,118, 90, 77,111, 56,158, 36, 99, 35, +140, 51,250, 25,197,211,116, 38, 82,104,101,120,101, 5, 20,150, 43,137,155, 73,211, 56,213, 6,106, 20, 18,245, 95, 96,233, 74, + 93, 43,155, 82, 57,135,158,208,166, 15, 0, 61,133,120, 65, 38,159, 23, 50,175, 22, 13,198,177, 4,108,177, 13, 28,188,224,190, +241,132, 77,248,221,182, 4, 21, 67,250, 27,156,123,156, 18,100,195,113, 54, 74, 53,200, 17,227, 9, 12, 34, 83,253, 13, 95, 62, +108,145,242,185,105,157,198,219,144, 56,133, 73, 79,112,236,129,158, 93,124, 40, 65,226, 9, 82,210,110,187,176, 22,239,172,126, +172,249, 23,134,158, 96,105,149,174,150,218,161,198,226,218,160,207,204,181,109,134, 5,183,125,141, 77,138,200, 21,147,179,235, +129, 88,104,150,234,214, 87,126,222, 28,151,130, 88,192, 48,207,169,217,166, 29,193, 71,158,237,124, 89, 52, 88,161,102, 48,133, +194,182,237,183, 46,163, 11,205, 91,152, 21, 52,217, 66,240, 80,117,107,195,100,104, 50, 81,194, 81,142,239,130,117,147, 77,224, + 12,108, 9, 57,225,160, 56, 41,229,230,163,205,155,232, 79, 20,247,232, 98, 19, 24,224,128, 29,181,214,125,242,227,236, 80,154, +118,224, 7,157,102,112,120,114, 72,183,118, 16, 15, 56,177, 93,213, 42,149, 36, 29, 83,235,160,142,226, 40,143,128,191,178,221, +211,235, 95, 15, 91,143,145,205,203,166,175,131, 36,162, 57,227,249,198,139, 47, 71,251,215, 3,240,127, 70,136, 61, 0,246,104, +120,141,126,210,227,172, 96,168, 43,104, 36,117,149,187,181,177,149, 85,197,238,167,247,116, 73,124,205,162,189, 20,156,133,231, + 75, 14,189, 10, 66,250,217,246,250,246,254,209,103,186,117,157, 70, 55, 78,123,118,158,190,254,250,161,159,165,255,151,161,182, +247,202,120,234, 27,163, 1,103,177, 24, 88,180, 70,153,113,147,128,150, 92,117, 1,216,235,158, 97, 84,140,203,254,238,203,119, + 59,111, 62,234, 98,241,192,107, 30,188,221, 91,221, 89,191,119,101, 87,134,221,148,181,103,203,107,142,148, 52, 53, 44, 87,154, +136, 97,169,214,175,194, 43,172,176,138,115, 34,244,114,134, 23, 51,200, 51,242,105,211,111,157,247, 78,233, 25,108,215,131, 48, + 14,251,113, 88,108,216, 8,222,213,105, 96,186,232,128,193,242, 91, 3,188,127, 71,216, 64, 36, 98,214,246,131,110, 99,229,251, +201, 55,230,219,176, 72,176,212, 55,229,101,217,178,196,156, 87,195,255,165,149,165,236, 37,163,117, 24,122,129,165, 51,163, 10, + 50,122, 57,187, 26,176,205,160, 71,158,154, 61,224,221,176, 39,196,220,130,216,145, 96,117,115,126,139,222, 88, 79, 93,233,130, + 12,145,105,222,135,206,152,194,151, 95,105,140,178,193, 4,253,166, 64,239,139,133,215,156,235,132,138, 4,167, 59,239,105, 14, +107,240,191, 2,112,118,238,186, 77, 68, 65, 24, 62,123,243,122,189, 94, 95, 48, 78, 76, 34,132, 4, 18, 13, 69, 10,160,160, 8, + 5, 45, 61, 8,158,129,134, 71,224, 5,120, 12, 58, 36, 58,218, 72,161, 68, 36, 69, 4, 18, 69,226, 4, 18,199, 78,226,141,124, +201,198,187,222,179,204, 63,179,142,185, 8,161,208, 89,174,142,215,103,103,230,204,249,231,251, 47, 17,223,255,108,206,128,147, +165,156, 88,159, 95, 76,171, 50, 2,172,192, 56, 23,139,175,140,126,177, 93,154, 99,212, 21,195, 11,113,200,154,254,214,165, 49, +148,157,240, 98,204, 92, 8, 47,198,145,153,141,117,138, 77,184,205,250, 25,182, 23, 80,182,103,187, 40,231, 77,167,228, 32,142, + 25,134,219,240,107,237,209, 78, 63,234,209,243,135,161, 6,124,135,240,198,162,252, 81, 57,254,205, 66,171,216,142,121,124,249, +226,233, 75,117,152,129,244,223,234, 13, 58,166, 50,255, 77, 44,158, 43, 81,249, 10,222,241,146, 52, 42, 23,107,227,100,204,224, + 70,133, 57, 85, 75,136,103,230,131,219,139,180,192,136,130, 40, 90,223, 84,137, 57, 65, 80, 52,153,170, 0,161, 27, 40, 19,106, +146, 64,228, 9,184, 82, 60,117, 80,134,107,139,169, 11,112,242, 6,240,208, 64, 35,151,123, 29, 37,203,242, 41,168,224,248,130, +243, 11,166,153, 92,140,245,234,137, 62,157, 80, 58,128,156,216,181,205, 56,211,148, 1, 39,105, 10, 99,192,204,104,213,131,245, +173,221, 41,100,146, 80,125,229,230,240, 90,198,254, 56,154,167,162,224, 18, 96, 94, 42, 85, 10, 58, 53, 58, 11,138,117,122,253, +176,138,220,239,150, 93, 19,229,205, 81, 12, 90, 0, 1,102, 56, 27,112, 51, 37, 67,138, 68, 65,110, 18, 92,232,196,153,140,156, +247, 58, 37, 1,101, 76,116, 48, 56, 29, 41,191, 16, 64,102, 3,193,143,205,110,102,244,126, 21,138,110,145, 42,241,102,101, 49, + 73,226,163, 17,212,129,180, 60,104,153, 53,232, 67,194,251,190,123,243,222,167,246, 71, 90,218,181, 90,171, 63, 58, 57, 99, 33, + 57,135,248,185,177, 99,198,158,233, 87,130,198,233, 40,132,205, 55, 6,239,225,156, 73,121,121,169,190,180,123,180,243,226,233, +203,247,107,239,190,247,247,109,238, 55,210,102, 46, 23,253,179, 36,242, 28, 88,172,208,134,162, 47, 87,110,172,108,110,111,174, +222,121,184,115,184, 77, 37, 82,171,209, 60, 12,123,131,241,192,117, 10,213, 82,117,239,184, 93,114,124,250, 67,168, 96, 15,188, + 74, 12,254,123, 84, 43, 85,198, 49,124, 10, 3,175,138,222, 91, 66, 9,195, 42,123, 84, 48, 70,180,103,194,179, 16,131, 21,150, + 89, 42,240, 85,170, 50, 40,198,193,201,104,120, 74,167, 4,218, 68, 5,112, 42,121, 2,154,254,126, 83, 72,164, 0, 66, 80, 90, + 98, 75,163,212, 98, 47,224,235,181,197,183, 95,214, 54,194,111,151,141,179,111, 30,223,127,246,250,185, 10, 12,168,110, 78,134, + 42, 60, 87,189,137,250,218, 87,131,201, 70,187,179,117, 48, 88,104, 85,247,143, 71,175, 62,124,222, 83,243, 51,186,171,220,147, +245,237,242,234,242,127,199,247, 39,183, 30, 81,162, 90,168, 55,187,131,110,167,223,229,243,156,246, 93,143,126,227, 56,130,181, +172,180,149,213,204,173, 46,229,137, 19, 72,103, 12, 61, 5,156, 6,219,170, 89,105,210, 71,144, 27,184, 88,155, 66,231,106,136, +141, 84, 54, 27, 32,146,107, 29, 9,159,240,153, 73, 19, 64, 67,217, 55,105, 54,197,142, 2,123,185,177,124, 16,118,242, 14, 72, + 46, 29,144, 27, 90, 45,133,206,148, 91, 42,162, 16,166,101, 52,130, 6, 29,197, 82,110,209,248,174, 15, 37,110, 62,233,148, 73, + 55,210,152,193,201, 24,170,157, 35,197,178, 92, 55, 15, 89,223,213,160,213, 29,118,242,211,176,150,230,187,176, 10,180, 24, 1, +230,245,163,254,203, 84,209, 79,170, 69,147,187, 75,179, 92,144,235,213,127, 8,192,217,181,236, 54, 13, 68, 81,207,140, 31,121, +213,105,155,168, 78, 75, 65, 37, 5,161, 72, 72,188, 37, 86,108,248, 0,190,128, 47,226, 51,248, 1,182,172, 89,116, 5,168, 43, + 68, 43, 1, 81, 68, 26, 26,147, 71, 19, 39,182, 19,143,185,247,206,216, 77, 10, 11, 84,229,161, 40,155,196,201,204,153,251, 56, +247,156,255,197,247,191,193, 61,205,152, 51, 76,195,174,210, 27,160, 38, 30, 21, 74,165,177,234,165,148, 99, 34, 96,129, 40, 96, + 45,186, 88, 16, 21,184,204,209,178, 39,117,139,142, 88, 68, 6,139,140,133,208, 52,117, 84, 79, 79,181,248,140, 80, 18,237,112, +162, 88,116, 60,192, 34,119, 56,220, 45, 19, 80, 14,125, 65,177, 74,227, 8,187, 90,112,253,176,223,153,125,135,211, 18, 2, 34, +137,108, 42, 36, 71, 6,170,175,155,234, 78, 10, 30, 36,105,148, 47,159, 60,120,135, 45, 45, 73, 90,122, 85, 1,250, 95,236,247, + 76,232,140, 94,115, 13, 99,156,140,133,169,102, 69,131,101,112,157,168,134,109, 41, 23, 40,188,211, 86, 36,141,108, 18,212,209, +179,199, 50,111, 7,163, 18, 11,233, 58, 98, 41,156, 92,253,200,170, 67, 48, 7,141, 52,113, 34,188, 86, 44, 25,214,242, 60,152, + 79,101, 60,140, 34, 72,122,130, 40, 25, 5,209,197, 52, 52,180, 98,227, 74,249,172,236,188,120,242, 56,156, 12, 55, 76,190, 91, + 67,191,159,163, 99,228, 81, 36,216,245, 75,104, 92,132, 24,145,104,251,164,250, 78,218,105,158, 50,217,172, 80,101,176,106,121, +251,247,164,175, 84, 53,178,193,223, 52, 55,111,147,186, 91,132,171, 28,189,202,208, 97,196, 92,146,195, 14, 58,124, 81, 94,220, +220, 57,132, 32, 12,224,143,161,175,161,168,187, 94,127,220,171,150,183, 70,193, 64, 77,135,145, 29, 23, 62,158, 30, 62,251,252, +237,163,169,106,208,216,166,226,174,227, 78, 98, 0,125, 12,213,201, 52, 69,211,175, 20, 95,214, 22,118,168,124, 63,116,201, 13, + 55,228,221,189,123,167,221, 19,146,245,190,220, 3, 36, 19, 34, 33,104,138,146,184,225,238,206, 48,245,198, 67, 20,178, 1,248, +121,127,141,123,158,219,184, 89,191,117,220,254, 4, 31,210,186,209, 58, 27,254, 68, 23, 37, 18,161, 52,177,239,178,132,231, 3, +175, 57, 13,208,158,247,108,132,202,227,158, 91,131,175,121,127,191,245,165,251,213, 31,251, 42,167,131,119,182, 74,155,131, 96, +120,123,231,224,199,121, 27,160, 31, 85, 13,136,180, 90, 46,194,178, 55, 32, 39, 32,226, 80, 10,171, 23,224,134, 56,121,105,165, +176,129,146, 41, 92, 44, 81,194, 31,110, 9,213,214,184,186, 92, 0,178,193,197,112,191,190,135, 50,247,156,155,150, 32,216, 72, + 82, 61,106, 6,127,254,226,237,201,135,235, 65,237, 75,183,242,230,213,243, 71, 15,154,198,130, 25, 93, 56,254,102,175,223, 31, +189,235,251, 87,102,213, 75, 54,100, 39,186,196, 93,181,107,163,200,135,133, 41,141,248,122, 31,250,112,251,142, 87,168,206,101, + 12,135, 19,196,103, 9, 68, 33, 92, 87,201, 97, 45, 1,218,182,251,109,142, 9,104, 17,182,240, 60, 86,140, 56, 29, 56,227, 47, +191,217,232,248, 29,169, 74, 52,186,167,137, 28,174, 36, 11, 82,232,223,207, 73, 21,218,216,154,115,197,224, 72,149,206, 44,185, +159, 41,197, 47,105, 91, 78,180,136, 57, 91,215, 51,103,151, 92, 25,137,126, 13,146, 34,236, 68,201,193,171,126, 45,192,177, 45, + 74, 72, 11,206,217,232,233,202, 40,105,206, 49, 99,153, 99,147,174,208,192,245, 10,242,156,224, 25,178, 83, 13,135,229, 85, 16, + 69,243,179,163, 56, 92,117,185, 88, 51,215,102,107,240,122,165,153,248, 71, 0,202,174,101,183,105, 32,138,122,198, 51,182,147, + 52, 78, 66,218, 82, 30, 93, 32, 85, 8,164,238, 80,191,128,207, 0,190,131, 5, 11, 62, 17,177, 64,130, 77, 97,199, 35, 16,225, +196,142,237,177, 61,195,125,140,173,180, 20, 1, 82,229, 69,149, 56, 19,103,230,206,185,119,206, 61,231,159,226,251,141,242, 2, +158,208, 54,184,135,248, 63,111, 86, 18,252,230, 2,203, 23,236,239, 10,112,214,114,245, 56, 85, 71,165,203,202, 46,231, 20,149, +136, 49, 72, 48, 21,126,147,240, 97, 93, 19, 96,151,100, 21,140, 87, 34,122,192, 60,208, 82,199, 24, 0, 21,188, 38, 9,227, 68, + 99,149,102, 18, 31,100, 38,187,204, 62,112,255, 27, 30, 10, 58, 58,101,117,189,166, 15, 25,150, 11, 78,250,124,250, 35,250,211, +127,172, 36, 88,111,170,114,197,171, 68, 6,215,184, 53,142,101,112, 90,215, 96, 46, 32, 81,229, 71,122,145, 3,146, 7,166,205, + 78, 33,120, 71,108, 75,114, 38,244, 6,252,135,116,164, 31,207,245, 11,233,225,191,220,107,169, 24,104, 86,206,211,123,144, 99, +163,176,106, 33,113,147,142, 70,209,106, 87,176,164, 11, 92,106,131,157,121,158, 71, 32,153,230, 11,159,169,166, 40,219,168,159, + 94, 60,169,202, 66, 52, 59,219,229,217,218,124, 94, 35, 47,135, 4,250, 2,114, 98,234, 13, 11, 58, 65,228, 36,199, 4, 71, 27, +176,102, 29,207,223, 46,214, 99,148,211,218,173, 49, 14,163,207,137, 24, 66,252, 64,182,133, 59,177, 2, 1, 90,107,161, 75, 31, + 58,176, 69,184, 95, 82,125,204, 89, 38, 0,209,226,178, 90,233,142,180, 1,232, 73, 98, 66, 5,131,128,212,187,174,139,170,133, + 39, 25,198, 58,110,154,122, 62, 94,110,235, 76, 12,204,179,160,175,224,248,230, 17, 17,171,228, 56, 61, 92,101,171,186,173, 7, + 71, 74, 22,235,134, 56,174, 67, 93,212,185,239, 66,164,226, 53,124,177,217,116,158,239,242,116,148,194, 8, 97,182,148,166,212, + 40,229,158,228, 53, 58,180, 40,165,206, 79,207,223, 94,190,185, 59, 63,253, 81,172,122, 50,168, 35,138,148,156, 31, 44, 98, 24, +121,219,193,109, 79, 22,119,190,174,191,132,168, 22,231, 70, 17, 0,136,130, 60,124, 37,255,136,112, 31,131,140, 8,145,142,230, + 57,154, 53,226,207,152, 38, 7,176,181,180,109, 3, 3, 67, 67, 74,129,189,178,228, 85, 82,244,114, 36,246,112,186, 52,214, 0, + 34,169, 76, 73,132,232,224,222,226, 62,236,130,232,196,133,155,129,129,196, 5,207,243,247, 78,239,216,136, 5,246,254,119,223, +223, 39, 74,193, 19,202,209, 32,192,230, 77, 93,117,205,182, 49, 59,242,199,176,246,239, 22, 62,103, 81,210,134,118, 85,153,130, + 94, 27, 43,180,247,194,250, 51,202,236,224,194, 49,166,101,148, 56, 22,105, 97,179,135,183, 31, 63,123,241,252,245,203, 87,226, + 88,252,111,124, 95, 70,211,139,163, 71,136,231,156,156,141,166,155,106, 75, 68,175, 16,251, 84, 16,105,105,106, 21,134,181,130, + 54,109, 53,106, 96, 4, 92, 36,225,242, 8, 12,169, 33, 18, 57,204, 55, 72,125, 0, 62, 7,212,192, 1,203,253,193,201,217,167, +111, 31,217,190,141, 33, 11, 32, 9,244,113,172,126, 74,191, 66,156, 63,104,237,251,206,111,162, 24,186,161,197,137,113, 59,103, + 12,183,210, 37,128, 52, 64,250, 40,135,194,233,175, 96, 69, 42, 33,254, 16, 57, 67,108,144, 78, 54,229,198, 43,202,247, 86,174, +110,192,236,253,162,155,198,179,194,108, 88, 72,135, 77,161, 70,209, 36,111,139,137, 26, 23, 87, 29, 50,122,139,146,235,195,182, +123, 37,157, 95, 2,112,118, 45,187, 77, 3, 81,212,227,113,236, 36,142,242,106,104, 40, 8, 33, 33, 33,177, 69, 42, 11, 62, 30, + 36,196, 23,176, 96, 87, 68, 4,148, 18,146, 38,196,241,219, 99, 15,247,220,177, 93, 71,237, 6,164,238,170,196,246,120,114, 31, +103,206, 61,199,249, 39, 88,166,139,188,235,198,115,195,234, 40, 10,224, 32, 91,186,102,204,241,193,194,151,215,209, 53,247,148, + 90,106,196, 67,107,250,100, 66,170, 45,165,133,185, 81,217, 92, 66,118,148, 35, 57, 14, 75,148,198,252, 7, 69, 42,240, 15, 65, + 53,164,111,204,216,231, 83, 52,208, 91,219,190,116,213,127,238, 83,249, 75,211, 94,104,109, 61,244,158,218, 79, 58, 96,209, 82, + 41,151,183, 41, 0, 89, 29, 54, 38, 92, 49, 48, 58, 13, 70, 12, 2, 29,187, 35, 27,183, 47,203,246,232,151, 3,116,163,162, 54, + 84, 40,118,155,180,237, 70, 32,195, 80, 67,234, 0, 63,241, 22,135,108,203, 11,202, 45, 1,178, 60, 0,156,202,193, 71,133, 67, + 97,130,178,131, 23, 82,177,161,196, 46,202,169,100,145, 3, 81,150, 44,238, 98,247, 38, 99, 15,234,180, 69, 57,245, 7, 83,223, + 47, 84,118,177, 60,223,252, 88, 5,123,245,107, 7, 46,189, 42,192,146,208, 44,233, 2, 46,101,221, 27, 34,239,241, 19, 24,235, + 24, 22,184, 21, 76, 56, 18,146,130, 17,133,155,250, 5,217, 82, 87,101, 71, 45,155,219,104,219,113,157, 94, 90, 38, 6,232,166, + 90,102,225, 47,183,225,186,160,252,135,188,198, 96,137,110,160, 44, 33, 20,188, 4,133, 54,213, 41,202, 22,164,191, 63,225,214, +180, 55,174,227, 82,116,198, 17,165, 74,140,218,187, 57,221, 26, 58,212, 92, 43,230, 31,213,155, 48,206,195,111,219,120,212, 31, +117,157, 27,152,224, 92,245, 49,132,204, 13,184, 70,115, 71,251, 36, 87, 57, 14, 14,192,148, 96,158, 27,204,190,119,103,227,229, +238,184,241,251,190, 72, 0,190,170, 66, 5, 81,168,116,185,141,214,108,228, 2, 79,208,229,236, 73,148,134, 84, 70, 77,135,227, +213,230,171, 3,171, 22,121, 76, 2,207,237,165,176, 18,180,162, 52,209, 48, 98, 68,228,225,150, 1,215,162, 69,241, 48,130,123, + 48,173, 16, 51,252,138, 36,139,105,223, 42, 27,172,217,153, 63, 59, 68,251,179,241,130, 34, 90,146, 37, 79,231,207,232,121,163, + 44, 46,209, 92,225,236,144, 86,227,241,244,252,231,254, 26, 61, 71, 94, 40,153,207, 6,211, 40,141,209, 15, 54,136, 13,215,147, +198,119,154, 46, 55,184, 77,143,125,156, 69,217,190,144,147,190,135,112,111,225,136, 22,182,162,130,222, 75,238,244,252, 87, 47, +158,127,248,252, 41, 73, 19, 9, 74, 49,244,108,143,170, 72,225,244,162,175,242,244,196,224, 13, 35,199,202, 64, 11,168, 6,212, +221,184, 80,172,131, 96,117,216, 28,110,223,125,124,255,246,245,155,255,168,223,179, 74,141,134,126, 26,193, 54,157,118,151,177, +174,134, 76, 33,235,199, 29, 19,198,250, 52, 53, 62, 69,201,120, 8, 51, 70,164,170, 50,115, 63, 60,249,196,200,137,160,109,144, +153,184,217,179,229,163,249,197,151,155, 43,250, 31,151,234,250,242,229,229,205,126,125,189,251, 94, 99,134,204,132,104, 3,186, +205, 97,153,233,112, 53,201,187,234,142,129,154, 3, 57,195, 81, 22, 70, 36, 92,255, 14,214, 92,182,219,117,131, 43,106, 51, 86, +235,132,167,126,194,174,166,133, 75,116, 90,233, 6, 4, 54,143, 42,152,154, 32,106,196,199,124, 71, 88, 4,148,212, 39,195, 57, + 75,212, 33,226, 71, 44, 41, 12, 74, 72,117,199,251,110, 35, 82,121, 47,226,119,141,171,254, 10,192,217,149,236, 54, 13, 69, 81, +191,103,199,142, 19,103, 78, 83, 16, 45,173, 64, 42, 18, 18, 43,246, 44, 97,197, 95,240,113,124, 2, 59,150, 72,253, 0, 36,186, + 66, 41, 67,105,234, 76,118, 28,207,230,158,251, 60,164,172, 42,178,204,164,228,249,250,142,231,158, 99,252,135, 60,147,184,183, +179,170,200,123,139, 74, 82,213, 40,177,240, 60,246, 46,154, 49, 69,211, 34, 98,132, 55, 64, 50, 38,227,100, 64,110,217,188, 46, + 12,128,121, 68,221,101,208,203,110,187, 34, 7,230,198, 46,210, 40, 52,220, 37, 83,150,130,237, 5, 34,198,104,189, 51, 90, 70, +152,154, 30, 21, 59, 9, 86,160,138, 37,162,242,238,181, 82,151,172,177, 71, 85,242,158, 61, 64, 16,188, 34,240, 81,251,180,108, +241,168,102, 75, 70, 44,254,121,228,129,121, 89, 31, 41, 47,229, 29,133,209,178,200, 14,169,162, 37, 95,150,134, 33,203, 83, 74, +214,214,102, 69,176, 44,171, 15,166,146, 50,134, 75, 95, 36,127,202,200,204,145,128, 62,149,114,159, 24,135,160, 75,202, 83,169, + 44,161,156,151,110,128,205,126,159,164, 74, 43, 74, 90, 45,100, 91,109,211, 60, 26,180,163,128,206, 48, 57,157, 30, 95,156, 63, +238, 15, 29,179,101,132,182,253,221,115, 25, 64, 6, 56, 0,214,189, 84,150,203,171, 33,148, 34, 73,238,201,128,203,129,255, 11, +171,169, 41,170,188, 2,140,101,152,151,148,106, 86,244, 97,199, 30, 48,115, 64,209,240,129,226,155, 82, 81,227, 73, 53,105,183, +109,233,139,202,196,203,133, 1,203,236,218,186,133,197, 60,241,111,133,199,107,126,152, 8,140,157, 41,121, 61, 72,230, 26,228, +212,246,195,222,216, 11, 60,141,145, 73, 84,148, 80,225,113, 58, 58,251,177,188, 38,151, 55,235, 31,207, 33,208,168, 81, 54, 93, +242,109,151,150,131,217, 76,202, 67, 47,117,243,150,116, 88, 26,131,115,164, 41,180, 32, 72,118,108, 72, 58,131, 87, 69, 68, 14, + 66,136,139,217,139,111,191,191, 82,116,121,118,244,124, 27,109,183,254, 26,237, 54, 10, 87,105,220,235, 12, 54,193, 6, 44, 49, +105,161,155,192, 56,186,254,157,198, 45, 0,165, 87, 71,135, 49,232, 12,200, 34, 23,235, 69,187, 77, 53, 53,246, 0,178,204,231, +234, 11,148, 21, 58,115,242,140,156,241,210,119,147, 4, 20,113, 94,184,161,103, 54,193, 86,128, 97, 16,244,103, 41,242,227,152, +126,113,156,135, 67,103,226, 5,171,159,171, 95,116,105,226, 36,146,116,233,227,162, 63, 25,158, 76, 79,230,183,215, 96, 95, 97, +194, 86,202,108,122, 38,149, 86, 43,178,139, 39,206,163,171,229, 13,107,185, 72,149,224, 64, 75, 5,122,129,188, 13, 40, 5, 69, +199, 87, 79,207, 62,188,127,247,242,124,246,241,211,231,137,105, 27,104,250, 1,208,139, 21, 60,118, 60,113,150,187, 73, 28,166, +233,151,197, 77,140,221, 14,173,129,235,137, 67, 60,177,209, 31, 13,200, 62,186,194,126,251,250,205, 65, 22,245,208,135,159,238, +189,104, 55,235, 77,200,146,195, 28, 32, 37,213,157, 48,165, 78,103,194,121,159,154, 0,193, 82, 91,166,229, 88,253, 91,255,150, +201,222,113,163,144,185, 14,157, 49,213,109, 65,184,163, 34, 86,133, 57,138,148,243,187, 57,221, 30,189,118,119, 31,133,244,182, +203,171, 75,134,127,232,133, 56,208,230, 80,137, 19, 79,100, 70,157,209,122,231, 10,132,231,123,122,213, 90, 53,185, 84,125,203, +146,118,134,221, 73, 85, 72, 20,234, 59,242, 26,200,168,213, 78, 69, 52,249,180,198, 91, 98, 24,159,113,127,176,241,236,138,227, +160,210, 95, 85, 12, 50,128, 14,229,174,239, 42,133, 85,197, 94, 74, 7, 19,103,145, 90,144,108, 72,196, 74,191,209,108,183,230, +117, 68,169,186, 67,127, 5, 96,236, 90,122,155,136,129,176,247,229,221, 58, 9,143,182,148,210,210, 86, 80,165, 45, 7,110, 72, + 72,252, 91,254, 5, 39,206,168,220,120,136,135, 84, 26, 53,173, 4, 37,217, 36, 77,178,105,118,215, 54,243,112,118, 83, 4, 82, +165, 28,162, 40,114,214,142, 61, 51,158,249,230,251,194,219,152,117,241, 47, 54,130, 69, 77,149,147,227,158, 99, 7, 35,156, 32, +134,243, 54,240,150,241, 50,142, 11, 0,211, 19,136, 87,198,150, 26, 12,193, 74, 61,183, 53,188,129, 23, 38, 32,239, 42,156, 60, + 83,205,255,142,172,187,216,130, 67, 98,162,152,158,102,201, 12, 75, 84, 39, 20,227,146, 94, 33,146, 31,140,145, 88, 10, 99,184, + 86,220, 26,100,169,168,105, 40,150,232, 38,110, 56,216,229, 58, 1,159, 5,251, 63,159, 71,249,106, 93, 79,172, 94,104,124,229, +196, 18,238,218,181,168, 39,205, 10, 66,178,123, 52, 41,195, 10,127, 54,137, 84,137, 77, 43,154,147, 90,102,121, 95, 49,196, 27, +105, 59,168, 27,215, 35,181, 63,176,244,154, 36,139,176, 56, 28,102,243,242,235,112, 2, 87,111, 47,138, 61,236, 43,130,221, 28, +220, 85, 82, 34, 51,131,215,240, 67,165, 34, 33,229,243,131,167,145,212,113,224,131,209,159,143,174,167,179, 18,111, 30, 46, 97, + 11,214,216, 74,171,154, 65, 51,244,147,132,236,128, 79, 5,174,171,114,144,230,125,226, 81, 9,180,227,233, 65, 78, 63, 42, 22, + 88, 71,194,172,233, 74, 74,249, 77,218,127, 40, 93,107,249,159,103,176,174,213,221, 94,103, 37, 92,193,188,179,103, 43,168,213, +117,158, 21, 30, 66,241, 67, 78,120,184,219, 42,165,180,104,254,251, 27,251,221,222, 25, 12, 56,157, 77,208, 44, 90,170,164, 97, +113,192, 87,113,163, 36,118,169,243,126, 7, 70,156,229,147, 97, 22,241, 38,219, 89,223, 5,139, 79, 29,131, 72, 42, 9,198, 26, +134, 99, 57, 52, 22,186, 65,230,112, 15,110,117,152, 75, 25, 99,182, 4, 11,179,240,227,133, 45, 71,217, 16,190, 52,205, 39,176, + 44,231,131,115,216,117,157, 94, 39,160,100, 14, 24, 23,229,203,185,185,134,144,237, 65,115, 13,158,246,112,251,240,248,251, 59, +216,195,131,113, 10,207,242,178,253,226,248,228, 61,248, 3, 42,105,148,200, 95, 36,130,246,227,182,146,234,244,242, 20, 66,242, + 39, 27, 7, 95, 46, 62, 27, 42,165,228,232, 64,139, 2, 37, 12,237, 74,164,192, 46,131, 11, 65,101, 74,236,137,143,136,161,240, +138, 13, 8,150,149, 25,255, 32,144, 78, 2,124,198,230,189,135,191, 70, 40, 68,126, 66,132,154,168, 29,230, 57,174, 82,226, 80, + 44,169, 64,111,162, 64,174,198,119,206,166,125, 8,225, 13,107, 90,212, 80, 0, 60,147,176, 14, 63, 46, 47,190,117,186,159, 46, +127,126, 24,252,222,148,141,216, 71, 69, 48, 21, 69,205, 80,182, 18, 25, 7,120, 21,222,130,247,161,236, 21,249,199, 30,210,103, +122,212,134,163,237, 13, 25, 59, 41, 98,209, 20, 59,219, 91, 38,212,226, 40,129, 79,222,190,126,243,168,189,251,236,213,209,237, + 77,188,129,149, 47,179,146,120,187, 96, 41, 10,106,208,207, 81, 52,167, 10,207, 8,181, 34, 80, 90,138,160, 50, 24, 74, 17,229, + 47,194, 95,193,237,149,186,208, 66, 47, 21,251,184, 42, 74, 48, 48,131,219,202, 6, 11, 60,156, 96, 23, 64,129,128, 17, 11, 84, +161,193,140,153,213,129,235, 13,173,144,114,149, 58,183,117, 4,149,124,118,137,255, 14,108,176, 74, 20, 60, 64, 70,123, 12, 6, +187,223, 88, 75,199,120,231, 94,107,173,167,211,212, 86,100, 4,124, 9,112,233, 12,179, 32,119, 52,172, 43,176,112, 9,124,178, + 42,164,134,191,183,186,119,150,158,186, 86, 40, 46, 15,176, 21, 51,181, 46,233, 66,162,228, 47, 43,205, 25,126, 55,139, 63, 2, + 80,118, 37, 61, 74, 4, 97,180,186,155,134,102, 27, 96,144,101, 28,102, 52, 30,252,189,254, 23, 79,222,141,137, 7, 15,106,204, +152, 24,200, 44, 9,195,192, 64,179, 52, 52,189, 85,249, 45, 85, 44, 17, 77,132, 27, 36,189, 85,215,183,190,239,189,220,191,205, +250,223,140,187, 97,121,100,118,100, 18, 44,210, 2,181,164,115, 41,116,235,194, 54,133,119,236, 26, 56,252,104, 48,146,165, 81, + 85, 30, 69,103,116,167,109,150,192,161,139, 70, 2,119,219, 16,146, 89, 26, 75,195,163, 33, 12,216,160, 19, 97,126, 10, 59,192, + 89, 35, 79,180, 40,186, 72,126, 2, 91, 97, 22, 47, 19,137,201, 26,230,194, 73,200, 21,136, 3,160,223,233, 0, 67, 25, 79,168, +140,142,151,110, 23,211, 80, 14, 28,202, 58,145, 7, 29,117,155, 13, 74, 67,115,218,176,178, 46, 51, 59, 51, 89,169,150, 94,145, + 54, 15, 53,176,188,228, 33,144, 84,147, 60, 75,145, 9, 45,236, 45, 17,243, 87,220, 38,129, 3,126,209,201,242,194,147, 50,134, + 56,240, 41,142,170,181,226,117,165, 6,193, 48,248, 61,216, 21,155, 40,113,165,163, 34,187, 92,176,170,121, 28,251, 66,209, 12, +156,191,203,138,213,234,118, 21,127,235, 63,194, 19, 75,241, 19, 35, 28, 43,243, 74,234,204,181,114, 40, 83, 34,151, 1,236, 2, +136, 74, 17,153, 94,238,120,189,139,226,229,175,224,103,148,133, 96,236,208,122, 88,200,238,159,237, 30,189, 5,166, 51,116,248, + 26,201,159,215,203,231,240,251, 60,152, 18,213,117,129,166,130,169,208, 14, 78, 55,203, 74,110, 21,187,185, 68,215, 14, 95,136, +194,130,208, 71,177,236, 92,142, 10, 38,170, 85,109,207, 55, 11,150,177,185,157, 12,152,229,201, 66, 68,144,167, 66,220, 57,235, +104, 5, 39,235,212,218, 35,255, 17,210, 35, 15, 81,176,118,152,172,151,225, 2,187,173, 74, 61, 60,223, 25, 62, 61, 36, 43,183, +120,120,208,210,220,203, 12,223,133,213, 40,230, 75, 96,205, 47,207,123,179,245, 20,145,145,201, 38,225,137,118,165, 59,105,193, + 22,177,231, 65,184,226, 23, 2,211, 37, 34,229,129,187,132,200, 29, 22,228,211,205, 71,162, 73, 65,189,221, 52, 74,135,243, 49, +174, 48, 17,134,240,212,155,227,184,240,124,111, 30,190,228, 28,116, 78,221, 70, 59, 85,201, 96, 52,144,102, 51, 82,169, 68, 16, + 93, 15, 15, 20,216,112,155,189,198,245,237,115, 31,121,118, 44,213,173,191,244,151, 83, 56,218,152, 38,155,234,165,230,114, 51, + 31,250,195,114,161, 28, 99,103, 2,167, 26,108, 91,191,159,182,160,161, 51,181,133, 28, 2, 73,206,178,244,109,243, 10,236,123, +138,236,180, 90, 3,154,100, 67,241, 14, 19,212, 77,205,190, 78, 6,239,222,127,248,124,255, 3,109, 52,172, 45, 4,239, 56, 84, +225, 20,108,183, 17,121, 47, 42, 16, 27,228, 9,128,162, 94, 85,106,223, 39, 35,211,232, 59,142,221,225,188, 34,134,183,227,245, +213,181,166, 30, 22, 86, 16,172,222,116, 47,254,171, 68, 51, 93,249,157,179,230,110,120, 48,159,115, 91,181, 86,255,169,143,226, +245,241, 54,193, 26,151, 96,253, 52,201, 12, 72,152,231,226,116, 94,193,241,210, 44,156,111, 23,202,100,207, 71,218, 23, 88,184, + 11,247,114,110, 66,167,219,218, 4,166,218,237, 17, 89,141, 88,132, 62,161, 35, 36, 83,172, 31, 2,231, 16,107, 7, 54, 70, 26, + 21, 55,140,184,117, 31, 67,151,143,184, 59, 35,117, 79, 20,254, 24, 47, 39, 66,253,129,173,102, 79, 66,209,183,142,231,108, 8, +200,106,254,122,182,115,153,114,175,205,173,238,103,119,146, 10, 64,134, 47, 75, 49, 40,211, 58, 29,120,154, 35,168, 61, 66,158, +215,234,183, 0,148, 93, 93,107,211, 80, 24, 78, 78, 62, 79,154,174,211,174,155,130, 94,168, 67, 65, 84,156,136,120,163,255,194, +127,224,165,191,203, 27, 65,240, 23, 56, 6, 10, 34,130, 87, 50,198, 46,198,220,148,205, 74,215,180, 73,147,180,201,241,125,222, + 55, 25,213, 93, 9,161,176,182,235,199,233,121,191,159,243, 60,234,191, 8, 9, 90,235, 54,231,206,157,110, 93, 70,179, 0,198, + 96,133, 29, 21,199,170, 27,169,110,199,233, 70,142,246, 65,171,229,122,134,246,139, 79,127,122,192,186,120, 46,221, 40, 15, 58, +188,182,244, 99, 64,167,123, 78,167, 64, 87, 64,153, 39,166,190,174,129,187,119,164, 50, 96,194, 25,224, 80,152,126,151, 81, 37, + 14, 12,155,207,249, 35,157,110,164, 91,140,141,206, 53,119,241,250, 43,235,194, 5,215,192, 96, 45, 97,254,191,184, 54,168,250, +151,151,137,178,126,223, 9,101,149, 92,112, 25,186, 23, 90,241, 23,175, 70,173,117, 45, 30, 44, 67, 80, 77, 83,192, 49,243, 59, + 26,170,182,124,152,180, 72,161, 10, 34,145,157,231,243,205, 37,202, 1,124,151,140, 38,210, 50, 17,248,173, 1,230,189,148,237, + 21,186,238, 32,210,218,241,205,220,157,231, 78, 61,243, 77, 25, 36,105, 29,163,134, 13,120, 15,217, 20,245, 78, 78,135,144,147, + 29, 37, 59, 31, 62, 27, 70,148,147, 55,191,127,237,209,213,104,179, 91,245,138,121, 49, 46,146, 89, 69,117, 64, 70,129,112, 86, +205,242, 69,150,149,211,113, 49, 10,148,127,187,119, 7, 9, 54,228,167, 21,109, 68, 9,217,189,112, 69,161,183, 38,237,116, 44, + 45, 23,185,214, 56, 27,145,199, 52,220,125,243, 64,194,200,117,134, 5, 29, 19, 16,107,148,208,206,100,142, 13,124,183,172,152, +176,224, 54,180, 53, 56, 41, 82,191,210, 97,205, 84, 81, 2, 36,229, 84, 30, 43,150,207, 11, 74,194, 78,198,199, 60, 32, 53,148, +186, 62,184,241,144,121, 90, 74,122,133,213, 78, 95,166, 44,173,230,174, 66,102, 71,161,174,204,132, 7, 11,114,131,224, 6, 0, +122,135, 1,154,112, 31,207,238, 62, 47, 64, 93,169, 38,197,164,228, 57,103,171, 91,220, 40, 24, 7, 62,152,218, 30,111, 62, 9, + 3, 77,241,120,146, 79, 48,163, 99,219, 81,144, 5,115, 7,189, 13,250, 17, 46,197,107,158,231, 31,254, 62, 68, 81,102,219,179, +124,170, 61,109,131, 93, 54,167,244,127, 99,245,138,239,209, 22, 82,219,223,182,247,126,236,201,156,157, 2, 85,228,235,114, 81, + 80, 56,100, 89, 6,140, 64, 40,220, 6,174,222, 61,222,165, 45, 71,182, 65,159,252, 44, 61,139,194,152,253,183, 29,235,120,206, +185, 57,217, 87, 28,196,100, 52,177,238,200, 52,130,167, 60,168,130, 13, 98,134, 41,217,203, 82,164, 15,252,206,245, 78, 31,236, +225,192, 31, 99, 75,129, 30,129,185,159,193,233,110, 27,122,143, 4, 36, 14,148,128, 91,133, 1,163, 67,182, 40,206,138,124,152, +167, 71,105,242,115,154,176, 72,186, 41, 22,139,117, 47, 92,137, 58, 34,249,172,254,242, 36,156,130, 90,243,131, 47,251,195,233, +232,251,233,241,209,215, 3,122,236,253,199,157,215,239,222,210, 67, 91, 91, 79, 67,189,218,226, 48,254, 73, 29,221, 72, 15,110, +221,188,247,242,197,171,157, 55,159,250,250,178,131,225,182,207,141, 75,156, 24,193,222,128, 83,192, 24,134,185,174,113, 8,175, +132,134, 30,250,242, 20, 44, 43,246,245, 25,160,186,140,149,172, 77, 11, 72,111, 15,132,182,122,154,102,217,178,154, 68, 88, 16, +241,109,105, 80,137, 97, 53, 22, 39, 67,134,230,216, 84,251,255,158, 2,136,182, 18,208, 48, 3, 36,107,232,124,233, 6,187,210, + 40, 11, 91,195,201,105,221,182,149, 91, 38, 2,179,244,238, 53,179,141, 32, 50, 85,130, 34, 49, 96,187,148,184, 91, 55,252, 62, +114, 30, 75,152, 63, 26,138,200, 54, 52, 9,151,193, 82, 26,202, 96,209,165, 47,205,247, 88,181, 57, 39,116,230, 39,255, 17,128, +175,107,105,109, 34,138,194,115,231,145,121,164,233, 36,166,212,166,169,165,180,130, 22, 23, 22, 93,139,224,218,165, 43,117, 81, + 68, 92,137, 63,209,165, 47, 68,148, 10, 82,137,148, 90, 16,146,148,182,233,188,238, 60,238, 92,207, 57,119,102,154,170, 24, 6, +178,153,144,185,119,206, 57,247, 60,190,115, 62,253,255,150,157, 28, 88,213, 94, 52,111,220, 13,118,145,156, 65,134,107,240,242, + 92,230,153,154, 5,145, 78, 80, 4, 65, 49, 67, 76, 66,233, 14,189,181,190,219, 55,113,230,185,229,217, 30,178,135,130,163, 32, +237,150,134,160, 70, 19,167, 32, 18,232, 15, 83, 16,134, 98, 44,172, 89,156, 44,149, 75, 50, 41,155, 79, 25, 11, 21, 21, 96, 88, + 74, 85, 70,173, 74,101,147, 83, 97,208, 20,114,120,212, 84,196, 97,126, 42, 8, 81, 48, 9,127, 21,165, 26, 38, 94,247,140, 41, +146,195, 75, 21, 8,138, 52, 77,103,126,233,168,249,148, 56,130,195,137,139, 60,202, 19, 54,239,181,252,219,190, 75,226,102, 23, +227,112, 42,254,196, 81,214,195,247,105, 84, 5, 98,101, 5,211, 26, 18,151,242,210,133, 37,176,250,163,200,103, 74, 89, 39,183, +145, 12, 76, 40, 59, 11, 94, 37,207, 69, 20,227,149,196, 16,186,202,156, 67, 68,202, 58, 14,232,191,233,216, 26,236,181,219, 2, +171,162, 5,103,147,111, 95, 71, 81,156, 26,172,234,211,248,184,255,229,228,120, 22, 21, 28,153, 76, 74, 80,101, 65, 2,136, 95, +185, 38, 82,145,242, 2,214, 31,244,172,222,162,217,163,167,102, 28, 75,130,232, 19,103, 89, 74,116, 2,106,146, 51, 83, 80, 32, +199,176,113,180, 61,190, 28,112,246,203, 12, 11,101, 26,113, 84,181,192,245,199, 49,200, 58, 97,161,136, 44, 69, 39, 40, 49,253, + 92,191,210, 94, 34,128,160,174, 58,108,117, 53, 62,178,142,129, 96, 7,112,176,143,206,108,195,182,117,251,170, 63, 0,215,248, +195,247,119,146, 48,165, 60, 11,193,171,253, 75,104,245,165, 78,223,208, 26,132,155,236,122,221,237,225,246,246,240,166, 36, 36, + 79, 46,210, 31,227, 17,248,107, 88,207, 37, 17,112,105,108, 78, 99, 25, 96,153,158,229,193, 97,115, 56, 61, 72,211,164, 78, 71, + 33, 23, 13,117, 3,148, 60,205, 38,179, 49,104,233,207,227,195,182,211,166, 30, 0,221,107,181, 65, 32,163, 44,164, 9,202,168, + 26, 32,243, 89,158, 33,255, 19, 8,191,105, 58,150, 3,178, 4,135,250,250,210,250,162,235,111,173,108,250,222, 34,207,147,142, +239, 63,122,248,100, 58,155,162,159, 8,239, 52,197, 3, 47,203,211,115, 62, 67,132, 46,211,195, 56,138,146, 96,208, 95,129, 48, +109, 18, 32,167,121,192, 19, 46,168,192, 72, 57,219, 5,187,141,217, 33, 74,137,149,228, 64,198, 69,118,173,187, 42, 48, 19, 45, + 43,225, 71, 82, 83,166,206, 40,154,253, 12,190,109,166,108,117,129, 68, 30, 66, 80,134, 7,142,177, 56,229,227, 48,154,128,184, + 72,176,167,120,251,157,254, 50,245,178, 53, 92,247,178, 25, 55, 53,112, 7, 27,119,175,239, 12,183,110,111,222, 88,219,217, 88, +246, 86, 31,220,191,183,251,114, 23, 54,228,211,251,183,175, 30,191,168,239, 68,134, 55,126,206, 63,191,222, 91,235,220,138, 14, +162, 40,158,140,222,236, 61,127,250,236,104,255, 8, 98, 50,120, 19,160, 98, 88, 25,210, 74,158,243, 51, 44,189, 56, 39,209, 41, + 54,142, 50,133, 58,199, 64,208,119,123, 78,203, 17,146,140, 62,101, 55, 20, 85,105,117, 6, 40, 3,218,216,229, 74,135,216,133, +126, 86,101,205, 6, 1, 92,221,211, 64, 31, 5, 10,155,133, 57,125,183,167,218,242, 20,192, 13, 14,146, 4, 66, 92, 66, 71, 98, + 61,151, 92, 50,207,105,215,152, 75,218, 97, 65,127,193,212,191,227,102,230,178, 32, 60,172,108,174,234,121, 84,178, 94,170, 14, + 85,226,168, 36,203,222,184,141,240,118, 22,156,142, 82, 2,108, 18,146,108,190, 67,135,214, 81, 77,142, 87,172,176,205, 85,214, + 83,205,202, 57,219,255, 91, 0,194,174,101,183,105, 32,138,122,198, 73,157,164,117, 40,106,139,218, 42,221,116,131, 90,216,176, +224,241, 7, 44,144,248, 26, 88,242, 61,136, 13, 59,126, 0, 9, 9, 80,165, 46, 88,128,132,168,148,144,164,113,227,212, 77, 60, +182,227,215,152,251,176,157,150,135,200, 34,146,101,201,178,199,158,251, 62,231,252,191,254,222,110, 88, 10, 33,118, 21,175, 72, + 89,147, 41, 3,106, 34, 69,148, 93,211, 70,129,102,145, 84, 45, 6,136, 61, 19, 55,117,205, 80, 28,111, 31, 25,182,113,230,159, +169, 68, 89, 18, 35,163, 92,226,180, 34,118,148,225,147, 70, 46,228, 28,113,243, 5,119, 19,120, 14, 28, 12,153,182,144,133,166, +102,129, 39, 15,192,253, 69, 26, 89,229, 12, 60, 66, 96,125,131,120,144,214, 54,154,109, 88,196,190, 58,203,137, 59, 84,211, 32, + 12,132,151, 58,103, 17, 20, 45,202, 85, 40,147, 23, 81,235,121,144,150,174,241, 91, 43,152, 90,135, 16, 79,101,105,246, 39, 21, +218, 63, 10, 60,165, 67,151, 72,196,167,197, 53,206, 53, 76,239, 11,228,181,128,135, 72,209,115,136, 18,224, 80,249, 88, 89,213, +234,116,213, 41,168, 4, 98,216, 42,227, 50, 55, 36, 92, 25,103, 90,224,225,183,186, 45, 2, 79,147,192, 97, 19,201,126, 59, 26, + 54,176,217,177,192,194,166,150,185,182,191,183,235, 47,194,109,219, 86, 23,211,129,227,164,112, 22, 99, 50,156, 21,237,202,219, +216, 92, 66, 25, 38, 51,101, 56, 52,161,170,169,136,174,145, 0, 29, 94, 95,142,210,151, 61,187,247,213,115,145,207,153, 16,185, + 68, 38,147, 83,168, 76, 66,218,130,243, 85,209, 89,223, 72,252,132,239,186,160, 92,135,171,242,200,182,144,229, 44,217, 41, 72, +219,132,128, 14, 60, 51,132, 73,176, 31,205,145, 72,174,168,100, 20, 37,199, 19,210,208,186,134, 4, 99, 33,126,169,224,112,170, + 38,118,203, 14, 35, 69,140, 12,154,188,111, 77,150,176,250, 65, 26,113,125,104,108, 30,205,189,208,195, 44, 4, 41,160,179, 36, +214, 97, 58,109, 8, 33,170, 22, 57,218, 53,136,160,215,172,150,217, 94,196, 8, 46,117,149, 11, 23, 8,146,136,183,138, 36,147, +129,125,221, 34,237, 52,214,151,200,195, 46, 73, 80, 64,187,254,148, 67, 31,199,119, 24,173, 11, 11,213,164, 26,209,216, 27,195, + 9, 75, 88, 56,228, 46,132, 10,249,182,151,253,139, 1,196, 64, 19,111,162,150, 1, 44,251,149,119,249,246,221,107,194, 65, 24, +135,187,135,167, 63, 78,153, 66,147,135,247,218, 86,139,145,201,163,217,216, 36, 40,111,156,197,247, 14,142,199,179, 81,148,132, + 12,224, 65,121, 16, 10,244, 50, 42, 64,195,141,194,195, 30,237,222,237,207,157,254, 98,162,105, 56, 42, 55, 86, 0,119,166,138, +186,140,195, 10,106,142, 47, 69, 99,139, 72, 18,208, 95,248, 73, 60, 81, 11,134, 89,132, 89,182, 71, 74,182, 72,142, 79,184, 42, +150, 52,134,192, 33, 79,115, 76,160, 13,227,187, 51,104,174,183,140,208, 8,194,224,211,201,201, 78,111, 31,190, 98,231,219,144, +247,221,147,251,143, 62,126,249,240,236,225,211,211, 55,159,207,207,175, 94,189,124, 49,186, 26,169,247,193, 86,119,243,241,243, + 7, 63,135,144,253, 24,119, 54,118, 46,212, 20,118, 44,120, 27, 8,210,193,178, 35, 11, 48,133, 15,120, 17,148,241, 65, 57,151, + 40, 90, 18, 72,206, 96,170, 93, 93,113, 50,234,149, 96, 81,217, 96, 44,203,109, 76,196, 85,220,104,251,214, 21,154, 27,152,202, +234,224, 86,103,243,220, 11,102,193,140,198,185,204, 27, 5,216,130,113,145, 56,233, 28,232,120,138, 66, 46, 57, 87, 80,200, 15, +160,226, 99,138, 12, 82,204,124, 46,122, 91, 7, 67,119, 80,252,189,141, 39,106,115, 45,235,234,188, 40,109, 1,252,145, 76, 5, + 30, 66,182, 7, 47, 58, 91, 33,195,217, 66,148, 85,250,250,193,181,177,234, 48,234,213, 20, 12,250,255, 95, 2,208,117,109,187, + 77, 3, 65,212,235,189,216,137, 29,231,210,196, 20,164, 64,139,104, 43,113,169, 84, 36, 36,126,128,239,224,185, 47,124, 3, 18, + 31,129,128,254, 3, 47,124, 0, 15, 72, 72, 72,168, 18, 15, 32,132,138, 74, 91,138,104,211,210,218,137,237, 92,236,101,103,118, +227,164, 69, 68,121, 75,228,120,189,177,231,204,204,153,115,236,255, 85, 99,102, 61,238,113, 98,207, 17,246,137,161, 42,154,153, + 38, 96,200,218,158, 39,130, 64,248, 62,171, 9,226, 98, 93, 5,112,253, 2,107,134, 94,200, 65,249, 43,184, 31,110,220,108,172, +168,171, 3,106, 62,212,169,128,247, 75,197, 33, 66, 16, 71, 72,161,110, 3,149, 56, 83,168,222, 48, 27,172,235, 24, 22,118, 84, +254, 40, 92,226,114, 34, 24, 16,222, 65, 51, 85,221, 86,128, 68,128,166, 2,226, 51,168,226, 69, 42, 76,120, 42,167,182,201,110, +188, 51, 46, 50,104, 28, 66, 74, 10,221,203, 98,162,167,198, 10, 20,209,215, 40,222, 98, 42,219,224,149, 89, 37,223,244,138,229, + 63,166, 29, 86,118, 1,185,207, 26,177, 51,247,150,203,159, 74, 28, 80,246,236,121, 57,127,227, 28, 0, 26, 94, 0,153,231, 24, +244,165,181,123, 49,215,240, 45, 19,186,178,150, 8, 34, 4,197,204, 64, 22,148,208,137,172,121,172, 21,216, 87,219,172,221,228, +157, 38,109,214,105, 35,192, 77, 47,236,187,107,107, 87,218,157,102,173, 78,250,233,222,207, 3, 50,140,232,240,207, 36, 61, 29, + 36, 39, 81,114,122, 56,250,214, 35, 95, 83,186,227,186,123,190,219, 19, 44,181,129,218,193,212,143,112, 12,219,128,234,209,192, +158,131,102,164,209,204, 54,214,230,196, 98,192, 93,243, 4,231,165,127,112, 52, 56,181, 96, 78,193,158,142,164, 26, 27, 63,143, +251, 84, 75, 38,131,136, 2, 5, 12,107, 81,137, 44,120,128,250,192, 14,165,126,213,195, 78, 58, 10,194,226,150,248, 78,141, 51, +231,114,216,132, 64, 34,163, 44,206,113, 92, 96,245,218, 42,153, 94, 43,156, 18,200,137,113,225,209, 26,175, 58, 7, 66,141,101, +180,191,133, 97, 9,140,182,126, 53,192,152, 9,114, 2,157, 90, 7, 2, 6,144,208,229,122,119, 61,202,206,144, 57, 7,207,195, +176, 30, 46,248, 45, 92, 73,241, 96,245,161, 58, 11,193,157,165,240,214,157,238,186,130,246, 56, 62, 83, 40, 80,174,125,145, 81, + 2, 86,175, 57, 87,135,237, 46, 44,213,220, 0,147,126,217, 10,218,150,185, 28, 64, 98, 84, 11, 78, 70,105, 14, 4,143, 31, 56, +161, 99, 9,199,225,156, 47,182, 22,213,119, 62,126,223,214,170, 15, 70, 17,156,200, 56,141,147, 52,233,103, 42, 45, 64, 61, 29, +196,122,159, 15,190,168,160,197,185,104,249, 13,152, 21, 71, 43, 72,135,241, 64, 1,121, 46,212,222, 29, 39,253,183,187,219, 59, +201,113,108,141, 34,153,197,150,122,150, 15, 83,107,148,225,123,104,169, 5,179,120, 0,169,207, 8,117, 88,141, 56,174,238, 88, + 66, 73, 39, 63,207,178,222, 96,144,141,199, 42,204, 11, 74,151,252,186, 52,211,148,104,134,134,166,102,196,230, 97, 0, 21,152, +222,254, 81,126, 2,147,234, 3,235, 60,160, 78,123, 2,141, 98,121, 28,251, 84, 60,219,124,250,254,211,187,229,198,218,155, 15, +175,111, 63,186, 39, 86,120,159,245,159,191,122,185,249,248,201,141,141,174, 58,239, 23, 91, 91,245,170,247,187,127,100, 58, 88, + 6,172, 18,220,134, 2,134,177,225,239, 82, 84,156, 42,162, 86,162, 57,178,133,161,181,232,145,207, 92, 87, 85,114,105,168, 96, + 58, 69,153,130,119, 67,122,209, 99,124, 90, 6,252, 34,142,151, 70,105, 0, 45, 34,126,157, 29,170,211,184,222, 89, 38,196,186, + 0,187,113,108,216, 97, 85,133,202,199, 19, 84,195, 71, 59, 64,169,235,242,144,100,231,181, 74, 3,202,153,133, 33,146,238,247, +118,101, 9,222,139,233,177,204,187, 32,250,142, 7,239, 55, 99, 39,106, 92,203, 17,208,229, 24, 69,213, 43,206, 34,236,156,207, + 90,134,165,230, 83, 73, 63,159, 76, 31,238,114,142,165, 38,167, 2, 48,127, 5, 32,236,220,122,154, 8,162, 56,190,179,221,237, +236,165,244,194,182, 80,192, 16,140,128,240,160,162,137, 74,162, 15,126, 0, 99,252, 68,190, 24, 63,131,207,126, 1,159,124, 51, +126, 1, 73, 32,160, 96,192,210, 66, 81,108,237,150,219,182,221,238,109,198, 57, 51,187,165,133, 68,210,183, 62,181,179,103,207, +109,206,249,255,110,184, 95,149, 71,117,128, 81,140,189,150,146,177, 72, 25,203,122, 9, 23,167, 51, 51, 30, 9,186, 32,146, 41, +107, 36,109,200,154,169,102, 13,102,112,192,246, 14, 17, 10, 52,148,158, 49,167,199,113,241,224,252,167, 67,123,106, 4, 76, 11, + 34,195, 30, 90,192,135,245,216,225, 42,176, 53, 42, 39,117, 12, 84,235,192, 38, 7, 69,105, 16, 72, 7, 10, 5,108,199, 8, 22, + 31, 4,128, 16, 20,104,211,134,202, 66,133,218, 13,186,181,206,145, 31,246, 41,167, 56, 69, 36,176,242,229, 63,167,191,161,165, + 33,230, 51,164, 88,181, 77,192,228,130, 32, 64, 55,207, 67,254,103,146,136,230,181,113, 55,112,253,168,127,221,197, 59, 92,163, +120, 16, 13,212, 20,230, 37, 91, 36, 83, 58, 44,156,121, 21,115, 40,226, 49,143,205,204,143,236, 28,109,198,215,234,177,126, 5, + 17,137,176, 20, 11, 87,202, 17,179, 53,128,202, 66, 15,135,157, 11,136, 62, 34, 24, 44, 10, 3, 22, 69,245,237,157, 31,172,198, +107,218,173,239,181, 38,230,153,133, 71, 40,203,177,251,241, 42,147,212,129,131, 37,138,212,215,113, 63,111, 66,127, 37,244, 51, + 36, 42, 40, 72, 67, 44,220, 34,141,197,212, 46,233, 67, 37, 6, 0, 68, 58, 16, 86, 37,176, 94,224, 80,158, 17,195,141, 34, 47, +222, 5,145,155, 47,225, 9,123,229, 73,153,211, 80,100, 85,100, 83, 6,214,152,171,154,159, 90,172, 52,246, 56,186, 21,246, 3, +152,175,100, 94, 30,136, 39,148, 88, 25, 24,146,243, 35,207,113, 79, 37,177,238, 36,110,172,147,147,162, 28,246, 77,121,109,180, +119,188, 59, 48,250,185,226,156,221, 61,233, 38, 36, 4,148,156, 97, 49, 55,209, 62,111, 9, 98,170,211,115,162, 40, 64,131, 18, +137, 74, 46,113,123,103,174,137, 77, 21,160, 19,238, 90,117, 45,157, 82,173,108,201, 50, 75, 91,245,117, 65,178, 22, 23,152,181, + 70,149, 29,190,235,245,236,139, 22,130,107,124, 3,118,220, 49,102, 41,121,185, 80,182, 29, 27,106, 20,110,175,236,143,244, 2, +183,210,220,101,129,124,117,113,117,255,184,242,203, 62, 20,113,229,150, 53,219, 56,111,248, 94, 63,197, 37,161, 41,103,216,178, + 39,190,114,251,222,198,193,214, 73,167, 45,164,214,178,122,142,189,210,214, 88,241,130,189,216,112,243,140, 12,221,152,202, 78, +178,199,122,216,172, 11,114,111,206,204, 95,244, 28,172,232, 62, 76,172,123,122, 74,153, 28, 43,125,174,125, 93,107, 87,174,217, +106,106,104,176, 11,197,253, 24, 73,240,130,226,141,211, 96,116, 4,131,207, 50, 68,138, 68,218,110, 71, 83, 20, 11, 68,162,209, +131, 66,177, 14, 58,204,136, 75, 65,132, 44,150, 96, 37,205, 98,255,236,236, 76,125,179,250,104,229,190,159,146,221,191,246,221, +220,194,252,194, 29, 31, 75,101,169,180,190,183,189,181,241,237,227,250,167, 55,239,223, 50,247,103,161,137, 49,108, 45, 45, 47, + 63,121,254,120,233,225,226,171,215, 47, 95, 60,125, 38,101,164,230,102,243,203,187, 15,149,179, 3,133, 15,178, 67,215, 5, 62, + 33,111, 62, 69, 62,116,187, 32,158,186,172,236,226,189, 77,156, 54,122, 98, 91,141,198,138,225, 48, 5,203,131,148,153, 54,253, + 16, 16,119, 73,106, 37,192,218,113, 19, 67, 96, 73, 10,122,193,238,180,233, 80, 94, 21,119, 2,165, 68,219,155, 91,121,181,185, + 15,133, 38, 26, 93, 77,103, 63, 4, 88,185, 36, 94, 26,225,113, 91,195, 90,215,235, 16,254,114,218,157, 22,239,152,197, 8, 87, +145,201, 39, 66,230, 28,112, 40, 56,116,151, 68, 64, 4,115, 64, 35, 78, 70,200,121,200, 3, 85, 44,110, 42,188, 13, 49,220, 94, + 16, 99, 64,151,229,200, 21, 72,213, 64,218, 11,190,254, 39, 0, 93, 87,178,219, 52, 16,134,103,188, 39,118,156,198,161,180,141, + 26, 84, 33, 69,170, 16, 21, 39, 56,240, 0,189,115,230,196,123,112,225, 21,120, 11,110, 92,224,136,132, 84, 56, 32, 36,184,180, +149, 16, 42, 41,173,104,170, 52,193, 77,236,216,142,151, 97,254,127,108,199,105,232, 45, 74,148, 56, 94,102,254,237, 91, 22,252, +213,255,118,226,151,141,247,160,182,147,243,201, 42, 42,192,128, 53,118,195,174, 57,150,218,156,197,190, 23,187,124,151,215,136, +172, 75,186,161,232,170, 2, 73,186,163, 91,154,102, 96,246, 77,195, 36, 83, 0, 8, 60, 31,206,134,243, 44,184,158,243,114, 56, +150,138,233, 60,220, 94,146, 22, 90, 96, 98,156, 32,214, 24, 84,122,224,222, 0, 30,100,186, 6,200,119, 69,227, 59, 60,188,159, +142,231,147,121, 58, 35,104, 45,129, 12, 74,145,131,196, 41, 74,224, 22,228,121,182,218,116,103, 75, 88, 73,186,130, 53,202,207, +190, 58,163,200, 22,104, 25,161,244,192,110, 9, 18,242, 98,226,186, 56,144, 36,173,132, 12, 90,145, 95, 99, 36,217,185,211,235, +143, 78,138,195, 97,158, 11,178, 44,216, 10,131, 41, 54,168,204,232, 48,157,166, 27, 29, 7,100,127,101,170,170, 64,255, 82, 20, + 58,143,193,160,200,100, 74,228, 39,118, 77,171,101,105,131,101,111,191, 30, 43, 5,142, 42,197,255, 31, 87,136, 90,114,229, 69, +130,237, 14, 93, 37,166, 74, 28,173,109,203,219, 93,115,215,151,162, 95,238,145, 23,186, 72, 53,203,138, 90, 4,179, 17, 64, 2, + 65, 82,100,155, 14, 47, 33,253,112,134,186, 56,130,170, 4,173,228,205,214,214,217,232,183,160,221,211, 92,178, 9,214,101,221, +104,180,204, 86, 16,249,215,193,132,127,182,185,182,117,233, 94,224,198, 5,251,163,161, 24,160, 1, 89,178,162,115, 8, 19, 44, +126, 75,183,194, 36, 68, 76, 99,233, 89,131,233, 24,197,182, 93,206,147, 34,120,193, 32,198,104,138, 1, 66, 93,208,186,197,128, +130,180,228,118,221,113,193,130, 17,201, 25, 21,251, 54, 97,224,197,207,208,182,154,227,233, 72,104, 6,149,178, 53, 24, 57, 89, + 97,156, 14, 89,142,109, 54, 39,193, 68, 22,237, 56, 42,237,172,223,239, 15, 79,100, 4,141,241,204,154, 95,130,142,211, 29, 79, +175,252, 40,135,120,242,195,236, 63,218, 63, 56, 62,224,191,198,191,235, 78,198,113, 26, 63,236,238, 29,158, 31, 74,168, 94,137, + 79, 18,235,109,244,206, 71,103, 48, 88, 78,194, 86,125,141, 71,196,140, 10, 50, 53,208,118,208, 69, 17,194,170,192,147,242,194, + 68,151,148,171,201,223,247,131,111,197, 83,151,146,197,171, 21,168, 5,220,105, 13,176,191, 76, 42, 90,190, 41,222,249,184, 76, + 16,171,240,117,147, 72,107,186,209,181,154,187,206,250,199,225,197,153, 55, 77,192,166,152,173,200,116, 48,247,116,248,244,193, +227, 35,191,255,249,205,187, 15,159,190,188,124,253,234,230,130,152,145, 31,223,127,158,254, 57,229,143,176, 49,168,185, 3, 55, +185, 27, 59,157,246,147,237,189, 23,207,159, 93, 49,143,151,167, 81, 28, 53, 84,251,114, 58, 64, 15,214, 88,150,245, 40, 3,123, + 6, 4,197,103,216,141, 76, 58,237,123,231,128,157, 37, 37,167,136,229,168, 19, 1,191,102, 18,165,171,244, 69, 82,110,186, 68, + 16, 79, 40, 43,225, 52,203, 12,251,178,111, 71, 42,130,137,203,178,178,153, 85,111,122,129,135,134, 82,128,195, 23,252,114,177, + 91, 9,165, 98,129, 87,186, 97,186, 81, 0,210, 97, 1, 25,170,201,128,175, 20,222,146, 84, 66,172,105,212,172, 32, 10, 64, 16, +179,152, 23,102, 57,252, 39, 21, 64,188, 44,143, 76,139,228,189, 64,208,148,108, 77,136,128,255, 4,224,235, 90,122,154,136,194, +232,237,220,153,219,153,190, 8,130, 37,196,132, 54,186, 33, 97,199,214, 45, 49, 49,254, 9, 22,198,133, 59, 55,198,191,224, 66, + 52, 13,198,196, 71,112,165,176,213, 63,161, 91, 68,220,144, 42, 72, 10,180,157, 82,250,154,182,243,242,251,190, 59,115, 25, 10, +178,235,162, 77, 51,115,103,206,247, 60,231, 92,135,239,137,219,164,116,125,185,156,118,114,156,104,106, 38,228,122,196, 53,151, + 24, 74, 66,209,144, 21,234,166,102,230,140, 12,164, 24,121, 35,151, 22,150,165,155,166,110, 97, 31, 63,240, 60,236,135,251, 80, +121,101,117, 3,126,210, 26,117, 28,175, 11,177,193,241,156,129,219, 35,123,115, 50,210, 64,178, 90,132,168, 88, 40,132,196,138, +103,104,191,184, 48, 87, 58, 32,230,113,138,242, 62,130, 26,202, 4,133,112,112,178,231, 82,121,230, 81, 51,145, 41,112, 79, 70, +184,240,130, 90,207,255,240, 61, 53,225, 21,126,105,113,254, 26, 70, 84, 20, 24,248,132, 69,107,244,215, 44,210, 76,100,202, 90, + 17, 1,203, 20, 89, 72, 39, 91,189,122,172, 90,140,192, 30, 48, 79, 34, 23,160, 58,199, 97, 29, 79, 11, 20, 30, 40,204,230,125, +174, 27, 80,191,160,244, 14, 36,219,154,227,185,142,235,231, 2, 61,135,180,110,191, 52,149,253,190,119,240,237,207, 73, 38,238, +208,249,241, 18,167,124,239, 13,122,179, 37,132,209, 75,207,148,125,106,150,227, 92,187, 32, 80, 38, 54,244, 69,154,167,125,166, + 13,144,230, 18, 89,156,196,246, 8,200, 32,195,224, 65, 86,241, 52, 24,198, 71, 92,112, 11, 78, 83,122, 19,148,138,119,142, 79, +107, 88,187, 80,109, 28,203,110,203, 65, 42,183, 12, 49, 68,165,195,240, 60, 87,210, 52, 58,121,149, 79,200, 6, 8, 50,194, 22, +138,229,253,250,111, 72,127,241, 75, 17,141, 47,149, 74, 24,105,198, 29,117, 36,249,113, 45, 90,225, 21,134,128,140,251,108,208, +230,196, 42, 51,200,126, 68,233, 66, 75, 19,184,225,120, 0,149,225,104, 60, 66, 61,122, 51, 43, 77,180,139,133,185, 70,183, 30, + 75,177, 50,157,139,169,108,193,238,217,180,177, 31,197, 18,185,213, 3,169, 6,148, 41, 40, 55, 79, 29,106,229,210, 6,161,171, +209, 57, 41,223, 44,255,109, 30, 2,154,195,217, 1, 28,224, 58, 25, 60,249,232,250, 54, 11, 1, 32, 12,125,142, 46, 87, 52,102, + 9,163, 11,135,235,155,159,158, 63,178,107,164, 81, 37, 21, 29,180,153,252,180,221,183,117, 38,229, 14,113,250,164, 97,245,230, + 86,221,206,250,179,183,181, 65,179, 90,171,222,191,187,242,225,203, 70,229,211,203, 4, 86,111,176,197, 85,214, 60,100, 77,168, +120,246, 25,131, 28,127,135,177, 95,140, 29, 51,214, 75,160, 91,154, 64,223,101, 9,249,176,115, 27, 63,171, 0, 55,244,204,117, + 71,163,254,235, 39,207, 31,175, 61,101, 13,199,177,219,112,181,118,235,212, 13,130,207,155, 91, 47,214, 43,187, 63,182, 31,174, + 62, 58,178,155,155,239,223,221, 91,121, 80,121,181,182,184,188,116,123,121, 41,104,247,181, 91,121,121,158,181,159,181,157,189, +221,254,112, 56,216,238, 66,124, 18, 29,247,227,215, 55, 99, 40,102, 60,212,215,132, 91,128, 27, 83,216,239,240,168,166,143,181, + 1,164,210,145,220, 94,196,106, 82,214,145,177,154, 70, 52,116,148, 14, 76,209, 7,158, 96, 0,133, 87,236, 18, 74,205,165, 75, +122, 45,161, 22,139,145,133, 87,213,241,114,205, 38, 94,114,140,172, 1,153, 74,219, 21,178, 75, 22, 82,144,208,105, 9,227, 69, +221, 27,153, 25, 36,181,133, 94, 74, 42,190, 94,176,221, 83,123, 92, 56,150,167,206, 76, 32, 3,150, 20, 76, 83,170, 6, 42, 84, + 4, 74, 51,126,146,185,154, 34,142, 14,251, 39, 0, 97,215, 14,219, 68, 16, 68,119,239,103, 59,118,144,147, 56, 82,148,159, 66, + 26, 20,137, 6, 20, 33,154, 8, 5, 33, 68,129,168,168, 17, 61, 2, 82, 82, 80,208, 80, 81,128,148,130,130,158,130, 2, 10,232, + 9, 10,161, 75, 5,162,161, 33, 38,113,126,216,241,231,108,223,221,122,119,153,157,221, 61, 59, 6, 9,251, 36, 75,150,229,251, +236,221,204,155,153, 55,111,188,255, 50, 35,165,157, 72,109, 90, 81, 48, 69, 99, 81,167,138,206,237,220, 59,233, 90, 3,161,198, +192,137,196, 23, 62,196,143, 61,166, 26,241, 99, 46,186,156, 67,100,151,165, 65,226, 38,224,252, 98,197,135,227,224, 9,192,246, + 79,229, 38,225,236, 26, 44, 82,140,102, 86,143,120, 20,211, 14,118,202,187,166, 87,193,246,160,186, 62, 63,168,237, 33, 35, 85, +121, 48,142,190,147, 73,165, 3, 30, 39,137, 48, 42, 17, 92, 24,207, 46,116, 94,116, 32, 96, 17,127, 87, 25,104, 31,137,167,208, +214,145,150,128, 63, 4,246, 41,177,110,199,152,196,127, 22, 79,164, 51,164, 48,153, 2, 65, 66,102,138,115, 71,205,125,157,126, + 85,196,130, 32, 7,151, 43, 67,131, 40,105,199, 74, 1,205, 96,122,213,178,148, 43, 52,193, 48, 89, 5, 33, 44, 81, 98,142, 70, + 74, 95,205,249,243, 24,202, 29,129,221,103, 76,118, 35,209,137,248,232,136, 51,145,205,140,229,178, 95, 42, 21, 37,136,141,113, +184, 59,160,204,144, 38,233, 18,219,222, 38, 17,191,113, 91,233,205,162,231,242,108, 37, 78, 56, 73,151, 38, 25,215,153, 80, 86, +159,196,220, 13,104, 16,118,105,140,100, 45,223, 85, 41, 26,162, 88, 63,166,131, 75,169,199,153, 26, 56,216,125,167,214,172,246, + 56,211, 84, 90, 0,182,112,203,130, 97,202, 6,106,174, 19,206,215,118,169,161,168,167,236,127,233, 12, 16,153,125, 55,128,189, + 98,163,191, 60,168, 87, 48, 49,149,206, 79,236,227, 36, 61, 81,150,219, 53,154, 25,155, 14,227,118, 24,135,240,119,103, 70,138, +106,170,134,173,112, 40, 98,126,170,172,129,171, 9, 54, 55,134, 35, 68,217,178, 30,239, 53, 59,141,102,212,130, 16, 60,102, 17, + 4,148,197,124,177,147,132, 76,241, 12, 89,163, 93,135,207,241,209,241, 38,132,228,234,144, 20,103,107,161,180, 80,174,149,225, + 14, 84,179, 19,113,198,137,113,228,130, 84, 78,246,125,207,253,221,170, 37, 0, 62,176, 88,167, 39,195, 8, 0,110,146, 30,213, + 15,177, 82,141, 20,103,117,135, 59, 16,187,248,190,223,137,218,112, 98,135,141,195, 82,113,178,224,229,118, 79, 42,186, 12, 12, +225, 2,186, 81,205,233, 32,186,115, 36,146,252,230,165, 91, 43,107, 87,165,106, 9, 34,143,214,201,155, 23,175, 23,207,174,175, + 61,189,143, 30, 60, 38,151,239,146, 87,132,100,102, 9,155, 37, 13, 66,106,104,225,127,226, 86,134,109,135, 84,191, 18,185, 69, +196, 51, 68,252, 57, 98,106,177,168, 60,227,122,177, 74,149,192,162, 39,224, 23,245,101,255,246,227, 59,169, 52,246,118,126,205, + 44, 45,144, 98, 97,154, 76,193,151, 55,170, 43, 60, 12,183, 55, 63,173, 46, 47,143, 79, 22, 23, 47,158,191,253,224,206,133, 43, +203, 25, 47,243,242,201,243,173,205,237,123,143, 31,150, 43,187, 75,243,231,230,167,231,174,175, 94, 35, 45,178,193, 62,191,125, +255,238,227,198,135,185,177, 82,143,245, 50, 94,182, 17,181,244,120, 83,174,223, 20,105,230, 84, 63, 99, 26, 14,153,206, 26, 68, +236, 66,203, 90,184, 40,121,106,201, 35,166,247,206, 76,215,144,166,114,233, 12, 60,216, 34,101,180,209, 65,107, 56, 96, 21,251, +102,242,148,102, 87, 26,217, 96, 37, 40,133,140, 52, 31,228, 1, 86,162, 8,185,149,122, 71,126, 62,237, 43,181,247, 77, 15,252, +228, 56,172,106,100, 64, 79,115,215, 29,174,103,152,234,182, 6, 9,207, 72, 33, 40,213,218,199,137, 96, 67, 49,191, 10, 53, 17, + 97,192,130,141,102,243, 77,165,216, 58, 92, 32, 76, 95,127, 4, 96,236,218,117,156, 6,162,232,120,108,199,175,132,205,138, 32, + 37, 2,241, 40, 16, 44, 5, 21, 5,162,162, 7,209, 64, 75,197, 39, 80, 82,130, 16, 21, 84, 72,124, 3,191,128,132,168,160,216, + 21, 5,210, 74, 11,236, 18, 65, 54, 18,210, 46,144,135, 54,142,147,177,135,123,238,120,178, 6,133, 71, 10, 43, 69,156,196,206, +205,204,185,143,115,206, 31,241,187, 91, 97, 10, 44, 76, 57, 12, 97,209,229, 83, 28,120, 62, 7,154,109,119,185,199,165,204, 19, +159, 21, 5, 2, 25,196,126, 28,122,180, 10,197,117, 47,129,244, 10, 6,225, 32, 39, 0, 7, 59, 41, 34, 15, 29,186, 73,158, 21, +232, 22, 58, 7,179,116, 14, 61,100, 88,132, 82,224,210, 66, 63, 86,227,130,123,162,198,209,156,107,178, 60,129,138,171, 83,216, + 28,216,222, 1,214,116,186,132,146, 76, 25,102,255,219, 82,145, 89, 23,135, 70,222,197, 95, 40, 92,186, 66,237, 21,203, 86,118, + 58,174, 70, 71,193,131,248,229,148,223,201, 82, 82, 44, 21, 99, 46, 55,111, 66,106,202, 81,214,138,197, 12, 63,177, 4, 77,129, + 35, 70, 20,156,178,109, 36,185,241,239, 50,114,101, 11, 63, 8,187, 7,158,134, 26,165, 75,241,237,175,157,109, 23,113,148,209, +221,194, 72,182,158, 43, 61,201,138, 73,170, 58, 73,176, 86,111,188,248,244,121, 60, 87, 39,188,160,223,223,133,234, 33, 99, 33, +186,173,105,165, 80, 99, 50,243, 69,105, 86, 86,202, 53,177, 41,220, 58,236,159, 44,197,152,145, 64,221,135,238, 77,205,149, 73, + 32,143, 53,100,205,235,108,246, 6,133, 85,100,205,217,226, 3,165, 49, 83, 58,100, 73, 15,138,117,130,171,161, 31, 42, 90,227, + 9, 53, 75, 86, 0,118, 28, 74, 48,120,106, 39, 55, 93, 17,199,142,192, 20, 6,199,234, 82,223,147,255, 65, 80,158,224, 78,140, +210,214,215, 82, 50,159,151, 94, 23,213,146,122,216,200,102,233,104, 58, 50, 70,151,173, 70,107, 15, 54,152,214, 75, 30,130,248, + 16,228,178,220, 88, 4,146,201,228, 69,169,219,170,245, 50, 55, 49,102, 48,161,226,234,187, 65, 28,196,105, 54,157,171, 41, 16, +133,118,106, 94,200,163,250,148,154,156,234,125,235,153, 6,137, 85, 12, 55,179,163,136, 62,202,172,234, 33,182,103, 7, 22,146, +185, 81,176,162, 15, 70, 83,212,245, 89,102,146,167,163,192,135,130, 44, 0,204, 26,121, 24, 13, 52, 50,142,144, 40, 76,232,106, +211, 57,251,250,130, 20,214, 0,201, 75,186,214, 39, 20,128,255,220,233, 11, 47,251,239,214,119, 54,170,209,246,229, 85,247,228, +213, 51,252,244,136,184, 54, 20, 79, 45, 82, 95,225,221,219, 65,229, 5,191,247,190, 16, 20,206,180, 56, 60, 23,226,201, 93, 33, + 30,131,121,162, 77, 13, 15,143, 80,122,148,125,239,167,147,128,178,237, 40, 78, 41,126,178,131, 59, 55,110,223,127,246,104,252, + 99,152,207,138,102, 45, 2,191, 55,142,154,171,205,239,221,221,139,151,175,188, 89,127,125,188,221, 81,174,152, 43, 69,112,127, +164,178,135,247, 30,108,189,253,120,235,250,205,205, 15, 91,239,187,219,219, 95,119,250,123,221, 5, 48,186,212, 62,191,146, 52, + 38, 89,218, 12, 86, 6,147, 33,109,201, 72,240,133, 50,137, 32, 45, 7,171, 73,107, 48, 29, 25,149, 9, 48,109,112,116, 43, 72, + 76,179,103,140,178, 14,125, 69,165,159, 42, 74, 27,106,171,128,183, 88,160, 17, 97, 44,111, 96,133, 37,243,202, 76,203,127,104, +229,219,183,214,214, 19,142,191,132, 54, 90,129, 6,101, 87, 7,117,254,213,207,171, 40,235,154,144,180,198,159,129, 27,229,140, + 92,173,194,157,153,109, 61,116,247,131,151,161,244, 64,143,168, 84,129, 23, 72,212,212,103,126, 10,192,215,213,235, 54, 17, 4, +225,221,189, 91,223,157, 29,199, 33,182, 33, 5, 33, 74, 68,210, 80, 32, 94,128, 71,224, 5,120, 11, 74, 10, 10, 10, 74,106, 26, + 26, 10, 30, 0, 42,168,144,160,167,136,144, 18, 5,145,132, 8, 43, 56, 63, 64,236,156,189,183,183,183,204,204,238, 58,150,108, +197,178, 44,123,117,231,187,211,236,206,204,206,124,243, 77,204,174, 11,187, 79,156,119,255,233,186, 65, 5, 8, 77, 20,106,165, +108,200,216, 58,133, 71, 88, 43,194,138,240, 18,100, 82, 42, 81,136, 42,170, 9,228,113,197,150,113, 52,149, 75,163,178, 90, 61, +227, 41,242, 24, 34, 51, 3, 56,116,250,178, 24,230, 5,210, 7,142,204, 8, 87, 17, 9, 13,182,113,221,122, 59,145,181,129, 30, +212,240,111,224,120,139,213,251, 24,202,119,141,200,141,245, 20,252,214,135, 14,152,103,204,154, 90,183,252,250, 68,106, 52, 67, +174, 25, 52, 59,107,165,173,139,241,191,160,220, 39, 93,168, 88, 52, 99, 45,231, 21,151,217,137,127, 90,178, 18,238, 85,198,201, +250,205,205,221,222,118, 40, 39,112,238,155, 17, 19,218, 7,102,111,119,214,127,157,253,144, 68,153, 11, 78,101,100,171, 78, 34, + 70, 32, 78,195, 27,177, 72, 19, 19,151,151,160,135, 7, 10,246,179,165, 47,157, 70, 40, 55, 95,205, 26, 95,246,123,251,231, 67, +112,225,147, 38,127,176,177, 88, 40,236,180,135, 76,147,218, 40, 77, 86,177,172, 70,218,230, 6,115,173,121, 8,190,235,192, 70, + 4,223,255, 82,196, 70, 34, 25, 61, 90,242,166,100, 32, 30, 85, 98,125, 95, 34,209, 77, 63, 58,183,235,221,227,141,174,252,142, +205,118, 16, 81, 67,251, 84,228,170, 23,174, 86,132,226, 47,130, 98,241,196, 5, 72,185,120,203, 82,153,129, 51,171, 80,225, 98, +172, 90,138,120,181,179,122,120,122, 0, 39,183, 27,203,167,195, 19,208,167, 50,138,177, 17, 37,229,187,224,160,118,163,253,123, +216,231,100, 2,157, 76, 42,151,142, 97, 54, 31,227,108, 89,170, 47,101, 50, 67, 26, 50, 4,156, 12, 29,159,176, 91,197,205,180, +165,176,247, 72,160,154,100,142,220,213,174,117,214, 16,187, 70,195, 53, 17, 83,120,183,154,102,155,240,124, 26, 92,140,171, 66, +231,133,147, 84,183,117,171, 33, 27,135, 39, 7,212, 67,156,237,247, 15, 5, 85,252,187,106, 22,138,210, 27, 87,234,130, 64, 70, +173,148, 46, 28, 80, 84,248,118,108,120,189,145,202,115, 42,103,207,226,236,238,202,230,183,159,219,139, 73, 29,153, 24, 4, 5, +115, 25,239, 46, 44,195, 67,221,233,172,237, 29,239,193,236,128,185,151, 36,201,159,193,153,241,176,105, 27,208, 19,209,168, 82, + 53,203,118,143,118, 60, 51,110,184,247, 15, 95, 63, 62,127,242,226,217,203,167,140,117, 89,155,177, 38,137,249,130,177, 77,146, +171, 9, 63,123,100,201,193, 16,108,193, 73, 43,158,113,128,107,138,210,224,107, 92,149, 41,140,136,136,202, 71,200,240,136,248, +245,187, 55,240,150, 52, 97, 30, 63,124,212,108, 45,188,122,255,118,145, 37,176, 24, 47,108,190,117,255, 94, 49,143,137,246,243, +206,167,217, 65, 16,116,123,225, 6,236,180,180,214,253,162,143, 92,213,168, 98, 76, 61,170, 43,152,170, 6,220, 62,137,173,154, + 4, 53, 28,137,168, 9, 76, 28,163,197, 23,161,158, 29,179,237,160,121, 52,122,119, 66, 19,188,223, 16,184,154,103,105,154,171, + 1,103,147,109,185,157,223,169,205,121, 17, 30,142, 98,130, 77,224,215, 81, 80,249, 44, 84,160, 9, 99,222, 67,241, 1,242,128, +117,228,211,128,160, 43, 98,199, 57, 74,130,160,123,194,105, 87,120,130,136,174,143, 36,154,149,154,142,225, 91,207,134,237, 24, +229,201,133,199,237,160,225, 87, 76,174, 14,220,232,243,171,180,224,204,127, 1,248,186,154,222,166,129, 32,186,187,222,117,156, + 56, 37, 31,141,160,237, 5,169,128, 4,103, 14,156,249,121, 72,136,191,192,141, 63,212, 11, 20,137,143,170,105,229,196,169,219, +216, 78,236,216,187,203,204,108,236, 54, 17,173,148, 91, 34, 71,222,143,183,111,102,223,188,145, 79,128,123,219, 53, 91,108, 31, + 77,137, 64,230, 18, 6,232, 6, 35,154,131,216,221,100, 10,215,154, 22, 49, 2, 19, 3, 28,205,156, 69,109, 1, 91, 84,165,107, +201,177, 31, 92,135, 43, 24,211,187,213, 2, 54,164, 14, 6,100,142, 42,201, 75, 70, 58,189, 58,137,243,181, 6, 20,128,189,192, +128, 10,240, 33,239,158,132,199,147,254,120,154, 93,207,215, 51,197, 37,118,227, 52, 48,159,165, 54, 30,229,118,237,224, 96,146, + 22, 75,234,127,102,218,238,131,118,103, 98,237, 94,179,145,125, 79,205,255, 77,170,239, 5, 28, 15,158,205, 3,251, 80,206,118, + 18,107, 79,156, 25,173,169,240,253,213,247,179,238, 56, 89,199,223,175,206, 90,247,133, 7, 17, 18,107,234,200,108,156, 92,194, +228,172,224,104,180,182, 79, 51,242, 59,195,234,196,174,176,201,218, 72,175,142,242,248,227,135, 99, 27, 98,167, 39,230,105,146, +207, 11, 94,138,139, 69,114, 22,207, 2,169, 2, 37, 86, 69,137, 69,139,134,111, 80,213,142,125,180,123, 10, 32, 4,165, 2, 69, +197, 54,149, 46, 52,222,135,148,154,173,145, 50, 97,198,198,111, 42,184,130,134,206, 11, 90,122,146,132, 55,181,230,232, 9,135, +205, 56,121,158,177, 87, 47,184, 84,225,207,168, 64, 96,167, 14, 30, 24, 4,248,157,158, 63, 72,178,152, 86, 29,194, 60,112,119, +228,183,232, 17,225,196,127,122,212, 27, 28, 13, 79,126, 69,231,240,255, 23,241, 95, 55, 86, 68,253,137, 22,176,186,157, 13,248, + 65,180,140,152,235,253,183,141,169,249, 65,119, 4,152, 14,180,125,150, 34,238, 47,242, 69, 32,187, 84, 6, 40,240, 2,214,181, +182,225,104, 80, 12,136, 9,240,236,123,157, 48, 8,111,243,196, 41,246,199,189,201, 69,252,199, 90, 87,134, 14, 4,137,187, 11, +164,214,189, 99,235, 4, 66,201, 19,231,202, 72, 39,176,185,190,141,200, 24, 18,227, 7, 96, 25, 82,170,178, 92, 43, 21,148,213, +218,208,190, 11,252, 46,188, 33, 32, 59,137,246, 24,111, 24, 35,138,208, 5,197, 37,130,167,101,238,209,179,243, 34, 63,191,250, + 1, 28,159, 60,132, 73,104, 79,225,196, 60,187, 1, 62, 56, 77, 46,145,217, 96, 53, 83,138,166,178, 64,193, 55,233,182, 88,183, +105, 44, 9, 99,254,114, 56, 57, 25,140,151,243,204,151,170,198,170, 75,180,167,186,154, 78, 79, 79,223,184, 66,108, 0, 94,252, +140, 25,123,215,220, 25,109, 8,241,225,179,160, 57,246, 8,238,155, 44,200,158,119, 7,188,233,235,195,231,179,187,196, 29, 96, +192,177,180, 81,195,142, 15,219,118,121,147,124,254,242,233,232,253,219,175,252, 91,127, 52, 52,240,133,237, 84,181,246,173, 79, +118,170,100,149,160,235,199,124,156, 80,171, 42,123,139,244, 38, 45, 86,253, 78, 24,101,183, 5,181,204, 46,117, 5, 27,188, 48, + 85,137,182,163, 24,179,135,234,217, 48, 28,193,138,198, 85, 34,125,129, 12, 79,114,236,253, 78,154, 42, 83,115,173, 44,185,116, + 3,185,192, 37, 88,139, 94,128,206, 37,124, 35,182,206, 19,220, 29,178,102, 55, 95,226,246,189,177, 13,207,135,209, 59, 60, 56, +140,239,230, 66, 8,182,147,207,121,200,190, 77,155,134,119,153, 50,135,236,198,213, 72,109, 69, 47,172,145,135,240,125, 37,133, +221,225, 16, 77,165,136, 91,224,198,161, 60,156,166, 20,163, 61,166,221,184, 39,149,141, 98,158, 2,113, 12,247, 49,124,212,173, + 62,135,128,254,159, 0,124,157,219,110,211, 64, 16,134,125,196,174, 93,210,186,180,161, 21, 18, 21, 23, 72,136, 27,170, 94,129, +196,203,160, 62, 15, 87,220,242, 52,220,150, 7, 64, 2,132,138, 82,165,165,173, 19, 39,196,235,117,246,192,204,172,215,135, 6, +136,172,220,228, 32,203, 94,207,206,254, 59,243,253,193,191,131,123,183,185,218,178,221,141,248, 78,114, 42, 33,144, 72, 0, 39, +121, 23,231,138, 86,215, 87,198, 65, 74, 27,214, 35,238, 7, 70,240, 78, 22,152,101, 93,230, 85, 94,114, 36, 53, 23,245,130, 42, +223,209, 59,156, 42, 68, 96,106, 14,211, 7, 41,172,223,179,120,132, 13, 65, 1,100, 47, 15,247,147, 44, 9,227,181, 82,227,248, +113,236, 37, 87,108, 10, 15, 81, 72,206, 31,144, 98,194,220, 14,227, 58,199, 4,199,148, 70, 25,192,218,102,188,246,238, 57, 5, +246,195,186,133, 48,245,127,101,132, 96, 92, 28,113,140, 26,253,127,243,220,193,111,251,159,245,255,188,169,148, 15,104,249, 46, + 9, 68,179,100, 51,194, 57,180,250,175,106, 41, 34, 29,236, 13,101,238,106, 73, 81, 39,177,107,235,128,174,115,160, 48,188,194, +232, 77, 93,121,117,241,253,104,255,240,224,209,222, 45,175,165, 80,137,231,127,186,184,252,122,151, 39,129,159,250,218,173,126, + 51, 88, 21, 81, 83, 10,185, 17,171,128, 54,112, 34, 20,124,116, 8,151, 46, 10, 43,200, 16,164,179,226,114, 27,155,209,213, 82, +209,205, 51,253, 86,246,128,220,187, 36,164,252, 22,230, 79, 72, 21, 75, 33,100, 19, 25,181,226,234,105,198,127,252, 18,138,138, + 75,124, 34,173, 74, 81, 23,242,166,171,127,161, 72, 25,249,240,228,215,164, 45, 56,105,180, 83,176, 57,195,254, 26,215, 86, 59, +224,208,198, 62, 50, 82,243,165, 20,182, 8,194, 49,186,138,182,169, 3,185,190,168, 98, 53, 55, 20,111,136,185,175,159,191, 57, +255,118, 46,101,219,131,166, 45,198, 9,238, 90, 77, 32, 51, 23,146,193,186,172,141,157, 0, 60, 52, 57,187, 53, 80, 73,221,124, + 83, 14, 42, 29, 60,111,111, 43,139,163,120,114, 55,177,183, 87,165, 81, 74,109,235,144,204,115, 42,210,146, 48, 80, 9,203, 24, +238,164,187,211,188, 36,131, 8,211,107,131,231, 73,126,136,200, 44,178,164, 58, 88,139, 58,163,116, 84,148, 5,118, 96, 34,153, + 0,217,200,108,205,145,175,226, 17,239, 1, 43,199, 76, 43,184,134,217,120,197, 16,179,172,154,245,178,193, 46, 53,180, 38,223, + 74,183, 16,230,224, 36,223, 30,191,252,114,243, 19,209,123,126,211,149,122,118,246,238,195,251,143, 70, 98,113,182, 73,135,135, + 49, 52, 33, 89, 6,206,166,117, 91,122, 65, 43, 53,152,201,153, 99,125,148,189,126, 31, 72, 28, 6,167, 71, 79,102, 21, 90, 20, +174,117,215,116, 39, 72, 6,129,197,232, 46,117,170,113, 3,243,114, 16,108,164,140,209, 23,185,143,146, 55,253,255, 94, 51,190, +248,124,189,248,219, 39, 77,237,166,235,199,144,132,204,235, 57, 28, 7,217,171,195,241,201, 90,230, 82, 92,251,100, 84,232,135, + 17,196, 52,244,236, 19, 76,224, 82,201,211,100,205, 33,181, 40, 33, 33, 83, 12,231, 0,101, 97, 92,180,195,225, 81,104,186, 39, +152, 40, 43,226,224, 80, 16,194,236,153, 91, 19, 37,199,154,235,169, 62,139,176,137,213,198,145, 85, 53,143, 48, 28,199,227,103, +211,252,178,150,220,213,238,112,123,207,209,195,188,125,192,150,236,106, 35, 27, 36,253, 70,136,119,155, 16, 37, 55,230,133,110, + 39, 29, 33, 96, 88,158, 32,101,111, 35,209,253, 35, 0, 97,215,178,219, 52, 16, 69,231, 97,123,156,230, 33, 64, 66, 44, 0, 5, + 85, 66,116,135,216, 84,252, 6,236,248, 14,190,162,124, 3,127,194,138,125, 89, 32,177, 1, 82,164,180,149, 32, 14,109,169,113, + 98,123, 50,158, 97,238,189,142, 51,105, 16,100,145,101,228, 36,227,235,115,207, 61,247,156,136,109, 96,227,214,172,153,111, 5, + 92,180,209,201, 8,222,219, 18,239,107,136, 70,228,190, 22,219, 59,188,201,129,183,241, 32,207,183,159,125,217,239, 39,123, 74, +246,250,145, 18, 16,134,231,159,231, 69,174,127,131,131,160,239, 1, 45, 80,209,218,195,157, 21,124, 44,218,120, 73, 37,227,145, +236,137,100,168, 32,212,188,151,196,137,199,149,145, 76,180,181,216,159,201, 94, 60,124,162, 70, 89, 61,155, 47,102, 49,139,157, + 32,131,124, 15, 17,133,107, 39, 24,102,231,171,176,176,178,187, 45, 71,124,190,230,160,108,128,167, 55, 66, 83, 52,129, 34,215, + 89, 30,116,103,225,200,244,111,138,199, 80,219, 78, 94, 80, 24,200, 37, 58,101,204,102,130,205, 59, 31, 78,214, 78, 47,108,233, +108,202,128, 43,215, 4,173,168,153,197,102,250, 78,204,110, 15,226, 81, 42, 7, 96,142,110,142, 63, 76,206,125,103, 26, 69,215, + 90, 47,128,167, 1,172,230, 32,202, 21,114,163,140,146, 46,130, 77,137,218,250,182, 73,164,146, 21,208,200, 66,165, 6, 31, 78, + 72, 82, 4, 95,112,205,228,170,241,213, 94, 38,232, 68, 93,130,194,201, 86,208, 39,178, 61, 1,208, 94,225, 3,205,248, 70, 10, +247,203,116, 3, 20,252, 48,145,198, 35,166,134,223,187, 21,253,184,182, 49, 85,105,206, 86,232, 2, 99, 37, 26, 22,208, 76, 67, + 50, 80,224, 96, 98, 3,176, 22,186, 34, 87,238,237,145,180, 43, 40, 93,171,219, 32,115,193, 15,136,148,188, 4,145, 17,217,105, +210,217, 7,124, 61,153, 77, 72, 39,192,130, 54, 86,180, 59, 86, 2,213,112,208,234, 14,212,160, 54, 53,162,251,221, 20, 46,167, + 34, 5, 45, 26,221,202,214, 93, 46, 46,199,189,113,240,196,198,193, 1, 0,112,237,120, 59,155, 45, 77, 89,193,206,186,251,142, +123,170, 22, 27,244, 69, 77,127, 23,215,198,116,183,144,105,181,174, 22,185,117, 59, 72, 71,249,242, 87, 26, 43,200,113, 54, 90, + 91, 35, 26,209, 72,158,128,127, 39,250,116,118,108, 43,169,160, 49, 48,145, 8, 9,209, 5,194, 83,248, 3,103,167, 23,217,235, +151,175,166,243,243,119,211, 79,116,181,135,251, 79,239, 31, 60, 58,122,123,132,205, 88, 2,135,134,224,195, 18,223,159,173,191, +213, 25, 99, 25,146, 51,224, 65,195,218,131, 6,246, 18,155,227, 60, 74,210,207, 63,179,188, 42, 85,172, 12,102, 20, 1, 62, 4, +185,150, 68,141,147, 77, 31,239, 79,223, 31,147,171, 19,185,208, 99, 36,125, 3,218, 23,107, 82, 25, 85,255, 43,241,255,126, 61, +184,123, 80, 20,217, 69, 1, 73,170,243,171,143,253,241,139,135,207,223,212,249, 23,177, 56,129, 37, 72,127, 20,231,103,166,202, + 93,126,194,202,175, 16, 88,227,175, 10,130,215, 26, 65,219, 78,228,112,200,108,199,152,220, 20,203,180,194, 16,187,182,105,228, + 87, 75,116, 43,131, 65,152,109,101,236, 65, 53,224,220,117, 44, 94, 39,201,115,157,231, 35,115,167,217, 55, 75,125, 33,223, 98, + 6,110, 24,247,216, 64,123, 23,224,193,181, 16, 38, 44,241, 34,224, 32,236, 14,171,179,253,208,104,192,135,188, 35,164,218,234, +253, 71, 0,202,174,223,197,137, 32, 10,207,204,206,206,102,243,227,146,179,136,114,156, 86,222, 63, 96, 33,130,104, 97, 33, 28, +216,216, 93,163,224,127, 96, 97,101, 99,103, 41, 22,214, 86, 90, 92, 39,135, 88,216,139,141,156, 65, 17, 4, 65,114,162,160, 57, +127, 36,187,155,219,236,102,103,198,121,111,102,147,221,200, 21, 54, 33,236,194, 6, 38, 59,223,123,223,188,239,125,143, 87,251, +152, 86,192,189,138,236,149,226, 42,142, 67, 6,192,129,136,161,136, 11,145,134,181,115,194, 5,225, 6, 40, 66, 22,130, 24,192, +227,154,178, 28, 44,173,180,206,129,132,134,140,107,132,173,220,121, 17,154,220,137,217,146,253,156,128,209, 32,160, 53, 55,168, +106,178,125,127,141,232, 30,252,164,111, 46,154, 52,204,167, 94,147,138,134,175,142, 84,113, 42,220,104,178,112,152, 28,248,138, + 3,132, 73,236,205, 39, 57,170, 40,153,170,175, 4,173,233, 29,157,143,124,105, 43, 22,160, 49,164, 61,135, 40,121, 13,163,139, + 29,196, 22,150,157,255,234,213,201, 49,212,179,142,240, 64,240,209, 42,195,171,187,250,128,212,212,173,155,157,167, 10,223, 67, + 6,149, 59,179, 61,198,245,103, 11, 96,216,180,223, 36,235, 45,222, 9,120,161, 89,150,169,113,174,162,204,132, 76,153, 26,112, +194, 0,160, 49, 6,116,133, 23, 10,195,132, 32, 25,131, 73,175,112, 90,169,218,104,146, 20, 40, 61,147, 36, 46, 32, 74, 11, 79, +183, 60,147,233,171, 0,186,245,213,172,128, 91, 62,213, 13, 73, 4,213,179, 57, 0,154, 79,172,110, 20,214,213,124,118,209, 36, + 75,120,172,109, 16, 17,115,161, 36, 37,167,187, 98, 20,101, 4,154,149, 60,187,253, 13, 43, 15,120, 43,206, 99,156, 42, 75, 17, +248, 98,187,230,157, 70,167,223, 59,249,237,215, 87,165,138,122,141,130,210, 21,251,230,106,183, 6,166, 89,134,228, 97, 67, 50, +144, 18,167, 64,163,128,197, 40, 77, 89, 77,151, 22, 59, 12,170, 82, 74, 78,179,169, 73,156,225,205,163, 96,238, 17,207, 98,236, +151, 96, 86, 11,193, 17,223, 93, 7, 25,162,240,240,231,112,201,177,168,158,204, 38,196, 21,125, 43, 6,185,104, 32, 46,173,164, + 78,151, 39,252, 68, 47, 11,117,122, 57, 44,194,220,249,157,140,205,149,195,104, 4, 57,136, 89, 34, 33,176,157, 71, 93, 59,119, +245,213,199,215,115,176,143,128,199, 8, 38,172, 89, 22,181,239, 36,179,219,158, 89,105,133, 66, 58,104,178,165, 19, 97, 47,201, +146,195, 52,126,252, 98,239,201,221,251,122,179,183,251,236,249,246,141,235, 91,151, 46,108,159,191, 2, 97,133, 54, 32, 44, 22, + 24, 97, 36,158,151, 79,203,104,243,153,144, 31,248,174,176, 82, 59, 5,121,254, 66, 32, 71,173, 80, 21,200,133,148,220, 48, 21, +226,113, 37,155, 30, 40, 53, 97,146,189, 23, 20,114,222, 15,215, 73,155,191, 31,188,117, 38, 0,168,145,102,224,102,227, 4,107, +103,123,221, 47, 81,186,115,121,103,179,127,102,247,205,222,135, 79,251,255,139,239, 7,223, 7,143,238, 60,189,253,224, 22, 14, +207, 33,195,193,195,173,155,247,214, 54,250, 69,116,145,100,113,145, 37, 65,242,135,180,154,202,203,211,119, 47,229,104,104,139, + 51,234,104,170, 97,114,101, 42,167,145,154,140,138, 60,150, 38,139, 65,100,150, 90,211,234,228, 30,247,103,210,197,206,119, 3, +220,168, 92,214, 42, 43,103, 52,214,111, 89,215,125, 14, 92,191, 81,121, 26,195,232, 49, 39,183,174,161, 10,167,117, 47,139,185, +246,170, 45, 19, 88, 89, 71, 29,226,173,115, 7, 43, 29,200,106,121, 73,205,239,176, 50, 31,169, 38, 10,253, 43, 0,101,215,174, +219, 68, 16, 69,103,102,103, 31,126, 36,150, 19, 68, 20, 3, 49,162, 67, 80, 4, 41, 5, 66, 2, 87, 20,124, 12, 63, 65,193,223, + 32,196, 67, 41,120, 20,180, 68, 72,137, 4, 69,138, 88, 50, 80,224, 36, 38,246,250,177,222,245, 60,152,123,103,199,222, 56, 17, +136,210,146,189,146,119,103,239,156, 57,247,220,115,248, 18,167, 83,132,183, 46, 36,143,205,221,128,145, 81,197,177, 85, 26,218, + 33,218, 8, 92, 98, 0, 84,113,240,147, 50,168, 17,146, 54, 2,212, 23,166, 74, 4, 26, 9, 37,204,243,240, 41,157,152, 98, 74, +117,232,209,136, 85,192,216, 15,105, 43, 78, 60,235, 28,224, 65, 17, 1, 49, 37,148, 62, 69,135, 50, 99, 51,223,148,179, 33,160, + 33, 22, 66,107,133,149,152, 65, 62,222, 88,100,155,213, 13,243,147,206,176,205, 41, 15,204,153,196, 51,187, 55,103,176, 53, 96, +238, 16, 93, 12,243, 23, 42,174,219,168,108, 90,139, 82,101,191, 50, 82,177, 21, 77, 47,190,175,116,161,170,211,249, 6,203,206, +233, 43,232, 95, 90,182,244,146, 49, 96,230, 48,128, 70,207, 69,184,167,158,243, 82,182,110,105,190, 84,177, 80, 99,167, 92,156, + 63,158, 58, 33, 87, 12,108, 55,183,204, 84, 98, 83, 43, 51,112, 68, 52,127, 50,153,209, 48, 34, 27,202, 75, 81, 92, 98,224,177, +231,145, 90, 8,177,193, 32, 91,196,181, 3, 17,194,184, 49,143,103,182,163, 69, 39, 2,156,100,220, 32,131, 1,212,240, 56, 3, +180, 90, 46, 83,128,234,150,175, 16,192,200,211, 41,240,153,180,132, 9,149,153, 36,229,144,150, 80,161, 89,139,168, 1, 73, 30, + 24, 69,178,122,141, 29, 30,179, 68,216, 9, 20,133, 52, 20,155,138,132,185, 27,143,172,136, 53, 44, 34,227,233,232,251,241,164, + 32,120,191,216, 3,153,139,123, 73, 33,108, 15,144, 88, 2, 94, 17, 32, 97,225,102, 63, 7, 20, 73,208,143,199, 17, 73,122, 89, +139, 90,132, 58, 66,137,209,116,100,205,166,226,228,236,218,218,141,238,160,139,242, 11,221,188,122,171,125,114,100, 87,181, 99, +223,216,162,193,174,237,241, 27,131,146,114,133,155,123, 53,148,155,105, 96,249,188,122, 78, 81,234,229, 63, 37,109,109, 48, 37, + 27, 89,120,180, 39,210, 73, 54,221, 90,111,118, 78, 58,239,247, 63,128,191, 13, 8,133,224,186, 1,247, 51,232, 9, 59, 83, 82, +101,249,118,232,163,120,129,111, 10, 43, 68,149,113, 30,167,113, 37,170,154,139,183,251,189,167,207,158,239,108,223,110, 60,184, +243,110,119,247,225,163, 86,151,100,181, 96,125, 32, 70,128,156,108,125, 55,207,181,129,139,201,190,238,107, 8,222, 83, 72, 80, +115,116, 72, 47,151, 59, 3,109, 5,211, 81, 17, 11, 87,194, 16,219, 15,112, 84, 55, 96, 28, 79, 15, 56,130,193,152,121, 35,107, + 37,144,180,191,124,243,182, 12, 21,192, 46, 99, 56,164,112, 16,126, 81, 41, 73,107,235,174, 94,105, 30,245,126,244,102,253,175, +159,190,236,127, 59,184,247,120,251,127, 75,252,222,225, 94,107,231,201,199,207,175,240, 83, 63, 30,255,188,121,255,186,185,190, +248,189,170,131,213,106,189,145,166, 96,191, 16,109,146,228,245, 11,121,118, 42, 6,167,233,217, 47, 57,236,101,147, 88,154, 3, + 22,242, 11,246, 48, 4,222, 39,204, 79,101, 34,117,158,172, 12,235, 21,193,187,147,143, 91,173,138,176, 2, 84,141,135, 47, 52, +117, 60,231,111,115,161,172,255, 91,187, 97,229, 45, 65, 80, 73, 33,177,146, 46, 53,253, 48,104,172, 2, 49, 9, 90, 22, 80, 60, +181,208,138,195, 24, 85,190,203, 20,140,221,149, 51, 48,215,139, 41,214,203,242,230,254, 8, 64,217,181,236, 54, 13, 68,209,185, +147,113,156, 52, 9,109,104,120,136, 22, 69, 66,108, 0,137, 29,127,193, 87, 32,161,110,251, 41,236,145, 64, 2,190, 0,137, 37, +172, 88,208, 5,170,216, 80, 68,165,166, 60, 90, 85, 84, 77,210, 58,113, 98,143, 99, 51,231,206,216,113,162,178, 32,171, 88,114, +172, 36, 51,190, 62,115,230,220,115,150,252, 9, 74, 73,196,110, 19, 86,209,156,153,227,254, 57,129,196,100,196, 39,177,189, 25, +187, 63, 10, 46, 86, 40,208, 24,125,171, 94, 99,163, 52,157,217,102, 15,130,137,184,116,145,170,133, 34, 85,113,124,132, 21,222, +120,108,219, 45,108,148,180, 84, 60,221, 85,149,119, 58,174, 85, 87, 64,221, 40, 3, 12,241,204,168,155,122,158, 65,170,188,234, +183, 87,227,171,195,168, 15,207, 86,208, 78, 72,231, 53, 56, 82, 59,223, 55, 42, 90,117,169,104,189,102,140,214,244, 91, 73,162, +199,105,136, 4, 34,235, 17, 78,214, 92, 41,115,132, 91,137,167,207, 55, 36, 36, 93, 66,159,205,115, 14, 23,159,155,229,120,175, + 98,117,103,255,110, 92,191,213,108, 79,167,131, 10,217,195, 89,146,205,214, 85,197, 12,102, 63,215,161,195,214,141, 49, 85,131, +196,186, 15,147, 93, 14,165, 76,135, 9,104, 90, 27,111, 40,161,184,128, 47,179, 89, 69, 53, 36,234,187,170,100,190,112, 94,141, +117,207, 90,139,155, 73, 45,214,148,210,121,240, 14,120, 24,130,130,213,254,134,134, 39,194, 68, 96,121, 36, 33,115, 52,103, 37, +169, 52,192,188, 93, 55,119,173, 12,176,182, 49,144, 13,254,101, 45, 31,163,110,134,168,225, 87,170,190,136, 19,140, 87,179, 38, + 87,188,170,167,226,120, 38, 61,226,233, 72,164,217,211,205,102,199, 47, 64,114, 86,186,167, 5,171, 14, 57,191,203,203, 94,112, +143,149,170,238,215,131,201, 5,148,206,169,237,138,149,182,196,179, 97,183,188,221,233,254, 58,253, 33,114,172,149, 50,108, 36, + 42,187, 65,185, 28,146,146,208,152, 74,205,198,116,212, 63, 54, 24,250,230,218, 70,172,245,193,159, 30,145, 35,244,210, 28, 20, + 21, 37,254,122,235,198, 32,186,208,113,100,111, 45,223, 51, 15, 56, 21, 68, 35, 89,190,137,242, 60, 29,146,255,216,185,231,159, +187,217,233, 14,130,179, 48,154,112, 2, 10,104,197,159,103,135,108,169, 36, 36,205,113, 91, 16,143,176,172,112, 57,101, 69,138, + 16, 62,100, 86, 63,231,227, 97,140, 88, 24,243,128,163,105, 56,170,154,153, 81,243,179,212,251,178,119,248,121,247,123,144,140, + 31,109, 60,108,119,186,162,214,126,189,243, 18,164,251,158, 16, 61, 33, 54,185,190, 23,237,118, 87,132,120,192,228,187,197,245, +218,241, 51, 48,186,207,177,144,249, 98, 30, 27,205,227,157,180, 13,191,206,177, 21,174,150, 73,120,239,238, 29,115,222,241,126, +175, 81,243,161,193,173, 72,100,140, 97,119,147,195,162, 4,125, 27,134,239,119, 95,185,203,221, 66,216,210,243,103, 47,158,110, + 63,249,175,250,254,246,195,155,173,199,219,121,125, 23,167,123,239,238,119,183,144,136, 50, 48, 7, 67,189,127,158,157,156,200, +163,223,211,157,143,193,215, 79,113, 18,206,208,196,173,205,244, 3, 35, 92,107, 78,162, 81,150, 71, 30,177,175, 95,230,114,246, +108,108,188,117,160,202, 17,133, 43,249,206,217, 15,127, 14,163,231,172, 32,208,201,137,230, 11,121, 69, 49,181, 88,205, 34, 47, + 77, 96,181, 23,151,188,178,208,153, 3,202,229,128,101, 64,243, 40,225,232, 62,135,122,236, 68,157,177, 43,174, 72, 74,216,187, +212,109, 74,185,170,101,105, 91, 96,249,245, 87, 0,202,174,165,199,105, 24, 8,143, 29,231,213,180, 37,203,150,135,246,176,128, + 56, 32, 14, 92, 56,172,196,149, 35,191,132,223,196,157, 95,194,111, 64,220,118,121, 8, 45,237, 62,219, 52,109, 94,182,241,140, +237, 52, 45, 39,122,168, 84, 69,105, 36,203,153, 25,207,124, 15, 49,100,231,194, 97,243,221,249,101, 59, 7, 37,172,113,236, 9, + 61,209, 36,176,102, 74,111,172, 58, 44, 7,137, 7, 94,244,216, 20,246, 56,234,108, 48,249,160, 41, 42, 89, 55, 91,177, 67,237, + 5, 84,180, 79, 62, 40,234, 43,136,196,174,201,149, 9,197,197, 76,242,224, 65, 26,196,121, 60, 34,139, 38,148, 32, 47,154, 54, + 11,195,204, 60, 26,109,100,216, 22,209, 84,250,100,124, 90,212, 75,179,122,157, 22, 10, 83,157,106, 20, 14, 6,200,158, 67,239, +132, 24,192,225, 13, 18, 54,153, 6, 83, 19,148,226, 36, 90,171,114,177,253,221,146,165,156,139, 61, 76, 9,128,129, 53,160,163, +182, 82,162,144,210, 9,170,177,125, 8, 37, 59, 28,109,239, 22, 91, 15,251,251, 12,252,236,130, 65, 87, 47, 99,242,105, 93,119, + 77,139,240, 46,120, 74, 62, 24,169, 71, 52,152,207,140,195, 56,226, 91,201, 74,224, 35,146, 56, 66, 56, 12, 67,216, 34,249,187, + 90, 67, 59, 88,119,128,125, 91, 50, 70,137,113,245, 8, 35,207, 81,170,109, 58, 10,243, 17, 98,134, 87, 53,122,121, 50, 43, 20, + 35, 76,166,212,141,210, 21,237,118,147, 6,114,102,182,151, 42, 59,156,243,153, 61,150, 68,172,150,202,132,105,243,172, 36, 50, +145,157,101, 33,111,200, 26, 11,179,189, 48,107,199,205,173, 89, 42, 2,242,195,205, 31, 64,102,110,105,129,132,197, 77,118,197, + 78,148,167,151, 14, 21, 33, 84, 28,142,209, 99,108, 96,241,124, 76, 26, 53, 61,249,206,102, 69, 83,107,151,117,105,182,122,158, +229,183,197,237,174,227, 66,219,222,228,131,159,139, 11, 90,217, 96,143,195, 58,172, 81,232,143,102,227, 71, 55,229,141,213,127, +181, 71, 54,237, 34, 62, 1, 85, 24,159, 47,255, 32, 63,148,236, 85,204,181, 52,206, 54, 77,249, 98,246,242,199,245,133,135,244, +192, 85,113,165,188,126, 9,182,221,219, 45, 21,132,186,215, 98, 36, 36,168,197, 72,106,178, 47,181,218,170,124, 15, 22, 71, 30, +115,223,231,231, 88,250,146, 92, 65, 18,165, 73,144,148, 85,225,164,208,240, 91,146,219, 1, 69, 32,110, 14,184,233,209, 56, 71, + 89, 74,122,201,201,175, 18, 65, 4,104,219,228,240,115, 78,249, 13, 39, 94, 66, 76,166, 71,235,102,147,137, 39,130, 69, 29, 11, +210, 48,153, 36, 15, 35,216, 28,127,249,120,123,246, 97,153, 61,111, 79,222,192,107, 6,175, 0,222, 2,152,200,124, 10,240,204, + 81,216,168,168,111, 45, 95, 90,226,172, 87,128,170,130, 90, 23,245,253, 10, 1, 88, 68,223,197, 38, 33,247, 78,106,108, 11,205, +251,179,119,230,182,175,191,206, 11, 40,139,170, 12, 17,194, 40,182,114, 35,251,120, 82,109,144,149, 45,146, 22,185,108,213, 44, +124,124, 45, 23,255, 27,223,239,202,235,201, 40,235,127, 86,139,111,226, 14,154, 75, 89,125,250,220, 92, 93,234,213,125, 91,222, +181,155,229,186,152, 87, 12,161, 97,138,145, 1,179,132,170,107,200, 34, 88, 57,180,180,213, 89,151,182,150, 71, 36,171,116,144, +172,254, 29, 39, 98, 42,147,189,194,139, 87, 90,239,171, 99,239,132,237, 99,163,114, 91,217, 86,247,106, 20, 77,214, 85,201,247, +154,142,188,143, 64,156, 9,115,236,198, 81,186,127, 96, 79, 87,102, 14,109,195,118, 82, 75,174,101,233,123,147,135,176,159, 78, +123, 26, 20,131,161, 91, 31,252, 91,194,255, 21,128,178, 43,231,109, 34,136,194, 51,123,120, 29, 31, 97,189, 38,114, 34, 69, 57, +164,112,132, 2, 81, 1, 63,129,142,134,138, 26,137, 72, 20, 32, 33,241, 11,160,128,158, 34, 18, 13, 61, 77, 68, 67, 1, 66,162, + 74,153,142, 16,129, 80, 8, 9, 78, 98,199,216,187,107,123,175, 25,222,123, 51,235,216, 40, 66,162,115,177,222,123,231, 29,223, +247,190,207, 58, 75, 57,146, 79,210,102, 24,137,188, 19, 62,139,242,235, 86,129, 91,176,164,218,218,240,218, 36,196, 25, 81, 53, + 26,213, 81, 83, 69,140,180, 10, 72,144, 22,107, 28,204,245,144, 20,207,117, 87, 81,205,184, 91, 52,220,161, 80,226, 84,153,105, +208, 54,112,229, 85,108,223,115, 63,137,145,168, 0,199, 73,177,209, 25,164,233, 52,122,109, 88, 21,252, 16, 10,131, 36,129,147, +105, 84,150, 15,252,175,144, 65,196, 72, 12,193,150, 47, 70, 26,122,124, 99,136, 2, 39,239,104, 35,148,131, 65, 58, 44,166, 5, +199, 40,121, 5,119,185,122,241,123,111, 7, 5,131,242,137, 24, 57,102,188, 55,162,181, 80, 93,234,120,213,122,171,119,200,207, +192, 83,229,153,211, 10, 35, 12,199,212,100, 59,165,194,136,168, 38,132,196, 1,186,243, 33,145, 27, 94,222, 37,215,170, 27,214, + 81, 38,102, 4, 97,177,156, 87,109, 6,129, 51,193,161, 23,236,202, 65,246, 24,103, 44, 76,241,118, 23,200, 54, 41,193,181, 6, +183,246, 76, 26, 89,202,152,131,252, 83,137,118, 86,166,225, 22,109,183, 98, 15, 35,177,179,223, 63,238,198,157,228, 20,116,134, +130,160, 86,177, 22,235, 83,139,141, 41, 63,147,221,128, 76,123, 81,164, 5, 61, 73, 19,116,217,130, 21,214,240,137,224, 87,194, +170,202,136, 4,237,214,128, 48,192, 67,193, 93,130,139, 83, 46,203, 69, 35, 21, 60,225,210, 45,115,100,109, 10,204,220,139, 78, + 9,162,200, 32, 10,209,131, 81,169,181,232,113, 4,120, 19, 98,164,174,211, 83,177,209,127, 78, 54,187,251, 51,211,179,221,160, + 29,231,192, 85, 62,105,129, 37, 88,199, 63, 49,116, 43,140, 80, 50,168,247,164,114,241, 27,181, 18,117, 45, 72, 25,145,254, 66, +184,169,199,212,219, 62, 44,238,217,185,114,173,135,110,124, 42,255,158,152,102,210, 37, 57,165,112, 94,165,113, 18,182, 96, 31, +123,237, 31,180,194, 26, 36,167,133,245,187, 55,229,157,160,197, 35, 63,117, 79,206, 20, 12, 73,245, 40,130, 43, 44, 35,189, 26, +219, 50, 23,106, 75,205,160, 57, 24,134, 90,137, 39,159,253,190, 60,191,250,121,127,155,144, 55,236,235,244,163, 97,132,236, 4, +136,214, 72, 12,149,228,146, 66,238,179, 8,111,205,213,230,227, 52,106,249, 45,236,121,113,124,202, 38, 83, 54,141, 58,166, 41, +122, 63,217,160, 40, 15, 1, 22,246,123, 84,254,210,140, 33,188, 2, 34,190,177,112,245,253,206,135,246,112,157,241,245,210,208, +153,251, 53,239, 30,175,132,111, 93,145, 93, 19,198,205,192,110,116,234, 13,177,232,177, 43,140,109,194, 46,183, 16, 78, 51,209, + 48,152,204,206, 68,123,251,155,113,105,118,226, 85, 63,236,237, 29, 28,244, 2, 31,174,248,119, 22,188,126,190,254,144, 59,117, + 94,249,248,233, 29,252,245,241,221,181,173,221, 47, 79,215,158, 92,191,115, 11,110,111,149, 89,207,238, 63, 42, 91, 69, 19, 18, + 60, 90, 40,218,233, 49,236,227,193,237,123, 47, 55, 94,253,215, 18,191,122, 97,101,244,219, 57,218,237,190,120, 19, 53,127,118, +182, 54,165, 73, 50,177, 73, 20, 71,253, 36, 14,105,142, 62, 67,173,248, 76, 97,130,130,236, 24,212, 13,210, 50,144, 57,233, 37, + 55,221, 25,205,184,144,219,164, 74,156,248,164,174,148, 24, 83,229, 29,131, 39,165,248,123, 73,229, 16,173, 21,179, 78,158, 42, +217, 96, 50,113,190, 92,111, 5, 71, 42,189,211,132, 74,170,244, 84,104,215,134, 84, 99,135,179, 70,157, 98,117,150, 57,209, 94, +213,162, 74,127,102, 60,121,151,255, 68, 3,255, 8,192,216,181,243, 54, 13, 69, 97,223,235, 71,220,196,110,154,180,149, 83, 37, + 2,149,242, 40, 42,108,252, 6,126, 2, 35, 19, 3,236, 44, 48,242,111, 16, 66, 98, 7, 22,196,194,128, 24, 24,232, 80,170,134, + 82,232, 35, 15, 18,219,241,243,250,114,206,185,177, 83, 9,138,216,162,100,137,125,237,243,250,206,247,125,198, 5,224, 32,171, + 12,149, 84,251, 72,222, 11, 8,240,219, 70,157, 43,179,134, 57,153,140, 23,170, 73,198,214, 30,189, 2,248,249, 62, 21, 11,119, +211,210, 77, 8,211, 53,110,154,220,134, 20, 59, 73, 2,129,178, 98,112,238, 40, 3,134,227, 24,148,172,225, 49,121, 35, 64,245, + 89,211,145, 82,225, 50, 35,101,210,230, 24,224,225, 10, 27,220, 32, 42, 35,110,251, 69,133,132,120, 7, 89, 44, 41, 18,215,114, +112,206,195, 12,163, 32,255,183,130,216,141,115,239, 19,165, 35, 14, 47, 13,196, 74, 56,235,136, 62,163,126,105, 82,224, 2, 68, + 71, 91,239, 58,151,250,193, 62, 43,217,109, 84, 46,137, 10,255,144,101, 18,134, 43, 27,162, 90,200, 92,192,168,106,255,201, 2, +141,253,149,144,166, 22,178, 72,222,138,118, 69,145,253,163,153, 4,171,166,105, 18, 75,220, 76,235,214,217,230, 90, 3,218, 32, + 63, 72,156, 37, 20,123, 85,202, 4,132, 66,227,102,122, 94, 30, 26,142, 95,232,167,156,178,182, 32,115, 90, 4,232, 12, 4,131, +200,117, 21,243,104, 82,112,175, 86, 91,117,140,254, 32, 60, 24, 37,126, 38, 3,234,189,179,243,226, 9,126,254,217,247, 55, 15, +253,219,151,235,215,122, 46,148, 60, 97, 20,255, 10, 69,154,227,189, 91,178,180,122, 14,157, 84, 49,142,181, 89, 70,249,201, 98, +106,110,181, 86,103,161,192, 9,190,109, 34, 25,159, 17,138,112, 58,205,183, 58,230,225, 0, 29,196, 13, 60,151, 40,205,171,139, + 80,107,221, 92,237,160,160,132,189, 97,120,173,141,163,193,161, 82, 13,242,150,187, 39,211,159, 84,166,148,179,111, 77, 46, 90, + 92, 94, 49, 66,152, 92,120,244,226,147, 93, 58,212, 42,145, 40,201,200,251,177,221, 88,153, 70,190, 10,244,170, 44,199, 58, 45, + 23,110,205,153, 66,165,140, 64, 62, 91,111, 18,193,149, 14,201, 91,217,136,210,208,143, 2,199,118,177, 48, 39, 97,145, 92,102, + 53,179,134,141,130,200,213,254, 4,122,105,150,141, 25,238,116, 25,102, 4, 1, 37,199, 37, 17, 8,136, 45,167, 61,152, 12,116, +226,185,192, 13,220, 63,219, 67,235, 56, 14,197, 46,203,196, 98, 25,101,247,232,203,156, 53, 41, 48,213,163,153,129,110, 73, 65, +204, 47, 89,108,121, 55, 14,206,246,200,136, 3,113,143,254,160,207,112,218,166,187,182, 91, 32, 36, 30,201,249,106, 58, 87,233, + 78,153, 34, 40,183,178,102,125, 57, 23,240,111, 50,174,252, 28, 9, 51, 16, 89,252,236,222,163,215,119, 95, 61,120,242,248,227, +247,189,227, 96, 24,197,242,219,248, 3, 13,101,158,107,118,163,227,118,111, 73,199,251,209, 29,239,166,130,241,208, 75,191,250, + 61, 11,154, 54, 29,223, 87, 72,228,237,237,235,150,150, 67,189,213,101,157,155, 87,182,118,118,182,123, 61,175,125,231,170,190, +218,132, 82, 96,181,213, 90,243, 58,157,102,119,195,105, 67, 6,205,179, 12, 30, 19, 19,186, 14,102, 65,126, 56,126,255,233,100, + 50,107, 8,189,109, 57, 41,181,174,182,105, 69,193,236,221,203,183,247,159, 62,164,248,254,191, 54,220,173, 70, 43, 30,141, 22, + 13, 95,158,156,190,121, 17, 4,147, 76,139,145,222, 8, 55,176, 16, 56, 82,132,119, 63,153, 33,118, 36, 83,173, 32,210, 7,169, + 20, 18, 82, 77, 1,177,116,117,210,230,154, 84,213, 91, 76, 14,124,220, 88,178,221, 41, 57, 7,192, 17,135, 89,120,161, 3,158, +246,231, 38,203,162, 36, 46,131,251, 28, 94, 34, 57, 13, 49, 10,135,232,125, 89, 82, 83,231, 18, 57, 82, 45,190,170,162,131, 21, +149, 29, 5,161,252,172,210,137, 34, 98, 25,124,209,176, 29, 8,161,227,217,240, 28,156, 95,106,102, 73,249,143, 85,143,223, 2, + 48,118,110,173, 77, 4, 81, 28,159,219,238,166,217, 54,109,146,154,120,105,139, 65,177,104, 21,145,170, 15, 62,248,224, 87,240, + 51,248,225,124,240,213, 7, 47, 40, 72,209, 23, 17, 65,104, 17,137,214, 54, 34,177, 37, 77,147,236,101,118,103,198, 57,103,118, +211,134,190, 20, 22,114,131,108,178,151,153, 51,231,252,207,255, 7,254, 4, 20,186,214, 20, 61,163,134,196,151, 28,217, 58,220, + 3,143, 66,120,210, 16, 13, 52,221, 22, 14,239,205,156,236, 0, 18,171,118, 58, 85, 78,228,175,145, 76,130, 68, 8, 48,138, 70, +251,100,200,182,219,173, 21,182,236, 12,177, 63,250,109, 3,118, 15,212,248,204,199, 69, 43,254, 93, 30,130,241,183, 0,235, 2, +238, 3, 87,148,176,128, 99,188,203, 88,232, 65, 68,111, 47,198,138,224, 17, 88,151,208, 84,101, 71,105, 36,152, 56, 76,246,254, + 70,253, 84, 37,137, 74,164, 78, 50,215, 16,107,138,208, 12, 15, 0,207, 1,218,155,163, 22,197,126,175,192,223,207, 67, 22, 94, +172,182,187,227,157,194,229,230,196,210, 29,105, 75,142, 18, 87,182,119, 77, 43, 18,174,122, 13,200, 30, 77, 18, 53,153, 49, 9, +154,113, 11,194,118,205, 60,177,255, 30,178,228, 8,153,245, 25, 77,210,216,206, 79, 77, 66,110, 44,251,215, 46, 45, 12, 34,213, + 31,102, 19,169, 61,110,236,102, 79,245, 24,234,253, 48,160, 35, 86,206,145, 93, 32, 40, 17,192, 90,193,226, 23,206,112,118, 84, +243, 49,188,245, 80,125,173, 64, 19, 76,154,213,160, 83,247,122, 7,241,207,163, 36,194,234, 90,132,250,230,164,140,223,221,141, +229, 99,201,109,158,144,203,139,252,254,245,165,149,118,104,163,160,254,145, 28, 78, 20,104,100,160,250, 71, 99,236,167, 84,176, + 83, 52,176,100,180, 94, 5,212,179,125,145, 27,112,106,110, 84,121, 96, 79,161,224,213,128,126,220,137,255,141, 33,132,146, 10, +166,165, 76,129, 1,127,171,182,218, 27,236, 21,182,168, 40, 19,210,174, 43, 21,133,107,206,213,145,160,142,101,214,170,173, 32, +150,219,113,214,213, 84,203, 44,183,102,101, 30,177,212,149,194, 71,141,249,102, 34,199, 18,248,127, 16,185, 3, 47,181,236, 37, + 49,133,163, 30,238,151,186,203,210,157,104,183,244, 45, 86,232,232, 79,103, 54, 86,111,117,251,221,123,157, 7,219,187, 95, 39, +114, 82,128,135, 40,173,250,243,199,241,192, 89, 41, 56,142, 41, 80, 46,114,181,182,220,233, 13,246, 49, 9, 80,200,233, 13, 14, +220,246,209,163, 2,162, 71,157,185,251, 92,149,157, 98, 87,154,171,189,131,221, 74, 37,148, 50,161,120, 71, 96,113,221,128,105, + 7,244,105,195,161,175, 87,234,169,145, 89,150, 58,211,202, 34,138,114, 60, 68, 92, 67,131, 64, 13, 60,135,184,131, 74,250,144, + 17,103, 62, 2, 43,219,139,173,195,104, 8, 93,176, 76,180,155, 45, 77,197,113,148,165,204, 78, 73,245,141,218,205,103,119,159, +146, 37,242, 97,235,203,243,207, 47, 95,247,183,126, 68,223,225,186,204, 15,236,151,214,130, 57,165,115,143, 74,192, 44,160, 11, +102,168, 23,124, 31,110, 62, 20,182,129,234,129,231,202,183,235, 72, 9, 19, 33, 76, 62, 21, 95, 4, 94, 20,199,163,209,208,198, +204, 94,224, 9,193,134,147,225, 24, 83,249,115, 36,120,220,238,140, 84,122, 8, 93, 8, 16,102,253, 26,252,249,244,226, 13,187, + 90,127,184,185,137, 41,160,115, 73, 39,111,175,108,180, 23, 46,188,221,126,143, 14,192,181,245,181, 59, 18, 69,152, 20,145, 10, + 20,201, 73,185, 76,158,172, 63,122,245,237, 29,172,133,128,247,128, 52, 39, 85,242,192,115, 87, 64,213,230,116,103,226,137,186, +209,184, 86,126,134, 78, 68,238,210, 66,115, 96, 58,117, 26,112, 64,230,105, 39, 42, 61,149,194, 61, 59,162, 58,183, 84, 83,232, + 26, 10,112,228, 73, 43,146,158,162, 66, 72, 73,104, 51,165,253,164, 41,209,223,196,204,214,243, 76, 33,251, 97,216,229, 78,245, +185, 6,247,226,189,255, 2, 80,118, 45,185, 81, 3, 65,180,237,246, 55,227, 36,206,151,100,136, 2, 72, 8, 37,130, 37, 18, 55, +200, 2,137, 21, 59,238,192,154, 59,176,230, 14,220,129, 61, 72, 8, 9,129, 16, 18, 34, 40, 32,148,160, 64, 38, 51,153,241,216, +110,183, 63, 77, 85,117,123,226,132,108,152,197,172, 44, 91,109, 87,119,253, 94,189,135,231, 59,173,176,110,249, 48,205,253,207, + 21,180, 45,148,244,113, 72,201,218,229, 65,196,122, 21,142,161,114, 98,204,176, 5,130, 57, 26,210, 81,197,215,100,112, 72, 72, + 45,162, 58, 36,100,154, 23, 11,163,170,149, 96,201,134, 19, 57, 59, 37, 98, 60,220,138, 46,113,225, 97,110,200,192,156, 28,188, + 43,132,240,182, 23,161,201,184, 10, 75,120, 62, 92, 9, 22,236, 56,188, 86, 6, 57, 84, 83, 17,104, 84, 8, 81, 21,178,201, 14, +211,111,101, 45, 69, 93,224,100, 51, 78,224, 87,122,166,140,138,168, 24,128, 87, 8,193,172, 8, 16, 10,207,112, 57,145,228, 4, + 86,176, 49,183,113, 84, 28,202, 42, 85,216, 22,170,187,128,215,203,188, 16,231, 4,111,172,147,233, 51,118,229,208,177,214, 30, +178,181, 34, 21, 18,205, 96,101,220,243, 67,238, 77, 39, 39,161,109,221,221, 12,183,215,123, 83, 81, 31,143,228, 72,128,155, 83, +145,141,197, 63, 48,203,164,109,224, 67,176,143,140,154, 4, 2,104, 52, 41, 46,149,221, 93, 91,151,107, 49, 27,200, 42,244,178, + 82, 89, 14, 87,203, 30,223, 93,157, 27, 37,242,251, 48,155,160,248, 49,178,199,192,226,199, 10,225, 17,250, 88,215,108,145, 33, + 25,135, 67,229,154,205,216,222,189, 17,239,220,138, 7,227, 34,205,242, 36,175, 39, 5,154, 82, 42,149, 32, 83, 10, 41,115,131, +224, 54, 14,120,207,199,207,147, 55,150,104,192, 27,241,181,200,134, 67, 31,108, 68, 86,234,205,151, 66, 72, 4, 31, 20, 40,145, +201, 74,228,138,210, 54,107,120,239,225,111, 33, 88,204,101, 78, 83, 5, 22,191, 72,177,116,105, 32,205,140, 35, 25,108,242, 63, + 12,170,204,240, 13, 19, 74, 7, 91, 56,164, 35, 66,138,190,237,136, 54,214, 55, 45,170,134, 16,220, 94,139,171,169, 78,203, 4, + 46,114, 93,240,244, 92,214,101, 63,238, 15,211, 65,154, 37, 40, 0, 98, 89,178, 20, 36,169, 98,220, 3,220, 60,244,123,147,116, + 84, 43, 45, 84, 7, 43,170, 92,199, 43,203,178,157,192,210,196, 67,202,231, 62,132,210,176,184, 56,140, 41, 43,183, 88,219,141, +128, 7,251,196, 94, 25, 5, 11, 66,166, 58, 33,182,177,233, 68,114,226,218,235, 33, 8,202,165,114,167,206,157, 53, 35, 8,215, +116, 14, 56, 42,136, 1, 23, 92, 1,169, 48, 56, 86, 14, 46,225,193,237,251, 31,127,124,210,252, 91, 56,197,138, 91,207,161,189, +231,130,201,192, 43, 40, 45, 8,110,156, 28, 27,159, 43,143,182,246, 30,223,217,243, 55,109, 86,176,241,135,230,231,150,253,250, + 55,123,247,235,112,127,184, 63, 20, 3,238, 71,238,218,189,188, 9, 78,135, 95,229,244,184,202, 39, 42, 25,220,224,243, 15, 23, +253,245,121, 39,201,216, 65,158,188, 29,191,170,216, 56,147, 39,121,121,214, 96, 28,210,152,206,156,197, 87,189,109, 76, 59,236, +249,107,188, 31, 56,107,103,242,253,242,210,209,176,144,153,213, 76,133, 56,160, 70,203,203,231, 47,158, 60,123,234, 65,220, 83, + 94,205, 85,217,253,204, 16, 86,239,172,222,252,252,103, 31, 91,194,110,212,143,175, 43,199,109,147, 65,211, 68, 71,126,248, 74, + 32, 39, 45,141, 79,211,201, 94, 25, 73, 31, 19,178,215,102, 59,117, 64, 81, 74,205,192,108,172, 54, 3, 60, 74, 93,144,148,193, + 82,124, 53, 67, 53,118,206,247, 46,199,203,165,152,206, 98,179, 42, 10, 1, 82,184,173,161, 38,154, 48,163,205, 68,217,185,192, +136, 86, 63,215,212, 2, 70,255,161,229,181,154,149,140, 47, 14,156,254,215,225, 14,191,191, 2,208,117, 45, 61, 81, 67, 81,248, +220,190,134,118,166, 51, 12,195, 35,128,137, 27, 3, 34, 97,193,214, 68,215,254, 5,255,131,107, 93,235, 95,112,225,222,133,137, + 27,254,135, 27,124, 36, 26, 19, 94, 33, 49,188, 4,129,150,182, 76,111,111,235,253,206,109,193, 1,204,172,154,153,116,218,219, +222,115,190,243,250,190,218,190,223,220, 62, 53, 33, 1, 66,106, 20,112, 88, 38, 91, 95,118, 87,140,219, 12,195, 53,126, 80,232, + 91,128,176, 47, 56,255, 4,139, 70, 32,205, 11, 87, 81,176,170, 14, 27, 33, 22,169, 1, 78,129,171,104,123,109,207, 26, 75,228, + 5, 18,169,182, 57,179, 6, 8, 88,132, 22, 40,176,209, 86,223,209, 56,221, 1,216, 13,132,231,123, 45, 1, 41, 15,189,109, 45, +151,129, 11,222, 36, 35,211,204, 78, 92, 59,146,131, 52, 26,150,197,238,249, 15, 73, 50, 43,146,172,208,166,102,200, 44,196, 69, + 37,174,228, 78, 96,101,114,146, 28, 7,129,194,222, 37,151,235, 69,238,164, 63,115,174,142,147, 34,230,202, 11,243,190,137,107, +221,241, 27,150,253,255, 77,145,163, 41,248,230, 79,177,125,249,145, 34, 94, 96,202,124, 71, 73,175, 44,151,103,131,126,207, 79, + 50,185, 31,229, 26,240,234,219, 13,225,217,232, 36, 47,115,240, 49,194, 69, 43, 14, 53,209, 21, 84, 19,128,215, 82, 5, 24, 19, + 23,208, 61,209,135,137, 98,133, 71, 18, 93, 71, 76,120,214,120,203,238, 56,222,250, 81,146,128,179, 1,153,166,201,192,154, 10, +220, 40, 41,183, 83,105, 58,158, 3,158, 88, 12, 16, 75,144, 14,170, 53,214, 10, 93,154,237,121,171, 11,189,153,169,240,215,111, +141,247,242,211,180, 72,115,212, 28, 83, 30, 47,215,206,208,101, 19,175,223,128,174,175,221,172, 72,149, 17, 65, 66, 65,188, 5, +224, 40,166, 66, 43,202,212,231, 13,121, 9,209, 22,160,248, 92, 34,149,196,196, 64,134,156,200,100, 31,241, 25,116, 38,143,227, + 19,123,180,111,102,100, 70,144,110, 45,103, 53,210, 73,108, 20,196,204, 70,194, 62, 18, 38, 9, 86, 35, 38,253,227, 65,119, 16, +167,209,124,127,126, 7, 10, 27,156,101, 7, 39,159,159,230,218, 49, 21, 85, 35,209,198,101, 33,204,196, 64, 97, 74,216, 99,174, +215,246,187,199,209,161,197,111,172, 42, 36,234, 77,128,128,104,147,131, 4,149,215, 30,132,253,141,195, 77,236, 92, 85,183,112, + 94, 13,206,113, 22,221,182,154,217, 23,141, 78, 22,231,150,190,237,126,233,119, 38, 50, 41, 51,153, 58,215,158, 0, 41,105, 92, +185, 81,149,230, 91, 48, 41, 91,196, 0,252, 53, 54,160,209, 27,111,142, 28,110, 54,112, 88,223,198, 5,216,194,164, 87,167,229, + 75, 85,120, 54,180,207,120,117, 45, 35,229, 9,174, 81,132,173, 66, 95,115,156,203, 82,216,185,176,135,100,203,202,189, 31, 46, + 44, 13, 22, 31,251,171, 43,175,166,105,133,175,233, 8,132,193,155,123,180,125, 70,235,251,180,126, 65,145,210,104,139, 30,204, +209,195,105,122,218,167,229, 9,250,179, 77,107, 95,233,253, 79,218, 75, 41,142,165,204,207,170, 2,204,236,101, 49, 20,178,180, +242, 19,223, 9,124, 41, 53,122,176, 85,150,157,127,207, 14,222,189,121,246,228,227,167,181,157,211,131, 61,186,124,253,252,197, +203, 15,111, 31,117,239,109,197,135,174,235,229, 96, 18, 84,183,232,183, 42, 99, 25,185, 79, 19,129, 93,232,140,233,133,133, 82, +144,231,195, 93, 89, 70, 13,161,166,224, 50,212, 96, 80, 0, 81,134,166,186,100,245, 8,214, 2, 81,134,138,170, 38, 14,166,170, +170,110, 81,143, 32,241,213,116,199,140, 76, 92,176,185, 21,166,145,163,230,147,169,232,159, 83, 8,170,202,187,120,219,205,131, + 53,105,109,180, 29,161,110,110,129, 77,161, 38, 8,106,148,148, 89, 76,170, 50,130,222, 92,166,101, 92,169, 68,163,211,236,183, +130,108,180,147,242,170, 25,239,122, 26,246, 14,227,126, 7,201,202, 95, 1,232,186,146,221,168,129, 32,218,221,110,187, 61,246, + 12, 78, 66,194, 37, 8, 36, 2, 72, 68,128, 56, 32,193,129, 3, 23,184,228, 47,144,248, 26,110,156,248, 0, 78,124, 1,103, 4, + 87, 54, 9,164, 8, 36, 32, 8, 2, 40, 25, 50,182,199,235,180,155,170,234,158, 37, 11,210, 28,230,104,245, 82, 93,245,234,213, +123,242, 36,201,148, 41,254, 78,167,159,226, 18,130,125,138, 7,182,148,182,217,144, 13,132,129,231,168, 93, 19, 66, 81, 57,153, +162,249, 83, 47, 49, 20, 56, 97,144,173,121,138,251,161, 68, 47,167,188, 29, 34,212, 3, 85, 41, 62,184,216, 99, 34,206,165, 5, +148,133,245, 50,147, 44, 32, 17, 36,116,176, 9,144,130,195,149,149,206, 20, 78,211,191,209,157, 79, 97, 30, 42,134, 65,160,228, + 4,107, 12,142,229, 48, 89, 44,116,194,181,203, 15,209, 92,160,194, 8, 38,148, 50, 16,235, 8,195,142,164,175, 68,105,195,233, + 60,188,163, 46, 97,238, 79, 76, 48, 11, 4,204,212,198, 73,122,220,156,248,116,119,204, 9,214,195, 10, 8,214, 87, 75, 99,244, +123, 67,112,138,211,212, 47,173, 19,235,251,242,210,170,234,199,222, 40,171,211, 90, 67,158, 27, 72, 30,249, 94, 44, 13,100,220, + 61, 37, 21, 82,200,121,137,157, 87, 74,192, 40, 48,162,243, 53,221,218,134,206,173,182,233,132, 97, 13,185,103, 10, 68,127,121, +214, 16,116, 83, 55,214,237,190,102,168,237, 9, 27,182,177,222,227, 58,208,219, 7, 5, 26,135, 34, 44, 19, 49,185, 30, 6,198, +215, 95,138,186,212,184,214,227,170,253,190, 91, 12,226, 48,137,101,110, 90, 85,243, 90,152, 24,202, 28, 4,193,144, 11, 63, 38, +141, 79,229,177,131,186, 91,225,162,106,160, 88,118, 51,120,154,122,191, 69,213, 13, 66,239,218, 6,127,243, 25, 2, 59, 18, 58, + 59,219, 52,160,217,203,142,116, 38, 59, 71, 3,236, 16,145, 60,170,174,199,237,172, 93,119, 24,220,156, 89,186,207, 84, 64,169, +242, 93, 32, 70, 25, 59,174,230,224, 22, 56,168,167,251,203,195,124,175,168,242, 72, 69, 59,195, 29,212,229,160,164, 10,190,179, +106, 10,227,188,166,230,227,130,184,111, 16, 48,201,166, 3,121, 89,117,190, 58, 88, 27,230, 67,122,158,189, 59,155,183, 95,124, +120, 73, 13, 78, 68, 34,199,213, 8,158, 7, 72,195,123, 97, 63,131,253,213,206, 93,203, 6,119, 65, 20, 50, 71, 76,230,166,110, +155,247,223,222,193,118,164,197, 8, 30,105, 41,248,140,127, 44,172,166,148,213,136, 9,147,113,149, 50, 71,197,243, 92, 23,194, +118, 36,220,159, 89, 71,110,238,232, 96,239, 42, 92, 25, 40,134,172, 16, 41,121,206,224, 13,130, 35,145, 68, 73,138, 45,110,136, + 30, 58, 10,121,209,181,240,101,112, 24, 98, 76,253, 85,218,254,124,189,223,220, 61,123,235,233, 31,182,187,207, 70, 1, 83,103, +216,185,132,221,188,206,238,113,118,127,182,250,250,144,131,193,202, 21,246, 96,139,109,110,179,247,159,216,222, 95, 63, 45,214, +178,146, 37, 13, 91,158,176, 44,133, 82,250,124, 58, 70, 27, 64,248,245,106, 45,194,184,172,222, 94, 13,183, 30,190,122,180,253, +241,249,133,141,139,254,141,203,207, 30, 63,249,154,253, 88,234, 37, 45,185, 69, 88, 26,147, 53, 98,130,119, 46,242,177, 49,166, +144, 62,135, 37, 10, 68,108,148, 35, 36, 56, 66, 5,209,169, 94,242,107,244, 27,139,170,133,177, 8,151,165,147, 49, 4, 41,192, + 88, 35,188,105, 82, 60, 5,227,216,124,208,116,222,147, 44,218,146,168,183,250, 72,255, 12,157, 97,252, 48,144, 50,171,114,241, +159, 68,221, 28,155,133, 21, 78,196,198, 51,238,125, 18,194,184,178,134,104,135,220,121, 38, 96, 72, 85,202, 11,137,129, 2,215, + 31, 19,161,202,148,180, 26,112, 64,104,238,150,241,210, 14, 66, 47,106,214, 76,153, 60,122, 1,121, 52,236, 24,147,254, 88,178, +249, 79, 0,190,206,101,197,137, 32, 10,195, 85,213,213,151,164, 33, 25,156,241,130, 3,142,224, 34,160, 65, 5, 23,226,202, 55, +112,225, 3,184,242, 29,124, 0,223,194,183,113,225, 74, 81,188,224,206, 36, 32,162, 51, 12,154,152, 78,210,221,213, 85,101,253, +167,170, 51,105, 25,221,205, 16, 18,146, 78,234,244,185,252,231,251,101,119, 49,115, 87, 22, 25, 56,239, 97,192,202,120, 46,250, +141,245, 40,192, 64,107, 0,232,203,138, 6,250, 19,234, 10,145,232, 62, 50,146, 54,195,253,100, 19,188, 65,255, 75, 85,150, 40, + 3,116, 64,117,107, 48,219,112,204, 87, 61,213, 28, 78, 21,136, 87,160, 2,184, 63,221,153,174, 34, 12,253, 74,152, 64, 54, 50, +146, 61,173,251, 88,236,198,171,103, 66, 84,232,195,144,238,144,162,186, 56,131,228,112,111,247, 96,182, 27, 78,132, 47,166,182, + 76, 70, 40, 45,207,147,130,120,223,221,105,192, 4,231, 29, 58,232, 48, 63, 80,245,166,210,155,118, 78,130, 49,169,228,190,237, +199,248,223, 11, 52,222,117,160,189,134,174, 58,182, 26,158, 71,158,178, 27,242, 49, 10,241,140,239,229, 50, 77,197,247,185,234, + 83,148,234, 37, 98,191,207,137,208,195, 47, 98,102,105,105,243,197,186, 79, 90, 41, 91, 54,148,228,104,160,125,221, 3, 85,203, +221,194,130,157,177, 27,146,221, 66,129, 99,192,117,213,152, 1,243, 95,141,245, 0, 64,207, 54, 48,133, 22,147,226,246,209,112, +124,152,207,167,122,193,116,206,162, 43,113,114,253, 82, 58,251,189,174,105, 6, 15,236,204,218, 14,151,245,241,201, 42,207,161, +186,113,239, 44, 23, 40, 32, 74,101,178, 8, 87, 77, 19,129,181,161,110, 69, 45, 12,110,234,238, 91,208, 16,246, 72,195,146,216, +133, 78, 28,171, 97,143,223,187,145,188,157,212,170, 17, 62, 65, 69,141, 16, 52, 72,224,128,186,127, 20,241, 49,252, 37,164,252, + 32, 37, 94,199,153,158, 52,234,162,157, 76, 40, 37, 77, 59, 4,233, 24,235,144,100, 15, 95, 72,100, 67,242,142,131, 45,224,217, +102,234,141,160, 5, 0,196, 94,141,101, 13, 87,103, 74, 97,181,181,187,251,124, 97, 67,131,194, 68, 5, 95, 99,190,166, 39,250, +135, 79,151, 63, 13, 66, 51,109,186,146,169,119,165,202,220, 5,247,205, 92,202, 4, 21,124, 24,145, 89,178, 37,239, 76,176, 90, +233,165, 24, 31,221,121, 63,123, 23,100,240,219, 59, 84,139,165,128,179, 96, 36,248,182, 93, 27, 62, 80,168, 78, 4,121,151, 80, + 85,233, 35, 60,167,190, 50,228, 30, 24,207, 81, 25, 61,232,247, 93,254, 94,148, 43,234, 68,186,104,152,205,203, 5, 61,215, 29, + 40,189,159, 15, 78,151,139, 84,194,172,184, 52,250,114, 47,249,182,169, 31,201,135, 35,177,119,181,102, 47,167,236,115,143, 85, + 55,217, 52, 99, 95,136, 22, 92, 83,251, 14,172,154, 8,213,222,152, 65, 98,227,149,187, 46, 55,191, 63, 98, 15, 70,116,120,182, + 23,209, 16,223,166,160,156, 98, 69,198, 33, 39,209,228,195,173,175,111, 30,207,142,127,124,122,246,226,218, 93,153, 45,213,243, + 39, 79, 95,125,124,125,152, 13, 21,232,224, 42, 70,214, 24, 39, 28,123, 46, 41,112,109,174, 72,143,149,167, 19, 82, 99, 79, 98, +209, 72,163,172,177,162, 40,151, 69, 89,248,113,160, 7,129,209, 77,218,119,200, 9, 6,174,169,249,230, 33, 65,220,231,245,188, +181,108, 11, 62, 26,116, 55,216, 26,151,154,128,163, 56,175, 28,207,129, 98, 46,254, 9, 29,220, 89,150, 52,157,173,151,240,251, +164,190, 12,247,106,114,170, 44, 37,242, 19, 46, 7,217,133,189,244, 32, 17,113, 89, 87, 69,179,174, 26, 21, 67, 71,210,244, 34, +181,214,171, 74,175, 60,213,156,140,206, 45,219,198, 72,222,121, 27,252,156,180,221,254, 7,110,252, 71, 0,190,174,174,183,105, + 24,138, 58,113,226, 38,235,216, 64,154, 54,241,128, 38,182,137, 55,196, 11, 63,129,255,201, 31, 64,188,242, 31,120,226, 67,130, +161,105,218, 3,104, 72,131,117,109,151,182, 73,236,216,220,115,175, 61,149, 49, 38, 85,171, 86, 69,109,148,216, 55,199,199,231, +158, 83,220,165,156,145,221,121, 49, 1,198, 89,210, 7,116, 15, 28, 35, 33,163, 49,177,233, 34,154,124,196, 79, 0,130,117, 26, +178, 30, 63,184,220, 65,105, 1,136,235,249,236,188, 97, 61,165,143, 49,102, 89, 34,167,176,134, 28, 56,114,172,224,181, 39, 27, +195,195,128,208, 2,247,160,124, 83,225, 54, 0, 77, 3,116,163, 28,230, 84, 1, 61,155,121,223,113,238, 79,105,131,175,224,236, + 74,224, 50,163, 69, 92,145,105, 39, 95, 29,242,248, 51, 65,165,118, 42,151,250,246, 28, 23,225, 50,112,137,207,184, 23,124, 54, + 76,125, 96,151,215, 36,155,161,215,245, 98,162, 56, 18, 58,249, 8, 97,130, 39, 91,177,112,203,225, 61,181, 80,221, 52,184,201, + 26,205, 7, 57, 21,126,182, 23, 34,142,164, 17,157,135,171,198,110, 19,138,202, 33,191,216,121, 80,110,109,148, 22,182, 76, 97, + 57,192,200,161,131,223, 38,238,225,168, 64,133,160, 75,188,176,236,252, 31, 60,158,149,188,209,179, 66, 88, 74,116,179, 18, 56, +183,112,252,215,202,102, 81,228, 58, 28, 91,192,254,152,187,227,207,151,123, 85, 94,151,153, 1,127, 25, 26,237,222, 95,180,147, +214,207,146, 5, 60, 21,250,234,218,215, 19,187,175, 1, 42, 8, 12, 65,150, 15, 84,165,154, 30,237,137, 53, 59,123,181,129, 48, +169, 62, 31,160,159,121, 52, 82, 15, 55,194,204,170, 69, 79,255,234,138,106, 7,104,247, 48,174,243,231, 7,197,199, 83, 68,160, + 7,141,139,192,108, 40,182, 88,134, 0, 98,186, 44, 52,194,111, 35,221,156,149, 69,217,115, 6,219, 45, 86, 51,172,181, 6,134, +191,228,187,121, 76, 20,205,214, 36, 94,194, 22,241,132,157,173,230, 69, 60,198,103,113,197, 0,238, 25,221,111, 50, 58, 5, 58, +139,231, 62,142,209,181, 25,173,218,149,138,125,170, 25,129, 71, 15,199, 7,124,245,241,247,111, 8, 76,149, 29, 89, 80,133,178, + 11,135,112,188, 50,135, 98, 75,244,159, 38, 51,210, 31,183,166,197,143,225,204,244,233,167,179, 15,185, 40,173,196,116,143, 10, +167,143,141,231,154,201, 26, 45, 29, 78, 50,245, 88,223, 25,169, 39, 62,166,130, 69,101, 27,205,216,120,136, 30,238, 29, 76,155, +203, 37, 68, 88, 66, 48, 7,203,113,174,242,240,160,117,131, 78,114, 95, 26,229,189,237,198,101,209,185, 14, 6, 50,122, 52,157, + 55,155,227,252,197,238, 62,205,137,233,107,245,242, 80,157,215,234,250,139,234,143, 84,243, 76,117,227,152,247,114,145, 60, 75, + 78,148,122,147,146, 29, 5, 55,136,155,180,248, 97,108,194, 38, 94, 29,110,169, 87, 91, 28,237,251, 83,253, 58, 81,167,103,106, +247,183, 26,153,213,219,171,119,195,233, 82,127,237,130,107,250,126,241,244,201,145,117,150, 80,158,227, 59, 65, 87,114,195,140, +175,218, 57,167,102,251, 78,178,121, 82, 20,147,151, 32, 36, 20, 98,140,195, 88,136,153,216, 48,166, 66,240,125,164, 76, 4,192, +251,132,228,227, 91, 52,100, 23,106, 48,150,117,191,214,156,114, 79,199,105, 54, 91, 78, 6, 58,199,255,122,205,170,127,123,254, +147, 38,133, 55, 44,229,193,139,226, 94, 8, 77,189,109,118,118,235,199, 52,216, 17, 64,103, 91,208,159, 67,143,134, 85, 21,241, + 27, 77, 53,131,125,205,118, 80, 54,109,236,229, 62, 69, 70,223,232,134,239,112, 58, 86,225,126,219,250, 63, 2, 16,118,173,173, + 77, 4, 81,116,102,118, 39,187,137,174, 41, 62,218,248, 69, 17, 21, 4,193, 79,126, 23,127,187, 8,226, 31,240,137, 32, 82, 86, + 67, 33,198,152,125,204, 99,199,251,154,152, 34, 69, 40,165,144, 66,186,205,220, 59,231,222,123,206, 61,144, 52,204,229,109, 98, + 4,132,181,216,103,139,166,201, 64,122,109, 12,235, 87,145,175,136,163, 29, 90,191, 14, 47, 1, 46,152,213,240, 85, 86,128,197, +144,208,206, 18, 55,154, 27,115,100, 22, 58,219,209, 73,173,141, 15,196,114, 91,120, 11,236, 42,242,251,106,237,161, 38,192,113, + 16, 14,190,107,170,209, 48,203,226,208, 9,173, 38,177,183,137,107, 43,141,165,117, 28, 80,207,192,161,118,147,135, 8,108,247, +223,125, 34,111, 16,204,248,226,223,148,111,239,195,254, 52, 89, 65, 54,195, 20,111, 0, 65, 64,161,180,143,191,148, 20,217, 7, +193, 42, 95,190,185, 79, 69,156, 8,157, 47,105,169,104,180,206, 50, 93,125, 28,139,204, 11,228, 31,152,240,142,140, 98, 22,162, + 36,117, 50,215, 0,135, 23,165,158,219,194,214,246,218,162, 4,240,117,190, 25,207, 55,125,187,245,235,157,119,131, 31, 29, 68, + 64, 28,225,169, 60, 94, 94,115, 3,249, 81, 87, 70, 53, 51, 13,144,191,194,134, 9,242,191,224,217,121,133,175,166,150, 75, 71, + 81,183,163,148, 82,230,228,222,103,124, 1,175,174, 67,106,167, 4, 88,116, 29, 83, 27, 98, 27,144, 55,233, 50, 66, 41,201, 58, +166,177,198,234,180,221,199,222, 79,142,124,112,125, 72,152,181, 39,217, 90, 81,235, 52, 47, 82, 85,144,228, 21,245, 80,234, 86, +141,233,104, 0,172, 28, 85, 83,195,103,164, 58,151,198, 73,175, 78,204,197, 54,162,234, 94,107, 91, 92,103, 11, 63, 58, 78,112, + 64,236,114,113,147, 56,127,248,175,242,148, 34, 37,187,253, 85, 92, 16, 11,165, 64,208, 57,137,183,159,129, 10,221,251,129, 32, +177, 16,118, 21,123, 57,226,249, 97,172,138, 24,183, 72, 76, 64,100,217,145, 34,247, 59, 52, 56, 61, 91,174, 16, 3, 10,209,145, + 42, 42, 67,150,143, 41, 56,184, 87,101,232,130,159, 52,156, 52, 74,226,252,193,227, 31, 84,217, 58, 0,122, 49,112, 57, 85, 99, + 24,104,163, 61, 14,242,184,105,142, 46, 34,101,197,253,185,163,103,144,111,167,203,213,224, 59, 30,197,192,205,161, 8, 85,152, + 12, 65, 12,229,120,148,149,176,133,172,225, 22,188,225,168,225, 56,154, 21, 51, 18,172, 42, 35,139, 53,148, 11, 99, 15, 25, 95, +137, 26, 0, 78,132, 11,161,160,206,100,161,143,204,169, 40, 45,238,250, 93, 64,145,176,161,165, 50,152,116, 92, 52, 91, 63, 62, +127,249,236,198, 99,181,249,160,236, 59,117,247,179, 50,239,213,233, 87,117,231,167,250,113,161, 6,139,137,190,215,136,200, 15, + 38,180, 37,157,180, 58,147,175, 14, 28, 62,248,157,205, 55,213,190, 85, 31, 95, 79,229, 39,255,176, 51, 79, 23,250,201, 70,189, +184,255,232,213,151, 55,186,112, 6, 42,250,186,130, 50, 48, 90, 27, 13,202,160, 34, 57,179,195, 25, 91,212, 77, 55,116,188,217, + 94,122,109,137, 83,155, 40, 1,167, 41,247, 89,132, 8,135,161, 13, 64, 5,247,110, 78,178,116, 61,177,242, 60, 79, 44,147, 88, +210, 75,251, 70,150,132,254,111,139,192,229,109,236, 68, 93,154,174, 26, 94,102,110,133,190,180,164,139, 72,145,124, 14, 81,132, + 95, 98,191, 5, 51,223,237,249,217,189,230, 65, 85,218, 33,184,189,239,127,135, 1,217, 31,232,112, 7, 81,238, 32,212, 28,206, +170, 92,148, 13, 35, 5,203,102,181, 56,115, 35,201,170,178,243, 72,123,125,254,233,182, 95,197,227, 57,216,246,168, 63, 2,176, +117,237,188, 77, 4, 65,120,119,239,124, 15,159, 45,192, 66, 66, 66, 81, 66,133,228, 14,209,210,243, 27,248, 49,252, 40, 36, 10, + 36, 26, 10, 26,144, 64,208, 64, 65, 42, 10, 64, 74,128, 4,251,226,123,236,238, 28,243,216, 61, 95, 20,183, 41,114,150,207, 59, +251,205,204,247, 56,228, 79,160, 71,162, 79,136,203, 76,240,122, 97,157,145, 54,148,151, 70, 98, 84,144, 32,160, 33,241, 44,125, +226,109, 79, 7, 80,170, 25, 24,103,240,118,130, 78, 66,138, 44,209, 9,166, 50,117,161,167,243,164, 85,218, 60, 26,211, 15, 41, + 39, 56,228, 42,113,100, 62, 24,210, 12, 17,164,227,195, 50, 26,143, 26, 71, 51, 21,151,233,124,149,151, 13,123,151, 83, 95,207, +154,204,203, 14,171,144,155,210, 23,167, 29,137, 9,235,181, 24, 9, 68,195, 6, 96, 74, 79, 70,197,157,230, 71, 16, 5,174,209, + 46, 80,143,203,213,240, 61, 4,204,190,127,165,195,112,221,185,108,212, 51,242, 48, 86,140, 93,185,190, 15,170, 40, 42, 0,184, +149, 53,203,116, 88,205,204,162, 34,147,181,139,198, 54,141,223,118,110,107,135,148,181, 42, 8,234,232, 12, 25,213, 88, 26,172, + 19,172,198,159,115,134, 53,221,244,148,145,198,164, 13, 46, 76, 57, 23, 64,128,192,142,111, 98, 8,159, 4, 51,117,251,229,112, +136, 16, 28,127, 4,246, 6,135,215,199,131,138,192,168,110,252, 31,141, 95, 44,126,122,126, 5,252, 20,172,227,121,138, 72,149, +196, 13, 91,175,111,151, 6,159,126,135, 18, 63, 84,221, 2,226,122,114,150,199, 18,223,251, 77,131, 5,142,150,230,206,233,188, + 76,158,172,205,219, 47, 29,145, 96, 85, 71, 26,182,148, 60, 73,200,234,202,119,117,219,139, 59, 13, 45, 64, 96,159, 99,175,167, + 93, 36, 37, 55, 88, 31, 53,219,248, 97,234,110, 35,188,137, 69, 62,111,218,157, 92,178,226,140, 33,193,214,154, 55,144,235,163, +135,223,126,158,142, 6, 3,136, 62,128,206,147, 99,181,234,164,203, 34, 59,123,207, 5, 55,201, 16,152,103,243,127,216,180, 49, + 87,159,174, 28, 86, 23, 19, 67,201,164,253, 96,203,188, 36,147,119,112,109,239, 76, 72,104, 74,184,161,227, 25, 50, 64, 71,190, +193, 18, 42, 43,195, 21, 16, 14, 28, 94,146, 23,155,115, 41,185, 51, 66,255,212,144, 99,109, 74, 88,198, 38,113,173,172, 25, 20, + 99,121, 50,209, 83,140,109,165,103,152,103, 69,211,119, 8,192, 19, 51,206, 75,201,112,172,181, 45,169,220,216, 51, 85,155, 48, +254, 18,226, 38,243,141, 76, 28, 55,106,209,212,104, 97,103,208, 98, 10, 47, 75,159,155,236,211,230,227,203, 87,235,167,207, 31, + 31, 63, 83,199,223,149,122,173, 94,188, 81,159,223,113, 65,199,127,184, 84,197, 66,109, 87,170, 58, 82,229,137,154, 63, 80,219, + 5, 54,227,234,146, 56, 58,170,134, 24,242,240, 91,185, 51,122,131,254,212,119,231, 80,218,254,204, 34, 34, 81,143,238,249, 95, + 95,179,247, 63, 62, 20,139,226, 2, 79, 38, 30, 84,168,123,187,179, 88,200, 60, 35,248, 65, 2,248,212,223,152,112,171,199,192, +142,152,131, 53, 4,192, 29,166, 43, 58,246,154, 3,109,167,174,132,205, 44,228,118,233,146, 98, 16,121, 12, 41, 13,156,132,195, + 56, 87, 31, 54,139,218, 91,167,139, 81,182,158,232,155,166,147,156,138, 83,195,124, 8,126, 18, 50, 36, 11,172,233,190, 55,188, +182,228,251, 92,235,101,118,247,126,117,146,233, 4,209,231,204,232, 42, 73, 72,225, 55,120, 34,115,187,157, 37,198, 7,109, 40, + 33, 46, 77,115,102, 51, 0,253, 61, 60,143,146,255, 44, 64,160,197, 95,179,221,187,177, 18,136,201,112, 19,223,130,255, 2,240, +117, 45, 43, 78, 4, 81,244, 86,117,119, 30, 61, 9, 72,102,227, 66, 65,130,224, 98,112,163, 32,110,117, 47,204,191, 8,126,135, + 59,191,193,133, 11,127,193,165, 56,138,160, 48, 40, 35,131, 48,142,200,204, 36,147, 73, 63,210,169,174,242,158, 91,213,157, 68, +163,100,151, 52, 73,167,187,250,214,169, 91,231, 17,211,223, 46,233, 77,139,166, 1,221, 46,141,134,221,152, 65, 7,131,169,101, + 81,151,226,127,100,100,224, 0, 52,148,182,215,211,113, 47, 78, 19, 60,233,194, 6, 68, 94, 71,109,161, 34,173,140,231,146, 55, + 22,222, 24, 33,248,218, 40,241, 0, 88, 82,143,133,224, 79, 49,220,151,163, 46, 5,115, 18, 9, 42, 99,244,103,165, 67, 98, 61, +213,141, 95,121,101,124, 11, 51,130,248, 21, 93,207,201, 34,115,155,230,253, 62, 99,175, 86,107, 74,128,128, 2, 84, 35, 71,195, +101,117, 43,107,157,246,118, 7, 1, 83,211,161, 10, 35,175,169,236,193, 82, 74,109,198,115,175, 85, 39,215,198,251,233, 16, 7, + 7, 49,231,110,143,174,167, 4,130,115, 2, 74,242, 36, 51,211,194,152,218,101, 96,110, 40, 24,244,105,156,205,229, 18,237,151, +172, 70,205,202, 25,253,242,191,171, 85, 21,213,120, 71,171,126,196,104, 23,164, 73,254,152,167,251,185, 36,114, 84, 82,196,189, + 9, 96,235, 2,171, 27,127, 5,221, 88, 4,254,103, 17,167, 27,176,127,150,195, 70,198, 98, 23,142,171,182, 36,183,147,202,132, +222, 88,201, 26,135, 47,245,180,112,195,142,222,233,168, 65,140,248,150,108,233, 58,206, 14,186, 90,172,207, 16, 36,194,247,134, + 7, 99, 94,216,209, 72, 63,190,155,188,253, 58,156,149,243,190,112, 60, 22,170, 22,178,128, 18,179, 95, 89, 19, 73, 67, 65, 38, + 19,193, 88, 54, 56,198,216,127,158, 42, 20,118, 69, 85,240,184, 75,187,169, 3,209,190,210, 62,210, 90,135, 92,133,163,211, 35, +237,181,158,242, 80, 26, 36, 57,162,107, 27, 76, 10,208,187,117, 50,234,160,207,232, 36,128,210,243,226, 42,231,179, 83, 94, 60, +142, 59, 31,235,196, 8, 98, 66,251,168, 50,211,249,133, 95, 8, 74, 82, 36,194, 2, 69, 76,132,190, 33, 79, 54,240, 62, 91,148, +109, 84, 24, 32, 28,143,101, 18,217, 25, 86, 15,104, 78,241,193,105,146,206,197,144, 32, 18, 78,142, 48,146,176, 76,212,232, 82, +198, 18, 69, 73,124,161,248, 52,203, 69, 33, 27,113,106, 52,216,253,121,121,170, 20, 53, 38,240, 94, 80,167,252,102,178,108, 9, +104,201, 68,209,181, 18,205,151, 22, 91,204,200, 54, 59, 22,209,166, 57,182, 79, 50,230,121,109, 49,142,110, 63, 25,223,251,240, +134, 62,190, 54,183,246,226, 59, 15,104,255, 33,237, 39, 84,126,163,131,247,244,234,144, 14,142,233,199, 39, 60, 36,123,215,232, +233,125,122, 52,166,195,239,244,252, 51,125, 41,104, 86,224,122,246, 98,234, 39, 52,118, 52,208,148,101,145, 41,237,137, 57, 63, +166,217,203,201,187,204,156,188, 24, 63,187,162, 95, 23,230,204,113,173,128, 49, 60,244, 96, 40,234,198,120,218, 50,186, 82,160, + 32,121,141,143,171,125,113,183, 27,142,233, 98,173, 38,185,185, 62,230,172, 53,116, 20,180, 14,178,140,167,185,120,245,169,183, +121,160, 16,226, 22, 4, 76,106,187, 30,201,173, 90,230,219,114,157,236,202,177, 75,181, 40,104,237, 64,145,170, 6,255, 59, 21, + 2,151,218,254,140,183,114,193,210,186, 19,245,111,238,220, 64,224,156,173,167, 37,215, 45,168,115,178, 69,150,155, 60,119,133, + 16, 23,204, 18,218,115,161, 80,132, 95,102, 68,215,225,239,180,212, 78, 30,202,254, 25,249,233, 54,201, 35,158,219, 97,183,154, + 27,254, 22,128,175,115,201,109, 34, 8,194,112,245, 99, 38,126,202, 50, 65, 66,113, 36, 47, 96, 11,130,236,179, 68, 57, 2, 43, + 46,195, 89, 56, 0, 59,174, 0, 11,118, 44, 88,102, 69, 20, 65,236,196,143,177,199, 51,211,211,244, 95,213, 51,118, 12,194, 43, +143,101,201,182,220, 83, 93, 93,245,215,247,219,163,159,231, 35, 26,173, 77,117,144,188, 15,236, 32,108,188,121,185,128,180, 28, +152,141,186, 53,206, 52,124, 60, 44,181,217, 85, 69,106, 59,195,164,103, 48,166,148,132,108, 60,188,178,241,224, 14,161, 35, 4, + 42, 52, 11, 4,209,144,147,217,237, 26,101, 39,199,202, 72,175,170,198, 77, 37, 73,176,248, 43, 87,132,229,123, 2,211, 33,221, + 81, 54,220,135,137,177,125,211, 13,111,219,241, 16,105, 31,156, 44,179,113, 57, 1,127,232, 76, 52, 97,244, 45,240,171,193,229, + 55,213,153,182,235, 28,185, 13, 13,230, 76,237,133,236,205,253, 29,207,217, 38,198,159, 56, 72,211, 36, 80, 94,235, 3,245,123, +189, 39,151,237, 63,135, 53, 35,173, 49,192,184, 75,207,186,186, 99,244, 34,119, 55,179, 85,200, 27, 87, 5,106,217,165,104,210, + 21,221,151,108,147,196,119,100,136,170, 27, 31,215, 20, 68, 68, 21,157, 66,152, 10, 30,192,150,183, 84,168, 89,224, 90, 19,169, + 32, 82, 24,205,155,191, 79,146,142, 84,120, 34,205,165,250,111,124,151,145,232,140,149, 4,180, 3,249,125,105,168,163,177,235, +244,172, 87, 78,175, 65,115, 11,151, 62, 69,183,136,182, 5,142, 88, 42,129,156,166,130,173,171, 46, 93,200, 58,116,146, 64, 11, +180,132, 95, 5,106,106,191, 22,245,244,137,121,253, 60,251,242,195,185,122, 7,221,125,136,174,140, 78,172,100, 76, 79,217,144, + 40, 24, 45,182, 69, 42,213,166,223, 27,206, 55, 15, 92, 54,255,135, 70, 82, 75,109,194,176,153,136, 39,112,228, 33, 30, 71,247, + 90,243,209, 82, 11, 6, 35, 82,191, 27,251, 49,199,193,221,199,184,200, 64,107, 60, 11,159, 59,234,141,102,171,185, 4, 92, 82, +123,161, 49,250, 64,117,180,152, 8,247,228,126,164,202,235, 19, 54, 15,130,188,129, 15,133,231,227,179,249,234, 30,197,163, 40, +164,149,236,221, 75,183, 41,234,153,163,174,221, 51,156, 68, 73,172,138,213, 61,163,197,106,205, 69,192, 1,101,187,109,200,217, +195,106, 71,149,209,251,223,203, 91, 81,216, 42, 29, 15,211,202,183, 54, 5,178, 63, 98, 8, 46, 77, 13,204, 44, 13,203,190,164, +136,233, 35,231,218,183,227,245,210, 16,197, 94,128,250,232, 91,125, 69, 51,186,120, 69,182,178, 63,239,252,231, 53,208, 75,250, +130, 38,239,168,119, 69,239,183,244, 33,101,166,228, 29, 13, 39, 68, 47,216, 14,228, 27, 93,126,164,211, 27,122, 40,168,204, 17, +146,173,165,169,162,243, 1,217,156, 38,117,242,102, 60, 29, 61, 37, 26,189, 12,203,241,251,245,237,167,235,175, 89,150, 1, 39, + 84,243, 68,138, 43, 75,100,219,152, 63, 18,176, 61, 34, 49,179,167, 35,192, 53,198,232, 70,185, 46, 39, 96,109,135,157,225, 12, +253,176,118, 50, 72,250, 26,184,232,166,253,188,100, 17,111,156, 21,138,194, 62,223,114,255,234, 67,165,137,218,247, 66, 93,132, +179,180,105,240, 33,225, 69,132,121,234,175,201,166,182, 24,163, 30, 9,103,226, 87,229,147,152,151,178, 54,183,237,205, 89,111, +218,181,221,220, 21, 69,177,201,171,245,182,200,178,114,131, 25,204,176,172,208,243,130, 85,153,228, 1, 45,152,139,181,209,149, + 63, 40, 67,248, 71,165,254, 99,233,189, 68, 60,117, 36,162, 60,120,252, 17,128,174,115,217,109, 34, 8,162,104,245, 60,108,207, +248,145, 4,226, 36, 44,128, 8,177, 1,133,143,224,255,216,243, 63,176,100,197, 2, 33, 33, 69, 8, 17, 34, 75,129,120, 60,182, +123, 94,221, 83,116, 85,247, 60,156,129, 40,203,216,138, 60,237,234,238, 91,183,238, 9, 6,135,119,175,105, 97,185,158,126, 28, + 76, 11, 37,247,213,158,167, 41, 45,191,150, 39,110, 28,225,136,161,215,154,130, 0,169, 49, 71, 88,216,145,117,187,231,164,202, + 58,101,141,220, 5, 94, 75, 35,199,166,153, 73,239,168, 41,216,215,188, 9,157,151, 66, 70,104, 19, 22, 93,216,216, 50,106, 28, +205, 2,210,157, 3, 2, 78,170,163,113,108, 46,198,102,181,236,170,122, 17,154, 47, 69, 48,245,188, 31, 85,106,205,174,162, 25, +104,199, 65,154, 35,118,213,204,239,225, 12,123,180,141,166,184,163,149, 62,193,113,208, 68,235, 22,117,131, 95,206, 32,201,151, +112,225,242,156, 45,207,189, 21,232,161,203, 76,137, 71,248,108, 33, 38, 30,252, 73,242,155,173,202, 56,248,220, 82,210, 38,252, +130, 77,115,254, 39, 35, 74, 83,175, 85,195,201, 51,229, 40, 99,124,184, 79,169,191,246, 3, 97, 51, 16,255,101,217,252,243,250, + 80,117,201,123, 15, 91, 12,194,253, 31,252,168, 70, 99, 45,120,119,137, 0, 18, 13,143,106,140,144, 87,159,192, 9,160, 52,247, + 12,237, 73,198, 63,153, 42, 63, 10,234, 88, 11, 41,176, 18,222,227,136, 86,104,161, 97,238,147, 85,197,198, 66,152, 43, 90,174, +224,118,131, 39, 51,239,237,155,209,199, 47,170,208, 65, 64,210, 56,255,214, 52,183,188, 60,126,178,186,191,157, 78,142,210, 44, + 97, 55,121,189,205, 83,218, 23, 57, 80,203,225,138,221,186,167, 30,191, 27, 65, 64, 11,238,230, 91,176,187, 12,123,110,182, 83, +216,156, 67, 50,170,155,131,130, 15,204,130,101,221,170, 77,202, 67,166,153,115,152, 20,174,119,107, 95,116,114,117, 19, 55, 68, +219, 69, 60,138,101, 33,205,193, 37, 10,103,210,156, 82,132,179, 36,230, 85, 97,113, 24, 30, 91,209,211,253, 38, 10,199,178,220, +249,110, 71, 18, 29, 6,172,118,169,208,214,175,231, 55,201, 2,162,109, 14,219,214,129,213, 0,173,218,194,150, 27,115,178,225, +171, 41, 61,183,249,100, 86, 80, 6,123, 5,173,160, 15, 3, 87, 52, 97,131,158,223,252,254,217,102,247,117, 86,142,238,185, 51, + 61, 21, 89,119, 64, 10,155,123,241,242, 66,254,130,175,239,117,116,233, 47, 47,149, 60, 14,239, 3,184, 91,193,135,207, 4,221, +133, 87,102,213,129, 62,135,250,140,140, 49, 87, 57,173,132,179, 43,184,120, 7,175, 77, 77,218,195,169, 4, 85, 18,205,118,182, +134,241, 2, 46, 19,120,122, 66,206, 25, 92,193,245, 55,248,244, 29,207,211,249,210, 63,189,243,174,203,202,156, 8, 85, 69,156, + 2,205,182, 9,170,235,243,120, 97, 62, 73,153,109,173, 71,213,217, 25,109,139,212,105,241,110,200,147,118,134, 44,105, 40,169, + 14, 64,203,105,121,244, 4,117,181,173,235,218,241, 54, 28, 10, 21,177,223,151, 28, 28,123,107,151,150,216, 29,127, 80, 60, 36, + 45,169,238,187,115, 48,182, 10,240,191,152, 23,207,245,143,144, 69, 26,214,214,166,225, 98, 30, 76,117, 93,202, 34, 77,178,116, + 95,237,168,178, 99, 81,146, 15, 78,115, 89,215, 86,117,232,229, 65, 2,119, 28, 88,247,166,122,160, 16,254, 1, 36,233,205,139, +160, 56, 36, 38, 12,115,104,254, 10, 64,217,181,244, 54, 13, 4,225,125,249, 17,167,110,218,138,148, 74,149, 80,133,132, 84,169, + 21, 7,110, 72, 32,113,231,140, 56,241, 7,248,131,252,129, 10,113, 6,133, 19, 66, 66, 37, 60, 42, 90,242,106,146,117,188,187, +236,204,120,253,128, 92,136,114,137,163,196,246,218, 26,207,124, 51,223,247, 85,252,166,150,137, 7, 39,236,210, 39,218, 0, 38, + 49,149,203, 28, 36, 55,157,193,189,129,166, 79,109,120, 20,170, 18,129,227,159,128, 99,246, 85, 26,137, 36, 18,232, 79, 6, 9, +186, 45,108,185,114, 27, 66,183,209,140,152,217,170, 13, 72,132, 14, 4, 68, 28,244,125, 72,231, 30,185,121,216,157, 16,162, 47, + 83, 21,197, 61, 17,251,244,102, 16,103,169,202,246,146,126,132,118,243,183, 6,136,202,133, 43,180,181, 31,110,222, 23,102,189, + 44,111,117,169, 87,128,204, 27, 72, 43, 17,157, 51,129,230,214,186, 58,146,179, 70, 36,162, 58,235, 16,220,155, 94, 95, 72,219, + 5,161,172,142,119, 60, 62,254,230,101,148,172, 38, 54, 87,139, 14,131, 22,254, 89,244,240, 14,247,135,248,237,183, 30, 27,176, +203,165,132, 58,197, 31,228,248,113,205, 42,141,238, 90, 80, 56,194, 4,188,192,175,106,186,169,106, 33, 45, 46, 72,202, 68,184, +113, 26,116, 0, 93,219,192,235,127, 94,116,117,146,218,115, 21,223,185,175,193,241,100,102, 72,223,142,112, 93,122,146, 15, 83, + 25, 3, 45, 7,135, 3,164, 15,133,160, 65, 28, 71,106, 39,102, 89, 79, 76, 52,215,214,165,177,175,249,164,102, 46,139,248,221, +129, 92,105,251,118,228, 43, 50, 80,161,180, 80, 13,192, 78,242,236,224,106,250,147,112, 75,188, 37,108, 44, 19,129, 84, 42,191, +242, 11, 61,195,250,169,163,105, 74,142,101,216, 65, 85,168,103,199,201, 13,149, 83,112,151, 36,198,197,207,142,207, 71,151, 31, + 81, 49, 0, 18, 68,128,188, 77, 97, 73,175, 2,139, 47, 18,174,176, 91,132,157,131, 44, 9,103,167,199,167,163,203,145,196,161, +120, 2,118,169,139,131,101, 4,165,223,156,160,109,116, 53, 35, 43,184,150,217, 47,122,214, 53,142, 63,172,197,100, 85,216,130, + 10, 22,175,212, 60,144,149, 6, 31, 54, 89, 5,197,125,199, 27,251,129, 10,159,161, 40, 2,118, 11, 85,191, 1,101,252, 37, 76, + 73,196, 10,140,167,163,208,138,192, 71, 14,106,245, 97, 96,243,145,245,232,224,232,251,205, 47, 41,211,149, 53, 79,246,159,190, +122,254,218,125,102, 23,239,216,245,114,206,119,197,124, 47,233, 61, 86,159,238,177,229, 33, 27,223,103,215,216, 29,145, 57,132, + 34,185,131,237,191,146,109,208,212,165, 44, 65,136,194,104,120, 88,100, 95,224,207, 15, 47,216,240,199, 66, 46, 39,143, 6,236, +217,238,112,104,146,248,138, 69,251,236,197,155,151,160, 71,100, 22,218,128,199,251,198,172,193,148,213,130,146,132, 15,248,132, +146,161,120, 9, 5,119, 75,209,180,162,239, 87,131, 35,174, 33,124, 54,172, 70,119, 50, 60, 25, 79,190, 10,167, 86,155,101,224, + 49,185, 16,227, 29,223, 38, 17, 35,186, 1, 90,213, 51,133,181,111,155, 97, 45,126, 1, 11,170, 94,255, 10, 18, 52, 5, 60,235, + 76,181, 66, 25, 9, 51, 51,120,147, 62,216, 61,235,201,120,170,103,211,245,100, 90,204, 97, 58, 28, 86, 14,149, 59, 48,178, 27, + 22, 68,231, 27, 7, 40, 81, 35,192,190, 24,182, 13,176,234,186, 56,112,125,144,174,155,179,111,161,179,254, 17,128,175, 43,216, +109, 26, 8,162,179,107,199,174,211,166,212,138, 67, 10,168,202,169, 8,184,112,226, 27,248, 91, 56,113,227, 6,226, 0,135, 10, +229,208, 10, 21, 16, 82,154,148,166,212, 73,104,108, 37, 78,118,217,153,217, 93,167,180,106,212, 83,218, 58,214,102,119, 60, 51, +239,205,123, 53,127,134, 35, 29,247,220, 67,242,159, 96,242,140, 53, 5,183,116, 20,181,105,162,182, 41, 90, 69, 72,151,217,154, + 13, 26,187,115, 61,111,170,152, 80,245,159,118,240,138, 16, 66, 94,163, 37,197,186,144,145, 32,103,250, 29,218,245,162,137,115, +204,191,200,180, 84,162,123, 89,130,158,209, 81, 72, 79, 14,147,235,205, 87,203,173, 16,245, 12,202,117,121,126, 61, 84,220,231, +211,230, 7,247,201,154,167,226,181,239,174,168, 13,232, 78,122, 76,196, 38, 83, 86,216, 77, 88, 8,220,125,103,210, 14,149, 4, +174, 52,102, 82,179,251, 53, 39, 92,150, 69, 21,112, 88,151, 78,111,204,124,114, 28,232, 87, 29, 49, 45,170,211,171,197, 72,163, +223,222, 22,176, 29,166,104, 67,208,134,112, 31,194, 24, 2,162,193,232,192,209,136,149,167,174,187, 45,199, 54, 12, 92, 80, 50, + 65,109,225, 28, 42,229,205,128, 46,239,237,195,220,255, 82, 14,125,245, 82, 1, 26,108,161, 72, 58,245,116,176, 77,118, 47,205, +246, 36,140, 87,154,220,202,132,114,106,223, 43,216,142,112,173, 43, 45, 90,145,164, 32,142,245,118,210, 64,201,201,188,212,205, + 40, 56,124, 28, 12,198,166, 64, 71, 61,105,204,214,145,108, 62,167,229, 18,156, 40,241, 0,136, 57, 6, 72, 80, 89, 47,152, 80, +170,221,172, 56, 53,212,205, 5,227, 56, 76, 20,234,249,112,231, 90,242,240, 4, 7,119, 73,110,179,173,228,193,121, 62,162,126, +180,224,240,106,174,155,110,239, 61, 63,120, 97,202, 5, 18, 24, 85,155,165,250,109, 64,158, 85, 13,198,132,139, 34, 78,230, 36, + 18, 26,102, 7,198, 9,130, 68,146,125, 48,120,128,197,105,118,219,212, 64,120,180,157,155,198,172, 33,101, 91, 56,146,165,174, +192,254, 51,155,172, 72,166, 90,217, 42, 4,233, 52, 62,100,240, 49,148,126, 48,133,158, 80,246, 15,200,225,132,108, 87,113,162, +149,253, 45,105, 85,108, 79, 72,215,137, 10,130, 28, 90,181,119, 59,211, 98,182,155,180,170,213,250, 91,249,163,127,122,210,123, +212,123,249,122,239, 89, 22,159, 12, 71,111,190,190, 63,234,119,207, 62, 54,139, 15,208,253, 12,135, 71,240,244, 59,116, 7, 80, + 28, 67,115, 0,242, 18,158,228,144, 77, 97,127, 6,114, 8,105, 14,237, 25,100,127,224,225, 25,180, 74,232,254,154,101,127, 7, +233,178,104,149, 81, 53,129,172,219,236,127, 82,111,143,223,253,132, 47,230,171,172,112,136,165, 82,106, 97,114,248,131, 78,111, + 50,191,178,169, 56,216,148,157, 20,209,184, 45,175,189, 92,162,118, 25,183, 29, 96,226,228, 29,119, 22, 54,169, 39, 69,190, 92, +153, 35,191,180,145,157,222,215, 53, 55, 92,187, 50, 90,241,193, 20,181, 82,183,205,150,149,135,214, 60, 49,226,102,112,119,222, + 78,162, 54,103,178,151,167,123, 23,178,238,146, 9,214,113,145,206, 77, 18,118,162,116,167,145,254,158, 95, 94,148,227, 98,117, +141, 19,245, 24,214, 81, 20,145,133,114,215,183,192, 94, 79,193,115,181,102,112,215, 67,234, 63, 85,203,205, 27,191,251,236,255, + 19,128,180,107, 89,141, 34,136,162, 85, 93, 93,211, 61,143, 30,199,152, 9, 89,140, 16,205, 74,196,141, 31,160,226,175,185,247, + 11, 4, 17,247, 46, 93,185, 54,224,194, 69, 4,117, 33, 40, 65, 99,195, 36, 65, 39,244,179,170,171,172,123,235,209, 61, 1,221, +152, 64, 66,134,153, 9,157,116,223, 62,247,220,115,207,217,194,239,145,179,181,132,241,104,132,248,125, 68,211,200,238,151,163, + 56, 73,187, 14, 70, 7, 74, 43,196,128,140, 12,126,143, 13,114,135, 49, 44, 24, 61,226,214, 8,232,128, 96, 81, 70,162, 3, 12, + 68,239, 2,198,178,139, 71,176,181,207, 56,222, 66,172, 33,103,232,178,193,238,134, 65, 72,141, 65,241, 28,196,144,124, 39,153, +101, 60,157,153,207,120,220,116, 32, 35,154,176,184,144, 32,153,253,186, 57,249, 89,252,104, 72, 85,136,202,170, 74, 17,188,119, + 22,191,171,208,210, 12,172, 97,131,101,152,173,232, 46,163,202,106, 25,172,106,136,146,225,190, 9, 11,142, 60,219, 93, 26,245, +230, 85,190,187,178, 30,178, 78,244,125,239,186,190, 44,219,111, 37,152,209, 9,196,224, 55,224, 43,155, 80, 62,101,108,153,240, +108,196,112, 19,149, 84,162, 91,151,245,169,170,215, 8,198,165, 39,206,148, 87, 64,234,160, 98,244,167,166,229,238, 19, 47,133, + 12,124,253,255,127, 88, 8, 63,243,230,209, 18, 31, 73,253, 32, 87, 99, 6,236, 28, 38,191, 52, 5, 89, 12,210,244, 73,148,165, +113,161, 13,138,103,230, 63, 36,113,236, 14,220, 25,165,215,198,116, 35, 0,249,238,101,156, 19,117,244, 81, 22, 45,199,173, 92, +108, 68,225,158,161, 23,147,221,245,239, 28, 77,122,240,158,223, 79, 53,224,175,191,152,238,158, 23,103, 12,171, 49,188,171,198, + 66, 78, 67,109,141,152, 35,207, 34,159, 0, 76, 44,252,181, 2, 22,137,131, 56,115, 50,152, 26,216,180, 21,166, 20, 56,152,248, +143,208, 45,139,238,181,207,114,112, 10,228, 8,141, 42,131,105,128,255, 69, 33, 54, 4,187, 5, 84, 86,246,214,132, 3,157, 21, +190,220,252,124, 23,188,130, 63, 49,127, 8,243, 52, 43,218,146,217, 99, 65,174, 41,118,212,121,160, 4, 67,152, 26,104,170,173, + 59, 42,162,126,130,109, 46,112, 57, 49,198,162, 38,144,250, 13,172, 78, 18,143, 76, 85, 45,155, 10, 72, 12,213, 9,123, 90,194, +115, 98,131, 37,148,185,226, 24,159,243,165,224,217,206,226,224,225,234,193,253,219,183,198,151,148,172,200,231,156,188, 62, 34, +111,190,147,119,107,114,222,192,200,228,209, 62,121,241,152,236, 31,146,227, 99,242,244, 11,201, 5,236, 64,165, 56, 55, 50,248, +189,218, 72, 26,199,249,233,179,174,126, 79,165, 52, 61,106,174, 79,110,146,213,243,195,151,175,196,147, 15,228,109, 39,155, 70, + 85, 82,213,109, 39, 36, 46,138, 75,200,217,160,158, 70,183,107,250, 78, 12,227, 43,251, 0,185, 43, 11, 0,160,130,163,191,167, +222,102,225,177,178, 43, 58,208, 80,170,193, 92,245,138,189,163,187,238,195, 77,221,170,126, 7, 89, 60,122,192,114,248, 94, 98, + 40,221, 33, 4,166,250, 32,151,170,163,158,225,141,168,175,239,230,251,114,186,119, 81, 92, 28,100,119,170,166,254,213,158, 9, +105, 42,187, 64,216, 14,132,140,196, 72, 45,218, 59,157,245,178, 28,218,187,141,219, 89, 11, 40,209,174,176, 5, 1,194,119,189, + 96,244,111, 42,120, 23, 58,251, 71, 0,210,174,158,199,105, 32,136,238,174,215, 73,156, 68,145,149,112,210, 17, 14, 9,116,208, +156, 78,208, 32, 81,242, 63,104,169,248, 63,252, 5,106,232, 40,105,169,168, 0,233, 36,160, 57,133, 40,185,187, 92, 32,216,103, +123,189,187,120,102,118,157,181,116, 29, 77, 26, 75,246,198, 31,179, 51,111,222,188, 39, 3,244,222,189,244,194, 45, 26,177, 41, + 35, 80, 29,193,205, 68, 7,145,221, 32,146, 69, 19, 64,244, 81, 69,160,137, 97,193, 76, 41, 6,240, 8,204,110, 13,150, 33,174, + 98, 50, 70,250, 23,182,246,163,183,216,122,173,177,197, 23, 65,163,192, 64,235,174, 89,127,243, 25,107,173, 5, 58, 27,247, 56, + 74, 76, 88,147, 87,170,121, 53,155, 42,190,168, 85, 18,129, 99, 95, 89,215, 23,229, 26,242, 45,237,228, 28,218, 17,247, 54,156, + 11,170,196, 3,209, 89,238,104, 14, 12, 60,216,155,179, 85, 55,248,177,220, 18,220,197, 62, 39, 11,117,195,237,254, 73,208, 45, +172,247,162,241, 66,200, 36, 73,231,209, 74,170,250, 71,174, 46, 16, 96,161,204,125,200,226, 52,146,211, 88,142,250,189, 81, 44, +239,140,123,195,158,156, 12,161, 52,105,182,190,159,171,237,135,197,242, 79, 23, 3,162,180, 61,246,203,214, 62,203, 14,241, 28, + 27,244, 81,217,127,164,240,161,221,171,242,160, 60, 93,165,194, 75, 12,168,188,168,217, 13, 90,209, 1,166,219,148,216, 70,228, +202, 54, 91, 84,191,199,210, 62,208, 32,147, 65, 44,192,130,153, 77, 71,160, 10,112, 52,225,219,204,236, 10,115, 47,141, 94, 60, +225,159,206,212,213, 78, 34,231, 27,147, 99,101,198,131,209,102,135,217, 28,210, 73, 45,221, 86, 20, 67, 7, 36,170,200, 56, 12, +160, 97,177,199,200, 63,119, 31,220,133, 15,238,212,207, 60, 61, 58, 57,223, 44,104,248, 48,108,136, 1,191, 86, 87, 17, 50, 97, + 45,187,205,146,178, 91,204, 24,214,106, 28, 5,146, 82, 22,169, 61,200,121,231,126, 13, 36,161, 74,178, 82, 26, 39,156, 34,154, + 46,117, 50, 57, 45,173, 13,253, 14,224, 87,127, 93,124,227,222,251, 25,212,154,203, 76, 58,134,140, 19,248,243, 2,226, 94,177, +199,135, 39, 65,172, 74,218, 94, 64, 41, 83,180,217,232,241,193,195, 95,215, 75,234, 65, 22, 85,145,151, 57, 53,154,155,243,207, +167,119,149,209, 89,145,111,243, 93,205, 81,216, 66,216,195,116, 86,100, 42, 22,234,119,181,126,191,254,248,174, 60, 27, 76, 30, +245, 78, 30, 63,125,205, 94, 50,246,170,121, 16, 11, 86,156,179,106,195,230, 15,112,128,181,121,250,111,216,120,197,138, 37, 43, + 11,150, 41,216,155, 19,104,113,200,195,132,149, 92, 76, 71,227,249,232,224,120,120,255,249,236,153,144,234, 75,246,246,251,245, +231, 26,192,247, 38,172, 43,141,251, 44,128, 18,181, 73,199,179,139,191,151, 52, 51, 76,164,117,227, 38, 81, 41,131,164, 3,220, + 77,106, 2,158, 71, 17,188, 69,105,168,111, 71,154,191, 64,157, 33,219, 88, 78,226,164, 93,251, 99,219, 25,241,244,182,124,172, +163, 4,105,130,208,215,133,221,157,129,134,222,251,122,216, 28,153, 51, 12, 21, 34,249,126,202,160,149,200, 96, 87,187,203,113, + 63, 77,120,188,211,151, 32,196,133, 36, 25,237,152,251, 45, 33,217,134, 14, 80,193,166, 2, 98,109, 18, 97, 73,239,187,106,195, +127, 67, 58, 90,164, 91, 97,131,234,189,171, 93,220,241, 12,252, 39, 0,107,231,178,219, 52, 16,133,225,185,216, 30,199, 78,226, + 22, 10,165, 8,161, 62, 3,139, 46,120, 25, 94,139, 37,111,196,162, 72, 32, 36, 42, 65,202, 2, 87, 81, 72,115,105, 98,123,108, +206,109,156,132,148, 29, 81,165,180, 73,164,168,118,226,249,207, 57,255,124, 63,234,247,142, 55,245,136, 92, 37, 46,145, 52,223, +141,211,131,150, 40,213,158,122, 8, 60, 47,165,181,200,244, 6,121,124,153,138, 83,234,188, 99,110, 31, 72,239, 78,215, 32,162, +113,226, 74, 2, 66,241,201, 32,158,144,198,253,153,134,121, 44,178, 95,143,150, 26, 45,248,172, 8,123,171, 54, 53,206,226,238, + 77, 7, 66,222, 26,208, 26,249,216,229, 32, 21, 46,242, 98,228,178,170, 37, 83,104,167,103,213,252,122,122, 13,127,173,155,213, + 6,249,145,176, 2,192,227,148,236,138,135,221, 51,225,236, 40,156, 80,139,167, 14,107, 8,211,246, 93,248,191, 46,238, 1,243, +164,118, 11,117,215,203,187, 29,178, 57,212,142, 92,184,213,190,123,158,214,175, 35,255,241,119, 61,161,167,115,165, 78, 48,243, + 50, 26, 42, 59, 76,146, 83,135, 16,241, 81, 26, 63,201,220,137,179, 89, 10, 85, 79,148,184, 56,119,238,211,143,242,253,231,111, +183,161, 33,222,236,184,162, 7,200, 80,191,247,123,171,254,243,205,132, 66,161,143, 39,244,225,227,146,135,137,238, 25,117, 22, +224, 48, 17,239, 13,189,171,121, 98,139,212, 34,224, 63,141, 94,156,198,195, 60,201, 51,168,182,116,221,242,188,203,223,206,177, +130,126, 54,178,137,233,190,223,109,191, 76,212, 67,133, 29, 5,248,238, 38, 81,190,220, 44,224,108,250, 86, 98,183, 58,145,171, +193, 9, 18,218,134,134,105, 92,134,119,222, 17, 45, 82,235,224,134, 52,180, 37, 42,110, 48, 41, 59, 24,194, 41, 98, 38,252, 52, + 12,218, 38,246,168, 14, 37,151,121,108, 26, 33,155,239,246, 69, 17,188, 60, 27, 96,222, 27, 69,213, 82,111,136, 17,129, 28, 42, + 98,130,233, 26, 86, 0, 79, 3, 32, 41, 32,122,242, 49,251,226, 9, 65,134, 66,158,147,163,120,157, 96,215, 52,179, 74, 20,255, + 95,134,161, 66,130, 65,166,110,142, 16,195, 25,197,129, 21, 51,110,134,209,246,188, 56,159, 46,202,152, 2,213, 99,236,211, 68, +130,139,162,113, 5,232, 34, 12, 80,136,226,213,118, 93,121,166, 22, 97,208, 13,172, 14, 89, 60,178,105,161, 7,227,139,179,203, +233,160,176,195,203,229,187, 55,221, 21,158,253,140,252,178,124,104,120,160,252,150,150,252,151, 74,221, 83,186,223, 56, 20,118, +219, 27,165, 75,245,245,195,204, 46,126,150,139,201,116, 57, 89,173,126,149,203,155,106, 51,127,168,239, 53, 58, 35,177,219,214, + 32, 55, 15,223, 31,196,156,181,182, 2, 9, 47, 78,198, 3,217,222, 6,156,191, 72,240, 86, 80, 18,129,249,200,121,184,140, 9, +225,187,110,127, 10,202, 19,176,227,207,243,129, 70, 22, 37,175,205, 63,119,165,118,125,241,197, 23,247, 71,113,145,189,103, 90, +115,136, 41,158, 20,164, 17,192,117,252,169,123, 21, 41, 55, 91,223, 85,104, 59,104,200, 73, 47,240, 90,105,133, 28,216, 61,132, + 40,105, 4, 95,193, 53, 58,245,222, 48, 75, 67,242,255,142,205,145,158, 47,170,123,148,227,227, 20, 86,184,253, 17,128,180,243, +217,141, 34,134,193,120,236,204,159,150, 86, 80, 21, 36, 4, 18, 92,184, 32,193,123,240,162,188, 15,170,122, 68, 28,128, 3,162, +162, 91,137,161, 59, 51, 59, 73, 76,108,199,217, 89,177,112,161,199,149,186,187,218, 36,158, 47,246,231,159,155, 53,220, 18,172, +158, 92,146,134,236, 85,239, 70, 23,146,253, 63, 21,181,238,141,236,228,100,156, 87, 62,215, 93,223,100, 73,221, 54, 76,187,242, + 75, 62,215, 50, 27,126,209,180, 65, 1,218,203, 33, 75,226,224, 46, 95, 83, 59,212,192, 28, 46,178,190, 76,217,113, 49, 75,248, + 4, 17, 35,242,236,160,162, 89,206,217,118, 73,195, 50,183,200,175,245, 30, 6,246,183,177,199, 70,202, 51, 4,171,103, 87,185, + 35, 75, 67, 24,185, 2, 77,198,125,239, 22,157,250, 62, 58,246,229,122,172, 5, 85, 51, 90,232, 52, 10,239,106, 35, 34, 88,213, + 1,172, 73, 11,214, 8, 55,208,217,188,156, 21, 58,111,233,213, 9, 93,221, 46, 95, 14,179,219,169, 96,165, 64,141,150,186, 66, + 81,124,178, 83, 98,244,101,254,149, 95, 63,127,242,110, 51,188,255,126,179,252,125,158, 64,252,247,156,129,255,254,211, 2, 0, +154,138, 39,219,115,218, 72, 37, 45, 24,220,125, 49, 74, 51, 86,240,138, 63,163,187,153,141,230,151, 15,120, 23, 13, 63,221, 48, +132,132, 35, 47, 55,184,190,243, 79, 31,250, 51,223,237, 28, 78, 1,186, 14,159, 61,238,193,207, 95, 55, 83,190, 10, 76,115, 92, +150,169,237,152, 13, 56,134,172,178,217,254,152, 86,160, 36,172,192, 12,177,252,169,121,154, 7,177, 49,231, 7, 76,165,138, 48, +225,150, 40, 30,193,155,131,192,155, 23,111,175, 63, 95, 31, 57,233,218,226, 80, 64,244, 71,131,187,208, 79,156,171, 79, 25, 13, + 54, 8,138,170,241, 26,217,197, 63, 99, 74, 90, 0, 27,145,193, 14, 30, 20, 96,230,107,185,181,186,170, 20,134,196,205, 64,143, + 78, 46,182,229,134,129, 21, 30,162, 59, 72,154,114, 69,130,217, 36, 79,132,242,244, 0,117,130, 74,221, 72,221, 59, 58,111,103, +154,239, 85,141, 53,168,216, 19, 41,223,162, 87,235,111, 2,156,195, 18,118,247,202, 25, 37,185,100, 36,150,100,110,160,109,155, +176, 73,205,143,120,183,227,116,232, 54, 95,208, 90, 9,238, 23,178,202,193, 50,132,121, 39,124,144,154, 80, 29,215,154,172, 78, + 51,191,116,191,110,220,101,248,216,208,167,184,124,163,233, 54,205,155, 51,207,231,159, 33,249, 92, 77, 25,153, 91, 17, 25,212, +147,248,246,144, 35,125, 16,218,163,148, 85,247,163,149,162, 24,124, 84,150, 23,122, 12,213,240,103, 1, 55,169,129, 18, 76,240, + 27, 29,125, 29,230,254,220,207,110,159,127, 47,110, 81, 49,152, 31,121,182,211, 62,230,146, 49,120,235,155, 38, 50,247,115,101, +190,144, 25,237, 20,214, 47,183,139, 28,155, 78, 39, 30,237, 29, 37,123,145, 76,122, 83, 53,192,172,146,131, 88,219, 35,209,224, + 19, 34,121,139,255,221, 36, 63,154,143,191,140,244, 51,122,246, 33, 10,248,112, 64,180,126,240,111, 1, 88,187,154, 30, 39, 98, + 24,154,143,105,102, 58,165, 93, 78, 11, 23, 96, 17, 7,126, 3, 63,157,223,129,144,246,178, 28, 88, 86,136, 2,210,150, 85, 59, + 31,137,109, 18, 59,153,153,178, 92,144, 56,244,218, 78,218,212,126,182,223,123,174, 30,101, 54, 9,183, 70, 84,189, 17, 16,141, +104, 49,109,134, 69,153, 34, 10, 73,147,241, 74, 50,218,173, 84,188, 25,117,109,156, 44,221,102, 58, 60, 72,114, 14,137, 64,144, + 80, 19,187, 47,165,196,171,203,130,158,136,238,185,151,138,217, 28, 25, 40,195, 99,173,165, 70,139,225, 97,149, 6,113, 38,130, +194,117,213, 56,110,233, 59, 27,159, 4, 15,190,107, 42,183,117,171, 14,194,215,211,158, 83, 71,234,240,240,237,161, 51, 10,131, +144,222,121,105,134, 85,122,134,107, 60,152, 26, 89,166, 40,193, 93,205, 36,119,230, 50, 76,140,167,121,210,117,182, 86,187,204, + 85,160, 96, 3, 70,124,164,157,133,183, 45,221,221,251, 79, 52,183,179,153,253,162,211,104, 20,233, 68,193,122, 14, 48,241, 56, + 62, 36,115,165,213,170,117,105, 90,227,185,201,244,238,229,179,247,223,246,119,229,231,161,127, 71,223,248,159,162,188, 47,234, +243,233, 58, 58,190,107, 93,249,159,199,115,213, 48, 3,212,135, 62,213,117,245, 0, 93,114, 56,128,129,153,112,163,210, 79,172, +185, 1, 60, 2, 93,236,220,213,139, 93,117,185,113,201, 45,128,126,245,240,227,190,135,180,119,189,103,148,143,236,107,222,140, +195, 22, 23, 66, 66,185,149,200,170,102,177,213,125,117,121,117,251,253,179, 22,167, 10, 91, 5,240,231, 78,242,233,245,225,246, + 35, 77, 11,238,105, 46,191,165, 64, 39,203,241, 3,181, 82,127, 74, 71,152,141, 76,187,205,211,211,216,249, 48, 44, 11,252,228, +121, 98, 68,147,196,171,103,121,190, 43,244,253, 8,234, 83,143,145, 39,251,172,108,207,159,147, 85, 57, 32,205,244,140, 50,145, + 38, 41,202, 52,201, 86,188,232, 74,192,163, 97, 65, 32,137,199, 36, 9,114,143,159, 72,197,172, 90,106, 24,149, 57,241,235,166, +237, 67,207,134,198, 74, 38,204,233, 1,197,118, 54,247, 51,112,187,190,136, 23,125,127,248, 25, 47, 88, 83,183, 15,125, 47,121, +200,135,163, 1,235,253,218,232, 77,107, 67,215,100,239,129, 41,130, 83, 33,110,185,146,239, 67,145, 73,203, 25, 14,149,242, 17, +223,169,158,146,192,124, 0, 58,198,247,140, 85,142,135,227,128, 3, 98,204,224,254,205,243,215,215, 95,174, 37, 58,163, 40,121, +184,151, 14, 5,210,241,124, 85,100, 91,210,101, 21,193,142,206,106, 84,181, 8,238, 2, 19, 97, 38,213, 76, 64, 27,255,158,204, +231,216, 87, 36, 79,147, 46, 73, 47, 67,124,153, 88,210,180,218, 20, 23, 86, 4,180,216,165, 76, 89,195,104,178,139,112, 81, 60, +148, 58, 35, 30, 13,120,191, 92,210, 9,201,206, 45,207, 61,106,200, 13, 15,181,240,163,199,210,111, 81,101,136, 71,133, 70,142, + 37, 42,155, 34,233,101, 7,142, 89, 57,191,240, 62,127,148,165,166,111,227,183, 0,188, 93,217,138, 19, 81, 16,237,253,102, 98, +119, 50,163,204,188, 9,234,147,248, 46,204,255,255,130, 8,163, 32, 34,130, 66,204,100, 72,199, 94,239, 82,222,170,186,213,139, +224,171,121, 10,233, 78,210, 27,117, 79,157,170,115, 74,230,107,207,205, 88,226,130, 70, 0,214,127, 82,101,207, 26,221,210,148, + 72, 38,125, 56,131,192, 56,168,166,224,158,109,114,212,163, 1, 14,203,242,207,142, 70,230,157,213,196,150, 35, 60,155,162,145, +143, 54,142, 28, 18,120,109,197,231,145, 87,196, 12,255, 63, 39,215, 5,244, 12, 81,200,143,251,228, 32,247, 17, 33, 33, 30,201, +255, 90,145,160,234,201,127,231,208, 62,142,168,143, 53,228,170, 25,156, 65, 23, 66, 84, 50,117,140,236,196,187,185,116, 30, 35, +190,104, 1,226,158, 36, 1,137,212,187, 26, 74,104,139,224, 62, 91, 23, 70, 11, 67,186,197,229, 5,148,155,194,219,202,194, 0, + 31,140,155, 56,141, 92,174,185,142,200,168,129, 56, 23,159,113,116,104,157,108,154, 81, 59, 80,123,163,174, 84,161,242,164, 79, +161,218,109,223,228, 87, 71,221,233,245,125,250,111,175,100, 22,195,204, 7, 0,194, 11, 49, 23, 63,202,123,110,236, 81,180,245, +201, 68, 30, 37,110,123,116,181,234,184,182,147, 68,247,175,170,215,213,238,203,247,250,225,212,124, 62, 14, 31,143,191,222,191, +236,238,223,189, 80,185,186, 45,157,238,205,227,197, 12, 35,244, 62,141, 71,237, 68, 84,170,230,122,227,195,194,222,206,144, 4, +111,211, 93,117, 87,183,104,229,232, 33,238,183,195, 87,210, 7, 98, 67, 75, 89,148, 79,221, 73,122,131,161, 82,101,171, 59,170, +113, 34,200,183,206, 73,137, 19,130, 45,123, 64, 93, 41,214,237, 50,122, 72,157, 72,224, 41,224, 98, 7,206,246,249,239,238, 60, +104, 61,233,172,226, 80,142,103, 9, 85,204,154,211, 20,163,123, 74,185,116,202, 0,139,134, 6,161, 37, 47,238,234,113, 73, 94, +212,221, 57,150, 21, 38,118, 65,217,124,233, 46, 41,213,123, 28, 19,228,137,204,119, 96, 77, 44, 15, 15, 34,246, 63,100,137,212, + 51,130,132,123, 26,198,128,208,216,136, 44,232, 83,208, 42, 33,144, 60, 42, 43,252, 97,105,107,216,152,229,166,188, 62,156,209, +232,248,220, 94, 60,136,198,129, 36,102,240,225,227,118,119,243,179, 62,161, 11, 20,234,108,253,238,117,220, 23,102,179,135,125, +184,203, 78,202,245, 83,233, 30,100, 81,119,178,213, 73, 29, 8,181,236,121,227,244, 48, 36,126,157,238,117,220, 27,104, 70,172, +169,142,168,195,183,238,225,199, 39, 75,229,106,114, 1,243,192, 20,229,166, 86, 90, 99, 32,204, 45,148, 22,199,136,243,183, 24, +214,225,149, 64,186, 19,228,190, 10,238,240,183,192, 52,134, 69, 67, 36, 44, 92, 72,215,132,124, 88,238,197,157, 10, 38,238,154, +173,132,220, 63,166, 59,196,100,103, 68,150,104,161,218, 27, 44,139, 57,183,192,243,193,193,201, 38, 4, 98, 58, 57,114,133, 76, + 41,196,195,170, 88,154, 36,139,122,128,168,142, 24,188,199, 11,207,152,160,172,164, 84, 46, 97,134,124,170, 40,202,218, 3,130, + 59, 87, 65,227,143, 0,164, 93,203,174, 19, 49, 12,205,107, 30,109, 5,213,189,176, 64,226,249, 9, 8, 22, 44,249,113,126, 2, +116,247, 8,177,132, 75, 75, 31, 51, 77,147,140,137,237, 36,147, 1,177, 64,108,186,105, 43,205,211, 62,182,143,207, 49, 53,234, +145, 9,191, 39, 90,161,162,253,130, 70,175,182,237,131, 1, 35,142,135,172,107,138, 44, 23,109, 90, 21,171,237,190, 69,173, 49, + 69,143, 38, 18,102,128,146,179,199,250, 11,239,176, 7, 46, 37, 66, 18, 82,229,168, 95, 13, 52, 96, 54, 75,198,178, 18, 1, 55, +170,148,181,189, 89,181,186, 51, 58, 6,190, 22, 45,107, 72, 77, 44,222, 97, 39,156,119, 83, 39,250,221,101,199, 91,112, 49,169, +224,155, 44,195,146,239,143,245, 65,144,243, 52, 67,213,115,106, 38, 66,228,174, 84, 78,105,152,152,117,145, 60, 73, 62, 44, 75, +223, 38, 33,235, 97, 53, 93,177,137, 20, 40,167,151, 27,215,131,188, 59, 94, 79,203, 68,202, 12,247,142,182,144, 77, 44,168,145, + 73, 16,107, 17, 19, 79,227,108,245,238,108,187,198,172, 59,115,211,247,183, 27,251,124,187,126,250,112, 45,238,199, 50,228,252, + 87,220,253,255,200,253,207,135,154,195,253,149, 62, 59, 2,245, 70,204,138, 16,150, 14,149,233,243, 7,218, 40, 26, 41,177, 61, +154,196,187, 23,143,135,189,212,147,238,165, 54, 16,190, 9,241,225,235, 73, 5,255,254,205,179, 39,219, 94, 7,231,172,255,124, +143,221, 89, 79,176,103,196,197,200,177,105,208, 90, 10, 42, 26,238,247, 35, 78,228, 8, 53, 19, 74, 69,140, 60, 93,236, 96,175, +140,169,105, 39, 49, 4, 73,146,144, 32, 19,155, 23,112, 48,176,161,221,209, 19, 36, 10, 75,122, 49, 9, 29,107,252,163, 33, 35, +123, 90, 73,154,136, 48,126, 28,142,125,183,114, 62, 76,105, 73, 27,168, 45,206,172, 69, 94,183, 82,166, 65,199, 27,110,255, 55, +216, 54, 12, 49,214,143,151,145,193,125, 32, 95,208,211,104,137, 86, 0,153,250, 46,147, 9, 56, 97, 28, 82,184, 9,200, 31,200, +107, 42,236, 39,137,106,249, 44, 9,204,134,145,148,126,222,190,122,253,241,203, 39,198, 25, 44,105,198,238, 96,241, 66,236,135, + 61,181, 43,177, 93, 67,182,101,120, 76, 68, 5,145,232,248,193, 12, 32, 82,245,163, 79,216,157,127,132, 65,225,142, 48,102, 35, +167,128,252,215, 20, 56,105,101, 55, 55, 94,124,149,221, 67, 53,234, 47, 95,133, 34, 39,105,196, 32, 14,241,178, 93,221, 79,239, + 15,224, 35,132,191, 32, 27,114,194,233, 34,189,149,116, 66,121,148,154,204, 80,127, 11,238, 18, 82, 95,102,182,208, 75,248, 20, +184,245, 41, 67,222, 71, 77,172,235,186,139, 34, 23,189,153,100, 75, 93,100, 99, 75,181, 84, 65,248,202,193,174,244,100,114, 36, + 88,130,247,153,226, 82, 9,177,135, 34,147,147, 15,131, 71,112,248,203, 49, 28,214,234, 70,179, 41, 20,225, 37, 86,226,128,121, +154, 5,101, 21,174,236,190,179,245, 16, 69,164,176,244, 69,224, 99, 69, 75, 84,154,202, 96, 16, 86,137,181, 41,179,116,229, 95, + 85, 36,127, 9, 64,219,181,236,182, 13, 3, 65, 46, 37,133,166, 29,167, 45,140,246, 80, 32, 31,208, 75,255, 31,232, 71, 20,254, +130, 32, 1,146,160,201,193, 41, 18, 61, 76,241, 81,238,131,178, 20,163,232,169, 62,217,134, 97, 75, 48,185,156,221,157,157,153, +234, 51, 58,157,134,127,104,121, 33,139, 95,102, 68, 26,125,177, 53,117,222, 63,132,226, 35, 77, 79, 96, 50, 13,200,102,169, 61, +182,174,124, 67,147,129, 52,136,136, 11,215, 67,224, 3,172,200,161,192, 98, 76, 88,204, 6,227,212, 48,164,173,130, 58,128,141, +202,176,221, 92, 86,118, 83, 27,219,172,242, 79,215,128,202,101, 67,242, 53,112, 20,143,249, 54,195,232,186,208,147,224,115, 32, +124, 83, 8,250,114,108,104,214,100, 39,191,122,173,102,138, 38, 32,212,119, 62,117,150,242, 3,160, 97,154, 88,152,212, 36,164, +231,174,225,196, 88,129,146, 39, 73,250,120, 1,233,235,102, 52, 40, 76, 17,111,206, 78,123, 45, 68, 37, 84,113,233, 81,189, 18, + 83, 84,163,198,118, 84,228, 21,170, 45,210, 61,171,167,186,189,106,170,231, 67,142, 44,222,252,203,187,236,127, 63,194, 76,193, + 38,204,240, 90, 85,162, 60,148,125,174,203,165,118,180,157,248,126, 7,122,153,159,223, 63,116,119,143,238,230,181,251,165,198, +182, 64,254, 31, 15,195,102,253,252,253,219,103, 99,204,151,173,187, 61,184, 21,160,221,171,163, 53,209,121,117,149, 94,183, 54, +199,101,227,252, 80,209, 88, 32, 18,185, 82,153, 7, 5,214,117,200,112,182,202, 57, 16,205,162, 51,193, 70, 93,239,174,247,119, +123, 42,157, 49,106,143,111,125,142,236, 49, 71, 58, 47,224, 48,125, 92,127, 58,244, 47,121, 1, 99,243, 93, 56,113,129, 92, 88, +164,152, 51, 6,231,250, 35, 85,232,133, 10,201,170,113,100,161, 85,163, 29, 60,202,250,194,218,174, 35,149, 34,173,181,249,139, +114,112, 71, 88, 39,166,247,242,233, 24,211, 4,168,120,228,157, 61, 56, 53,235,169,176,140,158,204,210, 39, 45,147,250, 28,194, + 88, 78, 65,214,243,207,219,189, 46,189,246, 98, 1, 71,254, 89, 74,203,186,149,172, 62,102, 60, 68,181,239,124, 17,225,241,247, + 19, 17, 13,240, 62,115, 16,111,143,125, 98,135, 71,224, 65,197, 64,188, 51, 18,140,136, 99,254, 47,194, 12,155,167, 25,242,157, +120,214, 97,249,102,152,130,190, 70,241, 18, 31,143, 65,185, 10, 25, 6,152, 85, 19,216, 11,156, 87, 75,109,134, 58,112, 65,184, +164,177, 68,244, 36,202, 36,212,141, 59, 67,238, 4,165, 33, 74,203,252,228,207, 33, 65, 45,190, 15,238, 11,186,204, 92, 57,125, + 14,225, 23, 33, 62, 45, 26,176,103, 29,218,119,243,162, 92,162, 81,197, 4, 91,151,194, 60,159, 88, 25, 79, 66,235,219, 15,171, + 93,229,204,136, 18, 36,172,174,195, 78,147,211, 81, 14,133,197, 23,197,147,141, 34, 76, 69,244,177,101,146, 33, 41,228,101,179, +179,176,165,213,133,214, 68,111,225,101, 32, 3, 8,152,198,143,254,242,248, 35, 0,107,231,178,219, 54, 12, 68, 81, 82, 15,218, +146,163,192,104,131,124, 67,182,253,255,125,209,101,251, 1,237, 38,221, 36,139,214, 54,100,189, 40,146,229,157, 33, 37,202,105, +129, 2,109, 86,206, 34,128, 95, 33,103,238,220, 57,183, 72, 54, 2,164, 92, 68,136,144, 97, 41,103, 57, 31,196, 94, 59,163,100, +177, 43, 75, 27, 37, 34,190,238, 74,138,164,232, 33,193, 33,103, 0,161,243,188, 38, 72, 16, 6, 35,102,148, 86, 38, 39,205,125, + 85,171, 13, 21,188,203, 65,156,241, 10, 35,217, 92,115,172,225, 41,112, 88,203,157, 63,234, 17, 73,157, 83, 82,154,179,190,163, +158, 51, 27, 51,111,241, 12, 59,221, 66,228,130, 89, 1,154, 23,111, 54,111, 69, 55,201,213,204, 6,189, 22, 61,154,110, 77,205, +102,255,123, 0,199, 71, 78,253,162,227, 80, 83,193, 37,188,115, 27,137,155,134, 98,117, 57, 42,171,125,163,235,239,161,239,227, + 60,253, 1,214,169, 67,217,235,104, 40,109,174,150, 83,133,178,157,152, 47, 70,214, 98, 6,129, 64,200,111,151,190,128,188,251, +127,204,236,255,126,202,155, 45,225, 64, 38, 30,158, 57,185,192, 92,194, 75, 88,164,207,147, 16, 31,159,127,182,189,123, 17,232, +105,122, 94,237,167, 7,159,190, 94, 62, 60, 61,188,107, 84,215,169, 59,133,204,194,110,194, 95, 93,169, 15, 56, 15,226,253, 97, +170,212,227,235,117,140,192,253, 40, 89,130,159,133, 19,113, 95,213,254,235,119,246, 5,163, 11,104, 76,255,141,252,252,252,133, + 0, 3, 75,239, 12, 71, 35,168,150,133,210, 19, 11,140,114,208,157, 63,214,154,234,216,235,126,176, 67, 93,214,135,125,115,238, + 78, 68, 72, 15,104,217, 56, 74,147,156,195,141, 98, 27,197,126,112, 21,208,134,105,174,141,190,111,142,151,211,143,234,112,215, +247,131,115, 87,114,185,132, 49, 79, 0, 27,210,232,192, 5,141,134,105, 30,172,241,145,194,206,196, 91,164,254,100,252,171, 63, + 17,203, 44,143, 82, 69,120,201,100, 2,229, 52, 67,123,139,127, 77, 54, 94, 12,165,253, 21,249, 78,155,214, 81,250, 10, 93, 94, +142,114, 73,194,214, 63,145, 0, 12,225, 10, 51, 7,235, 51,146,143,208, 55,137, 9,239, 90, 39,178, 35, 26, 47,187, 1, 82, 37, +166,227, 55, 71, 63, 30,251,150, 11,131,115, 4,121,249,154,125, 4, 56, 22,139,140,112, 4, 74, 2, 9, 56, 54,221, 17, 83,121, +217, 72, 93, 53,235, 16,226,196,154,187,189, 25, 25,146,158,141,232,207, 56, 78,180,113,110, 97, 23,196,192, 95, 15,169,100, 90, +140,187,223,252,159,218,219,141, 80,241,134, 58, 25,102,179,249, 90,179,218,104,152, 8,159,154,191, 44, 95,167,151, 90,221,219, +105,212, 46, 4, 29,175, 86,203,224, 85,225, 35, 40, 95, 52,119,210,159,253,203,212, 34,193, 80,176,131,182,204,171,166,120,108, +253, 13, 10,118, 5,212,191,210, 23,132, 66,181,216,150, 49, 78,164,227,222,219,159, 95, 2, 16,119, 53,171,109, 3, 65,120,215, +146,108,139,216, 77, 3, 33,161,167,190, 64,233, 59,180,167, 62, 70, 46,125,221, 60, 67,160, 16, 26, 72,156,196,114, 44,237,127, +119,190, 89,173, 54,200,144, 99,133, 14, 90, 73, 24, 44,217,179,179, 51,223,207, 98, 62, 83,101,235,176,138,250,156, 26,245, 46, +105,132, 53, 52, 59,145, 19, 94,252, 14,154, 94,164, 57, 88,221,123,211,144,150,250, 2, 76, 29,233,125, 2,163, 50,118,141,200, + 20,212, 72, 73, 69, 79,152,127,195, 56, 61, 33,219,208, 60, 18, 64,228, 74, 73, 50,173,245,186, 93,180,219,213,217,166, 33, 75, + 26,212,155,200,238,117, 73,102,194,130, 49,180,129,156,198,234,222,190,106,172, 1, 33,122, 99,121, 86,241,185,148, 38, 67,142, +207,114,210, 81,224,148, 60,100, 13,119,206,226, 25,166, 70, 97, 55, 73, 65,101, 38, 34,115,190, 2,106,174,128, 75, 84, 35,190, +136, 93,184,200,220,119,231,134, 99,160,133,177, 84, 78,222, 91,119,178, 81,169,199,182,164, 66, 98,219,225,237,146, 44, 48,250, +121, 74,184,189, 32,169,189,191,193,220,217,193,121,179, 46,212,193,254,251, 86, 38,110,182,216,203,171,254,253, 48,111,183,131, +122,147,230, 30,198, 64, 22,191,215, 22, 59,169, 99, 90,179,109,235, 47,159,215,159,214,139, 87, 77,170, 62,140,203, 84, 32,121, +253,121,222, 61,119, 15, 85, 33, 43, 61,225,195,240,255,142, 17,249,233,176, 99, 23,245,180,128,147,233, 26,178,198,204,148,161, +212,105, 48,241,241,135,186, 33, 3,169,222,168,111, 95,191,247,230, 24, 15, 72, 75, 61,184, 93,247, 24, 99,125,226, 81,195, 20, + 75, 22, 84,151, 9,153, 90,213,151,219, 43, 86, 93,103,172,138,182,250,199,207, 95, 55, 55,191, 73,158, 27, 90,103,163,120,189, +103,231, 55, 10,175, 84,143, 79,190,160, 24,142,158,114,228, 85,128, 41,135,162,158,133,183,215, 5,119,146,199,184, 28, 92, 81, +122, 6,220, 65,102,110, 71, 96,181,176,145,165,153,134,193,239,135,206, 56,191,172,150,117,211,196,143,182, 40,119,163,102,234, + 57,151,143,183, 94,111,175,192, 12,167,243,103,146,186,194, 72,147, 6,255,144, 22, 94,101, 19,213,191,143,239,161, 56,159,146, +253,131,128,130,152,118, 49, 66,196,231, 64, 96, 54,130, 70,131,179, 34,192, 48,116, 72,232,208,155,152, 36, 32,120,121,159,147, +247,178, 58, 30,194, 36,227, 88, 20,162,253,137, 90,162,252,168,153, 52,187, 95,206, 85,210,229,200, 83, 45,130,123,152,243,223, +240,252,171, 25, 93, 34, 41,149,142, 40,105, 58, 84,230,160,108,183,169,206, 27,177,106,128, 67,169,208, 82,132,239, 10,107, 41, + 50,151, 3,241,141,104,100, 13,220, 44, 77, 81,231,200,174, 21,148, 26,111, 98,110,237,148, 10,199, 65,244,111,225,184, 15, 47, + 90,168,149,104,165,200, 98,181,167,237, 72,254, 9, 64,221,149,181, 56, 17, 4,225,234,238, 57,122, 66, 68, 16, 23, 22, 87,196, + 7, 87,217,255,255, 55,244, 77,124, 19, 49, 32,235, 34, 43,230,154, 43,211,221,118, 85,117,205,225, 38, 63,192, 48, 15,129, 73, + 66,152,169,233,170,174,250,142, 89,127, 70, 9, 71, 54,169,233,226, 17, 11,234, 22,186,231,122,157, 36,155,113,117,203, 99, 60, +149, 56,222,153, 18, 39,223,137, 46,160,232,110, 97, 76,134,211,116,176, 42,199,200,166,239, 56,142, 87,159,202, 97,170,217, 51, +145, 1, 34, 61, 13,163, 43, 99,109, 22,143,202,154, 34, 94,164,248, 4,173,139, 50, 51,170, 69,154,128, 26, 51,126,252,176,205, +244,183,223, 27,212, 81, 30, 18,169,205,177, 38, 0,117,250,148,231,237,111, 80,139,161,203,130,164, 56,210, 70,216,101,129, 41, +198, 50, 88,215, 51,174, 80, 26,184,178,121, 34, 40,217, 12, 81,143,167,110,247,141,131, 28, 53, 83,212,137, 0, 52,143,231,128, +228,110,198, 21,202,102,158, 94, 67,122, 66, 2,139,182,139,247, 30,182,200,220, 76, 18,242,191,126,237, 2, 60,131,240, 26,224, + 65,100,109,214,148,240,226,117, 56,212,238,229,149,137, 85,248,221,117,181, 63, 14, 77,127,170,125,154,220,162,127,144,135, 23, +225,164,209,121, 16,198,174,198, 8, 84, 35, 48, 10,138,248,139, 3, 61,109,120, 5,210,166, 70, 45,232,212,170,195, 55, 85, 97, +223,223,220,125,250,250, 49,190,255,178,249,236, 37,241, 59, 44,219,137, 79,197,195,216, 9, 35,177,116, 17, 0,170,123, 73, 60, +152,161, 89,100, 78,169,110,223,221,190,125,115, 19, 51,135,106, 91,198,224,251,148, 84, 8, 3,152,148, 16, 19,153,144,218,238, +220,113, 8,101,110, 87,101, 44, 98,202,109,253,136,153,192, 13, 15,219, 95,198, 36,135,193,212,169, 16,196, 8,241, 55, 21, 76, +187, 24,166,110, 98,216,242,184, 49, 11,169, 90,231, 42,125,219,237,145,120, 2, 30, 9, 70, 26,122,100,176,106,242, 89,192,122, +248,126,123,159, 68,247,156,219, 13,141, 14, 22,207,184,206,255,112,240,193,184, 21, 9,103,202,130, 56,142, 88,189,100,110, 33, +177,211,169, 63, 16,126,198,250,166,246,174, 15,204, 99, 66, 12, 17,146,223,226,162, 78, 94, 17,248, 64,217, 60,111,250, 99, 72, +183, 70,114,103, 26,103, 94,138,113,181, 68,115,159,161,224,235, 75,219, 92, 5,151,202,122, 79, 66,128, 0,255,234,137, 79,218, +192, 50, 6, 16,240,226,164,180,110,230,139,238, 19,212,188, 26,117, 17,200,172,244,224,118,189,238, 42,179,118, 62,111,209,193, +163,163, 95,195, 37, 94,115, 7,132,102,123,132,171,137,203,102,167, 96,145,227,130, 96,199, 99,244, 54,254,224, 67,255,106,117, +189, 57,126, 63, 98,255, 18,227,101,128,161, 0,125,238,159, 44,230,200,127, 5, 96,238,106,122,155, 6,130,232,206,126,216,110, +156,224,208, 74,149,104,225, 16,137,123,213, 11,255,255, 14,247,246,208, 72, 28, 64, 2, 10, 74,101,133,184,254,216, 93,118,102, +118,157,164,177,212, 43,214, 30,156, 68,177, 44,199, 25,191,121,243,230,141,156, 42, 18,143,102, 23,158,102, 58,239, 56,117,146, +209,153,149,219, 89, 17,149,140,189, 61,108, 90,144, 1,202,156, 53,232, 92,209, 6, 42, 71,246, 60,227,150, 16, 45,101,161,179, + 51,147,151, 38, 47,100,166, 2,112, 80,212,179, 18,178,103,148,202, 20, 69,248, 28,248,171, 26,195,187, 14, 32,221,177,110,183, + 67, 41, 61,150,212, 10,109, 22, 89,118,183,185,175,251,154, 48,145,165, 17,125, 14, 68,170,132,251,189,254,157,248,211,180, 72, +217, 25,113,183,136,156, 37,202, 35, 61, 22,167,232,127,197,220,187, 2,230,231,233, 53,141,203,149,144, 12, 35,165, 63,144,142, +186,254,201,242,232,188,240,228,149,189,197,122, 85, 63,133,124, 33,197,250,140,118,114,218,105,211,213,239, 40,156, 53, 73, 89, +188,196,185,178,174,125,205,180,253,255,223,198, 59,239, 59, 21,117, 62, 21,250,166, 52, 55,115,179,154,235,183,134, 76,195,123, +191,125, 14,153,143, 60,175,138, 0,228,223, 24,201, 88, 99,108,208,237,112,104,134, 76,195,181, 64, 28, 81,164,110,102,102, 23, +139, 11,155,170,116,204, 50,243, 26, 34, 58, 65, 32,140, 3, 46,177,207,206,214,207,219,207,235, 47, 88,155,194, 84, 76, 41,242, + 37,163,158, 12,224, 70,153,171,229,149,135, 81, 85,125,132,220, 35,142, 4,255,167,126,172,202, 37, 51,174,225,200,187,182,121, +247,254,250,238,126,173,149,161,218,166,229,188,129,207,202, 71,184,126, 80, 76,140, 45,177,120, 71,182, 67,187,217,110,126,109, +127, 14,142, 1, 59,113,184, 86,240, 64, 34, 23,121, 21,239, 34,117, 29,165, 23,251,188, 36,206,140,181, 92,180, 28,162, 33, 7, +219, 15, 34,144,178,100,144,110,165,187, 93,221,146,231, 62, 54,254, 97, 83, 10, 75, 38,227, 67,144,246, 2, 74, 34,147, 71,247, +184, 25,214,113, 24, 64,159,150, 77,112,126,244, 61,221,171, 36, 67,164,121, 16,226,199, 55, 84, 81,180,168,107, 7,228, 74, 99, + 69, 12,128,156, 42,209,114,202, 54,168, 7, 63,188,164, 7, 50, 18,214,140,158, 88, 68, 76, 6,254,201,112,246,242, 93,152, 6, +239, 47,155, 81, 38,192,126,116, 84,190, 62,255, 32,246,161, 83,194, 9,215,122, 26,220,147,107, 2,147,236, 60,164, 51,164,134, + 77,109,127,239,252,147,130,144, 39,205, 43, 89, 45, 68,149,163,109,254, 25, 78,142, 17,170, 23, 93, 39, 26, 39, 7,141,253, 10, +224,197,177,190, 59, 61,205,195,137,125,253,251, 80, 22,229,106,241,241, 82, 94,206,208,247, 47,252, 4, 93, 43, 58,251, 90,144, +248, 39, 0,117,231,182,219, 52, 16,132,225, 61,186,177, 13,137,170,150, 11, 42,212, 62, 0,188, 61, 55,136,247, 64,189, 65,164, + 82, 15, 18, 80, 16,161,137, 15,233, 30,216,153,241,172,237, 40,226,190, 55,201, 85, 36,219,177,199,179,179,255,255,253,192, 23, + 3, 7,188,214,121,238,142,152, 71, 20,110,177,109, 48,253, 93,165,174,166,243, 56,136,215,193, 28,169, 72, 41, 58, 40, 94, 69, + 21,163,114, 32, 71,208,146, 93,227, 56, 94,212, 11,232,247, 11, 75, 30, 13, 24,222,128,235,136,112, 72, 5, 40, 32, 65, 97,153, +154,160,133,133, 22,190,178, 69,109,109,159,150,153, 70, 35,133, 20,158,137,116, 9, 74, 93,244, 97,119,187, 91, 55,190,193,251, +213,121,152, 26, 57,156,238, 5, 94,203,230,204, 23, 37,102,208,125, 78, 44, 33,249, 48,158,220, 0,153,149, 36, 63, 98,222, 44, + 23,247, 33,133,143, 93,106, 98, 34,135,212, 16,109,177,253, 30, 92,186, 40, 43,244,218, 47,141,252,235,252,195, 76, 90, 51,248, + 63, 45,127, 90, 86,145,103,178, 85,110,210, 45, 43,109, 46,140,126,242,254,241, 24,202,249,101, 21,119,197,180, 28,133,166,199, +206,133,203,165,249,112, 85,191,174,204,222,249, 90,203,247,151,103, 17,156,154,162,178,250,231,159,125,223,186, 38,181, 18, 92, +223,211, 15,223,106,191, 90,190,163,244,115,252, 31,137,194, 75,113, 23, 49,245,164, 77,191, 19,135, 30, 98,122,198,198,222,141, + 68,229,103,175,206,211,247,105,125,218,236,183,114, 48, 56,229, 97, 15,201,207,197,166,123,242, 33,240,248, 64,114,133,136,196, + 25,133,233, 12,205,101, 48, 26, 84,161,103,214, 40,123,179,254,246,233,243, 71, 99, 77, 7,122,121, 96,249, 58, 76, 67,167, 9, + 5, 1,138, 38, 70, 88,153,181, 52,168, 96,192,249, 62,199, 62,241,238,127,230, 68,146,163,107, 28, 45, 18, 35, 89,242,254,208, + 96,175,206, 64,193, 97,227, 48, 98, 24, 59,141, 98, 32,203,227,246,215, 29,197, 78,167,195, 47, 79,234,214,245,145,182,105,137, +239, 0,168,214, 19,101, 10, 91, 46,125,117,161,244, 27,115, 5,150, 69, 55,217,104,205,197,221,115, 71, 79, 37,242,249, 94,184, + 47,194,175,175,213,230,235,243,230,183,104,182, 1,102,149, 45, 38,164, 57,230,133, 16,217, 33, 78, 24,140, 81, 78,172,129, 98, + 80,194, 28,228, 19, 77,251,119, 57, 7,160,207,248,134,135,244, 94, 57, 74, 36,245,127,150, 6,199,114, 17, 60, 67,135,218,126, +139, 80,150,105,252,222, 81, 39, 84,148,226,128, 92, 34,199, 91, 47,230, 35, 9, 88,139,119, 93,108, 91,200, 51,238, 61,228,172, +182,132,128,167,205, 97, 52,249,207,234,186,156,191,120,210, 59,243,177,251, 97, 84,185, 42,210, 27, 98,145, 42, 42,174, 3,100, + 24, 55, 68,142,159,235, 63, 1,168,187,182,157,182,129, 32,186, 55, 59, 77,104, 8, 60,208,170, 18,226,153,255,255,137,126, 67, + 69,197, 19,138, 8, 36,160,160,166, 54,182,119,183,123,102,102,227, 77, 40, 18,175, 60, 70, 74, 34, 39,246,206,206,158, 57, 23, +247, 6,202, 18,103, 21, 35,156, 30,176, 79,250,216,190,248,237,169, 93, 80,103, 16,200, 64,208, 87, 90, 64, 31, 27, 13, 90,122, +116, 73, 16,142, 76,109,218,154,160,111, 4,163, 17,166, 37,232,228,233,219,112,207, 77, 85,243, 64,125,162,106,166, 51,167, 23, + 21,184, 16,169,202, 79,210,250,169, 93, 21,180,133, 60,218,185,129, 36, 27, 14, 42,246,190,143,205, 67,243,148,174,164, 7,239, +138, 9,239, 3,101,103, 19,244, 42, 99,105,137,213,166, 39, 95,120, 9, 58,167,120,240, 17,222,240, 48, 87,237,215, 84, 97, 8, +124, 32, 59,102,139, 72, 35,120,124,161, 16,139,148, 67,251,220, 55, 92,181, 29,232,252, 49,245,239,247,225, 56, 11,166,112,150, +144, 49,203, 73,198,106,116, 46,127, 54,243,205, 61,128,105,100,218,190, 32, 47,233, 19, 23,247, 61, 95,222, 21,167,218,157, 82, + 63, 55,221,175, 77, 55,179, 8,122,189,254, 54, 63, 59,173,119, 67,183,152,187,202,186,171,139,233,114,221,106, 28, 57, 35, 99, +244, 88,159, 6,220,108,203,200, 24,235,131,198,243,153, 30,217,191, 33,254,151,228,201, 86, 0, 44,106,222,252,121, 52,218,157, +185,122, 86,127,109,250, 93, 96, 53, 6,147,169,181,112, 55,210,251,102,147,105,186,227,127,219, 93,177, 40,228,137,192, 20,201, + 99,131,110,251,214, 56, 75,158,236,254,203,124,246,176, 94,165, 98,218,189,190,126, 63,255,113,187,252,237,105,120,233, 67, 6, +156,217, 41, 69,123, 97,138,101,143, 99, 60,248,184, 54, 82, 52,167,143, 88, 43,225,163, 81,154,184,160, 89,140,141, 71,155,236, + 54, 99, 58,105,122,204,169,104,146, 74,243, 88, 75,173,143,165,253,140, 11,125, 47, 6, 44,176, 90,231,246, 63,255, 85,176, 98, + 29,124,104,219, 78,139, 50,212,178,201,119, 4,131, 17,212, 84,184, 96,109,159,204,242, 89,173,207,135,203,241, 20,165, 10,102, +100, 41,159, 70,173,191, 81, 97,181, 84,219,149,106,218,212,137, 34, 82, 52,253,150, 33,251,170, 49, 14,197, 59,105,216,187,173, +137, 91,119, 12, 35,176, 30, 63,144, 66,147,225, 24,157,173, 87,162,201, 75,201,239,177,241,162,198,187,247,123,255, 80,152,164, +190,125, 3, 5,174,136,184,172,184, 36,173, 15, 34,250,120, 34,170,195, 17,101, 39,199, 35,141,114,170, 3,119,163, 88,112,240, +205, 33, 45,103,244,184,213,227,230, 97,178,241, 0,186,213,212,200,222, 53, 55,196,163,135, 87,247,128,230, 93, 16,148, 80,132, + 61, 28,245,133,255, 4,160,238,218,122, 26,132,161, 48, 45, 48, 96,211,105,162,137,137, 79,190,251,255,255,142,111, 62,168, 35, +139, 3, 39, 12,218,218,115, 43,133, 45,123,247,117, 25,201,202,224,235,233, 57,223, 37, 59,235, 34,145,120,155, 93, 58, 45,245, +254,148,223,113, 60,230, 52,219,116,155,194,135, 6,143, 84, 84,119,192,189, 6,207, 94, 96,185,128,249, 5,122,103,120,168, 78, +201,189,128,138,165,222,239, 7, 73, 94, 17, 95,145,163, 42, 93,231,108, 14, 38,131,128,203, 37, 36, 97,102, 21, 26, 28,156,172, + 45,210,236, 38, 47, 70,127,222,211,246,164,125,105,212, 66,168, 49,132,136,128,255,190, 95,234, 0, 20, 76,199,165,151,154, 8, + 45, 0,148,150,111, 35, 91, 41,187,192,137,228, 14,186,230, 84, 48,222,153,131, 4, 77, 12, 63, 21,201,141, 39,112,215,145, 47, +167, 70,123, 98, 3, 2,243, 28,241,218,255, 98, 36,111, 44,221,248,149,160, 91, 41, 97,243,133, 52,151, 49, 86, 16, 30,129,181, +144,220, 59,252,194,147,210,159, 88,188,255,107,112,143, 95,155,149, 0,125, 41, 82,222,202,232,231,109,249,250,242,112,232,129, +107,219,118,182,200,211,205,166,120,188,171,186,222,102,237,112, 76, 44,181,176,238,171,245, 97,248,165, 35,151, 75,196,130, 95, +207, 76, 60,221,196,164,152, 89, 49, 5,232, 71,132,135,203, 61,222,213, 77, 93,100, 43, 55,146,146, 84, 97,150, 29, 22, 27,252, + 38, 66,242,159,236,253,209,114,176, 16, 70, 77, 40, 20, 89, 96,104,101,212, 8, 62, 42,197, 79,211,228,171,220, 12,102, 63,212, +187, 67, 13,202, 22,235, 33, 14, 6,254,200,140, 68,211, 91, 8,228,145,198,185,150, 88, 32,197, 3, 29,129,120, 84,120,187, 32, +198, 83, 46,114,202,165,217,147, 65,242,177, 34,242, 3, 52,135, 52,123,233, 40, 49,165,214, 44,124,159,124,187,144,169,236,175, + 99,172,151,128, 59, 98, 9,225, 0, 3, 3, 41,140,213,227, 8, 41, 92,205, 62,169,119,238, 29,240,125,140, 90, 25,106, 62,110, +181,193,207,238,173, 79,190, 62,244,241,219,246, 39,232, 52,140,230, 54,201, 90, 88,141,225, 67,148,101, 30, 35,181,165, 22,149, +109, 48, 3,176, 60,222,188, 50,113,114,129, 79, 98, 46,139,181, 85,252,255,207, 92, 0,231,109,153, 40,170,240,202,179,235, 22, + 26,168,179, 70,141, 90,140,123,195,169,194, 73, 60,212,178,218, 72,162, 83, 86, 4,202, 65, 64, 29,115,199,137, 5, 43, 1, 74, + 49, 89, 73, 99,227,177,119, 51, 55, 99, 78, 46,188,184,160, 63, 1,152,187,150,228,166,129, 32, 58, 31, 73,182,113, 28, 39, 44, + 96,145,170, 28,129,251, 95,133, 19, 64,130,171,136, 13,182,132, 52, 51,141, 94,247,244,100,100, 10, 42, 75,188,151, 74, 37, 89, + 79,253,121,159,130,239, 73,193, 48,147,114,212,205, 39, 50, 81, 28,241, 27, 3,178,151,227,157,191,221, 80, 11,170, 98, 52,146, + 76, 45,123,204, 14,234, 58,150,111,107,215,199,121,144,124, 35, 96, 75,234, 37,147,208,105,220, 41, 89,191,243,110,203,177,174, + 93,211,108,154, 53,236,191, 29, 93,220,144, 58, 64,194,224, 71,156,184,113,241, 28,224,230,141,121,106,138,234,180,137,218, 2, + 66, 16,202, 70, 4,164,227, 42, 80, 93,184, 29, 76,172,113, 20,104,118, 69,131,154,115,180,115,130, 37,115,132,140,171,182,234, +206, 72,227,162, 91, 54, 86,130,147,179,175, 61, 14,205, 95,164, 83,232, 99, 81, 43,128,152,109,175,220,154,189,114, 69, 68,222, +205, 17,113,188, 95,117,218,243,102,127,145, 76,137,154,207,179,181,118,254, 90,124, 65, 81,246,134, 90,230,255,254, 57,157,164, +175, 52,159,228, 29,168,119, 8, 41,220,111, 87,159, 30,223,223,221,223,124, 62,124,223,128,207,146,154,134,186,174,189,191,233, +250,159,211,140, 18,109,140,107,107, 31,118,237,184,218,247,163,167, 44,117, 70,189,154,149, 43, 28,218,158,201,138,204,185,207, + 10,226,180,192, 7,158,186,113,227, 6, 16, 5,150,131, 16, 57,245,128, 83,140,245,163, 70, 70,136,120,146, 71, 4,214, 26,251, + 71, 18, 51,169, 61, 30, 8,237, 60, 35,151,247, 57,128, 45,246, 43,140, 1, 6,124,132,132, 34,120,115,128, 21, 19,120, 12, 27, + 24,192, 95, 35,128, 22,105,192,202,124,150,160, 75,167,174,153,185,126, 39, 53,234,192, 95,153,173,253, 4, 33, 19,251,237, 19, + 47,168, 37,251,143, 62,238, 63, 60, 29, 15, 62,123, 85,139,255,129,208, 16,193, 88, 6,239,221, 6,201, 96, 16,201,104, 33,255, +138,211,152,229,156,139, 38, 26, 63,198,230,114,246,167, 23, 58,196, 96,124,201, 48,138, 85, 33,159,106,196,159, 47,235,235, 55, +243,242,108,206, 71, 51,244, 54, 76, 38,132, 31,211, 37,133,144, 23,204,114,159,196,150,196,230,201, 87,126, 80,170,177,215, 66, +183,208,222, 23,196,149,180,152,165, 95,239, 87,255, 65,250,166, 37,219,199,214, 14, 45,244,215,249,126, 93, 35, 64,228,224,220, + 52,141,230,205, 47,227,210, 13,230,234, 32,170,221,128,139, 67,125,101,221, 78,173,109, 87,221, 26, 33,242,124,119,197,196,183, + 18,187,202,250, 48, 41,210, 23, 57, 85, 42, 67,174,219,245,110, 62,246, 56,156,234,171,250, 45, 0,115, 87,179,155, 54, 16,132, +103,108,175,193,118,164, 20, 18, 85,170,212, 7,232, 51, 84,125,251,168,143,144, 67,115,234, 37,149, 80, 83, 75,169,192, 6,214, +222,141,231, 15,219, 20,114, 46, 39, 31, 48, 32,172,157,253,118,230,251,201,230, 63, 78,184, 62, 81, 28,141,162,122,184,244,178, + 1,165, 72, 84,196, 58,214, 85, 90,149, 80,177, 62, 91,124,117, 8, 96,245,106,163,159, 49,203, 31,114,246, 58, 77,101,112, 25, + 37,241,146,154,239, 67,169,116, 72,209,169, 64, 54, 3, 46, 77, 51, 74,119,131,195,107, 95,135, 5, 25,184,228,108,252, 94, 22, + 55, 69, 85,174,238, 86, 79,143,143,100, 18, 78, 38,133, 65, 38,102,172,114,238,197,138,210, 92,195,212, 48, 28,163, 57, 75,112, +204,207,132, 39, 99,222, 29, 70, 16,210,104,142,228, 36, 90, 27,247,206, 83,142, 15, 55,149, 4, 26, 41,216, 79,232,120, 76,163, +225, 63,116,198, 39,244,237, 72,148, 69,158,247, 5,206, 64,235,194,144,123,193,116, 28,150, 33, 83,214,114, 74, 83, 23,250,244, +134,175, 61,243,213, 28,191,243, 99, 2,155, 62,180,239,176, 2,254,123,216, 30,255, 89, 54, 29, 31,113,128,254, 16,252,224,178, +219, 42,255,124,127,179, 94, 87,191, 94,155,109,227,189,199,172,195,204,245,197,194,125, 90, 47,186,237,209,123, 40, 49,174, 74, +215, 64,254,115,159, 39, 44,105, 81, 93, 73,192,147, 56, 99,128, 11, 95,191,124,251,254,227, 1, 76, 9, 29,103, 9,243,150, 2, + 20, 85, 76,130,154,204,102,180, 60, 53,219, 0, 49, 35, 84,222,132, 60,252,112,113, 61,115,121, 39,238,197, 0,108, 82,245,102, + 8,253,176, 4,142,157,200, 50, 3,201, 53,185,207, 45, 23, 76, 45, 15, 65,213, 61, 32,123,147,208,188,213, 71, 31,141,103, 35, + 60,180,225,173,153, 88, 13,227, 20,187, 89, 67, 67, 88, 12, 12,100, 80,187,217, 50, 68,104,253, 33,196,110, 68,158,209, 52, 83, +195, 41, 91, 20,223,226, 71, 72,197,193, 11,183, 7,116,184,128,149, 91, 50,239,157, 40,103,116,207,113, 7,127, 95,240,247,209, + 67, 17,141, 33, 19,230,156,200,177,191,177, 1,124,121,134, 93,157, 28,118,221,126, 7,195,179, 28, 78,212, 33,106,206, 85,156, + 16, 14,131,138,222,205, 84, 32, 41,150,203,182,221, 74, 26, 93,144,112,117,152,182,228, 47, 79, 83,241,122,249,188, 82,109,167, +136,248, 82,120,221,165, 91,148,211, 46,185,127,120, 70,206,141,147, 93,231,125,102,102, 60,243,236, 45, 92,217,248, 45,142,251, +214,108,173, 80, 14, 87,146, 90,113, 55,161,174, 57,183, 78, 52,255,227,198,167, 76, 41,251, 46,178,138,234, 90,195, 12,227,235, + 77, 0,222,174,100,183,109, 24,136,114, 72,138,150, 92,219, 41,156, 67,209, 94,210, 91, 17, 32, 95, 18,228,215,130, 2,253,167, +246,222, 91, 15, 69,128, 32,233,130,194, 49, 26, 43,146, 37, 75, 28,214, 51, 36,173, 37,201, 45,232,209, 7, 25, 90,103,134,143, +111,209,189,222, 70, 35,175, 12, 16,141,175,158, 33,101,212, 11,190,201, 38,140,159, 81,222,228, 37,108, 39, 42, 91,200,153,102, +229,118, 8, 70, 1,239, 88,167, 12,251,100, 88,231,243,152,132,214,236, 91, 45, 21,153,188, 19,236,161, 88,185,188, 91,213,247, + 5, 50,221, 86,203,253, 4,151,218,108,174, 23, 71,199,203, 15,167,167,231, 23,231, 39,103, 39, 87, 95,175, 62, 93,126, 92,253, +249, 69,193, 76, 2, 45,225, 66,241,229, 97, 71, 42,201,116,167,200, 96,242,139, 91,233, 2,157,102,224,235, 27,173, 86,227,246, +233, 33,205, 99,176,125, 58,122, 70,225, 16,223, 24, 92, 88,202,211,154,102,195,229,123,198, 55,184,180,194, 56, 55,209,144,245, +224,102,197,213, 31,216, 25, 62,229,232, 65,201,122,120, 5,100, 93, 97,232, 59,160,114,191,255,224, 12, 55,206, 4,224,214,138, + 7,210,184,254,111, 32,197,189,208, 95,201,206, 97,180, 35,229,250, 61,100, 96,202,127,214,226,204,225, 22,237,205,223,205,122, +215, 54, 72, 97, 78,182,109,139, 10,166,169, 62,158, 79,202,197,238,205, 52, 49, 42,185, 46,244,207, 13,111, 59,178,221,250,124, +242,154, 16,252,186,124,123,244,238,199,250, 6,152, 65,252,249,219, 23,146, 61, 75, 23,124,253,226, 87,231,250,204,183,195,154, + 57, 90,248,246, 38,233, 40,153, 60,112, 91,186,192,215, 94, 22,140,232,196,148,232,167, 81, 69,180, 71,244,182,118, 90,185,136, +180, 51, 38, 35,188,143,105,144, 20, 69,243, 27,223,176, 85, 8,115,226, 22,226,177,111, 16,135,149, 7, 72,136,210, 29, 12,254, +190, 72, 83, 92, 16,246,171, 48,215, 99,132, 87, 56, 67,134,218,222, 42,191,227, 57, 68, 36,202, 52, 54, 72,180, 48,248,164,209, +175,105,250,234, 97, 91,176,186,156, 85, 66, 4,221,107, 98, 36, 40, 73, 87,195,166,250,208, 84,203,187,124, 86,213, 75, 40,170, +247,237,247,184,123,148,244,140,104,154,161,138, 85,253, 22, 38, 95,111,171,123, 81,151,184,171,217,228,156,252, 88, 3, 65, 20, + 59,161,107, 4, 94, 48,160,201,176, 95,224,180,232,145, 47, 23,113,109, 55,130, 23, 32, 70,197,249,195,159,100,186,143,253,100, +134, 85,122,132, 6,141,222,115, 28,185,255, 75, 74, 50,232,217,180,120,250,213,128,109, 73,103,155,153,116,127,246, 13, 91,166, + 63,211, 36, 70, 17,169, 97,217,230, 65, 58,143, 25, 27,169, 26,162,200, 65, 47,124,143,204, 1,224,169, 58,228,186, 66,111, 71, +232, 16,136, 65, 94, 85,221,182,238,209,109,250, 39, 0,111,103,204,219, 54, 12, 68, 97,145, 34, 41, 43, 78, 16, 27, 69,129,174, +201, 18, 52, 91,183,238,253,243, 29,138,246,111, 36,118,108,184,173, 45, 81,180,196, 43,239,120,100,168, 38, 40,138, 14,245,160, +145,144, 44,137, 60, 29,191,247, 30,231,243, 41, 42,119,115,135, 58,201,167,242,185,250, 88,131, 67, 1, 36,185,112, 99,195,187, + 9, 54, 10,160, 80,184, 93, 73, 85, 27,231,189, 17, 26, 13, 12,164,194,234, 94,106,132,115,136, 83,177,112,126, 26,246,155,126, +187,113,219,157,221,246,211, 9, 51, 6,101, 76,147,167,122, 97, 26,123,219,119,221,241,253,253,253,237,199,155, 55,205,250,212, +217,195,247,195,224,200, 66,122, 12, 63, 71,159,191, 72,188,113, 33,150,222, 98,159, 54, 69,147, 35, 15,150, 45,192,222, 60,130, +160,151, 28,199,204,168,140, 18,209,184, 35, 90,122,196,142,123,157,164, 77,156,129,156,141,250,136,155,132,112, 45,199,243,105, + 51,218,150, 2, 84, 13,173, 23, 22,247, 34,144, 68,222, 97, 31,149, 27,205,215, 36, 93,208,244,153, 99,140,188,208, 82, 83,214, + 14,229, 83, 83, 88, 40,246,134,125,171,132, 6,185,159,252,211,127,244, 36, 16,105,109, 47,219,150,179, 88,128,127,154,223,171, + 2,155,201,227,251,103, 54, 20,208, 19,180, 70, 97,245,113,112,248,225, 94, 99,250,156, 86, 98,185, 80,151, 11,125, 85,139, 1, +154,207, 15,114,107, 37,111,105,225,255, 90, 55,234,226,100,143,161, 52,254,105,127,136,164,140,163,123,140,107,128, 86, 77,120, + 36,226, 14, 74,126,218, 33, 33, 18,220,188,203,134,123,153,179,137,192, 99,242, 47,100,204,220, 51, 1,189, 94,174,172,115, 69, +248,118,154, 21,124,230,109,162,104, 40, 42,121, 72,223,134,199, 8, 37, 82,240, 47, 99,195, 69, 10, 68,114,139,202,203, 17,123, +194,166, 13,126,214, 78,231,216,144, 42,209, 91,130,211,197,216,173,154,141, 20,240,176, 90,174,194,200, 14,227,145, 61, 37, 31, + 84,153,207,155,144,152,199,211, 49,152, 0,222,145, 23, 3, 55,134,194,203,104, 84,115,217, 94,185, 80, 53, 73,181, 16,245, 7, +185,190, 85,239,160, 50,230,124,238,222,222, 61,126,106, 33, 73,243,178, 80, 89, 22,114, 39,188,152,175,149,250,246,197,218, 93, +213,239,125,127,240, 67, 15,206,194,232,136,143,164, 69,193,243,140, 49,111,173, 80, 34,196,196,230,131, 80,206,113,233, 81,242, +101,178,104,225,151, 5,226,185, 41, 51, 31, 22,254, 92,164,252, 54,179,195, 11,224, 38,178, 72,121,137, 17,105, 11,127,166, 20, +134,234,186, 93, 57,140, 27, 28,197, 44,202,237,149,145, 35,129,154, 99, 2, 17, 58, 34, 11, 94,145, 80,175,169, 36,108,254,226, +245, 74, 59,200,162,140, 34,121,209,234,121,101,168, 95, 2,240,118, 37, 59, 13,195, 64,212, 75,156, 46, 20, 16,156,248, 8,126, + 30,144, 42,190,129, 63,224,196, 1,209, 3, 75, 27,154,110,105, 98, 15,158, 25,219, 73, 74,133,224,194, 61,109, 26,215,241, 44, +111,153,172, 23,118,128,222,185, 84, 61, 98, 68,113,192,174,229,252,119, 17, 98,131,135, 19,230,206,152, 93, 84, 77,189,183, 5, +157,158,216, 97,215, 26, 27,131,171, 38, 71, 17,173, 82,196,211,194,157, 81,185,218, 98,219,208, 41,166, 77, 18,104, 73,186, 39, +127, 69,237, 67,122,230,136, 58,233,239,216,192,108,246,124,119,115,123, 63,157,126,124,204,215,235,101,185, 41,201, 63,154,222, + 10, 31, 68, 44, 67,109,105, 96,146, 32,215, 7,136,222, 13, 36, 47,232,208,170, 84,226, 16, 48,217, 76,209,152, 8,201, 84,119, + 96,210,171,130, 80,215, 56,121, 40, 79, 75,238, 99, 84, 53,248,199, 83, 11,116,220, 22,148,173, 75,131,112, 54, 87, 88,112,238, + 31, 31,169, 97,173, 27,193, 88,171,201, 0,237,176,124, 1, 51, 50,208,144, 85,224, 8, 77,204,157,246,137,186, 1, 99,205,216, +194, 99,213,188,255,111, 23, 5, 34, 95,115, 23, 69, 88,166,227, 32,102,251, 61,162,223,131, 1, 92,184,232,142, 75,193, 54, 44, + 84, 56, 87, 75, 31,159,215,106,226,154, 44,167,190, 92,173, 70,198,161,103,131,116,167,131,236,225, 69, 63,205, 73,126,141, 27, + 3,225,122,218,134,174,220, 20, 52,248, 69,182,248,152, 12,178, 77, 64, 35, 71, 83,161, 60, 85, 49, 44,206,156, 13,209,101, 35, + 64,244,148, 35,150,109,131, 50,189,148,151, 71, 46,121, 95,238, 98,204, 80,169,165,128,228,198, 33,226,252, 14, 56,201,206,124, +176, 65,225, 4,105,212, 32,118,130, 40,103,181,244, 85, 54,142, 31,138,163,195, 68,192,161,100,148,204, 80,226,172,193,181,241, +227,184, 32, 37,124, 74, 7, 81, 29, 59,142, 97, 63,158, 61,200, 96,190, 90,164, 18,211,165, 95, 25, 6, 99,112, 29, 33,138,117, + 1,193,240,148,189,135,113,161,208, 18,126, 91,106, 61,244, 87, 93,231, 87, 23,217,228,117, 83,236,242, 26,106,181, 95,149,141, +184,244, 91, 1,242,158,132,181,157,119,197,118,183,111,203,202,126, 74,191,242,117,229,136,238, 16,103,181, 49, 49,137, 12, 71, +228, 17,170, 10,203,127, 82,251,152,211,248, 78,206, 30,207, 68, 68, 14, 66, 55, 8,218,158, 5, 28,201,222,225,247, 39,251,241, + 90,221,177,207, 99,143,130,249, 13,159, 21, 98,185, 45, 34,189,238, 16,222, 21, 45, 97, 38,180,206,122,206,137,180,101,135, 58, +223,218,138,110,247,215,254,235, 33,118,218, 5,138,127, 98, 71, 10,241, 37, 0,111, 87,178,211, 48, 12, 68,189, 36,105, 83, 10, +226,194, 17,241,255, 95,194, 47, 32,132, 4, 18, 2,169,128, 80,171, 82,234,198,177,141,103,177,227, 4, 4,136, 3,189, 85, 85, +183,140, 51,235,155,247,170,156,189, 37,133,169,144,232,137, 37,143, 35, 28,118, 46,137,150,148,154,101,208, 96,135,179,169, 97, +240,232, 9, 42, 4,152, 48,229,129,140, 91, 72, 43, 13,220,154, 61,105,102, 14,154, 41, 72, 36, 1, 11, 73, 4, 82, 68,149, 98, +141,232,121,237, 92, 3,248, 0, 21, 98,233,214, 54,237,245,237,213,225,221,192,134,170, 3,245,142,222,117,214,198, 10,166, 3, + 65,152, 64,107, 31,161,212, 54, 10, 12, 9,102,236,145, 47,210, 73, 18, 58,163, 36, 29,191, 81, 49,201, 42, 9, 92, 38, 42, 96, + 50, 23, 47,168,203, 97,234,205,225,193, 51,180, 45, 70,182,103,223,145,232, 65, 29,109,166,130, 5,165, 52,176,216,137, 6,197, + 16,155,102,170,139, 74,206, 26, 16, 58, 58,154,145,254,179, 56,105, 32,121, 55,224, 4,228,124, 46,218, 16,238,159,204,205,254, +255,156,123,118, 31,117,250,145,203,244, 84, 39,224,249,161, 16,125,213, 5,143,216,111,194, 70,126, 99,159, 38, 16,203,132, 84, +235, 73, 61,220,122,175,251,232,175,150, 72,169,214,202,190,209, 42,154,215,116,246,242, 97,119,247, 26,234,154, 41, 46,114,142, + 66,169,128, 99, 82,163,209, 33, 7,185, 15,204, 91, 75,180,100, 81,224, 15,186,242,138,101, 32,100,214,246, 16, 25, 68,144,210, +246, 98,248, 18, 86,235,149,202,119,178, 31, 13,208,218,217, 98, 99, 54,176, 18,146,228, 31,104,177,133,217,109, 8,171,139,114, +207, 89, 70, 54,196,218, 60, 84,169,156,166, 99, 39, 39,224, 11,149,161,152,137, 43, 55,121,122, 73,172,150, 49,239,130,184, 11, +116,143, 26, 14,170,194,213, 41,193, 84, 80,236, 74,104,154,140,175, 84, 85, 99,236, 65,229,209, 94,130,171, 16,236, 18,106, 87, + 80,190,241,231,245,241, 89,125,250,248,246,210,225,111, 48, 59,107,119,235, 94, 92, 40, 55,236,172, 78,186,222, 14, 57,129,228, +118,171,220, 94, 56,131, 12, 54, 61,201,162, 80,219, 42, 99,127,184, 81, 44, 71,126, 42, 3, 72, 44,178, 48, 50,109, 28, 67,224, +113,223, 29,155, 84,201,128,114,176,103,200,193,130, 81, 55,133, 28,246,247,143,145,103,199, 38,181,159,156, 94,140,227, 95,110, +167, 18, 89,163,144,159, 64,240,126,250,249,194, 49, 69, 90,233,142,115, 81, 16,116,221,196,203,245, 55,198,145,226, 66,132,178, +200,246, 63,253,247, 15, 1, 72, 59,159,222,132, 97, 24,138,215, 73,128,178,162, 29,166,221,216,113,223,255,235,236,178,105, 55, + 54,105, 82,217, 6,165,165,109,146,213,118,210, 36, 45,251, 35, 13,113, 64, 72, 32, 68,133,121,182, 95,126, 79,197,175, 7,207, +183,231,235, 35, 2, 52,216, 58,154,169, 71,114,241, 72,133, 79, 37,128, 99,197, 3,147,175,249, 25,154,132, 83,250,140, 21, 81, +208, 8, 93, 24, 76,212,118,115, 32, 57,116, 1,154,244, 44,126, 94,180,237,162,151, 92,169,114,255, 38,105,125,139, 12, 58,131, + 39, 16,113, 56,163,123, 67,245,221, 37,103,251, 48, 67,239,235, 12, 37, 94,122,165,224,250, 96, 24,131,205, 28,194, 27,192,101, +172,129, 13, 1,171,174, 12, 72,118, 31,139,104,214, 69, 93, 13, 17,254,106, 90, 79,111,176,190, 99, 7, 93, 25,194,213, 91, 68, + 43,229,185, 42, 90,168, 72,179, 45, 73,111,174, 21,228, 67, 39,140,192, 52, 78,131, 0,132,217,103, 98, 13,246, 80, 54, 15,187, +211,179, 54,205, 37, 55,164,138,194,249,254,127, 83,254,125,164, 31,149, 72,127, 95, 82,217,109,105, 91, 80, 80, 81, 30,231, 42, +205,143,186, 32,139, 88, 99, 38, 21,158, 34, 10, 23, 28,193,194,218, 95,148, 86,247,178, 83, 71,209, 99,117,110,224, 12,250,118, +248, 34,235,190,172, 50,220,192,227, 14,148, 81, 66, 73, 5,148,228,126,159, 43, 93, 37, 84,177, 42,246,186,229, 36, 1,240,240, + 42,152,104, 28,247,200, 12,127,174, 2,198,245, 86,144,237,169, 48, 20, 0,137,159, 34,132,162,217,236,245,125,103,177,201,164, +109,175,225,188, 80,195, 28, 49,150, 1, 25, 25,128, 33,104, 43,215,254,198,199,100, 60,100, 44, 26,134, 49, 58,152, 60, 97,249, + 98, 37,164, 28, 26, 99, 90, 8, 19,230,136,116, 9,201,112, 34, 51, 80,196, 50, 57,147,199,217,133,179, 15,185,189, 32,192,245, +213,166,222, 87, 26,196,132,184,231, 26,139, 12,184, 24,223, 23,219,247,174, 42,235, 79, 28, 28,246, 6,154,230, 68, 37, 1, 73, + 35,154,127,150,233, 42,144, 81,182,131, 22,248, 56,224, 57,141,161,178,119, 29, 5,113,106,232, 17, 26, 75, 88, 4,147, 86,183, +212,188,103,220, 98,245,238,102,187, 90,230, 79, 47,143,124, 56,198, 19,146, 67, 89, 79,160, 67,102,204,179, 8, 17, 28,246,247, +217,204,244, 31,198,207, 42, 46,220, 86,139,245,185,107,230, 18,158, 59, 8, 26,208, 59,210,251,172, 75, 0,223, 84,234,232,235, +178,147, 5,253, 49,117,182,152,239, 79,216,206,117,250,124,213,108,254,230,162,254, 18,128,180,115,219, 73, 24, 8,194,112,103, + 89, 10,229,144,160, 55,222,249,254,143,164,183,106,140, 24,130, 17,180,212, 30,118,236,156,150,150,214, 24, 35, 15, 64,104,179, +204,238,206,252,255,247,251,243,251,179, 88, 19, 20,252,133,173, 12, 60,143, 33,130, 92,152, 57,113, 41,206, 30,133,198,234,130, +164, 26,114,134,153, 6, 88,203, 30,124,193, 72,224,178, 28, 36, 65,195, 81,188,147,243, 46,168, 13,139, 89,104, 14,234,252,192, + 77,241,137,140,141, 9, 84, 84, 19,171,154,204, 35,168,180, 36,118, 33,152, 90, 70,133,152,120,177,205,154, 77,201, 76,171,104, +249, 12,224, 72,167, 47,184, 86, 55, 57,215,119,137, 89,160, 3, 82, 29, 89, 78,102, 25,164, 39,105,171,244, 71,149,175, 89,238, +194,128,105,136,179, 68,134,107,192,173, 79,143,245,151,231,138,118, 40,131, 75,125,150, 38,243,153, 95,103,211,205,210, 47, 82, +223,148, 97,187, 59,221, 63, 28,239,138,106, 55,214, 50,243,182,209,186, 14,122,247,255,103,246,218,208, 55, 83,110,152,144,176, +135, 18, 60,233, 96,178,118,232,137, 7, 71,150,180,207,146,235, 62, 63,124,106, 62,117,111,174,197,225, 60,182, 27,127, 51, 25, +172, 75,176,157, 67, 26, 86,237, 70, 50, 7,156,242, 5,189,106,160,168, 67,153, 80, 42,202,161, 0, 63,135,155,141,127,217,209, + 72,162,225,210, 3, 61,169,174,242,208,237,101, 27, 63,131,187,221,146,161, 65,206,186, 32,130, 47,250, 39,198, 19, 45,246, 14, + 57,186, 72,250, 34, 57,252,245, 82,108,232, 49,100, 57, 15,136,218, 32, 40,151, 92,217, 94,137,242,179,206, 72, 21, 48,247, 44, +152,243,133, 33, 50, 17, 5,213, 89,168,150,133,125,181,188,174, 67, 85, 20,133,227, 40, 4,210, 71,154,151,150,193,186, 78,104, +226, 19,254,187,114, 60,103, 84,141,203,226,165, 2,179,202, 86,135,252,253,121,191,181,161,156,235,249, 65, 21,192,222,222,182, +155,246,224, 49,115,243,183,252,181,106,239,199, 88, 82,195,168,200,203, 69,170, 15, 46,125, 24,175, 99, 65,249, 34,198,211,242, +157,224,152,135,166,162,230, 12, 18, 61,132,221,141, 68,239,150, 1, 47, 74, 68,185,222,107,130,208,114,236,152,171,121, 42, 79, +251, 71,173, 40,138,116,199,177, 22, 10,170,132, 20, 53, 11,219, 14,239,161,139, 17, 78,126,152,193,226, 88, 55,166,233,235,152, +227,231, 84,157,220,176, 61, 38, 3,122,192, 44, 93,145, 61, 66,227,156, 35, 71, 22, 76,121, 69, 6, 24,136, 82,221,145, 26, 13, + 67, 97, 15,142,133,187, 95,254,128, 1,111, 60,252,197, 31,243, 45, 0,105, 87,178,211, 48, 12, 68,109, 39,221,145,160,136, 59, + 66,226,255, 63, 9, 46, 8, 85,130,162,148,226,180,113,108, 15,158,197,169,187, 32,129,232,161,135, 30,186, 68, 29,103,230,205, + 91, 10,126,164,152, 34,131, 57, 77,177,144, 54, 46,224,223, 43, 71, 69, 82,216, 2, 93, 95,147, 26,240,244,191, 50, 3,157,156, +196, 23, 90,112, 75,163, 10,173,247,208,107, 84, 64,233, 86, 94, 87, 21,226,248,134,149, 26,100,188,137, 86,192,121, 5, 42,235, + 32, 37, 6,120,104,113, 22,153,147, 31,100,134,101,226,166, 65,177,147,196,114, 28,124,153, 9,200,171, 36, 74,150, 49,119, 62, +220, 41, 84, 77,218,119,105,225, 17, 98, 65,165, 71, 32,150, 51,168, 90, 38,100, 33, 91, 10, 85, 55,125,196,196,181, 55, 36, 52, +141,178,244,146,241,172,131,248,238,252,227,108,210,108,251, 53,245, 61, 29,168,198,186, 57,132,169,130,221,206,239,214,122,181, +117, 47,155,238, 53,115, 18, 76,145,139,116,142, 24,142, 50,172,241,207, 46,190,202,166, 55,124,231,184, 85,234,186,102, 11, 68, + 61, 31,225,250,120, 15,105,206, 48, 11,114,123,243, 65,245, 30,246,125,216, 58, 24,108,238,246, 66,112, 20,160, 6,142,238,212, + 71,101, 83, 23,252, 10,190, 61,196,108, 27,121, 69,103,189, 37, 27,196,218,227, 18, 98,140,153, 1,245, 24,213, 17,176,105,195, +114,209, 27,206,234, 30,192,194, 60, 33, 28,124,133,142,246,157,154, 66,233, 56, 28,140,248,136,236, 28, 36,240, 11,243,101,212, + 41,246,114,177, 75, 42, 37, 83,240, 67,228, 54, 70,135,233,152, 39,196, 32, 73, 55,194,189,201, 89,157, 32,254,182,116, 43, 18, +241,183, 46, 43, 28, 74, 92,151,149,213,195,158, 53, 61,111,108, 99,216, 48, 91, 31,192,210, 92,155,134, 65, 31, 93,226, 79,192, + 87, 94, 20,255,236,100,214,124, 53, 66, 13,206,254,228, 89,167, 69, 6, 74,149, 80, 54,211,219, 45,170, 89,235,221,199,222,246, +161,183,206, 58,191, 90,250,153,183, 40,223,133, 57, 23,179,108, 9, 35,168, 44, 53, 33,171,216,168,188,253,132,224,198,169, 18, +131,182, 88,126,248,154, 88, 17, 4, 73,224,224,145,253,254,238,225,249,237,105, 90, 79,218,116, 62,178,190,138, 42,178, 98,255, + 31, 37, 91,110, 85, 56,121, 29,166,174, 56, 80, 5, 65,159, 55,239,199,237,196,239,203,228,188, 83,209,151, 68, 81, 80,204, 17, +184,116, 41, 78,195,233,104,220,245, 29,127,231,244, 67, 82, 35,215,246,219,242,112,199,236,248,200, 59,204, 83, 32, 19, 10, 27, +203,242,148, 47, 56, 61, 23, 86,175,127, 61,217,249,241, 45, 0,105, 87,178,211, 48, 12, 68,227, 37,132,210, 5, 33,129,248, 2, + 46,252,255,119,112,224, 3, 16, 2,113,107, 5, 74,218,102,243,130,103, 60,227, 56, 85, 37, 4, 72, 61,244, 80,181, 74, 19, 63, +143,103,222,162,103, 87,235,217,169,158,127, 64,206,160, 57,151, 77,161,199, 54, 13, 66,224, 11, 12,234,234, 0,143, 44, 10,242, + 98,135, 94,122,198,119,155, 90, 38, 18,170, 12,176, 30,192,177, 70, 18,116,168,248,236, 27,103, 49,121, 12,152,243,113, 18, 64, + 78, 74, 46,137,242,224, 94, 91,239,179,117, 8, 52,122,104,114, 78, 99, 17,124,114,116, 84,252,197,242,136, 90,237,128,238,144, +171, 1, 47,141,109, 79,234,199,123, 52, 74, 8,219,135,140,178, 64,128,140,216,170,138,203, 80, 2, 53, 78,172,150, 55,227, 97, +167, 49,111,179,199,191, 38, 0,241, 32,138,123,184,157,102,244, 23,143,139,213, 83, 91, 71,203,176,176, 27,189,236,237,184,111, + 7, 14, 57,210,248,121,193, 29, 24,149, 87,164,153,144, 35,233, 74,226, 39,199,127, 84,238,201,253, 38,188,191, 21,226,186,244, +189,144, 99, 33, 42, 37, 22,165, 44,117,184,145,178,210,190, 43,228, 74,139, 5,196, 49,187, 59,173,143,157,219, 30,204, 87, 11, +227,241,142,149,183,197, 79, 58,242, 52,162,138,212, 11,197,166,240,138, 99,252, 96,226, 10,141, 93,223,132, 50, 93,234, 37,244, +150,193,121,179, 44,237,177, 18,101, 37,186,174,178, 54,146,210, 37, 97,187, 77, 49,216, 42,167, 19,196,101, 0, 14,133,236, 2, + 77, 43,135,124, 77,125, 30, 15,118, 30,220, 9,121, 49,204,154,123, 76,232,136,193,167,133, 68,219,192,128,208, 36,126,178,140, +233,137,123,227,104,172,230, 19,247, 98, 90,145, 42, 25,226,251,169,120,167,125,210,171, 25,208,112, 30,100, 50,213,193,201, 23, +105, 92, 33,205, 88, 57, 14, 4, 98,125, 62,185,166, 58, 65,108,255,137, 88,130,133,191,156,194, 43, 40,243, 2, 26, 56, 64,206, +177, 96,102, 32,225, 89,135,157,216,143,198,185,214, 12,199,207,143,117, 91,155, 26, 92,221,139, 13, 28,244, 68, 74, 42,194,171, +210,170,232,195, 77, 11,103,177,102,251,112,185,121,222,189,143, 67,141,140, 81, 76, 10,177,104,111,150,104,166,120, 26,126,219, +190, 66,117,108, 58,146,178, 98, 23, 41, 67, 82,204,207, 66,135,247, 9,100, 24,204,248,244,197,220, 25,218,178, 79,138,119,225, +127,185, 40, 78, 58,138,231,235,230, 25,221, 82,156,176,239, 17,220,233, 60, 2,195,229,177,113, 89,142, 18,166, 17,158, 61,123, +251, 74, 93,117,182, 69,231, 72,119, 50,190,202,209,124, 89,173, 15,125,147,115,219,254,166,137,249, 22,128,179, 43,217,105, 24, + 6,162, 94, 40,105,105,161, 82,132,250, 15,252,255,127,240, 1, 72, 92,185,176,137, 2, 77, 66, 60, 54,158,205,117,155, 34, 4, +183,222, 26, 39,246,140,103,230, 45,103,245,170,248,173, 65, 53, 36,134,163, 65, 66,213,230,183,123,225, 52, 57,114, 81,124,110, +172, 83, 50,118,190,214, 75, 81,205,197,181, 99,205, 15,138,168,116, 85,139, 66, 82,162,173,128,107, 70,112, 0,154,111,123, 0, +153,134,241,104,133, 42, 97,206,243, 34,254, 90,196,175, 89, 26,210,231, 59,247,158, 53, 76, 7,213, 36, 83,121,168, 82,139,198, +210, 69,222, 16,157, 64,208,146, 57,145,208, 25,180,164,239,129,211, 91, 54,115, 72, 81, 2, 20,217,233,106,139,223, 47,174,219, +240,182,197,254,171, 59,183,216,126, 4, 98, 86,230,164, 1, 96,159,251,225,166, 93,247, 97,121, 63,238,168,172, 68, 30, 83,175, + 24,193,166,210,105,114, 85,160,156,169, 50,159,215, 24, 54,211, 91,240,255, 90, 52, 5,173,200, 3,207,134,122, 50, 75,231, 54, +141, 13,206,181,200, 45, 51, 91,200,117,181, 9, 72, 73, 73, 67,178,237, 28, 97,115,232, 17,209,204, 86, 11,191,190, 0,188,177, +165, 49,199, 99,171,242,197,126, 82,222, 30,253, 99,217,142,190,250,193,250, 4,160, 3,216, 25,125,152, 49,218, 97,228,150,171, + 33, 19, 34,243,177, 29,214, 87,177,235,252,229, 98,179,251,122,135, 99, 37,125,119,138,246, 34, 83, 34, 65, 25,231,239, 25, 76, +250,205,179, 76, 90, 2,116, 4,121,112,150,180, 70, 51,188,105,131, 97,109, 24,169, 63, 89, 77, 70,189,111,180, 95, 98,196,105, +174,248, 85, 76,130,140, 21, 19, 54,155, 42,193, 28, 37, 23,201,158, 76,220, 6,197,141, 56,237,178,234, 90, 36,113, 41,215,147, +245, 56, 28, 3, 1,146,102,150, 3,203,233, 3,100,136,200,153,113,154, 35, 77,218,136, 36, 21,139, 1,125, 64,252, 91, 12, 61, +161,143,153, 10,149,250,207,248,128,215, 19,155,163,252, 28,133,162,144, 62,235,228,117,135,209,192,139,137, 79, 57,196, 63,222, +190,222,193,216,161, 86, 8, 22,214,140,184, 7,246, 73,149, 7,138,201, 9, 57,198, 21,205,200,138, 75, 40,171, 82,105,251,138, +227, 20, 75,129, 88,211,247, 99, 82, 23,139,233,108,243, 79,167,195,159,134,153, 11,125,110, 10,157, 73,167,123,119,118, 95, 60, + 85, 9,160, 32,211,235,231, 44, 48,144, 30,118, 21,132,230,199, 39,239, 80, 0, 37, 71,249,213, 24,114, 57, 29,254, 77,120,252, + 22,128,178,107,219, 73, 24, 8,162, 59,219, 34, 69,130, 81,131,193, 23,249, 4,255,255, 95,124,225, 69,141, 18,141,114,181,117, + 47,118,110,203, 22, 81,145,164, 9,225,129,150,101, 59,157, 57, 51,231,156, 14,127, 21,204,126, 71,254,208,211, 13,164,159,211, +101,136, 41,180, 22,152, 3,168,232, 53, 59,213,114, 79, 7, 89, 23,212,230,164, 33, 3,150, 92,103, 17,165,128,104, 59,201,157, +162,166,183, 35,215, 29, 66,236, 52,141,162, 30, 7,147,221,108,224, 79,229, 32,130,134,248,213,239,149, 94, 34, 29, 19, 85,139, + 79, 93, 59,172,216, 53, 1, 1, 65,166, 20,183, 44,148, 9,107,207, 63, 40,171,109,179, 13, 98,242, 64, 61,172,224, 19, 25, 5, + 13, 4,135,215,189,229, 19,245, 92,241,104,247,215,200, 82, 82, 99,224,195,249,187,197,250,118, 60,178,115,243,236, 26, 84, 70, + 53, 97,153,105, 34,110,232, 77,165, 17,147,113, 12, 14,247, 85, 86,130,165,153, 19,251,255,138, 44,237,179, 62,181, 76,121, 60, +113, 84,246,206, 75,232, 19,150,234,189,127,111,224,181, 13,237,180, 80,189,194,244, 45,108,154,130,230,208,139,139, 33,174,207, +104,216,191, 33, 91,221, 34,108,109, 29,239,181,218,240, 42,117,233,191,229, 60,169,177,233,119,194, 79,242, 60,112,202,132,100, +112,191,118,237, 51, 47, 86,224,171, 96,150, 14, 35, 40, 49, 9, 76,111,224, 38,151,245,195,252, 13,197, 73, 41, 89,140,201,220, + 2, 58,186, 50, 57,208, 25,187, 12, 22, 30,144, 84,169,244,253,245, 35,188,141, 71,179,117,119,118,235, 39,129,218,163, 60, 57, + 80, 5, 3, 96, 58,158,206, 94,102, 32,128,100, 74, 36, 85, 66, 36, 36,178, 61,228,231, 81, 77,140, 68,188,210,233, 72, 14,231, + 73,200,154, 10, 14, 27, 59,151, 64, 89, 3,133, 99, 22,131, 68, 58, 54, 14, 97, 25, 1,126,128, 6,105, 98,162,124,250, 36,219, +181, 27, 39,225, 38,177,116,212, 50,252, 23, 25,129,104, 85, 91,158,172,220,250,147,124, 71,106, 18, 15,230,159,226,183,171,248, +136, 27,212,175, 76,168,208,187,167,253,219, 88, 7,144, 56,176,166,216,152, 48, 55,208,172, 44, 14, 62,180, 55, 7,230,175, 68, + 3,224,118,179, 23,179,115,149,111,147, 88, 18, 83,139, 44,100,110, 33, 33,238,156,108, 98,174,203,188,179,187,150, 5,246, 9, +153,201,204, 81,205, 17,193, 29,254, 24, 72,209,215,213,217,100,190,120,202, 80,111,248,125, 20, 71,175, 48,238, 43, 70,106,112, +119,217, 87,200, 61, 94,156,214,126,243, 83,173,144,143,199,240,174, 70,209,252,120,216,231,231,200,200,240, 37, 0,101, 87,178, +155, 48, 12, 68,109, 19,160, 72,180,160,194, 1,169,234,165,234,177,255,255, 49, 61,112,105, 15, 84,137, 4, 82, 18, 26, 39, 94, +154,153,177, 29,187,132, 46,156, 33, 10, 16,143,199,111,222, 18,248, 51,148, 71,202,163,198,252, 7,220, 63, 78, 64, 24, 14,178, +129,116,194,135,128, 67, 27,146,206,252, 48, 2,122, 97,176, 73, 36,107,111,114,105,164, 51,151,197,134, 74, 3,149,222,165,218, + 43,206,227, 20, 66, 50,123,242, 41, 36,174,100, 27, 79,244,185, 68,211, 60,190, 25, 54, 0,180,126,156, 64, 50, 20,160, 74,128, +195,103, 78, 94, 5,243, 86, 20, 39,130,139, 59, 66,255,132, 55, 18,230, 41,158,119, 79,251,143, 87,202, 53,158,205, 86,221,164, +128,205,192, 0,200,219,225,113,147,147,217,136, 16,167,166,221,151,159, 47,187,245,225, 88,231,231,166,178,122,197, 76,203,140, +116,182, 33,238, 78, 9,159,105, 35, 59, 73, 17, 33,218,161,103,239,254,201, 64,103,145, 36,131,104, 60,119,128, 4,138,205, 76, +100, 25,108,145,109,103,106,165, 91, 28,145, 85,164, 75,196,204,195,123,169,182, 83,118,150,122, 41,108,169,193,214,101,187, 94, +128,252,168,179, 71,217, 76,241, 55,150,145, 66,253,218,216,202,140,176,199,220, 23, 68, 77, 28,155,227,147,115,131, 7,189,190, +126, 47,176,231, 43, 27, 64,225,231,156,173,110, 85,145,181,141,202, 40,105, 90, 89,182, 89,110, 78,213,137,166,139, 81,145, 10, +251,185, 53, 99,167,235,240, 76,130,110,211,196,107,154,132, 28, 46,202,135,251,219, 52, 99,235,204,105,160,172,201,171,220, 33, + 30, 3, 37, 35,225, 54, 98,217, 18,209,122,224, 78,118,225,160,164,137, 87, 80,115, 36,242,227,121, 85,248,201, 16, 75,200, 52, +222,170,202, 98, 52, 6, 72, 59,250,139, 63,110, 31,222,138,119, 76, 35,232,151,142,240,191,182,181, 9, 70,228,152,239,161, 87, + 23, 62,137,210,175, 86, 84,241, 96,102, 16,130,222,186,129,143,244,253, 59,105,178, 12,161, 78, 70,214, 58,135, 80, 49, 28,136, + 3,161, 13,198, 28,153, 83, 97,130, 3, 84,201,120, 81,202,250,160, 91,165,181, 52, 96,136,172,209,126, 95, 33,139,136,145, 85, + 61,143,124,154, 35,103,243, 0,233, 71,132, 28,158, 98,204, 35,197,221,229,103, 80,226,104, 84,239,126, 73,112,226,201,104,115, +184,158, 97,130, 95,240, 42,251,226,158, 98, 50,118,140, 77, 31,254, 37, 98, 15, 14, 54, 50,223,104, 51,151,119, 6,241,109, 73, +113,143,223, 63,156, 55,121, 2,213, 91,123,125,131,250,203,235, 75, 0,202,174,166,167, 97, 24,134,218, 73,199, 54, 16,159, 18, +147, 16, 39, 46,227,200,145,255,207,223, 64,226,136,208,196,132,246, 65,187, 37,105, 77, 18, 59,105,198, 24,130,222,167,118, 77, +237,196,207,126,239, 49,127,149, 9,205,136,189, 58, 31, 30,126,101,135,238, 88, 30,130,240,187, 50, 16, 47, 89, 58,133,117,210, +115,237,126,218,192,216,219,172,101,192,135, 21,196, 18, 99,101, 23, 72, 77, 56,101, 30, 39,206, 74,217,192,163, 6, 36,210, 2, + 66, 13, 68, 21,229,112, 98, 3, 43, 82, 85,181, 48, 84,149,216, 67,161, 20,146,121,117, 84, 18, 34,243, 33, 96,141,241, 69,173, +142, 10,146,174,173, 7, 16, 92,176,163,114, 36, 54,196,178,152, 49,122,129,230,198,157, 84,234,254,250, 44, 12,252,185, 48, 12, +234,111, 48, 10,245,129, 12,158, 67, 1,194,100, 61,146,204,252,196,162,173,154,135,168,240,128,183,192,254, 53, 72,239,252, 18, + 96, 2,234,106, 80,157,141,245, 72,211,218, 65,109,187, 55,211,190, 16,188,199,246,192, 80,154, 1,170, 1, 90, 0,204, 90, 88, + 89,170,108,232, 97,223,158, 86,147,139, 99,173,245,251,194,190,125,110, 93,209,219,105,255,185,205, 64,162, 83,141, 18, 46,207, +147,151, 71,161,114,162, 35,197, 68,226,132, 77,251, 26, 98,172, 62, 86, 21,187,170,116,177, 47, 98, 3,247, 15,123, 96, 19,178, + 97, 70, 86,253,239,235, 97, 14, 20,202,130,112, 37, 78,131, 34, 74,144, 26,182,253,222,128,244, 13,163,199,140,151,248, 71, 48, +214, 33, 82,153,174,138, 32, 17,248, 79,113,240, 36, 7, 25,113,241, 21,121,140,226, 56, 2,210, 1,138,244, 84,141,133, 89,118, +210,124, 79,190,192,189, 90,124,120,180,173,179,211,219,233,124, 57, 15,250,121,217,103, 74,168, 85,217,250, 99, 39,103,229,156, +234,255,230,249,241, 69, 23,116, 1, 28, 8, 85,156, 67,139, 6,161, 17,163,150,155, 85, 32, 41,249,111,220,214,195,155, 7,123, +247, 8,235,134, 54, 58,216, 10,109, 2, 22,239,207,242,190,246, 84, 53,152, 37,184, 69,221,205, 94,219,231, 39,107,155,174,169, +157,107,192,248, 95, 27,150,141,228, 17,120, 76,154, 15, 5, 74,158,176, 92,164, 29,215, 67, 44,206,224, 88,140, 81,255,124,106, + 46, 73,172,127,160,125, 74,219, 85,137,220, 55,230,181,192, 94,210, 98, 47,117,252,129,199, 39,213, 18,237, 38,247, 82,244,224, +144, 57,137, 46, 84,195, 66,180,234,106, 92,141,109,103, 56, 83, 13,245,168, 37, 71,191, 23, 26,255,185,190, 4,160,236, 76,118, + 26,134,129, 48,108, 79,210, 37, 45,136,125,145, 16,136, 19, 18,219, 1, 9,241,254, 79,192, 67, 32,122,160,108, 5, 74,200, 98, +103,176,199,107, 2, 69,165,135, 30,162,170,170, 26,251,119, 60,254,231,251,173,190,123,139,112,195, 22,173, 24, 93,233,231,139, + 15, 37,126, 83,249,200, 74,199,227, 26,126, 92,222,242, 0, 60, 50,154,153,185,216, 24,193, 7,127,122,212, 26, 15,230, 78, 65, +107, 62, 64,240,131, 25, 83,188,159, 69,224,178, 59,208, 20,223,149,192,167, 38,135,158, 39, 55, 39,215,147,231, 9, 80,104, 67, + 99, 75,252,214, 53,170, 46,214,162, 50, 84, 50,228,212,182,139, 18,100, 94,211,246, 50, 69, 34, 49, 19, 56,140, 80,127,160,222, +103, 95,117, 41,229,233,206,218,225,198, 56, 75, 19,117,203,212,164,236, 33, 97,213, 72,235,201,105,206, 19,119,220,218,143,224, + 30,157,142, 18,248,207,195, 59,184, 83,205, 17, 99, 91, 74,226,147,164, 55,128, 97, 10,111,181,154,131,242, 94,200, 7,194, 42, +156,103,131,203,205,193,241,122,118,180,218, 63,219, 24, 94,172,102, 87,227,108, 75,194, 84,212, 19,161,158,221,228, 8,224,120, +127,180,185,146,125,205,138,167,183,106, 74,155, 15,136,200,124,203,187, 20,252, 48, 21, 81, 25, 71,219,237,185,182,238,232,178, +152,110,157,208, 41, 95, 82, 7,117,177,181,113,250,248,158,218,156, 13, 6,186, 62,236, 12,188,216,138,204,116,206, 93,180,192, +116,157,207,219,214, 14,252,169,239,210, 56,116, 66,216, 38, 98,107,126,178, 54,125, 16, 89, 60,230, 26,214, 5, 87,217,173, 36, + 4,241, 8, 50, 17, 56, 23, 65,220, 13,232, 75,207, 56,226, 98, 83,194, 30,119, 76,140,144, 26, 25, 99,110,245,197, 74, 86,234, + 15,120,249,124, 97, 22,148,106,123,192,108,223, 44, 67, 23, 24,101,158,143, 26, 83,122,226,190,128,128,106,167, 95, 8,106, 79, + 33,143,141,173,252,147,141, 30,247,250,219, 31, 85,158,203,162,148,181, 20, 69,182,123, 89, 30,156,242,124,174,153, 79,234,191, + 87,139,127,169, 15,217,121,206, 89,142,197,251,107, 51,159,241,233,157,188,187, 21, 85,222,212,115, 44, 11, 29,198,172, 9, 43, + 2,121, 20,124, 27,119, 30, 5, 56,164,169,182,135, 1,139,110,143,207, 58, 4,247,214,195,187,175, 10,176,216,243,254, 55,149, +128, 91,226, 32,120,214, 8,215, 12,149,196,173,207, 93,137, 95, 78,217, 3, 62, 1, 23, 52,151, 46, 20,196,182,141,202,191, 4, + 5, 90,152, 15, 11, 20,113,208,199,176, 55,162, 69,188,137,191,118, 60, 88, 81,227, 97,201,223,253, 45, 0,101,231,179,218, 54, + 16,132,241,221, 89,201,150, 34,199,193,165, 1,135, 30,139, 15,189,247, 5, 10,125,255, 67,161, 15, 80,218, 38, 14,196,166, 77, + 99,201,187,210,206, 84,251, 87, 43,169, 9,169,241,193, 24, 12, 43,175,119,172,153,249,230,247, 9,107,141,237, 92, 28,135, 91, +197,127, 46, 56,132,126,224, 47,158,101, 62,111, 64, 39,205,103, 8,150,186,140, 39,116,124, 72, 71,143, 93,105, 52,234,195,112, +212,232,229,145, 9, 9,137, 59,135,181,237,112, 39, 13, 98, 3, 62, 78, 57,129,131,188, 59, 69,150,119,109, 98, 86, 8,207,132, + 63,156,164,111, 15,119,166, 81, 43,132, 70,132,160,136,116,181,251,116,111,150, 89,174,117,255,247,208,229,248,136,150, 55, 32, + 9,165,173, 38,181,140, 75,203,117,202,140,190,128,246, 82,125, 63,158,218, 14,183,171,242,221,213,106,187, 42,174, 22,139, 10, +178, 21, 65, 70, 80,152, 66, 62,207,163,237,170,189,171,237, 18,175,143,168, 56,212, 51,114,222,115,183,201, 44,201, 3,222,154, +248, 46, 54, 69, 94, 45,243,167,150,246,141,122, 64,188, 99,236, 99,177,252,244,126, 35, 42,174,179,126,181, 88,107,170,173, 38, + 73,228,176,187, 94,127,126,179,249,114,248,253,147,216,101, 71,187,237,250,102, 83,238,239, 79,223,142,231, 71,155,175,227, 76, + 34,249, 63, 7,195,107,129, 68,200, 96,140,182,199,154,153, 46, 4,244,207,101,110,188, 28,251,140,167,200,197,241, 36, 76,169, +204, 71, 2, 39, 13, 25, 23,224, 83,255,107, 23, 78, 44,210, 36,224, 79,121, 82, 95, 73,227, 59, 77,134,164,156,231, 42,114, 62, +181, 69,155, 93, 38, 78, 83,118,167,110, 31, 4, 69,105,184,231,222,170,221,107, 31, 99,112,231,228, 99, 57, 64,144,117,177,216, +254, 15,182, 76, 67,205, 19, 35,168,198, 58, 38,120, 63,178,254,122,138, 69,169,109, 32, 72,204,255,220, 11, 61,174, 33,152,183, + 47,203,117,109,168,200, 22, 34,207,252, 96, 40,243,228, 74,222,160,186,200,202,254, 59, 83,157, 50,216, 44,148,213,245,135,246, +102,199,154, 39,214,106, 82,103, 99, 61,212, 52, 40,207, 32,165,172,127,117,245,129,213,127,244,195, 15,125,255, 21, 85,255,233, + 51, 42,163,127, 39,173, 44, 44,179,139,139, 98,193, 8, 23, 61,152,129,134,150, 42,139, 91, 74, 33, 89, 10,243, 95, 48,130,217, +210,152, 75,250, 66,113, 70, 79, 19, 92,240,118, 1,129, 58,197, 29, 78, 16, 2,220, 34,204,188,167, 74,119,124,190,238, 30,192, + 56, 56,214, 86, 78,104,198,195,207,171, 18, 23, 45,181,243,163, 58, 57, 61, 20,178, 77,154, 49,100,204,166, 11, 51,193, 63,201, + 87, 50,200, 58,199,199,126,197,227,175, 0,156, 93,205,110,219, 48, 12, 22, 37, 71, 49,218, 96, 67,129, 98,167,237, 41, 6, 12, +216, 99,244, 89,251, 32, 29,176,123,111, 5, 6, 20,205,146,174, 73, 99,203, 34, 75, 82,146, 35, 59, 93, 81, 52,200,193, 39,195, +182, 8,138,164,190,159,166,126,188,154, 52,104, 95,213, 71, 86, 85, 26,204,179,198,211, 68, 79,165,121, 45,199, 84,217, 51, 35, +145,243,210, 50, 22,213,124,213,185, 19,229, 84, 81,236, 48,170, 48,137, 10, 84,201,130,194, 69,110,205, 36,110,160, 27,111,140, + 73, 10,124,160, 66,164, 34, 44, 38,202, 19,172, 69, 62,254, 74,194,221,229,194,230,108,160,246, 55, 58, 35, 20, 88,113, 3, 73, +135,198,101,242,133,134,129,179,205,186, 91,123,113, 16, 92, 73,205, 35, 30, 56, 41, 99, 32,130, 7,153, 37,200, 59, 44, 85,209, +102, 47,161, 45, 76,121,155,132,180, 52,221,255,163,248,107,179,189,217,108,189,177,151,203,229, 69, 35, 24,244,214,203,150,250, + 60, 32,196,208, 41,100,136,166,112,245, 52,177, 81, 18,184, 9, 83, 96,172, 45, 27, 0, 78,131,190, 78,253,177,160, 86, 90,206, +155, 11,215, 17,173,187,184, 37,228,202,253,187,247, 87, 63,191,253,126,248, 27,131, 17,167, 76,145,174,148,247,231, 13,237,241, +192,237,245,126,245,105,245,195,159, 95,247,187,208, 97,235,220,115,103,255, 60,134, 93, 5,245,250,176,241, 72, 83,189, 90, 91, + 90,110,254,123,245, 16,224, 85, 57, 4,241, 30,254,236,205,153,231, 11,174, 99,154,172,136, 84, 25, 94,211,104,248, 6,197,182, +169,116,117,164, 96,172, 36, 77,164, 35,246, 84,243,100, 81,192,233,211,103, 22, 18, 39,247,179,246, 60, 12, 65,188,107,104, 38, + 86, 5,179, 42,108, 26, 93,213,183, 31, 33, 50,101, 11,129, 99,231,112,180, 4, 58,218, 61, 86, 67,128, 35, 29, 30,211, 89,178, + 30,236, 66, 70, 12, 91,165,242, 66,141,145,118,121, 88,163,112,200,196,155,157, 36,247, 88,163,237, 71,222,153, 91, 80, 18,142, +167, 2, 84,144,122,206, 18,234,105, 55,216,219,221,221, 87,255,101,233,124,231,250, 1, 28, 87,229,180, 89, 35,246,224, 15, 92, +138,152,133,183,142, 3, 23,130,165, 94,128,148, 79,200, 97,187,189,231,180, 62,112, 87, 17,130, 16, 15, 57,240, 99,106, 36, 12, +141, 92, 37, 67,177,170,199,102,179, 0, 33, 37,230, 15,109,211,169, 92,154,128, 65,129,117,226,127, 80, 3,240, 90,169, 67, 21, +237, 5,230, 80,153,220, 62, 97, 68,191,104, 7,148, 78, 8,138,212,254,184,160, 5, 29, 48,242,149, 78,203, 41,132, 57,156,134, +234,217, 78,253,200,124,199,167,184,151,130,198,218, 1,209,190,181,109,188,213,139,244,161, 63,173,163, 15,130,205,123,239,239, + 69, 0,218,174, 37, 39,129, 32,136,118,247,124, 0, 13, 24,195, 13, 76, 76, 92,120, 6,247,186,242, 16,222,210,196,196,149, 71, +112,225, 5, 80, 80,144,225,215,204,116,183, 93, 85,253, 27,134,184, 49, 46,217, 0, 19,232,170, 87,175, 95,189,151,183,247, 15, + 99, 11,209,199,102,127, 19,175, 79, 25, 25,211,116, 91,128,112,117,223,248,219, 90, 39,149,116,191, 55,169, 39,157, 23,128,103, + 76,105, 8, 81, 60,169,242, 20,138,205,105, 67, 10, 5, 5, 44,243, 7,194, 80, 19,112, 68, 42,137, 34, 28,194,131, 63,178,208, +190, 22,192,123,101, 65,204,144,184, 47, 9, 74,167,196,133, 99,244, 22, 18,153,243, 14, 4, 45, 52,114,190,250,229,253,117, 94, +111, 47, 71,236,250,252, 98, 45,135,196,146,215,141, 68,139,133, 28, 18,125,208,243,126,207,180,157, 98, 37,192,118, 67,120,252, + 27,117,217, 37, 38,117,216,202,177,134,135, 85, 83, 89, 91,192, 44, 73, 47,239,181,240,228,202,146,238, 56,152,228,101,186, 67, +196, 59,188, 65,170, 9, 15,224,133, 42,251, 25, 92,171,242,158,200, 6, 69, 94,237,154, 93, 3, 14,112,246,227, 30,110,174, 38, +188, 66, 15, 52, 32, 42, 4,142, 80, 53,136,222,180, 61,192, 27,105,222,102,203,121, 3,160, 99, 92, 22,101,222, 91,172,155,106, +167,195,174,255, 95,188,139,181, 63,126, 52,166, 12,201,183,128,252, 82,189,167, 93, 14,173, 84,156, 20, 33,121, 19, 3, 92, 92, + 21, 19, 94,255,199, 18, 3, 25,111, 48,200, 61, 92,244,132,141,227, 47,184, 78, 26, 0, 42,161,156, 67, 8,201,195,249, 74,174, +220, 26, 78,226,116,152, 30, 55,209,145, 61,114, 22,171, 22,239,222,186,121,208, 19,185,149, 32, 7, 0,149,140, 56,140, 79,166, +122,236,252, 11,104,209,207,187,165,115, 87,229, 93, 2, 8,157, 1, 44,236,155,122,229, 90, 90,100,130,149,223,114,106,143,255, +198,204,150, 31, 49,197, 45,134, 90,195, 98,146, 81,117,150,243, 29,107,166,106, 49, 46, 79,165,253, 35,219,130,174,164,169,190, + 44,248, 48,229, 70,231, 37,122, 68,245, 41, 70, 77,233, 61,171,145,141,169, 62,149, 5,236,251, 26,236,127, 20, 36,132,163,110, +147, 84, 60, 38,236, 97,117,185,242,244,126, 60, 13, 60,202, 4, 87, 97,247, 11, 53, 67, 34,213,112,252,170, 85,244,147,142, 62, +210, 72, 40, 23, 3,191, 75,191, 63,186,189,187,127,126,122,156, 47, 38, 68,198, 35,240, 59, 64,223, 58,252,238, 16,212,102,154, +131,178,204,219,118, 68,166,133, 28, 34,120, 47,179,130, 65,130, 35, 93,100, 35, 33, 89, 12,182,118,138, 98,252,232, 99,252, 95, +152,207,143, 0,172, 93, 77, 79,194, 64, 16,221, 15,176, 96, 0,245, 96,226, 95,240, 55,120, 49, 30,252,255, 87,227, 93, 19, 48, + 32,208, 66,161,221, 25,119,103,118,182,203, 71, 36, 38,146, 13, 33,229,208,210,148,217,153, 55,111,222, 51,231,206,129, 39, 75, +122, 91, 39, 9,227,225,226,104,238,200, 98,169, 27,254, 74, 82,244,188,179,187,172, 51, 38,242,219, 14, 83,211,204,101, 93,163, +224,227, 33,205, 51, 57,168,146,214, 61, 2,116,197, 32, 38,160, 46,250,128, 80, 11, 63, 38,128, 24,237,231,217,138,129,223, 1, +163, 92, 55,241,204,130, 41, 3, 47,160,171,217, 52,155, 69, 80, 37, 84,239, 43,213, 31, 76, 93, 64, 34,153,244, 73,123, 24, 90, +206, 55,252, 22,215, 35,166,205,128, 56,125,170, 27,234,193, 29, 69,118, 29, 98,153,190, 33,159, 28, 39, 5, 38,146,122,240,152, + 12,155, 88,129, 43, 17, 34,217,180,126,255, 43,156,103,178, 60, 5, 78,192, 98, 19, 7, 86,237,248, 42,144,251,247,142, 16, 84, +165,158,134,215,119,247,253,143, 69,181,217, 1,231,137,117,131, 59,226, 77,248,210,218, 39, 99,208,186,217,122,251,230, 11,118, +165, 30, 31, 38,163, 97,177, 92,213, 77,221,180,255,241, 8, 98,150,174, 94,101,211, 94, 45, 89,245,250,219,230, 88,186, 19,131, +138, 9, 56,171,187, 70,141, 22,245,109, 96,207, 37,154,104,142,132, 15,255,185, 37,225,116,136,243,111, 42,202,174,243, 67, 36, +176, 95, 68,168, 33, 65, 58, 41, 85,103,245, 93,121,222,130,243, 34,166,133,142,178,210, 36, 51,121, 52,139,148, 97,178,210,157, + 51, 54, 87, 90, 22, 68, 93,192, 37,211,209,217, 65, 38, 74,169, 56, 21,157,196,214,117,188, 79,246,239,139,218,245,137,254, 24, +118, 37,167,251,182,152, 12,111,249,168,236,122, 90,199, 61, 10,115, 47,189, 32,201,106,248,239, 7,228,102, 66,222,129,129,241, + 27,202,183, 70, 1, 41, 27, 55,223,110,251,217,150,214,244,181,237,129,171,161,156,171,106, 97,170,149, 45,151,166, 92,181,213, +172,222, 78,155,106,142,229, 28,214, 95,254, 91,220,206,131,219, 42,139,117,251,236,136,201,145, 73, 91, 44,222, 1,192, 67, 79, + 13, 19,123, 99, 90,180, 18,140, 0,210, 52, 3,128, 70, 39,231, 60,125, 18,158,178,164,243, 40,225,165,223,126, 25, 56,180,214, + 62,191,188,142,198,227, 99,157,186, 46,115,207,185, 27,134,102, 24,245, 81, 28, 60, 27,220,177,131,145,229, 92,166,224,109,191, +141, 83, 58,106, 88,140, 18,193,198,215, 67,168, 46, 67,255,103, 66,240,223, 95, 63, 2,208,118, 45, 57, 13,195, 64, 52,227, 56, + 85, 74, 75, 65, 72,172, 88, 32,113, 9, 22,156,137, 3, 32,113, 88, 96, 27,209, 31, 77,243,113,237,193,158,177, 29,167,180, 18, + 18,162,203,170,170,210,198, 25,191, 25,191,143, 60,185,141,192,233, 77, 19,126,211,164,139,240, 51, 40,159, 32, 74, 27, 32,229, +215,103, 30,165, 64, 8, 96,242,113,148,113,166, 5,225,166,187,249, 19, 80,252,112,116,131,160, 22,152, 68,125,129, 96, 16, 78, +201,192,183,119,225, 82,153,158, 67, 10, 64,233, 89,249,174, 34, 48,255,217,173, 72,222,179,181,183,237, 99,111, 65,134, 79, 83, + 57,125,154,223,110,235,234, 3,179, 89, 6,181,116,249,195,114,160,196,217,213,152,219,117, 45, 69,214, 40,147,211,164, 41,152, +130, 33,159,145, 78,130, 71,163, 8,127, 26,121,191,192, 44,207, 23,165,180, 37,181,234, 85,163, 7, 27, 47,117,102, 51,135,227, +213, 60,176,203, 33, 41,232,145,217,194,246, 97, 45, 37, 32, 82,201,179,205,179,187, 99,247, 55, 23,111,159,219,174, 83, 78, 57, +198, 34, 46, 10,123, 0, 23, 57,132,246,163, 59,133,239,141,170,178,236, 81,200,135,187,107, 11, 61, 86,203,214,117,225, 73,106, +135,249, 67,125,135, 36, 88,220, 83, 66, 73,224,182,160, 51,199, 89, 1, 36,255,119,125,145,210,185, 24,123, 6,176,242,158,185, +240, 38,132,110, 33,166,148, 42, 15,198, 56, 8, 46,213,111,176, 77,209, 85,121, 89,119,117, 72,102,136, 76,235,240,221,236, 83, + 59, 58,239,135,129,153, 67, 19,122, 31,219,234,199,134,134, 65, 53,250,137, 92, 90,116, 96, 28, 9, 22,245,183,148,159,131,131, +192,218, 48,167,150,158, 2,224, 54, 68, 28, 72, 83, 42,144,237, 12,227, 44,211,141,163, 60,247,195,118,143,157,234,122,139,178, +189,158,150,177,139, 15,185,210,193,153,103, 52, 84,128,129,174,143,131,198,203,130,114,103, 41, 64, 99,132,188,150,186,215,186, +204, 39, 5, 20,186,171,105, 47,208, 7,145,245,210,160,148, 7,142,163,178,200,221,144,201,251,126,107,156, 45,112,143,110,100, +207,130, 2,139,203,180,193, 52,153, 40,157, 54,255, 72, 87, 37,151, 32,222, 98, 57, 55, 71,184, 12, 56, 17, 33, 60,103,146,195, + 89, 66,160, 73,202, 81, 68,238,246, 42, 89, 35,144,208, 98,130,205,114,187,255,122,125,121,222,108,214,172,152, 25, 31,233, 28, + 95,161,133, 18,173,214,112,190,125,192,227,183, 70, 79,109, 67, 13, 86,250, 90,238,170,184,241,207,139,249, 90,175,146, 99,116, +252, 63, 8,255, 45, 0,105,103,211,148, 48, 12,132,225,221, 52,210, 34,138,122,115,116, 70, 61,249, 87,252,255, 71,143,234,193, +131,142,194, 80,160, 31, 73,214,100, 55,161, 45, 21,199, 81,224,194,199,161, 12,237,178, 31,239,190,143,254, 54,160, 31,160,100, +253,234, 24, 92, 34,225,254, 42,202,203, 9,219,215,212, 39,243, 40,231,227,122,196, 51, 88,169,224, 35, 25,129,121,241, 52,154, +192, 32, 67,230, 17,247, 85, 98, 18, 14, 45, 47, 88,133, 86, 24,251,135,217,174, 86, 69,142,243,108, 79, 69,226,214,193,121, 61, +224,233,217,205,249,197,237,117,189,121, 91,249, 31,187,208,104,187, 36,206,217,134,183,148,248,224, 85,197,100, 28,177,216, 21, +232,246, 7, 11, 16,129,133, 34, 16,177,218, 52, 7,117, 53,203,213, 68,189,151,205, 83,219,110,135,254,171,120, 88, 83,165,210, +199,112, 52,116,234,167,243,147,244, 86,193, 13,144, 83,157, 21,153,158, 97, 76, 87, 22, 85,253,248,242,185,174,154,109, 77,219, +176,175, 8, 71, 66,109, 54,164, 9, 55,181,125,109,237, 19,192, 29,192,195,253,229,244,100, 74, 77,181, 90,173,151,100,203, 36, +217,252, 39,245,123,215, 98, 50,124,132,254,145, 35, 30,171,240,240,247,105,166, 74, 95,106, 56,156,135,221,101, 12, 77,227,148, +141,202,100, 80, 2, 34, 19,168, 83,199, 89,130,163, 27, 98,150,160,227, 34, 69,124, 16,139, 30,196, 6,157, 18, 40, 33, 46, 77, + 11,108, 33, 38, 5, 18, 22,251, 21,116,152,219, 83,183, 77,149, 28,248,118,157,118,164,189, 73, 85,226,111, 0,140, 41,110,209, +152, 21, 99,203, 72,118,172,226, 74,106,210, 0, 4, 36,135, 63, 13,141,226, 40, 15, 73,253, 18,237, 51,164, 20,225, 17,237,110, + 26,213,193,203,118,193,221, 82,154, 3,144,128,137,157,224,173,113,240,199,199, 79, 76,168, 68,131,239, 82,166,192,180,186, 48, +243, 73,173, 74, 40,159, 65,105,255,154,203,114, 48,156, 3,136,254,210,182,206,108,125, 88,135,106, 97,218, 42,120, 28,152, 80, +247, 69, 11,205,110, 1,215,237,205,162,199,150,141,233,234, 83,121,145,111,170,141,180,220,131,229, 44, 90,250,238, 90,112,208, +115, 57, 30,234,208,113,176,232,159, 26,181,194, 99,100, 49,190,140, 84,253,183, 92,151, 75,173, 99, 1,213,219,189, 23,149,220, + 88, 28, 69, 63,180,203,127,208, 47,226,112, 48,160, 6,157, 87, 94,106,177,141,142,126,168, 17, 79,152,146, 39,162,195,137,221, + 31, 50, 42,127,251, 18,128,180,115,235, 73, 24, 8,162,240,206,182,150,226,237,201, 40, 70,253, 71,254,124,159,125, 49,132,152, +104,140,168, 80,186,237,174,157,219,238, 86, 81, 48, 62,146, 66,128,164,153,238,204,156,243,157,156, 15, 28,236,246,128,168,221, +189,196,248, 61,225, 15, 85, 94,137,118,220, 31,201,166,195,112,158,157,161,186, 30,100,163,105, 33, 36, 94,113, 74, 70,140,140, + 55, 44,210, 4, 53, 24,213,117,229, 55,139, 47,148,156,221,192, 49,197,108,177, 35,173, 36,191,128, 49,141,175,195, 73, 52, 42, + 30, 58,116,138,116, 8,190, 9,148, 55, 47,207,219,146,249, 39,199,165,129,214,178,194,100, 67,151, 74,101, 52,182, 58,107, 30, +126,155, 51,112,117, 84, 87, 19,123,255,186,122, 32, 44,112,175, 16,177,126, 15, 7, 19,140,219,180,124, 49,223,233, 20,126,170, +158,169, 37,137,223,173,239, 79,171,233, 69,125, 48,111, 96,110,194,221,243,219,117,183, 30,142, 55,235,161,154, 99, 47, 18, 90, +148, 31,226,131,116,217,154, 5, 61,144,206,141,185,189,185,156,205, 78,134,178,185,120,124,127,125,105, 86,228,185,117,255, 46, +238, 38,203,117,146, 86, 3, 99,120,109, 77,154,153, 67,107,156,135,210,194,217,164,108, 29, 5, 42,114,158,155,151, 78,158,137, +132, 74, 70,167,241,122, 72,130, 24,174,211,209,171,196,172,152, 36,122, 49,209,106,228,245,110, 76,135,119,175,200, 71,225,183, +103, 2, 9,242, 46, 71,150,170, 36,109,131,206,189, 65, 37, 31,126,155,153, 61,152, 84,233,163,197, 65,178,182,133,144, 35, 27, + 62,118, 62,225,249,220, 10, 96,146,131,151, 16, 12, 68, 85, 30,228, 81,196, 97,225,212, 31,138, 42, 71, 66, 35, 99,100, 1,196, + 1, 38,232,176,221, 51,173, 24, 36, 67, 48, 9,201, 81,165, 96,233,107,105,193,239,240, 95,225, 2,172,234,221,135,111,158, 48, +184,175,168,123, 68, 52, 13,247, 8,208, 24,137,194,101,135,190, 1,243,233, 86,120,194, 9,148, 73,132, 2, 15,234,138,197,160, +234, 43, 91,185,206, 69, 15,123,126,239, 0, 29, 85,108,186, 16, 54,237,198,102,235,142, 31,229,217, 99, 59, 80, 54,248,246,240, + 85,230,199, 71,120, 89,215,210,125,209, 23, 60,254, 97,205,182, 23,148, 85,134,123,251, 6, 21,221, 65,198, 46,226,244, 9,182, + 44,123, 67, 46, 10,199,189, 56, 96, 96, 86,163,243,247,198,173,227,217,172, 80,212,129,176,214, 51,168,189,217,163,240,254,178, +238,226, 15,126, 10, 64,218,217,228, 52, 12, 3, 81,120,236,166, 41,148,170, 66,108, 64, 98,207, 33,184, 3,183,230, 10,108,187, + 3, 85,221, 84,252, 20,136, 19,123,240,252, 57, 73, 91,169,149,144,186,171,148, 74,105,242, 60,243,230,249,115, 53, 86, 16,236, + 93,177, 51, 84, 30, 79,168,188, 75,103, 58, 54,170,242,206,149,221,231,118, 14,176, 78,211,173, 17,238,127, 42,241, 77, 86,220, +163,162,252, 18,236,165,157,249,155,142, 23,114,122,169,124, 44, 44, 61, 17, 11,158,222, 69,151, 42, 13, 80,121,121, 28,236, 92, +123,155,167,209,117,253,196,220, 63, 59,253,157, 76,180, 95,157,232, 66,197, 68,137,107,112, 63,124,134,234,204,144, 3,129, 62, +116, 31,238,235,250,230,106,250,188,249,120, 27,220,182,246,140,206,200,143,141,200, 52,136, 10, 76,135,248, 87,195,215,116,150, + 65,220,181,112,151,127,119,113,185,253, 12,235,248,189, 2,216,190,119,185,159, 88,242,251,212,176,197,176,227, 86,163,225,107, + 62,186,250,233,225,182, 94, 94, 92,213,240,219, 52,171,215,221,186, 33,136,113,107, 45,194,127, 36,222, 91,112, 83,118,120,205, +193, 95,120, 88, 78,115,217, 94,101,245,252,202,130,212,193,188,246,139,185,127,217, 56,131,246,137,223,198,176, 58,144, 83, 43, + 80, 28, 54, 69, 32,106,138,134,255,194, 97,213,228, 16,143, 4,240, 37, 51,163,139,186, 86,241, 2,195, 2,245,222,221, 24, 67, +136,165, 74, 40, 89, 47,126,240, 82, 37,103, 92,171,212,151,136,159,218, 13, 88, 70,175,189,242,119,125,222,155,112,102, 74,255, + 53, 58,174,197,133, 93,191,135, 71, 92, 27, 81,121, 70,114, 76,248,202, 34,241,220,105, 38,232, 41,249,230,204, 56, 80,188,151, + 48,109,153,163,109,202, 46, 3,103,147, 50,225,110,208,246,222, 40,180, 50, 79, 33,169, 54,229,214,182, 37,244, 12,133,120,171, + 38, 63,245,145, 41, 33,116,191,137,204,221,166, 20, 48, 6, 12, 59, 97, 18,228,162,159, 77,179,168,120, 53,158,121,181, 41, 28, +174,122,206, 34,122,227,167, 66,204, 25,119, 44,198,177, 95, 29,167, 3,249,194,210,170,141, 7,224, 17,196,209, 69, 52, 54, 51, +253,185,209,151, 37, 1,177,180, 50, 34, 68, 49,245,165, 55,226,233,210, 56, 30,155, 89,130,211, 29,155,112,153,151, 70, 32,172, +249,132,232, 39,142,140,173, 54, 76,246,211, 61, 56,163, 60, 79,238,164, 3,244, 94, 77, 82,184,197, 65, 57,127,126,159, 92,249, + 42, 36,149,150, 63, 1, 72,187,118,157,134, 97, 40,106, 59, 78, 83,154,150,150,135, 64,170,224, 7, 88,144, 88,250,227,124, 3, + 59, 3, 35, 44,128,196,115,168,148,146,186, 73,108,236,123,175, 19, 39,164, 82, 36,218,173, 85, 7,215,241,241,125,157,115,186, +245,153, 33, 40,207,134,198,242,158,175, 20, 52, 99,107,148, 71,230, 90, 27,229,105,192,166, 9,228,189,249, 43, 41,207,161, 30, + 30, 15, 76, 44, 89, 56, 71,193, 77,159,144, 28,254,202,249, 33, 32, 8, 8, 77, 30,243, 36,205,103,223,178, 66, 65, 74, 83,146, + 68, 8, 17,230,252,252,150, 27,166,116,237,112, 16, 11, 54, 81,109,199, 12, 82,224, 18,144, 79, 66,252,187, 70,163, 91,130, 48, +146,126,180, 39, 46,101,114,153, 38,247,223, 63,111,204, 92, 50,190,154,204,111, 46, 78,215,185,186,125,126,121,216,255,167, 6, + 18,111,132,143, 85,176,103,166,253,249,200,119, 44, 13, 57, 40,153,162, 40,213,182, 56, 95, 76,174,206, 14, 71,159,230,174,204, +223, 45,196, 51,246,170, 91,123,105,163,254, 21, 23,215,199,243,229,201, 44,157, 69, 91, 27,206,103,250,233, 99,243,248,181, 89, +195, 68,208, 24,150,246,159,250, 32, 39,187, 43, 2,247, 41, 19, 71, 66,204,147,120,145,196, 7,177, 11, 15,109,214,108,131, 64, +128, 10,158,171, 24,146, 87, 94, 55,173, 56,186,154, 2,124, 4,224,238,154,133,164,234,200, 77,127,101,148,183, 19, 32,144,201, + 72,147,105,166, 50,212,195,232,128,123,151,255,233,117, 3,157, 10,186,129,121, 10, 19,145,208,183, 48, 88, 63,134,195, 40,124, + 29, 9, 67, 16,188, 60, 16,231,113,162, 38,228,167, 0, 39, 26, 38,182,200, 75,199,120, 79, 85, 80,118,108, 40,221,152,115,192, + 98,185,244,185,172,225,190, 48,196,125, 5,138,251,199, 17, 58,206,216,157, 2,150,110, 80,203,106, 60, 8, 27, 14, 33,139,200, +235,193,125, 13,156, 73, 27,143, 11, 22,149, 74,139,204,238,152,209, 59,237,100,111, 92, 95, 2, 46, 87,231,190, 80,217,115, 96, +225,187, 84, 22,229, 29,161,201, 61,221, 24,240,208,237,230,124,136,251,226, 78,220, 52, 77,245,144,125, 65,128,169,218,158,192, +193,156,115, 15,183,236, 79,240,222, 84,105, 80,204,156,244,132, 97,153, 58,144,162,107, 79,112,186,230,203,225,120,161,138,124, + 87,109,135,171,149,117,106,121, 82,140, 44, 86,131, 87, 9, 83,160, 87, 46,185, 4,134, 38, 58,220,225,165, 90,171, 81, 64,205, +182, 40,176, 6,192,105, 45, 56,130, 65, 3, 41,181, 10,139, 30,116,229, 52,217, 67, 13,238,246,245, 43, 0,105, 87,215,211, 54, + 12, 69,253,213, 52,165, 16, 84,182, 85, 27, 66, 98,111,240,206,127,224,223,243, 23,246,130,212,105,154, 4, 75,215,180, 77, 98, +251,206,190,246,117, 28, 70, 24,210,242, 84, 85, 85,149, 38,233,245,245, 57,231,158, 51,224, 51,234,165,247,252,100,149,127, 63, +159,150,191, 28,235,255,124, 91,150,247,242, 60, 51,176,180,201,191, 27, 6,141, 85,250, 31,243,216,181, 91,146,181, 11,178, 26, +131, 41,159, 80, 96, 41, 30,156, 35,130,139,150,129, 96,231,114, 6,166,175,245,102, 85,178,121,177,220, 31, 46,188,134, 45,234, + 92,210,213, 8, 37, 69, 80,236, 70, 84, 50,184, 51, 47,149,252,217,153, 83, 25, 61, 26,219,184,189,130, 61,213, 50,188,159,220, +173,206,159, 11,121,212,253,163,233,215,140,223,157,158,223, 94,125, 88,174,230,162,147,247,242,178,124,252,241, 96,244,212, 53, +148,201,189, 59,195,103,250, 12, 92, 83,196, 88,114,106,144,195,135, 27,102,119, 26,158, 14,253, 73,209,175,207,203,245,178,184, +217,182,223,234,221,166,109, 27,159,176, 6,103,140,175,228,236,162, 40,190, 84,139, 79, 85, 97,149,159,122,175,247, 93, 81,170, +205,179,126,122,110,106,173, 27,146,244, 24,246, 95, 71, 16,191,159, 32, 84,181, 96,242,107, 85, 94, 87,139,171,143,149, 18,226, +123,125,220,118, 26,180,249,101,244,178,100,173, 85,219, 3, 18,239,156,165, 1,205,116,251, 44, 27,138,187,209, 97,195,151, 66, +124,222,208,210, 13,213,193,253,144,223,125, 19,115,178,227,112,167, 37,241, 9,192, 95,120, 24,143,181,218, 15, 0,162, 39,146, +175, 27, 65,236, 1,228,109, 20, 51, 31, 34, 38, 15, 89,228, 25,203, 48,138, 49,143,135,150,234,104,124, 17, 11,115,232, 62,228, +152,172, 35, 86, 74,248,209, 92,225,234,132, 72,230,221,241, 81, 75, 78,232, 60,166,104, 36, 76, 38,166,154, 97,103, 26,120,105, + 72, 65, 67,168, 55, 13,155,159,176,109, 8,137, 84,146,107,215,228, 90,126,132, 78,128,236,220, 27,104, 17,228, 39,182, 17, 46, +179,184, 14, 6,183,200, 22, 39,202,122,220, 53, 91, 98, 50,248,139, 97,142, 28,174, 10, 5, 12, 18, 3,194, 13, 69, 35,254, 83, + 70, 18,239, 50,140,193, 25,152, 40,238, 68,193, 24, 24, 90, 74, 78,236,199,104, 98, 57, 32,191,225, 91,119,237,150,129,125,245, +108,236, 4,112,157, 79, 20,226,154,170,113,129,199,177, 36,188, 63,174,143,118,235, 33,186, 80,164,145,230,193,215,139,186, 52, + 75, 76,190,239,103, 20,159, 25,143,122,185,231, 76, 9,178,226,200, 76,185,225, 61, 73,153,249,241, 71, 0,210,174,101,167, 97, + 24, 8,102,243, 80, 91,209, 0,109, 65,136, 11,112,131, 15,224,255,127, 3,132,248,129, 10, 65, 11,164, 73,155,196, 94,188,246, +174,227, 52,225,212, 91,171, 70,145,220,196, 99,123,118,118, 38,245,239,178, 26,116,195,195,177,109,230, 41,234,184, 78,222, 4, +193,205,181,117,166, 99,159,106,217,200,131, 45,163,113,239,161, 76, 98,122, 5, 53,102,196, 72, 50,223,138,218, 25,234,137, 55, +218,177,153,156,159, 36, 46,237,213, 51,191, 46,199,141,210,224,118,117,249,186, 35,199,184, 89, 17, 61,173,202,171,185,250, 46, +150,148, 46,229, 83,182, 81,204, 43,120, 57,117, 91, 20, 86,225, 77,116,208, 37, 15, 81,102, 15,240,181,172,148,222,253,145, 2, +249,226,248,173,220,155,207,183,144,153, 1,191,127,109, 95, 62,177,106, 72,153,190, 72,210, 27,213,174,255,127, 84, 56, 80, 15, + 96,192,216,168, 64, 65,149, 6,100, 78, 67,245, 0, 85, 84,237, 38,163, 24,219, 12,210, 60,159, 62, 95, 76, 15, 20,103,107,142, +217,120,150, 81,126, 83,131,102,181,199,143,189,193, 15,179, 18,144,117,191,249,167,118,191,205,250,167,174, 35, 42, 18, 28, 78, + 6,119,103,192,144, 17,190,195,221,108,246,120,157,223, 47,231,243,116,242,176,202,201, 84,182, 41,182,229,182,178,230,128,139, +105,182, 41,128, 54,141,137,195,114,175,163,245,244, 2,159,167,209, 57,144, 6, 6, 39, 67,227,132,184, 59,237,119,102,173,116, +131, 86,100,185,128,130,195,129, 21,150, 0,145,243,179, 70,143,242, 32,133,109,215, 48,229,224, 9, 99, 23, 76, 36, 69, 87, 37, +144,204,188, 13,244,213,232,208, 73, 43,209,239,119,100, 11,239, 24, 21, 2,222,184,247,160, 89, 63, 67, 13, 65,212,137, 70,164, + 60,187, 91,137,111,130,173, 59,179,165,171, 61,230,114, 98, 6,181, 53,117,219,118, 14, 66, 50,131, 75,210, 68, 67,107, 39, 26, +155,228,156, 39,151,137, 85,148,153,117,107, 79, 49, 6, 21,104, 27, 24,107, 99, 55, 81,113,135, 48,146, 30,220, 92, 85, 99, 67, +202, 25,251,131, 45, 75, 49,240, 40, 30,163, 15,196,214,129,132, 9, 58, 84,141,128,143, 99, 99,237,216,136, 3,153,185, 62,214, + 75,192,176,176,137, 35, 93,153, 24, 6, 36,245, 3, 65, 28, 81,165,189,189,187,147, 80,245, 91,195, 16,250, 48,232, 11,195, 33, +101, 42, 36, 4, 11,100, 99,169,151, 70,214, 36, 49,181, 29,242,244, 37, 78,197,140, 44, 14, 23,113,215,210,214,201,194,109, 8, +188, 40, 66,188,232, 4, 69,155,239, 24, 60,212, 99, 42,187, 81,232,255, 19,128,182,171,217, 73, 24, 8,194,179,219,133, 66, 68, + 37, 61,153,120,242,224, 75,248,254,143,224, 19,152, 72, 36,132, 32, 6,104, 41,221, 89,119,102,246,167, 20,241, 98,228,194,165, + 9,180,221, 78,103,191,249,126,134,252, 72,219,115, 15,255,135, 66, 63,164,114,203,131, 20,171,188,138,185,175, 42, 74, 87, 51, +160,238, 66, 2, 54, 6, 51, 48,186, 34, 98,223, 1, 46,219, 68,171,159,228, 96, 86,114,251,228,121, 51,204,197, 32, 83,114,167, +223, 14, 27, 57,174, 6,120, 93,195,203,228,171, 80,119, 71, 43,199, 34,163,165, 28, 51, 24,168,253, 33,185,147, 56,125, 28, 0, + 44,192, 58, 98,174,176, 29,228,124,109,217, 88, 77, 64, 27,218,169,185,133,197, 27,250, 81, 92,213, 71,108,220, 1,187, 29, 98, + 67,194, 16, 34, 77,202, 31, 46,122,100, 74,219, 3,103,174, 33, 99,170,231, 17,159,216,135, 38,174,242, 45,116,170,131,114, 95, +212,246,120, 63, 34, 2,144,225,213,196, 49, 98,110,221, 98, 77,195, 53, 42, 42,219, 14,166, 99,221,250, 19, 55,186,109, 79, 31, +159,205,234,212,109, 89,159,101,255, 6,187, 79,153,224,239,139,123,165,204,243,124,246, 52,159,150, 8,139,229,222,194,225,125, + 77,218,162,189,237,252,123,206, 87,172,153,129,219,137,191, 11, 90, 44,151,147, 27,162,139,249, 46, 46, 69, 2,161, 40, 16, 7, +197,125, 32,111,145,180,162,222, 34, 8,227, 71,206,134,129,216,188, 7,187,177,108,222,151,186, 66, 21,249, 55,161,249,136,125, +121,168,241,156, 44, 47, 56,146,192,206,226,103, 29, 58,107,230,205,243,122,182,201, 73, 70, 37,158,117, 12, 74, 35,163,121,147, + 90,120, 9, 54, 34,196, 15,181,186, 96, 27,171,136,110,235,160,247,234,119,178,202,101, 86, 78,252,198, 52,126,133, 8, 53,138, +240, 67, 64, 98, 20,251, 25,122,101,148, 48, 46, 78,118,207, 67, 63,223, 7, 84,211,170, 30, 23, 59,138,170,229,177, 67,184,188, + 82,227,253,245, 98,149,136, 19,100,198,134,137,177,147,105,115,204, 97,194,190,234,247, 28, 54, 83,172, 86,151,147,201, 48, 58, +228,247,129,138, 14,194,191,240, 83, 46,104, 51,238, 10,137, 82,103,187,154,193, 48, 0,207, 55, 86,195,169,174,187, 52,227,191, +178,183,160, 74,162,203,145, 42, 26,219, 22,177,178,251,206,192, 56,209, 72,185,135,234,113,189, 89,234, 80,223,141, 74, 94,250, +100,203, 49,106,142,141,100, 91, 51,153,141,105,131,154, 12,228,144,137, 68, 52, 29, 1, 78,172,204, 94, 74,104,163, 46, 23,243, +140,240,234,231, 91, 0,210,206,102,167, 97, 24, 8,194, 94,203, 9, 52, 45, 63, 18, 18,103, 4, 23,222,255,129,224, 82,137, 3, + 69, 17, 45,184,141, 99,123,241,122,237,196,129,180,170,132,218, 67,212, 30,154,186,145,187,187,153,249, 38,241,103,250,105,179, +131,191, 98,140,255, 84,148,112,198,173, 93, 56,249, 2,204, 29,195,232,234,134,210, 68,130,153,212, 17, 97, 50,233,193,118, 8, + 20,165, 57,225,132, 27, 32,123,172,146, 12, 71,106,183,127,167, 9,196,120,101,220, 11,127,189, 92,124,155,177,147, 75,198, 90, +143, 67,138, 84,154, 25,197,113,126, 45,180, 35,107, 54, 33,118,163,236, 79,118,180,161, 3, 75,221, 49,165,143,202,134,116,232, +254,197,187, 56, 63, 9,187,170,109,157,221,120,191,165,124, 98, 81, 75, 50, 64,109,242,152,165,138,163,106,127,228,210,158,249, + 74,121, 1,171, 41,130, 99,152, 18,184, 28,119, 28, 78, 82, 27,111,156,239, 76,223, 26,175,123,219, 91,194,126, 83,162, 56,132, +146, 76,124, 57,103,156,216,237,205,122,103,222, 4, 45,141,249,199,112,134, 67, 1,155, 72,194,121, 94, 52, 79, 55,171, 86,219, +117,171, 63,181,177,214, 29, 40, 5,208, 28,122,251,161, 77, 56,238,188,187,109,100,189,168, 95, 91,197,238,159,232,134, 76, 38, + 56,255,171,120, 79,225,158, 2, 70, 48,233,252,197, 6, 83, 44,210, 88, 53,101,187, 80,209, 32, 79, 74, 54,244,165, 2,102,176, +209,227, 40,116, 28, 98,221, 89,123, 46,139,178, 34,115,154,112,136, 60, 45, 60, 85, 5,190,128, 93,213, 25, 50,147,131,140, 49, + 83, 81, 37, 14,221,226, 84,122, 87, 60,185,175,228, 1, 56,163,175,146,199, 11, 10, 80, 61, 83,185, 29,103, 38, 65,226,168, 20, + 1,113, 17,115, 84,147,248, 17,237,193,117,142,120,238,184, 4,213,161, 33,237, 35, 77, 99,108,180,123,245,196,153,177,134, 54, +119, 34, 94, 59,138,109, 2,254, 40,207, 46,194,162, 67, 47, 59, 23,200,137,159,105,105,176, 92,118, 44,229,193, 80,252, 31, 12, +134, 91, 16, 51,254, 50, 60,231,166,224, 25,111,225,156, 78,228,148,118, 70, 78, 54,119,228, 52, 92, 26, 38, 68, 32,168, 4, 85, +145,246, 72,169, 74, 85, 68,168,173, 76,215, 41,169,194,235,241,255, 52,222,173, 78,243, 84,106,213, 66, 11, 27, 74,251,240,195, + 55,151,171,176,236,138, 9,183,200,233,164,112, 81, 53,144,162, 8,112, 40,127, 31,238, 30,183,251,150, 55,199,171,234, 42,242, + 38,143,158,240,143, 0,140, 93,199, 82,195, 48, 16, 85,117,136, 9,101, 56,112,228, 19,248,255, 11,255,194,192, 5,134, 50, 64, + 8,196, 69, 43,180, 69,178,226, 1, 18, 79,238,118,108,105,181,229, 21,183,183,103,255, 71,223,230, 63,161,224, 3,179,120, 51, +167, 9,196,138,145,192, 6, 58, 81, 79,102,202,244, 47, 17, 11,111, 24,164,192, 20, 39,233,206,198,200,243,148,125, 69, 67,102, +172, 32, 63,159, 85, 98,166,235,170,109, 30,123,159, 22,175, 35,176,117, 54,227, 68,117, 34,200,253, 25,205,206, 91,146,201,153, + 83,171,159,122, 73,189, 1,245,103, 68, 0,178,206,226,189, 81, 29,154,210, 33,208,240,161,234,134,121, 50,185,110,211, 33,222, + 35,217, 36, 86, 52, 40, 91,189,153,240, 91,232,132,217,164,169,130,198,179, 6, 47, 33,214,227, 26,115,240, 97, 51, 96,255,118, +233,210,113, 18,207, 72,140,119, 19,128,228,189,208,109,213, 91,212, 9, 24, 52,156,123,179,233,250,117,215,111,200,185, 57,100, +183,169,189, 53,224,175,193,125, 73,191, 75,101,174, 79, 79,190, 1,110,158, 95,211,243, 92, 40, 59, 6, 19,130, 67,114, 60,105, +109, 45,104,144,116,236,213,217,194,223,191,185,110, 84,105,133, 3,229,135, 20,171,216, 42, 59, 22, 92, 19,247, 93,117,209,168, +202,233, 88, 77,190, 51,243,207, 94, 66, 9,183, 98,114,130,169,179, 20, 93, 44,125, 19, 25,255,149, 32, 27,166,154,188,178,226, + 41,201,190,206,101, 35,136,151,147, 54, 38, 78,248,238,200, 10,116,164, 14, 86, 44, 4, 37,182,231, 66,128, 86, 51, 22,162, 76, + 84,178,145, 27, 0, 90,154,250, 38,206, 55,111,172,168,203, 34,131, 44, 96,119, 16,239,139, 93,124, 17, 70,118, 17, 59,139,187, +109, 16, 35,176, 75, 19,122,189, 93,217,149,234,190,122, 28, 77, 12, 93,255, 49,142, 77,123,180,120,215, 91,224,225, 42,113, 94, +233,107,208, 30, 4,226, 18,107,182, 99, 3,222, 79,197, 77, 13,166,233, 52, 72,219, 67, 77,212,212,226,145, 93,169, 7, 75,217, + 4, 57, 3,139, 48, 29,201,121, 40, 91,167,243, 59, 48,214,131,145, 31,250,127,154,210, 33,193, 93, 87,105,187,146,241,161, 38, + 96, 12,130, 32,113,232,110,156, 55, 22,149, 42, 81,115, 1,147,209,166, 89, 24,176, 71,174,105, 93,219,218,214,219, 6, 97, 1, +204,161, 82,200, 16,235,198, 45, 78, 68, 81,222, 39,157,157,168,180, 31,108, 90, 9, 46,213,250, 64,250, 51, 30,185,241,114,148, +167,155,223,189,220,226,221,232, 85,124, 14,107,189,203,140,153, 93, 63, 2, 48,118, 45, 59, 13,195, 64,208,107,167, 41,180, 5, + 85, 28, 65,136, 35, 39,254,255, 27,184,243, 15,156,120, 8,149,166,137, 31,139,119,215,118, 28,210, 22,206, 85,163, 40,173, 39, +187, 51,187, 51,205,252, 93, 7,199,192,113,142,242,225,116, 2,200,255, 5,232,217, 83, 47, 16, 15, 48,182, 73,152,148,249,236, +118,170,197, 38, 12,114, 54,151, 46,102,204, 90,229, 92,214, 80,239,202,149,165,211, 66,122,197, 50,185, 89, 60,133,203,117,176, + 86,225, 1,113,219, 46,222,253,245,103,239, 56, 60, 86, 99,217, 57, 80, 73, 5, 43, 24, 74,193, 79, 74,139,129,159,225, 2,156, +104,247,144,168,112,118,188, 25,121,146,129,187,206,134,241,210,179,219, 76,147,205,208,215, 38,130,123,115,191, 89,190,125,196, + 99,149, 36,217, 54,155,139,193,105, 98, 36, 76,219,172,118,154,141, 39, 95,236,242, 92,205, 64,106, 42,205,185, 95, 5,108, 27, + 61,176, 84, 24, 31,220,142,247, 14, 91,178, 58,140,173, 35, 44, 53, 4,231,123,235, 58,231, 73,155,205,248,142, 21, 95, 23,254, +113,128,228,102, 86,236,129,243, 96,204,227,118,243,178,239,159,187, 67, 72, 31,121, 10,144,112, 68, 91,245,220,232,180, 10, 91, +128,141, 49, 30,240,117, 71,191,177,103, 34, 89,156, 37,164, 82,175,173, 97, 48, 40,156,217, 35,201,139,254,215,240,232,236,205, + 14, 18,118,156,166, 44, 85, 45,167,225,236, 20,135,186, 43,144,250,129, 52, 85,173, 96,210,214,143,252,114, 1,250,106,137, 42, +254,229,210, 34, 29,230, 52,108, 48, 69, 28,100, 41, 73, 94, 11,236,167,229,227,229,217,248, 78, 82,186, 33,173,231, 28, 27, 69, +153,222, 92, 41,111, 81,184,248, 84,182, 83,150,177,228,164,129,194,105,139,195, 9, 80,133,178,114,106, 31,187, 89,141, 87,203, + 53, 88,202,185,105, 34,228,235,176,115,223, 30,164,202,193,108, 65,236,179,193,140, 39,158,143,231, 14, 83, 99, 12, 53, 47, 92, +188, 32,202,188,105, 64, 85,243, 84, 48,110, 23,101,112,247,149, 93,125, 46,222,199, 57,200, 58,173, 9, 79,128, 59,254, 93, 82, +158,135,163,243,156, 76, 13,238,201,231, 95,102,167, 56,245,179, 97,103,127,169,217, 57, 20,142,120,155,197,106,113,113,183,186, +221,182, 55, 90,235,193,217,158,182, 98, 99,251, 74, 10,170, 97,134,235,210, 92,220,172,182, 17,250,227,133,186,205,112, 8, 93, +239,250, 47,251,213,217,254,219,237,173, 63, 88,138,198,101, 23,198,108, 30, 7,105, 99, 89,243,193,116, 50,129, 51,250, 93, 79, +111,250, 71, 0,202,174,174,167,113, 24, 8,218,235, 56, 77,139, 80,133,184, 59,241,122,226,133,255,255,204,255, 64,226, 23,128, + 16,186,147,144, 26, 66,237,245,237,135,183, 14, 41, 20,174,143,169, 84, 41, 77,188, 30,207,206,206,116,167,255, 6,127, 84,229, +195, 82, 1,233,191,195,179,127,147,142,119,213,233,204, 27,157, 2, 38,139, 55, 8, 95, 39,174, 51,109,143, 22,138,137, 30,235, +232, 2,231,111,122, 72, 31, 37,167, 28,146, 51,235, 12, 6,176,100,225, 79,127, 70,239,202,143, 72, 95,133, 71, 90, 92, 19, 61, +165,236, 27, 51, 88, 51,131,244,240, 11,214,143,231,169, 19, 1, 70,111,114,101,240,181, 9,217, 89,214,168, 90,113,105,162,180, +120,173,224,133,235, 68, 96,195,159, 94,202,223, 0,110, 27,225,234, 60,254,222,196,251,167, 93, 47, 5, 49,205,230,149, 38,219, +153,242,215,138,168,122, 92, 8,182,236,181,181, 59,182,168,144, 50,210, 29,211, 13,167,178,135, 16, 3,107, 58, 87,200,131, 1, +107,238, 90,139, 28,196,165, 93,194,241, 45,255,117, 89, 51, 99,119,239, 93,207, 78, 67,120,111, 74, 77,165,101,232, 94,110,226, +112,125,177,190,125,126,185, 19,117,144, 30,149, 94,100, 47,166, 45,103, 96,145, 93, 33,208,178,118,101, 83,252,165,131,135,169, +127,205,140,121,164,120,128,180, 84,184, 60, 41, 60, 60,144, 51,243, 74,229,103,193,243,150,164,244,241, 91, 87,135,230,148, 59, + 65,231,222,119, 86,143,101,218,110, 73, 13, 11,224,230,157,177,174, 43,197, 24,109,142,169, 73,189, 44, 69,187, 78,251,248, 42, +184, 2, 77,209, 41,161,250,228, 57,141,255, 82,139, 72,204,153, 48,159,188,200, 84,221, 53,136, 14,138,199,207,180, 33,179,138, +217,186, 83,141,125, 87,216,110, 62,201,232,154,170,191, 44,251, 94, 44,200,148,240,110, 55,166,113,130,137,128, 11,123,164,179, +159, 11,106,158,147,254, 69, 50, 5,170, 85, 94,156,126, 4,200,163,210,242,246,235,214, 13, 22,237, 65,133,234,104, 14, 34,126, +193,133, 88,185,199,170,242, 41,165,197, 81, 53,183,119, 83, 7,205,140, 61,173,181,124,138, 96,249,127,160, 89,190, 10,207, 57, + 78, 16,226, 43, 81,182,107,122,162, 67, 63, 32, 34,211, 50,146, 0, 4,190,251, 53, 92,254,220, 92,173, 96, 69, 15,122,164, 35, +116,206,123,182,174, 44,135, 76,201, 61, 18,240, 74,210,190, 67, 42,253, 49, 4,161,217,160,195,184,133,237,186,155,124,142, 37, +172,198,244, 58,122,142, 11, 77, 46, 9, 60, 82,240, 99,103, 53, 23, 84,110, 2,150, 4,187, 88,161,255, 4, 96,236,218,118,219, +134, 97,168, 40,167,142,147, 21,117, 59,236,105,239, 3, 6,108,223,189,255,106,135, 61, 20, 45,138,100,151, 68,150, 37,113, 34, +169, 91,235, 54,105,144,135,192, 72,108,193,142, 40,234,240,240,156,215,241,247, 19,123, 27,124,137,200,195,187, 33,120,120,207, +215,160, 1, 26,161, 96,147,139,139,229, 61,116, 53, 94,149,152,187,238,215,113,153, 4,128, 6,244,172,111,148,237, 46, 72,170, + 79, 63, 50,160,119, 30,140,120, 76,198, 7,165, 51,237, 1, 84,181,249,204, 83, 42,205, 40,182,157,140,143,106,208,118, 29,226, +138, 44,251,104, 10, 97,146,119, 31, 51,204,210,103, 66,235, 86,119, 49, 97,191,207,153, 23,101,253,168,198, 14, 70,232,126,237, +236, 79,239,123,142,251,151,164, 8, 79, 67, 55,153, 15,211, 61,199,106,222, 42,177,182,226,145,242,218,230,152,187,226, 51,111, +132, 93,139, 97, 31,148,225,174,152, 13,119,215,117, 90,226, 35, 88,135,143,179,127, 82,238, 15,183,191, 78,121,145,104,229, 98, +212,107, 18,213,133, 36, 51, 48, 32,211,179,175,200,247,126,248,242,241,195,143,135,167, 91,222,158,119,205,223, 78,244, 9, 38, +133,191,121, 14, 59,106, 14,192,207,215,195,157,217,120,145,129, 67,169,255, 33,151,177,125,170, 23, 22,212, 35,183, 33,161,106, + 49,228,218, 36,131,207,117,192, 67, 33, 4, 74,127, 83,229,153, 44,239, 42, 36,197, 73, 56,145, 15, 66,161, 45,166,181, 1,117, + 67,203,213,109,184, 41, 98,225, 5,169, 79, 5,216, 80,124, 44,115,176,128,100, 67, 70,215,214,117,158, 21,223,167, 70,204,182, + 25,187, 28, 46,182, 23,149, 36,227, 83, 38, 84,101, 63,206, 0,209,212,162,199, 1,217, 19, 80,232, 28, 87,181, 19,176,206, 39, +164,205, 78, 96,105, 85, 6,247, 69,164, 15, 67, 67,184, 76,144,147, 60, 47, 85,145,120, 92,178,250,160,208, 66, 84, 50, 57,199, +172, 12,207,100, 75, 85, 77,169,176,218, 34,150,224,238,213,219,222, 26,225, 92,168,111,106,135, 24,206, 6,166, 69,112, 87, 57, +103,239, 8, 71,164, 30,223,152,170,199,208, 60,110,110,194,236, 46,136,189,161,199,225,234,219,248,245,102,253,233,159, 53,123, +146, 60,154,172,183,115,152, 15, 49,117, 39, 82,136,140,210,179,252,115,146,223,137,119,243,224,173,245,179,117,211, 28, 98,230, +126, 60,122,243,215, 29,140,155,246,184, 51,234, 64,164, 62,162, 93,174, 50, 95,190, 83,141,141,204,178,135,169,124,254, 47, 0, +103,215,178,211, 48, 12, 4,215,206,163, 15, 64, 28,170, 74, 32,113, 70,226,159,249, 36,126,129, 3,226,196, 1,129, 40, 74,155, +164,177,241,172,215,206,166, 45, 8,144,170,158,114,104, 98,215,153,157,157,157, 41,255, 33,122,209, 40,222, 79, 98,133,127,198, +230,191,229,235, 21,132,151, 10,214, 38,255, 13,169,106,163, 11,187,152,106, 24,177,177,225,138,123,125,121,253,212, 62, 14,106, +224, 89,223,188,117,170, 31,139,132,108,136,191,202, 40,173,225,220, 37,126,155, 66, 60, 91,216,193, 57, 44,158,181,201, 61,158, +164,208, 29, 34, 13,196, 46, 52,252, 7,197,252,228, 46, 77,211, 85,140,124, 59, 78,249,224, 1, 87, 23,106,171,240, 10,185,173, +231,117,215, 62,160,205,137, 3, 20,145,211,173,123,110, 65, 92,156,225,124, 52, 75,124,202, 13,237, 59,100,214, 75,202, 71,118, +229,245,223, 96,103, 29, 11,208,166,185, 89, 23, 7,107, 83,135,179,226,145,246,240,240, 22,100,151,252,116, 3,102,223,161,187, +107, 59,214, 84,212,228, 63, 29,189,211,126,139, 44, 54, 9, 21, 33,229, 53,159,231,144,115,137,224,149, 66,191, 86,221,212,115, +162,187,249,114,117, 81,221,191,188,110, 20, 45,216,171, 18,176, 73, 47,158,125,202, 8,108,236,188, 25, 16,105,228, 93, 38, 97, + 37,252, 86,108, 98,180,109,202, 81, 67,224, 24,194,107, 60,105,200, 37,243, 45,239, 51, 15, 12, 52, 58,206,143,142,252,147,161, +147,163,137,199,194, 9, 97,177, 17,147,154,178, 42, 24,174, 79,229, 27,137,130,224, 81,163, 88,104,226,120,143, 40, 94, 70, 61, + 56, 92, 27, 54, 72, 46,128,103,118,167,142,233,172, 49, 99, 85,184, 49,175, 21,241, 52,145,200, 41,214, 17, 33, 86,195, 72,239, + 79,124,214,204,184,148, 78, 15,218,240,149, 61,123,123,153,188,242,224,216,125, 52, 6, 49, 38,153,187, 97,164,140,164,131, 27, + 97,187, 88,253, 37,110,195,143,116,202,193,201,174, 45,104,146, 92,149, 93,254,114,156,147, 40,233,213,225,110,178, 32, 39,201, + 96, 14,144,187,255, 27, 6,215, 91,198,211,111,155,135, 39, 14,119,139, 58,179,136,153, 80,133,173,194,247,110,219, 4,204,110, +108,121,181,184, 89, 47, 86, 31,253,110,211,190,177, 97, 50, 53,188,178,113, 95, 23,236, 75,152, 20,177,184, 97, 96,242,176,238, + 6,206,109,225,170,170, 0, 61,220,211,208, 33, 73,209, 84,182,174,221,172,243,221, 64,125, 79,125,216, 52, 51,170, 75, 8, 40, +145,131,203, 8,163, 48,162,168,113, 52,125, 44,241,103,127, 9, 64,217,181,244, 36, 16, 3,225,105,247,133, 32,143,141,137, 9, + 18, 47,222,136,209,255,236,143,243,224, 5, 53, 17,113, 95, 29,233, 76,103,182,139,128,122,225,202, 82, 96,250,245,235,247,232, +241,251, 31, 4, 48,199, 69, 47,240,155,156,230, 60,138, 63,245, 46,145, 35,128,219, 57,213,210, 97,251,196, 53,235, 52, 84,138, + 35,248, 94,183, 27,115, 96,109,141,126, 83,241,143, 61, 9,153,173,225,180, 78, 30, 73,156,141,220,114, 94,175,202,122, 57,239, + 22, 11, 15,116,183, 59, 11,166,215, 65,240,198,112, 53,189,110,154,198,186,207,170,105,129,173, 34,244, 71,172,229,122, 19,195, +168, 13, 68, 0,237, 28,230,174, 24,173,179,162,106,219, 55,202, 48, 96, 36,187, 0, 88, 66,122,107,178,155, 52,219, 63, 84,234, +125,129,189, 97, 6,251,218,198,115, 49,161,137,204,223, 90, 50,206, 76,164,152, 84, 38,189, 13, 66,111,252, 34,201, 69,133,110, +231, 85, 19,254, 90,167,130,110, 11,184, 17, 74, 71,139,191, 19, 97,169,148,125, 74,133, 53, 82, 84,126, 65, 31,118, 70,200,253, +113, 60, 89,149,249,211,203,251, 71, 20,108,121, 16,126,233,100,149,106,122,212,135,113,246,140,211,150,175,201, 53,102, 90,181, +143, 97,130,240, 55, 24,208,117,116,106, 57, 2,225, 35, 91, 19,162,214, 53, 80,165, 47, 66,204, 1,196,102,162, 80,250,129,135, +219, 40, 14,120, 77, 59,104,204, 50, 71, 64,189,236, 56,170,239, 1,171,137, 3,131, 99,111,143,226,213,172, 74, 39, 76,139,170, + 68,166, 61, 1,117, 89, 98,168, 62,184, 9, 52, 50, 11, 29, 74,168, 36, 68,125,150,253,178,171, 43, 50,230, 64,228, 58,148,215, +202, 33, 83, 6,161,159, 54,188, 58,162,205,124,196,176, 88,138,249, 68, 33,250, 84,166,113,226, 50, 62, 28, 78, 97, 38,228,141, + 42,220, 81, 46, 43, 64, 92,100,146, 8,163,247, 35, 28, 39, 31, 15,119, 93, 24,232, 6, 25, 6,120, 32, 49, 56,117,231,111,254, + 45, 8,249, 57,220,185,250,205,203, 92, 82,147,237,241,251, 30,179,103, 62,204, 9, 46,243,233,186,188, 47,139, 57,205,111,152, + 20,227, 34, 73, 51,203, 12,142,103,182, 50,210,180, 83,123,162,179, 50, 77, 88,123,227,188,134,205,228, 82,113,210, 96, 23,204, +183, 30,173, 39, 59, 95,144,136, 76,247,119,164,152,204, 33,247, 4, 53,225, 96,117,134, 70,249,225, 70, 73,204,111, 1, 24,187, +154,158,132,129, 32,186,211,143, 21, 4,149,132,112,195, 68,207,254, 13,255,161,191,207,131, 39, 53,129,196, 40,208, 98, 59, 59, +238,204,238,108, 11, 5,245, 74,210,148,182,219,217,215, 55,239,205,251, 91, 63, 3,167,240, 56, 13, 72, 27,211,187,251,195,129, + 75,231, 80,252, 63,194, 69, 85,201, 0,161, 94,136, 79, 58,170,159, 3,253, 33,111, 65,166, 62,190,136,205, 8, 50, 56, 97,156, + 72,251,134,144, 88, 28, 93,148,251, 27,103, 29,226,205,152,110,103, 77, 67,109,181,195,247,173,249,106,205,196, 54,203,133,185, + 25, 21,207,175, 8,234, 78, 8,223,161,171,207, 55,127,232, 53, 56,153,211,193,184,112, 39,249, 30, 1, 26,141,165, 64,127,199, + 55,148, 85,206, 30, 89,215,244, 93,239,113,150,219,199,217,124, 98,237,206,225,170,218, 35,210,180,132,169, 45,252, 21,125,214, +251,106,183,255, 16, 17, 78,171,158,142, 70,215,229,239,119, 41,141,158,207,123, 25, 99,121, 79,108,227,132, 18,169, 13,124, 25, + 55, 50,112, 45, 63,183,218,207, 10,118, 98, 43,101,186, 21,126,169,236, 77,140, 73, 28,145,211,179,160,212,244, 66,177,252, 68, +235,251,195,120,114,191, 24, 61,189,172, 55,218,135,112,103,186,178,233,114,252, 73,235,242,178, 66,206,218, 78, 38,247, 24, 30, + 29,201,220, 4,196, 37,142,229,104,229, 28, 67,248,212,120, 20, 82, 55, 85, 46,140,230, 73,211,205,158,164,195, 50,116, 52,138, + 22,186,218,212,183, 78, 29,202,137,244, 35, 49,209, 32,233, 65, 97, 24, 66,198,220, 77,230,122, 62,152,110,246,134,160,120,195, + 47, 41,229, 14, 66,130, 19, 47,222, 16,194,164,125, 0,248, 77,221,161,170,118,241,150,130,230, 83,116,138, 4,211,229,195, 68, + 30,220, 25,232,219,138,210, 31, 30,184,231, 28,165, 45, 36,116, 59, 59, 22, 41, 74, 48, 53, 27,195, 29,132,141,159,194,236, 20, +113,122,212,226, 29,248,143, 2, 89,145, 26,170, 6, 41, 17, 61,189,226,142,177,216,197,163,218, 78, 65,148, 54,190,179, 43,205, + 12, 30, 29, 12,100,223,244,119,113, 39,241, 46,113, 23, 69,138, 59, 39, 55, 23,172,105,183, 25, 75, 45,232,246,106,185,156,222, + 93, 64,182,105, 61,230,171,107, 9,164,245,117,182,200, 75, 91,150,121, 83,111,169,114,204,232,202, 28, 75, 10,182,153,184,153, +161,227,133,154,115, 7, 70,236, 18,130, 6, 81,237,201,190,148, 47, 96,190,166,117,107,176,148,188,181, 96, 96, 40,205,197, 56, +243,101,100, 3, 60,108,135, 49, 24,106, 68,137,114, 56,124,154, 31, 1, 56,187,182,214,132, 97, 48,218, 47,209,214,213, 27, 19, +199,246,176,193, 16,217,203, 94,246,139,247,231, 6, 99,136,232, 16,171, 73,219, 36,203,237, 75,211,234, 70,153, 79, 34,162,150, +182, 95,142, 39,231,242, 23,126,239,141,220,123, 9,228,161, 7, 17,223, 54, 14,180,138, 79,193,171,224, 27, 94, 8,111,176, 80, +114,128,183, 17, 9,175,123,181,149,106,197,244,227,226, 96, 77, 4,122,100,228, 89,125, 63,175, 39,105, 85, 50,161, 39,147, 9, + 66, 17,201,161,150,167, 82, 50,158, 60, 44,169,168,232,145, 59, 23,183, 31, 62, 38,176,130,170,155,132,243, 42, 97, 38,102,201, +248, 69,107,195, 60, 40, 17,177,213, 52,146,115,100,246, 42, 57, 42,185, 97,236,179, 96,147,193,224,245,110,186, 94,206, 22, 19, + 61,226,146, 93,193,191, 79,124, 47,235,194,182, 43,149,150,196, 8,217, 0, 61, 77, 70, 52,178, 56, 37, 81,124, 77,168, 38, 72, +209,125, 39,112,142, 91, 8,160,172,217,213,124,169,163,254, 99,180, 46,241, 9, 69,240, 30, 0,120,134,145, 3, 99,187,161,250, + 56, 28,189, 61,205,223, 63,182, 95,210,112,241,240,139,229,164,243, 88, 1,156,135,183,190,247,144,128, 79, 86,177,106, 62,147, +103,101,214,109, 97,211,133, 66,204,159,251,228, 38,160,168, 83,119,135, 35, 70,226,162,238,185, 5,123,226, 69,104,248,235, 12, +247,166, 7, 44, 98, 0, 84,210,175, 91, 65, 53,232, 30,218, 92,168,114,234, 46,136, 54,143, 60, 25,104,174,111, 95,131, 77,156, +253, 14, 87, 21, 64,197, 39, 33, 87,203,118, 33,180,200, 26, 91, 76, 80, 34, 54,206,207,184,100, 22,117,189,222, 60, 10, 45,134, + 86, 93,209, 1, 41,151,115, 16,225,101, 8,162,249,152, 30, 81,237, 69,166, 35,222,240,244,186, 53,169,218,221,217, 86,100,178, + 10,165,184, 74, 54,240, 28,188,165,184,131,220, 65,184,190,173, 11,230, 65, 69,219,137,255,176,224, 93, 86,103,144,139, 17,132, +127, 10,141,200,157,216,137,164,199, 58,213,176,157,208, 33,209,176, 61, 29,152,115,164,214,243,151,213,236, 89, 31,237,254,180, +219, 28, 55,219,211,246,192, 15,231,178, 96,226,204,107,198, 68, 73,128,140,104,166,127,254, 89,214, 54, 34, 20,119,137,253, 30, +131, 41,233, 20,190,191,198, 69,181,201, 74,131,120,236,150,161,132,140,146,188,178, 74, 8, 61,238,115, 24, 79, 6,211, 69, 58, +203, 73,174,223,207, 85,137,149,121,141,235, 5,209, 4,252, 8,192,218,213,244, 36, 12, 4,209,221,150,182, 96, 15, 69, 73,228, +224,193,155,241,238,255,143,119,255,133, 7,162,146, 96, 8, 72, 41,221, 47,119,118,102,182, 31,152, 96,140, 55, 14,180, 52,219, +101,246,205,155,121,111,254,194,191,143, 80,124,242, 83,215,141,227, 33,124,231,163, 44,127, 67,196,147, 81, 65,199, 15,210,108, + 70, 67,211, 44,157,235,213,104, 36, 57, 44, 37,168, 23, 76, 12,203, 71,136,189,196,209, 79, 22,166,105, 39, 14, 73, 49,108,179, +155,207,220, 2,150,200, 54, 13, 16,208, 40,151,244, 39,111,107, 68,173, 66, 92,147,122,245,217,222, 47,243,183,173, 77, 51, 10, +151,193, 23,194,223,165, 61, 40,113, 4,213, 18,236,253, 6,181,223, 12,186,243, 30,250,198, 37, 62, 4, 18, 60, 19,102, 43,210, + 70,156,222,119,234,101,183,157,131,186,213, 95,139,232, 19, 30,170, 69,229,123, 40, 87,214,195,117,190,104, 32,108,153, 54,193, +217,173, 81, 42, 21, 51, 83, 69,173, 84,240, 48,199, 96, 65,163, 3, 83,212,134,158,206,128,241,225,119, 45,135,254,188,103,234, +171,153,168,153,113,222,231, 24,197,251,132, 96, 41, 38, 79,119,213,243,102,247,170, 93,206, 91, 66, 95, 50,158,244,215,150,211, +114,111,252, 14, 38,234,214,132, 67,220, 31, 57,123,181,169,245,113, 81,148, 6, 76, 57, 89,207, 58,156,176, 60,106,236,225,118, + 89,166,110,177, 46, 40,201,128, 43,100,193,210,141, 59,175, 69, 52, 36, 96,146,219, 14,208,173,141,129,210,141, 20, 46,118, 24, + 20, 18,164,225,168,151,200,245,224,188,166,220, 90, 16,119, 18, 68,161, 96, 52, 32, 41, 39, 36, 71, 41, 41, 25,179,224,228, 56, +109, 49, 7, 69,255,254,128,247, 44,210,225,131,226, 2,170, 62, 35, 55,194,124,146, 38,218,134,165,252,110,172,138, 27,253, 97, + 49, 13, 96,243, 62,219,121,228,179,133, 89,215,164, 64, 84,209,136, 1,151,189,178,170, 99,204,142,128, 93,246,209,186,176,180, +168, 29, 80,235,102,162,179,104,185, 11,238,230,220,122, 37,194,118,251, 31,182,213,113, 41,162,207,118,124,203, 14,146,242, 36, + 52, 63, 73,166,101, 16,182, 67,124, 79, 96,178, 66,250, 48,127,188,157,222, 40,115, 90,237, 62,214,245,250, 75,213, 14, 12,100, + 92, 38,243,194,129, 25,201, 36, 49,202,180,254,251, 69, 58,187,154,228,254, 51, 72,239,185, 53, 8,231,138,133,100, 83,147,143, + 40,212,137, 32,244,107,224, 41,208, 23,194,166, 34,189,145, 85, 35, 84, 38,139,178,168,174,139,170,156, 76, 65,110, 86,251,216, +213,104,161, 66,147, 54,174,137,197,218, 14,190,172,111, 1, 72, 59,159,157, 54, 98, 32,140,123,236,253,151, 0, 66,169,168, 84, +113,229,128, 4,239,255, 18, 60, 3,135,158,138,160, 21, 41,162, 33,235,172,237,233,206,216,227,245,110, 36, 10,234, 45,135, 40, +171,216,222,207,163,111,102,126, 83,253,255,210,248,162, 66, 78, 29,213,210, 97, 65,231,249,140,196,227,209,237, 34,241, 7,171, + 60, 31, 57, 61,157, 44, 49, 39, 19, 63,150, 41, 80,228,151,145,173, 19,182,110,255,173, 85, 39,166,221, 90, 82, 18, 7,208,152, +241,214,165,182,201,231, 87,234, 12,174,216, 38,123, 38,198, 59,129,222,199,205, 36, 34, 57, 18,164,195, 91,119,113,170, 47,191, +248,199,223,170, 54, 9,137, 51,120,127,222,186, 31,251, 49,218,133, 53,107, 37,112,109,123,174, 17,236,197,160,136, 87,130, 77, +206, 56, 50, 11,158,208, 30,142, 65, 11, 91,250, 60,202,189,107,185,146, 36, 2,237,246, 18, 74,231,134, 3,252,204, 70,132,162, + 0, 92,139, 64,175, 10,134,251,138,119,228, 64, 15,162,108,112,155, 78, 51,207, 86, 96,161,223,241,247,131,240, 47,163,224,181, +226,239, 71,213,142,210, 31, 11,102, 54,202, 92, 93,172,108,135,119,223,223, 56,157, 59,155, 91,242,206, 27,120,109,148,213, 39, +129,199,111,138, 91, 76,226,254,210, 63,220, 91,250, 55,245, 97,215,172,215, 26,170,185,219,176,104, 95,196, 41, 55,138, 98, 4, +167, 43,188, 96,111,201,172,187, 82,217, 81,154,132,226, 4,223,178,151, 53,255, 40, 46, 43,163, 23, 81,228, 36,153, 58,138, 66, +172, 34, 49, 50,126, 47, 97,148, 4, 59,163,146,201, 74, 55, 49, 70,238, 47,103, 54, 97,106,138,215, 25, 63,140,114, 38,210, 46, + 64, 97,241,207,114,149, 37, 97,141,159, 31, 74,101,159,187,163,203, 33, 18, 33,241,115, 69,198,217, 19,139,240,177, 35,166, 21, + 44,173,255, 41,113, 42, 0,168,160,222, 81,246,114, 49,179,178,231,209, 62,121, 90, 46,166,226, 72, 15,185,145, 85,148,125,140, +157, 33,112, 65,207,191, 12, 22,154,154,105,186,222,247, 31,180,221, 97, 94, 56,192,111,159,206, 67, 34,169, 55, 85, 83,193, 76, + 5,117,173,235,138,250,144,224,102,115,187,105,206, 15,193,255,124,253,245,180,123,120, 25,254, 12,202, 38, 47, 25,161,129, 22, + 98,183, 12, 98,239, 14,150, 84,190,109,192,236, 85, 28, 9,202,123, 33,212,160, 4, 69,231, 32, 61,141, 17,133, 4,118, 14,232, + 28, 47, 69, 7,245,105,115,182,233,190,118, 85, 87, 27,109, 7, 63, 56,199,233, 86,143,203,132, 68,194,116,253, 21,128,178,171, +233, 73, 24, 8,162,179,116, 41,104, 82,176, 7,140,137, 39, 99, 60,120,241,255,255, 6,255, 7, 7,141, 33, 80, 43,221,214,118, +199,157,157,253, 42, 22, 13, 92,129, 64,191,222,206,190,121,243,158,188, 8,202,197,121, 41, 76, 10,244, 48,158,184, 73, 53, 54, +127,227, 58, 70, 78,134,138, 98,121, 26,120,140,209,153,201,121,252, 70, 30, 54,102, 27,249,202,194, 2, 61,168,129, 36, 43,219, + 22, 94, 10,226,190,204,233, 43, 37,222, 46,244,161,234,143,131, 85, 30, 33, 44, 36,225, 90, 99, 77, 99,231,212,185,160, 77, 84, +103,187,212,117, 7, 95,157,126,190,223,108,119,111, 50,227,223, 53, 53,187, 30,190,117, 77,145,147,110,156,177, 77,198,125, 89, + 43,162, 44, 38,102,158,217, 64,167, 11,164,137,158,144,144,169,136,226, 24,242, 88,228, 18, 22,176,211,111,127,121, 42,222, 73, +162,147, 28,243, 54,129,133, 28, 56, 59, 9, 98, 52, 96,206, 18, 73,192, 43, 95,182,244,201,149,106,146, 88,168,107,251,199, 66, + 90,172,217,109, 20,148, 56, 40,239, 54,197,107, 85,149, 51, 27,126,107, 87,136, 84,181, 57, 41,225, 47, 1,214,203,114, 71,102, + 98,218, 53,110,236,163,223,182,123, 6,247, 39, 83,221,203, 89, 43, 50, 76, 54,212, 98,234,120,157,135,170, 53,250,142,108,187, +107,155, 7,182, 97, 52, 45, 25, 24,113,246,146, 12, 54, 7,152,222,137, 26, 4, 68,111,163,127,217, 75,246, 3,153,121,191, 96, + 6,174,176,199, 71,116,185, 37,206, 22, 76,240, 98, 99, 99,105,236,160, 71,112, 48,115, 44,181, 39, 35,241,215,204, 37, 78, 75, +122,194, 50,192, 68,211, 9,178,139, 83,159, 46,127,222, 92,145,236,203, 73, 72,251, 19,113,244, 96,226,160,195,234,168, 3,172, +195, 0, 34, 17,188, 39, 13, 12, 28,213,221, 40, 18,100,247,211, 46, 24,150, 19,223,236,133,212, 25,198,251, 97, 14, 56, 17,143, + 55,253,234,176, 61,215, 74, 60,167,220, 75,216,121,183, 23,188, 89,174, 26,213, 88,181,140, 52,101, 50,131,187,129,251,135,213, +227, 42, 47,204, 7,106,117,120, 63,126, 84, 4,238,138,163,167, 25,190,204, 87,230,146, 22, 3, 27,246, 76,242, 71, 52,207, 28, + 41,165, 5, 25, 63, 8,231, 81,196,146, 60, 22,122,245,118, 48,130,231,212,156,151, 15,106,239,210,209,215,216, 41,213,212,237, +190,200,215,166,244,236,116,115,236, 63,205, 91, 11,177,108,176,177, 85, 90, 6,126,152,152,111,188, 31, 1, 72,187,150,157,134, + 97, 32,232,181,157, 7,105, 90,144,144,202, 29,206,252, 2,255,255, 5,252, 2, 2, 9,209,150,148, 18,146,216,120,215, 94, 39, +105,154,138,199, 53,135, 68,114,146,217,209,206,206,172,254, 15,115,135,121,148,233,198,106,245, 41,136,159,134,254, 40, 57,224, + 32,158, 6,177, 96, 43, 97,100,139,152,180, 14, 57,223,153, 55,245,244, 52, 35, 19,201,165,192,165, 64, 47, 31,120, 90,238,205, + 64,219, 60,126, 90,223,130, 40, 8,128,182,109, 47, 33,102,157, 3, 50,171, 20,206,167,231, 26, 74, 9, 36,156,238, 90,210, 60, +124,202,135,150,193, 76,230,161,121,207,147,239, 29,163, 97,194,109,110,134, 46,188,210, 50,255,165,161,111,164,204, 25,255, 16, +222,217, 84,243,196, 97, 44, 9,127,136,127,177, 3,215,143,228,201,116,143,179,121, 16,214,225, 61,176,111, 52,226, 82,201,193, +111, 91,135, 60, 13,247,104,168,133,169, 5, 84,116,164,121,216, 24, 30,154,242,254, 11,202,232, 41, 43,220, 27, 46,175, 46,116, +182,130,253,246,235,166,148, 85,237, 42,162, 73,236,208,121,116,218, 86,119,159,167,175, 54, 71,224, 83,156,185,132,101, 83, 44, +132,125, 80,112,157,166, 21,168, 39, 40, 73, 75, 55, 29,119,182,143, 60,207,214, 14,229,193,163, 9,119, 14, 99,233, 57,123,128, +164,208, 61, 96, 78, 60,234, 14,199,148,152,238, 71,150,221, 51, 40,207, 75,154,226,180, 15, 57, 96,100,236, 44,134, 81, 73,110, + 31, 70,223,147,239,190,251,109,175,209,113, 18, 25,174,128,217, 96,162,193, 62,169, 16, 48, 99,166, 42,129, 61, 11,238, 12,172, + 48,129,117, 24,131, 32, 35, 59, 49, 33, 66,248,161,143,106, 36,159,198,252, 63,232,203, 79,136,190, 55,140,236,102, 20, 98, 24, +211,102,236,113, 46,208,204, 78,161,217, 81, 72, 99,225,247,142,203,168,131, 16, 34,137, 26,247,184,161,166,154,128, 78,165,118, +252, 93, 73,117,183,188, 93, 47,214,181,227,207,162,125, 62,188,109,155,221, 1,153,187, 97, 22,226,247,116,169, 76, 23, 25, 54, +118, 13,180,178,177, 77,131,107,205,171, 60, 41, 58,165,154,182,137,241,214, 49,166,159,178, 36, 48, 0,133, 82,240,172, 9, 81, + 76,134,124, 80,152,248,227,126,204,189, 61,108,234, 13, 85, 76,119,107, 60,240, 66,148, 75,149, 86,221,134,100, 75,229,101, 36, +127,140,223, 2,144,118,109,187, 9,195, 48, 52, 78, 82, 74, 5, 26,131,151, 77,218, 55,236,255, 63,107, 76,136, 91,201,101,182, + 19,167,105, 87,134, 52, 30,145, 64, 42, 77,114,236,216,199,231,216,103, 48,253, 81, 50, 62, 74,228,103,179,248, 74,203, 31, 96, +170,164,154, 14, 64,150,139,185,115,210, 64, 87, 61,238, 88,165, 27, 70,244,226,137,112, 13,132, 96,124,243,129, 85,116,123, 31, +247, 21,221, 34,140, 23,150,196, 88, 16,185, 48, 92,106, 76,174, 72,249, 97,169,117,160, 25,126,240,217,215, 89,185,204,135, 84, + 74,220,180,211,159,186, 84, 70,169,150, 63, 26,145,154, 49, 50,212,154,176,187,231,205,189,224,199, 54, 82,115,231,197, 0,230, +206,211, 79,122, 9, 57,253,127, 70,242, 70, 11,113,145, 0,131,239,228,148, 25,238,164,253, 90, 52,123, 60, 21,154, 20,119, 8, + 18,160,107, 46, 38, 39, 49, 93,170,209,119, 34,154, 86,178,114, 12, 3, 11,198,247,205,218, 46, 95,154,143,221,146,138,127,193, + 95, 61,217, 54,123, 41,239,168, 57, 45,211, 79, 3,199,102,139, 95,196, 56, 74, 83,255, 58,179,228, 48,248,158, 48, 55,105,186, + 61, 6,158,104,217,248, 45,132, 42, 99,157,101,190, 14,227, 48, 73,110,178, 38,201, 36,113,223, 66,224, 75,230, 46, 48,113, 72, +141,106, 92,147,145,250,243,195,153,245,191, 80,190,130,120,113,228,128,164,126, 26,138,138, 36, 51,104,240, 72,155,172,158, 96, + 6,114,118,132, 18,147, 68,119,120, 82, 62,154,105, 90,149,179, 16,126,151, 98,102,118, 8,148, 9,172, 98,245, 55, 42, 97,133, + 65,166,113,164,246,161, 10,178,151, 48, 57, 70,246,124, 16, 93,186,142,196,170,251,231, 99, 28, 36, 7,202,248,146, 48, 63,105, +162,109, 82,112,143,119,192,253,201,153,213,248,128,236, 17,179,122, 44,121,177,120, 82, 13, 3,107, 84, 99,117,139,187,250,173, +123,127,109,119,206,135,133, 49, 95,231, 67,127, 59, 1,165, 71,244,186,220,160,133,142, 11,104,140,182, 8,241, 76,166,180,206, + 93,143,225,124,193, 75,127,127,110,155, 46,153, 10, 24,185,122, 42,246,195,104,201, 13,145,173, 53,165,230, 28,114, 11,132,216, +212,144, 59, 43, 9,187,129, 53,238, 41, 15,116,241,182,134, 21,216,205,193,125,115, 59,208,240,147, 19,207,245, 71, 0,210,206, +104, 55, 97, 24,134,162,113, 72, 41, 42, 76, 76,236, 97,210,248,131,253,255, 15, 77, 72,123, 69, 19,171,170,173,141,179,216,137, +147, 16, 86, 84,137,190,211, 7,218,222, 56,206,245,185,230,193,178,253,254,223,228,106,168, 97, 61, 12, 85, 84, 34,181, 85, 82, +203, 76,199,253,199, 32, 47,129,117,165,127,129,233,154,144, 72,127, 5,122,219,239,222, 47, 51, 65,166,169,180,164, 37,129,105, + 97, 29, 5,247, 41, 99,204,199,249, 87, 75,187,144,204, 39, 72, 40,221, 45,167,241,165,155,255,136, 34, 43,105, 91,167, 92,236, +100, 61,180,133,127, 81,179,223,198,176,184,135, 73, 87, 23,103, 65,161,229,231, 42,120,131,136,255, 93,238, 19, 72, 89, 31, 99, +177,129,104,233,182, 94,142,129,153,153,192,129, 74, 80,108, 50, 92,207, 67, 94, 77, 54,219,168, 55, 82,118, 28,104,214,212,133, +248,230, 38,118,240,233, 83,108, 89,179,122,255, 67,218,176,172, 15,251, 14, 71, 36,150,154,131,139,115,157, 85, 95, 55,132,178, +112,189,107,117,216, 29, 62,209,215, 65, 72,211, 99, 58, 19,190, 2,178,124,112, 77,120,227, 19, 69,108,110,182, 75,216,186,241, + 4, 22,197, 2,137, 69,217, 30,241, 41,220, 79,118, 57,150, 89,212, 28,231, 78,170,243,188,204,242, 42, 94, 87,125,109, 37,221, +165,232,154,201, 37,188, 74,132,177, 16, 91, 4, 43, 85, 74,188, 16,134,175,145,138,233,100,183, 10, 32,132,235, 0, 71, 92,146, + 2, 65, 31,227,164, 98,132, 1,132, 62, 86,189,215, 73,145,217,152, 23, 58,200,199,210,255, 40,123,182, 29, 9,159,222, 21, 59, +239, 74,220,115,183, 61, 25,240,111,197, 93,205, 84,238, 15, 94, 26,244,241,249,120, 58,159,102, 36, 78, 7,194, 12,143, 50, 25, +234,201,104, 95,188, 83,152,228,174,217,191,108, 94, 7,180, 79,134, 6,242, 98,186, 30, 33, 68, 77, 56, 48,200,243, 23,224,171, +125, 95, 28, 54,173,241, 66,175,251,177,239,167,193,226, 52,232,137, 18,212, 9, 43, 59,217,156,176, 9,210, 62, 35, 0, 10,218, + 21,103,198,133, 55,153,104,170,225,100,218,242, 50,192,218,200,222, 29, 38,181, 48,236, 98, 92,235,205,214,184,193,126,115,148, +227,138,253, 41,248, 39, 0,107,231,178,211, 48, 16, 67,209,241, 76, 58, 67,104,139, 0, 9, 22,101,193,255,255, 19,107,132,144, +128, 13, 82, 75, 50, 15, 98,123,156, 76, 30, 4, 16,116,221, 74, 73,212, 56,246,117,238,185,213,127, 93,175,117, 60,153,154,149, +248,223, 18, 40,211,218, 88, 6,197,170,109,130,151,159, 13,151,105,100,151,159,127,188, 8,214, 91,164,196,192, 77,237,246,206, + 61, 60,189, 33,119,145,153, 32, 4, 31,121,137,213,161, 10,143,190,121, 23, 61,106,210, 50,123, 97,246,114, 11,127,146, 35,179, + 18, 83,167, 36, 46,181, 25, 42,114, 87,118,177,113,222,101,132, 16, 22, 86, 43, 85,200,255,224, 69,120, 93,232,239,236, 44,221, +210,249, 19, 60, 0,211, 6,108,102, 75,225,232, 64, 35, 66, 58, 71,223, 51,215, 24,221,199, 23, 68,226,166,109, 98, 56, 42,211, +170,120, 41,235,120, 79, 39, 2, 57,230, 25, 11, 51,146,175, 61, 50,194,238,174,235,166,105,145, 80,246, 17, 94, 79,136,151, 1, +217,181,150,199,124,175,212,109,125,241,156,182, 21,229, 86, 23, 14,210,222,200, 52,212,243, 34,178, 39,138,172,161, 75,149, 0, +178,211, 38,228,247,126,217, 30,145, 29,107, 82, 53,162, 88,132, 36,201,104,112,197,124, 77, 47,129,162,255,128,233,170, 88,175, + 44,144, 74, 35, 84,182, 61,167,156, 64,147,178,175,169,207,132,231,152, 85,114,107,131,132,133, 6,206,147, 84, 5,105,244,219, +155, 98,237,107,176,220,188,143,149,153, 40,185,219,227, 21, 69, 26,228,151,217, 83,117, 50,251, 76,138,123, 14,242,200,237, 93, + 28,119,238, 48, 94,165,142, 53,153, 5, 89,102,145,181,247, 39,122, 45,197,148, 44, 22,119,149,135, 90,205, 18, 54,254, 69, 17, +116,170, 13, 88,163,187,123,194, 94,185,131, 51,174,187, 62, 22, 76, 27, 61,165,155,128, 49,149, 67,164, 76, 27, 9,138, 15,253, +211, 15,127,142,239, 46, 56,115,182, 65, 19, 77, 55,250,123, 82,105,212,222,238,121,199, 10,185, 21,236,253,186,137,211, 38, 80, + 27, 66,231, 83,164, 38,137,179,177, 2,111,155,169,241,231, 5,120, 54, 17, 6,148,118,218,238, 8,107,179, 59,250,163, 97,208, +157,130, 79, 1, 72,187,178,157,134, 97, 32,232,221,117, 46,170,130, 42, 1,226,129,255,255, 55,120,168, 84,142,182, 57,108,147, + 93, 31,113, 32,105, 5, 84,125,168,170, 86,121,136, 61,158,236,206,206,232,191, 65,249,213,178, 12,172,127,185,148,119, 5, 23, +122, 29,234,186, 81,156,203, 20,109,106,138, 6, 73,181,232,108, 2, 93,244,254, 87,204,118,218,168,245, 46, 17,239, 55, 85, 55, +208,203,123,215, 20,133, 13, 50, 50,190,192,222,142, 55, 92,111,141, 61,186,193, 3,217,249,135,230, 44,117, 41, 77,172,212, 83, +244,133, 79, 51,174,165,144,119, 41,187, 51, 95, 16, 97, 37,214,124,245, 17, 76,135, 86, 37, 91,202,235, 44, 50,193,122, 37,239, +173, 20,220, 41, 20,130,240,228,179, 8, 98,156,200, 13,231,240, 66,193, 51, 23, 56,162,115, 47,221,191,179, 24,212, 54,154, 91, +205, 90, 97,163,169, 29, 76,109, 65,168, 4, 47,183, 15,182, 91,240,226, 25, 50,242,204, 49,174,217,222,185,195,103,127,251, 80, +238, 54,229,235,190, 35, 50, 13,113, 83, 91,103, 81,130,254,245,168,212,115,179, 61, 20,119,192, 70, 19,144,203,169,178,105, 76, + 84,110, 38, 61,143,106,138, 89, 37, 63,164, 74, 68,149, 5,123,174, 72, 12,142, 11,134, 43, 1, 53, 76,252,107,200,168,179,223, +148,118,151, 34,227, 35,178, 39, 75, 26, 88,164, 23, 48,251, 20, 29, 7,226, 73, 25,146, 25,236, 68,225, 65,105, 23, 77,116, 98, + 68, 28,138, 17,128, 14,185,178, 78,121,145, 52, 96,230,179, 97,215,144, 27,112,141,239,172, 69,119,242,172,216, 4,238, 32,114, + 76, 55, 89,103, 39, 67, 71,249,221, 2,136,255, 58,161, 52, 49, 57,175, 11,180, 19, 23,243,227, 75, 6, 50, 3, 52, 55,223,212, +139,207, 79, 26,169,179,255, 10, 22,131,149, 29,228,226,237,211,194,241,145,203,238,220, 80, 45, 56,160, 3,118,205, 19, 1,141, + 80, 90,143,132,158,105,182,183,180,162, 26,171, 66,213, 6,173, 26,222,206,170, 19,246, 99,125,144,183, 24,205,114,163,203,231, +145, 27,225,224, 39,215, 86, 67, 73, 52,158, 16,189, 24,203,184,184,199,249,196, 0,111, 75,199,233, 89, 90, 44,208,253, 0, 28, + 66,214,127,177, 97, 81,216,148,108,193,100,209,154, 2, 75, 71,208,155,163,119, 53,255, 18,128,180, 43,217,105, 24, 6,162,241, +146,180,164,105, 37,122, 64,220, 56,244,255,255,128, 79,225, 74, 15, 64, 41, 82, 11,117, 22,219,204, 98,199,105,186, 32,160,199, +168,178, 34,103, 60,158,229,189, 55,127,140,223,127,236, 71,159,229,190,102,169, 86,115,169,204,147, 44,176, 87, 84,240,215, 60, +251,104,113,127,236, 5, 18, 98,179, 63, 3, 59,248, 72,180, 67,251,203, 47,175, 89, 4, 81,171,187,106,186,186,175, 30,159, 62, + 20, 99, 34,124,234, 76,195,106,175, 78, 62,228,170,109,236, 38,142, 58, 58,187, 3,252, 5,234, 88,143,102, 25, 50,134, 24, 50, +131,137, 26,170,136,149,211, 20, 74,207, 50,185, 40, 48, 19,116, 40, 8,221,238,233,101, 14, 87,181, 36,135,199,137,169,164,139, + 76, 44,208,133, 40,227, 81,166,145, 29, 61, 88,210, 82, 9, 84,177,147,106, 78,237,132, 70,194,237,130,138, 24,144,169,204, 20, + 50,164,193,148, 74, 37,182, 52, 75,178, 16,222,214,178, 54, 93, 23, 65, 16,224,246,225, 98, 32, 81, 29,140,253, 49, 9,144,162, +235,220,219,246, 80, 84,170,204, 53, 5, 59, 88, 31,249,140, 44, 42,254, 65, 26,177,130,100,168, 90,110,197, 28,140, 81,163,216, +174,198,234, 12, 70,136,196,133,244, 54,225,100, 2,192, 34, 12, 81,226,230,234, 88,233, 49,196,251,228,137,108, 24,182, 55,100, +205, 7,231, 30,149, 14,122, 42,205, 16, 45, 46,252,209,170, 1,252,157, 37,133,105, 63, 64, 9,136,203,221,236, 17, 88,145,240, + 49,204, 92, 18,146, 37,163, 73, 56,140,197,240, 28, 63, 29,244,158, 56,132,247, 16, 40,160, 58,129,236,211, 0,123,101, 8, 0, +221, 25,248, 87,217,207, 43, 78,102,224,143,207,205,168, 36,234, 66,128, 19, 57, 70, 46, 86,102,226,192,147, 40,232,232, 78,106, + 47,191,109, 2,249, 52, 22, 49, 72,255,186,190,230, 62,224,166,158, 2, 49, 71,125,224,147, 36,251,127,206, 29, 2,240,214,214, +231,114, 2,230, 36, 4, 97, 61,194,188, 35,167,137,120,170,186, 84,183, 83, 93, 58,186,119, 39,200, 91,199,239, 12,174,191,204, +115,147, 21, 16,147, 47,228,108,170,111,214,102,221,102, 6,246,184,113,109,151,185, 9,216,185,247,207, 95, 47, 27,243,190,179, + 7, 2, 80,130, 43,176,141, 51,112,224, 44, 98,167, 58, 56,143,164, 23, 42,104, 50,150,239,245, 63, 88, 34,169,200,114,200,149, + 91,156, 34, 1,254,129,143, 67, 16, 83, 21, 72,128,118, 68,131,102, 45, 74,196, 23, 21,106,162,164,168,173, 41,100,241, 45, 0, +105, 87,178,155, 48, 12, 68,109, 39,206, 2, 41,203, 1,245,212, 67,197,255,127, 79,111,189,209,170, 82,213, 2, 45, 91, 98,123, +234, 25, 59,198, 9, 75,183,136, 19, 7,100, 12, 30,207,242,150,127,245,103,126, 2, 98, 63, 27,226, 35, 9,145,240,235,118,114, + 41,213,151,120,238,151,129,230,140,164, 37,143,162, 60,239, 53,255,117,155,222,126, 48,113,135,123,135,255,143,186, 85, 2,232, + 61, 36,229,200,166,185,156,207,170,197,202, 60, 60,111,115, 41,180, 19,212,107,143, 2,199,184, 9,143, 38,189,151,192,155,230, +201, 75,116, 94,108, 43, 5,141, 45,211,102,241, 77,139, 19, 39, 76, 36,162,116, 82,140,155,162, 74,112, 88, 63, 40,132, 1,181, +170,213,158,193,175,140, 53,110,232, 53, 78,249, 40,147, 26, 68,161, 1,209,144, 32, 86,100,217, 91, 73,164,236,230, 9,212,164, + 50, 54, 73, 81, 21, 95, 10,155,164,160,171, 24,197, 26,190, 19,182, 52, 65, 66, 71,153,128, 77,198, 7, 41, 95,215,201, 90,233, +141, 65,112, 75,112,155, 76, 73,186,221,110,224, 70,195,226,237, 48,172,146, 26, 84,134,147, 89,172,253,221,101, 86, 18, 66,233, +214, 46,169, 24, 65, 62,126,199,224,207, 36, 39,197,118, 55, 0, 23, 32,140, 48, 29,201, 70,195, 34, 3, 45,237,169,153,167,115, + 78, 19,232,154,173,158, 59, 4, 39, 85,104, 27,238, 45,228, 47,192,168, 3, 50,239, 88, 6, 4,142,113,152,207, 71, 32, 10,207, +104,101, 87,133, 77,226,252, 15, 34, 65, 69,212,158, 35,161, 35,240,198,115,112,218,162,225,206,235,129, 26,190,206, 13,131,123, + 23, 3,184,154,126,226,151,208,116, 31,185,225,180,233, 66, 23, 67, 40,239, 95, 66, 60, 78,147, 59,114,188, 16, 48,136,208,155, +205, 2,251, 83,254,126,130,237,225, 81, 19,198,176, 35,211,146,157,210,151,216,229,228,253,252,188,238,187,135, 42, 78,127, 64, + 15,250,112, 57,163,247,201, 59,250,117, 56,182, 42,114,154,240,141,105, 49,195, 62, 8, 40,157,242, 61,215, 50,245, 24, 33,180, +245,192,122, 27,121, 70,147,108, 84, 38,243,117,179,220,169,221, 80,150, 85,146,229, 40, 61,178,124,253,124,217,106, 68,199,187, + 22, 0, 50, 31,161, 41, 52,182,236,181, 38,221, 76,180, 17,194,126,140, 12, 33, 11,108,209,172,221,190,208,226,115, 66,126,248, +118, 60,141,107,104,157,158, 93,142, 19,121,123,186,148,253,112,165,114,153, 9, 4,249,193,151, 0,172, 93, 75,111,219, 48, 12, + 54, 41, 75, 78,215,100,109,177,165,235,122,217,125,251,255,192,254,200,142,187,183,151,162,104,220,198, 15, 89, 28, 73, 73,137, + 93,123, 65, 6,236,152, 67,226, 4,145,168, 79,228,247,248, 15,250,166,127, 2,242,115,239,248, 49, 53, 42, 90, 46, 81,214, 19, + 46,166,134,207,141,226,222, 9,169, 38, 98,168, 81,216,194,225,222,247, 80,192, 29,184, 31, 5,237,200, 51,244,174, 71,147,207, +168,247,249, 84, 20,247,174,250,126,119, 3,214,253,252,165,180,119,205,197,212,185, 53,102,126,152,124, 44,191,241,119,176,223, +202,226,214,247,140,103,159,207,152,236, 15, 35,187,152,242, 72,169, 36, 61,177, 41,182,236,175, 12,110, 63, 84, 77,215,251,140, +241,207,161, 96,155,220,239,230, 87,155,202,221,174, 45, 18,223, 28,161,239,232,169,165,181,114,197, 90,128,181,163,107,203,181, + 88, 66, 54,120, 89,241, 50,221, 88, 89,211,206,224, 85, 85, 94, 90,149,232, 33,131, 14,134, 0, 34, 38,121,220, 53,245, 91, 83, +183,254,169,243,221, 32, 11,104, 5,184, 19, 18,209,129, 39, 44, 33,181,245,139,103,192, 98,251,240, 49,224,214,192,198,211,202, +192,118,101, 26,179,217,153,203,189,168,121, 52, 18, 65,183, 57,196,240, 6, 37,204, 16,166, 20,185,172,186,135,225,216,194,165, + 44,184, 95,232, 51,100, 79,173,212,118,167,163, 5, 87,108,222,100,234,217,212,222, 36, 22,154, 48,173, 27, 48,182,237,154,172, +222,133, 46, 1,254,149,170, 20, 70,165, 7,115, 42,141,176,132, 98,228,216, 33, 7, 94,202,183, 86,121,229,192,129, 58,102, 80, + 72,145, 17,209,138,203,159,250,175, 49,145, 39,147,141, 59, 1, 78,191, 4,193, 72,248, 52, 27, 29,231, 27,114,200,193,126, 71, +186,209,172,184, 19,205,118, 47,156,154,181, 77, 26,104,211, 3, 37, 31, 55,148, 83,182, 19,169,105,178,193,223, 5,159, 46,130, +119,135, 86, 2,143,150,195, 89, 78,236,187,225, 28, 72,154,161, 5, 3,106, 6,213,194,137, 52,146,135, 90,124,190,184,151,244, +153,208, 1,150, 93,240,174, 48, 46,136,125,100,201, 16,200, 24,212,152,130,166,111, 90,223, 34,186,155,234,250,235,197, 23,254, +125,207,175, 15,111,253,235, 94,252,103,106, 47, 12, 62, 31, 53,115,154,153, 60,180,212,201,147, 18,115, 16,194,128, 26,228, 38, +141, 29, 27, 93,141,210,108, 41,221,127,202,162, 84, 56,168,129, 31,169,201, 81, 26,189,103, 36,139,183,108,193,197,135, 6,159, + 76, 45,237,255, 8,192,218,213,244,180, 17, 3, 81,219, 99,103,119,147,109,137,128, 30,138,132,122,226,200, 63,239,127,233,185, +135, 10, 9, 36,122, 64,136, 64, 9,155,100,237,153,122,108,175,227, 77, 2,180, 18,199, 68, 81,178,218,172,159,199, 51,239,227, + 99,230,171,255, 85,200,103, 81,146, 44,189, 7, 18,207,193,137, 93,235, 18,218, 9, 68, 63,232,126, 67, 99, 33, 85, 30,222, 98, + 54,215, 27,168, 53,225,206,210, 53,209, 84,170, 11, 83,159,147,242,255,214, 2,125,153,236,113,214,205,216,123, 75,127,105,155, +203,111,243,171,174,255,254,227,183,199, 58, 0,158,217, 57, 84, 49, 22,176,120,234,217,234,198,127,219, 47,212,167, 32,190, 58, +238, 54,175, 69,138,251,120, 23,142,221, 72,147,194,237,142,192, 24,161,165,131, 79,214,181, 70,207,155, 74,117, 29, 13, 68, 26, +255,153, 99, 33,206,185,166,144, 29,239, 53,226, 94,224,141,160,151,196,186, 73,119,149, 27, 65, 0,103,173, 62,157, 79, 13,176, +138,249, 97,233,145,213,250, 35, 91,205,162, 45,226,124, 25, 96, 23, 7,195, 36, 32,229, 97,221,104,117,210, 76,218,137, 60,153, +177,169, 53, 7, 66,106,211, 84,218, 84,198, 0, 60, 46,186,199, 63,171,171,251,231,249,178,123,232,214, 43, 71,154, 67,127,120, +133, 25,160,217, 4,206, 62,195, 81, 51,169, 64, 78,107, 38, 7,191,180,245,207, 39,185,114,234,206, 86,183, 54,144, 59,253,143, + 70,227,129,200,200,141, 82, 30,127, 70,181, 50,199, 40, 97,193, 80,140,114,160,109,111,101, 76, 23,193, 98, 28,131,217,190,112, + 72,162, 72,137,110, 56, 12,243, 48, 23, 4, 37,121,131, 50,112, 28, 80, 11,141, 98, 6, 14,116, 40,156, 24, 21, 41,165, 9, 71, + 97, 93,128,169,207, 66, 41,218,221, 69, 35,177, 88,194, 51,249, 86, 15,188, 73, 18,219,204, 62, 26, 70, 70,251,155,136, 42,104, +221,209,176, 71, 15,226, 32,114,242, 93, 74, 66,129,207,140,236, 57,228, 58,103,209,238,128, 59,109,239,209,216, 40, 61, 53,144, +222, 88,247, 50, 53,134,229,118,217,202, 67,180, 93,220,187, 60, 42, 90, 40,205,218,117, 56, 46,216,227,203, 8,238,251,147,240, +127, 60, 92,208,171, 91, 83, 60, 97,248, 90, 93,134,226, 93,242, 90,224,231, 85,212,208, 54,186,117,110, 99, 49,148,220,128, 65, + 48,202,218, 72,191, 9,104,235,235, 33, 15,241,170, 23,182, 39,127,117,171,231,126,129,140,101,184, 97, 83, 95,134,181,158,237, +124, 83, 46, 89,156,139,134, 55, 45,155, 65, 18,183,246, 33, 60, 15,148,178, 2, 66,160, 74,232, 14, 25,161, 55, 65,193, 28,246, +126, 21,186,172, 38,159, 95, 69, 18, 9, 5, 41, 39,135, 2,166,146, 49,250, 83, 86,170,254, 43, 0,107,231,182,211, 54, 16,132, +225,217,131,215, 54, 77, 82,226, 74, 69,136,162,158, 37,158,128,167,230,158,135,224,174,247,149,170,162, 86, 13, 16,176,130, 72, +236,120,179, 83,207, 30,156,181, 9,130, 74,125,129, 72, 86, 70,179,179,255,252,251,253,255,205, 63,243, 79,103,128,137,218, 49, + 70, 65, 60,143,206,237,221,183,182,157,133,199,122,231,191,219, 63,108,165, 61,230,230,169, 96,126, 18, 4,116,220,124,163,151, +173,252,115,158,188, 21,105, 33, 69, 42,132,146,140, 39, 73, 9,250,236,199,237,124,185, 86,228,107, 2,143,165,182,150,203, 16, +255,135, 91,149,136, 8,206,236, 15,240, 49, 75,191,160,158,129, 94,134,240,163,213,115, 69,102, 34,193,148,123,211,133,153, 67, +157,175, 77,185, 88, 77,115,229,182,193, 83,194, 8,139,211,105,113,114,188,127, 49,187, 62,159,149,115,219,241, 39, 0, 31,129, + 23, 32,191, 67,115,239, 79,120,104,199,134,247, 74, 78, 94,165,239, 14,198,121, 59,123, 84,186,200,244,186, 78, 26, 34, 92,152, + 70,243,170, 29,213, 57, 77,143, 57,153,122, 97, 36,165,146,124,148,202, 44,229,175, 51,149,229,170, 49,244,190,238,242,182,186, +250,121,125,121,179, 40,151,245,155,145, 58, 62, 40,190, 30, 29, 94,221, 45, 87,117,211,150,115, 42,219,202,198, 81,130,119, 53, + 46,144,107, 20,191,239,245,175, 7, 44,169,158,137,141, 68, 65, 76, 27,194, 40,146, 8, 13,194, 82,182, 88, 64, 10, 9,231,184, +235,190, 29,131,236,238, 5,148,174, 47,116,116,224, 94,130,133,119,236, 5, 17,217,225, 7,224,169,225,157, 5, 35, 60,108,221, + 26, 96,162,102, 50,108,239,248,172, 57, 58,110,150,189,169,223, 34,136, 89, 68,221,233,152, 51, 17,149,151, 57,230,150, 17,232, +184,240,220,199,183, 51,214,201,232,216,211, 84, 88,124,193,112,224, 49,251,145,154,130,225,156, 8,223,223,247,236,158,125, 29, +120, 0,182,177,121,161,185,227,176,185,187, 4, 84, 51,252, 9, 30, 36,115,159, 23,183, 75,130,197, 39, 87,172,172,255,112,105, + 56,188, 15,142,217,202, 54,247,151, 8, 53, 93,247,207, 69,246,176,169, 94,110,221,134, 71, 73, 53,204, 3, 26, 29,134,156, 39, +246, 47, 73,197,228,195,248,211,138,158, 35,145,224,214, 24,172,117,181, 39, 20,221,115, 29, 86,211,198, 97,147, 95,192,208, 66, +220,208, 30,149,226,150,236,199,106,109, 61,142, 33,190,211,243, 42,172, 1, 6,237, 29,216,154, 84,219, 75, 43, 5, 9, 48,231, + 0,144,182,124,108,166, 7,154,136,130,167,195, 90,222,101,243, 56, 8,169,123,109, 78,186, 60, 45, 98, 18,193,136,153, 67,123, + 95,162, 76,178,191, 2,208,118, 45,185,109,195, 64,148,164, 40, 75, 70,163, 38,112, 12, 24,104, 29, 20,217,116, 83,244, 2,217, +231, 2, 57, 95, 47,209,109,114,130,172,178, 46, 80, 36, 93, 20,104,190,112, 28,196, 54,164, 80,195, 12,103, 72,153,180,157,207, +166, 94,121, 33,255,104,106, 56,111,230,205,123,250,127,132,239, 55,175, 89,169,210,216,110,202, 57, 89,253,205,168,205,190, 64, +150, 18,137,122,101,151,200,219,148,234,182,236,196,102,142,174,100,112, 35, 95, 44,154,223,124, 24,176, 11, 27,254, 81, 0, 89, +166, 49, 11, 38,227, 3, 95,235, 12, 55,190, 81, 30, 58,217,168,243,230,190,224, 84,192,163,212,123,206,151,197,252,165, 94,135, + 14,227,172, 98,125, 54,124, 83, 74,216, 80,228,187,167,145, 38,121, 47,198,173, 24, 23,229,172, 94, 20,194, 14, 85, 89,103,226, +248,207,213,233,195,195, 93,184,248,150, 46, 62, 44,242,163,178, 58,153, 78,230, 2, 10, 33,119,100,158,151,189,253,207,187, 7, + 95, 71,147,155,197, 84,212,117, 83,171, 18,116, 11, 91, 10, 79, 53, 49, 80,184, 51,179, 92,169, 39, 34, 40,126,196,253,219,215, +101,137,128, 84, 92, 78,235,243,139,219,235,201,227, 13,230,236, 77,139,187,185,234, 23,223, 71,219,223,198,131,159,191,254,253, + 56, 59,191, 18,142,238, 59,116,211,167,249,238,206,224,206,124,152, 67,238,228, 0, 92,221, 30, 17, 66,219,227,230, 40, 62,179, +236, 52,173, 98,186, 55,145, 0,104,228,154, 69,189,164,149,105, 25,129, 39,246,162,106, 9,216, 40,203,230, 23, 65, 8,195,113, + 5,121, 57, 47, 35,188, 88,110, 72, 16,109,100,232, 28,202, 62, 54,230,105,192,186,156,245, 90,190,241,110, 74, 70,240, 83, 50, +174, 34, 43, 35,120, 10,150,219, 46,214, 11,161,114, 69, 78,250, 66,141, 10, 70, 38, 65, 72, 71,110, 78, 49,149,232, 88,163,138, +103,219,153, 61, 3, 1, 18,179, 52, 88,112,181, 78,223,196, 46, 23,186, 83, 13,235, 14,146,216, 33,175,227, 31,181, 41, 68,134, +110,196, 36, 9,241,114, 85, 1, 47,210,117,144,203, 21, 6,155, 52,125, 33, 77,116, 18, 42,228, 59,229, 4,248,145,171,220,209, + 78,220, 96, 93,189, 98, 20, 60,218,250,116, 61,187, 76,181,106, 94,139, 79, 33,191,198,172, 78, 85,189,202, 24,140,191,217, 94, +245,165, 68, 8, 79,150, 98,115, 80, 51,131, 57, 82, 99,233, 19,129,176,178,198, 88, 1,154,188, 62,100, 75,184,136, 44, 10,129, + 41, 52,116, 80,118,193,221, 75,186, 19, 94, 7, 58, 16,100, 38, 28, 49,207,184, 16, 47, 91,175,222,238,105, 75,140,179, 52, 43, +112,250,170, 27,123,192,181,129, 64,194,109,124,252,133, 28,232, 17, 64,184,249, 68,119,215,129,107, 11, 60, 11, 64,218,181,181, + 36, 16,132,209,153, 93,117,119,205, 10,210,110,148, 4,249, 96, 15, 69, 69, 96, 84,255,184, 63, 17,244,216, 99,244, 18, 65, 81, +102,146,105,153,165,235,230,206,126,205,125,103,204,162, 72, 22, 17,113, 69,240,155,153,243, 93,206, 57, 63,233, 3,231,243,249, + 90,173, 86,175,215,255, 51,114,164, 31,213,106, 53, 12,233, 41, 56, 26,123,173,179,225,114,185,188,180,188,212,233,180,191,116, + 38, 97,242,184,194,247,191, 1,172, 37,162,217,198,114,197,238, 31, 29,110,238,110, 55,234,119,156, 34,204,152,169,156, 96, 38, +159, 89,167,209, 21,118,101,142,136, 80,190,123,137, 50, 46, 86, 21, 0,180,119,176,191,177,179,213,188,111,196,244, 75, 32,181, + 29,120,102,224,221, 45, 50, 88, 45,115, 89,109,113, 71,126,215,168, 16,250, 4,125, 4,209, 71,178,224,249, 67,146,188, 2,161, +215,195, 32,188,138,134,237, 47,248, 40, 34,113, 9,156, 15,194, 64,193,138,147, 93, 47, 6,187,149,210,218,204, 84,183, 61,188, +125, 26,244,232,253, 24, 21,114, 52, 64,221,188,159,161, 56,125,218,203,176,186, 77, 14, 7,158, 59, 27,184, 65, 22,247, 6,209, +117,163,123,118,249,120,114,217,186,104,117, 31,250,225, 77, 28,117, 32,246, 25,137, 9,157,191,188, 29,223, 52, 79,223, 7, 33, +130, 34, 66, 21,111,106,185,176,138,253,249,110, 82, 96,202,143, 14,202,136,162,186, 84, 58,101, 66,157, 68, 66,106,108, 96, 73, +129,116,148, 38, 10, 72,205, 79, 57,156, 46, 17,172, 42,177, 0,128, 37,228,104,176, 95,204, 17, 58, 60, 46,230,174, 53, 67,148, + 69,144,238, 34, 26,222, 24, 41, 32, 74,192,132,110,214,245,251,104,135,137,150, 53, 82, 50, 60, 53, 94, 16, 30, 49, 56, 13, 72, +108, 43,110,200,248,196, 63, 47, 40,144, 70, 32, 74,204, 61,149,231, 77, 82,228,147,142,253, 96, 43, 61, 74,147, 37,100,240,152, +164,100,163,105,127,154, 24, 53,244,196, 32, 45, 43,160,132, 29,171, 50, 5,227,211,239, 22, 20,183,236,209,237, 79, 77,104, 15, +252,117, 44, 38, 49,154,196, 38, 96,207,114,101,253,112,212, 87, 57,203,228, 63, 21, 91,197, 25, 36,104,239,172, 56,195, 49, 28, +221, 25, 23,131,213,146, 63, 71,223,137, 70,194,119, 7,124, 87,112,227, 97, 68,132,138, 16,221,232, 99,154,239,210, 13,154, 16, +102,190,193, 49,138,224, 37, 33,197, 12,211,222, 6,140, 96,200,207,105, 71, 37, 49, 44,183,117, 17,214,174,160, 92,186, 93,250, +127,196, 72,184,253, 8,151, 90,125, 76,153,174, 4,150,202, 38,191,157, 79,220,171, 73,194, 79, 1, 40, 59,159,159, 38,130, 40, +142,207,108,219,244, 7,181,166, 8, 6, 69,227,133, 72, 2, 4,216, 11,132,152, 24,255, 6, 99, 82,245, 32,233, 81,251,239,233, +213,179,137, 7, 37,225,104,132, 64, 66,176, 16, 64,183,216,101,119,103,158,243,222,252,216,233,178, 74,220, 76,154, 61,108,155, +201,108,247,237,155,153,247,253,124,255,149,164,168,128,219,239,247, 11, 17,191,215,235, 93, 63,191,241, 8,195,240,221, 96,160, +187,179, 30,134,111, 7, 3,191,186, 89,159,190,120,217, 91, 88,124, 92,128, 50,251,194,244, 27,131,187,143, 61, 40,148,222, 56, +120,233,230,147,173, 87,253, 55, 43,225,186, 53,145, 96,142,246,101,160, 55, 4, 33,195, 79,244, 90, 0,161,149,145, 84,131, 10, +198, 75,158,133, 91,155,207,183, 95, 47,173,173, 74, 74,149, 28,162,157, 27,213, 40,252,192,197,241,234, 60,171, 45,176, 96,134, +240,232, 29,170,201,169, 89,115,165,210, 67,107,157, 18,115, 34, 79, 89,114, 20,143,239,215,155,119, 88,237,130,137,239, 76,156, +148,125,235,140,193,151,228,114,140,198, 29,181,135,211,237,229,123,183,207,207,211,143,187,195,207, 7, 42,125, 79, 84, 96,111, + 85,177,140,163, 81,101,237,186,202, 21,121, 10,188, 59,197, 59, 77,158,102,226,219,113,244,126,231,232,195,215,195, 79,123, 39, +195, 81,116, 32,198, 67,134, 12,250,217, 32,232, 50, 54,130,108, 63,137,127,138,116,174,218,124, 54,117,247,233,244,202,226,236, + 70,171,189,198,235,115,191,161, 73,227, 35,137,167,134, 20,135,140,196,217,106,184, 80,147, 71,152,165, 76, 91, 55, 88, 55, 32, +105,248,226,224, 24,227,228, 75, 97, 44,174,180,237,181,224, 46, 24,217,176,207, 44, 24,197, 10,238,109,145,184,200,183, 7,243, + 93, 59, 74,222,109,222, 14,215, 22, 10,108,112, 55, 10,111,183, 28,175,187,236, 53,176,139, 9, 28,254, 18,247,109, 63,185,231, +241, 43, 11, 50,141,204, 43,199,113,182, 68,224, 40, 94, 28, 76,213,169, 6, 6,154,210, 8,167,216,229, 80,108,204, 26, 29, 57, + 77,191,134, 79,229,215, 8, 83,131,104,126,138,123, 45,112,151,185,109, 13, 67, 69,158, 8,238,110, 77, 95,187,190,112,106,238, +159,207,140,180, 13,172, 93,135,103, 11,203,243,224, 46, 39,109, 67,120, 62,212, 19,143, 60,120, 27, 42,255, 21,220,181, 68,241, + 65,247, 81, 11,141,235, 75,204,116, 51, 35,126,198, 46, 52,130,122,217,141, 43, 95,228, 65,121, 71,165,113,171,209,161, 10,212, +160,130, 12, 72,136,113, 66,143, 89,140, 26,171,113, 38, 46,211,171, 81,252, 43, 74, 46,162,171, 40, 78, 99,169, 39,253,172, 66, + 72,138, 0, 19,121,213, 16,189,193,193, 80,252, 53, 33, 20, 51,113,105,156,199,133, 29, 91, 3, 81,151,228, 96,142, 50, 37, 16, +168,129, 2,245, 62,201, 8, 45,141,209,133, 30, 52,144,142,117, 74, 65,159, 44,122,244, 61,114,166,103,244,226, 1,145, 16, 74, + 94,205, 48,254, 8,192,216,181,245, 54, 13, 67,225,216,105,218,164, 26,176,144, 84, 66,172, 12,161,149,246,181, 47, 60,241, 48, + 9,232,143,157,132, 64, 72,252,143,150,155, 32, 69, 32,113, 29, 18,105, 39, 54, 37, 77,156,196,198, 62,190, 52, 77, 35, 65,158, +226,212, 61,182, 44,231,228,248,243,231,239,252, 27,159, 9,195, 48, 8,130, 40,138,164,155,158,205,102,139,197, 98,181, 90,241, + 24,220,220,123,158,199,227,113, 94, 47,230,133, 56,150,222,159,255,203,196,254,211,233,116, 49,159,167,105,218,184, 15,194,112, + 0,213,100,209, 92,195, 59, 67,183,223,255, 8,141,114, 83, 55,131, 32, 1,251,188, 27, 1,116, 40,210, 63,241,143,144,105,180, +126,141, 38,147, 44,221,244,193,136,193,100,252,112,112,250,228,209,155,249,226,249,217, 83,254,240,100, 50,190,136,215,126, 24, +124,142,150,188,120, 52, 28,242,250,159,150, 75, 45, 10,137, 78, 70,163, 77,154,253,252,246, 67,189,161,240,101, 60, 28,248, 15, + 31,159,190,123,245,250,229,217, 51, 62,164,247,198,247,215,113, 44,140,124, 88,106,102,178,168,122,105, 49, 94, 14,113,231, 8, + 52, 94,127,195,146,202, 40, 47,102,181,253,213, 70, 60, 82,130, 96, 25,156, 59,165,107,154,247,114, 58,246,188,195, 18,191, 45, +184,243,109, 89,103,201,143,211, 45,187, 59,241, 15, 18,187,124,241,254,252,122,215,121,112, 55,244,251,158,139, 17,247,233, 66, +233,222, 21, 57, 27,255, 16,138, 29,188, 41,232,215,203,234,215, 85, 69, 9,177, 25, 57,190,225, 56,183,189,104,157,157, 95,217, +199, 7, 61, 87, 8,101,144,174, 32,127,150, 25,197, 4,119,122, 93,191, 68,131,130,185,185,224,219, 48,194, 3,244,146,183,120, + 77,164,138,164, 73,167, 76,168,181, 1,129, 44, 37,232, 36, 49, 68,153,175, 86, 75,138,138,217, 11, 96,226, 14, 90,192, 16, 82, +212, 23,164,188, 62,210,128,163, 97,169, 83, 80,253,215, 98, 44, 12, 64,100, 5,144, 54,196,220, 21,202,135, 40,211,185,134, 20, +109, 70,147,105,171,122, 20,108, 25,188,167, 53, 21,167,137,241,171, 93,228, 23,105,181, 59,214,182,246, 50, 76,203,173,135,214, +217,192,181, 0,172, 2,232,225,129,204, 62,134,235,137, 57, 36,255, 30,163, 54,141, 1,125,114,170,230, 42, 17,218, 15,129,217, + 78,120,211, 84,226, 99, 91, 52,156,194,241, 84,218,112,238, 90,242,161, 73,124, 67,122,231, 64,171,160,128, 55,171,185,248,125, + 57,101,157, 15, 71,209,222,173,182, 64,222, 44,119,254,223,185,155, 62,125,191,248, 98,181,229,159,104, 52,144,209, 38, 27,210, +115,220,188,200,246,204, 98, 37, 4, 79, 75, 82, 17, 12,164,114,233,109, 25,235, 36, 37,177,169,144, 98, 23, 34, 66,140,191, 5, + 69, 78,114,102, 37, 93,236,240,145,236, 8, 21, 66, 36,121, 44,124, 73, 91, 81, 12,218,194,216, 86,225, 13,108, 65,213, 80, 63, +170,226,113,108, 43, 14, 8,197,234,244, 56, 43,183,137,187,248, 80,151,146, 31,172, 18, 62, 11,149, 2,172, 25,218,146, 83, 75, + 11,109,132, 25,149, 62,152, 3, 5, 76,189,191, 2, 80,118, 53,175, 77, 4, 81,124,102,118,233,106,169, 18, 16,172,164,201,205, +147, 30,139, 70,183, 71,123, 19,130, 23,241,168,129, 42, 40,136,148, 26,104,176,182,164,148, 18, 72,161,215,222,226, 69,240,156, +252, 13, 45, 66,255, 1,191, 21,147, 74,233, 71,172,154, 52, 31,187, 59,227,155,121, 59,251,145,208,138,203, 18, 38, 75, 50,153, + 36,179,191,121,243,126,239,253,222,191,241,189, 84, 42,193, 35, 64,112,177, 88,180,109, 27,218,249,124,190, 90,173, 2,190, 71, +219,248, 20,142,173,205,205, 74,165,114,107,122, 58,155,205, 62,156,153, 65, 20,182,167,166,214,202,229,129,246,131, 92, 14,218, +216,249,106,177, 24, 24,236,247,115,185,155,250,250,122,185, 60,145, 78,131,189, 15,111,132, 43,128,227,128,239,248, 41,181, 90, +237,229,226, 34, 94, 47,204,207, 35,196,227,173,252, 98,105, 9,112, 95,189,254,112,117,121,185, 35, 23, 15,121,227,100,236, 12, +244, 6,103,163,222,248,252,254,227,147,231,179,157, 99, 73,130,174, 20, 22,238,220,187,123,205,190, 1,237,157,122, 99, 99,109, + 29,122,121, 60, 55,155, 76,167,224,202,246,214,219, 55,175, 94,171,123, 75,238,208, 38, 51,215,147,169, 9, 56,127,124,223,249, +242,225,211,163,185,167,216, 73,169,176, 0,139, 1, 82,107, 84, 37, 41,194,177,203, 5, 12,235,178, 97, 94, 33,214, 87,207, 1, + 51,252, 88,205,245, 49,109,167, 27, 10,235,137,134,254,104,206,103, 66, 77,250, 3,238, 30,116,218,169, 17,235,246,185,196, 94, +207,169,187, 48, 49,189, 54,231, 22, 99, 9, 33,206, 8, 58, 70, 13,151,209,111,162,191,221,220, 63,228,226, 34, 33,207,174, 94, +154, 76, 94,216,253,211,221,107,187,191, 61,242,238,168,215,234, 73,198,255, 87,215,147,132,142,162,103,152,116, 58, 73, 18, 66, + 18,200, 63,153,224,163,150,105, 0,192, 2, 84,115, 54,218,243,203, 12,153, 46,183, 92,158,232,123,172,235,181,148, 9,138, 2, + 93, 66, 58,254,100, 2,172,121,214, 26,103,162,219,234,239,195,114,129, 97,236, 92,243,155, 90,142,195,247,199,114, 74,233, 64, +157, 70,225,251,189,148,102, 63,231, 98,192,120,199,242,101, 49, 25,119, 29,245,161, 69, 18, 99, 98, 41,196, 11,162,207,185,136, +150, 24, 13,247, 1, 97, 80, 12, 13,134, 55, 28,132,199,134, 18, 89,163,184,175, 4,162, 13,122,154,174, 65, 36,166,203, 47,204, + 30, 66,188, 10,138,215,107,128, 70,121,157,160,142,177,112,158, 23, 33, 0,240,255, 10,244,106, 34, 96, 20,139, 43,141, 43,213, +156,232,230, 17,190, 3, 87, 96,154,172, 47, 72,207,195,156,163, 32,231, 43,226, 16, 32, 76,187,116, 40,193,162, 90, 52, 72,205, +101, 98, 32,149, 47, 42,239, 46, 68,200,172,198, 4, 33,196, 80, 14,212,255,197,210,199,247, 83, 12,203, 18,200, 25,105, 58,158, +115,186,143, 75,165,253,115,114,114,182, 26, 96,122,223,233, 91,230,136, 4,109,176,177,218,205,212,249,148,197, 72,179,115, 4, + 63, 24,124, 95, 71,238, 29,185,170, 48, 38,163,212, 93, 44, 59,142,245,240,164, 78, 24, 51,228,238,159, 26,186, 94,136,225, 15, +219, 80,197,200,136,210, 32, 67,240,165,104,230,251,108,138, 78, 76,165,154,186, 96,129, 84,153,162,112, 84, 92, 13, 23, 33,173, + 24,146,213, 6, 74,224,248, 65,240,114,122,192,192, 96,203,241, 87, 0,198,174,160,181,137, 32, 10,239,204, 38,105,220,244,208, +162,224,161, 85, 80, 73,215, 67,161, 45, 66,177,230, 71,120, 17,241, 36, 30, 60,136, 66, 17, 79,185,133,226,213,131,151,141, 1, + 17,241, 88,143, 77, 33,148,180, 30, 60,121,242,222,216, 94, 90,140,160, 96,208, 16,210,221,236,206,248,230,189,217,217,205, 26, +162, 57, 77,134,205,236,102,153,253,230,155,183,239,251,222,191,241,189, 90,173, 2, 61,175,213,106,128,224, 0,229, 0,232, 15, + 17,181,225,171,105, 67,163,221,110,191,223,222,166, 56,204, 78,179,121,176,191, 15, 36,157, 70, 0, 16, 7,240, 37,198,109,218, +208, 88, 93, 91,123,190,181, 5, 32, 14, 67,153,213,155,250, 27,158, 7,151, 14, 64,127,179, 82, 57, 61, 57, 1, 16,127,186,185, +185,228,186, 48, 56, 64, 57, 28, 15,107, 3,156, 2,250,235,158,103, 78, 68, 31, 56, 12,192,253,153, 58,254,250,163, 39,143,135, +241,206, 0,110, 92,107,103,183,236,186, 71,135, 29,106, 64,231, 27,175,113,124,216, 89,175,108, 44,175,174,188,173, 55,224, 6, +221,123,112,255,198,173,141,133, 75,139,112, 1,245, 23, 47, 23, 46, 47,222,190,123,231,227,193,135,111,167, 93,154,247,123,205, +214,213,165,242,113,231, 75,187,217,186,230,150,161,231,221,171,215, 48, 72, 98,155, 97, 37, 60,158, 18,210,143,162,240,187,229, +207, 88,246, 21,229, 4, 35,126, 40, 67, 70,217,179,100, 31, 17,188,132, 16, 31, 11,142,245, 62,159,242,226,125,116, 18,134,197, +160, 7,116, 65,170, 2,234, 43,142,147,199, 82,129, 48,251,206,162,104,175,255,171, 43,163, 52,249, 89,158,119,190, 14,228,167, +207,221,126, 40, 7, 33,236, 43,121, 94,109, 24,149, 91,169,133, 58, 13, 84, 6, 51,116,153,195, 66, 12, 74,156,174,104,201, 48, + 18,122, 22, 97,105, 60,229,172,148, 43,217,108, 46, 8, 3,102,249, 92,134, 20, 66,192,105,136, 74, 75, 33,124, 57,252, 45,252, +217,130,115, 46,127,177, 63,130,181,204,215,126, 94,104, 20,150,112, 59,204, 16, 97, 90,180,163, 25,140,246,111, 96, 4,238, 17, + 69,108, 68, 12, 53, 4,241, 34,214, 53,105,152,183, 18,121,217,223,150,191, 9, 21,101, 73, 90,164, 9,227,139,113,242,174,254, + 66,252, 98,119,226, 46,106,122,208, 22,126,110,167,171,253, 76,205, 51, 72, 67, 60,183, 98, 76,142,137,188, 70,121, 18, 84,240, +132, 43, 39, 69,239, 88,198,130, 30,139, 93,113, 67,240,249,248,155, 41,150,145,128,101,180, 77,177, 55,114,156, 74, 36, 49,221, +218,196,100,146,194,104,217,132,183,180, 72,156,150, 40,166,249,166,190,130,104, 44,147, 65,166,150, 83, 99, 43,100,226, 55,242, +127,164, 51, 57,110, 79,212,169, 22,212, 11,201, 81, 70,236,202,167,134,109,115, 22,101,168,235,211,141,162, 64,140,231,221,165, + 82,226,208,183,139,233,146, 44,190, 0,238, 18,156,119, 46,204, 21,138,103,118, 97, 16, 13, 1,220,129,203, 43,157, 49,170,170, + 3, 5,239, 56, 28, 19, 24, 21,129,103,135,178, 39, 41,109,134,124,125,165,177,107, 14,113, 31,143,102, 36, 57, 91, 23, 83, 37, + 47, 69, 45, 99, 70, 4, 87,206, 98, 4, 32, 24,104, 98, 76,231, 65, 78,150,241,227, 67,193,201,218,164,196,157,217,153,249, 98, +190, 40,162,209, 79,191,247, 71, 0,202,174,101,165, 97, 32,138,206, 76,147,106,170, 34, 90, 65, 65, 16,212,239,112,225, 3, 23, +162,110,251, 29, 46,252, 10,235, 79, 9,186,117,235, 11, 65,235, 99,211, 34, 69,105, 77,219,153,241, 62,102, 38,143, 90,196, 44, + 36, 84, 50, 77, 76,188, 57,247,222,115,207,249, 59,190,183,199, 74, 31,191,110,253, 62, 98,216,107, 10,181, 88, 63,105,183, 67, +201, 5, 80,255,229,213, 85,105,159,171, 55,207,173, 22,156, 58,135,126,190,237, 11,245, 58,252,220,222,219, 99,252, 30, 22,129, + 29,142,212,112, 62,112, 44,236,192,177,231,103,103,135,199,199,141, 70,163,217,108, 50,126,135,219,252,210,194,237,228,244,180, +150,212,238,104,229, 60, 65, 94, 20,213,108,238,111,177,168,178, 80,199,110,232,214,238, 14,225,247, 22,124, 17,124,146,212,146, +253,163, 3, 56, 14,144,190,227, 41,179, 84, 72, 78,229,152,151,186,187,189,201,245,255, 29, 89,205, 57,178,101, 73,147,237, 10, +221,177,189, 85, 21,173, 71, 9,164,112, 79,102,144, 8,195,188, 70, 54,213, 11,211,173,193,210, 90,248,146,125,140,252, 41,196, +177,157,209, 96,186,162,146,138, 26, 90,172,122,127,148, 31,125,241,145,170,139,247, 47,148, 42,139, 80,228, 0,115, 70, 28,122, +102,229, 85,247,143,224,169, 74,146, 71, 32,115,108, 83, 25,122,125, 70,205, 85,197,108, 58,234, 65,174,138, 22,134, 26,249, 97, + 49,218,198, 65,114, 10, 9,172, 32, 59, 74,153,218,225,247,168, 63, 83,157,153,143,150, 59,195, 87, 13,191,100,188, 38, 29,119, +197, 25,221,102, 77, 64, 93,168, 36, 88,118,206,243,193,157, 32, 58,155,166,142,216, 28,195,205,109,200, 49, 93,242,162,152,187, + 52,161,149,202,228,199, 64,139,148, 34,111, 88, 97, 60, 71, 77,138,178, 94,155,157,132,193,255,152, 90, 45, 78, 63,254, 78, 24, +163, 16, 31, 72,147,202,201,137, 33, 22,206, 80, 62,243, 43,195,248,169,239,193,149,128, 57,221, 50,225,165,170,113,252, 87, 78, +102,189, 75,146, 67,112, 92,140,192,146,116, 47, 17, 43, 76, 94, 42,192, 4, 77,246,128,196,243,127, 18,233, 49,187, 10, 54,243, +158, 12, 58,206, 94, 43,229, 85, 94, 6,199,138,137,239,203,127,108,196, 37, 23, 81,113, 57,132,240,214,142,131,119, 69, 47,137, + 16,220,217, 77,147, 18,101,185,182,180,249,216,126, 40,186,185,226,117, 85,176,198, 18,163, 27,170,140,186,131,206,210,212,202, +235,231,219,236,226, 6,172, 21, 43, 53, 48,118,138,132,158,177,116,163, 53,147,193,224, 50, 83,170,144,147, 14,146, 38,199, 37, +150,216,176, 60, 9, 97,178,142, 8, 63,123, 28,178,201,212,134,250,181,218, 55, 35,108,102, 44, 76,100, 75,122, 98,153,113, 59, +164, 16,175,188, 37, 64,120,239,106,223,155,169,202, 74, 45,158,131,204,190,151,118,251,250, 27,206,230, 71, 0,206,174,166, 55, +109, 32, 10,238,174,101, 62,172, 72,165,129, 83,148,220, 90, 53,183,146,107,126, 4,255,142, 63, 66,114, 35, 17, 82, 43,155, 42, +138,212,170,183,222,218,224, 99, 64, 13,145, 28,108,175,119,179,239, 61,239,174,221, 38, 84, 42, 7,100, 16,178, 87,102,153, 29, +102,223,155,249,159,250, 72, 67,210, 29,236,186, 99, 67,153, 13,173, 30,143,199,132,203,240,242,244,244,106, 62, 63,193,199,116, + 58,165,207,184, 99,131,194,147,201,132,232,252,112, 52, 90,198, 49,157,144, 36,251,101,146,208,251, 73, 28,147,242,243, 34,207, +234, 71,209,229,108, 6, 58,207,249,185, 97,241,230,138,139,249,220,141, 45, 93,221, 93,206, 46,204,193,199,179, 51,243,252,253, +235, 55,245,215,143, 0, 49, 66,164,171,212, 28,223, 36, 95, 54,247,235,195,209,240, 54, 89, 30,157, 28,155,147,127,190, 94,192, +210,149,237,210,187,212, 48,250,119, 31,222,127,186, 90,176,154, 39, 98,148, 43,205,155,118,147, 99,211,190, 42,176,147, 47, 99, +225, 91,206, 14,160,218, 4, 52,229,227,195,254, 32,239,109,178,221,189, 89,102, 25,104, 31,188, 65,130, 2, 27,115,218,195,254, + 41,243, 37, 61,160, 49,113, 15,237,116,163, 64,116, 59,193, 32, 10,135,253,110,252,227,247,207,198, 13, 57, 18, 92, 98,250,162, +153,164,165, 33, 14,138,115, 63, 91, 92,241, 24,101,161, 16,214,123,191, 21,220, 11,210,200,208, 21, 23, 7,161,138,182,197,246, +169,120,146, 76, 65, 37, 41,242,252, 2,119,111,114, 37, 67,168, 33, 51,248, 30, 8,240,177, 97,165, 42,100,248,166, 27, 12, 30, +205, 31, 21,238, 54, 9,181,135,113, 60,189,240,146, 43,118,144, 34,190, 84,140, 50,151, 80,123,103,118,247,149,251, 48, 33,221, +118,246,127, 5,217, 29, 96,121, 54,218,240,169,117,234, 64,171, 27, 70,237,107, 6,218,195, 7,181,240,235,111, 19,220,249,190, +154, 96,168, 87,175,211,157, 84,203, 48,169,246, 34,163,117, 81,184, 81, 86,184,246,186,161, 55, 34,133,188,191, 38, 20, 77, 51, + 43,167, 8,246, 66,247,144,182, 81, 78,190,188,191, 94,117,155,217,214,218,229, 23,182,154, 3,254,168,140,161,244, 99,229, 97, +220,105, 77,173, 42, 74, 23, 76,162, 93, 80,138,246, 29, 12,176,231, 81,187,222,253, 67,156,217, 99, 50,195,173, 67,139,126, 93, + 85,179,111,182,125, 67, 32,155,179,147,203,220, 92,122,181,249,213,108,156,178,229, 46,188,212,224, 11, 0,109,127, 48,192, 74, +178,242,113,183, 93,103,195,168,211,221,177, 12,123,153,132, 34,115, 35,164, 70, 24,232, 12, 62, 64, 56,111,165,170,111,112, 37, +107,116,102, 22,214, 5,129,187, 0,179, 1,141,250, 12,236,202, 6,214,160, 69,183,163,245, 42, 31,232, 75,177, 66,138,108,200, + 48,218, 83, 16, 44, 32,247,167,180, 85,133,222, 5,242,161,216,174,243, 82,130, 89, 2,168,136,207, 2,112,118, 53, 61, 77, 4, + 97,120,102,182,180,221, 2, 69,130, 92, 73,140,186,248, 19,212,223,224, 30, 60,136, 9, 23,227,201,196,254, 11, 14,254,141,158, + 77,188, 16, 61,152,144,152,112,104, 13, 9, 73, 35,158,154,248, 7, 64, 72,196, 0, 90, 58,239,142,207,204,188,179, 31,101,193, +232,158, 54,237,110,183,221,206, 62,243,204,251,241, 60,255,134,239, 99,183,245,122, 61,240,116,192,116,190,239,195, 53,192,122, +128,114,191,223, 7,194, 2,184,211, 52, 5,190, 3,121,113,152, 39,215,229,125,156,133,119, 65,189, 59,157, 14,246,129,227,120, + 61,113, 33,160, 36, 73, 54,194,235,131,193,224,186, 39,207, 23,240, 96, 14,192,148, 48, 28, 14,113,245, 39,105,250,105,103, 39, + 47,254,193,134, 15,124,179,181,245,240,241, 35,220, 37,224,123,157,164,153,125, 84, 14, 70,163,123, 73,242,244,249, 51,112,246, +175,163, 47,123,131,207, 31,223,127,216, 92,121,241,242,245, 43, 28,177,253,246,221,183,241,248,238,122, 2, 58,191, 11,124, 15, + 14, 17,161, 32,162,144,183,157,125,182, 3, 67,243, 25,193, 19, 43, 73,102, 39, 3, 18,122,239,248,188,169, 68, 87,202,181, 86, +187, 75,250, 80, 79, 79, 45,133,231,124,100,211,153,108, 76,108,120, 39,138, 45,149,182,163, 2,220,225, 86,203,118,151, 46,196, +209,131,213, 56,238,180,247,191, 95, 96,176,174,101,116,236, 58,220,186, 34,106, 71,173, 95,153,173, 49,183,137, 24,101,235,219, +141, 39,240, 66,134,112,170, 23, 37,204,219,190,252, 74, 67,185,103,148,156,228, 47, 78, 80, 45, 48,119,250, 13, 98,174,173, 70, +146, 77,199,187, 85, 39, 49,237,149,206,201, 67, 75, 82,218, 35, 16,101,209,153, 57, 93,157,191, 45,229,156,182,214, 79, 38,116, + 35,179, 85,153,114,142, 52, 52,187,168,228,138,146,160, 32,224, 93,201, 56,228,158,247,163,150, 28, 83, 3,217,172, 69,246,162, + 85, 53, 4,127, 77, 73,176,240,191,138,123,107, 43, 20,163, 26,112, 55, 55,138, 6,135, 80,128,241,189,166, 82, 22,210,146,121, + 64,198,176,143, 15, 23, 31,250,121,183,112, 21, 7,181,151,162,170, 58,160, 42,173, 88,121, 58,161,110,132,139,170, 9,234,172, +183,181, 40,100,123,175,107, 14, 8,118,199, 28,183, 8,235,212,210, 55, 15, 19, 83, 17,187, 55, 87,116,128,189, 99, 86,195,102, + 32, 5,213,119,221,150,189, 79,255,242,191, 81, 85,249,222,212, 79, 18,211,242, 93, 32,147, 45,183, 23, 39,103, 19, 55,104,167, + 87,252,223,139, 24,171,175,102, 81,170,241,227,242,100,190,185,116,116,126,120, 63,190,163, 65,101,136, 43,179, 66, 37, 19, 73, + 78,162,186,232,151, 77,108,146,119,230, 82,161, 33,214, 93,197,100, 44, 36, 96, 87,111, 13, 78,209,115,216, 93,135, 50, 74, 98, + 55, 15, 94,255,231, 5, 87,153,235,132,170,118,138,241,207, 55, 37,245, 77, 18,151, 23,217, 79, 2,221, 98, 22, 98,254, 8,192, +219,181,228, 52, 12, 3, 81,143,227, 36,106,161,168, 72, 21, 72, 8,150,172,184, 10,234, 57, 16,108,233, 1,202,130,227,176, 40, +151,225, 0, 72, 44,144, 88,132,150,182, 56,113,240,140, 63,113,226, 32,126, 18, 89,180, 93, 84,141,146,120,166,111,158,231,189, +129, 1,186, 78,193,170,103,208,197, 15,182,179,175,103, 51,157,184,239, 23, 11,246,239, 7, 68,125,199,250, 56,159, 78, 13, 36, +191,184,186,188,157,223,152,207,208,144,113, 73,221,227, 88,217, 68,169, 39, 47,120, 0,124, 60,200,141, 5,143, 96,247,172,122, +160,132, 71,206,193, 43, 88,177, 20, 61,108,253,118,152,136, 83, 1,133,148, 79,165, 90,210,211,202,137,148, 47,200, 31,110,140, +162, 52,174, 23,218, 36, 75, 38,195,236, 96,148,158, 29,237, 60,110,212,221,195,203,243,219, 59,118, 98,105, 12, 77, 27,191,202, +180, 95,160,104, 9,197,213,166, 43, 29, 76,198,227,192,218,189,222,118, 28, 10, 55, 25,197,130, 11, 20,222, 40,158,243, 17, 84, +249, 74,190,110,117,189, 91,149,100,136, 81,150,110, 36,155,129,249,134,126, 77,236,181,160,138, 66, 36,233,120,176, 95,178,213, + 82, 22,212,104,161,130,155,103,215,107, 7, 5, 83,136, 58,216, 78,132,189,243,248, 53,205,131,209,144, 7, 5,174, 56, 8, 36, + 78, 1,102,143,201,223, 80,211,212,113, 27,255,146, 25,136,211, 37,119,196, 78,251, 59,240,155, 21,235,152, 48,222, 37,134, 2, +209, 92, 99, 10, 9,125,182, 28, 0,225,180,208,154,125,230,118, 92, 7,132, 75,156,217, 61, 39, 83,181, 40,153,200,175,211,222, + 88, 27, 32,230,220,238,252,188,238, 84,102,129,222,184,207,228,221,144, 70,208, 0,124,198,190,169, 59,253,187, 12,211,255,120, +206, 53, 24,218,134,129,193,109,163, 11, 96,121,202, 68, 38,210, 20,178, 12,167, 42,137, 97,178,119,188,123,178,149,107, 86,109, +214,114, 67,136, 71, 98, 15, 98,109,112, 15, 35,127, 42, 36, 24,165, 14, 22,244, 4,182,217, 89, 56, 70,200,103, 24, 69,178, 38, +183, 1,160,106,139,211,149,203,218,173,254,112,143,195, 42, 55,198,139, 27,250,180,201, 57, 88, 10,164,196, 87, 17, 11,132,110, + 89, 26,147,209, 95, 8,255, 16,128,185,171,231,105, 24, 6,162, 57, 59, 73,145, 24, 64, 98,165, 98, 0,254,255,194, 6,226, 15, +240, 39, 24, 96, 65, 76,173, 72,210,218,190, 35,254, 56,251,156, 82, 33, 1, 3, 85,183, 84,170,100, 57,207,231,119,239,189,107, +255, 16, 94,255,201,103,174,235, 47,215,235, 25,226,199, 97,120,188,127,120,241,132, 79,149, 1, 27,110, 46,139, 43,173,176,142, +231,200, 4,242, 20,176,226, 55,144,129, 0, 15,146, 65,232, 72,131,174, 68,155,229,222, 41, 68,157,132, 7,221, 54, 50,125,243, +211, 55,135,239,182,185, 93,245, 55, 45,110,246,110, 66, 23,126,172, 78, 3,201,120,214,170,174,243, 33, 56,215,231,221,213,197, + 9,172,250,187,231,143,167,215,141, 15, 45,213,254,162,103, 49,202, 96, 19, 10,104, 42, 26, 6, 37,143,181, 34,134,136, 35, 62, +130, 89,206,229, 26, 16, 33,101, 58,162,113, 48,217,237, 14, 71,235,220,190,217, 33,143,199, 66,102,232,227, 87,135, 49, 96,236, +191,135,121,119, 79,251,161,239, 90, 10, 9,184, 32, 11, 65,200,209,205, 21,190, 99, 74,232, 45,156, 12, 17, 11,186, 83,163, 15, +147, 66, 27, 42,238, 56, 27,232,235,169,205, 57,221, 0, 22,121, 5,120,132,126, 57, 38,130,166,175,144, 93,213, 79,190, 45,219, +235,250, 87, 86,136, 74, 98,175, 19, 80, 13, 7,222,160, 74,217, 1,101,208,143, 42,190, 45, 46,237,161,136, 39,151,196,182, 88, + 40, 57,219, 58,175,176, 44,180,249,143,211,138, 83,233,204,168,140, 53,212,112, 70,127,234, 27,227,194,106,142,194, 71, 70,181, + 7,135, 83,239,127, 50,251,240,119, 64,181, 60, 0, 71,161,155,204, 76, 34,248, 88,247, 96,252,236, 86,214, 24,165,253,180, 73, +133,122,132,173, 37,211,233,126,112, 59,127,159,118,113,154,120, 58,180, 12, 89,229,149, 53, 24, 11,184,249,120,176, 77,212, 23, + 52,134, 19, 57, 36,129,102, 89,152, 27, 60,174,209,129, 17,105, 25,185, 97, 48, 4,199,167, 62, 22,178, 89, 50,236, 25, 23, 14, +137, 40,174, 79, 83, 16,216,196, 99, 66,202, 2,217,102,190,157,232, 79, 1,136,187,130,156,134, 97, 32,104,175,237,164,109,104, +185, 33,110, 72, 72,252,255, 13,124,133, 3, 7,224, 80,138, 68, 73,226,216,196,107,175,227, 77, 20,169, 8, 36, 30,208,168,138, +227,245,204,122,102,246,183,248,253,223,235,187,228,174, 7,207, 45, 21,101, 99,116,109,176, 20,100,176, 62, 97, 16,159, 39,122, +231,155,165,159,245,104, 11, 56,195, 81,188,140,180, 64,146,116, 89,209,154,141, 91,100,167,225,161,214,247, 6, 94,206,246,109, + 24, 26, 5,215, 90,238,183,112, 85,155,155, 67, 37, 43,243,220,186,199,167,211,120, 6,104, 5,136, 29,130,214, 42,119,168,163, +118,132,252,239, 82,161,175, 20,100, 78,247,145,204,254,149, 10, 6, 82,200,160,173, 65,159, 46,214, 49, 99, 15,199,254,216,249, + 22, 89,103,111, 83,167, 37, 17, 18,196,236, 74, 36,163,157,138,124, 8,203,189,110,204,182,169,119,239,221,107, 12,254, 45,198, + 25,205, 81, 40, 5,203,120,202,128,140,255,223,185, 50,111,192,145,100,134,182,230,100,188,247, 76,103,237,242, 32, 14,170,236, + 37,144,140,186, 73, 78, 5,104,120,209, 5,171, 8,252,219,184,184,178,139,181,252,244,229,207,103,140, 64,242,196,121,224,172, +145, 58,242, 32,138,146, 79, 39,144, 88,198, 61,122, 54,159,122, 98, 54,236, 42,181,232,201, 20,175,200, 9,158, 11, 18,141,151, +217, 71, 83,238,145,188,182,165, 84, 38,195,166, 97, 49, 85,149, 81,171,245, 67,247,175,202,203,190, 62,124,180,167,164, 65,128, +186,195,202, 62, 83, 73,201,212,124, 11, 95, 52,118, 84,148, 22, 90, 43, 93,129,169,196,198,132,152,166,205,109,125,215,218,179, + 31, 90, 59,244, 95, 99,161, 15,152,125,228,184,254,115, 68,237,120, 45,135,123,193, 59, 84,184,218, 36,114,119,144, 52,236, 81, + 73, 54,248, 41,171, 32,244,232,237,100, 37,163, 59, 97,161, 29,221, 75,231,177,233, 52,185, 41,177, 91,122,102,152, 2,224, 2, + 96, 5,106, 69, 58, 36, 13,218,138,110,124,206,183, 0,172,157, 95,107,131, 48, 20,197,115, 18,197, 89,101,143, 99, 79,133,189, +172,223,255,115,244,139,236, 31, 12,218,181, 80,109,110,102,114, 19,141, 81,219,210,173, 15, 82, 40,212, 32,250, 51,247, 36,247, +156, 63,241,253,238,171,111,110,251,219, 27,109,167, 49,209,103,102,249,126,217, 48,186, 95,146,158, 26, 27, 36,148, 23,151,226, +114,252,239,209,251, 0, 17, 83,165, 98, 95,240,160,108, 32, 66,191, 4,111, 9,148, 43,133,205, 74,189,214,197, 75,157,101,185, +250,106,205, 71,171,223, 78,180,125,255,145,142,215,118,181,147, 27,107,221,209,151,117,214,223, 4,185, 20, 79,143,178, 42,113, +106,205,238,104,190, 15,210,122,201, 43,223, 16, 36, 8, 52, 92, 13,112,202,132,123, 80,149,151,240,172,106,159,139, 38,223,211, +193,229, 9,112,240, 35,247,115,114,244, 1, 92,209,167,250,128,202,248, 75,149,213, 29,226,119,244, 25, 10,118, 55, 52, 57, 42, +244,145, 68, 99,135,110,204, 4,238,218, 4,103,112, 30, 59, 13,224,161,177,103,239, 56, 98,105, 80, 18, 40, 57, 75, 34,245,204, + 53, 61,206,221, 15, 18,247,144, 61,157,126, 95,187,213, 23,112,143,212,137,102,194,250, 62, 6,122, 66,249,208,133, 20,149,112, + 38,141,223,139, 36, 20,145,194,253,140,133, 7,206, 76, 40, 47,230,115,207, 71, 82,216, 44,220,197,181,212,108, 44, 68, 87,253, +215, 39,115,172, 31,243, 29,206, 34,198, 34, 94,161,131,251,131,178,211,153,162,176, 41,103,226,185, 90,151, 40,143,205,158,116, +211,241, 93, 91,113,198,122, 64,106,173,185, 17,248,236,230, 18, 33,144,145,250,246,102, 71,121,161, 7, 53,134,139, 75,195,145, +170,240, 5, 77, 60, 41, 65,180, 56,195, 59,100,248, 29,224,119,203,134, 28,205,126,250,134,224, 90, 65, 97,252,182,199,245, 87, + 0,214,174, 45, 55,129, 24, 6,102, 66, 34,180, 85,145,170,170,247,191, 88, 47,192, 13,160,221, 36,110, 76,226,144, 23, 81,171, + 34, 62,128, 15,172,197,152,137,215,246,140, 25,223,249, 86,101,169, 55,253, 68,124,255,255,146, 92,252, 5,223,135,154,230,111, +236,163,131,248,246, 9,152, 29, 66,163, 22,161,110, 63, 39,132,180,100, 61,231,239, 61,196,235,164, 34,137, 24, 82, 22,234,200, +148,104,149,196, 18,138,182, 80,234,206, 39,112, 15, 84,150,175,199, 88,164,163,225, 57,176,248,151,126, 49,120,219, 14, 31,175, + 54, 90,250, 60,211,238,138, 94, 32, 58, 63,201, 55,205, 51, 91,183,200, 49,222,225, 26, 46,187, 8, 13,248, 42,121,207, 27,135, + 27, 88,135,128,190,217,226,227,128,157, 46,194,112, 10,164,122, 47,220,231, 5, 51,175,124, 2,238, 65, 52,107,137,154, 69,110, +170, 79, 76,235,124,241, 33,176,182,154, 51,181, 34,233,170,246,174,231, 82, 48, 88, 84,231,187,119, 52, 52, 27,134,137,111, 60, + 14,102,172,177,190, 9,206,219,121,141,137, 25,106, 47,160,120, 93, 45,193,189, 3,229,249, 21,162,106, 69,160, 61,187,107,238, +146, 90,130,187, 26,176,155,158,148, 68,114, 28,107,235, 89, 2,108,117, 58,104,230, 17,132, 74,215, 36,113, 80, 41,189, 96,242, +145,142, 17,205,251,181,249,246, 89,219,205,158, 78,230,253,219, 93,157,251,242,126, 15,105,224,157, 7,213, 88, 15,128, 85, 4, +114,247,136,106,183,203,158,149,188, 78, 47,220,221, 75,133, 5, 38,191, 36,164,179,170, 43,197,205, 92,144,169, 37, 58,208, 83, + 30, 32,181,154,108, 54,101,244, 63, 2, 12, 0,210, 11, 96,129, 76, 18,236, 22, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, }; -- cgit v1.2.3 From 87929332c7e0e371933a54ca8b86ad2099c34ac7 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Mon, 31 Aug 2009 18:18:10 +0000 Subject: Changed sync difference time of sound strips to 0.5 seconds instead of 1 frame. Maybe this should be a user preference setting? --- source/blender/blenkernel/intern/sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 8159f2f8c4c..06ef8a23142 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -376,7 +376,7 @@ void sound_update_playing(struct bContext *C) float diff = AUD_getPosition(handle->handle) * fps - cfra + handle->startframe; if(diff < 0.0) diff = -diff; - if(diff > 1.0f) + if(diff > FPS/2.0) { action = 2; } -- cgit v1.2.3 From 121f310fab0a3e1171293583df2e7a984112363b Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Mon, 31 Aug 2009 22:50:08 +0000 Subject: Add missing define to rna for sound system. --- source/blender/makesrna/intern/Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/blender/makesrna/intern/Makefile b/source/blender/makesrna/intern/Makefile index c7cc6e7a4bf..4a4e41edd15 100644 --- a/source/blender/makesrna/intern/Makefile +++ b/source/blender/makesrna/intern/Makefile @@ -77,6 +77,18 @@ ifeq ($(WITH_QUICKTIME), true) CPPFLAGS += -DWITH_QUICKTIME endif +ifeq ($(WITH_SDL),true) + CPPFLAGS += -DWITH_SDL +endif + +ifeq ($(WITH_JACK),true) + CPPFLAGS += -DWITH_JACK +endif + +ifeq ($(WITH_OPENAL),true) + CPPFLAGS += -DWITH_OPENAL +endif + ifeq ($(OS),windows) # Windows needs these extra libs because of winstuff... It is not # _really_ needed, but it is the easiest fix for now. If you have -- cgit v1.2.3 From 04bbb6a0c7a7c8a6c55f1528e76132e7f5a38e6f Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 1 Sep 2009 00:33:39 +0000 Subject: 2.5: Layout Python Files: * Code cleanup. * Made some files match the code guidelines, should be all now. Please everybody use them: http://wiki.blender.org/index.php/Dev:Py/Blender2.5/Layouts/Guidelines * Made polls and header_draw functions as small as possible. * Small fixes here and there. --- release/ui/buttons_data_armature.py | 2 +- release/ui/buttons_data_bone.py | 7 +- release/ui/buttons_data_camera.py | 4 +- release/ui/buttons_data_curve.py | 71 ++++---- release/ui/buttons_data_lamp.py | 17 +- release/ui/buttons_data_lattice.py | 2 +- release/ui/buttons_data_mesh.py | 2 +- release/ui/buttons_data_modifier.py | 1 + release/ui/buttons_data_text.py | 40 ++--- release/ui/buttons_game.py | 30 ++-- release/ui/buttons_material.py | 316 +++++++++++++++------------------ release/ui/buttons_physics_cloth.py | 10 +- release/ui/buttons_physics_field.py | 2 +- release/ui/buttons_physics_smoke.py | 122 ++++++------- release/ui/buttons_physics_softbody.py | 18 +- release/ui/buttons_scene.py | 8 +- release/ui/buttons_world.py | 43 ++--- release/ui/space_image.py | 56 +++--- release/ui/space_info.py | 2 + release/ui/space_node.py | 3 +- release/ui/space_text.py | 14 +- release/ui/space_view3d_toolbar.py | 11 +- 22 files changed, 351 insertions(+), 430 deletions(-) diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index f207b556a6d..ed350caa3bd 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -83,7 +83,7 @@ class DATA_PT_bone_groups(DataButtonsPanel): layout = self.layout ob = context.object - pose= ob.pose + pose = ob.pose row = layout.row() row.template_list(pose, "bone_groups", pose, "active_bone_group_index") diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index cfdaabadf79..8098648886b 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -77,6 +77,7 @@ class BONE_PT_bone(BoneButtonsPanel): ob = context.object bone = context.bone arm = context.armature + if not bone: bone = context.edit_bone else: @@ -192,18 +193,18 @@ class BONE_PT_deform(BoneButtonsPanel): __default_closed__ = True def draw_header(self, context): - layout = self.layout - bone = context.bone + if not bone: bone = context.edit_bone - layout.itemR(bone, "deform", text="") + self.layout.itemR(bone, "deform", text="") def draw(self, context): layout = self.layout bone = context.bone + if not bone: bone = context.edit_bone diff --git a/release/ui/buttons_data_camera.py b/release/ui/buttons_data_camera.py index 0480897d641..aa107d8dbdd 100644 --- a/release/ui/buttons_data_camera.py +++ b/release/ui/buttons_data_camera.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.camera != None) + return (context.camera) class DATA_PT_context_camera(DataButtonsPanel): __show_header__ = False @@ -49,7 +49,7 @@ class DATA_PT_camera(DataButtonsPanel): elif cam.type == 'ORTHO': row.itemR(cam, "ortho_scale") - layout.itemR(cam, "panorama"); + layout.itemR(cam, "panorama") split = layout.split() diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 92e414ba2f3..ced3c6597e0 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -38,33 +38,34 @@ class DATA_PT_shape_curve(DataButtonsPanel): curve = context.curve space = context.space_data - if curve: - layout.itemR(curve, "curve_2d") + layout.itemR(curve, "curve_2d") - split = layout.split() + split = layout.split() - col = split.column() - colsub = col.column() - colsub.active = curve.curve_2d - colsub.itemL(text="Caps:") - colsub.itemR(curve, "front") - colsub.itemR(curve, "back") + col = split.column() + sub = col.column() + sub.active = curve.curve_2d + sub.itemL(text="Caps:") + sub.itemR(curve, "front") + sub.itemR(curve, "back") - col.itemL(text="Textures:") -# col.itemR(curve, "uv_orco") - col.itemR(curve, "auto_texspace") + col.itemL(text="Textures:") +# col.itemR(curve, "uv_orco") + col.itemR(curve, "auto_texspace") - sub = split.column() - sub.itemL(text="Resolution:") - sub.itemR(curve, "resolution_u", text="Preview U") - sub.itemR(curve, "resolution_v", text="Preview V") - sub.itemR(curve, "render_resolution_u", text="Render U") - sub.itemR(curve, "render_resolution_v", text="Render V") - -# sub.itemL(text="Display:") -# sub.itemL(text="HANDLES") -# sub.itemL(text="NORMALS") -# sub.itemR(curve, "vertex_normal_flip") + col = split.column() + col.itemL(text="Resolution:") + sub = col.column(align=True) + sub.itemR(curve, "resolution_u", text="Preview U") + sub.itemR(curve, "render_resolution_u", text="Render U") + sub = col.column(align=True) + sub.itemR(curve, "resolution_v", text="Preview V") + sub.itemR(curve, "render_resolution_v", text="Render V") + +# col.itemL(text="Display:") +# col.itemL(text="HANDLES") +# col.itemL(text="NORMALS") +# col.itemR(curve, "vertex_normal_flip") class DATA_PT_geometry_curve(DataButtonsPanel): __label__ = "Geometry " @@ -76,27 +77,25 @@ class DATA_PT_geometry_curve(DataButtonsPanel): split = layout.split() - sub = split.column() - sub.itemL(text="Modification:") - sub.itemR(curve, "width") - sub.itemR(curve, "extrude") - sub.itemR(curve, "taper_object", icon='ICON_OUTLINER_OB_CURVE') + col = split.column() + col.itemL(text="Modification:") + col.itemR(curve, "width") + col.itemR(curve, "extrude") + col.itemR(curve, "taper_object", icon='ICON_OUTLINER_OB_CURVE') - sub = split.column() - sub.itemL(text="Bevel:") - sub.itemR(curve, "bevel_depth", text="Depth") - sub.itemR(curve, "bevel_resolution", text="Resolution") - sub.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE') + col = split.column() + col.itemL(text="Bevel:") + col.itemR(curve, "bevel_depth", text="Depth") + col.itemR(curve, "bevel_resolution", text="Resolution") + col.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE') class DATA_PT_pathanim(DataButtonsPanel): __label__ = "Path Animation" def draw_header(self, context): - layout = self.layout - curve = context.curve - layout.itemR(curve, "path", text="") + self.layout.itemR(curve, "path", text="") def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_data_lamp.py b/release/ui/buttons_data_lamp.py index c1873d934c4..808a205b1b8 100644 --- a/release/ui/buttons_data_lamp.py +++ b/release/ui/buttons_data_lamp.py @@ -13,9 +13,7 @@ class DATA_PT_preview(DataButtonsPanel): __label__ = "Preview" def draw(self, context): - layout = self.layout - - layout.template_preview(context.lamp) + self.layout.template_preview(context.lamp) class DATA_PT_context_lamp(DataButtonsPanel): __show_header__ = False @@ -69,8 +67,7 @@ class DATA_PT_lamp(DataButtonsPanel): if lamp.type == 'AREA': col.itemR(lamp, "distance") col.itemR(lamp, "gamma") - - + col = split.column() col.itemR(lamp, "negative") col.itemR(lamp, "layer", text="This Layer Only") @@ -299,18 +296,12 @@ class DATA_PT_falloff_curve(DataButtonsPanel): def poll(self, context): lamp = context.lamp - if lamp and lamp.type in ('POINT', 'SPOT'): - if lamp.falloff_type == 'CUSTOM_CURVE': - return True - - return False + return (lamp and lamp.type in ('POINT', 'SPOT') and lamp.falloff_type == 'CUSTOM_CURVE') def draw(self, context): - layout = self.layout - lamp = context.lamp - layout.template_curve_mapping(lamp.falloff_curve) + self.layout.template_curve_mapping(lamp.falloff_curve) bpy.types.register(DATA_PT_context_lamp) bpy.types.register(DATA_PT_preview) diff --git a/release/ui/buttons_data_lattice.py b/release/ui/buttons_data_lattice.py index 5535f973b27..895c1a65bea 100644 --- a/release/ui/buttons_data_lattice.py +++ b/release/ui/buttons_data_lattice.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.lattice != None) + return (context.lattice) class DATA_PT_context_lattice(DataButtonsPanel): __show_header__ = False diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py index 42b637e1f9d..33b3960b381 100644 --- a/release/ui/buttons_data_mesh.py +++ b/release/ui/buttons_data_mesh.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.mesh != None) + return (context.mesh) class DATA_PT_context_mesh(DataButtonsPanel): __show_header__ = False diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py index bc41b04d32c..66c8179f990 100644 --- a/release/ui/buttons_data_modifier.py +++ b/release/ui/buttons_data_modifier.py @@ -27,6 +27,7 @@ class DATA_PT_modifiers(DataButtonsPanel): # the mt.type enum is (ab)used for a lookup on function names # ...to avoid lengthy if statements # so each type must have a function here. + def ARMATURE(self, layout, ob, md): layout.itemR(md, "object") diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py index 1abc82cfaa3..aabf218122f 100644 --- a/release/ui/buttons_data_text.py +++ b/release/ui/buttons_data_text.py @@ -38,29 +38,29 @@ class DATA_PT_shape_text(DataButtonsPanel): curve = context.curve space = context.space_data - if curve: - layout.itemR(curve, "curve_2d") + + layout.itemR(curve, "curve_2d") - split = layout.split() + split = layout.split() - col = split.column() - col.itemL(text="Caps:") - col.itemR(curve, "front") - col.itemR(curve, "back") - col.itemL(text="Textures:") - col.itemR(curve, "uv_orco") - col.itemR(curve, "auto_texspace") + col = split.column() + col.itemL(text="Caps:") + col.itemR(curve, "front") + col.itemR(curve, "back") + col.itemL(text="Textures:") + col.itemR(curve, "uv_orco") + col.itemR(curve, "auto_texspace") - col = split.column() - col.itemL(text="Resolution:") - sub = col.column(align=True) - sub.itemR(curve, "resolution_u", text="Preview U") - sub.itemR(curve, "render_resolution_u", text="Render U") - sub = col.column(align=True) - sub.itemR(curve, "resolution_v", text="Preview V") - sub.itemR(curve, "render_resolution_v", text="Render V") - col.itemL(text="Display:") - col.itemR(curve, "fast") + col = split.column() + col.itemL(text="Resolution:") + sub = col.column(align=True) + sub.itemR(curve, "resolution_u", text="Preview U") + sub.itemR(curve, "render_resolution_u", text="Render U") + sub = col.column(align=True) + sub.itemR(curve, "resolution_v", text="Preview V") + sub.itemR(curve, "render_resolution_v", text="Render V") + col.itemL(text="Display:") + col.itemR(curve, "fast") class DATA_PT_geometry_text(DataButtonsPanel): __label__ = "Geometry" diff --git a/release/ui/buttons_game.py b/release/ui/buttons_game.py index e28e3fda2c6..73ba566e23f 100644 --- a/release/ui/buttons_game.py +++ b/release/ui/buttons_game.py @@ -45,10 +45,9 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel): col = split.column() col.itemL(text="Attributes:") - sub = col.column() - sub.itemR(game, "mass") - sub.itemR(game, "radius") - sub.itemR(game, "form_factor") + col.itemR(game, "mass") + col.itemR(game, "radius") + col.itemR(game, "form_factor") col = split.column() sub = col.column() @@ -108,8 +107,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel): col.itemR(soft, "dynamic_friction", slider=True) col.itemR(soft, "margin", slider=True) col.itemR(soft, "bending_const", text="Bending Constraints") - - + col = split.column() col.itemR(soft, "shape_match") sub = col.column() @@ -134,32 +132,26 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel): elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'): - col = layout.column() - col.itemR(ob, "restrict_render", text="Invisible") + layout.itemR(ob, "restrict_render", text="Invisible") class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel): __label__ = "Collision Bounds" def poll(self, context): - ob = context.active_object - game = ob.game + game = context.object.game rd = context.scene.render_data return (game.physics_type in ('DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC')) and (rd.engine == 'BLENDER_GAME') def draw_header(self, context): - layout = self.layout - - ob = context.active_object - game = ob.game + game = context.active_object.game - layout.itemR(game, "use_collision_bounds", text="") + self.layout.itemR(game, "use_collision_bounds", text="") def draw(self, context): layout = self.layout - ob = context.scene.objects[0] - game = ob.game - + game = context.active_object.game + layout.active = game.use_collision_bounds layout.itemR(game, "collision_bounds", text="Bounds") @@ -184,8 +176,6 @@ class SCENE_PT_game(SceneButtonsPanel): def draw(self, context): layout = self.layout - - rd = context.scene.render_data row = layout.row() row.itemO("view3d.game_start", text="Start") diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py index e317d990c39..dc11731d7a9 100644 --- a/release/ui/buttons_material.py +++ b/release/ui/buttons_material.py @@ -8,18 +8,16 @@ class MaterialButtonsPanel(bpy.types.Panel): # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here def poll(self, context): - return (context.material) and (context.scene.render_data.engine in self.COMPAT_ENGINES) + mat = context.material + engine = context.scene.render_data.engine + return mat and (engine in self.COMPAT_ENGINES) class MATERIAL_PT_preview(MaterialButtonsPanel): __label__ = "Preview" COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def draw(self, context): - layout = self.layout - - mat = context.material - - layout.template_preview(mat) + self.layout.template_preview(context.material) class MATERIAL_PT_context_material(MaterialButtonsPanel): __show_header__ = False @@ -83,32 +81,27 @@ class MATERIAL_PT_shading(MaterialButtonsPanel): layout = self.layout mat = context.material - ob = context.object - slot = context.material_slot - space = context.space_data - if mat: - - if mat.type in ('SURFACE', 'WIRE'): - split = layout.split() + if mat.type in ('SURFACE', 'WIRE'): + split = layout.split() - col = split.column() - sub = col.column() - sub.active = not mat.shadeless - sub.itemR(mat, "emit") - sub.itemR(mat, "ambient") - sub = col.column() - sub.itemR(mat, "translucency") + col = split.column() + sub = col.column() + sub.active = not mat.shadeless + sub.itemR(mat, "emit") + sub.itemR(mat, "ambient") + sub = col.column() + sub.itemR(mat, "translucency") - col = split.column() - col.itemR(mat, "shadeless") - sub = col.column() - sub.active = not mat.shadeless - sub.itemR(mat, "tangent_shading") - sub.itemR(mat, "cubic") + col = split.column() + col.itemR(mat, "shadeless") + sub = col.column() + sub.active = not mat.shadeless + sub.itemR(mat, "tangent_shading") + sub.itemR(mat, "cubic") - elif mat.type == 'HALO': - layout.itemR(mat, "alpha") + elif mat.type == 'HALO': + layout.itemR(mat, "alpha") class MATERIAL_PT_strand(MaterialButtonsPanel): __label__ = "Strand" @@ -158,8 +151,7 @@ class MATERIAL_PT_physics(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material - phys = mat.physics + phys = context.material.physics split = layout.split() @@ -363,12 +355,11 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - layout = self.layout sss = context.material.subsurface_scattering mat = context.material - layout.active = (not mat.shadeless) - layout.itemR(sss, "enabled", text="") + self.layout.active = (not mat.shadeless) + self.layout.itemR(sss, "enabled", text="") def draw(self, context): layout = self.layout @@ -408,12 +399,10 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) - def draw_header(self, context): - layout = self.layout - + def draw_header(self, context): raym = context.material.raytrace_mirror - layout.itemR(raym, "enabled", text="") + self.layout.itemR(raym, "enabled", text="") def draw(self, context): layout = self.layout @@ -465,11 +454,9 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) - def draw_header(self, context): - layout = self.layout - + def draw_header(self, context): mat = context.material - layout.itemR(mat, "transparency", text="") + self.layout.itemR(mat, "transparency", text="") def draw(self, context): layout = self.layout @@ -477,15 +464,14 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): mat = context.material rayt = context.material.raytrace_transparency - row= layout.row() - row.itemR(mat, "transparency_method", expand=True) + row = layout.row() row.active = mat.transparency and (not mat.shadeless) + row.itemR(mat, "transparency_method", expand=True) split = layout.split() col = split.column() - row = col.row() - row.itemR(mat, "alpha") + col.itemR(mat, "alpha") row = col.row() row.active = mat.transparency and (not mat.shadeless) row.itemR(mat, "specular_alpha", text="Specular") @@ -517,29 +503,130 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): sub.itemR(rayt, "gloss_threshold", text="Threshold") sub.itemR(rayt, "gloss_samples", text="Samples") -class MATERIAL_PT_volume_shading(MaterialButtonsPanel): - __label__ = "Shading" - __default_closed__ = False +class MATERIAL_PT_halo(MaterialButtonsPanel): + __label__= "Halo" COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): mat = context.material engine = context.scene.render_data.engine - return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES) + return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout + + mat = context.material + halo = mat.halo + + split = layout.split() + + col = split.column() + col.itemR(mat, "diffuse_color", text="") + col.itemR(halo, "size") + col.itemR(halo, "hardness") + col.itemR(halo, "add") + col.itemL(text="Options:") + col.itemR(halo, "texture") + col.itemR(halo, "vertex_normal") + col.itemR(halo, "xalpha") + col.itemR(halo, "shaded") + col.itemR(halo, "soft") + col = split.column() + col.itemR(halo, "ring") + sub = col.column() + sub.active = halo.ring + sub.itemR(halo, "rings") + sub.itemR(mat, "mirror_color", text="") + col.itemS() + col.itemR(halo, "lines") + sub = col.column() + sub.active = halo.lines + sub.itemR(halo, "line_number", text="Lines") + sub.itemR(mat, "specular_color", text="") + col.itemS() + col.itemR(halo, "star") + sub = col.column() + sub.active = halo.star + sub.itemR(halo, "star_tips") + +class MATERIAL_PT_flare(MaterialButtonsPanel): + __label__= "Flare" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def poll(self, context): mat = context.material - vol = context.material.volume + engine = context.scene.render_data.engine + return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES) + + def draw_header(self, context): + layout = self.layout + + mat = context.material + halo = mat.halo + layout.itemR(halo, "flare_mode", text="") + + def draw(self, context): + layout = self.layout + + mat = context.material + halo = mat.halo + + layout.active = halo.flare_mode split = layout.split() - row = split.row() + col = split.column() + col.itemR(halo, "flare_size", text="Size") + col.itemR(halo, "flare_boost", text="Boost") + col.itemR(halo, "flare_seed", text="Seed") + col = split.column() + col.itemR(halo, "flares_sub", text="Subflares") + col.itemR(halo, "flare_subsize", text="Subsize") + +bpy.types.register(MATERIAL_PT_context_material) +bpy.types.register(MATERIAL_PT_preview) +bpy.types.register(MATERIAL_PT_diffuse) +bpy.types.register(MATERIAL_PT_specular) +bpy.types.register(MATERIAL_PT_shading) +bpy.types.register(MATERIAL_PT_transp) +bpy.types.register(MATERIAL_PT_mirror) +bpy.types.register(MATERIAL_PT_sss) +bpy.types.register(MATERIAL_PT_halo) +bpy.types.register(MATERIAL_PT_flare) +bpy.types.register(MATERIAL_PT_physics) +bpy.types.register(MATERIAL_PT_strand) +bpy.types.register(MATERIAL_PT_options) +bpy.types.register(MATERIAL_PT_shadow) + +# Volumetrics +class VolumeButtonsPanel(bpy.types.Panel): + __space_type__ = 'PROPERTIES' + __region_type__ = 'WINDOW' + __context__ = "material" + + def poll(self, context): + mat = context.material + engine = context.scene.render_data.engine + return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES) + +class MATERIAL_PT_volume_shading(VolumeButtonsPanel): + __label__ = "Shading" + __default_closed__ = False + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + mat = context.material + vol = context.material.volume + + row = layout.row() row.itemR(vol, "density") row.itemR(vol, "scattering") - + split = layout.split() + col = split.column() col.itemR(vol, "absorption") col.itemR(vol, "absorption_color", text="") @@ -548,20 +635,14 @@ class MATERIAL_PT_volume_shading(MaterialButtonsPanel): col.itemR(vol, "emission") col.itemR(vol, "emission_color", text="") -class MATERIAL_PT_volume_scattering(MaterialButtonsPanel): +class MATERIAL_PT_volume_scattering(VolumeButtonsPanel): __label__ = "Scattering" __default_closed__ = False COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def poll(self, context): - mat = context.material - engine = context.scene.render_data.engine - return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES) - + def draw(self, context): layout = self.layout - mat = context.material vol = context.material.volume split = layout.split() @@ -587,17 +668,9 @@ class MATERIAL_PT_volume_scattering(MaterialButtonsPanel): if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'): col.itemR(vol, "asymmetry") -class MATERIAL_PT_volume_transp(MaterialButtonsPanel): +class MATERIAL_PT_volume_transp(VolumeButtonsPanel): __label__= "Transparency" COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def poll(self, context): - mat = context.material - engine = context.scene.render_data.engine - return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES) - - def draw_header(self, context): - layout = self.layout def draw(self, context): layout = self.layout @@ -609,16 +682,11 @@ class MATERIAL_PT_volume_transp(MaterialButtonsPanel): row.itemR(mat, "transparency_method", expand=True) row.active = mat.transparency and (not mat.shadeless) -class MATERIAL_PT_volume_integration(MaterialButtonsPanel): +class MATERIAL_PT_volume_integration(VolumeButtonsPanel): __label__ = "Integration" __default_closed__ = False COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def poll(self, context): - mat = context.material - engine = context.scene.render_data.engine - return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES) - + def draw(self, context): layout = self.layout @@ -638,104 +706,8 @@ class MATERIAL_PT_volume_integration(MaterialButtonsPanel): col.itemL() col.itemR(vol, "depth_cutoff") col.itemR(vol, "density_scale") - - -class MATERIAL_PT_halo(MaterialButtonsPanel): - __label__= "Halo" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def poll(self, context): - mat = context.material - engine = context.scene.render_data.engine - return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - mat = context.material - halo = mat.halo - - split = layout.split() - - col = split.column() - col.itemR(mat, "diffuse_color", text="") - col.itemR(halo, "size") - col.itemR(halo, "hardness") - col.itemR(halo, "add") - col.itemL(text="Options:") - col.itemR(halo, "texture") - col.itemR(halo, "vertex_normal") - col.itemR(halo, "xalpha") - col.itemR(halo, "shaded") - col.itemR(halo, "soft") - - col = split.column() - col.itemR(halo, "ring") - sub = col.column() - sub.active = halo.ring - sub.itemR(halo, "rings") - sub.itemR(mat, "mirror_color", text="") - col.itemS() - col.itemR(halo, "lines") - sub = col.column() - sub.active = halo.lines - sub.itemR(halo, "line_number", text="Lines") - sub.itemR(mat, "specular_color", text="") - col.itemS() - col.itemR(halo, "star") - sub = col.column() - sub.active = halo.star - sub.itemR(halo, "star_tips") - -class MATERIAL_PT_flare(MaterialButtonsPanel): - __label__= "Flare" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def poll(self, context): - mat = context.material - engine = context.scene.render_data.engine - return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES) - - def draw_header(self, context): - layout = self.layout - - mat = context.material - halo = mat.halo - layout.itemR(halo, "flare_mode", text="") - - def draw(self, context): - layout = self.layout - - mat = context.material - halo = mat.halo - - layout.active = halo.flare_mode - - split = layout.split() - - col = split.column() - col.itemR(halo, "flare_size", text="Size") - col.itemR(halo, "flare_boost", text="Boost") - col.itemR(halo, "flare_seed", text="Seed") - col = split.column() - col.itemR(halo, "flares_sub", text="Subflares") - col.itemR(halo, "flare_subsize", text="Subsize") -bpy.types.register(MATERIAL_PT_context_material) -bpy.types.register(MATERIAL_PT_preview) -bpy.types.register(MATERIAL_PT_diffuse) -bpy.types.register(MATERIAL_PT_specular) -bpy.types.register(MATERIAL_PT_shading) -bpy.types.register(MATERIAL_PT_transp) -bpy.types.register(MATERIAL_PT_mirror) -bpy.types.register(MATERIAL_PT_sss) bpy.types.register(MATERIAL_PT_volume_shading) bpy.types.register(MATERIAL_PT_volume_scattering) bpy.types.register(MATERIAL_PT_volume_transp) bpy.types.register(MATERIAL_PT_volume_integration) -bpy.types.register(MATERIAL_PT_halo) -bpy.types.register(MATERIAL_PT_flare) -bpy.types.register(MATERIAL_PT_physics) -bpy.types.register(MATERIAL_PT_strand) -bpy.types.register(MATERIAL_PT_options) -bpy.types.register(MATERIAL_PT_shadow) diff --git a/release/ui/buttons_physics_cloth.py b/release/ui/buttons_physics_cloth.py index a1978f44c18..5cdca3c2c74 100644 --- a/release/ui/buttons_physics_cloth.py +++ b/release/ui/buttons_physics_cloth.py @@ -103,11 +103,10 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): return (context.cloth) def draw_header(self, context): - layout = self.layout cloth = context.cloth.collision_settings - layout.active = cloth_panel_enabled(context.cloth) - layout.itemR(cloth, "enable_collision", text="") + self.layout.active = cloth_panel_enabled(context.cloth) + self.layout.itemR(cloth, "enable_collision", text="") def draw(self, context): layout = self.layout @@ -139,11 +138,10 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): return (context.cloth != None) def draw_header(self, context): - layout = self.layout cloth = context.cloth.settings - layout.active = cloth_panel_enabled(context.cloth) - layout.itemR(cloth, "stiffness_scaling", text="") + self.layout.active = cloth_panel_enabled(context.cloth) + self.layout.itemR(cloth, "stiffness_scaling", text="") def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_physics_field.py b/release/ui/buttons_physics_field.py index 3c68327ba79..58033d2c431 100644 --- a/release/ui/buttons_physics_field.py +++ b/release/ui/buttons_physics_field.py @@ -8,7 +8,7 @@ class PhysicButtonsPanel(bpy.types.Panel): def poll(self, context): rd = context.scene.render_data - return (context.object != None) and (not rd.use_game_engine) + return (context.object) and (not rd.use_game_engine) class PHYSICS_PT_field(PhysicButtonsPanel): __label__ = "Force Fields" diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py index d7313632638..c87f71bff42 100644 --- a/release/ui/buttons_physics_smoke.py +++ b/release/ui/buttons_physics_smoke.py @@ -97,10 +97,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel): def poll(self, context): md = context.smoke - if md: - return (md.smoke_type == 'TYPE_DOMAIN') - - return False + return md and (md.smoke_type == 'TYPE_DOMAIN') def draw(self, context): layout = self.layout @@ -126,22 +123,15 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel): def poll(self, context): md = context.smoke - if md: - return (md.smoke_type == 'TYPE_DOMAIN') - - return False + return md and (md.smoke_type == 'TYPE_DOMAIN') def draw(self, context): layout = self.layout - md = context.smoke - - if md.smoke_type == 'TYPE_DOMAIN': - - domain = md.domain_settings - cache = domain.point_cache + md = context.smoke.domain_settings + cache = md.point_cache - point_cache_ui(self, cache, cache.baked==False, 0, 1) + point_cache_ui(self, cache, cache.baked==False, 0, 1) class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): __label__ = "Smoke High Resolution" @@ -149,95 +139,85 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): def poll(self, context): md = context.smoke - if md: - return (md.smoke_type == 'TYPE_DOMAIN') - - return False + return md and (md.smoke_type == 'TYPE_DOMAIN') - def draw_header(self, context): - layout = self.layout - + def draw_header(self, context): high = context.smoke.domain_settings - layout.itemR(high, "highres", text="") + self.layout.itemR(high, "highres", text="") def draw(self, context): layout = self.layout md = context.smoke.domain_settings - - if md: - - split = layout.split() + + split = layout.split() - col = split.column() - col.itemL(text="Resolution:") - col.itemR(md, "amplify", text="Divisions") + col = split.column() + col.itemL(text="Resolution:") + col.itemR(md, "amplify", text="Divisions") - sub = split.column() - sub.itemL(text="Noise Method:") - sub.row().itemR(md, "noise_type", text="") - sub.itemR(md, "strength") - sub.itemR(md, "show_highres") + col = split.column() + col.itemL(text="Noise Method:") + col.row().itemR(md, "noise_type", text="") + col.itemR(md, "strength") + col.itemR(md, "show_highres") class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel): __label__ = "Smoke Cache" __default_closed__ = True def poll(self, context): - return (context.smoke != None) + return (context.smoke) def draw(self, context): layout = self.layout md = context.smoke - - if md: - - cache = md.point_cache + + cache = md.point_cache - layout.set_context_pointer("PointCache", cache) + layout.set_context_pointer("PointCache", cache) - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index") - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") + row = layout.row() + row.template_list(cache, "point_cache_list", cache, "active_point_cache_index") + col = row.column(align=True) + col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") + col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - row = layout.row() - row.itemR(cache, "name") + row = layout.row() + row.itemR(cache, "name") - row = layout.row() - row.itemR(cache, "start_frame") - row.itemR(cache, "end_frame") + row = layout.row() + row.itemR(cache, "start_frame") + row.itemR(cache, "end_frame") - row = layout.row() + row = layout.row() - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") + if cache.baked == True: + row.itemO("ptcache.free_bake", text="Free Bake") + else: + row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - subrow = row.row() - subrow.enabled = cache.frames_skipped or cache.outdated - subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") + subrow = row.row() + subrow.enabled = cache.frames_skipped or cache.outdated + subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") - row = layout.row() - #row.enabled = smoke_panel_enabled(psys) - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") + row = layout.row() + #row.enabled = smoke_panel_enabled(psys) + row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - row = layout.row() - #row.enabled = smoke_panel_enabled(psys) + row = layout.row() + #row.enabled = smoke_panel_enabled(psys) - layout.itemL(text=cache.info) + layout.itemL(text=cache.info) - layout.itemS() + layout.itemS() - row = layout.row() - row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") - + row = layout.row() + row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") + row.itemO("ptcache.free_bake_all", text="Free All Bakes") + layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") bpy.types.register(PHYSICS_PT_smoke) bpy.types.register(PHYSICS_PT_smoke_cache) diff --git a/release/ui/buttons_physics_softbody.py b/release/ui/buttons_physics_softbody.py index 73eb15d2212..703977a056f 100644 --- a/release/ui/buttons_physics_softbody.py +++ b/release/ui/buttons_physics_softbody.py @@ -77,12 +77,10 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): return (context.soft_body) def draw_header(self, context): - layout = self.layout - softbody = context.soft_body.settings - layout.active = softbody_panel_enabled(context.soft_body) - layout.itemR(softbody, "use_goal", text="") + self.layout.active = softbody_panel_enabled(context.soft_body) + self.layout.itemR(softbody, "use_goal", text="") def draw(self, context): layout = self.layout @@ -120,12 +118,10 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel): return (context.soft_body) def draw_header(self, context): - #layout = self.layout - softbody = context.soft_body.settings - layout.active = softbody_panel_enabled(context.soft_body) - layout.itemR(softbody, "use_edges", text="") + self.layout.active = softbody_panel_enabled(context.soft_body) + self.layout.itemR(softbody, "use_edges", text="") def draw(self, context): layout = self.layout @@ -170,12 +166,10 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel): return (context.soft_body) def draw_header(self, context): - layout = self.layout - softbody = context.soft_body.settings - layout.active = softbody_panel_enabled(context.soft_body) - layout.itemR(softbody, "self_collision", text="") + self.layout.active = softbody_panel_enabled(context.soft_body) + self.layout.itemR(softbody, "self_collision", text="") def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index abd42e32e35..126afc4ef23 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -323,11 +323,9 @@ class SCENE_PT_antialiasing(RenderButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw_header(self, context): - layout = self.layout - rd = context.scene.render_data - layout.itemR(rd, "antialiasing", text="") + self.layout.itemR(rd, "antialiasing", text="") def draw(self, context): layout = self.layout @@ -391,11 +389,9 @@ class SCENE_PT_stamp(RenderButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw_header(self, context): - layout = self.layout - rd = context.scene.render_data - layout.itemR(rd, "render_stamp", text="") + self.layout.itemR(rd, "render_stamp", text="") def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_world.py b/release/ui/buttons_world.py index 342adfaf4af..b02673d126f 100644 --- a/release/ui/buttons_world.py +++ b/release/ui/buttons_world.py @@ -9,17 +9,14 @@ class WorldButtonsPanel(bpy.types.Panel): def poll(self, context): rd = context.scene.render_data - return (context.world != None) and (not rd.use_game_engine) and (rd.engine in self.COMPAT_ENGINES) + return (context.world) and (not rd.use_game_engine) and (rd.engine in self.COMPAT_ENGINES) class WORLD_PT_preview(WorldButtonsPanel): __label__ = "Preview" COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw(self, context): - layout = self.layout - world = context.world - - layout.template_preview(world) + self.layout.template_preview(context.world) class WORLD_PT_context_world(WorldButtonsPanel): __show_header__ = False @@ -52,32 +49,30 @@ class WORLD_PT_world(WorldButtonsPanel): world = context.world - if world: - - row = layout.row() - row.itemR(world, "paper_sky") - row.itemR(world, "blend_sky") - row.itemR(world, "real_sky") + row = layout.row() + row.itemR(world, "paper_sky") + row.itemR(world, "blend_sky") + row.itemR(world, "real_sky") - row = layout.row() - row.column().itemR(world, "horizon_color") - col = row.column() - col.itemR(world, "zenith_color") - col.active = world.blend_sky - row.column().itemR(world, "ambient_color") + row = layout.row() + row.column().itemR(world, "horizon_color") + col = row.column() + col.itemR(world, "zenith_color") + col.active = world.blend_sky + row.column().itemR(world, "ambient_color") class WORLD_PT_mist(WorldButtonsPanel): __label__ = "Mist" COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw_header(self, context): - layout = self.layout world = context.world - layout.itemR(world.mist, "enabled", text="") + self.layout.itemR(world.mist, "enabled", text="") def draw(self, context): layout = self.layout + world = context.world layout.active = world.mist.enabled @@ -87,7 +82,6 @@ class WORLD_PT_mist(WorldButtonsPanel): flow.itemR(world.mist, "start") flow.itemR(world.mist, "depth") flow.itemR(world.mist, "height") - layout.itemR(world.mist, "falloff") @@ -96,13 +90,13 @@ class WORLD_PT_stars(WorldButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw_header(self, context): - layout = self.layout world = context.world - layout.itemR(world.stars, "enabled", text="") + self.layout.itemR(world.stars, "enabled", text="") def draw(self, context): layout = self.layout + world = context.world layout.active = world.stars.enabled @@ -118,13 +112,13 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw_header(self, context): - layout = self.layout world = context.world - layout.itemR(world.ambient_occlusion, "enabled", text="") + self.layout.itemR(world.ambient_occlusion, "enabled", text="") def draw(self, context): layout = self.layout + ao = context.world.ambient_occlusion layout.active = ao.enabled @@ -186,4 +180,3 @@ bpy.types.register(WORLD_PT_world) bpy.types.register(WORLD_PT_ambient_occlusion) bpy.types.register(WORLD_PT_mist) bpy.types.register(WORLD_PT_stars) - diff --git a/release/ui/space_image.py b/release/ui/space_image.py index 8dc016f55b7..3f82727da47 100644 --- a/release/ui/space_image.py +++ b/release/ui/space_image.py @@ -7,6 +7,7 @@ class IMAGE_MT_view(bpy.types.Menu): def draw(self, context): layout = self.layout + sima = context.space_data uv = sima.uv_editor settings = context.tool_settings @@ -69,6 +70,7 @@ class IMAGE_MT_image(bpy.types.Menu): def draw(self, context): layout = self.layout + sima = context.space_data ima = sima.image @@ -148,13 +150,13 @@ class IMAGE_MT_uvs_weldalign(bpy.types.Menu): layout.itemO("uv.weld") # W, 1 layout.items_enumO("uv.align", "axis") # W, 2/3/4 - class IMAGE_MT_uvs(bpy.types.Menu): __space_type__ = 'IMAGE_EDITOR' __label__ = "UVs" def draw(self, context): layout = self.layout + sima = context.space_data uv = sima.uv_editor settings = context.tool_settings @@ -195,10 +197,11 @@ class IMAGE_HT_header(bpy.types.Header): __space_type__ = 'IMAGE_EDITOR' def draw(self, context): + layout = self.layout + sima = context.space_data ima = sima.image iuser = sima.image_user - layout = self.layout settings = context.tool_settings show_render = sima.show_render @@ -281,38 +284,34 @@ class IMAGE_PT_game_properties(bpy.types.Panel): return (sima and sima.image) and (rd.engine == 'BLENDER_GAME') def draw(self, context): - sima = context.space_data layout = self.layout - + + sima = context.space_data ima = sima.image - if ima: - split = layout.split() - - col = split.column() - - subcol = col.column(align=True) - subcol.itemR(ima, "clamp_x") - subcol.itemR(ima, "clamp_y") + split = layout.split() - col.itemR(ima, "mapping", expand=True) - col.itemR(ima, "tiles") + col = split.column() + col.itemR(ima, "clamp_x") + col.itemR(ima, "clamp_y") + col.itemR(ima, "mapping", expand=True) + col.itemR(ima, "tiles") - col = split.column() + col = split.column() - subcol = col.column(align=True) - subcol.itemR(ima, "animated") + sub = col.column(align=True) + sub.itemR(ima, "animated") - subcol = subcol.column() - subcol.itemR(ima, "animation_start", text="Start") - subcol.itemR(ima, "animation_end", text="End") - subcol.itemR(ima, "animation_speed", text="Speed") - subcol.active = ima.animated + subsub = sub.column() + subsub.active = ima.animated + subsub.itemR(ima, "animation_start", text="Start") + subsub.itemR(ima, "animation_end", text="End") + subsub.itemR(ima, "animation_speed", text="Speed") - subrow = col.row(align=True) - subrow.itemR(ima, "tiles_x", text="X") - subrow.itemR(ima, "tiles_y", text="Y") - subrow.active = ima.tiles or ima.animated + sub = col.row(align=True) + sub.active = ima.tiles or ima.animated + sub.itemR(ima, "tiles_x", text="X") + sub.itemR(ima, "tiles_y", text="Y") class IMAGE_PT_view_properties(bpy.types.Panel): __space_type__ = 'IMAGE_EDITOR' @@ -324,9 +323,9 @@ class IMAGE_PT_view_properties(bpy.types.Panel): return (sima and (sima.image or sima.show_uvedit)) def draw(self, context): - sima = context.space_data layout = self.layout - + + sima = context.space_data ima = sima.image show_uvedit = sima.show_uvedit uvedit = sima.uv_editor @@ -376,4 +375,3 @@ bpy.types.register(IMAGE_MT_uvs) bpy.types.register(IMAGE_HT_header) bpy.types.register(IMAGE_PT_game_properties) bpy.types.register(IMAGE_PT_view_properties) - diff --git a/release/ui/space_info.py b/release/ui/space_info.py index 4188209e393..79937816791 100644 --- a/release/ui/space_info.py +++ b/release/ui/space_info.py @@ -79,6 +79,8 @@ class INFO_MT_file_import(bpy.types.Menu): def draw(self, context): layout = self.layout + + layout.itemL(text="Nothing yet") class INFO_MT_file_export(bpy.types.Menu): __space_type__ = 'INFO' diff --git a/release/ui/space_node.py b/release/ui/space_node.py index 875aca7fd82..6ac1ac84f35 100644 --- a/release/ui/space_node.py +++ b/release/ui/space_node.py @@ -6,6 +6,7 @@ class NODE_HT_header(bpy.types.Header): def draw(self, context): layout = self.layout + snode = context.space_data row = layout.row(align=True) @@ -113,9 +114,7 @@ class NODE_MT_node(bpy.types.Menu): # layout.itemS() # layout.itemO("node.show_cyclic_dependencies") - bpy.types.register(NODE_HT_header) bpy.types.register(NODE_MT_view) bpy.types.register(NODE_MT_select) bpy.types.register(NODE_MT_node) - diff --git a/release/ui/space_text.py b/release/ui/space_text.py index 7b7ec176b72..117033c50a1 100644 --- a/release/ui/space_text.py +++ b/release/ui/space_text.py @@ -5,9 +5,10 @@ class TEXT_HT_header(bpy.types.Header): __space_type__ = 'TEXT_EDITOR' def draw(self, context): + layout = self.layout + st = context.space_data text = st.text - layout = self.layout row = layout.row(align=True) row.template_header() @@ -50,8 +51,9 @@ class TEXT_PT_properties(bpy.types.Panel): __label__ = "Properties" def draw(self, context): - st = context.space_data layout = self.layout + + st = context.space_data flow = layout.column_flow() flow.itemR(st, "line_numbers") @@ -69,8 +71,9 @@ class TEXT_PT_find(bpy.types.Panel): __label__ = "Find" def draw(self, context): - st = context.space_data layout = self.layout + + st = context.space_data # find col = layout.column(align=True) @@ -100,6 +103,7 @@ class TEXT_MT_text(bpy.types.Menu): def draw(self, context): layout = self.layout + st = context.space_data text = st.text @@ -200,8 +204,7 @@ class TEXT_MT_edit(bpy.types.Menu): __label__ = "Edit" def poll(self, context): - st = context.space_data - return st.text != None + return (context.space_data.text) def draw(self, context): layout = self.layout @@ -240,4 +243,3 @@ bpy.types.register(TEXT_MT_edit_view) bpy.types.register(TEXT_MT_edit_select) bpy.types.register(TEXT_MT_edit_markers) bpy.types.register(TEXT_MT_edit_to3d) - diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 517571e1b09..0b7ccb15d6c 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -420,10 +420,11 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel): context.texture_paint_object)) def draw(self, context): + layout = self.layout + settings = self.paint_settings(context) brush = settings.brush texture_paint = context.texture_paint_object - layout = self.layout if not texture_paint: layout.itemR(brush, "smooth_stroke") @@ -444,7 +445,6 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel): col.active = brush.airbrush col.itemR(brush, "rate", slider=True) - class VIEW3D_PT_tools_brush_curve(PaintPanel): __label__ = "Curve" __default_closed__ = True @@ -454,9 +454,10 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel): return (settings and settings.brush and settings.brush.curve) def draw(self, context): + layout = self.layout + settings = self.paint_settings(context) brush = settings.brush - layout = self.layout layout.template_curve_mapping(brush.curve) layout.item_menu_enumO("brush.curve_preset", property="shape") @@ -469,6 +470,7 @@ class VIEW3D_PT_sculpt_options(PaintPanel): def draw(self, context): layout = self.layout + sculpt = context.tool_settings.sculpt col = layout.column() @@ -497,6 +499,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel): def draw(self, context): layout = self.layout + wpaint = context.tool_settings.weight_paint col = layout.column() @@ -524,6 +527,7 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel): def draw(self, context): layout = self.layout + vpaint = context.tool_settings.vertex_paint col = layout.column() @@ -598,6 +602,7 @@ class VIEW3D_PT_tools_particlemode(View3DPanel): def draw(self, context): layout = self.layout + pe = context.tool_settings.particle_edit ob = pe.object -- cgit v1.2.3 From 47beb68a0fbeecf0135efd5a356b6ece03e24457 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Sep 2009 00:52:03 +0000 Subject: Open recent list was arseabout, only adding files on save, rather then open. This is problematic for a few reasons... * I'd often save a blendfile only so it would appier in the open recent menu. * Saving files (when you dont need to) makes access times less useful. * binary diff's in SVN dont give any useful info. Sometimes I wasnt sure if I actually edited or saves for fast re-opening. * Testing 2.4x files with animation data in 2.5 can loose info. * Its not logical and other apps dont work this way. Also made the recent file list in the file browser display the most recent item first (like the open recent menu). --- source/blender/editors/space_file/file_panels.c | 18 +++++++++++------- source/blender/windowmanager/intern/wm_files.c | 6 +++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index c48b3529389..24c3f9b4ca1 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -63,7 +63,7 @@ static void file_panel_cb(bContext *C, void *arg_entry, void *arg_unused) WM_operator_properties_free(&ptr); } -static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, short *nr, int icon, int allow_delete) +static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, short *nr, int icon, int allow_delete, int reverse) { SpaceFile *sfile= CTX_wm_space_file(C); uiBlock *block; @@ -71,7 +71,7 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat uiLayout *box, *col; struct FSMenu* fsmenu = fsmenu_get(); char *curdir= (sfile->params)? sfile->params->dir: ""; - int i, nentries = fsmenu_get_nentries(fsmenu, category); + int i, i_iter, nentries = fsmenu_get_nentries(fsmenu, category); /* reset each time */ *nr= -1; @@ -86,12 +86,16 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat box= uiLayoutBox(pa->layout); col= uiLayoutColumn(box, 1); - for (i=0; i< nentries;++i) { + for (i_iter=0; i_iter< nentries;++i_iter) { char dir[FILE_MAX]; char temp[FILE_MAX]; uiLayout* layout = uiLayoutRow(col, 0); - char *entry = fsmenu_get_entry(fsmenu, category, i); + char *entry; + i= reverse ? nentries-(i_iter+1) : i_iter; + + entry = fsmenu_get_entry(fsmenu, category, i); + /* set this list item as active if we have a match */ if(strcmp(curdir, entry) == 0) *nr= i; @@ -124,7 +128,7 @@ static void file_panel_system(const bContext *C, Panel *pa) SpaceFile *sfile= CTX_wm_space_file(C); if(sfile) - file_panel_category(C, pa, FS_CATEGORY_SYSTEM, &sfile->systemnr, ICON_DISK_DRIVE, 0); + file_panel_category(C, pa, FS_CATEGORY_SYSTEM, &sfile->systemnr, ICON_DISK_DRIVE, 0, 0); } static void file_panel_bookmarks(const bContext *C, Panel *pa) @@ -137,7 +141,7 @@ static void file_panel_bookmarks(const bContext *C, Panel *pa) uiItemO(row, "Add", ICON_ZOOMIN, "file.add_bookmark"); uiItemL(row, NULL, 0); - file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, &sfile->bookmarknr, ICON_BOOKMARKS, 1); + file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, &sfile->bookmarknr, ICON_BOOKMARKS, 1, 0); } } @@ -146,7 +150,7 @@ static void file_panel_recent(const bContext *C, Panel *pa) SpaceFile *sfile= CTX_wm_space_file(C); if(sfile) - file_panel_category(C, pa, FS_CATEGORY_RECENT, &sfile->recentnr, ICON_FILE_FOLDER, 0); + file_panel_category(C, pa, FS_CATEGORY_RECENT, &sfile->recentnr, ICON_FILE_FOLDER, 0, 1); } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 9c30c99bbdd..b98717c8629 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -96,6 +96,7 @@ #include "wm.h" #include "wm_window.h" +static void writeBlog(void); /* To be able to read files without windows closing, opening, moving we try to prepare for worst case: @@ -256,7 +257,10 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) if(retval==2) wm_init_userdef(); // in case a userdef is read from regular .blend - if (retval!=0) G.relbase_valid = 1; + if (retval!=0) { + G.relbase_valid = 1; + writeBlog(); + } // XXX undo_editmode_clear(); BKE_reset_undo(); -- cgit v1.2.3 From 285d665d99da1e4ab9406f66026fcca77195d761 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 1 Sep 2009 01:09:05 +0000 Subject: more use of data structures for communication. begining support for more than one file per fob (external dependencies, point cache, ...) --- release/io/netrender/client.py | 13 +++-- release/io/netrender/master.py | 117 +++++++++++++++++++++----------------- release/io/netrender/model.py | 23 +++++--- release/io/netrender/operators.py | 76 ++++++++++++------------- release/io/netrender/slave.py | 88 ++++++++++++++++++---------- release/io/netrender/ui.py | 23 ++++++-- release/io/netrender/utils.py | 36 +++++++----- 7 files changed, 221 insertions(+), 155 deletions(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index 90039a3273a..bc4d363c996 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -22,7 +22,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): def render_master(self, scene): server_address = (scene.network_render.server_address, scene.network_render.server_port) - httpd = master.RenderMasterServer(server_address, master.RenderHandler) + httpd = master.RenderMasterServer(server_address, master.RenderHandler, scene.network_render.path) httpd.timeout = 1 httpd.stats = self.update_stats while not self.test_break(): @@ -32,6 +32,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): slave.render_slave(self, scene) def render_client(self, scene): + netsettings = scene.network_render self.update_stats("", "Network render client initiation") conn = clientConnection(scene) @@ -41,7 +42,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): self.update_stats("", "Network render exporting") - job_id = scene.network_render.job_id + job_id = netsettings.job_id # reading back result @@ -51,10 +52,10 @@ class NetworkRenderEngine(bpy.types.RenderEngine): response = conn.getresponse() if response.status == http.client.NO_CONTENT: - scene.network_render.job_id = clientSendJob(conn, scene) + netsettings.job_id = clientSendJob(conn, scene) clientRequestResult(conn, scene, job_id) - while response.status == http.client.PROCESSING and not self.test_break(): + while response.status == http.client.ACCEPTED and not self.test_break(): print("waiting") time.sleep(1) clientRequestResult(conn, scene, job_id) @@ -68,7 +69,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): x= int(r.resolution_x*r.resolution_percentage*0.01) y= int(r.resolution_y*r.resolution_percentage*0.01) - f = open(PATH_PREFIX + "output.exr", "wb") + f = open(netsetting.path + "output.exr", "wb") buf = response.read(1024) while buf: @@ -78,7 +79,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): f.close() result = self.begin_result(0, 0, x, y) - result.load_from_file(PATH_PREFIX + "output.exr", 0, 0) + result.load_from_file(netsettings.path + "output.exr", 0, 0) self.end_result(result) conn.close() diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index daca3bcf653..6f97685935d 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -9,12 +9,22 @@ JOB_WAITING = 0 # before all data has been entered JOB_PAUSED = 1 # paused by user JOB_QUEUED = 2 # ready to be dispatched +class MRenderFile: + def __init__(self, filepath): + self.filepath = filepath + self.found = False + + def test(self): + self.found = os.path.exists(self.filepath) + return self.found + + class MRenderSlave(netrender.model.RenderSlave): - def __init__(self, name, adress, stats): + def __init__(self, name, address, stats): super().__init__() - self.id = hashlib.md5(bytes(repr(name) + repr(adress), encoding='utf8')).hexdigest() + self.id = hashlib.md5(bytes(repr(name) + repr(address), encoding='utf8')).hexdigest() self.name = name - self.adress = adress + self.address = address self.stats = stats self.last_seen = time.time() @@ -31,11 +41,12 @@ def groupKey(job): return (job.status, job.framesLeft() > 0, job.priority, job.credits) class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, path, chunks = 1, priority = 1, credits = 100.0, blacklist = []): + def __init__(self, job_id, name, files, chunks = 1, priority = 1, credits = 100.0, blacklist = []): super().__init__() self.id = job_id self.name = name - self.path = path + self.files = files + self.render_files = [MRenderFile(path) for path in files] self.status = JOB_WAITING self.frames = [] self.chunks = chunks @@ -44,6 +55,14 @@ class MRenderJob(netrender.model.RenderJob): self.blacklist = blacklist self.last_dispatched = time.time() + def testStart(self): + for f in self.render_files: + if not f.test(): + return False + + self.start() + return True + def start(self): self.status = JOB_QUEUED @@ -75,7 +94,7 @@ class MRenderJob(netrender.model.RenderJob): if f.status == QUEUED: self.update() frames.append(f) - if len(frames) == self.chunks: + if len(frames) >= self.chunks: break return frames @@ -162,10 +181,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if frame: if frame.status in (QUEUED, DISPATCHED): - self.send_head(http.client.PROCESSING) + self.send_head(http.client.ACCEPTED) elif frame.status == DONE: self.server.stats("", "Sending result back to client") - f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".exr", 'rb') + f = open(self.server.path + job_id + "%04d" % job_frame + ".exr", 'rb') self.send_head() @@ -173,13 +192,13 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): f.close() elif frame.status == ERROR: - self.send_head(http.client.NO_CONTENT) + self.send_head(http.client.PARTIAL_CONTENT) else: # no such frame - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) else: # no such job id - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "log": job_id = self.headers['job-id'] @@ -194,23 +213,21 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if frame: if frame.status in (QUEUED, DISPATCHED): self.send_head(http.client.PROCESSING) - elif frame.status == DONE: + else: self.server.stats("", "Sending log back to client") - f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".log", 'rb') + f = open(self.server.path + job_id + "%04d" % job_frame + ".log", 'rb') self.send_head() shutil.copyfileobj(f, self.wfile) f.close() - elif frame.status == ERROR: - self.send_head(http.client.NO_CONTENT) else: # no such frame - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) else: # no such job id - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "status": job_id = self.headers.get('job-id', "") @@ -228,13 +245,13 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): message = frame.serialize() else: # no such frame - self.send_heat(http.client.NOT_FOUND) + self.send_heat(http.client.NO_CONTENT) return else: message = job.serialize() else: # no such job id - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) return else: # status of all jobs message = [] @@ -262,6 +279,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if job and frames: for f in frames: + print("dispatch", f.number) f.status = DISPATCHED f.slave = slave @@ -274,9 +292,9 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.server.stats("", "Sending job frame to render node") else: # no job available, return error code - self.send_head(http.client.NO_CONTENT) + self.send_head(http.client.ACCEPTED) else: # invalid slave id - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "file": job_id = self.headers['job-id'] @@ -288,14 +306,14 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(headers={"job-id": job.id}) self.server.stats("", "Sending file to render node") - f = open(PATH_PREFIX + job.id + ".blend", 'rb') + f = open(self.server.path + job.id + ".blend", 'rb') shutil.copyfileobj(f, self.wfile) f.close() else: # no such job id - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "slave": message = [] @@ -322,33 +340,25 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.server.stats("", "Receiving job") length = int(self.headers['content-length']) - job_frame_string = self.headers['job-frame'] - job_name = self.headers.get('job-name', "") - job_chunks = int(self.headers.get('job-chunks', "1")) - blacklist = self.headers.get('slave-blacklist', '').split() - job_path = str(self.rfile.read(length), encoding='utf8') + job_info = netrender.model.RenderJob.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - if os.path.exists(job_path): - job_id = self.server.nextJobID() - - job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) - self.server.addJob(job) + job_id = self.server.nextJobID() + + print("chunks", job_info.chunks) + + job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) + self.server.addJob(job) + + for frame in job_info.frames: + frame = job.addFrame(frame.number) - if ":" in job_frame_string: - frame_start, frame_end = [int(x) for x in job_frame_string.split(":")] - - for job_frame in range(frame_start, frame_end + 1): - frame = job.addFrame(job_frame) - else: - job_frame = int(job_frame_string) - frame = job.addFrame(job_frame) - - job.start() - - self.send_head(headers={"job-id": job_id}) + headers={"job-id": job_id} + + if job.testStart(): + self.send_head(headers=headers) else: - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.ACCEPTED, headers=headers) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "cancel": job_id = self.headers.get('job-id', "") @@ -375,7 +385,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head() else: # job not found - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "slave": length = int(self.headers['content-length']) @@ -412,7 +422,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_path = job_id + ".blend" - f = open(PATH_PREFIX + job_path, "wb") + f = open(self.server.path + job_path, "wb") f.write(buf) f.close() del buf @@ -445,7 +455,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if job_result == DONE: length = int(self.headers['content-length']) buf = self.rfile.read(length) - f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".exr", 'wb') + f = open(self.server.path + job_id + "%04d" % job_frame + ".exr", 'wb') f.write(buf) f.close() @@ -471,7 +481,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): print("log length:", length) buf = self.rfile.read(length) - f = open(PATH_PREFIX + job_id + "%04d" % job_frame + ".log", 'wb') + f = open(self.server.path + job_id + "%04d" % job_frame + ".log", 'wb') f.write(buf) f.close() @@ -483,20 +493,21 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): class RenderMasterServer(http.server.HTTPServer): - def __init__(self, address, handler_class): + def __init__(self, address, handler_class, path): super().__init__(address, handler_class) self.jobs = [] self.jobs_map = {} self.slaves = [] self.slaves_map = {} self.job_id = 0 + self.path = path def nextJobID(self): self.job_id += 1 return str(self.job_id) - def addSlave(self, name, adress, stats): - slave = MRenderSlave(name, adress, stats) + def addSlave(self, name, address, stats): + slave = MRenderSlave(name, address, stats) self.slaves.append(slave) self.slaves_map[slave.id] = slave diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 98866ff1dfc..8b919b1fa36 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -10,7 +10,7 @@ class RenderSlave: def __init__(self): self.id = "" self.name = "" - self.adress = (0,0) + self.address = (0,0) self.stats = "" self.total_done = 0 self.total_error = 0 @@ -20,7 +20,7 @@ class RenderSlave: return { "id": self.id, "name": self.name, - "adress": self.adress, + "address": self.address, "stats": self.stats, "total_done": self.total_done, "total_error": self.total_error, @@ -40,7 +40,7 @@ class RenderSlave: slave = RenderSlave() slave.id = slave_id slave.name = data["name"] - slave.adress = data["adress"] + slave.address = data["address"] slave.stats = data["stats"] slave.total_done = data["total_done"] slave.total_error = data["total_error"] @@ -54,7 +54,7 @@ class RenderJob: def __init__(self): self.id = "" self.name = "" - self.path = "" + self.files = [] self.frames = [] self.chunks = 0 self.priority = 0 @@ -62,6 +62,11 @@ class RenderJob: self.blacklist = [] self.last_dispatched = 0.0 + def addFrame(self, frame_number): + frame = RenderFrame(frame_number) + self.frames.append(frame) + return frame + def __len__(self): return len(self.frames) @@ -96,8 +101,9 @@ class RenderJob: return { "id": self.id, "name": self.name, - "path": self.path, + "files": self.files, "frames": [f.serialize() for f in self.frames if not frames or f in frames], + "chunks": self.chunks, "priority": self.priority, "credits": self.credits, "blacklist": self.blacklist, @@ -112,8 +118,9 @@ class RenderJob: job = RenderJob() job.id = data["id"] job.name = data["name"] - job.path = data["path"] + job.files = data["files"] job.frames = [RenderFrame.materialize(f) for f in data["frames"]] + job.chunks = data["chunks"] job.priority = data["priority"] job.credits = data["credits"] job.blacklist = data["blacklist"] @@ -122,8 +129,8 @@ class RenderJob: return job class RenderFrame: - def __init__(self): - self.number = 0 + def __init__(self, number = 0): + self.number = number self.time = 0 self.status = QUEUED self.slave = None diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 8df662b6b52..a1208aa1b46 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -48,7 +48,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): return True def execute(self, context): - netprops = context.scene.network_render + netsettings = context.scene.network_render conn = clientConnection(context.scene) if conn: @@ -59,12 +59,12 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8'))) - while(len(netprops.jobs) > 0): - netprops.jobs.remove(0) + while(len(netsettings.jobs) > 0): + netsettings.jobs.remove(0) for j in jobs: - netprops.jobs.add() - job = netprops.jobs[-1] + netsettings.jobs.add() + job = netsettings.jobs[-1] job_results = j.framesStatus() @@ -93,22 +93,22 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator): return True def execute(self, context): - netprops = context.scene.network_render + netsettings = context.scene.network_render - if netprops.active_slave_index >= 0: + if netsettings.active_slave_index >= 0: - slave = netrender.slaves[netprops.active_slave_index] + slave = netrender.slaves[netsettings.active_slave_index] - netprops.slaves_blacklist.add() + netsettings.slaves_blacklist.add() - netprops.slaves_blacklist[-1].id = slave.id - netprops.slaves_blacklist[-1].name = slave.name - netprops.slaves_blacklist[-1].adress = slave.adress - netprops.slaves_blacklist[-1].last_seen = slave.last_seen - netprops.slaves_blacklist[-1].stats = slave.stats + netsettings.slaves_blacklist[-1].id = slave.id + netsettings.slaves_blacklist[-1].name = slave.name + netsettings.slaves_blacklist[-1].address = slave.address + netsettings.slaves_blacklist[-1].last_seen = slave.last_seen + netsettings.slaves_blacklist[-1].stats = slave.stats - netprops.slaves.remove(netprops.active_slave_index) - netprops.active_slave_index = -1 + netsettings.slaves.remove(netsettings.active_slave_index) + netsettings.active_slave_index = -1 return ('FINISHED',) @@ -129,22 +129,22 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): return True def execute(self, context): - netprops = context.scene.network_render + netsettings = context.scene.network_render - if netprops.active_blacklisted_slave_index >= 0: + if netsettings.active_blacklisted_slave_index >= 0: - slave = netprops.slaves_blacklist[netprops.active_blacklisted_slave_index] + slave = netsettings.slaves_blacklist[netsettings.active_blacklisted_slave_index] - netprops.slaves.add() + netsettings.slaves.add() - netprops.slaves[-1].id = slave.id - netprops.slaves[-1].name = slave.name - netprops.slaves[-1].adress = slave.adress - netprops.slaves[-1].last_seen = slave.last_seen - netprops.slaves[-1].stats = slave.stats + netsettings.slaves[-1].id = slave.id + netsettings.slaves[-1].name = slave.name + netsettings.slaves[-1].address = slave.address + netsettings.slaves[-1].last_seen = slave.last_seen + netsettings.slaves[-1].stats = slave.stats - netprops.slaves_blacklist.remove(netprops.active_blacklisted_slave_index) - netprops.active_blacklisted_slave_index = -1 + netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index) + netsettings.active_blacklisted_slave_index = -1 return ('FINISHED',) @@ -166,7 +166,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): return True def execute(self, context): - netprops = context.scene.network_render + netsettings = context.scene.network_render conn = clientConnection(context.scene) if conn: @@ -177,21 +177,21 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8'))) - while(len(netprops.slaves) > 0): - netprops.slaves.remove(0) + while(len(netsettings.slaves) > 0): + netsettings.slaves.remove(0) for s in slaves: - for slave in netprops.slaves_blacklist: + for slave in netsettings.slaves_blacklist: if slave.id == s.id: break - netprops.slaves.add() - slave = netprops.slaves[-1] + netsettings.slaves.add() + slave = netsettings.slaves[-1] slave.id = s.id slave.name = s.name slave.stats = s.stats - slave.adress = s.adress[0] + slave.address = s.address[0] slave.last_seen = time.ctime(s.last_seen) return ('FINISHED',) @@ -210,15 +210,15 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): __props__ = [] def poll(self, context): - netprops = context.scene.network_render - return netprops.active_job_index >= 0 and len(netprops.jobs) > 0 + netsettings = context.scene.network_render + return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 def execute(self, context): - netprops = context.scene.network_render + netsettings = context.scene.network_render conn = clientConnection(context.scene) if conn: - job = netprops.jobs[netprops.active_job_index] + job = netsettings.jobs[netsettings.active_job_index] conn.request("POST", "cancel", headers={"job-id":job.id}) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 59c474293b3..64801743d70 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -21,18 +21,51 @@ def testCancel(conn, job_id): response = conn.getresponse() # cancelled if job isn't found anymore - if response.status == http.client.NOT_FOUND: + if response.status == http.client.NO_CONTENT: return True else: return False +def testFile(conn, JOB_PREFIX, file_path, main_path = None): + if os.path.isabs(file_path): + # if an absolute path, make sure path exists, if it doesn't, use relative local path + job_full_path = file_path + if not os.path.exists(job_full_path): + p, n = os.path.split(job_full_path) + + if main_path and p.startswith(main_path): + directory = JOB_PREFIX + p[len(main_path):] + job_full_path = directory + n + if not os.path.exists(directory): + os.mkdir(directory) + else: + job_full_path = JOB_PREFIX + n + else: + job_full_path = JOB_PREFIX + file_path + + if not os.path.exists(job_full_path): + conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id}) + response = conn.getresponse() + + if response.status != http.client.OK: + return None # file for job not returned by server, need to return an error code to server + + f = open(job_full_path, "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + return job_full_path + + def render_slave(engine, scene): - NODE_PREFIX = PATH_PREFIX + "node" + os.sep + netsettings = scene.network_render timeout = 1 - if not os.path.exists(NODE_PREFIX): - os.mkdir(NODE_PREFIX) - engine.update_stats("", "Network render node initiation") conn = clientConnection(scene) @@ -43,6 +76,10 @@ def render_slave(engine, scene): slave_id = response.getheader("slave-id") + NODE_PREFIX = netsettings.path + "node_" + slave_id + os.sep + if not os.path.exists(NODE_PREFIX): + os.mkdir(NODE_PREFIX) + while not engine.test_break(): conn.request("GET", "job", headers={"slave-id":slave_id}) @@ -53,41 +90,30 @@ def render_slave(engine, scene): job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8'))) - print("File:", job.path) - engine.update_stats("", "Render File", job.path, "for job", job.id) + JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep + if not os.path.exists(JOB_PREFIX): + os.mkdir(JOB_PREFIX) - if os.path.isabs(job.path): - # if an absolute path, make sure path exists, if it doesn't, use relative local path - job_full_path = job.path - if not os.path.exists(job_full_path): - job_full_path = NODE_PREFIX + job.id + ".blend" - else: - job_full_path = NODE_PREFIX + job.path + job_path = job.files[0] + main_path, main_file = os.path.split(job_path) - if not os.path.exists(job_full_path): - conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id}) - response = conn.getresponse() - - if response.status != http.client.OK: - break # file for job not returned by server, need to return an error code to server - - f = open(job_full_path, "wb") - buf = response.read(1024) - - while buf: - f.write(buf) - buf = response.read(1024) - - f.close() + job_full_path = testFile(conn, JOB_PREFIX, job_path) + print("Fullpath", job_full_path) + print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) + engine.update_stats("", "Render File", main_file, "for job", job.id) + + for file_path in job.files[1:]: + testFile(conn, JOB_PREFIX, file_path, main_path) frame_args = [] for frame in job.frames: + print("frame", frame.number) frame_args += ["-f", str(frame.number)] start_t = time.time() - process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", NODE_PREFIX + job.id, "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) cancelled = False stdout = bytes() @@ -120,7 +146,7 @@ def render_slave(engine, scene): for frame in job.frames: headers["job-frame"] = str(frame.number) # send result back to server - f = open(NODE_PREFIX + job.id + "%04d" % frame.number + ".exr", 'rb') + f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') conn.request("PUT", "render", f, headers=headers) f.close() response = conn.getresponse() diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 71b013c5a63..f8179fedbda 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -48,9 +48,11 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col.itemR(scene.network_render, "mode") col.itemR(scene.network_render, "server_address") col.itemR(scene.network_render, "server_port") + col.itemR(scene.network_render, "path") if scene.network_render.mode == "RENDER_CLIENT": col.itemR(scene.network_render, "chunks") + col.itemR(scene.network_render, "priority") col.itemR(scene.network_render, "job_name") col.itemO("render.netclientsend", text="send job to server") bpy.types.register(SCENE_PT_network_settings) @@ -84,7 +86,7 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): slave = netrender.slaves[netrender.active_slave_index] layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Adress: " + slave.adress) + layout.itemL(text="Address: " + slave.address) layout.itemL(text="Seen: " + slave.last_seen) layout.itemL(text="Stats: " + slave.stats) @@ -119,7 +121,7 @@ class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): slave = netrender.slaves_blacklist[netrender.active_blacklisted_slave_index] layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Adress: " + slave.adress) + layout.itemL(text="Address: " + slave.address) layout.itemL(text="Seen: " + slave.last_seen) layout.itemL(text="Stats: " + slave.stats) @@ -189,6 +191,12 @@ NetRenderSettings.IntProperty( attr="server_port", min=1, max=65535) +NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = "/tmp/") + NetRenderSettings.StringProperty( attr="job_name", name="Job name", description="Name of the job", @@ -202,6 +210,13 @@ NetRenderSettings.IntProperty( attr="chunks", min=1, max=65535) +NetRenderSettings.IntProperty( attr="priority", + name="Priority", + description="Priority of the job", + default = 1, + min=1, + max=10) + NetRenderSettings.StringProperty( attr="job_id", name="Network job id", description="id of the last sent render job", @@ -249,8 +264,8 @@ NetRenderSlave.StringProperty( attr="name", maxlen = 64, default = "") -NetRenderSlave.StringProperty( attr="adress", - name="Adress of the slave", +NetRenderSlave.StringProperty( attr="address", + name="Address of the slave", description="", maxlen = 64, default = "") diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index c158ff115fa..d64b6fcda1e 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -3,9 +3,9 @@ import sys, os import http, http.client, http.server, urllib import subprocess, shutil, time, hashlib -VERSION = b"0.3" +import netrender.model -PATH_PREFIX = "/tmp/" +VERSION = b"0.3" QUEUED = 0 DISPATCHED = 1 @@ -41,40 +41,46 @@ def clientVerifyVersion(conn): return True def clientSendJob(conn, scene, anim = False, chunks = 5): + netsettings = scene.network_render + job = netrender.model.RenderJob() if anim: - job_frame = "%i:%i" % (scene.start_frame, scene.end_frame) + for f in range(scene.start_frame, scene.end_frame + 1): + job.addFrame(f) else: - job_frame = "%i" % (scene.current_frame, ) - - blacklist = [] + job.addFrame(scene.current_frame) filename = bpy.data.filename + job.files.append(filename) - name = scene.network_render.job_name - + name = netsettings.job_name if name == "[default]": path, name = os.path.split(filename) + job.name = name + for slave in scene.network_render.slaves_blacklist: - blacklist.append(slave.id) - - blacklist = " ".join(blacklist) + job.blacklist.append(slave.id) - headers = {"job-frame":job_frame, "job-name":name, "job-chunks": str(chunks), "slave-blacklist": blacklist} + job.chunks = netsettings.chunks + job.priority = netsettings.priority # try to send path first - conn.request("POST", "job", filename, headers=headers) + conn.request("POST", "job", repr(job.serialize())) response = conn.getresponse() + job_id = response.getheader("job-id") + # if not found, send whole file if response.status == http.client.NOT_FOUND: f = open(bpy.data.filename, "rb") - conn.request("PUT", "file", f, headers=headers) + conn.request("PUT", "file", f, headers={"job-id": job_id}) f.close() response = conn.getresponse() - return response.getheader("job-id") + # server will reply with NOT_FOUD until all files are found + + return job_id def clientRequestResult(conn, scene, job_id): conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) -- cgit v1.2.3 From d7a5cccb5bfc90c724d4771ec52bce9902a73b60 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 1 Sep 2009 06:48:40 +0000 Subject: 2.5 - Code shuffling in arithb.c * Moved all the euler-rotation functions so that they were near each other in the file. * Tagged all functions relevant to axis-angle rotations --- source/blender/blenlib/intern/arithb.c | 217 +++++++++++++++++---------------- 1 file changed, 111 insertions(+), 106 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index ebead4bce9b..32bacc9472c 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -1610,7 +1610,7 @@ void VecUpMat3(float *vec, float mat[][3], short axis) } /* A & M Watt, Advanced animation and rendering techniques, 1992 ACM press */ -void QuatInterpolW(float *, float *, float *, float ); +void QuatInterpolW(float *, float *, float *, float ); // XXX why this? void QuatInterpolW(float *result, float *quat1, float *quat2, float t) { @@ -2943,6 +2943,112 @@ void EulToQuat(float *eul, float *quat) quat[3] = cj*cs - sj*sc; } +void euler_rot(float *beul, float ang, char axis) +{ + float eul[3], mat1[3][3], mat2[3][3], totmat[3][3]; + + eul[0]= eul[1]= eul[2]= 0.0f; + if(axis=='x') eul[0]= ang; + else if(axis=='y') eul[1]= ang; + else eul[2]= ang; + + EulToMat3(eul, mat1); + EulToMat3(beul, mat2); + + Mat3MulMat3(totmat, mat2, mat1); + + Mat3ToEul(totmat, beul); + +} + +/* exported to transform.c */ +void compatible_eul(float *eul, float *oldrot) +{ + float dx, dy, dz; + + /* correct differences of about 360 degrees first */ + dx= eul[0] - oldrot[0]; + dy= eul[1] - oldrot[1]; + dz= eul[2] - oldrot[2]; + + while(fabs(dx) > 5.1) { + if(dx > 0.0f) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI; + dx= eul[0] - oldrot[0]; + } + while(fabs(dy) > 5.1) { + if(dy > 0.0f) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI; + dy= eul[1] - oldrot[1]; + } + while(fabs(dz) > 5.1) { + if(dz > 0.0f) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI; + dz= eul[2] - oldrot[2]; + } + + /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */ + if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) { + if(dx > 0.0) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI; + } + if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) { + if(dy > 0.0) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI; + } + if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) { + if(dz > 0.0) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI; + } + + /* the method below was there from ancient days... but why! probably because the code sucks :) + */ +#if 0 + /* calc again */ + dx= eul[0] - oldrot[0]; + dy= eul[1] - oldrot[1]; + dz= eul[2] - oldrot[2]; + + /* special case, tested for x-z */ + + if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) { + if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI; + if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1]; + if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI; + + } + else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) { + if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI; + if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI; + if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2]; + } + else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) { + if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0]; + if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI; + if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI; + } +#endif +} + +/* uses 2 methods to retrieve eulers, and picks the closest */ +void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) +{ + float eul1[3], eul2[3]; + float d1, d2; + + mat3_to_eul2(mat, eul1, eul2); + + compatible_eul(eul1, oldrot); + compatible_eul(eul2, oldrot); + + d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]); + d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]); + + /* return best, which is just the one with lowest difference */ + if( d1 > d2) { + VecCopyf(eul, eul2); + } + else { + VecCopyf(eul, eul1); + } + +} + +/* axis angle to 3x3 matrix */ void VecRotToMat3(float *vec, float phi, float mat[][3]) { /* rotation of phi radials around vec */ @@ -2969,6 +3075,7 @@ void VecRotToMat3(float *vec, float phi, float mat[][3]) } +/* axis angle to 4x4 matrix */ void VecRotToMat4(float *vec, float phi, float mat[][4]) { float tmat[3][3]; @@ -2978,6 +3085,7 @@ void VecRotToMat4(float *vec, float phi, float mat[][4]) Mat4CpyMat3(mat, tmat); } +/* axis angle to quaternion */ void VecRotToQuat(float *vec, float phi, float *quat) { /* rotation of phi radials around vec */ @@ -3074,111 +3182,6 @@ float NormalizedVecAngle2_2D(float *v1, float *v2) return 2.0f*(float)saasin(Vec2Lenf(v2, v1)/2.0f); } -void euler_rot(float *beul, float ang, char axis) -{ - float eul[3], mat1[3][3], mat2[3][3], totmat[3][3]; - - eul[0]= eul[1]= eul[2]= 0.0f; - if(axis=='x') eul[0]= ang; - else if(axis=='y') eul[1]= ang; - else eul[2]= ang; - - EulToMat3(eul, mat1); - EulToMat3(beul, mat2); - - Mat3MulMat3(totmat, mat2, mat1); - - Mat3ToEul(totmat, beul); - -} - -/* exported to transform.c */ -void compatible_eul(float *eul, float *oldrot) -{ - float dx, dy, dz; - - /* correct differences of about 360 degrees first */ - dx= eul[0] - oldrot[0]; - dy= eul[1] - oldrot[1]; - dz= eul[2] - oldrot[2]; - - while(fabs(dx) > 5.1) { - if(dx > 0.0f) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI; - dx= eul[0] - oldrot[0]; - } - while(fabs(dy) > 5.1) { - if(dy > 0.0f) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI; - dy= eul[1] - oldrot[1]; - } - while(fabs(dz) > 5.1) { - if(dz > 0.0f) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI; - dz= eul[2] - oldrot[2]; - } - - /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */ - if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) { - if(dx > 0.0) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI; - } - if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) { - if(dy > 0.0) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI; - } - if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) { - if(dz > 0.0) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI; - } - - /* the method below was there from ancient days... but why! probably because the code sucks :) - */ -#if 0 - /* calc again */ - dx= eul[0] - oldrot[0]; - dy= eul[1] - oldrot[1]; - dz= eul[2] - oldrot[2]; - - /* special case, tested for x-z */ - - if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) { - if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI; - if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1]; - if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI; - - } - else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) { - if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI; - if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI; - if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2]; - } - else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) { - if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0]; - if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI; - if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI; - } -#endif -} - -/* uses 2 methods to retrieve eulers, and picks the closest */ -void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) -{ - float eul1[3], eul2[3]; - float d1, d2; - - mat3_to_eul2(mat, eul1, eul2); - - compatible_eul(eul1, oldrot); - compatible_eul(eul2, oldrot); - - d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]); - d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]); - - /* return best, which is just the one with lowest difference */ - if( d1 > d2) { - VecCopyf(eul, eul2); - } - else { - VecCopyf(eul, eul1); - } - -} - /* ******************************************** */ void SizeToMat3( float *size, float mat[][3]) @@ -4745,6 +4748,8 @@ void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3 mat[3][2] = loc[2]; } +/********************************************************/ + /* Tangents */ /* For normal map tangents we need to detect uv boundaries, and only average -- cgit v1.2.3 From a44b9482603daaec9fa012714ddf4a1558c283fe Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 1 Sep 2009 12:18:17 +0000 Subject: 2.5 - Rotation Orders for Bones [Durian Rigging Request] This commit is the start of an implementation of (euler) rotation orders for Bones (later to be extended to Objects too). Technical details and references can be found at: http://wiki.blender.org/index.php/User:Aligorith/EulerRotationOrder In short, I've added a new set of Euler conversion functions (EulO... and ...EulO), coexisting with the old functions for now, which can handle different rotation orders. Changes have only been made to the basic evaluation code. However, the following places will still need modifications: * Transform code - needs to be made to use functions which take rotation order into account instead of using XYZ only * Rotation constraints - same story * Other rotation editing tools for armatures also need a check up, since there might have been some missing code when I ported eulers earlier --- source/blender/blenkernel/intern/armature.c | 4 +- source/blender/blenlib/BLI_arithb.h | 47 ++++-- source/blender/blenlib/intern/arithb.c | 217 ++++++++++++++++++++++++--- source/blender/editors/transform/transform.c | 2 +- source/blender/makesdna/DNA_action_types.h | 9 +- source/blender/makesrna/intern/rna_pose.c | 9 +- 6 files changed, 254 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 7b894d79b45..631bc2cb88c 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1988,9 +1988,9 @@ void chan_calc_mat(bPoseChannel *chan) SizeToMat3(chan->size, smat); /* rotations may either be quats or eulers (no rotation modes for now...) */ - if (chan->rotmode) { + if (chan->rotmode > 0) { /* euler rotations (will cause gimble lock... no rotation order to solve that yet) */ - EulToMat3(chan->eul, rmat); + EulOToMat3(chan->eul, chan->rotmode, rmat); } else { /* quats are normalised before use to eliminate scaling issues */ diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 0a0749d3382..4156e3c52ec 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -174,7 +174,36 @@ void CalcNormShort(short *v1, short *v2, short *v3, float *n); float power_of_2(float val); /** - * @section Euler conversion routines + * @section Euler conversion routines (With Custom Order) + */ + +/* Defines for rotation orders + * WARNING: must match the ePchan_RotMode in DNA_action_types.h + * order matters - types are saved to file! + */ +typedef enum eEulerRotationOrders { + EULER_ORDER_DEFAULT = 1, /* Blender 'default' (classic) is basically XYZ */ + EULER_ORDER_XYZ = 1, /* Blender 'default' (classic) - must be as 1 to sync with PoseChannel rotmode */ + EULER_ORDER_XZY, + EULER_ORDER_YXZ, + EULER_ORDER_YZX, + EULER_ORDER_ZXY, + EULER_ORDER_ZYX, + /* NOTE: there are about 6 more entries when including duplicated entries too */ +} eEulerRotationOrders; + +void EulOToQuat(float eul[3], short order, float quat[4]); + +void EulOToMat3(float eul[3], short order, float Mat[3][3]); +void EulOToMat4(float eul[3], short order, float Mat[4][4]); + +void Mat3ToEulO(float Mat[3][3], float eul[3], short order); +void Mat4ToEulO(float Mat[4][4], float eul[3], short order); + +void QuatToEulO(float quat[4], float eul[3], short order); + +/** + * @section Euler conversion routines (Blender XYZ) */ void EulToMat3(float *eul, float mat[][3]); @@ -185,11 +214,14 @@ void Mat4ToEul(float tmat[][4],float *eul); void EulToQuat(float *eul, float *quat); -void compatible_eul(float *eul, float *oldrot); - void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot); + +void compatible_eul(float *eul, float *oldrot); +void euler_rot(float *beul, float ang, char axis); + + /** * @section Quaternion arithmetic routines */ @@ -216,6 +248,8 @@ void printquat(char *str, float q[4]); void QuatInterpol(float *result, float *quat1, float *quat2, float t); void QuatAdd(float *result, float *quat1, float *quat2, float t); +void QuatToMat3(float *q, float m[][3]); +void QuatToMat4(float *q, float m[][4]); /** * @section matrix multiplication and copying routines @@ -349,8 +383,6 @@ float NormalizedVecAngle2(float *v1, float *v2); float VecAngle3_2D(float *v1, float *v2, float *v3); float NormalizedVecAngle2_2D(float *v1, float *v2); - -void euler_rot(float *beul, float ang, char axis); void NormalShortToFloat(float *out, short *in); void NormalFloatToShort(short *out, float *in); @@ -422,9 +454,6 @@ void VecStar(float mat[][3],float *vec); short EenheidsMat(float mat[][3]); -void QuatToMat3(float *q, float m[][3]); -void QuatToMat4(float *q, float m[][4]); - void Mat3ToQuat_is_ok(float wmat[][3], float *q); void i_ortho(float left, float right, float bottom, float top, float nearClip, float farClip, float matrix[][4]); @@ -435,8 +464,6 @@ void i_rotate(float angle, char axis, float mat[][4]); - - void MinMax3(float *min, float *max, float *vec); void SizeToMat3(float *size, float mat[][3]); void SizeToMat4(float *size, float mat[][4]); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 32bacc9472c..e0f17864d73 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -1408,22 +1408,6 @@ void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]) AxisAngleToQuat(q, axis, angle); } -void AxisAngleToQuat(float *q, float *axis, float angle) -{ - float nor[3]; - float si; - - VecCopyf(nor, axis); - Normalize(nor); - - angle /= 2; - si = (float)sin(angle); - q[0] = (float)cos(angle); - q[1] = nor[0] * si; - q[2] = nor[1] * si; - q[3] = nor[2] * si; -} - void vectoquat(float *vec, short axis, short upflag, float *q) { float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1; @@ -2807,6 +2791,156 @@ void MeanValueWeights(float v[][3], int n, float *co, float *w) /* ************ EULER *************** */ +/* Euler Rotation Order Code: + * was adapted from + ANSI C code from the article + "Euler Angle Conversion" + by Ken Shoemake, shoemake@graphics.cis.upenn.edu + in "Graphics Gems IV", Academic Press, 1994 + * for use in Blender + */ + +/* Type for rotation order info - see wiki for derivation details */ +typedef struct RotOrderInfo { + short i; /* first axis index */ + short j; /* second axis index */ + short k; /* third axis index */ + short parity; /* parity of axis permuation (even=0, odd=1) - 'n' in original code */ +} RotOrderInfo; + +/* Array of info for Rotation Order calculations + * WARNING: must be kept in same order as eEulerRotationOrders + */ +static RotOrderInfo rotOrders[]= { + /* i, j, k, n */ + {0, 1, 2, 0}, // XYZ + {0, 2, 1, 1}, // XZY + {1, 0, 2, 1}, // YXZ + {1, 2, 0, 0}, // YZX + {2, 0, 1, 0}, // ZXY + {2, 1, 0, 1} // ZYZ +}; + +/* Get relevant pointer to rotation order set from the array + * NOTE: since we start at 1 for the values, but arrays index from 0, + * there is -1 factor involved in this process... + */ +#define GET_ROTATIONORDER_INFO(order) (&rotOrders[(order)-1]) + +/* Construct quaternion from Euler angles (in radians). */ +void EulOToQuat(float e[3], short order, float q[4]) +{ + RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); + short i=R->i, j=R->j, k=R->k; + double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + double a[3]; + + if (R->parity) e[1] = -e[1]; + + ti = e[0]/2; tj = e[1]/2; th = e[2]/2; + + ci = cos(ti); cj = cos(tj); ch = cos(th); + si = sin(ti); sj = sin(tj); sh = sin(th); + + cc = ci*ch; cs = ci*sh; + sc = si*ch; ss = si*sh; + + a[i] = cj*sc - sj*cs; + a[j] = cj*ss + sj*cc; + a[k] = cj*cs - sj*sc; + + q[0] = cj*cc + sj*ss; + q[1] = a[0]; + q[2] = a[1]; + q[3] = a[2]; + + if (R->parity) q[j] = -q[j]; +} + +/* Construct 3x3 matrix from Euler angles (in radians). */ +void EulOToMat3(float e[3], short order, float M[3][3]) +{ + RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); + short i=R->i, j=R->j, k=R->k; + double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + + if (R->parity) { + e[0] = -e[0]; + e[1] = -e[1]; + e[2] = -e[2]; + } + + ti = e[0]; tj = e[1]; th = e[2]; + + ci = cos(ti); cj = cos(tj); ch = cos(th); + si = sin(ti); sj = sin(tj); sh = sin(th); + + cc = ci*ch; cs = ci*sh; + sc = si*ch; ss = si*sh; + + M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss; + M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc; + M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci; +} + +/* Construct 4x4 matrix from Euler angles (in radians). */ +void EulOToMat4(float e[3], short order, float M[4][4]) +{ + float m[3][3]; + + /* for now, we'll just do this the slow way (i.e. copying matrices) */ + Mat3Ortho(m); + EulOToMat3(e, order, m); + Mat4CpyMat3(M, m); +} + +/* Convert 3x3 matrix to Euler angles (in radians). */ +void Mat3ToEulO(float M[3][3], float e[3], short order) +{ + RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); + short i=R->i, j=R->j, k=R->k; + double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]); + + if (cy > 16*FLT_EPSILON) { + e[0] = atan2(M[j][k], M[k][k]); + e[1] = atan2(-M[i][k], cy); + e[2] = atan2(M[i][j], M[i][i]); + } + else { + e[0] = atan2(-M[k][j], M[j][j]); + e[1] = atan2(-M[i][k], cy); + e[2] = 0; + } + + if (R->parity) { + e[0] = -e[0]; + e[1] = -e[1]; + e[2] = -e[2]; + } +} + +/* Convert 4x4 matrix to Euler angles (in radians). */ +void Mat4ToEulO(float M[4][4], float e[3], short order) +{ + float m[3][3]; + + /* for now, we'll just do this the slow way (i.e. copying matrices) */ + Mat3CpyMat4(m, M); + Mat3ToEulO(m, e, order); +} + +/* Convert quaternion to Euler angles (in radians). */ +void QuatToEulO(float q[4], float e[3], short order) +{ + float M[3][3]; + + QuatToMat3(q, M); + Mat3ToEulO(M, e, order); +} + +/* ************ EULER (old XYZ) *************** */ + +/* XYZ order */ void EulToMat3( float *eul, float mat[][3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -2834,6 +2968,7 @@ void EulToMat3( float *eul, float mat[][3]) } +/* XYZ order */ void EulToMat4( float *eul,float mat[][4]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -2865,6 +3000,7 @@ void EulToMat4( float *eul,float mat[][4]) } /* returns two euler calculation methods, so we can pick the best */ +/* XYZ order */ static void mat3_to_eul2(float tmat[][3], float *eul1, float *eul2) { float cy, quat[4], mat[3][3]; @@ -2895,6 +3031,7 @@ static void mat3_to_eul2(float tmat[][3], float *eul1, float *eul2) } } +/* XYZ order */ void Mat3ToEul(float tmat[][3], float *eul) { float eul1[3], eul2[3]; @@ -2910,6 +3047,7 @@ void Mat3ToEul(float tmat[][3], float *eul) } } +/* XYZ order */ void Mat4ToEul(float tmat[][4], float *eul) { float tempMat[3][3]; @@ -2919,6 +3057,7 @@ void Mat4ToEul(float tmat[][4], float *eul) Mat3ToEul(tempMat, eul); } +/* XYZ order */ void QuatToEul(float *quat, float *eul) { float mat[3][3]; @@ -2927,7 +3066,7 @@ void QuatToEul(float *quat, float *eul) Mat3ToEul(mat, eul); } - +/* XYZ order */ void EulToQuat(float *eul, float *quat) { float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -2943,6 +3082,7 @@ void EulToQuat(float *eul, float *quat) quat[3] = cj*cs - sj*sc; } +/* XYZ order */ void euler_rot(float *beul, float ang, char axis) { float eul[3], mat1[3][3], mat2[3][3], totmat[3][3]; @@ -2962,6 +3102,7 @@ void euler_rot(float *beul, float ang, char axis) } /* exported to transform.c */ +/* XYZ order */ void compatible_eul(float *eul, float *oldrot) { float dx, dy, dz; @@ -3025,6 +3166,7 @@ void compatible_eul(float *eul, float *oldrot) } /* uses 2 methods to retrieve eulers, and picks the closest */ +/* XYZ order */ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) { float eul1[3], eul2[3]; @@ -3048,6 +3190,46 @@ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) } +/* ************ AXIS ANGLE *************** */ + +/* Axis angle to Quaternions */ +void AxisAngleToQuat(float *q, float *axis, float angle) +{ + float nor[3]; + float si; + + VecCopyf(nor, axis); + Normalize(nor); + + angle /= 2; + si = (float)sin(angle); + q[0] = (float)cos(angle); + q[1] = nor[0] * si; + q[2] = nor[1] * si; + q[3] = nor[2] * si; +} + +/* Quaternions to Axis Angle */ +void QuatToAxisAngle(float q[4], float axis[3], float *angle) +{ + float ha, si; + + /* calculate angle/2, and sin(angle/2) */ + ha= (float)acos(q[0]); + si= (float)sin(ha); + + /* from half-angle to angle */ + *angle= ha * 2; + + /* prevent division by zero for axis conversion */ + if (fabs(si) < 0.0005) + si= 1.0f; + + axis[0]= q[1] / si; + axis[1]= q[2] / si; + axis[2]= q[3] / si; +} + /* axis angle to 3x3 matrix */ void VecRotToMat3(float *vec, float phi, float mat[][3]) { @@ -4704,6 +4886,7 @@ float PdistVL3Dfl(float *v1, float *v2, float *v3) /* make a 4x4 matrix out of 3 transform components */ /* matrices are made in the order: scale * rot * loc */ +// TODO: need to have a version that allows for rotation order... void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]) { float rmat[3][3], smat[3][3], tmat[3][3]; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index dd7cebdfe3f..4a376f35552 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2670,7 +2670,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } - else { + else { // TODO: need some methods for the new euler types... float eulmat[3][3]; Mat3MulMat3(totmat, mat, td->mtx); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index c9d75d5c262..474d5a4217f 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -199,8 +199,13 @@ typedef enum ePchan_IkFlag { typedef enum ePchan_RotMode { /* quaternion rotations (default, and for older Blender versions) */ PCHAN_ROT_QUAT = 0, - /* euler rotations (xyz only) */ - PCHAN_ROT_EUL, + /* euler rotations - keep in sync with enum in BLI_arithb.h */ + PCHAN_ROT_XYZ = 1, /* Blender 'default' (classic) - must be as 1 to sync with PoseChannel rotmode */ + PCHAN_ROT_XZY, + PCHAN_ROT_YXZ, + PCHAN_ROT_YZX, + PCHAN_ROT_ZXY, + PCHAN_ROT_ZYX, } ePchan_RotMode; /* Pose ------------------------------------ */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index bfebc5ee49f..727e3ff6a6d 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -124,7 +124,7 @@ static void rna_PoseChannel_euler_rotation_set(PointerRNA *ptr, const float *val { bPoseChannel *pchan= ptr->data; - if(pchan->rotmode == PCHAN_ROT_QUAT) + if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers when using quats... */ EulToQuat((float*)value, pchan->quat); else VECCOPY(pchan->eul, value); @@ -353,7 +353,12 @@ static void rna_def_pose_channel(BlenderRNA *brna) { static EnumPropertyItem prop_rotmode_items[] = { {PCHAN_ROT_QUAT, "QUATERNION", 0, "Quaternion (WXYZ)", "No Gimbal Lock (default)"}, - {PCHAN_ROT_EUL, "EULER", 0, "Euler (XYZ)", "Prone to Gimbal Lock"}, + {PCHAN_ROT_XYZ, "XYZ", 0, "XYZ Euler", "XYZ Rotation Order. Prone to Gimbal Lock"}, + {PCHAN_ROT_XZY, "XZY", 0, "XZY Euler", "XZY Rotation Order. Prone to Gimbal Lock"}, + {PCHAN_ROT_YXZ, "YXZ", 0, "YXZ Euler", "YXZ Rotation Order. Prone to Gimbal Lock"}, + {PCHAN_ROT_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"}, + {PCHAN_ROT_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"}, + {PCHAN_ROT_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"}, {0, NULL, 0, NULL, NULL}}; StructRNA *srna; -- cgit v1.2.3 From 9965e8915d9121fae88aaa98990f714b3c2670bf Mon Sep 17 00:00:00 2001 From: William Reynish Date: Tue, 1 Sep 2009 12:41:06 +0000 Subject: Added the old Edge settings to scene properties. This old feature is really quite terrible as it isn't even resolution independent - the edge width should be relative to the image dimensions. Adjusted layout for sound in sequencer and a few other minor tweaks. --- release/ui/buttons_scene.py | 30 +++++++++++++++++++----------- release/ui/space_sequencer.py | 25 ++++++++++++++++--------- source/blender/makesrna/intern/rna_scene.c | 4 ++-- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index 126afc4ef23..d8b2b51751b 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -189,20 +189,28 @@ class SCENE_PT_post_processing(RenderButtonsPanel): col = split.column() col.itemR(rd, "use_compositing") col.itemR(rd, "use_sequencer") - + col = split.column() - row = col.row() - row.itemR(rd, "fields", text="Fields") - sub = row.row() + col.itemR(rd, "dither_intensity", text="Dither", slider=True) + + layout.itemS() + + split = layout.split() + + col = split.column() + col.itemR(rd, "fields", text="Fields") + sub = col.column() sub.active = rd.fields + sub.row().itemR(rd, "field_order", expand=True) sub.itemR(rd, "fields_still", text="Still") - sub = col.row() - sub.active = rd.fields - sub.itemR(rd, "field_order", expand=True) - - split = layout.split() - split.itemL() - split.itemR(rd, "dither_intensity", text="Dither", slider=True) + + col = split.column() + + col.itemR(rd, "edge") + sub = col.column() + sub.active = rd.edge + sub.itemR(rd, "edge_threshold", text="Threshold", slider=True) + sub.itemR(rd, "edge_color", text="") class SCENE_PT_output(RenderButtonsPanel): __label__ = "Output" diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index 87111b2925f..bef48f5ebdb 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -303,6 +303,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel): row.itemR(strip, "frame_locked", text="Frame Lock") col = layout.column() + col.enabled = not strip.lock col.itemR(strip, "channel") col.itemR(strip, "start_frame") col.itemR(strip, "length") @@ -422,16 +423,21 @@ class SEQUENCER_PT_input(SequencerButtonsPanel): strip = act_strip(context) - layout.itemR(strip, "directory", text="") - - # Current element for the filename - split = layout.split(percentage=0.3) + split = layout.split(percentage=0.2) col = split.column() - col.itemL(text="File Name:") + col.itemL(text="Path:") col = split.column() + col.itemR(strip, "directory", text="") + + # Current element for the filename + elem = strip.getStripElem(context.scene.current_frame) if elem: + split = layout.split(percentage=0.2) + col = split.column() + col.itemL(text="File:") + col = split.column() col.itemR(elem, "filename", text="") # strip.elements[0] could be a fallback if strip.type != 'SOUND': @@ -477,14 +483,15 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel): layout.template_ID(strip, "sound", new="sound.open") layout.itemS() + layout.itemR(strip.sound, "filename", text="") + row = layout.row() if strip.sound.packed_file: - layout.itemO("sound.unpack") + row.itemO("sound.unpack", icon='ICON_PACKAGE', text="Unpack") else: - layout.itemO("sound.pack") + row.itemO("sound.pack", icon='ICON_UGLYPACKAGE', text="Pack") - layout.itemR(strip.sound, "filename") - layout.itemR(strip.sound, "caching") + row.itemR(strip.sound, "caching") class SEQUENCER_PT_filter(SequencerButtonsPanel): __label__ = "Filter" diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 02b891c6cd2..935bf8ccc3f 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1621,10 +1621,10 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Edge", "Create a toon outline around the edges of geometry"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "edge_intensity", PROP_INT, PROP_NONE); + prop= RNA_def_property(srna, "edge_threshold", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "edgeint"); RNA_def_property_range(prop, 0, 255); - RNA_def_property_ui_text(prop, "Edge Intensity", "Threshold for drawing outlines on geometry edges"); + RNA_def_property_ui_text(prop, "Edge Threshold", "Threshold for drawing outlines on geometry edges"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "edge_color", PROP_FLOAT, PROP_COLOR); -- cgit v1.2.3 From add244bca8259e171155be6917307136fcb8e2c8 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 1 Sep 2009 14:59:50 +0000 Subject: 2.5 Buttons: * Fix for Point Density Texture panel. "System" label was there before the pointer button showed up. (For Source Type Particle System.) --- release/ui/buttons_scene.py | 1 - release/ui/buttons_texture.py | 32 +++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index d8b2b51751b..3c321f11f6e 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -205,7 +205,6 @@ class SCENE_PT_post_processing(RenderButtonsPanel): sub.itemR(rd, "fields_still", text="Still") col = split.column() - col.itemR(rd, "edge") sub = col.column() sub.active = rd.edge diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index ee3f85e15ef..90ce40b4832 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -665,27 +665,21 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): if pd.point_source == 'PARTICLE_SYSTEM': col.itemL(text="Object:") col.itemR(pd, "object", text="") - col = col.column() - col.enabled = pd.object - col.itemL(text="System:") - col.item_pointerR(pd, "particle_system", pd.object, "particle_systems", text="") - col.itemL(text="Cache:") - col.itemR(pd, "particle_cache", text="") + + sub = col.column() + sub.enabled = pd.object + if pd.object: + sub.itemL(text="System:") + sub.item_pointerR(pd, "particle_system", pd.object, "particle_systems", text="") + sub.itemL(text="Cache:") + sub.itemR(pd, "particle_cache", text="") else: col.itemL(text="Object:") col.itemR(pd, "object", text="") col.itemL(text="Cache:") col.itemR(pd, "vertices_cache", text="") - sub = split.column() - - sub.itemL() - sub.itemR(pd, "radius") - - sub.itemL(text="Falloff:") - sub.itemR(pd, "falloff", text="") - if pd.falloff == 'SOFT': - sub.itemR(pd, "falloff_softness") + col.itemS() col.itemL(text="Color Source:") col.itemR(pd, "color_source", text="") @@ -694,6 +688,14 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_AGE'): layout.template_color_ramp(pd.color_ramp, expand=True) + col = split.column() + col.itemL() + col.itemR(pd, "radius") + col.itemL(text="Falloff:") + col.itemR(pd, "falloff", text="") + if pd.falloff == 'SOFT': + col.itemR(pd, "falloff_softness") + class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel): __label__ = "Turbulence" -- cgit v1.2.3 From 6d5f824518cdbf8bf710096ab369624d12d23037 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Sep 2009 16:37:23 +0000 Subject: - enum for convex hull and triangle mesh were swapped - python pedantry --- release/ui/space_time.py | 4 ++-- release/ui/space_view3d.py | 22 +++++++++++----------- source/blender/makesrna/intern/rna_object.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/release/ui/space_time.py b/release/ui/space_time.py index 81681e42d92..bb82eea3272 100644 --- a/release/ui/space_time.py +++ b/release/ui/space_time.py @@ -141,8 +141,8 @@ class TIME_MT_autokey(bpy.types.Menu): layout.active = tools.enable_auto_key - layout.item_enumR(tools, "autokey_mode", "ADD_REPLACE_KEYS") - layout.item_enumR(tools, "autokey_mode", "REPLACE_KEYS") + layout.item_enumR(tools, "autokey_mode", 'ADD_REPLACE_KEYS') + layout.item_enumR(tools, "autokey_mode", 'REPLACE_KEYS') bpy.types.register(TIME_HT_header) bpy.types.register(TIME_MT_view) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 5801f9e7941..c5c1abf1d40 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -42,7 +42,7 @@ class VIEW3D_HT_header(bpy.types.Header): # ********** Utilities ********** class VIEW3D_MT_showhide(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" _operator_name = "" @@ -54,7 +54,7 @@ class VIEW3D_MT_showhide(bpy.types.Menu): layout.item_booleanO("%s.hide" % self._operator_name, "unselected", True, text="Hide Unselected") class VIEW3D_MT_snap(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Snap" def draw(self, context): @@ -136,7 +136,7 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu): layout.item_floatO("view3d.zoom", "delta", -1.0, text="Zoom Out") class VIEW3D_MT_view_align(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Align View" def draw(self, context): @@ -145,7 +145,7 @@ class VIEW3D_MT_view_align(bpy.types.Menu): layout.itemO("view3d.view_center") class VIEW3D_MT_view_cameras(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Cameras" def draw(self, context): @@ -580,7 +580,7 @@ class VIEW3D_MT_PARTICLE_showhide(VIEW3D_MT_showhide): # ********** Pose Menu ********** class VIEW3D_MT_POSE(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Pose" def draw(self, context): @@ -638,7 +638,7 @@ class VIEW3D_MT_POSE(bpy.types.Menu): layout.item_menu_enumO("pose.flags_set", 'mode', text="Bone Settings") class VIEW3D_MT_POSE_transform(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Clear Transform" def draw(self, context): @@ -653,7 +653,7 @@ class VIEW3D_MT_POSE_transform(bpy.types.Menu): layout.itemL(text="Origin") class VIEW3D_MT_POSE_pose(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Pose Library" def draw(self, context): @@ -668,7 +668,7 @@ class VIEW3D_MT_POSE_pose(bpy.types.Menu): layout.itemO("poselib.pose_remove", text="Remove Pose...") class VIEW3D_MT_POSE_motion(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Motion Paths" def draw(self, context): @@ -678,7 +678,7 @@ class VIEW3D_MT_POSE_motion(bpy.types.Menu): layout.itemO("pose.paths_clear", text="Clear") class VIEW3D_MT_POSE_group(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Bone Groups" def draw(self, context): @@ -693,7 +693,7 @@ class VIEW3D_MT_POSE_group(bpy.types.Menu): class VIEW3D_MT_POSE_ik(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Inverse Kinematics" def draw(self, context): @@ -703,7 +703,7 @@ class VIEW3D_MT_POSE_ik(bpy.types.Menu): layout.itemO("pose.ik_clear") class VIEW3D_MT_POSE_constraints(bpy.types.Menu): - __space_type__ = "VIEW_3D" + __space_type__ = 'VIEW_3D' __label__ = "Constraints" def draw(self, context): diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 0535ae131bc..bbb10991564 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -774,8 +774,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna) {OB_BOUND_SPHERE, "SPHERE", 0, "Sphere", ""}, {OB_BOUND_CYLINDER, "CYLINDER", 0, "Cylinder", ""}, {OB_BOUND_CONE, "CONE", 0, "Cone", ""}, - {OB_BOUND_POLYH, "CONVEX_HULL", 0, "Convex Hull", ""}, - {OB_BOUND_POLYT, "TRIANGLE_MESH", 0, "Triangle Mesh", ""}, + {OB_BOUND_POLYT, "CONVEX_HULL", 0, "Convex Hull", ""}, + {OB_BOUND_POLYH, "TRIANGLE_MESH", 0, "Triangle Mesh", ""}, //{OB_DYN_MESH, "DYNAMIC_MESH", 0, "Dynamic Mesh", ""}, {0, NULL, 0, NULL, NULL}}; -- cgit v1.2.3 From 83e9144ff0e077c2d9ffd3c0e1b0c2327eb3e497 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 1 Sep 2009 17:10:56 +0000 Subject: 2.5 Background picture used bad scissor/viewport code, causing bad drawing on tool region. --- source/blender/editors/space_view3d/view3d_draw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 4ca1f296f15..66113ec4941 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1421,7 +1421,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glaDefine2DArea(&ar->winrct); +// glaDefine2DArea(&ar->winrct); + ED_region_pixelspace(ar); glEnable(GL_BLEND); -- cgit v1.2.3 From 3bc5d87e5001453f05f9f14c0326dc87727982fa Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 1 Sep 2009 17:31:33 +0000 Subject: 2.5 Bugfix: new ALT+LMB pan in 2d windows hanged eternally; the modal keymaps didnt support this yet. Is on todo; but fix is easy for now. Also don't know if this is the right way to do it... systems with MMB can also get it as macro (like action mouse, select mouse). --- source/blender/editors/interface/view2d_ops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 1e8cda68e6d..f3610769d17 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -235,6 +235,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) } break; + case LEFTMOUSE: case MIDDLEMOUSE: if (event->val==0) { /* calculate overall delta mouse-movement for redo */ @@ -826,6 +827,7 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event) } break; + case LEFTMOUSE: case MIDDLEMOUSE: if (event->val==0) { /* for redo, store the overall deltas - need to respect zoom-locks here... */ -- cgit v1.2.3 From 3f5115064aea902b3f6886dc688e7a20d771a212 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 1 Sep 2009 23:32:34 +0000 Subject: == SCons == * Add BGE_CXXFLAGS so we can get rid of hard-coded BGE compiler settings. This was only done for windows, but now linuxers and osxers should be able to set BGE-specific optimisation too. See the windows default configs for example. --- config/win32-vc-config.py | 1 + config/win64-vc-config.py | 1 + source/gameengine/BlenderRoutines/SConscript | 8 +------- source/gameengine/Converter/SConscript | 2 +- source/gameengine/Expressions/SConscript | 8 +------- source/gameengine/GameLogic/SConscript | 6 +----- source/gameengine/GamePlayer/common/SConscript | 8 +------- source/gameengine/GamePlayer/ghost/SConscript | 12 +++--------- source/gameengine/Ketsji/KXNetwork/SConscript | 9 +-------- source/gameengine/Ketsji/SConscript | 6 +----- source/gameengine/Physics/Bullet/SConscript | 8 +------- source/gameengine/Physics/common/SConscript | 8 +------- source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript | 8 +------- source/gameengine/Rasterizer/SConscript | 8 +------- source/gameengine/SceneGraph/SConscript | 8 +------- source/gameengine/VideoTexture/SConscript | 7 +------ tools/btools.py | 2 ++ 17 files changed, 20 insertions(+), 90 deletions(-) diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index c50f41b6d4b..5c4342d4f30 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -149,6 +149,7 @@ CXX = 'cl.exe' CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] CXXFLAGS = ['/EHsc'] +BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index ed08e578df8..abc90c84f33 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -163,6 +163,7 @@ CXX = 'cl.exe' CFLAGS = [] CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] CXXFLAGS = ['/EHsc'] +BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index eb5f2a76e10..dc5a93a2e48 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -28,10 +28,4 @@ incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc','win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 45] , cxx_compileflags=cxxflags) +env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 45] , cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 7d3185605d5..9164a9f6d78 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -23,4 +23,4 @@ incs += ' #source/blender/makesrna' incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] -env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,50] ) +env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,50], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 69f87ffbb90..dc9c184fd8a 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -6,10 +6,4 @@ sources = env.Glob('*.cpp') incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader' incs += ' ' + env['BF_PYTHON_INC'] -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,120], cxx_compileflags=cxxflags) +env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,120], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index 837769e5e78..f259a338dc0 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -17,12 +17,8 @@ if env['WITH_BF_SDL']: else: defs.append('DISABLE_SDL') -cxxflags = [] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') if env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core','player'], priority=[330, 100], cxx_compileflags=cxxflags ) +env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core','player'], priority=[330, 100], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 1942cde2531..3ac2576b46d 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -62,10 +62,4 @@ incs += Split(env['BF_PYTHON_INC']) incs += Split(env['BF_PNG_INC']) incs += Split(env['BF_ZLIB_INC']) -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, cxx_compileflags=cxxflags) +env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 83bc61381c0..ce8b07b9393 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -42,14 +42,8 @@ incs = ['.', incs += Split(env['BF_PYTHON_INC']) -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -defs = '' +defs = [] if env['WITH_BF_FFMPEG']: - defs += ' WITH_FFMPEG' + defs.append('WITH_FFMPEG') -env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = Split(defs), libtype='player',priority=5, cxx_compileflags=cxxflags) +env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = defs, libtype='player',priority=5, cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index e6584b55ed2..ce4a29b9492 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -9,11 +9,4 @@ incs += ' #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - - -env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145], cxx_compileflags=cxxflags ) +env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index d3b67cfdb11..ea9d32fa0bf 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -29,12 +29,8 @@ if env['WITH_BF_SDL']: else: defs.append('DISABLE_SDL') -cxxflags = [] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') if env['BF_DEBUG']: defs.append('_DEBUG') # for Python -env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320, 60], cxx_compileflags = cxxflags ) +env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320, 60], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index 44b75402630..0b797c2cb8b 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -21,10 +21,4 @@ incs += ' #intern/guardedalloc' incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_PYTHON_INC'] -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,80], cxx_compileflags=cxxflags ) +env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,80], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index 447b0ec1bbb..8b373ec830c 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/SConscript @@ -5,10 +5,4 @@ sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp P incs = '. ../Dummy #intern/moto/include' -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags = cxxflags ) +env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index e206c90ea25..963c6616b64 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -8,10 +8,4 @@ incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel' incs += ' #intern/guardedalloc #source/blender/blenlib' -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115], cxx_compileflags = cxxflags ) +env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index 255131f9a44..c2af14e8ce5 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -7,10 +7,4 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna' incs += ' ' + env['BF_PYTHON_INC'] -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], cxx_compileflags = cxxflags ) +env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index b3db50117f1..8f433a21e49 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/SConscript @@ -6,10 +6,4 @@ sources = env.Glob('*.cpp') incs = '. #intern/moto/include' -cxxflags = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') - -env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,125], cxx_compileflags = cxxflags ) +env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,125], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index d6b78f6d1a6..583ccf29dbd 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -15,15 +15,10 @@ incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/m incs += ' #intern/guardedalloc #extern/glew/include' defs = [] -cxxflags = [] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - cxxflags.append ('/GR') - cxxflags.append ('/O2') - cxxflags.append ('/EHsc') if env['BF_DEBUG']: defs.append('_DEBUG') - incs += ' ' + env['BF_PYTHON_INC'] #incs += ' ' + env['BF_OPENGL_INC'] @@ -32,4 +27,4 @@ if env['WITH_BF_FFMPEG']: incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC'] defs.append('__STDC_CONSTANT_MACROS') -env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300, 72], cxx_compileflags = cxxflags ) +env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300, 72], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/tools/btools.py b/tools/btools.py index 1ae952adbc7..580a457e3a0 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -77,6 +77,7 @@ def validate_arguments(args, bc): 'BF_OPENGL_LINKFLAGS', 'CFLAGS', 'CCFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'REL_CFLAGS', 'REL_CCFLAGS', 'REL_CXXFLAGS', + 'BGE_CXXFLAGS', 'BF_PROFILE_CFLAGS', 'BF_PROFILE_CCFLAGS', 'BF_PROFILE_CXXFLAGS', 'BF_PROFILE_LINKFLAGS', 'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS', 'C_WARN', 'CC_WARN', 'CXX_WARN', @@ -333,6 +334,7 @@ def read_opts(cfg, args): ('CFLAGS', 'C only flags', ''), ('CCFLAGS', 'Generic C and C++ flags', ''), ('CXXFLAGS', 'C++ only flags', ''), + ('BGE_CXXFLAGS', 'C++ only flags for BGE', ''), ('CPPFLAGS', 'Defines', ''), ('REL_CFLAGS', 'C only release flags', ''), ('REL_CCFLAGS', 'Generic C and C++ release flags', ''), -- cgit v1.2.3 From d89e1eb437e7a78cc91cb71d25bfc30f93f272b3 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 1 Sep 2009 23:43:00 +0000 Subject: * BGE optimisation tweaks. --- config/win32-vc-config.py | 2 +- config/win64-vc-config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 5c4342d4f30..1e993565e98 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -149,7 +149,7 @@ CXX = 'cl.exe' CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] CXXFLAGS = ['/EHsc'] -BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast'] +BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index abc90c84f33..ce2fd8cd405 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -163,7 +163,7 @@ CXX = 'cl.exe' CFLAGS = [] CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] CXXFLAGS = ['/EHsc'] -BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast'] +BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE2'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] -- cgit v1.2.3 From f77fc5c3c9461dce9c694e35db736777214f8b2d Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 2 Sep 2009 00:07:55 +0000 Subject: support for multiple file: linked libraries --- release/io/netrender/client.py | 2 +- release/io/netrender/master.py | 207 +++++++++++++++++++++++++---------------- release/io/netrender/slave.py | 20 +--- release/io/netrender/utils.py | 52 +++++++++-- 4 files changed, 172 insertions(+), 109 deletions(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index bc4d363c996..59cb19c2075 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -69,7 +69,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): x= int(r.resolution_x*r.resolution_percentage*0.01) y= int(r.resolution_y*r.resolution_percentage*0.01) - f = open(netsetting.path + "output.exr", "wb") + f = open(netsettings.path + "output.exr", "wb") buf = response.read(1024) while buf: diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 6f97685935d..6f360a4e7a9 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -46,8 +46,6 @@ class MRenderJob(netrender.model.RenderJob): self.id = job_id self.name = name self.files = files - self.render_files = [MRenderFile(path) for path in files] - self.status = JOB_WAITING self.frames = [] self.chunks = chunks self.priority = priority @@ -55,8 +53,19 @@ class MRenderJob(netrender.model.RenderJob): self.blacklist = blacklist self.last_dispatched = time.time() + # special server properties + self.save_path = "" + self.files_map = {path: MRenderFile(path) for path in files} + self.status = JOB_WAITING + + def save(self): + if self.save_path: + f = open(self.save_path + "job.txt", "w") + f.write(repr(self.serialize())) + f.close() + def testStart(self): - for f in self.render_files: + for f in self.files_map.values(): if not f.test(): return False @@ -184,7 +193,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(http.client.ACCEPTED) elif frame.status == DONE: self.server.stats("", "Sending result back to client") - f = open(self.server.path + job_id + "%04d" % job_frame + ".exr", 'rb') + f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb') self.send_head() @@ -215,7 +224,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(http.client.PROCESSING) else: self.server.stats("", "Sending log back to client") - f = open(self.server.path + job_id + "%04d" % job_frame + ".log", 'rb') + f = open(job.save_path + "%04d" % job_frame + ".log", 'rb') self.send_head() @@ -270,8 +279,6 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): print("slave-id", slave_id) - self.server.getSlave(slave_id) - slave = self.server.updateSlave(slave_id) if slave: # only if slave id is valid @@ -297,22 +304,35 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "file": - job_id = self.headers['job-id'] - print("file:", job_id, "\n") + slave_id = self.headers['slave-id'] - job = self.server.getJobByID(job_id) + slave = self.server.updateSlave(slave_id) - if job: - self.send_head(headers={"job-id": job.id}) - - self.server.stats("", "Sending file to render node") - f = open(self.server.path + job.id + ".blend", 'rb') + if slave: # only if slave id is valid + job_id = self.headers['job-id'] + job_file = self.headers['job-file'] + print("job:", job_id, "\n") + print("file:", job_file, "\n") - shutil.copyfileobj(f, self.wfile) + job = self.server.getJobByID(job_id) - f.close() - else: - # no such job id + if job: + render_file = job.files_map.get(job_file, None) + + if render_file: + self.server.stats("", "Sending file to render node") + f = open(render_file.path, 'rb') + + shutil.copyfileobj(f, self.wfile) + + f.close() + else: + # no such file + self.send_head(http.client.NO_CONTENT) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "slave": @@ -345,14 +365,15 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_id = self.server.nextJobID() - print("chunks", job_info.chunks) + print(job_info.files) job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) - self.server.addJob(job) for frame in job_info.frames: frame = job.addFrame(frame.number) - + + self.server.addJob(job) + headers={"job-id": job_id} if job.testStart(): @@ -411,86 +432,100 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.server.stats("", "Receiving job") length = int(self.headers['content-length']) - job_frame_string = self.headers['job-frame'] - job_name = self.headers.get('job-name', "") - job_chunks = int(self.headers.get('job-chunks', "1")) - blacklist = self.headers.get('slave-blacklist', '').split() - - job_id = self.server.nextJobID() - - buf = self.rfile.read(length) - - job_path = job_id + ".blend" + job_id = self.headers['job-id'] + job_file = self.headers['job-file'] - f = open(self.server.path + job_path, "wb") - f.write(buf) - f.close() - del buf + job = self.server.getJobByID(job_id) - job = MRenderJob(job_id, job_name, job_path, chunks = job_chunks, blacklist = blacklist) - self.server.addJob(job) + if job: - if ":" in job_frame_string: - frame_start, frame_end = [int(x) for x in job_frame_string.split(":")] + render_file = job.files_map.get(job_file, None) - for job_frame in range(frame_start, frame_end + 1): - frame = job.addFrame(job_frame) - else: - job_frame = int(job_frame_string) - frame = job.addFrame(job_frame) - - job.start() - - self.send_head(headers={"job-id": job_id}) + if render_file: + main_file = job.files[0] + + main_path, main_name = os.path.split(main_file) + + if job_file != main_file: + file_path = prefixPath(job.save_path, job_file, main_path) + else: + file_path = job.save_path + main_name + + buf = self.rfile.read(length) + + f = open(file_path, "wb") + f.write(buf) + f.close() + del buf + + render_file.path = file_path # set the new path + + if job.testStart(): + self.send_head(headers=headers) + else: + self.send_head(http.client.ACCEPTED, headers=headers) + else: # invalid file + self.send_head(http.client.NO_CONTENT) + else: # job not found + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "render": print("writing result file") self.server.stats("", "Receiving render result") job_id = self.headers['job-id'] - job_frame = int(self.headers['job-frame']) - job_result = int(self.headers['job-result']) - job_time = float(self.headers['job-time']) - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(self.server.path + job_id + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() - - del buf - job = self.server.getJobByID(job_id) - frame = job[job_frame] - frame.status = job_result - frame.time = job_time - - self.server.updateSlave(self.headers['slave-id']) - self.send_head() + if job: + job_frame = int(self.headers['job-frame']) + job_result = int(self.headers['job-result']) + job_time = float(self.headers['job-time']) + + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() + + del buf + + job = self.server.getJobByID(job_id) + frame = job[job_frame] + frame.status = job_result + frame.time = job_time + + self.server.updateSlave(self.headers['slave-id']) + + self.send_head() + else: # job not found + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "log": print("writing log file") self.server.stats("", "Receiving log file") - length = int(self.headers['content-length']) job_id = self.headers['job-id'] - job_frame = int(self.headers['job-frame']) - print("log length:", length) + job = self.server.getJobByID(job_id) - buf = self.rfile.read(length) - f = open(self.server.path + job_id + "%04d" % job_frame + ".log", 'wb') - f.write(buf) - f.close() + if job: + length = int(self.headers['content-length']) + job_frame = int(self.headers['job-frame']) - del buf - - self.server.updateSlave(self.headers['slave-id']) - - self.send_head() - + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".log", 'wb') + f.write(buf) + f.close() + + del buf + + self.server.updateSlave(self.headers['slave-id']) + + self.send_head() + else: # job not found + self.send_head(http.client.NO_CONTENT) class RenderMasterServer(http.server.HTTPServer): def __init__(self, address, handler_class, path): @@ -500,7 +535,10 @@ class RenderMasterServer(http.server.HTTPServer): self.slaves = [] self.slaves_map = {} self.job_id = 0 - self.path = path + self.path = path + "master_" + str(os.getpid()) + os.sep + + if not os.path.exists(self.path): + os.mkdir(self.path) def nextJobID(self): self.job_id += 1 @@ -539,6 +577,13 @@ class RenderMasterServer(http.server.HTTPServer): def addJob(self, job): self.jobs.append(job) self.jobs_map[job.id] = job + + # create job directory + job.save_path = self.path + "job_" + job.id + os.sep + if not os.path.exists(job.save_path): + os.mkdir(job.save_path) + + job.save() def getJobByID(self, id): return self.jobs_map.get(id, None) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 64801743d70..3d7153a0c54 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -27,24 +27,10 @@ def testCancel(conn, job_id): return False def testFile(conn, JOB_PREFIX, file_path, main_path = None): - if os.path.isabs(file_path): - # if an absolute path, make sure path exists, if it doesn't, use relative local path - job_full_path = file_path - if not os.path.exists(job_full_path): - p, n = os.path.split(job_full_path) - - if main_path and p.startswith(main_path): - directory = JOB_PREFIX + p[len(main_path):] - job_full_path = directory + n - if not os.path.exists(directory): - os.mkdir(directory) - else: - job_full_path = JOB_PREFIX + n - else: - job_full_path = JOB_PREFIX + file_path + job_full_path = prefixPath(JOB_PREFIX, file_path, main_path) if not os.path.exists(job_full_path): - conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id}) + conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id, "job-file":file_path}) response = conn.getresponse() if response.status != http.client.OK: @@ -76,7 +62,7 @@ def render_slave(engine, scene): slave_id = response.getheader("slave-id") - NODE_PREFIX = netsettings.path + "node_" + slave_id + os.sep + NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep if not os.path.exists(NODE_PREFIX): os.mkdir(NODE_PREFIX) diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index d64b6fcda1e..30d96b2f92f 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -53,11 +53,22 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): filename = bpy.data.filename job.files.append(filename) - name = netsettings.job_name - if name == "[default]": - path, name = os.path.split(filename) + job_name = netsettings.job_name + path, name = os.path.split(filename) + if job_name == "[default]": + job_name = name - job.name = name + for lib in bpy.data.libraries: + lib_path = lib.filename + + if lib_path.startswith("//"): + lib_path = path + os.sep + lib_path[2:] + + job.files.append(lib_path) + + print(job.files) + + job.name = job_name for slave in scene.network_render.slaves_blacklist: job.blacklist.append(slave.id) @@ -71,12 +82,13 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): job_id = response.getheader("job-id") - # if not found, send whole file - if response.status == http.client.NOT_FOUND: - f = open(bpy.data.filename, "rb") - conn.request("PUT", "file", f, headers={"job-id": job_id}) - f.close() - response = conn.getresponse() + # if not ACCEPTED (but not processed), send files + if response.status == http.client.ACCEPTED: + for filepath in job.files: + f = open(filepath, "rb") + conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath}) + f.close() + response = conn.getresponse() # server will reply with NOT_FOUD until all files are found @@ -84,3 +96,23 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): def clientRequestResult(conn, scene, job_id): conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) + + +def prefixPath(prefix_directory, file_path, prefix_path): + if os.path.isabs(file_path): + # if an absolute path, make sure path exists, if it doesn't, use relative local path + full_path = file_path + if not os.path.exists(full_path): + p, n = os.path.split(full_path) + + if main_path and p.startswith(main_path): + directory = prefix_directory + p[len(main_path):] + full_path = directory + n + if not os.path.exists(directory): + os.mkdir(directory) + else: + full_path = prefix_directory + n + else: + full_path = prefix_directory + file_path + + return full_path \ No newline at end of file -- cgit v1.2.3 From bd7d26993f32bda6f0c0ca81e1455fb9f55418e3 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 2 Sep 2009 00:42:12 +0000 Subject: 2.5 - Rotation Order Tweaks for Armature Bones * All tools where rotation order matters for armature bones have now been adjusted to use the new code * Transform now uses the new code for bones too. However, there are some jumping issues here that I'm not too sure how to solve yet. Help fixing this is welcome. --- source/blender/blenlib/BLI_arithb.h | 3 +- source/blender/blenlib/intern/arithb.c | 74 ++++++++++++++++++++-- source/blender/editors/animation/keyframing.c | 2 +- source/blender/editors/armature/poseobject.c | 20 +++--- .../blender/editors/space_view3d/view3d_buttons.c | 4 +- source/blender/editors/transform/transform.c | 16 ++--- source/blender/editors/transform/transform.h | 1 + .../editors/transform/transform_conversions.c | 31 +++++---- 8 files changed, 113 insertions(+), 38 deletions(-) diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 4156e3c52ec..5f3622e8aa5 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -193,6 +193,7 @@ typedef enum eEulerRotationOrders { } eEulerRotationOrders; void EulOToQuat(float eul[3], short order, float quat[4]); +void QuatToEulO(float quat[4], float eul[3], short order); void EulOToMat3(float eul[3], short order, float Mat[3][3]); void EulOToMat4(float eul[3], short order, float Mat[4][4]); @@ -200,7 +201,7 @@ void EulOToMat4(float eul[3], short order, float Mat[4][4]); void Mat3ToEulO(float Mat[3][3], float eul[3], short order); void Mat4ToEulO(float Mat[4][4], float eul[3], short order); -void QuatToEulO(float quat[4], float eul[3], short order); +void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order); /** * @section Euler conversion routines (Blender XYZ) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index e0f17864d73..64fb7d78ef1 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2825,7 +2825,8 @@ static RotOrderInfo rotOrders[]= { * NOTE: since we start at 1 for the values, but arrays index from 0, * there is -1 factor involved in this process... */ -#define GET_ROTATIONORDER_INFO(order) (&rotOrders[(order)-1]) +// FIXME: what happens when invalid order given +#define GET_ROTATIONORDER_INFO(order) (((order)>=1) ? &rotOrders[(order)-1] : &rotOrders[0]) /* Construct quaternion from Euler angles (in radians). */ void EulOToQuat(float e[3], short order, float q[4]) @@ -2857,6 +2858,15 @@ void EulOToQuat(float e[3], short order, float q[4]) if (R->parity) q[j] = -q[j]; } +/* Convert quaternion to Euler angles (in radians). */ +void QuatToEulO(float q[4], float e[3], short order) +{ + float M[3][3]; + + QuatToMat3(q, M); + Mat3ToEulO(M, e, order); +} + /* Construct 3x3 matrix from Euler angles (in radians). */ void EulOToMat3(float e[3], short order, float M[3][3]) { @@ -2929,15 +2939,65 @@ void Mat4ToEulO(float M[4][4], float e[3], short order) Mat3ToEulO(m, e, order); } -/* Convert quaternion to Euler angles (in radians). */ -void QuatToEulO(float q[4], float e[3], short order) +/* returns two euler calculation methods, so we can pick the best */ +static void mat3_to_eulo2(float M[3][3], float *e1, float *e2, short order) { - float M[3][3]; + RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); + short i=R->i, j=R->j, k=R->k; + double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]); - QuatToMat3(q, M); - Mat3ToEulO(M, e, order); + if (cy > 16*FLT_EPSILON) { + e1[0] = atan2(M[j][k], M[k][k]); + e1[1] = atan2(-M[i][k], cy); + e1[2] = atan2(M[i][j], M[i][i]); + + e2[0] = atan2(-M[j][k], -M[k][k]); + e2[1] = atan2(-M[i][k], -cy); + e2[2] = atan2(-M[i][j], -M[i][i]); + } + else { + e1[0] = atan2(-M[k][j], M[j][j]); + e1[1] = atan2(-M[i][k], cy); + e1[2] = 0; + + VecCopyf(e2, e1); + } + + if (R->parity) { + e1[0] = -e1[0]; + e1[1] = -e1[1]; + e1[2] = -e1[2]; + + e2[0] = -e2[0]; + e2[1] = -e2[1]; + e2[2] = -e2[2]; + } +} + +/* uses 2 methods to retrieve eulers, and picks the closest */ +// FIXME: this does not work well with the other rotation modes... +void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order) +{ + float eul1[3], eul2[3]; + float d1, d2; + + mat3_to_eulo2(mat, eul1, eul2, order); + + compatible_eul(eul1, oldrot); + compatible_eul(eul2, oldrot); + + d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]); + d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]); + + /* return best, which is just the one with lowest difference */ + if (d1 > d2) + VecCopyf(eul, eul2); + else + VecCopyf(eul, eul1); } + + /* ************ EULER (old XYZ) *************** */ /* XYZ order */ @@ -3102,7 +3162,7 @@ void euler_rot(float *beul, float ang, char axis) } /* exported to transform.c */ -/* XYZ order */ +/* order independent! */ void compatible_eul(float *eul, float *oldrot) { float dx, dy, dz; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index dc73011549c..5f444609baa 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -704,7 +704,7 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_ float eul[3]; /* euler-rotation test before standard rotation, as standard rotation does quats */ - Mat4ToEul(tmat, eul); + Mat4ToEulO(tmat, eul, pchan->rotmode); return eul[array_index]; } else if (strstr(identifier, "rotation")) { diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 5b378878f91..9a72fce2bcf 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -760,6 +760,7 @@ void pose_copy_menu(Scene *scene) break; case 2: /* Local Rotation */ QUATCOPY(pchan->quat, pchanact->quat); + VECCOPY(pchan->eul, pchanact->eul); break; case 3: /* Local Size */ VECCOPY(pchan->size, pchanact->size); @@ -808,11 +809,14 @@ void pose_copy_menu(Scene *scene) break; case 10: /* Visual Rotation */ { - float delta_mat[4][4], quat[4]; + float delta_mat[4][4]; armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat); - Mat4ToQuat(delta_mat, quat); - QUATCOPY(pchan->quat, quat); + + if (pchan->rotmode > 0) + Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode); + else + Mat4ToQuat(delta_mat, pchan->quat); } break; case 11: /* Visual Size */ @@ -990,20 +994,20 @@ static int pose_paste_exec (bContext *C, wmOperator *op) /* check if rotation modes are compatible (i.e. do they need any conversions) */ if (pchan->rotmode == chan->rotmode) { /* copy the type of rotation in use */ - if (pchan->rotmode) { + if (pchan->rotmode > 0) { VECCOPY(pchan->eul, chan->eul); } else { QUATCOPY(pchan->quat, chan->quat); } } - else if (pchan->rotmode) { + else if (pchan->rotmode > 0) { /* quat to euler */ - QuatToEul(chan->quat, pchan->eul); + QuatToEulO(chan->quat, pchan->eul, pchan->rotmode); } else { /* euler to quat */ - EulToQuat(chan->eul, pchan->quat); + EulOToQuat(chan->eul, chan->rotmode, pchan->quat); } /* paste flipped pose? */ @@ -1011,7 +1015,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) pchan->loc[0]*= -1; /* has to be done as eulers... */ - if (pchan->rotmode) { + if (pchan->rotmode > 0) { pchan->eul[1] *= -1; pchan->eul[2] *= -1; } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 2fbe7e5db79..7c305d59866 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -512,7 +512,7 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float uiButSetFunc(but, validate_bonebutton_cb, bone, NULL); uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob); - QuatToEul(pchan->quat, tfp->ob_eul); + QuatToEulO(pchan->quat, tfp->ob_eul, pchan->rotmode); // XXX? tfp->ob_eul[0]*= 180.0/M_PI; tfp->ob_eul[1]*= 180.0/M_PI; tfp->ob_eul[2]*= 180.0/M_PI; @@ -841,7 +841,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) eul[0]= M_PI*tfp->ob_eul[0]/180.0; eul[1]= M_PI*tfp->ob_eul[1]/180.0; eul[2]= M_PI*tfp->ob_eul[2]/180.0; - EulToQuat(eul, pchan->quat); + EulOToQuat(eul, pchan->rotmode, pchan->quat); // xxx? } /* no break, pass on */ case B_ARMATUREPANEL2: diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 4a376f35552..f0de28476f0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2670,21 +2670,21 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } - else { // TODO: need some methods for the new euler types... + else { float eulmat[3][3]; - + Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); - + /* calculate the total rotatation in eulers */ VECCOPY(eul, td->ext->irot); - EulToMat3(eul, eulmat); - + EulOToMat3(eul, td->rotOrder, eulmat); + /* mat = transform, obmat = bone rotation */ Mat3MulMat3(fmat, smat, eulmat); - - Mat3ToCompatibleEul(fmat, eul, td->ext->rot); - + + Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder); + /* and apply (to end result only) */ protectedRotateBits(td->protectflag, eul, td->ext->irot); VECCOPY(td->ext->rot, eul); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index efa60b15293..e5bd405c0cd 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -199,6 +199,7 @@ typedef struct TransData { void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */ short flag; /* Various flags */ short protectflag; /* If set, copy of Object or PoseChannel protection */ + int rotOrder; /* rotation order (for eulers), as defined in BLI_arithb.h */ } TransData; typedef struct MouseInput { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 86d3af31c85..e0dfd90a3d1 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -502,22 +502,29 @@ static short apply_targetless_ik(Object *ob) /* apply and decompose, doesn't work for constraints or non-uniform scale well */ { - float rmat3[3][3], qmat[3][3], imat[3][3], smat[3][3]; + float rmat3[3][3], qrmat[3][3], imat[3][3], smat[3][3]; Mat3CpyMat4(rmat3, rmat); - - /* quaternion */ - Mat3ToQuat(rmat3, parchan->quat); - + + /* rotation */ + if (parchan->rotmode > 0) + Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode); + else + Mat3ToQuat(rmat3, parchan->quat); + /* for size, remove rotation */ /* causes problems with some constraints (so apply only if needed) */ if (data->flag & CONSTRAINT_IK_STRETCH) { - QuatToMat3(parchan->quat, qmat); - Mat3Inv(imat, qmat); + if (parchan->rotmode > 0) + EulOToMat3(parchan->eul, parchan->rotmode, qrmat); + else + QuatToMat3(parchan->quat, qrmat); + + Mat3Inv(imat, qrmat); Mat3MulMat3(smat, rmat3, imat); Mat3ToSize(smat, parchan->size); } - + /* causes problems with some constraints (e.g. childof), so disable this */ /* as it is IK shouldn't affect location directly */ /* VECCOPY(parchan->loc, rmat[3]); */ @@ -568,18 +575,20 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->size= pchan->size; VECCOPY(td->ext->isize, pchan->size); - if (pchan->rotmode) { + if (pchan->rotmode > 0) { td->ext->rot= pchan->eul; td->ext->quat= NULL; - + VECCOPY(td->ext->irot, pchan->eul); + td->rotOrder= pchan->rotmode; } else { td->ext->rot= NULL; td->ext->quat= pchan->quat; - + QUATCOPY(td->ext->iquat, pchan->quat); } + /* proper way to get parent transform + own transform + constraints transform */ Mat3CpyMat4(omat, ob->obmat); -- cgit v1.2.3 From 32b2b1f544661f6dee4a81428b562fe7a3bc3f13 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Sep 2009 01:39:46 +0000 Subject: Game options like enable physics visualisation, nomipmap, displaylists, ignore_deprecation_warnings etc work again. space_set_commmandline_options from space.c as game_set_commmandline_options --- source/blender/editors/space_view3d/view3d_view.c | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index c61b2f0f31d..de8166b372b 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -81,6 +81,10 @@ #include "PIL_time.h" /* smoothview */ +#if GAMEBLENDER == 1 +#include "SYS_System.h" +#endif + #include "view3d_intern.h" // own include /* use this call when executing an operator, @@ -1442,6 +1446,56 @@ static void RestoreState(bContext *C) glPopAttrib(); } +/* was space_set_commmandline_options in 2.4x */ +void game_set_commmandline_options(GameData *gm) +{ + SYS_SystemHandle syshandle; + int test; + + if ( (syshandle = SYS_GetSystem()) ) { + /* User defined settings */ + test= (U.gameflags & USER_DISABLE_SOUND); + /* if user already disabled audio at the command-line, don't re-enable it */ + if (test) + SYS_WriteCommandLineInt(syshandle, "noaudio", test); + + test= (U.gameflags & USER_DISABLE_MIPMAP); + GPU_set_mipmap(!test); + SYS_WriteCommandLineInt(syshandle, "nomipmap", test); + + /* File specific settings: */ + /* Only test the first one. These two are switched + * simultaneously. */ + test= (gm->flag & GAME_SHOW_FRAMERATE); + SYS_WriteCommandLineInt(syshandle, "show_framerate", test); + SYS_WriteCommandLineInt(syshandle, "show_profile", test); + + test = (gm->flag & GAME_SHOW_FRAMERATE); + SYS_WriteCommandLineInt(syshandle, "show_properties", test); + + test= (gm->flag & GAME_SHOW_PHYSICS); + SYS_WriteCommandLineInt(syshandle, "show_physics", test); + + test= (gm->flag & GAME_ENABLE_ALL_FRAMES); + SYS_WriteCommandLineInt(syshandle, "fixedtime", test); + +// a= (G.fileflags & G_FILE_GAME_TO_IPO); +// SYS_WriteCommandLineInt(syshandle, "game2ipo", a); + + test= (gm->flag & GAME_IGNORE_DEPRECATION_WARNINGS); + SYS_WriteCommandLineInt(syshandle, "ignore_deprecation_warnings", test); + + test= (gm->matmode == GAME_MAT_MULTITEX); + SYS_WriteCommandLineInt(syshandle, "blender_material", test); + test= (gm->matmode == GAME_MAT_GLSL); + SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", test); + test= (gm->flag & GAME_DISPLAY_LISTS); + SYS_WriteCommandLineInt(syshandle, "displaylists", test); + + + } +} + /* maybe we need this defined somewhere else */ extern void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int always_use_expand_framing); @@ -1483,6 +1537,8 @@ static int game_engine_exec(bContext *C, wmOperator *unused) view3d_operator_needs_opengl(C); + game_set_commmandline_options(&startscene->gm); + SaveState(C); StartKetsjiShell(C, ar, 1); RestoreState(C); -- cgit v1.2.3 From a0229b21cb5cfc6e263cc2396d5b1e8530d9d38d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Sep 2009 03:14:38 +0000 Subject: text display (debug info) in the game engine working again & other minor changes. --- source/gameengine/BlenderRoutines/KX_BlenderGL.cpp | 34 +++++++--------------- source/gameengine/BlenderRoutines/KX_BlenderGL.h | 4 +-- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 8 ++--- source/gameengine/Expressions/PyObjectPlus.cpp | 9 +++--- 4 files changed, 21 insertions(+), 34 deletions(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 5cf696fe146..dba6d1113c9 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -103,6 +103,8 @@ void BL_SwapBuffers(wmWindow *win) void DisableForText() { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* needed for texture fonts otherwise they render as wireframe */ + if(glIsEnabled(GL_BLEND)) glDisable(GL_BLEND); if(glIsEnabled(GL_ALPHA_TEST)) glDisable(GL_ALPHA_TEST); @@ -135,32 +137,25 @@ void DisableForText() } } -void BL_print_gamedebug_line(char* text, int xco, int yco, int width, int height) +void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height) { /* gl prepping */ DisableForText(); - //glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - - glOrtho(0, width, - 0, height, 0, 1); - + + glOrtho(0, width, 0, height, -100, 100); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); /* the actual drawing */ glColor3ub(255, 255, 255); - BLF_draw_default(xco, height-yco, 0.0f, text); + BLF_draw_default(xco, height-yco, 0.0f, (char *)text); - glMatrixMode(GL_TEXTURE); - glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -168,36 +163,29 @@ void BL_print_gamedebug_line(char* text, int xco, int yco, int width, int height glEnable(GL_DEPTH_TEST); } -void BL_print_gamedebug_line_padded(char* text, int xco, int yco, int width, int height) +void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int width, int height) { /* This is a rather important line :( The gl-mode hasn't been left * behind quite as neatly as we'd have wanted to. I don't know * what cause it, though :/ .*/ DisableForText(); - //glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0, width, - 0, height, 0, 1); + glOrtho(0, width, 0, height, -100, 100); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); /* draw in black first*/ glColor3ub(0, 0, 0); - BLF_draw_default(xco+1, height-yco-1, 0.0f, text); + BLF_draw_default(xco+2, height-yco-2, 0.0f, (char *)text); glColor3ub(255, 255, 255); - BLF_draw_default(xco, height-yco, 0.0f, text); + BLF_draw_default(xco, height-yco, 0.0f, (char *)text); - glMatrixMode(GL_TEXTURE); - glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h index 1e65f29d87c..5c947ff630e 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h @@ -47,8 +47,8 @@ void BL_HideMouse(); void BL_NormalMouse(); void BL_WaitMouse(); -void BL_print_gamedebug_line(char* text, int xco, int yco, int width, int height); -void BL_print_gamedebug_line_padded(char* text, int xco, int yco, int width, int height); +void BL_print_gamedebug_line(const char* text, int xco, int yco, int width, int height); +void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int width, int height); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 8ed36e860b4..ee9dae14b9b 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -284,12 +284,10 @@ void KX_BlenderRenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode, int width, int height) { - STR_String tmpstr(text); - if(mode == RAS_IRenderTools::RAS_TEXT_PADDED) - BL_print_gamedebug_line_padded(tmpstr.Ptr(), xco, yco, width, height); + BL_print_gamedebug_line_padded(text, xco, yco, width, height); else - BL_print_gamedebug_line(tmpstr.Ptr(), xco, yco, width, height); + BL_print_gamedebug_line(text, xco, yco, width, height); } /* Render Text renders text into a (series of) polygon, using a texture font, @@ -390,4 +388,4 @@ void KX_BlenderRenderTools::Update2DFilter(vector& propNames, void* void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas) { m_filtermanager.RenderFilters(canvas); -} \ No newline at end of file +} diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 99c943d4f24..1d1d9e6103b 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -751,16 +751,17 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt STR_String *var = reinterpret_cast(ptr); if (PyUnicode_Check(value)) { - char *val = _PyUnicode_AsString(value); + Py_ssize_t val_len; + char *val = _PyUnicode_AsStringAndSize(value, &val_len); if (attrdef->m_clamp) { - if (strlen(val) < attrdef->m_imin) + if (val_len < attrdef->m_imin) { // can't increase the length of the string PyErr_Format(PyExc_ValueError, "string length too short for attribute \"%s\"", attrdef->m_name); goto FREE_AND_ERROR; } - else if (strlen(val) > attrdef->m_imax) + else if (val_len > attrdef->m_imax) { // trim the string char c = val[attrdef->m_imax]; @@ -769,7 +770,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt val[attrdef->m_imax] = c; break; } - } else if (strlen(val) < attrdef->m_imin || strlen(val) > attrdef->m_imax) + } else if (val_len < attrdef->m_imin || val_len > attrdef->m_imax) { PyErr_Format(PyExc_ValueError, "string length out of range for attribute \"%s\"", attrdef->m_name); goto FREE_AND_ERROR; -- cgit v1.2.3 From 0763627e394bf4b634584a11f1b15dca33d94258 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 2 Sep 2009 04:55:33 +0000 Subject: * quick fix from Moguri to get things compiling again. --- source/blender/editors/space_view3d/SConscript | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript index 4eb9f3f5ecb..057c98a1d49 100644 --- a/source/blender/editors/space_view3d/SConscript +++ b/source/blender/editors/space_view3d/SConscript @@ -9,6 +9,7 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include #/intern/guardedalloc' incs += ' ../../gpu ../../makesrna ../../blenfont' incs += ' #/intern/smoke/extern' +incs += ' #source/kernel/gen_system' if env['WITH_BF_GAMEENGINE']: defs.append('GAMEBLENDER=1') -- cgit v1.2.3 From 01b4caa701c21b88b4447d7d4fd5570b05fa5979 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 2 Sep 2009 10:45:11 +0000 Subject: 2.5 - Rotation order is now taken into account for constraints * Added a 'rotOrder' parameter for constraint evaluation objects and constraint targets, which describes the rotation mode used for the matrices there. Todos: * Constraint targets default to using XYZ only for now. This will need be be addressed eventually. * Copy Rotation constraint currently cannot use the new rotation order code for the target matrix. What's surprising is that even though it's just using XYZ as the old code did, it doesn't work, and yet everything else works nicely. Silly constraint! (it is almost impossible to improve this constraint further without breaking a rig out there) --- source/blender/blenkernel/BKE_constraint.h | 1 + source/blender/blenkernel/intern/constraint.c | 43 +++++++++++++-------- source/blender/blenlib/BLI_arithb.h | 7 +++- source/blender/blenlib/intern/arithb.c | 52 ++++++++++++++++++++++++-- source/blender/makesdna/DNA_constraint_types.h | 2 +- 5 files changed, 83 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 6e69906b71d..a0061173438 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -49,6 +49,7 @@ typedef struct bConstraintOb { float startmat[4][4]; /* original matrix (before constraint solving) */ short type; /* type of owner */ + short rotOrder; /* rotation order for constraint owner (as defined in eEulerRotationOrders in BLI_arithb.h) */ } bConstraintOb; /* ---------------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 88e73a00ba7..e6e65ebd614 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -121,6 +121,7 @@ bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, if (ob) { cob->ob = ob; cob->type = datatype; + cob->rotOrder = EULER_ORDER_DEFAULT; // TODO: when objects have rotation order too, use that Mat4CpyMat4(cob->matrix, ob->obmat); } else @@ -137,6 +138,15 @@ bConstraintOb *constraints_make_evalob (Scene *scene, Object *ob, void *subdata, cob->pchan = (bPoseChannel *)subdata; cob->type = datatype; + if (cob->pchan->rotmode > 0) { + /* should be some type of Euler order */ + cob->rotOrder= cob->pchan->rotmode; + } + else { + /* Quats, so eulers should just use default order */ + cob->rotOrder= EULER_ORDER_DEFAULT; + } + /* matrix in world-space */ Mat4MulMat4(cob->matrix, cob->pchan->pose_mat, ob->obmat); } @@ -664,6 +674,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain * (Hopefully all compilers will be happy with the lines with just a space on them. Those are * really just to help this code easier to read) */ +// TODO: cope with getting rotation order... #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \ { \ ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \ @@ -687,6 +698,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain * (Hopefully all compilers will be happy with the lines with just a space on them. Those are * really just to help this code easier to read) */ +// TODO: cope with getting rotation order... #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \ { \ ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \ @@ -795,11 +807,11 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta /* extract components of both matrices */ VECCOPY(loc, ct->matrix[3]); - Mat4ToEul(ct->matrix, eul); + Mat4ToEulO(ct->matrix, eul, ct->rotOrder); Mat4ToSize(ct->matrix, size); VECCOPY(loco, invmat[3]); - Mat4ToEul(invmat, eulo); + Mat4ToEulO(invmat, eulo, cob->rotOrder); Mat4ToSize(invmat, sizo); /* disable channels not enabled */ @@ -814,8 +826,8 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f; /* make new target mat and offset mat */ - LocEulSizeToMat4(ct->matrix, loc, eul, size); - LocEulSizeToMat4(invmat, loco, eulo, sizo); + LocEulOSizeToMat4(ct->matrix, loc, eul, size, ct->rotOrder); + LocEulOSizeToMat4(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 @@ -1304,7 +1316,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t VECCOPY(loc, cob->matrix[3]); Mat4ToSize(cob->matrix, size); - Mat4ToEul(cob->matrix, eul); + Mat4ToEulO(cob->matrix, eul, cob->rotOrder); /* eulers: radians to degrees! */ eul[0] = (float)(eul[0] / M_PI * 180); @@ -1339,7 +1351,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t eul[1] = (float)(eul[1] / 180 * M_PI); eul[2] = (float)(eul[2] / 180 * M_PI); - LocEulSizeToMat4(cob->matrix, loc, eul, size); + LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder); } static bConstraintTypeInfo CTI_ROTLIMIT = { @@ -1546,14 +1558,15 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta VECCOPY(loc, cob->matrix[3]); Mat4ToSize(cob->matrix, size); - Mat4ToEul(ct->matrix, eul); - Mat4ToEul(cob->matrix, obeul); + //Mat4ToEulO(ct->matrix, eul, ct->rotOrder); + Mat4ToEul(ct->matrix, eul); // the version we should be using causes errors... + Mat4ToEulO(cob->matrix, obeul, cob->rotOrder); if ((data->flag & ROTLIKE_X)==0) eul[0] = obeul[0]; else { if (data->flag & ROTLIKE_OFFSET) - euler_rot(eul, obeul[0], 'x'); + eulerO_rot(eul, obeul[0], 'x', cob->rotOrder); if (data->flag & ROTLIKE_X_INVERT) eul[0] *= -1; @@ -1563,7 +1576,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta eul[1] = obeul[1]; else { if (data->flag & ROTLIKE_OFFSET) - euler_rot(eul, obeul[1], 'y'); + eulerO_rot(eul, obeul[1], 'y', cob->rotOrder); if (data->flag & ROTLIKE_Y_INVERT) eul[1] *= -1; @@ -1573,14 +1586,14 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta eul[2] = obeul[2]; else { if (data->flag & ROTLIKE_OFFSET) - euler_rot(eul, obeul[2], 'z'); + eulerO_rot(eul, obeul[2], 'z', cob->rotOrder); if (data->flag & ROTLIKE_Z_INVERT) eul[2] *= -1; } compatible_eul(eul, obeul); - LocEulSizeToMat4(cob->matrix, loc, eul, size); + LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder); } } @@ -3036,7 +3049,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * Mat4ToSize(ct->matrix, dvec); break; case 1: /* rotation (convert to degrees first) */ - Mat4ToEul(ct->matrix, dvec); + Mat4ToEulO(ct->matrix, dvec, cob->rotOrder); for (i=0; i<3; i++) dvec[i] = (float)(dvec[i] / M_PI * 180); break; @@ -3047,7 +3060,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * /* extract components of owner's matrix */ VECCOPY(loc, cob->matrix[3]); - Mat4ToEul(cob->matrix, eul); + Mat4ToEulO(cob->matrix, eul, cob->rotOrder); Mat4ToSize(cob->matrix, size); /* determine where in range current transforms lie */ @@ -3102,7 +3115,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * } /* apply to matrix */ - LocEulSizeToMat4(cob->matrix, loc, eul, size); + LocEulOSizeToMat4(cob->matrix, loc, eul, size, cob->rotOrder); } } diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 5f3622e8aa5..2ab60c6a8d0 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -202,6 +202,8 @@ void Mat3ToEulO(float Mat[3][3], float eul[3], short order); void Mat4ToEulO(float Mat[4][4], float eul[3], short order); void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order); + +void eulerO_rot(float beul[3], float ang, char axis, short order); /** * @section Euler conversion routines (Blender XYZ) @@ -484,8 +486,9 @@ void Mat4ToSize(float mat[][4], float *size); void triatoquat(float *v1, float *v2, float *v3, float *quat); -void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]); -void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3]); +void LocEulSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3]); +void LocEulOSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3], short rotOrder); +void LocQuatSizeToMat4(float mat[4][4], float loc[3], float quat[4], float size[3]); void tubemap(float x, float y, float z, float *u, float *v); void spheremap(float x, float y, float z, float *u, float *v); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 64fb7d78ef1..9d67ac50108 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2825,7 +2825,6 @@ static RotOrderInfo rotOrders[]= { * NOTE: since we start at 1 for the values, but arrays index from 0, * there is -1 factor involved in this process... */ -// FIXME: what happens when invalid order given #define GET_ROTATIONORDER_INFO(order) (((order)>=1) ? &rotOrders[(order)-1] : &rotOrders[0]) /* Construct quaternion from Euler angles (in radians). */ @@ -2936,6 +2935,7 @@ void Mat4ToEulO(float M[4][4], float e[3], short order) /* for now, we'll just do this the slow way (i.e. copying matrices) */ Mat3CpyMat4(m, M); + Mat3Ortho(m); Mat3ToEulO(m, e, order); } @@ -2996,7 +2996,27 @@ void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short VecCopyf(eul, eul1); } - +/* rotate the given euler by the given angle on the specified axis */ +// NOTE: is this safe to do with different axis orders? +void eulerO_rot(float beul[3], float ang, char axis, short order) +{ + float eul[3], mat1[3][3], mat2[3][3], totmat[3][3]; + + eul[0]= eul[1]= eul[2]= 0.0f; + if (axis=='x') + eul[0]= ang; + else if (axis=='y') + eul[1]= ang; + else + eul[2]= ang; + + EulOToMat3(eul, order, mat1); + EulOToMat3(beul, order, mat2); + + Mat3MulMat3(totmat, mat2, mat1); + + Mat3ToEulO(totmat, beul, order); +} /* ************ EULER (old XYZ) *************** */ @@ -4947,7 +4967,7 @@ float PdistVL3Dfl(float *v1, float *v2, float *v3) /* make a 4x4 matrix out of 3 transform components */ /* matrices are made in the order: scale * rot * loc */ // TODO: need to have a version that allows for rotation order... -void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]) +void LocEulSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3]) { float rmat[3][3], smat[3][3], tmat[3][3]; @@ -4970,7 +4990,31 @@ void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]) /* make a 4x4 matrix out of 3 transform components */ /* matrices are made in the order: scale * rot * loc */ -void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3]) +void LocEulOSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3], short rotOrder) +{ + float rmat[3][3], smat[3][3], tmat[3][3]; + + /* initialise new matrix */ + Mat4One(mat); + + /* make rotation + scaling part */ + EulOToMat3(eul, rotOrder, rmat); + SizeToMat3(size, smat); + Mat3MulMat3(tmat, rmat, smat); + + /* copy rot/scale part to output matrix*/ + Mat4CpyMat3(mat, tmat); + + /* copy location to matrix */ + mat[3][0] = loc[0]; + mat[3][1] = loc[1]; + mat[3][2] = loc[2]; +} + + +/* make a 4x4 matrix out of 3 transform components */ +/* matrices are made in the order: scale * rot * loc */ +void LocQuatSizeToMat4(float mat[4][4], float loc[3], float quat[4], float size[3]) { float rmat[3][3], smat[3][3], tmat[3][3]; diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 79f032d0d21..6fab633b192 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -85,7 +85,7 @@ typedef struct bConstraintTarget { short space; /* space that target should be evaluated in (overrides bConstraint->tarspace) */ short flag; /* runtime settings (for editor, etc.) */ short type; /* type of target (B_CONSTRAINT_OB_TYPE) */ - short pad; + short rotOrder; /* rotation order for target (as defined in BLI_arithb.h) */ } bConstraintTarget; /* bConstraintTarget -> flag */ -- cgit v1.2.3 From 0415e3be054bd6ad742da786e01ec3edc81f9e78 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 2 Sep 2009 12:16:00 +0000 Subject: 2.5 - UI Bugfixes * Modifiers for Lattices now get shown again * Auto IK and X-Axis Mirror options are now visible again in Armatures UI. Their placement isn't ideal yet, and they also need some proper poll-based visibility adjustments * F-Modifiers now correctly update the keyframes view after their settings are modified --- release/ui/buttons_data_armature.py | 5 +-- .../editors/space_buttons/buttons_context.c | 2 +- source/blender/makesrna/intern/rna_fcurve.c | 38 +++++++++++++++++++++- source/blender/makesrna/intern/rna_nla.c | 25 ++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index ed350caa3bd..ff0cc531c67 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -45,6 +45,9 @@ class DATA_PT_skeleton(DataButtonsPanel): col.template_layers(arm, "layer") col.itemL(text="Protected Layers:") col.template_layers(arm, "layer_protection") + col.itemL(text="Edit Options:") + col.itemR(arm, "x_axis_mirror") + col.itemR(arm, "auto_ik") col = split.column() col.itemR(arm, "rest_position") @@ -53,8 +56,6 @@ class DATA_PT_skeleton(DataButtonsPanel): col.itemR(arm, "deform_envelope", text="Envelopes") col.itemR(arm, "deform_quaternion", text="Quaternion") col.itemR(arm, "deform_bbone_rest", text="B-Bones Rest") - #col.itemR(arm, "x_axis_mirror") - #col.itemR(arm, "auto_ik") class DATA_PT_display(DataButtonsPanel): __label__ = "Display" diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 8306487013a..635abd429f6 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -200,7 +200,7 @@ static int buttons_context_path_modifier(ButsContextPath *path) if(buttons_context_path_object(path)) { ob= path->ptr[path->len-1].data; - if(ob && ELEM4(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF)) + if(ob && ELEM5(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE)) return 1; } diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index fa6eea5f8a9..bafe83f1812 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -34,6 +34,8 @@ #include "MEM_guardedalloc.h" +#include "WM_types.h" + EnumPropertyItem fmodifier_type_items[] = { {FMODIFIER_TYPE_NULL, "NULL", 0, "Invalid", ""}, {FMODIFIER_TYPE_GENERATOR, "GENERATOR", 0, "Generator", ""}, @@ -168,17 +170,20 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna) prop= RNA_def_property(srna, "additive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_GENERATOR_ADDITIVE); RNA_def_property_ui_text(prop, "Additive", "Values generated by this modifier are applied on top of the existing values instead of overwriting them."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); // XXX this has a special validation func prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Mode", "Type of generator to use."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* order of the polynomial */ // XXX this has a special validation func prop= RNA_def_property(srna, "poly_order", PROP_INT, PROP_NONE); RNA_def_property_ui_text(prop, "Polynomial Order", "The highest power of 'x' for this polynomial. (number of coefficients - 1)"); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* coefficients array */ // FIXME: this is quite difficult to try to wrap @@ -210,25 +215,31 @@ static void rna_def_fmodifier_function_generator(BlenderRNA *brna) /* coefficients */ prop= RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Amplitude", "Scale factor determining the maximum/minimum values."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "phase_multiplier", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Phase Multiplier", "Scale factor determining the 'speed' of the function."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "phase_offset", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Phase Offset", "Constant factor to offset time by for function."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "value_offset", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Value Offset", "Constant factor to offset values by."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* flags */ prop= RNA_def_property(srna, "additive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_GENERATOR_ADDITIVE); RNA_def_property_ui_text(prop, "Additive", "Values generated by this modifier are applied on top of the existing values instead of overwriting them."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "function_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, prop_type_items); RNA_def_property_ui_text(prop, "Type", "Type of built-in function to use."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } /* --------- */ @@ -249,15 +260,18 @@ static void rna_def_fmodifier_envelope_ctrl(BlenderRNA *brna) prop= RNA_def_property(srna, "minimum", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); RNA_def_property_ui_text(prop, "Minimum Value", "Lower bound of envelope at this control-point."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "maximum", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); RNA_def_property_ui_text(prop, "Maximum Value", "Upper bound of envelope at this control-point."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* Frame */ prop= RNA_def_property(srna, "frame", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "time"); RNA_def_property_ui_text(prop, "Frame", "Frame this control-point occurs on."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); // TODO: // - selection flags (not implemented in UI yet though) @@ -282,14 +296,17 @@ static void rna_def_fmodifier_envelope(BlenderRNA *brna) prop= RNA_def_property(srna, "reference_value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "midval"); RNA_def_property_ui_text(prop, "Reference Value", "Value that envelope's influence is centered around / based on."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "default_minimum", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); RNA_def_property_ui_text(prop, "Default Minimum", "Lower distance from Reference Value for 1:1 default influence."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "default_maximum", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); RNA_def_property_ui_text(prop, "Default Maximum", "Upper distance from Reference Value for 1:1 default influence."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } /* --------- */ @@ -314,18 +331,21 @@ static void rna_def_fmodifier_cycles(BlenderRNA *brna) prop= RNA_def_property(srna, "before_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_type_items); RNA_def_property_ui_text(prop, "Before Mode", "Cycling mode to use before first keyframe."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "before_cycles", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Before Cycles", "Maximum number of cycles to allow before first keyframe. (0 = infinite)"); - + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* after */ prop= RNA_def_property(srna, "after_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_type_items); RNA_def_property_ui_text(prop, "After Mode", "Cycling mode to use after last keyframe."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "after_cycles", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "After Cycles", "Maximum number of cycles to allow after last keyframe. (0 = infinite)"); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } /* --------- */ @@ -354,34 +374,42 @@ static void rna_def_fmodifier_limits(BlenderRNA *brna) prop= RNA_def_property(srna, "use_minimum_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_XMIN); RNA_def_property_ui_text(prop, "Minimum X", "Use the minimum X value."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "use_minimum_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_YMIN); RNA_def_property_ui_text(prop, "Minimum Y", "Use the minimum Y value."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "use_maximum_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_XMAX); RNA_def_property_ui_text(prop, "Maximum X", "Use the maximum X value."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "use_maximum_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_YMAX); RNA_def_property_ui_text(prop, "Maximum Y", "Use the maximum Y value."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "minimum_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.xmin"); RNA_def_property_ui_text(prop, "Minimum X", "Lowest X value to allow."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "minimum_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.ymin"); RNA_def_property_ui_text(prop, "Minimum Y", "Lowest Y value to allow."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "maximum_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.xmax"); RNA_def_property_ui_text(prop, "Maximum X", "Highest X value to allow."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "maximum_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rect.ymax"); RNA_def_property_ui_text(prop, "Maximum Y", "Highest Y value to allow."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } /* --------- */ @@ -405,22 +433,27 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna) prop= RNA_def_property(srna, "modification", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_modification_items); RNA_def_property_ui_text(prop, "Modification", "Method of modifying the existing F-Curve."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Size", "Scaling (in time) of the noise"); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "strength"); RNA_def_property_ui_text(prop, "Strength", "Amplitude of the noise - the amount that it modifies the underlying curve"); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "phase", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "phase"); RNA_def_property_ui_text(prop, "Phase", "A random seed for the noise effect"); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); prop= RNA_def_property(srna, "depth", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "depth"); RNA_def_property_ui_text(prop, "Depth", "Amount of fine level detail present in the noise"); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } @@ -459,17 +492,20 @@ void rna_def_fmodifier(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_MUTED); RNA_def_property_ui_text(prop, "Muted", "F-Curve Modifier will not be evaluated."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL); // XXX this is really an internal flag, but it may be useful for some tools to be able to access this... prop= RNA_def_property(srna, "disabled", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_DISABLED); RNA_def_property_ui_text(prop, "Disabled", "F-Curve Modifier has invalid settings and will not be evaluated."); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL); // TODO: setting this to true must ensure that all others in stack are turned off too... prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_ACTIVE); RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited "); + RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL); } /* *********************** */ diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 98c72b7ee74..98fdf4a6878 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -61,6 +61,30 @@ void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value) } } +static char *rna_NlaStrip_path(PointerRNA *ptr) +{ + NlaStrip *strip= (NlaStrip *)ptr->data; + AnimData *adt= BKE_animdata_from_id(ptr->id.data); + + /* if we're attached to AnimData, try to resolve path back to AnimData */ + if (adt) { + NlaTrack *nlt; + NlaStrip *nls; + + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + for (nls = nlt->strips.first; nls; nls = nls->next) { + if (nls == strip) { + // XXX but if we animate like this, the control will never work... + return BLI_sprintfN("animation_data.nla_tracks[\"%s\"].strips[\"%s\"]", nlt->name, strip->name); + } + } + } + } + + /* no path */ + return ""; +} + static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value) { @@ -271,6 +295,7 @@ void rna_def_nlastrip(BlenderRNA *brna) /* struct definition */ srna= RNA_def_struct(brna, "NlaStrip", NULL); RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action."); + RNA_def_struct_path_func(srna, "rna_NlaStrip_path"); RNA_def_struct_ui_icon(srna, ICON_NLA); // XXX /* name property */ -- cgit v1.2.3 From 21af438ef8c7cbc19ec0050195c3898ef4d95c29 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Wed, 2 Sep 2009 17:13:47 +0000 Subject: Blender 2.5 * recent files now just write content of G.recent_files, was adding untitled.blend! * removed unused and now superfluous code reading the .Bfs file (is done in fsmenu now) --- source/blender/windowmanager/intern/wm_files.c | 54 +--------------------- source/blender/windowmanager/intern/wm_operators.c | 18 ++------ 2 files changed, 5 insertions(+), 67 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index b98717c8629..3921da4f062 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -388,7 +388,7 @@ void WM_read_autosavefile(bContext *C) void read_Blog(void) { - char name[FILE_MAX], filename[FILE_MAX]; + char name[FILE_MAX]; LinkNode *l, *lines; struct RecentFile *recent; char *line; @@ -420,58 +420,6 @@ void read_Blog(void) BLI_free_file_lines(lines); -#ifdef WIN32 - /* Add the drive names to the listing */ - { - __int64 tmp; - char folder[MAX_PATH]; - char tmps[4]; - int i; - - tmp= GetLogicalDrives(); - - for (i=2; i < 26; i++) { - if ((tmp>>i) & 1) { - tmps[0]='a'+i; - tmps[1]=':'; - tmps[2]='\\'; - tmps[3]=0; - -// XX fsmenu_insert_entry(tmps, 0, 0); - } - } - - /* Adding Desktop and My Documents */ -// XXX fsmenu_append_separator(); - - SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0); -// XXX fsmenu_insert_entry(folder, 0, 0); - SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0); -// XXX fsmenu_insert_entry(folder, 0, 0); - -// XXX fsmenu_append_separator(); - } -#endif - - BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs"); - lines= BLI_read_file_as_lines(name); - - for (l= lines; l; l= l->next) { - char *line= l->link; - - if (!BLI_streq(line, "")) { -// XXX fsmenu_insert_entry(line, 0, 1); - } - } - -// XXX fsmenu_append_separator(); - - /* add last saved file */ - BLI_split_dirfile(G.sce, name, filename); /* G.sce shouldn't be relative */ - -// XXX fsmenu_insert_entry(name, 0, 0); - - BLI_free_file_lines(lines); } static void writeBlog(void) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5a385418e5d..b51fcfddc47 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -814,22 +814,12 @@ static EnumPropertyItem *open_recentfile_itemf(bContext *C, PointerRNA *ptr, int struct RecentFile *recent; int totitem= 0, i, ofs= 0; - if(G.sce[0]) { - tmp.value= 1; - tmp.identifier= G.sce; - tmp.name= G.sce; - RNA_enum_item_add(&item, &totitem, &tmp); - ofs = 1; - } - /* dynamically construct enum */ for(recent = G.recent_files.first, i=0; (inext, i++) { - if(strcmp(recent->filename, G.sce)) { - tmp.value= i+ofs+1; - tmp.identifier= recent->filename; - tmp.name= recent->filename; - RNA_enum_item_add(&item, &totitem, &tmp); - } + tmp.value= i+ofs+1; + tmp.identifier= recent->filename; + tmp.name= recent->filename; + RNA_enum_item_add(&item, &totitem, &tmp); } RNA_enum_item_end(&item, &totitem); -- cgit v1.2.3 From e80b37cd751260232678ebd550aa5a0f2226b693 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Sep 2009 20:46:28 +0000 Subject: * KX_PythonSeq - comparisons work again. eg. act1.sensors == act2.sensors, had to copy Py_CmpToRich inline grr!, mailed python-dev about this. * Shift-Click on states in the logic UI works again. * New Logic Space has all the view options pressed. --- source/blender/editors/space_logic/logic_window.c | 27 ++-------------- source/blender/editors/space_logic/space_logic.c | 7 +++++ source/gameengine/Ketsji/KX_PythonInit.cpp | 38 +++++++++++++++++++++++ source/gameengine/Ketsji/KX_PythonSeq.cpp | 20 +++++++++--- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 118bcaa0cf4..47ba197daa0 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -83,9 +83,6 @@ static int pupmenu() {return 1;} #define B_REDR 1 #define B_IDNAME 2 -#define B_ADD_PROP 2701 -#define B_CHANGE_PROP 2702 - #define B_ADD_SENS 2703 #define B_CHANGE_SENS 2704 #define B_DEL_SENS 2705 @@ -364,7 +361,6 @@ static void sca_move_actuator(bContext *C, void *datav, void *data2_unused) void do_logic_buts(bContext *C, void *arg, int event) { - bProperty *prop; bSensor *sens; bController *cont; bActuator *act; @@ -386,25 +382,7 @@ void do_logic_buts(bContext *C, void *arg, int event) case B_SETMAINACTOR: ob->gameflag &= ~(OB_SECTOR|OB_PROP); break; - - - case B_ADD_PROP: - prop= new_property(PROP_FLOAT); - make_unique_prop_names(C, prop->name); - BLI_addtail(&ob->prop, prop); - ED_undo_push(C, "Add property"); - break; -#if 0 // XXX Now done in python - case B_CHANGE_PROP: - prop= ob->prop.first; - while(prop) { - if(prop->type!=prop->otype) { - init_property(prop); - } - prop= prop->next; - } - break; -#endif + case B_ADD_SENS: for(ob=G.main->object.first; ob; ob=ob->id.next) { if(ob->scaflag & OB_ADDSENS) { @@ -1666,7 +1644,8 @@ char *get_state_name(Object *ob, short bit) static void check_state_mask(bContext *C, void *arg1_but, void *arg2_mask) { - int shift= 0; // XXX + wmWindow *win= CTX_wm_window(C); + int shift= win->eventstate->shift; unsigned int *cont_mask = arg2_mask; uiBut *but = arg1_but; diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c index 703b408aae6..3c46522bba2 100644 --- a/source/blender/editors/space_logic/space_logic.c +++ b/source/blender/editors/space_logic/space_logic.c @@ -102,6 +102,13 @@ static SpaceLink *logic_new(const bContext *C) slogic= MEM_callocN(sizeof(SpaceLogic), "initlogic"); slogic->spacetype= SPACE_LOGIC; + /* default options */ + slogic->scaflag = (BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_SENS_LINK) | + (BUTS_CONT_SEL|BUTS_CONT_ACT|BUTS_CONT_LINK) | + (BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_ACT_LINK) | + (BUTS_SENS_STATE|BUTS_ACT_STATE); + + /* header */ ar= MEM_callocN(sizeof(ARegion), "header for logic"); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 67ab67814b2..667b4cd5d89 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -2018,4 +2018,42 @@ void resetGamePythonPath() } +/* Copied from pythons 3's Object.c + * also in blenders bpy_uitl.c, mailed the python-dev + * list about enabling something like this again for py3 */ +PyObject * +Py_CmpToRich(int op, int cmp) +{ + PyObject *res; + int ok; + + if (PyErr_Occurred()) + return NULL; + switch (op) { + case Py_LT: + ok = cmp < 0; + break; + case Py_LE: + ok = cmp <= 0; + break; + case Py_EQ: + ok = cmp == 0; + break; + case Py_NE: + ok = cmp != 0; + break; + case Py_GT: + ok = cmp > 0; + break; + case Py_GE: + ok = cmp >= 0; + break; + default: + PyErr_BadArgument(); + return NULL; + } + res = ok ? Py_True : Py_False; + Py_INCREF(res); + return res; +} diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 1098dc03b62..165a85e2c14 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -345,6 +345,19 @@ static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) /* TODO - return ( a->type == b->type && a->base == b->base) ? 0 : -1; } +extern PyObject *Py_CmpToRich(int op, int cmp); + +static PyObject *KX_PythonSeq_richcmp(PyObject *a, PyObject *b, int op) +{ + int cmp_result= -1; /* assume false */ + + if(BPy_KX_PythonSeq_Check(a) && BPy_KX_PythonSeq_Check(b)) { + cmp_result= KX_PythonSeq_compare((KX_PythonSeq *)a, (KX_PythonSeq *)b); + } + + return Py_CmpToRich(op, cmp_result); +} + /* * repr function * convert to a list and get its string value @@ -374,8 +387,7 @@ PyTypeObject KX_PythonSeq_Type = { NULL, /* printfunc tp_print; */ NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ - /* TODO, richcmp */ - NULL, /* ( cmpfunc ) KX_PythonSeq_compare, // cmpfunc tp_compare; */ + NULL, /* cmpfunc tp_compare; */ ( reprfunc ) KX_PythonSeq_repr, /* reprfunc tp_repr; */ /* Method suites for standard classes */ @@ -401,14 +413,14 @@ PyTypeObject KX_PythonSeq_Type = { NULL, /* char *tp_doc; Documentation string */ /*** Assigned meaning in release 2.0 ***/ /* call function for all accessible objects */ - NULL, /* traverseproc tp_traverse; */ + NULL, /* traverseproc tp_traverse; */ /* delete references to contained objects */ NULL, /* inquiry tp_clear; */ /*** Assigned meaning in release 2.1 ***/ /*** rich comparisons ***/ - NULL, /* richcmpfunc tp_richcompare; */ + (richcmpfunc)KX_PythonSeq_richcmp, /* richcmpfunc tp_richcompare; */ /*** weak reference enabler ***/ 0, /* long tp_weaklistoffset; */ -- cgit v1.2.3 From 375f36dfcf21f046b2cde0a24a0846999e87d57a Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 2 Sep 2009 20:54:33 +0000 Subject: * actually commit the sndfile dll copying (and not just claiming I did) --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConstruct b/SConstruct index f2eb7146930..5a64cd7c117 100644 --- a/SConstruct +++ b/SConstruct @@ -575,6 +575,8 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc'): if env['WITH_BF_OPENAL']: dllsources.append('${LCGDIR}/openal/lib/OpenAL32.dll') dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll') + if env['WITH_BF_SNDFILE']: + dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll') if env['WITH_BF_FFMPEG']: dllsources += ['${LCGDIR}/ffmpeg/lib/avcodec-52.dll', '${LCGDIR}/ffmpeg/lib/avformat-52.dll', -- cgit v1.2.3 From 9004dc665cd303dc6bc84d1ea92716dc0c0020d3 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 2 Sep 2009 20:57:18 +0000 Subject: Fix thread hanging problem (mostly seen with material preview, but that sneaky f*er could strike any time). Story time: Once upon a time, in the green valley of fileselect, BLI_end_threads would get called on an empty threadbase, depending on the result of a previous call to readdir(). The function would then gladly decrement thread_level to -1 which would cause all kinds of fun havoc. THE END. Made sure thread_level is only incremented and decremented when needed. The caller should never have to make sure of that, especially since it already lets you call with a null threadbase. Please report any further hang (and how to reproduce, if possible). --- source/blender/blenlib/intern/threads.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 2812f17d58f..ed3e07b7f7e 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -142,10 +142,10 @@ void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot) tslot->do_thread= do_thread; tslot->avail= 1; } + + MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); + thread_levels++; } - - MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); - thread_levels++; } /* amount of available threads */ @@ -235,18 +235,21 @@ void BLI_end_threads(ListBase *threadbase) { ThreadSlot *tslot; - if (threadbase) { + /* only needed if there's actually some stuff to end + * this way we don't end up decrementing thread_levels on an empty threadbase + * */ + if (threadbase && threadbase->first != NULL) { for(tslot= threadbase->first; tslot; tslot= tslot->next) { if(tslot->avail==0) { pthread_join(tslot->pthread, NULL); } } BLI_freelistN(threadbase); + + thread_levels--; + if(thread_levels==0) + MEM_set_lock_callback(NULL, NULL); } - - thread_levels--; - if(thread_levels==0) - MEM_set_lock_callback(NULL, NULL); } void BLI_lock_thread(int type) -- cgit v1.2.3 From ac3f0695a2cf3d5706d8f49b1276579889997990 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Sep 2009 01:52:10 +0000 Subject: remove Py_CmpToRich (copy of py3.0 function), instead only support == and != for PyRNA and KX_PySequence types. mesh1 > mesh2 # will raise an error. --- source/blender/python/intern/bpy_rna.c | 61 ++++++++++++++++++++++++------ source/blender/python/intern/bpy_util.c | 38 ------------------- source/blender/python/intern/bpy_util.h | 2 - source/gameengine/Ketsji/KX_PythonInit.cpp | 41 -------------------- source/gameengine/Ketsji/KX_PythonSeq.cpp | 32 ++++++++++++---- 5 files changed, 75 insertions(+), 99 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 3902a9fd9b5..8ba3b5f8732 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -144,25 +144,64 @@ static int pyrna_prop_compare( BPy_PropertyRNA * a, BPy_PropertyRNA * b ) return (a->prop==b->prop && a->ptr.data==b->ptr.data ) ? 0 : -1; } -/* For some reason python3 needs these :/ */ -static PyObject *pyrna_struct_richcmp(BPy_StructRNA * a, BPy_StructRNA * b, int op) +static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) { - int cmp_result= -1; /* assume false */ - if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) { - cmp_result= pyrna_struct_compare(a, b); + PyObject *res; + int ok= -1; /* zero is true */ + + if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) + ok= pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); + + switch (op) { + case Py_NE: + ok = !ok; /* pass through */ + case Py_EQ: + res = ok ? Py_False : Py_True; + break; + + case Py_LT: + case Py_LE: + case Py_GT: + case Py_GE: + res = Py_NotImplemented; + break; + default: + PyErr_BadArgument(); + return NULL; } - return Py_CmpToRich(op, cmp_result); + Py_INCREF(res); + return res; } -static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, int op) +static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op) { - int cmp_result= -1; /* assume false */ - if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) { - cmp_result= pyrna_prop_compare(a, b); + PyObject *res; + int ok= -1; /* zero is true */ + + if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) + ok= pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); + + switch (op) { + case Py_NE: + ok = !ok; /* pass through */ + case Py_EQ: + res = ok ? Py_False : Py_True; + break; + + case Py_LT: + case Py_LE: + case Py_GT: + case Py_GE: + res = Py_NotImplemented; + break; + default: + PyErr_BadArgument(); + return NULL; } - return Py_CmpToRich(op, cmp_result); + Py_INCREF(res); + return res; } /*----------------------repr--------------------------------------------*/ diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index be343843acc..1766be62c83 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -122,44 +122,6 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag) return 0; /* ok */ } - -/* Copied from pythons 3's Object.c */ -PyObject * -Py_CmpToRich(int op, int cmp) -{ - PyObject *res; - int ok; - - if (PyErr_Occurred()) - return NULL; - switch (op) { - case Py_LT: - ok = cmp < 0; - break; - case Py_LE: - ok = cmp <= 0; - break; - case Py_EQ: - ok = cmp == 0; - break; - case Py_NE: - ok = cmp != 0; - break; - case Py_GT: - ok = cmp > 0; - break; - case Py_GE: - ok = cmp >= 0; - break; - default: - PyErr_BadArgument(); - return NULL; - } - res = ok ? Py_True : Py_False; - Py_INCREF(res); - return res; -} - /* for debugging */ void PyObSpit(char *name, PyObject *var) { fprintf(stderr, "<%s> : ", name); diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index 0400d595520..83fa7a5b7c4 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -50,8 +50,6 @@ void PyObSpit(char *name, PyObject *var); void PyLineSpit(void); void BPY_getFileAndNum(char **filename, int *lineno); -PyObject *Py_CmpToRich(int op, int cmp); - PyObject *BPY_exception_buffer(void); /* own python like utility function */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 667b4cd5d89..9e81bcb3871 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -2016,44 +2016,3 @@ void resetGamePythonPath() { gp_GamePythonPathOrig[0] = '\0'; } - - -/* Copied from pythons 3's Object.c - * also in blenders bpy_uitl.c, mailed the python-dev - * list about enabling something like this again for py3 */ -PyObject * -Py_CmpToRich(int op, int cmp) -{ - PyObject *res; - int ok; - - if (PyErr_Occurred()) - return NULL; - switch (op) { - case Py_LT: - ok = cmp < 0; - break; - case Py_LE: - ok = cmp <= 0; - break; - case Py_EQ: - ok = cmp == 0; - break; - case Py_NE: - ok = cmp != 0; - break; - case Py_GT: - ok = cmp > 0; - break; - case Py_GE: - ok = cmp >= 0; - break; - default: - PyErr_BadArgument(); - return NULL; - } - res = ok ? Py_True : Py_False; - Py_INCREF(res); - return res; -} - diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 165a85e2c14..75a7c9b8aeb 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -340,24 +340,42 @@ static PyObject *KX_PythonSeq_nextIter(KX_PythonSeq *self) } -static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) /* TODO - python3.x wants richcmp */ +static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) { return ( a->type == b->type && a->base == b->base) ? 0 : -1; } -extern PyObject *Py_CmpToRich(int op, int cmp); - static PyObject *KX_PythonSeq_richcmp(PyObject *a, PyObject *b, int op) { - int cmp_result= -1; /* assume false */ + PyObject *res; + int ok= -1; /* zero is true */ + + if(BPy_KX_PythonSeq_Check(a) && BPy_KX_PythonSeq_Check(b)) + ok= KX_PythonSeq_compare((KX_PythonSeq *)a, (KX_PythonSeq *)b); - if(BPy_KX_PythonSeq_Check(a) && BPy_KX_PythonSeq_Check(b)) { - cmp_result= KX_PythonSeq_compare((KX_PythonSeq *)a, (KX_PythonSeq *)b); + switch (op) { + case Py_NE: + ok = !ok; /* pass through */ + case Py_EQ: + res = ok ? Py_False : Py_True; + break; + + case Py_LT: + case Py_LE: + case Py_GT: + case Py_GE: + res = Py_NotImplemented; + break; + default: + PyErr_BadArgument(); + return NULL; } - return Py_CmpToRich(op, cmp_result); + Py_INCREF(res); + return res; } + /* * repr function * convert to a list and get its string value -- cgit v1.2.3 From 6239d18d50911959a8d5a40056ef87e7253cc70e Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 3 Sep 2009 02:55:23 +0000 Subject: BlenderPlayer linking again for cmake - 148 errors gone. After talking with Ton and Campbell we agreed that it wouldn't hurt to have blenderplayer again (specially now since BGE is almost 100% working in 2.5). However in order to make it link, I needed to bring back stubs, a lot of so-called bad calls. I'm not sure how we should proceed from here, but it looks like people could start to take a look at source/blenderplayer/bad_level_calls_stubs/stubs.c and fix their own modules/functions ** NOTE: I removed the sound calls from BlenderPlayer. In order to fix it look at //XXX ADD SOUND in GPG_Application.cpp and GPC_Engine *** tested in CMake+MSVC. - Scons is not building !!! (why does the building systems have to be so different?) And someone may like to fix make. (take a look at /trunk/source/blender/blenkernel/bad_level_call_stubs/Makefile ) **** it may work better inside /source/gameengine/GamePlayer --- blenderplayer/CMakeLists.txt | 4 + blenderplayer/bad_level_call_stubs/CMakeLists.txt | 40 +++++ blenderplayer/bad_level_call_stubs/Makefile | 45 ++++++ blenderplayer/bad_level_call_stubs/SConscript | 14 ++ blenderplayer/bad_level_call_stubs/stubs.c | 179 +++++++++++++++++++++ source/gameengine/GamePlayer/common/GPC_Engine.cpp | 6 +- .../GamePlayer/ghost/GPG_Application.cpp | 18 ++- 7 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 blenderplayer/bad_level_call_stubs/CMakeLists.txt create mode 100644 blenderplayer/bad_level_call_stubs/Makefile create mode 100644 blenderplayer/bad_level_call_stubs/SConscript create mode 100644 blenderplayer/bad_level_call_stubs/stubs.c diff --git a/blenderplayer/CMakeLists.txt b/blenderplayer/CMakeLists.txt index 0407361b845..35d26662f2f 100644 --- a/blenderplayer/CMakeLists.txt +++ b/blenderplayer/CMakeLists.txt @@ -130,4 +130,8 @@ ELSE(UNIX) TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_LINK_LIBS}) ENDIF(UNIX) +IF(WITH_PLAYER) + ADD_SUBDIRECTORY(bad_level_call_stubs) +ENDIF(WITH_PLAYER) + SETUP_LIBLINKS(blenderplayer) diff --git a/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/blenderplayer/bad_level_call_stubs/CMakeLists.txt new file mode 100644 index 00000000000..abb086b072a --- /dev/null +++ b/blenderplayer/bad_level_call_stubs/CMakeLists.txt @@ -0,0 +1,40 @@ +# $Id$ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +FILE(GLOB SRC stubs.c) + +SET(INC + . + .. + ../../source/blender/makesdna + ../../source/blender/makesrna +) + +IF(WITH_INTERNATIONAL) + ADD_DEFINITIONS(-DWITH_FREETYPE2) +ENDIF(WITH_INTERNATIONAL) + +BLENDERLIB_NOLIST(blenkernel_blc "${SRC}" "${INC}") diff --git a/blenderplayer/bad_level_call_stubs/Makefile b/blenderplayer/bad_level_call_stubs/Makefile new file mode 100644 index 00000000000..1d9f6a27327 --- /dev/null +++ b/blenderplayer/bad_level_call_stubs/Makefile @@ -0,0 +1,45 @@ +# +# $Id$ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL LICENSE BLOCK ***** +# +# + +LIBNAME = blenkernel_blc +DIR = $(OCGDIR)/blenderplayer/$(LIBNAME) + +include nan_compile.mk + +CFLAGS += $(LEVEL_2_C_WARNINGS) +CFLAGS += $(FIX_STUBS_WARNINGS) + +CPPFLAGS += $(OGL_CPPFLAGS) +CPPFLAGS += -I../../source/blender/makesdna +CPPFLAGS += -I../../source/blender/makesrna + +# path to our own external headerfiles +CPPFLAGS += -I.. + diff --git a/blenderplayer/bad_level_call_stubs/SConscript b/blenderplayer/bad_level_call_stubs/SConscript new file mode 100644 index 00000000000..bd3df38b557 --- /dev/null +++ b/blenderplayer/bad_level_call_stubs/SConscript @@ -0,0 +1,14 @@ +#!/usr/bin/python +Import ('env') + +sources = 'stubs.c' + +incs = '. ..' +incs += '../../source/blender/makesdna' +incs += '../../source/blender/makesrna' + +defs = '' +if env['WITH_BF_INTERNATIONAL']: + defs += 'WITH_FREETYPE2' + +env.BlenderLib ('blenkernel_blc', sources = Split(sources), includes=Split(incs), defines=Split(defs), libtype='player',priority=225 ) diff --git a/blenderplayer/bad_level_call_stubs/stubs.c b/blenderplayer/bad_level_call_stubs/stubs.c new file mode 100644 index 00000000000..b3c18784ccd --- /dev/null +++ b/blenderplayer/bad_level_call_stubs/stubs.c @@ -0,0 +1,179 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * BKE_bad_level_calls function stubs + */ + +#include +#include "dna_listbase.h" +#include "RNA_types.h" + +/*new render funcs */ +float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype) {return NULL;} +float RE_filter_value(int type, float x) {return 0.0f;} +struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name) {return (struct RenderLayer *)NULL;} + +/* zbuf.c stub */ +void antialias_tagbuf(int xsize, int ysize, char *rectmove) {} +void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect) {} + +/* imagetexture.c stub */ +void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) {} + +/* texture.c */ +int multitex_thread(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, short thread, short which_output) {return 0;} +int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres){return 0;} + +/* nodes */ +struct RenderResult *RE_GetResult(struct Render *re){return (struct RenderResult *) NULL;} +struct Render *RE_GetRender(const char *name){return (struct Render *) NULL;} + +/* blenkernel */ +char* btempdir(){return NULL;} +void RE_FreeRenderResult(struct RenderResult *res){} +char* datatoc_bmonofont_ttf(){return NULL;} +int datatoc_bmonofont_ttf_size(){return 0;} +struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty){return (struct RenderResult *) NULL;} +void RE_GetResultImage(struct Render *re, struct RenderResult *rr){} +int RE_RenderInProgress(struct Render *re){return 0;} +struct Scene *RE_GetScene(struct Render *re){return (struct Scene *) NULL;} +void RE_Database_Free(struct Render *re){} +void RE_FreeRender(struct Render *re){} +void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr){} +void RE_DataBase_GetView(struct Render *re, float mat[][4]){} +int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){return 0;} +float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip){return 0.0f;} +void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype){} +char stipple_quarttone[1]; //GLubyte stipple_quarttone[128] +double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, char *retstr) {return 0.0f;} +char bprogname[]=""; + +/* rna */ +void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference){} +void ED_armature_bone_rename(struct bArmature *arm, char *oldnamep, char *newnamep){} +void object_test_constraints (struct Object *owner){} +void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr){} +void ED_node_composit_default(struct Scene *sce){} + +struct EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, struct EditBone *ebo){return (struct EditBone *) NULL;} +struct ListBase *get_active_constraints (struct Object *ob){return (struct ListBase *) NULL;} +int ED_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan){return 0;} + +int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit){return 0;} +int ED_space_image_show_render(struct SpaceImage *sima){return 0;} +int ED_space_image_show_paint(struct SpaceImage *sima){return 0;} +void ED_space_image_set(struct bContext *C, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima){} +struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBuf *) NULL;} + +struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob){return (struct PTCacheEdit *) NULL;} + +/* rna editors */ +char *ED_info_stats_string(struct Scene *scene){return NULL;} +void ED_area_tag_redraw(struct ScrArea *sa){} +void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op){} +void ED_node_texture_default(struct Tex *tx){} +int text_file_modified(struct Text *text){return 0;} +void ED_node_shader_default(struct Material *ma){} +void ED_screen_animation_timer_update(struct bContext *C, int redraws){} +int ED_object_modifier_remove(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md){return 0;} +int ED_object_modifier_add(struct ReportList *reports, struct Scene *scene, struct Object *ob, int type){return 0;} +int uiLayoutGetActive(struct uiLayout *layout){return 0;} +int uiLayoutGetOperatorContext(struct uiLayout *layout){return 0;} +int uiLayoutGetAlignment(struct uiLayout *layout){return 0;} +int uiLayoutGetEnabled(struct uiLayout *layout){return 0;} +float uiLayoutGetScaleX(struct uiLayout *layout){return 0.0f;} +float uiLayoutGetScaleY(struct uiLayout *layout){return 0.0f;} +void uiLayoutSetActive(struct uiLayout *layout, int active){} +void uiLayoutSetOperatorContext(struct uiLayout *layout, int opcontext){} +void uiLayoutSetEnabled(struct uiLayout *layout, int enabled){} +void uiLayoutSetAlignment(struct uiLayout *layout, int alignment){} +void uiLayoutSetScaleX(struct uiLayout *layout, float scale){} +void uiLayoutSetScaleY(struct uiLayout *layout, float scale){} + +void uiItemR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int flag){} + +PointerRNA uiItemFullO(struct uiLayout *layout, char *name, int icon, char *idname, struct IDProperty *properties, int context, int flag){PointerRNA a; return a;} +struct uiLayout *uiLayoutRow(struct uiLayout *layout, int align){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutColumn(struct uiLayout *layout, int align){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutColumnFlow(struct uiLayout *layout, int number, int align){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutBox(struct uiLayout *layout){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutSplit(struct uiLayout *layout, float percentage){return (struct uiLayout *) NULL;} +void uiItemsEnumR(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} +void uiItemMenuEnumR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname){} +void uiItemEnumR_string(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value){} +void uiItemPointerR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname){} +void uiItemsEnumO(struct uiLayout *layout, char *opname, char *propname){} +void uiItemEnumO_string(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value_str){} +void uiItemMenuEnumO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname){} +void uiItemBooleanO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} +void uiItemIntO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} +void uiItemFloatO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, float value){} +void uiItemStringO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value){} +void uiItemL(struct uiLayout *layout, char *name, int icon){} +void uiItemM(struct uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname){} +void uiItemS(struct uiLayout *layout){} +void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct PointerRNA *ptr){} + +/* rna template */ +void uiTemplateHeader(struct uiLayout *layout, struct bContext *C, int menus){} +void uiTemplateID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *unlinkop){} +struct uiLayout *uiTemplateModifier(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;} +struct uiLayout *uiTemplateConstraint(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;} +void uiTemplatePreview(struct uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot){} +void uiTemplateCurveMapping(struct uiLayout *layout, struct CurveMapping *cumap, int type, int compact){} +void uiTemplateColorRamp(struct uiLayout *layout, struct ColorBand *coba, int expand){} +void uiTemplateLayers(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} +void uiTemplateTriColorSet(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} +void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser){} +ListBase uiTemplateList(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activepropname, int rows, int listtype){struct ListBase b = {0,0}; return b;} +void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C){} +void uiTemplateOperatorSearch(struct uiLayout *layout){} +void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C){} +void uiTemplate_view3d_select_faceselmenu(struct uiLayout *layout, struct bContext *C){} +void uiTemplateTextureImage(struct uiLayout *layout, struct bContext *C, struct Tex *tex){} + +/* rna render */ +struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;} +void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result){} +void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result){} +void RE_engine_update_stats(struct RenderEngine *engine, char *stats, char *info){} +void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, char *filename){} +void RE_result_load_from_file(struct RenderResult *result, struct ReportList *reports, char *filename){} +int RE_engine_test_break(struct RenderEngine *engine){return 0;} + +/* python */ +struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} +struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;} +struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;} +int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties, struct ReportList *reports){return 0;} +int WM_operatortype_remove(const char *idname){return 0;} +void WM_operator_properties_free(struct PointerRNA *ptr){} +void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){} +void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){} +void WM_operator_bl_idname(char *to, const char *from){} +short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;} + diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.cpp b/source/gameengine/GamePlayer/common/GPC_Engine.cpp index a46f30c1209..9ccb55f37bc 100644 --- a/source/gameengine/GamePlayer/common/GPC_Engine.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Engine.cpp @@ -58,7 +58,9 @@ #include "NG_LoopBackNetworkDeviceInterface.h" #include "RAS_IRenderTools.h" -#include "SND_DeviceManager.h" +#if 0 //XXX - ADD SOUND + #include "SND_DeviceManager.h" +#endif #include "GPC_Engine.h" #include "GPC_KeyboardDevice.h" @@ -339,8 +341,10 @@ void GPC_Engine::Exit() if (m_audiodevice) { +#if 0 //XXX - ADD SOUND SND_DeviceManager::Unsubscribe(); m_audiodevice = 0; +#endif } m_initialized = false; diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index c9a2e81bdae..879c2264247 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -84,7 +84,10 @@ extern "C" #include "KX_BlenderSceneConverter.h" #include "NG_LoopBackNetworkDeviceInterface.h" -#include "SND_DeviceManager.h" + +#if 0 //XXX - ADD SOUND + #include "SND_DeviceManager.h" +#endif #include "GPC_MouseDevice.h" #include "GPC_RenderTools.h" @@ -584,13 +587,16 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) if (!m_networkdevice) goto initFailed; +#if 0 //XXX - ADD SOUND // get an audiodevice SND_DeviceManager::Subscribe(); m_audiodevice = SND_DeviceManager::Instance(); if (!m_audiodevice) goto initFailed; m_audiodevice->UseCD(); - +#endif + + // create a ketsjisystem (only needed for timing and stuff) m_kxsystem = new GPG_System (m_system); if (!m_kxsystem) @@ -607,7 +613,9 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) m_ketsjiengine->SetRenderTools(m_rendertools); m_ketsjiengine->SetRasterizer(m_rasterizer); m_ketsjiengine->SetNetworkDevice(m_networkdevice); +#if 0 //XXX - ADD SOUND m_ketsjiengine->SetAudioDevice(m_audiodevice); +#endif m_ketsjiengine->SetTimingDisplay(frameRate, false, false); CValue::SetDeprecationWarnings(nodepwarnings); @@ -621,7 +629,9 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) return m_engineInitialized; initFailed: delete m_kxsystem; +#if 0 // XXX - ADD SOUND delete m_audiodevice; +#endif delete m_networkdevice; delete m_mouse; delete m_keyboard; @@ -680,7 +690,7 @@ bool GPG_Application::startEngine(void) KX_Scene* startscene = new KX_Scene(m_keyboard, m_mouse, m_networkdevice, - m_audiodevice, +// m_audiodevice, // XXX ADD SOUND startscenename, m_startScene); @@ -783,8 +793,10 @@ void GPG_Application::exitEngine() } if (m_audiodevice) { +#if 0 //XXX - ADD SOUND SND_DeviceManager::Unsubscribe(); m_audiodevice = 0; +#endif } if (m_networkdevice) { -- cgit v1.2.3 From 8d407b7b28242fbccb6f314f02056bcab753a67a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 3 Sep 2009 05:12:34 +0000 Subject: Grease Pencil: Datablock bugfixes * Grease Pencil datablocks can now be properly browsed/added/unlinked from the UI panels * Made Grease Pencil use the brush icon for now. A proper icon for this would be nice ;) --- source/blender/editors/gpencil/gpencil_buttons.c | 11 +++++++---- source/blender/makesrna/intern/rna_ID.c | 1 + source/blender/makesrna/intern/rna_gpencil.c | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index c3f779b59b8..0d7cd263245 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -238,12 +238,15 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi col= uiLayoutColumn(layout, 0); /* current Grease Pencil block */ // TODO: show some info about who owns this? - //uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink"); // XXX not working - uiItemR(col, NULL, 0, ctx_ptr, "grease_pencil", 0); // XXX this will have to do for now... + uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", "GPENCIL_OT_data_unlink"); - /* add new layer button */ + /* add new layer button - can be used even when no data, since it can add a new block too */ uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add"); + /* sanity checks... */ + if (gpd == NULL) + return; + /* draw each layer --------------------------------------------- */ for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { col= uiLayoutColumn(layout, 1); @@ -271,7 +274,7 @@ void gpencil_panel_standard(const bContext *C, Panel *pa) /* get pointer to Grease Pencil Data */ gpd_ptr= gpencil_data_get_pointers((bContext *)C, &ptr); - if (gpd_ptr && *gpd_ptr) + if (gpd_ptr) draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr); } diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index dd26391b11e..f5c6063e892 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -65,6 +65,7 @@ short RNA_type_to_ID_code(StructRNA *type) if(RNA_struct_is_a(type, &RNA_Brush)) return ID_BR; if(RNA_struct_is_a(type, &RNA_Camera)) return ID_CA; if(RNA_struct_is_a(type, &RNA_Curve)) return ID_CU; + if(RNA_struct_is_a(type, &RNA_GreasePencil)) return ID_GD; if(RNA_struct_is_a(type, &RNA_Group)) return ID_GR; if(RNA_struct_is_a(type, &RNA_Image)) return ID_IM; if(RNA_struct_is_a(type, &RNA_Key)) return ID_KE; diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index df0e5ae6703..5caa868fd2e 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -223,7 +223,7 @@ void rna_def_gpencil_data(BlenderRNA *brna) srna= RNA_def_struct(brna, "GreasePencil", "ID"); RNA_def_struct_sdna(srna, "bGPdata"); RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook."); - //RNA_def_struct_ui_icon(srna, ICON_GPENCIL); + RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA); // XXX: ICON_GPENCIL!!! /* Layers */ prop= RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); -- cgit v1.2.3 From 99fbcbcf4d97c83e3c2d976244919889278a9366 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Sep 2009 06:34:03 +0000 Subject: changes needed for building the blenderplayer with cmake on linux. --- SConstruct | 3 --- blenderplayer/CMakeLists.txt | 12 +++++++++--- blenderplayer/bad_level_call_stubs/stubs.c | 25 +++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/SConstruct b/SConstruct index 5a64cd7c117..ec302d90fce 100644 --- a/SConstruct +++ b/SConstruct @@ -402,9 +402,6 @@ dobj = B.buildinfo(env, "dynamic") + B.resources thestatlibs, thelibincs = B.setup_staticlibs(env) thesyslibs = B.setup_syslibs(env) -if env['WITH_BF_PLAYER']: - print("Warning: Game player may not build on 2.5") - if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: #env.BlenderProg(B.root_build_dir, "blender", dobj , [], mainlist + thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') diff --git a/blenderplayer/CMakeLists.txt b/blenderplayer/CMakeLists.txt index 35d26662f2f..030d9dbbba0 100644 --- a/blenderplayer/CMakeLists.txt +++ b/blenderplayer/CMakeLists.txt @@ -80,11 +80,11 @@ IF(UNIX) bf_oglrasterizer bf_expressions bf_scenegraph - bf_IK + bf_IK bf_moto bf_kernel bf_nodes - bf_gpu + bf_gpu bf_imbuf bf_avi kx_network @@ -93,15 +93,21 @@ IF(UNIX) extern_bullet bf_guardedalloc bf_memutil + bf_python + bf_gen_python bf_blenlib bf_cineon bf_openexr extern_libopenjpeg bf_dds bf_readblenfile + bf_dna + bf_rna + bf_blenfont + bf_audaspace blenkernel_blc extern_binreloc - extern_glew + extern_glew ) IF(WITH_QUICKTIME) diff --git a/blenderplayer/bad_level_call_stubs/stubs.c b/blenderplayer/bad_level_call_stubs/stubs.c index b3c18784ccd..2db012ebcea 100644 --- a/blenderplayer/bad_level_call_stubs/stubs.c +++ b/blenderplayer/bad_level_call_stubs/stubs.c @@ -29,7 +29,7 @@ */ #include -#include "dna_listbase.h" +#include "DNA_listBase.h" #include "RNA_types.h" /*new render funcs */ @@ -70,7 +70,6 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype){} char stipple_quarttone[1]; //GLubyte stipple_quarttone[128] double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, char *retstr) {return 0.0f;} -char bprogname[]=""; /* rna */ void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference){} @@ -177,3 +176,25 @@ void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), v void WM_operator_bl_idname(char *to, const char *from){} short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;} +/* smoke */ +void lzo1x_1_compress(void) {return;}; +void LzmaCompress(void) {return;}; +void smoke_export(void) {return;}; +void lzo1x_decompress(void) {return;}; +void LzmaUncompress(void) {return;}; +void smoke_init(void) {return;}; +void smoke_turbulence_init(void) {return;}; +void smoke_turbulence_initBlenderRNA(void) {return;}; +void smoke_initBlenderRNA(void) {return;}; +void smoke_free(void) {return;}; +void smoke_turbulence_free(void) {return;}; +void smoke_turbulence_step(void) {return;}; +void smoke_dissolve(void) {return;}; +void smoke_get_density(void) {return;}; +void smoke_get_heat(void) {return;}; +void smoke_get_velocity_x(void) {return;}; +void smoke_get_velocity_y(void) {return;}; +void smoke_get_velocity_z(void) {return;}; +void smoke_get_obstacle(void) {return;}; +void smoke_get_index(void) {return;}; +void smoke_step(void) {return;}; -- cgit v1.2.3 From 070f12d0ddd186769b0c0760e5ccd2de08d1e493 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Sep 2009 07:12:41 +0000 Subject: sound init/exit so at least the player opens --- source/gameengine/GamePlayer/common/GPC_Engine.cpp | 2 +- source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.cpp b/source/gameengine/GamePlayer/common/GPC_Engine.cpp index 9ccb55f37bc..f131987095a 100644 --- a/source/gameengine/GamePlayer/common/GPC_Engine.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Engine.cpp @@ -343,8 +343,8 @@ void GPC_Engine::Exit() { #if 0 //XXX - ADD SOUND SND_DeviceManager::Unsubscribe(); - m_audiodevice = 0; #endif + m_audiodevice = 0; } m_initialized = false; diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 2433c587179..d399d6b3443 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -59,6 +59,7 @@ extern "C" #include "BKE_icons.h" #include "BKE_node.h" #include "BKE_report.h" +#include "BKE_sound.h" #include "BLI_blenlib.h" #include "DNA_scene_types.h" #include "BLO_readfile.h" @@ -358,6 +359,8 @@ int main(int argc, char** argv) quicktime_init(); #endif + sound_init(); + libtiff_init(); // Parse command line options @@ -818,6 +821,8 @@ int main(int argc, char** argv) } free_nodesystem(); + + sound_exit(); return error ? -1 : 0; } -- cgit v1.2.3 From 40c89b5c6ee639539fdc74e669d92152e9e9fc06 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 3 Sep 2009 10:34:54 +0000 Subject: Missing header include for non-linux OS "BLI_exist()" --- source/blender/python/intern/bpy_interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index ac8acc2c07c..a935b517f77 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -55,6 +55,7 @@ #include "MEM_guardedalloc.h" #include "BLI_util.h" +#include "BLI_storage.h" #include "BLI_fileops.h" #include "BLI_string.h" -- cgit v1.2.3 From 78425fb6577e7d1a27e331daacf48c7c53422efd Mon Sep 17 00:00:00 2001 From: Michael Fox Date: Thu, 3 Sep 2009 10:42:53 +0000 Subject: 2.5 ***** first commit in a long time, and its great to be back! commited Select Mirror operator for objects eg. L.sword->R.sword added to 3dview select menu aswel the hotkey is shift-ctrl-m (hope its not taken) --- release/ui/space_view3d.py | 1 + source/blender/editors/object/object_edit.c | 161 ++++++++++++++++++++++++++ source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 2 + 4 files changed, 165 insertions(+) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index c5c1abf1d40..8477e52acab 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -167,6 +167,7 @@ class VIEW3D_MT_select_OBJECT(bpy.types.Menu): layout.itemO("object.select_all_toggle", text="Select/Deselect All") layout.itemO("object.select_inverse", text="Inverse") layout.itemO("object.select_random", text="Random") + layout.itemO("object.select_mirror", text="Mirror") layout.itemO("object.select_by_layer", text="Select All by Layer") layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...") layout.itemO("object.select_grouped", text="Select Grouped...") diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 04187c93196..33ecb144f13 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "MEM_guardedalloc.h" @@ -2189,6 +2191,165 @@ void OBJECT_OT_select_all_toggle(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ****** select mirror *******/ +/* finds the best possible flipped name. For renaming; check for unique names afterwards */ +/* if strip_number: removes number extensions */ +void object_flip_name (char *name) +{ + int len; + char prefix[128]={""}; /* The part before the facing */ + char suffix[128]={""}; /* The part after the facing */ + char replace[128]={""}; /* The replacement string */ + char number[128]={""}; /* The number extension string */ + char *index=NULL; + + len= strlen(name); + if(len<3) return; // we don't do names like .R or .L + + /* We first check the case with a .### extension, let's find the last period */ + if(isdigit(name[len-1])) { + index= strrchr(name, '.'); // last occurrance + if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! + strcpy(number, index); + *index= 0; + len= strlen(name); + } + } + + strcpy (prefix, name); + +#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') + + /* first case; separator . - _ with extensions r R l L */ + if( IS_SEPARATOR(name[len-2]) ) { + switch(name[len-1]) { + case 'l': + prefix[len-1]= 0; + strcpy(replace, "r"); + break; + case 'r': + prefix[len-1]= 0; + strcpy(replace, "l"); + break; + case 'L': + prefix[len-1]= 0; + strcpy(replace, "R"); + break; + case 'R': + prefix[len-1]= 0; + strcpy(replace, "L"); + break; + } + } + /* case; beginning with r R l L , with separator after it */ + else if( IS_SEPARATOR(name[1]) ) { + switch(name[0]) { + case 'l': + strcpy(replace, "r"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'r': + strcpy(replace, "l"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'L': + strcpy(replace, "R"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'R': + strcpy(replace, "L"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + } + } + else if(len > 5) { + /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ + index = BLI_strcasestr(prefix, "right"); + if (index==prefix || index==prefix+len-5) { + if(index[0]=='r') + strcpy (replace, "left"); + else { + if(index[1]=='I') + strcpy (replace, "LEFT"); + else + strcpy (replace, "Left"); + } + *index= 0; + strcpy (suffix, index+5); + } + else { + index = BLI_strcasestr(prefix, "left"); + if (index==prefix || index==prefix+len-4) { + if(index[0]=='l') + strcpy (replace, "right"); + else { + if(index[1]=='E') + strcpy (replace, "RIGHT"); + else + strcpy (replace, "Right"); + } + *index= 0; + strcpy (suffix, index+4); + } + } + } + +#undef IS_SEPARATOR + + sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); +} + +static int object_select_mirror_exec(bContext *C, wmOperator *op) +{ + char tmpname[32]; + short seltype; + + seltype = RNA_enum_get(op->ptr, "seltype"); + + CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) { + + strcpy(tmpname, primbase->object->id.name+2); + object_flip_name(tmpname); + + CTX_DATA_BEGIN(C, Base*, secbase, visible_bases) { + if(!strcmp(secbase->object->id.name+2, tmpname)) { + ED_base_object_select(secbase, BA_SELECT); + } + } + CTX_DATA_END; + + if (seltype == 0) ED_base_object_select(primbase, BA_DESELECT); + + } + CTX_DATA_END; + + /* undo? */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_mirror(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Select Mirror"; + ot->description = "Select the Mirror objects of the selected object eg. L.sword -> R.sword"; + ot->idname= "OBJECT_OT_select_mirror"; + + /* api callbacks */ + ot->exec= object_select_mirror_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); +} /* ****** random selection *******/ static int object_select_random_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 82bbb34f59a..27f80186bf9 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -54,6 +54,7 @@ void OBJECT_OT_select_by_type(struct wmOperatorType *ot); void OBJECT_OT_select_by_layer(struct wmOperatorType *ot); void OBJECT_OT_select_linked(struct wmOperatorType *ot); void OBJECT_OT_select_grouped(struct wmOperatorType *ot); +void OBJECT_OT_select_mirror(struct wmOperatorType *ot); void OBJECT_OT_location_clear(struct wmOperatorType *ot); void OBJECT_OT_rotation_clear(struct wmOperatorType *ot); void OBJECT_OT_scale_clear(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 73dad7895a1..5e90ed85625 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -79,6 +79,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_by_layer); WM_operatortype_append(OBJECT_OT_select_linked); WM_operatortype_append(OBJECT_OT_select_grouped); + WM_operatortype_append(OBJECT_OT_select_mirror); WM_operatortype_append(OBJECT_OT_location_clear); WM_operatortype_append(OBJECT_OT_rotation_clear); WM_operatortype_append(OBJECT_OT_scale_clear); @@ -192,6 +193,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); -- cgit v1.2.3 From 92395bb93cf862c5d19a40942ba3c8fbc94de962 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 3 Sep 2009 12:20:59 +0000 Subject: 2.5 - A few bugfixes... * Autoside renaming tools in EditMode for armatures now works again. (Wrong property name) * Action used by NLA Strips can now be chosen/changed to another action --- release/ui/buttons_data_bone.py | 1 + release/ui/space_view3d.py | 6 +++--- source/blender/editors/armature/editarmature.c | 4 ++-- source/blender/editors/space_nla/nla_buttons.c | 3 ++- source/blender/makesrna/intern/rna_nla.c | 1 + 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index 8098648886b..276ca066af5 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -80,6 +80,7 @@ class BONE_PT_bone(BoneButtonsPanel): if not bone: bone = context.edit_bone + pchan = None else: pchan = ob.pose.pose_channels[context.bone.name] diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 8477e52acab..1d7ea280222 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -1069,9 +1069,9 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu): layout.itemS() - layout.item_enumO("armature.autoside_names", "axis", 'XAXIS', text="AutoName Left/Right") - layout.item_enumO("armature.autoside_names", "axis", 'YAXIS', text="AutoName Front/Back") - layout.item_enumO("armature.autoside_names", "axis", 'ZAXIS', text="AutoName Top/Bottom") + layout.item_enumO("armature.autoside_names", "type", 'XAXIS', text="AutoName Left/Right") + layout.item_enumO("armature.autoside_names", "type", 'YAXIS', text="AutoName Front/Back") + layout.item_enumO("armature.autoside_names", "type", 'ZAXIS', text="AutoName Top/Bottom") layout.itemO("armature.flip_names") layout.itemS() diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 632f037679f..9f83733a640 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -5387,7 +5387,7 @@ static int armature_autoside_names_exec (bContext *C, wmOperator *op) Object *ob= CTX_data_edit_object(C); bArmature *arm; char newname[32]; - short axis= RNA_enum_get(op->ptr, "axis"); + short axis= RNA_enum_get(op->ptr, "type"); /* paranoia checks */ if (ELEM(NULL, ob, ob->pose)) @@ -5434,7 +5434,7 @@ void ARMATURE_OT_autoside_names (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* settings */ - RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with."); + RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with."); } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 2ffca5185f2..facea34510e 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -119,6 +119,7 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); for (ale= anim_data.first; ale; ale= ale->next) { + // TODO: need some way to select active animdata too... if (ale->type == ANIMTYPE_NLATRACK) { NlaTrack *nlt= (NlaTrack *)ale->data; AnimData *adt= ale->adt; @@ -210,7 +211,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa) /* Active Action Properties ------------------------------------- */ /* action */ row= uiLayoutRow(layout, 1); - uiItemR(row, NULL, 0, &adt_ptr, "action", 0); + uiTemplateID(row, C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators /* extrapolation */ row= uiLayoutRow(layout, 1); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 98fdf4a6878..690a198f12c 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -350,6 +350,7 @@ void rna_def_nlastrip(BlenderRNA *brna) /* Action */ prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "act"); + RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip."); /* Action extents */ -- cgit v1.2.3 From 9250ab0619387d80964c64738334e437a92c25cf Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Thu, 3 Sep 2009 17:45:04 +0000 Subject: 2.5/Multires: * Added back multires delete higher levels (new operator + button) --- release/ui/buttons_data_modifier.py | 6 +++++- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_modifier.c | 28 +++++++++++++++++++++++++ source/blender/editors/object/object_ops.c | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py index 66c8179f990..2835f55f71a 100644 --- a/release/ui/buttons_data_modifier.py +++ b/release/ui/buttons_data_modifier.py @@ -269,7 +269,11 @@ class DATA_PT_modifiers(DataButtonsPanel): def MULTIRES(self, layout, ob, md): layout.itemR(md, "subdivision_type") - layout.itemO("object.multires_subdivide", text="Subdivide") + + row = layout.row() + row.itemO("object.multires_subdivide", text="Subdivide") + row.itemO("object.multires_higher_levels_delete", text="Delete Higher") + layout.itemR(md, "level") def PARTICLE_INSTANCE(self, layout, ob, md): diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 27f80186bf9..8eaa388cdf0 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -109,6 +109,7 @@ void OBJECT_OT_modifier_apply(struct wmOperatorType *ot); void OBJECT_OT_modifier_convert(struct wmOperatorType *ot); void OBJECT_OT_modifier_copy(struct wmOperatorType *ot); void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot); +void OBJECT_OT_multires_higher_levels_delete(struct wmOperatorType *ot); void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot); void OBJECT_OT_hook_reset(struct wmOperatorType *ot); void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 0b8fedd2eda..f9e2ac2f4de 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -676,6 +676,34 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/************* multires delete higher levels operator ****************/ + +static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); + Object *ob= ptr.id.data; + MultiresModifierData *mmd= ptr.data; + + if(mmd) { + multiresModifier_del_levels(mmd, ob, 1); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + } + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot) +{ + ot->name= "Delete Higher Levels"; + ot->idname= "OBJECT_OT_multires_higher_levels_delete"; + ot->poll= ED_operator_object_active; + + ot->exec= multires_higher_levels_delete_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /****************** multires subdivide operator *********************/ static int multires_subdivide_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 5e90ed85625..09a27e9e613 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -119,6 +119,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_modifier_convert); WM_operatortype_append(OBJECT_OT_modifier_copy); WM_operatortype_append(OBJECT_OT_multires_subdivide); + WM_operatortype_append(OBJECT_OT_multires_higher_levels_delete); WM_operatortype_append(OBJECT_OT_meshdeform_bind); WM_operatortype_append(OBJECT_OT_hook_reset); WM_operatortype_append(OBJECT_OT_hook_recenter); -- cgit v1.2.3 From 579b8ef6e52255ff89ce62756709217fe68f596a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 3 Sep 2009 18:38:52 +0000 Subject: 2.5: fix missing LIB_NEEDLINK check in windowmanager reading, would cause crash with linking/appending. --- source/blender/blenloader/intern/readfile.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 64fabc825bc..0231d841c2b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4355,11 +4355,14 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) static void lib_link_windowmanager(FileData *fd, Main *main) { wmWindowManager *wm; + wmWindow *win; for(wm= main->wm.first; wm; wm= wm->id.next) { - wmWindow *win; - for(win= wm->windows.first; win; win= win->next) { - win->screen= newlibadr(fd, NULL, win->screen); + if(wm->id.flag & LIB_NEEDLINK) { + for(win= wm->windows.first; win; win= win->next) + win->screen= newlibadr(fd, NULL, win->screen); + + wm->id.flag -= LIB_NEEDLINK; } } } -- cgit v1.2.3 From fc975a91484a1346049071fa9c6c8877820245cd Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 3 Sep 2009 19:08:16 +0000 Subject: Bugfix for usage of uninitialized variable on windows (props_ptr.data needs to be set to NULL before calling uiItemFullO() ) - please check if this also compiles on gcc --- 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 33ecb144f13..a5e92096ef9 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2951,7 +2951,7 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) else if (ob->id.lib) { uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); uiLayout *layout= uiPupMenuLayout(pup); - PointerRNA props_ptr; + PointerRNA props_ptr = {0}; /* create operator menu item with relevant properties filled in */ props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); -- cgit v1.2.3 From 02f951c3a05f6586f12d129c70adffd8315ec3b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Sep 2009 22:37:09 +0000 Subject: allow execution mode to be given as an argument to operators from python (requested by algorith) example. bpy.ops.tfm.rotate('INVOKE_REGION_WIN', pivot=(0,1,2), ......) bpy_array.c - was too strict with types, 0 should be allowed as well as 0.0 in a float array. --- blenderplayer/bad_level_call_stubs/stubs.c | 2 +- release/ui/bpy_ops.py | 28 ++++++++++- source/blender/makesdna/DNA_windowmanager_types.h | 4 ++ source/blender/python/intern/bpy_array.c | 6 +-- source/blender/python/intern/bpy_operator.c | 35 ++++---------- source/blender/windowmanager/WM_api.h | 3 +- source/blender/windowmanager/intern/wm.c | 2 +- .../blender/windowmanager/intern/wm_event_system.c | 54 ++++++++++++++-------- 8 files changed, 79 insertions(+), 55 deletions(-) diff --git a/blenderplayer/bad_level_call_stubs/stubs.c b/blenderplayer/bad_level_call_stubs/stubs.c index 2db012ebcea..5ddafca5340 100644 --- a/blenderplayer/bad_level_call_stubs/stubs.c +++ b/blenderplayer/bad_level_call_stubs/stubs.c @@ -168,7 +168,7 @@ int RE_engine_test_break(struct RenderEngine *engine){return 0;} struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;} struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;} -int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties, struct ReportList *reports){return 0;} +int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;} int WM_operatortype_remove(const char *idname){return 0;} void WM_operator_properties_free(struct PointerRNA *ptr){} void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){} diff --git a/release/ui/bpy_ops.py b/release/ui/bpy_ops.py index aa9bfb460f0..dff8125fca1 100644 --- a/release/ui/bpy_ops.py +++ b/release/ui/bpy_ops.py @@ -5,6 +5,18 @@ from bpy.__ops__ import dir as op_dir from bpy.__ops__ import call as op_call from bpy.__ops__ import get_rna as op_get_rna +# Keep in sync with WM_types.h +context_dict = { + 'INVOKE_DEFAULT':0, + 'INVOKE_REGION_WIN':1, + 'INVOKE_AREA':2, + 'INVOKE_SCREEN':3, + 'EXEC_DEFAULT':4, + 'EXEC_REGION_WIN':5, + 'EXEC_AREA':6, + 'EXEC_SCREEN':7, +} + class bpy_ops(object): ''' Fake module like class. @@ -94,10 +106,22 @@ class bpy_ops_submodule_op(object): # submod.foo -> SUBMOD_OT_foo return self.module.upper() + '_OT_' + self.func - def __call__(self, **kw): + def __call__(self, *args, **kw): # Get the operator from blender - return op_call(self.idname(), kw) + if len(args) > 1: + raise ValueError("only one argument for the execution context is supported ") + + if args: + try: + context = context_dict[args[0]] + except: + raise ValueError("Expected a single context argument in: " + str(list(context_dict.keys()))) + + return op_call(self.idname(), kw, context) + + else: + return op_call(self.idname(), kw) def get_rna(self): ''' diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 7d03bbec1ee..10f83c8b9ec 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -285,6 +285,7 @@ typedef struct wmOperator { ListBase macro; /* list of operators, can be a tree */ struct wmOperator *opm; /* current running macro, not saved */ + short flag, pad[3]; } wmOperator; @@ -295,6 +296,9 @@ typedef struct wmOperator { /* add this flag if the event should pass through */ #define OPERATOR_PASS_THROUGH 8 +/* wmOperator flag */ +#define OPERATOR_REPORT_FREE 1 + /* ************** wmEvent ************************ */ /* for read-only rna access, dont save this */ diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index d52bfda202d..669cccb7011 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -203,17 +203,17 @@ static void pyrna_py_to_boolean(PyObject *py, char *data) static int py_float_check(PyObject *py) { - return PyFloat_Check(py); + return PyFloat_Check(py) || (PyIndex_Check(py)); } static int py_int_check(PyObject *py) { - return PyLong_Check(py); + return PyLong_Check(py) || (PyIndex_Check(py)); } static int py_bool_check(PyObject *py) { - return PyBool_Check(py); + return PyBool_Check(py) || (PyIndex_Check(py)); } int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size) diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index e431f2a21e9..062db42e0e9 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -40,42 +40,23 @@ #include "BKE_utildefines.h" -/* 'self' stores the operator string */ static PyObject *pyop_call( PyObject * self, PyObject * args) { wmOperatorType *ot; int error_val = 0; PointerRNA ptr; - char *opname; - PyObject *kw= NULL; + char *opname; + PyObject *kw= NULL; /* optional args */ + + /* note that context is an int, python does the conversion in this case */ + int context= WM_OP_EXEC_DEFAULT; // XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it... bContext *C = BPy_GetContext(); - - switch(PyTuple_Size(args)) { - case 2: - kw = PyTuple_GET_ITEM(args, 1); - - if(!PyDict_Check(kw)) { - PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected second arg to be a dict"); - return NULL; - } - /* pass through */ - case 1: - opname = _PyUnicode_AsString(PyTuple_GET_ITEM(args, 0)); - - if(opname==NULL) { - PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected the first arg to be a string"); - return NULL; - } - break; - default: - PyErr_SetString( PyExc_AttributeError, "bpy.__ops__.call: expected a string and optional dict"); + if (!PyArg_ParseTuple(args, "s|O!i:bpy.__ops__.call", &opname, &PyDict_Type, &kw, &context)) return NULL; - } - ot= WM_operatortype_find(opname, TRUE); @@ -88,7 +69,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect"); return NULL; } - + /* WM_operator_properties_create(&ptr, opname); */ /* Save another lookup */ RNA_pointer_create(NULL, ot->srna, NULL, &ptr); @@ -102,7 +83,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) BKE_reports_init(&reports, RPT_STORE); - WM_operator_call_py(C, ot, &ptr, &reports); + WM_operator_call_py(C, ot, context, &ptr, &reports); if(BPy_reports_to_error(&reports)) error_val = -1; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 0f5558382c4..544804b26d6 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -165,7 +165,7 @@ wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char int WM_operator_call (struct bContext *C, struct wmOperator *op); int WM_operator_repeat (struct bContext *C, struct wmOperator *op); int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties); -int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties, struct ReportList *reports); +int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports); void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_free(struct PointerRNA *ptr); @@ -245,6 +245,5 @@ void WM_jobs_stop_all(struct wmWindowManager *wm); char *WM_clipboard_text_get(int selection); void WM_clipboard_text_set(char *buf, int selection); - #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 85f8a647826..fecd5c20a15 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -69,7 +69,7 @@ void WM_operator_free(wmOperator *op) MEM_freeN(op->properties); } - if(op->reports) { + if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) { BKE_reports_clear(op->reports); MEM_freeN(op->reports); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 6c34ed6f902..717c2d25261 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -345,11 +345,12 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P /* initialize error reports */ if (reports) { - op->reports= reports; /* must be initialized alredy */ + op->reports= reports; /* must be initialized already */ } else { op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); BKE_reports_init(op->reports, RPT_STORE); + op->flag |= OPERATOR_REPORT_FREE; } /* recursive filling of operator macro list */ @@ -392,13 +393,13 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event) } } -static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties) +static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports) { wmWindowManager *wm= CTX_wm_manager(C); int retval= OPERATOR_PASS_THROUGH; if(wm_operator_poll(C, ot)) { - wmOperator *op= wm_operator_create(wm, ot, properties, NULL); + wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */ if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE) printf("handle evt %d win %d op %s\n", event?event->type:0, CTX_wm_screen(C)->subwinactive, ot->idname); @@ -442,10 +443,12 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P return retval; } -/* invokes operator in context */ -int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties) +/* WM_operator_name_call is the main accessor function + * this is for python to access since its done the operator lookup + * + * invokes operator in context */ +static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports) { - wmOperatorType *ot= WM_operatortype_find(opstring, 0); wmWindow *window= CTX_wm_window(C); wmEvent *event; @@ -473,7 +476,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe CTX_wm_region_set(C, ar1); } - retval= wm_operator_invoke(C, ot, event, properties); + retval= wm_operator_invoke(C, ot, event, properties, reports); /* set region back */ CTX_wm_region_set(C, ar); @@ -488,7 +491,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe ARegion *ar= CTX_wm_region(C); CTX_wm_region_set(C, NULL); - retval= wm_operator_invoke(C, ot, event, properties); + retval= wm_operator_invoke(C, ot, event, properties, reports); CTX_wm_region_set(C, ar); return retval; @@ -503,7 +506,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe CTX_wm_region_set(C, NULL); CTX_wm_area_set(C, NULL); - retval= wm_operator_invoke(C, ot, event, properties); + retval= wm_operator_invoke(C, ot, event, properties, reports); CTX_wm_region_set(C, ar); CTX_wm_area_set(C, area); @@ -512,32 +515,45 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe case WM_OP_EXEC_DEFAULT: event= NULL; /* pass on without break */ case WM_OP_INVOKE_DEFAULT: - return wm_operator_invoke(C, ot, event, properties); + return wm_operator_invoke(C, ot, event, properties, reports); } } return 0; } + +/* invokes operator in context */ +int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties) +{ + wmOperatorType *ot= WM_operatortype_find(opstring, 0); + if(ot) + return wm_operator_call_internal(C, ot, context, properties, NULL); + + return 0; +} + /* Similar to WM_operator_name_call called with WM_OP_EXEC_DEFAULT context. - wmOperatorType is used instead of operator name since python alredy has the operator type - poll() must be called by python before this runs. - reports can be passed to this function (so python can report them as exceptions) */ -int WM_operator_call_py(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports) +int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports) { - wmWindowManager *wm= CTX_wm_manager(C); - wmOperator *op= wm_operator_create(wm, ot, properties, reports); int retval= OPERATOR_CANCELLED; - + +#if 0 + wmOperator *op; + wmWindowManager *wm= CTX_wm_manager(C); + op= wm_operator_create(wm, ot, properties, reports); + if (op->type->exec) retval= op->type->exec(C, op); else printf("error \"%s\" operator has no exec function, python cannot call it\n", op->type->name); - - if (reports) - op->reports= NULL; /* dont let the operator free reports passed to this function */ - WM_operator_free(op); +#endif + + retval= wm_operator_call_internal(C, ot, context, properties, reports); return retval; } @@ -820,7 +836,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand wmOperatorType *ot= WM_operatortype_find(event->keymap_idname, 0); if(ot) - retval= wm_operator_invoke(C, ot, event, properties); + retval= wm_operator_invoke(C, ot, event, properties, NULL); } if(retval & OPERATOR_PASS_THROUGH) -- cgit v1.2.3 From 993037d3cb52aa438096215e9d120e6f3d95205b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 00:18:44 +0000 Subject: 2.5 - Bugfixes for Armature operators AutoSide names now gets called correctly from menus. However, the toggle bone settings operators aren't. I can't seem to get them to call the invoke again after making autoside call exec... --- release/ui/space_view3d.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 1d7ea280222..ae1edc0295b 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -622,6 +622,7 @@ class VIEW3D_MT_POSE(bpy.types.Menu): layout.itemS() + layout.operator_context = "EXEC_AREA" layout.item_enumO("pose.autoside_names", "axis", 'XAXIS', text="AutoName Left/Right") layout.item_enumO("pose.autoside_names", "axis", 'YAXIS', text="AutoName Front/Back") layout.item_enumO("pose.autoside_names", "axis", 'ZAXIS', text="AutoName Top/Bottom") @@ -630,6 +631,7 @@ class VIEW3D_MT_POSE(bpy.types.Menu): layout.itemS() + layout.operator_context = "INVOKE_AREA" layout.itemO("pose.armature_layers", text="Change Armature Layers...") layout.itemO("pose.bone_layers", text="Change Bone Layers...") @@ -1068,14 +1070,16 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu): layout.itemO("armature.subdivide_multi", text="Subdivide") layout.itemS() - + + layout.operator_context = "EXEC_AREA" layout.item_enumO("armature.autoside_names", "type", 'XAXIS', text="AutoName Left/Right") layout.item_enumO("armature.autoside_names", "type", 'YAXIS', text="AutoName Front/Back") layout.item_enumO("armature.autoside_names", "type", 'ZAXIS', text="AutoName Top/Bottom") layout.itemO("armature.flip_names") layout.itemS() - + + layout.operator_context = "INVOKE_DEFAULT" layout.itemO("armature.armature_layers") layout.itemO("armature.bone_layers") @@ -1084,7 +1088,7 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu): layout.itemM("VIEW3D_MT_edit_ARMATURE_parent") layout.itemS() - + layout.item_menu_enumO("armature.flags_set", "mode", text="Bone Settings") class VIEW3D_MT_edit_ARMATURE_parent(bpy.types.Menu): -- cgit v1.2.3 From 640e39206b25bcd433223d85298961a860fc5cd7 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 4 Sep 2009 01:33:22 +0000 Subject: add blendcache files to dependancies. next step, per frames deps. --- release/io/netrender/utils.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index 30d96b2f92f..62571011bc1 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -1,5 +1,6 @@ import bpy import sys, os +import re import http, http.client, http.server, urllib import subprocess, shutil, time, hashlib @@ -66,7 +67,22 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): job.files.append(lib_path) - print(job.files) + root, ext = os.path.splitext(name) + cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that + + print("cache:", cache_path) + + if os.path.exists(cache_path): + pattern = re.compile("[a-zA-Z0-9]+_([0-9]+)_[0-9]+\.bphys") + for cache_name in sorted(os.listdir(cache_path)): + match = pattern.match(cache_name) + + if match: + print("Frame:", int(match.groups()[0]), cache_name) + + job.files.append(cache_path + cache_name) + + #print(job.files) job.name = job_name -- cgit v1.2.3 From fa01703ac3caf08c42509e17be94559efd69bd2b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 02:44:56 +0000 Subject: 2.5 - Keyframe Types for DopeSheet It is now possible to tag certain keyframes as being 'breakdowns' in the DopeSheet. Breakdown keyframes are drawn as slightly smaller blue diamonds. Simply select the relevant keyframes and use the RKEY hotkey (or from the menus, Key->Keyframe Type) to choose between tagging the keyframe as a 'proper' keyframe and a 'breakdown' keyframe. Notes: * Please note that this feature does not currently imply anything about breakdowns moving around keyframes or behaving any differently from any other type of keyframe * In future, if there is any such need, more keyframe types could be added, though this is not really likely at all --- source/blender/editors/animation/keyframes_draw.c | 37 ++++++++--- source/blender/editors/animation/keyframes_edit.c | 31 +++++++++- source/blender/editors/include/ED_anim_api.h | 7 ++- source/blender/editors/include/ED_keyframes_draw.h | 6 +- source/blender/editors/include/ED_keyframes_edit.h | 3 +- source/blender/editors/space_action/action_edit.c | 71 ++++++++++++++++++++++ .../blender/editors/space_action/action_header.c | 18 ++++-- .../blender/editors/space_action/action_intern.h | 1 + source/blender/editors/space_action/action_ops.c | 2 + source/blender/editors/space_graph/graph_header.c | 10 +-- source/blender/editors/space_nla/nla_buttons.c | 2 +- source/blender/editors/space_nla/nla_draw.c | 2 +- source/blender/makesdna/DNA_curve_types.h | 17 ++++-- source/blender/makesrna/RNA_enum_types.h | 1 + source/blender/makesrna/intern/rna_curve.c | 19 +++++- 15 files changed, 193 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 2107e6e4252..abea38e129e 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -98,9 +98,7 @@ static ActKeyColumn *bezt_to_new_actkeycolumn(BezTriple *bezt) /* store settings based on state of BezTriple */ ak->cfra= bezt->vec[1][0]; ak->sel= BEZSELECTED(bezt) ? SELECT : 0; - - // TODO: handle type = bezt->h1 or bezt->h2 - ak->handle_type= 0; + ak->key_type= BEZKEYTYPE(bezt); /* set 'modified', since this is used to identify long keyframes */ ak->modified = 1; @@ -134,6 +132,10 @@ static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt) if (BEZSELECTED(bezt)) ak->sel = SELECT; ak->modified += 1; + /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */ + if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME) + ak->key_type= BEZT_KEYTYPE_KEYFRAME; + /* done... no need to insert */ return; } @@ -340,7 +342,7 @@ static const float _unit_diamond_shape[4][2] = { }; /* draw a simple diamond shape with OpenGL */ -void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short mode) +void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode) { static GLuint displist1=0; static GLuint displist2=0; @@ -371,6 +373,11 @@ void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel glEndList(); } + /* tweak size of keyframe shape according to type of keyframe + * - 'proper' keyframes have key_type=0, so get drawn at full size + */ + hsize -= 0.5f*key_type; + /* adjust view transform before starting */ glTranslatef(x, y, 0.0f); glScalef(1.0f/xscale*hsize, hsize, 1.0f); @@ -381,8 +388,22 @@ void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel /* draw! */ if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) { /* interior - hardcoded colors (for selected and unselected only) */ - if (sel) UI_ThemeColorShade(TH_STRIP_SELECT, 50); - else glColor3ub(0xE9, 0xE9, 0xE9); + switch (key_type) { + case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames for now */ + { + if (sel) glColor3f(0.33f, 0.75f, 0.93f); + else glColor3f(0.70f, 0.86f, 0.91f); + } + break; + + case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */ + default: + { + if (sel) UI_ThemeColorShade(TH_STRIP_SELECT, 50); + else glColor3f(0.91f, 0.91f, 0.91f); + } + break; + } glCallList(displist2); } @@ -454,7 +475,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* draw using OpenGL - uglier but faster */ // NOTE1: a previous version of this didn't work nice for some intel cards // NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; - draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), KEYFRAME_SHAPE_BOTH); + draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH); } } @@ -695,7 +716,7 @@ void gpl_to_keylist(bDopeSheet *ads, bGPDlayer *gpl, DLRBT_Tree *keys, DLRBT_Tre ak->cfra= (float)gpf->framenum; ak->modified = 1; - ak->handle_type= 0; + ak->key_type= 0; if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT; diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 77826eca87a..ac04dc7d1a8 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -655,7 +655,7 @@ static short set_bezt_bezier(BeztEditData *bed, BezTriple *bezt) return 0; } -/* Set the interpolation type of the selected BezTriples in each IPO curve to the specified one */ +/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */ // ANIM_editkeyframes_ipocurve_ipotype() ! BeztEditFunc ANIM_editkeyframes_ipo(short code) { @@ -669,6 +669,35 @@ BeztEditFunc ANIM_editkeyframes_ipo(short code) } } +/* ------- */ + +static short set_keytype_keyframe(BeztEditData *bed, BezTriple *bezt) +{ + if (bezt->f2 & SELECT) + BEZKEYTYPE(bezt)= BEZT_KEYTYPE_KEYFRAME; + return 0; +} + +static short set_keytype_breakdown(BeztEditData *bed, BezTriple *bezt) +{ + if (bezt->f2 & SELECT) + BEZKEYTYPE(bezt)= BEZT_KEYTYPE_BREAKDOWN; + return 0; +} + +/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */ +BeztEditFunc ANIM_editkeyframes_keytype(short code) +{ + switch (code) { + case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */ + return set_keytype_breakdown; + + case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */ + default: + return set_keytype_keyframe; + } +} + /* ******************************************* */ /* Selection */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 179f362b13f..af37cd87254 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -434,7 +434,12 @@ void ED_nla_postop_refresh(bAnimContext *ac); /* ------------- Utility macros ----------------------- */ /* checks if the given BezTriple is selected */ -#define BEZSELECTED(bezt) ((bezt->f2 & SELECT) || (bezt->f1 & SELECT) || (bezt->f3 & SELECT)) +#define BEZSELECTED(bezt) (((bezt)->f2 & SELECT) || ((bezt)->f1 & SELECT) || ((bezt)->f3 & SELECT)) + +/* provide access to Keyframe Type info in BezTriple + * NOTE: this is so that we can change it from being stored in 'hide' + */ +#define BEZKEYTYPE(bezt) ((bezt)->hide) /* set/clear/toggle macro * - channel - channel with a 'flag' member that we're setting diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index e940aaed36e..259104f7263 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -56,8 +56,8 @@ typedef struct ActKeyColumn { char tree_col; /* DLRB_BLACK or DLRB_RED */ /* keyframe info */ - char sel; - short handle_type; + char key_type; /* eBezTripe_KeyframeType */ + short sel; float cfra; /* only while drawing - used to determine if long-keyframe needs to be drawn */ @@ -99,7 +99,7 @@ typedef enum eKeyframeShapeDrawOpts { } eKeyframeShapeDrawOpts; /* draw simple diamond-shape keyframe (with OpenGL) */ -void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short mode); +void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode); /* ******************************* Methods ****************************** */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 77e95dc77de..390729eaec4 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -40,8 +40,6 @@ struct Scene; /* --------- BezTriple Selection ------------- */ -#define BEZSELECTED(bezt) ((bezt->f2 & SELECT) || (bezt->f1 & SELECT) || (bezt->f3 & SELECT)) - #define BEZ_SEL(bezt) { (bezt)->f1 |= SELECT; (bezt)->f2 |= SELECT; (bezt)->f3 |= SELECT; } #define BEZ_DESEL(bezt) { (bezt)->f1 &= ~SELECT; (bezt)->f2 &= ~SELECT; (bezt)->f3 &= ~SELECT; } #define BEZ_INVSEL(bezt) { (bezt)->f1 ^= SELECT; (bezt)->f2 ^= SELECT; (bezt)->f3 ^= SELECT; } @@ -133,6 +131,7 @@ BeztEditFunc ANIM_editkeyframes_mirror(short mode); BeztEditFunc ANIM_editkeyframes_select(short mode); BeztEditFunc ANIM_editkeyframes_handles(short mode); BeztEditFunc ANIM_editkeyframes_ipo(short mode); +BeztEditFunc ANIM_editkeyframes_keytype(short mode); /* ----------- BezTriple Callback (Assorted Utilities) ---------- */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index d4709e94e5e..b087736a368 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1038,6 +1038,77 @@ void ACT_OT_handle_type (wmOperatorType *ot) RNA_def_enum(ot->srna, "type", beztriple_handle_type_items, 0, "Type", ""); } +/* ******************** Set Keyframe-Type Operator *********************** */ + +/* this function is responsible for setting interpolation mode for keyframes */ +static void setkeytype_action_keys(bAnimContext *ac, short mode) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + BeztEditFunc set_cb= ANIM_editkeyframes_keytype(mode); + + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* loop through setting BezTriple interpolation + * Note: we do not supply BeztEditData to the looper yet. Currently that's not necessary here... + */ + for (ale= anim_data.first; ale; ale= ale->next) + ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, NULL); + + /* cleanup */ + BLI_freelistN(&anim_data); +} + +/* ------------------- */ + +static int actkeys_keytype_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + short mode; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + if (ac.datatype == ANIMCONT_GPENCIL) + return OPERATOR_PASS_THROUGH; + + /* get handle setting mode */ + mode= RNA_enum_get(op->ptr, "type"); + + /* set handle type */ + setkeytype_action_keys(&ac, mode); + + /* validate keyframes after editing */ + ANIM_editkeyframes_refresh(&ac); + + /* set notifier that keyframe properties have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL); + + return OPERATOR_FINISHED; +} + +void ACT_OT_keyframe_type (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Keyframe Type"; + ot->idname= "ACT_OT_keyframe_type"; + ot->description= "Set type of keyframe for the seleced keyframes."; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= actkeys_keytype_exec; + ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* id-props */ + RNA_def_enum(ot->srna, "type", beztriple_keyframe_type_items, 0, "Type", ""); +} + /* ************************************************************************** */ /* TRANSFORM STUFF */ diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index e2a725164c9..f18d31915f9 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -168,7 +168,7 @@ static void act_edit_transformmenu(bContext *C, uiLayout *layout, void *arg_unus static void act_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "ACT_OT_snap", "type", ACTKEYS_SNAP_CFRA); uiItemEnumO(layout, NULL, 0, "ACT_OT_snap", "type", ACTKEYS_SNAP_NEAREST_FRAME); uiItemEnumO(layout, NULL, 0, "ACT_OT_snap", "type", ACTKEYS_SNAP_NEAREST_SECOND); @@ -177,16 +177,23 @@ static void act_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused) static void act_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_CFRA); uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_YAXIS); uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_XAXIS); uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_MARKER); } +static void act_edit_keytypesmenu(bContext *C, uiLayout *layout, void *arg_unused) +{ + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_KEYFRAME); + uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_BREAKDOWN); +} + static void act_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "ACT_OT_handle_type", "type", HD_FREE); uiItemEnumO(layout, NULL, 0, "ACT_OT_handle_type", "type", HD_AUTO); uiItemEnumO(layout, NULL, 0, "ACT_OT_handle_type", "type", HD_VECT); @@ -196,7 +203,7 @@ static void act_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused static void act_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "ACT_OT_interpolation_type", "type", BEZT_IPO_CONST); uiItemEnumO(layout, NULL, 0, "ACT_OT_interpolation_type", "type", BEZT_IPO_LIN); uiItemEnumO(layout, NULL, 0, "ACT_OT_interpolation_type", "type", BEZT_IPO_BEZ); @@ -204,7 +211,7 @@ static void act_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused) static void act_edit_expomenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "ACT_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_CONSTANT); uiItemEnumO(layout, NULL, 0, "ACT_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_LINEAR); } @@ -226,6 +233,7 @@ static void act_editmenu(bContext *C, uiLayout *layout, void *arg_unused) uiItemS(layout); + uiItemMenuF(layout, "Keyframe Type", 0, act_edit_keytypesmenu, NULL); uiItemMenuF(layout, "Handle Type", 0, act_edit_handlesmenu, NULL); uiItemMenuF(layout, "Interpolation Mode", 0, act_edit_ipomenu, NULL); uiItemMenuF(layout, "Extrapolation Mode", 0, act_edit_expomenu, NULL); diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index 1aeeeff0c80..e5f0ab8994e 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -89,6 +89,7 @@ void ACT_OT_delete(struct wmOperatorType *ot); void ACT_OT_clean(struct wmOperatorType *ot); void ACT_OT_sample(struct wmOperatorType *ot); +void ACT_OT_keyframe_type(struct wmOperatorType *ot); void ACT_OT_handle_type(struct wmOperatorType *ot); void ACT_OT_interpolation_type(struct wmOperatorType *ot); void ACT_OT_extrapolation_type(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index f18b6197eb3..42b033040b1 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -75,6 +75,7 @@ void action_operatortypes(void) WM_operatortype_append(ACT_OT_handle_type); WM_operatortype_append(ACT_OT_interpolation_type); WM_operatortype_append(ACT_OT_extrapolation_type); + WM_operatortype_append(ACT_OT_keyframe_type); WM_operatortype_append(ACT_OT_sample); WM_operatortype_append(ACT_OT_clean); WM_operatortype_append(ACT_OT_delete); @@ -133,6 +134,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap) WM_keymap_add_item(keymap, "ACT_OT_handle_type", HKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ACT_OT_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "ACT_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "ACT_OT_keyframe_type", RKEY, KM_PRESS, 0, 0); /* destructive */ WM_keymap_add_item(keymap, "ACT_OT_clean", OKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index 06d48fe20f3..dd304cd8cf3 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -160,7 +160,7 @@ static void graph_edit_transformmenu(bContext *C, uiLayout *layout, void *arg_un static void graph_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_CFRA); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_FRAME); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_SECOND); @@ -169,7 +169,7 @@ static void graph_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused) static void graph_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_CFRA); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_YAXIS); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_XAXIS); @@ -178,7 +178,7 @@ static void graph_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unuse static void graph_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_FREE); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_AUTO); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_VECT); @@ -188,7 +188,7 @@ static void graph_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unus static void graph_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_CONST); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_LIN); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_BEZ); @@ -196,7 +196,7 @@ static void graph_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused) static void graph_edit_expomenu(bContext *C, uiLayout *layout, void *arg_unused) { - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx? + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_CONSTANT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_LINEAR); } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index facea34510e..bbf1358a37c 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -211,7 +211,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa) /* Active Action Properties ------------------------------------- */ /* action */ row= uiLayoutRow(layout, 1); - uiTemplateID(row, C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators + uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators /* extrapolation */ row= uiLayoutRow(layout, 1); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index f30954292b4..b21f37ab678 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -167,7 +167,7 @@ static void nla_action_draw_keyframes (AnimData *adt, bAction *act, View2D *v2d, * - size is 3.0f which is smaller than the editable keyframes, so that there is a distinction */ for (ak= keys.first; ak; ak= ak->next) - draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, KEYFRAME_SHAPE_FRAME); + draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, ak->key_type, KEYFRAME_SHAPE_FRAME); /* free icons */ BLI_dlrbTree_free(&keys); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index b0f089d670f..3bac2c73bcb 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -75,25 +75,28 @@ typedef struct BevPoint { short f1, f2; } BevPoint; -/* Keyframes on IPO curves and Points on Bezier Curves/Paths are generally BezTriples */ +/* Keyframes on F-Curves (allows code reuse of Bezier eval code) and + * Points on Bezier Curves/Paths are generally BezTriples + */ /* note: alfa location in struct is abused by Key system */ /* vec in BezTriple looks like this: vec[0][0]=x location of handle 1 vec[0][1]=y location of handle 1 - vec[0][2]=z location of handle 1 (not used for IpoCurve Points(2d)) + vec[0][2]=z location of handle 1 (not used for FCurve Points(2d)) vec[1][0]=x location of control point vec[1][1]=y location of control point vec[1][2]=z location of control point vec[2][0]=x location of handle 2 vec[2][1]=y location of handle 2 - vec[2][2]=z location of handle 2 (not used for IpoCurve Points(2d)) + vec[2][2]=z location of handle 2 (not used for FCurve Points(2d)) */ typedef struct BezTriple { float vec[3][3]; float alfa, weight, radius; /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */ short ipo; /* ipo: interpolation mode for segment from this BezTriple to the next */ char h1, h2; /* h1, h2: the handle type of the two handles */ - char f1, f2, f3, hide; /* f1, f2, f3: used for selection status, hide: used to indicate whether BezTriple is hidden */ + char f1, f2, f3; /* f1, f2, f3: used for selection status */ + char hide; /* hide: used to indicate whether BezTriple is hidden (3D), type of keyframe (eBezTriple_KeyframeTypes) */ } BezTriple; /* note; alfa location in struct is abused by Key system */ @@ -279,6 +282,12 @@ typedef enum eBezTriple_Interpolation { BEZT_IPO_BEZ, /* 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_BREAKDOWN, /* 'breakdown' keyframe */ +} eBezTriple_KeyframeType; + /* *************** CHARINFO **************** */ /* flag */ diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 3bba474677f..a59fc8716ec 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -38,6 +38,7 @@ extern EnumPropertyItem modifier_type_items[]; extern EnumPropertyItem constraint_type_items[]; extern EnumPropertyItem boidrule_type_items[]; +extern EnumPropertyItem beztriple_keyframe_type_items[]; extern EnumPropertyItem beztriple_handle_type_items[]; extern EnumPropertyItem beztriple_interpolation_mode_items[]; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index bb094eef962..503ca031fb6 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -48,6 +48,11 @@ EnumPropertyItem beztriple_interpolation_mode_items[] = { {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""}, {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""}, {0, NULL, 0, NULL, NULL}}; + +EnumPropertyItem beztriple_keyframe_type_items[] = { + {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""}, + {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""}, + {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME @@ -155,7 +160,10 @@ static void rna_Curve_update_data(bContext *C, PointerRNA *ptr) Scene *scene= CTX_data_scene(C); Curve *cu= ptr->id.data; Object *ob; - + + if (cu == NULL) + return; + for(ob=bmain->object.first; ob; ob= ob->id.next) { if(ob->data == cu) { /* XXX this will loop over all objects again (slow) */ @@ -259,10 +267,15 @@ static void rna_def_beztriple(BlenderRNA *brna) prop= RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "ipo"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_enum_items(prop, beztriple_interpolation_mode_items); RNA_def_property_ui_text(prop, "Interpolation", "(For F-Curves Only) Interpolation to use for segment of curve starting from current BezTriple."); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead... + + prop= RNA_def_property(srna, "keyframe_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "hide"); + RNA_def_property_enum_items(prop, beztriple_keyframe_type_items); + RNA_def_property_ui_text(prop, "Keyframe Type", "(For F-Curves only) The type of keyframe this control point defines."); + //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead... /* Vector values */ prop= RNA_def_property(srna, "handle1", PROP_FLOAT, PROP_TRANSLATION); -- cgit v1.2.3 From d577e0d986651ee28c6c1031df7db966430f218f Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 04:05:29 +0000 Subject: * clean commented-out parts --- SConstruct | 8 -------- 1 file changed, 8 deletions(-) diff --git a/SConstruct b/SConstruct index ec302d90fce..a66587695f3 100644 --- a/SConstruct +++ b/SConstruct @@ -207,7 +207,6 @@ if env['WITH_BF_OPENMP'] == 1: env.Append(CCFLAGS=['-fopenmp']) env.Append(CPPFLAGS=['-fopenmp']) env.Append(CXXFLAGS=['-fopenmp']) - # env.Append(LINKFLAGS=['-fprofile-generate']) #check for additional debug libnames @@ -301,7 +300,6 @@ if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-min env['PLATFORM_LINKFLAGS'].append('/ENTRY:main') # lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir -#B.root_build_dir = B.arguments.get('BF_BUILDDIR', '..'+os.sep+'build'+os.sep+platform+os.sep) B.root_build_dir = env['BF_BUILDDIR'] B.doc_build_dir = env['BF_DOCDIR'] if not B.root_build_dir[-1]==os.sep: @@ -403,7 +401,6 @@ thestatlibs, thelibincs = B.setup_staticlibs(env) thesyslibs = B.setup_syslibs(env) if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: - #env.BlenderProg(B.root_build_dir, "blender", dobj , [], mainlist + thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') @@ -579,11 +576,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc'): '${LCGDIR}/ffmpeg/lib/avformat-52.dll', '${LCGDIR}/ffmpeg/lib/avdevice-52.dll', '${LCGDIR}/ffmpeg/lib/avutil-50.dll', -# '${LCGDIR}/ffmpeg/lib/libfaad-2.dll', -# '${LCGDIR}/ffmpeg/lib/libfaac-0.dll', -# '${LCGDIR}/ffmpeg/lib/libmp3lame-0.dll', -# '${LCGDIR}/ffmpeg/lib/libx264-67.dll', -# '${LCGDIR}/ffmpeg/lib/xvidcore.dll', '${LCGDIR}/ffmpeg/lib/swscale-0.dll'] if env['WITH_BF_JACK']: dllsources += ['${LCGDIR}/jack/lib/libjack.dll'] -- cgit v1.2.3 From a819ef1bf2222b2e1132c0a3d9b6b133c8263348 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 04:27:06 +0000 Subject: 2.5 - Keyframing Bugfixes + Code Cleanups * DopeSheet + Graph Editor - 'Sample Keyframes' option now tags newly created keyframes as being breakdowns. Also moved reduced the code duplication here by moving the core code for this to the animation module. * Keyframing (Standard/Auto) - Added proper 'replace' option Keyframes can now be rekeyed non-destructively when the INSERTKEY_REPLACE flag is provided to the keyframing API functions, since this option will make sure that only the values of the handles get altered. For the Auto-Keyframing 'Replace/Edit Keys' option, this means that it truly works as it describes now, since it will now only replace the values of the keyframes on the current frame, and won't create new keyframes in the process or destroy the tangents already created for those keys. For things like the sliders in animation editors, keyframes changing the value won't destroy existing tangents. --- .../editors/animation/anim_channels_defines.c | 6 ++ .../blender/editors/animation/keyframes_general.c | 76 +++++++++++++++++- source/blender/editors/animation/keyframing.c | 90 +++++++++++++++------- source/blender/editors/animation/keyingsets.c | 3 +- source/blender/editors/include/ED_keyframes_draw.h | 2 +- source/blender/editors/include/ED_keyframes_edit.h | 1 + source/blender/editors/include/ED_keyframing.h | 5 +- source/blender/editors/interface/interface_anim.c | 2 + source/blender/editors/space_action/action_edit.c | 67 +--------------- .../blender/editors/space_action/action_header.c | 2 +- source/blender/editors/space_graph/graph_edit.c | 69 +---------------- .../editors/transform/transform_conversions.c | 52 +++++++------ 12 files changed, 186 insertions(+), 189 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index b16420a7094..e3418fa194f 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -2003,6 +2003,8 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi flag |= INSERTKEY_NEEDED; if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX; + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) + flag |= INSERTKEY_REPLACE; /* get RNA pointer, and resolve the path */ @@ -2010,6 +2012,10 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi /* try to resolve the path stored in the F-Curve */ if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) { + /* set the special 'replace' flag if on a keyframe */ + if (fcurve_frame_has_keyframe(fcu, cfra, 0)) + flag |= INSERTKEY_REPLACE; + /* insert a keyframe for this F-Curve */ done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag); diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index ced3c117700..f13d35c7d4a 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -357,6 +357,76 @@ void smooth_fcurve (FCurve *fcu) calchandles_fcurve(fcu); } +/* ---------------- */ + +/* little cache for values... */ +typedef struct tempFrameValCache { + float frame, val; +} tempFrameValCache; + + +/* Evaluates the curves between each selected keyframe on each frame, and keys the value */ +void sample_fcurve (FCurve *fcu) +{ + BezTriple *bezt, *start=NULL, *end=NULL; + tempFrameValCache *value_cache, *fp; + int sfra, range; + int i, n, nIndex; + + /* find selected keyframes... once pair has been found, add keyframes */ + for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { + /* check if selected, and which end this is */ + if (BEZSELECTED(bezt)) { + if (start) { + /* set end */ + end= bezt; + + /* cache values then add keyframes using these values, as adding + * keyframes while sampling will affect the outcome... + * - only start sampling+adding from index=1, so that we don't overwrite original keyframe + */ + range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) ); + sfra= (int)( floor(start->vec[1][0]) ); + + if (range) { + value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache"); + + /* sample values */ + for (n=1, fp=value_cache; nframe= (float)(sfra + n); + fp->val= evaluate_fcurve(fcu, fp->frame); + } + + /* add keyframes with these, tagging as 'breakdowns' */ + for (n=1, fp=value_cache; nframe, fp->val, 1); + BEZKEYTYPE(fcu->bezt + nIndex)= BEZT_KEYTYPE_BREAKDOWN; + } + + /* free temp cache */ + MEM_freeN(value_cache); + + /* as we added keyframes, we need to compensate so that bezt is at the right place */ + bezt = fcu->bezt + i + range - 1; + i += (range - 1); + } + + /* bezt was selected, so it now marks the start of a whole new chain to search */ + start= bezt; + end= NULL; + } + else { + /* just set start keyframe */ + start= bezt; + end= NULL; + } + } + } + + /* recalculate channel's handles? */ + calchandles_fcurve(fcu); +} + /* **************************************************** */ /* Copy/Paste Tools */ /* - The copy/paste buffer currently stores a set of temporary F-Curves containing only the keyframes @@ -529,8 +599,10 @@ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data) bezt->vec[1][0] += offset; bezt->vec[2][0] += offset; - /* insert the keyframe */ - insert_bezt_fcurve(fcu, bezt); + /* insert the keyframe + * NOTE: no special flags here for now + */ + insert_bezt_fcurve(fcu, bezt, 0); /* un-apply offset from src beztriple after copying */ bezt->vec[0][0] -= offset; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 5f444609baa..d731ec6f148 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -262,9 +262,8 @@ static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen * NOTE: any recalculate of the F-Curve that needs to be done will need to * be done by the caller. */ -int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt) +int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag) { - BezTriple *newb; int i= 0; if (fcu->bezt) { @@ -273,13 +272,34 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt) if (replace) { /* sanity check: 'i' may in rare cases exceed arraylen */ - // FIXME: do not overwrite handletype if just replacing...? - if ((i >= 0) && (i < fcu->totvert)) - *(fcu->bezt + i) = *bezt; + if ((i >= 0) && (i < fcu->totvert)) { + /* take care with the handletypes and other info if the replacement flags are set */ + if (flag & INSERTKEY_REPLACE) { + BezTriple *dst= (fcu->bezt + i); + float dy= bezt->vec[1][1] - dst->vec[1][1]; + + /* just apply delta value change to the handle values */ + dst->vec[0][1] += dy; + dst->vec[1][1] += dy; + dst->vec[2][1] += dy; + + // TODO: perform some other operations? + } + else { + /* just brutally replace the values */ + *(fcu->bezt + i) = *bezt; + } + } } - else { - /* add new */ - newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple"); + else if ((flag & INSERTKEY_REPLACE) == 0) { + /* add new - if we're not restricted to replacing keyframes only */ + BezTriple *newb; + + /* allocate a new array only if we have to */ + if ((flag & INSERTKEY_FASTR) == 0) + newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple"); + else + newb= fcu->bezt; /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */ if (i > 0) @@ -292,9 +312,11 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt) if (i < fcu->totvert) memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple)); - /* replace (+ free) old with new */ - MEM_freeN(fcu->bezt); - fcu->bezt= newb; + /* replace (+ free) old with new, only if necessary to do so */ + if ((flag & INSERTKEY_FASTR) == 0) { + MEM_freeN(fcu->bezt); + fcu->bezt= newb; + } fcu->totvert++; } @@ -313,13 +335,11 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt) return i; } -/* This function is a wrapper for insert_bezt_icu, and should be used when - * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere - * else yet. - * - * 'fast' - is only for the python API where importing BVH's would take an extreamly long time. +/* This function is a wrapper for insert_bezt_fcurve_internal(), and should be used when + * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. + * It returns the index at which the keyframe was added. */ -void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast) +int insert_vert_fcurve (FCurve *fcu, float x, float y, short flag) { BezTriple beztr; int a; @@ -337,21 +357,22 @@ void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast) beztr.h1= beztr.h2= HD_AUTO; // XXX what about when we replace an old one? /* add temp beztriple to keyframes */ - a= insert_bezt_fcurve(fcu, &beztr); + a= insert_bezt_fcurve(fcu, &beztr, flag); /* what if 'a' is a negative index? * for now, just exit to prevent any segfaults */ - if (a < 0) return; + if (a < 0) return -1; /* don't recalculate handles if fast is set * - this is a hack to make importers faster - * - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations) + * - we may calculate twice (due to autohandle needing to be calculated twice) */ - if (!fast) calchandles_fcurve(fcu); + if ((flag & INSERTKEY_FAST) == 0) + calchandles_fcurve(fcu); /* set handletype and interpolation */ - if (fcu->totvert > 2) { + if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE)==0) { BezTriple *bezt= (fcu->bezt + a); char h1, h2; @@ -370,10 +391,14 @@ void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast) /* don't recalculate handles if fast is set * - this is a hack to make importers faster - * - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations) + * - we may calculate twice (due to autohandle needing to be calculated twice) */ - if (!fast) calchandles_fcurve(fcu); + if ((flag & INSERTKEY_FAST) == 0) + calchandles_fcurve(fcu); } + + /* return the index at which the keyframe was added */ + return a; } /* -------------- 'Smarter' Keyframing Functions -------------------- */ @@ -812,7 +837,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl /* insert new keyframe at current frame */ if (insert_mode) - insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST)); + insert_vert_fcurve(fcu, cfra, curval, flag); /* delete keyframe immediately before/after newly added */ switch (insert_mode) { @@ -830,7 +855,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl } else { /* just insert keyframe */ - insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST)); + insert_vert_fcurve(fcu, cfra, curval, flag); /* return success */ return 1; @@ -1303,6 +1328,15 @@ static int insert_key_button_exec (bContext *C, wmOperator *op) float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap short success= 0; int a, index, length, all= RNA_boolean_get(op->ptr, "all"); + short flag = 0; + + /* flags for inserting keyframes */ + if (IS_AUTOKEY_FLAG(AUTOMATKEY)) + flag |= INSERTKEY_MATRIX; + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) + flag |= INSERTKEY_NEEDED; + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) + flag |= INSERTKEY_REPLACE; /* try to insert keyframe using property retrieved from UI */ memset(&ptr, 0, sizeof(PointerRNA)); @@ -1322,14 +1356,14 @@ static int insert_key_button_exec (bContext *C, wmOperator *op) length= 1; for (a=0; afcurves, RNA_property_identifier(prop), 0); + FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), flag); success+= insert_keyframe_direct(ptr, prop, fcu, cfra, 0); } diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 21f969467aa..f81f57d526a 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -879,6 +879,7 @@ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks */ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra) { + Scene *scene= CTX_data_scene(C); KS_Path *ksp; int kflag=0, success= 0; char *groupname= NULL; @@ -891,7 +892,7 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet * /* suppliment with info from the context */ if (IS_AUTOKEY_FLAG(AUTOMATKEY)) kflag |= INSERTKEY_MATRIX; if (IS_AUTOKEY_FLAG(INSERTNEEDED)) kflag |= INSERTKEY_NEEDED; - // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE; + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) kflag |= INSERTKEY_REPLACE; } else if (mode == MODIFYKEY_MODE_DELETE) kflag= 0; diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 259104f7263..0969398f1e2 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -99,7 +99,7 @@ typedef enum eKeyframeShapeDrawOpts { } eKeyframeShapeDrawOpts; /* draw simple diamond-shape keyframe (with OpenGL) */ -void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode); +void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, short key_type, short mode); /* ******************************* Methods ****************************** */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 390729eaec4..b2bf05ea5ea 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -147,6 +147,7 @@ void duplicate_fcurve_keys(struct FCurve *fcu); void clean_fcurve(struct FCurve *fcu, float thresh); void smooth_fcurve(struct FCurve *fcu); +void sample_fcurve(struct FCurve *fcu); /* ----------- */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 4bc24a0adeb..c492143751c 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -65,13 +65,14 @@ struct FCurve *verify_fcurve(struct bAction *act, const char group[], const char * Use this when validation of necessary animation data isn't necessary as it already * exists, and there is a beztriple that can be directly copied into the array. */ -int insert_bezt_fcurve(struct FCurve *fcu, struct BezTriple *bezt); +int insert_bezt_fcurve(struct FCurve *fcu, struct BezTriple *bezt, short flag); /* Main Keyframing API call: * Use this when validation of necessary animation data isn't necessary as it * already exists. It will insert a keyframe using the current value being keyframed. + * Returns the index at which a keyframe was added (or -1 if failed) */ -void insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag); +int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag); /* -------- */ diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 784d820ea52..d7904a19bfe 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -152,6 +152,8 @@ void ui_but_anim_autokey(uiBut *but, Scene *scene, float cfra) flag |= INSERTKEY_NEEDED; if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX; + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) + flag |= INSERTKEY_REPLACE; fcu->flag &= ~FCURVE_SELECTED; insert_keyframe(id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag); diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index b087736a368..89633d0cdfe 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -397,7 +397,7 @@ static void insert_action_keys(bAnimContext *ac, short mode) /* init keyframing flag */ if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX; if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; - // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE; + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE; /* insert keyframes */ for (ale= anim_data.first; ale; ale= ale->next) { @@ -679,11 +679,6 @@ void ACT_OT_clean (wmOperatorType *ot) /* ******************** Sample Keyframes Operator *********************** */ -/* little cache for values... */ -typedef struct tempFrameValCache { - float frame, val; -} tempFrameValCache; - /* Evaluates the curves between each selected keyframe on each frame, and keys the value */ static void sample_action_keys (bAnimContext *ac) { @@ -696,64 +691,8 @@ static void sample_action_keys (bAnimContext *ac) ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through filtered data and add keys between selected keyframes on every frame */ - for (ale= anim_data.first; ale; ale= ale->next) { - FCurve *fcu= (FCurve *)ale->key_data; - BezTriple *bezt, *start=NULL, *end=NULL; - tempFrameValCache *value_cache, *fp; - int sfra, range; - int i, n; - - /* find selected keyframes... once pair has been found, add keyframes */ - for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { - /* check if selected, and which end this is */ - if (BEZSELECTED(bezt)) { - if (start) { - /* set end */ - end= bezt; - - /* cache values then add keyframes using these values, as adding - * keyframes while sampling will affect the outcome... - */ - range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) ); - sfra= (int)( floor(start->vec[1][0]) ); - - if (range) { - value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache"); - - /* sample values */ - for (n=0, fp=value_cache; nframe= (float)(sfra + n); - fp->val= evaluate_fcurve(fcu, fp->frame); - } - - /* add keyframes with these */ - for (n=0, fp=value_cache; nframe, fp->val, 1); - } - - /* free temp cache */ - MEM_freeN(value_cache); - - /* as we added keyframes, we need to compensate so that bezt is at the right place */ - bezt = fcu->bezt + i + range - 1; - i += (range - 1); - } - - /* bezt was selected, so it now marks the start of a whole new chain to search */ - start= bezt; - end= NULL; - } - else { - /* just set start keyframe */ - start= bezt; - end= NULL; - } - } - } - - /* recalculate channel's handles? */ - calchandles_fcurve(fcu); - } + for (ale= anim_data.first; ale; ale= ale->next) + sample_fcurve((FCurve *)ale->key_data); /* admin and redraws */ BLI_freelistN(&anim_data); diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index f18d31915f9..8674f481a18 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -431,7 +431,7 @@ void action_header_buttons(const bContext *C, ARegion *ar) "Auto-snapping mode for keyframes when transforming"); } - xco += (70 + 8); + xco += (90 + 8); } /* COPY PASTE */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 37389b32b3a..d718ef28e99 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -430,7 +430,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode) /* init keyframing flag */ if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX; if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; - // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE; + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE; /* insert keyframes */ for (ale= anim_data.first; ale; ale= ale->next) { @@ -989,13 +989,6 @@ void GRAPH_OT_bake (wmOperatorType *ot) * of selected keyframes. It is useful for creating keyframes for tweaking overlap. */ -// XXX some of the common parts (with DopeSheet) should be unified in animation module... - -/* little cache for values... */ -typedef struct tempFrameValCache { - float frame, val; -} tempFrameValCache; - /* Evaluates the curves between each selected keyframe on each frame, and keys the value */ static void sample_graph_keys (bAnimContext *ac) { @@ -1008,64 +1001,8 @@ static void sample_graph_keys (bAnimContext *ac) ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through filtered data and add keys between selected keyframes on every frame */ - for (ale= anim_data.first; ale; ale= ale->next) { - FCurve *fcu= (FCurve *)ale->key_data; - BezTriple *bezt, *start=NULL, *end=NULL; - tempFrameValCache *value_cache, *fp; - int sfra, range; - int i, n; - - /* find selected keyframes... once pair has been found, add keyframes */ - for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { - /* check if selected, and which end this is */ - if (BEZSELECTED(bezt)) { - if (start) { - /* set end */ - end= bezt; - - /* cache values then add keyframes using these values, as adding - * keyframes while sampling will affect the outcome... - */ - range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) ); - sfra= (int)( floor(start->vec[1][0]) ); - - if (range) { - value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache"); - - /* sample values */ - for (n=0, fp=value_cache; nframe= (float)(sfra + n); - fp->val= evaluate_fcurve(fcu, fp->frame); - } - - /* add keyframes with these */ - for (n=0, fp=value_cache; nframe, fp->val, 1); - } - - /* free temp cache */ - MEM_freeN(value_cache); - - /* as we added keyframes, we need to compensate so that bezt is at the right place */ - bezt = fcu->bezt + i + range - 1; - i += (range - 1); - } - - /* bezt was selected, so it now marks the start of a whole new chain to search */ - start= bezt; - end= NULL; - } - else { - /* just set start keyframe */ - start= bezt; - end= NULL; - } - } - } - - /* recalculate channel's handles? */ - calchandles_fcurve(fcu); - } + for (ale= anim_data.first; ale; ale= ale->next) + sample_fcurve((FCurve *)ale->key_data); /* admin and redraws */ BLI_freelistN(&anim_data); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e0dfd90a3d1..302d9b675a0 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1748,7 +1748,7 @@ void flushTransParticles(TransInfo *t) Object *ob = OBACT; PTCacheEdit *edit = PE_get_current(scene, ob); ParticleSystem *psys = edit->psys; - ParticleSystemModifierData *psmd; + ParticleSystemModifierData *psmd = NULL; PTCacheEditPoint *point; PTCacheEditKey *key; TransData *td; @@ -4348,12 +4348,14 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) AnimData *adt= ob->adt; float cfra= (float)CFRA; // xxx this will do for now short flag = 0; - + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX; - + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) + flag |= INSERTKEY_REPLACE; + if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { /* only key on available channels */ if (adt && adt->action) { @@ -4365,7 +4367,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) } else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) { short doLoc=0, doRot=0, doScale=0; - + /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */ if (tmode == TFM_TRANSLATION) { doLoc = 1; @@ -4377,7 +4379,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) } else if (v3d->around == V3D_CURSOR) doLoc = 1; - + if ((v3d->flag & V3D_ALIGN)==0) doRot = 1; } @@ -4388,11 +4390,11 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) } else if (v3d->around == V3D_CURSOR) doLoc = 1; - + if ((v3d->flag & V3D_ALIGN)==0) doScale = 1; } - + // TODO: the group names here are temporary... // TODO: should this be made to use the builtin KeyingSets instead? if (doLoc) { @@ -4417,16 +4419,16 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag); - + insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag); - + insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag); } - + // XXX todo... find a way to send notifiers from here... } } @@ -4450,7 +4452,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, float cfra= (float)CFRA; short flag= 0; char buf[512]; - + /* flag is initialised 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 @@ -4460,12 +4462,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, flag |= INSERTKEY_MATRIX; if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; - + if (IS_AUTOKEY_MODE(scene, EDITKEYS)) + flag |= INSERTKEY_REPLACE; + for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) { if (pchan->bone->flag & BONE_TRANSFORM) { /* clear any 'unkeyed' flag it may have */ pchan->bone->flag &= ~BONE_UNKEYED; - + /* only insert into available channels? */ if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { if (act) { @@ -4476,7 +4480,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, /* only insert keyframe if needed? */ else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) { short doLoc=0, doRot=0, doScale=0; - + /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */ if (tmode == TFM_TRANSLATION) { if (targetless_ik) @@ -4487,18 +4491,18 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, else if (tmode == TFM_ROTATION) { if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE)) doLoc = 1; - + if ((v3d->flag & V3D_ALIGN)==0) doRot = 1; } else if (tmode == TFM_RESIZE) { if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE)) doLoc = 1; - + if ((v3d->flag & V3D_ALIGN)==0) doScale = 1; } - + if (doLoc) { sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); @@ -4533,7 +4537,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - + if (pchan->rotmode == PCHAN_ROT_QUAT) { sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); @@ -4547,7 +4551,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); } - + sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); @@ -4555,14 +4559,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, } } } - + // XXX todo... figure out way to get appropriate notifiers sent - + /* do the bone paths */ -#if 0 // TRANSFORM_FIX_ME +#if 0 // XXX TRANSFORM FIX ME if (arm->pathflag & ARM_PATH_ACFRA) { - pose_clear_paths(ob); - pose_recalculate_paths(ob); + //pose_clear_paths(ob); // XXX for now, don't need to clear + ED_pose_recalculate_paths(C, scene, ob); } #endif } -- cgit v1.2.3 From 6caff6b390b257f70abe3949463797898b8bd2fd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Sep 2009 04:29:54 +0000 Subject: - rna documentation layout now matches blenders internal layout, autogenerate packages for nested modules. bpy.data, bpy.ops.object etc. - added basic docs for bpy.props - omit panel, menu and operator classes (took up too much space and not useful) - exec cant be used as an operator suffix eg- CONSOLE_OT_exec --> CONSOLE_OT_execute (same for file) - fixed some crashes when generating docs Updated docs here http://www.graphicall.org/ftp/ideasman42/html/ --- release/ui/space_console.py | 2 +- source/blender/editors/object/object_modifier.c | 4 +- source/blender/editors/screen/screen_ops.c | 2 +- .../blender/editors/space_console/console_report.c | 2 +- .../blender/editors/space_console/space_console.c | 4 +- source/blender/editors/space_file/file_intern.h | 2 +- source/blender/editors/space_file/file_ops.c | 4 +- source/blender/editors/space_file/space_file.c | 2 +- source/blender/makesrna/intern/rna_sculpt_paint.c | 17 +- source/blender/python/epy_doc_gen.py | 212 ++++++++++++++++++--- source/blender/python/intern/bpy_operator_wrap.c | 4 +- 11 files changed, 203 insertions(+), 52 deletions(-) diff --git a/release/ui/space_console.py b/release/ui/space_console.py index f1038b5616a..dbf202f924c 100644 --- a/release/ui/space_console.py +++ b/release/ui/space_console.py @@ -110,7 +110,7 @@ class CONSOLE_OT_exec(bpy.types.Operator): ''' Operator documentatuon text, will be used for the operator tooltip and python docs. ''' - __idname__ = "console.exec" + __idname__ = "console.execute" __label__ = "Console Execute" __register__ = False diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index f9e2ac2f4de..96e485e5462 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -434,10 +434,8 @@ static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *f Object *ob; int totitem= 0, a; - if(!C) /* needed for docs */ + if(!C || !(ob= CTX_data_active_object(C))) /* needed for docs */ return modifier_type_items; - - ob= CTX_data_active_object(C); for(a=0; modifier_type_items[a].identifier; a++) { md_item= &modifier_type_items[a]; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 799bb0741f3..cb874ec1447 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3336,7 +3336,7 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_verify_item(keymap, "SCRIPT_OT_python_run_ui_scripts", F8KEY, KM_PRESS, 0, 0); /* files */ - WM_keymap_add_item(keymap, "FILE_OT_exec", RETKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "FILE_OT_execute", RETKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_cancel", ESCKEY, KM_PRESS, 0, 0); /* undo */ diff --git a/source/blender/editors/space_console/console_report.c b/source/blender/editors/space_console/console_report.c index 08d003f0706..b6920d148fd 100644 --- a/source/blender/editors/space_console/console_report.c +++ b/source/blender/editors/space_console/console_report.c @@ -97,7 +97,7 @@ static int report_replay_exec(bContext *C, wmOperator *op) for(report=reports->list.last; report; report=report->prev) { if((report->type & report_mask) && (report->type & RPT_OPERATOR_ALL) && (report->flag & SELECT)) { console_history_add_str(C, report->message, 0); - WM_operator_name_call(C, "CONSOLE_OT_exec", WM_OP_EXEC_DEFAULT, NULL); + WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL); ED_area_tag_redraw(CTX_wm_area(C)); } diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index a763e7ce153..48890d6cac2 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -278,8 +278,8 @@ void console_keymap(struct wmWindowManager *wm) RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR); #ifndef DISABLE_PYTHON - WM_keymap_add_item(keymap, "CONSOLE_OT_exec", RETKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */ - WM_keymap_add_item(keymap, "CONSOLE_OT_exec", PADENTER, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_execute", RETKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */ + WM_keymap_add_item(keymap, "CONSOLE_OT_execute", PADENTER, KM_PRESS, 0, 0); //WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", TABKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */ WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0); /* python operator - space_text.py */ diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 9f1e4ad0e25..a99594e9575 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -59,7 +59,7 @@ void FILE_OT_add_bookmark(struct wmOperatorType *ot); void FILE_OT_delete_bookmark(struct wmOperatorType *ot); void FILE_OT_hidedot(struct wmOperatorType *ot); void FILE_OT_loadimages(struct wmOperatorType *ot); -void FILE_OT_exec(struct wmOperatorType *ot); +void FILE_OT_execute(struct wmOperatorType *ot); void FILE_OT_cancel(struct wmOperatorType *ot); void FILE_OT_parent(struct wmOperatorType *ot); void FILE_OT_directory_new(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 9c73956d375..a06c1663d8e 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -566,11 +566,11 @@ int file_exec(bContext *C, wmOperator *unused) return OPERATOR_FINISHED; } -void FILE_OT_exec(struct wmOperatorType *ot) +void FILE_OT_execute(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Execute File Window"; - ot->idname= "FILE_OT_exec"; + ot->idname= "FILE_OT_execute"; /* api callbacks */ ot->exec= file_exec; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 22ad03f3523..793f7cf8815 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -330,7 +330,7 @@ void file_operatortypes(void) WM_operatortype_append(FILE_OT_select_bookmark); WM_operatortype_append(FILE_OT_loadimages); WM_operatortype_append(FILE_OT_highlight); - WM_operatortype_append(FILE_OT_exec); + WM_operatortype_append(FILE_OT_execute); WM_operatortype_append(FILE_OT_cancel); WM_operatortype_append(FILE_OT_parent); WM_operatortype_append(FILE_OT_previous); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index fabe0b647ea..b00119efaf6 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -122,9 +122,6 @@ static void rna_ParticleEdit_update(bContext *C, PointerRNA *ptr) static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *ptr, int *free) { - Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit; - if(C==NULL) { EnumPropertyItem *item= NULL; int totitem= 0; @@ -137,13 +134,15 @@ static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *pt return item; } + else { + Scene *scene= CTX_data_scene(C); + PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C)); + + if(edit && edit->psys) + return particle_edit_hair_brush_items; - edit = PE_get_current(scene, CTX_data_active_object(C)); - - if(edit && edit->psys) - return particle_edit_hair_brush_items; - - return particle_edit_cache_brush_items; + return particle_edit_cache_brush_items; + } } static int rna_ParticleEdit_editable_get(PointerRNA *ptr) diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py index 6a515648340..c2ef6bbc0d0 100644 --- a/source/blender/python/epy_doc_gen.py +++ b/source/blender/python/epy_doc_gen.py @@ -37,6 +37,94 @@ Generate html docs by running... # if you dont have graphvis installed ommit the --graph arg. +# GLOBALS['BASEDIR'] = './source/blender/python/doc' + +import os + +SUBMODULES = {} +INIT_SUBMODULES = {} # store initialized files + +INIT_SUBMODULES_IMPORTS = {} # dont import the same module twice + +def append_package(package_path, mod_name): + + init_path = os.path.join(os.path.dirname(package_path), "__init__.py") + + # avoid double ups + if mod_name: + imports = INIT_SUBMODULES_IMPORTS.setdefault(init_path, []) + if mod_name in imports: + return + imports.append(mod_name) + + try: + os.makedirs(os.path.dirname(init_path)) # make the dirs if they are not there + except: + pass + + # Open the new file for the first time, otherwise keep it open. + f = INIT_SUBMODULES.get(init_path) + if f == None: + f = INIT_SUBMODULES[init_path] = open(init_path, 'w') + + if mod_name: + f.write("import %s\n" % mod_name) + + return f + +def append_package_recursive(package_path, BASEPATH): + ''' + assume the last item of package_path will be a file (not a dir thats created) + ''' + + package_path = os.path.splitext(package_path)[0] # incase of .py + + try: + os.makedirs(os.path.join(BASEPATH, os.path.dirname(package_path))) # make the dirs if they are not there + except: + pass + + new_path = BASEPATH + + for mod_name in package_path.split(os.sep): + init_path = os.path.join(new_path, "__init__.py") + new_path = os.path.join(new_path, mod_name) + append_package(init_path, mod_name) + + +def open_submodule(subpath, BASEPATH): + ''' + This is a utility function that lets us quickly add submodules + ''' + + # create all the package paths leading up to this module + append_package_recursive(subpath, BASEPATH) + + module_name = os.path.basename( os.path.splitext(subpath)[0] ) + mod_path = os.path.join(BASEPATH, subpath) + + # Open the new file for the first time, otherwise keep it open. + f = SUBMODULES.get(mod_path) + if f == None: + f = SUBMODULES[mod_path] = open(mod_path, 'w') + + f = open(mod_path, 'w') + return f + +def close_all(): + for files in (INIT_SUBMODULES.values(), SUBMODULES.values()): + for f in files: + if f.name.endswith('.py'): + f_name = f.name + f.close() + + f = open(f_name, 'a') + f.write("\ndel __package__\n") # annoying, no need do show this + + + f.close() + + def range_str(val): if val < -10000000: return '-inf' if val > 10000000: return 'inf' @@ -59,6 +147,19 @@ def full_rna_struct_path(rna_struct): else: return rna_struct.identifier +def rna_id_ignore(rna_id): + if rna_id == "rna_type": + return True + + if "_OT_" in rna_id: + return True + if "_MT_" in rna_id: + return True + if "_PT_" in rna_id: + return True + + return False + def write_func(rna, ident, out, func_type): # Keyword attributes kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'" @@ -68,7 +169,7 @@ def write_func(rna, ident, out, func_type): # Operators and functions work differently if func_type=='OPERATOR': - rna_func_name = rna_struct.identifier + rna_func_name = rna_struct.identifier.split("_OT_")[-1] rna_func_desc = rna_struct.description.strip() items = rna_struct.properties.items() else: @@ -78,7 +179,7 @@ def write_func(rna, ident, out, func_type): for rna_prop_identifier, rna_prop in items: - if rna_prop_identifier=='rna_type': + if rna_id_ignore(rna_prop_identifier): continue # clear vars @@ -196,7 +297,7 @@ def write_func(rna, ident, out, func_type): -def rna2epy(target_path): +def rna2epy(BASEPATH): # Use for faster lookups # use rna_struct.identifier as the key for each dict @@ -255,7 +356,7 @@ def rna2epy(target_path): for rna_prop_identifier, rna_prop in rna_struct.properties.items(): if rna_prop_identifier=='RNA': continue - if rna_prop_identifier=='rna_type': continue + if rna_id_ignore(rna_prop_identifier): continue if rna_prop_identifier in rna_base_prop_keys: continue # does this prop exist in our parent class, if so skip rna_desc = rna_prop.description.strip() @@ -320,7 +421,10 @@ def rna2epy(target_path): for child in rna_children_dict[identifier]: write_struct(child, ident + '\t') - out = open(target_path, 'w') + + + # out = open(target_path, 'w') + out = open_submodule("types.py", BASEPATH) # bpy.types def base_id(rna_struct): try: return rna_struct.base.identifier @@ -343,21 +447,23 @@ def rna2epy(target_path): #if not rna_type_name.startswith('__'): identifier = rna_struct.identifier - structs.append( (base_id(rna_struct), identifier, rna_struct) ) - - # Simple lookup - rna_struct_dict[identifier] = rna_struct - - # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings' - rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct) - - # Store a list of functions, remove inherited later - rna_functions_dict[identifier]= list(rna_struct.functions) - - # fill in these later - rna_children_dict[identifier]= [] - rna_references_dict[identifier]= [] + if not rna_id_ignore(identifier): + structs.append( (base_id(rna_struct), identifier, rna_struct) ) + + # Simple lookup + rna_struct_dict[identifier] = rna_struct + + # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings' + rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct) + + # Store a list of functions, remove inherited later + rna_functions_dict[identifier]= list(rna_struct.functions) + + + # fill in these later + rna_children_dict[identifier]= [] + rna_references_dict[identifier]= [] else: @@ -417,7 +523,7 @@ def rna2epy(target_path): for rna_prop_identifier, rna_prop in rna_struct.properties.items(): if rna_prop_identifier=='RNA': continue - if rna_prop_identifier=='rna_type': continue + if rna_id_ignore(rna_prop_identifier): continue if rna_prop_identifier in rna_base_prop_keys: continue try: rna_prop_ptr = rna_prop.fixed_type @@ -431,7 +537,7 @@ def rna2epy(target_path): for rna_prop_identifier, rna_prop in rna_func.parameters.items(): if rna_prop_identifier=='RNA': continue - if rna_prop_identifier=='rna_type': continue + if rna_id_ignore(rna_prop_identifier): continue if rna_prop_identifier in rna_base_func_keys: continue @@ -476,6 +582,7 @@ def rna2epy(target_path): # # We could also just run.... # os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v') + target_path = os.path.join(BASEPATH, "dump.py") # XXX - used for other funcs # Write graphviz out= open(target_path.replace('.py', '.dot'), 'w') @@ -546,8 +653,8 @@ def rna2epy(target_path): out.write('%s\n' % w) -def op2epy(target_path): - out = open(target_path, 'w') +def op2epy(BASEPATH): + # out = open(target_path, 'w') op_mods = dir(bpy.ops) op_mods.remove('add') @@ -556,26 +663,73 @@ def op2epy(target_path): for op_mod_name in sorted(op_mods): if op_mod_name.startswith('__'): continue + + # open the submodule + mod_path = os.path.join("ops", op_mod_name + ".py") + out = open_submodule(mod_path, BASEPATH) + op_mod = getattr(bpy.ops, op_mod_name) - operators = dir(op_mod) for op in sorted(operators): # rna = getattr(bpy.types, op).__rna__ rna = getattr(op_mod, op).get_rna() write_func(rna, '', out, 'OPERATOR') + + out.write('\n') + out.close() + +def misc2epy(BASEPATH): + ''' + Hard coded modules, try to avoid adding stuff here + ''' - out.write('\n') - out.close() + f = append_package(os.path.join(BASEPATH, ""), ""); # add a slash on the end of the base path + f.write(''' +""" +@type data: L{bpy.types.Main} +@var data: blender data is accessed from here +""" +''') + + f = open_submodule("props.py", BASEPATH) + f.write(''' +MAX_INT= 2**31 +MAX_FLOAT= 1e+37 +def BoolProperty(attr, name="", description="", default=False): + """ + return a new bool property + """ +def IntProperty(attr, name="", description="", min=-MAX_INT, max=MAX_INT, soft_min=-MAX_INT, soft_max=MAX_INT, default=0): + """ + return a new int property + """ +def FloatProperty(attr, name="", description="", min=-MAX_FLOAT, max=MAX_FLOAT, soft_min=-MAX_FLOAT, soft_max=MAX_FLOAT, default=0.0): + """ + return a new float property + """ +def StringProperty(attr, name="", description="", maxlen=0, default=""): + """ + return a new string property + """ +def EnumProperty(attr, items, name="", description="", default=""): + """ + return a new enum property + """ +''') + if __name__ == '__main__': if 'bpy' not in dir(): print("\nError, this script must run from inside blender2.5") print(script_help_msg) - else: - rna2epy('source/blender/python/doc/rna.py') - op2epy('source/blender/python/doc/bpyoperator.py') + misc2epy('source/blender/python/doc/bpy') # first to write in info in some of the modules. + rna2epy('source/blender/python/doc/bpy') + op2epy('source/blender/python/doc/bpy') + + + close_all() import sys sys.exit() diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 9a74bf0aee8..0a487a8dbe8 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -228,7 +228,7 @@ static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event) return PYTHON_OT_generic(PYOP_INVOKE, C, op, event); } -static int PYTHON_OT_exec(bContext *C, wmOperator *op) +static int PYTHON_OT_execute(bContext *C, wmOperator *op) { return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL); } @@ -268,7 +268,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) if (PyObject_HasAttrString(py_class, "invoke")) ot->invoke= PYTHON_OT_invoke; if (PyObject_HasAttrString(py_class, "execute")) - ot->exec= PYTHON_OT_exec; + ot->exec= PYTHON_OT_execute; if (PyObject_HasAttrString(py_class, "poll")) ot->poll= PYTHON_OT_poll; -- cgit v1.2.3 From 62dd488ad16911620137ac655ae2f5980374c2bc Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 4 Sep 2009 06:55:01 +0000 Subject: * New and improved voxel interpolation methods, from Alfredo. Now there is (in order of speed): * Nearest neighbour (very rough quality) * Linear (medium quality) * Quadratic (good quality) * Cubic Catmull-rom (very good quality, crisp) * Cubic B-spline (very good quality, smooth) Thanks! --- source/blender/blenlib/BLI_voxel.h | 3 +- source/blender/blenlib/intern/voxel.c | 339 +++++++++--------------- source/blender/makesdna/DNA_texture_types.h | 5 +- source/blender/makesrna/intern/rna_texture.c | 8 +- source/blender/render/intern/source/voxeldata.c | 8 +- 5 files changed, 136 insertions(+), 227 deletions(-) diff --git a/source/blender/blenlib/BLI_voxel.h b/source/blender/blenlib/BLI_voxel.h index 9b815ccbf42..934bc820259 100644 --- a/source/blender/blenlib/BLI_voxel.h +++ b/source/blender/blenlib/BLI_voxel.h @@ -35,6 +35,7 @@ /* all input coordinates must be in bounding box 0.0 - 1.0 */ float voxel_sample_nearest(float *data, int *res, float *co); float voxel_sample_trilinear(float *data, int *res, float *co); -float voxel_sample_tricubic(float *data, int *res, float *co); +float voxel_sample_triquadratic(float *data, int *res, float *co); +float voxel_sample_tricubic(float *data, int *res, float *co, int bspline); #endif /* BLI_VOXEL_H */ diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c index b5b2ae793f9..7dad854af3a 100644 --- a/source/blender/blenlib/intern/voxel.c +++ b/source/blender/blenlib/intern/voxel.c @@ -57,243 +57,142 @@ float voxel_sample_nearest(float *data, int *res, float *co) return D(data, res, xi, yi, zi); } +// returns highest integer <= x as integer (slightly faster than floor()) +inline int FLOORI(float x) +{ + const int r = (int)x; + return ((x >= 0.f) || (float)r == x) ? r : (r - 1); +} -/* *** trilinear *** */ -/* input coordinates must be in bounding box 0.0 - 1.0 */ - -static inline float lerp(float t, float v1, float v2) { - return (1.f - t) * v1 + t * v2; +// clamp function, cannot use the CLAMPIS macro, it sometimes returns unwanted results apparently related to gcc optimization flag -fstrict-overflow which is enabled at -O2 +// this causes the test (x + 2) < 0 with int x == 2147483647 to return false (x being an integer, x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't) +inline int _clamp(int a, int b, int c) +{ + return (a < b) ? b : ((a > c) ? c : a); } -/* trilinear interpolation - taken partly from pbrt's implementation: http://www.pbrt.org */ float voxel_sample_trilinear(float *data, int *res, float *co) { - float voxx, voxy, voxz; - int vx, vy, vz; - float dx, dy, dz; - float d00, d10, d01, d11, d0, d1, d_final; - - if (!data) return 0.f; + if (data) { - voxx = co[0] * res[0] - 0.5f; - voxy = co[1] * res[1] - 0.5f; - voxz = co[2] * res[2] - 0.5f; + const float xf = co[0] * res[0] - 0.5f; + const float yf = co[1] * res[1] - 0.5f; + const float zf = co[2] * res[2] - 0.5f; + + const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf); - vx = (int)voxx; vy = (int)voxy; vz = (int)voxz; + const int xc[2] = {_clamp(x, 0, res[0] - 1), _clamp(x + 1, 0, res[0] - 1)}; + const int yc[2] = {res[0] * _clamp(y, 0, res[1] - 1), res[0] * _clamp(y + 1, 0, res[1] - 1)}; + const int zc[2] = {res[0] * res[1] * _clamp(z, 0, res[2] - 1), res[0] * res[1] * _clamp(z + 1, 0, res[2] - 1)}; - dx = voxx - vx; dy = voxy - vy; dz = voxz - vz; + const float dx = xf - (float)x; + const float dy = yf - (float)y; + const float dz = zf - (float)z; + + const float u[2] = {1.f - dx, dx}; + const float v[2] = {1.f - dy, dy}; + const float w[2] = {1.f - dz, dz}; - d00 = lerp(dx, D(data, res, vx, vy, vz), D(data, res, vx+1, vy, vz)); - d10 = lerp(dx, D(data, res, vx, vy+1, vz), D(data, res, vx+1, vy+1, vz)); - d01 = lerp(dx, D(data, res, vx, vy, vz+1), D(data, res, vx+1, vy, vz+1)); - d11 = lerp(dx, D(data, res, vx, vy+1, vz+1), D(data, res, vx+1, vy+1, vz+1)); - d0 = lerp(dy, d00, d10); - d1 = lerp(dy, d01, d11); - d_final = lerp(dz, d0, d1); + return w[0] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] ) ) + + w[1] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] ) ); - return d_final; -} - -/* *** tricubic *** */ - -int C[64][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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}, -{-3, 3, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 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,-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,-3, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 9,-9,-9, 9, 0, 0, 0, 0, 6, 3,-6,-3, 0, 0, 0, 0, 6,-6, 3,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 1, 0, 0, 0, 0, 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, 6, 6,-6, 0, 0, 0, 0,-3,-3, 3, 3, 0, 0, 0, 0,-4, 4,-2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-2,-1,-1, 0, 0, 0, 0, 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,-2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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,-2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{-6, 6, 6,-6, 0, 0, 0, 0,-4,-2, 4, 2, 0, 0, 0, 0,-3, 3,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1,-2,-1, 0, 0, 0, 0, 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,-4,-4, 4, 0, 0, 0, 0, 2, 2,-2,-2, 0, 0, 0, 0, 2,-2, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 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, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,-2,-1, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, -{ 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,-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,-3, 0, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-9,-9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3,-6,-3, 0, 0, 0, 0, 6,-6, 3,-3, 0, 0, 0, 0, 4, 2, 2, 1, 0, 0, 0, 0}, -{ 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, 6, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3,-3, 3, 3, 0, 0, 0, 0,-4, 4,-2, 2, 0, 0, 0, 0,-2,-2,-1,-1, 0, 0, 0, 0}, -{ 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,-2, 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, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,-2, 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, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4,-2, 4, 2, 0, 0, 0, 0,-3, 3,-3, 3, 0, 0, 0, 0,-2,-1,-2,-1, 0, 0, 0, 0}, -{ 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,-4,-4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,-2,-2, 0, 0, 0, 0, 2,-2, 2,-2, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}, -{-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 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,-3, 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,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 9,-9, 0, 0,-9, 9, 0, 0, 6, 3, 0, 0,-6,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-6, 0, 0, 3,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{-6, 6, 0, 0, 6,-6, 0, 0,-3,-3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 4, 0, 0,-2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-2, 0, 0,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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,-2, 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,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-9, 0, 0,-9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0, 0,-6,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-6, 0, 0, 3,-3, 0, 0, 4, 2, 0, 0, 2, 1, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 0, 0, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3,-3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 4, 0, 0,-2, 2, 0, 0,-2,-2, 0, 0,-1,-1, 0, 0}, -{ 9, 0,-9, 0,-9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0,-6, 0,-3, 0, 6, 0,-6, 0, 3, 0,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,-9, 0,-9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0,-6, 0,-3, 0, 6, 0,-6, 0, 3, 0,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 2, 0, 1, 0}, -{-27,27,27,-27,27,-27,-27,27,-18,-9,18, 9,18, 9,-18,-9,-18,18,-9, 9,18,-18, 9,-9,-18,18,18,-18,-9, 9, 9,-9,-12,-6,-6,-3,12, 6, 6, 3,-12,-6,12, 6,-6,-3, 6, 3,-12,12,-6, 6,-6, 6,-3, 3,-8,-4,-4,-2,-4,-2,-2,-1}, -{18,-18,-18,18,-18,18,18,-18, 9, 9,-9,-9,-9,-9, 9, 9,12,-12, 6,-6,-12,12,-6, 6,12,-12,-12,12, 6,-6,-6, 6, 6, 6, 3, 3,-6,-6,-3,-3, 6, 6,-6,-6, 3, 3,-3,-3, 8,-8, 4,-4, 4,-4, 2,-2, 4, 4, 2, 2, 2, 2, 1, 1}, -{-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0,-3, 0, 3, 0, 3, 0,-4, 0, 4, 0,-2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-2, 0,-1, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0,-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0,-3, 0, 3, 0, 3, 0,-4, 0, 4, 0,-2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-2, 0,-1, 0,-1, 0}, -{18,-18,-18,18,-18,18,18,-18,12, 6,-12,-6,-12,-6,12, 6, 9,-9, 9,-9,-9, 9,-9, 9,12,-12,-12,12, 6,-6,-6, 6, 6, 3, 6, 3,-6,-3,-6,-3, 8, 4,-8,-4, 4, 2,-4,-2, 6,-6, 6,-6, 3,-3, 3,-3, 4, 2, 4, 2, 2, 1, 2, 1}, -{-12,12,12,-12,12,-12,-12,12,-6,-6, 6, 6, 6, 6,-6,-6,-6, 6,-6, 6, 6,-6, 6,-6,-8, 8, 8,-8,-4, 4, 4,-4,-3,-3,-3,-3, 3, 3, 3, 3,-4,-4, 4, 4,-2,-2, 2, 2,-4, 4,-4, 4,-2, 2,-2, 2,-2,-2,-2,-2,-1,-1,-1,-1}, -{ 2, 0, 0, 0,-2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,-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, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{-6, 6, 0, 0, 6,-6, 0, 0,-4,-2, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 4,-4, 0, 0,-4, 4, 0, 0, 2, 2, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,-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, 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, 2, 0, 0, 0,-2, 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}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 0, 0, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4,-2, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-3, 3, 0, 0,-2,-1, 0, 0,-2,-1, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,-4, 0, 0,-4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0}, -{-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 0,-2, 0, 4, 0, 2, 0,-3, 0, 3, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0,-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 0,-2, 0, 4, 0, 2, 0,-3, 0, 3, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0,-2, 0,-1, 0}, -{18,-18,-18,18,-18,18,18,-18,12, 6,-12,-6,-12,-6,12, 6,12,-12, 6,-6,-12,12,-6, 6, 9,-9,-9, 9, 9,-9,-9, 9, 8, 4, 4, 2,-8,-4,-4,-2, 6, 3,-6,-3, 6, 3,-6,-3, 6,-6, 3,-3, 6,-6, 3,-3, 4, 2, 2, 1, 4, 2, 2, 1}, -{-12,12,12,-12,12,-12,-12,12,-6,-6, 6, 6, 6, 6,-6,-6,-8, 8,-4, 4, 8,-8, 4,-4,-6, 6, 6,-6,-6, 6, 6,-6,-4,-4,-2,-2, 4, 4, 2, 2,-3,-3, 3, 3,-3,-3, 3, 3,-4, 4,-2, 2,-4, 4,-2, 2,-2,-2,-1,-1,-2,-2,-1,-1}, -{ 4, 0,-4, 0,-4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,-2, 0,-2, 0, 2, 0,-2, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,-4, 0,-4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,-2, 0,-2, 0, 2, 0,-2, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0}, -{-12,12,12,-12,12,-12,-12,12,-8,-4, 8, 4, 8, 4,-8,-4,-6, 6,-6, 6, 6,-6, 6,-6,-6, 6, 6,-6,-6, 6, 6,-6,-4,-2,-4,-2, 4, 2, 4, 2,-4,-2, 4, 2,-4,-2, 4, 2,-3, 3,-3, 3,-3, 3,-3, 3,-2,-1,-2,-1,-2,-1,-2,-1}, -{ 8,-8,-8, 8,-8, 8, 8,-8, 4, 4,-4,-4,-4,-4, 4, 4, 4,-4, 4,-4,-4, 4,-4, 4, 4,-4,-4, 4, 4,-4,-4, 4, 2, 2, 2, 2,-2,-2,-2,-2, 2, 2,-2,-2, 2, 2,-2,-2, 2,-2, 2,-2, 2,-2, 2,-2, 1, 1, 1, 1, 1, 1, 1, 1}}; - -static int ijk2n(int i, int j, int k) { - return(i+4*j+16*k); -} - -static void tricubic_get_coeff_stacked(float a[64], float x[64]) { - int i,j; - for (i=0;i<64;i++) { - a[i]=(float)(0.0); - for (j=0;j<64;j++) { - a[i]+=C[i][j]*x[j]; - } } + return 0.f; } + +float voxel_sample_triquadratic(float *data, int *res, float *co) +{ + if (data) { + + const float xf = co[0] * res[0], yf = co[1] * res[1], zf = co[2] * res[2]; + const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf); + + const int xc[3] = {_clamp(x - 1, 0, res[0] - 1), _clamp(x, 0, res[0] - 1), _clamp(x + 1, 0, res[0] - 1)}; + const int yc[3] = {res[0] * _clamp(y - 1, 0, res[1] - 1), res[0] * _clamp(y, 0, res[1] - 1), res[0] * _clamp(y + 1, 0, res[1] - 1)}; + const int zc[3] = {res[0] * res[1] * _clamp(z - 1, 0, res[2] - 1), res[0] * res[1] * _clamp(z, 0, res[2] - 1), res[0] * res[1] * _clamp(z + 1, 0, res[2] - 1)}; + + const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z; + const float u[3] = {dx*(0.5f*dx - 1.f) + 0.5f, dx*(1.f - dx) + 0.5f, 0.5f*dx*dx}; + const float v[3] = {dy*(0.5f*dy - 1.f) + 0.5f, dy*(1.f - dy) + 0.5f, 0.5f*dy*dy}; + const float w[3] = {dz*(0.5f*dz - 1.f) + 0.5f, dz*(1.f - dz) + 0.5f, 0.5f*dz*dz}; + + return w[0] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] + u[2] * data[xc[2] + yc[0] + zc[0]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] + u[2] * data[xc[2] + yc[1] + zc[0]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[0]] + u[1] * data[xc[1] + yc[2] + zc[0]] + u[2] * data[xc[2] + yc[2] + zc[0]] ) ) + + w[1] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] + u[2] * data[xc[2] + yc[0] + zc[1]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] + u[2] * data[xc[2] + yc[1] + zc[1]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[1]] + u[1] * data[xc[1] + yc[2] + zc[1]] + u[2] * data[xc[2] + yc[2] + zc[1]] ) ) + + w[2] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[2]] + u[1] * data[xc[1] + yc[0] + zc[2]] + u[2] * data[xc[2] + yc[0] + zc[2]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[2]] + u[1] * data[xc[1] + yc[1] + zc[2]] + u[2] * data[xc[2] + yc[1] + zc[2]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] + u[2] * data[xc[2] + yc[2] + zc[2]] ) ); - - -static void tricubic_get_coeff(float a[64], float f[8], float dfdx[8], float dfdy[8], float dfdz[8], float d2fdxdy[8], float d2fdxdz[8], float d2fdydz[8], float d3fdxdydz[8]) { - int i; - float x[64]; - for (i=0;i<8;i++) { - x[0+i]=f[i]; - x[8+i]=dfdx[i]; - x[16+i]=dfdy[i]; - x[24+i]=dfdz[i]; - x[32+i]=d2fdxdy[i]; - x[40+i]=d2fdxdz[i]; - x[48+i]=d2fdydz[i]; - x[56+i]=d3fdxdydz[i]; - } - tricubic_get_coeff_stacked(a,x); } - -static float tricubic_eval(float a[64], float x, float y, float z) { - int i,j,k; - float ret=(float)(0.0); - - for (i=0;i<4;i++) { - for (j=0;j<4;j++) { - for (k=0;k<4;k++) { - ret+=a[ijk2n(i,j,k)]*pow(x,i)*pow(y,j)*pow(z,k); - } - } - } - return(ret); + return 0.f; } -/* tricubic interpolation - * from 'libtricubic': http://www.lekien.com/~francois/software/tricubic/ - * input coordinates must be in bounding box 0.0 - 1.0 */ -float voxel_sample_tricubic(float *data, int *res, float *co) +float voxel_sample_tricubic(float *data, int *res, float *co, int bspline) { - float xx, yy, zz; - int xi,yi,zi; - int *n = res; - float dx,dy,dz; - float a[64]; - - xx = co[0] * res[0] - 0.5f; - yy = co[1] * res[1] - 0.5f; - zz = co[2] * res[2] - 0.5f; - - xi = (int)xx; yi = (int)yy; zi = (int)zz; - - { - float fval[8]={data[V_I(xi,yi,zi,n)],data[V_I(xi+1,yi,zi,n)],data[V_I(xi,yi+1,zi,n)],data[V_I(xi+1,yi+1,zi,n)],data[V_I(xi,yi,zi+1,n)],data[V_I(xi+1,yi,zi+1,n)],data[V_I(xi,yi+1,zi+1,n)],data[V_I(xi+1,yi+1,zi+1,n)]}; - - float dfdxval[8]={0.5f*(data[V_I(xi+1,yi,zi,n)]-data[V_I(xi-1,yi,zi,n)]),0.5f*(data[V_I(xi+2,yi,zi,n)]-data[V_I(xi,yi,zi,n)]), - 0.5f*(data[V_I(xi+1,yi+1,zi,n)]-data[V_I(xi-1,yi+1,zi,n)]),0.5f*(data[V_I(xi+2,yi+1,zi,n)]-data[V_I(xi,yi+1,zi,n)]), - 0.5f*(data[V_I(xi+1,yi,zi+1,n)]-data[V_I(xi-1,yi,zi+1,n)]),0.5f*(data[V_I(xi+2,yi,zi+1,n)]-data[V_I(xi,yi,zi+1,n)]), - 0.5f*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi-1,yi+1,zi+1,n)]), - 0.5f*(data[V_I(xi+2,yi+1,zi+1,n)]-data[V_I(xi,yi+1,zi+1,n)])}; - - float dfdyval[8]={0.5f*(data[V_I(xi,yi+1,zi,n)]-data[V_I(xi,yi-1,zi,n)]),0.5f*(data[V_I(xi+1,yi+1,zi,n)]-data[V_I(xi+1,yi-1,zi,n)]), - 0.5f*(data[V_I(xi,yi+2,zi,n)]-data[V_I(xi,yi,zi,n)]),0.5f*(data[V_I(xi+1,yi+2,zi,n)]-data[V_I(xi+1,yi,zi,n)]), - 0.5f*(data[V_I(xi,yi+1,zi+1,n)]-data[V_I(xi,yi-1,zi+1,n)]),0.5f*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi+1,yi-1,zi+1,n)]), - 0.5f*(data[V_I(xi,yi+2,zi+1,n)]-data[V_I(xi,yi,zi+1,n)]), - 0.5f*(data[V_I(xi+1,yi+2,zi+1,n)]-data[V_I(xi+1,yi,zi+1,n)])}; - - float dfdzval[8]={0.5f*(data[V_I(xi,yi,zi+1,n)]-data[V_I(xi,yi,zi-1,n)]),0.5f*(data[V_I(xi+1,yi,zi+1,n)]-data[V_I(xi+1,yi,zi-1,n)]), - 0.5f*(data[V_I(xi,yi+1,zi+1,n)]-data[V_I(xi,yi+1,zi-1,n)]),0.5f*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi+1,yi+1,zi-1,n)]), - 0.5f*(data[V_I(xi,yi,zi+2,n)]-data[V_I(xi,yi,zi,n)]),0.5f*(data[V_I(xi+1,yi,zi+2,n)]-data[V_I(xi+1,yi,zi,n)]), - 0.5f*(data[V_I(xi,yi+1,zi+2,n)]-data[V_I(xi,yi+1,zi,n)]), - 0.5f*(data[V_I(xi+1,yi+1,zi+2,n)]-data[V_I(xi+1,yi+1,zi,n)])}; - - float d2fdxdyval[8]={0.25*(data[V_I(xi+1,yi+1,zi,n)]-data[V_I(xi-1,yi+1,zi,n)]-data[V_I(xi+1,yi-1,zi,n)]+data[V_I(xi-1,yi-1,zi,n)]), - 0.25*(data[V_I(xi+2,yi+1,zi,n)]-data[V_I(xi,yi+1,zi,n)]-data[V_I(xi+2,yi-1,zi,n)]+data[V_I(xi,yi-1,zi,n)]), - 0.25*(data[V_I(xi+1,yi+2,zi,n)]-data[V_I(xi-1,yi+2,zi,n)]-data[V_I(xi+1,yi,zi,n)]+data[V_I(xi-1,yi,zi,n)]), - 0.25*(data[V_I(xi+2,yi+2,zi,n)]-data[V_I(xi,yi+2,zi,n)]-data[V_I(xi+2,yi,zi,n)]+data[V_I(xi,yi,zi,n)]), - 0.25*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi-1,yi+1,zi+1,n)]-data[V_I(xi+1,yi-1,zi+1,n)]+data[V_I(xi-1,yi-1,zi+1,n)]), - 0.25*(data[V_I(xi+2,yi+1,zi+1,n)]-data[V_I(xi,yi+1,zi+1,n)]-data[V_I(xi+2,yi-1,zi+1,n)]+data[V_I(xi,yi-1,zi+1,n)]), - 0.25*(data[V_I(xi+1,yi+2,zi+1,n)]-data[V_I(xi-1,yi+2,zi+1,n)]-data[V_I(xi+1,yi,zi+1,n)]+data[V_I(xi-1,yi,zi+1,n)]), - 0.25*(data[V_I(xi+2,yi+2,zi+1,n)]-data[V_I(xi,yi+2,zi+1,n)]-data[V_I(xi+2,yi,zi+1,n)]+data[V_I(xi,yi,zi+1,n)])}; - - float d2fdxdzval[8]={0.25f*(data[V_I(xi+1,yi,zi+1,n)]-data[V_I(xi-1,yi,zi+1,n)]-data[V_I(xi+1,yi,zi-1,n)]+data[V_I(xi-1,yi,zi-1,n)]), - 0.25f*(data[V_I(xi+2,yi,zi+1,n)]-data[V_I(xi,yi,zi+1,n)]-data[V_I(xi+2,yi,zi-1,n)]+data[V_I(xi,yi,zi-1,n)]), - 0.25f*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi-1,yi+1,zi+1,n)]-data[V_I(xi+1,yi+1,zi-1,n)]+data[V_I(xi-1,yi+1,zi-1,n)]), - 0.25f*(data[V_I(xi+2,yi+1,zi+1,n)]-data[V_I(xi,yi+1,zi+1,n)]-data[V_I(xi+2,yi+1,zi-1,n)]+data[V_I(xi,yi+1,zi-1,n)]), - 0.25f*(data[V_I(xi+1,yi,zi+2,n)]-data[V_I(xi-1,yi,zi+2,n)]-data[V_I(xi+1,yi,zi,n)]+data[V_I(xi-1,yi,zi,n)]), - 0.25f*(data[V_I(xi+2,yi,zi+2,n)]-data[V_I(xi,yi,zi+2,n)]-data[V_I(xi+2,yi,zi,n)]+data[V_I(xi,yi,zi,n)]), - 0.25f*(data[V_I(xi+1,yi+1,zi+2,n)]-data[V_I(xi-1,yi+1,zi+2,n)]-data[V_I(xi+1,yi+1,zi,n)]+data[V_I(xi-1,yi+1,zi,n)]), - 0.25f*(data[V_I(xi+2,yi+1,zi+2,n)]-data[V_I(xi,yi+1,zi+2,n)]-data[V_I(xi+2,yi+1,zi,n)]+data[V_I(xi,yi+1,zi,n)])}; - - - float d2fdydzval[8]={0.25f*(data[V_I(xi,yi+1,zi+1,n)]-data[V_I(xi,yi-1,zi+1,n)]-data[V_I(xi,yi+1,zi-1,n)]+data[V_I(xi,yi-1,zi-1,n)]), - 0.25f*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi+1,yi-1,zi+1,n)]-data[V_I(xi+1,yi+1,zi-1,n)]+data[V_I(xi+1,yi-1,zi-1,n)]), - 0.25f*(data[V_I(xi,yi+2,zi+1,n)]-data[V_I(xi,yi,zi+1,n)]-data[V_I(xi,yi+2,zi-1,n)]+data[V_I(xi,yi,zi-1,n)]), - 0.25f*(data[V_I(xi+1,yi+2,zi+1,n)]-data[V_I(xi+1,yi,zi+1,n)]-data[V_I(xi+1,yi+2,zi-1,n)]+data[V_I(xi+1,yi,zi-1,n)]), - 0.25f*(data[V_I(xi,yi+1,zi+2,n)]-data[V_I(xi,yi-1,zi+2,n)]-data[V_I(xi,yi+1,zi,n)]+data[V_I(xi,yi-1,zi,n)]), - 0.25f*(data[V_I(xi+1,yi+1,zi+2,n)]-data[V_I(xi+1,yi-1,zi+2,n)]-data[V_I(xi+1,yi+1,zi,n)]+data[V_I(xi+1,yi-1,zi,n)]), - 0.25f*(data[V_I(xi,yi+2,zi+2,n)]-data[V_I(xi,yi,zi+2,n)]-data[V_I(xi,yi+2,zi,n)]+data[V_I(xi,yi,zi,n)]), - 0.25f*(data[V_I(xi+1,yi+2,zi+2,n)]-data[V_I(xi+1,yi,zi+2,n)]-data[V_I(xi+1,yi+2,zi,n)]+data[V_I(xi+1,yi,zi,n)])}; - - - float d3fdxdydzval[8]={0.125f*(data[V_I(xi+1,yi+1,zi+1,n)]-data[V_I(xi-1,yi+1,zi+1,n)]-data[V_I(xi+1,yi-1,zi+1,n)]+data[V_I(xi-1,yi-1,zi+1,n)]-data[V_I(xi+1,yi+1,zi-1,n)]+data[V_I(xi-1,yi+1,zi-1,n)]+data[V_I(xi+1,yi-1,zi-1,n)]-data[V_I(xi-1,yi-1,zi-1,n)]), - 0.125f*(data[V_I(xi+2,yi+1,zi+1,n)]-data[V_I(xi,yi+1,zi+1,n)]-data[V_I(xi+2,yi-1,zi+1,n)]+data[V_I(xi,yi-1,zi+1,n)]-data[V_I(xi+2,yi+1,zi-1,n)]+data[V_I(xi,yi+1,zi-1,n)]+data[V_I(xi+2,yi-1,zi-1,n)]-data[V_I(xi,yi-1,zi-1,n)]), - 0.125f*(data[V_I(xi+1,yi+2,zi+1,n)]-data[V_I(xi-1,yi+2,zi+1,n)]-data[V_I(xi+1,yi,zi+1,n)]+data[V_I(xi-1,yi,zi+1,n)]-data[V_I(xi+1,yi+2,zi-1,n)]+data[V_I(xi-1,yi+2,zi-1,n)]+data[V_I(xi+1,yi,zi-1,n)]-data[V_I(xi-1,yi,zi-1,n)]), - 0.125f*(data[V_I(xi+2,yi+2,zi+1,n)]-data[V_I(xi,yi+2,zi+1,n)]-data[V_I(xi+2,yi,zi+1,n)]+data[V_I(xi,yi,zi+1,n)]-data[V_I(xi+2,yi+2,zi-1,n)]+data[V_I(xi,yi+2,zi-1,n)]+data[V_I(xi+2,yi,zi-1,n)]-data[V_I(xi,yi,zi-1,n)]), - 0.125f*(data[V_I(xi+1,yi+1,zi+2,n)]-data[V_I(xi-1,yi+1,zi+2,n)]-data[V_I(xi+1,yi-1,zi+2,n)]+data[V_I(xi-1,yi-1,zi+2,n)]-data[V_I(xi+1,yi+1,zi,n)]+data[V_I(xi-1,yi+1,zi,n)]+data[V_I(xi+1,yi-1,zi,n)]-data[V_I(xi-1,yi-1,zi,n)]), - 0.125f*(data[V_I(xi+2,yi+1,zi+2,n)]-data[V_I(xi,yi+1,zi+2,n)]-data[V_I(xi+2,yi-1,zi+2,n)]+data[V_I(xi,yi-1,zi+2,n)]-data[V_I(xi+2,yi+1,zi,n)]+data[V_I(xi,yi+1,zi,n)]+data[V_I(xi+2,yi-1,zi,n)]-data[V_I(xi,yi-1,zi,n)]), - 0.125f*(data[V_I(xi+1,yi+2,zi+2,n)]-data[V_I(xi-1,yi+2,zi+2,n)]-data[V_I(xi+1,yi,zi+2,n)]+data[V_I(xi-1,yi,zi+2,n)]-data[V_I(xi+1,yi+2,zi,n)]+data[V_I(xi-1,yi+2,zi,n)]+data[V_I(xi+1,yi,zi,n)]-data[V_I(xi-1,yi,zi,n)]), - 0.125f*(data[V_I(xi+2,yi+2,zi+2,n)]-data[V_I(xi,yi+2,zi+2,n)]-data[V_I(xi+2,yi,zi+2,n)]+data[V_I(xi,yi,zi+2,n)]-data[V_I(xi+2,yi+2,zi,n)]+data[V_I(xi,yi+2,zi,n)]+data[V_I(xi+2,yi,zi,n)]-data[V_I(xi,yi,zi,n)])}; - - - tricubic_get_coeff(a,fval,dfdxval,dfdyval,dfdzval,d2fdxdyval,d2fdxdzval,d2fdydzval,d3fdxdydzval); + if (data) { + + const float xf = co[0] * res[0] - 0.5f, yf = co[1] * res[1] - 0.5f, zf = co[2] * res[2] - 0.5f; + const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf); + + const int xc[4] = {_clamp(x - 1, 0, res[0] - 1), _clamp(x, 0, res[0] - 1), _clamp(x + 1, 0, res[0] - 1), _clamp(x + 2, 0, res[0] - 1)}; + const int yc[4] = {res[0] * _clamp(y - 1, 0, res[1] - 1), res[0] * _clamp(y, 0, res[1] - 1), res[0] * _clamp(y + 1, 0, res[1] - 1), res[0] * _clamp(y + 2, 0, res[1] - 1)}; + const int zc[4] = {res[0] * res[1] * _clamp(z - 1, 0, res[2] - 1), res[0] * res[1] * _clamp(z, 0, res[2] - 1), res[0] * res[1] * _clamp(z + 1, 0, res[2] - 1), res[0] * res[1] * _clamp(z + 2, 0, res[2] - 1)}; + + const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z; + + float u[4], v[4], w[4]; + if (bspline) { // B-Spline + u[0] = (((-1.f/6.f)*dx + 0.5f)*dx - 0.5f)*dx + (1.f/6.f); + u[1] = (( 0.5f*dx - 1.f )*dx )*dx + (2.f/3.f); + u[2] = (( -0.5f*dx + 0.5f)*dx + 0.5f)*dx + (1.f/6.f); + u[3] = ( 1.f/6.f)*dx*dx*dx; + v[0] = (((-1.f/6.f)*dy + 0.5f)*dy - 0.5f)*dy + (1.f/6.f); + v[1] = (( 0.5f*dy - 1.f )*dy )*dy + (2.f/3.f); + v[2] = (( -0.5f*dy + 0.5f)*dy + 0.5f)*dy + (1.f/6.f); + v[3] = ( 1.f/6.f)*dy*dy*dy; + w[0] = (((-1.f/6.f)*dz + 0.5f)*dz - 0.5f)*dz + (1.f/6.f); + w[1] = (( 0.5f*dz - 1.f )*dz )*dz + (2.f/3.f); + w[2] = (( -0.5f*dz + 0.5f)*dz + 0.5f)*dz + (1.f/6.f); + w[3] = ( 1.f/6.f)*dz*dz*dz; + } + else { // Catmull-Rom + u[0] = ((-0.5f*dx + 1.0f)*dx - 0.5f)*dx; + u[1] = (( 1.5f*dx - 2.5f)*dx )*dx + 1.0f; + u[2] = ((-1.5f*dx + 2.0f)*dx + 0.5f)*dx; + u[3] = (( 0.5f*dx - 0.5f)*dx )*dx; + v[0] = ((-0.5f*dy + 1.0f)*dy - 0.5f)*dy; + v[1] = (( 1.5f*dy - 2.5f)*dy )*dy + 1.0f; + v[2] = ((-1.5f*dy + 2.0f)*dy + 0.5f)*dy; + v[3] = (( 0.5f*dy - 0.5f)*dy )*dy; + w[0] = ((-0.5f*dz + 1.0f)*dz - 0.5f)*dz; + w[1] = (( 1.5f*dz - 2.5f)*dz )*dz + 1.0f; + w[2] = ((-1.5f*dz + 2.0f)*dz + 0.5f)*dz; + w[3] = (( 0.5f*dz - 0.5f)*dz )*dz; + } + + return w[0] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] + u[2] * data[xc[2] + yc[0] + zc[0]] + u[3] * data[xc[3] + yc[0] + zc[0]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] + u[2] * data[xc[2] + yc[1] + zc[0]] + u[3] * data[xc[3] + yc[1] + zc[0]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[0]] + u[1] * data[xc[1] + yc[2] + zc[0]] + u[2] * data[xc[2] + yc[2] + zc[0]] + u[3] * data[xc[3] + yc[2] + zc[0]] ) + + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[0]] + u[1] * data[xc[1] + yc[3] + zc[0]] + u[2] * data[xc[2] + yc[3] + zc[0]] + u[3] * data[xc[3] + yc[3] + zc[0]] ) ) + + w[1] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] + u[2] * data[xc[2] + yc[0] + zc[1]] + u[3] * data[xc[3] + yc[0] + zc[1]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] + u[2] * data[xc[2] + yc[1] + zc[1]] + u[3] * data[xc[3] + yc[1] + zc[1]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[1]] + u[1] * data[xc[1] + yc[2] + zc[1]] + u[2] * data[xc[2] + yc[2] + zc[1]] + u[3] * data[xc[3] + yc[2] + zc[1]] ) + + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[1]] + u[1] * data[xc[1] + yc[3] + zc[1]] + u[2] * data[xc[2] + yc[3] + zc[1]] + u[3] * data[xc[3] + yc[3] + zc[1]] ) ) + + w[2] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[2]] + u[1] * data[xc[1] + yc[0] + zc[2]] + u[2] * data[xc[2] + yc[0] + zc[2]] + u[3] * data[xc[3] + yc[0] + zc[2]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[2]] + u[1] * data[xc[1] + yc[1] + zc[2]] + u[2] * data[xc[2] + yc[1] + zc[2]] + u[3] * data[xc[3] + yc[1] + zc[2]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] + u[2] * data[xc[2] + yc[2] + zc[2]] + u[3] * data[xc[3] + yc[2] + zc[2]] ) + + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[2]] + u[1] * data[xc[1] + yc[3] + zc[2]] + u[2] * data[xc[2] + yc[3] + zc[2]] + u[3] * data[xc[3] + yc[3] + zc[2]] ) ) + + w[3] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[3]] + u[1] * data[xc[1] + yc[0] + zc[3]] + u[2] * data[xc[2] + yc[0] + zc[3]] + u[3] * data[xc[3] + yc[0] + zc[3]] ) + + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[3]] + u[1] * data[xc[1] + yc[1] + zc[3]] + u[2] * data[xc[2] + yc[1] + zc[3]] + u[3] * data[xc[3] + yc[1] + zc[3]] ) + + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[3]] + u[1] * data[xc[1] + yc[2] + zc[3]] + u[2] * data[xc[2] + yc[2] + zc[3]] + u[3] * data[xc[3] + yc[2] + zc[3]] ) + + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[3]] + u[1] * data[xc[1] + yc[3] + zc[3]] + u[2] * data[xc[2] + yc[3] + zc[3]] + u[3] * data[xc[3] + yc[3] + zc[3]] ) ); + } - - dx = xx-xi; - dy = yy-yi; - dz = zz-zi; - - return tricubic_eval(a,dx,dy,dz); - + return 0.f; } - diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 1b6ed1bc032..4df63ee9cd9 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -515,7 +515,10 @@ typedef struct TexMapping { /* interpolation */ #define TEX_VD_NEARESTNEIGHBOR 0 #define TEX_VD_LINEAR 1 -#define TEX_VD_TRICUBIC 2 +#define TEX_VD_QUADRATIC 2 +#define TEX_VD_TRICUBIC_CATROM 3 +#define TEX_VD_TRICUBIC_BSPLINE 4 +#define TEX_VD_TRICUBIC_SLOW 5 /* file format */ #define TEX_VD_BLENDERVOXEL 0 diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 6de0be9b19c..b11e5c6c12f 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1496,10 +1496,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) static EnumPropertyItem interpolation_type_items[] = { {TEX_VD_NEARESTNEIGHBOR, "NEREASTNEIGHBOR", 0, "Nearest Neighbor", "No interpolation, fast but blocky and low quality."}, - {TEX_VD_LINEAR, "TRILINEAR", 0, "Trilinear", "Good smoothness and speed"}, - {TEX_VD_TRICUBIC, "TRICUBIC", 0, "Tricubic", "High quality interpolation, but slow"}, + {TEX_VD_LINEAR, "TRILINEAR", 0, "Linear", "Good smoothness and speed"}, + {TEX_VD_QUADRATIC, "QUADRATIC", 0, "Quadratic", "Mid-range quality and speed"}, + {TEX_VD_TRICUBIC_CATROM, "TRICUBIC_CATROM", 0, "Cubic Catmull-Rom", "High quality interpolation, but slower"}, + {TEX_VD_TRICUBIC_BSPLINE, "TRICUBIC_BSPLINE", 0, "Cubic B-Spline", "Smoothed high quality interpolation, but slower"}, {0, NULL, 0, NULL, NULL}}; - + static EnumPropertyItem file_format_items[] = { {TEX_VD_BLENDERVOXEL, "BLENDER_VOXEL", 0, "Blender Voxel", "Default binary voxel file format"}, {TEX_VD_RAW_8BIT, "RAW_8BIT", 0, "8 bit RAW", "8 bit greyscale binary data"}, diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 836faeb05b9..17858e55e3d 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -322,8 +322,12 @@ int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres) case TEX_VD_LINEAR: texres->tin = voxel_sample_trilinear(vd->dataset, vd->resol, co); break; - case TEX_VD_TRICUBIC: - texres->tin = voxel_sample_tricubic(vd->dataset, vd->resol, co); + case TEX_VD_QUADRATIC: + texres->tin = voxel_sample_triquadratic(vd->dataset, vd->resol, co); + break; + case TEX_VD_TRICUBIC_CATROM: + case TEX_VD_TRICUBIC_BSPLINE: + texres->tin = voxel_sample_tricubic(vd->dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); break; } -- cgit v1.2.3 From 15ef88b90239af30b08e798cc57cea317f1d56c9 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 07:26:32 +0000 Subject: Keying Sets: Added options to add/remove properties from the active Keying Set to the RMB menu (and also via KKEY and ALT-K respectively) --- source/blender/blenkernel/intern/anim_sys.c | 2 +- source/blender/editors/animation/anim_intern.h | 30 +++- source/blender/editors/animation/anim_ops.c | 6 +- source/blender/editors/animation/drivers.c | 4 +- source/blender/editors/animation/keyingsets.c | 165 +++++++++++++++++++++ source/blender/editors/include/ED_keyframing.h | 6 + source/blender/editors/interface/interface_anim.c | 26 ++++ .../blender/editors/interface/interface_handlers.c | 19 ++- .../blender/editors/interface/interface_intern.h | 2 + 9 files changed, 249 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index df7004d3f6b..b7cc98063ed 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -239,7 +239,7 @@ KS_Path *BKE_keyingset_find_destination (KeyingSet *ks, ID *id, const char group if ((ksp->rna_path==0) || strcmp(rna_path, ksp->rna_path)) eq_path= 0; - /* index */ + /* index - need to compare whole-array setting too... */ if (ksp->array_index != array_index) eq_index= 0; diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index e903007fbc0..462ef76ea8d 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -1,18 +1,42 @@ -/* Testing code for 2.5 animation system - * Copyright 2009, Joshua Leung +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place * Suite 330, Boston, MA 02111*1307, USA. + * + * The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung + * This is a new part of Blender (with some old code) + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** */ #ifndef ANIM_INTERN_H #define ANIM_INTERN_H - /* KeyingSets/Keyframing Interface ------------- */ /* list of builtin KeyingSets (defined in keyingsets.c) */ extern ListBase builtin_keyingsets; +/* for builtin keyingsets - context poll */ short keyingset_context_ok_poll(bContext *C, KeyingSet *ks); +/* Main KeyingSet operations API call */ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks); #endif // ANIM_INTERN_H diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 3d45dcc92ca..fedbe12c0e6 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -381,13 +381,14 @@ void ANIM_OT_time_toggle(wmOperatorType *ot) void ED_operatortypes_anim(void) { + /* Animation Editors only -------------------------- */ WM_operatortype_append(ANIM_OT_change_frame); WM_operatortype_append(ANIM_OT_time_toggle); WM_operatortype_append(ANIM_OT_previewrange_set); WM_operatortype_append(ANIM_OT_previewrange_clear); - // XXX this is used all over... maybe for screen instead? + /* Entire UI --------------------------------------- */ WM_operatortype_append(ANIM_OT_insert_keyframe); WM_operatortype_append(ANIM_OT_delete_keyframe); WM_operatortype_append(ANIM_OT_insert_keyframe_menu); @@ -398,6 +399,9 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_add_driver_button); WM_operatortype_append(ANIM_OT_remove_driver_button); + + WM_operatortype_append(ANIM_OT_add_keyingset_button); + WM_operatortype_append(ANIM_OT_remove_keyingset_button); } void ED_keymap_anim(wmWindowManager *wm) diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index e7b7d785d7b..8349b7f9bde 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -281,7 +281,7 @@ void ANIM_OT_add_driver_button (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array."); + RNA_def_boolean(ot->srna, "all", 1, "All", "Create drivers for all elements of the array."); } /* Remove Driver Button Operator ------------------------ */ @@ -344,7 +344,7 @@ void ANIM_OT_remove_driver_button (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyfames from all elements of the array."); + RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array."); } /* ************************************************** */ diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index f81f57d526a..a91a9bfa911 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -77,6 +77,171 @@ #include "anim_intern.h" +/* ************************************************** */ +/* KEYING SETS - OPERATORS (for use in UI menus) */ + +/* Add to KeyingSet Button Operator ------------------------ */ + +static int add_keyingset_button_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks = NULL; + PropertyRNA *prop= NULL; + PointerRNA ptr; + char *path = NULL; + short success= 0; + int index=0, pflag=0; + int all= RNA_boolean_get(op->ptr, "all"); + + /* verify the Keying Set to use: + * - use the active one for now (more control over this can be added later) + * - add a new one if it doesn't exist + */ + if (scene->active_keyingset == 0) { + short flag=0, keyingflag=0; + + /* validate flags + * - absolute KeyingSets should be created by default + */ + flag |= KEYINGSET_ABSOLUTE; + + if (IS_AUTOKEY_FLAG(AUTOMATKEY)) + keyingflag |= INSERTKEY_MATRIX; + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) + keyingflag |= INSERTKEY_NEEDED; + + /* call the API func, and set the active keyingset index */ + ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag); + + scene->active_keyingset= BLI_countlist(&scene->keyingsets); + } + else + ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* try to add to keyingset using property retrieved from UI */ + memset(&ptr, 0, sizeof(PointerRNA)); + uiAnimContextProperty(C, &ptr, &prop, &index); + + /* check if property is able to be added */ + if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) { + path= RNA_path_from_ID_to_property(&ptr, prop); + + if (path) { + /* set flags */ + if (all) + pflag |= KSP_FLAG_WHOLE_ARRAY; + + /* add path to this setting */ + BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME); + + /* free the temp path created */ + MEM_freeN(path); + } + } + + if (success) { + /* send updates */ + ED_anim_dag_flush_update(C); + + /* for now, only send ND_KEYS for KeyingSets */ + WM_event_add_notifier(C, ND_KEYS, NULL); + } + + return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; +} + +void ANIM_OT_add_keyingset_button (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add to Keying Set"; + ot->idname= "ANIM_OT_add_keyingset_button"; + + /* callbacks */ + ot->exec= add_keyingset_button_exec; + //op->poll= ??? + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set."); +} + +/* Remove from KeyingSet Button Operator ------------------------ */ + +static int remove_keyingset_button_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks = NULL; + PropertyRNA *prop= NULL; + PointerRNA ptr; + char *path = NULL; + short success= 0; + int index=0; + + /* verify the Keying Set to use: + * - use the active one for now (more control over this can be added later) + * - return error if it doesn't exist + */ + if (scene->active_keyingset == 0) { + BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from"); + return OPERATOR_CANCELLED; + } + else + ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* try to add to keyingset using property retrieved from UI */ + memset(&ptr, 0, sizeof(PointerRNA)); + uiAnimContextProperty(C, &ptr, &prop, &index); + + if (ptr.data && prop) { + path= RNA_path_from_ID_to_property(&ptr, prop); + + if (path) { + KS_Path *ksp; + + /* try to find a path matching this description */ + ksp= BKE_keyingset_find_destination(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME); + + if (ksp) { + /* just free it... */ + MEM_freeN(ksp->rna_path); + BLI_freelinkN(&ks->paths, ksp); + + success= 1; + } + + /* free temp path used */ + MEM_freeN(path); + } + } + + + if (success) { + /* send updates */ + ED_anim_dag_flush_update(C); + + /* for now, only send ND_KEYS for KeyingSets */ + WM_event_add_notifier(C, ND_KEYS, NULL); + } + + return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; +} + +void ANIM_OT_remove_keyingset_button (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove from Keying Set"; + ot->idname= "ANIM_OT_remove_keyingset_button"; + + /* callbacks */ + ot->exec= remove_keyingset_button_exec; + //op->poll= ??? + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* ************************************************** */ /* KEYING SETS - EDITING API */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index c492143751c..20c2301d2ac 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -155,6 +155,12 @@ struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, cha /* Initialise builtin KeyingSets on startup */ void init_builtin_keyingsets(void); +/* -------- */ + +/* KeyingSet managment operators for UI buttons. */ +void ANIM_OT_add_keyingset_button(struct wmOperatorType *ot); +void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot); + /* ************ Drivers ********************** */ /* Main Driver Management API calls: diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index d7904a19bfe..8e15bbde201 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -209,6 +209,18 @@ void ui_but_anim_remove_driver(bContext *C) WM_operator_name_call(C, "ANIM_OT_remove_driver_button", WM_OP_INVOKE_DEFAULT, NULL); } +void ui_but_anim_add_keyingset(bContext *C) +{ + /* this operator calls uiAnimContextProperty above */ + WM_operator_name_call(C, "ANIM_OT_add_keyingset_button", WM_OP_INVOKE_DEFAULT, NULL); +} + +void ui_but_anim_remove_keyingset(bContext *C) +{ + /* this operator calls uiAnimContextProperty above */ + WM_operator_name_call(C, "ANIM_OT_remove_keyingset_button", WM_OP_INVOKE_DEFAULT, NULL); +} + void ui_but_anim_menu(bContext *C, uiBut *but) { uiPopupMenu *pup; @@ -264,6 +276,20 @@ void ui_but_anim_menu(bContext *C, uiBut *but) else uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0); } + + if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) { + uiItemS(layout); + + if(length) { + uiItemBooleanO(layout, "Add All to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 1); + uiItemBooleanO(layout, "Add Single to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 0); + uiItemBooleanO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button", "all", 0); + } + else { + uiItemBooleanO(layout, "Add to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 0); + uiItemBooleanO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button", "all", 0); + } + } uiPupMenuEnd(C, pup); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 79c707f5535..259ccba6b89 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3265,18 +3265,18 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) ui_but_copy_paste(C, but, data, (event->type == CKEY)? 'c': 'v'); return WM_UI_HANDLER_BREAK; } - /* handle keyframeing */ + /* handle keyframing */ else if(event->type == IKEY && event->val == KM_PRESS) { if(event->alt) ui_but_anim_delete_keyframe(C); else ui_but_anim_insert_keyframe(C); - + ED_region_tag_redraw(CTX_wm_region(C)); - + return WM_UI_HANDLER_BREAK; } - /* handle driver adding */ + /* handle drivers */ else if(event->type == DKEY && event->val == KM_PRESS) { if(event->alt) ui_but_anim_remove_driver(C); @@ -3287,6 +3287,17 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) return WM_UI_HANDLER_BREAK; } + /* handle keyingsets */ + else if(event->type == KKEY && event->val == KM_PRESS) { + if(event->alt) + ui_but_anim_remove_keyingset(C); + else + ui_but_anim_remove_keyingset(C); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return WM_UI_HANDLER_BREAK; + } /* handle menu */ else if(event->type == RIGHTMOUSE && event->val == KM_PRESS) { /* RMB has two options now */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 806b40b8646..2e623114fe9 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -467,6 +467,8 @@ void ui_but_anim_insert_keyframe(struct bContext *C); void ui_but_anim_delete_keyframe(struct bContext *C); void ui_but_anim_add_driver(struct bContext *C); void ui_but_anim_remove_driver(struct bContext *C); +void ui_but_anim_add_keyingset(struct bContext *C); +void ui_but_anim_remove_keyingset(struct bContext *C); void ui_but_anim_menu(struct bContext *C, uiBut *but); int ui_but_anim_expression_get(uiBut *but, char *str, int maxlen); int ui_but_anim_expression_set(uiBut *but, const char *str); -- cgit v1.2.3 From 6ed49857a4408bf413f4bf626229aa00d6c8cad7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Sep 2009 08:49:11 +0000 Subject: poll functions to stop crashing when running operators in an invalid context. --- source/blender/editors/object/editconstraint.c | 32 +++++++++++++++++++++- source/blender/editors/physics/ed_pointcache.c | 16 +++++++---- source/blender/editors/space_buttons/buttons_ops.c | 10 +++++++ source/blender/editors/space_console/console_ops.c | 6 ++++ source/blender/editors/space_text/text_ops.c | 2 +- 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/editconstraint.c b/source/blender/editors/object/editconstraint.c index 23b3caf8e26..dc0442a5af9 100644 --- a/source/blender/editors/object/editconstraint.c +++ b/source/blender/editors/object/editconstraint.c @@ -465,6 +465,12 @@ void object_test_constraints (Object *owner) /* ---------- Distance-Dependent Constraints ---------- */ /* StretchTo, Limit Distance */ +static int stretchto_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); + return (ptr.id.data && ptr.data); +} + static int stretchto_reset_exec (bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); @@ -484,6 +490,7 @@ void CONSTRAINT_OT_stretchto_reset (wmOperatorType *ot) ot->description= "Reset original length of bone for Stretch To Constraint."; ot->exec= stretchto_reset_exec; + ot->poll= stretchto_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -501,6 +508,12 @@ static int limitdistance_reset_exec (bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int limitdistance_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); + return (ptr.id.data && ptr.data); +} + void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) { /* identifiers */ @@ -509,6 +522,7 @@ void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) ot->description= "Reset limiting distance for Limit Distance Constraint."; ot->exec= limitdistance_reset_exec; + ot->poll= limitdistance_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -516,6 +530,12 @@ void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) /* ------------- Child-Of Constraint ------------------ */ +static int childof_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); + return (ptr.id.data && ptr.data); +} + /* ChildOf Constraint - set inverse callback */ static int childof_set_inverse_exec (bContext *C, wmOperator *op) { @@ -582,12 +602,12 @@ void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot) ot->description= "Set inverse correction for ChildOf constraint."; ot->exec= childof_set_inverse_exec; + ot->poll= childof_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } - /* ChildOf Constraint - clear inverse callback */ static int childof_clear_inverse_exec (bContext *C, wmOperator *op) { @@ -612,6 +632,7 @@ void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot) ot->description= "Clear inverse correction for ChildOf constraint."; ot->exec= childof_clear_inverse_exec; + ot->poll= childof_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -684,6 +705,12 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con) } } +static int constraint_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); + return (ptr.id.data && ptr.data); +} + static int constraint_delete_exec (bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); @@ -711,6 +738,7 @@ void CONSTRAINT_OT_delete (wmOperatorType *ot) /* callbacks */ ot->exec= constraint_delete_exec; + ot->poll= constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -747,6 +775,7 @@ void CONSTRAINT_OT_move_down (wmOperatorType *ot) /* callbacks */ ot->exec= constraint_move_down_exec; + ot->poll= constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -784,6 +813,7 @@ void CONSTRAINT_OT_move_up (wmOperatorType *ot) /* callbacks */ ot->exec= constraint_move_up_exec; + ot->poll= constraint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c index 68e0c28e9c1..22316290c7b 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/ed_pointcache.c @@ -72,6 +72,12 @@ static int ptcache_bake_all_poll(bContext *C) return 1; } +static int ptcache_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache); + return (ptr.data && ptr.id.data); +} + static int ptcache_bake_all_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); @@ -215,7 +221,7 @@ void PTCACHE_OT_bake(wmOperatorType *ot) /* api callbacks */ ot->exec= ptcache_bake_exec; - ot->poll= ptcache_bake_all_poll; + ot->poll= ptcache_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -230,7 +236,7 @@ void PTCACHE_OT_free_bake(wmOperatorType *ot) /* api callbacks */ ot->exec= ptcache_free_bake_exec; - ot->poll= ptcache_bake_all_poll; + ot->poll= ptcache_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -243,7 +249,7 @@ void PTCACHE_OT_bake_from_cache(wmOperatorType *ot) /* api callbacks */ ot->exec= ptcache_bake_from_cache_exec; - ot->poll= ptcache_bake_all_poll; + ot->poll= ptcache_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -308,7 +314,7 @@ void PTCACHE_OT_add_new(wmOperatorType *ot) /* api callbacks */ ot->exec= ptcache_add_new_exec; - ot->poll= ptcache_bake_all_poll; + ot->poll= ptcache_poll; // ptcache_bake_all_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -321,7 +327,7 @@ void PTCACHE_OT_remove(wmOperatorType *ot) /* api callbacks */ ot->exec= ptcache_remove_exec; - ot->poll= ptcache_bake_all_poll; + ot->poll= ptcache_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 057f35a2487..954a52c54aa 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -613,6 +613,12 @@ void OBJECT_OT_particle_system_remove(wmOperatorType *ot) /********************** new particle settings operator *********************/ +static int psys_poll(bContext *C) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + return (ptr.data != NULL); +} + static int new_particle_settings_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -657,6 +663,7 @@ void PARTICLE_OT_new(wmOperatorType *ot) /* api callbacks */ ot->exec= new_particle_settings_exec; + ot->poll= psys_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -948,6 +955,9 @@ static int file_browse_exec(bContext *C, wmOperator *op) FileBrowseOp *fbo= op->customdata; char *str; + if (RNA_property_is_set(op->ptr, "filename")==0 || fbo==NULL) + return OPERATOR_CANCELLED; + str= RNA_string_get_alloc(op->ptr, "filename", 0, 0); RNA_property_string_set(&fbo->ptr, fbo->prop, str); RNA_property_update(C, &fbo->ptr, fbo->prop); diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index f8dbe0c3dd4..3d0d284b501 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -234,6 +234,11 @@ static int console_edit_poll(bContext *C) return 1; } +static int console_poll(bContext *C) +{ + return (CTX_wm_space_console(C) != NULL); +} + /* static funcs for text editing */ @@ -695,6 +700,7 @@ void CONSOLE_OT_zoom(wmOperatorType *ot) /* api callbacks */ ot->exec= zoom_exec; + ot->poll= console_poll; /* flags */ /* ot->flag= OPTYPE_REGISTER; */ /* super annoying */ diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 7e514ea723a..14b72e13856 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1478,7 +1478,7 @@ static int move_cursor(bContext *C, int type, int select) ARegion *ar= CTX_wm_region(C); /* ensure we have the right region, it's optional */ - if(ar->regiontype != RGN_TYPE_WINDOW) + if(ar && ar->regiontype != RGN_TYPE_WINDOW) ar= NULL; switch(type) { -- cgit v1.2.3 From bade641408882919ef3f22b3d5223d533678120c Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 10:40:41 +0000 Subject: == SCons == * first working changes to get blenderplayer linking * blenderplayer/ moved into source/ (CMakeLists.txt changed for that too) * added externs for bprogname to gp_ghost, so that it links properly --- CMakeLists.txt | 2 +- SConstruct | 3 +- blenderplayer/CMakeLists.txt | 143 --------------- blenderplayer/bad_level_call_stubs/CMakeLists.txt | 40 ----- blenderplayer/bad_level_call_stubs/Makefile | 45 ----- blenderplayer/bad_level_call_stubs/SConscript | 14 -- blenderplayer/bad_level_call_stubs/stubs.c | 200 --------------------- intern/guardedalloc/SConscript | 2 +- intern/memutil/SConscript | 2 +- source/SConscript | 5 +- source/blender/blenkernel/SConscript | 2 +- source/blender/blenlib/SConscript | 2 +- source/blender/blenlib/intern/util.c | 2 + source/blender/blenloader/SConscript | 2 +- source/blender/blenpluginapi/SConscript | 2 +- source/blender/gpu/SConscript | 2 +- source/blender/imbuf/intern/cineon/SConscript | 2 +- source/blender/imbuf/intern/dds/SConscript | 2 +- source/blender/makesdna/SConscript | 2 +- source/blender/python/SConscript | 4 +- source/blender/readblenfile/SConscript | 2 +- source/blenderplayer/CMakeLists.txt | 143 +++++++++++++++ .../bad_level_call_stubs/CMakeLists.txt | 40 +++++ source/blenderplayer/bad_level_call_stubs/Makefile | 45 +++++ .../blenderplayer/bad_level_call_stubs/SConscript | 13 ++ source/blenderplayer/bad_level_call_stubs/stubs.c | 200 +++++++++++++++++++++ source/gameengine/BlenderRoutines/SConscript | 2 +- source/gameengine/Converter/SConscript | 2 +- source/gameengine/Expressions/SConscript | 2 +- source/gameengine/GameLogic/SConscript | 2 +- source/gameengine/GamePlayer/common/SConscript | 2 +- source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 3 + source/gameengine/GamePlayer/ghost/SConscript | 2 +- source/gameengine/Ketsji/KXNetwork/SConscript | 2 +- source/gameengine/Ketsji/SConscript | 2 +- .../gameengine/Network/LoopBackNetwork/SConscript | 2 +- source/gameengine/Network/SConscript | 2 +- source/gameengine/Physics/Bullet/SConscript | 2 +- source/gameengine/Physics/Dummy/SConscript | 2 +- source/gameengine/Physics/common/SConscript | 2 +- .../Rasterizer/RAS_OpenGLRasterizer/SConscript | 2 +- source/gameengine/Rasterizer/SConscript | 2 +- source/gameengine/SceneGraph/SConscript | 2 +- source/gameengine/VideoTexture/SConscript | 2 +- source/kernel/SConscript | 2 +- 45 files changed, 484 insertions(+), 476 deletions(-) delete mode 100644 blenderplayer/CMakeLists.txt delete mode 100644 blenderplayer/bad_level_call_stubs/CMakeLists.txt delete mode 100644 blenderplayer/bad_level_call_stubs/Makefile delete mode 100644 blenderplayer/bad_level_call_stubs/SConscript delete mode 100644 blenderplayer/bad_level_call_stubs/stubs.c create mode 100644 source/blenderplayer/CMakeLists.txt create mode 100644 source/blenderplayer/bad_level_call_stubs/CMakeLists.txt create mode 100644 source/blenderplayer/bad_level_call_stubs/Makefile create mode 100644 source/blenderplayer/bad_level_call_stubs/SConscript create mode 100644 source/blenderplayer/bad_level_call_stubs/stubs.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 529d65b0dfe..5000ecfac5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -574,6 +574,6 @@ ADD_SUBDIRECTORY(source/creator) #----------------------------------------------------------------------------- # Blender Player IF(WITH_PLAYER) - ADD_SUBDIRECTORY(blenderplayer) + ADD_SUBDIRECTORY(source/blenderplayer) ENDIF(WITH_PLAYER) diff --git a/SConstruct b/SConstruct index a66587695f3..b3291c37e1a 100644 --- a/SConstruct +++ b/SConstruct @@ -390,7 +390,7 @@ SConscript(B.root_build_dir+'/source/SConscript') # libraries to give as objects to linking phase mainlist = [] for tp in B.possible_types: - if not tp == 'player' and not tp == 'player2': + if not tp == 'player': mainlist += B.create_blender_liblist(env, tp) if B.arguments.get('BF_PRIORITYLIST', '0')=='1': @@ -404,6 +404,7 @@ if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') + playerlist = playerlist[0:2] + [playerlist[3]] + mainlist[2:] + [playerlist[29]] env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') ##### Now define some targets diff --git a/blenderplayer/CMakeLists.txt b/blenderplayer/CMakeLists.txt deleted file mode 100644 index 030d9dbbba0..00000000000 --- a/blenderplayer/CMakeLists.txt +++ /dev/null @@ -1,143 +0,0 @@ -# $Id$ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -MESSAGE(STATUS "Configuring blenderplayer") - -SETUP_LIBDIRS() - -IF(WITH_QUICKTIME) - ADD_DEFINITIONS(-DWITH_QUICKTIME) -ENDIF(WITH_QUICKTIME) - -IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - ADD_DEFINITIONS(-DWITH_BINRELOC) - INCLUDE_DIRECTORIES(${BINRELOC_INC}) -ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") - -ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c - COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ - DEPENDS ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna -) - -IF(WIN32) - ADD_EXECUTABLE(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../source/icons/winblender.rc) -ELSE(WIN32) - ADD_EXECUTABLE(blenderplayer ${CMAKE_CURRENT_BINARY_DIR}/dna.c) -ENDIF(WIN32) - -ADD_DEPENDENCIES(blenderplayer makesdna) - -FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS) - -SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} gp_common gp_ghost blenkernel_blc) - -IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc) -ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") - -IF(UNIX) - # Sort libraries - SET(BLENDER_SORTED_LIBS - gp_ghost - gp_common - bf_string - bf_ghost - bf_blenkernel - bf_blenloader - bf_blenpluginapi - bf_blroutines - bf_converter - bf_ketsji - bf_bullet - bf_common - bf_dummy - bf_logic - bf_rasterizer - bf_oglrasterizer - bf_expressions - bf_scenegraph - bf_IK - bf_moto - bf_kernel - bf_nodes - bf_gpu - bf_imbuf - bf_avi - kx_network - bf_ngnetwork - bf_loopbacknetwork - extern_bullet - bf_guardedalloc - bf_memutil - bf_python - bf_gen_python - bf_blenlib - bf_cineon - bf_openexr - extern_libopenjpeg - bf_dds - bf_readblenfile - bf_dna - bf_rna - bf_blenfont - bf_audaspace - blenkernel_blc - extern_binreloc - extern_glew - ) - - IF(WITH_QUICKTIME) - SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} quicktime) - ENDIF(WITH_QUICKTIME) - - IF(WITH_CXX_GUARDEDALLOC) - SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_guardedalloc_cpp) - ENDIF(WITH_CXX_GUARDEDALLOC) - - FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) - SET(REMLIB ${SORTLIB}) - FOREACH(SEARCHLIB ${BLENDER_LINK_LIBS}) - IF(${SEARCHLIB} STREQUAL ${SORTLIB}) - SET(REMLIB "") - ENDIF(${SEARCHLIB} STREQUAL ${SORTLIB}) - ENDFOREACH(SEARCHLIB) - IF(REMLIB) - MESSAGE(STATUS "Removing library ${REMLIB} from blenderplayer linking because: not configured") - LIST(REMOVE_ITEM BLENDER_SORTED_LIBS ${REMLIB}) - ENDIF(REMLIB) - ENDFOREACH(SORTLIB) - - TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_SORTED_LIBS}) -ELSE(UNIX) - TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_LINK_LIBS}) -ENDIF(UNIX) - -IF(WITH_PLAYER) - ADD_SUBDIRECTORY(bad_level_call_stubs) -ENDIF(WITH_PLAYER) - -SETUP_LIBLINKS(blenderplayer) diff --git a/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/blenderplayer/bad_level_call_stubs/CMakeLists.txt deleted file mode 100644 index abb086b072a..00000000000 --- a/blenderplayer/bad_level_call_stubs/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# $Id$ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -FILE(GLOB SRC stubs.c) - -SET(INC - . - .. - ../../source/blender/makesdna - ../../source/blender/makesrna -) - -IF(WITH_INTERNATIONAL) - ADD_DEFINITIONS(-DWITH_FREETYPE2) -ENDIF(WITH_INTERNATIONAL) - -BLENDERLIB_NOLIST(blenkernel_blc "${SRC}" "${INC}") diff --git a/blenderplayer/bad_level_call_stubs/Makefile b/blenderplayer/bad_level_call_stubs/Makefile deleted file mode 100644 index 1d9f6a27327..00000000000 --- a/blenderplayer/bad_level_call_stubs/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# - -LIBNAME = blenkernel_blc -DIR = $(OCGDIR)/blenderplayer/$(LIBNAME) - -include nan_compile.mk - -CFLAGS += $(LEVEL_2_C_WARNINGS) -CFLAGS += $(FIX_STUBS_WARNINGS) - -CPPFLAGS += $(OGL_CPPFLAGS) -CPPFLAGS += -I../../source/blender/makesdna -CPPFLAGS += -I../../source/blender/makesrna - -# path to our own external headerfiles -CPPFLAGS += -I.. - diff --git a/blenderplayer/bad_level_call_stubs/SConscript b/blenderplayer/bad_level_call_stubs/SConscript deleted file mode 100644 index bd3df38b557..00000000000 --- a/blenderplayer/bad_level_call_stubs/SConscript +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/python -Import ('env') - -sources = 'stubs.c' - -incs = '. ..' -incs += '../../source/blender/makesdna' -incs += '../../source/blender/makesrna' - -defs = '' -if env['WITH_BF_INTERNATIONAL']: - defs += 'WITH_FREETYPE2' - -env.BlenderLib ('blenkernel_blc', sources = Split(sources), includes=Split(incs), defines=Split(defs), libtype='player',priority=225 ) diff --git a/blenderplayer/bad_level_call_stubs/stubs.c b/blenderplayer/bad_level_call_stubs/stubs.c deleted file mode 100644 index 5ddafca5340..00000000000 --- a/blenderplayer/bad_level_call_stubs/stubs.c +++ /dev/null @@ -1,200 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * BKE_bad_level_calls function stubs - */ - -#include -#include "DNA_listBase.h" -#include "RNA_types.h" - -/*new render funcs */ -float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype) {return NULL;} -float RE_filter_value(int type, float x) {return 0.0f;} -struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name) {return (struct RenderLayer *)NULL;} - -/* zbuf.c stub */ -void antialias_tagbuf(int xsize, int ysize, char *rectmove) {} -void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect) {} - -/* imagetexture.c stub */ -void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) {} - -/* texture.c */ -int multitex_thread(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, short thread, short which_output) {return 0;} -int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres){return 0;} - -/* nodes */ -struct RenderResult *RE_GetResult(struct Render *re){return (struct RenderResult *) NULL;} -struct Render *RE_GetRender(const char *name){return (struct Render *) NULL;} - -/* blenkernel */ -char* btempdir(){return NULL;} -void RE_FreeRenderResult(struct RenderResult *res){} -char* datatoc_bmonofont_ttf(){return NULL;} -int datatoc_bmonofont_ttf_size(){return 0;} -struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty){return (struct RenderResult *) NULL;} -void RE_GetResultImage(struct Render *re, struct RenderResult *rr){} -int RE_RenderInProgress(struct Render *re){return 0;} -struct Scene *RE_GetScene(struct Render *re){return (struct Scene *) NULL;} -void RE_Database_Free(struct Render *re){} -void RE_FreeRender(struct Render *re){} -void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr){} -void RE_DataBase_GetView(struct Render *re, float mat[][4]){} -int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){return 0;} -float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip){return 0.0f;} -void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype){} -char stipple_quarttone[1]; //GLubyte stipple_quarttone[128] -double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, char *retstr) {return 0.0f;} - -/* rna */ -void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference){} -void ED_armature_bone_rename(struct bArmature *arm, char *oldnamep, char *newnamep){} -void object_test_constraints (struct Object *owner){} -void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr){} -void ED_node_composit_default(struct Scene *sce){} - -struct EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, struct EditBone *ebo){return (struct EditBone *) NULL;} -struct ListBase *get_active_constraints (struct Object *ob){return (struct ListBase *) NULL;} -int ED_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan){return 0;} - -int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit){return 0;} -int ED_space_image_show_render(struct SpaceImage *sima){return 0;} -int ED_space_image_show_paint(struct SpaceImage *sima){return 0;} -void ED_space_image_set(struct bContext *C, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima){} -struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBuf *) NULL;} - -struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob){return (struct PTCacheEdit *) NULL;} - -/* rna editors */ -char *ED_info_stats_string(struct Scene *scene){return NULL;} -void ED_area_tag_redraw(struct ScrArea *sa){} -void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op){} -void ED_node_texture_default(struct Tex *tx){} -int text_file_modified(struct Text *text){return 0;} -void ED_node_shader_default(struct Material *ma){} -void ED_screen_animation_timer_update(struct bContext *C, int redraws){} -int ED_object_modifier_remove(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md){return 0;} -int ED_object_modifier_add(struct ReportList *reports, struct Scene *scene, struct Object *ob, int type){return 0;} -int uiLayoutGetActive(struct uiLayout *layout){return 0;} -int uiLayoutGetOperatorContext(struct uiLayout *layout){return 0;} -int uiLayoutGetAlignment(struct uiLayout *layout){return 0;} -int uiLayoutGetEnabled(struct uiLayout *layout){return 0;} -float uiLayoutGetScaleX(struct uiLayout *layout){return 0.0f;} -float uiLayoutGetScaleY(struct uiLayout *layout){return 0.0f;} -void uiLayoutSetActive(struct uiLayout *layout, int active){} -void uiLayoutSetOperatorContext(struct uiLayout *layout, int opcontext){} -void uiLayoutSetEnabled(struct uiLayout *layout, int enabled){} -void uiLayoutSetAlignment(struct uiLayout *layout, int alignment){} -void uiLayoutSetScaleX(struct uiLayout *layout, float scale){} -void uiLayoutSetScaleY(struct uiLayout *layout, float scale){} - -void uiItemR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int flag){} - -PointerRNA uiItemFullO(struct uiLayout *layout, char *name, int icon, char *idname, struct IDProperty *properties, int context, int flag){PointerRNA a; return a;} -struct uiLayout *uiLayoutRow(struct uiLayout *layout, int align){return (struct uiLayout *) NULL;} -struct uiLayout *uiLayoutColumn(struct uiLayout *layout, int align){return (struct uiLayout *) NULL;} -struct uiLayout *uiLayoutColumnFlow(struct uiLayout *layout, int number, int align){return (struct uiLayout *) NULL;} -struct uiLayout *uiLayoutBox(struct uiLayout *layout){return (struct uiLayout *) NULL;} -struct uiLayout *uiLayoutSplit(struct uiLayout *layout, float percentage){return (struct uiLayout *) NULL;} -void uiItemsEnumR(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} -void uiItemMenuEnumR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname){} -void uiItemEnumR_string(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value){} -void uiItemPointerR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname){} -void uiItemsEnumO(struct uiLayout *layout, char *opname, char *propname){} -void uiItemEnumO_string(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value_str){} -void uiItemMenuEnumO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname){} -void uiItemBooleanO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} -void uiItemIntO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} -void uiItemFloatO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, float value){} -void uiItemStringO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value){} -void uiItemL(struct uiLayout *layout, char *name, int icon){} -void uiItemM(struct uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname){} -void uiItemS(struct uiLayout *layout){} -void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct PointerRNA *ptr){} - -/* rna template */ -void uiTemplateHeader(struct uiLayout *layout, struct bContext *C, int menus){} -void uiTemplateID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *unlinkop){} -struct uiLayout *uiTemplateModifier(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;} -struct uiLayout *uiTemplateConstraint(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;} -void uiTemplatePreview(struct uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot){} -void uiTemplateCurveMapping(struct uiLayout *layout, struct CurveMapping *cumap, int type, int compact){} -void uiTemplateColorRamp(struct uiLayout *layout, struct ColorBand *coba, int expand){} -void uiTemplateLayers(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} -void uiTemplateTriColorSet(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} -void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser){} -ListBase uiTemplateList(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activepropname, int rows, int listtype){struct ListBase b = {0,0}; return b;} -void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C){} -void uiTemplateOperatorSearch(struct uiLayout *layout){} -void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C){} -void uiTemplate_view3d_select_faceselmenu(struct uiLayout *layout, struct bContext *C){} -void uiTemplateTextureImage(struct uiLayout *layout, struct bContext *C, struct Tex *tex){} - -/* rna render */ -struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;} -void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result){} -void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result){} -void RE_engine_update_stats(struct RenderEngine *engine, char *stats, char *info){} -void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, char *filename){} -void RE_result_load_from_file(struct RenderResult *result, struct ReportList *reports, char *filename){} -int RE_engine_test_break(struct RenderEngine *engine){return 0;} - -/* python */ -struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} -struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;} -struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;} -int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;} -int WM_operatortype_remove(const char *idname){return 0;} -void WM_operator_properties_free(struct PointerRNA *ptr){} -void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){} -void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){} -void WM_operator_bl_idname(char *to, const char *from){} -short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;} - -/* smoke */ -void lzo1x_1_compress(void) {return;}; -void LzmaCompress(void) {return;}; -void smoke_export(void) {return;}; -void lzo1x_decompress(void) {return;}; -void LzmaUncompress(void) {return;}; -void smoke_init(void) {return;}; -void smoke_turbulence_init(void) {return;}; -void smoke_turbulence_initBlenderRNA(void) {return;}; -void smoke_initBlenderRNA(void) {return;}; -void smoke_free(void) {return;}; -void smoke_turbulence_free(void) {return;}; -void smoke_turbulence_step(void) {return;}; -void smoke_dissolve(void) {return;}; -void smoke_get_density(void) {return;}; -void smoke_get_heat(void) {return;}; -void smoke_get_velocity_x(void) {return;}; -void smoke_get_velocity_y(void) {return;}; -void smoke_get_velocity_z(void) {return;}; -void smoke_get_obstacle(void) {return;}; -void smoke_get_index(void) {return;}; -void smoke_step(void) {return;}; diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript index 0184ddd9785..a93e12bebda 100644 --- a/intern/guardedalloc/SConscript +++ b/intern/guardedalloc/SConscript @@ -5,4 +5,4 @@ Import('env') sources = env.Glob('intern/*.c') incs = '.' -env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern', 'player'], priority = [5, 175] ) +env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern', 'player'], priority = [5, 130] ) diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript index 4528de814f3..3e15dde8855 100644 --- a/intern/memutil/SConscript +++ b/intern/memutil/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp') incs = '. ..' -env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern', 'player'], priority = [0, 180] ) +env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern', 'player'], priority = [0, 135] ) diff --git a/source/SConscript b/source/SConscript index d3a9373b4d8..e4e89671653 100644 --- a/source/SConscript +++ b/source/SConscript @@ -6,6 +6,9 @@ SConscript(['blender/SConscript', 'creator/SConscript']) if env['WITH_BF_GAMEENGINE']: SConscript (['gameengine/SConscript']) - + +if env['WITH_BF_PLAYER']: + SConscript (['blenderplayer/bad_level_call_stubs/SConscript']) + if env['OURPLATFORM'] in ('win64-vc', 'win32-vc', 'win32-mingw'): SConscript (['icons/SConscript']) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 0c7922de6ff..a5bb843cbef 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -65,4 +65,4 @@ if env['WITH_BF_LCMS']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [165] ) +env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [165,137] ) diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 3d7d6b63e64..b6c549fd145 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -16,4 +16,4 @@ if env['OURPLATFORM'] == 'linux2': if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core'], priority = [180], compileflags =cflags ) +env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core','player'], priority = [180,120], compileflags =cflags ) diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 3c441a81d6b..acf236d382b 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -54,6 +54,8 @@ #include "BKE_utildefines.h" + + #ifdef HAVE_CONFIG_H #include #endif diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 19a89b7e604..1bc834ab9f4 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -11,4 +11,4 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] -env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [135, 30] ) +env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [135, 20] ) diff --git a/source/blender/blenpluginapi/SConscript b/source/blender/blenpluginapi/SConscript index 776c188d73b..af69b4519b4 100644 --- a/source/blender/blenpluginapi/SConscript +++ b/source/blender/blenpluginapi/SConscript @@ -11,4 +11,4 @@ if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ' + env['BF_QUICKTIME_INC'] -env.BlenderLib ( libname = 'bf_blenpluginapi', sources = sources, includes = Split(incs), defines = defs, libtype=['core', 'player'], priority = [170, 35] ) +env.BlenderLib ( libname = 'bf_blenpluginapi', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [170] ) diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index 63f5fe53238..d40f3a97874 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -8,4 +8,4 @@ incs += ' #/extern/glew/include #intern/guardedalloc ../imbuf .' incs += ' ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core', 'player'], priority=[160, 20] ) +env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core', 'player'], priority=[160, 35] ) diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript index ef9c44b85c8..371e4cff9eb 100644 --- a/source/blender/imbuf/intern/cineon/SConscript +++ b/source/blender/imbuf/intern/cineon/SConscript @@ -14,4 +14,4 @@ incs = ['.', defs = [] -env.BlenderLib ('bf_cineon', source_files, incs, defs, libtype=['core','player'], priority = [220, 75]) +env.BlenderLib ('bf_cineon', source_files, incs, defs, libtype=['core'], priority = [220]) diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript index cec6023648b..6cabc3f7d79 100644 --- a/source/blender/imbuf/intern/dds/SConscript +++ b/source/blender/imbuf/intern/dds/SConscript @@ -16,4 +16,4 @@ incs = ['.', defs = ['WITH_DDS'] -env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core','player'], priority = [230, 105]) +env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core'], priority = [230]) diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript index f91cf166f62..6d96811e1cb 100644 --- a/source/blender/makesdna/SConscript +++ b/source/blender/makesdna/SConscript @@ -8,4 +8,4 @@ objs += o incs = '#/intern/guardedalloc .' -env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core','player'], priority = [215, 215] ) +env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core','player'], priority = [215, 140] ) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index d44cf762a0f..c681c5bdc39 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -13,9 +13,9 @@ defs = [] if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [140]) +env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [140,10]) # generic sources = env.Glob('generic/*.c') -env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) # ketsji is 360 +env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [361,85]) # ketsji is 360 diff --git a/source/blender/readblenfile/SConscript b/source/blender/readblenfile/SConscript index 59771aa0829..534ab0f7d4c 100644 --- a/source/blender/readblenfile/SConscript +++ b/source/blender/readblenfile/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.c') incs = '. ../blenloader ../blenloader/intern ../blenkernel ../blenlib ../makesdna ../../kernel/gen_messaging' -env.BlenderLib ( 'bf_readblenfile', sources, Split(incs), [], libtype=['core','player'], priority = [0, 220] ) +env.BlenderLib ( 'bf_readblenfile', sources, Split(incs), [], libtype=['core','player'], priority = [0, 0] ) diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt new file mode 100644 index 00000000000..030d9dbbba0 --- /dev/null +++ b/source/blenderplayer/CMakeLists.txt @@ -0,0 +1,143 @@ +# $Id$ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +MESSAGE(STATUS "Configuring blenderplayer") + +SETUP_LIBDIRS() + +IF(WITH_QUICKTIME) + ADD_DEFINITIONS(-DWITH_QUICKTIME) +ENDIF(WITH_QUICKTIME) + +IF(CMAKE_SYSTEM_NAME MATCHES "Linux") + ADD_DEFINITIONS(-DWITH_BINRELOC) + INCLUDE_DIRECTORIES(${BINRELOC_INC}) +ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") + +ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c + COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ + DEPENDS ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna +) + +IF(WIN32) + ADD_EXECUTABLE(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../source/icons/winblender.rc) +ELSE(WIN32) + ADD_EXECUTABLE(blenderplayer ${CMAKE_CURRENT_BINARY_DIR}/dna.c) +ENDIF(WIN32) + +ADD_DEPENDENCIES(blenderplayer makesdna) + +FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS) + +SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} gp_common gp_ghost blenkernel_blc) + +IF(CMAKE_SYSTEM_NAME MATCHES "Linux") + SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc) +ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") + +IF(UNIX) + # Sort libraries + SET(BLENDER_SORTED_LIBS + gp_ghost + gp_common + bf_string + bf_ghost + bf_blenkernel + bf_blenloader + bf_blenpluginapi + bf_blroutines + bf_converter + bf_ketsji + bf_bullet + bf_common + bf_dummy + bf_logic + bf_rasterizer + bf_oglrasterizer + bf_expressions + bf_scenegraph + bf_IK + bf_moto + bf_kernel + bf_nodes + bf_gpu + bf_imbuf + bf_avi + kx_network + bf_ngnetwork + bf_loopbacknetwork + extern_bullet + bf_guardedalloc + bf_memutil + bf_python + bf_gen_python + bf_blenlib + bf_cineon + bf_openexr + extern_libopenjpeg + bf_dds + bf_readblenfile + bf_dna + bf_rna + bf_blenfont + bf_audaspace + blenkernel_blc + extern_binreloc + extern_glew + ) + + IF(WITH_QUICKTIME) + SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} quicktime) + ENDIF(WITH_QUICKTIME) + + IF(WITH_CXX_GUARDEDALLOC) + SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_guardedalloc_cpp) + ENDIF(WITH_CXX_GUARDEDALLOC) + + FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) + SET(REMLIB ${SORTLIB}) + FOREACH(SEARCHLIB ${BLENDER_LINK_LIBS}) + IF(${SEARCHLIB} STREQUAL ${SORTLIB}) + SET(REMLIB "") + ENDIF(${SEARCHLIB} STREQUAL ${SORTLIB}) + ENDFOREACH(SEARCHLIB) + IF(REMLIB) + MESSAGE(STATUS "Removing library ${REMLIB} from blenderplayer linking because: not configured") + LIST(REMOVE_ITEM BLENDER_SORTED_LIBS ${REMLIB}) + ENDIF(REMLIB) + ENDFOREACH(SORTLIB) + + TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_SORTED_LIBS}) +ELSE(UNIX) + TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_LINK_LIBS}) +ENDIF(UNIX) + +IF(WITH_PLAYER) + ADD_SUBDIRECTORY(bad_level_call_stubs) +ENDIF(WITH_PLAYER) + +SETUP_LIBLINKS(blenderplayer) diff --git a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt new file mode 100644 index 00000000000..abb086b072a --- /dev/null +++ b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt @@ -0,0 +1,40 @@ +# $Id$ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +FILE(GLOB SRC stubs.c) + +SET(INC + . + .. + ../../source/blender/makesdna + ../../source/blender/makesrna +) + +IF(WITH_INTERNATIONAL) + ADD_DEFINITIONS(-DWITH_FREETYPE2) +ENDIF(WITH_INTERNATIONAL) + +BLENDERLIB_NOLIST(blenkernel_blc "${SRC}" "${INC}") diff --git a/source/blenderplayer/bad_level_call_stubs/Makefile b/source/blenderplayer/bad_level_call_stubs/Makefile new file mode 100644 index 00000000000..1d9f6a27327 --- /dev/null +++ b/source/blenderplayer/bad_level_call_stubs/Makefile @@ -0,0 +1,45 @@ +# +# $Id$ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL LICENSE BLOCK ***** +# +# + +LIBNAME = blenkernel_blc +DIR = $(OCGDIR)/blenderplayer/$(LIBNAME) + +include nan_compile.mk + +CFLAGS += $(LEVEL_2_C_WARNINGS) +CFLAGS += $(FIX_STUBS_WARNINGS) + +CPPFLAGS += $(OGL_CPPFLAGS) +CPPFLAGS += -I../../source/blender/makesdna +CPPFLAGS += -I../../source/blender/makesrna + +# path to our own external headerfiles +CPPFLAGS += -I.. + diff --git a/source/blenderplayer/bad_level_call_stubs/SConscript b/source/blenderplayer/bad_level_call_stubs/SConscript new file mode 100644 index 00000000000..ce502af57be --- /dev/null +++ b/source/blenderplayer/bad_level_call_stubs/SConscript @@ -0,0 +1,13 @@ +#!/usr/bin/python +Import ('env') + +sources = 'stubs.c' + +incs = '#/source/blender/makesdna' +incs += ' #/source/blender/makesrna' + +defs = '' +if env['WITH_BF_INTERNATIONAL']: + defs += 'WITH_FREETYPE2' + +env.BlenderLib ('blenkernel_blc', sources = Split(sources), includes=Split(incs), defines=Split(defs), libtype=['player'],priority=[145] ) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c new file mode 100644 index 00000000000..5ddafca5340 --- /dev/null +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -0,0 +1,200 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * BKE_bad_level_calls function stubs + */ + +#include +#include "DNA_listBase.h" +#include "RNA_types.h" + +/*new render funcs */ +float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype) {return NULL;} +float RE_filter_value(int type, float x) {return 0.0f;} +struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name) {return (struct RenderLayer *)NULL;} + +/* zbuf.c stub */ +void antialias_tagbuf(int xsize, int ysize, char *rectmove) {} +void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect) {} + +/* imagetexture.c stub */ +void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) {} + +/* texture.c */ +int multitex_thread(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, short thread, short which_output) {return 0;} +int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres){return 0;} + +/* nodes */ +struct RenderResult *RE_GetResult(struct Render *re){return (struct RenderResult *) NULL;} +struct Render *RE_GetRender(const char *name){return (struct Render *) NULL;} + +/* blenkernel */ +char* btempdir(){return NULL;} +void RE_FreeRenderResult(struct RenderResult *res){} +char* datatoc_bmonofont_ttf(){return NULL;} +int datatoc_bmonofont_ttf_size(){return 0;} +struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty){return (struct RenderResult *) NULL;} +void RE_GetResultImage(struct Render *re, struct RenderResult *rr){} +int RE_RenderInProgress(struct Render *re){return 0;} +struct Scene *RE_GetScene(struct Render *re){return (struct Scene *) NULL;} +void RE_Database_Free(struct Render *re){} +void RE_FreeRender(struct Render *re){} +void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr){} +void RE_DataBase_GetView(struct Render *re, float mat[][4]){} +int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){return 0;} +float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip){return 0.0f;} +void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype){} +char stipple_quarttone[1]; //GLubyte stipple_quarttone[128] +double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, char *retstr) {return 0.0f;} + +/* rna */ +void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference){} +void ED_armature_bone_rename(struct bArmature *arm, char *oldnamep, char *newnamep){} +void object_test_constraints (struct Object *owner){} +void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr){} +void ED_node_composit_default(struct Scene *sce){} + +struct EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, struct EditBone *ebo){return (struct EditBone *) NULL;} +struct ListBase *get_active_constraints (struct Object *ob){return (struct ListBase *) NULL;} +int ED_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan){return 0;} + +int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit){return 0;} +int ED_space_image_show_render(struct SpaceImage *sima){return 0;} +int ED_space_image_show_paint(struct SpaceImage *sima){return 0;} +void ED_space_image_set(struct bContext *C, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima){} +struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBuf *) NULL;} + +struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob){return (struct PTCacheEdit *) NULL;} + +/* rna editors */ +char *ED_info_stats_string(struct Scene *scene){return NULL;} +void ED_area_tag_redraw(struct ScrArea *sa){} +void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op){} +void ED_node_texture_default(struct Tex *tx){} +int text_file_modified(struct Text *text){return 0;} +void ED_node_shader_default(struct Material *ma){} +void ED_screen_animation_timer_update(struct bContext *C, int redraws){} +int ED_object_modifier_remove(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md){return 0;} +int ED_object_modifier_add(struct ReportList *reports, struct Scene *scene, struct Object *ob, int type){return 0;} +int uiLayoutGetActive(struct uiLayout *layout){return 0;} +int uiLayoutGetOperatorContext(struct uiLayout *layout){return 0;} +int uiLayoutGetAlignment(struct uiLayout *layout){return 0;} +int uiLayoutGetEnabled(struct uiLayout *layout){return 0;} +float uiLayoutGetScaleX(struct uiLayout *layout){return 0.0f;} +float uiLayoutGetScaleY(struct uiLayout *layout){return 0.0f;} +void uiLayoutSetActive(struct uiLayout *layout, int active){} +void uiLayoutSetOperatorContext(struct uiLayout *layout, int opcontext){} +void uiLayoutSetEnabled(struct uiLayout *layout, int enabled){} +void uiLayoutSetAlignment(struct uiLayout *layout, int alignment){} +void uiLayoutSetScaleX(struct uiLayout *layout, float scale){} +void uiLayoutSetScaleY(struct uiLayout *layout, float scale){} + +void uiItemR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int flag){} + +PointerRNA uiItemFullO(struct uiLayout *layout, char *name, int icon, char *idname, struct IDProperty *properties, int context, int flag){PointerRNA a; return a;} +struct uiLayout *uiLayoutRow(struct uiLayout *layout, int align){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutColumn(struct uiLayout *layout, int align){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutColumnFlow(struct uiLayout *layout, int number, int align){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutBox(struct uiLayout *layout){return (struct uiLayout *) NULL;} +struct uiLayout *uiLayoutSplit(struct uiLayout *layout, float percentage){return (struct uiLayout *) NULL;} +void uiItemsEnumR(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} +void uiItemMenuEnumR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname){} +void uiItemEnumR_string(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value){} +void uiItemPointerR(struct uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname){} +void uiItemsEnumO(struct uiLayout *layout, char *opname, char *propname){} +void uiItemEnumO_string(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value_str){} +void uiItemMenuEnumO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname){} +void uiItemBooleanO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} +void uiItemIntO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, int value){} +void uiItemFloatO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, float value){} +void uiItemStringO(struct uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value){} +void uiItemL(struct uiLayout *layout, char *name, int icon){} +void uiItemM(struct uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname){} +void uiItemS(struct uiLayout *layout){} +void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct PointerRNA *ptr){} + +/* rna template */ +void uiTemplateHeader(struct uiLayout *layout, struct bContext *C, int menus){} +void uiTemplateID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *unlinkop){} +struct uiLayout *uiTemplateModifier(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;} +struct uiLayout *uiTemplateConstraint(struct uiLayout *layout, struct PointerRNA *ptr){return (struct uiLayout *) NULL;} +void uiTemplatePreview(struct uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot){} +void uiTemplateCurveMapping(struct uiLayout *layout, struct CurveMapping *cumap, int type, int compact){} +void uiTemplateColorRamp(struct uiLayout *layout, struct ColorBand *coba, int expand){} +void uiTemplateLayers(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} +void uiTemplateTriColorSet(struct uiLayout *layout, struct PointerRNA *ptr, char *propname){} +void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser){} +ListBase uiTemplateList(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activepropname, int rows, int listtype){struct ListBase b = {0,0}; return b;} +void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C){} +void uiTemplateOperatorSearch(struct uiLayout *layout){} +void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C){} +void uiTemplate_view3d_select_faceselmenu(struct uiLayout *layout, struct bContext *C){} +void uiTemplateTextureImage(struct uiLayout *layout, struct bContext *C, struct Tex *tex){} + +/* rna render */ +struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;} +void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result){} +void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result){} +void RE_engine_update_stats(struct RenderEngine *engine, char *stats, char *info){} +void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, char *filename){} +void RE_result_load_from_file(struct RenderResult *result, struct ReportList *reports, char *filename){} +int RE_engine_test_break(struct RenderEngine *engine){return 0;} + +/* python */ +struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} +struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;} +struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;} +int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;} +int WM_operatortype_remove(const char *idname){return 0;} +void WM_operator_properties_free(struct PointerRNA *ptr){} +void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring){} +void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType*, void*), void *userdata){} +void WM_operator_bl_idname(char *to, const char *from){} +short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;} + +/* smoke */ +void lzo1x_1_compress(void) {return;}; +void LzmaCompress(void) {return;}; +void smoke_export(void) {return;}; +void lzo1x_decompress(void) {return;}; +void LzmaUncompress(void) {return;}; +void smoke_init(void) {return;}; +void smoke_turbulence_init(void) {return;}; +void smoke_turbulence_initBlenderRNA(void) {return;}; +void smoke_initBlenderRNA(void) {return;}; +void smoke_free(void) {return;}; +void smoke_turbulence_free(void) {return;}; +void smoke_turbulence_step(void) {return;}; +void smoke_dissolve(void) {return;}; +void smoke_get_density(void) {return;}; +void smoke_get_heat(void) {return;}; +void smoke_get_velocity_x(void) {return;}; +void smoke_get_velocity_y(void) {return;}; +void smoke_get_velocity_z(void) {return;}; +void smoke_get_obstacle(void) {return;}; +void smoke_get_index(void) {return;}; +void smoke_step(void) {return;}; diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index dc5a93a2e48..831f898853b 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -28,4 +28,4 @@ incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 45] , cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 25] , cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 9164a9f6d78..2d126310475 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -23,4 +23,4 @@ incs += ' #source/blender/makesrna' incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] -env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,50], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,40], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index dc9c184fd8a..51c3a0cc5af 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('*.cpp') incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,120], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,75], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index f259a338dc0..442420a8876 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -21,4 +21,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core','player'], priority=[330, 100], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core','player'], priority=[330, 50], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 3ac2576b46d..6f37c2f769e 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -62,4 +62,4 @@ incs += Split(env['BF_PYTHON_INC']) incs += Split(env['BF_PNG_INC']) incs += Split(env['BF_ZLIB_INC']) -env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype=['player'], priority=[15], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index d399d6b3443..b7677d29507 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -68,6 +68,9 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[]); +extern char bprogname[]; /* holds a copy of argv[0], from creator.c */ +extern char btempdir[]; /* use this to store a valid temp directory */ + #ifdef __cplusplus } #endif // __cplusplus diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index ce8b07b9393..6c71eafa1dc 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -46,4 +46,4 @@ defs = [] if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') -env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = defs, libtype='player',priority=5, cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = defs, libtype=['player'],priority=[5], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index ce4a29b9492..f2283f0b28d 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -9,4 +9,4 @@ incs += ' #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 100], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index ea9d32fa0bf..1f5df8dea00 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -33,4 +33,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['BF_DEBUG']: defs.append('_DEBUG') # for Python -env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320, 60], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320, 80], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript index be6545b4fd6..62b0a65a514 100644 --- a/source/gameengine/Network/LoopBackNetwork/SConscript +++ b/source/gameengine/Network/LoopBackNetwork/SConscript @@ -5,4 +5,4 @@ sources = 'NG_LoopBackNetworkDeviceInterface.cpp' incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Network' -env.BlenderLib ( 'bf_loopbacknetwork', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 155] ) +env.BlenderLib ( 'bf_loopbacknetwork', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 115] ) diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index 804851973af..297cfdb6748 100644 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_Netw incs = '. #source/kernel/gen_system #intern/string #intern/moto/include' -env.BlenderLib ( 'bf_ngnetwork', sources, Split(incs), [], libtype=['core', 'player'], priority=[400, 150] ) +env.BlenderLib ( 'bf_ngnetwork', sources, Split(incs), [], libtype=['core', 'player'], priority=[400, 110] ) diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index 0b797c2cb8b..1489e4c46f6 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -21,4 +21,4 @@ incs += ' #intern/guardedalloc' incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,80], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,70], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript index 93d6ac36446..cb4a09559be 100644 --- a/source/gameengine/Physics/Dummy/SConscript +++ b/source/gameengine/Physics/Dummy/SConscript @@ -5,4 +5,4 @@ sources = 'DummyPhysicsEnvironment.cpp' incs = '. ../common' -env.BlenderLib ( 'bf_dummy', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,95] ) +env.BlenderLib ( 'bf_dummy', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,55] ) diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index 8b373ec830c..bbf2d345a30 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/SConscript @@ -5,4 +5,4 @@ sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp P incs = '. ../Dummy #intern/moto/include' -env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_physics_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index 963c6616b64..851ec0c47c3 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -8,4 +8,4 @@ incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel' incs += ' #intern/guardedalloc #source/blender/blenlib' -env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 65], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index c2af14e8ce5..a1a1c7a4038 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -7,4 +7,4 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,60], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index 8f433a21e49..b7d8de450ab 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('*.cpp') incs = '. #intern/moto/include' -env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,125], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,45], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 583ccf29dbd..ada878b74f2 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -27,4 +27,4 @@ if env['WITH_BF_FFMPEG']: incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC'] defs.append('__STDC_CONSTANT_MACROS') -env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300, 72], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300, 30], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/kernel/SConscript b/source/kernel/SConscript index 908e059ceab..88fc58755c0 100644 --- a/source/kernel/SConscript +++ b/source/kernel/SConscript @@ -7,4 +7,4 @@ sources += ' gen_system/SYS_System.cpp' incs = 'gen_messaging gen_system #/intern/string #/intern/moto/include #/source/blender/blenloader ' -env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core', 'player'], priority = [400, 150] ) +env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core', 'player'], priority = [400, 95] ) -- cgit v1.2.3 From 1e6efcc96526a0d1ba16384c5500959ec9b5824d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 10:41:02 +0000 Subject: 2.5 - KeyingSet fixes * Fixed warnings in console about missing (removed) property * Fixed update problems after creating a new keyingset --- source/blender/editors/animation/keyingsets.c | 5 +++-- source/blender/editors/interface/interface_anim.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index a91a9bfa911..15d47211615 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -133,6 +133,7 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op) /* add path to this setting */ BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME); + success= 1; /* free the temp path created */ MEM_freeN(path); @@ -144,7 +145,7 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op) ED_anim_dag_flush_update(C); /* for now, only send ND_KEYS for KeyingSets */ - WM_event_add_notifier(C, ND_KEYS, NULL); + WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); } return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; @@ -222,7 +223,7 @@ static int remove_keyingset_button_exec (bContext *C, wmOperator *op) ED_anim_dag_flush_update(C); /* for now, only send ND_KEYS for KeyingSets */ - WM_event_add_notifier(C, ND_KEYS, NULL); + WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); } return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 8e15bbde201..8c41726b81b 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -283,11 +283,11 @@ void ui_but_anim_menu(bContext *C, uiBut *but) if(length) { uiItemBooleanO(layout, "Add All to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 1); uiItemBooleanO(layout, "Add Single to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 0); - uiItemBooleanO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button", "all", 0); + uiItemO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button"); } else { uiItemBooleanO(layout, "Add to Keying Set", 0, "ANIM_OT_add_keyingset_button", "all", 0); - uiItemBooleanO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button", "all", 0); + uiItemO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button"); } } -- cgit v1.2.3 From 0e40abf642b4360212b72791a01b4e7fe0cfacf5 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 11:19:12 +0000 Subject: 2.5 - Patches + Cleanups * Some of the patches in patch #19034 - by Wolfgang W. (bender) - outliner.patch - a small fix to make the outliner draw the last line of the list, if the list is bigger than the window. - scroll.patch - enables vertical scrolling in the buttons window in horizontal mode. Necessary if a panel is opened that is higher than the buttons window. * Also, fixed some messy comments in drivers code --- source/blender/editors/animation/drivers.c | 28 ++++++++++++------------ source/blender/editors/screen/area.c | 9 ++++++-- source/blender/editors/space_outliner/outliner.c | 3 +++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 8349b7f9bde..8b9224511ba 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -151,33 +151,33 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla /* create F-Curve with Driver */ fcu= verify_driver_fcurve(id, rna_path, array_index, 1); - if(fcu && fcu->driver) { + if (fcu && fcu->driver) { fcu->driver->type= type; - + /* fill in current value for python */ - if(type == DRIVER_TYPE_PYTHON) { + if (type == DRIVER_TYPE_PYTHON) { PropertyType proptype= RNA_property_type(prop); int array= RNA_property_array_length(&ptr, prop); char *expression= fcu->driver->expression; int val, maxlen= sizeof(fcu->driver->expression); float fval; - - if(proptype == PROP_BOOLEAN) { + + if (proptype == PROP_BOOLEAN) { if(!array) val= RNA_property_boolean_get(&ptr, prop); else val= RNA_property_boolean_get_index(&ptr, prop, array_index); - + BLI_strncpy(expression, (val)? "True": "False", maxlen); } - else if(proptype == PROP_INT) { - if(!array) val= RNA_property_int_get(&ptr, prop); + else if (proptype == PROP_INT) { + if (!array) val= RNA_property_int_get(&ptr, prop); else val= RNA_property_int_get_index(&ptr, prop, array_index); - + BLI_snprintf(expression, maxlen, "%d", val); } - else if(proptype == PROP_FLOAT) { - if(!array) fval= RNA_property_float_get(&ptr, prop); + else if (proptype == PROP_FLOAT) { + if (!array) fval= RNA_property_float_get(&ptr, prop); else fval= RNA_property_float_get_index(&ptr, prop, array_index); - + BLI_snprintf(expression, maxlen, "%.3f", fval); } @@ -232,7 +232,7 @@ static int add_driver_button_exec (bContext *C, wmOperator *op) short success= 0; int a, index, length, all= RNA_boolean_get(op->ptr, "all"); - /* try to insert keyframe using property retrieved from UI */ + /* try to create driver using property retrieved from UI */ memset(&ptr, 0, sizeof(PointerRNA)); uiAnimContextProperty(C, &ptr, &prop, &index); @@ -294,7 +294,7 @@ static int remove_driver_button_exec (bContext *C, wmOperator *op) short success= 0; int a, index, length, all= RNA_boolean_get(op->ptr, "all"); - /* try to insert keyframe using property retrieved from UI */ + /* try to find driver using property retrieved from UI */ memset(&ptr, 0, sizeof(PointerRNA)); uiAnimContextProperty(C, &ptr, &prop, &index); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 8c55cccd6b0..9a116bf95c0 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1248,6 +1248,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex /* before setting the view */ if(vertical) { + /* only allow scrolling in vertical direction */ v2d->keepofs |= V2D_LOCKOFS_X|V2D_KEEPOFS_Y; v2d->keepofs &= ~(V2D_LOCKOFS_Y|V2D_KEEPOFS_X); @@ -1258,8 +1259,12 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex y= -y; } else { - v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X; - v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y); + /* for now, allow scrolling in both directions (since layouts are optimised for vertical, + * they often don't fit in horizontal layout) + */ + v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_LOCKOFS_Y|V2D_KEEPOFS_X|V2D_KEEPOFS_Y); + //v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X; + //v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y); // don't jump back when panels close or hide if(!newcontext) diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index e6cd9c0e448..a9a9a5dab5f 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -5288,6 +5288,9 @@ void draw_outliner(const bContext *C) sizex += OL_TOGW*3; } + /* tweak to display last line (when list bigger than window) */ + sizey += V2D_SCROLL_HEIGHT; + /* update size of tot-rect (extents of data/viewable area) */ UI_view2d_totRect_set(v2d, sizex, sizey); -- cgit v1.2.3 From 20f39ec7d81af22d30700b3dde28938facfb2588 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 12:56:30 +0000 Subject: == SCons == * further cleaning of 'player' stuff. Now only 3 libs are remaining, of which ideally the stubs lib will be fixed at some point, fading away into the dark history of not-so-nice code. The current blenderplayer part is still a little bit hackish, I'll see if I can find a better alternative, for now it works good enough. --- SConstruct | 2 +- extern/libredcode/SConscript | 4 ++-- intern/guardedalloc/SConscript | 2 +- intern/memutil/SConscript | 2 +- source/blender/blenkernel/SConscript | 2 +- source/blender/blenlib/SConscript | 2 +- source/blender/blenloader/SConscript | 2 +- source/blender/gpu/SConscript | 2 +- source/blender/imbuf/intern/openexr/SConscript | 2 +- source/blender/makesdna/SConscript | 2 +- source/blender/python/SConscript | 4 ++-- source/blender/readblenfile/SConscript | 2 +- source/gameengine/BlenderRoutines/SConscript | 2 +- source/gameengine/Converter/SConscript | 2 +- source/gameengine/Expressions/SConscript | 2 +- source/gameengine/GameLogic/SConscript | 2 +- source/gameengine/Ketsji/KXNetwork/SConscript | 2 +- source/gameengine/Ketsji/SConscript | 2 +- source/gameengine/Network/LoopBackNetwork/SConscript | 2 +- source/gameengine/Network/SConscript | 2 +- source/gameengine/Physics/Bullet/SConscript | 2 +- source/gameengine/Physics/Dummy/SConscript | 2 +- source/gameengine/Physics/common/SConscript | 2 +- source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript | 2 +- source/gameengine/Rasterizer/SConscript | 2 +- source/gameengine/SceneGraph/SConscript | 2 +- source/gameengine/VideoTexture/SConscript | 2 +- source/icons/SConscript | 2 +- source/kernel/SConscript | 2 +- 29 files changed, 31 insertions(+), 31 deletions(-) diff --git a/SConstruct b/SConstruct index b3291c37e1a..3227e15aaa3 100644 --- a/SConstruct +++ b/SConstruct @@ -404,7 +404,7 @@ if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') - playerlist = playerlist[0:2] + [playerlist[3]] + mainlist[2:] + [playerlist[29]] + playerlist = [mainlist[0]] + playerlist[0:2] + mainlist[2:] + [playerlist[2]] env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') ##### Now define some targets diff --git a/extern/libredcode/SConscript b/extern/libredcode/SConscript index 9fd25ad63c7..3fb78dbea0f 100644 --- a/extern/libredcode/SConscript +++ b/extern/libredcode/SConscript @@ -12,5 +12,5 @@ incs = '. ../libopenjpeg' env.BlenderLib ( libname='extern_redcode', sources=sources, includes=Split(incs), defines=[], - libtype=['core','intern','player'], - priority=[5, 5, 200], compileflags = []) + libtype=['core','intern'], + priority=[5, 5], compileflags = []) diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript index a93e12bebda..8927bef2efc 100644 --- a/intern/guardedalloc/SConscript +++ b/intern/guardedalloc/SConscript @@ -5,4 +5,4 @@ Import('env') sources = env.Glob('intern/*.c') incs = '.' -env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern', 'player'], priority = [5, 130] ) +env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern'], priority = [5] ) diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript index 3e15dde8855..55c314d5211 100644 --- a/intern/memutil/SConscript +++ b/intern/memutil/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp') incs = '. ..' -env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern', 'player'], priority = [0, 135] ) +env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern'], priority = [0] ) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index a5bb843cbef..0c7922de6ff 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -65,4 +65,4 @@ if env['WITH_BF_LCMS']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [165,137] ) +env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [165] ) diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index b6c549fd145..3d7d6b63e64 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -16,4 +16,4 @@ if env['OURPLATFORM'] == 'linux2': if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core','player'], priority = [180,120], compileflags =cflags ) +env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core'], priority = [180], compileflags =cflags ) diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 1bc834ab9f4..0a9b8d05747 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -11,4 +11,4 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] -env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [135, 20] ) +env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core'], priority = [135] ) diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index d40f3a97874..b45547e359c 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -8,4 +8,4 @@ incs += ' #/extern/glew/include #intern/guardedalloc ../imbuf .' incs += ' ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core', 'player'], priority=[160, 35] ) +env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core'], priority=[160] ) diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript index 30757db1cef..729619c963b 100644 --- a/source/blender/imbuf/intern/openexr/SConscript +++ b/source/blender/imbuf/intern/openexr/SConscript @@ -15,4 +15,4 @@ incs += Split(env['BF_OPENEXR_INC']) defs = ['WITH_OPENEXR'] -env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core','player'], priority = [225, 85]) +env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core'], priority = [225]) diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript index 6d96811e1cb..1cb61f59121 100644 --- a/source/blender/makesdna/SConscript +++ b/source/blender/makesdna/SConscript @@ -8,4 +8,4 @@ objs += o incs = '#/intern/guardedalloc .' -env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core','player'], priority = [215, 140] ) +env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core'], priority = [215] ) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index c681c5bdc39..d44cf762a0f 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -13,9 +13,9 @@ defs = [] if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [140,10]) +env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [140]) # generic sources = env.Glob('generic/*.c') -env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [361,85]) # ketsji is 360 +env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) # ketsji is 360 diff --git a/source/blender/readblenfile/SConscript b/source/blender/readblenfile/SConscript index 534ab0f7d4c..c8189501d4b 100644 --- a/source/blender/readblenfile/SConscript +++ b/source/blender/readblenfile/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.c') incs = '. ../blenloader ../blenloader/intern ../blenkernel ../blenlib ../makesdna ../../kernel/gen_messaging' -env.BlenderLib ( 'bf_readblenfile', sources, Split(incs), [], libtype=['core','player'], priority = [0, 0] ) +env.BlenderLib ( 'bf_readblenfile', sources, Split(incs), [], libtype=['core'], priority = [0] ) diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index 831f898853b..cfb5b0ef525 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -28,4 +28,4 @@ incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 25] , cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core'], priority=[300] , cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 2d126310475..bf2dfa5e659 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -23,4 +23,4 @@ incs += ' #source/blender/makesrna' incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] -env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,40], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core'], priority=[305], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 51c3a0cc5af..cbf33f39568 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('*.cpp') incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,75], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core'], priority = [360], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index 442420a8876..f456f4125ab 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -21,4 +21,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core','player'], priority=[330, 50], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core'], priority=[330], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index f2283f0b28d..6429bd76a37 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -9,4 +9,4 @@ incs += ' #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 100], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=[],libtype=['core'], priority=[400], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 1f5df8dea00..122b77e0173 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -33,4 +33,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['BF_DEBUG']: defs.append('_DEBUG') # for Python -env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320, 80], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core'], priority=[320], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript index 62b0a65a514..2c27ee707f0 100644 --- a/source/gameengine/Network/LoopBackNetwork/SConscript +++ b/source/gameengine/Network/LoopBackNetwork/SConscript @@ -5,4 +5,4 @@ sources = 'NG_LoopBackNetworkDeviceInterface.cpp' incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Network' -env.BlenderLib ( 'bf_loopbacknetwork', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 115] ) +env.BlenderLib ( 'bf_loopbacknetwork', Split(sources), Split(incs), defines=[],libtype=['core'], priority=[400] ) diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index 297cfdb6748..f584503e109 100644 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_Netw incs = '. #source/kernel/gen_system #intern/string #intern/moto/include' -env.BlenderLib ( 'bf_ngnetwork', sources, Split(incs), [], libtype=['core', 'player'], priority=[400, 110] ) +env.BlenderLib ( 'bf_ngnetwork', sources, Split(incs), [], libtype=['core'], priority=[400] ) diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index 1489e4c46f6..baba40bcdc7 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -21,4 +21,4 @@ incs += ' #intern/guardedalloc' incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,70], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core'], priority=[350], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript index cb4a09559be..f4444cf6746 100644 --- a/source/gameengine/Physics/Dummy/SConscript +++ b/source/gameengine/Physics/Dummy/SConscript @@ -5,4 +5,4 @@ sources = 'DummyPhysicsEnvironment.cpp' incs = '. ../common' -env.BlenderLib ( 'bf_dummy', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,55] ) +env.BlenderLib ( 'bf_dummy', Split(sources), Split(incs), [], libtype=['core'], priority=[350] ) diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index bbf2d345a30..b9adbd7210a 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/SConscript @@ -5,4 +5,4 @@ sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp P incs = '. ../Dummy #intern/moto/include' -env.BlenderLib ( 'bf_physics_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_physics_common', Split(sources), Split(incs), [], libtype=['core'], priority=[360], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index 851ec0c47c3..b1e5289c14c 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -8,4 +8,4 @@ incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel' incs += ' #intern/guardedalloc #source/blender/blenlib' -env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 65], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core'], priority=[350], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index a1a1c7a4038..064736bcc88 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -7,4 +7,4 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,60], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core'], priority=[350], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index b7d8de450ab..79bf3033fa1 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('*.cpp') incs = '. #intern/moto/include' -env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,45], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core'], priority=[325], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index ada878b74f2..0b35c019178 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -27,4 +27,4 @@ if env['WITH_BF_FFMPEG']: incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC'] defs.append('__STDC_CONSTANT_MACROS') -env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300, 30], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core'], priority=[300], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/icons/SConscript b/source/icons/SConscript index 1471a06c09d..c929729f05b 100644 --- a/source/icons/SConscript +++ b/source/icons/SConscript @@ -3,4 +3,4 @@ Import ('env') source = 'winblender.rcscons' -env.BlenderRes('winresource', source, ['core', 'player'], priority=[95 , 100]) \ No newline at end of file +env.BlenderRes('winresource', source, ['core'], priority=[95]) diff --git a/source/kernel/SConscript b/source/kernel/SConscript index 88fc58755c0..746fb60d4ff 100644 --- a/source/kernel/SConscript +++ b/source/kernel/SConscript @@ -7,4 +7,4 @@ sources += ' gen_system/SYS_System.cpp' incs = 'gen_messaging gen_system #/intern/string #/intern/moto/include #/source/blender/blenloader ' -env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core', 'player'], priority = [400, 95] ) +env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core'], priority = [400] ) -- cgit v1.2.3 From 461cb87e1df40b87709a568967da6d252715b1ee Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 15:54:06 +0000 Subject: == SCons == * apply a patch from b333rt. I modified to test for relative/absolute paths before doing mods by b333rt. Fixes troubles with using absolute paths in BF_BUILDDIR --- tools/Blender.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/Blender.py b/tools/Blender.py index 421a79454df..d7cbe1076e7 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -101,7 +101,10 @@ def create_blender_liblist(lenv = None, libtype = None): sortlist.sort() for sk in sortlist: v = curlib[sk] - target = os.path.abspath(os.getcwd() + os.sep + root_build_dir + 'lib' + os.sep +lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX']) + if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'): + target = os.path.abspath(os.getcwd() + os.sep + root_build_dir + 'lib' + os.sep +lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX']) + else: + target = os.path.abspath(root_build_dir + 'lib' + os.sep +lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX']) lst.append(target) return lst @@ -465,7 +468,11 @@ class BlenderEnvironment(SConsEnvironment): print bc.HEADER+'Configuring resource '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC lenv = self.Clone() - res = lenv.RES('#'+root_build_dir+'lib/'+libname, source) + if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'): + res = lenv.RES('#'+root_build_dir+'lib/'+libname, source) + else: + res = lenv.RES(root_build_dir+'lib/'+libname, source) + SConsEnvironment.Default(self, res) resources.append(res) -- cgit v1.2.3 From b537da1837f8d41ad99a41def20f8bcdd41c64c3 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 16:13:43 +0000 Subject: * shuffle a bit with playerlist. Fixes some undefined references, but not all. 15 undefined references left for mingw. (msvc is fine) --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 3227e15aaa3..f322ae27e06 100644 --- a/SConstruct +++ b/SConstruct @@ -404,7 +404,7 @@ if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') - playerlist = [mainlist[0]] + playerlist[0:2] + mainlist[2:] + [playerlist[2]] + playerlist = playerlist[0:2] + [mainlist[0]] + mainlist[2:] + [playerlist[2]] env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') ##### Now define some targets -- cgit v1.2.3 From 01f9b34abec653aa445cc00788a35f646849b07f Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 16:41:46 +0000 Subject: * remove mtio.h - no magnetic tape support has been coded. Helps compilation on osx10.6. --- source/blender/blenlib/intern/storage.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index e6e37c58805..7cbef85b938 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -70,9 +70,6 @@ #include -#if !defined(WIN32) -#include /* tape comando's */ -#endif #include /* strcpy etc.. */ #ifndef WIN32 -- cgit v1.2.3 From d65a908ec10a1f58aff70abd831b33ae2d53439d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Sep 2009 18:32:31 +0000 Subject: update relative paths for CMake --- source/blenderplayer/bad_level_call_stubs/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt index abb086b072a..fea19d90ed0 100644 --- a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt +++ b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt @@ -29,8 +29,8 @@ FILE(GLOB SRC stubs.c) SET(INC . .. - ../../source/blender/makesdna - ../../source/blender/makesrna + ../../../source/blender/makesdna + ../../../source/blender/makesrna ) IF(WITH_INTERNATIONAL) -- cgit v1.2.3 From 5bc0fa9a04fae41433ea296221b1f8837453d517 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Sep 2009 19:09:05 +0000 Subject: fix for ffmpeg with cmake, still not linking yet --- source/blenderplayer/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 030d9dbbba0..01ec55f10c3 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -103,6 +103,7 @@ IF(UNIX) bf_readblenfile bf_dna bf_rna + bf_videotex bf_blenfont bf_audaspace blenkernel_blc -- cgit v1.2.3 From 9303254e4f137c2810c5bc99ef1783fab249bc16 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 4 Sep 2009 19:27:15 +0000 Subject: fix for ffmpeg with cmake, now linking --- source/blenderplayer/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 01ec55f10c3..30a1c08ebc9 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -66,6 +66,7 @@ IF(UNIX) gp_common bf_string bf_ghost + bf_rna bf_blenkernel bf_blenloader bf_blenpluginapi @@ -102,7 +103,6 @@ IF(UNIX) bf_dds bf_readblenfile bf_dna - bf_rna bf_videotex bf_blenfont bf_audaspace -- cgit v1.2.3 From 944d0e908728d07a5a8da809baf448592ba9e701 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 4 Sep 2009 20:03:27 +0000 Subject: Fixed sound stuff for gameplayer, no sound though as U.audiodevice is set to 0 (="No Audio"). --- source/gameengine/GamePlayer/common/GPC_Engine.cpp | 15 +-------- source/gameengine/GamePlayer/common/GPC_Engine.h | 3 -- .../GamePlayer/ghost/GPG_Application.cpp | 36 ++++------------------ .../gameengine/GamePlayer/ghost/GPG_Application.h | 3 -- source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 5 --- 5 files changed, 7 insertions(+), 55 deletions(-) diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.cpp b/source/gameengine/GamePlayer/common/GPC_Engine.cpp index f131987095a..85a362d042a 100644 --- a/source/gameengine/GamePlayer/common/GPC_Engine.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Engine.cpp @@ -58,9 +58,6 @@ #include "NG_LoopBackNetworkDeviceInterface.h" #include "RAS_IRenderTools.h" -#if 0 //XXX - ADD SOUND - #include "SND_DeviceManager.h" -#endif #include "GPC_Engine.h" #include "GPC_KeyboardDevice.h" @@ -77,8 +74,7 @@ GPC_Engine::GPC_Engine(char *customLoadingAnimationURL, m_system(NULL), m_keyboarddev(NULL), m_mousedev(NULL), m_canvas(NULL), m_rendertools(NULL), m_portal(NULL), m_sceneconverter(NULL), m_networkdev(NULL), - m_audiodevice(NULL), m_curarea(NULL), - m_customLoadingAnimationURL(NULL), + m_curarea(NULL), m_customLoadingAnimationURL(NULL), m_foregroundColor(foregroundColor), m_backgroundColor(backgroundColor), m_frameRate(frameRate), m_BlenderLogo(0), m_Blender3DLogo(0)/*, m_NaNLogo(0)*/ @@ -203,7 +199,6 @@ bool GPC_Engine::StartKetsji(void) m_keyboarddev, m_mousedev, m_networkdev, - m_audiodevice, m_system); m_system->SetMainLoop(m_portal->m_ketsjieng); @@ -339,14 +334,6 @@ void GPC_Engine::Exit() m_networkdev = 0; } - if (m_audiodevice) - { -#if 0 //XXX - ADD SOUND - SND_DeviceManager::Unsubscribe(); -#endif - m_audiodevice = 0; - } - m_initialized = false; } diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.h b/source/gameengine/GamePlayer/common/GPC_Engine.h index b7121599c6e..42234bcbcd6 100644 --- a/source/gameengine/GamePlayer/common/GPC_Engine.h +++ b/source/gameengine/GamePlayer/common/GPC_Engine.h @@ -40,7 +40,6 @@ class RAS_IRenderTools; class KetsjiPortal; class KX_ISceneConverter; class NG_LoopBackNetworkDeviceInterface; -class SND_IAudioDevice; class GPC_RawImage; @@ -77,8 +76,6 @@ public: KX_ISceneConverter* m_sceneconverter; /** Network interface. */ NG_LoopBackNetworkDeviceInterface* m_networkdev; - /** Audiodevice interface */ - SND_IAudioDevice* m_audiodevice; struct ScrArea *m_curarea; // for future use, not used yet diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 879c2264247..8ec41968042 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -57,6 +57,7 @@ extern "C" #include "BLO_readfile.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_sound.h" #include "IMB_imbuf.h" #include "DNA_scene_types.h" #ifdef __cplusplus @@ -85,10 +86,6 @@ extern "C" #include "KX_BlenderSceneConverter.h" #include "NG_LoopBackNetworkDeviceInterface.h" -#if 0 //XXX - ADD SOUND - #include "SND_DeviceManager.h" -#endif - #include "GPC_MouseDevice.h" #include "GPC_RenderTools.h" #include "GPG_Canvas.h" @@ -128,8 +125,7 @@ GPG_Application::GPG_Application(GHOST_ISystem* system) m_rendertools(0), m_rasterizer(0), m_sceneconverter(0), - m_networkdevice(0), - m_audiodevice(0), + m_networkdevice(0), m_blendermat(0), m_blenderglslmat(0), m_pyGlobalDictString(0), @@ -587,15 +583,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) if (!m_networkdevice) goto initFailed; -#if 0 //XXX - ADD SOUND - // get an audiodevice - SND_DeviceManager::Subscribe(); - m_audiodevice = SND_DeviceManager::Instance(); - if (!m_audiodevice) - goto initFailed; - m_audiodevice->UseCD(); -#endif - + sound_init(); // create a ketsjisystem (only needed for timing and stuff) m_kxsystem = new GPG_System (m_system); @@ -613,9 +601,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) m_ketsjiengine->SetRenderTools(m_rendertools); m_ketsjiengine->SetRasterizer(m_rasterizer); m_ketsjiengine->SetNetworkDevice(m_networkdevice); -#if 0 //XXX - ADD SOUND - m_ketsjiengine->SetAudioDevice(m_audiodevice); -#endif + m_ketsjiengine->SetTimingDisplay(frameRate, false, false); CValue::SetDeprecationWarnings(nodepwarnings); @@ -628,10 +614,8 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) return m_engineInitialized; initFailed: + sound_exit(); delete m_kxsystem; -#if 0 // XXX - ADD SOUND - delete m_audiodevice; -#endif delete m_networkdevice; delete m_mouse; delete m_keyboard; @@ -644,7 +628,6 @@ initFailed: m_keyboard = NULL; m_mouse = NULL; m_networkdevice = NULL; - m_audiodevice = NULL; m_kxsystem = NULL; return false; } @@ -690,7 +673,6 @@ bool GPG_Application::startEngine(void) KX_Scene* startscene = new KX_Scene(m_keyboard, m_mouse, m_networkdevice, -// m_audiodevice, // XXX ADD SOUND startscenename, m_startScene); @@ -780,6 +762,7 @@ void GPG_Application::stopEngine() void GPG_Application::exitEngine() { + sound_exit(); if (m_ketsjiengine) { stopEngine(); @@ -791,13 +774,6 @@ void GPG_Application::exitEngine() delete m_kxsystem; m_kxsystem = 0; } - if (m_audiodevice) - { -#if 0 //XXX - ADD SOUND - SND_DeviceManager::Unsubscribe(); - m_audiodevice = 0; -#endif - } if (m_networkdevice) { delete m_networkdevice; diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index 845686f5770..73430213078 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -38,7 +38,6 @@ class KX_KetsjiEngine; class KX_ISceneConverter; class NG_LoopBackNetworkDeviceInterface; -class SND_IAudioDevice; class RAS_IRasterizer; class GHOST_IEvent; class GHOST_ISystem; @@ -142,8 +141,6 @@ protected: KX_ISceneConverter* m_sceneconverter; /** Network interface. */ NG_LoopBackNetworkDeviceInterface* m_networkdevice; - /** Sound device. */ - SND_IAudioDevice* m_audiodevice; bool m_blendermat; bool m_blenderglslmat; diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index b7677d29507..edc32093eab 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -59,7 +59,6 @@ extern "C" #include "BKE_icons.h" #include "BKE_node.h" #include "BKE_report.h" -#include "BKE_sound.h" #include "BLI_blenlib.h" #include "DNA_scene_types.h" #include "BLO_readfile.h" @@ -362,8 +361,6 @@ int main(int argc, char** argv) quicktime_init(); #endif - sound_init(); - libtiff_init(); // Parse command line options @@ -824,8 +821,6 @@ int main(int argc, char** argv) } free_nodesystem(); - - sound_exit(); return error ? -1 : 0; } -- cgit v1.2.3 From 5342f7930fb26855b92f337ace45f2ee51153957 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 4 Sep 2009 20:14:59 +0000 Subject: Added sound device default settings for the gameplayer. --- source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index edc32093eab..fb2e1c72a85 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -61,6 +61,7 @@ extern "C" #include "BKE_report.h" #include "BLI_blenlib.h" #include "DNA_scene_types.h" +#include "DNA_userdef_types.h" #include "BLO_readfile.h" #include "BLO_readblenfile.h" #include "IMB_imbuf.h" @@ -390,6 +391,13 @@ int main(int argc, char** argv) } } #endif + // XXX add the ability to change this values to the command line parsing. + U.mixbufsize = 2048; + U.audiodevice = 2; + U.audiorate = 44100; + U.audioformat = 0x24; + U.audiochannels = 2; + for (i = 1; (i < argc) && !error #ifdef WIN32 && scr_saver_mode == SCREEN_SAVER_MODE_NONE -- cgit v1.2.3 From 7df35db1b1364dcd81dd8247ad3707d40a78fd59 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Sep 2009 20:51:09 +0000 Subject: 2.5 Notifiers --------- Various fixes for wrong use of notifiers, and some new notifiers to make things a bit more clear and consistent, with two notable changes: * Geometry changes are now done with NC_GEOM, rather than NC_OBJECT|ND_GEOM_, so an object does need to be available. * Space data now use NC_SPACE|ND_SPACE_*, instead of data notifiers or even NC_WINDOW in some cases. Note that NC_SPACE should only be used for notifying about changes in space data, we don't want to go back to allqueue(REDRAW..). Depsgraph --------- The dependency graph now has a different flush call: DAG_object_flush_update(scene, ob, flag) is replaced by: DAG_id_flush_update(id, flag) It still works basically the same, one difference is that it now also accepts object data (e.g. Mesh), again to avoid requiring an Object to be available. Other ID types will simply do nothing at the moment. Docs ---- I made some guidelines for how/when to do which kinds of updates and notifiers. I can't specify totally exact how to make these decisions, but these are basically the guidelines I use. So, new and updated docs are here: http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers --- source/blender/blenkernel/BKE_depsgraph.h | 7 +- source/blender/blenkernel/intern/armature.c | 1 - source/blender/blenkernel/intern/booleanops.c | 2 +- source/blender/blenkernel/intern/depsgraph.c | 93 +++-- source/blender/blenkernel/intern/mesh.c | 4 +- source/blender/blenkernel/intern/multires.c | 2 +- source/blender/blenkernel/intern/particle.c | 13 +- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/editors/armature/editarmature.c | 25 +- source/blender/editors/armature/poselib.c | 6 +- source/blender/editors/armature/poseobject.c | 18 +- source/blender/editors/curve/editcurve.c | 121 ++++--- source/blender/editors/curve/editfont.c | 14 +- .../editors/interface/interface_templates.c | 10 +- source/blender/editors/mesh/editmesh.c | 8 +- source/blender/editors/mesh/editmesh_add.c | 78 ++--- source/blender/editors/mesh/editmesh_loop.c | 7 +- source/blender/editors/mesh/editmesh_mods.c | 121 ++++--- source/blender/editors/mesh/editmesh_tools.c | 147 ++++---- source/blender/editors/mesh/mesh_layers.c | 88 ++--- source/blender/editors/mesh/meshtools.c | 2 +- source/blender/editors/metaball/editmball.c | 30 +- source/blender/editors/object/editconstraint.c | 13 +- source/blender/editors/object/editkey.c | 107 +----- source/blender/editors/object/editlattice.c | 9 +- source/blender/editors/object/object_edit.c | 55 ++- source/blender/editors/object/object_modifier.c | 52 +-- source/blender/editors/object/object_vgroup.c | 80 ++--- source/blender/editors/physics/editparticle.c | 62 ++-- source/blender/editors/sculpt_paint/paint_image.c | 2 +- source/blender/editors/sculpt_paint/paint_vertex.c | 18 +- source/blender/editors/space_action/space_action.c | 4 + source/blender/editors/space_buttons/buttons_ops.c | 19 +- .../blender/editors/space_buttons/space_buttons.c | 17 +- .../blender/editors/space_console/space_console.c | 6 +- source/blender/editors/space_file/file_ops.c | 30 +- source/blender/editors/space_file/space_file.c | 16 +- source/blender/editors/space_graph/space_graph.c | 4 + source/blender/editors/space_image/space_image.c | 12 +- source/blender/editors/space_info/space_info.c | 5 +- source/blender/editors/space_nla/space_nla.c | 4 + source/blender/editors/space_node/space_node.c | 9 + source/blender/editors/space_outliner/outliner.c | 6 +- .../editors/space_outliner/space_outliner.c | 8 + .../editors/space_sequencer/space_sequencer.c | 9 + source/blender/editors/space_text/space_text.c | 4 + source/blender/editors/space_text/text_ops.c | 3 +- source/blender/editors/space_time/space_time.c | 11 + source/blender/editors/space_view3d/space_view3d.c | 37 +- .../blender/editors/space_view3d/view3d_buttons.c | 16 +- .../blender/editors/space_view3d/view3d_header.c | 6 +- .../blender/editors/space_view3d/view3d_select.c | 4 +- source/blender/editors/space_view3d/view3d_snap.c | 8 +- source/blender/editors/transform/transform.c | 2 +- .../editors/transform/transform_conversions.c | 14 +- .../blender/editors/transform/transform_generics.c | 14 +- source/blender/editors/util/editmode_undo.c | 2 +- source/blender/editors/uvedit/uvedit_ops.c | 50 +-- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 40 +-- source/blender/makesrna/intern/rna_armature.c | 18 +- source/blender/makesrna/intern/rna_boid.c | 103 +++--- source/blender/makesrna/intern/rna_cloth.c | 63 ++-- source/blender/makesrna/intern/rna_constraint.c | 5 +- source/blender/makesrna/intern/rna_curve.c | 19 +- source/blender/makesrna/intern/rna_define.c | 3 +- source/blender/makesrna/intern/rna_fluidsim.c | 18 +- source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_key.c | 5 +- source/blender/makesrna/intern/rna_lattice.c | 14 +- source/blender/makesrna/intern/rna_mesh.c | 110 ++++-- source/blender/makesrna/intern/rna_mesh_api.c | 11 +- source/blender/makesrna/intern/rna_meta.c | 12 +- source/blender/makesrna/intern/rna_modifier.c | 344 +++++++++---------- source/blender/makesrna/intern/rna_object.c | 19 +- source/blender/makesrna/intern/rna_object_force.c | 90 ++--- source/blender/makesrna/intern/rna_particle.c | 356 +++++++++---------- source/blender/makesrna/intern/rna_pose.c | 2 +- source/blender/makesrna/intern/rna_sculpt_paint.c | 19 +- source/blender/makesrna/intern/rna_smoke.c | 2 +- source/blender/makesrna/intern/rna_space.c | 227 +++++++----- source/blender/makesrna/intern/rna_userdef.c | 380 +++++++++++---------- source/blender/makesrna/intern/rna_wm.c | 1 + source/blender/windowmanager/WM_types.h | 51 +-- source/blender/windowmanager/intern/wm.c | 2 +- .../blender/windowmanager/intern/wm_event_system.c | 4 +- 85 files changed, 1747 insertions(+), 1689 deletions(-) diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 70b6c1d13f4..e242ead3b87 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -32,6 +32,8 @@ #define DEPS_DEBUG */ +struct ID; +struct Main; struct Scene; struct DagNodeQueue; struct DagForest; @@ -103,8 +105,9 @@ void DAG_object_update_flags(struct Scene *sce, struct Object *ob, unsigned int /* flushes all recalc flags in objects down the dependency tree */ void DAG_scene_flush_update(struct Scene *sce, unsigned int lay, int time); - /* flushes all recalc flags for this object down the dependency tree */ -void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag); + /* flushes all recalc flags for this object down the dependency tree, + but not the DAG only supports objects and object data currently */ +void DAG_id_flush_update(struct ID *id, short flag); void DAG_pose_sort(struct Object *ob); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 631bc2cb88c..e568f1b2c0e 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -130,7 +130,6 @@ void free_bones (bArmature *arm) void free_armature(bArmature *arm) { if (arm) { - /* unlink_armature(arm);*/ free_bones(arm); /* free editmode data */ diff --git a/source/blender/blenkernel/intern/booleanops.c b/source/blender/blenkernel/intern/booleanops.c index eb3aefe7ee6..5f0697f06ce 100644 --- a/source/blender/blenkernel/intern/booleanops.c +++ b/source/blender/blenkernel/intern/booleanops.c @@ -589,7 +589,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) MEM_freeN(mat); /* update dag */ - DAG_object_flush_update(scene, ob_new, OB_RECALC_DATA); + DAG_id_flush_update(&ob_new->id, OB_RECALC_DATA); return 1; } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 6c765b02e5d..6a14762e0ed 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -61,6 +61,7 @@ #include "DNA_space_types.h" #include "DNA_view2d_types.h" #include "DNA_view3d_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_ghash.h" @@ -2141,39 +2142,77 @@ void DAG_scene_update_flags(Scene *scene, unsigned int lay) } - -/* flag this object and all its relations to recalc */ -/* if you need to do more objects, tag object yourself and - use DAG_scene_flush_update() in end */ -void DAG_object_flush_update(Scene *sce, Object *ob, short flag) +void DAG_id_flush_update(ID *id, short flag) { - - if(ob==NULL || sce->theDag==NULL) return; + Main *bmain= G.main; + wmWindowManager *wm; + wmWindow *win; + Scene *sce; + Object *obt, *ob= NULL; + short idtype; - ob->recalc |= flag; - BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH); - - /* all users of this ob->data should be checked */ - /* BUT! displists for curves are still only on cu */ - if(flag & OB_RECALC_DATA) { - if(ob->type!=OB_CURVE && ob->type!=OB_SURF) { - ID *id= ob->data; - if(id && id->us>1) { - /* except when there's a key and shapes are locked */ - if(ob_get_key(ob) && (ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK))); - else { - Object *obt; - for (obt=G.main->object.first; obt; obt= obt->id.next) { - if (obt != ob && obt->data==ob->data) { - obt->recalc |= OB_RECALC_DATA; - BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); - } - } + /* only one scene supported currently, making more scenes work + correctly requires changes beyond just the dependency graph */ + + if((wm= bmain->wm.first)) { + /* if we have a windowmanager, use sce from first window */ + for(win=wm->windows.first; win; win=win->next) { + sce= (win->screen)? win->screen->scene: NULL; + + if(sce) + break; + } + } + else + /* if not, use the first sce */ + sce= bmain->scene.first; + + if(!id || !sce || !sce->theDag) + return; + + /* set flags & pointcache for object */ + if(GS(id->name) == ID_OB) { + ob= (Object*)id; + ob->recalc |= flag; + BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH); + + if(flag & OB_RECALC_DATA) { + /* all users of this ob->data should be checked */ + id= ob->data; + + /* no point in trying in this cases */ + if(!id || id->us <= 1) + id= NULL; + /* curves and surfaces only need to mark one object, since + otherwise cu->displist would be computed multiple times */ + else if(ob->type==OB_CURVE || ob->type==OB_SURF) + id= NULL; + /* also for locked shape keys we make an exception */ + else if(ob_get_key(ob) && (ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK))) + id= NULL; + } + } + + /* set flags & pointcache for object data */ + if(id) { + idtype= GS(id->name); + + if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) { + for(obt=bmain->object.first; obt; obt= obt->id.next) { + if(!(ob && obt == ob) && obt->data == id) { + obt->recalc |= OB_RECALC_DATA; + BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); + + /* for these we only flag one object, otherwise cu->displist + would be computed multiple times */ + if(obt->type==OB_CURVE || obt->type==OB_SURF) + break; } } } } - + + /* flush to other objects that depend on this one */ // XXX if(G.curscreen) // DAG_scene_flush_update(sce, dag_screen_view3d_layers(), 0); // else diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index c7454d3b832..c92eda6d169 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -977,7 +977,7 @@ void mesh_set_smooth_flag(Object *meshOb, int enableSmooth) } } -// XXX do this in caller DAG_object_flush_update(scene, meshOb, OB_RECALC_DATA); +// XXX do this in caller DAG_id_flush_update(&me->id, OB_RECALC_DATA); } void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float **faceNors_r) @@ -1265,7 +1265,7 @@ void mesh_pmv_revert(Object *ob, Mesh *me) MEM_freeN(me->pv->vert_map); me->pv->vert_map= NULL; -// XXX do this in caller DAG_object_flush_update(scene, ob, OB_RECALC_DATA); +// XXX do this in caller DAG_id_flush_update(&me->id, OB_RECALC_DATA); } } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 9ba5769843f..37e7e55050a 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -83,7 +83,7 @@ int multiresModifier_switch_level(Object *ob, const int distance) mmd->lvl += distance; if(mmd->lvl < 1) mmd->lvl = 1; else if(mmd->lvl > mmd->totlvl) mmd->lvl = mmd->totlvl; - /* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + /* XXX: DAG_id_flush_update(&ob->id, OB_RECALC_DATA); object_handle_update(ob);*/ return 1; } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 18e3512967a..1ae3ec5dd50 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2631,7 +2631,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra ParticleInterpolationData pind; float birthtime = 0.0, dietime = 0.0; - float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec; + float t, time = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec; float col[4] = {0.5f, 0.5f, 0.5f, 1.0f}; float prev_tangent[3], hairmat[4][4]; float rotmat[3][3]; @@ -2853,14 +2853,13 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); - ParticleSettings *part = psys ? psys->part : NULL; ParticleData *pa = psys ? psys->particles : NULL; ParticleInterpolationData pind; ParticleKey result; float birthtime = 0.0, dietime = 0.0; - float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec; + float t, time = 0.0, keytime = 0.0, frs_sec; float hairmat[4][4]; int k,i; int steps = (int)pow(2.0, (double)pset->draw_step); @@ -3161,7 +3160,7 @@ void object_add_particle_system(Scene *scene, Object *ob) psys->cfra=bsystem_time(scene,ob,scene->r.cfra+1,0.0); DAG_scene_sort(scene); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } void object_remove_particle_system(Scene *scene, Object *ob) { @@ -3184,7 +3183,7 @@ void object_remove_particle_system(Scene *scene, Object *ob) ((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT; DAG_scene_sort(scene); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } static void default_particle_settings(ParticleSettings *part) { @@ -3364,7 +3363,7 @@ void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int reca } } if(flush) - DAG_object_flush_update(scene, base->object, OB_RECALC_DATA); + DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); } } @@ -3396,7 +3395,7 @@ LinkNode *psys_using_settings(struct Scene *scene, ParticleSettings *part, int f } if(flush_update && found) - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } return node; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index c0223d1690c..7a156f56d72 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1947,7 +1947,7 @@ void BKE_ptcache_set_continue_physics(Scene *scene, int enable) if(CONTINUE_PHYSICS == 0) { for(ob=G.main->object.first; ob; ob=ob->id.next) if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED)) - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 9f83733a640..65051c384b3 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -340,7 +340,7 @@ void ED_armature_from_edit(Scene *scene, Object *obedit) armature_rebuild_pose(obt, arm); } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); } @@ -1054,8 +1054,8 @@ static int separate_armature_exec (bContext *C, wmOperator *op) /* 4) fix links before depsgraph flushes */ // err... or after? separated_armature_fix_links(oldob, newob); - DAG_object_flush_update(scene, oldob, OB_RECALC_DATA); /* this is the original one */ - DAG_object_flush_update(scene, newob, OB_RECALC_DATA); /* this is the separated one */ + DAG_id_flush_update(&oldob->id, OB_RECALC_DATA); /* this is the original one */ + DAG_id_flush_update(&newob->id, OB_RECALC_DATA); /* this is the separated one */ /* 5) restore original conditions */ @@ -1890,7 +1890,7 @@ void mouse_armature(bContext *C, short mval[2], int extend) if(nearBone->flag & BONE_SELECTED) nearBone->flag |= BONE_ACTIVE; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, vc.obedit); } } @@ -4335,7 +4335,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor if (ob->mode & OB_MODE_WEIGHT_PAINT) { if (nearBone->flag & BONE_ACTIVE) { vertexgroup_select_by_name(OBACT, nearBone->name); - DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); + DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); } } @@ -4765,7 +4765,6 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par, int mod static int pose_clear_scale_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *ob= CTX_data_active_object(C); /* only clear those channels that are not locked */ @@ -4782,7 +4781,7 @@ static int pose_clear_scale_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); @@ -4807,7 +4806,6 @@ void POSE_OT_scale_clear(wmOperatorType *ot) static int pose_clear_loc_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *ob= CTX_data_active_object(C); /* only clear those channels that are not locked */ @@ -4824,7 +4822,7 @@ static int pose_clear_loc_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); @@ -4849,7 +4847,6 @@ void POSE_OT_loc_clear(wmOperatorType *ot) static int pose_clear_rot_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *ob= CTX_data_active_object(C); /* only clear those channels that are not locked */ @@ -4899,7 +4896,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); @@ -5337,7 +5334,6 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) static int armature_flip_names_exec (bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); bArmature *arm; char newname[32]; @@ -5357,7 +5353,7 @@ static int armature_flip_names_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* since we renamed stuff... */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -5383,7 +5379,6 @@ void ARMATURE_OT_flip_names (wmOperatorType *ot) static int armature_autoside_names_exec (bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); bArmature *arm; char newname[32]; @@ -5404,7 +5399,7 @@ static int armature_autoside_names_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* since we renamed stuff... */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 021bec05a3b..56d714fd058 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -843,7 +843,7 @@ static void poselib_preview_apply (bContext *C, wmOperator *op) */ // FIXME: shouldn't this use the builtin stuff? if ((pld->arm->flag & ARM_DELAYDEFORM)==0) - DAG_object_flush_update(pld->scene, pld->ob, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(&pld->ob->id, OB_RECALC_DATA); /* sets recalc flags */ else where_is_pose(pld->scene, pld->ob); } @@ -1346,7 +1346,7 @@ static void poselib_preview_cleanup (bContext *C, wmOperator *op) * - note: code copied from transform_generics.c -> recalcData() */ if ((arm->flag & ARM_DELAYDEFORM)==0) - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ else where_is_pose(scene, ob); @@ -1360,7 +1360,7 @@ static void poselib_preview_cleanup (bContext *C, wmOperator *op) action_set_activemarker(act, marker, 0); /* Update event for pose and deformation children */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* updates */ if (IS_AUTOKEY_MODE(scene, NORMAL)) { diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 9a72fce2bcf..2673640b213 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -893,7 +893,7 @@ void pose_copy_menu(Scene *scene) ob->pose->flag |= POSE_RECALC; } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); // and all its relations + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); // and all its relations BIF_undo_push("Copy Pose Attributes"); @@ -1067,7 +1067,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) } /* Update event for pose and deformation children */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); if (IS_AUTOKEY_ON(scene)) { // XXX remake_action_ipos(ob->action); @@ -1124,7 +1124,7 @@ void pose_adds_vgroups(Scene *scene, Object *meshobj, int heatweights) // and all its relations - DAG_object_flush_update(scene, meshobj, OB_RECALC_DATA); + DAG_id_flush_update(&meshobj->id, OB_RECALC_DATA); } /* ********************************************** */ @@ -1540,7 +1540,6 @@ void pose_select_grouped_menu (Scene *scene) static int pose_flip_names_exec (bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); bArmature *arm; char newname[32]; @@ -1560,7 +1559,7 @@ static int pose_flip_names_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* since we renamed stuff... */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1587,7 +1586,6 @@ void POSE_OT_flip_names (wmOperatorType *ot) static int pose_autoside_names_exec (bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); bArmature *arm; char newname[32]; @@ -1608,7 +1606,7 @@ static int pose_autoside_names_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* since we renamed stuff... */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1677,7 +1675,7 @@ void pose_activate_flipped_bone(Scene *scene) /* in weightpaint we select the associated vertex group too */ if(ob->mode & OB_MODE_WEIGHT_PAINT) { vertexgroup_select_by_name(OBACT, name); - DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); + DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); } // XXX notifiers need to be sent to other editors to update @@ -2116,7 +2114,7 @@ void pose_relax(Scene *scene) pchan->bone->flag &= ~ BONE_TRANSFORM; /* do depsgraph flush */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); BIF_undo_push("Relax Pose"); } @@ -2211,7 +2209,7 @@ void pose_clear_user_transforms(Scene *scene, Object *ob) rest_pose(ob->pose); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); BIF_undo_push("Clear User Transform"); } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 28a9d3ac7c9..4246c889de0 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -409,10 +409,10 @@ static int separate_exec(bContext *C, wmOperator *op) load_editNurb(newob); free_editNurb(newob); - DAG_object_flush_update(scene, oldob, OB_RECALC_DATA); /* this is the original one */ - DAG_object_flush_update(scene, newob, OB_RECALC_DATA); /* this is the separated one */ + DAG_id_flush_update(&oldob->id, OB_RECALC_DATA); /* this is the original one */ + DAG_id_flush_update(&newob->id, OB_RECALC_DATA); /* this is the separated one */ - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, oldob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, oldob->data); WM_cursor_wait(0); @@ -1005,8 +1005,8 @@ static int switch_direction_exec(bContext *C, wmOperator *op) if(isNurbsel(nu)) switchdirectionNurb(nu); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1052,8 +1052,8 @@ static int set_weight_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1103,8 +1103,8 @@ static int set_radius_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -1178,8 +1178,8 @@ static int smooth_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -1343,8 +1343,8 @@ static int smooth_radius_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -1493,7 +1493,7 @@ static int de_select_first_exec(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); selectend_nurb(obedit, FIRST, 1, DESELECT); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -1517,7 +1517,7 @@ static int de_select_last_exec(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); selectend_nurb(obedit, LAST, 1, DESELECT); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -1585,7 +1585,7 @@ static int de_select_all_exec(bContext *C, wmOperator *op) select_adjacent_cp(editnurb, 1, 1, SELECT); /* cascade selection */ } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -1654,8 +1654,8 @@ static int hide_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -1714,8 +1714,8 @@ static int reveal_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -1770,7 +1770,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -2166,8 +2166,8 @@ static int subdivide_exec(bContext *C, wmOperator *op) } /* End of 'if((nu->type & 7)==CU_NURBS)' */ } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -2500,14 +2500,13 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot) static int set_handle_type_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); ListBase *editnurb= curve_get_editcurve(obedit); sethandlesNurb(editnurb, RNA_enum_get(op->ptr, "type")); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -2861,8 +2860,8 @@ static int merge_nurb(bContext *C, wmOperator *op) set_actNurb(obedit, NULL); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -2870,7 +2869,6 @@ static int merge_nurb(bContext *C, wmOperator *op) static int make_segment_exec(bContext *C, wmOperator *op) { /* joins 2 curves */ - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu, *nu1=0, *nu2=0; @@ -3015,8 +3013,8 @@ static int make_segment_exec(bContext *C, wmOperator *op) set_actNurb(obedit, NULL); /* for selected */ - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -3100,7 +3098,7 @@ void mouse_nurb(bContext *C, short mval[2], int extend) } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); if(nu!=get_actNurb(obedit)) set_actNurb(obedit, nu); @@ -3231,8 +3229,8 @@ static int spin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -3255,7 +3253,6 @@ void CURVE_OT_spin(wmOperatorType *ot) static int addvert_Nurb(bContext *C, short mode, float location[3]) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; @@ -3367,8 +3364,8 @@ static int addvert_Nurb(bContext *C, short mode, float location[3]) test2DNurb(nu); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -3423,7 +3420,6 @@ void CURVE_OT_vertex_add(wmOperatorType *ot) static int extrude_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; @@ -3438,8 +3434,8 @@ static int extrude_exec(bContext *C, wmOperator *op) } else { if(extrudeflagNurb(editnurb, 1)) { /* '1'= flag */ - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } } @@ -3549,8 +3545,8 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -3641,7 +3637,7 @@ static int select_linked_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -3733,7 +3729,7 @@ static int select_row_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -3760,7 +3756,7 @@ static int select_next_exec(bContext *C, wmOperator *op) ListBase *editnurb= curve_get_editcurve(obedit); select_adjacent_cp(editnurb, 1, 0, SELECT); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -3787,7 +3783,7 @@ static int select_previous_exec(bContext *C, wmOperator *op) ListBase *editnurb= curve_get_editcurve(obedit); select_adjacent_cp(editnurb, -1, 0, SELECT); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -3874,7 +3870,7 @@ static int select_more_exec(bContext *C, wmOperator *op) select_adjacent_cp(editnurb, -1, 0, SELECT); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -4035,7 +4031,7 @@ static int select_less_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -4131,7 +4127,7 @@ static int select_random_exec(bContext *C, wmOperator *op) MEM_freeN(itemstobeselected); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -4165,7 +4161,7 @@ static int select_every_nth_exec(bContext *C, wmOperator *op) select_adjacent_cp(editnurb, n, 1, SELECT); select_adjacent_cp(editnurb, -n, 1, SELECT); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -4231,7 +4227,6 @@ void CURVE_OT_duplicate(wmOperatorType *ot) static int delete_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu, *next, *nu1; @@ -4243,8 +4238,8 @@ static int delete_exec(bContext *C, wmOperator *op) if(type==0) deleteflagNurb(C, op, 1); else freeNurblist(editnurb); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -4373,8 +4368,8 @@ static int delete_exec(bContext *C, wmOperator *op) bezt2= bezt+(nu->pntsu-1); if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) { nu->flagu &= ~CU_CYCLIC; - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } } @@ -4399,8 +4394,8 @@ static int delete_exec(bContext *C, wmOperator *op) bp2= bp+(nu->pntsu-1); if( bp2->f1 & SELECT ) { nu->flagu &= ~CU_CYCLIC; - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } } @@ -4497,8 +4492,8 @@ static int delete_exec(bContext *C, wmOperator *op) else if(type==2) freeNurblist(editnurb); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -4569,8 +4564,8 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -5119,8 +5114,8 @@ static int clear_tilt_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 46be95063ec..ae34f30a4f1 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -273,15 +273,14 @@ static void text_update_edited(bContext *C, Scene *scene, Object *obedit, int re BKE_text_to_curve(scene, obedit, mode); if(recalc) - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); } /********************** insert lorem operator *********************/ static int insert_lorem_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); char *p, *p2; int i; @@ -308,8 +307,8 @@ static int insert_lorem_exec(bContext *C, wmOperator *op) insert_into_textbuf(obedit, '\n'); insert_into_textbuf(obedit, '\n'); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -614,7 +613,6 @@ static EnumPropertyItem style_items[]= { static int set_style(bContext *C, int style, int clear) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); Curve *cu= obedit->data; EditFont *ef= cu->editfont; @@ -630,8 +628,8 @@ static int set_style(bContext *C, int style, int clear) ef->textbufinfo[i].flag |= style; } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 6aa5f5efc41..d253948e2e8 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -328,7 +328,6 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v) { - Scene *scene= CTX_data_scene(C); Object *ob = ob_v; ModifierData *md; @@ -343,12 +342,11 @@ static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v) } WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v) { - Scene *scene= CTX_data_scene(C); Object *ob = ob_v; ModifierData *md = md_v; ModifierData *nmd = modifier_new(md->type); @@ -361,7 +359,7 @@ static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v) ob->partype = PAROBJECT; WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); ED_undo_push(C, "Modifier convert to real"); } @@ -597,8 +595,8 @@ void do_constraint_panels(bContext *C, void *arg, int event) if(ob->pose) update_pose_constraint_flags(ob->pose); - if(ob->type==OB_ARMATURE) DAG_object_flush_update(scene, ob, OB_RECALC_DATA|OB_RECALC_OB); - else DAG_object_flush_update(scene, ob, OB_RECALC_OB); + if(ob->type==OB_ARMATURE) DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB); + else DAG_id_flush_update(&ob->id, OB_RECALC_OB); // XXX allqueue(REDRAWVIEW3D, 0); // XXX allqueue(REDRAWBUTSOBJECT, 0); diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index c3f1637d3af..980d699dda5 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1280,7 +1280,7 @@ void load_editMesh(Scene *scene, Object *ob) void remake_editMesh(Scene *scene, Object *ob) { make_editMesh(scene, ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); BIF_undo_push("Undo all changes"); } @@ -1390,8 +1390,8 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) /* hashedges are invalid now, make new! */ editMesh_set_hash(em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - DAG_object_flush_update(scene, basenew->object, OB_RECALC_DATA); + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + DAG_id_flush_update(&basenew->object->id, OB_RECALC_DATA); BKE_mesh_end_editmesh(me, em); @@ -1469,7 +1469,7 @@ static int mesh_separate_exec(bContext *C, wmOperator *op) retval= mesh_separate_loose(scene, base); if(retval) { - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, base->object); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 19078d2f6ff..4af5ddf56fa 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -217,8 +217,8 @@ static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event) } //retopo_do_all(); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); - DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, vc.obedit->data); + DAG_id_flush_update(vc.obedit->data, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -343,9 +343,8 @@ static int make_fgon_exec(bContext *C, wmOperator *op) EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); if( make_fgon(em, op, 1) ) { - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -376,9 +375,8 @@ static int clear_fgon_exec(bContext *C, wmOperator *op) EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); if( make_fgon(em, op, 0) ) { - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -666,7 +664,7 @@ void addfaces_from_edgenet(EditMesh *em) EM_select_flush(em); -// XXX DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// XXX DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } static void addedgeface_mesh(EditMesh *em, wmOperator *op) @@ -695,7 +693,7 @@ static void addedgeface_mesh(EditMesh *em, wmOperator *op) eed= addedgelist(em, neweve[0], neweve[1], NULL); EM_select_edge(eed, 1); - // XXX DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + // XXX DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return; } else if(amount > 4) { @@ -792,9 +790,8 @@ static int addedgeface_mesh_exec(bContext *C, wmOperator *op) addedgeface_mesh(em, op); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1311,7 +1308,6 @@ static float new_primitive_matrix(bContext *C, float primmat[][4]) static int add_primitive_plane_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1321,8 +1317,8 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_PLANE, mat, 4, 0, 0, dia, 0.0f, 0, 1); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1344,7 +1340,6 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) static int add_primitive_cube_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1354,8 +1349,8 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_CUBE, mat, 4, 0, 0, dia, 1.0f, 1, 1); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1377,7 +1372,6 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) static int add_primitive_circle_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1387,8 +1381,8 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_CIRCLE, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, 0.0f, 0, RNA_boolean_get(op->ptr, "fill")); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1415,7 +1409,6 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot) static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1425,8 +1418,8 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_CYLINDER, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, RNA_float_get(op->ptr, "depth"), 1, 1); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1453,7 +1446,6 @@ void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) static int add_primitive_tube_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1463,8 +1455,8 @@ static int add_primitive_tube_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_CYLINDER, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, RNA_float_get(op->ptr, "depth"), 1, 0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1491,7 +1483,6 @@ void MESH_OT_primitive_tube_add(wmOperatorType *ot) static int add_primitive_cone_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1501,8 +1492,8 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_CONE, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, RNA_float_get(op->ptr, "depth"), 0, RNA_boolean_get(op->ptr, "cap_end")); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1531,7 +1522,6 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) static int add_primitive_grid_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1541,8 +1531,8 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_GRID, mat, RNA_int_get(op->ptr, "x_subdivisions"), RNA_int_get(op->ptr, "y_subdivisions"), 0, dia, 0.0f, 0, 1); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1569,7 +1559,6 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) static int add_primitive_monkey_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float mat[4][4]; @@ -1577,8 +1566,8 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_MONKEY, mat, 0, 0, 2, 0.0f, 0.0f, 0, 0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1600,7 +1589,6 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1610,8 +1598,8 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_UVSPHERE, mat, RNA_int_get(op->ptr, "rings"), RNA_int_get(op->ptr, "segments"), 0, dia, 0.0f, 0, 0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1638,7 +1626,6 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); float dia, mat[4][4]; @@ -1648,8 +1635,8 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) make_prim(obedit, PRIM_ICOSPHERE, mat, 0, 0, RNA_int_get(op->ptr, "subdivisions"), dia, 0.0f, 0, 0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1677,7 +1664,6 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) static int mesh_duplicate_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(ob->data); @@ -1685,8 +1671,8 @@ static int mesh_duplicate_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(ob->data, em); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c index b46f745e8f5..4c3e76f2285 100644 --- a/source/blender/editors/mesh/editmesh_loop.c +++ b/source/blender/editors/mesh/editmesh_loop.c @@ -389,7 +389,7 @@ void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts) EM_selectmode_set(em); } -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return; } @@ -624,7 +624,6 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct static int knife_cut_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); ARegion *ar= CTX_wm_region(C); @@ -705,8 +704,8 @@ static int knife_cut_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index f2c5b7fb727..667a889b5fc 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -127,7 +127,7 @@ void EM_automerge(int update) // if (len) { // em->totvert -= len; /* saves doing a countall */ // if (update) { -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); // } // } // } @@ -807,7 +807,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) if (selcount) { /* here was an edge-mode only select flush case, has to be generalized */ EM_selectmode_flush(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(me, em); return OPERATOR_FINISHED; } @@ -839,7 +839,7 @@ static EnumPropertyItem prop_simedge_types[] = { {0, NULL, 0, NULL, NULL} }; -static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode) +static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mode) { EditEdge *eed, *base_eed=NULL; unsigned int selcount=0; /* count how many new edges we select*/ @@ -849,7 +849,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode) unsigned int deselcount=0; short ok=0; - float thresh= scene->toolsettings->select_thresh; + float thresh= ts->select_thresh; for(eed= em->edges.first; eed; eed= eed->next) { if (!eed->h) { @@ -1039,17 +1039,17 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode) /* wrap the above function but do selection flushing edge to face */ static int similar_edge_select_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); + ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); Mesh *me= obedit->data; EditMesh *em= BKE_mesh_get_editmesh(me); - int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type")); + int selcount = similar_edge_select__internal(ts, em, RNA_int_get(op->ptr, "type")); if (selcount) { /* here was an edge-mode only select flush case, has to be generalized */ EM_selectmode_flush(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(me, em); return OPERATOR_FINISHED; } @@ -1081,7 +1081,7 @@ static EnumPropertyItem prop_simvertex_types[] = { static int similar_vert_select_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); + ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); Mesh *me= obedit->data; EditMesh *em= BKE_mesh_get_editmesh(me); @@ -1094,7 +1094,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) int mode= RNA_enum_get(op->ptr, "type"); short ok=0; - float thresh= scene->toolsettings->select_thresh; + float thresh= ts->select_thresh; for(eve= em->verts.first; eve; eve= eve->next) { if (!eve->h) { @@ -1207,7 +1207,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) } /* end basevert loop */ if(selcount) { - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(me, em); return OPERATOR_FINISHED; } @@ -1413,7 +1413,7 @@ void EM_mesh_copy_edge(EditMesh *em, short type) } if (change) { -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } } @@ -1541,7 +1541,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type) } if (change) { -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } } @@ -1671,7 +1671,7 @@ void EM_mesh_copy_face_layer(EditMesh *em, wmOperator *op, short type) } if (change) { -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } } @@ -1991,7 +1991,7 @@ static int loop_multiselect(bContext *C, wmOperator *op) MEM_freeN(edarray); // if (EM_texFaceCheck()) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2060,7 +2060,7 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring EM_selectmode_flush(em); // if (EM_texFaceCheck()) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); } } @@ -2159,9 +2159,8 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2]) break; } - DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA); - - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); + DAG_id_flush_update(vc.obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); } } @@ -2261,7 +2260,7 @@ void mouse_mesh(bContext *C, short mval[2], short extend) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); } @@ -2405,12 +2404,12 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event /* return warning! */ if(limit) { int retval= select_linked_limited_invoke(&vc, 0, sel); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return retval; } if( unified_findnearest(&vc, &eve, &eed, &efa)==0 ) { - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_CANCELLED; } @@ -2464,7 +2463,7 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event // if (EM_texFaceCheck()) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -2545,7 +2544,7 @@ static int select_linked_exec(bContext *C, wmOperator *op) else selectconnected_mesh_all(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2671,7 +2670,7 @@ void EM_hide_mesh(EditMesh *em, int swap) em->totedgesel= em->totfacesel= em->totvertsel= 0; // if(EM_texFaceCheck()) - // DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + // DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } static int hide_mesh_exec(bContext *C, wmOperator *op) @@ -2681,7 +2680,7 @@ static int hide_mesh_exec(bContext *C, wmOperator *op) EM_hide_mesh(em, RNA_boolean_get(op->ptr, "unselected")); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2738,7 +2737,7 @@ void EM_reveal_mesh(EditMesh *em) EM_selectmode_flush(em); // if (EM_texFaceCheck()) -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } static int reveal_mesh_exec(bContext *C, wmOperator *op) @@ -2748,7 +2747,7 @@ static int reveal_mesh_exec(bContext *C, wmOperator *op) EM_reveal_mesh(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2798,7 +2797,7 @@ int select_by_number_vertices_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -2924,7 +2923,7 @@ static int select_sharp_edges_exec(bContext *C, wmOperator *op) // if (EM_texFaceCheck()) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ? + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); //TODO is this needed ? BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3092,7 +3091,7 @@ static int select_linked_flat_faces_exec(bContext *C, wmOperator *op) select_linked_flat_faces(em, op, RNA_float_get(op->ptr, "sharpness")); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3193,7 +3192,7 @@ static int select_non_manifold_exec(bContext *C, wmOperator *op) select_non_manifold(em, op); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3257,7 +3256,7 @@ static int select_inverse_mesh_exec(bContext *C, wmOperator *op) EM_select_swap(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3295,7 +3294,7 @@ static int toggle_select_all_exec(bContext *C, wmOperator *op) EM_toggle_select_all(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3366,7 +3365,7 @@ static int select_more(bContext *C, wmOperator *op) // if (EM_texFaceCheck(em)) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3456,7 +3455,7 @@ static int select_less(bContext *C, wmOperator *op) EM_select_less(em); // if (EM_texFaceCheck(em)) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3526,7 +3525,7 @@ static int mesh_select_random_exec(bContext *C, wmOperator *op) selectrandom_mesh(em, RNA_float_get(op->ptr,"percent")); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3577,7 +3576,7 @@ void EM_deselect_by_material(EditMesh *em, int index) EM_selectmode_flush(em); } -static void mesh_selection_type(Scene *scene, EditMesh *em, int val) +static void mesh_selection_type(ToolSettings *ts, EditMesh *em, int val) { if(val>0) { if(val==1) { @@ -3598,7 +3597,7 @@ static void mesh_selection_type(Scene *scene, EditMesh *em, int val) /* note, em stores selectmode to be able to pass it on everywhere without scene, this is only until all select modes and toolsettings are settled more */ - scene->toolsettings->selectmode= em->selectmode; + ts->selectmode= em->selectmode; // if (EM_texFaceCheck()) } } @@ -3612,13 +3611,13 @@ static EnumPropertyItem prop_mesh_edit_types[] = { static int mesh_selection_type_exec(bContext *C, wmOperator *op) { - + ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - mesh_selection_type(CTX_data_scene(C), em, RNA_enum_get(op->ptr,"type")); + mesh_selection_type(ts, em, RNA_enum_get(op->ptr,"type")); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -3648,7 +3647,6 @@ void MESH_OT_selection_type(wmOperatorType *ot) static int editmesh_mark_seam(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); Mesh *me= ((Mesh *)obedit->data); @@ -3681,8 +3679,8 @@ static int editmesh_mark_seam(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -3706,7 +3704,6 @@ void MESH_OT_mark_seam(wmOperatorType *ot) static int editmesh_mark_sharp(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); Mesh *me= ((Mesh *)obedit->data); @@ -3734,8 +3731,8 @@ static int editmesh_mark_sharp(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -3965,7 +3962,7 @@ void righthandfaces(EditMesh *em, int select) /* makes faces righthand turning * recalc_editnormals(em); -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); waitcursor(0); } @@ -3973,7 +3970,6 @@ void righthandfaces(EditMesh *em, int select) /* makes faces righthand turning * static int righthandfaces_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); @@ -3984,8 +3980,8 @@ static int righthandfaces_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ? + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); //TODO is this needed ? return OPERATOR_FINISHED; } @@ -4185,7 +4181,7 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, wmOperator *o static int smooth_vertex(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); + ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); EditVert *eve, *eve_mir = NULL; @@ -4273,7 +4269,7 @@ static int smooth_vertex(bContext *C, wmOperator *op) if(eve->f & SELECT) { if(eve->f1) { - if (scene->toolsettings->editbutflag & B_MESH_X_MIRROR) { + if (ts->editbutflag & B_MESH_X_MIRROR) { eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve->co); } @@ -4315,8 +4311,8 @@ static int smooth_vertex(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -4393,7 +4389,7 @@ void vertexnoise(Object *obedit, EditMesh *em) } recalc_editnormals(em); -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } @@ -4450,23 +4446,23 @@ static void vertices_to_sphere(Scene *scene, View3D *v3d, Object *obedit, EditMe } recalc_editnormals(em); -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } static int vertices_to_sphere_exec(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); vertices_to_sphere(scene, v3d, obedit, em, RNA_float_get(op->ptr,"percent")); BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -4512,7 +4508,6 @@ void flipface(EditMesh *em, EditFace *efa) static int flip_normals(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); EditFace *efa; @@ -4530,8 +4525,8 @@ static int flip_normals(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ac65820bfea..5a4397256de 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -484,11 +484,11 @@ int removedoublesflag(EditMesh *em, short flag, short automerge, float limit) / static int removedoublesflag_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); + ToolSettings *ts= CTX_data_tool_settings(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); char msg[100]; - int cnt = removedoublesflag(em,1,0,scene->toolsettings->doublimit); + int cnt = removedoublesflag(em,1,0,ts->doublimit); if(cnt) { @@ -496,8 +496,8 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_INFO, msg); } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -677,7 +677,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op) * This shouldn't be necessary, derived queries should be * automatically building this data if invalid. Or something. */ -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); object_handle_update(scene, obedit); /* individual faces? */ @@ -711,8 +711,8 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); RNA_enum_set(op->ptr, "proportional", 0); RNA_boolean_set(op->ptr, "mirror", 0); @@ -736,8 +736,8 @@ static int mesh_extrude_exec(bContext *C, wmOperator *op) extrude_mesh(scene, obedit, em, op); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -762,7 +762,6 @@ void MESH_OT_extrude(wmOperatorType *ot) static int split_mesh(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -776,8 +775,8 @@ static int split_mesh(bContext *C, wmOperator *op) WM_cursor_wait(0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -801,7 +800,6 @@ void MESH_OT_split(wmOperatorType *ot) static int extrude_repeat_mesh(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -837,8 +835,8 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op) EM_fgon_flags(em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -869,7 +867,7 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot) static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float degr, int dupli ) { Object *obedit= CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); + ToolSettings *ts= CTX_data_tool_settings(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); EditVert *eve,*nextve; float nor[3]= {0.0f, 0.0f, 0.0f}; @@ -891,7 +889,7 @@ static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float phi= degr*M_PI/360.0; phi/= steps; - if(scene->toolsettings->editbutflag & B_CLOCKWISE) phi= -phi; + if(ts->editbutflag & B_CLOCKWISE) phi= -phi; RNA_float_get_array(op->ptr, "axis", n); Normalize(n); @@ -907,7 +905,7 @@ static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float Mat3MulMat3(bmat,imat,tmat); if(dupli==0) - if(scene->toolsettings->editbutflag & B_KEEPORIG) + if(ts->editbutflag & B_KEEPORIG) adduplicateflag(em, 1); for(a=0; adata, OB_RECALC_DATA); } BKE_mesh_end_editmesh(obedit->data, em); @@ -950,7 +948,6 @@ static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float static int spin_mesh_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); int ok; @@ -960,8 +957,8 @@ static int spin_mesh_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -1006,7 +1003,6 @@ void MESH_OT_spin(wmOperatorType *ot) static int screw_mesh_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); EditVert *eve,*v1=0,*v2=0; @@ -1062,8 +1058,8 @@ static int screw_mesh_exec(bContext *C, wmOperator *op) } if(spin_mesh(C, op, dvec, turns*steps, 360.0f*turns, 0)) { - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1308,14 +1304,13 @@ static EnumPropertyItem prop_mesh_delete_types[] = { static int delete_mesh_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); delete_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type")); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2722,7 +2717,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float } } -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); // Now for each face in the mesh we need to figure out How many edges were cut // and which filling method to use for that face for(ef = em->faces.first;ef;ef = ef->next) { @@ -3696,7 +3691,6 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir) /* only accepts 1 selected edge, or 2 selected faces */ static int edge_rotate_selected(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); EditEdge *eed; @@ -3760,8 +3754,8 @@ static int edge_rotate_selected(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -4611,7 +4605,7 @@ useless: } else { draw = 0; } -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } @@ -4631,7 +4625,7 @@ useless: if(!immediate) EM_automerge(0); -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); // scrarea_queue_winredraw(curarea); //BLI_ghash_free(edgesgh, freeGHash, NULL); @@ -4681,7 +4675,7 @@ int EdgeLoopDelete(EditMesh *em, wmOperator *op) EM_select_more(em); removedoublesflag(em, 1,0, 0.001); EM_select_flush(em); - // DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + // DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return 1; } @@ -4793,7 +4787,6 @@ static void mesh_rip_setface(EditMesh *em, EditFace *sefa) /* based on mouse cursor position, it defines how is being ripped */ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) { - Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); RegionView3D *rv3d= ar->regiondata; Object *obedit= CTX_data_edit_object(C); @@ -4989,8 +4982,8 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) } } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); @@ -5061,7 +5054,7 @@ void shape_propagate(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op) } } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return; } @@ -5106,7 +5099,7 @@ void shape_copy_from_lerp(EditMesh *em, KeyBlock* thisBlock, KeyBlock* fromBlock } } sprintf(str,"Blending at %d%c MMB to Copy at 100%c",(int)(perc*100),'%','%'); -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); // headerprint(str); // force_draw(0); @@ -5764,7 +5757,6 @@ int merge_target(EditMesh *em, int target, int uvmerge) static int merge_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); int count= 0, uvs= RNA_boolean_get(op->ptr, "uvs"); @@ -5794,8 +5786,8 @@ static int merge_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -6040,7 +6032,7 @@ int select_vertex_path_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -6108,7 +6100,7 @@ static int region_to_loop(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -6284,7 +6276,7 @@ static int loop_to_region(bContext *C, wmOperator *op) freecollections(&allcollections); BKE_mesh_end_editmesh(obedit->data, em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -6311,7 +6303,6 @@ void MESH_OT_loop_to_region(wmOperatorType *ot) static int mesh_rotate_uvs(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -6378,15 +6369,14 @@ static int mesh_rotate_uvs(bContext *C, wmOperator *op) if(!change) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } static int mesh_mirror_uvs(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -6468,15 +6458,14 @@ static int mesh_mirror_uvs(bContext *C, wmOperator *op) if(!change) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } static int mesh_rotate_colors(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -6525,8 +6514,8 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op) if(!change) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -6534,7 +6523,6 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op) static int mesh_mirror_colors(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -6582,8 +6570,8 @@ static int mesh_mirror_colors(bContext *C, wmOperator *op) if(!change) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -6664,7 +6652,7 @@ void MESH_OT_colors_mirror(wmOperatorType *ot) static int subdivide_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); + ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); int cuts= RNA_int_get(op->ptr,"number_cuts"); @@ -6677,10 +6665,10 @@ static int subdivide_exec(bContext *C, wmOperator *op) if(fractal != 0.0f) flag |= B_FRACTAL; - esubdivideflag(obedit, em, 1, smooth, fractal, scene->toolsettings->editbutflag|flag, cuts, 0); + esubdivideflag(obedit, em, 1, smooth, fractal, ts->editbutflag|flag, cuts, 0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -6953,7 +6941,6 @@ static void fill_mesh(EditMesh *em) static int fill_mesh_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -6961,8 +6948,8 @@ static int fill_mesh_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; @@ -6985,7 +6972,6 @@ void MESH_OT_fill(wmOperatorType *ot) static int beauty_fill_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -6993,8 +6979,8 @@ static int beauty_fill_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -7018,14 +7004,13 @@ void MESH_OT_beauty_fill(wmOperatorType *ot) static int quads_convert_to_tris_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); convert_to_triface(em,0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -7048,14 +7033,13 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot) static int tris_convert_to_quads_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); join_triangles(em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -7078,14 +7062,13 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot) static int edge_flip_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); edge_flip(em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -7124,7 +7107,6 @@ void mesh_set_smooth_faces(EditMesh *em, short smooth) static int mesh_faces_shade_smooth_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -7132,8 +7114,8 @@ static int mesh_faces_shade_smooth_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -7155,14 +7137,13 @@ void MESH_OT_faces_shade_smooth(wmOperatorType *ot) static int mesh_faces_shade_flat_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); mesh_set_smooth_faces(em, 0); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/mesh_layers.c b/source/blender/editors/mesh/mesh_layers.c index 17a448ecf90..a36c7a56b7c 100644 --- a/source/blender/editors/mesh/mesh_layers.c +++ b/source/blender/editors/mesh/mesh_layers.c @@ -152,20 +152,21 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la /*********************** UV texture operators ************************/ +static int layers_poll(bContext *C) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ID *data= (ob)? ob->data: NULL; + return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib); +} + static int uv_texture_add_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me; + Mesh *me= ob->data; EditMesh *em; int layernum; - if(!ob || ob->type!=OB_MESH) - return OPERATOR_CANCELLED; - - me= (Mesh*)ob->data; - - if(scene->obedit == ob) { + if(me->edit_mesh) { em= me->edit_mesh; layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE); @@ -175,7 +176,7 @@ static int uv_texture_add_exec(bContext *C, wmOperator *op) EM_add_data_layer(em, &em->fdata, CD_MTFACE); CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum); } - else if(ob) { + else { layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE); if(layernum >= MAX_MTFACE) return OPERATOR_CANCELLED; @@ -189,8 +190,8 @@ static int uv_texture_add_exec(bContext *C, wmOperator *op) mesh_update_customdata_pointers(me); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return OPERATOR_FINISHED; } @@ -203,6 +204,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) ot->idname= "MESH_OT_uv_texture_add"; /* api callbacks */ + ot->poll= layers_poll; ot->exec= uv_texture_add_exec; /* flags */ @@ -211,16 +213,11 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) static int uv_texture_remove_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me; + Mesh *me= ob->data; CustomDataLayer *cdl; int index; - if(!ob || ob->type!=OB_MESH) - return OPERATOR_CANCELLED; - - me= (Mesh*)ob->data; index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); cdl= (index == -1)? NULL: &me->fdata.layers[index]; @@ -229,8 +226,8 @@ static int uv_texture_remove_exec(bContext *C, wmOperator *op) delete_customdata_layer(C, ob, cdl); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return OPERATOR_FINISHED; } @@ -243,6 +240,7 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot) ot->idname= "MESH_OT_uv_texture_remove"; /* api callbacks */ + ot->poll= layers_poll; ot->exec= uv_texture_remove_exec; /* flags */ @@ -255,17 +253,12 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me; + Mesh *me= ob->data; EditMesh *em; MCol *mcol; int layernum; - if(!ob || ob->type!=OB_MESH) - return OPERATOR_CANCELLED; - - me= (Mesh*)ob->data; - - if(scene->obedit == ob) { + if(me->edit_mesh) { em= me->edit_mesh; layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL); @@ -294,8 +287,8 @@ static int vertex_color_add_exec(bContext *C, wmOperator *op) shadeMeshMCol(scene, ob, me); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return OPERATOR_FINISHED; } @@ -308,6 +301,7 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot) ot->idname= "MESH_OT_vertex_color_add"; /* api callbacks */ + ot->poll= layers_poll; ot->exec= vertex_color_add_exec; /* flags */ @@ -316,16 +310,11 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot) static int vertex_color_remove_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me; + Mesh *me= ob->data; CustomDataLayer *cdl; int index; - if(!ob || ob->type!=OB_MESH) - return OPERATOR_CANCELLED; - - me= (Mesh*)ob->data; index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL); cdl= (index == -1)? NULL: &me->fdata.layers[index]; @@ -334,8 +323,8 @@ static int vertex_color_remove_exec(bContext *C, wmOperator *op) delete_customdata_layer(C, ob, cdl); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return OPERATOR_FINISHED; } @@ -349,6 +338,7 @@ void MESH_OT_vertex_color_remove(wmOperatorType *ot) /* api callbacks */ ot->exec= vertex_color_remove_exec; + ot->poll= layers_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -358,22 +348,16 @@ void MESH_OT_vertex_color_remove(wmOperatorType *ot) static int sticky_add_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me; - - if(!ob || ob->type!=OB_MESH) - return OPERATOR_CANCELLED; - - me= (Mesh*)ob->data; + Mesh *me= ob->data; if(me->msticky) return OPERATOR_CANCELLED; // XXX RE_make_sticky(); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return OPERATOR_FINISHED; } @@ -386,6 +370,7 @@ void MESH_OT_sticky_add(wmOperatorType *ot) ot->idname= "MESH_OT_sticky_add"; /* api callbacks */ + ot->poll= layers_poll; ot->exec= sticky_add_exec; /* flags */ @@ -394,14 +379,8 @@ void MESH_OT_sticky_add(wmOperatorType *ot) static int sticky_remove_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Mesh *me; - - if(!ob || ob->type!=OB_MESH) - return OPERATOR_CANCELLED; - - me= (Mesh*)ob->data; + Mesh *me= ob->data; if(!me->msticky) return OPERATOR_CANCELLED; @@ -409,8 +388,8 @@ static int sticky_remove_exec(bContext *C, wmOperator *op) CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert); me->msticky= NULL; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return OPERATOR_FINISHED; } @@ -423,6 +402,7 @@ void MESH_OT_sticky_remove(wmOperatorType *ot) ot->idname= "MESH_OT_sticky_remove"; /* api callbacks */ + ot->poll= layers_poll; ot->exec= sticky_remove_exec; /* flags */ diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 5d4be254593..2ef1d3b214d 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -681,7 +681,7 @@ void sort_faces(Scene *scene, View3D *v3d) MEM_freeN(index); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); } diff --git a/source/blender/editors/metaball/editmball.c b/source/blender/editors/metaball/editmball.c index b9bb219783f..9ab985fb3fb 100644 --- a/source/blender/editors/metaball/editmball.c +++ b/source/blender/editors/metaball/editmball.c @@ -212,8 +212,8 @@ static int select_deselect_all_metaelems_exec(bContext *C, wmOperator *op) else ml->flag |= SELECT; ml= ml->next; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - //DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); + //DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } return OPERATOR_FINISHED; @@ -251,7 +251,7 @@ static int select_inverse_metaelems_exec(bContext *C, wmOperator *op) ml->flag |= SELECT; ml= ml->next; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); } return OPERATOR_FINISHED; @@ -296,7 +296,7 @@ static int select_random_metaelems_exec(bContext *C, wmOperator *op) ml= ml->next; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); return OPERATOR_FINISHED; } @@ -325,7 +325,6 @@ void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot) /* Duplicate selected MetaElements */ static int duplicate_metaelems_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); MetaBall *mb = (MetaBall*)obedit->data; MetaElem *ml, *newml; @@ -341,8 +340,8 @@ static int duplicate_metaelems_exec(bContext *C, wmOperator *op) } ml= ml->prev; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } return OPERATOR_FINISHED; @@ -384,7 +383,6 @@ void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) /* Delete all selected MetaElems (not MetaBall) */ static int delete_metaelems_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); MetaBall *mb= (MetaBall*)obedit->data; MetaElem *ml, *next; @@ -400,8 +398,8 @@ static int delete_metaelems_exec(bContext *C, wmOperator *op) } ml= next; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } return OPERATOR_FINISHED; @@ -426,7 +424,6 @@ void MBALL_OT_delete_metaelems(wmOperatorType *ot) /* Hide selected MetaElems */ static int hide_metaelems_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); MetaBall *mb= (MetaBall*)obedit->data; MetaElem *ml; @@ -450,8 +447,8 @@ static int hide_metaelems_exec(bContext *C, wmOperator *op) ml= ml->next; } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } return OPERATOR_FINISHED; @@ -479,7 +476,6 @@ void MBALL_OT_hide_metaelems(wmOperatorType *ot) /* Unhide all edited MetaElems */ static int reveal_metaelems_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); MetaBall *mb= (MetaBall*)obedit->data; MetaElem *ml; @@ -491,8 +487,8 @@ static int reveal_metaelems_exec(bContext *C, wmOperator *op) ml->flag &= ~MB_HIDE; ml= ml->next; } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); } return OPERATOR_FINISHED; @@ -584,7 +580,7 @@ void mouse_mball(bContext *C, short mval[2], int extend) } mb->lastelem= act; - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); } } } diff --git a/source/blender/editors/object/editconstraint.c b/source/blender/editors/object/editconstraint.c index dc0442a5af9..c1b1062bfc4 100644 --- a/source/blender/editors/object/editconstraint.c +++ b/source/blender/editors/object/editconstraint.c @@ -825,7 +825,6 @@ void CONSTRAINT_OT_move_up (wmOperatorType *ot) static int pose_constraints_clear_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); /* free constraints for all selected bones */ @@ -836,7 +835,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* do updates */ - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob); return OPERATOR_FINISHED; @@ -857,7 +856,6 @@ void POSE_OT_constraints_clear(wmOperatorType *ot) static int object_constraints_clear_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); /* do freeing */ @@ -865,7 +863,7 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *op) free_constraints(&ob->constraints); /* do updates */ - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); return OPERATOR_FINISHED; @@ -1138,10 +1136,10 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase if ((ob->type==OB_ARMATURE) && (pchan)) { ob->pose->flag |= POSE_RECALC; /* sort pose channels */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA|OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB); } else - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, ob); @@ -1376,7 +1374,6 @@ void POSE_OT_ik_add(wmOperatorType *ot) /* remove IK constraints from selected bones */ static int pose_ik_clear_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Object *ob= CTX_data_active_object(C); /* only remove IK Constraints */ @@ -1397,7 +1394,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); diff --git a/source/blender/editors/object/editkey.c b/source/blender/editors/object/editkey.c index 82194a4c3b4..2ec3edd846a 100644 --- a/source/blender/editors/object/editkey.c +++ b/source/blender/editors/object/editkey.c @@ -473,7 +473,7 @@ int ED_object_shape_key_remove(bContext *C, Scene *scene, Object *ob) free_libblock_us(&(bmain->key), key); } - DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return 1; @@ -481,14 +481,18 @@ int ED_object_shape_key_remove(bContext *C, Scene *scene, Object *ob) /********************** shape key operators *********************/ +static int shape_key_poll(bContext *C) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ID *data= (ob)? ob->data: NULL; + return (ob && !ob->id.lib && data && !data->lib); +} + static int shape_key_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - if(!ob) - return OPERATOR_CANCELLED; - ED_object_shape_key_add(C, scene, ob); return OPERATOR_FINISHED; @@ -501,6 +505,7 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot) ot->idname= "OBJECT_OT_shape_key_add"; /* api callbacks */ + ot->poll= shape_key_poll; ot->exec= shape_key_add_exec; /* flags */ @@ -509,12 +514,9 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot) static int shape_key_remove_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - if(!ob) - return OPERATOR_CANCELLED; - if(!ED_object_shape_key_remove(C, scene, ob)) return OPERATOR_CANCELLED; @@ -528,97 +530,10 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot) ot->idname= "OBJECT_OT_shape_key_remove"; /* api callbacks */ + ot->poll= shape_key_poll; ot->exec= shape_key_remove_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -void move_keys(Object *ob) -{ -#if 0 - /* XXX probably goes away entirely */ - Key *key; - KeyBlock *kb; - float div, dy, oldpos, vec[3], dvec[3]; - int afbreek=0, firsttime= 1; - unsigned short event = 0; - short mval[2], val, xo, yo; - char str[32]; - - if(G.sipo->blocktype!=ID_KE) return; - - if(G.sipo->ipo && G.sipo->ipo->id.lib) return; - if(G.sipo->editipo==NULL) return; - - key= ob_get_key(ob); - if(key==NULL) return; - - /* which kb is involved */ - kb= BLI_findlink(&key->block, ob->shapenr-1); - if(kb==NULL) return; - - oldpos= kb->pos; - - getmouseco_areawin(mval); - xo= mval[0]; - yo= mval[1]; - dvec[0]=dvec[1]=dvec[2]= 0.0; - - while(afbreek==0) { - getmouseco_areawin(mval); - if(mval[0]!=xo || mval[1]!=yo || firsttime) { - firsttime= 0; - - dy= (float)(mval[1]- yo); - - div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin); - dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; - - VECCOPY(vec, dvec); - - apply_keyb_grid(vec, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID); - apply_keyb_grid(vec+1, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID); - - kb->pos= oldpos+vec[1]; - - sprintf(str, "Y: %.3f ", vec[1]); - headerprint(str); - - xo= mval[0]; - yo= mval[1]; - - force_draw(0); - } - else BIF_wait_for_statechange(); - - while(qtest()) { - event= extern_qread(&val); - if(val) { - switch(event) { - case ESCKEY: - case LEFTMOUSE: - case SPACEKEY: - afbreek= 1; - break; - default: - arrows_move_cursor(event); - } - } - } - } - - if(event==ESCKEY) { - kb->pos= oldpos; - } - - sort_keys(key); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - - /* for boundbox */ - editipo_changed(G.sipo, 0); - - BIF_undo_push("Move Shapekey(s)"); -#endif -} - diff --git a/source/blender/editors/object/editlattice.c b/source/blender/editors/object/editlattice.c index 3e30efd635a..3ec1f3af014 100644 --- a/source/blender/editors/object/editlattice.c +++ b/source/blender/editors/object/editlattice.c @@ -203,7 +203,7 @@ int de_select_all_exec(bContext *C, wmOperator *op) else setflagsLatt(obedit, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -234,7 +234,6 @@ int make_regular_poll(bContext *C) int make_regular_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); Lattice *lt; @@ -248,8 +247,8 @@ int make_regular_exec(bContext *C, wmOperator *op) resizelattice(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -318,7 +317,7 @@ void mouse_lattice(bContext *C, short mval[2], int extend) else bp->f1 ^= SELECT; /* swap */ - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); } } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index a5e92096ef9..53882ad8424 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -193,7 +193,7 @@ void ED_base_object_activate(bContext *C, Base *base) for(tbase=FIRSTBASE; tbase; tbase= tbase->next) { if(base!=tbase && (tbase->object->shapeflag & OB_SHAPE_TEMPLOCK)) { tbase->object->shapeflag &= ~OB_SHAPE_TEMPLOCK; - DAG_object_flush_update(scene, tbase->object, OB_RECALC_DATA); + DAG_id_flush_update(&tbase->object->id, OB_RECALC_DATA); } } WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); @@ -343,7 +343,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op) ED_object_enter_editmode(C, EM_DO_UNDO); newob = 1; } - else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); switch(RNA_enum_get(op->ptr, "type")) { case 0: @@ -379,7 +379,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, EM_FREEDATA); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; } @@ -425,7 +425,7 @@ static int object_add_curve_exec(bContext *C, wmOperator *op) ED_object_enter_editmode(C, 0); newob = 1; } - else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); obedit= CTX_data_edit_object(C); nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob); @@ -437,7 +437,7 @@ static int object_add_curve_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, EM_FREEDATA); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; } @@ -500,7 +500,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op) ED_object_enter_editmode(C, 0); newob = 1; } - else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); obedit= CTX_data_edit_object(C); nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob); @@ -512,7 +512,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, EM_FREEDATA); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; } @@ -557,7 +557,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) ED_object_enter_editmode(C, 0); newob = 1; } - else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); obedit= CTX_data_edit_object(C); elem= (MetaElem*)add_metaball_primitive(C, RNA_enum_get(op->ptr, "type"), newob); @@ -569,7 +569,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, EM_FREEDATA); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; } @@ -621,7 +621,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op) if(U.flag & USER_ADD_EDITMODE) ED_object_enter_editmode(C, 0); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; } @@ -653,7 +653,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) ED_object_enter_editmode(C, 0); newob = 1; } - else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); if(v3d) rv3d= CTX_wm_region(C)->regiondata; @@ -666,7 +666,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) ED_object_exit_editmode(C, EM_FREEDATA); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; } @@ -3034,7 +3034,7 @@ static int make_proxy_exec (bContext *C, wmOperator *op) /* depsgraph flushes are needed for the new data */ DAG_scene_sort(scene); - DAG_object_flush_update(scene, newob, OB_RECALC); + DAG_id_flush_update(&newob->id, OB_RECALC); WM_event_add_notifier(C, NC_OBJECT, NULL); } @@ -3543,7 +3543,7 @@ static int object_center_set_exec(bContext *C, wmOperator *op) recalc_editnormals(em); tot_change++; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); BKE_mesh_end_editmesh(me, em); } } @@ -3735,7 +3735,7 @@ static int object_center_set_exec(bContext *C, wmOperator *op) tot_change++; if(obedit) { if (centermode==0) { - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); } break; } @@ -3884,7 +3884,7 @@ void ED_object_exit_editmode(bContext *C, int flag) scene->obedit= NULL; // XXX for context /* also flush ob recalc, doesn't take much overhead, but used for particles */ - DAG_object_flush_update(scene, obedit, OB_RECALC_OB|OB_RECALC_DATA); + DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); ED_undo_push(C, "Editmode"); @@ -3963,7 +3963,7 @@ void ED_object_enter_editmode(bContext *C, int flag) scene->obedit= ob; ED_armature_to_edit(ob); /* to ensure all goes in restposition and without striding */ - DAG_object_flush_update(scene, ob, OB_RECALC); + DAG_id_flush_update(&ob->id, OB_RECALC); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene); } @@ -3997,7 +3997,7 @@ void ED_object_enter_editmode(bContext *C, int flag) } if(ok) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { scene->obedit= NULL; // XXX for context @@ -4327,7 +4327,7 @@ void special_editmenu(Scene *scene, View3D *v3d) } } } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else if(ob->mode & OB_MODE_VERTEX_PAINT) { Mesh *me= get_mesh(ob); @@ -4339,7 +4339,7 @@ void special_editmenu(Scene *scene, View3D *v3d) // XXX do_shared_vertexcol(me); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } else if(ob->mode & OB_MODE_WEIGHT_PAINT) { @@ -4386,7 +4386,7 @@ void special_editmenu(Scene *scene, View3D *v3d) break; } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); if(nr>0) waitcursor(0); #endif @@ -4809,7 +4809,7 @@ static void object_flip_subdivison_particles(Scene *scene, Object *ob, int *set, } } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } if(ob->dup_group && depth<=4) { @@ -6790,7 +6790,6 @@ void OBJECT_OT_join(wmOperatorType *ot) static int shade_smooth_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob; Curve *cu; Nurb *nu; @@ -6803,7 +6802,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) if(ob->type==OB_MESH) { mesh_set_smooth_flag(ob, !clear); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); done= 1; @@ -6817,7 +6816,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) nu= nu->next; } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); done= 1; @@ -6904,7 +6903,7 @@ void image_aspect(Scene *scene, View3D *v3d) else ob->size[1]= ob->size[0]*y/x; done= 1; - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } } if(done) break; @@ -7184,7 +7183,7 @@ void hookmenu(Scene *scene, View3D *v3d) Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); changed= 1; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } else { float *curs = give_cursor(scene, v3d); @@ -7202,7 +7201,7 @@ void hookmenu(Scene *scene, View3D *v3d) Mat3MulVecfl(imat, hmd->cent); changed= 1; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 96e485e5462..aecb778db06 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -119,7 +119,7 @@ int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int ty DAG_scene_sort(scene); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); return 1; } @@ -168,7 +168,7 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod BLI_remlink(&ob->modifiers, md); modifier_free(md); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); return 1; } @@ -376,7 +376,7 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi MEM_freeN(vertexCos); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); @@ -408,7 +408,8 @@ int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md) static int modifier_poll(bContext *C) { - return (CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier).data != NULL); + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); + return (ptr.data != NULL && !((ID*)ptr.id.data)->lib); } /************************ add modifier operator *********************/ @@ -518,7 +519,6 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot) static int modifier_move_up_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); Object *ob= ptr.id.data; ModifierData *md= ptr.data; @@ -526,7 +526,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) if(!ED_object_modifier_move_up(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -550,7 +550,6 @@ void OBJECT_OT_modifier_move_up(wmOperatorType *ot) static int modifier_move_down_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); Object *ob= ptr.id.data; ModifierData *md= ptr.data; @@ -558,7 +557,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op) if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -590,7 +589,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op) if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md)) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -622,7 +621,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op) if(!ob || !md || !ED_object_modifier_convert(op->reports, scene, ob, md)) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -646,7 +645,6 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot) static int modifier_copy_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); Object *ob= ptr.id.data; ModifierData *md= ptr.data; @@ -654,7 +652,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op) if(!ob || !md || !ED_object_modifier_copy(op->reports, ob, md)) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -718,8 +716,9 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) static int multires_subdivide_poll(bContext *C) { - return (CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier).data != NULL) && - CTX_data_edit_object(C) == NULL; + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier); + ID *id= ptr.id.data; + return (ptr.data && id && !id->lib); } void OBJECT_OT_multires_subdivide(wmOperatorType *ot) @@ -739,7 +738,9 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot) static int meshdeform_poll(bContext *C) { - return CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier).data != NULL; + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MeshDeformModifier); + ID *id= ptr.id.data; + return (ptr.data && id && !id->lib); } static int meshdeform_bind_exec(bContext *C, wmOperator *op) @@ -864,12 +865,13 @@ static uiBlock *modifiers_add_menu(void *ob_v) static int hook_poll(bContext *C) { - return CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier).data != NULL; + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); + ID *id= ptr.id.data; + return (ptr.data && id && !id->lib); } static int hook_reset_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); Object *ob= ptr.id.data; HookModifierData *hmd= ptr.data; @@ -892,7 +894,7 @@ static int hook_reset_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -925,7 +927,7 @@ static int hook_recenter_exec(bContext *C, wmOperator *op) VECSUB(hmd->cent, scene->cursor, ob->obmat[3]); Mat3MulVecfl(imat, hmd->cent); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -952,7 +954,7 @@ static int hook_select_exec(bContext *C, wmOperator *op) object_hook_select(ob, hmd); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; } @@ -972,7 +974,6 @@ void OBJECT_OT_hook_select(wmOperatorType *ot) static int hook_assign_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); Object *ob= ptr.id.data; HookModifierData *hmd= ptr.data; @@ -992,7 +993,7 @@ static int hook_assign_exec(bContext *C, wmOperator *op) hmd->indexar= indexar; hmd->totindex= tot; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; @@ -1015,19 +1016,20 @@ void OBJECT_OT_hook_assign(wmOperatorType *ot) static int explode_refresh_poll(bContext *C) { - return CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier).data != NULL; + PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier); + ID *id= ptr.id.data; + return (ptr.data && id && !id->lib); } static int explode_refresh_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_ExplodeModifier); Object *ob= ptr.id.data; ExplodeModifierData *emd= ptr.data; emd->flag |= eExplodeFlag_CalcFaces; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 767a04d9170..1660160b56c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1102,17 +1102,21 @@ void vgroup_operation_with_menu(Object *ob) /********************** vertex group operators *********************/ -static int vertex_group_add_exec(bContext *C, wmOperator *op) +static int vertex_group_poll(bContext *C) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Scene *scene= CTX_data_scene(C); + ID *data= (ob)? ob->data: NULL; + return (ob && !ob->id.lib && data && !data->lib); +} - if(!ob) - return OPERATOR_CANCELLED; +static int vertex_group_add_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; add_defgroup(ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } @@ -1124,6 +1128,7 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_add"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_add_exec; /* flags */ @@ -1135,18 +1140,16 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op) Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Scene *scene= CTX_data_scene(C); - if(!ob) - return OPERATOR_CANCELLED; - if(scene->obedit == ob) { del_defgroup(ob); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); } else { del_defgroup_in_object_mode(ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } + + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } @@ -1158,6 +1161,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_remove"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_remove_exec; /* flags */ @@ -1166,16 +1170,12 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) static int vertex_group_assign_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); ToolSettings *ts= CTX_data_tool_settings(C); Object *ob= CTX_data_edit_object(C); - if(!ob) - return OPERATOR_CANCELLED; - assign_verts_defgroup(ob, ts->vgroup_weight); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -1187,6 +1187,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_assign"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_assign_exec; /* flags */ @@ -1195,15 +1196,11 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); - if(!ob) - return OPERATOR_CANCELLED; - remove_verts_defgroup(ob, 0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -1215,6 +1212,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_remove_from"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_remove_from_exec; /* flags */ @@ -1225,11 +1223,11 @@ static int vertex_group_select_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - if(!ob) + if(!ob || ob->id.lib) return OPERATOR_CANCELLED; - sel_verts_defgroup(ob, 1); /* runs countall() */ - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + sel_verts_defgroup(ob, 1); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; } @@ -1241,6 +1239,7 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_select"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_select_exec; /* flags */ @@ -1251,11 +1250,8 @@ static int vertex_group_deselect_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - if(!ob) - return OPERATOR_CANCELLED; - - sel_verts_defgroup(ob, 0); /* runs countall() */ - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + sel_verts_defgroup(ob, 0); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; } @@ -1267,6 +1263,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_deselect"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_deselect_exec; /* flags */ @@ -1275,15 +1272,12 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) static int vertex_group_copy_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - if(!ob) - return OPERATOR_CANCELLED; - duplicate_defgroup(ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -1295,6 +1289,7 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_copy"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_copy_exec; /* flags */ @@ -1308,9 +1303,6 @@ static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op) Base *base; int retval= OPERATOR_CANCELLED; - if(!ob) - return retval; - for(base=scene->base.first; base; base= base->next) { if(base->object->type==ob->type) { if(base->object!=ob && base->object->data==ob->data) { @@ -1318,8 +1310,9 @@ static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op) BLI_duplicatelist(&base->object->defbase, &ob->defbase); base->object->actdef= ob->actdef; - DAG_object_flush_update(scene, base->object, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, base->object); + DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, base->object); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data); retval = OPERATOR_FINISHED; } @@ -1336,6 +1329,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_copy_to_linked"; /* api callbacks */ + ot->poll= vertex_group_poll; ot->exec= vertex_group_copy_to_linked_exec; /* flags */ diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 220928cb79c..3ddc143b5a3 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -1018,7 +1018,6 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys) static void PE_update_selection(Scene *scene, Object *ob, int useflag) { - ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit= PE_get_current(scene, ob); HairKey *hkey; POINT_P; KEY_K; @@ -1156,7 +1155,7 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) point->flag &= ~PEP_EDIT_RECALC; } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } /************************************************/ @@ -1235,7 +1234,7 @@ static int de_select_all_exec(bContext *C, wmOperator *op) } PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); return OPERATOR_FINISHED; } @@ -1283,7 +1282,7 @@ int PE_mouse_particles(bContext *C, short *mval, int extend) for_mouse_hit_keys(&data, toggle_key_select, 1); /* nearest only */ PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, data.ob); return OPERATOR_FINISHED; } @@ -1301,7 +1300,7 @@ static int select_first_exec(bContext *C, wmOperator *op) PE_set_data(C, &data); foreach_point(&data, select_root); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, data.ob); return OPERATOR_FINISHED; } @@ -1334,7 +1333,7 @@ static int select_last_exec(bContext *C, wmOperator *op) PE_set_data(C, &data); foreach_point(&data, select_tip); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, data.ob); return OPERATOR_FINISHED; } @@ -1374,7 +1373,7 @@ static int select_linked_exec(bContext *C, wmOperator *op) for_mouse_hit_keys(&data, select_keys, 1); /* nearest only */ PE_update_selection(data.scene, data.ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, data.ob); return OPERATOR_FINISHED; } @@ -1429,7 +1428,7 @@ int PE_border_select(bContext *C, rcti *rect, int select) for_mouse_hit_keys(&data, select_key, 0); PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); return OPERATOR_FINISHED; } @@ -1454,7 +1453,7 @@ int PE_circle_select(bContext *C, int selecting, short *mval, float rad) for_mouse_hit_keys(&data, select_key, 0); PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); return OPERATOR_FINISHED; } @@ -1520,7 +1519,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select) } PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); return OPERATOR_FINISHED; } @@ -1554,7 +1553,7 @@ static int hide_exec(bContext *C, wmOperator *op) } PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); return OPERATOR_FINISHED; } @@ -1596,7 +1595,7 @@ static int reveal_exec(bContext *C, wmOperator *op) } PE_update_selection(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); return OPERATOR_FINISHED; } @@ -1650,7 +1649,7 @@ static int select_less_exec(bContext *C, wmOperator *op) PE_set_data(C, &data); foreach_point(&data, select_less_keys); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, data.ob); return OPERATOR_FINISHED; } @@ -1708,7 +1707,7 @@ static int select_more_exec(bContext *C, wmOperator *op) PE_set_data(C, &data); foreach_point(&data, select_more_keys); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, data.ob); return OPERATOR_FINISHED; } @@ -1796,7 +1795,7 @@ static int rekey_exec(bContext *C, wmOperator *op) recalc_lengths(data.edit); PE_update_object(data.scene, data.ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, data.ob); return OPERATOR_FINISHED; } @@ -2091,7 +2090,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) recalc_lengths(data.edit); PE_update_object(data.scene, data.ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, data.ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, data.ob); return OPERATOR_FINISHED; } @@ -2180,8 +2179,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) BKE_reportf(op->reports, RPT_INFO, "Remove %d double particles.", totremoved); PE_update_object(scene, ob, 0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, ob); return OPERATOR_FINISHED; } @@ -2358,8 +2357,8 @@ static int delete_exec(bContext *C, wmOperator *op) PE_update_object(data.scene, data.ob, 0); - DAG_object_flush_update(data.scene, data.ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, data.ob); + DAG_id_flush_update(&data.ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, data.ob); return OPERATOR_FINISHED; } @@ -2512,8 +2511,8 @@ static int mirror_exec(bContext *C, wmOperator *op) PE_mirror_x(scene, ob, 0); update_world_cos(ob, edit); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -2593,11 +2592,11 @@ static int set_edit_mode_exec(bContext *C, wmOperator *op) void PARTICLE_OT_edit_type_set(wmOperatorType *ot) { /* identifiers */ - ot->name= "Set Brush"; + ot->name= "Set Edit Type"; ot->idname= "PARTICLE_OT_edit_type_set"; /* api callbacks */ - ot->exec= set_brush_exec; + ot->exec= set_edit_mode_exec; ot->invoke= WM_menu_invoke; ot->poll= PE_poll; @@ -2627,11 +2626,9 @@ static void brush_comb(PEData *data, float mat[][4], float imat[][4], int point_ static void brush_cut(PEData *data, int pa_index) { PTCacheEdit *edit = data->edit; - ParticleSystem *psys= edit->psys; ARegion *ar= data->vc.ar; Object *ob= data->ob; ParticleEditSettings *pset= PE_settings(data->scene); - ParticleData *pa= &psys->particles[pa_index]; ParticleCacheKey *key= edit->pathcache[pa_index]; float rad2, cut_time= 1.0; float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv; @@ -3237,12 +3234,12 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) update_world_cos(ob,edit); psys_free_path_cache(NULL, edit); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else PE_update_object(scene, ob, 1); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_SELECT, ob); bedit->lastmouse[0]= mouse[0]; bedit->lastmouse[1]= mouse[1]; @@ -3553,7 +3550,7 @@ void PE_undo_step(Scene *scene, int step) } PE_update_object(scene, OBACT, 0); - DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); + DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); } static void PTCacheUndo_number(Scene *scene, PTCacheEdit *edit, int nr) @@ -3780,9 +3777,7 @@ static int particle_edit_toggle_poll(bContext *C) static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit= PE_get_current(scene, ob); if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { ob->mode |= OB_MODE_PARTICLE_EDIT; @@ -3795,7 +3790,7 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); return OPERATOR_FINISHED; } @@ -3819,7 +3814,6 @@ void PARTICLE_OT_particle_edit_toggle(wmOperatorType *ot) static int clear_edited_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); ParticleSystem *psys = psys_get_current(ob); @@ -3833,7 +3827,7 @@ static int clear_edited_exec(bContext *C, wmOperator *op) psys->recalc |= PSYS_RECALC_RESET; psys_reset(psys, PSYS_RESET_DEPSGRAPH); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index d082e17cda3..870b66cdbbd 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5184,7 +5184,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) toggle_paint_cursor(C, 1); } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_SCENE|ND_MODE, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index f66a9fbc1ed..953a055c9e5 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -295,7 +295,7 @@ void make_vertexcol(Scene *scene, int shade) /* single ob */ else memset(me->mcol, 255, 4*sizeof(MCol)*me->totface); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); } @@ -358,7 +358,7 @@ void clear_vpaint(Scene *scene, int selected) } } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); } @@ -468,7 +468,7 @@ void clear_wpaint_selectedfaces(Scene *scene) MEM_freeN(indexar); copy_wpaint_prev(wp, NULL, 0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); } @@ -923,7 +923,7 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) val= 0; // XXX pupmenu(str); if(val>=0) { ob->actdef= val+1; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); } MEM_freeN(str); } @@ -1049,7 +1049,7 @@ static int set_wpaint(bContext *C, wmOperator *op) /* toggle */ * exit (exit needs doing regardless because we * should redeform). */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); if(ob->mode & OB_MODE_WEIGHT_PAINT) { Object *par; @@ -1446,7 +1446,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); - DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); ED_region_tag_redraw(vc->ar); } @@ -1478,7 +1478,7 @@ static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke) } } - DAG_object_flush_update(CTX_data_scene(C), ob, OB_RECALC_DATA); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); MEM_freeN(wpd); } @@ -1564,7 +1564,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ if (me) /* update modifier stack for mapping requirements */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&me->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_SCENE|ND_MODE, scene); @@ -1735,7 +1735,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P ED_region_tag_redraw(vc->ar); - DAG_object_flush_update(vc->scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); } static void vpaint_stroke_done(bContext *C, struct PaintStroke *stroke) diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 2977d07d845..b7a3df563ea 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -372,6 +372,10 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) }*/ ED_area_tag_refresh(sa); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_DOPESHEET) + ED_area_tag_redraw(sa); + break; } } diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 954a52c54aa..8cdc6b0cd2b 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -260,7 +260,6 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot) static int material_slot_assign_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; if(!ob) @@ -298,8 +297,8 @@ static int material_slot_assign_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -377,7 +376,7 @@ static int material_slot_de_select(bContext *C, int select) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; } @@ -648,7 +647,7 @@ static int new_particle_settings_exec(bContext *C, wmOperator *op) psys_check_boid_data(psys); DAG_scene_sort(scene); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -695,7 +694,7 @@ static int new_particle_target_exec(bContext *C, wmOperator *op) BLI_addtail(&psys->targets, pt); DAG_scene_sort(scene); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -742,7 +741,7 @@ static int remove_particle_target_exec(bContext *C, wmOperator *op) pt->flag |= PTARGET_CURRENT; DAG_scene_sort(scene); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -766,7 +765,6 @@ void PARTICLE_OT_remove_target(wmOperatorType *ot) static int target_move_up_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; @@ -781,7 +779,7 @@ static int target_move_up_exec(bContext *C, wmOperator *op) BLI_remlink(&psys->targets, pt); BLI_insertlink(&psys->targets, pt->prev->prev, pt); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } @@ -806,7 +804,6 @@ void PARTICLE_OT_target_move_up(wmOperatorType *ot) static int target_move_down_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; @@ -820,7 +817,7 @@ static int target_move_down_exec(bContext *C, wmOperator *op) BLI_remlink(&psys->targets, pt); BLI_insertlink(&psys->targets, pt->next, pt); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 71f8642afd4..5d1dbe47345 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -335,7 +335,6 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) case ND_TRANSFORM: case ND_BONE_ACTIVE: case ND_BONE_SELECT: - case ND_GEOM_SELECT: case ND_CONSTRAINT: ED_area_tag_redraw(sa); break; @@ -346,6 +345,13 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_GEOM: + switch(wmn->data) { + case ND_SELECT: + ED_area_tag_redraw(sa); + break; + } + break; case NC_MATERIAL: ED_area_tag_redraw(sa); @@ -358,14 +364,15 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) } break; case NC_WORLD: - ED_area_tag_redraw(sa); - sbuts->preview= 1; case NC_LAMP: - ED_area_tag_redraw(sa); - sbuts->preview= 1; case NC_TEXTURE: ED_area_tag_redraw(sa); sbuts->preview= 1; + break; + case NC_SPACE: + if(wmn->data == ND_SPACE_PROPERTIES) + ED_area_tag_redraw(sa); + break; } if(wmn->data == ND_KEYS) diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 48890d6cac2..7e0dfe94432 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -321,11 +321,11 @@ static void console_main_area_listener(ScrArea *sa, wmNotifier *wmn) /* context changes */ switch(wmn->category) { - case NC_CONSOLE: - if(wmn->data == ND_CONSOLE) { /* generic redraw request */ + case NC_SPACE: + if(wmn->data == ND_SPACE_CONSOLE) { /* generic redraw request */ ED_area_tag_redraw(sa); } - else if(wmn->data == ND_CONSOLE_REPORT && sc->type==CONSOLE_TYPE_REPORT) { + else if(wmn->data == ND_SPACE_CONSOLE_REPORT && sc->type==CONSOLE_TYPE_REPORT) { /* redraw also but only for report view, could do less redraws by checking the type */ ED_area_tag_redraw(sa); } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index a06c1663d8e..e1a6e346ce2 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -190,9 +190,9 @@ static int file_border_select_exec(bContext *C, wmOperator *op) BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); if (FILE_SELECT_DIR == file_select(sfile, ar, &rect, val )) { - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } else { - WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); } return OPERATOR_FINISHED; } @@ -239,12 +239,12 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) file_deselect_all(sfile); if (FILE_SELECT_DIR == file_select(sfile, ar, &rect, val )) - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); else - WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); WM_event_add_mousemove(C); /* for directory changes */ - WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); return OPERATOR_FINISHED; } @@ -322,7 +322,7 @@ static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event) BLI_cleanup_dir(G.sce, params->dir); file_change_dir(sfile); - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } return OPERATOR_FINISHED; @@ -587,7 +587,7 @@ int file_parent_exec(bContext *C, wmOperator *unused) BLI_parent_dir(sfile->params->dir); BLI_cleanup_dir(G.sce, sfile->params->dir); file_change_dir(sfile); - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } } @@ -614,7 +614,7 @@ int file_refresh_exec(bContext *C, wmOperator *unused) file_change_dir(sfile); - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; @@ -645,7 +645,7 @@ int file_previous_exec(bContext *C, wmOperator *unused) file_change_dir(sfile); } - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; } @@ -676,7 +676,7 @@ int file_next_exec(bContext *C, wmOperator *unused) file_change_dir(sfile); } - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; } @@ -705,7 +705,7 @@ int file_directory_new_exec(bContext *C, wmOperator *unused) BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX); } } - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; } @@ -754,7 +754,7 @@ int file_directory_exec(bContext *C, wmOperator *unused) BLI_cleanup_dir(G.sce, sfile->params->dir); BLI_add_slash(sfile->params->dir); file_change_dir(sfile); - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } @@ -769,7 +769,7 @@ int file_filename_exec(bContext *C, wmOperator *unused) if (file_select_match(sfile, sfile->params->file)) { sfile->params->file[0] = '\0'; - WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); } } @@ -796,7 +796,7 @@ int file_hidedot_exec(bContext *C, wmOperator *unused) sfile->params->flag ^= FILE_HIDE_DOT; filelist_free(sfile->files); sfile->params->active_file = -1; - WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } return OPERATOR_FINISHED; @@ -958,7 +958,7 @@ int file_delete_exec(bContext *C, wmOperator *op) file = filelist_file(sfile->files, sfile->params->active_file); BLI_make_file_string(G.sce, str, sfile->params->dir, file->relname); BLI_delete(str, 0, 0); - WM_event_add_notifier(C, NC_FILE | ND_FILELIST, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 793f7cf8815..722fa475727 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -212,14 +212,14 @@ static void file_listener(ScrArea *sa, wmNotifier *wmn) /* context changes */ switch(wmn->category) { - case NC_FILE: + case NC_SPACE: switch (wmn->data) { - case ND_FILELIST: + case ND_SPACE_FILE_LIST: if (sfile->files) filelist_free(sfile->files); ED_area_tag_refresh(sa); ED_area_tag_redraw(sa); break; - case ND_PARAMS: + case ND_SPACE_FILE_PARAMS: ED_area_tag_refresh(sa); ED_area_tag_redraw(sa); break; @@ -249,12 +249,12 @@ static void file_main_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { - case NC_FILE: + case NC_SPACE: switch (wmn->data) { - case ND_FILELIST: + case ND_SPACE_FILE_LIST: ED_region_tag_redraw(ar); break; - case ND_PARAMS: + case ND_SPACE_FILE_PARAMS: ED_region_tag_redraw(ar); break; } @@ -470,9 +470,9 @@ static void file_ui_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { - case NC_FILE: + case NC_SPACE: switch (wmn->data) { - case ND_FILELIST: + case ND_SPACE_FILE_LIST: ED_region_tag_redraw(ar); break; } diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 3717ccc8244..8887d464f30 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -423,6 +423,10 @@ static void graph_listener(ScrArea *sa, wmNotifier *wmn) }*/ ED_area_tag_refresh(sa); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_GRAPH) + ED_area_tag_redraw(sa); + break; default: if(wmn->data==ND_KEYS) ED_area_tag_refresh(sa); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index bb647e68917..c57bc5773b0 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -295,10 +295,14 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn) case NC_IMAGE: ED_area_tag_redraw(sa); break; - case NC_OBJECT: + case NC_SPACE: + if(wmn->data == ND_SPACE_IMAGE) + ED_area_tag_redraw(sa); + break; + case NC_GEOM: switch(wmn->data) { - case ND_GEOM_SELECT: - case ND_GEOM_DATA: + case ND_DATA: + case ND_SELECT: ED_area_tag_redraw(sa); break; } @@ -625,7 +629,7 @@ void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obe if(C) { if(obedit) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); ED_area_tag_redraw(CTX_wm_area(C)); } diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index b6f9cbeabb5..d3f9c97205c 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -167,8 +167,9 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn) if(wmn->data==ND_RENDER_RESULT) ED_region_tag_redraw(ar); break; - case NC_INFO: - ED_region_tag_redraw(ar); + case NC_SPACE: + if(wmn->data == ND_SPACE_INFO) + ED_region_tag_redraw(ar); break; } diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index c4f929274c7..89d4e7cddf2 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -488,6 +488,10 @@ static void nla_listener(ScrArea *sa, wmNotifier *wmn) }*/ ED_area_tag_refresh(sa); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_NLA) + ED_area_tag_redraw(sa); + break; } } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 2233a4db3a0..d3a445b18c0 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -163,6 +163,15 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) if(wmn->data==ND_NODES) ED_area_tag_refresh(sa); break; + case NC_TEXT: + /* pynodes */ + if(wmn->data==ND_SHADING) + ED_area_tag_refresh(sa); + break; + case NC_SPACE: + if(wmn->data==ND_SPACE_NODE) + ED_area_tag_refresh(sa); + break; } } diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index a9a9a5dab5f..a3b47d505fd 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1994,7 +1994,7 @@ static int tree_element_active_defgroup(bContext *C, Scene *scene, TreeElement * ob= (Object *)tselem->id; if(set) { ob->actdef= te->index+1; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); } else { @@ -2121,7 +2121,7 @@ static int tree_element_active_psys(bContext *C, Scene *scene, TreeElement *te, if(set) { Object *ob= (Object *)tselem->id; - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, ob); // XXX extern_set_butspace(F7KEY, 0); } @@ -4682,7 +4682,7 @@ static void restrictbutton_modifier_cb(bContext *C, void *poin, void *poin2) Scene *scene = (Scene *)poin; Object *ob = (Object *)poin2; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); object_handle_update(scene, ob); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index f57445a32f1..5058a167a29 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -137,6 +137,10 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn) /* all actions now, todo: check outliner view mode? */ ED_region_tag_redraw(ar); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_OUTLINER) + ED_region_tag_redraw(ar); + break; } } @@ -190,6 +194,10 @@ static void outliner_header_area_listener(ARegion *ar, wmNotifier *wmn) if(wmn->data == ND_KEYINGSET) ED_region_tag_redraw(ar); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_OUTLINER) + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 084416f3a60..26ffd88ae67 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -219,6 +219,10 @@ static void sequencer_main_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + case NC_SPACE: + if(wmn->data == ND_SPACE_SEQUENCER) + ED_region_tag_redraw(ar); + break; } } @@ -241,6 +245,10 @@ static void sequencer_buttons_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { + case NC_SPACE: + if(wmn->data == ND_SPACE_SEQUENCER) + ED_region_tag_redraw(ar); + break; } } @@ -293,6 +301,7 @@ void ED_spacetype_sequencer(void) art->init= sequencer_header_area_init; art->draw= sequencer_header_area_draw; + art->listener= sequencer_main_area_listener; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 4394fbfe1f5..0d08490cfb0 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -143,6 +143,10 @@ static void text_listener(ScrArea *sa, wmNotifier *wmn) ED_area_tag_redraw(sa); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_TEXT) + ED_area_tag_redraw(sa); + break; } } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 14b72e13856..a8ef72e3273 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -549,7 +549,6 @@ static int refresh_pyconstraints_exec(bContext *C, wmOperator *op) { #ifndef DISABLE_PYTHON Text *text= CTX_data_edit_text(C); - Scene *scene= CTX_data_scene(C); Object *ob; bConstraint *con; short update; @@ -579,7 +578,7 @@ static int refresh_pyconstraints_exec(bContext *C, wmOperator *op) } if(update) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } #endif diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index ce6846a4489..8f7486f81d9 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -260,6 +260,11 @@ static void time_main_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { + case NC_SPACE: + if(wmn->data == ND_SPACE_TIME) + ED_region_tag_redraw(ar); + break; + case NC_ANIMATION: ED_region_tag_redraw(ar); break; @@ -293,6 +298,7 @@ static void time_header_area_listener(ARegion *ar, wmNotifier *wmn) if(wmn->data==ND_ANIMPLAY) ED_region_tag_redraw(ar); break; + case NC_SCENE: switch (wmn->data) { case ND_FRAME: @@ -300,6 +306,11 @@ static void time_header_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; } + + case NC_SPACE: + if(wmn->data == ND_SPACE_TIME) + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 97c5549e1ea..2250c2e7718 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -452,16 +452,24 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_TRANSFORM: - case ND_GEOM_SELECT: - case ND_GEOM_DATA: case ND_DRAW: case ND_MODIFIER: case ND_CONSTRAINT: case ND_KEYS: - case ND_PARTICLE: + case ND_PARTICLE_SELECT: + case ND_PARTICLE_DATA: ED_region_tag_redraw(ar); break; } + break; + case NC_GEOM: + switch(wmn->data) { + case ND_DATA: + case ND_SELECT: + ED_region_tag_redraw(ar); + break; + } + break; case NC_GROUP: /* all group ops for now */ ED_region_tag_redraw(ar); @@ -483,6 +491,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) * more context than just the region */ ED_region_tag_redraw(ar); break; + case NC_SPACE: + if(wmn->data == ND_SPACE_VIEW3D) + ED_region_tag_redraw(ar); + break; } } @@ -528,6 +540,10 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + case NC_SPACE: + if(wmn->data == ND_SPACE_VIEW3D) + ED_region_tag_redraw(ar); + break; } } @@ -576,13 +592,24 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_TRANSFORM: - case ND_GEOM_SELECT: - case ND_GEOM_DATA: case ND_DRAW: case ND_KEYS: ED_region_tag_redraw(ar); break; } + break; + case NC_GEOM: + switch(wmn->data) { + case ND_DATA: + case ND_SELECT: + ED_region_tag_redraw(ar); + break; + } + break; + case NC_SPACE: + if(wmn->data == ND_SPACE_VIEW3D) + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 7c305d59866..c854de8e54d 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -660,7 +660,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) return; /* no notifier! */ case B_OBJECTPANEL: - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); break; case B_OBJECTPANELROT: @@ -668,7 +668,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0; ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0; ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0; - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } break; @@ -706,7 +706,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) VECCOPY(ob->size, tfp->ob_scale); } - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } break; @@ -752,14 +752,14 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */ VECCOPY(tfp->ob_dims, old_dims); - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } break; case B_OBJECTPANELMEDIAN: if(ob) { v3d_editvertex_buts(C, NULL, v3d, ob, 1.0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } break; @@ -770,7 +770,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) ob->parent= NULL; else { DAG_scene_sort(scene); - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } } break; @@ -847,7 +847,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) case B_ARMATUREPANEL2: { ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } break; case B_TRANSFORMSPACEADD: @@ -900,7 +900,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) int a; for(a=0; atotvert; a++) remove_vert_defgroup (ob, defGroup, a); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } break; diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 305b6956037..2283d36e018 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1725,7 +1725,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) em->selectmode= SCE_SELECT_VERTEX; ts->selectmode= em->selectmode; EM_selectmode_set(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Vertex"); } break; @@ -1739,7 +1739,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) } ts->selectmode= em->selectmode; EM_selectmode_set(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Edge"); } break; @@ -1753,7 +1753,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) } ts->selectmode= em->selectmode; EM_selectmode_set(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Face"); } break; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 7743ede399b..5c6a22f5157 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1359,7 +1359,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) vc.em= me->edit_mesh; do_mesh_box_select(&vc, &rect, (val==LEFTMOUSE)); // if (EM_texFaceCheck()) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); } else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { @@ -1802,7 +1802,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) if(CTX_data_edit_object(C)) { obedit_circle_select(&vc, selecting, mval, (float)radius); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obact); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); } else return PE_circle_select(C, selecting, mval, (float)radius); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 335bc2c9e56..2e5696170e2 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -106,7 +106,7 @@ static void special_transvert_update(Scene *scene, Object *obedit) if(obedit) { - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); if(obedit->type==OB_MESH) { Mesh *me= obedit->data; @@ -514,7 +514,7 @@ static int snap_sel_to_grid(bContext *C, wmOperator *op) /* auto-keyframing */ // XXX autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { ob->recalc |= OB_RECALC_OB; @@ -640,7 +640,7 @@ static int snap_sel_to_curs(bContext *C, wmOperator *op) /* auto-keyframing */ // XXX autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { ob->recalc |= OB_RECALC_OB; @@ -1028,7 +1028,7 @@ static int snap_selected_to_center(bContext *C, wmOperator *op) /* auto-keyframing */ ob->pose->flag |= POSE_DO_UNLOCK; // XXX autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { ob->recalc |= OB_RECALC_OB; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index f0de28476f0..370e98ebd07 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -333,7 +333,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t) else force_draw(0); #endif - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, t->obedit); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data); } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 302d9b675a0..0fce9592d1d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4722,9 +4722,9 @@ void special_aftertrans_update(TransInfo *t) ob->ctime= -1234567.0f; if (ob->pose || ob_get_key(ob)) - DAG_object_flush_update(scene, ob, OB_RECALC); + DAG_id_flush_update(&ob->id, OB_RECALC); else - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } /* Do curve cleanups? */ @@ -4748,7 +4748,7 @@ void special_aftertrans_update(TransInfo *t) } #endif // XXX old animation system - DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); + DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); } #if 0 // XXX future of this is still not clear else if (ac.datatype == ANIMCONT_GPENCIL) { @@ -4912,15 +4912,15 @@ void special_aftertrans_update(TransInfo *t) /* automatic inserting of keys and unkeyed tagging - only if transform wasn't cancelled (or TFM_DUMMY) */ if (!cancelled && (t->mode != TFM_DUMMY)) { autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); - DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else if (arm->flag & ARM_DELAYDEFORM) { /* old optimize trick... this enforces to bypass the depgraph */ - DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); ob->recalc= 0; // is set on OK position already by recalcData() } else - DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); //if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE) // allqueue(REDRAWBUTSEDIT, 0); @@ -4948,7 +4948,7 @@ void special_aftertrans_update(TransInfo *t) /* Creates troubles for moving animated objects without */ /* autokey though, probably needed is an anim sys override? */ /* Please remove if some other solution is found. -jahka */ - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); /* Set autokey if necessary */ if (!cancelled) diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0f715f1d35a..0b7029adde0 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -283,7 +283,7 @@ static void animedit_refresh_id_tags (Scene *scene, ID *id) case ID_OB: { Object *ob= (Object *)id; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ } break; } @@ -621,7 +621,7 @@ void recalcData(TransInfo *t) Curve *cu= t->obedit->data; Nurb *nu= cu->editnurb->first; - DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ if (t->state == TRANS_CANCEL) { while(nu) { @@ -641,7 +641,7 @@ void recalcData(TransInfo *t) } else if(t->obedit->type==OB_LATTICE) { Lattice *la= t->obedit->data; - DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); } @@ -653,7 +653,7 @@ void recalcData(TransInfo *t) if(sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_re_solve(); - DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); } else { EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; /* mirror modifier clipping? */ @@ -668,7 +668,7 @@ void recalcData(TransInfo *t) if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) editmesh_apply_to_mirror(t); - DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ recalc_editnormals(em); } @@ -752,7 +752,7 @@ void recalcData(TransInfo *t) } else - DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ } else if( (t->flag & T_POSE) && t->poseobj) { Object *ob= t->poseobj; @@ -772,7 +772,7 @@ void recalcData(TransInfo *t) /* old optimize trick... this enforces to bypass the depgraph */ if (!(arm->flag & ARM_DELAYDEFORM)) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); /* sets recalc flags */ + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ } else where_is_pose(scene, ob); diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c index 17a1e0b6cdb..2d73a9f1d25 100644 --- a/source/blender/editors/util/editmode_undo.c +++ b/source/blender/editors/util/editmode_undo.c @@ -267,7 +267,7 @@ void undo_editmode_step(bContext *C, int step) } } -// DAG_object_flush_update(G.scene, obedit, OB_RECALC_DATA); +// DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); /* XXX notifiers */ } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index bb5a8b1dd40..a44421e8145 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -139,7 +139,7 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre /* and update depdency graph */ if(update) - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); BKE_mesh_end_editmesh(obedit->data, em); } @@ -169,8 +169,8 @@ void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, i tf->tile= curtile; /* set tile index */ } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); } @@ -1058,8 +1058,8 @@ static void weld_align_uv(bContext *C, int tool) } } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); } @@ -1279,8 +1279,8 @@ static int stitch_exec(bContext *C, wmOperator *op) MEM_freeN(uv_average); } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1336,7 +1336,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1406,7 +1406,7 @@ static int de_select_all_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1710,8 +1710,8 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) } } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED; @@ -1834,8 +1834,8 @@ static int select_linked_exec(bContext *C, wmOperator *op) uvedit_pixel_to_float(sima, limit, 0.05f); select_linked(scene, ima, em, limit, NULL, extend); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1890,8 +1890,8 @@ static int unlink_selection_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2167,7 +2167,7 @@ static int border_select_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2262,7 +2262,7 @@ int circle_select_exec(bContext *C, wmOperator *op) if(select) EM_select_flush(em); else EM_deselect_flush(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2567,8 +2567,8 @@ static int snap_selection_exec(bContext *C, wmOperator *op) if(!change) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); return OPERATOR_FINISHED; } @@ -2627,7 +2627,7 @@ static int pin_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2672,7 +2672,7 @@ static int select_pinned_exec(bContext *C, wmOperator *op) } } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2704,7 +2704,7 @@ static int hide_exec(bContext *C, wmOperator *op) if(ts->uv_flag & UV_SYNC_SELECTION) { EM_hide_mesh(em, swap); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2812,7 +2812,7 @@ static int hide_exec(bContext *C, wmOperator *op) } EM_validate_selections(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2847,7 +2847,7 @@ static int reveal_exec(bContext *C, wmOperator *op) /* call the mesh function if we are in mesh sync sel */ if(ts->uv_flag & UV_SYNC_SELECTION) { EM_reveal_mesh(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -2943,7 +2943,7 @@ static int reveal_exec(bContext *C, wmOperator *op) EM_select_face(efa, 1); } - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index c4f4704e47e..c18c9f8e022 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -263,8 +263,8 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interact ms->lasttime = PIL_check_seconds_timer(); - DAG_object_flush_update(ms->scene, ms->obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ms->obedit); + DAG_id_flush_update(ms->obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ms->obedit->data); } } @@ -286,8 +286,8 @@ static void minimize_stretch_exit(bContext *C, wmOperator *op, int cancel) param_stretch_end(ms->handle); param_delete(ms->handle); - DAG_object_flush_update(ms->scene, ms->obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ms->obedit); + DAG_id_flush_update(ms->obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ms->obedit->data); MEM_freeN(ms); op->customdata= NULL; @@ -413,8 +413,8 @@ static int pack_islands_exec(bContext *C, wmOperator *op) param_flush(handle); param_delete(handle); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -446,8 +446,8 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op) param_flush(handle); param_delete(handle); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -810,8 +810,8 @@ static int unwrap_exec(bContext *C, wmOperator *op) param_delete(handle); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -943,8 +943,8 @@ static int from_view_exec(bContext *C, wmOperator *op) uv_map_clip_correct(em, op); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1010,8 +1010,8 @@ static int reset_exec(bContext *C, wmOperator *op) } } - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1098,8 +1098,8 @@ static int sphere_project_exec(bContext *C, wmOperator *op) uv_map_clip_correct(em, op); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1170,8 +1170,8 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) uv_map_clip_correct(em, op); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; @@ -1257,8 +1257,8 @@ static int cube_project_exec(bContext *C, wmOperator *op) uv_map_clip_correct(em, op); - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 7bab7947843..3f4b75508fe 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -48,29 +48,17 @@ static void rna_Armature_update_data(bContext *C, PointerRNA *ptr) { - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); ID *id= ptr->id.data; - Object *ob; - for(ob=bmain->object.first; ob; ob= ob->id.next) { - if(ob->data == id) { - /* XXX this will loop over all objects again (slow) */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - } - } + DAG_id_flush_update(id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr) { - Main *bmain= CTX_data_main(C); ID *id= ptr->id.data; - Object *ob; - for(ob=bmain->object.first; ob; ob= ob->id.next) - if(ob->data == id) - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } static void rna_bone_layer_set(short *layer, const int *values) diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c index 0c5565e253a..8002aa89313 100644 --- a/source/blender/makesrna/intern/rna_boid.c +++ b/source/blender/makesrna/intern/rna_boid.c @@ -41,6 +41,7 @@ #include "DNA_object_types.h" #include "DNA_particle_types.h" +#include "WM_api.h" #include "WM_types.h" EnumPropertyItem boidrule_type_items[] ={ @@ -82,14 +83,15 @@ static void rna_Boids_reset(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_RESET; - if(ob) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - } + if(ob) + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Boids_reset_deps(bContext *C, PointerRNA *ptr) { @@ -102,15 +104,16 @@ static void rna_Boids_reset_deps(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_RESET; - if(ob) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - } + if(ob) + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); DAG_scene_sort(scene); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static StructRNA* rna_BoidRule_refine(struct PointerRNA *ptr) @@ -247,12 +250,12 @@ static void rna_def_boidrule_goal(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "ob"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Object", "Goal object."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset_deps"); + RNA_def_property_update(prop, 0, "rna_Boids_reset_deps"); prop= RNA_def_property(srna, "predict", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_GOAL_AVOID_PREDICT); RNA_def_property_ui_text(prop, "Predict", "Predict target movement."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boidrule_avoid(BlenderRNA *brna) @@ -268,17 +271,17 @@ static void rna_def_boidrule_avoid(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "ob"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Object", "Object to avoid."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset_deps"); + RNA_def_property_update(prop, 0, "rna_Boids_reset_deps"); prop= RNA_def_property(srna, "predict", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_GOAL_AVOID_PREDICT); RNA_def_property_ui_text(prop, "Predict", "Predict target movement."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "fear_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Fear factor", "Avoid object if danger from it is above this threshol."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boidrule_avoid_collision(BlenderRNA *brna) @@ -292,17 +295,17 @@ static void rna_def_boidrule_avoid_collision(BlenderRNA *brna) prop= RNA_def_property(srna, "boids", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_ACOLL_WITH_BOIDS); RNA_def_property_ui_text(prop, "Boids", "Avoid collision with other boids."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "deflectors", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_ACOLL_WITH_DEFLECTORS); RNA_def_property_ui_text(prop, "Deflectors", "Avoid collision with deflector objects."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "look_ahead", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Look ahead", "Time to look ahead in seconds."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boidrule_follow_leader(BlenderRNA *brna) @@ -317,22 +320,22 @@ static void rna_def_boidrule_follow_leader(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "ob"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Object", "Follow this object instead of a boid."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset_deps"); + RNA_def_property_update(prop, 0, "rna_Boids_reset_deps"); prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Distance", "Distance behind leader to follow."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "queue_size", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Queue Size", "How many boids in a line."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "line", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_LEADER_IN_LINE); RNA_def_property_ui_text(prop, "Line", "Follow leader in a line."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boidrule_average_speed(BlenderRNA *brna) @@ -346,17 +349,17 @@ static void rna_def_boidrule_average_speed(BlenderRNA *brna) prop= RNA_def_property(srna, "wander", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Wander", "How fast velocity's direction is randomized."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "level", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Level", "How much velocity's z-component is kept constant."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Speed", "Percentage of maximum speed."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boidrule_fight(BlenderRNA *brna) @@ -370,12 +373,12 @@ static void rna_def_boidrule_fight(BlenderRNA *brna) prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Fight Distance", "Attack boids at max this distance."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "flee_distance", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Flee Distance", "Flee to this distance."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boidrule(BlenderRNA *brna) @@ -405,12 +408,12 @@ static void rna_def_boidrule(BlenderRNA *brna) prop= RNA_def_property(srna, "in_air", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BOIDRULE_IN_AIR); RNA_def_property_ui_text(prop, "In Air", "Use rule when boid is flying."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "on_land", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BOIDRULE_ON_LAND); RNA_def_property_ui_text(prop, "On Land", "Use rule when boid is on land."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); //prop= RNA_def_property(srna, "expanded", PROP_BOOLEAN, PROP_NONE); //RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Expanded); @@ -457,17 +460,17 @@ static void rna_def_boidstate(BlenderRNA *brna) prop= RNA_def_property(srna, "rule_fuzziness", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Rule Fuzzines", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Volume", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_text(prop, "Falloff", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } static void rna_def_boid_settings(BlenderRNA *brna) { @@ -480,17 +483,17 @@ static void rna_def_boid_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "landing_smoothness", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_text(prop, "Landing Smoothness", "How smoothly the boids land."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "banking", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 2.0); RNA_def_property_ui_text(prop, "Banking", "Amount of rotation around velocity vector on turns."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "height", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 2.0); RNA_def_property_ui_text(prop, "Height", "Boid height relative to particle size."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); /* states */ prop= RNA_def_property(srna, "states", PROP_COLLECTION, PROP_NONE); @@ -510,99 +513,99 @@ static void rna_def_boid_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "health", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Health", "Initial boid health when born."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Strength", "Maximum caused damage on attack per second."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "aggression", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Aggression", "Boid will fight this times stronger enemy."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "accuracy", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Accuracy", "Accuracy of attack."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "range", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Range", "The maximum distance from which a boid can attack."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); /* physical properties */ prop= RNA_def_property(srna, "air_min_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Min Air Speed", "Minimum speed in air (relative to maximum speed)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "air_max_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Max Air Speed", "Maximum speed in air."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "air_max_acc", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Max Air Acceleration", "Maximum acceleration in air (relative to maximum speed)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "air_max_ave", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Max Air Angular Velocity", "Maximum angular velocity in air (relative to 180 degrees)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "air_personal_space", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_text(prop, "Air Personal Space", "Radius of boids personal space in air (% of particle size)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "land_jump_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Jump Speed", "Maximum speed for jumping."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "land_max_speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 100.0); RNA_def_property_ui_text(prop, "Max Land Speed", "Maximum speed on land."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "land_max_acc", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Max Land Acceleration", "Maximum acceleration on land (relative to maximum speed)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "land_max_ave", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Max Land Angular Velocity", "Maximum angular velocity on land (relative to 180 degrees)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "land_personal_space", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_text(prop, "Land Personal Space", "Radius of boids personal space on land (% of particle size)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "land_stick_force", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_ui_text(prop, "Land Stick Force", "How strong a force must be to start effecting a boid on land."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); /* options */ prop= RNA_def_property(srna, "allow_flight", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BOID_ALLOW_FLIGHT); RNA_def_property_ui_text(prop, "Allow Flight", "Allow boids to move in air."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "allow_land", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BOID_ALLOW_LAND); RNA_def_property_ui_text(prop, "Allow Land", "Allow boids to move on land."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); prop= RNA_def_property(srna, "allow_climb", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "options", BOID_ALLOW_CLIMB); RNA_def_property_ui_text(prop, "Allow Climbing", "Allow boids to climb goal objects."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Boids_reset"); + RNA_def_property_update(prop, 0, "rna_Boids_reset"); } void RNA_def_boid(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 9096bfc2844..38086502d6f 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -37,6 +37,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "WM_api.h" #include "WM_types.h" #ifdef RNA_RUNTIME @@ -46,10 +47,10 @@ static void rna_cloth_update(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); - Object *ob = ptr->id.data; + Object *ob= (Object*)ptr->id.data; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value) @@ -180,50 +181,50 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "mingoal"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "maxgoal"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "defgoal"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "goalspring"); RNA_def_property_range(prop, 0.0f, 0.999f); RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "goalfrict"); RNA_def_property_range(prop, 0.0f, 50.0f); RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); /* mass */ prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Mass", "Mass of cloth material."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "mass_vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_ClothSettings_mass_vgroup_get", "rna_ClothSettings_mass_vgroup_length", "rna_ClothSettings_mass_vgroup_set"); RNA_def_property_ui_text(prop, "Mass Vertex Group", "Vertex Group for pinning of vertices."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, -100.0, 100.0); RNA_def_property_float_funcs(prop, "rna_ClothSettings_gravity_get", "rna_ClothSettings_gravity_set", NULL); RNA_def_property_ui_text(prop, "Gravity", "Gravity or external force vector."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); /* various */ @@ -231,73 +232,73 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "Cvi"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Air Damping", "Air has normally some thickness which slows falling things down."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "pin_cloth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL); RNA_def_property_ui_text(prop, "Pin Cloth", "Enable pinning of cloth vertices to other objects/positions."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "pin_stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "goalspring"); RNA_def_property_range(prop, 0.0f, 50.0); RNA_def_property_ui_text(prop, "Pin Stiffness", "Pin (vertex target position) spring stiffness."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "quality", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "stepsPerFrame"); RNA_def_property_range(prop, 4, 80); RNA_def_property_ui_text(prop, "Quality", "Quality of the simulation in steps per frame. (higher is better quality but slower)"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); /* springs */ prop= RNA_def_property(srna, "stiffness_scaling", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_SCALING); RNA_def_property_ui_text(prop, "Stiffness Scaling", "If enabled, stiffness can be scaled along a weight painted vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "Cdis"); RNA_def_property_range(prop, 0.0f, 50.0f); RNA_def_property_ui_text(prop, "Spring Damping", "Damping of cloth velocity. (higher = more smooth, less jiggling)"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "structural_stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "structural"); RNA_def_property_range(prop, 1.0f, 10000.0f); RNA_def_property_ui_text(prop, "Structural Stiffness", "Overall stiffness of structure."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "structural_stiffness_max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max_struct"); RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_struct_set", NULL); RNA_def_property_ui_text(prop, "Structural Stiffness Maximum", "Maximum structural stiffness value."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "structural_stiffness_vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_ClothSettings_struct_vgroup_get", "rna_ClothSettings_struct_vgroup_length", "rna_ClothSettings_struct_vgroup_set"); RNA_def_property_ui_text(prop, "Structural Stiffness Vertex Group", "Vertex group for fine control over structural stiffness."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "bending_stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bending"); RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_ui_text(prop, "Bending Stiffness", "Wrinkle coefficient. (higher = less smaller but more big wrinkles)"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "bending_stiffness_max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max_bend"); RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_bend_set", NULL); RNA_def_property_ui_text(prop, "Bending Stiffness Maximum", "Maximum bending stiffness value."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "bending_vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_ClothSettings_bend_vgroup_get", "rna_ClothSettings_bend_vgroup_length", "rna_ClothSettings_bend_vgroup_set"); RNA_def_property_ui_text(prop, "Bending Stiffness Vertex Group", "Vertex group for fine control over bending stiffness."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); /* unused */ @@ -358,48 +359,48 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "enable_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_ENABLED); RNA_def_property_ui_text(prop, "Enable Collision", "Enable collisions with other objects."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "min_distance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "epsilon"); RNA_def_property_range(prop, 0.001f, 1.0f); RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance between collision objects before collision response takes in."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 80.0f); RNA_def_property_ui_text(prop, "Friction", "Friction force if a collision happened. (higher = less movement)"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "collision_quality", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "loop_count"); RNA_def_property_range(prop, 1, 20); RNA_def_property_ui_text(prop, "Collision Quality", "How many collision iterations should be done. (higher is better quality but slower)"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); /* self collision */ prop= RNA_def_property(srna, "enable_self_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_SELF); RNA_def_property_ui_text(prop, "Enable Self Collision", "Enable self collisions."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "self_min_distance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "selfepsilon"); RNA_def_property_range(prop, 0.5f, 1.0f); RNA_def_property_ui_text(prop, "Self Minimum Distance", "0.5 means no distance at all, 1.0 is maximum distance."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "self_friction", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 80.0f); RNA_def_property_ui_text(prop, "Self Friction", "Friction/damping with self contact."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); prop= RNA_def_property(srna, "self_collision_quality", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "self_loop_count"); RNA_def_property_range(prop, 1, 10); RNA_def_property_ui_text(prop, "Self Collision Quality", "How many self collision iterations should be done. (higher is better quality but slower)"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update"); + RNA_def_property_update(prop, 0, "rna_cloth_update"); } void RNA_def_cloth(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index a8dc0454cef..c09a71f752a 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -160,15 +160,14 @@ static char *rna_Constraint_path(PointerRNA *ptr) static void rna_Constraint_update(bContext *C, PointerRNA *ptr) { - Scene *scene= CTX_data_scene(C); Object *ob= ptr->id.data; if(ob->pose) update_pose_constraint_flags(ob->pose); object_test_constraints(ob); - if(ob->type==OB_ARMATURE) DAG_object_flush_update(scene, ob, OB_RECALC_DATA|OB_RECALC_OB); - else DAG_object_flush_update(scene, ob, OB_RECALC_OB); + if(ob->type==OB_ARMATURE) DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB); + else DAG_id_flush_update(&ob->id, OB_RECALC_OB); } static void rna_Constraint_dependency_update(bContext *C, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 503ca031fb6..d19a2289490 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -156,21 +156,10 @@ static void rna_BPoint_array_begin(CollectionPropertyIterator *iter, PointerRNA static void rna_Curve_update_data(bContext *C, PointerRNA *ptr) { - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - Curve *cu= ptr->id.data; - Object *ob; - - if (cu == NULL) - return; - - for(ob=bmain->object.first; ob; ob= ob->id.next) { - if(ob->data == cu) { - /* XXX this will loop over all objects again (slow) */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - } - } + ID *id= ptr->id.data; + + DAG_id_flush_update(id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } #else diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 1f51b3ff34c..69e6698bd3b 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2559,13 +2559,14 @@ void RNA_def_property_free_pointers(PropertyRNA *prop) } case PROP_ENUM: { EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop; - if(eprop->item) MEM_freeN((void*)eprop->item); for(a=0; atotitem; a++) { if(eprop->item[a].identifier) MEM_freeN((void*)eprop->item[a].identifier); if(eprop->item[a].name) MEM_freeN((void*)eprop->item[a].name); if(eprop->item[a].description) MEM_freeN((void*)eprop->item[a].description); } + + if(eprop->item) MEM_freeN((void*)eprop->item); break; } case PROP_STRING: { diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index dda21f63528..a62002365c9 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -72,10 +72,17 @@ static StructRNA* rna_FluidSettings_refine(struct PointerRNA *ptr) } } +static void rna_fluid_update(bContext *C, PointerRNA *ptr) +{ + Object *ob= ptr->id.data; + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); +} + static void rna_FluidSettings_update_type(bContext *C, PointerRNA *ptr) { Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); Object *ob= (Object*)ptr->id.data; FluidsimModifierData *fluidmd; ParticleSystemModifierData *psmd; @@ -124,8 +131,7 @@ static void rna_FluidSettings_update_type(bContext *C, PointerRNA *ptr) } } - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + rna_fluid_update(C, ptr); } static void rna_DomainFluidSettings_memory_estimate_get(PointerRNA *ptr, char *value) @@ -216,7 +222,7 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "guiDisplayMode"); RNA_def_property_enum_items(prop, quality_items); RNA_def_property_ui_text(prop, "Viewport Display Mode", "How to display the mesh in the viewport."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_fluid_update"); prop= RNA_def_property(srna, "render_display_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "renderDisplayMode"); @@ -231,7 +237,7 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna) RNA_def_property_string_maxlength(prop, 240); RNA_def_property_string_sdna(prop, NULL, "surfdataPath"); RNA_def_property_ui_text(prop, "Path", "Directory (and/or filename prefix) to store baked fluid simulation files in."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_fluid_update"); prop= RNA_def_property(srna, "memory_estimate", PROP_STRING, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -431,7 +437,7 @@ static void rna_def_fluidsim_particle(BlenderRNA *brna) RNA_def_property_string_maxlength(prop, 240); RNA_def_property_string_sdna(prop, NULL, "surfdataPath"); RNA_def_property_ui_text(prop, "Path", "Directory (and/or filename prefix) to store and load particles from."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_fluid_update"); } static void rna_def_fluidsim_control(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 0a9ef9f90d1..13cc2ae9017 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -195,6 +195,7 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch void rna_Object_update(struct bContext *C, struct PointerRNA *ptr); void rna_Object_update_data(struct bContext *C, struct PointerRNA *ptr); +void rna_Mesh_update_draw(struct bContext *C, struct PointerRNA *ptr); /* API functions */ diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index 88047cda12b..fbe339fe7f3 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -260,14 +260,13 @@ static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter) static void rna_Key_update_data(bContext *C, PointerRNA *ptr) { Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); Key *key= ptr->id.data; Object *ob; for(ob=bmain->object.first; ob; ob= ob->id.next) { if(ob_get_key(ob) == key) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } } } diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c index b53a0589ba6..1f7eee4d2d8 100644 --- a/source/blender/makesrna/intern/rna_lattice.c +++ b/source/blender/makesrna/intern/rna_lattice.c @@ -89,18 +89,10 @@ static void rna_Lattice_points_begin(CollectionPropertyIterator *iter, PointerRN static void rna_Lattice_update_data(bContext *C, PointerRNA *ptr) { - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - Lattice *lt= ptr->id.data; - Object *ob; + ID *id= ptr->id.data; - for(ob=bmain->object.first; ob; ob= ob->id.next) { - if(ob->data == lt) { - /* XXX this will loop over all objects again (slow) */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - } - } + DAG_id_flush_update(id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } static void rna_Lattice_update_size(bContext *C, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index edecfc8cdb0..f7235db49a5 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -52,18 +52,24 @@ static void rna_Mesh_update_data(bContext *C, PointerRNA *ptr) { - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); ID *id= ptr->id.data; - Object *ob; - for(ob=bmain->object.first; ob; ob= ob->id.next) { - if(ob->data == id) { - /* XXX this will loop over all objects again (slow) */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - } - } + DAG_id_flush_update(id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); +} + +static void rna_Mesh_update_select(bContext *C, PointerRNA *ptr) +{ + ID *id= ptr->id.data; + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, id); +} + +void rna_Mesh_update_draw(bContext *C, PointerRNA *ptr) +{ + ID *id= ptr->id.data; + + WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value) @@ -867,10 +873,12 @@ static void rna_def_mvert_group(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "def_nr"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Group Index", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Weight", "Vertex Weight"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } static void rna_def_mvert(BlenderRNA *brna) @@ -886,6 +894,7 @@ static void rna_def_mvert(BlenderRNA *brna) prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_ui_text(prop, "Location", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION); RNA_def_property_float_sdna(prop, NULL, "no"); @@ -896,14 +905,17 @@ static void rna_def_mvert(BlenderRNA *brna) prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); RNA_def_property_ui_text(prop, "Selected", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "hidden", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE); RNA_def_property_ui_text(prop, "Hidden", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "bevel_weight", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_MeshVertex_bevel_weight_get", "rna_MeshVertex_bevel_weight_set", NULL); RNA_def_property_ui_text(prop, "Bevel Weight", "Weight used by the Bevel modifier 'Only Vertices' option"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_MeshVertex_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0, 0, 0); @@ -931,26 +943,32 @@ static void rna_def_medge(BlenderRNA *brna) prop= RNA_def_property(srna, "crease", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_MEdge_crease_get", "rna_MEdge_crease_set", NULL); RNA_def_property_ui_text(prop, "Crease", "Weight used by the Subsurf modifier for creasing"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "bevel_weight", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_MEdge_bevel_weight_get", "rna_MEdge_bevel_weight_set", NULL); RNA_def_property_ui_text(prop, "Bevel Weight", "Weight used by the Bevel modifier"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); RNA_def_property_ui_text(prop, "Selected", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "hidden", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE); RNA_def_property_ui_text(prop, "Hidden", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "seam", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SEAM); RNA_def_property_ui_text(prop, "Seam", "Seam edge for UV unwrapping"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "sharp", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SHARP); RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } static void rna_def_mface(BlenderRNA *brna) @@ -984,18 +1002,22 @@ static void rna_def_mface(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "mat_nr"); RNA_def_property_ui_text(prop, "Material Index", ""); RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MeshFace_material_index_range"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FACE_SEL); RNA_def_property_ui_text(prop, "Selected", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "hidden", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_HIDE); RNA_def_property_ui_text(prop, "Hidden", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "smooth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SMOOTH); RNA_def_property_ui_text(prop, "Smooth", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION); RNA_def_property_array(prop, 3); @@ -1021,20 +1043,24 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Mesh Texture Face Layer", "Layer of texture faces in a Mesh datablock."); RNA_def_struct_sdna(srna, "CustomDataLayer"); RNA_def_struct_path_func(srna, "rna_MeshTextureFaceLayer_path"); + RNA_def_struct_ui_icon(srna, ICON_GROUP_UVS); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshTextureFaceLayer_name_set"); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_MeshTextureFaceLayer_active_get", "rna_MeshTextureFaceLayer_active_set"); RNA_def_property_ui_text(prop, "Active", "Sets the layer as active for display and editing"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0); RNA_def_property_boolean_funcs(prop, "rna_MeshTextureFaceLayer_active_render_get", "rna_MeshTextureFaceLayer_active_render_set"); RNA_def_property_ui_text(prop, "Active Render", "Sets the layer as active for rendering"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTextureFace"); @@ -1052,88 +1078,109 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, "rna_TextureFace_image_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "tex", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_TEX); RNA_def_property_ui_text(prop, "Tex", "Render face with texture"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "light", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_LIGHT); RNA_def_property_ui_text(prop, "Light", "Use light for face"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "invisible", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_INVISIBLE); RNA_def_property_ui_text(prop, "Invisible", "Make face invisible"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_DYNAMIC); RNA_def_property_ui_text(prop, "Collision", "Use face for collision and ray-sensor detection"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "shared", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_SHAREDCOL); RNA_def_property_ui_text(prop, "Shared", "Blend vertex colors across face when vertices are shared"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "twoside", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_TWOSIDE); RNA_def_property_ui_text(prop, "Twoside", "Render face twosided"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "object_color", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_OBCOL); RNA_def_property_ui_text(prop, "Object Color", "Use ObColor instead of vertex colors"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "halo", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_BILLBOARD); RNA_def_property_ui_text(prop, "Halo", "Screen aligned billboard"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "billboard", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_BILLBOARD2); RNA_def_property_ui_text(prop, "Billboard", "Billboard with Z-axis constraint"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "shadow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_SHADOW); RNA_def_property_ui_text(prop, "Shadow", "Face is used for shadow"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "text", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_BMFONT); RNA_def_property_ui_text(prop, "Text", "Enable bitmap text on face"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "alpha_sort", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_ALPHASORT); RNA_def_property_ui_text(prop, "Alpha Sort", "Enable sorting of faces for correct alpha drawing (slow, use Clip Alpha instead when possible)"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "transp", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, transp_items); RNA_def_property_ui_text(prop, "Transparency", "Transparency blending mode"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "uv_selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TF_SEL1); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "UV Selected", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "uv_pinned", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "unwrap", TF_PIN1); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "UV Pinned", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop= RNA_def_property(srna, "uv1", PROP_FLOAT, PROP_XYZ); RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv1_get", "rna_MeshTextureFace_uv1_set", NULL); RNA_def_property_ui_text(prop, "UV 1", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "uv2", PROP_FLOAT, PROP_XYZ); RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv2_get", "rna_MeshTextureFace_uv2_set", NULL); RNA_def_property_ui_text(prop, "UV 2", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "uv3", PROP_FLOAT, PROP_XYZ); RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv3_get", "rna_MeshTextureFace_uv3_set", NULL); RNA_def_property_ui_text(prop, "UV 3", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "uv4", PROP_FLOAT, PROP_XYZ); RNA_def_property_array(prop, 2); RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv4_get", "rna_MeshTextureFace_uv4_set", NULL); RNA_def_property_ui_text(prop, "UV 4", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ); RNA_def_property_multidimensional_array(prop, 4 * 2, 2, uv_dim); @@ -1141,6 +1188,7 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTextureFace_uv_get_length", "rna_MeshTextureFace_uv_set_length"); RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv_get", "rna_MeshTextureFace_uv_set", NULL); RNA_def_property_ui_text(prop, "UV", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } static void rna_def_msticky(BlenderRNA *brna) @@ -1155,6 +1203,7 @@ static void rna_def_msticky(BlenderRNA *brna) prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ); RNA_def_property_ui_text(prop, "Location", "Sticky texture coordinate location."); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } static void rna_def_mcol(BlenderRNA *brna) @@ -1166,20 +1215,24 @@ static void rna_def_mcol(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Mesh Vertex Color Layer", "Layer of vertex colors in a Mesh datablock."); RNA_def_struct_sdna(srna, "CustomDataLayer"); RNA_def_struct_path_func(srna, "rna_MeshColorLayer_path"); + RNA_def_struct_ui_icon(srna, ICON_GROUP_VCOL); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshColorLayer_name_set"); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_MeshColorLayer_active_get", "rna_MeshColorLayer_active_set"); RNA_def_property_ui_text(prop, "Active", "Sets the layer as active for display and editing"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0); RNA_def_property_boolean_funcs(prop, "rna_MeshColorLayer_active_render_get", "rna_MeshColorLayer_active_render_set"); RNA_def_property_ui_text(prop, "Active Render", "Sets the layer as active for rendering"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshColor"); @@ -1196,24 +1249,28 @@ static void rna_def_mcol(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color1_get", "rna_MeshColor_color1_set", NULL); RNA_def_property_ui_text(prop, "Color 1", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "color2", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color2_get", "rna_MeshColor_color2_set", NULL); RNA_def_property_ui_text(prop, "Color 2", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "color3", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color3_get", "rna_MeshColor_color3_set", NULL); RNA_def_property_ui_text(prop, "Color 3", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "color4", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_funcs(prop, "rna_MeshColor_color4_get", "rna_MeshColor_color4_set", NULL); RNA_def_property_ui_text(prop, "Color 4", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } static void rna_def_mproperties(BlenderRNA *brna) @@ -1230,6 +1287,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshFloatProperty"); @@ -1244,6 +1302,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "f"); RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); /* Int */ srna= RNA_def_struct(brna, "MeshIntPropertyLayer", NULL); @@ -1254,6 +1313,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshIntProperty"); @@ -1268,6 +1328,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "value", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "i"); RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); /* String */ srna= RNA_def_struct(brna, "MeshStringPropertyLayer", NULL); @@ -1278,6 +1339,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MeshStringProperty"); @@ -1292,6 +1354,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop= RNA_def_property(srna, "value", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "s"); RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable) @@ -1307,17 +1370,20 @@ void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable) RNA_def_property_float_sdna(prop, NULL, "loc"); RNA_def_property_ui_text(prop, "Texure Space Location", "Texture space location."); RNA_def_property_editable_func(prop, texspace_editable); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Texture Space Size", "Texture space size."); RNA_def_property_editable_func(prop, texspace_editable); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); /* not supported yet prop= RNA_def_property(srna, "texspace_rot", PROP_FLOAT, PROP_EULER); RNA_def_property_float(prop, NULL, "rot"); RNA_def_property_ui_text(prop, "Texture Space Rotation", "Texture space rotation"); - RNA_def_property_editable_func(prop, texspace_editable);*/ + RNA_def_property_editable_func(prop, texspace_editable); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");*/ /* materials */ prop= RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE); @@ -1445,58 +1511,58 @@ static void rna_def_mesh(BlenderRNA *brna) prop= RNA_def_property(srna, "draw_edges", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEDGES); RNA_def_property_ui_text(prop, "Draw Edges", "Displays selected edges using hilights in the 3d view and UV editor"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_faces", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWFACES); RNA_def_property_ui_text(prop, "Draw Faces", "Displays all faces as shades in the 3d view and UV editor"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_normals", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWNORMALS); RNA_def_property_ui_text(prop, "Draw Normals", "Displays face normals as lines"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_vertex_normals", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_VNORMALS); RNA_def_property_ui_text(prop, "Draw Vertex Normals", "Displays vertex normals as lines"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_creases", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWCREASES); RNA_def_property_ui_text(prop, "Draw Creases", "Displays creases created for subsurf weighting"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_bevel_weights", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWBWEIGHTS); RNA_def_property_ui_text(prop, "Draw Bevel Weights", "Displays weights created for the Bevel modifier"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_seams", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWSEAMS); RNA_def_property_ui_text(prop, "Draw Seams", "Displays UV unwrapping seams"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_sharp", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWSHARP); RNA_def_property_ui_text(prop, "Draw Sharp", "Displays sharp edges, used with the EdgeSplit modifier"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_edge_lenght", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_EDGELEN); RNA_def_property_ui_text(prop, "Edge Length", "Displays selected edge lengths"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_edge_angle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_EDGEANG); RNA_def_property_ui_text(prop, "Edge Angles", "Displays the angles in the selected edges in degrees"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); prop= RNA_def_property(srna, "draw_face_area", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_FACEAREA); RNA_def_property_ui_text(prop, "Face Area", "Displays the area of selected faces"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); rna_def_texmat_common(srna, "rna_Mesh_texspace_editable"); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index c98b3fb7b09..686d91e4fe2 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -102,20 +102,13 @@ static void rna_Mesh_calc_edges(Mesh *mesh) static void rna_Mesh_update(Mesh *mesh, bContext *C) { - Main *bmain= CTX_data_main(C); - Object *ob; - if(mesh->totface && mesh->totedge == 0) rna_Mesh_calc_edges(mesh); mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL); - for(ob=bmain->object.first; ob; ob=ob->id.next) { - if(ob->data == mesh) { - ob->recalc |= OB_RECALC_DATA; - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - } - } + DAG_id_flush_update(&mesh->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh); } static void rna_Mesh_add_verts(Mesh *mesh, int len) diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index 7b14a7a4712..f3160a7bb18 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -57,14 +57,12 @@ static void rna_MetaBall_update_data(bContext *C, PointerRNA *ptr) MetaBall *mb= ptr->id.data; Object *ob; - for(ob=bmain->object.first; ob; ob= ob->id.next) { - if(ob->data == mb) { + for(ob=bmain->object.first; ob; ob= ob->id.next) + if(ob->data == mb) copy_mball_properties(scene, ob); - /* XXX this will loop over all objects again (slow) */ - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); - } - } + + DAG_id_flush_update(&mb->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); } #else diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index bb073d19a46..f8c8ddb9431 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -40,6 +40,7 @@ #include "BKE_bmesh.h" /* For BevelModifierData */ #include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */ +#include "WM_api.h" #include "WM_types.h" EnumPropertyItem modifier_type_items[] ={ @@ -170,7 +171,8 @@ static char *rna_Modifier_path(PointerRNA *ptr) static void rna_Modifier_update(bContext *C, PointerRNA *ptr) { - DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ptr->id.data); } static void rna_Modifier_dependency_update(bContext *C, PointerRNA *ptr) @@ -441,7 +443,7 @@ static void rna_def_property_subdivision_common(StructRNA *srna, const char type RNA_def_property_enum_sdna(prop, NULL, type); RNA_def_property_enum_items(prop, prop_subdivision_type_items); RNA_def_property_ui_text(prop, "Subdivision Type", "Selects type of subdivision algorithm."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_subsurf(BlenderRNA *brna) @@ -461,7 +463,7 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) RNA_def_property_range(prop, 1, 6); RNA_def_property_ui_range(prop, 1, 6, 1, 0); RNA_def_property_ui_text(prop, "Levels", "Number of subdivisions to perform."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "renderLevels"); @@ -472,12 +474,12 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) prop= RNA_def_property(srna, "optimal_draw", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_ControlEdges); RNA_def_property_ui_text(prop, "Optimal Draw", "Skip drawing/rendering of interior subdivided edges"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "subsurf_uv", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_SubsurfUv); RNA_def_property_ui_text(prop, "Subsurf UV", "Use subsurf to subdivide UVs."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_multires(BlenderRNA *brna) @@ -496,7 +498,7 @@ static void rna_def_modifier_multires(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "lvl"); RNA_def_property_ui_text(prop, "Level", ""); RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_lattice(BlenderRNA *brna) @@ -513,13 +515,13 @@ static void rna_def_modifier_lattice(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object", "Lattice object to deform with."); RNA_def_property_pointer_funcs(prop, NULL, "rna_LatticeModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LatticeModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_curve(BlenderRNA *brna) @@ -545,19 +547,19 @@ static void rna_def_modifier_curve(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object", "Curve object to deform with."); RNA_def_property_pointer_funcs(prop, NULL, "rna_CurveModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CurveModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "deform_axis", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "defaxis"); RNA_def_property_enum_items(prop, prop_deform_axis_items); RNA_def_property_ui_text(prop, "Deform Axis", "The axis that the curve deforms along."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_build(BlenderRNA *brna) @@ -573,21 +575,21 @@ static void rna_def_modifier_build(BlenderRNA *brna) prop= RNA_def_property(srna, "start", PROP_FLOAT, PROP_TIME); RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start", "Specify the start frame of the effect."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "length", PROP_FLOAT, PROP_TIME); RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Length", "Specify the total time the build effect requires"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "randomize", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Randomize", "Randomize the faces or edges during build."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "seed", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Seed", "Specify the seed for random if used."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_mirror(BlenderRNA *brna) @@ -603,50 +605,50 @@ static void rna_def_modifier_mirror(BlenderRNA *brna) prop= RNA_def_property(srna, "x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_AXIS_X); RNA_def_property_ui_text(prop, "X", "Enable X axis mirror."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_AXIS_Y); RNA_def_property_ui_text(prop, "Y", "Enable Y axis mirror."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_AXIS_Z); RNA_def_property_ui_text(prop, "Z", "Enable Z axis mirror."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "clip", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_CLIPPING); RNA_def_property_ui_text(prop, "Clip", "Prevents vertices from going through the mirror during transform."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "mirror_vertex_groups", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_VGROUP); RNA_def_property_ui_text(prop, "Mirror Vertex Groups", "Mirror vertex groups (e.g. .R->.L)."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "mirror_u", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_MIRROR_U); RNA_def_property_ui_text(prop, "Mirror U", "Mirror the U texture coordinate around the 0.5 point."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "mirror_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_MIRROR_V); RNA_def_property_ui_text(prop, "Mirror V", "Mirror the V texture coordinate around the 0.5 point."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "merge_limit", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "tolerance"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Merge Limit", "Distance from axis within which mirrored vertices are merged."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "mirror_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "mirror_ob"); RNA_def_property_ui_text(prop, "Mirror Object", "Object to use as mirror."); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); } static void rna_def_modifier_decimate(BlenderRNA *brna) @@ -663,7 +665,7 @@ static void rna_def_modifier_decimate(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "percent"); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Ratio", "Defines the ratio of triangles to reduce to."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "face_count", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "faceCount"); @@ -691,135 +693,135 @@ static void rna_def_modifier_wave(BlenderRNA *brna) prop= RNA_def_property(srna, "x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_X); RNA_def_property_ui_text(prop, "X", "X axis motion."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_Y); RNA_def_property_ui_text(prop, "Y", "Y axis motion."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "cyclic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_CYCL); RNA_def_property_ui_text(prop, "Cyclic", "Cyclic wave effect."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "normals", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_NORM); RNA_def_property_ui_text(prop, "Normals", "Dispace along normals."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "x_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_NORM_X); RNA_def_property_ui_text(prop, "X Normal", "Enable displacement along the X normal"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "y_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_NORM_Y); RNA_def_property_ui_text(prop, "Y Normal", "Enable displacement along the Y normal"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "z_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WAVE_NORM_Z); RNA_def_property_ui_text(prop, "Z Normal", "Enable displacement along the Z normal"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "timeoffs"); RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Time Offset", "Either the starting frame (for positive speed) or ending frame (for negative speed.)"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "lifetime", PROP_FLOAT, PROP_TIME); RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Lifetime", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "damping_time", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "damp"); RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Damping Time", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "falloff_radius", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "falloff"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 100, 2); RNA_def_property_ui_text(prop, "Falloff Radius", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "start_position_x", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "startx"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -100, 100, 100, 2); RNA_def_property_ui_text(prop, "Start Position X", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "start_position_y", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "starty"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -100, 100, 100, 2); RNA_def_property_ui_text(prop, "Start Position Y", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "start_position_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "objectcenter"); RNA_def_property_ui_text(prop, "Start Position Object", ""); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the wave."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Texture", "Texture for modulating the wave."); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "texture_coordinates", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "texmapping"); RNA_def_property_enum_items(prop, prop_texture_coordinates_items); RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used for modulating input."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); RNA_def_property_ui_text(prop, "UV Layer", "UV layer name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_uvlayer_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "texture_coordinates_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "map_object"); RNA_def_property_ui_text(prop, "Texture Coordinates Object", ""); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -1, 1, 10, 2); RNA_def_property_ui_text(prop, "Speed", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "height", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -2, 2, 10, 2); RNA_def_property_ui_text(prop, "Height", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "width", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 5, 10, 2); RNA_def_property_ui_text(prop, "Width", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "narrowness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "narrow"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 10, 10, 2); RNA_def_property_ui_text(prop, "Narrowness", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_armature(BlenderRNA *brna) @@ -836,43 +838,43 @@ static void rna_def_modifier_armature(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object", "Armature object to deform with."); RNA_def_property_pointer_funcs(prop, NULL, "rna_ArmatureModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ArmatureModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_INVERT_VGROUP); RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "use_vertex_groups", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_VGROUP); RNA_def_property_ui_text(prop, "Use Vertex Groups", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "use_bone_envelopes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_ENVELOPE); RNA_def_property_ui_text(prop, "Use Bone Envelopes", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "quaternion", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_QUATERNION); RNA_def_property_ui_text(prop, "Quaternion", "Deform rotation interpolation with quaternions."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "b_bone_rest", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_B_BONE_REST); RNA_def_property_ui_text(prop, "B-Bone Rest", "Make B-Bones deform already in rest position"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "multi_modifier", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "multi", 0); RNA_def_property_ui_text(prop, "Multi Modifier", "Use same input as previous modifier, and mix results using overall vgroup"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_hook(BlenderRNA *brna) @@ -889,28 +891,28 @@ static void rna_def_modifier_hook(BlenderRNA *brna) RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 100, 2); RNA_def_property_ui_text(prop, "Falloff", "If not zero, the distance from the hook where influence ends."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "force", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Force", "Relative force of the hook."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Object", "Parent Object for hook, also recalculates and clears offset"); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "subtarget"); RNA_def_property_ui_text(prop, "Sub-Target", "Name of Parent Bone for hook (if applicable), also recalculates and clears offset"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_HookModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_softbody(BlenderRNA *brna) @@ -954,12 +956,12 @@ static void rna_def_modifier_boolean(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object", "Mesh object to use for boolean operation."); RNA_def_property_pointer_funcs(prop, NULL, "rna_BooleanModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_operation_items); RNA_def_property_ui_text(prop, "Operation", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_array(BlenderRNA *brna) @@ -982,90 +984,90 @@ static void rna_def_modifier_array(BlenderRNA *brna) prop= RNA_def_property(srna, "fit_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_fit_type_items); RNA_def_property_ui_text(prop, "Fit Type", "Array length calculation method."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "count", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, INT_MAX); RNA_def_property_ui_range(prop, 1, 1000, 1, 0); RNA_def_property_ui_text(prop, "Count", "Number of duplicates to make."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "length", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0, INT_MAX); RNA_def_property_ui_range(prop, 0, 10000, 10, 2); RNA_def_property_ui_text(prop, "Length", "Length to fit array within."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "curve_ob"); RNA_def_property_ui_text(prop, "Curve", "Curve object to fit array length to."); RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_curve_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); /* Offset parameters */ prop= RNA_def_property(srna, "constant_offset", PROP_BOOLEAN, PROP_TRANSLATION); RNA_def_property_boolean_sdna(prop, NULL, "offset_type", MOD_ARR_OFF_CONST); RNA_def_property_ui_text(prop, "Constant Offset", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "constant_offset_displacement", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "offset"); RNA_def_property_ui_text(prop, "Constant Offset Displacement", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "relative_offset", PROP_BOOLEAN, PROP_TRANSLATION); RNA_def_property_boolean_sdna(prop, NULL, "offset_type", MOD_ARR_OFF_RELATIVE); RNA_def_property_ui_text(prop, "Relative Offset", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "relative_offset_displacement", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "scale"); RNA_def_property_ui_text(prop, "Relative Offset Displacement", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); /* Vertex merging parameters */ prop= RNA_def_property(srna, "merge_adjacent_vertices", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_ARR_MERGE); RNA_def_property_ui_text(prop, "Merge Vertices", "Merge vertices in adjacent duplicates."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "merge_end_vertices", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_ARR_MERGEFINAL); RNA_def_property_ui_text(prop, "Merge Vertices", "Merge vertices in first and last duplicates."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "merge_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "merge_dist"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 1, 1, 4); RNA_def_property_ui_text(prop, "Merge Distance", "Limit below which to merge vertices."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); /* Offset object */ prop= RNA_def_property(srna, "add_offset_object", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "offset_type", MOD_ARR_OFF_OBJ); RNA_def_property_ui_text(prop, "Add Offset Object", "Add an object transformation to the total offset."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "offset_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "offset_ob"); RNA_def_property_ui_text(prop, "Offset Object", ""); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); /* Caps */ prop= RNA_def_property(srna, "start_cap", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Start Cap", "Mesh object to use as a start cap."); RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_start_cap_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "end_cap", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "End Cap", "Mesh object to use as an end cap."); RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_end_cap_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); } static void rna_def_modifier_edgesplit(BlenderRNA *brna) @@ -1082,17 +1084,17 @@ static void rna_def_modifier_edgesplit(BlenderRNA *brna) RNA_def_property_range(prop, 0, 180); RNA_def_property_ui_range(prop, 0, 180, 100, 2); RNA_def_property_ui_text(prop, "Split Angle", "Angle above which to split edges."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "use_edge_angle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_EDGESPLIT_FROMANGLE); RNA_def_property_ui_text(prop, "Use Edge Angle", "Split edges with high angle between faces."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "use_sharp", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_EDGESPLIT_FROMFLAG); RNA_def_property_ui_text(prop, "Use Sharp Edges", "Split edges that are marked as sharp."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_displace(BlenderRNA *brna) @@ -1124,47 +1126,47 @@ static void rna_def_modifier_displace(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Texture", ""); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "midlevel", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Midlevel", "Material value that gives no displacement."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -100, 100, 10, 2); RNA_def_property_ui_text(prop, "Strength", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_direction_items); RNA_def_property_ui_text(prop, "Direction", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "texture_coordinates", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "texmapping"); RNA_def_property_enum_items(prop, prop_texture_coordinates_items); RNA_def_property_ui_text(prop, "Texture Coordinates", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); RNA_def_property_ui_text(prop, "UV Layer", "UV layer name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_uvlayer_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "texture_coordinate_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "map_object"); RNA_def_property_ui_text(prop, "Texture Coordinate Object", ""); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); } static void rna_def_modifier_uvproject(BlenderRNA *brna) @@ -1181,13 +1183,13 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); RNA_def_property_ui_text(prop, "UV Layer", "UV layer name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVProjectModifier_uvlayer_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "num_projectors", PROP_INT, PROP_NONE); RNA_def_property_ui_text(prop, "Number of Projectors", "Number of projectors to use."); RNA_def_property_int_funcs(prop, NULL, "rna_UVProjectModifier_num_projectors_set", NULL); RNA_def_property_range(prop, 1, MOD_UVPROJECT_MAX); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "projectors", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "UVProjector"); @@ -1197,26 +1199,26 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna) prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Image", ""); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "horizontal_aspect_ratio", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "aspectx"); RNA_def_property_range(prop, 1, FLT_MAX); RNA_def_property_ui_range(prop, 1, 1000, 100, 2); RNA_def_property_ui_text(prop, "Horizontal Aspect Ratio", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "vertical_aspect_ratio", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "aspecty"); RNA_def_property_range(prop, 1, FLT_MAX); RNA_def_property_ui_range(prop, 1, 1000, 100, 2); RNA_def_property_ui_text(prop, "Vertical Aspect Ratio", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "override_image", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_UVPROJECT_OVERRIDEIMAGE); RNA_def_property_ui_text(prop, "Override Image", "Override faces' current images with the given image."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); srna= RNA_def_struct(brna, "UVProjector", NULL); RNA_def_struct_ui_text(srna, "UVProjector", "UV projector used by the UV project modifier."); @@ -1241,35 +1243,35 @@ static void rna_def_modifier_smooth(BlenderRNA *brna) prop= RNA_def_property(srna, "x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SMOOTH_X); RNA_def_property_ui_text(prop, "X", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SMOOTH_Y); RNA_def_property_ui_text(prop, "Y", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SMOOTH_Z); RNA_def_property_ui_text(prop, "Z", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fac"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -10, 10, 0.5, 2); RNA_def_property_ui_text(prop, "Factor", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "repeat", PROP_INT, PROP_NONE); RNA_def_property_ui_range(prop, 0, 30, 1, 0); RNA_def_property_ui_text(prop, "Repeat", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmoothModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_cast(BlenderRNA *brna) @@ -1292,63 +1294,63 @@ static void rna_def_modifier_cast(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, prop_cast_type_items); RNA_def_property_ui_text(prop, "Cast Type", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Object", "Control object: if available, its location determines the center of the effect"); RNA_def_property_pointer_funcs(prop, NULL, "rna_CastModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_X); RNA_def_property_ui_text(prop, "X", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_Y); RNA_def_property_ui_text(prop, "Y", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_Z); RNA_def_property_ui_text(prop, "Z", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "from_radius", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_SIZE_FROM_RADIUS); RNA_def_property_ui_text(prop, "From Radius", "Use radius as size of projection shape (0 = auto)"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "use_transform", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_USE_OB_TRANSFORM); RNA_def_property_ui_text(prop, "Use transform", "Use object transform to control projection shape"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fac"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -10, 10, 5, 2); RNA_def_property_ui_text(prop, "Factor", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 10, 2); RNA_def_property_ui_text(prop, "Radius", "Only deform vertices within this distance from the center of the effect (leave as 0 for infinite.)"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 10, 2); RNA_def_property_ui_text(prop, "Size", "Size of projection shape (leave as 0 for auto.)"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_CastModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_meshdeform(BlenderRNA *brna) @@ -1365,29 +1367,29 @@ static void rna_def_modifier_meshdeform(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object", "Mesh object to deform with."); RNA_def_property_pointer_funcs(prop, NULL, "rna_MeshDeformModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MDEF_INVERT_VGROUP); RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshDeformModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "precision", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gridsize"); RNA_def_property_range(prop, 2, 10); RNA_def_property_ui_text(prop, "Precision", "The grid size for binding."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "dynamic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MDEF_DYNAMIC_BIND); RNA_def_property_ui_text(prop, "Dynamic", "Recompute binding dynamically on top of other deformers (slower and more memory consuming.)"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } @@ -1422,71 +1424,71 @@ static void rna_def_modifier_particleinstance(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "ob"); RNA_def_property_ui_text(prop, "Object", "Object that has the particle system."); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "particle_system_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "psys"); RNA_def_property_range(prop, 1, 10); RNA_def_property_ui_text(prop, "Particle System Number", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "axis"); RNA_def_property_enum_items(prop, particleinstance_axis); RNA_def_property_ui_text(prop, "Axis", "Pole axis for rotation"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Parents); RNA_def_property_ui_text(prop, "Normal", "Create instances from normal particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "children", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Children); RNA_def_property_ui_text(prop, "Children", "Create instances from child particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "path", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Path); RNA_def_property_ui_text(prop, "Path", "Create instances along particle paths."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "unborn", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Unborn); RNA_def_property_ui_text(prop, "Unborn", "Show instances when particles are unborn."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "alive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Alive); RNA_def_property_ui_text(prop, "Alive", "Show instances when particles are alive."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "dead", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_Dead); RNA_def_property_ui_text(prop, "Dead", "Show instances when particles are dead."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "keep_shape", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_KeepShape); RNA_def_property_ui_text(prop, "Keep Shape", "Don't stretch the object."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "size", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eParticleInstanceFlag_UseSize); RNA_def_property_ui_text(prop, "Size", "Use particle size to scale the instances."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "position", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "position"); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Position", "Position along path."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "random_position", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "random_position"); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "Random Position", "Randomize position along path."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_explode(BlenderRNA *brna) @@ -1506,27 +1508,27 @@ static void rna_def_modifier_explode(BlenderRNA *brna) prop= RNA_def_property(srna, "protect", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Protect", "Clean vertex group edges"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "split_edges", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_EdgeSplit); RNA_def_property_ui_text(prop, "Split Edges", "Split face edges for nicer shrapnel."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "unborn", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_Unborn); RNA_def_property_ui_text(prop, "Unborn", "Show mesh when particles are unborn."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "alive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_Alive); RNA_def_property_ui_text(prop, "Alive", "Show mesh when particles are alive."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "dead", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", eExplodeFlag_Dead); RNA_def_property_ui_text(prop, "Dead", "Show mesh when particles are dead."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_cloth(BlenderRNA *brna) @@ -1583,7 +1585,7 @@ static void rna_def_modifier_smoke(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, prop_smoke_type_items); RNA_def_property_ui_text(prop, "Type", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_set_type"); + RNA_def_property_update(prop, 0, "rna_Smoke_set_type"); } static void rna_def_modifier_collision(BlenderRNA *brna) @@ -1605,7 +1607,7 @@ static void rna_def_modifier_collision(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "absorption"); RNA_def_property_ui_range(prop, 0, 100, 1, 2); RNA_def_property_ui_text(prop, "Absorption %", "How much of effector force gets lost during collision with this object (in percent)."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_bevel(BlenderRNA *brna) @@ -1634,31 +1636,31 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "value"); RNA_def_property_range(prop, 0, 0.5); RNA_def_property_ui_text(prop, "Width", "Bevel value/amount."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "only_vertices", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_VERT); RNA_def_property_ui_text(prop, "Only Vertices", "Bevel verts/corners, not edges."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "limit_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "lim_flags"); RNA_def_property_enum_items(prop, prop_limit_method_items); RNA_def_property_ui_text(prop, "Limit Method", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "edge_weight_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "e_flags"); RNA_def_property_enum_items(prop, prop_edge_weight_method_items); RNA_def_property_ui_text(prop, "Edge Weight Method", "What edge weight to use for weighting a vertex."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bevel_angle"); RNA_def_property_range(prop, 0, 180); RNA_def_property_ui_range(prop, 0, 180, 100, 2); RNA_def_property_ui_text(prop, "Angle", "Angle above which to bevel edges."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) @@ -1681,80 +1683,80 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "shrinkType"); RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Mode", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Target", "Mesh target to shrink to."); RNA_def_property_pointer_funcs(prop, NULL, "rna_ShrinkwrapModifier_target_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "auxiliary_target", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "auxTarget"); RNA_def_property_ui_text(prop, "Auxiliary Target", "Additional mesh target to shrink to."); RNA_def_property_pointer_funcs(prop, NULL, "rna_ShrinkwrapModifier_auxiliary_target_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "vgroup_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShrinkwrapModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "keepDist"); RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 1, 2); RNA_def_property_ui_text(prop, "Offset", "Distance to keep from the target."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS); RNA_def_property_ui_text(prop, "X", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS); RNA_def_property_ui_text(prop, "Y", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS); RNA_def_property_ui_text(prop, "Z", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "subsurf_levels", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "subsurfLevels"); RNA_def_property_range(prop, 0, 6); RNA_def_property_ui_range(prop, 0, 6, 1, 0); RNA_def_property_ui_text(prop, "Subsurf Levels", "Number of subdivisions that must be performed before extracting vertices' positions and normals."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "negative", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR); RNA_def_property_ui_text(prop, "Negative", "Allow vertices to move in the negative direction of axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "positive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR); RNA_def_property_ui_text(prop, "Positive", "Allow vertices to move in the positive direction of axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "cull_front_faces", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE); RNA_def_property_ui_text(prop, "Cull Front Faces", "Stop vertices from projecting to a front face on the target."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "cull_back_faces", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_CULL_TARGET_BACKFACE); RNA_def_property_ui_text(prop, "Cull Back Faces", "Stop vertices from projecting to a back face on the target."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "keep_above_surface", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shrinkOpts", MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE); RNA_def_property_ui_text(prop, "Keep Above Surface", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_fluidsim(BlenderRNA *brna) @@ -1790,25 +1792,25 @@ static void rna_def_modifier_mask(BlenderRNA *brna) prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Mode", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "armature", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "ob_arm"); RNA_def_property_ui_text(prop, "Armature", "Armature to use as source of bones to mask."); RNA_def_property_pointer_funcs(prop, NULL, "rna_MaskModifier_armature_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "vgroup"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "inverse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MASK_INV); RNA_def_property_ui_text(prop, "Inverse", "Use vertices that are not part of region defined."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_simpledeform(BlenderRNA *brna) @@ -1831,29 +1833,29 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Mode", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "vgroup_name"); RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name."); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SimpleDeformModifier_vgroup_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "origin", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Origin", "Origin of modifier space coordinates."); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_dependency_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); prop= RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "originOpts", MOD_SIMPLEDEFORM_ORIGIN_LOCAL); RNA_def_property_ui_text(prop, "Relative", "Sets the origin of deform space to be relative to the object."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -10, 10, 0.5, 2); RNA_def_property_ui_text(prop, "Factor", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "limits", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "limit"); @@ -1861,17 +1863,17 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_range(prop, 0, 1, 5, 2); RNA_def_property_ui_text(prop, "Limits", "Lower/Upper limits for deform."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "lock_x_axis", 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", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "lock_y_axis", 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", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_surface(BlenderRNA *brna) @@ -1911,7 +1913,7 @@ void RNA_def_modifier(BlenderRNA *brna) prop= RNA_def_property(srna, "realtime", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Realtime); RNA_def_property_ui_text(prop, "Realtime", "Realtime display of a modifier."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 0); prop= RNA_def_property(srna, "render", PROP_BOOLEAN, PROP_NONE); @@ -1922,13 +1924,13 @@ void RNA_def_modifier(BlenderRNA *brna) prop= RNA_def_property(srna, "editmode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Editmode); RNA_def_property_ui_text(prop, "Editmode", "Use modifier while in the edit mode."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0); prop= RNA_def_property(srna, "on_cage", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_OnCage); RNA_def_property_ui_text(prop, "On Cage", "Enable direct editing of modifier control cage."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Modifier_update"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop= RNA_def_property(srna, "expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Expanded); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index bbb10991564..50ccbc86719 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -39,9 +39,9 @@ #include "DNA_property_types.h" #include "DNA_scene_types.h" +#include "WM_api.h" #include "WM_types.h" - EnumPropertyItem object_mode_items[] = { {OB_MODE_OBJECT, "OBJECT", ICON_OBJECT_DATAMODE, "Object", ""}, {OB_MODE_EDIT, "EDIT", ICON_EDITMODE_HLT, "Edit", ""}, @@ -84,17 +84,18 @@ static EnumPropertyItem parent_type_items[] = { void rna_Object_update(bContext *C, PointerRNA *ptr) { - DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_OB); + DAG_id_flush_update(ptr->id.data, OB_RECALC_OB); } void rna_Object_update_data(bContext *C, PointerRNA *ptr) { - DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ptr->id.data); } static void rna_Object_dependency_update(bContext *C, PointerRNA *ptr) { - DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_OB); + DAG_id_flush_update(ptr->id.data, OB_RECALC_OB); DAG_scene_sort(CTX_data_scene(C)); } @@ -1042,7 +1043,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_Object_data_editable"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Data", "Object data."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_Object_update_data"); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); @@ -1223,13 +1224,13 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_struct_type(prop, "VertexGroup"); RNA_def_property_pointer_funcs(prop, "rna_Object_active_vertex_group_get", "rna_Object_active_vertex_group_set", NULL); RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_Object_update_data"); prop= RNA_def_property(srna, "active_vertex_group_index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "actdef"); RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get", "rna_Object_active_vertex_group_index_set", "rna_Object_active_vertex_group_index_range"); RNA_def_property_ui_text(prop, "Active Vertex Group Index", "Active index in vertex group array."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_Object_update_data"); /* empty */ @@ -1490,7 +1491,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_shape_key_lock_set"); RNA_def_property_ui_text(prop, "Shape Key Lock", "Always show the current Shape for this Object."); RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_Object_update_data"); prop= RNA_def_property(srna, "active_shape_key", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ShapeKey"); @@ -1501,7 +1502,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "shapenr"); RNA_def_property_int_funcs(prop, "rna_Object_active_shape_key_index_get", "rna_Object_active_shape_key_index_set", "rna_Object_active_shape_key_index_range"); RNA_def_property_ui_text(prop, "Active Shape Key Index", "Current shape key index."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_Object_update_data"); RNA_api_object(srna); } diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 932bef9969d..3dfbfcccacf 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -54,7 +54,6 @@ static void rna_Cache_change(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); PointCache *cache = (PointCache*)ptr->data; PTCacheID *pid = NULL; @@ -67,7 +66,7 @@ static void rna_Cache_change(bContext *C, PointerRNA *ptr) BKE_ptcache_ids_from_object(&pidlist, ob); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache==cache) @@ -105,7 +104,6 @@ static void rna_Cache_toggle_disk_cache(bContext *C, PointerRNA *ptr) static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); PointCache *cache = (PointCache*)ptr->data; PTCacheID *pid = NULL, *pid2= NULL; @@ -133,7 +131,7 @@ static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr) cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_FRAMES_SKIPPED); BKE_ptcache_load_external(pid); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { for(pid=pidlist.first; pid; pid=pid->next) { @@ -362,7 +360,6 @@ static void rna_SoftBodySettings_goal_vgroup_set(PointerRNA *ptr, const char *va static void rna_FieldSettings_update(bContext *C, PointerRNA *ptr) { - Scene *scene= CTX_data_scene(C); Object *ob= (Object*)ptr->id.data; if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex) { @@ -370,7 +367,7 @@ static void rna_FieldSettings_update(bContext *C, PointerRNA *ptr) ob->pd->tex= 0; } - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); } @@ -413,9 +410,9 @@ static void rna_FieldSettings_dependency_update(bContext *C, PointerRNA *ptr) DAG_scene_sort(scene); if(ob->type == OB_CURVE && ob->pd->forcefield == PFIELD_GUIDE) - DAG_object_flush_update(scene, ob, OB_RECALC); + DAG_id_flush_update(&ob->id, OB_RECALC); else - DAG_object_flush_update(scene, ob, OB_RECALC_OB); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); } @@ -437,13 +434,20 @@ static void rna_CollisionSettings_dependency_update(bContext *C, PointerRNA *ptr static void rna_CollisionSettings_update(bContext *C, PointerRNA *ptr) { - Scene *scene= CTX_data_scene(C); Object *ob= (Object*)ptr->id.data; - DAG_object_flush_update(scene, ob, OB_RECALC); + DAG_id_flush_update(&ob->id, OB_RECALC); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); } +static void rna_softbody_update(bContext *C, PointerRNA *ptr) +{ + Object *ob= (Object*)ptr->id.data; + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); +} + #else static void rna_def_pointcache(BlenderRNA *brna) @@ -896,25 +900,25 @@ static void rna_def_softbody(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "mediafrict"); RNA_def_property_range(prop, 0.0f, 50.0f); RNA_def_property_ui_text(prop, "Friction", "General media friction for point movements"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "nodemass"); RNA_def_property_range(prop, 0.0f, 50000.0f); RNA_def_property_ui_text(prop, "Mass", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION); RNA_def_property_float_sdna(prop, NULL, "grav"); RNA_def_property_range(prop, -10.0f, 10.0f); RNA_def_property_ui_text(prop, "Gravitation", "Apply gravitation to point movement"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "physics_speed"); RNA_def_property_range(prop, 0.01f, 100.0f); RNA_def_property_ui_text(prop, "Speed", "Tweak timing for physics to control frequency and speed"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); /* Goal */ @@ -927,31 +931,31 @@ static void rna_def_softbody(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "mingoal"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "maxgoal"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "defgoal"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "goalspring"); RNA_def_property_range(prop, 0.0f, 0.999f); RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "goalfrict"); RNA_def_property_range(prop, 0.0f, 50.0f); RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); /* Edge Spring Settings */ @@ -959,43 +963,43 @@ static void rna_def_softbody(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "inspring"); RNA_def_property_range(prop, 0.0f, 0.999f); RNA_def_property_ui_text(prop, "Pull", "Edge spring stiffness when longer than rest length"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "push", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "inpush"); RNA_def_property_range(prop, 0.0f, 0.999f); RNA_def_property_ui_text(prop, "Push", "Edge spring stiffness when shorter than rest length"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "damp", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "infrict"); RNA_def_property_range(prop, 0.0f, 50.0f); RNA_def_property_ui_text(prop, "Damp", "Edge spring friction"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "spring_length", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "springpreload"); RNA_def_property_range(prop, 0.0f, 200.0f); RNA_def_property_ui_text(prop, "SL", "Alter spring length to shrink/blow up (unit %) 0 to disable"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "aero", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "aeroedge"); RNA_def_property_range(prop, 0.0f, 30000.0f); RNA_def_property_ui_text(prop, "Aero", "Make edges 'sail'"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "plastic", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "plastic"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Plastic", "Permanent deform"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "bending", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "secondspring"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Bending", "Bending Stiffness"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "shear", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "shearstiff"); @@ -1008,25 +1012,25 @@ static void rna_def_softbody(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "sbc_mode"); RNA_def_property_enum_items(prop, collision_type_items); RNA_def_property_ui_text(prop, "Collision Type", "Choose Collision Type"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "ball_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "colball"); RNA_def_property_range(prop, -10.0f, 10.0f); RNA_def_property_ui_text(prop, "Ball Size", "Absolute ball size or factor if not manual adjusted"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "ball_stiff", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ballstiff"); RNA_def_property_range(prop, 0.001f, 100.0f); RNA_def_property_ui_text(prop, "Ball Size", "Ball inflating presure"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "ball_damp", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "balldamp"); RNA_def_property_range(prop, 0.001f, 1.0f); RNA_def_property_ui_text(prop, "Ball Size", "Blending to inelastic collision"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); /* Solver */ @@ -1034,36 +1038,36 @@ static void rna_def_softbody(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "rklimit"); RNA_def_property_range(prop, 0.001f, 10.0f); RNA_def_property_ui_text(prop, "Error Limit", "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "minstep", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "minloops"); RNA_def_property_range(prop, 0, 30000); RNA_def_property_ui_text(prop, "Min Step", "Minimal # solver steps/frame"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "maxstep", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "maxloops"); RNA_def_property_range(prop, 0, 30000); RNA_def_property_ui_text(prop, "Max Step", "Maximal # solver steps/frame"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "choke", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "choke"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Choke", "'Viscosity' inside collision target"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "fuzzy", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "fuzzyness"); RNA_def_property_range(prop, 1, 100); RNA_def_property_ui_text(prop, "Fuzzy", "Fuzzyness while on collision, high values make collsion handling faster but less stable"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_OLDERR); RNA_def_property_ui_text(prop, "V", "Use velocities for automagic step sizes"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "diagnose", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_MONITOR); @@ -1074,37 +1078,37 @@ static void rna_def_softbody(BlenderRNA *brna) prop= RNA_def_property(srna, "use_goal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_goal_get", "rna_SoftBodySettings_use_goal_set"); RNA_def_property_ui_text(prop, "Use Goal", "Define forces for vertices to stick to animated position."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "use_edges", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_edges_get", "rna_SoftBodySettings_use_edges_set"); RNA_def_property_ui_text(prop, "Use Edges", "Use Edges as springs"); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "stiff_quads", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_stiff_quads_get", "rna_SoftBodySettings_stiff_quads_set"); RNA_def_property_ui_text(prop, "Stiff Quads", "Adds diagonal springs on 4-gons."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "edge_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_edge_collision_get", "rna_SoftBodySettings_edge_collision_set"); RNA_def_property_ui_text(prop, "Edge Collision", "Edges collide too."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "face_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_face_collision_get", "rna_SoftBodySettings_face_collision_set"); RNA_def_property_ui_text(prop, "Face Collision", "Faces collide too, SLOOOOOW warning."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "new_aero", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_new_aero_get", "rna_SoftBodySettings_new_aero_set"); RNA_def_property_ui_text(prop, "N", "New aero(uses angle and length)."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); prop= RNA_def_property(srna, "self_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get", "rna_SoftBodySettings_self_collision_set"); RNA_def_property_ui_text(prop, "Self Collision", "Enable naive vertex ball self collision."); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data"); + RNA_def_property_update(prop, 0, "rna_softbody_update"); } void RNA_def_object_force(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index a1f35eca3c2..2525209c3be 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -114,12 +114,14 @@ static void rna_Particle_redo(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_REDO; if(ob) - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_REDO); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Particle_reset(bContext *C, PointerRNA *ptr) @@ -134,13 +136,15 @@ static void rna_Particle_reset(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_RESET; if(ob) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } else { part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Particle_target_reset(bContext *C, PointerRNA *ptr) @@ -172,22 +176,23 @@ static void rna_Particle_target_reset(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_RESET; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); DAG_scene_sort(scene); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Particle_target_redo(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); - if(ptr->type==&RNA_ParticleTarget) { Object *ob = (Object*)ptr->id.data; ParticleSystem *psys = psys_get_current(ob); psys->recalc = PSYS_RECALC_REDO; - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } } @@ -203,13 +208,15 @@ static void rna_Particle_change_type(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_RESET|PSYS_RECALC_TYPE; if(ob) { - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } else { part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr) @@ -217,6 +224,7 @@ static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr) Scene *scene = CTX_data_scene(C); ParticleSettings *part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_PHYS); + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr) @@ -231,13 +239,15 @@ static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr) psys->recalc = PSYS_RECALC_CHILD; if(ob) - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } else { part = ptr->id.data; psys_flush_particle_settings(scene, part, PSYS_RECALC_CHILD); } + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static PointerRNA rna_particle_settings_get(PointerRNA *ptr) { @@ -892,19 +902,19 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_REACT_STA_END); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Start/End", "Give birth to unreacted particles eventually."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "react_multiple", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_REACT_MULTIPLE); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Multi React", "React multiple times."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "loop", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_LOOP); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Loop", "Loop particle lives."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* TODO: used somewhere? */ prop= RNA_def_property(srna, "hair_geometry", PROP_BOOLEAN, PROP_NONE); @@ -914,94 +924,94 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "unborn", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_UNBORN); RNA_def_property_ui_text(prop, "Unborn", "Show particles before they are emitted."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "died", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIED); RNA_def_property_ui_text(prop, "Died", "Show particles after they have died"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "trand", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_TRAND); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Random", "Emit in random order of elements"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "even_distribution", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_EDISTR); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Even Distribution", "Use even distribution from faces based on face areas or edge lengths."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "sticky", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_STICKY); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Sticky", "Particles stick to collided objects if they die in the collision."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "die_on_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Die on hit", "Particles die when they collide with a deflector object."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "size_deflect", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_SIZE_DEFL); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Size Deflect", "Use particle's size in deflection."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "rotation_dynamic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ROT_DYN); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Dynamic", "Sets rotation to dynamic/constant"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "sizemass", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_SIZEMASS); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Mass from Size", "Multiply mass with particle size."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "boids_2d", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_BOIDS_2D); RNA_def_property_ui_text(prop, "Boids 2D", "Constrain boids to a surface"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "branching", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_BRANCHING); RNA_def_property_ui_text(prop, "Branching", "Branch child paths from each other."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "animate_branching", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ANIM_BRANCHING); RNA_def_property_ui_text(prop, "Animated", "Animate branching"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "symmetric_branching", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_SYMM_BRANCHING); RNA_def_property_ui_text(prop, "Symmetric", "Start and end points are the same."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "hair_bspline", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_HAIR_BSPLINE); RNA_def_property_ui_text(prop, "B-Spline", "Interpolate hair using B-Splines."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "grid_invert", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_GRID_INVERT); RNA_def_property_ui_text(prop, "Invert", "Invert what is considered object and what is not."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "child_effector", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_EFFECT); RNA_def_property_ui_text(prop, "Children", "Apply effectors to children."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS); RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* TODO: used somewhere? */ prop= RNA_def_property(srna, "child_render", PROP_BOOLEAN, PROP_NONE); @@ -1011,19 +1021,19 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "child_guide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_GUIDE); RNA_def_property_ui_text(prop, "child_guide", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "self_effect", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_SELF_EFFECT); RNA_def_property_ui_text(prop, "Self Effect", "Particle effectors effect themselves."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, type_items); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Type", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_change_type"); + RNA_def_property_update(prop, 0, "rna_Particle_change_type"); prop= RNA_def_property(srna, "emit_from", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "from"); @@ -1031,14 +1041,14 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_from_itemf"); RNA_def_property_ui_text(prop, "Emit From", "Where to emit particles from"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "distr"); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_enum_items(prop, dist_items); RNA_def_property_ui_text(prop, "Distribution", "How to distribute particles on selected element"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* physics modes */ prop= RNA_def_property(srna, "physics_type", PROP_ENUM, PROP_NONE); @@ -1046,130 +1056,130 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_enum_items(prop, phys_type_items); RNA_def_property_ui_text(prop, "Physics Type", "Particle physics type"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_change_physics"); + RNA_def_property_update(prop, 0, "rna_Particle_change_physics"); prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "rotmode"); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_enum_items(prop, rot_mode_items); RNA_def_property_ui_text(prop, "Rotation", "Particles initial rotation"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "angular_velocity_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "avemode"); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_enum_items(prop, ave_mode_items); RNA_def_property_ui_text(prop, "Angular Velocity Mode", "Particle angular velocity mode."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "react_event", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "reactevent"); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_enum_items(prop, react_event_items); RNA_def_property_ui_text(prop, "React On", "The event of target particles to react on."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /*draw flag*/ prop= RNA_def_property(srna, "velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_VEL); RNA_def_property_ui_text(prop, "Velocity", "Show particle velocity"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "show_size", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_SIZE); RNA_def_property_ui_text(prop, "Size", "Show particle size"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "emitter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_EMITTER); RNA_def_property_ui_text(prop, "Emitter", "Render emitter Object also."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "draw_health", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_HEALTH); RNA_def_property_ui_text(prop, "Health", "Draw boid health"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "abs_path_time", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_ABS_PATH_TIME); RNA_def_property_ui_text(prop, "Absolute Path Time", "Path timing is in absolute frames"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_abspathtime_update"); + RNA_def_property_update(prop, 0, "rna_Particle_abspathtime_update"); prop= RNA_def_property(srna, "billboard_lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_BB_LOCK); RNA_def_property_ui_text(prop, "Lock Billboard", "Lock the billboards align axis"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_PARENT); RNA_def_property_ui_text(prop, "Parents", "Render parent particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "num", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_NUM); RNA_def_property_ui_text(prop, "Number", "Show particle number"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "rand_group", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_RAND_GR); RNA_def_property_ui_text(prop, "Pick Random", "Pick objects from group randomly"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "render_adaptive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_ADAPT); RNA_def_property_ui_text(prop, "Adaptive render", "Draw steps of the particle path"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "velocity_length", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_VEL_LENGTH); RNA_def_property_ui_text(prop, "Speed", "Multiply line length by particle speed"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "material_color", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_MAT_COL); RNA_def_property_ui_text(prop, "Material Color", "Draw particles using material's diffuse color."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "whole_group", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_WHOLE_GR); RNA_def_property_ui_text(prop, "Whole Group", "Use whole group at once."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "render_strand", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_STRAND); RNA_def_property_ui_text(prop, "Strand render", "Use the strand primitive for rendering"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "draw_as", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "draw_as"); RNA_def_property_enum_items(prop, part_draw_as_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_draw_as_itemf"); RNA_def_property_ui_text(prop, "Particle Drawing", "How particles are drawn in viewport"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "ren_as", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "ren_as"); RNA_def_property_enum_items(prop, part_ren_as_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_ren_as_itemf"); RNA_def_property_ui_text(prop, "Particle Rendering", "How particles are rendered"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "draw_size", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 10); RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in pixels (0=default)"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "child_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "childtype"); RNA_def_property_enum_items(prop, child_type_items); RNA_def_property_ui_text(prop, "Children From", "Create child particles"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 7); RNA_def_property_ui_range(prop, 0, 10, 1, 0); RNA_def_property_ui_text(prop, "Steps", "How many steps paths are drawn with (power of 2)"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "render_step", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ren_step"); @@ -1180,7 +1190,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "hair_step", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 2, 50); RNA_def_property_ui_text(prop, "Segments", "Number of hair segments"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); //TODO: not found in UI, readonly? @@ -1203,13 +1213,13 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "disp"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Display", "Percentage of particles to display in 3d view"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "material", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "omat"); RNA_def_property_range(prop, 1, 16); RNA_def_property_ui_text(prop, "Material", "Specify material used for the particles"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); //TODO: is this read only/internal? @@ -1221,24 +1231,24 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "integrator", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, integrator_type_items); RNA_def_property_ui_text(prop, "Integration", "Select physics integrator type"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "kink", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, kink_type_items); RNA_def_property_ui_text(prop, "Kink", "Type of periodic offset on the path"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "kink_axis", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, kink_axis_items); RNA_def_property_ui_text(prop, "Axis", "Which axis to use for offset"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* billboards */ prop= RNA_def_property(srna, "billboard_align", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "bb_align"); RNA_def_property_enum_items(prop, bb_align_items); RNA_def_property_ui_text(prop, "Align to", "In respect to what the billboards are aligned"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "billboard_uv_split", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "bb_uv_split"); @@ -1260,13 +1270,13 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "bb_tilt"); RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Tilt", "Tilt of the billboards"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "billboard_random_tilt", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bb_rand_tilt"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random Tilt", "Random tilt of the billboards"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "billboard_offset", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "bb_offset"); @@ -1274,7 +1284,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, -100.0f, 100.0f); RNA_def_property_ui_range(prop, -1.0, 1.0, 0.1, 3); RNA_def_property_ui_text(prop, "Billboard Offset", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* simplification */ prop= RNA_def_property(srna, "enable_simplify", PROP_BOOLEAN, PROP_NONE); @@ -1309,7 +1319,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_float_funcs(prop, NULL, "rna_PartSettings_start_set", NULL); RNA_def_property_ui_text(prop, "Start", "Frame # to start emitting particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "end", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); @@ -1317,37 +1327,37 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_float_funcs(prop, NULL, "rna_PartSettings_end_set", NULL); RNA_def_property_ui_text(prop, "End", "Frame # to stop emitting particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "lifetime", PROP_FLOAT, PROP_TIME); RNA_def_property_range(prop, 1.0f, MAXFRAMEF); RNA_def_property_ui_text(prop, "Lifetime", "Specify the life span of the particles"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "random_lifetime", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "randlife"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random", "Give the particle life a random variation."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "time_tweak", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "timetweak"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Tweak", "A multiplier for physics timestep (1.0 means one frame = 1/25 seconds)"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_float_sdna(prop, NULL, "jitfac"); RNA_def_property_range(prop, 0.0f, 2.0f); RNA_def_property_ui_text(prop, "Amount", "Amount of jitter applied to the sampling."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "effect_hair", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "eff_hair"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Stiffnes", "Hair stiffness for effectors"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "amount", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "totpart"); @@ -1358,14 +1368,14 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0, 10000000); RNA_def_property_ui_range(prop, 0, 100000, 1, 0); RNA_def_property_ui_text(prop, "Amount", "Total number of particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "userjit", PROP_INT, PROP_UNSIGNED);//TODO: can we get a better name for userjit? RNA_def_property_int_sdna(prop, NULL, "userjit"); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_range(prop, 0, 1000); RNA_def_property_ui_text(prop, "P/F", "Emission locations / face (0 = automatic)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "grid_resolution", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "grid_res"); @@ -1373,102 +1383,102 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, 1, 46); /* ~100k particles in a cube */ RNA_def_property_ui_range(prop, 1, 215, 1, 0); /* ~10M particles in a cube */ RNA_def_property_ui_text(prop, "Resolution", "The resolution of the particle grid."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* initial velocity factors */ prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "normfac");//optional if prop names are the same RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_text(prop, "Normal", "Let the surface normal give the particle a starting speed."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "object_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "obfac"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Object", "Let the object give the particle a starting speed"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "random_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "randfac");//optional if prop names are the same RNA_def_property_range(prop, 0.0f, 200.0f); RNA_def_property_ui_text(prop, "Random", "Give the starting speed a random variation."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "particle_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "partfac"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Particle", "Let the target particle give the particle a starting speed."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "tangent_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "tanfac"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_text(prop, "Tangent", "Let the surface tangent give the particle a starting speed."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "tangent_phase", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "tanphase"); RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Rot", "Rotate the surface tangent."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "reactor_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "reactfac"); RNA_def_property_range(prop, -10.0f, 10.0f); RNA_def_property_ui_text(prop, "Reactor", "Let the vector away from the target particles location give the particle a starting speed."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "angular_velocity_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "avefac"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_text(prop, "Angular Velocity", "Angular velocity amount"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "phase_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "phasefac"); RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Phase", "Initial rotation phase"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "random_rotation_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "randrotfac"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random Rotation", "Randomize rotation"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "random_phase_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "randphasefac"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random Phase", "Randomize rotation phase"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* physical properties */ prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.001f, 100000.0f); RNA_def_property_ui_range(prop, 0.01f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Mass", "Specify the mass of the particles"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "particle_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_range(prop, 0.001f, 100000.0f); RNA_def_property_ui_range(prop, 0.01f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Size", "The size of the particles"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "random_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "randsize"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random Size", "Give the particle size a random variation"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "reaction_shape", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "reactshape"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Shape", "Power of reaction strength dependence on distance to target."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* global physical properties */ @@ -1477,38 +1487,38 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_text(prop, "Acceleration", "Constant acceleration"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION); RNA_def_property_float_sdna(prop, NULL, "acc[2]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_text(prop, "Gravity", "Constant acceleration in global Z axis direction"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "drag_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "dragfac"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Drag", "Specify the amount of air-drag."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "brownian_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "brownfac"); RNA_def_property_range(prop, 0.0f, 200.0f); RNA_def_property_ui_text(prop, "Brownian", "Specify the amount of brownian motion"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "damp_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "dampfac"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Damp", "Specify the amount of damping"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* random length */ prop= RNA_def_property(srna, "random_length", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "randlength"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random Length", "Give path length a random variation."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* children */ prop= RNA_def_property(srna, "child_nbr", PROP_INT, PROP_NONE); @@ -1516,7 +1526,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0, 100000); RNA_def_property_ui_range(prop, 0, 1000, 1, 0); RNA_def_property_ui_text(prop, "Children Per Parent", "Amount of children/parent"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rendered_child_nbr", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ren_child_nbr"); @@ -1528,45 +1538,45 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "parents"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Virtual Parents", "Relative amount of virtual parents."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "child_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "childsize"); RNA_def_property_range(prop, 0.001f, 100000.0f); RNA_def_property_ui_range(prop, 0.01f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Child Size", "A multiplier for the child particle size."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "child_random_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "childrandsize"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Random Child Size", "Random variation to the size of the child particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "child_radius", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "childrad"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Child Radius", "Radius of children around parent."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "child_roundness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "childflat"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Child Roundness", "Roundness of children around parent."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* clumping */ prop= RNA_def_property(srna, "clump_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "clumpfac"); RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Clump", "Amount of clumping"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "clumppow", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "clumppow"); RNA_def_property_range(prop, -0.999f, 0.999f); RNA_def_property_ui_text(prop, "Shape", "Shape of clumping"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* kink */ @@ -1575,19 +1585,19 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, -100000.0f, 100000.0f); RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Amplitude", "The amplitude of the offset."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "kink_frequency", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "kink_freq"); RNA_def_property_range(prop, -100000.0f, 100000.0f); RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Frequency", "The frequency of the offset (1/total length)"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "kink_shape", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -0.999f, 0.999f); RNA_def_property_ui_text(prop, "Shape", "Adjust the offset to the beginning/end"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* rough */ @@ -1595,64 +1605,64 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Rough1", "Amount of location dependent rough."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough1_size", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.01f, 100000.0f); RNA_def_property_ui_range(prop, 0.01f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Size1", "Size of location dependent rough."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough2", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough2"); RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Rough2", "Amount of random rough."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough2_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough2_size"); RNA_def_property_range(prop, 0.01f, 100000.0f); RNA_def_property_ui_range(prop, 0.01f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Size2", "Size of random rough."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough2_thres", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough2_thres"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Threshold", "Amount of particles left untouched by random rough."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough_endpoint", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough_end"); RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Rough Endpoint", "Amount of end point rough."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough_end_shape", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Shape", "Shape of end point rough"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "child_length", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "clength"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Length", "Length of child paths"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "child_length_thres", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "clength_thres"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Threshold", "Amount of particles left untouched by child path length."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* branching */ prop= RNA_def_property(srna, "branch_threshold", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "branch_thres"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Threshold", "Threshold of branching."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* drawing stuff */ prop= RNA_def_property(srna, "line_length_tail", PROP_FLOAT, PROP_NONE); @@ -1660,33 +1670,33 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Back", "Length of the line's tail"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "line_length_head", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_PartSetting_linelenhead_get", "rna_PartSetting_linelenhead_set", NULL); RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Head", "Length of the line's head"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "path_start", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "path_start"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_PartSetting_pathstartend_range"); RNA_def_property_ui_text(prop, "Path Start", "Starting time of drawn path."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "path_end", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "path_end"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_PartSetting_pathstartend_range"); RNA_def_property_ui_text(prop, "Path End", "End time of drawn path."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "trail_count", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "trail_count"); RNA_def_property_range(prop, 1, 100000); RNA_def_property_ui_range(prop, 1, 100, 1, 0); RNA_def_property_ui_text(prop, "Trail Count", "Number of trail particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* keyed particles */ prop= RNA_def_property(srna, "keyed_loops", PROP_INT, PROP_NONE); @@ -1694,7 +1704,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_range(prop, 1.0f, 10000.0f); RNA_def_property_ui_range(prop, 1.0f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Loop count", "Number of times the keys are looped."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* boids */ prop= RNA_def_property(srna, "boids", PROP_POINTER, PROP_NONE); @@ -1709,21 +1719,21 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Group"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Dupli Group", "Show Objects in this Group in place of particles"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "dupli_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "dup_ob"); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Dupli Object", "Show this Object in place of particles."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "billboard_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bb_ob"); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Billboard Object", "Billboards face this object (default is active camera)"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* effectors */ prop= RNA_def_property(srna, "effector_group", PROP_POINTER, PROP_NONE); @@ -1731,77 +1741,77 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Group"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this Group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_all", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[0]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "All", "All effector's weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_spherical", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[1]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_vortex", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[2]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Vortex", "Vortex effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_magnetic", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[3]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Magnetic", "Magnetic effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_wind", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[4]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Wind", "Wind effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_curveguide", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[5]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Curve Guide", "Curve guide effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_texture", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[6]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Magnetic", "Texture effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_harmonic", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[7]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Harmonic", "Harmonic effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_charge", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[8]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Charge", "Charge effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_lennardjones", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[9]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Lennard-Jones", "Lennard-Jones effector weight."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* animation here? */ rna_def_animdata_common(srna); @@ -1836,25 +1846,25 @@ static void rna_def_particle_target(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "ob"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Target Object", "The object that has the target particle system (empty if same object)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_target_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_target_reset"); prop= RNA_def_property(srna, "system", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "psys"); RNA_def_property_range(prop, 1, INT_MAX); RNA_def_property_ui_text(prop, "Target Particle System", "The index of particle system on the target object."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_target_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_target_reset"); prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "time"); RNA_def_property_range(prop, 0.0, 30000.0f); //TODO: replace 30000 with MAXFRAMEF when available in 2.5 RNA_def_property_ui_text(prop, "Time", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_target_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_target_redo"); prop= RNA_def_property(srna, "duration", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "duration"); RNA_def_property_range(prop, 0.0, 30000.0f); //TODO: replace 30000 with MAXFRAMEF when available in 2.5 RNA_def_property_ui_text(prop, "Duration", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_target_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_target_redo"); prop= RNA_def_property(srna, "valid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PTARGET_VALID); @@ -1865,7 +1875,7 @@ static void rna_def_particle_target(BlenderRNA *brna) RNA_def_property_enum_items(prop, mode_items); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Mode", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_target_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_target_reset"); } static void rna_def_particle_system(BlenderRNA *brna) @@ -1889,7 +1899,7 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_particle_settings_get", "rna_particle_settings_set", NULL); RNA_def_property_ui_text(prop, "Settings", "Particle system settings."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart"); @@ -1903,7 +1913,7 @@ static void rna_def_particle_system(BlenderRNA *brna) prop= RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED); RNA_def_property_ui_text(prop, "Seed", "Offset in the random number table, to get a different randomized result."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* hair */ prop= RNA_def_property(srna, "softbody", PROP_POINTER, PROP_NONE); @@ -1919,20 +1929,20 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "target_ob"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Reactor Target Object", "For reactor systems, the object that has the target particle system (empty if same object)."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "reactor_target_particle_system", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "target_psys"); RNA_def_property_range(prop, 1, INT_MAX); RNA_def_property_ui_text(prop, "Reactor Target Particle System", "For reactor systems, index of particle system on the target object."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* keyed */ prop= RNA_def_property(srna, "keyed_timing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_KEYED_TIMING); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Keyed timing", "Use key times"); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "ParticleTarget"); @@ -1968,122 +1978,122 @@ static void rna_def_particle_system(BlenderRNA *brna) prop= RNA_def_property(srna, "vertex_group_density", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[0]"); RNA_def_property_ui_text(prop, "Vertex Group Density", "Vertex group to control density."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_density_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_DENSITY)); RNA_def_property_ui_text(prop, "Vertex Group Density Negate", "Negate the effect of the density vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_velocity", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[1]"); RNA_def_property_ui_text(prop, "Vertex Group Velocity", "Vertex group to control velocity."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_velocity_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_VEL)); RNA_def_property_ui_text(prop, "Vertex Group Velocity Negate", "Negate the effect of the velocity vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_length", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[2]"); RNA_def_property_ui_text(prop, "Vertex Group Length", "Vertex group to control length."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "vertex_group_length_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_LENGTH)); RNA_def_property_ui_text(prop, "Vertex Group Length Negate", "Negate the effect of the length vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); prop= RNA_def_property(srna, "vertex_group_clump", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[3]"); RNA_def_property_ui_text(prop, "Vertex Group Clump", "Vertex group to control clump."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_clump_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_CLUMP)); RNA_def_property_ui_text(prop, "Vertex Group Clump Negate", "Negate the effect of the clump vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_kink", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[4]"); RNA_def_property_ui_text(prop, "Vertex Group Kink", "Vertex group to control kink."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_kink_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_KINK)); RNA_def_property_ui_text(prop, "Vertex Group Kink Negate", "Negate the effect of the kink vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_roughness1", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[5]"); RNA_def_property_ui_text(prop, "Vertex Group Roughness 1", "Vertex group to control roughness 1."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_roughness1_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROUGH1)); RNA_def_property_ui_text(prop, "Vertex Group Roughness 1 Negate", "Negate the effect of the roughness 1 vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_roughness2", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[6]"); RNA_def_property_ui_text(prop, "Vertex Group Roughness 2", "Vertex group to control roughness 2."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_roughness2_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROUGH2)); RNA_def_property_ui_text(prop, "Vertex Group Roughness 2 Negate", "Negate the effect of the roughness 2 vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_roughness_end", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[7]"); RNA_def_property_ui_text(prop, "Vertex Group Roughness End", "Vertex group to control roughness end."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_roughness_end_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROUGHE)); RNA_def_property_ui_text(prop, "Vertex Group Roughness End Negate", "Negate the effect of the roughness end vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); + RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "vertex_group_size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[8]"); RNA_def_property_ui_text(prop, "Vertex Group Size", "Vertex group to control size."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_size_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_SIZE)); RNA_def_property_ui_text(prop, "Vertex Group Size Negate", "Negate the effect of the size vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_tangent", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[9]"); RNA_def_property_ui_text(prop, "Vertex Group Tangent", "Vertex group to control tangent."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_tangent_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_TAN)); RNA_def_property_ui_text(prop, "Vertex Group Tangent Negate", "Negate the effect of the tangent vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_rotation", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[10]"); RNA_def_property_ui_text(prop, "Vertex Group Rotation", "Vertex group to control rotation."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_rotation_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROT)); RNA_def_property_ui_text(prop, "Vertex Group Rotation Negate", "Negate the effect of the rotation vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_field", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "vgroup[11]"); RNA_def_property_ui_text(prop, "Vertex Group Field", "Vertex group to control field."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "vertex_group_field_negate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_EFFECTOR)); RNA_def_property_ui_text(prop, "Vertex Group Field Negate", "Negate the effect of the field vertex group."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* pointcache */ prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL); @@ -2101,7 +2111,7 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "parent"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Parent", "Use this object's coordinate system instead of global coordinate system."); - RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* hair or cache editing */ prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 727e3ff6a6d..6c951b5a1b7 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -55,7 +55,7 @@ static void rna_Pose_update(bContext *C, PointerRNA *ptr) { // XXX when to use this? ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); - DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); } static char *rna_PoseChannel_path(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index b00119efaf6..5575b170398 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -45,13 +45,6 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = { {PE_BRUSH_CUT, "CUT", 0, "Cut", "Cut hairs."}, {0, NULL, 0, NULL, NULL}}; -static EnumPropertyItem particle_edit_cache_brush_items[] = { - {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush."}, - {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb paths."}, - {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth paths."}, - {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", "Make paths longer or shorter."}, - {0, NULL, 0, NULL, NULL}}; - #ifdef RNA_RUNTIME #include "BKE_context.h" @@ -61,6 +54,13 @@ static EnumPropertyItem particle_edit_cache_brush_items[] = { #include "ED_particle.h" +static EnumPropertyItem particle_edit_cache_brush_items[] = { + {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush."}, + {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb paths."}, + {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth paths."}, + {PE_BRUSH_LENGTH, "LENGTH", 0, "Length", "Make paths longer or shorter."}, + {0, NULL, 0, NULL, NULL}}; + static PointerRNA rna_ParticleEdit_brush_get(PointerRNA *ptr) { ParticleEditSettings *pset= (ParticleEditSettings*)ptr->data; @@ -72,7 +72,6 @@ static PointerRNA rna_ParticleEdit_brush_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_ParticleBrush, brush); } - static PointerRNA rna_ParticleBrush_curve_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_CurveMapping, NULL); @@ -113,11 +112,9 @@ static void rna_ParticleEdit_redo(bContext *C, PointerRNA *ptr) static void rna_ParticleEdit_update(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - if(ob) - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + if(ob) DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *ptr, int *free) diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index d7c70d8b9e9..b3192b110f4 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -52,7 +52,7 @@ static void rna_Smoke_update(bContext *C, PointerRNA *ptr) { - DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); } static void rna_Smoke_dependency_update(bContext *C, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index d6a17526a65..0ac7fa40727 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -375,65 +375,68 @@ static void rna_def_space_image_uv(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "sticky"); RNA_def_property_enum_items(prop, sticky_mode_items); RNA_def_property_ui_text(prop, "Sticky Selection Mode", "Automatically select also UVs sharing the same vertex as the ones being selected."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); /* drawing */ prop= RNA_def_property(srna, "edge_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "dt_uv"); RNA_def_property_enum_items(prop, dt_uv_items); RNA_def_property_ui_text(prop, "Edge Draw Type", "Draw type for drawing UV edges."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "draw_smooth_edges", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SMOOTH_UV); RNA_def_property_ui_text(prop, "Draw Smooth Edges", "Draw UV edges anti-aliased."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "draw_stretch", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_STRETCH); RNA_def_property_ui_text(prop, "Draw Stretch", "Draw faces colored according to the difference in shape between UVs and their 3D coordinates (blue for low distortion, red for high distortion)."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "draw_stretch_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "dt_uvstretch"); RNA_def_property_enum_items(prop, dt_uvstretch_items); RNA_def_property_ui_text(prop, "Draw Stretch Type", "Type of stretch to draw."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "draw_modified_edges", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAWSHADOW); RNA_def_property_ui_text(prop, "Draw Modified Edges", "Draw edges after modifiers are applied."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "draw_other_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_OTHER); RNA_def_property_ui_text(prop, "Draw Other Objects", "Draw other selected objects that share the same image."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "normalized_coordinates", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_COORDFLOATS); RNA_def_property_ui_text(prop, "Normalized Coordinates", "Display UV coordinates from 0.0 to 1.0 rather than in pixels."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); /* todo: move edge and face drawing options here from G.f */ prop= RNA_def_property(srna, "snap_to_pixels", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_PIXELSNAP); RNA_def_property_ui_text(prop, "Snap to Pixels", "Snap UVs to pixel locations while editing."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "constrain_to_image_bounds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_CLIP_UV); RNA_def_property_ui_text(prop, "Constrain to Image Bounds", "Constraint to stay within the image bounds while editing."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "live_unwrap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_LIVE_UNWRAP); RNA_def_property_ui_text(prop, "Live Unwrap", "Continuously unwrap the selected UV island while transforming pinned vertices."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "pivot", 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", "Rotation/Scaling Pivot."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); } static void rna_def_space_outliner(BlenderRNA *brna) @@ -464,12 +467,12 @@ static void rna_def_space_outliner(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "outlinevis"); RNA_def_property_enum_items(prop, display_mode_items); RNA_def_property_ui_text(prop, "Display Mode", "Type of information to display"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_OUTLINER, NULL); prop= RNA_def_property(srna, "show_restriction_columns", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_HIDE_RESTRICTCOLS); RNA_def_property_ui_text(prop, "Show Restriction Columns", "Show colum"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_OUTLINER, NULL); } @@ -486,35 +489,34 @@ static void rna_def_background_image(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "ima"); RNA_def_property_ui_text(prop, "Image", "Image displayed and edited in this space."); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "iuser"); RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xof"); RNA_def_property_ui_text(prop, "X Offset", "Offsets image horizontally from the view center"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yof"); RNA_def_property_ui_text(prop, "Y Offset", "Offsets image vertically from the view center"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Size", "Scaling factor for the background image."); RNA_def_property_range(prop, 0.0, FLT_MAX); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "transparency", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "blend"); RNA_def_property_ui_text(prop, "Transparency", "Amount to blend the image against the background color."); RNA_def_property_range(prop, 0.0, 1.0); - RNA_def_property_update(prop, NC_WINDOW, NULL); - + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); } static void rna_def_space_3dview(BlenderRNA *brna) @@ -553,10 +555,12 @@ static void rna_def_space_3dview(BlenderRNA *brna) prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "camera"); RNA_def_property_ui_text(prop, "Camera", "Active camera used in this view (when unlocked from the scene's active camera)."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "lock_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "ob_centre"); RNA_def_property_ui_text(prop, "Lock Object", "3D View center is locked to this object's position"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "background_image", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bgpic"); @@ -566,136 +570,142 @@ static void rna_def_space_3dview(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "drawtype"); RNA_def_property_enum_items(prop, viewport_shading_items); RNA_def_property_ui_text(prop, "Viewport Shading", "Method to display/shade objects in the 3D View."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "localview", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "localview", 0); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Local View", "Display an isolated sub-set of objects, apart from the scene visibility."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "lens", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "lens"); RNA_def_property_ui_text(prop, "Lens", "Lens angle (mm) in perspective view."); RNA_def_property_range(prop, 1.0f, 250.0f); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "near"); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_text(prop, "Clip Start", "3D View near clipping distance."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "far"); RNA_def_property_range(prop, 1.0f, FLT_MAX); RNA_def_property_ui_text(prop, "Clip End", "3D View far clipping distance."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "grid_spacing", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "grid"); RNA_def_property_ui_text(prop, "Grid Spacing", "The distance between 3D View grid lines."); RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "grid_lines", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gridlines"); RNA_def_property_ui_text(prop, "Grid Lines", "The number of grid lines to display in perspective view."); RNA_def_property_range(prop, 0, 1024); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "grid_subdivisions", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gridsubdiv"); RNA_def_property_ui_text(prop, "Grid Subdivisions", "The number of subdivisions between grid lines."); RNA_def_property_range(prop, 1, 1024); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "display_floor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_FLOOR); RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid in perspective view."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "display_x_axis", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_X); RNA_def_property_ui_text(prop, "Display X Axis", "Show the X axis line in perspective view."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "display_y_axis", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_Y); RNA_def_property_ui_text(prop, "Display Y Axis", "Show the Y axis line in perspective view."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "display_z_axis", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_Z); RNA_def_property_ui_text(prop, "Display Z Axis", "Show the Z axis line in perspective view."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "outline_selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SELECT_OUTLINE); RNA_def_property_ui_text(prop, "Outline Selected", "Show an outline highlight around selected objects in non-wireframe views."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "all_object_centers", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_DRAW_CENTERS); RNA_def_property_ui_text(prop, "All Object Centers", "Show the object center dot for all (selected and unselected) objects."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "relationship_lines", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", V3D_HIDE_HELPLINES); RNA_def_property_ui_text(prop, "Relationship Lines", "Show dashed lines indicating parent or constraint relationships."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "textured_solid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_TEX); RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "display_background_image", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, NULL, "rna_View3D_display_background_image_set"); RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_DISPBGPIC); RNA_def_property_ui_text(prop, "Display Background Image", "Display a reference image behind objects in the 3D View"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); 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_VIEW3D, NULL); prop= RNA_def_property(srna, "manipulator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "twflag", V3D_USE_MANIPULATOR); RNA_def_property_ui_text(prop, "Manipulator", "Use a 3D manipulator widget for controlling transforms."); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "manipulator_translate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "twtype", V3D_MANIP_TRANSLATE); RNA_def_property_ui_text(prop, "Manipulator Translate", "Use the manipulator for movement transformations."); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "manipulator_rotate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "twtype", V3D_MANIP_ROTATE); RNA_def_property_ui_text(prop, "Manipulator Rotate", "Use the manipulator for rotation transformations."); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "manipulator_scale", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "twtype", V3D_MANIP_SCALE); RNA_def_property_ui_text(prop, "Manipulator Scale", "Use the manipulator for scale transformations."); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "transform_orientation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "twmode"); RNA_def_property_enum_items(prop, transform_orientation_items); RNA_def_property_ui_text(prop, "Transform Orientation", "The alignment of manipulator handles."); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, "RegionView3D", "viewlock", RV3D_LOCKED); RNA_def_property_ui_text(prop, "Lock", "Lock View Rotation"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "box_preview", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, "RegionView3D", "viewlock", RV3D_BOXVIEW); RNA_def_property_ui_text(prop, "Box", ""); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "box_clip", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, "RegionView3D", "viewlock", RV3D_BOXCLIP); RNA_def_property_ui_text(prop, "Clip", ""); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); } static void rna_def_space_buttons(BlenderRNA *brna) @@ -730,19 +740,19 @@ static void rna_def_space_buttons(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "mainb"); RNA_def_property_enum_items(prop, buttons_context_items); RNA_def_property_ui_text(prop, "Context", "Type of active data to display and edit."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_PROPERTIES, NULL); prop= RNA_def_property(srna, "align", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "align"); RNA_def_property_enum_items(prop, align_items); RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_align_set", NULL); RNA_def_property_ui_text(prop, "Align", "Arrangement of the panels."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_PROPERTIES, NULL); prop= RNA_def_property(srna, "brush_texture", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SB_BRUSH_TEX); RNA_def_property_ui_text(prop, "Brush Texture", "Show brush textures."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_PROPERTIES, NULL); /* pinned data */ prop= RNA_def_property(srna, "pin_id", PROP_POINTER, PROP_NONE); @@ -750,6 +760,7 @@ static void rna_def_space_buttons(BlenderRNA *brna) RNA_def_property_struct_type(prop, "ID"); RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_SpaceProperties_pin_id_typef"); RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_PROPERTIES, NULL); } static void rna_def_space_image(BlenderRNA *brna) @@ -766,35 +777,35 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceImageEditor_image_set", NULL); RNA_def_property_ui_text(prop, "Image", "Image displayed and edited in this space."); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "iuser"); RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "curves", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "cumap"); RNA_def_property_ui_text(prop, "Curves", "Color curve mapping to use for displaying the image."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "image_pin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "pin", 0); RNA_def_property_ui_text(prop, "Image Pin", "Display current image regardless of object selection."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); /* image draw */ prop= RNA_def_property(srna, "draw_repeated", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_TILE); RNA_def_property_ui_text(prop, "Draw Repeated", "Draw the image repeated outside of the main view."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); prop= RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, dc_all_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_SpaceImageEditor_draw_channels_itemf"); RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the image to draw."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); /* uv */ prop= RNA_def_property(srna, "uv_editor", PROP_POINTER, PROP_NEVER_NULL); @@ -807,7 +818,7 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAWTOOL); RNA_def_property_ui_text(prop, "Image Painting", "Enable image painting mode."); RNA_def_property_ui_icon(prop, ICON_TPAINT_HLT, 0); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_SpaceImageEditor_paint_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_paint_update"); /* grease pencil */ prop= RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); @@ -866,64 +877,69 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "mainb"); RNA_def_property_enum_items(prop, display_mode_items); RNA_def_property_ui_text(prop, "Display Mode", "The view mode to use for displaying sequencer output."); - RNA_def_property_update(prop, ND_SEQUENCER|NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); /* flag's */ prop= RNA_def_property(srna, "draw_frames", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAWFRAMES); RNA_def_property_ui_text(prop, "Draw Frames", "Draw frames rather then seconds."); - RNA_def_property_update(prop, ND_SEQUENCER|NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "transform_markers", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MARKER_TRANS); RNA_def_property_ui_text(prop, "Transform Markers", "Transform markers as well as strips."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "seperate_color_preview", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAW_COLOR_SEPERATED); RNA_def_property_ui_text(prop, "Seperate Colors", "Seperate color channels in preview."); - RNA_def_property_update(prop, ND_SEQUENCER|NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "draw_safe_margin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAW_SAFE_MARGINS); RNA_def_property_ui_text(prop, "Safe Margin", "Draw title safe margins in preview."); - RNA_def_property_update(prop, ND_SEQUENCER|NC_WINDOW, NULL); + 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, ND_SEQUENCER|NC_WINDOW, NULL); + 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"); RNA_def_property_ui_text(prop, "Display Channel", "The channel number shown in the image preview. 0 is the result of all strips combined."); RNA_def_property_range(prop, 0, 32); // MAXSEQ --- todo, move from BKE_sequence.h - RNA_def_property_update(prop, ND_SEQUENCER|NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "draw_overexposed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "zebra"); RNA_def_property_ui_text(prop, "Show Overexposed", "Show overexposed areas with zebra stripes."); RNA_def_property_range(prop, 0, 110); - RNA_def_property_update(prop, ND_SEQUENCER|NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); /* not sure we need rna access to these but adding anyway */ prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xof"); RNA_def_property_ui_text(prop, "X Offset", "Offsets image horizontally from the view center"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yof"); RNA_def_property_ui_text(prop, "Y Offset", "Offsets image horizontally from the view center"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); prop= RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "zoom"); RNA_def_property_ui_text(prop, "Zoom", "Display zoom level"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); } static void rna_def_space_text(BlenderRNA *brna) @@ -940,63 +956,68 @@ static void rna_def_space_text(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Text", "Text displayed and edited in this space."); RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceTextEditor_text_set", NULL); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); /* display */ prop= RNA_def_property(srna, "syntax_highlight", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "showsyntax", 0); RNA_def_property_ui_text(prop, "Syntax Highlight", "Syntax highlight for scripting."); RNA_def_property_ui_icon(prop, ICON_SYNTAX_OFF, 1); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "word_wrap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "wordwrap", 0); RNA_def_property_boolean_funcs(prop, NULL, "rna_SpaceTextEditor_word_wrap_set"); RNA_def_property_ui_text(prop, "Word Wrap", "Wrap words if there is not enough horizontal space."); RNA_def_property_ui_icon(prop, ICON_WORDWRAP_OFF, 1); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "line_numbers", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "showlinenrs", 0); RNA_def_property_ui_text(prop, "Line Numbers", "Show line numbers next to the text."); RNA_def_property_ui_icon(prop, ICON_LINENUMBERS_OFF, 1); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "overwrite", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Overwrite", "Overwrite characters when typing rather than inserting them."); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "live_edit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Live Edit", "Run python while editing."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "tab_width", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "tabnumber"); RNA_def_property_range(prop, 2, 8); RNA_def_property_ui_text(prop, "Tab Width", "Number of spaces to display tabs with."); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "font_size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "lheight"); RNA_def_property_range(prop, 8, 32); RNA_def_property_ui_text(prop, "Font Size", "Font size to use for displaying the text."); - RNA_def_property_update(prop, NC_TEXT|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); /* find */ prop= RNA_def_property(srna, "find_all", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", ST_FIND_ALL); RNA_def_property_ui_text(prop, "Find All", "Search in all text datablocks, instead of only the active one."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "find_wrap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", ST_FIND_WRAP); RNA_def_property_ui_text(prop, "Find Wrap", "Search again from the start of the file when reaching the end."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "find_text", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "findstr"); RNA_def_property_ui_text(prop, "Find Text", "Text to search for with the find tool."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); prop= RNA_def_property(srna, "replace_text", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "replacestr"); RNA_def_property_ui_text(prop, "Replace Text", "Text to replace selected text with using the replace tool."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TEXT, NULL); } static void rna_def_space_dopesheet(BlenderRNA *brna) @@ -1021,25 +1042,30 @@ static void rna_def_space_dopesheet(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, mode_items); RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); /* display */ prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_DRAWTIME); RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, only set with operator RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); prop= RNA_def_property(srna, "show_cframe_indicator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NODRAWCFRANUM); RNA_def_property_ui_text(prop, "Show Frame Number Indicator", "Show frame number beside the current frame indicator line."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); prop= RNA_def_property(srna, "show_sliders", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_SLIDERS); RNA_def_property_ui_text(prop, "Show Sliders", "Show sliders beside F-Curve channels."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); /* editing */ prop= RNA_def_property(srna, "automerge_keyframes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NOTRANSKEYCULL); RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Show handles of Bezier control points."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, NULL); // TODO... autosnap, dopesheet? } @@ -1064,33 +1090,40 @@ static void rna_def_space_graph(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, mode_items); RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); /* display */ prop= RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_DRAWTIME); RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, only set with operator RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); prop= RNA_def_property(srna, "show_cframe_indicator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NODRAWCFRANUM); RNA_def_property_ui_text(prop, "Show Frame Number Indicator", "Show frame number beside the current frame indicator line."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); prop= RNA_def_property(srna, "show_sliders", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SLIDERS); RNA_def_property_ui_text(prop, "Show Sliders", "Show sliders beside F-Curve channels."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); prop= RNA_def_property(srna, "show_handles", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_NOHANDLES); RNA_def_property_ui_text(prop, "Show Handles", "Show handles of Bezier control points."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); prop= RNA_def_property(srna, "only_selected_curves_handles", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SELCUVERTSONLY); RNA_def_property_ui_text(prop, "Only Selected Curve Keyframes", "Only keyframes of selected F-Curves are visible and editable."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); /* editing */ prop= RNA_def_property(srna, "automerge_keyframes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NOTRANSKEYCULL); RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Show handles of Bezier control points."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); // TODO... autosnap, dopesheet? } @@ -1109,14 +1142,17 @@ static void rna_def_space_nla(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", SNLA_DRAWTIME); RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, only set with operator RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NLA, NULL); prop= RNA_def_property(srna, "show_cframe_indicator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NODRAWCFRANUM); RNA_def_property_ui_text(prop, "Show Frame Number Indicator", "Show frame number beside the current frame indicator line."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NLA, NULL); prop= RNA_def_property(srna, "show_strip_curves", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NOSTRIPCURVES); RNA_def_property_ui_text(prop, "Show Control Curves", "Show influence curves on strips."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NLA, NULL); /* editing */ // TODO... autosnap, dopesheet? @@ -1136,43 +1172,44 @@ static void rna_def_space_time(BlenderRNA *brna) prop= RNA_def_property(srna, "play_top_left", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_REGION); RNA_def_property_ui_text(prop, "Top-Left 3D Window", ""); - RNA_def_property_update(prop, 0, "rna_SpaceTime_redraw_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); prop= RNA_def_property(srna, "play_all_3d", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_3D_WIN); RNA_def_property_ui_text(prop, "All 3D Windows", ""); - RNA_def_property_update(prop, 0, "rna_SpaceTime_redraw_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); prop= RNA_def_property(srna, "play_anim", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_ANIM_WIN); RNA_def_property_ui_text(prop, "Animation Windows", ""); - RNA_def_property_update(prop, 0, "rna_SpaceTime_redraw_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); prop= RNA_def_property(srna, "play_buttons", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_BUTS_WIN); RNA_def_property_ui_text(prop, "Properties Windows", ""); - RNA_def_property_update(prop, 0, "rna_SpaceTime_redraw_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); prop= RNA_def_property(srna, "play_image", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_ALL_IMAGE_WIN); RNA_def_property_ui_text(prop, "Image Windows", ""); - RNA_def_property_update(prop, 0, "rna_SpaceTime_redraw_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); prop= RNA_def_property(srna, "play_sequencer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_SEQ); RNA_def_property_ui_text(prop, "Sequencer Windows", ""); - RNA_def_property_update(prop, 0, "rna_SpaceTime_redraw_update"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); /* Other options */ prop= RNA_def_property(srna, "continue_physics", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_CONTINUE_PHYSICS); RNA_def_property_ui_text(prop, "Continue Physics", "During playblack, continue physics simulations regardless of the frame number"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, NULL); prop= RNA_def_property(srna, "only_selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TIME_ONLYACTSEL); RNA_def_property_ui_text(prop, "Only Selected channels", "Show keyframes only from active/selected channels."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, NULL); } static void rna_def_console_line(BlenderRNA *brna) @@ -1182,15 +1219,17 @@ static void rna_def_console_line(BlenderRNA *brna) srna = RNA_def_struct(brna, "ConsoleLine", NULL); RNA_def_struct_ui_text(srna, "Console Input", "Input line for the interactive console."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); prop= RNA_def_property(srna, "line", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_ConsoleLine_line_get", "rna_ConsoleLine_line_length", "rna_ConsoleLine_line_set"); RNA_def_property_ui_text(prop, "Line", "Text in the line."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); prop= RNA_def_property(srna, "current_character", PROP_INT, PROP_NONE); /* copied from text editor */ RNA_def_property_int_sdna(prop, NULL, "cursor"); RNA_def_property_int_funcs(prop, NULL, NULL, "rna_ConsoleLine_cursor_index_range"); - + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); } static EnumPropertyItem console_type_items[] = { @@ -1212,39 +1251,39 @@ static void rna_def_space_console(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "lheight"); RNA_def_property_range(prop, 8, 32); RNA_def_property_ui_text(prop, "Font Size", "Font size to use for displaying the text."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); prop= RNA_def_property(srna, "console_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, console_type_items); RNA_def_property_ui_text(prop, "Type", "Console type."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); /* reporting display */ prop= RNA_def_property(srna, "show_report_debug", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", CONSOLE_RPT_DEBUG); RNA_def_property_ui_text(prop, "Show Debug", "Display debug reporting info."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE_REPORT, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); prop= RNA_def_property(srna, "show_report_info", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", CONSOLE_RPT_INFO); RNA_def_property_ui_text(prop, "Show Info", "Display general information."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE_REPORT, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); prop= RNA_def_property(srna, "show_report_operator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", CONSOLE_RPT_OP); RNA_def_property_ui_text(prop, "Show Operator", "Display the operator log."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE_REPORT, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); prop= RNA_def_property(srna, "show_report_warn", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", CONSOLE_RPT_WARN); RNA_def_property_ui_text(prop, "Show Warn", "Display warnings."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE_REPORT, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); prop= RNA_def_property(srna, "show_report_error", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", CONSOLE_RPT_ERR); RNA_def_property_ui_text(prop, "Show Error", "Display error text."); - RNA_def_property_update(prop, NC_CONSOLE | ND_CONSOLE_REPORT, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); @@ -1292,82 +1331,82 @@ static void rna_def_fileselect_params(BlenderRNA *brna) prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "dir"); RNA_def_property_ui_text(prop, "Directory", "Directory displayed in the file browser."); - RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); prop= RNA_def_property(srna, "file", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "file"); RNA_def_property_ui_text(prop, "File Name", "Active file in the file browser."); - RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); prop= RNA_def_property(srna, "display", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "display"); RNA_def_property_enum_items(prop, file_display_items); RNA_def_property_ui_text(prop, "Display Mode", "Display mode for the file list"); - RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); prop= RNA_def_property(srna, "do_filter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_FILTER); RNA_def_property_ui_text(prop, "Filter Files", "Enable filtering of files."); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "hide_dot", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_HIDE_DOT); RNA_def_property_ui_text(prop, "Hide Dot Files", "Hide hidden dot files."); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST , NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST , NULL); prop= RNA_def_property(srna, "sort", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "sort"); RNA_def_property_enum_items(prop, file_sort_items); RNA_def_property_ui_text(prop, "Sort", ""); - RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); prop= RNA_def_property(srna, "filter_image", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", IMAGEFILE); RNA_def_property_ui_text(prop, "Filter Images", "Show image files."); RNA_def_property_ui_icon(prop, ICON_FILE_IMAGE, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_blender", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", BLENDERFILE); RNA_def_property_ui_text(prop, "Filter Blender", "Show .blend files."); RNA_def_property_ui_icon(prop, ICON_FILE_BLEND, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_movie", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", MOVIEFILE); RNA_def_property_ui_text(prop, "Filter Movies", "Show movie files."); RNA_def_property_ui_icon(prop, ICON_FILE_MOVIE, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_script", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", PYSCRIPTFILE); RNA_def_property_ui_text(prop, "Filter Script", "Show script files."); RNA_def_property_ui_icon(prop, ICON_FILE_SCRIPT, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_font", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", FTFONTFILE); RNA_def_property_ui_text(prop, "Filter Fonts", "Show font files."); RNA_def_property_ui_icon(prop, ICON_FILE_FONT, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_sound", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", SOUNDFILE); RNA_def_property_ui_text(prop, "Filter Sound", "Show sound files."); RNA_def_property_ui_icon(prop, ICON_FILE_SOUND, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_text", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", TEXTFILE); RNA_def_property_ui_text(prop, "Filter Text", "Show text files."); RNA_def_property_ui_icon(prop, ICON_FILE_BLANK, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); prop= RNA_def_property(srna, "filter_folder", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filter", FOLDERFILE); RNA_def_property_ui_text(prop, "Filter Folder", "Show folders."); RNA_def_property_ui_icon(prop, ICON_FILE_FOLDER, 0); - RNA_def_property_update(prop, NC_FILE | ND_FILELIST, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } @@ -1430,13 +1469,13 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "treetype"); RNA_def_property_enum_items(prop, tree_type_items); RNA_def_property_ui_text(prop, "Tree Type", "Node tree type to display and edit."); - RNA_def_property_update(prop, NC_NODE, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL); prop= RNA_def_property(srna, "texture_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "texfrom"); RNA_def_property_enum_items(prop, texture_type_items); RNA_def_property_ui_text(prop, "Texture Type", "Type of data to take texture from."); - RNA_def_property_update(prop, NC_NODE, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL); prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -1454,7 +1493,7 @@ static void rna_def_space_node(BlenderRNA *brna) prop= RNA_def_property(srna, "backdrop", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_BACKDRAW); RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes."); - RNA_def_property_update(prop, NC_NODE, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL); } static void rna_def_space_logic(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index a0716cc7dc7..ffc3f1696fc 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -33,6 +33,7 @@ #include "DNA_space_types.h" #include "DNA_userdef_types.h" +#include "WM_api.h" #include "WM_types.h" #include "BKE_utildefines.h" @@ -41,7 +42,12 @@ #ifdef RNA_RUNTIME -static void rna_userdef_lmb_select_set(struct PointerRNA *ptr,int value) +static void rna_userdef_update(bContext *C, PointerRNA *ptr) +{ + WM_event_add_notifier(C, NC_WINDOW, NULL); +} + +static void rna_userdef_lmb_select_set(PointerRNA *ptr,int value) { UserDef *userdef = (UserDef*)ptr->data; @@ -53,12 +59,12 @@ static void rna_userdef_lmb_select_set(struct PointerRNA *ptr,int value) userdef->flag &= ~USER_LMOUSESELECT; } -static void rna_userdef_rmb_select_set(struct PointerRNA *ptr,int value) +static void rna_userdef_rmb_select_set(PointerRNA *ptr,int value) { rna_userdef_lmb_select_set(ptr, !value); } -static void rna_userdef_emulate_set(struct PointerRNA *ptr,int value) +static void rna_userdef_emulate_set(PointerRNA *ptr,int value) { UserDef *userdef = (UserDef*)ptr->data; @@ -68,7 +74,7 @@ static void rna_userdef_emulate_set(struct PointerRNA *ptr,int value) userdef->flag ^= USER_TWOBUTTONMOUSE; } -static int rna_userdef_autokeymode_get(struct PointerRNA *ptr) +static int rna_userdef_autokeymode_get(PointerRNA *ptr) { UserDef *userdef = (UserDef*)ptr->data; short retval = userdef->autokey_mode; @@ -79,7 +85,7 @@ static int rna_userdef_autokeymode_get(struct PointerRNA *ptr) return retval; } -static void rna_userdef_autokeymode_set(struct PointerRNA *ptr,int value) +static void rna_userdef_autokeymode_set(PointerRNA *ptr,int value) { UserDef *userdef = (UserDef*)ptr->data; @@ -142,38 +148,38 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna) prop= RNA_def_property(srna, "points", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 6, 48); RNA_def_property_ui_text(prop, "Points", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "font_kerning_style", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "kerning"); RNA_def_property_enum_items(prop, font_kerning_style); RNA_def_property_ui_text(prop, "Kerning Style", "Which style to use for font kerning."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shadow", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 5); RNA_def_property_ui_text(prop, "Shadow Size", "Shadow size in pixels (0, 3 and 5 supported)"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shadx", PROP_INT, PROP_NONE); RNA_def_property_range(prop, -10, 10); RNA_def_property_ui_text(prop, "Shadow X Offset", "Shadow offset in pixels"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shady", PROP_INT, PROP_NONE); RNA_def_property_range(prop, -10, 10); RNA_def_property_ui_text(prop, "Shadow Y Offset", "Shadow offset in pixels"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shadowalpha", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Shadow Alpha", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shadowcolor", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Shadow Brightness", "Shadow color in grey value"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_ui_style(BlenderRNA *brna) @@ -195,25 +201,25 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "paneltitle"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Panel Font", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "grouplabel", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "grouplabel"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Group Label Font", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "widgetlabel", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "widgetlabel"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Widget Label Font", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "widget", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "widget"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Widget Font", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } @@ -229,47 +235,47 @@ static void rna_def_userdef_theme_ui_wcol(BlenderRNA *brna) prop= RNA_def_property(srna, "outline", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Outline", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Inner", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner_sel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Inner Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "item", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Item", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "text_sel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Text Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shaded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shaded", 1); RNA_def_property_ui_text(prop, "Shaded", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shadetop", PROP_INT, PROP_NONE); RNA_def_property_range(prop, -100, 100); RNA_def_property_ui_text(prop, "Shade Top", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "shadedown", PROP_INT, PROP_NONE); RNA_def_property_range(prop, -100, 100); RNA_def_property_ui_text(prop, "Shade Down", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna) @@ -284,36 +290,36 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna) prop= RNA_def_property(srna, "inner_anim", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Animated", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner_anim_sel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Animated Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner_key", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Keyframe", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner_key_sel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Keyframe Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner_driven", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Driven", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "inner_driven_sel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Driven Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "blend", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_ui_text(prop, "Blend", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_ui(BlenderRNA *brna) @@ -332,102 +338,102 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "wcol_regular"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Regular Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_tool", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_tool"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Tool Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_radio", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_radio"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Radio Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_text", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_text"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Text Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_option", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_option"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Option Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_toggle"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Toggle Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_num"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Number Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_numslider", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_numslider"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Slider Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_box", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_box"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Box Backdrop Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_menu", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Menu Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_pulldown", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_pulldown"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Pulldown Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_menu_back", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu_back"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Menu Backdrop Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_menu_item", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu_item"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Menu Item Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_scroll"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Scroll Widget Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_list_item", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_list_item"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "List Item Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wcol_state", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_state"); RNA_def_property_struct_type(prop, "ThemeWidgetStateColors"); RNA_def_property_ui_text(prop, "State Colors", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "iconfile"); RNA_def_property_ui_text(prop, "Icon File", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_spaces_main(StructRNA *srna, int spacetype) @@ -438,60 +444,60 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna, int spacetype) prop= RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Back", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "title", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Title", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "text_hi", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Text Highlight", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); /* header */ prop= RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Header", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "header_text", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Header Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Header Text Highlight", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); /* buttons */ if(! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { prop= RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Button Back", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Button Title", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Button Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Button Text Highlight", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } /* list/channels */ @@ -499,22 +505,22 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna, int spacetype) prop= RNA_def_property(srna, "list", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "List Back", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "list_title", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "List Title", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "list_text", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "List Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "list_text_hi", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "List Text Highlight", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } } @@ -525,17 +531,17 @@ static void rna_def_userdef_theme_spaces_vertex(StructRNA *srna) prop= RNA_def_property(srna, "vertex", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Vertex", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "vertex_select", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Vertex Select", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "vertex_size", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, 10); RNA_def_property_ui_text(prop, "Vertex Size", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_spaces_edge(StructRNA *srna) @@ -545,22 +551,22 @@ static void rna_def_userdef_theme_spaces_edge(StructRNA *srna) prop= RNA_def_property(srna, "edge_select", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "edge Select", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "edge_seam", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Edge Seam", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "edge_sharp", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Edge Sharp", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "edge_facesel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Edge UV Face Select", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_spaces_face(StructRNA *srna) @@ -570,22 +576,22 @@ static void rna_def_userdef_theme_spaces_face(StructRNA *srna) prop= RNA_def_property(srna, "face", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Face", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "face_select", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Face Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "face_dot", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Face Dot Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "facedot_size", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, 10); RNA_def_property_ui_text(prop, "Face Dot Size", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) @@ -604,51 +610,51 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Wire", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "lamp", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Lamp", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "object_selected", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "select"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Object Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "object_active", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "active"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Active Object", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "object_grouped", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "group"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Object Grouped", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "object_grouped_active", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "group_active"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Object Grouped Active", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "transform", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Transform", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); rna_def_userdef_theme_spaces_vertex(srna); rna_def_userdef_theme_spaces_edge(srna); @@ -657,28 +663,28 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) prop= RNA_def_property(srna, "editmesh_active", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Active Vert/Edge/Face", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "normal", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Normal", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "bone_solid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Bone Solid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "bone_pose", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Bone Pose", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "current_frame", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) @@ -697,24 +703,24 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Sliders", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "channels_region", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade2"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Channels Region", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); rna_def_userdef_theme_spaces_vertex(srna); @@ -722,46 +728,46 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "handle_vertex", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Handle Vertex", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "handle_vertex_select", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Handle Vertex Select", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "handle_vertex_size", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 255); RNA_def_property_ui_text(prop, "Handle Vertex Size", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "channel_group", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "group"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Channel Group", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "active_channels_group", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "group_active"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Active Channel Group", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "dopesheet_channel", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "ds_channel"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "DopeSheet Channel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "dopesheet_subchannel", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "ds_subchannel"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "DopeSheet Sub-Channel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_file(BlenderRNA *brna) @@ -781,37 +787,37 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "hilite"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Selected File", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "panel"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Tiles", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "scrollbar", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Scrollbar", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "scroll_handle", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade2"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Scroll Handle", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "active_file", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "active"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Active File", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "active_file_text", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "grid"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Active File Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_outliner(BlenderRNA *brna) @@ -871,55 +877,55 @@ static void rna_def_userdef_theme_space_text(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "grid"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Line Numbers Background", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "scroll_bar", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Scroll Bar", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "selected_text", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade2"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Selected Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "cursor", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "hilite"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Cursor", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "syntax_builtin", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxb"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Syntax Builtin", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "syntax_special", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxv"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Syntax Special", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "syntax_comment", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxc"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Syntax Comment", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "syntax_string", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxl"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Syntax String", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "syntax_numbers", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxn"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Syntax Numbers", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_node(BlenderRNA *brna) @@ -939,49 +945,49 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "wire"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Wires", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "wire_select", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "edge_select"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Wire Select", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "selected_text", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade2"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Selected Text", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "node_backdrop", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxl"); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Node Backdrop", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "in_out_node", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxn"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "In/Out Node", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "converter_node", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxv"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Converter Node", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "operator_node", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxb"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Operator Node", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "group_node", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "syntaxc"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Group Node", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) @@ -1000,7 +1006,7 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) prop= RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } @@ -1020,7 +1026,7 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna) prop= RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_time(BlenderRNA *brna) @@ -1039,13 +1045,13 @@ static void rna_def_userdef_theme_space_time(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "current_frame", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_sound(BlenderRNA *brna) @@ -1064,19 +1070,19 @@ static void rna_def_userdef_theme_space_sound(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Sliders", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "current_frame", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_image(BlenderRNA *brna) @@ -1097,7 +1103,7 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna) prop= RNA_def_property(srna, "editmesh_active", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Active Vert/Edge/Face", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_seq(BlenderRNA *brna) @@ -1114,79 +1120,79 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Window Sliders", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "movie_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "movie"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Movie Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "image_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "image"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Image Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "scene_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "scene"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Scene Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "audio_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "audio"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Audio Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "effect_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "effect"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Effect Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "plugin_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "plugin"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Plugin Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "transition_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "transition"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Transition Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "meta_strip", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "meta"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Meta Strip", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "current_frame", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "keyframe", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "vertex_select"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Keyframe", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "draw_action", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "bone_pose"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Draw Action", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_action(BlenderRNA *brna) @@ -1205,73 +1211,73 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "value_sliders", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "face"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Value Sliders", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "view_sliders", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "View Sliders", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "channels", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade2"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Channels", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "channels_selected", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "hilite"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Channels Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "channel_group", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "group"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Channel Group", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "active_channels_group", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "group_active"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Active Channel Group", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "long_key", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "strip"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Long Key", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "long_key_selected", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "strip_select"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Long Key Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "current_frame", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "dopesheet_channel", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "ds_channel"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "DopeSheet Channel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "dopesheet_subchannel", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "ds_subchannel"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "DopeSheet Sub-Channel", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_nla(BlenderRNA *brna) @@ -1290,43 +1296,43 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna) prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "view_sliders", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "View Sliders", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "bars", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shade2"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Bars", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "bars_selected", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "hilite"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Bars Selected", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR); 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, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "strips_selected", PROP_FLOAT, PROP_COLOR); 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, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "current_frame", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "cframe"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_colorset(BlenderRNA *brna) @@ -1342,23 +1348,23 @@ static void rna_def_userdef_theme_colorset(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "solid"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Normal", "Color used for the surface of bones."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "selected", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "select"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Selected", "Color used for selected bones."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "active", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Active", "Color used for active bones."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "colored_constraints", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TH_WIRECOLOR_CONSTCOLS); RNA_def_property_ui_text(prop, "Colored Constraints", "Allow the use of colors indicating constraints/keyed status."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_themes(BlenderRNA *brna) @@ -1547,27 +1553,27 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop= RNA_def_property(srna, "display_object_info", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DRAWVIEWINFO); RNA_def_property_ui_text(prop, "Display Object Info", "Display objects name and frame number in 3d view."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "global_scene", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_SCENEGLOBAL); RNA_def_property_ui_text(prop, "Global Scene", "Forces the current Scene to be displayed in all Screens."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "use_large_cursors", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "curssize", 0); RNA_def_property_ui_text(prop, "Large Cursors", "Use large mouse cursors when available."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "show_view_name", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_SHOW_VIEWPORTNAME); RNA_def_property_ui_text(prop, "Show View Name", "Show the name of the view's direction in each 3D View."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "show_playback_fps", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_SHOW_FPS); RNA_def_property_ui_text(prop, "Show Playback FPS", "Show the frames per second screen refresh rate, while animation is played back."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); /* menus */ prop= RNA_def_property(srna, "open_mouse_over", PROP_BOOLEAN, PROP_NONE); @@ -1662,19 +1668,19 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop= RNA_def_property(srna, "show_mini_axis", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_SHOW_ROTVIEWICON); RNA_def_property_ui_text(prop, "Show Mini Axis", "Show a small rotating 3D axis in the bottom left corner of the 3D View."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "mini_axis_size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rvisize"); RNA_def_property_range(prop, 10, 64); RNA_def_property_ui_text(prop, "Mini Axis Size", "The axis icon's size."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "mini_axis_brightness", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rvibright"); RNA_def_property_range(prop, 0, 10); RNA_def_property_ui_text(prop, "Mini Axis Brightness", "The brightness of the icon."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); /* middle mouse button */ prop= RNA_def_property(srna, "middle_mouse_rotate", PROP_BOOLEAN, PROP_NONE); @@ -1708,19 +1714,19 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop= RNA_def_property(srna, "use_manipulator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "tw_flag", 1); RNA_def_property_ui_text(prop, "Manipulator", "Use 3d transform manipulator."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "manipulator_size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "tw_size"); RNA_def_property_range(prop, 2, 40); RNA_def_property_ui_text(prop, "Manipulator Size", "Diameter of widget, in 10 pixel units."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "manipulator_handle_size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "tw_handlesize"); RNA_def_property_range(prop, 2, 40); RNA_def_property_ui_text(prop, "Manipulator Handle Size", "Size of widget handles as percentage of widget radius."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "manipulator_hotspot", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "tw_hotspot"); @@ -1731,7 +1737,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "obcenter_dia"); RNA_def_property_range(prop, 4, 10); RNA_def_property_ui_text(prop, "Object Center Size", "Diameter in Pixels for Object/Lamp center display."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "ndof_pan_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ndof_pan"); @@ -1951,13 +1957,13 @@ static void rna_def_userdef_language(BlenderRNA *brna) prop= RNA_def_property(srna, "international_fonts", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE); RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "dpi"); RNA_def_property_range(prop, 48, 128); RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "scrollback"); @@ -1969,27 +1975,27 @@ static void rna_def_userdef_language(BlenderRNA *brna) prop= RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, language_items); RNA_def_property_ui_text(prop, "Language", "Language use for translation."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "translate_tooltips", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS); RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate Tooltips."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "translate_buttons", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_BUTTONS); RNA_def_property_ui_text(prop, "Translate Buttons", "Translate button labels."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "translate_toolbox", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_MENUS); RNA_def_property_ui_text(prop, "Translate Toolbox", "Translate toolbox menu."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT); RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts."); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_system(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index eaed0100386..148af2c28e9 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -419,6 +419,7 @@ static void rna_def_windowmanager(BlenderRNA *brna) srna= RNA_def_struct(brna, "WindowManager", "ID"); RNA_def_struct_ui_text(srna, "Window Manager", "Window manager datablock defining open windows and other user interface data."); + RNA_def_struct_clear_flag(srna, STRUCT_ID_REFCOUNT); RNA_def_struct_sdna(srna, "wmWindowManager"); prop= RNA_def_property(srna, "operators", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 5687cb565d1..806f5409b0a 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -130,11 +130,10 @@ typedef struct wmNotifier { #define NC_BRUSH (11<<24) #define NC_TEXT (12<<24) #define NC_WORLD (13<<24) -#define NC_FILE (14<<24) -#define NC_ANIMATION (15<<24) -#define NC_CONSOLE (16<<24) -#define NC_NODE (17<<24) -#define NC_INFO (18<<24) +#define NC_ANIMATION (14<<24) +#define NC_SPACE (15<<24) +#define NC_NODE (15<<24) +#define NC_GEOM (16<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 @@ -172,13 +171,12 @@ typedef struct wmNotifier { #define ND_POSE (18<<16) #define ND_BONE_ACTIVE (19<<16) #define ND_BONE_SELECT (20<<16) -#define ND_GEOM_SELECT (21<<16) -#define ND_DRAW (22<<16) -#define ND_MODIFIER (23<<16) -#define ND_KEYS (24<<16) -#define ND_GEOM_DATA (25<<16) -#define ND_CONSTRAINT (26<<16) -#define ND_PARTICLE (27<<16) +#define ND_DRAW (21<<16) +#define ND_MODIFIER (22<<16) /* modifiers edited */ +#define ND_KEYS (23<<16) +#define ND_CONSTRAINT (24<<16) /* constraints edited */ +#define ND_PARTICLE_DATA (25<<16) /* particles edited */ +#define ND_PARTICLE_SELECT (26<<16) /* particles selecting change */ /* NC_MATERIAL Material */ #define ND_SHADING (30<<16) @@ -193,10 +191,6 @@ typedef struct wmNotifier { #define ND_CURSOR (50<<16) #define ND_DISPLAY (51<<16) - /* NC_FILE Filebrowser */ -#define ND_PARAMS (60<<16) -#define ND_FILELIST (61<<16) - /* NC_ANIMATION Animato */ #define ND_KEYFRAME_SELECT (70<<16) #define ND_KEYFRAME_EDIT (71<<16) @@ -207,9 +201,28 @@ typedef struct wmNotifier { #define ND_NLA_EDIT (76<<16) #define ND_NLA_ACTCHANGE (77<<16) - /* console */ -#define ND_CONSOLE (78<<16) /* general redraw */ -#define ND_CONSOLE_REPORT (79<<16) /* update for reports, could spesify type */ + /* NC_GEOM Geometry */ + /* Mesh, Curve, MetaBall, Armature, .. */ +#define ND_SELECT (80<<16) +#define ND_DATA (81<<16) + + /* NC_SPACE */ +#define ND_SPACE_CONSOLE (1<<16) /* general redraw */ +#define ND_SPACE_CONSOLE_REPORT (2<<16) /* update for reports, could specify type */ +#define ND_SPACE_INFO (2<<16) +#define ND_SPACE_IMAGE (3<<16) +#define ND_SPACE_FILE_PARAMS (4<<16) +#define ND_SPACE_FILE_LIST (5<<16) +#define ND_SPACE_NODE (6<<16) +#define ND_SPACE_OUTLINER (7<<16) +#define ND_SPACE_VIEW3D (8<<16) +#define ND_SPACE_PROPERTIES (9<<16) +#define ND_SPACE_TEXT (10<<16) +#define ND_SPACE_TIME (11<<16) +#define ND_SPACE_GRAPH (12<<16) +#define ND_SPACE_DOPESHEET (13<<16) +#define ND_SPACE_NLA (14<<16) +#define ND_SPACE_SEQUENCER (15<<16) /* subtype, 256 entries too */ #define NOTE_SUBTYPE 0x0000FF00 diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index fecd5c20a15..38cf39c2081 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -108,7 +108,7 @@ void wm_operator_register(bContext *C, wmOperator *op) MEM_freeN(buf); /* so the console is redrawn */ - WM_event_add_notifier(C, NC_CONSOLE|ND_CONSOLE_REPORT, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 717c2d25261..c2c90f055b0 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -177,9 +177,9 @@ void wm_event_do_notifiers(bContext *C) do_anim= 1; } } - if(note->category == NC_SCENE || note->category == NC_OBJECT) { + if(ELEM3(note->category, NC_SCENE, NC_OBJECT, NC_GEOM)) { ED_info_stats_clear(CTX_data_scene(C)); - WM_event_add_notifier(C, NC_INFO, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO, NULL); } } if(do_anim) { -- cgit v1.2.3 From 670296dabe9c4c5444c696af54e1b4ef07a8e60b Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 4 Sep 2009 20:57:50 +0000 Subject: fix for relative path to build bplayer with cmake in windows (ffmpeg still needs to be off) --- source/blenderplayer/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 30a1c08ebc9..76a1a405698 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -44,7 +44,7 @@ ADD_CUSTOM_COMMAND( ) IF(WIN32) - ADD_EXECUTABLE(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../source/icons/winblender.rc) + ADD_EXECUTABLE(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../icons/winblender.rc) ELSE(WIN32) ADD_EXECUTABLE(blenderplayer ${CMAKE_CURRENT_BINARY_DIR}/dna.c) ENDIF(WIN32) -- cgit v1.2.3 From 5dd9f7635afeda66ca4475288b1eb7ad621486f4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Sep 2009 21:02:43 +0000 Subject: 2.5 Make local and make single user are back for ID template. Internally these calls got unified, id_make_local and id_copy are now used to do these operations for all types that support it. Also reveals that for some ID types the implementation is still missing. Further, some small changes: * unlink_text is now in blenkernel. * copy_group was implemented. * ID template now has an open operator again. * fix preview to not change material reference count, even if temporary it shows up with threaded preview. * id_unlink unifies unlink for text, object and group. --- source/blender/blenkernel/BKE_armature.h | 1 - source/blender/blenkernel/BKE_group.h | 1 + source/blender/blenkernel/BKE_library.h | 3 + source/blender/blenkernel/BKE_sca.h | 1 - source/blender/blenkernel/BKE_scene.h | 2 - source/blender/blenkernel/BKE_text.h | 2 + source/blender/blenkernel/intern/group.c | 10 + source/blender/blenkernel/intern/library.c | 225 ++++++++++++++++++++- source/blender/blenkernel/intern/sca.c | 24 --- source/blender/blenkernel/intern/scene.c | 11 - source/blender/blenkernel/intern/text.c | 93 ++++++++- source/blender/editors/gpencil/gpencil_buttons.c | 2 +- source/blender/editors/include/UI_interface.h | 2 +- .../editors/interface/interface_templates.c | 112 ++++++++-- source/blender/editors/object/object_edit.c | 4 +- source/blender/editors/preview/previewrender.c | 10 +- source/blender/editors/space_nla/nla_buttons.c | 2 +- source/blender/editors/space_text/text_intern.h | 2 - source/blender/editors/space_text/text_ops.c | 44 +--- source/blender/makesrna/intern/rna_ui_api.c | 1 + 20 files changed, 436 insertions(+), 116 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 0595134f5c9..1cbb2331782 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -74,7 +74,6 @@ struct bArmature *add_armature(char *name); struct bArmature *get_armature(struct Object *ob); void free_boneChildren(struct Bone *bone); void free_bones (struct bArmature *arm); -void unlink_armature(struct bArmature *arm); void free_armature(struct bArmature *arm); void make_local_armature(struct bArmature *arm); struct bArmature *copy_armature(struct bArmature *arm); diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h index 35084aabadf..b66ddf13527 100644 --- a/source/blender/blenkernel/BKE_group.h +++ b/source/blender/blenkernel/BKE_group.h @@ -41,6 +41,7 @@ void free_group_object(struct GroupObject *go); void free_group(struct Group *group); void unlink_group(struct Group *group); struct Group *add_group(char *name); +struct Group *copy_group(struct Group *group); void add_to_group(struct Group *group, struct Object *ob); int rem_from_group(struct Group *group, struct Object *ob); struct Group *find_group(struct Object *ob, struct Group *group); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 4e7db115168..54722dac910 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -46,6 +46,9 @@ void *copy_libblock(void *rt); void id_lib_extern(struct ID *id); void id_us_plus(struct ID *id); void id_us_min(struct ID *id); +int id_make_local(struct ID *id, int test); +int id_copy(struct ID *id, struct ID **newid, int test); +int id_unlink(struct ID *id, int test); int check_for_dupid(struct ListBase *lb, struct ID *id, char *name); int new_id(struct ListBase *lb, struct ID *id, const char *name); diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h index 22c4f39148a..1b8e61f136f 100644 --- a/source/blender/blenkernel/BKE_sca.h +++ b/source/blender/blenkernel/BKE_sca.h @@ -47,7 +47,6 @@ void unlink_actuators(struct ListBase *lb); void free_actuator(struct bActuator *act); void free_actuators(struct ListBase *lb); -void free_text_controllers(struct Text *txt); void free_sensor(struct bSensor *sens); void free_sensors(struct ListBase *lb); struct bSensor *copy_sensor(struct bSensor *sens); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 12a13a2b50c..686fc265de0 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -84,7 +84,5 @@ int get_render_child_particle_number(struct RenderData *r, int num); int get_render_shadow_samples(struct RenderData *r, int samples); float get_render_aosss_error(struct RenderData *r, float error); -void free_dome_warp_text(struct Text *txt); - #endif diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index d288c0b6516..bd14053d121 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -35,6 +35,7 @@ extern "C" { #endif +struct Main; struct Text; struct TextLine; struct SpaceText; @@ -46,6 +47,7 @@ struct Text* add_empty_text (char *name); int reopen_text (struct Text *text); struct Text* add_text (char *file, const char *relpath); struct Text* copy_text (struct Text *ta); +void unlink_text (struct Main *bmain, struct Text *text); char* txt_to_buf (struct Text *text); void txt_clean_text (struct Text *text); diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 6fffbd794ef..6bb47bc0f0f 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -142,6 +142,16 @@ Group *add_group(char *name) return group; } +Group *copy_group(Group *group) +{ + Group *groupn; + + groupn= MEM_dupallocN(group); + BLI_duplicatelist(&groupn->gobject, &group->gobject); + + return groupn; +} + /* external */ void add_to_group(Group *group, Object *ob) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 3c8bf9200f8..f15552ab40c 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -119,6 +119,13 @@ #define MAX_IDPUP 60 /* was 24 */ +/* GS reads the memory pointed at in a specific ordering. + only use this definition, makes little and big endian systems + work fine, in conjunction with MAKE_ID */ + +/* from blendef: */ +#define GS(a) (*((short *)(a))) + /* ************* general ************************ */ void id_lib_extern(ID *id) @@ -148,6 +155,217 @@ void id_us_min(ID *id) id->us--; } +int id_make_local(ID *id, int test) +{ + if(id->flag & LIB_INDIRECT) + return 0; + + switch(GS(id->name)) { + case ID_SCE: + return 0; /* not implemented */ + case ID_LI: + return 0; /* can't be linked */ + case ID_OB: + if(!test) make_local_object((Object*)id); + return 1; + case ID_ME: + if(!test) { + make_local_mesh((Mesh*)id); + make_local_key(((Mesh*)id)->key); + } + return 1; + case ID_CU: + if(!test) { + make_local_curve((Curve*)id); + make_local_key(((Curve*)id)->key); + } + return 1; + case ID_MB: + if(!test) make_local_mball((MetaBall*)id); + return 1; + case ID_MA: + if(!test) make_local_material((Material*)id); + return 1; + case ID_TE: + if(!test) make_local_texture((Tex*)id); + return 1; + case ID_IM: + return 0; /* not implemented */ + case ID_WV: + return 0; /* deprecated */ + case ID_LT: + if(!test) make_local_lattice((Lattice*)id); + return 1; + case ID_LA: + if(!test) make_local_lamp((Lamp*)id); + return 1; + case ID_CA: + if(!test) make_local_camera((Camera*)id); + return 1; + case ID_IP: + return 0; /* deprecated */ + case ID_KE: + if(!test) make_local_key((Key*)id); + return 1; + case ID_WO: + if(!test) make_local_world((World*)id); + return 1; + case ID_SCR: + return 0; /* can't be linked */ + case ID_VF: + return 0; /* not implemented */ + case ID_TXT: + return 0; /* not implemented */ + case ID_SCRIPT: + return 0; /* deprecated */ + case ID_SO: + return 0; /* not implemented */ + case ID_GR: + return 0; /* not implemented */ + case ID_AR: + if(!test) make_local_armature((bArmature*)id); + return 1; + case ID_AC: + if(!test) make_local_action((bAction*)id); + return 1; + case ID_NT: + return 0; /* not implemented */ + case ID_BR: + if(!test) make_local_brush((Brush*)id); + return 1; + case ID_PA: + if(!test) make_local_particlesettings((ParticleSettings*)id); + return 1; + case ID_WM: + return 0; /* can't be linked */ + case ID_GD: + return 0; /* not implemented */ + } + + return 0; +} + +int id_copy(ID *id, ID **newid, int test) +{ + if(!test) *newid= NULL; + + /* conventions: + * - make shallow copy, only this ID block + * - id.us of the new ID is set to 1 */ + switch(GS(id->name)) { + case ID_SCE: + return 0; /* can't be copied from here */ + case ID_LI: + return 0; /* can't be copied from here */ + case ID_OB: + if(!test) *newid= (ID*)copy_object((Object*)id); + return 1; + case ID_ME: + if(!test) *newid= (ID*)copy_mesh((Mesh*)id); + return 1; + case ID_CU: + if(!test) *newid= (ID*)copy_curve((Curve*)id); + return 1; + case ID_MB: + if(!test) *newid= (ID*)copy_mball((MetaBall*)id); + return 1; + case ID_MA: + if(!test) *newid= (ID*)copy_material((Material*)id); + return 1; + case ID_TE: + if(!test) *newid= (ID*)copy_texture((Tex*)id); + return 1; + case ID_IM: + return 0; /* not implemented */ + case ID_WV: + return 0; /* deprecated */ + case ID_LT: + if(!test) *newid= (ID*)copy_lattice((Lattice*)id); + return 1; + case ID_LA: + if(!test) *newid= (ID*)copy_lamp((Lamp*)id); + return 1; + case ID_CA: + if(!test) *newid= (ID*)copy_camera((Camera*)id); + return 1; + case ID_IP: + return 0; /* deprecated */ + case ID_KE: + if(!test) *newid= (ID*)copy_key((Key*)id); + return 1; + case ID_WO: + if(!test) *newid= (ID*)copy_world((World*)id); + return 1; + case ID_SCR: + return 0; /* can't be copied from here */ + case ID_VF: + return 0; /* not implemented */ + case ID_TXT: + if(!test) *newid= (ID*)copy_text((Text*)id); + return 1; + case ID_SCRIPT: + return 0; /* deprecated */ + case ID_SO: + return 0; /* not implemented */ + case ID_GR: + if(!test) *newid= (ID*)copy_group((Group*)id); + return 1; + case ID_AR: + if(!test) *newid= (ID*)copy_armature((bArmature*)id); + return 1; + case ID_AC: + if(!test) *newid= (ID*)copy_action((bAction*)id); + return 1; + case ID_NT: + if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id, 0); + return 1; + case ID_BR: + if(!test) *newid= (ID*)copy_brush((Brush*)id); + return 1; + case ID_PA: + if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id); + return 1; + case ID_WM: + return 0; /* can't be copied from here */ + case ID_GD: + return 0; /* not implemented */ + } + + return 0; +} + +int id_unlink(ID *id, int test) +{ + Main *mainlib= G.main; + ListBase *lb; + + switch(GS(id->name)) { + case ID_TXT: + if(test) return 1; + unlink_text(mainlib, (Text*)id); + break; + case ID_GR: + if(test) return 1; + unlink_group((Group*)id); + break; + case ID_OB: + if(test) return 1; + unlink_object(NULL, (Object*)id); + break; + } + + if(id->us == 0) { + if(test) return 1; + + lb= wich_libbase(mainlib, GS(id->name)); + free_libblock(lb, id); + + return 1; + } + + return 0; +} + ListBase *wich_libbase(Main *mainlib, short type) { switch( type ) { @@ -409,13 +627,6 @@ void *alloc_libblock(ListBase *lb, short type, const char *name) return id; } -/* GS reads the memory pointed at in a specific ordering. - only use this definition, makes little and big endian systems - work fine, in conjunction with MAKE_ID */ - -/* from blendef: */ -#define GS(a) (*((short *)(a))) - /* by spec, animdata is first item after ID */ /* we still read ->adt itself, to ensure compiler warns when it doesnt exist */ static void id_copy_animdata(ID *id) diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index e4d73208c64..de2118af202 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -52,30 +52,6 @@ #include "BKE_blender.h" #include "BKE_sca.h" -//#include "wm_event_types.h" - -void free_text_controllers(Text *txt) -{ - Object *ob; - bController *cont; - - ob= G.main->object.first; - while(ob) { - cont= ob->controllers.first; - while(cont) { - if(cont->type==CONT_PYTHON) { - bPythonCont *pc; - - pc= cont->data; - if(pc->text==txt) pc->text= NULL; - } - cont= cont->next; - } - ob= ob->id.next; - } -} - - /* ******************* SENSORS ************************ */ void free_sensor(bSensor *sens) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 10f6a8cf47c..6f9ed3e0978 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -860,14 +860,3 @@ float get_render_aosss_error(RenderData *r, float error) return error; } -void free_dome_warp_text(struct Text *txt) -{ - Scene *scene; - - scene = G.main->scene.first; - while(scene) { - if (scene->r.dometext == txt) - scene->r.dometext = NULL; - scene = scene->id.next; - } -} diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 8e3d59bbc58..dac426de4eb 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -37,14 +37,22 @@ #include "BLI_blenlib.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_controller_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "DNA_text_types.h" -#include "BKE_utildefines.h" -#include "BKE_text.h" -#include "BKE_library.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_text.h" +#include "BKE_utildefines.h" #ifndef DISABLE_PYTHON #include "BPY_extern.h" @@ -451,6 +459,85 @@ Text *copy_text(Text *ta) return tan; } +void unlink_text(Main *bmain, Text *text) +{ + bScreen *scr; + ScrArea *area; + SpaceLink *sl; + Scene *scene; + Object *ob; + bController *cont; + bConstraint *con; + short update; + + /* dome */ + for(scene=bmain->scene.first; scene; scene=scene->id.next) + if(scene->r.dometext == text) + scene->r.dometext = NULL; + + for(ob=bmain->object.first; ob; ob=ob->id.next) { + /* game controllers */ + for(cont=ob->controllers.first; cont; cont=cont->next) { + if(cont->type==CONT_PYTHON) { + bPythonCont *pc; + + pc= cont->data; + if(pc->text==text) pc->text= NULL; + } + } + + /* pyconstraints */ + update = 0; + + if(ob->type==OB_ARMATURE && ob->pose) { + bPoseChannel *pchan; + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + for(con = pchan->constraints.first; con; con=con->next) { + if(con->type==CONSTRAINT_TYPE_PYTHON) { + bPythonConstraint *data = con->data; + if (data->text==text) data->text = NULL; + update = 1; + + } + } + } + } + + for(con = ob->constraints.first; con; con=con->next) { + if(con->type==CONSTRAINT_TYPE_PYTHON) { + bPythonConstraint *data = con->data; + if (data->text==text) data->text = NULL; + update = 1; + } + } + + if(update) + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + } + + /* pynodes */ + // XXX nodeDynamicUnlinkText(&text->id); + + /* text space */ + 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_TEXT) { + SpaceText *st= (SpaceText*) sl; + + if(st->text==text) { + st->text= NULL; + st->top= 0; + } + } + } + } + } + + text->id.us= 0; +} + + /*****************************/ /* Editing utility functions */ /*****************************/ diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 0d7cd263245..1036b4ccd8f 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -238,7 +238,7 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi col= uiLayoutColumn(layout, 0); /* current Grease Pencil block */ // TODO: show some info about who owns this? - uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", "GPENCIL_OT_data_unlink"); + uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); /* add new layer button - can be used even when no data, since it can add a new block too */ uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add"); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 0cb6964b39e..e2338078a8a 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -633,7 +633,7 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout); /* templates */ void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus); void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, - char *newop, char *unlinkop); + char *newop, char *openop, char *unlinkop); uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr); uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr); void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d253948e2e8..2b7d6f383bf 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -157,7 +157,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) { TemplateID *template= (TemplateID*)arg_litem; PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop); - ID *id= idptr.data; + ID *id= idptr.data, *newid; int event= GET_INT_FROM_POINTER(arg_event); switch(event) { @@ -185,28 +185,48 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) } else return; break; -#if 0 - case UI_ID_ALONE: - if(!id || id->us < 1) - return; - break; case UI_ID_LOCAL: - if(!id || id->us < 1) - return; + if(id) { + if(id_make_local(id, 0)) { + /* reassign to get get proper updates/notifiers */ + idptr= RNA_property_pointer_get(&template->ptr, template->prop); + RNA_property_pointer_set(&template->ptr, template->prop, idptr); + RNA_property_update(C, &template->ptr, template->prop); + } + } break; + case UI_ID_ALONE: + if(id) { + /* make copy */ + if(id_copy(id, &newid, 0) && newid) { + /* us is 1 by convention, but RNA_property_pointer_set + will also incremement it, so set it to zero */ + newid->us= 0; + + /* assign copy */ + RNA_id_pointer_create(newid, &idptr); + RNA_property_pointer_set(&template->ptr, template->prop, idptr); + RNA_property_update(C, &template->ptr, template->prop); + } + } + break; +#if 0 case UI_ID_AUTO_NAME: break; #endif } } -static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop) +static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop) { uiBut *but; PointerRNA idptr; ListBase *lb; + ID *id, *idfrom; idptr= RNA_property_pointer_get(&template->ptr, template->prop); + id= idptr.data; + idfrom= template->ptr.id.data; lb= template->idlb; uiBlockBeginAlign(block); @@ -221,33 +241,86 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc but->flag|= UI_HAS_ICON; but->flag|= UI_ICON_LEFT; } + + if((idfrom && idfrom->lib)) + uiButSetFlag(but, UI_BUT_DISABLED); } /* text button with name */ - if(idptr.data) { + if(id) { char name[64]; - //text_idbutton(idptr.data, name); + //text_idbutton(id, name); name[0]= '\0'; but= uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME)); + + if(id->lib) { + if(id->flag & LIB_INDIRECT) { + but= uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0, + "Indirect library datablock, cannot change."); + uiButSetFlag(but, UI_BUT_DISABLED); + } + else { + but= uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0, + "Direct linked library datablock, click to make local."); + if(!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib)) + uiButSetFlag(but, UI_BUT_DISABLED); + } + + uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL)); + } + + if(id->us > 1) { + char str[32]; + + sprintf(str, "%d", id->us); + + if(id->us<10) + but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy."); + else + but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X+10,UI_UNIT_Y, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy."); + + uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE)); + if(!id_copy(id, NULL, 1 /* test only */) || (idfrom && idfrom->lib)) + uiButSetFlag(but, UI_BUT_DISABLED); + } } if(flag & UI_ID_ADD_NEW) { - int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6; + int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6; if(newop) { - but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL); + but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } else { - but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } + + if((idfrom && idfrom->lib)) + uiButSetFlag(but, UI_BUT_DISABLED); + } + + if(flag & UI_ID_OPEN) { + int w= id?UI_UNIT_X: (flag & UI_ID_ADD_NEW)? UI_UNIT_X*3: UI_UNIT_X*6; + + if(openop) { + but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_REGION_WIN, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL); + uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); + } + else { + but= uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); + } + + if((idfrom && idfrom->lib)) + uiButSetFlag(but, UI_BUT_DISABLED); } /* delete button */ - if(idptr.data && (flag & UI_ID_DELETE)) { + if(id && (flag & UI_ID_DELETE)) { if(unlinkop) { but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); } @@ -255,12 +328,15 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE)); } + + if((idfrom && idfrom->lib)) + uiButSetFlag(but, UI_BUT_DISABLED); } uiBlockEndAlign(block); } -void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *unlinkop) +void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop) { TemplateID *template; uiBlock *block; @@ -286,6 +362,8 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname if(newop) flag |= UI_ID_ADD_NEW; + if(openop) + flag |= UI_ID_OPEN; type= RNA_property_pointer_type(ptr, prop); template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type)); @@ -293,7 +371,7 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname if(template->idlb) { uiLayoutRow(layout, 1); block= uiLayoutGetBlock(layout); - template_ID(C, block, template, type, flag, newop, unlinkop); + template_ID(C, block, template, type, flag, newop, openop, unlinkop); } MEM_freeN(template); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 53882ad8424..0ae987f2308 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2951,10 +2951,10 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) else if (ob->id.lib) { uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); uiLayout *layout= uiPupMenuLayout(pup); - PointerRNA props_ptr = {0}; + PointerRNA props_ptr; /* create operator menu item with relevant properties filled in */ - props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); RNA_string_set(&props_ptr, "object", ob->id.name+2); /* present the menu and be done... */ diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index d17391811bb..714ebcef0fb 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -349,8 +349,14 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre for(base= sce->base.first; base; base= base->next) { if(base->object->id.name[2]=='p') { - if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL)) - assign_material(base->object, mat, base->object->actcol); + if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL)) { + /* don't use assign_material, it changed mat->id.us, which shows in the UI */ + Material ***matar= give_matarar(base->object); + int actcol= MAX2(base->object->actcol > 0, 1) - 1; + + if(matar && actcol < base->object->totcol) + (*matar)[actcol]= mat; + } } } } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index bbf1358a37c..8532d78aa06 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -211,7 +211,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa) /* Active Action Properties ------------------------------------- */ /* action */ row= uiLayoutRow(layout, 1); - uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators + uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators /* extrapolation */ row= uiLayoutRow(layout, 1); diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index cb425274fc0..4847f2f0741 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -83,8 +83,6 @@ typedef struct FlattenString { int flatten_string(struct SpaceText *st, FlattenString *fs, char *in); void flatten_string_free(FlattenString *fs); -void unlink_text(struct Text *text); - int wrap_width(struct SpaceText *st, struct ARegion *ar); void wrap_offset(struct SpaceText *st, struct ARegion *ar, struct TextLine *linein, int cursin, int *offl, int *offc); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index a8ef72e3273..7751355a14d 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -273,48 +273,9 @@ void TEXT_OT_reload(wmOperatorType *ot) /******************* delete operator *********************/ -static void text_unlink(Main *bmain, Text *text) -{ - bScreen *scr; - ScrArea *area; - SpaceLink *sl; - - /* XXX this ifdef is in fact dangerous, if python is - * disabled it will leave invalid pointers in files! */ - -#ifndef DISABLE_PYTHON - // XXX BPY_free_pyconstraint_links(text); - // XXX free_text_controllers(text); - // XXX free_dome_warp_text(text); - - /* equivalently for pynodes: */ - if(0) // XXX nodeDynamicUnlinkText ((ID*)text)) - ; // XXX notifier: allqueue(REDRAWNODE, 0); -#endif - - 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_TEXT) { - SpaceText *st= (SpaceText*) sl; - - if(st->text==text) { - st->text= NULL; - st->top= 0; - - if(st==area->spacedata.first) - ED_area_tag_redraw(area); - } - } - } - } - } - - free_libblock(&bmain->text, text); -} - static int unlink_exec(bContext *C, wmOperator *op) { + Main *bmain= CTX_data_main(C); SpaceText *st= CTX_wm_space_text(C); Text *text= CTX_data_edit_text(C); @@ -330,7 +291,8 @@ static int unlink_exec(bContext *C, wmOperator *op) } } - text_unlink(CTX_data_main(C), text); + unlink_text(bmain, text); + free_libblock(&bmain->text, text); WM_event_add_notifier(C, NC_TEXT|NA_REMOVED, text); return OPERATOR_FINISHED; diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 7fc2d75a708..20948843f8a 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -247,6 +247,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_function_flag(func, FUNC_USE_CONTEXT); api_ui_item_rna_common(func); RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block."); + RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block."); RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block."); func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); -- cgit v1.2.3 From a49020b2414005cc7aef06749ff1f9c1c7e75a3f Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 4 Sep 2009 21:21:12 +0000 Subject: Strip input is not used for sound strips in 2.5. --- release/ui/space_sequencer.py | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index bef48f5ebdb..daae4a83ec4 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -416,7 +416,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel): if not strip: return False - return strip.type in ('MOVIE', 'IMAGE', 'SOUND') + return strip.type in ('MOVIE', 'IMAGE') def draw(self, context): layout = self.layout @@ -440,27 +440,26 @@ class SEQUENCER_PT_input(SequencerButtonsPanel): col = split.column() col.itemR(elem, "filename", text="") # strip.elements[0] could be a fallback - if strip.type != 'SOUND': - layout.itemR(strip, "use_translation", text="Image Offset:") - if strip.transform: - col = layout.column(align=True) - col.active = strip.use_translation - col.itemR(strip.transform, "offset_x", text="X") - col.itemR(strip.transform, "offset_y", text="Y") - - layout.itemR(strip, "use_crop", text="Image Crop:") - if strip.crop: - col = layout.column(align=True) - col.active = strip.use_crop - col.itemR(strip.crop, "top") - col.itemR(strip.crop, "left") - col.itemR(strip.crop, "bottom") - col.itemR(strip.crop, "right") - + layout.itemR(strip, "use_translation", text="Image Offset:") + if strip.transform: + col = layout.column(align=True) + col.active = strip.use_translation + col.itemR(strip.transform, "offset_x", text="X") + col.itemR(strip.transform, "offset_y", text="Y") + + layout.itemR(strip, "use_crop", text="Image Crop:") + if strip.crop: col = layout.column(align=True) - col.itemL(text="Trim Duration:") - col.itemR(strip, "animation_start_offset", text="Start") - col.itemR(strip, "animation_end_offset", text="End") + col.active = strip.use_crop + col.itemR(strip.crop, "top") + col.itemR(strip.crop, "left") + col.itemR(strip.crop, "bottom") + col.itemR(strip.crop, "right") + + col = layout.column(align=True) + col.itemL(text="Trim Duration:") + col.itemR(strip, "animation_start_offset", text="Start") + col.itemR(strip, "animation_end_offset", text="End") class SEQUENCER_PT_sound(SequencerButtonsPanel): __label__ = "Sound" -- cgit v1.2.3 From d3e35f096811dced93cc213392db43b7cb426a29 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Sep 2009 21:34:17 +0000 Subject: 2.5: increase subversion to init new sound userpref variables. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 10 ---------- source/blender/editors/interface/resources.c | 12 ++++++++++++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 42ee11587a7..d60737d62fe 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0231d841c2b..5a628192af6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9686,16 +9686,6 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->user->uifonts.first= bfd->user->uifonts.last= NULL; bfd->user->uistyles.first= bfd->user->uistyles.last= NULL; - // AUD_XXX that's bad because if the user has saved No Audio, it changes to OpenAL always - if(bfd->user->audiochannels == 0) - bfd->user->audiochannels = 2; - if(bfd->user->audiodevice == 0) - bfd->user->audiodevice = 2; - if(bfd->user->audioformat == 0) - bfd->user->audioformat = 0x24; - if(bfd->user->audiorate == 0) - bfd->user->audiorate = 44100; - bhead = blo_nextbhead(fd, bhead); /* read all attached data */ diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 8aaede7515a..c54e09b2b40 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1245,6 +1245,18 @@ void init_userdef_do_versions(void) SETCOLF(btheme->tuserpref.back, 0.45, 0.45, 0.45, 1.0); } } + + if (G.main->versionfile < 250 || (G.main->versionfile == 250 && G.main->subversionfile < 3)) { + /* new audio system */ + if(U.audiochannels == 0) + U.audiochannels = 2; + if(U.audiodevice == 0) + U.audiodevice = 2; + if(U.audioformat == 0) + U.audioformat = 0x24; + if(U.audiorate == 0) + U.audiorate = 44100; + } /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { -- cgit v1.2.3 From eaa079b9b7e8650411da90419fce73ffe3334f55 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Sep 2009 22:07:33 +0000 Subject: - buttons to move logic bricks up and down when they are collapsed - made actuators and sensors 300 wide (like they were in 2.4x, someone must have changed that). The layout didnt take advantage of the extra width and it looked odd. --- source/blender/editors/space_logic/logic_window.c | 65 ++++++++++++++++------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 47ba197daa0..3040d73bda9 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -74,11 +74,6 @@ #include "logic_intern.h" - -/* XXX */ -static int pupmenu() {return 1;} -/* XXX */ - #define MAX_RENDER_PASS 100 #define B_REDR 1 #define B_IDNAME 2 @@ -202,7 +197,7 @@ static void make_unique_prop_names_cb(bContext *C, void *strv, void *redraw_view } -static void sca_move_sensor(bContext *C, void *datav, void *data2_unused) +static void sca_move_sensor(bContext *C, void *datav, void *move_up) { Scene *scene= CTX_data_scene(C); bSensor *sens_to_delete= datav; @@ -210,7 +205,8 @@ static void sca_move_sensor(bContext *C, void *datav, void *data2_unused) Base *base; bSensor *sens, *tmp; - val= pupmenu("Move up%x1|Move down %x2"); + // val= pupmenu("Move up%x1|Move down %x2"); + val = move_up ? 1:2; if(val>0) { /* now find out which object has this ... */ @@ -253,7 +249,7 @@ static void sca_move_sensor(bContext *C, void *datav, void *data2_unused) } } -static void sca_move_controller(bContext *C, void *datav, void *data2_unused) +static void sca_move_controller(bContext *C, void *datav, void *move_up) { Scene *scene= CTX_data_scene(C); bController *controller_to_del= datav; @@ -261,7 +257,8 @@ static void sca_move_controller(bContext *C, void *datav, void *data2_unused) Base *base; bController *cont, *tmp; - val= pupmenu("Move up%x1|Move down %x2"); + //val= pupmenu("Move up%x1|Move down %x2"); + val = move_up ? 1:2; if(val>0) { /* now find out which object has this ... */ @@ -307,7 +304,7 @@ static void sca_move_controller(bContext *C, void *datav, void *data2_unused) } } -static void sca_move_actuator(bContext *C, void *datav, void *data2_unused) +static void sca_move_actuator(bContext *C, void *datav, void *move_up) { Scene *scene= CTX_data_scene(C); bActuator *actuator_to_move= datav; @@ -315,7 +312,8 @@ static void sca_move_actuator(bContext *C, void *datav, void *data2_unused) Base *base; bActuator *act, *tmp; - val= pupmenu("Move up%x1|Move down %x2"); + //val= pupmenu("Move up%x1|Move down %x2"); + val = move_up ? 1:2; if(val>0) { /* now find out which object has this ... */ @@ -981,6 +979,7 @@ static void draw_default_sensor_header(bSensor *sens, uiBut *but; /* Pulsing and frequency */ + uiBlockBeginAlign(block); uiDefIconButBitS(block, TOG, SENS_PULSE_REPEAT, 1, ICON_DOTSUP, (short)(x + 10 + 0. * (w-20)), (short)(y - 21), (short)(0.1 * (w-20)), 19, &sens->pulse, 0.0, 0.0, 0, 0, @@ -994,8 +993,10 @@ static void draw_default_sensor_header(bSensor *sens, (short)(x + 10 + 0.2 * (w-20)), (short)(y - 21), (short)(0.275 * (w-20)), 19, &sens->freq, 0.0, 10000.0, 0, 0, "Delay between repeated pulses (in logic tics, 0 = no delay)"); + uiBlockEndAlign(block); /* value or shift? */ + uiBlockBeginAlign(block); but= uiDefButS(block, TOG, 1, "Level", (short)(x + 10 + 0.5 * (w-20)), (short)(y - 21), (short)(0.20 * (w-20)), 19, &sens->level, 0.0, 0.0, 0, 0, @@ -1006,6 +1007,7 @@ static void draw_default_sensor_header(bSensor *sens, &sens->tap, 0.0, 0.0, 0, 0, "Trigger controllers only for an instant, even while the sensor remains true"); uiButSetFunc(but, verify_logicbutton_func, sens, &(sens->tap)); + uiBlockEndAlign(block); uiDefButS(block, TOG, 1, "Inv", (short)(x + 10 + 0.85 * (w-20)), (short)(y - 21), (short)(0.15 * (w-20)), 19, @@ -3020,7 +3022,7 @@ void logic_buttons(bContext *C, ARegion *ar) /* start with the controller because we need to know which one is visible */ /* ******************************* */ - xco= 500; yco= 170; width= 300; + xco= 400; yco= 170; width= 300; uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, UI_UNIT_Y, ""); @@ -3129,9 +3131,17 @@ void logic_buttons(bContext *C, ARegion *ar) cpack(0x999999); glRecti(xco+22, yco, xco+width-22,yco+19); but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller type"); - uiButSetFunc(but, sca_move_controller, cont, NULL); + //uiButSetFunc(but, sca_move_controller, cont, NULL); but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller name"); - uiButSetFunc(but, sca_move_controller, cont, NULL); + //uiButSetFunc(but, sca_move_controller, cont, NULL); + + uiBlockBeginAlign(block); + but= uiDefIconBut(block, BUT, B_REDR, VICON_MOVE_UP, (short)(xco+width-(110+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick up"); + uiButSetFunc(but, sca_move_controller, cont, (void *)TRUE); + but= uiDefIconBut(block, BUT, B_REDR, VICON_MOVE_DOWN, (short)(xco+width-(88+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick down"); + uiButSetFunc(but, sca_move_controller, cont, (void *)FALSE); + uiBlockEndAlign(block); + ycoo= yco; } @@ -3152,7 +3162,7 @@ void logic_buttons(bContext *C, ARegion *ar) } /* ******************************* */ - xco= 10; yco= 170; width= 400; + xco= 10; yco= 170; width= 300; uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, UI_UNIT_Y, ""); @@ -3213,9 +3223,16 @@ void logic_buttons(bContext *C, ARegion *ar) set_col_sensor(sens->type, 1); glRecti(xco+22, yco, xco+width-22,yco+19); but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 80, UI_UNIT_Y, sens, 0, 0, 0, 0, ""); - uiButSetFunc(but, sca_move_sensor, sens, NULL); + //uiButSetFunc(but, sca_move_sensor, sens, NULL); but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, 31, 0, 0, ""); - uiButSetFunc(but, sca_move_sensor, sens, NULL); + //uiButSetFunc(but, sca_move_sensor, sens, NULL); + + uiBlockBeginAlign(block); + but= uiDefIconBut(block, BUT, B_REDR, VICON_MOVE_UP, (short)(xco+width-(66+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick up"); + uiButSetFunc(but, sca_move_sensor, sens, (void *)TRUE); + but= uiDefIconBut(block, BUT, B_REDR, VICON_MOVE_DOWN, (short)(xco+width-(44+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick down"); + uiButSetFunc(but, sca_move_sensor, sens, (void *)FALSE); + uiBlockEndAlign(block); } but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, ""); @@ -3230,7 +3247,7 @@ void logic_buttons(bContext *C, ARegion *ar) } /* ******************************* */ - xco= 900; yco= 170; width= 400; + xco= 800; yco= 170; width= 300; uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, UI_UNIT_Y, ""); @@ -3286,9 +3303,17 @@ void logic_buttons(bContext *C, ARegion *ar) set_col_actuator(act->type, 1); glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19)); but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator type"); - uiButSetFunc(but, sca_move_actuator, act, NULL); + // uiButSetFunc(but, sca_move_actuator, act, NULL); but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator name"); - uiButSetFunc(but, sca_move_actuator, act, NULL); + // uiButSetFunc(but, sca_move_actuator, act, NULL); + + uiBlockBeginAlign(block); + but= uiDefIconBut(block, BUT, B_REDR, VICON_MOVE_UP, (short)(xco+width-(66+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick up"); + uiButSetFunc(but, sca_move_actuator, act, (void *)TRUE); + but= uiDefIconBut(block, BUT, B_REDR, VICON_MOVE_DOWN, (short)(xco+width-(44+5)), yco, 22, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Move this logic brick down"); + uiButSetFunc(but, sca_move_actuator, act, (void *)FALSE); + uiBlockEndAlign(block); + ycoo= yco; } -- cgit v1.2.3 From ec5a8c010c8100a1709786f81d5b9b501383287a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Sep 2009 22:50:15 +0000 Subject: 2.5 - Animation Tweaks * Sequencer data is now animateable. Was missing a 'path' setting. For now, sequencer data is animated under scene, since SequenceEditor is not an ID block. * Fixed some buggy insert-keyframe code. --- source/blender/editors/animation/keyframing.c | 18 +++++------------- source/blender/makesrna/intern/rna_sequence.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index d731ec6f148..7135f8802bc 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -292,14 +292,8 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag) } } else if ((flag & INSERTKEY_REPLACE) == 0) { - /* add new - if we're not restricted to replacing keyframes only */ - BezTriple *newb; - - /* allocate a new array only if we have to */ - if ((flag & INSERTKEY_FASTR) == 0) - newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple"); - else - newb= fcu->bezt; + /* insert new - if we're not restricted to replacing keyframes only */ + BezTriple *newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple"); /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */ if (i > 0) @@ -313,11 +307,9 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag) memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple)); /* replace (+ free) old with new, only if necessary to do so */ - if ((flag & INSERTKEY_FASTR) == 0) { - MEM_freeN(fcu->bezt); - fcu->bezt= newb; - } - + MEM_freeN(fcu->bezt); + fcu->bezt= newb; + fcu->totvert++; } } diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index 5d275f7a87c..9f016f73694 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -221,6 +221,16 @@ static StructRNA* rna_Sequence_refine(struct PointerRNA *ptr) } } +static char *rna_Sequence_path(PointerRNA *ptr) +{ + Sequence *seq= (Sequence*)ptr->data; + + /* sequencer data comes from scene... + * TODO: would be nice to make SequenceEditor data a datablock of its own (for shorter paths) + */ + return BLI_sprintfN("sequence_editor.sequences[\"%s\"]", seq->name+2); +} + static PointerRNA rna_SequenceEdtior_meta_stack_get(CollectionPropertyIterator *iter) { ListBaseIterator *internal= iter->internal; @@ -393,6 +403,7 @@ static void rna_def_sequence(BlenderRNA *brna) srna = RNA_def_struct(brna, "Sequence", NULL); RNA_def_struct_ui_text(srna, "Sequence", "Sequence strip in the sequence editor."); RNA_def_struct_refine_func(srna, "rna_Sequence_refine"); + RNA_def_struct_path_func(srna, "rna_Sequence_path"); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_Sequence_name_get", "rna_Sequence_name_length", "rna_Sequence_name_set"); -- cgit v1.2.3 From f09d6054100a17cc6129d035cf3634394f5e9377 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Fri, 4 Sep 2009 23:06:15 +0000 Subject: Some particles cleanup & fixes: - Some big refresh issues with softbody & cloth point cache usage should now be fixed. - Removed sticky objects from particles (better stuff will come back when I get to updating reactor particles). - Some initial easy memory efficiency cleanup for ParticleData struct. The ultimate goal is to get particles less memory hungry -> more particles possible in single scene. - Wrong path timing clamping caused hair particles to seem disappeared when changing between normal<->hair particles. - "Calculate to current frame" in cache buttons baked instead of the intended function. - Boids particle data is now a bit better organized. --- release/ui/buttons_particle.py | 1 - source/blender/blenkernel/BKE_particle.h | 4 + source/blender/blenkernel/intern/boids.c | 198 ++++++----- source/blender/blenkernel/intern/cloth.c | 27 +- source/blender/blenkernel/intern/modifier.c | 6 +- source/blender/blenkernel/intern/object.c | 51 +-- source/blender/blenkernel/intern/particle.c | 140 ++++---- source/blender/blenkernel/intern/particle_system.c | 377 ++++++++++----------- source/blender/blenkernel/intern/pointcache.c | 10 +- source/blender/blenkernel/intern/softbody.c | 40 ++- source/blender/blenloader/intern/readfile.c | 9 - source/blender/blenloader/intern/writefile.c | 2 +- source/blender/editors/object/object_edit.c | 3 + source/blender/editors/physics/ed_pointcache.c | 2 +- source/blender/editors/physics/editparticle.c | 61 ++-- source/blender/editors/space_view3d/drawobject.c | 11 +- source/blender/makesdna/DNA_particle_types.h | 45 +-- source/blender/makesrna/intern/rna_particle.c | 42 +-- .../blender/render/intern/source/convertblender.c | 6 +- 19 files changed, 509 insertions(+), 526 deletions(-) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index 0b18b7c2072..f3339049962 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -396,7 +396,6 @@ class PARTICLE_PT_physics(ParticleButtonsPanel): if part.physics_type=='NEWTON': sub.itemR(part, "size_deflect") sub.itemR(part, "die_on_collision") - sub.itemR(part, "sticky") elif part.physics_type=='KEYED' or part.physics_type=='BOIDS': if part.physics_type=='BOIDS': layout.itemL(text="Relations:") diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index e24114cd219..15896477a6a 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -59,6 +59,9 @@ struct SurfaceModifierData; struct BVHTreeRay; struct BVHTreeRayHit; +#define PARTICLE_P ParticleData *pa; int p +#define LOOP_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) + typedef struct ParticleEffectorCache { struct ParticleEffectorCache *next, *prev; struct Object *ob; @@ -207,6 +210,7 @@ void free_child_path_cache(struct ParticleSystem *psys); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); void free_hair(struct ParticleSystem *psys, int softbody); void free_keyed_keys(struct ParticleSystem *psys); +void psys_free_particles(struct ParticleSystem *psys); void psys_free(struct Object * ob, struct ParticleSystem * psys); void psys_free_children(struct ParticleSystem *psys); diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 5c62e434cb6..18f065b59d9 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -74,6 +74,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, BoidSettings *boids = bbd->part->boids; ParticleEffectorCache *ec; Object *priority_ob = NULL; + BoidParticle *bpa = pa->boid; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0); float priority = 0.0f, len = 0.0f; @@ -81,7 +82,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, /* first find out goal/predator with highest priority */ /* if rule->ob specified use it */ - if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != pa->stick_ob)) { + if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) { PartDeflect *pd = gabr->ob->pd; float vec_to_part[3]; @@ -104,7 +105,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, PartDeflect *pd = eob->pd; /* skip current object */ - if(rule->type == eBoidRuleType_Goal && eob == pa->stick_ob) + if(rule->type == eBoidRuleType_Goal && eob == bpa->ground) continue; if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) { @@ -169,10 +170,10 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, VECCOPY(bbd->goal_nor, nor); } } - else if(rule->type == eBoidRuleType_Avoid && pa->boid->mode == eBoidMode_Climbing && + else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing && priority > 2.0f * gabr->fear_factor) { /* detach from surface and try to fly away from danger */ - VECCOPY(vec_to_part, pa->r_ve); + VECCOPY(vec_to_part, bpa->gravity); VecMulf(vec_to_part, -1.0f); } @@ -205,6 +206,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * KDTreeNearest *ptn = NULL; ParticleEffectorCache *ec; ParticleTarget *pt; + BoidParticle *bpa = pa->boid; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float co1[3], vel1[3], co2[3], vel2[3]; float len, t, inp, t_min = 2.0f; @@ -231,7 +233,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * Object *eob = ec->ob; /* don't check with current ground object */ - if(eob == pa->stick_ob) + if(eob == bpa->ground) continue; col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) ); @@ -558,18 +560,19 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va } static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa) { + BoidParticle *bpa = pa->boid; BoidRuleAverageSpeed *asbr = (BoidRuleAverageSpeed*)rule; float vec[3] = {0.0f, 0.0f, 0.0f}; if(asbr->wander > 0.0f) { /* abuse pa->r_ave for wandering */ - pa->r_ave[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); - pa->r_ave[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); - pa->r_ave[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); + bpa->wander[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); + bpa->wander[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); + bpa->wander[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); - Normalize(pa->r_ave); + Normalize(bpa->wander); - VECCOPY(vec, pa->r_ave); + VECCOPY(vec, bpa->wander); QuatMulVecf(pa->prev_state.rot, vec); @@ -615,6 +618,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti ParticleTarget *pt; ParticleData *epars; ParticleData *enemy_pa = NULL; + BoidParticle *bpa; /* friends & enemies */ float closest_enemy[3] = {0.0f,0.0f,0.0f}; float closest_dist = fbr->distance + 1.0f; @@ -624,8 +628,10 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti /* calculate own group strength */ int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn); - for(n=0; npsys->particles[ptn[n].index].boid->health; + for(n=0; npsys->particles[ptn[n].index].boid; + health += bpa->data.health; + } f_strength += bbd->part->boids->strength * health; @@ -642,7 +648,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti health = 0.0f; for(n=0; nhealth; + bpa = epars[ptn[n].index].boid; + health += bpa->data.health; if(n==0 && pt->mode==PTARGET_MODE_ENEMY && ptn[n].dist < closest_dist) { VECCOPY(closest_enemy, ptn[n].co); @@ -674,7 +681,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti /* must face enemy to fight */ if(Inpf(pa->prev_state.ave, enemy_dir)>0.5f) { - enemy_pa->boid->health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy); + bpa = enemy_pa->boid; + bpa->data.health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy); } } else { @@ -683,7 +691,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti } /* check if boid doesn't want to fight */ - if(pa->boid->health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) { + bpa = pa->boid; + if(bpa->data.health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) { /* decide to flee */ if(closest_dist < fbr->flee_distance * fbr->distance) { VecMulf(bbd->wanted_co, -1.0f); @@ -721,18 +730,20 @@ static boid_rule_cb boid_rules[] = { static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *pa) { - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) { - val->max_speed = boids->land_max_speed * pa->boid->health/boids->health; + BoidParticle *bpa = pa->boid; + + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { + val->max_speed = boids->land_max_speed * bpa->data.health/boids->health; val->max_acc = boids->land_max_acc * val->max_speed; - val->max_ave = boids->land_max_ave * M_PI * pa->boid->health/boids->health; + val->max_ave = boids->land_max_ave * M_PI * bpa->data.health/boids->health; val->min_speed = 0.0f; /* no minimum speed on land */ val->personal_space = boids->land_personal_space; - val->jump_speed = boids->land_jump_speed * pa->boid->health/boids->health; + val->jump_speed = boids->land_jump_speed * bpa->data.health/boids->health; } else { - val->max_speed = boids->air_max_speed * pa->boid->health/boids->health; + val->max_speed = boids->air_max_speed * bpa->data.health/boids->health; val->max_acc = boids->air_max_acc * val->max_speed; - val->max_ave = boids->air_max_ave * M_PI * pa->boid->health/boids->health; + val->max_ave = boids->air_max_ave * M_PI * bpa->data.health/boids->health; val->min_speed = boids->air_min_speed * boids->air_max_speed; val->personal_space = boids->air_personal_space; val->jump_speed = 0.0f; /* no jumping in air */ @@ -740,11 +751,13 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData * } static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *ground_co, float *ground_nor) { - if(pa->boid->mode == eBoidMode_Climbing) { + BoidParticle *bpa = pa->boid; + + if(bpa->data.mode == eBoidMode_Climbing) { SurfaceModifierData *surmd = NULL; float x[3], v[3]; - surmd = (SurfaceModifierData *)modifiers_findByType ( pa->stick_ob, eModifierType_Surface ); + surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface ); /* take surface velocity into account */ effector_find_co(bbd->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL); @@ -753,7 +766,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro /* get actual position on surface */ effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL); - return pa->stick_ob; + return bpa->ground; } else { float zvec[3] = {0.0f, 0.0f, 2000.0f}; @@ -803,13 +816,15 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro } static int boid_rule_applies(ParticleData *pa, BoidSettings *boids, BoidRule *rule) { + BoidParticle *bpa = pa->boid; + if(rule==NULL) return 0; - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND) + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND) return 1; - if(pa->boid->mode==eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR) + if(bpa->data.mode==eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR) return 1; return 0; @@ -835,12 +850,13 @@ void boids_precalc_rules(ParticleSettings *part, float cfra) } static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, float *surface_nor) { + BoidParticle *bpa = pa->boid; float nor[3], vel[3]; VECCOPY(nor, surface_nor); - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, pa->r_ve, surface_nor, -1.0); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, bpa->gravity, surface_nor, -1.0); + Normalize(bpa->gravity); /* raise boid it's size from surface */ VecMulf(nor, pa->size * boids->height); @@ -877,16 +893,17 @@ static int apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val, } static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa) { BoidState *state = boids->states.first; + BoidParticle *bpa = pa->boid; for(; state; state=state->next) { - if(state->id==pa->boid->state_id) + if(state->id==bpa->data.state_id) return state; } /* for some reason particle isn't at a valid state */ state = boids->states.first; if(state) - pa->boid->state_id = state->id; + bpa->data.state_id = state->id; return state; } @@ -902,9 +919,11 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) BoidSettings *boids = bbd->part->boids; BoidValues val; BoidState *state = get_boid_state(boids, pa); + BoidParticle *bpa = pa->boid; + int rand; //BoidCondition *cond; - if(pa->boid->health <= 0.0f) { + if(bpa->data.health <= 0.0f) { pa->alive = PARS_DYING; return; } @@ -922,7 +941,9 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f; /* create random seed for every particle & frame */ - BLI_srandom(bbd->psys->seed + p + (int)bbd->cfra + (int)(1000*pa->r_rot[0])); + BLI_srandom(bbd->psys->seed + p); + rand = BLI_rand(); + BLI_srandom((int)bbd->cfra + rand); set_boid_values(&val, bbd->part->boids, pa); @@ -939,7 +960,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) case eBoidRulesetType_Random: { /* use random rule for each particle (allways same for same particle though) */ - rule = BLI_findlink(&state->rules, (int)(1000.0f * pa->r_rot[1]) % BLI_countlist(&state->rules)); + rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules)); apply_boid_rule(bbd, rule, &val, pa, -1.0); } @@ -969,7 +990,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) } /* decide on jumping & liftoff */ - if(pa->boid->mode == eBoidMode_OnLand) { + if(bpa->data.mode == eBoidMode_OnLand) { /* fuzziness makes boids capable of misjudgement */ float mul = 1.0 + state->rule_fuzziness; @@ -983,7 +1004,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) Normalize2(cvel); if(Inp2f(cvel, dir) > 0.95 / mul) - pa->boid->mode = eBoidMode_Liftoff; + bpa->data.mode = eBoidMode_Liftoff; } else if(val.jump_speed > 0.0f) { float jump_v[3]; @@ -1036,7 +1057,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) if(jump) { VECCOPY(pa->prev_state.vel, jump_v); - pa->boid->mode = eBoidMode_Falling; + bpa->data.mode = eBoidMode_Falling; } } } @@ -1045,6 +1066,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) void boid_body(BoidBrainData *bbd, ParticleData *pa) { BoidSettings *boids = bbd->part->boids; + BoidParticle *bpa = pa->boid; BoidValues val; float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3]; float dvec[3], bvec[3]; @@ -1066,10 +1088,10 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) pa_mass*=pa->size; /* if boids can't fly they fall to the ground */ - if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f) - pa->boid->mode = eBoidMode_Falling; + if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f) + bpa->data.mode = eBoidMode_Falling; - if(pa->boid->mode == eBoidMode_Falling) { + if(bpa->data.mode == eBoidMode_Falling) { /* Falling boids are only effected by gravity. */ acc[2] = bbd->part->acc[2]; } @@ -1079,14 +1101,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) float level = landing_level + 1.0f; float new_vel[3]; - if(pa->boid->mode == eBoidMode_Liftoff) { - pa->boid->mode = eBoidMode_InAir; - pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor); + if(bpa->data.mode == eBoidMode_Liftoff) { + bpa->data.mode = eBoidMode_InAir; + bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); } - else if(pa->boid->mode == eBoidMode_InAir && boids->options & BOID_ALLOW_LAND) { + else if(bpa->data.mode == eBoidMode_InAir && boids->options & BOID_ALLOW_LAND) { /* auto-leveling & landing if close to ground */ - pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor); + bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); /* level = how many particle sizes above ground */ level = (pa->prev_state.co[2] - ground_co[2])/(2.0f * pa->size) - 0.5; @@ -1097,7 +1119,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) if(level < 1.0f) { bbd->wanted_co[0] = bbd->wanted_co[1] = bbd->wanted_co[2] = 0.0f; bbd->wanted_speed = 0.0f; - pa->boid->mode = eBoidMode_Falling; + bpa->data.mode = eBoidMode_Falling; } else if(level < landing_level) { bbd->wanted_speed *= (level - 1.0f)/landing_level; @@ -1188,7 +1210,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* account for effectors */ do_effectors(p, pa, &pa->state, bbd->scene, bbd->ob, bbd->psys, pa->state.co, force, tvel, bbd->dfra, bbd->cfra); - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) { + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { float length = Normalize(force); length = MAX2(0.0f, length - boids->land_stick_force); @@ -1199,8 +1221,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) VecAddf(acc, acc, force); /* store smoothed acceleration for nice banking etc. */ - VECADDFAC(pa->boid->acc, pa->boid->acc, acc, dtime); - VecMulf(pa->boid->acc, 1.0f / (1.0f + dtime)); + VECADDFAC(bpa->data.acc, bpa->data.acc, acc, dtime); + VecMulf(bpa->data.acc, 1.0f / (1.0f + dtime)); /* integrate new location & velocity */ @@ -1218,32 +1240,32 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime); - if(pa->boid->mode != eBoidMode_InAir) - pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor); + if(bpa->data.mode != eBoidMode_InAir) + bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); /* change modes, constrain movement & keep track of down vector */ - switch(pa->boid->mode) { + switch(bpa->data.mode) { case eBoidMode_InAir: { float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f}; /* don't take forward acceleration into account (better banking) */ - if(Inpf(pa->boid->acc, pa->state.vel) > 0.0f) { - Projf(dvec, pa->boid->acc, pa->state.vel); - VecSubf(dvec, pa->boid->acc, dvec); + if(Inpf(bpa->data.acc, pa->state.vel) > 0.0f) { + Projf(dvec, bpa->data.acc, pa->state.vel); + VecSubf(dvec, bpa->data.acc, dvec); } else { - VECCOPY(dvec, pa->boid->acc); + VECCOPY(dvec, bpa->data.acc); } - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, grav, dvec, -boids->banking); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, grav, dvec, -boids->banking); + Normalize(bpa->gravity); /* stick boid on goal when close enough */ if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) { - pa->boid->mode = eBoidMode_Climbing; - pa->stick_ob = bbd->goal_ob; + bpa->data.mode = eBoidMode_Climbing; + bpa->ground = bbd->goal_ob; boid_find_ground(bbd, pa, ground_co, ground_nor); boid_climb(boids, pa, ground_co, ground_nor); } @@ -1251,7 +1273,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) else if(boids->options & BOID_ALLOW_LAND && pa->state.co[2] <= ground_co[2] + pa->size * boids->height) { pa->state.co[2] = ground_co[2] + pa->size * boids->height; pa->state.vel[2] = 0.0f; - pa->boid->mode = eBoidMode_OnLand; + bpa->data.mode = eBoidMode_OnLand; } break; } @@ -1259,15 +1281,15 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f}; - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, pa->r_ve, grav, dtime); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, bpa->gravity, grav, dtime); + Normalize(bpa->gravity); if(boids->options & BOID_ALLOW_LAND) { /* stick boid on goal when close enough */ if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) { - pa->boid->mode = eBoidMode_Climbing; - pa->stick_ob = bbd->goal_ob; + bpa->data.mode = eBoidMode_Climbing; + bpa->ground = bbd->goal_ob; boid_find_ground(bbd, pa, ground_co, ground_nor); boid_climb(boids, pa, ground_co, ground_nor); } @@ -1275,14 +1297,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) else if(pa->state.co[2] <= ground_co[2] + 1.01 * pa->size * boids->height){ pa->state.co[2] = ground_co[2] + pa->size * boids->height; pa->state.vel[2] = 0.0f; - pa->boid->mode = eBoidMode_OnLand; + bpa->data.mode = eBoidMode_OnLand; } /* if we're falling, can fly and want to go upwards lets fly */ else if(boids->options & BOID_ALLOW_FLIGHT && bbd->wanted_co[2] > 0.0f) - pa->boid->mode = eBoidMode_InAir; + bpa->data.mode = eBoidMode_InAir; } else - pa->boid->mode = eBoidMode_InAir; + bpa->data.mode = eBoidMode_InAir; break; } case eBoidMode_Climbing: @@ -1308,14 +1330,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { /* stick boid on goal when close enough */ if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) { - pa->boid->mode = eBoidMode_Climbing; - pa->stick_ob = bbd->goal_ob; + bpa->data.mode = eBoidMode_Climbing; + bpa->ground = bbd->goal_ob; boid_find_ground(bbd, pa, ground_co, ground_nor); boid_climb(boids, pa, ground_co, ground_nor); } /* ground is too far away so boid falls */ else if(pa->state.co[2]-ground_co[2] > 1.1 * pa->size * boids->height) - pa->boid->mode = eBoidMode_Falling; + bpa->data.mode = eBoidMode_Falling; else { /* constrain to surface */ pa->state.co[2] = ground_co[2] + pa->size * boids->height; @@ -1329,17 +1351,17 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) VECCOPY(grav, ground_nor); VecMulf(grav, -1.0f); - Projf(dvec, pa->boid->acc, pa->state.vel); - VecSubf(dvec, pa->boid->acc, dvec); + Projf(dvec, bpa->data.acc, pa->state.vel); + VecSubf(dvec, bpa->data.acc, dvec); - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, grav, dvec, -boids->banking); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, grav, dvec, -boids->banking); + Normalize(bpa->gravity); } else { - /* gather negative surface normal to r_ve */ - VECADDFAC(pa->r_ve, pa->r_ve, ground_nor, -1.0f); - Normalize(pa->r_ve); + /* gather negative surface normal */ + VECADDFAC(bpa->gravity, bpa->gravity, ground_nor, -1.0f); + Normalize(bpa->gravity); } break; } @@ -1347,29 +1369,29 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* save direction to state.ave unless the boid is falling */ /* (boids can't effect their direction when falling) */ - if(pa->boid->mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) { + if(bpa->data.mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) { VECCOPY(pa->state.ave, pa->state.vel); Normalize(pa->state.ave); } /* apply damping */ - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) VecMulf(pa->state.vel, 1.0f - 0.2f*bbd->part->dampfac); /* calculate rotation matrix based on forward & down vectors */ - if(pa->boid->mode == eBoidMode_InAir) { + if(bpa->data.mode == eBoidMode_InAir) { VECCOPY(mat[0], pa->state.ave); - Projf(dvec, pa->r_ve, pa->state.ave); - VecSubf(mat[2], pa->r_ve, dvec); + Projf(dvec, bpa->gravity, pa->state.ave); + VecSubf(mat[2], bpa->gravity, dvec); Normalize(mat[2]); } else { - Projf(dvec, pa->state.ave, pa->r_ve); + Projf(dvec, pa->state.ave, bpa->gravity); VecSubf(mat[0], pa->state.ave, dvec); Normalize(mat[0]); - VECCOPY(mat[2], pa->r_ve); + VECCOPY(mat[2], bpa->gravity); } VecMulf(mat[2], -1.0f); Crossf(mat[1], mat[2], mat[0]); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index eafd9eb01fe..8be8df8e63b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -496,23 +496,30 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, if(!do_init_cloth(ob, clmd, result, framenr)) return result; + if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) { + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + cache->simframe= framenr; + cache->flag &= ~PTCACHE_REDO_NEEDED; + return result; + } + /* try to read from cache */ cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec); if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - implicit_set_positions(clmd); cloth_to_object (ob, clmd, result); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + + if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) + BKE_ptcache_write_cache(&pid, framenr); + return result; } else if(cache_result==PTCACHE_READ_OLD) { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); - implicit_set_positions(clmd); - cache->flag |= PTCACHE_SIMULATION_VALID; } else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { @@ -524,12 +531,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, } if(framenr == startframe) { - if(cache->flag & PTCACHE_REDO_NEEDED) { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - do_init_cloth(ob, clmd, result, framenr); - } - cache->flag |= PTCACHE_SIMULATION_VALID; + implicit_set_positions(clmd); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; /* don't write cache on first frame, but on second frame write * cache for frame 1 and 2 */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7a0eb882083..9c8c43cc8cb 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6696,10 +6696,8 @@ static DerivedMesh * particleInstanceModifier_applyModifier( if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){ float ran = 0.0f; if(pimd->random_position != 0.0f) { - /* just use some static collection of random numbers */ - /* TODO: use something else that's unique to each instanced object */ - pa = psys->particles + (i/totvert)%totpart; - ran = pimd->random_position * 0.5 * (1.0f + pa->r_ave[0]); + BLI_srandom(psys->seed + (i/totvert)%totpart); + ran = pimd->random_position * BLI_frand(); } if(pimd->flag & eParticleInstanceFlag_KeepShape) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1cb0abfe21c..9a137bdb7e6 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -481,15 +481,15 @@ void unlink_object(Scene *scene, Object *ob) if(tpsys->part->dup_ob==ob) tpsys->part->dup_ob= NULL; - if(tpsys->part->flag&PART_STICKY) { + if(tpsys->part->phystype==PART_PHYS_BOIDS) { ParticleData *pa; + BoidParticle *bpa; int p; for(p=0,pa=tpsys->particles; ptotpart; p++,pa++) { - if(pa->stick_ob==ob) { - pa->stick_ob= 0; - pa->flag &= ~PARS_STICKY; - } + bpa = pa->boid; + if(bpa->ground == ob) + bpa->ground = NULL; } } if(tpsys->part->boids) { @@ -1082,19 +1082,35 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) { ParticleSystem *psysn; ParticleData *pa; - int a; + int p; psysn= MEM_dupallocN(psys); psysn->particles= MEM_dupallocN(psys->particles); psysn->child= MEM_dupallocN(psys->child); - if(psysn->particles->keys) - psysn->particles->keys = MEM_dupallocN(psys->particles->keys); - for(a=0, pa=psysn->particles; atotpart; a++, pa++) { - if(pa->hair) - pa->hair= MEM_dupallocN(pa->hair); - if(a) - pa->keys= (pa-1)->keys + (pa-1)->totkey; + if(psys->part->type == PART_HAIR) { + for(p=0, pa=psysn->particles; ptotpart; p++, pa++) + pa->hair = MEM_dupallocN(pa->hair); + } + + if(psysn->particles->keys || psysn->particles->boid) { + ParticleKey *key = psysn->particles->keys; + BoidParticle *boid = psysn->particles->boid; + + if(key) + key = MEM_dupallocN(key); + + if(boid) + boid = MEM_dupallocN(boid); + + for(p=0, pa=psysn->particles; ptotpart; p++, pa++) { + if(boid) + pa->boid = boid++; + if(key) { + pa->keys = key; + key += pa->totkey; + } + } } if(psys->soft) { @@ -1102,14 +1118,7 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) psysn->soft->particles = psysn; } - if(psys->particles->boid) { - psysn->particles->boid = MEM_dupallocN(psys->particles->boid); - for(a=1, pa=psysn->particles+1; atotpart; a++, pa++) - pa->boid = (pa-1)->boid + 1; - } - - if(psys->targets.first) - BLI_duplicatelist(&psysn->targets, &psys->targets); + BLI_duplicatelist(&psysn->targets, &psys->targets); psysn->pathcache= NULL; psysn->childcache= NULL; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 1ae3ec5dd50..81eb0b79c40 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -92,10 +92,10 @@ static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, P /* few helpers for countall etc. */ int count_particles(ParticleSystem *psys){ ParticleSettings *part=psys->part; - ParticleData *pa; - int tot=0,p; + PARTICLE_P; + int tot=0; - for(p=0,pa=psys->particles; ptotpart; p++,pa++){ + LOOP_PARTICLES { if(pa->alive == PARS_KILLED); else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); @@ -106,10 +106,10 @@ int count_particles(ParticleSystem *psys){ } int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ ParticleSettings *part=psys->part; - ParticleData *pa; - int tot=0,p; + PARTICLE_P; + int tot=0; - for(p=0,pa=psys->particles; ptotpart; p++,pa++){ + LOOP_PARTICLES { if(pa->alive == PARS_KILLED); else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); @@ -120,10 +120,10 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ } int psys_count_keys(ParticleSystem *psys) { - ParticleData *pa; - int i, totpart=psys->totpart, totkey=0; + PARTICLE_P; + int totkey=0; - for(i=0, pa=psys->particles; itotkey; return totkey; @@ -368,13 +368,16 @@ void psys_free_settings(ParticleSettings *part) void free_hair(ParticleSystem *psys, int softbody) { - ParticleData *pa; - int i, totpart=psys->totpart; + PARTICLE_P; + + if(psys->part->type != PART_HAIR) + return; - for(i=0, pa=psys->particles; ihair) MEM_freeN(pa->hair); pa->hair = NULL; + pa->totkey = 0; } psys->flag &= ~PSYS_HAIR_DONE; @@ -386,13 +389,15 @@ void free_hair(ParticleSystem *psys, int softbody) } void free_keyed_keys(ParticleSystem *psys) { - ParticleData *pa; - int i; + PARTICLE_P; + + if(psys->part->type == PART_HAIR) + return; if(psys->particles && psys->particles->keys) { MEM_freeN(psys->particles->keys); - for(i=0, pa=psys->particles; itotpart; i++, pa++) { + LOOP_PARTICLES { if(pa->keys) { pa->keys= NULL; pa->totkey= 0; @@ -431,6 +436,29 @@ void psys_free_children(ParticleSystem *psys) free_child_path_cache(psys); } +void psys_free_particles(ParticleSystem *psys) +{ + PARTICLE_P; + + if(psys->particles) { + if(psys->part->type==PART_HAIR) { + LOOP_PARTICLES { + if(pa->hair) + MEM_freeN(pa->hair); + } + } + + if(psys->particles->keys) + MEM_freeN(psys->particles->keys); + + if(psys->particles->boid) + MEM_freeN(psys->particles->boid); + + MEM_freeN(psys->particles); + psys->particles= NULL; + psys->totpart= 0; + } +} /* free everything */ void psys_free(Object *ob, ParticleSystem * psys) { @@ -440,22 +468,11 @@ void psys_free(Object *ob, ParticleSystem * psys) psys_free_path_cache(psys, NULL); - free_hair(psys, 1); - - free_keyed_keys(psys); + psys_free_particles(psys); if(psys->edit && psys->free_edit) psys->free_edit(psys->edit); - if(psys->particles){ - if(psys->particles->boid) - MEM_freeN(psys->particles->boid); - - MEM_freeN(psys->particles); - psys->particles = 0; - psys->totpart = 0; - } - if(psys->child){ MEM_freeN(psys->child); psys->child = 0; @@ -485,14 +502,11 @@ void psys_free(Object *ob, ParticleSystem * psys) psys->part=0; } - if(psys->reactevents.first) - BLI_freelistN(&psys->reactevents); - BKE_ptcache_free_list(&psys->ptcaches); psys->pointcache = NULL; - if(psys->targets.first) - BLI_freelistN(&psys->targets); + BLI_freelistN(&psys->targets); + BLI_freelistN(&psys->reactevents); BLI_kdtree_free(psys->tree); @@ -1015,11 +1029,12 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->dietime = *((point->keys + point->totkey - 1)->time); } else if(pind->keyed) { - pind->kkey[0] = pa->keys; - pind->kkey[1] = pa->totkey > 1 ? pa->keys + 1 : NULL; + ParticleKey *key = pa->keys; + pind->kkey[0] = key; + pind->kkey[1] = pa->totkey > 1 ? key + 1 : NULL; - pind->birthtime = pa->keys->time; - pind->dietime = (pa->keys + pa->totkey - 1)->time; + pind->birthtime = key->time; + pind->dietime = (key + pa->totkey - 1)->time; } else if(pind->cache) { get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL); @@ -1028,17 +1043,18 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->dietime = pa ? pa->dietime : pind->cache->endframe; } else { - pind->hkey[0] = pa->hair; - pind->hkey[1] = pa->hair + 1; + HairKey *key = pa->hair; + pind->hkey[0] = key; + pind->hkey[1] = key + 1; - pind->birthtime = pa->hair->time; - pind->dietime = (pa->hair + pa->totkey - 1)->time; + pind->birthtime = key->time; + pind->dietime = (key + pa->totkey - 1)->time; } - if(pind->soft) { - pind->bp[0] = pind->soft->bpoint + pa->bpi; - pind->bp[1] = pind->soft->bpoint + pa->bpi + 1; - } + //if(pind->soft) { + // pind->bp[0] = pind->soft->bpoint + pa->bpi; + // pind->bp[1] = pind->soft->bpoint + pa->bpi + 1; + //} } static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey) { @@ -2558,6 +2574,9 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa ListBase threads; int i, totchild, totparent, totthread; + if(psys->flag & PSYS_GLOBAL_HAIR) + return; + pthreads= psys_threads_create(scene, ob, psys); if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) { @@ -2688,7 +2707,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra } if(!psys->totchild) { - pa_length = 1.0f - part->randlength * 0.5 * (1.0f + pa->r_ave[0]); + BLI_srandom(psys->seed + i); + pa_length = 1.0f - part->randlength * BLI_frand(); if(vg_length) pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length); } @@ -2740,7 +2760,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); /* keyed, baked and softbody are allready in global space */ - if(!keyed && !baked && !soft) { + if(!keyed && !baked && !soft && !(psys->flag & PSYS_GLOBAL_HAIR)) { Mat4MulVecfl(hairmat, result.co); } @@ -3574,6 +3594,8 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, { ParticleTexture ptex; float size=1.0f; + + BLI_srandom(psys->seed + (pa - psys->particles) + 100); if(ma && part->from!=PART_FROM_PARTICLE){ ptex.size=size; @@ -3592,7 +3614,7 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size); if(part->randsize!=0.0) - size*= 1.0f - part->randsize*pa->sizemul; + size*= 1.0f - part->randsize * BLI_frand(); return size*part->size; } @@ -3759,13 +3781,6 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i if(pparticles + p; - - if(pa->alive==PARS_DEAD && part->flag & PART_STICKY && pa->flag & PARS_STICKY && pa->stick_ob){ - copy_particle_key(state,&pa->state,0); - key_from_object(pa->stick_ob,state); - return; - } - pind.keyed = keyed; pind.cache = cached ? psys->pointcache : NULL; pind.soft = NULL; @@ -3981,20 +3996,11 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy return 0; /* currently not supported */ else if(psys->totchild && p>=psys->totpart){ ChildParticle *cpa=psys->child+p-psys->totpart; - ParticleKey *key1, skey; + ParticleKey *key1; float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime; pa = psys->particles + cpa->parent; - - if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob) { - key1 = &skey; - copy_particle_key(key1,&pa->state,0); - key_from_object(pa->stick_ob,key1); - } - else { - key1=&pa->state; - } - + key1=&pa->state; offset_child(cpa, key1, state, part->childflat, part->childrad); CLAMP(t,0.0,1.0); @@ -4051,10 +4057,6 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy } } - if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob){ - key_from_object(pa->stick_ob,state); - } - if(psys->lattice) calc_latt_deform(psys->lattice, state->co,1.0f); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 0f72c1c5866..eb570ba287c 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -123,21 +123,11 @@ static int get_current_display_percentage(ParticleSystem *psys) void psys_reset(ParticleSystem *psys, int mode) { ParticleSettings *part= psys->part; - ParticleData *pa; - int i; + PARTICLE_P; if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) { if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->edit && psys->edit->edited))) { - if(psys->particles) { - if(psys->particles->keys) - MEM_freeN(psys->particles->keys); - - for(i=0, pa=psys->particles; itotpart; i++, pa++) - if(pa->hair) MEM_freeN(pa->hair); - - MEM_freeN(psys->particles); - psys->particles= NULL; - } + psys_free_particles(psys); psys->totpart= 0; psys->totkeyed= 0; @@ -155,10 +145,7 @@ void psys_reset(ParticleSystem *psys, int mode) } else if(mode == PSYS_RESET_CACHE_MISS) { /* set all particles to be skipped */ - ParticleData *pa = psys->particles; - int p=0; - - for(; ptotpart; p++, pa++) + LOOP_PARTICLES pa->flag |= PARS_NO_DISP; } @@ -180,9 +167,10 @@ void psys_reset(ParticleSystem *psys, int mode) static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) { - ParticleData *newpars = 0, *pa; - BoidData *newboids = 0; - int i, totpart, totsaved = 0; + ParticleData *newpars = NULL; + BoidParticle *newboids = NULL; + PARTICLE_P; + int totpart, totsaved = 0; if(new_totpart<0) { if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) { @@ -195,47 +183,46 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) else totpart=new_totpart; - if(totpart) { + if(totpart && totpart != psys->totpart) { newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles"); + + if(psys->particles) { + totsaved=MIN2(psys->totpart,totpart); + /*save old pars*/ + if(totsaved) { + memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData)); + + if(psys->particles->boid) + memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle)); + } - if(psys->part->phystype == PART_PHYS_BOIDS) - newboids = MEM_callocN(totpart*sizeof(BoidData), "Boid Data"); - } - if(psys->particles) { - totsaved=MIN2(psys->totpart,totpart); - /*save old pars*/ - if(totsaved) { - memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData)); - - if(newboids) - memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidData)); - } - - if(psys->particles->keys) - MEM_freeN(psys->particles->keys); + if(psys->particles->keys) + MEM_freeN(psys->particles->keys); - if(psys->particles->boid) - MEM_freeN(psys->particles->boid); + if(psys->particles->boid) + MEM_freeN(psys->particles->boid); - for(i=0, pa=newpars; ikeys) { - pa->keys= NULL; - pa->totkey= 0; + for(p=0, pa=newpars; pkeys) { + pa->keys= NULL; + pa->totkey= 0; + } } - } - for(i=totsaved, pa=psys->particles+totsaved; itotpart; i++, pa++) - if(pa->hair) MEM_freeN(pa->hair); + for(p=totsaved, pa=psys->particles+totsaved; ptotpart; p++, pa++) + if(pa->hair) MEM_freeN(pa->hair); - MEM_freeN(psys->particles); - } - psys->particles=newpars; + MEM_freeN(psys->particles); + } + + psys->particles=newpars; - if(newboids) { - pa = psys->particles; - pa->boid = newboids; - for(i=1, pa++; iboid = (pa-1)->boid + 1; + if(newboids) { + LOOP_PARTICLES + pa->boid = newboids++; + } + + psys->totpart=totpart; } if(psys->child) { @@ -243,8 +230,6 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) psys->child=0; psys->totchild=0; } - - psys->totpart=totpart; } static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys) @@ -291,8 +276,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) each original elements can reference its derived elements */ Mesh *me= (Mesh*)ob->data; - ParticleData *pa= 0; - int p; + PARTICLE_P; /* CACHE LOCATIONS */ if(!dm->deformedOnly) { @@ -329,7 +313,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) } /* cache the verts/faces! */ - for(p=0,pa=psys->particles; ptotpart; p++,pa++) { + LOOP_PARTICLES { if(psys->part->from == PART_FROM_VERT) { if(nodearray[pa->num]) pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link); @@ -349,7 +333,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) * should know to use the num or num_dmcache, set the num_dmcache to * an invalid value, just incase */ - for(p=0,pa=psys->particles; ptotpart; p++,pa++) + LOOP_PARTICLES pa->num_dmcache = -1; } } @@ -1449,12 +1433,11 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec /* ready for future use, to emit particles without geometry */ static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from) { - ParticleData *pa; - int totpart=psys->totpart, p; + PARTICLE_P; fprintf(stderr,"Shape emission not yet possible!\n"); - for(p=0,pa=psys->particles; pfuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0; pa->foffset= 0.0f; pa->num= -1; @@ -1476,12 +1459,11 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys, distribute_particles_on_shape(ob,psys,from); if(distr_error){ - ParticleData *pa; - int totpart=psys->totpart, p; + PARTICLE_P; fprintf(stderr,"Particle distribution error!\n"); - for(p=0,pa=psys->particles; pfuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0; pa->foffset= 0.0f; pa->num= -1; @@ -1576,7 +1558,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps Material *ma=0; //IpoCurve *icu=0; // XXX old animation system int totpart; - float rand,length; + float rand; part=psys->part; @@ -1631,40 +1613,8 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps pa->dietime= pa->time+pa->lifetime; - pa->sizemul= BLI_frand(); - - rand= BLI_frand(); - - /* while loops are to have a spherical distribution (avoid cubic distribution) */ - if(part->phystype != PART_PHYS_BOIDS) { - /* boids store gravity in r_ve, so skip here */ - length=2.0f; - while(length>1.0){ - pa->r_ve[0]=2.0f*(BLI_frand()-0.5f); - pa->r_ve[1]=2.0f*(BLI_frand()-0.5f); - pa->r_ve[2]=2.0f*(BLI_frand()-0.5f); - length=VecLength(pa->r_ve); - } - } - - length=2.0f; - while(length>1.0){ - pa->r_ave[0]=2.0f*(BLI_frand()-0.5f); - pa->r_ave[1]=2.0f*(BLI_frand()-0.5f); - pa->r_ave[2]=2.0f*(BLI_frand()-0.5f); - length=VecLength(pa->r_ave); - } - - pa->r_rot[0]=2.0f*(BLI_frand()-0.5f); - pa->r_rot[1]=2.0f*(BLI_frand()-0.5f); - pa->r_rot[2]=2.0f*(BLI_frand()-0.5f); - pa->r_rot[3]=2.0f*(BLI_frand()-0.5f); - - NormalQuat(pa->r_rot); - if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){ - /* any unique random number will do (r_ave[0]) */ - if(ptex.exist < 0.5*(1.0+pa->r_ave[0])) + if(ptex.exist < BLI_frand()) pa->flag |= PARS_UNEXIST; else pa->flag &= ~PARS_UNEXIST; @@ -1678,10 +1628,9 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd) { //IpoCurve *icu=0; // XXX old animation system - ParticleData *pa; - int p, totpart=psys->totpart; + PARTICLE_P; - for(p=0, pa=psys->particles; ppart->type != PART_FLUID) { @@ -1749,10 +1698,39 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4]; float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0}; float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0}; - float q_phase[4]; + float q_phase[4], length, r_phase; part=psys->part; ptex.ivel=1.0; + + BLI_srandom(psys->seed + (pa - psys->particles)); + + /* we need to get every random even if they're not used so that they don't effect eachother */ + /* while loops are to have a spherical distribution (avoid cubic distribution) */ + length=2.0f; + while(length>1.0){ + r_vel[0]=2.0f*(BLI_frand()-0.5f); + r_vel[1]=2.0f*(BLI_frand()-0.5f); + r_vel[2]=2.0f*(BLI_frand()-0.5f); + length=VecLength(r_vel); + } + + length=2.0f; + while(length>1.0){ + r_ave[0]=2.0f*(BLI_frand()-0.5f); + r_ave[1]=2.0f*(BLI_frand()-0.5f); + r_ave[2]=2.0f*(BLI_frand()-0.5f); + length=VecLength(r_ave); + } + + r_rot[0]=2.0f*(BLI_frand()-0.5f); + r_rot[1]=2.0f*(BLI_frand()-0.5f); + r_rot[2]=2.0f*(BLI_frand()-0.5f); + r_rot[3]=2.0f*(BLI_frand()-0.5f); + + NormalQuat(r_rot); + + r_phase = BLI_frand(); if(part->from==PART_FROM_PARTICLE){ Object *tob; @@ -1763,29 +1741,26 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic if(tob==0) tob=ob; - tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1); + tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1); state.time = pa->time; if(pa->num == -1) memset(&state, 0, sizeof(state)); else psys_get_particle_state(scene, tob,tpsys,pa->num,&state,1); - psys_get_from_key(&state,loc,nor,rot,0); + psys_get_from_key(&state, loc, nor, rot, 0); - QuatMulVecf(rot,vtan); - QuatMulVecf(rot,utan); - VECCOPY(r_vel,pa->r_ve); - VECCOPY(r_rot,pa->r_rot); - VECCOPY(r_ave,pa->r_ave); + QuatMulVecf(rot, vtan); + QuatMulVecf(rot, utan); - VECCOPY(p_vel,state.vel); + VECCOPY(p_vel, state.vel); speed=Normalize(p_vel); - VecMulf(p_vel,Inpf(pa->r_ve,p_vel)); - VECSUB(p_vel,pa->r_ve,p_vel); + VecMulf(p_vel, Inpf(r_vel, p_vel)); + VECSUB(p_vel, r_vel, p_vel); Normalize(p_vel); - VecMulf(p_vel,speed); + VecMulf(p_vel, speed); - VECCOPY(pa->fuv,loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */ + VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */ } else{ /* get precise emitter matrix if particle is born */ @@ -1839,29 +1814,25 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic /* -velocity */ if(part->randfac!=0.0){ - VECADD(r_vel,tloc,pa->r_ve); - Mat4MulVecfl(ob->obmat,r_vel); - VECSUB(r_vel,r_vel,loc); + Mat4Mul3Vecfl(ob->obmat,r_vel); Normalize(r_vel); } /* -angular velocity */ if(part->avemode==PART_AVE_RAND){ - VECADD(r_ave,tloc,pa->r_ave); - Mat4MulVecfl(ob->obmat,r_ave); - VECSUB(r_ave,r_ave,loc); + Mat4Mul3Vecfl(ob->obmat,r_ave); Normalize(r_ave); } /* -rotation */ if(part->randrotfac != 0.0f){ - QUATCOPY(r_rot,pa->r_rot); Mat4ToQuat(ob->obmat,rot); QuatMul(r_rot,r_rot,rot); } } if(part->phystype==PART_PHYS_BOIDS) { + BoidParticle *bpa = pa->boid; float dvec[3], q[4], mat[3][3]; VECCOPY(pa->state.co,loc); @@ -1878,16 +1849,21 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic VECCOPY(pa->state.ave, nor); } /* and gravity in r_ve */ - pa->r_ve[0] = pa->r_ve[1] = 0.0f; - pa->r_ve[2] = -1.0f; + bpa->gravity[0] = bpa->gravity[1] = 0.0f; + bpa->gravity[2] = -1.0f; if(part->acc[2]!=0.0f) - pa->r_ve[2] = part->acc[2]; + bpa->gravity[2] = part->acc[2]; + + //pa->r_ve[0] = pa->r_ve[1] = 0.0f; + //pa->r_ve[2] = -1.0f; + //if(part->acc[2]!=0.0f) + // pa->r_ve[2] = part->acc[2]; /* calculate rotation matrix */ - Projf(dvec, pa->r_ve, pa->state.ave); + Projf(dvec, r_vel, pa->state.ave); VecSubf(mat[0], pa->state.ave, dvec); Normalize(mat[0]); - VECCOPY(mat[2], pa->r_ve); + VECCOPY(mat[2], r_vel); VecMulf(mat[2], -1.0f); Normalize(mat[2]); Crossf(mat[1], mat[2], mat[0]); @@ -1896,10 +1872,10 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic Mat3ToQuat_is_ok(mat, q); QuatCopy(pa->state.rot, q); - pa->boid->health = part->boids->health; - pa->boid->mode = eBoidMode_InAir; - pa->boid->state_id = ((BoidState*)part->boids->states.first)->id; - pa->boid->acc[0]=pa->boid->acc[1]=pa->boid->acc[2]=0.0f; + bpa->data.health = part->boids->health; + bpa->data.mode = eBoidMode_InAir; + bpa->data.state_id = ((BoidState*)part->boids->states.first)->id; + bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f; } else { /* conversion done so now we apply new: */ @@ -1988,8 +1964,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic /* rotation phase */ phasefac = part->phasefac; - if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */ - phasefac += part->randphasefac * pa->r_ave[0]; + if(part->randphasefac != 0.0f) + phasefac += part->randphasefac * r_phase; VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase); /* combine base rotation & phase */ @@ -2027,8 +2003,7 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic pa->state.time = cfra; - pa->stick_ob = 0; - pa->flag &= ~PARS_STICKY; +// pa->flag &= ~PARS_STICKY; } static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from) { @@ -2094,8 +2069,9 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) { ParticleSystem *kpsys = psys; ParticleTarget *pt; - ParticleData *pa; - int totpart = psys->totpart, i, k, totkeys = psys->totkeyed; + PARTICLE_P; + ParticleKey *key; + int totpart = psys->totpart, k, totkeys = psys->totkeyed; /* no proper targets so let's clear and bail out */ if(psys->totkeyed==0) { @@ -2107,12 +2083,12 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) if(totpart && psys->particles->totkey != totkeys) { free_keyed_keys(psys); - psys->particles->keys = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys"); - psys->particles->totkey = totkeys; + key = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys"); - for(i=1, pa=psys->particles+1; ikeys = (pa-1)->keys + totkeys; + LOOP_PARTICLES { + pa->keys = key; pa->totkey = totkeys; + key += totkeys; } } @@ -2126,22 +2102,23 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) else kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1); - for(i=0,pa=psys->particles; ikeys + k)->time = -1.0; /* use current time */ + LOOP_PARTICLES { + key = pa->keys + k; + key->time = -1.0; /* use current time */ - psys_get_particle_state(scene, pt->ob, kpsys, i%kpsys->totpart, pa->keys + k, 1); + psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1); if(psys->flag & PSYS_KEYED_TIMING){ - (pa->keys+k)->time = pa->time + pt->time; + key->time = pa->time + pt->time; if(pt->duration != 0.0f && k+1 < totkeys) { - copy_particle_key(pa->keys+k+1, pa->keys+k, 1); - (pa->keys+k+1)->time = pa->time + pt->time + pt->duration; + copy_particle_key(key+1, key, 1); + (key+1)->time = pa->time + pt->time + pt->duration; } } else if(totkeys > 1) - (pa->keys+k)->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime; + key->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime; else - pa->keys->time = pa->time; + key->time = pa->time; } if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f) @@ -2296,16 +2273,15 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra static void update_particle_tree(ParticleSystem *psys) { if(psys) { - ParticleData *pa = psys->particles; - int p, totpart = psys->totpart; + PARTICLE_P; if(!psys->tree || psys->tree_frame != psys->cfra) { BLI_kdtree_free(psys->tree); - psys->tree = BLI_kdtree_new(totpart); + psys->tree = BLI_kdtree_new(psys->totpart); - for(p=0, pa=psys->particles; pflag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE) continue; @@ -2548,9 +2524,9 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ListBase *lb=&psys->effectors; ParticleEffectorCache *ec; ParticleSettings *part=psys->part; - ParticleData *pa; + PARTICLE_P; + int totpart; float vec2[3],loc[3],*co=0; - int p,totpart; for(ec= lb->first; ec; ec= ec->next) { PartDeflect *pd= ec->ob->pd; @@ -2574,7 +2550,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances"); ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations"); - for(p=0,pa=psys->particles; pfrom == PART_FROM_PARTICLE) { VECCOPY(loc, pa->fuv); } @@ -3253,9 +3229,10 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa /* override for boids */ if(part->phystype == PART_PHYS_BOIDS) { + BoidParticle *bpa = pa->boid; radius = pa->size; boid_z = pa->state.co[2]; - skip_ob = pa->stick_ob; + skip_ob = bpa->ground; } /* 10 iterations to catch multiple deflections */ @@ -3325,12 +3302,7 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa deflections=max_deflections; /* store for reactors */ - copy_particle_key(&reaction_state,&pa->state,0); - - if(part->flag & PART_STICKY){ - pa->stick_ob=ob; - pa->flag |= PARS_STICKY; - } + copy_particle_key(&reaction_state, &pa->state, 0); } else { float nor_vec[3], tan_vec[3], tan_vel[3], vel[3]; @@ -3418,7 +3390,8 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f)); if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) { - if(pa->boid->mode == eBoidMode_OnLand || co[2] <= boid_z) { + BoidParticle *bpa = pa->boid; + if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) { co[2] = boid_z; vel[2] = 0.0f; } @@ -3460,10 +3433,9 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa /* Hair */ /************************************************/ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){ - ParticleData *pa; - HairKey *key; + HairKey *key, *root; + PARTICLE_P; int totpart; - int i; Mat4Invert(ob->imat,ob->obmat); @@ -3474,21 +3446,22 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy totpart=psys->totpart; /* save new keys for elements if needed */ - for(i=0,pa=psys->particles; itotkey==0 || pa->hair==NULL) { pa->hair = MEM_callocN((psys->part->hair_step + 1) * sizeof(HairKey), "HairKeys"); pa->totkey = 0; } - key = pa->hair + pa->totkey; + key = root = pa->hair; + key += pa->totkey; /* convert from global to geometry space */ VecCopyf(key->co, pa->state.co); Mat4MulVecfl(ob->imat, key->co); if(pa->totkey) { - VECSUB(key->co, key->co, pa->hair->co); + VECSUB(key->co, key->co, root->co); psys_vec_rot_to_face(psmd->dm, pa, key->co); } @@ -3500,7 +3473,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy /* root is always in the origin of hair space so we set it to be so after the last key is saved*/ if(pa->totkey == psys->part->hair_step + 1) - pa->hair->co[0] = pa->hair->co[1] = pa->hair->co[2] = 0.0f; + root->co[0] = root->co[1] = root->co[2] = 0.0f; } } /************************************************/ @@ -3510,14 +3483,14 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra, float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size) { - ParticleData *pa; ParticleSettings *part=psys->part; KDTree *tree=0; IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system Material *ma=give_current_material(ob,part->omat); BoidBrainData bbd; + PARTICLE_P; float timestep; - int p, totpart; + int totpart; /* current time */ float ctime, ipotime; // XXX old animation system /* frame & time changes */ @@ -3546,7 +3519,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic if(part->type==PART_REACTOR) vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); - for(p=0, pa=psys->particles; pflag & PARS_UNEXIST) continue; /* set correct ipo timing */ @@ -3615,7 +3588,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic } /* main loop: calculate physics for all particles */ - for(p=0, pa=psys->particles; pflag & (PARS_UNEXIST+PARS_NO_DISP)) continue; copy_particle_key(&pa->prev_state,&pa->state,1); @@ -3703,9 +3676,6 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic else{ pa->alive=PARS_DEAD; pa->state.time=pa->dietime; - - if(pa->flag&PARS_STICKY) - psys_key_to_object(pa->stick_ob,&pa->state,0); } } else @@ -3769,12 +3739,13 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) { ParticleSettings *part = psys->part; - ParticleData *pa; - int p; - float disp = (float)get_current_display_percentage(psys)/50.0f-1.0f; + PARTICLE_P; + float disp = (float)get_current_display_percentage(psys)/100.0f; + + BLI_srandom(psys->seed); - for(p=0, pa=psys->particles; ptotpart; p++,pa++){ - if(pa->r_rot[0] > disp) + LOOP_PARTICLES { + if(BLI_frand() > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -3798,13 +3769,14 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) { ParticleSettings *part=psys->part; - ParticleData *pa; ParticleKey state; IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system Material *ma=give_current_material(ob,part->omat); - int p; + PARTICLE_P; float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra + BLI_srandom(psys->seed); + if(part->from!=PART_FROM_PARTICLE) vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); @@ -3817,9 +3789,9 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps precalc_effectors(scene, ob,psys,psmd,cfra); //} - disp= (float)get_current_display_percentage(psys)/50.0f-1.0f; + disp= (float)get_current_display_percentage(psys)/100.0f; - for(p=0, pa=psys->particles; ptotpart; p++,pa++){ + LOOP_PARTICLES { #if 0 // XXX old animation system if((part->flag&PART_ABS_TIME)==0 && part->ipo){ ipotime=100.0f*(cfra-pa->time)/pa->lifetime; @@ -3866,7 +3838,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps psys->lattice= NULL; } - if(pa->r_rot[0] > disp) + if(BLI_frand() > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -3919,8 +3891,8 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys) else { free_hair(psys, 1); - CLAMP(part->path_start, part->sta, part->end + part->lifetime); - CLAMP(part->path_end, part->sta, part->end + part->lifetime); + CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime)); + CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime)); } psys->softflag= 0; @@ -3929,23 +3901,25 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys) } void psys_check_boid_data(ParticleSystem *psys) { - ParticleData *pa = psys->particles; - int p = 1; + BoidParticle *bpa; + PARTICLE_P; + + pa = psys->particles; if(!pa) return; if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) { if(!pa->boid) { - pa->boid = MEM_callocN(psys->totpart * sizeof(BoidData), "Boid Data"); + bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data"); - for(pa++; ptotpart; p++, pa++) - pa->boid = (pa-1)->boid + 1; + LOOP_PARTICLES + pa->boid = bpa++; } } else if(pa->boid){ MEM_freeN(pa->boid); - for(; ptotpart; p++, pa++) + LOOP_PARTICLES pa->boid = NULL; } } @@ -4093,10 +4067,10 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra) { ParticleSettings *part; - ParticleData *pa; PointCache *cache; PTCacheID pid; - int totpart, oldtotpart, totchild, oldtotchild, p; + PARTICLE_P; + int totpart, oldtotpart, totchild, oldtotchild; float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0; int framenr, framedelta, startframe, endframe; @@ -4239,7 +4213,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle } else if(result==PTCACHE_READ_OLD) { psys->cfra = (float)cache->simframe; - for(p=0, pa=psys->particles; ptime > psys->cfra) pa->alive = PARS_UNBORN; @@ -4278,10 +4252,11 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle } /* set particles to be not calculated TODO: can't work with pointcache */ - disp= (float)get_current_display_percentage(psys)/50.0f-1.0f; + disp= (float)get_current_display_percentage(psys)/100.0f; - for(p=0, pa=psys->particles; pr_rot[0] > disp) + BLI_srandom(psys->seed); + LOOP_PARTICLES { + if(BLI_frand() > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 7a156f56d72..3e429749953 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -181,6 +181,7 @@ static int ptcache_write_particle(int index, void *psys_v, void **data) { ParticleSystem *psys= psys_v; ParticleData *pa = psys->particles + index; + BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL; float times[3] = {pa->time, pa->dietime, pa->lifetime}; if(data[BPHYS_DATA_INDEX]) { @@ -198,8 +199,8 @@ static int ptcache_write_particle(int index, void *psys_v, void **data) ptcache_data_from(data, BPHYS_DATA_SIZE, &pa->size); ptcache_data_from(data, BPHYS_DATA_TIMES, times); - if(pa->boid) - ptcache_data_from(data, BPHYS_DATA_TIMES, &pa->boid); + if(boid) + ptcache_data_from(data, BPHYS_DATA_BOIDS, &boid->data); return 1; } @@ -215,6 +216,7 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr { ParticleSystem *psys= psys_v; ParticleData *pa = psys->particles + index; + BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL; if(cfra > pa->state.time) memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey)); @@ -238,8 +240,8 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr pa->lifetime = times[2]; } - if(pa->boid) - ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &pa->boid); + if(boid) + ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &boid->data); /* determine velocity from previous location */ if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) { diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 40a28251495..fdbfe154fae 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3623,9 +3623,9 @@ static void particles_to_softbody(Scene *scene, Object *ob) /* find first BodyPoint index for each particle */ if(psys->totpart > 0) { - psys->particles->bpi = 0; - for(a=1, pa=psys->particles+1; atotpart; a++, pa++) - pa->bpi = (pa-1)->bpi + (pa-1)->totkey; +// psys->particles->bpi = 0; +// for(a=1, pa=psys->particles+1; atotpart; a++, pa++) +// pa->bpi = (pa-1)->bpi + (pa-1)->totkey; } /* we always make body points */ @@ -4079,7 +4079,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(framenr < startframe) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; - cache->last_exact= 0; + //cache->last_exact= 0; return; } @@ -4141,20 +4141,29 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i pa= sb->particles->particles; } + if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) { + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + cache->simframe= framenr; + cache->flag &= ~PTCACHE_REDO_NEEDED; + return; + } + /* try to read from cache */ cache_result = BKE_ptcache_read_cache(&pid, framenr, scene->r.frs_sec); if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - if(sb->particles==0) softbody_to_object(ob, vertexCos, numVerts, sb->local); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + + if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) + BKE_ptcache_write_cache(&pid, framenr); + return; } else if(cache_result==PTCACHE_READ_OLD) { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); cache->flag |= PTCACHE_SIMULATION_VALID; } else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { @@ -4166,16 +4175,11 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i } if(framenr == startframe) { - if(cache->flag & PTCACHE_REDO_NEEDED) { - softbody_update_positions(ob, sb, vertexCos, numVerts); - softbody_reset(ob, sb, vertexCos, numVerts); - cache->flag &= ~PTCACHE_REDO_NEEDED; - } /* first frame, no simulation to do, just set the positions */ softbody_update_positions(ob, sb, vertexCos, numVerts); - cache->flag |= PTCACHE_SIMULATION_VALID; cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; /* don't write cache on first frame, but on second frame write * cache for frame 1 and 2 */ @@ -4187,10 +4191,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i softbody_update_positions(ob, sb, vertexCos, numVerts); - /* do simulation */ - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - /* checking time: */ dtime = framedelta*timescale; @@ -4199,6 +4199,10 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(sb->particles==0) softbody_to_object(ob, vertexCos, numVerts, 0); + /* do simulation */ + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + BKE_ptcache_write_cache(&pid, framenr); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5a628192af6..6a26a71ee3d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3055,11 +3055,8 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles) { ParticleSystem *psys, *psysnext; - int a; for(psys=particles->first; psys; psys=psysnext){ - ParticleData *pa; - psysnext= psys->next; psys->part = newlibadr_us(fd, id->lib, psys->part); @@ -3070,12 +3067,6 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase pt->ob=newlibadr(fd, id->lib, pt->ob); psys->target_ob = newlibadr(fd, id->lib, psys->target_ob); - - for(a=0,pa=psys->particles; atotpart; a++,pa++){ - pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob); - } - - } else { /* particle modifier must be removed before particle system */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 88c6f205d15..c4a94660932 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -653,7 +653,7 @@ static void write_particlesystems(WriteData *wd, ListBase *particles) } if(psys->particles->boid && psys->part->phystype == PART_PHYS_BOIDS) - writestruct(wd, DATA, "BoidData", psys->totpart, psys->particles->boid); + writestruct(wd, DATA, "BoidParticle", psys->totpart, psys->particles->boid); } pt = psys->targets.first; for(; pt; pt=pt->next) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 0ae987f2308..a5d365cafd4 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -102,6 +102,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_property.h" #include "BKE_report.h" #include "BKE_sca.h" @@ -3883,6 +3884,8 @@ void ED_object_exit_editmode(bContext *C, int flag) /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context + BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH); + /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c index 22316290c7b..f2c7b64032f 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/ed_pointcache.c @@ -226,7 +226,7 @@ void PTCACHE_OT_bake(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "bake", 1, "Bake", ""); + RNA_def_boolean(ot->srna, "bake", 0, "Bake", ""); } void PTCACHE_OT_free_bake(wmOperatorType *ot) { diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 3ddc143b5a3..bc48d8f4f55 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -102,8 +102,6 @@ static void PTCacheUndo_clear(PTCacheEdit *edit); #define LOOP_SELECTED_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE)) #define LOOP_TAGGED_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if(key->flag & PEK_TAG) -#define LOOP_PARTICLES(i, pa) for(i=0, pa=psys->particles; itotpart; i++, pa++) - #define KEY_WCO (key->flag & PEK_USE_WCO ? key->world_co : key->co) /**************************** utilities *******************************/ @@ -642,12 +640,13 @@ static int count_selected_keys(Scene *scene, PTCacheEdit *edit) static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) { PTCacheEdit *edit; - ParticleData *pa; ParticleSystemModifierData *psmd; KDTree *tree; KDTreeNearest nearest; + HairKey *key; + PARTICLE_P; float mat[4][4], co[3]; - int i, index, totpart; + int index, totpart; edit= psys->edit; psmd= psys_get_modifier(ob, psys); @@ -656,11 +655,12 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) tree= BLI_kdtree_new(totpart); /* insert particles into kd tree */ - LOOP_PARTICLES(i, pa) { + LOOP_PARTICLES { + key = pa->hair; psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, pa->hair[0].co); + VECCOPY(co, key->co); Mat4MulVecfl(mat, co); - BLI_kdtree_insert(tree, i, co, NULL); + BLI_kdtree_insert(tree, p, co, NULL); } BLI_kdtree_balance(tree); @@ -669,27 +669,28 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) if(!edit->mirror_cache) edit->mirror_cache= MEM_callocN(sizeof(int)*totpart, "PE mirror cache"); - LOOP_PARTICLES(i, pa) { + LOOP_PARTICLES { + key = pa->hair; psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, pa->hair[0].co); + VECCOPY(co, key->co); Mat4MulVecfl(mat, co); co[0]= -co[0]; index= BLI_kdtree_find_nearest(tree, co, NULL, &nearest); /* this needs a custom threshold still, duplicated for editmode mirror */ - if(index != -1 && index != i && (nearest.dist <= 0.0002f)) - edit->mirror_cache[i]= index; + if(index != -1 && index != p && (nearest.dist <= 0.0002f)) + edit->mirror_cache[p]= index; else - edit->mirror_cache[i]= -1; + edit->mirror_cache[p]= -1; } /* make sure mirrors are in two directions */ - LOOP_PARTICLES(i, pa) { - if(edit->mirror_cache[i]) { - index= edit->mirror_cache[i]; - if(edit->mirror_cache[index] != i) - edit->mirror_cache[i]= -1; + LOOP_PARTICLES { + if(edit->mirror_cache[p]) { + index= edit->mirror_cache[p]; + if(edit->mirror_cache[index] != p) + edit->mirror_cache[p]= -1; } } @@ -1735,7 +1736,7 @@ static void rekey_particle(PEData *data, int pa_index) ParticleData *pa= psys->particles + pa_index; PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; - HairKey *key, *new_keys; + HairKey *key, *new_keys, *okey; PTCacheEditKey *ekey; float dval, sta, end; int k; @@ -1744,12 +1745,13 @@ static void rekey_particle(PEData *data, int pa_index) key= new_keys= MEM_callocN(data->totrekey * sizeof(HairKey),"Hair re-key keys"); + okey = pa->hair; /* root and tip stay the same */ - VECCOPY(key->co, pa->hair->co); - VECCOPY((key + data->totrekey - 1)->co, (pa->hair + pa->totkey - 1)->co); + VECCOPY(key->co, okey->co); + VECCOPY((key + data->totrekey - 1)->co, (okey + pa->totkey - 1)->co); - sta= key->time= pa->hair->time; - end= (key + data->totrekey - 1)->time= (pa->hair + pa->totkey - 1)->time; + sta= key->time= okey->time; + end= (key + data->totrekey - 1)->time= (okey + pa->totkey - 1)->time; dval= (end - sta) / (float)(data->totrekey - 1); /* interpolate new keys from old ones */ @@ -2034,9 +2036,11 @@ static void subdivide_particle(PEData *data, int pa_index) nkey= new_keys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(HairKey)),"Hair subdivide keys"); nekey= new_ekeys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(PTCacheEditKey)),"Hair subdivide edit keys"); - endtime= pa->hair[pa->totkey-1].time; + + key = pa->hair; + endtime= key[pa->totkey-1].time; - for(k=0, key=pa->hair, ekey=point->keys; ktotkey-1; k++, key++, ekey++) { + for(k=0, ekey=point->keys; ktotkey-1; k++, key++, ekey++) { memcpy(nkey,key,sizeof(HairKey)); memcpy(nekey,ekey,sizeof(PTCacheEditKey)); @@ -2461,7 +2465,6 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) *newpa= *pa; *newpoint= *point; if(pa->hair) newpa->hair= MEM_dupallocN(pa->hair); - if(pa->keys) newpa->keys= MEM_dupallocN(pa->keys); if(point->keys) newpoint->keys= MEM_dupallocN(point->keys); /* rotate weights according to vertex index rotation */ @@ -2966,7 +2969,7 @@ static void brush_add(PEData *data, short number) weight[w] /= totw; for(k=0; ktotaddkey; k++) { - hkey= pa->hair + k; + hkey= (HairKey*)pa->hair + k; hkey->time= pa->time + k * framestep; key[0].time= hkey->time/ 100.0f; @@ -2990,15 +2993,15 @@ static void brush_add(PEData *data, short number) if(k==0) VECSUB(co1, pa->state.co, key[0].co); - VECADD(pa->hair[k].co, key[0].co, co1); + VECADD(hkey->co, key[0].co, co1); - pa->hair[k].time= key[0].time; + hkey->time= key[0].time; } } else { for(k=0, hkey=pa->hair; ktotaddkey; k++, hkey++) { VECADDFAC(hkey->co, pa->state.co, pa->state.vel, k * framestep * timestep); - pa->hair[k].time += k * framestep; + hkey->time += k * framestep; } } for(k=0, hkey=pa->hair; ktotaddkey; k++, hkey++) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index e49616fc740..25ff1244254 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3373,8 +3373,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_birthtime=pa->time; pa_dietime = pa->dietime; pa_size=pa->size; - if(part->phystype==PART_PHYS_BOIDS) - pa_health = pa->boid->health; + if(part->phystype==PART_PHYS_BOIDS) { + pa_health = pa->boid->data.health; + } else pa_health = -1.0; @@ -3409,8 +3410,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } #endif // XXX old animation system - r_tilt = 1.0f + pa->r_ave[0]; - r_length = 0.5f * (1.0f + pa->r_ave[1]); + BLI_srandom(psys->seed+a); + + r_tilt = 2.0f*(BLI_frand() - 0.5f); + r_length = BLI_frand(); } else{ ChildParticle *cpa= &psys->child[a-totpart]; diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 12c253a7cb8..d4dc3df0965 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -33,6 +33,7 @@ #define DNA_PARTICLE_TYPES_H #include "DNA_ID.h" +#include "DNA_boid_types.h" struct AnimData; @@ -52,6 +53,14 @@ typedef struct ParticleKey { /* when changed update size of struct to copy_parti float time; /* when this key happens */ } ParticleKey; +typedef struct BoidParticle { + struct Object *ground; + struct BoidData data; + float gravity[3]; + float wander[3]; + float rt; +} BoidParticle; + /* Child particles are created around or between parent particles */ typedef struct ChildParticle { int num, parent; /* num is face index on the final derived mesh */ @@ -69,42 +78,34 @@ typedef struct ParticleTarget { float time, duration; } ParticleTarget; -/* Everything that's non dynamic for a particle: */ typedef struct ParticleData { - struct Object *stick_ob;/* object that particle sticks to when dead */ - - ParticleKey state; /* normally current global coordinates or */ - /* in sticky object space if dead & sticky */ + ParticleKey state; /* current global coordinates */ ParticleKey prev_state; /* previous state */ - + HairKey *hair; /* hair vertices */ - ParticleKey *keys; /* keyed states */ + ParticleKey *keys; /* keyed keys */ - struct BoidData *boid; /* boids data */ + BoidParticle *boid; /* boids data */ - float r_rot[4]; /* random values */ - float r_ave[3],r_ve[3]; - - float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ - /* face normal for volume emission */ + int totkey; /* amount of hair or keyed keys*/ float time, lifetime; /* dietime is not nescessarily time+lifetime as */ float dietime; /* particles can die unnaturally (collision) */ - float size, sizemul; /* size and multiplier so that we can update size when ever */ - int num; /* index to vert/edge/face */ int num_dmcache; /* index to derived mesh data (face) to avoid slow lookups */ - int totkey; - int bpi; /* softbody body point start index */ + float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ + /* face normal for volume emission */ + + float size; /* size and multiplier so that we can update size when ever */ short flag; - short alive; /* the life state of a particle */ + short alive; /* the life state of a particle */ short loop; /* how many times particle life has looped */ - short rt2; + short rt; } ParticleData; typedef struct ParticleSettings { @@ -258,7 +259,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_TRAND 128 #define PART_EDISTR 256 /* particle/face from face areas */ -#define PART_STICKY 512 /*collided particles can stick to collider*/ +//#define PART_STICKY 512 /*collided particles can stick to collider*/ #define PART_DIE_ON_COL (1<<12) #define PART_SIZE_DEFL (1<<13) /* swept sphere deflections */ #define PART_ROT_DYN (1<<14) /* dynamic rotation */ @@ -409,7 +410,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in /* psys->flag */ #define PSYS_CURRENT 1 -//#define PSYS_BAKING 2 +#define PSYS_GLOBAL_HAIR 2 //#define PSYS_BAKE_UI 4 #define PSYS_KEYED_TIMING 8 #define PSYS_ENABLED 16 /* deprecated */ @@ -426,7 +427,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in /* pars->flag */ #define PARS_UNEXIST 1 #define PARS_NO_DISP 2 -#define PARS_STICKY 4 +//#define PARS_STICKY 4 #define PARS_REKEY 8 /* pars->alive */ diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 2525209c3be..4a23605c717 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -643,12 +643,6 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_struct_sdna(srna, "ParticleData"); RNA_def_struct_ui_text(srna, "Particle", "Particle in a particle system."); - prop= RNA_def_property(srna, "stick_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "stick_ob"); - RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Stick Object", "Object that particle sticks to when dead"); - /* Particle State & Previous State */ prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "state.co"); @@ -693,24 +687,6 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "keys", "totkey"); RNA_def_property_struct_type(prop, "ParticleKey"); RNA_def_property_ui_text(prop, "Keyed States", ""); - - /* Random variables */ - - prop= RNA_def_property(srna, "random_rotation", PROP_FLOAT, PROP_QUATERNION); - RNA_def_property_float_sdna(prop, NULL, "r_rot"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random Rotation", ""); - - prop= RNA_def_property(srna, "random_a_velocity", PROP_FLOAT, PROP_VELOCITY); - RNA_def_property_float_sdna(prop, NULL, "r_ave"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random Angular Velocity", ""); - - prop= RNA_def_property(srna, "random_velocity", PROP_FLOAT, PROP_VELOCITY); - RNA_def_property_float_sdna(prop, NULL, "r_ve"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random Velocity", ""); - // // float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ // /* face normal for volume emission */ @@ -733,18 +709,12 @@ static void rna_def_particle(BlenderRNA *brna) // RNA_def_property_range(prop, lowerLimitf, upperLimitf); RNA_def_property_ui_text(prop, "Size", ""); - prop= RNA_def_property(srna, "size_multiplier", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sizemul"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Size Multiplier", ""); - // // int num; /* index to vert/edge/face */ // int num_dmcache; /* index to derived mesh data (face) to avoid slow lookups */ // int pad; // // int totkey; -// int bpi; /* softbody body point start index */ /* flag */ prop= RNA_def_property(srna, "unexist", PROP_BOOLEAN, PROP_NONE); @@ -755,10 +725,6 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_NO_DISP); RNA_def_property_ui_text(prop, "no_disp", ""); - prop= RNA_def_property(srna, "sticky", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_STICKY); - RNA_def_property_ui_text(prop, "sticky", ""); - prop= RNA_def_property(srna, "rekey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_REKEY); RNA_def_property_ui_text(prop, "rekey", ""); @@ -942,13 +908,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Even Distribution", "Use even distribution from faces based on face areas or edge lengths."); RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "sticky", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_STICKY); - RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); - RNA_def_property_ui_text(prop, "Sticky", "Particles stick to collided objects if they die in the collision."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - + prop= RNA_def_property(srna, "die_on_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index cf6246e3641..df99d5f2843 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1743,8 +1743,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem pa_size = pa->size; - r_tilt = 1.0f + pa->r_ave[0]; - r_length = 0.5f * (1.0f + pa->r_ave[1]); + BLI_srandom(psys->seed+a); + + r_tilt = 2.0f*(BLI_frand() - 0.5f); + r_length = BLI_frand(); if(path_nbr) { cache = psys->pathcache[a]; -- cgit v1.2.3 From c802d187e5810441545e08dbf1b7d63a71c21f88 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 4 Sep 2009 23:20:45 +0000 Subject: Comment out line so build does not crash due to NULL pointer. --- source/blender/makesrna/intern/rna_space.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 0ac7fa40727..542f6e2aeda 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1219,7 +1219,7 @@ static void rna_def_console_line(BlenderRNA *brna) srna = RNA_def_struct(brna, "ConsoleLine", NULL); RNA_def_struct_ui_text(srna, "Console Input", "Input line for the interactive console."); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); + // XXX using non-inited "prop", uh? RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); prop= RNA_def_property(srna, "line", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_ConsoleLine_line_get", "rna_ConsoleLine_line_length", "rna_ConsoleLine_line_set"); -- cgit v1.2.3 From fc8ba755bd1f9171064528761934e11ca43918ce Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 4 Sep 2009 23:22:46 +0000 Subject: * fix linking order. NOTE: this needs changes to stubs.c, but need to check with ideasman_42 how to fix with cmake. Probably linking order issues, but stubs.c currently generates warnings for msvc (redefinition of funcs) and errors for mingw (same redefinitions). Removing the offending lines from stubs.c fixes that. --- source/blender/avi/SConscript | 3 +-- source/blender/blenkernel/SConscript | 2 +- source/blender/blenlib/SConscript | 2 +- source/blender/blenloader/SConscript | 2 +- source/blender/imbuf/SConscript | 2 +- source/blender/makesrna/SConscript | 2 +- source/blender/python/SConscript | 4 ++-- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/source/blender/avi/SConscript b/source/blender/avi/SConscript index f6e5b787b58..61385958a84 100644 --- a/source/blender/avi/SConscript +++ b/source/blender/avi/SConscript @@ -1,5 +1,4 @@ #!/usr/bin/python -#Import ('extra_includes') Import ('env') sources = env.Glob('intern/*.c') @@ -7,4 +6,4 @@ sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc' incs += ' ' + env['BF_JPEG_INC'] -env.BlenderLib ('bf_avi', sources, Split(incs), [], libtype=['core'], priority = [185] ) +env.BlenderLib ('bf_avi', sources, Split(incs), [], libtype=['core'], priority = [190] ) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 0c7922de6ff..f000f778dcb 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -65,4 +65,4 @@ if env['WITH_BF_LCMS']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [165] ) +env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [166] ) diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 3d7d6b63e64..65bd65bdc35 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -16,4 +16,4 @@ if env['OURPLATFORM'] == 'linux2': if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core'], priority = [180], compileflags =cflags ) +env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core'], priority = [363], compileflags =cflags ) diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 0a9b8d05747..00e102c686c 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -11,4 +11,4 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] -env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core'], priority = [135] ) +env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core'], priority = [167] ) diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index 9da0cf21596..cdc1a5f5257 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -35,4 +35,4 @@ if env['WITH_BF_QUICKTIME']: incs += ' ../quicktime ' + env['BF_QUICKTIME_INC'] defs.append('WITH_QUICKTIME') -env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [190] ) +env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [185] ) diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 80abd4fda61..482c9ce7afd 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -37,4 +37,4 @@ if env['WITH_BF_LCMS']: if env['WITH_BF_GAMEENGINE']: defs.append('GAMEBLENDER=1') -env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core'], priority = [195] ) +env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core'], priority = [165] ) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index d44cf762a0f..2601626851e 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -13,9 +13,9 @@ defs = [] if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [140]) +env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) # generic sources = env.Glob('generic/*.c') -env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) # ketsji is 360 +env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [362]) # ketsji is 360 -- cgit v1.2.3 From 9216efcba2a5c62b081872da3fbd9c59524685bf Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 5 Sep 2009 01:58:02 +0000 Subject: == SCons == * bring back 'player' libtype, after investigation with ideasman. scons/mingw works nicely, for some reason msvc fails to link still, will look further into it. --- SConstruct | 2 +- extern/binreloc/SConscript | 2 +- extern/bullet2/src/SConscript | 16 ++++++++-------- extern/glew/SConscript | 2 +- extern/libopenjpeg/SConscript | 4 ++-- intern/audaspace/SConscript | 2 +- intern/ghost/SConscript | 2 +- intern/guardedalloc/SConscript | 2 +- intern/iksolver/SConscript | 2 +- intern/memutil/SConscript | 2 +- intern/moto/SConscript | 2 +- intern/string/SConscript | 2 +- source/blender/avi/SConscript | 2 +- source/blender/blenfont/SConscript | 2 +- source/blender/blenkernel/SConscript | 2 +- source/blender/blenlib/SConscript | 2 +- source/blender/blenloader/SConscript | 2 +- source/blender/gpu/SConscript | 2 +- source/blender/imbuf/SConscript | 2 +- source/blender/imbuf/intern/cineon/SConscript | 2 +- source/blender/imbuf/intern/dds/SConscript | 2 +- source/blender/imbuf/intern/openexr/SConscript | 2 +- source/blender/makesdna/SConscript | 2 +- source/blender/makesrna/SConscript | 2 +- source/blender/nodes/SConscript | 8 ++++---- source/blender/python/SConscript | 4 ++-- source/blender/quicktime/SConscript | 4 ++-- source/blender/readblenfile/SConscript | 2 +- source/blenderplayer/bad_level_call_stubs/SConscript | 2 +- source/gameengine/BlenderRoutines/SConscript | 2 +- source/gameengine/Converter/SConscript | 2 +- source/gameengine/Expressions/SConscript | 2 +- source/gameengine/GameLogic/SConscript | 2 +- source/gameengine/GamePlayer/common/SConscript | 2 +- source/gameengine/GamePlayer/ghost/SConscript | 2 +- source/gameengine/Ketsji/KXNetwork/SConscript | 2 +- source/gameengine/Ketsji/SConscript | 2 +- source/gameengine/Network/LoopBackNetwork/SConscript | 2 +- source/gameengine/Network/SConscript | 2 +- source/gameengine/Physics/Bullet/SConscript | 2 +- source/gameengine/Physics/Dummy/SConscript | 2 +- source/gameengine/Physics/common/SConscript | 2 +- .../Rasterizer/RAS_OpenGLRasterizer/SConscript | 2 +- source/gameengine/Rasterizer/SConscript | 2 +- source/gameengine/SceneGraph/SConscript | 2 +- source/gameengine/VideoTexture/SConscript | 2 +- source/kernel/SConscript | 2 +- 47 files changed, 60 insertions(+), 60 deletions(-) diff --git a/SConstruct b/SConstruct index f322ae27e06..12aa37772da 100644 --- a/SConstruct +++ b/SConstruct @@ -404,7 +404,7 @@ if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') - playerlist = playerlist[0:2] + [mainlist[0]] + mainlist[2:] + [playerlist[2]] + #playerlist = playerlist[0:2] + [mainlist[0]] + mainlist[2:] + [playerlist[2]] env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') ##### Now define some targets diff --git a/extern/binreloc/SConscript b/extern/binreloc/SConscript index 98d7adb2d1e..331b70a4ebc 100644 --- a/extern/binreloc/SConscript +++ b/extern/binreloc/SConscript @@ -9,5 +9,5 @@ cflags = [] sources = ['binreloc.c'] incs = 'include' -env.BlenderLib ( 'extern_binreloc', sources, Split(incs), Split(defs), libtype=['extern'], priority=[36], compileflags = cflags) +env.BlenderLib ( 'extern_binreloc', sources, Split(incs), Split(defs), libtype=['extern','player'], priority=[36,225], compileflags = cflags) diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript index 319cc57ce55..3d0c645e7a0 100644 --- a/extern/bullet2/src/SConscript +++ b/extern/bullet2/src/SConscript @@ -35,11 +35,11 @@ softbody_src = env.Glob("BulletSoftBody/*.cpp") incs = '. BulletCollision BulletDynamics LinearMath BulletSoftBody' -env.BlenderLib ( libname = 'extern_bullet2linmath', sources=linearmath_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[20], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2dynamics', sources=bulletdyn_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[19], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2collision_broadphase', sources=collision_broadphase_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[25], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2collision_dispatch', sources=collision_dispatch_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[20], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2collision_gimpact', sources=collision_gimpact_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[20], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2collision_shapes', sources=collision_shapes_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[20], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2collision_narrowphase', sources=collision_narrowphase_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[20], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2softbody', sources=softbody_src, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[18], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2linmath', sources=linearmath_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2dynamics', sources=bulletdyn_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[19,136], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2collision_broadphase', sources=collision_broadphase_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[25,145], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2collision_dispatch', sources=collision_dispatch_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,138], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2collision_gimpact', sources=collision_gimpact_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,138], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2collision_shapes', sources=collision_shapes_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,138], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2collision_narrowphase', sources=collision_narrowphase_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,138], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2softbody', sources=softbody_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[18,135], compileflags=cflags ) diff --git a/extern/glew/SConscript b/extern/glew/SConscript index b83525daffe..81a2fc67ccc 100644 --- a/extern/glew/SConscript +++ b/extern/glew/SConscript @@ -9,4 +9,4 @@ sources = ['src/glew.c'] defs = '' incs = 'include' -env.BlenderLib ( 'extern_glew', sources, Split(incs), Split(defs), libtype=['extern'], priority=[50]) +env.BlenderLib ( 'extern_glew', sources, Split(incs), Split(defs), libtype=['extern','player'], priority=[50,230]) diff --git a/extern/libopenjpeg/SConscript b/extern/libopenjpeg/SConscript index 693fee15c91..da661739783 100644 --- a/extern/libopenjpeg/SConscript +++ b/extern/libopenjpeg/SConscript @@ -24,5 +24,5 @@ if not env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): oj_env.BlenderLib ( libname='extern_openjpeg', sources=sources, includes=Split(incs), defines=defs, - libtype=['extern'], - priority=[10], compileflags = flags) + libtype=['extern','player'], + priority=[10,185], compileflags = flags) diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript index 0dfd0bb9e3a..025fa5a2379 100644 --- a/intern/audaspace/SConscript +++ b/intern/audaspace/SConscript @@ -31,4 +31,4 @@ if env['WITH_BF_SNDFILE']: incs += ' sndfile ' + env['BF_SNDFILE_INC'] defs.append('WITH_SNDFILE') -env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern'], priority = [25] ) +env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] ) diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 9de82ac44fb..48009152699 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -29,4 +29,4 @@ else: incs = '. ../string ' + env['BF_OPENGL_INC'] if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'): incs = env['BF_WINTAB_INC'] + ' ' + incs -env.BlenderLib ('bf_ghost', sources, Split(incs), defines=['_USE_MATH_DEFINES'], libtype=['intern'], priority = [40] ) +env.BlenderLib ('bf_ghost', sources, Split(incs), defines=['_USE_MATH_DEFINES'], libtype=['intern','player'], priority = [40,15] ) diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript index 8927bef2efc..2ee0f84b464 100644 --- a/intern/guardedalloc/SConscript +++ b/intern/guardedalloc/SConscript @@ -5,4 +5,4 @@ Import('env') sources = env.Glob('intern/*.c') incs = '.' -env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern'], priority = [5] ) +env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern','player'], priority = [5,150] ) diff --git a/intern/iksolver/SConscript b/intern/iksolver/SConscript index df8c10b7302..7adb2d50893 100644 --- a/intern/iksolver/SConscript +++ b/intern/iksolver/SConscript @@ -5,5 +5,5 @@ sources = env.Glob('intern/*.cpp') incs = 'intern ../moto/include ../memutil' -env.BlenderLib ('bf_IK', sources, Split(incs), [], libtype=['intern'], priority=[100] ) +env.BlenderLib ('bf_IK', sources, Split(incs), [], libtype=['intern','player'], priority=[100,90] ) diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript index 55c314d5211..318d4a3997e 100644 --- a/intern/memutil/SConscript +++ b/intern/memutil/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp') incs = '. ..' -env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern'], priority = [0] ) +env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern','player'], priority = [0,155] ) diff --git a/intern/moto/SConscript b/intern/moto/SConscript index a730e6de535..d9bbafe4623 100644 --- a/intern/moto/SConscript +++ b/intern/moto/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp') incs = 'include' -env.BlenderLib ('bf_moto', sources, Split(incs), [], libtype=['intern'], priority = [130] ) +env.BlenderLib ('bf_moto', sources, Split(incs), [], libtype=['intern','player'], priority = [130,95] ) diff --git a/intern/string/SConscript b/intern/string/SConscript index 8973ac88a66..4aca220183c 100644 --- a/intern/string/SConscript +++ b/intern/string/SConscript @@ -4,4 +4,4 @@ Import ('env') sources = env.Glob('intern/*.cpp') incs = '.' -env.BlenderLib ('bf_string', sources, Split(incs), [], libtype=['intern'], priority = [50] ) +env.BlenderLib ('bf_string', sources, Split(incs), [], libtype=['intern','player'], priority = [50,10] ) diff --git a/source/blender/avi/SConscript b/source/blender/avi/SConscript index 61385958a84..0bf8c3c74db 100644 --- a/source/blender/avi/SConscript +++ b/source/blender/avi/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc' incs += ' ' + env['BF_JPEG_INC'] -env.BlenderLib ('bf_avi', sources, Split(incs), [], libtype=['core'], priority = [190] ) +env.BlenderLib ('bf_avi', sources, Split(incs), [], libtype=['core','player'], priority = [190,120] ) diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index fa6fa19a9ef..d070d985247 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/SConscript @@ -14,4 +14,4 @@ defs = '' if sys.platform == 'win32': defs += ' _WIN32 USE_GETTEXT_DLL' -env.BlenderLib ( 'bf_blenfont', sources, Split(incs), Split(defs), libtype=['core'], priority=[210] ) +env.BlenderLib ( 'bf_blenfont', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[210,210] ) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index f000f778dcb..1f42390504d 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -65,4 +65,4 @@ if env['WITH_BF_LCMS']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [166] ) +env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [166,25] ) diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 65bd65bdc35..fc586de5085 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -16,4 +16,4 @@ if env['OURPLATFORM'] == 'linux2': if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core'], priority = [363], compileflags =cflags ) +env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core','player'], priority = [363,170], compileflags =cflags ) diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 00e102c686c..88d345290e5 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -11,4 +11,4 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] -env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core'], priority = [167] ) +env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [167,30] ) diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index b45547e359c..e55fbe973f8 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -8,4 +8,4 @@ incs += ' #/extern/glew/include #intern/guardedalloc ../imbuf .' incs += ' ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core'], priority=[160] ) +env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core','player'], priority=[160,110] ) diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index cdc1a5f5257..6052b344da7 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -35,4 +35,4 @@ if env['WITH_BF_QUICKTIME']: incs += ' ../quicktime ' + env['BF_QUICKTIME_INC'] defs.append('WITH_QUICKTIME') -env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [185] ) +env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [185,115] ) diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript index 371e4cff9eb..d9c8ab14d35 100644 --- a/source/blender/imbuf/intern/cineon/SConscript +++ b/source/blender/imbuf/intern/cineon/SConscript @@ -14,4 +14,4 @@ incs = ['.', defs = [] -env.BlenderLib ('bf_cineon', source_files, incs, defs, libtype=['core'], priority = [220]) +env.BlenderLib ('bf_cineon', source_files, incs, defs, libtype=['core','player'], priority = [220,175]) diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript index 6cabc3f7d79..0b7fd50e317 100644 --- a/source/blender/imbuf/intern/dds/SConscript +++ b/source/blender/imbuf/intern/dds/SConscript @@ -16,4 +16,4 @@ incs = ['.', defs = ['WITH_DDS'] -env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core'], priority = [230]) +env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core','player'], priority = [230,190]) diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript index 729619c963b..f504c503109 100644 --- a/source/blender/imbuf/intern/openexr/SConscript +++ b/source/blender/imbuf/intern/openexr/SConscript @@ -15,4 +15,4 @@ incs += Split(env['BF_OPENEXR_INC']) defs = ['WITH_OPENEXR'] -env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core'], priority = [225]) +env.BlenderLib ('bf_openexr', source_files, incs, defs, libtype=['core','player'], priority = [225,180]) diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript index 1cb61f59121..c3d39783b00 100644 --- a/source/blender/makesdna/SConscript +++ b/source/blender/makesdna/SConscript @@ -8,4 +8,4 @@ objs += o incs = '#/intern/guardedalloc .' -env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core'], priority = [215] ) +env.BlenderLib ( 'bf_dna', objs, Split(incs), [], libtype=['core','player'], priority = [215,200] ) diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 482c9ce7afd..c2790927cef 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -37,4 +37,4 @@ if env['WITH_BF_LCMS']: if env['WITH_BF_GAMEENGINE']: defs.append('GAMEBLENDER=1') -env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core'], priority = [165] ) +env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core','player'], priority = [165,20] ) diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 0b35db3b4b7..771ce42e1dc 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -38,7 +38,7 @@ if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ' + env['BF_QUICKTIME_INC'] -env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [190] ) -env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = defs, libtype=['core'], priority = [175] ) -env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = defs, libtype=['core'], priority = [175] ) -env.BlenderLib ( libname = 'bf_texnodes', sources = texsources, includes = Split(incs), defines = defs, libtype=['core'], priority = [175] ) +env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [190,105] ) +env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] ) +env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] ) +env.BlenderLib ( libname = 'bf_texnodes', sources = texsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] ) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 2601626851e..ca742a3646a 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -13,9 +13,9 @@ defs = [] if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc','win64-vc') and env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [361]) +env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [361,160]) # generic sources = env.Glob('generic/*.c') -env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [362]) # ketsji is 360 +env.BlenderLib( libname = 'bf_gen_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core','player'], priority = [362,165]) # ketsji is 360 diff --git a/source/blender/quicktime/SConscript b/source/blender/quicktime/SConscript index 5f3995a410a..10e88a8f461 100644 --- a/source/blender/quicktime/SConscript +++ b/source/blender/quicktime/SConscript @@ -19,7 +19,7 @@ incs = ['.', incs.append(env['BF_QUICKTIME_INC']) -types = ['core'] -priorities = [200] +types = ['core','player'] +priorities = [200,235] env.BlenderLib ('bf_quicktime', sources=source_files, includes=incs, defines=['WITH_QUICKTIME'], libtype=types, priority=priorities) diff --git a/source/blender/readblenfile/SConscript b/source/blender/readblenfile/SConscript index c8189501d4b..57ee1866263 100644 --- a/source/blender/readblenfile/SConscript +++ b/source/blender/readblenfile/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('intern/*.c') incs = '. ../blenloader ../blenloader/intern ../blenkernel ../blenlib ../makesdna ../../kernel/gen_messaging' -env.BlenderLib ( 'bf_readblenfile', sources, Split(incs), [], libtype=['core'], priority = [0] ) +env.BlenderLib ( 'bf_readblenfile', sources, Split(incs), [], libtype=['core','player'], priority = [0,195] ) diff --git a/source/blenderplayer/bad_level_call_stubs/SConscript b/source/blenderplayer/bad_level_call_stubs/SConscript index ce502af57be..ab98e984cef 100644 --- a/source/blenderplayer/bad_level_call_stubs/SConscript +++ b/source/blenderplayer/bad_level_call_stubs/SConscript @@ -10,4 +10,4 @@ defs = '' if env['WITH_BF_INTERNATIONAL']: defs += 'WITH_FREETYPE2' -env.BlenderLib ('blenkernel_blc', sources = Split(sources), includes=Split(incs), defines=Split(defs), libtype=['player'],priority=[145] ) +env.BlenderLib ('blenkernel_blc', sources = Split(sources), includes=Split(incs), defines=Split(defs), libtype=['player'],priority=[220] ) diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index cfb5b0ef525..ad6f9f23fce 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -28,4 +28,4 @@ incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core'], priority=[300] , cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core','player'], priority=[300,35] , cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index bf2dfa5e659..2d126310475 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -23,4 +23,4 @@ incs += ' #source/blender/makesrna' incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] -env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core'], priority=[305], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,40], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index cbf33f39568..c819bfb0d3e 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('*.cpp') incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core'], priority = [360], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,80], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index f456f4125ab..1530c71c7f3 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -21,4 +21,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['BF_DEBUG']: defs.append('_DEBUG') -env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core'], priority=[330], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_logic', sources, Split(incs), defs, libtype=['core','player'], priority=[330,65], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 6f37c2f769e..dd5a48c2b55 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -62,4 +62,4 @@ incs += Split(env['BF_PYTHON_INC']) incs += Split(env['BF_PNG_INC']) incs += Split(env['BF_ZLIB_INC']) -env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype=['player'], priority=[15], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype=['player'], priority=[5], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 6c71eafa1dc..fdd7792b72a 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -46,4 +46,4 @@ defs = [] if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') -env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = defs, libtype=['player'],priority=[5], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = defs, libtype=['player'],priority=[0], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 6429bd76a37..8f88511acca 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -9,4 +9,4 @@ incs += ' #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=[],libtype=['core'], priority=[400], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_network', Split(sources), Split(incs), defines=[],libtype=['core','player'], priority=[400,125], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 122b77e0173..5f38020780b 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -33,4 +33,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['BF_DEBUG']: defs.append('_DEBUG') # for Python -env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core'], priority=[320], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_ketsji', sources, Split(incs), defs, libtype=['core','player'], priority=[320,45], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript index 2c27ee707f0..dd23e1327eb 100644 --- a/source/gameengine/Network/LoopBackNetwork/SConscript +++ b/source/gameengine/Network/LoopBackNetwork/SConscript @@ -5,4 +5,4 @@ sources = 'NG_LoopBackNetworkDeviceInterface.cpp' incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Network' -env.BlenderLib ( 'bf_loopbacknetwork', Split(sources), Split(incs), defines=[],libtype=['core'], priority=[400] ) +env.BlenderLib ( 'bf_loopbacknetwork', Split(sources), Split(incs), defines=[],libtype=['core','player'], priority=[400,135] ) diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index f584503e109..3883dc71c9c 100644 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/SConscript @@ -5,4 +5,4 @@ sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_Netw incs = '. #source/kernel/gen_system #intern/string #intern/moto/include' -env.BlenderLib ( 'bf_ngnetwork', sources, Split(incs), [], libtype=['core'], priority=[400] ) +env.BlenderLib ( 'bf_ngnetwork', sources, Split(incs), [], libtype=['core','player'], priority=[400,130] ) diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index baba40bcdc7..49f2af1b001 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -21,4 +21,4 @@ incs += ' #intern/guardedalloc' incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core'], priority=[350], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,50], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript index f4444cf6746..dc76e8046a0 100644 --- a/source/gameengine/Physics/Dummy/SConscript +++ b/source/gameengine/Physics/Dummy/SConscript @@ -5,4 +5,4 @@ sources = 'DummyPhysicsEnvironment.cpp' incs = '. ../common' -env.BlenderLib ( 'bf_dummy', Split(sources), Split(incs), [], libtype=['core'], priority=[350] ) +env.BlenderLib ( 'bf_dummy', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,60] ) diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index b9adbd7210a..719c028ee8f 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/SConscript @@ -5,4 +5,4 @@ sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp P incs = '. ../Dummy #intern/moto/include' -env.BlenderLib ( 'bf_physics_common', Split(sources), Split(incs), [], libtype=['core'], priority=[360], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_physics_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360,55], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index b1e5289c14c..fb4c685f8d3 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -8,4 +8,4 @@ incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] incs += ' #source/blender/gameengine/Ketsji #source/gameengine/SceneGraph #source/blender/makesdna #source/blender/blenkernel' incs += ' #intern/guardedalloc #source/blender/blenlib' -env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core'], priority=[350], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,75], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index 064736bcc88..dbec2d92e31 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -7,4 +7,4 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core'], priority=[350], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,70], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index 79bf3033fa1..2a33cd67b5e 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/SConscript @@ -6,4 +6,4 @@ sources = env.Glob('*.cpp') incs = '. #intern/moto/include' -env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core'], priority=[325], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,85], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 0b35c019178..0d3e495f3e2 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -27,4 +27,4 @@ if env['WITH_BF_FFMPEG']: incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC'] defs.append('__STDC_CONSTANT_MACROS') -env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core'], priority=[300], cxx_compileflags=env['BGE_CXXFLAGS']) +env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300,205], cxx_compileflags=env['BGE_CXXFLAGS']) diff --git a/source/kernel/SConscript b/source/kernel/SConscript index 746fb60d4ff..3110f46cfad 100644 --- a/source/kernel/SConscript +++ b/source/kernel/SConscript @@ -7,4 +7,4 @@ sources += ' gen_system/SYS_System.cpp' incs = 'gen_messaging gen_system #/intern/string #/intern/moto/include #/source/blender/blenloader ' -env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core'], priority = [400] ) +env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core','player'], priority = [400,100] ) -- cgit v1.2.3 From d56f826ea9844a0289a216df6f62d28d123f0888 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 5 Sep 2009 02:13:13 +0000 Subject: remove unnecessary semi-colons --- source/blenderplayer/bad_level_call_stubs/stubs.c | 42 +++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 5ddafca5340..c1585a71ac1 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -177,24 +177,24 @@ void WM_operator_bl_idname(char *to, const char *from){} short insert_keyframe (struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag){return 0;} /* smoke */ -void lzo1x_1_compress(void) {return;}; -void LzmaCompress(void) {return;}; -void smoke_export(void) {return;}; -void lzo1x_decompress(void) {return;}; -void LzmaUncompress(void) {return;}; -void smoke_init(void) {return;}; -void smoke_turbulence_init(void) {return;}; -void smoke_turbulence_initBlenderRNA(void) {return;}; -void smoke_initBlenderRNA(void) {return;}; -void smoke_free(void) {return;}; -void smoke_turbulence_free(void) {return;}; -void smoke_turbulence_step(void) {return;}; -void smoke_dissolve(void) {return;}; -void smoke_get_density(void) {return;}; -void smoke_get_heat(void) {return;}; -void smoke_get_velocity_x(void) {return;}; -void smoke_get_velocity_y(void) {return;}; -void smoke_get_velocity_z(void) {return;}; -void smoke_get_obstacle(void) {return;}; -void smoke_get_index(void) {return;}; -void smoke_step(void) {return;}; +void lzo1x_1_compress(void) {return;} +void LzmaCompress(void) { return; } +void smoke_export(void) {return;} +void lzo1x_decompress(void) {return;} +void LzmaUncompress(void) {return;} +void smoke_init(void) {return;} +void smoke_turbulence_init(void) {return;} +void smoke_turbulence_initBlenderRNA(void) {return;} +void smoke_initBlenderRNA(void) {return;} +void smoke_free(void) {return;} +void smoke_turbulence_free(void) {return;} +void smoke_turbulence_step(void) {return;} +void smoke_dissolve(void) {return;} +void smoke_get_density(void) {return;} +void smoke_get_heat(void) {return;} +void smoke_get_velocity_x(void) {return;} +void smoke_get_velocity_y(void) {return;} +void smoke_get_velocity_z(void) {return;} +void smoke_get_obstacle(void) {return;} +void smoke_get_index(void) {return;} +void smoke_step(void) {return;} -- cgit v1.2.3 From 668b92dfedca02959bbe3467a9f62ca597987544 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 5 Sep 2009 02:14:45 +0000 Subject: * fix lib list creation. now blenderplayer links fine with both scons/mingw and scons/msvc --- SConstruct | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 12aa37772da..83ec6c1b718 100644 --- a/SConstruct +++ b/SConstruct @@ -404,7 +404,8 @@ if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']: env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender') if env['WITH_BF_PLAYER']: playerlist = B.create_blender_liblist(env, 'player') - #playerlist = playerlist[0:2] + [mainlist[0]] + mainlist[2:] + [playerlist[2]] + playerlist += B.create_blender_liblist(env, 'intern') + playerlist += B.create_blender_liblist(env, 'extern') env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer') ##### Now define some targets -- cgit v1.2.3 From 05c44056dc48bf718475a1e98c9abbd6cc00a535 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 5 Sep 2009 04:04:51 +0000 Subject: 2.5 - Demo of how to get node attributes animateable * Made sure that nodes have a working 'path' function (needed for any tools that will resolve paths needed for animating properties) * Replaced all the UI button controls for a single node (Vector Blur) with relevant RNA buttons which can be animated. There are probably some even nicer ways to do this (i.e. using layout engine for drawing all sets of buttons), though this is the easiest way forward in the immediate future. Anyways, if people are interested in getting this working, they will need to spend time to replace all the necessary button calls :) --- source/blender/editors/space_node/drawnode.c | 98 ++++++--------------------- source/blender/makesrna/intern/rna_nodetree.c | 10 +++ 2 files changed, 29 insertions(+), 79 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 1fb8cb3452b..2f64108384e 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1459,26 +1459,28 @@ static int node_composit_buts_lensdist(uiBlock *block, bNodeTree *ntree, bNode * static int node_composit_buts_vecblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { if(block) { - NodeBlurData *nbd= node->storage; + PointerRNA ptr; short dy= butr->ymin; short dx= (butr->xmax-butr->xmin); - uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_NODE_EXEC, "Samples:", - butr->xmin, dy+76, dx, 19, - &nbd->samples, 1, 256, 0, 0, "Amount of samples"); - uiDefButS(block, NUM, B_NODE_EXEC, "MinSpeed:", - butr->xmin, dy+57, dx, 19, - &nbd->minspeed, 0, 1024, 0, 0, "Minimum speed for a pixel to be blurred, used to separate background from foreground"); - uiDefButS(block, NUM, B_NODE_EXEC, "MaxSpeed:", - butr->xmin, dy+38, dx, 19, - &nbd->maxspeed, 0, 1024, 0, 0, "If not zero, maximum speed in pixels"); - uiDefButF(block, NUM, B_NODE_EXEC, "Blur:", - butr->xmin, dy+19, dx, 19, - &nbd->fac, 0.0f, 2.0f, 10, 2, "Scaling factor for motion vectors, actually 'shutter speed' in frames"); - uiDefButS(block, TOG, B_NODE_EXEC, "Curved", - butr->xmin, dy, dx, 19, - &nbd->curved, 0.0f, 2.0f, 10, 2, "Interpolate between frames in a bezier curve, rather than linearly"); + RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr); + + uiBlockBeginAlign(block); + uiDefButR(block, NUM, B_NODE_EXEC, NULL, + butr->xmin, dy+76, dx, 19, + &ptr, "samples", 0, 1, 256, 0, 0, NULL); + uiDefButR(block, NUM, B_NODE_EXEC, NULL, + butr->xmin, dy+57, dx, 19, + &ptr, "min_speed", 0, 0, 1024, 0, 0, NULL); + uiDefButR(block, NUM, B_NODE_EXEC, NULL, + butr->xmin, dy+38, dx, 19, + &ptr, "max_speed", 0, 0, 1024, 0, 0, NULL); + uiDefButR(block, NUM, B_NODE_EXEC, "Blur", + butr->xmin, dy+19, dx, 19, + &ptr, "factor", 0, 0, 2, 10, 2, NULL); + uiDefButR(block, TOG, B_NODE_EXEC, NULL, + butr->xmin, dy, dx, 19, + &ptr, "curved", 0, 0, 2, 10, 2, NULL); uiBlockEndAlign(block); } return 95; @@ -2625,66 +2627,4 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, do_shaded); } -#if 0 - -static void nodes_panel_gpencil(short cntrl) // NODES_HANDLER_GREASEPENCIL -{ - uiBlock *block; - SpaceNode *snode; - - snode= curarea->spacedata.first; - - block= uiNewBlock(&curarea->uiblocks, "nodes_panel_gpencil", UI_EMBOSS, UI_HELV, curarea->win); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(NODES_HANDLER_GREASEPENCIL); // for close and esc - if (uiNewPanel(curarea, block, "Grease Pencil", "SpaceNode", 100, 30, 318, 204)==0) return; - - /* we can only really draw stuff if there are nodes (otherwise no events are handled */ - if (snode->nodetree == NULL) - return; - - /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */ - if (snode->flag & SNODE_DISPGP) { - if (snode->gpd == NULL) - gpencil_data_setactive(curarea, gpencil_data_addnew()); - } - - if (snode->flag & SNODE_DISPGP) { - bGPdata *gpd= snode->gpd; - short newheight; - - /* this is a variable height panel, newpanel doesnt force new size on existing panels */ - /* so first we make it default height */ - uiNewPanelHeight(block, 204); - - /* draw button for showing gpencil settings and drawings */ - uiDefButBitS(block, TOG, SNODE_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &snode->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Node Editor (draw using Shift-LMB)"); - - /* extend the panel if the contents won't fit */ - newheight= draw_gpencil_panel(block, gpd, curarea); - uiNewPanelHeight(block, newheight); - } - else { - uiDefButBitS(block, TOG, SNODE_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &snode->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Node Editor"); - uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); - } -} -static void nodes_blockhandlers(ScrArea *sa) -{ - SpaceNode *snode= sa->spacedata.first; - short a; - - for(a=0; ablockhandler[a]) { - case NODES_HANDLER_GREASEPENCIL: - nodes_panel_gpencil(snode->blockhandler[a+1]); - break; - } - - /* clear action value for event */ - snode->blockhandler[a+1]= 0; - } - uiDrawBlocksPanels(sa, 0); -} -#endif diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 23e79831292..9062cec3828 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -57,6 +57,15 @@ StructRNA *rna_Node_refine(struct PointerRNA *ptr) } } +static char *rna_Node_path(PointerRNA *ptr) +{ + bNodeTree *ntree= (bNodeTree*)ptr->id.data; + bNode *node= (bNode*)ptr->data; + int index = BLI_findindex(&ntree->nodes, node); + + return BLI_sprintfN("nodes[%d]", index); +} + #else #define MaxNodes 1000 @@ -1353,6 +1362,7 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Node", "Node in a node tree."); RNA_def_struct_sdna(srna, "bNode"); RNA_def_struct_refine_func(srna, "rna_Node_refine"); + RNA_def_struct_path_func(srna, "rna_Node_path"); prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "locx"); -- cgit v1.2.3 From 3b743ac5565663d2fd0be4bbbc92e404afafbce4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Sep 2009 09:54:01 +0000 Subject: Option to correct for 3D curve twist error. example before and after. http://www.graphicall.org/ftp/ideasman42/curve_auto_twist.png Access next to the "3D" edit button. details... - open curves use the first points orientation and minimize twist for each new segment. - cyclic curves calculate the least twist in both directions and blend between them - AxisAngleToQuat replaced inline code. - Notice the model on the right now has more even corners. added Vec3ToTangent to arithb.c. --- source/blender/blenkernel/intern/curve.c | 172 ++++++++++++++++++++++++------ source/blender/blenlib/BLI_arithb.h | 1 + source/blender/blenlib/intern/arithb.c | 13 +++ source/blender/makesdna/DNA_curve_types.h | 2 + source/blender/src/buttons_editing.c | 3 +- 5 files changed, 156 insertions(+), 35 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 0d6382a8d37..709507a9b26 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1513,7 +1513,7 @@ void makeBevelList(Object *ob) BPoint *bp; BevList *bl, *blnew, *blnext; BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; - float min, inp, x1, x2, y1, y2, vec[3]; + float min, inp, x1, x2, y1, y2, vec[3], vec_prev[3], q[4], quat[4], quat_prev[4], cross[3]; float *coord_array, *tilt_array=NULL, *radius_array=NULL, *coord_fp, *tilt_fp=NULL, *radius_fp=NULL; float *v1, *v2; struct bevelsort *sortdata, *sd, *sd1; @@ -1872,7 +1872,10 @@ void makeBevelList(Object *ob) bl= cu->bev.first; while(bl) { - if(bl->nr==2) { /* 2 pnt, treat separate */ + if(bl->nr < 2) { + /* do nothing */ + } + else if(bl->nr==2) { /* 2 pnt, treat separate */ bevp2= (BevPoint *)(bl+1); bevp1= bevp2+1; @@ -1886,68 +1889,169 @@ void makeBevelList(Object *ob) if(cu->flag & CU_3D) { /* 3D */ float quat[4], q[4]; - vec[0]= bevp1->x - bevp2->x; - vec[1]= bevp1->y - bevp2->y; - vec[2]= bevp1->z - bevp2->z; + VecSubf(vec, &bevp1->x, &bevp2->x); vectoquat(vec, 5, 1, quat); - Normalize(vec); - q[0]= (float)cos(0.5*bevp1->alfa); - x1= (float)sin(0.5*bevp1->alfa); - q[1]= x1*vec[0]; - q[2]= x1*vec[1]; - q[3]= x1*vec[2]; + AxisAngleToQuat(q, vec, bevp1->alfa); QuatMul(quat, q, quat); QuatToMat3(quat, bevp1->mat); Mat3CpyMat3(bevp2->mat, bevp1->mat); } + } /* this has to be >2 points */ + else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) { + + /* Special case, cyclic curve with no twisy. tricky... */ + + float quat[4], q[4], cross[3]; + + /* correcting a cyclic curve is more complicated, need to be corrected from both ends */ + float *quat_tmp1, *quat_tmp2; /* store a quat in the matrix temporarily */ + int iter_dir; + BevPoint *bevp_start= (BevPoint *)(bl+1); + + /* loop over the points twice, once up, once back, accumulate the quat rotations + * in both directions, then blend them in the 3rd loop and apply the tilt */ + for(iter_dir = 0; iter_dir < 2; iter_dir++) { + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + + /* Normalizes */ + Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x); + + if(bl->nr==nr+1) { /* first time */ + vectoquat(vec, 5, 1, quat); + } + else { + float angle = NormalizedVecAngle2(vec_prev, vec); + + if(angle > 0.0f) { /* otherwise we can keep as is */ + Crossf(cross, vec_prev, vec); + AxisAngleToQuat(q, cross, angle); + QuatMul(quat, q, quat_prev); + } + else { + QUATCOPY(quat, quat_prev); + } + } + QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ + VECCOPY(vec_prev, vec); + + if(iter_dir==0) { /* up, first time */ + quat_tmp1= (float *)bevp1->mat; + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } + else { /* down second time */ + quat_tmp1= ((float *)bevp1->mat)+4; + + bevp2= bevp1; + bevp1= bevp0; + bevp0--; + + /* wrap around */ + if (bevp0 < bevp_start) + bevp0= bevp_start+(bl->nr-1); + } + + QUATCOPY(quat_tmp1, quat); + } + } + + /* Now interpolate the 2 quats and apply tilt */ + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + + Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x); + + quat_tmp1= (float *)bevp1->mat; + quat_tmp2= quat_tmp1+4; + + /* blend the 2 rotations gathered from both directions */ + QuatInterpol(quat, quat_tmp1, quat_tmp2, 1.0 - (((float)nr)/bl->nr)); + + AxisAngleToQuat(q, vec, bevp1->alfa); + QuatMul(quat, q, quat); + QuatToMat3(quat, bevp1->mat); + + /* generic */ + x1= bevp1->x- bevp0->x; + x2= bevp1->x- bevp2->x; + y1= bevp1->y- bevp0->y; + y2= bevp1->y- bevp2->y; + + calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } } - else if(bl->nr>2) { + else { + /* Any curve with 3 or more points */ + bevp2= (BevPoint *)(bl+1); bevp1= bevp2+(bl->nr-1); bevp0= bevp1-1; - nr= bl->nr; - while(nr--) { - + if(cu->flag & CU_3D) { /* 3D */ - float quat[4], q[4]; - - vec[0]= bevp2->x - bevp0->x; - vec[1]= bevp2->y - bevp0->y; - vec[2]= bevp2->z - bevp0->z; - - Normalize(vec); - vectoquat(vec, 5, 1, quat); - - q[0]= (float)cos(0.5*bevp1->alfa); - x1= (float)sin(0.5*bevp1->alfa); - q[1]= x1*vec[0]; - q[2]= x1*vec[1]; - q[3]= x1*vec[2]; + /* Normalizes */ + Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x); + + if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */ + vectoquat(vec, 5, 1, quat); + } + else { + float angle = NormalizedVecAngle2(vec_prev, vec); + + if(angle > 0.0f) { /* otherwise we can keep as is */ + Crossf(cross, vec_prev, vec); + AxisAngleToQuat(q, cross, angle); + QuatMul(quat, q, quat_prev); + } + else { + QUATCOPY(quat, quat_prev); + } + } + QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ + VECCOPY(vec_prev, vec); + + AxisAngleToQuat(q, vec, bevp1->alfa); QuatMul(quat, q, quat); - QuatToMat3(quat, bevp1->mat); } - + x1= bevp1->x- bevp0->x; x2= bevp1->x- bevp2->x; y1= bevp1->y- bevp0->y; y2= bevp1->y- bevp2->y; - + calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); - - + + bevp0= bevp1; bevp1= bevp2; bevp2++; } + /* correct non-cyclic cases */ if(bl->poly== -1) { if(bl->nr>2) { diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 092ed00fbe5..63b351016d4 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -270,6 +270,7 @@ void AxisAngleToQuat(float *q, float *axis, float angle); void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]); void vectoquat(float *vec, short axis, short upflag, float *q); +void Vec3ToTangent(float *v, float *v1, float *v2, float *v3); float VecAngle2(float *v1, float *v2); float VecAngle3(float *v1, float *v2, float *v3); float NormalizedVecAngle2(float *v1, float *v2); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index ad1dc1ca12c..970d8f7d0de 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2969,6 +2969,19 @@ void VecRotToQuat( float *vec, float phi, float *quat) } } +/* get a direction from 3 vectors that wont depend + * on the distance between the points */ +void Vec3ToTangent(float *v, float *v1, float *v2, float *v3) +{ + float d_12[3], d_23[3]; + VecSubf(d_12, v2, v1); + VecSubf(d_23, v3, v2); + Normalize(d_12); + Normalize(d_23); + VecAddf(v, d_12, d_23); + Normalize(v); +} + /* Return the angle in degrees between vecs 1-2 and 2-3 in degrees If v1 is a shoulder, v2 is the elbow and v3 is the hand, this would return the angle at the elbow */ diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index f809cac037d..88c03a41160 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -205,6 +205,8 @@ typedef struct Curve { #define CU_FAST 512 /* Font: no filling inside editmode */ #define CU_RETOPO 1024 +#define CU_NO_TWIST 4096 + /* spacemode */ #define CU_LEFT 0 #define CU_MIDDLE 1 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 2f9eac67d94..1e37fd0b9f8 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3671,7 +3671,8 @@ static void editing_panel_curve_type(Object *ob, Curve *cu) uiBlockSetCol(block, TH_BUT_SETTING1); uiDefButBitS(block, TOG, CU_BACK, B_MAKEDISP, "Back", 760,115,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled back for extruded/beveled curves"); uiDefButBitS(block, TOG, CU_FRONT, B_MAKEDISP, "Front",810,115,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled front for extruded/beveled curves"); - uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,115,50,19, &cu->flag, 0, 0, 0, 0, "Allow Curve to be 3d, it doesn't fill then"); + uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,115,30,19, &cu->flag, 0, 0, 0, 0, "Allow Curve to be 3d, it doesn't fill then"); + uiDefIconButBitS(block, TOG, CU_NO_TWIST, B_MAKEDISP, ICON_AUTO, 890,115,20,19, &cu->flag, 0.0, 0.0, 0, 0, "Avoid twisting artifacts for 3D beveled/extruded curves"); } } -- cgit v1.2.3 From 08b8fc34cfc082d73e657d1c2941662c36bc3514 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Sat, 5 Sep 2009 20:12:08 +0000 Subject: Disconnect/connect hair: - Moves hair from face-space to global space and back. - Allows for editing of emitter mesh after hair combing. - Disconnect hair before doing topology changing changes in mesh edit mode, connect after changes. - Notes: * The closest location on emitter surface to the hair root is used to connect the hair. * Emitter deflection, sticky roots and add brush don't apply for disconnect hair in particle mode. - Todo for future: * Copy disconnected hair from object to another (when 2.5 has proper copy operators again). * Possible automatic disconnect/connect with topology changing operations in mesh edit mode. Other changes/fixes: - Proper subtypes for some particle mode notifiers. - Particle mode selections didn't draw correctly because of using lighting for the paths. --- release/ui/buttons_particle.py | 5 + source/blender/blenkernel/BKE_pointcache.h | 1 + source/blender/blenkernel/intern/particle.c | 8 +- source/blender/blenkernel/intern/particle_system.c | 2 +- source/blender/editors/physics/editparticle.c | 52 +++-- .../blender/editors/space_buttons/buttons_intern.h | 2 + source/blender/editors/space_buttons/buttons_ops.c | 218 +++++++++++++++++++++ .../blender/editors/space_buttons/space_buttons.c | 2 + source/blender/editors/space_view3d/drawobject.c | 18 +- .../blender/editors/space_view3d/view3d_header.c | 6 +- .../editors/transform/transform_conversions.c | 8 +- source/blender/makesrna/intern/rna_particle.c | 5 + source/blender/makesrna/intern/rna_sculpt_paint.c | 10 +- 13 files changed, 294 insertions(+), 43 deletions(-) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index f3339049962..b0051453b29 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -151,6 +151,11 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): row = split.row() row.enabled = particle_panel_enabled(psys) row.itemR(part, "hair_step") + if psys.edited==True: + if psys.global_hair: + layout.itemO("particle.connect_hair") + else: + layout.itemO("particle.disconnect_hair") elif part.type=='REACTOR': split.enabled = particle_panel_enabled(psys) split.itemR(psys, "reactor_target_object") diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 9ba34091064..b7ab07b0f91 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -192,6 +192,7 @@ typedef struct PTCacheUndo { struct ParticleData *particles; struct KDTree *emitter_field; float *emitter_cosnos; + int psys_flag; /* cache stuff */ struct ListBase mem_cache; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 81eb0b79c40..0ba2f357a1f 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -418,7 +418,7 @@ void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit) edit->pathcache= NULL; edit->totcached= 0; } - else { + if(psys) { psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs); psys->pathcache= NULL; psys->totcached= 0; @@ -2676,7 +2676,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra baked = psys->pointcache->flag & PTCACHE_BAKED; /* clear out old and create new empty path cache */ - psys_free_path_cache(psys, NULL); + psys_free_path_cache(psys, psys->edit); cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1); if(psys->soft && psys->softflag & OB_SB_ENABLE) { @@ -2891,7 +2891,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf if(!cache || edit->totpoint != edit->totcached) { /* clear out old and create new empty path cache */ - psys_free_path_cache(NULL, edit); + psys_free_path_cache(edit->psys, edit); cache= edit->pathcache= psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, steps+1); } @@ -2946,7 +2946,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); /* non-hair points are allready in global space */ - if(psys) + if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) Mat4MulVecfl(hairmat, result.co); VECCOPY(ca->co, result.co); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index eb570ba287c..1931b89af38 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -158,7 +158,7 @@ void psys_reset(ParticleSystem *psys, int mode) psys->totchild= 0; /* reset path cache */ - psys_free_path_cache(psys, NULL); + psys_free_path_cache(psys, psys->edit); /* reset point cache */ psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID; diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index bc48d8f4f55..0f5e677b912 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -555,7 +555,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected Mat4One(mat); LOOP_VISIBLE_POINTS { - if(edit->psys) { + if(edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, psys->particles + p, mat); Mat4Invert(imat,mat); } @@ -812,7 +812,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) float *vec, *nor, dvec[3], dot, dist_1st; float hairimat[4][4], hairmat[4][4]; - if(edit==NULL || edit->psys==NULL || (pset->flag & PE_DEFLECT_EMITTER)==0) + if(edit==NULL || edit->psys==NULL || (pset->flag & PE_DEFLECT_EMITTER)==0 || (edit->psys->flag & PSYS_GLOBAL_HAIR)) return; psys = edit->psys; @@ -876,6 +876,9 @@ void PE_apply_lengths(Scene *scene, PTCacheEdit *edit) if(edit==0 || (pset->flag & PE_KEEP_LENGTHS)==0) return; + if(edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) + return; + LOOP_EDITED_POINTS { LOOP_KEYS { if(k) { @@ -899,10 +902,10 @@ static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit) float dv1[3]= {0.0f, 0.0f, 0.0f}; float dv2[3]= {0.0f, 0.0f, 0.0f}; - if(edit==0) + if(edit==0 || (pset->flag & PE_KEEP_LENGTHS)==0) return; - if((pset->flag & PE_KEEP_LENGTHS)==0) + if(edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) return; LOOP_EDITED_POINTS { @@ -1057,11 +1060,13 @@ static void update_world_cos(Object *ob, PTCacheEdit *edit) return; LOOP_POINTS { - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, hairmat); + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, hairmat); LOOP_KEYS { VECCOPY(key->world_co,key->co); - Mat4MulVecfl(hairmat, key->world_co); + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + Mat4MulVecfl(hairmat, key->world_co); } } } @@ -1480,7 +1485,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select) Mat4One(mat); LOOP_VISIBLE_POINTS { - if(edit->psys) + if(edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR)) psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + p, mat); if(pset->selectmode==SCE_SELECT_POINT) { @@ -1777,7 +1782,8 @@ static void rekey_particle(PEData *data, int pa_index) for(k=0, key=pa->hair; ktotkey; k++, key++, ekey++) { ekey->co= key->co; ekey->time= &key->time; - ekey->flag |= PEK_USE_WCO; + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + ekey->flag |= PEK_USE_WCO; } pa->flag &= ~PARS_REKEY; @@ -2059,7 +2065,9 @@ static void subdivide_particle(PEData *data, int pa_index) nekey->co= nkey->co; nekey->time= &nkey->time; - nekey->flag |= (PEK_SELECT|PEK_USE_WCO); + nekey->flag |= PEK_SELECT; + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + nekey->flag |= PEK_USE_WCO; nekey++; nkey++; @@ -2129,6 +2137,9 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) float mat[4][4], co[3], threshold= RNA_float_get(op->ptr, "threshold"); int n, totn, removed, flag, totremoved; + if(psys->flag & PSYS_GLOBAL_HAIR) + return OPERATOR_CANCELLED; + edit= psys->edit; psmd= psys_get_modifier(ob, psys); totremoved= 0; @@ -2400,6 +2411,9 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) int *mirrorfaces; int rotation, totpart, newtotpart; + if(psys->flag & PSYS_GLOBAL_HAIR) + return; + psmd= psys_get_modifier(ob, psys); mirrorfaces= mesh_get_x_mirror_faces(ob, NULL); @@ -2750,7 +2764,7 @@ static void brush_puff(PEData *data, int point_index) float mat[4][4], imat[4][4]; float lastco[3], rootco[3], co[3], nor[3], kco[3], dco[3], fac, length; - if(psys) { + if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat); Mat4Invert(imat,mat); } @@ -2849,6 +2863,9 @@ static void brush_add(PEData *data, short number) DerivedMesh *dm=0; Mat4Invert(imat,ob->obmat); + if(psys->flag & PSYS_GLOBAL_HAIR) + return; + BLI_srandom(psys->seed+data->mval[0]+data->mval[1]); /* painting onto the deformed mesh, could be an option? */ @@ -3070,6 +3087,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) float vec[3], mousef[2]; short mval[2], mvalo[2]; int flip, mouse[2], dx, dy, removed= 0, selected= 0; + int lock_root = pset->flag & PE_LOCK_FIRST; if(!PE_start_edit(edit)) return; @@ -3093,6 +3111,10 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) mvalo[0]= bedit->lastmouse[0]; mvalo[1]= bedit->lastmouse[1]; + /* disable locking temporatily for disconnected hair */ + if(edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR) + pset->flag &= ~PE_LOCK_FIRST; + if(((pset->brushtype == PE_BRUSH_ADD) ? (sqrt(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first) { @@ -3248,6 +3270,8 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) bedit->lastmouse[1]= mouse[1]; bedit->first= 0; } + + pset->flag |= lock_root; } static void brush_edit_exit(bContext *C, wmOperator *op) @@ -3382,6 +3406,8 @@ static void make_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) for(i=0; itotpoint; i++, pa++) pa->hair= MEM_dupallocN(pa->hair); + + undo->psys_flag = edit->psys->flag; } else { PTCacheMem *pm; @@ -3449,6 +3475,8 @@ static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo) hkey++; } } + + psys->flag = undo->psys_flag; } else { PTCacheMem *pm; @@ -3704,7 +3732,8 @@ static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, key->co= hkey->co; key->time= &hkey->time; key->flag= hkey->editflag; - key->flag |= PEK_USE_WCO; + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + key->flag |= PEK_USE_WCO; hkey++; } pa++; @@ -3828,6 +3857,7 @@ static int clear_edited_exec(bContext *C, wmOperator *op) psys->free_edit = NULL; psys->recalc |= PSYS_RECALC_RESET; + psys->flag &= ~PSYS_GLOBAL_HAIR; psys_reset(psys, PSYS_RESET_DEPSGRAPH); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 8ed17ab1fa8..0a5a5714a06 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -85,6 +85,8 @@ void PARTICLE_OT_new_target(struct wmOperatorType *ot); void PARTICLE_OT_remove_target(struct wmOperatorType *ot); void PARTICLE_OT_target_move_up(struct wmOperatorType *ot); void PARTICLE_OT_target_move_down(struct wmOperatorType *ot); +void PARTICLE_OT_connect_hair(struct wmOperatorType *ot); +void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot); void SCENE_OT_render_layer_add(struct wmOperatorType *ot); void SCENE_OT_render_layer_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 8cdc6b0cd2b..60480a9f165 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -35,6 +35,8 @@ #include "DNA_group_types.h" #include "DNA_object_types.h" #include "DNA_material_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "DNA_node_types.h" #include "DNA_texture_types.h" #include "DNA_scene_types.h" @@ -42,8 +44,11 @@ #include "DNA_space_types.h" #include "DNA_world_types.h" +#include "BKE_bvhutils.h" +#include "BKE_cdderivedmesh.h" #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_group.h" #include "BKE_font.h" #include "BKE_library.h" @@ -51,11 +56,13 @@ #include "BKE_material.h" #include "BKE_node.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_world.h" +#include "BLI_arithb.h" #include "BLI_editVert.h" #include "BLI_listbase.h" @@ -838,6 +845,217 @@ void PARTICLE_OT_target_move_down(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/************************ connect/disconnect hair operators *********************/ + +static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) +{ + ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys); + ParticleData *pa = psys->particles; + PTCacheEdit *edit = psys->edit; + PTCacheEditPoint *point = edit ? edit->points : NULL; + PTCacheEditKey *ekey = NULL; + HairKey *key; + int i, k; + float hairmat[4][4]; + + if(!ob || !psys || psys->flag & PSYS_GLOBAL_HAIR) + return; + + if(!psys->part || psys->part->type != PART_HAIR) + return; + + for(i=0; itotpart; i++,pa++) { + if(point) { + ekey = point->keys; + point++; + } + + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + + for(k=0,key=pa->hair; ktotkey; k++,key++) { + Mat4MulVecfl(hairmat,key->co); + + if(ekey) { + ekey->flag &= ~PEK_USE_WCO; + ekey++; + } + } + } + + psys_free_path_cache(psys, psys->edit); + + psys->flag |= PSYS_GLOBAL_HAIR; + + PE_update_object(scene, ob, 0); +} + +static int disconnect_hair_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= NULL; + int all = RNA_boolean_get(op->ptr, "all"); + + if(!ob) + return OPERATOR_CANCELLED; + + if(all) { + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + disconnect_hair(scene, ob, psys); + } + } + else { + psys = ptr.data; + disconnect_hair(scene, ob, psys); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) +{ + ot->name= "Disconnect Hair"; + ot->description= "Disconnect hair from the emitter mesh."; + ot->idname= "PARTICLE_OT_disconnect_hair"; + + ot->exec= disconnect_hair_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh"); +} + +static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) +{ + ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys); + ParticleData *pa = psys->particles; + PTCacheEdit *edit = psys->edit; + PTCacheEditPoint *point = edit ? edit->points : NULL; + PTCacheEditKey *ekey; + HairKey *key; + BVHTreeFromMesh bvhtree; + BVHTreeNearest nearest; + MFace *mface; + DerivedMesh *dm = CDDM_copy(psmd->dm); + int numverts = dm->getNumVerts (dm); + int i, k; + float hairmat[4][4], imat[4][4]; + float v[4][3], vec[3]; + + if(!psys || !psys->part || psys->part->type != PART_HAIR) + return; + + memset( &bvhtree, 0, sizeof(bvhtree) ); + + /* convert to global coordinates */ + for (i=0; iobmat, CDDM_get_vert(dm, i)->co); + + bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6); + + for(i=0; itotpart; i++,pa++) { + key = pa->hair; + + nearest.index = -1; + nearest.dist = FLT_MAX; + + BLI_bvhtree_find_nearest(bvhtree.tree, key->co, &nearest, bvhtree.nearest_callback, &bvhtree); + + if(nearest.index == -1) { + printf("No nearest point found for hair root!"); + continue; + } + + mface = CDDM_get_face(dm,nearest.index); + + VecCopyf(v[0], CDDM_get_vert(dm,mface->v1)->co); + VecCopyf(v[1], CDDM_get_vert(dm,mface->v2)->co); + VecCopyf(v[2], CDDM_get_vert(dm,mface->v3)->co); + if(mface->v4) { + VecCopyf(v[3], CDDM_get_vert(dm,mface->v4)->co); + MeanValueWeights(v, 4, nearest.co, pa->fuv); + } + else + MeanValueWeights(v, 3, nearest.co, pa->fuv); + + pa->num = nearest.index; + pa->num_dmcache = psys_particle_dm_face_lookup(ob,psmd->dm,pa->num,pa->fuv,NULL); + + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + Mat4Invert(imat,hairmat); + + VECSUB(vec, nearest.co, key->co); + + if(point) { + ekey = point->keys; + point++; + } + + for(k=0,key=pa->hair; ktotkey; k++,key++) { + VECADD(key->co, key->co, vec); + Mat4MulVecfl(imat,key->co); + + if(ekey) { + ekey->flag |= PEK_USE_WCO; + ekey++; + } + } + } + + free_bvhtree_from_mesh(&bvhtree); + dm->release(dm); + + psys_free_path_cache(psys, psys->edit); + + psys->flag &= ~PSYS_GLOBAL_HAIR; + + PE_update_object(scene, ob, 0); +} + +static int connect_hair_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= NULL; + int all = RNA_boolean_get(op->ptr, "all"); + + if(!ob) + return OPERATOR_CANCELLED; + + if(all) { + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + connect_hair(scene, ob, psys); + } + } + else { + psys = ptr.data; + connect_hair(scene, ob, psys); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_connect_hair(wmOperatorType *ot) +{ + ot->name= "Connect Hair"; + ot->description= "Connect hair to the emitter mesh."; + ot->idname= "PARTICLE_OT_connect_hair"; + + ot->exec= connect_hair_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh"); +} + /********************** render layer operators *********************/ static int render_layer_add_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 5d1dbe47345..385f55b71c1 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -204,6 +204,8 @@ void buttons_operatortypes(void) WM_operatortype_append(PARTICLE_OT_remove_target); WM_operatortype_append(PARTICLE_OT_target_move_up); WM_operatortype_append(PARTICLE_OT_target_move_down); + WM_operatortype_append(PARTICLE_OT_connect_hair); + WM_operatortype_append(PARTICLE_OT_disconnect_hair); WM_operatortype_append(SCENE_OT_render_layer_add); WM_operatortype_append(SCENE_OT_render_layer_remove); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 25ff1244254..57e7d897e24 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3749,7 +3749,6 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj nosel_col[1]=(float)nosel[1]/255.0f; nosel_col[2]=(float)nosel[2]/255.0f; - /* draw paths */ if(timed) { glEnable(GL_BLEND); @@ -3758,24 +3757,16 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj } glEnableClientState(GL_VERTEX_ARRAY); - - /* solid shaded with lighting */ - glEnableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - /* only draw child paths with lighting */ - if(dt > OB_WIRE) - glEnable(GL_LIGHTING); - - /* draw paths without lighting */ cache=edit->pathcache; for(i=0; ico); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); if(timed) { for(k=0, pcol=pathcol, pkey=path; kselectmode!=SCE_SELECT_PATH){ - glDisableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glDisable(GL_LIGHTING); glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); if(pset->selectmode==SCE_SELECT_POINT){ @@ -3810,7 +3798,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj if(!(point->flag & PEP_HIDE)) totkeys += point->totkey; - if(!edit->psys) + if(!(edit->points->keys->flag & PEK_USE_WCO)) pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data"); cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data"); @@ -3843,7 +3831,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj if(point->flag & PEP_HIDE) continue; - if(edit->psys) + if(point->keys->flag & PEK_USE_WCO) glVertexPointer(3, GL_FLOAT, sizeof(PTCacheEditKey), point->keys->world_co); else glVertexPointer(3, GL_FLOAT, 3*sizeof(float), pd); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 2283d36e018..b6159cf4314 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1760,17 +1760,17 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) case B_SEL_PATH: ts->particle.selectmode= SCE_SELECT_PATH; - WM_event_add_notifier(C, NC_OBJECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); ED_undo_push(C, "Selectmode Set: Path"); break; case B_SEL_POINT: ts->particle.selectmode = SCE_SELECT_POINT; - WM_event_add_notifier(C, NC_OBJECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); ED_undo_push(C, "Selectmode Set: Point"); break; case B_SEL_END: ts->particle.selectmode = SCE_SELECT_END; - WM_event_add_notifier(C, NC_OBJECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); ED_undo_push(C, "Selectmode Set: End point"); break; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 0fce9592d1d..3f32b707043 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1690,11 +1690,11 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if(!(point->flag & PEP_TRANSFORM)) continue; - if(psys) + 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++) { - if(psys) { + if(key->flag & PEK_USE_WCO) { VECCOPY(key->world_co, key->co); Mat4MulVecfl(mat, key->world_co); td->loc = key->world_co; @@ -1714,7 +1714,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) Mat3One(td->smtx); /* don't allow moving roots */ - if(k==0 && pset->flag & PE_LOCK_FIRST) + if(k==0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR))) td->protectflag |= OB_LOCK_LOC; td->ob = ob; @@ -1764,7 +1764,7 @@ void flushTransParticles(TransInfo *t) for(i=0, point=edit->points; itotpoint; i++, point++, td++) { if(!(point->flag & PEP_TRANSFORM)) continue; - if(psys) { + if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles + i, mat); Mat4Invert(imat,mat); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 4a23605c717..71b953effdf 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1884,6 +1884,11 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "softflag", OB_SB_ENABLE); RNA_def_property_ui_text(prop, "Use Soft Body", "Enable use of soft body for hair physics simulation."); + prop= RNA_def_property(srna, "global_hair", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_GLOBAL_HAIR); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Global Hair", "Hair keys are in global coordinate space"); + /* reactor */ prop= RNA_def_property(srna, "reactor_target_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "target_ob"); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 5575b170398..ab4b27cea7b 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -107,7 +107,7 @@ static void rna_ParticleEdit_redo(bContext *C, PointerRNA *ptr) if(!edit) return; - psys_free_path_cache(NULL, edit); + psys_free_path_cache(edit->psys, edit); } static void rna_ParticleEdit_update(bContext *C, PointerRNA *ptr) @@ -410,7 +410,7 @@ static void rna_def_particle_edit(BlenderRNA *brna) prop= RNA_def_property(srna, "fade_time", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_FADE_TIME); RNA_def_property_ui_text(prop, "Fade Time", "Fade paths and keys further away from current frame."); - RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_ParticleEdit_update"); prop= RNA_def_property(srna, "auto_velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PE_AUTO_VELOCITY); @@ -443,18 +443,18 @@ static void rna_def_particle_edit(BlenderRNA *brna) prop= RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 2, 10); RNA_def_property_ui_text(prop, "Steps", "How many steps to draw the path with."); - RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_redo"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_ParticleEdit_redo"); prop= RNA_def_property(srna, "fade_frames", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 2, 100); RNA_def_property_ui_text(prop, "Frames", "How many frames to fade."); - RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_ParticleEdit_update"); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "edittype"); RNA_def_property_enum_items(prop, edit_type_items); RNA_def_property_ui_text(prop, "Type", ""); - RNA_def_property_update(prop, NC_OBJECT, "rna_ParticleEdit_redo"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_ParticleEdit_redo"); prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_ParticleEdit_editable_get", NULL); -- cgit v1.2.3 From 75407a4ecceb701c9cc760768f5b58f2d099727b Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sat, 5 Sep 2009 22:39:42 +0000 Subject: == SCons == * makesrna and makesdna now use CFLAGS, CCFLAGS and Linking flags as specified in config. This might help with cross-compile on OSX 10.6 (32bit on 64bit). devroo & jensverwiebe, please test and report. --- source/blender/makesdna/intern/SConscript | 3 +++ source/blender/makesrna/intern/SConscript | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript index 1c716019e80..120398791a8 100644 --- a/source/blender/makesdna/intern/SConscript +++ b/source/blender/makesdna/intern/SConscript @@ -34,6 +34,9 @@ if not USE_WINE: if sys.platform != 'cygwin': makesdna_tool.Append (CCFLAGS = cflags) makesdna_tool.Append (CPPDEFINES = defines) +makesdna_tool.Append( CFLAGS = env['CFLAGS']) +makesdna_tool.Append( CCFLAGS = env['CCFLAGS']) +makesdna_tool.Append( LINKFLAGS = env['PLATFORM_LINKFLAGS']) targetdir = normpath(root_build_dir+'/lib') if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'): diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index a24c25b8b95..9234efa2a5d 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -6,7 +6,7 @@ def normpath(path): return os.path.abspath(os.path.normpath(path)) Import ('env') -cflags = '-Wall' +cflags = ['-Wall'] defines = [] root_build_dir=normpath(env['BF_BUILDDIR']) @@ -96,6 +96,10 @@ if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'): makesrna_tool.Append (LIBPATH = libdir) +makesrna_tool.Append( CFLAGS = env['CFLAGS']) +makesrna_tool.Append( CCFLAGS = env['CCFLAGS']) +makesrna_tool.Append( LINKFLAGS = env['PLATFORM_LINKFLAGS']) + if env['BF_PROFILE']: makesrna_tool.Append (LINKFLAGS = env['BF_PROFILE_FLAGS']) -- cgit v1.2.3 From c9dd69c11a639aece463dac9018e88dede4b9515 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Sep 2009 00:19:15 +0000 Subject: remove MTC_ functions, (don't merge) replacements... MTC_cross3Float -> Crossf MTC_diff3Float -> VecSubf MTC_dot3Float -> Inpf MTC_Mat3CpyMat4 -> Mat3CpyMat4 MTC_Mat3MulVecd -> Mat3MulVecd MTC_Mat3MulVecfl -> Mat3MulVecfl MTC_Mat4CpyMat4 -> Mat4CpyMat4 MTC_Mat4Invert -> Mat4Invert MTC_Mat4Mul3Vecfl -> Mat4Mul3Vecfl MTC_Mat4MulMat4 -> Mat4MulMat4 MTC_Mat4MulSerie -> Mat4MulSerie MTC_Mat4MulVec4fl -> Mat4MulVec4fl MTC_Mat4MulVecfl -> Mat4MulVecfl MTC_Mat4One -> Mat4One MTC_Mat4Ortho -> Mat4Ortho MTC_Mat4SwapMat4 -> Mat4SwapMat4 --- source/blender/blenkernel/intern/modifier.c | 34 +- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenlib/MTC_matrixops.h | 162 -------- source/blender/blenlib/MTC_vectorops.h | 58 --- source/blender/blenlib/intern/matrixops.c | 438 --------------------- source/blender/blenlib/intern/vectorops.c | 166 -------- source/blender/nodes/intern/TEX_nodes/TEX_rotate.c | 8 +- source/blender/python/api2_2x/Effect.c | 2 +- .../blender/render/intern/source/convertblender.c | 102 ++--- source/blender/render/intern/source/envmap.c | 80 ++-- source/blender/render/intern/source/initrender.c | 2 +- source/blender/render/intern/source/pixelshading.c | 12 +- source/blender/render/intern/source/shadbuf.c | 16 +- source/blender/render/intern/source/shadeinput.c | 14 +- source/blender/render/intern/source/shadeoutput.c | 8 +- source/blender/render/intern/source/texture.c | 36 +- source/blender/render/intern/source/zbuf.c | 4 +- source/blender/src/drawobject.c | 6 +- source/blender/src/editface.c | 2 +- source/blender/src/editfont.c | 2 +- source/blender/src/editmesh_mods.c | 2 +- source/blender/src/editmesh_tools.c | 2 +- source/blender/src/fluidsim.c | 4 +- source/blender/src/previewrender.c | 2 +- source/blender/src/vpaint.c | 10 +- source/blender/yafray/intern/export_File.cpp | 39 +- source/blender/yafray/intern/export_Plugin.cpp | 38 +- source/blender/yafray/intern/yafray_Render.cpp | 2 +- source/blender/yafray/intern/yafray_Render.h | 3 +- 29 files changed, 216 insertions(+), 1040 deletions(-) delete mode 100644 source/blender/blenlib/MTC_matrixops.h delete mode 100644 source/blender/blenlib/MTC_vectorops.h delete mode 100644 source/blender/blenlib/intern/matrixops.c delete mode 100644 source/blender/blenlib/intern/vectorops.c diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index fa2f857cc8b..77d54125564 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -72,8 +72,8 @@ #include "BLI_editVert.h" -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" + + #include "BKE_main.h" #include "BKE_anim.h" @@ -1182,7 +1182,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if(amd->end_cap && amd->end_cap != ob) end_cap = mesh_get_derived_final(amd->end_cap, CD_MASK_MESH); - MTC_Mat4One(offset); + Mat4One(offset); indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm), "indexmap"); @@ -1204,14 +1204,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, float result_mat[4][4]; if(ob) - MTC_Mat4Invert(obinv, ob->obmat); + Mat4Invert(obinv, ob->obmat); else - MTC_Mat4One(obinv); + Mat4One(obinv); - MTC_Mat4MulSerie(result_mat, offset, + Mat4MulSerie(result_mat, offset, obinv, amd->offset_ob->obmat, NULL, NULL, NULL, NULL, NULL); - MTC_Mat4CpyMat4(offset, result_mat); + Mat4CpyMat4(offset, result_mat); } if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) { @@ -1236,7 +1236,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, prescribed length */ if(amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) { - float dist = sqrt(MTC_dot3Float(offset[3], offset[3])); + float dist = sqrt(Inpf(offset[3], offset[3])); if(dist > 1e-6f) /* this gives length = first copy start to last copy end @@ -1269,11 +1269,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces); /* calculate the offset matrix of the final copy (for merging) */ - MTC_Mat4One(final_offset); + Mat4One(final_offset); for(j=0; j < count - 1; j++) { - MTC_Mat4MulMat4(tmp_mat, final_offset, offset); - MTC_Mat4CpyMat4(final_offset, tmp_mat); + Mat4MulMat4(tmp_mat, final_offset, offset); + Mat4CpyMat4(final_offset, tmp_mat); } numVerts = numEdges = numFaces = 0; @@ -1309,7 +1309,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if((count > 1) && (amd->flags & MOD_ARR_MERGE)) { float tmp_co[3]; VECCOPY(tmp_co, mv->co); - MTC_Mat4MulVecfl(offset, tmp_co); + Mat4MulVecfl(offset, tmp_co); for(j = 0; j < maxVerts; j++) { /* if vertex already merged, don't use it */ @@ -1324,7 +1324,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if(amd->flags & MOD_ARR_MERGEFINAL) { VECCOPY(tmp_co, inMV->co); inMV = &src_mvert[i]; - MTC_Mat4MulVecfl(final_offset, tmp_co); + Mat4MulVecfl(final_offset, tmp_co); if(VecLenCompare(tmp_co, inMV->co, amd->merge_dist)) indexMap[i].merge_final = 1; } @@ -1342,7 +1342,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, *mv2 = *mv; numVerts++; - MTC_Mat4MulVecfl(offset, co); + Mat4MulVecfl(offset, co); VECCOPY(mv2->co, co); } } else if(indexMap[i].merge != i && indexMap[i].merge_final) { @@ -3174,7 +3174,7 @@ static void tag_and_count_extra_edges(SmoothMesh *mesh, float split_angle, /* we know the edge has 2 faces, so check the angle */ SmoothFace *face1 = edge->faces->link; SmoothFace *face2 = edge->faces->next->link; - float edge_angle_cos = MTC_dot3Float(face1->normal, + float edge_angle_cos = Inpf(face1->normal, face2->normal); if(edge_angle_cos < threshold) { @@ -4042,11 +4042,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, /* find the projector which the face points at most directly * (projector normal with largest dot product is best) */ - best_dot = MTC_dot3Float(projectors[0].normal, face_no); + best_dot = Inpf(projectors[0].normal, face_no); best_projector = &projectors[0]; for(j = 1; j < num_projectors; ++j) { - float tmp_dot = MTC_dot3Float(projectors[j].normal, + float tmp_dot = Inpf(projectors[j].normal, face_no); if(tmp_dot > best_dot) { best_dot = tmp_dot; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 52b88de06e0..be005af7827 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -38,7 +38,7 @@ #include "PIL_dynlib.h" -#include "MTC_matrixops.h" + #include "BLI_blenlib.h" #include "BLI_arithb.h" diff --git a/source/blender/blenlib/MTC_matrixops.h b/source/blender/blenlib/MTC_matrixops.h deleted file mode 100644 index 2bc644be564..00000000000 --- a/source/blender/blenlib/MTC_matrixops.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * matrixops.h - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef MATRIXOPS_H -#define MATRIXOPS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------------------------------------------------------------- */ -/* need rewriting: */ -/** - * copy the left upp3 3 by 3 of m2 to m1 - */ -void MTC_Mat3CpyMat4(float m1[][3], float m2[][4]); - -/* ------------------------------------------------------------------------- */ -/* operations based on 4 by 4 matrices */ - -/** - * Copy m1 to m2 - */ -void MTC_Mat4CpyMat4(float m1[][4], float m2[][4]); - -/** - * Multiply all matrices after the first, leave the result in the - * first argument - */ -void MTC_Mat4MulSerie(float answ[][4], - float m1[][4], float m2[][4], float m3[][4], - float m4[][4], float m5[][4], float m6[][4], - float m7[][4], float m8[][4]); - -/** - * m1 = m2 matprod m3 - */ -void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]); - -/** - * Do vec^t prod mat, result in vec. Ignore vec[3] (vec is a - * float[3]) - */ -void MTC_Mat4MulVecfl(float mat[][4], float *vec); - -/** - * Invert mat, result in inverse. Always returns 1 - */ -int MTC_Mat4Invert(float inverse[][4], float mat[][4]); - -/** - * Make the set of mat orthonormal (mat should already be orthogonal)? - * (doesn't appear to normalize properly?) - */ -void MTC_Mat4Ortho(float mat[][4]); - -/** - * vec = mat prod vec, result in vec, ignore fourth component entirely - * (4th component is _not_ accessed!!! vec is 3d) - */ -void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec); - -/** - * vec = mat prod vec, result in vec - */ -void MTC_Mat4MulVec4fl(float mat[][4], float *vec); - -/** - * Set to the 4-D unity matrix - */ -void MTC_Mat4One(float m[][4]); - -/** - * Swap matrices m1 and m2 - */ -void MTC_Mat4SwapMat4(float m1[][4], float m2[][4]); - -/** - * Copy m2 to the top-left 3x3 of m1, don't touch the remaining elements. - */ -void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]); - -/** - * m1 = m2 * m3, but only the top-left 3x3 - */ -void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3]); - -/* ------------------------------------------------------------------------- */ -/* Operations based on 3 by 3 matrices */ -/** - * Do vec^t prod mat, result in vec.(vex is 3d) - */ -void MTC_Mat3MulVecfl(float mat[][3], float *vec); - -/** - * Copy m1 to m2 - */ -void MTC_Mat3CpyMat3(float m1[][3], float m2[][3]); - -/** - * m1 = m2 prod m3 - */ -void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]); - -/** - * vec = vec prod mat - */ -void MTC_Mat3MulVecd(float mat[][3], double *vec); - -/** - * Guess: invert matrix - * result goes to m1 - */ -void MTC_Mat3Inv(float m1[][3], float m2[][3]); - -/** - * Sort of a determinant matrix? Doesn't seem very adjoint to me... - * result goes to m1 - */ -void MTC_Mat3Adj(float m1[][3], float m[][3]); - -/** - * Set to the 3D unity matrix - */ -void MTC_Mat3One(float m[][3]); - -/* ------------------------------------------------------------------------- */ - -#ifdef __cplusplus -} -#endif - -#endif /* MATRIXOPS_H */ - diff --git a/source/blender/blenlib/MTC_vectorops.h b/source/blender/blenlib/MTC_vectorops.h deleted file mode 100644 index 4fec93b37b9..00000000000 --- a/source/blender/blenlib/MTC_vectorops.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * vectorops.h - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef VECTOROPS_H -#define VECTOROPS_H - -/* ------------------------------------------------------------------------- */ - -void MTC_diff3Int(int v1[3], int v2[3], int v3[3]); -void MTC_cross3Int(int v1[3], int v2[3], int v3[3]); -int MTC_dot3Int(int v1[3], int v2[3]); - -void MTC_diff3Float(float v1[3], float v2[3], float v3[3]); -void MTC_cross3Float(float v1[3], float v2[3], float v3[3]); -float MTC_dot3Float(float v1[3], float v2[3]); -void MTC_cp3Float(float v1[3], float v2[3]); -/** - * Copy vector with a minus sign (so a = -b) - */ -void MTC_cp3FloatInv(float v1[3], float v2[3]); - -void MTC_swapInt(int *i1, int *i2); - -void MTC_diff3DFF(double v1[3], float v2[3], float v3[3]); -void MTC_cross3Double(double v1[3], double v2[3], double v3[3]); -float MTC_normalize3DF(float n[3]); - -/* ------------------------------------------------------------------------- */ -#endif /* VECTOROPS_H */ - diff --git a/source/blender/blenlib/intern/matrixops.c b/source/blender/blenlib/intern/matrixops.c deleted file mode 100644 index 0f9fc65f016..00000000000 --- a/source/blender/blenlib/intern/matrixops.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * - * Some matrix operations. - * - * Always use - * - vector with x components : float x[3], int x[3], etc - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* ------------------------------------------------------------------------- */ -#include -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" -/* ------------------------------------------------------------------------- */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__) -#include -#endif - -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } - -void MTC_Mat4CpyMat4(float m1[][4], float m2[][4]) -{ - memcpy(m1, m2, 4*4*sizeof(float)); -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulSerie(float answ[][4], - float m1[][4], float m2[][4], float m3[][4], - float m4[][4], float m5[][4], float m6[][4], - float m7[][4], float m8[][4]) -{ - float temp[4][4]; - - if(m1==0 || m2==0) return; - - MTC_Mat4MulMat4(answ, m2, m1); - if(m3) { - MTC_Mat4MulMat4(temp, m3, answ); - if(m4) { - MTC_Mat4MulMat4(answ, m4, temp); - if(m5) { - MTC_Mat4MulMat4(temp, m5, answ); - if(m6) { - MTC_Mat4MulMat4(answ, m6, temp); - if(m7) { - MTC_Mat4MulMat4(temp, m7, answ); - if(m8) { - MTC_Mat4MulMat4(answ, m8, temp); - } - else MTC_Mat4CpyMat4(answ, temp); - } - } - else MTC_Mat4CpyMat4(answ, temp); - } - } - else MTC_Mat4CpyMat4(answ, temp); - } -} - -/* ------------------------------------------------------------------------- */ -void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]) -{ - /* matrix product: c[j][k] = a[j][i].b[i][k] */ - - m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0]; - m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1]; - m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2]; - m1[0][3] = m2[0][0]*m3[0][3] + m2[0][1]*m3[1][3] + m2[0][2]*m3[2][3] + m2[0][3]*m3[3][3]; - - m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0] + m2[1][3]*m3[3][0]; - m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1] + m2[1][3]*m3[3][1]; - m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2] + m2[1][3]*m3[3][2]; - m1[1][3] = m2[1][0]*m3[0][3] + m2[1][1]*m3[1][3] + m2[1][2]*m3[2][3] + m2[1][3]*m3[3][3]; - - m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0] + m2[2][3]*m3[3][0]; - m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1] + m2[2][3]*m3[3][1]; - m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2] + m2[2][3]*m3[3][2]; - m1[2][3] = m2[2][0]*m3[0][3] + m2[2][1]*m3[1][3] + m2[2][2]*m3[2][3] + m2[2][3]*m3[3][3]; - - m1[3][0] = m2[3][0]*m3[0][0] + m2[3][1]*m3[1][0] + m2[3][2]*m3[2][0] + m2[3][3]*m3[3][0]; - m1[3][1] = m2[3][0]*m3[0][1] + m2[3][1]*m3[1][1] + m2[3][2]*m3[2][1] + m2[3][3]*m3[3][1]; - m1[3][2] = m2[3][0]*m3[0][2] + m2[3][1]*m3[1][2] + m2[3][2]*m3[2][2] + m2[3][3]*m3[3][2]; - m1[3][3] = m2[3][0]*m3[0][3] + m2[3][1]*m3[1][3] + m2[3][2]*m3[2][3] + m2[3][3]*m3[3][3]; - -} -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulVecfl(float mat[][4], float *vec) -{ - float x,y; - - x=vec[0]; - y=vec[1]; - vec[0]=x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0]; - vec[1]=x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1]; - vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; -} - -/* ------------------------------------------------------------------------- */ -void MTC_Mat3MulVecfl(float mat[][3], float *vec) -{ - float x,y; - - x=vec[0]; - y=vec[1]; - vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; - vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; - vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; -} - -/* ------------------------------------------------------------------------- */ - -int MTC_Mat4Invert(float inverse[][4], float mat[][4]) -{ - int i, j, k; - double temp; - float tempmat[4][4]; - float max; - int maxj; - - /* Set inverse to identity */ - for (i=0; i<4; i++) - for (j=0; j<4; j++) - inverse[i][j] = 0; - for (i=0; i<4; i++) - inverse[i][i] = 1; - - /* Copy original matrix so we don't mess it up */ - for(i = 0; i < 4; i++) - for(j = 0; j <4; j++) - tempmat[i][j] = mat[i][j]; - - for(i = 0; i < 4; i++) { - /* Look for row with max pivot */ - max = ABS(tempmat[i][i]); - maxj = i; - for(j = i + 1; j < 4; j++) { - if(ABS(tempmat[j][i]) > max) { - max = ABS(tempmat[j][i]); - maxj = j; - } - } - /* Swap rows if necessary */ - if (maxj != i) { - for( k = 0; k < 4; k++) { - SWAP(float, tempmat[i][k], tempmat[maxj][k]); - SWAP(float, inverse[i][k], inverse[maxj][k]); - } - } - - temp = tempmat[i][i]; - if (temp == 0) - return 0; /* No non-zero pivot */ - for(k = 0; k < 4; k++) { - tempmat[i][k] /= temp; - inverse[i][k] /= temp; - } - for(j = 0; j < 4; j++) { - if(j != i) { - temp = tempmat[j][i]; - for(k = 0; k < 4; k++) { - tempmat[j][k] -= tempmat[i][k]*temp; - inverse[j][k] -= inverse[i][k]*temp; - } - } - } - } - return 1; -} - -/* ------------------------------------------------------------------------- */ -void MTC_Mat3CpyMat4(float m1[][3], float m2[][4]) -{ - - m1[0][0]= m2[0][0]; - m1[0][1]= m2[0][1]; - m1[0][2]= m2[0][2]; - - m1[1][0]= m2[1][0]; - m1[1][1]= m2[1][1]; - m1[1][2]= m2[1][2]; - - m1[2][0]= m2[2][0]; - m1[2][1]= m2[2][1]; - m1[2][2]= m2[2][2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3CpyMat3(float m1[][3], float m2[][3]) -{ - memcpy(m1, m2, 3*3*sizeof(float)); -} - -/* ------------------------------------------------------------------------- */ -/* void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ -void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) -{ - /* be careful about this rewrite... */ - /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */ - m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; - m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; - m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; - - m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; - m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; - m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; - - m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; - m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; - m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; - -/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ -/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ -/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ -/* m1+=3; */ -/* m2+=3; */ -/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ -/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ -/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ -/* m1+=3; */ -/* m2+=3; */ -/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ -/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ -/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ -} /* end of void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4Ortho(float mat[][4]) -{ - float len; - - len= MTC_normalize3DF(mat[0]); - if(len!=0.0) mat[0][3]/= len; - len= MTC_normalize3DF(mat[1]); - if(len!=0.0) mat[1][3]/= len; - len= MTC_normalize3DF(mat[2]); - if(len!=0.0) mat[2][3]/= len; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec) -{ - float x,y; - /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/ - - x= vec[0]; - y= vec[1]; - vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; - vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; - vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4One(float m[][4]) -{ - - m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0; - m[0][1]= m[0][2]= m[0][3]= 0.0; - m[1][0]= m[1][2]= m[1][3]= 0.0; - m[2][0]= m[2][1]= m[2][3]= 0.0; - m[3][0]= m[3][1]= m[3][2]= 0.0; -} - - -/* ------------------------------------------------------------------------- */ -/* Result is a 3-vector!*/ -void MTC_Mat3MulVecd(float mat[][3], double *vec) -{ - double x,y; - - /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/ - x=vec[0]; - y=vec[1]; - vec[0]= x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2]; - vec[1]= x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2]; - vec[2]= x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3Inv(float m1[][3], float m2[][3]) -{ - short a,b; - float det; - - /* first adjoint */ - MTC_Mat3Adj(m1,m2); - - /* then determinant old mat! */ - det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1]) - -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1]) - +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]); - - if(det==0) det=1; - det= 1/det; - for(a=0;a<3;a++) { - for(b=0;b<3;b++) { - m1[a][b]*=det; - } - } -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3Adj(float m1[][3], float m[][3]) -{ - m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1]; - m1[0][1]= -m[0][1]*m[2][2]+m[0][2]*m[2][1]; - m1[0][2]=m[0][1]*m[1][2]-m[0][2]*m[1][1]; - - m1[1][0]= -m[1][0]*m[2][2]+m[1][2]*m[2][0]; - m1[1][1]=m[0][0]*m[2][2]-m[0][2]*m[2][0]; - m1[1][2]= -m[0][0]*m[1][2]+m[0][2]*m[1][0]; - - m1[2][0]=m[1][0]*m[2][1]-m[1][1]*m[2][0]; - m1[2][1]= -m[0][0]*m[2][1]+m[0][1]*m[2][0]; - m1[2][2]=m[0][0]*m[1][1]-m[0][1]*m[1][0]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3One(float m[][3]) -{ - - m[0][0]= m[1][1]= m[2][2]= 1.0; - m[0][1]= m[0][2]= 0.0; - m[1][0]= m[1][2]= 0.0; - m[2][0]= m[2][1]= 0.0; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4SwapMat4(float m1[][4], float m2[][4]) -{ - float t; - int i, j; - - for(i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - t = m1[i][j]; - m1[i][j] = m2[i][j]; - m2[i][j] = t; - } - } -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulVec4fl(float mat[][4], float *vec) -{ - float x,y,z; - - x = vec[0]; - y = vec[1]; - z = vec[2]; - vec[0] = x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3]; - vec[1] = x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3]; - vec[2] = x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3]; - vec[3] = x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]) /* no clear */ -{ - m1[0][0]= m2[0][0]; - m1[0][1]= m2[0][1]; - m1[0][2]= m2[0][2]; - - m1[1][0]= m2[1][0]; - m1[1][1]= m2[1][1]; - m1[1][2]= m2[1][2]; - - m1[2][0]= m2[2][0]; - m1[2][1]= m2[2][1]; - m1[2][2]= m2[2][2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3]) -{ - /* m1_i_j = m2_i_k * m3_k_j ? */ - - m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; - m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; - m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; - - m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; - m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; - m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; - - m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; - m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; - m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; - -} - -/* ------------------------------------------------------------------------- */ - -/* eof */ diff --git a/source/blender/blenlib/intern/vectorops.c b/source/blender/blenlib/intern/vectorops.c deleted file mode 100644 index 3bff5235cfd..00000000000 --- a/source/blender/blenlib/intern/vectorops.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * - * Some vector operations. - * - * Always use - * - vector with x components : float x[3], int x[3], etc - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* ------------------------------------------------------------------------- */ -/* General format: op(a, b, c): a = b op c */ -/* Copying is done cp */ -/* ------------------------------------------------------------------------- */ - -#include "MTC_vectorops.h" -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -void MTC_diff3Int(int v1[3], int v2[3], int v3[3]) -{ - v1[0] = v2[0] - v3[0]; - v1[1] = v2[1] - v3[1]; - v1[2] = v2[2] - v3[2]; -} - -/* ------------------------------------------------------------------------- */ -void MTC_diff3Float(float v1[3], float v2[3], float v3[3]) -{ - v1[0] = v2[0] - v3[0]; - v1[1] = v2[1] - v3[1]; - v1[2] = v2[2] - v3[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cross3Int(int v1[3], int v2[3], int v3[3]) -{ - v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; - v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; - v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cross3Float(float v1[3], float v2[3], float v3[3]) -{ - v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; - v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; - v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; -} -/* ------------------------------------------------------------------------- */ - -void MTC_cross3Double(double v1[3], double v2[3], double v3[3]) -{ - v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; - v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; - v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; -} - -/* ------------------------------------------------------------------------- */ - -int MTC_dot3Int(int v1[3], int v2[3]) -{ - return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); -} - -/* ------------------------------------------------------------------------- */ - -float MTC_dot3Float(float v1[3], float v2[3]) -{ - return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cp3Float(float v1[3], float v2[3]) -{ - v2[0] = v1[0]; - v2[1] = v1[1]; - v2[2] = v1[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cp3FloatInv(float v1[3], float v2[3]) -{ - v2[0] = -v1[0]; - v2[1] = -v1[1]; - v2[2] = -v1[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_swapInt(int *i1, int *i2) -{ - int swap; - swap = *i1; - *i1 = *i2; - *i2 = swap; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_diff3DFF(double v1[3], float v2[3], float v3[3]) -{ - v1[0] = v2[0] - v3[0]; - v1[1] = v2[1] - v3[1]; - v1[2] = v2[2] - v3[2]; -} - -/* ------------------------------------------------------------------------- */ -float MTC_normalize3DF(float n[3]) -{ - float d; - - d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; - /* FLT_EPSILON is too large! A larger value causes normalize errors in */ - /* a scaled down utah teapot */ - if(d>0.0000000000001) { - - /* d= sqrt(d); This _should_ be sqrt, but internally it's a double*/ - /* anyway. This is safe. */ - d = sqrt(d); - - n[0]/=d; - n[1]/=d; - n[2]/=d; - } else { - n[0]=n[1]=n[2]= 0.0; - d= 0.0; - } - return d; -} - -/* ------------------------------------------------------------------------- */ - -/* eof */ diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c index 3a2c2b1def1..9fcc9dcb90c 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c @@ -27,7 +27,7 @@ */ #include -#include "MTC_vectorops.h" + #include "../TEX_util.h" static bNodeSocketType inputs[]= { @@ -64,19 +64,19 @@ static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, shor if(magsq == 0) magsq = 1; - ndx = MTC_dot3Float(coord, ax); + ndx = Inpf(coord, ax); para[0] = ax[0] * ndx * (1 - cos_a); para[1] = ax[1] * ndx * (1 - cos_a); para[2] = ax[2] * ndx * (1 - cos_a); - MTC_diff3Float(perp, coord, para); + VecSubf(perp, coord, para); perp[0] = coord[0] * cos_a; perp[1] = coord[1] * cos_a; perp[2] = coord[2] * cos_a; - MTC_cross3Float(cp, ax, coord); + Crossf(cp, ax, coord); cp[0] = cp[0] * sin_a; cp[1] = cp[1] * sin_a; diff --git a/source/blender/python/api2_2x/Effect.c b/source/blender/python/api2_2x/Effect.c index 4d3dce741fc..1a37856a4d6 100644 --- a/source/blender/python/api2_2x/Effect.c +++ b/source/blender/python/api2_2x/Effect.c @@ -41,7 +41,7 @@ #include "gen_utils.h" #include "blendef.h" #include "vector.h" -#include "MTC_matrixops.h" + #define EXPP_EFFECT_STA_MIN -250.0f #define EXPP_EFFECT_END_MIN 1.0f diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 3c6b872a16d..24f4a6f7ad3 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -32,7 +32,7 @@ #include #include "blendef.h" -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" @@ -203,8 +203,8 @@ void RE_make_stars(Render *re, void (*initfunc)(void), if (re) re->flag |= R_HALO; else stargrid *= 1.0; /* then it draws fewer */ - if(re) MTC_Mat4Invert(mat, re->viewmat); - else MTC_Mat4One(mat); + if(re) Mat4Invert(mat, re->viewmat); + else Mat4One(mat); /* BOUNDING BOX CALCULATION * bbox goes from z = loc_near_var | loc_far_var, @@ -252,7 +252,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void), done++; } else { - MTC_Mat4MulVecfl(re->viewmat, vec); + Mat4MulVecfl(re->viewmat, vec); /* in vec are global coordinates * calculate distance to camera @@ -841,7 +841,7 @@ static void autosmooth(Render *re, ObjectRen *obr, float mat[][4], int degr) /* rotate vertices and calculate normal of faces */ for(a=0; atotvert; a++) { ver= RE_findOrAddVert(obr, a); - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); } for(a=0; atotvlak; a++) { vlr= RE_findOrAddVlak(obr, a); @@ -1278,19 +1278,19 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Particl VECADD(vlr->v1->co, bb_center, xvec); VECADD(vlr->v1->co, vlr->v1->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v1->co); + Mat4MulVecfl(re->viewmat, vlr->v1->co); VECSUB(vlr->v2->co, bb_center, xvec); VECADD(vlr->v2->co, vlr->v2->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v2->co); + Mat4MulVecfl(re->viewmat, vlr->v2->co); VECSUB(vlr->v3->co, bb_center, xvec); VECSUB(vlr->v3->co, vlr->v3->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v3->co); + Mat4MulVecfl(re->viewmat, vlr->v3->co); VECADD(vlr->v4->co, bb_center, xvec); VECSUB(vlr->v4->co, vlr->v4->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v4->co); + Mat4MulVecfl(re->viewmat, vlr->v4->co); CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); VECCOPY(vlr->v1->n,vlr->n); @@ -1581,8 +1581,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } /* 2.5 setup matrices */ - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ Mat3CpyMat4(nmat, ob->imat); Mat3Transp(nmat); @@ -1854,7 +1854,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem time= curlen/strandlen; VECCOPY(loc,state.co); - MTC_Mat4MulVecfl(re->viewmat,loc); + Mat4MulVecfl(re->viewmat,loc); if(strandbuf) { VECCOPY(svert->co, loc); @@ -1894,7 +1894,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem VECCOPY(loc,state.co); if(part->draw_as!=PART_DRAW_BB) - MTC_Mat4MulVecfl(re->viewmat,loc); + Mat4MulVecfl(re->viewmat,loc); switch(part->draw_as) { case PART_DRAW_LINE: @@ -1903,7 +1903,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem sd.size = hasize; VECCOPY(vel,state.vel); - MTC_Mat4Mul3Vecfl(re->viewmat,vel); + Mat4Mul3Vecfl(re->viewmat,vel); Normalize(vel); if(part->draw & PART_DRAW_VEL_LENGTH) @@ -1997,8 +1997,8 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *me, int totvert, float vec[3], hasize, mat[4][4], imat[3][3]; int a, ok, seed= ma->seed1; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat3CpyMat4(imat, ob->imat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat3CpyMat4(imat, ob->imat); re->flag |= R_HALO; @@ -2009,7 +2009,7 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *me, int totvert, hasize= ma->hasize; VECCOPY(vec, mvert->co); - MTC_Mat4MulVecfl(mat, vec); + Mat4MulVecfl(mat, vec); if(ma->mode & MA_HALOPUNO) { xn= mvert->no[0]; @@ -2142,7 +2142,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve } if (texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(re->viewinv, shi->gl); + Mat4MulVecfl(re->viewinv, shi->gl); } if (texco & TEXCO_NORM) { VECCOPY(shi->orn, shi->vn); @@ -2282,9 +2282,9 @@ static void init_render_mball(Render *re, ObjectRen *obr) if (ob!=find_basis_mball(ob)) return; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); - MTC_Mat3CpyMat4(imat, ob->imat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); + Mat3CpyMat4(imat, ob->imat); ma= give_render_material(re, ob, 1); @@ -2305,7 +2305,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, data); - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); /* render normals are inverted */ xn= -nors[0]; @@ -2389,7 +2389,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, if(orco) { v1->orco= orco; orco+= 3; orcoret++; } - MTC_Mat4MulVecfl(mat, v1->co); + Mat4MulVecfl(mat, v1->co); for (v = 1; v < sizev; v++) { ver= RE_findOrAddVert(obr, obr->totvert++); @@ -2397,7 +2397,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, if(orco) { ver->orco= orco; orco+= 3; orcoret++; } - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); } /* if V-cyclic, add extra vertices at end of the row */ if (dl->flag & DL_CYCL_U) { @@ -2547,8 +2547,8 @@ static void init_render_surf(Render *re, ObjectRen *obr) nu= cu->nurb.first; if(nu==0) return; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* material array */ memset(matar, 0, 4*32); @@ -2609,8 +2609,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) dl= cu->disp.first; if(cu->disp.first==NULL) return; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* material array */ memset(matar, 0, 4*32); @@ -2651,7 +2651,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ver->flag = 0; } - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); if (orco) { ver->orco = orco; @@ -2703,7 +2703,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, fp); - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); fp+= 3; if (orco) { @@ -2951,9 +2951,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) me= ob->data; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); - MTC_Mat3CpyMat4(imat, ob->imat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); + Mat3CpyMat4(imat, ob->imat); if(me->totvert==0) return; @@ -3046,7 +3046,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, mvert->co); if(do_autosmooth==0) /* autosmooth on original unrotated data to prevent differences between frames */ - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); if(orco) { ver->orco= orco; @@ -3267,13 +3267,13 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) shb->soft= lar->soft; shb->shadhalostep= lar->shadhalostep; - MTC_Mat4Ortho(mat); - MTC_Mat4Invert(shb->winmat, mat); /* winmat is temp */ + Mat4Ortho(mat); + Mat4Invert(shb->winmat, mat); /* winmat is temp */ /* matrix: combination of inverse view and lampmat */ /* calculate again: the ortho-render has no correct viewinv */ - MTC_Mat4Invert(viewinv, re->viewmat); - MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat); + Mat4Invert(viewinv, re->viewmat); + Mat4MulMat4(shb->viewmat, viewinv, shb->winmat); /* projection */ shb->d= lar->clipsta; @@ -3351,11 +3351,11 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) BLI_addtail(&re->lampren, lar); go->lampren= lar; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); - MTC_Mat3CpyMat4(lar->mat, mat); - MTC_Mat3CpyMat4(lar->imat, ob->imat); + Mat3CpyMat4(lar->mat, mat); + Mat3CpyMat4(lar->imat, ob->imat); lar->bufsize = la->bufsize; lar->samp = la->samp; @@ -3527,7 +3527,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) lar->sh_invcampos[0]= -lar->co[0]; lar->sh_invcampos[1]= -lar->co[1]; lar->sh_invcampos[2]= -lar->co[2]; - MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos); + Mat3MulVecfl(lar->imat, lar->sh_invcampos); /* z factor, for a normalized volume */ angle= saacos(lar->spotsi); @@ -4149,7 +4149,7 @@ static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *d obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4); Mat4Invert(imat, dob->mat); - MTC_Mat4MulSerie(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0); + Mat4MulSerie(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0); } } @@ -4273,8 +4273,8 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject else if(render_object_type(ob->type)) add_render_object(re, ob, par, dob, timeoffset, vectorlay); else { - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); } time= PIL_check_seconds_timer(); @@ -4516,8 +4516,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp for(SETLOOPER(re->scene, base)) { ob= base->object; /* imat objects has to be done here, since displace can have texture using Object map-input */ - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* each object should only be rendered once */ ob->flag &= ~OB_DONE; ob->transflag &= ~OB_RENDER_DUPLI; @@ -4663,8 +4663,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp if(redoimat) { for(SETLOOPER(re->scene, base)) { ob= base->object; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); } } @@ -5070,7 +5070,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * return 0; Mat4CpyMat4(mat, re->viewmat); - MTC_Mat4Invert(imat, mat); + Mat4Invert(imat, mat); /* set first vertex OK */ if(!fss->meshSurfNormals) return 0; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 13fa9b17b71..46669fd8f47 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -51,7 +51,7 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" -#include "MTC_matrixops.h" + /* this module */ #include "render_types.h" @@ -209,9 +209,9 @@ static void envmap_transmatrix(float mat[][4], int part) eul[2]= -M_PI/2.0; } - MTC_Mat4CpyMat4(tmat, mat); + Mat4CpyMat4(tmat, mat); EulToMat4(eul, rotmat); - MTC_Mat4MulSerie(mat, tmat, rotmat, + Mat4MulSerie(mat, tmat, rotmat, 0, 0, 0, 0, 0, 0); } @@ -229,12 +229,12 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) int a; if(mode==0) { - MTC_Mat4Invert(tmat, mat); - MTC_Mat3CpyMat4(imat, tmat); + Mat4Invert(tmat, mat); + Mat3CpyMat4(imat, tmat); } else { - MTC_Mat4CpyMat4(tmat, mat); - MTC_Mat3CpyMat4(imat, mat); + Mat4CpyMat4(tmat, mat); + Mat3CpyMat4(imat, mat); } for(obi=re->instancetable.first; obi; obi=obi->next) { @@ -265,7 +265,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) if((a & 255)==0) har= obr->bloha[a>>8]; else har++; - MTC_Mat4MulVecfl(tmat, har->co); + Mat4MulVecfl(tmat, har->co); } } @@ -278,22 +278,22 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) Mat3CpyMat3(cmat, lar->imat); Mat3MulMat3(lar->imat, cmat, imat); - MTC_Mat3MulVecfl(imat, lar->vec); - MTC_Mat4MulVecfl(tmat, lar->co); + Mat3MulVecfl(imat, lar->vec); + Mat4MulVecfl(tmat, lar->co); lar->sh_invcampos[0]= -lar->co[0]; lar->sh_invcampos[1]= -lar->co[1]; lar->sh_invcampos[2]= -lar->co[2]; - MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos); + Mat3MulVecfl(lar->imat, lar->sh_invcampos); lar->sh_invcampos[2]*= lar->sh_zfac; if(lar->shb) { if(mode==1) { - MTC_Mat4Invert(pmat, mat); - MTC_Mat4MulMat4(smat, pmat, lar->shb->viewmat); - MTC_Mat4MulMat4(lar->shb->persmat, smat, lar->shb->winmat); + Mat4Invert(pmat, mat); + Mat4MulMat4(smat, pmat, lar->shb->viewmat); + Mat4MulMat4(lar->shb->persmat, smat, lar->shb->winmat); } - else MTC_Mat4MulMat4(lar->shb->persmat, lar->shb->viewmat, lar->shb->winmat); + else Mat4MulMat4(lar->shb->persmat, lar->shb->viewmat, lar->shb->winmat); } } @@ -371,8 +371,8 @@ static void env_set_imats(Render *re) base= G.scene->base.first; while(base) { - MTC_Mat4MulMat4(mat, base->object->obmat, re->viewmat); - MTC_Mat4Invert(base->object->imat, mat); + Mat4MulMat4(mat, base->object->obmat, re->viewmat); + Mat4Invert(base->object->imat, mat); base= base->next; } @@ -391,18 +391,18 @@ static void render_envmap(Render *re, EnvMap *env) short part; /* need a recalc: ortho-render has no correct viewinv */ - MTC_Mat4Invert(oldviewinv, re->viewmat); + Mat4Invert(oldviewinv, re->viewmat); envre= envmap_render_copy(re, env); /* precalc orthmat for object */ - MTC_Mat4CpyMat4(orthmat, env->object->obmat); - MTC_Mat4Ortho(orthmat); + Mat4CpyMat4(orthmat, env->object->obmat); + Mat4Ortho(orthmat); /* need imat later for texture imat */ - MTC_Mat4MulMat4(mat, orthmat, re->viewmat); - MTC_Mat4Invert(tmat, mat); - MTC_Mat3CpyMat4(env->obimat, tmat); + Mat4MulMat4(mat, orthmat, re->viewmat); + Mat4Invert(tmat, mat); + Mat3CpyMat4(env->obimat, tmat); for(part=0; part<6; part++) { if(env->type==ENV_PLANE && part!=1) @@ -410,17 +410,17 @@ static void render_envmap(Render *re, EnvMap *env) re->display_clear(envre->result); - MTC_Mat4CpyMat4(tmat, orthmat); + Mat4CpyMat4(tmat, orthmat); envmap_transmatrix(tmat, part); - MTC_Mat4Invert(mat, tmat); + Mat4Invert(mat, tmat); /* mat now is the camera 'viewmat' */ - MTC_Mat4CpyMat4(envre->viewmat, mat); - MTC_Mat4CpyMat4(envre->viewinv, tmat); + Mat4CpyMat4(envre->viewmat, mat); + Mat4CpyMat4(envre->viewinv, tmat); /* we have to correct for the already rotated vertexcoords */ - MTC_Mat4MulMat4(tmat, oldviewinv, envre->viewmat); - MTC_Mat4Invert(env->imat, tmat); + Mat4MulMat4(tmat, oldviewinv, envre->viewmat); + Mat4Invert(env->imat, tmat); env_rotate_scene(envre, tmat, 1); init_render_world(envre); @@ -501,13 +501,13 @@ void make_envmaps(Render *re) float orthmat[4][4], mat[4][4], tmat[4][4]; /* precalc orthmat for object */ - MTC_Mat4CpyMat4(orthmat, env->object->obmat); - MTC_Mat4Ortho(orthmat); + Mat4CpyMat4(orthmat, env->object->obmat); + Mat4Ortho(orthmat); /* need imat later for texture imat */ - MTC_Mat4MulMat4(mat, orthmat, re->viewmat); - MTC_Mat4Invert(tmat, mat); - MTC_Mat3CpyMat4(env->obimat, tmat); + Mat4MulMat4(mat, orthmat, re->viewmat); + Mat4Invert(tmat, mat); + Mat3CpyMat4(env->obimat, tmat); } else { @@ -676,20 +676,20 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe /* rotate to envmap space, if object is set */ VECCOPY(vec, texvec); - if(env->object) MTC_Mat3MulVecfl(env->obimat, vec); - else MTC_Mat4Mul3Vecfl(R.viewinv, vec); + if(env->object) Mat3MulVecfl(env->obimat, vec); + else Mat4Mul3Vecfl(R.viewinv, vec); face= envcube_isect(env, vec, sco); ibuf= env->cube[face]; if(osatex) { if(env->object) { - MTC_Mat3MulVecfl(env->obimat, dxt); - MTC_Mat3MulVecfl(env->obimat, dyt); + Mat3MulVecfl(env->obimat, dxt); + Mat3MulVecfl(env->obimat, dyt); } else { - MTC_Mat4Mul3Vecfl(R.viewinv, dxt); - MTC_Mat4Mul3Vecfl(R.viewinv, dyt); + Mat4Mul3Vecfl(R.viewinv, dxt); + Mat4Mul3Vecfl(R.viewinv, dyt); } set_dxtdyt(dxts, dyts, dxt, dyt, face); imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres); diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 40c0edb6e5f..e5894606454 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -41,7 +41,7 @@ #include "BLI_blenlib.h" #include "BLI_jitter.h" -#include "MTC_matrixops.h" + #include "DNA_camera_types.h" #include "DNA_group_types.h" diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index af6093ab36c..58101b5126a 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -32,8 +32,8 @@ /* External modules: */ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" + + #include "DNA_camera_types.h" #include "DNA_group_types.h" @@ -153,7 +153,7 @@ static void render_lighting_halo(HaloRen *har, float *colf) /* rotate view to lampspace */ VECCOPY(lvrot, lv); - MTC_Mat3MulVecfl(lar->imat, lvrot); + Mat3MulVecfl(lar->imat, lvrot); x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ @@ -545,7 +545,7 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th VECCOPY(lo, view); if(R.wrld.skytype & WO_SKYREAL) { - MTC_Mat3MulVecfl(R.imat, lo); + Mat3MulVecfl(R.imat, lo); SWAP(float, lo[1], lo[2]); @@ -587,7 +587,7 @@ void shadeSunView(float *colf, float *view) VECCOPY(sview, view); Normalize(sview); - MTC_Mat3MulVecfl(R.imat, sview); + Mat3MulVecfl(R.imat, sview); if (sview[2] < 0.0) sview[2] = 0.0; Normalize(sview); @@ -668,7 +668,7 @@ void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, calc_view_vector(view, fx, fy); Normalize(view); - /*MTC_Mat3MulVecfl(R.imat, view);*/ + /*Mat3MulVecfl(R.imat, view);*/ AtmospherePixleShader(sunsky, view, distance, collector); } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index c53a2b68c9c..cd7a0449d0e 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -26,7 +26,7 @@ #include #include -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" #include "DNA_group_types.h" @@ -403,7 +403,7 @@ void makeshadowbuf(Render *re, LampRen *lar) wsize= shb->pixsize*(shb->size/2.0); i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat); - MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat); + Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat); if(ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) { /* jitter, weights - not threadsafe! */ @@ -673,7 +673,7 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy VECCOPY(co, rco); co[3]= 1.0f; - MTC_Mat4MulVec4fl(shb->persmat, co); /* rational hom co */ + Mat4MulVec4fl(shb->persmat, co); /* rational hom co */ xs1= siz*(1.0f+co[0]/co[3]); ys1= siz*(1.0f+co[1]/co[3]); @@ -714,7 +714,7 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy co[1]= rco[1]+dxco[1]; co[2]= rco[2]+dxco[2]; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ + Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ dx[0]= xs1- siz*(1.0+co[0]/co[3]); dx[1]= ys1- siz*(1.0+co[1]/co[3]); @@ -722,7 +722,7 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy co[1]= rco[1]+dyco[1]; co[2]= rco[2]+dyco[2]; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ + Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ dy[0]= xs1- siz*(1.0+co[0]/co[3]); dy[1]= ys1- siz*(1.0+co[1]/co[3]); @@ -858,7 +858,7 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) co[1]= p1[1]; co[2]= p1[2]/lar->sh_zfac; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ + Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ xf1= siz*(1.0+co[0]/co[3]); yf1= siz*(1.0+co[1]/co[3]); zf1= (co[2]/co[3]); @@ -868,7 +868,7 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) co[1]= p2[1]; co[2]= p2[2]/lar->sh_zfac; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ + Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ xf2= siz*(1.0+co[0]/co[3]); yf2= siz*(1.0+co[1]/co[3]); zf2= (co[2]/co[3]); @@ -1659,7 +1659,7 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *v } /* move 3d vector to lampbuf */ - MTC_Mat4MulVec4fl(shb->persmat, hoco); /* rational hom co */ + Mat4MulVec4fl(shb->persmat, hoco); /* rational hom co */ /* clip We can test for -1.0/1.0 because of the properties of the * coordinate transformations. */ diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 1cd8ec110f9..7e3d906b035 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -29,7 +29,7 @@ #include #include -#include "MTC_matrixops.h" + #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -416,13 +416,13 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert if(texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(R.viewinv, shi->gl); + Mat4MulVecfl(R.viewinv, shi->gl); if(shi->osatex) { VECCOPY(shi->dxgl, shi->dxco); - MTC_Mat3MulVecfl(R.imat, shi->dxco); + Mat3MulVecfl(R.imat, shi->dxco); VECCOPY(shi->dygl, shi->dyco); - MTC_Mat3MulVecfl(R.imat, shi->dyco); + Mat3MulVecfl(R.imat, shi->dyco); } } @@ -974,12 +974,12 @@ void shade_input_set_shade_texco(ShadeInput *shi) if(texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(R.viewinv, shi->gl); + Mat4MulVecfl(R.viewinv, shi->gl); if(shi->osatex) { VECCOPY(shi->dxgl, shi->dxco); - MTC_Mat3MulVecfl(R.imat, shi->dxco); + Mat3MulVecfl(R.imat, shi->dxco); VECCOPY(shi->dygl, shi->dyco); - MTC_Mat3MulVecfl(R.imat, shi->dyco); + Mat3MulVecfl(R.imat, shi->dyco); } } diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 2fbd93df0ce..4bdd0b69699 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -30,7 +30,7 @@ #include #include -#include "MTC_matrixops.h" + #include "BLI_arithb.h" #include "BKE_colortools.h" @@ -168,7 +168,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) p1[0]= shi->co[0]-lar->co[0]; p1[1]= shi->co[1]-lar->co[1]; p1[2]= -lar->co[2]; - MTC_Mat3MulVecfl(lar->imat, p1); + Mat3MulVecfl(lar->imat, p1); VECCOPY(npos, p1); // npos is double! /* pre-scale */ @@ -180,7 +180,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) /* rotate view */ VECCOPY(nray, shi->view); - MTC_Mat3MulVecd(lar->imat, nray); + Mat3MulVecd(lar->imat, nray); if(R.wrld.mode & WO_MIST) { /* patchy... */ @@ -1143,7 +1143,7 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist) /* rotate view to lampspace */ VECCOPY(lvrot, lv); - MTC_Mat3MulVecfl(lar->imat, lvrot); + Mat3MulVecfl(lar->imat, lvrot); x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); /* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 007b69a9b97..3e8cf71605d 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -30,7 +30,7 @@ #include #include -#include "MTC_matrixops.h" + #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -829,7 +829,7 @@ static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float else { VECCOPY(nor, n); } - MTC_Mat4Mul3Vecfl(R.viewinv, nor); + Mat4Mul3Vecfl(R.viewinv, nor); x1= fabs(nor[0]); y1= fabs(nor[1]); @@ -922,7 +922,7 @@ static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *ad if(n==NULL) return 0; VECCOPY(nor, n); - if(ob) MTC_Mat4Mul3Vecfl(ob->imat, nor); + if(ob) Mat4Mul3Vecfl(ob->imat, nor); x1= fabs(nor[0]); y1= fabs(nor[1]); @@ -1540,13 +1540,13 @@ void do_material_tex(ShadeInput *shi) VECCOPY(tempvec, shi->co); if(mtex->texflag & MTEX_OB_DUPLI_ORIG) if(shi->obi && shi->obi->duplitexmat) - MTC_Mat4MulVecfl(shi->obi->duplitexmat, tempvec); - MTC_Mat4MulVecfl(ob->imat, tempvec); + Mat4MulVecfl(shi->obi->duplitexmat, tempvec); + Mat4MulVecfl(ob->imat, tempvec); if(shi->osatex) { VECCOPY(dxt, shi->dxco); VECCOPY(dyt, shi->dyco); - MTC_Mat4Mul3Vecfl(ob->imat, dxt); - MTC_Mat4Mul3Vecfl(ob->imat, dyt); + Mat4Mul3Vecfl(ob->imat, dxt); + Mat4Mul3Vecfl(ob->imat, dyt); } } else { @@ -2237,7 +2237,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f case TEXCO_OBJECT: if(mtex->object) { VECCOPY(tempvec, lo); - MTC_Mat4MulVecfl(mtex->object->imat, tempvec); + Mat4MulVecfl(mtex->object->imat, tempvec); co= tempvec; } break; @@ -2245,16 +2245,16 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f case TEXCO_GLOB: if(rco) { VECCOPY(tempvec, rco); - MTC_Mat4MulVecfl(R.viewinv, tempvec); + Mat4MulVecfl(R.viewinv, tempvec); co= tempvec; } else co= lo; // VECCOPY(shi->dxgl, shi->dxco); -// MTC_Mat3MulVecfl(R.imat, shi->dxco); +// Mat3MulVecfl(R.imat, shi->dxco); // VECCOPY(shi->dygl, shi->dyco); -// MTC_Mat3MulVecfl(R.imat, shi->dyco); +// Mat3MulVecfl(R.imat, shi->dyco); break; } @@ -2376,12 +2376,12 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef dx= dxt; dy= dyt; VECCOPY(tempvec, shi->co); - MTC_Mat4MulVecfl(ob->imat, tempvec); + Mat4MulVecfl(ob->imat, tempvec); if(shi->osatex) { VECCOPY(dxt, shi->dxco); VECCOPY(dyt, shi->dyco); - MTC_Mat4Mul3Vecfl(ob->imat, dxt); - MTC_Mat4Mul3Vecfl(ob->imat, dyt); + Mat4Mul3Vecfl(ob->imat, dxt); + Mat4Mul3Vecfl(ob->imat, dyt); } } else { @@ -2392,12 +2392,12 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef else if(mtex->texco==TEXCO_GLOB) { co= shi->gl; dx= shi->dxco; dy= shi->dyco; VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(R.viewinv, shi->gl); + Mat4MulVecfl(R.viewinv, shi->gl); } else if(mtex->texco==TEXCO_VIEW) { VECCOPY(tempvec, lavec); - MTC_Mat3MulVecfl(la->imat, tempvec); + Mat3MulVecfl(la->imat, tempvec); if(la->type==LA_SPOT) { tempvec[0]*= la->spottexfac; @@ -2410,8 +2410,8 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef VECCOPY(dxt, shi->dxlv); VECCOPY(dyt, shi->dylv); /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ - MTC_Mat3MulVecfl(la->imat, dxt); - MTC_Mat3MulVecfl(la->imat, dyt); + Mat3MulVecfl(la->imat, dxt); + Mat3MulVecfl(la->imat, dyt); VecMulf(dxt, la->spottexfac); VecMulf(dyt, la->spottexfac); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 509ac81c58b..19ec0059a08 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -42,7 +42,7 @@ #include "BLI_jitter.h" #include "BLI_threads.h" -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" #include "DNA_lamp_types.h" @@ -2314,7 +2314,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re hashlist_projectvert(NULL, winmat, NULL); /* needed for projectvert */ - MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat); + Mat4MulMat4(winmat, vw->viewmat, vw->winmat); /* 1.0f for clipping in clippyra()... bad stuff actually */ zbuf_alloc_span(&zspan, vw->rectx, vw->recty, 1.0f); diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index ef37b184a85..fddbadac22d 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -41,7 +41,7 @@ #include "IMB_imbuf.h" -#include "MTC_matrixops.h" + #include "DNA_armature_types.h" #include "DNA_camera_types.h" @@ -1040,7 +1040,7 @@ static void drawcamera(Object *ob, int flag) Mat4Ortho(vec); mymultmatrix(vec); - MTC_Mat4SwapMat4(G.vd->persmat, tmat); + Mat4SwapMat4(G.vd->persmat, tmat); mygetsingmatrix(G.vd->persmat); if(cam->flag & CAM_SHOWLIMITS) { @@ -1053,7 +1053,7 @@ static void drawcamera(Object *ob, int flag) if(cam->flag & CAM_SHOWMIST) if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF); - MTC_Mat4SwapMat4(G.vd->persmat, tmat); + Mat4SwapMat4(G.vd->persmat, tmat); } } } diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index f6a0b88cbc8..1430c6ad0d5 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -39,7 +39,7 @@ #include "BLI_edgehash.h" #include "BLI_editVert.h" -#include "MTC_matrixops.h" + #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c index 682125dabb1..30097f9e786 100644 --- a/source/blender/src/editfont.c +++ b/source/blender/src/editfont.c @@ -42,7 +42,7 @@ #include #endif -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 3dbbe7d7336..980478945cb 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -39,7 +39,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "MEM_guardedalloc.h" -#include "MTC_matrixops.h" + #include "DNA_mesh_types.h" #include "DNA_material_types.h" diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 0fb072c1af4..4c72d7450b6 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -106,7 +106,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "editmesh.h" -#include "MTC_vectorops.h" + #include "PIL_time.h" diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c index 4be00b63ecb..c176ff7800e 100644 --- a/source/blender/src/fluidsim.c +++ b/source/blender/src/fluidsim.c @@ -57,7 +57,7 @@ #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_arithb.h" -#include "MTC_matrixops.h" + #include "BKE_customdata.h" #include "BKE_displist.h" @@ -801,7 +801,7 @@ void fluidsimBake(struct Object *ob) } // init trafo matrix - MTC_Mat4CpyMat4(domainMat, fsDomain->obmat); + Mat4CpyMat4(domainMat, fsDomain->obmat); if(!Mat4Invert(invDomMat, domainMat)) { snprintf(debugStrBuffer,256,"fluidsimBake::error - Invalid obj matrix?\n"); elbeemDebugOut(debugStrBuffer); diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 21be4b2cf49..98cdb99b6d2 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -47,7 +47,7 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" -#include "MTC_matrixops.h" + #include "DNA_texture_types.h" #include "DNA_world_types.h" diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 8da5e1b2572..2b4c4b33ddf 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -43,7 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" -#include "MTC_matrixops.h" + #include "DNA_action_types.h" #include "DNA_armature_types.h" @@ -1204,7 +1204,7 @@ void weight_paint(void) else totindex= 0; } - MTC_Mat4SwapMat4(G.vd->persmat, mat); + Mat4SwapMat4(G.vd->persmat, mat); if(Gwp.flag & VP_COLINDEX) { for(index=0; indexpersmat, mat); + Mat4SwapMat4(G.vd->persmat, mat); } else BIF_wait_for_statechange(); @@ -1436,7 +1436,7 @@ void vertex_paint() else totindex= 0; } - MTC_Mat4SwapMat4(G.vd->persmat, mat); + Mat4SwapMat4(G.vd->persmat, mat); if(Gvp.flag & VP_COLINDEX) { for(index=0; indexpersmat, mat); + Mat4SwapMat4(G.vd->persmat, mat); do_shared_vertexcol(me); diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index ea700965826..425ec66bab3 100644 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -6,6 +6,8 @@ using namespace std; +#define MTC_cp3Float(_a, _b) VecCopyf(_b, _a) + static string command_path = ""; #ifdef WIN32 @@ -20,7 +22,6 @@ static string command_path = ""; #define FILE_MAXFILE 80 #endif - static string find_path() { HKEY hkey; @@ -1036,10 +1037,10 @@ void yafrayFileRender_t::writeMaterialsAndModulators() // In this case this means the inverse of that matrix float texmat[4][4], itexmat[4][4]; if ((mtex->texco & TEXCO_OBJECT) && (mtex->object)) - MTC_Mat4CpyMat4(texmat, mtex->object->obmat); + Mat4CpyMat4(texmat, mtex->object->obmat); else // also for refl. map - MTC_Mat4CpyMat4(texmat, maincam_obj->obmat); - MTC_Mat4Invert(itexmat, texmat); + Mat4CpyMat4(texmat, maincam_obj->obmat); + Mat4Invert(itexmat, texmat); ostr << "\n\t\tm00=\"" << itexmat[0][0] << "\" m01=\"" << itexmat[1][0] << "\" m02=\"" << itexmat[2][0] << "\" m03=\"" << itexmat[3][0] << "\"\n"; ostr << "\t\tm10=\"" << itexmat[0][1] << "\" m11=\"" << itexmat[1][1] @@ -1304,8 +1305,8 @@ void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vectorimat is no longer valid, // so have to create inverse render matrix ourselves here float mat[4][4], imat[4][4]; - MTC_Mat4MulMat4(mat, obj->obmat, re->viewmat); - MTC_Mat4Invert(imat, mat); + Mat4MulMat4(mat, obj->obmat, re->viewmat); + Mat4Invert(imat, mat); for (vector::const_iterator fci=VLR_list.begin(); fci!=VLR_list.end();++fci) @@ -1319,7 +1320,7 @@ void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vectorv1] = vidx++; ver = vlr->v1; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); ostr << "\t\t\t

\n"; @@ -1340,7 +1341,7 @@ void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vectorv2] = vidx++; ver = vlr->v2; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); ostr << "\t\t\t

\n"; @@ -1361,7 +1362,7 @@ void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vectorv3] = vidx++; ver = vlr->v3; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); ostr << "\t\t\t

\n"; @@ -1382,7 +1383,7 @@ void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vectorv4] = vidx++; ver = vlr->v4; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); ostr << "\t\t\t

\n"; @@ -1532,7 +1533,7 @@ void yafrayFileRender_t::writeAllObjects() for (int j=0;j<4;j++) obmat[i][j] = dupMtx->second[(i<<2)+j]; - MTC_Mat4Invert(imat, obmat); + Mat4Invert(imat, obmat); // first object written as normal (but with transform of first duplivert) Object* obj = dup_srcob[dupMtx->first]; @@ -1546,7 +1547,7 @@ void yafrayFileRender_t::writeAllObjects() for (int j=0;j<4;j++) nmat[i][j] = dupMtx->second[curmtx+(i<<2)+j]; - MTC_Mat4MulMat4(cmat, imat, nmat); // transform with respect to original = inverse_original * new + Mat4MulMat4(cmat, imat, nmat); // transform with respect to original = inverse_original * new ostr.str(""); // yafray matrix = transpose of Blender @@ -1592,13 +1593,13 @@ void yafrayFileRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][4] // transform area lamp coords back to world float lpco[4][3]; MTC_cp3Float(a, lpco[0]); - MTC_Mat4MulVecfl(iview, lpco[0]); + Mat4MulVecfl(iview, lpco[0]); MTC_cp3Float(b, lpco[1]); - MTC_Mat4MulVecfl(iview, lpco[1]); + Mat4MulVecfl(iview, lpco[1]); MTC_cp3Float(c, lpco[2]); - MTC_Mat4MulVecfl(iview, lpco[2]); + Mat4MulVecfl(iview, lpco[2]); MTC_cp3Float(d, lpco[3]); - MTC_Mat4MulVecfl(iview, lpco[3]); + Mat4MulVecfl(iview, lpco[3]); ostr << "\t\n"; ostr << "\t\n"; ostr << "\t\n"; @@ -1618,7 +1619,7 @@ void yafrayFileRender_t::writeLamps() float iview[4][4]; // re->viewinv != inv.re->viewmat because of possible ortho mode (see convertBlenderScene.c) // have to invert it here - MTC_Mat4Invert(iview, re->viewmat); + Mat4Invert(iview, re->viewmat); // all lamps for(go=(GroupObject *)re->lights.first; go; go= go->next, i++) { @@ -1751,9 +1752,9 @@ void yafrayFileRender_t::writeLamps() // transform lamp co & vec back to world float lpco[3], lpvec[3]; MTC_cp3Float(lamp->co, lpco); - MTC_Mat4MulVecfl(iview, lpco); + Mat4MulVecfl(iview, lpco); MTC_cp3Float(lamp->vec, lpvec); - MTC_Mat4Mul3Vecfl(iview, lpvec); + Mat4Mul3Vecfl(iview, lpvec); // position, (==-blendir for sun/hemi) if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp index db9fb7ccc72..cabb90f44c4 100644 --- a/source/blender/yafray/intern/export_Plugin.cpp +++ b/source/blender/yafray/intern/export_Plugin.cpp @@ -6,6 +6,7 @@ using namespace std; +#define MTC_cp3Float(_a, _b) VecCopyf(_b, _a) #ifdef WIN32 #define WIN32_SKIP_HKEY_PROTECTION @@ -19,7 +20,6 @@ using namespace std; #define FILE_MAXFILE 80 #endif - static string find_path() { HKEY hkey; @@ -939,10 +939,10 @@ void yafrayPluginRender_t::writeMaterialsAndModulators() // In this case this means the inverse of that matrix float texmat[4][4], itexmat[4][4]; if ((mtex->texco & TEXCO_OBJECT) && (mtex->object)) - MTC_Mat4CpyMat4(texmat, mtex->object->obmat); + Mat4CpyMat4(texmat, mtex->object->obmat); else // also for refl. map - MTC_Mat4CpyMat4(texmat, maincam_obj->obmat); - MTC_Mat4Invert(itexmat, texmat); + Mat4CpyMat4(texmat, maincam_obj->obmat); + Mat4Invert(itexmat, texmat); #define flp yafray::parameter_t params["m00"]=flp(itexmat[0][0]); params["m01"]=flp(itexmat[1][0]); params["m02"]=flp(itexmat[2][0]); params["m03"]=flp(itexmat[3][0]); @@ -1231,15 +1231,15 @@ void yafrayPluginRender_t::genVertices(vector &verts, int &vi // for deformed objects, object->imat is no longer valid, // so have to create inverse render matrix ourselves here float mat[4][4], imat[4][4]; - MTC_Mat4MulMat4(mat, obj->obmat, re->viewmat); - MTC_Mat4Invert(imat, mat); + Mat4MulMat4(mat, obj->obmat, re->viewmat); + Mat4Invert(imat, mat); if (vert_idx.find(vlr->v1)==vert_idx.end()) { vert_idx[vlr->v1] = vidx++; ver = vlr->v1; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); // has_orco now an int, if 1 -> strand mapping, if 2 -> normal orco mapping if (has_orco==1) @@ -1252,7 +1252,7 @@ void yafrayPluginRender_t::genVertices(vector &verts, int &vi vert_idx[vlr->v2] = vidx++; ver = vlr->v2; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); // has_orco now an int, if 1 -> strand mapping, if 2 -> normal orco mapping if (has_orco==1) @@ -1265,7 +1265,7 @@ void yafrayPluginRender_t::genVertices(vector &verts, int &vi vert_idx[vlr->v3] = vidx++; ver = vlr->v3; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); // has_orco now an int, if 1 -> strand mapping, if 2 -> normal orco mapping if (has_orco==1) @@ -1278,7 +1278,7 @@ void yafrayPluginRender_t::genVertices(vector &verts, int &vi vert_idx[vlr->v4] = vidx++; ver = vlr->v4; MTC_cp3Float(ver->co, tvec); - MTC_Mat4MulVecfl(imat, tvec); + Mat4MulVecfl(imat, tvec); verts.push_back(yafray::point3d_t(tvec[0], tvec[1], tvec[2])); // has_orco now an int, if 1 -> strand mapping, if 2 -> normal orco mapping if (has_orco==1) @@ -1414,7 +1414,7 @@ void yafrayPluginRender_t::writeAllObjects() for (int i=0;i<4;i++) for (int j=0;j<4;j++) obmat[i][j] = dupMtx->second[(i<<2)+j]; - MTC_Mat4Invert(imat, obmat); + Mat4Invert(imat, obmat); // first object written as normal (but with transform of first duplivert) Object* obj = dup_srcob[dupMtx->first]; @@ -1428,7 +1428,7 @@ void yafrayPluginRender_t::writeAllObjects() for (int j=0;j<4;j++) nmat[i][j] = dupMtx->second[curmtx+(i<<2)+j]; - MTC_Mat4MulMat4(cmat, imat, nmat); // transform with respect to original = inverse_original * new + Mat4MulMat4(cmat, imat, nmat); // transform with respect to original = inverse_original * new float mtr[4*4]; mtr[0*4+0]=cmat[0][0]; mtr[0*4+1]=cmat[1][0]; mtr[0*4+2]=cmat[2][0]; mtr[0*4+3]=cmat[3][0]; @@ -1475,13 +1475,13 @@ void yafrayPluginRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][ // transform area lamp coords back to world float lpco[4][3]; MTC_cp3Float(a, lpco[0]); - MTC_Mat4MulVecfl(iview, lpco[0]); + Mat4MulVecfl(iview, lpco[0]); MTC_cp3Float(b, lpco[1]); - MTC_Mat4MulVecfl(iview, lpco[1]); + Mat4MulVecfl(iview, lpco[1]); MTC_cp3Float(c, lpco[2]); - MTC_Mat4MulVecfl(iview, lpco[2]); + Mat4MulVecfl(iview, lpco[2]); MTC_cp3Float(d, lpco[3]); - MTC_Mat4MulVecfl(iview, lpco[3]); + Mat4MulVecfl(iview, lpco[3]); params["a"] = yafray::parameter_t(yafray::point3d_t(lpco[0][0], lpco[0][1], lpco[0][2])); params["b"] = yafray::parameter_t(yafray::point3d_t(lpco[1][0], lpco[1][1], lpco[1][2])); params["c"] = yafray::parameter_t(yafray::point3d_t(lpco[2][0], lpco[2][1], lpco[2][2])); @@ -1500,7 +1500,7 @@ void yafrayPluginRender_t::writeLamps() float iview[4][4]; // re->viewinv != inv.re->viewmat because of possible ortho mode (see convertBlenderScene.c) // have to invert it here - MTC_Mat4Invert(iview, re->viewmat); + Mat4Invert(iview, re->viewmat); // all lamps for(go=(GroupObject *)re->lights.first; go; go= go->next, i++) @@ -1641,9 +1641,9 @@ void yafrayPluginRender_t::writeLamps() // transform lamp co & vec back to world float lpco[3], lpvec[3]; MTC_cp3Float(lamp->co, lpco); - MTC_Mat4MulVecfl(iview, lpco); + Mat4MulVecfl(iview, lpco); MTC_cp3Float(lamp->vec, lpvec); - MTC_Mat4Mul3Vecfl(iview, lpvec); + Mat4Mul3Vecfl(iview, lpvec); // position, (==-blendir for sun/hemi) if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) diff --git a/source/blender/yafray/intern/yafray_Render.cpp b/source/blender/yafray/intern/yafray_Render.cpp index 01da4683d71..97a3f3b518a 100644 --- a/source/blender/yafray/intern/yafray_Render.cpp +++ b/source/blender/yafray/intern/yafray_Render.cpp @@ -85,7 +85,7 @@ bool yafrayRender_t::getAllMatTexObs() if(obi->flag & R_DUPLI_TRANSFORMED) { // compute object matrix with dupli transform, need to transform // obi->mat out of view space for it - MTC_Mat4MulSerie(mat, re->viewinv, obi->mat, re->viewmat, obi->obr->ob->obmat, 0, 0, 0, 0); + Mat4MulSerie(mat, re->viewinv, obi->mat, re->viewmat, obi->obr->ob->obmat, 0, 0, 0, 0); addDupliMtx(obi->obr->ob, mat); } } diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h index 43d2c6c602a..b3ab12e8ae9 100644 --- a/source/blender/yafray/intern/yafray_Render.h +++ b/source/blender/yafray/intern/yafray_Render.h @@ -29,8 +29,7 @@ extern "C" { #include "renderpipeline.h" /* useful matrix & vector operations */ -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" +#include "BLI_arithb.h" #include "BLI_blenlib.h" -- cgit v1.2.3 From d1c90f4bef6de71087cdcaaa6afd055e49bb893c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Sep 2009 00:36:26 +0000 Subject: =?UTF-8?q?easier=20to=20re-apply=20the=20replacement=20table=20th?= =?UTF-8?q?en=20merge=20from=202.4x=EF=BB=BF,=20same=20as=2023023?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit replacements... MTC_cross3Float -> Crossf MTC_diff3Float -> VecSubf MTC_dot3Float -> Inpf MTC_Mat3CpyMat4 -> Mat3CpyMat4 MTC_Mat3MulVecd -> Mat3MulVecd MTC_Mat3MulVecfl -> Mat3MulVecfl MTC_Mat4CpyMat4 -> Mat4CpyMat4 MTC_Mat4Invert -> Mat4Invert MTC_Mat4Mul3Vecfl -> Mat4Mul3Vecfl MTC_Mat4MulMat4 -> Mat4MulMat4 MTC_Mat4MulSerie -> Mat4MulSerie MTC_Mat4MulVec4fl -> Mat4MulVec4fl MTC_Mat4MulVecfl -> Mat4MulVecfl MTC_Mat4One -> Mat4One MTC_Mat4Ortho -> Mat4Ortho MTC_Mat4SwapMat4 -> Mat4SwapMat4 --- source/blender/blenkernel/intern/modifier.c | 34 +- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenlib/MTC_matrixops.h | 162 -------- source/blender/blenlib/MTC_vectorops.h | 58 --- source/blender/blenlib/intern/matrixops.c | 438 --------------------- source/blender/blenlib/intern/vectorops.c | 166 -------- source/blender/editors/mesh/editmesh_mods.c | 2 +- source/blender/editors/sculpt_paint/paint_vertex.c | 10 +- source/blender/editors/space_view3d/drawobject.c | 6 +- source/blender/editors/space_view3d/drawvolume.c | 2 +- source/blender/nodes/intern/TEX_nodes/TEX_rotate.c | 8 +- .../blender/render/intern/source/convertblender.c | 102 ++--- source/blender/render/intern/source/envmap.c | 80 ++-- source/blender/render/intern/source/initrender.c | 2 +- source/blender/render/intern/source/pixelshading.c | 12 +- source/blender/render/intern/source/shadbuf.c | 16 +- source/blender/render/intern/source/shadeinput.c | 18 +- source/blender/render/intern/source/shadeoutput.c | 8 +- source/blender/render/intern/source/texture.c | 44 +-- source/blender/render/intern/source/zbuf.c | 2 +- 20 files changed, 174 insertions(+), 998 deletions(-) delete mode 100644 source/blender/blenlib/MTC_matrixops.h delete mode 100644 source/blender/blenlib/MTC_vectorops.h delete mode 100644 source/blender/blenlib/intern/matrixops.c delete mode 100644 source/blender/blenlib/intern/vectorops.c diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9c8c43cc8cb..f06173264ee 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -73,8 +73,8 @@ #include "BLI_editVert.h" -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" + + #include "BKE_main.h" #include "BKE_anim.h" @@ -1190,7 +1190,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if(amd->end_cap && amd->end_cap != ob) end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH); - MTC_Mat4One(offset); + Mat4One(offset); indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm), "indexmap"); @@ -1212,14 +1212,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, float result_mat[4][4]; if(ob) - MTC_Mat4Invert(obinv, ob->obmat); + Mat4Invert(obinv, ob->obmat); else - MTC_Mat4One(obinv); + Mat4One(obinv); - MTC_Mat4MulSerie(result_mat, offset, + Mat4MulSerie(result_mat, offset, obinv, amd->offset_ob->obmat, NULL, NULL, NULL, NULL, NULL); - MTC_Mat4CpyMat4(offset, result_mat); + Mat4CpyMat4(offset, result_mat); } if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) { @@ -1244,7 +1244,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, prescribed length */ if(amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) { - float dist = sqrt(MTC_dot3Float(offset[3], offset[3])); + float dist = sqrt(Inpf(offset[3], offset[3])); if(dist > 1e-6f) /* this gives length = first copy start to last copy end @@ -1277,11 +1277,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces); /* calculate the offset matrix of the final copy (for merging) */ - MTC_Mat4One(final_offset); + Mat4One(final_offset); for(j=0; j < count - 1; j++) { - MTC_Mat4MulMat4(tmp_mat, final_offset, offset); - MTC_Mat4CpyMat4(final_offset, tmp_mat); + Mat4MulMat4(tmp_mat, final_offset, offset); + Mat4CpyMat4(final_offset, tmp_mat); } numVerts = numEdges = numFaces = 0; @@ -1317,7 +1317,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if((count > 1) && (amd->flags & MOD_ARR_MERGE)) { float tmp_co[3]; VECCOPY(tmp_co, mv->co); - MTC_Mat4MulVecfl(offset, tmp_co); + Mat4MulVecfl(offset, tmp_co); for(j = 0; j < maxVerts; j++) { /* if vertex already merged, don't use it */ @@ -1332,7 +1332,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, if(amd->flags & MOD_ARR_MERGEFINAL) { VECCOPY(tmp_co, inMV->co); inMV = &src_mvert[i]; - MTC_Mat4MulVecfl(final_offset, tmp_co); + Mat4MulVecfl(final_offset, tmp_co); if(VecLenCompare(tmp_co, inMV->co, amd->merge_dist)) indexMap[i].merge_final = 1; } @@ -1350,7 +1350,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, *mv2 = *mv; numVerts++; - MTC_Mat4MulVecfl(offset, co); + Mat4MulVecfl(offset, co); VECCOPY(mv2->co, co); } } else if(indexMap[i].merge != i && indexMap[i].merge_final) { @@ -3182,7 +3182,7 @@ static void tag_and_count_extra_edges(SmoothMesh *mesh, float split_angle, /* we know the edge has 2 faces, so check the angle */ SmoothFace *face1 = edge->faces->link; SmoothFace *face2 = edge->faces->next->link; - float edge_angle_cos = MTC_dot3Float(face1->normal, + float edge_angle_cos = Inpf(face1->normal, face2->normal); if(edge_angle_cos < threshold) { @@ -4051,11 +4051,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, /* find the projector which the face points at most directly * (projector normal with largest dot product is best) */ - best_dot = MTC_dot3Float(projectors[0].normal, face_no); + best_dot = Inpf(projectors[0].normal, face_no); best_projector = &projectors[0]; for(j = 1; j < num_projectors; ++j) { - float tmp_dot = MTC_dot3Float(projectors[j].normal, + float tmp_dot = Inpf(projectors[j].normal, face_no); if(tmp_dot > best_dot) { best_dot = tmp_dot; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 61f62b2222d..fe8b97db606 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -38,7 +38,7 @@ #include "PIL_dynlib.h" -#include "MTC_matrixops.h" + #include "BLI_blenlib.h" #include "BLI_arithb.h" diff --git a/source/blender/blenlib/MTC_matrixops.h b/source/blender/blenlib/MTC_matrixops.h deleted file mode 100644 index 2bc644be564..00000000000 --- a/source/blender/blenlib/MTC_matrixops.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * matrixops.h - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef MATRIXOPS_H -#define MATRIXOPS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------------------------------------------------------------- */ -/* need rewriting: */ -/** - * copy the left upp3 3 by 3 of m2 to m1 - */ -void MTC_Mat3CpyMat4(float m1[][3], float m2[][4]); - -/* ------------------------------------------------------------------------- */ -/* operations based on 4 by 4 matrices */ - -/** - * Copy m1 to m2 - */ -void MTC_Mat4CpyMat4(float m1[][4], float m2[][4]); - -/** - * Multiply all matrices after the first, leave the result in the - * first argument - */ -void MTC_Mat4MulSerie(float answ[][4], - float m1[][4], float m2[][4], float m3[][4], - float m4[][4], float m5[][4], float m6[][4], - float m7[][4], float m8[][4]); - -/** - * m1 = m2 matprod m3 - */ -void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]); - -/** - * Do vec^t prod mat, result in vec. Ignore vec[3] (vec is a - * float[3]) - */ -void MTC_Mat4MulVecfl(float mat[][4], float *vec); - -/** - * Invert mat, result in inverse. Always returns 1 - */ -int MTC_Mat4Invert(float inverse[][4], float mat[][4]); - -/** - * Make the set of mat orthonormal (mat should already be orthogonal)? - * (doesn't appear to normalize properly?) - */ -void MTC_Mat4Ortho(float mat[][4]); - -/** - * vec = mat prod vec, result in vec, ignore fourth component entirely - * (4th component is _not_ accessed!!! vec is 3d) - */ -void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec); - -/** - * vec = mat prod vec, result in vec - */ -void MTC_Mat4MulVec4fl(float mat[][4], float *vec); - -/** - * Set to the 4-D unity matrix - */ -void MTC_Mat4One(float m[][4]); - -/** - * Swap matrices m1 and m2 - */ -void MTC_Mat4SwapMat4(float m1[][4], float m2[][4]); - -/** - * Copy m2 to the top-left 3x3 of m1, don't touch the remaining elements. - */ -void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]); - -/** - * m1 = m2 * m3, but only the top-left 3x3 - */ -void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3]); - -/* ------------------------------------------------------------------------- */ -/* Operations based on 3 by 3 matrices */ -/** - * Do vec^t prod mat, result in vec.(vex is 3d) - */ -void MTC_Mat3MulVecfl(float mat[][3], float *vec); - -/** - * Copy m1 to m2 - */ -void MTC_Mat3CpyMat3(float m1[][3], float m2[][3]); - -/** - * m1 = m2 prod m3 - */ -void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]); - -/** - * vec = vec prod mat - */ -void MTC_Mat3MulVecd(float mat[][3], double *vec); - -/** - * Guess: invert matrix - * result goes to m1 - */ -void MTC_Mat3Inv(float m1[][3], float m2[][3]); - -/** - * Sort of a determinant matrix? Doesn't seem very adjoint to me... - * result goes to m1 - */ -void MTC_Mat3Adj(float m1[][3], float m[][3]); - -/** - * Set to the 3D unity matrix - */ -void MTC_Mat3One(float m[][3]); - -/* ------------------------------------------------------------------------- */ - -#ifdef __cplusplus -} -#endif - -#endif /* MATRIXOPS_H */ - diff --git a/source/blender/blenlib/MTC_vectorops.h b/source/blender/blenlib/MTC_vectorops.h deleted file mode 100644 index 4fec93b37b9..00000000000 --- a/source/blender/blenlib/MTC_vectorops.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * vectorops.h - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef VECTOROPS_H -#define VECTOROPS_H - -/* ------------------------------------------------------------------------- */ - -void MTC_diff3Int(int v1[3], int v2[3], int v3[3]); -void MTC_cross3Int(int v1[3], int v2[3], int v3[3]); -int MTC_dot3Int(int v1[3], int v2[3]); - -void MTC_diff3Float(float v1[3], float v2[3], float v3[3]); -void MTC_cross3Float(float v1[3], float v2[3], float v3[3]); -float MTC_dot3Float(float v1[3], float v2[3]); -void MTC_cp3Float(float v1[3], float v2[3]); -/** - * Copy vector with a minus sign (so a = -b) - */ -void MTC_cp3FloatInv(float v1[3], float v2[3]); - -void MTC_swapInt(int *i1, int *i2); - -void MTC_diff3DFF(double v1[3], float v2[3], float v3[3]); -void MTC_cross3Double(double v1[3], double v2[3], double v3[3]); -float MTC_normalize3DF(float n[3]); - -/* ------------------------------------------------------------------------- */ -#endif /* VECTOROPS_H */ - diff --git a/source/blender/blenlib/intern/matrixops.c b/source/blender/blenlib/intern/matrixops.c deleted file mode 100644 index 0f9fc65f016..00000000000 --- a/source/blender/blenlib/intern/matrixops.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * - * Some matrix operations. - * - * Always use - * - vector with x components : float x[3], int x[3], etc - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* ------------------------------------------------------------------------- */ -#include -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" -/* ------------------------------------------------------------------------- */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__) -#include -#endif - -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } - -void MTC_Mat4CpyMat4(float m1[][4], float m2[][4]) -{ - memcpy(m1, m2, 4*4*sizeof(float)); -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulSerie(float answ[][4], - float m1[][4], float m2[][4], float m3[][4], - float m4[][4], float m5[][4], float m6[][4], - float m7[][4], float m8[][4]) -{ - float temp[4][4]; - - if(m1==0 || m2==0) return; - - MTC_Mat4MulMat4(answ, m2, m1); - if(m3) { - MTC_Mat4MulMat4(temp, m3, answ); - if(m4) { - MTC_Mat4MulMat4(answ, m4, temp); - if(m5) { - MTC_Mat4MulMat4(temp, m5, answ); - if(m6) { - MTC_Mat4MulMat4(answ, m6, temp); - if(m7) { - MTC_Mat4MulMat4(temp, m7, answ); - if(m8) { - MTC_Mat4MulMat4(answ, m8, temp); - } - else MTC_Mat4CpyMat4(answ, temp); - } - } - else MTC_Mat4CpyMat4(answ, temp); - } - } - else MTC_Mat4CpyMat4(answ, temp); - } -} - -/* ------------------------------------------------------------------------- */ -void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]) -{ - /* matrix product: c[j][k] = a[j][i].b[i][k] */ - - m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0]; - m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1]; - m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2]; - m1[0][3] = m2[0][0]*m3[0][3] + m2[0][1]*m3[1][3] + m2[0][2]*m3[2][3] + m2[0][3]*m3[3][3]; - - m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0] + m2[1][3]*m3[3][0]; - m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1] + m2[1][3]*m3[3][1]; - m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2] + m2[1][3]*m3[3][2]; - m1[1][3] = m2[1][0]*m3[0][3] + m2[1][1]*m3[1][3] + m2[1][2]*m3[2][3] + m2[1][3]*m3[3][3]; - - m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0] + m2[2][3]*m3[3][0]; - m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1] + m2[2][3]*m3[3][1]; - m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2] + m2[2][3]*m3[3][2]; - m1[2][3] = m2[2][0]*m3[0][3] + m2[2][1]*m3[1][3] + m2[2][2]*m3[2][3] + m2[2][3]*m3[3][3]; - - m1[3][0] = m2[3][0]*m3[0][0] + m2[3][1]*m3[1][0] + m2[3][2]*m3[2][0] + m2[3][3]*m3[3][0]; - m1[3][1] = m2[3][0]*m3[0][1] + m2[3][1]*m3[1][1] + m2[3][2]*m3[2][1] + m2[3][3]*m3[3][1]; - m1[3][2] = m2[3][0]*m3[0][2] + m2[3][1]*m3[1][2] + m2[3][2]*m3[2][2] + m2[3][3]*m3[3][2]; - m1[3][3] = m2[3][0]*m3[0][3] + m2[3][1]*m3[1][3] + m2[3][2]*m3[2][3] + m2[3][3]*m3[3][3]; - -} -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulVecfl(float mat[][4], float *vec) -{ - float x,y; - - x=vec[0]; - y=vec[1]; - vec[0]=x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0]; - vec[1]=x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1]; - vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; -} - -/* ------------------------------------------------------------------------- */ -void MTC_Mat3MulVecfl(float mat[][3], float *vec) -{ - float x,y; - - x=vec[0]; - y=vec[1]; - vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; - vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; - vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; -} - -/* ------------------------------------------------------------------------- */ - -int MTC_Mat4Invert(float inverse[][4], float mat[][4]) -{ - int i, j, k; - double temp; - float tempmat[4][4]; - float max; - int maxj; - - /* Set inverse to identity */ - for (i=0; i<4; i++) - for (j=0; j<4; j++) - inverse[i][j] = 0; - for (i=0; i<4; i++) - inverse[i][i] = 1; - - /* Copy original matrix so we don't mess it up */ - for(i = 0; i < 4; i++) - for(j = 0; j <4; j++) - tempmat[i][j] = mat[i][j]; - - for(i = 0; i < 4; i++) { - /* Look for row with max pivot */ - max = ABS(tempmat[i][i]); - maxj = i; - for(j = i + 1; j < 4; j++) { - if(ABS(tempmat[j][i]) > max) { - max = ABS(tempmat[j][i]); - maxj = j; - } - } - /* Swap rows if necessary */ - if (maxj != i) { - for( k = 0; k < 4; k++) { - SWAP(float, tempmat[i][k], tempmat[maxj][k]); - SWAP(float, inverse[i][k], inverse[maxj][k]); - } - } - - temp = tempmat[i][i]; - if (temp == 0) - return 0; /* No non-zero pivot */ - for(k = 0; k < 4; k++) { - tempmat[i][k] /= temp; - inverse[i][k] /= temp; - } - for(j = 0; j < 4; j++) { - if(j != i) { - temp = tempmat[j][i]; - for(k = 0; k < 4; k++) { - tempmat[j][k] -= tempmat[i][k]*temp; - inverse[j][k] -= inverse[i][k]*temp; - } - } - } - } - return 1; -} - -/* ------------------------------------------------------------------------- */ -void MTC_Mat3CpyMat4(float m1[][3], float m2[][4]) -{ - - m1[0][0]= m2[0][0]; - m1[0][1]= m2[0][1]; - m1[0][2]= m2[0][2]; - - m1[1][0]= m2[1][0]; - m1[1][1]= m2[1][1]; - m1[1][2]= m2[1][2]; - - m1[2][0]= m2[2][0]; - m1[2][1]= m2[2][1]; - m1[2][2]= m2[2][2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3CpyMat3(float m1[][3], float m2[][3]) -{ - memcpy(m1, m2, 3*3*sizeof(float)); -} - -/* ------------------------------------------------------------------------- */ -/* void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ -void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) -{ - /* be careful about this rewrite... */ - /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */ - m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; - m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; - m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; - - m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; - m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; - m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; - - m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; - m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; - m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; - -/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ -/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ -/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ -/* m1+=3; */ -/* m2+=3; */ -/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ -/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ -/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ -/* m1+=3; */ -/* m2+=3; */ -/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ -/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ -/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ -} /* end of void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4Ortho(float mat[][4]) -{ - float len; - - len= MTC_normalize3DF(mat[0]); - if(len!=0.0) mat[0][3]/= len; - len= MTC_normalize3DF(mat[1]); - if(len!=0.0) mat[1][3]/= len; - len= MTC_normalize3DF(mat[2]); - if(len!=0.0) mat[2][3]/= len; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec) -{ - float x,y; - /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/ - - x= vec[0]; - y= vec[1]; - vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; - vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; - vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4One(float m[][4]) -{ - - m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0; - m[0][1]= m[0][2]= m[0][3]= 0.0; - m[1][0]= m[1][2]= m[1][3]= 0.0; - m[2][0]= m[2][1]= m[2][3]= 0.0; - m[3][0]= m[3][1]= m[3][2]= 0.0; -} - - -/* ------------------------------------------------------------------------- */ -/* Result is a 3-vector!*/ -void MTC_Mat3MulVecd(float mat[][3], double *vec) -{ - double x,y; - - /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/ - x=vec[0]; - y=vec[1]; - vec[0]= x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2]; - vec[1]= x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2]; - vec[2]= x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3Inv(float m1[][3], float m2[][3]) -{ - short a,b; - float det; - - /* first adjoint */ - MTC_Mat3Adj(m1,m2); - - /* then determinant old mat! */ - det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1]) - -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1]) - +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]); - - if(det==0) det=1; - det= 1/det; - for(a=0;a<3;a++) { - for(b=0;b<3;b++) { - m1[a][b]*=det; - } - } -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3Adj(float m1[][3], float m[][3]) -{ - m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1]; - m1[0][1]= -m[0][1]*m[2][2]+m[0][2]*m[2][1]; - m1[0][2]=m[0][1]*m[1][2]-m[0][2]*m[1][1]; - - m1[1][0]= -m[1][0]*m[2][2]+m[1][2]*m[2][0]; - m1[1][1]=m[0][0]*m[2][2]-m[0][2]*m[2][0]; - m1[1][2]= -m[0][0]*m[1][2]+m[0][2]*m[1][0]; - - m1[2][0]=m[1][0]*m[2][1]-m[1][1]*m[2][0]; - m1[2][1]= -m[0][0]*m[2][1]+m[0][1]*m[2][0]; - m1[2][2]=m[0][0]*m[1][1]-m[0][1]*m[1][0]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat3One(float m[][3]) -{ - - m[0][0]= m[1][1]= m[2][2]= 1.0; - m[0][1]= m[0][2]= 0.0; - m[1][0]= m[1][2]= 0.0; - m[2][0]= m[2][1]= 0.0; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4SwapMat4(float m1[][4], float m2[][4]) -{ - float t; - int i, j; - - for(i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - t = m1[i][j]; - m1[i][j] = m2[i][j]; - m2[i][j] = t; - } - } -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulVec4fl(float mat[][4], float *vec) -{ - float x,y,z; - - x = vec[0]; - y = vec[1]; - z = vec[2]; - vec[0] = x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3]; - vec[1] = x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3]; - vec[2] = x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3]; - vec[3] = x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]) /* no clear */ -{ - m1[0][0]= m2[0][0]; - m1[0][1]= m2[0][1]; - m1[0][2]= m2[0][2]; - - m1[1][0]= m2[1][0]; - m1[1][1]= m2[1][1]; - m1[1][2]= m2[1][2]; - - m1[2][0]= m2[2][0]; - m1[2][1]= m2[2][1]; - m1[2][2]= m2[2][2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3]) -{ - /* m1_i_j = m2_i_k * m3_k_j ? */ - - m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; - m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; - m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; - - m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; - m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; - m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; - - m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; - m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; - m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; - -} - -/* ------------------------------------------------------------------------- */ - -/* eof */ diff --git a/source/blender/blenlib/intern/vectorops.c b/source/blender/blenlib/intern/vectorops.c deleted file mode 100644 index 3bff5235cfd..00000000000 --- a/source/blender/blenlib/intern/vectorops.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * - * Some vector operations. - * - * Always use - * - vector with x components : float x[3], int x[3], etc - * - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* ------------------------------------------------------------------------- */ -/* General format: op(a, b, c): a = b op c */ -/* Copying is done cp */ -/* ------------------------------------------------------------------------- */ - -#include "MTC_vectorops.h" -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -void MTC_diff3Int(int v1[3], int v2[3], int v3[3]) -{ - v1[0] = v2[0] - v3[0]; - v1[1] = v2[1] - v3[1]; - v1[2] = v2[2] - v3[2]; -} - -/* ------------------------------------------------------------------------- */ -void MTC_diff3Float(float v1[3], float v2[3], float v3[3]) -{ - v1[0] = v2[0] - v3[0]; - v1[1] = v2[1] - v3[1]; - v1[2] = v2[2] - v3[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cross3Int(int v1[3], int v2[3], int v3[3]) -{ - v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; - v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; - v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cross3Float(float v1[3], float v2[3], float v3[3]) -{ - v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; - v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; - v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; -} -/* ------------------------------------------------------------------------- */ - -void MTC_cross3Double(double v1[3], double v2[3], double v3[3]) -{ - v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; - v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; - v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; -} - -/* ------------------------------------------------------------------------- */ - -int MTC_dot3Int(int v1[3], int v2[3]) -{ - return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); -} - -/* ------------------------------------------------------------------------- */ - -float MTC_dot3Float(float v1[3], float v2[3]) -{ - return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cp3Float(float v1[3], float v2[3]) -{ - v2[0] = v1[0]; - v2[1] = v1[1]; - v2[2] = v1[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_cp3FloatInv(float v1[3], float v2[3]) -{ - v2[0] = -v1[0]; - v2[1] = -v1[1]; - v2[2] = -v1[2]; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_swapInt(int *i1, int *i2) -{ - int swap; - swap = *i1; - *i1 = *i2; - *i2 = swap; -} - -/* ------------------------------------------------------------------------- */ - -void MTC_diff3DFF(double v1[3], float v2[3], float v3[3]) -{ - v1[0] = v2[0] - v3[0]; - v1[1] = v2[1] - v3[1]; - v1[2] = v2[2] - v3[2]; -} - -/* ------------------------------------------------------------------------- */ -float MTC_normalize3DF(float n[3]) -{ - float d; - - d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; - /* FLT_EPSILON is too large! A larger value causes normalize errors in */ - /* a scaled down utah teapot */ - if(d>0.0000000000001) { - - /* d= sqrt(d); This _should_ be sqrt, but internally it's a double*/ - /* anyway. This is safe. */ - d = sqrt(d); - - n[0]/=d; - n[1]/=d; - n[2]/=d; - } else { - n[0]=n[1]=n[2]= 0.0; - d= 0.0; - } - return d; -} - -/* ------------------------------------------------------------------------- */ - -/* eof */ diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 667a889b5fc..7301901aff5 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -39,7 +39,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "MEM_guardedalloc.h" -#include "MTC_matrixops.h" + #include "DNA_mesh_types.h" #include "DNA_material_types.h" diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 953a055c9e5..73589371c4f 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -43,7 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" -#include "MTC_matrixops.h" + #include "DNA_action_types.h" #include "DNA_armature_types.h" @@ -1327,7 +1327,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P mval[0]-= vc->ar->winrct.xmin; mval[1]-= vc->ar->winrct.ymin; - MTC_Mat4SwapMat4(wpd->vc.rv3d->persmat, mat); + Mat4SwapMat4(wpd->vc.rv3d->persmat, mat); /* which faces are involved */ if(wp->flag & VP_AREA) { @@ -1444,7 +1444,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P } } - MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); + Mat4SwapMat4(vc->rv3d->persmat, mat); DAG_id_flush_update(ob->data, OB_RECALC_DATA); ED_region_tag_redraw(vc->ar); @@ -1724,14 +1724,14 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P else totindex= 0; } - MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); + Mat4SwapMat4(vc->rv3d->persmat, mat); for(index=0; indextotface) vpaint_paint_face(vp, vpd, ob, indexar[index]-1, mval); } - MTC_Mat4SwapMat4(vc->rv3d->persmat, mat); + Mat4SwapMat4(vc->rv3d->persmat, mat); ED_region_tag_redraw(vc->ar); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 57e7d897e24..3b6ca455b48 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -37,7 +37,7 @@ #include "IMB_imbuf.h" -#include "MTC_matrixops.h" + #include "DNA_armature_types.h" #include "DNA_boid_types.h" @@ -1124,7 +1124,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob Mat4Ortho(vec); wmMultMatrix(vec); - MTC_Mat4SwapMat4(rv3d->persmat, tmat); + Mat4SwapMat4(rv3d->persmat, tmat); wmGetSingleMatrix(rv3d->persmat); if(cam->flag & CAM_SHOWLIMITS) { @@ -1137,7 +1137,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob if(cam->flag & CAM_SHOWMIST) if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF); - MTC_Mat4SwapMat4(rv3d->persmat, tmat); + Mat4SwapMat4(rv3d->persmat, tmat); } } } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index f4242c70139..342acfe92b3 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -38,7 +38,7 @@ #include "IMB_imbuf.h" -#include "MTC_matrixops.h" + #include "DNA_armature_types.h" #include "DNA_boid_types.h" diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c index 0fd95642be6..bdf5a1ce079 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c @@ -27,7 +27,7 @@ */ #include -#include "MTC_vectorops.h" + #include "../TEX_util.h" static bNodeSocketType inputs[]= { @@ -65,19 +65,19 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor if(magsq == 0) magsq = 1; - ndx = MTC_dot3Float(coord, ax); + ndx = Inpf(coord, ax); para[0] = ax[0] * ndx * (1 - cos_a); para[1] = ax[1] * ndx * (1 - cos_a); para[2] = ax[2] * ndx * (1 - cos_a); - MTC_diff3Float(perp, coord, para); + VecSubf(perp, coord, para); perp[0] = coord[0] * cos_a; perp[1] = coord[1] * cos_a; perp[2] = coord[2] * cos_a; - MTC_cross3Float(cp, ax, coord); + Crossf(cp, ax, coord); cp[0] = cp[0] * sin_a; cp[1] = cp[1] * sin_a; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index df99d5f2843..73ff826994a 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -31,7 +31,7 @@ #include #include -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" @@ -191,8 +191,8 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), if (re) re->flag |= R_HALO; else stargrid *= 1.0; /* then it draws fewer */ - if(re) MTC_Mat4Invert(mat, re->viewmat); - else MTC_Mat4One(mat); + if(re) Mat4Invert(mat, re->viewmat); + else Mat4One(mat); /* BOUNDING BOX CALCULATION * bbox goes from z = loc_near_var | loc_far_var, @@ -240,7 +240,7 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), done++; } else { - MTC_Mat4MulVecfl(re->viewmat, vec); + Mat4MulVecfl(re->viewmat, vec); /* in vec are global coordinates * calculate distance to camera @@ -829,7 +829,7 @@ static void autosmooth(Render *re, ObjectRen *obr, float mat[][4], int degr) /* rotate vertices and calculate normal of faces */ for(a=0; atotvert; a++) { ver= RE_findOrAddVert(obr, a); - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); } for(a=0; atotvlak; a++) { vlr= RE_findOrAddVlak(obr, a); @@ -1280,19 +1280,19 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Particl VECADD(vlr->v1->co, bb_center, xvec); VECADD(vlr->v1->co, vlr->v1->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v1->co); + Mat4MulVecfl(re->viewmat, vlr->v1->co); VECSUB(vlr->v2->co, bb_center, xvec); VECADD(vlr->v2->co, vlr->v2->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v2->co); + Mat4MulVecfl(re->viewmat, vlr->v2->co); VECSUB(vlr->v3->co, bb_center, xvec); VECSUB(vlr->v3->co, vlr->v3->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v3->co); + Mat4MulVecfl(re->viewmat, vlr->v3->co); VECADD(vlr->v4->co, bb_center, xvec); VECSUB(vlr->v4->co, vlr->v4->co, yvec); - MTC_Mat4MulVecfl(re->viewmat, vlr->v4->co); + Mat4MulVecfl(re->viewmat, vlr->v4->co); CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); VECCOPY(vlr->v1->n,vlr->n); @@ -1392,7 +1392,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re VECCOPY(loc, state->co); if(ren_as != PART_DRAW_BB) - MTC_Mat4MulVecfl(re->viewmat, loc); + Mat4MulVecfl(re->viewmat, loc); switch(ren_as) { case PART_DRAW_LINE: @@ -1401,7 +1401,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re sd->size = hasize; VECCOPY(vel, state->vel); - MTC_Mat4Mul3Vecfl(re->viewmat, vel); + Mat4Mul3Vecfl(re->viewmat, vel); Normalize(vel); if(part->draw & PART_DRAW_VEL_LENGTH) @@ -1621,8 +1621,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } /* 2.5 setup matrices */ - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ Mat3CpyMat4(nmat, ob->imat); Mat3Transp(nmat); @@ -1904,7 +1904,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem time= curlen/strandlen; VECCOPY(loc,state.co); - MTC_Mat4MulVecfl(re->viewmat,loc); + Mat4MulVecfl(re->viewmat,loc); if(strandbuf) { VECCOPY(svert->co, loc); @@ -2046,8 +2046,8 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *me, int totvert, float vec[3], hasize, mat[4][4], imat[3][3]; int a, ok, seed= ma->seed1; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat3CpyMat4(imat, ob->imat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat3CpyMat4(imat, ob->imat); re->flag |= R_HALO; @@ -2058,7 +2058,7 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *me, int totvert, hasize= ma->hasize; VECCOPY(vec, mvert->co); - MTC_Mat4MulVecfl(mat, vec); + Mat4MulVecfl(mat, vec); if(ma->mode & MA_HALOPUNO) { xn= mvert->no[0]; @@ -2191,7 +2191,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve } if (texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(re->viewinv, shi->gl); + Mat4MulVecfl(re->viewinv, shi->gl); } if (texco & TEXCO_NORM) { VECCOPY(shi->orn, shi->vn); @@ -2332,9 +2332,9 @@ static void init_render_mball(Render *re, ObjectRen *obr) if (ob!=find_basis_mball(re->scene, ob)) return; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); - MTC_Mat3CpyMat4(imat, ob->imat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); + Mat3CpyMat4(imat, ob->imat); ma= give_render_material(re, ob, 1); @@ -2355,7 +2355,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, data); - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); /* render normals are inverted */ xn= -nors[0]; @@ -2439,7 +2439,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, if(orco) { v1->orco= orco; orco+= 3; orcoret++; } - MTC_Mat4MulVecfl(mat, v1->co); + Mat4MulVecfl(mat, v1->co); for (v = 1; v < sizev; v++) { ver= RE_findOrAddVert(obr, obr->totvert++); @@ -2447,7 +2447,7 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, if(orco) { ver->orco= orco; orco+= 3; orcoret++; } - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); } /* if V-cyclic, add extra vertices at end of the row */ if (dl->flag & DL_CYCL_U) { @@ -2597,8 +2597,8 @@ static void init_render_surf(Render *re, ObjectRen *obr) nu= cu->nurb.first; if(nu==0) return; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* material array */ totmat= ob->totcol+1; @@ -2658,8 +2658,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) dl= cu->disp.first; if(cu->disp.first==NULL) return; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* material array */ totmat= ob->totcol+1; @@ -2701,7 +2701,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ver->flag = 0; } - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); if (orco) { ver->orco = orco; @@ -2753,7 +2753,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, fp); - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); fp+= 3; if (orco) { @@ -3050,9 +3050,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) me= ob->data; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); - MTC_Mat3CpyMat4(imat, ob->imat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); + Mat3CpyMat4(imat, ob->imat); if(me->totvert==0) return; @@ -3136,7 +3136,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) ver= RE_findOrAddVert(obr, obr->totvert++); VECCOPY(ver->co, mvert->co); if(do_autosmooth==0) /* autosmooth on original unrotated data to prevent differences between frames */ - MTC_Mat4MulVecfl(mat, ver->co); + Mat4MulVecfl(mat, ver->co); if(orco) { ver->orco= orco; @@ -3357,13 +3357,13 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) shb->soft= lar->soft; shb->shadhalostep= lar->shadhalostep; - MTC_Mat4Ortho(mat); - MTC_Mat4Invert(shb->winmat, mat); /* winmat is temp */ + Mat4Ortho(mat); + Mat4Invert(shb->winmat, mat); /* winmat is temp */ /* matrix: combination of inverse view and lampmat */ /* calculate again: the ortho-render has no correct viewinv */ - MTC_Mat4Invert(viewinv, re->viewmat); - MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat); + Mat4Invert(viewinv, re->viewmat); + Mat4MulMat4(shb->viewmat, viewinv, shb->winmat); /* projection */ shb->d= lar->clipsta; @@ -3441,11 +3441,11 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) BLI_addtail(&re->lampren, lar); go->lampren= lar; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); - MTC_Mat3CpyMat4(lar->mat, mat); - MTC_Mat3CpyMat4(lar->imat, ob->imat); + Mat3CpyMat4(lar->mat, mat); + Mat3CpyMat4(lar->imat, ob->imat); lar->bufsize = la->bufsize; lar->samp = la->samp; @@ -3601,7 +3601,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) lar->sh_invcampos[0]= -lar->co[0]; lar->sh_invcampos[1]= -lar->co[1]; lar->sh_invcampos[2]= -lar->co[2]; - MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos); + Mat3MulVecfl(lar->imat, lar->sh_invcampos); /* z factor, for a normalized volume */ angle= saacos(lar->spotsi); @@ -4225,7 +4225,7 @@ static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *d obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4); Mat4Invert(imat, dob->mat); - MTC_Mat4MulSerie(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0); + Mat4MulSerie(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0); } } @@ -4349,8 +4349,8 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject else if(render_object_type(ob->type)) add_render_object(re, ob, par, dob, timeoffset, vectorlay); else { - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); } time= PIL_check_seconds_timer(); @@ -4600,8 +4600,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp for(SETLOOPER(re->scene, base)) { ob= base->object; /* imat objects has to be done here, since displace can have texture using Object map-input */ - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); /* each object should only be rendered once */ ob->flag &= ~OB_DONE; ob->transflag &= ~OB_RENDER_DUPLI; @@ -4747,8 +4747,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp if(redoimat) { for(SETLOOPER(re->scene, base)) { ob= base->object; - MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); - MTC_Mat4Invert(ob->imat, mat); + Mat4MulMat4(mat, ob->obmat, re->viewmat); + Mat4Invert(ob->imat, mat); } } @@ -5174,7 +5174,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * return 0; Mat4CpyMat4(mat, re->viewmat); - MTC_Mat4Invert(imat, mat); + Mat4Invert(imat, mat); /* set first vertex OK */ if(!fss->meshSurfNormals) return 0; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index a57e38f47c8..b5774d11799 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -51,7 +51,7 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" -#include "MTC_matrixops.h" + /* this module */ #include "render_types.h" @@ -211,9 +211,9 @@ static void envmap_transmatrix(float mat[][4], int part) eul[2]= -M_PI/2.0; } - MTC_Mat4CpyMat4(tmat, mat); + Mat4CpyMat4(tmat, mat); EulToMat4(eul, rotmat); - MTC_Mat4MulSerie(mat, tmat, rotmat, + Mat4MulSerie(mat, tmat, rotmat, 0, 0, 0, 0, 0, 0); } @@ -231,12 +231,12 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) int a; if(mode==0) { - MTC_Mat4Invert(tmat, mat); - MTC_Mat3CpyMat4(imat, tmat); + Mat4Invert(tmat, mat); + Mat3CpyMat4(imat, tmat); } else { - MTC_Mat4CpyMat4(tmat, mat); - MTC_Mat3CpyMat4(imat, mat); + Mat4CpyMat4(tmat, mat); + Mat3CpyMat4(imat, mat); } for(obi=re->instancetable.first; obi; obi=obi->next) { @@ -267,7 +267,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) if((a & 255)==0) har= obr->bloha[a>>8]; else har++; - MTC_Mat4MulVecfl(tmat, har->co); + Mat4MulVecfl(tmat, har->co); } } @@ -280,22 +280,22 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) Mat3CpyMat3(cmat, lar->imat); Mat3MulMat3(lar->imat, cmat, imat); - MTC_Mat3MulVecfl(imat, lar->vec); - MTC_Mat4MulVecfl(tmat, lar->co); + Mat3MulVecfl(imat, lar->vec); + Mat4MulVecfl(tmat, lar->co); lar->sh_invcampos[0]= -lar->co[0]; lar->sh_invcampos[1]= -lar->co[1]; lar->sh_invcampos[2]= -lar->co[2]; - MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos); + Mat3MulVecfl(lar->imat, lar->sh_invcampos); lar->sh_invcampos[2]*= lar->sh_zfac; if(lar->shb) { if(mode==1) { - MTC_Mat4Invert(pmat, mat); - MTC_Mat4MulMat4(smat, pmat, lar->shb->viewmat); - MTC_Mat4MulMat4(lar->shb->persmat, smat, lar->shb->winmat); + Mat4Invert(pmat, mat); + Mat4MulMat4(smat, pmat, lar->shb->viewmat); + Mat4MulMat4(lar->shb->persmat, smat, lar->shb->winmat); } - else MTC_Mat4MulMat4(lar->shb->persmat, lar->shb->viewmat, lar->shb->winmat); + else Mat4MulMat4(lar->shb->persmat, lar->shb->viewmat, lar->shb->winmat); } } @@ -373,8 +373,8 @@ static void env_set_imats(Render *re) base= re->scene->base.first; while(base) { - MTC_Mat4MulMat4(mat, base->object->obmat, re->viewmat); - MTC_Mat4Invert(base->object->imat, mat); + Mat4MulMat4(mat, base->object->obmat, re->viewmat); + Mat4Invert(base->object->imat, mat); base= base->next; } @@ -393,18 +393,18 @@ static void render_envmap(Render *re, EnvMap *env) short part; /* need a recalc: ortho-render has no correct viewinv */ - MTC_Mat4Invert(oldviewinv, re->viewmat); + Mat4Invert(oldviewinv, re->viewmat); envre= envmap_render_copy(re, env); /* precalc orthmat for object */ - MTC_Mat4CpyMat4(orthmat, env->object->obmat); - MTC_Mat4Ortho(orthmat); + Mat4CpyMat4(orthmat, env->object->obmat); + Mat4Ortho(orthmat); /* need imat later for texture imat */ - MTC_Mat4MulMat4(mat, orthmat, re->viewmat); - MTC_Mat4Invert(tmat, mat); - MTC_Mat3CpyMat4(env->obimat, tmat); + Mat4MulMat4(mat, orthmat, re->viewmat); + Mat4Invert(tmat, mat); + Mat3CpyMat4(env->obimat, tmat); for(part=0; part<6; part++) { if(env->type==ENV_PLANE && part!=1) @@ -412,17 +412,17 @@ static void render_envmap(Render *re, EnvMap *env) re->display_clear(re->dch, envre->result); - MTC_Mat4CpyMat4(tmat, orthmat); + Mat4CpyMat4(tmat, orthmat); envmap_transmatrix(tmat, part); - MTC_Mat4Invert(mat, tmat); + Mat4Invert(mat, tmat); /* mat now is the camera 'viewmat' */ - MTC_Mat4CpyMat4(envre->viewmat, mat); - MTC_Mat4CpyMat4(envre->viewinv, tmat); + Mat4CpyMat4(envre->viewmat, mat); + Mat4CpyMat4(envre->viewinv, tmat); /* we have to correct for the already rotated vertexcoords */ - MTC_Mat4MulMat4(tmat, oldviewinv, envre->viewmat); - MTC_Mat4Invert(env->imat, tmat); + Mat4MulMat4(tmat, oldviewinv, envre->viewmat); + Mat4Invert(env->imat, tmat); env_rotate_scene(envre, tmat, 1); init_render_world(envre); @@ -503,13 +503,13 @@ void make_envmaps(Render *re) float orthmat[4][4], mat[4][4], tmat[4][4]; /* precalc orthmat for object */ - MTC_Mat4CpyMat4(orthmat, env->object->obmat); - MTC_Mat4Ortho(orthmat); + Mat4CpyMat4(orthmat, env->object->obmat); + Mat4Ortho(orthmat); /* need imat later for texture imat */ - MTC_Mat4MulMat4(mat, orthmat, re->viewmat); - MTC_Mat4Invert(tmat, mat); - MTC_Mat3CpyMat4(env->obimat, tmat); + Mat4MulMat4(mat, orthmat, re->viewmat); + Mat4Invert(tmat, mat); + Mat3CpyMat4(env->obimat, tmat); } else { @@ -678,20 +678,20 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe /* rotate to envmap space, if object is set */ VECCOPY(vec, texvec); - if(env->object) MTC_Mat3MulVecfl(env->obimat, vec); - else MTC_Mat4Mul3Vecfl(R.viewinv, vec); + if(env->object) Mat3MulVecfl(env->obimat, vec); + else Mat4Mul3Vecfl(R.viewinv, vec); face= envcube_isect(env, vec, sco); ibuf= env->cube[face]; if(osatex) { if(env->object) { - MTC_Mat3MulVecfl(env->obimat, dxt); - MTC_Mat3MulVecfl(env->obimat, dyt); + Mat3MulVecfl(env->obimat, dxt); + Mat3MulVecfl(env->obimat, dyt); } else { - MTC_Mat4Mul3Vecfl(R.viewinv, dxt); - MTC_Mat4Mul3Vecfl(R.viewinv, dyt); + Mat4Mul3Vecfl(R.viewinv, dxt); + Mat4Mul3Vecfl(R.viewinv, dyt); } set_dxtdyt(dxts, dyts, dxt, dyt, face); imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres); diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 842adcf8520..d388e81a745 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -41,7 +41,7 @@ #include "BLI_blenlib.h" #include "BLI_jitter.h" -#include "MTC_matrixops.h" + #include "DNA_camera_types.h" #include "DNA_group_types.h" diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index 75a2ab257f4..de3a50acddf 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -32,8 +32,8 @@ /* External modules: */ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "MTC_matrixops.h" -#include "MTC_vectorops.h" + + #include "DNA_camera_types.h" #include "DNA_group_types.h" @@ -155,7 +155,7 @@ static void render_lighting_halo(HaloRen *har, float *colf) /* rotate view to lampspace */ VECCOPY(lvrot, lv); - MTC_Mat3MulVecfl(lar->imat, lvrot); + Mat3MulVecfl(lar->imat, lvrot); x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ @@ -553,7 +553,7 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th VECCOPY(lo, view); if(R.wrld.skytype & WO_SKYREAL) { - MTC_Mat3MulVecfl(R.imat, lo); + Mat3MulVecfl(R.imat, lo); SWAP(float, lo[1], lo[2]); @@ -595,7 +595,7 @@ void shadeSunView(float *colf, float *view) VECCOPY(sview, view); Normalize(sview); - MTC_Mat3MulVecfl(R.imat, sview); + Mat3MulVecfl(R.imat, sview); if (sview[2] < 0.0) sview[2] = 0.0; Normalize(sview); @@ -678,7 +678,7 @@ void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, calc_view_vector(view, fx, fy); Normalize(view); - /*MTC_Mat3MulVecfl(R.imat, view);*/ + /*Mat3MulVecfl(R.imat, view);*/ AtmospherePixleShader(sunsky, view, distance, collector); } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 33085b98095..48305d31e10 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -26,7 +26,7 @@ #include #include -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" #include "DNA_group_types.h" @@ -403,7 +403,7 @@ void makeshadowbuf(Render *re, LampRen *lar) wsize= shb->pixsize*(shb->size/2.0); i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat); - MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat); + Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat); if(ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) { /* jitter, weights - not threadsafe! */ @@ -673,7 +673,7 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy VECCOPY(co, rco); co[3]= 1.0f; - MTC_Mat4MulVec4fl(shb->persmat, co); /* rational hom co */ + Mat4MulVec4fl(shb->persmat, co); /* rational hom co */ xs1= siz*(1.0f+co[0]/co[3]); ys1= siz*(1.0f+co[1]/co[3]); @@ -714,7 +714,7 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy co[1]= rco[1]+dxco[1]; co[2]= rco[2]+dxco[2]; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ + Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ dx[0]= xs1- siz*(1.0+co[0]/co[3]); dx[1]= ys1- siz*(1.0+co[1]/co[3]); @@ -722,7 +722,7 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy co[1]= rco[1]+dyco[1]; co[2]= rco[2]+dyco[2]; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ + Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ dy[0]= xs1- siz*(1.0+co[0]/co[3]); dy[1]= ys1- siz*(1.0+co[1]/co[3]); @@ -858,7 +858,7 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) co[1]= p1[1]; co[2]= p1[2]/lar->sh_zfac; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ + Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ xf1= siz*(1.0+co[0]/co[3]); yf1= siz*(1.0+co[1]/co[3]); zf1= (co[2]/co[3]); @@ -868,7 +868,7 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) co[1]= p2[1]; co[2]= p2[2]/lar->sh_zfac; co[3]= 1.0; - MTC_Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ + Mat4MulVec4fl(shb->winmat, co); /* rational hom co */ xf2= siz*(1.0+co[0]/co[3]); yf2= siz*(1.0+co[1]/co[3]); zf2= (co[2]/co[3]); @@ -1659,7 +1659,7 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *v } /* move 3d vector to lampbuf */ - MTC_Mat4MulVec4fl(shb->persmat, hoco); /* rational hom co */ + Mat4MulVec4fl(shb->persmat, hoco); /* rational hom co */ /* clip We can test for -1.0/1.0 because of the properties of the * coordinate transformations. */ diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 1a0edfd53ed..7541ce53073 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -29,7 +29,7 @@ #include #include -#include "MTC_matrixops.h" + #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -458,13 +458,13 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert if(texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(R.viewinv, shi->gl); + Mat4MulVecfl(R.viewinv, shi->gl); if(shi->osatex) { VECCOPY(shi->dxgl, shi->dxco); - MTC_Mat3MulVecfl(R.imat, shi->dxco); + Mat3MulVecfl(R.imat, shi->dxco); VECCOPY(shi->dygl, shi->dyco); - MTC_Mat3MulVecfl(R.imat, shi->dyco); + Mat3MulVecfl(R.imat, shi->dyco); } } @@ -1021,15 +1021,15 @@ void shade_input_set_shade_texco(ShadeInput *shi) if(texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(R.viewinv, shi->gl); + Mat4MulVecfl(R.viewinv, shi->gl); if(shi->osatex) { VECCOPY(shi->dxgl, shi->dxco); // TXF: bug was here, but probably should be in convertblender.c, R.imat only valid if there is a world - //MTC_Mat3MulVecfl(R.imat, shi->dxco); - MTC_Mat4Mul3Vecfl(R.viewinv, shi->dxco); + //Mat3MulVecfl(R.imat, shi->dxco); + Mat4Mul3Vecfl(R.viewinv, shi->dxco); VECCOPY(shi->dygl, shi->dyco); - //MTC_Mat3MulVecfl(R.imat, shi->dyco); - MTC_Mat4Mul3Vecfl(R.viewinv, shi->dyco); + //Mat3MulVecfl(R.imat, shi->dyco); + Mat4Mul3Vecfl(R.viewinv, shi->dyco); } } diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 2f6f86e9a09..5e523199755 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -30,7 +30,7 @@ #include #include -#include "MTC_matrixops.h" + #include "BLI_arithb.h" #include "BKE_colortools.h" @@ -168,7 +168,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) p1[0]= shi->co[0]-lar->co[0]; p1[1]= shi->co[1]-lar->co[1]; p1[2]= -lar->co[2]; - MTC_Mat3MulVecfl(lar->imat, p1); + Mat3MulVecfl(lar->imat, p1); VECCOPY(npos, p1); // npos is double! /* pre-scale */ @@ -180,7 +180,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) /* rotate view */ VECCOPY(nray, shi->view); - MTC_Mat3MulVecd(lar->imat, nray); + Mat3MulVecd(lar->imat, nray); if(R.wrld.mode & WO_MIST) { /* patchy... */ @@ -1143,7 +1143,7 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist) /* rotate view to lampspace */ VECCOPY(lvrot, lv); - MTC_Mat3MulVecfl(lar->imat, lvrot); + Mat3MulVecfl(lar->imat, lvrot); x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); /* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index c706c6ccc11..4d4a2c04808 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -30,7 +30,7 @@ #include #include -#include "MTC_matrixops.h" + #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -832,7 +832,7 @@ static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float else { VECCOPY(nor, n); } - MTC_Mat4Mul3Vecfl(R.viewinv, nor); + Mat4Mul3Vecfl(R.viewinv, nor); x1= fabs(nor[0]); y1= fabs(nor[1]); @@ -925,7 +925,7 @@ static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *ad if(n==NULL) return 0; VECCOPY(nor, n); - if(ob) MTC_Mat4Mul3Vecfl(ob->imat, nor); + if(ob) Mat4Mul3Vecfl(ob->imat, nor); x1= fabs(nor[0]); y1= fabs(nor[1]); @@ -1648,13 +1648,13 @@ void do_material_tex(ShadeInput *shi) VECCOPY(tempvec, shi->co); if(mtex->texflag & MTEX_OB_DUPLI_ORIG) if(shi->obi && shi->obi->duplitexmat) - MTC_Mat4MulVecfl(shi->obi->duplitexmat, tempvec); - MTC_Mat4MulVecfl(ob->imat, tempvec); + Mat4MulVecfl(shi->obi->duplitexmat, tempvec); + Mat4MulVecfl(ob->imat, tempvec); if(shi->osatex) { VECCOPY(dxt, shi->dxco); VECCOPY(dyt, shi->dyco); - MTC_Mat4Mul3Vecfl(ob->imat, dxt); - MTC_Mat4Mul3Vecfl(ob->imat, dyt); + Mat4Mul3Vecfl(ob->imat, dxt); + Mat4Mul3Vecfl(ob->imat, dyt); } } else { @@ -2291,9 +2291,9 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa VECCOPY(co, xyz); if(mtex->texflag & MTEX_OB_DUPLI_ORIG) { if(shi->obi && shi->obi->duplitexmat) - MTC_Mat4MulVecfl(shi->obi->duplitexmat, co); + Mat4MulVecfl(shi->obi->duplitexmat, co); } - MTC_Mat4MulVecfl(ob->imat, co); + Mat4MulVecfl(ob->imat, co); } } /* not really orco, but 'local' */ @@ -2305,12 +2305,12 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa else { Object *ob= shi->obi->ob; VECCOPY(co, xyz); - MTC_Mat4MulVecfl(ob->imat, co); + Mat4MulVecfl(ob->imat, co); } } else if(mtex->texco==TEXCO_GLOB) { VECCOPY(co, xyz); - MTC_Mat4MulVecfl(R.viewinv, co); + Mat4MulVecfl(R.viewinv, co); } else continue; // can happen when texco defines disappear and it renders old files @@ -2639,7 +2639,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f case TEXCO_OBJECT: if(mtex->object) { VECCOPY(tempvec, lo); - MTC_Mat4MulVecfl(mtex->object->imat, tempvec); + Mat4MulVecfl(mtex->object->imat, tempvec); co= tempvec; } break; @@ -2647,16 +2647,16 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f case TEXCO_GLOB: if(rco) { VECCOPY(tempvec, rco); - MTC_Mat4MulVecfl(R.viewinv, tempvec); + Mat4MulVecfl(R.viewinv, tempvec); co= tempvec; } else co= lo; // VECCOPY(shi->dxgl, shi->dxco); -// MTC_Mat3MulVecfl(R.imat, shi->dxco); +// Mat3MulVecfl(R.imat, shi->dxco); // VECCOPY(shi->dygl, shi->dyco); -// MTC_Mat3MulVecfl(R.imat, shi->dyco); +// Mat3MulVecfl(R.imat, shi->dyco); break; } @@ -2783,12 +2783,12 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef dx= dxt; dy= dyt; VECCOPY(tempvec, shi->co); - MTC_Mat4MulVecfl(ob->imat, tempvec); + Mat4MulVecfl(ob->imat, tempvec); if(shi->osatex) { VECCOPY(dxt, shi->dxco); VECCOPY(dyt, shi->dyco); - MTC_Mat4Mul3Vecfl(ob->imat, dxt); - MTC_Mat4Mul3Vecfl(ob->imat, dyt); + Mat4Mul3Vecfl(ob->imat, dxt); + Mat4Mul3Vecfl(ob->imat, dyt); } } else { @@ -2799,12 +2799,12 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef else if(mtex->texco==TEXCO_GLOB) { co= shi->gl; dx= shi->dxco; dy= shi->dyco; VECCOPY(shi->gl, shi->co); - MTC_Mat4MulVecfl(R.viewinv, shi->gl); + Mat4MulVecfl(R.viewinv, shi->gl); } else if(mtex->texco==TEXCO_VIEW) { VECCOPY(tempvec, lavec); - MTC_Mat3MulVecfl(la->imat, tempvec); + Mat3MulVecfl(la->imat, tempvec); if(la->type==LA_SPOT) { tempvec[0]*= la->spottexfac; @@ -2817,8 +2817,8 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef VECCOPY(dxt, shi->dxlv); VECCOPY(dyt, shi->dylv); /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ - MTC_Mat3MulVecfl(la->imat, dxt); - MTC_Mat3MulVecfl(la->imat, dyt); + Mat3MulVecfl(la->imat, dxt); + Mat3MulVecfl(la->imat, dyt); VecMulf(dxt, la->spottexfac); VecMulf(dyt, la->spottexfac); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 53a05dd0d67..3b3a8568933 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -42,7 +42,7 @@ #include "BLI_jitter.h" #include "BLI_threads.h" -#include "MTC_matrixops.h" + #include "MEM_guardedalloc.h" #include "DNA_lamp_types.h" -- cgit v1.2.3 From a46beac3f87ee78d6231b2f0038db31c50aa2315 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 6 Sep 2009 01:11:47 +0000 Subject: Rename Vec3ToTangent VecBisect3, since that's what it does. --- source/blender/blenkernel/intern/curve.c | 8 ++++---- source/blender/blenlib/BLI_arithb.h | 2 +- source/blender/blenlib/intern/arithb.c | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 709507a9b26..25af0cb5ce3 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1903,7 +1903,7 @@ void makeBevelList(Object *ob) } /* this has to be >2 points */ else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) { - /* Special case, cyclic curve with no twisy. tricky... */ + /* Special case, cyclic curve with no twist. tricky... */ float quat[4], q[4], cross[3]; @@ -1924,7 +1924,7 @@ void makeBevelList(Object *ob) while(nr--) { /* Normalizes */ - Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x); + VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x); if(bl->nr==nr+1) { /* first time */ vectoquat(vec, 5, 1, quat); @@ -1976,7 +1976,7 @@ void makeBevelList(Object *ob) nr= bl->nr; while(nr--) { - Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x); + VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x); quat_tmp1= (float *)bevp1->mat; quat_tmp2= quat_tmp1+4; @@ -2014,7 +2014,7 @@ void makeBevelList(Object *ob) if(cu->flag & CU_3D) { /* 3D */ /* Normalizes */ - Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x); + VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x); if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */ vectoquat(vec, 5, 1, quat); diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 63b351016d4..86b626dabdf 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -270,7 +270,7 @@ void AxisAngleToQuat(float *q, float *axis, float angle); void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]); void vectoquat(float *vec, short axis, short upflag, float *q); -void Vec3ToTangent(float *v, float *v1, float *v2, float *v3); +void VecBisect3(float *v, float *v1, float *v2, float *v3); float VecAngle2(float *v1, float *v2); float VecAngle3(float *v1, float *v2, float *v3); float NormalizedVecAngle2(float *v1, float *v2); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 970d8f7d0de..c20794953b9 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2969,17 +2969,16 @@ void VecRotToQuat( float *vec, float phi, float *quat) } } -/* get a direction from 3 vectors that wont depend - * on the distance between the points */ -void Vec3ToTangent(float *v, float *v1, float *v2, float *v3) +/* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */ +void VecBisect3(float *out, float *v1, float *v2, float *v3) { float d_12[3], d_23[3]; VecSubf(d_12, v2, v1); VecSubf(d_23, v3, v2); Normalize(d_12); Normalize(d_23); - VecAddf(v, d_12, d_23); - Normalize(v); + VecAddf(out, d_12, d_23); + Normalize(out); } /* Return the angle in degrees between vecs 1-2 and 2-3 in degrees -- cgit v1.2.3 From 0a3694cd6ebec710da7110e9f168a72d47c71ee0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Sep 2009 01:51:23 +0000 Subject: white space commit. (2 spaces -> tab). Was annoying to use a different editor for cmake only. theeth says this should be ok with gsoc and merges from branches. --- CMakeLists.txt | 768 ++++++++++----------- extern/CMakeLists.txt | 6 +- extern/bullet2/CMakeLists.txt | 20 +- extern/bullet2/src/BulletCollision/CMakeLists.txt | 4 +- extern/bullet2/src/BulletSoftBody/CMakeLists.txt | 2 +- extern/glew/CMakeLists.txt | 4 +- intern/CMakeLists.txt | 2 +- intern/audaspace/CMakeLists.txt | 38 +- intern/elbeem/CMakeLists.txt | 4 +- intern/ghost/CMakeLists.txt | 46 +- intern/guardedalloc/CMakeLists.txt | 4 +- intern/smoke/CMakeLists.txt | 6 +- source/CMakeLists.txt | 4 +- source/blender/CMakeLists.txt | 8 +- source/blender/avi/CMakeLists.txt | 4 +- source/blender/blenfont/CMakeLists.txt | 10 +- source/blender/blenkernel/CMakeLists.txt | 46 +- source/blender/blenlib/CMakeLists.txt | 12 +- source/blender/blenloader/CMakeLists.txt | 10 +- source/blender/blenpluginapi/CMakeLists.txt | 6 +- source/blender/editors/CMakeLists.txt | 52 +- source/blender/editors/screen/CMakeLists.txt | 40 +- source/blender/gpu/CMakeLists.txt | 4 +- source/blender/imbuf/CMakeLists.txt | 28 +- source/blender/imbuf/intern/cineon/CMakeLists.txt | 16 +- source/blender/imbuf/intern/dds/CMakeLists.txt | 18 +- source/blender/imbuf/intern/openexr/CMakeLists.txt | 20 +- source/blender/makesdna/intern/CMakeLists.txt | 6 +- source/blender/makesrna/intern/CMakeLists.txt | 42 +- source/blender/nodes/CMakeLists.txt | 26 +- source/blender/python/CMakeLists.txt | 16 +- source/blender/quicktime/CMakeLists.txt | 24 +- source/blender/readblenfile/CMakeLists.txt | 2 +- source/blender/render/CMakeLists.txt | 18 +- source/blender/windowmanager/CMakeLists.txt | 46 +- source/blenderplayer/CMakeLists.txt | 166 ++--- .../bad_level_call_stubs/CMakeLists.txt | 10 +- source/creator/CMakeLists.txt | 620 ++++++++--------- source/gameengine/BlenderRoutines/CMakeLists.txt | 68 +- source/gameengine/CMakeLists.txt | 2 +- source/gameengine/Converter/CMakeLists.txt | 68 +- source/gameengine/Expressions/CMakeLists.txt | 14 +- source/gameengine/GameLogic/CMakeLists.txt | 20 +- source/gameengine/GamePlayer/CMakeLists.txt | 2 +- source/gameengine/GamePlayer/common/CMakeLists.txt | 82 +-- source/gameengine/GamePlayer/ghost/CMakeLists.txt | 74 +- source/gameengine/Ketsji/CMakeLists.txt | 70 +- source/gameengine/Ketsji/KXNetwork/CMakeLists.txt | 20 +- source/gameengine/Network/CMakeLists.txt | 8 +- .../Network/LoopBackNetwork/CMakeLists.txt | 8 +- source/gameengine/Physics/Bullet/CMakeLists.txt | 34 +- source/gameengine/Physics/Dummy/CMakeLists.txt | 4 +- source/gameengine/Physics/common/CMakeLists.txt | 6 +- source/gameengine/Rasterizer/CMakeLists.txt | 18 +- .../Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt | 24 +- source/gameengine/SceneGraph/CMakeLists.txt | 4 +- source/gameengine/VideoTexture/CMakeLists.txt | 50 +- source/kernel/CMakeLists.txt | 10 +- 58 files changed, 1372 insertions(+), 1372 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5000ecfac5c..7196049f964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,11 +34,11 @@ IF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) MESSAGE(FATAL_ERROR "CMake generation for blender is not allowed within the source directory! Remove the CMakeCache.txt file and try again from another folder, e.g.: - rm CMakeCache.txt - cd .. - mkdir cmake-make - cd cmake-make - cmake -G \"Unix Makefiles\" ../blender + rm CMakeCache.txt + cd .. + mkdir cmake-make + cd cmake-make + cmake -G \"Unix Makefiles\" ../blender ") ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) @@ -76,7 +76,7 @@ OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) - MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE") + MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE") ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER) # For alternate Python locations the commandline can be used to override detected/default cache settings, e.g: @@ -95,421 +95,421 @@ INCLUDE(CMake/macros.cmake) #Platform specifics IF(UNIX AND NOT APPLE) - IF(WITH_OPENAL) - FIND_PACKAGE(OpenAL) - IF(OPENAL_FOUND) - SET(WITH_OPENAL ON) - ELSE(OPENAL_FOUND) - SET(WITH_OPENAL OFF) - ENDIF(OPENAL_FOUND) - ENDIF(WITH_OPENAL) - - IF(WITH_JACK) - SET(JACK /usr) - SET(JACK_INC ${JACK}/include/jack) - SET(JACK_LIB jack) - SET(JACK_LIBPATH ${JACK}/lib) - ENDIF(WITH_JACK) - - IF(WITH_SNDFILE) + IF(WITH_OPENAL) + FIND_PACKAGE(OpenAL) + IF(OPENAL_FOUND) + SET(WITH_OPENAL ON) + ELSE(OPENAL_FOUND) + SET(WITH_OPENAL OFF) + ENDIF(OPENAL_FOUND) + ENDIF(WITH_OPENAL) + + IF(WITH_JACK) + SET(JACK /usr) + SET(JACK_INC ${JACK}/include/jack) + SET(JACK_LIB jack) + SET(JACK_LIBPATH ${JACK}/lib) + ENDIF(WITH_JACK) + + IF(WITH_SNDFILE) SET(SNDFILE /usr) SET(SNDFILE_INC ${SNDFILE}/include) SET(SNDFILE_LIB sndfile) SET(SNDFILE_LIBPATH ${SNDFILE}/lib) - ENDIF(WITH_SNDFILE) - - FIND_LIBRARY(INTL_LIBRARY - NAMES intl - PATHS - /sw/lib - ) - FIND_LIBRARY(ICONV_LIBRARY - NAMES iconv - PATHS - /sw/lib - ) + ENDIF(WITH_SNDFILE) + + FIND_LIBRARY(INTL_LIBRARY + NAMES intl + PATHS + /sw/lib + ) + FIND_LIBRARY(ICONV_LIBRARY + NAMES iconv + PATHS + /sw/lib + ) - IF(INTL_LIBRARY AND ICONV_LIBRARY) - SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY}) - ENDIF(INTL_LIBRARY AND ICONV_LIBRARY) - - FIND_PACKAGE(Freetype) - # UNSET(FREETYPE_INCLUDE_DIRS CACHE) # cant use - - # No way to set py31. remove for now. - # FIND_PACKAGE(PythonLibs) - SET(PYTHON /usr) - SET(PYTHON_VERSION 3.1) - SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "") - # SET(PYTHON_BINARY python) # not used yet - SET(PYTHON_LIB python${PYTHON_VERSION} CACHE STRING "") - SET(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "") + IF(INTL_LIBRARY AND ICONV_LIBRARY) + SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY}) + ENDIF(INTL_LIBRARY AND ICONV_LIBRARY) + + FIND_PACKAGE(Freetype) + # UNSET(FREETYPE_INCLUDE_DIRS CACHE) # cant use + + # No way to set py31. remove for now. + # FIND_PACKAGE(PythonLibs) + SET(PYTHON /usr) + SET(PYTHON_VERSION 3.1) + SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "") + # SET(PYTHON_BINARY python) # not used yet + SET(PYTHON_LIB python${PYTHON_VERSION} CACHE STRING "") + SET(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "") - # FIND_PACKAGE(PythonInterp) # not used yet - # SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "") + # FIND_PACKAGE(PythonInterp) # not used yet + # SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "") - SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic") - - IF(WITH_SDL) - FIND_PACKAGE(SDL) - # UNSET(SDLMAIN_LIBRARY CACHE) - IF(NOT SDL_FOUND) - SET(WITH_SDL OFF) - ENDIF(NOT SDL_FOUND) - ENDIF(WITH_SDL) - - FIND_PATH(OPENEXR_INC - ImfXdr.h - PATHS - /usr/local/include/OpenEXR - /usr/include/OpenEXR - /sw/include/OpenEXR - /opt/local/include/OpenEXR - /opt/csw/include/OpenEXR - /opt/include/OpenEXR - ) - SET(OPENEXR_LIB Half IlmImf Iex Imath) - - SET(FFMPEG /usr) - SET(FFMPEG_INC ${FFMPEG}/include) - SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale) - SET(FFMPEG_LIBPATH ${FFMPEG}/lib) + SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic") + + IF(WITH_SDL) + FIND_PACKAGE(SDL) + # UNSET(SDLMAIN_LIBRARY CACHE) + IF(NOT SDL_FOUND) + SET(WITH_SDL OFF) + ENDIF(NOT SDL_FOUND) + ENDIF(WITH_SDL) + + FIND_PATH(OPENEXR_INC + ImfXdr.h + PATHS + /usr/local/include/OpenEXR + /usr/include/OpenEXR + /sw/include/OpenEXR + /opt/local/include/OpenEXR + /opt/csw/include/OpenEXR + /opt/include/OpenEXR + ) + SET(OPENEXR_LIB Half IlmImf Iex Imath) + + SET(FFMPEG /usr) + SET(FFMPEG_INC ${FFMPEG}/include) + SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale) + SET(FFMPEG_LIBPATH ${FFMPEG}/lib) - IF(WITH_FFTW3) - SET(FFTW3 /usr) - SET(FFTW3_INC ${FFTW3}/include) - SET(FFTW3_LIB fftw3) - SET(FFTW3_LIBPATH ${FFTW3}/lib) - ENDIF(WITH_FFTW3) + IF(WITH_FFTW3) + SET(FFTW3 /usr) + SET(FFTW3_INC ${FFTW3}/include) + SET(FFTW3_LIB fftw3) + SET(FFTW3_LIBPATH ${FFTW3}/lib) + ENDIF(WITH_FFTW3) - SET(LIBSAMPLERATE /usr) - SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include) - SET(LIBSAMPLERATE_LIB samplerate) - SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib) + SET(LIBSAMPLERATE /usr) + SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include) + SET(LIBSAMPLERATE_LIB samplerate) + SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib) - FIND_PACKAGE(JPEG REQUIRED) + FIND_PACKAGE(JPEG REQUIRED) - FIND_PACKAGE(PNG REQUIRED) + FIND_PACKAGE(PNG REQUIRED) - FIND_PACKAGE(ZLIB REQUIRED) + FIND_PACKAGE(ZLIB REQUIRED) - # Could use ${X11_Xinput_LIB} ${X11_X11_LIB} too - SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11") + # Could use ${X11_Xinput_LIB} ${X11_X11_LIB} too + SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11") - IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - # BSD's dont use libdl.so - SET(LLIBS "${LLIBS} -ldl") - ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") + IF(CMAKE_SYSTEM_NAME MATCHES "Linux") + # BSD's dont use libdl.so + SET(LLIBS "${LLIBS} -ldl") + ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") - IF(WITH_OPENMP) - SET(LLIBS "${LLIBS} -lgomp") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") - ENDIF(WITH_OPENMP) + IF(WITH_OPENMP) + SET(LLIBS "${LLIBS} -lgomp") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") + ENDIF(WITH_OPENMP) - SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts") + SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts") - SET(PLATFORM_LINKFLAGS "-pthread") + SET(PLATFORM_LINKFLAGS "-pthread") - # Better warnings - SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement") - SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare") + # Better warnings + SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement") + SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare") - INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) + INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) ENDIF(UNIX AND NOT APPLE) IF(WIN32) - # this file is included anyway when building under Windows with cl.exe - # INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) + # this file is included anyway when building under Windows with cl.exe + # INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) - SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows) - - # Setup 64bit and 64bit windows systems - IF(CMAKE_CL_64) - message("64 bit compiler detected.") - SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64) - ENDIF(CMAKE_CL_64) - - SET(PYTHON ${LIBDIR}/python) - SET(PYTHON_VERSION 3.1) - SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}") - # SET(PYTHON_BINARY python) # not used yet - SET(PYTHON_LIB python31) - SET(PYTHON_LIBPATH ${PYTHON}/lib) - - IF(CMAKE_CL_64) - SET(WITH_OPENAL OFF) - ELSE(CMAKE_CL_64) - #SET(WITH_OPENAL ON) - SET(OPENAL ${LIBDIR}/openal) - SET(OPENAL_INCLUDE_DIR ${OPENAL}/include) - SET(OPENAL_LIBRARY wrap_oal) - SET(OPENAL_LIBPATH ${OPENAL}/lib) - ENDIF(CMAKE_CL_64) - - IF(WITH_JACK) - SET(JACK ${LIBDIR}/jack) - SET(JACK_INC ${JACK}/include/jack ${JACK}/include) - SET(JACK_LIB libjack) - SET(JACK_LIBPATH ${JACK}/lib) - ENDIF(WITH_JACK) - - IF(WITH_SNDFILE) - SET(SNDFILE ${LIBDIR}/sndfile) - SET(SNDFILE_INC ${SNDFILE}/include) - SET(SNDFILE_LIB libsndfile-1) - SET(SNDFILE_LIBPATH ${SNDFILE}/lib) - ENDIF(WITH_SNDFILE) - - IF(CMAKE_CL_64) - SET(PNG_LIBRARIES libpng) - ELSE(CMAKE_CL_64) - SET(PNG_LIBRARIES libpng_st) - ENDIF(CMAKE_CL_64) - SET(JPEG_LIBRARY libjpeg) - - SET(ZLIB ${LIBDIR}/zlib) - SET(ZLIB_INC ${ZLIB}/include) - IF(CMAKE_CL_64) - SET(ZLIB_LIBRARIES libz) - ELSE(CMAKE_CL_64) - SET(ZLIB_LIBRARIES zlib) - ENDIF(CMAKE_CL_64) - SET(ZLIB_LIBPATH ${ZLIB}/lib) + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows) + + # Setup 64bit and 64bit windows systems + IF(CMAKE_CL_64) + message("64 bit compiler detected.") + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64) + ENDIF(CMAKE_CL_64) + + SET(PYTHON ${LIBDIR}/python) + SET(PYTHON_VERSION 3.1) + SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}") + # SET(PYTHON_BINARY python) # not used yet + SET(PYTHON_LIB python31) + SET(PYTHON_LIBPATH ${PYTHON}/lib) + + IF(CMAKE_CL_64) + SET(WITH_OPENAL OFF) + ELSE(CMAKE_CL_64) + #SET(WITH_OPENAL ON) + SET(OPENAL ${LIBDIR}/openal) + SET(OPENAL_INCLUDE_DIR ${OPENAL}/include) + SET(OPENAL_LIBRARY wrap_oal) + SET(OPENAL_LIBPATH ${OPENAL}/lib) + ENDIF(CMAKE_CL_64) + + IF(WITH_JACK) + SET(JACK ${LIBDIR}/jack) + SET(JACK_INC ${JACK}/include/jack ${JACK}/include) + SET(JACK_LIB libjack) + SET(JACK_LIBPATH ${JACK}/lib) + ENDIF(WITH_JACK) + + IF(WITH_SNDFILE) + SET(SNDFILE ${LIBDIR}/sndfile) + SET(SNDFILE_INC ${SNDFILE}/include) + SET(SNDFILE_LIB libsndfile-1) + SET(SNDFILE_LIBPATH ${SNDFILE}/lib) + ENDIF(WITH_SNDFILE) + + IF(CMAKE_CL_64) + SET(PNG_LIBRARIES libpng) + ELSE(CMAKE_CL_64) + SET(PNG_LIBRARIES libpng_st) + ENDIF(CMAKE_CL_64) + SET(JPEG_LIBRARY libjpeg) + + SET(ZLIB ${LIBDIR}/zlib) + SET(ZLIB_INC ${ZLIB}/include) + IF(CMAKE_CL_64) + SET(ZLIB_LIBRARIES libz) + ELSE(CMAKE_CL_64) + SET(ZLIB_LIBRARIES zlib) + ENDIF(CMAKE_CL_64) + SET(ZLIB_LIBPATH ${ZLIB}/lib) - SET(PTHREADS ${LIBDIR}/pthreads) - SET(PTHREADS_INC ${PTHREADS}/include) - SET(PTHREADS_LIB pthreadVC2) - SET(PTHREADS_LIBPATH ${PTHREADS}/lib) + SET(PTHREADS ${LIBDIR}/pthreads) + SET(PTHREADS_INC ${PTHREADS}/include) + SET(PTHREADS_LIB pthreadVC2) + SET(PTHREADS_LIBPATH ${PTHREADS}/lib) - SET(ICONV ${LIBDIR}/iconv) - SET(ICONV_INC ${ICONV}/include) - SET(ICONV_LIB iconv) - SET(ICONV_LIBPATH ${ICONV}/lib) + SET(ICONV ${LIBDIR}/iconv) + SET(ICONV_INC ${ICONV}/include) + SET(ICONV_LIB iconv) + SET(ICONV_LIBPATH ${ICONV}/lib) - IF(WITH_FFTW3) - SET(FFTW3 ${LIBDIR}/fftw3) - SET(FFTW3_INC ${FFTW3}/include) - SET(FFTW3_LIB libfftw) - SET(FFTW3_LIBPATH ${FFTW3}/lib) - ENDIF(WITH_FFTW3) + IF(WITH_FFTW3) + SET(FFTW3 ${LIBDIR}/fftw3) + SET(FFTW3_INC ${FFTW3}/include) + SET(FFTW3_LIB libfftw) + SET(FFTW3_LIBPATH ${FFTW3}/lib) + ENDIF(WITH_FFTW3) - SET(GETTEXT ${LIBDIR}/gettext) - SET(GETTEXT_INC ${GETTEXT}/include) - IF(CMAKE_CL_64) - SET(GETTEXT_LIB gettext) - ELSE(CMAKE_CL_64) - SET(GETTEXT_LIB gnu_gettext) - ENDIF(CMAKE_CL_64) - SET(GETTEXT_LIBPATH ${GETTEXT}/lib) - - SET(FREETYPE ${LIBDIR}/freetype) - SET(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2) - SET(FREETYPE_LIBPATH ${FREETYPE}/lib) - SET(FREETYPE_LIBRARY freetype2ST) + SET(GETTEXT ${LIBDIR}/gettext) + SET(GETTEXT_INC ${GETTEXT}/include) + IF(CMAKE_CL_64) + SET(GETTEXT_LIB gettext) + ELSE(CMAKE_CL_64) + SET(GETTEXT_LIB gnu_gettext) + ENDIF(CMAKE_CL_64) + SET(GETTEXT_LIBPATH ${GETTEXT}/lib) + + SET(FREETYPE ${LIBDIR}/freetype) + SET(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2) + SET(FREETYPE_LIBPATH ${FREETYPE}/lib) + SET(FREETYPE_LIBRARY freetype2ST) - SET(OPENEXR ${LIBDIR}/openexr) - SET(OPENEXR_INC ${OPENEXR}/include ${OPENEXR}/include/IlmImf ${OPENEXR}/include/Iex ${OPENEXR}/include/Imath) - SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread) - IF (MSVC80) - SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2005) - ELSE (MSVC80) - SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc) - ENDIF(MSVC80) - IF (MSVC90) - SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2008) - ENDIF(MSVC90) + SET(OPENEXR ${LIBDIR}/openexr) + SET(OPENEXR_INC ${OPENEXR}/include ${OPENEXR}/include/IlmImf ${OPENEXR}/include/Iex ${OPENEXR}/include/Imath) + SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread) + IF (MSVC80) + SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2005) + ELSE (MSVC80) + SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc) + ENDIF(MSVC80) + IF (MSVC90) + SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2008) + ENDIF(MSVC90) - SET(QUICKTIME ${LIBDIR}/QTDevWin) - SET(QUICKTIME_INC ${QUICKTIME}/CIncludes) - SET(QUICKTIME_LIB qtmlClient) - SET(QUICKTIME_LIBPATH ${QUICKTIME}/Libraries) - - SET(FFMPEG ${LIBDIR}/ffmpeg) - SET(FFMPEG_INC ${FFMPEG}/include ${FFMPEG}/include/msvc) - SET(FFMPEG_LIB avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0) - SET(FFMPEG_LIBPATH ${FFMPEG}/lib) - - SET(LIBSAMPLERATE ${LIBDIR}/samplerate) - SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include) - SET(LIBSAMPLERATE_LIB libsamplerate) - SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib) - - IF(CMAKE_CL_64) - SET(LLIBS kernel32 user32 vfw32 winmm ws2_32 ) - ELSE(CMAKE_CL_64) - SET(LLIBS kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid ws2_32 vfw32 winmm) - ENDIF(CMAKE_CL_64) - - SET(CMAKE_CXX_FLAGS_DEBUG "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_CXX_FLAGS_RELEASE "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_CXX_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_C_FLAGS_DEBUG "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_C_FLAGS_RELEASE "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_C_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE) - - IF(WITH_OPENMP) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp ") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp ") - ENDIF(WITH_OPENMP) - - SET(SDL ${LIBDIR}/sdl) - SET(SDL_INCLUDE_DIR ${SDL}/include) - SET(SDL_LIBRARY SDL) - SET(SDL_LIBPATH ${SDL}/lib) - - SET(PNG "${LIBDIR}/png") - SET(PNG_INC "${PNG}/include") - SET(PNG_LIBPATH ${PNG}/lib) - - SET(JPEG "${LIBDIR}/jpeg") - SET(JPEG_INC "${JPEG}/include") - SET(JPEG_LIBPATH ${JPEG}/lib) - - SET(TIFF ${LIBDIR}/tiff) - SET(TIFF_INC ${TIFF}/include) + SET(QUICKTIME ${LIBDIR}/QTDevWin) + SET(QUICKTIME_INC ${QUICKTIME}/CIncludes) + SET(QUICKTIME_LIB qtmlClient) + SET(QUICKTIME_LIBPATH ${QUICKTIME}/Libraries) + + SET(FFMPEG ${LIBDIR}/ffmpeg) + SET(FFMPEG_INC ${FFMPEG}/include ${FFMPEG}/include/msvc) + SET(FFMPEG_LIB avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0) + SET(FFMPEG_LIBPATH ${FFMPEG}/lib) + + SET(LIBSAMPLERATE ${LIBDIR}/samplerate) + SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include) + SET(LIBSAMPLERATE_LIB libsamplerate) + SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib) + + IF(CMAKE_CL_64) + SET(LLIBS kernel32 user32 vfw32 winmm ws2_32 ) + ELSE(CMAKE_CL_64) + SET(LLIBS kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid ws2_32 vfw32 winmm) + ENDIF(CMAKE_CL_64) + + SET(CMAKE_CXX_FLAGS_DEBUG "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_CXX_FLAGS_RELEASE "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_CXX_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_C_FLAGS_DEBUG "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_C_FLAGS_RELEASE "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_C_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) + SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE) + + IF(WITH_OPENMP) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp ") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp ") + ENDIF(WITH_OPENMP) + + SET(SDL ${LIBDIR}/sdl) + SET(SDL_INCLUDE_DIR ${SDL}/include) + SET(SDL_LIBRARY SDL) + SET(SDL_LIBPATH ${SDL}/lib) + + SET(PNG "${LIBDIR}/png") + SET(PNG_INC "${PNG}/include") + SET(PNG_LIBPATH ${PNG}/lib) + + SET(JPEG "${LIBDIR}/jpeg") + SET(JPEG_INC "${JPEG}/include") + SET(JPEG_LIBPATH ${JPEG}/lib) + + SET(TIFF ${LIBDIR}/tiff) + SET(TIFF_INC ${TIFF}/include) - SET(WINTAB_INC ${LIBDIR}/wintab/include) + SET(WINTAB_INC ${LIBDIR}/wintab/include) - IF(CMAKE_CL_64) - SET(PLATFORM_LINKFLAGS "/MACHINE:X64 /NODEFAULTLIB:libc.lib;MSVCRT.lib ") - ELSE(CMAKE_CL_64) - SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib ") - ENDIF(CMAKE_CL_64) + IF(CMAKE_CL_64) + SET(PLATFORM_LINKFLAGS "/MACHINE:X64 /NODEFAULTLIB:libc.lib;MSVCRT.lib ") + ELSE(CMAKE_CL_64) + SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib ") + ENDIF(CMAKE_CL_64) - SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ") + SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ") ENDIF(WIN32) IF(APPLE) - IF(CMAKE_OSX_ARCHITECTURES MATCHES i386) - SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.x.i386) - ELSE(CMAKE_OSX_ARCHITECTURES MATCHES i386) - SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) - ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) - - IF(WITH_OPENAL) - FIND_PACKAGE(OpenAL) - IF(OPENAL_FOUND) - SET(WITH_OPENAL ON) - ELSE(OPENAL_FOUND) - SET(WITH_OPENAL OFF) - ENDIF(OPENAL_FOUND) - ENDIF(WITH_OPENAL) - - IF(WITH_JACK) - SET(JACK /usr) - SET(JACK_INC ${JACK}/include/jack) - SET(JACK_LIB jack) - SET(JACK_LIBPATH ${JACK}/lib) - ENDIF(WITH_JACK) - - IF(WITH_SNDFILE) - SET(SNDFILE /usr) - SET(SNDFILE_INC ${SNDFILE}/include) - SET(SNDFILE_LIB sndfile) - SET(SNDFILE_LIBPATH ${SNDFILE}/lib) - ENDIF(WITH_SNDFILE) - - SET(PYTHON_VERSION 3.1) - - IF(PYTHON_VERSION MATCHES 3.1) - # we use precompiled libraries for py 3.1 and up by default - - SET(PYTHON ${LIBDIR}/python) - SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "") - # SET(PYTHON_BINARY "${PYTHON}/bin/python${PYTHON_VERSION}" CACHE STRING "") # not used yet - SET(PYTHON_LIB python${PYTHON_VERSION}) - SET(PYTHON_LIBPATH "${PYTHON}/lib/python${PYTHON_VERSION}" CACHE STRING "") - # SET(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled - ELSE(PYTHON_VERSION MATCHES 3.1) - # otherwise, use custom system framework - - SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/) - SET(PYTHON_VERSION 2.5) - SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "") - # SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "") # not used yet - SET(PYTHON_LIB "") - SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "") - SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python") - ENDIF(PYTHON_VERSION MATCHES 3.1) - - SET(GETTEXT ${LIBDIR}/gettext) - SET(GETTEXT_INC "${GETTEXT}/include") - SET(GETTEXT_LIB intl iconv) - SET(GETTEXT_LIBPATH ${GETTEXT}/lib) + IF(CMAKE_OSX_ARCHITECTURES MATCHES i386) + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.x.i386) + ELSE(CMAKE_OSX_ARCHITECTURES MATCHES i386) + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) + ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) + + IF(WITH_OPENAL) + FIND_PACKAGE(OpenAL) + IF(OPENAL_FOUND) + SET(WITH_OPENAL ON) + ELSE(OPENAL_FOUND) + SET(WITH_OPENAL OFF) + ENDIF(OPENAL_FOUND) + ENDIF(WITH_OPENAL) + + IF(WITH_JACK) + SET(JACK /usr) + SET(JACK_INC ${JACK}/include/jack) + SET(JACK_LIB jack) + SET(JACK_LIBPATH ${JACK}/lib) + ENDIF(WITH_JACK) + + IF(WITH_SNDFILE) + SET(SNDFILE /usr) + SET(SNDFILE_INC ${SNDFILE}/include) + SET(SNDFILE_LIB sndfile) + SET(SNDFILE_LIBPATH ${SNDFILE}/lib) + ENDIF(WITH_SNDFILE) + + SET(PYTHON_VERSION 3.1) + + IF(PYTHON_VERSION MATCHES 3.1) + # we use precompiled libraries for py 3.1 and up by default + + SET(PYTHON ${LIBDIR}/python) + SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "") + # SET(PYTHON_BINARY "${PYTHON}/bin/python${PYTHON_VERSION}" CACHE STRING "") # not used yet + SET(PYTHON_LIB python${PYTHON_VERSION}) + SET(PYTHON_LIBPATH "${PYTHON}/lib/python${PYTHON_VERSION}" CACHE STRING "") + # SET(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled + ELSE(PYTHON_VERSION MATCHES 3.1) + # otherwise, use custom system framework + + SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/) + SET(PYTHON_VERSION 2.5) + SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "") + # SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "") # not used yet + SET(PYTHON_LIB "") + SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "") + SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python") + ENDIF(PYTHON_VERSION MATCHES 3.1) + + SET(GETTEXT ${LIBDIR}/gettext) + SET(GETTEXT_INC "${GETTEXT}/include") + SET(GETTEXT_LIB intl iconv) + SET(GETTEXT_LIBPATH ${GETTEXT}/lib) - IF(WITH_FFTW3) - SET(FFTW3 ${LIBDIR}/fftw3) - SET(FFTW3_INC ${FFTW3}/include) - SET(FFTW3_LIB libfftw) - SET(FFTW3_LIBPATH ${FFTW3}/lib) - ENDIF(WITH_FFTW3) - - SET(PNG_LIBRARIES png) - SET(JPEG_LIBRARY jpeg) - - SET(ZLIB /usr) - SET(ZLIB_INC "${ZLIB}/include") - SET(ZLIB_LIBRARIES z) - - SET(FREETYPE ${LIBDIR}/freetype) - SET(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2) - SET(FREETYPE_LIBPATH ${FREETYPE}/lib) - SET(FREETYPE_LIBRARY freetype) - - SET(OPENEXR ${LIBDIR}/openexr) - SET(OPENEXR_INC ${OPENEXR}/include/OpenEXR ${OPENEXR}/include) - SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread) - SET(OPENEXR_LIBPATH ${OPENEXR}/lib) - - SET(FFMPEG ${LIBDIR}/ffmpeg) - SET(FFMPEG_INC ${CMAKE_SOURCE_DIR}/extern/ffmpeg) - SET(FFMPEG_LIB avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore) - SET(FFMPEG_LIBPATH ${FFMPEG}/lib) - - SET(LIBSAMPLERATE ${LIBDIR}/samplerate) - SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include) - SET(LIBSAMPLERATE_LIB samplerate) - SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib) - - SET(LLIBS stdc++ SystemStubs) - - SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") - SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime") - - IF(WITH_OPENMP) - SET(LLIBS "${LLIBS} -lgomp ") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ") - ENDIF(WITH_OPENMP) - - SET(SDL ${LIBDIR}/sdl) - SET(SDL_INCLUDE_DIR ${SDL}/include) - SET(SDL_LIBRARY SDL) - SET(SDL_LIBPATH ${SDL}/lib) - - SET(PNG "${LIBDIR}/png") - SET(PNG_INC "${PNG}/include") - SET(PNG_LIBPATH ${PNG}/lib) - - SET(JPEG "${LIBDIR}/jpeg") - SET(JPEG_INC "${JPEG}/include") - SET(JPEG_LIBPATH ${JPEG}/lib) - - SET(TIFF ${LIBDIR}/tiff) - SET(TIFF_INC ${TIFF}/include) - - SET(EXETYPE MACOSX_BUNDLE) + IF(WITH_FFTW3) + SET(FFTW3 ${LIBDIR}/fftw3) + SET(FFTW3_INC ${FFTW3}/include) + SET(FFTW3_LIB libfftw) + SET(FFTW3_LIBPATH ${FFTW3}/lib) + ENDIF(WITH_FFTW3) + + SET(PNG_LIBRARIES png) + SET(JPEG_LIBRARY jpeg) + + SET(ZLIB /usr) + SET(ZLIB_INC "${ZLIB}/include") + SET(ZLIB_LIBRARIES z) + + SET(FREETYPE ${LIBDIR}/freetype) + SET(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2) + SET(FREETYPE_LIBPATH ${FREETYPE}/lib) + SET(FREETYPE_LIBRARY freetype) + + SET(OPENEXR ${LIBDIR}/openexr) + SET(OPENEXR_INC ${OPENEXR}/include/OpenEXR ${OPENEXR}/include) + SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread) + SET(OPENEXR_LIBPATH ${OPENEXR}/lib) + + SET(FFMPEG ${LIBDIR}/ffmpeg) + SET(FFMPEG_INC ${CMAKE_SOURCE_DIR}/extern/ffmpeg) + SET(FFMPEG_LIB avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore) + SET(FFMPEG_LIBPATH ${FFMPEG}/lib) + + SET(LIBSAMPLERATE ${LIBDIR}/samplerate) + SET(LIBSAMPLERATE_INC ${LIBSAMPLERATE}/include) + SET(LIBSAMPLERATE_LIB samplerate) + SET(LIBSAMPLERATE_LIBPATH ${LIBSAMPLERATE}/lib) + + SET(LLIBS stdc++ SystemStubs) + + SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") + SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime") + + IF(WITH_OPENMP) + SET(LLIBS "${LLIBS} -lgomp ") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ") + ENDIF(WITH_OPENMP) + + SET(SDL ${LIBDIR}/sdl) + SET(SDL_INCLUDE_DIR ${SDL}/include) + SET(SDL_LIBRARY SDL) + SET(SDL_LIBPATH ${SDL}/lib) + + SET(PNG "${LIBDIR}/png") + SET(PNG_INC "${PNG}/include") + SET(PNG_LIBPATH ${PNG}/lib) + + SET(JPEG "${LIBDIR}/jpeg") + SET(JPEG_INC "${JPEG}/include") + SET(JPEG_LIBPATH ${JPEG}/lib) + + SET(TIFF ${LIBDIR}/tiff) + SET(TIFF_INC ${TIFF}/include) + + SET(EXETYPE MACOSX_BUNDLE) ENDIF(APPLE) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc) - SET(BINRELOC_INC ${BINRELOC}/include) + SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc) + SET(BINRELOC_INC ${BINRELOC}/include) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") @@ -534,10 +534,10 @@ set(OPENJPEG_LIb extern_libopenjpeg) # Blender WebPlugin IF(WITH_WEBPLUGIN) - SET(GECKO_DIR "${CMAKE_SOURCE_DIR}/../gecko-sdk/" CACHE PATH "Gecko SDK path") - SET(WEBPLUGIN_SANDBOX_MODE "apparmor" CACHE STRING "WEB Plugin sandbox mode, can be apparmor, privsep, none") + SET(GECKO_DIR "${CMAKE_SOURCE_DIR}/../gecko-sdk/" CACHE PATH "Gecko SDK path") + SET(WEBPLUGIN_SANDBOX_MODE "apparmor" CACHE STRING "WEB Plugin sandbox mode, can be apparmor, privsep, none") - SET(WITH_PLAYER ON) + SET(WITH_PLAYER ON) ENDIF(WITH_WEBPLUGIN) @@ -555,7 +555,7 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ${CXX_WARNINGS}") # better not define flags here but this is a debugging option thats off by default. IF(WITH_CXX_GUARDEDALLOC) - SET(CMAKE_CXX_FLAGS " -DWITH_CXX_GUARDEDALLOC -I${CMAKE_SOURCE_DIR}/intern/guardedalloc ${CMAKE_CXX_FLAGS}") + SET(CMAKE_CXX_FLAGS " -DWITH_CXX_GUARDEDALLOC -I${CMAKE_SOURCE_DIR}/intern/guardedalloc ${CMAKE_CXX_FLAGS}") ENDIF(WITH_CXX_GUARDEDALLOC) #----------------------------------------------------------------------------- @@ -574,6 +574,6 @@ ADD_SUBDIRECTORY(source/creator) #----------------------------------------------------------------------------- # Blender Player IF(WITH_PLAYER) - ADD_SUBDIRECTORY(source/blenderplayer) + ADD_SUBDIRECTORY(source/blenderplayer) ENDIF(WITH_PLAYER) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 019cd9de28b..44e47aaf88d 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -25,17 +25,17 @@ # ***** END GPL LICENSE BLOCK ***** IF(WITH_BULLET) - ADD_SUBDIRECTORY(bullet2) + ADD_SUBDIRECTORY(bullet2) ENDIF(WITH_BULLET) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - ADD_SUBDIRECTORY(binreloc) + ADD_SUBDIRECTORY(binreloc) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") ADD_SUBDIRECTORY(glew) IF(WITH_OPENJPEG) - ADD_SUBDIRECTORY(libopenjpeg) + ADD_SUBDIRECTORY(libopenjpeg) ENDIF(WITH_OPENJPEG) ADD_SUBDIRECTORY(lzo) diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt index edb6b9c525f..2e2d8920781 100644 --- a/extern/bullet2/CMakeLists.txt +++ b/extern/bullet2/CMakeLists.txt @@ -27,16 +27,16 @@ SET(INC . src) FILE(GLOB SRC - src/LinearMath/*.cpp - src/BulletCollision/BroadphaseCollision/*.cpp - src/BulletCollision/CollisionShapes/*.cpp - src/BulletCollision/NarrowPhaseCollision/*.cpp - src/BulletCollision/Gimpact/*.cpp - src/BulletCollision//CollisionDispatch/*.cpp - src/BulletDynamics/ConstraintSolver/*.cpp - src/BulletDynamics/Vehicle/*.cpp - src/BulletDynamics/Dynamics/*.cpp - src/BulletSoftBody/*.cpp + src/LinearMath/*.cpp + src/BulletCollision/BroadphaseCollision/*.cpp + src/BulletCollision/CollisionShapes/*.cpp + src/BulletCollision/NarrowPhaseCollision/*.cpp + src/BulletCollision/Gimpact/*.cpp + src/BulletCollision//CollisionDispatch/*.cpp + src/BulletDynamics/ConstraintSolver/*.cpp + src/BulletDynamics/Vehicle/*.cpp + src/BulletDynamics/Dynamics/*.cpp + src/BulletSoftBody/*.cpp ) ADD_DEFINITIONS(-D_LIB) diff --git a/extern/bullet2/src/BulletCollision/CMakeLists.txt b/extern/bullet2/src/BulletCollision/CMakeLists.txt index 4b4304f43b0..ddc806a3e6a 100644 --- a/extern/bullet2/src/BulletCollision/CMakeLists.txt +++ b/extern/bullet2/src/BulletCollision/CMakeLists.txt @@ -211,13 +211,13 @@ ADD_LIBRARY(BulletCollision ${BulletCollision_SRCS} ${BulletCollision_HDRS}) SET_TARGET_PROPERTIES(BulletCollision PROPERTIES VERSION ${BULLET_VERSION}) SET_TARGET_PROPERTIES(BulletCollision PROPERTIES SOVERSION ${BULLET_VERSION}) IF (BUILD_SHARED_LIBS) - TARGET_LINK_LIBRARIES(BulletCollision LinearMath) + TARGET_LINK_LIBRARIES(BulletCollision LinearMath) ENDIF (BUILD_SHARED_LIBS) #INSTALL of other files requires CMake 2.6 IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) INSTALL(TARGETS BulletCollision DESTINATION lib) - INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) diff --git a/extern/bullet2/src/BulletSoftBody/CMakeLists.txt b/extern/bullet2/src/BulletSoftBody/CMakeLists.txt index dbd87afea38..fe31d2bee71 100644 --- a/extern/bullet2/src/BulletSoftBody/CMakeLists.txt +++ b/extern/bullet2/src/BulletSoftBody/CMakeLists.txt @@ -34,7 +34,7 @@ ENDIF (BUILD_SHARED_LIBS) IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) INSTALL(TARGETS BulletSoftBody DESTINATION lib) - INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h") ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5) IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK) diff --git a/extern/glew/CMakeLists.txt b/extern/glew/CMakeLists.txt index eea34488e17..26d10a6ca9f 100644 --- a/extern/glew/CMakeLists.txt +++ b/extern/glew/CMakeLists.txt @@ -27,11 +27,11 @@ SET(INC include src) IF(UNIX) - SET(INC ${INC} ${X11_X11_INCLUDE_PATH}) + SET(INC ${INC} ${X11_X11_INCLUDE_PATH}) ENDIF(UNIX) SET(SRC - src/glew.c + src/glew.c ) BLENDERLIB(extern_glew "${SRC}" "${INC}") diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index f33ce6a893c..9efd1a6ee7c 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -38,7 +38,7 @@ ADD_SUBDIRECTORY(opennl) ADD_SUBDIRECTORY(smoke) IF(WITH_ELBEEM) - ADD_SUBDIRECTORY(elbeem) + ADD_SUBDIRECTORY(elbeem) ENDIF(WITH_ELBEEM) ADD_SUBDIRECTORY(bsp) diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt index 1b48de3190b..587ef30979b 100644 --- a/intern/audaspace/CMakeLists.txt +++ b/intern/audaspace/CMakeLists.txt @@ -25,38 +25,38 @@ SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC}) FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp) IF(WITH_FFMPEG) - SET(INC ${INC} ffmpeg ${FFMPEG_INC}) - FILE(GLOB FFMPEGSRC ffmpeg/*.cpp) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ffmpeg ${FFMPEG_INC}) + FILE(GLOB FFMPEGSRC ffmpeg/*.cpp) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(WITH_SDL) - SET(INC ${INC} SDL ${SDL_INCLUDE_DIR}) - FILE(GLOB SDLSRC SDL/*.cpp) - ADD_DEFINITIONS(-DWITH_SDL) + SET(INC ${INC} SDL ${SDL_INCLUDE_DIR}) + FILE(GLOB SDLSRC SDL/*.cpp) + ADD_DEFINITIONS(-DWITH_SDL) ENDIF(WITH_SDL) IF(WITH_OPENAL) - SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR}) - FILE(GLOB OPENALSRC OpenAL/*.cpp) - ADD_DEFINITIONS(-DWITH_OPENAL) + SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR}) + FILE(GLOB OPENALSRC OpenAL/*.cpp) + ADD_DEFINITIONS(-DWITH_OPENAL) - STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INCLUDE_DIR}) - IF(FRAMEWORK) - ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX) - ENDIF(FRAMEWORK) + STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INCLUDE_DIR}) + IF(FRAMEWORK) + ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX) + ENDIF(FRAMEWORK) ENDIF(WITH_OPENAL) IF(WITH_JACK) - SET(INC ${INC} jack ${JACK_INC}) - FILE(GLOB JACKSRC jack/*.cpp) - ADD_DEFINITIONS(-DWITH_JACK) + SET(INC ${INC} jack ${JACK_INC}) + FILE(GLOB JACKSRC jack/*.cpp) + ADD_DEFINITIONS(-DWITH_JACK) ENDIF(WITH_JACK) IF(WITH_SNDFILE) - SET(INC ${INC} sndfile ${SNDFILE_INC}) - FILE(GLOB SNDFILESRC sndfile/*.cpp) - ADD_DEFINITIONS(-DWITH_SNDFILE) + SET(INC ${INC} sndfile ${SNDFILE_INC}) + FILE(GLOB SNDFILESRC sndfile/*.cpp) + ADD_DEFINITIONS(-DWITH_SNDFILE) ENDIF(WITH_SNDFILE) SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC}) diff --git a/intern/elbeem/CMakeLists.txt b/intern/elbeem/CMakeLists.txt index 8b8a3000efd..e541d334086 100644 --- a/intern/elbeem/CMakeLists.txt +++ b/intern/elbeem/CMakeLists.txt @@ -30,11 +30,11 @@ FILE(GLOB SRC intern/*.cpp) ADD_DEFINITIONS(-DNOGUI -DELBEEM_BLENDER=1) IF(WINDOWS) - ADD_DEFINITIONS(-DUSE_MSVC6FIXES) + ADD_DEFINITIONS(-DUSE_MSVC6FIXES) ENDIF(WINDOWS) IF(WITH_OPENMP) - ADD_DEFINITIONS(-DPARALLEL=1) + ADD_DEFINITIONS(-DPARALLEL=1) ENDIF(WITH_OPENMP) BLENDERLIB_NOLIST(bf_elbeem "${SRC}" "${INC}") diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 3d588ecfd00..9128e923e19 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -29,30 +29,30 @@ SET(INC . ../string) FILE(GLOB SRC intern/*.cpp) IF(APPLE) - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp") ELSE(APPLE) - IF(WIN32) - SET(INC ${INC} ${WINTAB_INC}) - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp") - ELSE(WIN32) - SET(INC ${INC} ${X11_X11_INCLUDE_PATH}) - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp") - LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp") - ENDIF(WIN32) + IF(WIN32) + SET(INC ${INC} ${WINTAB_INC}) + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp") + ELSE(WIN32) + SET(INC ${INC} ${X11_X11_INCLUDE_PATH}) + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp") + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp") + ENDIF(WIN32) ENDIF(APPLE) BLENDERLIB(bf_ghost "${SRC}" "${INC}") diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt index b29837fac7d..40ca35632d7 100644 --- a/intern/guardedalloc/CMakeLists.txt +++ b/intern/guardedalloc/CMakeLists.txt @@ -32,6 +32,6 @@ BLENDERLIB(bf_guardedalloc "${SRC}" "${INC}") # Override C++ alloc optional IF(WITH_CXX_GUARDEDALLOC) - FILE(GLOB SRC cpp/*.cpp) - BLENDERLIB(bf_guardedalloc_cpp "${SRC}" "${INC}") + FILE(GLOB SRC cpp/*.cpp) + BLENDERLIB(bf_guardedalloc_cpp "${SRC}" "${INC}") ENDIF(WITH_CXX_GUARDEDALLOC) diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt index 0db6acb683f..8ed7a7c9115 100644 --- a/intern/smoke/CMakeLists.txt +++ b/intern/smoke/CMakeLists.txt @@ -29,12 +29,12 @@ SET(INC ${PNG_INC} ${ZLIB_INC} intern ../../extern/bullet2/src ../memutil ../gua FILE(GLOB SRC intern/*.cpp) IF(WITH_OPENMP) - ADD_DEFINITIONS(-DPARALLEL=1) + ADD_DEFINITIONS(-DPARALLEL=1) ENDIF(WITH_OPENMP) IF(WITH_FFTW3) - ADD_DEFINITIONS(-DFFTW3=1) - SET(INC ${INC} ${FFTW3_INC}) + ADD_DEFINITIONS(-DFFTW3=1) + SET(INC ${INC} ${FFTW3_INC}) ENDIF(WITH_FFTW3) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 4764caddf6a..4adc51bcb15 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -28,9 +28,9 @@ ADD_SUBDIRECTORY(blender) ADD_SUBDIRECTORY(kernel) IF(WITH_GAMEENGINE) - ADD_SUBDIRECTORY(gameengine) + ADD_SUBDIRECTORY(gameengine) ENDIF(WITH_GAMEENGINE) IF(WINDOWS) - ADD_SUBDIRECTORY(icons) + ADD_SUBDIRECTORY(icons) ENDIF(WINDOWS) diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index a9e3d50211f..703c5acd8a2 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -42,18 +42,18 @@ ADD_SUBDIRECTORY(render) ADD_SUBDIRECTORY(blenfont) IF(WITH_OPENEXR) - ADD_SUBDIRECTORY(imbuf/intern/openexr) + ADD_SUBDIRECTORY(imbuf/intern/openexr) ENDIF(WITH_OPENEXR) IF(WITH_DDS) - ADD_SUBDIRECTORY(imbuf/intern/dds) + ADD_SUBDIRECTORY(imbuf/intern/dds) ENDIF(WITH_DDS) IF(WITH_QUICKTIME) - ADD_SUBDIRECTORY(quicktime) + ADD_SUBDIRECTORY(quicktime) ENDIF(WITH_QUICKTIME) IF(WITH_PYTHON) - ADD_SUBDIRECTORY(python) + ADD_SUBDIRECTORY(python) ENDIF(WITH_PYTHON) diff --git a/source/blender/avi/CMakeLists.txt b/source/blender/avi/CMakeLists.txt index 4738ea14292..4e48b689055 100644 --- a/source/blender/avi/CMakeLists.txt +++ b/source/blender/avi/CMakeLists.txt @@ -27,8 +27,8 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../../../intern/guardedalloc - ${JPEG_INC} + . ../../../intern/guardedalloc + ${JPEG_INC} ) BLENDERLIB(bf_avi "${SRC}" "${INC}") diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index bc03e69eb88..844a6899bf5 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -25,17 +25,17 @@ FILE(GLOB SRC intern/*.c) SET(INC - ../../../intern/guardedalloc ../blenlib ../makesdna ../editors/include - ../blenkernel ../../../extern/glew/include . - ${FREETYPE_INCLUDE_DIRS} + ../../../intern/guardedalloc ../blenlib ../makesdna ../editors/include + ../blenkernel ../../../extern/glew/include . + ${FREETYPE_INCLUDE_DIRS} ) IF(WITH_INTERNATIONAL) - SET(INC ${INC} ${GETTEXT_INC}) + SET(INC ${INC} ${GETTEXT_INC}) ENDIF(WITH_INTERNATIONAL) IF(WIN32) - ADD_DEFINITIONS(-D_WIN32 -DUSE_GETTEXT_DLL) + ADD_DEFINITIONS(-D_WIN32 -DUSE_GETTEXT_DLL) ENDIF(WIN32) BLENDERLIB(bf_blenfont "${SRC}" "${INC}") diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 17079205423..68aed2b0184 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -27,57 +27,57 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna - ../render/extern/include ../../../intern/decimation/extern - ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern - ../../../intern/iksolver/extern ../blenloader - ../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern - ../../../intern/bsp/extern ../blenfont - ../../../intern/audaspace/intern - ../../../extern/lzo/minilzo - ../../../extern/lzma - ${ZLIB_INC} + . ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna + ../render/extern/include ../../../intern/decimation/extern + ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern + ../../../intern/iksolver/extern ../blenloader + ../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern + ../../../intern/bsp/extern ../blenfont + ../../../intern/audaspace/intern + ../../../extern/lzo/minilzo + ../../../extern/lzma + ${ZLIB_INC} ) IF(WITH_BULLET) - SET(INC ${INC} ../../../extern/bullet2/src) - ADD_DEFINITIONS(-DUSE_BULLET) + SET(INC ${INC} ../../../extern/bullet2/src) + ADD_DEFINITIONS(-DUSE_BULLET) ENDIF(WITH_BULLET) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_OPENJPEG) - ADD_DEFINITIONS(-DWITH_OPENJPEG) + ADD_DEFINITIONS(-DWITH_OPENJPEG) ENDIF(WITH_OPENJPEG) IF(WITH_DDS) - ADD_DEFINITIONS(-DWITH_DDS) + ADD_DEFINITIONS(-DWITH_DDS) ENDIF(WITH_DDS) IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(WITH_PYTHON) - SET(INC ${INC} ../python ${PYTHON_INC}) + SET(INC ${INC} ../python ${PYTHON_INC}) ELSE(WITH_PYTHON) - ADD_DEFINITIONS(-DDISABLE_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) ENDIF(WITH_PYTHON) IF(NOT WITH_ELBEEM) - ADD_DEFINITIONS(-DDISABLE_ELBEEM) + ADD_DEFINITIONS(-DDISABLE_ELBEEM) ENDIF(NOT WITH_ELBEEM) IF(WIN32) - SET(INC ${INC} ${PTHREADS_INC}) + SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) BLENDERLIB(bf_blenkernel "${SRC}" "${INC}") diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index a0bf2367b98..4ed9eb4b007 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -27,20 +27,20 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../makesdna ../blenkernel ../../../intern/guardedalloc ../include - ${FREETYPE_INCLUDE_DIRS} - ${ZLIB_INC} + . ../makesdna ../blenkernel ../../../intern/guardedalloc ../include + ${FREETYPE_INCLUDE_DIRS} + ${ZLIB_INC} ) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") SET(INC - ${INC} - ${BINRELOC_INC} + ${INC} + ${BINRELOC_INC} ) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF(WIN32) - SET(INC ${INC} ${PTHREADS_INC}) + SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) BLENDERLIB(bf_blenlib "${SRC}" "${INC}") diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 7bdffdedc05..d31a85ab208 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -27,11 +27,11 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../../../intern/guardedalloc ../blenlib ../blenkernel - ../makesdna ../readblenfile ../include ../makesrna - ../python ../../kernel/gen_messaging - ../render/extern/include - ${ZLIB_INC} + . ../../../intern/guardedalloc ../blenlib ../blenkernel + ../makesdna ../readblenfile ../include ../makesrna + ../python ../../kernel/gen_messaging + ../render/extern/include + ${ZLIB_INC} ) BLENDERLIB(bf_blenloader "${SRC}" "${INC}") diff --git a/source/blender/blenpluginapi/CMakeLists.txt b/source/blender/blenpluginapi/CMakeLists.txt index 856fb931e9d..1c5e2697c01 100644 --- a/source/blender/blenpluginapi/CMakeLists.txt +++ b/source/blender/blenpluginapi/CMakeLists.txt @@ -27,12 +27,12 @@ FILE(GLOB SRC intern/*.c) SET(INC - . .. ../../../intern/guardedalloc ../blenlib ../imbuf ../makesdna + . .. ../../../intern/guardedalloc ../blenlib ../imbuf ../makesdna ) IF(WITH_QUICKTIME) - SET(INC ${INC} ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) BLENDERLIB(bf_blenpluginapi "${SRC}" "${INC}") diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index c40b18ea099..066d42e723e 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -27,64 +27,64 @@ FILE(GLOB SRC */*.c) SET(INC ../windowmanager - ../editors/include - ../../../intern/guardedalloc ../../../intern/memutil - ../blenlib ../makesdna ../makesrna ../blenkernel - ../include ../imbuf ../render/extern/include - ../../../intern/bsp/extern - ../../../intern/decimation/extern ../blenloader ../python - ../../kernel/gen_system ../readstreamglue - ../../../intern/elbeem/extern - ../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include ../../../intern/smoke/extern - ../../../intern/audaspace/intern - ../nodes - ../gpu - ../blenfont + ../editors/include + ../../../intern/guardedalloc ../../../intern/memutil + ../blenlib ../makesdna ../makesrna ../blenkernel + ../include ../imbuf ../render/extern/include + ../../../intern/bsp/extern + ../../../intern/decimation/extern ../blenloader ../python + ../../kernel/gen_system ../readstreamglue + ../../../intern/elbeem/extern + ../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include ../../../intern/smoke/extern + ../../../intern/audaspace/intern + ../nodes + ../gpu + ../blenfont ) IF(WITH_GAMEENGINE) - ADD_DEFINITIONS(-DGAMEBLENDER) + ADD_DEFINITIONS(-DGAMEBLENDER) ENDIF(WITH_GAMEENGINE) IF(WITH_INTERNATIONAL) - ADD_DEFINITIONS(-DINTERNATIONAL) + ADD_DEFINITIONS(-DINTERNATIONAL) ENDIF(WITH_INTERNATIONAL) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_OPENJPEG) - ADD_DEFINITIONS(-DWITH_OPENJPEG) + ADD_DEFINITIONS(-DWITH_OPENJPEG) ENDIF(WITH_OPENJPEG) IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(NOT WITH_ELBEEM) - ADD_DEFINITIONS(-DDISABLE_ELBEEM) + ADD_DEFINITIONS(-DDISABLE_ELBEEM) ENDIF(NOT WITH_ELBEEM) IF(WITH_PYTHON) - SET(INC ${INC} ${PYTHON_INC}) + SET(INC ${INC} ${PYTHON_INC}) ELSE(WITH_PYTHON) - ADD_DEFINITIONS(-DDISABLE_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) ENDIF(WITH_PYTHON) IF(WIN32) - SET(INC ${INC} ${PTHREADS_INC}) + SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) # TODO buildinfo IF(BF_BUILDINFO) - ADD_DEFINITIONS(-DNAN_BUILDINFO) + ADD_DEFINITIONS(-DNAN_BUILDINFO) ENDIF(BF_BUILDINFO) BLENDERLIB_NOLIST(bf_editors "${SRC}" "${INC}") diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt index 7429f45c00f..ad7770e12fa 100644 --- a/source/blender/editors/screen/CMakeLists.txt +++ b/source/blender/editors/screen/CMakeLists.txt @@ -30,49 +30,49 @@ FILE(GLOB SRC */*.c) SET(INC ../../windowmanager - ../../editors/include - ../../../../intern/guardedalloc ../../../../intern/memutil - ../../blenlib ../../makesdna ../../makesrna ../../blenkernel - ../../include ../../imbuf - ../../render/extern/include ../../../../intern/bsp/extern - ../../../intern/decimation/extern ../../blenloader - ../../../kernel/gen_system ../../readstreamglue - ../../../../intern/elbeem/extern - ../../../../intern/ghost ../../../../intern/opennl/extern - ../../nodes + ../../editors/include + ../../../../intern/guardedalloc ../../../../intern/memutil + ../../blenlib ../../makesdna ../../makesrna ../../blenkernel + ../../include ../../imbuf + ../../render/extern/include ../../../../intern/bsp/extern + ../../../intern/decimation/extern ../../blenloader + ../../../kernel/gen_system ../../readstreamglue + ../../../../intern/elbeem/extern + ../../../../intern/ghost ../../../../intern/opennl/extern + ../../nodes ) IF(WITH_INTERNATIONAL) - ADD_DEFINITIONS(-DINTERNATIONAL) + ADD_DEFINITIONS(-DINTERNATIONAL) ENDIF(WITH_INTERNATIONAL) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_QUICKTIME) - SET(INC ${INC} ../../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(WITH_PYTHON) - SET(INC ${INC} ../../python ${PYTHON_INC}) + SET(INC ${INC} ../../python ${PYTHON_INC}) ELSE(WITH_PYTHON) - ADD_DEFINITIONS(-DDISABLE_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) ENDIF(WITH_PYTHON) IF(WIN32) - SET(INC ${INC} ${PTHREADS_INC}) + SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) # TODO buildinfo IF(BF_BUILDINFO) - ADD_DEFINITIONS(-DNAN_BUILDINFO) + ADD_DEFINITIONS(-DNAN_BUILDINFO) ENDIF(BF_BUILDINFO) BLENDERLIB_NOLIST(bf_editors "${SRC}" "${INC}") diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 4d376f47d91..85f4233a251 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -27,8 +27,8 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../blenlib ../blenkernel ../makesdna ../include - ../../../extern/glew/include ../../../intern/guardedalloc ../imbuf) + . ../blenlib ../blenkernel ../makesdna ../include + ../../../extern/glew/include ../../../intern/guardedalloc ../imbuf) BLENDERLIB(bf_gpu "${SRC}" "${INC}") diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 76dd2afebdc..5eb98151c14 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -27,35 +27,35 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../makesdna ../../../intern/guardedalloc ../../../intern/memutil ../blenlib - ../avi ../blenkernel - ${JPEG_INC} - ${PNG_INC} - ${TIFF_INC} - ${ZLIB_INC} - ${OPENJPEG_INC} + . ../makesdna ../../../intern/guardedalloc ../../../intern/memutil ../blenlib + ../avi ../blenkernel + ${JPEG_INC} + ${PNG_INC} + ${TIFF_INC} + ${ZLIB_INC} + ${OPENJPEG_INC} ) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_OPENJPEG) - ADD_DEFINITIONS(-DWITH_OPENJPEG) + ADD_DEFINITIONS(-DWITH_OPENJPEG) ENDIF(WITH_OPENJPEG) IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) if(WITH_DDS) - ADD_DEFINITIONS(-DWITH_DDS) + ADD_DEFINITIONS(-DWITH_DDS) ENDIF(WITH_DDS) BLENDERLIB(bf_imbuf "${SRC}" "${INC}") diff --git a/source/blender/imbuf/intern/cineon/CMakeLists.txt b/source/blender/imbuf/intern/cineon/CMakeLists.txt index 53cd161634b..8b28086016b 100644 --- a/source/blender/imbuf/intern/cineon/CMakeLists.txt +++ b/source/blender/imbuf/intern/cineon/CMakeLists.txt @@ -27,14 +27,14 @@ FILE(GLOB SRC *.c) SET(INC - . - ../../../blenkernel - ../../ - .. - ../../../blenlib - intern/include - ../../../../../intern/guardedalloc - ../../../makesdna + . + ../../../blenkernel + ../../ + .. + ../../../blenlib + intern/include + ../../../../../intern/guardedalloc + ../../../makesdna ) BLENDERLIB(bf_cineon "${SRC}" "${INC}") diff --git a/source/blender/imbuf/intern/dds/CMakeLists.txt b/source/blender/imbuf/intern/dds/CMakeLists.txt index 842f53bd88b..dc45afb9f5b 100644 --- a/source/blender/imbuf/intern/dds/CMakeLists.txt +++ b/source/blender/imbuf/intern/dds/CMakeLists.txt @@ -27,18 +27,18 @@ FILE (GLOB SRC *.cpp) SET(INC - . - ../../../blenkernel - ../../../makesdna - ../../ - .. - ../../../blenlib - intern/include - ../../../../../intern/guardedalloc + . + ../../../blenkernel + ../../../makesdna + ../../ + .. + ../../../blenlib + intern/include + ../../../../../intern/guardedalloc ) if(WITH_DDS) - ADD_DEFINITIONS(-DWITH_DDS) + ADD_DEFINITIONS(-DWITH_DDS) ENDIF(WITH_DDS) BLENDERLIB(bf_dds "${SRC}" "${INC}") diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt index 21792086774..33681da55af 100644 --- a/source/blender/imbuf/intern/openexr/CMakeLists.txt +++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt @@ -27,19 +27,19 @@ SET(SRC openexr_api.cpp) SET(INC - . - ../../../blenkernel - ../../ - .. - ../../../blenlib - intern/include - ../../../../../intern/guardedalloc - ../../../makesdna - ${OPENEXR_INC} + . + ../../../blenkernel + ../../ + .. + ../../../blenlib + intern/include + ../../../../../intern/guardedalloc + ../../../makesdna + ${OPENEXR_INC} ) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) BLENDERLIB(bf_openexr "${SRC}" "${INC}") diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 6024799f852..1fb63156f26 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -33,9 +33,9 @@ ADD_EXECUTABLE(makesdna ${SRC} ${INC_FILES}) # Output dna.c ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c - COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ - DEPENDS makesdna + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c + COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ + DEPENDS makesdna ) # Build bf_dna library diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index a1f42fbccb3..709c5d017ec 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -32,59 +32,59 @@ LIST(REMOVE_ITEM DEFSRC ${APISRC}) STRING(REGEX REPLACE "rna_([a-zA-Z0-9_-]*).c" "${CMAKE_CURRENT_BINARY_DIR}/rna_\\1_gen.c" GENSRC "${DEFSRC}") SET(SRC - makesrna.c - rna_define.c - ${DEFSRC} - ${APISRC} - ../../../../intern/guardedalloc/intern/mallocn.c - ../../../../intern/guardedalloc/intern/mmap_win.c) + makesrna.c + rna_define.c + ${DEFSRC} + ${APISRC} + ../../../../intern/guardedalloc/intern/mallocn.c + ../../../../intern/guardedalloc/intern/mmap_win.c) INCLUDE_DIRECTORIES(../../../../intern/guardedalloc .. ../../makesdna ../../blenkernel ../../blenlib ../../windowmanager ../../editors/include ../../imbuf ../../render/extern/include .) FILE(GLOB INC_FILES ../*.h ../../makesdna/*.h) IF(WITH_GAMEENGINE) - ADD_DEFINITIONS(-DGAMEBLENDER) + ADD_DEFINITIONS(-DGAMEBLENDER) ENDIF(WITH_GAMEENGINE) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_OPENJPEG) - ADD_DEFINITIONS(-DWITH_OPENJPEG) + ADD_DEFINITIONS(-DWITH_OPENJPEG) ENDIF(WITH_OPENJPEG) IF(WITH_DDS) - ADD_DEFINITIONS(-DWITH_DDS) + ADD_DEFINITIONS(-DWITH_DDS) ENDIF(WITH_DDS) IF(WITH_QUICKTIME) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(NOT WITH_ELBEEM) - ADD_DEFINITIONS(-DDISABLE_ELBEEM) + ADD_DEFINITIONS(-DDISABLE_ELBEEM) ENDIF(NOT WITH_ELBEEM) IF(WITH_FFTW3) - ADD_DEFINITIONS(-DFFTW3=1) + ADD_DEFINITIONS(-DFFTW3=1) ENDIF(WITH_FFTW3) IF(WITH_SDL) - ADD_DEFINITIONS(-DWITH_SDL) + ADD_DEFINITIONS(-DWITH_SDL) ENDIF(WITH_SDL) IF(WITH_OPENAL) - ADD_DEFINITIONS(-DWITH_OPENAL) + ADD_DEFINITIONS(-DWITH_OPENAL) ENDIF(WITH_OPENAL) IF(WITH_JACK) - ADD_DEFINITIONS(-DWITH_JACK) + ADD_DEFINITIONS(-DWITH_JACK) ENDIF(WITH_JACK) # Build makesrna executable @@ -93,9 +93,9 @@ TARGET_LINK_LIBRARIES(makesrna bf_dna) # Output rna_*_gen.c ADD_CUSTOM_COMMAND( - OUTPUT ${GENSRC} - COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesrna ${CMAKE_CURRENT_BINARY_DIR}/ - DEPENDS makesrna + OUTPUT ${GENSRC} + COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesrna ${CMAKE_CURRENT_BINARY_DIR}/ + DEPENDS makesrna ) # Build bf_rna diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index bba96adf25e..df2567142ca 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -26,32 +26,32 @@ FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c intern/TEX_nodes/*.c) SET(INC - . ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna - ../render/extern/include ../../../intern/decimation/extern ../makesrna - ../imbuf ../avi ../../../intern/elbeem/extern - ../../../intern/iksolver/extern ../blenloader - ../blenkernel ../../../extern/glew/include ../gpu - ${ZLIB_INC} + . ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna + ../render/extern/include ../../../intern/decimation/extern ../makesrna + ../imbuf ../avi ../../../intern/elbeem/extern + ../../../intern/iksolver/extern ../blenloader + ../blenkernel ../../../extern/glew/include ../gpu + ${ZLIB_INC} ) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(WITH_PYTHON) - SET(INC ${INC} ../python ${PYTHON_INC}) + SET(INC ${INC} ../python ${PYTHON_INC}) ELSE(WITH_PYTHON) - ADD_DEFINITIONS(-DDISABLE_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) ENDIF(WITH_PYTHON) BLENDERLIB(bf_nodes "${SRC}" "${INC}") diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt index 7700e6bc2aa..7abec566505 100644 --- a/source/blender/python/CMakeLists.txt +++ b/source/blender/python/CMakeLists.txt @@ -27,23 +27,23 @@ FILE(GLOB SRC intern/*.c) FILE(GLOB GENSRC generic/*.c) SET(INC - . ../../../intern/guardedalloc ../blenlib ../makesdna ../makesrna - ../blenkernel ../editors/include ../windowmanager ${PYTHON_INC} - ../../../extern/glew/include + . ../../../intern/guardedalloc ../blenlib ../makesdna ../makesrna + ../blenkernel ../editors/include ../windowmanager ${PYTHON_INC} + ../../../extern/glew/include ) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_QUICKTIME) - SET(INC ${INC} ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) ADD_DEFINITIONS(-DWITH_CCGSUBSURF) diff --git a/source/blender/quicktime/CMakeLists.txt b/source/blender/quicktime/CMakeLists.txt index 95969878cf1..ac503bb62cb 100644 --- a/source/blender/quicktime/CMakeLists.txt +++ b/source/blender/quicktime/CMakeLists.txt @@ -27,18 +27,18 @@ SET(SRC apple/quicktime_import.c apple/quicktime_export.c) SET(INC - . - ../quicktime - ../makesdna - ../../../intern/guardedalloc - ../blenlib - ../blenkernel - ../avi - ../imbuf - ../imbuf/intern - ../blenloader - ../render/extern/include - ../include + . + ../quicktime + ../makesdna + ../../../intern/guardedalloc + ../blenlib + ../blenkernel + ../avi + ../imbuf + ../imbuf/intern + ../blenloader + ../render/extern/include + ../include ) SET(INC ${INC} ${QUICKTIME_INC}) diff --git a/source/blender/readblenfile/CMakeLists.txt b/source/blender/readblenfile/CMakeLists.txt index dc4a8f5636d..ded4a1e00cf 100644 --- a/source/blender/readblenfile/CMakeLists.txt +++ b/source/blender/readblenfile/CMakeLists.txt @@ -27,7 +27,7 @@ FILE(GLOB SRC intern/*.c) SET(INC - . ../blenloader ../blenloader/intern ../blenkernel ../blenlib ../makesdna ../../kernel/gen_messaging + . ../blenloader ../blenloader/intern ../blenkernel ../blenlib ../makesdna ../../kernel/gen_messaging ) BLENDERLIB(bf_readblenfile "${SRC}" "${INC}") diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index ad96b9db166..3284f7ea79a 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -27,24 +27,24 @@ FILE(GLOB SRC intern/source/*.c) SET(INC - intern/include ../../../intern/guardedalloc ../blenlib ../makesdna - extern/include ../blenkernel ../imbuf - ../include ../../kernel/gen_messaging ../blenloader - ../../../intern/smoke/extern - ../makesrna + intern/include ../../../intern/guardedalloc ../blenlib ../makesdna + extern/include ../blenkernel ../imbuf + ../include ../../kernel/gen_messaging ../blenloader + ../../../intern/smoke/extern + ../makesrna ) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - ADD_DEFINITIONS(-DWITH_FFMPEG) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) #TODO diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 26d4ab20356..cb2fc92a1b6 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -27,52 +27,52 @@ FILE(GLOB SRC intern/*.c) SET(INC . - ../editors/include - ../../../intern/guardedalloc ../../../intern/memutil - ../blenlib ../makesdna ../makesrna ../blenkernel - ../include ../imbuf ../render/extern/include - ../../../intern/bsp/extern - ../../../intern/decimation/extern ../blenloader - ../../kernel/gen_system ../readstreamglue - ../../../intern/elbeem/extern - ../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include - ../nodes - ../gpu - ../blenfont - ${OPENGL_INCLUDE_DIR} + ../editors/include + ../../../intern/guardedalloc ../../../intern/memutil + ../blenlib ../makesdna ../makesrna ../blenkernel + ../include ../imbuf ../render/extern/include + ../../../intern/bsp/extern + ../../../intern/decimation/extern ../blenloader + ../../kernel/gen_system ../readstreamglue + ../../../intern/elbeem/extern + ../../../intern/ghost ../../../intern/opennl/extern ../../../extern/glew/include + ../nodes + ../gpu + ../blenfont + ${OPENGL_INCLUDE_DIR} ) IF(WITH_INTERNATIONAL) - ADD_DEFINITIONS(-DINTERNATIONAL) + ADD_DEFINITIONS(-DINTERNATIONAL) ENDIF(WITH_INTERNATIONAL) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) + SET(INC ${INC} ${FFMPEG_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) IF(WITH_PYTHON) - SET(INC ${INC} ../python ${PYTHON_INC}) + SET(INC ${INC} ../python ${PYTHON_INC}) ELSE(WITH_PYTHON) - ADD_DEFINITIONS(-DDISABLE_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) ENDIF(WITH_PYTHON) IF(WIN32) - SET(INC ${INC} ${PTHREADS_INC}) + SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) # TODO buildinfo IF(BF_BUILDINFO) - ADD_DEFINITIONS(-DNAN_BUILDINFO) + ADD_DEFINITIONS(-DNAN_BUILDINFO) ENDIF(BF_BUILDINFO) BLENDERLIB_NOLIST(bf_windowmanager "${SRC}" "${INC}") diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 76a1a405698..62064e31d59 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -29,24 +29,24 @@ MESSAGE(STATUS "Configuring blenderplayer") SETUP_LIBDIRS() IF(WITH_QUICKTIME) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - ADD_DEFINITIONS(-DWITH_BINRELOC) - INCLUDE_DIRECTORIES(${BINRELOC_INC}) + ADD_DEFINITIONS(-DWITH_BINRELOC) + INCLUDE_DIRECTORIES(${BINRELOC_INC}) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c - COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ - DEPENDS ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c + COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ${CMAKE_CURRENT_BINARY_DIR}/dna.c ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ + DEPENDS ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/makesdna ) IF(WIN32) - ADD_EXECUTABLE(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../icons/winblender.rc) + ADD_EXECUTABLE(blenderplayer ${EXETYPE} ${CMAKE_CURRENT_BINARY_DIR}/dna.c ../icons/winblender.rc) ELSE(WIN32) - ADD_EXECUTABLE(blenderplayer ${CMAKE_CURRENT_BINARY_DIR}/dna.c) + ADD_EXECUTABLE(blenderplayer ${CMAKE_CURRENT_BINARY_DIR}/dna.c) ENDIF(WIN32) ADD_DEPENDENCIES(blenderplayer makesdna) @@ -56,89 +56,89 @@ FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS) SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} gp_common gp_ghost blenkernel_blc) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc) + SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF(UNIX) - # Sort libraries - SET(BLENDER_SORTED_LIBS - gp_ghost - gp_common - bf_string - bf_ghost - bf_rna - bf_blenkernel - bf_blenloader - bf_blenpluginapi - bf_blroutines - bf_converter - bf_ketsji - bf_bullet - bf_common - bf_dummy - bf_logic - bf_rasterizer - bf_oglrasterizer - bf_expressions - bf_scenegraph - bf_IK - bf_moto - bf_kernel - bf_nodes - bf_gpu - bf_imbuf - bf_avi - kx_network - bf_ngnetwork - bf_loopbacknetwork - extern_bullet - bf_guardedalloc - bf_memutil - bf_python - bf_gen_python - bf_blenlib - bf_cineon - bf_openexr - extern_libopenjpeg - bf_dds - bf_readblenfile - bf_dna - bf_videotex - bf_blenfont - bf_audaspace - blenkernel_blc - extern_binreloc - extern_glew - ) + # Sort libraries + SET(BLENDER_SORTED_LIBS + gp_ghost + gp_common + bf_string + bf_ghost + bf_rna + bf_blenkernel + bf_blenloader + bf_blenpluginapi + bf_blroutines + bf_converter + bf_ketsji + bf_bullet + bf_common + bf_dummy + bf_logic + bf_rasterizer + bf_oglrasterizer + bf_expressions + bf_scenegraph + bf_IK + bf_moto + bf_kernel + bf_nodes + bf_gpu + bf_imbuf + bf_avi + kx_network + bf_ngnetwork + bf_loopbacknetwork + extern_bullet + bf_guardedalloc + bf_memutil + bf_python + bf_gen_python + bf_blenlib + bf_cineon + bf_openexr + extern_libopenjpeg + bf_dds + bf_readblenfile + bf_dna + bf_videotex + bf_blenfont + bf_audaspace + blenkernel_blc + extern_binreloc + extern_glew + ) - IF(WITH_QUICKTIME) - SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} quicktime) - ENDIF(WITH_QUICKTIME) - - IF(WITH_CXX_GUARDEDALLOC) - SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_guardedalloc_cpp) - ENDIF(WITH_CXX_GUARDEDALLOC) - - FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) - SET(REMLIB ${SORTLIB}) - FOREACH(SEARCHLIB ${BLENDER_LINK_LIBS}) - IF(${SEARCHLIB} STREQUAL ${SORTLIB}) - SET(REMLIB "") - ENDIF(${SEARCHLIB} STREQUAL ${SORTLIB}) - ENDFOREACH(SEARCHLIB) - IF(REMLIB) - MESSAGE(STATUS "Removing library ${REMLIB} from blenderplayer linking because: not configured") - LIST(REMOVE_ITEM BLENDER_SORTED_LIBS ${REMLIB}) - ENDIF(REMLIB) - ENDFOREACH(SORTLIB) - - TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_SORTED_LIBS}) + IF(WITH_QUICKTIME) + SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} quicktime) + ENDIF(WITH_QUICKTIME) + + IF(WITH_CXX_GUARDEDALLOC) + SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_guardedalloc_cpp) + ENDIF(WITH_CXX_GUARDEDALLOC) + + FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) + SET(REMLIB ${SORTLIB}) + FOREACH(SEARCHLIB ${BLENDER_LINK_LIBS}) + IF(${SEARCHLIB} STREQUAL ${SORTLIB}) + SET(REMLIB "") + ENDIF(${SEARCHLIB} STREQUAL ${SORTLIB}) + ENDFOREACH(SEARCHLIB) + IF(REMLIB) + MESSAGE(STATUS "Removing library ${REMLIB} from blenderplayer linking because: not configured") + LIST(REMOVE_ITEM BLENDER_SORTED_LIBS ${REMLIB}) + ENDIF(REMLIB) + ENDFOREACH(SORTLIB) + + TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_SORTED_LIBS}) ELSE(UNIX) - TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_LINK_LIBS}) + TARGET_LINK_LIBRARIES(blenderplayer ${BLENDER_LINK_LIBS}) ENDIF(UNIX) IF(WITH_PLAYER) - ADD_SUBDIRECTORY(bad_level_call_stubs) + ADD_SUBDIRECTORY(bad_level_call_stubs) ENDIF(WITH_PLAYER) SETUP_LIBLINKS(blenderplayer) diff --git a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt index fea19d90ed0..502b374a318 100644 --- a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt +++ b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt @@ -27,14 +27,14 @@ FILE(GLOB SRC stubs.c) SET(INC - . - .. - ../../../source/blender/makesdna - ../../../source/blender/makesrna + . + .. + ../../../source/blender/makesdna + ../../../source/blender/makesrna ) IF(WITH_INTERNATIONAL) - ADD_DEFINITIONS(-DWITH_FREETYPE2) + ADD_DEFINITIONS(-DWITH_FREETYPE2) ENDIF(WITH_INTERNATIONAL) BLENDERLIB_NOLIST(blenkernel_blc "${SRC}" "${INC}") diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index f563dec9575..1256881182b 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -27,56 +27,56 @@ SETUP_LIBDIRS() INCLUDE_DIRECTORIES(../../intern/guardedalloc - ../blender/blenlib - ../blender/blenkernel - ../blender/editors/include - ../blender/makesrna - ../blender/makesrna/intern - ../blender/nodes - ../blender/include - ../blender/blenloader - ../blender/imbuf - ../blender/renderconverter - ../blender/render/extern/include - ../blender/makesdna - ../blender/gpu - ../blender/windowmanager - ../kernel/gen_messaging - ../kernel/gen_system - ../../extern/glew/include + ../blender/blenlib + ../blender/blenkernel + ../blender/editors/include + ../blender/makesrna + ../blender/makesrna/intern + ../blender/nodes + ../blender/include + ../blender/blenloader + ../blender/imbuf + ../blender/renderconverter + ../blender/render/extern/include + ../blender/makesdna + ../blender/gpu + ../blender/windowmanager + ../kernel/gen_messaging + ../kernel/gen_system + ../../extern/glew/include ) IF(WITH_QUICKTIME) - ADD_DEFINITIONS(-DWITH_QUICKTIME) + ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) + ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) IF(WITH_PYTHON) - INCLUDE_DIRECTORIES(../blender/python) + INCLUDE_DIRECTORIES(../blender/python) ELSE(WITH_PYTHON) - ADD_DEFINITIONS(-DDISABLE_PYTHON) + ADD_DEFINITIONS(-DDISABLE_PYTHON) ENDIF(WITH_PYTHON) IF(NOT WITH_SDL) - ADD_DEFINITIONS(-DDISABLE_SDL) + ADD_DEFINITIONS(-DDISABLE_SDL) ENDIF(NOT WITH_SDL) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - ADD_DEFINITIONS(-DWITH_BINRELOC) - INCLUDE_DIRECTORIES(${BINRELOC_INC}) + ADD_DEFINITIONS(-DWITH_BINRELOC) + INCLUDE_DIRECTORIES(${BINRELOC_INC}) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") MESSAGE(STATUS "Configuring blender") IF(WIN32) - ADD_EXECUTABLE(blender ${EXETYPE} creator.c ../icons/winblender.rc) + ADD_EXECUTABLE(blender ${EXETYPE} creator.c ../icons/winblender.rc) ELSE(WIN32) - ADD_EXECUTABLE(blender ${EXETYPE} creator.c) + ADD_EXECUTABLE(blender ${EXETYPE} creator.c) ENDIF(WIN32) @@ -86,210 +86,210 @@ SET(TARGETDIR ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}) IF(WITH_INSTALL) - IF(UNIX) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - #COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/plugins ${TARGETDIR}/ - #COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/text/* ${TARGETDIR}/ - ) - ENDIF(UNIX) - - IF(UNIX AND NOT APPLE) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND rm -Rf ${TARGETDIR}/.blender - COMMAND mkdir ${TARGETDIR}/.blender/ - COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.bfont.ttf ${TARGETDIR}/.blender/ - ) + IF(UNIX) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + #COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/plugins ${TARGETDIR}/ + #COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/text/* ${TARGETDIR}/ + ) + ENDIF(UNIX) + + IF(UNIX AND NOT APPLE) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND rm -Rf ${TARGETDIR}/.blender + COMMAND mkdir ${TARGETDIR}/.blender/ + COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.bfont.ttf ${TARGETDIR}/.blender/ + ) - IF(WITH_INTERNATIONAL) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/.blender/ - COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/.blender/ - ) - ENDIF(WITH_INTERNATIONAL) + IF(WITH_INTERNATIONAL) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/.blender/ + COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/.blender/ + ) + ENDIF(WITH_INTERNATIONAL) - IF(WITH_PYTHON) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMENT "copying blender scripts..." - COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/ui ${TARGETDIR}/.blender/ - COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/io ${TARGETDIR}/.blender/ - COMMAND find ${TARGETDIR} -name "*.py?" -prune -exec rm -rf {} "\;" - ) + IF(WITH_PYTHON) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMENT "copying blender scripts..." + COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/ui ${TARGETDIR}/.blender/ + COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/io ${TARGETDIR}/.blender/ + COMMAND find ${TARGETDIR} -name "*.py?" -prune -exec rm -rf {} "\;" + ) - # Copy the systems python into the install directory - # Scons copy in tools/Blender.py - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMENT "copying a subset of the systems python..." + # Copy the systems python into the install directory + # Scons copy in tools/Blender.py + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMENT "copying a subset of the systems python..." - COMMAND mkdir ${TARGETDIR}/.blender/python # PYTHONPATH and PYTHONHOME is set here - COMMAND mkdir ${TARGETDIR}/.blender/python/lib/ - COMMAND cp -R ${PYTHON_LIBPATH}/python${PYTHON_VERSION} ${TARGETDIR}/.blender/python/lib/ + COMMAND mkdir ${TARGETDIR}/.blender/python # PYTHONPATH and PYTHONHOME is set here + COMMAND mkdir ${TARGETDIR}/.blender/python/lib/ + COMMAND cp -R ${PYTHON_LIBPATH}/python${PYTHON_VERSION} ${TARGETDIR}/.blender/python/lib/ - COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/distutils - COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/lib2to3 - COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/idlelib - COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/tkinter - COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/config + COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/distutils + COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/lib2to3 + COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/idlelib + COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/tkinter + COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/config - COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/site-packages - COMMAND mkdir ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/site-packages # python needs it. - - COMMAND rm -f ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/lib-dynload/_tkinter.so - COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "test" -prune -exec rm -rf {} "\;" - COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "*.py?" -exec rm -rf {} "\;" - COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "*.so"-exec strip -s {} "\;" - ) + COMMAND rm -rf ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/site-packages + COMMAND mkdir ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/site-packages # python needs it. + + COMMAND rm -f ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION}/lib-dynload/_tkinter.so + COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "test" -prune -exec rm -rf {} "\;" + COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "*.py?" -exec rm -rf {} "\;" + COMMAND find ${TARGETDIR}/.blender/python/lib/python${PYTHON_VERSION} -name "*.so"-exec strip -s {} "\;" + ) - ENDIF(WITH_PYTHON) + ENDIF(WITH_PYTHON) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;" - ) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;" + ) - ENDIF(UNIX AND NOT APPLE) - - IF(APPLE) - SET(SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app) - SET(SOURCEINFO ${SOURCEDIR}/Contents/Info.plist) - SET(TARGETINFO ${TARGETDIR}/blender.app/Contents/Info.plist) - - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND cp -R ${SOURCEINFO} ${TARGETDIR}/blender.app/Contents/ - COMMAND cp -R ${SOURCEDIR}/Contents/PkgInfo ${TARGETDIR}/blender.app/Contents/ - COMMAND cp -R ${SOURCEDIR}/Contents/Resources ${TARGETDIR}/blender.app/Contents/ - COMMAND cat ${SOURCEINFO} | sed s/VERSION/`cat ${CMAKE_SOURCE_DIR}/release/VERSION`/ | sed s/DATE/`date +'%Y-%b-%d'`/ > ${TARGETINFO} - COMMAND rm -Rf ${TARGETDIR}/blender.app/Contents/MacOS/.blender - COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ - COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.bfont.ttf ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ - ) + ENDIF(UNIX AND NOT APPLE) + + IF(APPLE) + SET(SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app) + SET(SOURCEINFO ${SOURCEDIR}/Contents/Info.plist) + SET(TARGETINFO ${TARGETDIR}/blender.app/Contents/Info.plist) + + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND cp -R ${SOURCEINFO} ${TARGETDIR}/blender.app/Contents/ + COMMAND cp -R ${SOURCEDIR}/Contents/PkgInfo ${TARGETDIR}/blender.app/Contents/ + COMMAND cp -R ${SOURCEDIR}/Contents/Resources ${TARGETDIR}/blender.app/Contents/ + COMMAND cat ${SOURCEINFO} | sed s/VERSION/`cat ${CMAKE_SOURCE_DIR}/release/VERSION`/ | sed s/DATE/`date +'%Y-%b-%d'`/ > ${TARGETINFO} + COMMAND rm -Rf ${TARGETDIR}/blender.app/Contents/MacOS/.blender + COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ + COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.bfont.ttf ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ + ) - IF(WITH_INTERNATIONAL) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ - COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/Resources/ - COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ - COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/blender.app/Contents/Resources/ - ) - ENDIF(WITH_INTERNATIONAL) + IF(WITH_INTERNATIONAL) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ + COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/Resources/ + COMMAND cp -R ${CMAKE_SOURCE_DIR}/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ + COMMAND cp ${CMAKE_SOURCE_DIR}/bin/.blender/.Blanguages ${TARGETDIR}/blender.app/Contents/Resources/ + ) + ENDIF(WITH_INTERNATIONAL) - IF(WITH_PYTHON) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/ui ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ - COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/io ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ - COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ - COMMAND unzip -q ${LIBDIR}/release/python.zip -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ - COMMAND find ${TARGETDIR}/blender.app -name "*.py?" -prune -exec rm -rf {} "\;" - ) - ENDIF(WITH_PYTHON) + IF(WITH_PYTHON) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/ui ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ + COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/io ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ + COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ + COMMAND unzip -q ${LIBDIR}/release/python.zip -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ + COMMAND find ${TARGETDIR}/blender.app -name "*.py?" -prune -exec rm -rf {} "\;" + ) + ENDIF(WITH_PYTHON) - ADD_CUSTOM_COMMAND( - TARGET blender POST_BUILD MAIN_DEPENDENCY blender - COMMAND find ${TARGETDIR}/blender.app -name .DS_Store -prune -exec rm -rf {} "\;" - COMMAND find ${TARGETDIR}/blender.app -name .svn -prune -exec rm -rf {} "\;" - ) - ENDIF(APPLE) - - IF(WIN32) - FILE(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} WIN_SOURCE_DIR) + ADD_CUSTOM_COMMAND( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND find ${TARGETDIR}/blender.app -name .DS_Store -prune -exec rm -rf {} "\;" + COMMAND find ${TARGETDIR}/blender.app -name .svn -prune -exec rm -rf {} "\;" + ) + ENDIF(APPLE) + + IF(WIN32) + FILE(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} WIN_SOURCE_DIR) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND if not exist \"${TARGETDIR}\\.blender\" mkdir \"${TARGETDIR}\\.blender\" - COMMAND if not exist \"${TARGETDIR}\\.blender\\locale\" mkdir \"${TARGETDIR}\\.blender\\locale\" - COMMAND if not exist \"${TARGETDIR}\\.blender\\ui\" mkdir \"${TARGETDIR}\\.blender\\ui\" - COMMAND if not exist \"${TARGETDIR}\\.blender\\io\" mkdir \"${TARGETDIR}\\.blender\\io\" - COMMAND if not exist \"${TARGETDIR}\\plugins\" mkdir \"${TARGETDIR}\\plugins\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\.Blanguages\" \"${TARGETDIR}\\.blender\\\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\.bfont.ttf\" \"${TARGETDIR}\\.blender\\\" - COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\locale\\*.*\" \"${TARGETDIR}\\.blender\\locale\" - COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\scripts\\*.*\" \"${TARGETDIR}\\.blender\\scripts\" - COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\ui\\*.*\" \"${TARGETDIR}\\.blender\\ui\" - COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\io\\*.*\" \"${TARGETDIR}\\.blender\\io\" - COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python26.zip\" \"${TARGETDIR}\\\" - ) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND if not exist \"${TARGETDIR}\\.blender\" mkdir \"${TARGETDIR}\\.blender\" + COMMAND if not exist \"${TARGETDIR}\\.blender\\locale\" mkdir \"${TARGETDIR}\\.blender\\locale\" + COMMAND if not exist \"${TARGETDIR}\\.blender\\ui\" mkdir \"${TARGETDIR}\\.blender\\ui\" + COMMAND if not exist \"${TARGETDIR}\\.blender\\io\" mkdir \"${TARGETDIR}\\.blender\\io\" + COMMAND if not exist \"${TARGETDIR}\\plugins\" mkdir \"${TARGETDIR}\\plugins\" + COMMAND copy /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\.Blanguages\" \"${TARGETDIR}\\.blender\\\" + COMMAND copy /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\.bfont.ttf\" \"${TARGETDIR}\\.blender\\\" + COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\bin\\.blender\\locale\\*.*\" \"${TARGETDIR}\\.blender\\locale\" + COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\scripts\\*.*\" \"${TARGETDIR}\\.blender\\scripts\" + COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\ui\\*.*\" \"${TARGETDIR}\\.blender\\ui\" + COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\io\\*.*\" \"${TARGETDIR}\\.blender\\io\" + COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\" + COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\" + COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python26.zip\" \"${TARGETDIR}\\\" + ) - FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR) + FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\release\\python31.zip\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\gettext\\lib\\gnu_gettext.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\png\\lib\\libpng.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\sdl\\lib\\SDL.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\zlib\\lib\\zlib.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\tiff\\lib\\libtiff.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python31.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python31_d.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\pthreads\\lib\\pthreadVC2.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\samplerate\\lib\\libsamplerate-0.dll\" \"${TARGETDIR}\\\" - ) - - IF(WITH_INTERNATIONAL) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\iconv\\lib\\iconv.dll\" \"${TARGETDIR}\\\" - ) - ENDIF(WITH_INTERNATIONAL) - - IF(WITH_FFMPEG) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avcodec-52.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avformat-52.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avdevice-52.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avutil-50.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaac-0.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaad-2.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libmp3lame-0.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libx264-67.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\swscale-0.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\xvidcore.dll\" \"${TARGETDIR}\\\" - ) - ENDIF(WITH_FFMPEG) - - IF(WITH_SNDFILE) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\sndfile\\lib\\libsndfile-1.dll\" \"${TARGETDIR}\\\" - ) - ENDIF(WITH_SNDFILE) - - IF(WITH_JACK) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\jack\\lib\\libjack.dll\" \"${TARGETDIR}\\\" - ) - ENDIF(WITH_JACK) - - IF(WITH_OPENAL) - ADD_CUSTOM_COMMAND(TARGET blender - POST_BUILD - MAIN_DEPENDENCY blender - COMMAND copy /Y \"${WIN_LIBDIR}\\openal\\lib\\OpenAL32.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\openal\\lib\\wrap_oal.dll\" \"${TARGETDIR}\\\" - - ) - ENDIF(WITH_OPENAL) - - - ENDIF(WIN32) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND copy /Y \"${WIN_LIBDIR}\\release\\python31.zip\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\gettext\\lib\\gnu_gettext.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\png\\lib\\libpng.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\sdl\\lib\\SDL.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\zlib\\lib\\zlib.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\tiff\\lib\\libtiff.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python31.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python31_d.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\pthreads\\lib\\pthreadVC2.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\samplerate\\lib\\libsamplerate-0.dll\" \"${TARGETDIR}\\\" + ) + + IF(WITH_INTERNATIONAL) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND copy /Y \"${WIN_LIBDIR}\\iconv\\lib\\iconv.dll\" \"${TARGETDIR}\\\" + ) + ENDIF(WITH_INTERNATIONAL) + + IF(WITH_FFMPEG) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avcodec-52.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avformat-52.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avdevice-52.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\avutil-50.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaac-0.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libfaad-2.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libmp3lame-0.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\libx264-67.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\swscale-0.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\ffmpeg\\lib\\xvidcore.dll\" \"${TARGETDIR}\\\" + ) + ENDIF(WITH_FFMPEG) + + IF(WITH_SNDFILE) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND copy /Y \"${WIN_LIBDIR}\\sndfile\\lib\\libsndfile-1.dll\" \"${TARGETDIR}\\\" + ) + ENDIF(WITH_SNDFILE) + + IF(WITH_JACK) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND copy /Y \"${WIN_LIBDIR}\\jack\\lib\\libjack.dll\" \"${TARGETDIR}\\\" + ) + ENDIF(WITH_JACK) + + IF(WITH_OPENAL) + ADD_CUSTOM_COMMAND(TARGET blender + POST_BUILD + MAIN_DEPENDENCY blender + COMMAND copy /Y \"${WIN_LIBDIR}\\openal\\lib\\OpenAL32.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\openal\\lib\\wrap_oal.dll\" \"${TARGETDIR}\\\" + + ) + ENDIF(WITH_OPENAL) + + + ENDIF(WIN32) ENDIF(WITH_INSTALL) ADD_DEPENDENCIES(blender makesdna) @@ -299,108 +299,108 @@ FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS) SET(BLENDER_LINK_LIBS bf_nodes ${BLENDER_LINK_LIBS} bf_windowmanager bf_editors blender_render) IF(WITH_ELBEEM) - SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} bf_elbeem) + SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} bf_elbeem) ENDIF(WITH_ELBEEM) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc) + SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF(UNIX) - # Sort libraries - SET(BLENDER_SORTED_LIBS - bf_windowmanager - bf_editors - bf_decimation - blender_BSP - bf_ghost - bf_string - blender_render - blender_ONL - bf_python - bf_gen_python - bf_blenkernel - bf_nodes - bf_gpu - bf_blenloader - bf_blenpluginapi - bf_imbuf - bf_blenlib - bf_avi - bf_cineon - bf_openexr - bf_dds - bf_readblenfile - blender_bop - bf_kernel - bf_decimation - bf_elbeem - bf_IK - bf_memutil - bf_guardedalloc - blender_CTR - bf_moto - bf_windowmanager - bf_editors - bf_blroutines - bf_converter - bf_dummy - bf_bullet - bf_smoke - bf_minilzo - bf_lzma - bf_common - bf_ketsji - bf_logic - bf_rasterizer - bf_oglrasterizer - bf_expressions - bf_scenegraph - bf_moto - bf_blroutines - kx_network - bf_kernel - bf_ngnetwork - extern_bullet - bf_loopbacknetwork - bf_common - bf_moto - bf_python - bf_gen_python - extern_binreloc - extern_glew - extern_libopenjpeg - bf_videotex - bf_rna - bf_dna - bf_blenfont - bf_audaspace - ) - - IF(WITH_CXX_GUARDEDALLOC) - SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_guardedalloc_cpp) - ENDIF(WITH_CXX_GUARDEDALLOC) - - IF(WITH_QUICKTIME) - SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_quicktime) - ENDIF(WITH_QUICKTIME) - - - FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) - SET(REMLIB ${SORTLIB}) - FOREACH(SEARCHLIB ${BLENDER_LINK_LIBS}) - IF(${SEARCHLIB} STREQUAL ${SORTLIB}) - SET(REMLIB "") - ENDIF(${SEARCHLIB} STREQUAL ${SORTLIB}) - ENDFOREACH(SEARCHLIB) - IF(REMLIB) - MESSAGE(STATUS "Removing library ${REMLIB} from blender linking because: not configured") - LIST(REMOVE_ITEM BLENDER_SORTED_LIBS ${REMLIB}) - ENDIF(REMLIB) - ENDFOREACH(SORTLIB) - TARGET_LINK_LIBRARIES(blender ${BLENDER_SORTED_LIBS}) + # Sort libraries + SET(BLENDER_SORTED_LIBS + bf_windowmanager + bf_editors + bf_decimation + blender_BSP + bf_ghost + bf_string + blender_render + blender_ONL + bf_python + bf_gen_python + bf_blenkernel + bf_nodes + bf_gpu + bf_blenloader + bf_blenpluginapi + bf_imbuf + bf_blenlib + bf_avi + bf_cineon + bf_openexr + bf_dds + bf_readblenfile + blender_bop + bf_kernel + bf_decimation + bf_elbeem + bf_IK + bf_memutil + bf_guardedalloc + blender_CTR + bf_moto + bf_windowmanager + bf_editors + bf_blroutines + bf_converter + bf_dummy + bf_bullet + bf_smoke + bf_minilzo + bf_lzma + bf_common + bf_ketsji + bf_logic + bf_rasterizer + bf_oglrasterizer + bf_expressions + bf_scenegraph + bf_moto + bf_blroutines + kx_network + bf_kernel + bf_ngnetwork + extern_bullet + bf_loopbacknetwork + bf_common + bf_moto + bf_python + bf_gen_python + extern_binreloc + extern_glew + extern_libopenjpeg + bf_videotex + bf_rna + bf_dna + bf_blenfont + bf_audaspace + ) + + IF(WITH_CXX_GUARDEDALLOC) + SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_guardedalloc_cpp) + ENDIF(WITH_CXX_GUARDEDALLOC) + + IF(WITH_QUICKTIME) + SET(BLENDER_SORTED_LIBS ${BLENDER_SORTED_LIBS} bf_quicktime) + ENDIF(WITH_QUICKTIME) + + + FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) + SET(REMLIB ${SORTLIB}) + FOREACH(SEARCHLIB ${BLENDER_LINK_LIBS}) + IF(${SEARCHLIB} STREQUAL ${SORTLIB}) + SET(REMLIB "") + ENDIF(${SEARCHLIB} STREQUAL ${SORTLIB}) + ENDFOREACH(SEARCHLIB) + IF(REMLIB) + MESSAGE(STATUS "Removing library ${REMLIB} from blender linking because: not configured") + LIST(REMOVE_ITEM BLENDER_SORTED_LIBS ${REMLIB}) + ENDIF(REMLIB) + ENDFOREACH(SORTLIB) + TARGET_LINK_LIBRARIES(blender ${BLENDER_SORTED_LIBS}) ELSE(UNIX) - TARGET_LINK_LIBRARIES(blender ${BLENDER_LINK_LIBS}) + TARGET_LINK_LIBRARIES(blender ${BLENDER_LINK_LIBS}) ENDIF(UNIX) SETUP_LIBLINKS(blender) diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 42e270d0fe7..ee15fd99ed5 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -2,43 +2,43 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../intern/string - ../../../intern/guardedalloc - ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../source/gameengine/Converter - ../../../source/blender/imbuf - ../../../intern/ghost/include - ../../../intern/moto/include - ../../../source/gameengine/Ketsji - ../../../source/blender/blenlib - ../../../source/blender/blenkernel - ../../../source/blender/blenfont - ../../../source/blender/editors/include - ../../../source/blender/windowmanager - ../../../source/blender - ../../../source/blender/include - ../../../source/blender/makesdna - ../../../source/blender/makesrna - ../../../source/gameengine/Rasterizer - ../../../source/gameengine/GameLogic - ../../../source/gameengine/Expressions - ../../../source/gameengine/Network - ../../../source/gameengine/SceneGraph - ../../../source/gameengine/Physics/common - ../../../source/gameengine/Physics/Bullet - ../../../source/gameengine/Network/LoopBackNetwork - ../../../source/blender/misc - ../../../source/blender/blenloader - ../../../source/blender/gpu - ../../../extern/bullet2/src - ../../../extern/glew/include - ${PYTHON_INC} + . + ../../../source/kernel/gen_system + ../../../intern/string + ../../../intern/guardedalloc + ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../source/gameengine/Converter + ../../../source/blender/imbuf + ../../../intern/ghost/include + ../../../intern/moto/include + ../../../source/gameengine/Ketsji + ../../../source/blender/blenlib + ../../../source/blender/blenkernel + ../../../source/blender/blenfont + ../../../source/blender/editors/include + ../../../source/blender/windowmanager + ../../../source/blender + ../../../source/blender/include + ../../../source/blender/makesdna + ../../../source/blender/makesrna + ../../../source/gameengine/Rasterizer + ../../../source/gameengine/GameLogic + ../../../source/gameengine/Expressions + ../../../source/gameengine/Network + ../../../source/gameengine/SceneGraph + ../../../source/gameengine/Physics/common + ../../../source/gameengine/Physics/Bullet + ../../../source/gameengine/Network/LoopBackNetwork + ../../../source/blender/misc + ../../../source/blender/blenloader + ../../../source/blender/gpu + ../../../extern/bullet2/src + ../../../extern/glew/include + ${PYTHON_INC} ) IF(WITH_FFMPEG) - ADD_DEFINITIONS(-DWITH_FFMPEG) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) BLENDERLIB(bf_blroutines "${SRC}" "${INC}") diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt index f546a31fb2e..5a1887bd6c3 100644 --- a/source/gameengine/CMakeLists.txt +++ b/source/gameengine/CMakeLists.txt @@ -41,5 +41,5 @@ ADD_SUBDIRECTORY(Physics/Bullet) ADD_SUBDIRECTORY(VideoTexture) IF(WITH_PLAYER) - ADD_SUBDIRECTORY(GamePlayer) + ADD_SUBDIRECTORY(GamePlayer) ENDIF(WITH_PLAYER) diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index f16e9e169ab..257ca856b2c 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -27,40 +27,40 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../intern/string - ../../../intern/guardedalloc - ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../intern/audaspace/intern - ../../../source/gameengine/Converter - ../../../source/gameengine/BlenderRoutines - ../../../source/blender/imbuf - ../../../intern/moto/include - ../../../source/gameengine/Ketsji - ../../../source/gameengine/Ketsji/KXNetwork - ../../../source/blender/blenlib - ../../../source/blender/blenkernel - ../../../source/blender/windowmanager - ../../../source/blender - ../../../source/blender/include - ../../../source/blender/makesdna - ../../../source/blender/makesrna - ../../../source/gameengine/Rasterizer - ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../source/gameengine/GameLogic - ../../../source/gameengine/Expressions - ../../../source/gameengine/Network - ../../../source/gameengine/SceneGraph - ../../../source/gameengine/Physics/common - ../../../source/gameengine/Physics/Bullet - ../../../source/gameengine/Physics/Dummy - ../../../source/gameengine/Network/LoopBackNetwork - ../../../source/blender/misc - ../../../source/blender/blenloader - ../../../source/blender/gpu - ../../../extern/bullet2/src - ${PYTHON_INC} + . + ../../../source/kernel/gen_system + ../../../intern/string + ../../../intern/guardedalloc + ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../intern/audaspace/intern + ../../../source/gameengine/Converter + ../../../source/gameengine/BlenderRoutines + ../../../source/blender/imbuf + ../../../intern/moto/include + ../../../source/gameengine/Ketsji + ../../../source/gameengine/Ketsji/KXNetwork + ../../../source/blender/blenlib + ../../../source/blender/blenkernel + ../../../source/blender/windowmanager + ../../../source/blender + ../../../source/blender/include + ../../../source/blender/makesdna + ../../../source/blender/makesrna + ../../../source/gameengine/Rasterizer + ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../source/gameengine/GameLogic + ../../../source/gameengine/Expressions + ../../../source/gameengine/Network + ../../../source/gameengine/SceneGraph + ../../../source/gameengine/Physics/common + ../../../source/gameengine/Physics/Bullet + ../../../source/gameengine/Physics/Dummy + ../../../source/gameengine/Network/LoopBackNetwork + ../../../source/blender/misc + ../../../source/blender/blenloader + ../../../source/blender/gpu + ../../../extern/bullet2/src + ${PYTHON_INC} ) BLENDERLIB(bf_converter "${SRC}" "${INC}") diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index dffd13f64ff..439a50852a7 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -27,13 +27,13 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../intern/string - ../../../intern/moto/include - ../../../source/gameengine/SceneGraph - ../../../source/blender/blenloader - ${PYTHON_INC} + . + ../../../source/kernel/gen_system + ../../../intern/string + ../../../intern/moto/include + ../../../source/gameengine/SceneGraph + ../../../source/blender/blenloader + ${PYTHON_INC} ) BLENDERLIB(bf_expressions "${SRC}" "${INC}") diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt index a1dce49e14b..601585f79d6 100644 --- a/source/gameengine/GameLogic/CMakeLists.txt +++ b/source/gameengine/GameLogic/CMakeLists.txt @@ -27,20 +27,20 @@ FILE(GLOB SRC *.cpp Joystick/*.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../intern/string - ../../../source/gameengine/Expressions - ../../../source/gameengine/SceneGraph - ../../../intern/moto/include - ../../../source/gameengine/Rasterizer - ${PYTHON_INC} + . + ../../../source/kernel/gen_system + ../../../intern/string + ../../../source/gameengine/Expressions + ../../../source/gameengine/SceneGraph + ../../../intern/moto/include + ../../../source/gameengine/Rasterizer + ${PYTHON_INC} ) IF(WITH_SDL) - SET(INC ${INC} ${SDL_INCLUDE_DIR}) + SET(INC ${INC} ${SDL_INCLUDE_DIR}) ELSE(WITH_SDL) - ADD_DEFINITIONS(-DDISABLE_SDL) + ADD_DEFINITIONS(-DDISABLE_SDL) ENDIF(WITH_SDL) BLENDERLIB(bf_logic "${SRC}" "${INC}") diff --git a/source/gameengine/GamePlayer/CMakeLists.txt b/source/gameengine/GamePlayer/CMakeLists.txt index 134f8fce3b2..7b4fa4892df 100644 --- a/source/gameengine/GamePlayer/CMakeLists.txt +++ b/source/gameengine/GamePlayer/CMakeLists.txt @@ -28,5 +28,5 @@ ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(ghost) IF(WITH_WEBPLUGIN) - ADD_SUBDIRECTORY(xembed) + ADD_SUBDIRECTORY(xembed) ENDIF(WITH_WEBPLUGIN) diff --git a/source/gameengine/GamePlayer/common/CMakeLists.txt b/source/gameengine/GamePlayer/common/CMakeLists.txt index da99087c917..c865cf5ce25 100644 --- a/source/gameengine/GamePlayer/common/CMakeLists.txt +++ b/source/gameengine/GamePlayer/common/CMakeLists.txt @@ -25,50 +25,50 @@ # ***** END GPL LICENSE BLOCK ***** SET(SRC - bmfont.cpp - GPC_Canvas.cpp - GPC_Engine.cpp - GPC_KeyboardDevice.cpp - GPC_MouseDevice.cpp - GPC_RawImage.cpp - GPC_RawLoadDotBlendArray.cpp - GPC_RawLogoArrays.cpp - GPC_RenderTools.cpp - GPC_System.cpp + bmfont.cpp + GPC_Canvas.cpp + GPC_Engine.cpp + GPC_KeyboardDevice.cpp + GPC_MouseDevice.cpp + GPC_RawImage.cpp + GPC_RawLoadDotBlendArray.cpp + GPC_RawLogoArrays.cpp + GPC_RenderTools.cpp + GPC_System.cpp ) SET(INC - . - ../../../../intern/string - ../../../../intern/ghost - ../../../../intern/guardedalloc - ../../../../intern/moto/include - ../../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../../source/kernel/gen_system - ../../../../source/kernel/gen_messaging - ../../../../source/gameengine/Converter - ../../../../source/blender/imbuf - ../../../../source/gameengine/Ketsji - ../../../../source/blender/blenlib - ../../../../source/blender/blenkernel - ../../../../source/blender - ../../../../source/blender/include - ../../../../source/blender/makesdna - ../../../../source/gameengine/Rasterizer - ../../../../source/gameengine/GameLogic - ../../../../source/gameengine/Expressions - ../../../../source/gameengine/Network - ../../../../source/gameengine/SceneGraph - ../../../../source/gameengine/Physics/common - ../../../../source/gameengine/Network/LoopBackNetwork - ../../../../source/gameengine/GamePlayer/ghost - ../../../../source/blender/misc - ../../../../source/blender/blenloader - ../../../../source/blender/gpu - ../../../../extern/glew/include - ${PYTHON_INC} - ${PNG_INC} - ${ZLIB_INC} + . + ../../../../intern/string + ../../../../intern/ghost + ../../../../intern/guardedalloc + ../../../../intern/moto/include + ../../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../../source/kernel/gen_system + ../../../../source/kernel/gen_messaging + ../../../../source/gameengine/Converter + ../../../../source/blender/imbuf + ../../../../source/gameengine/Ketsji + ../../../../source/blender/blenlib + ../../../../source/blender/blenkernel + ../../../../source/blender + ../../../../source/blender/include + ../../../../source/blender/makesdna + ../../../../source/gameengine/Rasterizer + ../../../../source/gameengine/GameLogic + ../../../../source/gameengine/Expressions + ../../../../source/gameengine/Network + ../../../../source/gameengine/SceneGraph + ../../../../source/gameengine/Physics/common + ../../../../source/gameengine/Network/LoopBackNetwork + ../../../../source/gameengine/GamePlayer/ghost + ../../../../source/blender/misc + ../../../../source/blender/blenloader + ../../../../source/blender/gpu + ../../../../extern/glew/include + ${PYTHON_INC} + ${PNG_INC} + ${ZLIB_INC} ) BLENDERLIB_NOLIST(gp_common "${SRC}" "${INC}") diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt index 377d765af85..d50784cb967 100644 --- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt +++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt @@ -25,49 +25,49 @@ # ***** END GPL LICENSE BLOCK ***** SET(SRC - GPG_Application.cpp - GPG_Canvas.cpp - GPG_ghost.cpp - GPG_KeyboardDevice.cpp - GPG_System.cpp + GPG_Application.cpp + GPG_Canvas.cpp + GPG_ghost.cpp + GPG_KeyboardDevice.cpp + GPG_System.cpp ) SET(INC - . - ../../../../intern/string - ../../../../intern/ghost - ../../../../intern/guardedalloc - ../../../../intern/moto/include - ../../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../../source/kernel/gen_system - ../../../../source/kernel/gen_messaging - ../../../../source/gameengine/Converter - ../../../../source/blender/imbuf - ../../../../source/gameengine/Ketsji - ../../../../source/blender/blenlib - ../../../../source/blender/blenkernel - ../../../../source/blender/readblenfile - ../../../../source/blender - ../../../../source/blender/include - ../../../../source/blender/makesdna - ../../../../source/blender/makesrna - ../../../../source/gameengine/Rasterizer - ../../../../source/gameengine/GameLogic - ../../../../source/gameengine/Expressions - ../../../../source/gameengine/Network - ../../../../source/gameengine/SceneGraph - ../../../../source/gameengine/Physics/common - ../../../../source/gameengine/Network/LoopBackNetwork - ../../../../source/gameengine/GamePlayer/common - ../../../../source/blender/misc - ../../../../source/blender/blenloader - ../../../../source/blender/gpu - ../../../../extern/glew/include - ${PYTHON_INC} + . + ../../../../intern/string + ../../../../intern/ghost + ../../../../intern/guardedalloc + ../../../../intern/moto/include + ../../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../../source/kernel/gen_system + ../../../../source/kernel/gen_messaging + ../../../../source/gameengine/Converter + ../../../../source/blender/imbuf + ../../../../source/gameengine/Ketsji + ../../../../source/blender/blenlib + ../../../../source/blender/blenkernel + ../../../../source/blender/readblenfile + ../../../../source/blender + ../../../../source/blender/include + ../../../../source/blender/makesdna + ../../../../source/blender/makesrna + ../../../../source/gameengine/Rasterizer + ../../../../source/gameengine/GameLogic + ../../../../source/gameengine/Expressions + ../../../../source/gameengine/Network + ../../../../source/gameengine/SceneGraph + ../../../../source/gameengine/Physics/common + ../../../../source/gameengine/Network/LoopBackNetwork + ../../../../source/gameengine/GamePlayer/common + ../../../../source/blender/misc + ../../../../source/blender/blenloader + ../../../../source/blender/gpu + ../../../../extern/glew/include + ${PYTHON_INC} ) IF(WITH_FFMPEG) - ADD_DEFINITIONS(-DWITH_FFMPEG) + ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) BLENDERLIB_NOLIST(gp_ghost "${SRC}" "${INC}") diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index c91a3771b45..01d369bc7a9 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -27,45 +27,45 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../intern/string - ../../../intern/guardedalloc - ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../source/gameengine/Converter - ../../../source/blender/imbuf - ../../../intern/ghost/include - ../../../intern/moto/include - ../../../source/gameengine/Ketsji - ../../../source/blender/blenlib - ../../../source/blender/blenkernel - ../../../source/blender/python - ../../../source/blender/python/generic - ../../../source/blender - ../../../source/blender/include - ../../../source/blender/makesdna - ../../../source/gameengine/Rasterizer - ../../../source/gameengine/GameLogic - ../../../source/gameengine/Expressions - ../../../source/gameengine/Ketsji/KXNetwork - ../../../source/gameengine/Network - ../../../source/gameengine/SceneGraph - ../../../source/gameengine/Physics/common - ../../../source/gameengine/Physics/Bullet - ../../../source/gameengine/Network/LoopBackNetwork - ../../../intern/audaspace/intern - ../../../source/blender/misc - ../../../source/blender/blenloader - ../../../source/blender/gpu - ../../../extern/bullet2/src - ../../../extern/glew/include - ${PYTHON_INC} + . + ../../../source/kernel/gen_system + ../../../intern/string + ../../../intern/guardedalloc + ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../source/gameengine/Converter + ../../../source/blender/imbuf + ../../../intern/ghost/include + ../../../intern/moto/include + ../../../source/gameengine/Ketsji + ../../../source/blender/blenlib + ../../../source/blender/blenkernel + ../../../source/blender/python + ../../../source/blender/python/generic + ../../../source/blender + ../../../source/blender/include + ../../../source/blender/makesdna + ../../../source/gameengine/Rasterizer + ../../../source/gameengine/GameLogic + ../../../source/gameengine/Expressions + ../../../source/gameengine/Ketsji/KXNetwork + ../../../source/gameengine/Network + ../../../source/gameengine/SceneGraph + ../../../source/gameengine/Physics/common + ../../../source/gameengine/Physics/Bullet + ../../../source/gameengine/Network/LoopBackNetwork + ../../../intern/audaspace/intern + ../../../source/blender/misc + ../../../source/blender/blenloader + ../../../source/blender/gpu + ../../../extern/bullet2/src + ../../../extern/glew/include + ${PYTHON_INC} ) IF(WITH_SDL) - SET(INC ${INC} ${SDL_INCLUDE_DIR}) + SET(INC ${INC} ${SDL_INCLUDE_DIR}) ELSE(WITH_SDL) - ADD_DEFINITIONS(-DDISABLE_SDL) + ADD_DEFINITIONS(-DDISABLE_SDL) ENDIF(WITH_SDL) BLENDERLIB(bf_ketsji "${SRC}" "${INC}") diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt index d9a9fc54f4b..b89b0dcff9f 100644 --- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt +++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt @@ -27,16 +27,16 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../../source/kernel/gen_system - ../../../../intern/string - ../../../../intern/moto/include - ../../../../source/gameengine/Ketsji - ../../../../source/gameengine/GameLogic - ../../../../source/gameengine/Expressions - ../../../../source/gameengine/SceneGraph - ../../../../source/gameengine/Network - ${PYTHON_INC} + . + ../../../../source/kernel/gen_system + ../../../../intern/string + ../../../../intern/moto/include + ../../../../source/gameengine/Ketsji + ../../../../source/gameengine/GameLogic + ../../../../source/gameengine/Expressions + ../../../../source/gameengine/SceneGraph + ../../../../source/gameengine/Network + ${PYTHON_INC} ) BLENDERLIB(kx_network "${SRC}" "${INC}") diff --git a/source/gameengine/Network/CMakeLists.txt b/source/gameengine/Network/CMakeLists.txt index 933f0550d0b..1e467a7d08d 100644 --- a/source/gameengine/Network/CMakeLists.txt +++ b/source/gameengine/Network/CMakeLists.txt @@ -27,10 +27,10 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../intern/string - ../../../intern/moto/include + . + ../../../source/kernel/gen_system + ../../../intern/string + ../../../intern/moto/include ) BLENDERLIB(bf_ngnetwork "${SRC}" "${INC}") diff --git a/source/gameengine/Network/LoopBackNetwork/CMakeLists.txt b/source/gameengine/Network/LoopBackNetwork/CMakeLists.txt index 0b958920dc5..18e3d8ef496 100644 --- a/source/gameengine/Network/LoopBackNetwork/CMakeLists.txt +++ b/source/gameengine/Network/LoopBackNetwork/CMakeLists.txt @@ -27,10 +27,10 @@ SET(SRC NG_LoopBackNetworkDeviceInterface.cpp) SET(INC - . - ../../../../source/kernel/gen_system - ../../../../intern/string - ../../../../source/gameengine/Network + . + ../../../../source/kernel/gen_system + ../../../../intern/string + ../../../../source/gameengine/Network ) BLENDERLIB(bf_loopbacknetwork "${SRC}" "${INC}") diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt index 7b7fb508ebd..da885122a4f 100644 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ b/source/gameengine/Physics/Bullet/CMakeLists.txt @@ -27,23 +27,23 @@ SET(SRC CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp) SET(INC - . - ../common - ../../../../extern/bullet2/src - ../../../../extern/glew/include - ../../../../intern/moto/include - ../../../../intern/guardedalloc - ../../../kernel/gen_system - ../../../../intern/string - ../../Rasterizer - ../../Ketsji - ../../Expressions - ../../GameLogic - ../../SceneGraph - ../../../../source/blender/makesdna - ../../../../source/blender/blenlib - ../../../../source/blender/blenkernel - ${PYTHON_INC} + . + ../common + ../../../../extern/bullet2/src + ../../../../extern/glew/include + ../../../../intern/moto/include + ../../../../intern/guardedalloc + ../../../kernel/gen_system + ../../../../intern/string + ../../Rasterizer + ../../Ketsji + ../../Expressions + ../../GameLogic + ../../SceneGraph + ../../../../source/blender/makesdna + ../../../../source/blender/blenlib + ../../../../source/blender/blenkernel + ${PYTHON_INC} ) BLENDERLIB(bf_bullet "${SRC}" "${INC}") diff --git a/source/gameengine/Physics/Dummy/CMakeLists.txt b/source/gameengine/Physics/Dummy/CMakeLists.txt index 4bd29e7779b..d613bf8fd14 100644 --- a/source/gameengine/Physics/Dummy/CMakeLists.txt +++ b/source/gameengine/Physics/Dummy/CMakeLists.txt @@ -27,8 +27,8 @@ SET(SRC DummyPhysicsEnvironment.cpp) SET(INC - . - ../common + . + ../common ) BLENDERLIB(bf_dummy "${SRC}" "${INC}") diff --git a/source/gameengine/Physics/common/CMakeLists.txt b/source/gameengine/Physics/common/CMakeLists.txt index 41b2687fe38..a34bd19d400 100644 --- a/source/gameengine/Physics/common/CMakeLists.txt +++ b/source/gameengine/Physics/common/CMakeLists.txt @@ -27,9 +27,9 @@ SET(SRC PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp PHY_IGraphicController.cpp PHY_IPhysicsEnvironment.cpp PHY_IVehicle.cpp) SET(INC - . - ../Dummy - ../../../intern/moto/include + . + ../Dummy + ../../../intern/moto/include ) BLENDERLIB(bf_common "${SRC}" "${INC}") diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index 143209f5a54..51d1f5001dd 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -27,15 +27,15 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/kernel/gen_system - ../../../source/blender/makesdna - ../../../source/gameengine/SceneGraph - ../../../intern/string - ../../../intern/moto/include - ../../../extern/glew/include - ../Expressions - ${PYTHON_INC} + . + ../../../source/kernel/gen_system + ../../../source/blender/makesdna + ../../../source/gameengine/SceneGraph + ../../../intern/string + ../../../intern/moto/include + ../../../extern/glew/include + ../Expressions + ${PYTHON_INC} ) BLENDERLIB(bf_rasterizer "${SRC}" "${INC}") diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index fe3d0f6aeea..f2b97bedb2f 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -27,18 +27,18 @@ FILE(GLOB SRC *.cpp) SET(INC - ../../../../source/kernel/gen_system - ../../../../intern/string - ../../../../intern/moto/include - ../../../../source/gameengine/Rasterizer - ../../../../source/gameengine/Ketsji - ../../../../source/gameengine/SceneGraph - ../../../../extern/glew/include - ../../../../source/blender/gpu - ../../../../source/blender/makesdna - ../../../../source/blender/blenkernel - ../../../../source/blender/blenlib - ../../../../source/blender/blenloader + ../../../../source/kernel/gen_system + ../../../../intern/string + ../../../../intern/moto/include + ../../../../source/gameengine/Rasterizer + ../../../../source/gameengine/Ketsji + ../../../../source/gameengine/SceneGraph + ../../../../extern/glew/include + ../../../../source/blender/gpu + ../../../../source/blender/makesdna + ../../../../source/blender/blenkernel + ../../../../source/blender/blenlib + ../../../../source/blender/blenloader ) BLENDERLIB(bf_oglrasterizer "${SRC}" "${INC}") diff --git a/source/gameengine/SceneGraph/CMakeLists.txt b/source/gameengine/SceneGraph/CMakeLists.txt index 0409b8c0ac4..2ac52be938e 100644 --- a/source/gameengine/SceneGraph/CMakeLists.txt +++ b/source/gameengine/SceneGraph/CMakeLists.txt @@ -27,8 +27,8 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../intern/moto/include + . + ../../../intern/moto/include ) BLENDERLIB(bf_scenegraph "${SRC}" "${INC}") diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt index 255d0907101..935c5a2c292 100644 --- a/source/gameengine/VideoTexture/CMakeLists.txt +++ b/source/gameengine/VideoTexture/CMakeLists.txt @@ -27,34 +27,34 @@ FILE(GLOB SRC *.cpp) SET(INC - . - ../../../source/gameengine/Ketsji - ../../../source/gameengine/Expressions - ../../../source/gameengine/GameLogic - ../../../source/gameengine/SceneGraph - ../../../source/gameengine/Rasterizer - ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer - ../../../source/gameengine/BlenderRoutines - ../../../source/blender/include - ../../../source/blender/blenlib - ../../../source/blender/blenkernel - ../../../source/blender/makesdna - ../../../source/blender/editors/include - ../../../source/blender/imbuf - ../../../source/blender/python - ../../../source/blender/gpu - ../../../source/kernel/gen_system - ../../../intern/string - ../../../intern/moto/include - ../../../intern/guardedalloc - ../../../extern/glew/include - ${PYTHON_INC} + . + ../../../source/gameengine/Ketsji + ../../../source/gameengine/Expressions + ../../../source/gameengine/GameLogic + ../../../source/gameengine/SceneGraph + ../../../source/gameengine/Rasterizer + ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer + ../../../source/gameengine/BlenderRoutines + ../../../source/blender/include + ../../../source/blender/blenlib + ../../../source/blender/blenkernel + ../../../source/blender/makesdna + ../../../source/blender/editors/include + ../../../source/blender/imbuf + ../../../source/blender/python + ../../../source/blender/gpu + ../../../source/kernel/gen_system + ../../../intern/string + ../../../intern/moto/include + ../../../intern/guardedalloc + ../../../extern/glew/include + ${PYTHON_INC} ) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC} ${PTHREADS_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) - ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS) + SET(INC ${INC} ${FFMPEG_INC} ${PTHREADS_INC}) + ADD_DEFINITIONS(-DWITH_FFMPEG) + ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS) ENDIF(WITH_FFMPEG) BLENDERLIB(bf_videotex "${SRC}" "${INC}") diff --git a/source/kernel/CMakeLists.txt b/source/kernel/CMakeLists.txt index ac759393326..3aea2b9bcb0 100644 --- a/source/kernel/CMakeLists.txt +++ b/source/kernel/CMakeLists.txt @@ -27,11 +27,11 @@ SET(INC gen_messaging gen_system ../../intern/string ../../intern/moto/include ../../source/blender/blenloader ) FILE(GLOB SRC - gen_messaging/intern/messaging.c - gen_system/GEN_HashedPtr.cpp - gen_system/GEN_Matrix4x4.cpp - gen_system/SYS_SingletonSystem.cpp - gen_system/SYS_System.cpp + gen_messaging/intern/messaging.c + gen_system/GEN_HashedPtr.cpp + gen_system/GEN_Matrix4x4.cpp + gen_system/SYS_SingletonSystem.cpp + gen_system/SYS_System.cpp ) BLENDERLIB(bf_kernel "${SRC}" "${INC}") -- cgit v1.2.3 From 51aa207d200d2cef1cdc7f4e90a6a0f7a4b31c8e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 Sep 2009 07:22:32 +0000 Subject: 2.5 Anim Bugfixes: * Rotation order code should be more correct now. Previously was only shuffling axes, and was also doing some evil things to provided that that it shouldn't have been doing, which was causing some flipping issues. * Built-in keyingsets for 'visual' options should now be more correct. The old code had typos, giving wrong array indices to start from. --- source/blender/blenlib/intern/arithb.c | 55 +++++++++++++++------------ source/blender/editors/animation/keyingsets.c | 14 +++---- source/blender/editors/transform/transform.c | 8 ++-- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 9d67ac50108..7a4aaa1a858 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2835,9 +2835,9 @@ void EulOToQuat(float e[3], short order, float q[4]) double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; double a[3]; - if (R->parity) e[1] = -e[1]; + if (R->parity) e[1] = -e[1]; // xxx watch it! - ti = e[0]/2; tj = e[1]/2; th = e[2]/2; + ti = e[i]/2; tj = e[j]/2; th = e[k]/2; ci = cos(ti); cj = cos(tj); ch = cos(th); si = sin(ti); sj = sin(tj); sh = sin(th); @@ -2874,12 +2874,11 @@ void EulOToMat3(float e[3], short order, float M[3][3]) double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; if (R->parity) { - e[0] = -e[0]; - e[1] = -e[1]; - e[2] = -e[2]; + ti = -e[i]; tj = -e[j]; th = -e[k]; + } + else { + ti = e[i]; tj = e[j]; th = e[k]; } - - ti = e[0]; tj = e[1]; th = e[2]; ci = cos(ti); cj = cos(tj); ch = cos(th); si = sin(ti); sj = sin(tj); sh = sin(th); @@ -2908,17 +2907,17 @@ void Mat3ToEulO(float M[3][3], float e[3], short order) { RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); short i=R->i, j=R->j, k=R->k; - double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]); + double cy = sqrt(M[i][i]*M[i][i] + M[i][j]*M[i][j]); if (cy > 16*FLT_EPSILON) { - e[0] = atan2(M[j][k], M[k][k]); - e[1] = atan2(-M[i][k], cy); - e[2] = atan2(M[i][j], M[i][i]); + e[i] = atan2(M[j][k], M[k][k]); + e[j] = atan2(-M[i][k], cy); + e[k] = atan2(M[i][j], M[i][i]); } else { - e[0] = atan2(-M[k][j], M[j][j]); - e[1] = atan2(-M[i][k], cy); - e[2] = 0; + e[i] = atan2(-M[k][j], M[j][j]); + e[j] = atan2(-M[i][k], cy); + e[k] = 0; } if (R->parity) { @@ -2944,21 +2943,28 @@ static void mat3_to_eulo2(float M[3][3], float *e1, float *e2, short order) { RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); short i=R->i, j=R->j, k=R->k; - double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]); + float m[3][3]; + double cy; + + /* process the matrix first */ + Mat3CpyMat3(m, M); + Mat3Ortho(m); + + cy= sqrt(m[i][i]*m[i][i] + m[i][j]*m[i][j]); if (cy > 16*FLT_EPSILON) { - e1[0] = atan2(M[j][k], M[k][k]); - e1[1] = atan2(-M[i][k], cy); - e1[2] = atan2(M[i][j], M[i][i]); + e1[i] = atan2(m[j][k], m[k][k]); + e1[j] = atan2(-m[i][k], cy); + e1[k] = atan2(m[i][j], m[i][i]); - e2[0] = atan2(-M[j][k], -M[k][k]); - e2[1] = atan2(-M[i][k], -cy); - e2[2] = atan2(-M[i][j], -M[i][i]); + e2[i] = atan2(-m[j][k], -m[k][k]); + e2[j] = atan2(-m[i][k], -cy); + e2[k] = atan2(-m[i][j], -m[i][i]); } else { - e1[0] = atan2(-M[k][j], M[j][j]); - e1[1] = atan2(-M[i][k], cy); - e1[2] = 0; + e1[i] = atan2(-m[k][j], m[j][j]); + e1[j] = atan2(-m[i][k], cy); + e1[k] = 0; VecCopyf(e2, e1); } @@ -2975,7 +2981,6 @@ static void mat3_to_eulo2(float M[3][3], float *e1, float *e2, short order) } /* uses 2 methods to retrieve eulers, and picks the closest */ -// FIXME: this does not work well with the other rotation modes... void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order) { float eul1[3], eul2[3]; diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 15d47211615..2639d49b5be 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -801,24 +801,24 @@ static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] = /* Keying Sets with Keying Flags ************************* */ /* Keying Set - "VisualLoc" ---------- */ - BI_KS_DEFINE_BEGIN("VisualLoc", 0) + BI_KS_DEFINE_BEGIN("VisualLoc", INSERTKEY_MATRIX) BI_KS_PATHS_BEGIN(1) - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", INSERTKEY_MATRIX, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END, /* Keying Set - "Rotation" ---------- */ - BI_KS_DEFINE_BEGIN("VisualRot", 0) + BI_KS_DEFINE_BEGIN("VisualRot", INSERTKEY_MATRIX) BI_KS_PATHS_BEGIN(1) - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", INSERTKEY_MATRIX, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END, /* Keying Set - "VisualLocRot" ---------- */ - BI_KS_DEFINE_BEGIN("VisualLocRot", 0) + BI_KS_DEFINE_BEGIN("VisualLocRot", INSERTKEY_MATRIX) BI_KS_PATHS_BEGIN(2) - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", INSERTKEY_MATRIX, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), - BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", INSERTKEY_MATRIX, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), + BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_PCHAN_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) BI_KS_PATHS_END BI_KS_DEFINE_END }; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 370e98ebd07..1f568be3e10 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1738,12 +1738,12 @@ static void constraintRotLim(TransInfo *t, TransData *td) eul[1]= tdi->roty[0]; eul[2]= tdi->rotz[0]; - EulToMat4(eul, cob.matrix); + EulOToMat4(eul, td->rotOrder, cob.matrix); } else { /* eulers */ if (td->ext) - EulToMat4(td->ext->rot, cob.matrix); + EulOToMat4(td->ext->rot, td->rotOrder, cob.matrix); else return; } @@ -1796,7 +1796,7 @@ static void constraintRotLim(TransInfo *t, TransData *td) TransDataIpokey *tdi= td->tdi; float eul[3]; - Mat4ToEul(cob.matrix, eul); + Mat4ToEulO(cob.matrix, eul, td->rotOrder); tdi->rotx[0]= eul[0]; tdi->roty[0]= eul[1]; @@ -1804,7 +1804,7 @@ static void constraintRotLim(TransInfo *t, TransData *td) } else { /* eulers */ - Mat4ToEul(cob.matrix, td->ext->rot); + Mat4ToEulO(cob.matrix, td->ext->rot, td->rotOrder); } } } -- cgit v1.2.3 From fb649d5824ccccca544c905209ba64340dc1bded Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sun, 6 Sep 2009 13:20:05 +0000 Subject: * cleaning up warnings (mostly windows). A collection of other warning fixes too (undefined function, assuming int, etc.) This compiled fine with scons/msvc and scons/mingw (gcc 4.4.0). Please test and report any problems. --- intern/iksolver/intern/TNT/tntmath.h | 4 ++- intern/smoke/intern/tnt/tnt_math_utils.h | 4 ++- intern/string/STR_String.h | 4 +++ source/blender/blenkernel/intern/image.c | 5 ++++ source/blender/blenkernel/intern/packedFile.c | 8 +++++ source/blender/blenkernel/intern/pointcache.c | 16 ++-------- source/blender/blenkernel/intern/sound.c | 2 +- source/blender/blenlib/BLI_fileops.h | 2 -- source/blender/blenlib/BLI_winstuff.h | 31 +++++++++----------- source/blender/blenlib/intern/bpath.c | 34 ++++++++++++---------- source/blender/blenlib/intern/fileops.c | 14 +++++---- source/blender/blenlib/intern/storage.c | 15 +++++----- source/blender/blenloader/intern/readblenentry.c | 9 ++++-- source/blender/blenloader/intern/readfile.c | 7 ++--- source/blender/blenloader/intern/writefile.c | 14 ++++----- .../editors/armature/editarmature_generate.c | 1 + source/blender/editors/interface/interface_icons.c | 1 + source/blender/editors/mesh/meshtools.c | 1 + source/blender/editors/space_buttons/buttons_ops.c | 1 + source/blender/imbuf/intern/anim5.c | 6 ++++ source/blender/imbuf/intern/hamx.c | 10 +++---- source/blender/imbuf/intern/iff.c | 7 +++-- source/blender/imbuf/intern/thumbs.c | 20 ++++++------- source/blender/imbuf/intern/writeimage.c | 8 ++--- source/blender/python/intern/bpy_interface.c | 11 +++---- .../blender/readblenfile/intern/BLO_readblenfile.c | 1 + source/blender/windowmanager/intern/wm_files.c | 2 +- .../gameengine/Converter/KX_ConvertProperties.cpp | 10 +++---- source/gameengine/Ketsji/KX_PythonInit.cpp | 14 ++++----- source/gameengine/VideoTexture/SConscript | 1 - 30 files changed, 142 insertions(+), 121 deletions(-) diff --git a/intern/iksolver/intern/TNT/tntmath.h b/intern/iksolver/intern/TNT/tntmath.h index 5773900caf9..55a79e2aba0 100644 --- a/intern/iksolver/intern/TNT/tntmath.h +++ b/intern/iksolver/intern/TNT/tntmath.h @@ -35,7 +35,9 @@ // conventional functions required by several matrix algorithms - +#ifdef _WIN32 +#define hypot _hypot +#endif namespace TNT { diff --git a/intern/smoke/intern/tnt/tnt_math_utils.h b/intern/smoke/intern/tnt/tnt_math_utils.h index 6e14a1d9b90..f6aad8eaf38 100644 --- a/intern/smoke/intern/tnt/tnt_math_utils.h +++ b/intern/smoke/intern/tnt/tnt_math_utils.h @@ -4,7 +4,9 @@ /* needed for fabs, sqrt() below */ #include - +#ifdef _WIN32 +#define hypot _hypot +#endif namespace TNT { diff --git a/intern/string/STR_String.h b/intern/string/STR_String.h index a5e7a0721ec..d8023a06f81 100644 --- a/intern/string/STR_String.h +++ b/intern/string/STR_String.h @@ -54,6 +54,10 @@ using namespace std; #include "MEM_guardedalloc.h" #endif +#ifdef _WIN32 +#define stricmp _stricmp +#endif + class STR_String; typedef unsigned long dword; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index eb8872c43a5..cdb175ed661 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -38,6 +38,11 @@ #include +#ifdef _WIN32 +#define open _open +#define close _close +#endif + #include "MEM_guardedalloc.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 3e47c1006e5..bd0b1a5e36e 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -63,6 +63,14 @@ #include "BKE_packedFile.h" #include "BKE_report.h" +#ifdef _WIN32 +#define open _open +#define close _close +#define read _read +#define write _write +#endif + + int seekPackedFile(PackedFile *pf, int offset, int whence) { int oldseek = -1, seek = 0; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 3e429749953..912acc4786f 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -67,23 +67,13 @@ /* needed for directory lookup */ +/* untitled blend's need getpid for a unique name */ #ifndef WIN32 #include +#include #else - #include "BLI_winstuff.h" -#endif - -/* untitled blend's need getpid for a unique name */ -#ifdef WIN32 #include -#else -#include -#endif - -#ifdef _WIN32 -#ifndef snprintf -#define snprintf _snprintf -#endif + #include "BLI_winstuff.h" #endif static void ptcache_data_to(void **data, int type, int index, void *to); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 06ef8a23142..2d5d8dad7a8 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -250,12 +250,12 @@ void sound_free(struct bSound* sound) void sound_unlink(struct bContext *C, struct bSound* sound) { - bSound *snd; Scene *scene; SoundHandle *handle; // XXX unused currently #if 0 + bSound *snd; for(snd = CTX_data_main(C)->sound.first; snd; snd = snd->id.next) { if(snd->child_sound == sound) diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index d2dd40b21a5..0c1cdbc4d3a 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -36,8 +36,6 @@ #ifndef BLI_FILEOPS_H #define BLI_FILEOPS_H - - void BLI_recurdir_fileops(char *dirname); int BLI_link(char *file, char *to); int BLI_is_writable(char *filename); diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index fad45f1b6c3..b46ebebacd5 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -65,24 +65,7 @@ extern "C" { #endif -# ifndef _WIN64 - #ifndef M_PI - #define M_PI 3.14159265358979323846 - #endif - #ifndef M_PI_2 - #define M_PI_2 1.57079632679489661923 - #endif - #ifndef M_SQRT2 - #define M_SQRT2 1.41421356237309504880 - #endif - #ifndef M_SQRT1_2 - #define M_SQRT1_2 0.70710678118654752440 - #endif - #ifndef M_1_PI - #define M_1_PI 0.318309886183790671538 - #endif -#endif - +#define _USE_MATH_DEFINES #define MAXPATHLEN MAX_PATH #ifndef S_ISREG @@ -92,6 +75,18 @@ extern "C" { #define S_ISDIR(x) ((x&S_IFMT) == S_IFDIR) #endif +/* defines for using ISO C++ conformant names */ +#define open _open +#define close _close +#define write _write +#define read _read +#define getcwd _getcwd +#define chdir _chdir +#define strdup _strdup +#define lseek _lseek +#define getpid _getpid +#define snprintf _snprintf + #ifndef FREE_WINDOWS typedef unsigned int mode_t; #endif diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 6c89afe7173..cadf8d2bdd1 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -26,6 +26,24 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include +#include + +#include +#include +#include +#include +#include + +/* path/file handeling stuff */ +#ifndef WIN32 + #include + #include +#else + #include + #include "BLI_winstuff.h" +#endif + #include "MEM_guardedalloc.h" #include "DNA_ID.h" /* Library */ @@ -53,23 +71,7 @@ //XXX define below from BSE_sequence.h - otherwise potentially odd behaviour #define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_IMAGE) -/* path/file handeling stuff */ -#ifndef WIN32 - #include - #include -#else - #include "BLI_winstuff.h" - #include -#endif -#include -#include - -#include -#include -#include -#include -#include #define FILE_MAX 240 diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 0228032df01..e7dc9b0eb1f 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -31,27 +31,29 @@ #include #include +#include +#include +#include + +#include + #include "zlib.h" #ifdef WIN32 -#include "BLI_winstuff.h" #include +#include "BLI_winstuff.h" #else #include // for read close #include #endif + #include "BLI_blenlib.h" #include "BLI_storage.h" #include "BLI_fileops.h" #include "BLI_callbacks.h" -#include -#include -#include - #include "BKE_utildefines.h" -#include #include "BLO_sys_types.h" // for intptr_t support diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 7cbef85b938..cdc5cec705f 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -33,13 +33,6 @@ #include #include -#ifdef WIN32 -#include "BLI_winstuff.h" -#include -#include -#include -#endif - #ifndef WIN32 #include #endif @@ -82,6 +75,14 @@ #include #endif +#ifdef WIN32 +#include +#include +#include +#include "BLI_winstuff.h" +#endif + + /* lib includes */ #include "MEM_guardedalloc.h" diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 33641a0b004..1c21c1817e6 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -32,13 +32,14 @@ #include #endif -#include "BLI_storage.h" /* _LARGEFILE_SOURCE */ - #include #include #include #include + +#include "BLI_storage.h" /* _LARGEFILE_SOURCE */ + #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" @@ -67,6 +68,10 @@ #include "BLO_sys_types.h" // needed for intptr_t +#ifdef _WIN32 +#include "BLI_winstuff.h" +#endif + /** * IDType stuff, I plan to move this * out into its own file + prefix, and diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6a26a71ee3d..0c4835a79b7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -29,11 +29,6 @@ #include "zlib.h" -#ifdef WIN32 -#include "winsock2.h" -#include "BLI_winstuff.h" -#endif - #include #include // for printf fopen fwrite fclose sprintf FILE #include // for getenv atoi @@ -46,6 +41,8 @@ #include // for MAXPATHLEN #else #include // for open close read +#include "winsock2.h" +#include "BLI_winstuff.h" #endif #include "DNA_anim_types.h" diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index c4a94660932..a22e4f66c8d 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -72,23 +72,23 @@ Any case: direct data is ALWAYS after the lib block #include #endif +#include +#include +#include +#include +#include + #include "zlib.h" #ifndef WIN32 #include #else #include "winsock2.h" -#include "BLI_winstuff.h" #include #include // for getpid +#include "BLI_winstuff.h" #endif -#include -#include -#include -#include -#include - #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c index 6c0eab16af0..d327ed34839 100644 --- a/source/blender/editors/armature/editarmature_generate.c +++ b/source/blender/editors/armature/editarmature_generate.c @@ -30,6 +30,7 @@ #include #include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 549164c23a1..6c4110c8c37 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -34,6 +34,7 @@ #else #include #include +#include "BLI_winstuff.h" #endif #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 2ef1d3b214d..4aa99820a6e 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 60480a9f165..1567f393d87 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -74,6 +74,7 @@ #include "ED_curve.h" #include "ED_mesh.h" +#include "ED_particle.h" #include "RNA_access.h" #include "RNA_define.h" diff --git a/source/blender/imbuf/intern/anim5.c b/source/blender/imbuf/intern/anim5.c index b6f29b6a145..4fe4217cd2c 100644 --- a/source/blender/imbuf/intern/anim5.c +++ b/source/blender/imbuf/intern/anim5.c @@ -31,6 +31,7 @@ #include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail BLI_countlist BLI_stringdec */ + #include "imbuf.h" #include "imbuf_patch.h" @@ -46,6 +47,11 @@ #include "IMB_anim5.h" +#ifdef _WIN32 +#include +#include "BLI_winstuff.h" +#endif + typedef struct Anhd{ unsigned char type, mask; unsigned short w, h; diff --git a/source/blender/imbuf/intern/hamx.c b/source/blender/imbuf/intern/hamx.c index 2f32d155407..258c196fcdf 100644 --- a/source/blender/imbuf/intern/hamx.c +++ b/source/blender/imbuf/intern/hamx.c @@ -31,11 +31,6 @@ #include "BLI_blenlib.h" -#ifdef WIN32 -#include -#endif - - #include "imbuf.h" #include "imbuf_patch.h" #include "IMB_imbuf_types.h" @@ -46,6 +41,11 @@ #include "IMB_ham.h" #include "IMB_hamx.h" +#ifdef WIN32 +#include +#include "BLI_winstuff.h" +#endif + /* actually hard coded endianness */ #define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) #define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0]) diff --git a/source/blender/imbuf/intern/iff.c b/source/blender/imbuf/intern/iff.c index c3695173068..5fd823e78c1 100644 --- a/source/blender/imbuf/intern/iff.c +++ b/source/blender/imbuf/intern/iff.c @@ -29,14 +29,15 @@ * $Id$ */ -#ifdef WIN32 -#include -#endif #include "BLI_blenlib.h" #include "imbuf.h" #include "imbuf_patch.h" #include "IMB_imbuf_types.h" #include "IMB_iff.h" +#ifdef WIN32 +#include +#include "BLI_winstuff.h" +#endif unsigned short imb_start_iff(struct ImBuf *ibuf, int file) { diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 86ca43824f3..6053c5556f1 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -39,31 +39,29 @@ #include "IMB_thumbs.h" #include "IMB_imginfo.h" - #include "md5.h" +#include +#include +#include +#include +#include +#include +#include + #ifdef WIN32 #include /* need to include windows.h so _WIN32_IE is defined */ #ifndef _WIN32_IE #define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */ #endif #include /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */ -#include "BLI_winstuff.h" #include /* getpid */ #include /* chdir */ +#include "BLI_winstuff.h" #else #include #endif -#include -#include -#include -#include -#include -#include -#include -#include - #define URI_MAX FILE_MAX*3 + 8 static int get_thumb_dir( char* dir , ThumbSize size) diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c index 7e1120bf3e4..b3af727190a 100644 --- a/source/blender/imbuf/intern/writeimage.c +++ b/source/blender/imbuf/intern/writeimage.c @@ -29,10 +29,6 @@ * $Id$ */ -#ifdef WIN32 -#include -#endif - #include #include "BKE_global.h" @@ -71,6 +67,10 @@ #include "IMB_bitplanes.h" #include "IMB_divers.h" +#ifdef WIN32 +#include +#include "BLI_winstuff.h" +#endif /* added facility to copy with saving non-float rects */ short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index a935b517f77..a85bcd011a6 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -28,11 +28,6 @@ #include #include -#ifndef WIN32 -#include -#else -#include "BLI_winstuff.h" -#endif /* grr, python redefines */ #ifdef _POSIX_C_SOURCE @@ -48,6 +43,12 @@ #include "bpy_ui.h" #include "bpy_util.h" +#ifndef WIN32 +#include +#else +#include "BLI_winstuff.h" +#endif + #include "DNA_anim_types.h" #include "DNA_space_types.h" #include "DNA_text_types.h" diff --git a/source/blender/readblenfile/intern/BLO_readblenfile.c b/source/blender/readblenfile/intern/BLO_readblenfile.c index 40a991ad702..5672b9f4cb2 100644 --- a/source/blender/readblenfile/intern/BLO_readblenfile.c +++ b/source/blender/readblenfile/intern/BLO_readblenfile.c @@ -43,6 +43,7 @@ #ifdef WIN32 #include // read, open +#include "BLI_winstuff.h" #else // ! WIN32 #include // read #endif diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 3921da4f062..a6e38a61e0f 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -37,8 +37,8 @@ #define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */ #endif #include /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */ -#include "BLI_winstuff.h" #include /* getpid */ +#include "BLI_winstuff.h" #else #include /* getpid */ #endif diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp index 5e8d6f3cbf0..1c22d2a0600 100644 --- a/source/gameengine/Converter/KX_ConvertProperties.cpp +++ b/source/gameengine/Converter/KX_ConvertProperties.cpp @@ -32,26 +32,26 @@ #include #endif -/* This little block needed for linking to Blender... */ -#ifdef WIN32 -#include "BLI_winstuff.h" -#endif #include "DNA_object_types.h" #include "DNA_property_types.h" /* end of blender include block */ + #include "Value.h" #include "VectorValue.h" #include "BoolValue.h" #include "StringValue.h" #include "FloatValue.h" #include "KX_GameObject.h" -//#include "ListValue.h" #include "IntValue.h" #include "SCA_TimeEventManager.h" #include "SCA_IScene.h" +/* This little block needed for linking to Blender... */ +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer) { diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 9e81bcb3871..298d485aaaf 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -32,11 +32,6 @@ // directory header for py function getBlendFileList #include -#ifndef WIN32 - #include -#else - #include "BLI_winstuff.h" -#endif #ifdef WIN32 #pragma warning (disable : 4786) @@ -80,8 +75,6 @@ extern "C" { #include "InputParser.h" #include "KX_Scene.h" -#include "NG_NetworkScene.h" //Needed for sendMessage() - #include "BL_Shader.h" #include "KX_PyMath.h" @@ -111,6 +104,13 @@ extern "C" { #include "BLI_blenlib.h" #include "GPU_material.h" +#ifndef WIN32 + #include +#else + #include "BLI_winstuff.h" +#endif +#include "NG_NetworkScene.h" //Needed for sendMessage() + static void setSandbox(TPythonSecurityLevel level); // 'local' copy of canvas ptr, for window height/width python scripts diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 0d3e495f3e2..119bd1c9954 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -25,6 +25,5 @@ incs += ' ' + env['BF_PYTHON_INC'] if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC'] - defs.append('__STDC_CONSTANT_MACROS') env.BlenderLib ( 'bf_videotex', sources, Split(incs), defs, libtype=['core','player'], priority=[300,205], cxx_compileflags=env['BGE_CXXFLAGS']) -- cgit v1.2.3 From 3d64d65ad9c43f82bd4b9241b4a7fdde0fd12000 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sun, 6 Sep 2009 14:32:02 +0000 Subject: * clean out some warnings (unrefenced vars mainly) --- intern/audaspace/FX/AUD_DoubleReader.cpp | 2 +- intern/audaspace/FX/AUD_PingPongFactory.cpp | 2 +- intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 14 +++++----- intern/audaspace/SDL/AUD_SDLMixerReader.cpp | 2 +- intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp | 8 +++--- intern/audaspace/intern/AUD_C-API.cpp | 42 ++++++++++++++-------------- intern/audaspace/jack/AUD_JackDevice.cpp | 8 +++--- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index 181e394da98..8d3afbf2f1d 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -47,7 +47,7 @@ AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1, AUD_THROW(AUD_ERROR_READER); } - catch(AUD_Exception e) + catch(AUD_Exception) { if(reader1) { diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp index a030d581b1a..8b72afe05e7 100644 --- a/intern/audaspace/FX/AUD_PingPongFactory.cpp +++ b/intern/audaspace/FX/AUD_PingPongFactory.cpp @@ -46,7 +46,7 @@ AUD_IReader* AUD_PingPongFactory::createReader() { reader2 = factory.createReader(); } - catch(AUD_Exception e) + catch(AUD_Exception) { reader2 = 0; } diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index f94b11a11b8..b33afa2b955 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -544,13 +544,13 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) if(alGetError() != AL_NO_ERROR) AUD_THROW(AUD_ERROR_OPENAL); } - catch(AUD_Exception e) + catch(AUD_Exception) { alDeleteSources(1, &sound->source); throw; } } - catch(AUD_Exception e) + catch(AUD_Exception) { delete sound; AUD_DELETE("handle") alcProcessContext(m_context); @@ -648,19 +648,19 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) if(alGetError() != AL_NO_ERROR) AUD_THROW(AUD_ERROR_OPENAL); } - catch(AUD_Exception e) + catch(AUD_Exception) { alDeleteSources(1, &sound->source); throw; } } - catch(AUD_Exception e) + catch(AUD_Exception) { alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); throw; } } - catch(AUD_Exception e) + catch(AUD_Exception) { delete sound; AUD_DELETE("handle") delete reader; AUD_DELETE("reader") @@ -1051,13 +1051,13 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value) if(alGetError() != AL_NO_ERROR) AUD_THROW(AUD_ERROR_OPENAL); } - catch(AUD_Exception e) + catch(AUD_Exception) { alDeleteBuffers(1, &bf->buffer); throw; } } - catch(AUD_Exception e) + catch(AUD_Exception) { delete bf; AUD_DELETE("bufferedfactory") delete reader; AUD_DELETE("reader") diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp index ec61f99f02d..0a47e36533a 100644 --- a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp +++ b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp @@ -87,7 +87,7 @@ AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader, specs.rate) == -1) AUD_THROW(AUD_ERROR_SDL); } - catch(AUD_Exception e) + catch(AUD_Exception) { delete m_reader; AUD_DELETE("reader") throw; diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp index d70a9c25bcb..0384ba5e0e6 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp @@ -119,7 +119,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename) // find audio stream and codec m_stream = -1; - for(int i = 0; i < m_formatCtx->nb_streams; i++) + for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++) if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) && (m_stream < 0)) { @@ -146,7 +146,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename) m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt); m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate; } - catch(AUD_Exception e) + catch(AUD_Exception) { av_close_input_file(m_formatCtx); throw; @@ -188,7 +188,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference buffer) // find audio stream and codec m_stream = -1; - for(int i = 0; i < m_formatCtx->nb_streams; i++) + for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++) if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) && (m_stream < 0)) { @@ -215,7 +215,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference buffer) m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt); m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate; } - catch(AUD_Exception e) + catch(AUD_Exception) { av_close_input_stream(m_formatCtx); av_free(m_byteiocontext); AUD_DELETE("byteiocontext") diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 995d4c5f99e..7a624aa53fd 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -116,7 +116,7 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize) return true; } - catch(AUD_Exception e) + catch(AUD_Exception) { return false; } @@ -204,7 +204,7 @@ AUD_Sound* AUD_bufferSound(AUD_Sound* sound) { return new AUD_StreamBufferFactory(sound); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -218,7 +218,7 @@ AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay) { return new AUD_DelayFactory(sound, delay); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -232,7 +232,7 @@ extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end) { return new AUD_LimiterFactory(sound, start, end); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -246,7 +246,7 @@ AUD_Sound* AUD_pingpongSound(AUD_Sound* sound) { return new AUD_PingPongFactory(sound); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -260,7 +260,7 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound) { return new AUD_LoopFactory(sound); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -278,7 +278,7 @@ int AUD_stopLoop(AUD_Handle* handle) { return AUD_device->sendMessage(handle, message); } - catch(AUD_Exception e) + catch(AUD_Exception) { } } @@ -299,7 +299,7 @@ AUD_Handle* AUD_play(AUD_Sound* sound, int keep) { return AUD_device->play(sound, keep); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -360,7 +360,7 @@ AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep) else return AUD_device->play(sound, keep); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -376,7 +376,7 @@ int AUD_updateListener(AUD_3DData* data) if(AUD_3ddevice) return AUD_3ddevice->updateListener(*data); } - catch(AUD_Exception e) + catch(AUD_Exception) { } return false; @@ -391,7 +391,7 @@ int AUD_set3DSetting(AUD_3DSetting setting, float value) if(AUD_3ddevice) return AUD_3ddevice->setSetting(setting, value); } - catch(AUD_Exception e) + catch(AUD_Exception) { } return false; @@ -406,7 +406,7 @@ float AUD_get3DSetting(AUD_3DSetting setting) if(AUD_3ddevice) return AUD_3ddevice->getSetting(setting); } - catch(AUD_Exception e) + catch(AUD_Exception) { } return 0.0; @@ -424,7 +424,7 @@ int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data) if(AUD_3ddevice) return AUD_3ddevice->updateSource(handle, *data); } - catch(AUD_Exception e) + catch(AUD_Exception) { } } @@ -443,7 +443,7 @@ int AUD_set3DSourceSetting(AUD_Handle* handle, if(AUD_3ddevice) return AUD_3ddevice->setSourceSetting(handle, setting, value); } - catch(AUD_Exception e) + catch(AUD_Exception) { } } @@ -461,7 +461,7 @@ float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting) if(AUD_3ddevice) return AUD_3ddevice->getSourceSetting(handle, setting); } - catch(AUD_Exception e) + catch(AUD_Exception) { } } @@ -481,7 +481,7 @@ int AUD_setSoundVolume(AUD_Handle* handle, float volume) { return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps); } - catch(AUD_Exception e) {} + catch(AUD_Exception) {} } return false; } @@ -499,7 +499,7 @@ int AUD_setSoundPitch(AUD_Handle* handle, float pitch) { return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps); } - catch(AUD_Exception e) {} + catch(AUD_Exception) {} } return false; } @@ -510,7 +510,7 @@ AUD_Device* AUD_openReadDevice(AUD_Specs specs) { return new AUD_ReadDevice(specs); } - catch(AUD_Exception e) + catch(AUD_Exception) { return NULL; } @@ -525,7 +525,7 @@ int AUD_playDevice(AUD_Device* device, AUD_Sound* sound) { return device->play(sound) != NULL; } - catch(AUD_Exception e) + catch(AUD_Exception) { return false; } @@ -540,7 +540,7 @@ int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length) { return device->read(buffer, length); } - catch(AUD_Exception e) + catch(AUD_Exception) { return false; } @@ -554,7 +554,7 @@ void AUD_closeReadDevice(AUD_Device* device) { delete device; } - catch(AUD_Exception e) + catch(AUD_Exception) { } } diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp index 445e68e1a9a..4d8ab93d672 100644 --- a/intern/audaspace/jack/AUD_JackDevice.cpp +++ b/intern/audaspace/jack/AUD_JackDevice.cpp @@ -35,7 +35,7 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data) { AUD_JackDevice* device = (AUD_JackDevice*)data; - int samplesize = AUD_SAMPLE_SIZE(device->m_specs); + unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs); if(device->m_buffer->getSize() < samplesize * length) device->m_buffer->resize(samplesize * length); device->mix(device->m_buffer->getBuffer(), length); @@ -44,10 +44,10 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data) float* out; int count = device->m_specs.channels; - for(int i = 0; i < count; i++) + for(unsigned int i = 0; i < count; i++) { out = (float*)jack_port_get_buffer(device->m_ports[i], length); - for(int j = 0; j < length; j++) + for(unsigned int j = 0; j < length; j++) out[j] = in[j * count + i]; } @@ -105,7 +105,7 @@ AUD_JackDevice::AUD_JackDevice(AUD_Specs specs) if(jack_activate(m_client)) AUD_THROW(AUD_ERROR_JACK); } - catch(AUD_Exception e) + catch(AUD_Exception) { jack_client_close(m_client); delete[] m_ports; AUD_DELETE("jack_port") -- cgit v1.2.3 From 62138aaa5a7f931fa2ddb4815f755413111cceb0 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sun, 6 Sep 2009 15:13:57 +0000 Subject: Python part of multidim. array support for RNA complete. Multidim. arrays can now be modified at any level, for example: struc.arrayprop = x struc.arrayprop[i] = x struc.arrayprop[i][j] = x struc.arrayprop[i][j][k] = x etc... Approriate rvalue type/length checking is done. To ensure all works correctly, I wrote automated tests in release/test/rna_array.py. These tests cover: array/item access, assignment on different levels, tests that proper exceptions are thrown on invalid item access/assignment. The tests use properties of the RNA Test struct defined in rna_test.c. This struct is only compiled when building with BF_UNIT_TEST=1 scons arg. Currently unit tests are run manually by loading the script in the Text Editor. Here's the output I have: http://www.pasteall.org/7644 Things to improve here: - better exception messages when multidim. array assignment fails. Those we have currently are not very useful for multidim. - add tests for slice assignment --- release/test/rna_array.py | 279 +++++++++++++++ source/blender/blenloader/intern/readblenentry.c | 5 +- source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/SConscript | 3 + source/blender/makesrna/intern/SConscript | 3 + source/blender/makesrna/intern/makesrna.c | 1 + source/blender/makesrna/intern/rna_access.c | 33 +- source/blender/makesrna/intern/rna_define.c | 2 + source/blender/makesrna/intern/rna_internal.h | 1 + .../blender/makesrna/intern/rna_internal_types.h | 8 +- source/blender/makesrna/intern/rna_main.c | 24 ++ source/blender/makesrna/intern/rna_mesh.c | 2 +- source/blender/makesrna/intern/rna_test.c | 188 ++++++++++ source/blender/python/intern/bpy_array.c | 383 ++++++++++++++++++--- source/blender/python/intern/bpy_rna.c | 296 ++++++++-------- source/blender/python/intern/bpy_rna.h | 13 +- tools/btools.py | 6 +- 17 files changed, 1038 insertions(+), 210 deletions(-) create mode 100644 release/test/rna_array.py create mode 100644 source/blender/makesrna/intern/rna_test.c diff --git a/release/test/rna_array.py b/release/test/rna_array.py new file mode 100644 index 00000000000..9b7c65ff017 --- /dev/null +++ b/release/test/rna_array.py @@ -0,0 +1,279 @@ +import unittest +import random + +test= bpy.data.test + +# farr - 1-dimensional array of float +# fdarr - dynamic 1-dimensional array of float +# fmarr - 3-dimensional ([3][4][5]) array of float +# fdmarr - dynamic 3-dimensional (ditto size) array of float + +# same as above for other types except that the first letter is "i" for int and "b" for bool + +class TestArray(unittest.TestCase): + # test that assignment works by: assign -> test value + # - rvalue = list of float + # - rvalue = list of numbers + # test.object + # bpy.data.test.farr[3], iarr[3], barr[...], fmarr, imarr, bmarr + + def setUp(self): + test.farr= (1.0, 2.0, 3.0) + test.iarr= (7, 8, 9) + test.barr= (False, True, False) + + # test access + # test slice access, negative indices + def test_access(self): + rvals= ([1.0, 2.0, 3.0], [7, 8, 9], [False, True, False]) + for arr, rval in zip((test.farr, test.iarr, test.barr), rvals): + self.assertEqual(prop_to_list(arr), rval) + self.assertEqual(arr[0:3], rval) + self.assertEqual(arr[1:2], rval[1:2]) + self.assertEqual(arr[-1], arr[2]) + self.assertEqual(arr[-2], arr[1]) + self.assertEqual(arr[-3], arr[0]) + + # fail when index out of bounds + def test_access_fail(self): + for arr in (test.farr, test.iarr, test.barr): + self.assertRaises(IndexError, lambda : arr[4]) + + # test assignment of a whole array + def test_assign_array(self): + # should accept int as float + test.farr= (1, 2, 3) + + # fail when: unexpected no. of items, invalid item type + def test_assign_array_fail(self): + def assign_empty_list(arr): + setattr(test, arr, ()) + + for arr in ("farr", "iarr", "barr"): + self.assertRaises(ValueError, assign_empty_list, arr) + + def assign_invalid_float(): + test.farr= (1.0, 2.0, "3.0") + + def assign_invalid_int(): + test.iarr= ("1", 2, 3) + + def assign_invalid_bool(): + test.barr= (True, 0.123, False) + + for func in [assign_invalid_float, assign_invalid_int, assign_invalid_bool]: + self.assertRaises(TypeError, func) + + # shouldn't accept float as int + def assign_float_as_int(): + test.iarr= (1, 2, 3.0) + self.assertRaises(TypeError, assign_float_as_int) + + # non-dynamic arrays cannot change size + def assign_different_size(arr, val): + setattr(test, arr, val) + for arr, val in zip(("iarr", "farr", "barr"), ((1, 2), (1.0, 2.0), (True, False))): + self.assertRaises(ValueError, assign_different_size, arr, val) + + # test assignment of specific items + def test_assign_item(self): + for arr, rand_func in zip((test.farr, test.iarr, test.barr), (rand_float, rand_int, rand_bool)): + for i in range(len(arr)): + val= rand_func() + arr[i]= val + + self.assertEqual(arr[i], val) + + # float prop should accept also int + for i in range(len(test.farr)): + val= rand_int() + test.farr[i]= val + self.assertEqual(test.farr[i], float(val)) + + # + + def test_assign_item_fail(self): + def assign_bad_index(arr): + arr[4] = 1.0 + + def assign_bad_type(arr): + arr[1]= "123" + + for arr in [test.farr, test.iarr, test.barr]: + self.assertRaises(IndexError, assign_bad_index, arr) + + # not testing bool because bool allows not only (True|False) + for arr in [test.farr, test.iarr]: + self.assertRaises(TypeError, assign_bad_type, arr) + + def test_dynamic_assign_array(self): + # test various lengths here + for arr, rand_func in zip(("fdarr", "idarr", "bdarr"), (rand_float, rand_int, rand_bool)): + for length in range(1, 64): + rval= make_random_array(length, rand_func) + setattr(test, arr, rval) + self.assertEqual(prop_to_list(getattr(test, arr)), rval) + + def test_dynamic_assign_array_fail(self): + # could also test too big length here + + def assign_empty_list(arr): + setattr(test, arr, ()) + + for arr in ("fdarr", "idarr", "bdarr"): + self.assertRaises(ValueError, assign_empty_list, arr) + + +class TestMArray(unittest.TestCase): + def setUp(self): + # reset dynamic array sizes + for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)): + setattr(test, arr, make_random_3d_array((3, 4, 5), func)) + + # test assignment + def test_assign_array(self): + for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)): + # assignment of [3][4][5] + rval= make_random_3d_array((3, 4, 5), func) + setattr(test, arr, rval) + self.assertEqual(prop_to_list(getattr(test, arr)), rval) + + # test assignment of [2][4][5], [1][4][5] should work on dynamic arrays + + def test_assign_array_fail(self): + def assign_empty_array(): + test.fmarr= () + self.assertRaises(ValueError, assign_empty_array) + + def assign_invalid_size(arr, rval): + setattr(test, arr, rval) + + # assignment of 3,4,4 or 3,3,5 should raise ex + for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)): + rval= make_random_3d_array((3, 4, 4), func) + self.assertRaises(ValueError, assign_invalid_size, arr, rval) + + rval= make_random_3d_array((3, 3, 5), func) + self.assertRaises(ValueError, assign_invalid_size, arr, rval) + + rval= make_random_3d_array((3, 3, 3), func) + self.assertRaises(ValueError, assign_invalid_size, arr, rval) + + def test_assign_item(self): + # arr[i] = x + for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2): + rval= make_random_2d_array((4, 5), func) + + for i in range(3): + getattr(test, arr)[i]= rval + self.assertEqual(prop_to_list(getattr(test, arr)[i]), rval) + + # arr[i][j] = x + for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2): + + arr= getattr(test, arr) + rval= make_random_array(5, func) + + for i in range(3): + for j in range(4): + arr[i][j]= rval + self.assertEqual(prop_to_list(arr[i][j]), rval) + + + def test_assign_item_fail(self): + def assign_wrong_size(arr, i, rval): + getattr(test, arr)[i]= rval + + # assign wrong size at level 2 + for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)): + rval1= make_random_2d_array((3, 5), func) + rval2= make_random_2d_array((4, 3), func) + + for i in range(3): + self.assertRaises(ValueError, assign_wrong_size, arr, i, rval1) + self.assertRaises(ValueError, assign_wrong_size, arr, i, rval2) + + def test_dynamic_assign_array(self): + for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)): + # assignment of [3][4][5] + rval= make_random_3d_array((3, 4, 5), func) + setattr(test, arr, rval) + self.assertEqual(prop_to_list(getattr(test, arr)), rval) + + # [2][4][5] + rval= make_random_3d_array((2, 4, 5), func) + setattr(test, arr, rval) + self.assertEqual(prop_to_list(getattr(test, arr)), rval) + + # [1][4][5] + rval= make_random_3d_array((1, 4, 5), func) + setattr(test, arr, rval) + self.assertEqual(prop_to_list(getattr(test, arr)), rval) + + + # test access + def test_access(self): + pass + + # test slice access, negative indices + def test_access_fail(self): + pass + +random.seed() + +def rand_int(): + return random.randint(-1000, 1000) + +def rand_float(): + return float(rand_int()) + +def rand_bool(): + return bool(random.randint(0, 1)) + +def make_random_array(len, rand_func): + arr= [] + for i in range(len): + arr.append(rand_func()) + + return arr + +def make_random_2d_array(dimsize, rand_func): + marr= [] + for i in range(dimsize[0]): + marr.append([]) + + for j in range(dimsize[1]): + marr[-1].append(rand_func()) + + return marr + +def make_random_3d_array(dimsize, rand_func): + marr= [] + for i in range(dimsize[0]): + marr.append([]) + + for j in range(dimsize[1]): + marr[-1].append([]) + + for k in range(dimsize[2]): + marr[-1][-1].append(rand_func()) + + return marr + +def prop_to_list(prop): + ret= [] + + for x in prop: + if type(x) not in (bool, int, float): + ret.append(prop_to_list(x)) + else: + ret.append(x) + + return ret + +def suite(): + return unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(TestArray), unittest.TestLoader().loadTestsFromTestCase(TestMArray)]) + +if __name__ == "__main__": + unittest.TextTestRunner(verbosity=2).run(suite()) + diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 1c21c1817e6..9cd45a268da 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -32,14 +32,13 @@ #include #endif +#include "BLI_storage.h" /* _LARGEFILE_SOURCE */ + #include #include #include #include - -#include "BLI_storage.h" /* _LARGEFILE_SOURCE */ - #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 98205d17ef3..4107c1346e5 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -586,6 +586,7 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop); int RNA_property_flag(PropertyRNA *prop); int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop); +int RNA_property_multidimensional_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension); int RNA_property_dynamic_array_set_length(PointerRNA *ptr, PropertyRNA *prop, int length); char RNA_property_array_item_char(PropertyRNA *prop, int index); unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short dim_size[]); diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index c2790927cef..845abf636e2 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -37,4 +37,7 @@ if env['WITH_BF_LCMS']: if env['WITH_BF_GAMEENGINE']: defs.append('GAMEBLENDER=1') +if env['BF_UNIT_TEST']: + defs.append('UNIT_TEST') + env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core','player'], priority = [165,20] ) diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 9234efa2a5d..569f0547731 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -71,6 +71,9 @@ if env['WITH_BF_OPENAL']: if env['WITH_BF_JACK']: defs.append('WITH_JACK') +if env['BF_UNIT_TEST']: + defs.append('UNIT_TEST') + makesrna_tool.Append(CPPDEFINES=defs) makesrna_tool.Append (CPPPATH = Split(incs)) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index bb7b6cbcd37..907eba4018f 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1991,6 +1991,7 @@ RNAProcessItem PROCESS_ITEMS[]= { {"rna_sequence.c", NULL, RNA_def_sequence}, {"rna_smoke.c", NULL, RNA_def_smoke}, {"rna_space.c", NULL, RNA_def_space}, + {"rna_test.c", NULL, RNA_def_test}, {"rna_text.c", NULL, RNA_def_text}, {"rna_timeline.c", NULL, RNA_def_timeline_marker}, {"rna_sound.c", NULL, RNA_def_sound}, diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index e71dcc2a586..f37fa01480c 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -557,14 +557,24 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop) int RNA_property_dynamic_array_set_length(PointerRNA *ptr, PropertyRNA *prop, int length) { - if (prop->setlength) - return prop->setlength(ptr, length); + /* length 0 is not allowed */ + if (!length) + return 0; + + if (prop->getlength) { + if (prop->setlength) + return prop->setlength(ptr, length); + else + /* length cannot be changed */ + return 0; + } else prop->arraylength= length; /* function parameters only? */ return 1; } +/* used by BPY to make an array from the python object */ unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short dimsize[]) { if (dimsize && prop->arraydimension > 1) { @@ -573,6 +583,25 @@ unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short di return prop->arraydimension; } +/* Return the size of Nth dimension. */ +int RNA_property_multidimensional_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim) +{ + unsigned short i; + int len; + + if (dim == 0) { + len= RNA_property_array_length(ptr, prop); + + for (i= 0; i < prop->arraydimension - 1; i++) + len /= prop->dimsize[i]; + } + else { + len= prop->dimsize[dim - 1]; + } + + return len; +} + char RNA_property_array_item_char(PropertyRNA *prop, int index) { const char *vectoritem= "XYZW"; diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 69e6698bd3b..e415304ab6c 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -1046,6 +1046,8 @@ void RNA_def_property_multidimensional_array(PropertyRNA *prop, int arraylength, prop->arraydimension= dimension; + /* TODO make sure dimsize values are sane */ + if (dimension > 1) memcpy(prop->dimsize, dimsize, sizeof(dimsize[0]) * (dimension - 1)); } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 13cc2ae9017..7de80843f27 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -157,6 +157,7 @@ void RNA_def_sensor(struct BlenderRNA *brna); void RNA_def_sequence(struct BlenderRNA *brna); void RNA_def_smoke(struct BlenderRNA *brna); void RNA_def_space(struct BlenderRNA *brna); +void RNA_def_test(struct BlenderRNA *brna); void RNA_def_text(struct BlenderRNA *brna); void RNA_def_texture(struct BlenderRNA *brna); void RNA_def_timeline_marker(struct BlenderRNA *brna); diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index d706fd5ac19..2bd89dbd3bf 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -39,7 +39,12 @@ struct bContext; struct IDProperty; struct GHash; +#ifdef UNIT_TEST +#define RNA_MAX_ARRAY 64 +#else #define RNA_MAX_ARRAY 32 +#endif + #define RNA_MAX_ARRAY_DIMENSION 3 /* Function Callbacks */ @@ -134,11 +139,10 @@ struct PropertyRNA { PropertySubType subtype; /* if an array this is > 0, specifying the length */ unsigned int arraylength; - /* these, if non-NULL, override arraylength */ + /* if non-NULL, overrides arraylength. Must not return 0? */ PropArrayLengthGetFunc getlength; /* if NULL, length cannot be changed by a user */ PropArrayLengthSetFunc setlength; - /* used only for dynamic arrays for now, default 1 */ unsigned short arraydimension; /* dimension sizes for dimensions greater than 1, first dimension size is not specified */ unsigned short dimsize[RNA_MAX_ARRAY_DIMENSION - 1]; diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 82e460ea57d..344135acaff 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -219,6 +219,18 @@ static void rna_Main_wm_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) rna_iterator_listbase_begin(iter, &bmain->wm, NULL); } +#ifdef UNIT_TEST + +static PointerRNA rna_Test_test_get(PointerRNA *ptr) +{ + PointerRNA ret= *ptr; + ret.type= &RNA_Test; + + return ret; +} + +#endif + #else void RNA_def_main(BlenderRNA *brna) @@ -276,6 +288,18 @@ void RNA_def_main(BlenderRNA *brna) } RNA_api_main(srna); + +#ifdef UNIT_TEST + + RNA_define_verify_sdna(0); + + prop= RNA_def_property(srna, "test", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Test"); + RNA_def_property_pointer_funcs(prop, "rna_Test_test_get", NULL, NULL); + + RNA_define_verify_sdna(1); + +#endif } #endif diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index f7235db49a5..efd0046d827 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1182,7 +1182,7 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV 4", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); - prop= RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ); + prop= RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE); RNA_def_property_multidimensional_array(prop, 4 * 2, 2, uv_dim); RNA_def_property_flag(prop, PROP_DYNAMIC); RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTextureFace_uv_get_length", "rna_MeshTextureFace_uv_set_length"); diff --git a/source/blender/makesrna/intern/rna_test.c b/source/blender/makesrna/intern/rna_test.c new file mode 100644 index 00000000000..bfaf318018a --- /dev/null +++ b/source/blender/makesrna/intern/rna_test.c @@ -0,0 +1,188 @@ +/** + * $Id: rna_test.c $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Arystanbek Dyussenov + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* Defines a structure with properties used for array manipulation tests in BPY. */ + +#include +#include + +#include "RNA_define.h" +#include "RNA_types.h" + +#include "rna_internal.h" + +#define ARRAY_SIZE 3 +#define DYNAMIC_ARRAY_SIZE 64 +#define MARRAY_DIM [3][4][5] +#define MARRAY_TOTDIM 3 +#define MARRAY_DIMSIZE 4, 5 +#define MARRAY_SIZE(type) (sizeof(type MARRAY_DIM) / sizeof(type)) +#define DYNAMIC_MARRAY_DIM [3][4][5] +#define DYNAMIC_MARRAY_SIZE(type) (sizeof(type DYNAMIC_MARRAY_DIM) / sizeof(type)) + +#ifdef RNA_RUNTIME + +#ifdef UNIT_TEST + +#define DEF_VARS(type, prefix) \ + static type prefix ## arr[ARRAY_SIZE]; \ + static type prefix ## darr[DYNAMIC_ARRAY_SIZE]; \ + static int prefix ## darr_len= ARRAY_SIZE; \ + static type prefix ## marr MARRAY_DIM; \ + static type prefix ## dmarr DYNAMIC_MARRAY_DIM; \ + static int prefix ## dmarr_len= sizeof(prefix ## dmarr); + +#define DEF_GET_SET(type, arr) \ + void rna_Test_ ## arr ## _get(PointerRNA *ptr, type *values) \ + { \ + memcpy(values, arr, sizeof(arr)); \ + } \ + \ + void rna_Test_ ## arr ## _set(PointerRNA *ptr, const type *values) \ + { \ + memcpy(arr, values, sizeof(arr)); \ + } + +#define DEF_GET_SET_LEN(arr, max) \ + static int rna_Test_ ## arr ## _get_length(PointerRNA *ptr) \ + { \ + return arr ## _len; \ + } \ + \ + static int rna_Test_ ## arr ## _set_length(PointerRNA *ptr, int length) \ + { \ + if (length > max) \ + return 0; \ + \ + arr ## _len= length; \ + \ + return 1; \ + } \ + +DEF_VARS(float, f) +DEF_VARS(int, i) +DEF_VARS(int, b) + +DEF_GET_SET(float, farr) +DEF_GET_SET(int, iarr) +DEF_GET_SET(int, barr) + +DEF_GET_SET(float, fmarr) +DEF_GET_SET(int, imarr) +DEF_GET_SET(int, bmarr) + +DEF_GET_SET(float, fdarr) +DEF_GET_SET_LEN(fdarr, DYNAMIC_ARRAY_SIZE) +DEF_GET_SET(int, idarr) +DEF_GET_SET_LEN(idarr, DYNAMIC_ARRAY_SIZE) +DEF_GET_SET(int, bdarr) +DEF_GET_SET_LEN(bdarr, DYNAMIC_ARRAY_SIZE) + +DEF_GET_SET(float, fdmarr) +DEF_GET_SET_LEN(fdmarr, DYNAMIC_MARRAY_SIZE(float)) +DEF_GET_SET(int, idmarr) +DEF_GET_SET_LEN(idmarr, DYNAMIC_MARRAY_SIZE(int)) +DEF_GET_SET(int, bdmarr) +DEF_GET_SET_LEN(bdmarr, DYNAMIC_MARRAY_SIZE(int)) + +#endif + +#else + +void RNA_def_test(BlenderRNA *brna) +{ +#ifdef UNIT_TEST + StructRNA *srna; + PropertyRNA *prop; + unsigned short dimsize[]= {MARRAY_DIMSIZE}; + + srna= RNA_def_struct(brna, "Test", NULL); + RNA_def_struct_sdna(srna, "Test"); + + prop= RNA_def_float_array(srna, "farr", ARRAY_SIZE, NULL, 0.0f, 0.0f, "farr", "float array", 0.0f, 0.0f); + RNA_def_property_float_funcs(prop, "rna_Test_farr_get", "rna_Test_farr_set", NULL); + + prop= RNA_def_int_array(srna, "iarr", ARRAY_SIZE, NULL, 0, 0, "iarr", "int array", 0, 0); + RNA_def_property_int_funcs(prop, "rna_Test_iarr_get", "rna_Test_iarr_set", NULL); + + prop= RNA_def_boolean_array(srna, "barr", ARRAY_SIZE, NULL, "barr", "boolean array"); + RNA_def_property_boolean_funcs(prop, "rna_Test_barr_get", "rna_Test_barr_set"); + + /* dynamic arrays */ + + prop= RNA_def_float_array(srna, "fdarr", DYNAMIC_ARRAY_SIZE, NULL, 0.0f, 0.0f, "fdarr", "dynamic float array", 0.0f, 0.0f); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_Test_fdarr_get_length", "rna_Test_fdarr_set_length"); + RNA_def_property_float_funcs(prop, "rna_Test_fdarr_get", "rna_Test_fdarr_set", NULL); + + prop= RNA_def_int_array(srna, "idarr", DYNAMIC_ARRAY_SIZE, NULL, 0, 0, "idarr", "int array", 0, 0); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_Test_idarr_get_length", "rna_Test_idarr_set_length"); + RNA_def_property_int_funcs(prop, "rna_Test_idarr_get", "rna_Test_idarr_set", NULL); + + prop= RNA_def_boolean_array(srna, "bdarr", DYNAMIC_ARRAY_SIZE, NULL, "bdarr", "boolean array"); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_Test_bdarr_get_length", "rna_Test_bdarr_set_length"); + RNA_def_property_boolean_funcs(prop, "rna_Test_bdarr_get", "rna_Test_bdarr_set"); + + /* multidimensional arrays */ + + prop= RNA_def_property(srna, "fmarr", PROP_FLOAT, PROP_NONE); + RNA_def_property_multidimensional_array(prop, MARRAY_SIZE(float), MARRAY_TOTDIM, dimsize); + RNA_def_property_float_funcs(prop, "rna_Test_fmarr_get", "rna_Test_fmarr_set", NULL); + + prop= RNA_def_property(srna, "imarr", PROP_INT, PROP_NONE); + RNA_def_property_multidimensional_array(prop, MARRAY_SIZE(int), MARRAY_TOTDIM, dimsize); + RNA_def_property_int_funcs(prop, "rna_Test_imarr_get", "rna_Test_imarr_set", NULL); + + prop= RNA_def_property(srna, "bmarr", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_multidimensional_array(prop, MARRAY_SIZE(int), MARRAY_TOTDIM, dimsize); + RNA_def_property_boolean_funcs(prop, "rna_Test_bmarr_get", "rna_Test_bmarr_set"); + + /* dynamic multidimensional arrays */ + + prop= RNA_def_property(srna, "fdmarr", PROP_FLOAT, PROP_NONE); + RNA_def_property_multidimensional_array(prop, DYNAMIC_MARRAY_SIZE(float), MARRAY_TOTDIM, dimsize); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_Test_fdmarr_get_length", "rna_Test_fdmarr_set_length"); + RNA_def_property_float_funcs(prop, "rna_Test_fdmarr_get", "rna_Test_fdmarr_set", NULL); + + prop= RNA_def_property(srna, "idmarr", PROP_INT, PROP_NONE); + RNA_def_property_multidimensional_array(prop, DYNAMIC_MARRAY_SIZE(int), MARRAY_TOTDIM, dimsize); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_Test_idmarr_get_length", "rna_Test_idmarr_set_length"); + RNA_def_property_int_funcs(prop, "rna_Test_idmarr_get", "rna_Test_idmarr_set", NULL); + + prop= RNA_def_property(srna, "bdmarr", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_multidimensional_array(prop, DYNAMIC_MARRAY_SIZE(int), MARRAY_TOTDIM, dimsize); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_Test_bdmarr_get_length", "rna_Test_bdmarr_set_length"); + RNA_def_property_boolean_funcs(prop, "rna_Test_bdmarr_get", "rna_Test_bdmarr_set"); + +#endif +} + +#endif /* RNA_RUNTIME */ + + diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index 669cccb7011..9db4b20d011 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -30,33 +30,65 @@ #include "BLI_string.h" +#include "BKE_global.h" + #include "MEM_guardedalloc.h" +#define MAX_ARRAY_DIMENSION 10 + +/* convenient way to access array dimension size */ +#define DIMSIZE(a) (dimsize[a - 1]) + typedef void (*ItemConvertFunc)(PyObject *, char *); -typedef int (*ItemTypeCheckFunc)(PyObject *); +typedef int (*ItemTypeCheckFunc)(PyObject *); typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *); +typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *); + +/* + arr[3][4][5] + 0 1 2 <- dimension index +*/ -/* Ensures that a python sequence has an expected number of items/sub-items and items are of expected type. */ -static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned short totdim, unsigned short dim_size[], - ItemTypeCheckFunc check_item_type, const char *item_type_str, char *error_str, int error_str_size) +/* + arr[2] = x + + py_to_array_index(arraydim=0, arrayoffset=0, index=2) + validate_array(lvalue_dim=0) + ... make real index ... +*/ + +/* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */ +/* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */ +static int validate_array_type(PyObject *seq, unsigned short dim, unsigned short totdim, unsigned short dimsize[], + ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix) { int i; - if (dim < totdim) { + + /* not the last dimension */ + if (dim + 1 < totdim) { + /* check that a sequence contains dimsize[dim] items */ + for (i= 0; i < PySequence_Length(seq); i++) { PyObject *item; int ok= 1; item= PySequence_GetItem(seq, i); if (!PySequence_Check(item)) { - BLI_snprintf(error_str, error_str_size, "expected a %d-dimensional sequence of %s", (int)totdim, item_type_str); + /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */ + PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s", error_prefix, item_type_str); ok= 0; } - else if (PySequence_Length(item) != dim_size[dim - 1]) { - BLI_snprintf(error_str, error_str_size, "dimension %d should contain %d items", (int)dim, (int)dim_size[dim - 1]); + /* arr[3][4][5] + DIMSIZE(1)=4 + DIMSIZE(2)=5 + + dim=0 */ + else if (PySequence_Length(item) != DIMSIZE(dim + 1)) { + /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)DIMSIZE(dim + 1)); */ + PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", error_prefix, (int)dim + 1, (int)DIMSIZE(dim + 1)); ok= 0; } - - if (!pyrna_validate_array(item, dim + 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size)) { + else if (!validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix)) { ok= 0; } @@ -67,13 +99,15 @@ static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned shor } } else { + /* check that items are of correct type */ for (i= 0; i < PySequence_Length(seq); i++) { PyObject *item= PySequence_GetItem(seq, i); if (!check_item_type(item)) { Py_DECREF(item); - - BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); + + /* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */ + PyErr_Format(PyExc_TypeError, "sequence items should be of type %s", item_type_str); return 0; } @@ -85,7 +119,7 @@ static int pyrna_validate_array(PyObject *seq, unsigned short dim, unsigned shor } /* Returns the number of items in a single- or multi-dimensional sequence. */ -static int pyrna_count_items(PyObject *seq) +static int count_items(PyObject *seq) { int totitem= 0; @@ -93,7 +127,7 @@ static int pyrna_count_items(PyObject *seq) int i; for (i= 0; i < PySequence_Length(seq); i++) { PyObject *item= PySequence_GetItem(seq, i); - totitem += pyrna_count_items(item); + totitem += count_items(item); Py_DECREF(item); } } @@ -103,40 +137,103 @@ static int pyrna_count_items(PyObject *seq) return totitem; } -static int pyrna_apply_array_length(PointerRNA *ptr, PropertyRNA *prop, int totitem, char *error_str, int error_str_size) +/* Modifies property array length if needed and PROP_DYNAMIC flag is set. */ +static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix) { - if (RNA_property_flag(prop) & PROP_DYNAMIC) { - /* length can be flexible */ - if (RNA_property_array_length(ptr, prop) != totitem) { - if (!RNA_property_dynamic_array_set_length(ptr, prop, totitem)) { - BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), totitem); + unsigned short dimsize[MAX_ARRAY_DIMENSION]; + int tot, totdim, len; + + tot= count_items(rvalue); + totdim= RNA_property_array_dimension(prop, dimsize); + + if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { + /* length is flexible */ + if (RNA_property_array_length(ptr, prop) != tot) { + if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) { + /* BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ + PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); return 0; } + + len= tot; } } else { /* length is a constraint */ - int len= RNA_property_array_length(ptr, prop); - if (totitem != len) { - BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); + if (!lvalue_dim) { + len= RNA_property_array_length(ptr, prop); + } + /* array item assignment */ + else { + int i; + + len= 1; + + /* arr[3][4][5] + + arr[2] = x + dimsize={4, 5} + DIMSIZE(1) = 4 + DIMSIZE(2) = 5 + lvalue_dim=0, totdim=3 + + arr[2][3] = x + lvalue_dim=1 + + arr[2][3][4] = x + lvalue_dim=2 */ + for (i= lvalue_dim; i < totdim; i++) + len *= DIMSIZE(i); + } + + if (tot != len) { + /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */ + PyErr_Format(PyExc_ValueError, "%s sequence must have %d items total", error_prefix, len); return 0; } } + + *totitem= len; + return 1; } -static char *pyrna_py_to_array(PyObject *seq, unsigned short dim, unsigned short totdim, char *data, unsigned int item_size, ItemConvertFunc convert_item) +static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix) +{ + unsigned short dimsize[MAX_ARRAY_DIMENSION]; + int totdim= RNA_property_array_dimension(prop, dimsize); + + /* validate type first because length validation may modify property array length */ + + if (!validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix)) + return 0; + + return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); +} + +static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, unsigned short dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index) { unsigned int i; + int totdim= RNA_property_array_dimension(prop, NULL); + for (i= 0; i < PySequence_Length(seq); i++) { PyObject *item= PySequence_GetItem(seq, i); - if (dim < totdim) { - data= pyrna_py_to_array(item, dim + 1, totdim, data, item_size, convert_item); + if (dim + 1 < totdim) { + data= copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index); } else { - convert_item(item, data); - data += item_size; + if (!data) { + char value[sizeof(int)]; + + convert_item(item, value); + rna_set_index(ptr, prop, *index, value); + *index = *index + 1; + } + else { + convert_item(item, data); + data += item_size; + } } Py_DECREF(item); @@ -145,21 +242,15 @@ static char *pyrna_py_to_array(PyObject *seq, unsigned short dim, unsigned short return data; } -static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size, - ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array) +static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix) { - unsigned short totdim, dim_size[100]; + unsigned short totdim, dim_size[MAX_ARRAY_DIMENSION]; int totitem; char *data= NULL; totdim= RNA_property_array_dimension(prop, dim_size); - if (!pyrna_validate_array(py, 1, totdim, dim_size, check_item_type, item_type_str, error_str, error_str_size)) - return 0; - - totitem= pyrna_count_items(py); - - if (!pyrna_apply_array_length(ptr, prop, totitem, error_str, error_str_size)) + if (!validate_array(py, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix)) return 0; if (totitem) { @@ -168,7 +259,7 @@ static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA else data= param_data; - pyrna_py_to_array(py, 1, totdim, data, item_size, convert_item); + copy_values(py, ptr, prop, 0, data, item_size, NULL, convert_item, NULL); if (param_data) { if (RNA_property_flag(prop) & PROP_DYNAMIC) { @@ -186,50 +277,236 @@ static int pyrna_py_to_array_generic(PyObject *py, PointerRNA *ptr, PropertyRNA return 1; } -static void pyrna_py_to_float(PyObject *py, char *data) +static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix) +{ + unsigned short totdim, dimsize[MAX_ARRAY_DIMENSION]; + int totitem, i; + + totdim= RNA_property_array_dimension(prop, dimsize); + + /* convert index */ + + /* arr[3][4][5] + + arr[2] = x + lvalue_dim=0, index = 0 + 2 * 4 * 5 + + arr[2][3] = x + lvalue_dim=1, index = 40 + 3 * 5 */ + + lvalue_dim++; + + for (i= lvalue_dim; i < totdim; i++) + index *= DIMSIZE(i); + + index += arrayoffset; + + if (!validate_array(py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix)) + return 0; + + if (totitem) + copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index); + + return 1; +} + +static void py_to_float(PyObject *py, char *data) { *(float*)data= (float)PyFloat_AsDouble(py); } -static void pyrna_py_to_int(PyObject *py, char *data) +static void py_to_int(PyObject *py, char *data) { *(int*)data= (int)PyLong_AsSsize_t(py); } -static void pyrna_py_to_boolean(PyObject *py, char *data) +static void py_to_bool(PyObject *py, char *data) { *(int*)data= (int)PyObject_IsTrue(py); } static int py_float_check(PyObject *py) { - return PyFloat_Check(py) || (PyIndex_Check(py)); + /* accept both floats and integers */ + return PyFloat_Check(py) || PyLong_Check(py); } static int py_int_check(PyObject *py) { - return PyLong_Check(py) || (PyIndex_Check(py)); + /* accept only integers */ + return PyLong_Check(py); } static int py_bool_check(PyObject *py) { - return PyBool_Check(py) || (PyIndex_Check(py)); + return PyBool_Check(py); +} + +static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) +{ + RNA_property_float_set_index(ptr, prop, index, *(float*)value); +} + +static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) +{ + RNA_property_int_set_index(ptr, prop, index, *(int*)value); +} + +static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) +{ + RNA_property_boolean_set_index(ptr, prop, index, *(int*)value); +} + +int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix) +{ + int ret; + switch (RNA_property_type(prop)) { + case PROP_FLOAT: + ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix); + break; + case PROP_INT: + ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix); + break; + case PROP_BOOLEAN: + ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix); + break; + default: + PyErr_SetString(PyExc_TypeError, "not an array type"); + ret= 0; + } + + return ret; } -int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size) +int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix) { - return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size, - py_float_check, "float", sizeof(float), pyrna_py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array); + int ret; + switch (RNA_property_type(prop)) { + case PROP_FLOAT: + ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix); + break; + case PROP_INT: + ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix); + break; + case PROP_BOOLEAN: + ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix); + break; + default: + PyErr_SetString(PyExc_TypeError, "not an array type"); + ret= 0; + } + + return ret; } -int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size) +static PyObject *pyrna_array_item(PointerRNA *ptr, PropertyRNA *prop, int index) { - return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size, - py_int_check, "int", sizeof(int), pyrna_py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array); + PyObject *item; + + switch (RNA_property_type(prop)) { + case PROP_FLOAT: + item= PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index)); + break; + case PROP_BOOLEAN: + item= PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index)); + break; + case PROP_INT: + item= PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index)); + break; + default: + PyErr_SetString(PyExc_TypeError, "not an array type"); + item= NULL; + } + + return item; } -int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size) +#if 0 +/* XXX this is not used (and never will?) */ +/* Given an array property, creates an N-dimensional tuple of values. */ +static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop, int dim, int *index) { - return pyrna_py_to_array_generic(py, ptr, prop, param_data, error_str, error_str_size, - py_bool_check, "boolean", sizeof(int), pyrna_py_to_boolean, (RNA_SetArrayFunc)RNA_property_boolean_set_array); + PyObject *tuple; + int i, len; + int totdim= RNA_property_array_dimension(prop, NULL); + + len= RNA_property_multidimensional_array_length(ptr, prop, dim); + + tuple= PyTuple_New(len); + + for (i= 0; i < len; i++) { + PyObject *item; + + if (dim + 1 < totdim) + item= pyrna_py_from_array_internal(ptr, prop, dim + 1, index); + else { + item= pyrna_array_item(ptr, prop, *index); + *index= *index + 1; + } + + if (!item) { + Py_DECREF(tuple); + return NULL; + } + + PyTuple_SetItem(tuple, i, item); + } + + return tuple; +} +#endif + +PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) +{ + int totdim, i, len; + unsigned short dimsize[MAX_ARRAY_DIMENSION]; + BPy_PropertyRNA *ret= NULL; + + /* just in case check */ + len= RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim); + if (index >= len || index < 0) { + /* this shouldn't happen because higher level funcs must check for invalid index */ + if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return NULL; + } + + totdim= RNA_property_array_dimension(self->prop, dimsize); + + if (self->arraydim + 1 < totdim) { + ret= (BPy_PropertyRNA*)pyrna_prop_CreatePyObject(&self->ptr, self->prop); + ret->arraydim= self->arraydim + 1; + + /* arr[3][4][5] + + x = arr[2] + index = 0 + 2 * 4 * 5 + + x = arr[2][3] + index = offset + 3 * 5 */ + + for (i= self->arraydim + 1; i < totdim; i++) + index *= DIMSIZE(i); + + ret->arrayoffset= self->arrayoffset + index; + } + else { + index = self->arrayoffset + index; + ret= (BPy_PropertyRNA*)pyrna_array_item(&self->ptr, self->prop, index); + } + + return (PyObject*)ret; +} + +PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop) +{ + PyObject *ret; + + ret= pyrna_math_object_from_array(ptr, prop); + + /* is this a maths object? */ + if (ret) return ret; + + return pyrna_prop_CreatePyObject(ptr, prop); } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 8ba3b5f8732..f2ffd5e0358 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -130,6 +130,70 @@ Mathutils_Callback mathutils_rna_matrix_cb = { (BaseMathSetIndexFunc) NULL }; +PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) +{ + PyObject *ret= NULL; + +#ifdef USE_MATHUTILS + int type, subtype, totdim; + int len; + + len= RNA_property_array_length(ptr, prop); + type= RNA_property_type(prop); + subtype= RNA_property_subtype(prop); + totdim= RNA_property_array_dimension(prop, NULL); + + if (type != PROP_FLOAT) return NULL; + + if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { + ret = pyrna_prop_CreatePyObject(ptr, prop); + + switch(RNA_property_subtype(prop)) { + case PROP_TRANSLATION: + case PROP_DIRECTION: + case PROP_VELOCITY: + case PROP_ACCELERATION: + case PROP_XYZ: + if(len>=2 && len <= 4) { + PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE); + Py_DECREF(ret); /* the vector owns now */ + ret= vec_cb; /* return the vector instead */ + } + break; + case PROP_MATRIX: + if(len==16) { + PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } + else if (len==9) { + PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } + break; + case PROP_EULER: + case PROP_QUATERNION: + if(len==3) { /* euler */ + PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= eul_cb; /* return the matrix instead */ + } + else if (len==4) { + PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE); + Py_DECREF(ret); /* the matrix owns now */ + ret= quat_cb; /* return the matrix instead */ + } + break; + default: + break; + } + } +#endif + + return ret; +} + #endif static StructRNA *pyrna_struct_as_srna(PyObject *self); @@ -288,58 +352,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) int len = RNA_property_array_length(ptr, prop); if (len > 0) { - /* resolve the array from a new pytype */ - PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop); - -#ifdef USE_MATHUTILS - - /* return a mathutils vector where possible */ - if(RNA_property_type(prop)==PROP_FLOAT) { - switch(RNA_property_subtype(prop)) { - case PROP_TRANSLATION: - case PROP_DIRECTION: - case PROP_VELOCITY: - case PROP_ACCELERATION: - case PROP_XYZ: - if(len>=2 && len <= 4) { - PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, FALSE); - Py_DECREF(ret); /* the vector owns now */ - ret= vec_cb; /* return the vector instead */ - } - break; - case PROP_MATRIX: - if(len==16) { - PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= mat_cb; /* return the matrix instead */ - } - else if (len==9) { - PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= mat_cb; /* return the matrix instead */ - } - break; - case PROP_EULER: - case PROP_QUATERNION: - if(len==3) { /* euler */ - PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= eul_cb; /* return the matrix instead */ - } - else if (len==4) { - PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, FALSE); - Py_DECREF(ret); /* the matrix owns now */ - ret= quat_cb; /* return the matrix instead */ - } - break; - default: - break; - } - } - -#endif - - return ret; + return pyrna_py_from_array(ptr, prop); } /* see if we can coorce into a python type - PropertyType */ @@ -511,7 +524,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v int len = RNA_property_array_length(ptr, prop); if (len > 0) { - char error_str[512]; + /* char error_str[512]; */ int ok= 1; #ifdef USE_MATHUTILS @@ -526,21 +539,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v return -1; } /* done getting the length */ - - /* for arrays we have a limited number of types */ - switch (type) { - case PROP_BOOLEAN: - ok= pyrna_py_to_boolean_array(value, ptr, prop, data, error_str, sizeof(error_str)); - break; - case PROP_INT: - ok= pyrna_py_to_int_array(value, ptr, prop, data, error_str, sizeof(error_str)); - break; - case PROP_FLOAT: - ok= pyrna_py_to_float_array(value, ptr, prop, data, error_str, sizeof(error_str)); - break; - } + ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix); + if (!ok) { - PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); + /* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */ return -1; } } @@ -733,82 +735,84 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v return 0; } -static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index) +static PyObject * pyrna_prop_to_py_index(BPy_PropertyRNA *self, int index) { - PyObject *ret; - int type = RNA_property_type(prop); - - /* see if we can coorce into a python type - PropertyType */ - switch (type) { - case PROP_BOOLEAN: - ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) ); - break; - case PROP_INT: - ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get_index(ptr, prop, index) ); - break; - case PROP_FLOAT: - ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) ); - break; - default: - PyErr_SetString(PyExc_AttributeError, "not an array type"); - ret = NULL; - break; - } - - return ret; + return pyrna_py_from_array_index(self, index); } -static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value) +static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *value) { int ret = 0; + int totdim; + PointerRNA *ptr= &self->ptr; + PropertyRNA *prop= self->prop; int type = RNA_property_type(prop); - - /* see if we can coorce into a python type - PropertyType */ - switch (type) { - case PROP_BOOLEAN: - { - int param = PyObject_IsTrue( value ); - - if( param < 0 ) { - PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1"); - ret = -1; - } else { - RNA_property_boolean_set_index(ptr, prop, index, param); - } - break; - } - case PROP_INT: - { - int param = PyLong_AsSsize_t(value); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected an int type"); - ret = -1; - } else { - RNA_property_int_set_index(ptr, prop, index, param); + + totdim= RNA_property_array_dimension(prop, NULL); + + if (totdim > 1) { + /* char error_str[512]; */ + if (!pyrna_py_to_array_index(&self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "")) { + /* PyErr_SetString(PyExc_AttributeError, error_str); */ + ret= -1; } - break; } - case PROP_FLOAT: - { - float param = PyFloat_AsDouble(value); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected a float type"); + else { + /* see if we can coorce into a python type - PropertyType */ + switch (type) { + case PROP_BOOLEAN: + { + int param = PyObject_IsTrue( value ); + + if( param < 0 ) { + PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1"); + ret = -1; + } else { + RNA_property_boolean_set_index(ptr, prop, index, param); + } + break; + } + case PROP_INT: + { + int param = PyLong_AsSsize_t(value); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "expected an int type"); + ret = -1; + } else { + RNA_property_int_set_index(ptr, prop, index, param); + } + break; + } + case PROP_FLOAT: + { + float param = PyFloat_AsDouble(value); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "expected a float type"); + ret = -1; + } else { + RNA_property_float_set_index(ptr, prop, index, param); + } + break; + } + default: + PyErr_SetString(PyExc_AttributeError, "not an array type"); ret = -1; - } else { - RNA_property_float_set_index(ptr, prop, index, param); + break; } - break; - } - default: - PyErr_SetString(PyExc_AttributeError, "not an array type"); - ret = -1; - break; } return ret; } //---------------sequence------------------------------------------- +static int pyrna_prop_array_length(BPy_PropertyRNA *self) +{ + if (RNA_property_array_dimension(self->prop, NULL) > 1) + return RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim); + else + return RNA_property_array_length(&self->ptr, self->prop); +} + static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self ) { Py_ssize_t len; @@ -816,10 +820,10 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self ) if (RNA_property_type(self->prop) == PROP_COLLECTION) { len = RNA_property_collection_length(&self->ptr, self->prop); } else { - len = RNA_property_array_length(&self->ptr, self->prop); + len = pyrna_prop_array_length(self); if (len==0) { /* not an array*/ - PyErr_SetString(PyExc_AttributeError, "len() only available for collection RNA types"); + PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types"); return -1; } } @@ -840,14 +844,15 @@ static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynu PyErr_Format(PyExc_IndexError, "index %d out of range", keynum); return NULL; } + static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum) { - int len= RNA_property_array_length(&self->ptr, self->prop); + int len= pyrna_prop_array_length(self); if(keynum < 0) keynum += len; if(keynum >= 0 && keynum < len) - return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum); + return pyrna_prop_to_py_index(self, keynum); PyErr_Format(PyExc_IndexError, "index %d out of range", keynum); return NULL; @@ -894,7 +899,7 @@ static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, i start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */ for(count = start; count < stop; count++) - PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count)); + PyList_SetItem(list, count - start, pyrna_prop_to_py_index(self, count)); return list; } @@ -947,8 +952,8 @@ static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key) return prop_subscript_array_int(self, PyLong_AsSsize_t(key)); } else if (PySlice_Check(key)) { - int len= RNA_property_array_length(&self->ptr, self->prop); Py_ssize_t start, stop, step, slicelength; + int len = pyrna_prop_array_length(self); if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) return NULL; @@ -974,13 +979,12 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) { if (RNA_property_type(self->prop) == PROP_COLLECTION) { return prop_subscript_collection(self, key); - } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* arrays are currently fixed length, zero length means its not an array */ + } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */ return prop_subscript_array(self, key); - } else { - PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection"); - return NULL; - } + } + PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection"); + return NULL; } static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value) @@ -991,7 +995,7 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int begin = MIN2(begin,end); for(count = begin; count < end; count++) { - if(pyrna_py_to_prop_index(&self->ptr, self->prop, count - begin, value) == -1) { + if(pyrna_py_to_prop_index(self, count - begin, value) == -1) { /* TODO - this is wrong since some values have been assigned... will need to fix that */ return -1; /* pyrna_struct_CreatePyObject should set the error */ } @@ -1002,13 +1006,12 @@ static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value) { - - int len= RNA_property_array_length(&self->ptr, self->prop); + int len= pyrna_prop_array_length(self); if(keynum < 0) keynum += len; if(keynum >= 0 && keynum < len) - return pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value); + return pyrna_py_to_prop_index(self, keynum, value); PyErr_SetString(PyExc_IndexError, "out of range"); return -1; @@ -1682,7 +1685,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) if (ret==NULL) { /* collection did not work, try array */ - int len = RNA_property_array_length(&self->ptr, self->prop); + int len = pyrna_prop_array_length(self); if (len) { int i; @@ -1690,7 +1693,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) ret = PyList_New(len); for (i=0; i < len; i++) { - PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(&self->ptr, self->prop, i)); + PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i)); } } } @@ -1781,6 +1784,8 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) /* resolve the array from a new pytype */ ret = PyTuple_New(len); + /* kazanbas: TODO make multidim sequences here */ + switch (type) { case PROP_BOOLEAN: for(a=0; aptr = *ptr; pyrna->prop = prop; + + pyrna->arraydim= 0; + pyrna->arrayoffset= 0; return ( PyObject * ) pyrna; } diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index d65849ad8a4..d006b168f45 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -55,6 +55,10 @@ typedef struct { PyObject_HEAD /* required python macro */ PointerRNA ptr; PropertyRNA *prop; + + /* Arystan: this is a hack to allow sub-item r/w access like: face.uv[n][m] */ + int arraydim; /* array dimension, e.g: 0 for face.uv, 2 for face.uv[n][m], etc. */ + int arrayoffset; /* array first item offset, e.g. if face.uv is [4][2], arrayoffset for face.uv[n] is 2n */ } BPy_PropertyRNA; /* cheap trick */ @@ -92,8 +96,11 @@ void pyrna_alloc_types(void); void pyrna_free_types(void); /* primitive type conversion */ -int pyrna_py_to_boolean_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size); -int pyrna_py_to_int_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size); -int pyrna_py_to_float_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, char *error_str, int error_str_size); +int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix); +int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix); + +PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop); +PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index); +PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop); #endif diff --git a/tools/btools.py b/tools/btools.py index 580a457e3a0..7cadab992b8 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -91,7 +91,7 @@ def validate_arguments(args, bc): 'BF_BSC', 'BF_CONFIG', 'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG', 'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG', - 'BF_DOCDIR'] + 'BF_DOCDIR', 'BF_UNIT_TEST'] okdict = {} @@ -386,7 +386,9 @@ def read_opts(cfg, args): ('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'), ('BF_NUMJOBS', 'Number of build processes to spawn', '1'), - ('BF_MSVS', 'Generate MSVS project files and solution', False) + ('BF_MSVS', 'Generate MSVS project files and solution', False), + + (BoolVariable('BF_UNIT_TEST', 'Build with unit test support.', False)) ) # end of opts.AddOptions() -- cgit v1.2.3 From 952fa6d1c182fafa1f2a9133809a2b58ad7a91c2 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 6 Sep 2009 16:58:14 +0000 Subject: 2.5/Paint: * Fixed some bad UI pointed out by letterrip. People had made some quite bad changes (duplicating buttons, adding UI for non-existent features, even deleting UI for existing features!) --- release/ui/space_view3d_toolbar.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 0b7ccb15d6c..8a42d9683f8 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -342,9 +342,6 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column() - if brush.sculpt_tool != 'LAYER': - col.itemR(brush, "anchored") - if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'): col.itemR(brush, "flip_direction") @@ -352,8 +349,6 @@ class VIEW3D_PT_tools_brush(PaintPanel): col.itemR(brush, "persistent") col.itemO("sculpt.set_persistent_base") - col.itemR(brush, "rake") - col.itemR(brush, "sculpt_tool") # Texture Paint Mode # @@ -426,24 +421,29 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel): brush = settings.brush texture_paint = context.texture_paint_object + if context.sculpt_object: + if brush.sculpt_tool != 'LAYER': + layout.itemR(brush, "anchored") + layout.itemR(brush, "rake") + + layout.itemR(brush, "airbrush") + col = layout.column() + col.active = brush.airbrush + col.itemR(brush, "rate", slider=True) + if not texture_paint: layout.itemR(brush, "smooth_stroke") col = layout.column() - col.itemR(brush, "airbrush") - col.itemR(brush, "anchored") - col.itemR(brush, "rake") + col.active = brush.smooth_stroke + col.itemR(brush, "smooth_stroke_radius", text="Radius", slider=True) + col.itemR(brush, "smooth_stroke_factor", text="Factor", slider=True) layout.itemR(brush, "space") row = layout.row(align=True) row.active = brush.space row.itemR(brush, "spacing", text="Distance", slider=True) if texture_paint: - row.itemR(brush, "spacing_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") - - layout.itemR(brush, "airbrush") - col = layout.column() - col.active = brush.airbrush - col.itemR(brush, "rate", slider=True) + row.itemR(brush, "spacing_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") class VIEW3D_PT_tools_brush_curve(PaintPanel): __label__ = "Curve" -- cgit v1.2.3 From 64af3a26184632f53b2ed536f784303e963f033c Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 6 Sep 2009 19:14:06 +0000 Subject: *introduced new method for packing/optimizing trees after building (this is a generalization of some of the experimental stuff i tried during SoC, but only had time to improve a few days ago) - it should yield slightly better results - the cost model can somehow be tweaked to optimize for diferent trees. *cleaned up some code *added counters for number of SIMD BB tests *added GPL license block on missing files --- source/blender/makesdna/DNA_scene_types.h | 16 +- source/blender/makesrna/intern/rna_scene.c | 26 +-- source/blender/render/extern/include/RE_raytrace.h | 2 +- source/blender/render/intern/raytrace/bvh.h | 8 +- source/blender/render/intern/raytrace/qbvh.h | 0 .../render/intern/raytrace/rayobject_bvh.cpp | 1 - .../render/intern/raytrace/rayobject_qbvh.cpp | 57 ++++- .../render/intern/raytrace/rayobject_rtbuild.cpp | 28 +++ .../render/intern/raytrace/rayobject_svbvh.cpp | 42 +++- .../render/intern/raytrace/rayobject_vbvh.cpp | 2 +- source/blender/render/intern/raytrace/reorganize.h | 235 +++++++++++++++++++++ source/blender/render/intern/raytrace/svbvh.h | 13 +- source/blender/render/intern/raytrace/vbvh.h | 43 +++- .../render/intern/source/rayobject_raycounter.c | 9 + source/blender/render/intern/source/rayshade.c | 138 ++++-------- 15 files changed, 465 insertions(+), 155 deletions(-) delete mode 100644 source/blender/render/intern/raytrace/qbvh.h diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 6efd47d9348..82658be24bf 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -769,15 +769,13 @@ typedef struct Scene { #define R_YAFRAY 1 /* raytrace structure */ -#define R_RAYSTRUCTURE_HIER_BVH_BVH 0 -#define R_RAYSTRUCTURE_HIER_BVH_OCTREE 1 -#define R_RAYSTRUCTURE_SINGLE_OCTREE 2 -#define R_RAYSTRUCTURE_SINGLE_BVH 3 - -/* raytrace tree type */ -#define R_RAYTRACE_TREE_BVH 0 -#define R_RAYTRACE_TREE_BLIBVH 1 -#define R_RAYTRACE_TREE_BIH 2 +#define R_RAYSTRUCTURE_AUTO 0 +#define R_RAYSTRUCTURE_OCTREE 1 +#define R_RAYSTRUCTURE_BLIBVH 2 +#define R_RAYSTRUCTURE_VBVH 3 +#define R_RAYSTRUCTURE_SIMD_SVBVH 4 /* needs SIMD */ +#define R_RAYSTRUCTURE_SIMD_QBVH 5 /* needs SIMD */ +#define R_RAYSTRUCTURE_BIH 6 /* scemode (int now) */ #define R_DOSEQ 0x0001 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7baf8c8fd93..db832f1d31c 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1032,18 +1032,16 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem raytrace_structure_items[] = { - {R_RAYSTRUCTURE_HIER_BVH_BVH, "{R_RAYSTRUCTURE_HIER_BVH_BVH", 0, "BVH of BVH's", "Create a BVH of objects (each object has it own BVH)"}, - {R_RAYSTRUCTURE_HIER_BVH_OCTREE, "{R_RAYSTRUCTURE_HIER_BVH_OCTREE", 0, "BVH of octree", "Create a BVH of objects (each object has it own octree)"}, - {R_RAYSTRUCTURE_SINGLE_BVH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "Single BVH", "BVH of all primitives (no instance support)"}, - {R_RAYSTRUCTURE_SINGLE_OCTREE, "{R_RAYSTRUCTURE_SINGLE_OCTREE", 0, "Octree", "Octree of all primitives (no instance support)"}, - {0, NULL, 0, NULL, NULL}}; + {R_RAYSTRUCTURE_AUTO, "{R_RAYSTRUCTURE_AUTO", 0, "auto", ""}, + {R_RAYSTRUCTURE_OCTREE, "R_RAYSTRUCTURE_OCTREE", 0, "octree", "Use old octree structure (no support for instances)"}, + {R_RAYSTRUCTURE_BLIBVH, "R_RAYSTRUCTURE_BLIBVH", 0, "blibvh", "Use BLI_kdopbvh.c"}, + {R_RAYSTRUCTURE_VBVH, "R_RAYSTRUCTURE_VBVH", 0, "vBVH", ""}, + {R_RAYSTRUCTURE_SIMD_SVBVH, "R_RAYSTRUCTURE_SIMD_SVBVH", 0, "SIMD SVBVH", "Requires SIMD"}, + {R_RAYSTRUCTURE_SIMD_QBVH, "R_RAYSTRUCTURE_SIMD_QBVH", 0, "SIMD QBVH", "Requires SIMD"}, + {R_RAYSTRUCTURE_BIH, "R_RAYSTRUCTURE_BIH", 0, "BIH", ""}, + {0, NULL, 0, NULL, NULL} + }; - static EnumPropertyItem raytrace_tree_type_items[] = { - {R_RAYTRACE_TREE_BVH, "{R_RAYTRACE_TREE_BVH", 0, "BVH", "rayobject_bvh.c"}, - {R_RAYTRACE_TREE_BLIBVH, "{R_RAYTRACE_TREE_BLIBVH", 0, "BLIbvh", "rayobject_blibvh.c"}, - {R_RAYTRACE_TREE_BIH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "BIH", "rayobject_bih.c"}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem fixed_oversample_items[] = { {5, "OVERSAMPLE_5", 0, "5", ""}, {8, "OVERSAMPLE_8", 0, "8", ""}, @@ -1462,12 +1460,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "raytrace_tree_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "raytrace_tree_type"); - RNA_def_property_enum_items(prop, raytrace_tree_type_items); - RNA_def_property_ui_text(prop, "Raytrace tree type", "Type of raytrace accelerator structure."); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA); RNA_def_property_ui_text(prop, "Anti-Aliasing", "Render and combine multiple samples per pixel to prevent jagged edges."); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 01b64c15058..c775a7d18ef 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -53,7 +53,7 @@ struct RayCounter { unsigned long long test, hit; - } faces, bb, raycast, raytrace_hint, rayshadow_last_hit; + } faces, bb, simd_bb, raycast, raytrace_hint, rayshadow_last_hit; }; /* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 21234a40673..7d3479e5331 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -241,17 +241,13 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) t_node[i] = t->child; } */ - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - + RE_RC_COUNT(isec->raycounter->simd_bb.test); int res = test_bb_group4( t_bb, isec ); for(int i=0; i<4; i++) if(res & (1<raycounter->bb.hit); + RE_RC_COUNT(isec->raycounter->simd_bb.hit); if(!is_leaf(t_node[i])) { for(Node *t=t_node[i]; t; t=t->sibling) diff --git a/source/blender/render/intern/raytrace/qbvh.h b/source/blender/render/intern/raytrace/qbvh.h deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp index bf54f889ebf..a7e96f6d3fc 100644 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_bvh.cpp @@ -65,7 +65,6 @@ struct BVHTree RTBuilder *builder; }; - /* * Push nodes (used on dfs) */ diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index e3a15b5d7f3..53579d2915f 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -1,6 +1,33 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include "vbvh.h" #include "svbvh.h" -#include "qbvh.h" #include "reorganize.h" #define DFS_STACK_SIZE 256 @@ -17,6 +44,17 @@ struct QBVHTree }; +/* + * Cost to test N childs + */ +struct PackCost +{ + float operator()(int n) + { + return (n / 4) + ((n % 4) > 2 ? 1 : n%4); + } +}; + template<> void bvh_done(QBVHTree *obj) { @@ -31,9 +69,20 @@ void bvh_done(QBVHTree *obj) BLI_memarena_use_align(arena2, 16); //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); - pushup_simd(root); - obj->root = Reorganize_SVBVH(arena2).transform(root); + + if(0) + { + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + pushup_simd(root); + obj->root = Reorganize_SVBVH(arena2).transform(root); + } + else + { + //Finds the optimal packing of this tree using a given cost model + OVBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + VBVH_optimalPackSIMD(PackCost()).transform(root); + obj->root = Reorganize_SVBVH(arena2).transform(root); + } //Cleanup BLI_memarena_free(arena1); diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 238929e1dbb..430045b56b6 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -1,3 +1,31 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include #include #include diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp index df033901526..1bcffddd0ac 100644 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -1,3 +1,31 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include "vbvh.h" #include "svbvh.h" #include "reorganize.h" @@ -25,9 +53,12 @@ void bvh_done(SVBVHTree *obj) MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); BLI_memarena_use_malloc(arena1); - //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena2); + BLI_memarena_use_align(arena2, 16); + //Build and optimize the tree + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); reorganize(root); remove_useless(root, &root); bvh_refit(root); @@ -35,12 +66,11 @@ void bvh_done(SVBVHTree *obj) pushup(root); pushdown(root); pushup_simd(root); - - MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); - BLI_memarena_use_malloc(arena2); - BLI_memarena_use_align(arena2, 16); + obj->root = Reorganize_SVBVH(arena2).transform(root); + + //Free data BLI_memarena_free(arena1); obj->node_arena = arena2; diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index f81ca1e5d1b..4e51de0da07 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -70,7 +70,7 @@ void bvh_done(VBVHTree *obj) //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); reorganize(root); remove_useless(root, &root); diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h index 712221fb739..f0335b769d5 100644 --- a/source/blender/render/intern/raytrace/reorganize.h +++ b/source/blender/render/intern/raytrace/reorganize.h @@ -26,7 +26,10 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#include +#include #include +#include #include extern int tot_pushup; @@ -279,3 +282,235 @@ float bvh_refit(Node *node) total += old_area - bb_area(node->bb, node->bb+3); return total; } + + +/* + * this finds the best way to packing a tree acording to a given test cost function + * with the purpose to reduce the expected cost (eg.: number of BB tests). + */ +#include +#include +#define MAX_CUT_SIZE 16 +#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE + +struct OVBVHNode +{ + float bb[6]; + + OVBVHNode *child; + OVBVHNode *sibling; + + /* + * Returns min cost to represent the subtree starting at the given node, + * allowing it to have a given cutsize + */ + float cut_cost[MAX_CUT_SIZE]; + float get_cost(int cutsize) + { + return cut_cost[cutsize-1]; + } + + /* + * This saves the cut size of this child, when parent is reaching + * its minimum cut with the given cut size + */ + int cut_size[MAX_CUT_SIZE]; + int get_cut_size(int parent_cut_size) + { + return cut_size[parent_cut_size-1]; + } + + /* + * Reorganize the node based on calculated cut costs + */ + int best_cutsize; + void set_cut(int cutsize, OVBVHNode ***cut) + { + if(cutsize == 1) + { + **cut = this; + *cut = &(**cut)->sibling; + } + else + { + if(cutsize > MAX_CUT_SIZE) + { + for(OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) + { + child->set_cut( 1, cut ); + cutsize--; + } + assert(cutsize == 0); + } + else + for(OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) + child->set_cut( child->get_cut_size( cutsize ), cut ); + } + } + + void optimize() + { + if(RE_rayobject_isAligned(this->child)) + { + //Calc new childs + { + OVBVHNode **cut = &(this->child); + set_cut( best_cutsize, &cut ); + *cut = NULL; + } + + //Optimize new childs + for(OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) + child->optimize(); + } + } +}; + +/* + * Calculates an optimal SIMD packing + * + */ +template +struct VBVH_optimalPackSIMD +{ + TestCost testcost; + + VBVH_optimalPackSIMD(TestCost testcost) + { + this->testcost = testcost; + } + + /* + * calc best cut on a node + */ + struct calc_best + { + Node *child[MAX_OPTIMIZE_CHILDS]; + float child_hit_prob[MAX_OPTIMIZE_CHILDS]; + + calc_best(Node *node) + { + int nchilds = 0; + //Fetch childs and needed data + { + float parent_area = bb_area(node->bb, node->bb+3); + for(Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) + { + this->child[nchilds] = child; + this->child_hit_prob[nchilds] = bb_area(child->bb, child->bb+3) / parent_area; + nchilds++; + } + + assert(nchilds >= 2 && nchilds <= MAX_OPTIMIZE_CHILDS); + } + + + //Build DP table to find minimum cost to represent this node with a given cutsize + int bt [MAX_OPTIMIZE_CHILDS+1][MAX_CUT_SIZE+1]; //backtrace table + float cost[MAX_OPTIMIZE_CHILDS+1][MAX_CUT_SIZE+1]; //cost table (can be reduced to float[2][MAX_CUT_COST]) + + for(int i=0; i<=nchilds; i++) + for(int j=0; j<=MAX_CUT_SIZE; j++) + cost[i][j] = INFINITY; + + cost[0][0] = 0; + + for(int i=1; i<=nchilds; i++) + for(int size=i-1; size/*+(nchilds-i)*/<=MAX_CUT_SIZE; size++) + for(int cut=1; cut+size/*+(nchilds-i)*/<=MAX_CUT_SIZE; cut++) + { + float new_cost = cost[i-1][size] + child_hit_prob[i-1]*child[i-1]->get_cost(cut); + if(new_cost < cost[i][size+cut]) + { + cost[i][size+cut] = new_cost; + bt[i][size+cut] = cut; + } + } + + //Save the ways to archieve the minimum cost with a given cutsize + for(int i = nchilds; i <= MAX_CUT_SIZE; i++) + { + node->cut_cost[i-1] = cost[nchilds][i]; + if(cost[nchilds][i] < INFINITY) + { + int current_size = i; + for(int j=nchilds; j>0; j--) + { + child[j-1]->cut_size[i-1] = bt[j][current_size]; + current_size -= bt[j][current_size]; + } + } + } + } + }; + + void calc_costs(Node *node) + { + + if( RE_rayobject_isAligned(node->child) ) + { + int nchilds = 0; + for(Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) + { + calc_costs(child); + nchilds++; + } + + for(int i=0; icut_cost[i] = INFINITY; + + //We are not allowed to look on nodes with with so many childs + if(nchilds > MAX_CUT_SIZE) + { + float cost = 0; + + float parent_area = bb_area(node->bb, node->bb+3); + for(Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) + { + cost += ( bb_area(child->bb, child->bb+3) / parent_area ) * child->get_cost(1); + } + + cost += testcost(nchilds); + node->cut_cost[0] = cost; + node->best_cutsize = nchilds; + } + else + { + calc_best calc(node); + + //calc expected cost if we optimaly pack this node + for(int cutsize=nchilds; cutsize<=MAX_CUT_SIZE; cutsize++) + { + float m = node->get_cost(cutsize) + testcost(cutsize); + if(m < node->cut_cost[0]) + { + node->cut_cost[0] = m; + node->best_cutsize = cutsize; + } + } + } + assert(node->cut_cost[0] != INFINITY); + } + else + { + node->cut_cost[0] = 1.0f; + for(int i=1; icut_cost[i] = INFINITY; + } + } + + Node *transform(Node *node) + { + if(RE_rayobject_isAligned(node->child)) + { + static int num = 0; + bool first = false; + if(num == 0) { num++; first = true; } + + calc_costs(node); + if(first) printf("expected cost = %f (%d)\n", node->cut_cost[0], node->best_cutsize ); + node->optimize(); + } + return node; + } +}; diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index b243e91d381..840ccc24d1a 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -56,15 +56,12 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN while(i+4 <= node->nchilds) { int res = test_bb_group4( (__m128*) (node->child_bb+6*i), isec ); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); - RE_RC_COUNT(isec->raycounter->bb.test); + RE_RC_COUNT(isec->raycounter->simd_bb.test); - if(res & 1) { stack[stack_pos++] = node->child[i+0]; RE_RC_COUNT(isec->raycounter->bb.hit); } - if(res & 2) { stack[stack_pos++] = node->child[i+1]; RE_RC_COUNT(isec->raycounter->bb.hit); } - if(res & 4) { stack[stack_pos++] = node->child[i+2]; RE_RC_COUNT(isec->raycounter->bb.hit); } - if(res & 8) { stack[stack_pos++] = node->child[i+3]; RE_RC_COUNT(isec->raycounter->bb.hit); } + if(res & 1) { stack[stack_pos++] = node->child[i+0]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 2) { stack[stack_pos++] = node->child[i+1]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 4) { stack[stack_pos++] = node->child[i+2]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 8) { stack[stack_pos++] = node->child[i+3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } i += 4; } diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h index 7c07bd9ded0..db1df43f665 100644 --- a/source/blender/render/intern/raytrace/vbvh.h +++ b/source/blender/render/intern/raytrace/vbvh.h @@ -1,3 +1,31 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include #include @@ -75,6 +103,7 @@ void append_sibling(Node *node, Node *sibling) /* * Builds a binary VBVH from a rtbuild */ +template struct BuildBinaryVBVH { MemArena *arena; @@ -84,9 +113,9 @@ struct BuildBinaryVBVH arena = a; } - VBVHNode *create_node() + Node *create_node() { - VBVHNode *node = (VBVHNode*)BLI_memarena_alloc( arena, sizeof(VBVHNode) ); + Node *node = (Node*)BLI_memarena_alloc( arena, sizeof(Node) ); assert( RE_rayobject_isAligned(node) ); node->sibling = NULL; @@ -100,26 +129,26 @@ struct BuildBinaryVBVH return ::rtbuild_heuristic_object_split(builder, 2); } - VBVHNode *transform(RTBuilder *builder) + Node *transform(RTBuilder *builder) { int size = rtbuild_size(builder); if(size == 1) { - VBVHNode *node = create_node(); + Node *node = create_node(); INIT_MINMAX(node->bb, node->bb+3); rtbuild_merge_bb(builder, node->bb, node->bb+3); - node->child = (VBVHNode*) rtbuild_get_primitive( builder, 0 ); + node->child = (Node*) rtbuild_get_primitive( builder, 0 ); return node; } else { - VBVHNode *node = create_node(); + Node *node = create_node(); INIT_MINMAX(node->bb, node->bb+3); rtbuild_merge_bb(builder, node->bb, node->bb+3); - VBVHNode **child = &node->child; + Node **child = &node->child; int nc = rtbuild_split(builder); assert(nc == 2); diff --git a/source/blender/render/intern/source/rayobject_raycounter.c b/source/blender/render/intern/source/rayobject_raycounter.c index 83ba15602da..b47df607c10 100644 --- a/source/blender/render/intern/source/rayobject_raycounter.c +++ b/source/blender/render/intern/source/rayobject_raycounter.c @@ -39,6 +39,9 @@ void RE_RC_INFO(RayCounter *info) printf("BB tests: %llu\n", info->bb.test ); printf("BB hits: %llu\n", info->bb.hit ); printf("\n"); + printf("SIMD BB tests: %llu\n", info->simd_bb.test ); + printf("SIMD BB hits: %llu\n", info->simd_bb.hit ); + printf("\n"); printf("Primitives tests: %llu\n", info->faces.test ); printf("Primitives hits: %llu\n", info->faces.hit ); printf("------------------------------------\n"); @@ -51,6 +54,9 @@ void RE_RC_INFO(RayCounter *info) printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) ); printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) ); printf("\n"); + printf("SIMD tests per ray: %f\n", info->simd_bb.test / ((float)info->raycast.test) ); + printf("SIMD hits per ray: %f\n", info->simd_bb.hit / ((float)info->raycast.test) ); + printf("\n"); printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) ); printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) ); printf("------------------------------------\n"); @@ -64,6 +70,9 @@ void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp) dest->bb.test += tmp->bb.test; dest->bb.hit += tmp->bb.hit; + dest->simd_bb.test += tmp->simd_bb.test; + dest->simd_bb.hit += tmp->simd_bb.hit; + dest->raycast.test += tmp->raycast.test; dest->raycast.hit += tmp->raycast.hit; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 928083620e1..727d5826e49 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -69,21 +69,47 @@ /* only to be used here in this file, it's for speed */ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -RayObject * RE_rayobject_tree_create(int type, int size) __attribute__((noinline)); - -RayObject * RE_rayobject_tree_create(int type, int size) +RayObject * RE_rayobject_create(int type, int size) { -// if(type == R_RAYTRACE_TREE_BIH) - return RE_rayobject_svbvh_create(size); - - if(type == R_RAYTRACE_TREE_BVH) - return RE_rayobject_bvh_create(size); - if(type == R_RAYTRACE_TREE_BIH) - return RE_rayobject_bih_create(size); - if(type == R_RAYTRACE_TREE_BLIBVH) - return RE_rayobject_blibvh_create(size); + if(type == R_RAYSTRUCTURE_AUTO) + { + //TODO +// if(detect_simd()) +// type = R_RAYSTRUCTURE_SIMD_SVBVH; +// else +// type = R_RAYSTRUCTURE_VBVH; + type = R_RAYSTRUCTURE_SIMD_QBVH; + } + + + if(type == R_RAYSTRUCTURE_OCTREE) + { + //TODO dynamic ocres + return RE_rayobject_octree_create(R.r.ocres, size); + } + if(type == R_RAYSTRUCTURE_BLIBVH) + { + return RE_rayobject_blibvh_create(size); + } + if(type == R_RAYSTRUCTURE_VBVH) + { + return RE_rayobject_vbvh_create(size); + } + if(type == R_RAYSTRUCTURE_SIMD_SVBVH) + { + return RE_rayobject_svbvh_create(size); + } + if(type == R_RAYSTRUCTURE_SIMD_QBVH) + { + return RE_rayobject_qbvh_create(size); + } + if(type == R_RAYSTRUCTURE_BIH) + { +// return RE_rayobject_bih_create(size); + } + + return NULL; } #ifdef RE_RAYCOUNTER @@ -205,14 +231,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) } assert( faces > 0 ); - //Create Ray cast accelaration structure - - //TODO dynamic ocres - if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) - raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); - else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH) - raytree = obr->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces ); - + //Create Ray cast accelaration structure + raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces ); face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); obr->rayobi = obi; @@ -239,51 +259,6 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) return obi->obr->raytree; } -/* - * create an hierarchic raytrace structure with all objects - * - * R_TRANSFORMED objects instances reuse the same tree by using the rayobject_instance - */ -static void makeraytree_hier(Render *re) -{ - //TODO - // out-of-memory safeproof - // break render - // update render stats - - ObjectInstanceRen *obi; - int num_objects = 0; - - re->i.infostr="Creating raytrace structure"; - re->stats_draw(re->sdh, &re->i); - - //Count number of objects - for(obi=re->instancetable.first; obi; obi=obi->next) - if(is_raytraceable(re, obi)) - num_objects++; - - //Create raytree - re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, num_objects ); - - for(obi=re->instancetable.first; obi; obi=obi->next) - if(is_raytraceable(re, obi)) - { - RayObject *obj = makeraytree_object(re, obi); - RE_rayobject_add( re->raytree, obj ); - - if(re->test_break(re->tbh)) - break; - } - - if(!re->test_break(re->tbh)) - { - RE_rayobject_done( re->raytree ); - } - - re->i.infostr= NULL; - re->stats_draw(re->sdh, &re->i); -} - static int has_special_rayobject(Render *re, ObjectInstanceRen *obi) { if( (obi->flag & R_TRANSFORMED) ) @@ -337,10 +312,7 @@ static void makeraytree_single(Render *re) } //Create raytree - if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) - raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces ); - else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) - raytree = re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces ); + raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces ); face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); @@ -385,32 +357,8 @@ void makeraytree(Render *re) { float min[3], max[3], sub[3]; int i; - const char *tree_type = "Tree(unknown)"; - re->r.raystructure = R_RAYSTRUCTURE_SINGLE_BVH; -#ifdef RE_RAYCOUNTER - if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BVH) - tree_type = "BVH"; - if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BIH) - tree_type = "BIH"; - if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BLIBVH) - tree_type = "BLIBVH"; - - if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE) - printf("Building single octree\n"); - else if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH) - printf("Building single tree(%s)\n", tree_type); - else if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE) - printf("Building tree(%s) of octrees\n", tree_type); - else - printf("Building tree(%s) of trees(%s)\n", tree_type, tree_type); -#endif - - if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE)) - BENCH(makeraytree_single(re), tree_build); - else - BENCH(makeraytree_hier(re), tree_build); - + BENCH(makeraytree_single(re), tree_build); //Calculate raytree max_size //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights -- cgit v1.2.3 From 6a301de3eb0e4021d892708ead17c55900682e47 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Sep 2009 19:18:12 +0000 Subject: users on blenderartist reported uncompressed TGA loading worked for them where compressed didnt. --- release/io/engine_render_pov.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/io/engine_render_pov.py b/release/io/engine_render_pov.py index c3165d22540..02b8aab4c42 100644 --- a/release/io/engine_render_pov.py +++ b/release/io/engine_render_pov.py @@ -616,7 +616,7 @@ def write_pov_ini(filename_ini, filename_pov, filename_image): file.write('Display=0\n') file.write('Pause_When_Done=0\n') - file.write('Output_File_Type=C\n') # TGA, best progressive loading + file.write('Output_File_Type=T\n') # TGA, best progressive loading file.write('Output_Alpha=1\n') if render.antialiasing: -- cgit v1.2.3 From 7064f6c5d88e17406df1c7c8d1fec20364571084 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sun, 6 Sep 2009 19:51:57 +0000 Subject: Mathutils fix: Vector.reflect * correct function for reflection and moving it to arithb.c * note: 2.5 has an already more elegant solution for it (still wrong, but the code is cleaner). Therefore the merge may need to be manual in that case. Specifically in 2.5 we are doing: if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) return NULL; And there we don't need to create a VectorObject *mirrvec; only to get the values. Code used to test it: http://www.pasteall.org/7654/python * YoFrankie script probably needs to be fixed too. --- source/blender/blenlib/BLI_arithb.h | 1 + source/blender/blenlib/intern/arithb.c | 23 +++++++++++++++++++++++ source/blender/python/api2_2x/vector.c | 31 ++++++------------------------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 86b626dabdf..0c3ec40f16d 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -270,6 +270,7 @@ void AxisAngleToQuat(float *q, float *axis, float angle); void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]); void vectoquat(float *vec, short axis, short upflag, float *q); +void VecReflect(float *out, float *v1, float *v2); void VecBisect3(float *v, float *v1, float *v2, float *v3); float VecAngle2(float *v1, float *v2); float VecAngle3(float *v1, float *v2, float *v3); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index c20794953b9..e7a31e37581 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2981,6 +2981,29 @@ void VecBisect3(float *out, float *v1, float *v2, float *v3) Normalize(out); } +/* Returns a reflection vector from a vector and a normal vector +reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror) +*/ +void VecReflect(float *out, float *v1, float *v2) +{ + float vec[3], normal[3]; + float reflect[3] = {0.0f, 0.0f, 0.0f}; + float dot2; + + VecCopyf(vec, v1); + VecCopyf(normal, v2); + + Normalize(normal); + + dot2 = 2 * Inpf(vec, normal); + + reflect[0] = vec[0] - (dot2 * normal[0]); + reflect[1] = vec[1] - (dot2 * normal[1]); + reflect[2] = vec[2] - (dot2 * normal[2]); + + VecCopyf(out, reflect); +} + /* Return the angle in degrees between vecs 1-2 and 2-3 in degrees If v1 is a shoulder, v2 is the elbow and v3 is the hand, this would return the angle at the elbow */ diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index a7e00e2878a..6a0107142c1 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -277,19 +277,14 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) /*----------------------------Vector.reflect(mirror) ---------------------- return a reflected vector on the mirror normal - ((2 * DotVecs(vec, mirror)) * mirror) - vec - using arithb.c would be nice here */ + vec - ((2 * DotVecs(vec, mirror)) * mirror) +*/ PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) { VectorObject *mirrvec; float mirror[3]; float vec[3]; - float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - float dot2; - - /* for normalizing */ - int i; - float norm = 0.0f; + float reflect[3] = {0.0f, 0.0f, 0.0f}; if (!VectorObject_Check(value)) { PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" ); @@ -302,27 +297,13 @@ PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) if (mirrvec->size > 2) mirror[2] = mirrvec->vec[2]; else mirror[2] = 0.0; - /* normalize, whos idea was it not to use arithb.c? :-/ */ - for(i = 0; i < 3; i++) { - norm += mirror[i] * mirror[i]; - } - norm = (float) sqrt(norm); - for(i = 0; i < 3; i++) { - mirror[i] /= norm; - } - /* done */ - vec[0] = self->vec[0]; vec[1] = self->vec[1]; if (self->size > 2) vec[2] = self->vec[2]; else vec[2] = 0.0; - - dot2 = 2 * vec[0]*mirror[0]+vec[1]*mirror[1]+vec[2]*mirror[2]; - - reflect[0] = (dot2 * mirror[0]) - vec[0]; - reflect[1] = (dot2 * mirror[1]) - vec[1]; - reflect[2] = (dot2 * mirror[2]) - vec[2]; - + + VecReflect(reflect, vec, mirror); + return newVectorObject(reflect, self->size, Py_NEW); } -- cgit v1.2.3 From a6466883250037a502ef2415dcb8e2acc3e9766f Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sun, 6 Sep 2009 20:59:06 +0000 Subject: SVN maintenance. --- source/blender/makesrna/intern/rna_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_test.c b/source/blender/makesrna/intern/rna_test.c index bfaf318018a..988c8f8a539 100644 --- a/source/blender/makesrna/intern/rna_test.c +++ b/source/blender/makesrna/intern/rna_test.c @@ -1,5 +1,5 @@ /** - * $Id: rna_test.c $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 84448173c39317a71a3f9456b5885c3eb653d675 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 Sep 2009 23:15:43 +0000 Subject: 2.5 - Rotation Order Tweaks * Copy Rotation constraint should now work ok with this new code again. Previously, it was the only thing that really went beserk when the typos were still uncaught. * Fixed one other case of a potential case where typos would cause problems. * Made changing the rotation order setting perform conversions of the current rotation to an equivalent representation in the other orders/forms. This is done at RNA level, so maybe not that great for switching representations while animating? --- source/blender/blenkernel/intern/constraint.c | 3 +- source/blender/blenlib/intern/arithb.c | 4 +- source/blender/makesrna/intern/rna_pose.c | 62 +++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e6e65ebd614..0f7767a1808 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1558,8 +1558,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta VECCOPY(loc, cob->matrix[3]); Mat4ToSize(cob->matrix, size); - //Mat4ToEulO(ct->matrix, eul, ct->rotOrder); - Mat4ToEul(ct->matrix, eul); // the version we should be using causes errors... + Mat4ToEulO(ct->matrix, eul, ct->rotOrder); Mat4ToEulO(cob->matrix, obeul, cob->rotOrder); if ((data->flag & ROTLIKE_X)==0) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 7a4aaa1a858..2e60fbba4c9 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2835,10 +2835,10 @@ void EulOToQuat(float e[3], short order, float q[4]) double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; double a[3]; - if (R->parity) e[1] = -e[1]; // xxx watch it! - ti = e[i]/2; tj = e[j]/2; th = e[k]/2; + if (R->parity) e[j] = -e[j]; + ci = cos(ti); cj = cos(tj); ch = cos(th); si = sin(ti); sj = sin(tj); sh = sin(th); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 6c951b5a1b7..c5297f7b7fa 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -130,6 +130,67 @@ static void rna_PoseChannel_euler_rotation_set(PointerRNA *ptr, const float *val VECCOPY(pchan->eul, value); } +static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) +{ + bPoseChannel *pchan= ptr->data; + + /* check if any change - if so, need to convert data */ + // TODO: this needs to be generalised at some point to work for objects too... + if (value > 0) { /* to euler */ + if (pchan->rotmode < 0) { // FIXME: need a define for this + /* axis-angle to euler */ + float m[3][3]; + + /* convert to 3x3 matrix, then to euler + * - axis angle is stored in quats + */ + VecRotToMat3(&pchan->quat[1], pchan->quat[0], m); + Mat3ToEulO(m, pchan->eul, value); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) { + /* quat to euler */ + QuatToEulO(pchan->quat, pchan->eul, value); + } + /* else { no conversion needed } */ + } + else if (value == PCHAN_ROT_QUAT) { /* to quat */ + if (pchan->rotmode < 0) { // FIXME: need a define for this + /* axis angle to quat */ + float q[4]; + + /* copy to temp var first, since quats and axis-angle are stored in same place */ + QuatCopy(q, pchan->quat); + AxisAngleToQuat(q, &pchan->quat[1], pchan->quat[0]); + } + else if (pchan->rotmode > 0) { + /* euler to quat */ + EulOToQuat(pchan->eul, pchan->rotmode, pchan->quat); + } + /* else { no conversion needed } */ + } + else { /* to axis-angle */ + if (pchan->rotmode > 0) { // FIXME: need a define for this + /* euler to axis angle */ + float q[4]; + + /* convert to temp quat, then to axis angle (since stored in same var) */ + EulOToQuat(pchan->eul, pchan->rotmode, q); + QuatToAxisAngle(q, &pchan->quat[1], pchan->quat[0]); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) { + /* quat to axis angle */ + float q[4]; + + /* copy to temp var first, since quats and axis-angle are stored in same place */ + QuatCopy(q, pchan->quat); + QuatToAxisAngle(q, &pchan->quat[1], pchan->quat[0]); + } + } + + /* finally, set the new rotation type */ + pchan->rotmode= value; +} + static void rna_PoseChannel_name_set(PointerRNA *ptr, const char *value) { Object *ob= (Object*)ptr->id.data; @@ -439,6 +500,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "rotmode"); RNA_def_property_enum_items(prop, prop_rotmode_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_PoseChannel_rotation_mode_set", NULL); RNA_def_property_ui_text(prop, "Rotation Mode", ""); RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); -- cgit v1.2.3 From 732bf328c51d630bace201b40ab2bedcb314d96e Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 7 Sep 2009 00:58:17 +0000 Subject: Bug fix (layers and some other checks were disabled) *bug found and isolated by ZanQdo (Daniel Salazar) --- source/blender/render/extern/include/RE_raytrace.h | 3 ++- source/blender/render/intern/source/rayobject.c | 20 +++++++++++++++ source/blender/render/intern/source/rayshade.c | 29 ++++------------------ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index c775a7d18ef..8fc3a96ca99 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -178,7 +178,8 @@ struct Isect #define RE_SKIP_CULLFACE (1 << 0) /* if using this flag then *face should be a pointer to a VlakRen */ -#define RE_SKIP_VLR_NEIGHBOUR (1 << 1) +#define RE_SKIP_VLR_NEIGHBOUR (1 << 1) +#define RE_SKIP_VLR_RENDER_CHECK (1 << 2) /* TODO use: FLT_MAX? */ #define RE_RAYTRACE_MAXDIST 1e33 diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 996be35090e..73711272935 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -141,6 +141,20 @@ static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, return 0; } +#include "DNA_material_types.h" +static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) +{ + /* for baking selected to active non-traceable materials might still + * be in the raytree */ + if(!(vlr->mat->mode & MA_TRACEBLE)) + return 0; + + /* I know... cpu cycle waste, might do smarter once */ + if(is->mode==RE_RAY_MIRROR) + return !(vlr->mat->mode & MA_ONLYCAST); + else + return (is->lay & obi->lay); +} /* ray - triangle or quad intersection */ /* this function shall only modify Isect if it detects an hit */ @@ -154,6 +168,12 @@ static int intersect_rayface(RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; + + if(is->skip & RE_SKIP_VLR_RENDER_CHECK) + { + if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) + return 0; + } RE_RC_COUNT(is->raycounter->faces.test); diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 727d5826e49..8733b89b88a 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -116,25 +116,6 @@ RayObject * RE_rayobject_create(int type, int size) RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {}; #endif -#if 0 -static int vlr_check_intersect(Isect *is, int ob, RayFace *face) -{ - ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob); - VlakRen *vlr = (VlakRen*)face; - - /* for baking selected to active non-traceable materials might still - * be in the raytree */ - if(!(vlr->mat->mode & MA_TRACEBLE)) - return 0; - - /* I know... cpu cycle waste, might do smarter once */ - if(is->mode==RE_RAY_MIRROR) - return !(vlr->mat->mode & MA_ONLYCAST); - else - return (is->lay & obi->lay); -} -#endif - void freeraytree(Render *re) { ObjectInstanceRen *obi; @@ -602,7 +583,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo VECCOPY(isec.vec, vec ); isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST; isec.mode= RE_RAY_MIRROR; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; + isec.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK; isec.hint = 0; isec.orig.ob = obi; @@ -1725,7 +1706,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac) RE_RC_INIT(isec, *shi); isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; + isec.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK; isec.hint = 0; isec.hit.ob = 0; @@ -1866,7 +1847,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) RE_RC_INIT(isec, *shi); isec.orig.ob = shi->obi; isec.orig.face = shi->vlr; - isec.skip = RE_SKIP_VLR_NEIGHBOUR; + isec.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK; isec.hint = 0; isec.hit.ob = 0; @@ -2087,7 +2068,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * RE_rayobject_hint_bb( R.raytree, &bb_hint, min, max); isec->hint = &bb_hint; - isec->skip = RE_SKIP_VLR_NEIGHBOUR; + isec->skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK; VECCOPY(vec, lampco); while (samples < max_samples) { @@ -2256,7 +2237,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa isec->vec[1] = vec[1]+lampco[1]-isec->start[1]; isec->vec[2] = vec[2]+lampco[2]-isec->start[2]; isec->labda = 1.0f; - isec->skip = RE_SKIP_VLR_NEIGHBOUR; + isec->skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK; if(isec->mode==RE_RAY_SHADOW_TRA) { /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */ -- cgit v1.2.3 From f5e80e7a80feb4b516792b961c2310210536aef8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Sep 2009 04:52:42 +0000 Subject: Operator docstring patch from Ron Walker, added console operator docs too. --- release/ui/space_console.py | 4 ++-- source/blender/editors/interface/view2d_ops.c | 11 +++++++++++ source/blender/editors/space_view3d/view3d_buttons.c | 1 + source/blender/editors/space_view3d/view3d_edit.c | 2 +- source/blender/editors/space_view3d/view3d_header.c | 1 + source/blender/editors/space_view3d/view3d_select.c | 4 ++++ source/blender/editors/space_view3d/view3d_snap.c | 7 +++++++ source/blender/editors/space_view3d/view3d_toolbar.c | 1 + source/blender/editors/space_view3d/view3d_view.c | 3 +++ 9 files changed, 31 insertions(+), 3 deletions(-) diff --git a/release/ui/space_console.py b/release/ui/space_console.py index dbf202f924c..136082a285a 100644 --- a/release/ui/space_console.py +++ b/release/ui/space_console.py @@ -108,7 +108,7 @@ def get_console(console_id): class CONSOLE_OT_exec(bpy.types.Operator): ''' - Operator documentatuon text, will be used for the operator tooltip and python docs. + Execute the current console line as a python expression. ''' __idname__ = "console.execute" __label__ = "Console Execute" @@ -385,7 +385,7 @@ def autocomp(bcon): class CONSOLE_OT_autocomplete(bpy.types.Operator): ''' - Operator documentatuon text, will be used for the operator tooltip and python docs. + Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one. ''' __idname__ = "console.autocomplete" __label__ = "Console Autocomplete" diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index f3610769d17..3e009884dee 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -257,6 +257,7 @@ void VIEW2D_OT_pan(wmOperatorType *ot) { /* identifiers */ ot->name= "Pan View"; + ot->description= "Pan the view."; ot->idname= "VIEW2D_OT_pan"; /* api callbacks */ @@ -305,6 +306,7 @@ void VIEW2D_OT_scroll_right(wmOperatorType *ot) { /* identifiers */ ot->name= "Scroll Right"; + ot->description= "Scroll the view right."; ot->idname= "VIEW2D_OT_scroll_right"; /* api callbacks */ @@ -351,6 +353,7 @@ void VIEW2D_OT_scroll_left(wmOperatorType *ot) { /* identifiers */ ot->name= "Scroll Left"; + ot->description= "Scroll the view left."; ot->idname= "VIEW2D_OT_scroll_left"; /* api callbacks */ @@ -396,6 +399,7 @@ void VIEW2D_OT_scroll_down(wmOperatorType *ot) { /* identifiers */ ot->name= "Scroll Down"; + ot->description= "Scroll the view down."; ot->idname= "VIEW2D_OT_scroll_down"; /* api callbacks */ @@ -442,6 +446,7 @@ void VIEW2D_OT_scroll_up(wmOperatorType *ot) { /* identifiers */ ot->name= "Scroll Up"; + ot->description= "Scroll the view up."; ot->idname= "VIEW2D_OT_scroll_up"; /* api callbacks */ @@ -575,6 +580,7 @@ void VIEW2D_OT_zoom_in(wmOperatorType *ot) { /* identifiers */ ot->name= "Zoom In"; + ot->description= "Zoom in the view."; ot->idname= "VIEW2D_OT_zoom_in"; /* api callbacks */ @@ -611,6 +617,7 @@ void VIEW2D_OT_zoom_out(wmOperatorType *ot) { /* identifiers */ ot->name= "Zoom Out"; + ot->description= "Zoom out the view."; ot->idname= "VIEW2D_OT_zoom_out"; /* api callbacks */ @@ -857,6 +864,7 @@ void VIEW2D_OT_zoom(wmOperatorType *ot) { /* identifiers */ ot->name= "Zoom View"; + ot->description= "Zoom in/out the view."; ot->idname= "VIEW2D_OT_zoom"; /* api callbacks */ @@ -958,6 +966,7 @@ void VIEW2D_OT_zoom_border(wmOperatorType *ot) { /* identifiers */ ot->name= "Zoom to Border"; + ot->description= "Zoom in the view to the nearest item contained in the border."; ot->idname= "VIEW2D_OT_zoom_border"; /* api callbacks */ @@ -1297,6 +1306,7 @@ void VIEW2D_OT_scroller_activate(wmOperatorType *ot) { /* identifiers */ ot->name= "Scroller Activate"; + ot->description= "Scroll view by mouse click and drag."; ot->idname= "VIEW2D_OT_scroller_activate"; /* flags */ @@ -1363,6 +1373,7 @@ void VIEW2D_OT_reset(wmOperatorType *ot) { /* identifiers */ ot->name= "Reset View"; + ot->description= "Reset the view."; ot->idname= "VIEW2D_OT_reset"; /* api callbacks */ diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index c854de8e54d..39e90a37b3f 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1451,6 +1451,7 @@ static int view3d_properties(bContext *C, wmOperator *op) void VIEW3D_OT_properties(wmOperatorType *ot) { ot->name= "Properties"; + ot->description= "Display the properties panel."; ot->idname= "VIEW3D_OT_properties"; ot->exec= view3d_properties; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index a7ea19e49f9..bbcee0415f8 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1895,7 +1895,7 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot) /* identifiers */ ot->name= "3D Manipulator"; - ot->description = ""; + ot->description = "Manipulate selected item by axis."; ot->idname= "VIEW3D_OT_manipulator"; /* api callbacks */ diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index b6159cf4314..45b0ea41215 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -252,6 +252,7 @@ void VIEW3D_OT_layers(wmOperatorType *ot) { /* identifiers */ ot->name= "Layers"; + ot->description= "Toggle layer(s) visibility."; ot->idname= "VIEW3D_OT_layers"; /* api callbacks */ diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 5c6a22f5157..42954e09060 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -756,6 +756,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) void VIEW3D_OT_select_lasso(wmOperatorType *ot) { ot->name= "Lasso Select"; + ot->description= "Select items using lasso selection."; ot->idname= "VIEW3D_OT_select_lasso"; ot->invoke= WM_gesture_lasso_invoke; @@ -1534,6 +1535,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) { /* identifiers */ ot->name= "Border Select"; + ot->description= "Select items using border selection."; ot->idname= "VIEW3D_OT_select_border"; /* api callbacks */ @@ -1593,6 +1595,7 @@ void VIEW3D_OT_select(wmOperatorType *ot) { /* identifiers */ ot->name= "Activate/Select"; + ot->description= "Activate/select item(s)."; ot->idname= "VIEW3D_OT_select"; /* api callbacks */ @@ -1831,6 +1834,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) void VIEW3D_OT_select_circle(wmOperatorType *ot) { ot->name= "Circle Select"; + ot->description= "Select items using circle selection."; ot->idname= "VIEW3D_OT_select_circle"; ot->invoke= WM_gesture_circle_invoke; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 2e5696170e2..73b70ccb532 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -555,6 +555,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Selection to Grid"; + ot->description= "Snap selected item(s) to nearest grid node."; ot->idname= "VIEW3D_OT_snap_selected_to_grid"; /* api callbacks */ @@ -680,6 +681,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Selection to Cursor"; + ot->description= "Snap selected item(s) to cursor."; ot->idname= "VIEW3D_OT_snap_selected_to_cursor"; /* api callbacks */ @@ -715,6 +717,7 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Cursor to Grid"; + ot->description= "Snap cursor to nearest grid node."; ot->idname= "VIEW3D_OT_snap_cursor_to_grid"; /* api callbacks */ @@ -821,6 +824,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Cursor to Selected"; + ot->description= "Snap cursor to center of selected item(s)."; ot->idname= "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ @@ -870,6 +874,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Cursor to Active"; + ot->description= "Snap cursor to active item."; ot->idname= "VIEW3D_OT_snap_cursor_to_active"; /* api callbacks */ @@ -1069,6 +1074,7 @@ void VIEW3D_OT_snap_selected_to_center(wmOperatorType *ot) /* identifiers */ ot->name= "Snap Selection to Center"; + ot->description= "Snap selected items to selections geometric center."; ot->idname= "VIEW3D_OT_snap_selected_to_center"; /* api callbacks */ @@ -1135,6 +1141,7 @@ void VIEW3D_OT_snap_menu(wmOperatorType *ot) { /* identifiers */ ot->name= "Snap Menu"; + ot->description= "Display snap menu."; ot->idname= "VIEW3D_OT_snap_menu"; /* api callbacks */ diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index c87dd0b7948..58248f675da 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -322,6 +322,7 @@ static int view3d_toolbar(bContext *C, wmOperator *op) void VIEW3D_OT_toolbar(wmOperatorType *ot) { ot->name= "Toolbar"; + ot->description= "Toggles toolbar display."; ot->idname= "VIEW3D_OT_toolbar"; ot->exec= view3d_toolbar; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index de8166b372b..808d1635b37 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -415,6 +415,7 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot) /* identifiers */ ot->name= "Align Camera To View"; + ot->description= "Set camera view to active view."; ot->idname= "VIEW3D_OT_camera_to_view"; /* api callbacks */ @@ -1395,6 +1396,7 @@ void VIEW3D_OT_localview(wmOperatorType *ot) /* identifiers */ ot->name= "Local View"; + ot->description= "Toggle display of selected object(s) seperately and centered in view."; ot->idname= "VIEW3D_OT_localview"; /* api callbacks */ @@ -1562,6 +1564,7 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) /* identifiers */ ot->name= "Start Game Engine"; + ot->description= "Start game engine."; ot->idname= "VIEW3D_OT_game_start"; /* api callbacks */ -- cgit v1.2.3 From 183c8e0a0a82f260c4db250f4b04bb3f650618c3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Sep 2009 07:42:12 +0000 Subject: no functional changes, use hole rather then dutch 'gat' for bevel lists and made some comments English. --- source/blender/blenkernel/intern/curve.c | 10 +++++----- source/blender/imbuf/intern/anim5.c | 10 +++++----- source/blender/include/BIF_oops.h | 2 +- source/blender/makesdna/DNA_curve_types.h | 2 +- source/blender/src/editlattice.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 25af0cb5ce3..a1ad5347f7e 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1783,14 +1783,14 @@ void makeBevelList(Object *ob) bl= blnext; } - /* STEP 3: COUNT POLYS TELLEN AND AUTOHOLE */ + /* STEP 3: POLYS COUNT AND AUTOHOLE */ bl= cu->bev.first; poly= 0; while(bl) { if(bl->nr && bl->poly>=0) { poly++; bl->poly= poly; - bl->gat= 0; /* 'gat' is dutch for hole */ + bl->hole= 0; } bl= bl->next; } @@ -1842,7 +1842,7 @@ void makeBevelList(Object *ob) sd1= sortdata+ (a-1); for(b=a-1; b>=0; b--, sd1--) { /* all polys to the left */ if(bevelinside(sd1->bl, bl)) { - bl->gat= 1- sd1->bl->gat; + bl->hole= 1- sd1->bl->hole; break; } } @@ -1852,7 +1852,7 @@ void makeBevelList(Object *ob) if((cu->flag & CU_3D)==0) { sd= sortdata; for(a=0; abl->gat==sd->dir) { + if(sd->bl->hole==sd->dir) { bl= sd->bl; bevp1= (BevPoint *)(bl+1); bevp2= bevp1+ (bl->nr-1); @@ -2033,7 +2033,7 @@ void makeBevelList(Object *ob) } QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ VECCOPY(vec_prev, vec); - + AxisAngleToQuat(q, vec, bevp1->alfa); QuatMul(quat, q, quat); QuatToMat3(quat, bevp1->mat); diff --git a/source/blender/imbuf/intern/anim5.c b/source/blender/imbuf/intern/anim5.c index b6f29b6a145..2437d0d9568 100644 --- a/source/blender/imbuf/intern/anim5.c +++ b/source/blender/imbuf/intern/anim5.c @@ -204,12 +204,12 @@ static void anim5decode(struct ImBuf * ibuf, uchar * dlta) { int *ofspoint; uchar **planes; - /* samenstelling delta: - lijst met ofsets voor delta's per bitplane (ofspoint) - per kolom in delta (point) - aantal handelingen (noops) + /* composition delta: + list with ofsets for delta' s by bitplane (ofspoint) + by column in delta (point) + number of operations (noops) code - bijbehorende data + associated data ... ... */ diff --git a/source/blender/include/BIF_oops.h b/source/blender/include/BIF_oops.h index 2375a918d0e..c35acf584f1 100644 --- a/source/blender/include/BIF_oops.h +++ b/source/blender/include/BIF_oops.h @@ -61,7 +61,7 @@ struct Oops *add_test_oops(void *id); /* incl links */ void add_texture_oops(struct Material *ma); void build_oops(void); struct Oops *find_oops(ID *id); -void free_oops(struct Oops *oops); /* ook oops zelf */ +void free_oops(struct Oops *oops); /* also oops themselves */ void free_oopspace(struct SpaceOops *so); void new_oops_location(struct Oops *); int oops_test_overlap(struct Oops *test); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 88c03a41160..60dba9ce018 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -61,7 +61,7 @@ typedef struct Path { typedef struct BevList { struct BevList *next, *prev; int nr, flag; - short poly, gat; + short poly, hole; } BevList; /* These two Lines with # tell makesdna this struct can be excluded. */ diff --git a/source/blender/src/editlattice.c b/source/blender/src/editlattice.c index 06b092a30ac..a65c51c76f6 100644 --- a/source/blender/src/editlattice.c +++ b/source/blender/src/editlattice.c @@ -25,7 +25,7 @@ * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** - * i.t.t. wat de naam doet vermoeden: ook algemene lattice (calc) functies + * what the name suggests: also general lattice (calc) functions */ #include -- cgit v1.2.3 From 10c18d72f49738d6b4caef3bfff7af87927e5d26 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 7 Sep 2009 09:43:04 +0000 Subject: * Another handful of brilliant new icons by jendryzch --- release/datafiles/blenderbuttons | Bin 179274 -> 182512 bytes source/blender/editors/datafiles/blenderbuttons.c | 11309 ++++++++++--------- source/blender/editors/include/UI_icons.h | 14 +- source/blender/editors/space_image/image_buttons.c | 8 +- source/blender/makesrna/intern/rna_brush.c | 4 + source/blender/makesrna/intern/rna_gpencil.c | 2 +- source/blender/makesrna/intern/rna_modifier.c | 2 +- source/blender/makesrna/intern/rna_scene.c | 8 +- 8 files changed, 5726 insertions(+), 5621 deletions(-) diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons index 98c321cd954..79d6138e3f0 100644 Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ diff --git a/source/blender/editors/datafiles/blenderbuttons.c b/source/blender/editors/datafiles/blenderbuttons.c index 722e3ada57b..cfd526d82ef 100644 --- a/source/blender/editors/datafiles/blenderbuttons.c +++ b/source/blender/editors/datafiles/blenderbuttons.c @@ -1,5609 +1,5710 @@ /* DataToC output of file */ -int datatoc_blenderbuttons_size= 179274; +int datatoc_blenderbuttons_size= 182512; char datatoc_blenderbuttons[]= { -137, 80, 78, 71, 13, 10, 26, 10, 0, 0, - 0, 13, 73, 72, 68, 82, 0, 0, 2, 88, 0, 0, 2,128, 8, 6, 0, 0, 0, 64, 11, 6,158, 0, 0, 0, 9,112, 72, 89,115, 0, - 0, 13,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 10, 79,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, - 67, 32,112,114,111,102,105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, 75,136,128,148, 75,111, 82, - 21, 8, 32, 82, 66,139,128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69, 4, 27,200,160,136, 3,142, -142,128,140, 21, 81, 44, 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107,214,188,247,230,205,254,181, -215, 62,231,172,243,157,179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131,199,196,198,225,228, 46, 64, -129, 10, 36,112, 0, 16, 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, 7,190, 0, 1,120,211, 11, 8, 0,192, - 77,155,192, 48, 28,135,255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,128, 20, 0, 64,122,142, 66,166, 0, 64, - 70, 1,128,157,152, 38, 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,127,230,211, 0,128,157,248,153,123, 1, - 0, 91,148, 33, 21, 1,160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, 69, 0, 88, 48, 0, 20,102, 75,196, 57, - 0,216, 45, 0, 48, 73, 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, 48, 81,136,133, 41, 0, 4,123, 0, 96, -200, 35, 35,120, 0,132,153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,153,178, 60,185, 36, 57, 69,129, 91, 8, - 45,113, 7, 87, 87, 46, 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,153, 25, 50,129, 52, 15,224,243,204, 0, - 0,160,145, 21, 17,224,131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191, 6,255, 34, 98, 98,227,254,229,207, -171,112, 64, 0, 0,225,116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,238, 4,104, 94, 11,160,117,247,139,102, -178, 15, 64,181, 0,160,233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, 74,196, 66, 91, 97,202, 87, -125,254,103,194, 95,192, 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71, 4,248,224,194,204,244, 76,165, - 28,207,146, 9,132, 98,220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20,227, 81, 18,113,142, 68,154, -140,243, 50,165, 34,137, 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, 0,176,106, 62, 1,123,145, 45,168, 93, - 99, 3,246, 75, 39, 16, 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,104,131,225,207,119,255,239, 63,253, 71, -160, 37, 0,128,102, 73,146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, 68,160,129, 42,176, 65, 27,244,193, 24, - 44,192, 6, 28,193, 5,220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, 96, 41,172,130, 66, 40,134, -205,176, 29, 42, 96, 47,212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15,250, 97, 8,158,193, 40,188, -129, 9, 4, 65,200, 8, 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, 33,193, 72, 4, 18,139, 36, 32,201,136, - 20, 81, 34, 75,145, 53, 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, 70,186,145, 59,200, 0, 50,130,252,134, -188, 71, 49,148,129,178, 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154,143, 22,160,155,208,114,180, - 26, 61,140, 54,161,231,208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,108, 48, 46,198,195, 66,177, 56, 44, 9, -147, 99,203,177, 34,172, 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, 18,129, 69,192, 9, 54, 4,119, 66, 32, - 97, 30, 65, 72, 88, 76, 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, 81,194, 39, 34,147,168, 75,180, 38,186, - 17,249,196, 24, 98, 50, 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18,137, 67, 50, 39,185,144, 2, - 73,177,164, 84,210, 18,210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107,178, 7, 57,148, 44, 32, 43, -200,133,228,157,228,195,228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82,202,106, 74, 25,229, 16,229, - 52,229, 6,101,152, 50, 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, 81,135,168, 19, 52,117,154, - 57,205,131, 22, 73, 75,165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, 78,151,208, 87,210,203,233, - 71,232,151,232, 3,244,119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, 25,119, 24,175,152, 76,166, 25,211,139, - 25,199, 84, 48, 55, 49,235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74,149, 38,149, 27, 42, 47, 84, -169,170,166,170,222,170, 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169, 9,212,150,171, 85,170,157, 80, -235, 83, 27, 83,103,169, 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,195, 76,195, 79, 67,164, 81,160,177, 95, -227,188,198, 32, 11, 99, 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, 42,187,152,253, 29,187,139, - 61,170,169,161, 57, 67, 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,116, 78, 9,231, 40,167,151,243,126,138, -222, 20,239, 41,226, 41, 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, 71,235,189, 54,174,237,167, -157,166,189, 69,187, 89,251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, 83,217, 83,221,167, 10,167, 22, 77, 61, - 58,245,174, 46,170,107,165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167,222,121,189,231,250, 28,125, - 47,253, 84,253,109,250,167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, 53,113,111, 60, 29, 47,199,219,241, 81, - 67, 93,195, 64, 67,165, 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, 92,227, 36,227,109,198,109, -198,163, 38, 6, 38, 33, 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205,204,205,162,205,214,153, 53, -155, 61, 49,215, 50,231,155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178,228, 90,166, 89,238,182,188, -110,133, 90, 57, 89,165, 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78,147, 78,171,158,214,103,195, -176,241,182,201,182,169,183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197,174,195,238,147,189,147,125, -186,125,141,253, 61, 7, 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206,156,238, 63,125,197,244,150, -233, 47,103, 88,207, 16,207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185,115,131,243,136,139,137, 75, -130,203, 46,151, 62, 46,155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179,155,194,237,168,219,175,238, - 54,238,105,238,135,220,159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11,159,149, 48,107,223,172,126, - 79, 67, 79,129,103,181,231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62,246, 62,114,159,227, 62,227, - 60, 55,222, 50,222, 89, 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255,100,255,122,255,209, 0,167, -128, 37, 1,103, 3,137,129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217,237, 65,140,160,185, 65, 21, - 65,143,130,173,130,229,193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80,126,232,214,208, 7, 97,230, - 97,139,195,126, 12, 39,133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67,115,223, 68,250, 68,150, 68, -222,155,103, 49, 79, 57,175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, 89,204,213, 88,157, 88, 73, -108, 75, 28, 57, 46, 42,174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47,200, 93,112,121,161,206,194, -244,133,167, 22,169, 46, 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, 19,119, 37,142, 10,121,194, - 29,194,103, 34, 47,209, 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53,121, 36,197, 51,165, 44,229, -185,132, 39,169,144,188, 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146,145,144,113, 66,170, 33, 77, -147,182,103,234,103,230,102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,201,107,179,144,172, 5, 89, 45, 10,182, - 66,166,232, 84, 90, 40,215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237,204,179,202,219,144, 55,156, -239,159,255,237, 18,194, 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113,121,219, 10,227, 21, 5, 43, -134, 86, 6,172, 60,184,138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94,193,202,130,193,181, 1,107, -235, 11, 85, 10,229,133,125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21,137,138,174, 20,219, 23,151, - 21,127,216, 40,220,120,229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222, 45,158, 91, 14, -150,170,151,230,151, 14,110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219,187,131,182, 67,185,163,191, - 60,184,188,101,167,201,206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248,110,209,238, 27,123,188,246, - 52,236,213,219, 91,188,247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,251,179,247, 63,174,137,170,233,248,150, -251,109, 93,173, 78,109,113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,210, 61, 84, 82,143,214, 43,235, 71, 14, -199, 31,190,254,157,239,119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,247, 9,223,247, 30, 13, 58,218,118,140, -123,172,225, 7,211, 31,118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, 79,204, 62,209,214,234,222, -122,252, 71,219, 31, 15,156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126, 46,249, -220, 96,219,162,182,123,231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, 59,206, 92,242,184,116,242, -178,219,229, 19, 87,184, 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154,174,185, 92,107,185,238,122, -189,181,123,102,247,233, 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243,122,111,247,197,247,245,223, - 22,221,126,114, 39,253,206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221,135,213, 63, 91,254,220,216, -239,220,127,106,192,119,160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, 5,143,153,143,203,134, 13,134,235,158, - 56, 62, 57, 57,226, 63,114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, 47,126,248,213,235,215,206, -209,152,209,161,151,242,151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,251, -237,193,119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251,147, 25,147,147,255, 4, 3, -152,243,252, 99, 51, 45,219, 0, 0, 0, 4,103, 65, 77, 65, 0, 0,177,142,124,251, 81,147, 0, 0, 0, 32, 99, 72, 82, 77, 0, - 0,122, 37, 0, 0,128,131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234, 96, 0, 0, 58,152, 0, 0, 23,111,146, - 95,197, 70, 0, 2,177,101, 73, 68, 65, 84,120,218,236,157,119,120, 20,197, 31,198,223,217,221,235,119,233, 33, 29, 82,168,129, -208,123, 9,189,137, 52, 5,233, 42, 88, 0, 5, 20,165,217, 16, 68,176,162,128, 74, 87, 17, 16, 17,164, 42,210,165, 55, 9,189, -183, 0,105,164,215,235,101,231,247, 71,114,247,187,132, 36,119, 1, 68,132,249, 60,207, 62, 87,118,239,189,153,221,217,217,119, -191, 83,150, 80, 74,193, 96, 48, 24, 12, 6,131,193,120,112,112,108, 23, 48, 24, 12, 6,131,193, 96,252,135, 12, 22, 33,164, 51, -211,100,154, 76,147,105, 50, 77,166,201, 52,153, 38, 51, 88, 12, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48, -152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, - 6,131,193, 96, 48, 24,143, 7,132, 77, 52,202, 96, 48, 24, 12, 6,131,241, 96, 17,202, 90,209,168, 81,163,223, 21, 10, 69,181, -178,214,235,116,186,148, 83,167, 78,117, 96,187,144,193, 96,184,188,147, 35,132,195,255, 35,230, 34, 0, 74,217,221, 29,131,193, -120, 18, 13,150, 84, 42,141,218,183,111, 95, 13, 81, 20, 97,179,217, 96,181, 90, 29,175, 38,147, 9,253,250,245, 19, 42,250,103, - 13, 26, 52,216,199,113, 92, 68, 69,126, 99,179,217,110,159, 62,125,186, 77, 89,235, 3, 3, 3, 15, 1,136, 34,132,216, 43,242, - 82, 95, 1,128,227, 28, 45,162,201, 9, 9, 9,141,202,211, 36,132, 68, 57, 93, 28,238,210,178,191,119, 87,179, 86,173, 90,199, - 5, 65, 8, 43,249,251,210, 62,219,223,139,162,120,227,236,217,179,173, 88, 49,125, 56, 52,104,208, 96, 31,207,243, 21, 46,159, -167, 78,157, 42,179,124,214,173, 91,247, 36,199,113, 33,165, 29,227,210,142, 57, 0,222,102,179, 93, 62,125,250,116,155,178, 12, - 72,112,112,240, 33, 0, 81,229,149,157, 18,101, 19, 0, 18, 19, 18, 18,154,184, 58,143,202, 59,135, 74, 41,243,229,106, 58,155, -171,208,208,208, 79, 43, 85,170, 52, 90,167,211, 25, 0, 80,158,231,105,237,218,181,139,237, 7,155,205,150,126,241,226,197,186, -172, 36, 50, 24,140,199,218, 96,137,162,200, 25,141, 70, 92,185,114, 5,165,213,243, 28,199,217, 42,250,103,148,210, 26,187, 86, -173, 8, 80, 86, 10,132,205, 98,134,220,175,146, 67, 59,231,226, 57,136,102, 51,108,102, 19,252,155,180,176, 87,184,232,208,161, - 3,239, 66, 54,236,173,183,222, 10,240,240,240,128,193, 96,128,193, 96,128,209,104,132,193, 96,128,201,100,130,201,100,130,217, -108,134,217,108,134,213,106,133,209,104,196,153, 51,103,108, 46, 46, 8, 97,227,198,141, 11,240,244,244,116,232,217, 23,187,166, - 93,215, 98,177,192, 96, 48,224,220,185,115,229,106, 10,130, 16,118,226,196,137, 0,169, 84, 10, 74, 41, 68, 81, 4,165,180,216, - 82,146, 86,173, 90,153, 89, 17,125,168,212,216,240,249,172, 0,185,175, 31, 68,139, 5,126, 13, 26,219,203, 45,146,119,111,131, -205,108,134,104,177, 32,188,215,179,142,239,219,181,107,231,170,124,134,255, 54,245, 29,111,169,135, 7,172, 6, 3, 34,123, 62, -227, 88,113,126,225, 28,136, 22, 51,168,197,140,122,111,189, 15, 0,200,200,200,208, 71, 71, 71, 39, 3, 32, 0,202,138,240,132, -221,184,113, 35,192,158,134,210, 76,191,243,114,240,224, 65, 12, 29, 58,212, 85,222,195,222,123,239,189, 0,251, 57, 82,178,156, - 91,173, 86,199,171,213,106,133,193, 96,192,201,147, 39,221,138, 92, 5, 7, 7,127, 22, 27, 27, 59, 98,229,202,149,234, 13, 27, - 54,168, 35, 34, 34, 32,149, 74,193,243, 60,120,158, 7,199,113, 16, 4, 1,189,123,247, 38,172, 8, 50, 24,140,199,222, 96,153, -205,230,248,174, 93,187, 82, 0, 48,153, 76,161, 50,153, 76, 90,194,128,133,180,110,221,250,114,201,223,185,106, 58, 84, 86, 10, -196, 15,145,190, 0,128,231,174,103, 58, 46, 12,107, 99, 27, 56,182, 25,124, 43,183,112, 91,165, 18, 28,199, 17, 23, 21, 56,212, -106, 53,186,116,233, 2,153, 76,134, 38, 77,154, 64, 34,145,148,186, 72,165, 82, 72, 36,146,187,162, 71,165,161,209,104, 48,125, -250,116,187, 57,130, 90, 33,199,216, 86, 77,160, 0,197,226,115, 87, 97, 18, 41, 4, 65,112, 44,238,104, 74,165, 82,156, 61,123, - 22,130, 32,128,231,121,199,171,253,253,166, 77,155,208,191,127,127, 8,130, 0,165, 82,137,162,139, 44,227, 33,162,240,243,199, -218,182, 13, 1, 0, 67, 19,242, 29,101,236,207,129, 61, 29,219, 60,159,164, 5, 33, 4, 82,169,212,189,227,238,225,129, 45,253, -159, 2, 0, 60,123, 37, 13, 18,137, 4,130, 32,224,204, 87, 31, 67, 34,147, 65,144, 74, 81,239,173,247,145,145,145,161,127,230, -153,103, 14, 40, 20,138,109,110,220,172, 32, 33, 33, 1,130, 32,148, 89,222, 57,142,195,178,101,203,112,235,214, 45,183,242,174, -215,235,241,201, 39,159,128, 16, 82,236,124, 41,235,189,171,188, 19, 66,184,160,160,160,143, 99, 99, 99,135,173, 92,185,210,135, - 16,130,111,191,253, 22, 82,169, 20, 61,122,244,128,159,159, 31,182,111,223, 14,169, 84,138, 73,147, 38,177,194,199, 96, 48,158, - 12,131,117,234,212,169,167,236,239, 91,180,104,113,241,192,129, 3,181,156, 66,249,176, 90,173, 82,171,213, 90,195,222,108,104, -191,243, 29, 60,120,112,185,119,244, 54,139,249, 46,131, 84, 90, 69,237,206,133,203,201, 12, 98,192,128, 1, 0, 80,230,197,198, -121,113,227,174, 27, 38,147, 9,130, 32,160,102,229, 74,248,160, 91, 67, 52,163, 22,104, 11, 8,172,185, 90,244,209, 88,112,177, -118, 35, 44,186,157,142, 91,121, 5, 16, 4,247, 90, 75, 69, 81, 44,211, 92,241, 60,143, 5, 11, 22, 96,208,160, 65,224,121,190, -204,253,194,248,103,177,153,205, 46,203, 97, 69,143,141,213, 96, 40,140, 44, 9,188,195, 92, 73, 36, 18, 72,228,114, 8, 82, 41, - 4,153, 20, 25, 25, 25,250,206,157, 59, 31,145,201,100, 63, 5, 6, 6, 38, 39, 38, 38,150, 91, 62, 41,165,197,181, 74,185,153, -248,241,199, 31,177,124,249,114, 52,111,222,220, 29, 51, 4,147,201, 4,169, 84,138,143, 63,254,248,174,245, 11, 23, 46,188,203, - 96,185,208, 35, 0,184,192,192,192,215, 86,173, 90,229,105,255,127,127,127,127, 72, 36, 18,212,173, 91, 23, 30, 30, 30, 56,112, -224, 0,108, 54,155,219, 55, 62, 12, 6,131,241,159, 55, 88, 37,140, 1,103, 52, 26,113,233,210, 37,184,234,151, 74, 41, 45,183, -150,148,251, 85,114, 68,174,214, 84,245,115,124, 63,232,102,142,227,194,181,165, 89, 53,200, 52,106, 52,249,240, 11,183,205, 80, - 90, 90,154,227,206,219,213,226, 78, 69,110, 50,153,160, 82, 42,176,115,124, 93, 36,100,202, 48,237,112, 22,254, 56,117, 13, 18, -137, 4,221,107,215,197, 83, 82, 15,188, 31, 46,195,248,171, 55, 97,161,212,173, 11, 24,165,180, 84, 99,101,127,111,111, 42,177, - 27, 44,198,195,199,175, 65, 99, 71,228,106,101,101,143,187,162, 86, 0,176,169, 81, 4,228, 30, 26,212,125, 99,138, 91,229, 51, -178,231, 51,142,200,213, 31,141, 35,193, 75, 36,144,200,100,120,238,108, 18,128,194,102,193, 14,117,163,247,230,240,178,101,195, -134, 13,139,255,235,175,191,148,238,164,181, 52,131,101, 55, 63, 63,254,248, 35, 86,172, 88, 1, 65, 16, 96, 54,155,221, 74,167, -209,104, 44,211, 56,221, 75, 4, 11, 0,116, 58,157,105,227,198,141,248,230,155,111,224,231,231,135,174, 93,187, 34, 56, 56, 24, -107,214,172, 1,165, 20, 99,198,140,129, 82,169,132, 82,169,100,101,158,193, 96, 60,121, 6,203,108, 54,199,119,238,220,217,173, - 17, 63,122,189,254,142, 11, 3, 86,106,100,192, 57, 42, 32,247,208, 64,174,209,128,115,115,150, 46,139,197,226, 48, 40, 59,118, -236,128, 82,169, 68,143, 30, 61,238, 43,130,101, 54,155, 33,147, 74,192,249, 7,226,133,175,255, 66,102,190,222,113, 65,219,115, - 35, 30, 39, 82,211, 48,190,101, 39,168,149,105, 40, 48,153,220,142, 96,149, 52, 87,130, 32, 96,192,128, 1, 48, 26,141, 32,132, - 20,235,151,226,202,172, 50,254, 57,202, 26,132, 64, 8,129,194,211, 3, 50,181, 26, 60,207,187,165,229, 28,109, 18,100, 50, 72, -228, 50, 8, 69,229,208, 30,185,202,225,101,203,146,146,146,142, 0, 80, 52,107,214, 76,233, 78,218,156, 13,150,179, 1,114, 54, - 87, 60,207,195, 98,177,184,101, 94,140, 70, 35,164,210,255,247, 4,184,125,251,118,185, 6,203, 69,158, 41, 33, 68, 36,132,136, - 81, 81, 81,142,223, 6, 5, 5,193,219,219, 27,162, 40, 66, 20, 69, 40, 20, 10, 40,149,202, 98,255,203, 96, 48, 24, 79,140,193, -114,110, 46,124, 80, 23,175,242, 46, 96, 74, 79, 79, 72,213,106,251,104, 37,234,142, 25,178,247, 57, 25, 61,122,116,185,253, 82, -236, 70,204, 13, 83, 9, 78,224,145, 18, 20, 9, 27,183,255,255, 23,200,162,133, 19, 36,184, 21, 84, 11,252,165,147,144,136,162, - 91, 23,176,146, 17,172, 49, 99,198, 96,201,146, 37,224, 56,206,177, 79, 4, 65, 64,245,234,213, 17, 31, 31,207, 74,231,191, 0, - 45, 39, 26,105,255, 94,225,225, 1,153, 70, 3,222,141,190,119, 37,205,144, 84, 46,135, 32,147, 66,144, 22, 54, 11,246,234,213, -107,111, 78, 78,206,178, 58,117,234, 92, 69,225, 52, 6,156,187,231,144, 32, 8,197,140, 79,105,230, 74, 16, 4, 88,173, 86,183, -111, 42, 74, 26,157,153, 51,103,222,181,109,191,126,253,220,141, 96, 81, 66, 8,149, 74,165,232,210,165, 11,234,213,171,135, 13, - 27, 54, 64, 20, 69,188,254,250,235, 80, 42,149,152, 51,103, 14,172, 86, 43, 62,251,236, 51, 22,193, 98, 48, 24, 79,158,193,122, -144,228, 92, 56,235,232, 68,236,220, 44,184,181, 85, 45,200, 53,106,200, 53, 26,180,222,176,223,113,215,140,143,103,187, 21,193, -178, 27,172,204,204,204,114,205,149, 59, 17, 44,135,193,146, 9, 88, 27,150, 13, 42,147, 64, 48, 89,138, 25, 44, 94,144, 32,193, - 47, 18,156, 68, 10,193,102,117, 75,147, 82,122, 87,147,224,139, 47,190, 8, 66,136, 99,196, 87,253,250,245,157, 47, 52,236,138, -243,144, 73,222,189,205,209,161,221,185, 89,240,247,102,213,160,240,208, 64,166, 86,163,237,230, 67,142,104, 35,230, 44,118,169, -121,249,251,239,112,118,206, 44, 72,100, 50, 60,123,242,150, 35,114,213,170,102,181, 35, 38,181,231,178,219,183,111, 31, 1,192, - 13, 28, 56,208,187,126,253,250,110,157,147,246, 78,246,101,153, 43,103,131,101,177, 88,220, 46,243,238,156, 31,246, 40,150, 27, -229,157, 70, 71, 71,131,227, 56,120,122,122, 66,163,209, 56, 70,208, 42, 20, 10,168, 84, 42, 71,255, 77,119,207, 75, 6,131,193, -248, 79, 27,172, 6, 13, 26,252,169, 82,169, 34,221, 21,169,200,164,163,206,157,136,237,230,138, 16, 2,133, 70, 3,153, 70, 13, -185,135,166,204, 40, 87, 89, 23, 26,123, 19, 33,207,243,142,139,205, 79, 63,253, 4,141, 70,131,225,195,135, 87,184, 15,150,253, -110,158,147,114,216, 46,223, 13, 94, 38, 20, 51, 87,130, 32,128,151, 72,112, 71, 19, 12, 78, 34,129, 96,117, 29, 21, 35,132, 32, - 55, 55, 23,130, 32,224,131, 15, 62,112,220,177, 59,155, 43,214,177,253,223, 71,116, 50, 35,197,162,170, 30, 30,142,242,233,252, -189,171, 62,137,132, 16, 80,171, 5, 18,185, 28,146,162,129,184,246,200,149, 73,237,185,172, 86,173, 90,142,200,149, 74,165,178, -143, 30,117,169,201,113, 92,177, 50,189,108,217,178, 98,230,170,100, 4,203,221, 50, 47,149, 74,177,100,201,146,114, 77,148, 84, - 42,117,123, 4, 37, 80, 56,109,196,222,189,123,113,226,196, 9,140, 30, 61, 26, 74,165, 18,243,230,205,131,213,106,197,140, 25, - 51,160, 84, 42, 33,147,201, 88,225, 99, 48, 24,143,191,193,146,201,100,145, 7, 15, 30,116, 76, 50, 90,222,171,201,100,194,128, - 1, 3,220,142,132,137, 69,163, 8,185, 18, 35,229,228,158, 26,200,139,154, 94,156,191, 39,110,212,226,246, 59, 96,103,131,245, -225,135, 31, 66, 16, 4, 44, 89,178, 4, 0, 48, 97,194, 4,183,251, 96,217, 53, 97, 35, 72,164,215,209,240,235,254, 48,173,180, - 32,245,224,105, 8,130,128,128, 22, 79, 65,108,214, 31, 58,165, 6,130,205,234,246, 40,194,172,172, 44,196,199,199,131,231,121, -188,245,214, 91,197,230, 42, 42,145,103,236,216,177,131,245,193,250, 23, 13, 22, 87,212,191,170,180,242, 89,194,124,185,110, 39, -179, 89, 11,251, 93, 73,255, 63, 90, 48, 39, 39,103,217,237,219,183,143, 2,224,134, 13, 27,230,173, 82,169,240,253,247,223,235, - 0,200,214,172, 89,227,210,101,217,203, 77, 89,230,234, 94,154, 8,237,145, 96,231,126, 93,247,107,176,236,102,144, 16, 2,155, -205, 6,165, 82, 89, 44,114,165, 80, 40, 32,151,203, 89,193, 99, 48, 24, 79,134,193,226, 56, 14, 70,163, 17, 23, 46, 92,112,247, - 14,213,237, 73, 71,253, 26, 55,199,224, 91,185, 32,132, 96,123,108, 29, 71,179, 75,171,223,246, 58, 42,236, 91,159, 76,128, 68, -173,129, 95,108,215, 10, 93, 24,156, 13, 86, 78, 78, 14, 36, 18, 9, 62,254,248, 99,112, 28,135,207, 62,251, 12,161,161,161, 72, - 73, 73, 65,187,118,237,220,186,155,231,109, 60,130,159,143,134,234, 69, 47,120, 62,223, 22, 62, 93, 62, 68,146, 73,192, 33,131, - 10,109, 13,231, 33,219, 62, 23, 38,209,230,150,193, 34,132,192,106,181, 98,239,222,189,197, 58,178, 3,133, 77,135,246,233, 46, - 44, 22, 11,204,102, 51, 62,251,236, 51, 86, 58,255, 5, 42, 63,221, 23, 47, 36,235, 0, 0,127, 58, 53, 91,183, 89,191,223, 81, - 62,227,103,190, 5,137, 90, 3,159,166,177,110,105,214,126,125, 34,106,191, 62, 17, 25, 25, 25,250, 78, 13,234,236, 43,144,170, -126,172, 91,183,110,177,200,149, 66,161, 32, 69,159,137, 59,101,137,227, 56,240, 60,239, 48, 87,118, 51, 85,154,193,114,247, 6, -192, 98,177, 64, 42,149,186,109,176,220,133,227, 56,188,244,210, 75, 8, 14, 14,118, 68,174, 62,250,232, 35, 40,149, 74,188,243, -206, 59,176, 88, 44,152, 59,119, 46, 43,124, 12, 6,227,241, 55, 88, 70,163,241,102,167, 78,157, 80,198,186, 80,185, 92, 94, 44, - 12,100,159,116,180,100, 83, 33, 33,164, 51,165,116,103,105, 23, 8,231,209, 88,242, 18, 81, 43,169,135, 39, 36,106, 13,184, 82, -162, 77, 37, 53,237,119,198, 37, 13,150,125,201,205,205,133, 68, 34,193, 55,223,124, 3, 79, 79, 79,199,104,189,242, 52,237, 17, - 44,158,231,161, 75,200,199,197, 89, 59, 33, 83, 28, 66,181,174,131, 16, 44, 81, 66,122, 96, 29,244, 54, 75,185, 19,141,150,166, - 89,163, 70, 13, 76,157, 58,245,174,233, 25,202,162, 81,163, 70, 46, 53,239, 23,166, 89,186,166, 59,229,147,151,203, 93, 30,119, -251,122,123,228,170, 64,170,250, 49, 62, 62,222, 30,185,242, 82,169, 84, 88,184,112,161, 14, 0, 55, 99,198, 12, 85,120,120, 56, -239, 78, 58,121,158,199, 79, 63,253,116, 87,135,246,210,204, 85,105,211,126,148,150, 78,171,213,122,151,193, 26, 48, 96,192, 93, -163, 7,203,138, 96,149,150, 78,123, 95, 53, 63, 63, 63, 71,228,202,102,179, 57, 70, 15, 90, 44, 22, 88,173,214, 50,155, 90, 89, -249,100,154, 76,243,201,209,124, 34, 12,214,201,147, 39,187,151,245,131,214,173, 91, 95, 57,120,240, 96,117,155,205,230,252,140, - 66,169,193, 96,168,209,167, 79, 31,151,183,202,162, 40, 66, 46,151,131, 82,138,134,239,127, 10, 66,238,238,111,229,221,170, 19, -136, 32,192,102,179,193, 98,177,184,156, 30, 66,175,215, 59, 46, 38,101,117,112, 47, 40, 40, 40,119,158,159,146, 23, 5,131,193, - 80,236, 66, 69,168,136, 91,187,126,189,107, 52, 97, 69, 34, 4, 0,160, 80, 40,138,245,187,114,149, 20, 86, 68, 31, 46,246, 41, - 21, 40,165,168, 51,118,114,225,113, 42,106, 46,180,155, 0,175, 38,177, 32, 18, 1, 34, 0,179,217,236,170,124, 18,123,159, 43, - 74,233, 15,125,250,244,185, 12,192, 8,128,106, 52, 26,185, 68, 34, 17, 1,100, 1,160,217,217,217, 94, 73, 73, 73,162,193, 96, -168,226, 42,157,123,247,238,197,181,107,215,208,184,113, 99,199, 35,155,236,205,110,118, 19,227,108,176,220,141, 96,149, 54,167, - 86, 89,179,185,187, 11,207,243,240,242,242,114, 76, 98, 42,149, 74,161, 82,169, 0, 0,115,231,206,117,236,115, 6,131,193,120, -236, 13,150, 11,131,196,151,213,124,232,170,169,208,102,179, 37, 54,107,214,172,162,255,151,234,226,130,152,184,111,223, 62,105, -121, 15,121, 46,229, 59,151,154, 71,143, 30,149,150,243,251,210,222,167,186,202,123,243,230,205, 75,253,125, 89, 88,173,214, 36, - 86, 68, 31, 30, 86,171,181,236,242,249,225,167,101, 29,215, 84, 23,166,229,106,245,234,213,147, 53, 26,205, 31,129,129,129,153, - 7, 15, 30,244,107,218,180,169,159,243, 54, 77,155, 54, 13, 46,241, 51, 19,202,153,158,132, 16,146,248,194, 11, 47, 72, 93,148, -241,146,159, 19, 93,220, 84, 36,158, 59,119, 78, 90,154, 86, 89,175,148,210, 68, 55,118,235,173,238,221,187,115,206,191, 45,171, -236, 91,173,214,116, 86, 10, 25, 12,198, 19,107,176, 12, 6, 67, 66,167, 78,157, 74,237, 53,171,211,233,110,151,247,219,115,231, -206, 53,121,208, 25, 72, 76, 76,108,245, 95,208,252, 39,242,206,120,244,143,209,185,115,231,154, 61,104,205,219,183,111,183,250, - 47,104, 2,192,249,243,231, 91,178,146,197, 96, 48,152,193,114, 3,119,167, 99, 96, 48, 24, 12, 6,131,193,120, 82,225,216, 46, - 96, 48, 24, 12, 6,131,193,120,176, 16, 0,157, 75, 91, 81,145,209, 1,132,144,206, 21,253, 99, 87,250, 76,147,105, 50, 77,166, -201, 52,153, 38,211,124,252, 52, 93,105, 63, 54,163, 19, 41,165,255,216, 2,160, 51,211,100,154, 76,147,105, 50, 77,166,201, 52, -153,230,147,182,176, 38, 66, 6,131,193, 96, 48, 24,140, 7,140,192,118,193,191, 3, 33,132,167,148,218, 30,160,164, 15,128,178, - 30,232,102, 2,144,125, 47,201, 4, 32, 45, 90,236, 19, 21, 89, 0,152,139, 22,234, 90, 98, 58,151,156,236, 19, 67,109,146,166, -148, 16,137, 40,226, 84,149, 42,149, 79, 2,221, 77, 0,160, 9,170, 93, 91,163, 86,118, 54,154, 77,145,114,137,236, 66,142,182, - 96,135, 33,245,242, 77, 86, 66, 24,140,135, 79,147, 38, 77, 70, 80, 74,103, 22, 86, 81,228,227,227,199,143,127,203,246, 10,131, -241,128, 13, 86,181,106,213,142,115, 28, 23,102,159, 12,179,188, 57,119,236,175, 54,155, 45,241,226,197,139,110, 13,117, 39,132, - 8,193,193,193,207,169,213,234, 14, 60,207,183, 46,250,253, 65,173, 86,251, 87, 74, 74,202, 26, 74,169,245, 94, 50, 20, 21, 21, -229,105, 48, 24, 6, 16, 66,134, 0, 0,165,244,103,133, 66,241,235,141, 27, 55,242,238,209, 8, 85, 11, 10, 10,250, 89, 34,145, -240, 9, 9, 9, 29, 0,160,114,229,202,127,153, 76, 38, 91, 90, 90,218, 16, 74,233,181, 10,234,113, 82,169,244,211,216,216,216, - 54,132,144,229,148,210, 5, 15,232, 88,202, 57,142, 43,213,152,136,162, 24,113, 15,122, 82, 0, 94,223,124,243,141,223,138, 21, - 43, 26, 38, 38, 38,214, 5,128,176,176,176,179,195,134, 13, 59, 57,118,236,216, 76, 0,185, 69, 70,171, 76,146,147,125, 98,210, -238,220, 24,157,154,118, 97, 0, 0, 4, 5,215,253,149,231, 57,105,104,232,137,195, 42,255, 33,254, 53,107, 85, 29,245,203,247, -223, 72, 35, 34, 43, 99,247,161, 19, 13,198,190,241,110,140, 34,176,230,108,102,178, 30, 30, 53,106,212, 56,206,113, 92, 88, 69, -230,146, 43,122,130, 66,226,249,243,231,155,148,165,201,243,124,152,171,185,186, 74,126, 39,138,226,141,115,231,206,149, 58,101, - 68,205,154, 53, 15,243, 60, 31,233,110,125,228,156,206,178,166,224,168, 89,179,230,113,158,231,195, 92,105,150,252, 78, 20,197, - 27,103,207,158,109,229,174,166,139, 57,244,238, 41,157,238,104,150,151, 78, 0,104,223,190,189, 92,171,213,254,172,209,104,234, -107,181,218, 17,148,210,169,123,246,236, 9,228, 56, 14,157, 59,119,158,218,164, 73,147,120,133, 66, 49, 95,175,215,159,212,104, - 52,131,247,236,217, 99,100,103, 12,131,113,159, 6,139,227,184,176, 19, 39, 78, 4,168,213,106, 20, 25, 21,216,103,111, 23, 69, - 17,162, 40,130, 82,234,120,181, 90,173,104,223,190,189, 91,127, 26, 22, 22, 86,183,102,205,154,107,199,140, 25, 83,165, 87,175, - 94,178,192,192, 64, 16, 66,112,231,206,157, 26,127,252,241,199,208,121,243,230,125, 24, 22, 22,214, 63, 49, 49,241,172,187,166, - 37, 56, 56,184, 19,128, 23,235,214,173,251,236,132, 9, 19,164,173, 91,183,134,205,102,195,238,221,187, 99,231,204,153,243, 77, - 72, 72,200, 58, 0,203, 82, 82, 82,118, 81, 74, 69, 55,117, 27, 70, 70, 70,254,186,127,255,254,200,155, 55,111,218,250,246,237, -187, 28, 0, 14, 29, 58, 84, 95, 20, 69,210,186,117,235, 63, 9, 33, 3, 40,165, 39, 43,176,207,251,140, 29, 59,182,255,152, 49, - 99, 42, 13, 31, 62,252,121, 0, 11,138,254,139, 20,237,103, 90,193, 99,232,136, 92, 81, 74,203,155, 94, 59,168, 2,145, 44,117, -124,124,188, 79,171, 86,173, 94, 75, 75, 75, 27,239,172,155,154,154,138,184,184, 56,243,172, 89,179,190, 62,116,232,208,252,200, -200,200,108, 0,218,178,132,168, 77,210, 52, 53,237,194,128,182, 45,191,241, 2,128, 53,155, 94, 27,116,236,100,186,199,239, 91, - 23, 13,149, 41,164,198, 21,139,191,150, 86,175, 22,129, 61,199,175,226,232,133, 44, 82,183, 77, 79, 33,247,247,229, 93, 0, 44, - 98,167,231,195,129,231,249,208,227,199,143, 7,168, 84,170, 82, 31,232, 94,162,223, 5, 8, 33,160,148, 34, 54, 54,182, 60,205, -176, 19, 39, 78, 4, 40, 20, 10, 71,221, 81,178,206,176,215, 43,142,178, 66, 41,218,182,109,107, 46,167, 78, 10,255,251,239,191, - 3, 84, 42,149, 67,167,180,244,149, 52, 26,109,219,182, 45, 55,157,113,113,113,142,116,186,163, 73, 41, 69,235,214,173,109,174, -242,110,127, 98,133,171,124,219, 53, 91,182,108, 73, 43,162,233,102, 58,203,189, 1,210,106,181, 63,175, 89,179,230,153,192,192, - 64,244,233,211,103,123,157, 58,117,100, 42,149, 10, 91,183,110, 69,229,202,149,253, 61, 60, 60,182,124,242,201, 39,152, 61,123, -118,149, 29, 59,118,172, 2,240, 12, 59, 99, 24,140,251, 55, 88, 80,171,213, 88,189,122,181,227,241, 48,246,199,100,148,246,190, - 74,149, 42,110,253, 97, 80, 80, 80,147,136,136,136,189, 27, 54,108, 80, 6, 4, 4, 56,190, 55,153, 76,240,244,244,196,139, 47, -190, 40,235,210,165, 75,245, 33, 67,134, 28, 9, 10, 10,106,119,231,206,157,227,229,233, 5, 7, 7, 63, 27, 19, 19,243,237,248, -241,227, 3,123,247,238, 13, 31, 31,159, 98,235,123,246,236,137, 30, 61,122, 72,111,220,184, 49,104,205,154, 53,131,150, 47, 95, -126, 39, 56, 56,120,108, 74, 74,202,186,114, 29,134, 90,221,185, 65,131, 6,223,239,222,189, 59,204,219,219, 27, 33, 33, 33,220, - 7, 31,124, 80,183,106,213,170,202,160,160, 32, 46, 37, 37, 5,235,214,173,171, 58,108,216,176,141, 10,133, 98,132,193, 96,216, -229,134, 97,147,249,250,250, 78, 28, 57,114,164, 95, 94, 94,158,245,196,137, 19, 87,237,223,203,229,242,169, 45, 90,180,104, 68, - 8, 89, 77, 41, 93,118, 47,145, 43, 74,105, 30,254,223,148,103,199, 98, 95,239,102, 36, 75,118,234,212, 41,223,150, 45, 91,174, - 51, 26,141,141, 70,143, 30,125,123,214,172, 89, 74, 79, 79, 79, 79, 0, 36, 47, 47, 47,123,250,244,233,166, 57,115,230, 76,174, - 93,187,118,167,195,135, 15, 63,219,160, 65, 3, 75,145,121,187,219, 96, 17,226, 72, 79, 66, 82, 58,246, 30, 18,101, 83,223,153, - 16,246,249,204,200, 91,127,159, 79, 16, 5,165, 39, 54,239, 59,135,212,204, 2,252,121,248, 60,130,252, 60,136, 84, 46,137,241, - 14,139,105,151,155,116,126,223, 61, 24, 78,198, 61,160, 82,169,176,121,243,230,187, 30, 49, 85,218,227,167, 4, 65,128,183,183, -119,185, 79, 35, 32,132, 64,161, 80, 96,199,142, 29,197, 30, 47, 85,218,123,251,171,151,151, 23, 40,165,229, 62,226, 64,161, 80, -224,224,193,131,224, 56,238,174,223,151, 76,179, 32, 8, 80,171,213, 32,132,112,174, 52,247,237,219,231, 82,203,254,170,209,104, - 0,160,220,231, 15,201,229,114, 28, 56,112,160,204, 60,151,124,175, 41,122,222,165, 43,205,131, 7, 15, 22,123, 68, 87,201, 71, -119, 57,127, 46,186, 57, 46, 87, 84,169, 84,214, 15, 12, 12,196,177, 99,199, 48,109,218, 52, 89, 76, 76, 12,174, 94,189, 10, 66, - 8,134, 15, 31,142, 58,117,234, 32, 37, 37, 5,117,234,212,193,129, 3, 7, 26,178, 51,133,193,120, 0, 6,203,142, 59,230,202, -254, 28,177,146, 21, 68,201,161,150, 17, 17, 17,114,141, 70,243,219,230,205,155,149,126,126,255,127, 90,136,209,104, 68,126,126, - 62, 10, 10, 10,144,159,159, 15, 15, 15, 15,204,159, 63, 95, 57,120,240,224,223, 34, 34, 34,106,220,188,121,211, 88,150, 38, 33, -228,235, 83,167, 78, 5, 90,173, 86,200,100,178, 50,205, 98,181,106,213, 48,118,236, 88,196,198,198, 6, 13, 28, 56,240,107, 0, -235,202,210, 44, 50,110,223, 29, 58,116, 40, 76, 42,149,226,202,149, 43, 72, 76, 76,196,168, 81,163,194, 69, 81, 68, 66, 66, 2, -174, 94,189,138,164,164, 36, 44, 89,178, 36,108,240,224,193,243, 1, 84, 47, 47,239, 69,188,242,214, 91,111,213,240,245,245,229, -190,248,226,139,220,130,130,130,197, 69,223,191, 51,119,238,220,193,109,219,182,173,244,242,203, 47,131, 16,242, 11,165,244, 46, -195, 82, 66,179,180,200,149, 13,192,197, 18, 63,139, 46, 17,217, 10, 66,225,179,240,114, 74,209, 36, 0,188,186,118,237,250,150, -209,104,108,116,224,192,129,107,173, 91,183, 14, 7,144, 2, 32, 29, 0,188,188,188,212, 95,127,253,117, 96,207,158, 61, 47,119, -236,216,177, 81,215,174, 93,223, 74, 79, 79,159, 85,180,158,150,212, 20, 69,156, 10, 10,174,251,235,190,195, 99, 7,236, 57,104, -146, 78,120,227,195,219, 85, 42, 71,228,158,186,146,101, 59,127, 35, 29,249,122, 43,158,233, 88, 15, 0,208,162,110, 21,124,187, -250, 0, 94,127,243, 61,201,186, 95,151,247,187, 70,161, 6,240, 71, 57,251,243,190, 96,154,255, 55, 67,162, 40, 66, 34,145,224, -169,167,158, 2, 33,228,174,103,109, 74, 36, 18, 28, 62,124, 24, 29, 59,118,132, 68, 34,193, 75, 47,189,228, 50,157,162, 40, 66, - 16, 4,116,237,218, 21, 86,171,245, 46,189,146,102,193,254,140,206,242, 52, 41,165, 16, 4, 1, 28,199,149,106,126, 74, 46,165, -153,150,210,242,238, 74,203,121, 93,105,143,251, 41,169,105, 79,167, 59,230,202,174,233,110, 58, 5, 65, 64,171, 86,173,112,242, -228,201,114,205, 22,199,113, 46,235,100,173, 86,251, 98,159, 62,125,182,143, 30, 61, 90, 1, 0,153,153,153,142, 7,209,243, 60, -143, 75,151, 46,193,100, 50, 97,229,202,149, 48, 26,141,163,217,121,196, 52,255, 73,205, 39,198, 96,217, 43, 9,119, 13,150, 59, -207,214,163,148,142,121,231,157,119, 2,203, 51, 87, 5, 5, 5, 72, 78, 78, 70,120,120, 56,158,123,238,185,192,229,203,151,143, - 1,240,101, 57,178, 82,158,231,113,236,216, 49,164,165,165,161, 94,189,122,136,140,140, 44,182,193,245,235,215,177,101,203, 22, -228,228,228,160,113,227,198, 64, 97,255,162, 82,105,208,160,193,180,232,232,232,174,237,219,183,151, 75, 36, 18,156, 58,117, 10, -141, 26, 53,194,234,213,171, 81,165, 74, 21,168, 84, 42, 92,190,124, 25,245,234,213,195,222,189,123, 81,169, 82, 37,196,196,196, -200, 27, 55,110,188, 63, 43, 43,235,175,155, 55,111, 78, 43, 99,127, 74, 67, 67, 67,223, 29, 57,114,164, 44, 57, 57, 89,252,233, -167,159, 14, 81, 74, 15, 17, 66, 70,189,247,222,123,207,119,235,214,173,210,137, 19, 39,242,254,254,251,239,191, 75, 51, 87,110, - 70,174,172, 37, 47, 70, 54,155,205,168,215,235, 77, 70,163,209,194,113,220, 77, 66,136,201,102,179,213, 40,235,102,254,197, 23, - 95,172,154,145,145,241,250,155,111,190, 25, 95,100,174, 46,161,176, 99, 59, 0,192,106,181, 26, 11, 10, 10,242, 90,182,108, 25, - 62,120,240,224,107,171, 86,173,122,253,197, 23, 95, 92,179,108,217,178, 2, 0,250,146,130, 85,170, 84, 62,201,243,156, 84,155, -239,123, 99,237,154,165,227,183,108, 26, 83, 57, 33, 33,169,186,159,127, 37,173, 84, 83, 41,121,205,207, 63, 30, 7, 96, 74, 78, -207,195,153,235,119, 32,145,240,184,144,144,139,182,221,159,147, 92,187, 50,179,141,221, 96, 49,254, 81,168,253,225,208,123,246, -236, 41, 55,130,117,248,240, 97, 72, 36, 18, 40,149, 74,172, 94,189,186, 92, 81,187, 33,176, 71,135, 92,153, 24, 87, 15, 63,183, -155, 12,251, 3,216, 75, 46,223,125,247, 29,222,124,243,205, 98,255, 81,164, 73,220, 73,103,105,233, 11,143,136, 64, 90,106,106, -177,239,220,120, 72, 59,108, 54, 27, 36, 18, 9,150, 44, 89,130,158, 61,123,226,247,223,127, 47,247,181,200,216, 82,119,210,217, -170, 85, 43,152,205,102, 71,154, 47, 93,186, 84,170,238,130, 5,229,119,239,108,210,164,201, 8, 66,200,204,154, 53,107,202, 59, -116,232,128,125,251,246, 97,230,204,153,162,213,106,205, 0,128, 86,173, 90, 85, 26, 63,126, 60,137,139,139,131, 70,163, 65,122, -122,250,178, 38, 77,154,204, 96, 29,223, 25,140, 7, 16,193,178, 87,186,174,204,149,253, 78,209,149,201,210,104, 52, 61,186,119, -239,238, 48, 55, 6,131,193, 97,172,236,230,202,254,249,242,229,203,136,137,137,145,106, 52,154, 30, 46, 12, 86, 97, 70, 4, 1, - 33, 33, 33,200,200,200,192,217,179,103, 17, 30, 30, 14,139,197,130,109,219,182, 33, 55, 55, 23, 18,137, 4, 82,169, 20,102,115, -185, 93, 18, 16, 29, 29,253,212,138, 21, 43,154, 44, 95,190, 60,219,126, 7,247,243,207, 63,131, 82,138, 74,149, 42, 65,167,211, - 33, 53, 53, 21,127,253,245, 23,172, 86, 43, 52, 26, 13, 66, 67, 67, 21, 99,198,140,105, 51,125,250,116, 9,128,105,101, 72, 55, -239,215,175,159,167,167,167, 39,222,120,227, 13,106, 54,155,191, 36,132,180,120,246,217,103,223, 29, 59,118,172,239,205,155, 55, - 77,175,188,242,202,113,179,217,252,117,209,197, 68, 66, 41,181,184, 48,172,101, 70,174, 44, 22,139,125,159,198, 23, 20, 20,192, -223,223, 63,220, 69, 31, 45, 0,144, 30, 60,120,176, 21, 0,126,198,140, 25, 10, 20, 62,192,218,145, 6,147,201,132,130,130, 2, -104,181, 90, 75,110,110,110,218,196,137, 19,173,171, 86,173,226,139,126,115,161, 52,131, 5,116, 55,213,169,163,150, 81,202,191, -183,104,209, 34, 77,183,110,221, 56,141, 70,131,252,252,124,207, 63,183,110,213,116,234,208, 38,106,214,167,159,111,247, 12,171, -151,122,240,212, 13, 36,221,201,133,201, 98, 65, 84,176, 87, 97,252,139,241,143, 83,212,193,218, 17,193,114, 54, 19,251,246,237, - 67,247,238,221, 29,231,186, 84, 42,117,108,231,142,166, 32, 8,232,222,189,251, 93, 17,157, 61,123,246,148, 26,109,114, 85,135, - 56,155,161,146,166,168, 52,227,197,113, 28, 92,181, 50,219,163,119,165,153, 44,231, 40,126, 9,211,230,234,102, 18,130, 32, 96, -236,216,177,144, 72, 36,152, 52,105, 18, 4, 65, 64,195,134, 13, 33, 8, 2, 90,182,108, 9,137, 68,130,142, 29, 59,150, 25,105, - 43,205, 92, 10,130,128, 35, 71,142,160, 81,163, 70,142, 52, 53,108,216, 16, 77,155, 54,133, 32, 8,136,141,141,133, 68, 34, 65, -215,174, 93, 93,106,218, 59,180,107, 52, 26, 92,190,124, 25, 60,207,131, 16,146, 25, 23, 23, 23, 8, 0,211,166, 77,203,208,235, -245,126, 6,131, 1,157, 58,117, 66,155, 54,109, 42,253,252,243,207, 31, 0, 96, 6,139,193,184,223, 8,150,189,210,117,215, 96, -185,194, 96, 48, 52,176, 71,175, 74, 51, 87,206,175, 38,147, 9, 85,171, 86,133,193, 96,104, 80,209,139, 69,112,112, 48,204,102, - 51,150, 46, 93, 10,169, 84, 10,169,244,255,190,194,100, 42, 63, 56,116,254,252,249,248, 35, 71,142, 52,106,220,184,177,207,250, -245,235,211,187,116,233, 82,169, 91,183,110, 80, 42,149,208,235,245,176, 88, 44,104,209,162, 5,162,163,163,145,150,150,134, 63, -255,252, 51,163, 70,141, 26,254, 71,143, 30, 21,239,220,185,115,171, 28,233, 78,157, 58,117, 2, 33, 4,127,254,249,103, 38,165, - 52, 78,169, 84,174,159, 53,107,150,183,201,100, 18,159,127,254,249,132,172,172,172,137, 0, 44,114,185,252,203,110,221,186, 53, -231,121,126,181,205,102,171,112,101, 86,114,223,106,181, 90, 40, 20, 10,119,166,132,144,100,101,101,213, 5, 0,181, 90,237, 11, -192, 49, 66, 82,175,215, 23, 51,193, 38,147,201,224,235,235,171, 6,128,162,223, 72,202, 56, 30,149, 84, 42,213,218, 91,183,110, -120, 56, 71, 46,189,189,189, 49,100,240, 96,174,117,171, 86,178,250, 13, 26,116,125,127,246,242,213, 33,126,158,166,168, 16, 63, - 88,108, 22,236,220,190, 77,164,162,101, 59, 59, 69, 31, 14,118,147, 81, 50,130, 37,145, 72,176,119,239,222,187,190,147, 74,165, -216,188,121,179, 91,102,200,110,166,202,106, 34, 43, 97,134,136, 59, 81,117,158,231,177,100,201, 18,136,162,136,241,227,199, 23, -107, 54,116,214,183,155, 29, 87,154,246,223, 68,127, 40, 2, 48, 33,241, 43,185,227,247, 37,211, 91,164, 73,220, 49, 67,223,124, -243,141, 91, 17,172,167,159,126,218, 45,211,230,156, 47,123,186, 78,158, 60, 89,170,238,162, 69,139, 92,246,105, 19, 69, 17,127, -252,241,135,195,156,218,249,224,131, 15, 70,122,122,122,106,246,237,219,135, 59,119,238, 64,171,213,162,160,160, 0, 62, 62, 62, -222,157, 59,119, 62,117,231,206,157,155,231,207,159,103, 29,222, 25,140,123,141, 96,217, 43, 93,119,154, 9, 75,107,239, 47, 69, - 79, 32,132,192, 96, 48,148,106,172,156, 77,129,217,108, 70,102,102, 38, 68, 81,188,231,185,186, 74,171, 88, 93, 25,172,179,103, -207, 14, 31, 49, 98, 68,178,151,151, 87,253,204,204,204, 20,185, 92, 30,187,111,223,190,202,102,179, 25,158,158,158,240,244,244, -196,150, 45, 91,224,237,237,141, 55,223,124,243,182, 94,175, 63,164, 86,171, 3,245,122,253,233, 59,119,238,188, 95,166,115,145, - 72, 58,181,109,219, 22,113,113,113,200,201,201,217, 77, 8,169,255,242,203, 47,119,169, 92,185, 50,153, 57,115,166,225,218,181, -107,223, 1, 72, 87,171,213, 75, 87,172, 88,209,174,113,227,198,154, 97,195,134,129, 16,242, 61,165,212,224,110,158,181, 90,109, - 49, 99,149,151,151,135,252,252,124,168,213,106,171,155,251, 76,130,194,190, 84,246,254, 84,142, 99, 83, 20,189,178, 31, 31, 42, - 8, 2, 45,220,132, 74,202,210, 83,171,213, 51,150, 47, 95, 94,172,207,157, 61, 58,154,154,154, 10, 79, 79, 79,124,240,254,251, -210,143,222,126,185, 17,175, 9, 60,204,113, 4, 38, 51,205,161,162,105,155, 54,117,224,126,118,138, 62,156, 8,150,221, 16,244, -238,221,251,174,102, 65,169, 84,138, 29, 59,118,160,111,223,190,142, 27,150,162,166,118,183, 12, 65,175, 94,189, 28,145,160,109, -219,182,149,218,188,103,143, 64,185, 99, 4,237,219,142, 27, 55, 14,130, 32,224,219,111,191,197, 91,111,189, 5,142,227,240,213, - 87, 95,129,227, 56, 76,157, 58,181, 66,245,132,189, 46,187,249,121,225,107,216, 91,121,200, 92, 16, 8, 0,240,240,244,180,111, - 88, 33, 77, 65, 16, 28,145,171, 6, 13, 26, 64, 34,145,160,101,203,150, 16, 4,193, 17,185,234,209,163,135,243,180, 10,212, 29, - 77, 65, 16,112,229,202, 21, 71,154, 91,182,108, 89, 44,114, 37, 8,130, 91,134,141, 16,242, 81,199,142, 29,103,134,133,133, 5, -140, 30, 61,154,240, 60,143, 38, 77,154,248, 79,157, 58, 53, 87, 34,145, 40, 39, 76,152, 80,218,121, 45, 1, 80,191,118,237,218, -106,118,230, 48, 24,247, 17,193,170,136,193,114,167,114, 84,169, 84,103, 50, 50, 50, 90,202,229,242, 98,230,170, 52,163,197,243, - 60,210,210,210,160, 82,169,206, 60,200, 12,187,106, 34, 44, 50, 51,111, 59,237,135,166,207, 61,247,220,170,213,171, 87, 71,237, -220,185, 19, 71,143, 30, 69,165, 74,149, 48,107,214,172, 27, 55,111,222, 28, 76, 41,253,219,157,255,173, 90,181,106, 29,181, 90, -141, 67,135, 14, 1,192,126, 0, 47,190,254,250,235,196,106,181, 98,254,252,249, 58, 0, 59,188,188,188,214,253,246,219,111, 13, -234,213,171, 39,219,185,115,103,254,209,163, 71,247,184,105,174,108,162, 40,222,101,172,156,247,169,135,135,135, 59, 17, 44,139, -151,151,215,217,188,188,188,231,244,122,125,158, 92, 46,247,200,203,203, 51, 58, 27, 43,187,190, 32, 8,146, 43, 87,174, 36, 3, -136,242,242,242, 58, 11,167,166,196, 98, 5, 76, 16, 58,117,234,212, 73, 40,121, 12, 82, 83, 83,113,231,206, 29,152,205,102, 52, -110,220,152,240,196,194,103,221, 62, 61,146,157,146, 15, 31,142,227,168,253, 92,183,143,250, 43,109,228,224,182,109,219, 28,159, - 57,142,195,159,127,254,233,150,105,219,177, 99, 71,185, 29,209, 75,116, 72,119, 25, 10,183,111, 63,127,254,252,194,199, 81, 20, - 69,174, 56,142,195,148, 41, 83, 32,151,203, 49,115,230, 76, 76,153, 50,165, 88, 84,198, 85, 4, 75, 16, 4, 68, 76,210, 57,223, - 20, 21,158, 20, 69,253,157, 8, 33,206, 38,203,173, 72,155,171, 14,238,238, 68,254, 75, 75,167, 66,161, 40,179,131,123, 9,205, - 50,255,224,248,241,227, 63, 52,106,212,232, 90,165, 74,149,118,180,108,217, 82,126,252,248,113,140, 25, 51,134, 24,141, 70,207, -157, 59,119, 58,254,183, 52,163,167,213,106,149,236,204, 97, 48,238, 35,130, 85,145, 78,238,238,244, 75,208,235,245,187,246,236, -217,211,180, 79,159, 62, 66,121,205,131, 90,173, 22,129,129,129,184,126,253,186, 85,175,215,187,156,254,192,102,115,127, 66,116, - 87, 6,171,148,125,240,119, 76, 76,140,213, 98,177,160,122,245,234, 8, 13, 13,133,193, 96,192,156, 57,115,172,238,154, 43, 66, -136,180, 73,147, 38, 60, 0,100,103,103, 3, 64, 38,128, 26, 53,106,212, 64, 92, 92, 28,178,179,179, 55, 2,232,252,209, 71, 31, - 53,108,222,188,185,116,245,234,213,186,209,163, 71,111,180, 88, 44, 51,221,209, 23, 69,209,100,181, 90, 35, 57,142, 51,231,228, -228, 36, 57,239,207,192,192, 64, 95,181, 90, 77, 82, 83, 83, 45,238, 24,172,250,245,235, 31,187,125,251, 54,102,204,152,145, 62, -107,214,172, 26,249,249,249,217,185,185,185, 86,103,147,101, 48, 24, 56,127,127,127,249,130, 5, 11,148, 0, 80,191,126,253, 99, -101, 25, 44,173, 86, 91, 89,165, 82, 57, 62, 27,141, 70,220,185,115, 7,119,238,220, 65,106,106, 42,242,243,243, 17, 21, 21, 5, -157, 78, 23,206, 78,199,127, 15,231,102, 50,231,243,219,249, 2, 94,145,115,221, 89,179,119,239,222,142,190, 91,246,136,152,125, - 89,187,118,109,177,142,227,174,154,222,236, 6,107,254,252,249, 24, 55,110, 28, 20, 10, 5,190,254,250,235, 98, 77,132,165,152, - 2,226, 78, 58, 35, 39,235,113,103,158, 47, 36, 18, 9,252, 70,167, 22,107,138, 43,101, 52,158, 91, 70,112,214,172, 89, 15,172, -137,208,174, 25, 30, 94,120,170, 44, 89,178, 4,207, 61,247, 28,246,239,223,127,207, 77,132,145,145,145, 43,230,206,157, 43, 63, -127,254, 60,242,242,242,144,158,158, 14,163,209,136,196,196, 68,199,190, 41, 13,157, 78,167, 96,103, 13,131,113, 31, 6,203,185, -243,167, 43,131, 85,212, 65,210,149, 17,248,250,195, 15, 63,124,189, 77,155, 54,190, 30, 30, 30, 72, 78, 78,190,203, 92, 21, 20, - 20, 64,163,209,192,100, 50, 97,207,158, 61,121,162, 40,126,237,202, 20, 88, 44, 22, 4, 4, 4, 32, 35, 35, 3, 98, 25,253,162, - 57,142,131, 82,169,132, 86,171, 69, 89,102,160,188, 10,216,108, 54,195, 98,177,192, 98,177, 84,216,164, 1, 80,218, 39,108, 45, -250,127,109, 72, 72, 72, 85,133, 66,129,248,248,120, 0,184, 2,160, 67,183,110,221, 36,153,153,153,244,149, 87, 94, 57, 76, 41, - 29,235, 98, 54,123,211,190,125,251, 34, 1, 64,169, 84, 94, 6,128,196,196, 68, 75, 78, 78, 78,177,200,160, 74,165,162,125,251, -246, 13,166,148, 98,223,190,125,145, 82,169,148,162,140, 57,171, 0, 24, 54,110,220,120,222,203,203,107,213,167,159,126, 58,184, -103,207,158,231,234,214,173, 27,169,213,106,211,244,122,189,222, 96, 48, 80,158,231,165, 62, 62, 62,138,237,219,183, 95, 59,124, -248,112,103, 79, 79,207, 85, 27, 55,110, 60, 15,160,212, 72,155, 90,173, 78,212,233,116, 17, 26,141, 6,122,189,190,152,185,186, -115,231, 14, 40,165,184,113,227, 6, 84, 42,213,109,118, 58,254, 59, 56, 71, 92, 74, 70, 90, 74,126,231,174,185,114, 54, 67,219, -183,111, 47,119, 14, 44,119, 53,157,205,208, 91,111,189,133,121,243,230,221, 21,193,154, 57,179,240,158,228,253,247,223,119, 25, -189,114, 70, 34,145,224,206, 60, 95, 4,141,203, 42,102,102, 0,128,216,211, 87,193, 41,217, 4, 65,192,140, 25, 51,238,234,124, -238,220,132,231,174,177,114, 78,103, 90, 90, 26, 4, 65,128,175,175, 47,134, 12, 25,130,174, 93,187, 58,154, 26, 43,170,155,144, -144,112,114,246,236,217, 85, 66, 67, 67,177,122,245,106,147, 90,173,150,117,236,216,145,230,228,228,144,242, 34, 88,204, 96, 49, - 24,174,225,220,169, 32,221,105, 38, 44,173,146, 36,132,116,118,254,124,243,230,205, 92,173, 86, 59,100,208,160, 65,122,163,209, -136,170, 85,171, 66, 46,151,195, 98,177,192,100, 50, 65, 42,149, 34, 56, 56, 24,148, 82,172, 91,183, 78,175,211,233,134,220,188, -121, 51,183, 60, 77, 66,200,123, 79, 61,245,148, 33, 62, 62, 30, 85,170, 84,129,135,135,199, 93,143,141,240,244,244,132,183,183, - 55, 46, 94,188,136,165, 75,151,234, 9, 33,239,149,167, 89,154,209,180, 27, 43,187,209,114, 53, 50,169,132,166,218, 30,197,209, -233,116, 0, 96,173, 82,165, 74, 32, 0,220,184,113, 3, 0,110, 69, 69, 69,181,171, 86,173, 26,217,191,127, 63, 40,165, 59, 75, - 51, 87, 37, 52,179, 98, 99, 99,111,197,198,198,154, 76, 38,147,212,100, 50, 73,115,115,115,205,254,254,254, 1,254,254,254,254, -129,129,129,190, 1, 1, 1,222,201,201,201, 86,171,213, 42,181,217,108,210,216,216, 88, 83,243,230,205,111,195,105, 54,247, 18, -154, 34,128,188, 69,139, 22, 77,151, 72, 36,183, 90,181,106, 21, 51,121,242,228,155, 22,139,197, 24, 26, 26,234, 19, 20, 20,164, -212,233,116,249,159,124,242, 73,218,188,121,243, 58, 75, 36,146, 91,139, 22, 45,154, 14, 32,175,232,183,119,105, 90,173,214, 93, - 59,119,238,180, 90, 44, 22, 36, 37, 37, 33, 57, 57, 25, 41, 41, 41,142, 87,111,111,111, 28, 59,118,204,102, 54,155,119, 86, 96, -127, 62, 40, 99,193, 52,241,255,190, 63,229, 25, 43,119,186, 1,148, 76,167,221, 12, 61,247,220,115, 24, 56,112, 32, 6, 13, 26, -132, 33, 67,134, 96,216,176, 97, 21,153,154,161,228,249,238,248,237,228,201,147,241,254,251,239,227,195, 15, 63,132, 92, 46,199, - 7, 31,124,128,105,211,166, 97,218,180,105, 37,205, 21, 41, 39,239,197,234,185,220, 37,161,208, 45,139,128,105,101,181,194, 38, - 66, 74,255,191,184,191, 63, 29,102,232,131, 15, 62,192,225,195,135, 49,113,226, 68,236,222,189, 27, 99,198,140,193,150, 45, 91, - 48,114,228, 72,252,241,199, 31,142,215,162,155, 64,234, 78, 58, 5, 65, 64,187,118,237,160,211,233, 28, 6,118,212,168, 81,197, -244, 70,142, 28,233,214,254, 84, 42,149,131, 55,110,220,184,126,233,210,165, 55,178,178,178,186,222,188,121,243,182, 86,171, 37, -185,185,185,142, 99, 88,114, 41,138, 68,203,217,121,196, 52,153,133,186,143, 8,150,213,106, 69,229,202,149,139, 61,219,138,227, -184, 98, 75, 69,250, 17, 0, 64, 74, 74,202,246,224,224,224,103,159,121,230,153,149, 47,190,248,162, 71,116,116,180, 36, 34, 34, - 2, 58,157, 14,183,110,221,194,205,155, 55,173,187,119,239,206,211,233,116, 67, 83, 82, 82, 92,142, 34, 75, 74, 74, 90, 30, 24, - 24,184,109,232,208,161, 83, 27, 54,108, 56,106,252,248,241,124, 84, 84, 20,114,115,115,225,227,227,131,128,128, 0,196,199,199, - 99,239,222,189,182,156,156,156,133, 54,155,237,163,212,212,212,244,138,236, 36,171,213,202,155,205,102, 12, 26, 52, 8,162, 40, - 98,206,156, 57,176, 90,173,124, 5, 36,204,102,179,153, 2, 32, 25, 25, 25, 0,160,179, 27,174,171, 87,175, 2,192,237,136,136, - 8, 13, 0,236,220,185,147, 0, 56,228,238, 13,189,115, 36, 43, 58, 58, 58,222, 94, 41, 58, 95,228,236,235,139, 34, 87,174,110, -195, 13, 3, 6, 12, 72,211,233,116,221,222,122,235,173,169,243,231,207, 31, 60,127,254,252,187, 54,242,244,244, 92,245,213, 87, - 95,125, 52, 96,192,128,180,178,162, 87, 69, 17,187,247, 95,120,225,133, 1,103,206,156,241, 80, 40, 20,208,106,181,200,204,204, -132,217,108, 70, 84, 84, 20,210,210,210,176,124,249,242,124,189, 94, 63,141,157,142,255, 46,101, 25, 43,119,251, 88,150, 21,197, -217,188,121,115,169,115, 76, 85, 84,179,164,201,112,119,110, 42, 55,110,134, 74,157,250,161, 34,245, 90, 89,154, 95,124,241,133, - 99,178,213,210, 34, 87, 21,137, 96,217, 53,125,125,125, 1, 20,206,190, 47,138, 34,158,126,250,233,123,214, 45,122,182,224,179, -246,207, 77,154, 52,249,104,245,234,213, 51, 41,165,126, 0, 4,231,125,192, 30,170,192, 96, 60, 32,131,101,179,217, 18,219,181, -107, 87,172, 98, 43,239,161,170, 69, 70, 36,209, 77,147,181, 45, 42, 42, 42,106,201,146, 37,111,168,213,234,206, 6,131,161, 30, - 0, 40, 20,138, 51, 90,173,118, 39,199,113,115, 83, 82, 82,220,126, 56,115,145, 97, 26, 19, 22, 22, 54,103,216,176, 97, 51, 91, -181,106,213,255,149, 87, 94, 33,130, 32, 96,205,154, 53, 52, 49, 49,113, 45,199,113,239, 37, 39, 39, 95,191,151,157,164, 82,169, - 46,175, 93,187,182,234,230,205,155, 97,177, 88,176, 96,193, 2, 40, 20,138,203,238,254,158, 82,154, 46, 8,194,202, 86,173, 90, - 13, 62,124,248,240, 42, 74,233, 89,185, 92,254,115,108,108,236,144, 67,135, 14,253, 74, 41,189, 32, 8,194,207, 45, 91,182, 28, -114,236,216,177,117,148,210,211, 21, 72, 94, 86,108,108,108, 54,128, 32,171,181,244, 22,197,216,216, 88, 19,128, 59,110,152, 43, - 59,121, 35, 70,140, 48,143, 24, 49,226,237, 1, 3, 6, 44,253,251,239,191,155,229,228,228,212, 3, 0,111,111,239, 51, 77,155, - 54, 61,246,235,175,191, 94, 42,138, 92, 25, 92,229,157, 16,210,183, 94,189,122,235, 62,254,248, 99,117, 76, 76,140, 80,189,122, -117,220,188,121, 19,103,207,158,181,254,240,195, 15, 5,122,189,190, 55,165, 52,155,157,142,255, 14,246, 38, 66,111,111,239, 98, - 55, 79,246,161,251, 21,105,194, 43, 77,179,228,141, 25,207,243,229,105,186,116, 53, 26,141,198, 49,106,217,157,174, 9,229, 61, -123,212,158, 78,187,166,125,113,195, 92, 81, 87,154, 69,143,233,169,136, 38,220,209,180, 88, 44, 14, 93, 55, 52, 43,244,167,199, -143, 31,255, 1,192, 15,213,171, 87,191, 10,160, 26, 51, 85, 12,198, 63, 96,176, 46, 94,188,216,228,159,252,227, 27, 55,110,228, - 1,248,168,104,121, 32, 36, 38, 38, 94, 7, 48, 32, 40, 40,232,203, 67,135, 14,125, 0, 0,162, 40,206,112,245, 60, 67, 87,156, - 62,125,186,175, 68, 34,153,191,108,217,178, 86,148, 82,120,121,121, 29,186,122,245,234,107, 21,140,130,141, 34,132,140,183,143, - 10, 52, 26,141,163, 8, 33, 19, 40,165, 90,167,245,142,207, 21,132, 2, 48, 82, 74, 67,202, 88,111,172,128,185,114, 68,178, 0, -152,126,253,245,215, 2, 0,167,240,255,121,174, 44, 69,139, 1, 78,205,130, 46, 46,112,127, 17, 66,170,127,240,193, 7,179,120, -158,239,164,213,106, 67,213,106,117,130,213,106,221,165,211,233,222,163,148,102,178, 83,241,223,195,106,181, 38,181,107,215, 78, - 40,237,198,169,188, 11,120,121, 55, 84, 54,155, 45, 49, 54, 54, 22,247,160,153, 84, 78, 82,111,181,108,217,146,115, 87,203,142, -197, 98, 73, 43, 47,157, 45, 91,182, 44,243,166,241, 94,243,222,178,101,203, 10,165,177,168,174, 74,122,208,154, 46,246,103,153, -232,245,250,236, 74,149, 42, 21, 24, 12, 6,137,209,104,148,148,140,216, 43,149,202,116,118,230, 48, 24,247,104,176,254,203, 20, - 25,170, 94, 15, 74,175,168, 63,212,171, 15, 64,199, 80,226,179,182,188,207, 21,228,159,136, 0,137, 0,116, 15,104, 31,102, 0, -120,133,157,114,143, 30,103,207,158,109,254,160, 53,207,159, 63,223,228, 31, 72,103,203, 7,173,121,238,220,185, 38, 79,170,102, -121, 36, 37, 37, 53,103,103, 6,131,113,127,112,108, 23, 48, 24, 12, 6,131,193, 96, 60, 88, 8,128, 82, 71, 2, 84,228, 73,217, -247, 50,154,192,149, 62,211,100,154, 76,147,105, 50, 77,166,201, 52, 31, 63, 77, 87,218, 21,241, 31,143, 52,165, 13,195,125, 80, - 11,128,206, 76,147,105, 50, 77,166,201, 52,153, 38,211,100,154, 79,218,194,154, 8, 25, 12, 6,131,193, 96, 48, 30, 48,204, 96, - 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24,140, 39, 8, 66, 8, 9, 11, 11, -107, 23, 18, 18,210,242, 73,221, 7, 2, 43, 6, 12, 6,131,193, 96, 48, 30, 4, 85,170, 84,241,182,217,108, 47,134,132,132,188, - 86,181,106,213,170, 0, 16, 26, 26,122,150, 82, 58, 87,169, 84,254,124,237,218, 53,211, 19, 99, 50,217,163, 16, 24, 12, 6,131, -193, 96,220, 15, 33, 33, 33, 13, 1,188,166, 84, 42,135, 54,111,222, 92,214,177, 99, 71,248,248,248,192,106,181, 34, 37, 37, 5, -127,253,245, 23, 78,158, 60,153,101,177, 88,230, 91, 44,150,249,233,233,233,169,204, 96, 49, 24, 12, 6,131,193, 96,148, 65,112, -112,240,236,238,221,187,191,229,227,227,131,234,213,171, 35, 40, 40, 8, 70,163, 17,122,189, 30,148, 82, 8,130, 0, 74, 41,242, -243,243,113,252,248,113, 28, 61,122,212,154,151,151,183,138, 16, 50, 55, 57, 57,249, 36, 51, 88, 12, 6,131,193, 96, 48, 24, 37, - 8, 9, 9, 73,221,189,123,119,128,213,106, 69, 70, 70, 6,140, 70, 35,116, 58,157,195, 96,241, 60, 15, 74, 41,172, 86, 43, 0, - 64, 20, 69, 92,184,112, 1,135, 15, 31, 70, 66, 66,194, 87, 41, 41, 41,111, 63,142,251,133,117,114,103, 48, 24, 12, 6,131,113, - 95, 24,141, 70,172, 88,177, 2, 25, 25, 25,168, 92,185, 50, 66, 67, 67,225,237,237, 13,165, 82, 9, 0, 14,115, 5, 0, 28,199, - 33, 38, 38, 6, 67,135, 14, 5, 33,100,200,227,186, 79, 88, 39,119, 6,131,193, 96, 48, 24,247,131,197,100, 50,161, 73,147, 38, -136,143,143, 71, 92, 92, 28, 26, 53,106,132,218,181,107, 35, 35, 35, 3,201,201,201,197, 54, 62,118,236, 24, 78,156, 56,129,182, -109,219, 62,214, 59,133, 53, 17, 50, 24, 12, 6,131,193,184,103, 66, 67, 67,159,175, 84,169,210,130, 97,195,134, 41, 27, 52,104, -128,196,196, 68, 36, 37, 37, 33, 59, 59, 27, 13, 27, 54, 68, 76, 76, 12,174, 95,191,142,109,219,182,225,196,137, 19,144,203,229, - 8, 11, 11,131,102,213, 47,248, 35, 36, 56, 41, 57, 57, 57,140, 25, 44, 6,131,193, 96, 48, 24,140, 18,132,132,132,248, 17, 66, -222, 11, 13, 13,125,125,200,144, 33,146,234,213,171, 35, 49, 49, 17,233,233,233,200,206,206,198,145, 35, 71,236,102, 12, 97, 97, - 97,184,121,243, 38,206,156, 57,163, 55, 26,141,163,147,146,146,150, 51,131,197, 96, 48, 24, 12, 6,131, 81,182,209,170, 12, 96, -122,181,106,213,158,127,238,185,231,184,144,144, 16, 36, 37, 37, 97,247,238,221,168, 86,173, 26, 82, 83, 83,113,252,248,113, 91, - 94, 94,222, 66,155,205,246, 81,106,106,106,250,227,186, 47,254,209, 78,238,132,144,206, 76,147,105, 50, 77,166,201, 52,153, 38, -211,124, 50, 52,147,147,147, 19,146,147,147,135, 95,185,114, 37,102,230,204,153, 27, 23, 44, 88, 0,158,231, 17, 26, 26,138,221, -187,119,211, 93,187,118,173, 45, 40, 40,168,153,156,156, 60,230,113, 54, 87, 0,235,228,206, 96, 48, 24, 12, 6,227, 1,115,231, -206,157,139, 0,250,134,134,134, 54, 63,119,238,220,187, 0, 32,138,226,140, 59,119,238, 28,127, 82,246, 1, 51, 88, 12, 6,131, -193, 96, 48,254, 17,146,146,146,142, 2,232,245, 36,230,157,205,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, - 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24, 79, 20, 4, 64,169, 35, 1, 40,165, 59,221, 22,185,135, 17, 10,174,244,153, 38,211, -100,154, 76,147,105, 50, 77,166,249,248,105,186,210,174,136,255,120,164,161,148,186, 92, 80, 52, 95, 86, 69, 23, 0,157,239,229, -119, 76,147,105, 50, 77,166,201, 52, 31,190,230,189,212,245,165,105, 22,221,188, 19, 20,182,146,112,246,207,143, 90, 58,255, 43, -121,127, 82, 52, 31,183, 69,112,225, 46, 29, 59,137, 16, 34, 2, 16,233, 3,152,153,148, 16, 98, 63, 0, 15, 68,143,241, 15,132, - 54, 11,143, 17,249,191, 15,103,199,137,193,120,140,207,247, 7, 86,215, 59,213, 29,188,211, 69,214, 6,192, 70, 8,193,253,212, - 37,255,196, 53,233, 81,207,251,147,172,249, 95, 71, 40,111, 71, 85,170, 84,105,123, 64, 64, 64,135,140,140, 12,177,232,123,132, -134,134,130,227, 56, 8,130,160,143,143,143,247,172,232, 31, 6, 6, 6,126, 31, 19, 19,243, 98,102,102,166,200,113, 28, 42, 87, -174, 12, 66, 8,120,158, 7,207,243,250,107,215,174,121,254,219, 59,165,113,227,198,217, 38,147, 73, 83,242,123,153, 76,102,136, -139,139,243,120, 18,204,149,191,191,255,179,129,129,129,222, 89, 89, 89, 20, 0,194,194,194,192,243,124, 97,161, 17, 4,235,245, -235,215,151,185,171, 23, 25, 25,121, 76,169, 84,122, 11,130, 0,158,231, 33, 8, 2,180, 90,109,206,133, 11, 23,154, 21,173, 63, -168, 84, 42,253,120,158,183,151, 45, 24, 12,134,204,243,231,207,183,102,151,190,255, 38,107,215,174,229,187,133,190, 84, 77,160, -250,250, 28, 71,189, 68,145,228, 90,137,242,244,182,164,239,175,185,243,251,254,253,251,219,254,229,115,160, 10, 0, 43,165, 52, -249, 30,126,204,149, 82,209,118,183, 1, 3,139, 62, 26, 56, 32,147, 0, 87,106, 2,235,206, 3,250, 18,205, 10,226,195,190,145, -170, 82,165,202,220, 74,149, 42, 13, 47, 40, 40,208,113, 28, 7, 66, 8,141,137,137,177,111, 83,236, 85, 20,197,196,115,231,206, - 53,113,113,145,149, 84,169, 82,229,171, 74,149, 42,189,160,211,233,116,132, 16, 16, 66, 40, 33, 4,245,234,213,187, 75,211,102, -179, 37,158, 61,123,182,201,195, 74,231,191,149,247,186,117,235,150,170, 89, 86,222, 75,211,116, 78, 39, 33, 4, 49, 49, 49,247, -157,206, 71, 81,243,177, 53, 88, 0,184,128,128,128,141,205,154, 53,107,191,105,211, 38,238,226,197,139, 92,116,116, 52,108, 54, - 27, 68,177,240,220,111,212,168,145,170,162,127, 22, 20, 20,244, 83,179,102,205, 6,109,218,180,137,219,184,113, 35,215,180,105, - 83, 16, 66, 96,179,217, 96,179,217,208,169, 83, 39,229,125, 86, 22, 26, 65, 16,198,203,100,178,118, 86,171,181, 54, 0, 72, 36, -146, 11, 70,163,113,175,213,106,253,154, 82, 90,224,142,142,197, 98, 81,157, 59,119,238,174,125,211,172, 89, 51,217,189,166,173, - 70,141, 26,135, 56,142,139, 42,237,164, 45,235,149, 82,122,227,220,185,115,173,202,210,172, 85,171,214, 33,142,227,162,236,219, -151,166, 81,242, 59, 81, 20,111,156, 61,123,182, 85,121,149, 78, 96, 96, 96,191, 86,173, 90,121,253,246,219,111, 36, 33, 33,129, - 40,149, 74,136,162, 8,155,205, 6,139,197,130,142, 29, 59, 86,104,254, 52,149, 74,229,185,107,215,174,106, 1, 1, 1, 72, 75, - 75, 67,102,102, 38, 70,142, 28,121,197,190, 94,169, 84,250,253,245,215, 95, 53,124,125,125,161,211,233,144,155,155,139, 33, 67, -134,252,231, 79,174,174,109,171,126, 76, 0, 95,251,103,155,136,172,157, 7,174,191,127,191,186,181,106,213, 58, 33,147,201, 2, -203, 58,230,165, 29,123,147,201,148,122,238,220,185, 70, 46,206,159, 8, 0,189,120,158,175, 46, 8, 66, 45, 0, 17, 86,171, 53, - 16, 0,164, 82,105, 42,207,243, 55, 45, 22,203, 37,147,201,116, 21,192,102, 74,233,205,178,180,186,133,190, 84,141, 88,117,253, -243,141, 98, 15, 85,213, 79,107,234,174, 79,185,172,146,235,182,116, 11,125,105,173,187, 38,235, 95, 52, 87,145, 33, 33, 33, 95, - 20,189,159, 72, 41,141,191, 95, 77, 27, 48,144, 82,234, 5, 0,185,185,185, 94, 9, 9, 9, 65,155, 55,111,142,153, 53,107, 86, - 71,153,193,240,185, 9,184, 88,222,239,187,180,171,118, 92,224, 72, 24,138, 98, 0, 86, 42, 38,238,216,123,253, 65, 92,152,184, -208,208,208,185,221,186,117, 27,182,112,225, 66,213,209,163, 71, 85,117,235,214, 5,207,243,246,250, 2, 37, 3, 15, 45, 90,180, - 40,119,247, 1, 16, 66, 66, 66,230, 60,245,212, 83,131,231,207,159,175,186,116,233,146, 42, 50, 50, 18, 69, 23,219, 98,101,211, -254, 93,195,134, 13, 31,118, 58,255,209,188,119,239,222,125,240,130, 5, 11, 84,103,206,156, 81, 85,175, 94, 29, 28,199,129,227, -184,187,244, 56,142, 67,147, 38, 77,220,210,236,218,181,235,224, 69,139, 22,169, 78,156, 56,161,170, 85,171,150, 99,223, 57, 53, -207, 85, 56,157,143,184,230,227,103,176, 8, 33, 92,165, 74,149, 86, 52,105,210,164,219,166, 77,155,120, 0, 56,113,226, 4,178, -178,178, 16, 26, 26, 10,141, 70, 3,185, 92, 14,131,193, 80,161,112, 95, 96, 96,224,247, 69,230, 74, 2, 0,235,134,246,197, 13, - 9, 48, 54,205, 4,169, 84,138,235,215,175,131,231,249,251, 9, 29,183,245,244,244, 92,190,126,253,122,159, 70,141, 26,113, 25, - 25, 25,136,140,140, 68, 86, 86, 86,179,125,251,246, 53,126,233,165,151, 94, 34,132, 60, 79, 41,221,231,174,230,150, 45, 91,160, - 86,171,161, 82,169,160, 86,171, 97, 54,155,201,189,166,143,231,249,176,163, 71,143, 6,104, 52, 26,136,162,232, 88, 74,180, 95, - 59, 16, 69, 17,109,219,182, 53,151,123,240, 4, 33,236,232,209,163, 1, 74,165, 18,148,210, 98,122, 54,155, 13,114,185,220,249, - 14, 17, 54,155, 13, 45, 91,182, 52,187,138, 92,217,205, 21, 0,172, 90,181, 10, 65, 65, 65, 8, 8, 8,128, 90,173,134, 82,169, -188,151,188,195,207,207, 15,175,191,254, 58, 6, 14, 28,136,149, 43, 87, 66, 34,145, 56,231, 3,190,190,190,216,186,117, 43, 60, - 61, 61, 17, 30, 30, 94,108,253,127, 54, 18, 8,248,110,219,119,221, 17,145,237,223,179,129,208, 57, 54,106,190,163,114, 45,220, -136,138,133,219, 82,209,102,203,222,117,240,214, 84,151, 87, 5,142, 11, 57,122,244,104,128, 92, 46,119,239,226,110,179,161, 81, -163, 70,188,139,243,167, 71, 76, 76,204,186,215, 94,123, 77, 90,189,122,117, 34,149, 74, 33, 8, 2, 4, 65,176,151,199,112, 74, -105,184, 40,138,237, 83, 83, 83,233, 55,223,124,243, 57, 33,228, 25, 74,233,150, 82,203, 38,213,215,207, 55,138, 61,246,159, 68, -179,254,157, 39, 99,235,154, 41,205, 98, 27,138,240, 80,233,175, 1,120,100, 13, 22, 33,196, 83,169, 84,126,176,102,205, 26, 41, - 0,116,238,220,249, 3, 66,200,155,148,210,188, 7,245, 31, 94, 94, 94,240,242,242, 66,221,186,117,241,236,179,207,122, 55,108, -216,112, 66,123,163,113,212, 30,160,204,115, 83,224,184,176, 63,255,186, 18, 96,255, 60,184,111, 99,105,183,246,213, 82, 11,111, -196, 74,110, 77, 33,218,104,226,206, 3, 55,154,184,200, 43, 23, 20, 20,244,101,247,238,221, 7, 44, 92,184,208, 3, 0,190,255, -254,123, 60,253,244,211, 8, 12, 12,132, 82,169,132, 76, 38,131, 68, 34,129, 84, 42,117,188,186,136, 8,241, 65, 65, 65,159, 63, -253,244,211,253,231,207,159,239, 1, 0, 63,253,244, 19,122,246,236, 9, 63, 63, 63,120,122,122, 66, 46,151, 67, 38,147, 65, 42, -149, 22, 51, 92, 21, 73,231,203, 93, 59,162,170, 82,142,158, 31,127, 14, 31, 31, 31,236,122,251, 53, 72, 56, 14, 99,182,237,131, -135,135, 71,185,233, 44, 75, 51, 46, 46, 14,105,105,105,165,230,157, 16, 82,110,221,231,156,247, 30, 61,122,244, 95,176, 96,129, - 35,239,221,186,117,131,159,159, 31, 60, 60, 60, 32,151,203, 33,149, 74,139, 45,101,237, 3,103,205,238,221,187,247, 95,180,104, -145, 7, 0, 44, 91,182, 12,157, 59,119,134,143,143, 15, 60, 60, 60, 28,251,178,162,199,232, 81,214,124, 44, 13,150,189,111, 84, - 64, 64,192,128,223,127,255,157,115,190, 0,202,229,114,199,137, 33,147,201,192,113, 92, 69, 42, 45, 18, 19, 19,243,226,166, 77, -155, 28, 63, 50,149,168, 20,228,114,121,133, 52, 75,232,119,238,208,161,195, 47,191,255,254,187, 66, 42,149, 66,175,215,227,220, -185,115,240,242,242,130, 76, 38, 67,159, 62,125,248,214,173, 91,251,181,111,223,254, 55, 66,200, 96,119, 70, 40, 80, 74,161,209, -104,138, 25,172,251,105, 66,182,159,160,155, 54,109, 2,207,243,197, 10,153,253,213,249,125, 64, 64,128, 91,186,114,185, 28,135, - 14, 29, 2,207,243,144, 72, 36, 16, 4, 1, 18,137, 4,127,252,241, 7,222,126,251,109,100,100,100,128, 16, 2,137, 68, 2, 15, - 15,151,173,155, 36, 48, 48,208,219,110,174,138, 34,128, 80, 42,149,144, 72, 36, 68, 16, 4, 98,111,198, 35,132, 16,119,219,212, - 5, 65,192,205,155, 55, 49,116,232, 80, 44, 91,182, 12, 51,102,204,192,224,193,131,139,173,207,203,203,131,143,143, 15,124,124, -124,160, 80, 40,238,185, 44, 60, 74,136, 37,246,206, 71, 51,191, 80, 65,164, 40,236,228, 33, 2, 34, 64, 65, 33, 82, 17,169, 73, -215, 48,251,203,121,188,187,101, 73, 46,151,227,224,193,131, 14, 19, 36, 8, 2, 8, 33,112, 54, 70,246, 37, 40, 40,200,165,166, - 84, 42,157,190, 97,195, 6,217,202,149, 43,177,122,245,106,199,127,168,213,106,120,123,123,195,207,207,207,177,132,133,133,145, - 31,126,248, 65, 90,191,126,253,233, 0,182,148,110, 2,169,151,170,234,167, 53,251,119,158, 92,104, 46, 39, 83,100, 95,153,217, -128,203,153,234,245, 8,155, 43, 1,192, 59,223,126,251,173, 95,227,198,141, 1, 0,223,126,251,173,223,136, 17, 35,222, 33,132, -188, 79, 41,181,222,243, 13, 22,176,154, 16, 50,176, 40, 98,171,232,210,165,139,236,187,239,190, 67,173, 90,181, 48,110,220, 56, -223,217,159,127,222, 11,192,111,101,151,165,226,133,233,211, 47,230,122, 83, 90, 88,126,168, 72,139,189,102,165,221,196, 7, 31, -124,236,178, 78, 6,192,133,132,132,188,180,120,241, 98, 71,119, 8, 31, 31,159, 82,235, 38,137, 68,226, 88,202, 49, 69,164, 40, - 42, 52, 98,225,194,133, 14, 77,127,127,127, 72,165,210, 98, 23,216, 91, 23, 79, 97,203,210, 79,160,246, 13,194,208,137,159, 85, - 56,157, 97,114, 25,194,148, 50, 52,104,208, 0, 42,149, 10,113,146,194, 75,153,135,135,135,203,116,150,165,233, 92, 47, 3,128, - 78,167,115, 68,237, 77, 38, 19,154, 52,105,226, 86,222, 23, 45, 90,228,208,244,243,243,115,228,221,158, 46,231,186,222,126, 3, - 83,158,102, 72, 72,200,136, 37, 75,150, 56, 52,125,125,125,139,105, 72, 36, 18, 44, 95,190,252,174, 58,226,126, 53, 43,122,220, - 75,106,222,188,121, 19,179,102,205,114,212, 73,246, 40,158,189,171,209,188,121,243,220, 50,216,143, 85, 4, 11, 0,201,200,200, - 16, 47, 94,188,200,197,197,197, 65, 34,145, 32, 32, 32, 0, 77,155, 54, 5, 0,152,205,102,251, 69,151,212,170, 85, 43,149,227, - 56,216, 47,186, 28,199,193,106,181, 58,218,147,157,140, 12,151,149,149, 37,238,216,177,131, 91,241, 76, 87,152, 40,208,240,131, - 79,208,173,103, 79,108, 11,149,129, 7,208,236, 98, 6,100, 50,153, 16, 28, 28,108,177, 31, 4,187,182,115,223,172,146,230,136, - 16,226,161, 86,171,127,216,188,121,179,130,227, 56,228,231,231, 67, 20, 69,180,110,221, 26, 28,199,225,236,217,179,120,239,189, -247,176,110,221, 58,108,216,176, 65,217,168, 81,163, 31, 8, 33,181, 41,165,249, 78,102,106,103,105,133,211,195,195, 3, 42,149, -202, 97,176,236,121, 46,106, 83, 47,217, 36,147,116,238,220,185,198,101,105,218, 35, 9,125,251,246,117,244, 57,179,155,161,146, -175, 82,169, 20,103,207,158, 45,205,244,221,165, 41,138, 34,218,180,105, 99,111,138,131, 70,163,193,158, 61,123, 28,235, 27, 54, -108, 8,147,201, 4,127,127,127, 92,184,112,193,165,102,122,122, 58, 77, 78, 78, 38, 43, 86,172,128, 68, 34,129,159,159, 31, 84, - 42, 21,249,237,183,223,222, 81, 40, 20, 97, 70,163, 81,180, 88, 44, 8, 11, 11,155, 23, 30, 30,110, 63, 70,218,107,215,174,249, -149,165,201,243, 60, 20, 10, 5,126,250,233, 39,204,154, 53, 11,239,190,251,110,177, 19,139,231,121, 24, 12, 6,248,251,251, 59, - 76, 86,201, 19,239,159, 24,182,251, 79,107, 82, 80,156, 59,177, 13,231,207,236,132,104, 19, 97, 19, 41, 40,181, 65,180, 2,113, - 59,142,212, 72,185,145, 28, 74, 65,129,162, 30, 55,150, 2,173,181,189,191,188, 22,128,141,123, 50,140,115, 92,165, 83, 16, 4, - 88, 44, 22,108,222,188, 25,215,174, 93,195,246,237,219,161,215,235, 29,251,177,101,203,150, 24, 49, 98, 4,130,130,130, 92,238, - 79, 74,233, 79, 9, 9, 9, 13,219,180,105, 67,114,114,114,144,147,147, 3,189, 94, 15,155,205, 6,171,213, 10, 65, 16,160, 80, - 40,160, 84, 42, 17, 24, 24, 8,131,193, 64,141, 70,227, 79,101,105,138, 34,201,213, 93,159,114,121,235,154, 41,205,250, 79,166, - 88,251, 25, 65,141, 8,185,110,239, 41,239, 17, 91,142,190,211,133, 80,142, 2,133, 89,231, 8,168,205,102,203,120,117,236,167, - 99, 30,246, 49, 42,193,168,241,227,199,215,118,110,158, 30, 50,100, 8,206,157, 59, 87,251,235,175,191, 30, 5,224,219,138,106, -250, 0,161, 0, 96, 5,182,162,112,193, 90,189,158, 12,218,184,177, 47,128, 23, 54,108,216,128,193,131, 7,227,203,207, 63,175, - 91,210, 96, 21, 43, 75,148,226,230,149,253,184,121,245, 0, 68,145, 58, 69,193, 75,127, 79,221, 75, 39, 41, 40, 40, 48, 28, 61, -122, 84,179,108,217, 50,120,123,123, 35, 42, 42,202,209, 74, 81,242, 2,107,255,236,170, 44,233,116, 58,195,197,139, 23, 53,191, -252,242, 11,124,125,125, 17, 30, 30, 14,149, 74,229,208,148,201,100, 56,178,109, 61, 70, 13,237,129,140,155,231, 49,247,205, 1, -110,167,243,229, 46, 29, 81, 89, 33, 67,223, 25,159, 34, 58, 58, 26,107, 7,246, 6, 71,128,209,187,143, 64, 42,149, 98, 89,143, -182,144,201,101, 24,189,251,111, 87,233,116,104, 30, 63,126, 28,162, 40, 34, 34, 34, 2, 58,157, 14,158,158,158, 80, 40, 20,144, - 72, 36,216,177, 99, 7,250,244,233,131,149, 43, 87,162,101,203,150, 46,243, 94, 80, 80, 96, 56,115,230,140,230,231,159,127,134, -175,175, 47, 42, 87,174, 12,149, 74,229, 8, 76,216,141, 22,207,243,136,138,138, 66,110,110, 46,170, 86,173, 90,174,166, 86,171, - 53,196,197,197,105,126,254,249,103,248,248,248, 32, 44, 44,204, 17, 97,179,155,162,105,211,166, 21,211,104,208,160,193,125,107, - 86,244,184,151,212,236,219,183, 47,170, 85,171, 6, 79, 79, 79,168,213,106,135,118,121,154,143,181,193,162,148,210,162, 81, 20, -136,142,142, 70, 86, 86, 22,228,114, 57,154, 54,109,138,140,140, 12,104, 52, 26, 72,165, 82, 80, 74, 49,112,224, 64,126,226,196, -137, 1, 69,166,202, 81,225,151,209,150, 46,114, 28,135, 86,173, 90,225, 92, 81,203, 79,183,158, 61, 17, 22, 22, 6,123, 39, 14, -133, 66,129,193,131, 7,147,183,223,126, 91,176, 71, 47, 40,165,208,235,245,168, 95,191,190,178,156,232,200,155,191,253,246,155, -151, 76, 38, 67,126,126,190,163,137,140,231,121, 92,188,120, 17, 95,126,249, 37, 94,120,225, 5,220,190,125, 27, 33, 33, 33,152, - 48, 97,130,230,211, 79, 63,125, 19,192, 71,174,118,142, 70,163,113,152, 43,149, 74,133, 97,195,134, 9,173, 91,183, 14,208,104, - 52,240,240,240,128,189,185,207,102,179,161, 85,171, 86,196, 85,212, 65, 20, 69,108,219,182, 13,130, 32,184,140, 96, 21,181, 89, -187,165,121,244,232, 81,135, 57,115,190, 43, 34,132,224,220,185,115, 14, 51, 87, 84,152,203,211,164, 60,207, 67,173, 86, 35, 40, - 40, 8, 74,165, 18, 42,149,138,108,218,180,233,253,136,136,136,224,215, 94,123,141,203,203,203,227,154, 52,105,130, 30, 61,122, - 8,162, 40,194,108, 54,163, 99,199,142,229,238, 71,137, 68,130, 99,199,142,225,211, 79, 63,197,228,201,147,177,104,209, 34,116, -238,220,185,152, 81, 32,132,160, 82,165, 74,240,244,244,124,124,206, 46, 17, 48, 91, 45,208, 21,232, 29, 77,184, 54,155, 13,103, -246,156,170,113,227,212,149,152,223,127, 89, 41, 1, 0,195,158,245,206,191, 10,126,118,254,175, 53,219,251, 74,143,238,201, 50, - 31,117,209, 84,136,113,227,198, 97,234,212,169, 24, 56,112, 32,118,236,216,129,247,222,123, 15, 47,189,244, 82,177, 8,150, 59, - 88, 44,150,197,207, 63,255,252,200,181,107,215,214,154, 60,121, 50,103,143, 96,169, 84, 42, 16, 66, 96, 48, 24, 96, 52, 26,161, -215,235,113,233,210, 37,241,149, 87, 94,185,108, 50,153, 22,151,165,103, 37,202,211, 42,185,110, 75,245, 42,124, 53,109,252, 23, - 30,109,154, 71,232,137,178,113,238,211,213, 59,211,206,131, 35,124, 64, 41,168, 88, 24,229, 51, 26,181,120,103,210, 4,254,223, - 60, 84,132,144, 30, 93,186,116,233, 58,115,230,204,187,214,205,156, 57, 19, 23, 46, 92,232, 74, 8,185, 89, 86,147,104,105,120, - 3, 97,138,160,160,175, 0,192,251,206,157,183,114,128, 68, 0, 24, 4,116,179, 1,189,119,236,216, 1, 0,168, 82,165, 10, 68, -160, 14, 1,126,226,129,213,214,210,162,130,148,194, 98,177, 66,175, 55,150,107,172,236,159, 93, 5,151,237,117, 61,207,243,168, - 91,183, 46,186,117,235, 6,169, 84, 10, 15, 15, 15, 71,115, 78,105, 81, 12, 23, 77,247, 20,128, 72, 8, 65, 84, 84, 20,186,118, -237, 10,169, 84, 10,181, 90,237, 48, 45, 50,153, 12, 60,207,163, 94,235, 78, 88,185,124, 38, 94,236,217, 8, 47,196, 6, 98,221, -153, 76,183,210, 25,161,148, 33, 92, 37, 71,116,116, 52, 60, 60, 60, 64, 8, 32,240,255,175, 79, 85, 42, 37,100,114, 89,185,233, - 44,169,153,154,154,138,248,248,120,196,199,199,131,227, 56,180,105,211,198, 17,117,185,122,245, 42, 62,250,232, 35, 24,141, 70, -183,242,206,113, 28,170, 87,175,142,142, 29, 59, 66, 38,147, 65,165, 82, 21,107, 26,180,239,211,252,252,124, 84,171, 86, 13, 27, - 55,110, 68,219,182,109, 93,106, 70, 71, 71,163, 93,187,118,144, 74,165,142, 27,105,165, 82,233,184,110, 20,153, 59,199,127, 52, -106,212,168, 66,154,219,143,221,198,210, 29,127,193,104, 18,145,167,179, 20,251, 65,176,191, 39, 14,252, 60,217,173,188,219, 53, -151, 44, 89,130,156,156, 28, 71, 29,100, 15,192,216,131, 39,149, 43, 87,198,130, 5, 11,158,172, 38, 66,251,101,193,238, 42, 67, - 67, 67, 97,239,231,161,209,104, 32,147,253,191,143,183,213,106,197,186,117,235, 16, 16, 16,224, 88,188,188,188,202, 44,208, 85, -170, 84, 1,165, 20,227,210, 11,187, 25,108, 13,145,226, 38,128,167,211,169, 35,186, 99,179,217,240,219,111,191,193,217,192,120, -120,120,148,219, 92, 36,147,201,218, 55,109,218,148, 51, 26,141,119,153,171, 79, 63,253, 20,131, 7, 15, 70,205,154, 53, 33,138, - 34, 10, 10, 10,208,161, 67, 7,201,188,121,243,218, 87,196, 96,169, 84,133,253,249, 77, 38, 19,246,236,217, 3, 31, 31, 31,248, -249,249,193,215,215, 23, 30, 30, 30, 80, 40, 20, 32,132,184,108, 46,163,148,162,111,223,190,142, 66,231, 28,181, 42,105,182, 14, - 29, 58,228, 86, 51, 25,165, 20,205,155, 55,135, 90,173,134, 70,163,129, 70,163,193,182,109,219, 28,235,155, 53,107, 6, 81, 20, - 17, 16, 16,128,195,135, 15,187,172,116,195,194,194, 28,219, 75, 36, 18,242,219,111,191,189, 19, 25, 25, 25, 60,122,244,104,142, -231,121,156, 56,113, 2,231,207,159, 71, 80, 80,144,163, 79,150,171,116,106,181,218,148,121,243,230,217,190,251,238, 59, 0, 64, -199,142, 29,145,155,155,155,230,180, 62,115,232,208,161,142, 81,138, 0,144,149,149,149,249, 24,248, 43, 88,205, 86,232, 12, 6, - 20,228,235, 28,209,160,180,228, 84,239,201,111,143,151,124, 57,102, 56, 0,224,237, 57,223, 34,127,209,255, 43,176,245,111, 15, - 10,120,102,246,234, 41, 0,250,148,167,175,211,233, 96, 52, 26, 17, 30, 30,142, 99,199,142, 33, 63, 63, 31,157, 59,119, 46, 22, - 33,117,222,167, 46,142,189,137, 16,210,186,103,207,158,127,127,253,245,215, 85,107,215,174, 77,180, 90, 45,116, 58, 29,156, 95, -207,156, 57, 67, 87,173, 90,117, 67,167,211,181,162,148,154,202,210,219,150,244,253,181,110,161, 47,173,221,119, 90,214,211, 63, -234,178,103, 82,118, 85,107,102,146, 92,155,167,191,100,176,209,243,160, 54,192, 6, 17,212, 42,194, 6,138,127,115,252, 54, 33, - 36,172, 70,141, 26,175,174, 92,185,178,212,253,197,243, 60, 86,174, 92,137, 54,109,218,188, 74, 8,185, 88, 94,231,126, 59, 45, - 1,153, 65, 34,153,188,249,215, 95, 11,251,114,117,236, 56,185,165,197,242,246, 97,192, 84,167, 94,189,126,135, 14, 29,242,178, -215, 43, 94, 94, 94,160,148,242, 58,157,206,171, 85,171, 86,253, 74,107,118,165, 34, 96,177, 88,160,215, 27,145,155,155, 15,147, -217, 82, 84,103,138,176,217,172, 69,175, 34,172, 69,245,168, 68,224, 61,218,183,172, 82, 80,104,180, 72,206,222, 35,183, 43,151, - 81,215, 83, 66, 8, 2, 3, 3, 33,149, 74,139, 69,153,220,137, 94,149,130,205, 94, 23,250,249,249, 65, 38,147,225,244,158,223, -145,118,225, 0,164,132, 66,180, 89, 32, 90,205,176, 89,205,224, 57, 30,151,174, 39, 35, 58,216,229,216, 33, 71, 58,187,125, 48, - 3, 45, 90,180,192,218,129,189, 65, 8,240,218,238, 35,144, 72, 36,248,185,111, 39,200,101, 82,188,178,227,136,187,233, 44,150, -247,227,199,143, 99,220,184,113,248,236,179,207,160, 84, 42,237, 45, 39,184,120,241, 34,126,253,245, 87,116,233,210,197,237,188, - 19, 66, 28,121, 23, 4, 1, 83,166, 76, 65,114,114, 50,230,204,153,131,198,141, 27, 67, 34,145, 32, 39, 39, 7,173, 90,181, 66, -106,106,170,219,251,211,222,140, 39,147,201,138, 69,155,236,198,239, 94,142,145, 93,115,120,223, 96,108, 58,184, 10, 4, 4, 71, -126, 30, 95,236, 90,180, 96,245,254, 10,107, 78,157, 58,181, 88, 58,159,196,232, 85,169, 6,139, 82, 74, 67, 67, 67, 33,138, 98, - 49, 83, 85,178, 67,173, 61,228,231, 28, 82, 44,183, 15, 2,207, 67, 20, 69, 71, 97,224, 75, 89,127,248,240,225,187, 76,192,210, -165, 75,203,189,128, 91,173,214,218, 30, 30, 30,197,162, 87, 82,169, 20, 83,166, 76,193,176, 97,195, 28,230, 74, 42,149, 98,217, -178,101,104,210,164, 9, 76, 38, 83,237,242,210, 42,149, 74,117,245,234,213,227,236, 81, 32,165, 82, 73, 6, 15, 30,204, 91,173, - 86,199, 62,177, 47,246,190,105,174, 76,134, 61,218,180,125,251,118,183, 34, 88,238,246, 65,162,148,226,212,169, 83,197, 76,155, -125, 20, 12, 0,156, 58,117,202,209, 63,203, 93, 77,155,205, 6,165, 82, 73,164, 82, 41, 81, 40, 20, 97,118,115,197,243,188,227, -120, 59,247,201,115,117,162,156, 62,125,186, 67,121,235,207,156, 57,243, 88, 78,199, 32, 66,132,217, 98,129, 94,103, 66,126,129, - 30,211, 63,249,177,112,197,116, 28, 5,112,180,245,168,113,120,173, 91,151,142, 0, 42, 85,208, 16,192,126, 1,251,237,183,223, - 32,145, 72,176,113,227, 70,120,122,122,162,119,239,222,240,244,244,196,228,201,147, 49,112,224, 64,183, 35, 88, 69,101, 41,151, - 16,210,250,205, 55,223,252,251,139, 47,190,168, 82,185,114,101,152, 76, 38,152,205,102,152, 76, 38, 92,187,118, 13,171, 86,173, - 74,208,233,116,173, 41,165,185,174,244,182, 37,125,127,237,247,195,239, 36,199, 62,251,172,254, 98,234, 86,220,185,147, 9,171, - 53, 9,162,205, 10,179,181,112, 68,178,205,106,133,213,106,131,192,115,158, 11,190,158,184,163,176,195, 63, 49,245,239,223,255, -169,135,120,168,232,149, 43, 87, 50, 43, 85,170,100,175,196, 60, 77, 38, 19, 41,186,129,163, 0,236, 29,220,181, 40,167, 35,186, - 51,199,128,145, 95,126,246, 89,152,189,249,254,147,207, 62, 11,155,240,214, 91, 35, 1,204,187,112,230,204,202,225,195,135,191, -185,102,205,154, 98,191, 25, 62,124, 56, 46,156, 57,179,178,244, 16, 65, 81, 4,203, 96, 64,122,102, 54, 94, 30,245,190, 35,116, - 0, 80, 56, 59, 84, 90,248, 89, 1, 0, 25,169,215, 48,118,220,219,242,178,110,168,234,212,169, 3, 81, 20,139, 69, 67,238,161, -239,149,115,100,200,177,157,167,167, 39,164, 82, 41,174, 29,250, 29,111,141, 26, 0,216,204,160, 22, 61, 96,214, 1,230, 2,136, - 38, 29,136, 84, 9, 88,244, 46,117,237,233,244,244,244, 44,236, 19, 42,240,144, 73,255,111,254,156, 35, 87,238, 92,184, 75,230, -253,230,205,155,120,237,181,215, 96, 54,155,209,183,111, 95,152, 76, 38, 24, 12, 6,232,245,122, 68, 69, 69, 65,167,211,185,157, -119,251,181, 83, 42,149, 98,252,248,241,104,210,164, 9, 62,250,232, 35, 76,154, 52, 9, 81, 81, 81, 24, 61,122, 52, 86,173, 90, -133,152,152,152,114,117,237,154,133, 77,238,133,154,246,252,150,108,202,179,183, 20,184,123,140, 74,211,180,207, 46, 82,242,184, -191,241,124,167, 10,107,126,250,233,167, 72, 79, 79,191, 43,114,101,127, 31, 26, 26,138,249,243,231, 63,145, 17, 44,199,112, 82, -251, 5,212,126, 33,119,174,220, 85, 42, 21,214,173, 91, 87,172,115, 93,121, 97,105,142,227, 32,138, 34,182, 84, 42,252,125,143, -162,200,149,243,231, 94,189,122, 33, 50, 50,178, 88,244, 74,169, 84,150, 91,104, 68, 81,196,173, 91,183,112,238,220, 57,180,104, -209, 2,185,185,185,144,112, 28,222, 62,115, 6,117,158,127, 30, 38,169, 20,162, 40, 66, 38,147, 97,228,200,145,110,117, 84,255, -251,239,191,125,156, 63,215,169, 83, 39, 49, 54, 54, 54,244,216,177, 99,142,142,239, 69,205,103, 14,163,225,230, 73,141,126,253, -250, 21,139, 90, 57,155, 43,231,101,235,214,173,110, 53, 17, 82, 74, 17, 27, 27,235,136, 94,121,120,120, 96,195,134, 13,142,245, -246,240,115, 96, 96,160, 91,154,246, 59,248,162,142,237, 48, 26,141, 98,126,126, 62, 23, 23, 23, 7,153, 76,230, 56, 38, 74,165, - 18, 10,133,226,190, 6, 39, 60,246,216, 68,152, 44, 22,232,245,122, 20, 20, 20,206, 16,114,237,108,241,126,204,102,227,189, 15, - 78,179, 71,169,242,243,243,177,107,215, 46,172, 95,191, 30,141, 27, 55,190,171,147,187,243,121,235, 70, 25, 77, 39,132,180,153, - 56,113,226,145,143, 63,254, 56,196,215,215, 23,102,179, 25,183,111,223,198, 15, 63,252,144,172,211,233,218, 80, 74,211, 43,224, -218, 96,177, 88, 97,208, 25,145,155,151,143,105, 51,151,149, 89, 69, 0, 64, 86,218, 37, 12, 30, 60, 68,246, 48, 15, 19,165, 52, - 9,192, 75, 78,231,213, 10, 0,246,112,124, 30,165,116, 88, 69,244, 36, 64,251,103,251,247,239, 56,126,252,120,199,119,227,199, -143,199,145, 35, 71, 58, 74,214,174, 61,103, 1,246,240,107,215,198,124,253,245,215,142,109,190,254,250,107,172, 91,187,118,183, - 13,216, 83, 86,221, 97,111, 34, 44, 40,208,195,211, 59, 24, 73,241,123, 93,166, 69,202, 27, 64, 69,209,229,141, 95,201,126, 55, - 37,235,167, 10,148, 31, 90,175, 94, 61,123,235, 2,164, 82, 41,234,118,236,143,217,115, 23, 67,206, 81, 60,219,185, 46, 42, 41, -108,128,210, 23,210,182,147, 65,188,195,139,110, 58, 26,186,117,131,186,239,253, 9,184,161, 86,224,149,237, 7, 32,149, 74,241, -219,192, 30,144,203,165,120,225,247,125,144, 74,165,248,125,196, 51,144,202,164,232,182,240, 87,183,110, 84,236,121,191,118,237, - 26, 14, 29, 58,132,232,232,104, 92,189,122, 21,206,253,108, 41,165,110,155,182,186,117,235, 58, 2, 18, 18,137, 4,119,238,220, - 65,207,158, 61, 29, 55,248,123,247,238,197,196,137, 19, 49, 98,196, 8,180,111,223,190,212,126,177, 37, 53, 99, 98, 98, 28,129, -131,146, 38,216,185,217,182, 34,199,168, 52, 77, 71,249,189,199,227,238,172,249,241,199, 31,151,106,214, 43,162,249, 88, 27, 44, -251, 9, 82, 86,187,179, 90,173,198,235,175,191,142,169, 83,167,194,223,223,223,101,223, 25,187,115, 45,143,205,155, 55,223,245, -221,198,141, 27, 93, 53, 17, 94,244,242,242,106,210,161, 67, 7,228,230,230, 34, 33, 33, 1,106,181, 26,117,102,207,198,153,215, - 94, 67,131,133, 11,193,117,236, 8, 66, 8,100, 50, 25,206,156, 57, 3,165, 82,121,177,162, 17, 3, 15, 15, 15,248,248,248, 56, -218,212,237, 70,203,201, 96, 81,119,204,208,150, 45, 91, 74, 29,161,115, 47,125,176,236, 21,239,145, 35, 71,138,245,191,114,110, -230, 56,114,228,136, 35,130, 85,180, 61,113,117,156,138,238,234,168, 93, 79,165, 82,193,215,215, 23,114,185,220, 97,172,236,230, -202, 29,115,233,106, 34,209,136,136,136, 98, 19,145, 74, 36,146, 98, 19,145,254,215,155, 8,245,122, 3, 10,242,245, 15,178, 73, -171,208,156, 21, 13, 56, 89,183,110, 29,154, 55,111,126,151,185,178, 71, 29,239,193,112, 36, 18, 66,218,207,157, 59,247,232, 87, - 95,125,229, 83, 80, 80,128, 31,127,252, 49,183,160,160,160, 61,165, 52,177, 66, 90, 0, 44,102, 51,116, 6, 35,180, 5,133,251, -224,250,185,223, 92,154,178,255, 50,181,235,213, 27,250,227,143, 63,222,245,253,143, 63,254,136,171, 87,175, 14,197,153, 51,123, -154, 1,139,222,153, 60,185,122,227,198,141,195, 0,224,157,201,147, 19,155, 1,139,202, 59,207,205, 69, 77,132, 5, 5,133, 81, - 15,131, 54,227,193,148,211, 34,147, 81, 86,159,171,123,185, 32,218,235, 91,169, 84,138,174, 3, 95, 70,242,141, 75,136, 86,103, -160,146,183, 10, 52, 47, 9,210,142, 31,226, 76,150, 10,115, 22,110,171, 80, 58,213,114, 25, 20, 10,185, 83,159, 43, 5,100, 10, -185, 35,157, 10,165, 18, 18,185,172,194,121,191,124,249, 50,148, 74, 37,108, 54,219, 93,215,155,138,230,223,217,184,124,253,245, -215,152, 56,113, 34,150, 45, 91,134, 51,103,206,160, 65,131, 6,232,220,185, 51,210,210,210,112,250,244,105, 24,141, 70,183,211, -233,220, 47,238,252,249,243,248,243,207, 63, 17, 31, 31,143,132,132,132,123, 62,238,206,154, 37, 13,214,186,157, 39,209,175, 75, -163,123,210,156, 54,109, 26,210,210,210,138, 69,174,156,163,155, 79,116, 4,203,222,196,228,116, 81,190, 43, 74,165, 86,171, 29, - 29, 34, 61, 61, 61, 93, 70,134,236, 6, 43,246, 70,126,177,190, 92,246, 72, 22, 0,140, 24, 49,226,174, 8, 86,201,201,233, 74, - 98, 52, 26,247,238,221,187,183, 97,175, 94,189,248,139, 23, 47, 58,154, 34, 77, 45, 91,162,193,194,133, 56, 59,126, 60,218,221, -188, 9,131,217, 12,133, 66,129,109,219,182,153,117, 58,221,222, 10, 86, 22,196,217, 96,169,213,106,120,121,121, 57, 12, 70, 69, - 92,121, 89,119,136,206,159, 43, 18, 17,178,247, 57,179, 47,246, 11, 43, 33, 4,122,189,222,209, 89,179, 34, 81, 17,155,205,230, - 56,241,236, 29, 20,189,189,189, 29,149,134,125, 52,153,187,205,163,174, 38, 18, 85, 40, 20,158,251,247,239,175,102,159, 70, 34, - 35, 35, 3, 3, 7, 14,188,242, 95, 63,185, 40, 40,204, 86, 27, 10,244, 6, 20,232,117, 15, 92,127,229,202,149,184,118,237, 26, -204,102, 51, 62,249,228,147,187,140, 85, 69, 58,185,151, 82,174,174, 53,106,212, 72,236,222,189, 59,142, 28, 57, 2,185, 92,110, -161,148, 86,120,254, 42, 42,138, 48, 91,173, 48,232,245, 40,208,106,159,136,187,214,243,103,206,252,166, 86,171, 7, 2,208,228, -228,228,240, 94, 94, 94, 80,169, 84,208,235,245,185,124,209, 72,193,195,128,201,219, 98,249,108,192,128, 1, 95, 1,128,194, 98, -249,236, 48, 96, 42,239, 60,183, 88,139,204,250, 3,220,143,246,122,171,172, 58,233, 94,162,211,246, 11,169, 84, 42,133,192,243, -248,113,214, 4, 68,171,211,209, 40,210, 3,198,212,171,144,121,248,131,120, 71, 96,206,194,109,184,112, 51,171, 66,233, 28,180, -124, 45, 42, 87,174,140, 77,207,247,134, 66,174,192,160,117,187, 32,145, 72,176,125,244, 64, 72,101, 50,116,254,238,231,123,202, -187, 86,171, 45, 51, 82,229,110, 4,171,100,222, 37, 18, 9, 26, 54,108,136, 26, 53,106, 96,207,158, 61,104,212,168, 17,174, 94, -189,138,171, 87,175,226,230,205,155, 56,115,230, 12,178,179,179, 43,124,140, 86,175, 94,141,172,172, 44,200,100, 50,100,100,100, - 32, 62, 62,222,173,169, 88, 92, 29,119, 59,181,158,158, 6, 0, 8,169,228, 85, 33,131,229,172,249,249,231,159,223,101,218,159, -196,150, 14,161, 12, 19,160,175, 85,171,150,210,185,253,148,227, 56,120,120,120,144,137, 19, 39,242, 69,239,225,229,229,133, 74, -149, 42,185,213,236, 38,145, 72,244,205,154, 53, 83,218, 11,160,221, 56,169,213,106,126,210,164, 73,100,233,210,165,101, 70,181, - 92,244,193,250,106,216,176, 97, 47, 37, 38, 38,250, 4, 4, 4, 32, 37, 37, 5, 50,153,172,240,164,232,208, 1,177, 55,110,192, - 92,216,167, 8,151, 47, 95,198,226,197,139,181, 70,163,241,171,138,238, 40,141, 70, 3, 63, 63, 63, 71,211,160, 61,130,227,100, - 22,233,189, 84,100, 37,151,138, 68, 28,236,154,206, 6,203,126, 97, 29, 53,106, 84, 49,179,229,118,129, 16, 4,107,187,118,237, - 4,123, 58, 44, 22, 11,234,213,171,135,180,180, 52, 72, 36, 18,200,100,178, 98,145, 59,119, 12,150,171,137, 68, 5, 65,128,201, -100, 66,219,182,109, 65, 8,193,183,223,126,123, 79,145,151, 71,206, 96, 89, 69,162,209,248, 33, 36,164, 38, 42, 5, 24, 32,138, - 15,238,233, 47, 86,171, 21,163, 71,143, 46, 22,177,178,143, 84,180, 55,241, 23, 54, 43, 89,238,121,210, 86,251,121,125, 63,243, -191,137, 20,142,166, 45,173,214,240,159, 59,134,225,225,225,158, 69, 77,134, 37,249,133, 82,250,103,169,199,166,104, 74, 6, 30, -152,113,251,246,237,186, 94, 94, 94,232,218,181, 43, 54,111,216,176,233, 23,192, 17,178,201, 1, 18,125,238,220, 25, 95,244, 62, -201, 85, 80,175,176, 15,150, 17, 90,173,254,129,231,243,126,111,244, 74,187,161,230,121, 30,235, 22,126,138,104, 85, 42, 26, 86, -145,227,208,145,147,104, 94, 25,128,233,222, 91,128,237,125,155, 84, 42, 37,164, 50,185, 35,157, 10,149, 10, 18,169,236,158,243, -238, 92,159,150,172, 47,239, 37,130,231,188, 63, 95,126,249,101, 76,158, 60, 25, 93,187,118,197,213,171, 87,177,111,223, 62, 92, -189,122, 21,227,198,141, 67, 76, 76, 12,186,117,235, 86, 33,205,181,107,215, 34, 55, 55, 23, 28,199, 33, 51, 51, 19,122,189, 30, - 83,167, 78,189,239,227,110, 39,126,231, 39, 0,128,223,118,156,184,103,205,247,222,123, 15,119,238,220, 41, 22,185,122, 82,162, - 86, 46, 13,214,229,203,151, 75,109,239,139,137,137, 73,237,210,165, 75, 64, 74, 74, 10, 52, 26,141, 75,115, 69, 8,233,108,159, - 43,227,220,185,115,165,106, 86,173, 90,213,220,165, 75, 23, 73,112,112,112,177,209,131,106,181,186,216,201, 90,154,102, 81,229, -159, 79, 8,121,181,117,235,214, 63,109,221,186, 85, 85,163, 70, 13,228,229,229,129, 82,138,101,203,150, 97,204,152, 49, 80, 40, - 20,184,124,249, 50,122,247,238,173,211,233,116,175, 58,207,129, 85,154,102,105, 70,134,227, 56,199,252, 48,165,152,171,114,243, -238,204,220,185,115, 29,115, 65,149,199,162, 69,139,128, 18, 83, 42,148,166, 73, 41,197,151, 95,126,249,192, 52, 47, 93,186,180, -204,121,125,100,100,228,183, 79, 61,245,148,144,144,144, 80,204, 84, 57, 47,165, 84, 72,197, 52, 93, 77, 36,202,243, 60, 2, 3, - 3,241,241,199, 31,195,207,207, 15, 65, 65, 65,119, 69, 94, 92, 29,163,123,188,123,255, 71, 53, 41, 71,227,230,126, 53,173,205, -162,239,215, 75,228, 50,224,240,190,223,144,151,125,167,120, 4,214,252,255, 33,209,178, 70,157, 96, 58,177,203,173,116, 26,141, - 70,124,254,249,231,152, 54,109,218, 93,115,224,148,113,220,239, 43,239,238,152,172,210, 52, 69, 81, 36, 42,181, 15, 20,234, 16, -212,137,241,129,232,198, 92,157,226,191,127,220,117, 9, 9, 9, 94,149, 43, 87,198,149, 43, 87, 8,254,223, 31,235,255,199, 74, - 38, 27, 4,224,207,242, 52, 9,112,102,213,170, 85,117,235,213,171,135,111,191,253, 22, 0, 94,120,113,251,246,129,207,233,245, - 6,160,112,242,209, 34, 51,230, 50,157, 54, 74,137, 82,229, 13,133, 58, 24,117,234,122, 67, 20,221,159,243,148,150,147,119,251, -197,175,100,244,170,130, 19, 73,223,165,105,191, 65,186,126,248, 15,244,236, 17,134,131, 71,207, 98, 87,130, 10, 97,178, 20,132, -232,210, 33,166, 95,196,155,253, 27, 97,206,218,194,139,248,217, 56,215,154,132, 16, 28,124,251, 21,168, 85, 10, 60,187,234, 79, - 72,165, 82,252,245,230,243,144, 74,229,104,247, 85, 97,147,236,153,207,166, 64, 34,151, 35,250,141,105,110,165,179,100, 75,141, -189, 43,135,243, 54,229, 69,176,202,203,123,126,126, 62,114,114,114,240,211, 79, 63, 97,248,240,225, 72, 75, 75,195,205,155, 55, -113,229,202, 21,252,242,203, 47,142,209,233, 21, 73,167,221,188,188,245,214, 91,160,148,162, 78,157, 58,152, 54,109, 26, 90,182, -108, 89,225, 99, 84,242,184,151,196, 85,244,170, 60,205, 57,115,230,220, 83, 89,122, 34, 12, 86,121,119, 37, 28,199,193,223,223, -223, 81, 56,156, 11,222,189,220,233,242, 60, 15,171,213,234,232, 56,109, 95, 0,160, 87,175, 94,216,188,121,179, 59, 35, 35,182, - 18, 66,134,214,174, 93,251,135,233,211,167,107,218,181,107, 39,132,132,132,160,105,211,166,184,124,249, 50,254,248,227, 15,203, -252,249,243,181, 58,157,110, 4,165,116,199,189,212,201,246, 71,207, 56, 47, 21,193,102,179, 37,196,199,199, 7,127,249,229,151, - 60,199,113,152, 51,103,142,243, 67,174,239, 42,132, 71,142, 28,177,186,106,146,177, 90,173, 9,241,241,241,193,179,103,207,230, - 9, 33, 14, 77,231,201, 95,157,247,157, 59,154,165,153, 75,251,128,135,210,150,210,210, 94,218, 49, 46,111, 34, 81, 65, 16,112, -249,242,101, 76,157, 58, 21,132, 16,252,246,219,111,143,197,201,117,240, 88,242,210, 86, 77, 66,124, 6,245,111, 95,143,128,131, -201,124,247, 0, 52, 62, 51,199, 97,174,158,153,189, 26,235,223, 30,232,142,217,185,118,236,216, 49,223,207, 63,255, 92,224,121, - 30, 95,127,253,117,177,201,126, 75, 30,247,163, 71,143, 90,239,169,121,175,232,124, 54,155,205,208,235,239, 45,106, 66, 57,114, -104,206,231, 31,118, 89,244,227,102, 9, 33, 38, 28,222,251, 27,114,115, 74, 31,154, 46,147, 8, 88,177,106,147, 85,224,185,132, -127,249,208, 45,234,220,185,243,212,157, 59,119, 10,149, 43, 87,190,103,145, 54,192,230,121,243,230, 61,245,252,243,207,251,214, -174, 93, 27,235,215,175, 7, 0, 89,209,130,162,153,221,183,186,103,146,196,141, 95,127,241,225, 11,139,127,220, 44,227,136, 25, -135,247,253,134,220, 18,102,189, 36, 82,169, 4, 43, 87,109, 52, 11, 2,127,201, 85,189,238, 28,189,186,223, 11,162,115,217,107, -212,243, 37,124,251,199, 98, 4,212,235,142, 1,189, 98,113,224,219,231, 49, 32,218, 0,243,154, 33,168,219,127, 57,150,189, 83, - 24,189,105,184,246, 93,183,174, 63, 30, 30,106, 71, 7,114,142,227, 32, 87,168, 32,145,255,191,255,144, 76,165,130, 80,129, 72, -150, 61,239,229, 69,170, 42, 26,193,226, 56, 14,145,145,145,168, 90,181, 42, 90,183,110,141, 70,141, 26,161, 67,135, 14, 56,125, -250, 52, 78,159, 62,141,113,227,198,149,105,174,220, 57, 70, 93,186,116,193,165, 75,151,238,187,144,151, 60,238, 15, 2,119,202, -210,107,175,189, 6, 0, 79,110, 31, 44, 87, 59,207, 94, 32,233, 3,232,140, 74, 8,129,201,100,114, 52,189, 57,207,171,100,239, -244,238,230,124, 80, 59, 8, 33, 49, 31,124,240,193,120,133, 66,209, 65,167,211,213, 4, 0,181, 90,125,217,104, 52,254,165,215, -235,191,166,148,230,220, 79, 90,157,167,101, 40, 37, 31,229,238,140,244,244,244,110,195,134, 13,219,193,113, 92,100,121, 15,231, -117,186,243,191,153,154,154,250,148, 43,205,161, 67,135,150,170, 89,154,174, 59,154,165, 29,115, 81, 20,203, 52, 87,238, 84, 64, -174, 38, 18,149, 72, 36, 80,171,213,216,176, 97, 3,252,253,253, 31,171, 19,236,208,241,228,207,203, 91,223,222, 95,190, 23, 64, -165,103,102,175,190,189, 39,195, 20,222,222, 95,118,107,253,219, 3,171,148,247,155,236,236,236,174,111,189,245,214,159,130, 32, - 68,150,119,188,157,140,120,124,122,122,122,133,167, 61,160,148,226,210,165, 75,226,203, 47,191,156,145,158,158,254,220,189,228, -127,236,248, 47,190,154,247,229,155,126,253,251,180,105, 10, 66, 96, 50,149,209,169,151,128, 82, 74,169,192,115, 9,175,191, 53, -251,149,127,243,152, 81, 74, 79, 17, 66, 62,170, 86,173,218, 72, 0,101, 93, 9,127,113,165,179, 7, 48,203,140,198, 47,155, 52, -105, 50,233,221,119,223,245,238,213,171, 23, 42, 87,174, 92,230,124,129,229,113,224,104,226,200,150, 77,130,195,250,245,110,211, -141, 35,132, 26, 77, 70, 23,245,106,209,254, 20,248, 75,123,143, 36,212,119, 21,157,231, 56,174,194, 93, 20,220,161, 83,255,225, -232,212,127,184,163, 60,237, 92,211, 30,113,201, 59,208,152, 75,132,113,113, 27, 16, 79,123, 81,231, 93, 94, 39, 56,142, 67,239, -101, 27,139,165,179,245,103,197,163,179, 53,199,124, 80,161,107,143,243,224,171, 7,213, 7,139,231,121,100,100,100,224,242,229, -203, 72, 77, 77,133, 78,167,195,133, 11, 23, 96, 54,155,145,157,157, 13,251, 72,195,123, 73,231,131, 58, 70,255,166,230,147,212, - 76, 88, 33,131,101,179,217, 18, 93, 61,245,220,106,181, 86,104,148,145, 32, 8,134, 54,109,218,144,210, 70, 27,216,223, 43,149, - 74,189,155, 21, 99, 14,128,169, 0,166, 22, 61,111, 10, 89, 89, 89,247,237, 2,109, 54, 91,114,179,102,205,248,242, 12,145,205, -102, 75,117, 97,134,180, 0, 90, 62,200,131,247, 79,104,150,114,124,180,237,218,181,187,107, 30, 19,231,227,163, 80, 40,202,237, -117,235,106, 34, 81,157, 78,151, 50,108,216, 48,155,115,179,160,243, 68,164,143, 53,132,222,234, 49,232,165,240, 61, 25,166,112, - 0,176,155, 44, 80,122,171,172,159, 36, 39, 39,235, 1,180,251,167,147,118,227,198, 13, 83,243,230,205, 87,230,231,231,191, 70, - 41,189,231, 94,250,227, 38,204,121,247,191,118, 88, 40,165,167, 0,140,186, 95, 29, 19,112,177,142,193,240,218,180, 15, 62,120, -246,195, 15, 62,168, 33, 2,126, 64,225, 28, 85, 60,176,186, 34, 90,135,143,167, 60,240,185,193,108, 54, 91, 98,171, 86,173, 42, - 20,169,113, 85,199, 91,173,214,114,175, 19,171, 80, 25, 56, 94, 49,205,127, 34,157,206,154, 13, 26, 52, 64,195,134, 13, 29,175, -118, 74,126,239,142,102,227,198,141, 81,167, 78,157, 50,103,104, 47,217,231,234,223,206,187, 93,211,110,251, 27, 54,220,254,192, - 52,239, 55,157, 79,148,193,178, 63, 99,240, 65,114,254,252,249,127,228,217, 40,148, 62,184,177,222,231,207,159,111,138, 39,148, - 75,151, 46,249,221,175,134,171,137, 68,207,156, 57,211,225, 73,221,191,123,210, 77, 47,222,245, 93,145,217,250,183,209,106,181, - 85, 40,165,247,212, 51,191,127,255,254,182, 39,245,152,130,210, 98, 19, 79,157, 47,156,160,244,167, 71, 49,169,231,206,157,123, -224,117,250, 63,113,157,248, 39,210,201,242,254,232,107,254,215, 97, 51, 68, 50, 24,140,178,110, 82,108,108, 47, 48, 24, 12,198, -189, 65, 0,116, 46,163,114,117,123,228, 14, 33,164,243, 61, 84,222, 59,153, 38,211,100,154, 76,147,105, 50, 77,166,249,100,105, -186,210,126,208, 35,135,255,205,187,212,127,108, 1,208,153,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,243, 73, 91, 88, 19, - 33,131,193, 96, 48, 24, 12,198, 3,134, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, - 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131,113,239,144, 7, 56, 31, 39,131,193, 96, 48, 24, 12, 6, 3, 44,130, -197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6, -131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12, -198,163, 96,176, 8, 33,157,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,153,193, 98, 48, 24, 12, 6,131,193, 96, 48,131, -197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6, -131,193, 96, 48,254, 37, 8,128, 82, 71, 2, 80, 74,119,186, 45,114, 15,163, 9, 92,233, 51, 77,166,201, 52,153, 38,211,100,154, - 76,243,241,211,116,165, 93, 17,255,241, 72, 67, 41,253,199, 22, 0,157,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,159, -180,133, 53, 17, 50, 92,221, 97, 8,132, 16,225, 94,215, 63, 44, 77, 6,131,193, 96, 48, 30, 37,216, 69,140, 81,158, 17,106, 9, -160,103,209,251,223, 41,165,135, 43,178,254, 97,105, 62, 44, 26, 55,110,172, 84, 40, 20, 93,119,239,222, 45,187,112,225, 2,254, -254,251,111,186,114,229, 74,179,193, 96,216, 30, 23, 23,167,103, 37,230,191, 79,163, 70,141,186, 1,152, 82,244,241,211, 19, 39, - 78,108,187,207,115,136, 84,171, 86,109,156, 76, 38,235, 33,149, 74, 67,172, 86, 43, 49, 26,141,201,122,189,126, 71, 82, 82,210, -108, 74,169,120, 15,154, 77,253,253,253, 71,197,196,196,212,184,113,227, 70,194,237,219,183, 87, 0,216, 6,160, 91,149, 42, 85, -134, 69, 69, 69, 85, 62,119,238,220,149,140,140,140,133,148,210,191,255,173,116, 50, 24,204, 96,185,119,242,113, 62, 62, 62, 93, -148, 74,229, 27, 5, 5, 5, 13, 61, 61, 61,207, 91,173,214,121, 41, 41, 41,191,179, 19,239,177, 53, 87, 2,128,158,148, 82, 9, - 0,240, 60,223,167,101,203,150,225,132, 16,145, 16, 66, 41,165,132,227,184,134, 54,155,141, 43,218,190, 39, 33,228,111, 74,169, -181, 34,154,205,155, 55,175, 44, 8, 2,165,148, 18, 74, 41,199,113, 92,253,138,104, 62, 40, 98, 98, 98,102, 81, 74, 67,202,219, - 70,173, 86, 55,217,189,123,119,173,141, 27, 55,218, 86,172, 88,145, 51,104,208, 32,205,240,225,195,133, 31,127,252,241, 59, 0, -111,148,220,190, 78,157, 58, 95,113, 28,231,239,206,255,139,162,152,113,254,252,249,183, 88,201,251,215,153,242,242,103,123,219, - 82, 10,124, 63,165, 29, 87,100, 92,238,153,134, 13, 27,254,212,183,111,223, 65, 53,107,214, 20, 68, 81,132,197, 98,129,201,100, -170,117,226,196,137,246,219,183,111,111, 2,224,185, 10,158,151, 61,167, 76,153,178,228,163,143, 62,170, 36,145, 72,136,197, 98, -105,241,235,175,191,118, 31, 53,106,212,169,133, 11, 23, 54, 24, 48, 96,128,135,253,251, 15, 63,252,240, 41, 66,200,120, 74,233, - 47, 15, 59,157, 12, 6,195,133,193,242,240,240,168, 94,169, 82,165,183,253,252,252,158,106,210,164, 73,238,171,175,190,122,253, -218,181,107,103, 35, 35, 35,117, 63,254,248,227, 76,139,197, 50,191,102,205,154,219,243,242,242,102,223,185,115,231, 66, 5, 43, -138,234, 0, 94, 5,240, 20,128, 48, 0,201, 0,254, 4,176,132, 82,122,233, 94, 50, 19, 26, 26, 90, 79,173, 86, 79, 34,132,180, -208,106,181, 97,106,181, 58,153, 82,122, 52, 63, 63,255,139,148,148,148, 19,247,162, 25, 22, 22, 86, 21,192, 88, 65, 16, 98,109, - 54, 91, 36,207,243,183,108, 54,219,126,155,205,246,109,114,114,242,149,123,209,108, 93,217,163,151,168,241,156,109,225,149,149, - 11, 12, 86,169, 70, 46, 88, 36,162, 33, 65,212,230, 76, 57,122,187,224,183, 71,177,160,200,100, 50,110,197,138, 21, 13,100, 50, - 25, 0,192,100, 50, 33, 38, 38,134,220,143,166, 68, 34,225,102,207,158,221, 72, 16, 4,152,205,102, 49, 63, 63,159, 62,251,236, -179,255, 74,179, 53, 33, 36, 44, 46, 46,206, 75, 42,149,150,186,222,102,179,161,119,239,222,145, 82,169, 20, 11, 22, 44,176,100, -102,102, 54, 92,186,116,233,137,249,243,231,251, 47, 91,182,172,127,105, 6,139,227, 56,255,178, 52,109, 54, 27,204,102, 51,172, - 86, 43, 76, 38, 19, 58,116,232,192,106,163, 71,131,112, 0,216,114,218, 0, 0,190,247, 43,166, 84, 42,163,159,121,230, 25, 33, - 61, 61, 29, 18,137, 4,102,179, 25,119,238,220, 65,181,106,213,248,141, 27, 55,214,172,168, 94,173, 90,181, 70,125,242,201, 39, - 1, 91,182,108, 49,175, 92,185,210,216,185,115,103,233,136, 17, 35, 60,219,182,109, 27, 27, 22, 22,198,253,240,195, 15,198,157, - 59,119,154,135, 14, 29, 42,159, 53,107, 86,192,159,127,254, 57, 8,192, 47, 15, 59,157, 12, 6,163, 28,131,229,225,225,177, 87, -163,209, 84,123,229,149, 87, 46,189,246,218,107,219, 53, 26,141, 13, 0,126,254,249,103,161, 79,159, 62,233,207, 62,251,108,154, - 78,167,227,231,207,159, 95,229,155,111,190,217,225,225,225,145,148,159,159,223,204,141, 11, 25, 1,240, 6,199,113, 99,187,118, -237,186,215, 98,177,164,111,218,180,105,205, 51,207, 60, 19, 75, 41, 85,239,222,189,251, 15, 66,200, 34, 0, 95,186, 27, 29, 35, -132,240, 81, 81, 81,211,194,194,194, 38, 44, 88,176, 64, 30, 21, 21, 5,165, 82,137,252,252,252, 42, 87,174, 92,169,252,198, 27, -111,244,174, 90,181,234, 60, 47, 47,175,247,227,226,226, 44,110,106,146,144,144,144, 55, 61, 61, 61, 63,158, 53,107,150,162,118, -237,218, 68,173, 86, 35, 62, 62,190,238,145, 35, 71, 98,150, 46, 93, 58, 34, 44, 44,108,122, 82, 82,146,219,233,108, 79,136, 96, -168, 90,105,187, 79,173,102,237, 23, 46,249,158,248,171, 85, 16, 8,129,197,108,150,164,234,244, 81, 99, 70,143, 92,211,178, 70, -208,193,124, 73,106,167,243,231,169,249, 95, 50, 26,114, 0,160,148, 26, 9, 33,191,243, 60,223, 71, 38,147,113,125,250,244,193, -206,157, 59,137,193, 96, 16, 0, 64,161, 80, 88,251,244,233, 3,165, 82, 9,147,201, 36, 2,248,189,172, 72, 83,105,154, 18,137, -132,235,208,161,131,238,216,177, 99, 89,118, 77,149, 74,101,233,208,161,131,159, 76, 38, 83, 90,173, 86, 90,158,230, 63,100, 34, -113,237,218,181, 98,223,229,231,231, 35, 61, 61, 29,153,153,153, 48,153, 76,200,201,201,129, 40,138,196,104, 52,166,139,162, 8, -142, 43, 12,182,149,165, 41,149, 74,113,249,242,229, 98,223, 89,173, 86,104,181, 90, 24,141, 70,152,205,102,232,245,122,165, 66, -161,168, 30, 27, 27,155, 8, 96, 99, 65, 65,193,236, 83,167, 78,221, 98,213,211,191,194,237,223, 79, 26,170, 0, 48, 1,136,127, - 0,231,147, 8, 0,251,247,239, 71,106,106, 42, 50, 50, 50,144,158,158,142,176,176, 48,220, 75,244,255,210,165, 75,115, 27, 54, -108, 72, 78,157, 58,181, 25,192,146,213,171, 87, 63,147,149,149,181, 96,226,196,137,190, 95,124,241, 69,214,164, 73,147, 70, 3, - 88,191,122,245,234,225,245,234,213,235,117,230,204,153, 57,255, 70, 58, 25, 12, 70, 57,243, 96, 81, 74, 67,170, 87,175,158,245, -245,215, 95,215,154, 50,101,138, 95, 65, 65, 1, 95, 20, 37, 50, 16, 66,168, 78,167,227, 39, 79,158, 92,233,211, 79, 63,173, 37, -151,203,179,173, 86,107,165, 82, 52, 74, 27,106, 57,214,211,211,179,119,124,124,252,234, 90,181,106,249,126,242,201, 39, 39,149, - 74, 37,157, 59,119,110, 92,213,170, 85,131,111,221,186,181,220,211,211,179, 35,128, 9,101,164,235, 46,205,200,200,200,143,251, -247,239, 63,225,224,193,131,242,250,245,235, 67,163,209,128,231,121,120,123,123,163,121,243,230,100,223,190,125,242, 30, 61,122, -140,203,205,205,253,194, 93,205,144,144,144,119,187,119,239, 62, 51, 46, 46, 78,217,169, 83, 39, 34,147,201,144,157,157, 13,185, - 92,142, 22, 45, 90,144,133,243,191, 83,214,173, 83,251,195,176,176,176,143,220,213, 52, 87,247,223, 49,232,245,201, 29,126,255, -115, 27, 9, 12, 12,196,245, 47, 63,194,254,182, 49,184, 58, 99, 10,130,131,131,177,121,203, 86,210,235,133,215,219,120, 90, 2, -119,187,171,121,191, 56,107, 18, 66, 94, 3,144, 5, 32,139, 16,242, 26,165,244,112, 76, 76, 76,220,133, 11, 23, 16, 27, 27,139, - 53,107,214,212,159, 56,113,226,107, 19, 39, 78,124,109,205,154, 53,245, 99, 99, 99,113,225,194, 5,196,196,196,196, 57,247,149, -114, 71,115,239,222,189,232,216,177, 99,246,154, 53,107,162,166, 78,157, 58,107,234,212,169,179, 86,175, 94, 93,181, 99,199,142, -217,115,230,204, 49,150,167,249, 79,228,221, 57,178,228,188,136,226,255,175, 45, 1, 1, 1,105,191,255,254, 59,122,245,234,197, - 5, 6, 6,166,244,233,211, 71,126,236,216, 49, 10,224,247,138,164,211, 96, 48, 64,175,215, 67,171,213,226,246,237,219,202,249, -243,231,183,153, 48, 97, 66,181, 53,107,214,132,142, 27, 55,110,180,167,167,231,137, 6, 13, 26,132, 63,236,188, 51, 77,128,227, -184, 59, 0,204, 0,180, 28,199,221,186, 31,205,126,253,250,213,141,136,136, 8,252,245,156, 15,178,165,181, 32, 74,189, 33, 74, -189, 97,243,107,138,107,178,167, 16, 26, 26, 26, 24, 30, 30,222,178, 34,154,148,210, 29, 39, 79,158,124,138, 82,186,144, 82,106, -163,148,174,157, 52,105,210,203,132,144,223, 38, 77,154, 52,146, 82,186,182,232,251,165,167, 79,159,238, 69, 41,253,235,223, 72, - 39, 43, 75, 76,147, 81,142,193, 34,132, 88, 62,255,252,243, 35,223,127,255,253,206,148,148,148,224,168,168,168,167,159,121,230, -153,240,220,220, 92,242,204, 51,207, 68, 6, 7, 7,247,220,187,119,111, 80,255,254,253,119,247,239,223,255, 48, 33,196,101,164, -129, 16, 82,149,231,249,241,167, 78,157, 58, 80,165, 74, 21,115,114,114,178, 71,195,134, 13,243, 1,160, 70,141, 26,186,204,204, - 76,165,151,151, 23,182,110,221,122,140, 16,242, 42, 33,164,150, 43,205,224,224,224, 70,126,126,126,111,124,252,241,199,114,158, -231, 75,221, 70, 46,151,227,227,143, 63,150,123,122,122,190, 18, 26, 26,218,194,149,102, 80, 80, 80,109, 15, 15,143,247,190,249, -230, 27,133,209,104,132,201,100, 66, 96, 96, 32, 52, 26, 13, 82,146,147,145,124, 51, 30,169,241, 55, 48,238,229,151,148,106,165, -114,124, 72, 72, 72, 3, 87,154,177, 17, 30,125,212, 97,117,218,143, 25,251, 6,206,141, 27,142,157,161, 50, 4,141,157,140,250, -123,206, 34,108,250,108,252, 21,229,137,184,231,186,224,205, 55,223,130, 52, 32,170, 85,171,202,154,129,255, 66,228,234, 11, 74, -169,146, 82,170, 36,132,204,109,213,170,213, 74,165, 82,249,218, 39,159,124,210,109,251,246,237,221,247,237,219,215,222,106,181, - 74,172, 86,171,100,255,254,253,177, 6,131, 65,144,203,229, 16, 4,129,186,171,217,178,101,203,159,148, 74,229,232, 5, 11, 22, -116,251,235,175,191,134, 29, 63,126,252,117,155,205, 38,179,217,108,178,227,199,143,143,212,235,245, 18, 74,169,173, 44,205,135, -141, 68, 34,129, 84, 42,133, 82,169, 68,195,134, 13,175,175, 90,181,202, 18, 28, 28, 44, 89,178,100,137, 79, 96, 96,160,122,217, -178,101, 57, 57, 57, 57,159,185,171,103, 54,155, 97, 52, 26,161,215,235, 97, 48, 24,112,232,208,161,200, 17, 35, 70, 8, 38,147, -201, 54,108,216,176, 44,139,197, 98, 28, 51,102,140,167, 70,163,121,155, 85, 79, 15,159,162,136,105, 1, 0, 45,165,212,104,255, - 62, 34, 34, 66, 30, 26, 26, 90, 47, 34, 34, 66,238,174, 86, 65, 65,193,162,175,190,250, 42,140,147,123,227,128,169, 7,126, 17, -167, 99,187,215,183, 72, 11,159,128,128,176,106,232,222,189,123, 0, 33,228,219, 7,144,230,141,148,210,254,148,210,117,247,242, -251,127, 58,157, 77,155, 54,141,109,210,164,201,241,198,141, 27,167, 52,105,210,228,120,211,166, 77, 99,239, 55,207,207,197,144, -206,195, 26,240,137,253,235, 16, 58,172, 1,159,248, 92, 76,197,231,106, 98, 48,254,105, 92,118,114,175, 84,169,146,233,221,119, -223, 61,101, 48, 24,206,254,244,211, 79,213,134, 14, 29,218, 48, 60, 60,252,242,179,207, 62,251,135, 70,163,177,218,251,228,184, -201, 75, 61,122,244,216,226,239,239,143,220,220, 92,193, 98,177,240, 90,173,150, 7, 0, 81, 20, 97, 48, 24,248, 27, 55,110, 8, - 70,163,145,182,104,209, 98,211,225,195,135, 95, 5, 48,190, 60, 65,181, 90,253,218,226,197,139, 21,101,153, 43,155,205,134,252, -252,124, 88,173, 86, 76,159, 62, 93, 49, 97,194,132, 55, 0, 28,113,113, 81, 29, 59,119,238, 92,185,213,106, 5,199,113,160,148, -226,196,137, 19,200, 76, 75,131, 33, 63, 15,198,188, 92,152,243,114,193,107,243, 49,236,169,110,138,133,235, 54,188, 5, 96, 88, -121,154, 38,185,230,211,159, 22, 47,133,205,102, 67,202,198, 95, 75,221, 38,235,224, 30,216,172, 22,124,242,217, 23,228,205,151, - 6,124, 2, 96,245,191, 85, 48,228,114,185,176, 98,197,138,193, 50,153, 12,148, 82, 98, 50,153,176,125,251,246,251,214, 92,190, -124,249, 48,187,166,217,108,166,117,235,214,189,171,121,205,104, 52,210, 71,229, 4,145,201,100, 80, 40, 20, 48,155,205,168, 82, -165,138,190,119,239,222,135,230,206,157, 91,133,231,121,181, 32, 8, 91,115,115,115,103,157, 59,119,238,134,187,122, 69,157,135, - 97, 50,153,160,215,235,113,251,246,237,160,208,208, 80,242,222,123,239,217,116, 58, 93,212,210,165, 75,175,253,250,235,175,170, -111,190,249,230, 89, 0, 99, 89, 21,245,240,168, 86,173,154,204,211,211,211,171,138,159,160,149,240, 40, 72,163,212, 35, 34, 34, - 34,220, 98,177, 60, 75, 8,105, 81,163, 70, 13,159,171, 87,175,102,135,134,134, 30,225, 56,238,151,132,132,132, 20, 23,198,135, - 88,173, 86,140,108,150,131,215, 90,242,176, 88,114,145,155,155,139, 91,183,110,225,252,249,243, 56,122,244,220, 61,165, 51, 50, - 50,242, 37,133, 66,209, 85, 38,147, 69,216,108, 54, 78,167,211,221, 50, 26,141, 59,147,147,147, 23,209,162, 9,138, 42,104,208, -254,145,116, 58,233,207,126,230,153,103, 66,188,188,188,112,242,228,201,144,211,167, 79,207, 6,208,228,190,206, 75,129,251, 97, -198,151,223,134, 6,251,123,227,220,193,205,161,115,150,252,250, 3, 10,251,242, 50, 24,255, 29,131,101, 71,161, 80,216, 70,141, - 26,117,121,211,166, 77, 17, 77,154, 52,185, 88, 86,103, 96, 23,180,142,142,142,190,117,232,208, 33,248,250,250,154, 45, 22, 11, -111, 48, 24, 56,169, 84, 74,179,178,178,136, 94,175,231, 78,159, 62,173, 72, 76, 76,148,250,248,248, 72, 0, 52,114, 35,194,208, - 50, 50, 50,178,116, 83, 99, 50,161,160,160, 0,249,249,249, 48, 26,141, 8, 12, 12, 36, 28,199, 53,119, 25,214,227,184, 54, 53, -107,214, 36,217,217,217, 8, 9, 9,193,193,131, 7, 81,144,147, 3, 67,126, 30, 76,121,185, 48,231,230,192,146,155,131,156,180, -100, 68, 4,135,145,162,169, 5,202,197,202, 43,195, 3, 52,106, 92,157, 49, 25, 77, 79,220, 2,145, 72,113,172,110, 48,168,165, -176,171, 85,179, 51,201, 32, 82, 25, 46,142,123, 17,129, 67, 95,129,133,147,135, 62,228, 59,119, 35, 33,100, 34,199,113,115,229, -114,185, 48,122,244,104,164,164,164, 20, 51, 63,163, 71,143,118,244,185,106,219,182,237,126,133, 66, 97, 77, 79, 79,135,209,104, -148,184,163, 25, 17, 17,113,235,253,247,223, 63,102, 50,153,194, 66, 66, 66,188,141, 70,163,190,102,205,154, 33, 74,165, 50,208, -100, 50,217,154, 52,105,178, 72,169, 84, 90, 10, 10, 10,168,213,106, 37,143,194, 9, 66, 8, 1, 33, 4, 86,171, 21, 86,171, 21, -222,222,222,218,204,204,204,163,215,175, 95, 31,124, 47,122, 22,139, 5, 22,139,197, 17,197, 18, 69, 17,103,206,156,129, 66,161, -144,136,162,120,206,102,179,169, 36, 18, 9,120,158,103,115,212, 61, 68, 26, 55,110,220,190,126,160,231, 87,163, 67,140,222, 85, -123,169,181, 42, 25,175,253, 34, 83, 25,241,199, 79,218,213, 61,123, 12,244,152, 48, 97, 66,184,175,175,175,226,198,141, 27,134, - 57,115,230, 68,174, 95,191,158, 0,248,178, 60,205,228,228,228,223, 62,253,244, 83,223,246,237,219, 71, 73, 36, 18,146,147,147, -131,244,244,116,164,165,165,225,246,237,219,244,230,205,155,215,173, 86,235,154,138,164,179,126,253,250, 75,135, 14, 29,250,124, -157, 58,117, 36,148, 82,152,205,102,232,116,186,134, 71,143, 30,237,125,224,192,129, 88, 0, 21, 46,151, 41, 41, 41,107, 62,251, -236, 51,117,187,118,237,106, 73, 36, 18,238, 65,164,179, 68, 61, 16,162,209,104,176,115,231, 78,120,123,123,195,213,104, 93,119, - 48, 90,196,208,160, 0, 63, 24, 14,126,133,234,190,225, 48, 90,196, 80, 86,138, 25,255, 89,131,149,158,158, 46,211,106,181,130, - 40,138,124,110,110,174, 74,165, 82, 89,101, 50,153,169,130,255, 87,167,119,239,222,199,154, 55,111, 94, 80, 20,209,176, 4, 4, - 4,152,115,115,115, 33,138, 34, 68, 81,180,122,122,122, 22, 88, 44, 22, 68, 69, 69,113, 0, 92, 54, 17,234,245,250, 42, 74,165, -242,174,239,117, 58,157,195, 92, 21, 20, 20, 64,167,211,193,203,203, 11, 90,173,214,229,201,109,179,217, 34, 84, 42, 21,146,147, -147, 1, 0,249,217, 89, 48,230,229,193,148,255,127,115,101,203,201,134,168,215,194, 59,172, 50,172, 86,107,101, 87,154, 90,163, - 77,198,131, 34,109,243,111, 8,124,109, 98,153,219,101, 31,216, 3,143,234,209,208,235,205, 15,125,142, 50, 74,233,252,134, 13, - 27, 54, 90,191,126,253,136,164,164,164,187,214,247,237,219, 23, 99,199,142,197,152, 49, 99, 46, 62,253,244,211,167, 55,111,222, -140,215, 95,127, 29,162, 40, 54, 32,132,228, 82, 74,255, 44, 79,115,202,148, 41,199, 19, 18, 18,246, 92,185,114,101,116, 64, 64, -128,188, 94,189,122, 87,235,213,171,199,175, 95,191, 62,240,149, 87, 94,137,235,222,189,251,205, 93,187,118,249,238,220,185, 83, - 33,138, 98, 99, 66, 72,210,191, 61, 15,150,189,137,216,100, 50,193, 96, 48,192,108, 54,195,102,179,145, 10,236,211, 98,159, 69, - 81,116,152, 53,163,209, 8,139,197, 66,118,236,216,142,205,155, 55,115, 23, 46,156, 15,155, 50,229, 29,228,230,230,194,102,179, -177,218,233, 33,208,164, 73,147,167, 4, 42, 46, 30, 26,100, 85, 12, 14,180,106,165,132, 22, 92, 89,252,126, 65,124,184, 70,235, -233,207,155, 60,253, 36, 33,147,167, 76, 14,190,126,237,186,241,243,207, 63,191,208,179,103,207,128, 87, 94,121,165,246,150, 45, - 91, 98,171, 84,169,242,253,237,219,183,115,202, 48,230,210, 17, 35, 70, 28,245,246,246,174,186,114,229,202,180,164,164, 36, 31, -139,197,162,178, 88, 44,102,131,193,112,205,108, 54, 31, 48,153, 76, 59, 83, 82, 82,226, 42,146, 94,141, 70, 83,127,192,128, 1, -146,156,156, 28, 20,141,190, 69, 90, 90, 26, 26, 53,106,196,239,218,181,171,206,189,236,131,243,231,207,127, 21, 18, 18,178,103, -211,166, 77, 93,213,106,117, 99,153, 76, 22, 36,138,162, 77,175,215,167, 26, 12,134, 83,247,146,206, 18,251, 34,249,196,137, 19, - 33,158,158,158, 72, 72, 72, 0, 33, 36,249,126,143,155, 66,202, 37, 92, 56,176,169,114,117,223, 72, 28, 61,114, 4, 10, 41,151, -192, 74, 51,227, 63,101,176,242,243,243,133, 19, 39, 78,248, 36, 36, 36,104,252,253,253, 13,181,107,215,206, 37,132,136, 28,199, -209,148,148, 20,223,248,248,120,133,159,159,159,182,106,213,170, 89,110,254,223,149,113,227,198,197, 78,157, 58, 53,174, 75,151, - 46, 25, 0,144,157,157,141,204,204, 76,164,167,167,195,108, 54, 35, 57, 57,153, 59,126,252,184,239,214,173, 91, 27, 2,112,217, -244,162, 84, 42,111,231,231,231,215,244,246,246,118, 92,208,236,166,202,217, 96,217,163, 89,106,181,218,229,201,205,113, 92, 82, - 82, 82, 82, 53,131, 94,143,219, 87,175,194,152, 95,216, 36,232, 48, 87,185, 89, 64, 65, 62,212, 10, 5,242,179, 50,193,243,252, - 29, 87,154,106, 57,111,178, 88,109,178, 74,221,123, 3,164,236,235,179, 87,179,214, 16,107,213,131, 82,185,214,242,111, 20, 8, -142,227,108,229, 53,251,202,100, 50, 4, 6, 6,138, 45, 90,180,192,235,175,191,110, 55, 2,132, 16,210,158, 16,114,128, 82, 90, - 80,150,166, 40,138,220,133, 11, 23,158,185,118,237, 26, 47,145, 72,184,230,205,155,199,180,105,211,198, 36,147,201, 32,149, 74, -133,130,130, 2,143,157, 59,119, 42, 44, 22, 11, 41,210,124,104,243, 96, 1,133,163,251, 74, 49,240,208,106,181,208,235,245, 40, - 40, 40, 64, 78, 78,142,160, 84, 42,107,182,109,219,246,136,209,104, 92, 99,179,217,126,136,139,139,203, 43, 75,211,108, 54, 23, - 51, 91,162, 40,130, 82, 10,155,205, 6,139,197, 2,137, 68, 34,110,218,180, 25,223,204,159,139,181,171,215,209,206,157, 59,147, -173, 91,183, 66, 20,197, 68, 86, 61,253,243,136,162, 56,251,175,201,253, 20,176,218,180,198,189,171, 10,182,101, 9,218,239,207, -253,117, 92, 47,112,121, 85,106,163, 94, 68,229,170,188,151,167, 23,183,108,249,226,204,173, 91,118, 95, 75, 76, 76,204,155, 49, - 99, 70,203,168,168, 40,175,203,151, 47,135, 2,200, 41,195, 8, 69, 12, 31, 62,124,120,118,118,182,116,201,146, 37,203,146,146, -146,246, 82, 74,175,151, 48, 30,141, 8, 33, 95, 0,144, 0, 8, 4, 96, 5,176,131, 82,186,188, 28,179, 34, 18, 66,240,215, 95, -127,221, 53,218, 79,116, 30,145, 81,241, 40, 86,118,243,230,205,235, 95,185,114,101, 99,118,118,246,202,146,235, 85, 42, 85,239, -152,152,152, 65,199,142, 29,251,128, 82,122,173,130, 55,110,227, 47, 92,184,240,185, 40,138,225, 28,199,221,162,148, 78,122, 0, - 17,172,151,231, 44, 89,189,196, 96,182, 85, 81, 72,249,219, 70,139,248, 10, 43,205,140,255,140,193,178, 90,173,154,247,223,127, -191,101,131, 6, 13, 82,218,182,109,123, 39, 50, 50, 82,103, 95,231,225,225,161,247,243,243,211, 27, 12, 6,229,173, 91,183,130, - 55,108,216, 80,195,102,179,169,220,248,191,221,222,222,222,190,199,143, 31,247,251,229,151, 95,170,159, 56,113, 34,124,200,144, - 33,237, 76, 38, 19,140, 70, 35,110,220,184, 17,190,120,241, 98, 81, 42,149,230, 16, 66,254, 6,224,242, 54,222, 98,177, 28,190, -114,229, 74,141,230,205,155, 19,139,197,226, 48, 84,206, 38,171,160,160, 0, 82,169, 20,201,201,201, 84, 20,197,163,110,164,243, -200,241, 99,199,170,213,173, 29, 13, 99,110,118,145,185,202,133, 53, 55, 27, 98,110, 22, 56,109, 1,252,124, 5,168, 20, 26, 92, - 78, 78, 65, 81, 90,203, 69, 98,213,223, 76,202,205,171, 89,109,218,151,248, 43,202, 19,212, 98,118, 52, 11, 2,112, 52, 23,182, -186,152,142,253,135, 14, 67,176, 25,147, 30,213, 66,115,250,244,233,180, 33, 67,134,196,137,162,216, 8,229, 76, 81, 80,206, 93, -120,126, 65, 65, 1, 50, 50, 50,108,153,153,153, 6, 0, 72, 75, 75,203,222,180,105,211, 5, 81, 20,155,221,139,230,131,192, 98, -177,220, 21,125,178,217,108,176, 90,173, 48,155,205, 72, 79, 79,151, 29, 56,112,160,237,145, 35, 71,164,231,207,159,199,145, 35, - 71, 26,108,216,176,225,157,232,232,232,122, 23, 47, 94,188,227,202,180,145,210,141, 53, 15, 0,155,214,255,142, 65,131, 6,145, -140,140, 12,108,216,176,225,129, 52,163, 48,220, 66, 11,171, 77,105,218,187,170,224,237,171,242,252,115, 58,126, 70, 92, 92,220, - 54, 74, 41,237,209,163,199,233,154,181,162,252, 1, 64, 46,211, 4,213,173, 91,183,157,143,143,143, 12, 0, 66, 66, 66, 26, 91, - 44,150,249, 0,218,148, 38,218,183,111,223, 86, 1, 1, 1, 13,255,252,243,207, 83, 73, 73, 73,251, 74,154, 43, 0,168, 89,179, -230,244,179,103,207, 62, 37,145, 72,136, 83, 25,161, 0, 74, 53, 88,253,250,245,171, 25, 22, 22,230,183,229,138, 23,242,164,213, - 64,249, 92, 64, 80,192,230, 93, 31,183,164,181, 17, 20,116,201,175, 90,181,106, 13,174, 93,187,118,170,130, 17,166, 42, 3, 6, - 12,248, 99,233,210,165,209,221,187,119,151, 1,184,203, 96, 69, 71, 71, 63,187,107,215,174,254,163, 71,143,174, 79, 8,233, 69, - 41,189,234,174,126, 92, 92,220, 65, 0, 45, 31,228, 65, 91,115,142,238, 68,209,156,101, 12,198,127,206, 96,153,205,230, 29, 87, -175, 94,109,218,175, 95,191, 12,103,115, 69, 41,117, 84, 6, 94, 94, 94,122,127,127,255,172, 83,167, 78, 85, 18, 69,113,175, 27, -255,183,100,215,174, 93,127,205,155, 55,111,149,175,175,175,101,216,176, 97,220,228,201,147,247,103,102,102,210,204,204, 76,124, -251,237,183,109, 99, 99, 99,247,223,186,117,203, 22, 23, 23, 55, 28, 64,119,151,181,163, 86, 59,255,245,215, 95, 31,180,127,255, -126,133,125,158,162,146,209, 43,139,197, 2, 65, 16, 48,127,254,124,163, 86,171,157,235, 70, 36, 99,209,119,223,125,215,127,241, - 55,243, 20,188,217, 12, 75, 78, 22,172,185, 57,176,229,100,129,211,105,225,161, 32,168,222,168, 18,178,147,228, 88,177,237,160, -222,106,181,126,231,210, 96, 25, 10, 38,142, 30,249,234,239, 59,118,255, 5,223, 54, 29,145,249,215,214,187,163, 67,149, 2, 97, - 50,155,241,241, 71,211, 40,209,231, 76,254,151,238,232,121,147,169,236,150, 95,147,201, 4, 81, 20, 19,207,159, 63,191,154, 16, -146, 79, 8,105, 95,180,106, 79,105,209, 43,103, 77,142,227,196,218,181,107,175, 15, 12, 12,124, 6,128,182,118,237,218,235,229, -114,121, 71,147,201,212, 92, 20,197,196,147, 39, 79,174, 35,132,220, 33,132,244, 44,250,233, 67,157, 7,203, 98,177, 96,234,212, -169,248,244,211, 79, 49,101,202, 20, 71,126,237,205,132,102,179, 57,114,251,246,237,210,131, 7, 15,210,159,126,250, 41,243,185, -231,158,243, 30, 50,100,136,247,138, 21, 43,198, 3,152, 84,150,230,164, 73,147,176,112,225, 66,140, 26, 53,234,110,119,197,243, - 98, 82, 82, 34, 76,102, 19, 93,190,124,121,178, 32, 8, 62, 95,127,253,181,114,194,132, 9,132, 85, 79,255, 60, 54,155,237,189, -214,179, 55,188, 73,136,210,108,181, 90,231,158, 62,125,114,143,211,141,128,114,246,151,179, 5, 0,248,242,139,217, 18, 74,169, -151,125, 98,216, 25, 51,102, 40, 70,142, 28, 25, 80,150,238,218,181,107,115,102,204,152,225,247,242,203, 47,119,223,179,103,143, -138, 16,178, 5,192,223, 0, 50,138,110, 28,253, 1, 28,172, 84,169, 82,240,234,213,171,171,117,237,218, 85,237, 70, 93,247,253, -130, 5, 11, 34,102,239,243,192, 22,237, 51, 72, 16,159, 3,245,166,240, 13,200, 71,109,205,109,116, 8, 77, 10, 89,185,114,229, - 18, 0,141, 43, 96,174,234,244,235,215,111,195,210,165, 75, 35, 95,125,245,213,196,131, 7, 15, 38, 16, 66,166,151,178,105,230, -139, 47,190,120,107,217,178,101,213, 68, 81,220, 70, 8,233, 78, 41,189,194, 74, 16,131,113,111, 17,172,151, 8, 33, 49, 83,166, - 76,249, 60, 36, 36,164,202,180,105,211,226,107,215,174,173,117,156,109,153,153,154,189,123,247, 70,229,229,229,229, 91,173,214, - 97,148,210,211,165,156,188,157,157,231,202,160,148,222, 34,132,124,222,160, 65,131, 65,191,254,250,235, 94, 15, 15,143,188, 35, - 71,142,120,122,122,122,230, 94,184,112, 65,205,243,188, 46, 62, 62, 30,219,183,111,111, 11,224,155,210,238,146, 74,106,166,164, -164,156,136,138,138,154, 59, 97,194,132, 55, 62,248,224, 3, 5,165, 20, 58,157, 14,121,121,121, 48, 26,141, 16, 4, 1,132, 16, -172, 90,181,202,104, 52, 26, 23, 39, 37, 37, 29,113,165,153,156,156,124,184,114,229,202, 63,204,157, 51,231,229, 87, 6, 13,148, - 33, 55, 19, 57, 41, 73, 32,186, 2,104,148,114,196,116, 10,131, 54,147, 96,233,222,191, 77, 89, 70,243,234,164,164,164, 61,174, - 52, 15,220,206,255,163,101,141,128, 93, 51,102, 76,235,244,206,143,235, 32,138, 34, 46,190,254, 60,178,247,237,128,170,118, 61, -180,186,152, 14,147,201,132, 41,147, 38,128,215,165,238, 63,114,187, 96,173, 43,205, 7,129,179, 38, 33,228, 53, 66,200,243,209, -209,209, 24, 61,122, 52,250,246,237, 91,108,219, 13, 27, 54, 96,193,130, 5, 48, 26,141,207, 19, 66, 78, 80, 74,231, 19, 66, 14, - 20, 29,219, 2, 87,154, 17, 17, 17, 77, 99, 98, 98, 16, 18, 18,162, 43, 50, 23, 93,206,159, 63,223, 56, 58, 58,186,164,230,223, - 69,154,214,135,149,119, 74,105,246,213,171, 87, 61,191,248,226, 11, 98, 54,155, 49,125,250,116,216,141,166,189,229,229,221,119, -223, 13,209,104, 52,248,242,203, 47, 77, 25, 25, 25, 29, 23, 44, 88,176,123,222,188,121,254,171, 86,173, 26,108, 55, 88, 37, 52, -211, 46, 92,184,224,177,112,225, 66,206,106,181,226,171,175,190,186,171, 25,114,252,248,241, 48,155, 45, 16,120,193,100,208, 27, -234, 40, 20,138,107, 62, 62, 62, 74, 81, 20,233,195,202,251,147,172,121,250,244,233, 29, 0,118,184,243, 59,131,193,128,244,244, -116,100,100,100,160,168, 75, 2, 41, 43,157, 6,131,225,228,164, 73,147,226, 22, 45, 90,212,253,224,193,131,253,247,237,219,215, -125,231,206,157,134, 91,183,110, 89, 45, 22, 11, 13, 14, 14, 22,218,180,105,163,232,209,163,135, 90, 46,151,115,239,189,247, 94, -198,204,153, 51,253, 1,100,150, 83,127,242,148, 82,188,221, 54, 31,147, 58,240, 48,153,204,200,201,201, 65, 82, 82, 34,206,159, - 63,143,195,135, 47,130, 82,202, 85,112,127,206, 93,185,114,101,148, 76, 38, 35,171, 86,173,170,178,106,213,170,113,174,246,195, -242,229,203, 35, 86,173, 90, 53,191, 72, 75,100,101,137,105, 50, 42,104,176,138, 78,232,115, 0,186, 19, 66,218,188,250,234,171, -159, 69, 71, 71, 27,173, 86,171,100,219,182,109,181, 50, 50, 50,100, 86,171,117, 18,165,116, 95, 69,254,144, 82,186,144, 16,130, - 62,125,250, 76,170, 90,181,234,174, 19, 39, 78,212,239,221,187,247,182,245,235,215,183,177, 90,173,215,207,158, 61,251, 60,128, -185, 0,190,113, 87, 51, 62, 62,254,253,157, 59,119, 90,143, 28, 57,242,246,228,201,147,229, 1, 1, 1,196,199,199, 7,201,201, -201, 72, 76, 76,164, 63,254,248,163,209,104, 52,126,227,229,229,245,190,187,154, 50,153,236,237,125,199,227,200,229,107,215,134, -191,244, 84, 87, 69,229, 26, 53,161, 33, 53,145,159,153,129,125,123, 82,177,236,239, 83,134, 84,131,233,103,158,231,221, 30, 74, - 31,122, 53,189,219,142, 95,150,254,185,103,215,238,206,179, 62,253,156,132, 12,125, 25,234,136, 72,136, 17,213,177,119,207, 30, -204,156, 49,157,242, 5,169,251, 44,215, 82,187, 60,236,130, 96,159,179, 74, 20, 69, 1, 0,148, 74, 37,198,142, 29, 11,231, 71, -227, 44, 88,176, 0,122,189, 30, 0, 4, 66,200, 23,132,144, 31,202,138, 90,149,161, 89,101,203,150, 45, 85,156, 53,163,163,163, - 75,211, 52, 62,236,252,167,166,166,190,255,226,139, 47,126, 34,145, 72,188,203,218, 70,173, 86, 35, 63, 63, 31, 54,155,205,230, -235,235,123,201, 30, 25, 45,235, 60,210,106,181,239,143, 26, 53,234, 99, 66, 72,153,145, 14,165, 82,121,235,192,129, 3,213,135, - 12, 25,194,173, 94,189,250,198,224,193,131,229, 7, 14, 28,176, 1, 88,199,170,167, 71, 11,231, 1, 11, 90,173, 22, 0,104, 57, -219,222, 38,132, 76,138,139,139, 83,140, 26, 53,170,241,208,161, 67, 61, 59,116,232,160,113,222, 70,175,215,139,155, 55,111,214, - 46, 92,184, 48,115,223,190,125,127,143, 24, 49,226, 25, 20,206, 32, 95, 42,201,201,201,127,124,243,205, 55, 94,237,219,183,175, - 97,179,217, 28,253,175,210,211,211,145,152,152,136,155, 55,111,222, 18, 69,113, 83, 5,179,245,250,144, 33, 67,182, 44, 91,182, - 44,252,213, 87, 95, 77,252,229,151, 95, 54, 1,200, 45,101, 59,205,179,207, 62,219,123,217,178,101,225, 35, 71,142,188, 13, 96, - 28,155,225,157,193,184, 15,131,229, 84, 89, 28, 0,208,146, 16,210,135,231,249,137, 5, 5, 5, 95, 81, 74, 55,222, 71, 69,181, -144, 16,178,237,234,213,171, 47, 3,104,242,213, 87, 95,189, 3, 32, 1,133, 33,244,174,165,245, 87,112,161,103, 3,240, 65,104, -104,232,111,211,167, 79,127, 32,207, 34,188,118,237,154, 9,192,235, 33, 33, 33,191,124,242,203,218,247, 41,165,141,120, 42,250, -217, 8,151,205,113,220, 73,155,205, 54, 51, 49, 49,113,111, 69, 52,215, 20,166,179,107,139, 42, 30, 61, 39,141, 28,242,185, 85, -162,140, 40, 48, 88,101,106,185, 96,146,218,140,183, 56,125,246,123, 71,110, 21, 60, 18, 23, 86,163,209,104,125,230,153,103,190, -231, 56, 78, 4, 0,155,205, 38, 24,141,198,225,168,192,200,211,210, 52,251,246,237,251, 35,207,243,214,162,200, 16,103, 52, 26, - 95,186, 31,205, 7, 69, 70, 70, 70, 1,128, 49,229,109, 19, 27, 27,187,226,207, 63,255, 28,210,165, 75, 23,219, 31,127,252,145, -246,244,211, 79, 11, 39, 78,156,160,132,144, 82,239,226,110,222,188,105, 68, 25, 79, 36,176,211,160, 65,131,240, 31,126,248,225, -196,203, 47,191,236, 57,127,254,124,223, 99,199,142,217,150, 46, 93,154, 87, 80, 80, 48,155, 85, 79,143, 22, 18,137, 4, 42,149, - 10, 38,147, 9,233,233,233,112,213,167,156, 82,122,141, 16,242,244,196,137, 19, 99, 39, 78,156,248,116, 88, 88, 88,157, 42, 85, -170, 84,225, 56,142, 75, 73, 73, 73, 79, 72, 72,184,105, 54,155,119, 1,248, 3,128,180,106,213,170, 39, 1,172, 40, 75,239,252, -249,243, 31,135,132,132,252,181,126,253,250,167,229,114,121,109,153, 76,230,107,181, 90,185,130,130,130, 44,179,217,124,193,104, - 52,254,158,156,156,124,168,130,117,231,101, 66, 72, 7, 65, 16,254, 88,186,116,105,116, 74, 74, 74,196,222,189,123,123,149,220, -174,113,227,198,203,150, 45, 91, 22, 62,122,244,232,107,171, 86,173,170, 80, 31, 44, 6,131, 25, 44,247, 78,198,141, 0, 54, 62, -136, 63,166,148,222, 2,240,126,209,242, 64, 72, 74, 74, 58, 3, 96,200,131,220, 65,201,201,201, 7, 1,116, 3, 10,103,115, 78, - 40,188,104,222, 23, 71,110,231,255, 14,167,199,171, 60, 34,119,231, 70, 66,200,196,162, 81, 77, 0, 48,241,228,201,147,243, 75, - 68,164, 78, 59,175,119, 21,105, 42, 77,243,212,169, 83, 37, 53,207, 86, 68,243,223, 36, 59, 59,251,141,101,203,150, 29,123,253, -245,215,229, 3, 6, 12,192,197,139, 23,241,221,119,223, 25,179,179,179, 87,221,171,230,169, 83,167,110, 53,104,208,160,209,146, - 37, 75,222, 94,188,120,113, 31, 66, 8,123, 22,225, 35,130,193, 96,184, 62,104,208, 32,112, 28, 71, 40,165,212,106,181, 58, 6, - 61, 20,205,103,118,221,141,243,202, 10,224,175,162,197, 21, 95,184, 81, 31, 29, 6,112,248, 1,159,251,183, 9, 33, 79,223,188, -121,115,214,229,203,151,183,150,182,205,185,115,231, 54,116,237,218, 85,117,248,240,225,119, 43, 58,138,144,193, 96, 6,139,225, -146,155, 15,192, 92, 61,202, 20,245,127,250,193,110,142, 42,186,254, 97,105,254, 91,156, 63,127, 62, 27,128,227,145, 33, 81, 81, - 81,232,217,179,231,125,235, 22,153,169,177, 96, 51,183, 63, 82,108,218,180,233,169, 39, 37,175,148,210,219,229,221,156,154, 76, -166, 77, 0, 54,177, 82,193, 96, 48,131,197,184,247,138,214,120, 63,235, 31,150, 38,131,193, 96, 48, 24,143, 50, 4, 64,231, 50, - 46,122,110,143, 14, 32,164,226, 15,218,116,165,207, 52,153, 38,211,100,154, 76,147,105, 50,205,199, 79,211,149,246, 99, 51, 58, -145, 82,250,143, 45, 0, 58, 51, 77,166,201, 52,153, 38,211,100,154, 76,147,105, 62,105, 11,123,160, 44,131,193, 96, 48, 24, 12, -198, 3,134,245,193, 98,252,231,120,238,185,231,248,138,108, 31,239,237,205,229, 38, 86,153,173, 81,201,123,233, 12,198,217, 87, -255,120,247,155,199, 97, 63, 4, 7, 7,215,242,244,244, 28, 6,160,142, 78,167, 11, 80,169, 84,105, 0,206,231,229,229,173, 72, - 73, 73,185,196, 74, 10,131,193, 96, 60,226, 6, 75, 38,147,197, 80, 74, 71, 16, 66,130, 8, 33,119, 40,165, 63,152, 76,166,115, - 79,218,206,146,201,100, 49,132,144, 17,148,210, 32, 74,233, 29, 66,200,191,188, 31, 8, 89,251, 92, 97, 20,178,255, 26,136, 0, -165,172, 72,151, 98,174,146,170, 44, 30,222,167,233,139,147, 71,116, 64,163, 1, 95, 77, 66, 5, 38,177,125, 20, 33,132,240, 81, - 81, 81,175,135,135,135, 15, 92,180,104,145, 52, 42, 42, 10, 10,133, 2,122,189, 62,248,250,245,235,193,163, 71,143,110, 87,181, -106,213,213, 55,110,220,248,174,104,142, 56, 6,131,193, 96, 60, 42, 6, 43,162,114,229, 1, 28, 79,230,153, 45, 54, 31,111,111, -111,238,219,111,191,229,122,245,234,133,223, 55,111,198,216,177, 99,199,133,134,134,136, 82, 65,200,166,162,117,220,205,132,228, - 95,221,249,179,103,159,125, 54,213, 98,177,148, 57,171, 53,207,243,105, 27, 54,108, 8,188,223, 76,133, 54, 30,144,106, 49,155, -203,252, 31, 65,144,164, 37,159, 92,227,214,255, 84,174, 28, 50,128, 39,220, 60,139, 77,244,241,241,241,225,190,249,230, 27,174, - 87,175, 94,216,188,121, 51,198,140, 25, 51, 46, 44, 52, 84,148, 74,248,108,209, 70,199,221, 76, 72,248,245,225, 29, 58, 66,214, -174, 5,135,254,133,159,214,174, 5,215,191, 63,121,162, 77, 86, 70, 70, 6, 1, 0,127,127,127, 90,204, 92,245,110,250,226,123, -175,118,194,204,197,187,160, 55,154, 86,254,215,243, 25, 21, 21,245,250,115,207, 61, 55,240,227,143, 63,150,114, 92, 97, 43,191, - 86,171,133, 94,175, 71,104,104, 40,246,236,217, 35,125,255,253,247, 7,110,216,176, 1, 0,230,177,106,142,193, 96, 48, 30, 33, -131, 69, 56,204, 95,181,232, 11,159,204,172,108,252,178, 97, 27,162,163,163,113,254,252,121,212,138,142, 70,108,179, 6, 92,215, - 86,245, 57,129,144, 74, 31,124,179,124, 62, 0,183,140,133,197, 98, 9, 88,191,126, 61, 8, 33,176,217,108,176,217,108,246, 9, -251, 80, 80, 80,128,113,227,198, 5, 60,136, 76, 89,204,230,128,235,127,175,131,132, 39,176,218, 40, 44, 54, 10,179, 85,132,217, - 74,145,167,179,162,227,211, 67,220,254, 31, 14,220,252, 31,191,249,210, 39, 59, 39, 7,235,255,220,233,216, 15,209,209,209,232, -216,186, 25,247,220,211,237, 56,181, 66, 94,233,149,201,159,184,189, 31, 30, 4,107,159,251,191,185,114,254,174,255, 26, 60, 81, - 17,139,139, 23, 47,242, 70,163,113,144,167,167,103, 11,137, 68, 18,168,242, 14, 22,115,164, 85, 51,181, 36,232,134, 89, 43,107, - 59,162,111,181,238,239,190,220, 30, 51, 23,239,194,143,155,254, 94,230, 21,154, 48,245,191,156,223,224,224,224, 90,225,225,225, -197,204,149,253,161,230,121,121,121,200,207,207, 7,199,113,152, 52,105,146,116,239,222,189, 3,131,131,131,119,178,230, 66, 6, -131,193,120,132, 12,150,201, 98,243, 9,242,243,198,143, 63,252,136, 73,239,204, 64,173, 90,181, 64, 41, 5, 33, 4,239, 76,157, -142,175, 63,154,130,129, 79,181,131,197, 42,250,148,165, 81,218, 80, 75, 66, 8,226,227,227, 97, 48, 24,160,215,235, 29, 75, 76, - 76,140, 91, 9,118,119,248,166,132, 39,248,227, 68,126,161,177,178,136, 48, 91, 69, 88,172, 34, 58,196,120, 84, 72,211, 98, 19, -125,188, 60,212, 88,188,112, 62, 38,125,244, 69,177,253, 48,249,221,247,241,221,103, 31, 96,252,168, 23, 96,178,216,124,238, 37, -157, 21,129,105, 22,231,208,161, 67,193, 42,149,234,171, 33, 67,134,132,140, 27, 55, 78, 70, 5,181,176,237,232, 45,175, 47,127, -216, 21, 98, 48,153,249,167,219, 84,197, 75,125,155, 96,230,146,191,138,204,213,237, 87, 35,115,114,196,255,114,222, 61, 61, 61, -135, 45, 90,180,232, 46,115,149,154,154,202, 21, 20, 20,192,108, 54,139, 69,207, 75,196,148, 41, 83, 36,239,191,255,254, 48, 66, -200, 71, 69, 58, 70, 86,150,152, 38,211,100,154,143,170,230, 19, 99,176, 0,192,108,212, 35,166,138, 47, 22,206,254, 24, 34,229, - 64, 65, 65, 69, 10, 74,109,136,244, 87,195,168,211, 86,248, 15, 69, 81,132,197, 98,129,217,108,198,162, 69,139, 80, 80, 80, 0, - 81, 20, 81,187,118,109, 0, 64,227,198,141,157,155,184,110,199,197,197,133,187,210, 12,168,215,247, 22, 40,170, 56,127,247,225, - 23,223,227,208,201,235, 16, 69, 64,174, 84,161,255,176,145,176,218, 40, 76,150,138, 63,159,212,168,215, 33, 68, 35,193,156, 89, - 83, 65, 4, 9,120, 66, 64, 8, 1, 71, 68,212, 10,245,134,201,160,123,232, 7,174,255, 26,136,107,215, 22, 31, 5, 90,216, 15, -235,201,137, 92,169, 84,170,175, 86,172, 88, 17,222,180,105, 83, 14, 0,142, 93,201,150,127,249,195,174,144,239,167, 61, 67, 26, -213, 10, 66,102,174, 30, 51,151,238,197,238, 19,201, 91, 75,154,171,255, 48,117,162,162,162,138,153,171, 47,191,252,210,127,254, -252,249,161, 0,208,175, 95,191,164, 78,157, 58,101, 92,190,124, 25,193,193,193, 36, 35, 35,227,105, 0,111, 20,221,220, 76,164, -148,206,103,213, 30,131,193, 96,252,203, 6,203,100,212, 35,204, 91,134, 32,141, 0,139,197,138,243,150, 16,228,235, 12, 48,155, - 45,184,109, 54,227,198,169, 59,104,221,186, 53,158,121,230, 25,155,217,108,134, 84, 42,205, 93,191,126,189,175, 43,131,101, 54, -155, 97, 54,155,161,213,106,177,114,229, 74, 8,130,224,120,112,170,243, 19,235, 91,181,106, 85,197, 61, 43,141, 42,215,142,253, - 6, 15, 5, 15,171, 72, 97,181, 82, 88, 69,192,106,163,208,155, 41,158, 25,241, 30,108, 54, 10,155, 72, 97,178,186,238,162, 84, -204,176,249, 54, 69,239, 41,191, 0,208, 56,214,123,202, 41, 38,181,230, 33,147, 73, 32,147, 9, 48,232,244,255,194,161,163,180, -127,127, 34, 62,169,157,220,141, 70,227,224, 33, 67,134,132,216,205, 21, 0,100,231, 25, 5,131,201,204, 55,170, 21,132, 46, 3, - 39, 96,199,234, 47,241,231,193, 43,240,209, 8,251,194, 30, 15,115, 5,157, 78, 23,160, 80, 40,160,213,106, 29,145,171,249,243, -231,135,154, 76, 38, 14, 0, 4, 65, 18,150, 46,134, 42,108, 34,224,229,153,130,236,236, 92, 63, 74, 41, 41, 50, 88, 95, 16, 66, -126, 96, 51,231, 51, 24, 12,198,191,108,176,204,122, 61, 44, 22, 43,172, 86, 27, 44, 86, 27,114, 11,244,248,236,179,207, 32,151, -203, 65, 8,129, 40,138, 40,122, 0, 42,103,177, 88,240,244,211, 79,251,184,250, 67,231,126, 87,148, 82,240, 60,143,230,205,155, -223,181,221,145, 35, 71, 42,148, 17, 15, 5,143,200,206,239,220,245,253,209,223, 62, 6,165,128, 77, 44, 50, 88,102, 55,174,179, - 46, 12, 91,131,182,253, 97, 50,153, 11, 35,122,148,222, 83, 36,239,129,153,172, 39,172,207,149, 29,153, 76,214,121,220,184,113, - 50,231,239,124, 60,229, 86,133, 76,106, 59,113, 49,133,236, 88,253, 37,119,252, 66,178, 40,147, 8, 84, 77,239, 68, 61, 46,249, - 86,169, 84,105, 58,157, 46, 88,175,215, 35, 47, 47, 15,121,121,121,197, 79,104,137,132,188, 58,106,140,191, 68, 42,131,197,108, -194,159, 43,102,178, 90,142,193, 96, 48, 30, 53,131,101, 52,232, 96,177,218, 96,181, 20, 62, 65,222,100, 50, 65,169, 84,162,109, -219,182, 69,151,119,234,120,221,190,125, 59, 76, 38,147,203, 63,180, 90,173,142, 8,150, 40,138,160,148,226,151, 95,126,129, 68, - 34,129, 84, 42,133, 68, 34,129, 68, 34, 1, 33,164, 66, 25,177,218, 40,222,157,252, 54, 36, 2, 7,169,192, 65, 34, 16, 72, 5, - 14, 54, 74, 65, 65, 97,181, 21, 46, 38,171,123,129,140,242, 12, 27, 0, 24, 77, 22,208, 66, 51, 6,157, 78,199, 74,210, 67, 36, - 35, 35,131,232,245,250, 8,111,111,111, 39,171, 73, 81, 73,101, 51, 14,239,213, 32,121,248,135,235, 66, 76, 22, 43,164, 2, 79, - 7,119,141, 78,222,181,126,143, 95,134, 49,135,216, 71, 23,254,199, 57,127,237,218,181,224,202,149, 43, 35, 47, 47, 15, 86,171, - 85,236,215,175, 95,146, 32, 72,194, 4,137,132,244, 28, 52, 70,188,115, 39,217,194,113, 60, 40,181,225,169,231, 70, 19,185, 66, - 41, 53,155, 76, 86, 0, 19, 89,244,138,193, 96, 48, 30, 5,131,165,215,195,106,177, 58, 76,150,217,108, 6, 0,204,158, 61,251, - 46, 67, 68, 41,117,172, 47, 87,211,104, 68, 84, 84, 20, 76, 38, 19,162,163,163, 65, 41,197,160, 65,131,238,218,238,216,177, 99, - 21,202,136,197, 70, 49,235,179,217,119,125,127, 96,205,199,168, 31, 29,137,230,213, 85, 48, 88, 68,228,106,173,247,109,216, 0, -192,100, 50, 3, 69,211,225,235,181, 90, 86,146,254, 69, 44, 22, 11,178,179,179, 97, 44,200,182,214, 12,162,185, 47,247,172,106, - 76,207,210, 9, 28, 53, 88,195, 60,116,198,130,172, 36, 94,165, 82, 61, 22,121,205,203,203, 91, 49,122,244,232,118,251,246,237, -147,114, 28,135,188,188, 60,116,232,208, 33, 35, 93, 12, 85,188, 58,106,140,127,114,114,146,213, 83, 41, 24,165, 82, 9,210,210, -210,196,118, 61,134,232, 7,141,120, 51,228,205,247, 62, 89,148,124,112, 62,235,127,197, 96, 48, 24,143,132,193,210,105, 97,177, -216,138,154, 8,173,142,168,211,216,177, 99,239,218,118,215,174, 93, 46, 13,150, 32, 8,105, 47,191,252,114,177, 41, 18, 40,165, - 88,183,110, 29,100, 50, 89, 49,211,118, 47, 17,172,105,239, 79,128, 76,194, 23, 25,162, 66, 99, 36, 82,138, 77,127,108,199,166, - 63,182, 59,182,229,121, 73,218,253, 24,182, 66,163,104, 1,165, 0, 5,160, 47, 96, 6,235, 97,226,239,239, 79,211,211,211,111, -230,228,228,212, 84,171,213,200,204,204, 68, 86, 86, 22,114,114,114,160,207,203,182,170,173, 57, 90,147, 53, 11,130, 32,224, 78, - 66, 42,108, 54,219,157,199, 36,122,133,148,148,148, 75, 85,171, 86, 93,253,238,187,239, 14,154, 50,101,138, 68, 20, 69, 92,190, -124, 25, 32,132, 74,164, 50,112, 28, 7,137, 68, 64,110,110,158,168,210,120,167,152, 41,175,146, 72,101,224,120, 41,155,112,148, -193, 96, 48, 30, 41,131,101,181,194,106, 41,236,131,101, 54,155, 97,181, 90,177,120,241,226, 98,102, 72, 42,149,130,227, 56,151, - 6,107,253,250,245,197, 38,247,108,220,184, 49,165,148,162, 95,191,126,142,230,198,225,195,135, 99,228,200,145,176, 15, 67,119, - 59,138, 97, 3,166,207,156,237,208,233,209, 37, 22,125,158,106, 7, 42, 22, 26,181,180,179, 27, 42,228,216,202, 51,108, 64, 81, - 4, 11, 20,160, 20, 5,249,249,172, 36, 61,100, 76, 38,211,206,121,243,230, 69,188,255,254,251,178,172,172, 44,100,100,100, 32, - 59, 59,219,177, 20, 20, 20, 32, 40, 40, 8, 91,183,110, 53,231,229,229, 29,121,156,242,126,227,198,141,239, 54,109,218,132,189, -123,247, 14,156, 50,101,138, 36, 40, 40,136,120,121,165, 18,139,217, 4,128,210,244,244,116, 81,165,241, 78,241, 15, 12,187,157, -124, 39, 45,218, 98, 54, 65,180,153,121, 86,106, 24, 12, 6,227, 17, 48, 88, 18,129,203,189,114, 43,197,171,146, 90, 9,171,104, -132,205, 84, 56,181,130,205,102,195,171,175,190,234,216,110,240,224,193,120,225,133, 23,192,113,220, 93,125,176, 8, 33,157, 93, -205,149, 33,138, 34, 14, 28, 56, 80, 56,237, 1,199, 57,150,178, 40, 75, 83,107,180,225,224,175, 31, 65,164,128, 88,232,123, 64, - 65,220, 26, 53, 88,154,166, 43,195,166,240,240, 1, 7, 10,240,192,245,164, 52, 8, 60,151, 91,209,188, 87, 20,166,249,127, 77, -185, 92,190,234,151, 95,126,233, 17, 27, 27, 27, 94,191,126,125, 46, 43, 43, 11, 5, 5, 5, 40, 40, 40, 0, 0,248,251,251,227, -194,133, 11,226,173, 91,183,146,228,114,249, 47,143, 83,222,139, 30,127, 51, 47, 56, 56,120,231,212,169, 83,135,101,100,100, 60, -157,157,157,227,247,251,143, 51,208,253,185,209,164, 93,143,193, 90, 19, 21, 20,137, 41,169,181,246,108,249,217,247,207,213,223, -193,108, 50,141, 36,100,193, 69,251, 52, 13,172, 44, 49, 77,166,201, 52, 31, 53,205, 39,198, 96, 81, 27, 29,183,240,247, 35,243, - 44, 54,209,203,254, 93,157, 58,117, 96, 54,155,177,117,235, 86,135,241, 16, 4, 1,130, 32,184, 21,193, 42,133,219,109,219,182, - 45,111, 42,134,219,238, 29,105,220,110,210, 97, 64,149,242,214, 87, 52, 97,174, 12,219,146, 61,103,255,191, 19, 57, 46, 23,148, -142, 99,197,233,225, 17, 29, 29,109, 59,116,232,208, 91,163, 71,143,254,170, 83,167, 78,161,125,250,244,145, 86,174, 92, 25,114, -185, 28,215,175, 95,199,254,253,251,205, 55,110,220, 72,210,233,116,111,213,175, 95,255,177,108, 30, 75, 73, 73,185, 84, 52,137, -232, 27,246,169, 24,228, 10,165,116,240,136, 55,195, 28,163, 8, 87,127, 7,163, 65, 15, 0, 2,155,166,129,193, 96, 48, 30, 1, -131,117, 59, 41,105, 5,128, 21,206,223, 61,253,244,211, 5,189,123,247, 86,218, 71, 20,218, 71, 3,154, 76, 38,152, 76, 38, 40, - 20,138, 10, 77, 8,229,206, 36,162,238,144,118,102, 67,248, 3,221, 43,110, 24,182,228,228,228,112, 86,124,254, 93, 90,181,106, -149,114,241,226,197, 33, 59,118,236, 24,188,111,223,190,206, 58,157, 46,130, 16, 2,165, 82,121,211,100, 50,237,148,203,229,171, - 30, 87,115, 85, 22,102,179,217, 58,101,250,151, 63,241,130,212, 42,138,102, 98, 54,155, 71,192,205,135,186, 51, 24, 12, 6,227, - 33, 24,172,210,208,233,116,222,132, 16, 33, 57, 57,249,174,117, 82,169, 20,183,110,221,178, 62, 14, 59,229,129, 27, 54,198, 63, - 70,116,116,180,173,232, 70, 96, 69,201,135, 61, 63, 9, 80, 74,141,132,144,137,132,144, 47,138,190,154,120,227,175,185,142,209, -130,132,204, 59,227,188,142, 69,175, 24, 12, 6,227, 17, 52, 88,123,246,236,177, 2,168,136,137, 74,251, 7,210,156,198, 14,219, -147,205,154, 53,107,216,136,184,226, 38,107, 62, 33,228, 7,187,225,114,119, 29,131,193, 96, 48, 30, 17,131,197, 96, 48, 30, 89, -147,101,188,151,117, 12, 6,131,193,248,103, 32, 0,234,150, 81, 41,159,117, 91,132,144,186,247,112, 65, 56,251, 8,105, 6,148, -163,185,211,133,102,231,123, 72, 39,211,100,154, 76,147,105, 50, 77,166,249, 68,106,186,210,126,108, 70, 39,210,162,217,200,255, -137, 5, 64,221,255,136,102,103,166,201, 52,153, 38,211,100,154, 76,147,105,254,123,154,143,219,194,129,193, 96, 48, 24, 12, 6, -131,241, 64, 41,181, 15, 86,165,152,190,224, 74,204,123, 46, 82, 32,253,220,134,123,218, 14, 0,166, 79,159,126, 95,102,238,195, - 15, 63,116,235, 41,205,149,234,246, 5,231,198, 24, 50,145, 0,233,103, 55,184,253,255, 36,188,239,251, 16,241,110,225, 7,124, - 78,111,111,152,198,138,207,189,209, 80, 67,252, 45, 68,210,211, 67, 33,233, 29,225, 33,105,121, 61,199,120, 72,103, 22, 55, 83, - 98,217,120, 62,143,102,179, 61,196, 96,252,243,248, 68,181, 30,226,231, 31, 52, 82,164, 84, 9, 0, 38,147,193,146,148,112,123, - 46,205, 62,191,186, 88,221,231, 91,187,127, 80, 72,216, 88,165, 66,173, 44,172,254,136, 41, 43,243,206,252,236, 27, 7,127,126, - 88,105, 37, 69,207, 78, 11, 13, 13,245, 62,120,240, 96,120,235,214,173,111, 37, 37, 37,229, 56,111, 83,218, 58,106,159,176,177, - 12,205,192,168, 70,207,123,104,212,175, 25,140,198, 72, 47, 79,207,180,172,204,204,133, 41, 55, 78,126,103,223, 38, 60, 60,220, -115,245,234,213,193,131, 7, 15, 78,142,143,143,207,119,165,201, 96,184, 52, 88, 28, 1,214,172, 89, 13, 74,105,209, 36,155, 20, -131, 7, 13, 46,117,187,202,242,228, 72, 81, 20, 95, 0, 48,148, 82,122, 42,217, 82,185,223,189, 36,100,215,174, 93,161, 22,139, -165,169,213,106,109, 4,160,145, 82,165,105, 96, 52, 26,210, 8,232,139, 79, 61,245,212, 73,119,117, 56, 10, 44,249,113, 57,166, -143,106,255, 7,128, 30,101,156, 88,211, 19,141,161, 21, 51, 72, 34,125,239,239,125,235,228,222, 42,130,106,141,159,157, 4,224, -145, 52, 88, 33, 33, 33, 74, 0, 47,114, 28,215, 73, 46,151,215, 48, 24, 12, 55, 1,156, 33,132,204, 79, 76, 76, 76,190,199,202, -141,139,209, 72, 94, 82, 41, 85,221,131,213,178, 70, 41, 57,121, 73, 58,139,184, 95, 36,230, 47, 42,106,136,170, 17, 34,171, 90, -217,123,239,219,125, 98,163,235, 71, 87,133,237,220, 62,152,204,230,222,199, 83,116,189, 23,157, 76,125,171, 26, 33,141,174, 81, -106,114, 51, 93,193, 0, 4, 74,105, 2, 0,132,133,133,249,136,162, 24, 11,160, 1,128, 83, 28,199,237, 79, 76, 76,188, 47,195, -246, 31,210, 12, 17, 69,241,229,192,192,192,167, 83, 83, 83,255,224, 56,110,233,189, 30,111,198,147,129,175, 95,208,107,223,254, -176, 86,102,255, 76, 69, 81, 50,168, 79,251, 97, 0,138, 25, 44,111,111,191, 23,127, 92,245,167,146,252,255, 9, 27,178, 49, 35, -250,143, 4,240, 80, 12, 22, 33,132, 80, 74, 49,125,250,116,178,100,201,146,225, 85,170, 84,169, 78, 41,189, 60,109,218,180,185, -206,219,149, 92,247,225,135, 31,210,162,223,210,210, 52,163, 98,218,108,124,233,133,129,237,199,141,126, 81,163, 82, 42,161,215, - 27,252, 22, 44, 89,254,229,119, 75, 87,244,124,161, 95,231,238, 0,176,120,241,226,190,149, 43, 87,142, 48,153, 76,241,211,166, - 77, 91, 94,158, 38,131,225,150,193, 42,114,233,184,122,241, 20,254,248,125, 11,142,157,186, 0,209,169, 56,213,169, 83, 71, 45, -147,201,250,135,201,184, 23,235, 53,106,217,166,247,115, 47, 18, 11, 81, 97,230,132,193, 21,158, 7,235,196,137, 19,242,148,148, -148, 25,145,181, 26,191,217,190,107, 31,174,118,116, 45,248,251,249, 64,228,100, 88,182,245,138,223,158, 69,195,191, 5,208,210, -109, 31, 68,128, 87,134, 63,143, 80, 25,122,252,186,229, 40, 82,114,108, 32, 4, 32,164,208, 16, 22, 24, 68,188, 59,162,205,135, - 21, 55, 72,132,243, 86, 17,140, 95,101, 0,128, 71,242,185,110,193,193,193,141,252,252,252,190, 27, 62,124,184, 79,141, 26, 53, -130,101, 50,153,202, 96, 48, 84,191,125,251,118,228, 87, 95,125,213, 37, 56, 56,248,211,148,148,148,117, 21,209,140,246, 86, 84, -121,170, 86,248,175,147, 71,189,216,172,102, 68,101, 8,198, 2,136, 70,109,229, 91, 55,174,181,156,245,227,186, 87, 98,188, 36, -131,206,229, 90,220,238,144,168,240,144,190,247,238, 75,131,163,171,169, 41, 76,103, 15, 66,194,243, 80,120,250,160, 57,207,131, - 35,180,246,135,251,147,222, 5,240,161, 27,149,238, 71, 0,222, 5, 64,164, 82,233,186,192,192,192,203,173, 90,181,170, 63,112, -224, 64, 82,183,110, 93,156, 58,117,170,225,239,191,255, 62,162,114,229,202,167, 45, 22,203, 95,106,181,250,200,181,107,215,220, - 50,110,213,170, 85,147,105,181,218, 22, 18,137,164,195,163,172, 25, 18, 18,162, 52,153, 76, 47,132,133,133,189,218,187,119,239, -122,189,122,245, 34, 53,107,214,196,165, 75,151, 26,255,249,231,159, 31, 54,104,208,224, 76, 98, 98,226, 98,153, 76,246, 83,114, -114,178, 91,147, 0, 15,172, 75, 46,173, 62, 75,107,221,235,250, 18,199,200, 27,128,146, 82,154,236,198,182,129, 0,212,148,210, -235, 15, 91,243, 31,186,209,185, 0,192,215,254,208,122,142,227, 28, 15,176,119,126,181,191,183,217,108,218,219,183,111, 87,117, -161, 89, 83, 20, 69,183, 91, 2, 8, 33, 52, 37, 37,229, 82,153,117, 60,168, 12, 0,102,125, 56, 1, 73, 9,183,160, 55,104,245, - 57, 57,153,203, 74,110,151,147,157,181,226,229,161, 61,223,144,201, 20,146,208,202,225,120,119,250,151,176, 71,189, 30, 22,211, -167, 79, 39, 31,126,248, 33, 22, 47, 94,220, 11, 64, 44,165,116,127,116,116,244,188, 18,215, 44,199,186, 15, 63,252,112,238,244, -233,211, 9,128, 82,141, 80,165,168, 6,195,134, 13,234,219,254,157,183, 95,211,216,191, 83, 42, 21,120,251,141,145, 50,189,209, -212,114,193,247,203, 95,157, 59,115,242, 18, 0, 29, 1, 52,161,148, 30, 7,176,188, 60, 77, 6,195,109,131, 37, 82,224,143,223, -183,224,237, 41, 31,224,135,101, 63,225,167,207, 70,146, 38, 77,154,180,165,148,190, 24, 17, 85,173,255,179, 67, 70, 42, 35,170, -215, 69,129,232,137,248, 12, 17, 39,254, 90,133,146,119, 62,174,216,182,109, 91, 19, 74,241,227,232, 41, 95,213,170,223,176, 41, -206, 38, 89,113, 48,193, 6,237, 53, 27, 4, 94, 15, 81,172,248, 16,115,123,179, 95,227,198,141,145,152,109,197,254, 75, 38,240, - 28,192,113, 0,207, 17,240,228, 30,247,148,104,186, 50,227,199, 19, 49, 25,169, 34, 32,154,174, 60,106, 7, 50, 52, 52,180, 99, - 84, 84,212,156, 55,222,120, 35, 40, 37, 37,197,247,216,177, 99,144,203,229,240,241,241, 17,252,252,252,106, 77,153, 50, 37,119, -214,172, 89, 19, 3, 3, 3, 79,166,166,166,222,116, 71,179,142, 70, 22,221,174, 81,204,161,169,211, 62,244, 50, 29,253, 19,217, -171,214,128,231, 40,164,106, 13, 66,148, 74,204,235, 26,225, 59,121,119,194,186,122, 74,101,244, 25,189, 62,201, 29,205,202, 1, -190, 93,171,215,172,133,236,245,223,226,106,158, 17,135,211,141,232,211,174, 25,170,249, 42,209,192,106,131,159, 66,232,232,202, - 96, 17, 66,124, 0, 76, 54,153, 76,156, 84, 42, 37, 10,133,162,255,178,101,203,118,215,172, 89,211, 96,223,166, 69,139, 22,104, -209,162, 5,209,106,181, 13, 14, 30, 60,216, 96,253,250,245,230,224,224,224, 3, 41, 41, 41,115,202,210, 85, 42, 85,183, 13, 6, -125,101,149, 90,109, 90,186,100,201,174, 22, 45, 90, 80,137, 68,130,251,209, 4,128,160,160,160,117, 17, 17, 17,254, 51,103,206, -204,111,214,172,217, 3,209,140,140,140,220, 30, 27, 27,219,161,107,215,174, 66,235,214,173, 17, 18, 18,226, 88,231,239,239,143, -216,216, 88,146,144,144, 80,127,255,254,253,243,183,111,223, 62, 47, 50, 50,242,175,248,248,248,174,174,142, 15, 5,106,222,207, -250, 18,240, 0,102, 17, 66,150, 80, 74, 15,150,115, 60, 27, 1, 24, 2,224,179,127, 73,179, 92,148, 74,101,170,193, 96, 8, 0, - 0,133, 66,145,166,215,235, 3,221, 48, 55,154,207, 63,255, 60, 64, 42,149,130,231,121,216,108, 54,199, 66, 41,133, 40,138,197, - 58,195,126,246,217,103,110,205,237,118,231,206, 29, 45, 10, 71,127, 83,167, 69, 44,237, 53, 34, 34,194,223, 29,205,164,132, 91, -240,176,196,103, 6,122, 40,195, 35, 61,188,103,180,110,221,122,134,243,250, 86,209, 94, 0,242,160,215,223,185,149,148, 0,191, -127,161,110,243, 94,178,100,201, 11,139, 23, 47,238, 67, 8,209, 22,237,223,122,111,190,249,230, 95, 37,246,121,189,162, 87,109, - 72, 72,200, 30, 66,200,230,208,208,208, 31, 1,220, 21, 29,246,210,120,140,124,107,204, 43, 26, 0,152,190, 54, 3,211,214,166, -227,131,103,124, 49,233,105, 53,134, 15,237,167,254, 97,249,175, 35, 1, 44,113,210,190, 20, 29, 29, 77, 46, 94,188,200,204, 21, -227,193, 68,176,142,157,186,128, 31,150,253,132,161, 67,135,225,220,206, 69, 91,158,122,230,249,238, 45,218,118,133, 85, 26,128, - 75,105, 4, 9,241, 20, 2,111, 5, 7, 17, 55,254,222, 72, 57,142,251,169,132, 70,153,211, 38,108,217,178,229,173, 42,213, 26, -124,250,238,180, 79,248,179,169, 50,252,184, 95, 15,155, 49, 23,250,140,107,208,166, 93, 65,254,157, 11,200, 73, 58,123,134,227, -184,105,238,106,222,157, 7, 64,164, 20,132,146,194, 42, 7, 20,119,117, 26,131,155, 67, 66,205,218,139, 81, 53, 99, 98,178,101, - 54,192,172,189,232,250,191, 31,252, 48,211,178, 52, 67, 66, 66,186, 68, 68, 68,124, 49,114,228,200,176, 51,103,206,120,234,116, - 58,237,209,163, 71,247,166,164,164, 4,250,251,251, 39, 12, 28, 56,176, 85, 96, 96, 96, 64,219,182,109, 85,219,182,109,123, 15, -192,203,174, 52,235,170,101, 49,177, 77,235, 30,254,248,243,217,234,140, 53,223,192,116,237, 52, 14,103,232,113, 38, 83, 79, 67, - 61,114,200,128,104, 95,168,100, 2, 70, 54, 14,212,188,177, 45,254,179,162,139,153,203,188, 71, 6, 7, 86,181,232,117, 48,232, - 45,216,114, 61, 87,127, 56, 47, 55,128, 59,125, 59,125, 82,175,166, 10, 62, 61, 25, 65, 26, 73,245,138,238, 79, 66, 8, 20, 10, - 69,169,235,188,189,189,209,178,101, 75, 68, 69, 69, 73, 7, 15, 30,220, 17,192,156,178, 52,205,102, 83,176, 40, 82,120,122,122, - 74, 59,117,234, 68, 8, 33,180,228, 3,204, 43,170, 9, 0,106,181,186, 91,131, 6, 13,248, 85,171, 86, 21,220,185,115,231,230, -211, 79, 63,157,161, 80, 40,196, 18,219, 32, 60, 60, 28,175,191,254,186,244,229,151, 95,118,169, 25, 24, 24,216,101,197,138, 21, - 32,132, 56, 46,220, 37, 9, 15, 15, 71, 80, 80, 16,122,244,232, 33,244,235,215,175, 75,121,251,115, 96, 93,114,201,110,158, 6, -212, 37,229, 94, 68, 6,212, 37,148, 0,151, 75, 70,178, 74,106, 82, 74, 51, 9, 33, 11, 1,172, 39,132,244, 47,205, 16, 17, 66, - 90, 3, 88, 11,224, 41, 74,105,154,171,227,238,172, 41,147,201,164,102,179,217,167,164,241,169,168,166,115,196, 39, 46, 46, 14, -141, 27, 55,134,243,171,193, 96,112, 60,123,149, 16, 18,224,110,249,228,121, 30, 95,125,245, 21,120,158,135, 84, 42,133, 76, 38, - 43,245,181,105,211,166, 21,173, 67, 18, 8, 33, 92,149, 42, 85, 38,243, 60,255,178,201,100, 10,147,203,229,201, 54,155,109,153, -175,175,239,204,184,184, 56, 11, 0,239,210,158, 13,235,172,169, 55,104,245, 84, 20,149, 38,147,193,162, 84, 43,195, 15, 30, 60, - 88,163,172, 99,110, 52, 26,209,169, 83, 39,164,230,107,211,237,191,121, 88,117,221,193,131, 7,195,171, 84,169, 82, 19, 64,108, -209, 87,251,146,146,146,218, 58,125,118,102, 95, 82, 82,210, 83, 69,239, 47,223,190,125, 59,220,110,176,156, 53, 77, 38,115,164, - 70,163, 6, 0, 76, 91,155, 14,227,138,170,144, 15,187,142, 17,205,141,240,240,240,128,205,102,173,249,230,155,111,254,132,194, -115,226,111, 74,105,223, 55,223,124,179, 22,128,221,225,225,225, 27, 0,228, 62,236,122,254, 73,208,124, 44, 13, 86, 81,147,178, -189,105,153,136, 20, 24, 60,104, 48, 68, 10,108,221,186, 21, 98, 97,221,237,153,168,247, 70, 65,188, 63, 4, 78,132,192, 19, 8, - 60, 0, 16,100, 38, 94,128, 73,155,121, 32,209, 20, 26, 47,186,225,239,183,110,221,218, 50,162,118,179,207,166,125,252, 37,247, -195, 62, 61,114,117, 6,100,156,223,132,148, 99,223,167,136, 86,243, 38,142,227,142,115, 28,119,162, 81,253,122,151,130,131,131, -239,121,214,110,145, 2, 54,103, 99, 37, 2,228, 49,139,238,134,133,133, 61, 85,173, 90,181, 79, 70,141, 26, 21, 30, 23, 23,231, -145,159,159,159,190,115,231,206, 75,102,179,249, 36,199,113,115,147,147,147,219,173, 88,177, 66, 53,105,210,164,174, 53,107,214, -172,185,125,251,118,157,203,200,149, 90, 90,255,249, 33, 3, 15,247, 25, 53, 78,113,254,215,239, 32,191, 16,135, 69, 87,178,109, -199,211,245,239, 25, 10,172,115,148, 42,161,117,182,209,186, 99, 66,243, 16, 46, 88, 45, 65,101, 79, 73,123,119,211, 43,147, 41, - 4, 42, 40, 96, 50, 89,161,181,136,166,243,233, 84,251, 86,187,122,102,170,246, 87, 0,128,192,113,130, 27, 39,118, 54, 33,228, - 51,153, 76,246, 62, 33,132,246,233,211,231,102,163, 70,141, 12, 0,160,215,235, 97, 52, 26, 33,145, 72, 96, 48, 24,112,227,198, - 13, 28, 57,114, 4, 62, 62, 62, 21,218,175,217,217,217, 8, 15, 15,135, 70,163,185,111, 77,155,205, 70,190,251,238, 59,217,185, -115,231,100,191,253,246,155,231,132, 9, 19,180,205,155, 55,191,245,244,211, 79,167,121,122,122, 90, 79,157, 58,133,195,135, 15, - 35, 39, 39, 7,205,154, 53,115, 75,211,100, 50, 65, 16, 4,232,245,122,200,229,114, 8,130, 0,171,213, 10, 81, 20, 29,166,171, -160,160, 0, 89, 89, 89,144, 74,165, 40,205, 40, 58, 99, 55, 75, 3,234, 18,250,235,150, 67,105,128, 72, 97,202,183,192,148,107, -129,209,190,100, 91, 6,140,159,221,224,215,179,148, 84,160, 18, 62, 66, 8,233, 15, 96,109, 73,147,229,100,132,250, 83, 74, 79, - 85, 84,211,108, 54, 31,176, 27, 31,133, 66, 17, 64, 72,161, 49,148,203,229, 22,163,209,216,161, 34,154, 0, 16, 23, 23,135, 70, -141, 26,241, 69,154,206,221,108,196,138,158,151,132, 16,240, 60, 15,185, 92, 14,142,227,208,188,121,115,244,235,215, 15,209,209, -209, 72, 72, 72,192,246,237,219,113,241,226, 69, 72,165,210, 98, 77,133,238,208,190,125,123, 62, 50, 50,242, 80,151, 46, 93, 98, -198,142, 29,171, 8, 15, 15,199,165, 75,151,170,204,255, 31,123,231, 29, 22,197,213,182,241,251,204,246,194,210,123, 17, 80, 64, -170,138,128,136, 21, 75,108,177,199, 26,163, 49,177, 39,118, 99, 73,140, 61,154, 24, 99,141, 45,177,247,104, 98,239,189, 87,176, -161,136,162,128,244,222,183,239,206,249,254, 0,124,213, 40, 44,232,251, 38, 95, 50,191,235,154, 11,157,157,185,231,204,204,153, - 51,247, 60,167,173, 90, 53,229,210,165, 75,221, 66, 66, 66, 66,163,162,162,170, 76,115, 70, 90,202,138,126,221, 34, 63, 45,200, -207,219, 90,203,207, 98,150, 70,163,193,195,135, 15, 77,222,231,127, 85,198, 53,109,218, 52,137, 82,250,132, 82,122,145, 16, 82, - 47, 53, 53,181,133,139,139,203, 81, 74,169,252,181,107, 94,154,154,154,218,209,197,197,165,136, 82,122,143, 16, 18, 71, 8, 73, - 74, 73, 73,249,243, 71,146,133,121,118, 73, 73,169,131,153,153, 28,223,116,179,132,248,147,167, 24,221,138, 7,189, 94,143,103, -207, 18,225,233,225, 70,118,110,216, 31, 10,224, 38,128,176,168,168, 40, 0, 8, 5,144,144,156,156,236, 84, 97,176, 56, 56,170, - 29,193,122,189, 23,160,125,189,238,168, 37,226,245,188,127,108,233, 53,111, 29,117,119, 8,252,176, 60, 18, 93, 22,169, 78,186, -115, 12, 44,203,110,202, 52,161, 87,222,213,171, 87, 37, 6, 22, 27, 38,127, 61,135, 89,123, 86,133,204,140, 52,164,157, 95, 8, - 85,214,195,141, 82,169,116, 98,155, 14,157,139,106,114, 34, 47,247,104,116, 17,166, 4, 90,218, 56, 66,163,163,229, 6,235, 85, -147,245, 79,193,217,217,185,139,151,151,215,156, 3, 7, 14,184,171, 84, 42,197,229,203,151, 11, 78,158, 60,249, 68,167,211,173, - 75, 79, 79,223, 86, 94,232, 28,224,243,249,115, 1, 64,161, 80,240,121, 60,158,180,178, 70,154, 65, 22,194,134,131, 63, 29,112, -105,194,178, 95, 37, 79,238,223,193,178, 61, 71, 32, 54,106,141, 15,242,181,221,239, 23,235, 15,149,111,118,166,147,179, 44,149, -130,186, 9, 24, 2,107,169,208, 49,130, 16,201, 85, 74,213, 85,165,217,214,205,157,209,215,242,196, 69,131, 26,102, 10,161, 8, - 0, 92,124,252,121,183, 85,122, 92,190,251, 16, 18,137,149,208,196,151,236, 12,123,123,251,198,231,207,159, 39, 37, 37, 37,234, -123,247,238,193,218,218, 26, 14, 14, 14,176,176,176,192,195,135, 15,113,250,244,105,196,197,197,129, 82,138,250,245,235, 87,235, -218,102,102,102,162,168,168, 8,221,187,247,104,157,150,150, 42,177,119,112,212,158, 57,125,234, 84, 77, 52, 89,150, 37, 0, 16, - 24, 24,136,192,192, 64, 65,106,106,170,229,161, 67,135,204, 22, 44, 88,224,108,103,103,119, 83,165, 82,189, 98,156, 76, 53, 88, - 0,160, 86,171,161,209,104, 32, 20, 10, 33,145, 72, 32, 20, 10, 81, 84, 84,132,204,204, 76, 20, 23, 23,191,136,184,153,170,251, -226,211,100, 75,179, 91,127,206, 28,159,218,215,240, 75,247,114,185,201, 58, 67, 8,169,184,191,153,229,127,123, 85, 86,213, 87, -133,230, 43, 17,150,151,162, 76,130,154,104,134,132,132, 84,104,188, 82, 74, 72, 36,146,172,138,200,149, 68, 34, 49,105,170, 46, - 66, 8, 88,150,133, 80, 40, 68,253,250,245,241,205, 55,223,224,193,131, 7, 56,123,246, 44,156,156,156,208,165, 75, 23, 8, 4, - 2, 36, 38, 38,190,210, 62,203,148,155,147,152,152, 56,165, 93,187,118,129,203,150, 45,147, 36, 37, 37, 33, 54, 54, 22,230,230, -230,152, 51,103,142,120,234,212,169, 94, 87,174, 92,153, 1,224,199, 42,175, 97,222,195, 61,229, 6, 23,193,193,193,159,182,105, -211,230,207,229,170,157,157,197,142, 29, 59,236, 43,140,215,203,251,252,175, 72, 77, 77, 45,152, 53,107,214, 18, 63, 63,191,165, -229,213,130,205, 41,165,242,180,180,180,200, 61,123,246, 16, 0,232,213,171, 23,117,118,118, 62, 87,158, 55,238, 45, 93,186,180, - 85,108,108, 44,157, 53,107,214, 27,203,185,244,172,244, 53, 63, 46, 95,187,100,214,180,241,162,175, 58,201,240, 89,184, 6, 44, -203,130,199,227, 97,217,234, 13,250,184, 7,247,238,134,134,134, 30,162,148,118, 47,143,102,150, 0,136, 35,132, 36,136, 68,162, -180,103,207,158,113,238,129,163, 74,152,151,195,227,111,219, 40,235,222, 62,176, 44,235,100,105,231, 98, 61,252,227,246, 96, 89, -192,192, 2, 6, 35,133, 74, 89,138,140, 71,103,149, 90,173,214,164,135, 46, 55, 55,119,238,224,113,223,123,221,122,206, 71,122, -190, 22, 41,167,231, 80, 77,206,163,143,186,116,233, 50,164, 77,155, 54, 69, 53, 62,145,242,158,143, 46,194,148, 64, 43, 91,231, -115,223, 46, 92,143,155,207,180, 96,233,127, 34, 89, 70, 22, 96,255, 33, 1, 44, 23, 23, 23,111, 43, 43,171, 69, 7, 14, 28,240, - 16,137, 68,138,248,248,120,227,185,115,231,210,244,122,253,170, 10,115, 85,110,194, 6, 4, 5, 5,233,101, 50, 25,148, 74,165, - 90,175,215,151,188,205, 92, 5, 74,165,174, 33, 65, 65, 23, 38, 44,251, 85,162,214,106, 81,168,210,192,206,201,209,120, 47, 95, -217,253, 94,177,230,208,139, 8,151, 66,208, 36,180,142,139, 11,145, 40, 64, 1,164, 22,107,211, 76, 49, 87, 0, 32, 87, 88, 48, -174,161,145, 8, 29,187, 2, 42,158, 5, 5, 0, 43,123,103,166,213,168,239,208, 97,217,121,104,248, 10,147, 45, 48,159,207,215, -120,123,123,171,203, 11, 85,228,230,230,226,193,131, 7,200,203,203,195,138, 21, 43,240,232,209,163, 23, 47,221,234, 25,140, 23, - 47,113,100,103,103,137, 41,165,200,202,204, 16,213, 84,179,194, 96,189,116,239, 48,114,228, 72,126,105,105,169,228,101,115, 85, - 93,131, 85,145, 14, 74, 41,180, 90, 45, 10, 11, 11,161,213,106,241,228,201,147, 23,230,170, 60,130, 86,189,243,215, 22,235,223, -184, 94,157,167,127,135,234,132,203, 0,132, 47, 13, 82,232, 80, 83,115,245,154,241,169, 86,244,167,170, 8, 22,222,208,128, 89, -165, 82, 57, 80, 74, 73, 84, 84, 20, 76,105,127,245,178,193, 18,137, 68,232,221,187, 55, 98, 98, 98,144,156,156, 12, 62,159, 15, -181, 90, 13,181, 90,141, 70,141, 26, 65, 36, 18, 85, 55,130, 69, 5, 2,193,128,209,163, 71, 75, 18, 18, 18,144,147,147, 3,134, - 97, 96, 48, 24, 96, 52, 26, 49,100,200, 16,169, 72, 36, 26,128,106, 54,196,190,125,251,118,251,203,151, 47,215,125,125,201,206, -206, 46, 20,139,197,127,203, 50,112,207,158, 61,164, 87,175, 94,180, 87,175, 94,180,194,104,153, 74,118,194,253, 53,219,118,238, - 59,249,205,172,133, 37, 57,185,121,144,203,229,200,206,201,197,183,115, 23,233,207, 94,186,113,110,228,144,143, 35,150, 44, 89, -242, 61,128,184,242, 93,226,150, 46, 93, 58,104,232,208,161, 91, 42,134,107,224,224, 48, 57,130, 85, 81, 69,248,150, 47,187, 96, - 75, 91,151,179,211,230,255,106,182,247, 46, 15,249,233,113, 80,103,197,193,173, 97, 55,100,198, 93, 6, 53,234,255,120,240,224, - 65,105, 85, 7, 59,126,252,184,143, 91,221,208,177, 13, 66,194,177,240,112, 9, 74, 30,236,132, 54, 63, 97,117,231,206,157,247, -189,235,137,176, 20,152, 48,160, 73,160,149,141,211,185,175,191,255,213,250, 96,140, 0,185,105,113,120,180,127, 10,140,186, 63, -213,138, 29,169,174,190,148,213,138, 74, 10, 50,161, 45, 54, 66,194, 40, 37,127,245,141, 75, 77, 77,125, 18, 24, 24,184,249,151, - 95,126, 25, 81,191,126,125,217,216,177, 99, 31, 23, 21, 21,205, 75, 75, 75,251,237,165, 23,121,235,218,181,107, 79,154, 51,103, -142,215,243,231,207,113,225,194,133, 39, 60, 30,239,230,219, 52, 99, 84,170,148,122, 22,226, 85,151,182,175,251,138,231, 94, 23, -187,102, 77, 54, 92,185,255,176,235,131, 98,195,209, 23,230,202, 76,228, 23, 17,232,125,232,203,209, 35, 24, 99,244, 49, 60, 74, -206, 66,122,169,254,180,201,233, 46, 86,234, 5, 98, 41,204, 28, 61,144,164,102,133,174,174,174, 55,134,246,232, 34,100,120,124, - 48,124, 33,158, 21,104, 76,126,137, 27, 12, 6,241,195,135, 15, 9,128, 87,204,157, 90,173,126,107,196,231,125, 98,170,230,155, -218, 71, 1,128, 94,175,175,177,230,203, 17,155,170,142,197,178, 44, 52,154,106,244, 21,209, 20,188,249, 30,168,114,244,239,227, -178,149,255, 21,189,139,185,170, 48, 62, 21, 13,208,197, 98,241, 11,147, 98,106,148,169,146, 8, 86,141,126,127,147, 65, 23, 10, -133,240,245,245,197,133, 11, 23, 96,105,105, 9, 51, 51, 51,200,229,114, 72, 36, 18, 88, 90, 90, 66, 36, 18,129, 97,170, 53, 68, - 32,213,233,116,181, 92, 93, 93,241,228,201, 19, 72, 36,146, 23,139, 88, 44,134,175,175, 47,148, 74,165, 11,254, 81,177,250,255, - 14,131,122,181,237,182,102,251,222,129,187,246, 30, 26,165, 81,171,131,124,235,122,211,216,251,209,119, 71, 14, 25,208,129,187, - 58, 28,239,213, 96, 85, 82,168, 4, 91,218,186,156,157,242,221, 47,230,187,163, 25, 20,164, 63, 66,210,177,175,139,141, 58,101, - 62,203,234,221,243,159, 94, 2,128, 77, 38,126,201,135, 53,105,221,141, 57, 23,171,133,174, 56, 13, 69, 49,187, 18,197, 98,241, -212,247,113, 34,110,162,148, 64, 43, 27,167,115, 83, 23,252,106,189,247, 46, 31,121,105,113,120,122,100, 90,161, 81,167,108, 29, - 21, 21,245, 98, 28, 45,135,192,238,248,108,202, 18,108,248, 97,188,201,218,159,136, 68,221,250,250, 91,118, 30,210, 60, 13, 70, - 98,196,128,135,177, 29,157,155,147,110,105, 23,233,254,191,242,230,197,196,196,124,231,237,237,205, 24, 12,134,207,116, 58,221, -172,180,180,180, 61, 47, 69,174, 62,112,119,119, 95, 56,119,238, 92,215,164,164, 36,209,213,171, 87,243,110,223,190,205, 26,141, -198,239, 43,211,188, 87,168,153, 28,164, 16,242,188,221,156, 71, 63, 73, 73,233,122,191,200,112,172,226,183, 32,185, 40,176,121, - 3,191,203,115,103,125,173,208, 94,218,131,210,244,100,172,136,202, 40, 98,141,250,105, 38, 70,221,172,221,133,148, 76, 27,250, - 41, 91, 92, 92, 12,153, 72,200, 38, 63,122,202, 27,216,182,133,241,135, 41, 19,153,140,140, 12, 40, 75, 75,249, 46, 46, 46,214, -169,169,169,121, 85, 68, 8,230, 0,104, 93,191,126,125,180,107,215, 46,113,246,236,217,177, 47,155,143,191,153,193,122,227,215, -181, 78,167, 35, 53,213,124, 57,130, 85,149,193,170,118, 4, 75, 83,244,102, 35,165,204,126, 87,131,245,156, 16, 82,171,226,223, -239,227, 30,168,213,106,251,151,170, 6, 65, 41,173,113, 56,171, 60,130, 85,227,223, 95,134, 97, 24, 80, 74, 33, 18,137, 16, 23, - 23, 7, 71, 71, 71, 24, 12, 6,200,229,114,200,100, 50,148, 71,148, 33, 18,137,192,231,243,171,147, 76, 86, 36, 18, 61,143,139, -139,171,107,101,101, 5,163,209,248,138,201, 74, 72, 72,128, 92, 46, 79,173,110, 4, 43, 56, 56,248,184, 84, 42,117,127,125,189, -157,157,157,197,223,245,229,245,114,228,170, 87,175, 94,116,220,184,113,213,214, 88,254,221, 87, 91, 1,108, 29, 55,110,220,230, -237,235,142,132,134,134,134, 30,246,243,243, 35, 0,192,245, 24,228,120, 47, 6,171,162, 80,170,248, 91,209,158,201, 69,152, 18, -108,105,227,124,118,210,220,181,230,219,111, 49, 40, 76,143, 69,218,169,233,133,172, 78,217,154, 97,152,244,228, 43,191,236, 1, -160,140,142,142, 62,111, 23,216, 29,132,148,245,220,123,211, 72,238,229, 5,125, 67, 95, 31, 31,236,142, 49, 64,157,113, 23, 12, -161,155,218,182,109,171,124,215,147, 8, 9, 9, 9,180,178,113, 58, 55,121,254, 47,214,187,111,243,145, 95,102, 2, 11, 89,157, -178,117,170,206,245,149, 65, 74, 89, 2,108,248, 97, 60, 88, 19,138,225, 33,132, 88,241,228,146, 85, 3,219,133,245,113,175,227, - 10,150,234,193, 10, 41,122, 78,182,229,199, 69, 43,247,213,106,199,251,141, 45, 97, 71,165, 92,253,235, 70, 31,127,242,228,201, - 92, 71, 71,199,189, 25, 25, 25, 47, 90,167,186,186,186,118,244,240,240,152, 63,103,206, 28,143,148,148, 20,197,237,219,183,139, -246,236,217,147,192, 48,204,156,244,244,244, 42,191,238,239, 23,235, 38, 6,154,137,214,197,148, 24, 94,140,161, 19, 32, 23,214, -255,116, 96,255,171,109,251,127, 42,121,122,106, 43,172, 19, 30, 98, 89,116,166, 49,181, 88,221, 63, 86, 73, 51, 76, 49, 87, 98, -177,120,207,138, 61,123,158,212,171, 87,143,148,150,150, 66,175,215, 35, 39, 39, 7, 63,110,219,253,128, 82, 10, 43, 43, 43,156, - 58,117,138, 29, 59,118,236, 30, 23, 23,151, 94,111, 51, 89, 47, 13,211, 0,161, 80, 72,164, 82,169,103, 98, 98, 98,162,135,135, -135,250, 77, 38, 69, 44, 22, 87,219, 96, 73,165, 82,176,236,219,131, 0,213,209, 52, 24, 12,196,148,245,213,209,172, 72, 91, 69, -227,246,215,215, 87,192,227,241,192,178,108,165,231,242,103,247,246,150, 8,150, 50,235,157, 12, 22,165,212,189,162, 35,205,223, -173, 32, 44,143,132, 1, 0,251,182,161, 24,170, 19,193, 42, 55,123, 16,137, 68,184,112,225, 2,186,116,233, 2, 74, 41,196, 98, - 49,100, 50, 25, 36, 18, 9, 46, 95,190, 12,145, 72, 4, 30,143, 87,157, 40, 22, 53, 24, 12,219,126,254,249,231,175, 23, 44, 88, - 32,173, 56, 70,133,193,250,233,167,159, 84, 26,141,102,155, 41, 6,139, 88, 5,244,181,180,178,254,164,160, 32,119, 83, 19, 95, -203, 74,123, 17,190,105,159,242,246, 88,255,117, 42,134,105,160,148,118,123,125, 40,134,138,109,198,141, 27,135,215,135,112,168, -108,152, 6,103,103,103,171,117,235,214, 13,101, 89, 54,160,124,213,235,189, 5, 43,238, 99,197,251,169,162, 87,225, 43,189, 8, - 57, 56,170, 29,193, 98, 8,224,196,127,238,103,105,227,122,118,194,220,181,230,155,175,243, 80,152,254, 16, 57,103,191, 45,164, - 6, 85,235,168,168,168,219,246,245,186, 35,188,105,235,102,109, 63,236, 5,135,131,187,113,243,202, 25,252,184, 98, 3,190, 26, -253,121,165, 31, 74,246,246, 54,200,185,162,134, 62,255, 9, 8, 33,209,239,122, 2,141, 26, 53,242,182,180,118, 60, 55,105,222, - 47,214, 59,162,248, 40, 72,251,143, 9,156,182,242,236,237, 47,134, 14,122,101,123, 83,167,199,249, 68, 36,234, 22,232,227,186, -190, 95,199,166, 86, 22,196, 0, 67, 82, 44,214,125,218, 7, 81, 93,116,104,218,215, 2,141, 58, 41,224, 21, 44,233,115,228,215, -188, 54,206,205,201,144,191, 50,154,245,178,185,114,118,118,238,226,234,234, 58,251,240,225,195,238, 6,131, 65,113,225,194,133, -226, 61,123,246, 60, 53, 24, 12,203,211,211,211, 15,155, 28, 29, 43,209,190, 48, 87, 65, 22,194,134, 67, 62, 27,116,105,236,210, - 53,146, 7, 81, 55,177,112,219, 65,152,243,244,198, 91, 25,234,222, 49, 37,255,169, 62,172, 52,163,241,249,115,119,236,216, 33, -247,247,247, 39,185,185,185, 47, 34, 45, 58,157, 14,133,133,133, 40, 46, 46,134, 70,163, 65, 80, 80, 16, 51,107,214, 44,249,183, -223,126, 59, 23,192, 40, 83,211,107,103,103, 7,161, 80, 8,157, 78,247,194,164,136, 68, 34, 88, 90, 90,162,176,176, 16, 39, 79, -158, 68, 85,131, 83, 10,133,162,116,134, 33,110,102, 10,133, 94, 46,151, 83,185, 92,254,167,109,170,171, 89,110,114,178, 59,118, -236,104, 55,103,206, 28, 65, 72, 72,200,139,245, 21, 85,132, 53,209,164,148, 42,219,181,107, 39, 91,190,124, 57,220,221,221,161, -213,106, 95, 49, 82, 12,195, 64, 40, 20, 34, 57, 57, 25,243,230,205, 3,165,212,244, 15, 25,117,190, 30, 65,131,236,161,202,213, - 67,149,171,135, 58, 71,135,210, 44, 61,244, 74,227,223,173, 0,171, 73, 3,116, 19, 34, 97,246,239, 26,193,170,168,174, 20,139, -197, 72, 76, 76,196,241,227,199, 17, 17, 17, 1,115,115,115,148,150,150,226,226,197,139, 72, 77, 77,133, 88, 44, 6,143,199,171, - 86, 35,247, 90,181,106,253,112,227,198,141, 46, 99,198,140, 9, 24, 54,108,152,212,207,207, 15, 9, 9, 9, 88,178,100,137,250, -222,189,123,241, 86, 86, 86,115,128,170,231,153,117,113,171, 53,118,221,182, 67,130,193,253, 59,142, 6, 74, 97, 74, 47,194, 87, -247,249,223, 52,118,127,203, 48, 13, 29,223,178,249,203, 67, 56,188, 50, 76,195,203,236,219,183,207,211,197,197,197, 15,101, 61, - 3,129, 63,247, 22,124,153,155, 81, 81, 81, 97,224,122, 17,114,188, 15,131, 85, 94, 64,143, 15,255,232, 27,243, 77,215,248,200, - 79,141, 65,225,197,153, 47,204, 21, 80,214,240,221,190, 94,119, 24, 89,138,214, 29, 62,170, 24, 20,244,245, 66, 38,232,229,113, -171, 4, 18, 69,144,129, 10, 1,168, 97, 40,120, 10,145, 72,116,187,186, 9,126, 93,147,101,217,137,141, 63,250,198,122,203, 77, - 62, 10,211, 30, 34,251,220,140, 66, 86,167,108,157,172,117,189,253,197,208, 65, 38, 53,106, 39,132,180,173, 24,211,227, 19,145, -232, 91, 1,143, 76,255,176, 69, 67, 97,179, 96, 31,200,179, 18,145,145,146,134, 93, 15,179,243,226,243, 53, 67, 46, 19, 29,146, -158,106,214,117, 26,106,109,109,229, 40, 64,231, 17, 54,214,215, 14, 22,237,115,105,205,232,168,142, 46, 72,187, 68,103,189,174, -249,190,168, 74,211,197,197,197, 91,161, 80,252,120,236,216, 49, 59,145, 72,100,254,224,193, 3,227,222,189,123,147,141, 70,227, - 79,233,233,233, 59,107,162, 25, 40,149,186, 6,212,245, 60, 63,118,241,106, 73, 73,169, 18,165, 90, 29,156,221, 92,140,231,163, - 99, 63,138, 41,209,238, 55, 69,211,193,193,161, 85,255,254,253,235,135,132,132, 48, 47,155, 43,173, 86,139,162,162, 34, 20, 23, - 23,163,168,168, 8, 69, 69, 69, 72, 77, 77, 69,211,166, 77, 25, 63, 63,191, 32, 7, 7,135, 86,153,153,153,103, 95,215,124,105, -152,134,175, 1, 48, 50,153, 44,238,202,149, 43,234,143, 62,250, 8, 82,169, 20,165,165,165,112,117,117, 5,203,178,184,120,241, - 34,226,226,226, 10, 0,236,200,200,200, 56, 85, 89, 58, 85, 42,101, 45, 66, 8,207, 92,161,104,219,190,125,251,254, 67,134, 12, -177,124,121,251,154,104, 2, 64,118,118,182,199,133, 11, 23,190,237,214,173,219,232, 14, 29, 58,200,166, 77,155, 38,240,244,244, -132,193, 96, 32, 53,213,204,207,207,183,136,142,142, 94,212,172, 89,179, 47, 58,116,232,192,159, 63,127, 62, 44, 44, 44, 96, 52, - 26, 33,149, 74, 81, 84, 84,132, 57,115,230,224,210,165, 75, 6, 74,233,202,194,194,194, 73,149,105,190, 50, 14,214,132,197, 13, - 42,203,135,111, 27, 7,235,175,200,243, 42,149,202,161,186, 81, 49, 83,210, 25, 29, 29, 77, 95, 31, 15,171,178, 8,214,155, 52, - 43,162, 75,124, 62, 31, 25, 25, 25, 56,116,232,208, 43, 99, 96, 85, 44,111,171, 34,124, 75, 58,233,185,115,231,140,132,144, 8, -131,193, 48,101,220,184,113, 67,148, 74,165,171, 92, 46, 79,211,233,116,155, 44, 45, 45, 43,198,193, 18, 86,165, 41, 18, 73, 4, -132, 97, 32,149,200,165, 42, 85,118,210,155,122, 17,190,118,173,147, 68, 34, 7,155,138,125,254, 87,247,253,181, 97, 26, 94, 25, -138,225,181,125, 94, 25,194,225,245, 97, 26, 94,214,236,222,189,123, 2,128, 71,148, 82,134, 16,242,232,245,222,130, 47,201,214, -141,138,138, 10, 11, 13, 13, 61, 79, 41,149,189,222,139,240,175,200,243,255,100,205,127,141,193, 2, 32,185, 28,245, 24,140, 56, - 11,197,215,127,124,197, 92,189,120,210, 89,224,230,149, 51, 96, 89,160, 69,187, 30, 85,154, 25,131,166, 52,126,238,174,103,193, - 70,173, 10,134,162,164,184, 14, 31,118,202,122,151,196,219, 5,245,128,155,144,202, 47, 69,199,131, 47,201, 69,193,181, 31, 10, -136, 81,211, 58, 42, 42,234, 78,141, 51, 13, 48,109,245,209, 61, 66, 98, 97,141,187,227, 6, 35,173,160, 20, 71,159,229,255, 70, -149,154, 81, 91,105, 89, 85,160,107, 4,185,184,254,155,140, 85,205,123, 90,244,177,117, 17, 96,241, 87,155, 32,153,106, 35,108, -212,166,197, 95, 58, 71, 97, 69,195,247,117,235,214,141, 12, 9, 9, 49,251,242,203, 47, 31, 23, 22, 22,190,210,240,189,186,196, -168, 84, 41,129, 10,209,234,179,191, 44,254, 74, 26, 24,142, 61,243,166, 25, 47, 68, 63,234,126,191, 88,123,200, 84, 13,177, 88, - 28, 57,106,212, 40, 97,105,105,233,159,204,213,235, 6,171,168,168, 8,119,239,222, 69,175, 94,189,196,177,177,177,145, 0,206, -190, 37,130, 51,163,124,192, 73,190,173,173,109,246,234,213,171,187,109,217,178,165,231,144, 33, 67,196,145,145,145,120,240,224, - 1,110,220,184,161,209,106,181,127, 8,133,194,253,137,137,137, 38,181,242,166,148, 26, 1, 28,247,240,240, 56,191,122,245,234, -110, 44,203,190,152,207,242, 29, 52,245, 0,102, 88, 91, 91, 47,218,179,103,207,194, 51,103,206,244, 31, 56,112,160, 68,175,215, -147,119,208, 52, 0, 24,103,103,103, 55,253,200,145, 35,155, 78,156, 56,209,253,147, 79, 62, 97,198,140, 25,131, 21, 43, 86,224, -247,223,127,103,141, 70,227,126,129, 64, 48, 40, 59, 59,187,202, 14, 40,175,140,131, 85,201, 56, 87, 85,253,110, 2,183,254, 11, - 89,255,157, 53, 95,143,132, 53,108,216,208,225,229, 94,154, 47,255, 53, 53,130, 69, 8, 65,104,104,232, 43,255,175, 24,146,129, -199,227,189,178, 84,167,138, 16,128, 37,165,148, 5,176, 18,192, 10,188, 58,138, 59, 15,255, 25,233,221, 36, 92,220,220,145,154, - 12,155,156, 82,117, 65,229,147, 61, 59,216,184,184,185,255, 21,229, 90,193,172, 89,179,150,204,156, 57,115,201,235, 67, 49,188, -188,221,235, 67, 56,204,158, 61, 27,111, 27,166, 33, 45, 45, 45,127,214,172, 89, 63, 0,128,159,159, 31, 41,175, 22, 12, 69,121, -111,193,151, 52, 55,163,108,170, 28,217,176, 97,195, 6, 2,120,171, 38, 7, 71,117, 12,214,215, 37, 81,203,244, 0,108, 8, 33, -211, 82,117,174, 15,254, 92,136, 0, 63,174,216,240,202,164,208,149,193,227, 49,211,178, 14, 14, 94, 78,129,124, 30,193,180,119, - 77,188,149,165, 57,140,197,198,111, 74,163,151,179,148, 82, 75, 66,200,212, 91,183,110, 61,120,103,103,110, 97,141,226, 57, 35, -241,123, 76, 26,205, 40,213,247,216,170,125, 53, 82, 83,222,230,170,175,115,115,178,203,202, 89,176,119, 92,107, 27,114, 56,111, -224,223,226,134,198,196,196,204,247,246,246,230,173, 89,179,230, 51,173, 86,251, 74,195,247, 26,107, 22,107, 39, 7, 41,132, 60, - 63, 79,183,209,177,137, 73,221,238, 23,155, 86, 45,248, 18, 34, 23, 23,151,251, 74,165, 18,132, 16,104, 52,154, 23,198,170,184, -184, 24,133,133,133, 47,254,175,211,233,144,157,157, 13, 79, 79, 79,188, 52,102,210,219, 76, 70,250,203, 30,193,202,202,234,216, -242,229,203,251, 47, 95,190,188, 13,128,211, 42,149,106, 71,126,126,126,141,134,254, 40, 55, 58,187,164, 82,217,143,132, 16, 23, -177, 68,170,189,116,233,210,209,119,209,204,203,203, 43, 6, 48, 66, 42,149,206,253,249,231,159,151, 75, 36,146,176,172,172,172, -119,210, 44, 55, 79, 31,217,216,216, 56,111,222,188,121,247,250,245,235, 27,243,249,252,107,132,144,222, 5, 5, 5,213,158,236, -153,188,250,245, 94,237,223, 77,224,247,255, 66,182,127,103, 77, 83,135, 95, 48, 21,131,193, 80, 50,115,230,204,172, 55,205, 59, - 88, 97,166, 94, 94,167,211,233, 76, 26,230,196,209,209,209,228,177,200, 42, 27,122, 7, 0, 24, 66, 84, 0,164, 95,207, 94, 84, -254,193,108,242,100,207, 32, 32,218,255,101,185, 54,115,230, 76, 58,123,246,108, 66, 8,217,143,178,241,168,158,188,222, 8,253, -229,223,102,207,158,141,153, 51,103,210, 89,179,102, 85,169, 25, 27, 27, 75, 9, 33,167, 1, 36, 0, 72,124, 89,247,229,245, 21, -251, 84,166,201,193, 81,165,193, 98, 41,144,170,115, 77, 6, 48,248,229,117,127,126,193,225, 79,109,174, 42,243, 88, 29, 58,116, - 56, 13,192,239,125, 37,190, 32,191, 16,196,186, 97, 82,126,126,238, 39, 89,247,247,191, 23, 77, 22,248,113, 72,163,200,175, 0, - 16, 10, 44,126,221, 92,189,242, 21,116,145,238,119,106, 74, 22, 52,106,211, 98,124,249,203,103,254,223,225,166,190,169,225,251, -187,242,166,134,239,213,120,217,156, 16,139,197,164,184,184, 24, 42,149,234,149,104, 85, 81, 81, 17,148, 74, 37, 74, 74, 74, 80, - 49,181, 71, 73, 73, 9,204,204,204,160,215,235,171,245,165, 88,110, 82, 86,135,132,132,172, 43,175, 38,121,103, 84, 42,165, 43, - 0,132,132,132, 8,222,159,166, 42, 13, 64,207,247,169,153,155,155,155, 6,160,137,151,151,151,200,212,201,162, 43,139,100,213, -244,119, 19, 88,243, 95,200,242, 91,241, 55, 35, 41, 41,201,255,125,107,166,165,165,197,189, 79,189,220,156,140,181, 95, 12,238, - 53,170, 98,210,103, 83, 38,123,174, 48,102,121,185, 25,107,255, 87,215,178, 98,154, 17, 0,212,197,197,101,243,243,231,207,221, - 9, 33, 73,175, 71,146, 94,255,109,214,172, 89,120,219,152,127, 47,107, 2,128,167,167,231,190,228,228,100,103,161, 80,152,254, -178,238,235,235, 43,211,228,224,120, 83, 70,251,175, 45, 0,130,254,159,104,182,229, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78, -243,175,211,252,167, 45, 12,103, 49, 57, 56, 56, 56, 56, 56, 56, 56,222, 47, 4, 64,208, 91, 34, 91,247, 77, 22, 33, 36,168, 6, -145,179,251,127, 35, 77,251, 74, 52, 79, 85,161,217,182, 6,233,228, 52, 57, 77, 78,147,211,228, 52, 57,205,127,165,102, 85,218, -255,152,222,137, 92, 21, 33, 23,230,229, 52, 57, 77, 78,147,211,228, 52, 57, 77,174,138,144,171, 34,228,224,224,224,224,224,224, -224,248, 91,243,214, 97, 26,122,214, 43,235, 62,252,199, 61,174,195, 4, 7,192,227,241, 22,180,104,209, 98,212,165, 75,151,126, -210,235,245,115,106,162, 65, 8,113,118,112,112,248,142, 82,218,132, 16, 34,230,243,249, 15, 51, 51, 51,231,235,245,250,139, 53, - 77, 23, 33,196,205,209,209,241, 59,150,101, 27, 3, 16,242,249,252,152,180,180,180,121,148,210,107,239,160,105,238,232,232,216, -138,101, 89,215,178, 83,231,101,165,167,167, 95,164,148,166,114, 57,129,131,131,131,131,163,198, 6,235,163, 0, 2, 6, 64, 64, - 36,156,102, 15, 39,252,153,107,105,114,197,139, 7,101,131,177,249, 1,136, 5,112,139, 82, 90,244, 46, 9,248,255,162,249,119, -135, 16,194, 88, 90, 90,182,147,201,100, 99, 75, 74, 74,130,205,205,205, 99,202,167,199, 57, 84, 62, 40,225,187,104,219,247,239, -223,127,234,186,117,235,208,167, 79,159,233,132,144, 37,148,210,146,234,104,216,216,216,116,245,244,244, 92,187,124,249, 10,187, -102,205,154, 17,169, 84,138,216,216, 88,151, 81,163, 70,134, 58, 59, 59,239, 74, 75, 75,251,162,186,233,178,179,179,235, 93,167, - 78,157,229, 43, 87,174,180,107,210,164, 9, 17, 8, 4,136,138,138,114, 29, 59,118,108,184,147,147,211,166,244,244,244,137,213, -213,180,182,182,246,175, 93,187,118,135, 85,171, 86,201,154, 54,109, 10,177, 88,140,187,119,239, 42,134, 15, 31,238,226,236,236, -124, 55, 45, 45,237,100,117,244, 66,134, 71, 11,132, 50, 29, 31, 0,116, 74,161, 33,106,109, 67,189,169,235,184,226,137,131,131, -131,227, 31,100,176,122, 7, 16, 16, 0,129,205, 48,135, 24,240, 53, 24,144,113,253,201,111, 43,126, 99,110,180,109,219,214,247, -243,207, 63, 39,229, 83, 71,248,239,220,185,243, 35, 30,143,247,136,101,217,235, 0,238,184,184,184,232, 42,166, 37,120,157,246, -222,228,197, 24, 89, 39,159, 66, 8,160, 1,195, 48,225, 85,105,126, 80, 7, 58, 66,128,227, 79,222, 28, 73,107,231, 69, 0, 10, -156,124, 86, 61,205, 19,241,255,140,200,156, 66,161,240,182,179,179,155,104, 99, 99,211, 49, 52, 52,180,104,196,136, 17,137, 15, - 30, 60,120,236,235,235,171, 94,191,126,253,124,189, 94,191,202,199,199,231,100,113,113,241,162,119, 24, 23,203, 67,175,215,227, -209,163, 71, 96, 24, 70, 0,192, 19,192,189,106, 24, 52, 39, 15, 15,143, 53,103, 47, 71,219, 23,105,121,120,146, 77, 1, 40,193, - 10, 29,177,122,195, 46,171, 25, 83, 70,247, 55, 55, 55,191, 84, 84, 84,180,171, 26,154,110,117,234,212, 89,126,255,254,125,123, -137, 68, 2,150,101, 81, 92, 92, 12,103,103,103,172, 95,191,222,234,171,175,190,250, 76, 38,147, 93, 80, 42,149, 7,171, 99,204, -107,215,174,221,225,193,131, 7, 50,177, 88, 76, 12, 6, 3,209,104, 52,112,115,115,163,219,183,111,151,140, 25, 51,166,129, 88, - 44,126,174,209,104, 30,155,100,174,126,137, 22, 20,229,156,141,160,201,170,233, 0, 64, 36,210,121,145,179,173,111, 20,229,156, -109, 84,213,186,144, 95,112, 53,106, 24,103,178, 56,254,183, 56, 57, 57,133, 88, 89, 89,237, 41, 40, 40, 56,159,158,158, 62,164, -124,102,131,119,253,248,115,230,243,249,158,148, 82,203,242,255, 23, 24, 12,134, 4, 83,230,220,124, 27,182, 94,173,186, 64, 44, - 27, 12,202, 54, 96, 0, 16,134,185, 99,212, 41, 55,230,196,157, 61,248, 78,154, 34,233,103, 0,109,192, 0, 44, 97,152,187,172, - 65,249,107,118,236,217,163, 92,206,224,120,111, 17,172,128,112, 88, 17, 96,202,180, 17,195, 24, 62,143, 71,230,175,253,165,223, -205, 43, 7,169, 83,173, 6, 47,166,220,104,222,188, 57,154, 55,111, 78, 22, 46, 92,232,119,230,204, 25,191,237,219,183,235,175, - 92,185, 18, 5, 96,211,155, 52, 41, 5, 90,118,144, 62, 55,232, 85,110, 77, 63,144,170, 61, 26,175,218,222,164, 73,115, 86, 44, - 22,163, 50,205,147, 87,174, 68,125, 80,231,205,154,101,194, 64,157, 96,254, 73,151,134,110, 36,178,243,140, 36, 83, 53,223,150, -206,255,103,230,234,188, 66,161,240, 26, 62,124,248,147,145, 35, 71, 94,144,203,229, 20, 0,148, 74,165,184, 75,151, 46,249,221, -187,119,207, 85, 42,149, 88,189,122,181,219,242,229,203, 79,154,155,155,167, 22, 21, 21, 53,170, 78, 84, 12,192,204,174, 93,187, - 78,255,242,203, 47, 81,171, 86, 45,140, 25, 51, 6,122,189, 62,138, 16, 50, 3,192,247,166, 12,186,103,111,111, 63,115,233,210, -165,246,165,122, 1,190,221, 18,143,188,146,178, 1, 69,101, 34, 6, 95,180,149, 96,244,232, 49, 22, 55,110,220, 88,136,215, 70, -144,174, 12, 71, 71,199,239, 86,174, 92,105, 39,145, 72, 64, 41, 69, 73, 73, 9,138,139,139, 81, 82, 82,130,210,210, 82,140, 28, - 57,210, 34, 38, 38,102, 41,128,131,213,208,108,181,106,213, 42,153, 88, 44,198,201,147, 39,235,106, 52, 26,158, 86,171,133,209, -104, 52,214,169, 83,231,209,151, 95,126, 41,190,127,255,126,123, 0, 38, 25, 44,167, 12, 8, 10, 85,170,149, 63,255,240,149, 29, - 0,124, 57,229,199,149,128, 42,156,154,176,206, 41, 3, 97, 0, 56,131, 85,121,254,228, 1,232, 33, 16, 8,122,122,121,121,133, - 62,121,242,228,182,193, 96,248, 3,192, 31,229,211, 19,189,139,118, 27,103,103,231,239,210,210,210,126,166,148,110,253,183, 92, - 83,123,123,251, 63,246,238,221,235,182,101,203,150, 79,127,253,245,215, 35,120,135, 81,242, 9, 33, 2, 0, 17,141, 26, 53,178, -237,217,179,167,192,209,209, 17, 74,165, 18,241,241,241,178, 83,167, 78,217, 73, 36,146, 92,141, 70,115,181, 58,247,202,182,110, - 83, 51,240,205,119, 70,180,106,219,172,207, 71, 61, 20, 14, 54, 22, 80,105,141,120,146,148, 94,235,216,145, 3, 45,157,131, 62, -188,162,211, 21,246,203,137,187, 92, 82, 93,205, 86, 29, 58, 55,107,219,166,141,194,194,210, 2,133,165, 58, 60, 77, 76,117, 63, -123,242, 96,115,167,160, 15, 47,176, 68,255, 73,230,189, 19, 74,238,169,227,168, 14,127,106,228,190,251, 1,125,211,131, 2,185, -153,252,141, 2, 22, 22, 22,136,140,140,196,252,249,243, 5, 0, 26,191,106,170,254, 51,108, 2, 3,192,104,212, 58, 77,255, 98, - 52, 68,124, 42,254,176, 99,123, 98,110,110,110,146, 38,239, 45,154, 0, 64, 25, 33, 28,172, 13,109,195,235,170, 90,102,222, 25, - 51,224,206,249,239,130,180,234, 2,193,235,154, 50,153, 12,222,222,222,248,230,155,111,222,148,206,247,222, 37,244,127,161, 73, - 41,117,246,247,247, 47, 94,186,116,105,221, 89,179,102, 89,169,213,106, 57, 0, 55,175,128, 70,174, 12,195,184,169,213,106,243, -153, 51,103,218, 45, 92,184,176,174,157,157, 93, 1,165,212,174,154,233,156,187,114,229,202, 25,251,247,239,103,154, 55,111, 14, - 43, 43, 43,180,106,213, 10, 71,142, 28,225,255,244,211, 79,243, 1, 76, 55, 37,157, 12,195, 52,111,214,172, 25, 97, 89,138,252, - 18, 61,206, 46, 8,193,229, 31,195,160,212,178,200, 47, 40,130, 90,173,134, 76, 38,147, 18, 66,204, 76, 61,119,150,101, 27, 55, -105,210,132, 0,101, 35,191,151, 45,165, 40, 46, 46,251,171,213,234, 32, 16, 8, 20,132, 16,113, 53, 52, 93,155, 54,109, 10, 0, - 80,169, 84,252, 54,109,218,144,214,173, 91,147,226,226, 98,126,197, 52, 62, 2,129, 64, 68, 8,225,155,162,169,149, 9, 8, 75, - 89, 7,185, 76,106, 43,151, 73,109, 89,202, 58, 0,128, 41,235,180, 50, 1,249, 43,243, 39, 33,196,142,199,227,109,240,242,242, -122,200,227,241, 54, 19, 66, 28,223, 69,147, 16, 18, 70, 8,153, 47,147,201, 78,249,251,251, 39,203,229,242, 51,132,144,239, 9, - 33, 17, 53,209, 36,132,136,100, 50,217,153,249,243,231,239,190,125,251,118,159,211,167, 79,123,222,187,119,239,163,133, 11, 23, -238, 52, 51, 51,187, 72, 8,145,189,203,179,233,233,233,185,254,250,245,235, 97, 77,154, 52, 89, 87, 89, 30,170,142, 38, 33,132, - 71, 8, 9, 38, 21,243,227,252, 13,202,144,151,113,117,117,117, 14, 12, 12,116, 19,139,197,104,214,172, 25, 40,165,145,239,168, - 25, 49, 98,196, 8,199, 9, 19, 38, 8,238,220,185,131,117,235,214, 97,255,254,253,200,202,202, 66,231,206,157,133,173, 91,183, -118, 20,139,197, 17,213,210,228,155,239, 28, 59,110,124,135,175,198, 12, 85,220,125,174,195,198, 83,207,177,239,106, 58,178,148, - 34,116,249,104,144, 69,251,110,125,219,139,196, 22, 59,171,171, 57,117,202,148, 14,195, 62,251, 88,241, 32,157,197,129,107, 25, -184,246,168, 16, 6,129, 37, 58,125, 52,196,170, 65,211, 14, 31,242, 33,216,244,119,184, 71,255,116,205,127, 69, 4,107,230, 58, -154, 63,103, 36,249, 97,254,234, 95,166, 51,132, 80, 87,159,246, 15, 60,189, 27,151,178, 44, 11,149, 74, 85,241,162,129, 74,165, - 66, 82, 82, 18,174, 95,191, 14, 11, 11,139, 74, 15,116, 44,158, 98,222, 23,255, 57, 92, 65, 97, 33, 92, 92, 61, 33,147,201,170, -212, 60, 90, 73,117, 30,159,150, 69, 67,134,246,234,206,127,158,158,206,191, 18,125, 54,100,215,178,237, 33,110,117, 62,136,109, - 16, 57,249,190,153, 69, 45,213,157, 59,119,112,245,234, 85,228,231,231,163, 81,163, 70,255,152,155, 71, 8,209, 47, 90,180, 40, - 58, 45, 45,141, 92,186,116,169,193,156,165,219, 61,239, 21,213,230,101,151, 80,129,157,217,115, 79,127,217, 99, 99, 97, 97, 97, -194,196,137, 19,207, 58, 58, 58,106, 70,143, 30,221,210, 68, 93, 9, 0,223, 94,189,122, 77, 29, 53,106, 20,226,227,227, 49,116, -232, 80,213,141, 27, 55,114,155, 52,105, 98,243,235,175,191, 74, 39, 76,152,128,243,231,207,207, 36,132,236, 5,144, 64, 41,125, -235, 92,106, 44,203,138,164, 82, 41, 80, 84,246,161,170, 51, 84,204, 77, 11,148,150,150,130,143, 2,136, 68, 34, 6,128, 29, 0, - 83,191, 60,133, 98,177,248,133,185, 74,201, 42, 70, 82, 86, 9,138, 75, 52, 80,169,244,208,170, 1,177,185, 3, 15, 72,182, 1, - 96,106,227,116,158, 88, 44,134,193, 96,128, 78,167,131, 90,173,134, 90,173,134, 70,163, 65, 97, 97, 33,138,139,139,193,231,243, -101, 0,204, 1,228, 85, 41, 38,146, 26,120,140,112,254,215,243, 86,206, 2, 0, 30, 35,156,111, 6, 53,107,202, 58,158, 72,106, -248, 11,243,149,216,206,206,238,236,238,221,187,253,189,189,189,145,144,144,224,215,187,119,239,112, 66, 72, 48,165, 84, 89, 77, - 45, 25,195, 48, 63, 12, 30, 60,120, 84,255,254,253,137,143,143, 15,248,124, 62, 12, 6,131,107,124,124,124,171,223,126,251,109, - 10,159,207,255,213,104, 52, 78, 52,181, 93, 31, 33,132, 17,137, 68,187,214,174, 93,219, 34, 60, 60, 28,155, 55,111,198,141, 27, - 55,216,176,176, 48,102,224,192,129,112,119,119, 15, 31, 56,112,224, 62, 66, 72,167,154, 68,178, 8, 33,238, 3, 6, 12,112,227, -241,120,104,210,164,137,240,202,149, 43, 13, 1, 92,121,199,107,106,230,234,234,122, 62, 50, 50, 50,248,212,169, 83,209,132,144, -200,234,180, 99,116,118,118,238,230,224,224,176, 80,161, 80, 88,153,186, 79, 73, 73,137, 50, 51, 51,115, 82,106,106,170, 73,243, -145, 82, 74, 27, 7, 5, 5, 33, 53, 53, 21, 94, 94, 94, 16, 10,133, 17, 46, 46, 46,195, 41,165, 29, 88,150,253,166, 58, 77, 12, - 8, 33,206, 17, 17, 17,182,145,145,145,228,251,239,191, 7, 0, 8, 4, 2, 24,141, 70, 48, 12, 3,129, 64, 0, 63, 63, 63,242, -236,217, 51,107, 66,136,179, 41,213,133,182, 94,173,186, 52,105,211,161, 89,139,240,250,204, 79,123,158,192,200, 26,193, 35, 6, -240, 9, 11, 86, 47,134, 88,200,131, 79, 96, 40,239, 81,204,221,112,219,186, 31,116,201,137, 59,121,208, 20,205, 14, 93,186, 54, -247,247,245, 97,150,237,123,138,130,212,135,198,212,216, 11, 57, 12,143,129,127, 72,107, 91,159,128, 96, 94,112,120,164, 32, 45, - 33,166,149,181,119,203,182,121, 79,206,115,166,130,163,250, 6,139, 16, 66, 41,165, 47,190,172,102,172,166, 51,108,173,136,199, -131,251,119,153,228, 12,109,233,221,187,119, 97, 99, 99, 3,123,123,123,152,155,155,227,209,163, 71, 56,117,234, 20,226,226,226, - 64, 41, 69,112,112,112,181, 14,156,153,145,129,220,188,226,119,214, 60, 26, 79, 49,119,100, 89,178,107, 57, 57,161,150,147, 19, - 63, 39,191, 0, 87,239,222,243, 63,248,107, 91,223, 76,102,248, 70,149, 74,245, 98,123,189,254,159, 87,235,226,224,224, 96,248, -226,139, 47,243,134,173, 74,168,211,175,181, 51,175, 91,132, 35,246, 93, 73,231,237, 60,199,163, 51, 62,175,159,253,228,201, 99, -147, 79, 90, 36, 18,125,215,177, 99,199,175, 40,165,130,177, 99,199, 2, 0, 6, 13, 26, 84,116,237,218, 53, 31, 74,105, 22, 33, -196,249,243,207, 63,127,124,246,236, 89,217,248,241,227,121, 6,131,225, 1,159,207,167,132,144, 57,148,210, 89,111,204,100,124, -254,237, 59,119,238,120,192,204, 29,182, 10, 30,218, 79,143, 6, 0,152,137,129,236,140, 20, 92,191,119, 14, 54, 54, 54, 22,205, -155, 55,143,245,246,246,214,164,167,167,143, 45, 45, 45,221, 84,105,198,229,243, 99,162,162,162, 92, 93, 93, 93,203, 12, 86,142, - 10, 27,175, 50, 80,106,164, 0,164, 32,172, 28,230,246, 30, 10, 31, 93,209, 29, 59, 59, 59,157, 86,171,157, 90, 84, 84, 84,105, - 85, 15,143,199,203,186,127,255,190,194,205,205, 13, 0,244,251,246,237,227,107,181, 90, 80, 74,141,135, 15, 31,238,144,156,156, - 28,236,233,233,201,184,186,186, 78,245,246,246, 86,165,166,166, 14, 85,169, 84,111,173, 66, 57, 54,198, 75,215,114,214,185, 85, - 5, 9,201,191, 1,128, 75,184,127,222,161, 89, 13,181, 45,103,149, 84,185,238,216, 24, 47, 29, 70,255,101,237, 4, 7,127,253, -245,215,254,214,214,214, 24, 49, 98, 4,102,207,158,141, 25, 51,102,120,143, 24, 49, 98, 24,128, 37,213,120,201, 74, 29, 29, 29, -111, 46, 91,182,204,175,105,211,166, 56,114,228, 8,118,236,216,129,103,207,158, 25, 60, 61, 61,249,225,225,225,152, 57,115, 38, -218,183,111, 63,116,244,232,209, 45, 9, 33, 13, 77, 52, 29,159,205,156, 57,179, 91,179,102,205,240,233,167,159,106,206,157, 59, -215, 7,192,137,147, 39, 79,182, 62,127,254,252,158,109,219,182, 73,231,207,159,223,118,194,132, 9, 35, 0,172,168,193,249,119, -111,209,162, 5, 0,160, 89,179,102, 88,184,112, 97,251,119, 49, 88,132, 16,145,141,141,205,225,205,155, 55, 7,215,173, 91, 23, -159,124,242, 73,195, 62,125,250, 28, 38,132,124, 64, 41, 53,105,222, 72, 39, 39,167, 31,214,174, 93,235, 37,149, 74, 77, 62,174, - 86,171,181, 30, 62,124,248,247, 0, 76, 50, 88, 44,203, 54, 14, 10, 10,194,190,125,251, 48,124,248,112,248,251,251,215, 15, 14, - 14, 94, 51, 96,192, 0,140, 24, 49,162,141,157,157,157, 67,249,228,226, 85,191, 88,248,124,207,206,157, 59, 11,254,248,227, 15, - 0, 64,139, 22, 45,208,182,109, 91,220,191,127, 31,151, 46, 93, 2,143,199,131, 92, 46, 71,211,166, 77, 69,105,105,105,158, 0, -170, 52, 88,140, 88, 54,184, 91,231, 78,138, 3,215,210, 97,100, 13, 8,245, 50, 71,184,159, 61, 30,165, 20, 33,234, 97, 10,140, - 90, 33,204,173,109, 16,209,178,157,117, 70,234,179,193, 48,165,121,128, 88, 54,184,103,183, 15,205, 14, 92, 77, 67, 65, 90, 44, -125,114, 99,239, 25,189,186,116, 40, 0,220, 58,189,115,141,163,141,244, 3,159,144, 80, 94,228, 7, 93,173,254,216,145, 49, 24, - 0,103,176, 56,222, 45,130, 85, 65,110, 1, 84, 54,142,254, 72,206,184, 93,246,255,220, 92,228,230,230,162,118,237,218, 88,190, -124,249, 43,219,170,213,234, 26, 37,224,191,161,105,107,101,137,174,173, 90,242,238, 63, 90,205, 83,177,170,247,162,249,119,165, -124,210, 82, 38, 41, 71,111,153, 93,168, 19,246,109,229, 70, 5, 60, 6,253, 90,213, 34, 63, 31, 76, 18,102,149, 10, 44, 25,134, - 73, 98,217,170, 59, 18, 18, 66, 4,221,186,117,251,106,215,174, 93,130,216,216, 88,212,169, 83, 7, 58,157, 14,215,174, 93, 75, -161,148,102,149, 31, 47,141,199,227,165,177, 44,235,221,160, 65, 3, 44, 88,176, 0,126,126,126,164, 83,167, 78, 83,202, 77,214, -159, 14,148,150,150, 54,255,203, 47,191,108,241,203,198,157, 54,159, 52, 38, 40, 46,214, 64,169, 84,226,209,253,155, 40,205, 44, -197,154, 53,107, 33,147,201, 8, 0, 97, 70, 70,134,112,194,132,241,235, 92, 93, 93, 59,167,164,164,244,124, 91, 90,211,210,210, -230,141, 30, 61, 58,124,203,150, 45, 86,101,237,174, 84, 40, 86,137,113,125,113, 89,132, 50,124,194, 13,252,250,203, 58,166,158, -135,220,166,184,184, 24, 67,135, 14, 93,230,228,228,212, 52, 61, 61,125,248,219, 52,211,211,211, 47, 14, 29, 58,212,229,183,223, -126,147,120,123,123,199, 21, 22, 22, 34, 47, 47,143,217,182,109,219,104, 39, 39, 39,139,125,251,246, 19,185, 92, 14, 0,188,196, -196, 68,225,151, 95,126,177,203,209,209,113, 91, 70, 70,198,167,111,187, 55, 0, 52,132, 32,221,217,185,182,151,242, 42, 51,203, -217, 89,125,233,220,204,212, 45,132, 32,189,108, 27, 80,167,181, 78, 3,158,111, 22, 55,211,104,216,165, 25, 25, 73,113,148,130, - 98,230, 95,215, 9,195,214,214,118,116,183,110,221,240,253,247,223,227,224,193,131, 19,172,173,173, 23,207,158, 61, 27,206,206, -206, 95, 18, 66,150, 86, 99,178,219, 31,151, 44, 89,226,231,231,231,135, 65,131, 6,105, 79,157, 58,245, 53,128,125, 0,146, 46, - 94,188, 88,107,211,166, 77, 93,118,237,218,245,253,178,101,203, 36, 43, 86,172,240,250,232,163,143,150, 2,248,220,132, 15,138, -241,253,251,247,199,162, 69,139,112,238,220,185,143, 40,165, 71, 42,190,183, 8, 33, 93,230,207,159,127,122,250,244,233, 88,178, -100,201,216,234, 26, 44, 66,136,153,191,191,255,183, 29, 58,116,192,197,139, 23,209,188,121,115, 68, 68, 68, 76, 32,132, 44,167, -148,230,212,192, 92, 49,102,102,102,187, 54,110,220,216,220,195,195, 3,243,230,205,195, 87, 95,125,133,245,235,215, 55,255,228, -147, 79,118, 17, 66,122,154,210,203,215,204,204,204, 76, 42,149,226,251,239,191,167,207,159, 63,207, 55,193,144, 89,125,251,237, -183,196,162,170,170,133,255, 68,200,164, 98,177,184,137,175,175, 47,126,250,233, 39, 92,188,120, 17, 99,198,140,129,175,175, 47, - 82, 82, 82,208,181,107, 87,217,227,199,143,123, 1,216,104, 98,185,100, 97, 99, 99,131,172,172, 44, 8, 4, 2, 52,109,218, 20, -251,246,237,131, 70,163,129,189,189, 61, 10, 10, 10, 94,212, 38,240,249,124, 11, 19, 75,187, 32, 91,107, 11,100,197,164,130, 15, - 3, 66,124,108,113,246,126, 46,116,122, 22,246, 54,150,200,200,202, 68,227, 32, 87,104,181,181, 64, 41,107,210, 76, 32, 34, 30, - 19, 34,150, 72,145, 87,156,131,212,135,231,114,117, 70,205,240,130,103,151,146, 1,192,186, 78,139,225,183, 46,157,188,213,251, -195, 22,246, 37,165,110, 32,148,109, 4, 14,142,106, 80,229, 64,163,111,122, 49,191, 28, 17,170, 64,167,211,189, 83, 66,254, 27, -154,111,226,191,161,249, 55, 48, 89,172,139, 21,191, 80, 46, 97, 12, 39,163,178,140,122,131, 17,199,111,101, 24,101, 98, 98,176, - 18,107,139, 88,150,165,132, 16,106,130,142,254,248,241,227,155,199,140, 25,131,197,139, 23,227,241,227,199, 16, 10,133, 8, 10, - 10,114,170,104, 31, 69, 8,177, 8, 9, 9,177,103, 24, 6,143, 30, 61,194, 79, 63,253,132,207, 62,251,140, 94,185,114,101,253, -219, 94, 20,148,210,219,233,233,233,107, 39,141, 29, 94,192, 40,147, 33,167, 57,208,229, 61, 6,171,202,198,215, 51,231, 35, 33, -151, 69,244,179, 98, 68, 63, 43, 70,142, 86,142,159,126,222,192, 11, 12, 12,236, 34, 16, 8,218, 87,146,214,107,233,233,233,155, -199,143, 31, 95,144,149,149,245,194, 56,235, 12, 44,116,134, 87,147,161, 80, 40,176,102,205, 26, 75, 55, 55,183, 94, 2,129,160, - 85, 37,154,169,105,105,105,247, 70,141, 26,165, 73, 79, 79, 71, 97, 97, 33, 78,156, 56,241,129,171,171,171,197,172,249, 75, 72, - 66, 46,125,145,206, 18, 98,131, 13,219,254,224,249,248,248,124, 44, 16, 8, 34, 42,127,121,185,120,249,251,215,217,125,237,218, -181, 79,189,188,188, 70, 85, 24, 43, 74, 65, 1,192,211,211,115, 68, 84, 84,212,103,193,193, 1,187, 29, 28, 28,125,255,202,188, - 68, 8,105,213,183,111, 95, 95,150,101,177,123,247,238,123,148,210, 37,123,247,238,189,169,209,104,208,175, 95, 63, 79, 0, 29, - 76,212, 9,251,248,227,143, 71, 53,111,222, 28,227,198,141,211,157, 58,117, 42,132, 82,186,152, 82,154, 72,203, 72,162,148, 46, - 63,127,254,124,131,209,163, 71,107, 26, 53,106,132, 79, 63,253,244, 51, 66, 72,243, 42,116,155,244,239,223,223,143,101, 89,236, -220,185,243,238, 75,230,170,226, 30,158,217,179,103,207, 53,173, 86,139, 1, 3, 6,212, 38,132,180,174,198,185, 11,197, 98,241, -238,185,115,231, 90,166,166,166, 98,224,192,129,154, 71,143, 30, 97,214,172, 89, 82, 11, 11,139, 35,149,181, 17,124,107,128, 68, - 44,254,101,245,234,213,221,234,213,171,135,145, 35, 71,106, 87,173, 90, 53,102,212,168, 81,218,144,144, 16,172, 92,185,178,155, - 72, 36,250,165, 90,145,255,204,204,130,115,231,206,217, 84,181,100,100,100,100,154, 24,253,150,121,123,123, 95,245,241,241, 41, -242,247,247, 15, 53, 24, 12,120,252,248,241,211,223,127,255,157,245,245,245,197,166, 77,155,176,102,205, 26,180,105,211, 6, 12, -195,244,170, 78, 90, 75, 75, 75, 33,145, 72, 32, 20, 10, 17, 21, 21, 5,141, 70, 3,153, 76, 6,137, 68, 2, 30,143, 7, 75, 75, - 75, 40, 20, 10, 0,160,166,221, 31,208, 34,165, 30, 2, 1, 3, 62,195, 34, 54,169, 16, 58, 61, 11,137,144, 7, 1,159, 0,148, -133,165, 92, 0,137,136, 7,134, 16,214, 68, 77, 20,150,234, 32, 18, 50, 16, 8, 69,132, 49, 24, 95,132, 8, 25,190, 81, 42,149, -138,136,173,185, 24, 18, 33, 55, 38, 55,199,123,142, 96, 1,128,209,248,231, 94,186,111,138, 2,105,181,218,119, 74,200,127, 67, -243, 45, 97,243,127,212, 13, 44, 42, 42,226, 95,189,122, 85, 33, 20, 10,197,221,130,195,115, 22,254,246,216,110,246,182, 56,136, -249, 32, 29, 3,105,230,209, 35, 7, 69,197,197,197,182,190,190,190,185, 38,222,135,161,132,144,121, 0, 2,248,124,254,161,141, - 27, 55,146,173, 91,183, 90,245,239,223, 63,158, 16,146, 26, 24, 24,232,190,113,227, 70,115, 0, 88,190,124, 57,221,181,107, 87, -123, 0, 49,148,210,140,202,116,211,211,211,167,139,197,226, 43,143, 30, 61, 90, 46, 16, 8, 44,205,205,205,173,206,159, 63, 79, - 50, 11,117,248,118,203,179, 23, 61, 11,229, 98, 30,166,245,180,199,224,193,159,241, 31, 60,120,240, 35,128,227,111,211, 76, 77, - 77,157, 32,147,201,206,223,187,119,111,137,194,165,190,181,109,196, 4,243,214,211,202,170, 31, 29,173, 68, 96,202,203,196,130, -130, 2,228,228,228, 96,194,132, 9,150, 19, 39, 78,156, 12,224,108, 37,233, 60, 33, 22,139,147, 98, 98, 98,218,241,249,124,177, -153,153, 89,240,213,171, 87,201,243, 2, 61,166,109,122,138, 98,117, 89,109,171, 66, 34,192,236,254,174, 24, 61,122, 52, 63, 62, - 62,254, 7, 0,205,222,164,231,226,226,226,237,239,239,191,123,251,246,237,254, 75,151, 46,205,123,242,228, 73,169,179,179,243, -236,215, 54,211, 44, 88,176, 32,119,203,150, 45,117, 7, 14, 28,184,219,209,209,177,207, 59, 12,169,241, 78,152,155,155,127, 63, -124,248,112,236,218,181, 11,249,249,249, 75,203,243,216,146,237,219,183,239, 28, 58,116, 40,182,108,217,242, 61, 33,228,152, 9, - 81,172,142,253,250,245,195,209,163, 71,113,250,244,233,111, 41,165, 15,222, 98,106, 31, 19, 66,166,236,223,191,127, 89,255,254, -253,177, 97,195,134, 14, 0, 42, 27,120,246,131,246,237,219,227,200,145, 35,200,205,205, 93,249,166, 13, 10, 10, 10, 86, 29, 56, -112,160,113,251,246,237,177, 96,193,130, 15, 0,156, 49,193, 92,249, 89, 88, 88,108, 92,182,108, 89, 88,189,122,245,240,241,199, - 31,171,117, 58, 93,135,175,190,250,234,224,142, 29, 59, 20,155, 55,111, 14, 29, 54,108,216,117, 66,200, 16, 83, 7,177,229,241, -120,243, 87,172, 88,241,121,100,100, 36, 38, 76,152, 96, 56,126,252,120, 87, 74,233, 9, 66, 72,252,228,201,147, 15,255,244,211, - 79,188, 69,139, 22,125,206,227,241,178,141, 70,227,215,127,201, 23, 54,195,204,157, 51,103, 78,227, 22, 45, 90, 32, 41, 41, 9, -209,209,209, 48, 24, 12, 91,110,221,186,117,161, 69,139, 22,115,117, 58,221, 65,137, 68, 50,200,204,204, 44, 48, 48, 48,176,181, -131,131,131, 44, 51, 51, 83,105,194,245, 44,136,143,143,151,219,219,219, 67, 32, 16,224,238,221,187,176,183, 47,155,242, 53, 43, - 43, 11, 65, 65, 65,224,241,120, 40, 40, 40, 0,128, 66,211,204, 16,115, 47, 62, 49,173,182,181, 66, 14, 24, 37,184,253, 40, 5, -118,182, 86, 48, 18, 6, 25, 25,233, 8,246,117, 5, 33, 4, 5,185, 25, 32,132,152, 52,151,174,145,178, 81,207,211,178, 92,108, - 20, 98,212,107,220,206,230,234,177,236,173, 22,117,154, 13,227,243, 8, 79, 44, 49, 95,251,249,167,159,218,178, 44, 69, 65,110, - 38,248, 12,115,131,179, 12, 28,239,213, 96,177, 44, 11,169, 84,250, 74,132,233,245, 40,144, 84, 42,133, 70,163,169,214,129,165, - 82, 41,116, 6,188, 87, 77, 83,142,249,190, 53,255, 74, 12, 6,131, 98,226,196,137,225,225,225,225,169,109,218,180, 73,168, 91, -215, 58,185,115, 99,169,237,178,245,123,131, 59,181,172, 23, 93,144,151,149,243,204,220, 92,147,152,152,104,255,235,175,191,134, -235,245,122,153,137, 17,177,231, 0,158, 19, 66, 86,117,232,208,225,139,222,189,123,227,193,131, 7,246, 74,165,210, 94, 38, 43, -147,216,186,117, 43,118,237,218,181,152, 82,106,242,192,155, 26,141,230, 24, 0, 47, 66,136,101,173, 90,181, 50,173,173,173,133, -233, 37,165, 47,122, 22, 10,249, 12,154,126,117, 19,249, 5, 69,176,181,181,133, 66,161,240,172, 74,179,124,156,171,131,222, 31, - 76,174,175,186,183,246,220,166,141, 27, 45, 0,128,199, 16,216, 89, 8, 81, 80, 80,128,236,236,108,228,228,228,128, 97, 24, 24, - 12, 6,127, 19,210,249, 24,192, 99, 66,136,115,235,214,173,231, 42, 20, 10,176,121,165,200, 47,209,189, 82, 5, 89, 82,162,132, -135,135, 7, 20, 10,197, 27,171, 35,172,173,173, 21, 98,177,120,211,186,117,235,252, 20, 10, 5,111,232,208,161,150, 67,135, 14, -109,246, 54, 51, 38,147,201,120, 27, 54,108,240, 9, 14, 14,222,232,225,225,241, 65, 98, 98, 98,225,255, 42, 47,149, 15,121, 48, - 98,210,164, 73,161, 18,137, 4, 63,255,252,243, 51, 0,219,202,127,222,189,106,213,170, 25,253,251,247,247, 29, 51,102, 76,224, -244,233,211, 39,148, 87, 21,190,117,140, 36,161, 80, 24,226,239,239,143,189,123,247, 2,192,222, 42, 14,191,231,202,149, 43,203, - 58,119,238, 12,137, 68, 18, 86,197,182,158,110,110,110,216,191,127, 63, 0,220,126,203, 54,183, 31, 61,122,132,158, 61,123,130, - 16,226,105,194,185,119,107,215,174,221,158, 5, 11, 22,240, 21, 10, 5, 62,255,252,115,237,245,235,215, 59, 81, 74, 47, 16, 66, - 90, 13, 24, 48,224,252,182,109,219,228,231,207,159,247,251,238,187,239,174,240,120,188,249, 70,163,113,122, 21,154,159,205,155, - 55,111, 90,247,238,221, 49,123,246,108,250,219,111,191,125, 76, 41, 61, 81,254,124, 29, 39,132, 12,180,178,178,218,246,205, 55, -223,144,194,194,194,105,132,144, 20, 74,233,234, 74,242,121,161,209,104,116, 84, 42,149, 38,125, 33,154,186,189,141,141, 77,199, - 22, 45, 90,224,199, 31,127,196,152, 49, 99,176,105,211, 38, 10,224, 80,122,122,250, 93, 0, 45,202, 34,176,206,138,168,168,168, -192,230,205,155, 11,239,221,187,247, 33,128,223, 76, 40,155, 18,207,158, 61,107,223,169, 83, 39,161, 76, 38,131,209,104, 68,110, -110, 46,212,106, 53,130,130,130,208,184,113, 99,100,101,101,225,208,161, 67,186,130,130,130, 68,147,202, 59,109,233,230,147,135, -255,104,213,165,223,112, 11,169,144, 7,163, 94,132,204,204,108, 20, 27, 13, 8,241,119, 71,243,224, 90, 72,202, 84,225,248,161, - 63,242,139,139,149,155, 77,209,212,107,148, 27, 79, 29, 59,216,178,121,199, 1, 22,114,223, 64,120, 58,141, 9,190,117,229,212, - 73,137, 72, 64, 6,244,239, 99,217,180,161, 55,238, 62, 43,194,209, 67,123,243, 11,139,138, 54,130,131,163, 38, 6,235,229, 6, -238, 47,145, 53, 97,194, 4,251,137, 19, 39,194,220,220, 28,185,185,185,208,235,245, 47,162, 77, 98,177, 24,150,150,150,200,205, -205,197,206,157, 59, 1, 32,171,242, 47, 58, 81,250,188,149, 43,220, 8, 79,174, 21, 75,101,212, 90,246,238,154, 0,160,213,243, -179, 86,239,252,221,186, 99,139, 8,126, 45, 39,167, 55,133,233,171,173,249,255, 1,157, 78,119, 34, 33, 33, 33,172, 95,191,126, -217,110,110,110, 42,181, 90, 13,149, 74, 85,124,104,199,178, 58, 46,230, 35,159, 49, 12, 67, 21, 10, 5,107,111,111, 95,120,250, -244,105,123,131,193,112,174,154,135,152,208,167, 79, 31,230,212,169, 83, 35, 70,141, 26, 69,188,189,189, 17, 21, 21,133,159,127, -254,153,110,222,188,121, 25,128,169, 53, 76,122,137, 70,163,121, 37, 2,242,114,207,194,146,146, 18,104, 85,153,208, 87,163, 71, - 66,252,169, 31, 31,213,174, 93, 91, 31,232,254,159,225, 68,242,243,243,145,157,147,243,194, 96,101,103,103, 3, 64,117, 66,152, - 69,127, 78,231,127,106, 30, 74, 75, 75,161, 86,102,192,104, 52,190, 81, 51, 47, 47,175,216,217,217,121,197,242,229,203,127,154, - 59,119,174,253,146, 37, 75,242, 98, 99, 99,139, 24,134, 81,191,246, 17, 35,241,242,242, 82, 44, 90,180,200, 97,249,242,229,121, - 44,203,174,248, 31,155,171,238,245,234,213,219,212,177, 99, 71,197,168, 81,163,176,124,249,114,164,167,167, 79,165,148, 26,202, -203, 6,150, 16, 50,121,229,202,149,135,166, 76,153, 2,157, 78,183,232,200,145, 35,179, 9, 33, 35, 40,165,219,222,164,105,103, -103,231,202,231,243, 17, 29, 29, 93, 68, 41,125, 90,133,161,207,168, 91,183,110, 38, 33,196,193,201,201,169, 78,101,219, 90, 91, - 91,123, 41, 20, 10,164,166,166, 2, 64,194, 91, 54, 75, 76, 75, 75,163, 34,145,136, 56, 59, 59,123, 87,117,254, 86, 86, 86,147, -215,173, 91,199, 63,123,246, 44,102,206,156,153,146,148,148, 52,128, 82,122,177, 60,109,209,132,144,230,173, 90,181,218, 49,101, -202,148,186, 63,252,240, 3,121,244,232,209, 72,188,101,136,146, 10,220,221,221, 71,124,246,217,103, 88,177, 98, 5,214,174, 93, - 59,146, 82,186,251,181,115,222, 65, 8,177,178,177,177, 89, 49,124,248,112,108,220,184,113, 0,128,213,149, 68,107,167,244,237, -219,119, 70, 94, 94,222,124, 83,238,169, 41,219,187,184,184,180,106,221,186,181,151, 90,173,198,238,221,187,159,238,217,179, 39, -223,104, 52,238, 44, 55, 87, 47,231,143,125,199,142, 29,155, 49,121,242,100,156, 61,123,118,163,179,179, 51, 47, 45, 45,109, 71, - 21,247, 52, 77, 34,145,228,220,189,123,215,209,207,207,143,113,114,114, 66,163, 70,141, 96,105,105, 9, 30,143,135,172,172, 44, - 92,184,112,129,141,143,143,207, 49,117,192,209,156,184,179, 7, 29,235,117,186, 28,125,253, 66,187,192,134, 77, 5, 46,182,214, -136, 8,116,129,165,153, 16, 4, 64, 82,150, 10,103,206,156,212, 39, 36, 60,189,106, 74, 15,194, 10, 77,231,250, 31, 94,177,180, -175,213, 46, 32,184, 41,191,142,175, 15,218,181,104, 96,101, 37, 23,130,165, 20,119,159, 21,226,228,137, 99,250,180,148,228,179, - 92, 15, 66,142,247, 29,193,154,181,118,237,218,166,235,215,175,239, 60, 97,194, 4,197,160, 65,131, 32,149, 74, 81, 90, 90, 10, - 55, 55, 55, 24, 12, 6, 28, 57,114, 4,209,209,209,197, 44,203, 30, 2,112,249,181, 7, 51,232,229,113,171,166, 45, 87,214, 42, - 27,188,178,180,233,236,181,245,223,139, 38, 0, 92,121,102,112,113, 78,207,153,149,155,127,100,188,187,139,147,176,125,179,198, -124, 91,171,178,222,204, 38,106,182,125,223, 99,122,252, 47, 52, 13, 6,195,231,132,144,192,201,147, 39, 47,116,113,113,113,158, - 61,123,246,243,128,128, 0, 85, 81, 81, 17,213,106,181,108, 78, 78,142,108,247,238,221,158,185,185,185,197,122,189,126, 32,165, -244,110,117,210, 73, 41,213, 1, 24, 69, 8, 57, 80, 88, 88,120,252,171,175,190,194,119,223,125,135,131, 7, 15, 54,167,148, 94, -174,233,185, 83, 74, 13,158,158,158, 5,183,111,223,118, 16,217,248,192,193, 82,136, 14,223,150, 5, 35, 20, 98, 2, 85,105, 49, - 98,239,223, 69, 81, 81,209,173,106,104,106, 93, 92, 92, 10, 51, 51, 51,109, 29, 28, 28,202,204, 85,118,246, 11,115,149,151,151, -135,220,220, 92,250,242,189, 55, 65,179,212,203,203, 75, 25, 27, 27, 43,226,201,220,224,104, 37, 70, 89, 21, 36,133,157,130,143, -210,210, 98, 60,188,118, 21,133,133,133,231,222,166,153,150,150,182,211,217,217, 25, 0,126,154, 49, 99,134,109,135, 14, 29,158, -220,184,113,163,229,203,199, 9, 9, 9,217, 55,123,246,236, 15,191,251,238,187,156, 77,155, 54, 77, 73, 79, 79,223,250,191,204, - 75, 54, 54, 54, 19, 15, 31, 62,172,208,233,116, 88,190,124, 57, 22, 47, 94,188,158, 82,250,251,107,215,226, 48,143,199, 91,201, - 48,204, 23, 95,126,249, 37,134, 15, 31, 46, 11, 13, 13,157,240, 82,148,235, 21,205,212,212,212,233, 33, 33, 33, 51,178,178,178, - 76, 50, 4,143, 31, 63, 30, 22, 18, 18, 50, 61, 43, 43,107, 97,101,231, 46,151,203,229, 70,163, 17, 9, 9, 9,249,148,210,194, -183,220, 55,181,143,143, 79,170,209,104,116,149,201,100,214, 85,229,207,252,252,252,249,161,161,161,179, 50, 51, 51, 79, 0,152, -247,250,144, 35,148,210, 59,132,144,192,177, 99,199,142,254,254,251,239,123,102,100,100,236,172, 74, 51, 41, 41,105,126,171, 86, -173,190,141,139,139,219, 68, 41, 93,251,150,116,254, 76, 8,209,109,221,186,117,100, 66, 66,194,130,202, 52,211,210,210, 14, 1, - 56,100,234,253,125,219,246, 47,107, 50, 12, 51,121,218,180,105,204,182,109,219, 0, 96, 81, 74, 74,202,218,183,152,181,187, 46, - 46, 46,155, 67, 67, 67, 7,173, 94,189, 90,210,166, 77,155,225, 0,118, 84,149, 63, 53, 26,205,181, 43, 87,174, 52, 78, 76, 76, -180,109,213,170,149, 16, 0,138,138,138, 80, 80, 80,128, 67,135, 14,233,226,227,227,115, 74, 75, 75,175, 85,167, 12, 49,104,139, -250, 95, 57,179,127, 71,226,227,251, 17,145, 29,186, 89,105,117,174, 16,231,242, 80,144,155,129, 99,135,254,200, 79, 72,120,122, - 85,169, 44,232, 95, 29, 77,157,166,176,223,213,179, 7,118,166, 36,196, 54,110,209,170,147,149, 90,235, 14,177,144, 65,110,102, - 42,142, 29,222,159,151,144,240,236,162, 90,175,249,244,175, 42,231,255, 77,154,255, 56,104, 69,107,219, 74, 22, 0, 34, 0, 31, - 42, 20,138,229, 51,103,206, 92,123,253,250,245,181,157, 59,119, 94, 43, 18,137,150, 3,248, 16,128,232, 45,251, 5,253, 47, 53, - 59, 52,130,226,179,174,204,134,185, 35,249,186,125, 75,124,245,115, 70,128,154,168,217,214,148,235, 80,157,229,127,173, 9,160, -153, 64, 32,184, 90,175, 94,189,179, 10,133, 34,219,195,195,227,162, 64, 32,184, 1,160,197,187,166, 19,128,109,223,190,125,217, -226,226, 98,218,167, 79, 31, 10,192,226, 93, 53,197, 98,113,235,200,200, 72,253,243,244,124,122,241, 78, 50, 61,116,254, 1,221, -126,240, 42, 93,187,227, 56, 93,178,114, 3,173, 95,191,190, 22,128,123,117, 52, 69, 34, 81,135,200,200,200,130,156,156, 28,250, -232,209, 35,122,225,194, 5,186,103,207, 30,186,118,237, 90,186,106,213, 42,234,236,236,156, 11,192,185, 58,154, 82,169,180, 91, -135, 14, 29, 12,169,217, 37,244,218,131, 12,122,234,250, 83,186,239,244, 93,186,243,208, 85,186,126,235,239,212,207,207, 79, 13, -192,161, 42, 77, 39, 39,167,190,125,250,244,121, 82,183,110,221, 53,175,255,230,237,237,189,178, 79,159, 62, 73,206,206,206, 3, -255,138,188, 4,160,131,139,139,203, 35,161, 80,120, 24,192,192, 42,246,235,199,231,243, 15, 58, 58, 58,222, 4,208,227,127,157, -231, 1,116,182,183,183,191, 6,160,107, 21,251, 85,108,215,253,159,248,188,191, 15, 77,103,103,231,214,110,110,110, 23,156,157, -157,191,169,106, 63,127,127,127,161,163,163,227, 92, 23, 23,151, 35, 78, 78, 78,109,170,147, 78, 0,206,102,102,102,205,204,204, -204,186,152,153,153,117,177,180,180,108,246,242,115, 88,147,115,183,241,105,219,165, 86,195,174,251,220, 26,124,152, 84, 43,184, -115,146,103, 72,183,125, 54, 62,109,187,188,171,166,123, 72,183,253,181,130, 59, 63,175, 21,220, 37,177,118, 88,183,125,182,190, -109, 59,254,211,238,251,223, 89,243,159,182,152,188, 97,175,178,150, 43,102, 0,250, 49, 12,243, 51,128,126, 0,204,170,184, 1, - 65, 38,220,164,247,174,217,161, 37, 92, 70,245,226, 29,153,250,169, 32,219, 68,205,127, 76,134, 6,208,141,207,231, 95, 1,208, -237,125,166,211,220,220,124, 93,239,222,189,141, 2,129, 96,197,251,210,180,177,177,249, 41, 34, 34, 66,183,108,217, 50,186,119, -239, 94,186,118,237, 90, 58,122,244,104, 26, 20, 20,164,177,182,182,254,180, 38,154,142,142,142,243,234,213,171,151,183,117,235, - 86,186,115,231, 78,186, 98,197, 10, 58,107,214, 44,182, 86,173, 90,217,214,214,214, 93,107,162,105,111,111,255, 75,179,102,205, -116,191,252,242, 11, 61,121,242, 36,221,190,125, 59,157, 56,113, 34,245,247,247, 87,203,229,242,143, 76,213,172, 83,167,142,232, -109,191, 53,108,216, 80,192, 21,184,156, 38,167,201,105,114, 6,235,159,179,240, 77,141,116,237,126, 64,241, 81, 0, 41, 33,192, -206,223, 31,178,123,122,250,195,240,251,131,119, 31,171,167,118,237,218, 37,132,144,157, 79,159, 62,221,227,238,238,110, 72, 76, - 76,124,103,205,163,231,104,106, 59, 79,210,233,100,162,145, 15,192, 96,250,176, 61,255,136,136,228,126, 0,251,223,183,110, 97, - 97,225, 16, 66,200, 24, 74,169,234,125,105,230,228,228, 76, 36,132,108,125,250,244,233, 34,185, 92, 30,108, 52, 26,245,106,181, -250, 82,118,118,246, 4, 74,105,114, 77, 52,211,211,211,167, 19, 66,246, 78,157, 58,117, 42,128,250,132, 16,173, 94,175,191,146, -149,149, 53,135, 82,154, 94, 19,205,204,204,204, 97, 66,161,112, 67,124,124,252, 2,169, 84, 90,159,101, 89,173, 82,169, 60,151, -147,147, 51,158, 82,154,105,170, 78,124,124,252, 91,219,127, 69, 69, 69,113,243, 14,114,112,112,112,252,139,218, 96,189,194,239, - 15, 40,122,214, 35,232, 17, 4,195,239,247,222,143,105,121,250,244, 69,251,215,247, 58, 53,200,137, 4,250,222, 53,185,234,228, -247,103,174, 94,210,188, 11,160,205,123,214,188, 13,160,247,251,212,212,233,116,215, 1, 68,114,185,128,131,131,131,131,227,189, - 27, 44, 0,248,227, 30,229,174, 26, 7, 7, 7, 7, 7, 7, 7, 71, 37, 16, 0, 65,111,137, 2,220, 55, 89,132,144,160,234, 30, -184, 42,253,255,177,166,125, 37,154,167,170,208,108, 91,131,116,114,154,156, 38,167,201,105,114,154,156,230,191, 82,179, 42,237, -127, 76,239,196,255,106, 11,122, 19, 26,164,255, 77, 52,185,134,138,156, 38,167,201,105,114,154,156, 38,167,201, 53,114,127,111, - 11, 55,193, 18, 7, 7, 7, 7, 7, 7, 7,199,123,134, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224, -224,224,224, 12, 22, 7, 7, 7, 7, 7, 7, 7, 7,103,176,222, 35,246,255, 79, 52, 57, 56, 56, 56, 56, 56, 56, 56,222, 27,228, -223, 52,202, 57, 7, 7, 7, 7, 7, 7, 7,199,255, 2,174,138,144,131,131,131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, - 28, 28, 28,156,193,226,224,224,224,224,224,224,224,224, 12, 22, 7, 7, 7, 7, 7, 7, 7, 7, 7,103,176, 56, 56, 56, 56, 56, - 56, 56, 56, 56,131,197,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,142,191,222, 96, 17, 66,218,114, -154,156, 38,167,201,105,114,154,156, 38,167,201,105,114, 6,139,131,131,131,131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, - 28, 28, 28,156,193,226,224,224,224,224,224,224,224,224, 12, 22, 7, 7, 7, 7, 7, 7, 7, 7, 7,103,176, 56, 56, 56, 56, 56, - 56, 56, 56,254, 34, 8,128, 55,246, 4,160,148,158, 50, 89,164, 6,189, 9,170,210,231, 52, 57, 77, 78,147,211,228, 52, 57, 77, - 78,243,159,167, 89,149,118,117,252,199,223, 26, 74,233,127,109, 1,208,150,211,228, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78, -243,223,182,240,185, 32, 30, 7,199,255,115,246, 16, 30,242,125, 61, 65,169, 51,120,162,116,164,223,123,138,153,148,125,103,205, -204, 0,119, 72,245, 14, 48, 72,178,145,121,247,217, 59,107,114,112,112,112,252,139,224, 12, 22, 7,199,255,119,178,253,234,130, -143, 5, 96,224, 4,170,139,135, 93,192, 2, 0,247,223, 89, 83,200,206,131,145,113, 5,213,197,193,222,247,123, 0, 15,184,139, -205,193,193,193, 97, 26,127, 73, 35,247,176,176,176,168,176,176,176,185,145,145,145, 98,238, 22,112,252,183,136,140,140, 20,135, -133,133,205, 13, 15, 15,143,250,199,158,228,214,122, 50, 48,198,142, 90, 61,235,114,236, 94,129,189, 82, 99,172, 11,198,208, 9, - 27,234,154,189,147, 38,159,180, 83,235,216, 90,219,110, 40, 29, 74,181, 6,127, 80,188,155,102, 57, 65, 65, 65,150,141, 26, 53, - 58, 22, 28, 28,108,203,229, 80, 14, 14, 14,206, 96,189,103, 88,150,109,104,111,111, 63, 65,165, 82, 37,133,134,134,118,253, 55, - 93,240,198,141, 27, 95,137,136,136,200,108,210,164, 73,102,147, 38, 77,162,171, 90,255, 79,196,217,217,185,110,189,122,245,146, - 2, 3, 3,227, 94, 94,111,223,160,103, 19,255, 22,131,102,218, 6,118,111,249,174,199, 8, 13, 13,237,170, 86,171,147,106,213, -170, 53,222, 96, 48, 52,252,199, 94, 76, 53,235, 0,134,215, 42, 38, 93, 41, 75, 47,210, 59, 68, 37, 42, 21, 0, 47, 18, 90, 56, -213, 88,179,144,117, 0,104,235, 59, 41, 42,249,149, 60, 59,135,139, 79, 53,230, 96,152, 86, 80, 19,199,119, 77,174, 72, 36, 26, - 73, 41,253, 64, 32, 16,140,227,138,223,127, 55,132,144, 32, 66, 72, 87, 66, 72,216,123,212,252,193,207,207, 47,149, 16, 50,150, -187,194, 28,255,111, 12, 86,239,218,164,233,199,117,200,249,190,181, 73,113,191, 58,164,100, 96, 29,114,169, 87,109,210,186,166, - 7,254,253,247,223,165, 91,182,108,177, 15, 8, 8,216, 25, 30, 30,126, 41, 52, 52,212,167, 38, 58, 97, 97, 97,199,194,194,194, -122,191,190, 46, 52, 52,180,239,203,235, 26, 53,106, 20,211,168, 81,163,194,176,176,176,167,166,232,134,132,132, 60, 9, 13, 13, - 45, 13, 11, 11,123,242,218,139,187,111,163, 70,141,142,189,118,188,222,175,175,123, 27, 60, 30,207,245,224,193,131,246,135, 15, - 31,182,231,243,249, 14, 47,110, 4,195,188,113,125, 13,174,199,208,176,176,176, 43,175,157,203,144,215,215, 85, 97, 78,174,132, -132,132, 12,121, 77,247, 74, 88, 88,216,208,247, 97,174, 90,180,104,113,233,246,237,219,181, 20, 10,133,229,203,191, 57,218, 88, -182,191,114,104,229,132, 79,123,183, 27,105, 31,208,163, 94, 13,141,149, 79,227,198,141, 47,121,121,121,237, 92,176, 96,129,253, -204,153, 51,101,255,216,167,119, 79,128, 16,132,109,193, 82,106,247, 48, 85,109,247, 97,215,222,252,219,201, 42, 59,189,209,104, - 13,240, 34,177,201, 67, 92, 35, 77,190,190, 57, 75,169,195,233, 68,129, 93,171, 62,163,121,103, 18,249,118,122,163,209, 6, 12, - 90,214, 72,243, 63,249, 80,192,227,241, 38, 12, 31, 62,156, 33,132,124,233,229,229, 37,250, 55, 21,182,225, 46,196,165,141, 55, -255, 70,136, 51,105,250, 30, 13, 69,160, 92, 46,191, 69, 8,169,251,255,204, 92, 53, 4, 32,163,148, 30, 0,224, 64, 8,225,191, - 7,205, 37,115,230,204,153, 28, 19, 19,227, 92,187,118,237,217,132, 16, 30,247,138,231,248,219, 27,172,126,181,201, 44, 7, 71, -151, 19,223, 44,217,222, 98,221,249,103,102,171, 14,221,150,143,159, 50,191,169,163,141,221,193, 1,117,200, 15,111,219,175,178, -174,150, 34,145, 8,207,158, 61,195,242,229,203, 37,179,102,205,106, 98, 97, 97,113, 55, 60, 60,124,105, 64, 64,128,188,178,180, -188,174, 73, 41,109, 42, 16, 8,214,133,135,135,111,172, 40,176, 9, 33, 77,197, 98,241, 47,225,225,225, 91, 43,170, 33, 67, 66, - 66,106,223,184,113,195,156, 16,226, 96, 74, 58, 27, 53,106,228,116,235,214, 45, 25, 80, 22, 9,136,140,140, 20, 55,106,212,104, -139,139,139,203, 90, 0, 77, 1,192,203,203, 75, 20, 30, 30,190,209,205,205,237, 87, 66, 94, 45, 52,223,118,238,132, 16, 88, 90, - 90, 98,251,246,237,224,241,120,127, 90,191,117,235, 86, 16, 66,170,125, 61, 3, 2, 2,228, 97, 97, 97,191, 59, 57, 57, 45,101, - 89, 54, 2, 0,234,213,171, 39,107,212,168,209, 30, 87, 87,215,101, 21,235, 76,209,164,148, 70, 8,133,194,165,141, 26, 53,218, - 83,175, 94, 61, 25, 0,176, 44, 27,193,231,243,151,132,133,133,253, 94,157,123,212,176, 97,195,225,245,235,215, 79,171, 95,191, -126,154,175,175,239,119, 14, 14, 14,231, 86,172, 88, 97,243,242,185, 87, 68,174, 50,179,114,243,175,220,140,121, 52, 97,120,175, -200, 90,110, 14, 3, 44, 27,116,183, 48,229,220, 43,206, 63, 60, 60,124,169,133,133,197,221,105,211,166, 69,204,155, 55, 79,162, -211,233, 32, 20, 10, 81,147,252, 89, 83,254,167,154, 57,196, 30,148,182,125,148,161,146,120,248,135,202,237, 67, 63,130,189,185, - 64,124,245,105,169, 2, 4,109,160,147,217,213, 72,147,240,219,196,164,170,164, 86,129,157,100, 97, 17, 45,192,216,248,136,207, -197,149,154,131, 97,106,166,249, 31,122, 69, 68, 68,136,218,182,109, 11,103,103,103,158,133,133,197,128,191,213,245,252, 47,106, -134,187, 16, 23,133,153,232,250, 79, 51,199,135, 58, 91,203,246,155, 98,178, 76,232, 62, 31,104,111,111,127,118,229,202,149, 33, - 10,133,226,130, 41, 38,235,239,112, 61,203,205,149,144, 82,122,173,124,213, 3, 0,205,223, 81,115,201,172, 89,179,198, 77,155, - 54, 13, 69, 69, 69, 24, 60,120,176, 57,128,159, 76,213, 84, 40, 20,222,245,235,215,223, 26, 24, 24,248, 60, 56, 56, 88, 27, 16, - 16,160,246,245,245, 77, 12, 10, 10,218, 36,145, 72, 60,255,233,249,243,239,162,249,175, 51, 88,125,234,144, 38,182,142, 46,147, -127,216,119, 83,106,124,112, 11,183, 62,109,137,216, 47, 58, 65, 26, 23,133,105, 99,190,150,154,155, 91,125,217,187, 14,105, 85, -147,131,199,197,197, 97,215,174, 93,176,181,181, 37, 27, 54,108, 16,247,238,221,123,164,185,185,121,114, 88, 88,216, 0, 83, 53, -120, 60,158,113,227,198,141,102,221,186,117,235,103,109,109, 29, 19, 18, 18, 82,155, 97, 24,227,230,205,155,205,250,246,237,219, - 91,171,213, 62, 12, 13, 13,245,137,142,142, 54,222,188,121, 19, 12, 99, 90,208, 46, 42, 42,202,112,244,232,209, 23, 81, 17, 74, -233,195,239,191,255,190,223,222,189,123, 21, 22, 22, 22,108, 72, 72, 72,109, 55, 55,183,152, 31,126,248, 97,192,158, 61,123, 20, -230,230,230,172,137, 5, 1,212,106, 53,164, 82,233, 43, 70,138, 16, 2,149, 74, 5,137, 68,242,138,241, 50, 49, 50, 16,104, 99, - 99, 19,187, 96,193,130,110,251,246,237,147, 42, 20, 10,132,133,133,249, 91, 90, 90, 62, 90,184,112, 97,247,138,117,166, 34, 20, - 10,177,125,251,118,217,199, 31,127,220, 85, 44, 22,199,134,133,133,249, 11,133, 66,236,216,177, 67, 54, 96,192,128,206, 50,153, -236, 97, 72, 72, 72,160, 41, 90,122,189,126,198,205,155, 55,157,206,159, 63,239,228,238,238, 62,102,213,170, 85, 14, 2,129, 0, - 0, 96, 52, 26, 95,137, 92, 13,232,249, 65,248,184, 25, 43,207,170,212, 26,237,188,169,159, 69, 10,140,104,108, 98,212,110,128, -185,185,121,242,231,159,127, 62,106,251,246,237, 98, 71, 71, 71, 38, 42, 42, 10,197,197,197,213,190,150,255,127,162, 87,132, 7, -190,177, 33, 0,175,168, 68,149,109,131,182,159,240, 17,127, 16,141, 60,205,248,103,227,138,237, 41, 67,221, 1,218, 8,179, 35, -249,213,210, 20,208, 6, 96, 88,159, 19,241,196,182, 73,167, 1,252,164,164, 36,120, 54,136,228, 29,142,131, 3, 37,212, 19, 44, - 66,171,165,249, 18, 2,129, 96,102,159, 62,125,228, 73, 73, 73,104,218,180,169, 76, 36, 18,205,120, 47, 81,188, 53,190,238, 88, -231,219, 18, 27,234, 58,225,124,228,223,174,227, 78,184, 11,113, 49, 55, 19, 93,219,177, 99,151,115,189, 14,195,200,218, 65, 30, -214,118,230,130,253,239, 18,201, 42, 55, 87,103,174, 95,191,110,211,174, 93, 59,204,154, 53,203,206,220,220,252,194,223, 61,146, -245,178,185, 34,132, 72,203,171, 7, 83, 1,184,190,131,230,178, 89,179,102,141,251,230,155,111,112,237,218, 53, 44, 92,184, 16, - 29, 58,116,128,149,149, 85,149,229,199,192,129, 3,101, 77,155, 54,141,234,218,181,235,157,241,227,199, 15, 56,116,232,144,219, -198,141, 27,133,159,126,250,169,184, 79,159, 62,238,227,199,143, 31,212,169, 83,167,251,141, 27, 55,190,222,187,119,111, 73, 53, -147,198, 7, 32, 42, 95, 4,101, 73, 37,132, 16,194, 39,132, 8,184, 8, 27,103,176,192,167,152, 51,108,226, 92, 73,194,166,197, -200,220,245, 51,120, 5,153, 16, 20,231, 66,115,233, 48,244,151, 14, 96, 96, 68,132, 84, 74,200,188,154, 28,220,204,204, 12, 66, -161, 16, 79,158, 60,193,131, 7, 15,208,169, 83, 39,225,138, 21, 43, 44, 3, 3, 3,127,105,218,180,233,157,176,176,176,250,166, - 24, 22,111,111,111,244,235,215, 79, 52,118,236,216, 58, 18,137, 36,154, 82, 42,240,244,244, 68,223,190,125,133, 83,166, 76,241, -144, 72, 36, 55, 89,150, 21,202,100,178,183, 70,135,222,164, 43,149, 74, 1, 64,224,227,227,115,107,231,206,157,158, 77,155, 54, -229,159, 60,121, 18, 69, 69, 69,252,186,117,235,222,217,177, 99,135, 87,147, 38, 77,248,151, 47, 95, 70,105,105, 41, 53, 85, 87, -169, 84, 66, 34,145,252,201, 96, 41,149, 74,136,197, 98,147,211, 88,110, 46,134,122,121,121,221,220,185,115,167,107,243,230,205, -121,231,206,157, 67,113,113, 49,220,221,221,111,237,220,185,211,181,105,211,166,188,171, 87,175,162,184,184,216,100, 77,145, 72, - 4, 15, 15, 15,244,233,211, 71, 48,105,210, 36, 87,129, 64,112, 83, 36, 18,193,221,221, 29,125,250,244, 17, 78,156, 56,209, 85, - 36, 18, 93, 55,177,202,144, 87,110,180,208,167, 79, 31,185, 76, 38, 67,114,114, 50, 88,150, 5,203,150,121,210,244,236,220,123, -151,111,222,143,157, 48,162,119,203, 82,141, 70,115,252,220,173,135, 1, 62,238,174,132, 80,143, 42,206,189,126,120,120,248,157, -200,200,200, 95, 15, 28, 56, 96,249,193, 7, 31, 8,110,222,188,137,231,207,159, 67, 44, 22,195,204,204, 12,124,254, 63,180,163, -108, 81,128, 13, 88,124,144,148,173, 21,139, 45, 93, 21,102, 78,117,129,231, 23, 80,219, 78, 12, 30,195,147,220,124,166,148, 3, -244, 3,212,202,177,169,158, 38,251,193,179, 44,173, 88,111, 29,100,230,236, 90, 11,185,185,185,112,171,227, 7,181,200, 78,116, -229, 73,169, 25, 72, 53, 53,203, 9, 14, 14,110,238,230,230,230,232,225,225,129,156,156, 28,120,123,123,195,204,204,204, 42, 36, - 36,228,131, 26, 95,131, 77, 30, 98, 20,161, 41,192, 44,130,145,204,134,158,191, 0, 79,178, 27,226,151, 16,193,223,206, 92,237, -220,229, 98, 83,203, 31, 56,252, 25, 28, 44,197, 88, 63,178,161,181,157,133,184, 70, 38,139, 16, 18,232,224,224,112,230,250,245, -235,182, 18,137, 4,209,209,209, 8, 8, 8,192,226,197,139,237,172,172,172,254,182, 38,235, 53,115,101, 77, 41, 85, 1, 96, 1, -244, 71, 13,122,189,150,155,149,159,231,206,157, 59,230,235,175,191,198,149, 43, 87,224,234,234,138,236,236,108, 52,111,222, 60, - 41, 63, 63,191,210,247, 82, 96, 96,160,235,227,199,143, 83, 39, 76,152,208,112,235,214,173, 82,153, 76,134,130,130, 2,252,250, -235,175,152, 54,109, 26, 8, 33,160,148, 98,195,134, 13,178,193,131, 7, 55,138,143,143, 79,245,240,240, 48,165,249, 6, 1, 32, - 1, 32, 43, 95,228, 0,100, 59,118,236,176,232,214,173,155,121,249, 58, 41, 0, 41, 33,132,235,232,245,111, 54, 88, 20,168,239, -232,233,139,194,147,187, 33,229, 19, 72,121,229, 11,159,128,121,122, 15,110, 18, 1,244,148, 6,214,228,224,102,102,102, 47, 22, -134, 97,144,158,158, 14,134, 97, 48, 99,198, 12,201,152, 49, 99,234,137, 68,162,171, 45, 90,180, 88, 80,233, 9,148, 71,164,110, -222,188, 9, 31, 31, 31,242,205, 55,223,152, 71, 70,150,125,197,222,187,119, 15, 94, 94, 94,100,254,252,249,138, 46, 93,186, 16, -185, 92,110,114, 4,139, 97, 24, 72,165, 82,180,106,213,138,108,220,184,209, 76, 44, 22,227,240,225,195,200,206,206, 70,187,118, -237,248, 27, 55,110, 52,147, 72, 36,184,112,225, 2, 10, 11, 11, 77,214,173, 42,130, 85,110,234, 76,162, 73,147, 38,235, 29, 29, - 29,151,110,217,178, 69, 44,149, 74,113,238,220, 57, 20, 20, 20,160, 95,191,126,134,109,219,182, 73,204,205,205,113,245,234, 85, - 20, 20, 20,212, 40,115,220,188,121, 19,222,222,222,100,250,244,233,210,136,136, 8, 61, 0,220,190,125,187,226, 58, 75,205,205, -205,151, 52,107,214,108,125,101, 26, 44,203, 34, 61, 61, 29, 49, 49, 49,120,250,244, 41,178,179,179,145,147,147,131,226,226, 98, - 24, 12, 6, 0,128,172,184,232,240,207, 27, 15,222,145, 75,165,178,240,122, 62,181,174, 71, 63,200,146, 75,165, 50, 31,207, 90, -117, 9,153,253,198, 11, 27, 17, 17,177,128,199,227, 93,157, 55,111, 94,253,233,211,167,139, 31, 61,122,132,232,232,232, 63,229, -171,127,164,193, 34,132,128,104,125, 64, 72,195,107, 79, 75,173,155,119,238, 47,196,179, 99, 0,171, 7, 24, 62, 34,235,187,242, -247,223, 43,117, 0, 69,125,104,224, 7,152,224,216, 9, 33,128,206, 27, 32,161, 39, 30, 27,108,154,246, 24, 41, 76, 77, 77,133, - 80, 40,132, 88, 44, 70,195,214, 31,241,119,220,209, 59,130,160, 1,116,240, 53, 73,243, 37,196, 98,241,183,159,125,246,153,252, -101,205,142, 29, 59,202,101, 50,217,204, 26,155,171, 82, 89, 4, 12,116,108, 76,170,210,227,187,195, 25,254,241, 89, 42, 95, 80, - 58, 1,208, 7,191,171,201,114,119,119,143,172, 91,183,238, 51, 79, 79,207,102,239,100,174, 20,162,171, 59,119,238,114,177,118, - 43, 51, 87, 48,168, 1,129, 20,142,118,150, 88, 63,190,149,181,157,165,180, 90, 38,171,220, 92,157,190,118,237,154,173, 68, 34, - 65, 84, 84, 20,132, 66, 33, 36, 18, 9,234,213,171,135,181,107,215,218, 89, 91, 91,255, 45, 76, 22, 33,196,138, 16,210,158, 16, -210,139, 16,242,209, 75,230,202, 19, 64,107, 66,200, 7, 0, 28, 1,156,167,148,222, 49, 81,179, 25,159,207, 63,220,160, 65,131, - 52, 62,159,255, 96,254,252,249, 95, 76,153, 50, 5,203,150, 45, 67,100,100,228,211, 41, 83,166, 32, 54, 54,214,160, 84, 42,187, - 82, 74, 15, 85,166, 85, 82, 82,114, 96,250,244,233, 22, 61,122,244,168,248, 63, 46, 93,186,132,205,155, 55, 67, 46,127,181, 21, - 68,215,174, 93, 49,116,232, 80, 43,173, 86,251,123,101,154, 14, 14, 14,109,174, 93,187, 22, 0, 64, 8, 64, 92, 97,176,238,223, -191,111, 89, 84, 84,100,105,102,102,102,233,228,228,164,168, 48, 89, 61,122,244,176, 20, 8, 4,205,192,241,239, 52, 88, 0,160, -203,203,132, 24, 70, 72,121, 4, 50,222, 75, 38, 11, 44,248,133, 89,213, 44,106,223,108,176, 20, 10,197, 11,163,165, 82,169, 76, -142,184, 84, 24, 27, 43, 43, 43, 20, 23, 23, 67,175,215,191,120, 56,172,172,172,160,209,104, 0, 0,114,185, 28, 53,140, 96,225, -202,149, 43,184,124,249, 50,248,124, 62,172,173,173, 1, 0,183,110,221,194,189,123,247, 32, 20, 10, 97,109,109, 93, 45, 93,157, - 78,247,198, 8,150, 78,167,131, 88, 44,174,150, 9, 84,171,213,244,214,173, 91,184,127,255, 62,196, 98, 49,236,236,236, 32, 18, -137,144,156,156,140,216,216, 88,136, 68, 34,216,217,217,213,232,254,152,155,155, 35, 63, 63, 31, 70,163,241,197,181,176,176,176, - 64,105,105, 41, 24,134, 49, 41,157, 44,203, 34, 45, 45, 13,217,217,217, 72, 78, 78, 70, 78, 78,206, 11,147, 85, 81, 69, 88,163, -140,203, 48, 32,132, 32, 58, 58,154,158, 57,115, 6,197,197,197,127,202, 75, 21, 17,210,127, 28,171, 2, 45,160, 23,180,203, 41, -209,139,179,117, 66, 11,135,192,182,192,179,163, 0,195, 7, 36, 86,104, 28, 84, 27, 73,249, 70,249,163, 76,173, 4, 4,237,177, -178,174,149, 73,154, 70,193, 7,217,197,122,113,162,206,206,220,191,126, 8, 50, 51, 51, 33, 22,139, 33, 22,139, 17,218,180, 45, -158,229, 26,101, 15, 82, 85, 50, 80,180, 51, 73,179,156,134, 13, 27,214,145, 74,165, 17, 13, 27, 54, 36, 47,107, 70, 68, 68,128, - 97,152,122,193,193,193,126,213, 58,255, 21, 94, 34,232,100,141,193,167, 99, 31,164, 43,157,247,223, 87,215,237,210,253, 35,235, -101,167,178,252, 31,102,104, 60, 65,245, 19, 65,117, 33, 53, 53, 89, 30, 30, 30, 45,205,204,204, 14,125,251,237,183,158, 98,177, -248,168,167,167,103,243, 26,149,111, 82,222,154,111,191,232,239, 98, 85, 97,174,244, 74,128, 47, 5, 4, 82,128, 47,133,163,189, - 45,230, 13,253,192, 90, 38, 17,252, 97,170,166, 84, 42,221,177,114,229, 74,187,215,205, 85,197,210,176, 97, 67,204,152, 49,195, -206,218,218,122,251, 95,108,174,172, 81,214,174,234, 46,128,223, 1,156,126,201, 92,121, 3,248,163, 60,106, 21, 77, 41, 77, 50, - 81,179, 73,135, 14, 29,206, 62,125,250,180,211,157, 59,119,156, 50, 50, 50,252, 38, 78,156,136,101,203,150, 97,202,148, 41,219, - 41,165,117,119,239,222, 29,124,227,198,141,122,148,210, 42, 35, 98, 25, 25, 25, 31, 79,153, 50, 37, 39, 39, 39, 7, 0, 80,175, - 94, 61, 20, 20, 20, 96,210,164, 73, 24, 55,110, 92, 69,228, 21,148, 82,100,102,102, 98,209,162, 69,153, 25, 25, 25,159, 86,166, -105, 52, 26,147,119,239,222,221, 72,167,211,185,162,172, 90, 80, 92, 80, 80, 96,158,151,151,167,208,233,116,114,150,101,229,150, -150,150,102, 0,100, 3, 7, 14,228, 63,120,240,192,223, 96, 48,164,114, 86,228, 95,106,176,120, 4,119,159,223,186, 0,235,192, -144, 87,162, 87, 50, 30,129,212,220, 2,207,146,147, 32, 4,137,169,238,129, 41,165,175, 24,172,138, 23, 99,122,122, 58,166, 78, -157,170,220,186,117,235, 61,173, 86, 27,113,225,194,133,105, 85,126,120, 3,176,179,179, 67, 82, 82, 18,253,241,199, 31,139,142, - 30, 61,106, 0, 0,123,123,123, 36, 39, 39,211,233,211,167, 23,239,218,181,139, 86,199, 96, 49, 12, 3,137, 68,130,115,231,206, -209,153, 51,103, 22,166,167,167, 83, 27, 27, 27,216,216,216,224,212,169, 83,134,105,211,166, 21,198,199,199,191, 88, 87, 29,131, - 85, 97, 88, 94, 54, 40,111, 51, 94,149,113,233,210,165,207, 11, 11, 11,199, 79,154, 52, 73,245,240,225, 67,106,103,103, 7, 59, - 59, 59,108,218,180,137, 63,104,208, 32,213,221,187,119, 95,172,171, 9, 54, 54, 54,136,139,139,163,243,231,207, 87,157, 62,125, - 90, 0, 0,182,182,182,136,141,141,165,115,230,204, 81, 21, 20, 20,140,191,116,233,210,231, 85, 20, 56,120,250,244,233,139,136, -149, 90,173, 70, 78, 78, 14,146,147,147, 95, 24, 44,149,220,188,195,151,131,187, 52, 40, 85,169,148,215,239, 61,126, 30,222, 48, -192,190, 84,165, 82, 62, 78,120, 30, 71,233,204, 55,182,109,187,124,249,242, 52,131,193, 16,113,240,224,193,123,107,215,174, 85, -230,229,229,189,209,176,255, 35, 13, 22,195, 58,130,208,102, 23, 31,151, 88,126,208,165,175,136,100,220, 0,116, 37,128,216, 10, - 16, 91,129, 47,183, 65,199,230,193,188, 77,215,138, 28, 65,217, 38, 16,138,171,110,223, 34,160, 14, 0,219,252,100,156,218,170, - 89,175,209,162,188,188, 60,240,120,188, 23,102, 72, 38,151,163, 77,247,129,204,134, 27, 26, 71,128, 54, 5,225,153,220,102, 70, - 40, 20, 78, 30, 60,120,176, 48, 63, 63, 31, 12,195,188,208,148, 74,165,232,209,163,135, 88,161, 80, 76, 55,249,220,247, 4, 8, - 33, 16, 55, 6,232,184, 71, 25,106,231, 3,247, 84,190, 19,191, 95, 47, 13, 12,110,132,225,145,246,210,239, 15,103, 5,222, 73, - 86,213, 6,140,227, 97,208,134, 86,215,100,121,122,122, 54,151,203,229,135,247,239,223, 47,107,213,170, 21, 38, 77,154, 36,151, - 72, 36, 71, 61, 60, 60, 90, 84,247, 54,149,150, 24,191,156,179,124, 75,230,221, 37,237, 1, 93,105,153,177,122,105,201, 42, 97, - 49, 99,253,153, 66,189,158,246, 55, 85, 83,165, 82, 13, 26, 50,100, 72,238, 31,127,252,241, 39,115, 37,145, 72,144,144,144,128, -239,190,251, 46, 47, 47, 47,239,211,191, 56,151, 6, 3,184, 13, 64, 13,160, 37, 0, 89,121, 79,193, 8, 0,167, 40,165, 70, 74, -105, 38,165, 52,221, 84, 65, 30,143, 55,101,213,170, 85,124,149, 74,133,161, 67,135, 34, 57, 57, 25,105,105,105,248,250,235,175, - 19, 88,150, 29, 84,174,121,135, 82, 26,107,138,158, 86,171,125,148,159,159,223,185,125,251,246, 5,249,249,249,168, 95,191, 62, -186,116,233, 2, 71, 71, 71, 56, 59, 59,163, 91,183,110,168, 91,183, 46,114,115,115,209,191,127,255,188,236,236,236,246,148,210, - 74,123,161,231,230,230,198,111,223,190, 61,110,244,232,209, 13, 83, 82, 82,252, 1,216, 20, 23, 23,203,139,139,139,197, 90,173, - 86,106,101,101,101, 21, 28, 28,108, 59,108,216, 48,179,219,183,111,251,167,164,164,148, 0, 72, 2,199,191,211, 96,233,128, 25, -155,119,111, 82,139,106,121,195,194,183, 1,100, 18, 9,164, 34, 17,164, 86, 54,208,176, 44,214, 37,100, 40, 75, 41,157, 94,221, - 3, 83, 74, 95,137, 52, 24,141, 70,172, 89,179, 70, 61,111,222,188,130,140,140,140, 17, 23, 46, 92,104,112,243,230,205,187,166, - 24,161,162,162, 34,236,222,189, 91,181,113,227,198,167, 42,149,170,161, 80, 40,212,107,181, 90,108,223,190, 93,189,116,233,210, - 68,165, 82, 25, 38, 16, 8,116,213, 49, 47, 21, 17, 44,129, 64,160, 87,171,213, 13,119,236,216, 17,127,232,208, 33,149,185,185, - 57, 4, 2,129, 94,169, 84,214,219,178,101,203,163, 29, 59,118,168, 20, 10, 69,181,140, 27,203,178,111,172, 34,100, 89,182, 90, - 6, 11, 0,110,222,188,249,171, 78,167, 11,223,190,125,123,202,250,245,235,213,230,230,230, 0, 0,189, 94, 31,182,121,243,230, -148,213,171, 87,107,170,211,192,189,188,224,129,209,104,196,150, 45, 91, 52, 59,118,236, 72, 49, 24, 12, 97, 21,235, 54,108,216, -160,222,178,101, 75,138, 78,167, 11,191,121,243,230,175, 85,105, 25,141, 70, 99, 81, 81, 17,248,124, 62,158, 62,125,170,169,136, -208, 61,121,242,228,133,193,178,183,181, 14,104, 26, 22,228,183,120,205,238,243,114,177, 88,220, 62, 50,212,255,193,227,164, 20, - 74, 73, 98, 21,231,126,247,202,149, 43, 13,242,242,242, 70,172, 93,187,182, 96,219,182,109,106,163,209,248,138,201, 18,137, 68, -255,196,167, 86, 6, 2,233,227, 44,141, 66,194, 24, 8,226,246,149,153, 43,137, 37, 32,177, 2, 36, 86,112,113,113,197,141, 4, -165, 2, 12, 68, 48,234,237, 77,120, 32,229, 32,144,221,207,132, 66, 32,146,146,140,140,140, 23, 70,168, 98,241,244,246, 71,116, - 82,137, 25, 8, 21,131, 7,135,106, 60,235,157, 21, 10, 5, 63, 61, 61,253,207,154,158,158, 60,189, 94,223,222,228,115, 79, 51, - 58, 1,236, 23,113, 25,106,167,189,119, 74,125,199, 47,216, 32,149, 26, 11,128, 91,203, 17, 88,199, 25,227,123, 5,139,190, 57, -144, 29,120, 51, 81, 89, 7, 60, 58, 28,108,137,201, 95, 23,158,158,158,205,100, 50,217,209,125,251,246,201,100, 50, 25,158, 62, -125,138,122,245,234, 97,206,156, 57, 50,153, 76,118,196,221,221, 61,178, 58,183,233, 90, 6, 77, 42, 41, 54, 70, 76,222,253, 60, -227,110,186,225, 21,115,149, 93, 74, 49,228,135, 3, 5,249, 69,234,143,174, 62,215,159,169,198,181,188, 93, 80, 80,208,110,250, -244,233,185,217,217,217,175,152,171,164,164,164, 10, 35, 16, 73, 41,141,249,139,115,169, 28,101,141,215,125, 1,120, 1,104, 64, - 41, 53, 0, 40,166,148,214, 40,116, 29, 16, 16,208,208,221,221, 29,171, 87,175,198,186,117,235,242, 23, 47, 94, 12, 74, 41,124, -124,124,204,107,170,153,153,153,121,227,209,163, 71,237,235,215,175,255,112,197,138, 21, 41, 78, 78, 78,236,176, 97,195, 48,100, -200, 16,216,217,217, 25,151, 46, 93,250,188,121,243,230,247,227,227,227,219,150,150,150,222, 51,225,254,208,156,156,156, 43,191, -252,242,203,181,214,173, 91,203, 6, 13, 26,100,183,127,255,126, 27,165, 82,233, 44, 22,139,237,181, 90,173,232,225,195,135,188, - 61,123,246, 56, 62,120,240, 32, 65,165, 82,221,160,229, 19,251,113,252, 11, 13,214,111, 79,233,149,210,226,130,133,115, 54,172, - 85, 61, 51, 16, 24,106, 7, 64,109,227,130,155, 5, 42, 76,122,152,162, 52,176,116,229,238,167,244,108, 77, 35, 88, 50,153, 12, -167, 79,159, 54,126,241,197, 23,234, 27, 55,110,252, 82, 88, 88,232,118,243,230,205,109,166,234,176, 44,203,251,236,179,207, 74, - 46, 95,190,188, 59, 61, 61, 61, 48, 42, 42,234, 25,203,178,188, 1, 3, 6,148,156, 60,121,242, 15, 66,136,255,173, 91,183, 30, -215, 32,196, 13,161, 80, 8, 66, 8,110,222,188,153,144,151,151, 23,120,237,218,181, 29,211,166, 77, 43,161,148,242,162,162,162, -146, 75, 75, 75,235, 95,185,114,101,235,151, 95,126, 89, 66, 41,229,153,170, 91, 97,222, 94, 54, 82, 21,209,172,234, 26, 44, 0, -136,138,138,138, 41, 40, 40,240,191,113,227,198,209, 97,195,134, 41,203,205,199,195,226,226, 98,191,107,215,174, 29, 30, 52,104, -144,178, 58,122, 58,157, 14,221,187,119, 87, 94,189,122,245,112,113,113,177,223,205,155, 55, 31, 86,172,187,124,249,242,209,130, -130, 2,255,168,168, 40, 83, 11,240, 57, 75,151, 46, 77,159, 55,111, 94,122,118,118,246,226, 37, 75,150,100,219,217,217, 65,167, -211,189, 48, 88, 89, 57,121,103,154,124, 56,250,135,173,191,159,186,185,116,206, 23,173,164, 18,177,104,250,247, 27,206,233,121, -184,102,162,201,220, 86, 84, 84,228,118,231,206,157, 95,198,143, 31,175, 62,113,226,132, 81, 42,149,194,204,204, 12, 98,241, 63, -177, 13,169,177, 8, 44, 73,235, 29,106,149,186,116,213,175,154,251,207, 50, 95, 24, 43,136, 45,113, 51,190, 0,223,174,216,205, -126,215,213,238, 25, 40,146,193,224, 81,213,154,252, 34,176, 36,107, 72, 35, 97,202,111, 63,141,211, 60,123,116,239, 21, 35, 20, -123,247, 38,150,204, 28,205,206,239, 98,253, 12, 44, 73, 3, 65,172,169,169, 53, 24, 12,189, 22, 44, 88, 80, 26, 31, 31,255,138, -102, 98, 98, 34,190,255,254,123,149, 70,163,249,200,228,135, 82,204,111, 96,164,212,126,219,213, 92,159, 17,195, 6, 75,165,134, - 60,224,250,143,128, 64, 6,136, 45, 16,236, 87, 7, 51,134,126, 40,152,184, 39, 35, 16, 96,221,193, 8,253, 77, 77, 39,159,207, - 63,188, 96,193, 2,153, 84, 42,197,147, 39, 79, 32,145, 72, 32,149, 74, 17, 26, 26,138,101,203,150,201, 68, 34,209,209,138,246, -157,213, 54, 89, 59,158,100,220, 77, 86, 3, 2, 9,114, 74,129, 33, 63, 28,204,207, 43, 84,245,170,142,185,122,221,100,141, 27, - 55, 46, 55, 51, 51, 19, 18,137, 4,201,201,201,232,215,175, 95,238,223,196, 92, 1, 64, 41, 0, 23, 0,113, 0,226, 1,220, 33, -132,136,240, 14,211,179, 61,120,240, 32, 58, 41, 41, 9,159,127,254, 57, 62,249,228, 19,171,143, 63,254, 24,207,158, 61, 67, 92, - 92,220,237,119, 73,168, 74,165,186,153,146,146, 82,111,220,184,113, 51, 92, 93, 93, 55,218,216,216,156,179,182,182, 62,235,234, -234,186, 97,218,180,105,223,166,167,167, 55,208,233,116,119,170,113,127, 40,165,244, 73,124,124,252,129, 45, 91,182, 68,141, 27, - 55, 46,225,227,143, 63, 78, 25, 59,118,108,250, 47,191,252,146,118,251,246,237,199, 5, 5, 5,199,171,138,134,113,252, 3, 48, -117, 86,232, 94,158,104, 58,184, 14, 57,255,113,109, 20,247,175,141,146,207,188,200,165,143, 60,209,186, 38,179,109, 55,108,216, -144, 26, 12, 6,122,226,196, 9,218,177, 99,199,210,102,205,154, 93, 10, 9, 9,241,169,201, 12,222,145,145,145,199, 66, 67, 67, -123,191,190,174, 81,163, 70,125, 95, 94,215,178,101,203,152,150, 45, 91, 22,182,104,209,226,169, 41,233,108,209,162, 69,108,211, -166, 77, 75, 91,180,104, 17,251,242,250,176,176,176,110,173, 91,183, 62,252,242,186, 70,141, 26,117,125,125,221,219,206,189,109, -219,182,201,113,113,113,244,249,243,231,180, 83,167, 78,105, 21,235,219,180,105,147,124,239,222, 61,250,248,241, 99,218,161, 67, -135,180,154,206, 94, 30, 26, 26, 58,180,121,243,230, 87, 94, 75,243,144,215,215, 85,166,217,188,121,243, 43, 97, 97, 97, 67, 94, - 95, 23, 26, 26, 58,244, 93,103, 89,119,114,114,170, 27, 28, 28,156,181,116,233, 82, 90,187,118,237,172,151,127, 11,140,252,236, -219,130,162,146,162, 73,115, 86,255,102,231,223,189, 94, 77,102,110, 15, 9, 9,241,105,209,162,197,165, 15, 63,252,176,244,198, -141, 27,148, 82, 74, 27, 54,108, 72,255, 81,179,214,239,246, 23,210,181,254, 77,233, 26,255,195,177, 51,221, 31,126, 26, 46,215, - 68,253,212,137,210, 51,147,233,181,213, 67,104,132,167,200,120,121,146, 91, 28, 93,235,119,148,110,168,219,130, 46,175, 35, 50, - 73,115,157, 87,115,186,214,239,232,131, 25,238, 15,123,132,216,105,119,108, 90, 75,159, 60,121, 66, 15,236,217, 78, 27,215,150, -149,105,174,241, 63, 65, 87,251,183, 50, 73,243,213,103,190,105, 68, 68, 68,201,111,191,253, 70,159, 60,121, 66, 79,158, 60, 73, -155, 54,109,170, 12, 14, 14,110,101,242,185, 3,132,174, 14,232,110, 88,229,123,113, 90, 91,179,130, 33,225, 18, 77,255, 96,145, -182, 91,160, 80,215,206, 91,104,104,226,206, 55, 54,112, 98, 88,127, 59,208,118,190, 82, 13, 93,227,123,129,174,241,111,111,106, - 58,125,124,124,158,123,120,120,208,183, 45,117,235,214,205,110,217,178, 37,191, 38,247, 61,220, 1,238,109,235,138,211, 79,207, -105, 77,187,212, 87,228, 54,118,227,183,126,215,188, 4, 32,216,214,214, 54,103,227,198,141,212,193,193, 33, 27, 64,224,223, 34, -127,150,173,179, 6,208, 13,128, 93,249,255,205, 0,180, 2, 80,251, 29, 52,155,180,107,215, 78, 31, 29, 29, 77,159, 62,125, 74, -143, 29, 59, 70,155, 54,109,106, 0, 16,249,183,121, 54, 57, 77,110,121,105, 33,255,205,232, 36, 33,164,237,155, 6, 35, 11, 9, - 9,161,237,219,183, 87,157, 63,127,190, 68,171,213, 14,191,117,235,214,129,119,213,252,111,164,243,191,161,217,186,117,235, 43, - 12,195,212, 46,239, 2,156,118,234,212,169,134, 0,208,170, 85,171, 43, 60, 30,175,118,185,233, 77, 59,125,250,116,195,127,218, -185, 87,224,236,236, 92,151, 97,152,227, 0, 52, 41, 41, 41, 47,122, 59,217, 7,118,139,176,182,178,104, 85, 80, 80,120, 59,227, -254,254,163,239,146,206,208,208,208,174, 98,177,120,109, 68, 68,132,252,204,153, 51,178,168,168, 40,242,143,186,158, 43,188, 68, - 16,137, 66, 65, 49,245,126,170,210,243,219,131, 57,117, 62,108,211, 84,176,105,223,121,118, 97, 79,251,248, 38, 94,242, 4, 8, -216, 31, 64, 52, 55,240,105,162,198,100, 77, 41,105, 4,163, 96,234,157,100,165,251,164, 63,242,189,219,126, 52,132,119,112,231, - 90,246,199,238, 54,241, 77,234,152, 61, 7,197, 15, 16, 43,175,154,172,249,234,115,223, 84, 44, 22, 31,237,223,191,191,217,142, - 29, 59, 84,106,181,186,115,116,116,244,217,106,157,251,122,191, 90, 48,146,121,160,212,173,234,175, 71, 60,129, 17,243,240, 69, -236,243,191,195,125,111,236, 72,220,229, 22,226, 67, 74,149, 97,156, 41,145, 43, 83, 52, 9, 33,193, 86, 86, 86, 91,243,243,243, -251,154, 18,185,250, 95,158, 59, 33,196, 14, 64, 88,121,212,138, 0,136, 49, 53,106, 83,137,102, 51, 30,143, 55,165, 78,157, 58, -245,159, 62,125,122,223,104, 52,254, 72, 41, 61,247,111,120,119,252, 27, 52,255,105,252, 37,125,216,165, 82,105,244,185,115,231, -142, 9,133,194,239, 46, 95,190,172,249, 55, 93,240, 51,103,206, 52,121,211,250,179,103,207, 54,249,183, 92,131,180,180,180, 56, - 0,238,175,175,207,138,217,127, 21,192,213,247,113,140, 91,183,110, 29,136,140,140, 60,113,249,242,229,111,228,114,121,135,127, -220, 69, 28, 29,175,197, 10,175, 91, 16,137,190, 15,114,145, 77,253,182, 19, 37, 11,142, 95,113, 95,216,211,254,121, 85,230,170, - 10,205, 27,144,234,191,111,224, 38,155, 58,191, 27,200, 15, 71, 55,185,255,216,221,230,121, 85,230,202, 20,162,162,162, 46,135, -132,132,116,220,185,115,231,102,181, 90, 61,180, 42,115,245, 70, 20, 76, 6, 74,245, 51,161,231, 5,129, 66, 84, 73,104, 94, 9, -134,119, 31, 89,200,252,187,220,178,107, 25, 52, 9, 64,224,251,212,164,148,222, 6,224,255,119,204,162,148,210,108, 0,135,223, -179,230, 37, 0,151,184, 87, 55, 7,103,176,222,194,197,139, 23, 67,184, 75,207,241,223,230,220,185,115, 26, 0,223,150, 47,255, - 60, 94, 50, 89, 33,181,164,163,255, 24, 33, 85,130,146, 20, 8,216,165,213, 54, 87,111, 48, 89,141,220,165,227,246, 14,151, 42, - 65,145, 1,138, 37,239, 98,174, 94, 54, 89, 0,106,215, 88,160,215, 3, 29,128, 4, 16,146,136, 89,120,123, 99,197, 89,120, 81, -143,193,193,193,193,241,175, 49, 88, 28, 28, 28,239,209,100,237, 9,184,137, 28,222, 36, 48,168, 13, 24,146, 80,106,200,192,232, - 68,237, 59,106, 94, 71, 14, 25, 11, 30,234, 66,100,136, 71,137, 54, 3, 35,222, 65,243,125, 83,102,158,222,110,160,102,114, 89, -131,131,131,131, 51, 88, 28, 28, 28,239, 66, 89, 84, 39,165,124,249,251,106,114,112,112,112,252,139, 32, 0,218,190,229, 3,209, -228,198,107,132,144,182, 53,248, 0, 61,197,105,114,154,156, 38,167,201,105,114,154,156,230,191, 75,179, 42,237,127, 76,227,249, -255,102, 23, 69,112, 93, 88, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252, 23, 46, 12, 56, 56, 56, 56, 56, 56, 56, 56, 56, -222, 43,127,105, 27, 44,153,109, 93, 39,240,153,250,132,165,126, 0, 64, 25, 18, 11, 3,123, 87,153, 19,151,254,174,218,196,161, -158,204, 76,192,219, 94,162, 55,126, 76, 51,239, 41,223, 71,122, 9, 33,205, 80, 54,188, 64, 82,121,119, 97, 14, 14, 14, 14, 14, - 14, 14, 14,211, 13, 86,221, 38, 61, 46,154,201,228,222, 0, 96,100, 41,140, 44, 80,148,159,117, 53,233,238,201, 30, 0,224, 28, -216,102,175, 88,110, 27, 97,100, 41, 88, 74, 97,100, 41,244, 26,213,147,236, 7,135, 77,154,121,222,204,222,183, 71,219,118,109, -123,118,238,252,161,111,189,160,122, 94, 0,112,239,254,189,248, 67,135, 14, 63, 50,179,247,253,163, 36,235,209,222,119, 57, 49, - 51,129,224,219,176, 70,225,237,111,222,188,254, 13,128,175,223,211,245, 18,210, 75,157,182,144,102, 71,218,112, 89,135,131,131, -131,131,131,131,163,218, 6,203, 76, 38,247, 62,189,111,189,253,222, 75,201, 0,128,182, 13, 29, 49,251,167,141,221, 9, 33,143, - 0,224,163, 47,127,170,251,237,248,193,184, 18,147, 5, 74, 41,130,189,109,208,237,227, 81, 38, 29, 84,234, 24, 16,214,183, 79, -159,143, 39, 77,154,216,245,201,147, 39,137, 59,118,236,184, 8, 0,205, 91,180,240,158, 63,127,126,159, 69, 86,214, 98,169, 99, - 64,170, 42,227,193,205, 26,153, 43, 71, 47, 91,255,192,176, 33, 59,214,253,200,111,213,177,223,231,102,142, 94, 75, 74, 50,226, -115,106,162, 37,118, 11,172,109, 33, 16,206, 38, 12,195,183,176,247,176, 7, 0,115, 39,255, 35,246, 94,205,140,102,150,246,119, - 74, 85,170,205, 89, 15,143,173,227, 38,236,228,224,224,224,224,224,224,168,210, 96, 1,128,153,148,143, 71,207, 50, 0, 0,150, - 82, 96,216,160, 94,200,204,204,168,171, 51,178, 24,216,183, 7,162, 99,211,241, 40, 33, 27,148, 82,212,117,149,153,124, 80, 30, -216,208,207, 62,255,172,229,241, 19, 39,110,124, 59,253,219, 45,132,148,141,222,189,246,151, 95, 35,102,204,156, 49,244,147, 65, -159,124,176,103,207,158, 24, 0, 53, 50, 88,140,192,114,233, 15,243,103,153,165,100,171,213,227, 38, 78,230, 77, 24, 63,102, 17, -128, 65, 53, 49, 87,254,110,174,223, 93, 60,177, 71, 38,147,201,176,110,221, 58, 49,176, 31,253,187,182, 16,117,250,240, 67,248, -248, 5, 53,249,113,229,142,250, 39, 68,162,207,109,235,126,208, 35, 39,238,100, 58,151,165, 56, 56, 56, 56, 56, 56, 56, 42,109, -228,110, 52, 82, 60, 74, 72,199,163,132,116,220,136,205,134,142,229,225,167,121, 83,241,195,172,201,200, 85, 2,123,175, 36, 35, - 46, 33, 3,113, 9, 25,200,201, 47,249,211,254,175,119,181,252,233,123, 89,195,165, 75, 45,126,108,215, 66, 30,105,109,101,101, -245, 56,102, 75,233,140, 9,153,254,179,199, 37, 11, 5, 18,135, 20, 43,135, 90, 77,118,239,217, 19,224, 96,103, 47, 55, 55,183, -152,108,237,215,110,189,165, 71,164, 69,101,154,127, 50,133,142,129, 45,187,116,233,212,201,209,193,158, 29,177, 52, 42, 54,192, -207,199,224, 83,215, 47,210,204,209,183,229,219,246,121,147,166,216, 45,176,182,151,147,195,119,231,143,237,145,169,213,106,220, -191,127, 31,185,185,185,229,219, 3, 14, 14, 78,112,119,117,198,207, 11, 38,201,102, 77, 29, 21, 34,150,200,246, 19, 66,136,169, -233,172, 9,156, 38,167,201,105,114,154,156, 38,167,249, 79,213,252, 87, 25,172,248,228, 60, 60,122,150,129, 16, 63, 23,120,121, - 56,225, 70, 92, 62,182,157, 73,198,250,227, 73, 56,115, 39, 27, 44, 95,129,140, 34,224,113, 98, 38, 30, 39,229,160,170, 74, 50, -158, 88,208,119,220,184,194, 73,245, 2,138, 26,159, 59, 58, 26, 46,118,143, 3,166, 76, 41, 24,205, 19, 11,250,218, 59, 90,238, -152, 52,118,196, 0,133, 76, 42,210,106,180,240,244,112,147,140, 28,250,217, 96,161,153,124,135,169, 39, 99,103, 23, 32, 23, 75, -229, 91,190,251,118,162,100,201,222,199,207, 75,181, 40,253,227, 74,230,211, 73, 83,103, 20,241, 4,210, 95,236,236, 2,228,166, -232,136,221, 2,107,187,219,216,124,119,233,248, 30,153, 78,167, 65,122,122, 58,180, 90, 45, 12, 6, 67,217,239, 18, 9,196, 18, - 9,138, 84, 6, 60,203, 80,162,101,243, 38,188,134,193,129,126,118,126, 29,135,115, 89,138,131,131,131,131,131,131,227,173, 6, -171, 68, 89,250,100,208,136,137, 89, 94,102,233,218,110,145,254,160,160,200, 78, 79,194,131,155,199,240, 36,250, 56,138,114,158, - 3,160,240,240,116,135, 80,245, 76,187,102,245,170, 44,214,160,126,242, 54,189,110,221,156, 93,159,196,202,153, 31, 23,214,186, - 22,247, 40,221,118,212,240,141,136,123,148,110,251,227,194, 90,215,158,196,202, 25,153,216,216,100, 80,191,110,164, 91,231, 14, -152, 50,101, 18,186,117,238,128, 73, 35,250, 16,137, 72,208,216,212,147,209,138, 36,223, 79,253,118,142, 34,163, 64,167,187, 17, - 87,162,145,201,165,210,203,143, 75,212, 90,200,244, 93,251,142,200,214, 8,249,115, 76, 49, 87, 78,230,230,223, 93, 57,245,187, -140, 82,138,212,212, 84,104,181, 90,232,245,250, 23, 6,203,210,210, 18, 5,165, 58, 60,207, 82, 34, 49, 83,137,152,196, 34,116, -236,208, 81,198, 23,136, 6,112, 89,138,131,131,131,131,131,131,227,173, 6, 43,238,202,222,230,183, 78,110,113,200,201,204, 40, - 52,147,240,193,103, 8, 50, 83,226,177,121,209, 88,236, 94, 49, 17, 5,233,241,160, 20,144, 10,121,208,148,230, 21,166,223,222, -237,144, 83, 73, 15, 66, 66,244, 31,172, 92,155,224,153,144, 64,205,183,111, 47, 17, 0,192,246,237, 37,130,132, 4,106,190,114, -109,130,167,136,228,128, 26,141,232,220,237, 35,108,217,180, 14, 17,173,187,225,247, 11,207,161, 84,233, 76,154,255, 76,226, 80, -215,195,214,209,241,163,177,159,180, 81, 52,170,107, 37,247,113,183,224,137, 4, 2,131,128, 39, 52, 30,188, 89,152,214,190, 75, -119,190, 76,110,222, 65,226, 80,215,163, 50, 29, 11,129,112,246,229, 19,191,203,120, 60, 30,158, 63,127, 14,173, 86, 11,173, 86, - 11,141, 70, 3,189, 94, 15, 0, 40, 86,233,145,158,171, 65,114,182, 10,201,217, 42, 60,120, 94, 12,145,220, 18,122,189, 62,136, -203, 82, 28, 28, 28, 28, 28, 28, 28, 38, 13, 52,154,154,153, 7, 27, 51, 62,236,156, 61, 49, 96,236, 79, 0, 0,163, 81, 15, 74, - 1,131,145,133, 41,253,231, 40, 21,156,252, 98,164,103,130,135, 39, 41, 28,240,177, 76, 5, 0, 3, 62,150,169, 60, 60, 73,225, - 23, 35, 61, 19,148, 58, 43,157,193,104,196,229,152, 44,252,184,235, 33,102,108,186,135, 99,183, 76,111, 51,206, 23, 72,199,253, -176, 96,190,140,207, 35, 36, 38,169,164, 36, 37,215, 80,194, 19, 8,116, 50,153,136,106, 41, 95,147,152,109,204,237,208,123,100, - 34,143, 39, 24, 85,117, 90, 89, 80, 74,161,209,104,160,213,106,161,211,233, 94, 68,177, 0,160,176, 84,143,244, 60, 53,146,179, - 85,120,158,173, 66, 74,182, 10,153,249,106,112, 29, 9, 57, 56, 56, 56, 56, 56, 56, 76, 50, 88, 44,128,199, 73, 57, 16,241, 89, -184,122,120,129,190, 52,129, 61, 5, 96, 48, 86, 62,169,125, 5,251,247,167,165,212,241, 46,101, 39, 79,126, 30, 17, 84,207,230, -238,200, 17,110,177, 65,245,108,238, 78,158,252, 60,162,142,119, 41,171, 55,138,140,148, 82,176, 20,229, 11,173,150, 97, 33,132, -215, 56,216,207,157, 63,123,251,227,231,163, 86,197, 61, 18, 10,133,122, 87, 91, 25,113,119,144,241,106,217, 73, 69, 26, 61,163, -241,173,215, 72, 71,128,134,149,233, 20,234,117, 51,155,181,239,173,212,233, 12,112,115,115,123,197, 92, 85, 84, 17, 22, 42,117, - 72,207, 87,227,121,182, 18,201,217, 74, 40, 53, 6,220,143, 75, 0, 97,120,247,185, 44,197,193,193,193,193,193,193, 97, 82, 4, -203,221,213, 1,215,239, 39,193,221, 78, 2, 11,115, 5, 98,227, 83,192, 99, 4, 96, 8,160, 55,152,110,130,168, 78,191,107,241, - 98,139, 69, 73, 9,198,235,171, 86, 63,125,146,148, 96,188,190,120,177,197, 34,170,211,239, 2,202,122,231,149,153,172, 50,163, -101,100, 77, 63, 17, 74, 89,123, 59, 75, 9,255,214,211,210, 92,134,225,105,108, 44, 36,172,141,133,152,113,178, 20, 11, 92,109, -132, 66,145,136,129,163,157,173, 1,148, 58, 84,166,163, 73,142,121,150, 94, 84,244, 77,243,118, 31, 41, 5, 2, 1, 60, 61, 61, - 95, 84, 19, 86, 24,172,172,236,252, 23, 17,172,244, 60, 13,164, 34, 6,183, 47,159, 86, 26,141,250,205, 92,150,226,224,224,224, -224,224,224,168,218, 96, 81,192, 76, 38, 1,229, 73,112, 49, 42, 30,190, 1,245,177,233,192, 13,120,215,107, 12,150, 53,192,192, - 26, 77, 62,216,196,169,202,232, 9, 19, 10,191, 74,207,164, 75,123,244,112, 57,156,158, 73,151, 78,152, 80,248,213,196,169,202, -232,242, 67,129,101,105,153,209, 42, 31, 33,222, 84, 8,144,150,148, 89, 92,234,233, 40, 7, 79, 32,208,200,197, 66,131,149, 92, -196,218, 89,136, 4,118,230, 98,145,189,185,136,159,155,151,165, 2, 72, 90, 85, 90,154,228,152,103,207,243,243,191,105,209,177, -159,210,204, 76, 1, 47, 47, 47,104, 52,154, 23, 6,171,184,164, 20,121, 69, 42, 80, 10,212,117,149, 35, 54,250,146, 49, 55, 43, -245, 65,126,220,177,117, 92,150,226,224,224,224,224,224,224, 48, 41,130,101,100, 41,108,109,172, 33,145,155, 35, 33, 83,135, 98, - 98,143,124, 37,133,209, 88,121, 4,139, 16,210,246, 77,235,247,239, 79, 75,217,183, 47,123,253,254,253,105, 41, 47, 59, 57,246, - 69, 21, 97,249, 95,150,154,172, 73,169,241,232,193,147, 87,242,186,134,219, 89, 49, 60,158, 74, 40, 96, 52,124, 33, 79, 39,228, - 51,122, 33,159,209, 58,152, 11,120,103, 14,108, 99, 8,161,103, 76,209,212, 36,199, 60, 75,200,202,250,166,117,231,254, 74,123, - 7, 7,124,242,201, 39,112,115,115, 3, 0,152, 73, 8,108, 69, 74,240,212,105, 56,127, 96, 67,105,108,212,217, 40, 24, 53, 61, - 94, 30,205,253,109,233,124, 23, 56, 77, 78,147,211,228, 52, 57, 77, 78,243,159,170,249, 79,195,132,201,158, 41,234, 56,201,225, -237, 34,135, 90,103, 15,181,214,136, 82,181, 17, 69, 74, 29,138,148,122, 36,100, 40,241,248,236,187, 39,132, 2,160, 44, 64, 80, - 86, 85, 8, 82,102,236, 40, 49,109,255, 82, 65,209,162, 31,231,207,234,183,115,247, 31, 24,243,161,147,219,221, 4,109, 26, 33, -140,138,225,241,245,214, 10,190,224,105,252,163,244,243, 39,246,132,150,138,148, 67, 76, 77,147, 38, 57,230,153,216, 45,240, 27, -223,134,173,103,131,130,175, 85, 21,202,167, 54, 13,192,157, 59,119,213,177,241, 25, 6,158,196,242, 46,107,212,109,205,143,227, -166,202,225,224,224,224,224,224,224,168,134,193, 82,170,148, 79, 62,232, 57,228,197,132,206, 70, 35, 5,203, 82, 24,203, 35, 76, - 44,165, 48,232, 84, 79,222, 53, 33, 70,150,189,177,122,211,206, 78, 13,130, 27,243, 2,106,153,161, 40, 63, 27, 55,175, 95, 53, - 80,150,189,106,146, 65, 75, 76,212,152, 57,248,245,233,243, 81,143,157,159,143, 24, 83,212,162, 69, 43,177,141,173,185, 46, 51, - 59,171,104,219,186, 29,198, 67,127,236, 12, 5,203, 14,164,137,137,154,234,164, 75,147, 28,243, 12,192,128,114,199,222, 26, 8, -104,169,202,126,220, 89,153, 21,119,134,203, 62, 28, 28, 28, 28, 28, 28, 28, 53, 50, 88,143,175,238,109,254,191, 72, 72, 94, 94, -230, 39, 91,119,252, 49,111,219,174, 3, 77, 53, 58,157, 11, 11, 94,178, 81,175, 63, 47, 46,206,157, 97,170, 70, 73,102,236, 3, -226,225, 17,250,235,207,139,198,255,178,114,113, 27,176, 70, 95, 16,146, 64, 8, 61, 83, 34, 84, 14,171,174,185,122, 3, 57,164, -217,145,118, 0,114,184,172,195,193,193,193,193,193,193, 81, 99,131,245,191, 34, 47,254,122, 49,128, 49,239,170, 83,110,162, 22, -148, 47,239, 21, 74,233,125, 0,220, 80, 12, 28, 28, 28, 28, 28, 28, 28,149,194,112,151,128,131,131,131,131,131,131,131,227,253, - 66, 0,188,165, 87,158,233, 51,101,215,164, 55, 65, 85,250,156, 38,167,201,105,114,154,156, 38,167,201,105,254,243, 52,171,210, -174,142,255,248, 91, 67,203, 71, 76,255,111, 44, 0,218,114,154,156, 38,167,201,105,114,154,156, 38,167,201,105,254,219, 22,174, -138,144,131,131,131,131,227, 95,135,109,221,174,102,182,117,187,154,153,186,189, 93, 64,111, 7,187,128,222, 14,220,149,227, 48, - 21, 62,119, 9,222, 29, 66,136, 24, 0, 75, 41,213,253, 85,105,176,178,170,109,110, 80,216,238,101, 88,205, 15,133,201,119, 79, -190,239,243, 11, 8, 8, 8, 6,128, 7, 15, 30,220,166,148,190,107,111, 76,200, 29,124,251, 91,153, 91, 14,215,177, 90,163,178, - 84,185,186, 36, 35,110,207,251, 76,179,157, 93,128, 92, 43,150, 46, 4,161, 29, 65,193, 80, 66,206,240,138,245,227, 11, 10,238, - 20, 86,182, 95,173,110, 11,252, 62,239,243,225,244,245,191, 29,158,247,124,255,180,216,215,127,183,238,184, 66, 49,122, 96,187, - 41, 43,119,238,255, 62,231,192,228, 18, 46,247, 87,159, 90,205, 62,182, 52,240, 29,121,105,231, 22,229, 86,103, 63, 87,223,136, - 24,129, 64, 96,167,211,233,178, 82,227,174, 5,153,178,143,155, 95,147,104, 30,143,113, 54, 26,216,148,228, 71, 87, 66,185,171, - 95, 53, 82,251, 58, 17, 48, 24,190,166, 0, 1,225,255,164,206,125,250, 78, 35, 29, 58, 59, 59, 75, 45, 44, 44, 90,152,155,155, -187,201,100, 50, 73,126,126,190, 42, 63, 63,255,121, 82, 82,210, 25, 74,169,225,175, 56, 71,187,192,238,211,248, 34,102,102,249, -191,103,103,199,236, 91, 80,249,246,221,230, 17,134, 76, 43,255,247,130,236,152,253,211,255, 14,247,202,161, 94,207,112, 80,118, - 60,195,240,154, 24,169, 97,126,214,189,253,171,170,179,127, 68, 68, 68,119,189, 94, 47,174,248,191, 64, 32,208, 92,189,122,117, - 31,247, 20,252, 69, 6,203, 53,160,183,149,158, 79,103,241,121,204, 71, 44,165,138,244,219,187,229,127,231, 19,116, 15, 31,120, -139, 97, 24,215,151,215,177, 44,155,146,116,125,203,123, 41,108, 9, 33,174, 63,141, 11,153,146,153,171, 42, 34,132,204,125,155, -249,112, 8,238,127,133, 48,164, 54, 33, 4, 12, 67,192, 43, 27, 64, 53,237,249,245,173, 13,223,160,233,100, 46,231,215, 45, 42, - 53,220,167,148, 86,249, 18,146,218,248, 56,203,108, 92,206, 71,118, 31,237,121,235,196, 70,127, 51, 7,191, 54, 37,153,177, 15, -222,195,185,217,121,121,121,133,213,173, 91,215,102,244,232,209, 66, 0, 88,178,100,137,183,183,183,119,110,124,124,252, 77, 74, -105,118,141,204,149,189,223, 39,203, 22,205,217,210,177, 99, 39,164,229,148, 98,225,226,149,145,102,142,117,123,191, 47,147, 69, -156, 67,164,150,114,121,204,151,227,103,184,116,106, 21,198,207, 47,213,225,200,153, 27, 3,246,172,255,161,181,165,101,131,160, -202, 76, 22,171, 44,156,238, 96, 70, 59,176,202, 66, 0,232,255,250,239, 46,102,250,182,118, 82, 99, 7, 39, 49,255, 54,128, 63, -170,124,185,132, 13, 58, 46, 16, 10,221, 9, 97,192, 16,128,199, 35, 96, 8, 1, 67, 0,131, 94,155,244,228,226,134,246,127,139, -130, 58,228,147, 12, 66,136, 13,195,148,165,143, 16,128, 97, 24,240,203, 70,254, 45,122,122,101,163,205,123,200, 79, 22, 65,222, -150,129, 31, 54,109,182,225,252,179, 60,121,173,150,227, 15, 19,202,172, 74,186,240,211, 29, 83,246,151, 72, 36, 86, 7, 15, 30, -180,235,208,161,131,133, 67, 80,247,243,166,236, 99, 38,146, 4, 28, 58,116, 64,216,161, 67,251,106,228, 79,223, 15,192, 48, 91, - 9, 32, 96, 89,186,132,199,210,223, 74,114,227,226,171, 59,152,176,125, 80,247, 57, 32,240, 55,121, 7,138,135, 89,247,247,205, -168,225,181,229, 73,237,125, 63,149, 74, 36,147,124,124,253,235, 38, 60,139,143, 43, 42, 42, 92,172,202,138, 91, 79, 41,101,171, - 37,166, 55,124,117,234, 98, 84, 71,190, 64, 64, 58,180, 9,231, 1,120, 39,131,229,224,224,208,125,197,138, 21,117, 34, 34, 34, - 0, 0, 6,131,193,124,247,238,221,142,115,231,206,149,155,242, 12,189, 9, 23, 23, 23, 23, 11, 11,139, 90, 82,169,212, 5, 0, - 84, 42, 85,106, 97, 97,225,243,212,212,212,212,170,246,117, 12,238,109,203, 48,152,115,236,143, 95,248, 0,208,190,231,240,121, -158,145, 95, 89, 17,158, 64,245,166,237,141, 6,173,156, 33,100,252,233,131, 27, 9, 0,180,233, 58,120,170, 93, 64,239,159,179, - 31,236,206,252, 75, 62,232,123,247,230,217, 62,214,117, 39,148, 76, 8, 9, 13,107,252, 81,183,142,240,247,114, 70,247,126, 35, - 39, 1,168,150,193,210,235,245,226, 61,123,246,184, 50, 12,195, 51, 24, 12,234, 62,125,250,100,189, 75,218,124,154, 13,186, 2, - 66,220,116, 6,195,175, 73,215,188,230, 81, 58,147,125, 61,237, 78, 9,252,111, 64,152,161,148,101,147,211,163,119, 52,225, 12, - 86, 57,182,117,187,154,241,196,194,251,173,154, 55,182,153, 58,178,135,104,205,111, 23,225, 28,220, 39, 53,237,246,111, 46,127, -215, 19,100, 24,198,117,223,246, 21,246, 50, 17, 15, 0, 80,162, 54,160,231, 39, 85,143, 6,225, 18, 54,224, 28, 8,124, 43,234, - 80,141, 70,131,132,207, 23,168, 9, 0,144,178,222, 1, 82,169,232,218,250,111, 34, 10, 7,119,169, 61,112,202,207,209,155, 0, - 88, 2,200,120,227, 67,193, 48,174, 59, 55, 44,177,119,177,145,128,207, 35, 40, 81, 25,208, 99,224, 4,227,155, 12,219,250,111, - 34,230,124,210,209,163,175,125,135,223,123, 2, 56, 90,233, 11,196, 49,192, 79, 97,235,124,242,163,225,115,156,149, 48,199,183, -243,150,216, 95, 62,177,251, 98,219,238, 67,116,207, 83, 82,148, 6,157,254, 81,110, 94,250,196,226,180,184,199,166, 22,212,102, -102,102,117,204,204,204, 26,116,236,216, 81, 50,105,210, 36, 65,100,100,228,139,223,135, 13, 27, 38, 60,119,238,156,211,162, 69, -139, 58, 57, 59, 59,171, 75, 74, 74,238,148,148,148, 60,165,148,154, 60, 41,165,163,163,221,151, 31,245,232,130,214, 61,191,128, -145, 37, 24, 54,106, 60,142, 31,253, 99, 4,128,247, 98,176,204,120,204,236,161,163,191,118,105, 17,209,144,191, 96,247, 99, 88, -202,132,104, 23,222,144, 47, 17,124,229,184,227,215, 69,139, 1,124,246,166,200, 21,171, 44,156, 30,100,171,237,215, 53,162, 54, - 14,236,208,246,115,109, 59, 5,140,204,226, 69, 36,203,171,227, 24,133,149, 84,186,194,217,146,103, 47, 54,102,175,240,234, 56, -230, 84,252,209,229,197,149,165, 69, 32, 20,186,175, 95,241,157,143,149, 66, 8, 62, 67,192,227, 17,240,121, 12,212, 90, 35, 6, -142,156,246,190, 34,140, 60,169,189, 79, 39, 6, 24, 12, 0, 44,176, 81,149,245,248, 72,117,238, 9, 97,120, 54,187, 55, 44,226, -219, 91,136,193,227, 17,240, 24,128,199, 16, 36,102,170, 48,122,210, 44,139,119, 53,234, 29,155,218,135,157,251,185,101,251,198, - 65,214,245,119, 93, 37, 22,141, 59,246,181,201, 81,203, 62,221,185,255,108,191, 90, 45, 38, 92,167,148,253, 49,249,226,210, 19, -149,233,104, 52,154,204,246, 29, 58,154, 19,190, 92,118,106,223,166, 22,124,134, 64,111,164, 48, 24,203, 6, 65,102, 41, 69,217, -119, 75,217, 71, 12,101, 41,134, 14,253, 28,237, 59,116, 84,178, 6, 54,165, 26,133,198,214, 99,167, 46,219,105,244, 44, 22,173, - 88, 63,167,180, 48,123,206,179, 88,155, 68,153, 67,221,241,202,204,184, 3,166,159, 56,252,227,174,236,238,177,253,208, 53, 4, - 5,248,151, 13,212,204, 82,248,186,202,177,253,240, 53,248,249,250,149,165,155,165,168,235,102,134,150, 31, 14,172,225,245,141, -228,203, 29,252,118,116,237, 53,168, 87,207, 94,253, 97,109,101, 14,173, 78, 83,247,244,241, 35,191,172, 94,177,176, 41, 33,228, -211,106,153, 67,106,124,241, 94,160, 44,251,206,181, 28,206,206,206,118, 97, 97, 97, 47,254,111, 48, 24,224,233,233,137,212,212, - 84,223, 26,152, 53,153,179,179,243,135, 11, 23, 46,180,111,213,170,149,192,206,206, 14, 0,144,157,157,237,114,254,252,249,134, - 13, 27, 54,204, 74, 75, 75, 59,156,153,153,169,124,171,169, 96,213, 66, 30,229,243,196, 98,105,185,175, 5, 51,105,244,199,245, -237,236,236,222,248,113,156,155,155, 39,154, 57,115, 6,225,243, 5,101,219, 83,202, 80,214,248,214, 57, 70,154, 52,105,210, 85, -167,211, 73,222,244, 91,142,193,174,147,154, 21,245, 45,123,139, 0,124, 30, 47, 63,237,246, 30, 59,147, 77,123,253,110,237,156, - 24,193,234, 46,221,186,121,116,239, 20, 9, 39, 59, 11,156,185, 22,135,177,223,252, 4,189,193,184,180, 38,247,135,199,227,241, -179,178,178, 18,173,172,172, 28,223,195,251,182,246,254,237,203,237,207, 94,188, 53,245,103,241,206,145,117,154, 13,214,151,181, - 71, 42,155,153,197, 87, 98, 46,104,217,189,173,185,181,139,159,100,221,138, 5, 2, 46,130,245,242,141, 16,241,230, 54,107, 18, -102, 51,117,220,231,162,185,235,207,227,234,241,195,170,180,219,187,223,139,185, 82,216,251, 70, 16, 30,127, 56,225,241,228,132, - 33, 34,214,200, 38, 27,180,218,121,202,156,184,244,119,213,102, 89,138,223,175, 84,211,152, 83,234,253,203,207,139,236, 29, 44, -197, 80,235,140, 24,252,229,183, 88,187,116,142,194,206, 66, 4,141,206,136, 77, 7,110,229,212, 83, 46,161,131, 59,212, 30,248, -221,250,152, 63,126,220, 26,251, 71,217,179,250,214,140, 7,123, 11, 49,190,219, 25, 7,115,169, 0, 86, 10, 33, 24,230,205,230, -106,112,151, 50,205,130, 98,173,129, 16, 34,162,148,106,223,104, 36,156,130,154,155,219,185,238,233, 49,116,142, 93, 92, 38, 1, -133, 14,241,230, 18,124,244,201, 72,203, 58,142, 82,200, 37, 60, 36, 38,167,123,126, 53,121,114,168,196,201, 47, 76,157, 30,251, -188,170,211,246,240,240,232,217,185,115,103,217,196,137, 19, 5,110,110,110,216,186,251,184,251, 7,189,198,116, 73,205,200,117, - 99, 41,224, 96,111,157,252,121,223, 78, 7,143, 28, 57,146,148,156,156, 44, 88,184,112, 97,248,222,189,123, 3,170,243, 37,106, -164, 20,106,141, 17,198,242, 23, 99,118,161,166, 6, 47, 21,194,188,253,203,156,118,107, 31, 25,198, 95,178,239, 41,138,149, 6, -200, 68,124,196,167,151, 34, 34, 60,140,191,107, 29,105,245,166, 61, 62,239,243,225,116, 7, 51,218,161,107, 68,109,216, 91,201, -176,225,231,239,112,224,234,179, 14,153, 37, 4,182, 93, 23, 14,119, 18,243, 63,176,147, 9, 87, 68,134,122, 57,182, 14,113,199, -205, 80, 47,199, 11, 81,143,226,234,245, 89, 60, 58,181, 68,112, 42,239,232,232, 55, 26, 45,134, 48,176, 86, 8,177,254,120, 18, -100, 18, 62,228, 18, 62,228,226,178,191, 12, 67,222, 41, 95, 75,157, 3,220,120,172,241,115,115,231,128,207,251,245,233,237,252, -113,191,222, 20, 60, 6,187,127, 63,216,109,219,182,173,233,102,142,190,235,140, 12,111,189, 42,237, 65,114,213,215, 19,176,183, - 16,225,171,117,247, 97, 46, 21, 64, 33, 19,192, 92, 38, 64,235,250,118, 53, 78, 39, 33,196,106, 68,183, 58,157,238,110,105,219, -202,183,150,153,207,157,248,194, 7,159,207,187,181,244, 92, 65,171,113, 63, 47, 9,176, 41, 41,208,242,103, 76, 26,202, 79, 73, - 75,107,181,251,224,249,214,206,141, 62,127,100,208,149,126,157,117,231,183,253,111,210, 75,142,189,210,208, 53,162,183, 68, 87, -162,191,119,231, 81,138, 87,190, 70,140,152,196, 34,200, 37,124,152, 85, 92, 91, 9, 31,114,137, 0,102, 18, 62,210, 82, 18,144, - 87,202,187,148,106,195,180,162,231,174, 84,171, 42, 74,173, 51,226,246,179, 18,120,248, 6,195,201,201, 25,218, 78, 3, 60,174, -159,249,125,191,220,201,127, 65,105,250,195,175, 77,213,217,126,232, 26,230, 46, 88,242, 24, 4, 15,203,223,230,254, 19, 39,140, -246,249,105,241,138, 87,214,141,252, 98,148, 79, 77,205,181,204,193,119, 91,203, 15, 63,233, 85,175,113, 59, 60, 77, 72,192,209, -131,183,208,230,131,142,232,212,165, 39,180, 90,205,192,245,107,151,223, 4,176,242, 79,101,174,147,127,179,122, 65,254,219, 92, -156,157,221, 88,182,108, 14, 88, 74,129,102, 45, 91, 99,242,184,161, 96, 41, 69,131,134,141, 90,119,234, 55,154, 82, 90,102, 4, -115,114,115, 74, 31,197, 62,104,171,202,140,189,110,242,181, 84,171,245,217,217,217,184,125,251, 54,226,226,226, 16, 19, 19,131, -220,220, 92, 88, 88, 88, 84,171,138,221,202,202,202, 60, 52, 52,244,227,223,126,251, 77, 98, 97,241, 31,207,175,213,106, 33,147, -201,208,181,107, 87, 65,179,102,205, 92, 6, 13, 26, 52,200,202,202,106,123,126,126,126,209, 27, 13,211,221, 67,105,142,245,186, -175,233,212,107,216, 72, 0, 16,138,205,158, 45,251,245,143,152,202,142, 45,148,152,187,183,237,254,153, 23, 40, 5, 33,100, 89, - 78,236, 31, 25,111,219, 86,167,211, 73,119,237,218,229, 66, 8,121,229,253, 58,123,217,206,166,247,159,100,180, 89, 61,107, 10, -223,220, 76,130,236, 2, 13,134,143, 28,109,107,178,185,170,215,109, 84, 88,195,134, 43,191,157, 52, 20,114,153, 20, 39,174, 63, -197,248,105,223, 27,242,114, 50,183,128,144, 37,217, 49,123,223,181,214,226,189, 76,247,230,227, 98, 6, 69,251, 8,201,208, 62, -145, 18,173,222,136,130, 82, 61, 52, 58, 35,140, 44, 69, 97,169, 30, 15,158, 23,195,214, 92,132,117,248,231, 83, 45,131,197, 23, -136, 58,143,249,180,147,104,209,246,235,184,122,124,187, 42, 45,122,183,172,226, 55,183,208,126,207,146,111,237,172,253,170, 71, -169,186,171,165,212, 57,192,141, 79,120,139, 91, 70,182,104, 55,114,212, 40,248,214,113, 21, 26,141, 70,122, 63,238,153,126,211, -250, 13,159, 90,184,213, 91, 90,148,114,127,122,197,203,180,186,221, 55, 89,150, 77,121, 61, 98,197,178,175,126,205,190, 73,147, - 16,192,210, 76,132, 53, 71, 19, 64, 41, 64, 64, 97, 33, 23, 96,231,185, 20, 20,230,166,229,212, 87, 46,185,252,121, 7,219,174, -243,214, 63,216,191,234, 96,102, 20,128, 24, 74,105,230,219, 52, 9, 33,224,243, 8,204,101, 2, 88,200,132,176,148, 11,193, 16, -242, 86,115,245,237, 47,119, 55, 1,120,244,178,185,122, 89, 83,238,224, 27,104,110,235,190,175,231,136, 5, 86,119,159,235,192, -231, 17,212,118,148,194, 90, 33,132,214, 64,144,152,173, 43,223,199, 28, 95, 76,156,109, 55,101,194,200, 35,132, 68,214,167,244, -156,161,178,115, 87, 42,149,162, 79, 62,249, 68,160,215,235,117,131,199,206,107,151,145,149,219,109,233,252,201, 98, 59, 91, 27, -148,170,245,136,126,152,228,255,253,162,159,107, 31, 62,125,109,223,215, 95,244,216,223,161, 67, 7,139, 93,187,118,177,213,185, -239,217,153, 57, 63,111,216,182,103,203,146, 69,243,241, 40, 41, 31,235,215,174, 4, 53, 26,214, 84,238,119, 95,213, 92,177, 98, -133, 67,120,120, 56,115,227,198,141,156,215, 13, 40, 33,144,231, 22,105, 96, 41, 23, 66, 38,230,195,193, 74, 2, 27, 51, 17, 68, - 2, 6, 12,243,159, 66,228,101,205,245,191, 29,158,199, 42, 11,113, 96,135,182,223,134,159,191,195,103, 95,126,131,251, 57,162, - 99,140,204, 98,222, 23,253,122, 78,181,147, 26, 59, 56, 91, 50,246,173, 67, 60, 32,151, 8, 49,109,204, 39,104, 20,149,104,159, - 90,192,126,147,173,226, 5, 3,248,230, 77,233,100,202, 35, 86, 10,153, 0,231, 14,237,200, 42, 45, 46, 40, 36,188,178, 42, 66, -189, 86,151,100,154,215,255,243,245,148, 59,248, 78, 13, 9,174,255,221,200, 97,159, 51, 77, 35, 26, 81,134, 17, 32,167, 88, 75, - 40, 5,198,141, 30,129, 47, 70, 12,117, 76, 78,203,154,177,114,229,154,233,102,246,254,115, 75,178, 30,206,170, 76,147, 71, 24, - 48, 12,129,153,132, 15, 51,105,153, 97, 49,147,240,161,214, 26, 65, 8,120,174, 33,253, 10, 65, 0, 66, 72, 90,242,205, 29,254, -166,164,211,185, 94,199,211,231,179,132,126,202, 35,234,171, 79, 30, 71,207,187,113,247,249, 13, 74,105, 94,173,150, 19, 6,233, - 12, 20, 37,106, 3, 18, 50,149, 48,232, 40,249,172,163, 59, 60,123, 17,223,249, 27,162,183, 16, 66,204, 43, 34, 46,175,107,166, - 92,221,173,182,173,215,179,239,146,229,107,111, 46,250,238, 27, 94, 78,161, 22, 44,165,144,136,120,144,138,248,229, 11, 15,170, -210, 66,172, 92,253,107,134, 1,164, 39, 61, 87,121,158,255,115,161, 65, 7,244,232,212, 98, 39, 1, 68,132, 17,166, 56,187,123, -184,183,233,242,169,164, 77,215, 79, 96, 52,104,167,202, 29,252,206,150,102,198,158, 54, 69, 51, 40,192, 31, 32,120,152,117,111, - 95,207,178,151,100,247, 63,252,124,253,124, 94, 95,231,237,237,235, 99,202,125,175,248,184,144,218,249, 12,243,246,171, 55,121, -228,183,107, 61, 18,210,149,176,118,243, 65,204,189,219, 56,186,235,231,104, 85,113,254,162,163, 7,254,152, 60,247,135,101, 13, -186,116,239,131,253,123,119, 77, 36,132,172,162,101,156,122, 41, 58, 53, 96,211,186, 95,220, 4, 34, 49,244, 6, 22,122, 35, 45, -251,107, 48, 34, 47, 47, 31,122, 3, 11,137, 76, 1, 3, 75,160, 55,178,208, 27, 88,104,180, 6,249,136, 79, 62, 28, 5,224,250, -155,210,233, 25,254,201, 45, 48,196,181,108,125,217, 58, 17, 99,161,116,114,114,218, 2, 0, 98,177, 24, 98,177, 24, 44,203,226, - 94, 26, 25,231, 28, 54, 96, 26,104,249,155,157,101, 83,210,163,119,132,190,237,220,221,220,220,186,188,110,174,212,106, 53, 74, - 74, 74,112,249,230, 93,139,205,187, 79,117, 72, 76,206,168,195, 26,237, 53, 82,199, 6,237, 1,116,121,219,245,204,184,183,111, - 84,173,200,113,204,196,145,159,120, 47,251,117,207,141,199,199,230, 86, 26, 78,174,221,118,170,118,242,168,254,161, 63, 44,219, -240, 56,229,252,210,241, 85,221, 35,161, 80, 40,200,206,206,126,241,124,207, 89,241,123,199,231,153, 69,109, 22,125, 55, 93, 24, -253,172, 4,247, 18, 50, 48,168,109, 45,147,159,119,167,192, 30,190,238,158,110, 75,151,206, 29,139,184, 52, 21, 86,252,126, 3, -231, 15,111,137,210,169,139, 63,204,138, 57,144, 85,147, 50,228, 93, 13, 86,101,154,103,239,230,160, 68,109,128, 70,107,128,158, -165, 40, 82,234,145, 85,160, 69,145, 82,135, 18,149, 1,131, 62,168,133,127, 3,213, 50, 88, 70,131,222,213,217,217, 9, 44, 77, -169,136,112,150, 69, 61,194,251, 41,199, 15,235, 45,117, 14,238, 85,154,118,123,143,201,109,178, 20,246,117,155, 72,165,178,195, - 63,253,244, 19,250,117,105, 46,125,158,163, 47,185,251, 92,149, 89,170,133,193,222,174,174,104,222,252,239,205,190, 95,248,227, - 23,135, 14,176, 5, 0,126,124, 99,248, 57,172,255, 45, 30,121,169,141, 21, 33,160, 44,155,146,114,115,123, 40, 0,188, 75, 91, -171, 18,181, 30, 60,166,172,237, 12, 33,128, 82,109, 64,105,126, 70,238,203,230,234,122,170,227, 83, 30, 47, 91, 71, 41,173,180, - 10,130, 33, 64,145, 82, 15, 11,153, 0,150,102, 2, 88,200,255, 19,193,122,139,185,138,169, 76, 83,168,211, 37, 27, 13, 90, 53, - 53, 26,209, 57,204, 14,246,150, 34, 56, 89,137, 33, 22,241,161, 55, 0, 42, 45, 11,181,214,136,196, 44, 21,138, 85, 34,212,143, -236,235,157,230,116, 77,105,235, 17,182, 41, 39,241,230,240, 74,239,179,209,136,109,123,142,123,167,101,100,119,219,191,101,177, - 56,171, 72,135, 59,137, 37,200, 42,208, 0,196, 2, 83,191,153, 46,158, 49, 99,102,247,109,191,159, 72,106, 25,238,159, 84,221, -235, 90,154, 21,187,181,126,211, 15,127,238,220,185,187, 34,230,250, 17, 60,190,125,250,219,146,204,234,181,191,242,246,246, 54, -252,252,243,207,118,107,215,174,245,182,183,183,127,158,149,149,245,172,162, 58,202, 51, 32, 34,237,212,233,139, 54, 45,154, 54, -231,167,228,168, 97,163, 16,194,195, 65,142,168,171,103,181, 12, 33,199,222,164, 87, 94, 13,216,223,181,237, 20, 28,184,250,172, - 67, 76,174,228,220,208,207, 7, 37,157,184,240, 40,119,197,150, 19, 63,184,152,233,111, 75,216,236, 21,183, 66,189, 28,167,142, -254, 4, 11,150,111,197,249,168, 71, 89,165,140,211,119,233, 26,195,201, 89,125, 39,191, 57,234,203, 0,124, 30,129, 66, 42, 64, -105,105, 65,225,253, 83,171,234,190,167,103,119,208,137,125, 91,153,188, 98, 61,146,115,212, 36, 45,175, 24, 70,150,194, 82, 38, -132,129,165, 40,200,203, 33,219,182,110,193,205,155, 87, 25,240,152, 33, 0,102, 85, 17, 9, 1,143, 33, 48,147, 8,202, 34, 64, -210,178,191,122, 35, 11,159,218,110, 88, 54,103,140,185,173,189, 3,218,245, 28,110,122,132, 77,110,213, 96,243,234,121, 56,119, -245,118,228,217, 39, 59,194,236,131, 26, 44,119, 13,232,189,136,177,118, 81,107,116, 70, 20, 22,228, 67,164, 77, 70, 35,151,108, - 88,203,140, 72, 44,114,194,253,140,199,102, 85, 85,103,229,220,251,227,182, 93, 80,143,233,123, 14,158, 89,208,254,131, 72,220, - 79, 44,130, 84,196,135, 68,196,131, 68,196,131,128, 24,177,120,245, 26,125,126, 97,113,231,156,251,251,114,106,144, 63, 79, 1, -120,209,230,204,204,161,142,221,214,229,211, 55, 15,157,188,176,125,135, 30,159,146,251, 55,207,126, 13,224,180, 73,101, 38, 75, - 77, 90,199,178,166,189,219, 8, 33,140,189, 87,232,246,141,155,118,244, 13,240,113, 67,102,129, 30,105,249, 58, 92,140,142,199, -230,117,211, 11,242, 51,159, 14,128,174,164,132, 37,134,194,227,199, 14, 30,251,114,236,100, 4, 6, 53,240, 40, 74, 41, 50, 7, - 80,248,202, 49,121,100,237,192,207,135,247,117,112,112, 80,252, 39,130, 69, 81,215, 55, 0,157,186,126,132,227,251,247,226, 65, -204, 93,176,180,108, 56, 31,150,165, 40,200,207,205, 48,232,181,155,222,154, 62, 30,207,117,227,154, 69,246, 12, 67,160,211,179, -208, 26, 88, 76,157, 58, 93, 59,118,198,138,102,237,155,214,143,225,129, 45,122,158, 94, 96, 25,245, 40,163, 30, 17, 40,156, 6, -140,152, 34, 84,107,140, 40, 84,234,113,106,247,178,183, 87, 51,214,105, 16,225,233,223,236,243, 97,223,172, 17,139,121,140, 46, -176,174,219,179,150,141, 3,147,107, 57,219, 22,207, 95,182,173,209,149,232, 71,157,122,246,236, 41,233, 91,199,159, 56,219, 72, - 20, 35, 70,141,174,239,232,211,108, 96,198,227, 75, 91,222,250,242,227,139, 11,220, 92,221, 94, 84, 37,218, 7,117,191, 11,192, -253,181,205,146,178,238,239,171, 15, 0,246, 14,142,106, 34, 16, 23, 87,195,128, 80, 0,152,189,124, 79,167,148,236,146, 94, 21, -230,234,246,211, 66,136,133, 12,116,122,211,155,198, 25, 9, 29, 55,101,244,103,130,188, 82, 3,206,221,205, 70,204,173,179,212, -160, 43,250,148, 18,254, 96,187,160,238, 3, 9,224, 73,129, 4,134,224, 23, 45,131, 77, 5,119,246, 21, 86,191,166,167, 44, 61, -246, 1, 61,155, 16, 30, 58,241,248,194, 48,128,245, 51,232,245,246, 12,143,151,147,113,103, 79,149, 61, 40, 95, 62,163,210,204, - 56, 44,156, 63, 3,203,214,237, 69, 90,174, 26, 22,198,100,236, 95, 63, 15, 19, 23,108,135, 74, 99,196,191, 1,147, 13,150, 67, -189,110,141, 0,134,231,104,109, 6,239,218,110, 48,235, 61, 88,234, 26,210,183,148,199, 99,152, 77, 75,191,150,228,170,248,224, -243,120,165, 38, 23,190, 14,126,225, 10,133,226,200, 31,191,239, 69,157, 90,246,194,109, 23,243, 18,162,159,169, 94,132,116,139, -178,147, 68,158,230, 74,126,207, 30, 61,100,167,207,156, 29,247, 54,131,197, 35,140,235,178,197, 63,216, 43,164, 2, 16, 2, 20, -171, 12, 24, 59, 97,202, 59, 95, 24, 10,202,251,114,194, 76,144,114,115, 85, 92,152,135,239,150,109, 42,233,233,114,230, 82,133, -185, 58,241, 80,250,164, 71,143,214,133,137,137,137,249, 85, 22,140,212,152,210,107,208, 88, 33,195,148, 85, 27, 49,132,128,194, -152, 89, 19,115, 5, 0,249,249,207,138,164,142,245,123,108, 93, 50,122, 93, 45, 23, 23, 43,133, 76, 66,204,228, 98,226,239,235, - 37,105,220, 56, 66, 82,203, 43, 80,116,225, 65, 9,158,103,171,240, 44,173, 16, 34,219, 64, 65,223,150,109,177,117,217,148, 78, -166,156,255,153,171,247,187,172, 90, 52, 93,156, 81,160, 69,236,243, 18,100,228,171,145,158,175, 65, 70,158, 26,102, 82, 1, 34, -218,246, 20, 31, 61,185,187, 75,203,112,255,229, 53,185,190, 79,227,159,237, 77, 76, 77,255,180,126,195, 70,216,182,121, 99, 99, -226,234, 42,161, 41, 41,106, 83,247, 95,183,110, 93, 94, 88, 88,152,221,247,223,127, 95,234,235,235, 27,236,235,235, 91, 59, 46, - 46,238,156,183,183,119,215, 85,203,230,158, 31,251,205, 34,119, 30,209, 91, 52,105,218,140, 39, 17, 18, 92,189,112, 92,179,105, -221,154, 52, 93, 65,201,228, 74,141,176,204, 98, 94,102, 9,129,157,139, 75,140,153,200,248, 1,159, 41,136,203, 59, 58,122, 11, -128, 63,188, 58,142, 57,117,246,214,163,184,208,168, 68,251, 51, 81, 79,178,242,148,186,186,241, 71, 39, 84, 90,224,242, 8,129, -128,199, 64, 33,229,191,136, 88, 58, 52,232,253,132, 18, 98, 87, 17, 41, 37, 40,139,104,145,178,207,150,180,148,168, 93, 38, 52, -140, 38,148,165,192,163,148, 82,148,168,203, 66,240,174,182, 50,100,103,166, 96,213,242, 77,136,190,117, 19,237, 58,118,197,202, - 95,183, 97,232,192,222, 85, 94, 87,134, 65, 89, 4,235,165,232,149,153,148, 15,128,160,160, 84,143,223, 47, 37,195,171, 54, 3, - 82,141,218, 66,133,153, 20,133,197, 42, 48, 2, 51,196, 94,220, 34, 59,122,246,198,180, 89, 63,174,255,170,168, 36,227,121,252, -131,171,240,181,202, 69,109, 23, 29, 98, 50,204,113, 43,215, 19,190,222,117,192, 8,111,154,164,157, 19, 83,111,225,126,230,247, -206,161,193, 1, 17,238,246,150, 80,105,141,229, 81, 44, 30, 54,110,216,130,196,132,148,207,115, 98,246, 69,191,143, 66,178, 36, -243,105,182,196,193,231,139,123,215, 79, 63,235,241,241, 23,112,114,169,213,160, 58,205, 19, 76, 89,103, 52,193, 96, 17, 66, 24, -107,143,224,205,155,183,238,238, 91,187,150, 35, 78, 94, 79,192,141,184, 92,216,218,218,128, 39,115,132, 79,203,193,150,247,142, - 45,251, 72,149, 83,178, 89, 32,148, 13, 9,111,220, 20,148, 82, 60,122, 24,147, 87, 88,104,241,167,178, 89,153, 22,123, 27,128, -249,203,235,100,118,254, 13,204, 44,172,111,107,116, 70,164,166,166,224,242,149,115, 13,203,183, 51, 25,177,144,135, 19,209, 89, -208,233, 89,232, 12, 44,194, 67, 2,181, 2,145,180,249, 15,235, 14, 55,206,204,204,102,164,102,230,172,133,125, 29,161,181, 62, - 67,115,231,105,161, 80,167,103, 81,199,185,242,239,114,153,117,157,249, 19, 38,142,245,231, 9,165, 40, 46,213,104,211,211, 82, - 29,127,217,113,182,228,225,163, 7, 46,158, 30,181,204,231,205,157, 37, 44, 84, 1, 89,133, 26,228, 21,235, 72,159,143, 63,119, -222,178,126,229, 0, 0, 91,170,145,244,122,187,182,172,209, 91,153, 9, 73,177, 74, 79,179, 11, 53,198, 81, 95,140,173,247, 46, -121,167,194, 92,253,248,221, 55,194,232,103, 37,184,243,180, 16, 18, 33, 15, 34, 33, 3,173,137, 6,203, 46,160,183,220,206,206, -114, 64,120, 3, 31, 28,143,206, 6,143,199, 64, 89, 90,168,149,136,205,238,251,249,249, 48,193, 13,130, 16,217,172, 9,226,159, - 37,250, 30, 63,121,102,201,141,155,209,223,217, 5,245,152,156,125,127,239,202,234,164, 53, 57, 61, 87,150,105,112, 27,107,239, -104, 27,212,181, 91, 23,113, 45, 23, 7, 98,103,109, 9, 35, 17, 98,196,200, 47,237, 77,206,243,180, 44,122,249,253,220,105,208, -104,180,176,179, 20,129, 82, 96,195,242, 89,208,106,181,112,182, 17,163,176, 84,207, 25,172, 23, 55,184,126,143,166, 82,177,252, -196,202, 5,227,152,130, 82, 61, 36, 66, 30,234,212,169,141,209, 99,199,201,218, 52,176,131,138,152,227,247, 29,155,138, 12, 70, -253, 33, 83,244,100,142, 62,161, 10,185,249,241,205, 91,119,177,182, 54, 54,204,170, 19,217, 79,115,139, 13, 47,134, 56,136,187, -126,128,189,117,252, 23, 39, 10,114, 76, 34,145,120,107,181, 90,171,170,110,232,134, 19, 73,229,141,115,201,123,185, 48, 12,195, - 24,127, 89, 62, 23,182,230, 34,104,244, 44,230, 44,217, 82,220,217,238,216,153,151,205, 85, 72, 72, 72, 97,131, 6, 13, 10, 24, -166,234,225,196,158,223,216,214,228, 13, 5,102,141,204, 85, 5,170,140,187, 55, 1, 4,189,170, 25, 34,176,245,220, 61,177,223, -128,129,211, 28, 3, 63, 84, 36,164, 23, 66, 72,116, 8,243,119,194,185,227,127,176,201,207, 30,142, 48, 69, 59, 43,183,208,205, -214,214, 6,209, 79,139,145,154,171, 66, 70,185,185, 74,207,215,160, 88, 85,140, 6, 30,118, 40, 40, 44,113,171,177,129, 37,116, -223,241,227,199, 63,237,212,173, 47, 70,127, 53,187,227,186, 85,139,238, 74, 29,252, 7,170, 50, 31,222, 48,101,255,221,187,119, - 27, 61, 60, 60,158,102,103,103, 55,154, 52,105, 82, 81,157, 58,117, 28,231,206,157, 59,172, 78,157, 58,206,173, 91,181, 42,188, -113,182,241,230,177, 95,205,106, 53,117,204,186,218, 12,195,100, 82,150, 30, 72, 43,213,207,164,217, 15, 84,149,222,167,253,211, - 98, 73,192,236, 79, 63,104,110,119,192, 90,198, 4,138,169,182, 31, 9,152,189,139, 62,152,169,139, 63,186,188,184, 94,159,197, -163,211, 10,216,111,212,140,253,119, 85,153,171,178, 8, 22,129,214, 96,132, 66, 42,248, 79,222,164,112, 90,181, 98,177,204,206, - 66, 4, 1,143, 1,159, 71, 80,164,212, 35,167, 72,135,175, 38,127,101,234, 21,100, 13, 70, 10,149,214, 0,101,249,215, 96,113, - 81, 14,166,125, 53, 1, 29,187,244,192,144, 17, 19,144,175, 2,110, 61, 43,134, 78,175,175,242,161,224, 17, 2,165,198,128,207, -218,185, 35,175, 68,135, 82,149, 1, 90, 3, 11,153,136, 15, 62,159,129, 92,194,135,185, 76, 0, 66,168,208,201,201,105, 24, 0, - 8, 4, 2,245,243,231,207,183, 86,242, 5, 15, 79, 55, 7,168,244, 12, 26,245, 93,132,182, 17,117,113,231,212,122,254,249,107, -247,106,127, 53,107, 9, 70,245,143,192,158, 88, 47, 88,219,187,195, 76, 46,133,158, 50, 0, 76, 27, 2,132,210,153,172,147, 95, -207,254,107,126,221,240,104,206,140,169,146,130, 82, 2,177,144,135, 51,167, 79,225,234,245, 91,203,178, 99,246,109,125,159, 5, -165,128, 50, 14,230,230,230,144,136,120,208,234, 52, 90,147, 35, 15, 44, 5, 40,252,237,235,117,255,163,252,222,251, 27, 89,188, - 97, 29,173,202, 92, 17, 11,231,160,141,107,214,109, 27,224,236,104,143,189,167,239, 98,227,175, 43, 80, 59,184, 51, 46, 29,222, - 8, 11,207,198,144,215,106, 6,145, 98,247, 48,134,199,175,247,229,184,175,123,134,132, 69,224,242,197, 51,200,202, 72, 95, 67, -105,172, 73,109,208,120, 2, 50,166,245, 7, 93,160,214, 26,209,188, 77,103, 28, 59,184,119, 52,202, 59, 79,152,202,235, 38,156, -101, 97,248,114, 72, 63, 65, 86,129, 86,144, 93,164, 69, 74,182, 18, 9,153, 74,236,223,185,158,154,250,214,102,248,188,176, 22, -245, 93, 5,195, 22,158, 73,118,115,117,210, 8, 52, 42,105, 92,252, 83,191, 33,159, 14, 16,212,246,246, 99,178, 10, 53,200, 46, -212, 32,167, 80,131, 18,181, 1,222, 78,181, 24,141,129, 31, 81,221,251,108,103, 41, 17,172, 60,248, 12,230,114, 1,154,248,217, -212,184, 17, 54,203,178,175,152,171,219,207, 74,113,247, 89, 33,196, 66, 30,196, 66, 6, 98, 33, 15, 6, 35, 53,241, 93,100,232, - 55,124,112, 95,169, 86, 79,145, 91,168, 5,159, 71,224,104,107, 35,118,115,170,139, 13,139,190, 4, 0, 12,157,178, 10, 67, 62, -251, 4,190,117,189, 81, 88, 88, 44, 29, 50,114,236, 98,188,161,221,221,219,210,186,109,255,133,128, 91,247,147, 38,126, 58,120, -144,160, 79,151,230,204,237,167, 69, 72,207,211,224,105,188, 18, 58,125,245, 70,163, 49, 24, 89, 80, 80,108,218,117, 8, 82, 17, - 31,217,133, 58, 80, 74, 49,111,197,111, 80, 72, 5, 72,207, 47,171,214,231, 12, 86,133,185, 18, 73, 78,108, 89,241,181,244, 76, - 28,176,236,228, 45,124, 24,238, 4, 33,159,129,216,204, 17,119,158,229,227,212,233,253,197,151,174, 94, 87,131,209, 87,217, 45, - 74,230,228,219, 80, 46, 53, 63,181,242,151,205, 6, 91,123,123,108,189,152,151,146, 95,106,208,255,167,122, 74, 79,110, 29,255, -165,182,129,213,119, 80,101, 60,174,242,115,150,165, 84,184, 96,245,126, 0, 20, 44,203,130,178, 44,120, 66,177,220,189,241, 39, -153,101,122,172,132,207, 99,212, 47, 63,249,148, 53,166, 36, 93,223, 94,105,213, 33, 1, 96, 33, 19, 96,215,249, 84, 20,230,165, -229,116,182, 59,246,162, 90,240, 88,140,248, 73, 72, 72,112, 97, 88, 88, 88,129, 84, 42, 5,143,199,171,246,133,127, 87,115,245, -246, 23, 79,148, 30,192,247,206,126, 45,187,118,148, 5,134,139, 24, 62, 66,124,157,112,238,196, 94,246,234,209,245, 61,148,153, -113,135, 77, 12,111,163, 68,165, 71, 90,174, 26,169,185,106,100,228,171,145,145,167, 65, 70,190, 26,132, 16,168,181,239, 54,124, -141, 50, 51,238,160,153, 75,224, 26,141, 14, 35, 90,180,235,129,137,179, 86,122,111, 93,243,195, 69,185,189, 79, 88,105,214,227, -123,166,104, 36, 38, 38,106, 28, 28, 28,162, 10, 10, 10,218, 45, 89,178,164,196,223,223, 95,100,102,102,150, 11, 64,250, 36, 46, - 78,120,230,200,238,132,236,180,180,225, 58,157,238,166,169,233,242,136, 28, 44,246, 51,207, 27, 86, 75,222,164,125, 29, 71, 25, -106,201,139,219,251,153,221,249,209,190,205,184,249, 89,167,151,102,165,107, 12, 39,179, 85,188,224,212, 18,129, 73,109, 1, 13, - 58,109,210,199,195,167,129, 71, 8,116, 26,109, 82, 69,230,178,183, 16, 97,214,182, 88,152, 73, 4, 80, 72,249, 48,147, 10,208, - 44,192, 26,213,248, 60,160,122, 35, 11,165,198, 8,149,198, 0,181,214, 0, 91, 55, 43,252,186,117, 55,158,103,169,176,255,102, - 14, 30, 37, 21,195,199, 85, 14, 74,171,142, 59,177,212, 80,218,103,216, 55, 10, 30,195,128, 71,192,248,121,123, 32,175, 68, 11, - 33,159,129, 72, 36,130, 92,204,135,185, 84, 0, 1, 95,128, 27,119,239, 66,163,209, 32, 60, 60, 92, 82,185, 5, 44,139, 98,249, -212,118,134, 78,111,192,145, 11, 15,240,221,248,158,248,160, 69, 40,190,226,137, 16,171,105, 8,133,181, 2, 44,195, 64,103, 96, -161,213, 25, 1, 48,111,141,182,213,170, 85,171,181, 92, 46,151, 43,149,202,226,164,164,164,115,233,177,127, 60,183, 15,236, 62, -236,216,137, 51, 91, 59,119,252, 0,209,119, 99,176,103,239,129,139, 57, 54,133,147, 42,246, 9, 10, 10,106,108,107,107,107,150, -155,155, 91,116,239,222,189, 27, 53,201,171,132, 16, 34,119,240, 27, 23,209, 44, 18, 37, 5, 89,200, 76, 78, 56,100,234,190,254, -238, 10, 76, 24, 63,218,199,183,174,175,143,177,188, 39, 85, 64, 45, 5, 70,140, 28,229,227,229, 83,215,167,162,163,135,127,173, -202,199,187,148, 59,248,142,250,110,241,234,129,181,220,220,112,244,114, 44, 22,124, 51, 34, 90, 46, 83,120,186, 58, 88, 89, 10, - 3, 67,113,251,246, 21,216, 67, 4,115, 7, 31,215,126, 93,135,187,182,239,216, 21,247,238,220,194,210,133,115,175,150,242,164, -243, 77, 73,171,153, 67, 29,187,224,176, 22, 31, 43,172, 29, 80, 80, 88, 12,133,149, 61,252,235,135,125,108,230, 80,103, 74, 73, -230,211,236,154, 62,235, 44,165,208,232, 40,242, 75,116, 72,206, 86, 33, 49,163,204, 96,177,108, 53,218,252, 80, 16, 51, 9,159, -111,173,127, 82,235,222,169, 51,212,221,205,129, 44,156,251, 21, 79,135,178,198,226,217,133, 26,100, 23,105,145, 93,168, 69,137, - 90, 15,107, 57, 31, 44,101,171,253,181,157, 95,162,131,162,188,157,172,145,173,185, 9,152,181,100, 71,147,148,108,101,155, 31, -231,125, 35,188,147,240,146,185, 18,148, 69,175,196, 66, 30,140,172,105, 17, 44, 30,159, 25,253, 97,155, 70, 72,206, 81,149,245, - 66,102, 8,188, 3, 27,194, 86,202,162, 77,223,169, 0,128, 46,157,202,134, 33,121,150, 94,138,131,215,210, 1, 64,104,106, 90, -115,115,139,197,123, 79, 70,143,221,241,235,143, 34, 13, 43,192,218,163, 73, 80,106, 12,144, 8,121, 16, 11,121,144, 10,171,247, -126, 51, 24,203, 58, 75, 60,207,209, 67,169, 86,163, 72,165, 7, 5,112,227, 73, 9, 84, 90, 3, 10, 75,245,104,236,103,197, 25, -172, 10,115,181,121,249,215,210,211,113, 20,103,239,228,162, 87,115, 87,228,102,165,224,215, 85,203, 88, 74, 1,177, 68,148, 97, - 52,176, 71, 85,172, 97,114,193,157,131,133,149, 22, 18,118, 1,245,165, 50,217,153, 31,150,174,213,217, 59,184,176,127, 92, 43, -200, 42, 84, 26, 95,137, 21, 26, 53, 26,134,178, 84,104,138,185, 42,143, 52,233,102,142,238, 1,150, 82,204, 90,186, 27,243, 39, -245,133,153,148, 47, 35,132,200, 74,213, 6,140,159,189, 14, 63,125,251,185, 66, 38,230,131, 16, 64,173, 53, 98,196,104,211,162, - 4, 74,141, 17,165, 5, 25,185,245, 74, 22,191,102,174, 66, 10,195,195,195, 11,172,172,172, 80, 19,131,245, 38,115,229,232,232, -232, 44,147,201,172,125,124,202,218,186,242,120, 60, 24,141,198,210,199,143, 31,215,104,208,183,162,130,236,125,233, 9,247,194, -155, 68,126,136,243, 39,246,177, 87,143,172,235, 81,157, 46,230,150, 22,230,201,209, 15,146,252, 9,204,202, 34, 88,229,230, 74, -171,103,225,238, 32, 67, 74,242,115, 88, 90,152, 37,155,170, 39,115,244,233,192, 80,222,112,150,224, 87,101, 70,236, 17, 0, 40, - 73,141, 25, 41,179,175,123, 47, 38,230,206,210,206,253, 71,139,218,245, 26, 41, 92,179,224,139,169, 0,250,153,170,155,153,153, -169,180,179,179,187,234,228,228,212,121,246,236,217, 26, 0, 98,141, 70,195, 12, 30, 60, 88,150,148,148, 52,158, 82,106, 82, 26, -155,127,182,199,150,136,139, 59,122,249,132,245,119, 87, 20,127,208,170,121, 4, 34, 2,221,144,220, 60, 2, 0,198, 36,149,152, -249, 54, 27,185,126, 87,109, 59,215, 35,107, 54, 30,156, 63,180,111,219,241,206, 93,102, 47, 78, 59, 56,179,210,136,216,163, 11, -235,219,191,201,190,243,121, 12, 20, 82, 1,204,164,124, 40,164, 2, 40, 36, 2,232, 13,180, 58, 85,112, 84,111, 96,203, 34, 88, - 90, 3, 74, 84, 6,156,185,157,137,140, 66, 45, 10,138,117, 80,233,140,160,160,208,233,217,138, 81, 69, 42, 55,171, 87, 54, 89, - 86,252,219, 53,164, 95,225,178, 57,163,205,127,191,148,242,162,135,158,133, 76, 4,133, 76, 0,128,226,194,133, 11,176,177,169, -122, 88, 44,150,101,177,231,216, 13, 44,222,116, 6,199, 54, 76,134, 68,200, 67,253,110,179,241,105,247,112,176, 44, 69,252,163, -152, 76,159,128, 6, 14, 12, 35, 5, 67, 8, 52,122, 22, 0,125,235,245,212,106,181, 54,207,159, 63, 47,242,246,246,118,116,113, -113,233,197,227,241,168, 24,208,236,219,153,167, 60,125,104,187,172, 84,165, 49,202, 12,133, 27,188,211, 85, 31,250,248,248,128, - 16, 66,109,109,109,133,103,206,156, 41,169, 87,175,158, 93, 77,158, 35, 66, 8, 35,181,175,187,108,200,200,113,189,188,234,212, -193,238,237, 27, 64, 41,249,221,212,253,183, 29,188,138,197, 75, 94,237, 49, 56, 98,228, 40,159, 53,171, 87,189,178,110,224,231, -195,124, 42, 51,120,174, 65,173, 39,251,249, 5,224,106, 76, 10, 22, 78, 31, 25,173,206,122,214, 95,107,102, 51, 92, 87,146, 62, - 33,184, 97, 40, 28,109,204,145,150,167, 65,215, 1,221,209,180, 89,115,220,187,115, 11,115,191,253,234, 42,148,218,118, 85, 69, -109,255, 99,132, 4, 35, 90,181,239, 46, 80,105,116, 88,190,112, 6,134, 79,250, 14,141, 91,119, 17,220,191,125,109, 4,128, 57, -166,158,179, 70,103, 68,171,122,182,101,166, 89,207,226,192, 51, 30,255, 77, 57,144,207, 35, 76,112, 29, 75,168,180, 6, 20, 41, -245, 85, 68,176, 72, 70, 65,113,169,199,207,243,199,241, 74,213, 6,100, 23,106,145, 85,168, 65, 78,193,127,140, 85, 78,161, 6, -217,133, 90, 8,248, 4,113, 9,105,224,241, 72,181,219,223,229,151,232,209,168,174, 85,217, 51, 90,195,218,144, 28,131, 93,199, - 59,113,105,109, 22,206,157, 38,188,147, 88,138,187,207,138,202, 35, 87, 60,136, 5, 12, 68,229,255, 54,154,224,175,236, 3,186, - 54, 25,216,175, 91,160,185, 92,130,180,184, 98,240,121,101, 67,189, 88,216,187,193, 66,172,198,151, 35,135,193,214,198, 18,207, -115, 52, 88,182, 55, 14,119, 31, 60, 1,171,170,222,105,255,188,253, 88,143, 65,159,244, 21,243,132, 98,108, 57,148, 0,177,144, - 7, 62,213, 34,230,218, 5, 77,102, 74,130,174,184,168, 64,206,231, 11, 76, 18, 37, 0,173,136,204,205,159, 53, 21, 59, 55,173, -194,241,168,172, 23,205,231, 47,253,254, 19,198, 77,155,135,156, 34, 45, 0,242,143, 15, 99,241, 43, 51, 87, 18,145,232,196,166, -101,211,164,167,227,128,115,119,203,204,149,170, 36, 7, 91,214,175, 45,161, 96,219,102,222,223,111,242, 23,161,220,190,110,144, - 88, 46, 63, 63,125,222, 50,141,131,139,135,225,200,237,162,220, 98,181,241, 79, 97, 16,161, 76,110,148, 91,216,169, 45,221, 27, - 46, 22,168,180, 51,178,179, 31,148, 86, 21,105, 98, 41,197,161,235, 25,160,180,236,147,232,183, 11,169,224, 49,101,213,133, 70, -182,172,250,228,228,237, 44,240, 25, 98,114,151,115, 66,128,223, 78,220,206, 9,122,131,185, 10, 11, 11, 43, 48, 55, 55,135,165, -165, 37,204,204,204,170, 91, 96,191, 49,114, 37,147,201,172,143, 31, 63, 46, 49, 55, 55, 7,143,199,131, 70,163,193, 7, 31,124, - 80,163,155, 42,119,240,237,215,184, 77,207, 5, 77, 91,125,136,179,199,255, 96,175, 30,217,216, 83,153, 85,141,241,123, 0,116, -108, 81,255,224, 15, 63,173,168,253,213,212,233, 98,133,132,143,135, 37, 90, 48,132,192,221, 65, 6, 27, 51, 30,174,158, 57,164, -238,245, 65,189,131,166,234,213,114,245,216,178,104,249, 26,155,197,223,207,110,103,101, 85,219, 33, 63,255, 89, 17, 0, 40,179, -226,214,152, 57,250, 62,114,173,117,226,124,131,150, 61,224,224,226,221,169,186,231,155,157,157,157, 25, 24, 24,248, 48, 32, 32, - 32,180, 87,175, 94,116,193,130, 5, 86, 41, 41, 41,187, 77, 53, 87,192,255,177,119,214,225, 81, 92,251, 27,127,207,250,102,227, -196, 29, 72, 8, 9, 17,220, 10, 65,131, 59,148, 2, 69, 74,105,145,150, 10, 82,161,180, 72,169, 64, 75,129, 42,180,208,226,238, -165,184,187, 75,132, 4,136,187,103, 37,155,213,217, 57,191, 63, 32,185,129, 27,217, 0,253,221,123,233,249, 60,207, 60,217, 36, -179,239,156, 51,115,102,206, 59,223, 99, 64,207, 94,225, 51,236,164,150, 14, 13, 20,130,240, 64, 79, 5, 58,134, 63,108,253, 28, - 53,160, 51,252,252,253,145,156, 87,222,178,164,156, 23,151, 25,133,129, 63,255,122,231, 90, 35, 87,225,155,156,206, 24, 15, 96, - 95,189, 43,109,252,171,227,123, 69,244,202,222, 70, 12,254, 97,249,168,151,193, 50,152, 44,208, 25, 44,208, 25, 57,104,141, 22, -148, 27, 45,224,233,195,123,130, 16, 2, 19,199, 87, 28,178, 94, 9,116,104,224,138,192, 70, 15, 71,189,218,219, 60,156,178,225, - 97, 19, 33,224,226,226, 2,119,247,186, 27,119, 40,165, 48,154, 30,222,226, 70, 51, 95,217, 68,106, 52,113,160,148,226,222,189, -196, 15,211, 82, 82,134, 52, 9,110,210, 37,172,121,139, 6, 10,153, 0, 0,106, 52, 3,229,229,229, 22,123,123,123,247, 6, 13, - 26, 8,178,179,179, 43,251, 61, 54,105,217,157,219,179,123, 23,134, 15, 31, 86,118,247,234,237,202, 17, 85, 58,157,142,116,234, -212,201,193,207,207, 79, 96, 48, 24,212,245,142, 90,185, 53, 29,234, 23,250,210,151,227, 39, 78,105,218, 61,186, 47, 78,157, 56, -138,125,187,183,172,215, 22, 36, 30,181, 86, 39, 36, 36,244,223, 70, 17, 6, 5, 55,253,183, 81,132, 13, 27, 7,215,104,176, 28, - 29,155, 59, 52,111,219,205, 47,173,200,132, 67,135, 14, 66,171,202,251,204,104, 44, 43,135,152,174, 57,176,229,231, 73,111,188, -191,208,161, 91,215, 40, 56, 59, 40, 32, 18, 9,113,227,218, 37, 44,254,252,147, 75, 40, 55,246,174,235,249, 89,153,223,176, 48, - 73, 19,255,134,239,249, 7, 69,224,198,229,115, 72,186, 23, 27,119,251,218,165,240, 38,145, 29,224,230, 29,240, 30, 9, 11, 91, - 76,227,227,235, 92,169,130, 90, 44, 89, 19, 38,207,124,116,253, 31,254,173, 99,203,198, 82,242,228, 13, 0,192,204,153, 44, 27, - 86, 45, 46,168, 58,138,176, 38, 93,189, 70,185,243,236,229, 59,179, 7,245,142, 18, 20,169,141, 15, 35, 86, 42,227,163,205,128, -162,138,207,106, 3,130,189,237,144, 20,123,151, 55,107, 85,187,234,119,103,210,252,105,111,189, 99,243, 48,237, 60, 40, 79,107, - 53,252, 53,166,213, 34,121,117,213,231, 31,147, 59,105, 90,220, 73, 85, 63,108, 18, 20, 11, 31, 26, 43,177,160,210,108, 89,213, - 74, 38, 16,124, 51,126,100, 31, 20,169, 77,224,121, 64, 36, 20, 60,218, 36,200,208, 16,100,106,202, 81, 84, 90,136,148,180,116, - 40,243,146, 32, 16, 8,224,234,221, 20,229, 25,214,165, 85, 99,177,107,106,182, 32,104,228,128, 40,225,158, 75,121, 80,200, 68, - 80, 23,103,226,194,145,109, 58,158,179,172, 50,154,141, 91,221,169, 52, 54, 62,102,135,201,202, 71, 71,161, 90,107,240,144,137, -133,216,177,238, 39,140,124,109, 90, 69, 4, 18, 0,240,225,220, 69,128,128,160, 84,169, 5, 64,158, 58, 42,250, 63,111,176,196, - 2,225,177,181, 43, 62,145,199, 23,202,113, 53, 49, 23, 47, 71,249,162, 92, 83,132, 95,127,250,190, 76,111, 54,244, 43,140,217, - 87,191,112,187, 64,208,103,212,235,179,227, 2,155,134, 25, 78,197,150,165, 42,181,230, 26,251, 49,116,124,249,211,184,235,127, -253,216, 95,101, 78,126,203,206, 59,220,194,115,220, 55,229, 5,137, 11,171,127, 75,166,210,133,223,239,168,108, 30,252,104,241, -134,135,159, 45, 22, 88, 40, 15,202, 3,211, 63, 91, 9,142,183,128,183, 88,192, 91, 40,136,217,162,168, 51, 92, 46,151, 28,141, - 40, 91,230, 88,157,185,114,114,114,130,139,139, 11, 92, 92, 92, 80, 97,136,158,181, 89, 48, 56, 56, 24,118,118,118, 56,119,238, - 28,108,108,108, 96,107,251,116, 19,228,219,121,132,190,210,190,199,176, 77,221, 7,189, 46, 56,190,231, 87,203,149,211, 7, 94, -214, 21, 36, 88,109, 2, 44, 22, 11, 49,155,205,232,211,173,117,250,173,196,140,195,159, 47, 92,208,183,109,143, 17,178,151, 66, -220,161, 51,114,200,206,202,194,165,147,251,244, 77,252, 93,142,116,109,223, 44,221,108, 54,195, 98,177,212, 89,129,235, 13,198, - 98,161,216,198,101,212,232, 87,101,215,174, 94,221,100,235, 17,178, 69, 32,228,111, 83,139,176, 57, 64, 95,105,222,188, 25, 76, -102, 30,229,229,154,146,167,201,119,124,124,252,213,229,203,151, 55, 21,139,197,126,219,183,111, 47, 42, 45, 45,173,215,114, 65, - 71,207, 38,174, 16,145,210,251, 82,222, 52, 38,192, 94,211, 43,163,115, 71,140, 30,216, 25, 91,255, 58,143,211,231, 46, 33,189, -204,238, 86, 25, 39,218,155,153,158, 99, 8,111,160,222, 53,184, 99, 67,225,142,117,165,187,220,187,207,121,133, 82,217,209,194, -211,243,181,214, 87,222,128, 70,103,134,131,226,225,124, 77, 21,145, 44, 33, 33, 86, 59, 33, 2,164,156,187,116, 35,162, 77,112, - 24,110,166,168, 80,160, 52, 64,103,224,192,243, 20, 60, 40, 92,236,165,144, 75, 4,200, 72, 75, 1, 79, 77,169,245,171,103, 80, -216,111,196, 20,209,195,227,240, 34,177, 88, 4,250,168, 94,180,145, 75,203,220,221,221,173,138, 96,153, 56, 14,195,251,182, 71, -135,182,205, 49,100,202, 82, 0,192,137,245, 31,195,217, 78,140,157, 59,119, 34,227,252,242,141,129, 47, 77, 59, 26, 27, 19, 55, - 34,238,230,197, 87,251,181,182,105,233, 41,202,169,177,105,163,172,172,108, 23, 33, 68, 42,145, 72,250,118,233,210,165,193,174, - 93,187,148,174,174,174,188, 84, 34, 41, 28, 60,104, 32, 47,150, 72, 42,203,206,133, 11, 23,196, 83,166, 76,177, 47, 45, 45,205, -200,207,207,191, 68, 41, 53,215,254, 2, 24, 26, 13, 1,182,128, 16,185,157,141, 34,189, 99,244,104,239,182, 29,218, 59, 14, 29, - 62, 18, 50,169, 12,199,142, 30,198, 15,203, 23,111, 47,203,189,251,122,125, 78,229,243, 24, 69,168, 82, 57,106,239,199,223, 46, - 77, 45, 48, 58,139,157,130, 33,150,217, 79, 33,142,222,223, 11,101,118,243,221, 90, 12,117,216,185,255, 32, 98, 98, 99,209,192, -198,140,228,164,251,229,177,183,110,254, 82, 78,196, 11,105, 97,124,185,213, 17,230, 98,203,136,142,227,250, 58, 27, 76, 22,156, - 61,249,151,158,231,248,190,151,206, 28, 76,242,109,218, 86, 30,209,182,167,115,209,190, 53,195, 1,108,173, 75, 39,245,202,198, -127,235,122, 17,216,254,149,156,131, 71,207,216,121, 5, 52, 17, 18, 8,161,215,149,163, 48, 61,134,211,171,242,202,243, 99,246, -122, 91,147,190,116, 46,251,179,207,190, 94,249, 86,155, 22,225,182,148, 74, 30,139, 88, 85, 24,171, 34,181, 17,174,246, 82, 24, -180,165, 72,186,115, 78, 95, 40,206,255,164,246,103,157, 89, 81, 92, 92, 34,173,248,221,166,204,169,161,202, 81, 37,171, 52,129, - 66,192, 81,229,100,248, 87, 83, 90,137,212, 98, 49, 43,172,185, 61, 29,237,228,136, 73,205,173,236,208, 46, 19, 63,236,123, 37, - 21, 11, 43,251, 97, 89,121,159,183, 22, 73,237,144, 93,172, 7, 1, 5,111,225,192,153,141,208,168,213,200,206,201, 67,126, 94, - 62, 52, 26, 37, 20,118,206,136,104,217, 14,246,118,182, 72,184,113, 26, 0,177,234,229, 87,207, 75,130,219,182,105, 35,142, 75, - 47,131,201,204, 67, 12, 19,206, 31,218,170, 55,155,141,131,242, 99,246,158,172,239,115,152,227,233,241,216,196,244,112, 95, 55, - 47,114, 43, 73,133,141,171,127,132,241, 81, 36,211,108,182, 32, 54, 67,139,220,146,114,100,101,166, 83,240,150,227,120,193,169, -209, 96,113, 28, 39,247, 15,104,132,209, 83,198,226,151, 95, 86,226, 94,114, 6,126,251,249,145,185,186,179,231,130,149,134, 34, -186, 98,174, 12,109, 94,194, 55,175,255,146,154,181,255,102,137, 64,103,172,125,253, 41,185, 91, 0,162, 94,255,238,136, 78, 83, - 34,181, 24,202, 69,127,110,124,125, 75,117,154, 15,125, 27, 49,126, 57,107, 20,236,108, 68, 32,132,160,162, 89,240,231, 69,147, -161,144, 9, 65, 8,129,206,192, 97,236,140,101,216,184,108, 38, 40,128, 55,222,154, 85, 94, 83, 58,171, 24, 33, 50,177,111,227, -193, 95,252, 30,191,239,124,154, 75,242,128, 1, 93, 85,173, 91,183, 86,218,216,216,192,198,198, 6, 14, 14, 14,112,118,118,134, -147,147, 83,157,121,127,244,187, 71, 93,125,174, 4, 2, 1,108,109,109, 97,103,103, 7, 91, 91,219,127, 51,110, 79,106,254,155, -185,242,108, 58,178, 93,247, 97, 91,122, 12,158, 36, 56,190,231, 55,254,250,233, 63, 71,234, 10, 18,247, 90,123,141, 30, 53,235, -220, 30, 62,124,120,228,148, 41, 83, 36,159,188, 53,252,200,145,211, 55,238,237, 62,182,107, 80,137, 82,227, 71, 41,133,147,163, - 93,230,203,189, 34,255,140,106, 27,146,126,226,196, 9,126,203,150, 45, 6, 66, 72, 76, 93,233, 44, 42, 42, 88,123,226,248,201, - 37, 81, 93,187, 97,245,186, 45, 3,226,226,239, 14, 72, 74,186, 15,191,128, 64, 52,106, 28,140,114,226,140,147,103,206, 65, 83, -146,183,214,154,116, 86, 37, 50, 50,210,167, 69,139, 22,190, 74,165, 82, 63,111,222,188, 16, 74,233,222,136,136,136, 54,173, 91, -183,206,187,121,243,102, 86, 77,195,254,171,106, 94, 92, 57,180, 16,192,250,134,221, 38,110,207, 54, 41,223, 3,176,216, 63,192, - 31,167,207, 93,194,165,243, 87, 86, 22, 41,252, 23,190, 62,118,226,228,134,131,133,111, 12,238,216, 80,232,238,172,192,230,223, -190, 19,238,191,148,182, 44,173,216,178, 6,192, 34,107,174, 81,229,195, 90, 99, 66,167,102, 13, 96,182, 80,240,244,161,233,178, -151,139,171,109, 34,172, 78, 83,100,148,189, 62,117,202,148,164,136,230, 45,223, 31, 59,113,170,164,101,160, 31,174, 62, 80, 2, -132,160,129,167, 45,114,115,115,113,118,231,111, 92,105,118,194, 74,161,144,255,188, 62,231, 51,235,198,214, 38, 21,159,189,188, -188, 38,223,138,141,197,233,211,167, 81, 97,172,220,220,220,170, 53, 88, 79,106,150,150,106, 46, 44, 90,186,186,211,155,227,134, - 96, 96,183,112,156,185,150, 4,227,163,249,150, 42,134,132,167, 92, 90, 37,125,111, 84,160,241,173,225, 77,213, 58,179, 52,237, -179, 84,213,217,170,147,200, 62,169, 73, 41, 53, 18, 66,246, 39, 38, 38,118,110,209,162, 69,195,131, 7, 15,150,196, 93, 57,242, -216, 68,119,179,102,205,178,251,229,151, 95, 20,148,210, 11, 6,131, 33,217,170,188, 11,176,249,198,245,235, 46, 38, 51,143,115, - 87,110, 55,235,217,169, 37,120, 10, 92,187,118, 13,107,126, 95,163,143,185,115,107,169, 54,223,243,243,154, 38,183,173,233,124, - 90,158, 97, 20, 97,133, 38,165,167, 57, 59,143,208,149, 23,206,157,153, 43,243,110,131,208,254,159, 12,206,190,189,127,176,103, - 88, 31,184, 6,190,132,156, 59,251,113,225,200,166,131, 60,199,125, 44,231, 5,233,218,194, 4,173,181,247,123, 5, 50, 27,197, - 59, 97,173,187, 34, 35, 61, 13,169,247, 99,215,235,138,239,231,216,121,134,174,207,201, 74,159,218, 56,188, 19,206, 31,217,250, -110, 77, 6,171,174, 50,239, 46,215,172, 60,117,254,226,232,236, 29,251, 61, 52,101, 58, 27,145, 72, 80, 46, 19,145,124, 73,121, -210, 54,107,211, 73,227,227, 77,238, 65, 47, 13, 31, 51,229,211,191,150,125, 61, 87,236,225, 36, 67, 94,169, 30,106,157, 9,154, -114, 19, 4,132,160,137,183, 45,116, 90, 53, 46, 29,220, 96,182,232,139, 71,209, 7,143, 71,220,170,106,186,133, 15,249,130, 16, - 76,255,244,211, 57, 16, 74, 29,188, 27,247,252,196, 36,104,236, 9,103, 60, 49,153,121, 3,160,113,207, 79, 96,208,228, 15,250, -244,211, 57, 33,148,210,158,110,225, 67, 52, 21,107, 17,214,148,247, 98,141, 9,175,118,247,131,137,123, 56,127, 24,199, 3, 22, -254,225, 11, 63,165, 0,173,165,221,190,170, 38, 5, 36,219,254,186,128,156,124, 37,116, 70, 51, 12, 70, 14, 38,179, 5, 2,161, - 16, 78,206, 78, 8,110,212, 10, 78, 78,142, 40, 40, 42,194,181, 75,231,113, 57,241, 86, 10, 5,190, 40,106,160,218,100,205, 53, - 34, 34,219, 38, 30,238,174, 36, 95,109,132,141, 84,136,203, 55, 78,155, 41,176,214, 26,115, 85,157,166,170, 92,185,236,227, 69, -223,143,249,229,187,249,158,145,141, 29,144, 85,164, 67, 86,161, 30, 26,253,195,247, 27,206,194,195,168, 83, 33,241,218,161, 60, - 14,229,203,254,185, 17, 44,177,216,112,237, 78,162,236,227,133,223,226,238,131, 20,172, 89,249,163,214, 96, 54, 89,109,174,170, -227,143,183, 26,109,173,223, 55, 30,205, 91,250,121, 90, 29, 47,220, 79, 52, 11, 82, 30, 60,165,248,243, 74, 94,101,179, 32,255, -168, 71,229,205, 36,101, 93,133, 70,252,237, 59, 45, 63,172, 48, 66, 63,236,201,190, 44,147, 21,241, 25, 25, 25,165,155, 54,109, -170, 52, 61, 66,161, 16, 21,163, 7,141, 70, 99,157,163,138,156, 29,164,225,227,250, 53, 28, 85,147,185, 18, 10,133,224,121, 30, - 14, 14, 14,176,177,177,169,119,211,163,173,123, 72,175,118, 61,134,109,237, 49,228, 13,193,137,189,171,249,235,167,247,191, 92, - 86,144,184,167,190,215,168,180,180, 52,142, 16,114,127,233,210,165, 45,215,172, 89,211,120,246,236,217,201,171,191,158,250,195, -195, 55,184,135,203, 34,222,188,121,147, 78,155, 54,205,160,215,235, 83, 74, 75, 75,111, 88,179,200,117,121,126,226,210, 63,126, - 89, 18,146,153,157,251, 90, 96, 68, 59,184, 53,110, 7,207, 38,237, 81,170, 49,225,234,131, 28, 36,223, 61,129,248, 11, 59,183, -233, 10, 61,190,170, 79,122, 91,182,108,233, 47, 22,139, 7, 1, 8,177,177,177,105, 72, 8,145,138,197,226, 87, 8, 33,247, 9, - 33,119, 67, 66, 66, 78,160,134,229,139,170, 35,237,244, 90, 67,195,110, 19,191, 79,215,216,119, 79,206, 43,111,149,174,177,191, - 89, 46,115,156, 89,112, 98,133,193,163,247,210,101,212, 84, 20,183, 99,157,122,215,230,223,190, 19,142,157, 60,203, 18,171,114, -126, 79,100, 35, 61,246,245,107,214,143,230, 22, 16,146, 59,123,246, 7,255,154,166,225, 81,228,234,209,148, 13, 57,214,104, 60, - 90, 79,241, 35, 27,239,240,159, 98,223,155,178,168,121,219, 78,227,186,244, 27, 37,224, 36,118, 56,178,103, 21, 77,185,115,114, -135,136, 90,230,150, 23, 36,165, 60,235, 67,194,104, 52,214,105,174,170,109,186,117, 81,117,251,235,232,233,215, 14, 28, 62,243, -117,191, 94,157, 93,126,254,236, 21,124,251,235, 94,216,218,200, 64,121, 11, 70,245,240,127,249,238,150, 62,131,252, 60,228, 62, -187, 78,101,157,157,190, 60,246,163,242,114,211,189,186,214,206,123,100,152,207,217,219,219, 23,118,238,220,185,131, 76, 38, 35, - 69, 69, 69, 34,119,119,119,206,209,209,209,152,149,149, 85,110, 48, 24,118, 81, 74,181,245,201,167,201,204, 35, 53, 95,143,125, -187,119,225,246,149, 19,184,123, 55, 81,115, 55,254,238,143, 68, 68,151,151,229,221,123,170,200, 42, 95,237, 40, 66, 90,239, 81, -132, 90,161,205, 87, 55, 15,124,219, 45,184,199,187, 29, 93,130, 58,193, 57,224, 97,160, 72,149, 21,139,204,107, 59,246,105,114, - 36, 35, 41,141,125,234,177,239,222,190,141,131,169, 80,138,139,167,255, 2,229,249,149, 0, 64,121,126,229,205,243, 7,167,182, -239,255, 6, 26,184, 55,108, 65, 8, 33,245, 93,143, 17, 0,100, 2,147,234,175,117, 95,237, 72, 77, 77, 69, 66, 66, 2, 30, 60, -120,128,146,146, 18,108, 78, 61,171,170,143, 78, 65,210,197, 99, 30, 77,187,244, 25,243,250,140, 63,135,141, 24, 38,247,111,212, - 68, 16,226,235, 0, 87, 59, 17, 18, 83,178,145, 20,123,159,127,112,231,172,158,234, 10,134, 22, 61,184, 80,163,225,115, 11, 27, -233, 33, 16,146,143, 79,236,127,184,182, 96,244,144,215, 67, 62,156, 62,187, 67, 3, 23,231,106,159,227, 37,197,165,210, 5, 11, -230,133, 84,236, 95,215, 90,132, 2,161, 80, 51,121,234, 59,182, 2, 34, 64,197,233,162, 21,109,100,149, 63, 30,126,144,136, 69, -117,150,209,137,195,162,192,241, 60,180, 58, 51, 52, 58, 35, 84, 26, 3,114,139,148,136,187,251, 0, 87,206, 29, 70,106,210,125, - 13,199,113,167, 64,177,187,208, 69,181,237,201,137,117,107, 45,159, 16,250, 55,112,118, 64,154, 82, 15,185, 84,132,156,140, 36, -206,196,233,159,122,146,245,162, 91,251,115, 61, 34,134,244,158,248,214, 39,135,187,116,137,114,108,222,170,141,194,213,193, 1, - 18, 17,144,148, 81,128, 59, 55,174,106,211,239,221, 82, 91,204,186,190, 69,177,251,159,121,149,150,255, 89,131,101,178,112,209, -179, 62, 89,124,212, 98,177,216,136,132, 66,157,153,242,125,159,197, 92,253, 93, 80,202,103,189,245,238, 7,149, 81, 93, 0, 48, - 91,120,155, 55,222,154,173,171,250,134, 64,204, 22, 69, 69,228,170,142,145,122,194, 66,165, 65, 51,231,151,219,235,151,172,143, -223, 9, 32,254, 89, 71,246, 1, 64,169,218,120,219,165,215,246, 33,154,114,142, 0,184, 91,141,166,182, 71,143, 30,149,102,235, - 81,115,157,213, 21,132, 84,174,152,218,125,208,235,130, 19,251,214,240,215, 78,237, 27,249, 52,230,170, 74, 5,102, 2,112,133, - 16, 18, 59,119,238,220,182, 30, 30, 30, 30,243,230,205,147,171,213,106,241,207, 63,255,172, 47, 42, 42,202, 83,171,213,151, 40, -181,190,127,194,163, 74,115,162,141, 71,179, 85,100,231,154,222,206,238, 62,125,156, 92,253,154,150, 22,102, 37,169,139,179, 14, - 19, 30,199, 52, 5,137,151,234,155,214, 91,183,110,101, 68, 70, 70,238, 21, 10,133, 55, 0,184, 2,176,167,148,150,112, 28, 87, - 42, 22,139,243, 18, 19, 19,235,189, 32,107,218,233,181,134, 46,111,253,190,165,164,156,151, 24, 5,146, 45,105,167,215, 26, 0, - 32,255,232,236,114, 0,251, 60,186,127, 60,124,255,165,180, 31,226, 74, 29,223, 45, 56,245,213,254,250,234,103,223,220,214,228, -121,149,127, 93, 78, 92, 22,128,215,108, 61, 66,190,139,185,121,105, 62,161, 16, 91,192,125, 81,158,127,255,250,243,208, 23,139, -197,250, 54,109,218, 84, 59, 90, 80, 38,147,213, 58,191,214,163, 7,253, 26,210,173,219,186,195, 39,206,189,118,232,216,249,175, - 59,116,236,236, 34,247,245, 65,128,179, 9,235, 62,104,253,238,137,155,133, 87, 7,127,112,246,151,228, 28,253, 29, 74,169,190, - 62,105,211,104, 52,247, 8, 33,165,101,101,101, 67, 40,165,153,132, 16,191,210,210,210, 91,102,179, 57,166,222, 70,128,199,171, - 29, 59,182,219, 76, 8, 17, 81,142,255,230,146, 88,184, 69,159,123, 55,235,105, 12,197, 99,209,213, 70, 14,152, 60,117, 90,112, - 80,147,166,193, 21,107, 17,134, 55,180,199,216,137,111, 6, 55,108, 28, 28,252,175,245, 9,107,127,161,162, 57, 55,116,196, 35, -178, 87,226,209,165,159,185, 36, 93,120,203,166,129,175,157,182, 40,173,164, 52,237,250,210,242, 2,143,165, 79,174,208, 80, 95, - 82, 31,196, 45, 95,179,244,163,217,185,217, 41,107,180, 5,247, 98, 1, 64, 91,112, 47, 86,225,209,244,179,162,188,172,217,197, - 5,201, 75,159,246, 92,104,181,218,156, 77,155, 54, 57,117,234,212, 73,224,225,225,129,194,194, 66,156, 58,117,138,231,121, 62, -187,190, 90,249,247,206,158, 34, 65, 65, 13,182,172, 83,125, 35,178,177,239,207, 89,224, 77, 41, 32, 18, 32,215,100, 80, 29, 46, -116,210,125, 64,239, 92,170,189, 92,242, 22, 66, 5, 84, 80,177,182, 32,207,243,228,219,159, 54,164, 9,197,210,106,155, 84, 45, -102,163,130,231,121,171,215, 34,204, 23,166,187, 68,152, 67,173, 26,197, 23, 75, 18,234,120, 57,165, 71, 94,234, 55,190, 15,199, - 89,204, 0,244, 85,182, 2, 74,201, 73, 16,203,209,162, 6,154, 75,245, 49, 85,143,213,243, 38,147, 19,132, 18,216,219,152, 65, - 64,160, 86, 41,101,110, 22,233,221,103, 41, 75,249,177,251,226, 72,183,110, 1,198,227, 39, 39,156, 57,119,113, 36,229, 45,141, - 44, 20, 0, 37,169, 70,147,126, 71,129, 67,209,250,167, 77,239,255, 26,132,254,141,243, 81, 88,219, 92,242,223,166, 73, 8,145, - 60,170,172, 45, 85,151,191,121, 30,233,172,109,109,193,103,201,187,189, 87,179,206, 50,185,226,131,242,114,205,154,242,252,123, -127, 62,207,243, 73, 8,113,148,201,100,173,236,236,236,196, 69, 69, 69, 87, 40,165,170, 23,241,186, 87, 37,234,245,157,174, 61, -123,133,207, 56,122, 54,113,197,163,230,195, 74,124, 71, 46,151,143,235,223,125,214,250,221,251,254,109, 20,225,139,144,247,191, - 75,147,116,235, 38,114, 47,117,120,205, 98,225,191,232, 17,172, 41,207, 75, 73,156,118, 46,166,240, 10,165, 84,243, 44,233,148, - 74,165, 99, 77, 38,147,141, 68, 34,209, 25,141,198, 77,255, 45,121,119,143, 24,250, 57, 8,154, 89, 45, 66,113,183, 32,118,239, -188, 58,159, 33, 97, 97, 18, 69, 33,156,203,139, 92,139,235,107,172,254, 35,215,157, 16, 97,100,100,100,148, 68, 34,241,183, 88, - 44, 10,163,209, 88,174,211,233, 82,211,210,210, 46,214,180, 32,249,223,157, 78,143,200,161,203,197, 98,241,123, 0, 96, 54,155, -191,207,143,217, 59,163,182,239,214,180,255,255, 75,125, 52,114,164,144,238,216, 97,249, 59,174,145, 79,171,151,149,102, 51,231, - 88,241,187, 68, 44, 82,101,221,220,233,244,159, 42, 75, 47, 28,244,209,242, 8,127,199, 6, 32,154,105, 50, 77,166,201, 52,171, -217, 87,192,206, 39,211,252, 79,106,122, 53, 27,232,231,213,108,160,159,181,223,175,110,127,118, 62, 41,216, 86,243, 38, 98, 22, -147,193, 96,252, 7, 94,236,120,118, 22, 24,255, 73,114,226,255,204,252, 59,247,103, 48, 8,128,232, 26, 30,128, 86,135,254, 8, - 33,209, 79,241,128, 61,206, 52,153, 38,211,100,154, 76,147,105, 50,205,127,150,102, 93,218, 47, 76,211, 35,107, 34,100,154, 76, -147,105, 50, 77,166,201, 52,153, 38,107, 34,124,190,155, 0, 12, 6,131,193, 96, 48, 24,140,231, 10, 51, 88, 12, 6,131,193, 96, - 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,227,233, -249, 91,103,114,103, 48, 24, 12, 6,131,193,248, 39,194, 34, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, - 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, - 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96,252,231, 13, 22, 33, 36,154,105, 50, 77,166,201, 52,153, 38,211, -100,154, 76,147, 25, 44, 6,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, - 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227, 63, 4, 1, 80,237, 72, 0, 74,233,113,171, 69, -158, 98, 52, 65, 93,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,241, 52,235,210,174,143,255,248,175,134, 82,250,183,109, - 0,162,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,255,105, 27,107, 34,100, 48, 24, 12, 6,131,193,120,206, 48,131,197, - 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131, -193, 96, 48,158, 30,242,104, 52, 0,131,193, 96, 48, 24, 12, 6,227, 57,193, 34, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, - 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, - 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96,252,231, 13, 22, 33, 36,154,105, 50, 77,166, -201, 52,153, 38,211,100,154, 76,147, 25, 44, 6,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, - 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227, 63, 4, 1, 80,237, 72, 0, - 74,233,113,171, 69,158, 98, 52, 65, 93,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,241, 52,235,210,174,143,255,248,175, -134, 82,250,183,109, 0,162,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,255,105, 27,107, 34,100, 48, 24, 12, 6,131,193, -120,206, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, - 49, 24, 12, 6,131,193, 96, 48,158, 30,242,104, 52, 0,131,193, 96, 48, 24, 12, 6,227, 57,193, 34, 88, 12, 6,131,193, 96, 48, - 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, - 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96,252,231, 13, 22, 33, 36, -154,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,147, 25, 44, 6,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, - 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227, 63, 4, - 1, 80,237, 72, 0, 74,233,113,171, 69,158, 98, 52, 65, 93,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,241, 52,235,210, -174,143,255,248,175,134, 82,250,183,109, 0,162,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,255,105, 27,107, 34,100, 48, - 24, 12, 6,131,193,120,206, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, - 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,158, 30,242,104, 52, 0,131,193, 96, 48, 24, 12, 6,227, 57,193, 34, 88, 12, - 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, - 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96,252, -231, 13, 22, 33, 36,154,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,147, 25, 44, 6,131,193, 96, 48, 24, 12, 6, 51, 88, 12, - 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, - 12, 6,227, 63, 4, 1, 80,237, 72, 0, 74,233,113,171, 69,158, 98, 52, 65, 93,250, 76,147,105, 50, 77,166,201, 52,153, 38,211, -124,241, 52,235,210,174,143,255,248,175,134, 82,250,183,109, 0,162,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,255,105, - 27,107, 34,100, 48, 24, 12, 6,131,193,120,206,136,170,251,163,184,253,151,249, 28,199,185, 3,128, 72, 36, 42, 48, 95,253,212, -171, 54, 17, 63, 47,175,158, 22, 96, 53, 0, 8,129, 55, 51,115,114,142, 85,163,121,140,227, 56,231, 71,154,165,230,171,159,246, -169, 77, 83,220,238,139, 35,143,237,127,101,110,175,106,226,139, 66,113,187, 47,114,158, 72,171,119, 61,194,119,150,255,143,116, -254,175,104,254,147,145,116,248, 50,223,108,126, 88,142,196, 98, 81,129,233, 74,237,229, 72,210,254,139,156,199,246,191, 60,215, -163, 54, 77,133,141,172, 56,200,199,109, 89,109,154,201, 57, 69, 51,181,229,122,151,218, 52,255,103,238, 77, 43,241,244,244,108, - 35, 16, 8, 62, 37,132, 56, 84,249,243,157,236,236,236,247, 89,169,100, 48, 24, 47,156,193,226, 56,206,253,198,158,249,208, 26, -128,158,227,191,112, 15, 28,250,235,230,127,219, 71, 95, 42,213,221,223, 27, 41,133,214,217, 70,204, 57,220,191,127,159, 0,128, -183,183,247,106, 0,254,213,104, 58,223,216, 51, 31,229, 70,160,203,232,133,206,157,253,252, 28,242,132,194, 89, 50, 27,155,238, -122,189, 62, 28, 0,228,114,121,156, 65,167, 59,229,105,177,124,247,228,254, 53,101,160,106, 90,123,140,251,194, 61,116,232,175, -239, 90,120, 94,170, 75,222,209,133,215,164,139, 36, 22,227,207,175,229,230, 30,154, 15, 88,172, 57, 33, 85,143,219,117,212, 39, - 46,254, 94, 94, 61,164,114,121, 11,123, 7,135, 40,158,210,102, 60,207, 19, 11,199,197,107,203,202,206,241, 28,119,219, 98, 46, -119,185,177,247, 43,190,182,116, 62,153,151,145,128,232,178,167,231,203, 10, 91,219,238, 2,145,232, 37, 0,224, 57,238, 98,185, - 86,123,170, 67, 94,222, 78,107,242,110,237,249,121,218,253,255,105,152,205,156,123,202,145,249, 48,152,129, 86, 35,190,118,111, -254,234,250,205, 0, 96, 44,184,237, 81,118,127,127,123, 0,176, 13, 26,120, 69,230,217, 42, 31, 0, 68,233,185,238,247, 14,204, -133,193, 12, 52, 27,184,208,189, 46,205,137,243,182,187,124, 56,121,184, 12, 0,142,238,250,169,233,201,221, 43,251, 1, 64,143, -225,211, 14,245, 30, 49,253, 30, 0,124,243,219,110,151,173, 95,191, 82,171,166,117,247,166, 74,162,186,127,160,137, 81,157,235, -228,103, 43,242,188,127,255,190,160, 62,247,166, 47,224,152, 11,188, 45, 16, 10,163,130,154, 52,105, 5,128, 38, 39, 37,221,180, -112,220,121, 47,224,231,231, 89,150,132, 66,225,187,217,217,217,131,170,254,205,199,199,135, 21, 72, 6,131,241, 98, 26, 44, 0, -208, 26,128, 51, 15,128,174, 29,154, 99,242,171,253,237,170,254,111,247,239,139,252,179, 98,143,133,126,181,246, 27, 65,120,120, - 56,146,147,147,173, 58, 88,185, 17, 56,125, 31,144,233, 83,237, 11,164,210,164,121,159,126,234, 16, 21, 21, 37,242,242,122,248, - 18, 94, 80, 80,208,225,252,249,243,109, 22, 44, 88, 48, 85,166, 79, 45, 45, 55, 66,115,250,126,221,186, 21,105, 13,111,218, 16, -159, 78,127,197, 17, 0,150,207,222,217,230,224,197,219, 13, 82, 83, 83,123,126,245,213, 87,197, 62,151, 46,173,108, 96,177,172, -141, 41, 40,200,180, 38,157,219,142,220,146, 7, 25,143, 5,190, 60,113,226,174,128,128, 0, 59,111,111,111,162, 80, 40, 32, 20, - 10,161, 86,171,253, 19, 19, 19,251,221,190,125, 91,123,238,242, 62,105,204,237, 17,201, 89,194,150,122,107,242, 46,225,138,228, -177,193,193,113, 47,247,235,231, 59,112,224, 64,121,163, 70,141, 0, 0,169,169,169,193,127,253,245,215,232,131, 7, 15,206,147, -112, 69, 92,185, 17,250,186,242, 94,161, 9, 0,114,224, 37, 39,119,247,177, 66,177, 56,156,227, 56,159, 71,209,133,108,139,217, - 28,167, 44, 40,216,244,228,254,140,127,199, 96, 6,238,230, 2,209, 81,173, 48,110,120,180, 45, 0,124, 52,234,203, 14,233,169, - 15, 36, 70,163, 17, 77, 67,154,117, 90,244,245,178, 35, 16, 8,176,113,247,241,202,253,173,209,188,115, 55, 5,243, 23, 45, 71, - 78,204,206, 14, 22,213,131,238, 26,181, 74, 8, 0, 14,142,142,195,119,110,219,114,202, 59,242,229,203, 15,138, 76, 86,105,214, -118,111, 30,222,246,163, 87, 86,236,169,176, 95,142,254, 33,246,247,247, 71, 76, 76, 76,189,238, 77,168, 18,237,121, 47,175,248, -239, 62,248,192,179, 75,151, 46,176,179,179,131, 72, 36, 2,199,113,209,231,207,159,143,158, 63,127,254, 52,168, 18,181,214,222, -155, 86,240,157,183,183,119,247, 33, 35,198,122,117,239, 51, 16,195,251,118, 98, 5,145,193, 96,188,184, 6, 75, 36, 18, 21,244, -154,240,149,123, 84,251, 8, 92,187,125, 79,149,150,145, 91, 86,241, 63,229,221,221, 77, 71, 71, 7,133,173, 58,248, 23, 12, 6, - 3, 46, 92,184,128,219,183,111, 35, 53, 53, 21,115,231,206, 53, 8,129, 55,107,208, 44,237, 50,122,161,179,204,144,105,215,218, - 37,179,209,214,205,167,132, 58,157, 14,167, 79,159, 70,105,105, 41,164, 82, 41,124,125,125,209,185,115,103,209,233,211,167, 27, -140, 26, 51,214,177,247,208, 73, 41, 6,153, 95,153, 72, 36, 42,173, 49, 3, 34, 81, 65,207,241, 95,184,135, 5, 55, 68, 82, 90, -142,234,211,175,127, 47,227,121, 42, 42, 79,207, 50,157, 57,115, 6,173, 90,181,194,182,109,219, 92, 74, 75, 75, 63, 91,183,110, -221,167, 94, 63,174,253, 62, 55, 43,113,118, 45,122,165, 93, 70, 47,116,110,106, 57, 25,176,115,203, 31,146,219,183,111, 75, 86, -173, 90,133,226,226, 98, 72,165, 82, 56, 57, 57,193,211,211, 19, 77,155, 54, 37,111,191,253,182, 93,247,238,137,248,108,230,164, -128, 92,167, 33,137, 53,165,179, 66, 83, 98,204, 85, 4, 11,175, 7,173, 94,191, 94,208,174, 93, 59, 82,117, 31,127,127,127,116, -235,214, 77, 62,108,216,176,160,105,111,191,195, 71, 15,155,146,100,146,122,149,215,165, 9,109,166,141, 75,249, 37,239,232,209, -163,247, 47, 92,184,208,201,211,211, 19,182,182,182, 0, 0,149, 74,229,155,150,150,214, 97,222,188,121, 35,174,220,217, 38,234, - 50, 48, 51, 7,182,126,186,218,206,231, 63, 21,177, 88, 84, 80, 17, 53,178,183,181, 41,205,204,202,215, 2,128,209,104,132,209, -104,132,193, 96,192, 91,211,166, 8,223, 28,209,174, 73, 64,212,187,183, 82,179,243, 75,154, 29,191,220,160,226,187,117,105,138, -202, 83,149,202,140, 19,111,206,255,224, 3, 79, 15,143,127,181,252,109,220,176, 65, 88, 82, 82, 18, 61,127,254,252, 48,170,232, -166,108, 54,112,161, 83,109,154,181,222,155,247,254,106,180,104,122,159, 22,191,126,125, 0, 22,139, 5,151, 46, 93,194,217,179, -103,177,108,217, 50,122,232,208, 33,149,131,173,109,173,247, 38, 84,137,246,157,189,242, 2,151, 44,217, 69,100, 50, 25,246,237, -219,135,132,132, 4, 8, 4, 2, 52,111,222, 28,227,198,141, 67,116,116,180,231,228,201, 83,104,151,190,163,146,225, 24,162,121, -150,178, 68, 8, 17,120,121,121,189,251,214,251,159,120, 13, 31,253, 26,126,252,246,115,102,176, 24, 12,198,139, 67,181,189,223, - 1, 65,227,161,191,110,221,113,157,255,171,241,208, 95,183, 82, 64, 64, 1,129, 3,208, 48, 42, 42,202,172, 84, 42,233,213,171, - 87,233, 91,111,189,165,253,254,251,239, 79,253,245,215, 95, 59, 57,147,105, 77,171, 22, 45,150, 82, 64, 80,147,102,115, 71, 71, -199,192,192,192,194,204,204, 76,122,240,224, 65,186, 96,193, 2,186,105,211, 38,122,232,208, 33,122,252,248,113,122,232,208, 33, -186,117,235, 86,122,231,206, 29,250,224,193, 3, 26, 20, 20, 84,216,220,209,209,177, 22, 77, 33, 5,132, 77,135,174,154,189,235, -154,121, 97,200,208, 95,103, 80, 64,216,204,195, 35,180, 87,175, 94,150,157, 59,119,210,141, 27, 55,210,245,235,215,211, 59,119, -238,208,162,162, 34,234, 19, 16, 88, 88,241,189,154,210, 73, 1, 65,171, 86,173, 10,149, 74, 37,245,243,243,163, 82,169,148,122, -120,120,208,166, 77,155,210, 14, 29, 58,208,126,253,250,209, 87, 95,125,149,126,246,217,103, 84,169, 84,210,128,128,128,252,138, -239,213,164, 57,208,203,203, 38, 40, 40, 40, 35, 38, 38,134,214,132, 78,167,163, 69, 69, 69,244,228,201,147, 52, 40, 40, 40, 99, -160,151,151, 77,109,154, 54, 64,235,200,200,200,194,162,162, 34,106, 50,153,104, 70, 70, 6,141,141,141,165, 9, 9, 9, 52, 35, - 35,131,234,116,186, 74,237,123,247,238,209,192,192,192, 66, 27,160,117,141,154,255,228,173,162, 76, 60,177,249,123,120,244,243, -244,244,212,237,218,181,139,102,103,103,211,117,235,214, 81, 1,240,229,191,237, 91,139,166, 20,232,221,185,115,103,203,165, 75, -151,232,173, 91,183,232,199, 31,127, 76,251,244,233, 67,251,246,237, 75,231,207,159, 79,179,178,178,104, 86, 86, 22,237,215,175, -159, 69, 10,244,174,171,124, 86,119,111, 58, 2,254, 3, 7, 14,212,153, 76, 38,154,156,156, 76,195,195,195,179,132,192, 88, 91, - 32,172, 43, 32,171,171,124,250, 0,206, 94, 94, 94,185,151, 46, 93,162,187,119,239,166, 1, 1, 1,133, 66, 96,162, 3,208,216, - 1,104, 44, 4, 38, 54,110,220,184,240,210,165, 75,180,184,184,152,250,251,251,231,250, 0,206, 79, 91,150, 0, 8,188,188,188, -254,248,226,155,159,104, 98,150,150,126,241,205, 79,212,203,203, 43,131, 82, 74,189,188,188,142,177, 50,201, 54,182,177,237,127, -125, 19,213,203,140,217,218,126,181,104,209, 34,145, 94,175,199,239,191,255,174, 25, 51,106,212,110, 39, 39, 39, 78, 44, 22,131, - 8,234, 30,144,168,113,116,124,111,238,156, 57, 78, 6,131, 1,215,175, 95, 71,155, 54,109, 32,147,201, 32,145, 72, 32, 22,139, - 33, 22,139,225,229,229,133,130,130, 2,132,135,135, 99,234,212,169,142, 63,255,248,227,123, 80,169, 22,213,166,203,243, 84, 4, - 0, 22,158,151, 54,244,246,158, 28, 26, 25,185,116,218,180,105, 2, 91, 91, 91,232,245,122, 24, 12, 6, 36, 36, 36,192,197,197, - 5, 10, 27, 27,171,242, 44, 16, 8, 4,118,118,118, 56,121,242, 36,126,251,237, 55,164,166,166, 34, 55, 55, 23,246,246,246, 8, - 15, 15, 71,179,102,205,208,181,107, 87, 36, 39, 39,131, 16, 66,234,210,139, 23,139,223, 30, 55,122,180,123, 68, 68, 68,181,255, -215,235,245, 80, 42,149, 80,169, 84,240,240,240, 64,191,126,253,220,255,220,183,239,109, 0,223, 85,183,191, 11,224,233, 27, 28, -188,255,234,213,171,174,148, 82,108,220,184, 17,101,101,101, 48, 26,141, 16, 8, 4,144,203,229,112,118,118, 70,143, 30, 61,224, -230,230,134,224,224, 96,108,223,190,221,181, 95,191,126, 7, 92, 10, 10, 90, 23, 3, 57,236,245,162,110,210,243,243,143,246, 6, - 92,199,190,250,234,161,219,119,238, 68,141, 29, 59, 22,249,249,249,159,136, 63,254, 88,105, 6,150,215,245,253, 16,192,177,129, -151,215,218, 37, 75,150, 8,242,242,242, 48,107,214,172,162,156,244,244,143, 29,129,115, 0,112,226,240,225,168, 77,155, 54, 45, -222,184,113,163,235,134, 13, 27, 4,173, 90,181, 90, 27,146,145, 17,158, 8,168,234,147, 78, 13,240,238,138, 21, 43,228,122,189, - 30,189,122,245, 74,150,167,166,182,224, 0,157,181,223,207, 5,222, 94,246,225,135,158, 50,153, 12,179,102,205, 42, 42, 79, 79, -143,224,128,194, 42,187,164,185,165,164, 28, 30, 63,126,124,236,157, 59,119, 92,151, 47, 95,238, 57, 98,216,176,183, 1,124,105, -237, 49,170,118,104,247,242,242, 10, 30, 50, 98,172, 71,211,176, 72,236,222,186, 14,191,172,248,106,173,197, 98,249,213,199,199, -103,186, 64, 32,248,150,149, 60, 6,131,241, 66, 54, 17,214,132,139,155, 91,155,208,208, 80,156, 57,115, 6,145,145,145, 87,157, -156,156, 56,137, 76, 6,177, 88, 12,202,243,117,126,223,198,214,182,103,151, 46, 93, 68, 23, 47, 94, 68, 96, 96, 32,108,108,108, - 42,141, 85,197, 38,145, 72,224,229,229, 5,181, 90,141,168,168, 40,241,218,181,107,123, 2, 88, 84,151,118, 78, 90,162, 29, 82, -214,190,186,248,187,165,141,219,181,107, 7,149, 74, 13,158,231,161, 80, 40, 96, 52, 26, 33, 18,137, 96, 52, 26,161, 55, 82,181, - 53,121,181, 88, 44, 22,161, 80,136,192,192, 64,124,245,213, 87,208,235,245,144, 72, 36, 0, 0,181, 90, 13,165, 82,137,216,216, - 88,164,165,165,129, 62,122, 37,175, 13, 91, 59,187,254,131, 7, 15,150, 86,247, 63,131,193, 0,149, 74, 5,149, 74, 5,165, 82, - 9,189, 94,143,230,205,155, 75, 79,157, 60,217,191, 38,131,101,144,203, 71,108,216,176,193, 93, 42,149, 66,167,211, 65,163,209, - 32, 51, 51, 19,233,233,233,250,130,130, 2,206,222,222, 94, 16, 16, 16, 32,144,201,100,178,161, 67,135, 18,181, 90, 13, 66, 8, - 6, 14, 28,232,178,121,227,198, 87, 0, 44, 99,197,223, 58,142, 2,134,214, 70,227,160,246,237,218,157,188,122,237, 90,171,247, -222,123, 15,119,238,220, 89,162,216,182,237, 76, 57,112,187,182,239, 38, 3,111, 47,173, 98, 92,104,122,122,164,233, 9,227, 18, -240,208,184,196, 84, 24,151,145,245, 52, 46, 0, 96,239,232,216,214,203,203, 11,135, 14, 29, 66, 70,106,234, 71,245, 49, 87, 0, - 32, 16, 10, 59,119,233,210, 5,251,246,237, 67, 86,122,250, 71, 79,152, 43, 0, 64, 33, 80, 40, 74, 78,254,104,237,218,181,127, -188,254,250,235, 16,138, 68,157,193,113, 86, 31,163,186, 14,237,111,191,247, 17,246,237,218,180, 54, 55, 55,247, 13, 74, 41, 15, -224, 42, 43,113, 12, 6,227, 69,160, 94,243, 96,121,122,122,250,216,218,218, 34, 39, 39, 7,205, 66, 67, 11,100, 50, 25,164, 98, - 49,228, 82,169, 85,223,215,235,245,145,158,158,158, 80,169, 84,112,117,117,133, 68, 34,169,220,164, 82,105,229,103,123,123,123, - 8, 4, 2,248,248,248, 64,175,215, 71,214,165,203, 41,239,187, 31, 94,247,241, 91,127,238,218,208,184, 95,191,254,112,118,110, - 0, 63, 63, 95,184,187,187,195,198,198, 6,126,126,126,104,210,164, 9, 93,189,122, 53, 4, 14, 77,172,122,128, 87, 53, 77, 34, -145, 8, 22,139, 5,249,249,249, 72, 76, 76,196,157, 59,119,112,233,210, 37,220,186,117, 11, 26,141, 6, 86,248, 43,104,203,203, - 91, 84, 23,232, 50, 24, 12, 80, 42,149,149,209, 43,165, 82,137,194,194, 66, 36, 39, 39, 67,173,209,180,172, 73,207,217,197,101, -120, 68, 68,132, 16, 0,108,108,108,208,178,101, 75,252,250,235,175,220,159,123,247,142, 10,187,116,169,129,223,145, 35, 78,171, - 87,173, 26,245,242,203, 47, 91, 46, 95,190, 12,181, 90,141,187,119,239,194,205,205, 77, 36,149,203, 95, 97, 69,191,126,220, 0, -180,174, 26, 77,223,151, 94,122, 41, 69,165, 82,225,219,111,191, 21,136,237,237,127, 91, 8, 8,235,112, 21,157,186,116,233,130, -253,251,247, 35, 39, 61,253,227,244,106,140, 75, 58, 80,152,145,156,252,241,218,181,107,209,187,119,111, 16,145,168,222, 29,145, - 58,116,232, 16,193,243, 60, 98, 98, 98,224, 4, 92,169,239,247,131,154, 52,105,101,103,103,135,132,132, 4,216, 62,138,174, 85, -251,162, 0,156,187,121,243, 38,108,108,108,208, 44, 44,172,117, 61, 15,243,157,183,183,119,238,219,239,125,132,221,135, 47, 0, - 0,246,237,218,148, 95,197, 92, 49, 24, 12,198, 63,211, 96, 85, 32, 22,139, 33,149,201, 32,149, 74, 31, 26, 35,153,204,234,239, - 18, 66, 32,151,203, 43, 13, 85, 85, 99, 85,245,179, 66,161,176,202,184, 0,128, 57,239, 66,212, 43, 35, 95,150, 74, 36, 18, 24, -141, 6, 80, 74, 33,147,201,225,228,228,132,192,192, 64,148,151,107, 49,120,200,112, 67,166, 82,114, 64,226,219,243,206,211,228, -153,227, 56,104,181, 90,148,150,150,162,164,164, 4,106,181, 26, 58,157, 14, 86,180, 14, 86, 86,181, 25, 25, 25,216,178,101, 11, -138,139,139, 1, 60,236, 64, 93, 97,170, 42,126,166,164,164, 96,227,198,141, 72, 77, 77,133, 80, 40,180,250,250, 68, 69, 69,225, -192,129, 3,194,110, 61,123,174, 57, 22, 16,144,115, 44, 32, 32,167, 91,207,158,107,246,239,223, 47,244,241,241, 65, 90, 90, 26, -174, 95,191,142,210,210, 82, 80, 74, 9, 43,250,245, 39, 9, 40, 45, 47, 41,121,253,147, 79, 62,161,118,118,118,248,118,233,210, - 22, 95, 2, 99,172, 53, 46,142,181, 24, 23,199,103, 51, 46,160,148,130,231,121, 88, 44,150,167,202, 27, 33,132,136,197,226,250, -148,103,224,225, 82, 91,214,234, 11, 40,165,239,190,245,254, 39, 94,239,124, 48, 15,167,142, 28,168,248,251,125,102,174, 24, 12, -198,139, 72,189,154, 8,115,114,114,178,181, 90,109,227,128,128, 0,100,101,101,185,251,251,251,167, 75,197, 98, 72,164, 82,171, -250, 96,201,229,242,152,252,252,252, 78, 62, 62, 62,224, 56,174,210, 76, 61,217, 68, 88, 17,149,185,123,247, 46,228,114,121,157, -227,204, 5,150,178,134,225,225,225,149,145, 32, 39, 39, 39, 56, 57, 57, 66, 38,147, 99,241,226,197,252,154,223,126,251, 89, 30, -254,182,234,253, 73, 31,210, 27, 95,174,121,174, 39,208,218, 10, 73,161, 80,196, 52,106,212,168,163, 66,161,192,238,221,187,145, -150,150,134,210,210, 82,148,151,151,195, 96, 48,160,188,188, 28, 70,163, 17,114,185, 28, 97, 97, 97,104,208,160, 1,226,226,226, -106,204,123,105,113,241,238,152,152,152,142,237,218,181,171,140,160,116,239,222,157,116,239,222,221,181,226,247,242,242,114, 20, - 21, 21,225,234,213,171, 56,126,252, 56, 8, 33,184,127,255,190,197,160,211,109,101, 69,255,233,208, 3, 23,133,107,215,254, 49, -117,234,212, 73,157, 58,117,130, 5,232, 7, 96,227,127,202,184, 84,112,233,210,165, 88,139,197,210,169,105,211,166, 80, 2,237, - 1,236,171,151,121,124,240,224, 38,199,113, 61, 91,180,104,129,221, 59,118, 68, 1, 72,171,110, 63, 45, 16,213,170, 85, 43,232, -116, 58,220,141,143,191, 97,173,185,242,242,242, 90,243,214,251,159, 76, 28, 62,250, 53,236,222,186, 14,251,118,109,202,252,249, -251, 37,126,148, 82, 19, 43, 85, 12, 6,227, 31,111,176, 74,139,139,111,196,198,198, 54,110,221,186, 53,214,172, 89,211,238,165, -142, 29,179, 37, 82, 41, 39,149, 72, 32,176,162, 2,209,105,181, 39,206,159, 63,223,190,119,239,222,162,203,151, 47,195,211,211, -179,210, 96, 85,252, 20,137, 68,160,148, 66,161, 80,224,208,161, 67, 38,157, 86,123,162, 46, 93, 11,103,177, 8, 30, 25, 60, 74, - 41,148, 74, 37, 36, 18, 9, 86,175, 94,131,117,191,253,246,106, 86,110,238,206,224, 54,206, 31, 0,144,255,199, 42,230,242,242, -147, 39, 78,156,104, 51,115,230, 76,177,175,175, 47,148, 74, 37, 74, 75, 75, 81, 92, 92, 12,181, 90, 13,181, 90,141,210,210, 82, - 40,149, 74,200,229,114, 60,120,240,192,172, 47, 47, 63, 89,147,158, 76,175,223, 53, 97,194,132, 15,111,222,188,233, 37, 18,137, - 96, 54,155,193,243, 60,120,158,135,201,100,194,131, 7, 15, 16, 23, 23,135,132,132, 4,148,148,148, 64, 44, 22, 67, 40, 20,226, -214,173, 91,165,182,102,243, 14, 86,244,159, 30, 49,176,251,252,249,243,147,198,141, 27, 7,111, 95,223,174,200,202,178,202,184, -236,173,197,184,168,158,194,184, 60,102,124, 52,154,107, 41, 41, 41,157,186,117,235, 6, 47, 95,223, 37, 97, 89, 89,199,226,235, -209, 15,203,194,113,231,206,159, 63,223,115,252,248,241, 88,179,102,205, 18,183,148,148,195,133, 79, 52,103,186, 1,110,141,130, -130,150, 76,156, 56, 17, 71,143, 30,133,133,227,106,140,200, 61,209,161,189,225,144, 17, 99,253, 88,135,118, 6,131,241, 79,162, - 94, 77,132, 68,171,157, 51,119,238, 92,179, 80, 40,196,240,225,195,237,247,237,223,255,242,173,219,183, 3, 11, 10, 10,156, 44, - 22, 75,157, 90,246, 42,213,247,139, 22, 45, 82,154,205,102,132,132,132,160,164,164, 4, 22,139, 5, 34,145, 8, 34,145, 8,132, - 16, 8, 4, 2,216,217,217, 33, 46, 46, 14,219,182,109, 83,219,171, 84,223,215,165,203,243,124,204,158, 61,123, 32, 18,137,168, - 92, 46, 7, 33, 4, 34,145, 8,171, 87,175, 46,152,147,155,187, 27, 0,132, 2,129, 17, 0, 4, 2, 98, 85,175, 92, 66, 72,157, -237,147, 82,169, 20,252,195,206,253,117,238,235,102, 54,175, 88,181,106,149,230,254,253,251,208,106,181,149,209,182,178,178,178, -202, 78,243, 74,165, 18,132, 16,232,245,122,156, 61,123, 86,227,102, 54,175,168, 73,175, 24,200,203,186,127,127,112,187,118,237, -138, 83, 82, 82,160, 82,169, 16, 19, 19,131,227,199,143, 99,251,246,237, 56,122,244, 40, 30, 60,120, 0,142,227,224,227,227, 3, - 74, 41,246,238,221,171,226, 52,154,126,197, 64, 30, 43,250, 53,211,208,211,179,167,135,187,123,134,155,171,107, 86, 67, 79,207, -158, 79,254,223, 17,184,119,239,222, 61,112, 28,135,192,192,192, 6,181,245,195,162, 28,119,254,252,249,243, 24, 63,126, 60,252, - 26, 55, 94, 28, 0,184, 61,185, 79, 0,224, 22, 16, 20,180,184,194,184, 80,142, 59, 95,223, 52,219, 3, 63,124,240,193, 7, 58, -137, 68,130,109,219,182, 5,154,155, 52, 73, 16, 1, 99,236,128,208,110,128,164,174,239,123, 1, 63,127,246,217,103,121,132, 16, -108,218,180,201,213, 49, 40, 40, 86, 4, 76,112, 4, 26, 58, 2, 13, 69,192, 4,199,160,160,216,109,219,182,185,114, 28,135, 25, - 51,102,228,121, 1, 63,215,164, 39, 20, 10,223,205,201,201, 25,148,157,157,221, 37, 39, 39,199,239,231,239,151,224,212,145, 3, -248,101,197, 87,107,115,115,115,223,200,207,207,191,154,157,157, 61, 46, 43, 43, 43,150,149, 56, 6,131,241, 34, 66,170,235,231, - 36,110,255,101, 62, 64,221,187,118,104,142,107,183, 19, 85,174,206, 14, 71, 42,254,167,188,187,187,233,192, 14,158,205,191,253, -246, 91,136, 68, 34,100,102,102, 34, 62, 62, 30, 14, 14, 14,120,239,189,247, 12,102,131, 97,112,197,122,103,132,144,104, 74,233, -241, 71,154,199, 56,142,115,150, 25, 50,237, 90, 57,167, 52,222,184,126,173,208,222,222, 30,101,101,101,149,211, 10, 40, 20, 10, -216,216,216,224,206,157, 59, 24,255,218,235,150, 36,174, 69,229, 68,163, 21,235,157, 85,213, 4, 33, 66, 0,232,231,236,172,184, - 43,147,205,114,241,240,152,253,206, 59,239,216,116,237,218, 21, 18,137, 4,109,218, 71,229,217,182,156,253,131, 64, 64,184,172, - 98,245,220,160,134,222,142,241,247,211, 0,144,135,107, 22, 62, 90,139,176,186,116, 70,202,239, 4,110,252,229,115,135,240,240, -240,135,249, 86, 42,145,159,159,143,130,130, 2, 40,149, 74,104,181, 90, 0,192,241,227,199,113,242,106,138, 58,215,174, 87,114, - 77,233,252, 87,222,211,236,155,217,220,107,244,195,138,101, 66, 39, 39, 39,228,231,231,163,176,176, 16, 74,165, 18, 58,157, 14, - 22,139, 5,106,181, 26,251, 15, 28,180, 36, 91, 34, 83, 13,178,134,154,186, 52,161,205,180,105, 80,118,193,167, 85, 88, 0,157, - 52,105,146,189,131,131, 3,120,158, 71,105,105, 41, 50, 50, 50,144,146,146,130,179,103,207,106, 11,148, 70,104, 93,123,101, 85, - 76, 52, 90,237,249,124, 94,133,234,127, 81,243, 81, 89, 2, 0,111, 47,175,156,244,244,116,119,139,197, 2, 31, 31, 31, 78, 89, - 82,178, 88, 10, 28,181, 7,114, 1,208, 34,224,211, 21, 63,252,240,250,144, 33, 67,208,182,109,219,204,188,252,252, 70,213,149, - 37, 16, 34, 12, 1, 28,203,125,125,227,174, 94,189,234,153,145,145,129,241,227,199, 23,165, 39, 37, 85, 78,211,160, 2,162, 2, -130,130, 22,111,219,182,205,181,113,227,198,136,140,140,204,147, 87, 76,211, 80,125,249,172,249,222,188,247, 87,163,105,195, 34, -218,190,245,214, 91,224, 56, 14,103,207,158,197,149, 43, 87,144,158,158,142, 11, 23, 46, 40, 29,108,109, 71,213,118,111, 66,149, -104,223, 47, 88, 27,184,105,211, 70, 34,145, 72,176,118,237, 90,220,188,121, 19, 0,208,170, 85, 43, 76,156, 56, 17, 28,199, 97, -236,216,113,244,175, 68,155,202,137, 70,171, 43, 75,190,190,190, 17, 60,207, 47, 37,132, 72, 40,165,109,115,114,114,228, 62, 62, - 62, 57, 57, 57, 57,126,245,233,115,197,202, 39,211,100,154,255, 28,205, 23,141, 58,215, 34,252, 98, 37, 28, 31, 95,142,227,205, -156, 61,191,127, 41,234,211,183, 95,232,220, 79,230, 8, 90,181,106, 5, 63, 63, 63,180,106,213, 10, 55,111,222,148, 53,107,214, -172,174,245,206,202,122, 15,157,148,210,187,119,111,167,183,223,126,219,177,107,215,174, 98,111,239,135,235,234,198,197,197,225, -208,161, 67,166, 45, 91,182,168,179,165, 81,202, 11,135,126, 47,179,102,189,179, 67,165,165,229, 0, 62,111,110, 52,254,246,217, -220,185,243,195, 35, 35, 39,189,255,254,251, 2, 59, 91,133,248,203,185,111,200, 1,224,139,159,182, 59, 14,121,249, 85,172,104, - 2,116, 29, 83,253, 58,111, 85,211,153,149, 91,144, 62,102,226,203, 77,222,126, 99,140,101,208,160, 65,182,118,118,118,240,243, -243,131,179,179, 51, 82, 83, 83, 17, 19, 19, 67,143, 29, 59, 86,118, 35, 46, 85,188,110,251,209,116,169,157,187, 53,235, 6,106, -122, 15,153,144, 58, 97,194, 4,231, 97,195,134,217,135,135,135,139,197, 98, 49,228,114, 57,138,139,139,145,153,153,105, 58,125, -250,116, 89,182,164, 99,233,133,195,235, 52, 86,174, 69,168,235, 50,122,225,131,115,199, 22,204,136,139,137, 25,199, 3, 45, 76, - 38,147,143,197, 98, 33, 2,129, 32,151,231,249, 24,147, 70,243,135,161,213,130,229,108, 45, 66,235,176, 88, 44, 18,139,197, 2, -165, 82,137, 99,199,142,137,146,146,146, 62,189,125,251,246,167, 57, 57, 57, 48,155,205, 24, 49, 98, 4, 90,181,106,133, 83,167, - 78,161, 48, 63,255,207,218,180, 18, 1,149, 44, 43,107,226,155,111,190,121,104,227,198,141,130,219,183,111,187,174, 93,187,246, -247,234,140,203,184,113,227,248,252,140,140,137,134, 90,230,192,170,227,222, 44, 58,188,237,199,219, 67,135,191, 28,182, 96,222, -167,226,151, 94,122, 9,174,174,174,136,138,138,130,201,100,114,178,226,222,212,116,233, 59, 42,185, 69,139, 22,182,203,151, 47, -247,124,253,245,215, 49,125,250,116, 0,128, 78,167,195,209,163, 71, 49, 99,198,140,188, 12, 81,123,237,141, 83,219,106, 45,159, -143, 34, 83,189, 0,192,199,199,231, 12,128, 46, 0,146, 89,135,118, 6,131,241,143, 54, 88,192,191,214, 59, 59,119, 37, 22, 85, -151,227,120,136, 91, 60,231, 58, 34,105,234,236, 37,145, 82,104,157,197,196,224,112,235,230, 77,146,146,146, 82,235,193, 42,214, - 59, 51,200,252,202, 20, 57, 69,237,126, 88,177,226,189, 53,107,214,244,172,152,138, 65, 46,151,199,232,180,218, 19,246, 42,213, -247,134,198,126, 39,234,187,118,222,157,146,146,124, 0,211, 66, 45,150, 31, 94,155, 52,229, 27,129,157,175,248,147, 47,215,232, -133, 2,129,241, 65, 78, 33, 86, 52, 1,108,173, 24,240, 88,110, 4, 98,138,221,185,120,116, 75, 92,178,112,225,172, 21,223,125, -215, 78, 97,103,215,213,204,113,193, 60,207,131, 90, 44,247,117, 58,221, 25,152, 76, 87,179,188, 39,127, 39,181,115,167,214,174, - 27,104,144, 55,210,120,104,207,180,219,181, 99,199,187,135, 14, 29,250,183,188,123,241,252, 15,201, 14,141,142, 91,147,247,170, -251,232,129,139, 40, 40,184, 88,227,219, 6,216, 90,132, 86,223, 20, 60, 63,217,217,217,121, 67,207,158, 61,229,209,209,209, 24, - 48, 96, 0, 94,122,233, 37,240, 60, 15, 74, 41, 52, 26, 13,182,111,223,142,111,190,249,230,126, 35,224,243,186,244, 12,192, 9, -217,193,131,253, 90,180,104,177,182, 54,227,242,200, 92,213,217,231,176,246,123, 83,118,159,115, 28,156, 54,250,237,175,154, 24, -213,185, 78, 46, 10,206, 51, 46, 54, 70, 96,237,189, 9,199, 16,141,229,230,246,246, 35,134, 13,123, 91, 40, 18, 69, 61, 26,209, - 72,239,198,199,223,168, 88,236, 25,173, 38, 30,171, 79, 89,162,244,225,220,115,172, 67, 59,131,193,248,199, 27, 44,145, 72, 84, - 80, 17,229, 17,137, 68, 5,201,123,167,188, 90,155,136,159,151, 87,207, 71,111,199,168,107, 45,194,138,207,183, 85, 42,205,163, - 25,218,171,157, 68, 84,252,196,254,245,201, 84, 66, 65, 65, 34,128,129, 64, 58,144,248,176, 59,139,184,221, 23, 31, 85,205, 83, -141, 39,228,177,227, 74, 74,210,242,243,207,225, 97,115, 78,181,157,113,197,254,146,146,186,210,249,100,222,207,103,102,170, 31, -229,187,250,188,123,214,157,119, 81, 61,207,143,232, 25,206,231, 63,141,236,162,162,189, 0,236,124, 15, 28,240, 56,124,224,192, - 43,179,102,206, 28,225,229,237, 29,228,234,234,234,108,111,111, 47,184,124,249,114, 10,167,215,255,208, 18, 88,119, 5, 40,183, - 70,211, 0,156, 8,201,200, 8, 31, 57,108,216,219, 68, 36,234, 92,213,184, 80,142,187, 16, 8,252,108,176, 98,246,246,122,223, -155,178,250,223,155, 89, 15,211,241, 37, 56,238, 75,220,185,243,204,247, 38,207,243, 95,248,248,248,104, 88,135,118, 6,131,241, -143,226,239, 92,135, 7, 64, 52,211,100,154, 47,138,230, 67,143, 2, 7,118, 62,153, 38,211,100,154, 76,243,249,107,254,163,215, - 34,100, 48,254,225, 47, 35, 22, 0,106,118, 38, 24, 12, 6,131, 81, 23, 4, 64,116, 13,149,137,213,163, 3, 8, 33,209, 79, 81, - 89, 29,103,154, 76,147,105, 50, 77,166,201, 52,153,230, 63, 75,179, 46,237, 23,102,116, 34,107, 34,100,154, 76,147,105, 50, 77, -166,201, 52,153, 38,107, 34,124,190,155, 0, 12, 6,131,193,192,194,133, 68, 0, 16, 2, 44, 20, 0, 59,133,192, 72,225,195,223, -159,158,145, 35, 73,181,147,208,190,251, 46,177,103,103,156,193,120,177, 97,125,176,254,131,120,121,121,249,123,120,120,252, 74, - 41, 37, 5, 5, 5,147,115,115,115, 51,216, 89,249,239,195,197,197,165, 39,199,113, 80,169, 84, 39, 94,196,252,133, 55, 33,195, -168, 0,205,254, 21,214, 70, 70,252,125,186,161,186,125,195,130,201,120,144,127,205,165, 69,120,220,141,123, 64,247, 88,123, 44, - 66,136, 96,104, 63,183,165, 0,176,247, 80,225,236,191, 99, 94, 44,111,111,239,166, 46, 46, 46, 71,132, 66,161,200, 98,177, 76, -139,137,137, 57, 80,179, 1, 26, 41, 4, 0, 55,155,221,115,156, 26,184,126,252,217, 44, 34, 54, 26,190, 85, 26,244,122,149, 64, - 36, 74,149, 74, 20,231, 57,129,237,161,172,252,126,241,213,125,127,199,142, 29, 53,174,174, 29, 17, 76,250,133,134,133, 13,106, - 29,105,147,188,244,251,118, 43,186, 6,186,138, 83, 50,111,217,173,220,144,241,171,155,179,207,160,247,222, 16, 29,144, 81,203, -184, 37,191,211, 50,118,151, 89,207,215,132, 52, 48, 1,145, 98,153,204,207,194,113, 30, 4,160, 66,145, 40,223,108, 48,100, 74, -128, 59, 31, 83,170,124,209, 53, 37, 50,153,175,133,227, 60, 0,224,191, 49,157,140, 58, 12, 86, 80, 80,208,117,129, 64,224, 91, -177,198, 95,213,197,106, 43, 62, 63,249,211, 98,177,100, 37, 36, 36,180,177,246,224,141, 27, 55,118,208,235,245,175, 16, 66, 94, - 5, 0, 74,233,102,185, 92,190, 61, 37, 37,229,169, 58, 18, 55,110,220,216,129, 82, 58,219,198,198,166,135, 94,175, 15, 7, 0, -185, 92, 30,167,211,233, 78, 18, 66,150, 62,141, 46, 33, 68,228,229,229, 53,210,214,214,182, 59,199,113,221, 41,165, 68, 36, 18, -157, 42, 47, 47, 63,153,155,155,187,131, 82,202,213, 87,211,219,219,219,198,197,197,229,203, 38, 77,154,140,121,251,237,183,139, - 27, 52,104, 16,178,112,225,194,107, 17, 17, 17, 91, 74, 74, 74,230,230,228,228,232,254, 27, 10, 7, 33, 36,200,211,211,115,179, - 88, 44, 22,102,102,102,118, 7, 0, 63, 63,191, 83, 70,163,209, 82, 80, 80,240, 42,165, 52,169, 62,122,110,110,110,182, 98,177, -184,131,173,173,109, 27, 91, 91,219, 46, 22,139,165,217,163,245, 19,239,106,181,218,179,102,179,249,186,217,108,190, 92, 88, 88, -168,253,111,185, 65, 8, 33,246,238,238,238, 27, 9, 33, 32,132, 4, 83, 74, 53, 47,218, 67,128, 10,208, 44, 62, 46, 33,164,210, - 68,133,135,214,114, 66,224, 95,205,190, 86, 27,172,254, 61,157,250, 14, 26,212, 66, 0, 0, 38,211,181,190, 0, 14, 62,111,115, -213,191,127,255,139, 63,252,240,131,179, 94,175,199, 7, 31,124,176, 57, 56, 56,248,231,251,247,239,207,169,237,123,246,246,246, - 51, 62, 95,244,147,226,209,179,204,157,231,121,247,220,220,204,224,196,132,152,190,137,137,177, 95,153,180,123, 46,155,168,112, -138,178,124,112,130, 53,233, 8, 11, 34, 3,135,140, 28, 54,224,243,207, 23, 96,204,168, 49, 13,227,226,244, 54, 62, 14,201, 82, -181,201,182,137,171,171,239,224,143, 62, 89, 66, 46, 95, 58, 61,120,199,246, 53, 39, 63,154, 68,122, 48,147,101,213,189, 72,190, - 16,137, 58, 56,135,134,118, 25,181,119, 47,236,252,252, 68, 34,153, 76, 0, 0,156,193,224, 87,150,153,233,181,109,240,224,246, - 11, 9, 57, 61,159,210, 43, 76,243,255, 95,147, 97,165,193, 18, 8, 4,190, 55,111,222,116,183,181,181,197, 35,243, 3,139,197, - 2,139,197, 82,185,168, 48,165,180,242, 39,199,113,232,214,173,155, 85,111,176, 94, 94, 94, 61, 0,188, 22, 17, 17, 49, 98,246, -236,217,146, 78,157, 58,193, 98,177,224,228,201,147, 81, 43, 86,172,248,209,219,219,123, 55,128,117,185,185,185, 39,172,125,195, -245,242,242,234, 99,107,107,187,233,211, 79, 63,117,136,138,138, 18,121,121,121, 1, 0, 10, 10, 10, 58,156, 63,127,190,205,130, - 5, 11,166,121,121,121,141,205,205,205, 61, 98,237,201,241,245,245,141, 8, 14, 14,222,217,175, 95, 63,223, 54,109,218,200,155, - 54,109, 10, 74, 41,110,221,186,245,122, 98, 98,226,232,131, 7, 15,206,247,245,245,125,217,218,245,212, 8, 33, 36, 40, 40,104, -130,167,167,231,151, 51,103,206,108, 48,116,232, 80,105,108,108,108,105, 96, 96, 32,217,189,123,183,219,159,127,254, 57,237,151, - 95,126, 25,217,164, 73,147,185, 73, 73, 73,235,105,117,235, 24, 61, 65,112,112,240,117,129, 64,224,107,141, 1, 38,132,128,227, - 56,171, 76, 48, 33,164,101,163, 70,141,182,159, 59,119,174, 81, 90, 90,154,101,232,208,161, 27, 0,224,228,201,147,145,102,179, -153,244,238,221,251, 16, 33,228, 21, 74,233, 45,107,242,238,227,227,211,220,205,205,109,223,208,161, 67, 27,248,251,251, 43,124, -125,125,137, 92, 46,135, 80, 40, 68, 89, 89,153,119, 98, 98, 98,244,173, 91,183,116, 23, 46, 92, 40,241,241,241, 25,156,157,157, -125,167, 30, 15,222,151,220,221,221,199,137,197,226, 8,142,227,124, 0, 64, 36, 18,101,155,205,230,216,130,130,130,141,148,210, -139, 79,123,131,120,120,120,252,248,229,151, 95,186, 22, 20, 20,208,197,139, 23,255, 8, 96,194,139,250, 48,216,188,101, 7,174, - 95,187, 2, 0, 18, 66, 8,121,178,252, 17, 66, 72,179, 96, 72,222,127,127, 38,218,180,109,143, 87,199,140,172, 83,115,232, 0, -215,207,165, 66,145, 75,185,209,112,165, 72, 37,216,231,239, 46, 29, 54,118,100,155,100, 0, 56,124, 40,102, 88,251,246, 13,206, -187, 58,242, 67, 20, 82, 89,123,163,133, 43,222,251, 87,209,188,250,152, 41, 79, 79,207, 35,246,246,246,138,210,210,210,188,226, -226,226,149,253,251,247,255, 98,249,242,229,206,201,201,201,200,204,204,196,107,175,189,102,151,157,157,253,182,191,191,255,165, -140,140,140, 26, 35, 89, 26,141,230,251, 47, 23,205,156,103,239,224, 44, 84,216,216,194,206,222, 1,141, 26, 5,163,109,187, 40, - 68,247, 26,140,228,228,196, 14,219,183,174,185, 41,204,221,249,181, 69,218,234, 11,165,178, 81,141,207,165,240, 16,210,181,194, - 92,205,155,183, 0,247, 18, 18, 52,105,169,130,119,254,218, 43, 82,244,235, 25, 42, 51,154,202,210, 46, 95, 58,221,168, 67,199, -110, 0,208,102,199,246, 53, 39, 23,142, 37, 61,231,111,122,241,204,251,243, 52, 87,159,139,197, 19,250, 44, 95,238,222,106,218, - 52, 73, 89,106,170, 41,121,213,170,242,252,179,103, 45, 34,153,140,250,245,237, 75,220,186,119,151, 79,187,123, 87,114, 97,241, -226, 46, 95, 73,165,129,159, 24,141,155,152,230,255,159, 38,163,126, 6, 11,182,182,182,216,182,109, 27,196, 98, 49, 68, 34, 17, -196, 98,113,141,159,253,253,253,173, 49, 65,195,195,195,195,127,154, 57,115,166,199,160, 65,131,224,236,252,248, 42, 27, 3, 7, - 14, 68,255,254,253, 37, 41, 41, 41,163,119,236,216, 49,122,195,134, 13,121, 94, 94, 94,239,228, 62, 90,176,185,150,202,187,123, - 96, 96,224,238, 45, 91,182,216,232,116, 58,156, 62,125, 26,165,165,165,144, 74,165,240,245,245, 69,231,206,157, 69,167, 79,159, -110, 48,122,244,232,221, 62, 62, 62, 3,179,179,179, 79,213,149, 86, 79, 79,207, 54,110,110,110,103,126,251,237, 55,121,104,104, - 40,121,240,224, 1, 90,180,104, 1, 0, 40, 46, 46,198,192,129, 3,229,195,134, 13, 11,122,235,173,183, 46,123,122,122,118,205, -203,203,187, 94, 71,222, 91,183,104,209, 98,125,223,190,125,189, 63,254,248, 99, 7, 59, 59, 59,164,165,165,229,122,122,122, 6, - 87,152,159, 33, 67,134, 72,123,245,234,229,181,114,229,202,239, 15, 30, 60,248,129,151,151,215,132,220,220,220, 27,181,233, 10, - 4, 2,223, 27, 55,110,184, 43, 20, 10,228,231,231, 99,243,230,205,120,251,237,183, 33, 20, 10, 81, 80, 80,128,237,219,183,227, -157,119,222,129, 80, 40,132, 74,165,178,202, 4,219,218,218, 70,183,104,209,226,247,147, 39, 79,250, 58, 57, 57,193,219,219, 91, -240,217,103,159, 69, 4, 6, 6,218, 52,108,216, 80,152,155,155,139,221,187,119, 7,142, 27, 55,110,159, 92, 46,127, 93,175,215, -215,217,116,230,226,226,242,199,250,245,235,253,111,223,190,141, 85,171, 86,161,164,164, 4, 82,169, 20, 78, 78, 78,240,244,244, - 68,112,112, 48,153, 54,109,154,162, 71,143, 30,138, 5, 11, 22,252, 1,160,165, 21, 15,221, 22,238,238,238,191,142, 30, 61, 58, -112,225,194,133, 78,158,158,158,168,120, 33, 80,169, 84,190,105,105,105, 29,230,205,155,247,178,135,135, 71, 74, 65, 65,193, 20, - 74,233,237,122, 62,212, 91,246,236,217,115,224,208,161, 67,133,185,185,185,216,184,113,227, 64, 66, 72, 75,107, 77,229,255, 26, -215,175, 93,193,228,183,222, 43,243,246,243,147,252,185,127,235,144,178,178,223,206,219, 9,156, 68, 0, 80,198, 43,185, 78, 29, -236, 58, 15, 26, 60, 90,210,127,192,208,178,223,126,249,222,206, 26,131, 37, 21,138, 92,182,109,154,154,121,246,194,253,102, 71, -142,167, 69, 15, 29, 28, 45, 16, 73, 66,130, 0, 96,214,204, 55,165,123,247, 31,255,185, 79,116,195,220, 46,157,130, 51, 71,141, - 93,229, 87, 31,115, 21, 24, 24,120,250,200,145, 35, 30, 82,169, 20,165,165,165, 46,107,215,174, 93,214,190,125,123, 65, 82, 82, - 18, 18, 18, 18,144,154,154, 10,149, 74,133,118,237,218,217,197,199,199,175, 4, 80,163,193, 42,212, 13,255, 50,208,189,232, 7, - 31, 23,231, 70,122,147,202,221,194, 21,135,157, 60,126,187,249,174, 29,229,173,220, 61,125,131, 71,143,158,140,143,230, 44, 17, -239,217,181,126,222,153,179, 71, 1, 52,170,121, 6,127,138,151, 62,153, 59, 7,106,141, 1, 99,199,188,137,113, 99,222,116,161, - 48,122, 81,139,222,214,168, 43,117,114,148,196, 29, 88,191,117,199, 48, 0,190, 85, 76,214, 9,102,178,106,230,115,145,168,253, -192,159,126,114,139,120,227, 13,217,237,133, 11,181, 69,103,207,234,154,244,239, 95,218,106,234, 84, 3, 0,104, 82, 83, 37,247, -230,207, 87,184,117,233, 98,211,113,246,108,103,139,209,232,185,136,144,118,159, 81,122,181,190,154,141,198,140,177, 44,221,189, -187,237,229,197,139,187, 97,209, 34, 97,247, 86,173,110,205,253,229,151,236,103,209,124,158,233,204, 57,115,198,160,109,214, 12, -145, 35, 70, 20,251,184,184, 24,158,103,222,159, 37,157,140,106,234,144,154,130, 36, 33, 33, 33,249,137,137,137,238,187,119,239, -174,211, 92,137,197, 98,120,121,121, 33, 42, 42,170, 32, 38, 38,198,163,150,135, 98,102,102,102,166, 47,199,113,144, 74,165,181, - 38, 76,163,209, 32, 38, 38, 6,163, 70,141,202,202,201,201,169,241,193,219,160, 65, 3,123,103,103,231,228, 83,167, 78,185,198, -197,197,225,250,245,235, 8, 12, 12,132,179,179, 51,196, 98, 49,204,102, 51,212,106, 53, 66, 66, 66, 96, 99, 99,131,254,253,251, - 23,149,148,148, 4,150,148,148,212,248, 32,107,216,176,161, 76, 44, 22,223,223,181,107,151, 95, 68, 68, 4,174, 94,189, 10, 63, - 63, 63,120,122,122, 2, 0, 82, 83, 83,113,254,252,121,244,239,223, 31,177,177,177,152, 58,117,106,166,217,108, 14, 78, 75, 75, - 51,212,216,100, 16, 22,150,187, 99,199,142,172,208,208, 80,189, 86,171, 21,228,231,231,139,207,158, 61,203,105, 52, 26, 59,149, - 74, 37, 86, 42,149, 98,181, 90, 45,210,106,181, 98,129, 64, 32, 49, 24, 12,226,203,151, 47, 11,139,139,139, 29,106, 59, 79,161, -161,161,249, 9, 9, 9,238,251,247,239, 71,100,100, 36,118,239,222,141, 89,179,102,225,194,133, 11,240,243,243,195,142, 29, 59, - 48,123,246,108, 36, 38, 38,194,213,213, 21, 61,122,244,168,245, 26, 1, 64,147, 38, 77, 30,196,196,196, 4, 73, 36, 18, 36, 39, - 39, 35, 43, 43,171, 98, 61, 59, 20, 22, 22, 34, 41, 41, 9,217,217,217,104,210,164, 9,198,140, 25,147,148,149,149,213,164,174, -130,214,186,117,235,194, 19, 39, 78,184, 54,111,222, 28,249,249,249,112,114,114,130,163,163, 35,156,156,156, 42, 63, 7, 6, 6, - 98,230,204,153,104,222,188,121, 65, 90, 90,154, 71, 93,230, 39, 50, 50,242,200,137, 19, 39, 92, 29, 28, 28,144,151,151, 7,181, - 90, 13,145, 72, 4,133, 66, 1, 87, 87, 87,200,229,114, 0,192,253,251,247, 49, 96,192,128,162,228,228,228, 62,214,154, 35, 66, -136,192,195,195, 35,225,206,157, 59,193,148, 82,100,100,100, 32, 49, 49, 17,111,189,245,214,125,189, 94, 31,250, 34,173,169, 87, -165, 95,149,100,194,196,201,146,161,131,135,148,223,186,126,152,183,193, 25,180,107,105,163, 4,128,171,183,116, 78, 58,116, 69, -203, 54,125, 5,123,247,239, 83,172, 95,247,155, 24, 60, 60, 64,144, 24,127,143, 46,170, 73,123, 96, 31,167,241,179,223,235,219, -172, 75,167, 46, 34,181,154,122,254,190, 97,117,187,244,148,100, 15, 0, 8,104, 28,152, 63,105,252,155, 87, 29, 28, 72,222,217, - 11,103,185,165,223, 31,190,123,224,136,114,131, 21,145,229, 64,127,127,255, 75,127,252,241,135,171,155,155, 27, 28, 29, 29,161, -213,106, 97, 50,153, 16, 31, 31,175,223,182,109,155,217,193,193,193, 62, 47, 47, 15, 74,165, 18, 34,145, 8,151, 46, 93,202,200, -203,203, 11,120, 82,171,162, 15, 22, 0,188,213,175,153, 56,172, 71,176,179, 68,198,217,216,136,239,121,129, 88,100,132,218,121, -156, 60,121,169,249,169, 51,231, 94,237, 63,112,148, 91,199,142,221,177,228,171,143,204, 25,121,249,173,148,229,131, 19,170,235, -131,213, 44,152,244, 24, 58, 98,216,200,207, 63, 95,128, 5,243, 22,226,192,254,189, 42, 59, 91,129,193,193, 73,236,216,165, 67, - 39,253,204,183,135,100,150,151,101,249, 45,251,121,245,152, 94,125, 70,250,118,232,216, 13,151, 47,157,198,142,237,107,174, 75, - 44,102,214, 92,248, 4, 11, 9,113,118, 10, 12,156,242,238,253,251,146,219, 11, 22,148,113, 57, 57,165,109,102,204, 40,170,110, -223,172, 99,199,108,165,222,222, 14,206,131, 7, 55,248, 62, 32,128,154, 11, 10,126,173,174, 15, 81,117,154, 87,189,188,156,246, -156, 58,213,147, 23,137,186,190, 61,125,186, 77,116,116, 52,212,106, 53, 14, 28, 56,128, 45,155, 55, 27, 60, 61, 60, 98,156,174, - 93,187, 25,152,155,251,169,181,154,109,102,204, 40,178, 88, 44,100,234, 87, 95,245,186,151,153,217,163,160,184,184, 33, 0,184, - 59, 58,102, 70,248,250, 94, 95,190,105, 83,226,143,141, 26,241,214,166,115,219,133, 11, 30,135, 10, 11,223,112,114,114,178, 41, - 44, 42, 18,201,164,210,226, 86, 77,154,236,248,122,250,244,211,198,155, 55, 37,114, 95, 95, 7,199,129, 3,235,157,247, 54, 51, -102, 20,169,202,203, 69,115,127,248,161, 83, 78,113,113, 67,173,209,216, 68, 85, 86,230,201,153, 76, 2,123, 27,155,226,128, 38, - 77, 10, 52, 39, 78,228, 6,148,149,189,183, 66,171, 45, 96,165,242, 25, 35, 88,132, 16, 80, 74,173,138, 94,137,197,226,199,250, -104,213,130, 68, 40, 20,226,234,213,171, 40, 40, 40, 64,100,100, 36, 26, 53,106,244,216, 14,201,201,201, 56,120,240, 32,148, 74, - 37, 90,183,110, 13, 0,146,218, 4,237,237,237,223,159, 51,103,142,147,193, 96,192,245,235,215,209,166, 77, 27,200,100, 50, 72, - 36,146,199,204, 95, 65, 65, 1,194,195,195, 49,117,234, 84,199, 31,127,252,241,125,212,178,134, 28,165,116,250,232,209,163,221, - 35, 34, 34, 0, 0,153,153,153, 21,105, 1, 0,184,185,185,225,214,173, 91,104,211,166, 13, 60, 60, 60,208,175, 95, 63,247,125, -251,246, 77, 7,176,180,198,140, 75, 36,130,208,208,208,182,143, 34, 68, 16, 8, 4,247, 28, 28, 28,220, 60, 60, 60,108, 29, 28, - 28,254, 45,143,107,215,174, 85, 74,165, 82,179, 53, 39, 53, 47, 47, 15, 17, 17, 17, 80,169, 84, 0, 0,173, 86,139, 38, 77,154, - 64,173,126,216,229,204, 96, 48,192,219,219, 27, 58, 93,237, 93,187, 90,180,104,177, 32, 52, 52,180,119,183,110,221,100, 98,177, - 24,183,111,223, 70,171, 86,173,176,109,219, 54,248,251,251, 67,161, 80,224,254,253,251,136,140,140,196,153, 51,103,224,230,230, -134,240,240,112, 89,235,214,173,207,149,148,148,156, 74, 75, 75, 91, 80, 75,164, 77, 96,103,103,135, 51,103,206,224,143, 63,254, - 64,106,106, 42,114,114,114, 96,111,111,143,150, 45, 91, 34, 44, 44, 12, 47,189,244, 18,238,223,191, 15, 82, 71, 97, 34,132,120, - 6, 7, 7, 31,184,122,245,170, 43,165, 20, 27, 55,110, 68, 89, 89, 25,140, 70, 35, 4, 2, 1,228,114, 57,156,157,157,209,163, - 71, 15,184,185,185, 33, 56, 56, 24,219,183,111,119,237,215,175,223,193, 71, 17,168,188,186,206,169,179,179,243,123,243,231,207, -247,115,119,119, 71, 90, 90, 26, 84, 42, 21, 60, 60, 60,208,173, 91, 55,159,227,199,143,191, 7, 96,249,139,242, 16,168,232,208, - 78, 8, 33,127,238,223, 58,196,223, 75,218,172, 93, 43, 77, 64,204, 13, 81,208,193,227, 15,154, 63, 60, 31, 1,119,218,181,214, - 36, 93,189,126, 56,253,207,253, 91,175,220,189,135,125,214, 52, 97, 23,169, 4,251,142, 28, 79,139,110, 30, 30, 37,252,225,231, -249, 67, 38, 79,234, 35,107,224, 28, 69,212, 5,219,113,225, 74, 76,192,103, 11, 62,118, 95,180, 96,241,159, 71,142,167, 89,138, - 84,130, 47,173, 73,111, 80, 96,131, 31,119,173, 22,185,106,140, 63,227,214, 21, 71, 64,220, 17,141, 3,155, 66,173, 86, 67, 46, -151,203,199,140, 25, 99,153, 51,103, 78,185,131,131,131, 66, 36, 18,225,214,173, 91, 5, 2,129,160, 79, 93,186,122,119,103,106, - 49,153, 57, 42, 21,242,148,216,235,136,165, 68, 26, 27,159,130,174, 93,251,229,183,109,211,234,171,197,223, 46,255, 36, 48, 48, -196,109,204,216, 41,226,165, 75, 63, 93, 5, 32,170, 58,157,187,247,233,201,176, 32, 98, 3, 96,192,231,139, 22, 32, 57,249,190, -243,228,215,148, 11, 69, 50, 27,239,208,128, 78,246,171,254, 56,213,183, 73,147, 70, 13, 39, 79,124,253,175,223,214,254, 49,160, -106, 36,107,235,150,223,246, 17, 66,122, 90,115,110,255, 65, 52, 31,119,224, 0,202, 50, 50,204, 37,231,206,233,123,254,244, 83, - 81,235,241,227,151,155, 57,206,181,162,174,170,248, 73, 8, 1,120,158,136,150, 46, 21, 80,111,111,152,157,156, 94,251, 24,104, - 90,151,230, 98,179,121,248,208,150, 45, 7,252,190,105, 19, 2, 2, 2, 42, 53, 29, 29, 29, 49,125,250,116, 76,155, 54, 77,118, -231,206,157,118, 7, 15, 30,108,183,225,231,159, 61, 62, 6,134, 91,147,206,179,183,111, 59,127,248,253,247,115,155, 69, 68,248, -175,248,233, 39, 89, 69,125,151,150,150, 22,252,211,143, 63, 6,244,136,142,206,255,232,195, 15,215,221,156, 53, 43, 28, 15,151, -100,171, 81, 51,239,236, 89,227,161,146,146, 55,118,236,220,233, 20, 18,242,176, 27,100, 82, 82,146,251,239,191,255,254,102,143, -183,223, 30, 59,107,244,232, 79,123, 60,120,160,116, 40, 44,148, 13,252,241, 71,209,214,145, 35,235,212,172, 72, 39, 0,140,152, - 61,251,253,246,157, 58,133,245, 27, 51,166,129,183,183, 55,177,177,177,129,201,100, 66,126,126,190,115, 98, 98, 98,208,113,165, - 82,125,244,214,173,141,120,180,136, 59,227, 25, 12, 22, 0, 88, 44, 22,171,204,149, 72, 36,250, 87,225,182,230,160, 34, 17,188, -189,189, 81, 84, 84,132,216,216, 88, 4, 4, 4,192,108, 54,227,200,145, 35, 80,169, 84, 16,139,197,144, 72, 36, 48,153,234, 94, - 27,214,214,214, 54,186, 75,151, 46,162,139, 23, 47, 34, 48, 48, 16, 54, 54, 54,149,233,170,216, 36, 18, 9,188,188,188,160, 86, -171, 17, 21, 21, 37, 94,187,118,109,116,109, 6,203,206,206,174,255,144, 33, 67, 42, 67,108,101,101,101, 16, 10,133,149,102,165, -172,172, 12, 37, 37, 37, 80, 42,149,208,235,245,104,222,188,185,244,228,201,147,253,107, 51, 88, 85, 41, 47, 47, 47, 43, 40, 40, -112,138,138,138,114, 94,183,110, 93, 98,199,142, 29, 67,170,254,255,244,233,211,122,189, 94, 47,150, 74,165,117,174,115, 71, 8, -193,166, 77,155, 42,207,125,118,118, 54, 86,173, 90, 85,249,255,251,247,239,227,135, 31,126,168,156,151,163,182,107, 20, 26, 26, -218,111,227,198,141,109, 54,108,216, 80, 42, 20, 10,145,152,152,136,205,155, 55,131, 82, 10, 55, 55, 55,148,151,151, 35, 63, 63, - 31,167, 78,157, 2,199,113,176,179,179,131,143,143,143,124,250,244,233,157, 23, 46, 92, 40, 6,176,160,150,178,100, 17, 10,133, - 8, 8, 8,192,188,121,243,160,215,235, 33,145, 60,244,149,106,181, 26, 74,165, 18, 55,111,222, 68, 90, 90, 26,234,170, 92,228, -114,249,203, 27, 54,108,112,151, 74,165,208,233,116,208,104, 52,200,204,204, 68,122,122,186,190,160,160,128,179,183,183, 23, 4, - 4, 4, 8,100, 50,153,108,232,208,161,164,194,104, 14, 28, 56,208,101,227,198,141,163,234, 50, 71,132, 16,183,102,205,154,125, -242,230,155,111,202,171,152,110,228,229,229, 97,248,240,225,138,139, 23, 47,206, 33,132,108,166,148, 22,190, 72, 15, 3, 74, 41, - 45, 43,251,237,252,217,125, 63, 53,139,185, 33, 10, 50, 26, 75, 59,246,234,255,158, 8, 0, 46,158, 89,219, 49,230, 70, 44,108, - 8,151,126,232,232,210,243,118,118,147,105, 93, 17,192,254, 61,157,250,250,187, 75,135, 13, 29, 28, 45,248,125,195,234,118,147, - 39,245,145,185, 55, 94, 77, 0,192, 89,226,139,151, 44,179, 4,122,131, 86,254,251,134,213,237,134, 14,238,127, 37, 53, 37,125, -249,128,104,231, 61, 7, 79, 40, 15,215, 22, 33,244,114, 23,249, 56,219, 23,193,217,190, 21, 2, 2,237,113,243,214, 29,236,219, -125, 14,193,161,157, 97, 48, 24,192,113,156,237,160, 65,131,202,119,236,216,161, 47, 46, 46,214,152, 76,166,174, 57, 57, 57,247, -234,202,127, 86, 86, 60, 31,226,217,193, 36,177,145,113, 26,149,164,252,227, 79,119,142,108,221,190,119, 27,103, 47, 31,177,155, - 45,255,103,247,174, 81,155,183,108,250,117,198,172, 15, 22,161,101,203,142, 29,239, 62, 56, 20, 6, 32,166, 90,211,154, 68, 15, - 68, 4, 19, 46,249,193,131, 1,233,105,105, 89, 77, 61, 60,141, 73, 74,106,126,239,227,213,189,162,186,190,220, 60,168, 89, 23, -105, 92,252, 25, 50,243,237, 55,183, 44,251,121,245,152, 10,147,117,246,236,145,174, 11, 22,164, 73, 1, 24, 88,245,244,232,229, - 84, 38,243,181, 11, 8, 16,165,174, 91,167, 11, 28, 52,168, 20, 0,204, 28,231,122,233,242,101, 71,133, 66, 1, 74, 41,204,102, -243, 99,125,132, 43,250, 5, 71,119,235,230, 97,141,102,230, 47,191, 52,127,251,237,183,145,151,151, 7,142,227, 32, 22,139,159, -124,102, 67,163,209, 96,196,136, 17, 88,187,114,101, 7,107, 52, 45, 22, 11,249,240,251,239,231, 78,127,239,189,160,177, 99,199, - 10,170, 62,123,157,156,156,240,219,234,213,210,117,235,214,249, 46,249,227,143,215,122,201,100,201,117,105,106,194,195,225, 20, - 19, 99, 83, 97,174, 0, 32, 40, 40, 8,139, 23, 47,150,141, 30, 61, 90, 58, 97,194,132,239,226, 66, 66,190, 95,144,158,254,192, -165,105, 83, 7,169, 76,230,107,237,249, 4,128, 50,163, 49, 98,254,231,159, 59, 95,185,114, 5, 57, 57, 57, 21,115, 93,129, 16, -130,200,200, 72, 50,114,228, 72,199, 14,109,218,180, 99, 37,242, 57, 69,176, 44, 22,203, 99, 70,165, 46,131, 85,239,246, 73, 66, -224,229,229, 5,147,201,132, 53,107,214, 64, 34,145, 84, 86,186, 0, 96, 52, 26,235,212,208,235,245,145,158,158,158, 80,169, 84, -104,218,180,233, 99,145, 43,137, 68, 2,145, 72, 4,137, 68, 2,153, 76, 6,131,193, 0, 31, 31, 31,232,245,250,200, 58, 12, 80, - 75, 7, 7,135,202,138,213, 96, 48, 84,154, 43,165, 82, 9,165, 82, 9,163,209,136,210,210, 82,148,149,149, 65,169, 84, 66,163, -209,180,178, 38,207, 60,207, 35, 54, 54, 54, 41, 36, 36,164,165, 80, 40,132,157,157,157,173, 86,171,173,236, 59, 84, 82, 82,130, -245,235,215,107,199,143, 31,239,122,229,202, 21,171, 22, 18,126,231,157,119, 32,147,201, 80, 94, 94,142,149, 43, 87,226,221,119, -223,133, 68, 34,129, 70,163,193,170, 85,171, 48,115,230, 76,136, 68, 34, 24,141, 70,108,219,182,173,230, 72, 70,124,124,234,229, -203,151, 91,181,110,221,218,121,207,158, 61,133,189,122,245,114,235,211,167, 15,108,108,108,160,211,233, 96, 54,155,209,161, 67, - 7,132,134,134,162,160,160, 0,135, 14, 29, 42, 10, 14, 14,118,189,114,229, 10,159,151,151,151, 94, 87,229, 93,213, 96, 91, 44, - 22,228,231,231, 67,169, 84,162,176,176, 16, 57, 57, 57,200,202,202,130, 72, 36, 66, 93, 47,239, 46, 46, 46, 35, 34, 34, 34,132, - 0, 96, 99, 99,131,150, 45, 91, 98,238,220,185,156, 78,167,123, 5,192,161, 71,187,245, 91,189,122,245,158,243,231,207,139,188, -189,189,145,144,144, 0, 55, 55, 55,145, 92, 46,175,211, 96,121,122,122,174,253,243,207, 63, 27, 84,152,234,138,178, 90, 94,254, -240,114, 12, 31, 62,188,193,134, 13, 27,214, 2,232,255,162, 61, 16,236, 4, 78,162,118, 45,109,148, 7,143, 63,104,222,171,255, -123, 34,175,160,249, 0,128,151, 0,209,177,131,223, 55,239, 31,221,100, 71, 69,191,172,218, 24,218,207,109,233,160, 65, 45, 4, - 99, 71,182, 73, 22, 73, 66,130, 54,109,248,222,163,129,115,212,191, 30, 18,194, 6,176,181, 1, 66,131, 44,130, 75, 91,147, 61, -102,190, 23, 98,220,188,238,141,228, 77, 59,174, 71, 75, 36,183,123, 0,152, 89,147,118, 92,162,121,191, 74,219,160,153,163,228, - 52,129,124, 48, 90,181, 12,134,155,155, 18, 43,127,219, 0, 31,255, 78, 48, 24, 12,112,112,112, 80, 0, 48,153, 76,166, 77,214, -152, 43, 0, 56,113, 66,201,135,135, 43,141, 66, 13,207,189,253,238,210, 97,189,250, 13, 14,235,209, 35,154, 63,122,236,168,169, - 83, 43, 83,110,143, 30, 29,243, 79,157, 62,123, 63, 47, 47, 59, 56, 52,180, 57,238, 37,222,234, 11,144, 88,160,250, 2, 27,123, -159, 30, 14, 10, 34,167,182,109,155,204,235,248,155, 54, 95,124, 25,211,111,192,128, 9, 17, 93,162,186,240,199,142,159, 52, 74, - 81,116,215,174,243, 75,217, 19, 70,191,178,103,219,238, 61,189, 79,157, 60,208, 68,165,206, 63,240,237,207,148,153,171,170, 47, -103, 28,231, 33,146,201, 4,133,167, 78,113,145,147, 38, 85,158, 27,133, 66,129,125,251,246, 65, 42,149, 86,110, 18,137,164,242, -179,135,135, 7, 8,165,130,250,104,230,230,230, 34, 47, 47, 15,142,142,142,112,115,115, 67, 94, 94, 30, 46, 94,188,136,123,247, -238, 65, 44, 22,163,111,223,190, 16,212, 80,111, 62,169, 57,245,171,175,122, 53,109,214,204,255, 73,115,133,135, 5, 19, 37, 37, - 37,136,142,142, 22,156, 56,113,194,243,210,131, 7,131, 1,108,170, 85,115,240,224,226,194, 19, 39,170, 61,118, 68, 68, 4,217, -183,111,159,108,204,232,209, 51, 22,254,248,227,207, 95,254,244, 83,166,133,227, 60,235,147,119, 66,136,128, 16, 2, 63, 63, 63, -148,148,148,160,172,172,172, 34,224, 0,103,103,103,152,205,102,240, 60, 47,102, 37,210,122, 4,117,153, 1,107,204,149, 88, 44, -134, 64, 32,120, 42,147, 85, 53, 66,240, 36,214, 24,172,138,202, 79, 46,151, 63,118,131, 85,152,181,170,159, 43,222,118,172, 64, -168, 86,171,177,107,215,174,202,130,102, 52, 26,161, 82,169,160, 84, 42,161, 82,169,160,215,235,145,154,154,138,173, 91,183, 34, - 39, 39, 7, 66,161,208,170, 73, 91,147,147,147,175, 55,106,212,168,101, 69,229,221,189,123,119,223,179,103,207,230, 84,156,131, - 79, 63,253,180,168, 67,135, 14,174, 85, 43,247, 58, 19, 43, 20,226,226,197,139,208,233,116,160,148, 66, 34,145, 32, 49, 49, 17, - 28,199,129,231,121,136, 68, 34, 20, 22, 22,214, 25,193,138,141,141,157,248,250,235,175,175,152, 52,105,210,169, 15, 63,252,240, - 88,247,238,221, 51, 9, 33, 48,153, 76,112,112,112,128,167,167, 39, 18, 19, 19,161,215,235,241,254,251,239,103,108,216,176,225, -248,202,149, 43, 79,173, 89,179,102, 69, 86, 86,214,235,245,185,222, 28,199, 65,171,213,162,180,180, 20, 37, 37, 37, 80,171,213, -208,235,245, 79, 85,134,162,162,162,112,224,192, 1, 97,207,158, 61,127, 15, 8, 8,200, 11, 8, 8,200,235,217,179,231,239,251, -247,239, 23,250,248,248, 32, 45, 45, 13,215,175, 95, 71,105,105, 41, 40,165,181, 30, 64, 44, 22,119, 31, 63,126,124,103,127,127, -127, 98, 50,153, 96, 48, 24, 96, 48, 24, 96, 50,153,192,243, 60,210,210,210,208,172, 89, 51, 65, 64, 64, 64, 71, 66, 72,119,246, - 8,177, 30,117,193,118,208,242,159, 64, 13, 91,193,171,127,134,246, 41, 39, 35, 41, 45, 45,253,242,173,143, 85, 5, 22,195, 45, -196,199,156,134,166,220, 7,190,141, 39,226,205,215,187,227,234,229,163, 40, 41, 41, 65,124,124, 60,186,118,237, 42, 33,132,212, -171, 92, 30, 59,118,217,242,202,184,119, 95,238,222,123,112,155,232,232,254,220,145, 35,199,141, 55,174, 29,185,222, 36,200,185, -128,242,101,249, 78, 78,138,155, 15, 30,220, 69,112,211, 48,152,204,230, 40, 96, 65,173,229, 41, 41,137, 26,255,250,203,203,242, -202,164,216,113,125,250,190,214,162,103,207, 62,230, 35,199,254,180,156, 59,181,243,102,159, 62, 65,103,190,254,126,187, 95,137, - 49, 52, 92,238,224,121,176, 99,103, 69,212,212, 87,253, 39,179,146, 82, 67, 52, 64, 46,231,241,232,185, 88,209,133,165,170,185, -122,114,179,166, 78,170,170, 89,181, 46, 82, 42,149,184,127,255, 62,190,253,246, 91,220,186,117, 11, 22,203,195,174,118,117,117, -179,168,170,153,152,145,209,227,221,119,223,149, 85,103,174,138,139,139, 81, 84, 84,132,236,236,108, 12, 28, 56, 80, 82,226,236, -220,186, 46, 77, 31,119,119,131, 66, 46,207,191,119,239,222,191,165, 87,173, 86, 67, 42,149,226,199,159,126,146, 28, 73, 72,120, -235,200,201,147,174,245, 57,159, 85,235, 82,119,119,119, 4, 5, 5,161, 85,171, 86,136,140,140,132, 92, 46, 71, 92, 92, 28,126, -253,245, 87, 8, 9,225, 88, 73,124, 78, 17,172,250, 24,172,250, 24, 2,107,177,166,137, 80, 46,151,199,228,231,231,119,242,241, -241, 1,199,113,149,102,234,201, 38,194,138,104,199,221,187,119, 33,151,203, 99,106,211, 84, 40, 20, 49, 66,161,176, 99,187,118, -237,176,123,247,110,156, 58,117, 10, 41, 41, 41, 40, 47, 47,135,193, 96,128, 78,167, 67, 92, 92, 28,120,158, 71, 68, 68, 4, 28, - 29, 29,161, 80, 40, 98,234, 74,171, 86,171,205, 21,139,197, 33, 54, 54, 54,255,106,238,240,242, 66,113,113, 49,111, 54,155,177, -126,253,122,181,167,167,167,173,141,141, 13, 42,230, 31,179,198, 92, 22, 20, 20,192,215,215,183,178, 15,150, 70,163,129,187,187, - 59, 76, 38, 83,101, 4,206,222,222,190, 78,115, 73, 41,213, 3,152, 85, 69,187,237,200,145, 35,183,108,219,182,173,241,241,227, -199,113,229,202, 21,184,185,185,225,171,175,190, 74, 73, 75, 75, 27, 67, 41,189,246,188,175,185, 53, 6,171,184,184,120, 87, 76, - 76, 76,199,118,237,218, 85, 22,186,238,221,187,147,238,221,187,187, 86, 13,233, 23, 22, 22,226,234,213,171, 56,126,252, 56, 8, - 33,184,127,255,190, 69,167,211,109,169,229,216,146,128,128,128,117,115,231,206,181,227, 56,174,178,108,219,216,216, 64, 46,151, - 67, 34,145, 64, 40, 20, 34, 45, 45, 13, 67,134, 12,113,252,233,167,159,214, 18, 66,130, 40,165,166, 23,229,129, 80,198, 43,185, -171,183,116, 78,206,206, 1,119, 46,158, 89,219,241,165, 71,207,136,139,103,214,114,206,206, 1,119,174,222,210, 57,117,241, 83, -114,118,117,232,236, 61, 84, 56,219,100,186,214,247,240,161,152, 97,179,102,190, 41, 13,104, 28,152,127,225, 74, 76,192, 75,150, - 89, 2, 91, 27, 64,171, 3, 74,148, 64, 66,146,144, 15,104, 28,152,127,237, 70,162,244,187,101,107, 2,203,117,198, 61, 7, 79, - 40, 15,215,166,157,149,149,165,247,241,241, 25, 58,107,161,226,204,232, 49,238, 82,137,220, 15,154,210, 27,104, 24,224,130, 87, - 70,132,224,231,223,110,192,193,161,193,195, 8, 6, 33,182,214,230,189,168,168,136,236,218,122,110,210,248,215,222,236,208,167, -247, 0,238,240,145,191, 68,167,142,238,191,184,246,183, 79,246, 80,161, 86, 65,168,198,198,207,223,247, 78,106,202,189, 49, 93, -186,244,134,141, 84,209, 4, 8,173,182,192, 86, 14, 28,160,200, 16, 8, 32, 31,255,218,228,151,250,244, 25,204, 29, 57,178, 23, - 71, 14,110,184, 60,127,126,195,131, 41,217,155, 37,151,174,101,201,135,190, 60,173,244,192,161,187,198, 17,131, 26,221,243,182, -109,169, 99,213,210, 19, 47,144, 34, 81, 62,103, 48,248,249,246,233, 35, 44, 79, 79, 23,219,121,120,112, 0, 96, 54,155,255,205, - 84, 85,141, 96, 9, 4, 2, 64, 32,224,173,209,180, 54, 45,229,229,229,224, 1,206, 26,205,194,146,146,134, 79,246, 49, 54,155, -205, 40, 46, 46,174,220,148, 74, 37,228,114, 57, 74, 31, 77, 26, 90,151,102,151,230,205,215, 47,251,238,187,217,191,173, 94, 45, -169,106,174, 42, 54,129, 64,128, 57,159,124, 34,153,247,245,215,211,134,139, 68,239,213,231,124, 86,188,172, 11,133, 66,136, 68, - 34,164,167,167, 35, 35, 35, 3,233,233,233, 72, 79, 79,135,141,141, 13, 40, 33, 60, 43,145,207,193, 96, 85, 92, 60,107, 59,185, - 91,107, 8, 42,222, 4,158,151,193,210,106,181,199,207,159, 63,223,190,119,239,222,162,203,151, 47,195,211,211,179,210, 96, 85, -252,172,104,118, 82, 40, 20, 56,116,232,144, 73,171,213,214,186,144,164, 78,167, 59,113,226,196,137, 54, 51,103,206, 20, 79,156, - 56, 17,241,241,241,152, 50,101, 10,148, 74, 37,212,106, 53,138,139,139, 81, 94, 94,142,246,237,219, 67, 46,151,227,193,131, 7, -102,157, 78, 87,215, 84, 5,180,160,160,160,204,205,205,205,235,201,127,188,252,242,203, 30,191,252,242, 75,121, 66, 66,130,185, - 83,167, 78, 14,214, 26,141, 10,182,110,221, 90,105,158,238,221,187,135, 95,126,249,165,178,207,213,141, 27, 55,176,116,233,210, -202,185,203,234, 25, 85,188, 22, 30, 30,206,153,205,102, 52,105,210,164,162,121, 21, 43, 86,172,224,254, 14,115,101, 45,122,189, -126,231,132, 9, 19, 62,186,121,243,166,151, 72, 36,170, 8, 93,131,231,121,152, 76, 38, 60,120,240, 0,113,113,113, 72, 72, 72, - 64, 73, 73, 73,229, 11,192,173, 91,183, 74,205,102,243,246,154,116,221,220,220, 62,253,227,143, 63, 60, 21, 10,197, 99,229, 89, - 32, 16, 84, 62,116, 36, 18, 9, 10, 11, 11,225,228,228,132,158, 61,123,186,159, 56,113,226, 83, 0,243, 94,132,135, 1, 33,132, -116,234, 96,215,249,157,105,175,161, 93,107, 77, 82,204,141, 88, 28, 59,248,125,115,224, 97, 39,247,200,214, 17, 73, 87,111,218, -163, 95,239,217,157, 47, 92,158, 82,107, 39,247, 71,125,168, 14,182,111,223,224,252,222,253,199,127,254,120,230,155, 87, 63, 91, -240,177,187,222,160,149,135, 6, 89, 4,192, 67,115,117,233,166,173,126,209,130, 55,175, 46, 94,182,158,207, 40, 48,205,184,114, -165,180,198,209,189, 85, 77,139,179, 29,228,158,126, 51,114, 26, 6,246,104, 20,115, 99, 13, 92, 29, 75, 97,223,164, 19,250,245, -105,143,227, 39, 98,144,158,173, 71, 65, 65, 1, 0,212, 58,237, 65,194,157, 61,227, 40,161,254,132,146, 12, 34,160,242,113, 19, -222,136, 26, 48, 96, 48, 61,112, 96, 63,183,119,207,166,243,219, 55,254,176, 83, 32, 17,139,116, 70, 71, 35, 33,122, 21, 47,176, -143,215,106,139, 31, 62, 60, 37,146,154,151,187,121, 52, 33,107, 88,120,168,231,184, 9, 83, 28,251,247, 27, 66, 15, 30,220,203, -111,223,182,254,212,246, 53,145,155,120,129, 90,146,155, 89, 46, 83,169,205, 42, 74,164, 78,101,106,190, 60, 63, 57, 72,239, 61, -224,101, 19,171,150,158,168, 7, 12,134,172,178,204, 76,175, 6, 93,187,202, 30, 44, 88,160,240,104,223, 94, 95,209,133,165, 54, -131, 37, 20, 10, 65, 1,222, 26, 77,107,211,162,211,233, 64, 9, 49, 63,141, 38,199,113,143,153,171, 10,131,245,232, 89,111, 85, - 58,191,125,255,253,203,109, 95,123,173,228,210,165, 75, 30, 29, 59,118, 36, 26,141, 6, 26,141,230, 49,147,229,230,230, 70, 26, - 7, 6, 42,142,228,230, 6,206,179,242,124, 90,147,119,129, 64, 80,227,249,100, 60,133,193,170,136, 96, 89, 99,176,132, 66,161, - 53,166,192,108, 54,155,225,238,238,142,162,162,162, 26, 43,124,129, 64, 0, 27, 27, 27,104,181, 90, 0,168,117, 36,157, 70,163, - 89,177,104,209,162,233,221,187,119,119, 13, 9, 9, 65, 97, 97, 33, 60, 60, 60, 32,151,203, 43,251,134, 85,232,197,198,198, 98, -219,182,109,106,141, 70,179,162,142,124, 47, 95,181,106,213,219,253,251,247,111,224,234,234, 10,103,103,103,220,185,115, 7,206, -206,206, 80,171,213, 72, 76, 76,132,189,189, 61, 8, 33,208,235,245, 56,123,246,172,134,231,249,229,117,220,152,244,194,133, 11, - 38,133, 66,113,167,176,176, 80, 88, 82, 82, 34, 42, 45, 45, 21,169,213,106,177, 74,165, 18, 31, 62,124,216,213,209,209,177,252, -228,201,147,133,254,254,254,194,212,212, 84,161,209,104, 20, 88, 81, 41,226,189,247,222,131, 68, 34,129,193, 96,192,138, 21, 43, - 48,123,246,236,202, 62, 87,223,124,243, 13,230,206,157, 91, 25, 82,255,243,207, 63,235,107,178, 96, 50,153, 96, 54,155, 97, 54, -155,173, 50,189,207,130, 53, 70,157, 82,154, 71, 8, 25,216,174, 93,187,163, 59,118,236,112,177,183,183, 71, 90, 90, 26,242,243, -243,145,159,159,143,194,194, 66,148,149,149,129,227, 56,248,248,248, 32, 63, 63, 31,123,247,238, 85,105, 52,154, 62,181,141, 32, - 20, 10,133, 19,162,162,162, 68, 79,166,161,226,173,174,194,180,203,100, 50,228,228,228,160,123,247,238,210,211,167, 79, 79,248, - 95, 55, 88, 21,198,165, 89, 48, 36,131, 6,143,150,180,108,211,183,252,234,245,195,233, 54,132, 75,239, 31,221,100, 7,240,112, -154,134,171, 55,237,209,178, 77, 95,193,160, 92, 99,123,101,233,111, 45,195,154, 18, 83,109,203,234, 0,128,171, 35, 63,164, 79, -116,195, 92, 7, 7, 34, 90,180, 96,241,159,191,111, 88,221,238,210,214,127, 77,211,176,104,193,195,105, 26,250, 68, 55,228,226, - 19,238, 13, 1,176,193, 90,211, 50,112, 96,159,155,127,172,221,134,236,212, 63,189,151,127,110, 35,133,190, 20, 16,135, 32,170, -131, 3,174,253,156,133,236,236,236, 60,158,231,107,109,198,165,132,250,199,197,199, 54,141, 12, 15,243, 28, 55, 97,178,195,192, -129, 67,112,224,192, 62,108, 92,191,230,236,136,209,195,127,207, 46, 85, 11,221,197, 10,137,130,242, 82,161,196, 81, 36, 87, 40, - 10, 76, 57, 57, 15, 31,158, 34,177, 3, 48,146, 7,106,142, 12, 79,157, 60,214,177, 71,244, 16,252,117,112, 31, 54,174,255,237, -204,103,225, 47,175,105,212,170, 25,105,223,250,219,105,141, 26, 55, 10,208,150,229,171, 5, 68,106,210,235,121,251,111,215,167, - 45, 75,158, 59, 33,249,102,236,200,239,216, 40,194,199,184,179,177,127,255,118,239, 38, 37, 73,220, 58,119,182,201, 57,117, 74, - 97,141,193, 18,137, 68,128, 64,192, 89,163, 73,142, 29, 19, 0,168,117,112,149, 68, 34, 65,121,121, 57, 56, 66, 76,214,104,186, -223,186,149,153,150,150, 22,236,228,228,244,152,185, 42, 41, 41,169,252,172,215,235, 97, 52, 26, 97, 35,151,199, 89,163,153,127, -246,172,126,238,196,137,243,222,126,235,173, 31,182,110,219, 38,119,116,116,132, 74,165,122,204, 96, 25,141, 70,180,107,223, 94, -178, 54, 33, 97, 28,128,249,214,156, 79,143,238,221,235,236,239,251,200,176,178, 38,194,250,212,103,117, 53,213, 88, 59,138,176, -186,138,145, 16, 18,253,196,239,115,251,245,235,167, 79, 73, 73,129,191,191,127,165, 73,169,122, 76, 7, 7, 7, 56, 57, 57, 33, - 33, 33, 1,107,214,172,209, 17, 66,230,214,166, 89, 82, 82,162,209,235,245,163, 70,143, 30,173,147, 72, 36, 8, 13, 13,173,156, -255,138,231,121, 72,165, 82,216,218,218, 34, 54, 54, 22, 19, 38, 76, 40,215,235,245,163,158,156, 3,235, 73,205,180,180, 52,149, - 86,171,125,245,213, 87, 95, 45,191,119,239, 30,162,162,162,112,251,246,109,148,149,149,161,172,172, 12,169,169,169, 8, 11, 11, -131,209,104,196,206,157, 59,117, 90,173,246,213,180,180, 52, 85,109,154, 26,141,102,208,146, 37, 75,132, 7, 15, 30,108,228,235, -235, 27,222,182,109,219,144,158, 61,123, 6, 13, 27, 54, 44,160,127,255,254, 94,193,193,193,250, 62,125,250,184,245,235,215,207, - 77, 40, 20,138,147,146,146,114, 41,165,253,106,211,172,106, 74,238,221,187, 87,217, 36, 40, 18,137, 80, 84, 84, 84, 57,211,126, -197,195,168, 58, 3, 92,147,102, 85,147, 93, 97,172, 42,140, 86, 93,207,254,234, 52, 9, 33,117, 86, 24, 82,169,180, 34,194, 73, -235,210,164,148,222,186,123,247,110,175,174, 93,187,222,154, 52,105,146, 38, 47, 47, 15,246,246,246, 8, 12, 12, 68,211,166, 77, -225,234,234, 10,147,201,132, 61,123,246,104,247,238,221, 27,163, 82,169,186, 63, 57, 7,214,147,154, 2,129, 32,181,186,135,107, - 69,244,170,194, 96,201,229,114,248,248,248, 84,156,219,212,250,156,207,167,140, 44,253,189,154,143,140, 75,207, 30,125, 26,247, - 31, 48,212,113,239,254,125,138, 31, 87,174,187,219,101,200,244, 85,174, 1,179,118,187, 6,204,218,221,101,200,244, 85, 63,174, - 92,119,119,239,254,125,138,254, 3,134, 58,246,236,209,167,113,124, 92, 66,200, 99,235, 18, 86,147, 78,133, 84,214,190, 75,167, - 96,229,217, 11,103,185,197,203,214, 91, 58,189,212,255,202, 15, 63,172,218,254,195, 15,171,182,119,122,169,255,149,197,203,214, - 91,206, 94, 56,203,117,233, 20,172, 84, 72,101,237,173,201,251,212,201, 99, 29, 7,244, 31,130, 3, 7,246,112, 91, 54,174,248, -102,223, 17, 99,215,151, 39,235,243,211, 83,111, 80,148,175,131,155, 67, 12, 50, 50, 50, 84, 28,199,117,175,174,131,123,117,154, - 83,222, 28, 91,213, 92,157,115,241,140, 90,125,247, 46, 44,199,142,253,105, 62,113,226,166,238,220,173, 2,213,245,248,162,146, - 98,181, 62, 69,171, 81, 27,121,158, 7,229, 45,194,133, 11, 65,106,187, 70,157, 58,117,195,201,227,155,177,126,221,175, 42,158, -135,254,229, 29, 59, 44, 35, 71, 46,160, 1, 13, 27, 6,108,218,186,153, 12, 28, 60,212,145, 2,252,160,225, 67,156,182,108,219, - 66, 26, 55,105,220, 48, 48,240,225,212, 52,255,147,101,233,111,208,156, 79,105,169, 58, 61,253,204,141,159,126, 50,120,140, 26, -213, 64,234,225,225, 0,158, 39, 21,207,247,154, 54,145, 72,244, 88,196,165, 54, 77,143, 6, 13,178,143, 28, 57,130,144,144, 16, -248,248,248, 60,214,229,165, 98, 34,109, 87, 87, 87, 28, 59,118, 12, 20,184,110,141,102,152,183,247,141,159,127,250,201,200,243, - 60, 74, 75, 75,255, 45,122, 85, 90, 90, 10,158,231,113,246,204, 25,163,170,172,108,189,181,121,111,111, 52,150, 13,109,211,230, -235,241,227,199,155, 82, 83, 83,193,243, 60,170, 70,178, 10, 10, 10,160, 80, 40, 80,174,211,249,121,120,120, 40,172,209, 44, 56, -124,216, 22,117, 60,215, 5, 2,193, 99, 77,132,127,199,117,255, 71, 69,176, 56,142,131,159,159,223, 99,243,140, 8, 4,130,199, -182,250,140, 32,204,206,206,222,224,225,225,113,100,220,184,113,243, 90,182,108, 57,117,198,140, 25,194,198,141, 27, 67,165, 82, -193,217,217, 25,238,238,238, 72, 77, 77,197,153, 51,103, 44, 74,165,114,149,197, 98,249, 60, 63, 63,191,208, 10,221, 83, 62, 62, - 62, 3,123,247,238,189,237,237,183,223,118,236,218,181,171,216,219,219, 27, 0, 16, 23, 23,135, 67,135, 14,153,182,108,217,162, -214,235,245,163,172,153,197, 29, 0,114,115,115,143,122,121,121,141,152, 48, 97,194,166, 97,195,134,217,235,245,122,113,106,106, - 42,140, 70, 35, 56,142, 67, 73, 73,137,233,204,153, 51,101,229,229,229, 99,115,115,115,143, 90,161,119,131, 16, 18,102, 50,153, - 38,220,188,121,243,203, 17, 35, 70,184,188,244,210, 75, 18,142,227,112,254,252,249,194, 86,173, 90,185,171,213,106,211,133, 11, - 23,138,245,122,253,220,156,156, 28,171,150,202, 33,132, 64,173, 86,195,213,213, 21, 6,131, 1, 60,207,195,104, 52,194,206,206, -174,114,121, 35, 74,233, 83,247,145,227, 56, 78,104, 50,153, 48,122,244,104,240, 60,143, 21, 43, 86,128,227,184,122,139,217,217, -217, 93,143,139,139, 27, 24, 30, 30, 94,105, 90, 42,202,144, 76, 38,131,171,171, 43, 92, 92, 92,112,252,248,113, 8,133,194,235, - 86, 70,215,110, 3,104, 69, 8,121, 41, 38, 38,102, 60,128,150, 38,147,201,199, 98,177, 16,129, 64,144, 75, 41,189,163, 86,171, -127,183,118,169,156,130,130,130, 47, 95,123,237,181, 86,155, 55,111,182, 19,137,254,117,107,136, 68, 34,200,100, 50,184,187,187, -195,209,209, 17,148, 82, 24,141, 70,124,250,233,167,106,173, 86,251,229,139,242, 48,104,211,182, 61,126,251,229,123,187, 19, 39, -143, 20,222,189,143,125, 85,167, 98,176, 3,112,225,242,148,125,202,210,223, 90,230,100,102,218,181,105,219,222, 42, 77,163,133, - 43, 30, 53,118,149,223,163,165,114,190, 76, 77, 73, 95,190,121,221, 27,201, 0,240,221,178, 53,129, 25, 5,166, 25,241, 9,247, -134,172, 92,117,186,189,209,194, 21, 91,163,249, 47,211,178, 73, 5, 10,125,118,118,246, 21, 95, 95,223, 70, 81, 67, 76,115, 67, -130,200,224,252, 34, 62,155, 16,242, 78,118,118,118,178,181,121,239,220,169, 43, 78, 30,221,130,141,235, 55,169, 41, 47,212,187, -186,186, 82, 0,184,123,215,149,222,189,171,164, 64,197,124,141, 78, 90, 55, 69,225,231,115,231, 76,157,169,209,104,150,255,252, -109,237, 19,206, 54,111,209, 1,205, 91,116,192,244,119, 62,113, 12, 11, 15,245, 7,128, 29, 59,168, 37, 34,152,252, 57,239,179, - 5,131, 63,255,124, 1,212, 26, 3, 62,255,252,225,178, 58,137,177,241,127, 37, 37, 81, 35,171,154, 30,103, 30,199, 93,193,204, -153,193,229, 37, 37,110,157, 63,250,200, 85,244,237,183,130,234, 58,185, 87, 68,176,170,222,191,214,104, 30, 62,113,226,175, 15, -102,206,204, 94,250,237,183,125, 22, 47, 89, 98,211,172, 89, 51,228,229,229, 33, 52, 52, 20, 62, 62, 62,184,112,225, 2,142, 28, - 60,168, 45,211,233,230,122,122,122,174,180, 70,243,199, 45, 91, 18,187,244,232, 81,180, 97,195, 6,239, 30, 61,122, 16,173, 86, - 11,149, 74, 5,149, 74, 5,131,193, 0,137, 68,130,236,236,108,154,145,153,121, 55, 43, 43,107,149,181,121,183, 20, 22,202,103, -101,100,100,137,214,173, 91, 50,101,242,228,217, 51,103,205,146,249,250,250, 18,131,193, 80, 25,197, 50,153, 76, 80, 40, 20, 38, -141, 70,227, 2,160,220, 26, 77,217,159,127,114,197,197,197,112,113,113,169,156,118,169,234,188,130, 90,173, 22,148,178, 73,112, -235,245,162, 80, 83, 29, 30, 26, 26,122, 93, 36, 18,249, 86,141,102,213,244,179, 74,101,156, 21, 27, 27,219,166,170,195,165,148, - 86,219,223,201,215,215, 55,144,231,249,175, 94,122,233,165, 17,111,190,249, 38, 57,115,230, 12, 78,158, 60, 73,179,178,178,118, - 10, 4,130,185, 89, 89, 89,201, 53,189,217,212,164,217,160, 65, 3,123,123,123,251,247,109,109,109,163, 43,166, 98,144,203,229, - 49, 90,173,246,184, 70,163, 89, 81,211,236,237,181,105, 54,110,220,216,129,231,249,247,108,109,109,123, 21, 21, 21,181, 4, 0, - 87, 87,215, 91, 90,173,246,152, 64, 32,248,190,166, 5,164,107,211,244,246,246,182,177,179,179,251,178, 65,131, 6,175,190,249, -230,155, 46,103,206,156,201,189,117,235,150, 68,173, 86,111,230, 56,174,198,197,158,171,211, 12, 11, 11,123,108, 45,194,231,121, -141, 0,160, 69,139, 22, 7, 6, 13, 26, 52, 96,236,216,177, 48,155,205, 88,185,114, 37,142, 29, 59,246,215,253,251,247, 7,214, -246,246,249,164,166,167,167,167,171,143,143,207,233,113,227,198, 5, 12, 29, 58, 84,225,224,224, 0,161, 80, 8,173, 86,139,148, -148, 20,220,185,115,135, 30, 59,118,172, 44, 46, 46, 46, 75,167,211,117,203,203,203, 43,178,246,124, 62,203, 91,242,147,154, 98, -177,184,171,159,159,223,214,249,243,231,219,247,234,213,203,198,197,197, 5, 66,161, 16,102,179, 25,185,185,185,136,141,141,197, -145, 35, 71,180, 59,119,238,212, 22, 23, 23,143,166,148,158,249, 79,164,243,121,106,134, 53, 37,159, 61,177,128,115,141,179,179, -215,182,175, 53,233, 28, 16,237,220,127,196,136,182,209, 0,176,107,215,181,227,127, 29, 47, 61,248,180,233,172, 43,173,214,104, - 54, 11, 22,206,143,139,143,125,108, 34,202,240,176,136,123,205, 34,135,127, 97,141, 86,197, 76,238, 79,230,189,202,236,248, 85, -222, 8, 30,111, 78,173, 88, 16,250,147,185,115,240,213,151, 95, 99,223,142, 61,127,197, 39,209, 3,255,203,101,233,239,212,172, - 88,156, 88,225,229,213,101,139,171,235,156,163,199,143,219, 85,125, 81,171,136, 52, 87,125,153,108,217,178,101,193,173, 91,183, - 60,172,209, 28,248,227,143, 38,189,189,189,108,241,170, 85, 93,203,141,198,174,179,102,205, 18,221,184,113, 3, 91, 54,109,226, -116,153,153,155,242, 44,150,247,170,107,253,168, 77, 51,232,131, 15,228, 95,109,222, 60,177, 97,227,198,238, 67,134, 12, 17, 11, -133, 66,104, 52, 26,228,228,228,224,226,133, 11,198,148,212,212,248,242,242,242,193, 89, 89, 89, 57,214,106, 14,252,241, 71,147, - 83, 96, 32, 20,110,110,244,194,165, 75,142, 31,206,159, 63,213,211,203,203,177,115, 84,148, 88,161, 80,160,180,180, 20, 25, 25, - 25, 56,119,238, 92, 65,114,114,178, 55,165,212, 98,141,230,254,152,152,230, 39,175, 92,121,249,195, 15, 63,148,134,132,132,192, -222,222, 30, 26,141, 6,241,241,241,184,120,241,162, 97,235,214,173, 42,173, 86, 59, 53, 51, 51,115,255,223,117,221,255, 49, 6, -235,255,235,198,243,244,244,108, 35, 16, 8, 62,123,212, 28,181,168,174, 53,253, 94,164,135,142,151,151,151,191,179,179,243,111, - 58,157,142, 26, 12,134, 41,185,185,185, 25,255,109,233, 36,132,136,218,180,105,243, 75, 65, 65,193, 75,148, 82, 56, 58, 58, 94, -140,139,139,123,139, 82,202,213, 87,147, 16, 34,244,244,244,124,201,214,214,182,189,173,173,109, 87,147,201,212,236, 81, 63,188, -187,229,229,229,103,204,102,243,149,188,188,188,139,148, 82,203,127, 50,239,132, 16, 33,128, 94,222,222,222,111,240, 60,223,132, - 16,226,100,177, 88, 96, 54,155,149, 60,207, 63, 80,169, 84,107, 0, 28,251, 79,167,243,121,105,134, 55, 33,195,168, 0,205,106, - 50, 2,143, 25,154, 39,140, 3,225,113, 55,238, 1,221, 99,109, 58, 9, 33,130,161,253,220,150, 2, 15, 71, 26,214,181,228,208, - 99, 6,203, 10,211, 82,111,115,217, 68,244, 26, 37,212,255,241,135, 34,201, 8,109, 62,108,227,179, 24, 44,107, 9, 15, 33, 93, - 65,241, 18, 79,113,229,238,125,122,242, 69,125,214, 61, 79,205,175, 9,105,176,163,105,211,139, 2,145,200,147, 16, 34, 0, 0, - 34, 16,240, 60, 96,129, 64,192, 85,109, 22,172,250, 66, 89,151,166, 9,136, 20,203,100,126, 22,142,243, 40,145, 72,236, 46,216, -218,182, 54, 0,101,158, 22,203,103,199,139,139, 19,159, 38,157, 38, 32, 82, 40,147,249, 95,176,183, 31,162,116,118,110, 94,106, - 50,185, 1,160, 54, 54, 54,119,203,202,203,215,167,165,165,253, 92,205,162,234,117,106, 74,100, 50, 95,203,163,145,135, 2,145, -168,224,136, 76,230, 87,232,230, 54,190, 92,167, 11,144,203,229,102, 74,169,218,100, 50,141,205,200,200, 56, 81,159,188,103, 8, -133, 97,119,236,237,163, 44, 14, 14, 46,102, 66,108,141, 22,139,201,100, 54,103, 26, 12,134, 24,161, 80,184, 44, 43, 43, 43,233, -239,188,238, 47, 28, 21,163,205,254,142, 13, 64, 52,211,100,154, 76,147,105, 50, 77,166,201, 52,255,126, 77,119,119,119,133,167, -167,167, 63, 0,225,255, 98,222, 95,180, 77,196, 44, 38,131,193, 96, 48, 24,255,251,228,231,231,151,163,154, 62, 87,140,255, 80, - 19, 33,128,232, 26, 34, 91, 86,135,254,158,102, 52,129, 21, 77, 9, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,193, 52,235, -210,126, 97,154, 30, 89, 19, 33,211,100,154, 76,147,105, 50, 77,166,201, 52, 89, 19,225,243,221, 4, 96,212,228,172, 61, 8, 33, - 30,207,123, 95,198,139, 93, 22,170,249,174, 15, 33,196,167,158,251,123,177,179,206, 96, 48, 24,255,219,252,191,247,193,170,168, -168, 40,165,249,207, 99,191,231,253,221, 71,223,255,154, 16,124,248,232,243, 55,148,210, 57,207, 99,223,186,240,246,246,246,107, -208,160,193,107,174,174,174,157,138,139,139,207,230,230,230,174, 45, 42, 42,202,173,199,247,131,229,114,249, 91, 2,129, 32, 2, - 0,120,158,143,213,235,245,191,228,228,228,220,127, 14,215,141, 0,152, 44,147,201, 94,113,118,118,110, 82, 82, 82,242,192,104, - 52,238, 0,240,235,211,204, 58,237,229,229,213,218, 98,177,188,139,135, 35, 89,127, 45, 44, 44,188, 96,237,119, 61, 34,134,110, -167, 64, 48, 0, 1, 79,248,151, 5, 84,176, 19, 0, 79,128,251,249,177,123, 95,121,206,229,245,169,175,111,125,191, 75, 8, 89, - 70,128,247, 65, 64,159,181, 44, 49, 24, 12, 6,227,127,200, 96,249,248,248, 76, 0, 48, 27, 15,103,218,254, 46, 59, 59,123,253, -223, 81, 89, 61,199, 74,109, 5,165,116, 86,253,163, 21,248,144,231,169, 0, 0, 4, 2,242,145,135,135, 71,132, 72, 36, 50, 60, -185, 47,199,113, 50, 66,208,151,231, 41,121,180,239,135,132,144,239,159,198,216,185,184,184,120,143, 25, 51,102,211,231,159,127, -110,163, 80, 40,144,145,145, 49,116,206,156, 57,209,222,222,222,227,115,114,114, 50,235,250,126,227,198,141,199, 68, 54,111, 57, -115,206, 39,159,217,185,185,187,219,114,156,197,148,153,157,165,248,246,235, 69,237, 27, 55,110,252,125, 74, 74,202,150,250, 24, - 41,145, 72,244,138, 92, 46, 15,210,235,245, 73, 28,199,237, 20, 10,133,125,190,252,242,203,136,254,253,251,203,213,106,181,148, -227,184, 38, 27, 55,110,156,249,199, 31,127,244, 35,132, 12,169,109,184,125, 69, 4,135, 82,154, 93,229,220,189,117,227,198,141, - 30, 98,177,152, 60, 90,180,249, 66,109,251, 87,133, 2,193,113,231,119, 68, 2, 64,120,231,145,247,226,206,239,192,163,207,207, -253,101,224,201,178,224,236,236,188,185,180,180, 52,190, 46, 35, 95,221,119, 9, 33, 63, 80, 74,243,188,189,189, 59, 1,120,235, -209,174,191,228,228,228, 92, 32,132,120,202,101,178,247,117,122, 61, 1, 64,158,165, 44, 49, 24, 12, 6,227,127, 47,130, 53,231, -222,189,123,246,148, 82,132,132,132,124, 12,192,106,131,245,100,133, 35, 20, 10, 62,238,213,171,215, 68,153, 76,246, 88,197,108, - 48, 24, 4, 2, 1,113,183, 88, 30,254,185, 62, 21, 77,197, 49,140, 70,131, 64, 44,150, 66, 40, 20,204,108,217,178,101,191,252, -252,252, 67, 50,153,236,155,212,212,212,130,167,137,220,172, 95,191,190,149,139,139,203,191, 25,136,226,226, 98, 65,191,126,125, - 73,125,244, 38, 18, 34, 51,200,100,237, 37,132,120, 89, 56,206, 9, 0, 68, 34, 81,105, 19, 15,143,174,159,206,153, 99,243, 72, - 23,101,101,101,120,237,181,215, 20, 15, 30, 60, 24, 11,224,171, 58, 34, 87, 77, 91,180,106, 51, 99,203,230, 77,205,212, 37,165, -250,213,203,127,189,161, 19, 73,202, 27,133,133, 74, 22,125,189,204,249,211,143,102,190,227,237,237,125,171,186,101, 67,158,200, -171, 0,192,158,247,223,127, 63,124,224,192,129, 82,141, 70, 35,215,233,116, 13, 55,109,218,244,105,155, 54,109,236, 90,182,108, - 41,221,186,117, 43, 81,169, 84,160,148, 42, 66, 67, 67,233, 43,175,188,162,223,182,109,219,116, 0, 63,212,199, 44,243, 60, 47, -172,174, 28, 90, 99,174, 9,112, 63,188,243, 72,128,160, 73,220,249, 29,242,240,168,145,122, 80, 60, 32,192,253, 71, 47, 2,159, - 3, 85,230,117,122,156,187,217,217,217, 79,181,118,224,128, 1, 3, 9,165,116,143,183,183,247,137,162,162, 34,123, 66, 48,186, - 30,209, 41,226,230,230,246, 14,128, 79, 40,165,239,159, 58,117,170, 35, 0,116,239,222, 93, 2,224,130,163,163, 99, 79,163,193, - 64,216, 35,137,193, 96, 48,254,129, 6,139, 82, 42, 3,128,115,231,206,129, 82, 42,127,154,160, 64,213, 95,102,205,154, 5, 23, - 23,151, 39, 77, 11, 78,158, 60, 81,227,119,234,123,140,175,191,254,218,169,160,160, 96,244,239,191,255, 62,212,211,211,243,237, -188,188,188,195,117,228, 49,159, 16,242,205,163,136, 3,145,203,109, 74, 39, 77,154,116,241,209,255,154,253,249,231,159,246,131, - 6, 13,210, 16, 66,238, 2,128, 92,110,211, 85, 40, 20, 56, 83, 74, 41,165,248,166, 54, 35, 56,146,144, 64,169, 84,218, 99,202, -143, 63,114,173, 7, 13, 18,217,186,185, 17, 0, 72, 79, 72,112,253,225,167,159,186, 40, 51, 51,101, 34,123,251,178,252,210, 82, -227,189,123,247, 32,151,203,137, 64, 32,232, 84, 87,134, 21, 10,197,187,179,102,127,108,171, 46, 81,234,244,106,141, 81,200,153, - 13,246, 54, 10, 75,126, 94, 65,177,157,141,109,249,228,183,223,149,206,255,100,246,187, 85,162, 38, 53, 49,125,230,204,153,205, -218,181,107,231,179,125,251,118,162, 82,169, 32, 18,137,236, 90,182,108,137, 54,109,218, 88, 78,158, 60, 73, 26, 53,106,132,136, -136, 8,156, 63,127, 30, 23, 47, 94, 36,173, 90,181, 82,236,222,189,123, 92,117, 6,171, 58, 83, 61,102,204,152,137, 82,169,148, -239,218,181, 43,222,120,227, 13, 80, 74,209,170, 85,171, 78,227,198,141,203,213,233,116, 86,153,235,138,102, 64,247,136,161,119, - 0, 68,130,226, 65, 65,236,222,230, 85,118,105,150,152,152,216,161,180,180,180,178,179, 97,197,194,226, 93,186,116,169, 79,121, -207, 39,132,124, 51,104,208,192,143, 1,130,232,232,232,178,233,211,167,211,196,196,196,222, 67,135, 14,105,116,255,254,131, 26, -211,249,100, 57,154, 58,117,154, 86, 44, 22,191,230,237,237, 29, 79, 8, 17,139,197,226,138,115, 36,106,216,176,161, 71,100,100, -228, 28, 47, 47,175,114,161, 64,160,160,168,187, 44, 49, 24, 12, 6,227, 5, 50, 88,132,144,156,219,183,111, 55, 44, 47, 47, 7, - 33, 36,199,138, 10,234,120,213, 10, 71, 36, 18,253, 38, 20, 10,166, 0, 64,219,182,237,180, 75,150, 44,169,174, 89,137,111,219, -182,157, 86, 40, 20,216, 62,172,188,132,191,114, 28,151, 95,157,102, 13, 21,226,183, 82,169,236, 3, 0,196,215,215,175,108,223, -190,125,252,136, 17, 35,240,237,183,223,202, 62,254,248,227,159, 27, 54,108,216, 61, 45, 45, 45,189,166,116, 62,250,125,142,135, -135, 71,196,250,245,235, 91, 77,154, 52,233, 98,118,118,246,240, 71,145,145,221, 0, 58, 16, 66,238, 86,253,219,238,221,187, 95, -154, 48, 97,194,205,252,252,252, 57, 53,105,142, 32, 36, 40, 32, 52,180,199,231,103,207, 82,129,193, 64,138,206,157, 83,151, 20, - 22,154,146,138,138,108, 55,199,196,140,254,112,225, 66,137,167,143, 15, 46, 28, 61,106,159,167, 84,106,148,229,229,198,212,212, - 84,222, 98,177,156,176, 34,239,225,110,174,174,138, 95,151,173,188,102, 47, 22,242,238,190, 62, 68,220,160,129, 72,160,112,144, - 10, 69, 2, 67,163,134,129, 82, 0,225,117, 93, 35,137, 68, 50,174,119,239,222,138,109,219,182,145,136,136, 8, 56, 57, 57,225, -220,185,115,184,117,235, 22, 74, 75, 75, 5,102,179, 25,109,219,182,197,146, 37, 75,224,239,239, 15,165, 82,137,140,140, 12, 87, -169, 84,234, 86,203,249, 36, 85,202, 15, 62,250,232, 35,184,185,185,193,108, 54,163,164,164, 4, 22,139, 5,182,182,182, 0,128, -188,188, 60,236,219,183,183,206,178,100,165, 57, 66,199,142, 29, 43,141,112,213, 8, 86,125, 52,125,124,124,206, 21, 22, 22,141, -236,209,163, 7, 74, 74, 74,184, 5, 11, 22,160, 69,139, 22,104,218,180,169, 53,101,126,142, 76, 38,251, 35, 32, 32, 96,221,212, -169, 83, 27, 58, 59, 59,195, 96, 48, 44, 45, 46, 46,198,135, 31,126, 8, 0,104,215,174, 93, 91, 74,233,173, 73,147, 38,161, 97, -195,134,154,188,188,188,162, 59,119,238, 12, 85, 42,149,119,158, 54,239, 86,158, 31,166,201, 52,153, 38,211,252,175,210,252, 71, - 27, 44, 0,249, 62, 62, 62, 13,109,108,108, 0,160,222,111,215, 28,199, 77,117,119,119, 23,124,250,233,167,131, 26, 55,110,204, - 79,159, 62,253, 66,106,106,234, 99, 29,103, 26, 53,106,180,227,167,159,126,234,148,146,146, 82,254,197, 23, 95,252, 89, 80, 80, - 48,173,158, 23,253, 35, 66,200,114, 0,200,204,204, 44,222,187,119,111,212,217,179,103,191, 94,190,124,185,239,244,233,211,101, -211,167, 79,255, 8, 64,157,154, 34,145,200, 80, 93,179, 96,117,184,184,184,240,213,245,209,170, 96, 16, 33, 54, 14, 82,105,247, -207,207,158,165,198,180,180,242,109, 63,255,108,179,234,218,181,121,102, 74,189, 60, 60, 60,132, 93, 59,119, 54,216, 75,165,154, -252,156, 28,222,217,215,151,164, 36, 37,217,153,133, 66,211,225,195,135,203, 10, 11, 11, 55, 89,145, 4, 53, 79,169,209,206,215, -223,252,242,208, 94, 17,215,174,220, 74,176,119,119, 21,180,106, 25,209, 60,225, 94,218, 13,240, 22, 19, 0,117, 93, 34,142,142, -142, 77,139,139,139,161, 86,171,225,230,230,134, 21, 43, 86,192,211,211, 19,229,229,229,136,139,139,163,190,190,190,228,236,217, -179,240,245,245, 69, 97, 97, 33,140, 70, 35, 52, 26, 77,129,193, 96,208,213,100,120, 69, 34,209, 31, 2, 1,153, 68, 8, 65, 72, - 72,168,118,249,242,229, 60,165, 20,205,154, 53,195,240,225,195,177,107,215, 46,196,197,197, 85, 68,154,248,160,160, 38, 90,129, -128,216, 2,224,159, 37,138,195,243, 60,170, 26,225,250,226,237,237,109, 3,224,195,224,224,224, 81,175,190,250, 42, 39,145, 72, -160,213,106,161,211,233, 16, 27, 27,203, 13, 24, 48,176,108,208,160,129,118,127,253,245, 87,173,233, 52, 24, 12, 73, 1, 1, 1, - 35,102,204,152,113,244,215, 95,127,117,153, 59,119, 46,120,158,175,220, 56,142,171, 92,148,123,239,222,189,120,240,224,193,156, -170,230,138,193, 96, 48, 24,255, 12,131,245,204,136,197,226,207,255,250,235,175,222, 95,125,245,149,184,103,207,158,157,188,189, -189, 95,202,201,201,185,248,168, 82,123,169,127,255,254,157,220,221,221,241,253,247,223, 27,197, 98,241,231, 79,233,172,171, 86, -118,167, 60, 61, 61,167,239,222,189,123,255,148, 41, 83,224,229,229,213,254,255, 59,207, 14, 50, 89,171, 73, 43, 86,112, 98,179, - 89,176,245,215, 95,101, 95,157, 56,177, 98,219,246,237,226,118,109,219,130, 2,136,143,139,147,125,243,227,143,178,145, 3, 7, - 22,196, 61,120,128,195,199,143, 27,149, 37, 37, 57,133,106,245,236,252,252,252, 66, 43,140,235,165,148,212, 20,239,168,174, 29, -125,206, 92,141,189,245,242,208,254, 61,196, 34, 1,121,144,150,117,221,203,211,213,241,226,249,243, 58,142,227, 46,213,165,163, -213,106, 83, 57,142,107, 64, 41,117, 59,125,250, 52,220,220,220, 80, 90, 90, 10,179,217, 12,163,209,104, 44, 47, 47,151, 23, 23, - 23, 67,175,215,195, 96, 48,192,193,193, 1, 49, 49, 49,249, 28,199,157,172, 37,109,111, 16, 66, 22, 80, 74, 17, 31, 31,159, 13, - 0,126,126,126, 97, 78, 78, 78,199, 42, 22, 80, 62,123,246,108,239,172,172,172,184, 42,145,174, 90, 59,185, 91, 27,193,122, 90, -188,188,188, 90,203,229,242,111, 62,254,248, 35,239, 22, 45, 90,160,176,176, 8, 60,207,195,206,206, 14, 58,157, 14,246,246,246, -232,212,169, 83,222,130, 5, 11, 82, 40, 69, 63, 74,105, 94,109,122,233,233,233,121,254,254,254,163,167, 76,153,242, 99,112,112, -112, 83, 74, 41,130,131,131,209,187,119,111, 28, 58,116, 8,247,238,221, 67, 89, 89, 25,119,245,234,213,213, 57, 57, 57,219,216, - 99,137,193, 96, 48,152,193,170, 55,217,217,217,217, 62, 62, 62, 27,110,222,188, 57,233,149, 87, 94,193,169, 83,167,230, 2,232, - 7, 0,114,185,124,238, 43,175,188,130,155, 55,111,226,238,221,187, 27,178,179,179,179,159,199, 49,165, 82,169,214,104, 52,226, -209, 49, 20,245,172,168,155, 61,106, 26, 4,165,180, 89, 77,127,171, 13,129, 72,228, 21,217,183,175,168,244,214, 45,245,242,243, -231, 23,109,217,186, 85,220,190, 93, 59,152,204,102,240, 22, 11,252,252,253,209, 35, 58, 90,182, 97,251,118, 91, 78,171,189,240, -217,123,239, 29, 90,249,218,107,101,151,203,202, 30, 88,147, 70,173, 86,251,195,103,159,124, 20,189,109,251, 46,159,176,208,160, - 6,135,143,158,186,233,226,226,168,104,218,164,137,173, 82,169,178, 44, 91,250,149,168,172,172,236,199,186,116,116, 58,221,158, -227,199,143, 15,245,243,243,115,139,141,141,133,209,104,132,197, 98, 65,207,158, 61, 43,250,223,241, 34,145, 8, 9, 9, 9, 48, -153, 76, 5,247,239,223,207,121,240,224,129, 12,192,226, 58,206,225,147,215,113,210,128, 1, 3, 96, 54,155,209,187,119,111,236, -221,187,247,117, 0, 51,106,217,255,169, 12, 86,213,235, 4, 43, 59,183,123,123,123,247,106,210,164,201,247, 75,150, 44, 17,248, -250,250,130,231,121, 56, 59, 59,163,188,188, 28, 69, 69,197, 8, 11, 11,131,159,159, 31, 22, 47, 94, 12, 0, 91,235, 50, 87, 21, -100,100,100,220, 5,208, 61, 40, 40, 72,170,215,235, 59, 69, 71, 71,111,236,217,179, 39,110,222,188,137,139, 23, 47,246, 32,132, -228,233,245,122,179,143,143,207, 44, 0, 78,148,210,223,172, 25, 61,202, 96, 48, 24,140,255,113,131, 21, 20, 20,100, 47, 22,139, -186, 77,155, 54,213,206, 98,225, 33, 22,139,186, 55,108,216,208, 49, 45, 45, 77,245, 20,149,223,247,155, 54,109,122,117,217,178, -101,178, 1, 3, 6, 52,247,242,242,234, 13, 0, 35, 71,142,108,238,224,224,128, 77,155, 54, 25, 40,165,223, 63,175, 76,114, 28, - 55,180, 77,155, 54, 40, 41, 41, 65, 90, 90,218,197,250,124,247,207, 63,255,180, 7,208,161,174,191,213,122,124,163,209,217,201, -199, 71,144,125,234,148,169, 68,173,246,174, 48, 87, 2,129, 0, 37, 37, 37, 72, 79, 75,131,131,189, 61,226, 19, 19,101, 43,223, -125,119, 91, 64, 68,132,216, 98, 52,186, 88,171, 95, 88, 88,168,245,244,244,156, 56,239,179, 79,247,252,248,211, 79,110, 74,181, - 58,201,198, 70, 97,144,201, 36,158,243,230,205,181,168, 84,170, 9, 69, 69, 69,101, 86, 72, 45,222,188,121,115,223,190,125,251, -222,241,247,247,119, 47, 44, 44,244, 84,169, 84,180,164,164,132,224, 97, 95, 42, 2, 0,119,238,220, 65, 90, 90, 26,103,177, 88, -206, 2,248,156, 82,106,180, 54,173,222,222,222, 46, 29, 59,118, 28,230,238,238, 94,217, 20,217,178,101,203, 97,222,222,222, 95, -230,228,228, 20, 63,207,194,125,236,216, 49,123, 74,105, 7, 74, 41,250,246,237,107,237,215,222, 26, 56,112,160,128, 16, 2,157, - 78, 7,153, 76, 6, 91, 91, 59,216,219, 59,160,105,211, 16,100,103,103,163,119,239,222,150,164,164,164, 45, 18,137,228,135,250, -166, 73,167,211,141,233,212,169,211,194,105,211,166,129,231,121, 12, 25, 50, 4,153,153,153,235, 82, 82, 82,214,248,250,250, 78, -155, 52,105,146,135,139,139, 11,102,205,154,165,168,106, 58, 25, 12, 6,131,241, 2, 26, 44,111,111,239,104,103,103,231,165, 78, - 78, 30,118, 71,142, 28, 21, 1, 64,215,174, 93,108,205,102,238,146,183,183,247,199, 57, 57, 57,127,214,231,160, 57, 57, 57,197, -222,222,222,191, 94,188,120,241,189,225,195,135,227,216,177, 99,159, 0,192,240,225,195,113,241,226, 69,164,164,164,252,250,188, - 42, 91, 31, 31,159, 9, 93,187,118,125,187, 93,187,118, 56,112,224, 0, 44, 22,203,193,250,124,191,234,136,193,234, 70, 17, 86, -252,205, 42, 49,161, 16,132, 16, 88, 44, 22, 80,158, 71, 81,113, 49, 18, 18, 19, 81, 90, 90, 10,139,197, 2, 93,121,185, 57,184, -113, 99,173,202,104,116, 32, 15,231, 26,179,154,188,188,188,244,160,160,160,140,114,189,206,221,197,185,129, 78,161,144, 65,163, - 41,147,196,220,185, 85,150,149,149,149,100,165,241, 53, 18, 66,186, 30, 58,116,104,158, 80, 40,124,197,199,199, 7, 35, 71,142, - 36, 61,123,246,132, 84, 42,133, 94,175, 71,105,105, 41,254,252,243, 79,112, 28,215, 24, 0,220,220,220, 60, 26, 54,108,184, 75, - 32, 16,228,167,164,164, 76,170,235, 24,132,144,241,131, 6, 13, 18, 27,141, 70, 44, 90,180, 8,243,231,207, 71,191,126,253,196, - 55,110,220, 24, 15, 96,217,243, 42,216, 60,207,163, 87,175, 94, 85, 59,185,223,173,235, 59,221,186,117, 19, 9,133,194,144,160, -160, 32, 20, 22, 22,162,176,176, 16,110,110,110,240,246,246,134,187,187, 59,150, 45, 91,134, 21, 43, 86, 92,165,148, 46,206,203, -203, 75,168,111,154,252,252,252,102,189,246,218,107,179, 70,141, 26, 5,141, 70,131,139, 23, 47,162, 83,167, 78, 88,178,100,137, -239,185,115,231, 22,182,105,211, 6, 18,137, 4,167, 79,159, 6,199,113,169,236,241,196, 96, 48, 24, 47,168,193,242,241,241,105, -192,243,252,151, 3, 7, 14, 28, 52,108,216, 48, 44, 89,178,184,138, 87, 16, 97,237,218,117,142,187,119,239, 94,229,231,231, 55, - 76, 40, 20,126,156,150,150,102,117,135,100, 27, 27,155,149,155, 55,111,158,216,177, 99, 71,251,232,232,232, 96, 0,144,201,100, -252,230,205,155, 53, 54, 54, 54, 43,235,155,145, 39, 39,125,244,242,242,234, 44,149, 74,167, 15, 26, 52,168,243,196,137, 19, 17, - 23, 23,135,141, 27, 55,222,246,246,246,222, 95, 79,221,187,117,141, 34,172, 43,154, 37,148, 74,139,149,121,121, 78,118,254,254, - 98, 23, 71,199,156, 83,167, 78, 5,180,111,223, 30,233, 25, 25, 80,150,150, 66,167,211, 33, 46, 46,142, 74, 68,162, 20,145,179, - 51, 73,191,116,137, 8,165,210,122, 27, 76, 91, 57, 9,254,236,195,201, 13,245,122,125,184, 74,165,226,196, 18,137,216, 70, 74, -235,213,204, 68, 41, 53,248,251,251, 15,177, 88, 44,174, 70,163,209,236,225,225, 33, 62,126,252, 56,164, 82, 41, 8, 33,136,140, -140,132, 84, 42, 53,250,250,250,106, 0,192,197,197, 69,176,120,241, 98,241,251,239,191, 31, 87,151,118,235,214,173,197, 1, 1, - 1,147, 66, 66, 66,112,241,226, 69,196,199,199, 39, 94,190,124, 57,164, 85,171, 86,240,241,241,153,212,186,117,235, 31,111,220, -184, 97,126, 30, 5,155, 82, 90,239, 78,238,103,206,156,161,222,222,222, 16, 8, 4, 16, 8, 4,224,121, 30,133,133,133,104,220, -184, 49, 86,174, 92,137, 21, 43, 86,252,146,155,155,251, 84,145,213,160,160, 32,105,139, 22, 45,222, 30, 53,106, 20,146,146,146, -240,213, 87, 95, 21,228,231,231, 31, 60,122,244,232,248,105,211,166,137, 58,117,234,132,226,226, 98,172, 93,187,214,124,243,230, -205, 31,114,115,115, 87,178,199, 19,131,193, 96,188,128, 6,203,207,207,111,162, 92, 46, 95, 56,106,212, 40, 81, 72, 72, 8,242, -243,243,161,209,148, 89, 34, 35, 35, 44, 0,161,118,118,182, 68,161, 80, 96,202,148, 41,104,222,188,121,175,143, 62,250,168,167, -183,183,247,215, 57, 57, 57, 63, 91,115,224,164,164, 36,141,183,183,247, 15, 51,103,206, 92,114,233,210, 69, 91, 0,184,117,235, -150, 54, 39, 39,231,139,156,156, 28, 77, 61, 77, 80,197,228,148,196,214,214,246,126,147, 38, 77,204, 3, 6, 12,112, 25, 54,108, - 24, 92, 93, 93,113,243,230, 77, 44, 94,188,248,166, 86,171, 29,147,150,150,102,254,255, 62,201,156,193,144,119,125,239, 94,251, -110,175,190,234,240,225,208,161, 95,189,249,230,155, 63,207, 95,176, 64, 28, 20, 24, 8,163,201,132,248,248,120,186,117,203, 22, -211,150, 37, 75,190,131,173,173,248,210,174, 93, 82,163,209,152, 94,159, 99,248,250,250,118,237,223,183,107,200,210,101, 63, 64, -175, 43,195,149,139,127,161,180,180, 16,191,254,182, 59,196,215,215,183,107, 86, 86,214, 25,171,211,203,113,129, 59,119,238, 4, - 0, 72,165, 82,124,254,249,231,240,246,246,134,131,131, 3, 52, 26, 13, 38, 79,158, 44,125,255,253,247, 1, 0,113,113,113,176, -179,179,179, 54,202,214,127,242,228,201, 78,102,179, 25,135, 14, 29,210, 75, 36,146, 87,143, 30, 61,122,177,121,243,230,242, 46, - 93,186, 56,109,220,184,113, 0,128,189,207,203, 96, 61,197,119, 44, 62, 62, 62, 41, 71,143, 30,109, 60,114,228, 72, 72, 36, 18, -148,150,150,194,193,193, 1, 63,253,244, 19,175, 80, 40,214, 62, 67,146,164, 10,133, 66,102,177, 88,176,125,251,118,228,231,231, - 15,172,232,143, 56,123,246,236, 47, 66, 67, 67,131, 18, 18, 18,146,245,122,253,220,236,236,236, 7,236,209,196, 96, 48, 24, 47, -168,193,226,121,254,195, 35, 71,142,136, 44, 22, 11, 86,175, 94,141,107,215,174,209,252,252,252,239, 76, 38,211,215, 10,133,130, - 43, 41, 41,153,253,230,155,111, 78,157, 63,127,190, 32, 42, 42, 10,151, 46, 93, 18, 52,110,220,120, 58,128,159,171, 24,159,232, -218,230,202, 40, 45, 45, 61,152,151,151,251, 51,207, 63,172, 12, 5, 2, 98, 43,149,202, 14,214, 97,166, 30,211,172,102, 50,203, -166, 95,127,253,117,129,139,139, 11, 31, 23, 23,135,149, 43, 87, 90,174, 95,191,190,139,231,249, 79,139,138,138,202,173,209,124, - 30, 84,213,148,114,220,141,141,179,103, 55,107, 61,100, 8, 63,252,141, 55, 12, 2,145,232,173,175,150, 47,255,164, 84,169,244, - 6, 33,212,213,217, 57,125,205,151, 95, 46,122,169,123,119,125,220,153, 51,242, 91,199,142,137,221,204,230,219,245, 73,103, 86, - 86,214,153,224, 32,127,172, 91,189, 12, 38,147, 1,185,217, 15,253, 89, 81,177, 10,181,153,171,234, 52, 5, 2,129,242,181,215, - 94, 83, 24,141, 70, 50,122,244,104,113, 65, 65, 1,130,130,130, 0, 0,106,181, 26,127,253,245, 23, 66, 67, 67, 1, 0, 49, 49, - 49,149,159,235, 74,167,141,141,205,164, 78,157, 58, 33, 61, 61, 29,241,241,241, 59,115,114,114,242,189,189,189,119,166,167,167, -143,111,219,182, 45,118,237,218,245,122, 77, 6,171,190,215,200, 26,131, 85, 67,222,223,216,189,123,247, 7,151, 46, 93,234, 59, -107,214, 44,210,189,123,119, 0, 64, 89, 89, 25,159,155,155,171,121, 26,205,170,105,226, 56, 14, 0, 32,151,203, 53, 0,240,200, - 76,141,124, 90,205,231, 81, 62,153, 38,211,100,154, 76,243,191, 65,243, 31, 99,176, 0,152, 44, 22, 11,206,156, 57,131,221,187, -119,115,122,189,126,120, 94, 94,222,245, 42,255,255,194,215,215,119,255,136, 17, 35, 14, 38, 38, 38,138,226,227,227, 1,128,171, -207,193, 13, 6,131,145, 16, 80,252,107, 50, 74,106, 48, 24,140, 79,115,173,171,254,242,251,239,191, 35, 55, 55,215,144,158,158, -190,149, 82,186, 42, 55, 55, 55,235, 25, 34, 33,207, 60,138,112, 45,165,134, 87, 9, 57, 62,191,115,231, 94,243,142, 29,147,189, - 50, 99,134,105,248,168, 81,179, 45, 70,163, 89, 40,145,240, 82, 91, 91,129, 69, 38, 19,199,157, 57, 35,255,126,218,180, 6, 58, -131,225,240,198,122,116, 28,175, 18,193,194,107,111,204,128,174, 74, 4,235,210,181,123,168,111, 4, 75, 36, 18,249,155,205,102, - 25,199,113,217, 60,207, 99,252,248,241,224,121, 30, 58,157, 14, 26,141, 6, 37, 37, 37,250,119,222,121, 71, 0, 0, 10,133, 2, -189,123,247,150, 90,163, 27, 24, 24,216, 72, 44, 22,227,240,225,195, 16,139,197,235, 1, 64, 44, 22,175, 63,118,236,216,248, 49, - 99,198,192,223,223, 63,140, 16, 66,234, 90, 60,186,114,177,103,130, 38,143,174,126, 19,247,136,161,119,170, 44,246,124,183, 85, -171, 86,128, 21,253,174,158, 36, 51, 51, 51, 23,192, 12, 95, 95,223,181, 31,124,240,193,135,237,219,183,111,179, 96,193, 2, 16, - 66,132,207,122,179,241, 60, 15,179,217,252, 76, 83, 72, 48, 24, 12, 6,227,127,223, 96, 45,235,222,189,251, 76, 74,169,136, 16, -242,237, 19,230,170, 34,106, 18,231,227,227,243, 89,227,198,141, 43, 23,128,174,167,121,201, 39,132, 44, 17, 8,200,135, 15,127, -175,255,196,146, 85, 52, 62,122,104, 14,196,219,174, 95,191,254, 73,122,122,122, 54,165,148,123,214, 19,244, 60, 70, 17, 2,192, -102, 74, 83, 71, 19,114,100, 86, 68, 68,116,223,105,211,208,188,111, 95, 7,239,128, 0,139,206,100,226, 99,206,159, 39, 23,119, -238,148,220, 58,118, 76,172, 51, 24, 14,239,166, 52,163,190,233,204,202,202, 58, 19, 20,232,123,244,229,225,253,123, 7, 54,242, - 6, 0, 36,167,230,160,168, 68,117,180, 62,230, 10, 0,210,210,210, 12, 0, 12, 94, 94, 94,195,183,111,223,190,243,145,233,169, - 92,118, 6,128, 65, 36, 18, 5, 3,128, 70,163, 9,216,179,103,207,102,145, 72, 84,167,137,189,123,247,238,154,249,243,231, 79, - 73, 78, 78,222,154,149,149,149, 8, 0,233,233,233,137, 62, 62, 62,223,228,230,230, 78,205,204,204, 92, 73,173,112, 31, 79, 44, -246,140,184,243, 59,228, 0, 34, 43, 22,123,126,218,181, 6,159, 56,159,177, 0,198,250,248,248,116,239,211,167,207,116, 0,121, -207,162,103, 48, 24,204, 6,131,193,204,243,188,216,100, 50, 81,131,193, 96,102,143, 31, 6,131,193,248, 7, 26,172,236,236,236, -245,176, 98, 49,103,107,247,171,197, 32,205, 33,132,124, 95, 97,150,158, 85,195,100, 50, 61,175,245,219,238, 14, 30, 60,184, 94, -251,215,181,195, 86, 74,211,223, 37,100,195,129, 31,127,108,121,120,213, 42, 31, 11,199,185, 16,128, 10,165,210, 98,163,209,152, -230,102, 54,223,174,111,228,170, 42, 73,201, 89,125, 0, 32, 56, 56,152, 62,120,240, 0,148,210,103, 90, 60, 56, 55, 55,247,168, -175,175,175,187, 72, 36,146, 18,242,152,148,225,145, 9, 3,128, 59,132,144, 48, 0,117, 70,120, 50, 51, 51,151, 3, 88, 94, 77, - 25, 90, 1, 96,133,181,233,170, 92,236, 25, 16,240,132,127, 57,188,243,200,157, 0,248,138,197,158,159, 39,217,217,217,167, 0, -156,122, 14,134, 77,223,176, 97,195, 85, 75,150, 44,153,122,251,246,237,223,179,178,178,244,236,241,195, 96, 48, 24,255, 64,131, -245,255,201,243, 88,212,246,121, 47,140,251, 60,162, 32,213,241,195, 67, 3,117,249,239, 60,159,247,239,223, 39,207, 75,235,145, - 17,208,215,113,238, 41,234,217, 60,252, 44, 84, 44,246, 92,133,136,255,133,155, 45, 45, 45,237,235,214,173, 91, 47,205,202,202, - 98,209, 43, 6,131,193,120,193, 17,176, 83,192, 96,252,255,241,188,166,161, 96, 48, 24, 12,198,127, 55, 4, 64,116,117,255,168, -207,232, 0, 66, 72,116,125, 15, 92,151, 62,211,100,154, 76,147,105, 50, 77,166,201, 52, 95, 60,205,186,180, 95,152,209,137, 85, - 59, 47, 63,239, 13, 64, 52,211,100,154, 76,147,105, 50, 77,166,201, 52,153,230, 63,109, 99, 77,132, 12, 6,131,193, 96, 48, 24, -207, 25, 17, 59, 5,213,211,210, 75,184,200,223,215,189, 77,101,148,143,231, 1, 0,252,163, 89, 4, 42,167, 19,224,121, 80, 74, -145, 83,160,188,113, 39,159,126,246,180,199, 11,241, 33, 13,220,229,242, 21, 60,165,157, 31,253,233,140,170,216, 48, 35, 86, 69, -149,214,106, 52,243, 36,205,228, 2,124,192, 83, 52, 7, 0, 1,193, 29, 61,143,111,239,230,209,187,207,122, 62, 8, 33, 36,220, - 13,147,165, 54,138, 81,142, 78,206, 77, 74, 75,139,238,155,244,134, 29,241,133,248,149, 62,197,196, 78, 65, 13, 72, 7,158,226, - 19, 0, 2,177, 0,223,221, 43,166,167, 88,169, 99, 48, 24,255, 79, 60,235,188,118,150,234, 30,147,207,168,201, 38,200,251, 39, - 27,172,112,119, 50, 13, 4, 11, 0, 80, 80, 44,140, 43,160,245, 90, 47, 45,220,155, 68,203,133,194, 53, 0,132,122,147,101, 22, -229,113,182,218,202, 92,128, 46,114,137,240, 59, 0,188,222, 98,153, 20,151, 99,125,123,108,132, 47,233, 43,226, 5, 27,121, 74, -197, 22,158,174, 7,197, 1, 59, 9, 46, 92,202,162,245, 26, 22,239,239,235,222,102,239,213,220,222,167, 86,190,135,246,205,131, - 64, 45, 28,192,155,161,136,250, 0, 39,150,143, 71,251,102,254,160,188, 25,224, 57,216,245, 91,138,126, 17,142, 79,125,115,132, -248,144, 6, 1,174,238,177,171, 87,175,241,244, 14, 12, 35, 60,103, 66,226,213,163, 99,223,255,112, 94,143, 8, 71, 18, 97,141, -201,106,225, 77,222, 8,106, 28,242,193,140, 5,203,132, 94,222,126,182,188,217,192,229,165,222,109,245,195, 55,243,118,181,240, - 38,223,221,206,161,107,172, 53, 82, 97,110,152, 34,146, 73, 71,218,200,109,155,148,151,107, 30, 88, 76,230, 29, 17,222,162,190, -223, 46, 93,209,178, 91,175,254,118, 22, 77,158,192,204, 35,108,251,182,173, 1, 63,254,252, 75,127, 66,200, 96, 74, 41, 95,159, - 60,243, 20, 31,222,219, 48,185,191, 88, 36, 36,205, 94, 95, 45,196, 83, 78,133, 16,230, 65,198, 16,138,168, 58,159, 92, 4,231, -226,243,233,150,167, 57, 70, 51, 15,242, 59,161,104, 10,130,157,132, 98,107, 92, 1, 45, 96,143, 14, 6,227,197,194,215,215,247, - 84, 86, 86, 86,247,231,169,233,237,237,221, 33, 39, 39,231, 50, 59,187,204, 96, 89, 81,251,226,139,184,164, 76,103, 88, 76, 8, -111, 26,184, 8, 64,189, 12,150, 92, 40, 92,127,237,126,190, 39, 56, 19, 86,127,249,214, 54,163, 25,224,204, 38, 88, 56, 51, 44, -156, 25, 28,103,130,197,108, 6, 53, 27, 48,239,143, 83,128, 81,131, 54, 17,193,235, 1,120, 89,123, 12, 49, 21,108,188,113,254, -104, 3, 98, 84, 97,203,202,175,223,201, 44, 44,123,231,248,157,156,162,112, 15, 50, 39,190, 0,107,235, 99, 4, 78,173,122, 15, -155,246,252,149,245,253,239,218, 4,158, 82, 52,112,176, 9, 25, 59, 48,206,111,195,190, 83,153, 43,214,235, 19, 0,192,209, 86, - 26, 50,225,206,125,255,103,185, 8,238,114,249,138, 95,127,249,209,211,203,197,134,112, 23, 23,131,179, 88,224, 23, 48, 64, 56, -103,250, 88,175, 47,150,175, 89, 14,224,181,218,190, 31,234, 65,194,154, 6, 53,155,181,254,175,139,254, 90,117,129,241,232,230, - 79,146, 96,128,217,211,167,153,120,209,215,203,132,115, 63,122,111,102,168, 7,185,146,144, 79,227,235, 48, 87,130,102,238,216, -247,245,226,165,205,123,244, 27,104,199,151, 21, 10,245,218,178,166,171,255, 88,179, 32,180,121, 59, 69, 84,132,175,164, 96,199, - 84,162,211,148,192, 36,144,203,122,132, 71, 59,232,198,141, 54,175, 94,183,105, 58,128, 31,234,245,250, 71,255, 85,246,120,254, -233,223, 38, 9, 69,212,173,203,167,166, 88,114,174,129, 90,204,128,197, 84,249, 19, 22, 51, 40,255,240,103,251,169,127, 0,192, - 83, 25, 44, 1, 69,239,227,231,175,121,229,231,229,182, 93,190,244,171, 57, 97,238,228, 16, 44,216,120,183, 4,103,234,107, 44, - 25, 12,198,127, 47,222,222,222, 92, 78, 78,206,115,109,217,241,241,241,233,159,157,157,125,240, 25,211,245, 1,128, 55, 30,253, -186, 38, 39, 39,231,219,103, 77, 87,219,182,109,125, 41,165,158,143,158,253,121,215,174, 93,203, 98, 37,224, 63,105,176, 0, 57, - 40, 15,236, 28, 10, 0, 54,245, 61, 24, 5,228, 32, 66,192,172,197,144,126,189,224,234,238, 9,152,203, 1, 83, 57, 96,214, 1, -102, 45, 96,214,161, 40, 55, 29, 48,105,129,228, 67,224, 40,149,213, 59, 87, 6, 21,112,111, 7,122,182,242,135,155,163, 28,239, - 13, 9,115,253,237,240,189, 53,107,142, 38, 70, 3, 24,101, 85, 90, 41, 69,251,200, 38,248,126,141, 54, 97,255,141,130, 62, 0, - 48,160,165,235,225,246, 97, 1,126, 43,214,235, 19,254,186, 83,210, 23, 0,250, 69, 56, 30,106, 23,226,229,207, 63, 67,116,151, -167, 52,202,187, 97, 19, 98,185,245, 43,120,117, 22,212,106, 29,178, 82, 55,192,217,167,181,192,194,163,107, 93,223,183, 17,226, -227,119,231, 46, 17,151,171,243,141,188,169,208,226, 38, 44, 21,138,164, 60, 65,246, 25, 67, 25,175,180,204,152, 60,158,155,245, -217,151, 31, 3, 24, 91,107, 52,200, 29,211,191,251,110, 69,100,167, 54,161,238,121,187,222, 35,101,165,249,224,132, 10,217,144, -142,157,224, 20, 28,198,231,159,254,142, 72, 3,163,225,228, 18,136,236,139,155,145,118,121, 55,233,220,106,184,108,237, 22,201, -184,154, 12, 86,176, 27,233,220,167, 75,187,109,129,254,222, 94,148,242,224,121, 10,202, 91,240,250,203,189, 49,103,123, 50, 44, - 22, 11, 70,244,233,220,115,201,148, 30,148,231,121, 80,202, 35, 51,175,184,252,228,149,132,158, 73, 37,244,138, 53,145,169, 22, - 29,186,119,190,115,227,114,168,249,222,159,104, 51,246,235, 4, 2,156,175, 82,230, 58,223, 60,178, 54, 20,248,227,233, 12, 28, - 33,164,153, 59, 44,105,135, 23,195,191,203,100,225,175, 91, 14,187,169, 10,179, 39,236,218,240,203,203, 43,127,253,117, 19,128, -169,236, 49,194, 96,188, 24,228,228,228, 60,119,147,117,241,226,197,156,103, 49, 89,109,219,182,237, 2,224,155,156,156,156, 10, -179,245, 77,251,246,237,231, 85,173,171,170,160,162,148,142,189,118,237,218,217,218, 52,103,206,156,233, 13,160,209,245,235,215, - 43,142,209,168,109,219,182,141,170,219, 87,161, 80, 88, 90,180,104,145,182,108,217,178, 28, 86, 66,254, 94,131,149,144,177,227, -189, 86,134,220, 50, 0, 72,176,194,164, 60,214,180,167, 55, 91, 22,175, 91, 48,126,113,120,195, 6,208,104,141, 56,122, 61, 13, - 22,139, 25, 22,142,123, 20,201,226, 96,225,204,232,211,194, 21, 47,233,167,226,135, 3,137,224, 44,252,215,181,105, 62,137,137, -242, 99, 90, 70,191,178,157,231,169, 84, 38, 22,168,154,250,185,184,207, 26,209, 66,240,222,144,112,232, 76,220, 43, 97, 30,228, -100,124, 62, 93,109,149, 38,255,239,115,103,210,234,254,102,225,234,204,123, 45,209,167,246,163, 7,246,114,160, 6, 21,204, 69, -201,208,148,155,145, 92,108, 70,158, 94, 9, 25,201,181, 74,147,167,104,238,235,227,165,184,176,237,163, 84, 23,161, 90,228, 46, -228, 36, 82, 1, 7, 11, 79,133, 84, 25,111,104, 16,218, 75, 92,209, 47,171,182,116,218, 40,236,199,119,233, 61,192, 49, 99,243, -100, 98,211,180, 15,220, 91,249, 33,245,236, 58, 20, 92, 63,128,226,156, 52,226,160, 87,194,195, 37, 8,253,198,142,194,183,163, -218, 66,163,214, 64,152,155,228, 40, 21,203,156,106,210,164, 22,140,253,110,201,151, 94, 34,161,224,225,249,172,216, 44,102,232, - 12, 6,192,194, 65, 46,226, 65,104,197,255,204,176,152, 77,138,230,195, 63,122, 11,192,149,186,242, 30,159, 79,183,132,187,147, - 40,240,230, 80,106,214,129, 0,231,227, 10,104,165,233, 9,243, 32, 99, 90,247,153, 24, 69, 9,206, 61,205, 53,138,112,193,192, - 54,141,236,108,109,213, 9,200,218,249, 14,146, 32,167, 30,157,222,192,152,215,167, 43,126,251,237,183, 65,132,144,105, 85,251, -160,253, 29,195,139,153, 38,211,252, 95,213,116,116,116,108,220,176, 97,195,121,102,179,185,139, 68, 34,241, 48,153, 76,224,121, - 62, 79, 42,149,158, 75, 75, 75,251, 92,165, 82,165,252,183,229,253,208,161, 67, 86,155, 44,107, 52,197, 98, 49, 78,156, 56,241, -192, 90,147, 85,205, 2,244, 27,119,238,220,137,237,219,183, 3, 0, 78,157, 58,133,224,224, 96,219,234,190,155,153,153,105, 59, - 98,196,136,141, 0,252,106,211,188,127,255,126,227, 47,191,252, 18, 59,119,238, 4, 0,108,216,176, 1, 77,155, 54,173, 54, 61, -183,111,223, 22,126,250,233,167,141, 1,228,252,221,215,232,159,110,176,146,253,157,165,173,160,183, 0, 64,114,125, 15, 22,159, - 71,151,180,240, 18,247, 61,177,243,231, 46,114,137, 0,243, 87,207,202, 44, 44,209,116, 16, 17,240, 0,192, 81, 8,156,237,164, -151,190,158,208,194,191,180, 76,143,253, 87,179,207,198,229,211,122,133, 66,227,114,232, 49, 0, 78,255,170, 32, 73,211, 9,223, - 30,219,186,245,227,190,205,103, 12,105,142,125, 23,211,102, 0, 88, 93,103, 33,231,121, 80,158,171,236,212,254,208,201,240, 0, -207, 61,246,198,192,131, 62,252, 27, 95,191, 8, 86, 55, 66, 68,165,238,232,215, 64, 33,253,105,202,148, 55, 29,204,133,247, 81, - 98,148, 32,179, 84,143, 60,157, 24,101, 34,119,100, 39,196, 88, 4, 4,199,234,142,178, 64, 77, 57,189,147,179,212, 78, 16,209, -235, 45, 31,245,225, 79, 74,165,132, 19, 58, 12,251,194,169,232,196,178, 52, 78, 91,168, 37, 4,117, 78,112,233,232,232, 20,172, - 47, 78, 19,170, 74,139,224,228, 25,142,190,175, 12,196,194, 1, 97,208,168,181, 40, 44,185, 68,155,120, 57,144,244,115,155, 48, -183, 95, 51, 20,231,231,194, 96, 6,136,214, 80,162, 55,234,203,106, 60,143, 2,252,250,254,236, 15,199, 4,120,185,217, 86, 12, - 22,160,188, 5, 45,154, 5,162, 87,151,246, 56,118,254, 2,174,197,220, 3,255,104,176, 0,229,121,100, 21,148,230,235, 77,150, -117,245, 58,161, 22, 14,212,172,175,214,128,225, 41,154, 6, 35, 61,136,194, 2,124,214,161,137,253,164,143, 7, 6,216,219,202, - 8,244,102, 11,244, 70, 51, 52, 23,126,130, 75,195, 72, 40,228,114,210, 10, 58, 17, 0, 54,121, 40,131, 81,133,145, 35, 71,202, -243,243,243, 79, 15, 24, 48, 32,172, 87,175, 94,138,168,168, 40,104,181, 90, 28, 61,122, 20, 90,173, 54,192,207,207, 47,224,232, -209,163,195, 59,116,232, 16,239,235,235,219,109,199,142, 29,245,233, 35, 43,194,191, 58,169,243, 0,184, 71, 75,121, 9,241,176, -163, 57, 79, 41,181, 60,109,218,165, 82, 41, 46, 93,186,244,220, 35, 89, 87,175, 94,125,240, 52,145, 44,173, 86, 43,241,242,242, -130,139,139, 11, 44, 22, 11,180, 90, 45,246,238,221, 11,149, 74, 5,158,231, 97, 99, 99,131, 47,190, 91,141,132,155,167,113,229, -202, 21,168, 84, 42, 73, 93,154, 69, 69, 69, 36, 36, 36, 4, 6,131, 1, 28,199, 65,175,215,227,248,241,227,149,191,139, 68, 34, -124,184,104, 57,238, 93, 63,141, 91,183,110,161,168,168,136,176, 82,253,247, 27,172,103,198, 98,225,230,252,182,126,235,165, 57, - 83, 71, 97,250,232,104,191,207,127,222, 29, 29, 95, 72,215, 3, 64,152, 27,153, 48,174,123, 19,127, 39,133, 24, 11, 55, 95, 7, - 40,157,243,172,199,139, 45,166,247,194, 61,201,140, 61, 87,210, 79,127, 50,170, 21, 2,189, 28,130,131,130,136, 52, 41,201,138, - 53,255,120, 14,206,118,178,144, 1, 45, 93, 15,131,231,225,100, 47, 11,133,133,131,147,157, 44,164, 95,132,227, 33, 0,112, 82, - 72, 66,171,139,116,213, 24,238,245,151, 76, 86,200, 68,147,109, 91,123,249,191, 54,168,151, 77,255, 65,195,109,236,196, 28,138, -175, 28,133, 90,236, 11,115,131, 0, 24,204, 37,200, 74, 73,178,156,184,124, 55,187, 72, 99,152, 85,103, 50, 41,206,102,167, 36, -186, 53,110,222,203,185,232,192,220,130,198, 19, 55, 55, 18,128, 23,104, 54, 13,203,183,117,111,103,115, 53, 57,165,140,167,255, - 30,193,121, 18,181, 74,149,102,182,192, 75,103, 17,217, 39,157, 90,139,143,251, 69,162,180,164, 0,122, 19, 7,149,142, 51,121, - 58,201,101,134,148, 88, 24, 76, 28,140,102, 30, 98, 39, 31, 28,189, 20, 83,196,155,205,135,106,210, 76, 42,162,183, 0,216, 85, -253, 91,144, 27,105,241,145,131,205, 45,152,117, 72,207,202,193,250,191, 46,181,122,180,223,211,191,157,242,220,195,102,230, 42, -145, 43, 66, 17,245, 52,157,219,155,121,144,118, 54,114,201,143,223,204,120, 53,172, 99,211, 6, 50, 62,235, 18, 8,111,130,173, - 69, 4,157,212, 2, 71,191, 64,240, 70, 13, 45,215,235,149,113,255,143, 75, 4, 49, 24,255, 11,132,134,134,122, 58, 58, 58,198, -205,158, 61,187,193,176, 97,195,176,103,207, 30,168,213,106,172, 91,183, 14, 43, 86,172,192,130, 5, 11, 96, 54,155,241,219,111, -191, 41,118,237,218,213,238,151, 95,126,201, 10, 8, 8, 8, 79, 79, 79,175,107, 65,117, 2, 64, 6, 64,252,168,238, 34, 0,248, -131, 7, 15,162,127,255,254, 56,120,240, 32,255,232,111, 22, 66,136,153, 82,106,120, 90,131, 37,149, 74,145,144,144,240, 92, 76, -150, 88, 44,134,157,157, 29,164, 82, 41, 18, 19, 19,235,109,178, 56,142, 19,102,101,101, 65,165, 82,161,215,160, 65, 88,254,245, -215,232,222,189, 59,122,245,234, 5, 74, 41,142, 31, 63,142,232, 78, 17, 24, 53,184, 27,238,222,189, 11,179,217,108, 85,122,243, -242,242,144,159,159,143,190,131, 6, 97,245, 47,191,160,125,251,246, 8, 9, 9, 1,199,113, 56,125,250, 52, 94,238,211, 9,242, -161,209,184,119,239, 30, 43,212,255, 43, 6, 43,182,128, 94, 14,115, 35, 7, 70,247,105, 55,112, 80,231, 48,172,222,118,226,203, -176, 48,178, 21, 0, 92,236,101, 95,140,239, 30,136,248,140, 82,156,184,149,115, 32,190,144, 62,151,209, 23,188, 5,174, 46, 14, - 10, 64, 40,133,206,196,115, 14,201,168,179, 99, 50, 79, 41, 20, 93, 62,194,184, 65,241,126,237,195,252,252, 42, 70, 17,218,245, - 95,134, 9, 49, 15,252,219,134,120,250,195, 98, 6, 44,102, 56,140,218, 12, 44,178,173, 51, 29,157, 27,203,142,125, 52,107,198, - 75,253,134,190, 98, 35, 85, 56,194,162,206,132, 57, 47, 6,197,247,207, 66,171, 8, 70, 94,122, 50,182, 31,185,162,186,159, 85, -172, 22, 8,112, 52, 95,101,248, 32,169,132,150,213,165,171, 55,227,235,121,115,103, 13,216,190,117,155,189, 44,176, 51, 73,250, -169,191, 74, 42,226,100,110,141, 90, 11,202,229,174,244,171,117,219, 28,180, 70, 44,174, 75,167, 92,171,222,125,252,232,225, 81, - 77, 26,119,182, 79,189,246, 23,116,122, 3, 12,102, 32,188, 93, 55, 88, 44, 84, 74, 4,132,119, 16, 10, 73, 65,113, 41,136,217, -146,127,238,118,106,238,249,219,201, 66,131,125,221,218,143, 21, 58, 34,124,119, 80,183,150,128, 89,135,193, 93, 34,177,124,211, -137,119, 0, 76,124,182,139,252, 48,130, 69,129,206,225,238,100, 21,128,206,215,247,174, 8,109, 51,244,125,212, 39,130, 21,225, - 70,250, 69, 4,121,175, 93,254,197, 71, 13, 92,124,131,133,132, 55,131,122, 54, 7,212, 89,148,100, 93,130,163, 79,123, 88,188, - 59,225,183, 31,150,150,241, 60,221,250, 52, 83, 84, 48, 24, 47, 50,122,189,126,247,146, 37, 75, 26, 12, 28, 56, 16, 0, 80, 86, - 86,134, 75,151, 46, 97,205,154, 53,176,181,125,252, 57,217,191,127,127, 80, 74, 27,204,159, 63,127, 55,128,142, 53,105,118,234, -212,105,208, 15, 63,252,144,211,178,101,203,228, 71, 38, 75, 2, 64, 16, 27, 27, 43,200,204,204, 36,206,206,206,212,219,219,219, -156,147,147,195, 3,176,188,254,250,235, 66, 59, 59,187, 38,101,101,101,103,158,214, 96, 73,165,210,231,210, 39, 75, 44, 22,131, - 16, 2,169, 84, 10,137, 68,130,236,236,236,122,153, 44,142,227, 68, 7, 15, 30,196,245,235,215,177,160,101, 75,204,240,241, 65, -131, 6, 13,112,250,244,105, 80, 74, 97,107,107,139,146,146, 18,108,221,186, 21, 61,122,244, 0,199,113, 18,107,116,119,238,220, -137, 27, 55,110, 96, 81,155, 54,152,225,232, 8, 59, 59, 59, 28, 63,254,176,213, 79, 38,147, 33, 61, 61, 29,199,143, 31, 71,183, -110,221, 88,161,254,187, 13, 86, 55, 66, 68,196, 3,158, 38,163, 14,148,163, 0,129,119, 88, 24,145,196,199, 83, 83,125, 15, 42, - 16, 96,238, 15,235, 15, 12, 88,246,254, 32, 50,121, 72, 43,239,207,215,158,154, 6, 0,147, 70, 52,245, 81,200, 68,248,126, 95, - 60, 21, 8, 48,247,121,100, 48, 44,140, 72, 4, 2, 76,235,213, 62, 4, 57, 74, 35,146,114,148, 39,227, 41,181,170, 73,231,196, -178,113,216,176,255,116,230,138, 13,250, 4, 74, 41,156,236,100, 33, 19,238, 36,249,175, 61,120, 35,227,187,237,250, 4,202, 83, - 56, 41,196,161, 19,239,118,170,115, 20, 97, 91,127,201,228, 57, 31,125,208,105,200,196,217,114, 46, 97, 7,140, 73, 71,192,155, -116, 80,155, 36, 80, 10, 61,145,149,145,129,175,126, 59,144,169,214, 26, 71,197, 22,212,207, 88,222, 43,162,101, 97,110,100,216, - 87, 11, 63, 57,246,245, 23,243,237,116,201,167,203,132,132,211, 9, 27,118, 21,125,177, 96, 25,209, 24,140,175, 36,149, 80, 77, - 93, 58, 6,123, 44, 94,242,221, 15, 3,222, 28, 59, 60,161,105,112, 87, 23, 75, 78,138,139, 94,173, 46,216,124,248,134,231,163, - 55, 67, 2, 0, 73, 89,197, 40, 84,105, 57, 11,103, 62, 99, 47,198,231,113,214, 68, 3, 31, 17,232, 65,220,134, 69, 53,127,213, -205, 94, 2, 93,153, 18,238,246, 98,244,105, 31,244,106,160, 7,249, 40, 57,159, 22, 62,189,193, 50,131,154,117,184,188,184, 71, - 40,181,152, 67, 97, 49,195,116,103, 99,253, 35, 97, 4, 51,166,119,177,115,112, 54,166, 10,160,181, 5,108, 92, 65, 28, 2, 0, -199, 70, 68,220,236, 21,228, 36,199,113,239,188, 58,182, 56, 37, 45,235,119, 87, 27,124,203, 30, 33, 12,198,227,164,167,167,143, -159, 51,103,206,249,246,237,219,123,184,186,186, 34, 50, 50, 18,251,247,239,199,236,217,179, 43,247,105,217,178, 37, 40,165, 40, - 41, 41,193,146, 37, 75,242,114,114,114,198,215,166, 25, 23, 23,151,176, 97,195,134, 46, 97, 97, 97, 38,137, 68,162, 4, 32, 83, - 42,149,242,146,146, 18,162,215,235,193,243, 60,239,232,232,104,201,201,201, 49,143, 26, 53,202,112,241,226,197, 32,173, 86,155, -254, 44, 17,172,182,109,219,198, 42,149, 74,149, 64, 32,120,230, 41, 28, 42,204, 85, 68, 68,132,155, 86,171,229, 1,148, 62,205, - 20, 14, 28,199,161, 77,155, 54, 56,114,246, 38, 14,158,184, 8,117, 78, 34,166,189, 57, 30,145,145,145, 56,114,228,200, 83, 95, -179, 22, 45, 90,224,240,241,243, 56,127,253, 54,210,239,221,193, 59,211,222, 68,120,120, 56, 14, 31, 62,204, 10,244,223,109,176, -154,185,145, 22,222, 77,164, 27,231,247, 11,106, 38,238, 53, 31, 68,108,131, 29,193,135, 59,205,253,234,167,132, 72, 15, 50, 54, - 38,191,238,209, 94,143, 69,177,242,105, 92,184, 59,217,114,251,110,232,171,131,219,251, 97,245,126,197,103, 0,240, 74, 84, 99, - 92,189, 95,136, 43,247, 10,182,196, 21,208,184,103,205, 92,164, 7, 81,128, 98,203,146,119,135,116, 11,240,245,196,154, 61,231, - 65, 8,118, 91, 85,209, 82, 74,219,135, 5, 96,197,134, 39, 71, 12,122,250,127,183, 93,159,112, 36, 86,221, 15, 0,122, 55,179, - 61,212, 54,200,217,191,174, 72,134,141, 84, 52,165,223,240,113,114,238,222,126, 32,237, 56, 8,103,128,206,196, 35,183, 72,131, -114, 71, 63,156,190,116, 91,167,210, 27,223,143, 43,120,186,168, 93,124, 33, 77,110,233, 69, 50,202,180, 58, 47,133, 91,144, 94, - 40,224,249, 50, 3,197,213,248, 52,117, 92, 46, 77,180, 70, 35, 41,137, 26, 59,250,146,168, 85,235,183,207, 19, 75,164,175, 8, - 9,136,187,147,173,219,170,101,139, 96,111,111, 7,222, 88,246,127,236,157,117,120, 84, 71,219,198,239, 57,235,217,221,184,111, - 18,136,224, 1, 2, 73,112, 40,161, 4, 45,148, 66,161, 20,104,145,182,120,129, 66,145, 82, 40, 82,156, 22, 43, 69,107, 80,220, -139,123,112, 77, 32, 33, 9,132, 32,113,119, 91, 61,123,230,251, 35,242, 6,136,108, 2,253,222,190,244,252,174,107,175,100,237, -222, 57,115,100,238,243,204,204, 51, 64, 97, 58,250, 79, 88,146, 30,150,168,247, 4,128,134,118, 68,249,142,151,120,155,144, 33, - 9, 23,162,117,115,170,251, 13, 98,192,216, 97, 61, 90,138, 56, 93, 33, 38, 45,223,131,205, 51,251,225,147,174, 77, 68,199,175, - 69,141, 5,176,176,182,251,154, 26, 89, 80,131, 26,237,102, 95,126, 72,128,171, 20,232,120,119,239,162,198, 64,136,201, 26,126, -132,136,132,206,164,137, 79, 29,133,152, 75,184, 6, 46,225, 26, 21,184,117, 0,169,243, 14, 33, 78,254,244,167, 21,243, 11,183, -110,253,229, 12,199, 96, 65,117, 41, 47,120,120,254,173, 80, 74,159, 90, 89, 89,245,236,221,187,247,249,211,167, 79,219, 52,107, -214, 12, 0, 80, 58, 99,205,223,223, 31, 13, 27, 54, 68,106,106, 42, 62,254,248,227,140,228,228,228,158,148,210, 42,199,244,230, -231,231, 63,219,191,127,191, 99, 97, 97, 97,203, 57,115,230,164,213,173, 91, 55, 79,163,209,144,156,156, 28,142,101, 89, 88, 91, - 91, 75, 90,182,108,137,246,237,219, 23,220,184,113,195, 61, 62, 62, 62, 31, 64, 76,109,202,255,249,231,159,227,224,193,226,102, -226, 77,228,197, 18,139,197, 8, 12, 12,116,185,126,253,122, 34, 0,212, 38, 47, 86,249,230,229,254,253,251,184, 20,146, 0,161, - 78, 13, 73,122, 18,110, 30,218,143,190, 99,198,131,101,107, 63, 90,225,254,253,251, 56,124,238, 38, 20, 82, 33, 30, 61, 10,199, -254,253,251, 49,110,220,184,215,210,228,169,198, 96,213,171, 71, 36,210, 2,204,235,225,239, 50,227,163,142,245, 4,134,188, 36, -112, 70, 14, 2, 17,224, 96,103,129, 63,255,220,229,185,107,207,158, 27, 45, 92, 68,235, 56,150,253, 54, 44,149, 22,213,224,183, -231,173,218,115,245,163, 63,167, 5, 8,199,245,106,108, 3, 0, 98, 33,131,181,127,133,179, 0,230,189,206, 70,181,115, 37,178, - 2, 3, 70, 59,217, 90,206,253,230,243,247,108, 2,252, 27,226,210,173, 7, 88,183,255,198,101, 73, 26,182,155,124, 80,115,134, -151,167,192, 86, 56,139, 16, 92,245,227, 41,141, 70,234, 36, 86, 88, 67, 31,115, 17,208,107,160,209,234, 17,159,105, 68,124,150, - 6, 66,185, 24,119,163, 18,212,182, 41, 56, 86,219,109, 38,132,144,142, 94, 50,213,119,139,127,116,213,168, 11,216,188,236, 12, - 86, 44,185, 41,146,155, 73,147,107,162,115, 35,129,106, 58,123,138,253, 0, 78, 32,145,209,162,217, 83, 71, 40, 18, 35, 78,163, - 62,147, 4, 66, 41,204,154,188, 7,115, 51,129,184,147,135, 56, 14, 0, 60,156, 44, 37,203, 23,124,109, 57,101,230,130,106,199, -120,121, 19, 34,110,222,202,105, 74,179,186,214,184, 28,252, 16,151,195, 98,195, 47,223,125,212,180, 75,115, 21, 26,186, 90, 77, -246, 38,100, 89, 4,173,121, 68,180,120,199,176,128, 65, 83, 54,139,208,219,145, 12,105,245,209,156, 10,103, 15, 86,134, 7,192, - 69, 25, 41,136, 64, 0, 16,166,120, 70, 99,252, 53, 8,173,188,232,174,189,135,139,126,249,101,251,247, 17,233,148,143, 90,241, -240, 84, 67, 78, 78, 78,168, 92, 46,239,225,227,227,243,199,164, 73,147,204,135, 13, 27,166,250,226,139, 47, 24, 0, 72, 77, 77, -229,214,172, 89,147,244,211, 79, 63,229,102,100,100,140,212,235,245, 97,166,220,240, 18, 66,174,255,250,235,175,233, 87,174, 92, -105,218,186,117,107,169,159,159, 31,103,109,109, 45,148, 74,165, 70,157, 78,167,137,138,138, 50, 62,125,250,212, 57, 39, 39, 39, - 26,192,147,218,116,223,171, 84, 42, 48, 12,179,208,213,213,245,187,164,164,164,102,111, 98, 12, 86,253,250,245, 85, 0,162, 93, - 92, 92,234,215,180,123,240,149, 6, 91, 40, 68,118,118, 54,138, 82,194, 33, 75,120, 12, 31, 5, 3,111,107, 37, 44, 44, 44, 94, -203, 12,229,230,230, 2,133,137,184,122,245, 62,192,178,176,180,180,132,165,165, 37,111,176,254, 46,131,213,212,129,140,179,150, - 96,205,152,247,234,137, 61,234,184, 66,155,112, 23,247,227, 11,240,109,219,214, 17, 2,169,185,102,204,167,253,252, 7, 12,116, - 71, 64,251, 86,196,195,217,114,242,178, 85, 27, 39, 52,117, 36, 95,135,167,210,181,166,252,112,120, 26,125,214,196,129,252,114, - 49, 52, 97,172,171, 92, 13,142,163,184, 24,150,140,176,152,236, 95, 34,211,232,179,154,108, 68, 83, 21, 9, 20,130,217, 67, 41, -149, 89, 42, 20,249, 45, 91, 52,182, 11,108,215,130,233,217,217, 31, 98, 1,112,245,246,125,124,181,234,224, 77,142,163,239, 5, -155,216, 61, 88, 60, 99,240, 69,227, 84, 60, 99,208,240,194,140, 65, 74, 41, 45,158, 69, 88,245,176, 46,129,128,164, 20,197,222, -113, 18,217, 54,128,250,201, 69,196,100,115,136, 77,203, 71,158,208, 9,218,196, 68,128,114,113, 65,148,214,250,104,182,179,179, -115,240,244,110, 88,111,253,182,253,208, 23,229,226, 89,208, 31, 40,200, 78,198,162, 77,127,213,115,117,117,237,156,144,144,112, -169, 6,102,173,225,249, 99,187, 28, 64, 1,129, 72,138,227, 27,246, 34,195,214, 12,118,114, 49, 56,117, 58,198, 76, 25,102,217, -171,219, 48, 75, 0,136,125,116, 15,117,229,106,147,116,245,182, 24,240, 81,151, 70, 86, 48,168,177,237,212, 61, 13, 3,244,220, -126, 38,252, 73,151,198, 86,178,143, 58,214,181, 94,152,148,243, 33,106,153, 12,180, 52,130, 85, 22,209,171,197,236,193,125,148, - 26,155,216,147, 39,123,174,167, 41, 6,118,243,147,139,133,132,208,130, 68, 80, 51, 59,108,220,182,175, 64, 98,192, 22,254,146, -193,195, 99, 26, 69, 69, 69,193,132,144,230,211,167, 79, 31, 50,123,246,236,119, 20, 10,133, 39, 0, 20, 22, 22, 62, 51, 24, 12, -151, 1,236,170,201,108,191, 18,195, 20, 77, 8,121,246,228,201, 19,199, 29, 59,118, 88, 1,144,149,188,173, 1,144, 3, 32,245, -117,102, 16,150,154, 41,149, 74,245,221,155,170,135, 82, 51,229,226,226, 82,191, 54,223, 23, 8, 4, 70, 66, 8, 8, 33,144, 74, -165,184,114,229, 10, 6,189,215, 13,145,199,115,208,204, 74,137,214, 35,199, 96,207,217,179, 16, 8, 4, 32,132, 64, 32, 16,212, -168, 29, 17, 10,133,184,122,245, 42, 62,249,120, 32,164, 66,192,210,210, 18,211,167, 79,199,145, 35, 71, 32, 20,242,171,233,253, - 61, 17, 44,130,133,103,255, 88, 34,134,209,128,163,127,252,128, 99, 15, 10,116,143,210,241,109,163,116,172,217,143,124, 46,125, -213,246,177,103,175, 62, 88, 57,106,112, 31,249,187, 93,186,225,221,128, 46,194,166,173, 58,207, 5,176,182, 92, 67, 29, 88, 85, -174, 12, 35,135,239,183,156,122, 56,102, 79, 80, 20,129, 62, 31,131,187,183,162, 70, 14,223, 87,211,248,191,162,105,105,166,220, -115,245,198, 13,107,232, 11, 16,115,239,130,204,221,179, 30, 96,212, 35, 58,250, 49,126,218,118,136, 11,186,253,232, 79, 29,139, - 73, 79,178,104,161,169,154,197,142,138,133,165, 66,210,168, 87, 51,203,147, 28, 40,172,228,226,198,148, 51,194, 74, 46,106,220, -189,137,226, 36,165,148,154,155,137, 26, 83,163,161, 90, 77,181,142,221,188,237,183, 95,126,252,236,179,207, 20, 25, 9, 41, 72, -202,123,128, 2,137, 11, 12,114, 55, 60,185,119, 89, 93,164,101,171,109,188,171,170,207,140,140,140,180,224, 91, 89,216,179,105, - 41, 12, 58, 45,210, 18,138, 61,106, 82, 70, 30, 44,236, 92,110,212, 68, 83,207,114,185, 3,134,141, 22,155,153,195,236,147, 1, -125, 36, 79, 50,181,240, 85,153, 23, 95,228, 10,210, 17,121,238, 42, 2, 10,139,253,218,211,120, 6,117, 91,168, 76, 42,167,185, - 76, 60,169,151,159, 11,158,197, 37,227, 74,120,226,182,167,153, 52,201,203,150,108,123,146,148, 51,182, 95,219, 58, 88,125, 36, -226,203,202, 76, 81,101,154,222,142,100, 8,128,142,197,131,220,213,160, 64, 71,111, 71, 50,196,148,153,131, 21,105, 10,197, 24, -250,227,201,216, 57,251,238,100,244,155, 49,180,147, 69,251,246,189, 37, 96,117,200, 87,107, 13, 17,217, 52,239,117,246,209,107, - 68, 39,121, 77, 94,243,127, 82,179,196,236,252, 89,242,120,147,154, 73,120, 41, 47,211,235,110,123,249,238,192,164,164, 36, 97, - 73,244,170,202, 65,238,213,105,150,239, 14, 76, 76, 76, 60, 81, 18,189,170, 50,138, 85,129,102, 82,155, 54,109,108,250,246,237, - 11,163,209,136,199,143, 31, 35, 54, 62, 30,129, 99,191,132,149,149, 21, 46,135,134,226,209,163, 71,248,238,187,239,192,113, 28, -110,222,188,153, 80,157,166, 72, 36,210,183,104,209, 66,252,193, 7, 31,128,101, 89, 60,125,250, 20,137,137,137,248,234,171,175, - 96,105,105,137,224,224,224, 50, 77,173, 86,139,103,207,158,233,255, 63,142,165,127,143,193, 2,140, 48, 26,144,123,118, 30,214, - 94,129, 94,111, 64,227,240, 52,250,188,220,251, 27,125,108,201,209,208, 7, 15,159, 5, 95,123, 87,130,180,176,226,239,212,128, -168, 12,154,220,202, 77,152, 15,125,190, 5,158,158,196,243,212,252,130,168, 12,154, 92,211,141,160,156,145, 64, 95, 4, 36,223, -197,245,203,151, 16,116,243, 62,238,132, 61, 52, 94, 15,142,218,195,112,248, 62, 34,131, 62,174,177, 38,165, 80,190,183, 26, 35, -194,162,235,180,106,232, 88, 7, 70, 22,148, 51,192,114,240, 46,140,140,104, 95,167,149,151, 85,157,226,200,149, 1,214,159, 95, - 0,126,148, 85,169,119, 39, 78,191,165,163,167,244,195,252,156,204,182, 93, 59,183, 83, 88, 54,233,133,140,232, 40, 60,190,127, - 85, 29,252,224,201,245, 59,113,250,215,138,142,184,184,184,188,211,181,115, 35, 12, 30,243, 13,244, 69,185,120, 26,244, 27, 10, -178, 82,112,229,134, 18, 15,243,242,218, 1, 48, 57,130,117, 61,214,208, 20, 0, 58,122,136,227,204,161,117,250,180, 79, 95, 72, -137, 6,156, 54, 15,164, 40, 3, 79, 18,117,185, 31,110,138, 55, 2,128, 92, 74,132, 10,154,107, 97,138,174,119, 93,219, 6,114, -129, 1,219,207,134,131,227,138,151, 89,226, 56,108,220,126,225,201,216,239, 63,241,133,119, 29,235, 22,132, 16, 82,147,208, 62, -161,232,116,103,207,130,198,154,243,115, 1, 78,143,171,147,109, 26,119, 90,155,213,169,182,145,176,176, 68,154, 8, 96,108, 19, - 21,217, 60,121,237,169,185,254,103, 35, 58, 78,251,188,159, 5, 40,191, 48, 58, 15, 15,207,127, 37, 18, 56,102,230,204,153,155, - 5, 2,129, 61, 0, 66, 41,133, 86,171, 21,110,218,180, 73,196,178, 44, 35, 16, 8,140, 50,153,140, 13, 14, 14, 54,112, 28,151, -174,215,235,199, 84,167,169,211,233,158,172, 95,191,190,158,193, 96, 40,155,113,168,213,106,241,219,111,191, 65,171,213, 66, 42, -149, 66,169, 84,226,233,211,167, 32,132,232,141, 70,227, 19,126, 79,188, 73,131, 69,177,160,195, 39,243,230, 1, 32,160,152,255, -146,185, 2, 0,132,102,210,164,166, 14,228,171,166,173, 58,207, 43,253, 78, 77, 11,160, 49, 26, 7,182,106,222,112, 55, 0,104, -169,241,147,218,108, 68,158, 86,253, 81,203, 86,237,246,112,148, 10, 89, 74,127, 97, 56, 28,208,176,136, 52,101,230, 92,165,119, - 30,105, 57,193,165, 11, 56,115,160,255,233, 22, 44, 73,199, 64, 41,165,101,221,130, 63,200,144,145,171,173, 54,143,211,213,103, -218,110,173,234,136, 71,159,185,118,111,140,209, 72,157, 4, 2,146,162,214,177,155, 95,215, 92,149,220,125, 93,242,118, 32,103, - 66, 91, 56,118,183,147,151, 68,181,138,128,140, 34,156, 73, 72,203,191, 84, 27,205,236, 66, 67,191,217,107,142,252, 37, 17, 9, -132,160,180, 56, 17, 40,165,208,232,141, 89,165, 38,204,199,150,168,166, 31,102,119, 11, 4, 36,182, 58,189, 91,143,146, 87, 15, - 94,118,238,235,240,152,236, 95,158,103,211, 7, 0,240, 60,155, 62,168,111, 75,230, 62, 73,201,255,250, 65,108,246, 15, 53, 29, - 55, 65, 9,174,180, 26, 60,239,149,215, 94,183, 62, 35,147,232,125, 0,253,155, 58,144,110,131,167,253, 52,141, 16,240,203, 68, -240,240,252,139, 40,141, 98, 49, 12,179,240, 77,105,150, 70,177, 0, 68,215,224, 59,183, 0, 52,127,147,219, 22, 28, 28,156, 9, - 32,147,223,203,255, 37,131, 21,158, 70, 55,194,132,197,156, 77,253, 92,165,223, 79,162,231, 0,216,190,206, 70,148,104,216,188, -201,138, 9, 77,165,115,255,142, 10, 47, 49, 83,127,203, 88,158,136, 52,218, 3, 0, 26, 52,104, 64,163,163,163, 65, 41,125,173, -236,187,145,233,244, 62, 94, 90,114,161, 34,147, 13,160,147, 41,122, 81, 25,244,123,224,213, 46,224,232, 76,186, 8,192,162, 90, -109,115, 45, 51,181,155,124,108,165,209,179, 64,245,217,244,121,120,120,222, 78,147,245,166, 53, 95,119,225,103,158,183,192, 96, -241,252,239,242,248,241, 99,126, 89, 3, 30, 30, 30,158,202, 49,254, 13,154,124,210, 97,158, 23, 96,248, 42,224,225,225,225,225, -225,225,225,121,179, 16, 0,129, 21, 90,241, 26,204, 14, 32,132, 4,214,216,234, 87,163,207,107,242,154,188, 38,175,201,107,242, -154,188,230,219,167, 89,157,246, 91, 51, 59,145,150, 27,188,252,166, 31, 0, 2,121, 77, 94,147,215,228, 53,121, 77, 94,147,215, -228, 53,255,109, 15,190,139,144,135,135,135,135,135,135,135,231, 13,195, 27, 44, 30, 30, 30, 30, 30, 30, 30, 30,222, 96,241,240, -240,240,240,240,240,240,240, 6,139,135,135,135,135,135,135,135,135, 55, 88, 60, 60, 60, 60, 60, 60, 60, 60, 60,181,135,212,112, -101, 18, 30, 30, 30, 30, 30, 30, 30, 30,158,106,224, 35, 88, 60, 60, 60, 60, 60, 60, 60, 60,188,193,226,225,225,225,225,225,225, -225,225, 13, 22, 15, 15, 15, 15, 15, 15, 15, 15,111,176,120,120,120,120,120,120,120,120,120,120,131,197,195,195,195,195,195,195, -195,195, 27, 44, 30, 30, 30, 30, 30, 30, 30, 30,222, 96,241,240,240,240,240,240,240,240,240,252,247, 13, 22, 33, 36,144,215,228, - 53,121, 77, 94,147,215,228, 53,121, 77, 94,147, 55, 88, 60, 60, 60, 60, 60, 60, 60, 60, 60,188,193,226,225,225,225,225,225,225, -225,225, 13, 22, 15, 15, 15, 15, 15, 15, 15, 15,111,176,120,120,120,120,120,120,120,120,120,120,131,197,195,195,195,195,195,195, -195,243, 95,130, 0,168,112, 38, 0,165,244,156,201, 34,181,152, 77, 80,157, 62,175,201,107,242,154,188, 38,175,201,107,242,154, -111,159,102,117,218, 53,241, 31,255,104, 40,165,127,219, 3, 64, 32,175,201,107,242,154,188, 38,175,201,107,242,154,188,230,191, -237,193,119, 17,242,152, 26,165,116, 36,132, 56,242, 53,193,195,195,195,195,195, 83, 61,194, 55, 41,214,152,144, 54, 43,223,169, - 51,175,247,165,216,158, 38, 52,216, 12,254, 51, 6,140, 43, 14,166, 21,219,226,215, 48, 1,111, 92,147, 7, 32,132, 44, 37, 4, - 51, 74,254, 95, 65, 41,253,230,109,220,206, 25, 51,102, 12,244,245,109, 5,107, 89, 42, 90,121, 61, 6,178,119, 1,214, 31, 97, -206,233, 46,104,229,219, 1,151, 67,226,113,249,102, 56,110,108,232,139,207,167,204,131, 70,163, 71, 70, 70, 18,238, 95, 61,181, -255, 45,218,215,109, 69, 34,209, 71,214,214,214,230,105,105,105,231, 1,252, 5,224,125, 7, 7,135,174,217,217,217,249, 6,131, - 97, 47,165,244,102,109,180,223,105, 73,102, 74,196,162, 81, 26,189, 97,249,213,123,244,183, 0, 63, 98,203,114, 88, 38, 19, 11, - 59,105,117,236,138, 43,247,233, 47, 53, 44, 43,121, 41, 26,207,159,235,175,201,187,239,190, 59, 66, 32, 16, 44, 6, 0,163,209, -248,237,133, 11, 23,254,120, 19,186, 42,149,106, 8,165, 84, 81,178,223, 10,147,146,146,118,153,250, 93, 63, 63,191, 88, 0,117, - 74,158,198, 5, 7, 7,215, 53,229, 61,158,154,113,247,238, 93, 90,183,110, 93, 52,111,222,252, 81, 74, 74,202, 79,148,210,141, -124,173,252, 67, 12, 86, 35, 66,234,143,237,221,254,108,247, 15,123, 40, 76, 49, 66, 46, 46, 46,203,236,237,237,199, 21, 21, 21, -105, 0, 80,129, 64, 64,155, 52,105, 2, 66, 8, 74,175,155, 70,163, 49,253,225,195,135,205, 76, 53, 87,111, 74,179, 97,195,134, -119, 25,134,113, 45,127,253,174,238,127,142,227, 18, 34, 34, 34,252,171, 43,167,179,179,115, 15,134, 97,102, 85,247, 57,142,227, -150, 37, 39, 39,159,174,234, 51,205,155, 55, 15, 81, 40, 20,142, 12,195,144,202, 62, 83,190,205, 97, 89,150, 22, 21, 21,165,134, -135,135,251,214,160, 17,115, 36, 4, 51, 56,142, 50, 0,192, 48,100,166,181,181,245,206,236,236,236,136,210,247, 75,126, 39,181, - 38,199,139,139,139,203,112, 0, 95, 3,160, 0,126, 76, 76, 76,220, 86,147,239, 55,104,208,224,174, 88, 44,118, 21, 8, 4,228, -229,125, 82,209,115,142,227,168, 78,167, 75,120,244,232, 81,165,251, 40, 40,232,210,190, 21, 43, 86,132,108,249,245, 23,223, 22, - 45, 7,130,145,119,129,158, 90, 32, 36, 70,139, 86, 45, 8, 40,199, 65,147,151, 6,142,227, 80,164,209,226,252,161,223, 66,234, -120,212,243, 69,241, 88,198,183,193, 92,245, 28, 62,124,248,146,229,203,151,219, 73, 36, 18,102,239,222,189,237,190,250,234,171, - 81,171, 87,175,118,249,232,163,143,204,117, 58, 29, 55,115,230,204,119, 8, 33, 11, 40,165, 71,106,162,221,190, 37,105,219,200, -195,249,187,137,195,222,197,215, 75,119, 79,236,216,156,100,152, 41,196, 27, 63,236, 84,207,170,169,167, 53, 22,108,190, 62, 9, -192, 47, 53, 40, 43,113,115,115,107,233,232,232,232,161, 86,171,141, 0,208,180,105, 83, 42, 16, 8, 94,248,156, 94,175,215, 63, -124,248,240, 4,127,169, 55, 13,129, 64,176,248,212,169, 83,206,148, 82,244,232,209, 99, 49,128, 55, 98,176, 40,165,138,228,228, -228,210,107,160,162,134, 95,175, 19, 28, 28, 92,106,168,234,212,224, 61,147,105,215,174,157,140,213,235,199, 11, 24,166, 59, 5, -154,163,248,164, 14, 51, 2,103,133, 66,225,207, 55,110,220,208,188,237,251,254,236,217,179, 24, 61,122, 52,194,194,194, 26,157, - 56,113, 98,131, 74,165,154,144,156,156,220,133, 82,154,206,159, 25,255, 69,131,213,148, 16,135, 62,126,141,174,140,255,100,160, -156,219,191,134, 96,196,156, 42,141,144,179,179,243,242, 78,157, 58,141,218,177, 99,135,226,240,225,195, 10,119,119,119,136,197, - 98, 8, 4, 2, 8, 4, 2, 48, 12, 3,161, 80,136,247,223,127,223,164,134,235,101,205,243,231,207, 43, 26, 54,108,248, 74, 35, -203, 48, 12,122,245,234, 85,173, 38,195, 48,174, 33, 33, 33, 14, 50,153,172,204,164,112, 28,247,194,163, 92, 63, 52, 88,150, 69, -167, 78,157, 76,170, 43,134, 97,102, 69, 70, 70,190, 83, 88, 88, 88,101,223,109,137,222,233,106,180, 84,215,174,156,119, 32,250, -103, 0,155, 5, 42,176, 1, 36,158, 0, 35,173,240,243, 89, 89, 89,232,210,165,139,224,117,246,245,123,239,245, 33,148,210, 67, - 42,149,234,124, 70, 70,134, 57, 33,248,184,150,145,173,111,162,162,162,204, 41,165,104,212,168,209, 44, 0, 53, 50, 88, 2,129, -192,245,204,153, 51, 14, 82,169,180,108, 63, 87,246,215,104, 52, 66,175,215,163,103,207,158,108, 53,166, 22, 63,111,254,205, 87, -163, 53, 64, 67,221, 17, 30, 89,136,147, 39, 15,193,163,208,128, 39, 15, 52,224, 56, 21, 52,249,105,160,148, 66,173,209,161, 69, -192,135,190, 28,247,246, 4, 77, 44, 45, 45, 7,174, 94,189,218,254,151, 95,126,201,123,244,232,145,126,211,166, 77,246, 99,198, -140,105,172,215,235, 49,118,236,216,244, 70,141, 26,137, 87,175, 94,109,127,232,208,161, 30, 0,106,100,176,132, 4,223,127,220, -175, 59, 52, 6, 6, 6, 3,107,239,108,111,254,231,228,225, 1, 34, 74,117,216,126, 36, 24, 6,150,251,173,166,230,170, 87,175, - 94,117, 55,110,220, 40,140,140,140, 20, 54,105,210, 4, 70,163,177,236,193,113, 28,140, 70,163,201,231, 37,207, 11,231, 22,226, -227,227, 97,105,105,105, 22, 16, 16,144, 76, 8,153,127,241,226,197, 45,127,199,111,189, 78,100,235, 77,225,231,231,215, 90,200, - 48, 7,230,206,158,232,228,211,178,165,192,193,209, 30, 81,143,227, 32, 22,112,129,209, 15,163, 2,150,252,176,113,178,159,159, -223,135,193,193,193,183,223,182,125, 93,119,192, 47, 27, 56, 86, 63,174,248,153, 21,128, 45,200,207,207,199,231,159,127,142, 35, - 71,142, 52,105,219,182,237, 50, 0,163,248,179,226,191,100,176,188, 9, 81,180,112,119, 10,250,254,235, 49,214,244,228,239, 76, - 81,102, 26,196, 85, 24, 33, 39, 39,167, 69,157, 58,117,250,100,199,142, 29,214,132, 16,156,157, 56, 10,214,122, 13, 84,223,173, -128,181,157, 61,116,179, 70,195,220,200,194,231, 98,168,169, 23,219, 87, 52, 31, 61,122,132,236,236,108,216,217,217, 65, 46,151, - 67, 38,147, 65, 44, 22, 67, 34,145,152,170, 9,153, 76,134,115,231,206, 65, 40, 20, 66, 32, 16, 64, 40, 20,150, 61,202, 63, 23, - 8, 4,112,116, 52,125,104, 18,199,113,203, 26, 55,110,236, 19, 21, 21,101,145,147,147,131,182,109,219,230, 17, 66, 66,203,221, -233,249,132,134,134, 90,152,220,216,232,159,161, 32,110, 19,104,246, 1,192,106, 0,140, 22,131,161,129,103, 89, 3, 83,254, 47, -199,113,181,185,243, 76, 37,132,172,232,219,183,207, 44,128, 32, 48, 48,176, 96,226,196,137,244,209,163, 71,221, 63,248,160,159, -199,227,199,209, 37,102,143,204, 32,132,172, 53, 53,146, 69, 41,149, 2,192,149, 43, 87, 64, 41,149,213,230,216,147, 74,165,184, -113,227, 70, 89,132,146, 97, 24, 48, 12, 3,129, 64,128,163,209,118, 40,212, 49, 40, 74,125,128, 47,251,212,129,167,167,231, 43, -134,251,149,125, 67, 41, 38,140, 25, 21,178,112,249, 26, 95,163,209,136,147, 39, 79, 98,213,170, 85,208,106,181, 8,232,218, 29, -207,105, 11, 52,243,180, 3,199,113, 80,107,116, 8,189,116, 32, 68, 85,199,211,247,109,185, 24,228,230,230,254,217,176, 97, 67, - 65,122,122,250, 5, 0,207, 12, 6,195,250, 63,255,252,211,225,179,207, 62, 75,219,177, 99,199, 68, 0,110, 43, 87,174,236, 81, - 80, 80,176,167, 38,186,157, 90,144,222,254, 45,155,181,173,227,230,134, 75,215,111, 67, 44, 17, 89,141, 31,209, 7, 74,165, 16, - 63,252,114,156,139, 77,200,154,120,229, 62,221,102,226,185, 73,156,157,157,125,186,119,239,238,182,113,227, 70, 49, 0, 60,120, -240, 0,105,105,105,176,181,181,133, 76, 38,131, 72, 36, 42,187, 97,227,169,145,209,104,216,165, 75, 23,153,209,104, 68, 97, 97, - 33, 54,110,220,104,105,102,102,102,217,171, 87,175,121, 0, 76, 54, 88,237,219,183, 79,213,233,116, 14, 0, 32,145, 72,210,174, - 95,191,238, 8,160,200,195,195,195,172,228, 35,234, 26, 70,182,226,202, 69,167,226,106,240, 94,181,248,251,251,183,106,210,208, -227,220,210,165,243,149, 57,121, 41,176,180, 76, 5,131, 28,108,217,242, 51,204,204, 44, 48,111,222,108,161,127,155, 54, 46,147, -191,154,125,206,207,207, 47,240,109, 51, 89, 28,171, 31,215,194,191,125,217,243,109,103,215, 65,107,233,139,196,249,243,177,102, -205, 26, 52,104,208,160, 53,127,102,252,151, 12, 86, 0, 33, 66, 87, 27,229,209, 13,243, 38,123, 48, 55,142,137,212,113,209, 72, -210, 24, 97,245,159,147,231, 92,249, 11, 35, 0,198,209,209,113,252,174, 93,187, 44, 74, 27,187, 70,196, 8, 43,232,225,209,180, - 41,228,150, 86, 72, 97,245,160, 6, 61,196, 34, 81,133, 13,162, 41,154,165, 17, 48,177, 88, 12,177, 88, 92,118,193, 21,139,197, -213,106,190, 80, 57, 66, 33, 24,134,193,217,179,103,193,178, 44, 6, 14, 28,248,138,185, 18, 10,133, 47,116, 65, 86,167,153,156, -156,124,218,197,197, 37,148, 82,250,142,209,104, 4, 33, 36, 52, 49, 49,177,115,233,251,206,206,206, 61, 90,180,104, 49,139,227, -184,101, 38,149,147,205, 4,205,218, 5,243,118, 25,200,187, 97, 7,162, 8, 4, 71,220, 17,246, 56, 25, 23,238,196, 32, 61,187, - 16,126, 13,237,209,163,125, 61, 24,141, 70,147,183,189, 60, 46, 46, 46, 87,210,211, 51, 6,189,251,238,187,200,202,202, 98,231, -207,159,143, 22, 45, 90,160, 97,195,134,149,153,167,106, 53, 9, 33, 73,161,161,161,238,106,181, 26,132,144, 36, 19, 12,217,185, -138,140,240,159,127,254, 9,141,230,213,232,189,117,231, 37,248,122, 64, 93,140,252,114, 27, 86, 60,218,139, 13, 27, 54,224,229, - 33, 58, 47,107,114, 28,135,133,203,214,248,170,181,186,178,186,210,106,181,184,113,227, 6,180, 69,249,184,184,227,139,178,232, -165, 90,163,131,171, 79, 55,223,234, 52,223, 4,255, 95,154,148,210, 32, 0, 65,229,234,119,206,142, 29, 59, 6, 1, 56, 72, 41, -189, 14,224, 58,128,221, 53, 46, 39,193,200,143, 6,124, 0,161,216, 28, 15,163, 19,208,185,157, 47, 28, 29, 28, 16, 26,249, 4, -177,137, 89,169,132, 96, 68,207, 14,210,101,106,181,110,206,229,123,244,215,234, 52,157,157,157, 61,183,108,217, 34, 42, 31,113, - 17, 8, 4, 47,156,235,165,175, 85,100,178,254,151,247,209,223,165,233,231,231,215, 48, 32, 32,224,250,162, 69,139,172,226,227, -227,113,237,218, 53,184,187,187,163,168,168, 8,213, 13,109,123, 89, 83,167,211, 57,148,235,182,115, 0,128,148,148,148,221,248, - 79, 87, 58,173, 73, 57,171, 26, 87, 85,147, 49, 87, 47,151,179, 94,189,122, 18, 59,107,235,125,203,150, 47, 84, 70, 68, 94, 70, -203, 22,109,161,180,244, 6,103, 76, 65,102, 86, 1,178,163,147,176,104,209, 10,204,155,255, 45, 86, 44, 95,164, 28, 60,100,228, -129,118,237,218,213, 47,223, 93,248,191,190,223, 25,161,120,227,253,187,215,199, 1, 64, 94,228, 65, 76, 30,210, 30,249,249,209, - 24, 59,118, 46, 18, 19, 19,241,248,241,227,224,255,207,114,242, 6,171,156,185,241,151,138,118,238,158, 55,177,181, 52, 38, 76, -162,125,112, 3, 73, 90,142,254, 17,207, 38,254, 80,197,247,138,138,138,116, 71,142, 28,193,153, 9,163, 80,159,176,176,249,110, - 37, 28, 93, 92,144, 51,242,125,228, 27,244,168,119,242, 54,164, 74, 37, 36, 10,101,181, 17,135,242,154, 23, 47, 94, 68,120,120, - 56,132, 66, 33,148, 74, 37,148, 74, 37,164, 82, 41, 36, 18, 73,153,185,170,204, 96, 85,114,240, 64, 32, 16,224,193,131, 7,136, -141,141,133,149,149, 21,174, 93,187,134,174, 93,187,190, 18,197,170,229, 1, 95, 97, 68,169,100,220,213,105, 83, 53, 32,178, 3, -108, 62, 65,254, 77, 21, 96, 61, 12, 6, 88,193,104, 52,226, 94,116, 38, 70,127,242, 30, 0, 96,252,156, 77, 8,108,227, 81,102, - 14, 76, 69,165, 82,153, 1,152,209,160, 65,131,193, 67,135, 14,101,197, 98, 49, 10, 11, 11,161, 86,171,241,224,193, 3,246,189, -247,250, 20,244,237,219, 71,121,252,248,113,142, 82,172,168,225, 56,172, 84,149, 74,229, 94,210, 13,155, 90,139,227, 15,132, 16, -236,221,187,183,194,247, 71,172,138,128,176,120,120, 22, 54,110,220, 8,163,209, 8, 74, 41,169,174, 62,191,155, 53, 37,100,242, -204,133,190, 28,199,161,107,215,174,152, 54,109, 26,158, 62,125,138, 65,131, 6,149, 69, 3, 41,165, 80,107,181, 72, 12, 59, 23, -226,236,230,225,251,182, 94, 28, 40,165, 39, 0,188,254,248, 37, 10, 23, 7, 39, 55, 48,212,128,164,180, 76,124,240, 94,119, 8, -196, 74, 60,143,207, 64, 11,111, 47,231,161,239,119,112, 22, 16, 22, 51,150,237, 26, 15,224, 87, 19,206,119, 99,100,100,164,232, -254,253,251, 16, 8, 4,176,176,176,128, 92, 46, 47, 59,199,203, 27, 46,158,202,233,214,173,219, 24, 0,243, 40,165, 57, 1, 1, - 1,142,139, 23, 47,182, 78, 76, 76, 68, 68, 68, 4,246,238,221,155,206,178, 44, 11,128, 80, 74, 23,188,129, 99,137, 43, 31,217, -106,223,190,125,218,245,235,215, 29, 9, 33,133,165,145, 43, 66, 72, 97, 45,162,110,162,188,156,228, 47,173, 21,180,159,144, 49, -247, 96,243, 10,158,103,179,204, 17, 11,123,199,159,130,131,131, 13, 85,125,215,210,210,242,243,197, 11,167,170,236,236, 56, 4, -116,126, 23,201,169,122, 44,153, 58, 28,153,153,249,248,117,235, 82, 0, 18,232, 89, 1,222, 9,248, 16, 14, 14, 46,232,212,177, -147,211,165,171, 87, 38, 0,248,225,109, 57, 6, 98, 15,126, 62,158, 16,242,125,157, 58,117, 46,109, 90,186,180,126,215,174, 93, - 1, 0,231,207,159,199,111, 67,134, 96, 62,240,233, 58, 66,146, 39,189,165, 19,155,254,177, 6,203, 67,170,188,180,229,171, 65, -109,109,141, 69, 34,221,213,163, 72,212,114,236, 15,209,250,162, 59, 57,116,200, 15, 21,159, 96,148, 16,194, 17, 66, 56, 79, 79, - 79, 88, 24, 52,176,162, 58, 56,170, 84, 48,183,177, 69,150,161, 56,114, 37, 81, 40, 32, 81, 40, 77,186, 56,150,215,244,246,246, - 70,106,106, 42, 36, 18, 9,148, 74, 37,204,205,205, 95, 49, 87,166, 94,112, 9, 33,224, 56, 14, 66,161, 16,161,161,161,232,216, -177, 35,220,220,220,176,119,239, 94,244,232,209,227,149, 46, 67, 83, 77,219,203,141,121,249,136, 82,233,224,119, 83, 6,183,191, -128,164, 30, 88,243,143,192,200,187,194, 0, 75,104, 56,167,226,238, 64, 74,113,226,118, 42, 30,197,102,130, 51,114, 53,238, 34, -116,118,118,246,147,201,100, 43,102,205,154,169,106,209,162, 5,210,211, 51,192,113, 28,148, 74, 37,212,106, 53,204,205,205,209, -161, 67,135,148,249,243,231, 63,163, 20,189, 40,165, 41,255,141, 3,248,204,153, 51, 47,116, 15,150, 62, 10,147, 19, 48,114,210, - 14, 72,132, 64,104,104, 40, 26, 55,110, 92,125,184,156,163,152, 52,115,129,175, 70,171,131, 68, 34, 65,251,246,237,209,182,109, -219,178,113,113,165, 6, 85,175,215,195,104,228,224,228,253,174, 47,121, 11, 47, 10,132,144, 86, 0, 62,179,180,180,116, 47, 42, - 42, 74, 49, 24, 12,123, 75, 76,127, 15,145, 72,244,145, 92, 46,119,202,205,205,141, 1,240, 43,165,244, 78,117,122,102, 50,153, -173, 84,102, 1,142,213, 66, 40, 20,194,205,205, 3,212,168, 67,118,158, 26, 35, 6,247, 69, 72,104, 36, 78, 93,188,201, 26, 12, -220, 58, 83,203,216,176, 97, 67,100,102,102, 66, 32, 16, 64, 46,151, 67,161, 80,160, 81,163, 70,136,143,143, 47, 51, 87,124, 23, - 97,181, 44, 56,121,242,164,131, 80, 40,116, 50, 26,141,136,139,139, 67,120,120, 56,214,174, 93,155,154,159,159, 31, 16, 28, 28, - 28, 85, 27, 81,137, 68,146, 86, 26,185,146, 72, 36,105, 85, 69,182, 94,103,204,149,171,171,171,151,139,131,244,236, 31,107, 39, -214,241,105,217,154, 49, 19, 40,179, 11,159,166,118,188,125,243,102,251, 57,191,238,159,224,234,234,218, 61, 33, 33,225,105,165, -141, 31,195,244,106,225,219, 82, 8,154, 2,161,164, 35, 86, 44, 31,140,244,140, 60,100,103,229, 67, 44, 86, 64,103, 16,192,200, - 17,180,239,216, 9,191,111,219,131,166, 77,155, 9, 4, 64,183,183,201, 96,149, 68,128,151, 29, 62,124,184,190, 76, 38,195,226, -197,139, 97,110,110,142,155,223,127,143,223,196, 98,152, 1,216,168,215,207, 2,192, 27,172,255, 47,131,165,112,108, 52,100,247, - 39,221, 58,120,123,186, 48,134,189,107,145, 80,196,106,230, 61,210,107, 30,230,211,247, 35, 40,189, 86,149,175, 32,132, 80,177, - 88, 12,199,153,223,163,110,179,230, 40, 28, 61, 0, 89, 6, 61,188,142,223,132, 84,169,196,195,110,190,160, 58, 29,222,121,152, -102,170,113,161,132, 16, 10, 0,246,246,246, 16,139,197,144,201,100,144, 74,165,144, 74,165,101,198, 74, 34,145, 64, 34,145,152, -108,134, 56,142, 67,126,126, 62,158, 63,127,142,209,163, 71, 67, 46,151,163, 36,212,141,186,117,235, 66, 40, 20, 34, 49, 49, 17, - 23, 46, 92,128,167,167, 39, 36, 18, 73,141,218,218,114, 13,182,143,139,139,203, 37, 66,136,207,221,187,119, 45,252,253,253, 97, -106, 4,171,184, 53, 20, 67,139,186,224,136,219, 11, 99,173, 12, 6,246,133,109, 41,141,190,152, 24,185,234, 86,191,126,253,181, -203,151, 47,103, 92, 93, 93,193,113, 28,172,173,173, 81, 84, 84,132,140,140, 76,120,123,123,195,205,205, 13,203,151, 47, 7,128, -221,255, 45,115, 5, 20,119, 7,151, 26,172,242, 70,107,210,251,117,144,149,165,132, 64,192,148, 25,230,106,247, 57,165, 88,183, -124, 94,200,208,209,211,124,167,204, 89, 1,141, 86, 15,181, 86, 7,141, 86, 7,141, 86, 95,242, 87,135,210,129,237, 41, 17, 23, -222,186, 8, 22, 33,164, 79, 96, 96,224,250, 85,171, 86, 57, 57, 57, 57,137,210,211,211,217,159,127,254,185,199,207, 63,255, 28, - 49, 97,194, 4,239, 9, 19, 38, 88,219,219,219, 11, 83, 82, 82, 12, 83,167, 78,237, 65, 8,153, 69, 41,221, 93,229,245, 66, 97, -110, 35, 16, 43, 64,136, 16, 86,150,214, 16, 74, 20,224, 88, 33,140, 28, 96, 97,105,143,235, 33,251,113, 45, 44,127, 76, 90, 38, -246,153,114, 83,213,172, 89, 51, 42, 16, 8, 96,107,107,251, 66,215, 32, 0, 56, 58, 58, 34, 47, 47, 15, 2,129,160,236, 53,158, -202,175, 65,148, 82, 60,123,246, 12, 69, 69, 69,184,126,253, 58, 14, 28, 56,144,254,178,185, 10, 12, 12,252, 66,169, 84,206, 87, -171,213, 43, 78,159, 62,189,182, 58,221,146, 49, 87,111,140,138, 82, 49,248,249,249,137,156,108, 5,167,207, 28, 92, 93,215,156, -187, 71, 16,243, 57,240, 56, 47, 92,121,203,225,157,174,173,222, 99,154,127, 63,217,189,215,236, 31, 79,251,249,249, 53,170, 44, -146, 69, 41,245, 53, 83, 40, 1,164, 34,248,110, 80,153,185,202,204,202,133, 86, 47,128, 86, 71,160,209, 51,120, 55,176, 39,214, -111,250, 19,137,169,153, 40,157, 97,248, 54,209,160, 65, 3, 63, 23, 23, 23, 76,153, 50, 5,154, 93,187, 80, 0,160, 15,128,195, -122, 61, 0,192, 28,152,198,159, 45,255, 79, 6,203,202,169, 81,231, 57, 51, 39,175,233,248, 97, 79, 38,245,139,118,200, 41,208, -106,103, 68,176, 92, 66, 81,181,230, 10,148, 82,218,184,113, 99, 48, 12, 3,165,165, 21,204, 44, 44,160, 41, 23,185,146, 42,205, - 65,117, 58,112,122, 29,196, 38, 94, 28, 75, 53, 41,165, 48, 51, 51,131, 88, 44,126,161,107,176,212, 88,213, 36,130, 5, 0, 57, - 57, 57,216,183,111, 31, 90,183,110, 13,185, 92, 14,161, 80, 8, 31, 31, 31, 68, 70, 70,194,203,203, 11,132, 16, 28, 62,124, 24, -253,251,247,199,211,167, 79,225,237,237,173,172,141,193, 58,123,246,172, 5,165,244, 29, 74, 41, 50, 50, 50,106,181, 19, 57,142, - 67, 65, 65, 1,206,156, 57,131,228,228,100, 56, 58, 58, 34, 59, 71, 14, 75, 85,147,226,223, 42,103,178, 76,100,124,159, 62,125, - 24, 66, 8,212,106, 53,164, 82, 41, 20, 10, 37,204,205, 45,208,176, 97, 35, 36, 38, 38,162,123,247,238,198, 39, 79,158,236, 18, -139,197,235,106, 90,222,122,245,234,153,231,228,228,188,231,225,225, 33, 6, 0, 51, 51,179, 62,238,238,238,150, 49, 49, 49,185, - 53, 52, 3,101,198,138, 16, 82, 54, 3,149, 97, 24, 8, 25, 6,206, 78, 14,101,207, 75,182,157, 84, 87,143, 67,190,152,230,203, - 25,117,216,190,234, 83, 16, 54, 19, 44, 44,161,133, 11, 88,163,160,204,192, 42, 20, 10, 52,237,252,209, 91, 25,193, 18,139,197, -195,183,110,221,234,242,199, 31,127,228, 28, 57,114, 36,183, 77,155, 54,138, 53,107,214, 56,172, 95,191,190,139, 78,167,195,148, - 41, 83,210,110,221,186, 85,216,175, 95, 63,203, 45, 91,182,184,212,175, 95,255,125, 84, 48, 46,139, 16,162, 0, 48, 24,192, 39, - 1,173, 45,133, 57,249,106,112,172, 14,207, 98,158, 35,183, 64, 7,206,168, 71, 92, 66, 18, 10, 52, 70,100,102,229,195,199,183, -251, 79, 65, 65, 65,223, 18, 66,102, 83, 74,143, 85, 87, 78,163,209,136,155, 55,111,226,218,181,107,184,124,249, 50, 98, 99, 99, -203,222,179,176,176,192,217,179,103,209,165, 75, 23,254, 10, 95,245, 53,104, 94,247,238,221,231,217,218,218,202,214,173, 91,103, - 89,183,110, 93,176, 44,171,123, 57,114,229,239,239, 63,103,206,156, 57,206, 31,124,240,193, 68, 0,107,107,251,123,149, 69,182, - 76,224,149, 84, 12,233,233, 41, 95,252,180,117,184,157, 66, 28,155,132,199, 63,186,148,196, 98,128,162, 60, 32,104, 39, 72,135, -185,207, 71, 4,142,183, 94,126,100,253, 23, 0, 54, 84, 38,252,228,105, 60, 54,110, 92,143,175,166,140,192,239,191,174, 0,199, - 9,161, 53, 8, 80,199,163, 45,180,122, 14,132, 17,162,133,175, 63, 46, 6, 93,129,136, 1, 38,143,185,245,214, 29, 7,143, 31, - 63,190, 29, 27, 27,219,120,238,220,185,248,221,197, 5,230,230,230,152, 58,111,222, 13,150,101,219,243,103,201,255,147,193,242, -107,232,245,189,165,141,245,168,246,173,154,216, 78,157,248,133,232,105,138, 6, 23, 58,126,147,179,127,249, 76,101, 60, 85, 78, -136,165, 57,215,106, 18,117, 96, 23, 78, 69,166, 81, 7,143,163,215, 33, 85, 42, 17,213,195, 31, 84,167, 67,135,144, 88, 72,149, - 74, 8,101,102,181, 57,129, 95,232, 14,124,249, 57,195,152,150,184, 94,175,215, 91,117,235,214, 13, 93,187,118,197,135, 31,126, - 88, 54,230,170,101,203,150,216,189,123, 55, 6, 12, 24,128,123,247,238,193,217,217, 25,141, 27, 55, 70,227,198,141,113,225,194, -133, 26,223, 61, 26,141, 70,244,232,209, 35,143, 16, 18, 74, 41,245,185,125,251,182, 69, 77, 53, 74, 27,155, 51,103,206,224,189, -247,222,131,151,151, 23,130,131,131,113,102,193, 15,144,219,212, 1, 96, 5,206,104,132, 78,167, 3,195, 48,213,142,193, 10, 8, - 8, 16, 10, 4,130, 70,245,234,213, 67,122,122, 58,210,211,211, 97,111,111, 15,149, 74, 5, 7, 7, 7,172, 90,181, 10,107,214, -172,185, 77, 41, 93,150,146,146,242,176,166,251, 72,165, 82, 5, 90, 91, 91,255,160, 86,171,197,165,101, 33,132,136,156,157,157, -111,168, 84,170, 89, 73, 73, 73, 71,107, 98,176,244,122, 61, 8, 33, 56,254, 76,133, 66, 29, 65, 94, 66, 48, 38,191, 95,247, 5, -195, 37, 18,137, 94, 72,171, 81,185,193,162,216,181,245,199,144, 89,223,124,230,139,172, 29, 96, 51,119,128, 88, 15,193,129,240, -158,248,243,150, 45, 0,160,161, 19,131, 31, 71, 41,223,218, 8,150, 94,175,223,210,160, 65, 3,232,116,186,243, 0,182,134,134, -134,246, 79, 78, 78, 94,253,215, 95,127,169, 6, 13, 26,148,116,244,232,209,175, 0, 28, 10, 13, 13, 29,185,120,241,226,174, 6, -131,161,194,217,101, 2,129,224,247,169, 83,167, 6, 12, 26, 52,136,136, 25,131,238,204,233,109, 66,150, 53,144,233,179,127, 49, - 6, 93,189,196,176,172,129,124,248,241, 84,238,196,133, 48,102,204,164,149,198,150,109,223,195,131, 7, 15,156,250,244,233,179, - 8,128, 73, 6, 75, 36, 18,149, 25,232, 10,126,159,239, 34,172,134,243,231,207,111, 6,176, 57, 32, 32, 32, 85,161, 80,160,160, -160,224,149,115,164, 93,187,118, 50,149, 74, 37, 19,137, 68,104,221,186,181, 77,143, 30, 61,162, 24,134, 89,123,242,228,201, 26, - 39,161,172, 40,178, 85,219, 52, 13,230,214, 92,159,150,109,155,154, 63, 50,159,111, 46, 19,106,238,185, 71,201, 44, 8,128, 92, -173,227,179,235,177,131,243, 72,154,180,101,179, 64,119,200, 25, 89,159,202, 12, 22, 33, 36, 36, 47, 39,183, 87, 94,190, 14, 87, -175, 61,192,199,131,235, 67,171, 39,224, 56, 6, 5,133, 90, 64, 32, 2, 3, 96,200,208,225,160, 68,136,236,140, 20, 16, 32,236, -109, 59, 14,140, 70,227,172,126,253,250,181, 90,188,120,113,147,169, 83,167,150,238,151,118, 42,149, 42,130,207,131,245,255, 96, -176, 26,120,185,246,236,220,202,127,210,183,179,191, 53,127,124,251, 50,190, 93,244, 19, 87,223,191, 71,238,178, 93,135,243,115, -149,117,186, 22, 37, 61,188, 87,211,168,131,136, 53,128,178,122, 72,149,202, 23, 34, 87, 18,133, 2, 34, 51,121,141, 54,130, 16, - 2, 74,233, 43,221,129,229,205, 85, 77, 46,182, 18,137, 36,231,202,149, 43, 14, 9, 9, 9, 47, 12,104,247,240,240, 0, 33, 4, -183,110,221,194,205,155, 55,241,241,199, 31, 67, 40, 20, 66, 36, 18, 33, 52, 52, 52,191, 54, 17,172,210, 89,132,206,206,206, 61, -218,180,105, 83,225,236, 65, 83, 34, 88,113,113,113,240,242,242,130, 86,171,133,181,181, 53,178, 82,158,225,233,227,135, 40,210, - 26,224,238, 32, 65, 70, 70, 6, 74,243,122, 85,197,165, 75,151,168, 74,165,122, 33,242,147,158,158, 14, 79, 79, 79,108,220,184, - 17,107,214,172,217,144,156,156, 92,227,187, 88, 23, 23, 23, 27,142,227, 22,247,233,211,167,111,255,254,253,209,163, 71,143, 23, -222,223,177, 99,135,229,193,131, 7, 55,185,185,185,245, 23, 8, 4,179, 98, 98, 98, 82,171,219,231, 0,240,219,111,197,233,147, -228,109,231, 97,214, 32,119,124, 50,126, 27,126,252,241, 32,164, 82,233, 11,141,237,194,133, 11,171,175, 71, 74,209,237,195,207, -125,187,248,232, 96,204, 60, 12,139,246,217,200,187,110,141,220,124, 95,220, 90,213, 27, 0,208,252,179, 99,160,212, 29, 0,222, -202, 8, 22,165,244, 44,128,179,229, 94,218, 79, 8, 49, 16, 66,134, 2,216, 67, 41, 61, 88,242,250, 47,168, 34, 49,104,219,182, -109, 91,206,158, 61, 91, 84,154, 54, 67, 85,103, 49,171,215,235, 57, 0,104,228,243,206, 11,125,213,209,209,209,248,241,199, 31, - 81, 88, 88, 8,113, 13,194,204,129,129,129,101, 99, 34,197, 98, 49,236,236,236,160,215,235,193,178, 44,111,174,106,198,188,222, -189,123,207,163,148, 82,142,227,230,150,187,217,146, 90, 91, 91, 95,249,233,167,159,108, 89,150,197,180,105,211,172, 50, 51, 51, -173,198,142, 29, 59, 11, 64,165, 6,171,146, 52, 13,149, 29,111,181, 74,211,192,113,104,168, 84, 90, 32, 19, 9,208,218, 25, 90, -230,216,178, 89,103,147,191,184,167,138,245,245, 86, 24, 13,158, 76,158, 14,150, 50,115, 80, 74, 27, 86,246,219, 44,199,157,124, - 24, 17,209,189,142, 91,125,193, 95,199, 46,163, 95,255, 65,208,106, 25,104, 12, 4, 68, 32, 2, 17,136,209,220,199, 23,141,155, -250,128, 2,136, 10, 15,101,141, 47,158, 27,255,243,212, 29,240,203, 6,215,190, 63,143, 3,128,105,107,207,227,219,239, 87, 99, -216,135, 61, 48,114,228, 72, 62, 15,214,255,135,193,170, 83,167,142,149,131, 82,254,219,132,207, 70,153,199,222,191,129,132,208, - 27,184,118, 53, 42,123,231,129, 35,137,121,185,233,159,213,196, 92,149,143, 96,121,237, 56, 14, 23,103,231,178,200, 85,251,224, - 24, 72,149, 74, 4, 53,119, 1,167,213,162,251,243,188, 26,111, 76, 69, 81, 43,177, 88, 92,171,153,126,165,166,234,229, 1,237, - 99,198,140,193,214,173, 91,209,161, 67, 7, 52,104,208,160,214,119,202, 47,143,137,170,201,236,193,138,180,234,212,169,131,176, -176, 48, 88, 90, 90, 98,251,246,237,112,117,117,193,200,158, 94, 16, 8,138,187,182, 24,134, 49,105, 12, 22,165,212,232,226,226, -242,236,204,153, 51,158,131, 6, 13,130, 88, 44, 70,118,118, 54, 44, 44, 44,176,126,253,122, 78, 46,151,255, 94,211,242,185,185, -185,141,148,201,100, 11, 6, 15, 30, 44,108,212,168, 17, 82, 83, 83, 97,105,105,201,149, 44,109, 4, 27, 27,107, 78, 46,151, 99, -204,152, 49,240,241,241,233, 54,115,230,204,174, 42,149,106,105, 82, 82,210,207,213,153,172,221,187,139,123,167, 62, 91,251, 16, - 58, 93,241, 80,139, 13, 27, 54,192,217,217,249,133,207, 62,121,242,164,250, 89,132, 28,135,179, 7,126, 9, 25, 63,113,176, 47, -177, 30,130,188,235,214,160,150, 31, 35,181,192, 28, 59, 46,165,225, 82, 72,108, 89,162,209,183, 45,130, 69, 8,233,135,226,161, - 23, 39, 40,165,135, 8, 33, 3, 1,244, 40,125,142, 26, 38, 22,101, 89,150, 50, 12, 67,226,227,227,245,114,185,156,216,216,216, - 8,165, 82, 41,180, 90,109,153,209,138,142,142,198,177, 99,199,144,144,144, 0, 27, 27, 27,198,210,210, 18,122,189, 62,219,196, -187,238, 87,210, 51,148,252, 46,111,174,106, 72, 80, 80,208,102, 0,155, 75,159,191,251,238,187, 35,133, 66,225,183, 0, 44,183, -108,217, 98,101,101,101, 69,142, 30, 61,106,216,178,101, 75,142, 64, 32,200, 6,176,186, 42,189,138, 6,179,191, 14, 21,165, 98, -160, 20, 17, 89,185,207,234,138,172, 84,220,125, 13,189, 62, 37,126, 86,227,108, 81,125,123,210,180, 25,250,167, 69, 94, 29,201, - 62,105,159,158,146,198, 80,208,136,202,116,115,115,115,127,249,125,219,190,233,123,247,252, 86, 71,170,148, 98,204,216,217, 56, -126,234, 34, 8, 35,194,149,235,183,160,211, 27,145,145,149,139,193, 67,134,193,213,217, 14, 40, 72, 76, 23, 73, 36, 63,191, 77, -251,254,133, 60, 88,254,237,113,237,224, 74,236,142,170,131,196,239,191,231,243, 96,253,157, 6,203,221,221, 93,170, 16, 97,180, -141,153,120,198,132,161, 31,216,167, 61, 9, 71, 66,100, 8, 0, 64,171, 85, 27,146,163, 46,181, 48,225,162, 29,248,114,174,140, -210,174, 27, 27,123,135,178,200, 85,249,217,131,156, 86, 11, 78,175, 3, 42,233,206,169, 76,147, 97,152, 87,140, 85,249, 11,111, - 77,202, 89, 26, 29,169, 40,193,168,155,155, 27,150, 46, 93,250, 74, 30, 44, 83,202, 89,114,151,214,131, 16,226, 83,106,140, 40, -165, 62,206,206,206, 61, 76,153, 57, 88,153,102,105,198,234,147, 39, 79, 34, 34, 34, 2,148, 82,244,233,211, 7, 34,145, 8,230, -230,230,101, 38,171,162, 49, 88, 21,105, 50, 12,243,249,193,131, 7,167,223,184,113,163,231,180,105,211, 72,233, 88,150,130,130, - 2, 46, 57, 57, 57,191,166,229,228, 56,110,198,233,211,167,133, 70,163, 17, 91,183,110,197,157, 59,119,168, 92, 46, 95, 38, 18, -137,150,202,229,114,214, 96, 48,124,253,197, 23, 95,140,157, 63,127, 62,211,169, 83, 39,220,184,113,131,241,244,244,156, 8,224, -231,234,182,253,214,173, 91,197, 93,206, 89,113, 24, 63,107, 15, 20,102, 66, 60,124,248, 16, 89, 89, 89,175, 36, 31,173,190,156, - 20,190, 93, 6,249,114, 84, 15,189,114, 16, 24,179,119,139,151,202,121,174, 69, 43,159,226,168,163, 58, 47,189,172, 30, 43,138, - 96, 85, 86,206,215, 52, 63,127,171, 38, 33,164,111,147, 38, 77,190,137,136,136,112,109,222,188,185, 55, 33, 36,160, 89,179,102, -173,194,194,194, 74,159,139, 40,165,123,107,162,121,231,206,157,253,235,215,175, 31, 59, 98,196, 8, 49,199,113,198,216,216, 88, - 3, 0,226,228,228, 36,184,115,231, 14,247,215, 95,127, 65,173, 86,195,213,213,149,113,113,113, 33,103,207,158,229, 34, 35, 35, -111, 81, 74,103,155,186,237,165,145,105,145, 72, 4,129, 64, 0,181, 90,109,146,185,250, 95,220, 71,255,159,154, 2,129, 96,225, -129, 3, 7, 92,180, 90, 45,196, 98, 49,246,237,219,167,223,182,109, 91, 68,110,110,110,199,224,224, 96,117,109,203, 89,147, 4, -164,213,105, 22,228, 8,142,159, 58,253,160,149,160,231, 47, 24,159,148,222,177,204,120, 17, 98,115,208,209,187,163,188,117,243, - 68,243,203, 43,153, 34,104,142, 87,166,249,228,201, 19,157,191,191,255,160,153, 51,230,157, 95,176,104,129,114,238,188,121,184, -118, 43, 12,153, 57, 5,224,168, 0, 28, 33,248,246,219,185,112,178,179,129,141,196, 80,148, 89, 72,250,191,188,100,206,255,250, -126,127,157, 60, 88,127, 71, 57,255, 53, 6,203, 92,136, 7, 29,189,189, 92, 58,249, 54,149, 9,141,106, 36, 68, 62, 65, 86,161, - 6,103,195, 99,115, 24,202,252,254, 58, 63, 42, 16, 8, 96,105,105, 9,177, 88,140,118, 97,137,144,136,197,144, 42,205, 1,160, - 56,114, 69, 41, 24,137,180,166, 7, 80,133, 6,171,182, 24,141, 70, 56, 58, 58,190,176,236, 74,249, 6,187,212, 40,214, 52, 69, - 3,195, 48,179,110,220,184, 97, 17, 23, 23, 7, 74, 41, 14, 29, 58,100, 49, 96,192,128, 89,181,137, 94, 81, 74,145,153,153, 9, -142,227, 32,149, 74,209,179,103, 79,116,234,212, 9,250,146,217, 31,165, 13, 80, 77, 51,185,199,199,199, 39, 3,248,202,213,213, -245,247,233,211,167,207,104,211,166,141,255,252,249,243, 65, 8,169,109,104, 64,111, 52, 26,113,233,210, 37, 28, 60,120,144,213, -104, 52, 3, 82, 82, 82,238,150,123,127,145,171,171,235, 95, 3, 6, 12, 56,241,232,209, 35, 97, 68, 68, 4, 0,176,213,137,170, -213,106, 52,104,208, 0, 44,203, 98,249,120, 55,228,231, 55, 7,203,178, 48, 26,141, 80, 40, 20, 47,228,253, 50,101, 63,113,148, - 67,200,197,125, 33,117, 91,246,240,173,110,169,156,183, 44,130,213, 51, 34, 34,194,117,232,208,161,105, 97, 97, 97,174,199,142, - 29,179,234,211,167,143, 98,200,144, 33,105, 97, 97, 97,174,132,144,119, 0,236,173,225,249,243, 13, 33,228,212,146, 37, 75,102, - 77,154, 52,169,205,136, 17, 35, 68, 34,145,136, 75, 76, 76,100,119,237,218, 69, 26, 52,104,192,136,197, 98,114,250,244,105,238, -246,237,219, 55, 89,150, 93, 78, 41,189, 82,211,235, 72,169,185,226,199, 92,189, 81,246, 14, 26, 52,104,228,128, 1, 3,204, 90, -183,110, 45,253,229,151, 95,114,139,138,138, 42, 52, 87, 21, 81,147, 52, 13, 53, 77, 64, 90, 74, 82, 82,210,175, 75, 23, 94,158, -242, 73,227, 33, 94,159,219,185,227, 92, 97, 26,178,133, 2,198,194,138,129,111, 93, 1,212, 57,207,237,207,223, 58,240, 60, 57, - 41,169,202,188,106,119,239,222,189,227,231,231, 23,248,201, 39, 35, 15,140,249,236, 11,135,185,223,204, 20,237,255,235, 4,192, -234,113,251,202, 21, 88,201, 9,101, 11,147, 83, 51,117,228,131,183,113,169,156,216,131,159,143, 7, 48,158, 16,242,241,188,121, -243,118,141, 31, 63, 30, 28,199, 33, 40, 40, 8, 63,207,156,137,249, 70,227,167,235, 8, 41,154, 68,233,120,254,180,120,131, 6, - 11, 12,201,191,249, 56,182,224,214,227,216, 2,112,148,114,148,106, 25, 6,241,133,122,253,146,168,167, 9,167, 95,103,159,246, -236,217,147,121,217,184, 84, 4,203,178,166, 14,174,139, 13, 12, 12,124, 99,154, 28,199, 37,116,236,216,241,149,134,185,178,255, - 75,116, 19, 76, 10,201,114,220,178,118,237,218,189,242, 90,173,194,187, 28,247,172,107,215,174,250,151, 77, 87, 85,207,141, 70, - 99,130,169,250, 9, 9, 9, 15, 0, 12,115,113,113,233,210,163, 71,143,137, 0,106,155,142, 97, 85,151, 46, 93,166, 82, 74,133, -132,144,149, 47,153,171,210,223, 10,119,113,113,153,235,233,233, 89,182, 0,116,117,219, 30, 24, 24,168,175,110,145,231,242, 3, -160, 57,142, 75,168, 90,147,162, 78,139,238,190,122, 67,177, 73,171,106,169,156,202, 34, 88,255,163,236, 33,132,136, 0,100, 71, - 68, 68,188, 83, 18,185, 74,120,240,224,193,185,221,187,119, 59, 2,213,167, 79,168,228, 6,224, 10,128, 43,132,144, 78, 27, 54, -108,248,102,204,152, 49,173, 63,254,248, 99, 97, 64, 64, 0,142, 31, 63,110, 12, 10, 10,186,165, 86,171,151,213,212, 88, 17, 66, - 10, 94, 62,135,170, 40,195, 91,191, 72,239,155,230,236,217,179, 95,183,107,215,110,238,190,125,251,146,188,188,188,164, 34,145, - 72,103,170,185, 2,106,150,166,129, 82,202,213,242,216, 98, 29, 29, 29,123,239, 24, 58,254, 72,139, 9, 35, 60,122,118,240,151, -187,184, 59,184, 60,122,158,129,132,176,115,133, 79,131,214,199, 24, 53, 89,253, 40,165,213,222,168, 5, 7, 7,223,110,215,174, - 93,253, 13, 91, 54,141, 23, 48, 76,119,214,104,244,153, 58,126, 24, 37, 64, 24, 7,156, 21, 75, 37,111,253, 98,207, 82,177,248, -211, 9, 19, 38,224,207, 63,255,196,161, 53,107,208, 35, 33, 1,187,197, 98,152,137,197,216,168,215,143, 3,192, 27,172, 55,105, -176,194, 30, 63,247,251, 59,126, 48, 34, 34,162,221, 63, 93, 51, 34, 34,194,255,239,170,240,215, 25,107, 85, 65, 57,255, 95,166, -209, 38, 38, 38, 94, 4,112,241, 53,190,191, 13, 38, 44,230,108,234,231, 0,224,225,195,135,111,124,219,169,212,114, 80,220,253, - 51, 57, 78, 77,222,181, 98, 89, 22,132, 16,104, 52, 26,220,188,121, 19,218,162,124, 4,237, 28, 93,150,201, 29, 20, 72,137,188, -144,227,228,209,204,234,127,253, 34, 64, 41,189, 12,224,114,137,121,233, 79, 8,233, 13,224, 52,165,116,255, 27,210, 47, 51, 90, - 91,182,108,153, 66, 41, 69, 94, 94,222,154,154, 26,171,178,107, 83, 88,216, 5,240,252,173,220,184,113, 67,211,181,107,215,223, - 23, 47, 94,220,150,227,184, 63,222,132,230,107,164,105,168,144,212,212,212,231,132,144, 22,220,247,107, 71, 5, 91,153,191, 71, - 13, 76, 35, 98, 16, 30, 37,186,204,227, 41, 41, 41,191, 81, 74,141, 53,217,222,146,155,186, 31,255,141,251,251,126, 88, 88, 15, - 0,232,213,171, 23,212,211,138,211, 94,109,251, 79, 30,172,141,252, 25,241,166, 35, 88, 60, 60,255, 50, 18,163,130,247, 3, 64, - 74,100,113,251,253,211, 79, 63, 1, 0,122,244,232,241,202,172,199,210,207,164, 60,127,240, 86,213, 65,201,128,246, 67,127,147, -246, 21, 0, 87,248, 35,237,127,131,243,231,207,191,209, 4,147,111, 58, 1,105,201, 49,101, 4,176,181,228,193, 83, 75, 26, 54, -108, 72, 0,192,206,206, 14,115,106,176,156, 26, 79,213, 48,124, 21,240,240,240,240,240,240,240,240,188, 89, 8,128,192, 74,238, - 12, 76,158, 29, 64, 8, 9,172,197,157,199, 57, 94,147,215,228, 53,121, 77, 94,147,215,228, 53,255, 93,154,213,105,191, 53,179, - 19, 75, 51, 92,255, 29, 15, 0,129,188, 38,175,201,107,242,154,188, 38,175,201,107,242,154,255,182, 71, 21, 99,176,246, 11, 18, - 19, 97, 33,145,200,197, 0,160,211, 21,233, 93, 92,144, 7, 12, 52,130,135,167, 38, 97, 82, 66, 28, 75,204,124,234,155,252, 44, - 15, 15, 15, 15, 15,207, 63, 21, 97,101,230, 42, 35, 67,110, 39, 20,102, 55, 52, 26, 53,141, 1, 64, 40,100, 30,102,100, 88, 71, -217,217,237,207,120,211, 38,171, 87,175, 94,179, 41,165,142, 34,145,232,184,147,147, 83,208,230,205,155, 13,255,102,163,241, 58, - 38,227,255,195,160,216,218,218,170, 28, 29, 29,135, 90, 89, 89, 5,228,230,230, 94, 73, 73, 73,217,158,153,153,153, 84, 73,121, -150, 18,130, 25, 37,255,175,160,148,126, 83, 69,217, 77,254,236,203,168, 84,170, 6, 50,153,108, 60,195, 48,205, 0,128,227,184, - 7, 26,141,102, 67, 82, 82,210,227,127,219, 73,173, 82,169,204, 40,165, 31,136, 68,162,225, 54, 54, 54,173,211,211,211,231, 39, - 38, 38,174,174,229, 49, 43, 4, 48,205,202,202,234, 99, 43, 43, 43,207,172,172,172,167,121,121,121,123, 1,252, 72, 41,173,246, - 60, 93, 48, 89,213, 46,160, 71,192,156,160,211, 65,139,230,173, 77,186,241,202,251, 95,171,108,187,119,235, 48, 55,232,232,245, -133,223,172, 79,204,170, 97,217, 24,252,103, 28, 41, 87,124,216,255,115, 71,232, 58, 56, 56,180, 45, 73,164,202, 48, 12,243, 99, -106,106,234,197,127,242,113,100,111,111,175,112,114,114, 90, 78, 8,233, 43, 16, 8, 34, 82, 83, 83, 71, 39, 37, 37, 37,188,161, -107, 33, 83,183,110, 93,243,216,216,216,252,218,166,106,248, 55,210,174, 93,187, 84,189, 94, 95,101,118,124,177, 88,156,118,227, -198, 13, 71,190,182,254,161, 6, 43, 49, 17, 22, 66, 97,118,195,180,148,176,193, 73,201,161, 31, 1,128,202,217,103,175,131, 83, -243, 61,137,137, 18,125,171,110, 3,148, 34,185,112,131, 64, 32,106,169,209,105,237, 68, 66, 81,134,158, 53,220, 99,116,116,124, -242,195,131,113,166,252,112,223,190,125, 27, 2,176,244,245,245,189,163,211,233, 90,175, 94,189,218,249,192,129, 3, 62,193,193, -193, 67,222,127,255,253,163,148,210,211, 71,143, 30, 85,215,232,164, 13, 8, 16, 58,228,216,124, 42, 16, 10,251, 2,240,161, 20, - 0, 17,132,114,122,221,137, 52,177,205, 31, 52,184,246,198,173, 93, 3,219,134,132,234,167,139, 8,237,100,160,228, 10, 37,226, -149, 55, 30,103, 70,213,224,130, 98,146,121,120, 29,147,241,210,119,215, 80, 74,167,189,233, 3,198,201,201,201,110,224,192,129, - 59, 22, 45, 90,164, 48, 55, 55, 39, 49, 49, 49,253,191,249,230,155, 30, 42,149,234,147,164,164,164,248,151,205, 30, 33,152,193, -113,148, 1, 0,134, 33, 51, 29, 29, 29,155, 9,133, 66,237,203,186, 44,203, 74, 9, 65, 79,142, 43, 94,206,134, 97,200, 12, 66, -200, 90, 83,140,162,167,167,231,144,230, 62, 45,167,126, 51,123,174,210,222,193, 65,193,178, 70,125,124, 98,130,124,229,210,239, -219,120,122,122,174,125,246,236,217,174,154,110, 39, 33,132,184,186,186, 14, 22,137, 68,125, 0, 52, 41,121, 57,210, 96, 48, 28, - 75, 72, 72,216, 99,106, 67,222,162, 69,139,203, 12,195,184,215,228,183,141, 70, 99, 92,104,104,104,199,218,236, 31, 23, 23,151, - 65, 46, 46, 46,191,181,109,219, 86,222,178,101, 75,136,197, 98,172, 88,177, 98, 26,170, 89,222,164,212, 72,201,229,242,193, 10, -133,194,171,160,160,224,137, 90,173, 62, 32,145, 72, 2,215,174, 93,235,214,161, 67, 7,243,212,212, 84, 34, 16, 8, 28,143, 29, - 59,246,233,186,117,235,122, 16, 66,186, 86,151,103, 40,247, 9,157, 35,237,219,164, 83,238,147,139,115, 0,244,122,101,191,107, -100,195,169,192,173,143,154,134,196,163, 6, 83,228, 9, 33,140,171,171,235, 90, 71, 71,199,145,106,181, 90, 67, 8,161,132, 16, -218,188,121,243,210,247, 1, 0, 58,157, 46,251,209,163, 71,141,170,210,242,104,103,115, 87,192, 8, 92, 43,221, 31,156, 49,225, -249,141,172,215, 78,221, 98, 52, 26,103, 68, 68, 68,244, 22,137, 68,164, 69,139, 22, 2,212, 32,245,137, 74,165,106, 72, 8,249, -150, 82,122, 39, 57, 57,121, 67,201,146, 86, 93, 40,165,101,215,138,146,116, 42,112,113,113,217, 80,191,126,253,247,163,163,163, - 55, 38, 38, 38, 46,122, 13,163,190,121,201,146, 37, 31,245,232,209, 67,144,153,153,233,210,189,123,247,157, 0, 58,189, 78, 29, -248,249,249,137, 82, 82, 82,166,181,104,209,226,203, 86,173, 90, 57,135,135,135,167,168, 84,170,117, 78, 78, 78, 63, 6, 7, 7, - 87,123,125,246,241,241, 81, 9,133,194,145, 0, 62, 5, 32,160,148,238, 6,240, 71, 72, 72,200,211,127, 67,131,173,215,235, 29, -206, 45,154, 11, 34, 20, 66,214,177, 43, 56,142, 67,198,202,121, 96,179, 50, 96,183,104, 29, 88,150, 69, 96, 96,160, 3,120,254, -185, 6, 75, 34,145,139,141, 70, 77,227,164,228,208,143,222,233,252,147, 37, 0, 92,190,244,229, 71, 14, 78, 77, 31, 72, 36,242, - 40,169,133,236,224,128,190,129, 45, 7,246,233, 76, 92,157, 29,144,144,156,230,248,235,238,211, 61,143,157,190,120, 16,128, 73, -249,179,242,242,242, 22,215,173, 91,215,254,252,249,243, 49, 18,137,196, 76, 38,147,145, 65,131, 6,153, 13, 25, 50,196,251,194, -133, 11, 94,167, 78,157, 26,216,175, 95,191, 83, 98,177,248,248,190,125,251,170, 93,159,204,177,121,127,111, 39,161,211,254,126, - 31,244,114,127,175,155,131,164,174,147, 61, 40, 39,195,195,103,250, 58,103,175,132,244, 60,126,242,244, 12, 7,239,254, 31,166, - 69, 28, 50,121, 53,244,102,205, 44,173,204,212,116,170,153,152,126,220,179,141,183, 71,223,110,237,137,167,167, 39,162, 30, 69, -121, 93,188,118,103,100,151,198,230,207,213,122,178, 91,109, 70, 86, 61,120,144,155, 83, 85, 84,169,188,209, 16, 8,152, 89,221, -186,117, 27, 41,149, 74, 95,184,115,211,106,181, 12,195, 16, 7,163,177,248,229,154,152,140,210,223,208,233,180,140, 72, 36,129, - 64,192, 76,109,217,178,101,175,212,212,212,147, 82,169,116,197,243,231,207,107,148,119,102, 18, 33,146,108,161,208,143,145, 74, -157,141, 58,157, 45, 0, 16,137, 36,187,142,173,109,219,239,190,251, 78, 41, 16, 8,144,153,153, 9,141, 70, 67, 62,255,252,115, -179, 39, 79,158,140, 0,176,176, 58,211,178,109,219, 54, 95, 91, 91,219, 87,238, 88, 51, 51, 51,153, 94,189,122,214, 56,111,167, - 74,165,106,216,194,215,255,171, 93, 59,119, 52,201,203,202,214,108, 93,189, 57,216, 32,147,107, 61,155, 52, 18,125,191,116,149, -229,156,153, 83,191, 84,169, 84,247,146,146,146, 76, 54,195,206,206,206,117,220,221,221, 15,206,158, 61,187, 89,199,142, 29, 69, - 14, 14, 14, 72, 77, 77,197,163, 71,143,154, 93,187,118,237,131,195,135, 15, 79,115,118,118, 30,144,156,156, 92,237,205, 4,165, -180,193,145,149, 75, 29,164, 54,182,224, 12, 6,216,248,248,150, 37,127, 77,190,120, 6, 70,189, 30,156,193, 0,183,247, 62, 64, - 73,228, 13,239,190,251,110,173, 82,146,187,186,186,170, 26, 54,108,248,231,172, 89,179,196, 58,157, 14, 33, 33, 33,184,113,227, - 6,151,150,150,182,172, 58,115, 69, 8, 57, 51,111,222, 60,215,142, 29, 59,154,103,100,100,192,104, 52,218, 29, 62,124,120,188, -175,175,175,133,155,155,155,100,251,246,237, 40, 40, 40, 0,203,178, 54, 94, 94, 94, 54, 67,134, 12,209,109,223,190,125, 26,128, -229,149, 69,174,242,158,208, 57, 41,196,171,103, 35,191,225, 72, 33,167,122, 78,237,229,124,210,162, 30, 41,139,100,245,170, 87, -207,220,171,177, 98,166,210,162,185, 77, 94,226,185,153,189,234,213,219,122,242,201, 19, 83,150, 98, 98, 92, 92, 92,214,246,238, -221,123,232,198,141, 27,229,145,145,145,242, 38, 77,154,128,227,184,178, 76,254,165, 43, 23,116,234, 84,189, 31, 16, 48, 2,215, -107, 7,195, 29,204,204,204,202,214, 8, 45,253, 91, 88, 88,136, 30,195,219,254, 29,215,219,154,238,227, 5,215,175, 95, 31,116, -242,228,201, 97,139, 22, 45,106, 0, 96, 34,199,113,115, 35, 35, 35, 59, 3, 64,147, 38, 77, 36, 0, 46,170, 84,170, 81,227,198, -141, 27, 55,113,226, 68,124,250,233,167,115, 9, 33,139,107, 19,213, 35,132, 8,154, 54,109,218,187, 71,143, 30, 2,131,193, 0, - 51, 51, 51,232,245,250,122,175,179,241,222,222,222,226,162,162,162, 3, 11, 23, 46,236,211,175, 95, 63, 8,133, 66,112, 28,231, -116,249,242,229,165,211,166, 77,107,239,231,231,215,191, 50,147,229,231,231,215, 18,192,194,250,245,235,247, 24, 62,124,184,160, - 67,135, 14, 40, 40, 40,192,153, 51,103,190, 61,120,240,224,183,126,126,126,215, 1,204, 13, 14, 14, 14,122,219, 27,109,129,210, - 28,143, 6,116,129, 87,100, 38, 0, 32,101,195, 74, 0,128,197,119, 63,240,142,230,127,193, 96, 85, 71, 81, 81,145,239, 55,147, - 62, 5,195, 20,183,135,245, 61,235, 96,233,236,209,228,200,177,211,190,213,132, 55, 87, 25,141,198, 6, 54, 54, 54,211, 53, 26, -141,108,205,154, 53,178,164,164,164,198,251,247,239,167,247,239,223,135, 88, 44,134,165,165, 37,186,118,237, 42,237,217,179,103, -189,235,215,175,215, 57,120,240, 96,191,247,222,123,239,143,227,199,143, 31,173,202, 92,217,217,219, 95,250, 97,209, 23, 54,205, - 60,189,160, 55, 24, 16,159,150, 8, 74, 36,112,118, 80,224,147,254, 45,197, 29,253, 37, 94, 63,252,124, 46,200,177, 89,191,119, - 82, 31, 28, 9,175,110, 27, 59,213, 87,220,238,239, 87,207,175,111, 96,123,166, 65, 35,111,136,101,242,178,247,154,183,244, 69, -243,150,190,100,244,200,124,207,251,247,239,207, 57,117,233,214,236, 78,245, 21,193, 87,162, 11,171, 90, 24,243, 5,243, 48,109, -218, 52,216,218,218,190,108, 50,112,225,194,249, 74,191, 99,202,117,177,252,147,165, 75,151, 90,165,165,165,125,252,235,175,191, -126,224,228,228, 52, 33, 37, 37,229,148, 41, 34,159, 18,226, 14,169,180,235,200, 31,127,228, 90,190,255,190,192,202,201,137,225, -140, 70,146,240,228,137,221,143,107,214, 4,230,199,199,203,213,230,230, 5,233,185,185,186,168,168, 40,152,153,153, 17,129, 64, -208,161, 2,115,145, 74, 8, 89,193, 48,100, 38, 33,132,200,100,102,217,159,125,246,217,245,146,247,154, 28, 61,122,212,188,111, -223,190,249,132,144, 72, 0,144,201,204, 58, 11, 4,140, 53, 45,238,232, 89, 97,138,177,148,203,229,147,166,125, 61, 75,145,151, -149,163,214, 23, 22, 26,236, 45,148,132, 40,205, 5,121,185,249,249,137,201,233,218,113, 95, 78, 17,204,153, 53,117, 18, 76,204, - 68,236,236,236, 92,167,113,227,198,183,183,110,221,234, 96,107,107,139,156,156, 28,100,102,102,226,246,237,219,224, 56, 14,189, -122,245,146,250,250,248,248,254,184,106,213, 13,103,103,231,118,166,152, 44,153,173, 29,246,191,211, 18, 0, 48,232,105,102, 89, -132,229,228,224, 62,101,159, 25, 18,155, 91,252, 89,153,172,198,203, 47,149,171,239,118, 29, 58,116, 16, 3,192,212,169, 83,243, - 10, 11, 11,151, 18, 66,118, 38, 37, 37, 37, 86,243,213,105,115,230,204,113,241,244,244,172,187,115,231, 78, 20, 20, 20, 0,128, -131,167,167, 39, 26, 53,106,100, 12, 10, 10, 66,195,134, 13, 97,110,110,142,203,151, 47,227,230,205,155,240,243,243, 51, 23,139, -197, 31, 85,102,176, 2,122, 4,204,145,246,109,210,169,145,223,112, 40, 45,156,177,117,215, 30, 60, 10,222,214, 73,171,143,156, -179,116,162,203, 39,106, 42, 29,225,218,192,124,150,187,127,103,219,250, 77,223, 71, 93,191, 16, 59,141,241,202,179,185, 19,188, -150, 9,101,154,109,243,126, 72,202,172,204, 92, 57, 57, 57,173,236,213,171,215,160,141, 27, 55, 90, 1, 64, 88, 88, 24, 82, 83, - 83, 97,111,111, 15,153, 76, 6,145, 72, 84,182,126,168,169,152,153,153, 33, 57, 57,185,108,153, 41,163,209,136,252,252,124, 56, - 57, 57, 21,187,155, 5,132,153, 55,207,180,174, 44,103,103,231,142,190,190,190, 59, 92, 93, 93,221,202,191,222,163, 71, 15,140, - 30, 61, 26,148, 82,116,232,208,161,235,232,209,163, 41,165, 20, 28,199, 33, 53, 53,181, 32, 44, 44,172, 91, 98, 98,226,173, 74, -182, 91,157,146,146,130,113,227,198, 33, 46, 46,110,130, 74,165,138,101, 24, 70, 86,186, 28, 24, 33, 68,162, 82,169, 26, 54,108, -216,112,237,232,209,163, 17, 19, 19,131,168,168,168,219,181,237, 50,165,148, 26,219,182,109, 27,109, 48, 24,252, 89,150,133, 90, -173, 70,207,158, 61,101,141, 27, 55, 78, 21,137, 68, 15,115,114,114,134,149, 44,169,101,138, 89, 19, 58, 59, 59, 59,137, 68,162, -141, 95,124,241, 69,239,246,237,219,227,225,195,135, 56,121,242, 36,250,245,235,135,128,128, 0,204,153, 51,231,189, 57,115,230, - 76, 3, 80,217,205,192,254, 3, 7, 14,120,184,186,186,150, 45,137,100, 97, 97,129,207, 62,251, 12,159,126,250, 41, 78,156, 56, -209,126,201,146, 37, 7, 2, 2, 2, 28,130,130,130,216,183,185,209,150,250,183,135, 87,100, 38,158, 54, 41,110, 63, 74,141, 86, -233,115,184,248,130,231, 31,108,176,116,186, 34,189, 80,200, 60, 84, 57,251,236,189,124,233,203,178, 46, 66,128,121,168,211, 21, -233,139,195,230, 20,121, 69, 44,204,164, 12, 98, 82,242, 17,254, 52,163,162,147,244,220, 75,198,236,171,117,235,214, 97,197,138, - 21,189,212,106,117,193,179,103,207,146, 11, 10, 10, 10, 63,249,228, 19, 34, 20, 10,113,237,218, 53, 60,127,254, 28,205,155, 55, -135,181,181, 53, 58,118,236, 40,238,222,189,187,219,168, 81,163, 62, 1,112,180, 34, 77, 18, 16, 32,116,150,218, 31, 92,185,104, -176, 13,152, 40, 68,197,229,160,158,107,107,216, 89,185, 33, 49,189, 0,119, 34, 78,224,241,147,227,168,231, 82, 23,163,135,214, -183, 90,189,249,218, 49,226, 55,166, 94,249,238,194,138,166,132,202, 4,198, 86,243,119,221,135, 49,235, 9,104,110, 28,104,225, -171,171,196,200,237,220,208,184,157, 35,228, 86,246, 76,216,195,213,173, 42,219,118, 74,105,170, 80, 40,220, 34, 16, 48, 99, 0, -160, 85,171,214,133,203,151, 47,175,232, 98,205,181,106,213,186, 80, 32, 96, 20,197, 17, 44,193,102,150,101, 83,171, 42,231, 75, -102,102,165, 68, 34,157, 14,128,184,186,186, 21, 28, 57,114,132,251,240,195, 15,177,114,229, 74,233,172, 89,179,126,118,119,119, -239, 18, 19, 19, 19, 91,213, 62, 26, 64, 72, 29,151,122,245,186, 47,190,118,141,138, 12, 6,146,117,251,118, 94,126,106,170, 33, - 49, 63, 95,246, 71, 72,200,192, 9, 51,102,200,156,188,188,112,253,220, 57,243,148,236,236,252,156,162, 34,221,179,103,207,168, -209,104,188, 82,201,182,127,227,232,232,216,108,219,182,109,190,159,125,246,217,245,196,196,196, 1, 37,221, 24, 7, 1,180, 37, -132, 68,150,127,237,224,193,131,237,135, 15, 31, 30,146,154,154,250, 77, 85,229, 44, 71, 83,123, 59, 59,249,174,205,219, 67,109, -204,205, 24,123, 87, 21, 35,178,178, 18,178, 18, 51, 49, 7,168,235,184,121, 40, 0, 52,173,164,206, 94, 94, 52,156,184,187,187, - 31,252,253,247,223, 29, 68, 34, 17,140, 70, 35,236,237,237,241,252,249,115,228,228,228, 32, 63, 63, 31,207, 30, 70,194,195,205, - 13,147, 71,127,238,188,224,135, 85, 7, 9, 33,254,229, 27,177, 10, 23,227,214,235, 95,110,112, 42, 91, 32, 28,166,148,179, 50, - 56,142,123,158,148,148, 4,185, 92,142, 38, 77,154, 40,239,220,185,115, 37, 49, 49, 49,177, 58, 77,153, 76,246, 81,135, 14, 29, -204,119,237,218, 5, 63, 63, 63, 88, 90, 90, 34, 40, 40, 8, 97, 97, 97,208,235,245, 76, 65, 65, 1,204,205,205,177,108,217, 50, -212,173, 91, 23,121,121,121,136,139,139,179, 21,137, 68,118,149,105, 6,157, 14, 90,148,251,228,226,156, 20,114,170,231,214, 93, -123,240,197,144,193,112,162, 79,175, 88,214, 35,139,186,247,237,240, 29, 21,184,245, 81,152,251, 88, 55,104,214, 23, 98,137, 18, - 19,103, 44, 68,212,131,163,214, 69,249,161, 19,136, 49,222, 13,192,228,151, 53, 73,113, 5, 49, 42,149,234,243,205,155, 55,155, -151,221,209,151,172, 73, 88,222, 88,149, 62, 42,170,211,202, 22, 76,215,235,245,208,235,245, 48, 26,141,200,200,200, 64,126,126, - 62,172,172, 74, 18,245,207, 3, 8, 8,161,149,172, 66, 95, 94,147, 97,152, 97,123,246,236,113,147,203,229, 47,127, 6, 37,209, - 65,200,229,114,112, 28, 7,189, 94, 15,150,101,161,213,106,149, 1, 1, 1,227, 1,220,170, 72, 83, 32, 16, 76, 29, 55,110, 92, -135, 99,199,142,121, 45, 90,180, 8,122,189,126,101,122,122, 58, 70,143, 30, 13,142,227,208,177, 99,199,182,148,210, 71,147, 39, - 79, 6, 0,204,159, 63,223, 80, 80, 80, 48,182,182,199,146,163,163,163,119,223,190,125,189,206,159, 63,143, 78,157, 58, 65,171, -213,226,187,239,190,179, 88,177, 98,133,197,222,189,123,237,151, 46, 93,250, 27,128, 30, 85,105,250,249,249,137, 82, 83, 83,103, - 14, 27, 54,108, 90, 96, 96,160,101, 92, 92, 28,204,204,204,112,228,200, 17,108,222,188,249,164, 94,175,159,115,224,192,129,197, - 91,182,108,233,217,175, 95, 63,108,222,188,121, 82,201,176, 8,174, 2, 77,149,155,155, 27, 66, 67, 67, 97,109,109, 13, 59, 59, - 59,228,230,230,226,230,205,155,184,125,251, 54, 26, 55,110, 12, 66,136,117, 73,155,198,190,206,121, 84, 67, 35,250,255,174, 89, - 58, 67,141, 43,119,236, 82, 74,139, 55,154,214,190,156,132, 16,161, 74,165,234,103,101,101, 53,129, 82, 42,204,206,206,222, 44, -151,203,247, 63,121,242, 68,247,255,181,237,255, 10,131,229,226,130,188,140, 12,235, 40, 7,167,230,123, 28,156,154,150,164,170, -102, 30, 10, 4,214, 81,142,142, 69,121, 0,160,103, 41,174, 63,204, 65,104,116, 10,194,162, 83,160,144, 86,127,215,109,107,107, -139,246,237,219,227,200,145, 35,136,143,143, 87, 46, 91,182,172,129, 94,175,215,247,237,219, 55,201,221,221, 61,187, 99,199,142, - 16,137, 68,184,115,231, 14,242,242,242,192, 48, 12,164, 82, 41, 56,142,171,244, 86,212, 33,219,122,248,240,209,205, 61,237,172, - 24, 28,189,122, 10,109, 27,247,135, 92, 42, 66,122,142, 26, 4, 4, 79,159,159, 3,199, 42,113, 63, 50, 6,237,125,228,120,167, -181,149,107,193,249,172,209, 0,126, 54,165,130,244,207,130, 32,241, 30, 0,112, 77, 65,179,159,128,203, 75, 4,149, 59,160,144, - 51, 67, 70, 82, 44, 30, 94,217, 7,170,175,126,168, 24,203,178, 99, 29, 28, 28,152, 57,115,230,244,245,244,244,228, 38, 78,156, -120,237,249,243,231,131,202,127,198,195,195, 99,223,250,245,235, 59, 60,123,246,172,104,209,162, 69, 71,211,210,210,198,213,240, -196,156, 73, 8, 89, 13, 0,241,241,241,153,135, 15, 31,238,116,249,242,229,165,171, 87,175,118,157, 56,113,162,116,226,196,137, - 51, 1,140,171,170, 91, 80, 33,149, 6, 46,190,124,153,178, 9, 9,218, 67,155, 55, 11,214,220,184, 49, 75,207,113,117,236, 29, - 28,132, 1,157, 58,105,236,172,172, 10, 83, 83, 82, 56, 43,149,138, 60,127,242, 68,201,137, 68,250, 83,167, 78,229,103,101,101, - 85,186,196,141, 80, 40,212, 86,212, 45, 88,201, 49,194, 85, 52, 70,171, 10,242, 56, 74,245, 86,158,158,180,123,215,118,245,163, - 31, 61,125, 42,179,178, 18, 52,168,239,209, 40,252,225,243,219,212,200,106, 0,228,153,216,197, 54,120,222,188,121,205, 45, 44, - 44,192,113, 28, 44, 45, 45,145,158,158, 14,157, 78,135,188,188, 60,232,242,115,161,203,205, 69, 88,236,115,116, 8, 8, 64,247, -118,109,155, 28, 55, 24, 6, 3,216, 93,149,174,141,143,111, 89,228,106,159,215,127,162,150, 31,199,228,148,153,173, 19,173,235, - 65,162, 84,160,249,148,111,106,125, 50, 39, 39, 39,135,212,173, 91,247, 68,175, 94,189,122,143, 25, 51,134, 73, 73, 73, 57,229, -232,232,216, 33, 53, 53, 53,162,170,239, 41,149,202,122,165,134,194,210,210, 18,107,214,172,129,163,163, 35,138,138,138,112,231, -206, 29,234,234,234, 74, 46, 94,188, 8, 87, 87, 87,100,100,100, 64,175,215,163,176,176, 48, 69,167,211, 85,122,224,151,116, 3, -246,154,218,203,249,228,163,224,109,157, 92,200,179, 59, 31, 77,235, 28,253, 40,236, 97,220,153,179,215,190,103, 53,178,248,156, -132,115, 51, 61, 91,133,216, 77,152,190, 0,235, 87,206,195,163, 91,151,179, 28,235,228,253,108, 70,180,127,180,233, 86,101, 4, - 93,243,240,225, 67,243,251,247,239,131, 16, 2, 75, 75, 75,200,229,242, 10, 77,150,169, 24,141,198,178,191, 25, 25, 25, 72, 79, - 79,199,147,216, 40, 28,184,176, 13, 6,214, 96,247,123, 27,139, 20, 47,177, 56,212, 46,151,204,206,120, 64, 67,170, 57, 15, 55, -127,252,241,199,131, 93, 92, 92,204,203,191,222,162, 69, 11, 12, 27, 54, 12,219,183,111,199,221,187,119,203,186, 49, 41,165, 72, - 79, 79, 79, 54, 26,141,127, 84,166, 25, 23, 23,151,227,234,234,218,243,243,207, 63, 15, 62,116,232,144,197, 15, 63,252, 0,163, -209, 8,150,101,203,186, 69, 75,255,238,220,185, 19,193,193,193,115, 83, 82, 82, 30,214,230, 56,114,114,114,106,220,183,111,223, -203, 63,255,252,179, 85, 90, 90, 26, 50, 50, 50, 80, 80, 80,128,194,194, 66, 24,141, 70,120,120,120, 16,150,101, 27, 85,215, 29, -200, 48,204,145, 11, 23, 46,244,108,208,160, 1, 0,192, 96, 48,224,250,245,235, 24, 61,122,116,166, 92, 46,255, 40, 38, 38,166, - 80,165, 82,125,123,252,248,241,158, 45, 91,182,132,143,143,143, 83, 90, 90,154, 57,128,220, 74,110, 32, 96, 52, 26,145,158,158, -142,244,244,116,252,250,235,127,214,113,214,106,181, 37,193, 1, 29,105,213,170,149,199,157, 59,119,158,191,173,141,118,204,159, - 91, 17, 51,251, 75,184, 95,121, 4, 0, 8,246, 46, 30,114, 85,247, 82,100,241,240,131,225,195,107,164,167, 82,169,108, 41,165, - 95, 4, 6, 6, 78,233,217,179,167,189, 74,165,130,141,141, 13,194,194,194, 58,156, 62,125,250, 39, 87, 87,215, 77, 70,163,113, -147, 41,209,122, 30,147,186, 8, 7, 26,237,236,246,103, 36, 38, 74,244, 18,137, 60,170, 52,170, 85,108,174, 6, 26,129, 93, 96, -245,134,146, 11, 4, 45,121,152,214,173,161, 73,254, 16,156,250, 47, 56,200,251, 97,203,150, 67, 72, 75, 75, 19,175, 89,179,198, -253,208,161, 67,174,195,134, 13,139,171, 95,191,126,110, 64, 64, 0,182,109,219, 6, 39, 39, 39,104,181, 90,112, 85,136,155,219, - 24, 7,182,109, 94, 95,240, 56,246, 1,252, 27, 14,132,135,170, 35,158, 38,230, 34, 43, 95,139,204, 92, 53, 26, 53,156,142,212, -204, 34,228, 22,106, 16,246,104, 39, 92,156, 60, 25,129,232, 73, 79, 83, 13,150,230,254, 14,104,195,246, 64,236,213, 5,146,166, -131, 33,114,109,135,248,176, 32,220, 59,241, 35, 18,194,175,130,114, 70, 56,186, 55, 49,105,219, 69, 34,209,194,227,199,143,119, - 95,178,100,137,168,107,215,174, 29, 84, 42, 85,251,164,164,164,235, 37, 7,121,251,222,189,123,119,112,112,112,192,218,181,107, -117, 34,145,104, 97, 45,239,126,202,119,171, 93,116,114,114,154,120,240,224,193,191,198,140, 25, 3,103,103,231, 54, 85,125, 55, - 93, 36,106, 49, 98,201, 18, 42, 18, 8,232,241,223,126, 35,179, 79,156, 88,183,253,207, 63, 37, 29, 58,116, 0, 1, 16, 26, 22, - 38, 91,182,102,141,217,224,126,253,210,162,158, 63,199,153, 11, 23,180,105, 41, 41, 25,233,133,133, 51,222,212,236,162,154,194, -178,236,141,184,248, 56, 23,255, 54, 45,237, 67, 34,159,133,247,120,183,125,123,134, 97,152, 71, 79, 99,175,219,219, 91,200,175, - 92,185,172,103, 89,246,134,137,251,167, 79,199,142, 29,133,217,217,217, 80,169, 84, 72, 79, 79, 71, 98, 98, 34, 12, 6, 3, 52, -185,217,208,231,230,194,144,151, 3, 99, 97, 1,158,221,185, 13,111, 55, 23,233,153,226, 65,240,187,171,187,227,172, 40, 66, 85, - 62,146, 37, 53, 87, 66,170, 84,190,176, 56,181,137, 23,199,126, 22, 22, 22, 51,243,243,243, 79, 36, 38, 38, 46,210,233,116, 19, -151, 44, 89,210,106,225,194,133,118,179,102,205,178,152, 49, 99,198, 62,119,119,247,150, 49, 49, 49,149,154,214,130,130,130, 39, - 44,203,218, 1,112, 56,127,254, 60, 28, 28, 28,144,155,155, 91,188,221, 26,141,174,168,168, 72,150,153,153, 9,173, 86, 11,157, - 78, 7, 11, 11, 11,220,189,123, 55,155,101,217,191,170, 43,159, 69, 61,178, 72,171,143,156, 99,219, 68,145,164,103,173, 59,167, -101,113,217,243,126, 72, 90, 8,224,199, 94,245,234,109,213,115,151,159, 61,126,112,212,250,249,157,160,172,164,199,133, 94, 91, -143, 63,205,175,162, 30, 41, 33,132, 35,132,208,134, 13, 27, 34, 61, 61, 29, 2,129, 0,114,185, 28, 74,165, 18,141, 27, 55, 70, -124,124,124,173, 13, 22,203,178,101,230,234,236,141, 99,200, 44, 72,198,214,149,187,224,226,228,198, 0,176, 79, 76,137,239, 54, -106,218,160, 54,158, 29,173,151, 62,187,154, 93,233,184,182,164,164,164,123, 0, 44, 94,188,105,117,233, 98, 99, 99,115, 65,167, -211, 33, 38, 38, 6,103,206,156, 9, 72, 72, 72,184, 84,147,125,157,144,144,240,212,197,197,165,231, 7, 31,124,176,173,121,243, -230,245, 40,165,104,220,184, 49,250,245,235,135, 3, 7, 14, 32, 34, 34, 2,121,121,121,220,149, 43, 87,126, 79, 78, 78,174,209, -128, 28, 66, 8,161,148, 82,103,103,231, 70,125,250,244,185,186,126,253,122,235,140,140, 12,168,213,106, 20, 22, 22, 98,255,254, -253,232,212,169, 19,108,108,108,112,248,240, 97,182,180, 71,161, 50,115, 69, 41, 61,114,232,208,161,158, 94, 94, 94,120,248,240, - 33,206,158, 61, 11, 79, 79, 79,136, 68, 34,244,233,211,199,118,207,158, 61, 19,189,189,189, 87,137, 68,162,239,123,247,238, 13, -163,209,136,187,119,239, 38,199,198,198,230, 87,103,130, 43, 66,173, 86,131, 82, 10,131,193,176,134, 97,152,143,252,252,252,186, - 7, 7, 7,223,126, 91, 26,106, 87, 87,215,166, 34,145,104,178,181,181, 53, 50, 51, 50,144,203, 1, 89, 89, 89,160,148, 34,151, - 43, 14, 92, 41, 50,255,211,171,222,160, 65,131,227,106,181,122,118, 66, 66, 66,165,107,121,185,184,184,248,200,229,242, 41,125, -251,246, 29,246,222,123,239, 9, 12, 6, 3,142, 30, 61,138,245,235,215,163,103,207,158,168, 95,191, 62,102,204,152, 97,169,209, -104,102,157, 58,117,106,102,147, 38, 77, 78,229,231,231,127, 83,149, 38,143, 73, 6,171,216,100,185,184, 32,187,228,142,198,206, -198,198,102,189,209,104,236, 2,124, 7,115,161, 37, 30,134,220, 65, 86,166, 0, 90,181, 17, 28, 45, 54, 89, 38,117, 99,168,255, -130, 69, 67,138,188, 40, 2,131,193, 0, 71, 71, 71, 44, 91,182, 12,185,185,185,194, 81,163, 70,121, 44, 88,176,224,158, 78,167, - 67, 97, 97, 33,212,106, 53,212,106, 53,140, 70, 99,165, 6, 75, 44,213, 54,175,227,216, 0,249,234,214,144, 75, 37,200,202,211, - 22,155,171, 28, 13, 14,252,245, 49,180, 69,106, 24,245,122,176, 58, 3,148,142,253, 81,207,187, 11,128,232,102, 38,154,149,226, -191, 28, 11, 93,244, 89,232,162,207, 66,209,101, 14,142, 44, 25,246,210,137,111,218,228,196,196,196,196, 68, 23, 23,151,237, 33, - 33, 33,159,125,244,209, 71,184,120,241,226,183, 40,153, 89, 37,147,201,190,253,232,163,143, 16, 18, 18,130,200,200,200,237,149, -117,237,212, 20,137, 68, 82,168,211,233, 74,187,130,228,213,124,214,165,213,128, 1, 76,110, 72, 72,222,146, 11, 23,230,253,241, -199, 31,146,119, 58,117,130,193, 80,108,166, 61, 60, 60,208,189, 71, 15,233,142,189,123,149,234,156,156, 59,179, 39, 78,252,107, -195,240,225,121,183, 11, 10, 30,152, 88,159, 77, 74,186, 6, 65, 41,109, 82,217,107, 53,161,176,176,112,221,236, 89,211, 2,247, - 31, 56,226, 86,199,205,197,226,244,217, 75,247,165,102, 18,198,203,163,158, 32, 63, 63, 71,184,126,205,143,102, 5, 5, 5, 63, -153, 40,215,196,206,206, 14, 41, 41, 41,136,142,142,134, 86,171, 45,222,246,162, 66,232,178,115,160,203,205, 2,209,168, 33, 53, - 26,161,201, 72,133,187,151, 39,240,159, 25,134,213, 53, 96, 21, 26,172,210,191,102, 22, 22, 16, 43, 20, 16,136, 68, 38,143,193, -114,118,118,246,243,245,245,221,187,101,203, 22,241,212,169, 83,219,184,187,187,175, 79, 73, 73,137,117,117,117,237,186,114,229, -202,219,139, 23, 47,150, 14, 27, 54,172,209,230,205,155,135, 3,216, 92,233, 77,132, 70,179,247,248,241,227, 67,235,214,173,235, - 16, 22, 22, 6,141, 70, 83, 58,222, 12, 0,100,165,159,123,244,232,145, 90,163,209,164, 61,120,240, 32, 47, 54, 54, 86, 7, 19, -102,253,205, 91,155,116, 99,234, 32,215, 1,142, 78, 46, 55,101,102,238, 30,180, 32,164,255,212, 65,174, 43, 87,237, 75,208,156, -124,242, 36,127,238, 4,175,101,133,249,161, 19,172, 92, 11,126, 62,121,244,105,190, 41,135, 81,201,140, 65,216,218,218, 66, 40, - 20, 66, 36, 18,161,116, 44,146,163,163, 35,114,115,115,171,236, 34,172,172,241,206,203,203, 67,110,110, 46, 30, 63,127,136,204, -130,100,156,217,117, 3, 70,163, 17, 26,141,166,216,204, 58,186,226,220,238,219,230, 1, 3, 91,205,182,245, 33, 23, 51, 67,233, - 29, 83,143, 83,134, 97,166, 12, 24, 48, 0,122,189, 30,253,250,245,195,174, 93,187,166, 0,184, 84,211,227, 61, 49, 49,241, 38, - 33,164, 65,116,116,180,133,193, 96,120,191,111,223,190,127,244,238,221, 27, 55,110,220,192,249,243,231, 3,116, 58, 93,148,209, -104, 84, 59, 59, 59, 47,117,118,118,118, 32,132, 44,173,106,130, 71, 73, 42,134, 13, 77,155, 54,125,191, 75,151, 46,247,123,247, -238,221,108,253,250,245, 86,105,105,105,165,147, 26,144,144,144,128, 19, 39, 78, 36, 31, 61,122, 52,143,227, 56, 91,134, 97,142, -103,100,100,124, 83, 89,183,160, 94,175, 63,116,244,232,209,158, 94, 94, 94,184,116,233, 18,150, 44, 89,130,230,205,155,227,248, -241,227,112,119,119, 71,227,198,141, 97, 99, 99, 51, 57, 47, 47,175,221,138, 21, 43,122,251,250,250,226,208,161, 67, 72, 77, 77, -253,169,170,148, 13, 44,203, 86,107,176,222,125,247,221,209, 83,167, 78, 69,223,190,125,207,248,251,251,183,190,123,247,238,255, -124,154, 22,149, 74,181, 44, 48, 48,112,102,139, 22, 45,240,231,159,127, 66,227,215, 1,138,223,143,226, 65,159, 14,160, 0, 84, -191, 31, 1,165, 20,225,253,222, 1, 5,224,209,117, 32,102,206,156,217,187,127,255,254,117, 80,201,240, 8,149, 74,245,195, 39, -159,124, 50,237,211, 79, 63, 69,112,112, 48, 54,111,222,140,123,247,238,149,181,121, 6,131, 1,145,145,145,136,140,140,132,179, -179, 51,250,244,233, 67,198,140, 25,211,171, 87,175, 94,246, 0,252,193,243,186, 6,171, 44, 92,108,103,109,109, 29,254,243,207, - 63,219,182,110,221, 90,192,178, 44, 46, 6, 5, 97,254,119,211,208,171,199,103,208,115,150, 96,117, 98,112, 98,153,105,191, 40, -237,131,188, 40, 2, 78,220, 27, 58,157, 14, 95,236, 20,193,138,164, 97,205, 8, 71, 0, 32, 26,141,166,204, 88,149,222, 61, 85, - 21,193,202,207, 85,232, 13, 6,138,164,180, 88, 36, 36,135,195, 66,233, 6, 42,112, 67, 90, 86, 17, 8, 28,193,106,163, 96, 52, - 20, 27, 32,173, 58, 1, 69, 58,242, 90, 21,102,204,122,117, 54,176,145, 53,125, 76, 37,165,116,237,142, 29, 59,134,174, 90,181, - 74,250,222,123,239,249, 56, 59, 59,119, 7,128, 65,131, 6,249, 88, 88, 88, 96,199,142, 29, 90, 74,233,218, 55, 24,225,249,192, -223,223, 31, 89, 89, 89,136,137,137,185, 94,229,182,233,116,182, 74, 7, 7, 65,218,197,139,134,172,252,252, 58,157, 74,204, 21, -195, 48,200,206,206,198,243,231,207,161, 84, 40,240, 32, 34, 66,250,227,184,113, 59, 26,251,248, 48,165, 51, 12, 77,225,232,209, -163,230, 0,218, 86,247, 90, 77, 72, 79, 79, 47,116,114,114, 26,249,237,236,217,135,126,250,233, 39,203,212,180,212, 40,169, 68, -194, 42,149, 50,213,228,201,227,133,121,121,121, 67, 51, 50, 50, 10, 76,213,203,206,206,198,179,103,207, 96,102,102, 6,177, 72, - 4, 78, 93, 4, 99, 97, 1, 52, 89,233, 16,232,117,144, 24,141,176,145, 75,225,230,232,136, 58,246,118,166,117,221, 93, 60, 83, - 54,160,189,124,183,224,169,246,141, 32, 85, 42, 32, 85, 42,209,225,112,241, 16, 54,177, 88, 12,172,217, 98, 74, 55,142,157, 74, -165,250,107,253,250,245,226,204,204, 76,132,135,135,223,143,137,137,201,181,177,177, 49, 23,137, 68,220,227,199,143,207, 61,124, -248,176,143,167,167, 39, 40,165,213,205,254,250,241,224,193,131,221, 58,118,236,200,122,120,120, 40,210,210,210,234,228,230,230, -146,228,228, 23,199, 48,223,185,115, 71, 22, 23, 23, 87,200,113,220, 33, 20,231,193,170,246,192,159, 58,200, 85,118, 61, 4,147, - 58,247,112,111,110, 97,231,131, 44, 54,164,249,205,251,201,147,166, 14,114, 93,183,106, 95,130,198,140,104,255, 32,198,120, 55, -161, 76,179,205,196,243,135,122,123,123,131, 82,138,219,183,111,227,234,213,171,184,124,249, 50, 98, 99, 99,203, 62, 99,105,105, -137,179,103,207,162, 75,151, 46, 38, 31, 71, 69, 69, 69,112,118,118,134,181,181, 53, 14, 94,220,142,173, 43,119,149, 13,116, 47, - 37, 35, 35, 3,114,185, 28,139,191, 94,165, 28, 53, 99,224,247, 0,186,155,162,237,230,230,230,217,161, 67,135,247, 28, 29, 29, -145,157,157, 13, 7, 7, 7,180,106,213,170,175,163,163,163, 71,106,106,106,173,186,178,116, 58,221,248, 46, 93,186, 44,250,250, -235,175,193,178, 44, 62,254,248, 99, 60,123,246,108,239,211,167, 79,215,212,173, 91,119,210,132, 9, 19, 28,237,236,236, 48,126, -252,120, 5,128, 1, 85, 24,172,165, 43, 86,172, 24, 26, 24, 24,200, 24, 12,134,119,206,159, 63,143,152,152, 24,232,116, 58,176, - 44,139,152,152, 24,204,155, 55, 47, 57, 47, 47,175,115, 66, 66,194,147,234,202,149,146,146, 50,237,240,225,195,189, 27, 54,108, -136,211,167, 79, 99,236,216,177,199, 45, 44, 44,154,250,248,248,212,169, 83,167, 14,254,250,235, 47,152,153,153,193,217,217,217, -113,214,172, 89,125,122,244,232,129,115,231,206, 97,225,194,133,199,156,156,156,126,172,206, 4, 11,133, 66, 24, 12, 47,222,208, - 10, 4, 2,220,187,119, 15,239,190,251, 46,102,206,156, 9, 0, 56,119,238,156, 69,247,238,221, 31, 4, 4, 4, 88, 4, 5, 5, -105,241, 63,140, 66,161, 24,249,251,239,191, 35, 58, 58, 26, 87,174, 92, 65, 70, 70, 6,116, 58, 29,114, 74,172,168,180, 36,146, - 69, 93,234,162,253,180,217, 24,210,103, 0,146,147,147,193, 48,140, 93, 21, 55,124,195,102,207,158,141,147, 39, 79, 98,249,242, -229,200,205,205,173,240,115,102,102,102,104,213,170, 21, 90,182,108,137,103,207,158, 1,128, 29,120,222,156,193,178,182,182, 94, -179, 97,195, 6,219, 14, 29, 58, 8, 74,204, 14, 90,183,106,133,225, 35, 71,226,236,193, 99,112,104,216, 19, 68,167, 4, 43,151, -152, 22,193,178,216,134, 76, 67, 38,100, 98, 25,164, 58, 29, 56,206, 12,161, 9,154, 50,215,172, 86,171, 81,106,178, 10, 11, 11, -161, 80, 40,170, 54, 16, 58, 73,112,228, 51,214, 45, 55,255, 30,110,134,108,135, 65,103, 64,189,134,179,161, 54,216, 66, 97,255, - 25, 52,186,191, 96,204, 41,158,185, 43,177, 8, 64, 74, 74, 6, 0, 98,106,196,229,213,147, 60,255,213,193,238,156,209,244,188, -171, 73, 73, 73,153, 42,149,106,243,245,235,215, 39, 15, 24, 48, 0,103,207,158,157, 13, 0, 3, 6, 12,192,245,235,215,241,236, -217,179,205, 73, 73, 21,207,160,170, 41, 46, 46, 46,195, 59,119,238, 60,161,117,235,214, 56,118,236, 24,140, 70,227, 9, 83,190, - 39, 16,137, 40, 33, 4,165, 51,156,178,178,179,241,232,209, 35,100,101,102,194,104, 52,162, 72,173,102,155, 54,106,148, 71, 57, -206,188, 38,229, 41, 63, 99,176,162, 89,132,165,175,213,116, 59, 83, 82, 82, 98,235,213,171, 23, 87, 84, 84,104,111,109,101,157, - 47,145, 72,140,121,249,249,185,209, 81, 15,117,166, 52, 10,229,136,140,136,136,104,150,144,144,128,184,184, 56,176,133,249, 16, -104,117, 96,180, 69,232,218,190, 29,204, 64, 33, 3, 7, 17,103,128, 72, 32, 66,126,241,108,187,200,106,143,249,114, 13, 66,169, -185, 34,132, 64,166, 84, 66,162, 84, 64,106,174,124, 33,162,101,202,196, 47, 51, 51,179,157,155, 55,111,118,118,114,114,194,170, - 85,171,224,236,236,220, 56, 48, 48,176,168,115,231,206,102,118,118,118,104,216,176, 33,252,253,253,113,241,226, 69, 16, 66,158, - 84,115,156,179,132,144,238, 87,174, 92,153,118,237,218,181, 65, 42,149,138,124,250,233,167,232,217,179, 39,100, 50, 25,138,138, -138,144,157,157,141,227,199,143, 19,163,209,232, 91, 98,240,234,186,187,187,239, 34,132, 36, 60,127,254,252,163,151, 53,183,175, -246, 81,165,101,113,159, 57, 58,185,244,239,220,195,189,249,187, 61, 2,225,217,224, 93,188,219, 35, 14, 0,150,217, 8, 99, 62, - 94, 57,167,217, 33, 59, 55,155,223,206,156, 58, 59,175, 99,231,119,191,157, 53,198,122,209,178,205,217,213,142,151, 35,132,148, - 53,182, 12,195, 84, 24,165, 18, 10,133,101,179,205,170,189,105,226,140, 9, 61, 71,180, 43,123,110, 96, 13,118, 46, 78,110, 76, -105,228, 10, 0,114,115,115, 17, 31, 31, 15,131,193, 0, 91, 91, 91, 24, 12,122,159, 26,116, 63, 78, 26, 60,120, 48,209,104, 52, -152, 54,109, 26,126,248,225, 7,244,235,215,143,220,186,117,107, 18,128, 41,181,136,104,172,156, 48, 97,194,180,145, 35, 71, 34, - 39, 39, 7, 23, 46, 92, 64,151, 46, 93,176,113,227, 70,251, 11, 23, 46, 44,105,223,190, 61, 4, 2, 1,206,158, 61, 11,189, 94, -255,168,202, 6, 64, 40,124, 63, 48, 48,144,137,143,143,135, 88, 44,134,191,191, 63, 18, 18, 18, 80, 84, 84,132,180,180, 52, 44, - 88,176, 32, 37, 55, 55, 55, 32, 49, 49,241,137, 9,251,133,233,208,161,195,228,250,245,235,227,194,133, 11, 24, 55,110,220, 73, -133, 66, 49, 32, 51, 51,115,140, 70,163, 89, 55,120,240, 96, 52,110,220, 24, 81, 81, 81,120,239,189,247,208,170, 85, 43, 92,184, -112, 1, 51,102,204, 56, 46,151,203, 63,172, 38, 15,214,227,160,160,160,102,254,254,254, 40, 42, 42, 66, 94, 94, 30, 68, 34, 17, -172,172,172, 16, 25, 25,137, 6, 13, 26, 96,230,204,153, 88,181,106, 21,166, 78,157,202,117,239,222,157,213,235,245, 98,137, 68, -242, 63,223, 72, 23, 22, 22,210,228,228,100, 88, 88, 88, 96,223,190,125, 8, 59,119, 26, 39,190,252, 12,178, 57, 43, 65, 41, 69, -252,162, 89,232, 58, 99, 14,218,222,127,138,228,228,100,108,219,182, 13, 12,195,148,205,136,173,172,109,203,205,205, 69,203,150, - 45,113,251,246,109,108,219,182, 13,171, 87,175, 46,139,214,138, 68, 34, 4, 4, 4,160, 91,183,110,120,252,248, 49, 54,111,222, - 12, 11, 11, 11,222, 49,189,105,131,197,113,220,187,173, 90,181, 18, 20, 20, 20, 64,163,209, 32, 37, 37, 5, 49, 49, 49, 48,147, -155, 33, 62, 35, 17, 45,124,245, 72,225,242, 16,121, 63,220, 72, 4,162,123,213,221,129,232,116, 58,232,116, 58,132,134,134, 22, - 79,125,111,176,180,108,160,167,193, 96,128, 86,171,133, 90,173,198,133, 11, 23,168, 84, 42,133, 66,161, 32, 85,245,189,115,172, -246,228,133,171,247,123, 15,235,223, 69,114, 54,104, 43, 12, 58, 14,121, 26, 11, 20,168,181, 40,208,136,160,149,246, 0, 33, 87, -192, 8,164,104,223,178, 62, 46, 92,141,210, 24, 13,122,147,210, 21,128, 51, 66,232,236, 3, 54, 57,244, 63, 47,189, 52,155, 80, - 44, 87,130, 51,214,108, 86,176,153,153,217,198,157, 59,119,142,108,215,174,157,121, 96, 96, 96, 3, 0,144, 74,165,220,206,157, - 59,243,205,204,204, 54,214,116, 39,190,156,189,221,217,217,185,163, 68, 34,153,216,183,111,223,142, 35, 71,142, 68,120,120, 56, -254,252,243,207,251, 42,149,170,202, 49, 51, 2,137, 36,179, 32, 45,205, 74,233,225, 33,180, 50, 55, 79, 58,125,250,180,251, 59, -157, 59, 35, 54, 38, 6, 89, 89, 89, 80,171,213,136,136,140,164, 98,134,137, 35, 22, 22,204,163,144, 16, 70, 32,145,100,214,160, -156,145,213,205, 34,172,109, 52, 75, 97, 70,234,205,153, 57,198, 83,163,209, 52,203,203,203, 99, 69, 34,145, 72, 46,161,177, 53, -209, 48, 24, 12,199,174, 92,185,242, 65,135, 14, 29,164, 81,161,247,192,230,230, 66,151,155, 13, 49,103,132,141,111, 11, 8,244, - 90, 64,103,128, 75, 19, 10, 77,142, 28,215,238, 61, 53, 24, 12,134, 99,166, 26, 44, 70, 32,120,113,220,149,133, 18, 82,115,115, - 72,148,202, 23, 94, 39,213,244,107, 57, 58, 58,202,123,245,234,213,213,215,183, 56,167,214,202,149, 43,161,215,235, 37, 6,131, -161,108, 38, 92, 65, 65, 1,246,239,223,143,237,219,183, 95,179,180,180,252,221,132,155, 9,214,213,213,117, 34,199,113, 14, 44, -203,234,237,237,237,197,123,247,238,133, 76, 38, 3,195, 48,104,217,178, 37,100, 50,153, 86,165, 82,233, 75,202, 96, 88,181,106, -149,240,179,207, 62, 19, 87,164,215,168,121,227,233,158,172,117,103,153,153,187,135,133,157, 15, 60, 27,188, 11, 0,232,214,103, - 20, 60,235,215, 65, 94, 70,168,135, 70, 29,211, 95, 44,204,182, 14, 95,151, 24, 97,246, 94,179,145,133,105, 65,143, 1,252, 98, -210,169,201,113, 8, 12, 12, 68,143, 30, 61,202,186, 3, 29, 28, 28,160,211,233, 96, 52, 26,107, 52,150,173, 52,137,232,130, 5, -132,193, 60,224,247, 54, 22, 41, 0,236,203,155,171,184,184, 56,196,197,197,149,221, 8,114,212,180, 20, 42, 42,149,202,204,211, -211,115, 68,179,102,205,112,254,252,121,132,134,134, 38, 6, 5, 5,185,180,110,221, 26,174,174,174, 35, 85, 42,213,236,164,164, - 36,147, 19, 42,219,219,219, 43, 58,117,234,244,229,200,145, 35,241,240,225, 67,204,154, 53, 43, 51, 57, 57,249,208,209,163, 71, - 63,255,234,171,175,152,206,157, 59, 35, 45, 45, 13, 27, 55,110, 52,222,190,125,251, 7,107,107,235,133,213,236,247,135, 73, 73, - 73,174, 26,141, 6, 89, 89, 89, 96, 89, 22, 69, 69, 69, 56,117,234, 20, 78,159, 62,157,154,147,147, 19,144,148,148, 20,109, 74, -217,234,214,173,107,238,239,239,239,248,248,241, 99,236,218,181, 11,122,189,126, 78, 76, 76,140,222,210,210,114,199,146, 37, 75, -230, 89, 90, 90,218, 4, 6, 6,162,244,184,253,235,175,191, 48,127,254,252,227,102,102,102, 3, 34, 34, 34,244,213,200,247,255, -254,251,239,191,183,179,179,251,104,232,208,161,140,191,191, 63,238,222,189, 11,163,209,136,174, 93,187,150,153,171, 83,167, 78, -237, 60,117,234,212, 64, 0, 98,165, 82, 41,251, 95,143, 94,149,162,209,104, 16, 21, 21, 5, 71, 71, 71,212,111,221, 14, 51, 31, - 60,199,149,235, 55, 64, 41, 69,199,240,231, 40, 40, 40,196,239,191,255,142,224,224, 96, 8, 4, 2,120,121,121, 85,171,169,215, -235, 17, 29, 29,141,244,244,116,244,235,215, 15,195,134, 13,195,138, 21, 43,160,215,235,241,237,183,223, 34, 43, 43, 11, 91,182, -108, 65,116,116, 52,132, 66, 33,148, 74, 37,239,152,222,180,193, 42,233,102, 2,199,113, 72, 76, 76,196,221,187,119,241,252,249, -115, 40, 20, 10,168, 89, 35,183,241,220, 85,142, 16,113, 2, 71,233, 53,202, 22,103, 17,175,202,137, 27, 12, 6, 34, 20, 10,113, -253,250,117, 60,125,250, 20,230,245,105,153,185, 42,141, 96, 21, 21, 21, 65, 36, 18, 21,220,184,113, 35, 38, 56, 56,216, 83, 40, - 20,234, 42,211, 76,179,206,222,118,246,252,185,233,126, 45,189, 27,116,235, 60, 31,199,142,205, 67,118,110, 30,138,116, 34,228, -171,245, 40, 84, 83,184, 88, 52, 64,107, 31, 31,164,103,233,240, 56, 60, 56, 33, 67,108, 83,109, 31,140,129, 50,185, 59,151,141, -181,124,127,216, 56,152,185,191, 3,109,248, 62,112,249, 41,224,242,139,187, 77, 36, 10, 11,152,219,185,161,160, 72,131,171, 15, -158,194, 64,153, 92, 83, 43,253,201,147, 39,249, 42,149,106,221,212,169, 83,151,223,184,113, 93, 1, 0,247,238,221, 43, 76, 74, - 74, 90,148,148,148,148, 95,147, 29, 88, 46,123, 59, 81, 40, 20,143,235,215,175,111,120,239,189,247,108,251,247,239, 15, 59, 59, - 59,132,132,132, 96,217,178,101, 33,133,133,133, 67, 98, 98, 98, 12,213,116, 59, 36, 6, 31, 62,108, 17,240,233,167, 86,179,250, -245, 91, 54,126,252,248,159, 22, 46, 92, 40,174, 87,191, 62, 56,163, 17, 17, 17, 17,116,199,142, 29,236, 47,115,231,174,148, 40, - 20,194,219, 71,142,136, 88,173, 54,241,191,125, 16,187,186,186,118,238,221,179,115,147, 31, 86,173,131, 70, 93,128, 91,215,143, - 35, 59, 59, 29,155,183, 28,108,226,234,234,218,217,212,193,196, 9, 9, 9,123, 14, 28, 56, 48,205,199,187,137,175,151,155, 27, -194, 98,159, 67,194, 25, 33,102, 89, 8,244, 90, 48,172, 6,110,205, 40, 8, 99,142,148,148,124,108, 60,125,225, 65, 66, 66,194, -158,106, 35,137,189,222,199,144,216, 92, 16, 66,112,166,147, 55,100,230, 74, 72, 20, 10,180, 63,112,169,204, 84,197, 46,253, 26, - 34,133, 18,214,173,223,169,182,156,169,169,169, 69,245,235,215,191,251,240,225,195, 86,141, 26, 53,194,130, 5, 11, 16, 31, 31, - 15, 74, 41,210,210,210, 52,233,233,233,137,153,153,153, 49,132,144, 67, 73, 73, 73, 91, 77, 93,138,132,227, 56,135,163, 71,143, - 2,128, 24, 0,206,159, 63, 15,149, 74, 5, 75, 75, 75,228,229,229,225,211, 79, 63,149,126,247,221,119, 0,128,187,119,239,138, -204,204,204, 42,213, 10, 11,142,252, 33, 39,159,102,211,130,144,254, 89,108, 72,243,119,123,196,163, 91,159,145, 56,123,236,119, - 92, 56,125, 14, 54,194,152,231, 80,228,159,204,120,158,145,151, 80,216, 96, 83, 19,191,207, 5,201,133,167, 55, 77,234,103, 45, -112,118,230,246,205,218, 80,121,226,222,210, 59,112,129, 64, 80, 54, 6,171,116, 64,123, 77,205, 85,121,230,205,163, 28, 1, 33, - 94, 98,113,104, 98, 74,124, 55,149,163, 43, 82, 83, 83, 17, 31, 31,143,184,184, 56,196,199,199,163,126,253,250,120, 30,251, 20, - 18,137,248,158,137, 81,240,161,125,251,246, 53,215,233,116, 56,124,248, 48, 75, 8,233,115,244,232,209,187, 45, 90,180, 16,118, -233,210,197,252,247,223,127, 31, 10, 96,107, 77,238, 37,148, 74,165, 88,175,215,227,143, 63,254, 64, 66, 66, 66,231,148,148,148, - 72,149, 74,181,105,236,216,177, 27,154, 52,105, 82, 63, 50, 50,242,177, 90,173, 30,159,148,148, 20, 90,157, 88, 78, 78,206,168, -158, 61,123,238,227, 56,174,110,199,142, 29, 21,243,230,205,179,120,244,232, 17,220,221,221, 65, 41, 13,171,201, 82, 83,177,177, -177,249, 87,175, 94, 77,109,218,180,169,163,179,179, 51,196, 98,241, 50,103,103,231, 69, 74,165,242,135, 46, 93,186,216,236,216, -177, 3,167, 79,159,134, 72, 36,194,211,167, 79,147, 30, 62,124,184,198,201,201,105,173, 41, 25,220,131,131,131,159, 1, 24,210, -186,117,235,249,171, 87,175,158,195, 48,204, 39,103,206,156,129, 72, 36, 2,128, 50,115,229,225,225, 49,124,223,190,125,195,222, -178,118,218,160,211,233, 96,107,107,139,244,244,116,164,165,165,161, 78,157, 58,104,215,174, 29, 12, 6, 3,142, 28, 59,142, 43, - 87,174,128, 82, 10, 59, 59, 59, 88, 90, 90,226,254,253,251, 0, 80,213,236, 97,131, 94,175,135,141,141, 13,114,114,114,112,255, -254,125, 56, 56, 56, 96,234,212,169,208,233,116,216,187,119, 47,238,221,187, 7,134, 97,224,224,224, 0,115,115,115, 83, 52,121, -106,106,176, 4, 2,193,197,139, 23, 47, 14,244,241,241, 17, 70, 71, 71, 35, 58,186,248,102, 70,173, 86,179, 66, 1,246,167,134, - 30, 30, 82, 69,227, 31, 88, 62, 87,134, 68, 34,217, 56,112,224,192,241,163, 70,141,194,196,137, 19, 65, 8,193,111,247,116,136, -139,227, 96, 48, 24,144,154,154,138,176,176, 48,218,170, 85, 43,194,113,156, 62, 32, 32,224,139,224,224,224,214, 2,129, 32,175, - 50, 77, 26, 20,196, 58, 54,239,255,225,207, 27,183, 94, 26, 49, 98,132, 77,223,126, 63,227, 94,100, 4,114,139,236, 1, 74,225, - 98,175, 68,235,134, 95, 35, 45, 83,131,211, 39,143,101,115,172,230, 67,250, 96,183,161,170,114, 2, 64,186, 80,237,176,105,251, -129,149,187,247, 29,252, 98,244,200,161,178,128,192, 79, 33,206, 8, 3,155, 20, 12, 23,239,142,160, 66, 51,220, 14, 14, 65,104, -116,188,166, 72, 47,216,154, 39, 86, 79,175, 78,179, 60,217,217,217, 39, 82, 82,146,127, 46,157, 28,192, 48, 68, 33,145, 72, 79, - 84, 99,166, 2, 95,202, 11,244,114,134,248,134, 75,151, 46, 77,179,181,181,229,194,195,195,177,113,227, 70,227,221,187,119, 15, -112, 28, 55, 39, 35, 35,163,168, 58, 77,123,131,225,254,206, 89,179,188, 91, 15, 24, 64,251,127,241,133,134,145,201,198, 47, 91, -181,106,118,102,110,174, 11, 0,216, 88, 89,197,111,158, 63,127, 97,175,222,189,243,195,175, 94, 53,187,126,248,176,153,132,101, -131,171, 43,231,155,160, 42,205,132,132,132, 75, 13,234,213,193, 31, 91, 87, 65,175,215, 34, 57,177, 56,112,149,145,153,139,170, -204,213, 43,199, 82,241, 44,170, 1,171,215,172,189, 57,238,211, 79,156,222,233, 26,136,184,251,247,160,207, 74, 7, 49,176, 16, - 17, 33, 10,211,228, 72, 75, 45,192,210, 19,231,210,212, 26,205,128,151, 19, 57, 86, 86,206,178,110, 65, 11,115, 72, 20,197,227, -174,202, 71,173,196,230, 22, 16, 41,148, 16,136,197, 21, 13,134, 15,172, 32,167,220,135,163, 71,143, 14, 61,113,226,132,245,144, - 33, 67,240,254,251,239,135,228,228,228,116,201,202,202,202,175,109,125, 50, 12,147,214,187,119,111, 7,157, 78,199, 14, 30, 60, - 88,152,145,145,129,210, 41,246, 5, 5, 5, 56,121,242, 36, 26, 53, 42,158,157, 31, 30, 30,142,166, 77,155, 86,170,249,249,140, -176, 68, 0, 11,167, 14,114, 93,121,243,126,242, 36, 0,203, 60,235,187,225,194,233,115,184,114,225,250,172,182,205,184,117,189, -135,181,250, 94,222,229,163,233, 77,252, 62, 23, 40, 45,156,177,237,224, 1, 65,100,240, 47,139,139,138,194,234, 1,248,186,178, -114,150,118, 95,191,156,146, 65,173, 86,155,100,174,170, 58,150, 40, 40,181,203, 37,179, 71, 77, 27,212,230,236,174, 91,230, 74, -165, 18,122,189, 30,148, 82,212,171, 87, 15, 66,145, 16,191, 30,250,169, 48, 39, 39, 99,174, 41,154, 10,133, 98, 98, 64, 64, 0, -158, 60,121,130,208,208,208, 3, 73, 73, 73,161, 42,149,234,192,179,103,207, 6,183,105,211, 6,123,246,236,153, 88,153,193,170, - 76,179, 52, 99, 61,165, 20, 70,163, 49, 11, 0,146,146,146,238,155, 18,253,125, 89,179, 36, 89,104, 7, 0,104,210,164, 73,188, -163,163,163,197,253,251,247,225,236,236, 12,189, 94,223,166, 38,199, 18,165,148, 83,169, 84,107,111,223,190,189,180,101,203,150, -248,248,227,143,187,221,189,123,183, 91,139, 22, 45,224,229,229,133,107,215,174,225,204,153, 51,127,114, 28, 55, 54, 57, 57, 89, - 83, 85, 18,212,202,182,253,246,237,219,209, 0, 62,245,243,243,251, 72, 40, 20,194,194,194, 66,144,152,152, 40, 56,115,230, 12, - 0,140,222,183,111,159,177, 54,251,253,239,184, 46,189, 41, 77, 66,200,183,195,135, 15,223, 52,102,204, 24, 89,155, 54,109, 94, -136,168,158, 56,113, 2, 28,199,193,214,214, 22,182,182,182,136,142,142,198,161, 67,135,116,185,185,185,107,196, 98,241,178,170, - 52, 63,253,244,211, 77, 99,198,140,145,181,110,221, 26,185,185,185,101,230,237,216,177, 99, 32,132,192,206,206, 14,182,182,182, -120,252,248, 49, 14, 29, 58,164,201,206,206, 94,165,211,233, 86,252,157,219,254,175, 51, 88, 89, 89, 89,147,191,249,230,155, 46, - 95,124,241,133,109, 97, 97,161,192,214,214, 22, 41, 41, 41,236,169, 83,167,178,242,243,243, 39,215,228,199,174, 95,191, 62,161, - 79,159, 62,107,126,251,237,183, 45, 91,183,110,237, 60,120,240, 96,124,250,222,123, 24,215, 86, 14,173, 86, 11, 66, 8, 78,159, - 62,253,232,226,197,139,158, 98,177, 88, 59,111,222, 60, 14,192,205,106,239,232,195, 14, 69, 56, 54,239,223,121,221, 79, 27,246, -251,250,183,173,235,238,225, 46,109,239,106, 9,189,193,136,212,180, 76, 92,186, 30,174,141,138,184,151, 72,245,250, 15,211, 34, -170,207,226, 14, 0, 17, 17, 84, 15, 96,178,183,183,197,130, 21,155,118,108,220,190,107,127,255,209,195, 6, 8,125, 91,116,197, -179,235,135,112,249,230, 5, 54, 91, 67, 15,229,139, 4,227, 34,162,243,178,107, 90,241, 90,173, 86, 71, 8, 40,254,147,125,157, -106,181, 90, 93,109,206,199,242, 79,126,253,245, 87, 36, 39, 39,107, 99, 99, 99,119, 83, 74, 55, 37, 39, 39,155,156, 62, 97, 29, -165,186, 1,132,156,155,211,177, 99,207, 57,167, 79,203, 6,125,249,165,174,255,135, 31, 78,135, 86,171,135, 68, 66,133, 10, 5, - 3,169, 84, 20,126,245,170,217,218,113,227,108,136, 78,119,246,119, 74, 77, 14,193,255, 29,179, 8,203, 69,176, 48,226,243,175, -160, 46, 23,193,186,113, 39, 10, 53,137, 96, 1, 64,114,114,114,156,179,179,115,219, 69,107,215, 29,236,213,182,117,147, 6, 42, -103,169,173,135, 59,148, 78, 78,200,202,200,192,173,123, 79, 12, 63,157,187,244, 64,173,209, 12, 48, 53, 47, 12,199,113,101,179, -220,188,191,156, 9, 70, 32, 40, 51, 2,165, 73, 3, 45,252, 59,130, 8,133, 48, 82, 10,189, 94, 95,237, 32,172,164,164,164, 4, - 23, 23,151, 15,191,252,242,203,243,127,252,241, 7, 19, 16, 16,208,242,175,191,254,122,173, 69,115, 19, 18, 18, 92, 75,186,181, -242, 44, 44, 44,132, 35, 71,142,132,193, 96, 64, 81, 81, 17,114,115,115,145,153,153,169,157, 50,101,138, 20, 0,196, 98,177,161, -103,207,158,213, 94, 63, 86,237, 75,208, 76, 29,228,186,206, 70, 24,243,113, 94, 70,168,135,141, 48,230,121,219,102,220,186, 85, -251, 18, 52, 11,190,178, 90,148, 17,115, 41, 42,185,240,244,166,109, 7, 15, 8,134,247,255,208,232,170,124, 60, 75,230, 64,247, -191,219,183,218, 70,232,149,164,162,181,141, 92,189, 76,198, 3, 26,226,217,209,122,105,151, 65,173,103, 47,154,182, 74,233,224, - 96, 15,214,200,226,121,220, 51,252,118,112,125, 97,190, 54,123,113,102, 4,189,107,138,150,167,167,167,135, 64, 32,192,145, 35, - 71, 0, 96,125,201,203,235, 79,157, 58, 53,120,200,144, 33,168, 91,183,174,183,187,187,187,180,170, 52, 26, 21, 69,239, 12, 6, - 3,222,244,186,214,132,144,167, 27, 55,110,116,177,177,177, 33, 87,174, 92, 97, 25,134, 57, 90, 83, 13, 39, 39,167, 31,143, 31, - 63,222,137, 82,218,211,215,215, 23,117,235,214, 45,185,158, 70,224,202,149, 43,187, 18, 19, 19, 71,188,161,197,157, 41, 33, 4, -121,121,121,165, 3,237,244, 74,165,242,173, 92, 52, 58, 49, 49,113,187,163,163,227,233,249,243,231,127, 87,175, 94,189,177,163, - 71,143, 22, 52,108,216, 16,185,185,185,176,176,176,128, 74,165, 66, 98, 98, 34,182,111,223,110, 76, 75, 75,251,141, 97,152, 5, - 73, 73, 73, 73,181,213,180,182,182,134,179,179, 51, 18, 18, 18, 74, 53,183, 24, 12,134,133,233,233,233,169,224,121,179, 6, 43, - 37, 37, 37,195,201,201,169,233,175,191,254,186,182, 56, 77, 67,113, 84, 43, 63, 63,127,114, 74,241,136,241, 26,113,236,216,177, - 39, 0, 2,250,244,233, 83,111,255,254,253, 91,118,238,220,217,185, 95,191,126, 24, 60,120, 48, 88,150, 69,175, 94,189, 70,188, - 28,181, 50,133,212,176, 67, 17, 36, 32,160,233,221, 91,151, 63, 13,185,123,179, 15,165,212, 7, 0, 33, 12,243,159,197,158, 35, -106,190,216,115, 68, 68, 94, 54,128,143,124, 93, 45,188, 22,175,223,177,213, 76,200,117, 84,179,204, 85,181,150,249, 34, 36, 33, -175,214, 11,140,150,100, 94, 95,206, 48,100, 70,241,115,211,150,134,169, 68, 99, 38, 0, 8,133,162, 61,119,239,222,157, 29, 27, - 27,155,104,202, 12,175,138, 56, 72,105,220,167,132,156,153,238,227,211,181,207,148, 41, 34,191,238,221,205,109,220,220, 56, 74, -169,241,249,173, 91,228,198,145, 35,162, 27, 71,142,200, 12, 90,237,249,125,148,214,104, 6,212,223, 49,139,176, 52,130, 85,207, -203,245,204,192, 1,189,187,123,121,168, 0, 0, 79,159, 39, 33, 35, 43,247, 76, 77,115, 13,149,154, 44, 66,136,255, 95, 44, 59, - 88, 36, 18,245, 33, 37,169, 24,104, 45, 22,123, 54, 26,141, 9,109,219, 86,178,121,243,150, 85,102,200, 82, 77,188,240, 6,169, - 84,170, 79,218,183,111,191, 44, 41, 41,233, 96,122,122,122,225, 27,186, 46,244,218,185,115,231, 9,142,227,204, 94,138,112,229, - 37, 37, 37,153,151, 52,164,117, 79,157, 58,181,139, 16, 82,173,129, 95,181, 47, 65,179,114, 78,179, 67, 26,117, 76,127,162, 44, - 58,180,106,109,241,172,150,121,171,115,114, 1,252, 50,169,191, 13, 23, 25,252,203, 10, 23,139,199, 51,214, 30,202,250,173, 58, - 61,134, 97, 30,183,105,211,166,204,104, 85, 83,255, 73,181,169,128,103, 87,179,151,217,250,144,139,159,205, 28,248,189, 78,175, -111,193, 16, 80,145, 88,124, 63, 39, 39, 99,174,169,230,170,196, 88,252, 60,109,218,180,201, 79,158, 60,217, 85,154,243, 46, 41, - 41,233,186, 74,165,250, 49, 46, 46,110, 66,124,124,252,250,248,248,120,147,205,149, 82,169,212,168,213,106,142,101, 89, 70,171, -213, 66, 34,145,232,223, 84, 99, 80, 88, 88, 56,116,195,134, 13,191, 26, 12,134, 38,132,144,163, 57, 57, 57, 53,206,122, 27, 28, - 28,108,240,246,246,238,119,252,248,241,201, 15, 30, 60,152,234,232,232,232,152,154,154, 26, 27, 23, 23,183, 52, 37, 37,229,151, - 55,100,174, 16, 28, 28, 44,245,243,243,211,150,171, 23,139,183,101,188, 85,133,237, 91,106,106, 58,128,137,174,174,174,107,166, - 79,159,190,184, 69,139, 22, 3, 71,141, 26, 69,228,114, 57,246,238,221,139,152,152,152, 67,148,210,217, 53,233,210,173, 76,211, -204,204, 12,123,247,238,165, 49, 49, 49,251, 24,134,153,147,148,148,244,175, 88, 72,251,239,128,188,233,187,160,154,134, 79,251, -244,233, 83, 47, 35, 35, 99,139, 86,171,125, 7, 64, 97,104,104,168,249,127, 59, 36, 91, 21, 1,222,246,138,160,136,234, 27, 50, - 83, 53, 95, 30,160, 94, 27,205,154,104,152,170, 89,217, 98,207,156, 86,155,100,203,178,119,215, 81,170, 51, 85,211,197,197,101, - 33, 76,204, 23, 85, 66,100, 98, 98,226,119,181,169,207, 6, 13, 26,208,232,232,104, 80, 74,201,155,220,239,127,199,177,244,111, -210,220,190,218, 71,213,168,121,227,233, 97,193,145, 63,148,116, 31,150,177, 96,146,141,121,199,119, 3,230, 94,189, 16,244,253, -188,117, 47,118,113,190, 13,219, 78, 8, 97, 42, 50, 22,165,201, 61,107,170, 89,167, 78,157, 77,190,190,190, 95,132,132,132,252, - 26, 23, 23, 55,250,159,186,237,132, 16, 82,183,110, 93, 73, 77,162,115,252,121,100,154,166,147,147,147, 63,195, 48,115, 75,110, - 56, 22, 39, 36, 36,220,126,131,154, 70, 74,233,162,228,228,228,144,255,239,109,255,215, 69,176,254,110, 74, 35, 90,239,191,255, -190,131, 64, 32,248,199, 47,210,105,138,185,170,105, 20,234,159,160,241, 50, 37, 6,234,250,155,208,122,217, 44,253,157, 60,126, -252,152,240,167,245, 63,143, 79,191, 10, 77, 2, 48,197,191,130,212, 84, 37,166,106,122,151,247,223,206,109,175, 44,106, 83,219, -133,152,227,226,226,198,170, 84,170,169, 53,153,125,248, 95,218,110, 10, 64,203, 31,253,111,158,148,148,148,187, 0,250,254,211, - 53,121,131,245, 15,225,175,191,254, 74,227,119, 7, 15, 15, 15, 79,245,252,211,205, 21, 15, 15, 79,241, 0,233,192, 74,238, 62, - 76, 14,253, 17, 66, 2,107,113,119,115,142,215,228, 53,121, 77, 94,147,215,228, 53,121,205,127,151,230,191,134,210, 89, 76,127, -199, 3, 64, 32,175,201,107,242,154,188, 38,175,201,107,242,154,188,230,191,237,193,240, 22,147,231,239,230,167, 1,196,229,167, - 1,196,229,239,250, 60, 15, 15, 15, 15, 15,207, 63, 13,225,219,182, 65,254,254,254,222,148,210,161,132,144,129, 37, 17,186,253, -132,144,157,119,239,222, 53, 41, 3,173,153,153, 89,170, 70,163,113, 0, 0,153, 76,150,166,209,104,156,202, 71, 75,129, 87,150, -200,160,197, 63, 83,249,128, 85, 79, 79,207, 84,173, 86,235, 96, 66, 52,241, 18, 33,228, 50,195, 48,151,106,147, 94,224,221,119, -223, 29, 33, 16, 8, 22, 3,128,209,104,252,246,194,133, 11,127,252, 93,245, 76, 8,105,227,166,114,250, 93,111,208,179,169,233, - 89,115, 41,165, 71, 42,250,220,134,190,100,169,144, 96,122,201,255, 43,199, 31,165, 85, 78,253,174,233,231,171, 40,159,191, 72, - 36,154,232,232,232,216, 43, 33, 33,225, 46,128, 25,148,210,106,143, 1, 43, 23,239, 79, 69, 34,209, 48,131,209,232, 37, 18, 8, -158, 26, 12,134, 29, 57,137, 17,219,249, 75, 5, 15, 15, 15, 15,207,223,102,176,218, 53,176,109, 72,168,126,186,136,208, 78, 6, - 74,174, 80, 34, 94,121,227,113,102,212,235, 20, 64,165, 82,185, 17, 66, 2, 40,165, 77, 24,134, 9,227, 56,238, 76, 77, 23, 59, -246,243,243,115, 3,240, 49,128, 33,109,219,182,109, 54,110,220, 56,212,175, 95, 31, 26,141, 6,183,111,223,158,181, 99,199,142, - 89,126,126,126, 15, 0,236, 2,176, 59, 56, 56, 56,190, 50, 45,141, 70,227, 80,234,149, 8, 33, 14, 3, 7, 14,188, 93,222, 84, -149, 44, 46, 75, 40,165, 55, 8, 33,215,141, 70,227,205,125,251,246,197, 55, 38,164,205, 24, 15,241,254,201,207,116,174, 47,107, -106,181, 90,135, 99, 83, 39,128, 82, 14,154,204, 12,116, 88,182,182,236,189,147, 61,219,130, 49, 26, 32,145,138, 47, 5, 28,189, -113, 25,192,165,146, 71,141, 17, 8, 4,139, 79,157, 58,229, 76, 41, 69,143, 30, 61, 22, 3,248, 91, 12, 22, 33, 68,218,214,191, -197,197,163, 7,118,201, 10,178, 82,209,179,223,224, 29,132,144, 17,148,210, 3, 47,152,165,222,196,145, 8, 49,125,220,146,157, - 2, 0,216, 48,123,232,140, 53, 61,200,186, 41,167,105,138,139,139, 75, 23, 74,233,140, 18,189, 21,137,137,137, 23, 55,244, 38, -142, 16, 96,230,184, 37, 59, 9, 0,108,156, 61,116,250,134,222,100,237,248, 19, 53,155, 37, 73, 8, 25, 63, 98,196,136,117,139, - 23, 47, 22, 56, 59, 59, 35, 49, 49,177,167,183,183,119, 67, 66,136, 55,165,180,210,193,193, 54,117,124,246,244,236,217,203,243, -227, 65, 3,228,246,118,214, 72, 72,206,176,248,115,199,206, 49, 54,117,124,122,101,197,133, 14,230, 47, 23, 60, 60, 60, 60, 60, -111,204, 96, 53,107,102,105,101,166,166, 83,205,196,244,227,158,109,188, 61,250,118,107, 79, 60, 61, 61, 17,245, 40,202,235,226, -181, 59, 35,187, 52, 54,127,174,214,147,221,106, 51,178,234,193,131,170,215, 15, 27,225, 75, 12, 6, 99,241,111,138,133, 48, 94, - 72,119, 61, 20, 24, 24,232, 49,106,212, 40,248,250,250,226,238,221,187, 93,246,237,219, 55,217,205,205,237,142,193, 96, 56, 33, -149, 74,131,170,203,161,226,231,231,183,204,197,197,101,198,180,105,211,136,191,191, 63,164, 82,105,217,123, 74,165, 18, 93,187, -118, 69,215,174, 93,145,154,154,218,236,226,197,139,205,118,238,220,185,212,207,207,111, 69,112,112,240, 44, 83, 42,104,238,220, -185,254, 21,188,124,138, 16,242,132,101,217,123, 62, 62, 62,241,141, 8,169, 63,182,119,251,179,227, 59, 52, 80, 84, 17,157,194, -157,197,197,171,107,148, 55, 88,180, 40, 31, 34, 11,243, 75, 34,165,242, 21,115,213,132,144, 22,109,173,153,223,127,201, 50,250, -212,192,100, 33, 62, 62, 30,150,150,150,102, 1, 1, 1,201,132,144,249, 23, 47, 94,220,242,134,143,155, 54,243,167,143, 23,103, -199,132, 34,229,225, 13, 76, 29,212, 81, 62,229,167,191,190, 7,112,160,106,227,195, 48,127, 60,181,155, 53, 5,152,204,113,220, -220,200,200,200,206, 0,208,164, 73, 19, 9,128,139,219,162,173,123,143,104,146, 91,235, 52, 11,132, 16,177, 64, 32,248,121,219, -182,109,159,127,250,233,167,136,141,141,197,213,171, 87,161, 84, 42,177,112,225, 66,247,105,211,166, 45, 5, 48,185,178,200, 85, -143,158,189, 61, 55,254, 48,199, 59, 63, 43, 87,187,249,231,189,119, 84,205, 26, 49, 83, 38, 77, 48,215,177,122, 39, 43, 23,239, - 79,249, 72, 22, 15, 15, 15, 15,207, 27, 49, 88,157,234, 43,110,247,247,171,231,215, 55,176, 61,211,160,145, 55,196, 50,121,217, -123,205, 91,250,162,121, 75, 95, 50,122,100,190,231,253,251,247,231,156,186,116,107,118,167,250,138,224, 43,209,133,173, 43,211, - 51, 24, 33,220,185,115, 39, 0,224,199,175,135, 10,126,190, 18,229, 81,126,193,216,206,157, 59,163,115,231,206,204,210,165, 75, -219, 92,188,120,177,205,238,221,187,245, 46, 46, 46,107, 18, 19, 19,247, 85, 81,204, 25,251,246,237, 35, 2,129, 0, 2,129,160, -210, 15, 57, 58, 58,162, 91,183,110,112,118,118, 38, 95,127,253,245, 12, 0, 21, 26, 44,153, 76,150, 70, 8,113, 0, 0, 27, 27, - 27,227,252,249,243,239, 81, 90,214, 3, 72, 41,165, 55, 24,134,185,201,113,220,173, 35, 71,142, 36, 52, 37,196,161,143, 95,163, - 43,227, 63, 25, 40,167,251,215, 84,106, 14,180, 57, 89, 21,190, 46, 81,200, 47, 73, 20,138,203, 82, 51,179, 23,204, 85, 83, 66, - 92,219, 54,242, 56,179,225,171,161,230, 38, 70,241, 26,118,233,210, 69,102, 52, 26, 81, 88, 88,136,141, 27, 55, 90,154,153,153, - 89,246,234,213,107, 30,128, 50,131,229, 77, 72,243, 15, 85,130,209,243, 19,217, 9,181, 48, 48, 86,157,218,249,199,252,180,108, -158,133,127,219, 78,120,124,241, 79,100,101,229, 35, 55,167, 0, 47,103,253, 6,128,241, 39,104,234,134,190,100,229,134,111,134, -206, 36, 12, 67, 90,244,159,129, 30, 13,233, 36,149, 74, 21, 78, 8, 17,149, 46, 31, 67, 8, 17,186,186,186,170, 26, 54,108,185, -178, 65,143,198,216,248,237, 39,160,197,139, 52,174, 52, 53,122, 69, 8,113, 48, 55, 55, 63,114,230,204,153, 54,173, 90,181,194, -205,155, 55,241,236,217, 51,140, 31, 63, 94, 55, 97,194, 4,241,240,225,195,201,212,169, 83,191, 36,132,236,167,148, 94,123,249, -251, 34,145,104,216, 71, 3, 62,144, 20,228,228,105,116, 90,189,206,198,206,138,211, 22,106,138, 50,178,243, 52,159, 12, 29,166, -187,119, 55,120, 24,128, 87, 12,214,235,212, 39, 15, 15, 15, 15,207,191,212, 96,201, 4,198, 86,243,119,221,135, 49,235, 9,104, -110, 28,104, 97,202, 43,159,145,219,185,161,113, 59, 71,200,173,236,153,176,135,171, 91,189, 20,181,169,114,170,102,169,185,218, - 60, 84,213,180, 48, 59, 89, 12, 0, 10,107,103,253,232, 29,137,225,173, 90,181,130,189,189,189,248,250,245,235, 83, 1,236,171, - 66,147,232,194,130,241,176, 79,123,212,123,152, 5,185, 92, 14,137, 68,242,194, 7,162,162,162,112,249,242,101,196,197,197,193, -203,203, 11,120,105, 28, 85,121, 77,181, 90,237,216,179,103,207,160, 21, 43, 86,116,254,241,199, 31, 31,108,219,182,173,115,101, -221, 74,222,132, 40, 90,184, 59, 5,125,255,245, 24,107,122,242,119,166, 40, 51, 13,226, 74,202,217,126,241, 42,180, 95,188, 10, - 0,176,215,219, 25, 50, 11,115,200,148,202, 75,129,167,239,190, 18,185,242, 35,196,194,203,217,246,194,250,249,147, 21,184,176, - 71,130, 47, 22, 86, 89,159,126,126,126, 13, 3, 2, 2,174, 47, 90,180,200, 42, 62, 62, 30,215,174, 93,131,187,187, 59,138,138, -138, 94, 88,175,204,155, 16,199,214,141,234,158,153, 61,109,164, 37,128, 9,166,236,163, 23, 76,136, 64,240,253, 15,243,103, 88, - 88, 74, 41,158, 92, 59,132,103, 79,158,227,118,196,115,195,246,179,161, 70,157,193, 56,170,162,250, 28,127,148,126, 51,173,171, -244,247,187,249, 94, 71,251,116,153,208, 96,209, 16, 71,232,245,250,173,233,233,233, 24, 61,122, 52, 56,142, 67,199,142, 29, 59, - 80, 74, 19, 39, 77,154, 4, 47, 47, 47,108, 57, 29, 85, 36,204,186, 21,176,227,122,222, 93, 83,142, 37, 66, 72,179,186,117,235, -158,185,120,241,162,163,139,139, 11,130,130,130,144,146,146, 2, 39, 39, 39, 76,152, 48, 65,178,108,217,178,109,121,121,121,131, - 22, 47, 94, 44,123,240,224,193,110, 66,136, 91,137,105, 46,211, 52,114, 70,149,167,187, 74,121, 96,247,233,251,214,230,114,212, -241,114, 19, 11,148, 22, 70, 10, 82, 84,199,217, 94,108,228,140,170, 10,246,255,107,213,167,169,240,154,188, 38,175,201,107,254, - 27, 52,255, 85, 6,171, 20,253,179, 32, 72,188, 7, 0, 92, 83,208,236, 39,224,242, 18, 65,229, 14, 40,228,204,144,145, 20,139, -135, 87,246,129,234,171,207,123, 39, 18,128,157, 51, 97,168,208, 74, 6, 72,204,237,245,249,249,249, 80, 40, 20, 40,204, 78, 22, - 79,251,161, 44,178, 37,190,120,241, 34,130,131,131,161, 82,169, 76, 42, 35,213, 21,247, 34,234,116, 58,232,116, 58,164,244,110, - 13, 69,219,119,144,253,201, 4,156, 63,127, 30,105,105,105, 16,139,197,144, 72, 36, 96,217,234,147,197, 51, 37,171,198,150, 70, -173, 42,250, 76, 0, 33, 66, 87, 27,229,209, 13,243, 38,123, 48, 55,142,137,212,113,209, 72,210, 24, 97,101, 66,125, 74,149, 10, - 72,228,102,151, 36, 74, 69, 69,230, 74,164, 80,202,142,254,190,104,170,147, 32,228,188, 76, 29, 29, 90,102,218,202,211,173, 91, -183, 49, 0,230, 81, 74,115, 2, 2, 2, 28, 23, 47, 94,108,157,152,152,136,136,136, 8,236,221,187, 55,157, 45,222, 80, 66, 41, - 93, 0, 0,237, 8,145,213,177,183, 58,189,254,187,201,230,184,184, 71,130,207,106,158, 92,221,178, 73,223,227, 31, 14, 31, 55, - 97,221,228,190, 40,204, 87, 99,231,217, 16,156, 10,126,242, 62,128,171,148,210, 74, 51,220,255,120, 94, 27,237,226,226,210,245, -139, 47,190,184,119,240,224, 65,187, 31,126,248, 1, 70,163, 17, 44,203,130,101,217,178,255,141, 70, 35,118,237,218,133,171,119, - 35, 38, 37, 37,229,153,180,222, 27, 33, 68,229,225,225,113,238,214,173, 91,246,114,185, 28,103,207,158, 69, 78, 78, 78, 89,228, -106,196,136, 17, 36, 39, 39,231,227,141, 27, 55,126, 24, 19, 19,243,195,149, 43, 87, 50, 1, 8, 0,176, 47,238,115,225, 19,150, - 53, 52,118,110, 82, 95, 56,168,111,167, 78, 5,153,161, 80,218,250,224,198,253, 39, 71,179,179,115,212, 12, 35,124, 82,254,243, -111,162, 62,121,120,120,120,120,254,229, 6, 75,115,127, 7,180, 97,123, 32,246,234, 2, 73,211,193, 16,185,182, 67,124, 88, 16, -238,157,248, 17, 9,225, 87, 65, 57, 35, 28,221,171, 95,106,238,143, 16, 42, 82,169, 84,193, 73, 73, 73, 8, 9, 9,193,147, 39, - 79, 32,147,201, 94,249,220,249,243,231, 1, 0, 78, 78, 78, 38,109,132,196,191, 61,220,238, 39, 35,190,133, 51, 0,192,237,126, - 50, 0, 96,233,236,217, 16,139,197, 16,139,197,101,139,194,154, 98,176, 72,201,135,185,226,110, 42, 90,209,251,254, 82,209,206, -221,243, 38,182,150,198,132, 73,180, 15,110, 32, 73,203,209,163,169,198,227,222,166, 24, 44,185,252,146, 68,169,188, 44, 86, 40, - 94, 48, 87, 0, 64, 69,162,237,127, 46,152,232,163, 72,125,170,208,220, 57,143,100, 13,167,183,168, 88,102,193,201,147, 39, 29, -132, 66,161,147,209,104, 68, 92, 92, 28,194,195,195,177,118,237,218,212,252,252,252,128,224,224,224,168,114,229,101, 90,153, 73, -246,110, 95, 56,217, 83, 24,122, 73,166,125,242,160, 66,211, 86, 21,246,205,251,247,120, 63,160,197,241, 49,159,124,139, 15,122, -119,199,240, 0,111,250, 60, 41, 75, 3,224, 44,165,212, 88,221,247, 19, 19, 19, 19, 93, 92, 92,186, 13, 24, 48, 96, 71,211,166, - 77,155, 80, 74,209,184,113, 99,244,235,215, 15, 7, 14, 28, 64, 68, 68, 4,242,243,243,245, 87,174, 92, 89,147,148,148,244,155, - 41,101, 34,132,200,173,173,173, 79, 93,184,112,193, 94, 46,151,227,204,153, 51, 80,171,213,112,118,118,126, 33,114,181,116,233, - 82,217,243,231,207,215,159, 62,125,218, 29, 0, 83,209, 66,216,122, 86,187,229,183,109,187,215, 77,253,242, 11,151, 11, 55, 35, -206,107, 11,242, 45,235,214,141,207,179,183, 86,154, 47, 94,186,188,142,158,213,141,169,184, 62,131,106, 85,159, 60, 60, 60, 60, - 60,255,114,131, 85,218,197, 68, 57, 22,186,232,179,208, 69,159,133,162,203, 28, 28, 89, 50,236,133,207, 25,141,134, 90, 21, 64, -163,209, 64,172,180,213,255,248,245, 80, 49, 0,112, 34, 69,217,234,240, 28,103,218,194,235, 53, 89,210,171, 38, 6,171, 68,247, - 21,243,224, 33, 85, 94,218,242,213,160,182,182,198, 34,145,238,234, 81, 36,106, 57,246,135,104,125,209,157, 28,186, 98,118, 37, -154,199,186,181,134, 33, 59, 3, 50,115,197,165,158, 23, 31, 84, 56, 91,208, 67,102,113,126,239,212, 33, 29,157,196, 16,235,142, -239, 67,146,150,211,110,138, 49,252,182,182,146,109,166,148,226,217,179,103, 40, 42, 42,194,245,235,215,113,224,192,129,244,151, -205, 85, 73,121,131,126,157, 49,172,141, 69,126,138, 88,119,231, 28,146,180,156,182,161, 41,166,202,167,127, 7, 49, 67,206, 16, - 70, 96,214,187,147, 55,166,124,209, 31,171,127,253,139,213, 57,116,234,179,238,200,137,143, 10,180,250,217,166,152,171,114, 38, - 43, 20,128,183,187,187,187,148,101,217, 46,125,251,246, 61,209,187,119,111,220,184,113, 3,231,206,157,107,160,215,235,147, 1, - 64,165, 82, 45, 4,224,200, 48,204,138,132,132,132,167,149,236, 35, 70, 44, 22,239, 62,119,238, 92, 83,149, 74,133,115,231,206, - 65,173, 86, 99,220,184,113,186,137, 19, 39,138, 71,140, 24, 65,114,115,115,203, 34, 87,215,175, 95,207,172,204, 92, 1, 64, 94, -194,195,147,214,110, 77,219,119,233,220,174,127,131, 6,245, 45,158,230,231,165,201,229, 50,179,139,151,174,136,111,221,188,181, - 62, 47, 33,242,118,197,245,121,222,228,250,228,225,225,225,225,225, 13, 86,149, 24,179, 94,109,243,140,108,237,215,105,110, 55, -243,116,184,153,153, 25, 54,110,220, 8,185, 92, 94, 99,227, 84,116,242, 16,226,199, 15, 45,139, 92,149, 70,178,208,115,196,107, - 25, 44,142,227,174, 3,120,193,229, 41, 28, 27, 13,217,253, 73,183, 14,222,158, 46,140, 97,239, 90, 36, 20,177,154,121,143,244, -154,135,249,244,253,136, 10, 6, 79,151, 97,208, 65,166, 40,142, 92, 85,100,174,148, 78, 13, 63,220, 54,164, 75, 64,139, 70,245, - 24,118,207, 42, 36, 22, 25, 10,102, 69,234,245, 79, 11,233,193, 74, 76,229,188,238,221,187,207,179,181,181,149,173, 91,183,206, -178,110,221,186, 96, 89, 86,247,178,185, 82, 56, 54, 26,178,103, 68,207, 14, 13,157,172, 25,195,254,159, 16,175, 54, 22,173,125, -106,216,182,201, 4,115,101,103,169, 60,189,105,201,120, 51,185, 84, 4,141, 70,131,101, 27,246,227,204,181, 7,125,210,195, 14, -157, 6,112,186,182,251, 91,175,215,127, 30, 24, 24,184,122,250,244,233, 96, 89, 22, 31,127,252, 49, 98, 98, 98,206, 68, 71, 71, -175,117,117,117,253,122,252,248,241, 42,123,123,123,140, 29, 59, 86, 12, 96, 68, 37, 50,203,119,238,220,217,167, 69,139, 22,184, -116,233, 18,114,114,114,224,236,236,140,137, 19, 39, 74,150, 46, 93,186, 45, 47, 47,111,208,146, 37, 75,100,207,158, 61,171, 50, -114, 85,158, 28,154,187,232,151,213, 99,191,110,221,182, 3, 19, 29, 29,197,198,181,238,204,156, 63,119,226,114,182,131,116,219, - 11,245, 57,178, 87,141,235,147,135,135,135,135,135, 55, 88,213, 70,135,140,249,175, 14,118,231,140, 38, 7, 50, 76, 54, 78, 70, - 19, 53, 57,173,166, 58,195, 84, 35,131, 85, 50, 6,235, 20,165,244, 5,131,101,229,212,168,243,156,153,147,215,116,252,176, 39, -147,250, 69, 59,228, 20,104,181, 51, 34, 88, 46,161,168, 26,115, 5,128, 49,234, 47,137, 44, 44, 46,139, 95,154, 45, 8, 0,102, -142,245, 91,207,250,234,203, 13,239, 14,233, 75,210,199,117, 68,118,142, 90,251,117, 56, 75, 18,213,116, 80, 4,165, 23, 43,210, - 59,127,254,252,102, 0,155, 3, 2, 2, 82, 21, 10, 5, 10, 10, 10, 94,169,215,210,242,118,248,176, 39,147,250,121, 27,100, 21, -234,181, 51,194, 89, 36,169,185,221,213,153, 43,123, 43,243,211,155, 22,143,151, 39, 37,196, 64, 44, 22, 67,169, 84,226,236,213, - 48,164, 63, 56,124,250,117, 14, 56, 87, 87,215,249,147, 38, 77,154, 55, 98,196, 8,100,103,103,227,236,217,179,120,247,221,119, -241,243,207, 63,215,189,112,225,194,234,246,237,219, 67, 32, 16,224,236,217,179, 48, 24, 12,143, 43,217,159,253, 71,143, 30,253, -245,135, 31,126,136,219,183,111, 35, 57, 57,249,133,200, 85, 78, 78,206,199, 27, 54,108,248,240,249,243,231,213, 70,174,202,227, - 2,180,246,172,215, 82,252,205,220, 31,161, 45, 74, 19,166, 39,222,188,116,254, 44,189, 81, 55, 43, 75, 14, 32,183,182,245,201, -195,195,195,195,195, 27,172, 10,220,139, 17, 66,103, 31,176,201,161,255,121,233,165,217,132, 98,185, 18,156,177,122,227, 50,194, -151, 24, 70,214,131,112, 85, 47, 6, 98,165,173,190,221,204,211,225,149,125, 86,169, 84,154,218, 69,104, 20,247,254, 80, 80,175, -199, 7,120,218,220, 9,212,160, 47,139,100, 97,246,236, 23, 76,150, 88, 44,134, 78,167, 3, 42,232,246,123,137, 91,132,144, 24, - 0, 55, 40,165,212,175,161,215,247, 50,133, 98,164,191, 79, 61,187, 41,227, 63, 23, 61, 79,211,226, 66,199,111,114,246, 47,159, -169,140,167,202, 9,177, 52,231, 90, 53,134,242, 82,239, 43, 15, 95,137, 92,249, 54,244,250, 86, 38,151,125,209,182, 89, 67,167, - 89, 83,199,139,158,167,106,201,133,214, 51,242, 14,172,152, 33,127, 6,243,175,227,105,246, 69, 19,182,127, 94,239,222,189,231, - 81, 74, 41,199,113,115, 1,160,124,121,167, 78,252, 66,244, 52, 69,131,243, 29,191,205, 62,176,124,166,121, 60,170, 46,175,189, - 79,255, 14,142,214, 22,167, 55, 45,153, 32, 79, 78,140,133, 84, 42,133,185,185, 57,226, 83,115, 33, 18, 10,212,175,115,176,185, -187,187, 75,219,180,105, 51,115,248,240,225,136,140,140,196,172, 89,179,146,147,146,146, 14, 30, 57,114,100,220,212,169, 83,133, -157, 59,119, 70, 90, 90, 26, 54,110,220,104,184,125,251,246,146,148,148,148,149, 21, 30,180, 66,225,231,223,127,255, 61, 77, 74, - 74, 34,207,158, 61,131,179,179, 51,190,252,242, 75,201,146, 37, 75,202,198, 92,213, 36,114, 85, 74, 66, 66,194,165, 6,245,234, -224,253,147,107,192, 26,180,151,114, 50,227, 46, 63,124,154,125,201, 70, 34,153,214,209,207,167, 86,245,201,195,195,195,195,195, - 27,172, 87, 48, 80, 38,119,231,178,177,150,239, 15, 27, 7, 51,247,119,160, 13,223, 7, 46, 63, 5, 92,126,177,129,145, 40, 44, - 96,110,231,134,130, 34, 13,174, 62,120, 10, 3,101,114,171,212, 51, 66,184,232,231,255,204, 22,180,178,178, 66,110,110,238, 11, -145, 23,185, 92, 14,149, 74,133,188,188, 60,236,223,191, 31,180,154,200, 16,165,244,251,225,195,135,127, 55,126,252,120,166,222, -144, 81, 40,184,121,229,229,104, 20,204,204,204, 32,147,201,144,144,144,128, 71,143, 30,113,148,210,239,171,137,120,221, 98, 89, -246,254,238,221,187, 19, 26,120,185,246, 12,104,213,122,210,236,111,102,153, 71, 92, 57,131,185, 75,214,115,245,253,123,228, 46, -219,117, 56, 63, 87, 89,167,107, 81,210,195,123,213, 85, 50, 33,228,213, 36,162,158,117,222,109,231,219,114,250,220,185,223, 90, -132, 95, 57,139,239, 86,108,162, 13, 90, 4,230,174, 56,112, 36, 47, 67,238,222, 93,157,250,159, 49, 63, 85, 17, 20, 20,180, 25, -192,230,210,231, 47,151,119,214,194,181, 92,195, 86, 61,179,151,237, 58, 80,152,103, 94, 39,176,170,242, 58,120, 15,104,239,230, -108,115,250,167, 69, 99,229, 41,137,113,144, 74,165, 80, 42,149,136, 75,206,193,188, 53,123, 11,245, 28,215,243, 53,143, 55,169, - 66,161,144,234,245,122,252,241,199, 31, 72, 76, 76,108,151,156,156, 28,231,228,228,180,105,236,216,177,235,154, 52,105,210,248, -209,163, 71,143, 11, 10, 10, 38,164,164,164, 60,172, 76,196,202,202,170,157,189,189, 61,185,113,227, 6,198,142, 29,171,251,242, -203, 47,197,195,135, 15, 39,217,217,217,181,138, 92,149,139,174,117,238,247, 94,123,116,232, 54,238,146, 78,147,115,249,249,195, -109,151, 24,122, 77,230,215,210,167, 86,245,201,195,195,195,195,195, 27,172, 10, 73, 23,170, 29, 54,109, 63,176,114,247,190,131, - 95,140, 30, 57, 84, 22, 16,248, 41,196, 25, 97, 96,147,130,225,226,221, 17, 84,104,134,219,119, 67, 16,250, 36, 94, 83,164, 23, -108,205, 19,171,167,191,100, 44, 2,171,202,149,145,155,155, 11,119,119,119,236, 26,215,168,169, 54, 47, 77, 92, 7, 0,147,104, -169,191, 16,213, 59,252,242,229,203, 5, 0,182, 54,104,208, 96, 95, 85,154, 33, 33, 33, 11, 90,182,108,121,228,155,111,190, 89, -218,160, 65,131,158,163, 23,254, 12,241,148,225, 80, 71,132, 66, 30, 48, 8, 54, 54, 54,200,204,204,196,237,219,183,145,159,159, -127,138, 82,250,205,189,123,247,194,170,210,164,148,222,244,241,241, 73,168, 83,167,142,149,131,210,236,183,113,159, 13, 55,143, - 13,189,137,212,168,251,184,118, 53, 42,123,231,129, 35,137,121,185,233,159, 85,213,184,150,215,100, 24,230, 5,115,213,176,161, -157, 82, 33,181,222, 62, 97,244, 40,139,184,176,219, 72,139,186,135, 43,215, 30,103,239,218,125, 40, 61, 51, 51,117,100,101,230, -170,186,250,172,168,188, 55,175, 60,202,222,189,239, 80, 66,126, 97,246,231, 21,149,183,188,166, 82, 33,154,126,228,143, 69,242, -164,132,216, 50,115, 21,155,156,141,239,214,236, 46, 84,235, 12, 61,211, 67, 15,153, 20,169,169,170,156, 28,199,129,101, 89, 80, - 74, 33,145, 72,242, 0,160,196, 76,117, 53, 85, 51, 35, 35, 35, 40, 38, 38,166,159, 82,169, 44,139, 92,229,230,230, 14, 90,182, -108, 89,141, 34, 87, 47,151, 51, 33, 33,225, 82, 61, 79,215,229,201,131, 7,105,157,157,237, 47, 29, 61,121, 39,204, 65,105,246, -176,182,245,249,166,224, 53,121, 77, 94,147,215,252, 55,104,254,171, 12, 86, 68, 4,213, 3,152,236,237,109,177, 96,197,166, 29, - 27,183,239,218,223,127,244,176, 1, 66,223, 22, 93,241,236,250, 33, 92,190,121,129,205,214,208, 67,249, 34,193,184,136,232,188, -236,234,126, 76, 36, 0, 59,116,232, 80, 33, 0, 72,132, 96, 87,245,233, 19,212,180,105,211,142,109, 13,105,226,121,235,138, 35, - 91, 11, 38, 13, 21, 7,221, 14,218, 39,149, 74, 55, 63,123,246, 44,207,148,141, 40, 49, 76,189, 90,181,106,245,206,215, 95,127, -189,188,183,135,107,235,254,237,187, 64, 36, 18,225,246,237,219,200,204,204,188,205, 48,204,204,144,144,144,203,166,232,133,133, -133,101, 52,173,239, 62,217,198, 76, 60,125,194,208,254,246,233, 79, 34,144, 16, 25, 2, 0,208,106,213,134,228,168, 75, 45,106, - 82,201,165, 11, 55,123,123,123,139,141,218,130, 17, 50,161,197,220,113, 31,247,115,200,124,254, 16,241,225,197,233,158,180,154, - 34,125,124,212,133,198,181,217,137,238,238,238, 82,133, 8, 99, 42, 44,175, 78, 99, 72,121, 28,217,210, 20,157, 34,173,110,201, -130,213,219,187, 47,154, 62, 82,106, 97, 97,129,224, 7,209,152,187,106, 87,141,204, 85,117, 80, 74, 97, 48, 24,106, 52,243,179, - 2,102,182,104,209,162,209,226,197,139, 27,148,140,229,122,173,200, 85,121,158, 60, 75,152, 21, 16, 16,224, 29,253, 40,184,139, -141,153,120,199,235,212, 39, 15, 15, 15, 15, 15,111,176, 80,181,209,202,203, 6,240,145,175,171,133,215,226,245, 59,182,154, 9, -185,142,106,150,185,170,214, 50, 95,132, 36,228, 61, 53,245,199,254, 8,161,162,151, 95,243,246,246, 86, 68, 11, 81, 80,250, 60, - 58, 11, 72, 74, 74, 90, 81,155,141,185,115,231,206,101, 0,109,124,125,125,251,159, 32,100, 54,240, 20,148,210, 37, 33, 33, 33, -135,106,162, 99, 46,196,131,142,222, 94, 46,157,124,155,202, 4, 70, 53, 18, 34,159, 32,171, 80,131,179,225,177, 57, 12,101,126, -175,109,101, 51,250,162,251,157,188,235,213,121,199,175,169, 92, 68,116, 72,136, 8, 70,174, 90,135, 51,225,177,185, 32,164,214, - 3,165,223, 84,121, 83, 66, 15,223,177,247,233, 31, 72, 8, 57, 55,123,226, 16,233,188, 85,187,223,168,185,178,177,177, 41, 74, - 73, 73,201,212,104, 52,182,169,169,169, 58, 27, 27,155,162, 90,154,180,104, 66, 72,243, 41, 83,166, 44,252,250,235,175,167, 47, - 95,190, 92, 92,155, 49, 87,149,145,157, 24,123,232,157,166,111,126,255,243,240,240,240,240,240, 6,171, 66, 74,204, 84, 64,128, -183,189,226,234,163,244,194, 55, 81,128,136,136,136,194, 17,190,164, 44,178, 37, 18,128,125, 93,205, 18, 67,117,168,214, 2, 12, -201,191,249, 56,182,224,214,227,216, 2,112,148,114,148,106, 25, 6,241,133,122,253,146,168,167, 9,181,159, 69, 71,136,241, 78, -116,156,250,238,147,120, 13,229, 56,202, 81,170, 35, 4, 41, 6, 3,183,228,193,211,152, 35,255,132,242,166,135, 30,186,230,228, - 61,160,211,181, 91, 15,166, 22, 22,234,215,167, 71, 28,186,254,166, 14,182,224,224, 96,131,179,179,243,176,190,125,251,142,226, - 56,110, 83, 98, 98,162,161,182, 90,148, 82, 29,128,153,132,144,131, 97, 97, 97,123,175, 95,191,158,252, 38,204,213,223,186,255, -121,120,120,120,120,120,131, 85, 21, 65, 17,111,198, 92,149, 82, 81,100,235,191, 73,216,227,231,126,127,135,238,131,199,207,155, -253, 47,148, 55, 37,226,224, 93, 0, 31,255, 29,101, 77, 78, 78, 62, 3,224,204,155,210,163,148,222, 33,132,120, 0, 16,188, 17, -115,245, 55,238,127, 30, 30, 30, 30, 30,222, 96,241,240,252,207, 64,139, 7,116,177,124, 77,240,240,240,240,240,252, 83, 32, 0, - 2, 43,105,180, 76,158, 29, 64, 8, 9,172, 69,163,120,142,215,228, 53,121, 77, 94,243, 45,209, 76,171, 66,243, 65, 53,154,149, - 69,182, 29,254,135,234,179,101, 37,154,203,171,209,156, 89,197,219,247,248,227,243,237,212,252, 55,221,253,255,109, 15, 0,129, -188, 38,175,201,107,242,154,255, 2,205,102,124,125,190, 81,205,153,124,125,254,251, 52,223,182, 7,195, 91, 76, 30, 30, 30, 30, -158,191,173,155,132, 16, 41, 33, 68, 90,219,247,121,120,254, 87,169,241, 24,172,214,173, 91,215, 7,128,219,183,111, 71,255,141, - 39,228, 68,103,103,231,209, 62, 62, 62, 77,196, 98, 49,147,159,159,191,224,194,133, 11,243, 95,254,220, 59, 77, 69,119, 5, 12, - 92,203,125, 19, 32, 2,128, 97, 96,164, 72,184,124,191,200,159,223,197,255, 93,156,157,157, 79,203,100,178,186, 28,199,129,229, - 40,140,172,177,248,175,145,131,193, 72,161,215,105, 98,181,133,185, 61,106,165,221,114, 64, 29,214, 72,151, 1,220, 6, 2,102, - 28, 5,183,145, 80,102, 28,101,176,129,112, 24, 11,161, 97, 37, 88,209,215, 66,177,240,219,164,224,125,241,111, 67,125,238,223, -191, 95,240, 58,223, 31, 56,112, 96,133,203, 68,249,250,250, 30,147,201,100,245, 42,251, 94, 81, 81, 81,242,253,251,247,187,188, -205,199,170,147,147,211, 59, 12,195,252, 4,160,233, 75,111, 61, 4, 48, 57, 41, 41,233,252,235,254, 70,107,185, 92,104, 39, 16, -140, 17, 17, 50, 3, 0, 12,148,174,200, 48, 26, 55,223, 46, 42,250,199,140, 33,116,112,112,184, 44, 16, 8, 27, 20, 22, 21, 22, -230,231,229,121,153,155, 91, 60, 53,147,203, 21, 70,214,248, 56, 35, 35,237,157, 26, 94,203,199, 3, 88, 89,242,255,116, 74,233, -134,154,188,207,195,243, 86, 27, 44, 63, 63,191,134, 0, 58, 19, 66, 58, 83, 74,223,105,220,184,177, 99, 81, 81, 17,252,252,252, - 82, 9, 33,151, 41,165,151, 0, 92, 10, 14, 14,142,122, 19, 5, 18, 8, 4, 63,172, 93,187,118,218,151, 95,126, 89,182, 72,115, -104,104,104,197,159,101,224,122,241,232, 57,135, 59, 97, 81,104, 21, 56,176,196, 96, 49, 64, 97, 50,186,116,107, 93,171,223,183, -177,177, 49,119,112,112, 88, 64, 8, 25,196, 48, 76,181,141, 25,199,113, 70, 74,233,190,180,180,180,121, 89, 89, 89,249, 53,249, -173, 86,254, 62,134, 98, 71, 88, 17,212,120,231,110,104,149,179, 43, 27, 55,110,124, 87, 32, 16,184,150, 92,156, 94,190,176, 85, -248,191,209,104, 76, 8, 15, 15,247, 55,181, 46,100,114,249,116,194, 8, 3, 65,185,226, 36,168,132,121, 72, 57,246,156,166,168, -104,165, 41,219, 43,149, 74,235, 6,135,220,107, 16, 17,245, 20, 94, 30,117,160,211,179,208,233, 89, 28, 57,119, 27, 45, 26,123, -160,111,239,110,181, 62, 86,140,148, 44,152, 59,121, 88,151,197,107,119,182,250,118,242, 80,197,226,181, 59, 91,125, 59,101,168, -114,241,186,157,254,223, 78, 25,166, 92,180,110,135,255,156, 41,195, 44, 22,175,219,169, 7,240, 89,109,126,227,179,230,117, 11, - 25, 35, 91,225,221, 53, 39, 16,106,127, 13,139, 85,252, 55, 78,220, 81,163, 70, 53, 44, 44, 44,140, 24,213,167,245,247, 77,220, - 29, 43, 28,255,147,147,153,234,240,248,193,237,185, 66,153,194,251,131,233,191, 85,121,126,138,197, 98,207,203,151, 47, 55,224, - 56, 14, 70,163, 17, 44,203,150,253,213,233,116,248,240,195, 15,223,200,132, 24,127,127,255, 81,148,210,197,197,135, 37, 89,116, -247,238,221,245,175,113, 35,166, 20, 10,133, 95, 73, 36,146,206, 44,203, 54, 1, 0,145, 72, 20,169,213,106, 47,177, 44,187,154, - 82, 90, 80, 19, 61,134, 97,214,220,185,115,199, 91,169, 84, 66,175,215,151, 45, 12, 47, 16, 8, 26,183,105,211,230,103, 0, 13, - 94,119,251,237, 4,130, 49,237, 59,118, 92, 59,106,202, 20, 65,246,157, 59,248,105,235,214, 53,200,206, 6,128,159,171,251,174, -171,171,235, 93, 66,136,107, 77,126,143, 82,154,144,144,144,224, 95,179,107,176,176, 65,108,124,146, 67, 93, 55, 21, 0, 64, 46, -151, 43,238, 60,120,238,224,215,212,163,198,145, 43, 0, 43, 41,165,102, 37,245,187,182,125,251,246,237, 8, 33, 44, 0,202,113, - 28, 67, 8, 25,194,113,156,176,228,243, 43, 9, 33,191, 81, 74,181,124,211,204,243, 86, 27, 44, 63, 63,191, 19, 0, 58, 55,110, -220,216,172, 91,183,110,240,245,245, 69,221,186,117, 33,147,201, 0, 0, 89, 89, 89,142, 17, 17, 17, 31,221,187,119,239,163, 27, - 55,110,192,207,207, 79, 13,224,106,112,112,112,133,209,136,192,190,157,190,148, 41,165,235, 0, 32, 61, 33, 51, 57,225, 89,218, -186,228,228,228,149,148, 82,174,220, 9,233, 53,124,248,240,169,147, 38, 77,194,177, 99,199,176,107,215, 46,104,181, 90,228,231, -231,227,194,133, 11,149,220, 90,167, 33,251,194, 50, 64,241, 28,136,187, 4,200, 29, 0,133,227,235,220,189, 45, 24, 60,120,240, - 20,111,111,239,178,172,227, 6,131, 1, 44,203,194, 96, 48, 32, 59, 59, 27, 83,167, 78, 45,189,120,129,227, 56, 92,184,112,225, -203, 25, 51,102, 0,192, 87, 21,105,118,235, 92,239,174,144, 16, 87,238, 63,166, 44,225,236,229,167,254, 0, 17,220,185,123,159, - 84,108,190, 90, 8,170,191, 16, 10, 92, 67, 66, 66, 28,196, 98,177, 73,219,198,113, 28,124,125,125, 77,250,172,139,139, 75, 23, -133,210, 98,215,128, 33,159, 91,183,244,109, 41,114,113,118,134,129,101,241,236,121, 92,235,251,247,130, 91,158, 57,186,231, 11, - 23, 23,151, 33,137,137,137, 85, 46, 72,109, 52,114,184, 31,241, 24,231,174,222, 67, 95,145, 12,133, 26, 29, 10,213, 58,108,255, -235, 58, 18,210,114,107,189,159,218,180,105,227, 34, 23,216,183,254,114,212, 7,138, 21, 63,109, 83,124, 57,234, 3,172, 92,191, -189,228,239, 54,197,151,163,250, 97,229,250, 63,148, 95,142,234,135,181, 27,126,107,219,166, 77, 27,151, 91,183,110, 37, 86,166, - 87,217, 62, 98,140,172,116,107, 68,162, 0, 0,210, 55,109,130, 33, 45, 13,170,121,243, 0, 0, 95,120,187,152,220,173,209,172, - 89,179,187, 66,161,176,218,198,145,101,217,132, 7, 15, 30,248,155, 98,174, 88,150,165, 66,161,112,238,213, 29,223,239,239,208, -178,225, 11,149, 25, 21, 21,101,249,221,119,115, 7,238, 13,206,167, 31,249,153, 71, 28, 94, 57,170, 74,147,197,113, 28,163,213, -106,241,248,241,227, 10,179,236, 51, 12, 99,172,205,126, 10, 8, 8,144, 22, 22, 22,238, 84, 42,149, 62,133,133,133,163, 40,165, -223, 5, 5, 5, 57, 50, 12,131,192,192,192,239,252,253,253,159,203,100,178, 13,106,181,250,158, 82,169, 28, 18, 20, 20,100, 82, -227, 74, 8,121,199,194,194, 98,251,161, 67,135,172,125,125,125,153,140,140, 12,120,120,120, 32, 43, 43,171,245,229,203,151,253, - 62,251,236,179,207, 8, 33,159, 82, 74, 47,215,160,184,141,228,114, 57, 29, 62,124, 56, 49, 26,255,179,185,191,254,250, 43,252, -156, 83,235,141,237,169, 40,210,232,104,238,249,199,150, 99,197, 98,241,213,152,152,152, 26, 31,192, 34, 66,102,140,154, 50, 69, - 32, 78, 78,134, 34, 42, 10,125, 8, 17,110, 41,142,102,253,108,194, 54,187,174, 90,183,210, 65, 34,145,128,101,217, 50, 19, 88, -122,141, 50, 24, 12,208,235,245, 48, 24, 12, 48, 26,141, 48,232, 13,216,186,233,183, 90,159, 99,114,133, 92,238,228,236,156,106, - 38, 87,200,223, 68, 99, 35,149, 74,133,219,182,109, 27, 34,145, 72, 0, 0, 58,157, 14,205,154, 53, 35,124, 51,204,243,111,140, - 96,245, 10, 10, 10, 2,203,178, 48, 55, 55,135, 64, 32,120, 57,186,129,119,222,121, 7,109,218,180, 65, 96, 96, 32, 30, 61,122, -100,182,124,249,242, 74,195, 17, 67,167,245,129, 91,131, 98,227, 99, 48,112,206,215,142,223, 91,246,235,247,251,237, 1, 76, 43, - 31, 48, 24, 51,102, 12,201,204,204,196,160, 65,131, 46,107,181,218,247, 41,165,149, 46,151, 99,228,144,208,229,227, 97,224, 40, - 49, 91,125,107, 43,209,105,212,148, 97, 24,117,105, 23, 97, 45,239,138, 7,169, 84, 42,236,222,189, 27, 58,157,238,149,247, 45, - 44, 44, 16, 30, 30, 94,222,228,160,101,203,150, 2, 66,200,160,202, 12, 22, 67,136,235,201,160,232,178, 25, 65,131,223,111, 41, -238,222,185, 94,170,144,145, 80, 0,228,219,111,191, 45, 51,108, 0,176, 96,193, 2,147,203, 43, 22,139,241,232,209, 35, 8, 4, - 2, 60,233, 80,124,131,221, 44, 36, 30, 2,129, 0,247,125,138,239, 64,219, 71,231, 64, 32, 16, 64,169, 84,154,106,174, 2, 28, -157, 93, 15,127, 51,111,169,185,198, 64,113,252,194,109,196, 37,157, 5,165, 20,206, 14, 54,104,239,231, 43,106,218,188,133,195, -175, 63,175, 56,236,226,226,210, 47, 49, 49, 49,168, 50, 45, 3,107, 68,147, 6,158,216,118,232, 50, 22,109, 56,128,204, 60, 53, -242,139,138,235,181,107, 91,111,252, 82,251, 72,231,202, 70,238,238,110,191,239, 61,133,118,109, 91,225,143,189,167,209,174, 77, - 43, 20, 63,111,131, 63,246,158, 66,251,118,197,127,155, 54,169, 87, 39, 43, 38,119, 37,170,200,237,245,202, 62,234, 87,188,143, - 60, 4,226,178, 6, 32,102,220, 56, 0, 40, 51, 88, 53, 58,209,132, 66,215,123,247,238, 57, 84,247,185,150, 45, 91,154, 20,185, - 98, 89, 22,105,105,105, 36, 39, 39,135, 90, 89, 89, 13, 44,111,178, 74,205,213,158,187,121, 80,223, 92, 79,118,252,117,137, 27, -246,126,231,136,195, 43, 71,121, 15, 28, 56, 48,178, 34, 93,189, 94,255,188,123,247,238,180,164,225,115,145, 72, 36,226,151, 12, -152,170, 67,135, 14,175, 24,180,234,186, 14, 11, 11, 11,119,110,217,178,165,127,189,122,245, 48, 96,192,128, 51,222,222,222, 18, -185, 92,142, 83,167, 78,193,205,205,205,206,220,220,252,196,210,165, 75,177,106,213,170, 58,103,206,156,217, 5,160,191, 9,231, -104, 96,151, 46, 93,118, 31, 59,118, 76, 38, 22,139,161, 86,171, 17, 30, 30, 14, 75, 75, 75, 72, 36, 18,244,235,215, 79,208,161, - 67, 7,219,128,128,128, 3,132,144, 33, 53,153,209,164,209,104,232,236,217,179, 33,151,203, 33,151,203,161, 80, 40,160, 80, 40, - 96, 38,230,200,166,201, 30,102,147,182,228,152,125, 53,111,211,178,237, 27,230, 95,172, 83,167,206,119,113,113,113, 57, 53, 61, - 22,178,239,220,129, 34, 42, 10,154,187,119,107,124, 28, 89, 42,108, 48,107,214,172,234,142, 53,136,197, 98,180,111,223,190, 90, -189, 38, 77,154,108, 18, 8, 4,246, 47,154,105, 34,152,251,237, 55,236,131,240, 40,133,222, 72, 21, 26, 45,139, 69, 11,231,178, - 2,134, 17, 52,107,214,236, 16,165, 52, 61, 60, 60,124,172, 9,209, 51, 45, 33,100, 58,195, 48,107,165, 82,169,208,221,221, 61, -118,238,220,185, 55,138,187, 26, 0, 74, 41,227,238,238,222,218,204,204,172,174, 86,171,101, 1, 76,231,163, 87, 60,255, 22,131, - 5,165, 82,137, 59,119,238,128, 16, 2,115,115,115, 88, 88, 88,192,210,210, 18,121,121,121,136,136,136,192,195,135, 15, 17, 19, - 19, 3, 66, 8,188,188,188, 80,122,226,148, 59,193,202, 46,108, 59,127, 60, 6,153, 82, 10, 66, 0,223,119,125,224,243, 78, 51, -180,186,253,116,178, 74,165,218,146,148,148,244,152, 16, 34,108,214,172,217,103,109,219,182,197,170, 85,171,160,213,106, 87, 85, -100,174,202,107, 94, 14, 55,248, 3,128, 74,165,250,250,207, 83, 79,228,159,244,172, 87,148,148,148,244, 67, 77, 43,225,229, 11, -112, 70, 70, 6, 56,142, 51, 57, 42,148,147,147, 83,165,230,203, 17,129, 69,203, 86, 91,229,231,166,226,251,229,127,194, 96, 48, - 96,218,180,105,224, 56,174,236, 81,145, 94, 69,229, 44,237,250, 19, 8, 4, 47, 24,224,234,158, 87,165,105,111,111,175,144,202, -228,187,190,254,246,123,243,208,168, 4, 28,187,112, 27,148, 82, 28,217,242, 29, 0,160,223,232,133, 72, 76,201, 64, 7,191,198, - 24, 49,118,170,249,234, 37,179,119,217,219,219,215, 75, 79,255, 79,242,217,242,154, 6,150,195,129, 83, 55,144,148, 89,128,225, - 3,186, 66,163,213, 35, 61, 45, 5,191,253,188, 2,227, 71, 28,128,181,210,204,201,203,203, 43,170,124, 29, 81, 74,137, 88, 44, -190, 26, 21, 21,245,121,101,229, 52, 24, 12,189,190,153,250, 5,214,110, 61,128,102,245,157,112,244,236,117,248, 55,173,139,147, - 23,110,163,109,115, 15,156,190, 20,140,182, 62,158,184,116, 51, 28, 83,198,126,138,233,147,175,246,170,201, 62, 90,188,116,181, - 85,126, 94, 42,142, 45,222,134,180,159,127, 70,236,196,137,104, 93,242,153,219,132, 64,236,234, 10,152, 87, 95,159, 47, 19, 25, - 25, 9,173, 86, 91,209,221, 61,154, 52,105, 82,237, 62, 42,141, 92,165,166,166,146,212,212, 84, 40, 20, 10, 18, 25,254,192,216, -164,105,179,129,244,225,254,173, 0, 80, 28,185,202, 67,209,245,117, 80,223,248, 9, 98,143, 80,102,235,194,177,186, 47,190,219, - 20, 81,174,113,123,161,156,247,239,223, 47,171,159,182,109,219, 62,188,122,245,106,163,210,227,171,164,171, 80,204,178,108,131, -210,110, 67,150,101,161,213,106, 49,100,200, 16, 65, 85,219,110,102,102,230,227,229,229,133,224,224, 96,140, 29, 59, 86,210,165, - 75, 23, 68, 71, 71,131, 16,130,145, 35, 71,194,219,219, 27,233,233,233,104,213,170, 21,174, 92,185,210,210,132, 99,222, 92,161, - 80,252,118,244,232, 81, 25,195, 48,200,207,207, 7,199,113,232,208,161, 3, 24,134,193,131, 7, 15,240,237,183,223,226,224,193, -131, 56,124,248,176,153,159,159,223,111,132,144, 38,148,210,124, 19,246, 17,213,104, 52, 84, 42,149, 66, 42,149, 66, 38,147, 65, - 38,147, 65, 34,145, 64,173,103, 48,122,117,172, 86, 32,179,227,154,182,236, 88,111,228,164, 37,204, 15,115, 71, 93, 0,112,164, - 68,243,129, 41,215, 11, 3,165, 43,214,255,242,203,186,247, 80, 60,193,104, 95,126, 62,103,160,116,133, 41,231, 38, 0, 20,104, -114, 81,215,203, 21, 7,246, 28,198,135,131, 63,168,208, 92,137, 68, 98,136, 69, 34, 88,216, 40,170,213, 20,137, 68,118, 33, 33, - 33, 86,229,175, 15, 44,203, 70,126,249,229,151, 94, 31,244,123,207,113,239,193, 99,130, 79, 6,247, 51, 58, 57,218,103,196,199, -199, 70, 3,176,242,243,243,163,166, 30,243,148,210, 13, 45, 91,182,244, 61,116,232,208,168, 89,179,102,221,253,250,235,175,191, - 47,255,254,202,149, 43, 23,158, 56,113,162,110,255,254,253,183,223,187,119,111, 67,185,239, 45,127,211,141,221,223,145, 58,128, -215,228,169,181,193, 42,223,248,228,229,229, 33, 47, 47, 15,241,241,241,216,180,105, 83,201,137, 44,130, 80, 40,132, 80, 40, 44, - 27,175, 80, 25,231,142, 94,249, 9,192, 79,126,126,126,162,176, 27,251, 78,206,216, 50,169,171,127,160,175, 32,248,124,216, 64, - 0,139, 0,244, 26, 62,124,184, 29, 0,108,219,182, 45, 3,192,201,255, 70,133, 80, 74,247, 61,126,252,120,138,179,179,115,217, - 24,148,242,221,132, 44,203, 66, 38,147,161,116,172,138, 86,171,197,206,157, 59, 89, 74,233,190,170,234, 47, 42,252, 2, 30,135, - 95, 44,254, 30,199,129, 51, 22,127, 95,163,209, 96,254,252,249,229,167,190, 98,220,184,113, 64, 13,214, 66,174, 44,114,213,238, -113, 54,132, 66, 33,174,120, 22, 59,129,222,233,244,149,177, 90,175,116, 97, 72,100,211,122, 15, 24,102,195, 82, 65,153,185, 42, -222,134, 98,195, 41, 17, 11, 97, 38, 21, 35,234,105, 28,220, 93,252,208,181,247, 7,214,231,142, 29,152, 6,160,194,176,155,222, -200,161, 87,128, 31,126,222, 19,132,188, 2, 53,114,179,179,144, 30, 23,137,200,208, 59, 16, 10,133,184,123,247,174,185,133,133, -165,185,167,167, 7,140, 28,135,107, 55,238,130,130,224,232, 95,135,188,234,122,120,226,255,216,187,234,240, 40,174,246,123,238, -204,250,110,220,179, 9, 16, 72,136, 2, 81, 8,238,197, 41,238, 20,183,162,133, 34, 69,138,182,184,148,226, 80,164,180,184,187, - 20,119,146,160, 33, 36, 36, 1, 34, 27,247,108,214,119,230,247, 71,164,129, 70, 54, 41,223, 87,190, 95,247, 60,207, 60,187, 59, - 51,123,230,206,189,119,238,156,251,222,247,190,247,253,219,216,209,229, 8, 91, 78,179, 32, 31,228,103, 36,128,166,105, 52,245, -119, 3, 77,211,104, 17,228, 1,154,166,209,188,161, 39, 56, 28, 14, 90, 55,246, 65,221,186,117, 81,236,231, 81,113, 25,253,129, -168,151, 55, 74,137, 93, 22, 44, 0, 77, 82,210, 95, 95,148, 73, 73, 96, 77,237,170, 90,183, 48,123,246,236,236,164,164, 36,205, -199,130, 78, 42,149,242,142, 31, 63,110, 81,217, 34,216, 18,137,196,135,195,225,132,103,102,102, 50, 98,177,152, 98, 24, 61,227, - 93,175, 62,125,231,183,165, 71,139,207, 89,178,100,233,209,254,129,102,125,247, 31, 57,203,242, 92,154, 19,194, 21,232,198,124, -191,141,207, 17, 74,124, 12,236, 52, 80, 42,149, 10,175, 95,191,174,116, 81,110,150,101, 43,172, 80,114,185,124,120,159, 62,125, - 46, 79,152, 48, 65, 72, 8,193,237,219,183, 75, 4, 63, 77,211,136,137,137, 1, 69, 81,216,177, 99, 7, 84, 42,213, 4, 3, 44, -129,211,142, 29, 59,102,206,231,243,145,151,151, 87,242,220,208, 52,141,136,136, 8,172, 89,179, 6,195,134, 13, 67, 92, 92, 28, -164, 82, 41,102,204,152, 97,178, 98,197,138,105, 0,150, 24,112,235,207,212,106,117,144, 88, 44,134, 80, 40, 68,177,208, 2,128, -208, 36,251, 23,177,177,177, 13,108,108,108, 28,108,111,158, 61,221,180,205,151,126,214,182,142, 77,138, 5,150,161,136,211,106, -119,200,228,242,249,253,118,239,182,187,117,250, 52,243,226,244,233, 4,142, 94,191,221,224, 58,164,165,240, 62, 38, 1,129,129, -129, 8, 13, 13, 69, 96, 96,224, 7,214,108, 62,159, 15, 30,143, 7, 30,143, 7, 27, 75,131, 92, 37, 88,154,166,145,156,156,252, -193,190,177, 99,199,190, 31, 50,100,136, 29, 0, 36,201, 18,216,111,166, 77, 78, 76, 79, 79,103,237,237, 43,230,244,243,243,187, - 69, 81,148,203, 71,162,216,114,220,184,113,200,206,206,238, 50, 97,194,132,230,133, 86, 50, 42,113,243,230,205, 67, 1,128,207, -231, 87,123, 8,218, 8, 35,254,231, 5,150, 33,168, 76, 96, 21, 35, 52, 52, 84,235,228,228,180, 51,234,201,187,118,110,190,174, - 16, 73, 4, 29, 8, 33, 63, 11, 4,130,233, 95,125,245, 21, 30, 60,120,128, 23, 47, 94,252,242,119,151, 61,105,208,160,193, 37, -129, 64, 80,171,172, 99, 42,149,234,253,243,231,207,203,244, 21, 75, 77, 77, 93,248,232,209, 35, 84,228,228,222,191,127,255,210, - 47,163, 18, 39,247,114, 91, 48,134,133, 86,163,133,188, 64,241,231,203,187, 72, 96,201,229,114, 12, 24, 48,224, 3, 11, 86,106, -106,106,181,238,185, 42,150,171,242, 64,209,116, 71, 95,191, 0,238,181,123,207, 62,120,185,246, 28,183, 12, 2, 30, 7, 98, 1, - 15, 66, 1, 23, 34, 1, 15,241,137, 41,240,242,170,207,187,121,233,108,199,242, 4,150, 86,199, 96,213, 47,231, 0, 0, 71,206, - 92, 67, 80,109, 49, 22,207,159,141,126,253,250,129,207, 23,226,216,177, 35, 88,179,121, 31,198,215, 42, 44,170, 70, 13,253,177, -122,235, 65, 44, 93,178,152, 58,114,248, 72,115, 3, 94,184,224,112, 56,160,105,250, 47,159,197,223, 13,177, 70,178, 12, 11,205, -199,101,196,176, 0,203,194,249,135, 31,224,252,195, 15,120, 84, 36, 78,125,228,114, 40, 20, 10,160,181,111,149,196,149, 90,173, -134, 76, 38,211, 60,125,250,212,190,140, 23, 83,138, 90,173,174, 84,208,236,222,189, 59,114,228,200,145, 62, 86, 86, 86,225,207, -158, 62,213,250,250,249,113, 63,246,193,242,240,240,200, 89,178,100,233,209,161,253,186,245,221,246,221, 64,221,248, 37,191,114, - 12,113,116, 47, 17,197, 26,205,219,246,237,219, 27, 36,241, 21, 10, 69,114,121,199,130,130,130, 70, 18, 66,126,240,240,240, 16, -180,105,211, 6,183,110,221,194, 15, 63,252,192,232,116,186,116, 0,104,218,180,169,237,210,165, 75, 73,120,120, 56, 44, 44, 44, -144,154,154,186, 55, 40, 40,104,105, 69,142,239,124, 62,191,117,195,134, 13, 41,149, 74,245, 23,113,181, 98,197, 10, 12, 26, 52, - 8, 30, 30, 30, 96, 24, 6,249,249,249,104,211,166, 13,119,227,198,141,173, 13, 17, 88, 20, 69, 77,109,215,174,221, 26, 20,206, - 34, 44, 45, 28, 95, 1,152, 89,100,221, 78,238,214,103,216,203, 22,237,123, 7,185,212,173,239, 88, 25,167,189,189,253,119, 20, - 69,245, 7, 64, 3,136,167,172,172,234,218,218,218,218,183,236,214, 13,249,132,208,219, 47, 94, 36, 28,145,200, 4,128, 65, 67, -141, 74,173, 28,181, 92, 11, 93,249,250, 12,232,137,208,208, 80,244, 29,216, 11, 60, 30, 15, 28, 14, 23, 60, 46, 23, 92, 94,161, - 5,203,194,198,172, 90,237, 72, 81,231,145,152,155,155, 3, 44, 96,102,110, 94,108,201, 36, 0, 88,138,162,216, 10,234,185,251, -254, 73, 99,237,120,102,230, 96,116, 90,212,252,178,111, 73,157,142,218,189, 69, 4,134, 17,229,199,189,197,212,235,143,184, 48, -194, 8,163,192, 50, 12,165,157, 66,203, 66,219,182,109, 39,155,154,154,110, 44,106,120, 17,255, 32, 17,241, 15, 18,225,237, 89, -175, 89,128, 95, 80,206,160, 65,131, 96,109,109,141,111,191,253,150, 5,240, 75, 85,175, 31, 19,249,210, 4, 0, 43,149, 74,191, - 45,178, 8,248, 61,122,244,200,246,241,227,199,104,216,176, 97,233,151, 7,154, 55, 47,255,189, 93, 52, 51,238, 27,148,227, 79, - 85, 77,171, 24, 52, 26, 13, 10, 10, 20, 80,171, 53,208,105, 25,232,116, 58, 4,214, 51,197,175, 59,230, 20,238,211, 21, 91,203, - 10,173,100, 2,158, 10,173, 26,215,208,130, 80,138,155,247,223, 87,216, 82,150,101,185,162,105, 26,119, 92, 11,255,214, 33, 73, -107,176,208, 98, 25,189,167,131,189, 61,226, 46, 62, 4, 0,152,136,133,184,180,111, 41, 36,226,194,201, 13, 93,134,205,133, 72, -192,131, 72,192,133, 70,163,129,189, 93,109,232,244, 90,207,114,133,183, 86,173,174,101,111, 14,199, 46,141,241,244,241,125,124, - 51,121, 12, 70,142, 28, 5,158,208, 20, 55,111, 94, 71,156, 44, 21,111, 18,178, 48,121,225, 22,104,117, 12, 52, 58, 61, 52, 90, - 61, 54,236, 61, 7,141,158,173,244, 37,207,227,241, 48, 99,198, 12, 81,121,199, 15, 30, 60,168, 48,188,140,180,144,203, 21, 80, -169, 84,208,168,117,208,104,117,208,215,225, 97,233,252,193,208,105,116, 40, 24,216, 4, 26,173, 14,204,180, 94,208,168,181,136, - 23,115,168,230, 13,165, 90,128, 82,220,121,156, 96, 86, 25,127,177, 40,168, 72,128, 25,130, 98,145,229,235,231, 23, 62,188,107, -163, 21,119,239, 63, 78,187,123,255,241, 95,206,115,173,215, 40,118,252,242,131,115,170, 34,174,128, 15,135, 11,255,102,189,255, -254,198,141, 27,246, 38, 38, 38,136,140,140, 4, 77,211, 32,132,100,132,134,134,218, 3,192,162, 69,139,210,185, 92,174, 53, 77, -211,152, 54,109, 26, 56, 28,142,237,215, 95,127,189, 0,192,166, 10, 58,114,222,166,166,166, 31, 88,175,120, 60, 30,230,204,153, -131,161, 67,135,150,136, 43, 30,143,135,189,123,247, 34, 40, 40, 8,106,181,218,219,144,244, 38, 36, 36, 60, 6,208,194, 0, 1, - 66,138, 68,121,165,245,147,162,168,225, 79, 39, 76,168,171,124,244, 8, 95, 51,140,143,167,167, 39,148, 74,101,201,113, 55, 55, -183,154, 9, 9, 9,201, 82,169,244, 55, 0, 91,100, 50,217,147,138,248,180, 74, 6,239, 99, 18,138, 59,171,104,212,168, 81,137, -197,170,180,245,138,199,227, 65,196, 55,169,114,153, 49, 12,131,220,220, 92,122,239,222,189,117,124,124,234, 17, 0,240,246,174, - 71,206,157, 59, 95,211,196,196, 36,214,202,202, 74, 83,233, 51,105,102,142,171,163, 6, 0, 0,250,181,237, 84,108,197, 66,200, -210,185,224,112,185,240,155, 62, 23,192,163,146,243,213,106, 53, 24,134,161, 97,132, 17, 70,129, 85,206,131,175,213, 86,120,124, -221,186,117,104,208,160, 65,133, 47,160,141, 27, 55, 98,255,254,253,235, 88,150,141,169,234,245,187,181, 11,168,135,245, 39, 94, -186,122, 20, 54, 10, 75,166,117,167,228,114, 57,238,222,189, 11,115,115,115,188,121, 99, 88,216,174,255, 68,152, 6,150, 5, 52, - 90, 29,228, 5, 74,168,213,106, 76,155,101,208,204,116,162, 81,231,113,186,118,106, 89,174,120, 40, 30,238,163, 40,170, 82, 31, -172,202,134, 6, 63,176, 96,104,181, 40,126,117,228, 23, 40,209,118,240,119,120,116,106, 3, 0, 20,138, 43, 33, 23, 34, 62, 15, - 34, 62, 7, 20, 1, 8,202,231,214, 42,114,191, 92,191,116,214,237,173,191,252,234,220,179,229, 24, 76,158, 52, 25, 28,190, 24, -150,214,182,208, 49, 44,106, 74,237, 16,157,152,133, 99, 63,207, 42, 26, 21,101,209,114,200, 34,172,155, 63, 6,171, 23, 86,110, -196,228,112, 56,216,180,105,147,226, 99,171, 85,233, 79,182,242,247,224,159, 2,171, 64, 1,133, 82,133,111,191,219, 98,120, 25, -117,108, 33, 50,228,228,138, 4, 84,101, 2,172, 44,145,101,200,243,235,215, 19,243,255,201, 6,134, 97, 24,156, 59,119,174,164, - 60,202, 43, 67, 67,173,173, 12,195,224,253,251,247,120,249,242, 37, 26, 55,110,140,156,156, 28,112, 41, 10, 51,158, 63,135,207, - 87, 95, 65,205,227,129, 97, 24,240,249,124,140, 27, 55,206,224,252,172,162,114, 44,242, 99,211, 87, 72,238,232,232,184,214,203, -203,171,110, 76, 86, 22, 66,159, 62, 69,163,177, 99, 1, 0,119,238,220, 41,109, 1,196,224,193,131,249,177,177,177,163, 34, 34, - 34, 70, 57, 58, 58,174, 75, 74, 74,154, 81,238,243,196,170, 74,124,176,250, 15,238,131,186, 94,117,176,127,207,129,146,227,211, -103, 78, 5,151,203, 3,151,199,133,133,185, 69,149,111, 45, 55, 55,151,179,118,237, 58,223,224,224,198,162, 33, 95,141,160, 52, - 58, 22, 75, 87,110,160, 15, 31,248,213,122,223,175,251, 69, 66,161,240, 85,165,101,164,213,252,165,157, 34,132,128,195,229,130, -195,231, 1, 12, 3,150,101, 37,171, 87,175, 94,242,242,229,203,134, 94, 94, 94, 80,169, 84, 95, 17, 66,194,140,113,176,140,248, - 87, 9, 44,154,166, 43,181, 78, 81, 20, 85,233, 16,225,244,233,211, 97,106,106, 90,222,139,135,125,254,252,121,120, 82, 82,210, - 14,150,101,171, 21, 23,231,236, 31, 97, 47, 23,127,211, 43, 15,128, 2, 0, 44, 44, 44,210,219,182,109,155, 15, 64,115,248,240, -225, 15,206, 85,169, 84,239,203,227,177,179,179, 91,188,106,213,170, 41,157, 59,119,166, 40,138,250, 75,227,254,241,166,213,106, -113,230,204,153, 41,203,151, 47, 71,121, 86,175,226,151,119,129, 92, 1, 69,145,131,115,244,139,163,134, 54,230,149,158,242,204, -207,169, 76,203,213, 23, 50, 13,104,154,198, 5,187,194,251,232,146, 86, 57, 23,161,232,200,183,239,227, 27, 57,216, 88, 32, 43, - 39, 31, 2, 62, 23, 34,193,159,214,124,145,176,208,122, 37, 18,112, 97,105, 97,138,140,140, 20,112,185,220,200, 10,132,195,123, - 66, 72,139, 1,189,186, 92,166,104,142,176,244, 49,174,200, 76,124,229,238,115,203,148, 76, 57, 74, 27, 3, 24,134,197,148,165, -123, 12,171,192, 28, 14, 38, 78,156, 88,174,192, 57,125,250,116,149, 45, 88, 10,101, 21,203,200, 64,254,138,134, 0, 43, 59, 94, - 25,138,103, 23, 74, 36, 18,159, 34,241,101, 48,252,252,252, 46,136,197, 98,131,131, 28, 25, 26,116,148, 16,178,164,109,219,182, - 63, 56, 59, 59,219, 77,152, 48,129,208, 52,141,160,160, 32,155,239,191,255, 62,167,208, 50,226,109, 90,220,198,172, 95,191, 30, -175, 94,189, 74, 35,132, 44,173,136,147,207,231, 71,152,155,155, 7,181,105,211, 6, 57, 57, 57,136,143,143,135, 68, 34,129,207, -218,181,120,254,245,215,240,219,182, 13, 84,219,182, 32,132,128,207,231,227,249,243,231, 16,137, 68, 17,229,241, 57, 57, 57, 5, -179,133, 78,230,205,240,231,176, 32, 11,224, 46, 33,100, 86, 98, 98,226,195, 50,218, 59, 10, 0,244, 12,195, 86,114,255,131,191, -251,238, 59, 80, 34, 17, 28,155, 52,129, 34, 38, 6, 26,141, 6,141, 27, 55, 46,177,170, 55,110,220, 24, 52, 77,163,110,221,186, -176,178,178,194,241,227,199, 7,227,195,153,213, 31, 64,153,175,193,251,152, 4, 52,105,210,164,196, 82,213,181,107,215, 18, 11, - 22,151,203, 45,177,100, 17,125,229,130,149, 16,194,126,212, 22, 19, 62,159, 39, 24, 54, 98, 20, 53,235,219,111, 24,173, 78,203, -208, 52,151,250,118,254,114,234,205,235, 23, 2,185, 92, 78,145, 74,122,107, 53,123,244, 67,191,118,133, 70,208, 99,117,109, 65, - 23, 9,171, 30, 47, 18, 74,202,197,236,236, 31,252, 21, 43, 86,244,245,242,242, 42, 28,110, 7, 56,198, 56, 88, 70,252,155, 4, - 86,212,211,167, 79,221,235,213,171,135,184,184,184,191,204,108, 43,126,198, 36, 18, 9, 68, 34, 81,177,133, 40,170, 60,178,107, -215,174,253, 12,224,231,226,223, 82,169,180, 73,155,254,173,239, 53,234,212, 16,191, 47, 63,144,147,148,148,228, 91, 28, 19,139, - 16, 66,164, 82,233, 80, 46,159, 51,192,181,126,205, 86, 96,152, 85, 87, 79,223, 89, 84,209,141,184,122,212,203, 7,160, 40, 53, -139,112, 77,117, 50,132, 16,210,175,115,231,206, 84,120,120, 56, 6, 12, 24,128,253,251,247,151,123,238,208,161, 67,113,240,224, - 65,116,236,216,145, 90,177, 98, 69,191,202, 4, 86,161,117, 68,253, 31, 43,204,178, 44, 87, 31,139,196, 74,133, 0,163,187,250, -252, 73,168,191,111, 80, 83,238,187,132, 20, 8,249, 28, 8, 5,127,206,216, 23, 21,249, 95,137, 4, 92, 56,216, 90,226,209,189, - 27, 26,157, 78,123,181, 18,113,241, 30,101, 4,105, 20,152,218, 68,126,209,172,129,101, 89,255, 89,251,221, 87,104,112,104,109, -165,233,229,114,185,216,189,123,183,162, 60,235,149,161,121, 80,104,101,212,162,160, 64,129, 2,133,242,147,149,137,189,189,189, -173,157,157,221, 86, 11, 11, 11, 97, 89, 2,234,227,227,127, 71, 92, 21,197,197, 10, 31, 57,114,100,149, 68, 22,159,207,175,125, -247,238,221,146, 32,163, 21,125,170,213,106,244,239,223,223, 32,203,119, 72, 72,200,238,128,128,128,104, 91, 91,219, 43, 62, 62, - 62,130,232,232,104, 44, 91,182,140,112,185, 92,179,226,246, 35, 47, 47, 15, 52, 77, 35, 43, 43, 11,132,144,225, 33, 33, 33, 23, - 43,226, 84,169, 84, 55,111,222,188,233,223,189,123,119, 58, 34, 34, 2, 52, 77, 23,166,171, 73, 19,248,109,219,134, 23,223,124, -131, 86,239,222, 65,169,209, 64, 40, 20,226,210,165, 75,154,130,130,130,155, 21,220,251,142,251,247,239,215, 19, 10,133,208,104, - 52, 96, 24, 6, 20, 69, 17, 14,135,211,220,199,199,103, 35,128,134, 31,117,192,236,198, 77, 95,233,169,215,233,244, 73,113,209, -105, 6, 88,132,176,127,255,126, 52,110,220, 24,173, 90,181, 66, 98, 98, 34, 98, 98, 98,208,165, 75,151,146,115,158, 62,125,138, -176,176, 48,184,185,185, 85,110,193,163,180,112,243,172, 13, 30,143, 7, 46,151, 11, 30,183,240,179,112, 43,180, 92,241,184, 60, -112, 57, 92, 8, 69, 66, 3,181,255,135,117,210,188,200,242, 37, 22,139,152,186,117,235,134,191,137,142,241, 1, 11,202,204,204, -220, 32, 95,219, 98, 62, 66, 72,137,184,226,242,121, 37,150, 44, 0,200,201,201, 81,246,236,217,243, 55,149, 74, 53, 2,159,112, - 36,197, 8, 35,254, 87, 4, 86,151,209,163, 71,111,235,208,161, 67,187, 25, 51,102,192,196,196, 4, 73, 73, 73, 37, 15, 24,159, -207, 71,141, 26, 53, 80, 80, 80,128, 91,183,110, 33, 59, 59,251, 26,128,113,134, 94, 56, 41, 41,233,193,155, 39, 81, 25,109,250, - 54,181,174,215,212,211, 34, 62, 42,161, 49,128,123, 69,226,234,151, 65,211,187,140,104,211,187, 17,120,124, 46,226,223, 36,255, -215, 50,132,162, 40,154, 16,130, 1, 3, 6, 24,116,254,192,129, 3,113,243,230, 77, 84, 52,156, 88, 98,193, 42, 80, 66,174,248, -116,157, 51, 66, 8,244,122, 61, 26, 71,102,126, 48, 51,171,216,114, 85, 44, 44, 12,177, 92,149,244,144, 11, 10, 86,223,190,122, -106,172, 87,125, 63,219,198,254,238,120, 19,155,128, 85,115,199,148, 28,255,118,252, 32,236, 61,116, 26, 78, 14, 54, 80, 22,228, -225,226,249, 51, 57,185,185,185,171,171,123, 15,251, 78, 22,198,129,108, 49,248,195, 57, 2, 3,190,249,201,160,255,115,185, 92, -140, 24, 49,162, 92, 11,214,149, 43, 87, 20,134, 12,143,178, 44, 11,141, 90,139,124,185, 2,138,130, 79, 35,176,164, 82,169, 95, -227,198,141,175,108,223,190,221,218,198,198, 6, 50,153,236, 3,129, 37,149, 74,253,130,131,131,175,108,223,190,221,218,214,214, - 22,241,241,241, 6,135, 7, 41, 67, 92, 33, 45, 45,141,100,101,101, 49,150,150,150, 85, 18, 89, 20, 69, 65,165, 82,225,213,171, - 87,134, 62, 35, 6,207,248, 50, 49, 49,217,179,124,249,114, 65,106,106, 42,104,154,198,171, 87,175, 62,168,171,197,219,119,223, -125,135,185,115,231,110, 5, 80,171, 34, 62,157, 78,183,110,232,208,161,163, 18, 19, 19, 45,237,236,236,144,148,148, 4, 62,159, - 15,150,101, 65,218,180, 65,139,216, 88,104,244,122,136, 68, 34, 68, 70, 70, 98,199,142, 29,114,149, 74,181,174, 44, 46, 55, 55, - 55, 62, 69, 81,238, 60, 30, 15, 67,134, 12,249,176, 94,238,219,135, 38,181,178,130,198,126, 33,200,215, 65,168, 74, 17,117,190, - 64,211, 52, 25,247,237, 42,143,224,150, 93,235,191,126,241, 48, 58, 45, 37,225,110, 37,183,175, 85,171,213,240,242,242,194,227, -199,143,113,245,234, 85,180,109,219, 22, 45, 91,182,196,141, 27, 55, 16, 18, 18,130,176,176, 48, 16, 66, 96,109,109, 93,236,102, - 81,161,175,133,186, 64,135, 84, 89,198, 95,172, 85, 31,255,230,241,120, 80, 41, 52, 6,149, 81,105,209, 68, 8,129,149,149,149, -106,195,250,213, 2, 19, 19, 19, 61, 0,152, 72,196,250,195,251, 54,195,198,218, 74,197, 26,104, 98, 45, 25, 22, 44, 18, 87, 52, -151,251,129,155, 2,203,178,121,207,158, 61, 27, 75, 8,121, 70, 8, 41,110, 63,140,113,176,140,248,119, 8,172,208,208,208, 88, - 0,237, 3, 2, 2, 6,223,186,117,107,221,244,233,211,109,155, 55,111,142,204,204, 76,212,170, 85, 11, 82,169, 20,143, 31, 63, -198,211,167, 79,211, 89,150,157, 17, 18, 18,178,191,140,135,172,125,121,177, 50, 88,150,101,165, 82,233, 17, 85,126,254,215,129, -173,188,113,237,240,237,229,142,142,142,227,156,156,156,166, 13,159,219, 99, 68,235,158, 13, 17, 25,246, 22, 15, 46, 63, 71, 74, - 92, 58,134,183,152, 85, 33,231,199, 78,238, 22, 22, 22,163,196, 98, 49, 31,128,166,140, 94,240, 7,179, 8, 75,115, 50, 12,163, - 87,171,213, 56,116,232,144, 65, 34,235,192,129, 3, 80, 42,149, 96, 24, 70, 95,222,189,235, 25,134,112,184, 2, 72,107,120, 65, -163,145,131, 97, 12,159, 32,201, 86,146,159, 58,157, 14,139, 23, 47,198,204,153, 51,177,116,105,249,163, 43, 28, 14, 7,155, 55, -111, 70,101,101,148,153,153,153, 39,149, 74,135, 30,220,245,211,209, 33, 99,166,152, 58, 55,245,197,158,195, 23,160,213,104, 32, - 16,112, 97,105, 38, 65,221,218,206, 80, 43,229,216,182,105,125,174, 82,161, 24,250,177,239, 89, 69,229,254, 49,134,245,108,137, - 21, 59, 78,225,246,239,127, 78, 66,108, 49,120, 33,126, 91, 61, 9, 1, 1,187, 43,228,212,235,245,224,112, 56, 56,120,240,160, -162,172,217,131, 52, 77,131,203,229,150,107,193,250,176,140,244,132,203, 19,162, 70, 45, 31,168, 85,249,159,164,140,172,173,173, -103,238,218,181,203, 90,169, 84,226,245,235,215,120,245,234, 21, 8, 33, 37, 42,166,248,120, 65, 65, 1, 94,188,120, 81, 44,112, - 94, 85,229, 57, 42,182, 92,165,165,165,145,164,164, 36,136,197, 98,234,217,179,103, 74, 95, 95,223,240,138,158,239,210,156, 42, -149,234, 93,187,118,237,202,179, 24, 57, 9, 4,130, 15,102,124, 21, 7, 29,253,120,168,176,172,116, 22, 20, 20, 60, 95,183,110, - 93,157,134, 13, 27, 98,251,246,237,106, 83, 83, 83,254,244,233,211, 89,154,166,201,134, 13, 27,144,149,149,165,158, 51,103, 14, -255,246,237,219,144,203,229, 79, 42,187,119,150,101,243, 8, 33, 99,155, 54,109,186,239,226,197,139, 98,119,119,119,228,230,230, -130,101, 89,236,221,187, 23,147, 38, 77,130, 80, 40, 68,100,100, 36,190,252,242,203,130,130,130,130,177,165, 99, 96,149,230,212, -233,116,132,203,229,178, 12,195, 96,193,130, 5, 37, 65, 69,139,131,140,138,120,122,236,152,238, 42,153,186, 51, 71, 50,248,251, -157, 95, 1,128, 94,167,211,191,126,241, 48,122,239,166,239,175,243,120,188, 91,165, 56,235,127, 28, 11,139, 16, 50,239,199, 31, -127,220,218,172, 89, 51,145,137,137, 9,220,221,221,113,247,238, 93,220,189,123, 23,183,111,223, 46,174, 3,176,178,178, 66,118, -118, 54,226,227,227, 21,132,144,121, 21,229, 39, 95,204,133,171, 71,237,194,217,130, 69, 22, 43,110,169,217,131,165,173, 89, 60, - 46,183,210,231,253, 99,247, 14, 43, 43, 43, 93, 96, 96, 64,184, 66,161,160,139,181,148,141,141,205,139,162,115,217, 26, 53,106, -168, 63,170,242,127,225,140,218,181, 25, 33,203,230, 21, 14, 11, 62,143, 47, 17, 91,215,191, 8, 0,135,199, 67,141,110,125, 74, -191, 7,182, 16, 66,118, 23,125, 87,149,226,156,253,169, 99, 97, 85,165, 93, 50,114,254, 51,156,255, 38, 11, 22, 0, 32, 44, 44, -236,247,250,245,235, 95, 88,177, 98,197,138, 19, 39, 78,140,153, 50,101, 10, 49, 51, 51,195,145, 35, 71,216,140,140,140, 61,124, - 62,127,230,253,251,247,179,170,115,113,150,101,247,220, 56,126,111,194,176, 57, 61,201,244, 13,195,155,135,252,241, 34,162, 65, - 83,119, 52,104,234,142,144,107,225,216, 52,247,192,126,189, 86,191, 32, 41, 41, 41,174, 18, 42, 85,251,102,158, 31, 59,185, 91, -223,188,254,135,117, 85,103, 17,178, 44,123,228,196,137, 19, 83,186,116,233, 66, 61,122,244,232, 47, 62, 87,197,203,227, 48, 12, -131, 43, 87,174, 64,163,209,224,200,145, 35, 76, 69,113,176, 24,176,167,182,109, 89, 61,108,219,174,227,124, 62,143,224,254,173, - 99,200,201,170,216, 42,199,227,113,241,219,129, 83, 26, 14,135,126, 93, 65, 90,223,135,133,133, 89,175, 90,181,138, 38,132, 96, -203,150, 45,160, 40,170, 92,135,246, 23, 47, 94, 48, 90,173,182,210,178,146,201,100, 87, 28, 28, 28, 6,110, 89,183,120,111,155, -142, 61, 44,188,189,124, 56,118,118, 53,193,161, 9,178, 50,210, 17,242,224,182,238,226,185, 83,217, 42,149,106,184, 76, 38,187, -242,119, 42,224,242,237, 39,203,220,223,103,202,186,202,172, 40, 58,173, 86,203,145, 72, 36,208,233,116,101,134,106,104,219,182, -173,232,238,221,187, 10,141, 70, 3,154,166, 43, 84, 76, 12,240,201,203, 72,175,215,123,103,101,101, 65, 46,151, 35, 52, 52,148, -221,180,105, 83, 90,118,118,246,220,210,199, 51, 51, 51,145,151,151,135,144,144, 16,118,251,246,237,105,185,185,185,115,171,146, -127,197,113,177,178,178,178, 24,177, 88, 76,105,181, 90,173,175,175,175, 80, 34, 49, 44,230, 21, 0, 60,121,242,164, 83,121,199, -154, 53,107, 22,117,247,238,221,186,122,189,190,244, 26,133, 60,165, 82,233,222,163, 71, 15,142, 1,233, 27,124,249,242,229,223, -111,223,190,221, 64,165, 82,141, 74, 77, 77,221, 7,160, 38,135,195,193,155, 55,111,210,212,106,117,159,121,243,230,237,145,203, -229,207, 77, 76, 76, 6, 27,216,110, 92, 36,132, 12,241,246,246,222,189,120,241, 98,147, 86,173, 90,113,164, 82, 41, 26, 54,108, -136,200,200, 72,156, 59,119, 78,187,101,203, 22,121, 65, 65,193, 72,150,101,175, 84,208,233, 96, 1, 16,157, 78, 7, 62,159, 95, -178, 9, 4, 2,240,120, 60, 20,168, 41,140, 94, 27,163,208, 65,164, 88,183,104,236, 57, 22, 32,201,241, 49,233,169,201,241, 15, - 9, 33,183,100, 50, 89, 78,121,150, 49,165, 82,233,207,178, 44, 39, 55, 55,119,131, 74,165, 26, 62,125,250,116,199, 85,171, 86, -193,215,215, 23,233,233,233,176,178,178,130,163,163, 35,242,243,243, 17, 27, 27,171,215,104, 52,219,244,122,253,146,148,148,148, - 10,135, 29,179,211,115,225,236, 80,243, 3, 75, 39,203,178, 96,245,128, 86,165,135, 94,195, 66, 77,180,224,114,181, 48,112, 9, - 45, 86,167,211,161, 91,183,110, 56,123,246, 44,122,246,236,201, 2, 40,215,138,116,246,236,217,202,135,220, 25, 6, 92, 1, 31, - 28,222,159,195,130,133,214,172,194,125, 20,249, 75,121, 26,173, 86, 70,252, 59, 5, 86,209,139, 57, 27,192,184,134, 13, 27,238, -155, 60,121,242, 89,134, 97,184, 12,195,116,125,242,228,201,237,191,115,241,164,164,164, 80,169, 84,250,157,189,179,229,138,206, - 67,155,195,211,191, 22,244, 58, 61,238,158,127,130, 61, 63,158, 60,152, 24,159, 56,188,244, 90,133,229, 63,207,204,245,102, 65, -158, 20, 0, 94,169,225, 23,166, 58,179, 8, 83, 83, 83, 23, 46, 91,182, 12, 63,252,240, 67,149,103, 17,150,119,206,189,199,137, -227,154, 4, 57, 58, 15,236,211,182, 35, 69, 40, 86,165, 86, 85,208, 43, 0, 91,236, 21,193,225,208,175,111, 62,136,247, 45,239, -220,228,228,228,118, 19, 38, 76,248,131,162,168, 90,165, 77,243,229, 65,175,215, 39,101,100,100,116, 48, 36, 31,146,147,147, 47, - 56, 59, 59,123,220,188,120,234,187, 59, 87,207,183,214,235, 53,110, 4, 4, 60, 30, 47, 90,171,215,221,208,170,213,203, 19, 18, - 18,178,254,110, 5,252,110, 92, 79,188,151,165,131,195,161, 11, 3,123, 22, 21,247,177,141,211, 17, 16,240, 91,185,255, 19, 8, - 4, 23,118,239,222,221,109,216,176, 97,164,216,239,140,101,217, 15, 26,244,135, 15, 31, 42,212,106, 53,246,236,217,195,138, 68, -162, 10, 3,215,126, 88, 70,132, 85, 85,224, 15,101,104, 25,229,231,231,143,236,209,163,199, 94, 0, 2, 0,111,114,114,114,198, -203,100,178,132,210,199,123,246,236,185, 23,128,128, 16,242,151,227,134,160, 56,100,131,165,165,101,120,145,229, 74, 88, 29, 71, -247, 10,234, 55, 93,222,240,161, 33, 67,133, 69,107, 11,246, 46,254, 29, 20, 20,180,100,194,132, 9, 37,139, 61,135,133,133,221, - 1,224, 90,141,206,217, 21, 66, 72,189, 5, 11, 22,124, 35, 20, 10,219, 20, 20, 20,120, 20, 9,186, 72,149, 74,117, 93,161, 80, -172,103, 89,182,194,216, 82,209,209,209,234, 58,117,234, 68,234,116,186,250,182,182,182,224,112, 56, 37, 34, 11, 0, 30,196, 89, -133, 36, 38, 38, 54,172,106,218,206,159, 63,239, 98,105,105,217,129, 16,210,151,101, 89,207,188,188, 60,213,247,223,127,127,239, -230,205,155,185, 17, 17, 17,157, 90,180,104, 65, 28, 28, 28,240,246,237, 91, 54, 63, 63,255, 40, 69, 81,243,100, 50, 89,140, 1, -247,156,176,103,207,158,170,230, 83,133,245, 73,173, 86,167,221,191,127,223,234,234,213,171,180, 94,175,199,197,139, 23, 75, 58, -146,101,141, 6,198,196,196, 64,173, 86, 87, 56,134,174,201,201,130,239,212,217, 96,139,102,115, 22,163,102,215, 62, 32, 96,193, -170,141,122,202,136,127, 7,200,127,100, 26,115, 21, 77,136, 82,169,116,128, 80, 34,152, 88,203,195,209, 87, 22,147, 26,158,151, - 83,176, 63, 41, 41,105, 59,203,178,250,234,114, 86, 37,208,168,209,204,251,207,112,242,197,102,151, 8,205,171, 85,238,203, 65, -175,121,175, 46,200,237, 88, 22,103,112,112,176, 19,143,199, 91,173, 82,169, 58, 87, 20,165,157,166,105,157, 72, 36,186,160, 84, - 42,103,126,188,216,243,255, 98,126, 30, 61,122,180, 76,209,111,232, 44,194,190,125,251,234,171,146, 78, 63, 63,191,235, 98,177, -184,204,128,154, 5, 5, 5,113, 79,159, 62,237,240, 57,228,103,241,204, 54, 67,124,132, 74,115, 86,103, 22, 97, 57,156, 37, 67, -132, 46, 46, 46, 2,141, 70, 19, 0,192, 3,128, 5,128, 76,173, 86,123, 49, 45, 45, 45,197,193,193, 33,136,162,168, 5, 69,226, -117,105,114,114,114,200, 63,249,108, 58, 59, 59, 11,205,204,204, 86, 83, 20,229,104,200,255, 25,134, 81,167,166,166, 78, 79, 79, - 79, 79, 46,139,179, 94,189,122, 33, 52, 77, 87,186,168,185, 94,175, 79,120,249,242,101, 80, 5,233, 52, 14, 17,254, 11, 57,255, -149, 22,172,255, 52,100, 50,217, 33, 0,135, 62, 37,103,121,145,218,141,248,124, 80, 44,158,170,131, 34,177, 52,240,223,150,103, -197, 2,169,140,253,175, 0,144, 79,125, 61, 67,194, 49,124, 14, 96,171,217, 83, 44, 18, 80, 45, 62,101, 90,222,189,123,167, 2, -112,175,104,251, 0, 69,130,170,251,231,146,111, 9, 9, 9, 74, 0,147, 62, 21, 95, 69,162,201, 8, 35,254,109,160,140, 89, 96, -132, 17, 70, 24, 97,132, 17, 70, 24,241,105, 65, 0,180, 47,167, 71,104,176,233,143, 16,210,190, 26, 61,206,171, 70, 78, 35,167, -145,211,200,249,255,132, 51,181, 2,206, 23,149,112,214, 47,231,144,221,255, 80,126,250,151,195,185,178, 18,206,217, 21, 28,126, - 98,172,159,255, 63, 57,255, 53, 40,118,102,252, 79,108, 0,218, 27, 57,141,156, 70, 78, 35,167,145,211,200,105,228, 52,114,254, -219, 54,227, 16,161, 17, 70, 24, 97,132, 17, 70, 24, 97,196, 39,134,193, 2,203,196,193,219,219,214,197,111,175, 85, 13,223,103, - 86, 53,124,159,217,186,248,237, 53,113,240,246,254, 55,102,154, 84, 42, 21, 57, 58, 58, 14,174, 89,179,230, 21,127,127,255, 92, - 39, 39,167,111,140, 85,169,234,104, 77, 8,103, 32, 33, 19,135, 17, 18, 55,140,144,184,129,132, 76,108, 77,200,255,187,101, 51, - 22, 79,149, 54,185,125,113,200,133,197, 83,165, 77,202, 60,254,173,212,250,225,149,254, 63, 45,159,228,100,245, 41,174, 71, 8, - 49,181,183,183,223,225,224,224,240,206,222,222,254,189,189,189,253,110, 66,136,185,177,198, 25, 97,132, 17, 70,252,247, 96,208, -203,204,170, 86,131,209,222, 94,158, 51,151, 45,154, 75, 28,236,108,196, 58, 61,163,121,251, 46,222,103,225,178, 21, 71,173,106, - 53, 88,151,249,254,249,174,106,188, 4,136,179,179,243, 0, 46,151,219, 13, 64,177, 80,123,165,213,106,207, 38, 36, 36, 28, 50, -116, 86,144,175,175,239, 29,154,166,107, 86,229,218, 12,195,188,123,250,244,105,203,234,100,152,147,147, 83, 63, 39, 39,167,221, -141, 27, 55, 22,251,251,251,131,199,227, 97,213,170, 85, 51, 0,172, 55,248,222, 91,183,230,216,101, 91,125, 69,115, 56,221, 1, -248,178, 44, 0, 66, 63, 99, 52,234,243,169, 60,171,189,108,232,118,173, 33, 60,142,142,142,115, 9, 33,195, 81, 56,173,124,151, - 76, 38, 91,253,159,168, 36, 82,169,180, 6, 33,164, 13,203,178, 94, 20, 69, 61,103, 24,230,178, 76, 38,203,248,187,188,246,192, -184,166,205,155,255, 52,108,198, 12, 90,113,235, 22,126,218,189,123, 3,114,115, 1, 96,115, 85,235, 82,112,176,127, 95, 83, 83, -116, 35, 64, 0, 8, 8, 5,246, 73,102, 54,117,254,241,227,176, 67,134,196, 82, 43, 15,129,129,129,231, 0, 20, 47, 28,119, 62, - 52, 52,180,107, 85, 57,114,162,217,249,130,238,222, 45,114,162,175,207, 7,208,249,227,227, 58,165,112, 24, 75,215,232,166, 96, -195,226, 1,172,253, 59,121, 74, 8, 17,219,218,218, 62, 59,117,234,148,115,163, 70,141, 56, 0, 16, 18, 18,242, 85,183,110,221, -218, 22,133, 18,200,253, 39, 26,154, 38, 77,154, 88,234,116,186,125, 52, 33,141, 25,134,177, 0, 0,138,162,178,245, 44,251,128, -195,225, 12,171,110,176, 98, 35,140, 48,194,136,255, 89,129,101, 98,239,229, 83,175,158,247,140,139, 39,246,213,200,206,204, 86, -254,188,102, 95,168,156,195, 47,112,247,113,231,253,188,126,181,229,196,169,211,167,153,216,123, 61,204, 79,137, 8, 55,244,162, -142,142,142, 53, 93, 92, 92,142,207,157, 59,183,126,243,230,205,185,118,118,118, 72, 73, 73,193,235,215,175,235,223,189,123,183, -231,201,147, 39,103, 56, 58, 58,246, 54, 32,130, 59, 36,124, 94,157, 67,171,150, 59,240,205, 45,192,234,117,176,172,239, 95, 56, -254,201, 48, 72,190,121, 21,122,141, 6, 44,163,135,115,167, 47,139,197, 21,130,131,131,121,213,201, 44,103,103,103,169,135,135, -199,254, 57,115,230,240,212,106, 53,194,194,194,112,255,254,125, 38, 53, 53,117,133,193,162,162, 65, 47, 31, 7,142,195,209, 30, - 61, 59,187,116,253,194,142, 95,203,193, 22, 44, 35, 68, 68,172,166,230,149,219, 97,157,206, 93,184, 52,203,206,167, 87,159,212, -240, 19,207, 43,226,169, 95,191,126, 99,138,162,126, 72, 76, 76, 44, 22, 65,171,130,131,131,191, 47,125,206,199, 26,149, 97, 24, -112, 56,156,148,130,130,130, 1, 47, 94,188, 8, 43,139,119,120, 0,209,106,245,133,245,130,199,129,254, 90,154,243,137,246,237, -219,215, 30, 57,114, 36, 2, 2, 2, 16, 18, 18,210,230,200,145, 35, 83,107,212,168,241, 88,171,213,158, 23, 8, 4, 55,138,166, -165, 87, 25, 60, 96,214,176, 25, 51,104,147,119,239, 96,242,244, 41,134,228,230,114, 86, 2,179,170, 34,176, 2, 3, 3,235,116, -104, 31,112,180,103,239, 86,222, 14, 14, 62, 60, 46,215, 6, 44,203, 66,171,205,244, 72, 75,123,213,215,220, 28,115, 26, 53,106, -212,231,209,163, 71, 6, 69,154,109,216,176,161, 61,195, 48,219, 88,150,229, 17, 66, 38, 3,232,114,241,226, 69,232,245,122,116, -237,218,181, 75, 96, 96, 96, 29,150,101,127, 54, 49, 49, 97, 21, 10,197,168,199,143, 31,167, 84,100,185,202,141,102,231, 39, 19, -215, 78,158,129,195,144, 76, 46,118,154,222,217,241,130,153, 27, 89,182,240, 39,217,125, 0,232,236,230,102,234,234, 37,153,109, - 98,214,192, 42, 55,241,234,236,206,110,110, 59, 47, 68, 71,231, 85,167,195, 82, 84, 15, 86,255,250,235,175, 53,130,131,131, 75, -226,101,249,251,251,211,171, 87,175,118,250,230,155,111, 54, 0, 24, 97,160,168,246,176,182,182,190,196, 48,140,234,229,203,151, - 30,197,251,237,252,122, 55,181, 54,149,180, 75,203,202,187,149,254,242,228, 77, 67,184,130,130,130, 70,242, 40,106,199,250, 5, -147,104,175, 6,126, 16,219,218, 66,147, 32,131, 92,175,181,122,240,244,101,215,149,235,119,164, 5, 5, 5,141, 13, 9, 9,217, -109,108,146,141, 48,194,136,127,141,192, 18, 8,248,115, 22,206,155, 77,178, 51,178, 21,202,220, 60,181, 86,169, 84, 82, 60, 86, -249, 60, 60, 54,149,226,208,217,223, 76,157, 98, 58,231,187,121,115, 0, 12, 49, 84, 92,121,121,121, 61,218,185,115,167,157,149, -149, 21,114,114,114,144,145,145,129, 71,143, 30,129,101, 89,116,238,220, 89,224,215,160,126,192,186,245, 27,238, 59, 58, 58, 54, -169, 76,100,113,184, 28,194, 21,139,113,172, 85, 0, 40, 30, 15,125, 34,146, 10,197,133, 86,131, 11, 3,186, 1, 0,104, 62, 31, -253,163, 10, 39,249, 8,133,194,106,103, 22,203,178, 77,154, 53,107,198, 3,128,233,211,167,231,202,229,242,229,132,144,223,101, - 50, 89,162,161,226,202,198,214,246,230,154,101, 99,172,234,215,113,133, 70,171, 69,124,106, 34, 88,194,135,163,157, 4, 67,123, -249,243,154, 7,241, 93,215,108,190,122,195,190,126,143,150, 41, 47, 78,189, 44, 87, 88, 74, 36,251, 54,108,216,128,195,135, 15, - 3, 0,174, 95,191, 14,119,119,119, 73,101,105,120,253,250,181,235,240,225,195, 15, 2,168, 91,214,113,173, 30,156,223,127,255, - 29, 0,176,246,219,193,244,230,219,145,181, 69,162, 63,215, 82,110,213,170, 21, 90,181,106, 69, 45, 95,190, 60,248,250,245,235, -193, 7, 15, 30,212, 56, 57, 57,109, 72, 76, 76, 60, 82,157, 60, 85,220,186, 5,147,167, 79,129,155, 55,171,252,223,192,192,192, - 58, 94, 94,214, 15,214,173,253,222,230,204,217,151, 88,179,102, 55,162,163,163, 1, 0,174,174,174, 24, 60,168, 31,247,247,223, -182,213,155, 51,103,209,189,192,192,192,230,161,161,161,149, 70, 55,103, 24,102,219,183,223,126,251,165,147,147, 19,230,207,159, - 31, 89,167, 78, 29,152,153,153, 97,251,246,237,176,180,180,132, 86,171,141, 92,181,106, 21, 71, 38,147, 97,227,198,141,191,148, -178,110,253, 5,173, 59,182,158, 47,232,238,221,194, 51,112, 24, 76,204, 28,177,243,192, 33,188, 14,221,215, 66,165,121, 53,127, -249, 36,167,161, 10, 86, 48,220,217,221,116,142, 75, 80, 43,235,186,245,190, 68,173,192, 48, 27,165,254,118,236,130,137,174, 43, - 56, 66,229,190,133,107,254,106, 37, 36,253,142,210,245,115, 35,172, 94, 92, 65, 6,203, 46,100,138,132, 85, 73,252, 43, 61,139, - 47, 91,182,108, 89, 34,174,222,189,123, 7,149, 74, 5,111,111,111, 74,173, 86, 27, 20,211, 74, 42,149,122,180,108,217,242,206, -254,253,251,173, 91,180,104,241,193,210, 45, 14,214, 22, 29,111, 30,223, 48,229,135,159,126,243,178,243,233,149, 93, 89, 71, 32, - 40, 40,104,100, 3, 79,183, 93, 27, 86,125, 79,232,188,120,112, 44,210, 0,125, 58,146, 14,253, 2, 34,182, 66,215,241,211,209, - 48, 56,152,158,242,205,220, 93, 13, 27, 54,100, 31, 63,126,188,199,216, 44, 27, 97,132, 17,255, 10,129,197,176,140,175,189,157, -181,104,195,154,189,143,105,141, 90, 45,177, 48, 87,115,205,205, 24, 98,106, 78,107,212,218,252, 90,174,181,248, 12,203,248,150, - 35, 72,174,126,220,203,118,113,113, 57,190,103,207, 30, 59, 46,151, 11,134, 97, 96,107,107,139,183,111,223, 34, 59, 59, 27,121, -121,121,136,126,245, 10,181,107,214,192,148,177, 99, 28,151,174, 89,123,156, 16, 18, 84,122,184,240, 99, 78,150, 97,193,232,116, - 31,247,230,129, 50,150,140, 41,111, 25, 25, 67,167,148, 50, 12,243, 86, 38,147, 65, 44, 22,195,219,219,219,228,241,227,199,183, - 19,139, 77, 72,149,221,123,235,214, 28, 71,129,237,241,213,203, 6, 88,129,138, 68,100, 92, 54,220,156, 27,193,198,162, 6, 18, -211,242,241, 56,252, 60,162,162,207,193,205,169, 22,198, 14,174,107,177,126,251,221,179, 36,112,156, 91,233,225,194,210,156,121, -121,121, 38,181,106,213,130,147,147, 19, 24,134,129, 94,175, 71,120,120, 56,244,122,125,201,239,210,159,123,143, 93,131, 46,247, - 61,134,125,245, 21, 50, 51, 51, 77, 12,189,247, 98,113,181,125,176,180,158, 60, 43,137, 7, 0, 18, 75, 71,205,216,223, 18, 95, - 54,108,216, 16,182,182,182,188,123,247,238, 77, 7,112,164,170,249,169, 1, 86,253,180,103,207,198, 33, 57, 57, 20, 0,236, 34, -132,209, 20, 70,213, 54,168, 46,181,111,239,119,108,195,134, 5, 54,132, 13,135,149,249, 74, 60,122,244, 30, 26, 77, 97, 85,201, -200, 72,197,228,137,185,224,112, 76,177,118,221, 34,235,254,253,199, 31, 43, 26, 34, 99, 42, 74, 39,203,178,188,107,215,174, 97, -208,160, 65, 56,120,240, 32,135,166,105, 60,124,248, 16, 34,145, 8, 35, 70,140, 64,189,122,245, 56, 34,145, 8,119,238,220, 65, -110,110, 46,169, 40,157, 55, 46,221, 88,150, 19,125,125,126, 50,185,216,105,231,129, 67, 24, 51,104, 0, 28,216,152,219,230,110, -100, 89,135,238,205,190,103,233, 26,221, 36,166,190,150,238,245,187,131,199, 55,193,164, 89, 75, 16,249,226,140,101, 65,222,179, -137, 68, 31, 95, 3,192,212,143, 57,217, 35,125,245, 27, 15,220, 11,188, 82,243,113, 45,105,224,184,135, 0,158,253, 41,176, 92, - 57,132,210,155, 23, 91, 47,223,188,121,131,232,232,104,112, 56, 28, 40, 20,138, 15, 22,245, 45,205, 25, 16, 16, 48, 78,175,215, -127, 15, 0,106,181,122,175,189,189,253,200,159,127,254,217,186,120, 9,162,210,150,171,204,236,220,172,123,143, 95,190,158, 62, -174,111,235, 91, 15, 94,196, 91,248,245,140,203,126,122, 50,167,172,252,108,210,164,137, 37,159,166,119,252,180,122, 33,209,199, - 92,131,192,187, 53, 56, 38,238,208,107, 19,161,204,146, 67, 25,155, 4,245,246, 77,112,157,240, 13, 86,175,252,129, 12, 26, 58, -106,135,155,155,219,241,232, 82, 22,188,255,196,116,111, 35,167,145,211,200,249,121,114,254,235, 4, 22, 33, 84,174, 94,207, 8, -120,182,118,202, 81,253,219, 53,184,124, 53,228,137,216,198,140,211,177,117, 64,171, 71,207, 99,239, 19,138,104, 9,161, 12,242, -235,112,118,118, 30,176,112,225,194, 6,102,102,102, 96, 24, 6,230,230,230, 72, 75, 75,131, 90,173, 70, 78, 78, 14, 84,121,185, -208,228,229,226,105,252, 59, 52,107,213, 26,237,155, 52,246,190,160,213, 14, 0,112,176, 60, 78, 61, 69,179,214, 1,141,208, 47, - 38, 3,140, 70,141, 35,174,214, 37, 86,171,129,239,178, 65, 8, 1,163, 81,227, 66,112, 93,240, 77, 36,240,155,185,176,218,153, -149,148,148, 20, 86,171, 86,173, 11,157, 59,119,238, 60,110,220, 56, 42, 57, 57,249,162,189,189,125,179,148,148,148, 74,135, 71, -237,178, 44,135, 13, 27,219,160,142,141, 5,133, 51,119, 46,162,177, 87, 47,136, 5, 92,164,101, 43, 64, 64, 16,243,246, 42, 24, -157, 9,158,190,122,135,166,190, 98,180,108,100,225,156,255, 71,230, 88,148, 63, 92, 70,178,178,178,144,154,154, 10,173, 86, 11, -173, 86,139,190,253,250,225,215,125,251, 32,151,203,161, 80, 40,160, 86,171,161,215,235, 65, 81, 20,174,156, 61,130,248,216, 87, -104,218,164, 9, 80, 65,196,111, 46, 13,221,218,111, 7,115, 0,128,111,106,171,201,203,203,131, 68, 34,129, 60, 43,137, 55, 99, - 77,137,101,139,119,253,250,117,132,134,134, 66, 42,149, 26, 84,143,202, 66, 52,176,227,173, 94, 63,191,243,137, 19,118,119, 79, -156, 96, 30,156, 57,147, 32,200,203,219,110,200,127,131,131,253,251, 78,153,220,213, 83, 36, 20, 33, 33,110, 3,188,188,120,152, -241,141, 53,150,175, 76, 7, 0, 76,153,236,140,134, 65, 54,200,205, 62, 10, 27, 59, 55,204,152,222,211, 45, 63,159,253, 10,192, -222,138,235, 59,153,252,236,217,179, 72,123,123,123, 78, 88, 88, 24,248,124, 62, 68, 34, 17, 68, 34, 17,132, 66, 33,146,147,147, -161, 86,171,113,248,240, 97, 93,209, 16, 98,185, 40, 26, 6,236, 60,189,179,227,133,215,161,251, 90, 56,209,177, 79,251, 76,106, -254,238,217,131,176,188,203, 87,238, 46,213, 41,133,241,217, 9, 87,103,215,105, 24,102, 51,113,230, 98,108, 90,189, 16,175, 31, -222,202,180,175,153,187, 89, 68, 84,123,131,191, 40,195, 42,214,122, 49,103,226,130,254,186,113,195,251, 88,156,177,191, 55,238, - 60,135,164, 37,167,135,174,193,219, 48,133,160,110,192, 80, 15, 87, 74,125,237,218, 53, 81,203,150, 45,161, 84, 22, 46, 25, 71, -211, 52,246,239,223,207,232,116,186,235,101, 90, 45,181,218,239, 67, 67, 67, 29, 21, 10, 5, 6, 14, 28, 56,101,209,162, 69, 18, - 46,151, 91,248,124,233,245, 31, 88,174,150,173,255,245,210,180,239, 55, 95,191,116,112,165,116,217,156,145,173,135, 76,250,225, - 58,128,139,101,241,234,116,186,125, 27, 86,126, 71, 11, 44,180, 32, 13, 59, 64,147,162,192,251,157, 99,160,206, 85,194, 99,233, - 98, 0,124,168,181, 20,206,245,232, 11,202, 74,138,209, 45,154,113,182,223,186,179, 15, 64, 79, 99,211,108,132, 17, 70,252,255, -183, 96, 49,204,173, 55,177,239,186,116,104, 31,236,124,246,230,243,199,227, 70,116,237, 72, 81, 20,121, 18,254,254,166, 91, 45, - 7,155,235, 55,110,177, 12,195,220, 50,228, 98, 92, 46,183, 91,243,230,205, 57, 89, 89, 89,144, 74,165, 72, 75, 75, 67, 98, 98, - 34,180, 90, 45,148, 57,217, 80,231,229, 66,157,155, 3,189, 60, 15,209, 33,143,224, 85,211, 89,112,181,208, 9,254,160, 33,252, - 31, 91,168,138, 23,253, 5, 33, 16,152,154, 64, 96, 98, 82,249, 74,240, 31, 65, 42,149,246, 48, 51, 51,155,157,151,151,119, 62, - 49, 49,113,153, 90,173,158,248,227,143, 63, 62, 94,178,100,137,205,156, 57,115,204,102,205,154,117,196,197,197,197,191, 50, 63, - 36, 83, 43,125,223,198, 13,234,210, 81,239, 95, 32,200,163, 47,106, 75,155, 35, 38, 49, 7,153,121, 42,100,228, 40,224,233, 49, - 19, 41, 25, 5,200,145, 43,241,252,245,239,112,114,168, 67,209,220,232, 78, 21, 8, 44,164,164,164,124,112,207, 7, 15, 28, 64, - 65, 78, 14,220,220,220,224,237,237, 13, 91, 91, 91,188,127,255, 30,119,238,220,193,144,254, 95,130,203,237,131,212,212,212, 10, -239,119,111, 24,203,149, 74,165,161, 50,153, 12, 97, 97, 97,136,142,142, 46,115, 88,245,143, 63,254, 40,124,241, 58, 56, 24,156, -151,246,246,246,223, 81, 20,213, 31, 0, 13, 32,158,146, 74,235,218,218,218,218, 55,235,217, 19, 57, 92, 46,253,243,245,235,132, - 99,110,110, 2, 32,187, 50, 46, 51, 51,116, 13, 10,106,206,207,206,218, 13,160,208, 40, 53,114,132, 45, 58,119,178, 7,161, 4, -144, 58,154,130, 80, 2, 16,194, 71,129,252, 26,124,234,249,242, 76, 77,143,119,171, 72, 96, 21, 59,180,215,171, 87, 15,227,199, -143,199,201,147, 39,177,119,239,159,167,247,233,211, 7,189,123,247, 70,126,126, 62,236,237,237, 57, 50,153, 44, 38, 48, 48,176, - 82,199,119, 51, 55,178, 76,165,121, 53,223,194, 93,146,166,135, 77,211,124,173, 32, 99,225,154,152,133, 0,214,118,118,115,219, -169, 97,110,197, 70,189, 56, 99,249,246,241,141, 76, 89,148,220,117,231,185,152,114,125,176,110,222, 4, 99,239,123, 83,243,101, -167, 86,156,158,221,219, 20, 56, 57,219,123,252,188, 89,189, 63,211,201,122,153, 75, 77,231, 33, 11,127,156,173, 25,218,171,133, -102,246,140,201,220,122, 62,222, 36, 55, 55, 23,135, 14, 29,210, 93,184,112, 33,137, 97,152,105,229,208,210, 69, 66, 11,253,251, -247,151,136,197, 98,196,199,199,195,203,203, 11, 12, 83,152,183, 73,105, 25,207,239, 62,126, 17, 49,125,124,191, 86,191,159,190, -254,234,210,141,144, 87, 61, 59, 53,243, 35,132,117, 41, 47,173, 52, 33,141,125,124,125,193,178,137,160,185, 30, 72,216, 63, 18, -202,140, 60,168,228, 74, 80, 92, 9,212, 90, 26, 26,134, 64,224,219, 8,111, 78,158, 70,221,193,245,192, 33,164,153,177, 89, 54, -194, 8, 35,254, 63,160, 82,181, 65, 43,213,203,191,157, 61, 31,150,230, 34,243, 70, 1,238, 14,167, 46,222, 12,185,117, 47,228, -149, 75, 13, 27, 91, 86,171,182, 92,181,110,147, 51, 41, 80, 24,234,228,237,109, 99, 99, 3,141, 70,131, 55,111,222, 32, 33, 33, - 1, 26,141, 6, 58,185, 28,170,236,108, 40,179,178,160,151,231,129,167,215, 67,145,150, 10, 75, 33, 31,248,115,134, 97, 69,166, -202, 63,197, 84, 25,130,139, 16, 2,145,153, 25, 4,166,166,160, 56,180,193,153,227,232,232, 24,232,239,239,127,248,218,181,107, -193,205,155, 55, 95,234,226,226, 98,158,156,156,252, 62, 37, 37,165,221,234,213,171, 85,182,182,182, 24, 50,100,136,167, 86,171, - 29, 86, 25, 23, 79,160,106, 80,211,222, 29, 53,236,191,132,212,166, 49, 50,115, 85, 72,205, 86, 32, 37,163, 0,135,142, 15,192, -229,243, 3,241,228,206, 87,120,243,112, 36,210,243,205, 32,180,106, 3,128,173, 95, 17,231,189,123,247,176,109,219, 54,108,219, -182, 13, 91,183,110,197,166, 77,155,144,149,149,133,250,245,235, 35, 46, 46, 14, 23, 46, 92, 64, 82, 82, 18,108,108,108,240,228, -201, 19,108,223,190, 29,143, 30, 61,170,114, 37, 81, 42,149,224,153, 88,107,214,126, 59, 24,107,191, 29, 12,134, 43,209,148, 18, -224,134, 87, 54,138, 26,158,212,179,103,131, 36, 11, 11, 31, 95, 95,223,206,253,251,247,119, 13, 14, 14, 46, 57,238,230,230, 86, -147,195,225, 36, 75,165,210, 93, 82,169,212,191, 98,229,207, 6, 88, 90,121, 67,173,138, 40, 42, 99, 46, 8, 17,162,237, 23,175, -208,172, 69, 8, 52, 90, 30, 40, 34, 0, 69, 9,161,211,101,192,204,212, 30, 44, 75,234, 87,146,196, 46, 23, 47, 94,196,182,109, -219,240,246,237,219, 18, 97,217,173, 91,183,201,131, 6, 13, 58,174,215,235,113,246,236, 89,156, 60,121, 18,181,107,215,134,159, -159, 31, 52, 26, 77,151,202,238,123,225, 79,178,251,191,175,187, 48,144,171,181,244, 23,138, 92,106, 67,110,210, 99, 98,107, 91, - 9, 0, 92,136,142,206,179,171,153,187, 66,158,247, 44,206,194, 57,127,101,101, 14,238, 44,187,144, 9,141,138,120,240,251,137, -139, 57,169, 41, 89,220,128, 6,245, 20,203,151,204,228,185,212,174,187,106,225,236,241, 14,137,185,194,236, 47,166, 92,136, 56, -126,241, 81,254,208, 17, 99,116,163,198, 78, 82, 94,184,120,229, 4,195, 48, 13,202,155, 65,200, 48, 12,146,146,146,240,242,229, - 75,196,196,196, 32, 45, 45, 13,233,233,233,200,203,203, 43, 25, 86, 20,231,229,158,219,180,231,204, 83,137, 72, 36, 14,110,224, - 94,243, 97, 88,120,170, 68, 36, 18,187,215,174,233, 65,200, 98,170, 28, 94, 11,161, 72, 8,128, 32,239,197, 45, 40, 51,243,161, -200,206,135, 50, 43, 31, 42, 13, 13,165,138,130, 66, 77,193,166, 69, 7,228,203,149, 80,102,100,129, 97, 89, 75, 99,179,108,132, - 17, 70,252, 43, 44, 88,233,233,145,249,102,182, 62,189,191,153,245,253,133, 3,191,252,108,167, 82, 21,196, 89, 91,154,232, 77, -196,124,155, 81,227,126, 64, 94,126, 86,175,252, 76,195,103, 61,101,101,101, 33, 54, 54, 22, 34,145, 8, 60, 46, 23,122,133, 2, -122,133, 28,138,172, 12, 80, 26, 21,120,122, 61,172,196, 34,212,146, 58,192,197,190,114,235, 8,205,232,137,236,202,121, 92, 26, -218,235, 47,195,130, 23,155,122, 66, 96, 34,129,208,194, 18,205, 78,222, 46, 20, 58, 60, 30,176,176,242, 69,218, 29, 28, 28,108, -164, 82,233,233, 77,155, 54,241, 50, 50, 50,240,242,229,203,167,239,222,189,203,177,178,178, 50,229,114,185, 76, 84, 84,212,213, -136,136,136,110,117,234,212, 1,203,178,110,149,241,229,229, 72, 52, 90, 45, 11, 89,234,123, 36, 36,189,132,153, 73, 13,176,116, - 13,164,102, 22,128,192, 30, 58, 85, 36,244,218, 66,119, 43,149, 34, 1, 5,106,195,214,237,213,104, 52,208,104, 52,208,106,181, - 80,169, 84, 24, 58,116, 40,238,222,187,135,131, 39,255, 64,108,116, 36, 60,107, 59,224,171,175,134,194,223,223, 31,143, 31, 63, -174,118, 69,105, 50,251,210, 75,145, 72,132,173, 91,183, 66, 44, 22,127, 32,110, 13, 20,171,107,219,181,107, 87, 55, 82, 46,199, -203,136, 8, 52,234,215, 15, 0,112,231,206,157,146,115, 20, 10, 5, 6, 15, 30,204,143,141,141, 29, 21, 17, 17, 49,202,209,209, -113, 93, 82, 82,210,140,242, 56,207,157,187,143,241,227,195,145,150, 86,232,135,125,232, 64,189,146, 99,111, 99, 53,232,212,181, -112,228,202,194,194, 2,235,214,213, 55, 40,157,122,189, 30, 59,118,236, 40, 25, 22, 4, 0, 14,135,211,108,250,244,233,189,203, - 58,223,199,199,167, 82,206,233,253,156,133, 79,222,139, 38,154,215,117,169,103,102,227,139, 12,109, 88,253,176,196,164,201,211, -251, 57,111, 88,119, 36, 65, 41, 34,170,189, 68, 31, 95,131, 35, 84,238, 51, 36,141,209, 23, 54,170, 45, 92, 70,236, 75, 78,203, -157, 55,105,204, 96,107, 51, 11, 59,249,174, 77,203, 45, 41,154, 98, 79,135,104,178,235,185, 90, 91,244,104,252, 83,254,248,111, - 22,132,169,117,241,147, 16,127, 58,178,162, 80, 21, 12,195, 64, 38,147, 33, 45, 45, 13,113,113,113, 72, 79, 79, 47,122,246,211, - 75,134, 8,171, 3, 66, 8,212,113,113, 72, 57,185, 11, 14, 67,134,194, 99,201, 18,232, 25, 14,148, 5,122, 28,109,217, 14,185, -217, 10,168, 25, 2,139,192,166,232,112,246, 54, 8,163, 7, 30,220, 51,182,202, 70, 24, 97,196,191, 67, 96, 1, 64,110, 90,120, -140,117, 45, 95,153, 92, 33, 23,219,219,217,170,196, 66, 1,147,147,155, 71,135, 61,127,170,201, 79,122,243,186, 10,215,123, 21, - 30, 30, 94, 63, 33, 33, 1,113,239,223, 67,167,144,131, 82,169,193, 42, 11,208,190,121, 83, 8, 1, 8, 41, 2, 30,163, 1,135, -230, 35, 47, 63, 23, 0, 94, 85, 70,202,104,181, 31, 52,234,132, 16, 16,138,130,208,196, 4,124, 83, 9, 4,102,166, 31, 88,180, - 12,129, 72, 36,250,125,251,246,237,142, 14, 14, 14, 88,183,110, 29, 28, 29, 29,189,218,183,111, 95,208,170, 85, 43,145,141,141, - 13, 60, 60, 60, 16, 20, 20,132,235,215,175,131, 16, 18, 93, 25,159, 78,205, 15,125, 21,171,171,145,147,247, 4, 15,194,126,133, - 86,173,133,155,199, 92, 40,180,214,144,216,142,130, 82,125, 26,250,236, 27, 0, 0,190, 89,107, 36, 39,167, 3, 32, 47,170, 82, -152, 44,203,226,217,179,103, 56,112,234, 38, 28,107,121, 35, 46, 42, 2, 17,215,175,226,174,173, 53, 92,124,234, 65,171,213, 26, - 44,136, 12, 61,207,208, 23, 48, 33,100,240,152, 49, 99,144,205,225, 0, 93,187,130, 23, 19, 3,141, 70,131,198,141, 27,163, 97, -195,134, 0,128,198,141, 27,131,166,105,212,173, 91, 23,214,214,214, 56,118,236,216, 96, 0,101, 10, 44,150,144, 39,140, 62,195, -203,213,213,181, 68, 96,237,251, 53, 13, 97, 33, 95,128,128,143,141,155,254,140,202, 80,179,102, 77, 36, 39,199,130, 16,182,178, -252, 60,223,181,107,215, 46,150,150,150, 24, 57,114, 36,132, 66, 33,122,245,234, 5,165, 82,217, 31, 0, 86,172, 88,129,239,190, -251,174,208, 42,181,112, 33, 22, 45, 90,132,130,130,130,114,135,134,127, 93,239, 43, 77,205,100, 70,217, 59, 56,245,106, 99,227, -210,160,109,199,246,168,227,222, 22,109, 59,198, 1,192,143, 86,156,119,253, 87,207,175,127,194,166,134,213,238,203, 23,175, 44, -108,222,170,237,188, 57,227, 44,151,173,216,158, 85,169, 79, 99,206,251,189,121,175,249, 3,214,255,188,237,215,245,223,127, 55, - 85, 24,151,166,206, 74,204, 98,243, 77, 4, 28, 19, 55,123, 98, 50,121,214,210, 88,153, 44,102, 6,226, 47, 70, 26, 82,134, 49, - 49, 49, 37, 62,123, 74,165, 18,114,185, 28,241,241,241, 37,229,171,144,152,117,154, 52,162,187,159, 92,161, 40,120,248, 60, 42, -110,254,148, 33, 77,228, 10, 69, 65,212,219,184, 72,150,253,137, 41,167,204,179, 11,228, 5, 86,170, 28, 37,114,158,190,134,117, -219, 90,208,232, 8, 84,122, 61,178,210,243,160,214, 1, 90,154, 11,231,190, 95, 65, 11, 14,114,211,146, 65, 17, 98,140,135,101, -132, 17, 70,252,123, 4, 22, 33,132,248, 53,168, 37, 93,189,112,136, 51,163,211,121,166,166,167,232, 56, 28, 1,183,134,185, 34, -169, 42, 23,211,106,181,103,111,223,190,221,179,121,243,230,130,168,231, 79,161,206,201,129, 58, 39, 27, 92, 70, 7, 43, 81, 16, - 40,141, 10, 68,173,134,147, 23, 3,101,158, 8,247, 30,189,214,106,181,218,179, 21, 10, 1,176, 44,163, 43, 20, 88,132,162, 62, - 24, 42, 20,152,155, 66, 96, 98, 2,129,169,105,153, 67,136,229,193,222,222, 94,220,185,115,231,118, 1, 1, 1, 96, 89, 22,171, - 87,175,134, 70,163,225,107,181,218, 18,139, 81,126,126, 62,142, 30, 61,138, 95,127,253,245,174,185,185,121,165, 83,203, 25,157, -234,194,181, 59, 79,187, 12,233,213,134,127,229,198, 78,104,213, 12,114,149,102,200, 87,168,144,175,228, 66, 37,232, 8, 66,110, -131,162, 5,104,234, 95, 23,215,238, 68, 42,245, 90,205,197,170, 10, 33,165, 82,137,248,184,119, 72,136,142,132, 73,110, 50,108, -205,196, 40,136,137,132,255, 87,195,160, 86,171, 43,189,247,225, 1, 68, 59,189, 62, 56,235, 58, 83,224,153, 88,107,154,204,190, - 84,110,168, 8, 19, 19,147, 42, 13, 17,166,167,167,227,204,153, 51,104,220,184, 49, 90,181,106,133,196,196, 68,196,196,196,160, - 75,151, 63, 71,217,158, 62,125,138,176,176, 48,184,185, 85,108, 20,204,205,101,207,103,102,190,233,215,163, 71, 15,222,131, 7, - 15,192,178, 44,220,221,205, 96,102, 42, 1,161, 4,240,246,182, 3, 80,168,253, 91,183,110, 13,181, 58, 81, 39,151,227,124, 69, -156,161,161,161, 93, 3, 3, 3,235,104,181,218,200, 86,173, 90,113,222,188,121,131,190,125,251,226,208,161, 67, 0,128, 57,115, -230, 96,206,156, 57, 31,252, 39, 63, 63, 95, 89, 30,159,103, 3,175,153,117,116,150,173,132, 34,151,218,102, 54,190,168,227,222, - 22, 0,240, 69,183,145,168, 83,183, 38,114,211,159,213, 86, 42,222,245,226,113,178, 44,159,109, 76, 12, 23,117,173, 63, 66,153, -122, 35, 10,128, 33,129,123, 89, 69,212,161,148, 56,238,208,195, 39, 79, 95, 24,215,165,219,151, 92,173, 94,167,171, 95,139,107, -113,228,196,185,212,196,247,113, 63, 33,238,226,139,146,199,164, 98,129,165,207,205,205,133, 68, 34, 65, 76, 76,140,170,123,247, -238, 2,133, 66,129, 55,111,222,148, 8, 44, 59, 27, 43,159,102, 13,235,123, 45, 91,255,235, 37,137, 64, 32,232,216, 58,200, 59, - 60,234,125, 2,203,146,119,229,242,178,236,131, 55,175, 94,119,181,115,172, 11,217,205, 7, 16, 55,239, 2,149,138,130, 82,205, - 64,165, 3,116, 52, 15,230,126,193, 16,185,122,131, 5,240,234,249, 83,232, 88,246,174,177, 89, 54,194, 8, 35,254, 53, 2,203, -198,198,198, 46, 32, 32,200,109,231, 47,135,193,178, 44, 94,135,173, 65, 86,106, 4, 22,252,120,223,205,217,217,185, 85, 66, 66, -194, 77, 67,120, 18, 18, 18, 14, 29, 59,118,108,134,175,143, 79, 64,109,103,103, 60,125,247, 22, 60, 86, 15,158, 94, 15, 74,163, - 2, 71,175,134,115,125, 61, 40, 98,130,164,164, 92,108,191,120,245, 69, 66, 66,194,161, 10, 95, 14,132, 70,141,238,125, 48,232, -139,174, 96,181, 26, 92,110,225, 3,161,169, 9, 4, 22, 22,104,122,244, 6, 8, 33, 96,117, 90,188, 95,254, 45,184, 18, 19, 88, - 53,169, 60, 20, 80, 74, 74, 74, 65,221,186,117, 67, 34, 34, 34, 26,122,122,122, 98,241,226,197,136,143,143, 7,203,178, 72, 77, - 77, 85,166,165,165, 37,102,100,100,188, 35,132,156,144,201,100, 59, 13,137, 20,158,106,153,181,239,202, 31, 87,103, 6,250,251, -184,127,209,106, 17,206,158, 93,136,172,156, 92, 20,168,185,200, 83,104, 32, 87,176,112, 50,115, 71, 35, 95, 95,164,101,170, 17, -245, 50, 52, 33,157,103,181,163, 42,214, 43,138,162,240,244,233, 83,184, 74, 77, 17,121,251, 38,108,196, 92,248, 73, 29, 32,109, -214, 28, 49, 49, 49,134,137, 96, 61, 56,165,103, 11, 90, 88, 88, 32, 39, 39,231, 3, 33, 39, 22,139, 33,149, 74,145,155,155,139, -163, 71,143,130, 53,236,165,168, 85,171,213,240,242,242,194,227,199,143,113,245,234, 85,180,109,219, 22,173, 90,181,194,179,103, -207,112,249,242,101,132,133,133,129, 16, 2,107,107,235, 98,223,159,114, 35,218, 63,122,244,244,136,137, 9,153, 59, 98,196,132, -122, 67,134, 12,193,177, 99, 7, 49,114,132,103,145, 99,187, 0, 95,118,247,196,146,165,143, 17, 28,220, 26,182, 54, 60, 92,185, -250, 50,150,195, 49,255,213,128,124,252,249,231,159,127,230, 40, 20, 10,228,231,231,195,196,196, 4, 25, 25,133,225,168,202,177, - 96,149, 27, 88,237,121,232,171, 53,217,121,108, 22,155, 31,214, 43, 83, 23,214,160,109,199,120,124,209,109, 4,174,156,221,131, -107,151,174,194,138,243,238, 45, 36,121, 23,210,223,166,231, 38,201,221,183,121, 7,142,166, 19,228,151,182, 77,233, 97, 73, 59, - 58, 50, 71,230,108,201,201,174, 32,157, 44, 33,132,100,134,239, 63,125,130,197,151, 77,155, 4,215,173, 95,211,145,159,149,158, -202, 30, 61,117,225,133,230,237,177, 51,197,194,202,128, 85, 17,150,108,216,176,225,123, 0, 96, 24,102,239,250,245,235, 71,207, -156, 57,211, 86, 38,147,149, 8,172,212,244,204,107, 77,187, 78,214,103,100,231,168,119,175,159,213, 87, 36, 20,240,231,175,216, -125, 67, 75,227, 65,185,141, 11,135, 51,108,238,214,223,210,142, 29,217, 67,219, 8,121,184, 59,103, 33,162,175, 94,135,134,226, -161,227,229,135, 80,107,244,200, 77,203,192,245, 81, 19, 97,225, 96,137,243,233, 81,250,156,188,220, 97,198,102,217, 8, 35,140, -248,255, 0,131,166,212,165,167,167,167,222,186,245, 16, 55,206, 46,195,205,179,203,240, 50,236, 41,100,137,106, 36,166, 40, 97, -102,102,118,191, 2,203, 87,251,143, 95, 10, 74,165,178,247,250, 13, 27,146,197, 18, 9, 90,182,107, 7, 7, 91, 59,136,121, 92, -208, 58, 6, 52,225, 34, 63,205, 2, 81,207, 21, 88,126,226,108,170, 66,169,236,253,241,203,225, 99,206, 82,251, 1, 66, 32, 50, - 51, 5,223,196, 4,194,210, 86, 43, 66,192, 51, 53, 3,207,212, 12, 52,143, 95,105, 58, 1,160,160,160,160,207,216,177, 99,179, -242,242,242, 48,104,208, 32, 60,120,240, 32,236,226,197,139,102, 87,175, 94, 21, 61,127,254,188,174, 76, 38,235,144,152,152,184, -189, 60,113,245,151,123,191,113, 67,199,234, 52,125, 54,111,221,153,169,208,218,163,123,143,205, 48,227,103, 64,171,211, 3, 44, - 11, 39, 91, 19, 52,106,246, 45, 82, 85, 77,113,246,204,217, 44, 70,167,236,243,241,146, 57,165, 57, 89,150,101,173,173,173, 63, -176,202, 81, 20,133, 27, 55,110,160, 95,223, 62,232,216,171, 39,108,107,187,194,174,125, 23,116, 28, 61, 30,219,183,111, 7, 69, - 81,176,178,178,250,192,162, 81, 94,126, 22, 35, 39, 39, 7, 46, 46, 46,120,184,186, 75,189, 11,211,189, 2,106, 70,255, 28, 32, -126,178,182,222,181,107,215,176,118,237,218,252,200,200,200,117,238,238,238,223, 86,150,159,132,144,121, 63,254,248,163,226,253, -251,247, 48, 49, 49,129, 78,167,195,221,187,119,177,101,203, 22,172, 93,187, 22, 97, 97, 97,176,182,182, 70,221,186,117, 65, 81, - 20,226,226,226, 20,132,144,121, 21,212, 37, 38, 47,143,211,231,242,229, 19, 25,221,187,183,196,238,221,155,224,224,208, 20, 92, -142, 3, 56, 92, 91, 72, 76,188,176,107,231, 74,116,237, 18,136, 87, 17, 79, 50,243,243, 57,125,110,220,184,161, 51, 32,157,154, -231,207,159,227,248,241,227, 88,178,100,137,110,241,226,197,200,201,201, 41,177, 96, 21,175,146,190,104,209, 34, 0,128, 74,165, - 18,148,199, 57,122,214,243,196,153,203, 94, 44, 73, 73, 78,108,124,243,250,253,193,215, 46, 93, 69,108,212, 53, 92,187,116, 21, -183,175,221,155,147,146,156,216, 56,160,145, 7,175,247,232, 73, 51,247, 29, 63, 70,155,152, 57, 98,223,241, 99,244,160,201,211, -126, 8,234,216,118,158, 1,101,196, 2, 96,243, 83, 83,190,251,113,205,207,249, 58,141,146, 90,253,211,102,153, 34, 45,105, 30, -138,167, 86,150, 99,189, 42,205, 25, 19, 19,179,253,237,219,183,210,183,111,223, 74,223,191,127, 63, 47, 49, 49,177,229,242,229, -203,211,138, 4, 87,161,192,122,121,234,254,171,219,123,126,180,179,177, 20, 53,109, 88,207,115,221,246,163, 55,226,226, 83,126, - 43,142,129, 85, 86, 58,239,223,191,159,165,210,234,198,126, 59,107, 17,155,157,173,134,231,212, 57,208, 9, 76,160,210, 1, 26, -134,134, 6, 28,132, 45, 91, 7, 83,107, 83,220,101,179, 88, 21, 77,141,137,254,200,201,191,178,250, 89, 29, 24, 57,141,156, 70, -206,207,147,243, 95,105,193,114,114,114,106,217,227,203,246,104,221,109, 62, 88,150, 69, 68,232, 42,100,165,189,134,147,131, 0, - 49,113,185, 77, 0,220, 52,244,130, 73, 73, 73,113,142,142,142,141,151,109,216,120,188, 99,112, 35,111,119, 39, 71,129,133, 75, - 45, 72,236,236,144,158,158,134, 7, 33,145,218,173,151,175,189, 80, 40,149, 6, 45,149,195, 48, 12,203, 48, 12,120, 60, 30, 88, -154,134,207,148, 57, 32, 20, 5,138,203, 41,177,236,128, 16,152, 5, 54, 3,225,114,161, 53,208,103, 72, 38,147, 37, 56, 57, 57, -245,153, 60,121,242, 31,123,247,238,165, 90,183,110,237,127,250,244,105,230,239,100,118,202,243, 19,225,246, 13,122,181,218,248, -243,150,163, 1, 65,141,107,185,212,118, 17, 52,117, 54,135, 70,171, 71, 74,106, 6,110,222,123,169,138, 12,127,146,200,106, 52, -125, 82,195,203,143,226, 14, 0, 90,173, 54,206,217,217,217,126,241,226,197,208,233,116,208,233,116,208,235,245, 72, 79, 79,199, -253,251,247,209,160, 97, 48,188, 71,140, 66, 90, 90, 26, 54,110,220, 8,103,103,103,252,248,227,143,200,203,203,195,173, 91,183, -202,205, 87, 46, 13,221,224,193, 69,113,176, 56,208,173,235,214,237, 70,189,122,245,154, 55,214,166,242, 22,110, 44,180,108, 77, - 29, 51,152,119, 35,238,198, 17,129, 64,176, 61, 54, 54,182, 66,127, 33, 55, 55, 55,190, 82,169,244,103, 89,150,206,205,205,221, -160, 84, 42,135, 79,159, 62,221,113,197,138, 21,112,119,119, 71,122,122, 58, 36, 18, 9,220,221,221,145,151,151,135,216,216, 88, -189, 70,163,217,166,215,235,151,164,164,164,164, 85,196,253,232,209,163, 55, 1, 1, 1,141, 83, 83,182, 30,159, 48,190,163,187, - 86, 23,196, 55, 51,107, 1,150,213, 34, 59, 43, 1,192, 51,205,137,147, 87,163,179,179,233,222, 33, 33, 33, 81, 6,245, 56, 40, -106,252,250,245,235, 81,188, 84, 78, 98, 98, 98,137,233,175, 44, 11,150, 33, 88,119, 36, 65, 9,224,192,234,111,154,126,147,155, -254,204,221,138,243,238,109,227,250,204,198,117, 71, 18,148,139,191,177, 88,150,254,238,102,100,146,252,210,182,125,199,143,209, -195,122,245,209, 59,155, 68,205, 17,218,177, 71,219,118,175,212,218,198,250,251,251,215, 32, 36,179, 78,106,198,235,144,145,163, -199,245, 55,231, 41,206,251, 57,103,184, 81, 53, 3,132, 97, 97, 97,111, 13, 93,211,243,163,186, 31, 41,149, 74, 91,174, 89,179, -230, 18,128, 15,124,204, 82,211, 51,175, 53,233, 54,137,205,206,206,121,146, 26,126,234,121,101, 92, 33, 33, 33,187,131,130,130, -240,213,208,145, 59,198,140, 26, 67,215,159, 50, 19,137, 55,174, 1,122, 45,146,111,223,132,200, 68,143,179,233,239,244, 5, 52, - 53, 54, 36, 36,196, 24,197,221, 8, 35,140,248,119, 9,172,132,132,132,155,110,174,206,151, 35, 35, 91,118,168,233,108, 91,216, -235,125, 43, 67, 98,138,234,178,161,195,131, 31,139, 44, 66, 72,208, 57,157,110,192,101, 46,183, 27, 41, 10,197,192, 86, 99,177, -231,130,130,130,148,198,141, 27,151, 19,123,225,199, 50,247,234,245,250, 4, 67,184, 19, 19, 19,111, 72,165,210,161, 77,155, 54, - 93, 33,147,201,142,167,165,165,201,255,110,134,167, 60, 63, 17, 78, 90,183,174, 23,242,240,214, 87, 97, 33, 15,186,177, 44,235, - 11,128, 16,138,250,115,177,231,240,202, 23,123, 86, 40, 20,227,230,207,159,191,157,195,225,212, 68, 81,224,208,226, 44,211,104, - 52,244,238,221,187,133,106,181,154, 6, 64,120, 60,158,206,196,196, 68,121,247,238, 93,157, 94,175,143,211,106,181,227,202,227, -221, 27,198,114, 63,222,231,227,227, 35,121,195, 65,126,241,239, 12, 5, 32,147,201, 86, 25,114,191,231,207,159,119,177,180,180, -236, 64, 8,233,203,178,172, 87, 94, 94,158,234,251,239,191,191,119,253,250,245,220,215,175, 95,119,106,209,162, 5,113,112,112, - 64,108,108, 44,155,159,159,127,148,162,168,121, 50,153, 44,198,208,252, 12, 11, 11,139, 33,132,248,201, 11,216,129,166, 38, 23, -187, 50, 44,252, 0,150, 16, 66,158,231,231,147,243,142,142,174,191, 93,185,114,196,224,169,112, 69,107, 11,246, 40,254, 29, 24, - 24,120,254,245,235,215, 93,138, 45, 88, 31,251, 96, 85, 9,226,252,211, 74,197,187, 62,196,164,224,196,186,159, 18,148, 0,176, -112,125,118, 14,128, 93, 83,122, 89, 49,175, 66,119,173,114, 50,139,154,245,211,137, 76,131,214,228, 11, 8, 8,112,165, 40,106, - 0,128,250,118,130,236,186,182,252, 28, 61, 33,108, 27, 66, 40, 27, 0,207,124,124,124,206, 2, 72,168, 78, 82,101, 50, 89, 36, -128, 90, 31,239, 79,125,121,234, 62,128,251, 85,225, 10, 9, 9,217,221,164, 73,147, 83,155,119,108,219, 71, 19,210,152,232,245, - 22,250,241,131,254, 92,236, 89,192, 31, 22, 98, 92,236,217, 8, 35,140,248, 55, 10, 44, 0,136,142, 73,232, 8, 0,238,238,238, -236,155, 55,111,192,178, 44,249, 59, 23, 46, 18, 80, 7, 97, 96, 16,209,242,240,226,197,139,128,255,100, 6,201,100,178, 3, 0, - 14,124, 74, 78,182,112,168,106,119,209, 86, 45, 36, 38, 38, 62, 7, 16,252,223,168, 36,225,225,225,242,225, 1,164,196,178,197, -165,161, 51,244,191, 29, 58,116,120,175,209,104,174, 2,136, 39,132, 88, 0,200,212,104, 52,151,210,210,210, 82, 28, 28, 28,130, -222,191,127,191,160,200, 18,185, 52, 57, 57, 57,164,154,117,137, 1,240,123,209,246, 73, 17, 26, 26,218, 85, 42,149,134, 89, 91, - 91,187, 41,149, 74,190, 82,169,228,149,214,254, 34,145, 40,205, 80, 46, 11, 83,178,151,199,201,178,182, 48, 37,127, 41,119, 43, - 39, 28, 83,200, 95,120, 90, 57,225, 88, 85,196,165,191,191,255,126,138,162,106,179, 44,107, 15,176,230, 44,139, 52,150,101,211, - 57, 28, 78, 98,120,120,120,226,231,210,208,220, 47, 20, 80,221,140, 77,174, 17, 70, 24, 97, 20, 88,229, 32, 42, 42,138, 24,179, -237,223,135,178, 44, 91,134,160, 40,194,253,189,162,237, 3, 20, 9,170,238,159,251,189,203,100,178, 79, 34,226, 71,207,122,158, - 8, 96, 90, 80, 25,243, 44, 22,110,204,204, 3, 48,179,205,151, 85,227,124,242,228, 73, 28,128, 56, 99, 13, 53,194, 8, 35,140, -248,188, 64, 25,179,192, 8, 35,140, 48,194, 8, 35,140, 48,226,211,130, 0, 40,115, 38, 64, 85, 86,202,174,206,108,130,202,248, -141,156, 70, 78, 35,167,145,211,200,105,228, 52,114,254,255,227,252,215,160,120,218,249,127, 98, 3,208,222,200,105,228, 52,114, - 26, 57,141,156, 70, 78, 35,167,145,243,223,182, 25,135, 8,141, 48,194, 8, 35,140, 48,194, 8, 35, 62, 49,202,117,114,119,117, -173,225, 67,233,153,102, 44, 75,209, 44,197,106, 73,174,226, 80,116,102,230, 7, 65, 0,107,214,172,105,193,165,208,157,176,172, -132, 16, 70,207,208,212,221,152,152,248,112, 67, 46,236,227,227,195, 3, 48,156,203,229, 54,215,106,181,142, 28, 14, 39, 73,169, - 84,222,225,114,185,123,195,195,195, 53,159, 83, 38, 53,111,222,124,208,209,163, 71, 45,186,117,235,166,210,104, 52, 58,129, 64, -192,249,253,247,223, 5, 35, 70,140,200,190,115,231, 78,181,102, 24,250,251,251,183, 93,189,122,117,157,182,109,219,162,121,243, -230,242, 46, 93,186,240,130,130,130,120, 51,103,206,140,125,242,228,201,181,170,112,217,219,219,251,112, 56,156, 95, 9, 33, 52, -203,178, 95, 21,205, 48,252,143,128, 16, 50, 8, 64, 63, 0,142, 0,146, 1, 28,102, 89,246, 64, 53,185, 58,161,208,201,221,183, -104,215, 51, 0,103, 88,150,189,248, 55,210,215, 9, 64,119,154,166,253, 1, 64,175,215, 63,249, 84,156, 92, 46,215, 15, 0,180, - 90,237,211, 79,197, 73, 8,241, 43,178, 36, 87,139, 51, 48, 48,240,123, 62,159, 63, 6, 0,212,106,245,110, 19, 19,147,229,101, -157,119,243,230, 77,117,121,161, 79,124,234, 16, 54,124,150, 87,225,247, 85, 17, 0,128, 74,127,199, 86,115, 22,241,118,111,182, - 44, 94,140,123, 85,237,201, 51, 82,169,244,235, 46, 93,186,204,190,120,241,226, 15, 9, 9, 9, 59, 96,132, 17, 70, 24,241,185, - 10, 44, 87,215, 26, 62,125,123,246,254,113,252,184, 9,132,166, 41,188,138,136,224, 76,156,242, 77, 7,111,111,111, 39,137, 82, -233,205, 2,140, 66, 36,122, 65,211, 84,226,214,205, 63,155,122,122,120,232,245,122, 6,219,182,111,237,236,234, 90, 99,110,101, - 34,203,206,206,174,142,163,163,227,134, 41, 83,166,216,117,232,208,129,178,183,183, 71, 66, 66,130,217,137, 19, 39,234,254,242, -203, 47,221,236,236,236,166,165,166,166,198, 86,231,134, 28, 29, 29, 91,216, 89,160,131,137,144,109,135, 92,130,124, 61,254, 72, - 85,225,114, 82, 82,210,237,234,102,146, 90,173,158, 92, 80, 80, 16,236,237,237,205,110,219,182,141,140, 25, 51,134, 37,132, 16, -133, 66,177, 23,213, 12,225, 32, 22,139, 55,183,109,219,214,189, 89,179,102, 49,247,238,221,235,194,178,236,249,190,125,251,186, -138,197,226, 40, 0, 30, 85,225,162,105,122, 79,120,120,184,159, 82,169, 68, 96, 96,224, 47, 0, 2,255, 67,226,234, 23,107,107, -107,102,235,214,173,219, 27, 52,104,224, 38,151,203, 11, 70,143, 30,221,145, 16,210,150,101,217, 81, 85,224,145, 0,216,104,110, -110,206, 91,182,108,217,131,214,173, 91,199,241,249,124,113,100,100, 36, 59,101,202,148,145,132,144,190, 0,166,176, 44, 43,175, - 42,167, 84, 42, 53, 91,185,114,229,235,128,128,128,123,124, 62,159,247,246,237, 91, 76,157, 58,117,252,223,225,244,242,242, 18, -175, 92,185,242,169,183,183,119,134, 80, 40,228,189,127,255, 30,211,167, 79, 31, 77,211,116, 95,134, 97,170,197,105,103,103, 39, - 89,190,124,249,243,160,160,160,108,161, 80,200,139,142,142,102,191,249,230,155, 49, 85, 73,103,171, 86,173, 6, 82, 20,181,248, -214,173, 91, 0,128, 38, 77,154,124,175, 86,171,231,127,124, 30,203,178,104,222,188,185,178, 85,171, 86, 99,110,222,188, 89,102, - 88,148,125,130, 89,131, 0, 96,230,247, 69,191,139,246,151,245,123,152,106, 85,149,235,188, 79, 29,194, 2,192,196,111,183, 12, - 45,252, 44,220,191,181, 40,116,239,230, 58,132,173,138,104,115,114,114, 26,215,168, 81,163,239, 30, 62,124,184, 47, 40, 40,104, -234,142, 29, 59,184,221,186,117, 91, 38,149, 74,221, 58,117,234,212,247,254,253,251,171, 35, 34, 34, 54, 27,155,120, 35,140, 48, -226,179, 18, 88,148,158,105, 54,126,220, 4, 50, 96,208,192,228,164,148, 84,198,196,212,124,208,225, 35, 71,196, 30, 30, 30,148, -242,231,159,161, 75, 75,131,126,198,140,166, 55,111,222,212, 78,154, 54, 67,161, 82, 22,236,113,180,183, 19, 31, 58,112,208,225, -248,177,163,205, 0,132, 87,100,185,114,116,116,220,112,236,216, 49,135, 58,117,234, 64,173, 86, 35, 35, 35, 3, 90,173, 22,189, -122,245,162, 27, 55,110,236, 48,114,228,200, 13, 62, 62, 62,189,171, 98,201,178,181,181,181,119,175,201, 61,187,112, 90,103,143, -182,173, 2, 37, 14, 78,181,129, 4, 6,137,177,111, 26, 94,125, 24, 58,165,185,155,115,100, 84,174,186, 91, 90, 90, 90, 74, 85, - 51, 41, 35, 35, 99,214,184,113,227,142,249,250,250,218, 10, 4, 2, 56, 56, 56,144,209,163, 71,167, 38, 37, 37, 45,254, 27, 98, -165, 48,175, 41, 74, 95,250,211,208, 5,169, 63,130,179,185,185, 57,204,205,205, 1,192,233,239, 84,136,126,253,250,209,113,113, -113, 99, 24,134,241, 46,189, 63, 41, 41,201,213,214,214, 54,229,237,219,119,126, 10,181, 38,104,194,164,185,139, 6,244,109,111, -113,239,222, 61,116,237,218,149, 34,132, 12,170,130, 37,107, 99,112,112,112,212,138, 21, 43,120, 81, 49,111,235, 61,120,252, 4, - 18, 33, 79,239,236,236, 36,120,246,236, 25,127,229,202,149, 41, 63,252,240,195, 70, 0, 35,171,144,244,141,253,250,245,203,154, - 54,109, 90, 65,100,244,219,218, 15,195,158,179, 38, 2,158,214,222,222,150,190,119,239, 30,119,243,230,205,100,222,188,121, 85, -230, 28, 61,122,116,210,180,105,211, 56,105, 25,217,117,147, 83,210, 89, 62,143,214, 88, 88, 88,112,174, 92,185, 66,237,217,179, - 71, 51,101,202,148, 42,115,118,237,218, 53,101,206,156, 57,220,136,168, 24,215, 7,161,207, 97, 34,224,106, 29, 28,236,232, 7, - 15, 30,208, 27, 55,110,212, 45, 92,184,208, 32, 78,150,101,183,173, 89,179, 6,167, 78,157, 2, 0, 28, 56,112, 0,174,174,174, - 31, 12,251, 43,148, 42, 80, 4,120,251,246,173,120,252,248,241,219, 80, 70,220,185,240, 89, 94,216, 7, 96,216,176, 97,201,134, - 89,161, 86, 85,173, 82,109,247,102,139,133,213,132, 9, 19,202,139,205, 53,212,167, 10, 34,171, 89,179,102,179, 15, 29, 58,100, -115,228,200,145,111, 79,156, 56, 81,220,105, 17,111,218,180,233,235, 30, 61,122, 96,212,168, 81,179, 1, 24, 5,150, 17, 70, 24, -241,121, 9, 44,150,165,104,154,166,144,154,146,174,253,162,125,135,145,155,182,108, 17,240,249,124,168,213,106,200,175, 93, 3, -171, 84,194, 66, 44, 70,151, 46, 93,184,245,235,215, 55, 27, 55,122,244,232,148,100,217,118,154,166, 28, 88,150,162, 43,185,230, -240, 41, 83,166,216,213,169, 83,231,131,157,122,189, 30,153,153,153, 48, 53, 53, 69,255,254,253,109,246,239,223, 63, 28,128, 65, -230,126,123,123,123, 23, 15, 87,251,187, 71,119,205,112,180,179,160,128,180,163,192,251, 55,192,239, 66,184,219,213,132,123,155, -214,146, 30,141, 26, 4,244, 95,189, 59,204,222,222,190, 89, 74, 74,202,187,170,100,210,219,183,111,239, 72,165,210,209, 10,133, -226, 20, 0,234,238,221,187,108, 92, 92,220,184,228,228,228,247,213,205,120,134, 97,144,157,157, 13,134, 97,232,162,223,197,159, -255, 88,101,232,215,175, 31, 29, 31, 31, 63,206,219,219,187,238,206,157, 59,145,154,154, 10,145, 72, 4,189, 94,143,166, 77,155, -214,108,215,174, 93,116, 90, 70,182,165, 86,167, 85, 39, 37, 68, 55, 58,184,227, 93,129,159,187,251,189,195,135, 15, 55,176,182, -182,238,111,136, 53,143, 16,210,201,212,212,148,243,227,143, 63, 82,166, 22, 14, 93, 27, 5, 75,185,207,195, 95,191,227, 9, 56, - 76, 78, 78,110,198,211,167, 79, 35, 22, 46, 92,216,226,244,233,211,201,132,144, 78,134, 12,153, 17, 66, 58, 57, 56, 56,152, 78, -157, 58, 85, 46, 50,181,105,222, 48,216,142,243, 34,252, 77, 34,151, 71,105,155, 53,107,214,230,254,253,251,123,102,204,152,225, -123,238,220,185,156,170,112,214,173, 91, 87, 52,109,218, 52,218,220,194,166,189,173,131,148,182,181,178,112, 3,128,152,152,152, -253, 41, 41, 41, 81, 19, 38, 76,104,120,238,220,185,188,170,112,218,216,216,136,231,204,153,195,169,237,234,217,199,213,221,147, -186,122,227,225,115, 62,159,210, 42, 20,138,204, 87,175, 94,189,153, 61,123,118,208,185,115,231,114, 13,225, 44, 40, 40, 48,117, -114,114,130,189,189, 61, 24,133, 2, 57, 57, 57, 56,126,252, 56,242,242,242,160,215,235, 33, 18,137,240,195,186,237,136,126,241, - 0,183,111,223,134, 66,161, 48,253, 20,245,196,103, 85, 4,194,199, 25, 46,174,182, 50,147,134, 86, 32,172, 80, 74,120, 13,197, -118,111,182,162,225,194, 82,150,171,132, 35, 71,142,216,185,185,185,161,117,235,214, 0,128,145, 35, 71,162,125,251,246, 56,117, -234, 20, 46, 95,190, 28,215,164, 73,147, 55,241,241,241,107, 19, 19, 19,183, 27,155,122, 35,140, 48,226,191,141, 50,157,220, 89, - 66,228, 47, 95,189,226,154, 88, 88, 12,221,180,101,139,128,203,229,226,253,251,247, 8, 15, 15, 71,193, 31,127, 64,113,239, 30, - 82, 82, 82,144,159,159, 15, 91, 91, 91, 44, 95,181, 74,194, 19, 73, 70, 70,189,121, 67,179, 20,171, 45,213,195,254,203, 84, 77, - 62,159,223,188, 75,151, 46,229, 58,215, 39, 39, 39,163, 67,135, 14, 28, 14,135,211,188,156, 94,251,213,143, 94, 90, 68,106, 75, -206, 28,217, 49,213,209,142,243, 28,120, 51, 29,200, 11, 3, 88, 21,160, 83, 3,113, 17,192,201,117,112,202,136, 34, 7, 38,247, -119,112, 18,241,206,144,143,204, 68,149, 77, 41,117,118,118,118,117,117,117,221,213,183,111, 95, 10, 0,154, 55,111, 78, 92, 93, - 93,119, 56, 59, 59,187, 86, 96, 93,168,144, 83,169, 84, 62,200,202,202, 66,183,110,221,172,155, 54,109,122,181, 91,183,110,214, -197,251,171,203, 89, 4,235,182,109,219,102,184,186,186, 30,112,113,113, 17, 24, 96, 5, 41,225,140,139,139, 27,227,229,229, 85, -119,231,206,157, 52, 77,211,216,185,115, 39, 14, 29, 58,132, 59,119,238, 32, 53, 53, 85, 60,125,250,116,139,179, 87, 31, 92,188, -123,231,209,233, 53,243,191,181,238,213,174,181,171,101, 78, 90,174,149,149, 85, 23, 0, 14, 6,166,179,251,252,249,243,111, 62, -121, 21, 99, 71,113,184, 60, 1,143, 43,178,181,177,168,229, 96,107, 89,215,201,218,178,174, 41,159,107,145,155,155, 27,123,242, -228, 73, 29, 74, 5, 33,173,140,115,245,234,213,175, 34, 98,226,173, 41,154,195,229,210, 92,190,133,185,137,245,151,221, 58,180, - 1, 0, 17, 77, 4,185,185,185,241,251,247,239,175, 18,231,138, 21, 43, 66,147,210,178,236,184, 60, 62, 71,192,227, 10,139, 15, - 88,154,153,216, 75, 4, 2, 81, 65, 65,193,251, 93,187,118,169,171,200,249,244,101,212,123, 27, 66,129,166, 64,184,150,150,166, -118,182, 22,166, 14,118,102, 38, 14, 66, 10,194,220,220,220,119, 7, 14, 28,208, 24,202,153,154,154,138,136,136, 8,212,104,216, - 16, 87,175, 94, 69,205,154, 53,209,191,127,127, 12, 28, 56, 16, 34,145, 8,109,155, 52,192,220,185,115, 17, 29, 29, 93,110,185, - 23,251, 67, 85, 4,169, 84,122,163, 42,117, 9, 40, 28, 22,172, 72, 92,125,204, 89,214,121, 31,115, 54,107,214,108,246,241,227, -199,109,214,175, 95,239,255,205, 55,223,196, 28, 63,126, 28,190,190,190,120,245,234, 21,156,156,156,112,240,224, 65, 76,154, 52, - 41,102,209,162, 69,254, 87,174, 92,145, 74,165,210, 89,213,124,142,170, 4, 35,167,145,211,200,105,132, 65, 22, 44, 45,131, 51, -147,167, 78,239,126,236,248,113, 49,159,207,199,219,183,111,145,154,154,138,115,103,206,232,207, 55,104, 80, 64,211, 52,219,251, -216, 49,211,254, 3, 7, 18, 46,151,139,186,117,235,162, 75,151, 46,162,209, 99, 39,164,114,228,138, 67,149, 20,138,157,173,173, - 45,190,251,238, 59, 44, 95,254,161, 63,238,240,225,195,177, 97,195, 6,152,154,154,130, 16, 98,103,200, 13, 56, 58, 58,246, 27, - 57,179,141,179, 89, 45,179, 20, 54,108, 31,151,208, 98, 43,208, 98,128,226, 1, 34, 17,160, 85, 3,106, 10,170,199,119, 50,217, - 54,155,115, 59, 6,228, 57, 37,171, 15,246, 3,112,216,208, 76,178,177,177, 89,112,244,232, 81,219,153, 51,103,178,121,121,121, - 36, 37, 37,133,157, 61,123,182,237,252,249,243, 23, 0, 24, 86,157,140,151,201,100, 75, 71,142, 28,217,113,247,238,221,246,125, -250,244, 49, 47,234,129,167,200,100,178,165,127,167, 64,185, 92, 46,125,237,218, 53,171,109,219,182, 13, 92,182,108, 89,189,118, -237,218, 57,100,103,103,191, 75, 74, 74,234, 91,153,197,141, 97, 24,239,157, 59,119,130,166, 11,141,144, 20, 69,129,207,231,131, -207,231,195,220,220, 60, 59, 38, 38, 70,239, 98, 47,226,203, 83,146,114, 44, 57,150, 92,226,232, 96,109,225,224,216, 90, 46,151, -223, 1, 32, 49, 48,137,190,173, 91,183, 14,191,118,255,133,126,194,240,182,117,197, 60,138,107, 42, 18,210, 34, 62,151, 16,150, -213,107,180,234, 38,155,247, 93,223, 93,187,118,237, 96, 0, 6, 13, 17, 19, 66,252,124,125,125,111,221, 15,139,196,211,151, 49, - 9,182, 86, 98,235, 78,109,155,121,150, 92,176, 81,227,129,165, 78, 55,104,105, 27, 14,135,227,215,160, 65,131,228,184,164, 76, -216,217,152,127, 32,164, 45,109,236,218, 3,128, 60, 39,103,179,163,163,163, 71,209,122,144, 6,165, 51, 40, 40, 40,237, 78, 72, - 36, 28,108,173,172,138,118,155,149, 62, 39, 61, 41,105,155,139,139,139, 7, 33,196,217, 16,206,147, 39, 79, 34, 52, 52, 20, 75, -235,213,195, 76, 23, 23,216,218,218,226,143, 63,254, 0,203,178, 48, 49, 49, 65,118,118, 54, 14, 31, 62,140,118,237,218,253,237, -198, 66, 42,149,222,144,201,100,173, 75, 28,211, 63, 1,138, 57, 13,181,142,221,185,115,231,248,145, 35, 71,190,118,115,115,195, -136, 17, 35, 92,247,236,217, 19,227,233,233,233,218,188,121,115,220,185,115, 7,179,102,205,138, 89,180,104,145,235,240,225,195, -177,119,239, 94, 36, 38, 38,254,102,108,230,141, 48,194,136,207, 70, 96,197,197,197,101,123,123,123, 59,185,185,185, 81,106,181, - 26, 57, 57, 57,184,116,225,130,254,224,225,195,231,212,106,245, 20,138,162,120,123,127,253,117,155,131,163, 99,155,222,125,250, - 16,173, 86,139,246,237,219,243,175, 93,187,102,253, 44, 46, 46,175,162, 11,210, 52, 93, 98, 61,250,250,235,175,177,126,253,122, - 0,192, 87, 95,125,245,167,192,211,106, 13,246, 69, 18,153, 48, 93, 90,181,175,111, 22, 47,249,217, 76,211, 84,155,239, 18,109, -250, 64,146, 47, 10, 2,197,231, 64, 36, 4,163, 22,234,162,178,219,135, 68,191,173,237, 35, 82,166,214,110,230, 25,140, 67, 15, - 78,116,169,138,192, 18,137, 68,141,196, 98, 49, 34, 34, 34, 50, 3, 3, 3,179,205,204,204,204,221,221,221,109, 68, 34, 81,163, -234,102,124, 74, 74,202, 91, 39, 39,167,150,189,123,247,158, 68, 81, 84,123,134, 97,174,102,100,100,108, 74, 73, 73,121,107,200, -255,157,156,156, 38,176, 44,187, 16,192,209,226,125,106,181, 26, 20, 69,129,101, 89,116,239,222, 29, 43, 86,172,240,185,122,245, - 42,110,221,186,101, 53,120,240,224, 7, 82,169, 52,155, 16, 50, 42, 49, 49,177, 92, 43, 89, 70, 70, 6,182,109,219, 6, 14,135, - 3, 11, 11, 11,152,154,154, 66, 40, 20,162,117,235,214, 41,107,214,172,113, 63,112,224,128, 54, 59, 53,149,136,242,114, 84,196, -218, 90, 8,105,205, 78, 67,251, 15,120, 0,224,136,161,247,110, 98, 98, 34,226, 67,149, 71,233,149,212,234, 69,155, 57, 98, 30, -143, 8,121, 28, 8,152, 2,122,238,138,101,172,144,176,220,226, 33, 83, 67, 33, 20, 10,249, 18, 62,171,226, 10, 40,173,152, 98, - 63,201, 56, 43,135,195, 17, 8,184, 80,148,119,156, 71, 17,154, 16, 34, 2,160,170, 74, 58, 77,248,250,114,207, 23, 82,160, 41, -138, 18,150,199,217,175, 30, 97,143, 76, 42, 22, 56, 37, 70, 53,232,116, 58, 52,106,212, 8, 7, 79, 93,199,249, 63,238, 33,253, -253, 51, 76,153, 48, 18,238,238,238,184,116,233, 82,133,105, 42,246,193, 50,160, 83, 80, 40,136,190, 55,175,252,228, 34,191,171, -202,134, 6, 75,115,250,172,138,168,112,118,162,179,179,243, 88,127,127,255, 97, 39, 78,156, 64,155, 54,109,208,173, 91, 55,120, -122,122,186, 14, 30, 60, 24, 0,208,178,101, 75, 44, 88,176,192,117,224,192,129, 56,121,242, 36,206,159, 63,143,160,160,160,169, - 82,169, 52, 85, 38,147,109, 49, 54,247, 70, 24, 97,196, 63, 46,176, 0, 64,160,209,120,170,182,109,131,252,234, 85,240, 47, 95, -198, 89, 63,191,124,157, 78, 55, 67, 38,147,197, 3,128,189,189,253,180,195, 71,142,220,109,255,199, 31,102,234,136, 8, 56, 63, -127, 14,142,135,135,191,161, 23, 46,182, 94,169,213,106, 0,192,175,191,254,138,156,156, 28,228,228,228, 64,167, 51,120, 45, 97, -112,249,104,110,103, 93, 19, 73,136, 2,195,161, 76,222,121, 22, 52, 54, 81,154,202,156,226,236,229, 57, 60, 15, 68, 36,212,147, - 40,178, 85,141, 9,173,134, 50,189, 0,206,205,221,193, 65,217,195,143,229,129,162,168,226,151, 99,102,104,104,104,247,230,205, -155,159, 1, 96, 83,188,191,186, 72, 76, 76,124, 3, 96, 74,117,254, 75,211,244,194,219,183,111,219, 29, 62,124,120,210, 79, 63, -253,196,150, 22, 88,197,223, 57, 28, 14, 88,150,133, 68, 34, 1,135,195,177, 63,121,242,164,253,151, 95,126,185, 25, 64,185,229, - 36, 22,139, 97,103,103, 7, 62,159, 15, 83, 83, 83,200,115,179, 36, 91,127,156,223, 90,108,105,111, 53,101,234, 12,106,236,216, -177,225, 27, 54,108,168,225,224,233,233,253,226,197,139,183,189, 6, 12,188,119,234,212, 41, 69, 21, 28,220,159, 69, 68, 68,208, -238,110, 46, 60, 70,171, 96, 36, 60, 64,248,244, 39,134,111,234, 0, 33, 77,131, 67,192,138,196, 18,187,248,164,164, 56, 0, 73, -134, 16,178, 44,251,244,221,187,119,196, 89,106,207,201,147, 43,179, 37, 28,134, 31,251,248,209,171, 58, 13, 27,121, 3,128,242, -241,189, 19, 2,207,122,166,178,220, 60,145,147,147, 83,140, 33,156, 58,157,238,105, 66, 66, 2,177,178,178,226, 70, 69,189,249, -205,218,204, 84,106,101,111,223, 26, 0,212,153,105,183,136, 66, 41,227,114,185, 78,105, 25, 25, 73, 58,157, 46,206,208,116,198, -198,198, 18,103,169, 61,231,204,185,243, 7, 29, 36, 98, 71, 11,145,192, 92, 72,129, 8, 89, 38,135,175,211, 37,139,196, 18,105, - 66, 98, 98, 10,203,178,229,250, 9,110,101, 38, 13, 45,252,246,203,254,143,172, 59,184, 30, 18, 11,115, 90, 15,174, 86,142, 7, -199, 15,163,247,228,111, 12,122,158, 86, 47, 25,126, 96,245,146,225,229,134,103,248, 72, 16, 65, 54,238,111,182, 60,219,189,111, -252,133, 83, 86,177,131,123,167, 78,157,230,237,216,177, 67, 92,252,251,213,171, 87,104,222,188,240, 81, 94,188,120, 49, 58,118, -236, 8, 63, 63, 63,188,122,245, 10,181,106,213,194,241,227,199, 65,211, 52,119,236,216,177,179, 1, 24, 5,150, 17, 70, 24,241, - 95, 69,185, 10,129, 97, 89, 70,151,153, 9, 86, 85,216,145,230,241,120, 44,203,178, 37,141, 27,151,203, 21,155,155,155, 19,174, -179, 51,136,160,200,213,135, 16,253, 39,176, 26, 64,175, 55,156, 70,175, 7, 13,162, 1,139, 63, 67,252,200,133, 4, 63,216,180, -195, 20,201, 55, 72,230,155,151,126,195,129,213, 49,208,163,106,214, 17, 66, 8, 43,151,203,161, 82,169, 44,221,220,220,206, 41, -149, 74,203,162, 23, 38,251, 79, 21,156, 78,167,139,225,112, 56, 24, 62,124, 56, 80,184,228, 17,212,106, 53,158, 60,121, 2,149, - 74, 5,181, 90,141,187,119,239, 34, 39, 39, 7,106,181, 26, 87,174, 92, 65,173, 90,181,192,225,112, 28, 43,226,101, 24, 6,182, -182,182,176,183,183,135, 74,158, 43, 57,182, 99, 67,215, 85,139,190,179, 25,228,198, 82,191,108, 92,203,184,185,185,101,213,175, - 95,223, 74, 36, 18,101, 5, 6, 6,102,159, 60,121,242,116, 85, 66, 52, 0, 56, 51,103,206, 28,223,224,224, 96, 23, 11, 19,137, - 70,192,167, 33,208,201, 89,129, 42,131,229, 40,210,217, 90,206, 46, 26, 72, 76, 26,245,233,211, 71, 15,224,140,161,156, 83,166, - 76,169,233,237,237,109, 99, 97, 38,201,229, 80, 72,228,233,245,137, 89, 33,247,174, 0, 0,207,198, 78, 1,137, 73,163,193,131, - 7,107,171,194, 57, 99,198, 12, 55, 39, 39, 39,107,138, 34,217, 58,141,230,125, 73,125, 80, 42, 82,104,129, 80, 14,129,176,197, -168, 81,163,116, 85, 76,167,171,175,175,175,181,165,185, 89, 54,151, 34,113, 60,189, 46, 94,196,234, 19,248, 90, 77,154,192,206, - 62, 31, 18,147,102,131, 6, 13, 42, 55,157,197,214,171,143, 45, 67, 28, 14, 7,137,137,137, 40,144, 61, 3, 47, 49, 2,126, 38, - 92, 52,118,176,129, 68, 34,169, 92, 96,141,123, 69,194, 99, 89, 18, 30,203, 18,140,123, 69,202,250, 93,134,200,170,176,238, 87, -232,215,181,221,251, 70,117, 56,207,159, 63,191,178, 71,143, 30,218, 1, 3, 6,224,202,149, 43, 32,132,224,206,157, 59, 72, 76, - 76, 68,199,142, 29,193,178, 44,158, 60,121, 82, 34,190,250,246,237,139,110,221,186, 21, 92,188,120,241, 7, 99, 83,111,132, 17, - 70,124, 54, 2, 75, 43, 16,188,100, 38, 79,134,197,233,211,224, 70, 69,161,111,239,222,102, 2,129, 96,163,163,163, 99,160, 84, - 42,109, 38, 18,137, 54,207,152, 62,221,212,102,249,114, 72,111,221, 66,242,213,171,208,114,185,143,171,114,113,133, 66, 81, 44, - 96,160, 42, 18,114, 22, 22, 22, 85, 18, 88,140, 14,247,147,210,162,192,135, 11, 24,176,249, 23,115, 91, 62, 28, 20, 51,223,238, -108,110, 29,247, 55,114,158,251, 18,219,198,118, 27,107, 53,127, 40, 39,156,124,190,133, 16,178, 68, 25,244, 96,238, 87, 37,157, - 74,165, 50, 71, 46,151,163,110,221,186,214,161,161,161,110,238,238,238, 86, 69,130,230,209,223,201,124,169, 84,218, 36, 32, 32, -224, 72, 96, 96,224,219,128,128,128, 35, 82,169,180, 73, 21,254,254,203,227,199,143, 65,211, 52,198,142, 29,139,188,188, 60,104, - 52, 26,100,100,100, 32, 46, 46, 14,106,181, 26, 9, 9, 9,120,253,250, 53,212,106, 53,222,189,123, 87,146,199, 21, 65,171,213, -194,212,212, 20,217, 25,169,146, 67, 91,215,118, 93,182,104,158, 40, 39, 58, 20, 9,178, 20, 48,122,133,108,193,130, 5, 49,110, -110,110,119, 84, 42,149,151, 78,167,235,194,178,236,161, 42, 8, 85, 10,192, 19,119,119,247, 14,107,214,172,105,190, 96,197, 46, -129, 41,157,199,242, 77, 5, 12,223,148,207,242,189, 26, 99,244,194, 77,194,117,235, 86,223, 15, 9, 9,201, 49,112,102, 30, 5, -224, 73, 96, 96, 96,147,228,228,228,230,126,126,126,254, 14,117, 61,132, 2, 39,105, 58, 95, 90, 43,131, 85, 20, 92,165,106,214, -238,190,103,207,158,219,183,110,221, 74,169, 10,167,189,189,125,243,109,219,182, 5,212,172, 89,179,161,208,220, 92,148,159,157, -189, 67,149,157,185,139,107,227, 32,162,172,109,250, 29, 59,118,236,143,115,231,206,101, 84,133,211,211,211,179,217,242,229,203, -253, 2, 2, 2, 2, 29, 61, 60,133, 34, 39,231, 52,158, 83,173, 84,145,111,144,144,170,229,218,119,215,174, 93,215,239,222,189, -155,110,104,192, 81,138,162,192,229,114, 33,145, 72,112,243,230, 77, 12,234,221, 9, 14,118,102,240,240,244, 68,235,113,147,113, -238,220, 57,240,249,124,252, 93,107,235,199, 48, 68, 16, 85, 85,124, 85,198, 41,147,201,182,132,132,132,252,212,191,127,127,180, -111,223, 30, 79,159, 62,197,172, 89,179, 98,206,157, 59, 7, 0,120,250,244, 41,150, 45, 91, 22,115,255,254,125,140, 24, 49, 2, -205,155, 55,199,147, 39, 79,246, 25,131,143, 26, 97,132, 17,159,141,192,114,179,178, 50, 85, 42, 11, 18,110,221,186,165,161, 40, - 10, 98,177, 24,253, 6, 12,160,126,252,241,199, 22, 61,253,252,174, 13,110,210,228,194,225, 67,135, 2,252, 3, 2, 10,215,219, -161, 40,156, 58,117, 74,145,147,147,157, 81,179,102, 77, 11, 67, 47,158,150,150, 86,210,251, 86, 40, 20, 96, 89, 22,166,166,166, - 85, 18, 88,138,124,234,234,237,155,225, 89,172,254,235,184, 46,111,214,107, 86, 36,247, 12,206,102,244,156, 28,189, 22, 57, 10, - 22,121, 74,112, 30, 82, 86,193,195,221,123,105, 98,219, 7,191,126,248, 54, 44, 67,205,170,171, 52,251, 33, 43, 43,107,222,132, - 9, 19, 50,236,237,237,137,169,169, 41,236,237,237,169,209,163, 71,167,199,199,199, 47,169,110,198,251,248,248, 12,108,210,164, -201,153,176,176,176,190,135, 15, 31,118, 57,114,228, 72,223, 38, 77,154,156,241,241,241, 25,104, 32,197,225,149, 43, 87,202,249, -124, 62, 26, 55,110,140,188,188, 60,168,213,234, 74,183, 74, 5, 43,195, 64, 40, 20,226,200,174, 13, 29,150, 45,154, 39,202,140, -120,136,103,119,174,224,226, 91, 85,193,194, 21, 63, 61, 16, 10,133,213,186, 95,119, 59, 73,131, 6, 82,211, 87,223,140, 28, 32, -155, 51,123,182,249,243,231,207,197,211,191,153,198,202,210,178, 89, 97,215,117, 52,213,122, 1,245, 82,105, 67,122,116,107,139, - 31, 22,207,234, 0, 3,134, 78,125,236, 36, 13,234, 75, 77,195,191, 29, 59, 40,102,202,148, 41,226,149, 43, 87, 22, 52,111,222, - 60, 59, 39, 39, 71,100,110,239, 24, 32,176,179, 15,150,101,101, 75,154, 54,107,246,100,228,200,145,242,170,114, 46, 88,176, 64, -114,251,246,109, 65,167, 78,157,242,114,115,115, 37, 66, 19,147, 96,158,153, 69,203,180,156, 28,179,206,157, 59,135,245,239,223, - 95, 91, 29,206,215,175, 95, 11,154, 54,109,154,151,147,147, 35, 49,179,119,108, 36,180,115,104,145,152,153,101,218,184, 73,147, -176, 49, 99,198,168, 43,226,236,183,233, 79,113, 34, 22,139, 51,189,189,189, 49,127,254,124, 44, 94,188, 24,253,250,245, 67,236, -219, 88,180, 26, 49, 22,117,134,143,199,153,251, 15,145,152,152,136,185,115,231,194,221,221, 29, 20, 69, 37,125,202,198,163, 34, - 65, 84,158, 35,188, 79, 29,114,163, 34, 63,171,202, 68, 86,135, 14, 29, 70,244,232,209, 3,167, 78,157, 42,113,104, 31, 50,100, - 8, 0,192,223,223, 31, 51,102,204,112, 93,179,102, 77,204,186,117,235,208,164, 73, 19, 56, 59, 59,127,105,108,230,141, 48,194, -136,127, 2,101,199,193, 50, 19, 13,216,177,101,179,249,164,105, 51,228,222,222,222,150, 14, 14, 14, 32,132,160, 83,167, 78,164, -201,197,139,166, 92,169, 20,214, 13, 26,148, 44,104,120,251,214, 45, 92,187,118, 77,190,127,247, 47, 78, 35, 71,143,238, 14,148, -239, 51, 91,122, 88, 45, 35, 35, 3, 14, 14, 14, 37,179,213,100, 50, 25, 28, 28, 28,192,227,241, 64,211, 52,167,104,233,151, 10, -213,150,131,131,195,175, 43,150,189,156,147,224, 59,163, 78,176,152, 34, 23,228,201,208,179, 44,184, 68, 15, 40, 88,104,245,128, - 74,203, 34,168, 54,109,245,135, 26,150, 15, 95, 94,142,117,112,112,248,181, 42,153, 20, 19, 19,115,221,209,209,113, 92, 65, 65, -193, 81, 0,212,131, 7, 15,152,183,111,223, 78, 52,212, 33,189, 44,136, 68,162, 89, 71,143, 30,181, 90,178,100, 73,214,181,107, -215,114,218,182,109,107,190, 98,197, 10,171,129, 3, 7,206, 66, 25,193, 32,203,120, 17, 41,164, 82,233,190,164,164,164,137, 13, - 27, 54, 68,102,102, 38, 52, 26, 13, 66, 67, 67,225,238,238,142,144,144, 16,120,120,120,224,241,227,199,240,244,244,132, 94,175, -135, 82,169,132,222, 0,245, 42,139,127,111, 34, 86,101,153,201, 30, 94, 64,228,243, 80,156,143, 81, 21,172,222,125,232,124, 3, -255, 32,121,241, 12,195,170,192,211, 94, 82,207,201,206,250,242,138,197,223,219,189,187,126, 8,199,119,111, 98,174,159, 63, 95, - 95,100,134, 97,205, 6, 76, 29,168,209,194, 5, 4,130,150,205,154,162,187, 85,164,158, 87, 3, 41,127,188,172, 56,146,185,167, -189,164,158,212,214,250,210,234,229, 75, 76,163, 47,238,197,225,237,235,216,163,191, 30, 8, 80, 2,245,220,220,220,186,211, 52, -109, 15, 64,161,215,235,163, 97,224, 18, 52,101,113,254,113,246,108,160, 18,168,231,236,236,220,157,203,229,214, 0,160,210,106, -181,239, 63, 5,103,221,186,117,187, 19, 66,156, 0, 40,139,124,174,170,180, 84, 78,251,246,237, 87,239,218,181,107,186, 74,165, -178, 42,101,109, 37,167, 78,157,130, 70,163, 33, 60, 30,143,145, 72, 36,136,139,139, 99, 1, 36,177, 44, 59,254, 83, 53, 28,125, -250,244,193,131, 7, 15, 22, 3, 88, 88,209,121,153,153,153, 28, 43, 43, 43, 93,101,194,203, 80,206,135, 15, 31,174, 28, 51,102, -204,204,139, 23, 47, 38, 44, 90,180,200,127,248,240,225, 56,121,242, 36,106,214,172,137,215,175, 95, 99,250,244,233, 32,132,184, -174, 89,179,230,201,193,131, 7, 29,147,147,147,215, 26,155,121, 35,140, 48,226,179,177, 96, 17,134,112,221,235,214,213,171, 11, -242,247,140, 30, 49,162,224,229,203,151,208,235,245,208,233,116, 80, 62,122, 4,249,197,139,208,235,245, 96, 89, 22, 15, 31, 60, -192,148,201,147,243,149, 5,249,187,106,215,118, 97, 9,203,150, 76,215, 39,132,180,255,152, 91, 93,202,140,162, 80, 40,160, 80, - 40,192,225,112, 96,106,106,138,212,212, 84,240,249,124,136, 68, 34,248,249,249, 81,206,206,206,221,254,146,182,143, 56, 67, 67, - 67,181,200, 85,245, 61, 53,124,106,146,115,129,142, 29,103, 81, 27,181,120,162,146, 89,136, 14,102, 4, 95,250,113, 97,207, 75, -103,159,237, 29, 36, 35,186,156,190,161,161,161,218,138, 56, 63,134, 84, 42,245,240,241,241,217,210,167, 79, 31, 10, 0, 90,180, -104, 65,213,171, 87,239,103,169, 84, 90,238,146, 54,149,113, 10,133, 66, 1, 0, 92,189,122, 53,243,246,237,219,157,174, 94,189, -154, 89,122,191, 33,156, 20, 69,237,216,186,117, 43,196, 98, 49,116, 58, 29,212,106,117,137,255, 85,233, 79,141, 70, 3, 27, 27, - 27,252,241,199, 31, 96, 24,230, 92,101,233,244,174,239,155,159,195,177, 72,217,119,230, 26, 46,188,211,228, 87, 85, 92,149,230, -172,235,104,226,233, 96, 99,125,101,245,143, 75,109,179,222,132, 34, 33, 33,129,189,116,241,220,125, 5,203, 38,102,228,176, 63, -100,230,177, 62,249, 74, 86, 28, 84, 27,241,231,126,158,206,126,219, 4, 58, 16,176, 21,113,214,115, 52,241,116,178,181,190,180, -118,245,143,166,217,111, 66,145,148,156,140,243,231,206, 60, 81,176,108, 34,203,178, 23, 89,150,157,160,211,233, 26,233,116,186, - 70, 44,203, 78, 40, 79,180, 84,149, 83,163,209, 4,107, 52,154,224, 79,201,201, 48, 76, 48,195, 48, 6,115,254, 57,131, 16,152, - 63,127,254,163, 91,183,110,245,127,244,232, 81,187,226,237,197,139, 23,109, 99, 99, 99,219, 38, 36, 36,180,137,157, 37,160,159, - 63,127,206,121,252,248, 49,247,241,227,199, 53, 67, 66, 66, 46, 26, 90, 63, 43,120, 22, 74,139,252, 69, 50,153,140,148,201, 57, -238, 21,217,188,230,235,253, 71,142, 28,177,255,100,156, 0, 34, 34, 34, 54,239,218,181,171,150,147,147,147,227,192,129, 3,177, -119,239, 94,236,218,181, 11, 64, 97, 36,251, 82,150, 43,187,144,144,144, 58,101, 5, 25,173,238,189, 27, 90,231,141,156, 70, 78, - 35,167, 17,229, 11, 44,194,232,245,122, 6,118,246,118,166,105,169,169,155, 38, 76, 24,159,177,100,201, 18,229,205,155, 55,161, -142,136,128, 50, 44, 12, 87,174, 92,193,212,169, 83, 11,198,142, 27,151,164, 44,200,223,224, 96,111,103,163,215, 51, 32,132,169, -208, 66, 66, 81, 84, 76, 84, 84, 84,113,111, 27,155, 54,109,210,105, 52, 26,152,154, 22, 6,153,222,185,115, 39,195,178, 44,218, -181,107, 39,225,114,185, 6, 45, 65,146,152,152,248, 44, 55, 78,214,241,216,128,241,209,175, 14,157,206,242,205,208, 96,136, 72, -138, 1,129,128,143,105, 28, 18, 31,254,146,117,111, 75,207,232,130,204,248, 78,137,137,137,207,170,154, 73,246,246,246, 11,127, -255,253,119,187,208,208, 80, 86,165, 82, 33, 49, 49,145,157, 53,107,150,157,189,189,253,194,234,102, 60,203,178, 36, 59, 59, 27, -132, 16,166,168,178, 50,197,251, 13,229, 72, 72, 72,120,113,228,200,145, 83,215,175, 95,135,179,179,115,137,200,250, 88, 96,113, - 56, 28, 16, 66,176,117,235,214,108, 66,200,119,149,241, 10, 4, 2,236, 60,122,241,194,183, 91,143, 31, 62,124,245,209,241,234, - 90,174, 0,128, 79, 81,139, 86, 46,253,222, 46,253,213, 3,242,226,254, 53,230,208,211,164, 20,157,158,157, 84,230,201,121, 50, -182,168, 82, 86,236,219, 67,209,139, 86,254,184,196,188,120,248,242,247, 80, 89, 46,209,179,147,255,222,147,240, 63,194,249, 15, -162,112,166,159,140, 72,165, 82, 28, 59,118,172,202, 62, 88, 62,117,200, 95,156,219,171,203, 41,147,201, 86,125,241,197, 23,178, - 69,139, 22,109, 81, 42,149,242,162,206,155,102,237,218,181,107, 38, 77,154,148,146,152,152,104,180, 92, 25, 97,132, 17,255, 40, -202, 28, 34,100,104,234,238,182,237, 91, 59, 31, 58,112,208,129,166, 41,135,216,216,183,143,191, 26, 53, 42,241,214,173, 91, 86, -220,186,117, 27, 81, 20,197,168,231,204,185,159,159,155,147,249,235,158,221,181,106,215,118,241, 43, 90,236,153,101,104,234,110, - 69, 23,204,204,204,220, 59,109,218,180, 70,251,246,237,227,173, 90,181, 74,158,152,152,120,249,193,131, 7,157,183,108,217, 34, -220,185,115,103, 65, 94, 94,222,233,243,231,207,247,104,211,166,141, 78,173, 86, 23, 24,122, 35, 41, 41, 41,225,132, 16,111,106, -237,174,193,175,183,254,254, 5, 75,147,102, 80,241, 64, 88,221, 93, 74, 39,191,146, 34,147,253,206,178,172,174, 58,153, 36, 18, -137,252, 68, 34, 17,222,188,121,147,213,168, 81, 35, 53,159,207,231,185,184,184, 88,139, 68, 34,191,191, 33,176,216,172,172, 44, -176, 44,203, 1, 64, 24,134,225, 20,237,175, 82, 12, 39, 30,143, 55,112,228,200,145,167,182,108,217,210,161,125,251,246,112,117, -117,133, 86,171,133,135,135, 7,212,106, 53,220,221,221,161, 82,169,176, 97,195, 6,228,231,231, 79, 79, 76, 76,204,170,140, 83, - 40, 20,130,207,231,195,211,187,126,129, 80, 40, 68,117,197, 21, 0, 72,184,148,235,235,179,187,145,154,145,206, 28,126,154,146, - 82,160,209,119,140, 74,149,191,252,248,188, 2, 61,228,109, 70, 76, 73, 4, 0, 21,131,252, 10, 57,249,112,141, 60,183, 19, 41, -169,233, 56, 20,150,148, 45,215, 48,157, 94,151,193, 89,165,116,254,143,112,246,219, 20,129,214, 95, 27,126,238,145,113,159,166, -161, 40,109, 85, 50, 20,225,177, 44,193,118,111, 22,219, 55,149, 25,227,170, 58,156,165, 58, 85,219, 1,108, 7, 0,103,103,231, -232, 41, 83,166,204, 76, 76, 76, 92, 95, 20,239,106,161,177,105, 55,194, 8, 35, 62, 75,129, 21, 19, 19, 31,238,234, 90, 99,238, -241, 99, 71,155,177, 44, 69,179,132,200, 1,234,204,203,151, 47,179, 75,159,231,102,101,101, 58,114,204,200, 1,132, 33, 92, 66, - 24, 61, 67, 83,119, 99, 98,226,195, 43,105, 24,159, 15, 27, 54,108, 83,155, 54,109, 70,233,245,250, 85, 81, 81, 81,151, 61, 61, - 61,159,116,234,212,233, 91,157, 78,183, 38, 58, 58,250,178,151,151,215,149, 67,135, 14,205,210,235,245,223, 87, 81,180,232, 80, -232,255,181,239, 83,102, 18, 69, 81, 75, 88,150, 53, 23,137, 68, 57, 33, 33, 33, 7, 90,182,108, 57,136,101, 89,115,138,162,114, -170,203,169, 86,171, 39,231,229,229,217, 12, 28, 56, 80, 75, 8,241,236,213,171,215,156,168,168, 40,174, 92, 46,143,169, 10,207, -187,119,239, 84, 46, 46, 46, 61,190,254,250,235, 93, 60, 30,175, 29, 10, 67, 54,176,165,242, 4, 44,203, 66,175,215,159,150,201, -100, 21,230, 11,151,203,205,239,220,185,179, 73,165, 86, 41, 62, 63,223,208,244,229,169,245,211,182, 94,123,185, 92,169,101, 89, - 29,195,142,123,157, 34, 47,115, 10,217,163,215,108, 61,131, 57,149,204,180,141,151,194,151,171,180, 12,163, 99,216,241,229,113, - 86, 5,255, 43,156, 0, 48,129,218,180, 31,219, 55,149, 56,188, 23, 15, 27,126,252,251, 63,133, 34,139, 19, 11,160,242,197,206, -139, 44, 86,149,173, 93, 88, 37,206,143, 80, 52, 75,208, 56, 83,208, 8, 35,140,248,188, 80,252, 2,254, 79,108, 0,218, 27, 57, -141,156, 70, 78, 35,167,145,211,200,105,228, 52,114,254,219, 54,202, 40, 49,141, 48,194, 8, 35,140, 48,194, 8, 35, 62, 45, 8, -128,246,229, 88,182, 12,142, 21, 85,157,217, 4,149,241, 27, 57,141,156, 70, 78, 35,167,145,211,200,105,228,252,255,199,249,175, -129,113,136,208,200,105,228, 52,114, 26, 57,141,156, 70, 78, 35,167,113,136,208, 56, 68,104,132, 17, 70, 24, 97,132, 17, 70, 24, -241, 89,195, 40,176,170, 1, 66,200, 87,132,144,139,132,144, 23,132,144, 75,132,144,175,254, 6,151,136, 16, 50,167, 20,223, 5, - 66,200, 44, 66,136,192,152,211,159,117, 29,160,141,185, 96, 68,117, 81, 20,188, 56,180,162, 96,197, 70, 24, 97,196,255, 54, 56, -229, 29,112,115,115,187, 71, 81, 84,157,226, 69, 98,139, 35,163, 23,127,255,248, 55, 0,176, 44, 27, 27, 30, 30,222,180, 60,206, - 58,117,234,148,112, 22,111,132, 16,104,181, 90, 83,154,166,243,202,226,212,235,245, 9,175, 95,191, 14,250,140, 94,172,251,173, -172,172,152,109,219,182,109,246,245,245,173,155,151,151, 87, 48,102,204,152, 46,132,144,246, 44,203, 14,173, 34, 87,125, 66,200, -175, 13, 27, 54, 60, 62,105,210,164, 35, 62, 62, 62,102, 10,133,130,127,224,192, 1,135,109,219,182,221, 38,132,140,100, 89, 54, -220, 88, 77, 63, 31, 56, 58, 58, 6, 16, 66, 54,185,187,187, 7, 73,165,210,199, 0, 38,202,100,178,167,198,156,249,175, 62,131, -163,249,124,126, 39,119,119,247, 70, 42,149, 42, 43, 54, 54,246,145, 94,175,255,158,101,217,228, 79,196,111, 14,224,123,129, 64, - 16,236,230,230, 86, 35, 42, 42, 42, 94,163,209, 60, 4,176,132,101,217,156, 79, 33,174,130,131,131,239,252,248,227,143,214,223, -125,247,221, 29,169, 84,218, 92, 38,147, 69, 26, 75,214,136,127, 2, 53,107,214,180,144,203,229,187, 56, 28, 78,128, 64, 32,112, - 48, 49, 49,129,137,137, 73,178, 64, 32,120, 34, 22,139, 71,157, 59,119, 46,219,152, 75,159, 88, 96,209, 52,237,252,232,209, 35, -187,226,197,151, 25,134, 1,195, 48, 96, 89,182,228,179, 24, 69,113,150,208,166, 77, 27, 77,133, 23,227,112,106,132,134,134,218, -153,152,252, 25,106, 73,163,209,192,215,215,151, 9, 11, 11,179,251,120, 33, 97,181, 90,141,192,192, 64,246,115,201, 44, 66,200, - 16,107,107,107,249,251,247,113, 45,149, 42, 77,240,152,201,223,205, 29,210,247, 11,203,187,119,239,162,123,247,238, 52, 33,228, - 43,150,101,127, 53,144, 75, 68, 8,249,101,238,220,185, 43,185,124,177,221,177,115,119,232, 13, 59,246,191,247,247,168, 77,166, - 76,153,104, 50,105,210,164,199, 62, 62, 62,187, 9, 33, 45, 88,150, 85, 25,171,234,103, 81,254,156, 26, 53,106,156, 90,190,124, -185, 83,114, 82, 18,214,173, 95,223, 24,192, 22, 0,141,141,185,243, 95, 43,131, 57,139, 23, 47, 94, 62,120,240, 96,232,245,122, - 40, 20, 10,233,155, 55,111,234,205,159, 63,191, 23, 33,164, 17,203,178, 49,127,147,223,214,221,221, 61, 98,218,180,105, 86,141, - 26, 53, 2, 69, 81,200,201,201,145,222,190,125,187,241, 47,191,252,242, 21, 33,196,139,101,217,180,191,115, 13, 75, 75,203,223, -214,172, 89, 99, 45, 16, 8,176,103,207, 30,235,254,253,251,223,150, 74,165, 45,170, 43,178, 8, 33,148,181,181,245, 20, 0,109, - 25,134,225, 3,120,152,149,149,181,140,101, 89,141,177,198, 24, 81, 17,108,108,108, 70,231,229,229,109, 22,139,197, 60, 51, 51, - 51,136,197, 98,112,185, 92,240,249,252,154,150,150,150, 53, 77, 76, 76,186, 12, 26, 52,104,226,129, 3, 7,118, 25,115,235, 19, - 10, 44,138,162, 32, 18,137,112,248,240, 97,208, 52, 13, 46,151, 11, 46,151, 11, 30,143, 87,230,247,154, 53,107, 26,210, 16, 0, - 0,206,156, 57, 3, 51, 51, 51,152,155,155,195,203,203, 11,132, 16, 8, 4, 2,252,241,199, 31,224,114,185,224,112, 56,224,114, -185, 8, 10, 10,250,192, 82,246,223, 64,191,122,132, 5,202, 14,222,216,181,158, 9,186, 79,254,177, 79,129, 82,211, 14,128, 60, - 59, 43, 43,235,241,241,227, 50,127, 15, 15,222,225,195,135,253,172,172,172, 6, 1, 48,116, 33,233,169,141, 27, 55, 62,205,242, - 36,246,195,134,143, 24, 54,138, 67,105,190, 26,247,237, 15,241, 73,233,242,177, 99,199, 30, 63,125,250,244,176,141, 27, 55, 70, - 77,156, 56,113, 10,128, 85,134,166,223,197,197,229, 30, 77,211,197,150, 71,217,155, 55,111, 2, 62,147, 23,163, 20,192,106, 0, - 90, 0, 43, 89,150,141, 40,117,204,131,199,227,173,210,104, 52,153, 0, 22,178, 44, 27,255, 57, 62, 44, 78, 78, 78, 94, 67,135, - 14,181,201, 76, 79,199,186,245,235,139,119, 7, 25,178, 40,249,167, 70, 96, 96, 96, 29,161, 80,184, 26, 64,128, 74,165,114, 2, - 0,145, 72,148,200,178,236, 9,133, 66, 49, 47, 52, 52, 84, 81,205,114,170, 1,160, 30, 10,103, 24,151, 5,118,249,242,229, 81, -115,230,204,137,249,111,115, 18, 66, 92,236,237,237,127,236,215,175, 31,206,157, 59,135,243,231,207,107, 69, 34, 17,103,248,240, -225,100,226,196,137,150,211,166, 77,235, 2,224,167,191,153,181, 93, 22, 47, 94,108,229,237,237,141,163, 71,143,226,217,179,103, - 10,119,119,119, 81,235,214,173,193,225,112,172,230,206,157,219, 25,192,222,191,115,129,172,172,172,101, 75,151, 46,221,183,105, -211, 38,211,216,216, 88, 44, 89,178,196,102,210,164, 73, 55,165, 82,105, 43, 67, 69, 86,145, 11,193, 20, 0,109,104,154,110, 49, -124,248,112,221,228,201,147,185, 20, 69,105,215,175, 95,111,251,203, 47,191, 12,176,177,177, 9, 72, 79, 79,207,135, 17,168,192, -144,160, 97, 24,134, 11, 64,200,178,172,170,178,223,255,159,238,221,218,218,122, 66, 86, 86,214, 22,169, 84, 10, 91, 91,219,146, -119, 45,195, 48,144,203,229, 80, 40, 20,168, 83,167, 14,207,219,219,123,231,164, 73,147,184,155, 54,109,218,106,172, 49,159, 72, - 96, 17, 66,192, 48, 12,184, 92,238, 7, 2,171, 88,252,124,252,189,204, 86,243,163,169,154, 20, 69,145,252,252,252, 18,113,101, -102,102, 86, 98, 9,211,106,181,127,225,213,235,245,160, 40,138,173,136,179,156,180, 79, 0,240, 7,203,178,209,134,100, 66,105, -206, 35,147,188,176, 79, 48,107, 80,113,200,243, 46,223, 22,126,238, 3,112,245,205,184, 85,171,154, 53,171, 49,101,193,198, 69, -138, 12, 89,250,220,161,221, 93,220, 29,172, 69,146,236,212, 28, 75, 79,207,238, 0, 82,170,144,206,230, 99,199,142, 61,122,252, -234, 75,161, 80,200,227,113,104,154,219,188,129,135,117, 13,115,218,220, 20, 48,143,143,137,186,247,213, 87, 95,141,153, 56,113, -162, 85,177,192, 50,228,222,185, 92,174,243,195,135, 15,237, 56, 28, 14,154, 53,107,166,175,202,189,127, 42,148,195, 57, 63, 37, - 37,101,160, 82,169, 68, 80, 80,208,151,132,144, 54, 44,203, 62, 33,132, 52,232,209,163,199,237, 35, 71,142,152,134,133,133,161, -113,227,198, 34, 0,253,255,193,116,254, 5, 82,169,244, 50,128, 47,104,154,134, 90,169, 84,175, 94,251,193, 50,119, 33,165,197, -213,127, 35,157,254,254,254, 94, 98,177,248,222,218,181,107,205,124,124,124, 8,151,203,133, 78,167, 67, 84, 84, 84,141,253,251, -247,143,123,252,248,113,231,192,192, 64,159,143, 23, 53, 55,240,222,235,221,190,125, 91,238,234,234, 90,102,221,201,205,205,229, -120,120,120,180, 2, 16,243, 15,112, 38,164,164,164,244,252,226,139, 47,198, 39, 39, 39, 71,232,116,186,217, 0,234,219,216,216, -132,245,238,221, 27, 34,145,168,141, 33, 2,171,162, 50,178,179,179,235,209,180,105, 83,108,218,180, 9, 43, 87,174,108,207,178, -236, 31,132,144,118,185,185,185, 87,191,252,242, 75, 88, 88, 88,244, 44, 75, 96, 85,161, 46,121, 52,106,212,104,231,244,233,211, - 77,207,157, 59, 7,119,119,119,228,228,228, 96,196,136, 17,118, 27, 55,110,188, 33,149, 74, 91, 23,139,172,242, 56, 9, 33, 62, - 2,129, 96,239,129, 3, 7, 76, 92, 93, 93, 93,121, 60, 30,229,234,234,138,204,204, 76, 40,149, 74,193, 15, 63,252,208, 64, 36, - 18, 61,253,233,167,159,246, 2,232,253, 79, 62, 71,132,144, 28, 0,102, 0, 44,170, 50,188, 90,193,189,231, 0, 16,148,106,239, - 32, 20, 10, 33, 20, 10, 33, 16, 8, 16, 27, 27,123,140,166,233, 17, 69, 29,185, 74, 57,201,159, 61,120, 63, 66,200, 35,154,166, - 43,252,253,241, 82,102,255, 68,187, 68, 8,113, 38,132,108, 0,208, 6,133,126,212, 55,237,236,236,166, 38, 39, 39,191, 55,148, - 83, 42,149, 90,231,231,231,255, 36,149, 74, 97,103,103, 87, 44, 54, 17, 20, 20, 4,165, 82,137,151, 47, 95,130, 97, 24, 68, 71, - 71,195,204,204, 12, 13, 26, 52,248,105,241,226,197, 71, 23, 46, 92,152,241,159,188,247,127,141,192, 42, 86,178, 28, 14,231, 3, -129,245,241, 86, 44,134, 8, 33,149, 46, 84, 76, 8,161,212,106,117,137,184, 50, 55, 55, 47,249,175, 78,167, 43, 83, 96, 85, 83, -153,251, 50, 12, 83,135, 16,178,221, 80,145,245, 49,134, 13, 27,246, 23,127,142, 57,115,230, 36,164,167,167, 51,125, 58,250, 73, - 34, 46,200,146,220, 44, 77, 68,182,166,166,181,133,150, 86, 22,249,249,249,183, 0,152, 84,225, 18, 78,222,222,222,230,155,247, - 93,144,141,249,102,249,210, 32, 87,107, 51, 95,103, 27, 75, 7,115, 17,223,132, 34,114,161, 78,155, 32,145, 72,124, 0,100, 84, - 37,221, 20, 69,193,204,204, 12,167, 79,159, 70,177,255,220,103, 2, 75,133, 66,129,172,172, 44,108,219,182,205,108,252,248,241, -215, 9, 33, 83,123,246,236,185,233,200,145, 35,146,236,236,108,104, 52, 26, 0, 80,124,134,207,201, 82, 75, 75,203,150,109,218, -180,225, 31, 60,124,152,207,178,172, 28,133,203, 17,229,179,108, 57, 11, 87,255, 7, 33, 20, 10,191, 93,182,108,153,153,143,143, - 15,201,200,200, 0,195, 48,160, 40, 10, 54, 54, 54,152, 57,115,166,112,254,252,249, 78,175, 95,191,158,139,106, 44, 59, 3,128, -148, 39,132, 0,192,204,204, 76,135,170, 79,142, 41,147, 83,167,211,145,102,205,154,205, 76, 79, 79,111,160, 80, 40,126, 48,224, -197,163, 3,112,186,104, 43,110, 83,158, 70, 68, 68, 40,250,247,239, 47,170, 93,187,118,240,223,205, 91, 15, 15,143, 38, 92, 46, - 23, 15, 31, 62, 84, 1,184, 89,180,251,230,179,103,207, 84,189,123,247, 22,212,168, 81,163,137,161, 92, 82,169,212,195,205,205, -237,138,141,141,141,168,120,218,118,215,174, 93,185,171, 87,175, 54, 77, 72, 72,128, 70,163,193,156, 57,115,208,173, 91, 55, 88, - 90, 90, 98,228,200,145,246, 59,118,236,248, 13, 64, 96, 5,109,168,144,207,231,255,250,230,205, 27,119, 71, 71, 71,209,131, 7, - 15,224,235,235,139,244,244,116, 36, 39, 39, 35, 63, 63, 31,201,201,201, 24, 53,106,148,221,186,117,235,164,159,209, 51,148,205, -227,241, 32, 22,139, 45,178,179,179,115,254, 6,143, 0, 0,191,180,184, 18, 8, 4, 16, 8, 4,248,216,197,228,255, 35, 8, 33, - 78,132,144,112, 30,143, 39, 16,139,197, 60,138,162, 32,145, 72, 58,214,168, 81,227,229, 87, 95,125, 85,255,215, 95,127,125,103, - 8,143, 82,169,252, 85, 36, 18,113,109,109,109, 1, 0, 29, 58,116,192,240,225,195,145,150,150,198,200,100, 50,120,121,121, 81, - 55,110,220, 64, 74, 74, 10,158, 62,125,138, 70,141, 26,113,173,172,172,126, 5,208,217, 40,155, 62,161, 5,139,195,225,148,108, -101, 89,174,138,183,143, 29,223,203,227,212,235,245,176,183,183,135, 88, 44,134, 88, 44, 46,237,204,254, 23,126,150,101,171, 53, - 68, 40,145, 72, 48,120,240, 96,118,235,214,173,227,139, 68,214, 27, 67,255,219,111, 83, 68,137,213,234, 99,248,250,250,222,157, - 55,111, 94,167, 75,151, 46,101, 5,185,214,230, 72,100,239,243,133,102, 22, 22,112,174,217,245,171,126, 3,238, 1, 56, 80,133, -100,202, 84, 42, 21,207,205, 89,172,166, 40, 37,169, 41,224,152, 58, 74,120, 2, 7, 75, 75, 39,158, 90,149,106,102,105,201, 47, - 26, 50,147, 85, 70, 84, 60,121,128, 16, 2, 11, 11, 11,110,209, 39,236,236,236, 4,245,235,215, 79,161, 40, 10, 44,203,202,158, - 63,127,110,240,112,161,171,171,107, 8, 69, 81,206,132,144, 15, 38, 36,148,222, 24,134, 73,120,249,242,165,161, 19, 16,230,249, -249,249,181,218,178,101,139,173,187,187, 59,182,109,219,102,118,244,232,209,189,191,253,246, 27,178,179,179,241,238,221, 59,140, - 26, 53, 42, 23,133,195,136,159, 21,172,172,172,238,244,235,215, 15, 59,119,238,100,139, 58, 17, 18, 66,136,175,185,185,249,235, -240,240,240,255,186,159, 11, 69, 81, 29,189,188,188, 72, 78, 78, 14, 24,134, 1, 77,211, 37, 29, 33,154,166,241,237,183,223,138, - 70,141, 26, 53,191, 73,147, 38, 51,185, 92,110,174, 78,167, 59,152,159,159,255,195,139, 23, 47, 62, 43,103,213, 22, 45, 90,124, - 19, 31, 31,223,173, 86,173, 90,103,254, 70,111,159,109,216,176,161, 26,128,136,166,105,238, 39,120,129,209, 69,237,145,178,120, -113,120,150,101,117,129,129,129,202,162,151, 59, 93,133,122,243,219,254,253,251,157,157,157,157,161,213,106,161,211,233,144,159, -159,143, 27, 55,110, 64,165, 82, 65,167,211,193,203,203, 11, 43, 87,174, 84, 78,156, 56, 81,120,232,208,161, 84,133, 66, 49,164, - 18,218,169, 71,143, 30,149, 56, 58, 58,138, 20, 10, 5, 98, 98, 98, 16, 24, 24,136,188,188, 60,200,229,114, 20, 20, 20, 64,163, -209, 32, 55, 55,215, 66,175,215,171, 63,155, 23, 13,135, 3,129, 64, 0, 30,143,151, 93,171, 86, 45, 16, 66,132,239,222,189,171, -206,144,155, 25,128, 92, 46,151,203, 47, 45,172, 4, 2, 1,158, 63,127,126,168, 60,235, 85, 69,245,167, 42,191, 63, 3,129,181, -129,199,227, 9,172,172,172,120,197,251, 52, 26, 13,207,210,210, 18,181,107,215,222, 4,160,139,129,109,136,191,165,165, 37, 8, - 33,224,241,120, 24, 51,102, 12, 30, 61,122,116, 34, 33, 33,225,171,212,212, 84, 20, 20, 20,252,106,110,110,222, 43, 53, 53, 21, -122,189, 30,111,223,190,133,191,191,191,191, 81, 50,125, 98, 11, 86,121,130,234, 99,193,101,136,181, 68,163,209,152,116,237,218, -149, 41,253,146, 46,250, 31,169, 64, 96, 85,171,130,115,185, 92,211, 9, 19, 38,228,109,221,186,117, 28, 33,100, 7,203,178, 81, -213,205,164, 51,199, 14,216,175,252,126,206,247, 86,210,218,110,179,103,207,230,244,238,221,251,218,158, 61,123, 26, 90,121,123, -127,113,253,242,126,251, 77,179,231,158, 60,117,234, 84,129,161, 14,238, 69,184,123,226,196, 9,199,233, 83, 38,242,190,255,118, -234, 69, 51,119, 27,190, 9,177,146, 8, 85,242, 52, 19,176, 10, 65, 93,175,110,103, 47, 93,138, 7,112,199,128,198,203,249,225, -195,135,118, 22, 22, 22, 0, 10, 39, 7, 88, 88, 88, 96,235,214,173,150,197,150, 66, 67,134, 11, 63,122, 0,157,195,194,194,236, - 76, 76, 76, 32,151,203, 75, 94, 8, 44,203,150, 52,150, 45, 91,182,172,202,139, 48,134, 16,210,242,235,175,191,190,181,101,203, - 22, 91, 55, 55, 55, 44, 93,186, 20, 25, 25, 25,136,139,139,195,144, 33, 67,114, 99, 98, 98,218,148,246,205,250, 28,208,160, 65, - 3,246,238,221,187,184,120,241, 34,190,252,242, 75,114,234,212, 41,141, 94,175,231, 37, 38, 38, 62,255,167,210,164,211,233, 76, -121, 60, 94,201,176,122,177,176, 42,222,156,157,157,113,245,234, 85, 78, 65, 65, 1, 39, 61, 61, 93,252,203, 47,191, 76, 14, 9, - 9,113, 4, 48,232,159,204,203,173, 91,183,214, 26, 51,102, 76, 28,135,195, 97, 59,117,234, 52,244,253,251,247, 61, 29, 29, 29, -255,184,126,253,250, 90, 0, 85, 14, 87, 80,191,126,253, 16, 14,135,227,204,178, 44,239,228,201,147, 90,189, 94,207,107,208,160, - 65,202, 71,193, 16,161,211,233, 18, 34, 35, 35,131, 12,225, 19, 10,133,188, 29, 59,118,104,149, 74, 37,207,215,215, 55,165, 20, - 15,239,212,169, 83, 90,173, 86,203,243,244,244, 12, 49,100,102,115,102,102,230,144,105,211,166,221, 62,124,248,176, 13, 77,211, -120,255,254, 61, 50, 50, 50, 96, 97, 97,129, 95,127,253, 21,181,107,215,198,149, 43, 87, 50,117, 58,221,232,157, 59,119,206, 87, - 40, 20, 67, 12,240,193,106, 25, 28, 28, 92, 43, 59, 59, 27, 22, 22, 22,144,203,229, 8, 9, 9,129,143,143, 15,100, 50, 25, 40, -138,130,133,133, 5,182,108,217, 82, 64, 8,201,252, 28,158, 33,154,166, 75,172, 76,165, 68,145,178, 73,147, 38,184,115,231,206, -239, 85, 17, 69, 44,203,170,185, 92,238, 7,194,170,248, 59, 77,211, 85, 30,242,208,235,245, 60, 66,136, 63,138,252, 3, 43,251, -253, 25,160,149, 88, 44,230,149, 81,215,120, 30, 30, 30, 45, 12, 37,225,243,249,214, 34,145,168,144,176, 85, 43,164,166,166,234, - 93, 93, 93, 7,244,239,223, 95, 11, 0,227,198,141, 27,144,154,154,170,212,233,116, 52, 77,211, 72, 75, 75, 67,237,218,181,173, -141,146,233, 63, 96,193,170,200,114, 85,218,130, 85, 89, 37,164, 40, 42, 59, 52, 52, 84, 34,145, 72, 74,246,105,181, 90,248,251, -251, 51, 12,195,144,143,175, 83,156,142,234,130,203,229,154,126,247,221,119,217, 91,182,108,249, 10,192, 60, 67,254,115,100,146, - 23,246,125, 36,174,182,173, 92,178,233,231,149,203,172,162, 47,238,193,174,141,107,244, 92,190, 73,136,191,191,127,203,156,156, - 28,149,133, 68,133,228, 12,156, 96, 89,246,183, 42,244, 66, 40, 0,135,238,223,191,255,164, 67,135, 14, 15,118, 31, 58,110, 37, -139,137,185, 47,200, 77, 79, 50,171,235,206,225, 57,213,234, 37, 87,171,185,189,122,245, 50, 1,176,209, 0, 62,196,197,197,225, -222,189,123, 48, 51, 51,131,153,153, 25, 44, 44, 44, 74,190, 87, 39, 15,139,135,109,207,158, 61, 11,137, 68,130,162,169,187,144, - 72, 36,224,243,249, 40, 93,134, 85, 16, 89,145,132,144,169,199,143, 31, 63,184,124,249,114,100,102,102, 66, 46,151, 99,225,194, -133,136,137,137,153,198,178,236,147,207,233,225,240,245,245,101,239,223,191,143,187,119,239, 66, 46,151,227,231,159,127,134,163, -163, 99, 91, 0, 11,254,201,116, 49, 12,195, 43,182, 40,150, 22, 86,165,173, 88, 52, 77, 67, 40, 20,194,198,198, 6,115,231,206, -229,125,249,229,151,221,254,201, 52,175, 90,181,170,238,134, 13, 27,126,217,183,111,223,133, 33, 67,134, 28,126,241,226,197, 8, -115,115,243,231,215,174, 93, 91, 38, 16, 8,152,106, 90, 69,156,159, 60,121, 98, 87,250,145,103, 24, 70,172,211,233,160,211,233, -160,213,106, 81, 80, 80,128,246,237,219, 27,204,247,232,209, 35, 49, 0, 44, 88,176,128, 11, 64,204, 48, 12,244,122, 61,138, 57, - 11, 10, 10,184,237,218,181,115, 54,200, 68, 45,147, 69, 74,165,210, 22,253,251,247,191,119,240,224, 65,203, 90,181,106, 33, 49, - 49, 17,137,137,137,168, 91,183, 46, 54,110,220, 40,103, 89,182, 89,145,168, 58,101,224,109, 75, 45, 45, 45,185,113,113,113,208, -233,116,240,247,247,199,150, 45, 91, 48, 96,192, 0,212,175, 95, 31,185,185,185, 8, 15, 15,199,222,189,123, 45,121, 60, 94,159, -127,250, 25,162, 40,234, 47,226,170,244, 86,205, 14,134,153, 80, 40,204, 21, 8, 4,252, 98,255,171, 71,143, 30, 85,217,122, 85, -170, 93,122, 82,149,223,255, 36, 76, 77, 77, 97, 98, 98, 2,173,246,195,219,148, 72, 36,168, 91,183,174,193, 60, 38, 38, 38,164, -216,136,161,213,106,145,148,148,164,127,241,226,133, 62, 32,160,112,144,195,209,209, 81,255,240,225, 67,189, 82,169,164, 77, 77, - 77, 81, 52, 42, 66, 96,196,167,179, 96, 21, 91, 43, 42,178, 92, 21,127, 47,182, 68, 85,246,176,209, 52,141,139, 23, 47,150, 84, - 20, 47, 47,175,146,107,125,106,129,101,109,109, 45, 15, 14, 14, 54,139,143,143, 63, 80,157,255, 23,139,171,229, 75, 23, 90,101, -190,122,128, 4, 89, 18, 50, 83,181,161,119,158,191,189, 12,224, 50, 0, 96,187,247, 13,140,123,101,176,184,242,182, 21,251, 53, -144,154,158,248,162, 75,183, 26,253,199,126, 67, 77,156, 56,177,241,136, 17, 35, 50,134, 12, 25, 50, 81, 36, 18,121,235,116,186, -140,179,151, 46, 69,247,234,213,203, 65,167,211, 13,103, 89,214, 16,159,164,132,193,131, 7,243, 8, 33,176,179,179,227,238,219, -183,207,210,204,204, 12, 35, 70,140,200,122,251,246,173,182,168, 39,150, 82,197,219, 79,104,214,172,217, 95,134, 5,139, 95,236, -197,150,129, 42,138, 54,255,110,221,186,237, 60,124,248, 48,210,211,211, 33,151,203,193,229,114,177,122,245,106,196,197,197,253, - 68, 8,121,241,185, 52,102,126,126,126,236,195,135, 15,241,252,249,115,168, 84, 42,140, 30, 61,186,180,143, 97,135,127,122,164, - 32, 49, 49, 17,251,247,239, 7,195, 48, 24, 50,100, 8,106,213,170, 85, 34,172,146,147,147,177,123,247,110,232,245,122,140, 25, - 51, 6, 53,107,214,132, 86,171, 21,182,110,221,154,115,227,198, 13,221, 63,145,224,233,211,167, 71,159, 56,113,226, 66,124,124, -124,231,149, 43, 87,182, 34,132, 48, 51,103,206, 92, 97,102,102,246,183,102, 95,102,229,228,225,245,155,247, 37, 2,232,227,205, -214,198,170,202,124, 81, 49,241, 37,255,215,235, 75,243,233, 97,109,101, 89, 37,190,164,164,164,130,140,140, 12,249,232,209,163, - 45,118,238,220, 73,234,214,173,139,216,216, 88,112,185, 92,152,154,154, 22, 68, 68, 68, 84, 53, 52, 67, 98,102,102,166, 59, 77, -211,188, 55,111,222,192,197,197, 5,193,193,193,248,225,135, 31,144,158,158, 14,157, 78, 7, 59, 59, 59, 70,171,213,134,169,213, -234, 91,255,244,115, 84,218,202, 84,122,187,123,247,238,239, 52, 77, 83, 0,206, 0,168,146,192,102, 89, 86, 93,179,102,205, 15, -184,171, 99,189,250, 15, 90,236,254, 99, 51, 19, 61, 60, 60,110, 74, 36,146,110,175, 95,191,254,192,138, 53,120,240, 96,141,155, -155,219,109, 67,121,204,204,204,178,120, 60,158,181, 82,169,196,253,251,247,225,237,237,205,203,201,201, 89, 78, 8,153, 83,212, -185, 92,158,146,146,194,147, 74, 11,221,248, 60, 61, 61,145,151,151,151,101,148, 76,159, 88, 96,149,101,185, 42, 75,100,209,116, -229,174, 9,132, 16, 40, 20, 10, 72, 36,146,146,173,216,207,170, 44,129, 85,228,251, 83,173, 33,194, 34,113, 37, 58,120,240,224, -239, 27, 55,110,188,107,232,255, 74,251, 96,109, 95,187,116,101,177,184,122,118,247, 10, 78, 69,228,164,207, 90,190,126, 67,117, - 51,219,199, 86,226,235, 96,111,115, 99,245,143, 75,204,162, 47,238,197,225,237,235,216,103,143, 30, 53, 28,255,232, 81,159,241, -227,199, 91, 1, 72, 2,144, 8,224, 62,128,159, 12, 20, 87,136,140,140, 44, 9,238, 26, 16, 16, 16,111,105,105,105, 41, 18,137, - 32,147,201, 84, 79,158, 60,169,150,163,107, 84, 84,212, 39, 13,238, 74, 8,241,232,222,189,251,173, 99,199,142, 73,178,179,179, -241,254,253,123,204,156, 57, 19,155, 55,111,134,153,153, 25,206,157, 59,103,218,173, 91,183, 27,132,144,166,255,116,112, 85,127, -127,127,246,241,227,199,120,247,238, 29,116, 58, 29,122,244,232, 81,233, 4,142,255,178, 5,139,157, 54,109, 26,118,238,220, 9, -154,166,241,213, 87, 95, 33, 55, 55,183,228,184,149,149, 85, 89,199,232,162,231,253, 31, 17, 88, 28, 14,135,189,121,243,230,202, - 86,173, 90, 33, 62, 62,190,115, 96, 96,224,207, 35, 70,140, 72,252,187,188,150,230,166,240,243,113,133, 74,165,130, 74,165,130, - 84, 42, 69, 94, 94, 30,162,163,163,161, 82,169, 96,111,103, 81,101,190,128,250,117, 75,248,236,236,236, 32,151,203,241,246,237, - 91,168,213,106,216,216, 88, 86,165,206,215,232,216,177,227,245,223,127,255,221,250,247,223,127, 87,247,238,221,155,191,100,201, - 18, 98,102,102,134,212,212, 84, 84,211,189,231,230,157, 59,119,106,181,111,223,222,243,213,171, 87,184,121,243, 38,212,106, 53, - 2, 2, 2, 16, 21, 21,133, 38, 77,154, 32, 63, 63,255,225,227,199,143, 79,127, 14,117,181,120,248,174,120, 11, 9, 9, 57,196, -227,241, 88, 0,213,178, 54, 21, 35, 46, 46, 78,224,235,235,171, 18, 10,133,252, 34,177,246,183,248, 62,113, 91,247,183,102, 38, - 86, 4, 87, 87,215,105,206,206,206,237, 3, 2, 2,240,234,213, 43,158, 64, 32,192,208,161, 67, 53, 93,186,116,209,112, 56, 28, -131, 39,220,136, 68,162, 87, 38, 38, 38, 45, 85, 42, 21,212,106, 53,174, 92,185, 2,107,107,235, 89,221,187,119,159,154,148,148, - 4,153, 76,198,231,243,249, 37,254,183,173, 91,183, 70, 70, 70,198, 43,163,100,250, 68, 2,171,184,142, 24, 50, 60,104,168, 15, - 22, 69, 81, 80,171,213,144, 72, 36, 16,139,197,144, 72, 36, 37,215, 33,132,148, 41,176,170,131, 26, 53,106, 32, 56, 56, 88,116, -248,240,225,223,214,172, 89,115,175, 58, 28, 71,127,223,239,104,206, 20,212,144, 61, 60,143,200,231,161, 56, 17,158,157, 62,107, -249,250, 41,221,251, 12, 74,249, 88,144, 29, 25,103, 64,207,195, 78, 82,223,201,222,250,198,218, 85,203,205, 50, 95, 61, 64, 82, -114, 50,206, 63,124, 28,170, 42,244, 13,251,225, 19, 62,220, 40, 30, 91,255,156, 32, 16, 8,166, 29, 61,122, 84,146,157,157,141, -152,152, 24, 12, 25, 50, 36,251,221,187,119, 95,247,236,217,115,243,229,203,151, 45, 45, 44, 44,112,249,242,101,211, 26, 53,106, - 44, 7,208,237, 31,108, 28, 89,189, 94,143,204,204, 66,247,149,102,205,154,125, 86,226, 10, 0, 66, 66, 66,120,221,187,119,255, - 3, 64,219, 87,175, 94,129, 97,152,123,161,161,161,205,138,143, 87,116,204, 16,253,150,151,151,199, 53, 53, 53, 45,243,101,197, -227,241,120, 85,181, 56,148,230,188,123,247,238,138,181,107,215,158,152, 49, 99,198,155,191,201, 89,166, 5,171, 91,183,110, 80, -168, 52, 72, 72,201,129, 94,175,131, 66,147,250,183, 44, 88,221,186,117, 67,129, 82,141,184,164, 76,232,116,122,228, 41,116,134, -214, 35,241, 23, 95,124,113,233,224,193,131, 14,247,239,223,135, 74,165, 98, 66, 66, 66,222,142, 29, 59,214,108,212,168, 81,214, -229,133,182, 49, 0, 27, 7, 13, 26,212,247,238,221,187,153,158,158,158, 86, 15, 31, 62, 68,106,106, 42,116, 58, 29,218,182,109, - 11, 62,159, 31,183,124,249,114, 30, 12,112, 45,248,111, 9, 44,129, 64,128,240,240,240, 98, 97, 53,236, 83, 9, 33, 62,159, 95, -237, 97,198,255, 85,252,246,219,111,137,123,246,236,241,113,114,114,218, 48,108,216,176, 54, 82,169,148, 18, 8, 4, 55, 57, 28, -206, 84, 0,239, 13,229,225,241,120, 35, 44, 44, 44,162, 41,138,162, 19, 19, 19,241,230,205, 27,196,198,198, 2, 0,191,160,160, - 0,118,118,118, 37, 70,147, 65,131, 6,161, 70,141, 26,250,168,168,168, 17, 70,201,244,137, 45, 88, 75,150, 44,193,246,237,219, - 49,110, 92,197, 42,226,204,153, 51,192, 71, 67,132, 69,203,199, 92, 45,253,242,215,235,245, 88,184,112,225, 7,255, 43, 30,126, -250,250,235,175, 63,224, 60,121,242,228, 95,134, 8, 63,230, 44, 11,169,169,169,175,142, 28, 57,242,120,213,170, 85, 15, 13,108, - 12, 75, 56,139,125,176,250, 14, 30,154,180,105,197,247, 47,246,157,185, 86, 63, 73,193, 38,205, 90,190,126,198,199,226,202, 80, - 78,111, 7, 19,111,103, 59,235,155,107, 86, 45, 55, 47,182,134, 29, 12, 75,206,129,142, 29, 87,149,194, 50,228,222,117, 58, 93, -130,191,191, 63, 15, 48,108, 88,208, 16,206,106,136,148,191,112,170, 84, 42, 60,120,240, 0, 0, 48,114,228,200,236,119,239,222, -181,100, 89,246, 37, 33,228, 85,199,142, 29,111, 94,186,116,201,146, 97, 24,160,156,176, 20,255,173,116, 22,229, 27, 56, 28, 14, -220,221,221,171, 44,174,254, 91,233, 76, 74, 74, 26, 55,126,252,248,237, 42,149,138, 35,151,203,199, 25,122,172,178,116, 30, 57, -114,228,141,187,187,123, 43,148, 31,138,129, 41,178,176, 86,155,115,195,134, 13, 0,224,249,119, 56,203,179, 96, 29, 58,116, 8, - 12,195,160,134,131, 5, 84, 42, 21,196, 98,113,149, 56, 63,182, 96, 29, 62,124, 24, 12,195,160,166,163, 21,212,106,117,185,157, -151,143, 57,173,173,173,215,237,219,183,207, 57, 34, 34, 2, 9, 9, 9, 88,191,126,253,251,180,180,180, 46, 28, 14, 71,240,243, -207, 63,223,232,218,181,171,189, 78,167, 83, 85,181,220, 89,150, 85, 17, 66, 70, 52,109,218,244,215,101,203,150,197,122,121,121, -213,108,214,172,153, 69, 70, 70, 70,218,147, 39, 79,222,110,223,190,221, 68,167,211,141, 40,111,232,233,191,249, 28, 1, 64, 98, - 98,226,105, 0,220,170, 10, 43, 67,210,249,232,209,163,195, 69,220,231, 13,225,254,111,221,251,223,157,153, 88, 89, 58, 71,140, - 24,145,128,143,226,155, 85, 53,157,151, 47, 95,126, 55,120,240,224,165,245,235,215, 95,100, 98, 98,130,200,200,200,146,176, 72, -197,117,156, 16,130,126,253,250,225,235,175,191,198,165, 75,151,150,246,237,219,247,221,127, 58, 63,255, 53, 2, 75,175,215,199, -191,123,247,206,113,223,190,125, 52, 33, 4,191,253,246, 27, 74, 79,217,167,105, 26, 20, 69,129,195, 41,164,120,240,224,129,174, -178,152, 83,122,189, 62, 62, 36, 36,196,126,239,222,189,220, 98,147,113, 98, 98, 34, 24,134, 97, 82, 82, 82,168,223,127,255,189, -196, 26,198,225,112,240,224,193, 3,157, 70,163,137,171,234, 77, 69, 70, 70,126,146,222,219,173,151,239,166, 94, 58,127,210,166, -113,112,139,108, 51, 43,171, 50,187,174,197, 17,223, 43,172,220, 28,234,135,149, 63, 46,177, 40, 22, 87,135,194,146,179,149, 42, -125,155, 87,105, 5,207, 62,117,129, 62,123,246,172,233,103, 90,215, 22,182,106,213,138, 1, 96, 3, 96,126,241,172,206, 34,145, -213,184,110,221,186, 51, 0,136, 0, 44,252, 39,173, 87,165, 67,131,124,110,150,171,210, 8, 13, 13,141, 5,208,174,170,199, 42, - 67,223,190,125, 99, 80, 70,192,207,191,131,255, 4,103, 49, 50,179,115, 17,243, 46, 17,133,206,232, 12,244,239, 83, 74,252,166, -180, 90, 29, 50,115,171, 20, 70, 14, 89, 57,121,136,126,155, 88,180, 52,152, 30,122,189,172,136,175,208,209,157,205, 42,168,148, -131,203,229, 54,223,176, 97, 67, 23,138,162,168, 7, 15, 30,168, 86,173, 90, 21,159,150,150,214,131,101,217, 56, 0,144, 74,165, -173, 79,158, 60,249,155, 1, 33, 25,202,235,248,134, 19, 66,154,204,158, 61,123, 10,128,230, 0,106, 2,136, 67,225,140,227,141, -159, 89,196,241, 97,255,163,220,213,198,255,202,204,196,223,127,255,125,241,215, 95,127,205, 9, 14, 14,158,219,176, 97, 67,234, -237,219,183, 72, 77, 77, 5,135,195,129,135,135, 7, 58,116,232, 0, 23, 23, 23,230,220,185,115, 63,246,234,213,107, 49,140,248, -116, 2, 43, 61, 61,189,227,176, 97,195,174, 80, 20, 85,187,244, 48, 94, 89,159, 0,192, 48,204,187,148,148,148, 10,131,144,165, -167,167,119, 92,184,112,225, 21, 14,135, 83,187, 84,252, 43, 85, 70, 70,198,215,253,250,245,219,194,229,114, 5,165,173, 93, 12, -195,188, 79, 74, 74,250,175, 58, 20,127, 28, 7,171, 99,151,158,233,127,151,211,132, 71,185, 69,158,219,137,148,212,116, 28, 10, - 75,206,202, 83,235, 91, 71,166,201, 95,252,155, 42, 26,203,178,169, 0,190, 46,231,216, 27, 0,227, 62,131, 52,146, 34,145,101, -156, 45,243, 63, 0,157, 78,151,208,190,109,107,124, 28,150,225,227,223,122,189, 62,193, 80,190,118,109, 90,149,203, 83,252,189, - 50, 62,154,166,103, 4, 7, 7,211, 51,102,204, 72,185,112,225,194, 31, 89, 89, 89,211, 89,150, 45, 81,102, 69,179, 6, 3,255, -102, 93, 85,161,112,133,135, 85,198,154,240, 89,182,119,255, 19, 51, 19,183,108,217,178, 96,214,172, 89,123,157,157,157,247, 55, -111,222,220,211,205,205,205,204,212,212, 20,185,185,185,121, 89, 89, 89,175,207,158, 61, 59,100,216,176, 97,177,198, 18,253,196, - 2, 43, 45, 45, 77, 14,160,201,167,188, 88, 37,156,181, 62,155, 46,151,106,213, 1,108, 95,245,193, 58,132,197,226,171,204,223, -149, 72,131, 28,133,110,226,198, 75, 47,215,168,116, 44,163,209, 49, 35, 35, 83,229,225,198,170,247,217, 54,140, 70,113,245, 63, -130, 23, 47, 94, 4,125,142,124,106,181,122,106,211,166, 77,127,210,235,245,107,181, 90,237, 29, 99, 73, 25,241, 57, 99,213,170, - 85,177,197,239,229,126,253,250,209, 0,112,228,200, 17,189, 49,103,254,131, 2,235,223,138, 35, 47,255,124,193,126, 44,156, 42, -251, 93, 30, 94, 39,231,223,252,187, 61, 86, 35,140, 48,226,127, 70,164,199, 1,232, 97,204, 9, 35,254,231,222,127, 70, 97,245, - 73, 65, 25,179,192, 8, 35,140, 48,194, 8, 35,140, 48,226,211,130, 0,104, 95, 78, 47,204,224,217, 1,132,144,246, 85,189,176, - 1, 43,134, 27, 57,141,156, 70, 78, 35,167,145,211,200,105,228,252,127,198,249,175, 65,105, 71,206, 79,189, 1,104,111,228, 52, -114, 26, 57,141,156, 70, 78, 35,167,145,211,200,249,111,219,140, 67,132, 70, 24, 97,132, 17, 70, 24, 97,132, 17,159, 24, 70, 39, -119, 35,140, 48,194,136, 82,144, 74,165,221, 1, 44, 70,161, 11,197,114,153, 76,118,216,152, 43, 70,252,127,130,173,173,173,196, -218,218,250, 15,138,162,106, 1, 31,134, 92, 42, 35,184, 55,244,122,125, 82,102,102,102,135,228,228,228,244,255, 38,231,191, 78, - 96,181,173,107,209,194,181,142,203,239,105,169,233, 97,249,202,220, 81,127,188,206,203,172,206,133, 9, 33,214,124, 62,127,128, - 68, 34,105,207,178,172, 43, 77,211, 17, 57, 57, 57, 87,181, 90,237, 65,150,101,243,141,143,128, 17,255, 52,252,253,253, 27,240, -249,252, 89,132,144,198, 58,157,206,153,203,229,202, 0, 60, 84,169, 84,171,195,194,194,194,140, 57,244,255, 3,132, 16,202,209, -209,241, 39, 11, 11,139,224,236,236,236, 33, 0,230, 70, 70, 70,250, 82, 20, 5, 31, 31,159,185, 82,169, 52,218,204,204,108, 87, -110,110,238,189,164,164,164,169, 85, 89, 59,206,136,207, 23,110,110,110, 33, 20, 69, 57, 23, 47,201,246,177, 32, 40, 75, 32,176, - 44, 27, 27, 30, 30, 94,110, 48,103,103,103,103, 87, 51, 51,179, 45, 0, 26,126, 44, 42, 62, 70,209, 48,219,227,220,220,220,175, - 19, 18, 18,202, 12,196,107,101,101,101,106,103,103,183,152, 16,210,143,162,168, 74, 23,252,101, 24, 70,207,178,236,145,212,212, -212,133,153,153,153,121,229,157,103,109,109,125,245,214,173, 91, 13,109,108,108, 42, 13, 75,163,211,233,144,152,152,104,219,181, -107,215, 91, 0,188,254,155,156,255, 58,129, 5,150, 26,186,122,222, 24,167,180,248,104,167,185, 27,142,123,180,240,178,105,125, - 59, 34, 61,185, 42, 20, 34,145,104,128,175,175,239,198,159,126,250,201,218,197,197,133,136,197, 98, 36, 37, 37,121, 61,121,242, -164,215,162, 69,139, 22,114,185,220, 17, 90,173,246,202,223,108, 52, 45,172,196,156, 89, 25,114,237,119,198,166,196,136,170,160, - 95,191,126,116,124,124,252, 34, 27, 27,155,111,231,204,153, 35,168, 93,187, 54, 76, 76, 76,144,154,154, 90,243,205,155, 55, 53, - 54,111,222,220,189,105,211,166, 63,171,213,234,249,161,161,161, 90, 99,142,253,111,195,209,209,241,167, 83,167, 78, 77,242,244, -244, 68,203,150, 45,239,249,251,251,155,137,197, 98, 92,188,120, 17,110,110,110,245,204,204,204, 30,110,219,182,141,187,120,241, - 98,191,227,199,143, 3,192,100, 99,174,253,239,131,162, 40,231,176,176, 48, 59,177, 88, 12,189, 94, 95, 20,189,159, 1,203,178, - 37,159,165,197,144, 94,175, 71,155, 54,109, 52, 21,113, 10,133,194,205,207,159, 63,111, 95,188,142, 95, 41, 33, 85, 38,100, 50, - 89,251, 54,109,218,108, 6, 80,102, 64,109, 59, 59,187,197,253,251,247,159, 86,191,126,125, 0, 40, 73,103,241,103,122,122, 58, - 38, 78,156, 88,114, 13,134, 97,112,235,214,173, 41,223,124,243, 13, 0,124, 83,193,189,215,178,177,177, 33,149, 45,129,183,104, -209, 34, 44, 90,180, 8, 27, 55,110, 36, 28, 14,199,162,146,252,252,228,156,255, 58,129, 69, 40,114,126,211,182,189,163,166,247, -111, 76, 86,141,109,225, 62,111,215,141,251,237,235, 88,182,188, 26,155, 21,111,160,184,154, 50,126,252,248, 21, 75,150, 44, 17, -190,126,253, 26,225,225,225,208,233,116, 48, 53, 53,133,175,175, 47,117,254,252,121,199,169, 83,167, 30,229,243,249, 35,213,106, -245,241,234,222,152,131, 25,119,181, 68, 64, 13,230,115, 56, 15,213, 58,221,233,207, 49,243, 93, 92, 92, 46,107,181,218,149,137, -137,137,215,255, 87, 42,140, 84, 42,109,198,231,243, 23,190,123,247,174, 19,203,178,186,255,143, 15, 69, 92, 92,220,146,230,205, -155, 79, 95,180,104,145,224,237,219,183,136,138,138,130, 76, 38, 67,237,218,181,225,226,226, 66, 54,110,220, 40,252,249,231,159, - 39, 63,125,250,148, 11, 96,122, 85, 44, 37, 14, 14, 14,163,219,181,107,215,199,198,198,198, 60, 49, 49, 49,231,238,221,187,167, -146,146,146,118, 84, 55, 47, 9, 33,148,141,141,205,240,110,221,186,245,177,178,178,178, 74, 78, 78,206,186,122,245,234,201,212, -212,212, 93,127,199,210, 66, 8,113, 4,224, 11,192,186,104, 87,146,139,139,203,203,183,111,223,166,126, 66, 78,153,139,139, 75, -120,117, 56,109,109,109, 37, 28, 14,231, 48, 33, 68, 90,129,133, 64,166,211,233,250, 23, 5, 56, 46, 23,102,102,102,141,221,221, -221, 17, 26, 26,138,249,243,231, 91,181,105,211, 6,111,222,188, 1, 33, 4, 51,102,204, 32, 62, 62, 62,220,164,164, 36, 4, 5, - 5,225,234,213,171, 77, 97, 68, 85,202,252, 8, 0, 11, 0,131, 88,150, 77, 47,181,223, 6,192, 73, 0,169, 44,203,246,254,167, -210, 39, 18,137,112,240,224, 65,112,185, 92,112,185, 92,100,101,101,193,217,217,185,228, 55,143,199, 43,249, 94,179,102,205, 74, -249, 24,134,105, 68,211, 52,242,243,243,161,215,235, 75,182,236,236,108,176, 44, 11,129, 64, 0,189,190,112,217,165,226, 99, 12, -195, 52,170, 32,255,250, 73,165, 82, 28, 56,112, 0,106,181,186,172,186,139, 23, 47,254, 92, 20,132,166,105,248,249,249, 81,132, -144,126, 21, 9, 44, 66, 8, 11, 0, 99,199,142, 5, 77,211, 37, 75,223, 21,127, 47,222,244,122, 61, 22, 45, 90, 84,232,176, 77, - 81,149,149,245, 39,231,252,159,175,255, 21,169,235, 54,110,150, 95,183,110,209,120,181, 80,192, 17, 49, 58, 45,244, 58, 45, 24, -157, 26, 52, 97,208,194,219, 14, 1, 53,133,200,204,202,195,252,253, 79,115,101, 25,202,224,203, 81, 25,145,149, 20,128, 75,112, -112,112,216,181,107,215, 44,254,248,227, 15, 68, 70, 70,226,135, 31,126, 0, 0, 72, 36, 18, 92,188,120, 17, 52, 77,131, 97, 24, -116,234,212, 41, 77, 38,147,121,177, 44,155, 89,141,135,186, 86,203,250,206,161,199,191,107,105, 85,111,194,209,247,201, 57,106, - 87,150,101, 63,187, 0,106, 82,169,148,229,114,185, 5, 58,157,174,251,255,130,200,146, 74,165,205,184, 92,238, 69,157, 78, 39, -230,114,185,162,119,239,222,169,254,191, 61, 16,254,254,254, 13,172,172,172, 30,156, 56,113, 66,248,232,209, 35,100,101,101, 33, - 53, 53, 21, 83,166, 76,193,214,173, 91, 81,175, 94, 61, 72, 36, 18,240,249,124, 76,156, 56, 81,145,151,151,215, 58, 36, 36,228, -177, 1,117,146,110,217,178,229,129,223,126,251,205, 69,167,211, 81, 0,160, 86,171, 17, 31, 31,175,159, 55,111, 94, 92, 72, 72, -200,160,170,138, 44, 66, 8,213,180,105,211,253,191,253,246,155, 27,159,207,167, 24,134,129, 86,171,197,155, 55,111,244,243,230, -205,123, 23, 26, 26, 58,184, 58,245,158, 16,226, 47, 22,139,125,190,254,250,235,180, 30, 61,122,104, 0,224,241,227,199,212,179, -103,207,204,234,212,169,243,126,193,130, 5, 97,213,224, 12, 52, 53, 53,245, 28, 55,110, 92,122,183,110,221,180, 60, 30,143,185, -123,247, 46, 39, 50, 50,210,204,197,197, 37,102,238,220,185,207,170, 88, 23,207,157, 56,113,162,181, 84, 42,213, 3, 96,139, 27, -120,138,162,216,162, 79,196,196,196,112,250,246,237,123, 67, 38,147,125, 89, 97,103,204,193,193,219,209,209,241,214,130, 5, 11, -172,138, 95, 82,165,183,226,178, 90,180,104,145, 38, 41, 41,169,177, 76, 38,123, 2, 35, 12, 45,247,135, 0, 26, 1,120, 9,160, - 45,203,178,233, 69,226,234, 58, 0, 31, 0,119, 89,150,109,254, 79,164,205,211,211, 51,229,197,139, 23,118,167, 78,157, 2,151, -203,197,149, 43, 87,176,117,235, 86, 28, 60,120,176, 76,145,229,232,232,136, 22, 45, 90, 36, 60,121,242,164, 70,121,156,110,110, -110, 57,209,209,209,102, 57, 57, 57,208,235,245,120,248,240, 33,118,237,218, 5, 59, 59, 59,216,216,216,192,214,214, 22,141, 26, - 53,130, 68, 34, 41, 17, 89,253,250,245,203,141,142,142, 54, 47,139,207,219,219, 91, 54,100,200, 16,199,208,208, 80,104,181,218, - 50, 5,214,180,105,211, 74, 91,145, 32,145, 72,208,163, 71,143,164, 87,175, 94,149,219,249,168, 87,175, 94,210,203,151, 47, 29, -158, 61,123,246, 65, 93, 47, 75, 16,209, 52, 13, 83, 83, 83, 52,105,210, 36,229,201,147, 39, 14,255, 77,206,255,215, 22, 44,247, - 90, 14,243,190, 27,223, 83, 4,189, 6,172, 86, 1,104, 10, 0, 77, 62, 24,117, 1, 8, 79, 4,104, 21,176,226,103, 98,227,176, - 58,102,203, 79,189,123,213,214,213,182,235,181,152,180,139,229,241, 89, 88, 88, 44,218,182,109,155,197,139, 23, 47, 16, 25, 25, -137,117,235,214, 97,233,210,165,224,241,120,200,204,204, 68,247,238,221,113,239,222, 61,104, 52, 26,204,159, 63,223,106,246,236, -217,147, 80,232,108, 90, 69,235, 21,103,235,225,221, 27,173,172,232, 12,140,108, 27, 98,189,249,242,219,175, 1,252,252, 57, 22, -192,234,213,171,197,179,102,205, 58,227,228,228,244, 89,139, 44,169, 84,218, 76, 36, 18, 93,156, 54,109,154,100,197,138, 21,159, - 68,172, 58, 59, 59,215,227,112, 56,135,212,106,245,140,164,164,164, 75,213,104,188,107, 7, 7, 7,175, 8, 15, 15, 63,150,159, -159,127,164,172,115, 76, 76, 76,250,121,122,122,246, 12, 9, 9,153,199,178,236,219,202, 56, 5, 2,193,148,153, 51,103, 10, 19, - 19, 19,145,157,157, 13, 62,159, 95,178,202, 60, 33, 4, 2,129, 0, 20, 69,129,207,231,227,171,175,190, 18,254,242,203, 47,223, - 0, 24, 88,105,157,116,112, 24,181,127,255,126, 23,141, 70, 67,201,229,114,240,120, 60,240,120, 60, 52,104,208,128,158, 57,115, -102,141, 41, 83,166,140, 7,176,169, 42,247,111,105,105, 57,108,255,254,253,110,124, 62,159, 74, 74, 74, 66,179,102,205,240,240, -225, 67, 4, 7, 7,211,179,102,205,170, 57,105,210,164,177, 0,182, 86,213,202, 36, 22,139,235, 95,191,126, 61,190, 70,141, 26, - 37,189,175,218,181,107,235,187,118,237,154, 25, 17, 17,225,121,255,254,253,140, 38, 77,154,196, 85,129,211, 73, 44, 22,123,157, - 63,127, 62,105,201,146, 37,237,182,111,223,222, 3, 0, 26, 53,106,116,122,233,210,165,215, 50, 51, 51,235,221,190,125, 59,179, - 69,139, 22, 9, 85, 72,170,181,189,189,189,238,235,175,191, 54, 45,239,132,189,123,247,102, 0,176,171,164, 94,119,167, 40,106, -113,189,122,245,204,218,180,105,131, 91,183,110, 97,242,228,201, 42,173, 86, 27, 5, 0,237,219,183,247, 88,180,104, 17, 63, 52, - 52, 20, 22, 22, 22,220,164,164,164,221, 82,169,212,232,248,110, 56,122, 0,184, 1,160, 30,128,107,132,144,254, 0,142, 2,240, - 6, 16, 9,160,239, 63,153, 56,189, 94, 15, 14,135,131,132,132, 4,252,242,203, 47,248,241,199, 31,225,238,238, 14,173, 86, 91, - 34,176, 56, 28, 14,184, 92, 46, 8, 33, 6, 47,165,165,211,233,240,248,241, 99,236,255,245, 87,204,159, 55, 15,166,166,133,213, - 84,163,209, 32, 51, 43, 11, 66,161,176,196,130, 85, 17, 88,150, 61,242,230,205,155,105,206,206,206, 31, 12, 13, 22,127, 22,181, -113, 96, 24, 6, 58,157, 14, 42,149, 10, 59,119,238,212,177, 44,123,164,146,103,178,196,226, 53,109,218, 52,168, 84,127,246,149, -125,125,125, 1, 0, 46, 46, 46,240,243,243, 43,249, 93,108,161, 50,132,115,103,211,250, 80,148, 58,219,115,209,154,226, 54, 31, -158,158,158,112,116,116, 52,136,243,255,181,192,138,138, 75, 93, 57,107,241, 79,107, 36,124,154, 59,162,179, 55,164,102, 92, 64, -100, 5, 94,203,217, 32, 22,181, 10, 43, 64,102, 44,112,121, 54,230,119,200,160,230, 40, 52, 39, 59,187, 89,217, 94,136, 46,215, -185,174, 81,141, 26, 53,112,251,246,109,212,169, 83, 7, 11, 22, 44,128,151,151, 23, 36, 18, 9, 82, 82, 82, 32,151,203, 33,145, - 72,144,155,155,139,128,128, 0,218,212,212,180, 77, 85, 5, 22, 33, 36, 96,116,247,224, 70, 28,123,111, 52,107,215, 24,151, 23, -182,150,236,189,153,248, 29, 33,100,119,233, 5, 87, 63, 23,244,237,219, 23,201,201,201,226, 13, 27, 54, 84, 91,100,185,184,184, - 92,214,104, 52, 95, 24, 96, 14,191, 30, 29, 29,221,182,186,226,234,204,153, 51, 18, 83, 83, 83,172, 88,177,226, 83,137,171, 59, - 29, 59,118, 52,187,116,233,210, 9, 71, 71,199, 94, 85, 17, 89,132,144,218,253,250,245, 59,187,107,215, 46,143,182,109,219,234, - 1,148,217,160,248,248,248,244,185,124,249,114,239,209,163, 71,215, 39,132,116,171, 76,100, 17, 66,154,214,174, 93, 27,241,241, -241, 72, 73, 73,129, 82,169, 68, 74, 74, 10, 0, 32, 33, 33, 1,206,206,206,176,176,176,128,179,179, 51, 60, 60, 60, 8, 69, 81, -193,134,164,183, 77,155, 54, 61, 0, 80, 49, 49, 49, 72, 75, 75,131,185,185, 57, 36, 18, 9,156,157,157,209,186,117,107,142,155, -155, 91,151,170, 10,172,206,157, 59,247, 17,139,197, 84,124,124, 60,222,190,125, 11,149, 74,133,168,168, 40,152,155,155,163, 93, -187,118, 92, 55, 55,183,110, 85, 21, 88, 0,234,143, 29, 59, 54,165,180,184, 42,134, 68, 34, 33, 30, 30, 30,153,214,214,214,129, - 0,226,170,194, 57,105,210,164,212,229,203,151,183,188,122,245,234,236,226,157, 87,175, 94,157, 5, 0, 63,253,244,211,109, 91, - 91,219, 64, 0, 85, 17, 88, 96, 89,150, 25, 61,122,244, 27, 30,143, 7, 62,159, 95,178, 9, 4, 2,112,185, 92,208, 52,109,110, - 0,205,220,200,200, 72, 95, 19, 19, 19, 68, 70, 70,130,166,105, 16, 66,222,200,100, 50, 95, 0,152, 61,123,118,180, 66,161,112, - 85, 42,149,232,219,183, 47,233,222,189,123,131,117,235,214,205, 3,240, 89, 8, 44, 66, 72, 67, 0,235, 0,168, 1,204, 99, 89, -246,225,231,212,190,177, 44,155, 66, 8,105, 93, 74,100, 61, 1, 32, 40, 18, 87,173, 89,150, 77,249, 7,243, 14, 12,195,128,203, -229, 98,205,154, 53,208,104, 52,248,237,183,223,112,244,232, 81, 80, 20, 85,226,232,110,102,102,134,141, 27, 55,254,197,241,189, - 50,225,182,119,239, 94,204,158, 53,171, 68, 92, 1, 0,143,199,131,131,189, 61,172,109,108, 16, 19, 19, 83,169,192, 74, 77, 77, - 93,248,232,209, 35, 84,228,228,222,187,247,159, 35,172,165,157,220, 13, 73, 39, 77,211, 80,169, 84,248,226,139, 63, 95, 31,147, - 38, 77, 42,249,158,153,153, 89,252, 76,128, 24,120,243, 52, 77, 67,193, 2, 61,133,127,238,235, 50, 99, 70,201,247,244,244,244, - 42,115,254,191, 20, 88, 45,163, 51, 55,221, 35,240,155, 53,178,221,112,169,141, 25,216,252, 20,240,218, 46,196,243, 76, 49, 54, -108, 43,124, 23, 78,235, 27,128,250,237,151, 65,189,167, 3, 70,249,235,249,223, 36, 97, 38,128, 5,101,241,217,216,216, 88,235, -116, 58, 16, 66, 32,145, 72,224,237,237, 13,161, 80,136,180,180, 52, 76,158, 60, 25, 23, 47, 94,132, 70,163, 1,143,199, 67,157, - 58,117,160,209,104, 92,171, 97,189,218,181,126,245,143, 22, 25, 97, 7, 16, 26,155, 13,177,117, 13,204, 27,212,200,114,209,111, -143, 22, 2,152,245, 57, 22,130,159,159, 31,150, 44, 89, 34, 94,184,112, 97,181, 68,150, 70,163, 89,202,229,114,155,253,248,227, -143,162, 65,131, 6,253,229,248,211,167, 79,209,183,111, 95,133, 82,169,252,161,186,226,234,244,233,211, 18, 43, 43, 43,196,199, -199,227,239, 62, 19,197,226,234,247,223,127, 55,171, 85,171, 22,234,213,171, 39, 92,187,118,173,193, 34,139, 16,226,219,187,119, -239,227,187,118,237,170, 53, 98,196,136,247, 33, 33, 33, 41,132,144,242,132,184,108,228,200,145,239,247,236,217,227, 65, 8, 57, - 91,153,200,210,233,116, 53,197, 98, 49,210,210,210, 48,117,234,212, 15, 28, 84,139,135,179, 1, 32, 50, 50, 18,206,206,206, 80, - 42,149, 78,134,220,179,149,149,149, 37, 0,140, 25, 51, 6,241,241,127,186, 43, 58, 57, 57, 33, 62, 62, 30, 58,157,206,170,170, -249,104,101,101,101,165,213,106,209,162, 69, 11, 40,149, 74, 0, 64,255,254,253,193,229,114,145,154,154, 10,141, 70, 99, 93,141, -226,177,233,218,181,171,172,188,131,102,102,102, 26, 75, 75, 75,239, 42,114, 90,119,239,222, 61,113,199,142, 29,127, 25,170,123, -244,232,209,151, 86, 86, 86, 87,173,172,172, 60,170,145, 86,166,180,160, 42,254,206,231,243,139, 45, 14, 6,245,142, 25,134,193, -185,115,231, 64,211, 52, 56,156, 63,155,196, 5, 11, 22,140,179,176,176,176,191,117,235, 22,146,147,147, 33,151,203,145,159,159, -143,186,117,235,214,105,223,190,253,211,228,228,228,119,225,225,225,189,254,105, 35, 56,128, 98,191,176,173, 0,252, 62,183,246, -173, 72,100,245, 3, 16, 82, 36,174,212, 0,250,252,147,226,170,116,217,115, 56,156,146,231, 92, 40, 20, 34, 32, 32,160, 68, 76, - 17, 66, 80, 80, 80, 0, 14,135, 83,236, 47,100, 80,227,151,157,157, 13, 71, 7, 7,152,154,154,162,174,187, 59,222, 68, 69, 1, - 64,201,119,129, 64, 0, 66, 8,116,186,138,189, 2,138,102, 2,126,131, 10,252,169,170, 41, 46,217, 98, 49, 84, 73,251, 15,134, - 97,138,219,124,246, 83,112,218,216,216, 32, 63, 63,223, 32,206,255,183, 2,107, 49, 33,212,189,186, 86,191,204, 26,222,122,120, - 11, 15, 75, 40,211,222, 66, 96,106, 3, 98,225,130, 13,219, 46,225,213,187, 66,215,168, 13, 71,195,176,247,187,142,128,200, 10, -174, 38,145,176,145,136,123,149, 39,176, 50, 51, 51,229, 90,173,214, 74, 36, 18,129,195,225,128,207,231, 35, 35, 35, 3, 11, 22, - 44,192,225,195,135,225,226,226, 2,189, 94, 15,129, 64,128,212,212, 84,240,120,188, 42,205, 78,228,112, 72,215, 69, 99, 58,215, -150, 56,184, 35,227,202,210,194,157,246,254, 24,219,157,226,175, 61,254,124, 24, 33,100, 45,203,178,169,159, 91, 33,152,152,152, -160, 81,163, 70,152, 48, 97,130,120,219,182,109,251, 0, 56, 87,229,255, 50,153,236,174, 84, 42,237, 48,111,222,188,203,137,137, -137,162,198,141, 27,195,196,196, 4, 38, 38, 38,136,136,136,192,255,177,119,237, 81, 81, 92,121,250,171,170,126, 3,205, 75,161, - 21, 80, 48, 1,154,230, 49,108, 0, 17,118,112,243, 24, 53,146, 77,102,141,102, 98, 98,226,104, 52,179,192,100, 93,204, 26, 95, -135,205,104,194, 14,171, 39,103,116, 18, 71,196,179, 74,102,207, 1, 93, 38,232,134, 56,113, 9,230,140,154,241, 57,193, 30, 26, - 21,232,238,129, 70, 4,177, 5, 58, 60,187,171,155,174,187,127,208,221,211,102,120,116, 35,137,168,245,157,115, 79, 83,221,156, -175,234,222,170,186,247,171,239,254,238,175,242,243,243,205, 44,203, 62, 63, 25,119, 76, 40, 20,150,102,103,103,251, 74, 36, 18, -232,116, 58, 4, 7, 7,223, 83, 93,157,226,234,200,145, 35,254, 74,165, 18, 13, 13, 13,200,204,204,196,236,217,179,165,155, 54, -109,154, 80,100, 57,158,120,126,125,244,232,209, 40,129, 64, 64,125,242,201, 39,243, 0,228,123,178,239,178,178,178,184,138,138, -138, 95, 81, 20,181,140,140, 17,124, 40, 18,137,218,140, 70, 99,244,156, 57,115,112,232,208, 33,208, 52,141,142,142, 14,108,223, -190, 29, 69, 69, 69, 88,176, 96, 1,228,114, 57,230,204,153, 3,157, 78, 7,169, 84,218,225,201,190,111,222,188,217,205,113, 92, -232,201,147, 39, 97, 52, 26, 93,223, 71, 70, 70,162,167,167, 7, 22,139,165,203,219,182,108,107,107,235, 2,160, 80,171,213,104, -105,105,193,210,165, 75,113,252,248,113,164,165,165,193, 17,143,213, 53,137, 83,100,103, 24,134, 76,208,254, 65, 83,201,233, 24, -180,188,229, 4, 33,132,184, 11, 42,231,223,206, 34, 16, 8, 60, 9,242,255,165, 74,165,218,249,216, 99,143,197, 23, 20, 20, 8, - 25,134, 65, 86, 86,150,242,157,119,222, 49, 72,165,210, 25, 91,183,110,245, 25,205, 12, 6,144, 28, 31, 31,239, 59, 13,186, 15, -119,151,110, 90, 46, 58,161, 40, 42,212,225,248,137, 1, 88, 29,159, 71, 40,138,122,198, 61,240,253,126, 58, 88, 59,119,238, 68, - 78, 78, 14, 20, 10, 5,182,108,217, 2,129, 64,224, 42, 20, 69,185, 28, 45,111, 16,170, 80,140,251,187, 51, 6,107,130,135,168, -239, 36, 77,131,167, 98,104,100, 92, 21,120,228,222,125, 23,156, 15,165,192,114,138,171, 45, 63, 93,184, 38, 75,233,143,154, 51, -127,194,211,143,211, 0, 43, 30,167, 11,181,129, 18,249, 66, 33,167, 35,198,177, 14,213, 6,131, 97,110, 96, 96, 32,172, 86, 43, -196, 98, 49, 18, 19, 19,113,254,252,121,176, 44, 11,139,197,226,234, 28,175, 94,189, 10,171,213,122,198,139,155,133, 81,200,133, - 31,110, 46,120, 95, 14,205, 97, 4,250,138,241,116,106, 52, 48, 67, 5,166,187, 17,191,218,248, 66,240, 63,239, 58,182, 23, 30, -196,203,220, 15,129,165,213,106, 81, 82, 82, 50,104,177, 88,126, 58, 25, 14,167,200, 42, 46, 46,174, 14, 12, 12,148, 61,249,228, -147,208,104, 52,216,180,105,147,153,101,217,127,156,108,124,151,205,102, 91,251,217,103,159,157,140,142,142,246, 93,184,112,225, - 93,118,247,100,196, 21,195, 48, 95,173, 91,183, 78, 30, 21, 21, 5,189, 94,143,128,128, 0,248,249,249, 97,222,188,121, 40, 47, - 47,151,174, 90,181,106, 92,145, 69, 8, 33, 20, 69,229,173, 92,185,178,170,180,180, 52,114,237,218,181,134,202,202,202, 42, 0, - 99,117, 38,242,229,203,151,191, 80, 90, 90, 26,185,126,253,250, 70, 0,111,147,113, 86,118,112, 28,119, 78,167,211, 61,174, 82, -169, 40,165, 82, 9,177, 88,140,240,240, 17,147, 42, 57, 57, 25,241,241,241, 16, 10,133, 0, 0,173, 86, 11, 0,151, 60,169,251, -217,179,103, 63,109,106,106, 90,151,150,150,198,204,154, 53,203, 21, 60, 43, 18,137, 80, 88, 88,104, 53, 24, 12, 39,188,109,207, - 47,191,252,242,184, 70,163,121, 51, 43, 43, 75, 16, 20, 20, 4,137, 68,130,164,164, 36,132,133,133,161,176,176,208,218,220,220, -124, 98, 18,167,169, 85,163,209, 72, 99, 99, 99, 71,237,249,101, 50,153, 63, 0,111,157,135, 27,151, 47, 95, 22,103,100,100,124, -250,249,231,159, 39,186,255,144,158,158,254,169,159,159, 95, 0,128,142, 73, 28, 43,231, 46,168,156,197, 57,101,232,137,192,106, -111,111,175,154, 53,107,214, 95, 20, 10,197, 31, 19, 18, 18, 2, 52, 26, 13, 10, 10, 10, 68, 22,139,101,110, 77, 77,141,107, 32, - 30,229, 58,196,192,192,128,108, 26,116, 31,249, 0,246, 0,240, 1,176,101, 26,138, 43, 5, 70, 2,218,227, 48, 50, 45,248,178, - 67,108, 57, 99,178,238,171,200, 34,132, 64, 40, 20, 34, 46, 46, 14, 27, 55,110,196,174, 93,187,144,151,151,135,216,216, 88,215, -185,119, 6,185,123,227, 96,137, 68, 34, 40, 20,138,145, 69, 39, 14,247, 10, 0,180, 77, 77, 16, 8, 4,224, 56, 14, 44,203, 78, -232, 96,133,134,134,238,220,189,123,247,134,236,236,108,250,219, 43,238,156,105, 37,220,139,205,102, 67, 85, 85,213,134,162,162, - 34,120,226,122, 49, 12,131,228,228,228,187,166, 5,247,237,251,107,164, 66, 74, 74, 10, 22, 47, 94,236,145,104,114,231,140,219, -241,193, 93,211,130,191, 15,249,107,179,205, 89,253, 51,196,254,242, 35,175, 56, 31, 84,140,186, 70,242, 92, 76, 96,225,150,215, -126,184, 38, 43, 70,142, 47,206, 92,193,222,223, 55, 55, 24, 58,186,192,117,106,192, 25,175, 35,255,165, 20,196, 71, 5, 35, 62, - 42, 24,249, 47,165,128,187, 93, 15,210,163, 7,145, 4,226,134, 9,237,227,216,166,187,222,127,255,125, 83,112,112, 48,100, 50, - 25,196, 98, 49,218,218,218,144,144,144, 0,137, 68,226,122, 2,165,105, 26, 5, 5, 5, 70,163,209,120,192,211,138,248,138,233, -159,237,250,183,151, 21, 34,169, 31,112,227, 12,252,229,126, 56,244,155, 15,128,254,118,128, 17,225,133, 39,255,142,153, 61, 51, -240, 25,138,162,148,211,237, 36,232,245,122,108,216,176, 97,208,108, 54,223, 83,160,123,123,123,251, 31,173, 86,235,146,162,162, -162,161,178,178,178,123, 22, 87, 78, 78,150,101,151,238,217,179,103, 64,167,211,221,147,192, 18, 8, 4, 91,109, 54,155,127, 73, - 73, 9,151,154,154,106, 95,182,108,153,125,201,146, 37,246,204,204, 76,123, 66, 66,130,125,197,138, 21,118,179,217, 44,241,241, -241,217, 61, 65,167,120,173,178,178,114,209,250,245,235, 27, 75, 75, 75, 35, 23, 44, 88, 16, 70, 8,249,197,104, 37, 45, 45, 77, -225, 20, 87, 21, 21, 21, 19,198, 96, 89, 44,150,125,197,197,197,102,231, 42, 23,177, 88,140,144,144, 16,151, 16, 22,137, 68,144, - 72, 36,176, 90,173,216,191,127,255,208,208,208,208, 94, 79,234,222,213,213,117,120,243,230,205,173,213,213,213,182,222,222, 94, - 80, 20,133,155, 55,111,162,176,176,208,122,240,224,193,155, 38,147,233,160,183,237,217,219,219, 91,186,121,243,230,150, 19, 39, - 78,216,104,154, 70, 79, 79, 15,252,253,253, 93,156,125,125,125, 94,115,102,102,102,234, 12, 6,131,255,224,224,224,104,110, 38, -229,235,235, 59, 31,192,151,222,112,166,164,164,232, 91, 91, 91,229,133,133,133,167, 23, 45, 90,180, 75, 46,151, 55,201,229,242, -166, 69,139, 22,237,254,232,163,143,254, 32,149, 74,211, 1,120,253,114, 88,154,166, 57,247,126,195, 61, 6, 75, 34,145, 64, 36, - 18,121,148,166, 34, 32, 32,224,227,226,226,226,128,142,142, 14, 88, 44, 22,168,213,106,168,213,106,180,181,181,185, 6,225, 81, -222,195,134,193,193, 65,233,253,238, 59, 8, 33,127, 32,132, 36, 19, 66,162, 9, 33,211,113,145,204,239,220,196,213, 83,132, 16, - 13,128,167, 28,219,137, 0,254,247,126, 58, 88, 78,129, 37, 16, 8,240,234,171,175,226,212,169, 83,136,137,137,113, 5,182,187, - 7,185,123, 35, 8,134,135,135,145,148,148, 4, 11,203,222, 37,208, 5, 2, 1, 66, 66, 67,161,211,233, 60,114,176, 40,138,250, - 73,118,118, 54,125,245,234, 85,168, 84, 42,212,214,214,186,138, 90,173, 70, 93, 93, 29,234,235,235,113,237,218, 53,164,166,166, -194, 96, 48,224,217,103,159,117,166,105, 24,247,210,241,212,109,114,174, 4,244,192,109,250, 46, 56, 31, 62, 7, 43, 34,196,103, -237, 15,231, 81,248,226,236, 21,124, 88,221,254, 49, 33,164,242,164,166,247,179,156,212, 97, 88, 43, 86, 33,233,165,255, 30,153, - 22, 4,192,221,174,135,181,226,117, 80, 62, 51,113,169, 83,140, 94,179,109,204,167,102,171,213,122, 49, 40, 40,232,200,225,195, -135,215,189,241,198, 27, 98, 0,240,241,241,193,219,111,191, 13, 66, 8,196, 98, 49, 24,134, 65,110,110,110,255,237,219,183,247, - 16, 66,116, 30,222, 40,178,240, 32,113,193,107, 63,255,119, 41,212, 7, 1, 90,132, 59,126, 41, 72,126,118, 29,110, 55,158, 7, -186,174, 3,140, 8, 7,118,188, 57,243,199,111,125,112, 16,192,194,233,114, 2,234,235,235,241,214, 91,111,221,179,184,250,182, -147, 85, 94, 94,254, 91,150,101,223,156, 66,206,165, 91,182,108, 57,169, 80, 40, 38, 61, 45, 98, 48, 24, 86, 71, 70, 70,174,155, -232,198,211,235,245, 19, 78,117, 16, 66,154, 41,138,122,190,165,165,229, 63, 26, 26, 26,142,143,245,127, 13, 13, 13,199, 23, 47, - 94,204, 92,188,120,113,171, 39,171, 8,107,107,107,107, 51, 50, 50,138,247,238,221,155,155,159,159, 47,147, 72, 36,240,247,247, - 71, 99, 99,163, 43, 15, 14,203,178,216,182,109,219,144,205,102,251,248,242,229,203,231, 61, 28, 8,135, 41,138,122, 37, 39, 39, -103,189, 82,169,252, 49,199,113, 51, 88,150,237, 50, 24, 12, 39,250,250,250, 38,149, 7,139, 16,194, 81, 20,181, 42, 55, 55,119, - 77,108,108,236, 10,171,213, 58,195,110,183,119,181,182,182,126,218,219,219,123,104, 50,156,231,206,157, 51,238,223,191,255, 47, - 70,163, 81, 21, 17, 17,241,141,159,159, 31,203,178, 44, 35,147,201,252,125,125,125, 83, 0,156, 7,112,205, 27,206,175,191,254, -250,214,129, 3, 7, 90, 44, 22, 75,220,129, 3, 7,206,250,251,251,159,162, 40,138, 18,137, 68, 65, 50,153,236,105, 0,167, 1, -104,189, 61, 86,134, 97,198,117,176,224, 97,124, 71, 95, 95,223,197, 29, 59,118,164, 62,241,196, 19, 40, 46, 46,238,246,243,243, -147,175, 88,177, 66, 96, 50,153,168,241, 28,172,233, 32,176, 30, 0,116, 57, 92,222,127,114,198, 92,185, 5,190,255, 14,128,233, - 62, 11,212,187,132,212,220,185,115, 93,219,238,197, 45, 6,203, 35,216,237,118,136, 68, 34, 8, 4, 2,204, 14, 11,115,137, 57, - 66, 8,116, 58, 29,186,187,187, 61, 18, 88, 52, 77, 51, 20, 69, 97,229,202,149, 30,237,247,149, 87, 94,193,233,211,167, 49,209, -116,162,251,138,191,168,168,168, 9,197,144,227, 88, 60, 94, 69, 24, 17, 17, 49, 37,156, 15,165,192,106, 53,154, 11, 55, 30,188, -188, 77,127,219, 82,249,247,218,158,141, 59, 0, 2, 4, 85,171,130,169, 37, 11,233, 54, 88, 14,102,129,242, 31, 25,108, 72,127, - 7, 40, 95, 5, 58, 16,129, 95, 87,235,111,217,136,117, 92,247,193,100, 50,229,239,219,183,143,169,174,174,126,185,168,168, 40, - 64,165, 82,225,245,215, 95, 7,203,178,168,171,171, 67, 78, 78, 78,183,209,104, 44, 49,153, 76,187, 60,173,196, 76, 63,193,187, -123,255,101,201, 12,218,214, 15,220,170, 5, 36, 1,152, 25,228,135, 63, 95, 58, 3,220,250, 26, 96, 68, 0, 35, 70,218, 15, 84, - 72,142,143, 86, 81, 20,149, 69, 8,249,106, 58,156,128, 23, 95,124,113,202,196,149,187, 32, 2,240,216, 84, 30,167, 83,100,173, - 89,179,230, 36,199,113, 62,147,177,119, 29, 57,153,236, 83,216, 57, 54, 99,130, 41, 95, 71,250,134, 10,111,120,109, 54,219, 54, -141, 70,131,220,220,220,220,213,171, 87,203,148, 74, 37,162,162,162,208,212,212,132,198,198, 70,148,148,148, 12, 13, 15, 15, 31, - 50,153, 76,155, 38, 81,255, 18, 71,153,170, 54,224, 0, 28,118,148, 41, 65, 94, 94,222,159,245,122,125, 87, 72, 72,200, 2,145, - 72,244, 3,140,196,249,220,114,236, 67, 59, 25,206,156,156, 28,181, 94,175,191, 19, 30, 30,158,225,224, 12, 4,112, 19,192,127, - 77,146,179, 75,173, 86, 71,167,167,167,115, 2,129,128, 56, 28, 6, 34, 20, 10,137, 80, 40, 36, 0, 80, 93, 93, 45, 1, 48, 97, -204,101, 71, 71,199,191, 30, 59,118, 12, 53, 53, 53, 11,250,251,251, 95, 3,240,219,193,193,193,244,111,190,249,198, 53, 8,143, -225,118, 74,120,253, 52,225,245,185,108,140,239, 59, 1,100, 77,131,227,195,123,239,189,135,146,146, 18, 76,148,129,188,170,170, - 10,152, 96,138,208,121,173, 56,197,147,213,106, 69,125,125,189,243,221,123,174,105, 65,103,138,134,225,225,225,113, 51,189,115, - 28,103,103, 89, 22, 71,143, 30,245, 72,100,149,151,151,195,108, 54,131,227, 56,143,250, 89, 71, 98, 82,116,119,119, 35, 44, 44, -204,233, 56,187,155, 34, 94,183, 41,195, 48,136,139,139,195,157, 59,119, 48,115,230, 76, 0, 35,211,130, 46,119,111, 96,224,145, -185,254,199, 77, 52,234,142,167,162, 2, 3,104, 17,117,236, 71, 49,162,167,158, 79,146, 99, 78,136, 31, 4, 98, 9,110,247,218, -241,149,190, 31,255,115,222,120,131,181,219,159, 63,213,216,163,241,208,117,202,152, 61,123,246,118,187,221,158, 72,211,180, 15, - 33,164,159, 97,152, 43,237,237,237, 59, 9, 33,245,222, 84, 34, 80,198,104,131,124,153, 0,161, 80, 76,236, 28, 7,128, 6, 40, -103, 97, 70, 62,233,145,237, 33,179, 85,100, 39, 84,101,167,241,206,250,251,221,248, 74,165,178,122, 96, 96,224,129,203,228,238, -235,235,251, 11,173, 86,251,208,102,114,119, 98,254,252,249,105, 50,153,108, 59,199,113,243,205,102,243, 44,153, 76,214, 73, 81, -212,159,250,250,250,254,243,202,149, 43, 23,248,225,243,254, 97, 42, 51,185,143,114,141,191, 0, 96,231,140, 25, 51,148,117,117, -117, 18,119, 7,203,189,191,244, 38, 47, 18,143,233,135,248,248,248,139,101,101,101,105,115,231,206,165,221, 3,217,105,154,118, - 37,199,164,105,218,181,178,244,194,133, 11,195,121,121,121,231,213,106,245, 63,140,197, 25, 19, 19, 83, 93, 83, 83,179,216,100, - 50,253,141,144,114,207,236,238,220, 30, 26, 26,194,187,239,190,251,133, 86,171, 29,245, 85, 57, 42,149,106, 79, 65, 65,193,134, -231,158,123,142,166,105,250,111, 98,174,156,175,245,113, 22,171,213,138,202,202, 74,174,180,180,244,195,235,215,175,143, 25,131, -149,146,146,114,163,182,182, 54,194,153, 50, 97,172,226,142,140,140,140,142, 11, 23, 46,132,125,159,156,143,140,192,114,116, 40, -212, 51, 49,129, 47, 19, 66,253,132, 2,149, 68, 83, 68, 60, 76,208, 72, 1,213, 62,131,146,253, 85,237,237, 67,252,109,203,227, -161,188, 81, 40,138,230, 95,242,251,104, 33, 38, 38, 70,171,213,106,163,199,185, 38,120,129,245,128,139,244,144,144,144, 83, 52, - 77, 71, 58, 69,244, 88,159, 14, 55,169,165,179,179,243, 71,157,157,157, 99,230, 83,140,136,136,120, 92, 42,149,254,134,227,184, -116, 79, 94,246, 76,211,244, 37,179,217,252,243,239,251,101,207,137,137,137,186, 75,151, 46, 61, 46,147,201,238,138, 43,116,214, -249,219,199,222,220,220,140,229,203,151, 27,212,106,117,212,247,201,249, 72, 9, 44, 30, 60,120,240,120, 84, 16, 30, 30,126,209, -106,181,170,204,102,179,208, 98,177, 8,135,135,135,239, 26,224,100, 50,153,113,112,112, 48,148,111, 41, 30, 15, 26,194,194,194, -148,129,129,129,255, 39, 20, 10, 37,163, 61, 56,124, 27,118,187,221,220,213,213,181,180,189,189,189,241,251,228,124,224, 49,218, - 10,153,169, 42, 0, 22,241,156, 60, 39,207,201,115,242,156, 60, 39,207,201,115, 62,106,133,230,181, 60, 15, 30, 60,120,240,224, -193,131,199,212,130, 23, 88, 60,120,240,224,193,131, 7, 15, 30,188,192,226,193,131, 7, 15, 30, 60,120,240,224, 5, 22, 15, 30, - 60,120,240,224,193,131,199, 35,133,255, 31, 0, 6,160,247, 56,137, 5,159,139, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, + 0, 0, 2, 88, 0, 0, 2,128, 8, 6, 0, 0, 0, 64, 11, 6,158, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13, +215, 1, 66, 40,155,120, 0, 0, 10, 79,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102, +105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139, +128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44, + 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157, +179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16, + 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135, +255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38, + 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1, +160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73, + 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132, +153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46, + 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224, +131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225, +116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160, +233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, + 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98, +220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, + 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16, + 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73, +146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5, +220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47, +212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8, + 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, + 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178, + 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231, +208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172, + 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76, + 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, + 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18, +210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195, +228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50, + 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75, +165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244, +119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49, +235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, + 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, + 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, + 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, + 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, + 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89, +251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107, +165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250, +167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, + 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33, + 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231, +155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, + 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169, +183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7, + 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16, +207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46, +155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220, +159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181, +231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, + 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137, +129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229, +193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39, +133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57, +175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42, +174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46, + 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, + 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, + 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230, +102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40, +215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194, + 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184, +138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133, +125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120, +229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14, +110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201, +206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188, +247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109, +113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239, +119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31, +118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15, +156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123, +231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, + 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233, + 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253, +206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119, +160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63, +114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242, +151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29, +239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45, +219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234, + 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 2,190, 27, 73, 68, 65, 84,120,218,236,157,119,120, 20,197, 31,198,223, +217,221,235,119,233, 33, 61,144,132, 26, 8, 61,116, 66,111, 34, 77, 69,186, 10, 22, 64,129,159, 32,205,134, 32,130, 93, 1,149, +174, 34, 32, 34, 72, 85,148, 42,189, 73,239, 61,129, 52,210,235,245,178,243,251, 35,185,243, 18,146,220, 37, 32, 22,230,243, 60, +251, 92,178,187,247,222,236,236,236,236,187,223, 41, 75, 40,165, 96, 48, 24, 12, 6,131,193, 96, 60, 56, 56,150, 5, 12, 6,131, +193, 96, 48, 24,255, 34,131, 69, 8,233,198, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 12, 22,131,193, 96, 48, 24, 12, + 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 48,131, +197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12,198,127, 3,194, 38, 26,101, 48, 24, 12, 6,131,193,120,176, 8, +229,109,104,214,172,217,207, 10,133,162, 86,121,219,117, 58, 93,234,153, 51,103, 58,179, 44,100, 48, 24, 46,159,228, 8,225,240, +103,196, 92, 4, 64, 41,123,186, 99, 48, 24,143,162,193,146, 74,165, 81,251,247,239,175, 35,138, 34,108, 54, 27,172, 86,171,227, +211,100, 50,225,169,167,158, 18, 42,251, 99, 77,154, 52,217,207,113, 92, 68,101,190, 99,179,217,238,156, 61,123,182,125,121,219, + 3, 3, 3, 15, 3,136, 34,132,216, 43,242, 50, 63, 1,128,227, 28, 45,162, 41,137,137,137,205, 42,210, 36,132, 68, 57,221, 28, +238,209,178,255,237,174,102,189,122,245, 78, 8,130, 16, 86,250,251,101,253,111,255, 91, 20,197, 91,231,207,159,111,203,138,233, +195,161, 73,147, 38,251,121,158,175,116,249, 60,115,230, 76,185,229,179, 97,195,134,167, 57,142, 11, 41,235, 28,151,117,206, 1, +240, 54,155,237,234,217,179,103,219,151,103, 64,130,131,131, 15, 3,136,170,168,236,148, 42,155, 0,144,148,152,152, 24,235,234, + 58,170,232, 26, 42,163,204, 87,168,233,108,174, 66, 67, 67, 63,168, 86,173,218, 88,157, 78,103, 0, 64,121,158,167,245,235,215, + 47,145, 15, 54,155, 45,227,242,229,203, 13, 89, 73,100, 48, 24,255,105,131, 37,138, 34,103, 52, 26,113,237,218, 53,148, 85,207, +115, 28,103,171,236,143, 81, 74,235,236, 94,179, 42, 64, 89, 45, 16, 54,139, 25,114,191,106, 14,237,220,203, 23, 32,154,205,176, +153, 77,240,143,109,109,175,112,209,185,115,103,222,133,108,216,164, 73,147, 2, 60, 60, 60, 96, 48, 24, 96, 48, 24, 96, 52, 26, + 97, 48, 24, 96, 50,153, 96, 50,153, 96, 54,155, 97, 54,155, 97,181, 90, 97, 52, 26,113,238,220, 57,155,139, 27, 66,216,132, 9, + 19, 2, 60, 61, 61, 29,122,246,197,174,105,215,181, 88, 44, 48, 24, 12,184,112,225, 66,133,154,130, 32,132,157, 58,117, 42, 64, + 42,149,130, 82, 10, 81, 20, 65, 41, 45,177,148,166,109,219,182,102, 86, 68, 31, 42,117, 54,125, 52, 55, 64,238,235, 7,209, 98, +129, 95,147,230,246,114,139,148, 61,219, 97, 51,155, 33, 90, 44,168,209,247, 73,199,250,142, 29, 59,186, 42,159, 53,126,154,241, +186,183,212,195, 3, 86,131, 1,145,125,158,112,108,184,184,120, 30, 68,139, 25,212, 98, 70,163, 73,111, 1, 0, 50, 51, 51,245, +209,209,209, 41, 0, 8,128,242, 34, 60, 97,183,110,221, 10,176,167,161, 44,211,239,188, 28, 58,116, 8,195,135, 15,119,117,236, + 97,111,190,249,102,128,253, 26, 41, 93,206,173, 86,171,227,211,106,181,194, 96, 48,224,244,233,211,110, 69,174,130,131,131, 63, +140,139,139, 27,181,122,245,106,245,166, 77,155,212, 17, 17, 17,144, 74,165,224,121, 30, 60,207,131,227, 56, 8,130,128,126,253, +250, 17, 86, 4, 25, 12,198,127,222, 96,153,205,230,248, 30, 61,122, 80, 0, 48,153, 76,161, 50,153, 76, 90,202,128,133,180,107, +215,238,106,233,239,185,106, 58, 84, 86, 11,196, 55,145,190, 0,128,167,111,102, 57,110, 12,235,227,154, 56,246, 25,122, 59,175, +104, 95,165, 18, 28,199, 17, 23, 21, 56,212,106, 53,186,119,239, 14,153, 76,134,216,216, 88, 72, 36,146, 50, 23,169, 84, 10,137, + 68,114, 79,244,168, 44, 52, 26, 13,102,205,154,101, 55, 71, 80, 43,228, 24,223, 54, 22, 10, 80, 44,189,112, 29, 38,145, 66, 16, + 4,199,226,142,166, 84, 42,197,249,243,231, 33, 8, 2,120,158,119,124,218,255,222,178,101, 11, 6, 14, 28, 8, 65, 16,160, 84, + 42, 81,124,147,101, 60, 68, 20,126,254, 88,223,161, 41, 0, 96,120, 98,129,163,140,253, 58,184,143, 99,159,103,146,181, 32,132, + 64, 42,149,186,119,222, 61, 60,176,109,224, 99, 0,128, 39,175,165, 67, 34,145, 64, 16, 4,156,251,236, 61, 72,100, 50, 8, 82, + 41, 26, 77,122, 11,153,153,153,250, 39,158,120,226,160, 66,161,216,238,198,195, 10, 18, 19, 19, 33, 8, 66,185,229,157,227, 56, +172, 88,177, 2,183,111,223,118,235,216,245,122, 61,222,127,255,125, 16, 66, 74, 92, 47,229,253,237,234,216, 9, 33, 92, 80, 80, +208,123,113,113,113, 35, 86,175, 94,237, 67, 8,193,151, 95,126, 9,169, 84,138,222,189,123,195,207,207, 15, 59,118,236,128, 84, + 42,197,212,169, 83, 89,225, 99, 48, 24,143,134,193, 58,115,230,204, 99,246,191, 91,183,110,125,249,224,193,131,245,156, 66,249, +176, 90,173, 82,171,213, 90,199,222,108,104,127,242, 29, 58,116,104,133, 79,244, 54,139,249, 30,131, 84, 86, 69,237,206,141,203, +201, 12, 98,208,160, 65, 0, 80,238,205,198,121,113,227,169, 27, 38,147, 9,130, 32,160,110,120, 53,188,221,179, 41, 90, 82, 11, +180,133, 4,214, 60, 45,250,107, 44,184, 92,191, 25,150,220,201,192,237,252, 66, 8,130,123,173,165,162, 40,150,107,174,120,158, +199,162, 69,139, 48,100,200, 16,240, 60, 95,110,190, 48,254, 90,108,102,179,203,114, 88,217,115, 99, 53, 24,138, 34, 75, 2,239, + 48, 87, 18,137, 4, 18,185, 28,130, 84, 10, 65, 38, 69,102,102,166,190, 91,183,110, 71,101, 50,217,119,129,129,129, 41, 73, 73, + 73, 21,150, 79, 74,105, 73,173, 50, 30, 38,190,253,246, 91,172, 92,185, 18,173, 90,181,114,199, 12,193,100, 50, 65, 42,149,226, +189,247,222,187,103,251,226,197,139,239, 49, 88, 46,244, 8, 0, 46, 48, 48,240,229, 53,107,214,120,218,127,223,223,223, 31, 18, +137, 4, 13, 27, 54,132,135,135, 7, 14, 30, 60, 8,155,205,230,246,131, 15,131,193, 96,252,235, 13, 86, 41, 99,192, 25,141, 70, + 92,185,114, 5,174,250,165, 82, 74, 43,172, 37,229,126,213, 28,145,171,117, 53,253, 28,235,135, 36,228, 58,110, 92,219, 90,214, +130, 76,163, 70,236, 59, 31,187,109,134,210,211,211, 29, 79,222,174, 22,119, 42,114,147,201, 4,149, 82,129, 93, 19, 27, 34, 49, + 75,134,153, 71,178,241,203,153, 27,144, 72, 36,232, 85,191, 33, 30,147,122,224,173, 26, 50, 76,188,158, 0, 11,165,110,221,192, + 40,165,101, 26, 43,251,223,246,166, 18,187,193, 98, 60,124,252,154, 52,119, 68,174, 86,135,123,220, 19,181, 2,128, 45,205, 34, + 32,247,208,160,225,255,166,187, 85, 62, 35,251, 60,225,136, 92,253,210, 60, 18,188, 68, 2,137, 76,134,167,207, 39, 3, 40,106, + 22,236,220, 48,122, 95, 46, 47, 91, 49, 98,196,136,248,223,127,255, 93,233, 78, 90,203, 50, 88,118,243,243,237,183,223, 98,213, +170, 85, 16, 4, 1,102,179,217,173,116, 26,141,198,114,141, 83, 85, 34, 88, 0,160,211,233, 76,155, 55,111,198, 23, 95,124, 1, + 63, 63, 63,244,232,209, 3,193,193,193, 88,183,110, 29, 40,165, 24, 55,110, 28,148, 74, 37,148, 74, 37, 43,243, 12, 6,227,209, + 51, 88,102,179, 57,190, 91,183,110,110,141,248,209,235,245,119, 93, 24,176, 50, 35, 3,206, 81, 1,185,135, 6,114,141, 6,156, +155,179,116, 89, 44, 22,135, 65,217,185,115, 39,148, 74, 37,122,247,238,125, 95, 17, 44,179,217, 12,153, 84, 2,206, 63, 16,207, +126,254, 59,178, 10,244,142, 27,218,222, 91,241, 56,149,150,142,137,109,186, 66,173, 76, 71,161,201,228,118, 4,171,180,185, 18, + 4, 1,131, 6, 13,130,209,104, 4, 33,164, 68,191, 20, 87,102,149,241,215, 81,222, 32, 4, 66, 8, 20,158, 30,144,169,213,224, +121,222, 45, 45,231,104,147, 32,147, 65, 34,151, 65, 40, 46,135,246,200, 85, 46, 47, 91,145,156,156,124, 20,128,162,101,203,150, + 74,119,210,230,108,176,156, 13,144,179,185,226,121, 30, 22,139,197, 45,243, 98, 52, 26, 33,149,254,217, 19,224,206,157, 59, 21, + 26, 44, 23,199, 76, 9, 33, 34, 33, 68,140,138,138,114,124, 55, 40, 40, 8,222,222,222, 16, 69, 17,162, 40, 66,161, 80, 64,169, + 84,150,248, 93, 6,131,193,120,100, 12,150,115,115,225,131,186,121, 85,116, 3, 83,122,122, 66,170, 86,219, 71, 43, 81,119,204, +144,189,207,201,216,177, 99, 43,236,151, 98, 55, 98,110,152, 74,112, 2,143,212,160, 72,216,184, 3,127,222, 32,139, 23, 78,144, +224,118, 80, 61,240, 87, 78, 67, 34,138,110,221,192, 74, 71,176,198,141, 27,135,101,203,150,129,227, 56, 71,158, 8,130,128,218, +181,107, 35, 62, 62,158,149,206,191, 1, 90, 65, 52,210,190, 94,225,225, 1,153, 70, 3,222,141,190,119,165,205,144, 84, 46,135, + 32,147, 66,144, 22, 53, 11,246,237,219,119, 95,110,110,238,138, 6, 13, 26, 92, 71,209, 52, 6,156,187,215,144, 32, 8, 37,140, + 79, 89,230, 74, 16, 4, 88,173, 86,183, 31, 42, 74, 27,157, 57,115,230,220,179,239, 83, 79, 61,229,110, 4,139, 18, 66,168, 84, + 42, 69,247,238,221,209,168, 81, 35,108,218,180, 9,162, 40,226,149, 87, 94,129, 82,169,196,188,121,243, 96,181, 90,241,225,135, + 31,178, 8, 22,131,193,120,244, 12,214,131, 36,247,210,121, 71, 39, 98,231,102,193,223,218,214,131, 92,163,134, 92,163, 65,187, + 77, 7, 28, 79,205,120,239, 83,183, 34, 88,118,131,149,149,149, 85,161,185,114, 39,130,229, 48, 88, 50, 1,235,195,114, 64,101, + 18, 8, 38, 75, 9,131,197, 11, 18, 36,250, 69,130,147, 72, 33,216,172,110,105, 82, 74,239,105, 18,124,238,185,231, 64, 8,113, +140,248,106,220,184,177,243,141,134,221,113, 30, 50, 41,123,182, 59, 58,180, 59, 55, 11,254,220,178, 22, 20, 30, 26,200,212,106, +116,216,122,216, 17,109,196,188,165, 46, 53,175,126,253, 21,206,207,155, 11,137, 76,134, 39, 79,223,118, 68,174,218,214,173,117, +212,164,246, 92,113,231,206,157,163, 0,184,193,131, 7,123, 55,110,220,216,173,107,210,222,201,190, 60,115,229,108,176, 44, 22, +139,219,101,222,157,235,195, 30,197,114,163,188,211,232,232,104,112, 28, 7, 79, 79, 79,104, 52, 26,199, 8, 90,133, 66, 1,149, + 74,229,232,191,233,238,117,201, 96, 48, 24,255,106,131,213,164, 73,147, 95, 85, 42, 85,164,187, 34,149,153,116,212,185, 19,177, +221, 92, 17, 66,160,208,104, 32,211,168, 33,247,208,148, 27,229, 42,239, 70, 99,111, 34,228,121,222,113,179,249,238,187,239,160, +209,104, 48,114,228,200, 74,247,193,178, 63,205,115, 82, 14, 59,228,123,192,203,132, 18,230, 74, 16, 4,240, 18, 9,238,106,130, +193, 73, 36, 16,172,174,163, 98,132, 16,228,229,229, 65, 16, 4,188,253,246,219,142, 39,118,103,115,197, 58,182,255,253,136, 78, +102,164, 68, 84,213,195,195, 81, 62,157,215,187,234,147, 72, 8, 1,181, 90, 32,145,203, 33, 41, 30,136,107,143, 92,153,212,158, + 43,234,213,171,231,136, 92,169, 84, 42,251,232, 81,151,154, 28,199,149, 40,211, 43, 86,172, 40, 97,174, 74, 71,176,220, 45,243, + 82,169, 20,203,150, 45,171,208, 68, 73,165, 82,183, 71, 80, 2, 69,211, 70,236,219,183, 15,167, 78,157,194,216,177, 99,161, 84, + 42,177, 96,193, 2, 88,173, 86,204,158, 61, 27, 74,165, 18, 50,153,140, 21, 62, 6,131,241,223, 55, 88, 50,153, 44,242,208,161, + 67,142, 73, 70, 43,250, 52,153, 76, 24, 52,104,144,219,145, 48,177,120, 20, 33, 87,106,164,156,220, 83, 3,121,113,211,139,243, +122,226, 70, 45,110,127, 2,118, 54, 88,239,188,243, 14, 4, 65,192,178,101,203, 0, 0,147, 39, 79,118,187, 15,150, 93, 19, 54, +130, 36,122, 19, 77, 63, 31, 8,211,106, 11,210, 14,157,133, 32, 8, 8,104,253, 24,196,150, 3,161, 83,106, 32,216,172,110,143, + 34,204,206,206, 70,124,124, 60,120,158,199,164, 73,147, 74,204, 85, 84,234,152,177,115,231, 78,214, 7,235,111, 52, 88, 92,113, +255,170,178,202,103, 41,243,229,186,157,204,102, 45,234,119, 37,253,115,180, 96,110,110,238,138, 59,119,238, 28, 3,192,141, 24, + 49,194, 91,165, 82,225,235,175,191,214, 1,144,173, 91,183,206,165,203,178,151,155,242,204, 85, 85,154, 8,237,145, 96,231,126, + 93,247,107,176,236,102,144, 16, 2,155,205, 6,165, 82, 89, 34,114,165, 80, 40, 32,151,203, 89,193, 99, 48, 24,143,134,193,226, + 56, 14, 70,163, 17,151, 46, 93,114,247, 9,213,237, 73, 71,253,154,183,194,208,219,121, 32,132, 96, 71, 92, 3, 71,179, 75,219, +159,246, 57, 42,236,219,239, 79,134, 68,173,129, 95, 92,143, 74,221, 24,156, 13, 86,110,110, 46, 36, 18, 9,222,123,239, 61,112, + 28,135, 15, 63,252, 16,161,161,161, 72, 77, 77, 69,199,142, 29,221,122,154,231,109, 60,130,159,137,134,234, 57, 47,120, 62,211, + 1, 62,221,223, 65,178, 73,192, 97,131, 10, 29, 12, 23, 33,219, 49, 31, 38,209,230,150,193, 34,132,192,106,181, 98,223,190,125, + 37, 58,178, 3, 69, 77,135,246,233, 46, 44, 22, 11,204,102, 51, 62,252,240, 67, 86, 58,255, 6,194, 31, 31,128,103, 83,116, 0, +128, 95,157,154,173,219,111, 60,224, 40,159,241,115, 38, 65,162,214,192,167, 69,156, 91,154,245, 95,153,130,250,175, 76, 65,102, +102,166,190,107,147, 6,251, 11,165,170,111, 27, 54,108, 88, 34,114,165, 80, 40, 72,241,255,196,157,178,196,113, 28,120,158,119, +152, 43,187,153, 42,203, 96,185,251, 0, 96,177, 88, 32,149, 74,221, 54, 88,238,194,113, 28,158,127,254,121, 4, 7, 7, 59, 34, + 87,239,190,251, 46,148, 74, 37, 94,127,253,117, 88, 44, 22,204,159, 63,159, 21, 62, 6,131,241,223, 55, 88, 70,163, 49,161,107, +215,174, 40,103, 91,168, 92, 46, 47, 17, 6,178, 79, 58, 90,186,169,144, 16,210,141, 82,186,171,172, 27,132,243,104, 44,121,169, +168,149,212,195, 19, 18,181, 6, 92, 25,209,166,210,154,246, 39,227,210, 6,203,190,228,229,229, 65, 34,145,224,139, 47,190,128, +167,167,167, 99,180, 94, 69,154,246, 8, 22,207,243,208, 37, 22,224,242,220, 93,144, 41, 14,163, 86,143, 33, 8,150, 40, 33, 61, +184, 1,122,155,165,194,137, 70,203,210,172, 83,167, 14,102,204,152,113,207,244, 12,229,209,172, 89, 51,151,154,247, 11,211, 44, + 91,211,157,242,201,203,229, 46,207,187,125,187, 61,114, 85, 40, 85,125, 27, 31, 31,111,143, 92,121,169, 84, 42, 44, 94,188, 88, + 7,128,155, 61,123,182,170, 70,141, 26,188, 59,233,228,121, 30,223,125,247,221, 61, 29,218,203, 50, 87,101, 77,251, 81, 86, 58, +173, 86,235, 61, 6,107,208,160, 65,247,140, 30, 44, 47,130, 85, 86, 58,237,125,213,252,252,252, 28,145, 43,155,205,230, 24, 61, +104,177, 88, 96,181, 90,203,109,106,101,229,147,105, 50,205, 71, 71,243,145, 48, 88,167, 79,159,238, 85,222, 23,218,181,107,119, +237,208,161, 67,181,109, 54,155,243, 59, 10,165, 6,131,161, 78,255,254,253, 93, 62, 42,139,162, 8,185, 92, 14, 74, 41,154,190, +245, 1, 8,185,183,191,149,119,219,174, 32,130, 0,155,205, 6,139,197,226,114,122, 8,189, 94,239,184,153,148,215,193,189,176, +176,176,194,121,126, 74,223, 20, 12, 6, 67,137, 27, 21,161, 34,110,239,254,241,158,209,132,149,137, 16, 0,128, 66,161, 40,209, +239,202, 85, 82, 88, 17,125,184,216,167, 84,160,148,162,193,248,105, 69,231,169,184,185,208,110, 2,188, 98,227, 64, 36, 2, 68, + 0,102,179,217, 85,249, 36,246, 62, 87,148,210,111,250,247,239,127, 21,128, 17, 0,213,104, 52,114,137, 68, 34, 2,200, 6, 64, +115,114,114,188,146,147,147, 69,131,193, 80,221, 85, 58,247,237,219,135, 27, 55,110,160,121,243,230,142, 87, 54,217,155,221,236, + 38,198,217, 96,185, 27,193, 42,107, 78,173,242,102,115,119, 23,158,231,225,229,229,229,152,196, 84, 42,149, 66,165, 82, 1, 0, +230,207,159,239,200,115, 6,131,193,248,207, 27, 44, 23, 6,137, 47,175,249,208, 85, 83,161,205,102, 75,106,217,178,101,101,127, + 47,205,197, 13, 49,105,255,254,253,210,138, 94,242, 92,198, 58,151,154,199,142, 29,147, 86,240,253,178,254, 78,115,117,236,173, + 90,181, 42,243,251,229, 97,181, 90,147, 89, 17,125,120, 88,173,214,242,203,231, 59, 31,148,119, 94,211, 92,152,150,235,181,107, +215, 78,209,104, 52,191, 4, 6, 6,102, 29, 58,116,200,175, 69,139, 22,126,206,251,180,104,209, 34,184,212,215, 76,168, 96,122, + 18, 66, 72,210,179,207, 62, 43,117, 81,198, 75,255,159,228,226,161, 34,233,194,133, 11,210,178,180,202,251,164,148, 38,185,145, +173,183,123,245,234,197, 57,127,183,188,178,111,181, 90, 51, 88, 41,100, 48, 24,143,172,193, 50, 24, 12,137, 93,187,118, 45,179, +215,172, 78,167,187, 83,209,119, 47, 92,184, 16,251,160, 15, 32, 41, 41,169,237,191, 65,243,175, 56,118,198, 63,255, 28, 93,184, +112,161,229,131,214,188,115,231, 78,219,127,131, 38, 0, 92,188,120,177, 13, 43, 89, 12, 6,131, 25, 44, 55,112,119, 58, 6, 6, +131,193, 96, 48, 24,140, 71, 21,142,101, 1,131,193, 96, 48, 24, 12,198,131,133, 0,232, 86,214,134,202,140, 14, 32,132,116,171, +236, 15,187,210,103,154, 76,147,105, 50, 77,166,201, 52,153,230,127, 79,211,149,246,127,102,116, 34,165,244, 47, 91, 0,116, 99, +154, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,212, 22,214, 68,200, 96, 48, 24, 12, 6,131,241,128, 17, 88, 22,252, 61, 16, + 66,120, 74,169,237, 1, 74,250, 0, 40,239,133,110, 38, 0, 57, 85, 73, 38, 0,105,241, 98,159,168,200, 2,192, 92,188, 80,215, + 18,179,184,148, 20,159, 24,106,147,180,160,132, 72, 68, 17,103,170, 87, 15, 63, 13,244, 50, 1,128, 38,168,126,125,141, 90,217, +205,104, 54, 69,202, 37,178, 75,185,218,194,157,134,180,171, 9,172,132, 48, 24, 15,159,216,216,216, 81,148,210, 57, 69, 85, 20, +121,239,196,137, 19, 95,178, 92, 97, 48, 30,176,193,170, 85,171,214, 9,142,227,194,236,147, 97, 86, 52,231,142,253,211,102,179, + 37, 93,190,124,217,173,161,238,132, 16, 33, 56, 56,248,105,181, 90,221,153,231,249,118,197,223, 63,164,213,106,127, 79, 77, 77, + 93, 71, 41,181, 86,229,128,162,162,162, 60, 13, 6,195, 32, 66,200, 48, 0,160,148,126,175, 80, 40,126,188,117,235, 86,126, 21, +141, 80,173,160,160,160,239, 37, 18, 9,159,152,152,216, 25, 0,194,195,195,127, 55,153, 76,182,244,244,244, 97,148,210, 27,149, +212,227,164, 82,233, 7,113,113,113,237, 9, 33, 43, 41,165,139, 30,208,185,148,115, 28, 87,166, 49, 17, 69, 49,162, 10,122, 82, + 0, 94, 95,124,241,133,223,170, 85,171,154, 38, 37, 37, 53, 4,128,176,176,176,243, 35, 70,140, 56, 61,126,252,248, 44, 0,121, +197, 70,171, 92, 82, 82,124, 98,210,239,222, 26,155,150,126,105, 16, 0, 4, 5, 55,252,145,231, 57,105,104,232,169, 35, 42,255, + 97,254,117,235,213, 28,243,195,215, 95, 72, 35, 34,195,177,231,240,169, 38,227,255,247, 70,140, 34,176,238,167,204,100, 61, 60, +234,212,169,115,130,227,184,176,202,204, 37, 87,252, 6,133,164,139, 23, 47,198,150,167,201,243,124,152,171,185,186, 74,175, 19, + 69,241,214,133, 11, 23,202,156, 50,162,110,221,186, 71,120,158,143,116,183, 62,114, 78,103,121, 83,112,212,173, 91,247, 4,207, +243, 97,174, 52, 75,175, 19, 69,241,214,249,243,231,219,186,171,233, 98, 14,189, 42,165,211, 29,205,138,210, 9, 0,157, 58,117, +146,107,181,218,239, 53, 26, 77, 99,173, 86, 59,138, 82, 58, 99,239,222,189,129, 28,199,161, 91,183,110, 51, 98, 99, 99,227, 21, + 10,197, 66,189, 94,127, 90,163,209, 12,221,187,119,175,145, 93, 49, 12,198,125, 26, 44,142,227,194, 78,157, 58, 21,160, 86,171, + 81,108, 84, 96,159,189, 93, 20, 69,136,162, 8, 74,169,227,211,106,181,162, 83,167, 78,110,253,104, 88, 88, 88,195,186,117,235, +174, 31, 55,110, 92,245,190,125,251,202, 2, 3, 3, 65, 8,193,221,187,119,235,252,242,203, 47,195, 23, 44, 88,240, 78, 88, 88, +216,192,164,164,164,243,238,154,150,224,224,224,174, 0,158,107,216,176,225,147,147, 39, 79,150,182,107,215, 14, 54,155, 13,123, +246,236,137,155, 55,111,222, 23, 33, 33, 33, 27, 0,172, 72, 77, 77,221, 77, 41, 21,221,212,109, 26, 25, 25,249,227,129, 3, 7, + 34, 19, 18, 18,108, 3, 6, 12, 88, 9, 0,135, 15, 31,110, 44,138, 34,105,215,174,221,175,132,144, 65,148,210,211,149,200,243, +254,227,199,143, 31, 56,110,220,184,106, 35, 71,142,124, 6,192,162,226,223, 34,197,249, 76, 43,121, 14, 29,145, 43, 74,105, 69, +211,107, 7, 85, 34,146,165,142,143,143,247,105,219,182,237,203,233,233,233, 19,157,117,211,210,210,112,242,228, 73,243,220,185, +115, 63, 63,124,248,240,194,200,200,200, 28, 0,218,242,132,168, 77,210, 34, 45,253,210,160, 14,109,190,240, 2,128,117, 91, 94, + 30,114,252,116,134,199,207,191, 45, 25, 46, 83, 72,141,171,150,126, 46,173, 93, 43, 2,123, 79, 92,199,177, 75,217,164, 97,251, + 62, 66,222,207, 43,187, 3, 88,194, 46,207,135, 3,207,243,161, 39, 78,156, 8, 80,169, 84,101,190,208,189, 84,191, 11, 16, 66, + 64, 41, 69, 92, 92, 92, 69,154, 97,167, 78,157, 10, 80, 40, 20,142,186,163,116,157, 97,175, 87, 28,101,133, 82,116,232,208,193, + 92, 65,157, 84,227,143, 63,254, 8, 80,169, 84, 14,157,178,210, 87,218,104,116,232,208,161,194,116,158, 60,121,210,145, 78,119, + 52, 41,165,104,215,174,157,205,213,177,219,223, 88,225,234,184,237,154,109,218,180,161,149,209,116, 51,157, 21, 62, 0,105,181, +218,239,215,173, 91,247, 68, 96, 96, 32,250,247,239,191,163, 65,131, 6, 50,149, 74,133,223,126,251, 13,225,225,225,254, 30, 30, + 30,219,222,127,255,125,124,250,233,167,213,119,238,220,185, 6,192, 19,236,138, 97, 48,238,223, 96, 65,173, 86, 99,237,218,181, +142,215,195,216, 95,147, 81,214,223,213,171, 87,119,235, 7,131,130,130, 98, 35, 34, 34,246,109,218,180, 73, 25, 16, 16,224, 88, +111, 50,153,224,233,233,137,231,158,123, 78,214,189,123,247,218,195,134, 13, 59, 26, 20, 20,212,241,238,221,187, 39, 42,210, 11, + 14, 14,126, 50, 38, 38,230,203,137, 19, 39, 6,246,235,215, 15, 62, 62, 62, 37,182,247,233,211, 7,189,123,247,150,222,186,117, +107,200,186,117,235,134,172, 92,185,242,110,112,112,240,248,212,212,212, 13, 21, 58, 12,181,186, 91,147, 38, 77,190,222,179,103, + 79,152,183,183, 55, 66, 66, 66,184,183,223,126,187, 97,205,154, 53,149, 65, 65, 65, 92,106,106, 42, 54,108,216, 80,115,196,136, + 17,155, 21, 10,197, 40,131,193,176,219, 13,195, 38,243,245,245,157, 50,122,244,104,191,252,252,124,235,169, 83,167,174,219,215, +203,229,242, 25,173, 91,183,110, 70, 8, 89, 75, 41, 93, 81,149,200, 21,165, 52, 31,127, 54,229,217,177,216,183,187, 25,201,146, +157, 57,115,198,183, 77,155, 54, 27,140, 70, 99,179,177, 99,199,222,153, 59,119,174,210,211,211,211, 19, 0,201,207,207,207,153, + 53,107,150,105,222,188,121,211,234,215,175,223,245,200,145, 35, 79, 54,105,210,196, 82,108,222,238, 53, 88,132, 56,210,147,152, +156,129,125,135, 69,217,140,215, 39,135,125, 52, 39,242,246, 31, 23, 19, 69, 65,233,137,173,251, 47, 32, 45,171, 16,191, 30,185, +136, 32, 63, 15, 34,149, 75, 98,188,195, 98, 58,230, 37, 95,220, 95, 5,195,201,168, 2, 42,149, 10, 91,183,110,189,231, 21, 83, +101,189,126, 74, 16, 4,120,123,123, 87,248, 54, 2, 66, 8, 20, 10, 5,118,238,220, 89,226,245, 82,101,253,109,255,244,242,242, + 2,165,180,194, 87, 28, 40, 20, 10, 28, 58,116, 8, 28,199,221,243,253,210,105, 22, 4, 1,106,181, 26,132, 16,206,149,230,254, +253,251, 93,106,217, 63, 53, 26, 13, 0, 84,248,254, 33,185, 92,142,131, 7, 15,150,123,204,165,255,214, 20,191,239,210,149,230, +161, 67,135, 74,188,162,171,244,171,187,156,255, 47,126, 56,174, 80, 84,169, 84, 54, 14, 12, 12,196,241,227,199, 49,115,230, 76, + 89, 76, 76, 12,174, 95,191, 14, 66, 8, 70,142, 28,137, 6, 13, 26, 32, 53, 53, 21, 13, 26, 52,192,193,131, 7,155,178, 43,133, +193,120, 0, 6,203,142, 59,230,202,254, 30,177,210, 21, 68,233,161,150, 17, 17, 17,114,141, 70,243,211,214,173, 91,149,126,126, +127,190, 45,196,104, 52,162,160,160, 0,133,133,133, 40, 40, 40,128,135,135, 7, 22, 46, 92,168, 28, 58,116,232, 79, 17, 17, 17, +117, 18, 18, 18,140,229,105, 18, 66, 62, 63,115,230, 76,160,213,106,133, 76, 38, 43,215, 44,214,170, 85, 11,227,199,143, 71, 92, + 92, 92,208,224,193,131, 63, 7,176,161, 60,205, 98,227,246,213,225,195,135,195,164, 82, 41,174, 93,187,134,164,164, 36,140, 25, + 51,166,134, 40,138, 72, 76, 76,196,245,235,215,145,156,156,140,101,203,150,133, 13, 29, 58,116, 33,128,218, 21, 29,123, 49, 47, + 78,154, 52,169,142,175,175, 47,247,241,199, 31,231, 21, 22, 22, 46, 45, 94,255,250,252,249,243,135,118,232,208,161,218, 11, 47, +188, 0, 66,200, 15,148,210,123, 12, 75, 41,205,178, 34, 87, 54, 0,151, 75,125, 45,186, 84,100, 43, 8, 69,239,194,203, 45, 67, +147, 0,240,234,209,163,199, 36,163,209,216,236,224,193,131, 55,218,181,107, 87, 3, 64, 42,128, 12, 0,240,242,242, 82,127,254, +249,231,129,125,250,244,185,218,165, 75,151,102, 61,122,244,152,148,145,145, 49,183,120, 59, 45,173, 41,138, 56, 19, 20,220,240, +199,253, 71,198, 15,218,123,200, 36,157,252,191,119,238, 84, 15,143,200, 59,115, 45,219,118,241, 86, 6, 10,244, 86, 60,209,165, + 17, 0,160,117,195,234,248,114,237, 65,188,242,234,155,146, 13, 63,174,124,234, 6,133, 26,192, 47, 21,228,231,125,193, 52,255, + 52, 67,162, 40, 66, 34,145,224,177,199, 30, 3, 33,228,158,119,109, 74, 36, 18, 28, 57,114, 4, 93,186,116,129, 68, 34,193,243, +207, 63,239, 50,157,162, 40, 66, 16, 4,244,232,209, 3, 86,171,245, 30,189,210,102,193,254,142,206,138, 52, 41,165, 16, 4, 1, + 28,199,149,105,126, 74, 47,101,153,150,178,142,221,149,150,243,182,178, 94,247, 83, 90,211,158, 78,119,204,149, 93,211,221,116, + 10,130,128,182,109,219,226,244,233,211, 21,154, 45,142,227, 92,214,201, 90,173,246,185,254,253,251,239, 24, 59,118,172, 2, 0, +178,178,178, 28, 47,162,231,121, 30, 87,174, 92,129,201,100,194,234,213,171, 97, 52, 26,199,178,235,136,105,254,149,154,143,140, +193,178, 87, 18,238, 26, 44,119,222,173, 71, 41, 29,247,250,235,175, 7, 86,100,174, 10, 11, 11,145,146,146,130, 26, 53,106,224, +233,167,159, 14, 92,185,114,229, 56, 0,159, 84, 32, 43,229,121, 30,199,143, 31, 71,122,122, 58, 26, 53,106,132,200,200,200, 18, + 59,220,188,121, 19,219,182,109, 67,110,110, 46,154, 55,111, 14, 20,245, 47, 42,147, 38, 77,154,204,140,142,142,238,209,169, 83, + 39,185, 68, 34,193,153, 51,103,208,172, 89, 51,172, 93,187, 22,213,171, 87,135, 74,165,194,213,171, 87,209,168, 81, 35,236,219, +183, 15,213,170, 85, 67, 76, 76,140,188,121,243,230, 7,178,179,179,127, 79, 72, 72,152, 89, 78,126, 74, 67, 67, 67,223, 24, 61, +122,180, 44, 37, 37, 69,252,238,187,239, 14, 83, 74, 15, 19, 66,198,188,249,230,155,207,244,236,217,179,218,169, 83,167,242,255, +248,227,143, 63,202, 50, 87,110, 70,174,172,165,111, 70, 54,155,205,168,215,235, 77, 70,163,209,194,113, 92, 2, 33,196,100,179, +217,234,148,247, 48,255,220,115,207,213,204,204,204,124,229,213, 87, 95,141, 47, 54, 87, 87, 80,212,177, 29, 0, 96,181, 90,141, +133,133,133,249,109,218,180,169, 49,116,232,208, 27,107,214,172,121,229,185,231,158, 91,183, 98,197,138, 66, 0,250,210,130,213, +171,135,159,230,121, 78,170, 45,240,189,181,126,221,242,137,219,182,140, 11, 79, 76, 76,174,237,231, 95, 77, 43,213, 84, 75, 89, +247,253,183, 39, 0,152, 82, 50,242,113,238,230, 93, 72, 36, 60, 46, 37,230,161, 67,175,167, 37, 55,174,205,105,111, 55, 88,140, +191, 20,106,127, 57,244,222,189,123, 43,140, 96, 29, 57,114, 4, 18,137, 4, 74,165, 18,107,215,174,173, 80,212,110, 8,236,209, + 33, 87, 38,198,213,203,207,237, 38,195,254, 2,246,210,203, 87, 95,125,133, 87, 95,125,181,196,111, 20,107, 18,119,210, 89, 86, +250,106, 68, 68, 32, 61, 45,173,196, 58, 55, 94,210, 14,155,205, 6,137, 68,130,101,203,150,161, 79,159, 62,248,249,231,159, 43, +252, 44, 54,182,212,157,116,182,109,219, 22,102,179,217,145,230, 43, 87,174,148,169,187,104, 81,197,221, 59, 99, 99, 99, 71, 17, + 66,230,212,173, 91, 87,222,185,115,103,236,223,191, 31,115,230,204, 17,173, 86,107, 38, 0,180,109,219,182,218,196,137, 19,201, +201,147, 39,161,209,104,144,145,145,177, 34, 54, 54,118, 54,235,248,206, 96, 60,128, 8,150,189,210,117,101,174,236, 79,138,174, + 76,150, 70,163,233,221,171, 87, 47,135,185, 49, 24, 12, 14, 99,101, 55, 87,246,255,175, 94,189,138,152,152, 24,169, 70,163,233, +237,194, 96, 21, 29,136, 32, 32, 36, 36, 4,153,153,153, 56,127,254, 60,106,212,168, 1,139,197,130,237,219,183, 35, 47, 47, 15, + 18,137, 4, 82,169, 20,102,115,133, 93, 18, 16, 29, 29,253,216,170, 85,171, 98, 87,174, 92,153, 99,127,130,251,254,251,239, 65, + 41, 69,181,106,213,160,211,233,144,150,150,134,223,127,255, 29, 86,171, 21, 26,141, 6,161,161,161,138,113,227,198,181,159, 53, +107,150, 4,192,204,114,164, 91, 61,245,212, 83,158,158,158,158,248,223,255,254, 71,205,102,243, 39,132,144,214, 79, 62,249,228, + 27,227,199,143,247, 77, 72, 72, 48,189,248,226,139, 39,204,102,243,231,197, 55, 19, 9,165,212,226,194,176,150, 27,185,178, 88, + 44,246, 60,141, 47, 44, 44,132,191,191,127, 13, 23,125,180, 0, 64,122,232,208,161,182, 0,248,217,179,103, 43, 80,244, 2,107, + 71, 26, 76, 38, 19, 10, 11, 11,161,213,106, 45,121,121,121,233, 83,166, 76,177,174, 89,179,134, 47,254,206,165,178, 12, 22,208, +203,212,160,129, 90, 70, 41,255,230,146, 37, 75, 52, 61,123,246,228, 52, 26, 13, 10, 10, 10, 60,127,253,237, 55, 77,215,206,237, +163,230,126,240,209, 14,207,176, 70,105,135,206,220, 66,242,221, 60,152, 44, 22, 68, 5,123, 21,197,191, 24,127, 57,197, 29,172, + 29, 17, 44,103, 51,177,127,255,126,244,234,213,203,113,173, 75,165, 82,199,126,238,104, 10,130,128, 94,189,122,221, 19,209,217, +187,119,111,153,209, 38, 87,117,136,179, 25, 42,109,138,202, 50, 94, 28,199,193, 85, 43,179, 61,122, 87,150,201,114,142,226,151, + 50,109,174, 30, 38, 33, 8, 2,198,143, 31, 15,137, 68,130,169, 83,167, 66, 16, 4, 52,109,218, 20,130, 32,160, 77,155, 54,144, + 72, 36,232,210,165, 75,185,145,182,178,204,165, 32, 8, 56,122,244, 40,154, 53,107,230, 72, 83,211,166, 77,209,162, 69, 11, 8, +130,128,184,184, 56, 72, 36, 18,244,232,209,195,165,166,189, 67,187, 70,163,193,213,171, 87,193,243, 60, 8, 33, 89, 39, 79,158, + 12, 4,128,153, 51,103,102,234,245,122, 63,131,193,128,174, 93,187,162,125,251,246,213,190,255,254,251,183, 1, 48,131,197, 96, +220,111, 4,203, 94,233,186,107,176, 92, 97, 48, 24,154,216,163, 87,101,153, 43,231, 79,147,201,132,154, 53,107,194, 96, 48, 52, +169,236,205, 34, 56, 56, 24,102,179, 25,203,151, 47,135, 84, 42,133, 84,250,167,175, 48,153, 42, 14, 14, 93,188,120, 49,254,232, +209,163,205,154, 55,111,238,179,113,227,198,140,238,221,187, 87,235,217,179, 39,148, 74, 37,244,122, 61, 44, 22, 11, 90,183,110, +141,232,232,104,164,167,167,227,215, 95,127,205,172, 83,167,142,255,177, 99,199,196,187,119,239,222,174, 64,186,107,215,174, 93, + 65, 8,193,175,191,254,154, 69, 41, 61,169, 84, 42, 55,206,157, 59,215,219,100, 50,137,207, 60,243, 76, 98,118,118,246, 20, 0, + 22,185, 92,254, 73,207,158, 61, 91,241, 60,191,214,102,179, 85,186, 50, 43,157,183, 90,173, 22, 10,133,194,157, 41, 33, 36,217, +217,217, 13, 1, 64,173, 86,251, 2,112,140,144,212,235,245, 37, 76,176,201,100, 50,248,250,250,170, 1,160,248, 59,146,114,206, + 71, 53,149, 74,181,254,246,237, 91, 30,206,145, 75,111,111,111, 12, 27, 58,148,107,215,182,173,172,113,147, 38, 61,222,250,116, +229,218, 16, 63, 79, 83, 84,136, 31, 44, 54, 11,118,237,216, 46, 82,209,178,131, 93,162, 15, 7,187,201, 40, 29,193,146, 72, 36, +216,183,111,223, 61,235,164, 82, 41,182,110,221,234,150, 25,178,155,169,242,154,200, 74,153, 33,226, 78, 84,157,231,121, 44, 91, +182, 12,162, 40, 98,226,196,137, 37,154, 13,157,245,237,102,199,149,166,253, 59,209,239,136, 0, 76, 72,250, 76,238,248,126,233, +244, 22,107, 18,119,204,208, 23, 95,124,225, 86, 4,235,241,199, 31,119,203,180, 57, 31,151, 61, 93,167, 79,159, 46, 83,119,201, +146, 37, 46,251,180,137,162,136, 95,126,249,197, 97, 78,237,188,253,246,219,163, 61, 61, 61, 53,251,247,239,199,221,187,119,161, +213,106, 81, 88, 88, 8, 31, 31, 31,239,110,221,186,157,185,123,247,110,194,197,139, 23, 89,135,119, 6,163,170, 17, 44,123,165, +235, 78, 51, 97, 89,237,253,101,232, 9,132, 16, 24, 12,134, 50,141,149,179, 41, 48,155,205,200,202,202,130, 40,138, 85,158,171, +171,172,138,213,149,193, 58,127,254,252,200, 81,163, 70,165,120,121,121, 53,206,202,202, 74,149,203,229,113,251,247,239, 15, 55, +155,205,240,244,244,132,167,167, 39,182,109,219, 6,111,111,111,188,250,234,171,119,244,122,253, 97,181, 90, 29,168,215,235,207, +222,189,123,247,173,114,157,139, 68,210,181, 67,135, 14, 56,121,242, 36,114,115,115,247, 16, 66, 26,191,240,194, 11,221,195,195, +195,201,156, 57,115, 12, 55,110,220,248, 10, 64,134, 90,173, 94,190,106,213,170,142,205,155, 55,215,140, 24, 49, 2,132,144,175, + 41,165, 6,119,143, 89,171,213,150, 48, 86,249,249,249, 40, 40, 40,128, 90,173,182,186,153,103, 18, 20,245,165,178,247,167,114, +156,155,226,232,149,253,252, 80, 65, 16,104,209, 46, 84, 82,158,158, 90,173,158,189,114,229,202, 18,125,238,236,209,209,180,180, + 52,120,122,122,226,237,183,222,146,190,251,218, 11,205,120, 77,224, 17,142, 35, 48,153,105, 46, 21, 77,219,181,105,131, 15,176, + 75,244,225, 68,176,236,134,160, 95,191,126,247, 52, 11, 74,165, 82,236,220,185, 19, 3, 6, 12,112, 60,176, 20, 55,181,187,101, + 8,250,246,237,235,136, 4,109,223,190,189,204,230, 61,123, 4,202, 29, 35,104,223,119,194,132, 9, 16, 4, 1, 95,126,249, 37, + 38, 77,154, 4,142,227,240,217,103,159,129,227, 56,204,152, 49,163, 82,245,132,189, 46, 75,248,168,232, 51,108, 82, 62,178, 22, + 5, 2, 0, 60, 60, 61,237, 59, 86, 74, 83, 16, 4, 71,228,170, 73,147, 38,144, 72, 36,104,211,166, 13, 4, 65,112, 68,174,122, +247,238,237, 60,173, 2,117, 71, 83, 16, 4, 92,187,118,205,145,230, 54,109,218,148,136, 92, 9,130,224,150, 97, 35,132,188,219, +165, 75,151, 57, 97, 97, 97, 1, 99,199,142, 37, 60,207, 35, 54, 54,214,127,198,140, 25,121, 18,137, 68, 57,121,242,228,178,174, +107, 9,128,198,245,235,215, 87,179, 43,135,193,184,143, 8, 86,101, 12,150, 59,149,163, 74,165, 58,151,153,153,217, 70, 46,151, +151, 48, 87,101, 25, 45,158,231,145,158,158, 14,149, 74,117,238, 65, 30,176,171, 38,194, 98, 51,243,154, 83, 62,180,120,250,233, +167,215,172, 93,187, 54,106,215,174, 93, 56,118,236, 24,170, 85,171,134,185,115,231,222, 74, 72, 72, 24, 74, 41,253,195,157,223, +173, 89,179,102, 3,181, 90,141,195,135, 15, 3,192, 1, 0,207,189,242,202, 43,196,106,181, 98,225,194,133, 58, 0, 59,189,188, +188, 54,252,244,211, 79, 77, 26, 53,106, 36,219,181,107, 87,193,177, 99,199,246,186,105,174,108,162, 40,222, 99,172,156,243,212, +195,195,195,157, 8,150,197,203,203,235,124,126,126,254,211,122,189, 62, 95, 46,151,123,228,231,231, 27,157,141,149, 93, 95, 16, + 4,201,181,107,215, 82, 0, 68,121,121,121,157,135, 83, 83, 98,137, 2, 38, 8, 93,187,118,237, 42,148, 62, 7,105,105,105,184, +123,247, 46,204,102, 51,154, 55,111, 78,120, 98,225,179,239,156, 29,205, 46,201,135, 15,199,113,212,126,173,219, 71,253,149, 53, +114,112,251,246,237,142,255, 57,142,195,175,191,254,234,150,105,219,185,115,103,133, 29,209, 75,117, 72,119, 25, 10,183,239,191, +112,225,194,162,215, 81, 20, 71,174, 56,142,195,244,233,211, 33,151,203, 49,103,206, 28, 76,159, 62,189, 68, 84,198, 85, 4, 75, + 16, 4, 68, 76,213, 57, 63, 20, 21, 93, 20,197,253,157, 8, 33,206, 38,203,173, 72,155,171, 14,238,238, 68,254,203, 74,167, 66, +161, 40,183,131,123, 41,205,114,127,224,196,137, 19,223, 52,107,214,236, 70,181,106,213,118,182,105,211, 70,126,226,196, 9,140, + 27, 55,142, 24,141, 70,207, 93,187,118, 57,126,183, 44,163,167,213,106,149,236,202, 97, 48,238, 35,130, 85,153, 78,238,238,244, + 75,208,235,245,187,247,238,221,219,162,127,255,254, 66, 69,205,131, 90,173, 22,129,129,129,184,121,243,166, 85,175,215,187,156, +254,192,102,115,127, 66,116, 87, 6,171,140, 60,248, 35, 38, 38,198,106,177, 88, 80,187,118,109,132,134,134,194, 96, 48, 96,222, +188,121, 86,119,205, 21, 33, 68, 26, 27, 27,203, 3, 64, 78, 78, 14, 0,100, 1,168, 83,167, 78, 29,156, 60,121, 18, 57, 57, 57, +155, 1,116,123,247,221,119,155,182,106,213, 74,186,118,237, 90,221,216,177, 99, 55, 91, 44,150, 57,238,232,139,162,104,178, 90, +173,145, 28,199,153,115,115,115,147,157,243, 51, 48, 48,208, 87,173, 86,147,180,180, 52,139, 59, 6,171,113,227,198,199,239,220, +185,131,217,179,103,103,204,157, 59,183, 78, 65, 65, 65, 78, 94, 94,158,213,217,100, 25, 12, 6,206,223,223, 95,190,104,209, 34, + 37, 0, 52,110,220,248,120,121, 6, 75,171,213,134,171, 84, 42,199,255, 70,163, 17,119,239,222,197,221,187,119,145,150,150,134, +130,130, 2, 68, 69, 69, 65,167,211,213, 96,151,227,223,135,115, 51,153,243,245,237,124, 3,175,204,181,238,172,217,175, 95, 63, + 71,223, 45,123, 68,204,190,172, 95,191,190, 68,199,113, 87, 77,111,118,131,181,112,225, 66, 76,152, 48, 1, 10,133, 2,159,127, +254,121,137, 38,194, 50, 76, 1,113, 39,157,145,211,244,184,187,192, 23, 18,137, 4,126, 99,211, 74, 52,197,149, 49, 26,207, 45, + 35, 56,119,238,220, 7,214, 68,104,215,172, 81,163,232, 82, 89,182,108, 25,158,126,250,105, 28, 56,112,160,202, 77,132,145,145, +145,171,230,207,159, 47,191,120,241, 34,242,243,243,145,145,145, 1,163,209,136,164,164, 36, 71,222,148,133, 78,167, 83,176,171, +134,193,184, 15,131,229,220,249,211,149,193, 42,238, 32,233,202, 8,124,254,206, 59,239,188,210,190,125,123, 95, 15, 15, 15,164, +164,164,220, 99,174, 10, 11, 11,161,209,104, 96, 50,153,176,119,239,222,124, 81, 20, 63,119,101, 10, 44, 22, 11, 2, 2, 2,144, +153,153, 9,177,156,126,209, 28,199, 65,169, 84, 66,171,213,162, 60, 51, 80, 81, 5,108, 54,155, 97,177, 88, 96,177, 88, 42,109, +210, 0, 40,237, 19,182, 22,255,190, 54, 36, 36,164,166, 66,161, 64,124,124, 60, 0, 92, 3,208,185,103,207,158,146,172,172, 44, +250,226,139, 47, 30,161,148,142,119, 49,155,189,105,255,254,253,145, 0,160, 84, 42,175, 2, 64, 82, 82,146, 37, 55, 55,183, 68, +100, 80,165, 82,209, 1, 3, 6, 4, 83, 74,177,127,255,254, 72,169, 84, 74, 81,206,156, 85, 0, 12,155, 55,111,190,232,229,229, +181,230,131, 15, 62, 24,218,167, 79,159, 11, 13, 27, 54,140,212,106,181,233,122,189, 94,111, 48, 24, 40,207,243, 82, 31, 31, 31, +197,142, 29, 59,110, 28, 57,114,164,155,167,167,231,154,205,155, 55, 95, 4, 80,102,164, 77,173, 86, 39,233,116,186, 8,141, 70, + 3,189, 94, 95,194, 92,221,189,123, 23,148, 82,220,186,117, 11, 42,149,234, 14,187, 28,255, 30,156, 35, 46,165, 35, 45,165,215, +185,107,174,156,205,208,142, 29, 59, 42,156, 3,203, 93, 77,103, 51, 52,105,210, 36, 44, 88,176,224,158, 8,214,156, 57, 69,207, + 36,111,189,245,150,203,232,149, 51, 18,137, 4,119, 23,248, 34,104, 66,118, 9, 51, 3, 0,196,158,190, 74, 78,201, 38, 8, 2, +102,207,158,125, 79,231,115,231, 38, 60,119,141,149,115, 58,211,211,211, 33, 8, 2,124,125,125, 49,108,216, 48,244,232,209,195, +209,212, 88, 89,221,196,196,196,211,159,126,250,105,245,208,208, 80,172, 93,187,214,164, 86,171,101, 93,186,116,161,185,185,185, +164,162, 8, 22, 51, 88, 12,134,107, 56,119, 42, 72,119,154, 9,203,170, 36, 9, 33,221,156,255, 79, 72, 72,200,211,106,181,195, +134, 12, 25,162, 55, 26,141,168, 89,179, 38,228,114, 57, 44, 22, 11, 76, 38, 19,164, 82, 41,130,131,131, 65, 41,197,134, 13, 27, +244, 58,157,110, 88, 66, 66, 66, 94, 69,154,132,144, 55, 31,123,236, 49, 67,124,124, 60,170, 87,175, 14, 15, 15,143,123, 94, 27, +225,233,233, 9,111,111,111, 92,190,124, 25,203,151, 47,215, 19, 66,222,172, 72,179, 44,163,105, 55, 86,118,163,229,106,100, 82, + 41, 77,181, 61,138,163,211,233, 0,192, 90,189,122,245, 64, 0,184,117,235, 22, 0,220,142,138,138,234, 88,171, 86, 45,114,224, +192, 1, 80, 74,119,149,101,174, 74,105,102,199,197,197,221,142,139,139, 51,153, 76, 38,169,201,100,146,230,229,229,153,253,253, +253, 3,252,253,253,253, 3, 3, 3,125, 3, 2, 2,188, 83, 82, 82,172, 86,171, 85,106,179,217,164,113,113,113,166, 86,173, 90, +221,129,211,108,238,165, 52, 69, 0,249, 75,150, 44,153, 37,145, 72,110,183,109,219, 54,102,218,180,105, 9, 22,139,197, 24, 26, + 26,234, 19, 20, 20,164,212,233,116, 5,239,191,255,126,250,130, 5, 11,186, 73, 36,146,219, 75,150, 44,153, 5, 32,191,248,187, +247,104, 90,173,214,221,187,118,237,178, 90, 44, 22, 36, 39, 39, 35, 37, 37, 5,169,169,169,142, 79,111,111,111, 28, 63,126,220, +102, 54,155,119, 85, 34, 63, 31,148,177, 96,154,248,179,239, 79, 69,198,202,157,110, 0,165,211,105, 55, 67, 79, 63,253, 52, 6, + 15, 30,140, 33, 67,134, 96,216,176, 97, 24, 49, 98, 68,101,166,102, 40,125,189, 59,190, 59,109,218, 52,188,245,214, 91,120,231, +157,119, 32,151,203,241,246,219,111, 99,230,204,153,152, 57,115,102,105,115, 69, 42, 56,246, 18,245, 92,222,178, 80,232, 86, 68, +192,180,186, 86, 81, 19, 33,165,127, 46,238,231,167,195, 12,189,253,246,219, 56,114,228, 8,166, 76,153,130, 61,123,246, 96,220, +184,113,216,182,109, 27, 70,143, 30,141, 95,126,249,197,241, 89,252, 16, 72,221, 73,167, 32, 8,232,216,177, 35,116, 58,157,195, +192,142, 25, 51,166,132,222,232,209,163,221,202, 79,165, 82, 57,116,243,230,205, 27,151, 47, 95,126, 43, 59, 59,187, 71, 66, 66, +194, 29,173, 86, 75,242,242,242, 28,231,176,244, 82, 28,137,150,179,235,136,105, 50, 11,117, 31, 17, 44,171,213,138,240,240,240, + 18,239,182,226, 56,174,196, 82,153,126, 4, 0,144,154,154,186, 35, 56, 56,248,201, 39,158,120, 98,245,115,207, 61,231, 17, 29, + 29, 45,137,136,136,128, 78,167,195,237,219,183,145,144,144, 96,221,179,103, 79,190, 78,167, 27,158,154,154,234,114, 20, 89,114, +114,242,202,192,192,192,237,195,135, 15,159,209,180,105,211, 49, 19, 39, 78,228,163,162,162,144,151,151, 7, 31, 31, 31, 4, 4, + 4, 32, 62, 62, 30,251,246,237,179,229,230,230, 46,182,217,108,239,166,165,165,101, 84, 38,147,172, 86, 43,111, 54,155, 49,100, +200, 16,136,162,136,121,243,230,193,106,181,242,149,144, 48,155,205,102, 10,128,100,102,102, 2,128,206,110,184,174, 95,191, 14, + 0,119, 34, 34, 34, 52, 0,176,107,215, 46, 2,224,176,187, 15,244,206,145,172,232,232,232,120,123,165,232,124,147,179,111, 47, +142, 92,185,122, 12, 55, 12, 26, 52, 40, 93,167,211,245,156, 52,105,210,140,133, 11, 23, 14, 93,184,112,225, 61, 59,121,122,122, +174,249,236,179,207,222, 29, 52,104, 80,122,121,209,171,226,136,221, 91,207, 62,251,236,160,115,231,206,121, 40, 20, 10,104,181, + 90,100,101,101,193,108, 54, 35, 42, 42, 10,233,233,233, 88,185,114,101,129, 94,175,159,201, 46,199,191,151,242,140,149,187,125, + 44,203,139,226,108,221,186,181,204, 57,166, 42,171, 89,218,100,184, 59, 55,149, 27, 15, 67,101, 78,253, 80,153,122,173, 60,205, +143, 63,254,216, 49,217,106, 89,145,171,202, 68,176,236,154,190,190,190, 0,138,102,223, 23, 69, 17,143, 63,254,120,149,117,139, +223, 45,248,164,253,255,216,216,216,119,215,174, 93, 59,135, 82,234, 7, 64,112,206, 3,246, 82, 5, 6,227, 1, 25, 44,155,205, +150,212,177, 99,199, 18, 21, 91, 69, 47, 85, 45, 54, 34, 73,110,154,172,237, 81, 81, 81, 81,203,150, 45,251,159, 90,173,238,102, + 48, 24, 26, 1,128, 66,161, 56,167,213,106,119,113, 28, 55, 63, 53, 53,213,237,151, 51, 23, 27,166,113, 97, 97, 97,243, 70,140, + 24, 49,167,109,219,182, 3, 95,124,241, 69, 34, 8, 2,214,173, 91, 71,147,146,146,214,115, 28,247,102, 74, 74,202,205,170,100, +146, 74,165,186,186,126,253,250,154, 91,183,110,133,197, 98,193,162, 69,139,160, 80, 40,174,186,251,125, 74,105,134, 32, 8,171, +219,182,109, 59,244,200,145, 35,107, 40,165,231,229,114,249,247,113,113,113,195, 14, 31, 62,252, 35,165,244,146, 32, 8,223,183, +105,211,102,216,241,227,199, 55, 80, 74,207, 86, 34,121,217,113,113,113, 57, 0,130,172,214,178, 91, 20,227,226,226, 76, 0,238, +186, 97,174,236,228,143, 26, 53,202, 60,106,212,168,215, 6, 13, 26,180,252,143, 63,254,104,153,155,155,219, 8, 0,188,189,189, +207,181,104,209,226,248,143, 63,254,120,165, 56,114,101,112,117,236,132,144, 1,141, 26, 53,218,240,222,123,239,169, 99, 98, 98, +132,218,181,107, 35, 33, 33, 1,231,207,159,183,126,243,205, 55,133,122,189,190, 31,165, 52,135, 93,142,127, 15,246, 38, 66,111, +111,239, 18, 15, 79,246,161,251,149,105,194, 43, 75,179,244,131, 25,207,243, 21,105,186,116, 53, 26,141,198, 49,106,217,157,174, + 9, 21,189,123,212,158, 78,187,166,125,113,195, 92, 81, 87,154,197,175,233,169,140, 38,220,209,180, 88, 44, 14, 93, 55, 52, 43, +245,163, 39, 78,156,248, 6,192, 55,181,107,215,190, 14,160, 22, 51, 85, 12,198, 95, 96,176, 46, 95,190, 28,251, 87,254,240,173, + 91,183,242, 1,188, 91,188, 60, 16,146,146,146,110, 2, 24, 20, 20, 20,244,201,225,195,135,223, 6, 0, 81, 20,103,187,122,159, +161, 43,206,158, 61, 59, 64, 34,145, 44, 92,177, 98, 69, 91, 74, 41,188,188,188, 14, 95,191,126,253,229, 74, 70,193,198, 16, 66, + 38,218, 71, 5, 26,141,198, 49,132,144,201,148, 82,173,211,118,199,255,149,132, 2, 48, 82, 74, 67,202,217,110,172,132,185,114, + 68,178, 0,152,126,252,241,199, 66, 0,103,240,231, 60, 87,150,226,197, 0,167,102, 65, 23, 55,184,223, 9, 33,181,223,126,251, +237,185, 60,207,119,213,106,181,161,106,181, 58,209,106,181,238,214,233,116,111, 82, 74,179,216,165,248,247, 97,181, 90,147, 59, +118,236, 40,148,245,224, 84,209, 13,188,162, 7, 42,155,205,150, 20, 23, 23,135, 42,104, 38, 87,144,212,219,109,218,180,225,220, +213,178, 99,177, 88,210, 43, 74,103,155, 54,109,202,125,104,172,234,177,183,105,211,166, 82,105, 44,174,171,146, 31,180,166,139, +252, 44, 23,189, 94,159, 83,173, 90,181, 66,131,193, 32, 49, 26,141,146,210, 17,123,165, 82,153,193,174, 28, 6,163,138, 6,235, +223, 76,177,161,234,251,160,244,138,251, 67,189,244, 0,116, 12,165,254,215, 86,244,127, 37,249, 43, 34, 64, 34, 0,221, 3,202, +195, 76, 0, 47,178, 75,238,159,199,249,243,231, 91, 61,104,205,139, 23, 47,198,254, 5,233,108,243,160, 53, 47, 92,184, 16,251, +168,106, 86, 68,114,114,114, 43,118,101, 48, 24,247, 7,199,178,128,193, 96, 48, 24, 12, 6,227,193, 66, 0,148, 57, 18,160, 50, +111,202,174,202,104, 2, 87,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,252,239,105,186,210,174,140,255,248, 71, 83,214, 48, +220, 7,181, 0,232,198, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,249,168, 45,172,137,144,193, 96, 48, 24, 12, 6,227, 1, +195, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193,120,132, 32,132,144, +176,176,176,142, 33, 33, 33,109, 30,213, 60, 16, 88, 49, 96, 48, 24, 12, 6,131,241, 32,168, 94,189,186,183,205,102,123, 46, 36, + 36,228,229,154, 53,107,214, 4,128,208,208,208,243,148,210,249, 74,165,242,251, 27, 55,110,152, 30, 25,147,201, 94,133,192, 96, + 48, 24, 12, 6,227,126, 8, 9, 9,105, 10,224,101,165, 82, 57,188, 85,171, 86,178, 46, 93,186,192,199,199, 7, 86,171, 21,169, +169,169,248,253,247,223,113,250,244,233,108,139,197,178,208, 98,177, 44,204,200,200, 72, 99, 6,139,193, 96, 48, 24, 12, 6,163, + 28,130,131,131, 63,237,213,171,215, 36, 31, 31, 31,212,174, 93, 27, 65, 65, 65, 48, 26,141,208,235,245,160,148, 66, 16, 4, 80, + 74, 81, 80, 80,128, 19, 39, 78,224,216,177, 99,214,252,252,252, 53,132,144,249, 41, 41, 41,167,153,193, 98, 48, 24, 12, 6,131, +193, 40, 69, 72, 72, 72,218,158, 61,123, 2,172, 86, 43, 50, 51, 51, 97, 52, 26,161,211,233, 28, 6,139,231,121, 80, 74, 97,181, + 90, 1, 0,162, 40,226,210,165, 75, 56,114,228, 8, 18, 19, 19, 63, 75, 77, 77,125,237,191,152, 47,172,147, 59,131,193, 96, 48, + 24,140,251,194,104, 52, 98,213,170, 85,200,204,204, 68,120,120, 56, 66, 67, 67,225,237,237, 13,165, 82, 9, 0, 14,115, 5, 0, + 28,199, 33, 38, 38, 6,195,135, 15, 7, 33,100,216,127, 53, 79, 88, 39,119, 6,131,193, 96, 48, 24,247,131,197,100, 50, 33, 54, + 54, 22,241,241,241, 56,121,242, 36,154, 53,107,134,250,245,235, 35, 51, 51, 19, 41, 41, 41, 37,118, 62,126,252, 56, 78,157, 58, +133, 14, 29, 58,252,167, 51,133, 53, 17, 50, 24, 12, 6,131,193,168, 50,161,161,161,207, 84,171, 86,109,209,136, 17, 35,148, 77, +154, 52, 65, 82, 82, 18,146,147,147,145,147,147,131,166, 77,155, 34, 38, 38, 6, 55,111,222,196,246,237,219,113,234,212, 41,200, +229,114,132,133,133, 65,179,230, 7,252, 18, 18,156,156,146,146, 18,198, 12, 22,131,193, 96, 48, 24, 12, 70, 41, 66, 66, 66,252, + 8, 33,111,134,134,134,190, 50,108,216, 48, 73,237,218,181,145,148,148,132,140,140, 12,228,228,228,224,232,209,163,118, 51,134, +176,176, 48, 36, 36, 36,224,220,185,115,122,163,209, 56, 54, 57, 57,121, 37, 51, 88, 12, 6,131,193, 96, 48, 24,229, 27,173,112, + 0,179,106,213,170,245,204,211, 79, 63,205,133,132,132, 32, 57, 57, 25,123,246,236, 65,173, 90,181,144,150,150,134, 19, 39, 78, +216,242,243,243, 23,219,108,182,119,211,210,210, 50,254,171,121,241,151,118,114, 39,132,116, 99,154, 76,147,105, 50, 77,166,201, + 52,153,230,163,161,153,146,146,146,152,146,146, 50,242,218,181,107, 49,115,230,204,217,188,104,209, 34,240, 60,143,208,208, 80, +236,217,179,135,238,222,189,123,125, 97, 97, 97,221,148,148,148,113,255,101,115, 5,176, 78,238, 12, 6,131,193, 96, 48, 30, 48, +119,239,222,189, 12, 96, 64,104,104,104,171, 11, 23, 46,188, 1, 0,162, 40,206,190,123,247,238,137, 71, 37, 15,152,193, 98, 48, + 24, 12, 6,131,241,151,144,156,156,124, 12, 64,223, 71,241,216,217, 60, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6, +131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,241, 72, 65, 0,148, 57, 18,128, 82,186,203,109,145, 42,140, 80,112,165,207, 52, +153, 38,211,100,154, 76,147,105, 50,205,255,158,166, 43,237,202,248,143,127, 52,148, 82,151, 11,138,231,203,170,236, 2,160, 91, + 85,190,199, 52,153, 38,211,100,154, 76,243,225,107, 86,165,174, 47, 75,179,248,225,157,160,168,149,132,179,255,255, 79, 75,231, +191,229,216, 31, 21,205,255,218, 34,184,112,151,142, 76, 34,132,136, 0, 68,250, 0,102, 38, 37,132,216, 79,192, 3,209, 99,252, + 5,161,205,162,115, 68,254,244,225,236, 60, 49, 24,255,225,235,253,129,213,245, 78,117, 7,239,116,147,181, 1,176, 17, 66,112, + 63,117,201, 95,113, 79,250,167, 31,251,163,172,249,111, 71,168, 40,163,170, 85,171,182, 35, 32, 32,160,115,102,102,166, 88,188, + 30,161,161,161,224, 56, 14,130, 32,232,227,227,227, 61, 43,251,131,129,129,129, 95,199,196,196, 60,151,149,149, 37,114, 28,135, +240,240,112, 16, 66,192,243, 60,120,158,215,223,184,113,195,243,239,206,148,230,205,155,231,152, 76, 38, 77,233,245, 50,153,204, +112,242,228, 73,143, 71,193, 92,249,251,251, 63, 25, 24, 24,232,157,157,157, 77, 1, 32, 44, 44, 12, 60,207, 23, 21, 26, 65,176, +222,188,121,115,133,187,122,145,145,145,199,149, 74,165,183, 32, 8,224,121, 30,130, 32, 64,171,213,230, 94,186,116,169,101,241, +246, 67, 74,165,210,143,231,121,123,217,130,193, 96,200,186,120,241, 98, 59,118,235,251,119,178,126,253,122,190,103,232,243,181, + 4,170,111,204,113,212, 75, 20, 73,158,149, 40,207,110, 79,254,250,134, 59,223, 31, 56,112,160,237,111,190, 6,170, 3,176, 82, + 74, 83,170,240,101,174,140,138,182,151, 13, 24, 92,252,175,129, 3,178, 8,112,173, 46,176,225, 34,160, 47,213,172, 32, 62,236, + 7,169,234,213,171,207,175, 86,173,218,200,194,194, 66, 29,199,113, 32,132,208,152,152, 24,251, 62, 37, 62, 69, 81, 76,186,112, +225, 66,172,139,155,172,164,122,245,234,159, 85,171, 86,237, 89,157, 78,167, 35,132,128, 16, 66, 9, 33,104,212,168,209, 61,154, + 54,155, 45,233,252,249,243,177, 15, 43,157,127,215,177, 55,108,216,176, 76,205,242,142,189, 44, 77,231,116, 18, 66, 16, 19, 19, +115,223,233,252, 39,106,254,103, 13, 22, 0, 46, 32, 32, 96,115,203,150, 45, 59,109,217,178,133,187,124,249, 50, 23, 29, 29, 13, +155,205, 6, 81, 44,186,246,155, 53,107,166,170,236,143, 5, 5, 5,125,215,178,101,203, 33, 91,182,108,225, 54,111,222,204,181, +104,209, 2,132, 16,216,108, 54,216,108, 54,116,237,218, 85,121,159,149,133, 70, 16,132,137, 50,153,172,163,213,106,173, 15, 0, + 18,137,228,146,209,104,220,103,181, 90, 63,167,148, 22,186,163, 99,177, 88, 84, 23, 46, 92,184, 39,111, 90,182,108, 41,171,106, +218,234,212,169,115,152,227,184,168,178, 46,218,242, 62, 41,165,183, 46, 92,184,208,182, 60,205,122,245,234, 29,230, 56, 46,202, +190,127, 89, 26,165,215,137,162,120,235,252,249,243,109, 43,170,116, 2, 3, 3,159,106,219,182,173,215, 79, 63,253, 68, 18, 19, + 19,137, 82,169,132, 40,138,176,217,108,176, 88, 44,232,210,165, 75,165,230, 79, 83,169, 84,158,187,119,239,174, 21, 16, 16,128, +244,244,116,100,101,101, 97,244,232,209,215,236,219,149, 74,165,223,239,191,255, 94,199,215,215, 23, 58,157, 14,121,121,121, 24, + 54,108,216,191,254,226,234,209,161,230,123, 4,240,181,255,111, 19,145,189,235,224,205,183,238, 87,183, 94,189,122,167,100, 50, + 89, 96,121,231,188,172,115,111, 50,153,210, 46, 92,184,208,204,197,245, 19, 1,160, 47,207,243,181, 5, 65,168, 7, 32,194,106, +181, 6, 2,128, 84, 42, 77,227,121, 62,193, 98,177, 92, 49,153, 76,215, 1,108,165,148, 38,148,167,213, 51,244,249, 90,196,170, + 27, 88, 96, 20,123,171,106,126, 80, 87,119,115,250, 85,149, 92,183,173,103,232,243,235,221, 53, 89,127,163,185,138, 12, 9, 9, +249,184,248,239, 41,148,210,248,251,213,180, 1,131, 41,165, 94, 0,144,151,151,231,149,152,152, 24,180,117,235,214,152,185,115, +231,118,145, 25, 12, 31,153,128,203, 21,125,191,123,199, 90, 39, 4,142,132,161, 56, 6, 96,165, 98,210,206,125, 55, 31,196,141, +137, 11, 13, 13,157,223,179,103,207, 17,139, 23, 47, 86, 29, 59,118, 76,213,176, 97, 67,240, 60,111,175, 47, 80, 58,240,208,186, +117,235, 10,179, 15,128, 16, 18, 18, 50,239,177,199, 30, 27,186,112,225, 66,213,149, 43, 87, 84,145,145,145, 40,190,217,150, 40, +155,246,117, 77,155, 54,125,216,233,252, 75,143,189, 87,175, 94, 67, 23, 45, 90,164, 58,119,238,156,170,118,237,218,224, 56, 14, + 28,199,221,163,199,113, 28, 98, 99, 99,221,210,236,209,163,199,208, 37, 75,150,168, 78,157, 58,165,170, 87,175,158, 35,239,156, +154,231, 42,157,206,127,184,230,127,207, 96, 17, 66,184,106,213,170,173,138,141,141,237,185,101,203, 22, 30, 0, 78,157, 58,133, +236,236,108,132,134,134, 66,163,209, 64, 46,151,195, 96, 48, 84, 42,220, 23, 24, 24,248,117,177,185,146, 0,192,134,225, 3,112, + 75, 2,140, 79, 55, 65, 42,149,226,230,205,155,224,121,254,126, 66,199, 29, 60, 61, 61, 87,110,220,184,209,167, 89,179,102, 92, +102,102, 38, 34, 35, 35,145,157,157,221,114,255,254,253,205,159,127,254,249,231, 9, 33,207, 80, 74,247,187,171,185,109,219, 54, +168,213,106,168, 84, 42,168,213,106,152,205,102, 82,213,244,241, 60, 31,118,236,216,177, 0,141, 70, 3, 81, 20, 29, 75,169,246, +107, 7,162, 40,162, 67,135, 14,230, 10, 79,158, 32,132, 29, 59,118, 44, 64,169, 84,130, 82, 90, 66,207,102,179, 65, 46,151, 59, + 63, 33,194,102,179,161, 77,155, 54,102, 87,145, 43,187,185, 2,128, 53,107,214, 32, 40, 40, 8, 1, 1, 1, 80,171,213, 80, 42, +149, 85, 57,118,248,249,249,225,149, 87, 94,193,224,193,131,177,122,245,106, 72, 36, 18,231,227,128,175,175, 47,126,251,237, 55, +120,122,122,162, 70,141, 26, 37,182,255,107, 35,129,128,239,246,253, 55, 29, 17,217,129,125,154, 8,221,226,162, 22, 58, 42,215, +162,157,168, 88,180, 47, 21,109,182,156,221,135,110,207,112,121, 87,224,184,144, 99,199,142, 5,200,229,114,247,110,238, 54, 27, +154, 53,107,198,187,184,126,122,199,196,196,108,120,249,229,151,165,181,107,215, 38, 82,169, 20,130, 32, 64, 16, 4,123,121,172, + 65, 41,173, 33,138, 98,167,180,180, 52,250,197, 23, 95,124, 68, 8,121,130, 82,186,173,204,178, 73,245,141, 11,140, 98,239, 3, +167,209,114, 96,183,105,248,109,221,244,150,113, 77, 69,120,168,244, 55, 0,252, 99, 13, 22, 33,196, 83,169, 84,190,189,110,221, + 58, 41, 0,116,235,214,237,109, 66,200,171,148,210,252, 7,245, 27, 94, 94, 94,240,242,242, 66,195,134, 13,241,228,147, 79,122, + 55,109,218,116,114, 39,163,113,204, 94,160,220,107, 83,224,184,176, 95,127,191, 22, 96,255,127,232,128,230,210,158,157,106,165, + 21, 61,136,149,222,155, 66,180,209,164, 93, 7,111,197,186, 56, 86, 46, 40, 40,232,147, 94,189,122, 13, 90,188,120,177, 7, 0, +124,253,245,215,120,252,241,199, 17, 24, 24, 8,165, 82, 9,153, 76, 6,137, 68, 2,169, 84,234,248,116, 17, 17,226,131,130,130, + 62,122,252,241,199, 7, 46, 92,184,208, 3, 0,190,251,238, 59,244,233,211, 7,126,126,126,240,244,244,132, 92, 46,135, 76, 38, +131, 84, 42, 45, 97,184, 42,147,206, 23,122,116, 65, 77,165, 28,125,222,251, 8, 62, 62, 62,216,253,218,203,144,112, 28,198,109, +223, 15, 15, 15,143, 10,211, 89,158,230,201,147, 39,145,158,158, 94,230,177, 19, 66, 42,172,251,156,143,189,119,239,222, 3, 23, + 45, 90,228, 56,246,158, 61,123,194,207,207, 15, 30, 30, 30,144,203,229,144, 74,165, 37,150,242,242,192, 89,179, 87,175, 94, 3, +151, 44, 89,226, 1, 0, 43, 86,172, 64,183,110,221,224,227,227, 3, 15, 15, 15, 71, 94, 86,246, 28,253,147, 53,255,147, 6,203, +222, 55, 42, 32, 32, 96,208,207, 63,255,204, 57,223, 0,229,114,185,227,194,144,201,100,224, 56,174, 50,149, 22,137,137,137,121, +110,203,150, 45,142, 47,153, 74, 85, 10,114,185,188, 82,154,165,244,187,117,238,220,249,135,159,127,254, 89, 33,149, 74,161,215, +235,113,225,194, 5,120,121,121, 65, 38,147,161,127,255,254,124,187,118,237,252, 58,117,234,244, 19, 33,100,168, 59, 35, 20, 40, +165,208,104, 52, 37, 12,214,253, 52, 33,219, 47,208, 45, 91,182,128,231,249, 18,133,204,254,233,252,119, 64, 64,128, 91,186,114, +185, 28,135, 15, 31, 6,207,243,144, 72, 36, 16, 4, 1, 18,137, 4,191,252,242, 11, 94,123,237, 53,100,102,102,130, 16, 2,137, + 68, 2, 15, 15,151,173,155, 36, 48, 48,208,219,110,174,138, 35,128, 80, 42,149,144, 72, 36, 68, 16, 4, 98,111,198, 35,132, 16, +119,219,212, 5, 65, 64, 66, 66, 2,134, 15, 31,142, 21, 43, 86, 96,246,236,217, 24, 58,116,104,137,237,249,249,249,240,241,241, +129,143,143, 15, 20, 10, 69,149,203,194, 63, 9,177, 84,238,188, 59,231, 99, 21, 68,138,162, 78, 30, 34, 32, 2, 20, 20, 34, 21, +145,150,124, 3,159,126,178,128,119,183, 44,201,229,114, 28, 58,116,200, 97,130, 4, 65, 0, 33, 4,206,198,200,190, 4, 5, 5, +185,212,148, 74,165,179, 54,109,218, 36, 91,189,122, 53,214,174, 93,235,248, 13,181, 90, 13,111,111,111,248,249,249, 57,150,176, +176, 48,242,205, 55,223, 72, 27, 55,110, 60, 11,192,182,178, 77, 32,245, 82,213,252,160,238,192,110,211,138,204,229, 52,138,156, +107,115,154,112,185, 51,188,254,193,230, 74, 0,240,250,151, 95,126,233,215,188,121,115, 0,192,151, 95,126,233, 55,106,212,168, +215, 9, 33,111, 81, 74,173, 85,126,192, 2,214, 18, 66, 6, 23, 71,108, 21,221,187,119,151,125,245,213, 87,168, 87,175, 30, 38, + 76,152,224,251,233, 71, 31,245, 5,240, 83,249,101,169,100, 97,250,224,227,249,222,148, 22,149, 31, 42,210, 18,159,217,233, 9, +120,251,237,247, 92,214,201, 0,184,144,144,144,231,151, 46, 93,234,232, 14,225,227,227, 83,102,221, 36,145, 72, 28, 75, 5,166, +136, 20, 71,133, 70, 45, 94,188,216,161,233,239,239, 15,169, 84, 90,226, 6,123,251,242, 25,108, 91,254, 62,212,190, 65, 24, 62, +229,195, 74,167, 51, 76, 46, 67,152, 82,134, 38, 77,154, 64,165, 82,225,164,164,232, 86,230,225,225,225, 50,157,229,105, 58,215, +203, 0,160,211,233, 28, 81,123,147,201,132,216,216, 88,183,142,125,201,146, 37, 14, 77, 63, 63, 63,199,177,219,211,229, 92,215, +219, 31, 96, 42,210, 12, 9, 9, 25,181,108,217, 50,135,166,175,175,111, 9, 13,137, 68,130,149, 43, 87,222, 83, 71,220,175,102, +101,207,123,105,205,132,132, 4,204,157, 59,215, 81, 39,217,163,120,246,174, 70, 11, 22, 44,112,203, 96,255,167, 34, 88, 0, 72, +102,102,166,120,249,242,101,238,228,201,147,144, 72, 36, 8, 8, 8, 64,139, 22, 45, 0, 0,102,179,217,126,211, 37,245,234,213, + 75,227, 56, 14,246,155, 46,199,113,176, 90,173,142,246,100, 39, 35,195,101,103,103,139, 59,119,238,228, 86, 61,209, 3, 38, 10, + 52,125,251,125,244,236,211, 7,219, 67,101,224, 1,180,188,156, 9,153, 76, 38, 4, 7, 7, 91,236, 39,193,174,237,220, 55,171, +180, 57, 34,132,120,168,213,234,111,182,110,221,170,224, 56, 14, 5, 5, 5, 16, 69, 17,237,218,181, 3,199,113, 56,127,254, 60, +222,124,243, 77,108,216,176, 1,155, 54,109, 82, 54,107,214,236, 27, 66, 72,125, 74,105,129,147,153,218, 85, 86,225,244,240,240, +128, 74,165,114, 24, 44,251, 49, 23,183,169,151,110,146, 73,190,112,225, 66,243,242, 52,237,145,132, 1, 3, 6, 56,250,156,217, +205, 80,233, 79,169, 84,138,243,231,207,151,101,250,238,209, 20, 69, 17,237,219,183,183, 55,197, 65,163,209, 96,239,222,189,142, +237, 77,155, 54,133,201,100,130,191,191, 63, 46, 93,186,228, 82, 51, 35, 35,131,166,164,164,144, 85,171, 86, 65, 34,145,192,207, +207, 15, 42,149,138,252,244,211, 79,175, 43, 20,138, 48,163,209, 40, 90, 44, 22,132,133,133, 45,168, 81,163,134,253, 28,105,111, +220,184,225, 87,158, 38,207,243, 80, 40, 20,248,238,187,239, 48,119,238, 92,188,241,198, 27, 37, 46, 44,158,231, 97, 48, 24,224, +239,239,239, 48, 89,165, 47,188,191, 98,216,238, 95,173, 73, 65,113,225,212,118, 92, 60,183, 11,162, 77,132, 77,164,160,212, 6, +209, 10,156,220,121,180, 78,234,173,148, 80, 10, 10, 20,247,184,177, 20,106,173,157,252,229,245, 0,108,222,155,105,156,231, 42, +157,130, 32,192, 98,177, 96,235,214,173,184,113,227, 6,118,236,216, 1,189, 94,239,200,199, 54,109,218, 96,212,168, 81, 8, 10, + 10,114,153,159,148,210,239, 18, 19, 19,155,182,111,223,158,228,230,230, 34, 55, 55, 23,122,189, 30, 54,155, 13, 86,171, 21,130, + 32, 64,161, 80, 64,169, 84, 34, 48, 48, 16, 6,131,129, 26,141,198,239,202,211, 20, 69,146,167,187, 57,253,234,111,235,166,183, + 28, 56,141, 98,253,135, 4,117, 34,228,186,125,103,188, 71,109, 59,246,122,119, 66, 57, 10, 20, 29, 58, 71, 64,109, 54, 91,230, + 75,227, 63, 24,247,176,207, 81, 41,198, 76,156, 56,177,190,115,243,244,176, 97,195,112,225,194,133,250,159,127,254,249, 24, 0, + 95, 86, 86,211, 7, 8, 5, 0, 43,240, 27,138, 22,172,215,235,201,144,205,155, 7, 0,120,118,211,166, 77, 24, 58,116, 40, 62, +249,232,163,134,165, 13, 86,137,178, 68, 41, 18,174, 29, 64,194,245,131, 16, 69,234, 20, 5, 47,251,111,234, 94, 58, 73, 97, 97, +161,225,216,177, 99,154, 21, 43, 86,192,219,219, 27, 81, 81, 81,142, 86,138,210, 55, 88,251,255,174,202,146, 78,167, 51, 92,190, +124, 89,243,195, 15, 63,192,215,215, 23, 53,106,212,128, 74,165,114,104,202,100, 50, 28,221,190, 17, 99,134,247, 70,102,194, 69, +204,127,117,144,219,233,124,161,123, 23,132, 43,100, 24, 48,251, 3, 68, 71, 71, 99,253,224,126,224, 8, 48,118,207, 81, 72,165, + 82,172,232,221, 1, 50,185, 12, 99,247,252,225, 42,157, 14,205, 19, 39, 78, 64, 20, 69, 68, 68, 68, 64,167,211,193,211,211, 19, + 10,133, 2, 18,137, 4, 59,119,238, 68,255,254,253,177,122,245,106,180,105,211,198,229,177, 23, 22, 22, 26,206,157, 59,167,249, +254,251,239,225,235,235,139,240,240,112,168, 84, 42, 71, 96,194,110,180,120,158, 71, 84, 84, 20,242,242,242, 80,179,102,205, 10, + 53,181, 90,173,225,228,201,147,154,239,191,255, 30, 62, 62, 62, 8, 11, 11,115, 68,216,236,166,104,230,204,153, 37, 52,154, 52, +105,114,223,154,149, 61,239,165, 53, 7, 12, 24,128, 90,181,106,193,211,211, 19,106,181,218,161, 93,145,230,127,218, 96, 81, 74, +105,241, 40, 10, 68, 71, 71, 35, 59, 59, 27,114,185, 28, 45, 90,180, 64,102,102, 38, 52, 26, 13,164, 82, 41, 40,165, 24, 60,120, + 48, 63,101,202,148,128, 98, 83,229,168,240,203,105, 75, 23, 57,142, 67,219,182,109,113,161,184,229,167,103,159, 62, 8, 11, 11, +131,189, 19,135, 66,161,192,208,161, 67,201,107,175,189, 38,216,163, 23,148, 82,232,245,122, 52,110,220, 88, 89, 65,116,228,213, +159,126,250,201, 75, 38,147,161,160,160,192,209, 68,198,243, 60, 46, 95,190,140, 79, 62,249, 4,207, 62,251, 44,238,220,185,131, +144,144, 16, 76,158, 60, 89,243,193, 7, 31,188, 10,224, 93, 87,153,163,209,104, 28,230, 74,165, 82, 97,196,136, 17, 66,187,118, +237, 2, 52, 26, 13, 60, 60, 60, 96,111,238,179,217,108,104,219,182, 45,113, 21,117, 16, 69, 17,219,183,111,135, 32, 8, 46, 35, + 88,197,109,214,110,105, 30, 59,118,204, 97,206,156,159,138, 8, 33,184,112,225,130,195,204, 21, 23,230,138, 52, 41,207,243, 80, +171,213, 8, 10, 10,130, 82,169,132, 74,165, 34, 91,182,108,121, 43, 34, 34, 34,248,229,151, 95,230,242,243,243,185,216,216, 88, +244,238,221, 91, 16, 69, 17,102,179, 25, 93,186,116,169, 48, 31, 37, 18, 9,142, 31, 63,142, 15, 62,248, 0,211,166, 77,195,146, + 37, 75,208,173, 91,183, 18, 70,129, 16,130,106,213,170,193,211,211,243,191,115,117,137,128,217,106,129,174, 80,239,104,194,181, +217,108, 56,183,247, 76,157, 91,103,174,197,252,252,195,106, 9, 0, 24,246,110,116,254, 86,240,147, 11,127,172,219,201, 87,122, +108,111,182,249,152,139,166, 66, 76,152, 48, 1, 51,102,204,192,224,193,131,177,115,231, 78,188,249,230,155,120,254,249,231, 75, + 68,176,220,193, 98,177, 44,125,230,153,103, 70,175, 95,191,190,222,180,105,211, 56,123, 4, 75,165, 82,129, 16, 2,131,193, 0, +163,209, 8,189, 94,143, 43, 87,174,136, 47,190,248,226, 85,147,201,180,180, 60, 61, 43, 81,158, 85,201,117,219,106, 87,231,107, +105,227, 63,246,104,223, 42, 66, 79,148,205,243, 30,175,221,141,118, 27, 26,225, 3, 74, 65,197,162, 40,159,209,168,197,235, 83, + 39,243,127,231,169, 34,132,244,238,222,189,123,143, 57,115,230,220,179,109,206,156, 57,184,116,233, 82, 15, 66, 72, 66,121, 77, +162,101,225, 13,132, 41,130,130, 62, 3, 0,239,187,119, 39,229, 2, 73, 0, 48, 4,232,105, 3,250,237,220,185, 19, 0, 80,189, +122,117,136, 64, 3, 2,124,199, 3,107,173,101, 69, 5, 41,133,197, 98,133, 94,111,172,208, 88,217,255,119, 21, 92,182,215,245, + 60,207,163, 97,195,134,232,217,179, 39,164, 82, 41, 60, 60, 60, 28,205, 57,101, 69, 49, 92, 52,221, 83, 0, 34, 33, 4, 81, 81, + 81,232,209,163, 7,164, 82, 41,212,106,181,195,180,200,100, 50,240, 60,143, 70,237,186, 98,245,202, 57,120,174, 79, 51, 60, 27, + 23,136, 13,231,178,220, 74,103,132, 82,134, 26, 42, 57,162,163,163,225,225,225, 1, 66, 0,129,255,179, 62, 85,169,148,144,201, +101, 21,166,179,180,102, 90, 90, 26,226,227,227, 17, 31, 31, 15,142,227,208,190,125,123, 71,212,229,250,245,235,120,247,221,119, + 97, 52, 26,221, 58,118,142,227, 80,187,118,109,116,233,210, 5, 50,153, 12, 42,149,170, 68,211,160, 61, 79, 11, 10, 10, 80,171, + 86, 45,108,222,188, 25, 29, 58,116,112,169, 25, 29, 29,141,142, 29, 59, 66, 42,149, 58, 30,164,149, 74,165,227,190, 81,108,238, + 28,191,209,172, 89,179, 74,105,238, 56,126, 7,203,119,254, 14,163, 73, 68,190,206, 82,226, 11,193,254,158, 56,248,253, 52,183, +142,221,174,185,108,217, 50,228,230,230, 58,234, 32,123, 0,198, 30, 60, 9, 15, 15,199,162, 69,139, 30,173, 38, 66,251,109,193, +238, 42, 67, 67, 67, 97,239,231,161,209,104, 32,147,253,217,199,219,106,181, 98,195,134, 13, 8, 8, 8,112, 44, 94, 94, 94,229, + 22,232,234,213,171,131, 82,138, 9, 25, 69,221, 12,126, 11,145, 34, 1,192,227, 25,212, 17,221,177,217,108,248,233,167,159,224, +108, 96, 60, 60, 60, 42,108, 46,146,201,100,157, 90,180,104,193, 25,141,198,123,204,213, 7, 31,124,128,161, 67,135,162,110,221, +186, 16, 69, 17,133,133,133,232,220,185,179,100,193,130, 5,157, 42, 99,176, 84,170,162,254,252, 38,147, 9,123,247,238,133,143, +143, 15,252,252,252,224,235,235, 11, 15, 15, 15, 40, 20, 10, 16, 66, 92, 54,151, 81, 74, 49, 96,192, 0, 71,161,115,142, 90,149, + 54, 91,135, 15, 31,118,171,153,140, 82,138, 86,173, 90, 65,173, 86, 67,163,209, 64,163,209, 96,251,246,237,142,237, 45, 91,182, +132, 40,138, 8, 8, 8,192,145, 35, 71, 92, 86,186, 97, 97, 97,142,253, 37, 18, 9,249,233,167,159, 94,143,140,140, 12, 30, 59, +118, 44,199,243, 60, 78,157, 58,133,139, 23, 47, 34, 40, 40,200,209, 39,203, 85, 58,181, 90,109,234,130, 5, 11,108, 95,125,245, + 21, 0,160, 75,151, 46,200,203,203, 75,119,218,158, 53,124,248,112,199, 40, 69, 0,200,206,206,206,250, 15,248, 43, 88,205, 86, +232, 12, 6, 20, 22,232, 28,209,160,244,148, 52,239,105,175, 77,148,124, 50,110, 36, 0,224,181,121, 95,162, 96,201,159, 21,216, +198,215,134, 4, 60,241,233,218,233, 0,250, 87,164,175,211,233, 96, 52, 26, 81,163, 70, 13, 28, 63,126, 28, 5, 5, 5,232,214, +173, 91,137, 8,169,115,158,186, 56,247, 38, 66, 72,187, 62,125,250,252,241,249,231,159,215,172, 95,191, 62,209,106,181,208,233, +116,112,254, 60,119,238, 28, 93,179,102,205, 45,157, 78,215,150, 82,106, 42, 79,111,123,242,215, 55,122,134, 62,191,126,255, 89, + 89, 31,255,168,171,158,201, 57, 53,173, 89,201,114,109,190,254,138,193, 70, 47,130,218, 0, 27, 68, 80,171, 8, 27, 40,254,206, +241,219,132,144,176, 58,117,234,188,180,122,245,234, 50,243,139,231,121,172, 94,189, 26,237,219,183,127,137, 16,114,185,162,206, +253,118,218, 0, 50,131, 68, 50,109,235,143, 63, 22,245,229,234,210,101, 90, 27,139,229,181, 35,128,169, 65,163, 70, 79, 29, 62, +124,216,203, 94,175,120,121,121,129, 82,202,235,116, 58,175,182,109,219, 62, 85, 86,179, 43, 21, 1,139,197, 2,189,222,136,188, +188, 2,152,204,150,226, 58, 83,132,205,102, 45,254, 20, 97, 45,174, 71, 37, 2,239,209,169, 77,245,194, 34,163, 69,114,247, 29, +189, 19, 94, 78, 93, 79, 9, 33, 8, 12, 12,132, 84, 42, 45, 17,101,114, 39,122, 85, 6, 54,123, 93,232,231,231, 7,153, 76,134, +179,123,127, 70,250,165,131,144, 18, 10,209,102,129,104, 53,195,102, 53,131,231,120, 92,185,153,130,232, 96,151, 99,135, 28,233, +236,249,246,108,180,110,221, 26,235, 7,247, 3, 33,192,203,123,142, 66, 34,145,224,251, 1, 93, 33,151, 73,241,226,206,163,238, +166,179,196,177,159, 56,113, 2, 19, 38, 76,192,135, 31,126, 8,165, 82,105,111, 57,193,229,203,151,241,227,143, 63,162,123,247, +238,110, 31, 59, 33,196,113,236,130, 32, 96,250,244,233, 72, 73, 73,193,188,121,243,208,188,121,115, 72, 36, 18,228,230,230,162, +109,219,182, 72, 75, 75,115, 59, 63,237,205,120, 50,153,172, 68,180,201,110,252,170,114,142,236,154, 35, 7, 4, 99,203,161, 53, + 32, 32, 56,250,253,196, 18,247,162, 69,107, 15, 84, 90,115,198,140, 25, 37,210,249, 40, 70,175,202, 52, 88,148, 82, 26, 26, 26, + 10, 81, 20, 75,152,170,210, 29,106,237, 33, 63,231,144, 98,133,125, 16,120, 30,162, 40, 58, 10, 3, 95,198,246, 35, 71,142,220, + 99, 2,150, 47, 95, 94,225, 13,220,106,181,214,247,240,240, 40, 17,189,146, 74,165,152, 62,125, 58, 70,140, 24,225, 48, 87, 82, +169, 20, 43, 86,172, 64,108,108, 44, 76, 38, 83,253,138,210, 42,149, 74,117,141, 26, 53,226,236, 81, 32,165, 82, 73,134, 14, 29, +202, 91,173, 86, 71,158,216, 23,123,223, 52, 87, 38,195, 30,109,218,177, 99,135, 91, 17, 44,119,251, 32, 81, 74,113,230,204,153, + 18,166,205, 62, 10, 6, 0,206,156, 57,227,232,159,229,174,166,205,102,131, 82,169, 36, 82,169,148, 40, 20,138, 48,187,185,226, +121,222,113,190,157,251,228,185,186, 80,206,158, 61,219,185,162,237,231,206,157,251, 79, 78,199, 32, 66,132,217, 98,129, 94,103, + 66, 65,161, 30,179,222,255,182,104,195, 44, 28, 3,112,172,221,152, 9,120,185,103,247, 46, 0,170, 85,210, 16,192,126, 3,251, +233,167,159, 32,145, 72,176,121,243,102,120,122,122,162, 95,191,126,240,244,244,196,180,105,211, 48,120,240, 96,183, 35, 88,197, +101, 41,143, 16,210,238,213, 87, 95,253,227,227,143, 63,174, 30, 30, 30, 14,147,201, 4,179,217, 12,147,201,132, 27, 55,110, 96, +205,154, 53,137, 58,157,174, 29,165, 52,207,149,222,246,228,175,111,252,124,228,245,148,184, 39,159,212, 95, 78,251, 13,119,239, +102,193,106, 77,134,104,179,194,108, 45, 26,145,108,179, 90, 97,181,218, 32,240,156,231,162,207,167,236, 44,234,240, 79, 76, 3, + 7, 14,124,236, 33,158, 42,122,237,218,181,172,106,213,170,217, 43, 49, 79,147,201, 68,138, 31,224, 40, 0,123, 7,119, 45, 42, +232,136,238,204,113, 96,244, 39, 31,126, 24,102,111,190,127,255,195, 15,195, 38, 79,154, 52, 26,192,130, 75,231,206,173, 30, 57, +114,228,171,235,214,173, 43,241,157,145, 35, 71,226,210,185,115,171,203, 14, 17, 20, 71,176, 12, 6,100,100,229,224,133, 49,111, + 57, 66, 7, 0,133,179, 67,165, 69,255, 43, 0, 32, 51,237, 6,198, 79,120, 77, 94,222, 3, 85,131, 6, 13, 32,138, 98,137,104, + 72, 21,250, 94, 57, 71,134, 28,251,121,122,122, 66, 42,149,226,198,225,159, 49,105,204, 32,192,102, 6,181,232, 1,179, 14, 48, + 23, 66, 52,233, 64,164, 74,192,162,119,169,107, 79,167,167,167,103, 81,159, 80,129,135, 76,250,167,249,115,142, 92,185,115,227, + 46,125,236, 9, 9, 9,120,249,229,151, 97, 54,155, 49, 96,192, 0,152, 76, 38, 24, 12, 6,232,245,122, 68, 69, 69, 65,167,211, +185,125,236,246,123,167, 84, 42,197,196,137, 19, 17, 27, 27,139,119,223,125, 23, 83,167, 78, 69, 84, 84, 20,198,142, 29,139, 53, +107,214, 32, 38, 38,166, 66, 93,187,102, 81,147,123,145,166,253,120, 75, 55,229,217, 91, 10,220, 61, 71,101,105,218,103, 23, 41, +125,222,255,247, 76,215, 74,107,126,240,193, 7,200,200,200,184, 39,114,101,255, 59, 52, 52, 20, 11, 23, 46,124, 36, 35, 88,142, +225,164,246, 27,168,253, 70,238, 92,185,171, 84, 42,108,216,176,161, 68,231,186,138,194,210, 28,199, 65, 20, 69,108,171, 86,244, +253,222,197,145, 43,231,255,251,246,237,139,200,200,200, 18,209, 43,165, 82, 89, 97,161, 17, 69, 17,183,111,223,198,133, 11, 23, +208,186,117,107,228,229,229, 65,194,113,120,237,220, 57, 52,120,230, 25,152,164, 82,136,162, 8,153, 76,134,209,163, 71,187,213, + 81,253,143, 63,254,240,113,254,191, 65,131, 6, 73,113,113,113,161,199,143, 31,119,116,124, 47,110, 62,115, 24, 13, 55, 47,106, + 60,245,212, 83, 37,162, 86,206,230,202,121,249,237,183,223,220,106, 34,164,148, 34, 46, 46,206, 17,189,242,240,240,192,166, 77, +155, 28,219,237,225,231,192,192, 64,183, 52,237, 79,240,197, 29,219, 97, 52, 26,197,130,130, 2,238,228,201,147,144,201,100,142, +115,162, 84, 42,161, 80, 40,238,107,112,194,127, 30,155, 8,147,197, 2,189, 94,143,194,194,162, 25, 66,110,156, 47,217,143,217, +108,172,250,224, 52,123,148,170,160,160, 0,187,119,239,198,198,141, 27,209,188,121,243,123, 58,185, 59, 95,183,110,148,209, 12, + 66, 72,251, 41, 83,166, 28,125,239,189,247, 66,124,125,125, 97, 54,155,113,231,206, 29,124,243,205, 55, 41, 58,157,174, 61,165, + 52,163, 18,174, 13, 22,139, 21, 6,157, 17,121,249, 5,152, 57,103, 69,185, 85, 4, 0,100,167, 95,193,208,161,195,100, 15,243, + 52, 81, 74,147, 1, 60,239,116, 93,173, 2, 96, 15,199,231, 83, 74, 71, 84, 70, 79, 2,116,122,114,224,192, 46, 19, 39, 78,116, +172,155, 56,113, 34,142, 30, 61,218, 69,178,126,253, 5, 11,176,151, 95,191, 62,230,243,207, 63,119,236,243,249,231,159, 99,195, +250,245,123,108,192,222,242,234, 14,123, 19, 97, 97,161, 30,158,222,193, 72,142,223,231, 50, 45, 82,222, 0, 42,138, 46, 31,252, + 74,247,187, 41, 93, 63, 85,162,252,208, 70,141, 26,217, 91, 23, 32,149, 74,209,176,203, 64,124, 58,127, 41,228, 28,197,147,221, + 26,162,154,194, 6, 40,125, 33,237, 48, 13,196,187, 70,241, 67, 71, 83,183, 30, 80,247,191, 53, 25,183,212, 10,188,184,227, 32, +164, 82, 41,126, 26,220, 27,114,185, 20,207,254,188, 31, 82,169, 20, 63,143,122, 2, 82,153, 20, 61, 23,255,232,214,131,138,253, +216,111,220,184,129,195,135, 15, 35, 58, 58, 26,215,175, 95,135,115, 63, 91, 74,169,219,166,173, 97,195,134,142,128,132, 68, 34, +193,221,187,119,209,167, 79, 31,199, 3,254,190,125,251, 48,101,202, 20,140, 26, 53, 10,157, 58,117, 42,179, 95,108,105,205,152, +152, 24, 71,224,160,180, 9,118,110,182,173,204, 57, 42, 75,211, 81,126,171,120,222,157, 53,223,123,239,189, 50,205,122,101, 52, +255,211, 6,203,126,129,148,215,238,172, 86,171,241,202, 43,175, 96,198,140, 25,240,247,247,119,217,119,198,238, 92, 43, 98,235, +214,173,247,172,219,188,121,179,171, 38,194,203, 94, 94, 94,177,157, 59,119, 70, 94, 94, 30, 18, 19, 19,161, 86,171,209,224,211, + 79,113,238,229,151,209,100,241, 98,112, 93,186,128, 16, 2,153, 76,134,115,231,206, 65,169, 84, 94,174,108,196,192,195,195, 3, + 62, 62, 62,142, 54,117,187,209,114, 50, 88,212, 29, 51,180,109,219,182, 50, 71,232, 84,165, 15,150,189,226, 61,122,244,104,137, +254, 87,206,205, 28, 71,143, 30,117, 68,176,138,247, 39,174,206, 83,241, 83, 29,181,235,169, 84, 42,248,250,250, 66, 46,151, 59, +140,149,221, 92,185, 99, 46, 93, 77, 36, 26, 17, 17, 81, 98, 34, 82,137, 68, 82, 98, 34,210,127,123, 19,161, 94,111, 64, 97,129, +254, 65, 54,105, 21,153,179,226, 1, 39, 27, 54,108, 64,171, 86,173,238, 49, 87,246,168, 99, 21, 12, 71, 18, 33,164,211,252,249, +243,143,125,246,217,103, 62,133,133,133,248,246,219,111,243, 10, 11, 11, 59, 81, 74,147, 42,165, 5,192, 98, 54, 67,103, 48, 66, + 91, 88,148, 7, 55, 47,252,228,210,148,253,155,169,223,168,209,240,111,191,253,246,158,245,223,126,251, 45,174, 95,191, 62, 28, +231,206,237,109, 9, 44,121,125,218,180,218,205,155, 55, 15, 3,128,215,167, 77, 75,106, 9, 44,169,232, 58, 55, 23, 55, 17, 22, + 22, 22, 69, 61, 12,218,204, 7, 83, 78,139, 77, 70,121,125,174,170,114, 67,180,215,183, 82,169, 20, 61, 6,191,128,148, 91, 87, + 16,173,206, 68, 53,111, 21,104,126, 50,164, 93,222,193,185,108, 21,230, 45,222, 94,169,116,170,229, 50, 40, 20,114,167, 62, 87, + 10,200, 20,114, 71, 58, 21, 74, 37, 36,114, 89,165,143,253,234,213,171, 80, 42,149,176,217,108,247,220,111, 42,123,252,206,198, +229,243,207, 63,199,148, 41, 83,176, 98,197, 10,156, 59,119, 14, 77,154, 52, 65,183,110,221,144,158,158,142,179,103,207,194,104, + 52,186,157, 78,231,126,113, 23, 47, 94,196,175,191,254,138,248,248,120, 36, 38, 38, 86,249,188, 59,107,150, 54, 88, 27,118,157, +198, 83,221,155, 85, 73,115,230,204,153, 72, 79, 79, 47, 17,185,114,142,110, 62,210, 17, 44,123, 19,147,211, 77,249,158, 40,149, + 90,173,118,116,136,244,244,244,116, 25, 25,178, 27,172,184, 91, 5, 37,250,114,217, 35, 89, 0, 48,106,212,168,123, 34, 88,165, + 39,167, 43,141,209,104,220,183,111,223,190,166,125,251,246,229, 47, 95,190,236,104,138, 52,181,105,131, 38,139, 23,227,252,196, +137,232,152,144, 0,131,217, 12,133, 66,129,237,219,183,155,117, 58,221,190, 74, 86, 22,196,217, 96,169,213,106,120,121,121, 57, + 12, 70,101, 92,121,121, 79,136,206,255, 87, 38, 34,100,239,115,102, 95,236, 55, 86, 66, 8,244,122,189,163,179,102,101,162, 34, + 54,155,205,113,225,217, 59, 40,122,123,123, 59, 42, 13,251,104, 50,119,155, 71, 93, 77, 36,170, 80, 40, 60, 15, 28, 56, 80,203, + 62,141, 68,102,102, 38, 6, 15, 30,124,237,223,126,113, 81, 80,152,173, 54, 20,234, 13, 40,212,235, 30,184,254,234,213,171,113, +227,198, 13,152,205,102,188,255,254,251,247, 24,171,202,116,114, 47,163, 92,221,104,214,172,153,216,171, 87, 47, 28, 61,122, 20, +114,185,220, 66, 41,173,244,252, 85, 84, 20, 97,182, 90, 97,208,235, 81,168,213, 62, 18, 79,173, 23,207,157,251, 73,173, 86, 15, + 6,160,201,205,205,229,189,188,188,160, 82,169,160,215,235,243,248,226,145,130, 71, 0,147,183,197,242,225,160, 65,131, 62, 3, + 0,133,197,242,225, 17,192, 84,209,117,110,177, 22,155,245, 7,152,143,246,122,171,188, 58,169, 42,209,105,251,141, 84, 42,149, + 66,224,121,124, 59,119, 50,162,213, 25,104, 22,233, 1, 99,218,117,200, 60,252, 65,188, 35, 48,111,241,118, 92, 74,200,174, 84, + 58,135,172, 92,143,240,240,112,108,121,166, 31, 20,114, 5,134,108,216, 13,137, 68,130, 29, 99, 7, 67, 42,147,161,219, 87,223, + 87,233,216,181, 90,109,185,145, 42,119, 35, 88,165,143, 93, 34,145,160,105,211,166,168, 83,167, 14,246,238,221,139,102,205,154, +225,250,245,235,184,126,253, 58, 18, 18, 18,112,238,220, 57,228,228,228, 84,250, 28,173, 93,187, 22,217,217,217,144,201,100,200, +204,204, 68,124,124,188, 91, 83,177,184, 58,239,118,234, 61, 62, 19, 0, 16, 82,205,171, 82, 6,203, 89,243,163,143, 62,186,199, +180, 63,138, 45, 29, 66, 57, 38, 64, 95,175, 94, 61,165,115,251, 41,199,113,240,240,240, 32, 83,166, 76,225,139,255,134,151,151, + 23,170, 85,171,230, 86,179,155, 68, 34,209,183,108,217, 82,105, 47,128,118,227,164, 86,171,249,169, 83,167,146,229,203,151,151, + 27,213,114,209, 7,235,179, 17, 35, 70, 60,159,148,148,228, 19, 16, 16,128,212,212, 84,200,100,178,162,139,162,115,103,196,221, +186, 5,115, 81,159, 34, 92,189,122, 21, 75,151, 46,213, 26,141,198,207, 42,155, 81, 26,141, 6,126,126,126,142,166, 65,123, 4, +199,201, 44,210,170, 84,100,165,151,202, 68, 28,236,154,206, 6,203,126, 99, 29, 51,102, 76, 9,179,229,118,129, 16, 4,107,199, +142, 29, 5,123, 58, 44, 22, 11, 26, 53,106,132,244,244,116, 72, 36, 18,200,100,178, 18,145, 59,119, 12,150,171,137, 68, 5, 65, +128,201,100, 66,135, 14, 29, 64, 8,193,151, 95,126, 89,165,200,203, 63,206, 96, 89, 69,162,209,248, 33, 36,164, 46,170, 5, 24, + 32,138, 15,238,237, 47, 86,171, 21, 99,199,142, 45, 17,177,178,143, 84,180, 55,241, 23, 53, 43, 89,170, 60,105,171,253,186,190, +159,249,223, 68, 10, 71,211,150, 86,107,248,215,157,195, 26, 53,106,120, 22, 55, 25,150,230, 7, 74,233,175,101,158,155,226, 41, + 25,120, 96,246,157, 59,119, 26,122,121,121,161, 71,143, 30,216,186,105,211,150, 31, 0, 71,200, 38, 23, 72,242,185,123,119, 98, +241,223,201,174,130,122, 69,125,176,140,208,106,245, 15,252, 56,239,247, 65,175,172, 7,106,158,231,177, 97,241, 7,136, 86,165, +161,105,117, 57, 14, 31, 61,141, 86,225, 0, 76, 85,111, 1,182,247,109, 82,169,148,144,202,228,142,116, 42, 84, 42, 72,164,178, + 42, 31,187,115,125, 90,186,190,172, 74, 4,207, 57, 63, 95,120,225, 5, 76,155, 54, 13, 61,122,244,192,245,235,215,177,127,255, +126, 92,191,126, 29, 19, 38, 76, 64, 76, 76, 12,122,246,236, 89, 41,205,245,235,215, 35, 47, 47, 15, 28,199, 33, 43, 43, 11,122, +189, 30, 51,102,204,184,239,243,110, 39,126,215,251, 0,128,159,118,158,170,178,230,155,111,190,137,187,119,239,150,136, 92, 61, + 42, 81, 43,151, 6,235,234,213,171,101,182,247,197,196,196,164,117,239,222, 61, 32, 53, 53, 21, 26,141,198,165,185, 34,132,116, +179,207,149,113,225,194,133, 50, 53,107,214,172,105,238,222,189,187, 36, 56, 56,184,196,232, 65,181, 90, 93,226, 98, 45, 75,179, +184,242, 47, 32,132,188,212,174, 93,187,239,126,251,237, 55, 85,157, 58,117,144,159,159, 15, 74, 41, 86,172, 88,129,113,227,198, + 65,161, 80,224,234,213,171,232,215,175,159, 78,167,211,189,228, 60, 7, 86, 89,154,101, 25, 25,142,227, 28,243,195,148, 97,174, + 42, 60,118,103,230,207,159,239,152, 11,170, 34,150, 44, 89, 2,148,154, 82,161, 44, 77, 74, 41, 62,249,228,147, 7,166,121,229, +202,149, 21,206,219, 35, 35, 35,191,124,236,177,199,132,196,196,196, 18,166,202,121, 41,163, 66, 42,161,233,106, 34, 81,158,231, + 17, 24, 24,136,247,222,123, 15,126,126,126, 8, 10, 10,186, 39,242,226,234, 28, 85,241,233,253, 47,213,164, 28, 61, 57,255,179, +153,237,151,124,189, 81, 34,151, 1, 71,246,255,132,252,156,187, 37, 35,176,230, 63,135, 68,203,154,117,133,233,212,110,183,210, +105, 52, 26,241,209, 71, 31, 97,230,204,153,247,204,129, 83,206,121,191,175, 99,119,199,100,149,165, 41,138, 34, 81,169,125,160, + 80,135,160, 65,140, 15, 68, 55,230,234, 20,255,254,243,174, 75, 76, 76,244, 10, 15, 15,199,181,107,215, 8,254,236,143,245,231, +185,146,201,134, 0,248,181, 34, 77, 2,156, 91,179,102, 77,195, 70,141, 26,225,203, 47,191, 4,128,103,159,219,177, 99,240,211, +122,189, 1, 40,154,124,180,216,140,185, 76,167,141, 82,162, 84,121, 67,161, 14, 70,131,134,222, 16, 69,247,231, 60,165, 21, 28, +187,253,230, 87, 58,122, 85,201,137,164,239,209,180, 63, 32,221, 60,242, 11,250,244, 14,195,161, 99,231,177, 59, 81,133, 48, 89, + 42, 66,116, 25, 16, 51, 46,227,213,129,205, 48,111,125,209, 77,252,252, 73,215,154,132, 16, 28,122,237, 69,168, 85, 10, 60,185, +230, 87, 72,165, 82,252,254,234, 51,144, 74,229,232,248, 89, 81,147,236,185, 15,167, 67, 34,151, 35,250,127, 51,221, 74,103,233, +150, 26,123, 87, 14,231,125, 42,138, 96, 85,116,236, 5, 5, 5,200,205,205,197,119,223,125,135,145, 35, 71, 34, 61, 61, 29, 9, + 9, 9,184,118,237, 26,126,248,225, 7,199,232,244,202,164,211,110, 94, 38, 77,154, 4, 74, 41, 26, 52,104,128,153, 51,103,162, + 77,155, 54,149, 62, 71,165,207,123,105, 92, 69,175, 42,210,156, 55,111, 94,149,202,210, 35, 97,176, 42,122, 42,225, 56, 14,254, +254,254,142,194,225, 92,240,170,242,164,203,243, 60,172, 86,171,163,227,180,125, 1,128,190,125,251, 98,235,214,173,238,140,140, +248,141, 16, 50,188,126,253,250,223,204,154, 53, 75,211,177, 99, 71, 33, 36, 36, 4, 45, 90,180,192,213,171, 87,241,203, 47,191, + 88, 22, 46, 92,168,213,233,116,163, 40,165, 59,171, 82, 39,219, 95, 61,227,188, 84, 6,155,205,150, 24, 31, 31, 31,252,201, 39, +159,240, 28,199, 97,222,188,121,206, 47,185,190,167, 16, 30, 61,122,212,234,170, 73,198,106,181, 38,198,199,199, 7,127,250,233, +167, 60, 33,196,161,233, 60,249,171,115,222,185,163, 89,150,185,180, 15,120, 40,107, 41, 43,237,101,157,227,138, 38, 18, 21, 4, + 1, 87,175, 94,197,140, 25, 51, 64, 8,193, 79, 63,253,244,159,184,184, 14, 29, 79, 89,222, 54, 54,196,103,200,192, 78,141, 8, + 56,152,204,247, 14, 64,227,179,114, 29,230,234,137, 79,215, 98,227,107,131,221, 49, 59, 55,142, 31, 63,238,251,209, 71, 31, 9, + 60,207,227,243,207, 63, 47, 49,217,111,233,243,126,236,216, 49,107,149,154,247,138,175,103,179,217, 12,189,190,106, 81, 19,202, +145,195,243, 62,122,167,251,146,111,183, 74, 8, 49,225,200,190,159,144,151, 91,246,208,116,153, 68,192,170, 53, 91,172, 2,207, + 37,254,205,167,110, 73,183,110,221,102,236,218,181, 75, 8, 15, 15,175,178, 72,123, 96,235,130, 5, 11, 30,123,230,153,103,124, +235,215,175,143,141, 27, 55, 2,128,172,120, 65,241,204,238,191,185,103,146,196,205,159,127,252,206,179, 75,191,221, 42,227,136, + 25, 71,246,255,132,188, 82,102,189, 52, 82,169, 4,171,215,108, 54, 11, 2,127,197, 85,189,238, 28,189,186,223, 27,162,115,217, +107,214,231,121,124,249,203, 82, 4, 52,234,133, 65,125,227,112,240,203,103, 48, 40,218, 0,243,186, 97,104, 56,112, 37, 86,188, + 94, 20,189,105,186,254, 13,183,238, 63, 30, 30,106, 71, 7,114,142,227, 32, 87,168, 32,145,255,217,127, 72,166, 82, 65,168, 68, + 36,203,126,236, 21, 69,170, 42, 27,193,226, 56, 14,145,145,145,168, 89,179, 38,218,181,107,135,102,205,154,161,115,231,206, 56, +123,246, 44,206,158, 61,139, 9, 19, 38,148,107,174,220, 57, 71,221,187,119,199,149, 43, 87,238,187,144,151, 62,239, 15, 2,119, +202,210,203, 47,191, 12, 0,143,110, 31, 44, 87,153,103, 47,144,244, 1,116, 70, 37,132,192,100, 50, 57,154,222,156,231, 85,178, +119,122,119,115, 62,168,157,132,144,152,183,223,126,123,162, 66,161,232,172,211,233,234, 2,128, 90,173,190,106, 52, 26,127,215, +235,245,159, 83, 74,115,239, 39,173,206,211, 50,148,113, 28, 21,102, 70, 70, 70, 70,207, 17, 35, 70,236,228, 56, 46,178,162,151, +243, 58, 61,249, 39,164,165,165, 61,230, 74,115,248,240,225,101,106,150,165,235,142,102, 89,231, 92, 20,197,114,205,149, 59, 21, +144,171,137, 68, 37, 18, 9,212,106, 53, 54,109,218, 4,127,127,255,255,212, 5,118,248, 68,202, 71, 21,109,239,228, 47,223, 7, +160,218, 19,159,174,189,179, 55,211, 84,163,147,191,236,246,198,215, 6, 87,175,232, 59, 57, 57, 57, 61, 38, 77,154,244,171, 32, + 8,145, 21,157,111, 39, 35, 30,159,145,145, 81,233,105, 15, 40,165,184,114,229,138,248,194, 11, 47,100,102,100,100, 60, 93,149, +227, 31, 63,241,227,207, 22,124,242,170,223,192,254,237, 91,128, 16,152, 76,229,116,234, 37,160,148, 82, 42,240, 92,226, 43,147, + 62,125,241,239, 60,103,148,210, 51,132,144,119,107,213,170, 53, 26, 64,121,119,194, 31, 92,233,236, 5,204, 50,163,241,147,216, +216,216,169,111,188,241,134,119,223,190,125, 17, 30, 30, 94,238,124,129, 21,113,240, 88,210,232, 54,177,193, 97, 79,245,107,223, +147, 35,132, 26, 77, 70, 23,245,106,113,126, 10,252,149,125, 71, 19, 27,187,138,206,115, 28, 87,233, 46, 10,238,208,117,224, 72, +116, 29, 56,210, 81,158,118,173,235,132,147, 41, 59,209,156, 75,130,113,105,123, 16, 79,123, 81,231, 93,222, 39, 56,142, 67,191, + 21,155, 75,164,179,221,135, 37,163,179,117,199,189, 93,169,123,143,243,224,171, 7,213, 7,139,231,121,100,102,102,226,234,213, +171, 72, 75, 75,131, 78,167,195,165, 75,151, 96, 54,155,145,147,147, 3,251, 72,195,170,164,243, 65,157,163,191, 83,243, 81,106, + 38,172,148,193,178,217,108, 73,174,222,122,110,181, 90, 43, 53,202, 72, 16, 4, 67,251,246,237, 73, 89,163, 13,236,127, 43,149, + 74,189,155, 21, 99, 46,128, 25, 0,102, 20,191,111, 10,217,217,217,247,237, 2,109, 54, 91, 74,203,150, 45,249,138, 12,145,205, +102, 75,115, 97,134,180, 0,218, 60,200,147,247, 87,104,150,113,126,180, 29, 59,118,188,103, 30, 19,231,243,163, 80, 40, 42,236, +117,235,106, 34, 81,157, 78,151, 58, 98,196, 8,155,115,179,160,243, 68,164,255,105, 8,189,221,123,200,243, 53,246,102,154,106, + 0,128,221,100,129,210,219,229,125, 37, 37, 37, 69, 15,160,227, 95,157,180, 91,183,110,153, 90,181,106,181,186,160,160,224,101, + 74,105,149,123,233, 79,152, 60,239,141,127,219,105,161,148,158, 1, 48,230,126,117, 76,192,229, 6, 6,195,203, 51,223,126,251, +201,119,222,126,187,142, 8,248, 1, 69,115, 84,241,192,218,202,104, 29, 57,145,250,192,231, 6,179,217,108, 73,109,219,182,173, + 84,164,198, 85, 29,111,181, 90, 43,188, 79,172, 65, 56,112,162,114,154,127, 69, 58,157, 53,155, 52,105,130,166, 77,155, 58, 62, +237,148, 94,239,142,102,243,230,205,209,160, 65,131,114,103,104, 47,221,231,234,239, 62,118,187,166,221,246, 55,109,186,227,129, +105,222,111, 58, 31, 41,131,101,127,199,224,131,228,226,197,139,127,201,187, 81, 40,125,112, 99,189, 47, 94,188,216, 2,143, 40, + 87,174, 92,241,187, 95, 13, 87, 19,137,158, 59,119,174,243,163,154,191,123, 51, 76,207,221,179,174,216,108,253,221,104,181,218, +234,148,210, 42,245,204, 31, 56,112,160,237, 81, 61,167,160,180,196,196, 83, 23,139, 38, 40,253,238,159,152,212, 11, 23, 46, 60, +240, 58,253,175,184, 79,252, 21,233,100,199,254,207,215,252,183,195,102,136,100, 48, 24,229, 61,164,216, 88, 46, 48, 24, 12, 70, +213, 32, 0,186,149, 83,185,186, 61,114,135, 16,210,173, 10,149,247, 46,166,201, 52,153, 38,211,100,154, 76,147,105, 62, 90,154, +174,180, 31,244,200,225,191,243, 41,245, 47, 91, 0,116, 99,154, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,212, 22,214, 68, +200, 96, 48, 24, 12, 6,131,241,128, 97, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, + 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 84, 29,242, 0,231,227,100, 48, 24, 12, 6,131,193, 96,128, 69,176, + 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, + 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, +248, 39, 24, 44, 66, 72, 55,166,201, 52,153, 38,211,100,154, 76,147,105, 50, 77,102,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, + 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, + 96, 48, 24,140,191, 9, 2,160,204,145, 0,148,210, 93,110,139, 84, 97, 52,129, 43,125,166,201, 52,153, 38,211,100,154, 76,147, +105,254,247, 52, 93,105, 87,198,127,252,163,161,148,254,101, 11,128,110, 76,147,105, 50, 77,166,201, 52,153, 38,211,100,154,143, +218,194,154, 8, 25,174,158, 48, 4, 66,136, 80,213,237, 15, 75,147,193, 96, 48, 24,140,127, 18,236, 38,198,168,200, 8,181, 1, +208,167,248,239,159, 41,165, 71, 42,179,253, 97,105, 62, 44,154, 55,111,174, 84, 40, 20, 61,246,236,217, 35,187,116,233, 18,254, +248,227, 15,186,122,245,106,179,193, 96,216,113,242,228, 73, 61, 43, 49,255,126,154, 53,107,214, 19,192,244,226,127, 63, 56,117, +234,212,246,251,188,134, 72,173, 90,181, 38,200,100,178,222, 82,169, 52,196,106,181, 18,163,209,152,162,215,235,119, 38, 39, 39, +127, 74, 41, 21,171,160,217,194,223,223,127, 76, 76, 76, 76,157, 91,183,110, 37,222,185,115,103, 21,128,237, 0,122, 86,175, 94, +125, 68, 84, 84, 84,248,133, 11, 23,174,101,102,102, 46,166,148,254,241,119,165,147,193, 96, 6,203,189,139,143,243,241,241,233, +174, 84, 42,255, 87, 88, 88,216,212,211,211,243,162,213,106, 93,144,154,154,250, 51,187,240,254,179,230, 74, 0,208,135, 82, 42, + 1, 0,158,231,251,183,105,211,166, 6, 33, 68, 36,132, 80, 74, 41,225, 56,174,169,205,102,227,138,247,239, 67, 8,249,131, 82, +106,173,140,102,171, 86,173,194, 5, 65,160,148, 82, 66, 41,229, 56,142,107, 92, 25,205, 7, 69, 76, 76,204, 92, 74,105, 72, 69, +251,168,213,234,216, 61,123,246,212,219,188,121,179,109,213,170, 85,185, 67,134, 12,209,140, 28, 57, 82,248,246,219,111,191, 2, +240,191,210,251, 55,104,208,224, 51,142,227,252,221,249,125, 81, 20, 51, 47, 94,188, 56,137,149,188,191,157,233, 47,124,184,175, + 3,165,192,215,211, 59,114,197,198,165,202, 52,109,218,244,187, 1, 3, 6, 12,169, 91,183,174, 32,138, 34, 44, 22, 11, 76, 38, + 83,189, 83,167, 78,117,218,177, 99, 71, 44,128,167, 43,121, 93,246,153, 62,125,250,178,119,223,125,183,154, 68, 34, 33, 22,139, +165,245,143, 63,254,216,107,204,152, 49,103, 22, 47, 94,220,100,208,160, 65, 30,246,245,239,188,243,206, 99,132,144,137,148,210, + 31, 30,118, 58, 25, 12,134, 11,131,229,225,225, 81,187, 90,181,106,175,249,249,249, 61, 22, 27, 27,155,247,210, 75, 47,221,188, +113,227,198,249,200,200, 72,221,183,223,126, 59,199, 98,177, 44,172, 91,183,238,142,252,252,252, 79,239,222,189,123,169,146, 21, + 69,109, 0, 47, 1,120, 12, 64, 24,128, 20, 0,191, 2, 88, 70, 41,189, 82,149,131, 9, 13, 13,109,164, 86,171,167, 18, 66, 90, +107,181,218, 48,181, 90,157, 66, 41, 61, 86, 80, 80,240,113,106,106,234,169,170,104,134,133,133,213, 4, 48, 94, 16,132, 56,155, +205, 22,201,243,252,109,155,205,118,192,102,179,125,153,146,146,114,173, 42,154,237,194, 61,250,138, 26,207, 79, 45,188, 50,188, +208, 96,149,106,228,130, 69, 34, 26, 18, 69,109,238,244, 99,119, 10,127,250, 39, 22, 20,153, 76,198,173, 90,181,170,137, 76, 38, + 3, 0,152, 76, 38,196,196,196,144,251,209,148, 72, 36,220,167,159,126,218, 76, 16, 4,152,205,102,177,160,160,128, 62,249,228, +147,127, 75,179, 53, 33, 36,236,228,201,147, 94, 82,169,180,204,237, 54,155, 13,253,250,245,139,148, 74,165, 88,180,104,145, 37, + 43, 43,171,233,242,229,203, 79, 45, 92,184,208,127,197,138, 21, 3,203, 50, 88, 28,199,249,151,167,105,179,217, 96, 54,155, 97, +181, 90, 97, 50,153,208,185,115,103, 86, 27,253, 51,168, 1, 0,219,206, 26, 0,192,247,126,197,148, 74,101,244, 19, 79, 60, 33, +100,100,100, 64, 34,145,192,108, 54,227,238,221,187,168, 85,171, 22,191,121,243,230,186,149,213,171, 87,175,222,152,247,223,127, + 63, 96,219,182,109,230,213,171, 87, 27,187,117,235, 38, 29, 53,106,148,103,135, 14, 29,226,194,194,194,184,111,190,249,198,184, +107,215, 46,243,240,225,195,229,115,231,206, 13,248,245,215, 95,135, 0,248,225, 97,167,147,193, 96, 84, 96,176, 60, 60, 60,246, +105, 52,154, 90, 47,190,248,226,149,151, 95,126,121,135, 70,163,177, 1,192,247,223,127, 47,244,239,223, 63,227,201, 39,159, 76, +215,233,116,252,194,133, 11,171,127,241,197, 23, 59, 61, 60, 60,146, 11, 10, 10, 90,186,113, 35, 35, 0,254,199,113,220,248, 30, + 61,122,236,179, 88, 44, 25, 91,182,108, 89,247,196, 19, 79,196, 81, 74,213,123,246,236,249,133, 16,178, 4,192, 39,238, 70,199, + 8, 33,124, 84, 84,212,204,176,176,176,201,139, 22, 45,146, 71, 69, 69, 65,169, 84,162,160,160,160,250,181,107,215,194,255,247, +191,255,245,171, 89,179,230, 2, 47, 47,175,183, 78,158, 60,105,113, 83,147,132,132,132,188,234,233,233,249,222,220,185,115, 21, +245,235,215, 39,106,181, 26,241,241,241, 13,143, 30, 61, 26,179,124,249,242, 81, 97, 97, 97,179,146,147,147,221, 78,103, 39, 66, + 4, 67,205,106, 59,124,234,181,236,180,120,217,215,196, 95,173,130, 64, 8, 44,102,179, 36, 77,167,143, 26, 55,118,244,186, 54, +117,130, 14, 21, 72,210,186, 94,188, 72,205,127,147,209,144, 3, 0,165,212, 72, 8,249,153,231,249,254, 50,153,140,235,223,191, + 63,118,237,218, 69, 12, 6,131, 0, 0, 10,133,194,218,191,127,127, 40,149, 74,152, 76, 38, 17,192,207,229, 69,154,202,210,148, + 72, 36, 92,231,206,157,117,199,143, 31,207,182,107,170, 84, 42, 75,231,206,157,253,100, 50,153,210,106,181,210,138, 52,255, 34, + 19,137, 27, 55,110,148, 88, 87, 80, 80,128,140,140, 12,100,101,101,193,100, 50, 33, 55, 55, 23,162, 40, 18,163,209,152, 33,138, + 34, 56,174, 40,216, 86,158,166, 84, 42,197,213,171, 87, 75,172,179, 90,173,208,106,181, 48, 26,141, 48,155,205,208,235,245, 74, +133, 66, 81, 59, 46, 46, 46, 9,192,230,194,194,194, 79,207,156, 57,115,155, 85, 79,127, 11,119,126, 62,109,168, 14,192, 4, 32, +254, 1, 92, 79, 34, 0, 28, 56,112, 0,105,105,105,200,204,204, 68, 70, 70, 6,194,194,194, 80,149,232,255,149, 43, 87,230, 55, +109,218,148,156, 57,115,102, 43,128,101,107,215,174,125, 34, 59, 59,123,209,148, 41, 83,124, 63,254,248,227,236,169, 83,167,142, + 5,176,113,237,218,181, 35, 27, 53,106,212,247,220,185,115,243,254,142,116, 50, 24,140, 10,230,193,162,148,134,212,174, 93, 59, +251,243,207, 63,175, 55,125,250,116,191,194,194, 66,190, 56, 74,100, 32,132, 80,157, 78,199, 79,155, 54,173,218, 7, 31,124, 80, + 79, 46,151,231, 88,173,214,106,101,104,148, 53,212,114,188,167,167,103,191,248,248,248,181,245,234,213,243,125,255,253,247, 79, + 43,149, 74, 58,127,254,252,147, 53,107,214, 12,190,125,251,246, 74, 79, 79,207, 46, 0, 38,151,147,174,123, 52, 35, 35, 35,223, + 27, 56,112,224,228, 67,135, 14,201, 27, 55,110, 12,141, 70, 3,158,231,225,237,237,141, 86,173, 90,145,253,251,247,203,123,247, +238, 61, 33, 47, 47,239, 99,119, 53, 67, 66, 66,222,232,213,171,215,156,147, 39, 79, 42,187,118,237, 74,100, 50, 25,114,114,114, + 32,151,203,209,186,117,107,178,120,225, 87,202,134, 13,234,191, 19, 22, 22,246,174,187,154,230,218,254, 59,135,188, 50,173,243, +207,191,110, 39,129,129,129,184,249,201,187, 56,208, 33, 6,215,103, 79, 71,112,112, 48,182,110,251,141,244,125,246,149,246,158, +150,192, 61,238,106,222, 47,206,154,132,144,151, 1,100, 3,200, 38,132,188, 76, 41, 61, 18, 19, 19,115,242,210,165, 75,136,139, +139,195,186,117,235, 26, 79,153, 50,229,229, 41, 83,166,188,188,110,221,186,198,113,113,113,184,116,233, 18, 98, 98, 98, 78, 58, +247,149,114, 71,115,223,190,125,232,210,165, 75,206,186,117,235,162,102,204,152, 49,119,198,140, 25,115,215,174, 93, 91,179, 75, +151, 46, 57,243,230,205, 51, 86,164,249, 87, 28,187,115,100,201,121, 17,197, 63,239, 45, 1, 1, 1,233, 63,255,252, 51,250,246, +237,203, 5, 6, 6,166,246,239,223, 95,126,252,248,113, 10,224,231,202,164,211, 96, 48, 64,175,215, 67,171,213,226,206,157, 59, +202,133, 11, 23,182,159, 60,121,114,173,117,235,214,133, 78,152, 48, 97,172,167,167,231,169, 38, 77,154,212,120,216,199,206, 52, + 1,142,227,238, 2, 48, 3,208,114, 28,119,251,126, 52,159,122,234,169,134, 17, 17, 17,129, 63, 94,240, 65,142,180, 30, 68,169, + 55, 68,169, 55,108,126, 45,112, 67,246, 24, 66, 67, 67, 3,107,212,168,209,166, 50,154,148,210,157,167, 79,159,126,140, 82,186, +152, 82,106,163,148,174,159, 58,117,234, 11,132,144,159,166, 78,157, 58,154, 82,186,190,120,253,242,179,103,207,246,165,148,254, +254,119,164,147,149, 37,166,201,168,192, 96, 17, 66, 44, 31,125,244,209,209,175,191,254,122, 87,106,106,106,112, 84, 84,212,227, + 79, 60,241, 68,141,188,188, 60,242,196, 19, 79, 68, 6, 7, 7,247,217,183,111, 95,208,192,129, 3,247, 12, 28, 56,240, 8, 33, +196,101,164,129, 16, 82,147,231,249,137,103,206,156, 57, 88,189,122,117,115, 74, 74,138, 71,211,166, 77, 11, 0,160, 78,157, 58, +186,172,172, 44,165,151,151, 23,126,251,237,183,227,132,144,151, 8, 33,245, 92,105, 6, 7, 7, 55,243,243,243,251,223,123,239, +189, 39,231,121,190,204,125,228,114, 57,222,123,239, 61,185,167,167,231,139,161,161,161,173, 93,105, 6, 5, 5,213,247,240,240, +120,243,139, 47,190, 80, 24,141, 70,152, 76, 38, 4, 6, 6, 66,163,209, 32, 53, 37, 5, 41, 9,241, 72,139,191,133, 9, 47, 60, +175, 84, 43,149, 19, 67, 66, 66,154,184,210,140,139,240,232,175, 14,107,208,105,220,248,255,225,194,132,145,216, 21, 42, 67,208, +248,105,104,188,247, 60,194,102,125,138,223,163, 60,113,242,233,238,120,245,213, 73,144, 6, 68,181,109, 27,174, 25,252, 55, 68, +174, 62,166,148, 42, 41,165, 74, 66,200,252,182,109,219,174, 86, 42,149, 47,191,255,254,251, 61,119,236,216,209,107,255,254,253, +157,172, 86,171,196,106,181, 74, 14, 28, 56, 16,103, 48, 24, 4,185, 92, 14, 65, 16,168,187,154,109,218,180,249, 78,169, 84,142, + 93,180,104, 81,207,223,127,255,125,196,137, 19, 39, 94,177,217,108, 50,155,205, 38, 59,113,226,196,104,189, 94, 47,161,148,218, +202,211,124,216, 72, 36, 18, 72,165, 82, 40,149, 74, 52,109,218,244,230,154, 53,107, 44,193,193,193,146,101,203,150,249, 4, 6, + 6,170, 87,172, 88,145,155,155,155,251,161,187,122,102,179, 25, 70,163, 17,122,189, 30, 6,131, 1,135, 15, 31,142, 28, 53,106, +148, 96, 50,153,108, 35, 70,140,200,182, 88, 44,198,113,227,198,121,106, 52,154,215, 88,245,244,240, 41,142,152, 22, 2,208, 82, + 74,141,246,245, 17, 17, 17,242,208,208,208, 70, 17, 17, 17,114,119,181, 10, 11, 11,151,124,246,217,103, 97,156,220, 27, 7, 77, +189,241,131, 56, 11, 59,188,190, 68,122,141,201, 8, 8,171,133, 94,189,122, 5, 16, 66,190,124, 0,105,222, 76, 41, 29, 72, 41, +221, 80,149,239,255,213,233,108,209,162, 69, 92,108,108,236,137,230,205,155,167,198,198,198,158,104,209,162, 69,220,253, 30,243, +211, 49,164,219,136, 38,124,210,192, 6,132,142,104,194, 39, 61, 29, 83,249,185,154, 24,140,191, 26,151,157,220,171, 85,171,102, +122,227,141, 55,206, 24, 12,134,243,223,125,247, 93,173,225,195,135, 55,173, 81,163,198,213, 39,159,124,242, 23,141, 70, 99,181, +247,201,113,147,231,123,247,238,189,205,223,223, 31,121,121,121,130,197, 98,225,181, 90, 45, 15, 0,162, 40,194, 96, 48,240,183, +110,221, 18,140, 70, 35,109,221,186,245,150, 35, 71,142,188, 4, 96, 98, 69,130,106,181,250,229,165, 75,151, 42,202, 51, 87, 54, +155, 13, 5, 5, 5,176, 90,173,152, 53,107,150, 98,242,228,201,255, 3,112,212,197, 77,117,252,252,249,243,229, 86,171, 21, 28, +199,129, 82,138, 83,167, 78, 33, 43, 61, 29,134,130,124, 24,243,243, 96,206,207, 3,175, 45,192,136,199,122, 42, 22,111,216, 52, + 9,192,136,138, 52, 77,114,205, 7,223, 45, 93, 14,155,205,134,212,205, 63,150,185, 79,246,161,189,176, 89, 45,120,255,195,143, +201,171,207, 15,122, 31,192,218,191,171, 96,200,229,114, 97,213,170, 85, 67,101, 50, 25, 40,165,196,100, 50, 97,199,142, 29,247, +173,185,114,229,202, 17,118, 77,179,217, 76, 27, 54,108,120, 79,243,154,209,104,164,255,148, 11, 68, 38,147, 65,161, 80,192,108, + 54,163,122,245,234,250,126,253,250, 29,158, 63,127,126,117,158,231,213,130, 32,252,150,151,151, 55,247,194,133, 11,183,220,213, + 43,238, 60, 12,147,201, 4,189, 94,143, 59,119,238, 4,133,134,134,146, 55,223,124,211,166,211,233,162,150, 47, 95,126,227,199, + 31,127, 84,125,241,197, 23, 79, 2, 24,207,170,168,135, 71,173, 90,181,100,158,158,158, 94,213,253, 4,173,132, 71, 97, 58,165, + 30, 17, 17, 17, 53, 44, 22,203,147,132,144,214,117,234,212,241,185,126,253,122, 78,104,104,232, 81,142,227,126, 72, 76, 76, 76, +117, 97,124,136,213,106,197,232,150,185,120,185, 13, 15,139, 37, 15,121,121,121,184,125,251, 54, 46, 94,188,136, 99,199, 46, 84, + 41,157,145,145,145,207, 43, 20,138, 30, 50,153, 44,194,102,179,113, 58,157,238,182,209,104,220,149,146,146,178,132, 22, 79, 80, + 84, 73,131,246,151,164,211, 73,255,211, 39,158,120, 34,196,203,203, 11,167, 79,159, 14, 57,123,246,236,167, 0, 98,239,235,186, + 20,184,111,102,127,242,101,104,176,191, 55, 46, 28,218, 26, 58,111,217,143,223,160,168, 47, 47,131,241,239, 49, 88,118, 20, 10, +133,109,204,152, 49, 87,183,108,217, 18, 17, 27, 27,123,185,188,206,192, 46,104, 23, 29, 29,125,251,240,225,195,240,245,245, 53, + 91, 44, 22,222, 96, 48,112, 82,169,148,102,103,103, 19,189, 94,207,157, 61,123, 86,145,148,148, 36,245,241,241,145, 0,104,230, + 70,132,161, 77,100,100,100,217,166,198,100, 66, 97, 97, 33, 10, 10, 10, 96, 52, 26, 17, 24, 24, 72, 56,142,107,229, 50,172,199, +113,237,235,214,173, 75,114,114,114, 16, 18, 18,130, 67,135, 14,161, 48, 55, 23,134,130,124,152,242,243, 96,206,203,133, 37, 47, + 23,185,233, 41,136, 8, 14, 35,197, 83, 11, 84,136,149, 87,214, 8,208,168,113,125,246, 52,180, 56,117, 27, 68, 34,197,241,134, +193,160,150,162,174, 86, 45,207,165,128, 72,101,184, 60,225, 57, 4, 14,127, 17, 22, 78, 30,250,144,159,220,141,132,144, 41, 28, +199,205,151,203,229,194,216,177, 99,145,154,154, 90,194,252,140, 29, 59,214,209,231,170, 67,135, 14, 7, 20, 10,133, 53, 35, 35, + 3, 70,163, 81,226,142,102, 68, 68,196,237,183,222,122,235,184,201,100, 10, 11, 9, 9,241, 54, 26,141,250,186,117,235,134, 40, +149,202, 64,147,201,100,139,141,141, 93,162, 84, 42, 45,133,133,133,212,106,181,146,127,194, 5, 66, 8, 1, 33, 4, 86,171, 21, + 86,171, 21,222,222,222,218,172,172,172, 99, 55,111,222, 28, 90, 21, 61,139,197, 2,139,197,226,136, 98,137,162,136,115,231,206, + 65,161, 80, 72, 68, 81,188, 96,179,217, 84, 18,137, 4, 60,207,179, 57,234, 30, 34,205,155, 55,239,212, 56,208,243,179,177, 33, + 70,239,154,125,213, 90,149,140,215,126,156,165,140,248,229, 59,237,218, 62,189, 7,123, 76,158, 60,185,134,175,175,175,226,214, +173, 91,134,121,243,230, 69,110,220,184,145, 0,248,164, 34,205,148,148,148,159, 62,248,224, 3,223, 78,157, 58, 69, 73, 36, 18, +146,155,155,139,140,140, 12,164,167,167,227,206,157, 59, 52, 33, 33,225,166,213,106, 93, 87,153,116, 54,110,220,120,249,240,225, +195,159,105,208,160,129,132, 82, 10,179,217, 12,157, 78,215,244,216,177, 99,253, 14, 30, 60, 24, 7,160,210,229, 50, 53, 53,117, +221,135, 31,126,168,238,216,177, 99, 61,137, 68,194, 61,136,116,150,170, 7, 66, 52, 26, 13,118,237,218, 5,111,111,111,184, 26, +173,235, 14, 70,139, 24, 26, 20,224, 7,195,161,207, 80,219,183, 6,140, 22, 49,148,149, 98,198,191,214, 96,101,100,100,200,180, + 90,173, 32,138, 34,159,151,151,167, 82,169, 84, 86,153, 76,102,170,228,239, 53,232,215,175,223,241, 86,173, 90, 21, 22, 71, 52, + 44, 1, 1, 1,230,188,188, 60,136,162, 8, 81, 20,173,158,158,158,133, 22,139, 5, 81, 81, 81, 28, 0,151, 77,132,122,189,190, +186, 82,169,188,103,189, 78,167,115,152,171,194,194, 66,232,116, 58,120,121,121, 65,171,213,186,188,184,109, 54, 91,132, 74,165, + 66, 74, 74, 10, 0,160, 32, 39, 27,198,252,124,152, 10,254, 52, 87,182,220, 28,136,122, 45,188,195,194, 97,181, 90,195, 93,105, +106,141, 54, 25, 15,138,244,173, 63, 33,240,229, 41,229,238,151,115,112, 47, 60,106, 71, 67,175, 55, 63,244, 57,202, 40,165, 11, +155, 54,109,218,108,227,198,141,163,146,147,147,239,217, 62, 96,192, 0,140, 31, 63, 30,227,198,141,187,252,248,227,143,159,221, +186,117, 43, 94,121,229, 21,136,162,216,132, 16,146, 71, 41,253,181, 34,205,233,211,167,159, 72, 76, 76,220,123,237,218,181,177, + 1, 1, 1,242, 70,141, 26, 93,111,212,168, 17,191,113,227,198,192, 23, 95,124,241,100,175, 94,189, 18,118,239,222,237,187,107, +215, 46,133, 40,138,205, 9, 33,201,127,247, 60, 88,246, 38, 98,147,201, 4,131,193, 0,179,217, 12,155,205, 70, 42,145,167, 37, +254, 23, 69,209, 97,214,140, 70, 35, 44, 22, 11,217,185,115, 7,182,110,221,202, 93,186,116, 49,108,250,244,215,145,151,151, 7, +155,205,198,106,167,135, 64,108,108,236, 99, 2, 21,151, 14, 15,178, 42,134, 6, 90,181, 82, 66, 11,175, 45,125,171, 48,190,134, + 70,235,233,207,155, 60,253, 36, 33,211,166, 79, 11,190,121,227,166,241,163,143, 62,186,212,167, 79,159,128, 23, 95,124,177,254, +182,109,219,226,170, 87,175,254,245,157, 59,119,114,203, 49,230,210, 81,163, 70, 29,243,246,246,174,185,122,245,234,244,228,228, +100, 31,139,197,162,178, 88, 44,102,131,193,112,195,108, 54, 31, 52,153, 76,187, 82, 83, 83, 79, 86, 38,189, 26,141,166,241,160, + 65,131, 36,185,185,185, 40, 30,125,139,244,244,116, 52,107,214,140,223,189,123,119,131,170,228,193,197,139, 23, 63, 11, 9, 9, +217,187,101,203,150, 30,106,181,186,185, 76, 38, 11, 18, 69,209,166,215,235,211, 12, 6,195,153,170,164,179, 84, 94,164,156, 58, +117, 42,196,211,211, 19,137,137,137, 32,132,164,220,239,121, 83, 72,185,196, 75, 7,183,132,215,246,141,196,177,163, 71,161,144, +114,137,172, 52, 51,254, 85, 6,171,160,160, 64, 56,117,234,148, 79, 98, 98,162,198,223,223,223, 80,191,126,253, 60, 66,136,200, +113, 28, 77, 77, 77,245,141,143,143, 87,248,249,249,105,107,214,172,153,237,230,239, 93,155, 48, 97, 66,220,140, 25, 51, 78,118, +239,222, 61, 19, 0,114,114,114,144,149,149,133,140,140, 12,152,205,102,164,164,164,112, 39, 78,156,240,253,237,183,223,154, 2, +112,217,244,162, 84, 42,239, 20, 20, 20,212,245,246,246,118,220,208,236,166,202,217, 96,217,163, 89,106,181,218,229,197,205,113, + 92,114,114,114,114, 45,131, 94,143, 59,215,175,195, 88, 80,212, 36,232, 48, 87,121,217, 64, 97, 1,212, 10, 5, 10,178,179,192, +243,252, 93, 87,154,106, 57,111,178, 88,109,178,106,189,250, 1,164,252,251,179, 87,203,118, 16,235, 53,130, 82,185,222,242,119, + 20, 8,142,227,108, 21, 53,251,202,100, 50, 4, 6, 6,138,173, 91,183,198, 43,175,188, 98, 55, 2,132, 16,210,137, 16,114,144, + 82, 90, 88,158,166, 40,138,220,165, 75,151,158,184,113,227, 6, 47,145, 72,184, 86,173, 90,197,180,111,223,222, 36,147,201, 32, +149, 74,133,194,194, 66,143, 93,187,118, 41, 44, 22, 11, 41,214,124,104,243, 96, 1, 69,163,251,202, 48,240,208,106,181,208,235, +245, 40, 44, 44, 68,110,110,174,160, 84, 42,235,118,232,208,225,168,209,104, 92,103,179,217,190, 57,121,242,100,126,121,154,102, +179,185,132,217, 18, 69, 17,148, 82,216,108, 54, 88, 44, 22, 72, 36, 18,113,203,150,173,248, 98,225,124,172, 95,187,129,118,235, +214,141,252,246,219,111, 16, 69, 49,137, 85, 79,127, 61,162, 40,126,250,251,180,167, 20,176,218,180,198,125,107, 10,183,103, 11, +218,175, 47,252,126, 66, 47,112,249,213,235,163, 81, 68,120, 77,222,203,211,139, 91,177,114,105,214,111,219,246,220, 72, 74, 74, +202,159, 61,123,118,155,168,168, 40,175,171, 87,175,134, 2,200, 45,199, 8, 69,140, 28, 57,114,100, 78, 78,142,116,217,178,101, + 43,146,147,147,247, 81, 74,111,150, 50, 30,205, 8, 33, 31, 3,144, 0, 8, 4, 96, 5,176,147, 82,186,178, 2,179, 34, 18, 66, +240,251,239,191,223, 51,218, 79,116, 30,145, 81,249, 40, 86, 78,171, 86,173, 26, 95,187,118,109,115, 78, 78,206,234,210,219, 85, + 42, 85,191,152,152,152, 33,199,143, 31,127,155, 82,122,163,146, 15,110, 19, 47, 93,186,244,145, 40,138, 53, 56,142,187, 77, 41, +157,250, 0, 34, 88, 47,204, 91,182,118,153,193,108,171,174,144,242,119,140, 22,241, 69, 86,154, 25,255, 26,131,101,181, 90, 53, +111,189,245, 86,155, 38, 77,154,164,118,232,208,225,110,100,100,164,206,190,205,195,195, 67,239,231,231,167, 55, 24, 12,202,219, +183,111, 7,111,218,180,169,142,205,102, 83,185,241,123,123,188,189,189,125, 79,156, 56,225,247,195, 15, 63,212, 62,117,234, 84, +141, 97,195,134,117, 52,153, 76, 48, 26,141,184,117,235, 86,141,165, 75,151,138, 82,169, 52,151, 16,242, 7, 0,151,143,241, 22, +139,229,200,181,107,215,234,180,106,213,138, 88, 44, 22,135,161,114, 54, 89,133,133,133,144, 74,165, 72, 73, 73,161,162, 40, 30, +115, 35,157, 71, 79, 28, 63, 94,171, 97,253,104, 24,243,114,138,205, 85, 30,172,121, 57, 16,243,178,193,105, 11,225,231, 43, 64, +165,208,224,106, 74, 42,138,211, 90, 33, 18,171, 62, 33, 57, 47,191,110,173,153,159,224,247, 40, 79, 80,139,217,209, 44, 8,192, +209, 92,216,246,114, 6, 14, 28, 62, 2,193,102, 76,254,167, 22,154,179,103,207,166, 15, 27, 54,236,164, 40,138,205, 80,193, 20, + 5, 21, 60,133, 23, 20, 22, 22, 34, 51, 51,211,150,149,149,101, 0,128,244,244,244,156, 45, 91,182, 92, 18, 69,177,101, 85, 52, + 31, 4, 22,139,229,158,232,147,205,102,131,213,106,133,217,108, 70, 70, 70,134,236,224,193,131, 29,142, 30, 61, 42,189,120,241, + 34,142, 30, 61,218,100,211,166, 77,175, 71, 71, 71, 55,186,124,249,242, 93, 87,166,141,148,109,172,121, 0,216,178,241,103, 12, + 25, 50,132,100,102,102, 98,211,166, 77, 15,164, 25,133,225, 22, 90, 88,109, 74,211,190, 53,133,175, 93,151, 23, 92,208,241,179, + 79,158, 60,185,157, 82, 74,123,247,238,125,182,110,189, 40,127, 0,144,203, 52, 65, 13, 27, 54,236,232,227,227, 35, 3,128,144, +144,144,230, 22,139,101, 33,128,246,101,137, 14, 24, 48,160,109, 64, 64, 64,211, 95,127,253,245, 76,114,114,242,254,210,230, 10, + 0,234,214,173, 59,235,252,249,243,143, 73, 36, 18,226, 84, 70, 40,128, 50, 13,214, 83, 79, 61, 85, 55, 44, 44,204,111,219, 53, + 47,228, 75,107,129,242,121,128,160,128,205,187, 49,110, 75,235, 35, 40,232,138, 95,173, 90,181,154,220,184,113,227, 76, 37, 35, + 76,213, 7, 13, 26,244,203,242,229,203,163,123,245,234, 37, 3,112,143,193,138,142,142,126,114,247,238,221, 3,199,142, 29,219, +152, 16,210,151, 82,122,221, 93,253,147, 39, 79, 30, 2,208,230, 65,158,180,117, 23,232, 46, 20,207, 89,198, 96,252,235, 12,150, +217,108,222,121,253,250,245, 22, 79, 61,245, 84,166,179,185,162,148, 58, 42, 3, 47, 47, 47,189,191,191,127,246,153, 51,103,170, +137,162,184,207,141,223, 91,182,123,247,238,223, 23, 44, 88,176,198,215,215,215, 50, 98,196, 8,110,218,180,105, 7,178,178,178, +104, 86, 86, 22,190,252,242,203, 14,113,113,113, 7,110,223,190,109, 59,121,242,228, 72, 0,189, 92,214,142, 90,237,194, 87, 94, +121,101,200,129, 3, 7, 20,246,121,138, 74, 71,175, 44, 22, 11, 4, 65,192,194,133, 11,141, 90,173,118,190, 27,145,140, 37, 95, +125,245,213,192,165, 95, 44, 80,240,102, 51, 44,185,217,176,230,229,194,150,155, 13, 78,167,133,135,130,160,118,179,106,200, 73, +150, 99,213,246, 67,122,171,213,250,149, 75,131,101, 40,156, 50,118,244, 75, 63,239,220,243, 59,124,219,119, 65,214,239,191,221, + 27, 29,170, 22, 8,147,217,140,247,222,157, 73,137, 62,119,218,223,244, 68,207,155, 76,229,183,252,154, 76, 38,136,162,152,116, +241,226,197,181,132,144, 2, 66, 72,167,226, 77,123,203,138, 94, 57,107,114, 28, 39,214,175, 95,127, 99, 96, 96,224, 19, 0,180, +245,235,215,223, 40,151,203,187,152, 76,166, 86,162, 40, 38,157, 62,125,122, 3, 33,228, 46, 33,164, 79,241, 87, 31,234, 60, 88, + 22,139, 5, 51,102,204,192, 7, 31,124,128,233,211,167, 59,142,215,222, 76,104, 54,155, 35,119,236,216, 33, 61,116,232, 16,253, +238,187,239,178,158,126,250,105,239, 97,195,134,121,175, 90,181,106, 34,128,169,229,105, 78,157, 58, 21,139, 23, 47,198,152, 49, + 99,238,117, 87, 60, 47, 38, 39, 39,193,100, 54,209,149, 43, 87,166, 8,130,224,243,249,231,159, 43, 39, 79,158, 76, 88,245,244, +215, 99,179,217,222,108,247,233,166, 87, 9, 81,154,173, 86,235,252,179,103, 79,239,117,122, 16, 80,126,250,201,167, 2, 0,124, +242,241,167, 18, 74,169,151,125, 98,216,217,179,103, 43, 70,143, 30, 29, 80,158,238,250,245,235,115,103,207,158,237,247,194, 11, + 47,244,218,187,119,175,138, 16,178, 13,192, 31, 0, 50,139, 31, 28,253, 1, 28,170, 86,173, 90,240,218,181,107,107,245,232,209, + 67,237, 70, 93,247,245,162, 69,139, 34, 62,221,239,129,109,218, 39,144, 40, 62, 13,234, 77,225, 27, 80,128,250,154, 59,232, 28, +154, 28,178,122,245,234,101, 0,154, 87,194, 92, 53,120,234,169,167, 54, 45, 95,190, 60,242,165,151, 94, 74, 58,116,232, 80, 34, + 33,100, 86, 25,187,102, 61,247,220,115,183, 87,172, 88, 81, 75, 20,197,237,132,144, 94,148,210,107,172, 4, 49, 24, 85,139, 96, + 61, 79, 8,137,153, 62,125,250, 71, 33, 33, 33,213,103,206,156, 25, 95,191,126,125,173,227,106,203,202,210,236,219,183, 47, 42, + 63, 63,191,192,106,181,142,160,148,158, 45,227,226,237,230, 60, 87, 6,165,244, 54, 33,228,163, 38, 77,154, 12,249,241,199, 31, +247,121,120,120,228, 31, 61,122,212,211,211,211, 51,239,210,165, 75,106,158,231,117,241,241,241,216,177, 99, 71, 7, 0, 95,148, +245,148, 84, 90, 51, 53, 53,245, 84, 84, 84,212,252,201,147, 39,255,239,237,183,223, 86, 80, 74,161,211,233,144,159,159, 15,163, +209, 8, 65, 16, 64, 8,193,154, 53,107,140, 70,163,113,105,114,114,242, 81, 87,154, 41, 41, 41, 71,194,195,195,191,153, 63,111, +222, 11, 47, 14, 25, 44, 67, 94, 22,114, 83,147, 65,116,133,208, 40,229,136,233, 26, 6,109, 22,193,242,125,127,152,178,141,230, +181,201,201,201,123, 93,105, 30,188, 83,240, 75,155, 58, 1,187,103,207,158,217,245,245,111, 55, 64, 20, 69, 92,126,229, 25,228, +236,223, 9, 85,253, 70,104,123, 57, 3, 38,147, 9,211,167, 78, 6,175, 75, 59,112,244, 78,225,122, 87,154, 15, 2,103, 77, 66, +200,203,132,144,103,162,163,163, 49,118,236, 88, 12, 24, 48,160,196,190,155, 54,109,194,162, 69,139, 96, 52, 26,159, 33,132,156, +162,148, 46, 36,132, 28, 44, 62,183,133,174, 52, 35, 34, 34, 90,196,196,196, 32, 36, 36, 68, 87,108, 46,186, 95,188,120,177,121, +116,116,116,105,205, 63,138, 53,173, 15,235,216, 41,165, 57,215,175, 95,247,252,248,227,143,137,217,108,198,172, 89,179, 96, 55, +154,246,150,151, 55,222,120, 35, 68,163,209,224,147, 79, 62, 49,101,102,102,118, 89,180,104,209,158, 5, 11, 22,248,175, 89,179, +102,168,221, 96,149,210, 76,191,116,233,146,199,226,197,139, 57,171,213,138,207, 62,251,236,158,102,200,137, 19, 39,194,108,182, + 64,224, 5,147, 65,111,104,160, 80, 40,110,248,248,248, 40, 69, 81,164, 15,235,216, 31,101,205,179,103,207,238, 4,176,211,157, +239, 25, 12, 6,100,100,100, 32, 51, 51, 19,197, 93, 18, 72,121,233, 52, 24, 12,167,167, 78,157,122,114,201,146, 37,189, 14, 29, + 58, 52,112,255,254,253,189,118,237,218,101,184,125,251,182,213, 98,177,208,224,224, 96,161,125,251,246,138,222,189,123,171,229, +114, 57,247,230,155,111,102,206,153, 51,199, 31, 64, 86, 5,245, 39, 79, 41,197,107, 29, 10, 48,181, 51, 15,147,201,140,220,220, + 92, 36, 39, 39,225,226,197,139, 56,114,228, 50, 40,165, 92, 37,243,115,254,234,213,171,163,100, 50, 25, 89,179,102, 77,245, 53, +107,214, 76,112,149, 15, 43, 87,174,140, 88,179,102,205,194, 98, 45,145,149, 37,166,201,168,164,193, 42,190,160, 47, 0,232, 69, + 8,105,255,210, 75, 47,125, 24, 29, 29,109,180, 90,173,146,237,219,183,215,203,204,204,148, 89,173,214,169,148,210,253,149,249, + 65, 74,233, 98, 66, 8,250,247,239, 63,181,102,205,154,187, 79,157, 58,213,184, 95,191,126,219, 55,110,220,216,222,106,181,222, + 60,127,254,252, 51, 0,230, 3,248,194, 93,205,248,248,248,183,118,237,218,101, 61,122,244,232,107,211,166, 77,147, 7, 4, 4, + 16, 31, 31, 31,164,164,164, 32, 41, 41,137,126,251,237,183, 70,163,209,248,133,151,151,215, 91,238,106,202,100,178,215,246,159, + 56, 73,174,222,184, 49,242,249,199,122, 40,194,235,212,133,134,212, 69, 65, 86, 38,246,239, 77,195,138, 63,206, 24,210, 12,166, +239,121,158,119,123, 40,125,232,245,140,158, 59,127, 88,254,235,222,221,123,186,205,253,224, 35, 18, 50,252, 5,168, 35, 34, 33, + 70,212,198,190,189,123, 49,103,246, 44,202, 23,166,237,183,220, 72,235,254,176, 11,130,125,206, 42, 81, 20, 5, 0, 80, 42,149, + 24, 63,126, 60,156, 95,141,179,104,209, 34,232,245,122, 0, 16, 8, 33, 31, 19, 66,190, 41, 47,106, 85,142,102,245,109,219,182, + 85,119,214,140,142,142, 46, 75,211,248,176,143, 63, 45, 45,237,173,231,158,123,238,125,137, 68,226, 93,222, 62,106,181, 26, 5, + 5, 5,176,217,108, 54, 95, 95,223, 43,246,200,104,121,215,145, 86,171,125,107,204,152, 49,239, 17, 66,202,141,116, 40,149,202, +219, 7, 15, 30,172, 61,108,216, 48,110,237,218,181,183,134, 14, 29, 42, 63,120,240,160, 13,192, 6, 86, 61,253,179,112, 30,176, +160,213,106, 1,128, 86,176,239, 29, 66,200,212,147, 39, 79, 42,198,140, 25,211,124,248,240,225,158,157, 59,119,214, 56,239,163, +215,235,197,173, 91,183,106, 23, 47, 94,156,181,127,255,254, 63, 70,141, 26,245, 4,138,102,144, 47,147,148,148,148, 95,190,248, +226, 11,175, 78,157, 58,213,177,217,108,142,254, 87, 25, 25, 25, 72, 74, 74, 66, 66, 66,194,109, 81, 20,183, 84,242,176, 94, 25, + 54,108,216,182, 21, 43, 86,212,120,233,165,151,146,126,248,225,135, 45, 0,242,202,216, 79,243,228,147, 79,246, 91,177, 98, 69, +141,209,163, 71,223, 1, 48,129,205,240,206, 96,220,135,193,114,170, 44, 14, 2,104, 67, 8,233,207,243,252,148,194,194,194,207, + 40,165,155,239,163,162, 90, 76, 8,217,126,253,250,245, 23, 0,196,126,246,217,103,175, 3, 72, 68, 81, 8,189, 71, 89,253, 21, + 92,232,217, 0,188, 29, 26, 26,250,211,172, 89,179, 30,200,187, 8,111,220,184, 97, 2,240, 74, 72, 72,200, 15,239,255,176,254, + 45, 74,105, 51,158,138,126, 54,194,229,112, 28,119,218,102,179,205, 73, 74, 74,218, 87, 25,205,117, 69,233,236,209,186,186, 71, +159,169,163,135,125,100,149, 40, 35, 10, 13, 86,153, 90, 46,152,164, 54,227,109, 78,159,243,230,209,219,133,255,136, 27,171,209, +104,180, 62,241,196, 19, 95,115, 28, 39, 2,128,205,102, 19,140, 70,227, 72, 84, 98,228,105, 89,154, 3, 6, 12,248,150,231,121, +107,113,100,136, 51, 26,141,207,223,143,230,131, 34, 51, 51,179, 16,192,184,138,246,137,139,139, 91,245,235,175,191, 14,235,222, +189,187,237,151, 95,126, 73,127,252,241,199,133, 83,167, 78, 81, 66, 72,153, 79,113, 9, 9, 9, 70,148,243, 70, 2, 59, 77,154, + 52,169,241,205, 55,223,156,122,225,133, 23, 60, 23, 46, 92,232,123,252,248,113,219,242,229,203,243, 11, 11, 11, 63,101,213,211, + 63, 11,137, 68, 2,149, 74, 5,147,201,132,140,140, 12,184,234, 83, 78, 41,189, 65, 8,121,124,202,148, 41,113, 83,166, 76,121, + 60, 44, 44,172, 65,245,234,213,171,115, 28,199,165,166,166,102, 36, 38, 38, 38,152,205,230,221, 0,126, 1, 32,173, 89,179,230, +105, 0,171,202,211,187,120,241,226,123, 33, 33, 33,191,111,220,184,241,113,185, 92, 94, 95, 38,147,249, 90,173, 86,174,176,176, + 48,219,108, 54, 95, 50, 26,141, 63,167,164,164, 28,174,100,221,121,149, 16,210, 89, 16,132, 95,150, 47, 95, 30,157,154,154, 26, +177,111,223,190,190,165,247,107,222,188,249,138, 21, 43, 86,212, 24, 59,118,236,141, 53,107,214, 84,170, 15, 22,131,193, 12,150, +123, 23,227,102, 0,155, 31,196, 15, 83, 74,111, 3,120,171,120,121, 32, 36, 39, 39,159, 3, 48,236, 65,102, 80, 74, 74,202, 33, + 0, 61,129,162,217,156, 19,139,110,154,247,197,209, 59, 5, 63,195,233,245, 42,255,144,167,115, 35, 33,100, 74,241,168, 38, 0, +152,114,250,244,233,133,165, 34, 82,103,157,183,187,138, 52,149,165,121,230,204,153,210,154,231, 43,163,249,119,146,147,147,243, +191, 21, 43, 86, 28,127,229,149, 87,228,131, 6, 13,194,229,203,151,241,213, 87, 95, 25,115,114,114,214, 84, 85,243,204,153, 51, +183,155, 52,105,210,108,217,178,101,175, 45, 93,186,180, 63, 33,132,189,139,240, 31,130,193, 96,184, 57,100,200, 16,112, 28, 71, + 40,165,212,106,181, 58, 6, 61, 20,207,103,118,211,141,235,202, 10,224,247,226,197, 21, 31,187, 81, 31, 29, 1,112,228, 1, 95, +251,119, 8, 33,143, 39, 36, 36,204,189,122,245,234,111,101,237,115,225,194,133, 77, 61,122,244, 80, 29, 57,114,228,141,202,142, + 34,100, 48,152,193, 98,184, 36,225, 1,152,171,127, 50,197,253,159,190,177,155,163,202,110,127, 88,154,127, 23, 23, 47, 94,204, + 1,224,120,101, 72, 84, 84, 20,250,244,233,115,223,186,197,102,106, 60,216,204,237,255, 40,182,108,217,242,216,163,114,172,148, +210, 59, 21, 61,156,154, 76,166, 45, 0,182,176, 82,193, 96, 48,131,197,168,122, 69,107,188,159,237, 15, 75,147,193, 96, 48, 24, +140,127, 50, 4, 64,183,114,110,122,110,143, 14, 32,164,242, 47,218,116,165,207, 52,153, 38,211,100,154, 76,147,105, 50,205,255, +158,166, 43,237,255,204,232, 68, 74,233, 95,182, 0,232,198, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,249,168, 45,236,133, +178, 12, 6, 3,237,171, 19,239,158, 97,196,167,172,109, 61,195,136, 79,251,234,196,155,229, 18,131,193, 96,184, 15,235,131,197, +248,215,241,244,211, 79,243,149,217, 63,222,219,155,203, 75,170,254,169, 70, 37,239,171, 51, 24, 63,189,254,203, 27, 95,252, 23, +242, 33, 56, 56,184,158,167,167,231, 8, 0, 13,116, 58, 93,128, 74,165, 74, 7,112, 49, 63, 63,127, 85,106,106,234, 21,119,117, + 58, 69,145,233, 2,143,153, 70, 30,164,115, 4,153,243,123, 2,125,215,190,173,115, 4,153, 33, 74,240,166, 0,208, 78,145,228, +189,189,241,244, 61,119,117,123,214, 34, 6, 10,200, 9,129,121,251,117,234,120,193,101,175,218,196, 32,210,123,215,247,172, 77, + 76,148, 66, 74, 0,227,246, 27, 84,193, 74, 58,131,193,248,207, 27, 44,153, 76, 22, 67, 41, 29, 69, 8, 9, 34,132,220,165,148, +126, 99, 50,153, 46, 60,106,153, 37,147,201, 98, 8, 33,163, 40,165, 65,148,210,187,132,144,191, 57, 31, 8, 89,255,116, 81, 20, +114,224, 58,136, 0,165,172, 72,151, 97,174,146,171, 47, 29,217,191,197,115,211, 70,117, 70,179, 65,159, 77, 69, 37, 38,177,253, + 39, 66, 8,225,163,162,162, 94,169, 81,163,198,224, 37, 75,150, 72,163,162,162,160, 80, 40,160,215,235,131,111,222,188, 25, 60, +118,236,216,142, 53,107,214, 92,123,235,214,173,175,138,231,136, 43,223, 4,133, 17, 31, 72, 48,115,239,194,177, 50, 0,232, 56, +118,209,140,200,208, 0,106,134, 68, 47,133, 69, 25, 46,193,140,125, 11,199,242,197,219,102, 70,134, 6, 16, 51, 36,122, 39,137, +164,228,228,228,117,101,105, 83, 64,246,243,202, 79,208,239,153,201, 66,104,104,232,107,246,245, 77, 52,132,252,188,106, 30,122, + 13,249, 95,137,245, 49, 10, 8, 91, 87,126,130, 62,207, 76, 46,247,109,227,189,234,112, 22, 81,164,229,214, 91, 28, 71,172, 23, +116,193,211,203,216, 84,102, 58,251, 68, 11,105,102,139,173,204,137, 96,165, 18, 62,253,231,203,214,192,208,208,208,167, 1,132, +185,171,201, 96, 48, 24, 21, 26,172,136,240,240, 65, 28, 79, 22,152, 45, 54, 31,111,111,111,238,203, 47,191,228,250,246,237,139, +159,183,110,197,248,241,227, 39,132,134,134,136, 82, 65,200,161,162,117, 66, 66, 98,202,143,238,252,216,147, 79, 62,153,102,177, + 88,202,157,213,154,231,249,244, 77,155, 54, 5,222,239, 65,133, 54, 31,148,102, 49,155,203,253, 29, 65,144,164,167,156, 94,231, +214,239,132,135,135, 12,226, 9,183,192, 98, 19,125,124,124,124,184, 47,190,248,130,235,219,183, 47,182,110,221,138,113,227,198, + 77, 8, 11, 13, 21,165, 18, 62, 71,180,209, 9, 9,137,137, 63, 62,188, 83, 71,200,250,245,224, 48,176,232,191,245,235,193, 13, + 28, 72, 30,105,147,149,153,153, 73, 0,192,223,223,159,150, 48, 87,253, 90, 60,247,230, 75, 93, 49,103,233,110,232,141,166,213, +255,246,227,140,138,138,122,229,233,167,159, 30,252,222,123,239, 73, 57,174,168,149, 95,171,213, 66,175,215, 35, 52, 52, 20,123, +247,238,149,190,245,214, 91,131, 55,109,218, 4, 0, 11, 42,163,205,243, 60,249,125,231,254, 40,223,192, 16, 83,118, 90,138,236, +249, 94, 13, 72, 89,219,236,235,234,213,171,231, 82,179,154,175,167,241,202,174, 43,181,237,255,143,235, 22,102, 43,103,189, 17, +128,178, 34, 45, 81,164,194,142, 47,198,150,187,125,204,251,107,109,235,126,249, 83,211, 85, 58,205, 22, 91, 64,121,122, 61,198, + 47,178,215, 33, 97, 87,174,184,175,201, 96, 48, 24, 21, 26, 44,194, 97,225,154, 37, 31,251,100,101,231,224,135, 77,219, 17, 29, + 29,141,139, 23, 47,162, 94,116, 52,226, 90, 54,225,122,180,109,204, 9,132, 84,123,251,139,149, 11, 1,184,101, 44, 44, 22, 75, +192,198,141, 27, 65, 8,129,205,102,131,205,102,179, 79,216,135,194,194, 66, 76,152, 48, 33,224, 65, 28,148,197,108, 14,184,249, +199, 6, 72,120, 2,171,141,194, 98,163, 48, 91, 69,152,173, 20,249, 58, 43,186, 60, 62,204,237,223,225,192, 45,252,246,139, 79, +124,114,114,115,177,241,215, 93,142,124,136,142,142, 70,151,118, 45,185,167, 31,239,200,169, 21,242,106, 47, 78,123,223,237,124, +120, 16,172,127,250, 79,115,229,188,110,224, 58,216, 30,165, 2,124,249,242,101,222,104, 52, 14,241,244,244,108, 45,145, 72, 2, + 85,222,193, 98,174,180,102,150,150, 4,221, 50,107,101, 29, 70, 13,168,213,235,141, 23, 58, 97,206,210,221,248,118,203, 31, 43, +188, 66, 19,103,252,155,143, 55, 56, 56,184, 94,141, 26, 53, 74,152, 43,251, 75,205,243,243,243, 81, 80, 80, 0,142,227, 48,117, +234, 84,233,190,125,251, 6, 7, 7, 7,239,170,168,185,112,123, 18,205,233, 20, 69,102,118,124,121,209,108,158,227, 57,153, 79, +248,169,217, 31,124,156,175, 86,171,169, 66,161,208, 87,139,136, 57,213,101,220,210,102,148, 82,234, 21, 90,231,143, 37,223,124, +151,167, 86,171,169, 92, 46,151,191,244,210, 75,110,245,225,212, 27,244,152, 52,105,146, 81,169, 84, 82,133, 66, 65,141,166,162, + 89, 57, 12, 70, 3,222,124,243, 77,163, 74,165,162,106,181,154,154,204, 38,183,243,225,214,221, 2, 72, 5, 14, 82, 9, 15,169, +192, 67, 25, 84, 23,178,194,120,152,205,230, 18,154,238,166,115,207,217,100, 40,101, 18,168,228, 2,106, 71,134, 65, 78,245,247, +236, 51,118,236, 88,209,203,203,203,172,209,104,164,111,188,241, 6,235,191,202, 96, 48,170,102,176, 76, 22,155, 79,144,159, 55, +190,253,230, 91, 76,125,125, 54,234,213,171, 7, 74, 41, 8, 33,120,125,198, 44,124,254,238,116, 12,126,172, 35, 44, 86,209,167, + 60,141,178,134, 90, 18, 66, 16, 31, 31, 15,131,193, 0,189, 94,239, 88, 98, 98, 98,220, 74,176,187,195, 55, 37, 60,193, 47,167, + 10,138,140,149, 69,132,217, 42,194, 98, 21,209, 57,198,163, 82,154, 22,155,232,227,229,161,198,210,197, 11, 49,245,221,143, 75, +228,195,180, 55,222,194, 87, 31,190,141,137, 99,158,133,201, 98,243,169, 74, 58, 43, 3,211, 44,201,225,195,135,131, 85, 42,213, +103,195,134, 13, 11,153, 48, 97,130,140, 10,106, 97,251,177,219, 94,159,124,179, 59,196, 96, 50,243,143,183,175,137,231, 7,196, + 98,206,178,223,139,205,213,157,151, 34,115,115,197,127,243,177,123,122,122,142, 88,178,100,201, 61,230, 42, 45, 45,141, 43, 44, + 44,132,217,108, 22,139,223,151,136,233,211,167, 75,222,122,235,173, 17,132,144,119,139,117,140,101,105,238,189, 69, 63,168, 17, + 26, 40,236,219,187,175,230,187,239,127,148, 63, 96,192,128,235, 28,199, 65, 34,145,224, 70,120, 56,125,172, 91,231,203,239,127, +248,161,241,185,231, 95,186,192,113, 28,120,158,199,213,171, 87,163, 0,168,220, 57,118, 2,208,126,253,250, 57, 52,191,217, 57, +159,218,215, 15, 25, 50,228,186, 93,243,210,198, 57,212,221,252, 20,120,130, 48,127,245,159,191, 32, 87, 2,197,111,197,116,214, +116, 55,157, 2,207,161,117,189,226,231,174,208,102, 64,210,193,123,126, 83,161, 80,152,159,122,234,169,235, 9, 9, 9,110, 31, + 59,187,222,153, 38,211,100, 6,171, 76,204, 70, 61, 98,170,251, 98,241,167,239, 65,164, 28, 40, 40,168, 72, 65,169, 13,145,254, +106, 24,117,218, 74,255,160, 40,138,176, 88, 44, 48,155,205, 88,178,100, 9, 10, 11, 11, 33,138, 34,234,215,175, 15, 0,104,222, +188,185,115, 37,123,231,228,201,147, 53, 92,105, 6, 52, 26,112, 27, 20,213,157,215,189,243,241,215, 56,124,250, 38, 68, 17,144, + 43, 85, 24, 56, 98, 52,172, 54, 10,147,165,242,239, 39, 53,234,117, 8,209, 72, 48,111,238, 12, 16, 65, 2,158, 16, 16, 66,192, + 17, 17,245, 66,189, 97, 50,232, 30,250,137, 27,184, 14,226,250,245, 37, 71,129, 22,245,195,122,116, 34, 87, 42,149,234,179, 85, +171, 86,213,104,209,162, 5, 7, 0,199,175,229,200, 63,249,102,119,200,215, 51,159, 32,205,234, 5, 33, 43, 79,143, 57,203,247, + 97,207,169,148,223, 74,155,171,127, 49, 13,162,162,162, 74,152,171, 79, 62,249,196,127,225,194,133,161, 0,240,212, 83, 79, 37, +119,237,218, 53,243,234,213,171, 8, 14, 14, 38,153,153,153,143, 3,248, 95,241,195,205, 20, 74,233,194,178, 68,173, 16, 12,190, +129, 33, 38,153, 76, 6,137, 68, 2,142,227, 28,139,111, 96,136, 73,237,233, 99, 42,189,222, 93, 8, 33, 37, 52, 75, 60, 8,149, +179,222,101,197, 85,193,254, 85, 73, 39,207, 17, 39,241,178,187,128,201,100, 50, 8,130, 80,233,180, 50, 24, 12,102,176,238,141, + 98, 25,245, 8,243,150, 33, 72, 35,192, 98,177,226,162, 37, 4, 5, 58, 3,204,102, 11,238,152,205,184,117,230, 46,218,181,107, +135, 39,158,120,194,102, 54,155, 33,149, 74,243, 54,110,220,232,235,202, 96,153,205,102,152,205,102,104,181, 90,172, 94,189, 26, +130, 32, 56, 94,156,234,252,198,250,182,109,219, 86,119,207, 74,163,250,141,227, 63,193, 67,193,195, 42, 82, 88,173, 20, 86, 17, +176,218, 40,244,102,138, 39, 70,189, 9,155,141,194, 38, 82,152,172,174,187, 40,149, 48,108,190, 45,208,111,250, 15, 0, 52,142, +237,158,114,138,169,237,120,200,100, 18,200,100, 2, 12, 58,253,223,112,234, 40, 29, 56,144,136,143,106, 39,119,163,209, 56,116, +216,176, 97, 33,118,115, 5, 0, 57,249, 70,193, 96, 50,243,205,234, 5,161,251,224,201,216,185,246, 19,252,122,232, 26,124, 52, +194,254,176,255,134,185,130, 78,167, 11, 80, 40, 20,208,106,181,142,200,213,194,133, 11, 67, 77, 38, 19, 7, 0,130, 32, 9,203, + 16, 67, 21, 54, 17,240,242, 76, 69, 78, 78,158, 31,165,148, 20, 27,157,143, 9, 33,223,148, 53,115,190, 20, 22,101, 86, 90,138, + 76, 46,151, 27,236,198,132,231,121,112, 28,135,172,180, 20, 25,103, 51,209,210,235, 43,131,243,119,157,141, 87, 89,235,221,170, +184,120, 82,162, 2, 40, 79,211,221,116, 10,188,211,126,124,217, 6, 75, 46,151, 83,158,231, 43,157, 86, 6,131,193, 12,214,189, + 17, 44,189, 30, 22,139, 21, 86,171, 13, 22,171, 13,121,133,122,124,248,225,135,144,203,229, 32,132, 64, 20, 69, 20,191, 0,149, +179, 88, 44,120,252,241,199,125, 92,253,160,115,191, 43, 74, 41,120,158, 71,171, 86,173,238,217,239,232,209,163,149, 58, 16, 15, + 5,143,200,110,175,223,179,254,216, 79,239,129, 82,192, 38, 22, 27, 44,179, 27,247, 89, 23,134,173, 73,135,129, 48,153,204, 69, + 17, 61, 74,171, 20,201,123, 96, 38,235, 17,235,115,229, 20, 77,232, 54, 97,194,132, 18,119, 66, 31, 79,185, 85, 33,147,218, 78, + 93, 78, 37, 59,215,126,194,157,184,148, 34,202, 36, 2, 85,211,187, 81,255,149,227, 86,169, 84,233, 58,157, 46, 88,175,215, 35, + 63, 63, 31,249,249,249, 37, 47,104,137,132,188, 52,102,156,191, 68, 42,131,197,108,194,175,171,230,184,212,236, 28, 65,102,132, + 75, 48,227,197,199, 98,224, 87,163,193,233, 27,181,106,137,118,131,114,252,183, 85,109,214,125,252, 74,115, 81, 20, 73,222,157, +179,199, 59, 13,124,249, 24,199,113, 48,153, 76,238, 79,163, 64, 8,185,113,227, 70,148,195, 72, 17, 66,236,235, 47, 95,190, 28, +101, 55, 68,180,232,205, 18,110,161,241,240, 0, 52,213, 0,185,125,122,174, 63,191,234,172,233,110, 58, 27,212, 12, 1,130, 26, + 1, 50,175,138,202,156,236,234,213,171, 81, 54,155,141, 77, 33,193, 96, 48,238,207, 96, 25, 13, 58, 88,172, 54, 88, 45, 69,111, +144, 55,153, 76, 80, 42,149,232,208,161, 67,137,104, 19,165, 20, 59,118,236,128,201,228,186,147,170,213,106,117, 68,176, 68, 81, + 4,165, 20, 63,252,240, 3, 36, 18, 9,164, 82, 41, 36, 18, 9, 36, 18,137,163, 14,118, 23,171,141,226,141,105,175, 65, 34,112, +144, 10, 28, 36, 2,129, 84,224, 96,163, 20, 20, 20, 86, 91,209, 98,178,186, 23,200,168,200,176, 1,128,209,100, 41,122,110,166, +128, 78,167, 99, 37,233, 33,146,153,153, 73,244,122,125,132,183,183,183,147,213,164,168,166,178, 25, 71,246,109,146, 50,242,157, + 13, 33, 38,139, 21, 82,129,167, 67,123, 68,167,236,222,184,215, 47,211,152, 75,236,163, 11,255,229, 92,188,113,227, 70,112,120, +120, 56,242,243,243, 97,181, 90,197,167,158,122, 42, 89, 16, 36, 97,130, 68, 66,250, 12, 25, 39,222,189,155, 98,225, 56, 30,148, +218,240,216,211, 99,137, 92,161,148,154, 77, 38, 43,128, 41,165,163, 87, 61,195,136,143, 40,193,155,246,169, 24,186,140, 91,218, +236,177,110,157, 47,219, 71, 17,254,248,209,203,205,119,127,241,162,125, 91,203, 55, 63, 90,126,221,121, 20,161, 59,200,101,114, +140, 24, 49,194,209,103,233,208,215, 83,138, 12,139, 84,134,126,253,250, 57,214,255, 54, 79,234,182,166,146,183, 2,133,119, 1, +237,221, 18,235, 37, 18, 73, 9, 77,119, 81, 11, 86,224,238,169, 10,247,153, 62,125, 58,135, 82,125,175, 24, 12, 6,163,106, 6, + 75,175,135,213, 98,117,152, 44,179,217, 12, 0,248,244,211, 79,239, 49, 68,148, 82,199,246, 10, 53,141, 70, 68, 69, 69,193,100, + 50, 33, 58, 58, 26,148, 82, 12, 25, 50,228,158,253,142, 31, 63, 94,169, 3,177,216, 40,230,126,248,233, 61,235, 15,174,123, 15, +141,163, 35,209,170,182, 10, 6,139,136, 60,173,245,190, 13, 27, 0,152, 76,102,160,120, 58,124,189, 86,203, 74,210,223,136,197, + 98, 65, 78, 78, 14,140,133, 57,214,186, 65, 52,239,133, 62, 53,141, 25,217, 58,129,163, 6,107,152,135,206, 88,152,157,204,171, + 84,255,141,251, 98,126,126,254,170,177, 99,199,118,220,191,127,191,148,227, 56,228,231,231,163,115,231,206,153, 25, 98,168,226, +165, 49,227,252, 83, 82,146,173,158, 74,193, 40,149, 74,144,158,158, 46,118,236, 61, 76, 63,100,212,171, 33,175,190,249,254,146, +148, 67, 11,239,233,127,165,227, 64, 5,167, 54, 54, 74, 41,253,240,227,143,140, 94,190, 1, 70,129,216,108,206, 77,246,148, 82, +250,205,138,111, 13,190,213,130,141,114,185, 92, 62,116,232, 80,183,218,223, 12, 70, 3,222,126,251,109,163, 66,161, 40, 49, 90, +208, 96, 52, 96,238,220,185, 70,141, 70, 67, 85, 42, 21, 53, 91, 92,215, 31, 28, 71,172, 99,222, 95,107,179,215, 53, 78,193, 48, + 8,130, 0,179,141,104,157, 53,221, 77,167, 59,163, 8, 39, 77,154, 36,250,248,248,152, 61, 61, 61,165,227,199,143,103, 29,177, + 24, 12,198,125, 24, 44,157, 22, 22,139,173,184,137,208,234,136, 58,141, 31, 63,254,158,125,119,239,222,237,210, 96, 9,130,144, +254,194, 11, 47,148,152, 34,129, 82,138, 13, 27, 54,192,222,185,214,110,218,170, 18,193,154,249,214,100,200, 36,124,177, 33, 42, + 50, 70, 34,165,216,242,203, 14,108,249,101,135, 99, 95,158,151,164,223,143, 97, 43, 50,138, 22, 80, 90,116,103,210, 23, 50,131, +245, 48,241,247,247,167, 25, 25, 25, 9,185,185,185,117,213,106, 53,178,178,178,144,157,157,141,220,220, 92,232,243,115,172,106, +107,174,214,100,205,134, 32, 8,184,155,152, 6,155,205,118,247, 63, 18,189, 66,106,106,234,149,154, 53,107,174,125,227,141, 55, +134, 76,159, 62, 93, 34,138, 34,174, 94,189, 10, 16, 66, 37, 82, 25,138, 70,234, 9,200,203,203, 23, 85, 26,239, 84, 51,229, 85, + 18,169, 12, 28, 47, 45,179, 41,249,224, 29,154,219, 41,130,188,211,241,229, 69,179, 37, 82, 41,241, 10,171,119,236,153,145, 47, + 94,176,119, 20,207, 78, 56,115,168,219,171, 95,183,181, 89,173,104,210,182,219,182,103, 70,190,120, 81, 34,145,224,252,249,243, + 81,174,162, 57, 4,176, 14,120,110, 42,239,225,161, 46, 28, 52,104,208,117,187,230,141, 95,231, 23, 62, 59,110, 6, 4,169,162, +112,228,200,145,142,209,133,231,126,122,191,112,192,115, 83,229, 4,229, 55,123, 95,208, 5, 79, 95,247,203,149,218,175,191,254, +186,113,216,176, 97, 14,205,203,151, 47, 71,245,235,215, 79,245,222,123,239, 25,157, 53,221, 73, 39,224,222, 40, 66,149, 74,101, +126,230,153,103,174,151, 53, 50,145,193, 96, 48, 42,111,176,172, 86, 88, 45, 69,125,176,204,102, 51,172, 86, 43,150, 46, 93, 90, +194, 12, 73,165, 82,112, 28,231,210, 96,109,220,184,177,196,228,158,205,155, 55,167,148, 82, 60,245,212, 83,142,230,198,145, 35, + 71, 98,244,232,209,149,238, 68,107,177, 1,179,230,124,234,208,233,221, 61, 14,253, 31,235, 8, 42, 22, 25,181,244,243,155, 42, +229,216, 42, 50,108,142, 8, 22, 40, 64, 41, 10, 11, 10, 88, 73,122,200,152, 76,166, 93, 11, 22, 44,136,120,235,173,183,100,217, +217,217,200,204,204, 68, 78, 78,142, 99, 41, 44, 44, 68, 80, 80, 16,126,251,237, 55,115,126,126,254,209,255,210,177,223,186,117, +235,171, 45, 91,182, 96,223,190,125,131,167, 79,159, 46, 9, 10, 10, 34, 94, 94,105,196, 98, 54, 1,160, 52, 35, 35, 67, 84,105, +188, 83,253, 3,195,238,164,220, 77,143,182,152, 77, 16,109,230,114,123,102,239, 77,160, 31,134,135, 6,242, 71,247, 31,171,249, +217,188, 47, 10,237,166, 69, 34,145,160, 93,159,145,167,223,252,104, 89,252,130, 47, 22,152, 94,124,233,229,139,149, 25,245,119, +209, 16,242,250,149, 43, 87,106,207,156, 57,211,232,172,217,253,149,121,107,250,244,233,163,250,248,227,143,141,246,117, 28,199, +225,201,233, 95,175,137,139,139, 83,213,171, 87,239,186, 43,109,231,209,142,246, 79,251,122,231,117, 15,114, 20,161, 66,161,168, +210,136, 71, 6,131,193, 12, 86, 9, 36, 2,151,119,237,118,170, 87, 53,181, 18, 86,209, 8,155,169,104,106, 5,155,205,134,151, + 94,122,201,177,223,208,161, 67,241,236,179,207,218, 59,148,150,124,130, 37,164,155,171,185, 50, 68, 81,196,193,131, 7, 75,140, +254,169,168, 2, 43, 79, 83,107,180,225,208,143,239, 66,164,128, 88,228,123, 64, 65,220, 26, 53, 88,150,166, 43,195,166,240,240, + 1, 7, 10,240,192,205,228,116, 8, 60,151, 87,217, 99,175, 44, 76,243, 79, 77,185, 92,190,230,135, 31,126,232, 29, 23, 23, 87, +163,113,227,198, 92,118,118, 54, 10, 11, 11, 81, 88, 88,104,143,114,225,210,165, 75,226,237,219,183,147,229,114,249, 15,255,165, + 99, 47,126,253,205,130,224,224,224, 93, 51,102,204, 24,145,153,153,249,120, 78, 78,174,223,207,223,206, 70,175,167,199,146,142, +189,135,106, 77, 84, 80, 36,165,166,213,219,187,237,123,223, 95,215,126, 5,179,201, 52,154,144, 69,151,237,211, 52,148,214, 20, + 33,152, 60,188,124, 45, 74,165,146, 58, 27, 20, 65, 16,224,225,229,107,241,246,169,102,114, 54, 52,101,141,164, 43,239,216,203, +210,180,175,255,167,104, 86,102, 20,161,253,183,216,181,201, 52,153, 38,155, 11,171, 74, 6,139,218,232,132,197, 63, 31, 93, 96, +177,137, 94,246,117, 13, 26, 52,128,217,108,198,111,191,253,230, 48, 30,130, 32, 56,230,134,113,167, 15, 86, 41,238,116,232,208, +161,162,169, 24,238,184,119,166,113, 39,182,243,160,234, 21,109,175,108,194, 92, 25,182,101,123,207,255,153,137, 28,151, 7, 74, + 39,176,226,244,240,136,142,142,182, 29, 62,124,120,210,216,177, 99, 63,235,218,181,107,104,255,254,253,165,225,225,225,144,203, +229,184,121,243, 38, 14, 28, 56, 96,190,117,235, 86,178, 78,167,155,212,184,113,227,255,228, 72,203,212,212,212, 43,197,147,136, +254,207, 62, 21,131, 92,161,148, 14, 29,245,106,152, 99, 20,225,218,175, 96, 52,232, 1, 64,168,104,154, 6, 59, 30, 30, 30, 50, +251, 40, 60, 65, 16, 28,163,240, 60, 61, 61,101,231,207,159,119,140, 4,172,204, 40,194,135,169, 41,145, 72,170,164,233,206, 40, + 66,137, 68, 34,187,116,233, 18, 27, 69,200, 96, 48,238,207, 96,221, 73, 78, 94, 5, 96,149,243,186,199, 31,127,188,176, 95,191, +126, 74,251,136, 66,251,104, 64,147,201, 4,147,201, 4,133, 66, 81,169, 9,161,220,153, 68,212, 29,210,207,109,170,241, 64,115, +197, 13,195,150,146,146, 82,131, 21,159,191,151,182,109,219,166, 94,190,124,121,216,206,157, 59,135,238,223,191,191,155, 78,167, +139, 32,132, 64,169, 84, 38,152, 76,166, 93,114,185,124,205,127,213, 92,149,135,217,108,182, 78,159,245,201,119,188, 32,181,138, +162,153,152,205,230, 81,112,243,165,238, 0, 48,102,204,152, 50, 71,202, 13, 31, 62,188,202, 35,232, 30,166,102,241,107,113,254, +146, 81,132,197, 29,219, 89,223, 43, 6,131,113,127, 6,171, 44,116, 58,157, 55, 33, 68, 72, 73, 73,185,103,155, 84, 42,197,237, +219,183,173,255,133, 76,121,224,134,141,241,151, 17, 29, 29,109, 43,126, 16, 88, 85,250,101,207,143, 2,148, 82, 35, 33,100, 10, + 33,228,227,226, 85, 83,110,253, 62,223, 49, 90,144,144, 5,231,156,183, 85, 16,189, 74,170,226,203,139,147, 42,218,246, 79,215, +148, 74,248,116,167,151, 58,223,179,205,197,111, 38,177, 43,144,193, 96, 60, 16,131,181,119,239, 94, 43,128,202,152,168,244,191, + 32,205,233,236,180, 61,218,172, 91,183,206,198,114,161,132,201, 90, 72, 8,249,198,110,184,220,221,230, 76,114,114,242,186, 7, +157,174,127,131,230,207,151,173,129,127,199,113, 48, 24, 12,102,176, 24, 12,198,191,195,100, 25,171,178,141,193, 96, 48, 24,127, + 13, 4, 64,195,114, 42,229,243,110,139, 16,210,176, 10, 55,132,243,255, 32,205,128, 10, 52,119,185,208,236, 86,133,116, 50, 77, +166,201, 52,153, 38,211,100,154,143,164,166, 43,237,255,204,232, 68, 90, 60, 27,249, 95,177, 0,104,248, 47,209,236,198, 52,153, + 38,211,100,154, 76,147,105, 50,205,191, 79,243,191,182,176, 25,243, 24, 12, 6,131,193, 96, 48, 30, 48,101,246,193,170, 22, 51, + 0, 92,169,121,207, 69, 10,100, 92,216, 84,165,253, 0, 96,214,172, 89,247,101,230,222,121,231, 29,183,222,210, 92,173,225, 0, +112,110,140, 33, 19, 9,144,113,126,147,219,191, 79,106, 12,120, 11, 34,222, 40,250, 7, 31,209, 59,155,102,178,226, 83, 53,154, +106,136,191,133, 72,250,120, 40, 36,253, 34, 60, 36,109,110,230, 26, 15,235,204,226, 86, 74, 44,155, 47,230,211, 28,150, 67, 12, +198, 95,143, 79, 84,187, 97,126,254, 65,163, 69, 74,149, 0, 96, 50, 25, 44,201,137,119,230,211,156,139,107, 75,212,125,190,245, + 7, 6,133,132,141, 87, 42,212,202,162,234,143,152,178,179,238, 46,204,185,117,232,251,135,149, 86, 82,252,238,180,208,208, 80, +239, 67,135, 14,213,104,215,174,221,237,228,228,228, 92,231,125,202,218, 70,157, 95,166, 89,134,102, 96, 84,179,103, 60, 52,234, +151, 13, 70, 99,164,151,167,103,122,118, 86,214,226,212, 91,167,191,178,239, 83,163, 70, 13,207,181,107,215, 6, 15, 29, 58, 52, + 37, 62, 62,190,192,149, 38,131,225,210, 96,113, 4, 88,183,110, 45, 40,165,197,147,108, 82, 12, 29, 50,180,204,253,194,229, 41, +145,162, 40, 62, 11, 96, 56,165,244, 76,138, 37,252,169,170, 36,100,247,238,221,161, 22,139,165,133,213,106,109, 6,160,153, 82, +165,105, 98, 52, 26,210, 9,232,115,143, 61,246,216,105,119,117, 56, 10, 44,251,118, 37,102,141,233,244, 11,128,222,229, 92, 88, +179,146,140,161,149, 51, 72, 34,125,243,143,253, 27,228,222, 42,130, 90,205,159,156, 10,224, 31,105,176, 66, 66, 66,148, 0,158, +227, 56,174,171, 92, 46,175, 99, 48, 24, 18, 0,156, 35,132, 44, 76, 74, 74, 74,169, 98,229,198,197,104, 36,207,171,148,170, 94, +193,106, 89,179,212,220,252,100,157, 69, 60, 32, 18,243,199,149, 53, 68,181, 8,145,213, 12,247,222,247, 90,255,184,232,198,209, + 53, 97,187,176, 31, 38,179,185,223,137, 84, 93,191, 37,167,211, 38,213, 34,164,217, 13, 74, 77,110,166, 43, 24,128, 64, 41, 77, + 4,128,176,176, 48, 31, 81, 20,227, 0, 52, 1,112,134,227,184, 3, 73, 73, 73,247,101,216,254, 69,154, 33,162, 40,190, 16, 24, + 24,248,120, 90, 90,218, 47, 28,199, 45,175,234,249,102, 60, 26,248,250, 5,189,252,229, 55,235, 29,211,214, 83, 81,148, 12,233, +223,105, 4,128, 18, 6,203,219,219,239,185,111,215,252,170, 36,127,190, 97, 67, 54,110,212,192,209, 0, 30,138,193, 34,132, 16, + 74, 41,102,205,154, 69,150, 45, 91, 54,178,122,245,234,181, 41,165, 87,103,206,156, 57,223,121,191,210,219,222,121,231, 29, 90, +252, 93, 90,150,102, 84, 76,251,205,207, 63, 59,184,211,132,177,207,105, 84, 74, 37,244,122,131,223,162,101, 43, 63,249,106,249, +170, 62,207, 62,213,173, 23, 0, 44, 93,186,116, 64,120,120,120,132,201,100,138,159, 57,115,230,202,138, 52, 25, 12,183, 12, 86, +177, 75,199,245,203,103,240,203,207,219,112,252,204, 37,136, 78,197,169, 65,131, 6,106,153, 76, 54, 48, 76,198, 61,215,168, 89, +155,246,253,158,126,142, 88,136, 10,115, 38, 15,173,244, 60, 88,167, 78,157,146,167,166,166,206,142,172,215,252,213, 78, 61,250, +115,245,163,235,193,223,207, 7, 34, 39,195,138,223,174,249,237, 93, 50,242, 75, 0,109,220,246, 65, 4,120,113,228, 51, 8,149, +161,247,143,219,142, 33, 53,215, 6, 66, 0, 66,138, 12, 97,161, 65,196, 27,163,218,191, 83,121,131, 68, 56,111, 21,193,196, 53, + 6, 0,224,255,137, 39, 51, 56, 56,184,153,159,159,223, 87, 35, 71,142,244,169, 83,167, 78,176, 76, 38, 83, 25, 12,134,218,119, +238,220,137,252,236,179,207,186, 7, 7, 7,127,144,154,154,186,161, 50,154,209,222,138,234,143,213,171,241,227,180, 49,207,181, +172, 27, 17, 14,193, 88, 8,209,168, 13,191,125,235, 70,155,185,223,110,120, 49,198, 75, 50,228, 66,158,197,237, 14,137, 10, 15, +233,155,111, 60, 63, 52,186,150,154,194,116,254, 16, 36, 60, 15,133,167, 15, 90,241, 60, 56, 66,235,191,115, 32,249, 13, 0,239, +184, 81,233,190, 11,224, 13, 0, 68, 42,149,110, 8, 12, 12,188,218,182,109,219,198,131, 7, 15, 38, 13, 27, 54,196,153, 51,103, +154,254,252,243,207,163,194,195,195,207, 90, 44,150,223,213,106,245,209, 27, 55,110,184,101,220,106,213,170, 37,211,106,181,173, + 37, 18, 73,231,127,178,102, 72, 72,136,210,100, 50, 61, 27, 22, 22,246, 82,191,126,253, 26,245,237,219,151,212,173, 91, 23, 87, +174, 92,105,254,235,175,191,190,211,164, 73,147,115, 73, 73, 73, 75,101, 50,217,119, 41, 41, 41,110, 77, 2, 60,184, 33,185,178, +246, 60,173, 87,213,237,165,206,145, 55, 0, 37,165, 52,197,141,125, 3, 1,168, 41,165, 55, 31,182,230, 95,244,160,115, 9,128, +175,253,165,245, 28,199, 57, 94, 96,239,252,105,255,219,102,179,105,239,220,185, 83,211,133,102, 93, 81, 20,221,110, 9, 32,132, +208,212,212,212, 43,229,214,241,160, 50, 0,152,251,206,100, 36, 39,222,134,222,160,213,231,230,102,173, 40,189, 95,110, 78,246, +170, 23,134,247,249,159, 76,166,144,132,134,215,192, 27,179, 62,129, 61,234,245,176,152, 53,107, 22,121,231,157,119,176,116,233, +210,190, 0,226, 40,165, 7,162,163,163, 23,148,186,103, 57,182,189,243,206, 59,243,103,205,154, 69, 0,148,105,132,170, 69, 53, + 25, 49, 98,200,128, 78,175,191,246,178,198,190, 78,169, 84,224,181,255,141,150,233,141,166, 54,139,190, 94,249,210,252, 57,211, +150, 1,232, 2, 32,150, 82,122, 2,192,202,138, 52, 25, 12,183, 13,150, 72,129, 95,126,222,134,215,166,191,141,111, 86,124,135, +239, 62, 28, 77, 98, 99, 99, 59, 80, 74,159,139,136,170, 53,240,201, 97,163,149, 17,181, 27,162, 80,244, 68,124,166,136, 83,191, +175, 65,233, 39, 31, 87,108,223,190, 61,150, 82,124, 59,118,250,103,245, 26, 55,109,129,243,201, 86, 28, 74,180, 65,123,195, 6, +129,215, 67, 20, 43, 63,196,220,222,236,215,188,121,115, 36,229, 88,113,224,138, 9, 60, 7,112, 92,209, 11, 93,121, 82,197,156, + 18, 77,215,102,127,123, 42, 38, 51, 77, 4, 68,211,181,127,218,137, 12, 13, 13,237, 18, 21, 21, 53,239,127,255,251, 95, 80,106, +106,170,239,241,227,199, 33,151,203,225,227,227, 35,248,249,249,213,155, 62,125,122,222,220,185,115,167, 4, 6, 6,158, 78, 75, + 75, 75,112, 71,179,129, 70, 22,221,177, 89,204,225, 25, 51,223,241, 50, 29,251, 21, 57,107,214,129,231, 40,164,106, 13, 66,148, + 74, 44,232, 17,225, 59,109, 79,226,134, 70, 74,101,244, 57,189, 62,217, 29,205,240, 0,223, 30,181,235,214, 67,206,198, 47,113, + 61,223,136, 35, 25, 70,244,239,216, 18,181,124,149,104, 98,181,193, 79, 33,116,113,101,176, 8, 33, 62, 0,166,153, 76, 38, 78, + 42,149, 18,133, 66, 49,112,197,138, 21,123,234,214,173,107,176,239,211,186,117,107,180,110,221,154,104,181,218, 38,135, 14, 29, +106,178,113,227, 70,115,112,112,240,193,212,212,212,121,229,233, 42,149,170, 59, 6,131, 62, 92,165, 86,155,150, 47, 91,182,187, +117,235,214, 84, 34,145,224,126, 52, 1, 32, 40, 40,104, 67, 68, 68,132,255,156, 57,115, 10, 90,182,108,249, 64, 52, 35, 35, 35, +119,196,197,197,117,238,209,163,135,208,174, 93, 59,132,132,132, 56,182,249,251,251, 35, 46, 46,142, 36, 38, 38, 54, 62,112,224, +192,194, 29, 59,118, 44,136,140,140,252, 61, 62, 62,190,135,171,243, 67,129,186,247,179,189, 20, 60,128,185,132,144,101,148,210, + 67, 21,156,207,102, 0,134, 1,248,240,111,210,172, 16,165, 82,153,102, 48, 24, 2, 0, 64,161, 80,164,235,245,122,151,115,103, + 17, 66, 52, 31,125,244, 81,128, 84, 42, 5,207,243,176,217,108,142,133, 82, 10, 81, 20, 75,116,134,253,240,195, 15,221,154,219, +237,238,221,187, 90, 20,141,254,166, 78,139, 88,214,103, 68, 68,132,191, 59,154,201,137,183,225, 97,137,207, 10,244, 80,214,136, +244,240,158,221,174, 93,187,217,206,219,219, 70,123, 1,200,135, 94,127,247,118,114, 34,252,254,134,186,205,123,217,178,101,207, + 46, 93,186,180, 63, 33, 68, 91,156,191,141, 94,125,245,213,223, 75,229,121,163,226, 79,109, 72, 72,200, 94, 66,200,214,208,208, +208,111, 1,220, 19, 29,246,210,120,140,158, 52,238, 69,205,255,217, 59,239,168, 42,174,181,141, 63,123, 78, 47,244, 94, 5, 20, +164, 8, 54, 64,196,138,189,196,222,141, 37, 38, 26, 75, 98, 55,150,104,236, 81, 99, 76,108,177, 37,246, 30, 77,236,189,247,138, + 21, 4, 20, 5,164,247,126,250, 57,179,191, 63, 0, 47, 26,133, 3,122,111,242,153,249,173, 53, 11,157, 51,243,204,158,153, 61, +123,158,121,119, 3,128,121,251,179, 48,119,127, 38,190,235,105,133,169,159,200, 49,108, 80,111,249,230,237,191,143, 4,240, 91, + 57,237,104, 95, 95, 95, 18, 21, 21,197,153, 43,142, 15, 19,193,186,253,224, 9, 54,111,221,134, 65,131, 6, 35,226,236,134,227, +157,122, 14,233,216,184, 69,123,232,133,118,136,206, 32, 72,140,163,224,243,244, 96,192,226,197,157, 67,148, 97,152,109,111,104, +188,115,216,132,227,199,143, 79,170,225, 89,127,201,183,115, 23,243, 30,167,139,176,229,138, 18, 6,117, 62,148, 89,177, 40,206, +120,138,194,180, 39,200, 75,126,252,136, 97,152,185,198,106,254,245, 28, 0,150, 82, 16, 74, 74,138, 28, 80,252,165,209, 24,140, +236, 18,170, 45,142,170,233,237,239,159, 43, 50, 0,218,226,168,202,143,253,225,187,153,190, 75,211,201,201,169,157,187,187,251, +143, 35, 71,142,116,121,244,232,145,153, 66,161, 40,190,117,235,214,165,212,212, 84,123, 27, 27,155,196,254,253,251, 55,177,183, +183,183,107,209,162,133,236,212,169, 83, 51, 1, 12,175, 76, 51, 64, 46,242,111, 30, 28,112, 99,225,210,159,228, 89,251, 86, 67, + 19,251, 16, 55,178,148,120,148,173,164,206,166,121,164,159,175, 21,100, 34, 62, 70, 6,218,155,140, 63, 21,247, 67,233,203,172, +210,115,247,112,180,175,165, 83, 42,160, 82,234,112,252,121,190,242, 70, 65,190, 29,243,240,101,230,212,174,193, 18, 94,102, 10, + 28, 76, 4, 94, 85,189,158,132, 16, 72, 36,111,159, 30,206,194,194, 2,161,161,161,168, 89,179,166,112,224,192,129,173, 1,172, +120,151,166, 86,171,113,100, 89, 10, 51, 51, 51, 97,155, 54,109, 8, 33,132,190, 57,129,121, 85, 53, 1, 64, 46,151,119,168, 95, +191, 62,111,247,238,221, 69,105,105,105,241,159,124,242, 73,150, 68, 34, 97,223,216, 6,110,110,110,248,234,171,175,132,195,135, + 15,175, 84,211,222,222,190,221,142, 29, 59, 64, 8,121,245,226,126, 19, 55, 55, 55, 56, 56, 56,160,115,231,206,252,222,189,123, +183,171,232,122,246, 15, 32,209,101,230,169, 95, 0,169,240, 37,210, 47,128, 80, 2,196,188, 25,201,122, 83,147, 82,154, 77, 8, + 89, 15,224, 0, 33,164,207,219, 12, 17, 33,164, 41,128,253, 0, 58, 81, 74, 51, 42,187,239,229, 53, 69, 34,145, 80,171,213, 90, +190,105,124,170,170, 89, 62,226, 19, 30, 30,142,192,192, 64,148,255,171, 82,169, 94,205,189, 74, 8,177, 51, 54,127,242,120, 60, +252,252,243,207,224,241,120, 16, 10,133, 16,137, 68,111,253, 27, 28, 28, 92,213, 50, 36,145, 16,194,212,168, 81, 99, 26,143,199, + 27,174,209,104, 92,196, 98,113,138,193, 96,216,106,101,101,245,125,120,120,184, 14,128,197,219,230,134, 45,175,169, 84, 21, 43, + 41,203, 74, 53, 26,149, 78, 42,151,186, 93,187,118,173,246,187,238,185, 90,173, 70,155, 54,109,144, 94, 88,156, 89,182,207,255, +170,172,187,118,237,154, 91,141, 26, 53,188, 1, 52, 47, 93,117, 57, 57, 57,185, 69,185,255,151,231,114,114,114,114,167,210,127, +199,188,124,249,210,173,204, 96,149,215,212,104,180, 30, 38, 38,114, 0,192,220,253,153, 80,239,168, 5,241,224,231,248, 60, 68, + 13, 83, 83, 83, 24, 12,122,239, 9, 19, 38,108, 67,201, 51,113,135, 82,218, 99,194,132, 9, 62, 0,206,187,185,185, 29, 4,144, +255,191, 46,231,255, 13,154, 31,165,193, 42,173, 82, 46,171, 90, 38, 44, 5, 6, 14, 24, 8,150, 2, 39, 79,158, 4, 91, 82,118, +155, 37, 41, 45, 80, 20,103, 3, 62,195,130,207, 35,224,243, 0,128, 32, 59,233, 9, 52,197,217, 87,147, 52,206,113,172, 17,254, +254,228,201,147,161,238,126,141,126,152,187,112, 25,179,249,178, 18,249, 10, 21,178, 34, 15, 35,245,246,166, 84, 86,175, 61,204, + 48,204, 93,134, 97,238, 53,172, 87, 55,218,209,209,177,218,163,118,179, 20, 48,148, 55, 86, 44, 64, 62,178,232,174,139,139, 75, + 39, 79, 79,207,197,163, 70,141,114, 11, 15, 15, 55, 45, 44, 44,204, 60,123,246,108,180, 86,171,189,207, 48,204,202,148,148,148, +150, 59,118,236,144, 77,157, 58,181,189,183,183,183,247,233,211,167, 21,149, 70,174,228,194,122, 67, 62,237,127,163,251,168,113, +146,200,223,215, 64,252, 36, 28, 27,158,230, 26,238,102, 42,103,170,138,244, 43,164, 50,126,211, 92,181,254,204,148, 16, 39,198, + 81, 46,128,171,153, 32,204,216,244,138, 68, 18, 62,229, 75,160,209,232, 81,172, 99, 53,145,153,180,120, 82,203,186, 90, 42,183, +145, 0, 0,159, 97,248, 70, 60,216,185,132,144, 31, 68, 34,209, 44, 66, 8,237,222,189,123,124,195,134, 13, 85, 0,160, 84, 42, +161, 86,171, 33, 16, 8,160, 82,169,240,226,197, 11,220,188,121, 19,150,150,150, 85,186,174,185,185,185,112,115,115,131,137,137, +201,123,107, 26, 12, 6,178,102,205, 26, 81, 68, 68,132,232,143, 63,254, 48,155, 50,101, 74,113, 72, 72, 72,194, 39,159,124,146, + 97,102,102,166,127,240,224, 1,110,220,184,129,188,188, 60, 52,106,212,200, 40, 77,141, 70, 3, 62,159, 15,165, 82, 9,177, 88, + 12, 62,159, 15,189, 94, 15,150,101, 95,153,174,162,162, 34,228,228,228, 64, 40, 20,226,109, 70,177, 60,101,102,169, 95, 0,161, +191, 31,191,158, 1,176, 20,154, 66, 29, 52,249, 58,168,203,150, 92, 93,191,137, 63,213,255,253, 49, 37, 85, 40,132,111, 18, 66, +250, 0,216,255,166,201, 42,103,132,250, 80, 74, 31, 84, 85, 83,171,213, 94, 45, 51, 62, 18,137,196,142,144, 18, 99, 40, 22,139, +117,106,181,186, 85, 85, 52, 1, 32, 60, 60, 28, 13, 27, 54,228,149,106,150,111,102,195, 86,245,185, 36,132,128,199,227, 65, 44, + 22,131, 97, 24,132,132,132,160,119,239,222,240,245,245, 69, 98, 98, 34, 78,159, 62,141,168,168, 40, 8,133,194,215,170, 10,141, + 33, 44, 44,140,231,225,225,113,189, 93,187,118,254, 99,199,142,149,184,185,185, 33, 58, 58,186,198,218,181,107,167, 93,189,122, +181,123, 96, 96, 96, 80,120,120,120,165,105, 78, 75, 73, 90, 61,160,123,216,103,121,185, 57, 59,106,248,154,207, 85,171,213,120, +242,228,137,209,251,252,175,202,184,166, 77,155, 38, 80, 74,159, 81, 74,175, 16, 66,234, 38, 39, 39,183,112,118,118, 62, 65, 41, +149,191,113,205,139,147,147,147, 59, 57, 59, 59, 23, 80, 74, 31, 17, 66, 98, 8, 33, 9, 73, 73,127,157,209,200,194,220, 44,179, +168,168,216,222,196, 68,142,153,221, 45, 32, 30,252, 28, 99, 91,241,160,211,233,240,226, 69, 60, 60,220, 93,201,158,205,135,130, + 0,220, 1, 16, 28, 30, 30, 14, 0, 65, 0,226, 18, 19, 19, 29,203, 12, 22, 7, 71,149, 35, 88,111,246, 2,180,171,219, 3, 53, + 68,188, 94,143, 79,174,184,233,165,165,110,246,254,159,148, 70,162, 75, 34,213, 9, 15, 78,130,101,217,173,233, 70,244,202,187, +113,227,134, 68,207, 98,243,212,111,231, 51, 27, 46, 40,145,158,150,130,148, 75, 75,161,204,120,178, 69, 42,149, 78,110,211,177, + 75, 65,117, 78,164,124,143, 70,103, 97,146,191,133,181, 3,212, 90, 90,106,176, 94, 55, 89, 31, 11, 78, 78, 78, 93, 61, 61, 61, +231, 31, 62,124,216, 77,169, 84,154, 94,187,118, 45,239,204,153, 51,207,180, 90,237,198,212,212,212,157,165,133,206, 97, 62,159, +191, 0, 0, 76, 77, 77,249, 60, 30, 79, 90, 81, 35,205, 0,115, 97,195, 97,159, 13,186, 58,105,229,111,146,103,143, 31, 96,229, +254,227, 16, 27, 52,134,200, 92, 77,143,199,133,186,163,165,155,157,239,236, 36, 75,166,160,174, 2,134,192, 74, 42,116, 8, 37, + 68,114,131, 82, 85,101,105,182,113,117, 99,116, 53, 60,112, 69,175,130,137,169, 80, 4, 0,206,181,253,120,247,149, 58, 92,123, +248, 4, 18,137,165,208,200,151,236,108, 59, 59,187,198,151, 46, 93, 34, 69, 69, 69,170, 71,143, 30,193,202,202, 10,246,246,246, + 48, 55, 55,199,147, 39, 79,112,238,220, 57,196,196,196,128, 82,138,122,245,234, 85,233,218,166,167,167,163,160,160, 0, 61,122, +244,108,157,146,146, 44,177,179,119,208,156, 63,119,246,108,117, 52, 89,150, 37, 0,224,239,239, 15,127,127,127, 65,114,114,178, +197,209,163, 71, 77, 22, 47, 94,236,100,107,107,123, 71,169, 84,190,102,156,140, 53, 88, 0,160, 82,169,160, 86,171, 33, 20, 10, + 33,145, 72, 32, 20, 10, 81, 80, 80,128,244,244,116, 20, 22, 22,190,138,184, 25,171,251,234,211,100,123,179,187,127,205, 28,159, +217, 85,243, 75,247, 90,169,201, 58, 79, 8, 41,187,191,233,165,127,251, 84, 84,213, 87,137,230,107, 17,150,114, 81, 38, 65,117, + 52, 3, 3, 3,203, 52, 94, 43, 37, 36, 18, 73, 70, 89,228, 74, 34,145, 24, 53, 85, 23, 33, 4, 44,203, 66, 40, 20,162, 94,189, +122,152, 57,115, 38, 34, 35, 35,113,225,194, 5, 56, 58, 58,162,107,215,174, 16, 8, 4,136,143,143,127,173,125,150, 49, 55, 39, + 62, 62,126, 90,251,246,237,253, 87,174, 92, 41, 73, 72, 72, 64, 84, 84, 20,204,204,204, 48,127,254,124,241,244,233,211, 61,175, + 95,191, 62, 27,192,143,149, 94,195,156, 39,251, 75, 13, 46, 26, 52,104,240, 89,155, 54,109,254, 90,174,218,218,154,239,222,189, +219,174,204,120,149,223,231,127, 69,114,114,114,222,220,185,115,151,251,250,250,174, 40,173, 22,108, 78, 41,149,167,164,164,132, +237,223,191,159, 0, 64,159, 62,125,168,147,147,211,197,210,188,241,104,197,138, 21,173,162,162,162,232,220,185,115,223, 90,206, +165,102,164,174,255,113,213,134,229,115,103, 76, 20,125,211, 89,134,207, 67,212, 96, 89, 22, 60, 30, 15, 43,215,109,214,197, 68, + 62,122, 24, 20, 20,116,148, 82,218,163, 52,154, 89, 4, 32,134, 16, 18, 39, 18,137, 82, 94,188,120,193,185, 7,142, 74, 97,202, +135,199,223,181, 81,198,163,131, 96, 89,214,209,194,214,217,106,228,167, 29,192,178,128,158, 5,244, 6, 10,165,162, 24,105,209, + 23, 20, 26,141,198,168,135, 46, 59, 59,123,193,176, 9, 75, 60,239,190,228, 35, 53, 87,131,164,115,243,169, 58, 43,186,119,215, +174, 93,135,183,105,211,166,160,218, 39, 82,218,243,209, 89,152,228,111,105,227,116,241,187,165,155,112,231,133, 6, 44,253, 79, + 36,203,192, 2,236, 71, 18,192,114,118,118,246,178,180,180, 92,118,248,240, 97,119,145, 72,100, 26, 27, 27,107,184,120,241, 98, +138, 78,167, 91, 91,102,174, 74, 77,216,160,128,128, 0,157, 76, 38,131, 66,161, 80,233,116,186,162,119,153, 43,127,169,212, 37, + 48, 32,224,242,164,149,191, 73, 84, 26, 13,242,149,106,216, 58, 58, 24, 30,229, 42,122, 60, 42, 84, 31,125, 21,225, 50, 21, 52, + 9,170,229,236, 76, 36,166,160, 0,146, 11, 53, 41,198,152, 43, 0,144,155,154, 51, 46, 65, 97, 8, 26,191, 26, 74,158, 57, 5, + 0, 75, 59, 39,166,213,152,239,209,113,229, 37,168,249,166, 70, 91, 96, 62,159,175,246,242,242, 82,149, 22,170,200,206,206, 70, +100,100, 36,114,114,114,176,122,245,106, 68, 71, 71,191,122,233, 86,205, 96,188,122,137, 35, 51, 51, 67, 76, 41, 69, 70,122,154, +168,186,154,101, 6,171,220,189,195,232,209,163,249,197,197,197,146,242,230,170,170, 6,171, 44, 29,148, 82,104, 52, 26,228,231, +231, 67,163,209,224,217,179,103,175,204, 85,105, 4,173,106,231,175, 41,212,189,117,189, 42, 71,247, 30,213, 9,215, 0, 8,203, + 13, 82,104, 95, 93,115,245,134,241,169, 82,244,167,178, 8, 22,222,210,128, 89,169, 84,218, 83, 74, 73,120,120, 56,140,105,127, + 85,222, 96,137, 68, 34,244,237,219, 23, 17, 17, 17, 72, 76, 76, 4,159,207,135, 74,165,130, 74,165, 66,163, 70,141, 32, 18,137, +170, 26,193,162, 2,129, 96,208,216,177, 99, 37,113,113,113,200,202,202, 2,195, 48,208,235,245, 48, 24, 12, 24, 62,124,184, 84, + 36, 18, 13, 66, 21, 27, 98,223,191,127,191,195,181,107,215,188,223, 92, 50, 51, 51,243,197, 98,241, 63,178, 12,220,191,127, 63, +233,211,167, 15,237,211,167, 15, 45, 51, 90,198,146, 25,247,120,253,206, 61, 7,207,204,156,187,180, 40, 43, 59, 7,114,185, 28, +153, 89,217,248,110,193, 50,221,133,171,183, 47,142, 30,254,105,232,242,229,203,151, 0,136, 41,221, 37,102,197,138, 21, 67, 71, +140, 24,177,189,108,184, 6, 14, 14,163, 35, 88,101, 85,132,239,248,178,107, 96, 97,227,124, 97,198,162,223, 76, 14, 60,228, 33, + 55, 53, 6,170,140, 24,184, 54,236,142,244,152,107,160, 6,221,159,145,145,145,197,149, 29,236,212,169, 83,181, 93,189,131,198, +215, 15, 12,193,210, 99, 69, 40,138,220, 3, 77,110,220,186, 46, 93,186, 28,124,223, 19, 97, 41, 48,105, 80, 19,127, 75,107,199, +139,223, 46,249,205,234, 72,132, 0,217, 41, 49,136, 62, 52, 13, 6,237, 95,106,197,142, 87, 85, 95,202,106, 68, 69,121,233,208, + 20, 26, 32, 97, 20,146,191,251,198, 37, 39, 39, 63,243,247,247,223,246,235,175,191,142,170, 87,175,158,108,252,248,241, 79, 11, + 10, 10, 22,166,164,164,252, 94,238, 69,222,186,102,205,154, 83,230,207,159,239,249,242,229, 75, 92,190,124,249, 25,143,199,187, +243, 46,205, 8,165, 50,169,174,185,120,237,213, 93, 27,191,225,185,121, 99,239,220,169,250,235,143,159,116,139, 44,212,159,120, +101,174, 76, 68,190,161,254, 94, 71,191, 30, 59,138, 49,220, 59,137,232,196, 12,164, 22,235,206, 25,157,238, 66,133, 78, 32,150, +194,196,193, 29, 9, 42, 86,232,226,226,114,123, 68,207,174, 66,134,199, 7,195, 23,226, 69,158,218,232,151,184, 94,175, 23, 63, +121,242,132, 0,120,205,220,169, 84,170,119, 70,124, 62, 36,198,106,190,173,125, 20, 0,232,116,186,106,107,150,143,216, 84,118, + 44,150,101,161, 86, 87,161,175,136, 58,239,237,247, 64,153,165,251, 16,151,173,244,175,232,125,204, 85,153,241, 41,107,128, 46, + 22,139, 95,153, 20, 99,163, 76, 21, 68,176,170,245,251,219, 12,186, 80, 40,132,143,143, 15, 46, 95,190, 12, 11, 11, 11,152,152, +152, 64, 46,151, 67, 34,145,192,194,194, 2, 34,145, 8, 12, 83,165, 33, 2,169, 86,171,173,225,226,226,130,103,207,158, 65, 34, +145,188, 90,196, 98, 49,124,124,124,160, 80, 40,156,241, 81,197,234,255, 59, 12,237,211,182,251,250, 93, 7,134,236, 61,112,116, +140, 90,165, 10,240,241,246,162, 81,143,239, 61, 28, 61,124, 80, 71,238,234,112,124, 80,131, 85, 65,161,210,192,194,198,249,194, +180,239,127, 53,219,119,143, 65, 94,106, 52, 18, 78,126, 91,104,208, 42,114, 89, 86,231,150,251,252, 42, 0,108, 53,242, 75, 62, +184, 73,235,238,204,197, 40, 13,180,133, 41, 40,136,216, 27, 47, 22,139,167,127,136, 19,113, 21, 37,249, 91, 90, 59, 94,156,190, +248, 55,171, 3, 15,249,200, 73,137,193,243,227, 51,242, 13, 90, 69,235,240,240,240, 87,227,104,217,251,247,192,231,211,150, 99, +243, 15, 19,141,214, 30, 44, 18,117,239,239,103,209,101,120,243, 20, 24,136, 1,131,158, 68,117,114,106, 78,186,167, 92,161,135, +254,206,155, 23, 17, 17,241,189,151,151, 23,163,215,235, 63,215,106,181,115, 83, 82, 82,246,151,139, 92,181,115,115,115, 91,186, + 96,193, 2,151,132,132, 4,209,141, 27, 55,114,238,223,191,207, 26, 12,134, 37, 21,105, 62,202, 87, 79, 13, 48, 21,242,188, 92, +157,198, 62, 75, 74,234,246,184, 64,127,178,236,183, 0,185,200,191,121,125,223,107, 11,230,126,107,170,185,186, 31,197,169,137, + 88, 29,158, 86,192, 26,116, 51,140,140,186, 89,185, 9, 41,153, 49,226, 51,182,176,176, 16, 50,145,144, 77,140,126,206, 27,210, +182,133,225,135,105,147,153,180,180, 52, 40,138,139,249,206,206,206, 86,201,201,201, 57,149, 68, 8,230, 3,104, 93,175, 94, 61, +180,111,223, 62,126,222,188,121, 81,229,205,199, 63,204, 96,189,245,235, 90,171,213,146,234,106,150,143, 96, 85,102,176,170, 28, +193, 82, 23,188,221, 72, 41, 50,223,215, 96,189, 36,132,212, 40,251,247,135,184, 7, 42,149,202,174, 92,213, 32, 40,165,213, 14, +103,149, 70,176,170,253,123,121, 24,134, 1,165, 20, 34,145, 8, 49, 49, 49,112,112,112,128, 94,175,135, 92, 46,135, 76, 38, 67, +105, 68, 25, 34,145, 8,124, 62,191, 42,201,100, 69, 34,209,203,152,152, 24,111, 75, 75, 75, 24, 12,134,215, 76, 86, 92, 92, 28, +228,114,121,114, 85, 35, 88, 13, 26, 52, 56, 37,149, 74,221,222, 92,111,107,107,107,254, 79,125,121,149,143, 92,245,233,211,135, + 78,152, 48,161,202, 26,171,190,255,102, 7,128, 29, 19, 38, 76,216,182,107,227,241,160,160,160,160, 99,190,190,190, 4, 0,184, + 30,131, 28, 31,196, 96,149, 21, 74,101,127,203,218, 51, 57, 11,147, 26, 88, 88, 59, 93,152,178, 96,131,217,174,187, 12,242, 83, +163,144,114,118, 86, 62,171, 85,180,102, 24, 38, 53,241,250,175,251, 1, 40,238,221,187,119,201,214,191, 7, 8, 41,233,185,247, +182,145,220, 75, 11,250,134, 62,181,107, 99, 95,132, 30,170,180,135, 96, 8,221,218,182,109, 91,197,251,158, 68, 96, 96,160,191, +165,181,227,197,169,139,126,181,218,119,159,143,220, 18, 19,152,207,106, 21,173,147,181, 46,175, 13, 82,202, 18, 96,243, 15, 19, +193, 26, 81, 12, 15, 39,196,146, 39,151,172, 29,210, 62,184,159, 91, 45, 23,176, 84, 7, 86, 72,209,107,170, 13, 63,230,158,226, + 96,141,246,188,223,217, 34,118, 76,210,141,191,111,244,241,103,207,158, 45,112,112,112, 56,144,150,150,246,170,117,170,139,139, + 75, 39,119,119,247, 69,243,231,207,119, 79, 74, 74, 50,189,127,255,126,193,254,253,251,227, 24,134,153,159,154,154, 90,233,215, +253,227, 66,237,100,127, 19,209,198,136, 34,253,171, 49,116,234,200,133,245, 62, 27, 50,240, 70,219,129,159, 73,158,159,221, 1, +171,184, 39, 88,121, 47,221,144, 92,168, 26, 24,165,160,105,198,152, 43,177, 88,188,127,245,254,253,207,234,214,173, 75,138,139, +139,161,211,233,144,149,149,133, 31,119,238,139,164,148,194,210,210, 18,103,207,158,101,199,143, 31,191,223,217,217,185,207,187, + 76, 86,185, 97, 26, 32, 20, 10,137, 84, 42,245,136,143,143,143,119,119,119, 87,189,205,164,136,197,226, 42, 27, 44,169, 84, 10, +150,125,119, 16,160, 42,154,122,189,158, 24,179,190, 42,154,101,105, 43,107,220,254,230,250, 50,120, 60, 30, 88,150,173,240, 92, +254,234,222,222, 17,193, 82,100,188,151,193,162,148,186,149,117,164,249,167, 21,132,165,145, 48, 0, 96,223, 53, 20, 67, 85, 34, + 88,165,102, 15, 34,145, 8,151, 47, 95, 70,215,174, 93, 65, 41,133, 88, 44,134, 76, 38,131, 68, 34,193,181,107,215, 32, 18,137, +192,227,241,170, 18,197,162,122,189,126,231, 47,191,252,242,237,226,197,139,165,101,199, 40, 51, 88, 63,253,244,147, 82,173, 86, +239, 52,198, 96, 17,203, 58,253, 45, 44,173, 6,231,229,101,111,109,226, 99, 81, 97, 47,194,183,237, 83,218, 30,235,191, 78,217, + 48, 13,148,210,238,111, 14,197, 80,182,205,132, 9, 19,240,230, 16, 14, 21, 13,211,224,228,228,100,185,113,227,198, 17, 44,203, +214, 41, 93,245,102,111,193,178,251, 88,246,126, 42,235, 85,248, 90, 47, 66, 14,142, 42, 71,176, 24, 2, 56,242, 95,250, 90, 88, +187, 92,152,180, 96,131,217,182, 91, 60,228,167, 62, 65,214,133,239,242,169, 94,217, 58, 60, 60,252,190, 93,221, 30, 8,105,218, +186, 89,219, 79,250,192,254,200, 62,220,185,126, 30, 63,174,222,140,111,198,126, 81,225,135,146,157,157, 53,178,174,171,160,203, +125, 6, 66,200,189,247, 61,129, 70,141, 26,121, 89, 88, 57, 92,156,178,240, 87,171,221,225,124,228,165,252,199, 4,206, 88,115, +225,254, 87, 35,134,190,182,189,177,211,227, 12, 22,137,186,251,215,118,217, 52,160, 83, 83, 75,115,162,135, 62, 33, 10, 27, 63, +235,135,240,174, 90, 52,237,111,142, 70,157, 77,225,217, 64,210,239,248,111, 57,109,156,154,147,225,127,103, 52,171,188,185,114, +114,114,234,234,226,226, 50,239,216,177, 99,110,122,189,222,244,242,229,203,133,251,247,239,127,174,215,235, 87,165,166,166, 30, + 51, 58, 58, 86,164,121,101,174, 2,204,133, 13,135,127, 62,244,234,248, 21,235, 37,145,225,119,176,116,231, 17,152,241,116,134, +187,105,170,190, 17, 69,255,169, 62,172, 48,163,241,249, 11,118,239,222, 45,247,243,243, 35,217,217,217,175, 34, 45, 90,173, 22, +249,249,249, 40, 44, 44,132, 90,173, 70, 64, 64, 0, 51,119,238, 92,249,119,223,125,183, 0,192, 24, 99,211,107,107,107, 11,161, + 80, 8,173, 86,251,202,164,136, 68, 34, 88, 88, 88, 32, 63, 63, 31,103,206,156, 65,101,131, 83, 10,133,162, 84,134, 33,174, 38, +166,166, 58,185, 92, 78,229,114,249, 95,182,169,170,102,169,201,201,236,212,169,147,237,252,249,243, 5,129,129,129,175,214,151, + 85, 17, 86, 71,147, 82,170,104,223,190,189,108,213,170, 85,112,115,115,131, 70,163,121,205, 72, 49, 12, 3,161, 80,136,196,196, + 68, 44, 92,184, 16,148, 82,227, 63,100, 84,185, 58, 4, 12,181,131, 50, 91, 7,101,182, 14,170, 44, 45,138, 51,116,208, 41, 12, +255,180, 2,172, 58, 13,208,141,136,132,217,189,111, 4,171,172,186, 82, 44, 22, 35, 62, 62, 30,167, 78,157, 66,104,104, 40,204, +204,204, 80, 92, 92,140, 43, 87,174, 32, 57, 57, 25, 98,177, 24, 60, 30,175, 74,141,220,107,212,168,241,195,237,219,183,187,142, + 27, 55,174,206,151, 95,126, 41,245,245,245, 69, 92, 92, 28,150, 47, 95,174,122,244,232, 81,172,165,165,229,124,160,242,121,102, +157, 93,107,140,223,184,243,168, 96,216,192, 78, 99,129, 98, 24,211,139,240,245,125,254, 55,141,221,223, 49, 76, 67,167,119,108, + 94,126, 8,135,215,134,105, 40,207,193,131, 7, 61,156,157,157,125, 81,210, 51, 16,248,107,111,193,242,220, 9, 15, 15, 15, 6, +215,139,144,227, 67, 24,172,210, 2,122, 98, 72,239,153,102, 91,111,242,145,155, 28,129,252, 43,115, 94,153, 43,160,164,225,187, + 93,221, 30, 48,176, 20,173, 59,246, 46, 27, 20,244,205, 66, 38,160,252,184, 85, 2,137,105,128,158, 10, 1,168,160,207,123, 14, +145, 72,116,191,170, 9,126, 83,147,101,217,201,141,123,207,180,218,126,135,143,252,148, 39,200,188, 56, 59,159,213, 42, 90, 39, +106, 92,238,127, 53, 98,168, 81,141,218, 9, 33,109,203,198,244, 24, 44, 18,125, 39,224,145, 89,159,180,104, 40,108,214,160, 54, +228, 25,241, 72, 75, 74,193,222, 39,153, 57,177,185,234,225,215,136, 22, 9,207,213, 27, 59,143,176,178,178,116, 16,160,203, 40, +107,171,155, 71, 10, 14, 58,183,102,180, 84, 75, 23,167, 92,165,115,223,212,252, 80, 84,166,233,236,236,236,101,106,106,250,227, +201,147, 39,109, 69, 34,145, 89,100,100,164,225,192,129, 3,137, 6,131,225,167,212,212,212, 61,213,209,244,151, 74, 93,234,120, +123, 92, 26,255,243, 58, 73, 81,177, 2,197, 26, 45,156, 92,157, 13,151,238, 69,245,142, 40,210, 28, 50, 70,211,222,222,190,213, +192,129, 3,235, 5, 6, 6, 50,229,205,149, 70,163, 65, 65, 65, 1, 10, 11, 11, 81, 80, 80,128,130,130, 2, 36, 39, 39,163,105, +211,166,140,175,175,111,128,189,189,125,171,244,244,244, 11,111,106,150, 27,166,225, 91, 0,140, 76, 38,139,185,126,253,186,170, +119,239,222,144, 74,165, 40, 46, 46,134,139,139, 11, 88,150,197,149, 43, 87, 16, 19, 19,147, 7, 96,119, 90, 90,218,217,138,210, +169, 84, 42,106, 16, 66,120,102,166,166,109, 59,116,232, 48,112,248,240,225, 22,229,183,175,142, 38, 0,100,102,102,186, 95,190, +124,249,187,238,221,187,143,237,216,177,163,108,198,140, 25, 2, 15, 15, 15,232,245,122, 82, 93,205,220,220, 92,243,123,247,238, + 45,107,214,172,217, 87, 29, 59,118,228, 47, 90,180, 8,230,230,230, 48, 24, 12,144, 74,165, 40, 40, 40,192,252,249,243,113,245, +234, 85, 61,165,116, 77,126,126,254,148,138, 52, 95, 27, 7,107,210,207,245, 43,202,135,239, 26, 7,235,239,200,243, 74,165,210, +190,170, 81, 49, 99,210,121,239,222, 61,250,230,120, 88, 21, 69,176,222,166, 89, 22, 93,226,243,249, 72, 75, 75,195,209,163, 71, + 95, 27, 3,171,108,121, 87, 21,225, 59,210, 73, 47, 94,188,104, 32,132,132,234,245,250,105, 19, 38, 76, 24,174, 80, 40, 92,228, +114,121,138, 86,171,221,106, 97, 97, 81, 54, 14,150,176, 50, 77,145, 72, 34, 32, 12, 3,169, 68, 46, 85, 42, 51, 19,222,214,139, +240,141,107,157, 32, 18,217, 91,151,237,243,191,186,239,111, 12,211,240,218, 80, 12,111,236,243,218, 16, 14,111, 14,211, 80, 94, +179, 71,143, 30,113, 0,162, 41,165, 12, 33, 36,250,205,222,130,229,100,189,195,195,195,131,131,130,130, 46, 81, 74,101,111,246, + 34,252, 59,242,252,199,172,249,175, 49, 88, 0, 36,215,194,159,130, 17,103,160,240,214,143,175,153,171, 87, 79, 58, 11,220,185, +126, 30, 44, 11,180,104,223,179, 82, 51,163, 87, 23,199, 46,216,251,162,129, 65,163,132,190, 32, 33,166,227, 39,157, 51,222, 39, +241,182, 1, 61,225, 42,164,242,171,247, 98,193,151,100, 35,239,230, 15,121,196,160,110, 29, 30, 30,254,160,218,153, 6,152,177, +238,196,126, 33, 49,183,194,195, 9,195,144,146, 87,140, 19, 47,114,127,167, 10,245,152, 29,180,164, 42,208, 37,148, 92,217, 52, + 51,109,109,243, 94,230,253,108,156, 5,248,249,155,173,144, 76,183, 22, 54,106,211,226,111,157,163,176,172,225,251,198,141, 27, + 71, 7, 6, 6,154,124,253,245,215, 79,243,243,243, 95,107,248, 94, 85, 34,148,202, 36,127, 83,209,186, 11,191,254,252,141,212, + 63, 4,251, 23,206, 48, 92,190, 23,221,227,113,161,230,168,177, 26, 98,177, 56,108,204,152, 49,194,226,226,226,191,152,171, 55, + 13, 86, 65, 65, 1, 30, 62,124,136, 62,125,250,136,163,162,162,194, 0, 92,120, 71, 4,103,118,233,128,147,124, 27, 27,155,204, +117,235,214,117,223,190,125,123,175,225,195,135,139,195,194,194, 16, 25, 25,137,219,183,111,171, 53, 26,205,159, 66,161,240, 80, +124,124,188, 81,173,188, 41,165, 6, 0,167,220,221,221, 47,173, 91,183,174, 59,203,178,175,230,179,124, 15, 77, 29,128,217, 86, + 86, 86,203,246,239,223,191,244,252,249,243, 3,135, 12, 25, 34,209,233,116,228, 61, 52,245, 0, 38,216,218,218,206, 58,126,252, +248,214,211,167, 79,247, 24, 60,120, 48, 51,110,220, 56,172, 94,189, 26,127,252,241, 7,107, 48, 24, 14, 9, 4,130,161,153,153, +153,149,118, 64,121,109, 28,172, 10,198,185,170,236,119, 35,184,251, 95,200,250,239,173,249,102, 36,172, 97,195,134,246,229,123, +105,150,255,107,108, 4,139, 16,130,160,160,160,215,254, 95, 54, 36, 3,143,199,123,109,169, 74, 21, 33, 0, 11, 74, 41, 11, 96, + 13,128,213,120,125, 20,119, 30,254, 51,210,187, 81, 56,187,186, 33, 57, 17,214, 89,197,170,188,138, 39,123,182,183,118,118,117, +251, 59,202,181,188,185,115,231, 46,159, 51,103,206,242, 55,135, 98, 40,191,221,155, 67, 56,204,155, 55, 15,239, 26,166, 33, 37, + 37, 37,119,238,220,185, 63, 0,128,175,175, 47, 41,173, 22, 12, 66,105,111,193,114,154,219, 80, 50, 85,142,236,203, 47,191, 28, + 2,224,157,154, 28, 28, 85, 49, 88,223, 22,133,175,212, 1,176, 38,132,204, 72,214,186, 68,254,181, 16, 1,126, 92,189,249,181, + 73,161, 43,130,199, 99,102,100, 28, 25,182,138, 2,185, 60,130, 25,239,155,120, 75, 11, 51, 24, 10, 13, 51,139,239,173, 98, 41, +165, 22,132,144,233,119,239,222,141,124,111,103,110,110,133,194,249,163,241, 71, 68, 10, 77, 43,214,245,220,161,121, 61, 82, 83, +218,230,170,191, 83,115,178,215,210, 73,112, 96, 66,107,107,114, 44,103,200, 63,226,134, 70, 68, 68, 44,242,242,242,226,173, 95, +191,254,115,141, 70,243, 90,195,247,106,107, 22,106,166, 6,152, 10,121,190, 30,174, 99,163,226, 19,186, 63, 46, 52,174, 90,176, + 28, 34,103,103,231,199, 10,133, 2,132, 16,168,213,234, 87,198,170,176,176, 16,249,249,249,175,254,175,213,106,145,153,153, 9, + 15, 15, 15,148, 27, 51,233, 93, 38, 35,181,188, 71,176,180,180, 60,185,106,213,170,129,171, 86,173,106, 3,224,156, 82,169,220, +157,155,155, 91,173,161, 63, 74,141,206, 94,169, 84,246, 35, 33,196, 89, 44,145,106,174, 94,189,122,226,125, 52,115,114,114, 10, + 1,140,146, 74,165, 11,126,249,229,151, 85, 18,137, 36, 56, 35, 35,227,189, 52, 75,205, 83,111,107,107,107,167,109,219,182,237, +219,180,105, 83, 99, 62,159,127,147, 16,210, 55, 47, 47,175,202,147, 61,147,215,191,222,171,252,187, 17,252,241, 95,200,246,239, +173,105,236,240, 11,198,162,215,235,139,230,204,153,147,241,182,121, 7,203,204, 84,249,117, 90,173,214,168, 97, 78, 28, 28, 28, +140, 30,139,172,162,161,119, 0,128, 33, 68, 9, 64,250,237,188,101,165, 31,204, 70, 79,246, 12, 2,162,249, 95,150,107,115,230, +204,161,243,230,205, 35,132,144, 67, 40, 25,143,234,217,155,141,208,203,255, 54,111,222, 60,204,153, 51,135,206,157, 59,183, 82, +205,168,168, 40, 74, 8, 57, 7, 32, 14, 64,124,121,221,242,235,203,246,169, 72,147,131,163, 82,131,197, 82, 32, 89,235,146, 8, + 96, 88,249,117,127,125,193,225, 47,109,174, 42,242, 88, 29, 59,118, 60, 7,192,247, 67, 37, 62, 47, 55, 31,196,170, 97, 66,110, +110,246,224,140,199,135, 62,136, 38, 11,252, 56,188, 81,216, 55, 0, 8, 5,126,126,211, 92,189,246, 21,116,133, 30,114,108, 74, + 22, 55,106,211, 98, 98,233,203,103,209, 63,225,166,190,173,225,251,251,242,182,134,239, 85,120,217,156, 22,139,197,164,176,176, + 16, 74,165,242,181,104, 85, 65, 65, 1, 20, 10, 5,138,138,138, 80, 54,181, 71, 81, 81, 17, 76, 76, 76,160,211,233,170,244,165, + 88,106, 82,214, 5, 6, 6,110, 44,173, 38,121,111,148, 74,133, 11, 0, 4, 6, 6, 10, 62,156,166, 50, 5, 64,175, 15,169,153, +157,157,157, 2,160,137,167,167,167,200,216,201,162, 43,138,100, 85,247,119, 35, 88,255, 95,200,242, 59,240, 15, 35, 33, 33,193, +239, 67,107,166,164,164,196,124, 72,189,236,172,180, 13, 95, 13,235, 51,166,108,210,103, 99, 38,123, 46, 51,102, 57,217,105, 27, +254, 87,215,178,108,154, 17, 0,212,217,217,121,219,203,151, 47,221, 8, 33, 9,111, 70,146,222,252,109,238,220,185,120,215,152, +127,229, 53, 1,192,195,195,227, 96, 98, 98,162,147, 80, 40, 76, 45,175,251,230,250,138, 52, 57, 56,222,150,209,254,107, 11,128, +128,255, 39,154,109, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252,251, 52, 63,182,133,225, 44, 38, 7, 7, 7, 7, 7, 7, + 7,199,135,133, 0, 8,120, 71,100,235,177,209, 34,132, 4, 84, 35,114,246,248, 31,164,105, 87,129,230,217, 74, 52,219, 86, 35, +157,156, 38,167,201,105,114,154,156, 38,167,249,175,212,172, 76,251,163,233,157,200, 85, 17,114, 97, 94, 78,147,211,228, 52, 57, + 77, 78,147,211,228,170, 8,185, 42, 66, 14, 14, 14, 14, 14, 14, 14,142,127, 52,239, 28,166,161, 87,221,146,238,195,127, 62,226, + 58, 76,112, 0, 60, 30,111,113,139, 22, 45,198, 92,189,122,245, 39,157, 78, 55,191, 58, 26,132, 16, 39,123,123,251,239, 41,165, + 77, 8, 33, 98, 62,159,255, 36, 61, 61,125,145, 78,167,187, 82,221,116, 17, 66, 92, 29, 28, 28,190,103, 89,182, 49, 0, 33,159, +207,143, 72, 73, 73, 89, 72, 41,189,249, 30,154,102, 14, 14, 14,173, 88,150,117, 41, 57,117, 94, 70,106,106,234, 21, 74,105, 50, +151, 19, 56, 56, 56, 56, 56,170,109,176,122,215, 33, 96, 0,212, 9,131,227,188,145,132, 63,103, 3, 77, 44,123,241,160,100, 48, + 54, 95, 0, 81, 0,238, 82, 74, 11,222, 39, 1,255, 95, 52,255,233, 16, 66, 24, 11, 11,139,246, 50,153,108,124, 81, 81, 81, 3, + 51, 51,179,136,210,233,113,142,150, 14, 74,248, 62,218,118, 3, 7, 14,156,190,113,227, 70,244,235,215,111, 22, 33,100, 57,165, +180,168, 42, 26,214,214,214,221, 60, 60, 60, 54,172, 90,181,218,182, 89,179,102, 68, 42,149, 34, 42, 42,202,121,204,152,209, 65, + 78, 78, 78,123, 83, 82, 82,190,170,106,186,108,109,109,251,214,170, 85,107,213,154, 53,107,108,155, 52,105, 66, 4, 2, 1,194, +195,195, 93,198,143, 31, 31,226,232,232,184, 53, 53, 53,117,114, 85, 53,173,172,172,252,106,214,172,217,113,237,218,181,178,166, + 77,155, 66, 44, 22,227,225,195,135,166, 35, 71,142,116,118,114,114,122,152,146,146,114,166, 42,122,129, 35,239, 9,132, 50, 45, + 31, 0,180, 10,161, 62,124, 67, 67,157,177,235,184,226,137,131,131,131,227, 35, 50, 88,125,235, 16, 16, 0,254,205, 48,159,232, +241, 45, 24,144, 9, 3,201,239,171,127,103,110,183,109,219,214,231,139, 47,190, 32,165, 83, 71,248,237,217,179,167, 55,143,199, +139,102, 89,246, 22,128, 7,206,206,206,218,178,105, 9,222,164,131, 23,121, 53, 70,214,153,231, 16, 2,168,207, 48, 76, 72,101, +154,237,106, 65, 75, 8,112,234,217,219, 35,105,237, 61, 9, 64,129, 51, 47,170,166,121, 58,246,227,136,204,153,154,154,122,217, +218,218, 78,182,182,182,238, 20, 20, 20, 84, 48,106,212,168,248,200,200,200,167, 62, 62, 62,170, 77,155, 54, 45,210,233,116,107, +107,215,174,125,166,176,176,112,217,123,140,139,229,174,211,233, 16, 29, 29, 13,134, 97, 4, 0, 60, 0, 60,170,130, 65,115,116, +119,119, 95,127,225,218, 61,187, 2, 13, 15,207, 50, 41, 0, 5, 88,161, 3,214,109,222,107, 57,123,218,216,129,102,102,102, 87, + 11, 10, 10,246, 86, 65,211,181, 86,173, 90,171, 30, 63,126,108, 39,145, 72,192,178, 44, 10, 11, 11,225,228,228,132, 77,155, 54, + 89,126,243,205, 55,159,203,100,178,203, 10,133,226, 72, 85,140,121,205,154, 53, 59, 70, 70, 70,202,196, 98, 49,209,235,245, 68, +173, 86,195,213,213,149,238,218,181, 75, 50,110,220,184,250, 98,177,248,165, 90,173,126,106,148,185,250,245,158,160, 32,235, 66, + 40, 77, 84,206, 2, 0, 34,145, 46, 12,155,103,117,187, 32,235, 66,163,202,214, 5,254,138, 27,225, 95,114, 38,139,227,127,139, +163,163, 99,160,165,165,229,254,188,188,188, 75,169,169,169,195, 75,103, 54,120,223,143, 63, 39, 62,159,239, 65, 41,181, 40,253, +127,158, 94,175,143, 51,102,206,205,119, 97,227,217,170, 43,196,178, 97,160,108,125, 6, 0, 97,152, 7, 6,173, 98, 75, 86,204, +133, 35,239,165, 41,146,126, 14,208,250, 12,192, 18,134,121,200,234, 21,191,101, 70, 93, 56,193,229, 12,142, 15, 22,193,170, 19, + 2, 75, 2, 76,155, 49,234, 75,134,207,227,145, 69, 27,126, 29,112,231,250, 17,234, 88,163,254,171, 41, 55,154, 55,111,142,230, +205,155,147,165, 75,151,250,158, 63,127,222,119,215,174, 93,186,235,215,175,135, 3,216,250, 54, 77, 74,129,150, 29,165, 47,245, + 58,165,107,211,118, 82,149,123,227,181,187,154, 52,105,206,138,197, 98, 84,164,121,230,250,245,240,118,181,222,174, 89, 34, 12, +212,106,192, 63,227,220,208,149,132,117,153,157, 96,172,230,187,210,249,255,204, 92, 93, 50, 53, 53,245, 28, 57,114,228,179,209, +163, 71, 95,150,203,229, 20, 0, 20, 10,133,184,107,215,174,185, 61,122,244,200, 86, 40, 20, 88,183,110,157,235,170, 85,171,206, +152,153,153, 37, 23, 20, 20, 52,170, 74, 84, 12,192,156,110,221,186,205,250,250,235,175, 81,163, 70, 13,140, 27, 55, 14, 58,157, + 46,156, 16, 50, 27,192, 18, 99, 6,221,179,179,179,155,179, 98,197, 10,187, 98,157, 0,223,109,143, 69, 78, 81,201,128,162, 50, + 17,131,175,218, 74, 48,118,236, 56,243,219,183,111, 47,197, 27, 35, 72, 87,132,131,131,195,247,107,214,172,177,149, 72, 36,160, +148,162,168,168, 8,133,133,133, 40, 42, 42, 66,113,113, 49, 70,143, 30,109, 30, 17, 17,177, 2,192,145, 42,104,182, 90,187,118, +173, 76, 44, 22,227,204,153, 51,222,106,181,154,167,209,104, 96, 48, 24, 12,181,106,213,138,254,250,235,175,197,143, 31, 63,238, + 0,192, 40,131,229,152, 6, 65,190, 82,185,230,151, 31,190,177, 5,128,175,167,253,184, 6, 80,134, 80, 35,214, 57,166, 33, 24, + 0,103,176, 42,206,159, 60, 0, 61, 5, 2, 65, 47, 79, 79,207,160,103,207,158,221,215,235,245,127, 2,248,179,116,122,162,247, +209,110,227,228,228,244,125, 74, 74,202, 47,148,210, 29,255,150,107,106,103,103,247,231,129, 3, 7, 92,183,111,223,254,217,111, +191,253,118, 28,239, 49, 74, 62, 33, 68, 0, 32,180, 81,163, 70, 54,189,122,245, 18, 56, 56, 56, 64,161, 80, 32, 54, 54, 86,118, +246,236, 89, 91,137, 68,146,173, 86,171,111, 84,229, 94,217,120, 55, 53, 1,223,108, 79,104,171,182,205,250,245,238,105,106,111, +109, 14,165,198,128,103, 9,169, 53, 78, 30, 63,220,210, 41,224,147,235, 90,109,254,128,172,152,107, 69, 85,213,108,213,177, 75, +179,182,109,218,152,154, 91,152, 35,191, 88,139,231,241,201,110, 23,206, 28,105,238, 24,240,201,101,150,232, 6,167, 63, 58,173, +224,158, 58,142,170,240,151, 70,238,251, 34,233,219, 30, 20,200, 77,228,111, 21, 48, 55, 55, 71, 88, 88, 24, 22, 45, 90, 36, 0, +208,248,117, 83,245,159, 97, 19, 24, 0, 6,131,198,113,214, 87, 99, 33,226, 83,241, 39,157, 58, 16, 51, 51, 51,163, 52,121,239, +208, 4, 0,202, 8, 97,111,165,111, 27,226,173,108,153,254, 96,220,160, 7,151,190, 15,208,168,242, 4,111,106,202,100, 50,120, +121,121, 97,230,204,153,111, 75,231, 7,239, 18,250,191,208,164,148, 58,249,249,249, 21,174, 88,177,194,123,238,220,185,150, 42, +149, 74, 14,192,213,179, 78, 35, 23,134, 97, 92, 85, 42,149,217,156, 57,115,108,151, 46, 93,234,109,107,107,155, 71, 41,181,173, + 98, 58, 23,172, 89,179,102,246,161, 67,135,152,230,205,155,195,210,210, 18,173, 90,181,194,241,227,199,249, 63,253,244,211, 34, + 0,179,140, 73, 39,195, 48,205,155, 53,107, 70, 88,150, 34,183, 72,135, 11,139, 3,113,237,199, 96, 40, 52, 44,114,243, 10,160, + 82,169, 32,147,201,164,132, 16, 19, 99,207,157,101,217,198, 77,154, 52, 33, 64,201,200,239, 37, 75, 49, 10, 11, 75,254,106, 52, + 90, 8, 4, 2, 83, 66,136,184, 10,154, 46, 77,155, 54, 5, 0, 40,149, 74,126,155, 54,109, 72,235,214,173, 73, 97, 97, 33,191, +108, 26, 31,129, 64, 32, 34,132,240,141,209,212,200, 4,132,165,172,189, 92, 38,181,145,203,164, 54, 44,101,237, 1,192,152,117, + 26,153,128,252,157,249,147, 16, 98,203,227,241, 54,123,122,122, 62,225,241,120,219, 8, 33, 14,239,163, 73, 8, 9, 38,132, 44, +146,201,100,103,253,252,252, 18,229,114,249,121, 66,200, 18, 66, 72,104,117, 52, 9, 33, 34,153, 76,118,126,209,162, 69,251,238, +223,191,223,239,220,185,115, 30,143, 30, 61,234,189,116,233,210, 61, 38, 38, 38, 87, 8, 33,178,247,121, 54, 61, 60, 60, 54,221, +186,117, 43,184, 73,147, 38, 27, 43,202, 67, 85,209, 36,132,240, 8, 33, 13, 72,217,252, 56,255,128, 50,164, 60, 46, 46, 46, 78, +254,254,254,174, 98,177, 24,205,154, 53, 3,165, 52,236, 61, 53, 67, 71,141, 26,229, 48,105,210, 36,193,131, 7, 15,176,113,227, + 70, 28, 58,116, 8, 25, 25, 25,232,210,165,139,176,117,235,214, 14, 98,177, 56,180, 74,154,124,179, 61,227, 39, 76,236,248,205, +184, 17,166, 15, 95,106,177,229,236, 75, 28,188,145,138, 12,133, 8, 93,123, 15, 53,239,208,189,127, 7,145,216,124, 79, 85, 53, +167, 79,155,214,241,203,207, 63, 53,141, 76,101,113,248,102, 26,110, 70,231, 67, 47,176, 64,231,222,195, 45,235, 55,237,248, 9, + 31,130,173,255,132,123,244,177,107,254, 43, 34, 88,115, 54,210,220,249,163,201, 15,139,214,253, 58,139, 33,132,186,212,238, 16, +233,225,213,184,152,101, 89, 40,149,202,178, 23, 13,148, 74, 37, 18, 18, 18,112,235,214, 45,152,155,155, 87,120,160,147,177, 20, + 11,191,250,207,225,242,242,243,225,236,226, 1,153, 76, 86,169,230,137, 10,170,243,248,180, 36, 26, 50,162, 79, 15,254,203,212, + 84,254,245,123, 23, 2,247,174,220, 21,232, 90,171, 93, 84,253,176,169,143, 77,204,107, 40, 31, 60,120,128, 27, 55,110, 32, 55, + 55, 23,141, 26, 53,250,104,110, 30, 33, 68,183,108,217,178,123, 41, 41, 41,228,234,213,171,245,231,175,216,229,241,168,160, 38, + 47,179,136, 10,108, 77, 94,122,248,201,158, 26,242,243,243,227, 38, 79,158,124,193,193,193, 65, 61,118,236,216,150, 70,234, 74, + 0,248,244,233,211,103,250,152, 49, 99, 16, 27, 27,139, 17, 35, 70, 40,111,223,190,157,221,164, 73, 19,235,223,126,251, 77, 58, +105,210, 36, 92,186,116,105, 14, 33,228, 0,128, 56, 74,233, 59,231, 82, 99, 89, 86, 36,149, 74,129,130,146, 15, 85,173,190,108, +110, 90,160,184,184, 24,124,228, 65, 36, 18, 49, 0,108, 1, 24,251,229, 41, 20,139,197,175,204, 85, 82, 70, 33, 18, 50,138, 80, + 88,164,134, 82,169,131, 70, 5,136,205,236,121, 64,162, 53, 0, 99, 27,167,243,196, 98, 49,244,122, 61,180, 90, 45, 84, 42, 21, + 84, 42, 21,212,106, 53,242,243,243, 81, 88, 88, 8, 62,159, 47, 3, 96, 6, 32,167, 82, 49,145, 84,207, 99,132,139,190, 93,184, +102, 46, 0,240, 24,225, 34, 19,168, 88, 99,214,241, 68, 82,253,223,152,175,196,182,182,182, 23,246,237,219,231,231,229,229,133, +184,184, 56,223,190,125,251,134, 16, 66, 26, 80, 74, 21, 85,212,146, 49, 12,243,195,176, 97,195,198, 12, 28, 56,144,212,174, 93, + 27,124, 62, 31,122,189,222, 37, 54, 54,182,213,239,191,255, 62,141,207,231,255,102, 48, 24, 38, 27,219,174,143, 16,194,136, 68, +162,189, 27, 54,108,104, 17, 18, 18,130,109,219,182,225,246,237,219,108,112,112, 48, 51,100,200, 16,184,185,185,133, 12, 25, 50, +228, 32, 33,164,115,117, 34, 89,132, 16,183, 65,131, 6,185,242,120, 60, 52,105,210, 68,120,253,250,245,134, 0,174,191,231, 53, + 53,113,113,113,185, 20, 22, 22,214,224,236,217,179,247, 8, 33, 97, 85,105,199,232,228,228,212,221,222,222,126,169,169,169,169, +165,177,251, 20, 21, 21, 41,210,211,211,167, 36, 39, 39, 27, 53, 31, 41,165,180,113, 64, 64, 0,146,147,147,225,233,233, 9,161, + 80, 24,234,236,236, 60,146, 82,218,145,101,217,153, 85,105, 98, 64, 8,113, 10, 13, 13,181, 9, 11, 11, 35, 75,150, 44, 1, 0, + 8, 4, 2, 24, 12, 6, 48, 12, 3,129, 64, 0, 95, 95, 95,242,226,197, 11, 43, 66,136,147, 49,213,133, 54,158,173,186, 54,105, +211,177, 89,139,144,122,204, 79,251,159,193,192, 26,192, 35,122,240, 9, 11, 86, 39,134, 88,200, 67,109,255, 32, 94,116,196,195, + 16, 27,239,118, 93,179, 98,206, 28, 49, 70,179, 99,215,110,205,253,124,106, 51, 43, 15, 62, 71, 94,242, 19, 67,114,212,229, 44, +134,199,192, 47,176,181, 77,237, 58, 13,120, 13, 66,194, 4, 41,113, 17,173,172,188, 90,182,205,121,118,137, 51, 21, 28, 85, 55, + 88,132, 16, 74, 41,125,245,101, 53,123, 29,157,109, 99, 73,220, 35, 31, 63,100, 18,211, 52,197, 15, 31, 62,132,181,181, 53,236, +236,236, 96,102,102,134,232,232,104,156, 61,123, 22, 49, 49, 49,160,148,162, 65,131, 6, 85, 58,112,122, 90, 26,178,115, 10,223, + 91,243, 68, 44,197,130,209, 37,201,174,225,232,136, 26,142,142,252,172,220, 60,220,120,248,200,239,200,111,109,125,210,153,145, + 91,148, 74,229,171,237,117,186,143,175,214,197,222,222, 94,255,213, 87, 95,231,124,185, 54,174,214,128,214, 78,188,238,161, 14, + 56,120, 61,149,183,231, 34,143,206,254,162, 94,230,179,103, 79,141, 62,105,145, 72,244,125,167, 78,157,190,161,148, 10,198,143, + 31, 15, 0, 24, 58,116,104,193,205,155, 55,107, 83, 74, 51, 8, 33, 78, 95,124,241,197,211, 11, 23, 46,200, 38, 78,156,200,211, +235,245,145,124, 62,159, 18, 66,230, 83, 74,231,190, 53,147,241,249,247, 31, 60,120,224, 14, 19, 55,216,152,242,208, 97,214, 61, + 0,128,137, 24,200, 76, 75,194,173, 71, 23, 97,109,109,109,222,188,121,243, 40, 47, 47, 47,117,106,106,234,248,226,226,226,173, + 21,102, 92, 62, 63, 34, 60, 60,220,197,197,197,165,196, 96,101, 41,177,229, 6, 3,133, 90, 10, 64, 10,194,202, 97,102,231,110, + 90, 91, 91,240,192,214,214, 86,171,209,104,166, 23, 20, 20, 84, 88,213,195,227,241, 50, 30, 63,126,108,234,234,234, 10, 0,186, +131, 7, 15,242, 53, 26, 13, 40,165,134, 99,199,142,117, 76, 76, 76,108,224,225,225,193,184,184,184, 76,247,242,242, 82, 38, 39, + 39,143, 80, 42,149,239,172, 66, 57, 57,206, 83,219,114,238,197,181,121,113,137,191, 3,128,115,136, 95,206,209,185, 13, 53, 45, +231, 22, 85,186,238,228, 56, 79, 45,198,254,109,237, 4,135,125,251,237,183,126, 86, 86, 86, 24, 53,106, 20,230,205,155,135,217, +179,103,123,141, 26, 53,234, 75, 0,203,171,240,146,149, 58, 56, 56,220, 89,185,114,165,111,211,166, 77,113,252,248,113,236,222, +189, 27, 47, 94,188,208,123,120,120,240, 67, 66, 66, 48,103,206, 28,116,232,208, 97,196,216,177, 99, 91, 18, 66, 26, 26,105, 58, + 62,159, 51,103, 78,247,102,205,154,225,179,207, 62, 83, 95,188,120,177, 31,128,211,103,206,156,105,125,233,210,165,253, 59,119, +238,148, 46, 90,180,168,237,164, 73,147, 70, 1, 88, 93,141,243,239,209,162, 69, 11, 0, 64,179,102,205,176,116,233,210, 14,239, + 99,176, 8, 33, 34,107,107,235, 99,219,182,109,107,224,237,237,141,193,131, 7, 55,236,215,175,223, 49, 66, 72, 59, 74,169, 81, +243, 70, 58, 58, 58,254,176, 97,195, 6, 79,169, 84,106,244,113, 53, 26,141,213,200,145, 35,151, 0, 48,202, 96,177, 44,219, 56, + 32, 32, 0, 7, 15, 30,196,200,145, 35,225,231,231, 87,175, 65,131, 6,235, 7, 13, 26,132, 81,163, 70,181,177,181,181,181, 47, +157, 92,188,242, 23, 11,159,239,209,165, 75, 23,193,159,127,254, 9, 0,104,209,162, 5,218,182,109,139,199,143, 31,227,234,213, +171,224,241,120,144,203,229,104,218,180,169, 40, 37, 37,197, 3, 64,165, 6,139, 17,203,134,117,239,210,217,244,240,205, 84, 24, + 88, 61,130, 60,205, 16,226,107,135,232,164, 2,132, 63, 73,130, 65, 35,132,153,149, 53, 66, 91,182,183, 74, 75,126, 49, 12,198, + 52, 15, 16,203,134,245,234,254,137,201,225, 27, 41,200, 75,137,162,207,110, 31, 56,175, 83, 21,143, 0,128,187,231,246,172,119, +176,150,182,171, 29, 24,196, 11,107,215,205,242,207,221,105,195, 0,112, 6,139,227,253, 34, 88,101,100,231, 65,105,237,224,135, +196,180,251, 37,255,207,206, 70,118,118, 54,106,214,172,137, 85,171, 86,189,182,173, 74,165,170, 86, 2,254, 27,154, 54,150, 22, +232,214,170, 37,239,113,244, 58,158,146, 85,126, 16,205,127, 42,165,147,150, 50, 9, 89, 58,139,204,124,173,176,127, 43, 87, 42, +224, 49, 24,208,170, 6,249,229, 72,130, 48,163, 88, 96,193, 48, 76, 2,203, 86,222,145,144, 16, 34,232,222,189,251, 55,123,247, +238, 21, 68, 69, 69,161, 86,173, 90,208,106,181,184,121,243,102, 18,165, 52,163,244,120, 41, 60, 30, 47,133,101, 89,175,250,245, +235, 99,241,226,197,240,245,245, 37,157, 59,119,158, 86,106,178,254,114,160,148,148,148, 69, 95,127,253,117,139, 95,183,236,177, + 30,220,152,160,176, 80, 13,133, 66,129,232,199,119, 80,156, 94,140,245,235, 55, 64, 38,147, 17, 0,194,180,180, 52,225,164, 73, + 19, 55,186,184,184,116, 73, 74, 74,234,245,174,180,166,164,164, 44, 28, 59,118,108,200,246,237,219, 45, 75,218, 93, 41, 81,168, + 20,227,214,207, 37, 17,202,144, 73,183,241,219,175, 27,153,186,238,114,235,194,194, 66,140, 24, 49, 98,165,163,163, 99,211,212, +212,212,145,239,210, 76, 77, 77,189, 50, 98,196, 8,231,223,127,255, 93,226,229,229, 21,147,159,159,143,156,156, 28,102,231,206, +157, 99, 29, 29, 29,205, 15, 30, 60, 68,228,114, 57, 0,240,226,227,227,133, 95,127,253,213, 94, 7, 7,135,157,105,105,105,159, +189,235,222, 0, 80, 19,130, 84, 39,167,154,158,138, 27,204, 92, 39, 39,213,213,139,115,146,183, 19,130,212,146,109, 64, 29, 55, + 56, 14,122,185, 77,220, 76,173,102, 87,164,165, 37,196, 80, 10,138, 57,127, 95, 39, 12, 27, 27,155,177,221,187,119,199,146, 37, + 75,112,228,200,145, 73, 86, 86, 86, 63,207,155, 55, 15, 78, 78, 78, 95, 19, 66, 86, 84, 97,178,219, 31,151, 47, 95,238,235,235, +235,139,161, 67,135,106,206,158, 61,251, 45,128,131, 0, 18,174, 92,185, 82, 99,235,214,173, 93,247,238,221,187,100,229,202,149, +146,213,171, 87,123,246,238,221,123, 5,128, 47,140,248,160,152, 56,112,224, 64, 44, 91,182, 12, 23, 47, 94,236, 77, 41, 61, 94, +246,189, 69, 8,233,186,104,209,162,115,179,102,205,194,242,229,203,199, 87,213, 96, 17, 66, 76,252,252,252,190,235,216,177, 35, +174, 92,185,130,230,205,155, 35, 52, 52,116, 18, 33,100, 21,165, 52,171, 26,230,138, 49, 49, 49,217,187,101,203,150,230,238,238, +238, 88,184,112, 33,190,249,230, 27,108,218,180,169,249,224,193,131,247, 18, 66,122, 25,211,203,215,196,196,196, 68, 42,149, 98, +201,146, 37,244,229,203,151,185, 70, 24, 50,203,239,190,251,142,152, 87, 86,181,240,159, 8,153, 84, 44, 22, 55,241,241,241,193, + 79, 63,253,132, 43, 87,174, 96,220,184,113,240,241,241, 65, 82, 82, 18,186,117,235, 38,123,250,244,105, 31, 0, 91,140, 44,151, +204,173,173,173,145,145,145, 1,129, 64,128,166, 77,155,226,224,193,131, 80,171,213,176,179,179, 67, 94, 94,222,171,218, 4, 62, +159,111,110,100,105, 23, 96, 99,101,142,140,136,100,240,161, 71, 96,109, 27, 92,120,156, 13,173,142,133,157,181, 5,210, 50,210, +209, 56,192, 5, 26, 77, 13, 80,202, 26, 53, 19,136,136,199, 4,138, 37, 82,228, 20,102, 33,249,201,197,108,173, 65, 61, 50,239, +197,213, 68, 0,176,170,213, 98,228,221,171,103,238,246,253,164,133, 93, 81,177, 43, 8,101, 27,129,131,163, 10, 84, 58,208,232, +219, 94,204,229, 35, 66,101,104,181,218,247, 74,200,127, 67,243,109,252, 55, 52,255, 1, 38,139,117,182,228,231,203, 37,140,254, + 76,120,134, 65,167, 55,224,212,221, 52,131, 76, 76,244,150, 98, 77, 1,203,178,148, 16, 66,141,208,209,157, 58,117,106,219,184, +113,227,240,243,207, 63,227,233,211,167, 16, 10,133, 8, 8, 8,112, 44,107, 31, 69, 8, 49, 15, 12, 12,180, 99, 24, 6,209,209, +209,248,233,167,159,240,249,231,159,211,235,215,175,111,122,215,139,130, 82,122, 63, 53, 53,117,195,148,241, 35,243, 24, 69, 34, +228, 52, 11,218,156,167, 96,149,153,248,118,206, 34,196,101,179,184,247,162, 16,247, 94, 20, 34, 75, 35,199, 79,191,108,230,249, +251,251,119, 21, 8, 4, 29, 42, 72,235,205,212,212,212,109, 19, 39, 78,204,203,200,200,120,101,156,181,122, 22, 90,253,235,201, + 48, 53, 53,197,250,245,235, 45, 92, 93, 93,251, 8, 4,130, 86, 21,104, 38,167,164,164, 60, 26, 51,102,140, 58, 53, 53, 21,249, +249,249, 56,125,250,116, 59, 23, 23, 23,243,185,139,150,147,184,108,250, 42,157, 69,196, 26,155,119,254,201,171, 93,187,246,167, + 2,129, 32,180,226,151,151,179,167,159, 95,173,125, 55,111,222,252,204,211,211,115, 76,153,177,162, 20, 20, 0, 60, 60, 60, 70, +133,135,135,127,222,160, 65,157,125,246,246, 14, 62,127,103, 94, 34,132,180,234,223,191,191, 15,203,178,216,183,111,223, 35, 74, +233,242, 3, 7, 14,220, 81,171,213, 24, 48, 96,128, 7,128,142, 70,234, 4,127,250,233,167, 99,154, 55,111,142, 9, 19, 38,104, +207,158, 61, 27, 72, 41,253,153, 82, 26, 79, 75, 72,160,148,174,186,116,233, 82,253,177, 99,199,170, 27, 53,106,132,207, 62,251, +236,115, 66, 72,243, 74,116,155, 12, 28, 56,208,151,101, 89,236,217,179,231, 97, 57,115, 85,118, 15,207,239,223,191,255,166, 70, +163,193,160, 65,131,106, 18, 66, 90, 87,225,220,133, 98,177,120,223,130, 5, 11, 44,146,147,147, 49,100,200, 16,117,116,116, 52, +230,206,157, 43, 53, 55, 55, 63, 94, 81, 27,193,119, 6, 72,196,226, 95,215,173, 91,215,189,110,221,186, 24, 61,122,180,102,237, +218,181,227,198,140, 25,163, 9, 12, 12,196,154, 53,107,186,139, 68,162, 95,171, 20,249, 79, 79,207,187,120,241,162,117,101, 75, + 90, 90, 90,186,145,209,111,153,151,151,215,141,218,181,107, 23,248,249,249, 5,233,245,122, 60,125,250,244,249, 31,127,252,193, +250,248,248, 96,235,214,173, 88,191,126, 61,218,180,105, 3,134, 97,250, 84, 37,173,197,197,197,144, 72, 36, 16, 10,133, 8, 15, + 15,135, 90,173,134, 76, 38,131, 68, 34, 1,143,199,131,133,133, 5, 76, 77, 77, 1,128, 26,119,127, 64, 11, 20, 58, 8, 4, 12, +248, 12,139,168,132,124,104,117, 44, 36, 66, 30, 4,124, 2, 80, 22, 22,114, 1, 36, 34, 30, 24, 66, 88, 35, 53,145, 95,172,133, + 72,200, 64, 32, 20, 17, 70,111,120, 21, 34,100,248, 6,169, 84, 42, 34, 54,102, 98, 72,132,220,152,220, 28, 31, 56,130, 5, 0, + 6,195, 95,123,233,190, 45, 10,164,209,104,222, 43, 33,255, 13,205,119,132,205, 63,170, 27, 88, 80, 80,192,191,113,227,134,169, + 80, 40, 20,119,111, 16,146,181,244,247,167,182,243,118,198, 64,204, 7,233,228, 79,211, 79, 28, 63, 34, 42, 44, 44,180,241,241, +241,201, 54,242, 62,140, 32,132, 44, 4, 80,135,207,231, 31,221,178,101, 11,217,177, 99,135,229,192,129, 3, 99, 9, 33,201,254, +254,254,110, 91,182,108, 49, 3,128, 85,171, 86,209,189,123,247,118, 0, 16, 65, 41, 77,171, 72, 55, 53, 53,117,150, 88, 44,190, + 30, 29, 29,189, 74, 32, 16, 88,152,153,153, 89, 94,186,116,137,164,231,107,241,221,246, 23,175,122, 22,202,197, 60,204,232,101, +135, 97,195, 62,231, 71, 70, 70,254, 8,224,212,187, 52,147,147,147, 39,201,100,178, 75,143, 30, 61, 90,110,234, 92,207,202, 38, +116,146, 89,235, 25, 37,213,143, 14,150, 34, 48,165,101, 98, 94, 94, 30,178,178,178, 48,105,210, 36,139,201,147, 39, 79, 5,112, +161,130,116,158, 22,139,197, 9, 17, 17, 17,237,249,124,190,216,196,196,164,193,141, 27, 55,200,203, 60, 29,102,108,125,142, 66, + 85, 73,109,171,169, 68,128,121, 3, 93, 48,118,236, 88,126,108,108,236, 15, 0,154,189, 77,207,217,217,217,203,207,207,111,223, +174, 93,187,252, 86,172, 88,145,243,236,217,179, 98, 39, 39,167,121,111,108,166, 94,188,120,113,246,246,237,219,189,135, 12, 25, +178,207,193,193,161,223,123, 12,169,241, 94,152,153,153, 45, 25, 57,114, 36,246,238,221,139,220,220,220, 21,165,121,108,249,174, + 93,187,246,140, 24, 49, 2,219,183,111, 95, 66, 8, 57,105, 68, 20,171,211,128, 1, 3,112,226,196, 9,156, 59,119,238, 59, 74, +105,228, 59, 76,237, 83, 66,200,180, 67,135, 14,173, 28, 56,112, 32, 54,111,222,220, 17, 64, 69, 3,207,182,235,208,161, 3,142, + 31, 63,142,236,236,236, 53,111,219, 32, 47, 47,111,237,225,195,135, 27,119,232,208, 1,139, 23, 47,110, 7,224,188, 17,230,202, +215,220,220,124,203,202,149, 43,131,235,214,173,139, 79, 63,253, 84,165,213,106, 59,126,243,205, 55, 71,118,239,222,109,186,109, +219,182,160, 47,191,252,242, 22, 33,100,184,177,131,216,242,120,188, 69,171, 87,175,254, 34, 44, 44, 12,147, 38, 77,210,159, 58, +117,170, 27,165,244, 52, 33, 36,118,234,212,169,199,126,250,233, 39,222,178,101,203,190,224,241,120,153, 6,131,225,219,191,229, + 11,155, 97, 22,204,159, 63,191,113,139, 22, 45,144,144,144,128,123,247,238, 65,175,215,111,191,123,247,238,229, 22, 45, 90, 44, +208,106,181, 71, 36, 18,201, 80, 19, 19, 19,127,127,127,255,214,246,246,246,178,244,244,116,133, 17,215, 51, 47, 54, 54, 86,110, +103,103, 7,129, 64,128,135, 15, 31,194,206,174,100,202,215,140,140, 12, 4, 4, 4,128,199,227, 33, 47, 47, 15, 0,242,141, 51, + 67,204,163,216,248,148,154, 86,166,114,192, 32,193,253,232, 36,216,218, 88,194, 64, 24,164,165,165,162,129,143, 11, 8, 33,200, +203, 78, 3, 33,196,168,185,116, 13,148, 13,127,153,146,225,108,109, 42, 70,221,198,237,173,111,156,204,220, 97, 94,171,217,151, +124, 30,225,137, 37,102, 27,190,248,236, 51, 27,150,165,200,203, 78, 7,159, 97,110,115,150,129,227,131, 26, 44,150,101, 33,149, + 74, 95,139, 48,189, 25, 5,146, 74,165, 80,171,213, 85, 58,176, 84, 42,133, 86,143, 15,170,105,204, 49, 63,180,230,223,137, 94, +175, 55,157, 60,121,114, 72, 72, 72, 72,114,155, 54,109,226,188,189,173, 18,187, 52,150,218,172,220,116,160, 65,231,150,117,239, +229,229,100,100,189, 48, 51, 83,199,199,199,219,253,246,219,111, 33, 58,157, 78,102,100, 68,236, 37,128,151,132,144,181, 29, 59, +118,252,170,111,223,190,136,140,140,180, 83, 40, 20,118, 50, 89,137,196,142, 29, 59,176,119,239,222,159, 41,165, 70, 15,188,169, + 86,171, 79, 2,240, 36,132, 88,212,168, 81, 35,221,202,202, 74,152, 90, 84,252,170,103,161,144,207,160,233, 55,119,144,155, 87, + 0, 27, 27, 27,152,154,154,122, 84,166, 89, 58,206,213, 17,175,118, 83,235, 41, 31,109,184,184,117,203, 22,115, 0,224, 49, 4, +182,230, 66,228,229,229, 33, 51, 51, 19, 89, 89, 89, 96, 24, 6,122,189,222,207,136,116, 62, 5,240,148, 16,226,212,186,117,235, + 5,166,166,166, 96,115,138,145, 91,164,125,173, 10,178,168, 72, 1,119,119,119,152,154,154,190,181, 58,194,202,202,202, 84, 44, + 22,111,221,184,113,163,175,169,169, 41,111,196,136, 17, 22, 35, 70,140,104,246, 46, 51, 38,147,201,120,155, 55,111,174,221,160, + 65,131, 45,238,238,238,237,226,227,227,243,255, 87,121,169,116,200,131, 81, 83,166, 76, 9,146, 72, 36,248,229,151, 95, 94, 0, +216, 89,250,243,190,181,107,215,206, 30, 56,112,160,207,184,113,227,252,103,205,154, 53,169,180,170,240,157, 99, 36, 9,133,194, + 64, 63, 63, 63, 28, 56,112, 0, 0, 14, 84,114,248,253,215,175, 95, 95,217,165, 75, 23, 72, 36,146,224, 74,182,245,112,117,117, +197,161, 67,135, 0,224,254, 59,182,185, 31, 29, 29,141, 94,189,122,129, 16,226, 97,196,185,119,111,223,190,253,254,197,139, 23, +243, 77, 77, 77,241,197, 23, 95,104,110,221,186,213,153, 82,122,153, 16,210,106,208,160, 65,151,118,238,220, 41,191,116,233,146, +239,247,223,127,127,157,199,227, 45, 50, 24, 12,179, 42,209,252,124,225,194,133, 51,122,244,232,129,121,243,230,209,223,127,255, +253, 83, 74,233,233,210,231,235, 20, 33,100,136,165,165,229,206,153, 51,103,146,252,252,252, 25,132,144, 36, 74,233,186, 10,242, +121,190,193, 96,112, 80, 40, 20, 70,125, 33, 26,187,189,181,181,117,167, 22, 45, 90,224,199, 31,127,196,184,113,227,176,117,235, + 86, 10,224,104,106,106,234, 67, 0, 45, 74, 34,176, 78,166,225,225,225,254,205,155, 55, 23, 62,122,244,232, 19, 0,191, 27, 81, + 54,197, 95,184,112,193,174,115,231,206, 66,153, 76, 6,131,193,128,236,236,108,168, 84, 42, 4, 4, 4,160,113,227,198,200,200, +200,192,209,163, 71,181,121,121,121,241, 70,149,119,154,226,109,103,142,253,217,170,235,128,145,230, 82, 33, 15, 6,157, 8,233, +233,153, 40, 52,232, 17,232,231,134,230, 13,106, 32, 33, 93,137, 83, 71,255,204, 45, 44, 84,108, 51, 70, 83,167, 86,108, 57,123, +242, 72,203,230,157, 6,153,203,125,252,225,225, 56,174,193,221,235,103,207, 72, 68, 2, 50,104, 96, 63,139,166, 13,189,240,240, + 69, 1, 78, 28, 61,144,155, 95, 80,176, 5, 28, 28,213, 49, 88,229, 27,184,151, 35, 99,210,164, 73,118,147, 39, 79,134,153,153, + 25,178,179,179,161,211,233, 94, 69,155,196, 98, 49, 44, 44, 44,144,157,157,141, 61,123,246, 0, 64, 70,197, 95,116,162,212,133, +107, 86,187, 18,158, 92, 35,150,202,168,149,236,253, 53, 1, 64,163,227,103,172,219,243,135, 85,167, 22,161,252, 26,142,142,111, + 11,211, 87, 89,243,255, 3, 90,173,246,116, 92, 92, 92,240,128, 1, 3, 50, 93, 93, 93,149, 42,149, 10, 74,165,178,240,232,238, +149,181,156,205, 70,191, 96, 24,134,154,154,154,178,118,118,118,249,231,206,157,179,211,235,245, 23,171,120,136, 73,253,250,245, + 99,206,158, 61, 59,106,204,152, 49,196,203,203, 11,225,225,225,248,229,151, 95,232,182,109,219, 86, 2,152, 94,205,164, 23,169, +213,234,215, 34, 32,229,123, 22, 22, 21, 21, 65,163, 76,135,174, 10, 61, 18, 98,207,254, 24, 93,179,102, 77,157,191,219,127,134, + 19,201,205,205, 69,102, 86,214, 43,131,149,153,153, 9, 0, 85, 9, 97, 22,252, 53,157,255,169,121, 40, 46, 46,134, 74,145, 6, +131,193,240, 86,205,156,156,156, 66, 39, 39,167,213,171, 86,173,250,105,193,130, 5,118,203,151, 47,207,137,138,138, 42, 96, 24, + 70,245,198, 71,140,196,211,211,211,116,217,178,101,246,171, 86,173,202, 97, 89,118,245,255,216, 92,245,168, 91,183,238,214, 78, +157, 58,153,142, 25, 51, 6,171, 86,173, 66,106,106,234,116, 74,169,190,180,108, 96, 9, 33, 83,215,172, 89,115,116,218,180,105, +208,106,181,203,142, 31, 63, 62,143, 16, 50,138, 82,186,243,109,154,182,182,182, 46,124, 62, 31,247,238,221, 43,160,148, 62,175, +196,208,167,121,123,123,167, 19, 66,236, 29, 29, 29,107, 85,180,173,149,149,149,167,169,169, 41,146,147,147, 1, 32,238, 29,155, +197,167,164,164, 80,145, 72, 68,156,156,156,188, 42, 59,127, 75, 75,203,169, 27, 55,110,228, 95,184,112, 1,115,230,204, 73, 74, + 72, 72, 24, 68, 41,189, 82,154,182,123,132,144,230,173, 90,181,218, 61,109,218, 52,239, 31,126,248,129, 68, 71, 71,143,198, 59, +134, 40, 41,195,205,205,109,212,231,159,127,142,213,171, 87, 99,195,134, 13,163, 41,165,251,222, 56,231,221,132, 16, 75,107,107, +235,213, 35, 71,142,196,150, 45, 91, 6, 1, 88, 87, 65,180,118, 90,255,254,253,103,231,228,228, 44, 50,230,158, 26,179,189,179, +179,115,171,214,173, 91,123,170, 84, 42,236,219,183,239,249,254,253,251,115, 13, 6,195,158, 82,115, 85, 62,127, 28, 60,121,242, +228,236,169, 83,167,226,194,133, 11, 91,156,156,156,120, 41, 41, 41,187, 43,185,167, 41, 18,137, 36,235,225,195,135, 14,190,190, +190,140,163,163, 35, 26, 53,106, 4, 11, 11, 11,240,120, 60,100,100,100,224,242,229,203,108,108,108,108,150,177, 3,142,102,197, + 92, 56,226, 80,183,243,181,123,183, 46,183,247,111,216, 84,224,108, 99,133, 80,127,103, 88,152, 8, 65, 0, 36,100, 40,113,254, +252, 25, 93, 92,220,243, 27,198,244, 32, 44,211,116,170,247,201,117, 11,187, 26,237,235, 52,104,202,175,229, 83, 27,237, 91,212, +183,180,148, 11,193, 82,138,135, 47,242,113,230,244, 73, 93, 74, 82,226, 5,174, 7, 33,199,135,142, 96,205,221,176, 97, 67,211, + 77,155, 54,117,153, 52,105,146,233,208,161, 67, 33,149, 74, 81, 92, 92, 12, 87, 87, 87,232,245,122, 28, 63,126, 28,247,238,221, + 43,100, 89,246, 40,128,107,111, 60,152, 1,229,199,173,154,177, 74, 81,163,100,240,202,226,166,243, 54,212,251, 32,154, 0,112, +253,133,222,217, 41, 53,107,110,118,238,241,137,110,206,142,194, 14,205, 26,243,109, 44, 75,122, 51, 27,169,217,246, 67,143,233, +241,191,208,212,235,245, 95, 16, 66,252,167, 78,157,186,212,217,217,217,105,222,188,121, 47,235,212,169,163, 44, 40, 40,160, 26, +141,134,205,202,202,146,237,219,183,207, 35, 59, 59,187, 80,167,211, 13,161,148, 62,172, 74, 58, 41,165, 90, 0, 99, 8, 33,135, +243,243,243, 79,125,243,205, 55,248,254,251,239,113,228,200,145,230,148,210,107,213, 61,119, 74,169,222,195,195, 35,239,254,253, +251,246, 34,235,218,176,183, 16,162,227,119, 37,193, 8, 83, 49,129,178,184, 16, 81,143, 31,162,160,160,224,110, 21, 52, 53,206, +206,206,249,233,233,233, 54,246,246,246, 37,230, 42, 51,243,149,185,202,201,201, 65,118,118, 54, 45,127,239,141,208, 44,246,244, +244, 84, 68, 69, 69,137,120, 50, 87, 56, 88,138, 81, 82, 5, 73, 97,107,202, 71,113,113, 33,158,220,188,129,252,252,252,139,239, +210, 76, 73, 73,217,227,228,228, 4, 0, 63,205,158, 61,219,166, 99,199,142,207,110,223,190,221,178,252,113, 2, 3, 3, 15,206, +155, 55,239,147,239,191,255, 62,107,235,214,173,211, 82, 83, 83,119,252, 47,243,146,181,181,245,228, 99,199,142,153,106,181, 90, +172, 90,181, 10, 63,255,252,243, 38, 74,233, 31,111, 92,139, 99, 60, 30,111, 13,195, 48, 95,125,253,245,215, 24, 57,114,164, 44, + 40, 40,104, 82,185, 40,215,107,154,201,201,201,179, 2, 3, 3,103,103,100,100, 24,101, 8,158, 62,125,250,101, 96, 96,224,172, +140,140,140,165, 21,157,187, 92, 46,151, 27, 12, 6,196,197,197,229, 82, 74,243,223,113,223, 84,181,107,215, 78, 54, 24, 12, 46, + 50,153,204,170,178,252,153,155,155,187, 40, 40, 40,104,110,122,122,250,105, 0, 11,223, 28,114,132, 82,250,128, 16,226, 63,126, +252,248,177, 75,150, 44,233,149,150,150,182,167, 50,205,132,132,132, 69,173, 90,181,250, 46, 38, 38,102, 43,165,116,195, 59,210, +249, 11, 33, 68,187, 99,199,142,209,113,113,113,139, 43,210, 76, 73, 73, 57, 10,224,168,177,247,247, 93,219,151,215,100, 24,102, +234,140, 25, 51,152,157, 59,119, 2,192,178,164,164,164, 13,239, 48,107, 15,157,157,157,183, 5, 5, 5, 13, 93,183,110,157,164, + 77,155, 54, 35, 1,236,174, 44,127,170,213,234,155,215,175, 95,111, 28, 31, 31,111,211,170, 85, 43, 33, 0, 20, 20, 20, 32, 47, + 47, 15, 71,143, 30,213,198,198,198,102, 21, 23, 23,223,172, 74, 25,162,215, 20, 12,188,126,254,208,238,248,167,143, 67,195, 58, +118,183,212,104, 93, 32,206,230, 33, 47, 59, 13, 39,143,254,153, 27, 23,247,252,134, 66,145, 55,176, 42,154, 90,117,254,128, 27, + 23, 14,239, 73,138,139,106,220,162, 85,103, 75,149,198, 13, 98, 33,131,236,244,100,156, 60,118, 40, 39, 46,238,197, 21,149, 78, +253,217,223, 85,206,255,155, 52, 63, 58,104, 89,107,219, 10, 22, 0, 34, 0,159,152,154,154,174,154, 51,103,206,134, 91,183,110, +109,232,210,165,203, 6,145, 72,180, 10,192, 39, 0, 68,239,216, 47,224,127,169,217,177, 17, 76, 63,239,198,108, 94, 48,154,175, + 61,184,220, 71, 55,127, 20,168,145,154,109,141,185, 14, 85, 89,254,215,154, 0,154, 9, 4,130, 27,117,235,214,189, 96,106,106, +154,233,238,238,126, 69, 32, 16,220, 6,208,226,125,211, 9,192,166,127,255,254,108, 97, 97, 33,237,215,175, 31, 5, 96,254,190, +154, 98,177,184,117, 88, 88,152,238,101,106, 46,189,242, 32,145, 30,189, 20, 73,119, 29,185, 65, 55,236, 62, 69,151,175,217, 76, +235,213,171,167, 1,224, 86, 21, 77,145, 72,212, 49, 44, 44, 44, 47, 43, 43,139, 70, 71, 71,211,203,151, 47,211,253,251,247,211, + 13, 27, 54,208,181,107,215, 82, 39, 39,167,108, 0, 78, 85,209,148, 74,165,221, 59,118,236,168, 79,206, 44,162, 55, 35,211,232, +217, 91,207,233,193,115, 15,233,158,163, 55,232,166, 29,127, 80, 95, 95, 95, 21, 0,251,202, 52, 29, 29, 29,251,247,235,215,239, +153,183,183,247,250, 55,127,243,242,242, 90,211,175, 95,191, 4, 39, 39,167, 33,127, 71, 94, 2,208,209,217,217, 57, 90, 40, 20, + 30, 3, 48,164,146,253, 6,240,249,252, 35, 14, 14, 14,119, 0,244,252, 95,231,121, 0, 93,236,236,236,110, 2,232, 86,201,126, +101,219,245,248, 24,159,247, 15,161,233,228,228,212,218,213,213,245,178,147,147,211,204,202,246,243,243,243, 19, 58, 56, 56, 44, +112,118,118, 62,238,232,232,216,166, 42,233, 4,224,100, 98, 98,210,204,196,196,164,171,137,137, 73, 87, 11, 11,139,102,229,159, +195,234,156,187,117,237,182, 93,107, 52,236,118,208,181,254, 39, 9, 53, 26,116, 73,240, 8,236,126,208,186,118,219,174,239,171, +233, 22,216,253, 80,141, 6, 93, 94,214,104,208, 53,190,102,112,247,131, 54, 62,109, 59,125,108,247,253,159,172,249,177, 45, 70, +111,216,167,164,229,138, 9,128, 1, 12,195,252, 2, 96, 0, 0,147, 74,110, 64,128, 17, 55,233,131,107,118,108, 9,231, 49,125, +120,199,167,127, 38,200, 52, 82,243,163,201,208, 0,186,243,249,252,235, 0,186,127,200,116,154,153,153,109,236,219,183,175, 65, + 32, 16,172,254, 80,154,214,214,214, 63,133,134,134,106, 87,174, 92, 73, 15, 28, 56, 64, 55,108,216, 64,199,142, 29, 75, 3, 2, + 2,212, 86, 86, 86,159, 85, 71,211,193,193, 97, 97,221,186,117,115,118,236,216, 65,247,236,217, 67, 87,175, 94, 77,231,206,157, +203,214,168, 81, 35,211,202,202,170, 91,117, 52,237,236,236,126,109,214,172,153,246,215, 95,127,165,103,206,156,161,187,118,237, +162,147, 39, 79,166,126,126,126, 42,185, 92,222,219, 88,205, 90,181,106,137,222,245, 91,195,134, 13, 5, 92,129,203,105,114,154, +156, 38,103,176, 62,158,133,111,108,164,107, 95, 36, 69,239, 58,164,136, 0,123,254,120,194,238,239,229, 7,253, 31,145,239, 63, + 86, 79,205,154, 53,139, 8, 33,123,158, 63,127,190,223,205,205, 77, 31, 31, 31,255,222,154, 39, 46,210,228,246, 30,164,243,153, +120, 3, 31,128,222,248, 97,123, 62,138,136,228, 33, 0,135, 62,180,110,126,126,254,112, 66,200, 56, 74,169,242, 67,105,102,101, +101, 77, 38,132,236,120,254,252,249, 50,185, 92,222,192, 96, 48,232, 84, 42,213,213,204,204,204, 73,148,210,196,234,104,166,166, +166,206, 34,132, 28,152, 62,125,250,116, 0,245, 8, 33, 26,157, 78,119, 61, 35, 35, 99, 62,165, 52,181, 58,154,233,233,233, 95, + 10,133,194,205,177,177,177,139,165, 82,105, 61,150,101, 53, 10,133,226, 98, 86, 86,214, 68, 74,105,186,177, 58,177,177,177,239, +108,255, 21, 30, 30,206,205, 59,200,193,193,193,241, 47,106,131,245, 26,127, 68, 82,244,170, 75,208, 51, 0,250, 63, 30,125, 24, +211,242,252,249,171,246,175, 31,116,106,144,211,113,244,131,107,114,213,201, 31,206, 92,149,211,124, 8,160,205, 7,214,188, 15, +160,239,135,212,212,106,181,183, 0,132,113,185,128,131,131,131,131,227,131, 27, 44, 0,248,243, 17,229,174, 26, 7, 7, 7, 7, + 7, 7, 7, 71, 5, 16, 0, 1,239,136, 2, 60, 54, 90,132,144,128,170, 30,184, 50,253,255,177,166, 93, 5,154,103, 43,209,108, + 91,141,116,114,154,156, 38,167,201,105,114,154,156,230,191, 82,179, 50,237,143,166,119,226,127,181, 5,189, 17, 13,210,255, 33, +154, 92, 67, 69, 78,147,211,228, 52, 57, 77, 78,147,211,228, 26,185,127,176,133,155, 96,137,131,131,131,131,131,131,131,227, 3, +195, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112,112, 6,139,131,131,131,131,131,131,131,131, + 51, 88, 31, 16,187,255, 39,154, 28, 28, 28, 28, 28, 28, 28, 28, 31, 12,242,111, 26,229,156,131,131,131,131,131,131,131,227,127, + 1, 87, 69,200,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112, +112, 6,139,131,131,131,131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224,224,224, +224, 12, 22, 7, 7, 7, 7, 7, 7, 7, 7,199,223,111,176, 8, 33,109, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,228, 52, + 57,131,197,193,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112, +112, 6,139,131,131,131,131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,127, 19, 4,192, 91,123, 2, 80, 74,207, + 26, 45, 82,141,222, 4,149,233,115,154,156, 38,167,201,105,114,154,156, 38,167,249,241,105, 86,166, 93, 21,255,241,143,134, 82, +250, 95, 91, 0,180,229, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252,183, 45,124, 46,136,199,193,241,255,156,253,132, +135, 92, 31, 15, 80,234, 4,158, 40, 21,169,143,158, 99, 14,101,223, 91, 51,189,142, 27,164, 58,123,232, 37,153, 72,127,248,226, +189, 53, 57, 56, 56, 56,254, 69,112, 6,139,131,227,255, 59,153,190,222,224, 99, 49, 24, 56,130,106, 99, 97, 91,103, 49,128,199, +239,173, 41,100, 23,194,192,184,128,106, 99, 96,231,179, 4, 64, 36,119,177, 57, 56, 56, 56,140,227,111,105,228, 30, 28, 28, 28, + 30, 28, 28,188, 32, 44, 44, 76,204,221, 2,142,255, 22, 97, 97, 97,226,224,224,224, 5, 33, 33, 33,225, 31,237, 73,238,168, 43, + 3, 99,232,164,209,177,206, 39, 31,229,217, 41,212, 6,111, 48,250,206,216,236,109,242, 94,154,124,210, 94,165,101,107,236,188, +173,176, 47,214,232,253, 64,241,126,154,165, 4, 4, 4, 88, 52,106,212,232,100,131, 6, 13,108,184, 28,202,193,193,193, 25,172, + 15, 12,203,178, 13,237,236,236, 38, 41,149,202,132,160,160,160,110,255,166, 11,222,184,113,227,235,161,161,161,233, 77,154, 52, + 73,111,210,164,201,189,202,214,127,140, 56, 57, 57,121,215,173, 91, 55,193,223,223, 63,166,252,122,187,250,189,154,248,181, 24, + 58,199,198,191, 71,203,247, 61, 70, 80, 80, 80, 55,149, 74,149, 80,163, 70,141,137,122,189,190,225, 71,123, 49, 85,172, 61, 24, + 94,171,136, 84,133, 44,181, 64,103, 31, 30,175, 48, 5,120, 97,208,192,177,218,154,249,172, 61, 64, 91, 63, 72, 82,202,175,231, +216,218, 95,121,174, 54, 3,195,180,130,138, 56,188,111,114, 69, 34,209,104, 74,105, 59,129, 64, 48,129, 43,126,255,221, 16, 66, + 2, 8, 33,221, 8, 33,193, 31, 80,243, 7, 95, 95,223,100, 66,200,120,238, 10,115,252,191, 49, 88,125,107,146,166,159,214, 34, +151,250,215, 36,133, 3,106,145,162, 33,181,200,213, 62, 53, 73,235,234, 30,248,143, 63,254,144,110,223,190,221,174, 78,157, 58, +123, 66, 66, 66,174, 6, 5, 5,213,174,142, 78,112,112,240,201,224,224,224,190,111,174, 11, 10, 10,234, 95,126, 93,163, 70,141, + 34, 26, 53,106,148, 31, 28, 28,252,220, 24,221,192,192,192,103, 65, 65, 65,197,193,193,193,207,222,120,113,247,111,212,168,209, +201, 55,142,215,247,205,117,239,130,199,227,185, 28, 57,114,196,238,216,177, 99,118,124, 62,223,254,213,141, 96,152,183,174,175, +198,245, 24, 17, 28, 28,124,253,141,115, 25,254,230,186, 74,204,201,245,192,192,192,225,111,232, 94, 15, 14, 14, 30,241, 33,204, + 85,139, 22, 45,174,222,191,127,191,134,169,169,169, 69,249,223, 28,172, 45, 58, 92, 63,186,102,210,103,125,219,143,182,171,211, +179,110, 53,141, 85,237,198,141, 27, 95,245,244,244,220,179,120,241, 98,187, 57,115,230,200, 62,218,167,119,127, 29, 33, 8,219, +130,165,212,246, 73,178,202,246,147,110,125,249,247, 19,149,182, 58,131,193, 10,224,133, 97,171,187,184, 90,154,124, 93,115,150, + 82,251,115,241, 2,219, 86,253,198,242,206,199,243,109,117, 6,131, 53, 24,180,172,150,230,127,242,161,128,199,227, 77, 26, 57, +114, 36, 67, 8,249,218,211,211, 83,244,111, 42,108, 67,156,137,115, 27, 47,254,237, 64, 39,210,244, 3, 26, 10,127,185, 92,126, +151, 16,226,253,255,204, 92, 53, 4, 32,163,148, 30, 6, 96, 79, 8,225,127, 0,205,229,243,231,207,159, 26, 17, 17,225, 84,179, +102,205,121,132, 16, 30,247,138,231,248,199, 27,172, 1, 53,201, 92,123, 7,231,211, 51,151,239,106,177,241,210, 11,147,181, 71, +239,203, 39, 78, 91,212,212,193,218,246,200,160, 90,228,135,119,237, 87, 81, 87, 75,145, 72,132, 23, 47, 94, 96,213,170, 85,146, +185,115,231, 54, 49, 55, 55,127, 24, 18, 18,178,162, 78,157, 58,242,138,210,242,166, 38,165,180,169, 64, 32,216, 24, 18, 18,178, +165,172,192, 38,132, 52, 21,139,197,191,134,132,132,236, 40,171,134, 12, 12, 12,172,121,251,246,109, 51, 66,136,189, 49,233,108, +212,168,145,227,221,187,119,101, 64, 73, 36, 32, 44, 44, 76,220,168, 81,163,237,206,206,206, 27, 0, 52, 5, 0, 79, 79, 79, 81, + 72, 72,200, 22, 87, 87,215,223, 8,121,189,208,124,215,185, 19, 66, 96, 97, 97,129, 93,187,118,129,199,227,253,101,253,142, 29, + 59, 64, 8,169,242,245,172, 83,167,142, 60, 56, 56,248, 15, 71, 71,199, 21, 44,203,134, 2, 64,221,186,117,101,141, 26, 53,218, +239,226,226,178,178,108,157, 49,154,148,210, 80,161, 80,184,162, 81,163, 70,251,235,214,173, 43, 3, 0,150,101, 67,249,124,254, +242,224,224,224, 63,170,114,143, 26, 54,108, 56,178, 94,189,122, 41,245,234,213, 75,241,241,241,249,222,222,222,254,226,234,213, +171,173,203,159,123, 89,228, 42, 61, 35, 59,247,250,157,136,232, 73, 35,251,132,213,112,181, 31,100, 81,191,135,185, 49,231, 94, +118,254, 33, 33, 33, 43,204,205,205, 31,206,152, 49, 35,116,225,194,133, 18,173, 86, 11,161, 80,136,234,228,207,234,242, 63,213, +204, 34,118,160,180,109,116,154, 82,226,238, 23, 36,183, 11,234, 13, 59, 51,129,248,198,243, 98, 83, 16,180,129, 86,102, 91, 45, + 77,194,111, 19,145,172,148, 90,250,119,150, 5,135,182, 0, 99, 93, 91,124, 49,166,216, 12, 12, 83, 61,205,255,208, 39, 52, 52, + 84,212,182,109, 91, 56, 57, 57,241,204,205,205, 7,253,163,174,231,127, 81, 51,196,153, 56,155,154,136,110,253, 52,103, 98,144, +147,149,236,144, 49, 38,203,136,238,243,254,118,118,118, 23,214,172, 89, 19,104,106,106,122,217, 24,147,245, 79,184,158,165,230, + 74, 72, 41,189, 89,186, 42, 18, 64,243,247,212, 92, 62,119,238,220, 9, 51,102,204, 64, 65, 65, 1,134, 13, 27,102, 6,224, 39, + 99, 53, 77, 77, 77,189,234,213,171,183,195,223,223,255,101,131, 6, 13, 52,117,234,212, 81,249,248,248,196, 7, 4, 4,108,149, + 72, 36, 30, 31,123,254,252,167,104,254,235, 12, 86,191, 90,164,137,141,131,243,212, 31, 14,222,145, 26, 34,239,226,238,103, 45, + 17,245, 85,103, 72, 99,194, 49, 99,220,183, 82, 51, 51,203,175,251,214, 34,173,170,115,240,152,152, 24,236,221,187, 23, 54, 54, + 54,100,243,230,205,226,190,125,251,142, 54, 51, 51, 75, 12, 14, 14, 30,100,172, 6,143,199, 51,108,217,178,197,164,123,247,238, + 3,172,172,172, 34, 2, 3, 3,107, 50, 12, 99,216,182,109,155, 73,255,254,253,251,106, 52,154, 39, 65, 65, 65,181,239,221,187, +103,184,115,231, 14, 24,198,184,160, 93,120,120,184,254,196,137, 19,175,162, 34,148,210, 39, 75,150, 44, 25,112,224,192, 1, 83, +115,115,115, 54, 48, 48,176,166,171,171,107,196, 15, 63,252, 48,104,255,254,253,166,102,102,102,172,145, 5, 1, 84, 42, 21,164, + 82,233,107, 70,138, 16, 2,165, 82, 9,137, 68,242,154,241, 50, 50, 50,224,111,109,109, 29,181,120,241,226,238, 7, 15, 30,148, +154,154,154, 34, 56, 56,216,207,194,194, 34,122,233,210,165, 61,202,214, 25,139, 80, 40,196,174, 93,187,100,159,126,250,105, 55, +177, 88, 28, 21, 28, 28,236, 39, 20, 10,177,123,247,110,217,160, 65,131,186,200,100,178, 39,129,129,129,254,198,104,233,116,186, +217,119,238,220,113,188,116,233,146,163,155,155,219,184,181,107,215,218, 11, 4, 2, 0,128,193, 96,120, 45,114, 53,168, 87,187, +144, 9,179,215, 92, 80,170,212,154,133,211, 63, 15, 19, 24,208,216,200,168,221, 32, 51, 51,179,196, 47,190,248, 98,204,174, 93, +187,196, 14, 14, 14, 76,120,120, 56, 10, 11, 11,171,124, 45,255,255, 68,175, 8, 15,124, 67, 67, 0,158,225,241, 74,155,250,109, + 7,243, 17,123, 4,141, 60, 76,248, 23, 98, 10,237, 40, 67,221, 0,218, 8,243,194,248, 85,210, 20,208,250, 96,216,218,167, 99, +137, 77,147,206,131,248, 9, 9, 9,240,168, 31,198, 59, 22, 3,123, 74,168, 7, 88, 4, 85, 73,179, 28, 2,129, 96, 78,191,126, +253,228, 9, 9, 9,104,218,180,169, 76, 36, 18,205,254, 32, 81,188,245, 62,110,216,232,211, 18,155,189, 29,113, 41,236, 31,215, +113, 39,196,153, 56,155,153,136,110,238,222,189,215,169,110,199, 47,201,134,161,238, 86,182,102,130, 67,239, 19,201, 42, 53, 87, +231,111,221,186,101,221,190,125,123,204,157, 59,215,214,204,204,236,242, 63, 61,146, 85,222, 92, 17, 66,164,165,213,131,201, 0, + 92,222, 67,115,229,220,185,115, 39,204,156, 57, 19, 55,111,222,196,210,165, 75,209,177, 99, 71, 88, 90, 90, 86, 90,126, 12, 25, + 50, 68,214,180,105,211,240,110,221,186, 61,152, 56,113,226,160,163, 71,143,186,110,217,178, 69,248,217,103,159,137,251,245,235, +231, 54,113,226,196,161,157, 59,119,126,220,184,113,227, 91,125,251,246,149, 84, 49,105,124, 0,162,210, 69, 80,146, 84, 66, 8, + 33,124, 66,136,128,139,176,113, 6, 11,124,138,249, 95, 78, 94, 32,137,219,250, 51,210,247,254, 2, 94, 94, 58, 4,133,217, 80, + 95, 61, 6,221,213,195, 24, 18, 26, 42,149, 18,178,176, 58, 7, 55, 49, 49,129, 80, 40,196,179,103,207, 16, 25, 25,137,206,157, + 59, 11, 87,175, 94,109,225,239,239,255,107,211,166, 77, 31, 4, 7, 7,215, 51,198,176,120,121,121, 97,192,128, 1,162,241,227, +199,215,146, 72, 36,247, 40,165, 2, 15, 15, 15,244,239,223, 95, 56,109,218, 52,119,137, 68,114,135,101, 89,161, 76, 38,123,103, +116,232,109,186, 82,169, 20, 0, 4,181,107,215,190,187,103,207, 30,143,166, 77,155,242,207,156, 57,131,130,130, 2,190,183,183, +247,131,221,187,119,123, 54,105,210,132,127,237,218, 53, 20, 23, 23, 83, 99,117, 21, 10, 5, 36, 18,201, 95, 12,150, 66,161,128, + 88, 44, 54, 58,141,165,230, 98,132,167,167,231,157, 61,123,246,184, 52,111,222,156,119,241,226, 69, 20, 22, 22,194,205,205,237, +238,158, 61,123, 92,154, 54,109,202,187,113,227, 6, 10, 11, 11,141,214, 20,137, 68,112,119,119, 71,191,126,253, 4, 83,166, 76, +113, 17, 8, 4,119, 68, 34, 17,220,220,220,208,175, 95, 63,225,228,201,147, 93, 68, 34,209, 45, 35,171, 12,121,165, 70, 11,253, +250,245,147,203,100, 50, 36, 38, 38,130,101, 89,176,108,137, 39, 77,205,204,126,116,237,206,227,168, 73,163,250,182, 44, 86,171, +213,167, 46,222,125, 82,167,182,155, 11, 33,212,189,146,115,175, 23, 18, 18,242, 32, 44, 44,236,183,195,135, 15, 91,180,107,215, + 78,112,231,206, 29,188,124,249, 18, 98,177, 24, 38, 38, 38,224,243, 63,210,142,178, 5,117,172,193,162, 93, 66,166, 70, 44,182, +112, 49, 53,113,244, 6, 94, 94, 70, 77, 91, 49,120, 12, 79,114,231,133, 66, 14,208,118,168,145,101, 93, 53, 77,182,221,139, 12, +141, 88,103, 21, 96,226,228, 82, 3,217,217,217,112,173,229, 11,149,200, 86,116,253, 89,177, 9, 72, 21, 53, 75,105,208,160, 65, +115, 87, 87, 87, 7,119,119,119,100,101,101,193,203,203, 11, 38, 38, 38,150,129,129,129,237,170,125, 13,182,186,139, 81,128,166, + 0,179, 12, 6, 50, 15, 58,254, 98, 60,203,108,136, 95, 3, 5,255, 56,115,181,103,175,179,117, 13, 63,224,216,231,176,183, 16, + 99,211,232,134, 86,182,230,226,106,153, 44, 66,136,191,189,189,253,249, 91,183,110,217, 72, 36, 18,220,187,119, 15,117,234,212, +193,207, 63,255,108,107,105,105,249,143, 53, 89,111,152, 43, 43, 74,169, 18, 0, 11, 96, 32,170,209,235,181,212,172,252,178, 96, +193,130,113,223,126,251, 45,174, 95,191, 14, 23, 23, 23,100,102,102,162,121,243,230, 9,185,185,185, 21,190,151,252,253,253, 93, +158, 62,125,154, 60,105,210,164,134, 59,118,236,144,202,100, 50,228,229,229,225,183,223,126,195,140, 25, 51, 64, 8, 1,165, 20, +155, 55,111,150, 13, 27, 54,172, 81,108,108,108,178,187,187,187, 49,205, 55, 8, 0, 9, 0, 89,233, 34, 7, 32,219,189,123,183, +121,247,238,221,205, 74,215, 73, 1, 72, 9, 33, 92, 71,175,127,179,193,162, 64, 61, 7, 15, 31,228,159,217, 7, 41,159, 64,202, + 43, 93,248, 4,204,243, 71,112,149, 8,160,163,212,191, 58, 7, 55, 49, 49,121,181, 48, 12,131,212,212, 84, 48, 12,131,217,179, +103, 75,198,141, 27, 87, 87, 36, 18,221,104,209,162,197,226, 10, 79,160, 52, 34,117,231,206, 29,212,174, 93,155,204,156, 57,211, + 44, 44,172,228, 43,246,209,163, 71,240,244,244, 36,139, 22, 45, 50,237,218,181, 43,145,203,229, 70, 71,176, 24,134,129, 84, 42, + 69,171, 86,173,200,150, 45, 91, 76,196, 98, 49,142, 29, 59,134,204,204, 76,180,111,223,158,191,101,203, 22, 19,137, 68,130,203, +151, 47, 35, 63, 63,223,104,221,202, 34, 88,165,166,206, 40,154, 52,105,178,201,193,193, 97,197,246,237,219,197, 82,169, 20, 23, + 47, 94, 68, 94, 94, 30, 6, 12, 24,160,223,185,115,167,196,204,204, 12, 55,110,220, 64, 94, 94, 94,181, 50,199,157, 59,119,224, +229,229, 69,102,205,154, 37, 13, 13, 13,213, 1,192,253,251,247,203,174,179,212,204,204,108,121,179,102,205, 54, 85,164,193,178, + 44, 82, 83, 83, 17, 17, 17,129,231,207,159, 35, 51, 51, 19, 89, 89, 89, 40, 44, 44,132, 94,175, 7, 0,200, 10, 11,142,253,178, +229,200, 3,185, 84, 42, 11,169, 91,187,198,173,123,145, 25,114,169, 84, 86,219,163,134, 55, 33,243,222,122, 97, 67, 67, 67, 23, +243,120,188, 27, 11, 23, 46,172, 55,107,214, 44,113,116,116, 52,238,221,187,247,151,124,245, 81, 26, 44, 66, 8,136,166, 54, 8, +105,120,243,121,177, 85,243, 46, 3,133,120,113, 18, 96,117, 0,195, 71, 88, 61, 23,254,161, 71,197,246,160,168, 7, 53,124, 1, + 35, 28, 59, 33, 4,208,122, 1, 36,232,244, 83,189,117,211,158,163,133,201,201,201, 16, 10,133, 16,139,197,104,216,186, 55,127, +247, 3,157, 3, 8,234, 67, 11, 31,163, 52,203, 33, 22,139,191,251,252,243,207,229,229, 53, 59,117,234, 36,151,201,100,115,170, +109,174,138,101,161,208,211,241, 17,201, 10,247,239,143,165,249,197,102, 40,125, 64,233, 36, 64,215,224,125, 77,150,155,155, 91, +152,183,183,247, 11, 15, 15,143,102,239,101,174, 76, 69, 55,246,236,217,235,108,229, 90, 98,174,160, 87, 1, 2, 41, 28,108, 45, +176,105, 98, 43, 43, 91, 11,105,149, 76, 86,169,185, 58,119,243,230, 77, 27,137, 68,130,240,240,112, 8,133, 66, 72, 36, 18,212, +173, 91, 23, 27, 54,108,176,181,178,178,250, 71,152, 44, 66,136, 37, 33,164, 3, 33,164, 15, 33,164,119, 57,115,229, 1,160, 53, + 33,164, 29, 0, 7, 0,151, 40,165, 15,140,212,108,198,231,243,143,213,175, 95, 63,133,207,231, 71, 46, 90,180,232,171,105,211, +166, 97,229,202,149, 8, 11, 11,123, 62,109,218, 52, 68, 69, 69,233, 21, 10, 69, 55, 74,233,209,138,180,138,138,138, 14,207,154, + 53,203,188,103,207,158,101,255,199,213,171, 87,177,109,219, 54,200,229,175,183,130,232,214,173, 27, 70,140, 24, 97,169,209,104, +254,168, 72,211,222,222,190,205,205,155, 55,235, 0, 16, 2, 16,151, 25,172,199,143, 31, 91, 20, 20, 20, 88,152,152,152, 88, 56, + 58, 58,154,150,153,172,158, 61,123, 90, 8, 4,130,102,224,248,119, 26, 44, 0,208,230,164, 67, 12, 3,164, 60, 2, 25,175,156, +201, 2, 11,126,126, 70, 21,139,218,183, 27, 44, 83, 83,211, 87, 70, 75,169, 84, 26, 29,113, 41, 51, 54,150,150,150, 40, 44, 44, +132, 78,167,123,245,112, 88, 90, 90, 66,173, 86, 3, 0,228,114, 57,170, 25,193,194,245,235,215,113,237,218, 53,240,249,124, 88, + 89, 89, 1, 0,238,222,189,139, 71,143, 30, 65, 40, 20,194,202,202,170, 74,186, 90,173,246,173, 17, 44,173, 86, 11,177, 88, 92, + 37, 19,168, 82,169,232,221,187,119,241,248,241, 99,136,197, 98,216,218,218, 66, 36, 18, 33, 49, 49, 17, 81, 81, 81, 16,137, 68, +176,181,181,173,214,253, 49, 51, 51, 67,110,110, 46, 12, 6,195,171,107, 97,110,110,142,226,226, 98, 48, 12, 99, 84, 58, 89,150, + 69, 74, 74, 10, 50, 51, 51,145,152,152,136,172,172,172, 87, 38,171,172,138,176, 90, 25,151, 97, 64, 8,193,189,123,247,232,249, +243,231, 81, 88, 88,248,151,188, 84, 22, 33,253,232, 88,235,111, 14,157,160,125, 86,145, 78,156,169, 21,154,219,251,183, 5, 94, +156, 0, 24, 62, 32,177, 68,227,128,154, 72,200, 53,200,163,211, 53, 18, 16,116,192, 26,111, 75,163, 52, 13,130,118,153,133, 58, +113,188,214,214,204,175, 94, 32,210,211,211, 33, 22,139, 33, 22,139, 17,212,180, 45, 94,100, 27,100,145,201, 74, 25, 40,218, 27, +165, 89, 74,195,134, 13,107, 73,165,210,208,134, 13, 27,146,242,154,161,161,161, 96, 24,166,110,131, 6, 13,124,171,116,254,171, + 61, 69,208,202, 26,131, 79,199, 71,166, 42,156, 14, 61, 86,121,119,237,209,219,106,229,217, 12,191, 39,105,106, 15, 80,221,100, + 80,109, 96,117, 77,150,187,187,123, 75, 19, 19,147,163,223,125,247,157,135, 88, 44, 62,225,225,225,209,188, 90,229,155,148,183, +254,187,175, 6, 58, 91,150,153, 43,157, 2,224, 75, 1,129, 20,224, 75,225, 96,103,131,133, 35,218, 89,201, 36,130, 63,141,213, +148, 74,165,187,215,172, 89, 99,251,166,185, 42, 91, 26, 54,108,136,217,179,103,219, 90, 89, 89,237,250,155,205,149, 21, 74,218, + 85, 61, 4,240, 7,128,115,229,204,149, 23,128, 63, 75,163, 86,247, 40,165, 9, 70,106, 54,233,216,177,227,133,231,207,159,119, +126,240,224,129, 99, 90, 90,154,239,228,201,147,177,114,229, 74, 76,155, 54,109, 23,165,212,123,223,190,125, 13,110,223,190, 93, +151, 82, 90,105, 68, 44, 45, 45,237,211,105,211,166,101,101,101,101, 1, 0,234,214,173,139,188,188, 60, 76,153, 50, 5, 19, 38, + 76, 40,139,188,130, 82,138,244,244,116, 44, 91,182, 44, 61, 45, 45,237,179,138, 52, 13, 6, 67,226,190,125,251, 26,105,181, 90, + 23,148, 84, 11,138,243,242,242,204,114,114,114, 76,181, 90,173,156,101, 89,185,133,133,133, 9, 0,217,144, 33, 67,248,145,145, +145,126,122,189, 62,153,179, 34,255, 82,131,197, 35,120,248,242,238,101, 88,249, 7,190, 22,189,146,241, 8,164,102,230,120,145, +152, 0, 33, 72, 68, 85, 15, 76, 41,125,205, 96,149,189, 24, 83, 83, 83, 49,125,250,116,197,142, 29, 59, 30,105, 52,154,208,203, +151, 47,207,168,244,195, 27,128,173,173, 45, 18, 18, 18,232,143, 63,254, 88,112,226,196, 9, 61, 0,216,217,217, 33, 49, 49,145, +206,154, 53,171,112,239,222,189,180, 42, 6,139, 97, 24, 72, 36, 18, 92,188,120,145,206,153, 51, 39, 63, 53, 53,149, 90, 91, 91, +195,218,218, 26,103,207,158,213,207,152, 49, 35, 63, 54, 54,246,213,186,170, 24,172, 50,195, 82,222,160,188,203,120, 85,196,213, +171, 87,191,200,207,207,159, 56,101,202, 20,229,147, 39, 79,168,173,173, 45,108,109,109,177,117,235, 86,254,208,161, 67,149, 15, + 31, 62,124,181,174, 58, 88, 91, 91, 35, 38, 38,134, 46, 90,180, 72,121,238,220, 57, 1, 0,216,216,216, 32, 42, 42,138,206,159, + 63, 95,153,151,151, 55,241,234,213,171, 95, 84, 82,224,224,249,243,231,175, 34, 86, 42,149, 10, 89, 89, 89, 72, 76, 76,124,101, +176,148,114,179,142, 95, 15,235, 90,191, 88,169, 84,220,122,244,244,101, 72,195, 58,118,197, 74,165,226,105,220,203, 24, 74,231, +188,181,109,219,181,107,215,102,232,245,250,208, 35, 71,142, 60,218,176, 97,131, 34, 39, 39,231,173,134,253,163, 52, 88, 12,235, + 0, 66,155, 93,121, 90,100,209,174,107,127, 17, 73,187, 13,104,139, 0,177, 37, 32,182, 4, 95,110,141, 78,205, 27,240,182,222, + 44,112, 0,101,155, 64, 40,174,188,125,139,128,218, 3,108,243, 51, 49, 42,203,102,125,198,138,114,114,114,192,227,241, 94,153, + 33,153, 92,142, 54, 61,134, 48,155,111,171, 29, 0,218, 20,132,103,116,155, 25,161, 80, 56,117,216,176, 97,194,220,220, 92, 48, + 12,243, 74, 83, 42,149,162,103,207,158, 98, 83, 83,211, 89, 70,159,251,254, 58, 66, 8,196,141, 1, 58, 33, 58, 77,229,116,248, +145,210,103,242,146, 77, 82,255, 6,141, 48, 50,204, 78,186,228, 88,134,255,131, 68,101, 77,192, 48, 17,122, 77, 80, 85, 77,150, +135,135, 71,115,185, 92,126,236,208,161, 67,178, 86,173, 90, 97,202,148, 41,114,137, 68,114,194,221,221,189, 69, 85,111, 83,113, +145,225,235,249,171,182,167, 63, 92,222, 1,208, 22,151, 24,171,114, 75, 70, 17,139,217,155,206,231,235,116,116,160,177,154, 74, +165,114,232,240,225,195,179,255,252,243,207,191,152, 43,137, 68,130,184,184, 56,124,255,253,247, 57, 57, 57, 57,159,253,205,185, +180, 1,128,251, 0, 84, 0, 90, 2,144,149,246, 20, 12, 5,112,150, 82,106,160,148,166, 83, 74, 83,141, 21,228,241,120,211,214, +174, 93,203, 87, 42,149, 24, 49, 98, 4, 18, 19, 19,145,146,146,130,111,191,253, 54,142,101,217,161,165,154, 15, 40,165, 81,198, +232,105, 52,154,232,220,220,220, 46, 29, 58,116,200,203,205,205, 69,189,122,245,208,181,107, 87, 56, 56, 56,192,201,201, 9,221, +187,119,135,183,183, 55,178,179,179, 49,112,224,192,156,204,204,204, 14,148,210, 10,123,161,103,103,103,199,238,218,181, 43,102, +236,216,177, 13,147,146,146,252, 0, 88, 23, 22, 22,202, 11, 11, 11,197, 26,141, 70,106,105,105,105,217,160, 65, 3,155, 47,191, +252,210,228,254,253,251,126, 73, 73, 73, 69, 0, 18,192,241,239, 52, 88, 90, 96,246,182,125, 91, 85,162, 26, 94, 48,247,169, 15, +153, 68, 2,169, 72, 4,169,165, 53,212, 44,139,141,113,105,138, 98, 74,103, 85,245,192,148,210,215, 34, 13, 6,131, 1,235,215, +175, 87, 45, 92,184, 48, 47, 45, 45,109,212,229,203,151,235,223,185,115,231,161, 49, 70,168,160,160, 0,251,246,237, 83,110,217, +178,229,185, 82,169,108, 40, 20, 10,117, 26,141, 6,187,118,237, 82,173, 88,177, 34, 94,161, 80, 4, 11, 4, 2,109, 85,204, 75, + 89, 4, 75, 32, 16,232, 84, 42, 85,195,221,187,119,199, 30, 61,122, 84,105,102,102, 6,129, 64,160, 83, 40, 20,117,183,111,223, + 30,189,123,247,110,165,169,169,105,149,140, 27,203,178,111,173, 34,100, 89,182, 74, 6, 11, 0,238,220,185,243,155, 86,171, 13, +217,181,107, 87,210,166, 77,155, 84,102,102,102, 0, 0,157, 78, 23,188,109,219,182,164,117,235,214,169,171,210,192,189,180,224, +129,193, 96,192,246,237,219,213,187,119,239, 78,210,235,245,193,101,235, 54,111,222,172,218,190,125,123,146, 86,171, 13,185,115, +231,206,111,149,105, 25, 12, 6, 67, 65, 65, 1,248,124, 62,158, 63,127,174, 46,139,208, 61,123,246,236,149,193,178,179,177,170, +211, 52, 56,192,247,231,245,251, 46,201,197, 98,113,135,176, 32,191,200,167, 9, 73,148,146,248, 74,206,253,225,245,235,215,235, +231,228,228,140,218,176, 97, 67,222,206,157, 59, 85, 6,131,225, 53,147, 37, 18,137, 62,198,167, 86, 6, 2,233,211, 12,181,169, +132,209, 19,196, 28, 44, 49, 87, 18, 11, 64, 98, 9, 72, 44,225,236,236,130,219,113, 10, 83, 48, 16,193,160,179, 51,226,129,148, +131, 64,246, 56, 29,166, 2,145,148,164,165,165,189, 50, 66,101,139,135,151, 31,238, 37, 20,153,128, 80, 49,120,176,175,194,179, +222,197,212,212,148,159,154,154,250, 87, 77, 15, 15,158, 78,167,235, 96,244,185,167, 24, 28, 1,246,171,152, 52,149,227,129, 7, +197, 62, 19, 23,111,150, 74, 13,121,192,221, 85,240,175,229,132,137,125, 26,136,102, 30,206,244,191, 19,175,168, 5, 30, 29, 9, +182,200,232,175, 11, 15, 15,143,102, 50,153,236,196,193,131, 7,101, 50,153, 12,207,159, 63, 71,221,186,117, 49,127,254,124,153, + 76, 38, 59,238,230,230, 22, 86,149,219,116, 51,141, 38, 20, 21, 26, 66,167,238,123,153,246, 48, 85,255,154,185,202, 44,166, 24, +254,195,225,188,220, 2, 85,239, 27, 47,117,231,171,112, 45,239,231,229,229,181,159, 53,107, 86,118,102,102,230,107,230, 42, 33, + 33,161,204, 8,132, 81, 74, 35,254,230, 92, 42, 71, 73,227,117, 31, 0,158, 0,234, 83, 74,245, 0, 10, 41,165,213, 10, 93,215, +169, 83,167,161,155,155, 27,214,173, 91,135,141, 27, 55,230,254,252,243,207,160,148,162,118,237,218,102,213,213, 76, 79, 79,191, + 29, 29, 29,221,161, 94,189,122, 79, 86,175, 94,157,228,232,232,200,126,249,229,151, 24, 62,124, 56,108,109,109, 13, 43, 86,172, +120,217,188,121,243,199,177,177,177,109,139,139,139, 31, 25,113,127,104, 86, 86,214,245, 95,127,253,245,102,235,214,173,101, 67, +135, 14,181, 61,116,232,144,181, 66,161,112, 18,139,197,118, 26,141, 70,244,228,201, 19,222,254,253,251, 29, 34, 35, 35,227,148, + 74,229,109, 90, 58,177, 31,199,191,208, 96,253,254,156, 94, 47, 46,204, 91, 58,127,243, 6,229, 11, 61,129,190,102, 29,168,172, +157,113, 39, 79,137, 41, 79,146, 20,122,150,174,217,247,156, 94,168,110, 4, 75, 38,147,225,220,185,115,134,175,190,250, 74,117, +251,246,237, 95,243,243,243, 93,239,220,185,179,211, 88, 29,150,101,121,159,127,254,121,209,181,107,215,246,165,166,166,250,135, +135,135,191, 96, 89,150, 55,104,208,160,162, 51,103,206,252, 73, 8,241,187,123,247,238,211,106,132,184, 33, 20, 10, 65, 8,193, +157, 59,119,226,114,114,114,252,111,222,188,185,123,198,140, 25, 69,148, 82, 94,120,120,120, 98,113,113,113,189,235,215,175,239, +248,250,235,175,139, 40,165, 60, 99,117,203,204, 91,121, 35, 85, 22,205,170,170,193, 2,128,240,240,240,136,188,188, 60,191,219, +183,111,159,248,242,203, 47, 21,165,230,227, 73, 97, 97,161,239,205,155, 55,143, 13, 29, 58, 84, 81, 21, 61,173, 86,139, 30, 61, +122, 40,110,220,184,113,172,176,176,208,247,206,157, 59, 79,202,214, 93,187,118,237, 68, 94, 94,158, 95,120,120,184,177, 5,248, +252, 21, 43, 86,164, 46, 92,184, 48, 53, 51, 51,243,231,229,203,151,103,218,218,218, 66,171,213,190, 50, 88, 25, 89, 57,231,155, +124, 50,246,135, 29,127,156,189,179, 98,254, 87,173,164, 18,177,104,214,146,205, 23,117, 60,220, 52,210,100,238, 44, 40, 40,112, +125,240,224,193,175, 19, 39, 78, 84,157, 62,125,218, 32,149, 74, 97, 98, 98, 2,177,248, 99,108, 67,106, 40, 0, 75, 82,250, 6, + 89, 38,175, 88,251,155,250,241,139,244, 87,198, 10, 98, 11,220,137,205,195,119,171,247,177,223,119,179,125, 1,138, 68, 48,136, +174, 92,147, 95, 0,150,100, 12,111, 36, 76,250,253,167, 9,234, 23,209,143, 94, 51, 66, 81, 15,239, 96,249,156,177,236,162,174, + 86, 47,192,146, 20, 16, 68, 25,155, 90,189, 94,223,103,241,226,197,197,177,177,177,175,105,198,199,199, 99,201,146, 37, 74,181, + 90,221,219,232,135, 82,204,175,111,160,212,110,231,141,236,218,163,190, 28, 38,149,234,115,128, 91, 63, 2, 2, 25, 32, 54, 71, + 3,223, 90,152, 61,226, 19,193,228,253,105,254, 0,235, 6, 70,232,103,108, 58,249,124,254,177,197,139, 23,203,164, 82, 41,158, + 61,123, 6,137, 68, 2,169, 84,138,160,160, 32,172, 92,185, 82, 38, 18,137, 78,148,181,239,172,178,201,218,253, 44,237, 97,162, + 10, 16, 72,144, 85, 12, 12,255,225, 72,110, 78,190,178, 79, 85,204,213,155, 38,107,194,132, 9,217,233,233,233,144, 72, 36, 72, + 76, 76,196,128, 1, 3,178,255, 33,230, 10, 0,138, 1, 56, 3,136, 1, 16, 11,224, 1, 33, 68,132,247,152,158, 45, 50, 50,242, + 94, 66, 66, 2,190,248,226, 11, 12, 30, 60,216,242,211, 79, 63,197,139, 23, 47, 16, 19, 19,115,255,125, 18,170, 84, 42,239, 36, + 37, 37,213,157, 48, 97,194,108, 23, 23,151, 45,214,214,214, 23,173,172,172, 46,184,184,184,108,158, 49, 99,198,119,169,169,169, +245,181, 90,237,131, 42,220, 31, 74, 41,125, 22, 27, 27,123,120,251,246,237,225, 19, 38, 76,136,251,244,211, 79,147,198,143, 31, +159,250,235,175,191,166,220,191,127,255,105, 94, 94,222,169,202,162, 97, 28, 31, 1,198,206, 10,221,199, 3, 77,135,213, 34,151, + 62,173,137,194,129, 53, 81,244,185, 39,185,218,219, 3,173,171, 51,219,118,195,134, 13,169, 94,175,167,167, 79,159,166,157, 58, +117, 42,110,214,172,217,213,192,192,192,218,213,153,193, 59, 44, 44,236,100, 80, 80, 80,223, 55,215, 53,106,212,168,127,249,117, + 45, 91,182,140,104,217,178,101,126,139, 22, 45,158, 27,147,206, 22, 45, 90, 68, 53,109,218,180,184, 69,139, 22, 81,229,215, 7, + 7, 7,119,111,221,186,245,177,242,235, 26, 53,106,212,237,205,117,239, 58,247,182,109,219, 38,198,196,196,208,151, 47, 95,210, +206,157, 59,167,148,173,111,211,166, 77,226,163, 71,143,232,211,167, 79,105,199,142, 29, 83,170, 59,123,121, 80, 80,208,136,230, +205,155, 95,127, 35,205,195,223, 92, 87,145,102,243,230,205,175, 7, 7, 7, 15,127,115, 93, 80, 80,208,136,247,157,101,221,209, +209,209,187, 65,131, 6, 25, 43, 86,172,160, 53,107,214,204, 40,255,155,127,216,231,223,229, 21, 20, 21, 76,153,191,238,119, 91, +191, 30,117,171, 51,115,123, 96, 96, 96,237, 22, 45, 90, 92,253,228,147, 79,138,111,223,190, 77, 41,165,180, 97,195,134,244,163, +154,181,126,159,159,144,110,240,107, 74,215,251, 29,139,154,227,246,228,179, 16,185, 58,252,167,206,148,158,159, 74,111,174, 27, + 78, 67, 61, 68,134,107, 83, 92, 99,232, 6,223, 19,116,179,119, 11,186,170,150,200, 40,205,141,158,205,233, 6,223, 19,145,179, +221,158,244, 12,180,213,236,222,186,129, 62,123,246,140, 30,222,191,139, 54,174, 41, 43,209, 92,239,119,154,174,243,107,101,148, +230,235,207,124,211,208,208,208,162,223,127,255,157, 62,123,246,140,158, 57,115,134, 54,109,218, 84,209,160, 65,131, 86, 70,159, + 59, 64,232,186, 58, 61,244,107,125,174,204,104,107,146, 55, 60, 68,162, 30,216, 64,164,233,238, 47,212,182,247, 18,234,155,184, +241, 13,245, 29, 25,214,207, 22,180,189,143, 84, 77,215,251, 92,166,235,253, 58, 24,155,206,218,181,107,191,116,119,119,167,239, + 90,188,189,189, 51, 91,182,108,201,175,206,125, 15,177,135, 91, 91,111,113,234,185,249,173,105,215,122,166,217,141, 93,249,173, +223, 55, 47, 1,104, 96, 99, 99,147,181,101,203, 22,106,111,111,159, 9,192,255, 31,145, 63, 75,214, 89, 1,232, 14,192,182,244, +255, 38, 0, 90, 1,168,249, 30,154, 77,218,183,111,175,187,119,239, 30,125,254,252, 57, 61,121,242, 36,109,218,180,169, 30, 64, +216, 63,230,217,228, 52,185,165,220, 66,254,155,209, 73, 66, 72,219,183, 13, 70, 22, 24, 24, 72, 59,116,232,160,188,116,233, 82, +145, 70,163, 25,121,247,238,221,195,239,171,249,223, 72,231,127, 67,179,117,235,214,215, 25,134,169, 89,218, 5, 56,229,236,217, +179, 13, 1,160, 85,171, 86,215,121, 60, 94,205, 82,211,155,114,238,220,185,134, 31,219,185,151,225,228,228,228,205, 48,204, 41, + 0,234,164,164,164, 87,189,157,236,252,187,135, 90, 89,154,183,202,203,203,191,159,246,248,208,137,247, 73,103, 80, 80, 80, 55, +177, 88,188, 33, 52, 52, 84,126,254,252,121, 89,120,120, 56,249,168,174,231,106, 79, 17, 68,162, 32, 80, 76,127,156,172,240,248, +238, 72, 86,173, 79,218, 52, 21,108, 61,120,137, 93,218,203, 46,182,137,167, 60, 14, 2,246, 7, 16,245,109,124, 22,175, 54, 90, + 83, 74, 26,193, 32,152,254, 32, 81,225, 54,229,207, 92,175,182,189,135,243,142,236,217,192,254,216,195, 58,182, 73, 45,147,151, +160,248, 1, 98,197, 13,163, 53, 95,127,238,155,138,197,226, 19, 3, 7, 14, 52,217,189,123,183, 82,165, 82,117,185,119,239,222, +133, 42,157,251, 38,223, 26, 48,144,133,160,212,181,242,175, 71, 60,131, 1, 11,241, 85,212,203,127,194,125,111,236, 64,220,228, +230,226,163, 10,165,126,130, 49,145, 43, 99, 52, 9, 33, 13, 44, 45, 45,119,228,230,230,246, 55, 38,114,245,191, 60,119, 66,136, + 45,128,224,210,168, 21, 1, 16, 97,108,212,166, 2,205,102, 60, 30,111, 90,173, 90,181,234, 61,127,254,252,177,193, 96,248,145, + 82,122,241,223,240,238,248, 55,104,126,108,252, 45,125,216,165, 82,233,189,139, 23, 47,158, 20, 10,133,223, 95,187,118, 77,253, +111,186,224,231,207,159,111,242,182,245, 23, 46, 92,104,242,111,185, 6, 41, 41, 41, 49, 0,220,222, 92,159, 17,113,232, 6,128, + 27, 31,226, 24,119,239,222, 61, 28, 22, 22,118,250,218,181,107, 51,229,114,121,199,143,238, 34,142,141,213, 96,181,231, 93,136, + 68, 75, 2,156,101,211,191,235, 76,201,226, 83,215,221,150,246,178,123, 89,153,185,170, 68,243, 54,164,186, 37,245, 93,101,211, + 23,117, 7,249,225,196, 86,183, 31,123, 88,191,172,204, 92, 25, 67,120,120,248,181,192,192,192, 78,123,246,236,217,166, 82,169, + 70, 84,102,174,222,138, 41,147,134, 98,221, 28,232,120, 1,160, 16, 85, 16,154, 87,128,225, 61, 70, 6,210,255, 41,183,236,102, + 26, 77, 0,224,255, 33, 53, 41,165,247, 1,248,253, 19,179, 40,165, 52, 19,192,177, 15,172,121, 21,192, 85,238,213,205,193, 25, +172,119,112,229,202,149, 64,238,210,115,252,183,185,120,241,162, 26,192,119,165,203,199, 71, 57,147, 21, 88, 67, 58,246,207, 81, + 82, 5, 40, 73,130,128, 93, 81,101,115,245, 22,147,213,200, 77, 58,225,192, 72,169, 2, 20,105,160, 88,254, 62,230,170,188,201, + 2, 80,179,218, 2,125, 34,181, 0,226, 64, 72, 60,230,226,221,141, 21,231,226, 85, 61, 6, 7, 7, 7,199,191,198, 96,113,112, +112,124, 64,147,181,191,206, 29,100,241,166,128, 65, 77, 64,159,128, 98,125, 26,198,198,107,222, 83,243, 22,178,200,120,240,224, + 13,145, 62, 22, 69,154, 52,140,122, 15,205, 15, 77,137,121,122,183,129,154,195,101, 13, 14, 14, 14,206, 96,113,112,112,188, 15, + 37, 81,157,164,210,229,159,171,201,193,193,193,241, 47,130, 0,104,251,142, 15, 68,163, 27,175, 17, 66,218, 86,227, 3,244, 44, +167,201,105,114,154,156, 38,167,201,105,114,154,255, 46,205,202,180, 63,154,198,243,255,205, 46,138,224,186,176,114,154,156, 38, +167,201,105,114,154,156, 38,167,249, 47, 92, 24,112,112,112,112,112,112,112,112,112,124, 80,254,214, 54, 88, 50, 27,111, 71,240, +153,122,132,165,190, 0, 64, 25, 18, 5, 61,251, 80,145, 21,147,250,190,218,196,190,174,204, 68,192,219, 85,164, 51,124, 74,211, + 31, 41, 62, 68,122, 9, 33,205, 80, 50,188, 64, 66,105,119, 97,227,246,179,241, 54,177, 55, 55,105,175,209,104,189, 68, 66,126, +106,122,161,230, 15,154, 25, 89,204,101, 63, 14, 14, 14, 14, 14,142,127,153,193,242,110,210,243,138,137, 76,238, 5, 0, 6,150, +194,192, 2, 5,185, 25, 55, 18, 30,158,233, 9, 0, 78,254,109, 14,136,229, 54,161, 6,150,130,165, 20, 6,150, 66,167, 86, 62, +203,140, 60,102,212,204,243, 38,118, 62, 61,219,182,111,219,171, 75,151, 79,124,234, 6,212,245, 4,128, 71,143, 31,197, 30, 61, +122, 44,218,196,206,231,207,162,140,232, 3,239,115, 98, 38, 2,193,119,193,141, 66, 58,220,185,115,107, 38,128,111, 63,208,245, + 18,210,171,157,183,147,102,199,219, 84,101, 39,123,115,147,246, 61, 58,183,247,157, 50, 97, 20, 25,254,205, 98,151,194, 43, 23, + 38,201, 29,235, 22, 82,170,190,174, 76,127,118,143, 82,202,114, 89,145,131,131,131,131,131,227, 95, 96,176, 76,100,114,175,115, + 7, 55,217, 29,184,154, 8, 0,104,219,208, 1,243,126,218,210,131, 16, 18, 13, 0,189,191,254,201,251,187,137,195,112, 61, 34, + 3,148, 82, 52,240,178, 70,247, 79,199, 24,117, 80,169, 67,157,224,254,253,250,125, 58,101,202,228,110,207,158, 61,139,223,189, +123,247, 21, 0,104,222,162,133,215,162, 69,139,250, 45,179,180, 18, 75, 29,234, 36, 43,211, 34,239, 84,203, 92, 57,120,218,248, +249, 7, 15,223,189,241, 71,126,171, 78, 3,190, 48,113,240, 92, 94,148, 22,155, 85, 29, 45,177,171,127, 77,115,129,112, 30, 97, + 24,190,185,157,187, 29, 0,152, 57,250, 29,183,243,108,102, 48,177,176,123, 80,172, 84,110,203,120,114,114, 99, 69, 19,118,106, + 52, 90,175, 9, 95,127, 78,238, 63,207, 70, 77,255,102,204,170,197, 51,193,234,245,102, 19,103,204,111,127,235, 22, 0,224, 46, +151, 21, 57, 56, 56, 56, 56, 56,254, 5, 6, 11, 0, 76,164,124, 68,191, 72, 3, 0, 88, 72,129, 47,135,246, 65,122,122,154,183, +214,192, 98, 72,255,158,184, 23,149,138,232,184, 76, 80, 74,225,237, 34, 51,250,160, 60,176, 65,159,127,241,121,203, 83,167, 79, +223,254,110,214,119,219, 9, 41, 25,189,123,195,175,191,133,206,158, 51,123,196,224,161,131,219,237,223,191, 63, 2, 64,181, 12, + 22, 35,176, 88,241,195,162,185, 38, 73,153, 42,213,132,201, 83,121,147, 38,142, 91, 6, 96,104,117,204,149,159,171,203,247, 87, + 78,239,151,201,100, 50,108,220,184, 81, 12, 28,194,192,110, 45, 68,157, 63,249, 4,181,125, 3,154,252,184,102,119,189,211, 34, +209, 23, 54,222,237,122,102,197,156,121,107,213,166, 72, 36,124, 54,119,201, 47,190,212,194,151,204, 28,217, 9,117,106, 57, 34, + 57, 51, 31, 45,218,119,231,221,190,125,183, 9,103,176, 56, 56, 56, 56, 56, 56, 62, 46, 42,108,228,110, 48, 80, 68,199,165, 34, + 58, 46, 21,183,163, 50,161,101,121,248,105,225,116,252, 48,119, 42,178, 21,192,129,235,137,136,137, 75, 67, 76, 92, 26,178,114, +139,254,178,255,155, 93, 45,127, 90, 34,107,184, 98,133,249,143,237, 91,200,195,172, 44, 45, 45,159, 70,108, 47,158, 61, 41,221, +111,222,132, 68,161, 64, 98,159,100,105, 95,163,201,190,253,251,235,216,219,218,201,205,204,204,167, 90,249,182,223,100,225, 30, +102, 94,145,230, 95, 76,161,131,127,203,174, 93, 59,119,118,176,183, 99, 71,173, 8,143,170,227, 91, 91, 95,219,219, 55,204,196, +193,167,229,187,246,121,155,166,216,213,191,166,167,163,253,247,151, 78,238,151,169, 84, 42, 60,126,252, 24,217,217,217,165,219, + 3,246,246,142,112,115,113,194, 47,139,167,200,230, 78, 31, 19, 40,150,200, 14, 17, 66,200,219, 52,211,243,139, 78, 31, 59,113, + 38,253,216,158, 95, 88, 0,200,204, 45,198,133, 59,207,112,247, 73, 98,149,110,214,127,163,235, 42,167,201,105,114,154,156, 38, +167,201,105,254, 19, 52, 63, 54, 42,140, 96,197, 38,230, 32,250, 69, 26, 6,119, 9,130,139,179, 35,110,199,228, 34,191, 88,135, +188, 98, 45,242,138,181, 96,249,166, 72, 43,200, 67, 65, 78, 58,158, 38,100,161,178,137, 41,120, 98, 65,255, 9, 19,242,167, 20, + 45,172,157,122,241,196, 88, 56,219, 62,173, 51,109, 90, 94,187, 21, 43,204, 53,118, 14, 22,126,163,135, 15,233,112,232,192, 31, + 68,163,214,192,195,221, 85,210,188, 93,247, 97,191,109,217,233, 0,160,147, 49, 39, 99,107, 91, 71, 46, 54, 49,217,254,253,119, +147, 37,139,127,143,142, 47,214,160,248,207,235,233,207,167, 76,159,109, 54,242,179,126,191,218,218,214,105,144,105, 68,227,114, +177,171,127, 77, 55,107,235,239,175,158,218, 47,211,106,213, 72, 77, 77,133, 70,163,129, 94,175, 47,249, 93, 34,129, 88, 34, 65, +129, 82,143,172,124, 53, 90, 54,111,194,107,120,234,170,175, 86,171, 29, 9, 96,253, 95, 50, 98, 86, 76,145,169,115,128,252,248, +161,189,204,158, 51,247, 97, 33,151,226,250,189,103,184,123,249,184,129, 82,245,245,178,237, 76,157,106,123, 3,146, 83, 32, 68, +252,106,103,194, 38, 21, 38, 61, 10,226,178, 42, 7, 7, 7, 7, 7,199, 71, 96,176,138, 20,197,207,134,142,154, 12, 79, 59, 7, +243,238, 97,126,162,240,216, 60,100,166, 38,224, 89,204, 99, 40, 84, 58, 8, 45,107, 2, 18, 7,184,123,184, 33, 42,233,154,102, +253,186,219,249,172, 94,245,236, 93,122,221,187, 59,185, 56,218,202,153, 31,151,214,184, 25, 19,157, 27,184,107,214, 22,124,250, +169,137,205,143, 75,107,220,140,127, 46,103,100, 98, 67,147,161, 3,186, 19,232, 20,152, 54,109, 10,186,119,233,136,207,135,245, + 35, 59,119,255,222,216,216,147,209,136, 36, 75,102,127, 55,223, 52, 45, 79,171,189, 29, 83,164,150,201,165,210,107, 79,139,138, +253, 61, 44,165,221,250,143, 42, 56,184,123,205,124, 0,147, 42, 51, 87,142,102,102,223, 95, 63,251,135,140, 82,138,228,228,100, +104,181, 90,232,116,186, 87, 6,203,194,194, 2,121,197, 90,104, 50, 20,200,200, 83, 67,111, 96,209,169, 99, 39,217,221,123,145, +131,222,102,176, 0,128,101, 9,171,215,107,113,224,244, 93, 36,222,217, 71, 9, 17,190,106,228, 94,102,174, 28, 28,106, 92,238, +210,107,136,173, 72, 82, 82,221, 90, 88,172,198,182,245, 75,185, 92,202,193,193,193,193,193,241,177, 24,172,152,235, 7,154, 3, + 64, 96,219, 33,233, 38, 18,190, 29,159, 33, 72, 79,138,197,182,101,227,193,178, 20,157, 71,252, 8, 83, 15, 7, 72,133, 60,168, +139,115,242, 83,239,239,179,175,232, 64,132,232,218,173,217,144,236, 49,102,116, 45,179, 93,187,138, 4, 0,176,107, 87,145, 96, +244, 40, 87,179,181, 27,226, 60,154,180,105, 9,106, 48,160, 75,247,222,232, 63,160, 63,226,211, 20,248,227,242, 75, 40,148, 90, +163,230, 63,147,216,123,187, 59,185,122,245, 30, 63,184,141, 41,159, 71, 72,109, 55,115, 94, 98,166, 78,207,227, 9, 12, 71,238, +228,167,244,234,218,195,230,204,145,157, 29, 37,246,222,171, 85,233, 49,241,239,210, 49, 23, 8,231, 93, 59,253,135,140,199,227, + 33, 33, 33, 1, 90,173,246,213,162,211,233, 74,140,143, 82,135,212,108, 53,132, 58, 37, 50,242,212,200, 45,214,194,209,204, 2, + 58,157, 46,224, 93,186, 6, 86,125,164,107,207,193, 93,193, 80,134,165,244,160, 42,237,209,171, 52,148,153,171,142,221, 63,181, +189, 28, 30,139,103,119, 79,228, 82, 86, 95,114, 48,194,114, 83,149,112,112,112,112,112,112,252, 63,195,168,129, 70,147,211,115, + 96,109,194,135,173,147, 7, 6,141,255,169,196, 48, 24,116,160, 20,208, 27, 88, 24, 51,103, 61,165,130, 51, 95,141,246,136,115, +247, 32,249,131, 62,149, 41, 1, 96,208,167, 50,165,187, 7,201,255,106,180, 71,156, 66,107,169,213, 27, 12,184, 22,145,129, 31, +247, 62,193,236,173,143,112,242,174,241,195, 97,241, 5,210, 9, 63, 44, 94, 36,227,243, 8,137, 72, 40, 42, 74,202,214, 23,241, + 4, 2,173, 76, 38,162, 26,202, 87,199,103, 26,178, 59,246, 29, 29,207,227, 9,198, 84,158, 86, 22,148, 82,168,213,106,104, 52, + 26,104,181, 90,104, 52,154, 87, 6, 43,191, 88,135,212, 28, 21, 18, 51,149,120,153,169, 68, 82,166, 18,233,185, 42,188,171, 35, +161,169, 83,109,111,107, 11,171, 11,214,150,166,211,173,204,204,166, 90,152, 88, 92, 44,169, 14,124,221, 92,221,140, 72, 65,236, +253,179,233, 6,173,162, 95, 97,242, 3,251,194,228, 7,246, 92,245, 32, 7, 7, 7, 7, 7,199, 71,104,176, 88, 0, 79, 19,178, + 32,226,179,112,113,247, 4, 45, 55,129, 61, 5,160, 55, 84, 60,169,125, 25,135, 14,165, 36,213,242, 42,102,167, 78,125, 25, 26, + 80,215,250,225,232, 81,174, 81, 1,117,173, 31, 78,157,250, 50,180,150, 87, 49,171, 51,136, 12,148, 82,176, 20,165, 11, 5, 53, +198,185,149, 66, 8,175,113, 3, 95, 55,254,188, 93, 79, 95,142, 89, 27, 19, 45, 20, 10,117, 46, 54, 50,226,102, 47,227,213,176, +149,138,212, 58, 70,237, 83,183,145,150, 0, 13, 43,210,201,215,105,231, 52,235,208, 87,161,213,234,225,234,234,250,154,185, 42, +171, 34,204, 87,104,145,154,171,194,203, 76, 5, 18, 51, 21, 80,168,245,120, 28, 19, 7,194,240, 30,191, 77,211,204,212,234,212, +177,131,251,106,212,247,171,101, 87,199,219,221,110,227,214,237, 53, 36, 18,139, 83,166, 78,181,189,107,120,248,132,223, 58,251, +187,237,205,136, 20, 36, 68,223, 77,211,171, 11,118, 23,167, 71,157,227,178, 38, 7, 7, 7, 7, 7,199, 71,108,176, 0,192,205, +197, 30,183, 30, 39,192,205, 86, 2,115, 51, 83, 68,197, 38,129,199, 8,192, 16, 64,167, 55,222, 4, 81,173,110,239,207, 63,155, + 47, 75,136, 51,220, 90,187,238,249,179,132, 56,195,173,159,127, 54, 95, 70,181,186,189, 64, 73,239,188, 18,147, 85, 98,180, 12, + 85, 24,126,147, 82,214,206,214, 66,194,191,251,188, 56,155, 97,120,106,107,115, 9,107,109, 46,102, 28, 45,196, 2, 23,107,161, + 80, 36, 98,224, 96,107,163, 7,165, 21, 86,101,170, 19, 35, 94,164, 22, 20,204,108,222,190,183, 66, 32, 16,192,195,195, 3, 26, +141,230,181, 70,238, 25,153,185,175, 34, 88,169, 57,106, 72, 69, 12,238, 95, 59,167, 48, 24,116,219,222,166,201, 19, 8,205,109, +108,172,241,237,130,159, 49,117,206,207, 72, 46,224, 67, 40, 22, 59,184,123,248, 63, 24, 58,102,150,236,235, 13,207, 48,180,133, + 57, 20, 89,177,201,138,116,201,116, 46, 91,114,112,112,112,112,112,252,255,166,242,169,114, 40, 96, 34,147,128,242, 36,184, 18, + 30, 11,159, 58,245,176,245,240,109,120,213,109,140,212, 66, 61,170, 50,157,225,228,233,138,123, 0,238,117,239,238,228,210,179, +167,115, 59, 74, 5,103,214,174,207, 79, 2,128, 77, 71,122,129, 2, 96, 89, 90, 98,180, 74, 71,136, 55, 22, 2,164, 36,164, 23, +154,122, 56,200, 17,153,164, 85,203,197, 66,198, 82, 46,226,217,154,139,132, 66, 62, 31, 6, 74,212,217, 57, 25,133, 0, 73,169, + 76, 75,157, 24,241, 66,236,234, 63,179, 69,167, 1,223, 95, 57,249,187,204,211,211, 19,247,239,223,127,101,176, 10,139,138,145, + 83,160,132,204, 10,240,118,145,227, 73,248, 21, 67,118, 70,114,100,110,204,201,141,111,211, 99, 89,240, 84, 90, 3, 30, 60,207, + 71, 94,177, 14,121, 69, 90, 52,109,213, 85,216,180,109, 55, 92,126,156,133,220,124, 5,230,110,249,179,192, 64,117,253, 41,141, +212,113,217,146,131,131,131,131,131,227,255, 55, 70,185, 35, 3, 75, 97, 99,109, 5,137,220, 12,113,233, 90, 20, 18, 59,228, 42, + 40, 12,134,138, 35, 88,132,144,182,111, 91,127,232, 80, 74,210,193,131,153,155, 14, 29, 74, 73, 42,239,228,216, 87, 85,132,165, +127, 89,106,180, 38,165,134, 19, 71,206, 92,207,233, 22, 98,107,201,240,120, 74,161,128, 81,243,133, 60,173,144,207,232,132,124, + 70, 99,111, 38,224,157, 63,188,147, 33,132,158, 55, 70, 83,157, 24,241, 34, 46, 35, 99,102,235, 46, 3, 21,118,246,246, 24, 60, +120, 48, 92, 93, 93, 1, 0, 38, 18, 2, 27,145, 2, 60, 85, 10, 46, 29,222, 92, 28, 21,126, 33, 28, 6,117,207,242,163,185,191, +166, 73, 41,155,149,167,134, 82,163, 71,110,145, 22,185,197, 90,232,109, 67,113,240,122, 10,178,242, 53,136,189,190, 93,161, 86, +228, 78, 80,165, 63,141,171,208, 68,190,227,220,223, 7, 78,147,211,228, 52, 57, 77, 78,147,211,252, 39,104,126,108, 24, 49,217, + 51, 69, 45, 71, 57,188,156,229, 80,105,237,160,210, 24, 80,172, 50,160, 64,161, 69,129, 66,135,184, 52, 5,158, 94,120,255,132, + 80, 0,148, 5, 8, 74,170, 10, 65, 74,140, 29, 37,198,237, 95, 44, 40, 88,246,227,162,185, 3,246,236,251, 19,227, 62,113,116, +125, 24,167, 73, 33,132, 81, 50, 60,190,206,202,148, 47,120, 30, 27,157,122,233,244,254,160, 98,145, 98,184,177,105, 42,139,100, +249, 52,108, 61, 15, 20,124,141, 50, 95, 62,189,105, 29, 60,120,240, 80, 21, 21,155,166,231, 73, 44, 30,178, 6,237,142,220,152, +138,167,202, 97,132,146, 39, 55,195, 31, 53,150, 90,187,161, 72,169, 67,161, 82, 7,133,186, 36, 26,246,242,254, 33, 77, 94,114, +212,239,133,201, 15,182,114,217,145,131,131,131,131,131,227, 95, 98,176, 20, 74,197,179,118,189,134,191,154,208,217, 96,160, 96, + 89, 10, 67,105,132,137,165, 20,122,173,242,217,251, 38,196,192,178,183,215,109,221,211,185,126,131,198,188, 58, 53, 76, 80,144, +155,137, 59,183,110,232, 41,203,222, 48,202,160,197,199,171, 77,236,125,251,245,235,221,115,207, 23,163,198, 21,180,104,209, 74, +108,109, 99,166, 77,207,204, 40,216,185,113,183,225,232,159,123,130,192,178, 67,104,124,188,186, 42,233, 82, 39, 70,188, 0, 48, +168,212,177,183, 6,234,180, 84,102, 62,237,162,200,136, 57,111,172, 70, 86,114, 98,175,159,126, 88, 24,223,109,208, 87, 34, 75, +123, 79,104,116, 60,164,167,167,227,249,237, 3,170,162,148,136,131, 69,201, 15,134,115, 89,145,131,131,131,131,131,227, 95,100, +176,158,222, 40, 25, 15,235,191, 77, 78, 78,250,224, 29,187,255, 92,184,115,239,225,166,106,173,214,153, 5, 47,209,160,211, 93, + 18, 23,102,207, 54, 86,163, 40, 61, 42,146,184,187, 7,253,246,203,178,137,191,174,249,185, 13, 88,131, 15, 8,137, 35,132,158, + 47, 18, 42,190,172,170,185,122,155, 87, 34,205,142,183, 7, 80,165,137,163, 21, 89, 81,105, 38,246,181, 92,119,255,186,244, 71, +134,225,181, 55, 24, 88, 1,107,208, 61, 51,104, 85, 63, 40, 51,163, 15,211,170,116,151,228,224,224,224,224,224,224,248,255,111, +176,254, 87,228,196,222, 42, 4, 48,238,125,117, 74, 77,212,226,210,229,131, 66, 41,125, 12,224,113,117,246, 45, 74,127,158,137, +106, 76, 56,205,193,193,193,193,193,193,241,255, 15,134,187, 4, 28, 28, 28, 28, 28, 28, 28, 28, 31, 22, 2,224, 29,189,242,140, +159, 41,187, 58,189, 9, 42,211,231, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78,243,227,211,172, 76,187, 42,254,227, 31, 13, 45, + 29, 49,253,191,177, 0,104,203,105,114,154,156, 38,167,201,105,114,154,156, 38,167,249,111, 91,184, 42, 66, 14, 14, 14, 14,142, +127, 29, 54,222,221, 76,108,188,187,153, 24,187,189,109,157,190,246,182,117,250,218,115, 87,142,195, 88,248,220, 37,120,127, 8, + 33, 98, 0, 44,165, 84,251,119,165,193,210,178,166,153,222,212,230, 0,195,170,127,200, 79,124,120,230, 67,159, 95,157, 58,117, + 26, 0, 64,100,100,228,125, 74,233,251,246,198,132,220,222,103,160,165,153,197, 72, 45,171, 49, 40,138, 21,235,138,210, 98,246, +127,200, 52,219,218,214,145,107,196,210,165, 32,180, 19, 40, 24, 74,200,121, 94,161,110, 98, 94,222,131,252,138,246,171,209,125, +177,239, 23,253, 62,153,181,233,247, 99, 11, 95, 30,154, 17,245,230,239, 86,157, 86,155,142, 29,210,126,218,154, 61,135,150,100, + 29,158, 90,196,229,254,170, 83,163,217,167, 22,122,190, 3, 47,229,226,178,236,170,236,231,226, 19, 26, 33, 16, 8,108,181, 90, +109, 70,114,204,205, 0, 99,246,113,245,109,114,143,199, 99,156, 12,122, 54, 41, 49,250, 58, 55,113,186, 17, 72,237,106,133, 66, +175,255,150, 2, 4,132,255,147, 42,251,249,123,141,116,232,228,228, 36, 53, 55, 55,111, 97,102,102,230, 42,147,201, 36,185,185, +185,202,220,220,220,151, 9, 9, 9,231, 41,165,250,191,227, 28,109,253,123,204,224,139,152, 57,165,255,158,151, 25,113,112,113, +197,219,119, 95, 72, 24, 50,163,244,223,139, 51, 35, 14,205,250, 39,220, 43,251,186,189, 66, 64,217,137, 12,195,107, 98,160,250, + 69, 25,143, 14,173,173,202,254,161,161,161, 61,116, 58,157,184,236,255, 2,129, 64,125,227,198,141,131,220, 83,240, 55, 25, 44, +151, 58,125, 45,117,124, 58,151,207, 99,122,179,148,154,166,222,223, 39,255, 39,159,160, 91,200,144,187, 12,195,184,148, 95,199, +178,108, 82,194,173,237, 31,164,176, 37,132,184,252, 52, 33,112, 90,122,182,178,128, 16,178,224, 93,230,195,190,193,192,235,132, + 33, 53, 9, 33, 96, 24, 2, 94,201, 0,170, 41, 47,111,237,104,248, 22, 77, 71, 51, 57,223,187,160, 88,255,152, 82, 90,233, 75, + 72,106, 93,219, 73,102,237,124, 41,172,199, 88,143,187,167,183,248,153,216,251,182, 41, 74,143,138,252, 0,231,102,235,233,233, + 25,236,237,237,109, 61,118,236, 88, 33, 0, 44, 95,190,220,203,203,203, 43, 59, 54, 54,246, 14,165, 52,179, 90,230,202,206,119, +240,202,101,243,183,119,234,212, 25, 41, 89,197, 88,250,243,154, 48, 19, 7,239,190, 31,202,100, 17,167, 64,169,133, 92, 30,241, +245,196,217,206,157, 91, 5,243,115,139,181, 56,126,254,246,160,253,155,126,104,109, 97, 81, 63,160, 34,147,197, 42,242,103,217, +155,208,142,172, 34, 31, 0, 6,190,249,187,179,137,174,173,173,212,208,209, 81,204,191, 15,224,207, 74, 95, 46,193, 67, 79, 9, +132, 66, 55, 66, 24, 48, 4,224,241, 8, 24, 66,192, 16, 64,175,211, 36, 60,187,178,185,195, 63,162,160, 14, 28,156, 70, 8,177, +102,152,146,244, 17, 2, 48, 12, 3,126,201,200,191, 5,207,175,111,177,254, 0,249,201, 60,192,203,194,255,147,166,205, 54, 95, +122,145, 35,175,209,114,226, 49, 66,153,181, 9,151,127,122, 96,204,254, 18,137,196,242,200,145, 35,182, 29, 59,118, 52,183, 15, +232,113,201,152,125, 76, 68,146, 58, 71,143, 30, 22,118,236,216,161, 10,249,211,167, 29, 24,102, 7, 1, 4, 44, 75,151,243, 88, +250,123, 81,118, 76,108, 85,135, 83,177, 11,232, 49, 31, 4,126, 70,239, 64,241, 36,227,241,193,217,213,188,182, 60,169,157,207, +103, 82,137,100, 74,109, 31, 63,239,184, 23,177, 49, 5, 5,249, 63, 43, 51, 98, 54, 81, 74,217, 42,137,233,244,223,156,189, 18, +222,137, 47, 16,144,142,109, 66,120, 0,222,203, 96,217,219,219,247, 88,189,122,117,173,208,208, 80, 0,128, 94,175, 55,219,183, +111,159,195,130, 5, 11,228,198, 60, 67,111,195,217,217,217,217,220,220,188,134, 84, 42,117, 6, 0,165, 82,153,156,159,159,255, + 50, 57, 57, 57,185,178,125, 29, 26,244,181, 97, 24,204, 63,249,231,175,124, 0,232,208,107,228, 66,143,176,111, 44, 9, 79,160, +124,219,246, 6,189, 70,206, 16, 50,241,220,145, 45, 4, 0,218,116, 27, 54,221,182, 78,223, 95, 50, 35,247,165,255, 45, 31,244, +125,251,242,108,158,106,123, 16, 74, 38, 5, 6, 5, 55,238,221,189, 19,252, 60,157,208, 99,192,232, 41, 0,170,100,176,116, 58, +157,120,255,254,253, 46, 12,195,240,244,122,189,170, 95,191,126, 25,239,147,182,218,205,134, 94, 7, 33,174, 90,189,254,183,132, +155,158, 11, 41,157,195,190,153,118,199, 56,254, 76, 16,102, 4,101,217,196,212,123,187,155,112, 6,171, 20, 27,239,110, 38, 60, +177,240,113,171,230,141,173,167,143,238, 41, 90,255,251, 21, 56, 53,232,151,156,114,255,119,231,127,234, 9, 50, 12,227,114,112, +215,106, 59,153,136, 7, 0, 40, 82,233,209,107,112,229,163, 65, 56, 7, 15,186, 8, 2,159,178, 58, 84,131, 65, 47,225,243, 5, + 42, 2, 0,164,164,119,128, 84, 42,186,185,105,102,104,254,176,174, 53,135, 76,251,229,222, 86, 0, 22, 0,210,222,250, 80, 48, +140,203,158,205,203,237,156,173, 37,224,243, 8,138,148,122,244, 28, 50,201,240, 54,195,182,105,102,232,252,193,157,220,251,219, +117,252,163, 23,128, 19, 21,190, 64, 28,234,248,154,218, 56,157,233, 61,114,190,147, 2,102,248,110,225,114,187,107,167,247, 93, +105,219, 99,184,246,101, 82,146, 66,175,213, 69,103,231,164, 78, 46, 76,137,121,106,108, 65,109, 98, 98, 82,203,196,196,164,126, +167, 78,157, 36, 83,166, 76, 17,132,133,133,189,250,253,203, 47,191, 20, 94,188,120,209,113,217,178,101,157,157,156,156, 84, 69, + 69, 69, 15,138,138,138,158, 83, 74, 13,198,222, 19, 7, 7,219,175,123,247,236,138,214,189,190,130,129, 37,248,114,204, 68,156, + 58,241,231, 40, 0, 31,196, 96,153,240,152,121, 35,198,126,235,220, 34,180, 33,127,241,190,167,176,144, 9,209, 62,164, 33, 95, + 34,248,198, 97,247,111,203,126, 6,240,249,219, 34, 87,172, 34,127, 86,128,141,102, 64,183,208,154, 56,188, 91, 51,192,165,237, + 52, 48, 50,243, 87,145, 44,207, 78,227, 76, 45,165,210,213, 78, 22, 60, 59,177, 33,115,181,103,167,113,103, 99, 79,172, 42,172, + 40, 45, 2,161,208,109,211,234,239,107, 91,154, 10,193,103, 8,120, 60, 2, 62,143,129, 74, 99,192,144,209, 51, 62, 84,132,145, + 39,181,171,221,153, 1,134, 1, 0, 11,108, 81,102, 60, 61, 94,149,123, 66, 24,158,245,190,205,203,248,118,230, 98,240,120, 4, + 60, 6,224, 49, 4,241,233, 74,140,157, 50,215,252,125,141,122,167,166,118,193, 23,127,105,217,161,113,128, 85,189,189, 55,136, +121,227, 78,253,173,179, 84,178,207,246, 28,186, 48,160, 70,139, 73,183, 40,101,127, 76,188,178,226,116, 69, 58,106,181, 58,189, + 67,199, 78,102,132, 47,151,157, 61,184,181, 5,159, 33,208, 25, 40,244,134,146, 65,144, 89, 74, 81,242,221, 82,242, 17, 67, 89, +138, 17, 35,190, 64,135,142,157, 20,172,158, 77,170, 66,161,177,227,228,217,107,182,106, 29,139,101,171, 55,205, 47,206,207,156, +255, 34,202, 58, 94,102,239, 61, 81,145, 30,115,216,248, 19,135, 95,204,245,125, 61,119, 29,189,137,128, 58,126, 37, 3, 53,179, + 20, 62, 46,114,236, 58,118, 19,190, 62,190, 37,233,102, 41,188, 93, 77,208,242,147, 33,213,188,190, 97,124,185,189,239,238,110, +125,134,246,233,213,103, 32,172, 44,205,160,209,170,189,207,157, 58,254,235,186,213, 75,155, 18, 66, 62,171,146, 57,164,134, 87, +239, 5,202,178,239, 93,203,225,228,228,100, 27, 28, 28,252,234,255,122,189, 30, 30, 30, 30, 72, 78, 78,246,169,134, 89,147, 57, + 57, 57,125,178,116,233, 82,187, 86,173, 90, 9,108,109,109, 1, 0,153,153,153,206,151, 46, 93,106,216,176, 97,195,140,148,148, +148, 99,233,233,233,138,119,154, 10, 86, 37,228, 81, 62, 79, 44,150,150,250, 90, 48, 83,198,126, 90,207,214,214,246,173, 31,199, +217,217, 57,162, 57,115,102, 19, 62, 95, 80,178, 61,165, 12,101, 13,239,156, 99,164, 73,147, 38,221,180, 90,173,228,109,191,101, +233,109, 59,171, 88, 81,255,146,183, 8,192,231,241,114, 83,238,239,183, 53,218,180,215,235,222,222,145, 17,172,235,218,189,187, +123,143,206, 97,112,180, 53,199,249,155, 49, 24, 63,243, 39,232,244,134, 21,213,185, 63, 60, 30,143,159,145,145, 17,111,105,105, +233,240, 1,222,183, 53, 15,237, 90,101,119,225,202,221,233,191,136,247,140,174,213,108,152,174,164, 61, 82,201,204, 44, 62, 18, + 51, 65,203, 30,109,205,172,156,125, 37, 27, 87, 47, 22,112, 17,172,242, 55, 66,196, 91,208,172, 73,176,245,244, 9, 95,136, 22, +108,186,132, 27,167,142, 41, 83,238,239,251, 32,230,202,212,206, 39,148,240,248, 35, 9,143, 39, 39, 12, 17,177, 6, 54, 81,175, +209, 44, 84,100,197,164,190,175, 54,203, 82,252,113,189,138,198,156, 82,175, 95,127, 89,102,103,111, 33,134, 74,107,192,176,175, +191,195,134, 21,243, 77,109,205, 69, 80,107, 13,216,122,248,110, 86, 93,197,114, 58,172, 99,205, 33,223,111,138,248,243,199, 29, + 81,127,150, 60,171,239,204,120,176, 51, 23,227,251, 61, 49, 48,147, 10, 96,105, 42, 4,195,188,221, 92, 13,235, 90,162,153, 87, +168,209, 19, 66, 68,148, 82,205, 91,141,132, 99, 64,115, 51, 91,151,253, 61, 71,204,183,141, 73, 39,160,208, 34,214, 76,130,222, +131, 71, 91,212,114,144, 66, 46,225, 33, 62, 49,213,227,155,169, 83,131, 36,142,190,193,170,212,168,151,149,157,182,187,187,123, +175, 46, 93,186,200, 38, 79,158, 44,112,117,117,197,142,125,167,220,218,245, 25,215, 53, 57, 45,219,149,165,128,189,157, 85,226, + 23,253, 59, 31, 57,126,252,120, 66, 98, 98,162, 96,233,210,165, 33, 7, 14, 28,168, 83,149, 47, 81, 3,165, 80,169, 13, 48,148, +190, 24, 51,243,213,213,120,169, 16,230,221, 95,230,180,123,135,176, 96,254,242,131,207, 81,168,208, 67, 38,226, 35, 54,181, 24, +161, 33,193,252,189, 27, 73,171,183,237,241, 69,191, 79,102,217,155,208,142,221, 66,107,194,206, 82,134,205,191,124,143,195, 55, + 94,116, 76, 47, 34,176,233,182,116,164,163,152,223,206, 86, 38, 92, 29, 22,228,233,208, 58,208, 13,119,130, 60, 29, 46,135, 71, +199,212,237,247,243,216,228, 34,193,217,156, 19, 99,223,106,180, 24,194,192,202, 84,136, 77,167, 18, 32,147,240, 33,151,240, 33, + 23,151,252,101, 24,242, 94,249, 90,234, 84,199,149,199, 26,190, 48,115,170,243,197,128,126,125,157, 62, 29,208,151,130,199, 96, +223, 31, 71,186,239,220,185, 35,213,196,193,103,163,129,225,109, 82,166, 68, 38, 86,126, 61, 1, 59,115, 17,190,217,248, 24,102, + 82, 1, 76,101, 2,152,201, 4,104, 93,207,182,218,233, 36,132, 88,142,234, 94,171,243,195,237,109, 91,249,212, 48,169,253, 32, + 54, 63,242,139,133,119, 87, 92,204,107, 53,225,151,229,117,172,139,242, 52,252,217, 83, 70,240,147, 82, 82, 90,237, 59,114,169, +181, 83,163, 47,162,245,218,226,111, 51, 30,252,126,232,109,122,137, 81,215, 27,186,132,246,149,104,139,116,143, 30, 68, 39,121, +230,170,197,136,136, 47,128, 92,194,135, 73,217,181,149,240, 33,151, 8, 96, 34,225, 35, 37, 41, 14, 57,197,188,171,201,214, 76, + 43,122,241,122,149,170,162, 84, 90, 3,238,191, 40,130,187, 79, 3, 56, 58, 58, 65,211,121,144,251,173,243,127, 28,146, 59,250, + 45, 46, 78,125,242,173,177, 58,187,142,222,196,130,197,203,159,130,224, 73,233,219,220,111,242,164,177,181,127,250,121,245,107, +235, 70,127, 53,166,118,117,205,181,204,222,103,103,203, 79, 6,247,169,219,184, 61,158,199,197,225,196,145,187,104,211,174, 19, + 58,119,237, 5,141, 70, 61,100,211,134, 85,119, 0,172,249, 75,153,235,232,215,172,110,128,223, 78,103, 39, 39, 87,150, 45,153, + 3,150, 82,160, 89,203,214,152, 58, 97, 4, 88, 74, 81,191, 97,163,214,157, 7,140,165,148,150, 24,193,172,236,172,226,232,168, +200,182,202,244,168, 91, 70, 95, 75,149, 74,151,153,153,137,251,247,239, 35, 38, 38, 6, 17, 17, 17,200,206,206,134,185,185,121, +149,170,216, 45, 45, 45,205,130,130,130, 62,253,253,247,223, 37,230,230,255,241,252, 26,141, 6, 50,153, 12,221,186,117, 19, 52, +107,214,204,121,232,208,161, 67, 45, 45, 45,119,229,230,230, 22,188,213, 48, 61, 60,154,226, 80,183,199,250,206,125,190, 28, 13, + 0, 66,177,201,139,149,191,253, 25, 81,209,177,133, 18, 51,183,182, 61, 62,247, 4,165, 32,132,172,204,138,250, 51,237, 93,219, +106,181, 90,233,222,189,123,157, 9, 33,175,189, 95,231,173,220,211,244,241,179,180, 54,235,230, 78,227,155,153, 72,144,153,167, +198,200,209, 99,109,140, 54, 87,117,187,143, 9,110,216,112,205,119, 83, 70, 64, 46,147,226,244,173,231,152, 56, 99,137, 62, 39, + 43,125, 59, 8, 89,158, 25,113,224,125,107, 45, 62,200,128,215,181,157, 77, 96,218, 33, 84, 50,162, 95,152, 68,163, 51, 32,175, + 88, 7,181,214, 0, 3, 75,145, 95,172, 67,228,203, 66,216,152,137,176, 17, 31, 63, 85, 50, 88,124,129,168,203,184,207, 58,139, +150,237,186,133, 27,167,118, 41, 83,238,237,147,149,253,230, 26, 52,224, 69,226,221, 61, 53, 95,247, 40,149,119,181,148, 58,213, +113,229, 19,222,207, 45,195, 90,180, 31, 61,102, 12,124,106,185, 8, 13, 6, 3,125, 28,243, 66,183,117,211,230,207,204, 93,235, +174, 40, 72,122, 60,171,236,101, 90,213,238,155, 44,203, 38,189, 25,177, 98,217,215,191,102,223,166, 73, 8, 96, 97, 34,194,250, + 19,113,160, 20, 32,160, 48,151, 11,176,231, 98, 18,242,179, 83,178,234, 41,150, 95,251,162,163, 77,183,133,155, 34, 15,173, 61, +146, 30, 14, 32,130, 82,154,254, 46, 77, 66, 8,248, 60, 2, 51,153, 0,230, 50, 33, 44,228, 66, 48,132,188,211, 92,125,247,235, +195,173, 0,162,203,155,171,242,154,114,123, 31,127, 51, 27,183,131,189, 70, 45,182,124,248, 82, 11, 62,143,160,166,131, 20, 86, +166, 66,104,244, 4,241,153,218,210,125,204,240,213,228,121,182,211, 38,141, 62, 78, 72, 88, 61, 74, 47,234, 43, 58,119,133, 66, + 33, 26, 60,120,176, 64,167,211,105,135,141, 95,216, 62, 45, 35,187,251,138, 69, 83,197,182, 54,214, 40, 86,233,112,239, 73,130, +223,146,101,191,212, 60,118,238,230,193,111,191,234,121,168, 99,199,142,230,123,247,238,101,171,114,223, 51,211,179,126,217,188, +115,255,246,229,203, 22, 33, 58, 33, 23,155, 54,172, 1, 53,232,215, 87,236,119, 95,215, 92,189,122,181,125, 72, 72, 8,115,251, +246,237,172, 55, 13, 40, 33,144,103, 23,168, 97, 33, 23, 66, 38,230,195,222, 82, 2,107, 19, 17, 68, 2, 6, 12,243,159, 66,164, +188,230,166,223,143, 45,100, 21,249, 56,188, 91, 51, 96,243, 47,223,227,243,175,103,226,113,150,232, 36, 35, 51, 95,248,213,128, + 94,211,109,165,134,142, 78, 22,140, 93,235, 64,119,200, 37, 66,204, 24, 55, 24,141,194,227,237,146,243,216,153,153, 74, 94, 3, + 0, 51,223,150, 78,166, 52, 98,101, 42, 19,224,226,209,221, 25,197,133,121,249,132, 87, 82, 69,168,211,104, 19,140,243,250,127, +189,158,114,123,159,233,129, 13,234,125, 63,250,203, 47,152,166,161,141, 40,195, 8,144, 85,168, 33,148, 2, 19,198,142,194, 87, +163, 70, 56, 36,166,100,204, 94,179,102,253, 44, 19, 59,191, 5, 69, 25, 79,230, 86,164,201, 35, 12, 24,134,192, 68,194,135,137, +180,196,176,152, 72,248, 80,105, 12, 32, 4, 60,151,192, 1,249, 32, 0, 33, 36, 37,241,206,110, 63, 99,210,233, 84,183,211,185, + 75, 25, 66, 95,197,113,213,141,103, 79,239, 45,188,253,240,229,109, 74,105, 78,141,150,147,134,106,245, 20, 69, 42, 61,226,210, + 21,208,107, 41,249,188,147, 27, 60,250, 16,159, 69,155,239,109, 39,132,152,149, 69, 92,222,212, 76,186,177, 79,101, 83,183, 87, +255,229,171, 54,220, 89,246,253, 76, 94, 86,190, 6, 44,165,144,136,120,144,138,248,165, 11, 15,202,226,124,172, 89,247, 91,154, + 30,164, 23,189, 88,113,158,255,107,161, 65, 7,245,236,220, 98, 15, 1, 68,132, 17, 38, 57,185,185,187,181,233,250,153,164, 77, +183,193, 48,232, 53,211,229,246,190, 23,138,211,163,206, 25,163, 25, 80,199, 15, 32,120,146,241,232, 96,175,146,151,100,143, 63, +125,125,124,107,191,185,206,203,203,167,182, 49,247,189,236,227, 66,106, 91,251, 75, 47,223,186, 83, 71,127,183,193, 61, 46, 85, + 1, 43,215,218,136,120,116, 31, 39,246,254,114, 79, 89,152,187,236,196,225, 63,167, 46,248, 97,101,253,174, 61,250,225,208,129, +189,147, 9, 33,107,105, 9,103,203, 69,167, 6,109,221,248,171,171, 64, 36,134, 78,207, 66,103,160, 37,127,245, 6,228,228,228, + 66,167,103, 33,145,153, 66,207, 18,232, 12, 44,116,122, 22,106,141, 94, 62,106,240, 39, 99, 0,220,122, 91, 58, 61, 66, 6,223, + 5, 67, 92, 74,214,151,172, 19, 49,230, 10, 71, 71,199,237, 0, 32, 22,139, 33, 22,139,193,178, 44, 30,165,144, 9, 78,193,131, +102,128,150,190,217, 89, 54, 41,245,222,238,160,119,157,187,171,171,107,215, 55,205,149, 74,165, 66, 81, 81, 17,174,221,121,104, +190,109,223,217,142,241,137,105,181, 88,131,157, 90,234, 80,191, 3,128,174,239,186,158,105,143, 14,142,169, 17, 54,129,153, 60, +122,176,215,202,223,246,223,126,122,114, 65,133,225,228,154,109,167,107,166,142, 25, 24,244,195,202,205, 79,147, 46,173,152, 88, +217, 61, 18, 10,133,130,204,204,204, 87,207,247,252,213,127,116,122,153, 94,208,102,217,247,179,132,247, 94, 20,225, 81, 92, 26, +134,182,173, 97,244,243,238,232,223,211,199,205,195,117,197,138, 5,227, 17,147,162,196,234, 63,110,227,210,177,237,225, 90, 85, +225, 39, 25, 17,135, 51,170, 83,134,188,175,193,170, 72,243,194,195, 44, 20,169,244, 80,107,244,208,177, 20, 5, 10, 29, 50,242, + 52, 40, 80,104, 81,164,212, 99,104,187, 26,248, 55, 80, 37,131,101,208,235, 92,156,156, 28,193,210,164,178, 8,103, 73,212, 35, +100,128, 98,226,151,125,165, 78, 13,250, 20,167,220,223,111,116,155, 44, 83, 59,239, 38, 82,169,236,216, 79, 63,253,132, 1, 93, +155, 75, 95,102,233,138, 30,190, 84,166, 23,107,160,183,179,245, 22, 45, 92,180,196,100,201,210, 31,191, 58,122,152,205, 3,240, +227, 91,195,207,193, 3,239,242, 72,185, 54, 86,132,128,178,108, 82,210,157, 93, 65, 0,240, 62,109,173,138, 84, 58,240,152,146, +182, 51,132, 0, 10,149, 30,197,185,105,217,229,205,213,173,100,135,231, 60, 94,166,150, 82, 90, 97, 21, 4, 67,128, 2,133, 14, +230, 50, 1, 44, 76, 4, 48,151,255, 39,130,245, 14,115, 21, 81,145,166, 80,171, 77, 52,232, 53, 42,106, 48,160, 75,176, 45,236, + 44, 68,112,180, 20, 67, 44,226, 67,167, 7,148, 26, 22, 42,141, 1,241, 25, 74, 20, 42, 69,168, 23,214,223, 43,197,241,166,194, +198, 61,120,107, 86,252,157,145, 21,222,103,131, 1, 59,247,159,242, 74, 73,203,236,126,104,251,207,226,140, 2, 45, 30,196, 23, + 33, 35, 79, 13, 16,115, 76,159, 57, 75, 60,123,246,156, 30, 59,255, 56,157,208, 50,196, 47,161,170,215,181, 56, 35,106, 71,189, +166,159,252,210,165, 75, 15,211,136, 91,199,241,244,254,185,239,138,210,171,214,254,202,203,203, 75,255,203, 47,191,216,110,216, +176,193,203,206,206,238,101, 70, 70,198,139,178,234, 40,143, 58,161, 41,103,207, 93,177,110,209,180, 57, 63, 41, 75, 5,107, 83, + 33,220,237,229, 8,191,113, 65,195, 16,114,242,109,122,165,213,128, 3, 93,218, 78,195,225, 27, 47, 58, 70,100, 75, 46,142,248, + 98,104,194,233,203,209,217,171,183,159,254,193,217, 68,119, 95,194,102,174,190, 27,228,233, 48,125,236, 96, 44, 94,181, 3,151, +194,163, 51,138, 25,199,239, 83,213,250, 51,115,251, 79,125,123,212,151, 1,248, 60, 2, 83,169, 0,197,197,121,249,143,207,174, +245,254, 64,207,238,208,211, 7,119, 48, 57,133, 58, 36,102,169, 72, 74, 78, 33, 12, 44,133,133, 76, 8, 61, 75,145,151,147, 69, +118,238,216,142, 59,119,110, 48,224, 49,195, 1,204,173, 36, 18, 2, 30, 67, 96, 34, 17,148, 68,128,164, 37,127,117, 6, 22,181, +107,186, 98,229,252,113,102, 54,118,246,104,223,107,164,241, 17, 54,185,101,253,109,235, 22,226,226,141,251, 97, 23,158,237, 14, +182, 11,168,191,202,165, 78,223,101,140,149,179, 74,173, 53, 32, 63, 47, 23, 34, 77, 34, 26, 57,103,194, 74,102, 64,124,129, 35, + 30,167, 61, 53,169,172, 58, 43,235,209,159,247,109, 3,122,206,218,127,228,252,226, 14,237,194,240, 56,190, 0, 82, 17, 31, 18, + 17, 15, 18, 17, 15, 2, 98,192,207,235,214,235,114,243, 11,187,100, 61, 62,152, 85,141,252,121, 22,192,171, 54,103, 38,246,181, +108,119,172,154,181,109,196,212,165, 29, 58,246,252,140, 60,190,115,225, 91, 0,231,140, 42, 51, 89,106,212, 58,150, 53,238,221, + 70, 8, 97,236, 60,131,118,109,217,186,187,127,157,218,174, 72,207,211, 33, 37, 87,139, 43,247, 98,177,109,227,172,188,220,244, +231,131,160, 45, 42, 98,137, 62,255,212,201, 35, 39,191, 30, 63, 21,254, 1,245,221, 11,146, 10,204, 0,228,191,118, 76, 30,217, + 48,228,139,145,253,237,237,237, 77,255, 19,193,162,240,246,169,131,206,221,122,227,212,161, 3,136,140,120, 8,150,150, 12,231, +195,178, 20,121,185,217,105,122,157,102,235, 59,211,199,227,185,108, 89,191,204,142, 97, 8,180, 58, 22, 26, 61,139,233,211,103, +105,198,207, 94,221,172, 67,211,122, 17, 60,176, 5, 47, 83,243, 44,194,163,211,234, 18,129,169,227,160, 81,211,132, 42,181, 1, +249, 10, 29,206,238, 91,249,238,106,198, 90,245, 67, 61,252,154,125,241,229,204,245, 98, 49,143,209,250,123,187,190,104,217,216, + 63,177,134,147, 77,225,162,149, 59, 27, 93,191, 23,221,185, 87,175, 94,146,254,181,252,136,147,181,196,116,212,152,177,245, 28, +106, 55, 27,146,246,244,234,246,119,190,252,248,226, 60, 87, 23,215, 87, 85,137,118, 1, 61, 30, 2,112,123, 99,179,132,140,199, + 7,235, 1,128,157,189,131,138, 8,196,133, 85, 48, 32, 20, 0,230,173,218,223, 57, 41,179,168, 79,153,185,186,255, 60, 31, 98, + 33, 3,173,206,248,166,113, 6, 66, 39, 76, 27,251,185, 32,167, 88,143,139, 15, 51, 17,113,247, 2,213,107, 11, 62,163,132, 63, +204, 54,160,199, 16, 2,120, 80, 32,142, 33,248, 85,195, 96,107,222,131,131,249, 85,175,233, 41, 73,143, 93,157, 94, 77, 8, 15, +157,121,124, 97, 48,192,250,234,117, 58, 59,134,199,203, 74,123,176,191,210, 30,148,229,207,168, 56, 61, 6, 75, 23,205,198,202, +141, 7,144,146,173,130,185, 33, 17,135, 54, 45,196,228,197,187,160, 84, 27,240,111,192,104,131,101, 95,183,123, 35,128,225, 57, + 88,153,192,171,166, 43, 76,250, 14,147,186, 4,246, 47,230,241, 24,102,235,138,111, 37,217, 74, 62,248, 60, 94,177,209,133,175, +189,111,136,169,169,233,241, 63,255, 56,128, 90, 53,236,132, 59,175,228,196,221,123,161,124, 21,210, 45,200, 76, 16,121,152, 41, +248,189,122,246,148,157, 59,127, 97,194,187, 12, 22,143, 48, 46, 43,127,254,193,206, 84, 42, 0, 33, 64,161, 82,143,241,147,166, +189,247,133,161,160,188,175, 39,205, 1, 41, 53, 87,133,249, 57,248,126,229,214,162, 94,206,231,175,150,153,171,211, 79,164,207, +122,246,108,157, 31, 31, 31,159, 91,105,193, 72, 13, 73,125,134,142, 23, 50, 76, 73,181, 17, 67, 8, 40, 12,233,213, 49, 87, 0, +144,155,251,162, 64,234, 80,175,231,142,229, 99, 55,214,112,118,182, 52,149, 73,136,137, 92, 76,252,124, 60, 37,141, 27,135, 74, +106,120,250,139, 46, 71, 22,225,101,166, 18, 47, 82,242, 33,178,241, 23,244,111,217, 22, 59, 86, 78,235,108,204,249,159,191,241, +184,235,218,101,179,196,105,121, 26, 68,189, 44, 66, 90,174, 10,169,185,106,164,229,168, 96, 34, 21, 32,180,109, 47,241,137, 51, +251,186,182, 12,241, 91, 85,157,235,251, 60,246,197,129,248,228,212,207,234, 53,108,132,157,219,182, 52, 38, 46, 46, 18,154,148, +164, 50,118,255,141, 27, 55,230, 4, 7, 7,219, 46, 89,178,164,216,199,199,167,129,143,143, 79,205,152,152,152,139, 94, 94, 94, +221,214,174, 92,112,105,252,204,101,110, 60,162, 51,111,210,180, 25, 79, 34, 36,184,113,249,148,122,235,198,245, 41,218,188,162, +169, 21, 26, 97,153,249,194,244, 34, 2, 91,103,231, 8, 19,145,161, 29,159,201,139,201, 57, 49,118, 59,128, 63, 61, 59,141, 59, +123,225,110,116, 76, 80,120,188,221,249,240,103, 25, 57, 10,173,119,236,137, 73, 21, 22,184, 60, 66, 32,224, 49, 48,149,242, 95, + 69, 44,237,235,247,125, 70, 9,177, 45,139,148, 18,148, 68,180, 72,201,103, 75, 74, 82,248, 94, 35, 26, 70, 19,202, 82, 32, 58, +169, 24, 69,170,146, 16,188,139,141, 12,153,233, 73, 88,187,106, 43,238,221,189,131,246,157,186, 97,205,111, 59, 49, 98, 72,223, + 74,175, 43,195,160, 36,130, 85, 46,122,101, 34,229, 3, 32,200, 43,214,225,143,171,137,240,172,201,128, 84,161,182,208,212, 68, +138,252, 66, 37, 24,129, 9,162,174,108,151,157,184,112,123,198,220, 31, 55,125, 83, 80,148,246, 50, 54,242, 6,124, 44,179, 81, +211, 89,139,136, 52, 51,220,205,246,128,143, 87, 45, 48,194, 59, 70,105,103, 69,212, 93,122,136,249,163, 75, 80,131, 58,161,110, +118, 22, 80,106, 12,165, 81, 44, 30,182,108,222,142,248,184,164, 47,178, 34, 14,222,251, 16,133,100, 81,250,243, 76,137,125,237, +175, 30,221, 58,247,162,231,167, 95,193,209,185, 70,253,170, 52, 79, 48,102,157,193, 8,131, 69, 8, 97,172,220, 27,108,219,182, + 99, 95,255,154, 53, 28,112,230, 86, 28,110,199,100,195,198,198, 26, 60,153, 3,106,183, 28,102,241,232,228,202,222,202,172,162, +109, 2,161,108,120, 72,227,166,160,148, 34,250, 73, 68, 78,126,190,249, 95,202,102, 69, 74,212,125, 0,102,229,215,201,108,253, +234,155,152, 91,221, 87,107, 13, 72, 78, 78,194,181,235, 23, 27,150,110,103, 52, 98, 33, 15,167,239,101, 64,171, 99,161,213,179, + 8, 9,244,215, 8, 68,210,230, 63,108, 60,214, 56, 61, 61,147,145,154,152,177,230,118,181,132, 86,186, 52,245,131,231,249, 66, +173,142, 69, 45,167,138,191,203,101, 86,181, 22, 77,154, 60,222,143, 39,148,162,176, 88,173, 73, 77, 73,118,248,117,247,133,162, + 39,209,145,206, 30,238, 53,204, 22, 46,152, 43,204, 87, 2, 25,249,106,228, 20,106, 73,191, 79,191,112,218,190,105,205, 32, 0, +219,171,144,244,186,123,183,175,215, 89,154, 8, 73,161, 82, 71, 51,243,213,134, 49, 95,141,175,251, 62,121,167,204, 92,253,248, +253, 76,225,189, 23, 69,120,240, 60, 31, 18, 33, 15, 34, 33, 3,141,145, 6,203,182, 78, 95,185,173,173,197,160,144,250,181,113, +234, 94, 38,120, 60, 6,138,226,124,141, 68,108,242,216,215,183, 54,211,160,126, 0,194,154, 53, 65,236,139,120,159, 83,103,206, + 47,191,125,231,222,247,182, 1, 61,167,102, 62, 62,176,166, 42,105, 77, 76,205,150,165,235, 93,199,219, 57,216, 4,116,235,222, + 85, 92,195,217,158,216, 90, 89,192, 64,132, 24, 53,250,107, 59,163,243, 60, 45,137, 94, 46, 89, 48, 3,106,181, 6,182, 22, 34, + 80, 10,108, 94, 53, 23, 26,141, 6, 78,214, 98,228, 23,235, 56,131,245,234, 6,215,235,217, 84, 42,150,159, 94,179,120, 2,147, + 87,172,131, 68,200, 67,173, 90, 53, 49,118,252, 4, 89,155,250,182, 80, 18, 51,252,177,123,107,129,222,160, 59,106,140,158,204, +161,118,144,169,220,236,212,182, 29,123, 89, 27,107,107,102,237,233,204,231,217,133,250, 87, 67, 28,196,220, 58,204,222, 61,245, +171, 35, 5, 57, 41,145, 72,188, 52, 26,141,101,101, 55,116,243,233,132,210,198,185,228,131, 92, 24,134, 97, 12,191,174, 90, 0, + 27, 51, 17,212, 58, 22,243,151,111, 47,236, 98,123,242,124,121,115, 21, 24, 24,152, 95,191,126,253, 60,134,169,124, 56,177,151, +183,119, 54,121, 75,129, 89, 45,115, 85,134, 50,237,225, 29, 0, 1,175,107, 6, 10,108, 60,246, 77, 30, 48,104,200, 12, 7,255, + 79, 76,227, 82,243, 33, 36, 90, 4,251, 57,226,226,169, 63,217,196, 23, 79, 70, 25,163,157,145,157,239,106, 99, 99,141,123,207, + 11,145,156,173, 68, 90,169,185, 74,205, 85,163, 80, 89,136,250,238,182,200,203, 47,114,173,182,129, 37,244,224,169, 83,167, 62, +235,220,189, 63,198,126, 51,175,211,198,181,203, 30, 74,237,253,134, 40,211,159,220, 54,102,255,125,251,246, 25,220,221,221,159, +103,102,102, 54,154, 50,101, 74, 65,173, 90,181, 28, 22, 44, 88,240,101,173, 90,181,156, 90,183,106,149,127,251, 66,227,109,227, +191,153,219,106,250,184,141, 53, 25,134, 73,167, 44, 61,156, 82,172,155, 67, 51, 35,149, 21,222,167, 67, 51,162, 72,157,121,159, +181,107,110,123,216, 74,198,248,139,169,102, 0,169, 51,111, 47,141,156,163,141, 61,177,170,176,110,191,159,199,166,228,177, 51, + 85,140,221,247,149,153,171,146, 8, 22,129, 70,111,128,169, 84,240,159,188, 73,225,184,118,245,207, 50, 91,115, 17, 4, 60, 6, +124, 30, 65,129, 66,135,172, 2, 45,190,153,250,141,177, 87,144,213, 27, 40,148, 26, 61, 20,165, 95,131,133, 5, 89,152,241,205, + 36,116,234,218, 19,195, 71, 77, 66,174, 18,184,251,162, 16, 90,157,174,210,135,130, 71, 8, 20,106, 61, 62,111,239,134,156, 34, + 45,138,149,122,104,244, 44,100, 34, 62,248,124, 6,114, 9, 31,102, 50, 1, 8,161, 66, 71, 71,199, 47, 1, 64, 32, 16,168, 94, +190,124,185,163,130, 47,120,120,184,218, 67,169, 99,208,168,255, 50,180, 13,245,198,131,179,155,248,151,110, 62,170,249,205,220, +229, 24, 51, 48, 20,251,163, 60, 97,101,231, 6, 19,185, 20, 58,202, 0, 48,110, 8, 16, 74,231,176,142,190,189, 6,174,255,109, +115,244,252,217,211, 37,121,197, 4, 98, 33, 15,231,207,157,197,141, 91,119, 87,102, 70, 28,220,241, 33, 11, 74, 1,101,236,205, +204,204, 32, 17,241,160,209,170, 53, 70, 71, 30, 88, 10, 80,248,217,213,237,241,103,233,189,247, 51,176,120,203, 58, 90,153,185, + 34,230, 78, 1, 91,214,111,220, 57,200,201,193, 14, 7,206, 61,196,150,223, 86,163,102,131, 46,184,122,108, 11,204, 61, 26, 67, + 94,163, 25, 68,166,251,190,100,120,252,186, 95, 79,248,182, 87, 96,112, 40,174, 93, 57,143,140,180,212,245,148, 70, 25,213, 6, +141, 39, 32,227, 90,183,235, 10,149,198,128,230,109,186,224,228,145, 3, 99, 81,218,121,194, 88,222, 52,225, 44, 11,253,215,195, + 7, 8, 50,242, 52,130,204, 2, 13,146, 50, 21,136, 75, 87,224,208,158, 77,212,216,183, 54,195,231, 5,183,168,231, 34,248,114, +233,249, 68, 87, 23, 71,181, 64,173,148,198,196, 62,247, 29,254,217, 32, 65, 77, 47, 95, 38, 35, 95,141,204,124, 53,178,242,213, + 40, 82,233,225,229, 88,131, 81,235,249,161, 85,189,207,182, 22, 18,193,154, 35, 47, 96, 38, 23,160,137,175,117,181, 27, 97,179, + 44,251,154,185,186,255,162, 24, 15, 95,228, 67, 44,228, 65, 44,100, 32, 22,242,160, 55, 80, 35,223, 69,250, 1, 35,135,245,151, +106,116, 20,217,249, 26,240,121, 4, 14, 54,214, 98, 87, 71,111,108, 94,246, 53, 0, 96,196,180,181, 24,254,249, 96,248,120,123, + 33, 63,191, 80, 58,124,244,248,159,241,150,118,119,239, 74,235,206, 67,151,235,220,125,156, 48,249,179, 97, 67, 5,253,186, 54, +103,238, 63, 47, 64,106,142, 26,207, 99, 21,208,234,170, 54, 26,141,222,192,130,130, 98,235,222,163,144,138,248,200,204,215,130, + 82,138,133,171,127,135,169, 84,128,212,220,146,106,125,206, 96,149,153, 43,145,228,244,246,213,223, 74,207,199, 0, 43,207,220, +197, 39, 33,142, 16,242, 25,136, 77, 28,240,224, 69, 46,206,158, 59, 84,120,245,198, 45, 21, 24, 93,165,221,162,100,142, 62, 13, +229, 82,179,179,107,126,221,166,183,177,179,195,142, 43, 57, 73,185,197,122,221,127,170,167,116,228,238,169, 95,107,234, 89, 93, + 71,101,218,211, 74, 63,103, 89, 74,133,139,215, 29, 2, 64,193,178, 44, 40,203,130, 39, 20,203,221, 26, 15, 78, 47,209, 99, 37, +124, 30,163, 42,255,228, 83,214,144,148,112,107, 87,133, 85,135, 4,128,185, 76,128,189,151,146,145,159,147,146,213,197,246,228, +171,106,193,147, 17,226,103,129,129, 13,242,131,131,131,243,164, 82, 41,120, 60, 94,149, 47,252,251,154,171,119,191,120,194,117, + 0,150, 56,249,182,236,214, 73,230, 31, 34, 98,248, 8,244,113,196,197,211, 7,216, 27, 39, 54,245, 84,164,199, 28, 51, 50,188, +141, 34,165, 14, 41,217, 42, 36,103,171,144,150,171, 66, 90,142, 26,105,185, 42, 16, 66,160,210,188,223,240, 53,138,244,152, 35, + 38,206,254,235,213, 90,140,106,209,190, 39, 38,207, 93,227,181, 99,253, 15, 87,228,118,181,131,139, 51,158, 62, 50, 70, 35, 62, + 62, 94,109,111,111, 31,158,151,151,215,126,249,242,229, 69,126,126,126, 34, 19, 19,147,108, 0,210,103, 49, 49,194,243,199,247, +197,101,166,164,140,212,106,181,119,140, 77,151,123,216, 48,177,239,255,177,119,214,225, 81, 92,251, 27,127,103, 93,226,196, 29, +136,144, 64,130, 4,151,160,193,221, 10, 20, 41,165, 69, 90, 42, 72, 91, 40, 45, 82, 10,133,150, 34, 53,104,161,197, 29,138, 21, +119, 11, 30,136, 64, 8, 16,119,221,205,102,125,103,230,252,254,128,228,166,220,200,134,210,223,189,151,158,207,243,204,147, 77, + 50,243,206, 57,179,103,230,188,243, 61,102, 95, 60,217,207,166, 67,239, 0, 15, 37,252,108, 52,189, 67,109,239,126,227,214,227, +195,165,249,103, 86,231,231, 24,217, 83, 5,122, 97,139,172, 50,177, 85,125, 1, 89,179, 41,237,245, 41,115, 33,100, 24,152,141, +166,180,242,194,229,230, 32,197,194,109, 15, 96, 43, 23,195, 78, 33,130,173, 66,140, 78, 77,234,161, 14,175, 7,196,194,241,208, + 25, 57,232,141, 44, 12, 38, 22, 46,190, 78, 88,191,117, 15,210,243,245, 56,120,179, 16,137,105, 26, 4,251,216,128,144,218,227, + 78, 60, 97,181,175, 77,158,103, 39, 20, 8, 32,100, 32, 8, 13,170,143,226, 50, 19, 36, 34, 1,164, 82, 41,108,100, 34,216, 43, +196, 16,139,196,184,113,239, 30,140, 70, 35,218,182,109, 43,175,217, 2, 62,141, 98, 5, 55,244,130,217,194,226,232,197, 4, 44, +153, 49, 12, 61, 59,183,194, 71, 66, 41, 30, 24, 35, 96, 87,207, 14,188, 64, 0, 51,203,195,100,230, 0, 8,170,141,182,249,249, +249,117,183,177,177,177,209,233,116,154,180,180,180,243, 57, 15,246,167,187,133, 13,153,124,252,228,217,173, 3,250,246,196,157, +123,241,216,251,251,161, 75,133,206,234,217,229,199,132,135,135,183,115,113,113,177, 45, 42, 42, 42,141,141,141,189,241, 34,101, +149, 97, 24,198,198, 61,244,195,246,157,186,162, 76,149,143,188,140,148, 35,214, 30,219,216,223, 14, 51,103,188, 23, 28,210, 40, + 36,152,123, 54,146,170,137,159, 29,166, 78,123, 39, 56, 48,184, 81,112,249, 64,143,198,126, 53,207,119,105,227, 30,242,206,146, +149,107,199,251,249,250,226,216,149, 7,248,106,222,212, 59, 54, 74,187, 6, 62,238, 78,142,146,176, 86,136,137,185, 10, 55, 72, + 97,239, 30,236, 51,122,208, 20,159,222,125, 7, 33,246,238, 45,172,254,122,113,180, 86,168, 88,106, 77, 90,109,221, 3, 92, 91, +180,238,252,186, 93, 61,119,168,212, 26,216, 57,185,161,113,179,214,175,219,186, 7,124,242,108,177,250, 23, 51, 27,132,192,104, + 38, 40, 41, 51, 35,163, 64,143,212,220,167, 6,139,231,235,208,231,135,128,177,149,139, 68,245, 44,143,252, 98, 79,159, 37,254, +190,238,204,215,139, 63, 18,154,241,180,179,120,129,218,136,130, 82, 19, 10,212, 38,148, 25, 44,168,103, 35, 2, 79,248, 58,191, +109,151,148,153, 97,247,172,159, 44,199,191,184, 9, 88,184,106, 71,135,204, 2, 93,143,111,190,156, 39,185,155, 82,201, 92,137, +159, 70,175,100, 18, 33, 56,222,186, 8,150, 80, 36,120,175,127,143, 54,200, 40,212, 63, 29,133, 44, 96, 16, 20, 22, 1, 23, 5, +143, 30,163,230, 0, 0, 6,246,123, 58, 13, 73,114,142, 22,135,175,229, 0,128,196,218,180, 22, 21,105,100,191,159,186,243,193, +142,245,223, 72,141,188, 24, 63, 31, 75,131,206,200, 66, 46, 17, 66, 38, 17, 66, 33,169, 91,253,198,114, 79, 7, 75,164, 23, 90, +160, 51, 24, 80,170,183,128, 0,184,241,168, 12,122, 19, 11,181,214,130,118,161, 78,212, 96,149,155,171,205,223,125,170, 56,243, +144,224,220,221, 34,140,136,244, 65, 81,126, 38,214,255,180,134, 39, 4,144,201,165,185, 28,203, 31,211,243,236,199,170,187,135, +213, 53, 62, 36, 92,155, 52, 83, 40,149,103,151,175,254,217,236,230,238,205,239,191,166,202, 87,235,184, 63,197, 10, 57,163, 81, + 64,120, 34,177,198, 92, 61,139, 52,153, 23,188, 55, 20, 60, 33, 88,184,122, 15,150,206, 30, 5, 91,133, 72,201, 48,140, 82,107, + 96, 49, 99,209, 6,124,251,249, 36, 59,165, 76, 4,134, 1, 12, 38, 14, 83,223,179, 46, 74,160, 51,114,208,170,114,139,154,150, +173,124,206, 92,181, 84,183,109,219, 86,229,228,228,132, 23, 49, 88, 85,153, 43, 15, 15, 15, 47,165, 82, 89, 47, 56,248,105, 95, + 87,161, 80, 8,142,227,180, 73, 73, 73, 47, 52,233, 91,169,170,224, 64, 78, 74,108,219, 14, 93,251,227,194,201, 3,124,244,209, + 13, 67,235, 50,196,220,209,193, 62,227, 78, 66, 90, 99, 6,182, 79, 35, 88,207,204,149,201,194,195,223, 93,137,204,140,116, 56, + 58,216,102, 88,171,167,244, 8,238, 35, 32,194, 41, 60,131,245,186,220, 7, 71, 1,160, 44, 43,126,154,210,173, 81,108,124,252, +221,213, 3,198,188, 39,237, 53, 98,154,100,221, 87,239,206, 1, 48,218, 90,221,188,188, 60,157,171,171,107,180,167,167,231,128, + 69,139, 22, 25, 1,200,140, 70,163, 96,226,196,137,202,180,180,180, 25,132, 16,171,210, 24,249,230, 94, 23, 70,166,233, 27, 24, +220,122,140,191,157,166,103,183,200,246,104, 31,230,139,140,200,246, 0,240,126, 90,153,109, 72,167,105,191,238,106,232,234,115, +116,221,198,195, 75,223, 30, 21, 53,195,107,224,162,149,217,135, 23,212, 24, 17, 75,188,248,107,239,170,236,187, 72, 40,128,157, + 66, 12, 91,133, 8,118, 10, 49,236,228, 98, 88, 88, 82,151, 38, 56, 98, 97,249,167, 17, 44, 19,139, 50, 61,139,179, 49,121,200, + 85,155,160,210,152,161, 55,115, 32, 32, 48, 91,248,242, 89, 69,106, 54,171, 87, 55, 57,150,127,246,105, 57, 90,189,230,139,247, +236,247, 93,206,172, 24,161,231,160,148,194, 78, 41, 6, 64,112,241,226, 69, 56, 59,215, 62, 45, 22,207,243,216,123,252, 6, 86, +110, 58,139,227,191,125, 12,185, 68,136,102,131, 23,225,141, 33,109,193,243, 4,143, 19,227,243,130,155, 52,119, 23, 8, 20, 16, + 48, 12,140, 22, 30, 0,169,246,122,154, 76, 38,231,244,244,244,210,160,160, 32, 15,111,111,239, 17, 66,161,144,200, 0,227,129, +157,197,186, 51, 71,182, 43,181,122, 35,167,100,213,191, 5,229,232,251, 7, 7, 7,131, 97, 24,226,226,226, 34, 57,123,246,108, + 89,211,166, 77, 93, 95,228, 62, 98, 24, 70,160,112,107,180,230,173,105, 31,142, 8, 12, 8,192,158,237,191,129, 16,102,159,181, +199,111, 59, 28,141,149,171,254, 60, 98,112,234,180,119,130,215,173,253,233, 79,127, 27, 63,105,114,112, 77, 6,207, 39,188,251, +199,161,161, 77, 16, 29,159,137,175, 63,155,118,199,144,159, 60,198,100,235, 60,197, 92,150, 51,179, 69, 68, 43,120, 56,219, 35, +187,216,136, 65, 99,135,160, 99,167, 72,196,222,189,133,197,159,127, 20, 13,157,169, 87,109, 81,219,127, 25, 33,241,212,110,189, +135,136,245, 70, 51,190,251,122, 62,166,204, 94,130,118,221, 7,138,227, 98,174, 77, 5,240,133,181,121, 54,154, 57,116,107,234, +242,212, 52, 91,120, 28, 74, 22,138,170, 42,129, 34, 33, 35,104, 17,224, 8,189,137, 69,169,206, 82, 75, 4,139,201, 85,105,180, +245,127, 88,250,161, 80,107, 96, 81,160, 54, 33, 95,109, 68,161,234, 95,198,170, 80,109, 68,129,218, 4,177,136,193,195,148,108, + 8,133, 76,157,251,223,149,148, 89,208,166,145,211,211,123,244, 5, 91, 67, 10, 89,215,190,119, 31,102,247,248,122,241, 92,201, +221, 84, 45,238, 37,151, 62,139, 92, 9, 33, 19, 11, 32,125,246,153,179,194, 95,185, 53, 25,212, 97,252,232,193, 97,246, 54,114, +100, 63,212, 64, 36,124, 58,213,139,131,155, 47, 28,100, 6, 76,159, 54, 25, 46,206,142, 72, 47, 52, 98,205,239, 15,113, 47,225, + 17,120,125,221,178,253,195,246,227, 67, 39,140, 27, 37, 19, 74,100,216,114, 36, 5, 50,137, 16, 34, 98, 66,252,181,139,198,188, +204, 20,179,166, 84,101, 35, 18,137,173, 18,101, 0, 82, 30,153, 91,186,112, 14,118,110,250, 9, 39,110,231, 87,116,159,191,188, +239, 91,124, 56,247, 75, 20,150,154, 0, 48,175,124, 24, 75, 84,147,185,146, 75,165, 39, 55,173,153,171, 56,243, 16, 56,127,239, +169,185,210,151, 21, 98,203,175, 63,151, 17,240, 81,121,113, 7,173,126, 35,180,113,107, 20, 46,179,177,185,240,217,151,107,140, +238,222,245,217,163, 49,165, 69, 26, 3,247,111, 97, 16,137,210,134,179,113,112, 53, 56,250, 71,172, 20,235, 77,243, 11, 10, 18, +180,181, 69,154,120, 66,112,228,122, 46, 8,121,250, 74,180,251, 98, 22,132,130,167,205,133, 28,255,180,249,228, 84, 76, 62, 68, + 2,198,234, 33,231, 12, 3,236, 62, 25, 83, 24, 94,133,185,106,221,186,181,202,222,222, 30,142,142,142,176,181,181,173,235, 3, +187,202,200,149, 82,169,172,119,226,196, 9,185,189,189, 61,132, 66, 33,140, 70, 35,122,246,236,249, 66, 95,170,141,123,200,232, +118, 61,134,125,213,177, 91,127,156, 59,177,159,143, 62,186,113,152, 46,191, 14,243,247, 0,232,219,185,217,225,229,223,126,223, +240,163, 57,159,201,236,228, 34,220, 47, 51, 65,192, 48,240,119, 87,194,217, 86,136,232,179, 71, 12, 35,122, 54, 61,108,173,158, +159, 79,253, 45, 43,190, 91,231,188,114,217,162, 94, 78, 78, 13,221, 75, 74,146, 75, 1, 64,151,255,112,157,173, 71, 72,162,143, +223,201, 11,205,187, 12,133,187,119, 80,191,186,230,183,160,160, 32, 47, 44, 44,236,126,147, 38, 77, 90,141, 24, 49,130,124,245, +213, 87, 78,153,153,153,123,172, 53, 87, 0,208,163,103,216, 12, 91, 41,215,174,158, 82, 16, 22,224,161, 68,251,176,167,173,159, +163,250,119,130,175,159, 31,158,228,234, 90, 20,235,120,113,153, 73, 24,240,227,207,247,110, 54,112, 17,190,205,234, 77, 9, 0, + 14,214,185,210,198,191, 58,190,151, 71,175,236, 20, 98,240, 79,203, 71,157, 12,150,209,204, 65,111,228,160, 55,177,208,154, 56, +232, 76, 28,120,242,244,158, 96, 24, 6,102,150, 47, 63,101,157, 18,104, 95,207, 5, 1, 13,158,142,122,181, 83, 60,157,178,225, +105, 19, 33,224,236,236, 12, 55,183,218, 27,119, 8, 33, 48,153,159,222,226, 38, 11, 95,209, 68,106, 50,179, 32,132,224,225,195, +196,143, 83,147,147, 7, 7, 5, 7,117,110,210,172,121, 61,165, 76, 0, 0,213,154, 1,157, 78,199,217,217,217,185,213,171, 87, + 79,144,149,149, 85,209,239, 49,168, 69, 55,246,247,253,251, 48,108,216,208,178,251, 55,238, 86,140,168,210,235,245, 76,199,142, + 29,237,125,125,125, 5, 70,163,177,180,206, 81, 43,215, 70, 67,124, 67, 59, 44, 25, 63,113, 74,163,110, 81,125,112,238,204, 73, + 28,220,191, 99,179, 54, 63,241,164,181, 58, 33, 33,161,255, 54,138, 48, 48,184,209,191,141, 34,172,223, 48,184, 90,131,229,224, +208,204,190, 89,235,174,190,169,133,102, 28, 59,118, 20, 90,117,238,231, 38, 83,153, 14, 98,178,225,200,142, 31, 39,189,245,225, + 34,251,174, 93, 34,225,100,175,132, 72, 36,196,237,155,209, 88,246,197,167,209,208,153,122,213,246,252,172,200,111,147, 38,146, + 32,191,250, 31,248, 5,134,227,246,181, 75,120,252, 48, 46,254,238,205,232,176,160,166,237,224,234,229,255, 1,211,164,201, 50, +146,144, 80,235, 74, 21,132,227, 50, 39, 76,158,249,236,251,127,250,183,246, 45, 26, 74,153,231,111, 0, 0, 22,214,204,109, 89, +183, 44,191,242, 40,194,234,116, 13, 26,213,222,139,215,238,205, 30,216, 43, 82, 80, 88,106,122, 26,177, 82,155,158,109, 70, 20, +150,127, 46, 53, 34,216,203, 22,143,227,238,243, 22,173,122, 95,221,238, 76,146, 55,237,157,247, 20, 79,211,206,131,240,164, 70, +195, 95,109, 90, 57,201,235,235,190,152,195,220, 75,213,226, 94, 74,233,211, 38, 65,177,240,169,177, 18, 11, 42,204,150, 85,173, +100, 2,193,215,227, 71,246, 70, 97,169, 25, 60, 15,136,132,130,103,155, 4,233, 26, 6, 25, 26, 29, 10, 75, 10,144,156,154, 6, + 85,238, 99, 8, 4, 2,184,120, 53,130, 46,221,186,180,106, 56,219, 70, 22, 14,129, 35,251, 71, 10,127,143,206,133, 82, 38, 66, +105, 81, 6,174,156,216,165,231, 89,110,157,201, 98,218,233, 70,164,113, 9,177,123,204, 86, 62, 58, 10, 74,181, 70,119,153, 88, +136, 61,155,126,192,200, 55,166,149, 71, 32, 1, 0, 31,207, 91, 12, 8, 24,148,168,180, 0,152, 23,142,138,254,207, 27, 44,177, + 64,120,106,227,234, 79,229, 9, 5,114,220, 72,204,193,136, 72, 31,232, 52,133,248,249,135, 53,101, 6,139,177,111, 65,236,193, +186,133,219, 5,130,222,163,222,156, 29, 31,208,168,137,241, 92, 92, 89,138, 74,107,169,182, 31, 67,251, 17,159,197,223,250,227, +251,126,106,203,147,119,108,189,194, 56,158,101,191,214,229, 39, 46,170,250, 45,153, 72, 23,173,217, 83,209, 60,248,201,178, 45, + 79, 63,115, 28, 56,194,131,240,192,244,207,215,130,229, 57,240, 28, 7,158, 35, 96, 44,156,178,214,112,185, 92,114, 50,188,108, +165, 67, 85,230,202,209,209, 17,206,206,206,112,118,118, 70,185, 33,250,171,205,130,193,193,193,176,181,181,197,165, 75,151,160, + 80, 40, 96, 99,243, 98, 19,228,219,186,135,190,214,182,251,208,109,221, 6,190, 41, 56,253,251,207,220,245,243, 71, 70,232,243, + 31, 88,109, 2, 56,142, 99, 44, 22, 11,122,119,109,153, 22,147,152,126,252,139, 69, 11,251,180,238, 62, 92,214, 33,196, 13,122, + 19,139,172,204, 76, 68,159, 61,104, 8,242,115, 62,209,165,109,227, 52,139,197, 2,142,227,106,173,192, 13, 70, 83,145, 80,172, +112, 30, 53,250,117,217,205, 27, 55,182,217,184,135,236, 16, 8,249,187,132, 19, 54, 3,200,107,205,154, 53,134,217,194, 67,167, +211, 20,191, 72,190, 19, 18, 18,110,172, 90,181,170,145, 88, 44,246,221,189,123,119, 97, 73, 73, 73,157,150, 11, 58,121, 49,113, +181,136, 41, 73,146,242,230, 49,254,118,154,158,233,157,218, 99,244,128, 78,216,249,199,101,156,191, 20,141,180, 50,219,152, 50, + 86,116, 32, 35, 45,219, 24, 86,175,116,223,160,246,245,133,123, 54,149,236,115,235, 54,247, 53, 66,100, 39, 11,206, 47,208, 90, + 95,121, 3, 26,189, 5,246,202,167,243, 53,149, 71,178,132, 12, 99,181, 19, 98,128,228, 75,209,183,195, 91, 5, 55,193,157,100, + 53,242, 85, 70,232,141, 44,120,158,128, 7,129,179,157, 20,114,137, 0,233,169,201,224,137, 57,165,110,245, 12, 10,250, 14,159, + 34,122,122, 30, 94, 36, 22,139, 64,158,213,139, 10,185,180,204,205,205,205,170, 8,150,153,101, 49,172, 79, 91,180,107,221, 12, +131,167,172, 0, 0,156,217, 60, 7, 78,182, 98,236,221,187, 23,233,151, 87,109, 13,232, 48,237,100, 92,108,252,240,248, 59, 87, + 95,239,219, 82,209,194, 67,148, 93,109,211, 70, 89, 89,217, 62,134, 97,164, 18,137,164, 79,231,206,157,235,237,219,183, 79,229, +226,226,194, 75, 37,146,130, 65, 3, 7,240, 98,137,164,162,236, 92,185,114, 69, 60,101,202, 20,187,146,146,146,244,188,188,188, +104, 66,136,165,230, 23,192,208, 40, 8,176, 3, 12, 35,183, 85, 40,211,218, 71,141,246,106,221,174,173,195,144, 97, 35, 33,147, +202,112,234,228,113,124,183,106,217,238,178,156,251,111,214,229, 82,190,140, 81,132,106,181,131, 54, 41,225,110, 73, 74,190,201, + 73,236, 24, 12,177,204,110, 10,227,224,181, 70, 40,179, 93,224,218,124,136,253,222, 67, 71, 17, 27, 23,135,122, 10, 11,158, 60, + 78,210,197,197,220,249, 73,199,136, 23,145,130, 4,157,213, 17,230, 34,110,120,251,113,125,156,140,102, 14, 23,207,254, 97,224, + 89,190, 79,244,133,163,143,125, 26,181,150,135,183,238,225, 84,120,112,195, 48, 0, 59,107,211, 73,185,190,245,223,186, 94, 4, +180,125, 45,251,232,201, 11,182,158,254, 65, 66, 6, 66, 24,244, 58, 20,164,197,178, 6,117,174, 46, 47,246,128,151, 53,233, 75, + 99,179, 62,255,252,171,181,239,180,106, 30,102, 67,136,228, 79, 17,171,114, 99, 85, 88,106,130,139,157, 20, 70,109, 9, 30,223, +187,100, 40, 16,231,125, 90,243,179,206,162, 44, 42, 42,150,150,255,174, 40,115,172,175,118, 80,203, 42, 76,160, 16,112, 80, 59, + 26,255,213,148, 86, 44,229, 56,139,210,154,219,211,193, 86,142,216,148,156,138, 14,237, 50,241,211,190, 87, 82,177,176,162, 31, +150,149,247,121, 75,145,212, 22, 89, 69, 6, 48, 32,224, 57, 22,172,197, 4, 77,105, 41,178,178,115,145,151,155, 7,141, 70, 5, +165,173, 19,194, 91,180,129,157,173, 13, 30,220, 62, 15,128,177,234,229,215,192, 75,130, 91,183,106, 37,142, 79, 43,131,217,194, + 67, 12, 51, 46, 31,219,105,176, 88, 76, 3,243, 98, 15,156,173,235,115,152,229,201,233,184,196,180, 48, 31, 87, 79, 38,230,177, + 26, 91,215,127, 15,211,179, 72,166,197,194, 33, 46, 93,139,156, 98, 29, 50, 51,210, 8,120,238, 52, 94,113,170, 53, 88, 44,203, +202,253,252, 27, 96,244,148,177,248,233,167,181,120,248, 36, 29,191,252,248,204, 92,221,251,253,138,149,134, 34,170,124,174, 12, +109,238,131,175,223,252, 41, 37,243,208,157, 98,129,222, 84,243,250, 83,114, 87,127, 68,190,249,237, 9,189,166, 88,202, 25,117, +162,195, 91,223,220, 81,149,230, 83,223,198,152,150,204, 26, 5, 91,133, 8, 12,195,160,188, 89,240,199,197,147,161,148, 9,193, + 48, 12,244, 70, 22, 99,103,172,196,214,149, 51, 65, 0,188,245,206, 44, 93,117,233,172,100,132,152,137,125, 26, 14,250,242,215, +132,131,151, 83,157,159,244,239,223, 69,221,178,101, 75,149, 66,161,128, 66,161,128,189,189, 61,156,156,156,224,232,232, 88,107, +222,159,253,238, 94, 91,159, 43,129, 64, 0, 27, 27, 27,216,218,218,194,198,198,230,223,140,219,243,154,255,102,174, 60, 26,141, +108,211,109,232,142,238,131, 38, 9, 78,255,254, 11,127,235,252,225,145,250,252,196, 3,214,126, 71,207,154,117,238, 14, 27, 54, +172,233,148, 41, 83, 36,159,190, 51,236,196,137,243,183, 31,238, 63,181,111, 96,177, 74,227, 75, 8,129,163,131,109,198,136,158, + 77, 15, 71,182, 14, 73, 59,115,230, 12,191, 99,199, 14, 35,195, 48,177,181,165,179,176, 48,127,227,153,211,103,151, 71,118,233, +138,245,155,118,244,143, 79,184,223,255,241,227, 36,248,250, 7,160, 65,195, 96,232, 24, 39,156,189,112, 9,154,226,220,141,214, +164,179, 50, 77,155, 54,245,110,222,188,185,143, 74,165, 50,204,159, 63, 63,132, 16,114, 32, 60, 60,188, 85,203,150, 45,115,239, +220,185,147, 89,221,176,255,202,154, 87,215, 14, 41, 0,176,185,126,215,137,187,179,204,170, 15, 0, 44,243,243,247,195,249, 75, +209,136,190,124,125,109,161,210,111,209,155, 99, 39, 78,174, 63, 72,248,214,160,246,245,133,110, 78, 74,108,255,229, 91,225,161, +232,212,149,169, 69,220, 6, 0,139,173,249,142, 42, 30,214, 26, 51, 58, 54,174, 7, 11, 71,192,147,167,166,203, 78, 46,174,178, +137,176, 42, 77,145, 73,246,230,212, 41, 83, 30,135, 55,107,241,225,216,137, 83, 37, 45, 2,124,113,227,145, 10, 96, 24,212,243, +176, 65, 78, 78, 14, 46,238,253,133, 45,201,122,176, 86, 40,228,191,168,203,245,204,188,189, 51,168,252,179,167,167,231,228,152, +184, 56,156, 63,127, 30,229,198,202,213,213,181, 74,131,245,188,102, 73,137,230,202,226, 21,235, 59,190, 61,110, 48, 6,116, 13, +195,133,155,143, 97,122, 54,223, 82,249,144,240,228,232,117,210, 15, 70, 5,152,222, 25,214,168, 84,111,145,166,126,158,162,190, + 88,121, 18,217,231, 53, 9, 33, 38,134, 97, 14, 37, 38, 38,118,106,222,188,121,253,163, 71,143, 22,199, 95, 63,241,167,137,238, +102,205,154,101,251,211, 79, 63, 41, 9, 33, 87,140, 70,227, 19,171,242, 46,192,246,219,183,110, 57,155, 45, 60, 46, 93,191,219, +184, 71,199, 22,224, 9,112,243,230, 77,108,248,117,131, 33,246, 94,204, 10,109,158,199, 23,213, 77,110, 91,221,245,228,254,194, + 40,194,114, 77, 66,206,179,182,238,161,107,175, 92,186, 48, 79,230,213, 10,161,253, 62, 29,148,117,247,208, 32,143, 38,189,225, + 18,208, 1,217,247, 14,225,202,137,109, 71,121,150,157, 35,231, 5,105,218,130, 7, 90,107,239,247,114,100, 10,229,123, 77, 90, +118, 65,122, 90, 42, 82,146,226, 54,235,139,146,178,109, 61, 66, 55,103,103,166, 77,109, 24,214, 17,151, 79,236,124,191, 58,131, + 85, 91,153,119,147,107,214,158,187,124,117,116,214,158, 67,238,154, 50,189, 66, 36, 18,232,100, 34, 38, 79,162,123,188,203,218, +116,146,132, 4,179, 91, 96,135, 97, 99,166,124,246,199,202,175,230,137,221, 29,101,200, 45, 49,160, 84,111,134, 70,103,134,128, + 97, 16,228,101, 3,189,182, 20,209, 71,183, 88, 56, 67,209, 40,242,232,207, 17,183,202,154,174, 97,131,191,100, 24, 76,255,236, +179,185, 16, 74,237,189, 26,246,248,212, 44,104,232, 1, 39, 60, 55,153,121, 61,160, 97,143, 79, 97,212,228, 13,252,236,179,185, + 33,132,144, 30,174, 97,131, 53,229,107, 17, 86,151,247, 34,141, 25,175,119,243,133,153,125, 58,127, 24,203, 3, 28,255,244,133, +159, 16,128,212,208,110, 95, 89,147, 0,146, 93,127, 92, 65,118,158, 10,122,147, 5, 70, 19, 11,179,133,131, 64, 40,132,163,147, + 35,130, 27, 68,192,209,209, 1,249,133,133,184, 25,125, 25,215, 18, 99,146, 9,240,101, 97, 61,245, 54,107,190, 35, 70,100, 19, +228,238,230,194,228,149,154,160,144, 10,113,237,246,121, 11, 1, 54, 90, 99,174,170,210, 84,235, 84, 43,231, 44, 94, 51,230,167, +111, 23,120, 52,109,104,143,204, 66, 61, 50, 11, 12,208, 24,158,190,223,176, 28, 15,147, 94,141,196,155,199,114, 89,232, 86,254, +115, 35, 88, 98,177,241,230,189, 68,217,156, 69,223,224,254,163,100,108, 88,251,189,214,104, 49, 91,109,174,170,226,183,119, 26, +236,172,219, 17,207,230, 45,253, 34,181,150, 23,238,231,154, 5, 9, 15,158, 16, 28,190,158, 91,209, 44,200, 63,235, 81,121,231, +177,170,182, 66, 35,254,230,189, 22, 31,151, 27,161,239,126,207,186, 38,147, 21,242,233,233,233, 37,219,182,109,171, 48, 61, 66, +161, 16,229,163, 7, 77, 38, 83,173,163,138,156,236,165, 97,227,250,214, 31, 85,157,185, 18, 10,133,224,121, 30,246,246,246, 80, + 40, 20,117,110,122,180,113, 11,233,217,166,251,208,157,221, 7,191, 37, 56,115, 96, 61,127,235,252,161, 17,101,249,137,191,215, +245, 59, 42, 41, 41,137,103, 24, 38,105,197,138, 21, 45, 54,108,216,208,112,246,236,217, 79,214,127, 53,245,187,167,111,112, 79, +151, 69,188,115,231, 14,153, 54,109,154,209, 96, 48, 36,151,148,148,220,182,102,145,107, 93, 94,226,138,223,126, 90, 30,146,145, +149,243, 70, 64,120, 27,184, 54,108, 3,143,160,182, 40,209,152,113,227, 81, 54,158,220, 63,131,132, 43,123,119,233, 11,220,151, +214, 37,189, 45, 90,180,240, 19,139,197, 3, 1,132, 40, 20,138,250, 12,195, 72,197, 98,241,107, 12,195, 36, 49, 12,115, 63, 36, + 36,228, 12,170, 89,190,168, 42, 82,207,111, 52,214,239, 58,113, 77,154,198,174,219,147, 92, 93, 68,154,198,238,142, 78,230, 48, + 51,255,204,106,163,123,175, 21, 43,137,185, 48,126,207,166,210,125,219,127,249, 86, 56,118,242, 44, 46, 78,237,244,129, 72, 33, + 61,245,213, 27,214,143,230, 22, 48, 76,206,236,217, 31,253,107,154,134,103,145,171,103, 83, 54,100, 91,163,241,108, 61,197, 79, + 20, 94, 97, 63,196,125, 48,101,113,179,214, 29,199,117,238, 59, 74,192, 74,108,113,226,247,117, 36,249,222,217, 61, 34,194,205, +211,229, 63, 78,254,171, 15, 9,147,201, 84,171,185,170,178,233,214, 89,221,245,143,147,231,223, 56,114,252,194, 87,125,123,118, +114,254,241,243,215,240,205,207, 7, 96,163,144,129,240, 28, 70,117,247, 27,113,127, 71,239,129,190,238,114,239,125,231, 50, 47, + 78, 95, 21,247,137, 78,103,126, 88,219,218,121,207, 12,243, 37, 59, 59,187,130, 78,157, 58,181,147,201,100, 76, 97, 97,161,200, +205,205,141,117,112,112, 48,101,102,102,234,140, 70,227, 62, 66,136,182, 46,249, 52, 91,120,164,228, 25,112,112,255, 62,220,189, +126, 6,247,239, 39,106,238, 39,220,255,158, 17,145, 85,101,185, 15, 95, 40,178,202, 87, 57,138,144,212,121, 20,161, 86,168, 88, +122,231,200, 55, 93,131,187,191,223,222, 57,176, 35,156,252,159, 6,138,212,153,113,200,184,185,231,160, 38, 91, 50,146,144,184, + 23, 30,251,238,229,211, 48,152, 8,165,184,122,254, 15, 16,158, 95, 11, 0,132,231,215,222,185,124,116,106,219,126,111,161,158, + 91,253,230, 12,195, 48,117, 93,143, 17, 0,100, 2,179,250,143, 77, 75,247,164,164,164,224,193,131, 7,120,244,232, 17,138,139, +139,177, 61,229,162,186, 46, 58,249,143,175,158,114,111,212,185,247,152, 55,103, 28, 30, 58,124,168,220,175, 65,144, 32,196,199, + 30, 46,182, 34, 36, 38,103,225,113, 92, 18,255,232,222, 69, 3,209,231, 15, 41,124,116,165, 90,195,231,218,100,164,187, 64,200, +204, 57,115,232,233,218,130, 81,131,223, 12,249,120,250,236,118,245,156,157,170,124,142, 23, 23,149, 72, 23, 46,156, 31, 82,190, +127,109,107, 17, 10,132, 66,205,228,169,239,217, 8, 24, 1,202, 47, 23, 41,111, 35,171,248,241,244,131, 68, 44,170,181,140, 78, + 28, 26, 9,150,231,161,213, 91,160,209,155,160,214, 24,145, 83,168, 66,252,253, 71,184,126,233, 56, 82, 30, 39,105, 88,150, 61, + 7,130,253, 5,206,234, 93,207, 79,172, 91, 99,249,132,208,175,158,147, 61, 82, 85, 6,200,165, 34,100,167, 63,102,205,172,225, +133, 39, 89, 47,140, 57,148,227, 30, 62,184,215,196,119, 62, 61,222,185,115,164, 67,179,136, 86, 74, 23,123,123, 72, 68,192,227, +244,124,220,187,125, 67,155,246, 48,166,148,179,232,251, 20,198, 29,250,203,171,180,252,207, 26, 44, 51,199, 70,205,250,116,217, + 73,142,227, 20, 34,161, 80,111, 33,124,159,191, 98,174,254, 46, 8,225, 51,223,121,255,163,138,168, 46, 0, 88, 56, 94,241,214, + 59,179,245,149,223, 16, 24, 11,167, 44,143, 92,213, 50, 82, 79, 88,160, 50,106,230,254,116,119,243,242,205, 9,123, 1, 36,252, +213,145,125, 0, 80, 82,106,186,235,220,115,247, 96,141,142,101, 0,220,175, 66, 83,219,189,123,247, 10,179,245,172,185,206,234, + 10, 66, 42, 87, 78,237, 54,240, 77,193,153,131, 27,248,155,231, 14,142,124, 17,115, 85,169, 2, 51, 3,184,206, 48, 76,220,188, +121,243, 90,187,187,187,187,207,159, 63, 95, 94, 90, 90, 42,254,241,199, 31, 13,133,133,133,185,165,165,165,209,132, 88,223, 63, +225, 89,165, 57, 81,225,222,120, 29,179,119, 67, 47, 39, 55,239,222,142, 46,190,141, 74, 10, 50, 31,151, 22,101, 30,103,120,156, +210,228, 39, 70,215, 53,173, 49, 49, 49,233, 77,155, 54, 61, 32, 20, 10,111, 3,112, 1, 96, 71, 8, 41,102, 89,182, 68, 44, 22, +231, 38, 38, 38,214,121, 65,214,212,243, 27,141,157,223,249,117, 71,177,142,151,152, 4,146, 29,169,231, 55, 26, 1, 32,239,228, +108, 29,128,131,238,221,230, 12, 59, 20,157,250, 93,124,137,195,251,249,231,150, 30,170,171,126,214,157, 93, 65, 47,171,252,235, +179,227, 51, 1,188, 97,227, 30,242,109,236,157,232, 5, 12,129,152, 3,251,165, 46, 47,233,214,203,208, 23,139,197,134, 86,173, + 90, 85, 57, 90, 80, 38,147,213, 56,191,214,179, 7,253, 6,166,107,215, 77,199,207, 92,122,227,216,169,203, 95,181,107,223,201, + 89,238,227, 13,127, 39, 51, 54,125,212,242,253, 51,119, 10,110, 12,250,232,226, 79, 79,178, 13,247, 8, 33,134,186,164, 77,163, +209, 60,100, 24,166,164,172,172,108, 48, 33, 36,131, 97, 24,223,146,146,146, 24,139,197, 18, 91,103, 35,192,227,245,246,237,219, +108,103, 24, 70, 68, 88,254,235,104,177,112,135, 33,231,126,230,139, 24,138, 63, 69, 87, 27,216, 99,242,212,105,193,129, 65,141, +130,203,215, 34, 12,171,111,135,177, 19,223, 14,174,223, 48, 56,248, 95,235, 19,214,252, 66, 69,178,111,235, 25,247,166, 61, 19, + 79,174,248,220,249,241,149,119, 20,245,124,108,181,133,169,197, 37,169,183, 86,232,242,221, 87, 60,191, 66, 67, 93, 73,121, 20, +191,106,195,138, 79,102,231,100, 37,111,208,230, 63,140, 3, 0,109,254,195, 56,165,123,163,207, 11,115, 51,103, 23,229, 63, 89, +241,162,215, 66,171,213,102,111,219,182,205,177, 99,199,142, 2,119,119,119, 20, 20, 20,224,220,185,115, 60,207,243, 89,117,213, +202,123,120,241, 28, 19, 24, 88,111,199, 38,245,215, 34,133, 93, 63,150,131, 23, 33,128, 72,128, 28,179, 81,125,188,192, 81,255, + 17,185, 23, 93,115,185,228, 57,134, 8,136,160,124,109, 65,158,231,153,111,126,216,146, 42, 20, 75,171,108, 82,229, 44, 38, 37, +207,243, 86,175, 69,152, 39, 76,115, 14,183,132, 90, 53,138, 47,142,121, 80,203,203, 41, 57,209,161,239,248,222, 44,203, 89, 0, + 24, 42,109,249,132, 48,103,193,112, 39, 11,235,105,162,235, 98,170,254, 84,207,155,205,142, 16, 74, 96,167,176,128, 1,131, 82, +181, 74,230,202, 73,239,255,149,178,148, 23,119, 48,158,233,218,213,223,116,250,236,132, 11,151,174,142, 36, 60,215,128, 35, 0, + 8,147, 98, 50, 27,246,228,219, 23,110,126,209,244,254,175,193,144,191,113, 62, 10,107,155, 75,254,219, 52, 25,134,145, 60,171, +172,185,202,203,223,188,140,116,214,180,182,224, 95,201,187,157,103,227, 78, 50,185,242, 35,157, 78,179, 65,151,247,240,240,203, +188,158, 12,195, 56,200,100,178, 8, 91, 91, 91,113, 97, 97,225,117, 66,136,250, 85,252,222, 43, 19,249,230, 94,151, 30, 61,195, +102,156,188,152,184,250, 89,243, 97, 5, 62, 35, 87,201,199,245,235, 54,107,243,254,131,255, 54,138,240, 85,200,251,223,165,201, +116,237, 42,114, 43,177,127,131,227,248, 47,187, 7,107,116,185,201,137,211, 46,197, 22, 92, 39,132,104,254, 74, 58,165, 82,233, + 88,179,217,172,144, 72, 36,122,147,201,180,237,191, 37,239,110,225, 67,190, 0,131,198, 86,139, 16,220,207,143, 59, 48,191,214, +103, 72,147, 38, 18,101, 1,156,116,133, 46, 69,117, 53, 86,255,145,239,157, 97,132, 77,155, 54,141,148, 72, 36,126, 28,199, 41, + 77, 38,147, 78,175,215,167,164,166,166, 94,173,110, 65,242,191, 59,157,238, 77,135,172, 18,139,197, 31, 0,128,197, 98, 89,147, + 23,123, 96, 70, 77,199, 86,183,255,255, 75,125, 52,114,164,144,236,217,195,253, 29,223,145,119,196, 8,149,197,194, 58,148,255, + 46, 17,139,212,153,119,246, 58,254,167,202,210, 43, 7,121,182, 60,194,223,177, 1,136,162,154, 84,147,106, 82,205, 42,246, 21, +208,235, 73, 53,255,147,154,158,141, 7,248,122, 54, 30,224,107,237,241, 85,237, 79,175, 39, 1,221,170,223, 68,212, 98, 82, 40, +148,255,192,139, 29, 79,175, 2,229, 63, 73,118,194,225,140,191,115,127, 10,133, 1, 16, 85,205, 3,208,234,208, 31,195, 48, 81, + 47,240,128, 61, 77, 53,169, 38,213,164,154, 84,147,106, 82,205,127,150,102,109,218,175, 76,211, 35,109, 34,164,154, 84,147,106, + 82, 77,170, 73, 53,169, 38,109, 34,124,185,155, 0, 20, 10,133, 66,161, 80, 40,148,151, 10, 53, 88, 20, 10,133, 66,161, 80, 40, +212, 96, 81, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10,229,197,249, 91, +103,114,167, 80, 40, 20, 10,133, 66,249, 39, 66, 35, 88, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161, 80,131, + 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66,161, 80, 40, 20,106,176, 40, 20, 10, +133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161,252,231, 13, 22,195, 48, 81, 84,147,106, 82, 77,170, 73, 53,169, 38,213, +164,154,212, 96, 81, 40, 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10,133, 26, + 44, 10,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,255, 33, 24, 0, 85,142, 4, 32,132,156,182, 90,228, 5, + 70, 19,212,166, 79, 53,169, 38,213,164,154, 84,147,106, 82,205, 87, 79,179, 54,237,186,248,143,255,106, 8, 33,127,219, 6, 32, +138,106, 82, 77,170, 73, 53,169, 38,213,164,154, 84,243,159,182,209, 38, 66, 10,133, 66,161, 80, 40,148,151, 12, 53, 88, 20, 10, +133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, + 10,229,197, 97,158,141, 6,160, 80, 40, 20, 10,133, 66,161,188, 36,104, 4,139, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66, +161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, + 66, 13, 22,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,148,255,188,193, 98, 24, 38,138,106, 82, 77,170, 73, + 53,169, 38,213,164,154, 84,147, 26, 44, 10,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, + 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10,229, 63, 4, 3,160,202,145, 0,132, +144,211, 86,139,188,192,104,130,218,244,169, 38,213,164,154, 84,147,106, 82, 77,170,249,234,105,214,166, 93, 23,255,241, 95, 13, + 33,228,111,219, 0, 68, 81, 77,170, 73, 53,169, 38,213,164,154, 84,147,106,254,211, 54,218, 68, 72,161, 80, 40, 20, 10,133,242, +146,161, 6,139, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66,161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80,168,193,162, + 80, 40, 20, 10,133, 66,161,188, 56,204,179,209, 0, 20, 10,133, 66,161, 80, 40,148,151, 4,141, 96, 81, 40, 20, 10,133, 66,161, + 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40, 20,106,176, 40, + 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10,133,242,159, 55, 88, 12,195, 68, + 81, 77,170, 73, 53,169, 38,213,164,154, 84,147,106, 82,131, 69,161, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10, +133, 26, 44, 10,133, 66,161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161,252,135, 96, + 0, 84, 57, 18,128, 16,114,218,106,145, 23, 24, 77, 80,155, 62,213,164,154, 84,147,106, 82, 77,170, 73, 53, 95, 61,205,218,180, +235,226, 63,254,171, 33,132,252,109, 27,128, 40,170, 73, 53,169, 38,213,164,154, 84,147,106, 82,205,127,218, 70,155, 8, 41, 20, + 10,133, 66,161, 80, 94, 50,212, 96, 81, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, + 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,148, 23,135,121, 54, 26,128, 66,161, 80, 40, 20, 10,133,242,146,160, 17, 44, 10, +133, 66,161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, + 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161, 80,254, +243, 6,139, 97,152, 40,170, 73, 53,169, 38,213,164,154, 84,147,106, 82, 77,106,176, 40, 20, 10,133, 66,161, 80, 40,212, 96, 81, + 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66,161, + 80, 40,148,255, 16, 12,128, 42, 71, 2, 16, 66, 78, 91, 45,242, 2,163, 9,106,211,167,154, 84,147,106, 82, 77,170, 73, 53,169, +230,171,167, 89,155,118, 93,252,199,127, 53,132,144,191,109, 3, 16, 69, 53,169, 38,213,164,154, 84,147,106, 82, 77,170,249, 79, +219,104, 19, 33,133, 66,161, 80, 40, 20,202, 75, 70, 84,213, 31,197,109,151,228,177, 44,235, 6, 0, 34,145, 40,223,114,227, 51, +207,154, 68,124, 61, 61,123,112,192,122, 0, 16, 2,111,103,100,103,159,170, 66,243, 20,203,178, 78,207, 52, 75, 44, 55, 62,235, + 93,147,166,184,205,151, 39,254,180,255,245,121, 61,171,136, 47, 10,197,109,190,204,126, 46,173, 94,117, 8,223,113,255, 31,233, +252, 95,209,252, 39, 35,105,183, 36,207, 98,121, 90,142,196, 98, 81,190,249,122,205,229, 72,210,246,203,236, 63,237,127,109,158, +123, 77,154, 74,133,172, 40,208,219,117,101, 77,154, 79,178, 11,103,106,117, 6,231,154, 52,255,103,238, 77, 43,241,240,240,104, + 37, 16, 8, 62, 99, 24,198,190,210,159,239,101,101,101,125, 72, 75, 37,133, 66,121,229, 12, 22,203,178,110,183,127, 95, 0,173, + 17,232, 49,254, 75,183,128, 33, 63,111,255,183,125, 12, 37, 82,125,210,129,166, 82,104,157, 20, 98,214, 62, 41, 41,137, 1, 0, + 47, 47,175,245, 0,252,170,208,116,186,253,251, 2,232, 76, 64,231,209,139,156, 58,249,250,218,231, 10,133,179,100, 10, 69, 55, +131,193, 16, 6, 0,114,185, 60,222,168,215,159,243,224,184,111,159,223,191,186, 12, 84, 78,107,247,113, 95,186,133, 14,249,249, +125,142,231,165,250, 39,123, 58,243,154, 52,145,132, 51,253,248, 70, 78,206,177, 5, 0,103,205, 5,169,124,222, 46,163, 62,117, +246,243,244,236, 46,149,203,155,219,217,219, 71,242,132, 52,230,121,158,225, 88, 54, 65, 91, 86,118,137,103,217,187,156, 69,231, +124,251,192, 82,190,166,116, 62,159,151,145,128,232,154,135,199, 8,165,141, 77, 55,129, 72,212, 1, 0,120,150,189,170,211,106, +207,181,203,205,221,107, 77,222,173,189, 62, 47,186,255, 63, 13,139,133,117, 75, 62,177, 0, 70, 11, 16, 49,252, 43,183,102,175, +111,222, 14, 0,166,252,187,238,101, 73,135,218, 2,128, 77,224,128,235, 50,143,136, 60, 0, 16,165,229,184, 61, 60, 50, 15, 70, + 11,208,120,192, 34,183,218, 52, 39,206,223,237,252,241,228, 97, 50, 0, 56,185,239,135, 70,103,247,175,237, 11, 0,221,135, 77, + 59,214,107,248,244,135, 0,240,245, 47,251,157,119,126,245, 90,141,154,214,221,155,106,137, 58,233, 72,144,169, 52,199,209,215, + 70,228,145,148,148, 36,168,203,189,233, 3, 56,228, 0,239, 10,132,194,200,192,160,160, 8, 0,228,201,227,199,119, 56,150,189, +236, 9,252,248, 50,203,146, 80, 40,124, 63, 43, 43,107, 96,229,191,121,123,123,211, 2, 73,161, 80, 94, 77,131, 5, 0, 90, 35, +112,225, 17,208,165, 93, 51, 76,126,189,159,109,229,255,237,255,117,177, 95,102,220,169,208,165, 27,191, 22,132,133,133,225,201, +147, 39, 86,157, 76,103, 2,206, 39, 1, 50, 67,138, 93,190, 84,250,120,254,103,159,217, 71, 70, 70,138, 60, 61,159,190,132,231, +231,231,183,187,124,249,114,171,133, 11, 23, 78,149, 25, 82, 74,116, 38,104,206, 39,213,174, 91,158,214,176, 70,245,241,217,244, +215, 28, 0, 96,213,236,189,173,142, 94,189, 91, 47, 37, 37,165,199,210,165, 75,139,188,163,163,215,214,227,184,141,177,249,249, + 25,214,164,115,215,137, 24,121,160,233, 84,192,136,137, 19,247,249,251,251,219,122,121,121, 49, 74,165, 18, 66,161, 16,165,165, +165,126,137,137,137,125,239,222,189,171,189,116,237,160, 52,246,238,240, 39,153,194, 22, 6,107,242, 46, 97, 11,229,113,193,193, +241, 35,250,246,245, 25, 48, 96,128,188, 65,131, 6, 0,128,148,148,148,224, 63,254,248, 99,244,209,163, 71,231, 75,216, 66, 86, +103,130,161,182,188,151,107, 2,128, 28,232,224,232,230, 54, 86, 40, 22,135,177, 44,235,253, 44,186,144,197, 89, 44,241,170,252, +252,109,207,239, 79,249,119,140, 22,224,126, 14, 16, 21, 25,129,113,195,162,108, 0,224,147, 81, 75,218,165,165, 60,146,152, 76, + 38, 52, 10,105,220,113,241, 87, 43, 79, 64, 32,192,214,253,167, 43,246,183, 70,243,222,253,100, 44, 88,188, 10,217,177,123,219, +113,234, 71,221, 52,165,106, 33, 0,216, 59, 56, 12,219,187,107,199, 57,175,166, 35,174, 61, 42, 52, 91,165, 89,211,189,121,124, +215,247,158,153,113,231,154,252,116,242, 55,177,159,159, 31, 98, 99, 99,235,116,111, 66,157,104,199,123,122, 38,124,251,209, 71, + 30,157, 59,119,134,173,173, 45, 68, 34, 17, 88,150,141,186,124,249,114,212,130, 5, 11,166, 65,157,168,181,246,222,180,130,111, +189,188,188,186, 13, 30, 62,214,179, 91,239, 1, 24,214,167, 35, 45,136, 20, 10,229,213, 53, 88, 34,145, 40,191,231,132,165,110, +145,109,195,113,243,238, 67,117,106,122, 78, 89,249,255, 84,247,247, 55, 26, 29, 21,216,100,221,209, 63, 96, 52, 26,113,229,202, + 21,220,189,123, 23, 41, 41, 41,152, 55,111,158, 81, 8,188, 93,141,102, 73,231,209,139,156,100,198, 12,219,150,206, 25, 13,118, +110, 63, 39,212,235,245, 56,127,254, 60, 74, 74, 74, 32,149, 74,225,227,227,131, 78,157, 58,137,206,159, 63, 95,111,212,152,177, + 14,189,134, 76, 74, 54,202,124,203, 68, 34, 81, 73,181, 25, 16,137,242,123,140,255,210,173, 73,112,125, 60, 78,205, 86,127,246, +213,175,101, 60, 79, 68,186,180, 76,243,133, 11, 23, 16, 17, 17,129, 93,187,118, 57,151,148,148,124,190,105,211,166,207, 60,191, +223,184, 38, 39, 51,113,118, 13,122, 37,157, 71, 47,114,106,196,157,245,223,187,227, 55,201,221,187,119, 37,235,214,173, 67, 81, + 81, 17,164, 82, 41, 28, 29, 29,225,225,225,129, 70,141, 26, 49,239,190,251,174,109,183,110,137,248,124,230, 36,255, 28,199,193, +137,213,165,179, 92, 83, 98,202, 81, 6, 11,111, 5,174,223,188, 89,208,166, 77, 27,166,242, 62,126,126,126,232,218,181,171,124, +232,208,161,129,211,222,125,143,143, 26, 58,229,177, 89,234,169,171, 77, 19,218, 12,133,179, 46,218, 43,106,244,232, 67,139, 22, + 45,114,244,240,240,128,141,141, 13, 0, 64,173, 86,251,164,166,166,182,155, 63,127,254,240,235,247,118,137, 58, 15,200,200,134, +141,175,190,166,235,249, 79, 69, 44, 22,229,151, 71,141,236,108, 20, 37, 25,153,121, 90, 0, 48,153, 76, 48,153, 76, 48, 26,141, +120,103,218, 20,225,219,195,219, 4,249, 71,190, 31,147,146,149, 87,220,248,244,181,122,229,199,214,166, 41,210,165,168, 84,233, +103,222, 94,240,209, 71, 30,238,238,255,106,249,219,186,101,139,176,184,184, 56,106,193,130, 5, 77,136,178,171,170,241,128, 69, +142, 53,105,214,120,111, 62,252,163,193,226,233,189,155,255,252,213, 17,112, 28,135,232,232,104, 92,188,120, 17, 43, 87,174, 36, +199,142, 29, 83,219,219,216,212,120,111, 66,157,104,215,201, 51, 55, 96,249,242,125,140, 76, 38,195,193,131, 7,241,224,193, 3, + 8, 4, 2, 52,107,214, 12,227,198,141, 67, 84, 84,148,199,228,201, 83, 72,231, 62,163,158,192, 33, 68,243, 87,202, 18,195, 48, + 2, 79, 79,207,247,223,249,240, 83,207, 97,163,223,192,247,223,124, 65, 13, 22,133, 66,121,117,168,178,247, 59, 32,104, 56,228, +231,157,123,110,241,127, 52, 28,242,243, 78, 2, 8, 8, 32,176, 7,234, 71, 70, 70, 90, 84, 42, 21,185,113,227, 6,121,231,157, +119,180,107,214,172, 57,247,199, 31,127,236,101,205,230, 13, 17,205,155,175, 32,128,160, 58,205,102, 14, 14, 14, 1, 1, 1, 5, + 25, 25, 25,228,232,209,163,100,225,194,133,100,219,182,109,228,216,177, 99,228,244,233,211,228,216,177, 99,100,231,206,157,228, +222,189,123,228,209,163, 71, 36, 48, 48,176,160,153,131,131, 67, 13,154, 66, 2, 8, 27, 13, 89, 55,123,223, 77,203,162,144, 33, + 63,207, 32,128,176,177,187,123,104,207,158, 61,185,189,123,247,146,173, 91,183,146,205,155, 55,147,123,247,238,145,194,194, 66, +226,237, 31, 80, 80,126, 92,117,233, 36,128, 32, 34, 34,162, 64,165, 82, 17, 95, 95, 95, 34,149, 74,137,187,187, 59,105,212,168, + 17,105,215,174, 29,233,219,183, 47,121,253,245,215,201,231,159,127, 78, 84, 42, 21,241,247,247,207, 43, 63,174, 58,205, 1,158, +158,138,192,192,192,244,216,216, 88, 82, 29,122,189,158, 20, 22, 22,146,179,103,207,146,192,192,192,244, 1,158,158,138,154, 52, + 21, 64,203,166, 77,155, 22, 20, 22, 22, 18,179,217, 76,210,211,211, 73, 92, 92, 28,121,240,224, 1, 73, 79, 79, 39,122,189,190, + 66,251,225,195,135, 36, 32, 32,160, 64, 1,180,172, 86,243,159,188,149,151,137,231, 54, 63,119,247,190, 30, 30, 30,250,125,251, +246,145,172,172, 44,178,105,211, 38, 34, 0,150,252,219,190, 53,104, 74,129, 94,157, 58,117,226,162,163,163, 73, 76, 76, 12,153, + 51,103, 14,233,221,187, 55,233,211,167, 15, 89,176, 96, 1,201,204,204, 36,153,153,153,164,111,223,190,156, 20,232, 85, 91,249, +172,234,222,116, 0,252, 6, 12, 24,160, 55,155,205,228,201,147, 39, 36, 44, 44, 44, 83, 8,140,181, 1,154,116, 1,100,181,149, + 79,111,192,201,211,211, 51, 39, 58, 58,154,236,223,191,159,248,251,251, 23, 8,129,137,246, 64, 67,123,160,161, 16,152,216,176, + 97,195,130,232,232,104, 82, 84, 84, 68,252,252,252,114,188, 1,167, 23, 45, 75, 0, 4,158,158,158,191,125,249,245, 15, 36, 49, + 83, 75,190,252,250, 7,226,233,233,153, 78, 8, 33,158,158,158,167,104,153,164, 27,221,232,246,191,190,137,234,100,198,108,108, +150, 46, 94,188, 88,100, 48, 24,240,235,175,191,106,198,140, 26,181,223,209,209,145, 21,139,197, 96, 4,181, 15, 72,212, 56, 56, +124, 48,111,238, 92, 71,163,209,136, 91,183,110,161, 85,171, 86,144,201,100,144, 72, 36, 16,139,197, 16,139,197,240,244,244, 68, +126,126, 62,194,194,194, 48,117,234, 84,135, 31,191,255,254, 3,168,213,139,107,210,229,121, 34, 2, 0,142,231,165,245,189,188, + 38,135, 54,109,186, 98,218,180,105, 2, 27, 27, 27, 24, 12, 6, 24,141, 70, 60,120,240, 0,206,206,206, 80, 42, 20, 86,229, 89, + 32, 16, 8,108,109,109,113,246,236, 89,252,242,203, 47, 72, 73, 73, 65, 78, 78, 14,236,236,236, 16, 22, 22,134,198,141, 27,163, + 75,151, 46,120,242,228, 9, 24,134, 97,106,211, 75, 16,139,223, 29, 55,122,180, 91,120,120,120,149,255, 55, 24, 12, 80,169, 84, + 80,171,213,112,119,119, 71,223,190,125,221, 14, 31, 60,248, 46,128,111,171,218,223, 25,240,240, 9, 14, 62,116,227,198, 13, 23, + 66, 8,182,110,221,138,178,178, 50,152, 76, 38, 8, 4, 2,200,229,114, 56, 57, 57,161,123,247,238,112,117,117, 69,112,112, 48, +118,239,222,237,210,183,111,223, 35,206,249,249, 45,139,128,108,250,122, 81, 59,105,121,121, 39,123, 1, 46, 99, 95,127,253,216, +221,123,247, 34,199,142, 29,139,188,188,188, 79,197,115,230,168, 44,192,170,218,142, 15, 1, 28,234,121,122,110, 92,190,124,185, + 32, 55, 55, 23,179,102,205, 42,204, 78, 75,155,227, 0, 92, 2,128, 51,199,143, 71,110,219,182,109,217,214,173, 91, 93,182,108, +217, 34,136,136,136,216, 24,146,158, 30,150, 8,168,235,146, 78, 13,240,254,234,213,171,229, 6,131, 1, 61,123,246,124, 34, 79, + 73,105,206, 2,122,107,143,207, 1,222, 93,249,241,199, 30, 50,153, 12,179,102,205, 42,212,165,165,133,179, 64, 65,165, 93, 82, + 93,147,147,143,143, 31, 63, 62,238,222,189,123, 46,171, 86,173,242, 24, 62,116,232,187, 0,150, 88,123,142,202, 29,218, 61, 61, + 61,131, 7, 15, 31,235,222,168, 73, 83,236,223,185, 9, 63,173, 94,186,145,227,184,159,189,189,189,167, 11, 4,130,111,104,201, +163, 80, 40,175,100, 19, 97,117, 56,187,186,182, 10, 13, 13,197,133, 11, 23,208,180,105,211, 27,142,142,142,172, 68, 38,131, 88, + 44, 6,225,249, 90,143, 87,216,216,244,232,220,185,179,232,234,213,171, 8, 8, 8,128, 66,161,168, 48, 86,229,155, 68, 34,129, +167,167, 39, 74, 75, 75, 17, 25, 25, 41,222,184,113, 99, 15, 0,139,107,211,206, 78, 77,180, 69,242,198,215,151,125,187,162, 97, +155, 54,109,160, 86,151,130,231,121, 40,149, 74,152, 76, 38,136, 68, 34,152, 76, 38, 24, 76,164,212,154,188,114, 28,199, 9,133, + 66, 4, 4, 4, 96,233,210,165, 48, 24, 12,144, 72, 36, 0,128,210,210, 82,168, 84, 42,196,197,197, 33, 53, 53, 21,228,217, 43, +121, 77,216,216,218,246, 27, 52,104,144,180,170,255, 25,141, 70,168,213,106,168,213,106,168, 84, 42, 24, 12, 6, 52,107,214, 76, +122,238,236,217,126,213, 25, 44,163, 92, 62,124,203,150, 45,110, 82,169, 20,122,189, 30, 26,141, 6, 25, 25, 25, 72, 75, 75, 51, +228,231,231,179,118,118,118, 2,127,127,127,129, 76, 38,147, 13, 25, 50,132, 41, 45, 45, 5,195, 48, 24, 48, 96,128,243,246,173, + 91, 95, 3,176,146, 22,127,235, 56, 9, 24, 91,154, 76, 3,219,182,105,115,246,198,205,155, 17, 31,124,240, 1,238,221,187,183, + 92,185,107,215, 5, 29,112,183,166, 99,159, 0,239,174,168,100, 92, 72, 90, 90, 83,243,115,198,197,255,169,113,137, 45, 55, 46, + 35,235,104, 92, 0,192,206,193,161,181,167,167, 39,142, 29, 59,134,244,148,148, 79,234, 98,174, 0, 64, 32, 20,118,234,220,185, + 51, 14, 30, 60,136,204,180,180, 79,158, 51, 87, 0,128, 2,160, 64,244,228,201, 39, 27, 55,110,252,237,205, 55,223,132, 80, 36, +234, 4,150,181,250, 28, 85,117,104,127,247,131, 79,112,112,223,182,141, 57, 57, 57,111, 17, 66,120, 0, 55,104,137,163, 80, 40, +175, 2,117,154, 7,203,195,195,195,219,198,198, 6,217,217,217,104, 28, 26,154, 47,147,201, 32, 21,139, 33,151, 74,173, 58,222, + 96, 48, 52,245,240,240,128, 90,173,134,139,139, 11, 36, 18, 73,197, 38,149, 74, 43, 62,219,217,217, 65, 32, 16,192,219,219, 27, + 6,131,161,105,109,186,172, 42,201,237,248,166, 57,239, 28,222,183,165, 97,223,190,253,224,228, 84, 15,190,190, 62,112,115,115, +131, 66,161,128,175,175, 47,130,130,130,200,250,245,235, 33,176, 15,178,234, 1, 94,217, 52,137, 68, 34,112, 28,135,188,188, 60, + 36, 38, 38,226,222,189,123,136,142,142, 70, 76, 76, 12, 52, 26, 13,172,240, 87,208,234,116,205,171, 10,116, 25,141, 70,168, 84, +170,138,232,149, 74,165, 66, 65, 65, 1,158, 60,121,130, 82,141,166, 69,117,122, 78,206,206,195,194,195,195,133, 0,160, 80, 40, +208,162, 69, 11,252,252,243,207,236,225, 3, 7, 70, 53,137,142,174,231,123,226,132,227,250,117,235, 70,141, 24, 49,130,187,118, +237, 26, 74, 75, 75,113,255,254,125,184,186,186,138,164,114,249,107,180,232,215,141,219,128,214, 69,163,233,211,161, 67,135,100, +181, 90,141,111,190,249, 70, 32,182,179,251,101, 17, 32,172,197, 85,116,236,220,185, 51, 14, 29, 58,132,236,180,180, 57,105, 85, + 24,151, 52,160, 32,253,201,147, 57, 27, 55,110, 68,175, 94,189,192,136, 68,117,238,136,212,174, 93,187,112,158,231, 17, 27, 27, + 11, 71,224,122, 93,143, 15, 12, 10,138,176,181,181,197,131, 7, 15, 96,243, 44,186, 86,229,139, 2,112,233,206,157, 59, 80, 40, + 20,104,220,164, 73,203, 58,158,230, 91, 47, 47,175,156,119, 63,248, 4,251,143, 95, 1, 0, 28,220,183, 45,175,146,185,162, 80, + 40,148,127,166,193, 42, 71, 44, 22, 67, 42,147, 65, 42,149, 62, 53, 70, 50,153,213,199, 50, 12, 3,185, 92, 94, 97,168, 42, 27, +171,202,159,149, 74,165, 85,198, 5, 0, 44,185, 87, 34, 95, 27, 57, 66, 42,145, 72, 96, 50, 25, 65, 8,129, 76, 38,135,163,163, + 35, 2, 2, 2,160,211,105, 49,104,240, 48, 99,134, 74,114, 68,226,211,227,222,139,228,153,101, 89,104,181, 90,148,148,148,160, +184,184, 24,165,165,165,208,235,245,176,162,117,176,162,170, 77, 79, 79,199,142, 29, 59, 80, 84, 84, 4,224,105, 7,234,114, 83, + 85,254, 51, 57, 57, 25, 91,183,110, 69, 74, 74, 10,132, 66,161,213,223, 79,100,100, 36,142, 28, 57, 34,236,218,163,199,134, 83, +254,254,217,167,252,253,179,187,246,232,177,225,208,161, 67, 66,111,111,111,164,166,166,226,214,173, 91, 40, 41, 41, 1, 33,132, +161, 69,191,238, 60, 6, 74,116,197,197,111,126,250,233,167,196,214,214, 22,223,172, 88,209,124, 9, 48,198, 90,227,226, 80,131, +113,113,248,107,198, 5,132, 16,240, 60, 15,142,227, 94, 40,111, 12,195, 48, 98,177,184, 46,229, 25,120,186,212,150,181,250, 2, + 66,200,251,239,124,248,169,231,123, 31,205,199,185, 19, 71,202,255,158, 68,205, 21,133, 66,121, 21,169, 83, 19, 97,118,118,118, +150, 86,171,109,232,239,239,143,204,204, 76, 55, 63, 63,191, 52,169, 88, 12,137, 84,106, 85, 31, 44,185, 92, 30,155,151,151,215, +209,219,219, 27, 44,203, 86,152,169,231,155, 8,203,163, 50,247,239,223,135, 92, 46,175,117,156,185,128, 43,171, 31, 22, 22, 86, + 17, 9,114,116,116,132,163,163, 3,100, 50, 57,150, 45, 91,198,111,248,229,151, 31,229, 97,239,170, 63,156,244, 49,185,189,100, +195, 75,189,128,214, 86, 72, 74,165, 50,182, 65,131, 6,237,149, 74, 37,246,239,223,143,212,212, 84,148,148,148, 64,167,211,193, +104, 52, 66,167,211,193,100, 50, 65, 46,151,163, 73,147, 38,168, 87,175, 30,226,227,227,171,205,123, 73, 81,209,254,216,216,216, +246,109,218,180,169,136,160,116,235,214,141,233,214,173,155, 75,249,239, 58,157, 14,133,133,133,184,113,227, 6, 78,159, 62, 13, +134, 97,144,148,148,196, 25,245,250,157,180,232,191, 24, 6,224,170,112,227,198,223,166, 78,157, 58,169, 99,199,142,224,128,190, + 0,182,254,167,140, 75, 57,209,209,209,113, 28,199,117,108,212,168, 17, 84, 64, 91, 0, 7,235,100, 30, 31, 61,186,195,178,108, +143,230,205,155, 99,255,158, 61,145, 0, 82,171,218, 79, 11, 68, 70, 68, 68, 64,175,215,227,126, 66,194,109,107,205,149,167,167, +231,134,119, 62,252,116,226,176,209,111, 96,255,206, 77, 56,184,111, 91,198,143,107,150,251, 18, 66,204,180, 84, 81, 40,148,127, +188,193, 42, 41, 42,186, 29, 23, 23,215,176,101,203,150,216,176, 97, 67,155, 14,237,219,103, 73,164, 82, 86, 42,145, 64, 96, 69, + 5,162,215,106,207, 92,190,124,185,109,175, 94,189, 68,215,174, 93,131,135,135, 71,133,193, 42,255, 41, 18,137, 64, 8,129, 82, +169,196,177, 99,199,204,122,173,246, 76,109,186, 28,203,113,130,103, 6,143, 16, 2,149, 74, 5,137, 68,130,245,235, 55, 96,211, + 47,191,188,158,153,147,179, 55,184,149,211, 71, 0,228,255,177,138, 89,167, 59,123,230,204,153, 86, 51,103,206, 20,251,248,248, + 64,165, 82,161,164,164, 4, 69, 69, 69, 40, 45, 45, 69,105,105, 41, 74, 74, 74,160, 82,169, 32,151,203,241,232,209, 35,139, 65, +167, 59, 91,157,158,204, 96,216, 55, 97,194,132,143,239,220,185,227, 41, 18,137, 96,177, 88,192,243, 60,120,158,135,217,108,198, +163, 71,143, 16, 31, 31,143, 7, 15, 30,160,184,184, 24, 98,177, 24, 66,161, 16, 49, 49, 49, 37, 54, 22,203, 30, 90,244, 95, 28, + 49,176,255,242,229,203,147,198,141, 27, 7, 47, 31,159, 46,200,204,180,202,184, 28,168,193,184,168, 95,192,184,252,201,248,104, + 52, 55,147,147,147, 59,118,237,218, 21,158, 62, 62,203,155,100,102,158, 74,168, 67, 63, 44,142,101, 47, 93,190,124,185,199,248, +241,227,177, 97,195,134,229,174,201,201,199, 11,158,107,206,116, 5, 92, 27, 4, 6, 46,159, 56,113, 34, 78,158, 60, 9,142,101, +171,141,200, 61,215,161,189,254,224,225, 99,125,105,135,118, 10,133,242, 79,162, 78, 77,132,140, 86, 59,119,222,188,121, 22,161, + 80,136, 97,195,134,217, 29, 60,116,104, 68,204,221,187, 1,249,249,249,142, 28,199,213,170,101,167, 86,175, 89,188,120,177,202, + 98,177, 32, 36, 36, 4,197,197,197,224, 56, 14, 34,145, 8, 34,145, 8, 12,195, 64, 32, 16,192,214,214, 22,241,241,241,216,181, +107, 87,169,157, 90,189,166, 54, 93,158,231, 99,127,255,253,119,136, 68, 34, 34,151,203,193, 48, 12, 68, 34, 17,214,175, 95,159, + 63, 55, 39,103, 63, 0, 8, 5, 2, 19, 0, 8, 4,140, 85,189,114, 25,134,169,181,125, 82, 42,149,130,127,218,185,191,214,125, + 93, 45,150,213,235,214,173,211, 36, 37, 37, 65,171,213, 86, 68,219,202,202,202, 42, 58,205,171, 84, 42, 48, 12, 3,131,193,128, +139, 23, 47,106, 92, 45,150,213,213,233, 21, 1,185,153, 73, 73,131,218,180,105, 83,148,156,156, 12,181, 90,141,216,216, 88,156, + 62,125, 26,187,119,239,198,201,147, 39,241,232,209, 35,176, 44, 11,111,111,111, 16, 66,112,224,192, 1, 53,171,209,244, 45, 2, +114,105,209,175,158,250, 30, 30, 61,220,221,220,210, 93, 93, 92, 50,235,123,120,244,120,254,255, 14,192,195,135, 15, 31,130,101, + 89, 4, 4, 4,212,171,169, 31, 22, 97,217,203,151, 47, 95,198,248,241,227,225,219,176,225, 50,127,192,245,249,125,252, 1, 87, +255,192,192,101,229,198,133,176,236,229,186,166,217, 14,248,238,163,143, 62,210, 75, 36, 18,236,218,181, 43,192, 18, 20,244, 64, + 4,140,177, 5, 66,187, 2,146,218,142,247, 4,126,252,252,243,207,115, 25,134,193,182,109,219, 92, 28, 2, 3,227, 68,192, 4, + 7,160,190, 3, 80, 95, 4, 76,112, 8, 12,140,219,181,107,151, 11,203,178,152, 49, 99, 70,174, 39,240, 99,117,122, 66,161,240, +253,236,236,236,129, 89, 89, 89,157,179,179,179,125,127, 92,179, 28,231, 78, 28,193, 79,171,151,110,204,201,201,121, 43, 47, 47, +239, 70, 86, 86,214,184,204,204,204, 56, 90,226, 40, 20,202,171, 8, 83, 85, 63, 39,113,219, 37,121, 0,113,235,210,174, 25,110, +222, 77, 84,187, 56,217,159, 40,255,159,234,254,254, 70, 3,218,121, 52,251,230,155,111, 32, 18,137,144,145,145,129,132,132, 4, +216,219,219,227,131, 15, 62, 48, 90,140,198, 65,229,235,157, 49, 12, 19, 69, 8, 57,253, 76,243, 20,203,178, 78, 50, 99,134,109, +132, 83,114,195,173,155, 55, 10,237,236,236, 80, 86, 86, 86, 49,173,128, 82,169,132, 66,161,192,189,123,247, 48,254,141, 55,185, +199,108,243,138,137, 70,203,215, 59,171,172, 9,134, 17, 2, 64, 95, 39, 39,229,125,153,108,150,179,187,251,236,247,222,123, 79, +209,165, 75, 23, 72, 36, 18,180,106, 27,153,107,211, 98,246,119, 2, 1,195,102, 22,149,206, 11,172,239,229,144,144,148, 10,128, +121,186,102,225,179,181, 8,171, 74,103, 83,249,189,128,173, 63,125, 97, 31, 22, 22,246, 52,223, 42, 21,242,242,242,144,159,159, + 15,149, 74, 5,173, 86, 11, 0, 56,125,250, 52,206,222, 72, 46,205,177,237,249,164,186,116,254, 43,239,169,118,141, 21, 15, 27, +124,183,122,165,208,209,209, 17,121,121,121, 40, 40, 40,128, 74,165,130, 94,175, 7,199,113, 40, 45, 45,197,161, 35, 71,185, 39, + 92,211, 20,163,172,190,166, 54, 77,104, 51, 20,245,202,174,120, 71, 52,241, 39,147, 38, 77,178,179,183,183, 7,207,243, 40, 41, + 41, 65,122,122, 58,146,147,147,113,241,226, 69,109,190,202, 4,173, 75,207,204,242,137, 70,171,188,158, 47,171, 80,253, 47,106, + 62, 43, 75, 0,224,229,233,153,157,150,150,230,198,113, 28,188,189,189, 89, 85,113,241, 50, 41,112,210, 14,200, 1, 64, 10,129, +207, 86,127,247,221,155,131, 7, 15, 70,235,214,173, 51,114,243,242, 26, 84, 85,150,192, 48,194, 16,192, 65,231,227, 19,127,227, +198, 13,143,244,244,116,140, 31, 63,190, 48,237,241,227,138,105, 26,212, 64,164,127, 96,224,178, 93,187,118,185, 52,108,216, 16, + 77,155, 54,205,149,151, 79,211, 80,117,249,172,254,222,124,248, 71,131,105, 67,195, 91,191,243,206, 59, 96, 89, 22, 23, 47, 94, +196,245,235,215,145,150,150,134, 43, 87,174,168,236,109,108, 70,213,116,111, 66,157,104,215, 55, 88, 27,176,109,219, 86, 70, 34, +145, 96,227,198,141,184,115,231, 14, 0, 32, 34, 34, 2, 19, 39, 78, 4,203,178, 24, 59,118, 28,249, 35, 81, 81, 49,209,104, 85, +101,201,199,199, 39,156,231,249, 21, 12,195, 72, 8, 33,173,179,179,179,229,222,222,222,217,217,217,217,190,117,233,115, 69,203, + 39,213,164,154,255, 28,205, 87,141, 90,215, 34,252,114, 45, 28,254,188, 28,199,219,217,191,255,186, 68,212,187, 79,223,208,121, +159,206, 21, 68, 68, 68,192,215,215, 23, 17, 17, 17,184,115,231,142,172,113,227,198,181,173,119, 86,214,107,200,164,228, 94,189, +122, 57,190,251,238,187, 14, 93,186,116, 17,123,121, 61, 93, 87, 55, 62, 62, 30,199,142, 29, 51,239,216,177,163, 52, 75, 26,169, +186,114,236,215, 50,107,214, 59, 59, 86, 82,162, 3,240, 69, 51,147,233,151,207,231,205, 91, 16,214,180,233,164, 15, 63,252, 80, + 96,107,163, 20, 47,153,247,150, 28, 0,190,252, 97,183,195,224, 17,175, 99,117, 16,208,101, 76,213,235,188, 85, 78,103,102, 78, +126,218,152,137, 35,130,222,125,107, 12, 55,112,224, 64, 27, 91, 91, 91,248,250,250,194,201,201, 9, 41, 41, 41,136,141,141, 37, +167, 78,157, 42,187, 29,159, 34,222,180,251,100,154,212,214,205,154,117, 3, 53,189, 6, 79, 72,153, 48, 97,130,211,208,161, 67, +237,194,194,194,196, 98,177, 24,114,185, 28, 69, 69, 69,200,200,200, 48,159, 63,127,190, 44, 75,210,190,228,202,241, 77, 26, 43, +215, 34,212,119, 30,189,232,209,165, 83, 11,103,196,199,198,142,227,129,230,102,179,217,155,227, 56, 70, 32, 16,228,240, 60, 31, +107,214,104,126, 51, 70, 44, 92, 69,215, 34,180, 14,142,227, 36, 28,199, 65,165, 82,225,212,169, 83,162,199,143, 31,127,118,247, +238,221,207,178,179,179, 97,177, 88, 48,124,248,112, 68, 68, 68,224,220,185,115, 40,200,203, 59, 92,147, 86, 34,160,150,101,102, + 78,124,251,237,183,143,109,221,186, 85,112,247,238, 93,151,141, 27, 55,254, 90,149,113, 25, 55,110, 28,159,151,158, 62,209, 88, +195, 28, 88,181,220,155,133,199,119,125,127,119,200,176, 17, 77, 22,206,255, 76,220,161, 67, 7,184,184,184, 32, 50, 50, 18,102, +179,217,209,138,123, 83,211,185,207,168, 39,205,155, 55,183, 89,181,106,149,199,155,111,190,137,233,211,167, 3, 0,244,122, 61, + 78,158, 60,137, 25, 51,102,228,166,139,218,106,111,159,219, 85, 99,249,124, 22,153,234, 9, 0,222,222,222, 23, 0,116, 6,240, +132,118,104,167, 80, 40,255,104,131, 5,252,107,189,179, 75,215,227, 80,121, 57,142,167,184, 38,176, 46,195, 31, 79,157,189,188, +169, 20, 90, 39, 49, 99,180,143,185,115,135, 73, 78, 78,174,241,100,229,235,157, 25,101,190,101,202,236,194, 54,223,173, 94,253, +193,134, 13, 27,122,148, 79,197, 32,151,203, 99,245, 90,237, 25, 59,181,122,141,177,161,239,153,186,174,157,119,175,184, 56, 15, +192,180, 80,142,251,238,141, 73, 83,190, 22,216,250,136, 63, 93,178,193, 32, 20, 8, 76,143,178, 11,176, 58, 8,176,177, 98,192, +163,206, 4,196, 22,185,177, 9,232,154,184,124,209,162, 89,171,191,253,182,141,210,214,182,139,133,101,131,121,158, 7,225,184, + 36,189, 94,127, 1,102,243,141, 76,175,201,223, 74,109,221,136,181,235, 6, 26,229, 13, 52,238,218, 11,109,246,237,217,243,254, +177, 99,199,254, 45,239,158, 60,255,221, 19,251, 6,167,173,201,123,229,125, 12,192, 85,228,231, 95,173,246,109, 3,116, 45, 66, +171,111, 10,158,159,236,228,228,180,165, 71,143, 30,242,168,168, 40,244,239,223, 31, 29, 58,116, 0,207,243, 32,132, 64,163,209, + 96,247,238,221,248,250,235,175,147, 26, 0, 95,212,166,103, 4,206,200,142, 30,237,219,188,121,243,141, 53, 25,151,103,230,170, +214, 62,135, 53,223,155,178, 36,214, 97, 80,234,232,119,151, 6,153, 74,115, 28,157,149,172, 71,124, 92,172,192,218,123, 19, 14, + 33, 26,238,206,238,182,195,135, 14,125, 87, 40, 18, 69, 62, 27,209, 72,238, 39, 36,220, 46, 95,236, 25, 17, 19, 79,213,165, 44, + 17,242,116,238, 57,218,161,157, 66,161,252,227, 13,150, 72, 36,202, 47,143,242,136, 68,162,252, 39, 7,166,188, 94,147,136,175, +167,103,143,103,111,199,168,109, 45,194,242,207,119,213,106,205,179, 25,218,171,156, 68, 84,252,220,254,117,201,212,131,252,252, + 68, 0, 3,128, 52, 32,241,105,119, 22,113,155, 47, 63,169,156,167,106, 47,200,159,206, 43, 41, 78,205,203,187,132,167,205, 57, + 85,118,198, 21,251, 73,138,107, 75,231,243,121,191,156,145, 81,250, 44,223, 85,231,221,163,246,188,139,234,120,125, 68,127,225, +122,254,211,200, 42, 44, 60, 0,192,214,231,200, 17,247,227, 71,142,188, 54,107,230,204,225,158, 94, 94,129, 46, 46, 46, 78,118, +118,118,130,107,215,174, 37,179, 6,195,119, 45,128, 77,215, 1,157, 53,154, 70,224, 76, 72,122,122,216,200,161, 67,223,101, 68, +162, 78,149,141, 11, 97,217, 43, 1,192,143, 70, 43,102,111,175,243,189, 41,171,251,189,153,249, 52, 29, 75,192,178, 75,112,239, +222, 95,190, 55,121,158,255,210,219,219, 91, 67, 59,180, 83, 40,148,127, 20,127,231, 58, 60, 0,162,168, 38,213,124, 85, 52,159, +122, 20,216,211,235, 73, 53,169, 38,213,164,154, 47, 95,243, 31,189, 22, 33,133,242, 15,127, 25,225, 0,148,210, 43, 65,161, 80, + 40,148,218, 96, 0, 68, 85, 83,153, 88, 61, 58,128, 97,152,168, 23,168,172, 78, 83, 77,170, 73, 53,169, 38,213,164,154, 84,243, +159,165, 89,155,246, 43, 51, 58,145, 54, 17, 82, 77,170, 73, 53,169, 38,213,164,154, 84,147, 54, 17,190,220, 77, 0, 10,133, 66, +161, 96,209, 34, 70, 0, 48, 12,176, 72, 0,236, 21, 2, 35,133, 79,127,127,113, 70,142,100,170,156,132,246,253,247, 25, 59,122, +197, 41,148, 87, 27,218, 7,235, 63,136,167,167,167,159,187,187,251,207,132, 16, 38, 63, 63,127,114, 78, 78, 78, 58,189, 42,255, +125, 56, 59, 59,247, 96, 89, 22,106,181,250,204,171,152,191,176, 32,102, 40, 17,160,241,191,194,218, 72, 79, 72, 34, 91,170,218, +183, 73, 48, 51, 30,204,191,230,210, 98,120,220,143,127, 68,126,183,246, 92, 12,195, 8,134,244,117, 93, 1, 0, 7,142, 21,204, +254, 59,230,197,242,242,242,106,228,236,236,124, 66, 40, 20,138, 56,142,155, 22, 27, 27,123,164,122, 3, 52, 82, 8, 0,174,138, +253,115, 29,235,185,204,249,124, 22, 35, 54, 25,191, 81, 25, 13, 6,181, 64, 36, 74,145, 74,148,151, 89,129,205,177,204,188,190, + 9, 85, 29,191,103,207,158,106, 87,215, 14, 15,102,250,134, 54,105, 50,176,101, 83,197,147, 21,107,218,172,238, 18,224, 34, 78, +206,136,177, 93,187, 37,253,103, 87, 39,239,129, 31,188, 37, 58, 34, 35,220,184,229,191,146, 50,122,151, 89,207, 87, 12, 83,207, + 12, 52, 21,203,100,190, 28,203,186, 51, 0, 17,138, 68,121, 22,163, 49, 67, 2,220,155, 67,136,234, 85,215,148,200,100, 62, 28, +203,186, 3,192,127, 99, 58, 41,181, 24,172,192,192,192, 91, 2,129,192,167,124,141,191,202,139,213,150,127,126,254, 39,199,113, +153, 15, 30, 60,104,101,237,201, 27, 54,108,104,111, 48, 24, 94, 99, 24,230,117, 0, 32,132,108,151,203,229,187,147,147,147, 95, +168, 35,113,195,134, 13,237, 9, 33,179, 21, 10, 69,119,131,193, 16, 6, 0,114,185, 60, 94,175,215,159,101, 24,102,197,139,232, + 50, 12, 35,242,244,244, 28,105, 99, 99,211,141,101,217,110,132, 16, 70, 36, 18,157,211,233,116,103,115,114,114,246, 16, 66,216, +186,106,122,121,121, 41,156,157,157,151, 4, 5, 5,141,121,247,221,119,139,234,213,171, 23,178,104,209,162,155,225,225,225, 59, +138,139,139,231,101,103,103,235,255, 27, 10, 7,195, 48,129, 30, 30, 30,219,197, 98,177, 48, 35, 35,163, 27, 0,248,250,250,158, + 51,153, 76, 92,126,126,254,235,132,144,199,117,209,115,117,117,181, 17,139,197,237,108,108,108, 90,217,216,216,116,230, 56,174, +241,179,245, 19,239,107,181,218,139, 22,139,229,150,197, 98,185, 86, 80, 80,160,253,111,185, 65, 24,134,177,115,115,115,219,202, + 48, 12, 24,134, 9, 38,132,104, 94,181,135, 0, 17,160,113, 66,252,131,144, 10, 19, 21, 22, 90,195, 5,129, 95, 21,251, 90,109, +176,250,245,112,236, 51,112, 96,115, 1, 0,152,205, 55,251, 0, 56,250,178,205, 85,191,126,253,174,126,247,221,119, 78, 6,131, + 1, 31,125,244,209,246,224,224,224, 31,147,146,146,230,214,116,156,157,157,221,140, 47, 22,255,160,124,246, 44,115,227,121,222, + 45, 39, 39, 35, 56,241, 65,108,159,196,196,184,165,102,237,239,215,204, 68, 56, 69,165, 27,244,192,154,116, 52, 9,100, 6, 12, + 30, 57,180,255, 23, 95, 44,196,152, 81, 99,234,199,199, 27, 20,222,246, 79,164,165,102,155, 32, 23, 23,159, 65,159,124,186,156, +185, 22,125,126,208,158,221, 27,206,126, 50,137,233, 78, 77,150, 85,247, 34,243,165, 72,212,206, 41, 52,180,243,168, 3, 7, 96, +235,235, 43, 18,201,100, 2, 0, 96,141, 70,223,178,140, 12,207, 93,131, 6,181, 93,196, 48,231, 23, 16,114,157,106,254,255,107, + 82,172, 52, 88, 2,129,192,231,206,157, 59,110, 54, 54, 54,120,102,126,192,113, 28, 56,142,171, 88, 84,152, 16, 82,241,147,101, + 89,116,237,218,213,170, 55, 88, 79, 79,207,238, 0,222, 8, 15, 15, 31, 62,123,246,108, 73,199,142, 29,193,113, 28,206,158, 61, + 27,185,122,245,234,239,189,188,188,246, 3,216,148,147,147,115,198,218, 55, 92, 79, 79,207,222, 54, 54, 54,219, 62,251,236, 51, +251,200,200, 72,145,167,167, 39, 0, 32, 63, 63,191,221,229,203,151, 91, 45, 92,184,112,154,167,167,231,216,156,156,156, 19,214, + 94, 28, 31, 31,159,240,224,224,224,189,125,251,246,245,105,213,170,149,188, 81,163, 70, 32,132, 32, 38, 38,230,205,196,196,196, +209, 71,143, 30, 93,224,227,227, 51,194,218,245,212, 24,134, 97, 2, 3, 3, 39,120,120,120, 44,153, 57,115,102,189, 33, 67,134, + 72,227,226,226, 74, 2, 2, 2,152,253,251,247,187, 30, 62,124,120,218, 79, 63,253, 52, 50, 40, 40,104,222,227,199,143, 55,147, +170,214, 49,122,142,224,224,224, 91, 2,129,192,199, 26, 3,204, 48, 12, 88,150,181,202, 4, 51, 12,211,162, 65,131, 6,187, 47, + 93,186,212, 32, 53, 53,149, 27, 50,100,200, 22, 0, 56,123,246,108, 83,139,197,194,244,234,213,235, 24,195, 48,175, 17, 66, 98, +172,201,187,183,183,119, 51, 87, 87,215,131, 67,134, 12,169,231,231,231,167,244,241,241, 97,228,114, 57,132, 66, 33,202,202,202, +188, 18, 19, 19,163, 98, 98, 98,244, 87,174, 92, 41,246,246,246, 30,148,149,149,117,175, 14, 15,222, 14,110,110,110,227,196, 98, +113, 56,203,178,222, 0, 32, 18,137,178, 44, 22, 75, 92,126,126,254, 86, 66,200,213, 23,189, 65,220,221,221,191, 95,178,100,137, + 75,126,126, 62, 89,182,108,217,247, 0, 38,188,170, 15,131,237, 59,246,224,214,205,235, 0, 32, 97, 24,134,121,190,252, 49, 12, +195, 52, 14,134,228,195, 15,103,162, 85,235,182,120,125,204,200, 90, 53,135,244,119,249, 66, 42, 20, 57,235, 76,198,235,133,106, +193, 65, 63, 55,233,208,177, 35, 91, 61, 1,128,227,199, 98,135,182,109, 91,239,178,139, 3, 63, 88, 41,149,181, 53,113,108,209, +129, 63, 10,231,215,197, 76,121,120,120,156,176,179,179, 83,150,148,148,228, 22, 21, 21,173,237,215,175,223,151,171, 86,173,114, +122,242,228, 9, 50, 50, 50,240,198, 27,111,216,102,101,101,189,235,231,231, 23,157,158,158, 94,109, 36, 75,163,209,172, 89,178, +120,230,124, 59,123, 39,161, 82, 97, 3, 91, 59,123, 52,104, 16,140,214,109, 34, 17,213,115, 16,158, 60, 73,108,183,123,231,134, + 59,194,156,189, 95,113,210,136, 47, 85,170, 6,213, 62,151,194, 66,152, 46,229,230,106,254,252,133,120,248,224,129, 38, 53, 69, +240,222, 31, 7, 68,202,190, 61, 66,101, 38,115, 89,234,181,232,243, 13,218,181,239, 10, 0,173,246,236,222,112,118,209, 88,166, +199,130,109,175,158,121,127,153,230,234, 11,177,120, 66,239, 85,171,220, 34,166, 77,147,148,165,164,152,159,172, 91,167,203,187, +120,145, 19,201,100,196,183, 79, 31,198,181, 91, 55,249,180,251,247, 37, 87,150, 45,235,188, 84, 42, 13,248,212,100,218, 70, 53, +255,255, 52, 41,117, 51, 88,176,177,177,193,174, 93,187, 32, 22,139, 33, 18,137, 32, 22,139,171,253,236,231,231,103,141, 9, 26, + 22, 22, 22,246,195,204,153, 51,221, 7, 14, 28, 8, 39,167, 63,175,178, 49, 96,192, 0,244,235,215, 79,146,156,156, 60,122,207, +158, 61,163,183,108,217,146,235,233,233,249, 94,206,179, 5,155,107,168,188,187, 5, 4, 4,236,223,177, 99,135, 66,175,215,227, +252,249,243, 40, 41, 41,129, 84, 42,133,143,143, 15, 58,117,234, 36, 58,127,254,124,189,209,163, 71,239,247,246,246, 30,144,149, +149,117,174,182,180,122,120,120,180,114,117,117,189,240,203, 47,191,200, 67, 67, 67,153, 71,143, 30,161,121,243,230, 0,128,162, +162, 34, 12, 24, 48, 64, 62,116,232,208,192,119,222,121,231,154,135,135, 71,151,220,220,220, 91,181,228,189,101,243,230,205, 55, +247,233,211,199,107,206,156, 57,246,182,182,182, 72, 77, 77,205,241,240,240, 8, 46, 55, 63,131, 7, 15,150,246,236,217,211,115, +237,218,181,107,142, 30, 61,250,145,167,167,231,132,156,156,156,219, 53,233, 10, 4, 2,159,219,183,111,187, 41,149, 74,228,229, +229, 97,251,246,237,120,247,221,119, 33, 20, 10,145,159,159,143,221,187,119,227,189,247,222,131, 80, 40,132, 90,173,182,202, 4, +219,216,216, 68, 53,111,222,252,215,179,103,207,250, 56, 58, 58,194,203,203, 75,240,249,231,159,135, 7, 4, 4, 40,234,215,175, + 47,204,201,201,193,254,253,251, 3,198,141, 27,119, 80, 46,151,191,105, 48, 24,106,109, 58,115,118,118,254,109,243,230,205,126, +119,239,222,197,186,117,235, 80, 92, 92, 12,169, 84, 10, 71, 71, 71,120,120,120, 32, 56, 56,152,153, 54,109,154,178,123,247,238, +202,133, 11, 23,254, 6,160,133, 21, 15,221,230,110,110,110, 63,143, 30, 61, 58, 96,209,162, 69,142, 30, 30, 30, 40,127, 33, 80, +171,213, 62,169,169,169,237,230,207,159, 63,194,221,221, 61, 57, 63, 63,127, 10, 33,228,110, 29, 31,234, 45,122,244,232, 49, 96, +200,144, 33,194,156,156, 28,108,221,186,117, 0,195, 48, 45,172, 53,149,255,107,220,186,121, 29,147,223,249,160,204,203,215, 87, +114,248,208,206,193,101,101,191, 92,182, 21, 56,138, 0,160,140, 87,177, 29,219,217,118, 26, 56,104,180,164, 95,255, 33,101,191, +252,180,198,214, 26,131, 37, 21,138,156,119,109,155,154,113,241, 74, 82,227, 19,167, 83,163,134, 12,138, 18,136, 36, 33,129, 0, + 48,107,230,219,210, 3,135, 78,255,216, 59,170,126, 78,231,142,193, 25,163,198,174,243,173,139,185, 10, 8, 8, 56,127,226,196, + 9,119,169, 84,138,146,146, 18,231,141, 27, 55,174,108,219,182,173,224,241,227,199,120,240,224, 1, 82, 82, 82,160, 86,171,209, +166, 77, 27,219,132,132,132,181, 0,170, 53, 88, 5,250, 97, 75, 2,220, 10,191,243,118,118,106, 96, 48,171,221, 56,182,168,201, +217,211,119,155,237,219,163,139,112,243,240, 9, 30, 61,122, 50, 62,153,187, 92,252,251,190,205,243, 47, 92, 60, 9,160, 65,245, + 51,248, 19,116,248,116,222, 92,148,106,140, 24, 59,230,109,140, 27,243,182, 51,129,201,147,112, 6, 27,147,190,196,209, 65, 18, +127,100,243,206, 61, 67, 1,248, 84, 50, 89,103,168,201,170,158, 47, 68,162,182, 3,126,248,193, 53,252,173,183,100,119, 23, 45, +210, 22, 94,188,168, 15,234,215,175, 36, 98,234, 84, 35, 0,104, 82, 82, 36, 15, 23, 44, 80,186,118,238,172,104, 63,123,182, 19, +103, 50,121, 44,102,152, 54,159, 19,114,163,174,154, 13,198,140,225, 86,236,223,223,250,218,178,101, 93,177,120,177,176, 91, 68, + 68,204,188,159,126,202,250, 43,154, 47, 51,157,217, 23, 46, 24,181,141, 27,163,233,240,225, 69,222,206,206,198,151,153,247,191, +146, 78, 74, 21,117, 72,117, 65,146,144,144,144,188,196,196, 68,183,253,251,247,215,106,174,196, 98, 49, 60, 61, 61, 17, 25, 25, +153, 31, 27, 27,235, 94,195, 67, 49, 35, 35, 35,195,135,101, 89, 72,165,210, 26, 19,166,209,104, 16, 27, 27,139, 81,163, 70,101, +102,103,103, 87,251,224,173, 87,175,158,157,147,147,211,147,115,231,206,185,196,199,199,227,214,173, 91, 8, 8, 8,128,147,147, + 19,196, 98, 49, 44, 22, 11, 74, 75, 75, 17, 18, 18, 2,133, 66,129,126,253,250, 21, 22, 23, 23, 7, 20, 23, 23, 87,251, 32,171, + 95,191,190, 76, 44, 22, 39,237,219,183,207, 55, 60, 60, 28, 55,110,220,128,175,175, 47, 60, 60, 60, 0, 0, 41, 41, 41,184,124, +249, 50,250,245,235,135,184,184, 56, 76,157, 58, 53,195, 98,177, 4,167,166,166, 26,171,109, 50,104,210, 36,103,207,158, 61,153, +161,161,161, 6,173, 86, 43,200,203,203, 19, 95,188,120,145,213,104, 52,182,106,181, 90,172, 82,169,196,165,165,165, 34,173, 86, + 43, 22, 8, 4, 18,163,209, 40,190,118,237,154,176,168,168,200,190,166,235, 20, 26, 26,154,247,224,193, 3,183, 67,135, 14,161, +105,211,166,216,191,127, 63,102,205,154,133, 43, 87,174,192,215,215, 23,123,246,236,193,236,217,179,145,152,152, 8, 23, 23, 23, +116,239,222,189,198,239, 8, 0,130,130,130, 30,197,198,198, 6, 74, 36, 18, 60,121,242, 4,153,153,153,229,235,217,161,160,160, + 0,143, 31, 63, 70, 86, 86, 22,130,130,130, 48,102,204,152,199,153,153,153, 65,181, 21,180,150, 45, 91, 22,156, 57,115,198,165, + 89,179,102,200,203,203,131,163,163, 35, 28, 28, 28,224,232,232, 88,241, 57, 32, 32, 0, 51,103,206, 68,179,102,205,242, 83, 83, + 83,221,107, 51, 63, 77,155, 54, 61,113,230,204, 25, 23,123,123,123,228,230,230,162,180,180, 20, 34,145, 8, 74,165, 18, 46, 46, + 46,144,203,229, 0,128,164,164, 36,244,239,223,191,240,201,147, 39,189,173, 53, 71, 12,195, 8,220,221,221, 31,220,187,119, 47, +152, 16,130,244,244,116, 36, 38, 38,226,157,119,222, 73, 50, 24, 12,161,175,210,154,122,149,250, 85, 73, 38, 76,156, 44, 25, 50, +104,176, 46,230,214,113, 94,129, 11,104,211, 66,161, 2,128, 27, 49,122, 71, 61,186,160, 69,171, 62,130, 3,135, 14, 42, 55,111, +250, 69, 12, 30,238, 96,144,152,240,144, 44,174, 78,123, 64,111,199,241,179, 63,232,211,184,115,199,206,162,210, 82,226,241,235, +150,245,109,210,146,159,184, 3,128,127,195,128,188, 73,227,223,190, 97,111,207,228, 94,188,114,145, 93,177,230,248,253, 35, 39, + 84, 91,172,136, 44, 7,248,249,249, 69,255,246,219,111, 46,174,174,174,112,112,112,128, 86,171,133,217,108, 70, 66, 66,130, 97, +215,174, 93, 22,123,123,123,187,220,220, 92,168, 84, 42,136, 68, 34, 68, 71, 71,167,231,230,230,250, 63,175, 85,222, 7, 11, 0, +222,233,219, 88,220,164,123,176,147, 68,198, 42, 20,226,135,158, 96, 56, 25, 67,108,221,207,158,141,110,118,238,194,165,215,251, + 13, 24,229,218,190,125, 55, 44, 95,250,137, 37, 61, 55, 47, 66,165, 27,244,160,170, 62, 88,141,131,153,238, 67,134, 15, 29,249, +197, 23, 11,177,112,254, 34, 28, 57,116, 64,109,107, 35, 48,218, 59,138, 29, 58,183,235,104,152,249,238,224, 12, 93, 89,166,239, +202, 31,215,143,233,217,123,164, 79,187,246, 93,113, 45,250, 60,246,236,222,112, 75,194, 89,104,115,225,115, 44, 98, 24, 39,199, +128,128, 41,239, 39, 37, 73,238, 46, 92, 88,198,102,103,151,180,154, 49,163,176,170,125, 51, 79,157,178,145,122,121,217, 59, 13, + 26, 84,111,141,191, 63,177,228,231,255, 92, 85, 31,162,170, 52,111,120,122, 58,254,126,238, 92, 15, 94, 36,234,242,238,244,233, +138,168,168, 40,148,150,150,226,200,145, 35,216,177,125,187,209,195,221, 61,214,241,230,205, 59, 1, 57, 57,159, 89,171,217,106, +198,140, 66,142,227,152,169, 75,151,246,124,152,145,209, 61,191,168,168, 62, 0,184, 57, 56,100,132,251,248,220, 90,181,109, 91, +226,247, 13, 26,240,214,166,115,215,149, 43,238,199, 10, 10,222,114,116,116, 84, 20, 20, 22,138,100, 82,105, 81, 68, 80,208,158, +175,166, 79, 63,111,186,115, 71, 34,247,241,177,119, 24, 48,160,206,121,111, 53, 99, 70,161, 90,167, 19,205,251,238,187,142,217, + 69, 69,245,181, 38, 83,144,186,172,204,131, 53,155, 5,118, 10, 69,145,127, 80, 80,190,230,204,153, 28,255,178,178, 15, 86,107, +181,249,180, 84,254,197, 8, 22,195, 48, 32,132, 88, 21,189, 18,139,197,127,234,163, 85, 3, 18,161, 80,136, 27, 55,110, 32, 63, + 63, 31, 77,155, 54, 69,131, 6, 13,254,180,195,147, 39, 79,112,244,232, 81,168, 84, 42,180,108,217, 18, 0, 36, 53, 9,218,217, +217,125, 56,119,238, 92, 71,163,209,136, 91,183,110,161, 85,171, 86,144,201,100,144, 72, 36,127, 50,127,249,249,249, 8, 11, 11, +195,212,169, 83, 29,190,255,254,251, 15, 81,195, 26,114,132,144,233,163, 71,143,118, 11, 15, 15, 7, 0,100,100,100,148,167, 5, + 0,224,234,234,138,152,152, 24,180,106,213, 10,238,238,238,232,219,183,175,219,193,131, 7,167, 3, 88, 81,109,198, 37, 18, 65, +104,104,104,235,103, 17, 34, 8, 4,130,135,246,246,246,174,238,238,238, 54,246,246,246,255,150,199,141, 27, 55,170,164, 82,169, +197,154,139,154,155,155,139,240,240,112,168,213,106, 0,128, 86,171, 69, 80, 80, 16, 74, 75,159,118, 57, 51, 26,141,240,242,242, +130, 94, 95,115,215,174,230,205,155, 47, 12, 13, 13,237,213,181,107, 87,153, 88, 44,198,221,187,119, 17, 17, 17,129, 93,187,118, +193,207,207, 15, 74,165, 18, 73, 73, 73,104,218,180, 41, 46, 92,184, 0, 87, 87, 87,132,133,133,201, 90,182,108,121,169,184,184, +248, 92,106,106,234,194, 26, 34,109, 2, 91, 91, 91, 92,184,112, 1,191,253,246, 27, 82, 82, 82,144,157,157, 13, 59, 59, 59,180, +104,209, 2, 77,154, 52, 65,135, 14, 29,144,148,148, 4,166,150,194,196, 48,140, 71,112,112,240,145, 27, 55,110,184, 16, 66,176, +117,235, 86,148,149,149,193,100, 50, 65, 32, 16, 64, 46,151,195,201,201, 9,221,187,119,135,171,171, 43,130,131,131,177,123,247, +110,151,190,125,251, 30,125, 22,129,202,173,237,154, 58, 57, 57,125,176, 96,193, 2, 95, 55, 55, 55,164,166,166, 66,173, 86,195, +221,221, 29, 93,187,118,245, 62,125,250,244, 7, 0, 86,189, 42, 15,129,242, 14,237, 12,195, 48,135, 15,237, 28,236,231, 41,109, +220, 38, 66,227, 31,123, 91, 20,120,244,244,163,102, 79,175,135,255,189, 54, 45, 53,143,111,220, 58,158,118,248,208,206,235,247, + 31,226,160, 53, 77,216,133,106,193,193, 19,167, 83,163,154,133, 69, 10,191,251,113,193,224,201,147,122,203,234, 57, 69, 50,165, +249,187,113,229,122,172,255,231, 11,231,184, 45, 94,184,236,240,137,211,169, 92,161, 90,176,196,154,244, 6, 6,212,251,126,223, +122,145,139,198,244, 35, 98,174, 59, 0,226,246,104, 24,208, 8,165,165,165,144,203,229,242, 49, 99,198,112,115,231,206,213,217, +219,219, 43, 69, 34, 17, 98, 98, 98,242, 5, 2, 65,239,218,116, 13,110, 78,132, 51, 91, 88, 34, 21,242,132,177,211, 51, 92,177, + 52, 46, 33, 25, 93,186,244,205,107,221, 42, 98,233,178,111, 86,125, 26, 16, 16,226, 58,102,236, 20,241,138, 21,159,173, 3, 16, + 89,149,206,253, 36,114,182, 73, 32,163, 0,208,255,139,197, 11,241,228, 73,146,211,228, 55, 84,139, 68, 50,133, 87,168,127, 71, +187,117,191,157,235, 19, 20,212,160,254,228,137,111,254,241,203,198,223,250, 87,142,100,237,220,241,203, 65,134, 97,122, 88,115, +109,255, 65, 52, 27,119,228, 8,202,210,211, 45,197,151, 46, 25,122,252,240, 67, 97,203,241,227, 87, 89, 88,214,165,188,174, 42, +255,201, 48, 12,192,243,140,104,197, 10, 1,241,242,130,197,209,241,141, 57, 64,163,218, 52,151, 89, 44,195,134,180,104,209,255, +215,109,219,224,239,239, 95,161,233,224,224,128,233,211,167, 99,218,180,105,178,123,247,238,181, 57,122,244,104,155, 45, 63,254, +232, 62, 7, 24,102, 77, 58, 47,222,189,235,244,241,154, 53,243, 26,135,135,251,173,254,225, 7, 89,121,125,151,154,154, 26,252, +195,247,223,251,119,143,138,202,251,228,227,143, 55,221,153, 53, 43, 12, 79,151,100,171, 86, 51,247,226, 69,211,177,226,226,183, +246,236,221,235, 24, 18,242,180, 27,228,227,199,143,221,126,253,245,215,183,187,191,251,238,216, 89,163, 71,127,214,253,209, 35, +149,125, 65,129,108,192,247,223,139,118,142, 28, 89,171,102,121, 58, 1, 96,248,236,217, 31,182,237,216,177, 73,223, 49, 99,234, +121,121,121, 49, 10,133, 2,102,179, 25,121,121,121, 78,137,137,137,129,167, 85,170,210,147, 49, 49, 91,241,108, 17,119,202, 95, + 48, 88, 0,192,113,156, 85,230, 74, 36, 18,253,171,112, 91,115, 82,145, 8, 94, 94, 94, 40, 44, 44, 68, 92, 92, 28,252,253,253, + 97,177, 88,112,226,196, 9,168,213,106,136,197, 98, 72, 36, 18,152,205,181,175, 13,107, 99, 99, 19,213,185,115,103,209,213,171, + 87, 17, 16, 16, 0,133, 66, 81,145,174,242, 77, 34,145,192,211,211, 19,165,165,165,136,140,140, 20,111,220,184, 49,170, 38,131, +101,107,107,219,111,240,224,193, 21, 33,182,178,178, 50, 8,133,194, 10,179, 82, 86, 86,134,226,226, 98,168, 84, 42, 24, 12, 6, + 52,107,214, 76,122,246,236,217,126, 53, 25,172,202,232,116,186,178,252,252,124,199,200,200, 72,167, 77,155, 54, 37,182,111,223, + 62,164,242,255,207,159, 63,111, 48, 24, 12, 98,169, 84, 90,235, 58,119, 12,195, 96,219,182,109, 21,215, 62, 43, 43, 11,235,214, +173,171,248,127, 82, 82, 18,190,251,238,187,138,121, 57,106,250,142, 66, 67, 67,251,110,221,186,181,213,150, 45, 91, 74,132, 66, + 33, 18, 19, 19,177,125,251,118, 16, 66,224,234,234, 10,157, 78,135,188,188, 60,156, 59,119, 14, 44,203,194,214,214, 22,222,222, +222,242,233,211,167,119, 90,180,104,145, 24,192,194, 26,202, 18, 39, 20, 10,225,239,239,143,249,243,231,195, 96, 48, 64, 34,121, +234, 43, 75, 75, 75,161, 82,169,112,231,206, 29,164,166,166,162,182,202, 69, 46,151,143,216,178,101,139,155, 84, 42,133, 94,175, +135, 70,163, 65, 70, 70, 6,210,210,210, 12,249,249,249,172,157,157,157,192,223,223, 95, 32,147,201,100, 67,134, 12, 97,202,141, +230,128, 1, 3,156,183,110,221, 58,170, 54,115,196, 48,140,107,227,198,141, 63,125,251,237,183,229,149, 76, 55,114,115,115, 49, +108,216, 48,229,213,171, 87,231, 50, 12,179,157, 16, 82,240, 42, 61, 12, 8, 33,164,172,236,151,203, 23, 15,254,208, 56,246,182, + 40,208,100, 42,105,223,179,223, 7, 34, 0,184,122, 97, 99,251,216,219,113, 80, 48,108,218,177,147, 43, 46,219,218, 78, 38,181, + 69, 0,251,245,112,236,227,231, 38, 29, 58,100, 80,148,224,215, 45,235,219, 76,158,212, 91,230,214,112, 61, 3, 0, 78, 18, 31, +116,224,102, 9, 12, 70,173,252,215, 45,235,219, 12, 25,212,239,122, 74,114,218,170,254, 81, 78,191, 31, 61,163, 58, 94, 83,132, +208,211, 77,228,237,100, 87, 8, 39,187, 8,248, 7,216,225, 78,204, 61, 28,220,127, 9,193,161,157, 96, 52, 26,193,178,172,205, +192,129, 3,117,123,246,236, 49, 20, 21, 21,105,204,102,115,151,236,236,236,135,181,229, 63, 51, 51,129, 15,241,104,103,150, 40, +100,172, 70, 45,209,205,249,108,239,200,150,109,123,181,114,242,244, 22,187,218,240,135,187,117,137,220,190, 99,219,207, 51,102, +125,180, 24, 45, 90,180,111,127,255,209,177, 38, 0, 98,171, 52,173,143,201,145,240, 96,134,125,242,232, 81,255,180,212,212,204, + 70,238, 30,166,199, 42, 98,249, 96,206,250,158,145, 93, 70, 52, 11,108,220, 89, 26,159,112,129,153,249,238,219, 59, 86,254,184, +126, 76,185,201,186,120,241, 68,151,133, 11, 83,165, 0,140,180,122,122,246,114, 42,147,249,216,250,251,139, 82, 54,109,210, 7, + 12, 28, 88, 2, 0, 22,150,117,137,190,118,205, 65,169, 84,130, 16, 2,139,197,242,167, 62,194,229,253,130,163,186,118,117,183, + 70, 51,227,167,159,154,189,251,238,187,200,205,205, 5,203,178, 16,139,197,207, 63,179,161,209,104, 48,124,248,112,108, 92,187, +182,157, 53,154, 28,199, 49, 31,175, 89, 51,111,250, 7, 31, 4,142, 29, 59, 86, 80,249,217,235,232,232,136, 95,214,175,151,110, +218,180,201,103,249,111,191,189,209, 83, 38,123, 82,155,166, 38, 44, 12,142,177,177,138,114,115, 5, 0,129,129,129, 88,182,108, +153,108,244,232,209,210, 9, 19, 38,124, 27, 31, 18,178,102, 97, 90,218, 35,231, 70,141,236,165, 50,153,143,181,215, 19, 0,202, + 76,166,240, 5, 95,124,225,116,253,250,117,100,103,103,151,207,117, 5,134, 97,208,180,105, 83,102,228,200,145, 14,237, 90,181, +106, 67, 75,228, 75,138, 96,113, 28,247, 39,163, 82,155,193,170,115,251, 36,195,192,211,211, 19,102,179, 25, 27, 54,108,128, 68, + 34,169,168,116, 1,192,100, 50,213,170, 97, 48, 24,154,122,120,120, 64,173, 86,163, 81,163, 70,127,138, 92, 73, 36, 18,136, 68, + 34, 72, 36, 18,200,100, 50, 24,141, 70,120,123,123,195, 96, 48, 52,173,197, 0,181,176,183,183,175,168, 88,141, 70, 99,133,185, + 82,169, 84, 80,169, 84, 48,153, 76, 40, 41, 41, 65, 89, 89, 25, 84, 42, 21, 52, 26, 77,132, 53,121,230,121, 30,113,113,113,143, + 67, 66, 66, 90, 8,133, 66,216,218,218,218,104,181,218,138,190, 67,197,197,197,216,188,121,179,118,252,248,241, 46,215,175, 95, +183,106, 33,225,247,222,123, 15, 50,153, 12, 58,157, 14,107,215,174,197,251,239,191, 15,137, 68, 2,141, 70,131,117,235,214, 97, +230,204,153, 16,137, 68, 48,153, 76,216,181,107, 87,245,145,140,132,132,148,107,215,174, 69,180,108,217,210,233,247,223,127, 47, +232,217,179,167,107,239,222,189,161, 80, 40,160,215,235, 97,177, 88,208,174, 93, 59,132,134,134, 34, 63, 63, 31,199,142, 29, 43, + 12, 14, 14,118,185,126,253, 58,159,155,155,155, 86, 91,229, 93,217, 96,115, 28,135,188,188, 60,168, 84, 42, 20, 20, 20, 32, 59, + 59, 27,153,153,153, 16,137, 68,168,237,229,221,217,217,121,120,120,120,184, 16, 0, 20, 10, 5, 90,180,104,129,121,243,230,177, +122,189,254, 53, 0,199,158,237,214,119,253,250,245,191, 95,190,124, 89,228,229,229,133, 7, 15, 30,192,213,213, 85, 36,151,203, +107, 53, 88, 30, 30, 30, 27, 15, 31, 62, 92,175,220, 84,151,151, 85,157,238,233,215, 49,108,216,176,122, 91,182,108,217, 8,160, +223,171,246, 64,176, 21, 56,138,218,180, 80,168,142,158,126,212,172,103,191, 15, 68,158,129, 11, 0, 0, 29, 0,209,169,163,107, +154,245,139, 10,218, 83,222, 47,171, 38,134,244,117, 93, 49,112, 96,115,193,216,145,173,158,136, 36, 33,129,219,182,172,113,175, +231, 20,249,175,135,132,176, 30,108, 20, 64,104, 32, 39,136,222,249,196,125,230, 7, 33,166,237,155,222,122,178,109,207,173, 40, +137,228,110,119, 0, 51,171,211,142, 79,180, 28, 82,107,235, 53,118,144,156,103, 32, 31,132,136, 22,193,112,117, 85, 97,237, 47, + 91,224,237,215, 17, 70,163, 17,246,246,246, 74, 0,102,179,217,188,205, 26,115, 5, 0,103,206,168,248,176, 48,149, 73,168,225, +217,119,223, 95, 49,180,103,223, 65, 77,186,119,143,226, 79,158, 58,105,238, 24, 97,206,233,222,189,125,222,185,243, 23,147,114, +115,179,130, 67, 67,155,225, 97, 98, 76, 31,128,137, 3,170, 46,176,113, 73,228,120, 96, 32,115,110,215,174,201,188,158,191,163, +248,114, 73,108,223,254,253, 39,132,119,142,236,204,159, 58,125,214, 36, 69,225,125,219, 78, 29,178, 38,140,126,237,247, 93,251, +127,239,117,238,236,145, 32,117,105,222,145,111,126, 36,212, 92, 85,126, 57, 99, 89,119,145, 76, 38, 40, 56,119,142,109, 58,105, + 82,197,181, 81, 42,149, 56,120,240, 32,164, 82,105,197, 38,145, 72, 42, 62,187,187,187,131, 33, 68, 80, 23,205,156,156, 28,228, +230,230,194,193,193, 1,174,174,174,200,205,205,197,213,171, 87,241,240,225, 67,136,197, 98,244,233,211, 7,130,106,234,205,231, + 53,167, 46, 93,218,179, 81,227,198,126,207,155, 43, 60, 45,152, 40, 46, 46, 70, 84, 84,148,224,204,153, 51, 30,209,143, 30, 13, + 2,176,173, 70,205, 65,131,138, 10,206,156,169,242,220,225,225,225,204,193,131, 7,101, 99, 70,143,158,177,232,251,239,127, 92, +242,195, 15, 25, 28,203,122,212, 37,239, 12,195, 8, 24,134,129,175,175, 47,138,139,139, 81, 86, 86, 86, 30,112,128,147,147, 19, + 44, 22, 11,120,158, 23,211, 18,105, 61,130,218,204,128, 53,230, 74, 44, 22, 67, 32, 16,188,144,201,170, 28, 33,120, 30,107, 12, + 86,121,229, 39,151,203,255,116,131,149,155,181,202,159,203,223,118,172, 64, 88, 90, 90,138,125,251,246, 85, 20, 52,147,201, 4, +181, 90, 13,149, 74, 5,181, 90, 13,131,193,128,148,148, 20,236,220,185, 19,217,217,217, 16, 10,133, 86, 77,218,250,228,201,147, + 91, 13, 26, 52,104, 81, 94,121,119,235,214,205,231,226,197,139,217,229,215,224,179,207, 62, 43,108,215,174,157, 75,229,202,189, +214,196, 10,133,184,122,245, 42,244,122, 61, 8, 33,144, 72, 36, 72, 76, 76, 4,203,178,224,121, 30, 34,145, 8, 5, 5, 5,181, + 70,176,226,226,226, 38,190,249,230,155,171, 39, 77,154,116,238,227,143, 63, 62,213,173, 91,183, 12,134, 97, 96, 54,155, 97,111, +111, 15, 15, 15, 15, 36, 38, 38,194, 96, 48,224,195, 15, 63, 76,223,178,101,203,233,181,107,215,158,219,176, 97,195,234,204,204, +204, 55,235,242,125,179, 44, 11,173, 86,139,146,146, 18, 20, 23, 23,163,180,180, 20, 6,131,225,133,202, 80,100,100, 36,142, 28, + 57, 34,236,209,163,199,175,254,254,254,185,254,254,254,185, 61,122,244,248,245,208,161, 67, 66,111,111,111,164,166,166,226,214, +173, 91, 40, 41, 41, 1, 33,164,198, 19,136,197,226,110,227,199,143,239,228,231,231,199,152,205,102, 24,141, 70, 24,141, 70,152, +205,102,240, 60,143,212,212, 84, 52,110,220, 88,224,239,239,223,158, 97,152,110,244, 17, 98, 61,165,249,187, 65,116, 63,128, 24, +119,130, 47,253, 17,218, 23,156,140,164,164,164,100,201, 59,115,212,249,156, 49, 6, 9,177,231,161,209,121,195,167,225, 68,188, +253,102, 55,220,184,118, 18,197,197,197, 72, 72, 72, 64,151, 46, 93, 36, 12,195,212,169, 92,158, 58,117,141,123,109,220,251, 35, +186,245, 26,212, 42, 42,170, 31,123,226,196,105,211,237,155, 39,110, 5, 5, 58,229, 19,190, 44,207,209, 81,121,231,209,163,251, + 8,110,212, 4,102,139, 37, 18, 88, 88, 99,121,122,252,152,152,254,248,195,147,123,109, 82,220,184,222,125,222,104,222,163, 71, +111,203,137, 83,135,185, 75,231,246,222,233,221, 59,240,194, 87,107,118,251, 22,155, 66,195,228,246, 30, 71,219,119, 82, 70, 78, +125,221,111, 50, 45, 41,213, 68, 3,228,114, 30,207,158,139,229, 93, 88, 42,155,171,231, 55,107,234,164,202,154,149,235, 34,149, + 74,133,164,164, 36,124,243,205, 55,136,137,137, 1,199, 61,237,106, 87, 91, 55,139,202,154,137,233,233,221,223,127,255,125, 89, + 85,230,170,168,168, 8,133,133,133,200,202,202,194,128, 1, 3, 36,197, 78, 78, 45,107,211,244,118,115, 51, 42,229,242,188,135, + 15, 31,254, 91,122, 75, 75, 75, 33,149, 74,241,253, 15, 63, 72, 78, 60,120,240,206,137,179,103, 93,234,114, 61, 43,215,165,110, +110,110, 8, 12, 12, 68, 68, 68, 4,154, 54,109, 10,185, 92,142,248,248,120,252,252,243,207, 16, 50, 12, 75, 75,226, 75,138, 96, +213,197, 96,213,197, 16, 88,139, 53, 77,132,114,185, 60, 54, 47, 47,175,163,183,183, 55, 88,150,173, 48, 83,207, 55, 17,150, 71, + 59,238,223,191, 15,185, 92, 30, 91,147,166, 82,169,140, 21, 10,133,237,219,180,105,131,253,251,247,227,220,185,115, 72, 78, 78, +134, 78,167,131,209,104,132, 94,175, 71,124,124, 60,120,158, 71,120,120, 56, 28, 28, 28,160, 84, 42, 99,107, 75,171, 86,171,205, + 17,139,197, 33, 10,133,226, 95,205, 29,158,158, 40, 42, 42,226, 45, 22, 11, 54,111,222, 92,234,225,225, 97,163, 80, 40, 80, 62, +255,152, 53,230, 50, 63, 63, 31, 62, 62, 62, 21,125,176, 52, 26, 13,220,220,220, 96, 54,155, 43, 34,112,118,118,118,181,154, 75, + 66,136, 1,192,172, 74,218,173, 71,142, 28,185, 99,215,174, 93, 13, 79,159, 62,141,235,215,175,195,213,213, 21, 75,151, 46, 77, + 78, 77, 77, 29, 67, 8,185,249,178,191,115,107, 12, 86, 81, 81,209,190,216,216,216,246,109,218,180,169, 40,116,221,186,117, 99, +186,117,235,230, 82, 57,164, 95, 80, 80,128, 27, 55,110,224,244,233,211, 96, 24, 6, 73, 73, 73,156, 94,175,223, 81,195,185, 37, +254,254,254,155,230,205,155,103,203,178,108, 69,217, 86, 40, 20,144,203,229,144, 72, 36, 16, 10,133, 72, 77, 77,197,224,193,131, + 29,126,248,225,135,141, 12,195, 4, 18, 66,204,175,202, 3,161,140, 87,177, 55, 98,244,142, 78, 78,254,247,174, 94,216,216,190, +195,179,103,196,213, 11, 27, 89, 39, 39,255,123, 55, 98,244,142,157,125, 85,172,109, 45, 58, 7,142, 21,204, 54,155,111,246, 57, +126, 44,118,232,172,153,111, 75,253, 27, 6,228, 93,185, 30,235,223,129,155, 37,176, 81, 0, 90, 61, 80,172, 2, 30, 60, 22,242, +254, 13, 3,242,110,222, 78,148,126,187,114, 67,128, 78,111,250,253,232, 25,213,241,154,180, 51, 51, 51, 13,222,222,222, 67,102, + 45, 82, 94, 24, 61,198, 77, 42,145,251, 66, 83,114, 27,245,253,157,241,218,240, 16,252,248,203,109,216,219,215,123, 26,193, 96, + 24, 27,107,243, 94, 88, 88,200,236,219,121,105,210,248, 55,222,110,215,187, 87,127,246,248,137, 63, 68,231, 78, 30,186,186,241, +151, 79,127, 39, 66,173,146, 33, 26,133,175,159,207,189,148,228,135, 99, 58,119,238, 5,133, 84, 25, 4,132, 86, 89, 96, 43, 6, + 14, 16,164, 11, 4,144,143,127, 99,114,135,222,189, 7,177, 39, 78, 28,192,137,163, 91,174, 45, 88, 80,255,104,114,214,118, 73, +244,205, 76,249,144, 17,211, 74,142, 28,187,111, 26, 62,176,193, 67, 47,155, 22,122, 90, 45, 61,247, 2, 41, 18,229,177, 70,163, +175, 79,239,222, 66, 93, 90,154,216,214,221,157, 5, 0,139,197,242,111,166,170,114, 4, 75, 32, 16, 0, 2, 1,111,141,166,181, +105,209,233,116,224, 1,214, 26,205,130,226,226,250,207,247, 49,182, 88, 44, 40, 42, 42,170,216, 84, 42, 21,228,114, 57, 74,158, + 77, 26, 90,155,102,231,102,205, 54,175,252,246,219,217,191,172, 95, 47,169,108,174,202, 55,129, 64,128,185,159,126, 42,153,255, +213, 87,211,134,137, 68, 31,212,229,122,150,191,172, 11,133, 66,136, 68, 34,164,165,165, 33, 61, 61, 29,105,105,105, 72, 75, 75, +131, 66,161, 0, 97, 24,158,150,200,151, 96,176,202,191, 60,107, 59,185, 91,107, 8,202,223, 4, 94,150,193,210,106,181,167, 47, + 95,190,220,182, 87,175, 94,162,107,215,174,193,195,195,163,194, 96,149,255, 44,111,118, 82, 42,149, 56,118,236,152, 89,171,213, +214,184,144,164, 94,175, 63,115,230,204,153, 86, 51,103,206, 20, 79,156, 56, 17, 9, 9, 9,152, 50,101, 10, 84, 42, 21, 74, 75, + 75, 81, 84, 84, 4,157, 78,135,182,109,219, 66, 46,151,227,209,163, 71, 22,189, 94, 95,219, 84, 5, 36, 63, 63,191,204,213,213, +213,243,249,127,140, 24, 49,194,253,167,159,126,210, 61,120,240,192,210,177, 99, 71,123,107,141, 70, 57, 59,119,238,172, 48, 79, + 15, 31, 62,196, 79, 63,253, 84,209,231,234,246,237,219, 88,177, 98, 69,197,220,101,117,140, 42,222, 12, 11, 11, 99, 45, 22, 11, +130,130,130,202,155, 87,177,122,245,106,246,239, 48, 87,214, 98, 48, 24,246, 78,152, 48,225,147, 59,119,238,120,138, 68,162,242, +208, 53,120,158,135,217,108,198,163, 71,143, 16, 31, 31,143, 7, 15, 30,160,184,184,184,226, 5, 32, 38, 38,166,196, 98,177,236, +174, 78,215,213,213,245,179,223,126,251,205, 67,169, 84,254,169, 60, 11, 4,130,138,135,142, 68, 34, 65, 65, 65, 1, 28, 29, 29, +209,163, 71, 15,183, 51,103,206,124, 6, 96,254,171,240, 48, 96, 24,134,233,216,206,182,211,123,211,222, 64,155,150,154,199,177, +183,227,112,234,232,154,102,192,211, 78,238, 77, 91,134, 63,190,113,199, 14,125,123,205,238,116,229,218,148, 26, 59,185, 63,235, + 67,117,180,109,219,122,151, 15, 28, 58,253,227,156,153,111,223,248,124,225, 28, 55,131, 81, 43, 15, 13,228, 4,192, 83,115, 21, +125,199,198,176,120,225,219, 55,150,173,220,204,167,231,155,103, 92,191, 94, 82,237,232,222,202,166,197,201, 22,114, 15,223, 25, +217,245, 3,186, 55,136,189,189, 1, 46, 14, 37,176, 11,234,136,190,189,219,226,244,153, 88,164,101, 25,144,159,159, 15, 0, 53, + 78,123,240,224,222,239,227, 8, 67,252, 24,194,164, 51, 2, 34, 31, 55,225,173,200,254,253, 7,145, 35, 71, 14,177, 7,126,223, +118,121,247,214,239,246, 10, 36, 98,145,222,228, 96, 98, 24,131,154, 23,216, 37,104,181, 69, 79, 31,158, 18, 73,245,203,221, 60, +155,144,181, 73, 88,168,199,184, 9, 83, 28,250,245, 29, 76,142, 30, 61,192,239,222,181,249,220,238, 13, 77,183,241,130, 82, 73, + 78,134, 78,166, 46,181,168, 9, 35,117, 44, 43,229,117,121, 79, 2, 13, 94,253, 71,152,105,181,244, 92, 61, 96, 52,102,150,101, +100,120,214,235,210, 69,246,104,225, 66,165,123,219,182,134,242, 46, 44, 53, 25, 44,161, 80, 8, 2,240,214,104, 90,155, 22,189, + 94, 15,194, 48,150, 23,209,100, 89,246, 79,230,170,220, 96, 61,123,214, 91,149,206,111, 62,252,240, 90,235, 55,222, 40,142,142, +142,118,111,223,190, 61,163,209,104,160,209,104,254,100,178, 92, 93, 93,153,134, 1, 1,202, 19, 57, 57, 1,243,173,188,158,214, +228, 93, 32, 16, 84,123, 61, 41, 47, 96,176,202, 35, 88,214, 24, 44,161, 80,104,141, 41,176, 88, 44, 22,184,185,185,161,176,176, +176,218, 10, 95, 32, 16, 64,161, 80, 64,171,213, 2, 64,141, 35,233, 52, 26,205,234,197,139, 23, 79,239,214,173,155, 75, 72, 72, + 8, 10, 10, 10,224,238,238, 14,185, 92, 94,209, 55,172, 92, 47, 46, 46, 14,187,118,237, 42,213,104, 52,171,107,201,247,170,117, +235,214,189,219,175, 95,191,122, 46, 46, 46,112,114,114,194,189,123,247,224,228,228,132,210,210, 82, 36, 38, 38,194,206,206, 14, + 12,195,192, 96, 48,224,226,197,139, 26,158,231, 87,213,114, 99,146, 43, 87,174,152,149, 74,229,189,130,130, 2, 97,113,113,177, +168,164,164, 68, 84, 90, 90, 42, 86,171,213,226,227,199,143,187, 56, 56, 56,232,206,158, 61, 91,224,231,231, 39, 76, 73, 73, 17, +154, 76, 38,129, 21,149, 34, 62,248,224, 3, 72, 36, 18, 24,141, 70,172, 94,189, 26,179,103,207,174,232,115,245,245,215, 95, 99, +222,188,121, 21, 33,245,195,135, 15,215,213,100,193,108, 54,195, 98,177,192, 98,177, 88,101,122,255, 10,214, 24,117, 66, 72, 46, +195, 48, 3,218,180,105,115,114,207,158, 61,206,118,118,118, 72, 77, 77, 69, 94, 94, 30,242,242,242, 80, 80, 80,128,178,178, 50, +176, 44, 11,111,111,111,228,229,229,225,192,129, 3,106,141, 70,211,187,166, 17,132, 66,161,112, 66,100,100,164,232,249, 52,148, +191,213,149,155,118,153, 76,134,236,236,108,116,235,214, 77,122,254,252,249, 9,255,235, 6,171,220,184, 52, 14,134,100,224,160, +209,146, 22,173,250,232,110,220, 58,158,166, 96,216,180,126, 81, 65,123,128,167,211, 52,220,184, 99,135, 22,173,250, 8, 6,230, +152,218,170, 74,126,105,209,164, 17, 99,174,105, 89, 29, 0,112,113,224, 7,247,142,170,159, 99,111,207,136, 22, 47, 92,118,248, +215, 45,235,219, 68,239,252,215, 52, 13,139, 23, 62,157,166,161,119, 84,125, 54,225,193,195,193, 0,182, 88,107, 90, 6, 12,232, +125,231,183,141,187,144,149,114,216,107,213, 23, 10, 41, 12, 37,128, 56, 4,145,237,236,113,243,199, 76,100,101,101,229,242, 60, + 95, 99, 51, 46, 97,136, 95,124, 66, 92,163,166, 97, 77, 60,198, 77,152,108, 63, 96,192, 96, 28, 57,114, 16, 91, 55,111,184, 56, +124,244,176, 95,179, 74, 74,133,110, 98,165, 68, 73,120,169, 80,226, 32,146, 43,149,249,230,236,236,167, 15, 79,145,216, 30, 24, +201, 3,213, 71,134,167, 78, 30,235,208, 61,106, 48,254, 56,122, 16, 91, 55,255,114,225,243,176, 17, 27, 26, 68, 52,102,218,182, +252,102, 90,131,134, 13,252,181,101,121,165, 2, 70,106, 54, 24,120,187,111, 54,167,174,124, 50,111,194,147, 59,113, 35,191,165, +163, 8,255,196,189,173,253,250,181,121,255,241, 99,137,107,167, 78,138,236,115,231,148,214, 24, 44,145, 72, 4, 8, 4,172, 53, +154,204,169, 83, 2, 0, 53, 14,174,146, 72, 36,208,233,116, 96, 25,198,108,141,166, 91, 76, 76, 70,106,106,106,176,163,163,227, +159,204, 85,113,113,113,197,103,131,193, 0,147,201, 4,133, 92, 30,111,141,102,222,197,139,134,121, 19, 39,206,127,247,157,119, +190,219,185,107,151,220,193,193, 1,106,181,250, 79, 6,203,100, 50,161, 77,219,182,146,141, 15, 30,140, 3,176,192,154,235,233, +222,173, 91,173,253,125,159, 25, 86,218, 68, 88,151,250,172,182,166, 26,107, 71, 17, 86, 85, 49, 50, 12, 19,245,220,239,243,250, +246,237,107, 72, 78, 78,134,159,159, 95,133, 73,169,124, 78,123,123,123, 56, 58, 58,226,193,131, 7,216,176, 97,131,158, 97,152, +121, 53,105, 22, 23, 23,107, 12, 6,195,168,209,163, 71,235, 37, 18, 9, 66, 67, 67, 43,230,191,226,121, 30, 82,169, 20, 54, 54, + 54,136,139,139,195,132, 9, 19,116, 6,131, 97,212,243,115, 96, 61,175,153,154,154,170,214,106,181,175,191,254,250,235,186,135, + 15, 31, 34, 50, 50, 18,119,239,222, 69, 89, 89, 25,202,202,202,144,146,146,130, 38, 77,154,192,100, 50, 97,239,222,189,122,173, + 86,251,122,106,106,170,186, 38, 77,141, 70, 51,112,249,242,229,194,163, 71,143, 54,240,241,241, 9,107,221,186,117, 72,143, 30, + 61, 2,135, 14, 29,234,223,175, 95, 63,207,224,224, 96, 67,239,222,189, 93,251,246,237,235, 42, 20, 10,197,143, 31, 63,206, 33, +132,244,173, 73,179,178, 41,121,248,240, 97, 69,147,160, 72, 36, 66, 97, 97, 97,197, 76,251,229, 15,163,170, 12,112,117,154,149, + 77,118,185,177, 42, 55, 90,181, 61,251,171,210,100, 24,166,214, 10, 67, 42,149,150, 71, 56, 73,109,154,132,144,152,251,247,239, +247,236,210,165, 75,204,164, 73,147, 52,185,185,185,176,179,179, 67, 64, 64, 0, 26, 53,106, 4, 23, 23, 23,152,205,102,252,254, +251,239,218, 3, 7, 14,196,170,213,234,110,207,207,129,245,188,166, 64, 32, 72,169,234,225, 90, 30,189, 42, 55, 88,114,185, 28, +222,222,222,229,215, 54,165, 46,215,243, 5, 35, 75,127,175,230, 51,227,210,163,123,239,134,253,250, 15,113, 56,112,232,160,242, +251,181,155,238,119, 30, 60,125,157,139,255,172,253, 46,254,179,246,119, 30, 60,125,221,247,107, 55,221, 63,112,232,160,178, 95, +255, 33, 14, 61,186,247,110,152, 16,255, 32,228, 79,235, 18, 86,145, 78,165, 84,214,182,115,199, 96,213,197, 43, 23,217,101, 43, + 55,115, 29, 59,244,187,254,221,119,235,118,127,247,221,186,221, 29, 59,244,187,190,108,229,102,238,226,149,139,108,231,142,193, + 42,165, 84,214,214,154,188, 79,157, 60,214,161,127,191,193, 56,114,228,119,118,199,214,213, 95, 31, 60, 97,234, 50, 98,178, 33, + 47, 45,229, 54,129,110, 19, 92,237, 99,145,158,158,174,102, 89,182, 91, 85, 29,220,171,210,156,242,246,216,202,230,234,146,179, + 71,228,250,251,247,193,157, 58,117,216,114,230,204, 29,253,165,152,124,245,173,132,194,226,162, 82, 67,178, 86, 83,106,226,121, + 30,132,231,132,139, 22,129,169,233, 59,234,216,177, 43,206,158,222,142,205,155,126, 86,243, 60, 12, 35,246,236,225, 70,142, 92, + 72,252,235,215,247,223,182,115, 59, 51, 96,208, 16, 7, 2,240, 3,135, 13,118,220,177,107, 7,211, 48,168, 97,253,128,128,167, + 83,211,252, 79,150,165,191, 65,115, 1, 33, 37,165,105,105, 23,110,255,240,131,209,125,212,168,122, 82,119,119,123,240, 60, 83, +254,124,175,110, 19,137, 68,127,138,184,212,164,233, 94,175, 94,214,137, 19, 39, 16, 18, 18, 2,111,111,239, 63,117,121, 41,159, + 72,219,197,197, 5,167, 78,157, 2, 1,110, 89,163,217,196,203,235,246,143, 63,252, 96,226,121, 30, 37, 37, 37,255, 22,189, 42, + 41, 41, 1,207,243,184,120,225,130, 73, 93, 86,182,217,218,188,183, 53,153,202,134,180,106,245,213,248,241,227,205, 41, 41, 41, +224,121, 30,149, 35, 89,249,249,249, 80, 42,149,208,233,245,190,238,238,238, 74,107, 52,243,143, 31,183, 65, 45,207,117,129, 64, +240,167, 38,194,191,227,123,255, 71, 69,176, 88,150,133,175,175,239,159,230, 25, 17, 8, 4,127,218,234, 50,130, 48, 43, 43,107, +139,187,187,251,137,113,227,198,205,111,209,162,197,212, 25, 51,102, 8, 27, 54,108, 8,181, 90, 13, 39, 39, 39,184,185,185, 33, + 37, 37, 5, 23, 46, 92,224, 84, 42,213, 58,142,227,190,200,203,203, 43,176, 66,247,156,183,183,247,128, 94,189,122,237,122,247, +221,119, 29,186,116,233, 34,246,242,242, 2, 0,196,199,199,227,216,177, 99,230, 29, 59,118,148, 26, 12,134, 81,214,204,226, 14, + 0, 57, 57, 57, 39, 61, 61, 61,135, 79,152, 48, 97,219,208,161, 67,237, 12, 6,131, 56, 37, 37, 5, 38,147, 9, 44,203,162,184, +184,216,124,225,194,133, 50,157, 78, 55, 54, 39, 39,231,164, 21,122,183, 25,134,105, 98, 54,155, 39,220,185,115,103,201,240,225, +195,157, 59,116,232, 32, 97, 89, 22,151, 47, 95, 46,136,136,136,112, 43, 45, 45, 53, 95,185,114,165,200, 96, 48,204,203,206,206, +182,106,169, 28,134, 97, 80, 90, 90, 10, 23, 23, 23, 24,141, 70,240, 60, 15,147,201, 4, 91, 91,219,138,229,141, 8, 33, 47,220, + 71,142,101, 89,161,217,108,198,232,209,163,193,243, 60, 86,175, 94, 13,150,101,235, 44,102,107,107,123, 43, 62, 62,126, 64, 88, + 88, 88,133,105, 41, 47, 67, 50,153, 12, 46, 46, 46,112,118,118,198,233,211,167, 33, 20, 10,111, 89, 25, 93,187, 11, 32,130, 97, +152, 14,177,177,177,227, 1,180, 48,155,205,222, 28,199, 49, 2,129, 32,135, 16,114,175,180,180,244, 87,107,151,202,201,207,207, + 95,242,198, 27,111, 68,108,223,190,221, 86, 36,250,215,173, 33, 18,137, 32,147,201,224,230,230, 6, 7, 7, 7, 16, 66, 96, 50, +153,240,217,103,159,149,106,181,218, 37,175,202,195,160, 85,235,182,248,229,167, 53,182,103,206,158, 40,184,159,132,131,149,167, + 98,176, 5,112,229,218,148,131,170,146, 95, 90,100,103,100,216,182,106,221,214, 42, 77, 19,199, 22,141, 26,187,206,247,217, 82, + 57, 75, 82,146,211, 86,109,223,244,214, 19, 0,248,118,229,134,128,244,124,243,140,132, 7, 15, 7,175, 93,119,190,173,137, 99, +139,172,209,252,151,105,217,166, 6,129, 33, 43, 43,235,186,143,143, 79,131,200,193,230,121, 33,129,204,160,188, 66, 62,139, 97, +152,247,178,178,178,158, 88,155,247, 78, 29,187,224,236,201, 29,216,186,121, 91, 41,225,133, 6, 23, 23, 23, 2, 0,247,239,187, +144,251,247, 85, 4, 40,159,175,209, 81,235,170, 44,248, 98,222,220,169, 51, 53, 26,205,170, 31,191,169,121,194,217,102,205,219, +161, 89,243,118,152,254,222,167, 14, 77,194, 66,253, 0, 96,207, 30,194,133, 7, 51,135,231,127,190,112,208, 23, 95, 44, 68,169, +198,136, 47,190,120,186,172, 78, 98, 92,194, 31,143, 31, 19, 19,173,154,254,204,124,150,189,142,153, 51,131,117,197,197,174,157, + 62,249,196, 69,244,205, 55,130,170, 58,185,151, 71,176, 42,223,191,214,104, 30, 63,115,230,143,143,102,206,204, 90,241,205, 55, +189,151, 45, 95,174,104,220,184, 49,114,115,115, 17, 26, 26, 10,111,111,111, 92,185,114, 5, 39,142, 30,213,150,233,245,243, 60, + 60, 60,214, 90,163,249,253,142, 29,137,157,187,119, 47,220,178,101,139, 87,247,238,221, 25,173, 86, 11,181, 90, 13,181, 90, 13, +163,209, 8,137, 68,130,172,172, 44,146,158,145,113, 63, 51, 51,115,157,181,121,231, 10, 10,228,179,210,211, 51, 69,155, 54, 45, +159, 50,121,242,236,153,179,102,201,124,124,124, 24,163,209, 88, 17,197, 50,155,205, 80, 42,149,102,141, 70,227, 12, 64,103,141, +166,236,240, 97,182,168,168, 8,206,206,206, 21,211, 46, 85,158, 87, 80,171,213,130, 16, 58, 9,110,157, 94, 20,170,171,195, 67, + 67, 67,111,137, 68, 34,159,202,209,172,234,126, 86,170,140, 51,227,226,226, 90, 85,118,184,132,144, 42,251, 59,249,248,248, 4, +240, 60,191,180, 67,135, 14,195,223,126,251,109,230,194,133, 11, 56,123,246, 44,201,204,204,220, 43, 16, 8,230,101,102,102, 62, +169,238,205,166, 58,205,122,245,234,217,217,217,217,125,104, 99, 99, 19, 85, 62, 21,131, 92, 46,143,213,106,181,167, 53, 26,205, +234,234,102,111,175, 73,179, 97,195,134,246, 60,207,127, 96, 99, 99,211,179,176,176,176, 5, 0,184,184,184,196,104,181,218, 83, + 2,129, 96, 77,117, 11, 72,215,164,233,229,229,165,176,181,181, 93, 82,175, 94,189,215,223,126,251,109,231, 11, 23, 46,228,196, +196,196, 72, 74, 75, 75,183,179, 44, 91,237, 98,207, 85,105, 54,105,210,228, 79,107, 17,190,204,239, 8, 0,154, 55,111,126,100, +224,192,129,253,199,142, 29, 11,139,197,130,181,107,215,226,212,169, 83,127, 36, 37, 37, 13,168,233,237,243,121, 77, 15, 15, 15, + 23,111,111,239,243,227,198,141,243, 31, 50,100,136,210,222,222, 30, 66,161, 16, 90,173, 22,201,201,201,184,119,239, 30, 57,117, +234, 84, 89,124,124,124,166, 94,175,239,154,155,155, 91,104,237,245,252, 43,111,201,207,107,138,197,226, 46,190,190,190, 59, 23, + 44, 88, 96,215,179,103, 79,133,179,179, 51,132, 66, 33, 44, 22, 11,114,114,114, 16, 23, 23,135, 19, 39, 78,104,247,238,221,171, + 45, 42, 42, 26, 77, 8,185,240,159, 72,231,203,212,108,210,136,249,252,185, 5,156,171,157,157,189,166,125,173, 73,103,255, 40, +167,126,195,135,183,142, 2,128,125,251,110,158,254,227,116,201,209, 23, 77,103,109,105,181, 70,179,113,176,112, 65,124, 66,220, +159, 38,162, 12,107, 18,254,176,113,211, 97, 95, 90,163, 85, 62,147,251,243,121,175, 52, 59,126,165, 55,130, 63, 55,167,150, 47, + 8,253,233,188,185, 88,186,228, 43, 28,220,243,251, 31, 9,143,201,145,255,229,178,244,119,106,150, 47, 78,172,244,244,236,188, +195,197,101,238,201,211,167,109, 43,191,168,149, 71,154, 43,191, 76,182,104,209, 34, 63, 38, 38,198,221, 26,205, 1,223,127,111, + 54,216,217,201,150,173, 91,215, 69,103, 50,117,153, 53,107,150,232,246,237,219,216,177,109, 27,171,207,200,216,150,203,113, 31, + 84,213,250, 81,147,102,224, 71, 31,201,151,110,223, 62,177,126,195,134,110,131, 7, 15, 22, 11,133, 66,104, 52, 26,100,103,103, +227,234,149, 43,166,228,148,148, 4,157, 78, 55, 40, 51, 51, 51,219, 90,205, 1,223,127,111,118, 12, 8,128,210,213,149, 92,137, +142,118,248,120,193,130,169, 30,158,158, 14,157, 34, 35,197, 74,165, 18, 37, 37, 37, 72, 79, 79,199,165, 75,151,242,159, 60,121, +226, 69, 8,225,172,209, 60, 20, 27,219,236,236,245,235, 35, 62,254,248, 99,105, 72, 72, 8,236,236,236,160,209,104,144,144,144, +128,171, 87,175, 26,119,238,220,169,214,106,181, 83, 51, 50, 50, 14,253, 93,223,251, 63,198, 96,253,127,221,120, 30, 30, 30,173, + 4, 2,193,231,207,154,163, 22,215,182,166,223,171,244,208,241,244,244,244,115,114,114,250, 69,175,215, 19,163,209, 56, 37, 39, + 39, 39,253,191, 45,157, 12,195,136, 90,181,106,245, 83,126,126,126, 7, 66, 8, 28, 28, 28,174,198,199,199,191, 67, 8, 97,235, +170,201, 48,140,208,195,195,163,131,141,141, 77, 91, 27, 27,155, 46,102,179,185,241,179,126,120,247,117, 58,221, 5,139,197,114, + 61, 55, 55,247, 42, 33,132,251, 79,230,157, 97, 24, 33,128,158, 94, 94, 94,111,241, 60, 31,196, 48,140, 35,199,113,176, 88, 44, + 42,158,231, 31,169,213,234, 13, 0, 78,253,167,211,249,178, 52,195,130,152,161, 68,128,198,213, 25,129, 63, 25,154,231,140, 3, +195,227,126,252, 35,242,187,181,233,100, 24, 70, 48,164,175,235, 10,224,233, 72,195,218,150, 28,250,147,193,178,194,180,212,217, + 92, 6,137,222, 32, 12,241,251,243, 67,145, 73, 15,109, 54,116,235, 95, 49, 88,214, 18, 22,194,116, 1, 65, 7,158,224,250,253, + 36,114,246, 85,125,214,189, 76,205,175, 24,166,222,158, 70,141,174, 10, 68, 34, 15,134, 97, 4, 0,192, 8, 4, 60, 15,112, 16, + 8,216,202,205,130,149, 95, 40,107,211, 52, 3, 77,197, 50,153, 47,199,178,238,197, 18,137,237, 21, 27,155,150, 70,160,204,131, +227, 62, 63, 93, 84,148,248, 34,233, 52, 3, 77,133, 50,153,223, 21, 59,187,193, 42, 39,167,102, 37,102,179, 43, 0,162, 80, 40, +238,151,233,116,155, 83, 83, 83,127,172, 98, 81,245, 90, 53, 37, 50,153, 15,247,108,228,161, 64, 36,202, 63, 33,147,249, 22,184, +186,142,215,233,245,254,114,185,220, 66, 8, 41, 53,155,205, 99,211,211,211,207,212, 37,239,233, 66, 97,147,123,118,118,145,156, +189,189,179,133, 97,108, 76, 28,103, 54, 91, 44, 25, 70,163, 49, 86, 40, 20,174,204,204,204,124,252,119,126,239,175, 28,229,163, +205,254,142, 13, 64, 20,213,164,154, 84,147,106, 82, 77,170, 73, 53,255,126, 77, 55, 55, 55,165,135,135,135, 31, 0,225,255, 98, +222, 95,181, 77, 68, 45, 38,133, 66,161, 80, 40,255,251,228,229,229,233, 80, 69,159, 43,202,127,168,137, 16, 64, 84, 53,145, 45, +171, 67,127, 47, 50,154,192,138,166, 4,170, 73, 53,169, 38,213,164,154, 84,147,106,190, 98,154,181,105,191, 50, 77,143,180,137, +144,106, 82, 77,170, 73, 53,169, 38,213,164,154,180,137,240,229,110, 2, 80,170,115,214,238, 12,195,184,191,236,125, 41,175,118, + 89,168,226, 88,111,134, 97,188,235,184,191, 39,189,234, 20, 10,133,242,191,205,255,123, 31,172,242,138,138, 16,146,247, 50,246, +123,217,199, 62, 59,254, 43,134,193,199,207, 62,127, 77, 8,153,251, 50,246,173, 13, 47, 47, 47,223,122,245,234,189,225,226,226, +210,177,168,168,232, 98, 78, 78,206,198,194,194,194,156, 58, 28, 31, 44,151,203,223, 17, 8, 4,225, 0,192,243,124,156,193, 96, +248, 41, 59, 59, 59,233, 37,124,111, 12,128,201, 50,153,236, 53, 39, 39,167,160,226,226,226, 71, 38,147,105, 15,128,159, 95,100, +214,105, 79, 79,207,150, 28,199,189,143,167, 35, 89,127, 46, 40, 40,184, 98,237,177,238,225, 67,118, 19, 32, 24,128,128,103,248, + 17, 2, 34,216, 11,128,103,128,164,188,184, 3,175,189,228,242,250,194,223,111, 93,143,101, 24,102, 37, 3,124, 8, 6,228,175, +150, 37, 10,133, 66,161,252, 15, 25, 44,111,111,239, 9, 0,102,227,233, 76,219,223,102,101,101,109,254, 59, 42,171,151, 88,169, +173, 38,132,204,170,123,180, 2, 31,243, 60, 17, 0,128, 64,192,124,226,238,238, 30, 46, 18,137,140,207,239,203,178,172,140, 97, +208,135,231, 9,243,108,223,143, 25,134, 89,243, 34,198,206,217,217,217,107,204,152, 49,219,190,248,226, 11,133, 82,169, 68,122, +122,250,144,185,115,231, 70,121,121,121,141,207,206,206,206,168,237,248,134, 13, 27,142,105,218,172,197,204,185,159,126,110,235, +234,230,102,195,178,156, 57, 35, 43, 83,249,205, 87,139,219, 54,108,216,112, 77,114,114,242,142,186, 24, 41,145, 72,244,154, 92, + 46, 15, 52, 24, 12,143, 89,150,221, 43, 20, 10,123, 47, 89,178, 36,188, 95,191,126,242,210,210, 82, 41,203,178, 65, 91,183,110, +157,249,219,111,191,245,101, 24,102,112, 77,195,237,203, 35, 56,132,144,172, 74,215,238,157,219,183,111,119, 23,139,197,204,179, + 69,155,175,212,180,127,101, 8, 16, 28,127,121, 79, 83, 0, 8,235, 52,242, 97,252,229, 61,120,246,249,165,191, 12, 60, 95, 22, +156,156,156,182,151,148,148, 36,212,102,228,171, 58,150, 97,152,239, 8, 33,185, 94, 94, 94, 29, 1,188,243,108,215,159,178,179, +179,175, 48, 12,227, 33,151,201, 62,212, 27, 12, 12, 0,230,175,148, 37, 10,133, 66,161,252,239, 69,176,230, 62,124,248,208,142, + 16,130,144,144,144, 57, 0,172, 54, 88,207, 87, 56, 66,161, 96, 78,207,158, 61, 39,202,100,178, 63, 85,204, 70,163, 81, 32, 16, + 48,110, 28,247,244,207,117,169,104,202,207, 97, 50, 25, 5, 98,177, 20, 66,161, 96,102,139, 22, 45,250,230,229,229, 29,147,201, +100, 95,167,164,164,228,191, 72,228,102,243,230,205, 17,206,206,206,255,102, 32,138,138,138, 4,125,251,246, 97,234,162, 55,145, + 97,100, 70,153,172,173,132, 97, 60, 57,150,117, 4, 0,145, 72, 84, 18,228,238,222,229,179,185,115, 21,207,116, 81, 86, 86,134, + 55,222,120, 67,249,232,209,163,177, 0,150,214, 18,185,106,212, 60,162,213,140, 29,219,183, 53, 46, 45, 46, 49,172, 95,245,243, +109,189, 72,162,107,208, 36, 84,178,248,171,149, 78,159,125, 50,243, 61, 47, 47,175,152,170,150, 13,121, 46,175, 2, 0,191,127, +248,225,135, 97, 3, 6, 12,144,106, 52, 26,185, 94,175,175,191,109,219,182,207, 90,181,106,101,219,162, 69, 11,233,206,157, 59, + 25,181, 90, 13, 66,136, 50, 52, 52,148,188,246,218,107,134, 93,187,118, 77, 7,240, 93, 93,204, 50,207,243,194,170,202,161, 53, +230,154, 1,146,194, 58,141, 4, 24, 4,197, 95,222, 35, 15,139, 28,105, 0,193, 35, 6, 72,122,246, 34,240, 5, 80,105, 94,167, + 63,115, 63, 43, 43,235,133,214, 14,236,223,127, 0, 67, 8,249,221,203,203,235, 76, 97, 97,161, 29,195, 96,116, 29,162, 83,140, +171,171,235,123, 0, 62, 37,132,124,120,238,220,185,246, 0,208,173, 91, 55, 9,128, 43, 14, 14, 14, 61, 76, 70, 35, 67, 31, 73, + 20, 10,133,242, 15, 52, 88,132, 16, 25, 0, 92,186,116, 9,132, 16,249,139, 4, 5, 42,255, 50,107,214, 44, 56, 59, 59, 63,111, + 90,112,246,236,153,106,143,169,235, 57,190,250,234, 43,199,252,252,252,209,191,254,250,235, 16, 15, 15,143,119,115,115,115,143, +215,146,199, 60,134, 97,190,126, 22,113, 96,228,114, 69,201,164, 73,147,174, 62,251, 95,227,195,135, 15,219, 13, 28, 56, 80,195, + 48,204,125, 0,144,203, 21, 93,132, 66,129, 19, 33,132, 16,130,175,107, 50,130, 35, 25, 38, 64, 42,149,118,159,242,253,247,108, +203,129, 3, 69, 54,174,174, 12, 0,164, 61,120,224,242,221, 15, 63,116, 86,101,100,200, 68,118,118,101,121, 37, 37,166,135, 15, + 31, 66, 46,151, 51, 2,129,160, 99,109, 25, 86, 42,149,239,207,154, 61,199,166,180, 88,165, 55,148,106, 76, 66,214, 98,180, 83, + 40,185,188,220,252, 34, 91,133,141,110,242,187,239, 75, 23,124, 58,251,253, 74, 81,147,234,152, 62,115,230,204,198,109,218,180, +241,222,189,123, 55,163, 86,171, 33, 18,137,108, 91,180,104,129, 86,173, 90,113,103,207,158,101, 26, 52,104,128,240,240,112, 92, +190,124, 25, 87,175, 94,101, 34, 34, 34,148,251,247,239, 31, 87,149,193,170,202, 84,143, 25, 51,102,162, 84, 42,229,187,116,233, +130,183,222,122, 11,132, 16, 68, 68, 68,116, 28, 55,110, 92,142, 94,175,183,202, 92,151, 55, 3,186,133, 15,185, 7,160, 41, 8, + 30,229,199, 29,104, 86,105,151,198,137,137,137,237, 74, 74, 74, 42, 58, 27,150, 47, 44,222,185,115,231,186,148,247, 60,134, 97, +190, 30, 56,112,192, 28,128, 65, 84, 84, 84,217,244,233,211, 73, 98, 98, 98,175, 33, 67, 6, 55, 72, 74,122, 84,109, 58,159, 47, + 71, 83,167, 78,211,138,197,226, 55,188,188,188, 18, 24,134, 17,139,197,226,242,107, 36,170, 95,191,190,123,211,166, 77,231,122, +122,122,234,132, 2,129,146,160,246,178, 68,161, 80, 40,148, 87,200, 96, 49, 12,147,125,247,238,221,250, 58,157, 14, 12,195,100, + 91, 81, 65,157,174, 92,225,136, 68,162, 95,132, 66,193, 20, 0,104,221,186,141,118,249,242,229, 85, 53, 43,241,173, 91,183,209, + 10,133, 2,155,167,149,151,240,103,150,101,243,170,210,172,166, 66,252, 70, 42,149,125, 4,128,241,241,241, 45, 59,120,240, 32, + 63,124,248,112,124,243,205, 55,178, 57,115,230,252, 88,191,126,253,110,169,169,169,105,213,165,243,217,239,115,221,221,221,195, + 55,111,222, 28, 49,105,210,164,171, 89, 89, 89,195,158, 69, 70,246, 3,104,199, 48,204,253,202,127,219,191,127,127,135, 9, 19, + 38,220,201,203,203,155, 91,157,230,112,134, 9,244, 15, 13,237,254,197,197,139, 68, 96, 52, 50,133,151, 46,149, 22, 23, 20,152, + 31, 23, 22,218,108,143,141, 29,253,241,162, 69, 18, 15,111,111, 92, 57,121,210, 46, 87,165,210,168,116, 58, 83, 74, 74, 10,207, +113,220, 25, 43,242, 30,230,234,226,162,252,121,229,218,155,118, 98, 33,239,230,227,205,136,235,213, 19, 9,148,246, 82,161, 72, + 96,108, 80, 63, 64, 10, 32,172,182,239, 72, 34,145,140,235,213,171,151,114,215,174, 93, 76,120,120, 56, 28, 29, 29,113,233,210, + 37,196,196,196,160,164,164, 68, 96,177, 88,208,186,117,107, 44, 95,190, 28,126,126,126, 80,169, 84, 72, 79, 79,119,145, 74,165, +174, 53, 92, 79,166, 82,249,193, 39,159,124, 2, 87, 87, 87, 88, 44, 22, 20, 23, 23,131,227, 56,216,216,216, 0, 0,114,115,115, +113,240,224,129, 90,203,146,149,230, 8,237,219,183,175, 48,194,149, 35, 88,117,209,244,246,246,190, 84, 80, 80, 56,178,123,247, +238, 40, 46, 46,102, 23, 46, 92,136,230,205,155,163, 81,163, 70,214,148,249,185, 50,153,236, 55,127,127,255, 77, 83,167, 78,173, +239,228,228, 4,163,209,184,162,168,168, 8, 31,127,252, 49, 0,160, 77,155, 54,173, 9, 33, 49,147, 38, 77, 66,253,250,245, 53, +185,185,185,133,247,238,221, 27,162, 82,169,238,189,104,222,173,188, 62, 84,147,106, 82, 77,170,249, 95,165,249,143, 54, 88, 0, +242,188,189,189,235, 43, 20, 10, 0,168,243,219, 53,203,178, 83,221,220,220, 4,159,125,246,217,192,134, 13, 27,242,211,167, 79, +191,146,146,146,242,167,142, 51, 13, 26, 52,216,243,195, 15, 63,116, 76, 78, 78,214,125,249,229,151,135,243,243,243,167,213,241, + 75,255,132, 97,152, 85, 0,144,145,145, 81,116,224,192,129,200,139, 23, 47,126,181,106,213, 42,159,233,211,167,203,166, 79,159, +254, 9,128, 90, 53, 69, 34,145,177,170,102,193,170,112,118,118,230,171,234,163, 85,206, 64,134, 81,216, 75,165,221,190,184,120, +145,152, 82, 83,117,187,126,252, 81,177,238,230,205,249, 22, 66, 60,221,221,221,133, 93, 58,117, 50,218, 73,165,154,188,236,108, +222,201,199,135, 73,126,252,216,214, 34, 20,154,143, 31, 63, 94, 86, 80, 80,176,205,138, 36,148,242,132,152,108,125,252, 44, 35, +134,244, 12,191,121, 61,230,129,157,155,139, 32,162, 69,120,179, 7, 15, 83,111,131,231,204, 0, 74,107, 19,113,112,112,104, 84, + 84, 84,132,210,210, 82,184,186,186, 98,245,234,213,240,240,240,128, 78,167, 67,124,124, 60,241,241,241, 97, 46, 94,188, 8, 31, + 31, 31, 20, 20, 20,192,100, 50, 65,163,209,228, 27,141, 70,125,117,134, 87, 36, 18,253, 38, 16, 48,147, 24,134, 65, 72, 72,168, +118,213,170, 85, 60, 33, 4,141, 27, 55,198,176, 97,195,176,111,223, 62,196,199,199,151, 71,154,248,192,192, 32,173, 64,192,216, + 0,224,255, 74, 20,135,231,121, 84, 54,194,117,197,203,203, 75, 1,224,227,224,224,224, 81,175,191,254, 58, 43,145, 72,160,213, +106,161,215,235, 17, 23, 23,199,246,239, 63,160,108,224,192, 1,182,127,252,241, 71,141,233, 52, 26,141,143,253,253,253,135,207, +152, 49,227,228,207, 63,255,236, 60,111,222, 60,240, 60, 95,177,177, 44, 91,177, 40,247,129, 3, 7,240,232,209,163,185,149,205, + 21,133, 66,161, 80,254, 25, 6,235, 47, 35, 22,139,191,248,227,143, 63,122, 45, 93,186, 84,220,163, 71,143,142, 94, 94, 94, 29, +178,179,179,175, 62,171,212, 58,244,235,215,175,163,155,155, 27,214,172, 89, 99, 18,139,197, 95,188,160,179,174, 92,217,157,243, +240,240,152,190,127,255,254, 67, 83,166, 76,129,167,167,103,219,255,239, 60,219,203,100, 17,147, 86,175,102,197, 22,139, 96,231, +207, 63,203,150,158, 57,179,122,215,238,221,226, 54,173, 91,131, 0, 72,136,143,151,125,253,253,247,178,145, 3, 6,228,199, 63, +122,132,227,167, 79,155, 84,197,197,217, 5,165,165,179,243,242,242, 10,172, 48,174,209,201, 41,201, 94,145, 93,218,123, 95,184, + 17, 23, 51, 98, 72,191,238, 98,145,128,121,148,154,121,203,211,195,197,225,234,229,203,122,150,101,163,107,211,209,106,181, 41, + 44,203,214, 35,132,184,158, 63,127, 30,174,174,174, 40, 41, 41,129,197, 98,129,201,100, 50,233,116, 58,121, 81, 81, 17, 12, 6, + 3,140, 70, 35,236,237,237, 17, 27, 27,155,199,178,236,217, 26,210,246, 22,195, 48, 11, 9, 33, 72, 72, 72,200, 2, 0, 95, 95, +223, 38,142,142,142,167,202, 23, 80,190,120,241, 98,175,204,204,204,248, 74,145,174, 26, 59,185, 91, 27,193,122, 81, 60, 61, 61, + 91,202,229,242,175,231,204,249,196,171,121,243,230, 40, 40, 40, 4,207,243,176,181,181,133, 94,175,135,157,157, 29, 58,118,236, +152,187,112,225,194,100, 66,208,151, 16,146, 91,147, 94, 90, 90, 90,174,159,159,223,232, 41, 83,166,124, 31, 28, 28,220,136, 16, +130,224,224, 96,244,234,213, 11,199,142, 29,195,195,135, 15, 81, 86, 86,198,222,184,113, 99,125,118,118,246, 46,250, 88,162, 80, + 40, 20,106,176,234, 76, 86, 86, 86,150,183,183,247,150, 59,119,238, 76,122,237,181,215,112,238,220,185,121, 0,250, 2,128, 92, + 46,159,247,218,107,175,225,206,157, 59,184,127,255,254,150,172,172,172,172,151,113, 78,169, 84,170, 53,153, 76,120,118, 14,101, + 29, 43,234,198,207,154, 6, 65, 8,105, 92,221,223,106, 66, 32, 18,121, 54,237,211, 71, 84, 18, 19, 83,186,234,242,229,197, 59, +118,238, 20,183,109,211, 6,102,139, 5, 60,199,193,215,207, 15,221,163,162,100, 91,118,239,182, 97,181,218, 43,159,127,240,193, +177,181,111,188, 81,118,173,172,236,145, 53,105,212,106,181,223,125,254,233, 39, 81,187,118,239,243,110, 18, 26, 88,239,248,201, +115,119,156,157, 29,148,141,130,130,108, 84, 42, 53,183,114,197, 82, 81, 89, 89,217,247,181,233,232,245,250,223, 79,159, 62, 61, +196,215,215,215, 53, 46, 46, 14, 38,147, 9, 28,199,161, 71,143, 30,229,253,239,120,145, 72,132, 7, 15, 30,192,108, 54,231, 39, + 37, 37,101, 63,122,244, 72, 6, 96, 89, 45,215,240,249,239,113, 82,255,254,253, 97,177, 88,208,171, 87, 47, 28, 56,112,224, 77, + 0, 51,106,216,255,133, 12, 86,229,239, 9, 86,118,110,247,242,242,234, 25, 20, 20,180,102,249,242,229, 2, 31, 31, 31,240, 60, + 15, 39, 39, 39,232,116, 58, 20, 22, 22,161, 73,147, 38,240,245,245,197,178,101,203, 0, 96,103,109,230,170,156,244,244,244,251, + 0,186, 5, 6, 6, 74, 13, 6, 67,199,168,168,168,173, 61,122,244,192,157, 59,119,112,245,234,213,238, 12,195,228, 26, 12, 6, +139,183,183,247, 44, 0,142,132,144, 95,172, 25, 61, 74,161, 80, 40,148,255,113,131, 21, 24, 24,104, 39, 22,139,186, 78,155, 54, +213,150,227,120,136,197,162,110,245,235,215,119, 72, 77, 77, 85,191, 64,229,183,102,219,182,109,175,175, 92,185, 82,214,191,127, +255,102,158,158,158,189, 0, 96,228,200,145,205,236,237,237,177,109,219, 54, 35, 33,100,205,203,202, 36,203,178, 67, 90,181,106, +133,226,226, 98,164,166,166, 94,173,203,177,135, 15, 31,182, 3,208,174,182,191,213,120,126,147,201,201,209,219, 91,144,117,238, +156,185,184,180,212,171,220, 92, 9, 4, 2, 20, 23, 23, 35, 45, 53, 21,246,118,118, 72, 72, 76,148,173,125,255,253, 93,254,225, +225, 98,206,100,114,182, 86,191,160,160, 64,235,225,225, 49,113,254,231,159,253,254,253, 15, 63,184,170, 74, 75, 31, 43, 20, 74, +163, 76, 38,241,152, 63,127, 30,167, 86,171, 39, 20, 22, 22,150, 89, 33,181,108,251,246,237,125,250,244,233,115,207,207,207,207, +173,160,160,192, 67,173, 86,147,226,226, 98, 6, 79,251, 82, 49, 0,112,239,222, 61,164,166,166,178, 28,199, 93, 4,240, 5, 33, +196,100,109, 90,189,188,188,156,219,183,111, 63,212,205,205,173,162, 41,178, 69,139, 22, 67,189,188,188,150,100,103,103, 23,189, +204,194,125,234,212, 41, 59, 66, 72, 59, 66, 8,250,244,233, 99,237, 97,239, 12, 24, 48, 64,192, 48, 12,244,122, 61,100, 50, 25, +108,108,108, 97,103,103,143, 70,141, 66,144,149,149,133, 94,189,122,113,143, 31, 63,222, 33,145, 72,190,171,107,154,244,122,253, +152,142, 29, 59, 46,154, 54,109, 26,120,158,199,224,193,131,145,145,145,177, 41, 57, 57,121,131,143,143,207,180, 73,147, 38,185, + 59, 59, 59, 99,214,172, 89,202,202,166,147, 66,161, 80, 40,175,160,193,242,242,242,138,114,114,114, 90,225,232,232,110,123,226, +196, 73, 17, 0,116,233,210,217,198, 98, 97,163,189,188,188,230,100,103,103, 31,174,203, 73,179,179,179,139,188,188,188,126,190, +122,245,234, 7,195,134, 13,195,169, 83,167, 62, 5,128, 97,195,134,225,234,213,171, 72, 78, 78,254,249,101, 85,182,222,222,222, + 19,186,116,233,242,110,155, 54,109,112,228,200, 17,112, 28,119,180, 46,199, 87, 30, 49, 88,213, 40,194,242,191, 89, 37, 38, 20, +130, 97, 24,112, 28, 7,194,243, 40, 44, 42,194,131,196, 68,148,148,148,128,227, 56,232,117, 58, 75,112,195,134, 90,181,201,100, +207, 60,157,107,204,106,114,115,115,211, 2, 3, 3,211,117, 6,189,155,179, 83, 61,189, 82, 41,131, 70, 83, 38,137,189, 23, 83, +150,153,153,249,216, 74,227,107, 98, 24,166,203,177, 99,199,230, 11,133,194,215,188,189,189, 49,114,228, 72,166, 71,143, 30,144, + 74,165, 48, 24, 12, 40, 41, 41,193,225,195,135,193,178,108, 67, 0,112,117,117,117,175, 95,191,254, 62,129, 64,144,151,156,156, + 60,169,182,115, 48, 12, 51,126,224,192,129, 98,147,201,132,197,139, 23, 99,193,130, 5,232,219,183,175,248,246,237,219,227, 1, +172,124, 89, 5,155,231,121,244,236,217,179,114, 39,247,251,181, 29,211,181,107, 87,145, 80, 40, 12, 9, 12, 12, 68, 65, 65, 1, + 10, 10, 10,224,234,234, 10, 47, 47, 47,184,185,185, 97,229,202,149, 88,189,122,245, 13, 66,200,178,220,220,220, 7,117, 77,147, +175,175,239,172, 55,222,120, 99,214,168, 81,163,160,209,104,112,245,234, 85,116,236,216, 17,203,151, 47,247,185,116,233,210,162, + 86,173, 90, 65, 34,145,224,252,249,243, 96, 89, 54,133, 62,158, 40, 20, 10,229, 21, 53, 88,222,222,222,245,120,158, 95, 50, 96, +192,128,129, 67,135, 14,197,242,229,203, 42,121, 5, 17, 54,110,220,228,176,127,255,254,117,190,190,190, 67,133, 66,225,156,212, +212, 84,171, 59, 36, 43, 20,138,181,219,183,111,159,216,190,125,123,187,168,168,168, 96, 0,144,201,100,252,246,237,219, 53, 10, +133, 98,109, 93, 51,242,252,164,143,158,158,158,157,164, 82,233,244,129, 3, 7,118,154, 56,113, 34,226,227,227,177,117,235,214, +187, 94, 94, 94,135,234,168,123,191,182, 81,132,181, 69,179,132, 82,105,145, 42, 55,215,209,214,207, 79,236,236,224,144,125,238, +220, 57,255,182,109,219, 34, 45, 61, 29,170,146, 18,232,245,122,196,199,199, 19,137, 72,148, 44,114,114, 98,210,162,163, 25,161, + 84, 90,103,131,105, 35,103,130, 63,255,120,114,125,131,193, 16,166, 86,171, 89,177, 68, 34, 86, 72, 73,157,154,153, 8, 33, 70, + 63, 63,191,193, 28,199,185,152, 76, 38,139,187,187,187,248,244,233,211,144, 74,165, 96, 24, 6, 77,155, 54,133, 84, 42, 53,249, +248,248,104, 0,192,217,217, 89,176,108,217, 50,241,135, 31,126, 24, 95,155,118,203,150, 45,197,254,254,254,147, 66, 66, 66,112, +245,234, 85, 36, 36, 36, 36, 94,187,118, 45, 36, 34, 34, 2,222,222,222,147, 90,182,108,249,253,237,219,183, 45, 47,163, 96, 19, + 66,234,220,201,253,194,133, 11,196,203,203, 11, 2,129, 0, 2,129, 0, 60,207,163,160,160, 0, 13, 27, 54,196,218,181,107,177, +122,245,234,159,114,114,114, 94, 40,178, 26, 24, 24, 40,109,222,188,249,187,163, 70,141,194,227,199,143,177,116,233,210,252,188, +188,188,163, 39, 79,158, 28, 63,109,218, 52, 81,199,142, 29, 81, 84, 84,132,141, 27, 55, 90,238,220,185,243, 93, 78, 78,206, 90, +250,120,162, 80, 40,148, 87,208, 96,249,250,250, 78,148,203,229,139, 70,141, 26, 37, 10, 9, 9, 65, 94, 94, 30, 52,154, 50,174, +105,211,112, 14, 96,136,173,173, 13,163, 84, 42, 49,101,202, 20, 52,107,214,172,231, 39,159,124,210,195,203,203,235,171,236,236, +236, 31,173, 57,241,227,199,143, 53, 94, 94, 94,223,205,156, 57,115,121,116,244, 85, 27, 0,136,137,137,209,102,103,103,127,153, +157,157,173,169,163, 9, 42,159,156,146,177,177,177, 73, 10, 10, 10,178,244,239,223,223,121,232,208,161,112,113,113,193,157, 59, +119,176,108,217,178, 59, 90,173,118, 76,106,106,170,229,255,251, 34,179, 70, 99,238,173, 3, 7,236,186,190,254,186,253,199, 67, +134, 44,125,251,237,183,127, 92,176,112,161, 56, 48, 32, 0, 38,179, 25, 9, 9, 9,100,231,142, 29,230, 29,203,151,127, 11, 27, + 27,113,244,190,125, 82,147,201,148, 86,151,115,248,248,248,116,233,215,167, 75,200,138,149,223,193,160, 47,195,245,171,127,160, +164,164, 0, 63,255,178, 63,196,199,199,167, 75,102,102,230, 5,171,211,203,178, 1,123,247,238, 5, 0, 72,165, 82,124,241,197, + 23,240,242,242,130,189,189, 61, 52, 26, 13, 38, 79,158, 44,253,240,195, 15, 1, 0,241,241,241,176,181,181,181, 54,202,214,111, +242,228,201,142, 22,139, 5,199,142, 29, 51, 72, 36,146,215, 79,158, 60,121,181, 89,179,102,242,206,157, 59, 59,110,221,186,181, + 63,128, 3, 47,203, 96,189,192, 49,156,183,183,119,242,201,147, 39, 27,142, 28, 57, 18, 18,137, 4, 37, 37, 37,176,183,183,199, + 15, 63,252,192, 43,149,202,141,127, 33, 73, 82,165, 82, 41,227, 56, 14,187,119,239, 70, 94, 94,222,128,242,254,136,179,103,207, +254, 50, 52, 52, 52,240,193,131, 7, 79, 12, 6,195,188,172,172,172, 71,244,209, 68,161, 80, 40,175,168,193,226,121,254,227, 19, + 39, 78,136, 56,142,195,250,245,235,113,243,230, 77,146,151,151,247,173,217,108,254, 74,169, 84,178,197,197,197,179,223,126,251, +237,169, 11, 22, 44, 16, 68, 70, 70, 34, 58, 58, 90,208,176, 97,195,233, 0,126,172,100,124,162,106,154, 43,163,164,164,228,104, +110,110,206,143, 60,255,180, 50, 20, 8, 24, 27,169, 84,118,180, 22, 51,245, 39,205, 42, 38,179,108,244,213, 87, 95,229, 59, 59, + 59,243,241,241,241, 88,187,118, 45,119,235,214,173,125, 60,207,127, 86, 88, 88,168,179, 70,243,101, 80, 89, 83,202,178,183,183, +206,158,221,184,229,224,193,252,176,183,222, 50, 10, 68,162,119,150,174, 90,245,105,137, 74,229, 5,134, 33, 46, 78, 78,105, 27, +150, 44, 89,220,161, 91, 55, 67,252,133, 11,242,152, 83,167,196,174, 22,203,221,186,164, 51, 51, 51,243, 66,112,160, 31, 54,173, + 95, 9,179,217,136,156,172,167,254,172,176, 72,141,154,204, 85, 85,154, 2,129, 64,245,198, 27,111, 40, 77, 38, 19, 51,122,244, +104,113,126,126, 62, 2, 3, 3, 1, 0,165,165,165,248,227,143, 63, 16, 26, 26, 10, 0,136,141,141,173,248, 92, 91, 58, 21, 10, +197,164,142, 29, 59, 34, 45, 45, 13, 9, 9, 9,123,179,179,179,243,188,188,188,246,166,165,165,141,111,221,186, 53,246,237,219, +247,102,117, 6,171,174,223,145, 53, 6,171,154,188,191,181,127,255,254,143,162,163,163,251,204,154, 53,139,233,214,173, 27, 0, +160,172,172,140,207,201,201,209,188,136,102,229, 52,177, 44, 11, 0,144,203,229, 26, 0,120,102,166, 70,190,168,230,203, 40,159, + 84,147,106, 82, 77,170,249,223,160,249,143, 49, 88, 0,204, 28,199,225,194,133, 11,216,191,127, 63,107, 48, 24,134,229,230,230, +222,170,244,255, 47,125,124,124, 14, 13, 31, 62,252,104, 98, 98,162, 40, 33, 33, 1, 0,216,186,156,220,104, 52,154, 24, 6, 4, +255,154,140,146, 24,141, 70,211,139,124,215,149,127,249,245,215, 95,145,147,147, 99, 76, 75, 75,219, 73, 8, 89,151,147,147,147, +249, 23, 34, 33,127,121, 20,225, 70, 66,140,175, 51,204,233, 5,157, 58,245,156,127,234,148,236,181, 25, 51,204,195, 70,141,154, +205,153, 76, 22,161, 68,194, 75,109,108, 4,156, 76, 38,142,191,112, 65,190,102,218,180,122,122,163,241,248,214, 58,116, 28,175, + 20,193,194, 27,111,205,128,190, 82, 4, 43,250,230, 67,212, 53,130, 37, 18,137,252, 44, 22,139,140,101,217, 44,158,231, 49,126, +252,120,240, 60, 15,189, 94, 15,141, 70,131,226,226, 98,195,123,239,189, 39, 0, 0,165, 82,137, 94,189,122, 73,173,209, 13, 8, + 8,104, 32, 22,139,113,252,248,113,136,197,226,205, 0, 32, 22,139, 55,159, 58,117,106,252,152, 49, 99,224,231,231,215,132, 97, + 24,166,182,197,163, 43, 22,123,102, 16,244,236,219, 15,114, 11, 31,114,175,210, 98,207,247, 35, 34, 34, 0, 43,250, 93, 61, 79, + 70, 70, 70, 14,128, 25, 62, 62, 62, 27, 63,250,232,163,143,219,182,109,219,106,225,194,133, 96, 24, 70,248, 87,111, 54,158,231, + 97,177, 88,254,210, 20, 18, 20, 10,133, 66,249,223, 55, 88, 43,187,117,235, 54,147, 16, 34, 98, 24,230,155,231,204, 85,121,212, + 36,222,219,219,251,243,134, 13, 27, 86, 44, 0, 93, 71,243,146,199, 48,204,114,129,128,249,248,233,239,117,159, 88,178,146,198, + 39, 79,205,129,120,215,173, 91,183, 62, 77, 75, 75,203, 34,132,176,127,245, 2,189,140, 81,132, 0,176,157,144,148,209, 12,115, + 98, 86,120,120, 84,159,105,211,208,172, 79, 31,123, 47,127,127, 78,111, 54,243,177,151, 47, 51, 87,247,238,149,196,156, 58, 37, +214, 27,141,199,247, 19,146, 94,215,116,102,102,102, 94, 8, 12,240, 57, 57, 98, 88,191, 94, 1, 13,188, 0, 0, 79, 82,178, 81, + 88,172, 62, 89, 23,115, 5, 0,169,169,169, 70, 0, 70, 79, 79,207, 97,187,119,239,222,251,204,244, 84, 44, 59, 3,192, 40, 18, +137,130, 1, 64,163,209,248,255,254,251,239,219, 69, 34, 81,173, 38,246,254,253,251, 27, 22, 44, 88, 48,229,201,147, 39, 59, 51, + 51, 51, 19, 1, 32, 45, 45, 45,209,219,219,251,235,156,156,156,169, 25, 25, 25,107,137, 21,238,227,185,197,158, 17,127,121,143, + 28, 64,211,242,197,158, 95,116,173,193,231,174,103, 28,128,177,222,222,222,221,122,247,238, 61, 29, 64,238, 95,209, 51, 26,141, + 22,163,209,104,225,121, 94,108, 54,155,137,209,104,180,208,199, 15,133, 66,161,252, 3, 13, 86, 86, 86,214,102, 88,177,152,179, +181,251,213, 96,144,230, 50, 12,179,166,220, 44,253, 85, 13,179,217,252,178,214,111,187, 63,104,208,160, 58,237, 95,219, 14, 59, + 9, 73,123,159, 97,182, 28,249,254,251, 22,199,215,173,243,230, 88,214,153, 1,136, 80, 42, 45, 50,153, 76,169,174, 22,203,221, +186, 70,174, 42,243,248, 73,102,111, 0, 8, 14, 14, 38,143, 30, 61, 2, 33,228, 47, 45, 30,156,147,147,115,210,199,199,199, 77, + 36, 18, 73, 25,230, 79, 82,198,103, 38, 12, 0,238, 49, 12,211, 4, 64,173, 17,158,140,140,140, 85, 0, 86, 85, 81,134, 86, 3, + 88,109,109,186, 42, 22,123, 6, 4, 60,195,143, 8,235, 52,114, 47, 0,190,124,177,231,151, 73, 86, 86,214, 57, 0,231, 94,130, + 97, 51,212,175, 95,127,221,242,229,203,167,222,189,123,247,215,204,204, 76, 3,125,252, 80, 40, 20,202, 63,208, 96,253,127,242, + 50, 22,181,125,217, 11,227,190,140, 40, 72, 85,124,247,212, 64, 93,251, 59,175,103, 82, 82, 18,243,178,180,158, 25, 1, 67, 45, +215,158,160,142,205,195,127,133,242,197,158, 43, 17,254,191,112,179,165,166,166,126,213,178,101,203, 21,153,153,153, 52,122, 69, +161, 80, 40,175, 56, 2,122, 9, 40,148,255, 63, 94,214, 52, 20, 20, 10,133, 66,249,239,134, 1, 16, 85,213, 63,234, 50, 58,128, + 97,152,168,186,158,184, 54,125,170, 73, 53,169, 38,213,164,154, 84,147,106,190,122,154,181,105,191, 50,163, 19, 43,119, 94,126, +217, 27,128, 40,170, 73, 53,169, 38,213,164,154, 84,147,106, 82,205,127,218, 70,155, 8, 41, 20, 10,133, 66,161, 80, 94, 50, 34, +122, 9,170,166,133,167,112,177,159,143, 91,171,138, 40, 31,207, 3, 0,248,103,179, 8, 84, 76, 39,192,243, 32,132, 32, 59, 95, +117,251, 94, 30,249,252, 69,207, 23,226,205,212,115,147,203, 87,243,132,116,122,246,167, 11,234, 34,227,140, 56, 53, 81, 89,171, +209,216,131,105, 44, 23,224, 35,158,160, 25, 0, 8, 24,220, 51,240,248,230,126, 46,185,255, 87,175, 7,195, 48, 76,152, 43, 38, + 75, 21,202, 81, 14,142, 78, 65, 37, 37,133, 73,102,131,113, 79, 66, 1,126, 38, 47, 48,177, 83, 96, 61,166, 29, 79,240, 41, 0, +129, 88,128,111, 31, 22,145,115,180,212, 81, 40,148,255, 39,254,234,188,118, 92, 85,143,201,191,168, 73, 39,200,251, 39, 27,172, + 48, 55,102, 26, 24, 44, 4, 64, 64,176, 40, 62,159,212,105,189,180, 48, 47, 38, 74, 46, 20,110, 0, 32, 52,152,185, 89,132,199, +197, 42, 43,115, 1, 58,203, 37,194,111, 1,240, 6,142,155, 20,159,109,125,123,108,184, 15,211, 71,196, 11,182,242,132,136, 57, +158,108, 6,193, 17, 91, 9,174, 68,103,146, 58, 13,139,247,243,113,107,117,224, 70, 78,175,115,107, 63, 64,219,102,129, 32, 28, + 11,240, 22, 40, 35, 63,194,153, 85,227,209,182,177, 31, 8,111, 1,120, 22,182,125, 87,160,111,184,195, 11,223, 28, 33,222, 76, + 61,127, 23,183,184,245,235, 55,120,120, 5, 52, 97,120,214,140,196, 27, 39,199,126,248,241,252,238,225, 14, 76,184, 53, 38,171, +185, 23,243, 86, 96,195,144,143,102, 44, 92, 41,244,244,242,181,225, 45, 70, 54, 55,229,126,196,119, 95,207,223,215,220,139,249, +246,110, 54,217, 96,173,145,106,226,138, 41, 34,153,116,164, 66,110, 19,164,211,105, 30,113,102,203,158,112, 47, 81,159,111, 86, +172,110,209,181,103, 63, 91, 78,147, 43,176,240,104,178,123,215, 78,255,239,127,252,169, 31,195, 48,131, 8, 33,124, 93,242,204, + 19,124,252,112,203,228,126, 98,145,144,105,252,230,122, 33, 94,112, 42,132, 38,238,204, 24,134, 32,178,214, 39, 23,131, 75, 9, +121,100,199,139,156,163,177, 59,243, 43, 67,208, 8, 12,246, 50, 4, 59,227,243, 73, 62,125,116, 80, 40,175, 22, 62, 62, 62,231, + 50, 51, 51,187,189, 76, 77, 47, 47,175,118,217,217,217,215,232,213,165, 6,203,138,218, 23, 95,198, 63,206,112, 2,103, 70, 88, +163,128,197, 0,234,100,176,228, 66,225,230,155, 73,121, 30, 96,205, 88,191,228,157, 93, 38, 11,192, 90,204,224, 88, 11, 56,214, + 2,150, 53,131,179, 88, 64, 44, 70,204,255,237, 28, 96,210,160, 85,120,240,102, 0,158,214,158, 67, 76, 4, 91,111, 95, 62, 89, +143, 49,169,177, 99,237, 87,239,101, 20,148,189,119,250, 94,118, 97,152, 59, 51, 55, 33, 31, 27,235, 98, 4,206,173,251, 0,219, +126,255, 35,115,205,175,218, 7, 60, 33,168,103,175, 8, 25, 59, 32,222,119,203,193,115, 25,171, 55, 27, 30, 0,128,131,141, 52, +100,194,189, 36,191,191,242, 37,184,201,229,171,127,254,233,123, 15, 79,103, 5,195, 94, 93, 6,150,227,224,235,223, 95, 56,119, +250, 88,207, 47, 87,109, 88, 5,224,141,154,142, 15,117,103,154, 52, 10,108, 60,107,243, 31, 87,253,180,165,249,166,147,219, 63, +125, 12, 35, 44, 30,222,141,197,139,191, 90, 41,156,247,201, 7, 51, 67,221,153,235, 15,242, 72, 66, 45,230, 74,208,216, 13, 7, +191, 90,182,162, 89,247,190, 3,108,249,178, 2,161, 65, 91,214,104,253,111, 27, 22,134, 54,107,163,140, 12,247,145,228,239,153, +202,232, 53,197, 48, 11,228,178,238, 97, 81,246,250,113,163, 45,235, 55,109,155, 14,224,187, 58,189,254,145,127,149, 61,158,127, +241,183, 73,134, 32, 50,230,218,185, 41, 92,246, 77, 16,206, 2,112,230,138,159,224, 44, 32,252,211,159,109,167,254, 6, 0, 47, +100,176, 4, 4,189, 78, 95,190,233,153,151,155,211,122,213,138,165,115,155,184, 49,199,192, 97,235,253, 98, 92,168,171,177,164, + 80, 40,255,189,120,121,121,177,217,217,217, 47,181,101,199,219,219,187, 95, 86, 86,214,209,191,152,174,143, 0,188,245,236,215, + 13,217,217,217,223,252,213,116,181,110,221,218,135, 16,226,241,236,217,159,123,243,230,205, 76, 90, 2,254,147, 6, 11,144,131, +240,192,222, 33, 0,160,168,235,201, 8, 32, 7, 35, 4, 44, 90, 12,238,219, 19, 46,110, 30,128, 69, 7,152,117,128, 69, 15, 88, +180,128, 69,143,194,156, 52,192,172, 5,158, 28, 3, 75,136,172,206,185, 50,170,129,135,123,208, 35,194, 15,174, 14,114,124, 48, +184,137,203, 47,199, 31,110,216,112, 50, 49, 10,192, 40,171,210, 74, 8,218, 54, 13,194,154, 13,218, 7,135,110,231,247, 6,128, +254, 45, 92,142,183,109,226,239,187,122,179,225,193, 31,247,138,251, 0, 64,223,112,135, 99,109, 66, 60,253,248,191, 16,221,229, + 9,137,244,170, 31,196,112, 49, 63,131, 47,205, 68,105,169, 30,153, 41, 91,224,228,221, 82,192,241,232, 82,219,241, 10, 33,230, +188, 63,111,185, 88, 87,154,103,226,205, 5,156,171,176, 68, 40,146,242, 12,178, 46, 24,203,120, 21, 55, 99,242,120,118,214,231, + 75,230, 0, 24, 91, 99, 52,200, 13,211,191,253,118,117,211,142,173, 66,221,114,247,125,192,148,149,228,129, 21, 42,101,131,219, +119,132, 99,112, 19, 62,239,252,183,140, 52, 32, 10,142,206, 1,200,186,186, 29,169,215,246, 51,157, 34,134,201, 54,238,144,140, +171,206, 96, 5,187, 50,157,122,119,110,179, 43,192,207,203,147, 16, 30, 60, 79, 64,120, 14,111,142,232,133,185,187,159,128,227, + 56, 12,239,221,169,199,242, 41,221, 9,207,243, 32,132, 71, 70,110,145,238,236,245, 7, 61, 30, 23,147,235,214, 68,166,154,183, +235,214,233,222,237,107,161,150,135,135,209,106,236, 87, 15, 24,224,114,165, 50,215,233,206,137,141,161,192,111, 47,102,224, 24, +134,105,236, 6, 46,245,248, 50,248,117,158, 44,252,121,199,113, 87,117, 65,214,132,125, 91,126, 26,177,246,231,159,183, 1,152, + 74, 31, 35, 20,202,171, 65,118,118,246, 75, 55, 89, 87,175, 94,205,254, 43, 38,171,117,235,214,157, 1,124,157,157,157, 93,110, +182,190,110,219,182,237,252,202,117, 85, 37,212,132,144,177, 55,111,222,188, 88,147,230,204,153, 51,189, 0, 52,184,117,235, 86, +249, 57, 26,180,110,221,186, 65, 85,251, 42,149, 74,174,121,243,230,169, 43, 87,174,204,166, 37,228,239, 53, 88, 15,210,247,124, + 16, 97,204, 41, 3,128, 7, 86,152,148, 63, 53,237, 25, 44,220,178, 77, 11,199, 47, 11,171, 95, 15, 26,173, 9, 39,111,165,130, +227, 44,224, 88,246, 89, 36,139, 5,199, 90,208,187,185, 11, 58, 24,166,226,187, 35,137, 96, 57,254,171,154, 52,159,199, 76,248, + 49, 45,162, 94,219,205,243, 68, 42, 19, 11,212,141,124,157,221,102, 13,111, 46,248, 96,112, 24,244,102,246,181, 38,238,204,217, +132, 60,178,222, 42, 77,254,223,231,206, 36, 85,253,141, 99,107,205,123, 13,209,167,182,163, 7,244,180, 39, 70, 53, 44,133, 79, +160,209, 89,240,164,200,130, 92,131, 10, 50, 38,199, 42, 77,158,160,153,143,183,167,242,202,174, 79, 82,156,133,165, 34, 55, 33, + 43,145, 10, 88,112, 60, 17, 18, 85,130,177, 94,104, 79,113,121,191,172,154,210,169, 80,218,141,239,220,171,191, 67,250,246,201, +140,162, 81,111,184, 69,248, 34,229,226, 38,228,223, 58,130,162,236, 84,198,222,160,130,187,115, 32,250,142, 29,133,111, 70,181, +134,166, 84, 3, 97,206, 99, 7,169, 88,230, 88,157, 38,225, 48,246,219,229, 75, 60, 69, 66,193,211,235, 89,190,113, 22,232,141, + 70,128, 99, 33, 23,241, 96, 72,249,255, 44,224, 44,102,101,179, 97,159,188, 3,224,122,109,121, 79,200, 35, 59,194,220,152, 72, +240,150, 80, 98,209,131, 1, 46,199,231,147, 10,211,211,196,157, 25,211,178,247,196, 72,194,224,210,139,124, 71,225,206, 24,208, +170,129,173,141, 77,233, 3,100,238,125, 15,143, 33, 39,238, 29,223,194,152, 55,167, 43,127,249,229,151,129, 12,195, 76,171,220, + 7,237,239, 24, 94, 76, 53,169,230,255,170,166,131,131, 67,195,250,245,235,207,183, 88, 44,157, 37, 18,137,187,217,108, 6,207, +243,185, 82,169,244, 82,106,106,234, 23,106,181, 58,249,191, 45,239,199,142, 29,179,218,100, 89,163, 41, 22,139,113,230,204,153, + 71,214,154,172, 42, 22,160,223,186,119,239, 94,236,222,189, 27, 0,112,238,220, 57, 4, 7, 7,219, 84,117,108, 70, 70,134,205, +240,225,195,183, 2,240,173, 73, 51, 41, 41,169,225,146, 37, 75,176,119,239, 94, 0,192,150, 45, 91,208,168, 81,163, 42,211,115, +247,238, 93,225,103,159,125,214, 16, 64,246,223,253, 29,253,211, 13,214, 19, 63, 39,105, 4, 12, 28, 0, 60,169,235,201, 18,114, +201,242,230,158,226, 62,103,246,254,216, 89, 46, 17, 96,193,250, 89, 25, 5,197,154,118, 34, 6, 60, 0,176, 4, 2, 39, 91,105, +244, 87, 19,154,251,149,148, 25,112,232, 70,214,197,248, 60, 82,167, 80,104,124, 54, 57, 5,192,241, 95, 21, 36,211,104,194, 55, +167,118,238,156,211,167,217,140,193,205,112,240,106,234, 12, 0,235,107, 45,228, 60, 15,194,179, 21,157,218,159, 58, 25, 30,224, +217, 63,189, 49,240, 32, 79,255,198,215, 45,130,213,149, 97, 68, 37,110,232, 91, 79, 41,253, 97,202,148,183,237, 45, 5, 73, 40, + 54, 73,144, 81, 98, 64,174, 94,140, 50,145, 27,178, 30,196,114, 2, 6,167,106,143,178,160,148,176, 6, 71, 39,169,173, 32,188, +231, 59,222,165,199, 63, 45,145, 50,172,208,126,232,151,142,133,103, 86,166,178,218, 2, 45,195,160,214, 9, 46, 29, 28, 28,131, + 13, 69,169, 66,117, 73, 33, 28, 61,194,208,231,181, 1, 88,212,191, 9, 52,165, 90, 20, 20, 71,147, 32, 79,123, 38,237,210, 54, +204,235,219, 24, 69,121, 57, 48, 90, 0, 70,107, 44, 54,152, 12,101,213, 94, 71, 1,126,254,112,246,199, 99,252, 61, 93,109,202, + 7, 11, 16,158, 67,243,198, 1,232,217,185, 45, 78, 93,190,130,155,177, 15,193, 63, 27, 44, 64,120, 30,153,249, 37,121, 6, 51, +183,169, 78, 23,148, 99, 65, 44,134, 42, 13, 24, 94,160,105,176,169, 59,163,228,128,207,219, 5,217, 77,154, 51,192,223,206, 70, +198,192, 96,225, 96, 48, 89,160,185,242, 3,156,235, 55,133, 82, 46,103, 34,160, 23, 1,160,147,135, 82, 40,149, 24, 57,114,164, + 60, 47, 47,239,124,255,254,253,155,244,236,217, 83, 25, 25, 25, 9,173, 86,139,147, 39, 79, 66,171,213,250,251,250,250,250,159, + 60,121,114, 88,187,118,237, 18,124,124,124,186,238,217,179,167, 46,125,100, 69,248, 87, 39,117, 30, 0,251,108, 41, 47, 33,158, +118, 52,231, 9, 33,220,139,166, 93, 42,149, 34, 58, 58,250,165, 71,178,110,220,184,241,232, 69, 34, 89, 90,173, 86,226,233,233, + 9,103,103,103,112, 28, 7,173, 86,139, 3, 7, 14, 64,173, 86,131,231,121, 40, 20, 10,124,249,237,122, 60,184,115, 30,215,175, + 95,135, 90,173,150,212,166, 89, 88, 88,200,132,132,132,192,104, 52,130,101, 89, 24, 12, 6,156, 62,125,186,226,119,145, 72,132, +143, 23,175,194,195, 91,231, 17, 19, 19,131,194,194, 66,134,150,234,191,223, 96,253,101, 56,142,157,251,203,230,157,209,115,167, +142,194,244,209, 81,190, 95,252,184, 63, 42,161,128,108, 6,128, 38,174,204,132,113,221,130,252, 28,149, 98, 44,218,126, 11, 32, +100,238, 95, 61, 95, 92, 17,121, 24,230,193,204,248,253,250,255,177,119,222, 97, 81, 29,109, 27,191,231,108,103,119,233,125, 1, + 65, 80, 17, 81, 81,192,174, 17, 21,187,198,104, 52, 70,141, 45,177, 27, 53, 26, 75,140, 70, 99,236, 38,182, 24,141,154,166,177, +183, 24,123,199, 6, 54, 84, 80, 80, 20,145,186,244, 94,182,239,153,239, 15,202,171,134,178,160,249,222,188,230,252,174,107, 47, +216,118,239,156, 57,101,238,243,204,204, 51, 9, 33,243,135,250,195,203,217,162, 81,131, 6, 68, 20, 27,107,194,154,127,172, 1, +214,114,113,227,190, 45,237, 78,131,101, 97,101, 46,246,129,209, 0, 43,185,184,113,239,102,150,167, 0,192, 74, 42,244,169, 44, +210, 85,101,184,183,158,112,188, 84,204, 31, 47, 11,112,174, 55,186,127,119,179, 62,253, 7,153,201, 5, 6,100,223, 60,139, 2, +129, 43,244, 54,238,208,232,115,144, 28, 23,107,188,112, 35, 58, 37,171, 80, 51,171,198, 98, 82, 92, 73,137,123,108,239,233,215, +221, 58,235,248,151, 25,158, 99,118,215,103,192, 50,133,187, 6,166,203, 28, 90,155,221,122, 22, 87,196,210,191, 70,112, 94,165, + 32, 63, 63, 94,111,132,179,202,200, 55,143,189,244, 43,230,245,110,142,220,156, 12,168,117, 6,228,171, 12, 58, 39, 43,137, 88, + 19,247, 0, 26,157, 1, 90, 61, 11,129,149, 11,206,134, 69,102,177,122,253,169,170, 52, 99,179,232, 61, 0,242, 23, 95,107, 96, + 79, 90,204,181, 48,187, 7,189, 10, 9,201, 74,236, 56, 17,230, 95,246,185,186,223,157,178,134,210,110,230, 23, 34, 87,132,162, + 83, 93, 6,183, 55,113, 36,173,205, 36,194,239, 87,127, 54,220,183,157,183,141,152, 77, 14, 3, 97,117,144, 25,249, 80,137,140, +176,116,243, 2,171, 45,164, 37,106,117,222,195,255,199, 37,130, 56, 56,254, 23,240,241,241,113,178,180,180,124,248,249,231,159, +219, 12, 28, 56, 16, 71,142, 28, 65, 65, 65, 1,126,251,237, 55,172, 95,191, 30,139, 23, 47,134, 94,175,199,182,109,219,164,135, + 14, 29,106,189,121,243,230,100,119,119,247,166, 9, 9, 9, 53, 45,168, 78, 0,136, 1, 8,202,218, 46, 2,128, 61,121,242, 36, +250,244,233,131,147, 39, 79,178,101,175, 25, 9, 33,122, 74,169,166,174, 6, 75, 36, 18,225,209,163, 71,111,196,100, 9, 4, 2, +200,229,114,136, 68, 34, 60,126,252,184,214, 38,203, 96, 48,240,146,147,147,145,159,159,143,238,253,251, 99,221,138, 21,232,210, +165, 11,186,119,239, 14, 74, 41,206,159, 63,143,224, 14,205, 48,244,221, 32, 68, 71, 71, 67,175,215,155, 84,222,180,180, 52,164, +167,167,163, 87,255,254,216,190,121, 51,218,180,105,131,198,141, 27,195, 96, 48, 32, 36, 36, 4,131,123,118,128,228,189, 96,196, +196,196,112, 7,245,255,138,193,122,144, 65,111,248,218,147,227, 31,246,108,221,175,127, 71, 95,108,223,119, 97,153,175, 47,217, + 11, 0,182,230,226,165, 35,187,120, 33, 42, 49, 23, 23,238, 41,143, 71,101,210, 55, 50,251,130, 53,194,206,214, 66, 10,240, 68, + 80,233, 88,131,197, 51,212, 56, 48,153,165, 20,210,119,230,226,163,254, 81,110,109,124,221,220,202,103, 17,202,251,172,197,168, +200,167,245, 90, 53,118,170, 7,163, 30, 48,234, 97, 49,116, 55,240,141,172,198,114,116,244, 20,159,155, 59,235,179,246,189,223, +251,192, 76, 36,181,132,177, 32, 9,250,180, 72,100, 63,185,130, 98,105, 35,164, 37, 60,195,254, 51, 55,243,159, 36,103, 23, 48, + 12,206,166,231,107,102,199,230,208,162,154,116,213,122,172,248,234,203, 89,125,247,239,221,103, 46,246,234, 72, 98, 55,245,201, + 23,241, 13, 98,251,250, 1, 76,137,196,142, 46,255,109,159, 69,177, 22, 43,107,210, 41, 41, 46, 56,124,254,236,233,161, 13, 61, + 59,154, 63,191,125, 2, 42,181, 6, 26, 61,208,180,117, 16,140, 70, 42, 34, 12, 97, 45,120, 60,146,145,157, 11,162, 55,166, 95, +189,255, 60,245,218,253,103, 60,141,121,205,218, 47, 29,116,132, 55,173,127, 80, 75, 64,175,194,187,239, 52,199,186, 93, 23, 62, + 5, 48,230,245,118,114,105, 4,139, 2, 29,155, 58,144, 31, 1,116,188,243,199,122,159,192,247,102,160, 54, 17,172,102,246,164, +119,179, 6,138, 95,215, 45,157,107, 99,235,218,136, 71, 88, 61,168,147, 31, 80,144, 76, 73,114, 24, 44, 93,218,192,168,232,128, +109, 27,191, 45, 98, 89,186,183, 46, 41, 42, 56, 56,222,102,212,106,245,225, 85,171, 86,217,244,235,215, 15, 0, 80, 84, 84,132, +176,176, 48,252,244,211, 79,144,201, 94,190, 78,246,233,211, 7,148, 82,155, 69,139, 22, 29, 6,208,174, 42,205, 14, 29, 58,244, +223,184,113,163,178,101,203,150,207,202, 76,150, 16, 0,243,224,193, 3, 38, 41, 41,137, 88, 91, 91, 83,133, 66,161, 87, 42,149, + 44, 0,227,216,177, 99,121,114,185,188, 97, 81, 81,209,229,186, 26, 44,145, 72,244, 70,198,100, 9, 4, 2, 16, 66, 32, 18,137, + 32, 20, 10,145,146,146, 82, 43,147,101, 48, 24,248, 39, 79,158,196,157, 59,119,176,184,101, 75,124,230,226, 2, 27, 27, 27,132, +132,132,128, 82, 10,153, 76,134,156,156, 28,236,221,187, 23, 93,187,118,133,193, 96, 16,154,162,123,240,224, 65,132,135,135,227, +155,192, 64,124,102,105, 9,185, 92,142,243,231, 75,123,253,196, 98, 49, 18, 18, 18,112,254,252,121, 4, 5, 5,113, 7,245,223, +109,176,130, 8,225, 19, 71, 56,233,180, 42, 80, 3, 5, 8, 20,190,190, 68, 24, 21, 69,117,181,253, 81,134,193,151, 27,119, 28, +239,187,118, 70,127, 50,126,128,191, 98,201,175,151, 38, 1,192,199,239,123,187, 72,197,124,108, 56, 26, 69, 25, 6, 95,190,137, + 13,244,245, 37, 66,134,193,164,238,109, 26, 67,153,167, 69,172, 50,239, 98, 20,165, 38,117,233, 92, 88,251, 17,118,254, 25,146, +180,126,167,250, 17,165, 20, 86,114,113,227, 81, 17,177,245,126, 61, 25,158,248,221,126,245, 35,202, 82, 88, 73, 5, 62, 99,162, + 59,212, 56,139,176, 85, 61,225,248, 47,230,206,238, 48, 96,204,231, 18,195,163, 3,208,198,158, 1,171, 83,161, 64, 39, 68, 30, +207, 9,201,137,137, 88,190,237,120, 82, 65,177,118,232,131,140,218, 25,203,152, 44, 90,228,107, 79, 6, 46,255,122,254,185, 21, + 75, 23,201, 85,207, 66,138,120,196,160,226,121,116,230, 47, 93,188,150, 20,106,180, 31,196,230,208,194,154,116, 52,230, 88,185, +234,187,141,125,199,141, 24,244,200,187, 81,103, 91,163, 50,206, 86, 93, 80,144,177,251,116,184, 83,217,157, 33, 1,128,216,228, +108,100,230, 23, 27,140, 6,253,101,115, 1,150, 60, 52, 37, 26, 88,134,151, 35,177, 31,216,201,111,184,189,185, 16,170,162, 60, + 56,152, 11,208,179, 77,131,225, 94,142,100,238,179,116,154, 89,119,131,165, 7,213,171,112, 99,101, 87, 31,106,212,251,192,168, +135, 46,226,247,218, 71,194, 8, 62,155,250,142,220,194, 90,251,156, 65,177, 12, 48,179, 3,177,112, 7, 44,235, 19, 65,147, 15, +160,124,246,208,240,233,240, 17,217,113,241,201, 63,219,153, 97, 13,119, 9,225,224,120,153,132,132,132,145, 95,124,241,197,181, + 54,109,218, 56,218,217,217,161,121,243,230,248,243,207, 63,241,249,231,159, 87,124,166,101,203,150,160,148, 34, 39, 39, 7,171, + 86,173, 74, 83, 42,149, 35,171,211,124,248,240,225,163,157, 59,119,190,227,235,235,171, 19, 10,133,121, 0,196,121,121,121,146, +156,156, 28,162, 86,171,193,178, 44,107,105,105,105, 84, 42,149,250,161, 67,135,106, 66, 67, 67, 27, 20, 23, 23, 39,188, 78, 4, +171, 85,171, 86, 15,242,242,242,242, 25,134,121,237, 20, 14,229,230,170, 89,179,102,246,197,197,197, 44,128,220,186,164,112, 48, + 24, 12, 8, 12, 12,196,153, 43,119,113,242, 66, 40, 10,148,143, 49,105,220, 72, 52,111,222, 28,103,206,156,169,243, 62,107,209, +162, 5, 78,159,191,134,107,119,238, 35, 33, 38, 2,159, 78, 26,135,166, 77,155,226,244,233,211,220, 1,253,119, 27,172, 38,246, +164,133,162,161,232,247, 69,189, 27, 52, 17,116, 95, 4, 34, 48,195,129, 70,167, 59,124,185,124,211,163,230,142,100, 68,100,122, +205,179,189, 94,138, 98,165,211,135, 77, 29,200,158,251,209, 62,195,223,109,227,134,237,127, 74, 23, 2,192, 7,157, 60,113,235, + 73, 38,110,198,100,236,121,152, 65, 31,190,238,198, 53,119, 36, 82, 80,236, 89, 53,109, 64,144,187,171, 19,126, 58,114, 13,132, +224,176, 73, 13, 45,165,180,141,175, 59,214,239,124,117,198,160, 83,189,239,246,171, 31,157,121, 80,208, 27, 0,122, 52,145,157, +106,213,192,186, 94, 77,145, 12, 51, 17,127, 66,239, 65, 31, 73, 12, 49,127, 2,241,231, 65, 12, 26,168,116, 44, 82,179, 10, 81, + 98,233,134,144,176,251,170,124,181,118,198,195,140,186, 69,237,162, 50,233,179,150,206, 36,177,168, 88,229, 44,181,111,160,230, + 49, 44, 91,164,161,184, 21, 21, 95,240, 48,149, 62, 54, 69, 35, 54,150,106,219,185,146, 78, 63,238,216,255,149, 64, 40,250,128, + 71, 64, 28,172,100,246, 63,174,253, 6,230,230,114,176,218, 34,160, 56, 19, 3,167, 44,207,140, 76,209,121, 2,128,183, 29,145, +191,227, 37,220,193,103, 72,242,197,167,218, 5, 53,253, 6,209, 99,226,136,158, 45, 5,172,182, 24,211, 86,237,195,214,185, 3, +240, 81,183, 38,130, 19,215, 99, 38, 2, 88, 82,215,125, 77,141, 6, 80,189, 10,237,230, 95,121, 68,128,107, 20,232,120,103,255, + 82, 31,224,174,201, 26, 1,132, 8,248,206,164,137, 95, 61,153,144, 77,190, 14, 54,249, 58,229,185,117, 0,169,247, 14, 33, 78, +129,244,251,213,139,139,183,111,255,233, 44,203,224,235,154, 82, 94,112,112,252, 91,161,148, 62,179,178,178,234,213,167, 79,159, + 11,103,206,156,177,105,214,172, 25, 0,160,124,198, 90, 96, 96, 32,188,189,189,145,158,158,142, 15, 63,252, 48, 43, 53, 53,181, + 23,165,180,218, 49,189,133,133,133,113, 7, 15, 30,116, 44, 46, 46,110,185, 96,193,130, 12,119,119,247, 2,181, 90, 77,242,242, +242, 88,131,193, 0,107,107,107, 81,203,150, 45,209,190,125,251,162,176,176, 48,143,164,164,164, 66, 0,241,117, 41,255, 39,159, +124,130,195,135, 75,155,137, 55,145, 23, 75, 40, 20, 34, 56, 56,216, 37, 52, 52, 52, 5, 0,234,146, 23,235,197,230,229,254,253, +251,184,124, 55, 25,124,173, 10,162, 76, 37,110, 28, 57,136,254, 19, 38,195, 96,168,251,104,133,251,247,239,227,143,243, 55, 32, + 19,243,241,248,241, 67, 28, 60,120, 16,147, 38, 77,122, 45, 77,142, 26, 12, 86,131, 6, 68, 36, 46,194,162,158,129, 46,115, 62, +232,216,128,167, 47, 80,130, 53,178,224, 9, 0, 7, 59, 11,252,254,251, 30,207, 61,251,246,133,181,112, 17,108,100, 13,134, 47, + 35,211,105, 73, 45,126,123,209,218,125,215, 62,248,125, 86, 16,127, 82,111, 31, 27, 0, 16,242, 25,108,248,243,161, 1,192,162, +215,217,168,118,174, 68, 82,164,199,120, 39, 91,203,133, 95,124,210,215, 38, 40,208, 27,151,111, 62,192,198,131, 97, 87, 68, 25, +216,105,242, 65,205,234, 95,157, 2, 91,233, 44, 66,176, 53,143,167, 52, 26,169,147, 80,102, 13, 93,252, 37, 64,167,134, 90,163, + 67, 82,182, 17, 73, 57,106,240,165, 66,220,137, 73, 86,217,166,225,120, 93,183,153, 16, 66, 58,122, 73, 20, 95, 45,251,206, 85, +173, 42, 50, 20,228,102, 25,132,162, 27, 2,169,153, 56,181, 54, 58, 97,201, 84,221,217, 83, 24, 0,176, 60,145,132,150,204,159, + 57, 90,150, 18,117, 6, 13, 25, 37, 8,165, 48,107,210, 23,230,102, 60, 97,167,250,194, 68, 0,168,239,100, 41, 90,245,245,231, +150, 51,230,126, 93,227, 24, 47, 95, 66,132,205, 91, 57,205,104,230,110,141, 43,225,143,112, 37, 50,225,225,149, 59,143,155,118, +105,174,128,183,171,213,116, 95, 66, 86, 70,209,218, 71, 68, 75,119,140, 1,208,171, 43,102, 17,250, 58,146, 97,173, 62, 88, 80, +233,236,193,170,168, 15,176, 49, 70, 10,194,227, 1,132, 41,157,209,152,116, 29,124, 43, 47,186,103,255, 31, 37, 63,253,180,243, +155,168, 76,202, 69,173, 56, 56,106, 32, 47, 47, 47, 66, 42,149,246,244,243,243,251,109,218,180,105,230, 35, 70,140, 80,140, 27, + 55,142, 1,128,244,244,116,118,253,250,245,202,239,191,255, 62, 63, 43, 43,107,140, 78,167,139, 52,229,134,151, 16, 18,250,243, +207, 63,103, 94,189,122,181,105,235,214,173,197, 1, 1, 1,172,181,181, 53, 95, 44, 22, 27,181, 90,173, 58, 38, 38,198,248,236, +217, 51,231,188,188,188,167, 0, 98,235,210,125,175, 80, 40,192, 48,204, 18, 87, 87,215,175,148, 74,101,179, 55, 49, 6,171, 97, +195,134, 10, 0, 79, 93, 92, 92, 26,214,182,123,240, 47, 13, 54,159,143,220,220, 92,148,164, 61,132, 36,249, 9,252,100, 12,124, +173,229,176,176,176,120, 45, 51,148,159,159, 15, 20,167,224,218,181,251,128,193, 0, 75, 75, 75, 88, 90, 90,114, 6,235,239, 50, + 88, 77, 29,200, 36,107, 17,214, 79,232,219, 64, 88,191,158, 43, 52,201,119,112, 63,169, 8, 95,182,109, 29,197, 19,155,171, 39, +140, 28, 16, 56,104,176, 7,130,218,183, 34,245,157, 45,167,175, 92,187,101, 74, 83, 71,242,249,195,116,186,193,148, 31,126,152, + 65,227,154, 56,144,159, 46, 69, 36, 79,116,149,170,192,178, 20,151, 34, 83, 17, 25,159,251, 83,116, 6,141,171,205, 70, 52, 85, +144, 96, 62,152,125,148, 82,137,165, 76, 86,216,178,133,143, 93,112,187, 22, 76,175,206,129, 16,242,128,107,183,238,227,179,181, +135,111,176, 44,237, 27,110, 98,247, 96,233,140,193,151,141, 83,233,140, 65,253, 75, 51, 6, 41,165,180,116, 22, 97,245,195,186, +120, 60,146, 86,146,112,219, 73, 96,219, 8,170,216, 75,136,207,101,145,144, 81,136, 2,190, 19, 52, 41, 41, 0,101, 19, 67, 40, +173,243,209,108,103,103,231,224,233,235,221, 96,211,142,131,208,149,228, 35, 46,228, 55, 20,229,166, 98,233,143,127, 54,112,117, +117,237,156,156,156,124,185, 22,102,205,251,194,241, 61, 14,160, 0, 79, 32,198,137,205,251,145,101,107, 6, 59,169, 16,172, 42, + 19, 19,102,140,176,236,221,125,132, 37, 0, 36, 60,190, 7,119,169,202, 36, 93,157, 45, 6,125,208,165,177, 21,244, 42,236, 56, +125, 79,205, 0,189,118,158,125, 24,219,197,199, 74,242, 65, 71,119,235, 37,202,188,247, 81,199,100,160,229, 17,172,138,136, 94, + 29,102, 15, 30,160,212,216,196,158,196,238, 11,205,144, 13,238, 30, 32, 21,242, 9,161, 69, 41,160,102,118,216,178,227, 64,145, + 72,143,109,220, 37,131,131,195, 52, 74, 74, 74,194, 9, 33,205,103,207,158, 61,108,254,252,249,239,200,100, 50, 79, 0, 40, 46, + 46,142,211,235,245, 87, 0,236,169,205,108,191, 50,195,244,148, 16, 18, 23, 27, 27,235,184,107,215, 46, 43, 0,146,178,183,213, + 0,242, 0,164,191,206, 12,194,114, 51,165, 80, 40,190,122, 83,245, 80,110,166, 92, 92, 92, 26,214,229,251, 60, 30,207, 72, 8, + 1, 33, 4, 98,177, 24, 87,175, 94,197,144,190,221, 17,125, 34, 15,205,172,228,104, 61,102, 2,246,157, 59, 7, 30,143, 7, 66, + 8,120, 60, 94,173,218, 17, 62,159,143,107,215,174,225,163, 15, 7, 67,204, 7, 44, 45, 45, 49,123,246,108, 28, 61,122, 20,124, + 62,183,154,222,223, 19,193, 34, 88,114,238,183,229, 66, 24,245, 56,246,219,183, 56,254,160, 72,251, 56, 19, 95, 54,206,196,250, +131, 40,100, 51,215,238,156,120,238,218,131, 53, 99,135,246,147,118,237,210, 29, 93,131,186,240,155,182,234,188, 16,192,134, 23, + 26,234,224,234,114,101, 24, 89,124,179,237,244,163, 9,251, 66, 98, 8,116,133, 24,218,163, 21, 53,178,248,166,134,198,255, 47, +154,150,102,242,125,215,194,194,172,161, 43, 66,252,189,139, 18, 15,207, 6,128, 81,135,167, 79,159,224,251, 29, 71,216,144, 91, +143,127,215, 26, 48, 45, 54,135, 22,155,170, 89,234,168, 12,176,148,137, 26,247,110,102,121,138, 5,133,149, 84,232, 67, 89, 35, +172,164, 2,159, 30, 77,100,167, 40,165,212,220, 76,224, 67,141,250, 26, 53, 85, 90,195,214, 29,191,252,244,221,199, 31,127, 44, +203, 74, 78,131,178,224, 1,138, 68, 46,208, 75,221, 16,123,239,138,170, 68, 99,168,177,241,174,174, 62,179,178,178, 50,194,111, +230, 96,223,143, 43,160,215,106,144,145, 92,234, 81,149, 89, 5,176,176,115, 9,171,141,166,206,192,230, 15, 26, 49, 94,104,102, + 14,179,143, 6,245, 19,197,102,107,224,175, 48, 47,189,200, 21,101, 34,250,252, 53, 4, 21,151,250,181,103, 73, 12,220, 91, 40, + 76, 42,167,185, 68, 56,173,119,128, 11,226, 18, 83,113,245, 97,202,142,103,217, 84,233,101, 75,118,196, 42,243, 38, 14,104, 91, + 15,235,142, 70,125, 90,149, 41,170, 74,211,215,145, 12, 3,208,177,116,144,187, 10, 20,232,232,235, 72,134,153, 50,115,176, 50, + 77,190, 16,195,191, 59,149,176,224,192,237,172, 1,115,134,119,178,104,223,190,143, 8, 6, 45, 10, 85, 26,125, 84, 46, 45,120, +157,125,244, 26,209, 73, 78,147,211,252,159,212, 44, 51, 59,191,151, 61,222,164,166, 18,175,228,101,122,221,109,127,177, 59, 80, +169, 84,242,203,162, 87,213, 14,114,175, 73,243,197,238,192,148,148,148,147,101,209,171,106,163, 88,149,104, 42,219,180,105, 99, +211,191,127,127, 24,141, 70, 60,121,242, 4, 9, 73, 73, 8,158,248, 41,172,172,172,112, 37, 34, 2,143, 31, 63,198, 87, 95,125, + 5,150,101,113,227,198,141,228,154, 52, 5, 2,129,174, 69,139, 22,194,247,222,123, 15, 6,131, 1,207,158, 61, 67, 74, 74, 10, + 62,251,236, 51, 88, 90, 90, 34, 60, 60,188, 66, 83,163,209, 32, 46, 46, 78,247,255,113, 44,253,123, 12, 22, 96,132, 81,143,252, +115,139,176,225, 42,116, 58, 61,124, 30,102,208,231, 47,188,191,197,207,150, 28,139,120,240, 40, 46,252,122, 87, 17, 50, 34, 75, +191, 83, 11, 98,178,104,106, 43, 55,126, 33,116,133, 22,120,118, 10,207,211, 11,139, 98,178,104,106,109, 55,130,178, 70, 2, 93, + 9,144,122, 7,161, 87, 46, 35,228,198,125,220,142,124,100, 12, 13,143,217,199,176,248, 38, 42,139, 62,169,181, 38,165,144,247, + 93,135,209,145, 79,235,181,242,118,172, 7,163, 1,148,213,195,114,232, 30,140,137,106, 95,175,149,151, 85,189,210,200,149, 30, +214,159, 92, 4,190,147, 84,171,119, 59, 81,183,173,163,167,248,253,194,188,236,182,221, 58,183,147, 89, 54,233,141,172,167, 49, +120,114,255,154, 42,252, 65,108,232,237, 68,221,107, 69, 71, 92, 92, 92,222,233,214,185, 49,134, 78,248, 2,186,146,124, 60, 11, +249, 5, 69, 57,105,184, 26, 38,199,163,130,130,118, 0, 76,142, 96,133, 38,232,155, 2, 64,199,250,194, 68,115,104,156, 70,246, +235, 15, 49, 81,131,213, 20,128,148,100, 33, 54, 69,155,255,254,143, 73, 70, 0,144,138, 9, 95, 70,243, 45, 76,209,245,117,183, +109, 36,229,233,177,243,220, 67,176,108,233, 50, 75, 44,139, 45, 59, 47,198, 78,252,230, 35,127,248,214,179,110, 65, 8, 33,181, + 9,237, 19,138, 78,183,247,125,237,163,190,176, 16, 96,117,184, 54,221,198,167,211,134,156, 78,117,141,132, 69,166,208, 20, 0, + 19,155, 40,200,214,233, 27, 78, 47, 12, 60, 23,213,113,214, 39, 3, 44, 64,185,133,209, 57, 56, 56,254, 43,145,192, 9,115,231, +206,221,202,227,241,236, 1, 16, 74, 41, 52, 26, 13,255,199, 31,127, 20, 24, 12, 6,134,199,227, 25, 37, 18,137, 33, 60, 60, 92, +207,178,108,166, 78,167,155, 80,147,166, 86,171,141,221,180,105, 83, 3,189, 94, 95, 49,227, 80,163,209,224,151, 95,126,129, 70, +163,129, 88, 44,134, 92, 46,199,179,103,207, 64, 8,209, 25,141,198, 88,110, 79,188, 73,131, 69,241,117,135,143, 22, 45, 2, 64, + 64,177,248, 21,115, 5, 0,136,200,166,202,166, 14,228,179,166,173, 58, 47, 42,255, 78,109, 11,160, 54, 26, 7,183,106,238,189, + 23, 0, 52,212,248, 81, 93, 54,162, 64,163,250,160,101,171,118,251, 88, 74,249, 6, 74,127, 98, 88, 28, 82, 27, 16,109,202,204, +185, 42,239, 60, 50,242,194,203, 23,112,102, 65,255,211, 45, 88,150,142,129, 82, 74, 43,186, 5,191,149, 32, 43, 95, 83, 99, 30, +167,107,113,154,238,173,234, 9,199,159,189,126,111,130,209, 72,157,120, 60,146,166,210, 26,182,190,174,185, 42,187,251,186,236, +235, 64,206, 70,180,112,236, 97, 39, 45,139,106,149, 0, 89, 37, 56,155,156, 81,120,185, 46,154,185,197,250, 1,243,215, 31,253, + 83, 36,224,241, 65,105,105, 34, 80, 74,161,214, 25,115,202, 77,152,159, 45, 81,204,254,195,176,151,199, 35, 9, 53,233,221,124, +156,186,110,232,202,243,159, 63,140,207,253,233,121, 46,125, 0, 0,207,115,233,131,134,182,100, 97,108, 90,225,231, 15, 18,114, +191,173,237,184, 9, 74,112,181,213,208, 69,127,121,237,117,235, 51, 90, 73,239, 3, 24,216,212,129,116, 31, 58,235,251, 89,132, +128, 91, 38,130,131,227, 95, 68,121, 20,139, 97,152, 37,111, 74,179, 60,138, 5,224,105, 45,190,115, 19, 64,243, 55,185,109,225, +225,225,217, 0,178,185,189,252, 95, 50, 88, 15, 51,232, 22,152,176,152,179,169,159,171,242,251, 74,122, 30,128,237,235,108, 68, +153,134,205,155,172,152,136,116,186,240,239,168,240, 50, 51,245,183,140,229,137,202,160, 61, 1,160, 81,163, 70,244,233,211,167, +160,148,190, 86,246,221,232, 76,122, 31,175, 44,185, 80,153,201, 6,208,201, 20,189,152, 44,250, 13,240,215, 46,224,167,217,116, + 41,128,165,117,218,230, 58,102,106, 55,249,216,202,160,231,128,154,179,233,115,112,112,188,157, 38,235, 77,107,190,238,194,207, + 28,111,129,193,226,248,223,229,201,147, 39,220,178, 6, 28, 28, 28, 28, 85, 99,252, 27, 52,185,164,195, 28, 47,193,112, 85,192, +193,193,193,193,193,193,193,241,102, 33, 0,130, 43,181,226,181,152, 29, 64, 8, 9,174,181,213,175, 65,159,211,228, 52, 57, 77, + 78,147,211,228, 52, 57,205,183, 79,179, 38,237,183,102,118, 34,125, 97,240,242,155,126, 0, 8,230, 52, 57, 77, 78,147,211,228, + 52, 57, 77, 78,147,211,252,183, 61,184, 46, 66, 14, 14, 14, 14, 14, 14, 14,142, 55, 12,103,176, 56, 56, 56, 56, 56, 56, 56, 56, + 56,131,197,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112,112, +212, 29, 82,203,149, 73, 56, 56, 56, 56, 56, 56, 56, 56, 56,106,128,139, 96,113,112,112,112,112,112,112,112,112, 6,139,131,131, +131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224,224,224,224,224, 12, 22, 7, 7, + 7, 7, 7, 7, 7, 7,103,176, 56, 56, 56, 56, 56, 56, 56, 56, 56,131,197,193,193,193,193,193,193,193,193,241,223, 55, 88,132, +144, 96, 78,147,211,228, 52, 57, 77, 78,147,211,228, 52, 57, 77,206, 96,113,112,112,112,112,112,112,112,112,112, 6,139,131,131, +131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224,224,224,224,224, 12, 22, 7, 7, + 7, 7, 7, 7, 7,199,127, 9, 2,160,210,153, 0,148,210,243, 38,139,212, 97, 54, 65, 77,250,156, 38,167,201,105,114,154,156, + 38,167,201,105,190,125,154, 53,105,215,198,127,252,163,161,148,254,109, 15, 0,193,156, 38,167,201,105,114,154,156, 38,167,201, +105,114,154,255,182, 7,215, 69,200, 97,106,148,210,145, 16,226,200,213, 4, 7, 7, 7, 7, 7, 71,205,240,223,164,152, 15, 33, +109,214,188, 83,111, 81,159,203, 9,189, 76,104,176, 25,252,103, 12, 24, 91, 26, 76, 43,181,197,175, 97, 2,222,184, 38, 7, 64, + 8, 89, 65, 8,230,148,253,191,154, 82,250,197,219,184,157,115,230,204, 25,236,239,223, 10,214,146,116,180,242,122, 2,228,238, + 1,172, 63,192,130, 51, 93,208,202,191, 3,174,220, 77,194,149, 27, 15, 17,182,185, 63, 62,153,177, 8,106,181, 14, 89, 89, 74, +220,191,118,250,224, 91,180,175,219, 10, 4,130, 15,172,173,173,205, 51, 50, 50, 46, 0,248, 19,192,187, 14, 14, 14,221,114,115, +115, 11,245,122,253,126, 74,233,141,186,104,191,211,146,204, 21, 9, 5, 99,213, 58,253,170,107,247,232, 47, 65, 1,196,214,192, + 98,165, 68,200,239,164,209, 26, 86, 95,189, 79,127,170,101, 89,201, 43,209,248, 90,159,235, 7, 9,225,153,250,217, 63,172,173, +189, 45,228,242, 11, 18, 30,239,121, 74, 73,201,136,193, 25, 25, 73,131, 41, 53,190, 77,231, 64,215,174, 93, 71,243,120,188,101, + 0, 96, 52, 26,191,188,120,241,226,111,111, 66, 87,161, 80, 12,163,148,202,202,246, 91,177, 82,169,220, 99,234,119, 3, 2, 2, + 18, 0,212, 43,123,154, 24, 30, 30,238,110,202,123, 28,181,227,206,157, 59,212,221,221, 29,205,155, 55,127,156,150,150,246, 61, +165,116, 11, 87, 43,255, 16,131,213,152,144,134, 19,251,180, 63,215,227,253,158, 50, 83,140,144,139,139,203, 74,123,123,251, 73, + 37, 37, 37,106, 0,148,199,227,209, 38, 77,154,128, 16,130,242,235,166,209,104,204,124,244,232, 81, 51, 83,205,213,155,210,244, +246,246,190,195, 48,140,235,139,215,239,154,254,103, 89, 54, 57, 42, 42, 42,176,166,114, 58, 59, 59,247,100, 24,102, 94, 77,159, + 99, 89,118,101,106,106,234,153,234, 62,211,188,121,243,187, 50,153,204,145, 97, 24, 82,213,103, 94,108,115, 12, 6, 3, 45, 41, + 41, 73,127,248,240,161,127, 45, 26, 49, 71, 66, 48,135,101, 41, 3, 0, 12, 67,230, 90, 91, 91,239,206,205,205,141, 42,127,191, +236,119,210,107,115,188,184,184,184,140, 2,240, 57, 0, 10,224,187,148,148,148, 29,181,249,126,163, 70,141,238, 8,133, 66, 87, + 30,143, 71, 94,221, 39,149, 61,103, 89,150,106,181,218,228,199,143, 31, 87,185,143, 66, 66, 46, 31, 88,189,122,245,221,109, 63, +255,228,223,162,229, 96, 48,210, 46,208, 81, 11,220,141,215,160, 85, 11, 2,202,178, 80, 23,100,128,101, 89,148,168, 53,184,112, +228,151,187,245,234, 55,240, 71,233, 88,198,183,193, 92,245, 26, 53,106,212,242, 85,171, 86,217,137, 68, 34,102,255,254,253,237, + 62,251,236,179,177,235,214,173,115,249,224,131, 15,204,181, 90, 45, 59,119,238,220,119, 8, 33, 95, 83, 74,143,214, 70,187,125, + 75,210,182,113,125,231,175,166,142,232,138,207, 87,236,157,218,177, 57,201, 50,147, 9,183,188,223,169,129, 85, 83, 79,107,124, +189, 53,116, 26,128,159,106, 81, 86,226,230,230,214,210,209,209,177,190, 74,165, 50, 2, 64,211,166, 77, 41,143,247,178, 95,210, +233,116,186, 71,143, 30,157,124,221,186,249, 92, 34,105,211, 73, 38, 61,247,197,196,113,102,185, 89, 89,142, 91, 15, 30,142, 56, +232,224,224, 55, 24,136,127,155, 26, 4, 30,143,183,236,244,233,211,206,148, 82,244,236,217,115, 25,128, 55, 98,176, 40,165,178, +212,212,212,242,107,160,172,150, 95,175, 23, 30, 30, 94,110,168,234,213,226, 61,147,105,215,174,157,196,160,211, 77,230, 49, 76, + 15, 10, 52, 71,233, 73, 29,105, 4,206,241,249,252, 31,194,194,194,212,111,187, 25, 56,119,238, 28,198,143, 31,143,200,200,200, +198, 39, 79,158,220,172, 80, 40,166,164,166,166,118,161,148,102,114, 86,233,191,104,176,154, 18,226,208, 47,160,241,213,201, 31, + 13,150,178, 7,215, 19,140, 94, 80,173, 17,114,118,118, 94,213,169, 83,167,177,187,118,237,146,253,241,199, 31, 50, 15, 15, 15, + 8,133, 66,240,120, 60,240,120, 60, 48, 12, 3, 62,159,143,119,223,125,215,164,134,235, 85,205, 11, 23, 46,200,188,189,189,255, +210,200, 50, 12,131,222,189,123,215,168,201, 48,140,235,221,187,119, 29, 36, 18, 73,133, 73, 97, 89,246,165,199, 11,253,208, 48, + 24, 12,232,212,169,147, 73,117,197, 48,204,188,232,232,232,119,138,139,139,171,237,187, 45,211, 59, 83,131,150,226,250,213, 11, + 14, 68, 23, 7, 24,114, 64,121, 54,128,200, 19, 96,196,149,126, 62, 39, 39, 7, 93,186,116,225,189,206,190,238,219,183, 31,161, +148, 30, 81, 40, 20, 23,178,178,178,204, 9,193,135,117,140,108,125, 17, 19, 19, 99, 78, 41, 69,227,198,141,231, 1,168,149,193, +226,241,120,174,103,207,158,117, 16,139,197, 21,251,185,170,191, 70,163, 17, 58,157, 14,189,122,245, 50,212, 96,106,241,195,214, + 95,252,213, 26, 61,212,212, 3, 15,163,139,113,234,212, 17,212, 47,214, 35,246,129, 26, 44,171,128,186, 48, 3,148, 82,168,212, + 90,180, 8,122,223,159,101,223,158, 0,169,165,165,229,224,117,235,214,217,255,244,211, 79, 5,143, 31, 63,214,253,248,227,143, +246, 19, 38, 76,240,209,233,116,152, 56,113, 98,102,227,198,141,133,235,214,173,179, 63,114,228, 72, 79, 0,181, 50, 88,124,130, +111, 62, 28,208, 3,106, 61, 3,189,222, 96,239,108,111,254,251,244, 81, 65, 2, 74,181,216,121, 52, 28,122, 3,251, 75,109,205, + 85,239,222,189,221,183,108,217,194,143,142,142,230, 55,105,210, 4, 70,163,177,226,193,178, 44,140, 70,163,201,231,101,117,140, + 5,188,157,172,173,207,181,233,211,215,204, 73, 38,133,248,249, 83,244,183,150,153,159, 76,205,218, 5,160,253,219,214, 40,240, +120, 60, 36, 37, 37,193,210,210,210, 44, 40, 40, 40,149, 16,178,248,210,165, 75,219,254,142,223,122,157,200,214,155, 34, 32, 32, +160, 53,159, 97, 14, 45,156, 63,213,201,175,101, 75,158,131,163, 61, 98,158, 36, 66,200, 99,131,159, 62,138, 9, 90,254,237,150, +233, 1, 1, 1,239,135,135,135,223,122,219,246,181,251,160,159, 54,179, 6,221,164,210,103, 86, 0,182,161,176,176, 16,159,124, +242, 9,142, 30, 61,218,164,109,219,182, 43, 75, 79, 1,142,255,138,193,242, 37, 68,214,194,195, 41,228,155,207, 39, 88,211, 83, +191, 50, 37,217, 25, 16, 86, 99,132,156,156,156,150,118,234,212,233,163, 93,187,118, 89, 19, 66,112,110,234, 88, 88,235,212, 80, +124,181, 26,214,118,246,208,206, 27, 15,115,163, 1,126,151, 34, 76,189,216,254, 69,243,241,227,199,200,205,205,133,157,157, 29, +164, 82, 41, 36, 18, 9,132, 66, 33, 68, 34,145,169,154,144, 72, 36, 56,127,254, 60,248,124, 62,120, 60, 30,248,124,126,197,227, +197,231, 60, 30, 15,142,142,166, 15, 77, 98, 89,118,165,143,143,143, 95, 76, 76,140, 69, 94, 94, 30,218,182,109, 91, 64, 8,137, +120,225, 78,207, 47, 34, 34,194,194,228,198, 70, 23,135,162,196, 31, 65,115, 15, 1, 86,131, 96,180, 24, 10, 53, 60, 43, 26,152, + 23,255,178, 44, 91,151, 59,207,116, 66,200,234,254,253,251,205, 3, 8,130,131,131,139,166, 78,157, 74, 31, 63,126,220,227,189, +247, 6,212,127,242,228,105,153,217, 35,115, 8, 33, 27, 76,141,100, 81, 74,197, 0,112,245,234, 85, 80, 74, 37,117, 57,246,196, + 98, 49,194,194,194, 42, 34,148, 12,195,128, 97, 24,240,120, 60, 28,123,106,135, 98, 45,131,146,244, 7,248,180, 95, 61,120,122, +122,254,197,112,255,101,223, 80,138, 41, 19,198,222, 93,178,106,189,191,209,104,196,169, 83,167,176,118,237, 90,104, 52, 26, 4, +117,235,129,231,180, 5,154,121,218,129,101, 89,168,212, 90, 68, 92, 62,116, 87, 81,207,211,255,109,185, 24,228,231,231,255,238, +237,237,205,203,204,204,188, 8, 32, 78,175,215,111,250,253,247,223, 29, 62,254,248,227,140, 93,187,118, 77, 5,224,182,102,205, +154,158, 69, 69, 69,251,106,163,219,169, 5,233, 19,216,178, 89,219,122,110,110,184, 28,122, 11, 66,145,192,106,242,232,126,144, +203,249,248,246,167, 19,108, 66,114,206,212,171,247,233, 14, 19,207, 77,226,236,236,236,215,163, 71, 15,183, 45, 91,182, 8, 1, +224,193,131, 7,200,200,200,128,173,173, 45, 36, 18, 9, 4, 2, 65,197, 13,219, 27, 49, 87,118,118, 55, 15, 30, 60,104, 6,189, + 30,155,190, 93,141,126,170,124,152, 17, 64, 11, 82,255,109,106, 12, 2, 2, 2,188,187,116,233, 34, 49, 26,141, 40, 46, 46,198, +150, 45, 91, 44,205,204,204, 44,123,247,238,189, 8,128,201, 6,171,125,251,246,233, 90,173,214, 1, 0, 68, 34, 81, 70,104,104, +168, 35,128,146,250,245,235,155,149,125, 68, 85,203,200, 86,226, 11,209,169,196, 90,188, 87, 35,129,129,129,173,154,120,215, 63, +191, 98,197, 98,121, 94, 65, 26, 44, 45,211,193, 32, 15,219,182,253, 0, 51, 51, 11, 44, 90, 52,159, 31,216,166,141,203,244,207, +230,159, 15, 8, 8, 8,126,219, 76, 22,107,208, 77,106, 17,248,159,123,132, 29,231, 54, 66, 99,233,143,148,197,139,177,126,253, +122, 52,106,212,168, 53,103,147,254, 75, 6, 43,136, 16,190,171,141,252,216,230, 69,211,235, 51, 97,199, 5,170,196,167, 80,170, +141,176,250,207,201,115,254,197, 11, 35, 0,198,209,209,113,242,158, 61,123, 44,202, 27,187,198,196, 8, 43,232, 80,191,105, 83, + 72, 45,173,144,102,208,129,234,117, 16, 10, 4,149, 54,136,166,104,150, 71,192,132, 66, 33,132, 66, 97,197, 5, 87, 40, 20,214, +168,249, 82,229,240,249, 96, 24, 6,231,206,157,131,193, 96,192,224,193,131,255, 98,174,248,124,254, 75, 93,144, 53,105,166,166, +166,158,113,113,113,137,160,148,190, 99, 52, 26, 65, 8,137, 72, 73, 73,233, 92,254,190,179,179,115,207, 22, 45, 90,204, 99, 89, +118,165, 73,229, 52,100,131,230,236,129,121,187, 44, 20,132,217,129,200,130,193, 18, 15, 68, 62, 73,197,197,219,241,200,204, 45, + 70,128,183, 61,122,182,111, 0,163,209,104,242,182,191,136,139,139,203,213,204,204,172, 33, 93,187,118, 69, 78, 78,142, 97,241, +226,197,104,209,162, 5,188,189,189,171, 50, 79, 53,106, 18, 66,148, 17, 17, 17, 30, 42,149, 10,132, 16,165, 9,134,236,124,101, + 70,248,247,223,127,135, 90,253,215,232,189,117,231,229,248,124,144, 59,198,124,186, 3,171, 31,239,199,230,205,155,241,234, 16, +157, 87, 53, 89,150,197,146,149,235,253, 85, 26,109, 69, 93,105, 52, 26,132,133,133, 65, 83, 82,136, 75,187,198, 85, 68, 47, 85, +106, 45, 92,253,186,251,215,164,249, 38,248,255,210,164,148,134, 0, 8,121,161,126, 23,236,218,181,107, 8,128,195,148,210, 80, + 0,161, 0,246,214,186,156, 4, 99, 62, 24,244, 30,248, 66,115, 60,122,154,140,206,237,252,225,232,224,128,136,232, 88, 36,164, +228,164, 19,130,209,189, 58,136, 87,170, 84,218, 5, 87,238,209,159,107,210,116,118,118,246,220,182,109,155,224,197,136, 11,143, +199,123,233, 92, 47,127,173, 50,147,101,106,125,142, 5,188, 93,172,173,111, 30,253,242, 75, 89,218,175,191, 34,191, 99, 71, 8, + 90,183,197,246,115,167,145,153,171, 82,107,141,108,183,183, 97,191,151,155,171,160,160,160,208,165, 75,151, 90, 37, 37, 37,225, +250,245,235,240,240,240, 64, 73, 73, 9,106, 26,218,246,170,166, 86,171,117,120,161,219,206, 1, 0,210,210,210,246,226, 63, 93, +233,180, 54,229,172,110, 92, 85,109,198, 92,189, 90,206, 6, 13, 26,136,236,172,173, 15,172, 92,181, 68, 30, 21,125, 5, 45, 91, +180,133,220,210, 23,172, 49, 13,217, 57, 69,200,125,170,196,210,165,171,177,104,241,151, 88,189,106,169,124,232,176, 49,135,218, +181,107,215,240,197,238,194,255,245,253,206,240,133, 91,238,223, 9,157, 4, 0, 5,209,135, 49,125, 88,123, 20, 22, 62,197,196, +137, 11,145,146,146,130, 39, 79,158,132,255,127,150,147, 51, 88, 47,152,155, 64,177, 96,247,222, 69, 83, 91,139,227, 35, 69,154, + 7, 97, 80,106, 88,250, 91,146, 33,229,219,106,190, 87, 82, 82,162, 61,122,244, 40,206, 78, 25,139,134,196, 0,155,175,214,192, +209,197, 5,121, 99,222, 69,161, 94,135, 6,167,110, 65, 44,151, 67, 36,147,215, 24,113,120, 81,243,210,165, 75,120,248,240, 33, +248,124, 62,228,114, 57,228,114, 57,196, 98, 49, 68, 34, 81,133,185,170,202, 96, 85,113,240,128,199,227,225,193,131, 7, 72, 72, + 72,128,149,149, 21,174, 95,191,142,110,221,186,253, 37,138, 85,199, 3,190,210,136, 82,217,184,171, 51,166,106, 64, 96, 7,216, +124,132,194, 27, 10,192,122, 4,244,176,130,209,104,196,189,167,217, 24,255, 81, 95, 0,192,228, 5, 63, 34,184, 77,253, 10,115, + 80,139,240,189, 25,128, 57,141, 26, 53, 26, 58,124,248,112,131, 80, 40, 68,113,113, 49, 84, 42, 21, 30, 60,120, 96,232,219,183, + 95, 81,255,254,253,228, 39, 78,156, 96, 41,197,234, 90,142,195, 74, 87, 40, 20, 30,101,221,176,233,117, 56,254, 64, 8,193,254, +253,251, 43,125,127,244,218, 40,240, 75,135,103, 97,203,150, 45, 48, 26,141,160,148,146,154,234,243,171,121, 51,238, 78,159,187, +196,159,101, 89,116,235,214, 13,179,102,205,194,179,103,207, 48,100,200,144,138,104, 32,165, 20, 42,141, 6, 41,145,231,239, 58, +187,213,247,127, 91, 47, 14,148,210,147, 0, 78,190,190, 16, 92, 28,156,220,192, 80, 61,148, 25,217,120,175,111, 15,240,132,114, + 60, 79,202, 66, 11, 95, 47,231,225,239,118,112,230, 17, 3,230,172,220, 51, 25,192,207, 38,156,239,198,232,232,104,193,253,251, +247,193,227,241, 96, 97, 97, 1,169, 84, 90,113,142,191,104,184, 94, 39,114,229, 98,109,125,243,207, 69,139,100, 13,175, 95, 71, +195,131, 7,177,236,202, 21,168,122,247,198,190, 71, 79,212, 40, 41, 9,254, 86,173,142,249, 95,222,191,221,187,119,159, 0, 96, + 17,165, 52, 47, 40, 40,200,113,217,178,101,214, 41, 41, 41,136,138,138,194,254,253,251, 51, 13, 6,131, 1, 0,161,148,126,253, + 6,142, 37,246,197,200, 86,251,246,237, 51, 66, 67, 67, 29, 9, 33,197,229,145, 43, 66, 72,113, 29,162,110,130,130,188,212, 79, +173,101,116, 0,159, 49,175,111, 40, 40,122,158,107, 96,142, 90,216, 59,126, 31, 30, 30,174,175,238,187,150,150,150,159, 44, 91, + 50, 83, 97,103,199, 34,168,115, 87,164,166,235,176,124,230, 40,100,103, 23,226,231,237, 43, 0,136,160, 51,240,240, 78,208,251, +112,112,112, 65,167,142,157,156, 46, 95,187, 58, 5,192,183,111,203, 57,158,112,248,147,201,132,144,111,234,213,171,119,249,199, + 21, 43, 26,118,235, 86,122,207,112,225,194, 5,252, 50,108, 24, 22, 3, 35, 55, 18,146, 58,237, 45,157,216,244,143, 53, 88,245, +197,242,203,219, 62, 27,210,214,214, 88, 34,208, 94, 59,134, 20, 13,107,248,246,169,174,228,118, 30, 29,246,109,229, 39, 24, 37, +132,176,132, 16,214,211,211, 19, 22,122, 53,172,168, 22,142, 10, 5,204,109,108,145,163, 47,141, 92,137,100, 50,136,100,114,147, + 46,142, 47,106,250,250,250, 34, 61, 61, 29, 34,145, 8,114,185, 28,230,230,230,127, 49, 87,166, 94,112, 9, 33, 96, 89, 22,124, + 62, 31, 17, 17, 17,232,216,177, 35,220,220,220,176,127,255,126,244,236,217,243, 47, 93,134,166,154,182, 87, 27,243, 23, 35, 74, +229,131,223, 77, 25,220,254, 18,162, 6, 48,152,127, 0, 70,218, 13,122, 88, 66,205, 58,149,118, 7, 82,138,147,183,210,241, 56, + 33, 27,172,145,173,117, 23,161,179,179,115,128, 68, 34, 89, 61,111,222, 92, 69,139, 22, 45,144,153,153, 5,150,101, 33,151,203, +161, 82,169, 96,110,110,142, 14, 29, 58,164, 45, 94,188, 56,142, 82,244,166,148,166,253, 55, 14,224,179,103,207,190,212, 61, 88, +254, 40, 78, 77,198,152,105,187, 32,226, 3, 17, 17, 17,240,241,241,169, 57, 92,206, 82, 76,155,251,181,191, 90,163,133, 72, 36, + 66,251,246,237,209,182,109,219,138,113,113,229, 6, 85,167,211,193,104,100,225,228,219,213,159,188,133, 23, 5, 66, 72, 43, 0, + 31, 91, 90, 90,122,148,148,148,164,233,245,250,253,101,166,191,167, 64, 32,248, 64, 42,149, 58,229,231,231,199, 3,248,153, 82, +122,187, 38, 61, 51,137,196, 86, 44,177, 0,107,208,128,207,231,195,205,173, 62,168, 81,139,220, 2, 21, 70, 15,237,143,187, 17, +209, 56,125,233,134, 65,175,103, 55,154, 90, 70,111,111,111,100,103,103,131,199,227, 65, 42,149, 66, 38,147,161,113,227,198, 72, + 74, 74,170, 48, 87,117,237, 34, 44, 51, 87, 55,202,205, 21, 61,120, 16, 49, 50, 25, 60, 37, 18,124,249,235,175,197,185, 5, 5, +109,126, 1, 98,222,130, 93,253,245,169, 83,167, 28,248,124,190,147,209,104, 68, 98, 98, 34, 30, 62,124,136, 13, 27, 54,164, 23, + 22, 22, 6,133,135,135,215,105, 27, 69, 34, 81, 70,121,228, 74, 36, 18,101, 84, 23,217,122,157, 49, 87,174,174,174, 94, 46, 14, +226,115,191,109,152, 90,207,175,101,107,198,140, 39,207, 45,126,150,222,241,214,141, 27,237, 23,252,124,112,138,171,171,107,143, +228,228,228,103, 85, 54,126, 12,211,187,133,127, 75, 62,104, 26,248,162,142, 88,189,106, 40, 50,179, 10,144,155, 83, 8,161, 80, + 6,173,158, 7, 35, 75,208,190, 99, 39,252,186, 99, 31,154, 54,109,198,227, 1,221,223, 38,131, 85, 22, 1, 94,249,199, 31,127, + 52,148, 72, 36, 88,182,108, 25,204,205,205,113,227,155,111,240,139, 80, 8, 51, 0, 91,116,186,121, 0, 56,131,245,255,101,176, +100,142,141,135,237,253,168,123, 7, 95, 79, 23, 70,191,127, 3,146, 75, 12,234, 69,143,117,234, 71,133,244,221, 40, 74,175, 87, +231, 43, 8, 33, 84, 40, 20,194,113,238, 55,112,111,214, 28,197,227, 7, 33, 71,175,131,215,137, 27, 16,203,229,120,212,221, 31, + 84,171,197, 59,143, 50, 76, 53, 46,148, 16, 66, 1,192,222,222, 30, 66,161, 16, 18,137, 4, 98,177, 24, 98,177,184,194, 88,137, + 68, 34,136, 68, 34,147,205, 16,203,178, 40, 44, 44,196,243,231,207, 49,126,252,120, 72,165, 82,148,133,186,225,238,238, 14, 62, +159,143,148,148, 20, 92,188,120, 17,158,158,158, 16,137, 68,181,106,107, 95,104,176,253, 92, 92, 92, 46, 19, 66,252,238,220,185, + 99, 17, 24, 24, 8, 83, 35, 88,165,173,161, 16, 26,184,131, 37,110, 47,141,181,210,235, 13, 47,109, 75,121,244,197,196,200, 85, +247,134, 13, 27,110, 88,181,106, 21,227,234,234, 10,150,101, 97,109,109,141,146,146, 18,100,101,101,195,215,215, 23,110,110,110, + 88,181,106, 21, 0,236,253,111,153, 43,160,180, 59,184,220, 96,189,104,180,166,189, 91, 15, 57, 57,114,240,120, 76,133, 97,174, +113,159, 83,138,141,171, 22,221, 29, 62,126,150,255,140, 5,171,161,214,232,160,210,104,161,214,104,161,214,232,202,254,106, 81, + 62,176, 61, 45,234,226, 91, 23,193, 34,132,244, 11, 14, 14,222,180,118,237, 90, 39, 39, 39, 39, 65,102,102,166,225,135, 31,126, +232,249,195, 15, 63, 68, 77,153, 50,197,119,202,148, 41,214,246,246,246,252,180,180, 52,253,204,153, 51,123, 18, 66,230, 81, 74, +247, 86,123,189,144,153,219,240,132, 50, 16,194,135,149,165, 53,248, 34, 25, 88, 3, 31, 70, 22,176,176,180, 71,232,221,131,184, + 30, 89, 56, 33, 35, 27, 7, 76,185,169,106,214,172, 25,229,241,120,176,181,181,125,169,107, 16, 0, 28, 29, 29, 81, 80, 80, 0, + 30,143, 87,241, 90, 93,204,213,177, 69,139,228, 13,202,205,149, 84,138, 8, 79, 79, 44, 75, 72,200,203, 42, 40,232,248,150,152, +171,138, 27,135,184,184, 56,148,148,148, 32, 52, 52, 20,135, 14, 29,202,124,213, 92, 5, 7, 7,143,147,203,229,139, 85, 42,213, +234, 51,103,206,108,168, 73,183,108,204,213, 27,163,178, 84, 12, 1, 1, 1, 2, 39, 91,222,153,179,135,215,185,155,179,247, 8, +226, 63, 1,158, 20, 60,148,223,116,120,167, 91,171,190, 76,243,111,166,123,244,158,255,221,153,128,128,128,198, 85, 69,178, 40, +165,254,102, 50, 57,128,116,132,223, 9,169, 48, 87,217, 57,249,208,232,120,208,104, 9,212, 58, 6, 93,131,123, 97,211,143,191, + 35, 37, 61, 27,229, 51, 12,223, 38, 26, 53,106, 20,224,226,226,130, 25, 51,102, 64,189,103, 15,138, 0,244, 3,240,135, 78, 7, + 0, 48, 7,102,113, 86,233,255,201, 96, 89, 57, 53,238,188, 96,238,244,245, 29,223,239,197,164,143,107,135,188, 34,141,102, 78, +148,129, 77, 46,169,209, 92,129, 82, 74,125,124,124,192, 48, 12,228,150, 86, 48,179,176,128,250,133,200,149, 88,110, 14,170,213, +130,213,105, 33, 52,241,226, 88,174, 73, 41,133,153,153, 25,132, 66,225, 75, 93,131,229,198,170, 54, 17, 44, 0,200,203,203,195, +129, 3, 7,208,186,117,107, 72,165, 82,240,249,124,248,249,249, 33, 58, 58, 26, 94, 94, 94, 32,132,224,143, 63,254,192,192,129, + 3,241,236,217, 51,248,250,250,202,235, 98,176,206,157, 59,103, 65, 41,125,135, 82,138,172,172,172, 58,237, 68,150,101, 81, 84, + 84,132,179,103,207, 34, 53, 53, 21,142,142,142,200,205,147,194, 82,209,164,244,183, 94, 48, 89, 38, 50,185, 95,191,126, 12, 33, + 4, 42,149, 10, 98,177, 24, 50,153, 28,230,230, 22,240,246,110,140,148,148, 20,244,232,209,195, 24, 27, 27,187, 71, 40, 20,110, +172,109,121, 27, 52,104, 96,158,151,151,215,183,126,253,250, 66, 0, 48, 51, 51,235,231,225,225, 97, 25, 31, 31,159, 95, 75, 51, + 80, 97,172, 8, 33, 21, 51, 80, 25,134, 1,159, 97,224,236,228, 80,241,188,108,219, 73, 77,245, 56,108,220, 44,127,214,168,197, +206,181, 35, 65, 12,217, 48,192, 18, 26,184,192, 96,228, 85, 24, 88,153, 76,134,166,157, 63,120, 43, 35, 88, 66,161,112,212,246, +237,219, 93,126,251,237,183,188,163, 71,143,230,183,105,211, 70,182,126,253,122,135, 77,155, 54,117,209,106,181,152, 49, 99, 70, +198,205,155, 55,139, 7, 12, 24, 96,185,109,219, 54,151,134, 13, 27,190,139, 74,198,101, 17, 66,100, 0,134, 2,248, 40,168,181, + 37, 63,175, 80, 5,214,160, 69, 92,252,115,228, 23,105,193, 26,117, 72, 76, 86,162, 72,109, 68,118, 78, 33,252,252,123,124, 31, + 18, 18,242, 37, 33,100, 62,165,244,120, 77,229, 52, 26,141,184,113,227, 6,174, 95,191,142, 43, 87,174, 32, 33, 33,161,226, 61, + 11, 11, 11,156, 59,119, 14, 93,186,116,121,163,230, 42,241, 45, 50, 87,101,215,160, 69, 61,122,244, 88,100,107,107, 43,217,184, +113,163,165,187,187, 59, 12, 6,131,246,213,200, 85, 96, 96,224,130, 5, 11, 22, 56,191,247,222,123, 83, 1,108,168,235,239, 85, + 21,217, 50,129,191,164, 98,200,204, 76, 27,247,253,246, 81,118, 50, 97,130, 18, 79,190,115, 41,139,197, 0, 37, 5, 64,200,110, +144, 14, 11,159,143, 14,158,108,189,234,232,166,113, 0, 54, 87, 37, 28,251, 44, 9, 91,182,108,194,103, 51, 70,227,215,159, 87, +131,101,249,208,232,121,168, 87,191, 45, 52, 58, 22,132,225,163,133,127, 32, 46,133, 92,133,128, 1,166, 79,184,249,214,153,128, + 39, 79,158,220, 74, 72, 72,240, 89,184,112, 33,126,117,113,129,185,185, 57,102, 46, 90, 20,102, 48, 24,222,186, 25,178,255, 88, +131, 21,224,237,245,141,165,141,245,216,246,173,154,216,206,156, 58, 78,240, 44, 77,141,139, 29,191,200, 59,184,106,174, 60,137, +202,167, 36,208,188,235,181,137, 58, 24,150,204, 68,182, 81,139,250,199, 66, 33,150,203, 17,211, 51, 16, 84,171, 69,135,187, 9, + 16,203,229,224, 75,204,234,114, 2,191,212, 29,248,234,115,134, 49, 45,113,189, 78,167,179,234,222,189, 59,186,117,235,134,247, +223,127,191, 98,204, 85,203,150, 45,177,119,239, 94, 12, 26, 52, 8,247,238,221,131,179,179, 51,124,124,124,224,227,227,131,139, + 23, 47,214,250,238,209,104, 52,162,103,207,158, 5,132,144, 8, 74,169,223,173, 91,183, 44,106,171, 81,222,216,156, 61,123, 22, +125,251,246,133,151,151, 23,194,195,195,113,246,235,111, 33,181,169, 7,192, 10,172,209, 8,173, 86, 11,134, 97,106, 28,131, 21, + 20, 20,196,231,241,120,141, 27, 52,104,128,204,204, 76,100,102,102,194,222,222, 30, 10,133, 2, 14, 14, 14, 88,187,118, 45,214, +175, 95,127,139, 82,186, 50, 45, 45,237, 81,109,247,145, 66,161, 8,182,182,182,254, 86,165, 82, 9,203,203, 66, 8, 17, 56, 59, + 59,135, 41, 20,138,121, 74,165,242, 88,109, 12,150, 78,167, 3, 33, 4, 39,226, 20, 40,214, 18, 20, 36,135, 99,250,187,238, 47, + 25, 46,129, 64,240, 82, 90,141,170, 13, 22,197,158,237,223,221,157,247,197,199,254,200,217, 5, 67,246, 46, 16,235, 97, 56,244, +176, 23,126,191,105, 11, 0,240,118, 98,240,221, 88,249, 91, 27,193,210,233,116,219, 26, 53,106, 4,173, 86,123, 1,192,246,136, +136,136,129,169,169,169,235,254,252,243, 79,197,144, 33, 67,148,199,142, 29,251, 12,192,145,136,136,136, 49,203,150, 45,235,166, +215,235,183, 85,209,237,240,235,204,153, 51,131,134, 12, 25, 66,132,140, 94,123,246,204, 14,190,193,160, 39,179,231,255,100, 12, +185,118,153, 49, 24,244,228,253, 15,103,178, 39, 47, 70, 50, 19,166,173, 49,182,108,219, 23, 15, 30, 60,112,234,215,175,223, 82, + 0, 38, 25, 44,129, 64, 80, 97,160, 43,249,253, 90,117, 17,126, 12,120,185, 90, 91,223, 56,182,120,177,220,235,218,181,151,205, + 85, 98,226, 91,103,174, 0,224,194,133, 11, 91, 1,108, 13, 10, 10, 74,151,201,100, 40, 42, 42,250,203, 57,210,174, 93, 59,137, + 66,161,144, 8, 4, 2,180,110,221,218,166,103,207,158, 49, 12,195,108, 56,117,234, 84,173,147, 80, 86, 22,217,170,107,154, 6, +115,107,182, 95,203,182, 77,205, 31,155, 47, 54,151,240,213,247, 60, 98, 36, 22, 4, 64,190,198, 49, 46, 52, 97,104, 1,201, 16, +183,108, 22,236, 1, 41, 35,233, 87,149,193, 34,132,220, 45,200,203,239, 93, 80,168,197,181,235, 15,240,225,208,134,208,232, 8, + 88,150, 65, 81,177, 6,224, 9,192, 0, 24, 54,124, 20, 40,225, 35, 55, 43, 13, 4,136,124,219, 76,128,209,104,156, 55, 96,192, +128, 86,203,150, 45,107, 50,115,230,204,242,253,210, 78,161, 80, 68,113,121,176,254, 31, 12, 86, 35, 47,215, 94,157, 91, 5, 78, +251,114,254,151,230, 79,110, 93,193,151, 75,191,103, 27, 6,246,204, 95,185,231,143,194,124,121,189,110, 37,202, 71,247,106, 27, +117, 16, 24,244,160, 6, 29,196,114,249, 75,145, 43,145, 76, 6,129,153,180, 86, 27, 65, 8, 1,165,244, 47,221,129, 47,154,171, +218, 92,108, 69, 34, 81,222,213,171, 87, 29,146,147,147, 95, 26,208, 94,191,126,125, 16, 66,112,243,230, 77,220,184,113, 3, 31, +126,248, 33,248,124, 62, 4, 2, 1, 34, 34, 34, 10,235, 18,193, 42,159, 69,232,236,236,220,179, 77,155, 54,149,206, 30, 52, 37, +130,149,152,152, 8, 47, 47, 47,104, 52, 26, 88, 91, 91, 35, 39, 45, 14,207,158, 60, 66,137, 70, 15, 15, 7, 17,178,178,178, 80, +158,215,171, 58, 46, 95,190, 76, 21, 10,197, 75,145,159,204,204, 76,120,122,122, 98,203,150, 45, 88,191,126,253,230,212,212,212, + 90,223,197,186,184,184,216,176, 44,187,172, 95,191,126,253, 7, 14, 28,136,158, 61,123,190,244,254,174, 93,187, 44, 15, 31, 62, +252,163,155,155,219, 64, 30,143, 55, 47, 62, 62, 62,189,166,125, 14, 0,191,252, 82,154, 62, 73,218,118, 17,230, 13,241,192, 71, +147,119,224,187,239, 14, 67, 44, 22,191,212,216, 46, 89,178,164,230,122,164, 20,221,223,255,196,191,139,159, 22,198,236, 63, 96, +209, 62, 23, 5,161,214,200, 47,244,199,205,181,125, 0, 0,205, 63, 62, 14, 74, 61, 0,224,173,140, 96, 81, 74,207, 1, 56,247, +194, 75, 7, 9, 33,122, 66,200,112, 0,251, 40,165,135,203, 94,255, 9,213, 36, 6,109,219,182,109,203,249,243,231, 11,202,211, +102, 40,234, 45, 51,232,116, 58, 22, 0, 26,251,189,243, 82, 95,245,211,167, 79,241,221,119,223,161,184,184, 24,194, 90,132,153, +131,131,131, 43,198, 68, 10,133, 66,216,217,217, 65,167,211,193, 96, 48,212,122,252,149,157,171,235,247,119,174, 95, 55,138,126, +216,160,162, 7, 15,154,197,152,153,189,213,230,234, 21, 22,245,233,211,103, 17,165,148,178, 44,187,240,133,155, 45,177,181,181, +245,213,239,191,255,222,214, 96, 48, 96,214,172, 89, 86,217,217,217, 86, 19, 39, 78,156, 7,160, 74,131, 85, 69,154,134,170,142, +183, 58,165,105, 96, 89,120,203,229, 22,200, 70, 50, 52,118,250,150,121,182,134,156,115,169,227,238, 41, 18,252,125,101, 70,189, + 39, 83,160,133,165,196, 28,148, 82,239,170,126,219,192,178,167, 30, 69, 69,245,168,231,214,144,247,231,241, 43, 24, 48,112, 8, + 52, 26, 6,106, 61, 1,225, 9, 64,120, 66, 52,247,243,135, 79, 83, 63, 80, 0, 49, 15, 35, 12,198,151,207,141,255,121,220, 7, +253,180,217,181,255, 15,147, 0, 96,214,134, 11,248,242,155,117, 24,241,126, 79,140, 25, 51,134,203,131,245,255, 97,176,234,213, +171,103,229, 32,151,254, 50,229,227,177,230, 9,247,195,144, 28, 17,134,235,215, 98,114,119, 31, 58,154, 82,144,159,249,113,109, +204,213,139, 17, 44,175, 93, 39,224,226,236, 92, 17,185,106, 31, 30, 15,177, 92,142,144,230, 46, 96, 53, 26,244,120, 94, 80,235, +141,169, 44,106, 37, 20, 10,235, 52,211,175,220, 84,189, 58,160,125,194,132, 9,216,190,125, 59, 58,116,232,128, 70,141, 26,213, +250, 78,249, 69, 83,244,226,152,168,218,204, 30,172, 76,171, 94,189,122,136,140,140,132,165,165, 37,118,238,220, 9, 87, 87, 23, +140,233,229, 5, 30,175,180,107,139, 97, 24,147,198, 96, 81, 74,141, 46, 46, 46,113,103,207,158,245, 28, 50,100, 8,132, 66, 33, +114,115,115, 97, 97, 97,129, 77,155, 54,177, 82,169,244,215,218,150,207,205,205,109,140, 68, 34,249,122,232,208,161,252,198,141, + 27, 35, 61, 61, 29,150,150,150,108,217,210, 70,176,177,177,102,165, 82, 41, 38, 76,152, 0, 63, 63,191,238,115,231,206,237,166, + 80, 40, 86, 40,149,202, 31,106, 50, 89,123,247,150,246, 78,125,188,225, 17,180,218,210,161, 22,155, 55,111,134,179,179,243,203, + 93, 1,177,177, 53,207, 34,100, 89,156, 59,244,211,221,201, 83,135,250, 19,235, 97, 40, 8,181, 6,181,252, 16,233, 69,230,216, +117, 57, 3,151,239, 38, 84, 36, 26,125,219, 34, 88,132,144, 1, 40, 29,122,113,146, 82,122,132, 16, 50, 24, 64,207,242,231,168, +101, 98, 81,131,193, 64, 25,134, 33, 73, 73, 73, 58,169, 84, 74,108,108,108,248, 98,177, 24, 26,141,166,194,104, 61,125,250, 20, +199,143, 31, 71,114,114, 50,108,108,108, 24, 75, 75, 75,232,116,186, 92, 19,239,186,255,146,158,161,236,119,107,125, 62,142, 6, +154,109, 94, 60,223, 67,197,207,181,204, 26,211, 21,236,189,235,170,200, 76,141,217,191,196, 92, 33, 36, 36,100, 43,128,173,229, +207,187,118,237, 58,134,207,231,127, 9,192,114,219,182,109, 86, 86, 86, 86,228,216,177, 99,250,109,219,182,229,241,120,188, 92, + 0,235,170,211,171,108, 48,251,235, 80, 89, 42, 6, 74, 17,149,147, 31,231, 46,176, 82,176,247,213, 52,116, 70,210, 60,159, 92, + 65, 67,123,210,180, 25, 6,102, 68, 95, 27, 99,136,109,159,153,150,193, 80,208,168,170,116,243,243,243,127,250,117,199,129,217, +251,247,253, 82, 79, 44, 23, 99,194,196,249, 56,113,250, 18, 8, 35,192,213,208,155,208,234,140,200,202,201,199,208, 97, 35,224, +234,108, 7, 20,165,100, 10, 68,162, 31,222,166,125,255, 82, 30,172,192,246,184,126,120, 13,246,198,212, 67,202, 55,223,112,121, +176,254, 78,131,229,225,225, 33,150, 9, 48,222,198, 76, 56,103,202,240,247,236, 51, 98, 31, 34, 57,250, 46, 0, 64,163, 81,233, + 83, 99, 46,183, 48,225,162, 29,252,106,174,140,242,174, 27, 27,123,135,138,200,213,139,179, 7, 89,141, 6,172, 78, 11, 84,209, +157, 83,149, 38,195, 48,127, 49, 86, 47, 94,120,107, 83,206,242,232, 72,101, 9, 70,221,220,220,176, 98,197,138,191,228,193, 50, +165,156,101,119,105, 61, 9, 33,126,229,198,136, 82,234,231,236,236,220,211,148,153,131, 85,105,150,103,172, 62,117,234, 20,162, +162,162, 64, 41, 69,191,126,253, 32, 16, 8, 96,110,110, 94, 97,178, 42, 27,131, 85,153, 38,195, 48,159, 28, 62,124,120,118, 88, + 88, 88,175, 89,179,102,145,242,177, 44, 69, 69, 69,108,106,106,106, 97,109,203,201,178,236,156, 51,103,206,240,141, 70, 35,182, +111,223,142,219,183,111, 83,169, 84,186, 82, 32, 16,172,144, 74,165, 6,189, 94,255,249,184,113,227, 38, 46, 94,188,152,233,212, +169, 19,194,194,194, 24, 79, 79,207,169, 0,126,168,105,219,111,222,188, 89,218,229,156,147,136,201,243,246, 65,102,198,199,163, + 71,143,144,147,147,243,151,228,163, 53,151,147,194,191,203, 16,127,150,234,160,147, 15, 1, 99,214,181,116,169,156,231, 26,180, +242, 43,141, 58,170, 10, 50, 43,234,177,178, 8, 86, 85,229,124, 77,243,243,183,106, 18, 66,250, 55,105,210,228,139,168,168, 40, +215,230,205,155,251, 18, 66,130,154, 53,107,214, 42, 50, 50,178,252,185,128, 82,186,191, 54,154,183,111,223, 62,184,105,211,166, +137,163, 71,143, 22,178, 44,107, 76, 72, 72,208, 3, 32, 78, 78, 78,188,219,183,111,179,127,254,249, 39, 84, 42, 21, 92, 93, 93, + 25, 23, 23, 23,114,238,220, 57, 54, 58, 58,250, 38,165,116,190,169,219, 94, 30,153, 22, 8, 4,224,241,120, 80,169, 84, 38,153, +171, 87, 53,221, 27,121, 45,239,220,222,195, 45, 75, 25,129,132,132,120, 36, 6, 54,212,111,222,124,188, 86,230,234,127,113,191, + 87,115,115,185,228,208,161, 67, 46, 26,141, 6, 66,161, 16, 7, 14, 28,208,237,216,177, 35, 42, 63, 63,191, 99,120,120,184,170, +174,229,172, 77, 2,210,154, 52,139,242,120, 39, 78,159,121,208,138,215,235, 39, 76, 86,102,118,172, 48, 94,132,216, 28,118,244, +237, 40,109,221, 60,197,252,202, 26,166, 4,234, 19, 85,105,198,198,198,106, 3, 3, 3,135,204,157,179,232,194,215, 75,191,150, + 47, 92,180, 8,215,111, 70, 34, 59,175, 8, 44,229,129, 37, 4, 95,126,185, 16, 78,118, 54,176, 17,233, 75,178,139,201,192, 87, +151,204,249, 95,223,239,175,147, 7,235,239, 40,231,191,198, 96,153,243,241,160,163,175,151, 75, 39,255,166, 18,190, 81,133,228, +232, 88,228, 20,171,113,238, 97, 66, 30, 67,153, 95, 95,231, 71,121, 60, 30, 44, 45, 45, 33, 20, 10,209, 46, 50, 5, 34,161, 16, + 98,185, 57, 0,148, 70,174, 40, 5, 35, 18,215,246, 0,170,212, 96,213, 21,163,209, 8, 71, 71,199,151,150, 93,121,177,193, 46, + 55,138,181, 77,209,192, 48,204,188,176,176, 48,139,196,196, 68, 80, 74,113,228,200, 17,139, 65,131, 6,205,171, 75,244,138, 82, +138,236,236,108,176, 44, 11,177, 88,140, 94,189,122,161, 83,167, 78,208,149,205,254, 40,111,128,106,155,201, 61, 41, 41, 41, 21, +192,103,174,174,174,191,206,158, 61,123, 78,155, 54,109, 2, 23, 47, 94, 12, 82,139,133,113, 95, 65,103, 52, 26,113,249,242,101, + 28, 62,124,216,160, 86,171, 7,165,165,165,221,121,225,253,165,174,174,174,127, 14, 26, 52,232,228,227,199,143,249, 81, 81, 81, + 0, 96,168, 73, 84,165, 82,161, 81,163, 70, 48, 24, 12, 88, 53,217, 13,133,133,205, 97, 48, 24, 96, 52, 26, 33,147,201, 94,202, +251,101,202,126, 98, 41,139,187,151, 14,220,117,111,217,211,191,166,165,114,222,178, 8, 86,175,168,168, 40,215,225,195,135,103, + 68, 70, 70,186, 30, 63,126,220,170, 95,191,126,178, 97,195,134,101, 68, 70, 70,186, 18, 66,222, 1,176,191,150,231,207, 23,132, +144,211,203,151, 47,159, 55,109,218,180, 54,163, 71,143, 22, 8, 4, 2, 54, 37, 37,197,176,103,207, 30,210,168, 81, 35, 70, 40, + 20,146, 51,103,206,176,183,110,221,186, 97, 48, 24, 86, 81, 74,175,214,246, 58, 82,110,174,234, 26, 73, 94, 7,140,106,156,152, +220,113,255,146, 53,140,160,137,179,238,216,169,155, 73,119,239, 60,127, 6,157,113,198, 47,192,179,127,105,187,176,127,200,144, + 33, 99, 6, 13, 26,100,214,186,117,107,241, 79, 63,253,148, 95, 82, 82, 82,169,185,170,140,218,164,105,168,109, 2,210,114,148, + 74,229,207, 43,150, 92,153,241,145,207, 48,175, 79,236, 60,112,190, 56, 3,185,124, 30, 99, 97,197,192,223,157, 7, 85,222,115, +251, 11, 55, 15, 61, 79, 85, 42,171,205,171,118,231,206,157,219, 1, 1, 1,193, 31,125, 52,230,208,132,143,199, 57, 44,252, 98, +174,224,224,159, 39, 1,131, 14,183,174, 94,133,149,148, 80, 67,113,106,122,182,150,188,247, 54, 46,149,147,112,248,147,201, 0, + 38, 19, 66, 62, 92,180,104,209,158,201,147, 39,131,101, 89,132,132,132,224,135,185,115,177,216,104, 28,185,145,144,146,105,148, + 78,230,236,210, 27, 52, 88, 96, 72,225,141, 39, 9, 69, 55,159, 36, 20,129,165,148,165, 84,195, 48, 72, 42,214,233,150,199, 60, + 75, 62,243, 58,251,180, 87,175, 94,204,171,198,165,138,110, 6, 83, 7,215, 37, 4, 7, 7,191, 49, 77,150,101,147, 59,118,236, +248,151,134,185,170,255,203,116,147, 77, 10,201,178,236,202,118,237,218,253,229,181, 58,133,119, 89, 54,174, 91,183,110,186, 87, + 77, 87,117,207,141, 70, 99,178,169,250,201,201,201, 15, 0,140,112,113,113,233,210,179,103,207,169, 0,234,154,142, 97,109,151, + 46, 93,102, 82, 74,249,132,144, 53,175,152,171,242,223,122,232,226,226,178,208,211,211,179, 98, 1,232,154,182, 61, 56, 56, 88, + 87,211, 34,207, 47, 14,128,102, 89, 54,185,122, 77,138,122, 45,122,248,235,244,165, 38,173,186,165,114,170,138, 96,253,143,178, +143, 16, 34, 0,144, 27, 21, 21,245, 78, 89,228, 42,249,193,131, 7,231,247,238,221,235, 8,212,156, 62,161,138, 27,128,171, 0, +174, 18, 66, 58,109,222,188,249,139, 9, 19, 38,180,254,240,195, 15,249, 65, 65, 65, 56,113,226,132, 49, 36, 36,228,166, 74,165, + 90, 89, 91, 99, 69, 8, 41,122,245, 28,170,166, 12,213, 46,210,235,205, 48,155, 86, 8,132,146,113, 7, 46, 23, 93, 22,146, 80, +163,202, 48,255, 55,224,193,191,185, 81, 56,119,238,220,231,237,218,181, 91,120,224,192, 1,165,151,151,151, 88, 32, 16,104, 77, + 53, 87, 64,237,210, 52, 80, 74,217, 58, 30, 91, 6, 71, 71,199, 62,187,134, 79, 62,218, 98,202,232,250,189, 58, 4, 74, 93, 60, + 28, 92, 30, 63,207, 66,114,228,249,226,103, 33,155,226,141,234,156, 1,148,210, 26,111,212,194,195,195,111,181,107,215,174,225, +230,109, 63, 78,230, 49, 76, 15,131,209,232, 55,115,242, 8, 74,128, 72, 22, 56, 39, 20,139,222,250,197,158,197, 66,225,200, 41, + 83,166,224,247,223,127,199,145,245,235,209, 51, 57, 25,123,133, 66,152, 9,133,216,162,211, 77, 2,192, 25,172, 55,105,176, 34, +159, 60, 15,248, 59,126, 48, 42, 42,170,221, 63, 93, 51, 42, 42, 42,240,239,170,240,215, 25,107, 85, 73, 57,255, 95,166,209,166, +164,164, 92, 2,112,233, 53,190,191, 3, 38, 44,230,108,234,231, 0,224,209,163, 71,111,124,219,169,216,114, 72,226,253,179,121, + 78, 77,186, 90, 25, 12, 6, 16, 66,160, 86,171,113,227,198, 13,104, 74, 10, 17,178,123,124, 69, 38,119, 80, 32, 45,250, 98,158, + 83,253,102, 86,255,235, 23, 1, 74,233, 21, 0, 87,202,204,203, 64, 66, 72, 31, 0,103, 40,165, 7,223,144,126,133,209,218,182, +109,219, 12, 74, 41, 10, 10, 10,214,215,214, 88, 85, 92,155, 34, 35, 47,190,169,109,143,103,217,139, 11, 75, 74,186,102,179,236, +140,159, 13,181, 91,112,252,109, 38, 44, 44, 76,221,173, 91,183, 95,151, 45, 91,214,150,101,217,223,222,132,230,107,164,105,168, +148,244,244,244,231,132,144, 22,236, 55, 27,198,134, 91,153,247,165,122,166, 49,209,243,143, 17,109,246,137,180,180,180, 95, 40, +165,198,218,108,111,217, 77,221,119,255,198,253,125, 63, 50,178, 39, 0,244,238,221, 27,170, 89,165,105,175,118,252, 39, 15,214, + 22,238,140,120,211, 17, 44, 14,142,127, 25, 41, 49,225, 7, 1, 32, 45,186,180,253,254,254,251,239, 1, 0, 61,123,246,252,203, +172,199,242,207,164, 61,127,187,130, 29,101, 3,218,143,252, 77,218, 87, 1, 92,253, 39,109,111, 8,165,253,184, 35,191,114, 46, + 92,184,240, 70, 19, 76,190,233, 4,164,101,199,148, 17,192,246,178, 7, 71, 29,241,246,246, 38, 0, 96,103,103,135, 5,181, 88, + 78,141,163,122, 24,174, 10, 56, 56, 56, 56, 56, 56, 56, 56,222, 44, 4, 64,112, 21,119, 6, 38,207, 14, 32,132, 4,215,225,206, +227, 60,167,201,105,114,154,156, 38,167,201,105,114,154,255, 46,205,154,180,223,154,217,137,229, 25,174,255,142, 7,128, 96, 78, +147,211,228, 52, 57, 77, 78,147,211,228, 52, 57,205,127,219,163,154, 49, 88, 7,121, 41, 41,176, 16,137,164, 66, 0,208,106, 75, +116, 46, 46, 40, 0, 6, 27,193,193, 81,155, 48, 41, 33,142,101,102, 62,253, 77,126,150,131,131,131,131,131,227,159, 10,191, 42, +115,149,149, 37,181,227,243,115,189,141, 70,181, 15, 0,240,249,204,163,172, 44,235, 24, 59,187,131, 89,111,218,100,245,238,221, +123, 62,165,212, 81, 32, 16,156,112,114,114, 10,217,186,117,171,254,223,108, 52, 94,199,100,252,127, 24, 20, 91, 91, 91,133,163, +163,227,112, 43, 43,171,160,252,252,252,171,105,105,105, 59,179,179,179,149, 85,148,103, 5, 33,152, 83,246,255,106, 74,233, 23, +213,148,221,228,207,190,138, 66,161,104, 36,145, 72, 38, 51, 12,211, 12, 0, 88,150,125,160, 86,171, 55, 43,149,202, 39,255,182, +147, 90,161, 80,152, 81, 74,223, 19, 8, 4,163,108,108,108, 90,103,102,102, 46, 78, 73, 73, 89, 87,199, 99,150, 15, 96,150,149, +149,213,135, 86, 86, 86,158, 57, 57, 57,207, 10, 10, 10,246, 3,248,142, 82, 90,227,121,250,245,116, 69,187,160,158, 65, 11, 66, +206,132, 44, 93,180, 65, 25,246,151,247, 63, 87,216,246,232,222, 97, 97,200,177,208, 37, 95,108, 74,201,169,101,217, 24,252,103, + 28, 41, 91,122,216,255,115, 71,232, 58, 56, 56,180, 45, 75,164,202, 48, 12,243, 93,122,122,250,165,127,242,113,100,111,111, 47, +115,114,114, 90, 69, 8,233,207,227,241,162,210,211,211,199, 43,149,202,228, 55,116, 45,100,220,221,221,205, 19, 18, 18, 10,235, +154,170,225,223, 72,187,118,237,210,117, 58, 93,181,217,241,133, 66, 97, 70, 88, 88,152, 35, 87, 91,255, 80,131,149,146, 2, 11, + 62, 63,215, 59, 35, 45,114,168, 50, 53,226, 3, 0, 80, 56,251,237,119,112,106,190, 47, 37, 69,164,107,213,125,144, 92, 32,229, +111,230,241, 4, 45,213, 90,141,157,128, 47,200,210, 25,244,247, 24, 45,157,156,250,232,112,162, 41, 63,220,191,127,127,111, 0, +150,254,254,254,183,181, 90,109,235,117,235,214, 57, 31, 58,116,200, 47, 60, 60,124,216,187,239,190,123,140, 82,122,230,216,177, + 99,170, 90,157,180, 65, 65,124,135, 60,155,145, 60, 62,191, 63, 0, 63, 74, 1, 16, 94, 4,171,211,158,204, 16,218,252, 70,195, +235,110,220,218, 53,178,245, 38, 84, 55, 91, 64,104, 39, 61, 37, 87, 41, 17,174, 9,123,146, 29, 83,139, 11,138, 73,230,225,117, + 76,198, 43,223, 93, 79, 41,157,245,166, 15, 24, 39, 39, 39,187,193,131, 7,239, 90,186,116,169,204,220,220,156,196,199,199, 15, +252,226,139, 47,122, 42, 20,138,143,148, 74,101,210,171,102,143, 16,204, 97, 89,202, 0, 0,195,144,185,142,142,142,205,248,124, +190,230, 85, 93,131,193, 32, 38, 4,189, 88,182,116, 57, 27,134, 33,115, 8, 33, 27, 76, 49,138,158,158,158,195,154,251,181,156, +249,197,252,133,114,123, 7, 7,153,193, 96,212, 37,165, 36, 75,215,172,248,166,141,167,167,231,134,184,184,184, 61,181,221, 78, + 66, 8,113,117,117, 29, 42, 16, 8,250, 1,104, 82,246,114,180, 94,175, 63,158,156,156,188,207,212,134,188, 69,139, 22, 87, 24, +134,241,168,205,111, 27,141,198,196,136,136,136,142,117,217, 63, 46, 46, 46, 67, 92, 92, 92,126,105,219,182,173,180,101,203,150, + 16, 10,133, 88,189,122,245, 44,212,176,188, 73,185,145,146, 74,165, 67,101, 50,153, 87, 81, 81, 81,172, 74,165, 58, 36, 18,137, +130, 55,108,216,224,214,161, 67, 7,243,244,244,116,194,227,241, 28,143, 31, 63, 62,114,227,198,141, 61, 9, 33,221,106,202, 51, +148, 31, 75, 23,136,251, 55,233,148, 31,123,105, 1,128,222,127,217,239,106,201, 40,202,115,235,167,162,119,147, 80,139, 41,242, +132, 16,198,213,213,117,131,163,163,227, 24,149, 74,165, 38,132, 80, 66, 8,109,222,188,121,249,251, 0, 0,173, 86,155,251,248, +241,227,198,213,105,213,111,103,115,135,199,240, 92,171,220, 31,172, 49,249,121, 88,206,107,167,110, 49, 26,141,115,162,162,162, +250, 8, 4, 2,210,162, 69, 11, 30,106,145,250, 68,161, 80,120, 19, 66,190,164,148,222, 78, 77, 77,221, 92,182,164, 85, 23, 74, +105,197,181,162, 44,157, 10, 92, 92, 92, 54, 55,108,216,240,221,167, 79,159,110, 73, 73, 73, 89,250, 26, 70,125,235,242,229,203, + 63,232,217,179, 39, 47, 59, 59,219,165, 71,143, 30,187, 1,116,122,157, 58, 8, 8, 8, 16,164,165,165,205,106,209,162,197,167, +173, 90,181,114,126,248,240, 97,154, 66,161,216,232,228,228,244, 93,120,120,120,141,215,103, 63, 63, 63, 5,159,207, 31, 3, 96, + 36, 0, 30,165,116, 47,128,223,238,222,189,251,175, 72, 10,171,211,233, 28,206, 47, 93, 8,194,231, 67,210,177, 27, 88,150, 69, +214,154, 69, 48,228,100,193,110,233, 70, 24, 12, 6, 4, 7, 7, 59,128,227,159,107,176, 68, 34,169,208,104, 84,251, 40, 83, 35, + 62,120,167,243,247,150, 0,112,229,242,167, 31, 56, 56, 53,125, 32, 18, 73, 99,196, 22,146,195,131,250, 7,183, 28,220,175, 51, +113,117,118, 64,114,106,134,227,207,123,207,244, 58,126,230,210, 97, 0, 38,229,207, 42, 40, 40, 88,230,238,238,110,127,225,194, +133,120,145, 72,100, 38,145, 72,200,144, 33, 67,204,134, 13, 27,230,123,241,226, 69,175,211,167, 79, 15, 30, 48, 96,192,105,161, + 80,120,226,192,129, 3, 53,174, 79,230,216,124,160,175, 19,223,233,224,128,247,122,123,244,237,238, 32,114,119,178, 7,101, 37, +120, 20,167,171,119,238,234,221, 94, 39, 78,157,153,227,224, 59,240,253,140,168, 35, 38,175,134,222,172,153,165,149,153,138,206, + 52, 19,210, 15,123,181,241,173,223,191,123,123,226,233,233,137,152,199, 49, 94,151,174,223, 30,211,197,199,252,185, 74, 71,246, +170,204,200,218, 7, 15,242,243,170,139, 42,189,104, 52,120, 60,102, 94,247,238,221,199,136,197,226,151,238,220, 52, 26, 13,195, + 48,196,193,104, 44,125,185, 54, 38,163,252, 55,180, 90, 13, 35, 16,136,192,227, 49, 51, 91,182,108,217, 59, 61, 61,253,148, 88, + 44, 94,253,252,249,243, 90,229,157,153, 70,136, 40,151,207, 15, 96,196, 98,103,163, 86,107, 11, 0, 68, 36,202,173,103,107,219, +246,171,175,190,146,243,120, 60,100,103,103, 67,173, 86,147, 79, 62,249,196, 44, 54, 54,118, 52,128, 37, 53,153,150, 29, 59,118, +248,219,218,218,254,229,142, 53, 59, 59,155,233,221,187, 87,173,243,118, 42, 20, 10,239, 22,254,129,159,237,217,189,171, 73, 65, + 78,174,122,251,186,173,225,122,137, 84,227,217,164,177,224,155, 21,107, 45, 23,204,157,249,169, 66,161,184,167, 84, 42, 77, 54, +195,206,206,206,245, 60, 60, 60, 14,207,159, 63,191, 89,199,142, 29, 5, 14, 14, 14, 72, 79, 79,199,227,199,143,155, 93,191,126, +253,189, 63,254,248, 99,150,179,179,243,160,212,212,212, 26,111, 38, 40,165,141,142,174, 89,225, 32,182,177, 5,171,215,195,198, +207,191, 34,249,107,234,165,179, 48,234,116, 96,245,122,184,245,125, 15,101,145, 55,116,237,218,181, 78, 25,243, 93, 93, 93, 21, +222,222,222,191,207,155, 55, 79,168,213,106,113,247,238, 93,132,133,133,177, 25, 25, 25, 43,107, 50, 87,132,144,179,139, 22, 45, +114,237,216,177,163,121, 86, 86, 22,140, 70,163,221, 31,127,252, 49,217,223,223,223,194,205,205, 77,180,115,231, 78, 20, 21, 21, +193, 96, 48,216,120,121,121,217, 12, 27, 54, 76,187,115,231,206, 89, 0, 86, 85, 21,185, 42,136,165, 11,210,136, 87,175,198, 1, +163,144, 70, 78,247,154,217,219,249,148, 69, 3, 82, 17,201,234,221,160,129,185,151,143,108,174,220,162,185, 77, 65,202,249,185, +189, 27, 52,216,126, 42, 54,214,148,165,152, 24, 23, 23,151, 13,125,250,244, 25,190,101,203, 22,105,116,116,180,180, 73,147, 38, + 96, 89,182, 34,147,127,249,202, 5,157, 58,213,236, 7,120, 12,207,245,250,225,135, 14,102,102,102, 21,107,132,150,255, 45, 46, + 46, 70,207, 81,109,255,142,235,109,109,247,241,215,161,161,161, 67, 78,157, 58, 53, 98,233,210,165,141, 0, 76,101, 89,118, 97, +116,116,116,103, 0,104,210,164,137, 8,192, 37,133, 66, 49,118,210,164, 73,147,166, 78,157,138,145, 35, 71, 46, 36,132, 44,171, + 75, 84,143, 16,194,107,218,180,105,159,158, 61,123,242,244,122, 61,204,204,204,160,211,233, 26,188,206,198,251,250,250, 10, 75, + 74, 74, 14, 45, 89,178,164,223,128, 1, 3,192,231,243,193,178,172,211,149, 43, 87, 86,204,154, 53,171,125, 64, 64,192,192,170, + 76, 86, 64, 64, 64, 75, 0, 75, 26, 54,108,216,115,212,168, 81,188, 14, 29, 58,160,168,168, 8,103,207,158,253,242,240,225,195, + 95, 6, 4, 4,132, 2, 88, 24, 30, 30, 30,242,182, 55,218, 60,185, 57, 30, 15,234, 2,175,232,108, 0, 64,218,230, 53, 0, 0, +139,175,190,229, 28,205,255,130,193,170,137,146,146, 18,255, 47,166,141, 4,195,148,182,135, 13, 61,235, 97,197,252,241,228,232, +241, 51,254, 53,132, 55,215, 26,141,198, 70, 54, 54, 54,179,213,106,181,100,253,250,245, 18,165, 82,233,115,240,224, 65,122,255, +254,125, 8,133, 66, 88, 90, 90,162, 91,183,110,226, 94,189,122, 53, 8, 13, 13,173,119,248,240,225, 1,125,251,246,253,237,196, +137, 19,199,170, 51, 87,118,246,246,151,191, 93, 58,206,166,153,167, 23,116,122, 61,146, 50, 82, 64,137, 8,206, 14, 50,124, 52, +176,165,176, 99,160,200,235,219, 31,206,135, 56, 54, 27,240, 78,250,131,163, 15,107,218,198, 78, 13,101,183, 6, 6, 52, 8,232, + 31,220,158,105,212,216, 23, 66,137,180,226,189,230, 45,253,209,188,165, 63, 25, 63,166,208,243,254,253,251, 11, 78, 95,190, 57, +191, 83, 67, 89,248,213,167,197,213, 45,140,249,146,121,152, 53,107, 22,108,109,109, 95, 53, 25,184,120,241, 66,149,223, 49,229, +186,248,226,147, 21, 43, 86, 88,101,100,100,124,248,243,207, 63,191,231,228,228, 52, 37, 45, 45,237,180, 41, 34, 35, 9,241,128, + 88,220,109,204,119,223,177, 45,223,125,151,103,229,228,196,176, 70, 35, 73,142,141,181,251,110,253,250,224,194,164, 36,169,202, +220,188, 40, 51, 63, 95, 27, 19, 19, 3, 51, 51, 51,194,227,241, 58, 84, 98, 46,210, 9, 33,171, 25,134,204, 37,132, 16,137,196, + 44,247,227,143, 63, 14, 45,123,175,201,177, 99,199,204,251,247,239, 95, 72, 8,137, 6, 0,137,196,172, 51,143,199, 88,211,210, +142,158,213,166, 24, 75,169, 84, 58,109,214,231,243,100, 5, 57,121, 42, 93,113,177,222,222, 66, 78,136,220,156, 87,144, 95, 88, +152,146,154,169,153,244,233, 12,222,130,121, 51,167,193,196, 76,196,206,206,206,245,124,124,124,110,109,223,190,221,193,214,214, + 22,121,121,121,200,206,206,198,173, 91,183,192,178, 44,122,247,238, 45,246,247,243,243,255,110,237,218, 48,103,103,231,118,166, +152, 44,137,173, 29, 14,190,211, 18, 0, 48,228, 89,118, 69,132,229,212,208,255,164, 96, 26,150,144, 95,250, 89,137,164,214,203, + 47,189, 80,223,237, 58,116,232, 32, 4,128,153, 51,103, 22, 20, 23, 23,175, 32,132,236, 86, 42,149, 41, 53,124,117,214,130, 5, + 11, 92, 60, 61, 61,221,119,239,222,141,162,162, 34, 0,112,240,244,244, 68,227,198,141,141, 33, 33, 33,240,246,246,134,185,185, + 57,174, 92,185,130, 27, 55,110, 32, 32, 32,192, 92, 40, 20,126, 80,149,193, 10,234, 25,180, 64,220,191, 73,167,198, 1,163, 32, +183,112,198,246, 61,251,240, 56,124, 71, 39,141, 46,122,193,138,169, 46, 31,169,168,120,180,107, 35,243,121, 30,129,157,109, 27, + 54,125, 23,238, 1,119,237,212,198,171,113, 11,167,120,173,228, 75,212, 59, 22,125,171,204,174,202, 92, 57, 57, 57,173,233,221, +187,247,144, 45, 91,182, 88, 1, 64,100,100, 36,210,211,211, 97,111,111, 15,137, 68, 2,129, 64, 80,177,126,168,169,152,153,153, + 33, 53, 53,181, 98,153, 41,163,209,136,194,194, 66, 56, 57, 57,149,186,155,175, 9,179,104,145,105, 93, 89,206,206,206, 29,253, +253,253,119,185,186,186,186,189,248,122,207,158, 61, 49,126,252,120, 80, 74,209,161, 67,135,110,227,199,143,167,148, 82,176, 44, +139,244,244,244,162,200,200,200,238, 41, 41, 41, 55,171,216,110, 85, 90, 90, 26, 38, 77,154,132,196,196,196, 41, 10,133, 34,129, + 97, 24, 73,249,114, 96,132, 16,145, 66,161,240,246,246,246,222, 48,126,252,120,196,199,199, 35, 38, 38,230, 86, 93,187, 76, 41, +165,198,182,109,219, 62,213,235,245,129, 6,131, 1, 42,149, 10,189,122,245,146,248,248,248,164, 11, 4,130, 71,121,121,121, 35, +202,150,212, 50,197,172,241,157,157,157,157, 4, 2,193,150,113,227,198,245,105,223,190, 61, 30, 61,122,132, 83,167, 78, 97,192, +128, 1, 8, 10, 10,194,130, 5, 11,250, 46, 88,176, 96, 22,128,170,110, 6, 14, 30, 58,116,168,190,171,171,107,197,146, 72, 22, + 22, 22,248,248,227,143, 49,114,228, 72,156, 60,121,178,253,242,229,203, 15, 5, 5, 5, 57,132,132,132, 24,222,230, 70, 91, 28, +216, 30, 94,209,217,120,214,164,180,253, 40, 55, 90,229,207,225,226, 15,142,127,176,193,210,106, 75,116,124, 62,243, 72,225,236, +183,255,202,229, 79, 43,186, 8, 1,230,145, 86, 91,162, 43, 13,155, 83, 20,148, 24, 96, 38,102, 16,159, 86,136,135,207,178, 42, + 59, 73,207,191, 98,204, 62,219,184,113, 35, 86,175, 94,221, 91,165, 82, 21,197,197,197,165, 22, 21, 21, 21,127,244,209, 71,132, +207,231,227,250,245,235,120,254,252, 57,154, 55,111, 14,107,107,107,116,236,216, 81,216,163, 71, 15,183,177, 99,199,126, 4,224, + 88,101,154, 36, 40,136,239, 44,182, 63,188,102,233, 80, 27, 48, 49,136, 73,204, 67, 3,215,214,176,179,114, 67, 74,102, 17,110, + 71,157,196,147,216, 19,104,224,226,142,241,195, 27, 90,173,219,122,253, 56, 9,152,208,224,197,238,194,202,166,132, 74,120,198, + 86,139,247,220,135, 49, 39, 22, 52, 63, 17,180,248,175,171,196, 72,237,220,224,211,206, 17, 82, 43,123, 38,242,209,186, 86, 85, +109, 59,165, 52,157,207,231,111,227,241,152, 9, 0,208,170, 85,235,226, 85,171, 86, 85,118,177,102, 91,181,106, 93,204,227, 49, +178,210, 8, 22,111,171,193, 96, 72,175,174,156,175,152,153, 53, 34,145,120, 54, 0,226,234,234, 86,116,244,232, 81,246,253,247, +223,199,154, 53,107,196,243,230,205,251,193,195,195,163, 75,124,124,124, 66,117,251,104, 16, 33,245, 92, 26, 52,232,177,236,250, +117, 42,208,235, 73,206,173, 91, 5,133,233,233,250,148,194, 66,201,111,119,239, 14,158, 50,103,142,196,201,203, 11,161,231,207, +155,167,229,230, 22,230,149,148,104,227,226,226,168,209,104,188, 90,197,182,127,225,232,232,216,108,199,142, 29,254, 31,127,252, +113,104, 74, 74,202,160,178,110,140,195, 0,218, 18, 66,162, 95,124,237,240,225,195,237, 71,141, 26,117, 55, 61, 61,253,139,234, +202,249, 2, 77,237,237,236,164,123,182,238,140,176, 49, 55, 99,236, 93, 21,140,192,202,138,111, 16,153, 9, 89, 64, 85,207,173, +190, 12, 64,211, 42,234,236,213, 69,195,137,135,135,199,225, 95,127,253,213, 65, 32, 16,192,104, 52,194,222,222, 30,207,159, 63, + 71, 94, 94, 30, 10, 11, 11, 17,247, 40, 26,245,221,220, 48,125,252, 39,206, 95,127,187,246, 48, 33, 36,240,197, 70,172,210,197, +184,117,186, 87, 27,156,170, 22, 8,135, 41,229,172, 10,150,101,159, 43,149, 74, 72,165, 82, 52,105,210, 68,126,251,246,237,171, + 41, 41, 41, 41, 53,105, 74, 36,146, 15, 58,116,232, 96,190,103,207, 30, 4, 4, 4,192,210,210, 18, 33, 33, 33,136,140,140,132, + 78,167, 99,138,138,138, 96,110,110,142,149, 43, 87,194,221,221, 29, 5, 5, 5, 72, 76, 76,180, 21, 8, 4,118, 85,105,134,156, + 9, 89,154, 31,123,105, 65, 26, 57,221,107,251,158,125, 24, 55,108, 40,156,232,179,171,150, 13,200,210, 30,253, 59,124, 69,121, +110,253,100,230,126,214,141,154,245,135, 80, 36,199,212, 57, 75, 16,243,224,152,117, 73, 97,196, 20, 98, 76,114, 3, 48,253, 85, + 77, 82, 90, 65,140, 66,161,248,100,235,214,173,230, 21,119,244,101,107, 18,190,104,172,202, 31,149,213,105, 85, 11,166,235,116, + 58,232,116, 58, 24,141, 70,100,101,101,161,176,176, 16, 86, 86,101,137,250, 23, 1, 4,132,208, 42, 86,161,127, 81,147, 97,152, + 17,251,246,237,115,147, 74,165,175,126, 6,101,209, 65, 72,165, 82,176, 44, 11,157, 78, 7,131,193, 0,141, 70, 35, 15, 10, 10, +154, 12,224,102,101,154, 60, 30,111,230,164, 73,147, 58, 28, 63,126,220,107,233,210,165,208,233,116,107, 50, 51, 51, 49,126,252, +120,176, 44,139,142, 29, 59,182,165,148, 62,158, 62,125, 58, 0, 96,241,226,197,250,162,162,162,137,117, 61,150, 28, 29, 29,125, +251,247,239,239,117,225,194, 5,116,234,212, 9, 26,141, 6, 95,125,245,149,197,234,213,171, 45,246,239,223,111,191, 98,197,138, + 95, 0,244,172, 78, 51, 32, 32, 64,144,158,158, 62,119,196,136, 17,179,130,131,131, 45, 19, 19, 19, 97,102,102,134,163, 71,143, + 98,235,214,173,167,116, 58,221,130, 67,135, 14, 45,219,182,109, 91,175, 1, 3, 6, 96,235,214,173,211,202,134, 69,176,149,104, + 42,220,220,220, 16, 17, 17, 1,107,107,107,216,217,217, 33, 63, 63, 31, 55,110,220,192,173, 91,183,224,227,227, 3, 66,136,117, + 89,155,102,120,157,243,168,150, 70,244,255, 93,179,124,134, 26,251,194,177, 75, 41, 45,221,104, 90,247,114, 18, 66,248, 10,133, + 98,128,149,149,213, 20, 74, 41, 63, 55, 55,119,171, 84, 42, 61, 24, 27, 27,171,253,255,218,246,127,133,193,114,113, 65, 65, 86, +150,117,140,131, 83,243,125, 14, 78, 77,203, 82, 85, 51,143,120, 60,235, 24, 71,199,146, 2, 0,208, 25, 40, 66, 31,229, 33,226, +105, 26, 34,159,166, 65, 38,174,249,174,219,214,214, 22,237,219,183,199,209,163, 71,145,148,148, 36, 95,185,114,101, 35,157, 78, +167,235,223,191,191,210,195,195, 35,183, 99,199,142, 16, 8, 4,184,125,251, 54, 10, 10, 10,192, 48, 12,196, 98, 49, 88,150,173, +242, 86,212, 33,215,122,212,168,241,205, 61,237,172, 24, 28,187,118, 26,109,125, 6, 66, 42, 22, 32, 51, 79, 5, 2,130,103,207, +207,131, 53,200,113, 63, 58, 30,237,253,164,120,167,181,149,107,209,133,156,241, 0,126, 48,165,130,116,113, 33, 16,249, 14, 2, +216,166,160,185,177, 96, 11, 82, 64,165, 14, 40,102,205,144,165, 76,192,163,171, 7, 64,117, 53, 15, 21, 51, 24, 12, 19, 29, 28, + 28,152, 5, 11, 22,244,247,244,244,100,167, 78,157,122,253,249,243,231, 67, 94,252, 76,253,250,245, 15,108,218,180,169, 67, 92, + 92, 92,201,210,165, 75,143,101,100,100, 76,170,229,137, 57,151, 16,178, 14, 0,146,146,146,178,255,248,227,143, 78, 87,174, 92, + 89,177,110,221, 58,215,169, 83,167,138,167, 78,157, 58, 23,192,164,234,186, 5,101, 98,113,240,178, 43, 87,168, 33, 57, 89,115, +100,235, 86,222,250,176,176,121, 58,150,173,103,239,224,192, 15,234,212, 73,109,103,101, 85,156,158,150,198, 90, 41, 20,228,121, +108,172,156, 21, 8,116,167, 79,159, 46,204,201,201,169,114,153, 17, 62,159,175,169,172, 91,176,138, 99,132,173,108,140, 86, 53, + 20,176,148,234,172, 60, 61,105,143,110,237, 26, 62,125,252,236,153,196,202,138,215,168, 97,253,198, 15, 31, 61,191, 69,141, 6, + 53,128, 2, 19,187,216,134, 46, 90,180,168,185,133,133, 5, 88,150,133,165,165, 37, 50, 51, 51,161,213,106, 81, 80, 80, 0,109, + 97, 62,180,249,249,136, 76,120,142, 14, 65, 65,232,209,174,109,147, 19,122,253, 80, 0,123,171,211,181,241,243,175,136, 92, 29, +240,250, 79,212,242,195,248,188, 10,179,117,178,117, 3,136,228, 50, 52,159,241, 69,157, 79,230,212,212,212,187,238,238,238, 39, +123,247,238,221,103,194,132, 9, 76, 90, 90,218,105, 71, 71,199, 14,233,233,233, 81,213,125, 79, 46,151, 55, 40, 55, 20,150,150, +150, 88,191,126, 61, 28, 29, 29, 81, 82, 82,130,219,183,111, 83, 87, 87, 87,114,233,210, 37,184,186,186, 34, 43, 43, 11, 58,157, + 14,197,197,197,105, 90,173,182,202, 3,191,172, 27,176,247,204,222,206,167, 30,135,239,232,228, 66,226,110,127, 48,171,243,211, +199,145,143, 18,207,158,187,254,141, 65, 45, 73,202, 75, 62, 63,215,179,213, 93,187, 41,179,191,198,166, 53,139,240,248,230,149, + 28,199,122, 5, 63,152, 17,205,111,109,186, 87, 27, 65, 87, 63,122,244,200,252,254,253,251, 32,132,192,210,210, 18, 82,169,180, + 82,147,101, 42, 70,163,177,226,111, 86, 86, 22, 50, 51, 51, 17,155, 16,131, 67, 23,119, 64,111,208,219,253,218,198, 34,205, 75, + 40,140,176,203, 39,243,179, 30,208,187, 53,156,135, 91, 63,252,240,195,161, 46, 46, 46,230, 47,190,222,162, 69, 11,140, 24, 49, + 2, 59,119,238,196,157, 59,119, 42,186, 49, 41,165,200,204,204, 76, 53, 26,141,191, 85,165,153,152,152,152,231,234,234,218,235, +147, 79, 62, 9, 63,114,228,136,197,183,223,126, 11,163,209, 8,131,193, 80,209, 45, 90,254,119,247,238,221, 8, 15, 15, 95,152, +150,150,246,168, 46,199,145,147,147,147, 79,255,254,253,175,252,240,195, 15, 86, 25, 25, 25,200,202,202, 66, 81, 81, 17,138,139, +139, 97, 52, 26, 81,191,126,125, 98, 48, 24, 26,215,212, 29,200, 48,204,209,139, 23, 47,246,106,212,168, 17, 0, 64,175,215, 35, + 52, 52, 20,227,199,143,207,150, 74,165, 31,196,199,199, 23, 43, 20,138, 47, 79,156, 56,209,171,101,203,150,240,243,243,115,202, +200,200, 48, 7,144, 95,197, 13, 4,140, 70, 35, 50, 51, 51,145,153,153,137,159,127,254,207, 58,206, 26,141,166, 44, 56,160, 37, +173, 90,181,170,127,251,246,237,231,111,107,163, 29,255,251,118,196,207,255, 20, 30, 87, 31, 3, 0,194,125, 75,135, 92,185, 95, +142, 46, 29,126, 48,106, 84,173,244, 20, 10,133, 45,165,116, 92,112,112,240,140, 94,189,122,217, 43, 20, 10,216,216,216, 32, 50, + 50,178,195,153, 51,103,190,119,117,117,253,209,104, 52,254,104, 74,180,158,195,164, 46,194,193, 70, 59,187,131, 89, 41, 41, 34, +157, 72, 36,141, 41,143,106,149,154,171,193, 70, 96, 15, 12, 58,125,217, 5,130,150, 61, 76,235,214, 80,167,190, 15, 86,245, 39, + 28,164, 3,176,109,219, 17,100,100,100, 8,215,175, 95,239,113,228,200, 17,215, 17, 35, 70, 36, 54,108,216, 48, 63, 40, 40, 8, + 59,118,236,128,147,147, 19, 52, 26, 13,216,106,196,205,109,140,131,219, 54,111,200,123,146,240, 0,129,222,131, 81, 95,209, 17, +207, 82,242,145, 83,168, 65,118,190, 10,141,189,103, 35, 61,187, 4,249,197,106, 68, 62,222, 13, 23, 39, 79,134, 39,136,237,101, +170,193, 82,223,223, 5, 77,228, 62, 8,189,186, 64,212,116, 40, 4,174,237,144, 20, 25,130,123, 39,191, 67,242,195,107,160,172, + 17,142, 30, 77, 76,218,118,129, 64,176,228,196,137, 19, 61,150, 47, 95, 46,232,214,173, 91, 7,133, 66,209, 94,169, 84,134,150, + 29,228,237,251,244,233,211,193,193,193, 1, 27, 54,108,208, 10, 4,130, 37,117,188,251,121,177, 91,237,146,147,147,211,212,195, +135, 15,255, 57, 97,194, 4, 56, 59, 59,183,169,238,187,153, 2, 65,139,209,203,151, 83, 1,143, 71, 79,252,242, 11,153,127,242, +228,198,157,191,255, 46,234,208,161, 3, 8,128,136,200, 72,201,202,245,235,205,134, 14, 24,144, 17,243,252, 57,206, 94,188,168, +201, 72, 75,203,202, 44, 46,158,243,166,102, 23,213, 22,131,193, 16,150,152,148,232, 18,216,166,165,253,221,232,184,135, 61,187, +182,111,207, 48, 12,243,248, 89, 66,168,189,189,133,244,234,213, 43, 58,131,193, 16,102,226,254,233,215,177, 99, 71,126,110,110, + 46, 20, 10, 5, 50, 51, 51,145,146,146, 2,189, 94, 15,117,126, 46,116,249,249,208, 23,228,193, 88, 92,132,184,219,183,224,235, +230, 34, 62, 91, 58, 8,126,111, 77,119,156,149, 69,168, 94,140,100,137,205,229, 16,203,229, 47, 45, 78,109,226,197,113,128,133, +133,197,220,194,194,194,147, 41, 41, 41, 75,181, 90,237,212,229,203,151,183, 90,178,100,137,221,188,121,243, 44,230,204,153,115, +192,195,195,163,101,124,124,124,149,166,181,168,168, 40,214, 96, 48,216, 1,112,184,112,225, 2, 28, 28, 28,144,159,159, 95,186, +221,106,181,182,164,164, 68,146,157,157, 13,141, 70, 3,173, 86, 11, 11, 11, 11,220,185,115, 39,215, 96, 48,252, 89, 83,249, 44, + 26,144,165, 26, 93,244, 2,219, 38, 50,165,206, 96,221, 57, 35,135,205, 93,244,173,114, 9,128,239,122, 55,104,176, 93,199, 94, +137,123,242,224,152,245,243,219, 33, 57,202, 39,197, 94,219, 79, 60, 43,172,166, 30, 41, 33,132, 37,132, 80,111,111,111,100,102, +102,130,199,227, 65, 42,149, 66, 46,151,195,199,199, 7, 73, 73, 73,117, 54, 88, 6,131,161,194, 92,157, 11, 59,142,236,162, 84, +108, 95,179, 7, 46, 78,110, 12, 0,251,148,180,164,238, 99,103, 13,105,227,217,209,122, 69,220,181,220, 42,199,181, 41,149,202, +123, 0, 44, 94,190,105,117,233, 98, 99, 99,115, 81,171,213, 34, 62, 62, 30,103,207,158, 13, 74, 78, 78,190, 92,155,125,157,156, +156,252,204,197,197,165,215,123,239,189,183,163,121,243,230, 13, 40,165,240,241,241,193,128, 1, 3,112,232,208, 33, 68, 69, 69, +161,160,160,128,189,122,245,234,175,169,169,169,181, 26,144, 67, 8, 33,148, 82,234,236,236,220,184, 95,191,126,215, 54,109,218, +100,157,149,149, 5,149, 74,133,226,226, 98, 28, 60,120, 16,157, 58,117,130,141,141, 13,254,248,227, 15, 67,121,143, 66, 85,230, +138, 82,122,244,200,145, 35,189,188,188,188,240,232,209, 35,156, 59,119, 14,158,158,158, 16, 8, 4,232,215,175,159,237,190,125, +251,166,250,250,250,174, 21, 8, 4,223,244,233,211, 7, 70,163, 17,119,238,220, 73, 77, 72, 72, 40,172,201, 4, 87,134, 74,165, + 2,165, 20,122,189,126, 61,195, 48, 31, 4, 4, 4,244, 8, 15, 15,191,245,182, 52,212,174,174,174, 77, 5, 2,193,116,107,107, +107,100,103,101, 33,159, 5,114,114,114, 64, 41, 69, 62, 91, 26,184,146,101,255,167, 87,189, 81,163, 70, 39, 84, 42,213,252,228, +228,228, 42,215,242,114,113,113,241,147, 74,165, 51,250,247,239, 63,162,111,223,190, 60,189, 94,143, 99,199,142, 97,211,166, 77, +232,213,171, 23, 26, 54,108,136, 57,115,230, 88,170,213,234,121,167, 79,159,158,219,164, 73,147,211,133,133,133, 95, 84,167,201, + 97,146,193, 42, 53, 89, 46, 46,200, 45,187,163,177,179,177,177,217,100, 52, 26,187, 0, 95,193,156,111,137, 71,119,111, 35, 39, +155, 7,141,202, 8,150,150,154, 44,147,186, 49, 84,127,194,194,155,162, 32,134, 64,175,215,195,209,209, 17, 43, 87,174, 68,126, +126, 62,127,236,216,177,245,191,254,250,235,123, 90,173, 22,197,197,197, 80,169, 84, 80,169, 84, 48, 26,141, 85, 26, 44,161, 88, +211,188,158, 99, 35, 20,170, 90, 67, 42, 22, 33,167, 64, 83,106,174,242,212, 56,244,231,135,208,148,168, 96,212,233, 96,208,234, + 33,119, 28,136, 6,190, 93, 0, 60,109,102,162, 89, 41,253,203, 26,160,125,122, 14,218,167,231, 32,235,178, 0, 71,151,143,120, +229,196, 55,109,114, 98, 74, 74, 74,138,139,139,203,206,187,119,239,126,252,193, 7, 31,224,210,165, 75, 95,162,108,102,149, 68, + 34,249,242,131, 15, 62,192,221,187,119, 17, 29, 29,189,179,170,174,157,218, 34, 18,137,138,181, 90,109,121, 87,144,180,134,207, +186,180, 26, 52,136,201,191,123,183, 96,249,197,139,139,126,251,237, 55,209, 59,157, 58, 65,175, 47, 53,211,245,235,215, 71,143, +158, 61,197,187,246,239,151,171,242,242,110,207,159, 58,245,207,205,163, 70, 21,220, 42, 42,122, 96, 98,125, 54, 41,235, 26, 4, +165,180, 73, 85,175,213,134,226,226,226,141,243,231,205, 10, 62,120,232,168, 91, 61, 55, 23,139, 51,231, 46,223, 23,155,137, 24, +175,250, 13,120,133,133,121,252, 77,235,191, 51, 43, 42, 42,250,222, 68,185, 38,118,118,118, 72, 75, 75,195,211,167, 79,161,209, +104, 74,183,189,164, 24,218,220, 60,104,243,115, 64,212, 42,136,141, 70,168,179,210,225,225,229, 9,252,103,134, 97, 77, 13, 88, +165, 6,171,252,175,153,133, 5,132, 50, 25,120, 2,129,201, 99,176,156,157,157, 3,252,253,253,247,111,219,182, 77, 56,115,230, +204, 54, 30, 30, 30,155,210,210,210, 18, 92, 93, 93,187,173, 89,179,230,214,178,101,203,196, 35, 70,140,104,188,117,235,214, 81, + 0,182, 86,121, 19,161, 86,239, 63,113,226,196,112,119,119,119,135,200,200, 72,168,213,234,242,241,102, 0, 32, 41,255,220,227, +199,143, 85,106,181, 58,227,193,131, 7, 5, 9, 9, 9, 90,152, 48,235,111,209, 6,101,216,204, 33,174,131, 28,157, 92,110, 72, +204, 60,234,211,162,187, 3,103, 14,113, 93,179,246, 64,178,250, 84,108,108,225,194, 41, 94, 43,139, 11, 35,166, 88,185, 22,253, +112,234,216,179, 66, 83, 14,163,178, 25,131,176,181,181, 5,159,207,135, 64, 32, 64,249, 88, 36, 71, 71, 71,228,231,231, 87,219, + 69, 88, 85,227, 93, 80, 80,128,252,252,124, 60,121,254, 8,217, 69,169, 56,187, 39, 12, 70,163, 17,106,181,186,212,204, 58,186, +226,252,222, 91,230, 65,131, 91,205,183,245, 35,151,178, 35,232,109, 83,143, 83,134, 97,102, 12, 26, 52, 8, 58,157, 14, 3, 6, + 12,192,158, 61,123,102, 0,184, 92,219,227, 61, 37, 37,229, 6, 33,164,209,211,167, 79, 45,244,122,253,187,253,251,247,255,173, + 79,159, 62, 8, 11, 11,195,133, 11, 23,130,180, 90,109,140,209,104, 84, 57, 59, 59,175,112,118,118,118, 32,132,172,168,110,130, + 71, 89, 42,134,205, 77,155, 54,125,183, 75,151, 46,247,251,244,233,211,108,211,166, 77, 86, 25, 25, 25,229,147, 26,144,156,156, +140,147, 39, 79,166, 30, 59,118,172,128,101, 89, 91,134, 97, 78,100,101,101,125, 81, 85,183,160, 78,167, 59,114,236,216,177, 94, + 94, 94, 94,184,124,249, 50,150, 47, 95,142,230,205,155,227,196,137, 19,240,240,240,128,143,143, 15,108,108,108,166, 23, 20, 20, +180, 91,189,122,117, 31,127,127,127, 28, 57,114, 4,233,233,233,223, 87,151,178,193, 96, 48,212,104,176,186,118,237, 58,126,230, +204,153,232,223,191,255,217,192,192,192,214,119,238,220,249,159, 79,211,162, 80, 40, 86, 6, 7, 7,207,109,209,162, 5,126,255, +253,119,168, 3, 58, 64,246,235, 49, 60,232,215, 1, 20,128,226,215,163,160,148,226,225,128,119, 64, 1,212,239, 54, 24,115,231, +206,237, 51,112,224,192,122,168, 98,120,132, 66,161,248,246,163,143, 62,154, 53,114,228, 72,132,135,135, 99,235,214,173,184,119, +239, 94, 69,155,167,215,235, 17, 29, 29,141,232,232,104, 56, 59, 59,163, 95,191,126,100,194,132, 9,189,123,247,238,109, 15, 32, + 16, 28,175,107,176, 42,194,197,118,214,214,214, 15,127,248,225, 7,219,214,173, 91,243, 12, 6, 3, 46,133,132, 96,241, 87,179, +208,187,231,199,208,177,150, 48,104,133, 96,133, 18,211,126, 81,220, 15, 5, 49, 4,172,176, 15,180, 90, 45,198,237, 22,192,138, +100, 96,253,104, 71, 0, 32,106,181,186,194, 88,149,223, 61, 85, 23,193, 42,204,151,233,244,122, 10,101, 70, 2,146, 83, 31,194, + 66,238, 6,202,115, 67, 70, 78, 9, 8, 28, 97,208,196,192,168, 47, 53, 64, 26, 85, 50, 74,180,228,181, 42,204,152,243,215,217, +192, 70,131,233, 99, 42, 41,165, 27,118,237,218, 53,124,237,218,181,226,190,125,251,250, 57, 59, 59,247, 0,128, 33, 67,134,248, + 89, 88, 88, 96,215,174, 93, 26, 74,233,134, 55, 24,225,121, 47, 48, 48, 16, 57, 57, 57,136,143,143, 15,173,118,219,180, 90, 91, +185,131, 3, 47,227,210, 37,125, 78, 97, 97,189, 78,101,230,138, 97, 24,228,230,230,226,249,243,231,144,203,100,120, 16, 21, 37, +254,110,210,164, 93, 62,126,126, 76,249, 12, 67, 83, 56,118,236,152, 57,128,182, 53,189, 86, 27, 50, 51, 51,139,157,156,156,198, +124, 57,127,254,145,239,191,255,222, 50, 61, 35, 61, 70, 44, 18, 25,228,114,137, 98,250,244,201,252,130,130,130,225, 89, 89, 89, + 69,166,234,229,230,230, 34, 46, 46, 14,102,102,102, 16, 10, 4, 96, 85, 37, 48, 22, 23, 65,157,147, 9,158, 78, 11,145,209, 8, + 27,169, 24,110,142,142,168,103,111,103, 90,215,221,165,179, 21, 3,218, 95,236, 22, 60,221,190, 49,196,114, 25,196,114, 57, 58, +252, 81, 58,132, 77, 40, 20, 2,235,183,153,210,141, 99,167, 80, 40,254,220,180,105,147, 48, 59, 59, 27, 15, 31, 62,188, 31, 31, + 31,159,111, 99, 99, 99, 46, 16, 8,216, 39, 79,158,156,127,244,232, 81, 63, 79, 79, 79, 80, 74,107,154,253,245,221,225,195,135, +187,119,236,216,209, 80,191,126,125, 89, 70, 70, 70,189,252,252,124,146,154,250,242, 24,230,219,183,111, 75, 18, 19, 19,139, 89, +150, 61,130,210, 60, 88, 53, 30,248, 51,135,184, 74, 66,239, 98, 90,231,158, 30,205, 45,236,252,144, 99,184,219,252,198,253,212, +105, 51,135,184,110, 92,123, 32, 89,109, 70, 52,191, 17, 99,146, 27, 95,162,222, 97,226,249, 67,125,125,125, 65, 41,197,173, 91, +183,112,237,218, 53, 92,185,114, 5, 9, 9, 9, 21,159,177,180,180,196,185,115,231,208,165, 75, 23,147,143,163,146,146, 18, 56, + 59, 59,195,218,218, 26,135, 47,237,196,246, 53,123, 42, 6,186,151,147,149,149, 5,169, 84,138,101,159,175,149,143,157, 51,248, + 27, 0, 61, 76,209,118,115,115,243,236,208,161, 67, 95, 71, 71, 71,228,230,230,194,193,193, 1,173, 90,181,234,239,232,232, 88, + 63, 61, 61,189, 78, 93, 89, 90,173,118,114,151, 46, 93,150,126,254,249,231, 48, 24, 12,248,240,195, 15, 17, 23, 23,183,255,217, +179,103,235,221,221,221,167, 77,153, 50,197,209,206,206, 14,147, 39, 79,150, 1, 24, 84,141,193, 90,177,122,245,234,225,193,193, +193,140, 94,175,127,231,194,133, 11,136,143,143,135, 86,171,133,193, 96, 64,124,124, 60, 22, 45, 90,148, 90, 80, 80,208, 57, 57, + 57, 57,182,166,114,165,165,165,205,250,227,143, 63,250,120,123,123,227,204,153, 51,152, 56,113,226, 9, 11, 11,139,166,126,126, +126,245,234,213,171,135, 63,255,252, 19,102,102,102,112,118,118,118,156, 55,111, 94,191,158, 61,123,226,252,249,243, 88,178,100, +201,113, 39, 39,167,239,106, 50,193,124, 62, 31,122,253,203, 55,180, 60, 30, 15,247,238,221, 67,215,174, 93, 49,119,238, 92, 0, +192,249,243,231, 45,122,244,232,241, 32, 40, 40,200, 34, 36, 36, 68,131,255, 97,100, 50,217,152, 95,127,253, 21, 79,159, 62,197, +213,171, 87,145,149,149, 5,173, 86,139,188, 50, 43, 42, 46,139,100, 81, 23,119,180,159, 53, 31,195,250, 13, 66,106,106, 42, 24, +134,177,171,230,134,111,196,252,249,243,113,234,212, 41,172, 90,181, 10,249,249,249,149,126,206,204,204, 12,173, 90,181, 66,203, +150, 45, 17, 23, 23, 7, 0,118,224,120,115, 6,203,218,218,122,253,230,205,155,109, 59,116,232,192, 43, 51, 59,104,221,170, 21, + 70,141, 25,131,115,135,143,195,193,187, 23,136, 86, 14,131, 84,100, 90, 4,203, 98, 7,178,245,217,144, 8, 37, 16,107,181, 96, + 89, 51, 68, 36,171, 43, 92,179, 74,165, 66,185,201, 42, 46, 46,134, 76, 38,171,222, 64,104, 69,225,209,113, 6,183,252,194,123, +184,113,119, 39,244, 90, 61, 26,120,207,135, 74,111, 11,153,253,199, 80,107,255,132, 49,175,116,230,174,200, 34, 8,105,105, 89, + 0,136,169, 17,151,191,158,228,133,127, 29,236,206, 26, 77,207,187,170, 84, 42,179, 21, 10,197,214,208,208,208,233,131, 6, 13, +194,185,115,231,230, 3,192,160, 65,131, 16, 26, 26,138,184,184,184,173, 74,101,229, 51,168,106,139,139,139,203,168,206,157, 59, + 79,105,221,186, 53,142, 31, 63, 14,163,209,120,210,148,239,241, 4, 2, 74, 8, 65,249, 12,167,156,220, 92, 60,126,252, 24, 57, +217,217, 48, 26,141, 40, 81,169, 12, 77, 27, 55, 46,160, 44,107, 94,155,242,188, 56, 99,176,178, 89,132,229,175,213,118, 59,211, +210,210, 18, 26, 52,104,144, 88, 82, 82,108,111,109,101, 93, 40, 18,137,140, 5,133,133,249, 79, 99, 30,105, 77,105, 20, 94, 32, + 58, 42, 42,170, 89,114,114, 50, 18, 19, 19, 97, 40, 46, 4, 79,163, 5,163, 41, 65,183,246,237, 96, 6, 10, 9, 88, 8, 88, 61, + 4, 60, 1, 10, 75,103,219, 69,215,120,204,191,208, 32,148,155, 43, 66, 8, 36,114, 57, 68,114, 25,196,230,242,151, 34, 90,166, + 76,252, 50, 51, 51,219,189,117,235, 86,103, 39, 39, 39,172, 93,187, 22,206,206,206, 62,193,193,193, 37,157, 59,119, 54,179,179, +179,131,183,183, 55, 2, 3, 3,113,233,210, 37, 16, 66, 98,107, 56,206, 13,132,144, 30, 87,175, 94,157,117,253,250,245, 33, 10, +133,130,140, 28, 57, 18,189,122,245,130, 68, 34, 65, 73, 73, 9,114,115,115,113,226,196, 9, 98, 52, 26,253,203, 12,158,187,135, +135,199, 30, 66, 72,242,243,231,207, 63,120, 85,115,231, 58, 63, 69, 70, 14,251,177,163,147,203,192,206, 61, 61,154,119,237, 25, + 12,207, 70, 93,209,181,103, 34, 0,172,180,225,199,127,184,102, 65,179, 35,118,110, 54,191,156, 61,125,110, 81,199,206, 93,191, +156, 55,193,122,233,202,173,185, 53,142,151, 35,132, 84, 52,182, 12,195, 84, 26,165,226,243,249, 21,179,205,106,188,105, 98,141, +201,189, 70,183,171,120,174, 55,232,237, 92,156,220,152,242,200, 21, 0,228,231,231, 35, 41, 41, 9,122,189, 30,182,182,182,208, +235,117,126,181,232,126,156, 54,116,232, 80,162, 86,171, 49,107,214, 44,124,251,237,183, 24, 48, 96, 0,185,121,243,230, 52, 0, + 51,234, 16,209, 88, 51,101,202,148, 89, 99,198,140, 65, 94, 94, 30, 46, 94,188,136, 46, 93,186, 96,203,150, 45,246, 23, 47, 94, + 92,222,190,125,123,240,120, 60,156, 59,119, 14, 58,157,238,113,181, 13, 0,159,255,110,112,112, 48,147,148,148, 4,161, 80,136, +192,192, 64, 36, 39, 39,163,164,164, 4, 25, 25, 25,248,250,235,175,211,242,243,243,131, 82, 82, 82, 98, 77,216, 47, 76,135, 14, + 29,166, 55,108,216, 16, 23, 47, 94,196,164, 73,147, 78,201,100,178, 65,217,217,217, 19,212,106,245,198,161, 67,135,194,199,199, + 7, 49, 49, 49,232,219,183, 47, 90,181,106,133,139, 23, 47, 98,206,156, 57, 39,164, 82,233,251, 53,228,193,122, 18, 18, 18,210, + 44, 48, 48, 16, 37, 37, 37, 40, 40, 40,128, 64, 32,128,149,149, 21,162,163,163,209,168, 81, 35,204,157, 59, 23,107,215,174,197, +204,153, 51,217, 30, 61,122, 24,116, 58,157, 80, 36, 18,253,207, 55,210,197,197,197, 52, 53, 53, 21, 22, 22, 22, 56,112,224, 0, + 34,207,159,193,201, 79, 63,134,100,193, 26, 80, 74,145,180,116, 30,186,205, 89,128,182,247,159, 33, 53, 53, 21, 59,118,236, 0, +195, 48, 21, 51, 98,171,106,219,242,243,243,209,178,101, 75,220,186,117, 11, 59,118,236,192,186,117,235, 42,162,181, 2,129, 0, + 65, 65, 65,232,222,189, 59,158, 60,121,130,173, 91,183,194,194,194,130,115, 76,111,218, 96,177, 44,219,181, 85,171, 86,188,162, +162, 34,168,213,106,164,165,165, 33, 62, 62, 30,102, 82, 51, 36,101,165,160,133,191, 14,105,108, 1,162,239, 63, 52, 18,158,224, + 94, 77,119, 32, 90,173, 22, 90,173, 22, 17, 17, 17,165, 83,223, 27,173,168, 24,232,169,215,235,161,209,104,160, 82,169,112,241, +226, 69, 42, 22,139, 33,147,201, 72,117,125,239,172, 65,115,234,226,181,251,125, 70, 12,236, 34, 58, 23,178, 29,122, 45,139, 2, +181, 5,138, 84, 26, 20,169, 5,208,136,123,130,144,171, 96,120, 98,180,111,217, 16, 23,175,197,168,141,122,157, 73,233, 10,192, + 26,193,119,246,131, 33, 53,226, 63, 47,189, 50,155, 80, 40,149,131, 53,214,110, 86,176,153,153,217,150,221,187,119,143,105,215, +174,157,121,112,112,112, 35, 0, 16,139,197,236,238,221,187, 11,205,204,204,182,212,118, 39,190,154,189,221,217,217,185,163, 72, + 36,154,218,191,127,255,142, 99,198,140,193,195,135, 15,241,251,239,191,223, 87, 40, 20,213,142,153,225,137, 68,217, 69, 25, 25, + 86,242,250,245,249, 86,230,230,202, 51,103,206,120,188,211,185, 51, 18,226,227,145,147,147, 3,149, 74,133,168,232,104, 42,100, +152, 68, 98, 97,193, 60,190,123,151,225,137, 68,217,181, 40,103,116, 77,179, 8,235, 26,205,146,153,145, 6, 11,230, 78,240, 84, +171,213,205, 10, 10, 10, 12, 2,129, 64, 32, 21,209,132,218,104,232,245,250,227, 87,175, 94,125,175, 67,135, 14,226,152,136,123, + 48,228,231, 67,155,159, 11, 33,107,132,141,127, 11,240,116, 26, 64,171,135, 75, 19, 10,117,158, 20,215,239, 61,211,235,245,250, +227,166, 26, 44,134,199,123,121,220,149,133, 28, 98,115,115,136,228,242,151, 94, 39, 53,244,107, 57, 58, 58, 74,123,247,238,221, +205,223,191, 52,167,214,154, 53,107,160,211,233, 68,122,189,190, 98, 38, 92, 81, 81, 17, 14, 30, 60,136,157, 59,119, 94,183,180, +180,252,213,132,155, 9,131,171,171,235, 84,150,101, 29, 12, 6,131,206,222,222, 94,184,127,255,126, 72, 36, 18, 48, 12,131,150, + 45, 91, 66, 34,145,104, 20, 10,133,174,172, 12,250,181,107,215,242, 63,254,248, 99, 97,101,122,141,155,251,204,246, 52, 88,119, +150,152,121,212,183,176,243,131,103,163,174, 0,128,238,253,198,194,179, 97, 61, 20,100, 69,212, 87,171,226, 7, 10,249,185,214, + 15, 55,166, 68,153,245,109, 54,166, 56, 35,228, 9,128,159, 76, 58, 53, 89, 22,193,193,193,232,217,179,103, 69,119,160,131,131, + 3,180, 90, 45,140, 70, 99,173,198,178,149, 39, 17,253,250,107,194, 96, 17,240,107, 27,139, 52, 0,246, 47,154,171,196,196, 68, + 36, 38, 38, 86,220, 8,178,212,180, 20, 42, 10,133,194,204,211,211,115,116,179,102,205,112,225,194, 5, 68, 68, 68,164,132,132, +132,184,180,110,221, 26,174,174,174, 99, 20, 10,197,124,165, 82,105,114, 66,101,123,123,123, 89,167, 78,157, 62, 29, 51,102, 12, + 30, 61,122,132,121,243,230,101,167,166,166, 30, 57,118,236,216, 39,159,125,246, 25,211,185,115,103,100,100,100, 96,203,150, 45, +198, 91,183,110,125,107,109,109,189,164,134,253,254, 72,169, 84,186,170,213,106,228,228,228,192, 96, 48,160,164,164, 4,167, 79, +159,198,153, 51,103,210,243,242,242,130,148, 74,229, 83, 83,202,230,238,238,110, 30, 24, 24,232,248,228,201, 19,236,217,179, 7, + 58,157,110, 65,124,124,188,206,210,210,114,215,242,229,203, 23, 89, 90, 90,218, 4, 7, 7,163,252,184,253,243,207, 63,177,120, +241,226, 19,102,102,102,131,162,162,162,116, 53,200, 15,252,230,155,111,190,177,179,179,251, 96,248,240,225, 76, 96, 96, 32,238, +220,185, 3,163,209,136,110,221,186, 85,152,171,211,167, 79,239, 62,125,250,244, 96, 0, 66,185, 92, 46,249, 95,143, 94,149,163, + 86,171, 17, 19, 19, 3, 71, 71, 71, 52,108,221, 14,115, 31, 60,199,213,208, 48, 80, 74,209,241,225,115, 20, 21, 21,227,215, 95, +127, 69,120,120, 56,120, 60, 30,188,188,188,106,212,212,233,116,120,250,244, 41, 50, 51, 51, 49, 96,192, 0,140, 24, 49, 2,171, + 87,175,134, 78,167,195,151, 95,126,137,156,156, 28,108,219,182, 13, 79,159, 62, 5,159,207,135, 92, 46,231, 28,211,155, 54, 88, +101,221, 76, 96, 89, 22, 41, 41, 41,184,115,231, 14,158, 63,127, 14,153, 76, 6,149,193,200,110, 57,127,141, 37, 68,152,204, 82, +122,157, 26, 74,179,136, 87,231,196,245,122, 61,225,243,249, 8, 13, 13,197,179,103,207, 96,222,144, 86,152,171,242, 8, 86, 73, + 73, 9, 4, 2, 65, 81, 88, 88, 88,124,120,120,184, 39,159,207,215, 86,165,153, 97,157,187,227,220,133,243,179, 3, 90,250, 54, +234,222,121, 49,142, 31, 95,132,220,252, 2,148,104, 5, 40, 84,233, 80,172,162,112,177,104,132,214,126,126,200,204,209,226,201, +195,240,228, 44,161, 77,141,125, 48,122,202,228,239, 94, 57,209,242,221, 17,147, 96,230,241, 14, 52, 15, 15,128, 45, 76, 3, 91, + 88,218,109, 34,146, 89,192,220,206, 13, 69, 37,106, 92,123,240, 12,122,202,228,155, 90,233,177,177,177,133, 10,133, 98,227,204, +153, 51, 87,133,133,133,202, 0,224,222,189,123,197, 74,165,114,169, 82,169, 44,172,205, 14,124, 33,123, 59,145,201,100, 79, 26, + 54,108,168,239,219,183,175,237,192,129, 3, 97,103,103,135,187,119,239, 98,229,202,149,119,139,139,139,135,197,199,199,235,107, +232,118, 72, 9,255,227, 15,139,160,145, 35,173,230, 13, 24,176,114,242,228,201,223, 47, 89,178, 68,216,160, 97, 67,176, 70, 35, +162,162,162,232,174, 93,187, 12, 63, 45, 92,184, 70, 36,147,241,111, 29, 61, 42, 48,104, 52, 41,255,237,131,216,213,213,181,115, +159, 94,157,155,124,187,118, 35,212,170, 34,220, 12, 61,129,220,220, 76,108,221,118,184,137,171,171,107,103, 83, 7, 19, 39, 39, + 39,239, 59,116,232,208, 44, 63,223, 38,254, 94,110,110,136, 76,120, 14, 17,107,132,208, 96, 0, 79,167, 1, 99, 80,195,173, 25, + 5, 97,204,145,150, 86,136, 45,103, 46, 62, 72, 78, 78,222, 87, 99, 36,177,247,187, 24,150,144, 15, 66, 8,206,118,242,133,196, + 92, 14,145, 76,134,246,135, 46, 87,152,170,132, 21,159, 67, 32,147,195,186,245, 59, 53,150, 51, 61, 61,189,164, 97,195,134,119, + 30, 61,122,212,170,113,227,198,248,250,235,175,145,148,148, 4, 74, 41, 50, 50, 50,212,153,153,153, 41,217,217,217,241,132,144, + 35, 74,165,114,187,169, 75,145,176, 44,235,112,236,216, 49, 0, 16, 2,192,133, 11, 23,160, 80, 40, 96,105,105,137,130,130, 2, +140, 28, 57, 82,252,213, 87, 95, 1, 0,238,220,185, 35, 48, 51, 51,171, 82, 43, 50, 60,250,219,188, 66,154, 75,139,238, 14,204, + 49,220,109,222,181,103, 18,186,247, 27,131,115,199,127,197,197, 51,231, 97,195,143,127, 14, 89,225,169,172,231, 89, 5,201,197, +141,126,108, 18,240, 9, 47,181,248,204,143,211, 6, 88,243,156,157,217, 3,243, 54, 87,157,184,183,252, 14,156,199,227, 85,140, +193, 42, 31,208, 94, 91,115,245, 34,139, 22, 81,150,128, 16, 47,161, 48, 34, 37, 45,169,187,194,209, 21,233,233,233, 72, 74, 74, + 66, 98, 98, 34,146,146,146,208,176, 97, 67, 60, 79,120, 6,145, 72,120,207,196, 40,248,240,254,253,251,155,107,181, 90,252,241, +199, 31, 6, 66, 72,191, 99,199,142,221,105,209,162, 5,191, 75,151, 46,230,191,254,250,235,112, 0,219,107,115, 47, 33,151,203, +133, 58,157, 14,191,253,246, 27,146,147,147, 59,167,165,165, 69, 43, 20,138, 31, 39, 78,156,184,185, 73,147, 38, 13,163,163,163, +159,168, 84,170,201, 74,165, 50,162, 38,177,188,188,188,177,189,122,245, 58,192,178,172,123,199,142, 29,101,139, 22, 45,178,120, +252,248, 49, 60, 60, 60, 64, 41,141,172,205, 82, 83, 9, 9, 9,133,215,174, 93, 75,111,218,180,169,163,179,179, 51,132, 66,225, + 74,103,103,231,165,114,185,252,219, 46, 93,186,216,236,218,181, 11,103,206,156,129, 64, 32,192,179,103,207,148,143, 30, 61, 90, +239,228,228,180,193,148, 12,238,225,225,225,113, 0,134,181,110,221,122,241,186,117,235, 22, 48, 12,243,209,217,179,103, 33, 16, + 8, 0,160,194, 92,213,175, 95,127,212,129, 3, 7, 70,188,101,237,180, 94,171,213,194,214,214, 22,153,153,153,200,200,200, 64, +189,122,245,208,174, 93, 59,232,245,122, 28, 61,126, 2, 87,175, 94, 5,165, 20,118,118,118,176,180,180,196,253,251,247, 1,160, +186,217,195,122,157, 78, 7, 27, 27, 27,228,229,229,225,254,253,251,112,112,112,192,204,153, 51,161,213,106,177,127,255,126,220, +187,119, 15, 12,195,192,193,193, 1,230,230,230,166,104,114,212,214, 96,241,120,188, 75,151, 46, 93, 26,236,231,231,199,127,250, +244, 41,158, 62, 45,189,153, 81,169, 84, 6, 62, 15, 7,211, 35,254, 24, 86, 77,227, 31,252, 98,174, 12,145, 72,180,101,240,224, +193,147,199,142, 29,139,169, 83,167,130, 16,130, 95,238,105,145,152,200, 66,175,215, 35, 61, 61, 29,145,145,145,180, 85,171, 86, +132,101, 89, 93, 80, 80,208,184,240,240,240,214, 60, 30,175,160, 42, 77, 26, 18, 98,112,108, 62,240,253, 31,182,108,191, 60,122, +244,104,155,254, 3,126,192,189,232, 40,228,151,216, 3,148,194,197, 94,142,214,222,159, 35, 35, 91,141, 51,167,142,231,178, 6, +245,251,244,193, 94,125,117,229, 4,128, 76,190,202,225,199,157,135,214,236, 61,112,120,220,248, 49,195, 37, 65,193, 35, 33,204, +138,132, 65, 25, 14, 23,223,142,160,124, 51,220, 10,191,139,136,167, 73,234, 18, 29,111,123,129, 80, 53,187, 38,205, 23,201,205, +205, 61,153,150,150,250, 67,249,228, 0,134, 33, 50,145, 72,124,178, 6, 51, 21,252, 74, 94,160, 87, 51,196,123,175, 88,177, 34, +195,214,214,150,125,248,240, 33,182,108,217, 98,188,115,231,206, 33,150,101, 23,100,101,101,149,212,164,105,175,215,223,223, 61, +111,158,111,235, 65,131,232,192,113,227,212,140, 68, 50,121,229,218,181,243,179,243,243, 93, 0,192,198,202, 42,105,235,226,197, + 75,122,247,233, 83,248,240,218, 53,179,208, 63,254, 48, 19, 25, 12,225, 53,149,243, 77, 80,157,102,114,114,242,229, 70, 13,234, +225,183,237,107,161,211,105,144,154, 82, 26,184,202,202,206, 71,117,230,234, 47,199, 82,233, 44,170, 65,235,214,111,184, 49,105, +228, 71, 78,239,116, 11, 70,226,253,123,208,229,100,130,232, 13, 16, 16, 62,138, 51,164,200, 72, 47,194,138,147,231, 51, 84,106, +245,160, 87, 19, 57, 86, 85,206,138,110, 65, 11,115,136,100,165,227,174, 94,140, 90, 9,205, 45, 32,144,201,193, 19, 10, 43, 27, + 12, 31, 92, 73, 78,185,247,199,143, 31, 31,113,242,228, 73,235, 97,195,134,225,221,119,223,189,155,151,151,215, 37, 39, 39,167, +176,174,245,201, 48, 76, 70,159, 62,125, 28,180, 90,173, 97,232,208,161,252,172,172, 44,148, 79,177, 47, 42, 42,194,169, 83,167, +208,184,113,233,236,252,135, 15, 31,162,105,211,166, 85,106,126, 50, 39, 50, 5,192,146,153, 67, 92,215,220,184,159, 58, 13,192, + 74,207,134,110,184,120,230, 60,174, 94, 12,157,215,182, 25,187,177,207,136, 86,223, 72,187,124, 48,187, 73,192, 39, 60,185,133, + 51,118, 28, 62,196,139, 14,255,105, 89, 73, 73,100, 3, 0,159, 87, 85,206,242,238,235, 87, 83, 50,168, 84, 42,147,204, 85,117, +199, 18, 5,165,118,249,100,254,216, 89, 67,218,156,219,115,211, 92, 46,151, 67,167,211,129, 82,138, 6, 13, 26,128, 47,224,227, +231, 35,223, 23,231,229,101, 45, 52, 69, 83, 38,147, 77, 13, 10, 10, 66,108,108, 44, 34, 34, 34, 14, 41,149,202, 8,133, 66,113, + 40, 46, 46,110,104,155, 54,109,176,111,223,190,169, 85, 25,172,170, 52,203, 51,214, 83, 74, 97, 52, 26,115, 0, 64,169, 84,222, + 55, 37,250,251,170,102, 89,178,208, 14, 0,208,164, 73,147, 36, 71, 71, 71,139,251,247,239,195,217,217, 25, 58,157,174, 77,109, +142, 37, 74, 41,171, 80, 40, 54,220,186,117,107, 69,203,150, 45,241,225,135, 31,118,191,115,231, 78,247, 22, 45, 90,192,203,203, + 11,215,175, 95,199,217,179,103,127,103, 89,118, 98,106,106,170,186,186, 36,168, 85,109,251,173, 91,183,158, 2, 24, 25, 16, 16, +240, 1,159,207,135,133,133, 5, 47, 37, 37,133,119,246,236, 89, 0, 24,127,224,192, 1, 99, 93,246,251,223,113, 93,122, 83,154, +132,144, 47, 71,141, 26,245,227,132, 9, 19, 36,109,218,180,121, 41,162,122,242,228, 73,176, 44, 11, 91, 91, 91,216,218,218,226, +233,211,167, 56,114,228,136, 54, 63, 63,127,189, 80, 40, 92, 89,157,230,200,145, 35,127,156, 48, 97,130,164,117,235,214,200,207, +207,175, 48,111,199,143, 31, 7, 33, 4,118,118,118,176,181,181,197,147, 39, 79,112,228,200, 17,117,110,110,238, 90,173, 86,187, +250,239,220,246,127,157,193,202,201,201,153,254,197, 23, 95,116, 25, 55,110,156,109,113,113, 49,207,214,214, 22,105,105,105,134, +211,167, 79,231, 20, 22, 22, 78,175,205,143,133,134,134, 78,233,215,175,223,250, 95,126,249,101,219,246,237,219, 59, 15, 29, 58, + 20, 35,251,246,197,164,182, 82,104, 52, 26, 16, 66,112,230,204,153,199,151, 46, 93,242, 20, 10,133,154, 69,139, 22,177, 0,110, +212,120, 71, 31,121, 36,202,177,249,192,206, 27,191,223,124,208, 63,176,173,187, 71,125, 15,113,123, 87, 75,232,244, 70,164,103, +100,227,114,232, 67, 77, 76,212,189, 20,170,211,189,159, 17, 85,115, 22,119, 0,136,138,162, 58, 0,211,125,125, 45,190, 94,253, +227,174, 45, 59,247, 28, 28, 56,126,196, 32,190,127,139,110,136, 11, 61,130, 43, 55, 46, 26,114,213,244, 72,161,128, 55, 41,234, +105, 65,110,109, 43, 94,163,209,104, 9, 1,197,127,178,175, 83,141, 70,163,173,203,249,248,226,147,159,127,254, 25,169,169,169, +154,132,132,132,189,148,210, 31, 83, 83, 83, 77, 78,159,176,145, 82,237, 32, 66,206, 47,232,216,177,215,130, 51,103, 36, 67, 62, +253, 84, 59,240,253,247,103, 67,163,209, 65, 36,162,124,153,140,129, 88, 44,120,120,237,154,217,134, 73,147,108,136, 86,123,238, + 87, 74, 77, 14,193,255, 29,179, 8, 95,136, 96, 97,244, 39,159, 65,245, 66, 4, 43,236,118, 12,106, 19,193, 2,128,212,212,212, + 68,103,103,231,182, 75, 55,108, 60,220,187,109,235, 38,141, 20,206, 98,219,250, 30,144, 59, 57, 33, 39, 43, 11, 55,239,197,234, +191, 63,127,249,129, 74,173, 30,100,106, 94, 24,150,101, 43,102,185,249,126, 58, 23, 12,143, 87, 97, 4,202,147, 6, 90, 4,118, + 4,225,243, 97,164, 20, 58,157,174,198, 65, 88, 74,165, 50,217,197,197,229,253, 79, 63,253,244,194,111,191,253,198, 4, 5, 5, +181,252,243,207, 63, 95,107,209,220,228,228,100,215,178,110,173, 2, 11, 11, 11,254,152, 49, 99,160,215,235, 81, 82, 82,130,252, +252,124,100,103,103,107,102,204,152, 33, 6, 0,161, 80,168,239,213,171, 87,141,215,143,181, 7,146,213, 51,135,184,110,180,225, +199,127, 88,144, 21, 81,223,134, 31,255,188,109, 51,118,227,218, 3,201,234,175, 63,179, 90,154, 21,127, 57, 38,181,248,204,143, + 59, 14, 31,226,141, 26,248,190,209, 85,254,100,158,196,129, 30,236,218,191,198, 70,232, 47, 73, 69,235, 26,185,122,149,172, 7, +244,174,103, 71,235, 21, 93,134,180,158,191,116,214, 90,185,131,131, 61, 12, 70, 3,158, 39,198,225,151,195,155,138, 11, 53,185, +203,178,163,232, 29, 83,180, 60, 61, 61,235,243,120, 60, 28, 61,122, 20, 0, 54,149,189,188,233,244,233,211, 67,135, 13, 27, 6, +119,119,119, 95, 15, 15, 15,113,117,105, 52, 42,139,222,233,245,122,188,233,117,173, 9, 33,207,182,108,217,226, 98, 99, 99, 67, +174, 94,189,106, 96, 24,230, 88,109, 53,156,156,156,190, 59,113,226, 68, 39, 74,105, 47,127,127,127,184,187,187,151, 93, 79,163, +112,245,234,213, 61, 41, 41, 41,163,223,208,226,206,148, 16,130,130,130,130,242,129,118, 58,185, 92,254, 86, 46, 26,157,146,146, +178,211,209,209,241,204,226,197,139,191,106,208,160,193,196,241,227,199,243,188,189,189,145,159,159, 15, 11, 11, 11, 40, 20, 10, +164,164,164, 96,231,206,157,198,140,140,140, 95, 24,134,249, 90,169, 84, 42,235,170,105,109,109, 13,103,103,103, 36, 39, 39,151, +107,110,211,235,245, 75, 50, 51, 51,211,193,241,102, 13, 86, 90, 90, 90,150,147,147, 83,211,159,127,254,121, 67,105,154,134,210, +168, 86, 97, 97,225,244,180,210, 17,227,181,226,248,241,227,177, 0,130,250,245,235,215,224,224,193,131,219,118,239,222,221,121, +192,128, 1, 24, 58,116, 40, 12, 6, 3,122,247,238, 61,250,213,168,149, 41,164, 71, 30,137, 34, 65, 65, 77,239,220,188, 50,242, +238,157, 27,253, 40,165,126, 0, 8, 97,152,255, 44,246, 28, 85,251,197,158,163,162, 10,114, 1,124,224,239,106,225,181,108,211, +174,237,102,124,182,163,202,192, 92, 83,105,152,113,119,147, 11,234,188,192,104, 89,230,245, 85, 12, 67,230,148, 62, 55,109,105, +152, 42, 52,230, 2, 0,159, 47,216,119,231,206,157,249, 9, 9, 9, 41,166,204,240,170,140,195,148, 38,142, 36,228,236,108, 63, +191,110,253,102,204, 16, 4,244,232, 97,110,227,230,198, 82, 74,141,207,111,222, 36, 97, 71,143, 10,194,142, 30,149,232, 53,154, + 11, 7, 40,173,213, 12,168,191, 99, 22, 97,121, 4,171,129,151,235,217,193,131,250,244,240,170,175, 0, 0, 60,123,174, 68, 86, + 78,254,217,218,230, 26, 42, 55, 89,132,144,192, 63, 13,134,161, 2,129,160, 31, 41, 75,197, 64,235,176,216,179,209,104, 76,110, +219,182,138,205, 91,180,178, 42, 67,150,110,226,133, 55, 68,161, 80,124,212,190,125,251,149, 74,165,242,112,102,102,102,241, 27, +186, 46,244,222,189,123,247, 73,150,101,205, 94,137,112, 21, 40,149, 74,243,178,134,212,253,244,233,211,123, 8, 33, 53, 26,248, +181, 7,146,213,107, 22, 52, 59,162, 86,197, 15, 36,242,146, 35,107, 55,148,206,106, 89,180, 46, 47, 31,192, 79,211, 6,218,176, +209,225, 63,173,118,177,120, 50,103,195,145,156, 95,106,210, 99, 24,230, 73,155, 54,109, 42,140, 86, 13,245,175,172, 75, 5,196, + 93,203, 93,105,235, 71, 46,125, 60,119,240, 55, 90,157,174, 5, 67, 64, 5, 66,225,253,188,188,172,133,166,154,171, 50, 99,241, +195,172, 89,179,166,199,198,198,238, 41,207,121,167, 84, 42, 67, 21, 10,197,119,137,137,137, 83,146,146,146, 54, 37, 37, 37,153, +108,174,228,114,185, 90,165, 82,177, 6,131,129,209,104, 52, 16,137, 68,186, 55,213, 24, 20, 23, 23, 15,223,188,121,243,207,122, +189,190, 9, 33,228, 88, 94, 94, 94,173,179,222,134,135,135,235,125,125,125, 7,156, 56,113, 98,250,131, 7, 15,102, 58, 58, 58, + 58,166,167,167, 39, 36, 38, 38,174, 72, 75, 75,251,233, 13,153, 43,132,135,135,139, 3, 2, 2, 52, 47,212,139,197,219, 50,222, +170,210,246, 45, 61, 61, 19,192, 84, 87, 87,215,245,179,103,207, 94,214,162, 69,139,193, 99,199,142, 37, 82,169, 20,251,247,239, + 71,124,124,252, 17, 74,233,252,218,116,233, 86,165,105,102,102,134,253,251,247,211,248,248,248, 3, 12,195, 44, 80, 42,149,255, +138,133,180,255, 14,200,155,190, 11,170,109,248,180, 95,191,126, 13,178,178,178,182,105, 52,154,119, 0, 20, 71, 68, 68,152,255, +183, 67,178,213, 17,228,107, 47, 11,137,170,185, 33, 51, 85,243,213, 1,234,117,209,172,141,134,169,154, 85, 45,246,204,106, 52, + 74, 91,131,225,206, 70, 74,181,166,106,186,184,184, 44,129,137,249,162,202,136, 78, 73, 73,249,170, 46,245,217,168, 81, 35,250, +244,233, 83, 80, 74,201,155,220,239,127,199,177,244,111,210,220,185,206, 79,209,184,185,207,236,200,240,232,111,203,186, 15, 43, +248,122,154,141,121,199,174, 65, 11,175, 93, 12,249,102,209,198,151,187, 56,223,134,109, 39,132, 48,149, 25,139,242,228,158,181, +213,172, 87,175,222,143,254,254,254,227,238,222,189,251,115, 98, 98,226,248,127,234,182, 19, 66,136,187,187,187,168, 54,209, 57, +238, 60, 50, 77,211,201,201, 41,144, 97,152,133,101, 55, 28,203,146,147,147,111,189, 65, 77, 35,165,116,105,106,106,234,221,255, +239,109,255,215, 69,176,254,110,202, 35, 90,239,190,251,174, 3,143,199,251,199, 47,210,105,138,185,170,109, 20,234,159,160,241, + 42,101, 6, 42,244, 77,104,189,106,150,254, 78,158, 60,121, 66,184,211,250,159,199,200,207, 34,148, 0,102, 4, 86,146,154,170, +204, 84,205,238,242,238,219,185,237, 85, 69,109,234,186, 16,115, 98, 98,226, 68,133, 66, 49,179, 54,179, 15,255, 75,219, 77, 1, +104,184,163,255,205,147,150,150,118, 7, 64,255,127,186, 38,103,176,254, 33,252,249,231,159, 25,220,238,224,224,224,224,168,153, +127,186,185,226,224,224, 40, 29, 32, 29, 92,197,221,135,201,161, 63, 66, 72,112, 29,238,110,206,115,154,156, 38,167,201,105,114, +154,156, 38,167,249,239,210,252,215, 80, 62,139,233,239,120, 0, 8,230, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252, +183, 61, 24,206, 98,114,252,221,124, 63,136,184,124, 63,136,184,252, 93,159,231,224,224,224,224,224,248,167,193,127,219, 54, 40, + 48, 48,208,151, 82, 58,156, 16, 50,184, 44, 66,119,144, 16,178,251,206,157, 59, 38,101,160, 53, 51, 51, 75, 87,171,213, 14, 0, + 32,145, 72, 50,212,106,181,211,139,209, 82,224, 47, 75,100,208,210,159,169,122,192,170,167,167,103,186, 70,163,113, 48, 33,154, +120,153, 16,114,133, 97,152,203,117, 73, 47,208,181,107,215,209, 60, 30,111, 25, 0, 24,141,198, 47, 47, 94,188,248,219,223, 85, +207,132,144, 54,110, 10,167, 95,117,122,157, 33, 61, 51,103, 33,165,244,104,101,159,219,220,159,172,224, 19,204, 46,251,127,205, +228, 99,180,218,169,223,181,253,124, 53,229, 11, 20, 8, 4, 83, 29, 29, 29,123, 39, 39, 39,223, 1, 48,135, 82, 90,227, 49, 96, +229,226, 59, 82, 32, 16,140,208, 27,141, 94, 2, 30,239,153, 94,175,223,149,151, 18,181,147,187, 84,112,112,112,112,112,252,109, + 6,171, 93, 35, 91,111, 66,117,179, 5,132,118,210, 83,114,149, 18,225,154,176, 39,217, 49,175, 83, 0,133, 66,225, 70, 8, 9, +162,148, 54, 97, 24, 38,146,101,217,179,181, 93,236, 56, 32, 32,192, 13,192,135, 0,134,181,109,219,182,217,164, 73,147,208,176, + 97, 67,168,213,106,220,186,117,107,222,174, 93,187,230, 5, 4, 4, 60, 0,176, 7,192,222,240,240,240,164,170,180,212,106,181, + 67,185, 87, 34,132, 56, 12, 30, 60,248,214,139,166,170,108,113, 89, 66, 41, 13, 35,132,132, 26,141,198, 27, 7, 14, 28, 72,242, + 33,164,205,132,250,194,131,211,227,180,174,175,106,106, 52, 26,135,227, 51,167,128, 82, 22,234,236, 44,116, 88,185,161,226,189, + 83,189,218,130, 49,234, 33, 18, 11, 47, 7, 29, 11,187, 2,224,114,217,163,214,240,120,188,101,167, 79,159,118,166,148,162,103, +207,158,203, 0,252, 45, 6,139, 16, 34,110, 27,216,226,210,177, 67,123, 36, 69, 57,233,232, 53, 96,232, 46, 66,200,104, 74,233, +161,151,204, 82, 31,226, 72,248,152, 61,105,249,110, 30, 0,108,158, 63,124,206,250,158,100,227,140, 51, 52,205,197,197,165, 11, +165,116, 78,153,222,234,148,148,148, 75,155,251, 16, 71,240, 48,119,210,242,221, 4, 0,182,204, 31, 62,123,115, 31,178, 97,242, +201,218,205,146, 36,132, 76, 30, 61,122,244,198,101,203,150,241,156,157,157,145,146,146,210,203,215,215,215,155, 16,226, 75, 41, +173,114,112,176, 77, 61,191,125,189,122,245,246,252,112,200, 32,169,189,157, 53,146, 83,179, 44,126,223,181,123,130, 77, 61,191, +222, 57,137, 17, 67,185,203, 5, 7, 7, 7, 7,199, 27, 51, 88,205,154, 89, 90,153,169,232, 76, 51, 33,253,176, 87, 27,223,250, +253,187,183, 39,158,158,158,136,121, 28,227,117,233,250,237, 49, 93,124,204,159,171,116,100,175,202,140,172,125,240,160,250,245, +195, 70,251, 19,189,222, 88,250,155, 66, 62,140, 23, 51, 93,143, 4, 7, 7,215, 31, 59,118, 44,252,253,253,113,231,206,157, 46, + 7, 14, 28,152,238,230,230,118, 91,175,215,159, 20,139,197, 33, 53,229, 80, 9, 8, 8, 88,233,226,226, 50,103,214,172, 89, 36, + 48, 48, 16, 98,177,184,226, 61,185, 92,142,110,221,186,161, 91,183,110, 72, 79, 79,111,118,233,210,165,102,187,119,239, 94, 17, + 16, 16,176, 58, 60, 60,124,158, 41, 21,180,112,225,194,192, 74, 94, 62, 77, 8,137, 53, 24, 12,247,252,252,252,146, 26, 19,210, +112, 98,159,246,231, 38,119,104, 36,171, 38, 58,133,219,203, 74, 87,215,120,209, 96,209,146, 66, 8, 44,204, 47, 11,228,242,191, +152,171, 38,132,180,104,107,205,252,250, 83,142,209,175, 22, 38, 11, 73, 73, 73,176,180,180, 52, 11, 10, 10, 74, 37,132, 44,190, +116,233,210,182, 55,124,220,180, 89, 60,123,178, 48, 55, 62, 2,105,143,194, 48,115, 72, 71,233,140,239,255,252, 6,192,161,234, +141, 15,195,252,246,204,110,222, 12, 96, 58,203,178, 11,163,163,163, 59, 3, 64,147, 38, 77, 68, 0, 46,237,120,106,221,103,116, +147,252, 58,167, 89, 32,132, 8,121, 60,222, 15, 59,118,236,248,100,228,200,145, 72, 72, 72,192,181,107,215, 32,151,203,177,100, +201, 18,143, 89,179,102,173, 0, 48,189,170,200, 85,207, 94,125, 60,183,124,187,192,183, 48, 39, 95,179,245,135,253,183, 21,205, + 26, 51, 51,166, 77, 49,215, 26,116, 78, 86, 46,190, 35,185, 72, 22, 7, 7, 7, 7,199, 27, 49, 88,157, 26,202,110, 13, 12,104, + 16,208, 63,184, 61,211,168,177, 47,132, 18,105,197,123,205, 91,250,163,121, 75,127, 50,126, 76,161,231,253,251,247, 23,156,190, +124,115,126,167,134,178,240,171, 79,139, 91, 87,165,167, 55,130,191,123,247,110, 0,192,119,159, 15,231,253,112, 53,166,254,139, + 11,198,118,238,220, 25,157, 59,119,102, 86,172, 88,209,230,210,165, 75,109,246,238,221,171,115,113,113, 89,159,146,146,114,160, +154, 98,206, 57,112,224, 0,225,241,120,224,241,120, 85,126,200,209,209, 17,221,187,119,135,179,179, 51,249,252,243,207,231, 0, +168,212, 96, 73, 36,146, 12, 66,136, 3, 0,216,216,216, 24, 23, 47, 94,124,143,210,138, 30, 64, 74, 41, 13, 99, 24,230, 6,203, +178, 55,143, 30, 61,154,220,148, 16,135,126, 1,141,175, 78,254,104,176,148, 30, 92, 95,165, 57,208,228,229, 84,250,186, 72, 38, +189, 44,146,201,174,136,205,204, 94, 50, 87, 77, 9,113,109,219,184,254,217,205,159, 13, 55, 55, 49,138,231,221,165, 75, 23,137, +209,104, 68,113,113, 49,182,108,217, 98,105,102,102,102,217,187,119,239, 69, 0, 42, 12,150, 47, 33,205,223, 87,240,198, 47, 78, + 49, 76,169,131,129,177,234,212, 46, 48,254,251,149,139, 44, 2,219,118,194,147, 75,191, 35, 39,167, 16,249,121, 69,120, 53,235, + 55, 0, 76, 62, 73,211, 55,247, 39,107, 54,127, 49,124, 46, 97, 24,210, 98,224, 28,244,244,166,211, 20, 10,197, 67, 66,136,160, +124,249, 24, 66, 8,223,213,213, 85,225,237,221,114, 77,163,158, 62,216,242,229, 71,160,165,139, 52,174, 49, 53,122, 69, 8,113, + 48, 55, 55, 63,122,246,236,217, 54,173, 90,181,194,141, 27, 55, 16, 23, 23,135,201,147, 39,107,167, 76,153, 34, 28, 53,106, 20, +153, 57,115,230,167,132,144,131,148,210,235,175,126, 95, 32, 16,140,248, 96,208,123,162,162,188, 2,181, 86,163,211,218,216, 89, +177,154, 98,117, 73, 86,110,129,250,163,225, 35,180,247,238,132,143, 0,240, 23,131,245, 58,245,201,193,193,193,193,241, 47, 53, + 88, 18,158,177,213,226, 61,247, 97,204,137, 5,205, 79, 4, 45, 78,251,203,103,164,118,110,240,105,231, 8,169,149, 61, 19,249, +104, 93,171, 87,162, 54,213, 78,213, 44, 55, 87, 91,135, 43,154, 22,231,166, 10, 1, 64,102,237,172, 27,191, 43,229, 97,171, 86, +173, 96,111,111, 47, 12, 13, 13,157, 9,224, 64, 53,154, 68, 27, 25,142, 71,253,218,163,193,163, 28, 72,165, 82,136, 68,162,151, + 62, 16, 19, 19,131, 43, 87,174, 32, 49, 49, 17, 94, 94, 94,192, 43,227,168, 94,212, 84,169, 84,142,189,122,245, 10, 89,189,122, +117,231,239,190,251,238,193,142, 29, 59, 58, 87,213,173,228, 75,136,172,133,135, 83,200, 55,159, 79,176,166,167,126,101, 74,178, + 51, 32,172,162,156,237,151,173, 69,251,101,107, 1, 0,251,125,157, 33,177, 48,135, 68, 46,191, 28,124,230,206, 95, 34, 87, 1, +132, 88,120, 57,219, 94,220,180,120,186, 12, 23,247,137, 48,110, 73,181,245, 25, 16, 16,224, 29, 20, 20, 20,186,116,233, 82,171, +164,164, 36, 92,191,126, 29, 30, 30, 30, 40, 41, 41,121,105,189, 50, 95, 66, 28, 91, 55,118, 63, 59,127,214, 24, 75, 0, 83, 76, +217, 71, 47,153, 16, 30,239,155,111, 23,207,177,176, 20, 83,196, 94, 63,130,184,216,231,184, 21,245, 92,191,243, 92,132, 81,171, + 55,142,173,172, 62, 39, 31,163, 95,204,234, 38,254,245, 78,161,215,177,126, 93,166, 52, 90, 58,204, 17, 58,157,110,123,102,102, + 38,198,143, 31, 15,150,101,209,177, 99,199, 14,148,210,148,105,211,166,193,203,203, 11,219,206,196,148,240,115,110, 6,237, 10, + 45,184, 99,202,177, 68, 8,105,230,238,238,126,246,210,165, 75,142, 46, 46, 46, 8, 9, 9, 65, 90, 90, 26,156,156,156, 48,101, +202, 20,209,202,149, 43,119, 20, 20, 20, 12, 89,182,108,153,228,193,131, 7,123, 9, 33,110,101,166,185, 66,211,200, 26, 21,158, + 30, 10,249,161,189,103,238, 91,155, 75, 81,207,203, 77,200,147, 91, 24, 41, 72, 73, 61,103,123,161,145, 53, 42, 42,217,255,175, + 85,159,166,194,105,114,154,156, 38,167,249,111,208,252, 87, 25,172,114,116,113, 33, 16,249, 14, 2,216,166,160,185,177, 96, 11, + 82, 64,165, 14, 40,102,205,144,165, 76,192,163,171, 7, 64,117, 53,231,189, 19,240, 96, 88, 48,101, 56,223, 74, 2,136,204,237, +117,133,133,133,144,201,100, 40,206, 77, 21,206,250,182, 34,178, 37,188,116,233, 18,194,195,195,161, 80, 40, 76, 42, 35,213,150, +246, 34,106,181, 90,104,181, 90,164,245,105, 13, 89,219,119,144,251,209, 20, 92,184,112, 1, 25, 25, 25, 16, 10,133, 16,137, 68, + 48, 24,106, 78, 22,207,148,173, 26, 91, 30,181,170,236, 51, 65,132,240, 93,109,228,199, 54, 47,154, 94,159, 9, 59, 46, 80, 37, + 62,133, 82,109,132,149, 9,245, 41,150,203, 32,146,154, 93, 22,201,101,149,153, 43,129, 76, 46, 57,246,235,210,153, 78,188,187, + 23, 36,170,167, 17, 21,166,237, 69,186,119,239, 62, 1,192, 34, 74,105, 94, 80, 80,144,227,178,101,203,172, 83, 82, 82, 16, 21, + 21,133,253,251,247,103, 26, 74, 55,148, 80, 74,191, 6,128,118,132, 72,234,217, 91,157,217,244,213,116,115, 92,218, 39,194,199, +181, 79,174,110,217,164,255,137,247, 71, 77,154,178,113,122,127, 20, 23,170,176,251,220, 93,156, 14,143,125, 23,192, 53, 74,105, +149, 25,238,191,187,160,121,234,226,226,210,109,220,184,113,247, 14, 31, 62,108,247,237,183,223,194,104, 52,194, 96, 48,192, 96, + 48, 84,252,111, 52, 26,177,103,207, 30, 92,187, 19, 53, 77,169, 44, 48,105,189, 55, 66,136,162,126,253,250,231,111,222,188,105, + 47,149, 74,113,238,220, 57,228,229,229, 85, 68,174, 70,143, 30, 77,242,242,242, 62,220,178,101,203,251,241,241,241,223, 94,189, +122, 53, 27, 0, 15,128,225,229,125,206,143, 53, 24,244, 62,206, 77, 26,242,135,244,239,212,169, 40, 59, 2,114, 91, 63,132,221, +143, 61,150,155,155,167, 98, 24,126,236,139,159,127, 19,245,201,193,193,193,193,241, 47, 55, 88,234,251,187,160,137,220, 7,161, + 87, 23,136,154, 14,133,192,181, 29,146, 34, 67,112,239,228,119, 72,126,120, 13,148, 53,194,209,163,230,165,230,126,187, 75, 5, + 10,133, 34, 92,169, 84,226,238,221,187,136,141,141,133, 68, 34,249,203,231, 46, 92,184, 0, 0,112,114,114, 50,105, 35, 68,129, +237,225,118, 63, 21, 73, 45,156, 1, 0,110,247, 83, 1, 0, 43,230,207,135, 80, 40,132, 80, 40,172, 88, 20,214, 20,131, 69,202, + 62,204,150,118, 83,209,202,222, 15, 20, 11,118,239, 93, 52,181,181, 56, 62, 82,164,121, 16, 6,165,134,165,199,210,141, 39,124, + 77, 49, 88, 82,233,101,145, 92,126, 69, 40,147,189,100,174, 0,128, 10, 4, 59,127,255,122,170,159, 44,253,153, 76,125,251, 2, + 82,213,172,206,162,114,153,175, 79,157, 58,229,192,231,243,157,140, 70, 35, 18, 19, 19,241,240,225, 67,108,216,176, 33,189,176, +176, 48, 40, 60, 60, 60,230,133,242, 50,173,204, 68,251,119, 46,153,238,201,143,184, 44,209,196, 62,168,212,180, 85,135,125,243, +129, 61,223, 13,106,113, 98,194, 71, 95,226,189, 62, 61, 48, 42,200,151, 62, 87,230,168, 1,156,163,148, 26,107,250,126, 74, 74, + 74,138,139,139, 75,247, 65,131, 6,237,106,218,180,105, 19, 74, 41,124,124,124, 48, 96,192, 0, 28, 58,116, 8, 81, 81, 81, 40, + 44, 44,212, 93,189,122,117,189, 82,169,252,197,148, 50, 17, 66,164,214,214,214,167, 47, 94,188,104, 47,149, 74,113,246,236, 89, +168, 84, 42, 56, 59, 59,191, 20,185, 90,177, 98,133,228,249,243,231,155,206,156, 57,227, 1,128,169,108, 33,108,157, 65,179,237, +151, 29,123, 55,206,252,116,156,203,197, 27, 81, 23, 52, 69,133,150,238,238, 73, 5,246,214,114,243,101, 43, 86,213,211, 25,180, + 19, 42,175,207,144, 58,213, 39, 7, 7, 7, 7,199,191,220, 96,149,119, 49, 81,214, 0,237,211,115,208, 62, 61, 7, 89,151, 5, + 56,186,124,196, 75,159, 51, 26,245,117, 42,128, 90,173,134, 80,110,171,251,238,243,225, 66, 0, 96, 5,178,138,213,225, 89,214, +180,133,215,107,179,164, 87,109, 12, 86,153,238, 95,204, 67,125,177,252,242,182,207,134,180,181, 53,150, 8,180,215,142, 33, 69, +195, 26,190,125,170, 43,185,157, 71, 87,207,175, 66,243,120,247,214,208,231,102, 65, 98, 46,187,220,235,210,131, 74,103, 11,214, +151, 88, 92,216, 63,115, 88, 71, 39, 33,132,218, 19, 7,160,212,176,154, 31,227,245,191,108,168, 98,155, 41,165,136,139,139, 67, + 73, 73, 9, 66, 67, 67,113,232,208,161,204, 87,205, 85, 89,121, 67,126,158, 51,162,141, 69, 97,154, 80,123,251, 60,148, 26, 86, +227,109,138,169,242, 27,216, 65,200,144,179,132,225,153,245,233,228,139, 25,227, 6, 98,221,207,127, 26,180, 14,157,250,109, 60, +122,242,131, 34,141,110,190, 41,230,234, 5,147, 21, 1,192,215,195,195, 67,108, 48, 24,186,244,239,223,255,100,159, 62,125, 16, + 22, 22,134,243,231,207, 55,210,233,116,169, 0,160, 80, 40,150, 0,112,100, 24,102,117,114,114,242,179, 42,246, 17, 35, 20, 10, +247,158, 63,127,190,169, 66,161,192,249,243,231,161, 82,169, 48,105,210, 36,237,212,169, 83,133,163, 71,143, 38,249,249,249, 21, +145,171,208,208,208,236,170,204, 21, 0, 20, 36, 63, 58,101,237,214,180,125,151,206,237, 6, 54,106,212,208,226, 89, 97, 65,134, + 84, 42, 49,187,116,249,170,240,230,141,155,155, 10,146,163,111, 85, 94,159, 23, 76,174, 79, 14, 14, 14, 14, 14,206, 96, 85,139, + 49,231,175,109,158,209, 80,247,117,154,219,205, 61,243,208,204,204, 12, 91,182,108,129, 84, 42,173,181,113, 42, 57,117, 4, 73, +147,135, 87, 68,174,202, 35, 89,232, 53,250,181, 12, 22,203,178,161, 0, 94,114,121, 50,199,198,195,246,126,212,189,131,175,167, + 11,163,223,191, 1,201, 37, 6,245,162,199, 58,245,163, 66,250,110, 84, 37,131,167, 43,208,107, 33,145,149, 70,174, 42, 51, 87, +114, 39,239,247,119, 12,235, 18,212,162,113, 3,198,176,111, 45, 82, 74,244, 69,243,162,117,186,103,197,244,112, 21,166,114, 81, +143, 30, 61, 22,217,218,218, 74, 54,110,220,104,233,238,238, 14,131,193,160,125,213, 92,201, 28, 27, 15,219, 55,186, 87, 7,111, + 39,107, 70,127,240,123, 36,169,140, 37, 27,158,233,119,252,104,130,185,178,179,148,159,249,113,249,100, 51,169, 88, 0,181, 90, +141,149,155, 15,226,236,245, 7,253, 50, 35,143,156, 1,112,166,174,251, 91,167,211,125, 18, 28, 28,188,110,246,236,217, 48, 24, + 12,248,240,195, 15, 17, 31, 31,127,246,233,211,167, 27, 92, 93, 93, 63,159, 60,121,178,194,222,222, 30, 19, 39, 78, 20, 2, 24, + 93,133,204,170,221,187,119,247,107,209,162, 5, 46, 95,190,140,188,188, 60, 56, 59, 59, 99,234,212,169,162, 21, 43, 86,236, 40, + 40, 40, 24,178,124,249,114, 73, 92, 92, 92,181,145,171, 23,201,163,249, 75,127, 90, 55,241,243,214,109, 59, 48, 79,159,198, 24, + 18, 91,119,102, 46,156, 63,121, 37,215, 65,188,227,165,250, 28,211,187,214,245,201,193,193,193,193,193, 25,172, 26,163, 67,198, +194,191, 14,118,103,141, 38, 7, 50, 76, 54, 78, 70, 19, 53, 89,141,186, 38,195, 84, 43,131, 85, 54, 6,235, 52,165,244, 37,131, +101,229,212,184,243,130,185,211,215,119,124,191, 23,147, 62,174, 29,242,138, 52,154, 57, 81, 6, 54,185,164, 6,115, 5,128, 49, +234, 46, 11, 44, 44,174, 8, 95,153, 45, 8, 0,102,142, 13, 91,207,251,236,211,205, 93,135,245, 39,153,147, 58, 34, 55, 79,165, +249,252,161,129,164,168,232,144, 40, 74, 47, 85,166,119,225,194,133,173, 0,182, 6, 5, 5,165,203,100, 50, 20, 21, 21,253,165, + 94,203,203,219,225,253, 94, 76,250, 39,109,144, 83,172,211,204,121,104,128, 82,197,238,173,201, 92,217, 91,153,159,249,113,217, +100,169, 50, 57, 30, 66,161, 16,114,185, 28,231,174, 69, 34,243,193, 31,103, 94,231,128,115,117,117, 93, 60,109,218,180, 69,163, + 71,143, 70,110,110, 46,206,157, 59,135,174, 93,187,226,135, 31,126,112,191,120,241,226,186,246,237,219,131,199,227,225,220,185, +115,208,235,245, 79,170,216,159, 3,199,143, 31,255,249,251,239,191,143, 91,183,110, 33, 53, 53,245,165,200, 85, 94, 94,222,135, +155, 55,111,126,255,249,243,231, 53, 70,174, 94,196, 5,104,237,217,160,165,240,139,133,223, 65, 83,146,193,207, 76,185,113,249, +194, 57, 26,230,158,147, 35, 5,144, 95,215,250,228,224,224,224,224,224, 12, 86, 37,238,197, 8,190,179, 31, 12,169, 17,255,121, +233,149,217,132, 66,169, 28,172,177,102,227, 50,218,159,232,199, 52, 0,127,109,111, 6, 66,185,173,174,221,220, 51, 15,171,250, +172, 92, 46, 55,181,139,208, 40,236,243, 62,175, 65,207,247,240,172,185, 19,168, 94, 87, 17,201,194,252,249, 47,153, 44,161, 80, + 8,173, 86, 11, 84,210,237,247, 10, 55, 9, 33,241, 0,194, 40,165, 52,192,219,235, 27,137, 76, 54, 38,208,175,129,221,140,201, +159, 8,158,103,104,112,177,227, 23,121, 7, 87,205,149, 39, 81,249,148, 4,154,119,189, 6, 67,121,185,207,213, 71,127,137, 92, +249,123,123,125, 41,145, 74,198,181,109,230,237, 52,111,230,100,193,243,116, 13,185,216,122, 78,193,161,213,115,164,113, 48,255, + 60,137,230, 94, 50, 97,251, 23,245,233,211,103, 17,165,148,178, 44,187, 16, 0, 94, 44,239,204,169,227, 4,207,210,212,184,208, +241,203,220, 67,171,230,154, 39,161,250,242,218,251, 13,236,224,104,109,113,230,199,229, 83,164,169, 41, 9, 16,139,197, 48, 55, + 55, 71, 82,122, 62, 4,124,158,234,117, 14, 54, 15, 15, 15,113,155, 54,109,230,142, 26, 53, 10,209,209,209,152, 55,111, 94,170, + 82,169, 60,124,244,232,209, 73, 51,103,206,228,119,238,220, 25, 25, 25, 25,216,178,101,139,254,214,173, 91,203,211,210,210,214, + 84,122,208,242,249,159,124,243,205, 55, 84,169, 84,146,184,184, 56, 56, 59, 59,227,211, 79, 63, 21, 45, 95,190,188, 98,204, 85, +109, 34, 87,229, 36, 39, 39, 95,110,212,160, 30,222, 61,181, 30, 6,189,230,114, 94,118,226,149, 71,207,114, 47,219,136, 68,179, + 58, 6,248,213,169, 62, 57, 56, 56, 56, 56, 56,131,245, 23,244,148,201,223,189,114,162,229,187, 35, 38,193,204,227, 29,104, 30, + 30, 0, 91,152, 6,182,176,212,192,136,100, 22, 48,183,115, 67, 81,137, 26,215, 30, 60,131,158, 50,249,213,234, 25,193, 95,250, +195,127,102, 11, 90, 89, 89, 33, 63, 63,255,165,200,139, 84, 42,133, 66,161, 64, 65, 65, 1, 14, 30, 60, 8, 90, 67,100,136, 82, +250,205,168, 81,163,190,154, 60,121, 50,211, 96,216, 88, 20,221,184,250,106, 52, 10,102,102,102,144, 72, 36, 72, 78, 78,198,227, +199,143, 89, 74,233, 55, 53, 68,188,110, 26, 12,134,251,123,247,238, 77,110,228,229,218, 43,168, 85,235,105,243,191,152,103, 30, +117,245, 44, 22, 46,223,196, 54, 12,236,153,191,114,207, 31,133,249,242,122,221, 74,148,143,238,213, 84,201,132,144,191, 38, 17, +245,172,215,181,157,127,203,217, 11, 23,126,105,241,240,234, 57,124,181,250, 71,218,168, 69,112,254,234, 67, 71, 11,178,164, 30, + 61, 84,233,255, 25,243, 83, 29, 33, 33, 33, 91, 1,108, 45,127,254,106,121,231, 45,217,192,122,183,234,149,187,114,207,161,226, + 2,243,122,193,213,149,215,193,119, 80,123, 55,103,155, 51,223, 47,157, 40, 77, 75, 73,132, 88, 44,134, 92, 46, 71, 98,106, 30, + 22,173,223, 95,172, 99,217, 94,175,121,188,137,101, 50,153, 88,167,211,225,183,223,126, 67, 74, 74, 74,187,212,212,212, 68, 39, + 39,167, 31, 39, 78,156,184,177, 73,147, 38, 62,143, 31, 63,126, 82, 84, 84, 52, 37, 45, 45,237, 81, 85, 34, 86, 86, 86,237,236, +237,237, 73, 88, 88, 24, 38, 78,156,168,253,244,211, 79,133,163, 70,141, 34,185,185,185,117,138, 92,189, 16, 93,235, 60,160,111, +123,116,232, 62,233,178, 86,157,119,229,249,163, 29,151, 25,122, 93, 18,208,210,175, 78,245,201,193,193,193,193,193, 25,172, 74, +201,228,171, 28,126,220,121,104,205,222, 3,135,199,141, 31, 51, 92, 18, 20, 60, 18,194,172, 72, 24,148,225,112,241,237, 8,202, + 55,195,173, 59,119, 17, 17,155,164, 46,209,241,182, 23, 8, 85,179, 95, 49, 22,193,213,229,202,200,207,207,135,135,135, 7,246, + 76,106,220, 84, 83,144, 33,172, 7,128, 73,177,212, 93,140,233,243,240,202,149, 43, 69, 0,182, 55,106,212,232, 64,117,154,119, +239,222,253,186,101,203,150, 71,191,248,226,139, 21,141, 26, 53,234, 53,126,201, 15, 16,206, 24, 5, 85, 84, 4,164, 65, 67, 96, + 99, 99,131,236,236,108,220,186,117, 11,133,133,133,167, 41,165, 95,220,187,119, 47,178, 58, 77, 74,233, 13, 63, 63,191,228,122, +245,234, 89, 57,200,205,126,153,244,241, 40,243,132,136, 27, 72,143,185,143,235,215, 98,114,119, 31, 58,154, 82,144,159,249,113, +117,141,235,139,154, 12,195,188,100,174,188,189,237,228, 50,177,245,206, 41,227,199, 90, 36, 70,222, 66, 70,204, 61, 92,189,254, + 36,119,207,222, 35,153,217,217,233, 99,170, 50, 87, 53,213,103,101,229,189,113,245,113,238,222, 3, 71,146, 11,139,115, 63,169, +172,188, 47,106,202,101,130,217, 71,127, 91, 42, 85, 38, 39, 84,152,171,132,212, 92,124,181,126,111,177, 74,171,239,149, 25,113, +196,164, 72, 77,117,229,100, 89, 22, 6,131, 1,148, 82,136, 68,162, 2, 0, 40, 51, 83,221, 76,213,204,202,202, 10,137,143,143, + 31, 32,151,203, 43, 34, 87,249,249,249, 67, 86,174, 92, 89,171,200,213,171,229, 76, 78, 78,190,220,192,211,117, 85,234,208, 33, + 26,103,103,251,203,199, 78,221,142,116,144,155, 61,170,107,125,190, 41, 56, 77, 78,147,211,228, 52,255, 13,154,255, 42,131, 21, + 21, 69,117, 0,166,251,250, 90,124,189,250,199, 93, 91,118,238, 57, 56,112,252,136, 65,124,255, 22,221, 16, 23,122, 4, 87,110, + 92, 52,228,170,233,145, 66, 1,111, 82,212,211,130,220,154,126, 76,192,131, 97,248,240,225,124, 0, 16,241, 97, 88,219,175, 95, + 72,211,166, 77, 59,182,213,103, 8, 23,109, 44,141,108,125, 61,109,184, 48,228, 86,200, 1,177, 88,188, 53, 46, 46,174,192,148, +141, 40, 51, 76,189, 91,181,106,245,206,231,159,127,190,170, 79,125,215,214, 3,219,119,129, 64, 32,192,173, 91,183,144,157,157, +125,139, 97,152,185,119,239,222,189, 98,138, 94,100,100,100, 86,211,134, 30,211,109,204,132,179,167, 12, 31,104,159, 25, 27,133, +228,232,187, 0, 0,141, 70,165, 79,141,185,220,162, 54,149, 92,190,112,179,175,175,175,208,168, 41, 26, 45,225, 91, 44,156,244, +225, 0,135,236,231,143,144,244,176, 52,221,147, 70, 93,162, 75,138,185,232, 83,151,157,232,225,225, 33,150, 9, 48,161,210,242, +106,213,250,180, 39,209, 45, 77,209, 41,209,104,151,127,189,110,103,143,165,179,199,136, 45, 44, 44, 16,254,224, 41, 22,174,221, + 83, 43,115, 85, 19,148, 82,232,245,250, 90,205,252,172,132,185, 45, 90,180,104,188,108,217,178, 70,101, 99,185, 94, 43,114,245, + 34,177,113,201,243,130,130,130,124,159, 62, 14,239, 98, 99, 38,220,245, 58,245,201,193,193,193,193,193, 25, 44, 84,111,180, 10, +114, 1,124,224,239,106,225,181,108,211,174,237,102,124,182,163,202,192, 92, 83,105,152,113,119,147, 11,158,153,250, 99,191,221, +165,130, 87, 95,243,245,245,149, 61,229,163,168,252,249,211, 28, 64,169, 84,174,174,203,198,220,190,125,251, 10,128, 54,254,254, +254, 3, 79, 18, 50, 31,120, 6, 74,233,242,187,119,239, 30,169,141,142, 57, 31, 15, 58,250,122,185,116,242,111, 42,225, 25, 85, + 72,142,142, 69, 78,177, 26,231, 30, 38,228, 49,148,249,181,174,149,205,232, 74,238,119,242,109, 80,239,157,128,166, 82, 1,209, + 34, 57, 42, 28,249, 42, 45,206, 62, 76,200, 7, 33,117, 30, 40,253,166,202,155, 22,241,199,109,123,191,129,193,132,144,243,243, +167, 14, 19, 47, 90,187,247,141,154, 43, 27, 27,155,146,180,180,180,108,181, 90,109,155,158,158,174,181,177,177, 41,169,163, 73, +123, 74, 8,105, 62, 99,198,140, 37,159,127,254,249,236, 85,171, 86, 9,235, 50,230,170, 42,114, 83, 18,142,188,211,244,205,239, +127, 14, 14, 14, 14, 14,206, 96, 85, 74,153,153, 10, 10,242,181,151, 93,123,156, 89,252, 38, 10, 16, 21, 21, 85, 60,218,159, 84, + 68,182, 4, 60, 24, 94, 87,179,204, 80, 29,169,179, 0, 67, 10,111, 60, 73, 40,186,249, 36,161, 8, 44,165, 44,165, 26,134, 65, + 82,177, 78,183, 60,230, 89,114,221,103,209, 17, 98,188,253, 52, 81,117, 39, 54, 73, 77, 89,150,178,148,106, 9, 65,154, 94,207, + 46,127,240, 44,254,232, 63,161,188,153, 17, 71,174, 59,249, 14,234,116,253,230,131,153,197,197,186, 77,153, 81, 71, 66,223,212, +193, 22, 30, 30,174,119,118,118, 30,209,191,127,255,177, 44,203,254,152,146,146,162,175,171, 22,165, 84, 11, 96, 46, 33,228,112, +100,100,228,254,208,208,208,212, 55, 97,174,254,214,253,207,193,193,193,193,193, 25,172,234, 8,137,122, 51,230,170,156,202, 34, + 91,255, 77, 34,159, 60, 15,248, 59,116, 31, 60,121,222,236,127,161,188,105, 81,135,239, 0,248,240,239, 40,107,106,106,234, 89, + 0,103,223,148, 30,165,244, 54, 33,164, 62, 0,222, 27, 49, 87,127,227,254,231,224,224,224,224,224, 12, 22, 7,199,255, 12,180, +116, 64,151,129,171, 9, 14, 14, 14, 14,142,127, 10, 4, 64,112, 21,141,150,201,179, 3, 8, 33,193,117,104, 20,207,115,154,156, + 38,167,201,105,190, 37,154, 25,213,104, 62,168, 65,179,170,200,182,195,255, 80,125,182,172, 66,115, 85, 13,154,115,171,121,251, + 30,119,124,190,157,154,255,166,187,255,191,237, 1, 32,152,211,228, 52, 57, 77, 78,243, 95,160,217,140,171,207, 55,170, 57,151, +171,207,127,159,230,219,246, 96, 56,139,201,193,193,193,193,241,183,117,147, 16, 34, 38,132,136,235,250, 62, 7,199,255, 42,181, + 30,131,213,186,117,235,134, 0,112,235,214,173,167,127,227, 9, 57,213,217,217,121,188,159,159, 95, 19,161, 80,200, 20, 22, 22, +126,125,241,226,197,197,175,126,238,157,166,130, 59, 60, 6,174, 47,124, 19, 32, 60,128, 97, 96,164, 72,190,114,191, 36,144,219, +197,255, 93,156,157,157,207, 72, 36, 18,119,150,101, 97, 96, 41,140, 6, 99,233, 95, 35, 11,189,145, 66,167, 85, 39,104,138,243, +123,214, 73,187,229,160,122, 6, 35, 93, 9,176,155, 9,152, 73, 20,236, 22, 66,153, 73,148,193,102,194, 98, 34,248,250, 53, 48, + 8, 62,231, 11,249, 95, 42,195, 15, 36,189, 13,245,121,240,224, 65,222,235,124,127,240,224,193,149, 46, 19,229,239,239,127, 92, + 34,145, 52,168,234,123, 37, 37, 37,169,247,239,223,239,242, 54, 31,171, 78, 78, 78,239, 48, 12,243, 61,128,166,175,188,245, 8, +192,116,165, 82,121,225,117,127,163,181, 84,202,183,227,241, 38, 8, 8,153, 3, 0,122, 74, 87,103, 25,141, 91,111,149,148,252, + 99,198, 16, 58, 56, 56, 92,225,241,248,141,138, 75,138,139, 11, 11, 10,188,204,205, 45,158,153, 73,165, 50,163,193,248, 36, 43, + 43,227,157, 90, 94,203, 39, 3, 88, 83,246,255,108, 74,233,230,218,188,207,193,241, 86, 27,172,128,128, 0,111, 0,157, 9, 33, +157, 41,165,239,248,248,248, 56,150,148,148, 32, 32, 32, 32,157, 16,114,133, 82,122, 25,192,229,240,240,240,152, 55, 81, 32, 30, +143,247,237,134, 13, 27,102,125,250,233,167, 21,139, 52, 71, 68, 68, 84,254, 89, 6,174,151,142,157,119,184, 29, 25,131, 86,193, +131,203, 12, 22, 3, 20,167,162, 75,247,214,117,250,125, 27, 27, 27,115, 7, 7,135,175, 9, 33, 67, 24,134,169,177, 49, 99, 89, +214, 72, 41, 61,144,145,145,177, 40, 39, 39,167,176, 54,191,213, 42,208, 79, 95,234, 8, 43,131, 26,111,223,137,168,118,118,165, +143,143,207, 29, 30,143,231, 90,118,113,122,245,194, 86,233,255, 70,163, 49,249,225,195,135,129,166,214,133, 68, 42,157, 77, 24, +126, 48, 40, 91,154, 4,149, 48,143, 40,107, 56,175, 46, 41, 89, 99,202,246,138,197, 98,247,240,187,247, 26, 69,197, 60,131, 87, +253,122,208,234, 12,208,234, 12, 56,122,254, 22, 90,248,212, 71,255, 62,221,235,124,172, 24, 41,249,122,225,244, 17, 93,150,109, +216,221,234,203,233,195,101,203, 54,236,110,245,229,140,225,242,101, 27,119, 7,126, 57, 99,132,124,233,198, 93,129, 11,102,140, +176, 88,182,113,183, 14,192,199,117,249,141,143,155,187, 23, 51, 70, 67,165,119,215, 44,143,175,249, 57, 50, 65,246,223, 56,113, +199,142, 29,235, 93, 92, 92, 28, 53,182, 95,235,111,154,120, 56, 86, 58,254, 39, 47, 59,221,225,201,131, 91, 11,249, 18,153,239, +123,179,127,169,246,252, 20, 10,133,158, 87,174, 92,105,196,178, 44,140, 70, 35, 12, 6, 67,197, 95,173, 86,139,247,223,127,255, +141, 76,136, 9, 12, 12, 28, 75, 41, 93, 86,122, 88,146,165,119,238,220,217,244, 26, 55, 98,114, 62,159,255,153, 72, 36,234,108, + 48, 24,154, 0,128, 64, 32,136,214,104, 52,151, 13, 6,195, 58, 74,105, 81,109,244, 24,134, 89,127,251,246,109, 95,185, 92, 14, +157, 78, 87,177, 48, 60,143,199,243,105,211,166,205, 15, 0, 26,189,238,246,219,241,120, 19,218,119,236,184, 97,236,140, 25,188, +220,219,183,241,253,246,237,235,145,155, 11, 0, 63,212,244, 93, 87, 87,215, 59,132, 16,215,218,252, 30,165, 52, 57, 57, 57, 57, +176,118,215, 96,126,163,132, 36,165,131,187,155, 2, 0, 32,149, 74,101,183, 31, 60,119, 8,104, 90,191,214,145, 43, 0,107, 40, +165,102,101,245,187,161,125,251,246,237, 8, 33, 6, 0,148,101, 89,134, 16, 50,140,101, 89,126,217,231,215, 16, 66,126,161,148, +106,184,166,153,227,173, 54, 88, 1, 1, 1, 39, 1,116,246,241,241, 49,235,222,189, 59,252,253,253,225,238,238, 14,137, 68, 2, + 0,200,201,201,113,140,138,138,250,224,222,189,123, 31,132,133,133, 33, 32, 32, 64, 5,224, 90,120,120,120,165,209,136,224,254, +157, 62,149,200,197, 27, 1, 32, 51, 57, 59, 53, 57, 46, 99, 99,106,106,234, 26, 74, 41,251,194, 9,233, 53,106,212,168,153,211, +166, 77,195,241,227,199,177,103,207, 30,104, 52, 26, 20, 22, 22,226,226,197,139, 85,220, 90,103, 32,247,226, 74, 64,246, 28, 72, +188, 12, 72, 29, 0,153,227,235,220,189,125, 61,116,232,208, 25,255,199,222,117,135, 69,113,181,223,115,103,182, 23,122, 95, 80, + 81, 16, 21, 84,164, 40,246, 30,187, 81, 99,139,189,151, 88,163,137, 49,198,196,154,216, 75,140, 93, 99,141,189,247, 22,123, 23, +176, 34,130,130, 74, 89,122,103,217, 58, 59,243,251,131, 18, 36,148,133,248,125,201,247,203,158,231,153,103,119,103,102,207,220, +185,115,231,222,115,223,251,222,247,250,248,248, 20, 69, 29, 55, 24, 12, 96, 24, 6, 6,131, 1, 25, 25, 25,152, 49, 99, 70, 97, +229, 5,150,101,113,245,234,213, 41,179,102,205, 2,128, 47, 75,227,252,164,141,103, 48,143, 16, 55,246, 15, 81, 22,119,249,102, + 84, 32, 64,232, 71,193, 79, 72,233,226,171, 17, 93,113, 69, 72,187,133,134,134, 58, 10, 4, 2,147,238,141,101, 89,248,251,251, +155,116,174,171,171,107, 59,153,220,114,255,103,131,198,216,248,249,251,241, 93, 93, 92, 96, 96, 24, 68,191,141,105,242,228,113, +136,223,165,211, 7,199,186,186,186, 14,138,143,143, 47,119, 65,106,163,145,197,147,176, 72, 92,185,253, 24, 61,249, 98,168, 52, + 58,168,212, 58,236, 57,117, 23,113,201, 89, 85,126, 78, 65, 65, 65,174, 82,218,161,201,148, 81,189,101,203,127,217, 45,155, 50, +170, 55, 86,172,223, 83,240,185, 91, 54,101, 84, 47,172, 88,191, 75, 62,101, 84, 47,252,188,113, 71,211,160,160, 32,215, 7, 15, + 30,196,151,197, 87,214, 51,162,140,140,104, 91, 88, 60, 13, 0, 41,155, 55,195,144,156, 12,197,188,121, 0,128,177, 62,174, 38, + 15,107, 52,104,208, 32,152,199,227, 85,216, 56, 50, 12, 19,247,252,249,243, 64, 83,196, 21,195, 48, 28,143,199,251,254,246,111, +139,142,180,240,171,243, 65,102, 70, 68, 68, 88,253,240,195,247,253, 14,133,228,112, 3, 2, 44,194, 78,172, 24, 85,174,200, 98, + 89,150,210,106,181,136,140,140, 44, 53,202, 62, 69, 81,198,170, 60,167,182,109,219,138, 84, 42,213, 62,185, 92,238,171, 82,169, + 70,113, 28,247,195,245,235,215,157, 40,138, 66,199,142, 29,127, 8, 12, 12,124, 43, 22,139, 55,170,213,234,199,114,185,124,208, +245,235,215, 77,106, 92, 9, 33,173, 45, 45, 45,247, 28, 63,126,220,198,223,223,159, 74, 77, 77, 69,205,154, 53,145,158,158,222, +228,230,205,155, 1,163, 71,143, 30, 77, 8, 25,198,113,220,205, 74, 36,183,174, 84, 42,229,134, 15, 31, 78,140,198, 63,110,247, +215, 95,127, 69,128, 75,146,231,132, 46,178, 60,141,142,203,250, 61,210,106,130, 64, 32,184,253,238,221,187, 74, 23, 96, 62, 33, +179, 70, 77,159, 78, 11, 18, 18, 32,139,136, 64, 15, 66,120, 91,243,173, 89, 27, 76,184,103,183,213,235, 86, 56, 10,133, 66, 48, + 12, 83, 36, 2, 11,235, 40,131,193, 0,189, 94, 15,131,193, 0,163,209, 8,131,222,128,109,155,119, 84,249, 29,147,202,164, 82, +103, 23,151, 36,137, 84, 38,253, 24,141,141, 72, 36,226,237,222,189,123,144, 80, 40, 4, 0,232,116, 58, 52,104,208,128,152,155, + 97, 51,254,141, 22,172,174,215,175, 95, 7,195, 48,176,176,176, 0, 77,211, 37,173, 27,104,221,186, 53,130,130,130,208,177, 99, + 71,188,122,245, 74,178,108,217,178, 50,205, 17,131,103,246, 64, 53,175,124,225, 99, 48,176, 46,119,206, 62, 94,250,235,162, 35, + 14, 0,102, 22, 55, 24,140, 31, 63,158,164,165,165,161,127,255,254, 55,181, 90,237,167, 28,199,149,185, 92,142,145, 69, 92,187, +207,135,128,229,136,100,205,131,109, 68,167, 81,115, 20, 69,169, 11,135, 8,171,216, 43,238,175, 80, 40,112,224,192, 1,232,116, +186, 63, 29,183,180,180,196,139, 23, 47,138,139, 28,248,249,249,209,132,144,254,101, 9, 44,138, 16,183,243,215, 95, 23,205, 8, + 26,248,169,159,160, 83, 27,207, 36, 30, 37,228, 0,144,239,190,251,174, 72,176, 1,192,130, 5, 11, 76, 78,175, 64, 32,192,171, + 87,175, 64,211, 52,222,180,200,239, 96, 55, 8,141, 5, 77,211,120,226,155,223, 3,109,254, 58, 19, 52, 77, 67, 46,151,155, 42, +174,218, 58,185,184,157,248,118,222, 18, 11,141,129,195,217,171, 15, 17,163,188, 12,142,227,224,226,104,139,230, 1,254,252,250, + 13, 27, 57,254,186, 97,249, 9, 87, 87,215, 94,241,241,241,215,203,226, 50, 48, 70,120,123,213,194,238,227, 55,177,120,227, 81, +164,101,171,145,147,151,159,175, 29,154,250, 96,123,213, 45,157, 43,234,186,187, 87,219,121,232, 2,154, 53,109,140, 93,135, 46, +162, 89, 80, 99,228,255, 14,194,174, 67, 23,208,188, 89,254,103,125,111,207,234,233,239,178, 86,160,156,216, 94,127,122, 70,189, +242,159, 81, 77, 90, 80,212, 0,188,155, 56, 17, 0,138, 4, 86,165, 94, 52, 30,207,237,241,227,199,142, 21,157,231,231,231,103, +146,229,138, 97, 24, 36, 39, 39,147,204,204, 76,206,218,218,186, 95,113,145, 85, 40,174, 14, 6,103, 67,125,127, 61,249,237,212, + 13,118,200,167,109,194, 78,172, 24,229,211,175, 95,191,151,165,241,234,245,250,183,157, 58,117,226, 10, 26, 62, 87,161, 80, 40, + 40, 33,192, 20, 45, 90,180,248,147, 64,171,104,232, 80,165, 82,237,219,186,117,107, 31, 79, 79, 79,124,246,217,103,151,124,124, +124,132, 82,169, 20, 23, 46, 92, 64,181,106,213,236, 45, 44, 44,206, 45, 89,178, 4,171, 87,175,174,126,233,210,165,253, 0,250, +152,240,142,118,108,215,174,221,129, 51,103,206,136, 5, 2, 1,212,106, 53, 94,188,120, 1, 43, 43, 43, 8,133, 66,244,234,213, +139,110,209,162,133, 93,219,182,109,143, 18, 66, 6, 85,102, 70,147, 70,163,225,230,204,153, 3,169, 84, 10,169, 84, 10,153, 76, + 6,153, 76, 6,137,128, 37,155,167,213,148, 76,221,154, 41,249,114,222,230,165,123, 54,206,191, 86,189,122,245, 31, 98, 98, 98, + 50, 43, 91, 22, 50, 30, 61,130, 44, 34, 2,154,224,224, 74,151, 35, 43,153, 45,102,207,158, 93, 81, 89,131, 64, 32, 64,243,230, +205, 43,228,243,246,246,222, 76,211,180,195,135, 98,154,208,223,127,247, 45,243,252, 69,132, 76,111,228,100, 26, 45,131,197, 11, +191,103,104,138,162, 27, 52,104,112,156,227,184,148, 23, 47, 94, 76, 48,193,122,166, 37,132,124, 77, 81,212,207, 34,145,136,231, +238,238,254,254,251,239,191,191,151, 63,212, 0,112, 28, 71,185,187,187, 55,145, 72, 36, 53,180, 90, 45, 3,224,107,179,245,202, +140,127,139,192,130, 92, 46,199,163, 71,143, 64, 8,129,133,133, 5, 44, 45, 45, 97,101,101,133,236,236,108,132,133,133, 33, 60, + 60, 28,239,222,189, 3, 33, 4, 30, 30, 30, 40,124,113,138,189, 96, 69, 21,219,190, 85,103, 32,150,139, 64, 8,224,223,222, 23, +190,173, 27,160,241,195,168,105, 10,133, 98,171, 82,169,140, 36,132,240, 26, 52,104, 48,186,105,211,166, 88,189,122, 53,180, 90, +237,234,210,196, 85,113,206,155, 47, 12,129, 0,160, 80, 40,190,218,123,225,141,116,104, 23,207, 60,165, 82,185,178,178,153, 80, +178, 2, 78, 77, 77, 5,203,178, 38, 91,133, 50, 51, 51,203,229, 44,105, 17, 88,188,116,141,117, 78, 86, 18, 22, 45,219, 11,131, +193,128,153, 51,103,130,101,217,162,173, 52,190,210,210, 89, 56,244, 71,211,244, 7, 2,184,162,223,229,113, 58, 56, 56,200, 68, + 98,233,254,175,190, 91,100,241, 52, 34, 14,103,174, 62, 4,199,113, 56,185,245, 7, 0, 64,175,113, 11, 17,159,152,138, 22, 1, +245, 48, 98,194, 12,139, 53, 63,205,217,239,224,224,224,153,146,242, 71,240,217,226,156, 6,134,197,209, 11,247,160, 76,203,197, +240,207, 58, 64,163,213, 35, 37, 57, 17, 59, 54, 44,199, 23, 35,142,194, 70, 46,113,246,240,240,136, 40,158, 71, 28,199, 17,129, + 64,112, 59, 34, 34, 98, 76, 89,233, 52, 24, 12, 93,191,157, 49, 22, 63,111, 59,138, 6,181,157,113,250,242, 93, 4,214,175,129, +243, 87, 31,162,105,195,154,184,120, 35, 4, 77,125,107,225,198,253, 23,152, 62, 97, 24,190,158,118,187,107,101,158,209,143, 75, +214, 88,231,100, 39,225,204,143,187,145,188, 97, 3,222, 79,158,140, 38, 5,231, 60, 36, 4, 2, 55, 55,192,162,226,252, 44,137, +151, 47, 95, 66,171,213,150,214,187,135,183,183,119,133,207,168,208,114,149,148,148, 68,146,146,146, 32,147,201,200,203, 23,207, +141,222,245, 27,244,227,194,143,108, 3,128,124,203, 85, 54,242,238,174,131,250,222, 47, 16,212,124, 74,109, 91, 56, 65, 55,246, +135,205, 97,197, 26,183, 15,210,249,228,201,147,162,252,105,218,180,105,248,237,219,183,235, 22,150,175,130,161, 66, 1,195, 48, + 94,133,195,134, 12,195, 64,171,213, 98,208,160, 65,116,121,247, 46,145, 72,124, 61, 60, 60, 16, 18, 18,130, 9, 19, 38, 8,219, +181,107,135,215,175, 95,131, 16,130,145, 35, 71,194,199,199, 7, 41, 41, 41,104,220,184, 49,110,221,186,229,103, 66,153,183,144, +201,100, 59, 78,159, 62, 45,166, 40, 10, 57, 57, 57, 96, 89, 22, 45, 90,180, 0, 69, 81,120,254,252, 57,190,251,238, 59, 28, 59, +118, 12, 39, 78,156,144, 4, 4, 4,236, 32,132,120,115, 28,151, 99,194, 51,226, 52, 26, 13, 39, 18,137, 32, 18,137, 32, 22,139, + 33, 22,139, 33, 20, 10,161,214, 83, 24,183,230,189,150, 22,219,179,245,253, 90,122,142,156,250, 19,181,242,251, 81, 87, 1,156, + 44,224,124,110, 74,125, 97,224,184,229,235,183,111, 95,215, 29,249, 19,140, 14,231,228,176, 6,142, 91,110,202,187, 9, 0,185, +154, 44,212,240,112,195,209,131, 39,208,119, 96,239, 82,197, 21,159, 47,128,128,207,135,165,173,172, 66, 78, 62,159,111, 31, 26, + 26,106, 93,188,126, 96, 24,230,229,148, 41, 83, 60,122,247,234,238,116,232,216, 25,122,232,192, 94, 70,103, 39,135,212,216,216, +247,175, 1, 88, 7, 4, 4,112,166,150,121,142,227, 54,250,249,249,249, 31, 63,126,124,212,236,217,179,131,191,250,234,171, 69, +197,143,175, 88,177, 98,225,185,115,231,106,244,233,211,103,207,227,199,143, 55, 22,251,223,178,143,221,216,253, 39, 66, 7,152, + 57,205,168,178,192, 42,222,248,100,103,103, 35, 59, 59, 27,177,177,177,216,188,121,115,193,139,204, 7,143,199, 3,143,199, 43, +242, 87, 40, 11, 87, 78,223,250, 5,192, 47, 1, 1, 1,252,103,247, 14,159,159,181,117,106,135,192,142,254,116,200,239,207,250, + 1, 88, 12,160,235,240,225,195,237, 1, 96,247,238,221,169, 0,206,255, 29, 25,194,113,220,225,200,200,200,233, 46, 46, 46, 69, + 62, 40,197,135, 9, 25,134,129, 88, 44, 70,161,175,138, 86,171,197,190,125,251, 24,142,227, 14,151,151,127, 17, 47,174, 34,242, +197,181,252,255,177, 44, 88, 99,254,255, 53, 26, 13,230,207,159, 95,124,234, 43, 38, 78,156, 8, 84, 98, 45,228,178, 44, 87,205, + 34, 51,192,227,241,112,171, 86,190, 18,232,150,194,253,201, 87,235, 79, 67, 24, 66,241,204,110,159, 13,177,101, 56,186, 72, 92, +229,223, 67,190,224, 20, 10,120,144,136, 4,136,136,138,129,187,107, 0, 58,116,235,109,115,229,204,209,153, 0, 74, 53,187,233, +141, 44,186,182, 13,192,134,131,215,145,157,171, 70, 86, 70, 58, 82, 98, 94,226,229,211, 71,224,241,120, 8, 14, 14,182,176,180, +180,178,168, 85,171, 38,140, 44,139, 59,247,130,193,129,224,244,169,227, 30, 53,106,214,194,251,183,209, 99,202, 16,182,188, 22, +129, 62,200, 77,139, 3, 77,211,104,238,231, 9,154,166,209, 42,176, 14,104,154, 70,203,198,117,193,227,241,208,182,169, 15,106, +215,174,141, 66, 63,143,242,159,209,239,136,124,113,189,152,216,229,192, 1,208, 39, 36,252,185,161, 76, 72, 0,103,225, 88,217, +178,133,111,190,249, 38, 51, 33, 33, 65, 95, 82,208, 41, 20, 10,193,177, 99,199,172, 43, 90, 4, 91, 38,147,249,240,120,188,176, +244,244,116, 86, 42,149, 82, 44,107,100,189,235, 55,160,111,255,182,232, 72,225, 57, 11, 23, 46, 58, 50, 32,192,178,223,222,195, +103, 56,129,123, 75, 66,248, 34,102,236, 15,155,133, 60,177,204,199,196, 78, 3,165,213,106,241,234,213,171, 10, 23,229,230, 56, +174,220, 2,165, 82,169, 70,244,237,219,247,210,196,137, 19,197,132, 16,220,186,117,171, 72,240,211, 52,141,168,168, 40, 80, 20, +133,173, 91,183, 66,171,213, 78, 52,193, 18, 56,253,232,209,163, 86, 66,161, 16, 57, 57, 57, 69,239, 13, 77,211, 8, 15, 15,199, +202,149, 43, 49,124,248,112,196,196,196, 64,161, 80, 96,230,204,153,242,165, 75,151, 78, 7,176,208,132, 91,127,170,211,233, 2, +165, 82, 41,196, 98, 49, 10,133, 22, 0,132, 36, 56, 61,143,142,142,110,104,111,111,239,236,112,227,204,169,230,237, 62,109,100, +231,224,210,172, 80, 96,153,138, 24,131, 97,171, 82,165,154,219,127,199, 14,199,155,167, 78,177,207, 79,157,138,227, 25,141, 91, + 76, 46, 67, 6, 10,239,163,226, 16, 16, 16,128,144,144, 16, 4, 4, 4,124, 96,205, 22, 10,133, 16, 8, 4, 16, 8, 4,176,183, + 49,201, 85,130,163,105, 26,137,137,137, 31,236, 27, 55,110,220,251, 33, 67,134, 56, 2, 64,130, 50,142,251,114,250,148,248,212, +212, 84,206,201,169,124,206, 70,141, 26,221,164, 40,202,189,132, 40,182, 25, 63,126, 60, 50, 51, 51,187, 77,156, 56,177,101,190, +149,140,138,223,176, 97,195, 80, 0, 16, 10,133, 85, 30,130, 54,195,140,255,121,129,101, 10, 42, 18, 88,133, 8, 9, 9, 49,184, +186,186,110,139,124,252,174,131,167,175, 7, 36, 50, 81, 39, 66,200, 47, 34,145,104,198,176, 97,195,112,255,254,125, 60,127,254, +252,215,191,186,236, 73,195,134, 13, 47,138, 68,162, 26,165, 29,211,106,181,239,159, 61,123, 86,170,175, 88,114,114,242,188,135, + 15, 31,162, 60, 39,247, 1, 3, 6, 20,111,140,138,156,220,203,172,193, 88, 14, 6,189, 1,170, 60,245, 31,141,119,129,192, 82, +169, 84, 24, 56,112,224, 7, 22,172,228,228,228, 42,221,115,101, 44, 87,101,129,162,233,206,190,141,252,249, 87,239, 62,253,160, +113,237, 61,126, 49, 68, 2, 30,164, 34, 1,196, 34, 62, 36, 34, 1, 98,227,147, 80,175, 94, 3,193,141,139,103, 58,151, 37,176, + 12, 12,139,229,191,158, 5, 0, 28, 62,125, 21,129, 53,165, 88, 48,247, 27,244,239,223, 31, 66,161, 24, 71,143, 30,198,202, 13, +187, 49,161, 70,254,163,106,210,216, 15, 43, 54, 29,192,162,133, 11,168,195,135, 14,183, 52,161,193, 5,143,199, 3, 77,211,127, +250, 44,252,110,138, 53,146, 99, 57,232, 75, 62, 35,150, 3, 56, 14,110, 63,254, 8,183, 31,127,196,195, 2,113,234,163, 82, 65, +173, 86, 3,109,125, 43, 37,174,116, 58, 29,148, 74,165,254,201,147, 39, 78,165, 52, 76, 73, 58,157,174, 66, 65,179, 99,199,142, +136, 81,163, 70,249,216,218,218,134, 61,125,242,196,224,219,168, 17,191,164, 15, 86,157, 58,117,178, 22, 46, 92,116,100,104,255, + 30,253, 54,127,251, 57, 51, 97,225, 30,158, 41,142,238, 69,162, 88,175,127,219,177, 99, 71,147, 36,190, 90,173, 78, 44,235, 88, + 96, 96,224, 40, 66,200,143,117,234,212, 17,181,107,215, 14, 55,111,222,196,143, 63,254,200, 50, 12,147, 10, 0,205,155, 55,119, + 88,180,104, 17, 9, 11, 11,131,181,181, 53,146,147,147,119, 5, 6, 6, 46, 42,207,241, 93, 40, 20,182,109,220,184, 49,165,213, +106,255, 36,174,150, 46, 93,138, 65,131, 6,161, 78,157, 58, 96, 89, 22,185,185,185,104,215,174, 29,127,221,186,117,109, 77, 17, + 88, 20, 69, 77,235,208,161,195, 74,228,207, 34, 44, 46, 28, 95, 2,248,186,192,186,157,216,163,239,240, 23,173, 58,126, 22,232, + 94,187,129, 75, 69,156, 78, 78, 78,223, 82, 20, 53, 0, 0, 13, 32,150,178,181,173,237,224,224,224,212,186, 71, 15,228, 18, 66, +111,185,112,129,240, 36, 18, 57, 0,147,134, 26, 53, 6, 21,106,120,228,187,242,245, 29,216, 27, 33, 33, 33,232,247,121, 31, 8, + 4, 2,240,120,124, 8,248,124,240, 5,249, 22, 44,107,123,203, 42,213, 35, 5,157, 71, 98,101,101, 5,112,128,165,149, 85,161, + 37,147, 0,224, 40,138,226,202, 41,231, 94,123, 39,143,115, 20, 88, 90,129,101, 12,168,254,105,191,162, 50, 29,185, 99,163, 4, + 44, 43,201,141,121,139,105,215, 30,242, 97,134, 25,102,129,101, 26,138, 59,133,150,134,246,237,219, 79,177,176,176, 88, 87, 80, +241, 34,246,126, 60, 98,239,199,195,187,110,253, 22,254,141, 2,179, 6, 13, 26, 4, 59, 59, 59,124,245,213, 87, 28,128, 95, 43, +123,253,168,136, 23,114, 0,156, 66,161,248,170,192, 34,208,232,225,195,135, 14,143, 30, 61, 66,227,198,141,139, 55, 30,104,217, +178,236,118,187, 96,102,220,151, 40,195,159,170,138, 86, 49,232,245,122,228,229,169,161,211,233,193, 24, 88, 48, 12,131,128,250, + 22,216,179,117,118,254, 62,166,208, 90,150,111, 37, 19, 9,180,104,211,180,154, 1,132, 82,223,184,247,190,220,154,178, 52,203, + 21, 77,211,184,237,145,255,183, 78, 9, 6,147,133, 22,199, 26,235, 58, 59, 57, 33,230,194, 3, 0,128, 92, 42,198,197,221,139, + 32,147,230, 79,110,232, 54,124, 14, 36, 34, 1, 36, 34, 62,244,122, 61,156, 28,107,130, 49, 26,234,150, 41,188, 13, 58, 93, 13, + 39, 43,184,116,107,138, 39,143,238,225,203, 41, 99, 49,106,212,104, 8,196, 22,184,113,227, 26, 98,148,201,120, 29,151,129, 41, +243, 54,194,192,176,208, 51, 70,232, 13, 70,172,221,117, 22,122, 35, 87, 97, 35, 47, 16, 8, 48,115,230, 76, 73, 89,199, 15, 28, + 56,160, 54,253, 25, 25,160, 82,169,161,213,106,161,215, 49,208, 27, 24, 24,107, 9,176,104,238, 96, 48,122, 6,121,159, 55,131, +222,192,128,157,222, 7,122,157, 1,177, 82, 30,213,178,177,194, 0, 80,234,219,143,226, 44, 43,226, 47, 20, 5,229, 9, 48, 83, + 80, 40,178,124, 27, 53, 10, 27,209,189,201,210, 59,247, 30,165,220,185,247,232, 79,231,121,212,111, 18, 61, 97,201,129,217,149, + 17, 87,192,135,195,133,127,177,220,255,112,253,250,117, 39,185, 92,142,136,136, 8,208, 52, 13, 66, 72, 90, 72, 72,136, 19, 0, +204,159, 63, 63,149,207,231,219,209, 52,141,233,211,167,131,199,227, 57,124,241,197, 23,223, 3, 88, 95, 78, 71,206,219,194,194, +226, 3,235,149, 64, 32,192,236,217,179, 49,116,232,208, 34,113, 37, 16, 8,176,107,215, 46, 4, 6, 6, 66,167,211,121,155,146, +222,184,184,184, 71, 0, 90,153, 32, 64, 72,129, 40,175,176,124, 82, 20, 53,226,201,196,137,181, 53, 15, 31,226, 11,150,245,169, + 91,183, 46, 52, 26, 77,209,113, 79, 79,207,234,113,113,113,137, 10,133,226, 55, 0, 27,149, 74,229,227,242,248, 12, 26, 22,239, +163,226, 10, 59,171,104,210,164, 73,145,197,170,184,245, 74, 32, 16, 64, 34,148, 87,250,153,177, 44,139,236,236,108,122,215,174, + 93,181,124,124,234, 19, 0,240,246,174, 79,206,158, 61, 87, 93, 46,151, 71,219,218,218,234, 43,124, 39, 45,173,112,101,244, 64, + 0, 64,255,246, 93, 10,173, 88, 8, 94, 52, 7, 60, 62, 31,141,102,204, 1,240,176,232,124,157, 78, 7,150,101,105,152, 97,134, + 89, 96,149,241,226, 27, 12,229, 30, 95,189,122, 53, 26, 54,108, 88,110, 3,180,110,221, 58,236,221,187,119, 53,199,113, 81,149, +189,126,143, 14,254,245,177,230,248, 11,143, 58,249,149,194,194,233, 61, 41,149, 74,133, 59,119,238,192,202,202, 10,175, 95,155, + 22,182,235, 63, 17,166,129,227, 0,189,129,129, 42, 79, 3,157, 78,135,233,179, 76,154,153, 78,244,186, 28, 94,247, 46,173,203, + 20, 15,133,195,125, 20, 69, 85,232,131, 85,209,208,224, 7, 22, 12,131, 1,133, 77, 71,110,158, 6,237, 7,127,139,135, 39,215, + 2, 64,190,184, 18,243, 33, 17, 10, 32, 17,242, 64, 17,128,160,108,110,131, 58,251,211, 53,139,102,221,218,244,235, 30,183,222, +173,199, 98,202,228, 41,224, 9,165,176,177,115, 0,195,114,168,174,112,196,155,248, 12, 28,253,101, 86,193,168, 40,135,214, 67, +230, 99,245,220,177, 88, 49,175, 98, 35, 38,143,199,195,250,245,235,213, 37,173, 86,197, 63,185,138,219,193, 63, 4, 86,158, 26, +106,141, 22, 95,125,187,209,244,103,212,185,149,196,148,147,203, 19, 80, 21, 9,176,210, 68,150, 41,239,111,163,222,152,251,119, + 86, 48, 44,203,226,236,217,179, 69,207,163,172,103,104,170,181,149,101, 89,188,127,255, 30, 47, 94,188, 64,211,166, 77,145,149, +149, 5, 62, 69, 97,230,179,103,240, 25, 54, 12, 58,129, 0, 44,203, 66, 40, 20, 98,252,248,241, 38,231,103, 37,149, 99,129, 31, +155,177, 92,114, 23, 23,151, 85,245,234,213,171, 29,149,145,129,144, 39, 79,208,100,220, 56, 0,192,237,219,183,139, 91, 0, 49, +120,240, 96, 97,116,116,244,232,240,240,240,209, 46, 46, 46,171, 19, 18, 18,102,150,249, 62,113,218, 34, 31,172, 1,131,251,162, +118,189, 90,216,187,115,127,209,241, 25, 95, 79, 3,159, 47, 0, 95,192,135,181,149,117,165,111, 45, 59, 59,155,183,106,213,106, +223,160,160,166,146, 33,195, 70, 82,122,134,195,162,101,107,233, 67,251,247,216,237,222,179, 87, 34, 22,139, 95, 86,248,140, 12, +250, 63,213, 83,132, 16,240,248,124,240,132, 2,128,101,193,113,156,108,197,138, 21, 11, 95,188,120,209,184, 94,189,122,208,106, +181,195, 8, 33,161,230, 56, 88,102,252,171, 4, 22, 77,211, 21, 90,167, 40,138,170,112,136,112,198,140, 25,176,176,176, 40,171, +225,225,158, 61,123, 22,150,144,144,176,149,227,184, 42,197,197, 57,243,123,232,139, 5, 95,246,201, 1,160, 6, 0,107,107,235, +212,246,237,219,231, 2,208, 31, 58,116,232,131,115,181, 90,237,251,178,120, 28, 29, 29, 23, 44, 95,190,124,106,215,174, 93, 41, +138,162,254, 84,185,151,220, 12, 6, 3, 78,159, 62, 61,117,201,146, 37, 40,203,234, 85,216,120,231,169,212, 80, 23, 56, 56,191, +121,126,196,212,202,188,194, 83,158, 54,114, 45,213,114,245,137, 82, 15,154,166,113,222, 49,255, 62,186,165, 84,204, 69, 40, 58, +226,237,251,216, 38,206,246,214,200,200,202,133, 72,200,135, 68,244,135, 53, 95, 34,206,183, 94, 73, 68,124,216, 88, 91, 32, 45, + 45, 9,124, 62, 63,162, 28,225,240,158, 16,210,106, 96,159,110,151, 40,154, 39, 46,126,140, 47,177,148, 94,190,243,204, 38, 41, + 93,133,226,198, 0,150,229, 48,117,209, 78,211, 10, 48,143,135, 73,147, 38,149, 41,112, 78,157, 58, 85,105, 11,150, 90, 83,201, +103,100, 34,127,121, 67,128, 21, 29,175, 8,133,179, 11,101, 50,153, 79,129,248, 50, 25,141, 26, 53, 58, 47,149, 74, 77, 14,114, +100,106,208, 81, 66,200,194,246,237,219,255,232,230,230,230, 56,113,226, 68, 66,211, 52, 2, 3, 3,237,127,248,225,135,172,124, +203,136,183, 69, 97, 29,179,102,205, 26,188,124,249, 50,133, 16,178,168, 60, 78,161, 80, 24,110,101,101, 21,216,174, 93, 59,100, +101,101, 33, 54, 54, 22, 50,153, 12, 62,171, 86,225,217, 23, 95,160,209,230,205,160,218,183, 7, 33, 4, 66,161, 16,207,158, 61, +131, 68, 34, 9, 47,139,207,213,213, 53,136,203,119, 50,111,129, 63,134, 5, 57, 0,119, 8, 33,179,226,227,227, 31,148, 82,223, + 81, 0, 96,100, 89,174,130,251, 31,252,237,183,223,130,146, 72,224,210,172, 25,212, 81, 81,208,235,245,104,218,180,105,145, 85, +189,105,211,166,160,105, 26,181,107,215,134,173,173, 45,142, 29, 59, 54, 24, 31,206,172,254, 0,154, 92, 61,222, 71,197,161, 89, +179,102, 69,150,170,238,221,187, 23, 89,176,248,124,126,145, 37,139, 24, 43, 22,172,132, 16,174, 68, 93, 76,132, 66,129,104,248, +200,209,212,172,175,190,100, 13,140,129,165,105, 62,245,213,220, 37,212,235, 87,207, 69, 42,149,138, 34, 21,244,214,170,247,234, +143,254, 29,242,141,160, 71,107, 59,128, 46, 16, 86,189,158,199, 21, 61, 23,203, 51,191, 11,151, 46, 93,218,175, 94,189,122,249, +195,237, 0,207, 28, 7,203,140,127,147,192,138,124,242,228,137, 87,253,250,245, 17, 19, 19,243,167,153,109,133,239,152, 76, 38, +131, 68, 34, 41,180, 16, 69,150, 69,118,245,234,213, 95, 0,252, 82,248, 91,161, 80, 52,107, 55,160,237,221, 38, 93, 26, 99,223, +146,253, 89, 9, 9, 9,190,133, 49,177, 8, 33, 68,161, 80, 12,229, 11,121, 3, 61, 26, 84,111, 3,150, 93,126,229,212,237,249, +229,221,136, 71,157,250,185, 0,212,197,102, 17,174,172, 74,134, 16, 66,250,119,237,218,149, 10, 11, 11,195,192,129, 3,177,119, +239,222, 50,207, 29, 58,116, 40, 14, 28, 56,128,206,157, 59, 83, 75,151, 46,237, 95,145,192,202,183,142,232,254, 99, 15,179, 52, +203, 85, 73,145, 88,161, 16, 96,153, 43,207, 30,135,248,249, 6, 54,231,191,139, 75,130, 88,200,131, 88,244,199,140,125, 73,129, +255,149, 68,196,135,179,131, 13, 30,222,189,174,103, 24,195,149, 10,196,197,123,148, 18,164, 81,100, 97, 31,241, 73,139,134, 54, +165,253,103,213,183,195,208,240,224,170, 10,211,203,231,243,177, 99,199, 14,117, 89,214, 43, 83,243, 32,223,202,104, 64, 94,158, + 26,121,106,205, 71,123, 38, 78, 78, 78, 14,142,142,142,155,172,173,173,197,165, 9,168,146,199,255,138,184, 42,136,139, 21, 54, +106,212,168, 74,137, 44,161, 80, 88,243,206,157, 59, 69, 65, 70,203,251,212,233,116, 24, 48, 96,128, 73,150,239,224,224,224, 29, +254,254,254,111, 28, 28, 28, 46,251,248,248,136,222,188,121,131,197,139, 23, 19, 62,159,111, 89, 88,127,228,228,228,128,166,105, +100,100,100,128, 16, 50, 34, 56, 56,248, 66,121,156, 90,173,246,198,141, 27, 55,252,122,246,236, 73,135,135,135,131,166,233,252, +116, 53,107,134, 70,155, 55,227,249,151, 95,162,205,187,119,208,232,245, 16,139,197,184,120,241,162, 62, 47, 47,239, 70, 57,247, +190,245,222,189,123,245,197, 98, 49,244,122, 61, 88,150, 5, 69, 81,132,199,227,181,244,241,241, 89, 7,160,113,137, 14,152,227, +248, 25,203,234, 26, 25,198,152, 16,243, 38,197, 4,139, 16,246,238,221,139,166, 77,155,162, 77,155, 54,136,143,143, 71, 84, 84, + 20,186,117,235, 86,116,206,147, 39, 79, 16, 26, 26, 10, 79, 79,207,138, 45,120,148, 1,158,117,107, 66, 32, 16,128,207,231, 67, +192,207,255,204,223,242, 45, 87, 2,190, 0,124, 30, 31, 98,137,216, 68,237,255, 97,153,180, 42,176,124, 73,165, 18,182,118,237, +218, 97,175,223, 68,249,128, 3,101,105,105,101,146,175,109, 33, 31, 33,164, 72, 92,241,133,130, 34, 75, 22, 0,100,101,101,105, +122,247,238,253,155, 86,171, 29,137,143, 56,146, 98,134, 25,255, 43, 2,171,219,152, 49, 99, 54,119,234,212,169,195,204,153, 51, + 33,151,203,145,144,144, 80,244,130, 9,133, 66, 84,171, 86, 13,121,121,121,184,121,243, 38, 50, 51, 51,175, 2, 24,111,234,133, + 19, 18, 18,238,191,126, 28,153,214,174, 95,115,187,250,205,235, 90,199, 70,198, 53, 5,112,183, 64, 92,253, 58,104, 70,183,145, +237, 62,107, 2,129,144,143,216,215,137,255,181, 12,161, 40,138, 38,132, 96,224,192,129, 38,157,255,249,231,159,227,198,141, 27, + 40,111, 56,177,200,130,149,167,129, 74,253,241, 58,103,132, 16, 24,141, 70, 52,141, 72,255, 96,102, 86,161,229,170, 80, 88,152, + 98,185, 42,234, 33,231,229,173,184,117,229,228,184,122, 13, 26, 57, 52,245,243,194,235,232, 56, 44,159, 51,182,232,248, 87, 19, + 6, 97,215,193, 83,112,117,182,135, 38, 47, 7, 23,206,157,206,202,206,206, 94, 81,213,123,216,125, 34, 63, 14,100,171,193, 31, +206, 17, 24,248,229,207, 38,253,159,207,231, 99,228,200,145,101, 90,176, 46, 95,190,172, 54,101,120,148,227, 56,232,117, 6,228, +170,212, 80,231,125, 28,129,165, 80, 40, 26, 53,109,218,244,242,150, 45, 91,236,236,237,237,161, 84, 42, 63, 16, 88, 10,133,162, + 81, 80, 80,208,229, 45, 91,182,216, 57, 56, 56, 32, 54, 54,214,228,240, 32,165,136, 43,164,164,164,144,140,140, 12,214,198,198, +166, 82, 34,139,162, 40,104,181, 90,188,124,249,210,212,119,196,228, 25, 95,114,185,124,231,146, 37, 75, 68,201,201,201,160,105, + 26, 47, 95,190,252,160,172, 22,110,223,126,251, 45,230,204,153,179, 9, 64,141,242,248, 24,134, 89, 61,116,232,208,209,241,241, +241, 54,142,142,142, 72, 72, 72,128, 80, 40, 4,199,113, 32,237,218,161, 85,116, 52,244, 70, 35, 36, 18, 9, 34, 34, 34,176,117, +235, 86,149, 86,171, 93, 93, 26,151,167,167,167,144,162, 40, 47,129, 64,128, 33, 67,134,124, 88, 46,119,239, 70,179, 26, 25,129, +227, 62, 17,229, 50, 16,107,147, 36, 93,207,211, 52, 77,198,127,181,188, 78, 80,235,238, 13, 94, 61,127,240, 38, 37, 41,238, 78, + 5,183,111,208,233,116,168, 87,175, 30, 30, 61,122,132, 43, 87,174,160,125,251,246,104,221,186, 53,174, 95,191,142,224,224, 96, +132,134,134,130, 16, 2, 59, 59,187, 66, 55,139,114,125, 45,116,121, 12,146,149,105,127,178, 86,149,252, 45, 16, 8,160, 85,235, + 77,122, 70,197, 69, 19, 33, 4,182,182,182,218,181,107, 86,136,228,114,185, 17, 0,228, 50,169,241,208,238, 13,176,183,179,213, +114, 38,154, 88,139,134, 5, 11,196, 21,205,231,127,224,166,192,113, 92,206,211,167, 79,199, 17, 66,158, 18, 66, 10,235, 15,115, + 28, 44, 51,254, 29, 2, 43, 36, 36, 36, 26, 64, 71,127,127,255,193, 55,111,222, 92, 61, 99,198, 12,135,150, 45, 91, 34, 61, 61, + 29, 53,106,212,128, 66,161,192,163, 71,143,240,228,201,147, 84,142,227,102, 6, 7, 7,239, 45,229, 37,235, 88, 86,172, 12,142, +227, 56,133, 66,113, 88,155,155,251, 69, 64, 27,111, 92, 61,116,107,137,139,139,203,120, 87, 87,215,233, 35,230,244, 26,217,182, +119, 99, 68,132,190,197,253, 75,207,144, 20,147,138, 17,173,102,149,203, 89,210,201,221,218,218,122,180, 84, 42, 21, 2,208,151, +210, 11,254, 96, 22, 97,113, 78,150,101,141, 58,157, 14, 7, 15, 30, 52, 73,100,237,223,191, 31, 26,141, 6, 44,203, 26,203,186, +119, 35,203, 18, 30, 95, 4, 69,181,122,208,235, 85, 96, 89,211, 39, 72,114, 21,228, 39,195, 48, 88,176, 96, 1,190,254,250,107, + 44, 90, 84,246,232, 10,143,199,195,134, 13, 27, 80,209, 51, 74, 79, 79,207, 81, 40, 20, 67, 15,108,255,249,200,144,177, 83, 45, +220,154,251, 98,231,161,243, 48,232,245, 16,137,248,176,177,148,161,118, 77, 55,232, 52, 42,108, 94,191, 38, 91,163, 86, 15, 45, +233,123, 86,222,115, 47,137,225,189, 91, 99,233,214,147,184,181,239,143, 73,136,173, 6,207,195,111, 43, 38,195,223,127, 71,185, +156, 70,163, 17, 60, 30, 15, 7, 14, 28, 80,151, 54,123,144,166,105,240,249,252, 50, 45, 88, 31, 62, 35, 35,225, 11,196,168, 86, +195, 7, 58,109,238, 71,121, 70,118,118,118, 95,111,223,190,221, 78,163,209,224,213,171, 87,120,249,242, 37, 8, 33, 69, 42,166, +240,120, 94, 94, 30,158, 63,127, 94, 40,112, 94, 86,230, 61, 42,180, 92,165,164,164,144,132,132, 4, 72,165, 82,234,233,211,167, + 26, 95, 95,223,176,242,222,239,226,156, 90,173,246, 93,135, 14, 29,202,178, 24,185,138, 68,162, 15,102,124, 21, 6, 29, 45, 57, + 84, 88, 90, 58,243,242,242,158,173, 94,189,186, 86,227,198,141,177,101,203, 22,157,133,133,133,112,198,140, 25, 28, 77,211,100, +237,218,181,200,200,200,208,205,158, 61, 91,120,235,214, 45,168, 84,170,199, 21,221, 59,199,113, 57,132,144,113,205,155, 55,223, +125,225,194, 5,169,151,151, 23,178,179,179,193,113, 28,118,237,218,133,201,147, 39, 67, 44, 22, 35, 34, 34, 2,159,126,250,105, + 94, 94, 94,222,184,226, 49,176,138,115, 50, 12, 67,248,124, 62,199,178, 44,190,255,254,251,162,160,162,133, 65, 70, 37, 2, 35, +182,206,240,144, 77,219,150, 37, 27,252,195,182, 97, 0, 96,100, 24,227,171,231, 15,222,236, 90,255,195, 53,129, 64,112,179, 24, +103,131,146,177,176, 8, 33,223,253,244,211, 79,155, 90,180,104, 33,145,203,229,240,242,242,194,157, 59,119,112,231,206, 29,220, +186,117,171,176, 12,192,214,214, 22,153,153,153,136,141,141, 85, 19, 66,190, 43, 47, 63,133, 82, 62, 60,234,212,204,159, 45, 88, + 96,177,226, 23,155, 61, 88,220,154, 37,224,243, 43,124,223, 75,186,119,216,218,218, 50, 1, 1,254, 97,106,181,154, 46,212, 82, +246,246,246,207, 11,206,229,170, 85,171,166, 43, 81,228,255,196, 25,185,125, 3,130, 23,127,151, 63, 44,248, 44,182, 72,108, 93, +251,196, 31, 60,129, 0,213,122,244, 45,222, 14,108, 36,132,236, 40,248,174, 45,198,249,205,199,142,133, 85,153,122,201,204,249, +247,112,254,155, 44, 88, 0,128,208,208,208,125, 13, 26, 52, 56,191,116,233,210,165,199,143, 31, 31, 59,117,234, 84, 98,105,105, +137,195,135, 15,115,105,105,105, 59,133, 66,225,215,247,238,221,203,168,202,197, 57,142,219,121,253,216,221,137,195,103,247, 38, + 51,214,142,104, 25,252,251,243,240,134,205,189,208,176,185, 23,130,175,134, 97,253,156,253,123,141, 6,227,247, 9, 9, 9, 49, + 21, 80,105, 59,182,168, 91,210,201,221,238,198,181,223,237, 42, 59,139,144,227,184,195,199,143, 31,159,218,173, 91, 55,234,225, +195,135,127,242,185, 42, 92, 30,135,101, 89, 92,190,124, 25,122,189, 30,135, 15, 31,102,203,139,131,197,130, 59,185,121,227,138, +225,155,183, 31, 19, 10, 5, 4,247,110, 30, 69, 86, 70,249, 86, 57,129,128,143,223,246,159,212,243,120,244,171,114,210,250, 62, + 52, 52,212,110,249,242,229, 52, 33, 4, 27, 55,110, 4, 69, 81,101, 58,180, 63,127,254,156, 53, 24, 12, 21, 62, 43,165, 82,121, +217,217,217,249,243,141,171, 23,236,106,215,185,151,181,119, 61, 31,158,163, 99,117,240,104,130,140,180, 84, 4,223,191,197, 92, + 56,123, 50, 83,171,213,142, 80, 42,149,151,255, 74, 1, 92,178,229, 68,169,251,251, 78, 93, 93,145, 21,133, 49, 24, 12, 60,153, + 76, 6,134, 97, 74, 13,213,208,190,125,123,201,157, 59,119,212,122,189, 30, 52, 77,151,171,152, 88,224,163, 63, 35,163,209,232, +157,145,145, 1,149, 74,133,144,144, 16,110,253,250,245, 41,153,153,153,115,138, 31, 79, 79, 79, 71, 78, 78, 14,130,131,131,185, + 45, 91,182,164,100,103,103,207,169, 76,254, 21,198,197,202,200,200, 96,165, 82, 41,101, 48, 24, 12,190,190,190, 98,153,204,180, +152, 87, 0,240,248,241,227, 46,101, 29,107,209,162, 69,228,157, 59,119,106, 27,141,198,226,107, 20, 10, 52, 26,141, 87,175, 94, +189,120, 38,164,111,240,165, 75,151,246,221,186,117,171,161, 86,171, 29,157,156,156,188, 27, 64,117, 30,143,135,215,175, 95,167, +232,116,186,190,223,125,247,221, 78,149, 74,245, 76, 46,151, 15, 54,177,222,184, 64, 8, 25,226,237,237,189, 99,193,130, 5,242, + 54,109,218,240, 20, 10, 5, 26, 55,110,140,136,136, 8,156, 61,123,214,176,113,227, 70, 85, 94, 94,222, 40,142,227, 46,151,211, +233,224, 0, 16,134, 97, 32, 20, 10,139, 54,145, 72, 4,129, 64,128, 60, 29,133, 49,171,162,212, 12, 36,234,213,243,199,157,229, + 0,146, 24, 27,149,154,156, 24,251,128, 16,114, 83,169, 84,102,149,101, 25,211,104, 52,126, 28,199,241,178,179,179,215,106,181, +218, 17, 51,102,204,112, 89,190,124, 57,124,125,125,145,154,154, 10, 91, 91, 91,184,184,184, 32, 55, 55, 23,209,209,209, 70,189, + 94,191,217,104, 52, 46, 76, 74, 74, 42,119,216, 49, 51, 53, 27,110,206,213, 63,176,116,114, 28, 7,206, 8, 24,180, 70, 24,245, + 28,116,196, 0, 62,223, 0, 19,151,208,226, 24,134, 65,143, 30, 61,112,230,204, 25,244,238,221,155, 3, 80,166, 21,233,204,153, + 51, 21, 15,185,179, 44,248, 34, 33,120,130, 63,134, 5,243,173, 89,249,251, 40,242,167,231,105,182, 90,153,241,239, 20, 88, 5, + 13,115, 38,128,241,141, 27, 55,222, 61,101,202,148, 51, 44,203,242, 89,150,237,254,248,241,227, 91,127,229,226, 9, 9, 9, 33, + 10,133,226, 91, 39, 55,155,165, 93,135,182, 68, 93,191, 26, 48, 50, 70,220, 57,247, 24, 59,127, 58,113, 32, 62, 54,126, 68,241, +181, 10,203,126,159,217,107, 45, 2,235, 82, 0, 4,197,134, 95,216,170,204, 34, 76, 78, 78,158,183,120,241, 98,252,248,227,143, +149,158, 69, 88,214, 57,119, 31,197,143,111, 22,232,226,246,121,223,246,157, 41, 66,113, 90,157,182,156, 94, 1,184, 66,175, 8, + 30,143,126,117,227,126,172,111, 89,231, 38, 38, 38,118,152, 56,113,226,239, 20, 69,213, 40,110,154, 47, 11, 70,163, 49, 33, 45, + 45,173,147, 41,249,144,152,152,120,222,205,205,173,206,141, 11, 39,191,189,125,229, 92, 91,163, 81,239, 73, 64, 32, 16, 8,222, + 24,140,204,117,131, 78,183, 36, 46, 46, 46,227,175, 22,192,111,199,247,198,123,101, 42,120, 60, 58, 63,176,103,193,227, 62,186, +110, 6,252,253,127, 43,243,127, 34,145,232,252,142, 29, 59,122, 12, 31, 62,156, 20,250,157,113, 28,247, 65,133,254,224,193, 3, +181, 78,167,195,206,157, 59, 57,137, 68, 82,110,224,218, 15,159, 17,225,180,229,248, 67,153,250,140,114,115,115, 71,245,234,213, +107, 23, 0, 17,128,215, 89, 89, 89, 19,148, 74,101, 92,241,227,189,123,247,222, 5, 64, 68, 8,249,211,113, 83, 80, 24,178,193, +198,198, 38,172,192,114, 37,174,138,163,123, 57,229,155, 46,107,248,208,148,161,194,130,181, 5, 63, 43,252, 29, 24, 24,184,112, +226,196,137, 69,139, 61,135,134,134,222, 6,224, 81,133,206,217,101, 66, 72,253,239,191,255,254, 75,177, 88,220, 46, 47, 47,175, + 78,129,160,139,208,106,181,215,212,106,245, 26,142,227,202,141, 45,245,230,205, 27, 93,173, 90,181, 34, 24,134,105,224,224,224, + 0, 30,143, 87, 36,178, 0,224,126,140,109,112,124,124,124,227,202,166,237,220,185,115,238, 54, 54, 54,157, 8, 33,253, 56,142, +171,155,147,147,163,253,225,135, 31,238,222,184,113, 35, 59, 60, 60,188, 75,171, 86,173,136,179,179, 51,222,190,125,203,229,230, +230, 30,161, 40,234, 59,165, 82, 25,101,194, 61,199,237,220,185,179,178,249, 84,110,121,210,233,116, 41,247,238,221,179,189,114, +229, 10,109, 52, 26,113,225,194,133,162,142,100,105,163,129, 81, 81, 81,208,233,116,229,142,161,235,179, 50,224, 59,237, 27,112, + 5,179, 57, 11, 81,189,123, 95, 16,112,224,116,102, 61,101,198,191, 3,228, 63, 50,141,185,146, 38, 68,133, 66, 49, 80, 44, 19, + 77,170, 81,199,197, 87, 25,149, 28,150,147,149,183, 55, 33, 33, 97, 11,199,113,198,170,114, 86, 38,208,168,217,204,251,247,112, + 10,165,150, 23, 9, 45,168, 81,102,227, 96,212,191,215,229,101,119, 46,141, 51, 40, 40,200, 85, 32, 16,172,208,106,181, 93,203, +139,210, 78,211, 52, 35,145, 72,206,107, 52,154,175, 75, 46,246,252,191,152,159, 71,142, 28, 41, 85,244,155, 58,139,176, 95,191, +126,198,202,164,179, 81,163, 70,215,164, 82,105,169, 1, 53,243,242,242, 98,158, 60,121,210,233,159,144,159,133, 51,219, 76,241, + 17, 42,206, 89,149, 89,132,101,112, 22, 13, 17,186,187,187,139,244,122,189, 63,128, 58, 0,172, 1,164, 27, 12,134, 11, 41, 41, + 41, 73,206,206,206,129, 20, 69,125, 95, 32, 94, 23, 37, 38, 38, 6,255,157,239,166,155,155,155,216,210,210,114, 5, 69, 81, 46, +166,252,159,101, 89, 93,114,114,242,140,212,212,212,196,210, 56,235,215,175, 31, 76,211,116,133,139,154, 27,141,198,184, 23, 47, + 94, 4,150,147, 78,243, 16,225,191,144,243, 95,105,193,250, 79, 67,169, 84, 30, 4,112,240, 99,114,150, 21,169,221,140,127, 14, + 10,197, 83, 85, 80, 32,150, 62,255,183,229, 89,161, 64, 42,101,255, 75, 0,228, 99, 95,207,148,112, 12,255, 4,112, 85,236, 41, + 22, 8,168, 86, 31, 51, 45,239,222,189,211, 2,184, 91,176,125,128, 2, 65,213,243,159,146,111,113,113,113, 26, 0,147, 63, 22, + 95,121,162,201, 12, 51,254,109,160,204, 89, 96,134, 25,102,152, 97,134, 25,102,152,241,113, 65, 0,116, 44,163, 71,104,178,233, +143, 16,210,177, 10, 61,206, 43,102, 78, 51,167,153,211,204,249,255,132, 51,185, 28,206,231, 21,112, 54, 40,227,144,227,255, 80, +126,250,149,193,185,172, 2,206,111,202, 57,252,216, 92, 62,255,127,114,254,107, 80,232,204,248,159,216, 0,116, 52,115,154, 57, +205,156,102, 78, 51,167,153,211,204,105,230,252,183,109,230, 33, 66, 51,204, 48,195, 12, 51,204, 48,195,140,143, 12,147, 5,150, +220,217,219,219,193,189,209, 46,219,106,190, 79,109,171,249, 62,117,112,111,180, 75,238,236,237,253,111,204, 52,133, 66, 33,113, +113,113, 25, 92,189,122,245,203,126,126,126,217,174,174,174, 95,154,139, 82,229,209,150, 16,222,231,132, 76, 26, 78, 72,204,112, + 66, 98, 62, 39,100, 82, 91, 66,254,223, 45,155,177, 96,154,162,217,173, 11, 67,206, 47,152,166,104, 86,234,241,175, 20,118, 15, + 46, 15,248,121,201,100, 87,219,143,113, 61, 66,136,133,147,147,211, 86,103,103,231,119, 78, 78, 78,239,157,156,156,118, 16, 66, +172,204, 37,206, 12, 51,204, 48,227,191, 7,147, 26, 51,219, 26, 13,199,120,215,171,251,245,226,249,115,136,179,163,189,148, 49, +178,250,183,239, 98,125,230, 45, 94,122,196,182, 70,195,213,233,239,159,109,175, 66, 35, 64,220,220,220, 6,242,249,252, 30, 0, + 10,133,218, 75,131,193,112, 38, 46, 46,238,160,169,179,130,124,125,125,111,211, 52, 93,189, 50,215,102, 89,246,221,147, 39, 79, + 90, 87, 37,195, 92, 93, 93,251,187,186,186,238,104,218,180,169,212,207,207, 15, 2,129, 0,203,151, 47,159, 9, 96,141,201,247, +222,182, 45,207, 49,211,118, 24,205,227,245, 4,224,203,113, 0, 8,253,148,213,235,206, 37, 11,108,119,113, 33, 91, 12,166,240, +184,184,184,204, 33,132,140, 64,254,180,242,237, 74,165,114,197,127,162,144, 40, 20,138,106,132,144,118, 28,199,213,163, 40,234, + 25,203,178,151,148, 74,101,218, 95,229,117, 2,198, 55,111,217,242,231,225, 51,103,210,234,155, 55,241,243,142, 29,107,145,157, + 13, 0, 27, 42, 91,150,130,130,252,250, 89, 88,160, 7, 1,252, 65, 64, 40,112,143,211, 51,169,115,143, 30,133, 30, 52, 37,150, + 90, 89, 8, 8, 8, 56, 11,160,112,225,184,115, 33, 33, 33,221, 43,203,145,245,134,155, 43,234,233,221, 42,235,205,181,185, 0, +186,150, 60,206,104,196,195, 57,186, 90, 15, 53, 23, 26, 11, 96,213, 95,201, 83, 66,136,212,193,193,225,233,201,147, 39,221,154, + 52,105,194, 3,128,224,224,224, 97, 61,122,244,104, 95, 16, 74, 32,251,239,168,104,154, 53,107,102,195, 48,204,110,154,144,166, + 44,203, 90, 3, 0, 69, 81,153, 70,142,187,207,227,241,134, 87, 53, 88,177, 25,102,152, 97,198,255,172,192,146, 59,213,243,169, + 95,223,123,230,133,227,187,171,101,166,103,106,126, 89,185, 59, 68,197, 19,230,121,249,120, 9,126, 89,179,194,102,210,180, 25, +211,229, 78,245, 30,228, 38,133,135,153,122, 81, 23, 23,151,234,238,238,238,199,230,204,153,211,160,101,203,150,124, 71, 71, 71, + 36, 37, 37,225,213,171, 87, 13,238,220,185,211,251,196,137, 19, 51, 93, 92, 92, 62, 51, 33,130, 59,100, 66, 65,173,131,203,151, + 56, 11,173,172,193, 25, 25,216, 52,240,203, 31,255,100, 89, 36,222,184, 2,163, 94, 15,142, 53,194,173,203,167,133,226, 10, 65, + 65, 65,130,170,100,150,155,155,155,162, 78,157, 58,123,103,207,158, 45,208,233,116, 8, 13, 13,197,189,123,247,216,228,228,228, +165, 38,139,138,134,125,124,156,121,206, 71,122,245,238,234,222,253, 19, 71, 97, 13,103, 7,112,172, 24,225,209,250,234,151,111, +133,118, 57,123,254,226, 44, 71,159, 62,125,147,195,142, 63, 43,143,167, 65,131, 6, 77, 41,138,250, 49, 62, 62,190, 80, 4, 45, + 15, 10, 10,250,161,248, 57, 37, 53, 42,203,178,224,241,120, 73,121,121,121, 3,159, 63,127, 30, 90, 26,239, 8,127, 98, 48, 24, +243,203,133,128, 7,227,213, 20,183,227, 29, 59,118,172, 57,106,212, 40,248,251,251, 35, 56, 56,184,221,225,195,135,167, 85,171, + 86,237,145,193, 96, 56, 39, 18,137,174, 23, 76, 75,175, 52, 4,192,172,225, 51,103,210,242,119,239, 32,127,242, 4, 67,178,179, +121,203,128, 89,149, 17, 88, 1, 1, 1,181, 58,117,244, 63,210,251,179, 54,222,206,206, 62, 2, 62,223, 30, 28,199,193, 96, 72, +175,147,146,242,178,159,149, 21,102, 55,105,210,164,239,195,135, 15, 77,138, 52,219,184,113, 99, 39,150,101, 55,115, 28, 39, 32, +132, 76, 1,208,237,194,133, 11, 48, 26,141,232,222,189,123,183,128,128,128, 90, 28,199,253, 34,151,203, 57,181, 90, 61,250,209, +163, 71, 73,229, 89,174,178,223,112,115, 19,137, 71,151,186, 1,195,145, 72, 46,116,153,209,213,229,188,165, 39, 89, 60,239,103, +229, 61, 0,232,234,233,105,225, 81, 79,246,141,220,178,161,109,118,252,149,111,186,122,122,110, 59,255,230, 77, 78, 85, 58, 44, + 5,229, 96,197,158, 61,123,170, 5, 5, 5, 21,197,203,242,243,243,163, 87,172, 88,225,250,229,151, 95,174, 5, 48,210, 68, 81, + 93,199,206,206,238, 34,203,178,218, 23, 47, 94,212, 41,220,239,216,232,179,230,118, 22,178, 14, 41, 25, 57, 55, 83, 95,156,184, + 97, 10, 87, 96, 96,224, 40, 1, 69,109, 93,243,253,100,186, 94,195, 70,144, 58, 56, 64, 31,167,132,202,104,176,189,255,228, 69, +247,101,107,182,166, 4, 6, 6,142, 11, 14, 14,222, 97,174,146,205, 48,195,140,127,141,192, 18,137,132,179,231,125,247, 13,201, + 76,203, 84,107,178,115,116, 6,141, 70, 67, 9, 56,205,179,176,232,100,138, 71,103,126, 57,109,170,197,236,111,191,155, 13, 96, +136,169,226,170, 94,189,122, 15,183,109,219,230,104,107,107,139,172,172, 44,164,165,165,225,225,195,135,224, 56, 14, 93,187,118, + 21, 53,106,216,192,127,245,154,181,247, 92, 92, 92,154, 85, 36,178,120,124, 30,225, 75,165, 56,218,198, 31,148, 64,128,190,225, + 9,249,226,194,160,199,249,129, 61, 0, 0,180, 80,136, 1,145,249,147,124,196, 98,113,149, 51,139,227,184,102, 45, 90,180, 16, + 0,192,140, 25, 51,178, 85, 42,213, 18, 66,200, 62,165, 82, 25,111,170,184,178,119,112,184,177,114,241, 88,219, 6,181, 60,160, + 55, 24, 16,155, 28, 15,142, 8,225,226, 40,195,208, 62,126,130,150,129, 66,143,149, 27,174, 92,119,106,208,171,117,210,243,147, + 47,202, 20,150, 50,217,238,181,107,215,226,208,161, 67, 0,128,107,215,174,193,203,203, 75, 86, 81, 26, 94,189,122,229, 49, 98, +196,136, 3, 0,106,151,118,220, 96, 4,111,223,190,125, 0,128, 85, 95, 13,166, 55,220,138,168, 41,145,252,177,150,114,155, 54, +109,208,166, 77, 27,106,201,146, 37, 65,215,174, 93, 11, 58,112,224,128,222,213,213,117,109,124,124,252,225,170,228,169,250,230, + 77,200,159, 60, 1,110,220,168,244,127, 3, 2, 2,106,213,171,103,119,127,245,170, 31,236, 79,159,121,129,149, 43,119,224,205, +155, 55, 0, 0, 15, 15, 15, 12, 30,212,159,191,239,183,205,245,103,207,158,127, 55, 32, 32,160,101, 72, 72, 72,133,209,205, 89, +150,221,252,213, 87, 95,125,234,234,234,138,185,115,231, 70,212,170, 85, 11,150,150,150,216,178,101, 11,108,108,108, 96, 48, 24, + 34,150, 47, 95,206, 83, 42,149, 88,183,110,221,175,197,172, 91,127, 66,219,206,109,231,138,122,122,183,170, 27, 48, 28,114, 75, + 23,108,219,127, 16,175, 66,118,183,210,234, 95,206, 93, 50,217,117,168,154, 19,141,112,243,178,152,237, 30,216,198,174,118,253, + 79, 81, 35, 32,212, 94, 99,188, 21,253,253, 36,143,165, 60,177,102,247,188,149,127,182, 18,146,254, 71,232, 6,217,225,182,207, + 47, 35,141,227,230,177, 5,194,170, 40,254,149,145,195,167,173, 91,183, 46, 18, 87,239,222,189,131, 86,171,133,183,183, 55,165, +211,233, 76,138,105,165, 80, 40,234,180,110,221,250,246,222,189,123,237, 90,181,106,245,193,210, 45,206,118,214,157,111, 28, 91, + 59,245,199,159,127,171,231,232,211, 39,179,162,142, 64, 96, 96,224,168,134,117, 61,183,175, 93,254, 3,161,115, 98,193,179, 78, + 1,140,169, 72, 56,248, 43,136,212, 22,221, 39,204, 64,227,160, 32,122,234,151,115,182, 55,110,220,152,123,244,232,209, 78,115, +181,108,134, 25,102,252, 43, 4, 22,203,177,190, 78,142,118,146,181, 43,119, 61,162,245, 58,157,204,218, 74,199,183,178,100,137, +133, 21,173,215, 25,114,107,120,212, 16,178, 28,235, 91,134, 32,185, 82,178,151,237,238,238,126,108,231,206,157,142,124, 62, 31, + 44,203,194,193,193, 1,111,223,190, 69,102,102, 38,114,114,114,240,230,229, 75,212,172, 94, 13, 83,199,141,117, 89,180,114,213, + 49, 66, 72, 96,241,225,194,146,156, 28,203,129,101,152,146,189,121,160,148, 37, 99,202, 90, 70,198,212, 41,165, 44,203,190, 85, + 42,149,144, 74,165,240,246,246,150, 63,122,244,232, 86,124,161, 9,169,162,123,111,219,150,231, 34,114, 56,182, 98,241, 64, 91, + 80, 17,136,136,201,132,167, 91, 19,216, 91, 87, 67,124, 74, 46, 30,133,157, 67,228,155,179,240,116,173,129,113,131,107, 91,175, +217,114,231, 12, 9, 24,239, 89,124,184,176, 56,103, 78, 78,142,188, 70,141, 26,112,117,117, 5,203,178, 48, 26,141, 8, 11, 11, +131,209,104, 44,250, 93,252,115,215,209,171, 96,178,223, 99,248,176, 97, 72, 79, 79,151,155,122,239,133,226,106,203, 96, 69,125, + 85, 70,130, 0, 0,100, 54, 46,250,113,191,197,191,104,220,184, 49, 28, 28, 28, 4,119,239,222,157, 1,224,112,101,243, 83, 15, + 44,255,121,231,206,117, 67,178,178, 40, 0,216, 78, 8,171,207,143,170,109, 82, 89,234,216,177,209,209,181,107,191,183, 39, 92, + 24,108,173,150,225,225,195,247,208,235,243,139, 74, 90, 90, 50,166, 76,202, 6,143,103,129, 85,171,231,219, 13, 24, 48,225,104, +193, 16, 25, 91, 94, 58, 57,142, 19, 92,189,122, 21,131, 6, 13,194,129, 3, 7,120, 52, 77,227,193,131, 7,144, 72, 36, 24, 57, +114, 36,234,215,175,207,147, 72, 36,184,125,251, 54,178,179,179, 73,121,233,188,126,241,250,226,172, 55,215,230, 38,146, 11, 93, +182,237, 63,136,177,131, 6,194,153,139,186,101,229, 73, 22,119,234,217,226, 7,142,174,214, 67,102,225,107,227,213,160, 39, 4, + 66, 57, 38,207, 90,136,136,231,167,109,242,114,158, 78, 34,198,216,106, 0,166,149,228,228, 14,247, 51,174,219,127, 55,224,114, +245, 71, 53, 20, 1,227, 31, 0,120,250,135,192,242,224, 17,202,104, 85,104,189,124,253,250, 53,222,188,121, 3, 30,143, 7,181, + 90,253,193,162,190,197, 57,253,253,253,199, 27,141,198, 31, 0, 64,167,211,237,114,114,114, 26,245,203, 47,191,216, 21, 46, 65, + 84,220,114,149,158,153,157,113,247,209,139, 87, 51,198,247,107,123,243,254,243, 88,235, 70,189, 99, 50,159,156,200, 42, 45, 63, +155, 53,107,102, 35,164,233,173, 63,175,152, 71,140, 81, 87, 33,242,110, 11,158,220, 11, 70, 67, 60, 52, 25, 42,104,162, 19,160, +219,178, 30, 30, 19,191,196,138,101, 63,146, 65, 67, 71,111,245,244,244, 60,246,166,152, 5,239, 63, 49,221,219,204,105,230, 52, +115,254, 51, 57,255,117, 2,139, 16, 42,219,104,100, 69, 2, 7, 71,205,232, 1, 29, 26, 94,186, 18,252, 88,106,111,201,235,220, +214,191,205,195,103,209,247, 8, 69, 12,132, 80, 38,249,117,184,185,185, 13,156, 55,111, 94, 67, 75, 75, 75,176, 44, 11, 43, 43, + 43,164,164,164, 64,167,211, 33, 43, 43, 11,218,156,108,232,115,178,241, 36,246, 29, 90,180,105,139,142,205,154,122,159, 55, 24, + 6, 2, 56, 80, 22,167,145,162, 57, 59,255, 38,232, 31,149, 6, 86,175,195, 97, 15,187, 34,171,213,231,239, 50, 65, 8, 1,171, +215,225,124, 80,109, 8,229, 50, 52,250,122, 94,149, 51, 43, 33, 33, 33,180, 70,141, 26,231,187,118,237,218,117,252,248,241, 84, + 98, 98,226, 5, 39, 39,167, 22, 73, 73, 73, 21, 14,143, 58,102,216, 12, 31, 62,174, 97, 45,123,107, 10,167,111, 95, 64,211,122, +125, 32, 21,241,145,146,169, 6, 1, 65,212,219, 43, 96, 25, 57,158,188,124,135,230,190, 82,180,110, 98,237,150,251,123,250, 56, +148, 61, 92, 70, 50, 50, 50,144,156,156, 12,131,193, 0,131,193,128,126,253,251, 99,207,238,221, 80,169, 84, 80,171,213,208,233, +116, 48, 26,141,160, 40, 10,151,207, 28, 70,108,244, 75, 52,111,214, 12, 40, 39,226, 55,159, 6,179,234,171,193, 60, 0, 16, 90, + 56,232,115,114,114, 32,147,201,160,202, 72, 16,204, 92, 89,100,217, 18, 92,187,118, 13, 33, 33, 33, 80, 40, 20, 38,149,163,210, +240, 6,216,250,214,104,156,219,245,248,113,199, 59,199,143,179,247, 79,159,142, 19,229,228,108, 49,229,191, 65, 65,126,253,166, + 78,233, 94, 87, 34,150, 32, 46,102, 45,234,213, 19, 96,230,151,118, 88,178, 44, 21, 0, 48,117,138, 27, 26, 7,218, 35, 59,243, + 8,236, 29, 61, 49,115, 70,111,207,220, 92,110, 24,128, 93,229,151,119, 50,229,233,211,167, 17, 78, 78, 78,188,208,208, 80, 8, +133, 66, 72, 36, 18, 72, 36, 18,136,197, 98, 36, 38, 38, 66,167,211,225,208,161, 67, 76,193, 16, 98,153, 40, 24, 6,236, 58,163, +171,203,249, 87, 33,187, 91,185,210,209, 79,250, 78,110,249,238,233,253,208,156, 75,151,239, 44, 98, 52,226,216,204,184, 43,223, +212,106, 28,106, 63,233,235, 5, 88,191, 98, 30, 94, 61,184,153,238, 84, 61,123,131,132,104,119, 5,125, 82,138, 85,172,237, 2, +222,164,239, 7, 48,227, 71,244,181, 62,237,116,119,252, 57, 30, 73, 73, 76, 13, 89,137,183,161,106, 81,109,255,161,117, 60, 40, +221,213,171, 87, 37,173, 91,183,134, 70,147,191,100, 28, 77,211,216,187,119, 47,203, 48,204,181, 82,173,150, 6,195, 15, 33, 33, + 33, 46,106,181, 26,159,127,254,249,212,249,243,231,203,248,124,126,254,251,101, 52,126, 96,185, 90,188,102,207,197,233, 63,108, +184,118,241,192, 50,197,226,217,163,218, 14,153,252,227, 53, 0, 23, 74,227,101, 24,102,247,218,101,223,210, 34,107, 3, 72,227, + 78,208, 39,169,241,126,219, 88,232,178, 53,168,179,104, 1, 0, 33,116, 6, 10,103,123,245, 3,101,171,192,152, 86, 45,120, 91, +110,222,222, 13,160,183,185,106, 54,195, 12, 51,254,255, 91,176, 88,246,230,235,232,119,221, 58,117, 12,114, 59,115,227,217,163, +241, 35,187,119,166, 40,138, 60, 14,123,127,195,179,134,179,253,181,235, 55, 57,150,101,111,154,114, 49, 62,159,223,163,101,203, +150,188,140,140, 12, 40, 20, 10,164,164,164, 32, 62, 62, 30, 6,131, 1,154,172, 76,232,114,178,161,203,206,130, 81,149,131, 55, +193, 15, 81,175,186,155,232, 74,190, 19,252, 1, 83,248, 75, 90,168, 10, 23,253, 5, 33, 16, 89,200, 33,146,203, 43, 94, 9,190, + 4, 20, 10, 69, 47, 75, 75,203,111,114,114,114,206,197,199,199, 47,214,233,116,147,126,250,233,167, 71, 11, 23, 46,180,159, 61, +123,182,229,172, 89,179, 14,187,187,187,251, 85,228,135,100, 97,107,236,215,180, 97,109, 58,242,253,115, 4,214,233,135,154,138, +150,136,138,207, 66,122,142, 22,105, 89,106,212,173,243, 53,146,210,242,144,165,210,224,217,171,125,112,117,174, 69,209,252, 55, + 93,202, 17, 88, 72, 74, 74,250,224,158, 15,236,223,143,188,172, 44,120,122,122,194,219,219, 27, 14, 14, 14,120,255,254, 61,110, +223,190,141, 33, 3, 62, 5,159,223, 23,201,201,201,229,222,239,174, 80,142,175, 80, 40, 66,148, 74, 37, 66, 67, 67,241,230,205, +155, 82,135, 85,127,255,253,247,252,134,215,217,217,228,188,116,114,114,250,150,162,168, 1, 0,104, 0,177,148, 66, 81,219,193, +193,193,169, 69,239,222,200,226,243,233, 95,174, 93, 35, 60, 43, 43, 57,128,204,138,184, 44, 45,209, 61, 48,176,165, 48, 51, 99, + 7,128,124,163,212,168,145, 14,232,218,197, 9,132, 18, 65,225, 98, 1, 66,137, 64,136, 16,121,170,171,240,169,239, 43,176,176, + 56,214,163, 60,129, 85,232,208, 94,191,126,125, 76,152, 48, 1, 39, 78,156,192,174, 93,127,156,222,183,111, 95,124,246,217,103, +200,205,205,133,147,147, 19, 79,169, 84, 70, 5, 4, 4, 84,232,248,110,233, 73, 22,107,245, 47,231, 90,123,201, 82,140,176,111, +158,107, 16,165,205, 91, 25, 53, 15,192,170,174,158,158,219,244,236,205,232,200,231,167,109,222, 62,186,158,174,140, 84,121,108, + 59, 27, 85,166, 15,214,141, 27, 96,157,124,111,232, 63,237,210,134,215,187,103,187, 60, 87, 55,167, 58,191,108,208,237, 77,119, +181, 91,236, 94,221,109,200,188,159,190,209, 15,237,211, 74,255,205,204, 41,252,250, 62,222, 36, 59, 59, 27, 7, 15, 30,100,206, +159, 63,159,192,178,236,244, 50,104,233, 2,161,133, 1, 3, 6,200,164, 82, 41, 98, 99, 99, 81,175, 94, 61,176,108,126,222, 38, +164,164, 61,187,243,232,121,248,140, 9,253,219,236, 59,117,237,229,197,235,193, 47,123,119,105,209,136, 16,206,189,172,180,210, +132, 52,245,241,245, 5,199,197,131,230,215, 65,220,222, 81,208,164,229, 64,171,210,128,226,203,160, 51,208,208,179, 4, 34,223, + 38,120,125,226, 20,106, 15,174, 15, 30, 33, 45,204,213,178, 25,102,152,241,255, 1, 21,170, 13, 90,163, 91,242,213, 55,115, 97, + 99, 37,177,106,226,239,229,124,242,194,141,224,155,119,131, 95,186, 87,179,119,224, 12, 58,155,229,171,215,187,145, 60,181,169, + 78,222,222,246,246,246,208,235,245,120,253,250, 53,226,226,226,160,215,235,193,168, 84,208,102,102, 66,147,145, 1,163, 42, 7, + 2,163, 17,234,148,100,216,136,133,192, 31, 51, 12,203, 51, 85,254, 33,166, 74, 17, 92,132, 16, 72, 44, 45, 33,178,176, 0,197, +163, 77,206, 28, 23, 23,151, 0, 63, 63,191, 67, 87,175, 94, 13,106,217,178,229, 34,119,119,119,171,196,196,196,247, 73, 73, 73, + 29, 86,172, 88,161,117,112,112,192,144, 33, 67,234, 26, 12,134,225, 21,113, 9, 68,218,134,213,157,188, 80,205,233, 83, 40,236, +155, 34, 61, 91,139,228, 76, 53,146,210,242,112,240,216, 64, 92, 58,247, 57, 30,223, 30,134,215, 15, 70, 33, 53,215, 18, 98,219, +118, 0,184, 6,229,113,222,189,123, 23,155, 55,111,198,230,205,155,177,105,211, 38,172, 95,191, 30, 25, 25, 25,104,208,160, 1, + 98, 98, 98,112,254,252,121, 36, 36, 36,192,222,222, 30,143, 31, 63,198,150, 45, 91,240,240,225,195, 74, 23, 18,141, 70, 3,129, +220, 78,191,234,171,193, 88,245,213, 96,176,124,153,190,152, 0, 55,189,176, 81,212,136,132,222,189, 27, 38, 88, 91,251,248,250, +250,118, 29, 48, 96,128, 71, 80, 80, 80,209,113, 79, 79,207,234, 60, 30, 47, 81,161, 80,108, 87, 40, 20,126,229, 43,127,206,223, +198,214, 27, 58,109,120,193, 51,230,131, 16, 49,218,127,242, 18, 45, 90, 5, 67,111, 16,128, 34, 34, 80,148, 24, 12,147, 6, 75, + 11, 39,112, 28,105, 80, 65, 18,187, 93,184,112, 1,155, 55,111,198,219,183,111,139,132,101,143, 30, 61,166, 12, 26, 52,232,152, +209,104,196,153, 51,103,112,226,196, 9,212,172, 89, 19,141, 26, 53,130, 94,175,239, 86,209,125,207,251, 89,121,111,223,234,243, +159,243, 13, 54,126, 98,137,123, 77,168,228,189, 38,181,117,144, 1,192,249, 55,111,114, 28,171,103, 47, 85,229, 60,141,177,118, +203, 93, 86,145,131, 59,199,205, 99, 67, 34,195,239,239, 59,126, 33, 43, 57, 41,131,239,223,176,190,122,201,194,175, 5,238, 53, +107, 47,159,247,205, 4,231,248,108,113,230, 39, 83,207,135, 31,187,240, 48,119,232,200,177,204,232,113,147, 53,231, 47, 92, 62, +206,178,108,195,178,102, 16,178, 44,139,132,132, 4,188,120,241, 2, 81, 81, 81, 72, 73, 73, 65,106,106, 42,114,114,114,138,134, + 21,165, 57,217,103,215,239, 60,253, 68, 38,145, 72,131, 26,122, 85,127, 16, 26,150, 44,147, 72,164, 94, 53,171,215, 33,100, 1, + 85, 6,175,181, 88, 34, 6, 64,144,243,252, 38, 52,233,185, 80,103,230, 66,147,145, 11,173,158,134, 70, 75, 65,173,163, 96,223, +170, 19,114, 85, 26,104,210, 50,192,114,156,141,185, 90, 54,195, 12, 51,254, 21, 22,172,212,212,136, 92, 75, 7,159,207,190,156, +245,195,249,253,191,254,226,168,213,230,197,216,217,200,141,114,169,208,126,244,248, 31,145,147,155,209, 39, 55,221,244, 89, 79, + 25, 25, 25,136,142,142,134, 68, 34,129,128,207,135, 81,173,134, 81,173,130, 58, 35, 13,148, 94, 11,129,209, 8, 91,169, 4, 53, + 20,206,112,119,170,216, 58, 66,179, 70,162,188,124, 14, 23,135,246,249,211,176,224,133,230,117, 33,146,203, 32,182,182, 65,139, + 19,183,242,133,142, 64, 0,204,171,120,145,118,103,103,103,123,133, 66,113,106,253,250,245,130,180,180, 52,188,120,241,226,201, +187,119,239,178,108,109,109, 45,248,124, 62, 27, 25, 25,121, 37, 60, 60,188, 71,173, 90,181,192,113,156,103, 69,124, 57, 89, 50, +189,193,192, 65,153,252, 30,113, 9, 47, 96, 41,175, 6,142,174,134,228,244, 60, 16, 56,129,209, 70,192,104,200,119,183,210,170, +227,144,167, 51,109,221, 94,189, 94, 15,189, 94, 15,131,193, 0,173, 86,139,161, 67,135,226,206,221,187, 56,112,226,119, 68,191, +137, 64,221,154,206, 24, 54,108, 40,252,252,252,240,232,209,163, 42, 23,148,102,223, 92,124, 33,145, 72,176,105,211, 38, 72,165, +210, 15,196,173,137, 98,117, 85,135, 14, 29,106, 71,168, 84,120, 17, 30,142, 38,253,251, 3, 0,110,223,190, 93,116,142, 90,173, +198,224,193,131,133,209,209,209,163,195,195,195, 71,187,184,184,172, 78, 72, 72,152, 89, 22,231,217,179,247, 48, 97, 66, 24, 82, + 82,242,253,176, 15,238,175, 95,116,236,109,180, 30, 93,186,231,143, 92, 89, 91, 91, 99,245,234, 6, 38,165,211,104, 52, 98,235, +214,173, 69,195,130, 0,192,227,241, 90,204,152, 49,227,179,210,206,247,241,241,169,144,115, 70,127, 55,241,227,247,146, 73, 86, +181,221,235, 91,218,251, 34,205, 16,218, 32, 52, 62, 97,202,140,254,110,107, 87, 31,142,211, 72,136,118, 23, 49,198, 86,227,137, + 53,187, 77, 73,227,155,243,235,116,214,238, 35,119, 39,166,100,127, 55,121,236, 96, 59, 75,107, 71,213,246,245, 75,108, 40,154, +226, 78, 5,235, 51,235,123,216, 89,247,106,250,115,238,132, 47,191, 15,213, 49,177,147, 17,123, 42,162,188, 80, 21, 44,203, 66, +169, 84, 34, 37, 37, 5, 49, 49, 49, 72, 77, 77, 45,120,247, 83,139,134, 8,171, 2, 66, 8,116, 49, 49, 72, 58,177, 29,206, 67, +134,162,206,194,133, 48,178, 60,104,242,140, 56,210,186, 3,178, 51,213,208,177, 4,214, 1,205,209,233,204, 45, 16,214, 8,220, +191,107,174,149,205, 48,195,140,127,135,192, 2,128,236,148,176, 40,187, 26,190, 74,149, 90, 37,117,114,116,208, 74,197, 34, 54, + 43, 59,135, 14,125,246, 68,159,155,240,250, 85, 37,174,247, 50, 44, 44,172, 65, 92, 92, 28, 98,222,191, 7,163, 86,129,210,234, +192,105,242,208,177,101,115,136, 1,136, 41, 2, 1,171, 7,143, 22, 34, 39, 55, 27, 0, 94, 86, 68,202, 26, 12, 31, 84,234,132, + 16, 16,138,130, 88, 46,135,208, 66, 6,145,165,197, 7, 22, 45, 83, 32,145, 72,246,109,217,178,197,197,217,217, 25,171, 87,175, +134,139,139, 75,189,142, 29, 59,230,181,105,211, 70, 98,111,111,143, 58,117,234, 32, 48, 48, 16,215,174, 93, 3, 33,228, 77, 69, +124,140, 78, 24,242, 50,154,169,150,149,243, 24,247, 67,247,192,160, 51,192,179,206, 28,168, 13,118,144, 57,140,134, 70,119, 10, +198,204,235, 0, 0,161,101, 91, 36, 38,166, 2, 32,207, 43,243, 48, 57,142,195,211,167, 79,177,255,228, 13,184,212,240, 70, 76, +100, 56,194,175, 93,193, 29, 7, 59,184,251,212,135,193, 96, 48, 89, 16,153,122,158,169, 13, 48, 33,100,240,216,177, 99,145,201, +227, 1,221,187, 67, 16, 21, 5,189, 94,143,166, 77,155,162,113,227,198, 0,128,166, 77,155,130,166,105,212,174, 93, 27,118,118, +118, 56,122,244,232, 96, 0,165, 10, 44,142,144,199,172, 49,173,158,135,135, 71,145,192,218,189, 39, 5,161,193,159,128, 64,136, +117,235,255,136,202, 80,189,122,117, 36, 38, 70,131, 16,174,162,252, 60,215,189,123,247,110, 54, 54, 54, 24, 53,106, 20,196, 98, + 49,250,244,233, 3,141, 70, 51, 0, 0,150, 46, 93,138,111,191,253, 54,223, 42, 53,111, 30,230,207,159,143,188,188,188, 50,135, +134,247,172,241, 85, 36,167,179,163,157,156, 93,251,180,179,119,111,216,190,115, 71,212,242,106,143,246,157, 99, 0,224, 39, 91, +222,187, 1, 43,230, 54, 56,110, 95,205,118,199,165, 11,151,231,181,108,211,254,187,217,227,109, 22, 47,221,146, 81,161, 79, 99, +214,251, 93, 57,175,132, 3,215,252,178,121,207,154, 31,190,157, 38,142, 73,209,101,196,103,112,185,114, 17, 79,238,233, 68,228, + 83,102, 45,138, 86, 42,163,102, 34,246, 66,132, 41,207, 48, 42, 42,170,200,103, 79,163,209, 64,165, 82, 33, 54, 54,182,232,249, +170,101,150, 93, 38,143,236,217, 72,165, 86,231, 61,120, 22, 25, 51,119,234,144,102, 42,181, 58, 47,242,109, 76, 4,199,253,204, +150,241,204, 51,243, 84,121,182,218, 44, 13,178,158,188,130, 93,251, 26,208, 51, 4, 90,163, 17, 25,169, 57,208, 49,128,129,230, +195,173,223, 48, 24,192, 67,118, 74, 34, 40, 66,204,241,176,204, 48,195,140,127,143,192, 34,132,144, 70, 13,107, 40, 86,204, 27, +226,198, 50, 76,221,228,212, 36,134,199, 19,241,171, 89,169, 19, 42,115, 49,131,193,112,230,214,173, 91,189, 91,182,108, 41,138, +124,246, 4,186,172, 44,232,178, 50,193,103, 25,216, 74, 2, 65,233,181, 32, 58, 29, 92,235,177,208,228, 72,112,247,225, 43,131, +193, 96, 56, 83,174, 16, 0,199,177, 76,190,192, 34, 20,245,193, 80,161,200,202, 2, 34,185, 28, 34, 11,139, 82,135, 16,203,130, +147,147,147,180,107,215,174, 29,252,253,253,193,113, 28, 86,172, 88, 1,189, 94, 47, 52, 24, 12, 69, 22,163,220,220, 92, 28, 57, +114, 4,123,246,236,185, 99,101,101, 85,225,212,114,150,209,158,191,122,251, 73,183, 33,125,218, 9, 47, 95,223, 6,131,142, 69, +182,198, 18,185,106, 45,114, 53,124,104, 69,157, 65,200, 45, 80,180, 8,205,253,106,227,234,237, 8,141,209,160,191, 80, 89, 33, +164,209,104, 16, 27,243, 14,113,111, 34, 32,207, 78,132,131,165, 20,121, 81, 17,240, 27, 54, 28, 58,157,174,194,123, 31,225, 79, + 12, 51, 26,128,183,186, 43, 5,129,220, 78,223,236,155,139,101,134,138,144,203,229,149, 26, 34, 76, 77, 77,197,233,211,167,209, +180,105, 83,180,105,211, 6,241,241,241,136,138,138, 66,183,110,127,140,178, 61,121,242, 4,161,161,161,240,244, 44,223, 40,152, +157,205,157, 75, 79,127,221,191, 87,175, 94,130,251,247,239,131,227, 56,120,121, 89,194,210, 66, 6, 66,137,224,237,237, 8, 32, + 95,251,183,109,219, 22, 58, 93, 60,163, 82,225, 92,121,156, 33, 33, 33,221, 3, 2, 2,106, 25, 12,134,136, 54,109,218,240, 94, +191,126,141,126,253,250,225,224,193,131, 0,128,217,179,103, 99,246,236,217, 31,252, 39, 55, 55, 87, 83, 22, 95,221,134,245,190, +174,197,216,180, 17, 75,220,107, 90,218,251,162,150, 87,123, 0,192, 39, 61, 70,161, 86,237,234,200, 78,125, 90, 83,163,126,215, + 71,192,203,176,121,186, 46, 62, 76,210,189,193, 72, 77,242,245, 72, 0,166, 4,238,229,212,145, 7,147, 98,248, 67, 15,157, 56, +117,126,124,183, 30,159,242, 13, 70,134,105, 80,131,111,125,248,248,217,228,248,247, 49, 63, 35,230,194,243,162,215,164,124,129, +101,204,206,206,134, 76, 38, 67, 84, 84,148,182,103,207,158, 34,181, 90,141,215,175, 95, 23, 9, 44, 71,123, 91,159, 22,141, 27, +212, 91,188,102,207, 69,153, 72, 36,234,220, 54,208, 59, 44,242,125, 28,199,145,119,101,242,114,220,253,215, 47, 95,117,119,116, +169, 13,229,141,251,144,182,236, 6,173,150,130, 70,199, 66,203, 0, 12, 45,128, 85,163, 32, 72, 60,188,193, 1,120,249,236, 9, + 24,142,187, 99,174,150,205, 48,195,140,127,141,192,178,183,183,119,244,247, 15,244,220,246,235, 33,112, 28,135, 87,161, 43,145, +145, 28,142,239,127,186,231,233,230,230,214, 38, 46, 46,238,134, 41, 60,113,113,113, 7,143, 30, 61, 58,211,215,199,199,191,166, +155, 27,158,188,123, 11, 1,103,132,192,104, 4,165,215,130,103,212,193,173,129, 17, 20,145, 35, 33, 33, 27, 91, 46, 92,121, 30, + 23, 23,119,176,220,198,129,208,168,214,179, 47, 6,125,210, 29,156, 65,143, 75,173,124, 32,182,144, 67,100,109,141,230, 71,174, +131, 16, 2,142, 49,224,253,146,175,192,151,201, 97,219,172,226, 80, 64, 73, 73, 73,121,181,107,215, 14, 14, 15, 15,111, 92,183, +110, 93, 44, 88,176, 0,177,177,177,224, 56, 14,201,201,201,154,148,148,148,248,180,180,180,119,132,144,227, 74,165,114,155, 41, +145,194,147,109, 50,118, 95,254,253,202,215, 1,126, 62, 94,159,180,153,143, 51,103,230, 33, 35, 43, 27,121, 58, 62,114,212,122, +168,212, 28, 92, 45,189,208,196,215, 23, 41,233, 58, 68,190, 8,137, 75, 21,216,110,173,140,245,138,162, 40, 60,121,242, 4, 30, + 10, 11, 68,220,186, 1,123, 41, 31,141, 20,206, 80,180,104,137,168,168, 40,211, 68,176, 17,188,226,179, 5,173,173,173,145,149, +149,245,129,144,147, 74,165, 80, 40, 20,200,206,206,198,145, 35, 71,192,153,214, 40, 26,116, 58, 29,234,213,171,135, 71,143, 30, +225,202,149, 43,104,223,190, 61,218,180,105,131,167, 79,159,226,210,165, 75, 8, 13, 13, 5, 33, 4,118,118,118,133,190, 63,101, + 70,180,127,248,240,201, 97,185,156,204, 25, 57,114, 98,253, 33, 67,134,224,232,209, 3, 24, 53,178,110,129, 99,187, 8,159,246, +172,139,133,139, 30, 33, 40,168, 45, 28,236, 5,184,124,229, 69, 52,143,103,181,199,132,124,252,229,151, 95,126,225,169,213,106, +228,230,230, 66, 46,151, 35, 45, 45, 63, 28, 85, 25, 22,172, 50, 3,171, 61, 11,121,185, 50, 51,135,203,224,114, 67,251,164, 51, +161, 13,219,119,142,197, 39, 61, 70,226,242,153,157,184,122,241, 10,108,121,239,222, 66,150,115, 62,245,109,106,118,130,202,107, +179,119,192, 24, 58, 78,117,113,243,212, 94, 54,180,139, 11,123,120,246,198,172,204,114,210,201, 17, 66, 72,122,216,222, 83,199, + 57,124,218,188, 89, 80,237, 6,213, 93,132, 25,169,201,220,145,147,231,159,235,223, 30, 61, 93, 40,172, 76, 88, 21, 97,225,218, +181,107,127, 0, 0,150,101,119,173, 89,179,102,204,215, 95,127,237,160, 84, 42,139, 4, 86,114,106,250,213,230,221,167, 24,211, + 50,179,116, 59,214,204,234, 39, 17,139,132,115,151,238,184,110,160,113,191,204,202,133,199, 27, 62,103,211,111, 41, 71, 15,239, +164,237,197, 2,220,153, 61, 15,111,174, 92,131,158, 18,160,243,165, 7,208,233,141,200, 78, 73,195,181,209,147, 96,237,108,131, +115,169,145,198,172,156,236,225,230,106,217, 12, 51,204,248,255, 0,147,166,212,165,166,166, 38,223,188,249, 0,215,207, 44,198, +141, 51,139,241, 34,244, 9,148,241, 58,196, 39,105, 96,105,105,121,175, 28,203, 87,199,146,141,130, 70,163,249,108,205,218,181, +137, 82,153, 12,173, 59,116,128,179,131, 35,164, 2, 62,104,134, 5, 77,248,200, 77,177, 70,228, 51, 53,150, 28, 63,147,172,214, +104, 62, 43,217, 56,148,228, 44,182, 31, 32, 4, 18, 75, 11, 8,229,114,136,139, 91,173, 8,129,192,194, 18, 2, 11, 75,208, 2, + 97,133,233, 4,128,188,188,188,190,227,198,141,203,200,201,201,193,160, 65,131,112,255,254,253,208, 11, 23, 46, 88, 94,185,114, + 69,242,236,217,179,218, 74,165,178, 83,124,124,252,150,178,196,213,159,238,253,250,117,134, 99,244,125, 55,108,218,150,174, 54, + 56,161,103,175, 13,176, 20,166,193,192, 24, 1,142,131,171,131, 28, 77, 90,124,133,100,109,115,156, 57,125, 38,131,101, 52,125, + 75, 46,153, 83,156,147,227, 56,206,206,206,238, 3,171, 28, 69, 81,184,126,253, 58,250,247,235,139,206,125,122,195,161,166, 7, + 28, 59,118, 67,231, 49, 19,176,101,203, 22, 80, 20, 5, 91, 91,219, 15, 44, 26,101,229,103, 33,178,178,178,224,238,238,142, 7, + 43,186,213, 63, 63,163,158,127,245, 55,191,248, 75, 31,175,170,127,245,234, 85,172, 90,181, 42, 55, 34, 34, 98,181,151,151,215, + 87, 21,229, 39, 33,228,187,159,126,250, 73,253,254,253,123,200,229,114, 48, 12,131, 59,119,238, 96,227,198,141, 88,181,106, 21, + 66, 67, 67, 97,103,103,135,218,181,107,131,162, 40,196,196,196,168, 9, 33,223,149, 83,150,216,156, 28, 94,223, 75,151,142,167, +245,236,217, 26, 59,118,172,135,179,115,115,240,121,206,224,241, 29, 32,147,215,195,246,109,203,208,189, 91, 0, 94,134, 63, 78, +207,205,229,245,189,126,253, 58, 99, 66, 58,245,207,158, 61,195,177, 99,199,176,112,225, 66,102,193,130, 5,200,202,202, 42,178, + 96, 21,174,146, 62,127,254,124, 0,128, 86,171, 21,149,197, 57,102,214,179,248,175, 23, 63, 95,152,148, 24,223,244,198,181,123, +131,175, 94,188,130,232,200,171,184,122,241, 10,110, 93,189, 59, 59, 41, 49,190,169,127,147, 58,130,207,198, 76,254,122,247,177, +163,180,220,210, 5,187,143, 29,165, 7, 77,153,254, 99, 96,231,246,223,153,240,140, 56, 0, 92,110,114,210,183, 63,173,252, 37, +151,209,107,168, 21, 63,111, 80,170, 83, 18,190, 67,225,212,202, 50,172, 87,197, 57,163,162,162,182,188,125,251, 86,241,246,237, + 91,197,251,247,239,191,139,143,143,111,189,100,201,146,148, 2,193,149, 47,176, 94,156,188,247,242,214,206,159, 28,237,109, 36, +205, 27,215,175,187,122,203,145,235, 49,177, 73,191, 21,198,192, 42, 45,157,247,238,221,203,208, 26,152,113, 95,205,154,207,101, +102,234, 80,119,218,108, 48, 34, 57,180, 12,160,103,105,232,193, 67,232,226,213,176,176,179,192, 29, 46,131,211,210,212,216, 55, + 37,156,252, 43, 42,159, 85,129,153,211,204,105,230,252,103,114,254, 43, 45, 88,174,174,174,173,123,125,218, 17,109,123,204, 5, +199,113, 8, 15, 89,142,140,148, 87,112,117, 22, 33, 42, 38,187, 25,128, 27,166, 94, 48, 33, 33, 33,198,197,197,165,233,226,181, +235,142,117, 14,106,226,237,229,234, 34,178,118,175, 1,153,163, 35, 82, 83, 83,112, 63, 56,194,176,233,210,213,231,106,141,198, +164,165,114, 88,150,229, 88,150,133, 64, 32, 0, 71,211,240,153, 58, 27,132,162, 64,241,121, 69,150, 29, 16, 2,203,128, 22, 32, +124, 62, 12, 38,250, 12, 41,149,202, 56, 87, 87,215,190, 83,166, 76,249,125,215,174, 93, 84,219,182,109,253, 78,157, 58,197,254, +149,204, 78,122,118, 60,204,169, 97,159, 54,235,126,217,120,196, 63,176,105, 13,247,154,238,162,230,110, 86,208, 27,140, 72, 74, + 78,195,141,187, 47,180, 17, 97,143,227, 57,189,190,111,114, 88,217, 81,220, 1,192, 96, 48,196,184,185,185, 57, 45, 88,176, 0, + 12,195,128, 97, 24, 24,141, 70,164,166,166,226,222,189,123,104,216, 56, 8,222, 35, 71, 35, 37, 37, 5,235,214,173,131,155,155, + 27,126,250,233, 39,228,228,228,224,230,205,155,101,230, 43,159, 6, 51,120,112, 65, 28, 44, 30,152,213, 61,122, 92,175, 95,191, +126,203,166,134,100,193,188,117,249,150,173,105, 99, 7, 11,174,199, 92, 63, 44, 18,137,182, 68, 71, 71,151,235, 47,228,233,233, + 41,212,104, 52,126, 28,199,209,217,217,217,107, 53, 26,205,136, 25, 51,102,184, 44, 93,186, 20, 94, 94, 94, 72, 77, 77,133, 76, + 38,131,151,151, 23,114,114,114, 16, 29, 29,109,212,235,245,155,141, 70,227,194,164,164,164,148,242,184, 31, 62,124,248,218,223, +223,191,105,114,210,166, 99, 19, 39,116,246, 50, 48,129, 66, 75,203, 86,224, 56, 3, 50, 51,226, 0, 60,213, 31, 63,113,229, 77, +102, 38,253, 89,112,112,112,164, 73, 61, 14,138,154,176,102,205, 26, 20, 46,149, 19, 31, 31, 95,100,250, 43,205,130,101, 10, 86, + 31,142,211, 0,216,191,226,203,230, 95,102,167, 62,245,178,229,189,123,219,180, 1,187,110,245,225, 56,205,130, 47,173, 23,167, +190,187, 17,145,160,186,184,121,247,177,163,244,240, 62,125,141,110,242,200,217, 98, 71,238, 72,251,158, 21, 90,219, 56, 63, 63, +191,106,132,164,215, 74, 78,123, 21, 60,106,204,248, 1, 86, 2,245,185, 70,110,105,158, 84,117,127,113,104,104,232, 91, 83,215, +244, 44, 81,246, 35, 20, 10, 69,235,149, 43, 87, 94, 4,240,129,143, 89,114,106,250,213,102, 61, 38,115,153,153, 89,143,147,195, + 78, 62,171,136, 43, 56, 56,120, 71, 96, 96, 32,134, 13, 29,181,117,236,232,177,116,131,169, 95, 35,254,250, 85,192,104, 64,226, +173, 27,144,200,141, 56,147,250,206,152, 71, 83,227,130,131,131,205, 81,220,205, 48,195,140,127,151,192,138,139,139,187,225,233, +225,118, 41, 34,162,117,167,234,110, 14,249,189,222,183, 74,196, 39,105, 47,153, 58, 60, 88, 82,100, 17, 66, 2,207, 50,204,192, + 75,124,126, 15, 82, 16,138,129,171,194, 98,207,121,121,121, 73, 77,155, 54, 45, 35,246,194, 79,165,238, 53, 26,141,113,166,112, +199,199,199, 95, 87, 40, 20, 67,155, 55,111,190, 84,169, 84, 30, 75, 73, 73, 81,253,213, 12, 79,122,118, 60,140,180,109, 91, 63, +248,193,205, 97,161,193,247,123,112, 28,231, 11,128, 16,138,250, 99,177,231,176,138, 23,123, 86,171,213,227,231,206,157,187,133, +199,227, 85, 71, 65,224,208,194, 44,211,235,245,244,142, 29, 59,196, 58,157,142, 6, 64, 4, 2, 1, 35,151,203, 53,119,238,220, + 97,140, 70, 99,140,193, 96, 24, 95, 22,239,174, 80,142, 95,114,159,143,143,143,236, 53, 15,185,133,191,211,212,128, 82,169, 92, +110,202,253,158, 59,119,206,221,198,198,166, 19, 33,164, 31,199,113,245,114,114,114,180, 63,252,240,195,221,107,215,174,101,191, +122,245,170, 75,171, 86,173,136,179,179, 51,162,163,163,185,220,220,220, 35, 20, 69,125,167, 84, 42,163, 76,205,207,208,208,208, + 40, 66, 72, 35, 85, 30,247,185,133,252, 66,119,150, 67, 35,128, 35,132,144,103,185,185,228,156,139,139,199,111,151, 47, 31, 54, +121, 42, 92,193,218,130,189, 10,127, 7, 4, 4,156,123,245,234, 85,183, 66, 11, 86, 73, 31,172, 74, 65,154,123, 74,163,126,215, +151,200,243,142,175,254, 57, 78, 3, 0,243,214,100,102, 1,216, 62,181,143, 45,251, 50,100,251,114, 87,203,200, 89, 63, 31, 79, + 55,105, 77, 62,127,127,127, 15,138,162, 6, 2,104,224, 40,202,172,237, 32,204, 50, 18,194,181, 35,132,178, 7,240,212,199,199, +231, 12,128,184,170, 36, 85,169, 84, 70, 0,168, 81,114,127,242,139,147,247, 0,220,171, 12, 87,112,112,240,142,102,205,154,157, +220,176,117,243,110,154,144,166,196,104,180, 54, 78, 24,244,199, 98,207, 34,225,240, 96,243, 98,207,102,152, 97,198,191, 81, 96, + 1,192,155,168,184,206, 0,224,229,229,197,189,126,253, 26, 28,199,145,191,114,225, 2, 1,117, 0, 38, 6, 17, 45, 11,207,159, + 63,247,255, 79,102,144, 82,169,220, 15, 96,255,199,228,228,242,135,170,118, 20,108, 85, 66,124,124,252, 51, 0, 65,255,141, 66, + 18, 22, 22,166, 26,225, 79,138, 44, 91,124, 26,140,169,255,237,212,169,211,123,189, 94,127, 5, 64, 44, 33,196, 26, 64,186, 94, +175,191,152,146,146,146,228,236,236, 28,248,254,253,251,239, 11, 44,145,139, 18, 19, 19,131,171, 88,150, 88, 0,251, 10,182,143, +138,144,144,144,238, 10,133, 34,212,206,206,206, 83,163,209, 8, 53, 26,141,160,184,246,151, 72, 36, 41,166,114, 89, 91,144, 93, + 2, 94,134,157,181, 5,249,211,115,183,117,197, 81,181,234,121, 93, 91, 87, 28,173,140,184,244,243,243,219, 75, 81, 84, 77,142, +227,156, 0,206,138,227,144,194,113, 92, 42,143,199,139, 15, 11, 11,139,255,167, 84, 52,247,242, 5, 84, 15,115,149,107,134, 25, +102,152, 5, 86, 25,136,140,140, 36,230,108,251,247,161, 52,203,150, 41, 40,136,112,127,183, 96,251, 0, 5,130,170,231, 63,253, +222,149, 74,229, 71, 17,241, 99,102, 61,139, 7, 48, 61,176,148,121, 22,243,214,165,231, 0,248,186,221,167,149,227,124,252,248, +113, 12,128, 24,115, 9, 53,195, 12, 51,204,248,103,129, 50,103,129, 25,102,152, 97,134, 25,102,152, 97,198,199, 5, 1, 80,234, + 76,128,202,172,148, 93,149,217, 4, 21,241,155, 57,205,156,102, 78, 51,167,153,211,204,105,230,252,255,199,249,175, 65,225,180, +243,255,196, 6,160,163,153,211,204,105,230, 52,115,154, 57,205,156,102, 78, 51,231,191,109, 51, 15, 17,154, 97,134, 25,102,152, + 97,134, 25,102,124,100,148,233,228,238,225, 81,205,135, 50,178, 45, 56,142,162, 57,138, 51,144,108,245,193, 55,233,233, 31, 4, + 1,172, 94,189,186, 53,159, 66, 79,194,113, 50, 66, 88, 35, 75, 83,119,162,162, 98,195, 76,185,176,143,143,143, 0,192, 8, 62, +159,223,210, 96, 48,184,240,120,188, 4,141, 70,115,155,207,231,239, 10, 11, 11,211,255,147, 50,169,101,203,150,131,142, 28, 57, + 98,221,163, 71, 15,173, 94,175,103, 68, 34, 17,111,223,190,125,162,145, 35, 71,102,222,190,125,187, 74, 51, 12,253,252,252,218, +175, 88,177,162, 86,251,246,237,209,178,101, 75, 85,183,110,221, 4,129,129,129,130,175,191,254, 58,250,241,227,199, 87, 43,195, +229,228,228,228,195,227,241,246, 16, 66,104,142,227,134, 21,204, 48,252,143,128, 16, 50, 8, 64,127, 0, 46, 0, 18, 1, 28,226, + 56,110,127, 21,185,186, 32,223,201,221,183, 96,215, 83, 0,167, 57,142,187,240, 23,210,215, 5, 64, 79,154,166,253, 0,192,104, + 52, 62,254, 88,156,124, 62,191, 17, 0, 24, 12,134, 39, 31,139,147, 16,210,168,192,146, 92, 37,206,128,128,128, 31,132, 66,225, + 88, 0,208,233,116, 59,228,114,249,146,210,206,187,113,227,134,174,172,208, 39, 62,181, 8, 23, 54,171, 94,254,247,229,225, 0, +128, 10,127, 71, 87,113, 22,241, 22,111,174, 52, 94,140,127, 89,229,201, 51, 10,133,226,139,110,221,186,125,115,225,194,133, 31, +227,226,226,182, 86,246,255, 71,142, 28,161, 77, 57,239,243, 89,219,123,200,229, 54,223,231,102,103, 45, 61,176,114,212,241,194, +253,253,250,245, 51,194, 12, 51,204, 48,195, 20,129,229,225, 81,205,167, 95,239,207,126,154, 48,126, 34,161,105, 10, 47,195,195, +121,147,166,126,217,201,219,219,219, 85,166,209,120,115, 0,171,150, 72,158,211, 52, 21,191,105,195, 47, 22,117,235,212, 49, 26, +141, 44, 54,111,217,212,213,195,163,218,156,138, 68,150,163,163, 99, 45, 23, 23,151,181, 83,167, 78,117,236,212,169, 19,229,228, +228,132,184,184, 56,203,227,199,143,215,254,245,215, 95,123, 56, 58, 58, 78, 79, 78, 78,142,174,202, 13,185,184,184,180,114,180, + 70, 39,185,152,235,128,108,130, 92, 35,126, 79,214,226, 82, 66, 66,194,173,170,102,146, 78,167,155,146,151,151, 23,228,237,237, +205,109,222,188,153,140, 29, 59,150, 35,132, 16,181, 90,189, 11, 85, 12,225, 32,149, 74, 55,180,111,223,222,171, 69,139, 22, 81, +119,239,222,237,198,113,220,185,126,253,250,121, 72,165,210, 72, 0,117, 42,195, 69,211,244,206,176,176,176, 70, 26,141, 6, 1, + 1, 1,191, 2, 8,248, 15,137,171, 95,237,236,236,216, 77,155, 54,109,105,216,176,161,167, 74,165,202, 27, 51,102, 76,103, 66, + 72,123,142,227, 70, 87,130, 71, 6, 96,157,149,149,149, 96,241,226,197,247,219,182,109, 27, 35, 20, 10,165, 17, 17, 17,220,212, +169, 83, 71, 17, 66,250, 1,152,202,113,156,170,178,156, 10,133,194,114,217,178,101,175,252,253,253,239, 10,133, 66,193,219,183, +111, 49,109,218,180, 9,127,133,179, 94,189,122,210,101,203,150, 61,241,246,246, 78, 19,139,197,130,247,239,223, 99,198,140, 25, + 99,104,154,238,199,178,108,149, 56, 29, 29, 29,101, 75,150, 44,121, 22, 24, 24,152, 41, 22,139, 5,111,222,188,225,190,252,242, +203,177,149, 73,103,155, 54,109, 62,167, 40,106,193,205,155, 55, 1, 0,205,154, 53,251, 65,167,211,205, 45,121, 30,199,113,104, +217,178,165,166, 77,155, 54, 99,111,220,184, 81,106, 88,148,221,162, 89,131, 0,224,235, 31, 10,126, 23,236, 47,237,247,112,237, +242, 74,151,121,159, 90,132, 3,128, 73, 95,109, 28,154,255,153,191,127, 83, 65,232,222, 13,181, 8, 87, 25,209,230,234,234, 58, +190, 73,147, 38,223, 62,120,240, 96,119, 96, 96,224,180,173, 91,183,242,123,244,232,177, 88,161, 80,120,118,233,210,165,223,189, +123,247, 86,132,135,135,111,248,152,229,223,217,185,218,250, 85, 63,111, 85, 76,159, 60,122, 41,128,227,230,230,195, 12, 51,204, +168,180,192,162,140,108,139, 9,227, 39,146,129,131, 62, 79, 76, 72, 74,102,229, 22, 86,131, 14, 29, 62, 44,173, 83,167, 14,165, +249,229, 23, 48, 41, 41, 48,206,156,217,252,198,141, 27,134,201,211,103,170,181,154,188,157, 46, 78,142,210,131,251, 15, 56, 31, + 59,122,164, 5,128,176,242, 44, 87, 46, 46, 46,107,143, 30, 61,234, 92,171, 86, 45,232,116, 58,164,165,165,193, 96, 48,160, 79, +159, 62,116,211,166, 77,157, 71,141, 26,181,214,199,199,231,179,202, 88,178, 28, 28, 28,156,188,170,243,207,204,155,222,181, 78, +251, 54, 1, 50,103,215,154, 64, 28,139,248,232,215,141,175, 60, 8,153,218,210,211, 45, 34, 50, 91,215, 35, 37, 37, 37,169,178, +153,148,150,150, 54,107,252,248,241, 71,125,125,125, 29, 68, 34, 17,156,157,157,201,152, 49, 99,146, 19, 18, 18, 22,252, 5,177, +146,159,215, 20,101, 44,254,105,234,130,212, 37,224,102,101,101, 5, 43, 43, 43, 0,112,253, 43, 5,162,127,255,254,116, 76, 76, +204, 88,150,101,189,139,239, 79, 72, 72,240,112,112,112, 72,122,251,246, 93, 35,181, 78, 31, 56,113,242,156,249, 3,251,117,180, +190,123,247, 46,186,119,239, 78, 17, 66, 6, 85,194,146,181, 46, 40, 40, 40,114,233,210,165,130,200,168,183,245,239, 63,122, 12, +153, 88, 96,116,115,115, 21, 61,125,250, 84,184,108,217,178,164, 31,127,252,113, 29,128, 81,149, 72,250,186,254,253,251,103, 76, +159, 62, 61, 47,226,205,219,154, 15, 66,159,113,114,145,192,224,228,228, 64,223,189,123,151,191, 97,195, 6,242,221,119,223, 85, +154,115,204,152, 49, 9,211,167, 79,231,165,164,101,214, 78, 76, 74,229,132, 2, 90,111,109,109,205,187,124,249, 50,181,115,231, + 78,253,212,169, 83, 43,205,217,189,123,247,164,217,179,103,243,195, 35,163, 60,238,135, 60,131, 92,196, 55, 56, 59, 59,210,247, +239,223,167,215,173, 91,199,204,155, 55,207, 36, 78,142,227, 54,175, 92,185, 18, 39, 79,158, 4, 0,236,223,191, 31, 30, 30, 30, + 31, 12,251,171, 53, 90, 80, 4,120,251,246,173,116,194,132, 9,155, 81, 74,220,185,176, 89,245,176, 27,192,240,225,195, 19, 77, +179, 66, 45,175, 92,161,218,226,205, 21, 10,171,137, 19, 39,150, 21,155,107,168, 79, 37, 68, 86,139, 22, 45,190, 57,120,240,160, +253,225,195,135,191, 58,126,252,120, 97,167, 69,186,126,253,250, 47,122,245,234,133,209,163, 71,127, 3,224,163, 10, 44,161, 64, + 36, 34, 20,129, 68, 44,181, 52, 55, 29,102,152, 97, 70,149, 4, 22,199, 81, 52, 77, 83, 72, 78, 74, 53,124,210,177,211,168,245, + 27, 55,138,132, 66, 33,116, 58, 29, 84, 87,175,130,211,104, 96, 45,149,162, 91,183,110,252, 6, 13, 26, 88,142, 31, 51,102, 76, + 82,162,114, 11, 77, 83,206, 28, 71, 85,100,110, 31, 49,117,234, 84,199, 90,181,106,125,176,211,104, 52, 34, 61, 61, 29, 22, 22, + 22, 24, 48, 96,128,253,222,189,123, 71, 0, 48,201,220,239,228,228,228, 94,199,195,233,206,145,237, 51, 93, 28,173, 41, 32,229, + 8,240,254, 53,176, 79, 12, 47,199,234,240,106,215, 86,214,171, 73, 67,255, 1, 43,118,132, 58, 57, 57,181, 72, 74, 74,122, 87, +153, 76,122,251,246,237,109,133, 66, 49, 70,173, 86,159, 4, 64,221,185,115,135,139,137,137, 25,159,152,152,248,190,170, 25,207, +178, 44, 50, 51, 51,193,178, 44, 93,240,187,240,243,111, 43, 12,253,251,247,167, 99, 99, 99,199,123,123,123,215,222,182,109, 27, +146,147,147, 33,145, 72, 96, 52, 26,209,188,121,243,234, 29, 58,116,120,147,146,150,105, 99, 96, 12,186,132,184, 55, 77, 14,108, +125,151,215,200,203,235,238,161, 67,135, 26,218,217,217, 13, 48,197,154, 71, 8,233, 98, 97, 97,193,251,233,167,159, 40, 11,107, +231,238, 77,130, 20,252,103, 97,175,222, 9, 68, 60, 54, 43, 43, 59,237,201,147, 39,225,243,230,205,107,117,234,212,169, 68, 66, + 72, 23, 83,134,204, 8, 33, 93,156,157,157, 45,166, 77,155,166,146, 88,216,183,108, 28,228,200,123, 30,246, 58,158, 47,160, 12, + 45, 90,180,104,119,239,222,189,157, 51,103,206,244, 61,123,246,108, 86,101, 56,107,215,174, 45,153, 62,125, 58,109,101,109,223, +209,193, 89, 65, 59,216, 90,123, 2, 64, 84, 84,212,222,164,164,164,200,137, 19, 39, 54, 62,123,246,108, 78,101, 56,237,237,237, +165,179,103,207,230,213,244,168,219,215,195,171, 46,117,229,250,131,103, 66, 33,101, 80,171,213,233, 47, 95,190,124,253,205, 55, +223, 4,158, 61,123, 54,219, 20,206,188,188, 60, 11, 87, 87, 87, 56, 57, 57,129, 85,171,145,149,149,133, 99,199,142, 33, 39, 39, + 7, 70,163, 17, 18,137, 4, 63,174,222,130, 55,207,239,227,214,173, 91, 80,171,213, 22, 31,163,156,248, 44, 15, 71,216,120,211, +197,213, 38,118,242,208,114,132, 21,138, 9,175,161,216,226,205,149, 55, 92, 88,204,114, 21,119,248,240, 97, 71, 79, 79, 79,180, +109,219, 22, 0, 48,106,212, 40,116,236,216, 17, 39, 79,158,196,165, 75,151, 98,154, 53,107,246, 58, 54, 54,118, 85,124,124,252, +150,143,113,223, 70,206,168, 7, 0,145, 88, 36, 10, 15, 15, 39,245,234,213,227,204, 77,136, 25,102,152, 81, 22, 74,117,114,231, + 8, 81,189,120,249,146, 47,183,182, 30,186,126,227, 70, 17,159,207,199,251,247,239, 17, 22, 22,134,188,223,127,135,250,238, 93, + 36, 37, 37, 33, 55, 55, 23, 14, 14, 14, 88,178,124,185, 76, 32,145,141,138,124,253,154,230, 40,206, 80,172,135,253,167,169,154, + 66,161,176,101,183,110,221,202,116,174, 79, 76, 76, 68,167, 78,157,120, 60, 30,175,101, 25,189,246, 43, 37, 26, 45,162,112, 32, +167, 15,111,157,230,226,200,123, 6,188,158, 1,228,132, 2,156, 22, 96,116, 64, 76, 56,112, 98, 53, 92,211, 34,201,254, 41, 3, +156, 93, 37,130,211,164,132,153,168,162, 41,165,110,110,110, 30, 30, 30, 30,219,251,245,235, 71, 1, 64,203,150, 45,137,135,135, +199, 86, 55, 55, 55,143,114,172, 11,229,114,106, 52,154,251, 25, 25, 25,232,209,163,135, 93,243,230,205,175,244,232,209,195,174, +112,127, 85, 57, 11, 96,215,190,125,251, 52, 15, 15,143,253,238,238,238, 34, 19,172, 32, 69,156, 49, 49, 49, 99,235,213,171, 87, +123,219,182,109, 52, 77,211,216,182,109, 27, 14, 30, 60,136,219,183,111, 35, 57, 57, 89, 58, 99,198, 12,235, 51, 87,238, 95,184, +115,251,225,169,149,115,191,178,235,211,161,173,135, 77, 86, 74,182,173,173,109, 55, 0,206, 38,166,179,231,220,185,115,111, 60, +126, 25,229, 72,241,248, 2,145,128, 47,113,176,183,174,225,236, 96, 83,219,213,206,166,182,133,144,111,157,157,157, 29,125,226, +196, 9, 6,197,130,144, 86,196,185, 98,197,138,151,225, 81,177,118, 20,205,227,243,105,190,208,218, 74,110,247,105,143, 78,237, + 0, 64, 66, 19, 81,118,118,118,236,222,189,123, 43,197,185,116,233,210,144,132,148, 12, 71,190, 64,200, 19, 9,248,226,194, 3, + 54,150,114, 39,153, 72, 36,201,203,203,123,191,125,251,118, 93, 37, 57,159,188,136,124,111, 79, 40,208, 20, 8,223,198,198,194, +209,193,218,194,217,209, 82,238, 44,166, 32,206,206,206,126,183,127,255,126,189,169,156,201,201,201, 8, 15, 15, 71,181,198,141, +113,229,202, 21, 84,175, 94, 29, 3, 6, 12,192,231,159,127, 14,137, 68,130,246,205, 26, 98,206,156, 57,120,243,230, 77,153,207, +189,208, 31,170, 60, 40, 20,138,235,149, 41, 75, 64,254,176, 96,121,226,170, 36,103,105,231,149,228,108,209,162,197, 55,199,142, + 29,179, 95,179,102,141,223,151, 95,126, 25,117,236,216, 49,248,250,250,226,229,203,151,112,117,117,197,129, 3, 7, 48,121,242, +228,168,249,243,231,251, 93,190,124, 89,161, 80, 40,102,153,250, 30, 13, 27, 54,172,101,255,254,253,111,245,239,223,255,241,192, +129, 3,183,142, 31, 63, 94,241,129, 21, 87, 25, 23,172,211,233,208,200,191,177,116,209,175, 15,134, 84,225,221,172, 20,204,156, +102,206,127, 27,231,191, 66, 96, 25, 88,156,158, 50,109, 70,222,238,221,187,165, 66,161, 16,239,223,191, 71, 98, 98, 34,142, 31, + 61,106, 28,220,176, 97,206, 48, 63,191,236,227, 71,143,114,122,189, 30, 28,199,161,118,237,218,232,214,173,155,100,204,184,137, +201, 36, 91,125,176,130,135,226,232,224,224, 80,180,104,238, 7,166,173, 17, 35,192, 48, 12, 44, 44, 44, 64, 8,113, 52,229, 6, + 92, 92, 92,250,143,250,186,131,155,101, 13,203, 36, 46,113,119, 58,104, 49,192,179, 0,120,150,128,196, 18, 16,203, 0,129, 24, +218, 71,183,211, 57,180,120,215,217,191,191,171,139,139, 75,255,202,100,146,189,189,253,247, 71,142, 28,113,120,250,244, 41,151, +147,147,131,164,164, 36,238,155,111,190,113,176,183,183,255,190,170, 25,175, 84, 42, 23,141, 26, 53, 42,169,111,223,190, 86,187, +119,239,174,214,183,111, 95,171, 81,163, 70, 37, 41,149,202, 69,127,229,129,242,249,124,250,234,213,171,182, 95,125,245,213,231, + 6,131, 33,184, 67,135, 14,105,254,254,254,193,206,206,206, 53, 76,176,170,121, 23,138, 43, 0,160, 40, 10, 66,161, 16, 66,161, + 16, 86, 86, 86,153, 81, 81, 81, 70,119, 39,137, 80,204,228, 26,109,120, 20,191,166,139,179,157,181,179, 75, 91,149, 74,117, 27, + 64,130,137, 73,244,109,219,182,173,152, 97,105,227,196, 17,237,107, 79, 30,217,190,230,182,165, 19,125, 55,252, 52,177,254,202, +133, 19, 90, 45,253, 97,244, 48,194, 48, 57, 53,107,214,244,192, 31,206,239, 21, 89,134, 26,249,250,250,138, 56,240,241,228, 69, + 84,220,219,152,248,236, 46,237, 91,212, 45,186, 96,147,166,159, 59, 58, 58,126,234,225,225,209, 17, 64,103,147, 76,187, 60, 94, +163,134, 13, 27, 74,120,124, 17, 28,237,173, 60, 44,228,178,162,161, 87, 27,123,199,142,206,110,110,163,121, 64,154,139,139,139, + 27,143,199,107,100,106, 58, 3, 3, 3,197, 44, 4,112,118,176,181,117,176,183,177,236,214,161,165, 79,139, 86,205, 27,250, 55, +111,217,206,191, 89,139,145,148,209,152,225,238,238,238, 90,232,252, 94, 17, 78,156, 56,129,117,235,214,161,101,253,250,112,119, +119,135,131,131, 3,126,255,253,119,252,254,251,239,144,203,229,200,204,204,196,166, 77,155,112,241,226,197,191, 92, 89, 20, 10, +162, 34,199,244,143,128,146, 34,171, 34,177,119,251,246,237, 99,135, 15, 31,134,167,167, 39, 70,142, 28,233,177,115,231,206,168, +168,168, 40,200,229,114, 60,121,242, 4, 95,127,253,117,212,252,249,243, 61, 70,140, 24,129, 3, 7, 14, 32, 62, 62,254, 55, 83, +210, 49,112,224,192, 73,126,126,126, 87, 19, 19, 19,155,165,167,167, 55, 56,118,236,216,168, 62,125,250, 68, 15, 26, 52,168, 67, +145, 5,203, 96,216,119,246,212, 81,116,255,244, 51,212,173,223, 96,243,136, 57,123, 27,154,155, 16, 51,204, 48,163,204,118,164, +180,157, 49, 49, 49,153,222,222,222,174,158,158,158,148, 78,167, 67, 86, 86, 22, 46,158, 63,111, 60,112,232,208, 89,157, 78, 55, +149,162, 40,193,174, 61,123, 54, 59,187,184,180,251,172,111, 95, 98, 48, 24,208,177, 99, 71,225,213,171, 87,237,158,198,196,228, +148,119, 65,154,166,139,172, 71, 95,124,241, 5,214,172, 89, 83,216,123,252, 67,224, 25, 12, 38,251, 34, 73,228,108,183, 54, 29, + 27, 88,198,202,126,177,212, 55, 55,228,186,191,177,184, 47,203,149, 4,130, 18,242, 32, 17,131,213,137,153,200,204,142,193,111, +222,214,244,145,104,146,107,182,168, 27,132,131,247,143,119, 3,112,200,212, 76,146, 72, 36, 77,164, 82, 41,194,195,195,211, 3, + 2, 2, 50, 45, 45, 45,173,188,188,188,236, 37, 18, 73,147,170,102,124, 82, 82,210, 91, 87, 87,215,214,159,125,246,217,100,138, +162, 58,178, 44,123, 37, 45, 45,109,125, 82, 82,210, 91, 83,254,239,234,234, 58,145,227,184,121, 0,142, 20,238,211,233,116,160, + 40, 10, 28,199,161,103,207,158, 88,186,116,169,207,149, 43, 87,112,243,230, 77,219,193,131, 7,223, 87, 40, 20,153,132,144,209, +241,241,241,101, 90,201,210,210,210,176,121,243,102,240,120, 60, 88, 91, 91,195,194,194, 2, 98,177, 24,109,219,182, 77, 90,185, +114,165,215,254,253,251, 13,153,201,201, 68,146,147,165, 37,118,118, 98, 40,170,119, 25, 58, 96,224,125, 0,135, 77,189,119,185, + 92, 46, 17, 66,155, 67, 25, 53,212,138,249, 27,120, 82,129,128,136, 5, 60,136,216, 60,122,206,210,197,156,152,112,252,194, 33, + 83, 83, 33, 22,139,133, 50, 33,167,229,139, 40,131,148,226, 62,202, 56, 43,143,199, 19,137,248, 80,151,117, 92, 64, 17,154, 16, + 34, 1,160,173, 76, 58,229, 66, 99,153,231,139, 41,208, 20, 69,137,203,226,236, 95,159,112,135, 39, 23, 10,156, 34,163, 26, 24, +134, 65,147, 38, 77,112,224,228, 53,156,251,253, 46, 82,223, 63,197,212,137,163,224,229,229, 85,161,184, 42,244,193, 50,161, 83, + 0,133, 66,113, 93,249,131, 85,197, 39, 23,248, 93, 85, 52, 52, 88,156,211,103,121,120,185,179, 19,221,220,220,198,249,249,249, + 13, 63,126,252, 56,218,181,107,135, 30, 61,122,160,110,221,186, 30,131, 7, 15, 6, 0,180,110,221, 26,223,127,255,189,199,231, +159,127,142, 19, 39, 78,224,220,185,115, 8, 12, 12,156,166, 80, 40,146,149, 74,229,198,114,196,213,252, 49, 99,198,204, 93,191, +126, 61,248,252,252, 21,161,122,247,238, 93, 88, 63,238,232,223,191,127, 90,225,185,135,183,199,221,173,229,225,213,124,210,212, +175,132,147, 39, 12,155, 13,224,115,115, 51, 98,134, 25,102,152, 44,176, 0, 64,164,215,215,213,110,222, 12,213,149, 43, 16, 94, +186,132, 51,141, 26,229, 50, 12, 51, 83,169, 84,198, 2,128,147,147,211,244, 67,135, 15,223,233,248,251,239,150,186,240,112,184, + 61,123, 6, 94,157, 58,126,166, 94,120,201,146, 37, 69,162, 0, 0,246,236,217,131,172,172, 44,100,101,101,129, 97, 76, 94, 75, + 24,124, 33, 90, 58,218, 85, 71, 2, 34,193,242, 40,249,187,186,121, 77,229, 26, 11,165,107,140,147, 42, 75, 80, 7,225,113,245, +101,234, 76,109, 83, 66,235,160, 73,205,131, 91, 75, 47,240, 80,250,240, 99,153,102, 62,138, 42,108, 28,211, 67, 66, 66,122,182, +108,217,242, 52, 0,251,194,253, 85, 69,124,124,252,107, 0, 83,171,242, 95,154,166,231,221,186,117,203,241,208,161, 67,147,127, +254,249,103,174,184,192, 42,252,206,227,241,192,113, 28,100, 50, 25,120, 60,158,211,137, 19, 39,156, 62,253,244,211, 13, 0,202, +124, 78, 82,169, 20,142,142,142, 16, 10,133,176,176,176,128, 42, 59, 67,182,233,167,185,109,165, 54, 78,182, 83,167,205,164,198, +141, 27, 23,182,118,237,218,106,206,117,235,122, 63,127,254,252,109,159,129,159,223, 61,121,242,164,186, 18, 14,238, 79,195,195, +195,105, 47, 79,119, 1,107, 80,179, 50, 1, 32,126,242, 51, 43,180,112,134,152,166,193, 35,224, 36, 82,153, 99,108, 66, 66,140, +169, 86, 49,142,227,158,188,123,247,142,184, 41,156,120, 57, 42, 77,166,140,199, 10,163, 31, 61,124, 89,171,113, 19,111, 0,208, + 60,186,123, 92, 84,183,190,133, 50, 59, 71,226,234,234, 26,101, 10, 39,195, 48, 79,226,226,226,136,173,173, 45, 63, 50,242,245, +111,118,150, 22, 10, 91, 39,167,182, 0,160, 75, 79,185, 73,212, 26, 37,159,207,119, 77, 73, 75, 75, 96, 24, 38,198,212,116, 70, + 71, 71, 19, 55,133, 19,239,244,217,115, 7,156,101, 82, 23,107,137,200, 74, 76,129,136, 57, 54, 75,200, 48,137, 18,169, 76, 17, + 23, 31,159,196,113, 92,153,126,130,155,216,201, 67,243,191,253,186,183,132,117, 7,215,130,163, 97, 69, 27,193, 55,168,112,255, +216, 33,124, 54,229, 75,147,222,167, 21, 11, 71,236, 95,177,112, 68,153,225, 25, 74, 8, 34, 40,199,255,197,154,103,139,247,245, + 63,113, 42,203,119,112,239,210,165,203,119, 91,183,110,149, 22,254,126,249,242, 37, 90,182,204,127,149, 23, 44, 88,128,206,157, + 59,163, 81,163, 70,120,249,242, 37,106,212,168,129, 99,199,142,129,166,105,254,184,113,227,190, 1,176,177, 28,203,109,207, 45, + 91, 62,116,211,210,235,245, 96, 24, 6, 6,131,193,133, 97, 24,151,194, 78,223,207, 63,175, 75,189,116,241, 12,190,153,179, 0, +142, 14,206,126,230, 38,196, 12, 51,204, 40, 83, 59,148, 89,233,112, 28,203,164,167,131,211,230,119,164, 5, 2, 1,199,113, 92, + 81,229,198,231,243,165, 86, 86, 86,132,239,230, 6, 34, 42,112,245, 33,228, 47,199,131,225,241,120, 48, 26, 77,167, 49, 26, 65, +131,232,193,225, 15,127, 83,149,152,224, 71,251, 14,152, 42,251, 18,137, 66,171,226, 45, 28, 56,134,133, 17,149,179,142, 16, 66, + 56,149, 74, 5,173, 86,107,227,233,233,121, 86,163,209,216, 20, 52,152,127,155,147, 43,195, 48, 81, 60, 30, 15, 35, 70,140, 0, +242,151, 60,130, 78,167,195,227,199,143,161,213,106,161,211,233,112,231,206, 29,100,101,101, 65,167,211,225,242,229,203,168, 81, +163, 6,120, 60,158, 75,121,188, 44,203,194,193,193, 1, 78, 78, 78,208,170,178,101, 71,183,174,237,190,124,254,183,246,131, 60, + 57,234,215,117,171, 88, 79, 79,207,140, 6, 13, 26,216, 74, 36,146,140,128,128,128,204, 19, 39, 78,156,170, 76,136, 6, 0,167, +103,207,158,237, 27, 20, 20,228,110, 45,151,233, 69, 66, 26, 34, 70,197,137,180,105, 28, 79,157,202,213,112,115,215, 67, 38,111, +210,183,111, 95, 35,128,211,166,114, 78,157, 58,181,186,183,183,183,189,181,165, 44,155, 71, 33, 94, 96, 52,198,103, 4,223,189, + 12, 0, 2,123, 71, 53,100,242, 38,131, 7, 15, 54, 84,134,115,230,204,153,158,174,174,174,118, 20, 69, 50, 25,189,254,125, 81, +121,208,168,147,104,145, 88, 5,145,184,213,232,209,163,153, 74,166,211,195,215,215,215,206,198,202, 50,147, 79,145, 24,129,145, +137,149,112,198, 56,161, 65,159, 34,114,116,202,133, 76,222, 98,208,160, 65,101,166,179,208,122, 85,210, 50,196,227,241, 16, 31, + 31,143, 60,229, 83, 8,226,195,209, 72,206, 71, 83,103,123,200,100,178,138, 5,214,248,151, 36, 44,154, 35, 97,209, 28,193,248, +151,164,180,223,165,136,172,114,203,126,185, 67,125, 91,188,175, 87,133,243,220,185,115,203,122,245,234,101, 24, 56,112, 32, 46, + 95,190, 12, 66, 8,110,223,190,141,248,248,120,116,238,220, 25, 28,199,225,241,227,199, 69,226,171, 95,191,126,232,209,163, 71, +222,133, 11, 23,126, 52,181,112,110,221,186, 21, 12,195,128,207,231, 67, 34,145,192,210,210, 18,182,182,182,112,114,114,122,227, +232,232,248,124,201,230, 19,175, 59,117,238,129,244,180, 84, 36,167, 36, 62, 54, 55, 33,102,152, 97, 70,165, 5,150, 65, 36,122, +193, 78,153, 2,235, 83,167,192,143,140, 68,191,207, 62,179, 20,137, 68,235, 92, 92, 92, 2, 20, 10, 69, 11,137, 68,178, 97,230, +140, 25, 22,246, 75,150, 64,113,243, 38, 18,175, 92,129,129,207,127, 84,153,139,171,213,234, 66, 1, 3,109,129,144,179,182,182, +174,148,192, 98, 25,220, 75, 72,137,132, 16,238, 96,193,229, 94,200,110,253, 96, 80,212, 92,199, 51,217,181,188, 94,171, 4, 94, + 11, 29,154, 58,174,171,209,242,129,138,240,114,133,214, 98, 40,227,149, 48,130,189, 87,153,116,106, 52,154, 44,149, 74,133,218, +181,107,219,133,132,132,120,122,121,121,217, 22, 8,154,135,127, 37,243, 21, 10, 69, 51,127,127,255,195, 1, 1, 1,111,253,253, +253, 15, 43, 20,138,102,149,248,251,175,143, 30, 61, 2, 77,211, 24, 55,110, 28,114,114,114,160,215,235,145,150,150,134,152,152, + 24,232,116, 58,196,197,197,225,213,171, 87,208,233,116,120,247,238, 93, 81, 30,151, 7,131,193, 0, 11, 11, 11,100,166, 37,203, + 14,110, 90,213,125,241,252,239, 36, 89,111, 66, 16,167, 76, 2,107, 84, 43,191,255,254,251, 40, 79, 79,207,219, 90,173,182, 30, +195, 48,221, 56,142, 59, 88, 9,161, 74, 1,120,236,229,229,213,105,229,202,149, 45,191, 95,186, 93,100, 65,231,112, 66, 11, 17, + 43,180, 16,114,194,122, 77, 49,102,222,122,241,234,213, 43,238, 5, 7, 7,103,153, 56, 51,143, 2,240, 56, 32, 32,160, 89, 98, + 98, 98,203, 70,141, 26,249, 57,215,174, 35, 22,185, 42, 82,133,138, 26,105,156, 58,239, 10, 85,189,102,207,157, 59,119,222,186, +121,243,102, 82,101, 56,157,156,156, 90,110,222,188,217,191,122,245,234,141,197, 86, 86,146,220,204,204,173,218,204,244,237,124, +123,103, 9,101,103,223,255,232,209,163,191,159, 61,123, 54,173, 50,156,117,235,214,109,177,100,201,146, 70,254,254,254, 1, 46, +117,234,138, 37,174,110, 41, 2,215, 26,201, 18,223, 64, 49, 85,195,163,223,246,237,219,175,221,185,115, 39,213,212,128,163, 20, + 69,129,207,231, 67, 38,147,225,198,141, 27, 24,244, 89, 23, 56, 59, 90,162, 78,221,186,104, 59,126, 10,206,158, 61, 11,161, 80, +136,191,106,109, 45, 9, 83, 4, 81,101,197, 87, 69,156, 74,165,114, 99,112,112,240,207, 3, 6, 12, 64,199,142, 29,241,228,201, + 19,204,154, 53, 43,234,236,217,179, 0,128, 39, 79,158, 96,241,226,197, 81,247,238,221,195,200,145, 35,209,178,101, 75, 60,126, +252,120,119,101,130,143,142, 26, 53, 10, 6,131, 1,185,185,185, 72, 79, 79,199,153, 51,103,208,168, 81, 35, 78, 42,149,126, 70, + 87,235,244, 99,255, 49,115,154, 55,240,245,195,134,117, 43,117, 66, 30,127,169,185, 9, 49,195, 12, 51, 42, 37,176, 60,109,109, + 45, 52,154,188,184,155, 55,111,234, 41,138,130, 84, 42, 69,255,129, 3,169,159,126,250,169, 85,239, 70,141,174, 14,110,214,236, +252,161,131, 7,253,253,252,253,243,215,219,161, 40,156, 60,121, 82,157,149,149,153, 86,189,122,117,107, 83, 47,158,146,146, 82, +212,251, 86,171,213,224, 56, 14, 22, 22, 22,149, 18, 88,234, 92,234,202,173, 27, 97, 25,156,241,139,152,110,175,215,232,151, 38, +246, 14,202,100,141,188, 44,163, 1, 89,106, 14, 57, 26,240, 30, 80,182, 65, 35,188,250,232,163, 59, 6,189,122,240, 54, 52, 77, +199,233, 42, 53,251, 33, 35, 35,227,187,137, 19, 39,166, 57, 57, 57, 17, 11, 11, 11, 56, 57, 57, 81, 99,198,140, 73,141,141,141, + 93, 88,213,140,247,241,241,249,188, 89,179,102,167, 67, 67, 67,251, 29, 58,116,200,253,240,225,195,253,154, 53,107,118,218,199, +199,199, 84,159,142, 67,203,150, 45, 83, 9,133, 66, 52,109,218, 20, 57, 57, 57,208,233,116, 21,110, 21, 10, 86,150,133, 88, 44, +198,225,237,107, 59, 45,158,255,157, 36, 61,252, 1,158,222,190,140, 11,111,181,121,243,150,254,124, 95, 44, 22, 87,233,126,189, + 28,101, 13, 27, 42, 44, 94,126, 57,106,160,114,246, 55,223, 88, 61,123,246, 76, 58,227,203,233,156, 50, 37,147, 19,119, 95, 77, + 83,109,191,167, 94,104,236, 73,175, 30,237,241,227,130, 89,157, 96,194,208,169,143,163,172, 97, 3,133, 69,216, 87,227, 6, 69, + 77,157, 58, 85,186,108,217,178,188,150, 45, 91,102,102,101,101, 73,172,156, 92,252, 69,142, 78, 65,202,140, 76, 89,243, 22, 45, + 30,143, 26, 53, 74, 85, 89,206,239,191,255, 94,118,235,214, 45, 81,151, 46, 93,114,178,179,179,101, 98,185, 60, 72, 96,105,221, + 58, 37, 43,203,178,107,215,174,161, 3, 6, 12, 48, 84,133,243,213,171, 87,162,230,205,155,231,100,101,101,201, 44,157, 92,154, +136, 29,157, 91,197,167,103, 88, 52,109,214, 44,116,236,216,177,186,242, 56,251,175,255, 67,156, 72,165,210,116,111,111,111,204, +157, 59, 23, 11, 22, 44, 64,255,254,253, 17,253, 54, 26,109, 70,142, 67,173, 17, 19,112,250,222, 3,196,199,199, 99,206,156, 57, +240,242,242, 2, 69, 81, 9, 31,179,242, 40, 79, 16,149,229, 8,239, 83,139, 92, 47,207,207,170, 34,145,213,169, 83,167,145,189, +122,245,194,201,147, 39, 49,107,214,172,168,249,243,231,123, 12, 25,146, 63,161,207,207,207, 15, 51,103,206,244, 88,185,114,101, +212,234,213,171,209,172, 89, 51,184,185,185,125, 90, 9,171, 48,118,236,216, 1,134, 97, 32,151,203, 97,107,107,139, 30, 61,122, +224,249,243,231, 19,118,238,220, 25, 78,243,249,131,187,127,218, 23,103, 79, 29,195,171, 23,207, 39,236,250,105,232, 51,115, 19, + 98,134, 25,102,148,133,210,227, 96, 89, 74, 6,110,221,184,193,106,242,244,153, 42,111,111,111, 27,103,103,103, 16, 66,208,165, + 75, 23,210,236,194, 5, 11,190, 66, 1,187,134, 13,139, 22, 52,188,117,243, 38,174, 94,189,170,218,187,227, 87,215, 81, 99,198, +244, 4,202,246,153, 45, 62,172,150,150,150, 6,103,103,231,162,217,106, 74,165, 18,206,206,206, 16, 8, 4,160,105,154, 87,176, +244, 75,185,106,203,217,217,121,207,210,197, 47,102,199,249,206,172, 21, 36,165,200,121, 85, 34,140, 28, 7, 62, 49, 2,106, 14, + 6, 35,160, 53,112, 8,172, 73,219,254,174,131,205,131, 23,151,162,157,157,157,247, 84, 38,147,162,162,162,174,185,184,184,140, +207,203,203, 59, 2,128,186,127,255, 62,251,246,237,219, 73,166, 58,164,151, 6,137, 68, 50,235,200,145, 35,182, 11, 23, 46,204, +184,122,245,106, 86,251,246,237,173,150, 46, 93,106,251,249,231,159,207, 66, 41,193, 32, 75,105,136,212, 10,133, 98,119, 66, 66, +194,164,198,141, 27, 35, 61, 61, 29,122,189, 30, 33, 33, 33,240,242,242, 66,112,112, 48,234,212,169,131, 71,143, 30,161,110,221, +186, 48, 26,141,208,104, 52, 48,154,160, 94,149,177,239,229, 82,109,134,165,242,193,121, 68, 60, 11,193,185, 40,109,222,138, 29, + 7,207, 53,244, 11, 84, 21,206, 48,172, 12,234, 58,201,234,187, 58,218, 93, 90,186,224, 7,199,119,215, 14,226,216,142,245,236, +181,115,231, 26, 72, 44, 49,188,197,192,105,159,235, 13,112, 7,129,168,117,139,230,232,105, 27, 97, 20, 84, 67,210,239, 47,202, +143,100, 94,215, 73, 86, 95,225, 96,119,113,197,146,133, 22,111, 46,236,194,161, 45,171,185, 35,123,246,251,107,128,250,158,158, +158, 61,105,154,118, 2,160, 54, 26,141,111, 96,226, 18, 52,165,113,254,126,230, 76,128, 6,168,239,230,230,214,147,207,231, 87, + 3,160, 53, 24, 12,239, 63, 6,103,237,218,181,123, 18, 66, 92, 1,104, 10,124,174, 42,181, 84, 78,199,142, 29, 87,108,223,190, +125,134, 86,171,181, 45,102,109, 37, 39, 79,158,132, 94,175, 39, 2,129,128,149,201,100,136,137,137,225, 0, 36,112, 28, 55,225, + 99, 85, 28,125,251,246,197,253,251,247, 23, 0,152, 87,222,121,233,233,233, 60, 91, 91, 91,166, 34,225,101, 42,231,131, 7, 15, +150,141, 29, 59,246,235, 11, 23, 46,196,205,159, 63,223,111,196,136, 17, 56,113,226, 4,170, 87,175,142, 87,175, 94, 97,198,140, + 25, 32,132,120,172, 92,185,242,241,129, 3, 7, 92, 18, 19, 19, 87,153,114, 63, 70,163, 17, 12,195, 96,208,160, 65, 48, 24, 12, + 72, 73, 73, 65, 68, 68, 4,110,221,186,133, 9, 19, 38,136, 1,192, 69,225, 22, 40, 20, 10,241, 36,244, 81,222,247,163,131,126, + 51, 55, 31,102,152, 97, 70,165, 45, 88,132, 37,124,175,218,181,141,186,188,220,157, 99, 70,142,204,123,241,226, 69, 81, 5,164, +121,248, 16,170, 11, 23, 96, 52, 26,193,113, 28, 30,220,191,143,169, 83,166,228,106,242,114,183,215,172,233,206, 17,142,147, 21, +241, 16,210,177, 36,183,174,152, 25, 69,173, 86, 67,173, 86,131,199,227,193,194,194, 2,201,201,201, 16, 10,133,144, 72, 36,104, +212,168, 17,229,230,230,214,227, 79,105, 43,193, 25, 18, 18, 98, 64,182,182,223,201, 17,211, 18,220,242, 24,110,188,117, 77,212, + 16, 72,138,102, 33, 58, 91, 18,124,218,136, 15, 39, 65, 42,247,116,215, 32, 37, 97,178,250,133,132,132, 24,202,227, 44, 9,133, + 66, 81,199,199,199,103, 99,223,190,125, 41, 0,104,213,170, 21, 85,191,126,253, 95, 20, 10, 69,153, 75,218, 84,196, 41, 22,139, + 69, 0,112,229,202,149,244, 91,183,110,117,185,114,229, 74,122,241,253,166,112, 82, 20,181,117,211,166, 77,144, 74,165, 96, 24, + 6, 58,157,174,200,255,170,248,167, 94,175,135,189,189, 61,126,255,253,119,176, 44,123,182,162,116,122, 55,240,205,205,226, 89, + 39,237, 62,125, 21,231,223,233,115, 43, 43,174,138,115,214,118,145,215,117,182,183,187,188,226,167, 69, 14, 25,175, 67, 16, 23, + 23,199, 93,188,112,246,158,154,227,226,211,178,184, 31,211,115, 56,159, 92, 13, 39, 13,172,137,216,179,191,204,224,190,106, 6, + 6, 4, 92,121,156,245, 93,228,117, 93, 29,236, 46,174, 90,241,147, 69,230,235, 16, 36, 36, 38,226,220,217,211,143,213, 28, 23, +207,113,220, 5,142,227, 38, 50, 12,211,132, 97,152, 38, 28,199, 77, 44, 75,180, 84,150, 83,175,215, 7,233,245,250,160,143,201, +201,178,108, 16,203,178, 38,115,254, 49,131, 16,152, 59,119,238,195,155, 55,111, 14,120,248,240, 97,135,194,237,249,243,231,237, +163,163,163,219,199,197,197,181,139,158, 37,162,159, 61,123,198,123,244,232, 17,255,209,163, 71,213,131,131,131, 47,152, 90, 62, +203,121, 23,138,139,252,249, 74,165,146,148,202, 57,254, 37,217,176,242,139,189,135, 15, 31,118,250,104,156, 0,194,195,195, 55, +108,223,190,189,134,171,171,171,203,231,159,127,142, 93,187,118, 97,251,246,237, 0,242, 35,217, 23,179, 92, 57, 6, 7, 7,215, + 42, 45,200,104,105,247,110, 48, 24,192, 48, 12,246,239,223, 15,134, 97,224,224,224, 0, 31, 31, 31, 76,154, 52,233,218,152, 49, + 99, 54, 2, 0, 77,104, 1, 0,104, 53, 90,109,201, 32,163, 85,205, 79, 83,223, 35, 51,167,153,243,223,192,249,239, 16, 88,132, + 53, 26,141, 44, 28,157, 28, 45, 82,146,147,215, 79,156, 56, 33,109,225,194,133,154, 27, 55,110, 64, 23, 30, 14, 77,104, 40, 46, + 95,190,140,105,211,166,229,141, 27, 63, 62, 65,147,151,187,214,217,201,209,222,104,100, 65, 8, 91,174,133,132,162,168,168,200, +200,200,194,222, 54,214,175, 95,207,232,245,122, 88, 88,228, 7,153,222,182,109, 27,203,113, 28, 58,116,232, 32,227,243,249, 38, + 45, 65, 18, 31, 31,255, 52, 59, 70,217,249,232,192, 9,111, 94, 30, 60,149,225,155,166,199, 16,137, 2, 3, 3, 0, 31,139, 24, +196, 63,248, 53,227,238,198,222,111,242,210, 99,187,196,199,199, 63,173,108, 38, 57, 57, 57,205,219,183,111,159, 99, 72, 72, 8, +167,213,106, 17, 31, 31,207,205,154, 53,203,209,201,201,105, 94, 85, 51,158,227, 56,146,153,153, 9, 66, 8, 91, 80, 88,217,194, +253,166,114,196,197,197, 61, 63,124,248,240,201,107,215,174,193,205,205,173, 72,100,149, 20, 88, 60, 30, 15,132, 16,108,218,180, + 41,147, 16,242,109, 69,188, 34,145, 8,219,142, 92, 56,255,213,166, 99,135, 14, 93,121,120,172,170,150, 43, 0, 16, 82,212,252, +101,139,126,112, 76,125,121,159, 60,191,119,149, 61,248, 36, 33,137, 49,114,147, 75, 61, 57, 71,201, 21, 20,202,242,125,123, 40, +122,254,178,159, 22, 90, 21, 14, 95,238, 11, 81,102, 19, 35, 55,229,175,189, 9,255, 35,156,127, 35,242,103,250, 41,137, 66,161, +192,209,163, 71, 43,237,131,229, 83,139,252,201,185,189,170,156, 74,165,114,249, 39,159,124,162,156, 63,127,254, 70,141, 70,163, + 42,232,188,233, 87,173, 90,181,114,242,228,201, 73,241,241,241,171, 76,126, 76, 20,181,167, 83,167, 78,220,205,155, 55,209,187, +119,111, 24, 12, 6,196,198,198, 98,219,182,109, 96, 24, 38,187, 67,135, 14, 44, 0,168, 53,121,217, 28,203, 65,167,215,106, 97, +134, 25,102,152, 81, 1, 74, 29, 34,100,105,234,206,230, 45,155,186, 30,220,127,192,153,166, 41,231,232,232,183,143,134,141, 30, + 29,127,243,230, 77, 91,126,237,218, 77, 40,138, 98,117,179,103,223,203,205,206, 74,223,179,115, 71,141,154, 53,221, 27, 21, 44, +246,204,177, 52,117,167,188, 11,166,167,167,239,154, 62,125,122,147,221,187,119, 11,150, 47, 95,174,138,143,143,191,116,255,254, +253,174, 27, 55,110, 20,111,219,182, 45, 47, 39, 39,231,212,185,115,231,122,181,107,215,142,209,233,116,121,166,222, 72, 82, 82, + 82, 24, 33,196,155, 90,181,125,240,171, 77,251, 62,225,104,210, 2, 90, 1, 8,199,220,161, 24,213,229, 36,165,114, 31,199,113, + 76, 85, 50, 73, 34,145, 52,146, 72, 36,120,253,250,117, 70,147, 38, 77,116, 66,161, 80,224,238,238,110, 39,145, 72, 26, 85, 53, +227, 57,142,227, 50, 50, 50,192,113, 28, 15, 0, 97, 89,150, 87,176,191, 82, 49,156, 4, 2,193,231,163, 70,141, 58,185,113,227, +198, 78, 29, 59,118,132,135,135, 7, 12, 6, 3,234,212,169, 3,157, 78, 7, 47, 47, 47,104,181, 90,172, 93,187, 22,185,185,185, + 51,226,227,227, 51, 42,226, 20,139,197, 16, 10,133,168,235,221, 32, 79, 44, 22,163,170,226, 10, 0,100,124,202,227,213,153, 29, + 72, 78, 75,101, 15, 61, 73, 74,202,211, 27, 59, 71, 38,171, 94,148, 60, 47,207, 8, 85,187,145, 83,227, 1, 64,203, 34,183, 92, + 78, 33, 60, 34,206,110, 67, 82,114, 42, 14,134, 38,100,170,244,108,151, 87,165,112, 86, 42,157,255, 35,156,253,215,135,163,237, + 23,166,159,123,120,252,199,169, 40,138, 91,149, 76, 69, 88, 52, 71,176,197,155,195,150,245,165,198,184,170, 10,103,177, 78,213, + 22, 0, 91, 0,192,205,205,237,205,212,169, 83,191,142,143,143, 95, 83, 16,239,170, 82, 29,159,131, 7, 15,174, 29, 53,106,212, +133,158, 61,123,126,195,178,172,111,177, 30,122,180,163,163, 99, 81, 14,166, 36, 37,206, 30, 63,122,208,236,220,220,140, 69, 48, +195, 12, 51,204,168,138,192,138,138,138, 13,243,240,168, 54,231,216,209, 35, 45, 56,142,162, 57, 66, 84, 0,117,250,197,139, 23, +153,197,207,243,180,181,181, 24, 53,118,212, 64,194, 18, 62, 33,172,145,165,169, 59, 81, 81,177, 97, 21, 84,140,207,134, 15, 31, +190,190, 93,187,118,163,141, 70,227,242,200,200,200, 75,117,235,214,125,220,165, 75,151,175, 24,134, 89,249,230,205,155, 75,245, +234,213,187,124,240,224,193, 89, 70,163,241,135, 74,138, 22, 6,249,254, 95,187, 63,102, 38, 81, 20,181,144,227, 56, 43,137, 68, +146, 21, 28, 28,188,191,117,235,214,131, 56,142,179,162, 40, 42,171,170,156, 58,157,110, 74, 78, 78,142,253,231,159,127,110, 32, +132,212,237,211,167,207,236,200,200, 72,190, 74,165,138,170, 12,207,187,119,239,180,238,238,238,189,190,248,226,139,237, 2,129, +160, 3,242, 67, 54,112,197,242, 4, 28,199,193,104, 52,158, 82, 42,149,229,230, 11,159,207,207,237,218,181,171,188, 66,171,148, + 80,152,107,106,250,114,116,198,233,155,174,190, 88,162, 49,112, 28,195,114,227, 95, 37,169, 74,157, 66,246,240, 21, 87,223,100, + 78, 13, 59,125,221,197,176, 37, 90, 3,203, 50, 44, 55,161, 44,206,202,224,127,133, 19, 0, 38, 82,235,247, 98,203,250, 34,135, +247,194, 97,195,146,191,255, 83, 40,176, 56,113, 0, 42, 94,236,188,192, 98, 85,209,218,133,149,226, 44,129,130, 89,130, 91,255, +202, 61,237,216,177, 35, 18, 21, 44,176,125, 96,229,168,227, 0,142,155,155, 13, 51,204, 48,195, 84, 81,242, 31,219, 0,116, 52, +115,154, 57,205,156,102, 78, 51,167,153,211,204,105,230,252,183,109,148, 89, 98,154, 97,134, 25,102,152, 97,134, 25,102,124, 92, + 16, 0, 29,203,176,108,153, 28, 43,170, 42,179, 9, 42,226, 55,115,154, 57,205,156,102, 78, 51,167,153,211,204,249,255,143,243, + 95, 3,243, 16,161,153,211,204,105,230, 52,115,154, 57,205,156,102, 78,243, 16,161,121,136,208, 12, 51,204, 48,195, 12, 51,204, + 48,227, 31, 13,179,192,170, 2, 8, 33,195, 8, 33, 23, 8, 33,207, 9, 33, 23, 9, 33,195,254, 2,151,132, 16, 50,187, 24,223, +121, 66,200, 44, 66,136,200,156,211,255,232, 50, 64,155,115,193,140,170,162, 32,120,113, 72,121,193,138,205, 48,195,140,255,109, +240,202, 58,224,233,233,121,151,162,168, 90,133,139,196, 22, 70, 70, 47,252, 94,242, 55, 0,112, 28, 23, 29, 22, 22,214,188, 44, +206, 90,181,106, 21,113, 22,110,132, 16, 24, 12, 6, 11,154,166,115, 74,227, 52, 26,141,113,175, 94,189, 10,252, 7, 53,172,123, +109,109,109,217,205,155, 55,111,240,245,245,173,157,147,147,147, 55,118,236,216,110,132,144,142, 28,199, 13,173, 36, 87, 3, 66, +200,158,198,141, 27, 31,155, 60,121,242, 97, 31, 31, 31, 75,181, 90, 45,220,191,127,191,243,230,205,155,111, 17, 66, 70,113, 28, + 23,102, 46,166,255, 28,184,184,184,248, 19, 66,214,123,121,121, 5, 42, 20,138, 71, 0, 38, 41,149,202, 39,230,156,249,175,190, +131, 99,132, 66, 97, 23, 47, 47,175, 38, 90,173, 54, 35, 58, 58,250,161,209,104,252,129,227,184,196,143,196,111, 5,224, 7,145, + 72, 20,228,233,233, 89, 45, 50, 50, 50, 86,175,215, 63, 0,176,144,227,184,172,143, 33,174,130,130,130,110,255,244,211, 79,118, +223,126,251,237,109,133, 66,209, 82,169, 84, 70,152,159,172, 25,127, 7,170, 87,175,110,173, 82,169,182,243,120, 60,127,145, 72, +228, 44,151,203, 33,151,203, 19, 69, 34,209, 99,169, 84, 58,250,236,217,179,153,230, 92,250,200, 2,139,166,105,183,135, 15, 31, + 58, 22, 46,190,204,178, 44, 88,150, 5,199,113, 69,159,133, 40,136,179,132,118,237,218,233,203,189, 24,143, 87, 45, 36, 36,196, + 81, 46,255, 35,212,146, 94,175,135,175,175, 47, 27, 26, 26,234, 88,114, 33, 97,157, 78,135,128,128, 0,238,159,146, 89,132,144, + 33,118,118,118,170,247,239, 99, 90,107,180,250,160,177, 83,190,157, 51,164,223, 39, 54,119,238,220, 65,207,158, 61,105, 66,200, + 48,142,227,246,152,200, 37, 33,132,252, 58,103,206,156,101,124,161,212,241,232,217,219,244,218,173,123,223,251,213,169, 73,166, + 78,157, 36,159, 60,121,242, 35, 31, 31,159, 29,132,144, 86, 28,199,153, 35, 71,255, 51,158, 63,175, 90,181,106, 39,151, 44, 89, +226,154,152,144,128,213,107,214, 52, 5,176, 17, 64, 83,115,238,252,215,158,193,236, 5, 11, 22, 44, 25, 60,120, 48,140, 70, 35, +212,106,181,226,245,235,215,245,231,206,157,219,135, 16,210,132,227,184,168,191,200,239,224,229,229, 21, 62,125,250,116,219, 38, + 77,154,128,162, 40,100,101,101, 41,110,221,186,213,244,215, 95,127, 29, 70, 8,169,199,113, 92,202, 95,185,134,141,141,205,111, + 43, 87,174,180, 19,137, 68,216,185,115,167,221,128, 1, 3,110, 41, 20,138, 86, 85, 21, 89,132, 16,202,206,206,110, 42,128,246, + 44,203, 10, 1, 60,200,200,200, 88,204,113,156,222, 92, 98,204, 40, 15,246,246,246, 99,114,114,114, 54, 72,165, 82,129,165,165, + 37,164, 82, 41,248,124, 62,132, 66, 97,117, 27, 27,155,234,114,185,188,219,160, 65,131, 38,237,223,191,127,187, 57,183, 62,162, +192,162, 40, 10, 18,137, 4,135, 14, 29, 2, 77,211,224,243,249,224,243,249, 16, 8, 4,165,126,175, 94,189,186, 41, 21, 1, 0, +224,244,233,211,176,180,180,132,149,149, 21,234,213,171, 7, 66, 8, 68, 34, 17,126,255,253,119,240,249,124,240,120, 60,240,249, +124, 4, 6, 6,126, 96, 41,251,111,160,127,125,194, 1,165, 7,111,236, 94, 95,142,158, 83,126,234,155,167,209,119, 0,160,202, +204,200,200,120,116,236,152,210,175, 78, 29,193,161, 67,135, 26,217,218,218, 14, 2, 96,234, 66,210,211,154, 54,109,122,138, 19, +200,156,134,143, 24, 57,124, 52,143,210, 15, 27,255,213,143,177, 9,169,170,113,227,198, 29, 59,117,234,212,240,117,235,214, 69, + 78,154, 52,105, 42,128,229,166,166,223,221,221,253, 46, 77,211,133,150, 71,229,235,215,175,253,255, 33, 13,163, 2,192, 10, 0, + 6, 0,203, 56,142, 11, 47,118,172,142, 64, 32, 88,174,215,235,211, 1,204,227, 56, 46,246,159,248,178,184,186,186,214, 27, 58, +116,168,125,122,106, 42, 86,175, 89, 83,184, 59,208,148, 69,201, 63, 54, 2, 2, 2,106,137,197,226, 21, 0,252,181, 90,173, 43, + 0, 72, 36,146,120,142,227,142,171,213,234,239, 66, 66, 66,212, 85,124, 78,213, 0,212, 71,254, 12,227,210,192, 45, 89,178, 36, +114,246,236,217, 81,255,109, 78, 66,136,187,147,147,211, 79,253,251,247,199,217,179,103,113,238,220, 57,131, 68, 34,225,141, 24, + 49,130, 76,154, 52,201,102,250,244,233,221, 0,252,252, 23,179,182,219,130, 5, 11,108,189,189,189,113,228,200, 17, 60,125,250, + 84,237,229,229, 37,105,219,182, 45,120, 60,158,237,156, 57,115,186, 2,216,245, 87, 46,144,145,145,177,120,209,162, 69,187,215, +175, 95,111, 17, 29, 29,141,133, 11, 23,218, 79,158, 60,249,134, 66,161,104, 99,170,200, 42,112, 33,152, 10,160, 29, 77,211,173, + 70,140, 24,193, 76,153, 50,133, 79, 81,148, 97,205,154, 53, 14,191,254,250,235, 64,123,123,123,255,212,212,212, 92,152,129,114, + 12, 9,122,150,101,249, 0,196, 28,199,105, 43,250,253,255,233,222,237,236,236, 38,102,100,100,108, 84, 40, 20,112,112,112, 40, +106,107, 89,150,133, 74,165,130, 90,173, 70,173, 90,181, 4,222,222,222,219, 38, 79,158,204, 95,191,126,253, 38,115,137,249, 72, + 2,139, 16, 2,150,101,193,231,243, 63, 16, 88,133,226,167,228,247, 82,107,205, 18, 83, 53, 41,138, 34,185,185,185, 69,226,202, +210,210,178,200, 18,102, 48, 24,254,196,107, 52, 26, 65, 81, 20, 87, 30,103, 25,105,159, 8,224,119,142,227,222,152,146, 9,197, + 57, 15, 79,174,135,221,162, 89,131, 10, 67,158,119,251, 42,255,115, 55,128, 43,175,199, 47, 95,222,162, 69,181,169,223,175,155, +175, 78, 83,166,206, 25,218,211,221,203,217, 78, 34,203, 76,206,178,169, 91,183, 39,128,164, 74,164,179,229,184,113,227,142, 28, +187,242, 66, 44, 22, 11, 4, 60,154,230,183,108, 88,199,174,154, 21,109,101, 1, 88,197, 70, 69,222, 29, 54,108,216,216, 73,147, + 38,217, 22, 10, 44, 83,238,157,207,231,187, 61,120,240,192,145,199,227,161, 69,139, 22,198,202,220,251,199, 66, 25,156,115,147, +146,146, 62,215,104, 52, 8, 12, 12,252,148, 16,210,142,227,184,199,132,144,134,189,122,245,186,117,248,240, 97,139,208,208, 80, + 52,109,218, 84, 2, 96,192,223,152,206, 63, 65,161, 80, 92, 2,240, 9, 77,211,208,105, 52,186, 21,171, 62, 88,230, 46,184,184, +184,250,111,164,211,207,207,175,158, 84, 42,189,187,106,213, 42, 75, 31, 31, 31,194,231,243,193, 48, 12, 34, 35, 35,171,237,221, +187,119,252,163, 71,143,186, 6, 4, 4,248,148, 92,212,220,196,123,175,127,235,214, 45,149,135,135, 71,169,101, 39, 59, 59,155, + 87,167, 78,157, 54, 0,162,254, 6,206,184,164,164,164,222,159,124,242,201,132,196,196,196,112,134, 97,190, 1,208,192,222,222, + 62,244,179,207, 62,131, 68, 34,105,103,138,192, 42,239, 25, 57, 58, 58,246,106,222,188, 57,214,175, 95,143,101,203,150,117,228, + 56,238,119, 66, 72,135,236,236,236, 43,159,126,250, 41,172,173,173,123,151, 38,176, 42, 81,150,234, 52,105,210,100,219,140, 25, + 51, 44,206,158, 61, 11, 47, 47, 47,100,101,101, 97,228,200,145,142,235,214,173,187,174, 80, 40,218, 22,138,172,178, 56, 9, 33, + 62, 34,145,104,215,254,253,251,229, 30, 30, 30, 30, 2,129,128,242,240,240, 64,122,122, 58, 52, 26,141,232,199, 31,127,108, 40, +145, 72,158,252,252,243,207,187, 0,124,246,119,190, 71,132,144, 44, 0,150, 0,172, 43, 51,188, 90,206,189,103, 1, 16, 21,171, +239, 32, 22,139, 33, 22,139, 33, 18,137, 16, 29, 29,125,148,166,233,145, 5, 29,185, 10, 57,201, 31, 61,248, 70,132,144,135, 52, + 77,151,251,187,228, 82,102,127, 71,189, 68, 8,113, 35,132,172, 5,208, 14,249,126,212, 55, 28, 29, 29,167, 37, 38, 38,190, 55, +149, 83,161, 80,216,229,230,230,254,172, 80, 40,224,232,232, 88, 40, 54, 17, 24, 24, 8,141, 70,131, 23, 47, 94,128,101, 89,188, +121,243, 6,150,150,150,104,216,176,225,207, 11, 22, 44, 56, 50,111,222,188,180,255,228,189,255,107, 4, 86,161,146,229,241,120, + 31, 8,172,146, 91,161, 24, 34,132, 84,184, 80, 49, 33,132,210,233,116, 69,226,202,202,202,170,232,191, 12,195,148, 42,176,170, +168,204,125, 89,150,173, 69, 8,217, 98,170,200, 42,137,225,195,135,255,201,159, 99,246,236,217,113,169,169,169,108,223,206,141, +100,225,231,149, 9,158, 54,114,137,131,133, 69, 77,177,141,173,117,110,110,238, 77, 0,242, 74, 92,194,213,219,219,219,106,195, +238,243,202,177, 95, 46, 89, 20,232, 97,103,233,235,102,111,227,108, 37, 17,202, 41,162, 18, 51,134, 56,153, 76,230, 3, 32,173, + 50,233,166, 40, 10,150,150,150, 56,117,234, 20, 10,253,231,254, 33,176, 81,171,213,200,200,200,192,230,205,155, 45, 39, 76,152, +112,141, 16, 50,173,119,239,222,235, 15, 31, 62, 44,203,204,204,132, 94,175, 7, 0,245, 63,240, 61, 89,100, 99, 99,211,186, 93, +187,118,194, 3,135, 14, 9, 57,142, 83, 33,127, 57,162, 92,142, 43, 99,225,234,255, 32,196, 98,241, 87,139, 23, 47,182,244,241, +241, 33,105,105,105, 96, 89, 22, 20, 69,193,222,222, 30, 95,127,253,181,120,238,220,185,174,175, 94,189,154,131, 42, 44, 59, 3, +128,148, 37,132, 0,192,210,210,146, 65,229, 39,199,148,202,201, 48, 12,105,209,162,197,215,169,169,169, 13,213,106,245,143, 38, + 52, 60, 12,128, 83, 5, 91, 97,157,242, 36, 60, 60, 92, 61, 96,192, 0, 73,205,154, 53,131,254,106,222,214,169, 83,167, 25,159, +207,199,131, 7, 15,180, 0,110, 20,236,190,241,244,233, 83,237,103,159,125, 38,170, 86,173, 90, 51, 83,185, 20, 10, 69, 29, 79, + 79,207,203,246,246,246,146,194,105,219,221,187,119,231,175, 88,177,194, 34, 46, 46, 14,122,189, 30,179,103,207, 70,143, 30, 61, + 96, 99, 99,131, 81,163, 70, 57,109,221,186,245, 55, 0, 1,229,212,161, 98,161, 80,184,231,245,235,215, 94, 46, 46, 46,146,251, +247,239,195,215,215, 23,169,169,169, 72, 76, 76, 68,110,110, 46, 18, 19, 19, 49,122,244,104,199,213,171, 87, 43,254, 65,239, 80, +166, 64, 32,128, 84, 42,181,206,204,204,204,250, 11, 60, 34, 0,194,226,226, 74, 36, 18, 65, 36, 18,161,164,139,201,255, 71, 16, + 66, 92, 9, 33, 97, 2,129, 64, 36,149, 74, 5, 20, 69, 65, 38,147,117,174, 86,173,218,139, 97,195,134, 53,216,179,103,207, 59, + 83,120, 52, 26,205, 30,137, 68,194,119,112,112, 0, 0,116,234,212, 9, 35, 70,140, 64, 74, 74, 10,171, 84, 42, 81,175, 94, 61, +234,250,245,235, 72, 74, 74,194,147, 39, 79,208,164, 73, 19,190,173,173,237, 30, 0, 93,205,178,233, 35, 90,176,120, 60, 94,209, + 86,154,229,170,112, 43,233,248, 94, 22,167,209,104,132,147,147, 19,164, 82, 41,164, 82,105,113,103,246, 63,241,115, 28, 87,165, + 33, 66,153, 76,134,193,131, 7,115,155, 54,109,154, 80, 32,178, 94,155,250,223,254,235,195,139,172, 86, 37,225,235,235,123,231, +187,239,190,235,114,241,226,197,140, 64,143,154, 60,153,242,125,174,216,210,218, 26,110,213,187, 15,235, 63,240, 46,128,253,149, + 72,166, 82,171,213, 10, 60,221,164, 58,138,210,144,234, 34,158,133,139, 76, 32,114,182,177,113, 21,232,180,201,150, 54, 54,194, +130, 33, 51,101, 69, 68,133,147, 7, 8, 33,176,182,182,230, 23,124,194,209,209, 81,212,160, 65,131, 36,138,162,192,113,156,242, +217,179,103, 38, 15, 23,122,120,120, 4, 83, 20,229, 70, 8,249, 96, 66, 66,241,141,101,217,184, 23, 47, 94,152, 58, 1,225,187, + 70,141, 26,181,217,184,113,163,131,151,151, 23, 54,111,222,108,121,228,200,145, 93,191,253,246, 27, 50, 51, 51,241,238,221, 59, +140, 30, 61, 58, 27,249,195,136,255, 40,216,218,218,222,238,223,191, 63,182,109,219,198, 21,116, 34,100,132, 16, 95, 43, 43,171, + 87, 97, 97, 97,255,117, 63, 23,138,162, 58,215,171, 87,143,100,101,101,129,101, 89,208, 52, 93,212, 17,162,105, 26, 95,125,245, +149,100,244,232,209,115,155, 53,107,246, 53,159,207,207,102, 24,230, 64,110,110,238,143,207,159, 63,255, 71, 57,171,182,106,213, +234,203,216,216,216, 30, 53,106,212, 56,253, 23,122,251, 92,227,198,141,117, 0, 36, 52, 77,243, 63, 66, 3, 70, 23,212, 71,154, +194,197,225, 57,142, 99, 2, 2, 2, 52, 5,141, 59, 93,137,114,243,219,222,189,123,221,220,220,220, 96, 48, 24,192, 48, 12,114, +115,115,113,253,250,117,104,181, 90, 48, 12,131,122,245,234, 97,217,178,101,154, 73,147, 38,137, 15, 30, 60,152,172, 86,171,135, + 84, 64, 59,237,200,145, 35, 50, 23, 23, 23,137, 90,173, 70, 84, 84, 20, 2, 2, 2,144,147,147, 3,149, 74,133,188,188, 60,232, +245,122,100,103,103, 91, 27,141, 70,221, 63,166,161,225,241, 32, 18,137, 32, 16, 8, 50,107,212,168, 1, 66,136,248,221,187,119, + 85, 25,114,179, 4,144,205,231,243,133,197,133,149, 72, 36,194,179,103,207, 14,150,101,189, 42,175,252, 84,230,247, 63, 64, 96, +173, 21, 8, 4, 34, 91, 91, 91, 65,225, 62,189, 94, 47,176,177,177, 65,205,154, 53,215, 3,232,102, 98, 29,226,103, 99, 99, 3, + 66, 8, 4, 2, 1,198,142, 29,139,135, 15, 31, 30,143,139,139, 27,150,156,156,140,188,188,188, 61, 86, 86, 86,125,146,147,147, + 97, 52, 26,241,246,237, 91,248,249,249,249,153, 37,211, 71,182, 96,149, 37,168, 74, 10, 46, 83,172, 37,122,189, 94,222,189,123, +119,182,120, 35, 93,240, 63, 82,142,192,170, 82, 1,231,243,249, 22, 19, 39, 78,204,217,180,105,211,120, 66,200, 86,142,227, 34, +171,154, 73,167,143,238,119, 90,246,195,236, 31,108, 21, 53, 61,191,249,230, 27,222,103,159,125,118,117,231,206,157,141,109,189, +189, 63,185,118,105,175,211,250,111,230,156, 56,121,242,100,158,169, 14,238, 5,184,115,252,248,113,151, 25, 83, 39, 9,126,248, +106,218, 5, 75, 47,123,161,156,216,202,196, 90, 85,138, 28,156, 90, 84,187, 94,143, 51, 23, 47,198, 2,184,109, 66,229,229,246, +224,193, 3, 71,107,107,107, 0,249,147, 3,172,173,173,177,105,211, 38,155, 66, 75,161, 41,195,133, 37, 94, 64,183,208,208, 80, + 71,185, 92, 14,149, 74, 85,212, 32,112, 28, 87, 84, 89,182,110,221,186, 50, 13, 97, 20, 33,164,245, 23, 95,124,113,115,227,198, +141, 14,158,158,158, 88,180,104, 17,210,210,210, 16, 19, 19,131, 33, 67,134,100, 71, 69, 69,181, 43,238,155,245, 79, 64,195,134, + 13,185, 59,119,238,224,194,133, 11,248,244,211, 79,201,201,147, 39,245, 70,163, 81, 16, 31, 31,255,236,239, 74, 19,195, 48, 22, + 2,129,160,104, 88,189, 80, 88, 21,110,110,110,110,184,114,229, 10, 47, 47, 47,143,151,154,154, 42,253,245,215, 95,167, 4, 7, + 7,187, 0, 24,244,119,230,229,166, 77,155,106,140, 29, 59, 54,134,199,227,113, 93,186,116, 25,250,254,253,251,222, 46, 46, 46, +191, 95,187,118,109, 21,128, 74,135, 43,104,208,160, 65, 48,143,199,115,227, 56, 78,112,226,196, 9,131,209,104, 20, 52,108,216, + 48,169, 68, 48, 68, 48, 12, 19, 23, 17, 17, 17,104, 10,159, 88, 44, 22,108,221,186,213,160,209,104, 4,190,190,190, 73,197,120, + 4, 39, 79,158, 52, 24, 12, 6, 65,221,186,117,131, 77,153,217,156,158,158, 62,100,250,244,233,183, 14, 29, 58,100, 79,211, 52, +222,191,127,143,180,180, 52, 88, 91, 91, 99,207,158, 61,168, 89,179, 38, 46, 95,190,156,206, 48,204,152,109,219,182,205, 85,171, +213, 67, 76,240,193,106, 29, 20, 20, 84, 35, 51, 51, 19,214,214,214, 80,169, 84, 8, 14, 14,134,143,143, 15,148, 74, 37, 40,138, +130,181,181, 53, 54,110,220,152, 71, 8, 73,255, 39,188, 67, 52, 77, 23, 89,153,138,137, 34, 77,179,102,205,112,251,246,237,125, +149, 17, 69, 28,199,233,248,124,254, 7,194,170,240, 59, 77,211,149, 30,242, 48, 26,141, 2, 66,136, 31, 10,252, 3, 43,250,253, + 15, 64, 27,169, 84, 42, 40,165,172, 9,234,212,169,211,202, 84, 18,161, 80,104, 39,145, 72,242, 9,219,180, 65,114,114,178,209, +195,195, 99,224,128, 1, 3, 12, 0, 48,126,252,248,129,201,201,201, 26,134, 97,104,154,166,145,146,146,130,154, 53,107,218,153, + 37,211,127,192,130, 85,158,229,170,184, 5,171,162, 66, 72, 81, 84,102, 72, 72,136, 76, 38,147, 21,237, 51, 24, 12,240,243,243, + 99, 89,150, 37, 37,175, 83,152,142,170,130,207,231, 91,124,251,237,183,153, 27, 55,110, 28, 6,224, 59, 83,254,115,120,114, 61, +236, 46, 33,174, 54, 47, 91,184,254,151,101,139,109,223, 92,216,137,237,235, 86, 26,249, 66,121,176,159,159, 95,235,172,172, 44, +173,181, 76,139,196, 52, 28,231, 56,238,183, 74,244, 66, 40, 0, 7,239,221,187,247,184, 83,167, 78,247,119, 28, 60,102,171,140, +138,186, 39,202, 78, 77,176,172,237,197, 19,184,214,232,163,210,233,248,125,250,244,145, 3, 88,103, 2, 31, 98, 98, 98,112,247, +238, 93, 88, 90, 90,194,210,210, 18,214,214,214, 69,223,171,146,135,133,195,182,103,206,156,129, 76, 38, 67,193,212, 93,200,100, + 50, 8,133, 66, 20,127,134,149, 16, 89, 17,132,144,105,199,142, 29, 59,176,100,201, 18,164,167,167, 67,165, 82, 97,222,188,121, +136,138,138,154,206,113,220,227,127,210,203,225,235,235,203,221,187,119, 15,119,238,220,129, 74,165,194, 47,191,252, 2, 23, 23, +151,246, 0,190,255, 59,211,197,178,172,160,208,162, 88, 92, 88, 21,183, 98,209, 52, 13,177, 88, 12,123,123,123,204,153, 51, 71, +240,233,167,159,246,248, 59,211,188,124,249,242,218,107,215,174,253,117,247,238,221,231,135, 12, 25,114,232,249,243,231, 35,173, +172,172,158, 93,189,122,117,177, 72, 36, 98,171,104, 21,113,123,252,248,177, 99,241, 87,158,101, 89, 41,195, 48, 96, 24, 6, 6, +131, 1,121,121,121,232,216,177,163,201,124, 15, 31, 62,148, 2,192,247,223,127,207, 7, 32,101, 89, 22, 70,163, 17,133,156,121, +121,121,252, 14, 29, 58,184,153,100,162, 86, 42, 35, 20, 10, 69,171, 1, 3, 6,220, 61,112,224,128, 77,141, 26, 53, 16, 31, 31, +143,248,248,120,212,174, 93, 27,235,214,173, 83,113, 28,215,162, 64, 84,157, 52,241,182, 21, 54, 54, 54,252,152,152, 24, 48, 12, + 3, 63, 63, 63,108,220,184, 17, 3, 7, 14, 68,131, 6, 13,144,157,157,141,176,176, 48,236,218,181,203, 70, 32, 16,244,253,187, +223, 33,138,162,254, 36,174,138,111, 85,236, 96, 88,138,197,226,108,145, 72, 36, 44,244,191,122,248,240, 97,165,173, 87,197,234, +165,199,149,249,253,119,194,194,194, 2,114,185, 28, 6,195,135,183, 41,147,201, 80,187,118,109,147,121,228,114, 57, 41, 52, 98, + 24, 12, 6, 36, 36, 36, 24,159, 63,127,110,244,247,207, 31,228,112,113,113, 49, 62,120,240,192,168,209,104,104, 11, 11, 11, 20, +140,138, 16,152,241,241, 44, 88,133,214,138,242, 44, 87,133,223, 11, 45, 81, 21,189,108, 52, 77,227,194,133, 11, 69, 5,165, 94, +189,122, 69,215,250,216, 2,203,206,206, 78, 21, 20, 20,100, 25, 27, 27,187,191, 42,255, 47, 20, 87, 75, 22,205,179, 77,127,121, + 31,113,202, 4,164, 39, 27, 66,110, 63,123,123, 9,192, 37, 0,192, 22,239,235, 24,255,210,100,113,229,237, 32,109,212, 80, 97, +113,252,147,110, 61,170, 13, 24,247, 37, 53,105,210,164,166, 35, 71,142, 76, 27, 50,100,200, 36,137, 68,226,205, 48, 76,218,153, +139, 23,223,244,233,211,199,153, 97,152, 17, 28,199,153,226,147, 20, 55,120,240, 96, 1, 33, 4,142,142,142,252,221,187,119,219, + 88, 90, 90, 98,228,200,145, 25,111,223,190, 53, 20,244,196,146, 42,121,251,113, 45, 90,180,248,211,176, 96, 97,195, 94,104, 25, +168,164,104,243,235,209,163,199,182, 67,135, 14, 33, 53, 53, 21, 42,149, 10,124, 62, 31, 43, 86,172, 64, 76, 76,204,207,132,144, +231,255,148,202,172, 81,163, 70,220,131, 7, 15,240,236,217, 51,104,181, 90,140, 25, 51,166,184,143, 97,167,191,123,164, 32, 62, + 62, 30,123,247,238, 5,203,178, 24, 50,100, 8,106,212,168, 81, 36,172, 18, 19, 19,177, 99,199, 14, 24,141, 70,140, 29, 59, 22, +213,171, 87,135,193, 96, 16,183,109,219,150,119,253,250,117,230,239, 72,240,140, 25, 51,222, 28, 63,126,252,124,108,108,108,215, +101,203,150,181, 33,132,176, 95,127,253,245, 82, 75, 75,203,191, 52,251, 50, 35, 43, 7,175, 94,191, 47, 18, 64, 37, 55, 7,123, +219, 74,243, 69, 70,197, 22,253,223,104, 44,206,103,132,157,173, 77,165,248, 18, 18, 18,242,210,210,210, 84, 99,198,140,177,222, +182,109, 27,169, 93,187, 54,162,163,163,193,231,243, 97, 97, 97,145, 23, 30, 30, 94,217,208, 12,241,233,233,233, 94, 52, 77, 11, + 94,191,126, 13,119,119,119, 4, 5, 5,225,199, 31,127, 68,106,106, 42, 24,134,129,163,163, 35,107, 48, 24, 66,117, 58,221,205, +191,251, 61, 42,110,101, 42,190,221,185,115,103, 31, 77,211, 20,128,211, 0, 42, 37,176, 57,142,211, 85,175, 94,253, 3,238,170, + 88,175,254,131, 22,187,255,216,204,196, 58,117,234,220,144,201,100, 61, 94,189,122,245,129, 21,107,240,224,193,122, 79, 79,207, + 91,166,242, 88, 90, 90,102, 8, 4, 2, 59,141, 70,131,123,247,238,193,219,219, 91,144,149,149,181,132, 16, 50,187,160,115,185, + 36, 41, 41, 73,160, 80,228,187,241,213,173, 91, 23, 57, 57, 57, 25,102,201,244,145, 5, 86,105,150,171,210, 68, 22, 77, 87,236, +154, 64, 8,129, 90,173,134, 76, 38, 43,218, 10,253,172, 74, 19, 88, 5,190, 63, 85, 26, 34, 44, 16, 87,146, 3, 7, 14,236, 91, +183,110,221, 29, 83,255, 87,220, 7,107,203,170, 69,203, 10,197,213,211, 59,151,113, 50, 60, 43,117,214,146, 53,107,171,154,217, + 62, 14, 50, 95,103, 39,251,235, 43,126, 90,104,249,230,194, 46, 28,218,178,154,123,250,240, 97,227, 9, 15, 31,246,157, 48, 97, +130, 45,128, 4, 0,241, 0,238, 1,248,217, 68,113,133,136,136,136,162,224,174,254,254,254,177, 54, 54, 54, 54, 18,137, 4, 74, +165, 82,251,248,241,227, 42, 57,186, 70, 70, 70,126,212,224,174,132,144, 58, 61,123,246,188,121,244,232, 81, 89,102,102, 38,222, +191,127,143,175,191,254, 26, 27, 54,108,128,165,165, 37,206,158, 61,107,209,163, 71,143,235,132,144,230,127,119,112, 85, 63, 63, + 63,238,209,163, 71,120,247,238, 29, 24,134, 65,175, 94,189, 42,156,192,241, 95,182, 96,113,211,167, 79,199,182,109,219, 64,211, + 52,134, 13, 27,134,236,236,236,162,227,182,182,182,165, 29,163, 11,222,247,191, 69, 96,241,120, 60,238,198,141, 27,203,218,180, +105,131,216,216,216,174, 1, 1, 1,191,140, 28, 57, 50,254,175,242,218, 88, 89,160,145,143, 7,180, 90, 45,180, 90, 45, 20, 10, + 5,114,114,114,240,230,205, 27,104,181, 90, 56, 57, 90, 87,154,207,191, 65,237, 34, 62, 71, 71, 71,168, 84, 42,188,125,251, 22, + 58,157, 14,246,246, 54,149, 41,243,213, 58,119,238,124,109,223,190,125,118,251,246,237,211,125,246,217,103,194,133, 11, 23, 18, + 75, 75, 75, 36, 39, 39,163,138,238, 61, 55,110,223,190, 93,163, 99,199,142,117, 95,190,124,137, 27, 55,110, 64,167,211,193,223, +223, 31,145,145,145,104,214,172, 25,114,115,115, 31, 60,122,244,232,212, 63,161,172, 22, 14,223, 21,110,193,193,193, 7, 5, 2, + 1, 7,160, 74,214,166, 66,196,196,196,136,124,125,125,181, 98,177, 88, 88, 32,214,254, 18,223, 71,174,235,254,210,204,196,242, +224,225,225, 49,221,205,205,173,163,191,191, 63, 94,190,124, 41, 16,137, 68, 24, 58,116,168,190, 91,183,110,122, 30,143,103,242, +132, 27,137, 68,242, 82, 46,151,183,214,106,181,208,233,116,184,124,249, 50,236,236,236,102,245,236,217,115, 90, 66, 66, 2,148, + 74,165, 80, 40, 20, 22,249,223,182,109,219, 22,105,105,105, 47,205,146,233, 35, 9,172,194, 50, 98,202,240,160,169, 62, 88, 20, + 69, 65,167,211, 65, 38,147, 65, 42,149, 66, 38,147, 21, 93,135, 16, 82,170,192,170, 10,170, 85,171,134,160,160, 32,201,161, 67, +135,126, 91,185,114,229,221,170,112, 28,217,183,215,197,138,205,171,166,124,112, 14, 17,207, 66,112, 60, 44, 51,117,214,146, 53, + 83,123,246, 29,148, 84, 82,144, 29, 30,111, 66,207,195, 81,214,192,213,201,238,250,170,229, 75, 44,211, 95,222, 71, 66, 98, 34, +206, 61,120, 20,162,205,247, 13,251,241, 35,190,220, 40, 28, 91,255, 39, 65, 36, 18, 77, 63,114,228,136, 44, 51, 51, 19, 81, 81, + 81, 24, 50,100, 72,230,187,119,239,190,232,221,187,247,134, 75,151, 46,217, 88, 91, 91,227,210,165, 75, 22,213,170, 85, 91, 2, +160,199,223, 88, 57,114, 70,163, 17,233,233,249,238, 43, 45, 90,180,248, 71,137, 43, 0, 8, 14, 14, 22,244,236,217,243,119, 0, +237, 95,190,124, 9,150,101,239,134,132,132,180, 40, 60, 94,222, 49, 83,244, 91, 78, 78, 14,223,194,194,162,212,198, 74, 32, 16, + 8, 42,107,113, 40,206,121,231,206,157,165,171, 86,173, 58, 62,115,230,204,215,127,145,179, 84, 11, 86,143, 30, 61,160,214,234, + 17,151,148, 5,163,145,129, 90,159,252,151, 44, 88, 61,122,244, 64,158, 70,135,152,132,116, 48,140, 17, 57,106,198,212,114, 36, +253,228,147, 79, 46, 30, 56,112,192,249,222,189,123,208,106,181,108,112,112,240,219,113,227,198, 89,142, 30, 61,218,174,172,208, + 54, 38, 96,221,160, 65,131,250,221,185,115, 39,189,110,221,186,182, 15, 30, 60, 64,114,114, 50, 24,134, 65,251,246,237, 33, 20, + 10, 99,150, 44, 89, 34,128, 9,174, 5,255, 45,129, 37, 18,137, 16, 22, 22, 86, 40,172,134,127, 44, 33, 36, 20, 10,171, 60,204, +248,191,138,223,126,251, 45,126,231,206,157, 62,174,174,174,107,135, 15, 31,222, 78,161, 80, 80, 34,145,232, 6,143,199,155, 6, +224,189,169, 60, 2,129, 96,164,181,181,245, 27,138,162,232,248,248,120,188,126,253, 26,209,209,209, 0, 32,204,203,203,131,163, +163, 99,145,209,100,208,160, 65,168, 86,173,154, 49, 50, 50,114,164, 89, 50,125,100, 11,214,194,133, 11,177,101,203, 22,140, 31, + 95,190,138, 56,125,250, 52, 80, 98,136,176, 96,249,152, 43,197, 27,127,163,209,136,121,243,230,125,240,191,194,225,167, 47,190, +248,226, 3,206, 19, 39, 78,252,105,136,176, 36,103,105, 72, 78, 78,126,121,248,240,225, 71,203,151, 47,127, 96, 98,101, 88,196, + 89,232,131,213,111,240,208,132,245, 75,127,120,190,251,244,213, 6, 9,106, 46, 97,214,146, 53, 51, 75,138, 43, 83, 57,189,157, +229,222,110,142,118, 55, 86, 46, 95, 98, 85,104, 13, 59, 16,154,152, 5,134, 27, 95,153,135,101,202,189, 51, 12, 19,231,231,231, + 39, 0, 76, 27, 22, 52,133,179, 10, 34,229, 79,156, 90,173, 22,247,239,223, 7, 0,140, 26, 53, 42,243,221,187,119,173, 57,142, +123, 65, 8,121,217,185,115,231, 27, 23, 47, 94,180, 97, 89, 22, 40, 35, 44,197,127, 43,157, 5,249, 6, 30,143, 7, 47, 47,175, + 74,139,171,255, 86, 58, 19, 18, 18,198, 79,152, 48, 97,139, 86,171,229,169, 84,170,241,166, 30,171, 40,157,135, 15, 31,126,237, +229,229,213, 6,101,135, 98, 96, 11, 44,172, 85,230, 92,187,118, 45, 0,212,253, 43,156,101, 89,176, 14, 30, 60, 8,150,101, 81, +205,217, 26, 90,173, 22, 82,169,180, 82,156, 37, 45, 88,135, 14, 29, 2,203,178,168,238, 98, 11,157, 78, 87,102,231,165, 36,167, +157,157,221,234,221,187,119,187,133,135,135, 35, 46, 46, 14,107,214,172,121,159,146,146,210,141,199,227,137,126,249,229,151,235, +221,187,119,119, 98, 24, 70, 91,217,231,206,113,156,150, 16, 50,178,121,243,230,123, 22, 47, 94, 28, 93,175, 94,189,234, 45, 90, +180,176, 78, 75, 75, 75,121,252,248,241,219, 45, 91,182,200, 25,134, 25, 89,214,208,211,127,243, 61, 2,128,248,248,248, 83, 0, +248,149, 21, 86,166,164,243,225,195,135,135, 10,184,207,153,194,253,223,186,247,191, 58, 51,177,162,116,142, 28, 57, 50, 14, 37, +226,155, 85, 54,157,151, 46, 93,122, 55,120,240,224, 69, 13, 26, 52,152, 47,151,203, 17, 17, 17, 81, 20, 22,169,176,140, 19, 66, +208,191,127,127,124,241,197, 23,184,120,241,226,162,126,253,250,189,251, 79,231,231,191, 70, 96, 25,141,198,216,119,239,222,185, +236,222,189,155, 38,132,224,183,223,126, 67,241, 41,251, 52, 77,131,162, 40,240,120,249, 20,247,239,223,103, 42,138, 57,101, 52, + 26, 99,131,131,131,157,118,237,218,197, 47, 52, 25,199,199,199,131,101, 89, 54, 41, 41,137,218,183,111, 95,145, 53,140,199,227, +225,254,253,251,140, 94,175,143,169,236, 77, 69, 68, 68,124,148,222,219,205, 23,239,166, 93, 60,119,194,190,105, 80,171, 76, 75, + 91,219, 82,187,174,133, 17,223,203, 45,220, 60,234,199,101, 63, 45,180, 46, 20, 87, 7, 67, 19, 51, 53, 90, 99,187,151, 41,121, + 79, 63,246, 3,125,250,244,105,243,127,104, 89,155,215,166, 77, 27, 22,128, 61,128,185,133,179, 58, 11, 68, 86,211,218,181,107, +207, 4, 32, 1, 48,239,239,180, 94, 21, 15, 13,242, 79,179, 92, 21, 71, 72, 72, 72, 52,128, 14,149, 61, 86, 17,250,245,235, 23, +133, 82, 2,126,254, 21,252, 39, 56, 11,145,158,153,141,168,119,241,200,119, 70,103, 97,124,159, 84,228, 55,101, 48, 48, 72,207, +174, 84, 24, 57,100,100,229,224,205,219,248,130,165,193,140, 48, 26,149, 5,124,249,142,238, 92, 70, 94,133, 28,124, 62,191,229, +218,181,107,187, 81, 20, 69,221,191,127, 95,187,124,249,242,216,148,148,148, 94, 28,199,197, 0,128, 66,161,104,123,226,196,137, +223, 76, 8,201, 80, 86,199, 55,140, 16,210,236,155,111,190,153, 10,160, 37,128,234, 0, 98,144, 63,227,120,221, 63, 44,226,248, +240,255, 81,238, 42,227,127,101,102,226,190,125,251, 22,124,241,197, 23,188,160,160,160, 57,141, 27, 55,166,222,190,125,139,228, +228,100,240,120, 60,212,169, 83, 7,157, 58,117,130,187,187, 59,123,246,236,217,159,250,244,233,179, 0,102,124, 60,129,149,154, +154,218,121,248,240,225,151, 41,138,170, 89,124, 24,175,180, 79, 0, 96, 89,246, 93, 82, 82, 82,185, 65,200, 82, 83, 83, 59,207, +155, 55,239, 50,143,199,171, 89, 44,254,149, 54, 45, 45,237,139,254,253,251,111,228,243,249,162,226,214, 46,150,101,223, 39, 36, + 36,252, 87, 29,138, 75,198,193,234,220,173,119,234, 95,229,148, 11, 40,207,136,179,219,144,148,156,138,131,161,137, 25, 57, 58, + 99,219,136, 20,213,243,127, 83, 65,227, 56, 46, 25,192, 23,101, 28,123, 13, 96,252, 63, 32,141,164, 64,100,153,103,203,252, 15, +128, 97,152,184,142,237,219,162,100, 88,134,146,191,141, 70, 99,156,169,124, 29,218,181, 41,147,167,240,123, 69,124, 52, 77,207, + 12, 10, 10,162,103,206,156,153,116,254,252,249,223, 51, 50, 50,102,112, 28, 87,164,204, 10,102, 13, 6,252,197,178,170, 69,254, + 10, 15,203,205, 37,225, 31, 89,223,253, 79,204, 76,220,184,113,227,247,179,102,205,218,229,230,230,182,183,101,203,150,117, 61, + 61, 61, 45, 45, 44, 44,144,157,157,157,147,145,145,241,234,204,153, 51, 67,134, 15, 31, 30,109,126,162, 31, 89, 96,165,164,164, +168, 0, 52,251,152, 23,171,128,179,198, 63,166,203,165, 93,190, 31, 91,150,127,176, 14, 97,161,248, 42,245,119, 5,210, 32, 75, +205, 76, 90,119,241,197, 74, 45,195,177,122,134, 29, 21,145,172, 10, 51, 23,189,127,108,197,104, 22, 87,255, 35,120,254,252,121, +224, 63,145, 79,167,211, 77,107,222,188,249,207, 70,163,113,149,193, 96,184,109,126, 82,102,252,147,177,124,249,242,232,194,118, +185,127,255,254, 52, 0, 28, 62,124,216,104,206,153,255,160,192,250,183,226,240,139, 63, 26,216,146,194,169,162,223,101,225, 85, + 98,238,141,191,218, 99, 53,195, 12, 51,254,103, 68,122, 12,128, 94,230,156, 48,227,127,174,253, 51, 11,171,143, 10,202,156, 5, +102,152, 97,134, 25,102,152, 97,134, 25, 31, 23, 4, 64,199, 50,122, 97, 38,207, 14, 32,132,116,172,236,133, 77, 88, 49,220,204, +105,230, 52,115,154, 57,205,156,102, 78, 51,231,255, 51,206,127, 13,138, 59,114,126,236, 13, 64, 71, 51,167,153,211,204,105,230, + 52,115,154, 57,205,156,102,206,127,219,102, 30, 34, 52,195, 12, 51,204, 48,195, 12, 51,204,248,200, 48, 59,185,155, 97,134, 25, +102, 20,131, 66,161,232, 9, 96, 1,242, 93, 40,150, 40,149,202, 67,230, 92, 49,227,255, 19, 28, 28, 28,100,118,118,118,191, 83, + 20, 85, 3,248, 48,228, 82, 41,193,189, 97, 52, 26, 19,210,211,211, 59, 37, 38, 38,166,254, 55, 57,255,117, 2,171,125,109,235, + 86, 30,181,220,247,165, 36,167,134,230,106,178, 71,255,254, 42, 39,189, 42, 23, 38,132,216, 9,133,194,129, 50,153,172, 35,199, +113, 30, 52, 77,135,103,101,101, 93, 49, 24, 12, 7, 56,142,203, 53,191, 2,102,252,221,240,243,243,107, 40, 20, 10,103, 17, 66, +154, 50, 12,227,198,231,243,149, 0, 30,104,181,218, 21,161,161,161,161,230, 28,250,255, 1, 66, 8,229,226,226,242,179,181,181, +117, 80,102,102,230, 16, 0,115, 34, 34, 34,124, 41,138,130,143,143,207, 28,133, 66,241,198,210,210,114,123,118,118,246,221,132, +132,132,105,149, 89, 59,206,140,127, 46, 60, 61, 61,131, 41,138,114, 43, 92,146,173,164, 32, 40, 77, 32,112, 28, 23, 29, 22, 22, + 86,102, 48,103, 55, 55, 55, 15, 75, 75,203,141, 0, 26,151, 20, 21, 37, 81, 48,204,246, 40, 59, 59,251,139,184,184,184, 82, 3, +241,218,218,218, 90, 56, 58, 58, 46, 32,132,244,167, 40,170,194, 5,127, 89,150, 53,114, 28,119, 56, 57, 57,121, 94,122,122,122, + 78, 89,231,217,217,217, 93,185,121,243,102, 99,123,123,251, 10,195,210, 48, 12,131,248,248,120,135,238,221,187,223, 4, 80,239, +191,201,249,175, 19, 88,224,168,161, 43,190, 27,235,154, 18,251,198,117,206,218, 99,117, 90,213,179,111,123, 43, 60, 53,177, 50, + 20, 18,137,100,160,175,175,239,186,159,127,254,217,206,221,221,157, 72,165, 82, 36, 36, 36,212,123,252,248,113,159,249,243,231, +207,227,243,249, 35, 13, 6,195,229,191, 88,105, 90,219, 74,121,179,210, 84,134,111,205, 85,137, 25,149, 65,255,254,253,233,216, +216,216,249,246,246,246, 95,205,158, 61, 91, 84,179,102, 77,200,229,114, 36, 39, 39, 87,127,253,250,117,181, 13, 27, 54,244,108, +222,188,249, 47, 58,157,110,110, 72, 72,136,193,156, 99,255,219,112,113,113,249,249,228,201,147,147,235,214,173,139,214,173, 91, +223,245,243,243,179,148, 74,165,184,112,225, 2, 60, 61, 61,235, 91, 90, 90, 62,216,188,121, 51,127,193,130, 5,141,142, 29, 59, + 6, 0, 83,204,185,246,191, 15,138,162,220, 66, 67, 67, 29,165, 82, 41,140, 70, 99, 65,244,126, 22, 28,199, 21,125, 22, 23, 67, + 70,163, 17,237,218,181,211,151,199, 41, 22,139, 55, 60,123,246,172, 99,225, 58,126,197,132, 84,169, 80, 42,149, 29,219,181,107, +183, 1, 64,169, 1,181, 29, 29, 29, 23, 12, 24, 48, 96,122,131, 6, 13, 0,160, 40,157,133,159,169,169,169,152, 52,105, 82,209, + 53, 88,150,197,205,155, 55,167,126,249,229,151, 0,240,101, 57,247, 94,195,222,222,158, 84,180, 4,222,252,249,243, 49,127,254, +124,172, 91,183,142,240,120, 60,235, 10,242,243,163,115,254,235, 4, 22,161,200,185,245,155,119,141,158, 49,160, 41, 89, 62,174, +149,215,119,219,175,223,235, 88,203,166,245,149,232,140, 88, 19,197,213,212, 9, 19, 38, 44, 93,184,112,161,248,213,171, 87, 8, + 11, 11, 3,195, 48,176,176,176,128,175,175, 47,117,238,220, 57,151,105,211,166, 29, 17, 10,133,163,116, 58,221,177,170,222,152, +179, 37,127,133, 76, 68, 13, 22,242,120, 15,116, 12,115,234,159,152,249,238,238,238,151, 12, 6,195,178,248,248,248,107,255, 43, + 5, 70,161, 80,180, 16, 10,133,243,222,189,123,215,133,227, 56,230,255,227, 75, 17, 19, 19,179,176,101,203,150, 51,230,207,159, + 47,122,251,246, 45, 34, 35, 35,161, 84, 42, 81,179,102, 77,184,187,187,147,117,235,214,137,127,249,229,151, 41, 79,158, 60,225, + 3,152, 81, 25, 75,137,179,179,243,152, 14, 29, 58,244,181,183,183,183,138,143,143,207,186,115,231,206,201,132,132,132,173, 85, +205, 75, 66, 8,101,111,111, 63,162, 71,143, 30,125,109,109,109,109, 19, 19, 19, 51,174, 92,185,114, 34, 57, 57,121,251, 95,177, +180, 16, 66, 92, 0,248, 2,176, 43,216,149,224,238,238,254,226,237,219,183,201, 31,145, 83,233,238,238, 30, 86, 21, 78, 7, 7, + 7, 25,143,199, 59, 68, 8, 81,148, 99, 33, 80, 50, 12, 51,160, 32,192,113,153,176,180,180,108,234,229,229,133,144,144, 16,204, +157,251,127,236, 93,123, 92, 84, 85, 30,255,158,123,231,197,188, 96, 24, 64, 96, 24, 5,149, 55,152,138, 6,152,226,170,169,105, +202, 90,138,149,181,165,105,166,100, 46,110, 9,169,176,226, 35,205, 30,102,143, 13,113, 85,220,245, 85,150, 86,102, 25,161,109, +186,105,226, 11,197,215,240, 88, 69,112, 16, 70, 30, 34,143,153,185, 51,115,239,254, 1, 51,226,198, 99,134,220, 36,155,239,231, +115, 62,115,239,157,225,203,185,231,156,251, 59,223,251, 59,191,115, 78,170,114,228,200,145, 40, 44, 44, 4, 33, 4,175,188,242, + 10,137,136,136,224,151,151,151, 99,240,224,193,200,201,201,121, 8, 78, 56, 82,231,187, 0, 40, 0, 76,227, 56,238, 70,171,235, +158, 0, 62, 7, 80,201,113,220,228,123,149, 63,177, 88,140,157, 59,119,130,207,231,131,207,231,163,166,166, 6,106,181,218,118, + 46, 16, 8,108,199,189,122,245,234,148,143,101,217,104,154,166, 81, 95, 95, 15,139,197, 98, 75,181,181,181,224, 56, 14, 34,145, + 8, 22, 75,243,182, 75,214,239, 88,150,141,238,160,252,166,170, 84, 42,236,216,177, 3, 70,163,177,173,182,139,252,252,219,155, +130,208, 52,141, 1, 3, 6, 80,132,144,169, 29, 9, 44, 66, 8, 7, 0,179,103,207, 6, 77,211,182,173,239,172,199,214,100,177, + 88,144,158,158,222, 28,176, 77, 81,157,213,245, 93,231,252,205,183,255,142,212,245,200, 64,247,196, 17,113,177,111,185,136,120, + 98,214,108,130,197,108, 2,107, 54,130, 38, 44,226,194,123, 32,170,151, 11,170,107,110, 33,117,107, 94,157,182, 74, 31,147, 93, + 80,165,233,164, 2, 2, 98, 98, 98, 78, 29, 60,120, 80,113,224,192, 1,104, 52, 26,188,254,250,235, 0, 0,169, 84,138,253,251, +247,131,166,105,176, 44,139,113,227,198,233,180, 90,109, 24,199,113,213, 93,120,168,253,135,247, 83,159,220,189,104,184, 50,114, +238,167, 37,215,111, 26,251,114, 28,215,237, 22, 80, 83,169, 84, 28,159,207,111, 52,155,205,241,191, 5,145,165, 82,169,134,242, +249,252,253,102,179, 89,194,231,243,197, 87,174, 92, 49,220,111, 15,196,192,129, 3, 31, 80, 42,149, 63,237,217,179,199, 37, 55, + 55, 23, 53, 53, 53,168,172,172,196,252,249,243,145,145,145,129,200,200, 72, 72,165, 82, 8,133, 66,188,244,210, 75, 77,183,110, +221, 26,113,226,196,137,227,118,180, 73,122,248,240,225, 59,182,109,219, 22, 96, 54,155, 41, 0, 48, 26,141, 40, 45, 45,181, 44, + 89,178,228,234,137, 19, 39,166, 57, 42,178, 8, 33,212, 67, 15, 61,180,117,219,182,109,129, 66,161,144, 98, 89, 22, 38,147, 9, +133,133,133,150, 37, 75,150, 92, 57,121,242,228,211, 93,105,247,132,144,129, 18,137, 36, 34, 49, 49, 81, 55,105,210, 36, 6, 0, +142, 31, 63, 78,157, 57,115,198,181, 79,159, 62, 37,105,105,105,167,186,192, 57, 72, 46,151,135,190,248,226,139, 55, 38, 78,156, +104, 18, 8, 4,236,143, 63,254,200,211,104, 52,174, 1, 1, 1,197,139, 23, 47, 62,227, 96, 91,220,183,103,207,158, 17, 42,149, +202, 2,128,179, 26,120,138,162,184,150, 79, 20, 23, 23,243, 18, 18, 18,254,165,213,106,255,216,225,203,152,143, 79,184,175,175, +239,161,180,180, 52,165,181,147,106,157,172,117,149,158,158,206,148,151,151,199,106,181,218,211,112,194,222,122, 63, 6, 32, 26, +192, 57, 0,163, 56,142,187,209, 34,174,190, 7, 16, 1,224, 71,142,227,134,221,139,188,133,134,134, 86,228,231,231,247,248,226, +139, 47,192,231,243,241,221,119,223, 33, 35, 35, 3, 59,119,238,108, 83,100,249,250,250, 34, 46, 46,174,236,244,233,211, 61,219, +227, 12, 12, 12,188, 89, 84, 84,228,122,243,230, 77, 88, 44, 22, 28, 59,118, 12, 27, 55,110, 68,143, 30, 61,224,233,233, 9, 47, + 47, 47, 68, 71, 71, 67, 42,149,218, 68,214,212,169, 83,235,138,138,138,220,218,226, 11, 15, 15,215, 62,243,204, 51,190, 39, 79, +158,132,201,100,106, 83, 96, 37, 37, 37,181,246, 34, 65, 42,149, 98,210,164, 73,229, 23, 46, 92,104,247,229, 35, 50, 50,178,252, +220,185,115, 62,103,206,156,185,163,173,183, 37,136,104,154,134, 92, 46,199,144, 33, 67, 42, 78,159, 62,237,243,107,114,222,215, + 30,172, 96,127,159, 37,139,230, 60, 38,134,133, 1,103,106, 2,152, 70,128,169, 7,107,108, 4, 17,136, 1, 83, 19,148,194,106, +188,255, 92, 31,215,213, 95, 92,185, 48,170,175,215,132,131,197,186,253,237,241, 41, 20,138,244,245,235,215, 43,242,243,243,161, +209,104,176,118,237, 90,172, 88,177, 2, 2,129, 0,213,213,213,136,143,143,199,145, 35, 71,192, 48, 12, 82, 83, 83,149, 41, 41, + 41,243,208, 28,108,234,160,247,138,151,241,201,230,247,149, 74,186, 10,207,143, 58,225,241,183,236,203,137, 0, 62,232,142, 21, +240,214, 91,111, 73,146,147,147,247,250,249,249,117,107,145,165, 82,169,134,138,197,226,253, 73, 73, 73,210, 55,222,120,227,174, +136, 85,181, 90, 29,201,227,241, 62, 54, 26,141,175,148,151,151,127,219, 5,227,221, 59, 38, 38,230,141,243,231,207,127, 86, 95, + 95,191,171,173,223,200,100,178,169,161,161,161,143,157, 56,113, 98, 9,199,113,151, 59,227, 20,137, 68,243, 23, 46, 92,232,114, +237,218, 53,212,214,214, 66, 40, 20,218,118,153, 39,132, 64, 36, 18,129,162, 40, 8,133, 66, 60,251,236,179, 46,155, 54,109, 90, + 0,224,169, 78,219,164,143,207,204,173, 91,183, 6, 48, 12, 67, 53, 52, 52, 64, 32, 16, 64, 32, 16,224,129, 7, 30,160, 23, 46, + 92,216,115,254,252,249,115, 0,124,232,200,253,187,187,187, 63,183,117,235,214, 64,161, 80, 72,149,151,151, 99,232,208,161, 56, +118,236, 24, 98, 98, 98,232,228,228,228, 94,243,230,205,155, 13, 32,195, 81, 47,147, 68, 34,233,247,253,247,223,151,246,236,217, +211,246,246,213,187,119,111,203,132, 9, 19,170, 47, 94,188, 24,122,244,232,209,170, 33, 67,134, 92,117,128,211, 79, 34,145,132, +125,253,245,215,229,203,151, 47,127, 56, 51, 51,115, 18, 0, 68, 71, 71,127,185, 98,197,138,131,213,213,213,145,135, 15, 31,174, +142,139,139, 43,115, 32,171, 30,222,222,222,230,196,196, 68,121,123, 63,216,178,101, 75, 21,128, 30,157,180,235,120,138,162,150, + 69, 70, 70,186,142, 28, 57, 18,135, 14, 29,194,203, 47,191,108, 48,153, 76, 5, 0, 48,122,244,232,144,244,244,116,225,201,147, + 39,161, 80, 40,248,229,229,229,155, 85, 42,149, 51,240,221,126, 76, 2,240, 47, 0,145, 0, 14, 18, 66,158, 0,240, 41,128,112, + 0, 26, 0, 9,247, 50,115, 22,139, 5, 60, 30, 15,101,101,101,216,180,105, 19, 86,173, 90,133,224,224, 96,152, 76, 38,155,192, +226,241,120,224,243,249, 32,132,216,189,149,150,217,108,198,241,227,199,177,245,159,255, 68,234,146, 37,144,203,155,155, 41,195, + 48,168,174,169,129,139,139,139,205,131,213, 17, 56,142,219, 85, 88, 88,152,164, 86,171,239, 24, 26,180,126,182,216, 56,176, 44, + 11,179,217, 12,131,193,128,191,255,253,239,102,142,227,118,117,242, 76,218, 60, 94, 73, 73, 73, 48, 24,110,191, 43,247,239,223, + 31, 0, 16, 16, 16,128, 1, 3, 6,216,206,173, 30, 42,123, 56,255,254, 80, 63, 52,181,250,117,104,250,219, 86,155,143,208,208, + 80,248,250,250,218,197,121, 95, 11,172,130,171,149,107,146,151,189,247,182, 84, 72,243,103,140, 15,135,202,149, 15,136,149, 16, + 12, 79, 1, 81,248, 55, 55,128,234,255, 0,217, 41, 72, 29, 91, 69,189,214,196,124, 62, 62, 80,233,245, 77, 81,187,193,117,209, + 61,123,246,196,225,195,135,209,167, 79, 31,164,165,165, 33, 44, 44, 12, 82,169, 20, 21, 21, 21,104,104,104,128, 84, 42, 69, 93, + 93, 29,162,162,162,104,185, 92, 62,210, 81,129, 69, 8,137,154, 21, 31, 19,205,243, 14,199,208,135, 99,145,189,116,132,116,203, + 15,215, 22, 17, 66, 54,183,222,112,181,187, 32, 33, 33, 1,215,175, 95,151,172, 91,183,174,203, 34, 43, 32, 32, 32,155, 97,152, + 49,118,184,195,191, 47, 42, 42, 26,213, 85,113,181,119,239, 94,169, 92, 46,199, 27,111,188,113,183,196,213,191, 31,121,228, 17, +215,111,191,253,118,143,175,175,239,227,142,136, 44, 66, 72,239,169, 83,167,126,181,113,227,198,144, 81,163, 70, 89, 0,180,105, + 80, 34, 34, 34,166,100,103,103, 79,158, 53,107, 86, 63, 66,200,196,206, 68, 22, 33,228,161,222,189,123,163,180,180, 20, 21, 21, + 21,208,235,245,168,168,168, 0, 0,148,149,149, 65,173, 86, 67,161, 80, 64,173, 86, 35, 36, 36,132, 80, 20, 21, 99, 79,126, 71, +142, 28, 57, 9, 0, 85, 92, 92, 12,157, 78, 7, 55, 55, 55, 72,165, 82,168,213,106,140, 24, 49,130, 23, 24, 24,248,168,163, 2, +107,252,248,241, 83, 36, 18, 9, 85, 90, 90,138,203,151, 47,195, 96, 48,160,160,160, 0,110,110,110,120,248,225,135,249,129,129, +129, 19, 29, 21, 88, 0,250,205,158, 61,187,162,181,184,178, 66, 42,149,146,144,144,144,106, 15, 15,143, 65, 0,174, 58,194, 57, +111,222,188,202,213,171, 87, 15,207,201,201, 73,177, 94,204,201,201, 73, 6,128,247,222,123,239,176,151,151,215, 32, 0,142, 8, + 44,112, 28,199,206,154, 53,171, 80, 32, 16, 64, 40, 20,218,146, 72, 36, 2,159,207, 7, 77,211,110,118,208, 44,214,104, 52,253, +101, 50, 25, 52, 26, 13,104,154, 6, 33,164, 80,171,213,246, 7,128,148,148,148,162,166,166,166,190,122,189, 30, 9, 9, 9, 36, + 62, 62,254,129,181,107,215, 46, 1,208, 45, 4, 22, 33,228, 65, 0,107, 1, 24, 1, 44,225, 56,238, 88,119,178,111, 28,199, 85, + 16, 66, 70,180, 18, 89,167, 1,136, 90,196,213, 8,142,227, 42,238, 97,217,129,101, 89,240,249,124,188,253,246,219, 96, 24, 6, +219,182,109,195,167,159,126, 10,138,162,108,129,238,174,174,174,120,255,253,247,127, 22,248,222,153,112,219,178,101, 11, 82,146, +147,109,226, 10, 0, 4, 2, 1,124,188,189,225,225,233,137,226,226,226, 78, 5, 86,101,101,229,210,220,220, 92,116, 20,228, 62, +121,242,237, 17,214,214, 65,238,246,228,147,166,105, 24, 12, 6,140, 25,115,187,251,152, 55,111,158,237,184,186,186,218,250, 76, +128,216,121,243, 52, 77,163,137, 3, 30,115,185,125,237,209, 87, 94,177, 29,223,184,113,195, 97,206,251, 82, 96, 13, 47,170,254, +240, 8,193,128,228,231, 31,158,174,242,116, 5, 87, 95, 1,193,168,165, 56, 91, 45,193,186,245,205,125, 97, 82, 66, 20,250,141, + 94, 9, 99,214, 88,204, 28,104, 17, 46, 40,199, 66, 0,105,109,241,121,122,122,122,152,205,102, 16, 66, 32,149, 74, 17, 30, 30, + 14, 23, 23, 23,232,116, 58,188,252,242,203,216,191,127, 63, 24,134,129, 64, 32, 64,159, 62,125,192, 48, 76,223, 46,120,175, 54, +190,251,214, 42, 69,213,169, 29, 56,249,159, 90, 72, 60,122, 98,201,180,104,247,244,109,185, 75, 1, 36,119,199, 74, 24, 48, 96, + 0,150, 47, 95, 46, 89,186,116,105,151, 68, 22,195, 48, 43,248,124,254,208, 85,171, 86,137,167, 77,155,246,179,239,243,242,242, +144,144,144,208,164,215,235, 95,239,170,184,250,242,203, 47,165, 74,165, 18,165,165,165,248,165,207,132, 85, 92,109,223,190,221, +213,223,223, 31,145,145,145, 46,239,188,243,142,221, 34,139, 16,210,127,242,228,201,187, 55,110,220,232, 63, 99,198,140,146, 19, + 39, 78, 84, 16, 66,218, 19,226,218,231,159,127,190, 36, 43, 43, 43,132, 16,242, 85,103, 34,203,108, 54,247,146, 72, 36,208,233, +116,248,243,159,255,124, 71,128,170,117, 56, 27, 0, 52, 26, 13,212,106, 53,244,122,189,159, 61,247,172, 84, 42,221, 1,224,133, + 23, 94, 64,105,233,237,112, 69, 63, 63, 63,148,150,150,194,108, 54, 43, 29, 45, 71,165, 82,169, 52,153, 76,136,139,139,131, 94, +175, 7, 0, 60,241,196, 19,224,243,249,168,172,172, 4,195, 48, 30, 93,168, 30,207, 9, 19, 38,104,219,251,210,213,213,149,113, +119,119, 15,119,144,211, 35, 62, 62,254,218,134, 13, 27,126, 54, 84,151,155,155,251, 71,165, 82,153,163, 84, 42, 67,186,144, 87, +182,181,160,178, 30, 11,133, 66,171,199,193,174,183, 99,150,101,177,111,223, 62,208, 52, 13, 30,239,182, 73, 76, 75, 75,123, 81, +161, 80,120, 31, 58,116, 8,215,175, 95, 71, 67, 67, 3,234,235,235, 17, 20, 20,212,103,244,232,209,121,215,175, 95,191,114,254, +252,249,199,239,181, 19, 28,128, 53, 46, 44, 3,192,128,238,102,223, 90, 68,214, 84, 0, 39, 90,196,149, 17,192,148,123, 41,174, + 90,215, 61,143,199,179, 61,231, 46, 46, 46,136,138,138,178,137, 41, 66, 8, 26, 27, 27,193,227,241,172,241, 66,118, 25,191,218, +218, 90,248,250,248, 64, 46,151, 35, 40, 56, 24,133, 5, 5, 0, 96, 59, 22,137, 68, 32,132,192,108,238, 56, 42,160,101, 38,224, + 2,116, 16, 79,213, 69,113,201, 89,197, 80, 39,246, 31, 44,203, 90,109, 62,119, 55, 56, 61, 61, 61, 81, 95, 95,111, 23,231,125, + 43,176,150, 17, 66, 29, 9, 82,110, 74,158, 62, 98,122, 92,136, 59,244,186,203, 16,201, 61, 65, 20, 1, 88,183,254, 91, 92,184, +210, 28, 26,181,238,211, 83,216,178,232, 17, 64,172, 68, 95,153, 6,158, 82,201,227,237, 9,172,234,234,234, 6,147,201,164, 20, +139,197,224,241,120, 16, 10,133,168,170,170, 66, 90, 90, 26, 62,249,228, 19, 4, 4, 4,192, 98,177, 64, 36, 18,161,178,178, 18, + 2,129,192,161,217,137, 60, 30,153,144,254,194,248,222, 82,159, 96, 84,125,183,162,249,162,247, 64,204,142,167,132,239,236, 62, +251, 28, 33,228, 29,142,227, 42,187, 91, 37,200,100, 50, 68, 71, 71, 99,238,220,185,146,245,235,215,255, 3,128,218,145,191,215, +106,181, 63,170, 84,170,177, 75,150, 44,201,190,118,237,154, 56, 54, 54, 22, 50,153, 12, 50,153, 12, 23, 47, 94, 68, 82, 82,146, +222,104, 52, 78,236,138,119,140,207,231,103,141, 31, 63, 94, 42, 18,137, 80, 84, 84, 4,165, 82,249,139,238,213, 42,174,118,238, +220,233, 26, 18, 18,130, 75,151, 46, 97,200,144, 33,240,245,245,117,121,245,213, 87, 59, 21, 89, 45,111, 60,239,125,252,241,199, + 1, 60, 30,143,124,246,217,103,189, 1, 36,217,243,191,183,111,223, 30,186,107,215,174,181,132,144,199,184,118,130, 15, 5, 2, + 65,153, 78,167, 11,236,217,179, 39, 54,109,218, 4,138,162, 80, 94, 94,142,197,139, 23, 99,245,234,213,136,137,137,129, 92, 46, + 71,207,158, 61, 81, 84, 84, 4, 23, 23,151,114,123,254,247,181,107,215,170, 89,150,237,177,127,255,126,232,116, 58,219,117,127, +127,127,212,212,212,192, 96, 48, 84, 57, 90,150,101,101,101, 85, 0,188,243,242,242,112,229,202, 21,140, 27, 55, 14,159,127,254, + 57, 6, 15, 30,140,150,120,172,170, 46, 84,145,133,166,105,174,147,242,119,191,155,156, 45,157,150,163,156,224, 56,142,107, 45, +168,172,199,214,196,227,241,236, 9,242, 95, 21, 22, 22,182,172, 79,159, 62,225,169,169,169,124,154,166, 49,108,216,176,144,133, + 11, 23,150,184,184,184,120,188,246,218,107,146,182,156,193, 0,250,135,135,135, 75,187,129,249,104,237,165,235,150,147, 78, 8, + 33, 61, 90, 60,126, 66, 0, 76,203,231, 78, 66,200,168,214,129,239,247,210,131,181,108,217, 50,204,153, 51, 7,222,222,222, 72, + 73, 73, 1,143,199,179, 37, 66,136,205,163,229, 8,122,120,123,119,248,189, 53, 6,171,147,151,168,255,203, 50, 13,246,138,161, +230,126,149,103,151,247,238,255,193,121, 95, 10, 44,171,184, 74,121, 46,110,250,176, 16, 87,228, 28, 58,129,145,125, 41,192, 40, +236,192,132,154, 64, 4, 82,120,203, 41,117, 7,174,195,188,146,146,146, 94, 10,133, 2, 12,195, 64, 40, 20, 34, 50, 50, 18, 71, +143, 30,133,209,104,132,193, 96,176, 25,199,243,231,207,131, 97,152, 67, 14, 60, 44,180,183,156,255,126,114,234, 10, 57,242, 55, + 67, 33, 21, 98,228,160, 64,192, 35, 12,116,181, 6,107, 23,196, 43, 95, 92,179,103, 29,236,136,151,185, 23, 2,171,176,176, 16, +153,153,153,141, 6,131,225,185,174,112, 88, 69, 86, 70, 70, 70,182, 66,161, 16,255,225, 15,127, 64,126,126, 62, 94,125,245, 85, +189,209,104,156,208,213,248, 46,147,201, 52,227,171,175,190,218, 31, 24, 24, 40,141,139,139,187,195,221,221, 21,113, 69,211,244, +191,103,206,156, 41, 15, 8, 8, 64,113,113, 49,220,220,220, 32,147,201,208,187,119,111,236,216,177,195,229,233,167,159,238, 80, +100,113, 28,199, 17, 66, 18,159,124,242,201,189, 89, 89, 89,254, 51,102,204, 40,217,189,123,247, 94, 0,237, 25, 19,249,228,201, +147,227,179,178,178,252,103,205,154,165, 1,240, 23,174,131,153, 29, 44,203, 30, 41, 42, 42,234, 27, 22, 22, 70, 66, 66, 66, 32, + 20, 10,225,231,215,236,164,234,223,191, 63,194,195,195,193,231,243, 1, 0,133,133,133, 0,144,107,207,189, 31, 62,124,248,203, +130,130,130,153,131, 7, 15,166,125,124,124,108,193,179, 2,129, 0, 43, 87,174,100, 74, 74, 74,246, 57, 90,158, 7, 15, 30,252, + 60, 63, 63,255,133, 97,195,134,241,220,221,221, 33, 18,137,208,175, 95, 63,168, 84, 42,172, 92,185,146,185,124,249,242,190, 46, + 84,211,213,252,252,124,151,224,224,224, 54, 45,191, 88, 44,118, 5,224,168,231,161,244,248,241,227,194,216,216,216, 47,191,249, +230,155,200,214, 95, 68, 71, 71,127, 41,147,201,220, 0,148,119, 33,175,108,107, 65,101, 77,214, 33, 67,123, 4,150, 86,171,221, +235,227,227,243, 31,111,111,239, 31, 35, 34, 34,220,242,243,243,145,154,154, 42, 48, 24, 12,189,114,114,114,108, 29,113, 27,237, + 16, 13, 13, 13,226,110, 96, 62,146, 0,188, 11, 64, 2, 32,165, 27,138, 43,111, 52, 7,180,135,162,121, 88,240,137, 22,177,101, +141,201,186,167, 34,139,227, 56,240,249,124,132,134,134, 98,193,130, 5, 88,179,102, 13, 18, 19, 19, 17, 28, 28,108,171,123,107, +144,187, 35, 30, 44,129, 64, 0,111,111,239,230, 73, 39, 45,222, 43, 0, 40, 44, 40, 0,143,199, 3,203,178, 48, 26,141,157,122, +176,122,244,232,177,236,205, 55,223,156, 63,126,252,120,234,127,103,220, 89,151,149,104,157, 76, 38, 19,246,238,221, 59,127,245, +234,213,176,199,235, 69,211, 52,250,247,239,127,199,176,224,135, 31,222,142, 84,136,138,138,194,152, 49, 99,236, 18, 77,173, 57, + 67,211,223,190, 99, 88,240,107,175,219,197,214,243,217,217, 8, 94,245,129, 67,156,191, 85,180, 57, 71,242, 72,144, 98,101,202, + 51, 67,167, 15, 11,146,227,187, 67,167,177,238,235,203,151, 74,202,171,192, 86,228,131,213, 93, 68, 82, 66, 20,194, 3,148, 8, + 15, 80, 34, 41, 33, 10,108,229, 57,112, 53,197,224, 68, 10,148,214, 66,219,129,219,116,205,138, 21, 43,106,149, 74, 37,196, 98, + 49,132, 66, 33,202,202,202, 16, 17, 17, 1,145, 72,100,123, 3,165, 40, 10,169,169,169, 58,157, 78,183,222,222, 27,145, 10,169, +217,107, 94,121,194, 91,224, 34, 3, 74, 15,193, 85, 46,195,166,191,189, 13,212,107, 1, 90,128,248, 63, 12,160,125, 61, 21,163, + 8, 33, 33,221,173, 18,138,139,139, 49,127,254,252, 70,189, 94,255,139, 2,221,181, 90,237,143, 12,195,140, 93,189,122,117,211, +246,237,219,127,177,184,178,114, 26,141,198,113,239,190,251,110, 67, 81, 81,209, 47, 18, 88, 60, 30,239, 53,147,201,228,154,153, +153,201, 14, 26, 52,200,242,216, 99,143, 89,198,142, 29,107, 25, 50,100,136, 37, 34, 34,194, 50,101,202, 20,139, 94,175, 23, 73, + 36,146, 55, 59, 49,138, 23,118,239,222, 61,122,214,172, 89,154,172,172, 44,255,152,152, 24, 21,199,113, 75,219, 74,131, 7, 15, +246,182,138,171, 93,187,118,117, 26,131,101, 48, 24, 62,204,200,200,208, 91,103,185, 8,133, 66,120,121,121,217,132,176, 64, 32, +128, 72, 36, 2,195, 48,248,232,163,143,154,154,154,154,214,217,115,239, 85, 85, 85,155,147,147,147,175,102,103,103,155,234,234, +234, 64, 8,193,181,107,215,176,114,229, 74,102,195,134, 13,215,106,107,107, 55, 56, 90,158,117,117,117, 89,201,201,201, 87,246, +237,219,103,162, 40, 10, 53, 53, 53,112,117,117,181,113,222,186,117,203, 97,206, 33, 67,134, 20,149,148,148,184, 54, 54, 54,182, +229,205, 36, 82,169,244, 65, 0, 7, 29,225,140,138,138, 42,190,122,245,170,124,229,202,149, 63,140, 30, 61,122,141, 92, 46, 47, +144,203,229, 5,163, 71,143,126,243,131, 15, 62,248,151,139,139, 75, 52, 0,135, 55,135,165, 40,138,109,109, 55, 90,199, 96,137, + 68, 34, 8, 4, 2,187,150,169,112,115,115,219,146,145,145,225, 86, 94, 94, 14,131,193,128,188,188, 60,228,229,229,161,172,172, +204,214, 9,183,177, 15, 27, 26, 27, 27, 93,238,181,237,224, 56,238, 95, 28,199,245,231, 56, 46,144,227,184,238, 56, 73,230,211, + 86,226,106, 4,199,113,249, 0, 70,180,156, 71, 2,248,226, 94,122,176,172, 2,139,199,227, 97,218,180,105, 56,112,224, 0,130, +130,130,108,129,237,173,131,220, 29, 17, 4,102,179, 25,253,250,245,131,193,104,188, 67,160,243,120, 60,120,245,232,129,162,162, + 34,187, 60, 88,132,144,169,227,199,143,167,206,159, 63,143,176,176, 48,156, 58,117,202,150,242,242,242,112,246,236, 89,156, 59, +119, 14, 23, 46, 92,192,160, 65,131, 80, 82, 82,130, 71, 30,121,196,186, 76, 67,135, 77,199, 94,111,147,117, 38,160, 29,222,166, +255, 7,231,253,231,193, 82,123, 73,102, 12,237, 77,240,221,225,211,120, 63, 91,187,133,227,184,221,251,243,235,190,154, 51,200, + 12,102,215,211,232,151,240,207,230, 97, 65, 0,108,229, 57, 48,187,254, 4, 34,241, 68,110,133, 16,117,122, 83,187,111,205, 12, +195, 28,115,119,119,223,185,121,243,230,153,207, 63,255,188, 16, 0, 36, 18, 9,254,242,151,191,128,227, 56, 8,133, 66,208, 52, +141,185,115,231,214, 87, 86, 86,190,203,113, 92,145,157, 15,138,216,207, 93,152,250,204, 75,105, 46,200,219, 0, 80, 2,220,144, + 69,161,255, 35, 51, 81,169, 57, 10, 84, 93, 4,104, 1,214,167,191,224,249,199,121,111,111, 0, 16,215, 93, 42,224,220,185,115, +152, 55,111,222, 47, 22, 87,255,235,201,218,177, 99,199, 63,140, 70,227, 11,119,145,115, 92, 74, 74,202,126,111,111,239, 46, 15, +139,148,148,148, 60,235,239,239, 63,179,179, 7,175,184,184,184,211,161, 14,142,227, 46, 19, 66, 38, 94,185,114,229,245, 75,151, + 46,125,222,222,239, 46, 93,186,244,249,152, 49, 99,232, 99,199,142,189,102,207, 44,194, 83,167, 78,157,138,141,141,205, 88,183, +110,221,220,164,164, 36,177, 72, 36,130,171,171, 43, 52, 26,141,109, 29, 28,163,209,136, 69,139, 22, 53,153, 76,166, 45,199,143, + 31, 63,106,103, 71,104, 38,132, 60, 53,103,206,156, 89, 33, 33, 33,127,100, 89,214,195,104, 52, 86,149,148,148,236,187,117,235, + 86,151,214,193,226, 56,142, 37,132, 60, 61,119,238,220,233,193,193,193, 83, 24,134,241,176, 88, 44, 85, 87,175, 94,253,178,174, +174,110, 83, 87, 56,143, 28, 57,162,251,232,163,143,254,163,211,233,194,212,106,245, 77,153, 76,102, 52, 26,141,180, 88, 44,118, +149, 74,165, 81, 0,142, 2,184,224, 8,231,201,147, 39,175,175, 95,191,254,138,193, 96, 8, 93,191,126,253, 97, 87, 87,215, 3, +132, 16, 34, 16, 8,220,197, 98,241, 72, 0, 63, 0, 40,116, 52,175, 52, 77,119,232,193,130,157,241, 29,183,110,221, 58,150,158, +158, 62,104,224,192,129,200,200,200,168,150,201,100,242, 41, 83,166,240,106,107,107, 73, 71, 30,172,238, 32,176,126, 3,168,106, +241,242, 78,178,198, 92,181, 10,124,255, 20, 64,237, 61, 22,168,119, 8,169, 94,189,122,217,206, 91,167, 86, 49, 88,118,193, 98, +177, 64, 32, 16,128,199,227,193, 87,165,178,137, 57,142,227, 80, 84, 84,132,234,234,106,187, 4, 22, 69, 81, 52, 33, 4, 79, 62, +249,164, 93,255,247,169,167,158,194, 15, 63,252,128,206,134, 19, 91,207,248, 11, 8, 8,232, 84, 12,181,228,197,238, 89,132,106, +181,250,174,112,222,151, 2,235,170, 78,191,114,193,134,227,139,138, 43, 13,187, 31, 42,172, 89,144, 14,112,128,123,118,152,146, +140,141,163,202, 96,216, 48, 12,196,181,185,179,225,234,203, 65,164,222, 40,135, 26,239,101, 23, 95, 55,113, 76,135,222,135,218, +218,218,164, 15, 63,252,144,206,206,206,126, 98,245,234,213,110, 97, 97, 97,248,211,159,254, 4,163,209,136,179,103,207, 98,206, +156, 57,213, 58,157, 46,179,182,182,118,141,189, 55,225, 41,227,253,117,221,203, 99, 61, 40, 83, 61,112,253, 20, 32,114,131,167, +187, 12,103,114, 15, 1,215, 79, 2,180, 0,160,133, 24,252, 64, 24,250,135, 7,134, 17, 66,134,113, 28,247,239,238, 80, 1,143, + 63,254,248, 93, 19, 87,173, 5, 17,128, 62,119, 51,159, 86,145, 53,125,250,244,253, 44,203, 74,186,226,222,109, 89,147,201,114, + 23,141,227,101,116, 50,228,219,178,124,195, 46, 71,120, 77, 38,211,162,252,252,124,204,157, 59,119,238,179,207, 62, 43, 14, 9, + 9, 65, 64, 64, 0, 10, 10, 10,160,209,104,144,153,153,217,100, 54,155, 55,213,214,214,190,218,133,251,207,108, 73,119,171, 12, + 88, 0,155, 91,210, 93, 65, 98, 98,226,153,226,226,226, 42, 47, 47,175, 24,129, 64,240, 0,154,227,124,174,183,252,143,194,174, +112,206,153, 51, 39,175,184,184,248,134,159,159, 95,108, 11,167, 2,192, 53, 0, 27,187,200, 89,149,151,151, 23, 24, 29, 29,205, +242,120, 60,174,197,195,192,241,249,124,142,207,231,115, 0,144,157,157, 45, 2,208,105,204,101,121,121,249,159,247,236,217,131, +156,156,156,152,250,250,250,103, 0,252,163,177,177, 49,250,230,205,155,182, 78,184, 29,111,167,200,169,159, 58,109,159,143,181, +115,189, 2,192,176,110,144, 63, 44, 95,190, 28,153,153,153,232,108, 5,242,189,123,247, 2,157, 12, 17, 90,219,138, 85, 60, 49, + 12,131,115,231,206, 89,247,222,179, 13, 11, 90,151,104, 48,155,205, 29,174,244,206,178,172,197,104, 52,226,227,143, 63,182, 75, +100,237,216,177, 3,122,189, 30, 44,203,218,101,103, 91, 22, 38, 69,117,117, 53, 84, 42,149,213,227,220,218, 41,226,112,153,210, + 52,141,208,208, 80,220,184,113, 3,158,158,158, 0,154,135, 5,109,222,189,134,134,223, 77,251,239,112,161,209,214, 24, 17,160, +112,163, 4,100,207,195, 65,130, 17, 19,251,201,209,211, 75, 6,158, 80,132,202, 58, 11,254, 93, 92,143, 79,142,234, 74,141, 22, +203,196, 3,154,154,124, 59,189, 78,177,190,190,190,139, 45, 22, 75, 36, 69, 81, 18,142,227,234,105,154, 62,173,213,106,151,113, + 28,119,206,145,155, 80,136,233, 66,119, 41,237,198,231, 11, 57, 11,203, 2,160, 0, 98, 77,116,243, 39,213,124,222,164,103, 4, + 22,142,236,174,208,221,152,117,175, 11, 63, 36, 36, 36,187,161,161,225, 55,183,146,187, 84, 42, 93, 90, 88, 88,120,223,174,228, +110,197,131, 15, 62, 56, 88, 44, 22, 47,102, 89,246, 65,189, 94,239, 35, 22,139, 43, 8, 33, 39,110,221,186,245,198,233,211,167, +127,114,118,159,247, 14,119,115, 37,247, 54,218,120, 60,128,101, 30, 30, 30, 33,103,207,158, 21,181,246, 96,181,182,151,142,172, +139,228, 68,247, 67,120,120,248,177,237,219,183, 15,238,213,171, 23,213, 58,144,157,162, 40,219,226,152, 20, 69,217,102,150,254, +244,211, 79,230,196,196,196,163,121,121,121,195,219,227, 12, 10, 10,202,206,201,201, 25, 83, 91, 91,251, 51, 33,213,122,101,119, +235,121, 83, 83, 19,254,250,215,191,126, 87, 88, 88,216,230, 86, 57, 97, 97, 97,239,166,166,166,206,127,244,209, 71, 41,138,162, +126, 22,115,101,221,214,199,154, 24,134,193,238,221,187,217,172,172,172,247, 47, 94,188,216,110, 12, 86, 84, 84, 84,233,169, 83, +167,212,214, 37, 19,218, 75,173, 17, 27, 27, 91,254,211, 79, 63,169,126, 77,206,223,141,192,106, 49, 40,100, 84,144,226, 9,142, + 35, 83, 9, 72, 63,138,112, 66, 51, 7, 13, 1,178, 37,141,162,143,246,106,181, 77,206,199,214,137,251,242, 65, 33,132,114,110, +242,251,251, 66, 80, 80, 80, 97, 97, 97, 97, 96, 7,109,194, 41,176,126,227, 34,221,203,203,235, 0, 69, 81,254, 86, 17,221,222, +103,139, 55,233, 74, 69, 69,197,195, 21, 21, 21,237,174,167,168, 86,171,251,186,184,184,252,141,101,217,104,123, 54,123,166, 40, + 42, 87,175,215,191,244,107,111,246, 28, 25, 25, 89,148,155,155,219, 87, 44, 22,223, 17, 87,104,189,231,255,205,251,229,203,151, + 49,121,242,228,146,188,188,188,128, 95,147,243,119, 37,176,156,112,194, 9, 39,126, 47,240,243,243, 59,198, 48, 76,152, 94,175, +231, 27, 12, 6,190,217,108,190,163,131, 19,139,197,186,198,198,198, 30,206,146,114,226,183, 6,149, 74, 21,162, 80, 40,190,229, +243,249,162,182, 94, 28,254, 23, 22,139, 69, 95, 85, 85, 53, 78,171,213,106,126, 77,206,223, 60,218,154, 33,115,183, 18,128,209, + 78, 78, 39,167,147,211,201,233,228,116,114, 58, 57,157,156,191,183, 68, 57,181,188, 19, 78, 56,225,132, 19, 78, 56,225,196,221, +133, 83, 96, 57,225,132, 19, 78, 56,225,132, 19, 78, 56, 5,150, 19, 78, 56,225,132, 19, 78, 56,225,132, 83, 96, 57,225,132, 19, + 78, 56,225,132, 19, 78,252,174,240,223, 1, 0, 29, 13,182,141,194,138, 6,132, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, 0}; diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 010101a1a80..f16fc9ebe05 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -101,7 +101,7 @@ DEF_ICON(ICON_RENDER_REGION) DEF_ICON(ICON_BORDER_RECT) DEF_ICON(ICON_BORDER_LASSO) DEF_ICON(ICON_FREEZE) -DEF_ICON(ICON_BLANK031) +DEF_ICON(ICON_STYLUS_PRESSURE) DEF_ICON(ICON_BLANK032) DEF_ICON(ICON_BLANK033) DEF_ICON(ICON_BLANK034) @@ -241,7 +241,7 @@ DEF_ICON(ICON_BLANK080F) DEF_ICON(ICON_BOIDS) DEF_ICON(ICON_STRANDS) DEF_ICON(ICON_LIBRARY_DATA_INDIRECT) -DEF_ICON(ICON_BLANK082) +DEF_ICON(ICON_GREASEPENCIL) DEF_ICON(ICON_BLANK083) DEF_ICON(ICON_BLANK084) DEF_ICON(ICON_GROUP_BONE) @@ -538,7 +538,7 @@ DEF_ICON(ICON_MOD_CLOTH) DEF_ICON(ICON_MOD_EXPLODE) DEF_ICON(ICON_MOD_FLUIDSIM) DEF_ICON(ICON_MOD_MULTIRES) -DEF_ICON(ICON_BLANK157) +DEF_ICON(ICON_MOD_SMOKE) DEF_ICON(ICON_BLANK158) DEF_ICON(ICON_BLANK159) DEF_ICON(ICON_BLANK160) @@ -686,10 +686,10 @@ DEF_ICON(ICON_BLANK231) DEF_ICON(ICON_BLANK232) DEF_ICON(ICON_BLANK233) DEF_ICON(ICON_BLANK234) -DEF_ICON(ICON_BLANK235) -DEF_ICON(ICON_BLANK236) -DEF_ICON(ICON_BLANK237) -DEF_ICON(ICON_BLANK238) +DEF_ICON(ICON_UV_VERTEXSEL) +DEF_ICON(ICON_UV_EDGESEL) +DEF_ICON(ICON_UV_FACESEL) +DEF_ICON(ICON_UV_ISLANDSEL) DEF_ICON(ICON_BLANK239) DEF_ICON(ICON_BLANK240) DEF_ICON(ICON_BLANK241) diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 2eb070e0e6d..21fccdc65f8 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -521,13 +521,13 @@ void brush_buttons(const bContext *C, uiBlock *block, short fromsima, uiBlockBeginAlign(block); uiDefButF(block, COL, B_VPCOLSLI, "", 0,yco,200,19, brush->rgb, 0, 0, 0, 0, ""); uiDefButF(block, NUMSLI, evt_nop, "Opacity ", 0,yco-20,180,19, &brush->alpha, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); - uiDefButBitS(block, TOG|BIT, BRUSH_ALPHA_PRESSURE, evt_nop, "P", 180,yco-20,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefIconButBitS(block, TOG|BIT, BRUSH_ALPHA_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-20,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiDefButI(block, NUMSLI, evt_nop, "Size ", 0,yco-40,180,19, &brush->size, 1, 200, 0, 0, "The size of the brush"); - uiDefButBitS(block, TOG|BIT, BRUSH_SIZE_PRESSURE, evt_nop, "P", 180,yco-40,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefIconButBitS(block, TOG|BIT, BRUSH_SIZE_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-40,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush"); - uiDefButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, "P", 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefIconButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiDefButF(block, NUMSLI, evt_nop, "Spacing ",0,yco-80,180,19, &brush->spacing, 1.0, 100.0, 0, 0, "Repeating paint on %% of brush diameter"); - uiDefButBitS(block, TOG|BIT, BRUSH_SPACING_PRESSURE, evt_nop, "P", 180,yco-80,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefIconButBitS(block, TOG|BIT, BRUSH_SPACING_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-80,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiBlockEndAlign(block); yco -= 110; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 9c453ac44df..448a2046855 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -166,18 +166,22 @@ void rna_def_brush(BlenderRNA *brna) prop= RNA_def_property(srna, "strength_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength."); prop= RNA_def_property(srna, "size_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SIZE_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size."); prop= RNA_def_property(srna, "falloff_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RAD_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Falloff Pressure", "Enable tablet pressure sensitivity for falloff."); prop= RNA_def_property(srna, "spacing_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACING_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Spacing Pressure", "Enable tablet pressure sensitivity for spacing."); prop= RNA_def_property(srna, "rake", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 5caa868fd2e..72e77e93607 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -223,7 +223,7 @@ void rna_def_gpencil_data(BlenderRNA *brna) srna= RNA_def_struct(brna, "GreasePencil", "ID"); RNA_def_struct_sdna(srna, "bGPdata"); RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook."); - RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA); // XXX: ICON_GPENCIL!!! + RNA_def_struct_ui_icon(srna, ICON_GREASEPENCIL); /* Layers */ prop= RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index f8c8ddb9431..295cb460f5b 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -75,7 +75,7 @@ EnumPropertyItem modifier_type_items[] ={ {eModifierType_Fluidsim, "FLUID_SIMULATION", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""}, {eModifierType_ParticleInstance, "PARTICLE_INSTANCE", ICON_MOD_PARTICLES, "Particle Instance", ""}, {eModifierType_ParticleSystem, "PARTICLE_SYSTEM", ICON_MOD_PARTICLES, "Particle System", ""}, - {eModifierType_Smoke, "SMOKE", 0, "Smoke", ""}, + {eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""}, {eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""}, {eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 935bf8ccc3f..bd29443646d 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -394,10 +394,10 @@ static void rna_def_tool_settings(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem uv_select_mode_items[] = { - {UV_SELECT_VERTEX, "VERTEX", ICON_VERTEXSEL, "Vertex", "Vertex selection mode."}, - {UV_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edge", "Edge selection mode."}, - {UV_SELECT_FACE, "FACE", ICON_FACESEL, "Face", "Face selection mode."}, - {UV_SELECT_ISLAND, "ISLAND", ICON_LINKEDSEL, "Island", "Island selection mode."}, + {UV_SELECT_VERTEX, "VERTEX", ICON_UV_VERTEXSEL, "Vertex", "Vertex selection mode."}, + {UV_SELECT_EDGE, "EDGE", ICON_UV_EDGESEL, "Edge", "Edge selection mode."}, + {UV_SELECT_FACE, "FACE", ICON_UV_FACESEL, "Face", "Face selection mode."}, + {UV_SELECT_ISLAND, "ISLAND", ICON_UV_ISLANDSEL, "Island", "Island selection mode."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem mesh_select_mode_items[] = { -- cgit v1.2.3 From a83aa92e80aace4509ab26a98d805c3cb2b2683e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 7 Sep 2009 11:05:16 +0000 Subject: 2.5 - Armature/Pose Bugfixes: * Added missing prototype from arithb * Added define for Axis-Angle rotations. This has not yet been hooked up for actual usage yet, since there are some issues regarding evaluation which I'd like to investigate further first. * Editing numbuttons for posechannel transforms now updates in realtime. Sending ND_POSE|ND_TRANSFORM was causing confusion for the listeners (which only check for either/or) * Partial fix for axis drawing on bones. Now the axes are drawn at the tips of the bones again, but unfortunately the texts aren't (since they only use the object matrix, they get drawn at the origin). --- source/blender/blenlib/BLI_arithb.h | 1 + source/blender/editors/space_view3d/drawarmature.c | 4 +- source/blender/makesdna/DNA_action_types.h | 5 ++ source/blender/makesrna/intern/rna_pose.c | 58 ++++++++++++---------- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 6deb6edf9fb..71604758b80 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -377,6 +377,7 @@ void Vec2Copyf(float *v1, float *v2); void Vec2Lerpf(float *target, float *a, float *b, float t); void AxisAngleToQuat(float *q, float *axis, float angle); +void QuatToAxisAngle(float *q, float *axis, float *angle); void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]); void vectoquat(float *vec, short axis, short upflag, float *q); diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index a5718386554..fa810677fe8 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1816,7 +1816,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) { glPushMatrix(); glMultMatrixf(pchan->pose_mat); - //glTranslatef(0.0f, pchan->bone->length, 0.0f); + glTranslatef(0.0f, pchan->bone->length, 0.0f); drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS); glPopMatrix(); } @@ -2000,7 +2000,7 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) if (arm->flag & ARM_DRAWAXES) { glPushMatrix(); set_matrix_editbone(eBone); - //glTranslatef(0.0f, eBone->length, 0.0f); + glTranslatef(0.0f, eBone->length, 0.0f); drawaxes(eBone->length*0.25f, 0, OB_ARROWS); glPopMatrix(); } diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 474d5a4217f..318204e3dd8 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -206,6 +206,11 @@ typedef enum ePchan_RotMode { PCHAN_ROT_YZX, PCHAN_ROT_ZXY, PCHAN_ROT_ZYX, + /* NOTE: space is reserved here for 18 other possible + * euler rotation orders not implemented + */ + /* axis angle rotations */ + PCHAN_ROT_AXISANGLE = -1 } ePchan_RotMode; /* Pose ------------------------------------ */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index c5297f7b7fa..6c2018c61f4 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -137,7 +137,7 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) /* check if any change - if so, need to convert data */ // TODO: this needs to be generalised at some point to work for objects too... if (value > 0) { /* to euler */ - if (pchan->rotmode < 0) { // FIXME: need a define for this + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { /* axis-angle to euler */ float m[3][3]; @@ -154,7 +154,7 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) /* else { no conversion needed } */ } else if (value == PCHAN_ROT_QUAT) { /* to quat */ - if (pchan->rotmode < 0) { // FIXME: need a define for this + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { /* axis angle to quat */ float q[4]; @@ -169,13 +169,13 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) /* else { no conversion needed } */ } else { /* to axis-angle */ - if (pchan->rotmode > 0) { // FIXME: need a define for this + if (pchan->rotmode > 0) { /* euler to axis angle */ float q[4]; /* convert to temp quat, then to axis angle (since stored in same var) */ EulOToQuat(pchan->eul, pchan->rotmode, q); - QuatToAxisAngle(q, &pchan->quat[1], pchan->quat[0]); + QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); } else if (pchan->rotmode == PCHAN_ROT_QUAT) { /* quat to axis angle */ @@ -183,7 +183,7 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) /* copy to temp var first, since quats and axis-angle are stored in same place */ QuatCopy(q, pchan->quat); - QuatToAxisAngle(q, &pchan->quat[1], pchan->quat[0]); + QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); } } @@ -420,6 +420,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) {PCHAN_ROT_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"}, {PCHAN_ROT_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"}, {PCHAN_ROT_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"}, + //{PCHAN_ROT_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."}, {0, NULL, 0, NULL, NULL}}; StructRNA *srna; @@ -479,30 +480,30 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "loc"); RNA_def_property_ui_text(prop, "Location", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Scale", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_QUATERNION); RNA_def_property_float_sdna(prop, NULL, "quat"); RNA_def_property_ui_text(prop, "Rotation", "Rotation in Quaternions."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); prop= RNA_def_property(srna, "euler_rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "eul"); RNA_def_property_float_funcs(prop, "rna_PoseChannel_euler_rotation_get", "rna_PoseChannel_euler_rotation_set", NULL); RNA_def_property_ui_text(prop, "Rotation (Euler)", "Rotation in Eulers."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "rotmode"); RNA_def_property_enum_items(prop, prop_rotmode_items); RNA_def_property_enum_funcs(prop, NULL, "rna_PoseChannel_rotation_mode_set", NULL); RNA_def_property_ui_text(prop, "Rotation Mode", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); /* These three matrix properties await an implementation of the PROP_MATRIX subtype, which currently doesn't exist. */ /* prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX); @@ -535,97 +536,97 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_PoseChannel_has_ik_get", NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Has IK", "Is part of an IK chain."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_dof_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "ikflag", BONE_IK_NO_XDOF); RNA_def_property_ui_text(prop, "IK X DoF", "Allow movement around the X axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_dof_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "ikflag", BONE_IK_NO_YDOF); RNA_def_property_ui_text(prop, "IK Y DoF", "Allow movement around the Y axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_dof_z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "ikflag", BONE_IK_NO_ZDOF); RNA_def_property_ui_text(prop, "IK Z DoF", "Allow movement around the Z axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_limit_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_XLIMIT); RNA_def_property_ui_text(prop, "IK X Limit", "Limit movement around the X axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_limit_y", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_YLIMIT); RNA_def_property_ui_text(prop, "IK Y Limit", "Limit movement around the Y axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_limit_z", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_ZLIMIT); RNA_def_property_ui_text(prop, "IK Z Limit", "Limit movement around the Z axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_min_x", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "limitmin[0]"); RNA_def_property_range(prop, -180.0f, 0.0f); RNA_def_property_ui_text(prop, "IK X Minimum", "Minimum angles for IK Limit"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_max_x", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "limitmax[0]"); RNA_def_property_range(prop, 0.0f, 180.0f); RNA_def_property_ui_text(prop, "IK X Maximum", "Maximum angles for IK Limit"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_min_y", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "limitmin[1]"); RNA_def_property_range(prop, -180.0f, 0.0f); RNA_def_property_ui_text(prop, "IK Y Minimum", "Minimum angles for IK Limit"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_max_y", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "limitmax[1]"); RNA_def_property_range(prop, 0.0f, 180.0f); RNA_def_property_ui_text(prop, "IK Y Maximum", "Maximum angles for IK Limit"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_min_z", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "limitmin[2]"); RNA_def_property_range(prop, -180.0f, 0.0f); RNA_def_property_ui_text(prop, "IK Z Minimum", "Minimum angles for IK Limit"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_max_z", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "limitmax[2]"); RNA_def_property_range(prop, 0.0f, 180.0f); RNA_def_property_ui_text(prop, "IK Z Maximum", "Maximum angles for IK Limit"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_stiffness_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness[0]"); RNA_def_property_range(prop, 0.0f, 0.99f); RNA_def_property_ui_text(prop, "IK X Stiffness", "IK stiffness around the X axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_stiffness_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness[1]"); RNA_def_property_range(prop, 0.0f, 0.99f); RNA_def_property_ui_text(prop, "IK Y Stiffness", "IK stiffness around the Y axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_stiffness_z", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness[2]"); RNA_def_property_range(prop, 0.0f, 0.99f); RNA_def_property_ui_text(prop, "IK Z Stiffness", "IK stiffness around the Z axis."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "ik_stretch", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ikstretch"); RNA_def_property_range(prop, 0.0f,1.0f); RNA_def_property_ui_text(prop, "IK Stretch", "Allow scaling of the bone for IK."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); /* custom bone shapes */ prop= RNA_def_property(srna, "custom_shape", PROP_POINTER, PROP_NONE); @@ -655,16 +656,19 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_LOCX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Location", "Lock editing of location in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "lock_scale", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_SCALEX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Scale", "Lock editing of scale in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); } static void rna_def_pose(BlenderRNA *brna) -- cgit v1.2.3 From fcf1040473da1f9b4bf9df5662b763cd7e2f616a Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 7 Sep 2009 11:51:19 +0000 Subject: 2.5: * New Smoke Modifier icon was missing in the Smoke RNA struct. --- source/blender/makesrna/intern/rna_modifier.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 295cb460f5b..28223d2f80b 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1568,6 +1568,7 @@ static void rna_def_modifier_smoke(BlenderRNA *brna) srna= RNA_def_struct(brna, "SmokeModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Smoke Modifier", "Smoke simulation modifier."); RNA_def_struct_sdna(srna, "SmokeModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_SMOKE); prop= RNA_def_property(srna, "domain_settings", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "domain"); -- cgit v1.2.3 From f4f51efa5106d53a4aacf145d644934f6ccd6f65 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 7 Sep 2009 11:59:05 +0000 Subject: 2.5: * Use new Pressure Size Icons, old ones were still defined in the py file. --- release/ui/space_view3d_toolbar.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 8a42d9683f8..43772f7a072 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -333,12 +333,12 @@ class VIEW3D_PT_tools_brush(PaintPanel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "size_pressure", toggle=True, text="") if brush.sculpt_tool != 'GRAB': row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "strength_pressure", text="") col = layout.column() @@ -367,11 +367,11 @@ class VIEW3D_PT_tools_brush(PaintPanel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "strength_pressure", toggle=True, text="") col.itemR(brush, "blend") @@ -383,11 +383,11 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column() row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "strength_pressure", toggle=True, text="") # Vertex Paint Mode # @@ -397,11 +397,11 @@ class VIEW3D_PT_tools_brush(PaintPanel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "strength_pressure", toggle=True, text="") class VIEW3D_PT_tools_brush_stroke(PaintPanel): __label__ = "Stroke" @@ -443,7 +443,7 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel): row.active = brush.space row.itemR(brush, "spacing", text="Distance", slider=True) if texture_paint: - row.itemR(brush, "spacing_pressure", toggle=True, icon='ICON_BRUSH_DATA', text="") + row.itemR(brush, "spacing_pressure", toggle=True, text="") class VIEW3D_PT_tools_brush_curve(PaintPanel): __label__ = "Curve" @@ -573,8 +573,7 @@ class VIEW3D_PT_tools_texturepaint(View3DPanel): col = split.column() col.active = (ipaint.use_normal_falloff and use_projection) col.itemR(ipaint, "normal_angle", text="") - - + split = layout.split(percentage=0.7) col = split.column(align=False) @@ -584,8 +583,7 @@ class VIEW3D_PT_tools_texturepaint(View3DPanel): col = split.column(align=False) col.active = (use_projection and ipaint.use_stencil_layer) col.itemR(ipaint, "invert_stencil", text="Inv") - - + col = layout.column() sub = col.column() sub.active = (settings.tool == 'CLONE') -- cgit v1.2.3 From 70c4898db8b870a853a1c0dec4c47b34c75b3148 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 7 Sep 2009 14:58:08 +0000 Subject: 2.5: * Fixed a Typo in Particle Effector Panel. Reported by Jack*RED on graphicall. Thanks! --- source/blender/makesrna/intern/rna_particle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 71b953effdf..719e6f43eed 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1749,7 +1749,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "effector_weight[6]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Magnetic", "Texture effector weight."); + RNA_def_property_ui_text(prop, "Texture", "Texture effector weight."); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_harmonic", PROP_FLOAT, PROP_NONE); -- cgit v1.2.3 From 4c859897f623f8996b5aa239bd6cbfd290204672 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Sep 2009 15:02:43 +0000 Subject: - crash fix for setting a curve smooth operator - added curve attribute use_twist_correction - added nurb attribute type - NURBS, POLY, BEZIER - renamed a number of curve attributes with the use_ prefix. - UI layout adjustments to only show buttons that are needed and reflect internals for nurbs. ... Note that many of the buttons only apply to NURBS, and all the "V" buttons only apply to surfaces, remove when not needed. --- release/ui/buttons_data_curve.py | 107 +++++++++++++++++++--------- source/blender/editors/object/object_edit.c | 1 - source/blender/makesrna/intern/rna_curve.c | 46 ++++++++++-- 3 files changed, 113 insertions(+), 41 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index ced3c6597e0..46311493ad3 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -6,6 +6,13 @@ class DataButtonsPanel(bpy.types.Panel): __region_type__ = 'WINDOW' __context__ = "data" + def poll(self, context): + return (context.object and context.object.type in ('CURVE', 'SURFACE') and context.curve) + +class DataButtonsPanelCurve(DataButtonsPanel): + ''' + Same as above but for curves only + ''' def poll(self, context): return (context.object and context.object.type == 'CURVE' and context.curve) @@ -37,17 +44,24 @@ class DATA_PT_shape_curve(DataButtonsPanel): ob = context.object curve = context.curve space = context.space_data + is_surf = (ob.type == 'SURFACE') - layout.itemR(curve, "curve_2d") + row = layout.row() + row.itemR(curve, "curve_2d") + row.itemR(curve, "use_twist_correction") + split = layout.split() col = split.column() - sub = col.column() - sub.active = curve.curve_2d - sub.itemL(text="Caps:") - sub.itemR(curve, "front") - sub.itemR(curve, "back") + + if not is_surf: + sub = col.column() + sub.active = curve.curve_2d + sub.itemL(text="Caps:") + row = sub.row() + row.itemR(curve, "front") + row.itemR(curve, "back") col.itemL(text="Textures:") # col.itemR(curve, "uv_orco") @@ -58,23 +72,26 @@ class DATA_PT_shape_curve(DataButtonsPanel): sub = col.column(align=True) sub.itemR(curve, "resolution_u", text="Preview U") sub.itemR(curve, "render_resolution_u", text="Render U") - sub = col.column(align=True) - sub.itemR(curve, "resolution_v", text="Preview V") - sub.itemR(curve, "render_resolution_v", text="Render V") + + if is_surf: + sub = col.column(align=True) + sub.itemR(curve, "resolution_v", text="Preview V") + sub.itemR(curve, "render_resolution_v", text="Render V") + # col.itemL(text="Display:") # col.itemL(text="HANDLES") # col.itemL(text="NORMALS") # col.itemR(curve, "vertex_normal_flip") -class DATA_PT_geometry_curve(DataButtonsPanel): +class DATA_PT_geometry_curve(DataButtonsPanelCurve): __label__ = "Geometry " def draw(self, context): layout = self.layout curve = context.curve - + split = layout.split() col = split.column() @@ -88,31 +105,32 @@ class DATA_PT_geometry_curve(DataButtonsPanel): col.itemR(curve, "bevel_depth", text="Depth") col.itemR(curve, "bevel_resolution", text="Resolution") col.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE') + -class DATA_PT_pathanim(DataButtonsPanel): +class DATA_PT_pathanim(DataButtonsPanelCurve): __label__ = "Path Animation" def draw_header(self, context): curve = context.curve - self.layout.itemR(curve, "path", text="") + self.layout.itemR(curve, "use_path", text="") def draw(self, context): layout = self.layout curve = context.curve - layout.active = curve.path + layout.active = curve.use_path split = layout.split() col = split.column() col.itemR(curve, "path_length", text="Frames") - col.itemR(curve, "follow") + col.itemR(curve, "use_path_follow") col = split.column() - col.itemR(curve, "stretch") - col.itemR(curve, "offset_path_distance", text="Offset Children") + col.itemR(curve, "use_stretch") + col.itemR(curve, "use_time_offset", text="Offset Children") class DATA_PT_current_curve(DataButtonsPanel): __label__ = "Current Curve" @@ -120,33 +138,56 @@ class DATA_PT_current_curve(DataButtonsPanel): def draw(self, context): layout = self.layout + ob = context.object currentcurve = context.curve.curves[0] # XXX - + is_surf = (ob.type == 'SURFACE') + split = layout.split() - + col = split.column() col.itemL(text="Cyclic:") - col.itemR(currentcurve, "cyclic_u", text="U") - col.itemR(currentcurve, "cyclic_v", text="V") - col.itemL(text="Order:") - col.itemR(currentcurve, "order_u", text="U") - col.itemR(currentcurve, "order_v", text="V") - col.itemL(text="Endpoints:") - col.itemR(currentcurve, "endpoint_u", text="U") - col.itemR(currentcurve, "endpoint_v", text="V") + if currentcurve.type == 'NURBS': + col.itemL(text="Bezier:") + col.itemL(text="Endpoint:") + col.itemL(text="Order:") + col.itemL(text="Resolution:") + col = split.column() - col.itemL(text="Bezier:") - col.itemR(currentcurve, "bezier_u", text="U") - col.itemR(currentcurve, "bezier_v", text="V") - col.itemL(text="Resolution:") + col.itemR(currentcurve, "cyclic_u", text="U") + + if currentcurve.type == 'NURBS': + sub = col.column() + sub.active = (not currentcurve.cyclic_u) + sub.itemR(currentcurve, "bezier_u", text="U") + sub.itemR(currentcurve, "endpoint_u", text="U") + + sub = col.column() + sub.itemR(currentcurve, "order_u", text="U") col.itemR(currentcurve, "resolution_u", text="U") - col.itemR(currentcurve, "resolution_v", text="V") + + if is_surf: + col = split.column() + col.itemR(currentcurve, "cyclic_v", text="V") + + # its a surface, assume its a nurb. + sub = col.column() + sub.active = (not currentcurve.cyclic_v) + sub.itemR(currentcurve, "bezier_v", text="V") + sub.itemR(currentcurve, "endpoint_v", text="V") + sub = col.column() + sub.itemR(currentcurve, "resolution_v", text="V") + sub.itemR(currentcurve, "order_v", text="V") + + + split = layout.split() + col = split.column() col.itemL(text="Interpolation:") col.itemR(currentcurve, "tilt_interpolation", text="Tilt") - col.itemR(currentcurve, "radius_interpolation", text="Tilt") + col.itemR(currentcurve, "radius_interpolation", text="Radius") col.itemR(currentcurve, "smooth") + bpy.types.register(DATA_PT_context_curve) bpy.types.register(DATA_PT_shape_curve) bpy.types.register(DATA_PT_geometry_curve) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index a5d365cafd4..d226834bc21 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -6816,7 +6816,6 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) for(nu=cu->nurb.first; nu; nu=nu->next) { if(!clear) nu->flag |= ME_SMOOTH; else nu->flag &= ~ME_SMOOTH; - nu= nu->next; } DAG_id_flush_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index d19a2289490..8c805c11f78 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -148,6 +148,20 @@ static int rna_Nurb_length(PointerRNA *ptr) return nu->pntsv>0 ? nu->pntsu*nu->pntsv : nu->pntsu; } +/* grr! mixing CU_2D with type is dodgy */ +static int rna_Nurb_type_get(PointerRNA *ptr) +{ + Nurb *nu= (Nurb*)ptr->data; + return nu->type & 7; +} + +static void rna_Nurb_type_set(PointerRNA *ptr, int value) +{ + Nurb *nu= (Nurb*)ptr->data; + nu->type &= CU_2D; + nu->type |= value; +} + static void rna_BPoint_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Nurb *nu= (Nurb*)ptr->data; @@ -161,7 +175,6 @@ static void rna_Curve_update_data(bContext *C, PointerRNA *ptr) DAG_id_flush_update(id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } - #else static void rna_def_bpoint(BlenderRNA *brna) @@ -203,7 +216,7 @@ static void rna_def_bpoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "bevel_radius", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "radius"); /*RNA_def_property_range(prop, 0.0f, 1.0f);*/ RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -297,7 +310,7 @@ static void rna_def_beztriple(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "bevel_radius", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "radius"); /*RNA_def_property_range(prop, 0.0f, 1.0f);*/ RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -317,22 +330,22 @@ static void rna_def_path(BlenderRNA *brna, StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); /* flags */ - prop= RNA_def_property(srna, "path", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_path", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_PATH); RNA_def_property_ui_text(prop, "Path", "Enable the curve to become a translation path."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "follow", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_path_follow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_FOLLOW); RNA_def_property_ui_text(prop, "Follow", "Make curve path children to rotate along the path."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "stretch", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_stretch", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_STRETCH); RNA_def_property_ui_text(prop, "Stretch", "Option for curve-deform: makes deformed child to stretch along entire path."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "offset_path_distance", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_time_offset", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_OFFS_PATHDIST); RNA_def_property_ui_text(prop, "Offset Path Distance", "Children will use TimeOffs value as path distance offset."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); @@ -677,6 +690,11 @@ static void rna_def_curve(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Back", "Draw filled back for extruded/beveled curves."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + prop= RNA_def_property(srna, "use_twist_correction", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_NO_TWIST); + RNA_def_property_ui_text(prop, "Minimal Twist", "Correct for twisting."); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + prop= RNA_def_property(srna, "retopo", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_RETOPO); RNA_def_property_ui_text(prop, "Retopo", "Turn on the re-topology tool."); @@ -685,6 +703,14 @@ static void rna_def_curve(BlenderRNA *brna) static void rna_def_curve_nurb(BlenderRNA *brna) { + static EnumPropertyItem curve_type_items[] = { + {CU_POLY, "POLY", 0, "Poly", ""}, + {CU_BEZIER, "BEZIER", 0, "Bezier", ""}, + {CU_BSPLINE, "BSPLINE", 0, "BSpline", ""}, + {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""}, + {CU_NURBS, "NURBS", 0, "Ease", ""}, + {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem spline_interpolation_items[] = { {BEZT_IPO_CONST, "LINEAR", 0, "Linear", ""}, {BEZT_IPO_LIN, "CARDINAL", 0, "Cardinal", ""}, @@ -722,6 +748,12 @@ static void rna_def_curve_nurb(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Radius Interpolation", "The type of radius interpolation for Bezier curves."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + // XXX - switching type probably needs comprehensive recalc of data like in 2.4x + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, curve_type_items); + RNA_def_property_enum_funcs(prop, "rna_Nurb_type_get", "rna_Nurb_type_set", NULL); + RNA_def_property_ui_text(prop, "Type", "The interpolation type for this curve element."); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop= RNA_def_property(srna, "point_count_u", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* editing this needs knot recalc*/ -- cgit v1.2.3 From 01eaf4fd5f674858281a253e0a0150d3f44ee325 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Mon, 7 Sep 2009 18:44:01 +0000 Subject: 2.5 MSVC 9 projectfiles * maintenance --- projectfiles_vc9/blender/blender.vcproj | 2 +- projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj | 16 ---------------- projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj | 4 ++++ 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/projectfiles_vc9/blender/blender.vcproj b/projectfiles_vc9/blender/blender.vcproj index 56913cb8160..e6a5c483f7a 100644 --- a/projectfiles_vc9/blender/blender.vcproj +++ b/projectfiles_vc9/blender/blender.vcproj @@ -201,7 +201,7 @@ /> diff --git a/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj index 75bd6686d01..a6630c81aca 100644 --- a/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj +++ b/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj @@ -566,10 +566,6 @@ RelativePath="..\..\..\source\blender\blenlib\intern\listbase.c" > - - @@ -606,10 +602,6 @@ RelativePath="..\..\..\source\blender\blenlib\intern\util.c" > - - @@ -735,14 +727,6 @@ RelativePath="..\..\..\source\blender\blenlib\BLI_winstuff.h" > - - - - diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj index 9ed358efc0b..8dd1982deca 100644 --- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj +++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj @@ -802,6 +802,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_space.c" > + + -- cgit v1.2.3 From 0ab2f675c364f2ca1212b0453bf2ffdce5ebb9ea Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 7 Sep 2009 22:26:23 +0000 Subject: Fix bug in Mathutil with matrix/matrix and matrix/vector multiplication order. MathUtil matrix type follows Blender convention of column major storage. This means that the elements on one column are contiguous in memory. Vectors are one dimensional arrays that can be considered in row or in column but the Blender convention is column so vector should only be considered as row. This means that the only logical multiplication operation between matrix and vector is matrix * vector. This convention is respected in all parts of MathUtil except in matrix/matrix and matrix/vector multiplication where the row major convention is assumed, which in the and is equivalent to reversing the order of multiplication. This is clearly a bug and must be corrected but the side effect is that it will break all scripts using these operations. Script writers who care about the correctness of the matrix operations have already implemented work around: 1) change order of matrix/vector multiplication. vec2 = vec1 * mat1 This must be changed to the normal order: vec2 = mat1 * vec1 2) change order of matrix/matrix multiplication (with matl a local transform in matw reference) mat3 = matl * matw This must be changed to the normal order: mat3 = matw * matl 3) transpose before an after the multiplication matl.transpose() matw.transpose() mat3 = matw * matl mat3.transpose() This must be changed to: mat3 = matw * matl; --- source/blender/python/generic/matrix.c | 29 +++++++++++++++-------------- source/blender/python/generic/vector.c | 16 ++++++++-------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index be3e704460a..37d06d0b531 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -933,21 +933,21 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } if(mat1 && mat2) { /*MATRIX * MATRIX*/ - if(mat1->colSize != mat2->rowSize){ + if(mat1->rowSize != mat2->colSize){ PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize"); return NULL; } - for(x = 0; x < mat1->rowSize; x++) { - for(y = 0; y < mat2->colSize; y++) { - for(z = 0; z < mat1->colSize; z++) { - dot += (mat1->matrix[x][z] * mat2->matrix[z][y]); + for(x = 0; x < mat2->rowSize; x++) { + for(y = 0; y < mat1->colSize; y++) { + for(z = 0; z < mat1->rowSize; z++) { + dot += (mat1->matrix[z][y] * mat2->matrix[x][z]); } - mat[((x * mat1->rowSize) + y)] = (float)dot; + mat[((x * mat1->colSize) + y)] = (float)dot; dot = 0.0f; } } - return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW, NULL); + return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, NULL); } if(mat1==NULL){ @@ -1288,9 +1288,9 @@ PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb //----------------column_vector_multiplication (internal)--------- //COLUMN VECTOR Multiplication (Matrix X Vector) -// [1][2][3] [a] -// [4][5][6] * [b] -// [7][8][9] [c] +// [1][4][7] [a] +// [2][5][8] * [b] +// [3][6][9] [c] //vector/matrix multiplication IS NOT COMMUTATIVE!!!! static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) { @@ -1312,11 +1312,12 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* for(x = 0; x < vec->size; x++){ vecCopy[x] = vec->vec[x]; - } + } + vecNew[3] = 1.0f; - for(x = 0; x < mat->rowSize; x++) { - for(y = 0; y < mat->colSize; y++) { - dot += mat->matrix[x][y] * vecCopy[y]; + for(x = 0; x < mat->colSize; z++) { + for(y = 0; y < mat->rowSize; y++) { + dot += mat->matrix[y][x] * vecCopy[y]; } vecNew[z++] = (float)dot; dot = 0.0f; diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index c4a8a37ee05..46a0df4ae4d 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -1955,9 +1955,9 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su //-----------------row_vector_multiplication (internal)----------- //ROW VECTOR Multiplication - Vector X Matrix -//[x][y][z] * [1][2][3] -// [4][5][6] -// [7][8][9] +//[x][y][z] * [1][4][7] +// [2][5][8] +// [3][6][9] //vector/matrix multiplication IS NOT COMMUTATIVE!!!! static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) { @@ -1966,7 +1966,7 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat int x, y, z = 0, vec_size = vec->size; if(mat->colSize != vec_size){ - if(mat->rowSize == 4 && vec_size != 3){ + if(mat->colSize == 4 && vec_size != 3){ PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); return NULL; }else{ @@ -1980,11 +1980,11 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat for(x = 0; x < vec_size; x++){ vecCopy[x] = vec->vec[x]; } - + vecNew[3] = 1.0f; //muliplication - for(x = 0; x < mat->colSize; x++) { - for(y = 0; y < mat->rowSize; y++) { - dot += mat->matrix[y][x] * vecCopy[y]; + for(x = 0; x < mat->rowSize; x++) { + for(y = 0; y < mat->colSize; y++) { + dot += mat->matrix[x][y] * vecCopy[y]; } vecNew[z++] = (float)dot; dot = 0.0f; -- cgit v1.2.3 From 8b6b31b41fc6ed07036ea30153131e6824fc7c7e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2009 00:23:33 +0000 Subject: Made Nurb->type only store the type rather then mixing the type with flags. moved CU_2D to Nurb->flag in do_versions This made simple type checks confusing to read. many... if( (nu->type & 7)==CU_BEZIER) replaced with ... if(nu->type == CU_BEZIER) made setting rna curve_2d clamp the Z values. still more RNA/UI changes to do. --- source/blender/blenkernel/BKE_curve.h | 2 +- source/blender/blenkernel/intern/anim.c | 4 +- source/blender/blenkernel/intern/curve.c | 39 +++++---- source/blender/blenkernel/intern/displist.c | 6 +- source/blender/blenkernel/intern/font.c | 3 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenlib/intern/freetypefont.c | 3 +- source/blender/blenloader/intern/readfile.c | 11 +++ source/blender/blenloader/intern/writefile.c | 2 +- source/blender/editors/curve/editcurve.c | 98 +++++++++++----------- source/blender/editors/object/object_edit.c | 22 ++--- source/blender/editors/space_info/info_stats.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 12 +-- .../blender/editors/space_view3d/view3d_buttons.c | 4 +- source/blender/editors/space_view3d/view3d_snap.c | 4 +- .../editors/transform/transform_conversions.c | 4 +- .../editors/transform/transform_manipulator.c | 2 +- .../editors/transform/transform_orientations.c | 2 +- source/blender/makesdna/DNA_curve_types.h | 5 +- source/blender/makesrna/intern/rna_curve.c | 34 ++++++-- 20 files changed, 144 insertions(+), 117 deletions(-) diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index e5a8df1a932..b9f3ee2dd6e 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -47,7 +47,7 @@ struct BevList; #define SEGMENTSU(nu) ( ((nu)->flagu & CU_CYCLIC) ? (nu)->pntsu : (nu)->pntsu-1 ) #define SEGMENTSV(nu) ( ((nu)->flagv & CU_CYCLIC) ? (nu)->pntsv : (nu)->pntsv-1 ) -#define CU_DO_TILT(cu, nu) (((nu->type & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1) +#define CU_DO_TILT(cu, nu) (((nu->flag & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1) #define CU_DO_RADIUS(cu, nu) ((CU_DO_TILT(cu, nu) || cu->bevobj || cu->ext1!=0.0 || cu->ext2!=0.0) ? 1:0) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 6c1b8eb9000..eb74dc1fbfc 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -271,8 +271,8 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK nu= cu->nurb.first; /* make sure that first and last frame are included in the vectors here */ - if((nu->type & 7)==CU_POLY) set_four_ipo(1.0f-fac, data, KEY_LINEAR); - else if((nu->type & 7)==CU_BEZIER) set_four_ipo(1.0f-fac, data, KEY_LINEAR); + if(nu->type == CU_POLY) set_four_ipo(1.0f-fac, data, KEY_LINEAR); + else if(nu->type == CU_BEZIER) set_four_ipo(1.0f-fac, data, KEY_LINEAR); else if(s0==s1 || p2==p3) set_four_ipo(1.0f-fac, data, KEY_CARDINAL); else set_four_ipo(1.0f-fac, data, KEY_BSPLINE); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index ca0d4a5fdc3..58ff601e7f7 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -470,8 +470,11 @@ void test2DNurb(Nurb *nu) BezTriple *bezt; BPoint *bp; int a; + + if((nu->flag & CU_2D)==0) + return; - if( nu->type== CU_BEZIER+CU_2D ) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -481,7 +484,7 @@ void test2DNurb(Nurb *nu) bezt++; } } - else if(nu->type & CU_2D) { + else { a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { @@ -497,7 +500,7 @@ void minmaxNurb(Nurb *nu, float *min, float *max) BPoint *bp; int a; - if( (nu->type & 7)==CU_BEZIER ) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -594,7 +597,7 @@ static void makecyclicknots(float *knots, short pnts, short order) void makeknots(Nurb *nu, short uv) { - if( (nu->type & 7)==CU_NURBS ) { + if(nu->type == CU_NURBS) { if(uv == 1) { if(nu->knotsu) MEM_freeN(nu->knotsu); if(check_valid_nurb_u(nu)) { @@ -1587,7 +1590,7 @@ void makeBevelList(Object *ob) else resolu= nu->resolu; - if((nu->type & 7)==CU_POLY) { + if(nu->type == CU_POLY) { len= nu->pntsu; bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList2"); BLI_addtail(&(cu->bev), bl); @@ -1610,7 +1613,7 @@ void makeBevelList(Object *ob) bp++; } } - else if((nu->type & 7)==CU_BEZIER) { + else if(nu->type == CU_BEZIER) { len= resolu*(nu->pntsu+ (nu->flagu & CU_CYCLIC) -1)+1; /* in case last point is not cyclic */ bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelBPoints"); @@ -1718,7 +1721,7 @@ void makeBevelList(Object *ob) bl->nr++; } } - else if((nu->type & 7)==CU_NURBS) { + else if(nu->type == CU_NURBS) { if(nu->pntsv==1) { len= (resolu*SEGMENTSU(nu)); @@ -2311,7 +2314,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */ BezTriple *bezt, *prev, *next; short a; - if((nu->type & 7)!=CU_BEZIER) return; + if(nu->type != CU_BEZIER) return; if(nu->pntsu<2) return; a= nu->pntsu; @@ -2346,7 +2349,7 @@ void testhandlesNurb(Nurb *nu) BezTriple *bezt; short flag, a; - if((nu->type & 7)!=CU_BEZIER) return; + if(nu->type != CU_BEZIER) return; bezt= nu->bezt; a= nu->pntsu; @@ -2474,7 +2477,7 @@ void sethandlesNurb(ListBase *editnurb, short code) if(code==1 || code==2) { nu= editnurb->first; while(nu) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -2504,7 +2507,7 @@ void sethandlesNurb(ListBase *editnurb, short code) } else { /* Toggle */ while(nu) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -2521,7 +2524,7 @@ void sethandlesNurb(ListBase *editnurb, short code) } nu= editnurb->first; while(nu) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -2569,7 +2572,7 @@ void switchdirectionNurb(Nurb *nu) if(nu->pntsu==1 && nu->pntsv==1) return; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt1= nu->bezt; bezt2= bezt1+(a-1); @@ -2608,7 +2611,7 @@ void switchdirectionNurb(Nurb *nu) bp1++; bp2--; } - if((nu->type & 7)==CU_NURBS) { + if(nu->type == CU_NURBS) { /* inverse knots */ a= KNOTSU(nu); fp1= nu->knotsu; @@ -2671,7 +2674,7 @@ float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3] co = cos[0]; for (nu=lb->first; nu; nu=nu->next) { - if ((nu->type & 7)==CU_BEZIER) { + if (nu->type == CU_BEZIER) { BezTriple *bezt = nu->bezt; for (i=0; ipntsu; i++,bezt++) { @@ -2698,7 +2701,7 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3]) int i; for (nu=lb->first; nu; nu=nu->next) { - if ((nu->type & 7)==CU_BEZIER) { + if (nu->type == CU_BEZIER) { BezTriple *bezt = nu->bezt; for (i=0; ipntsu; i++,bezt++) { @@ -2720,7 +2723,7 @@ int check_valid_nurb_u( struct Nurb *nu ) { if (nu==NULL) return 0; if (nu->pntsu <= 1) return 0; - if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */ + if (nu->type != CU_NURBS) return 1; /* not a nurb, lets assume its valid */ if (nu->pntsu < nu->orderu) return 0; if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagu>>1) & 2)) { /* Bezier U Endpoints */ @@ -2734,7 +2737,7 @@ int check_valid_nurb_v( struct Nurb *nu) { if (nu==NULL) return 0; if (nu->pntsv <= 1) return 0; - if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */ + if (nu->type != CU_NURBS) return 1; /* not a nurb, lets assume its valid */ if (nu->pntsv < nu->orderv) return 0; if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagv>>1) & 2)) { /* Bezier V Endpoints */ diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 069129c15da..de85b0a33f6 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -834,7 +834,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) resolu= nu->resolu; if(!check_valid_nurb_u(nu)); - else if((nu->type & 7)==CU_BEZIER) { + else if(nu->type == CU_BEZIER) { /* count */ len= 0; @@ -902,7 +902,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) bezt++; } } - else if((nu->type & 7)==CU_NURBS) { + else if(nu->type == CU_NURBS) { len= (resolu*SEGMENTSU(nu)); dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); @@ -919,7 +919,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) else dl->type= DL_SEGM; makeNurbcurve(nu, data, NULL, NULL, resolu); } - else if((nu->type & 7)==CU_POLY) { + else if(nu->type == CU_POLY) { len= nu->pntsu; dl= MEM_callocN(sizeof(DispList), "makeDispListpoly"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 70901778585..5ce021e3931 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -462,7 +462,7 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i nu2->resolu= cu->resolu; nu2->bezt = NULL; nu2->knotsu = nu2->knotsv = NULL; - nu2->flag= 0; + nu2->flag= CU_2D; nu2->charidx = charidx+1000; if (mat_nr > 0) nu2->mat_nr= mat_nr-1; nu2->pntsu = 4; @@ -495,7 +495,6 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i nu2->bp[3].vec[2] = 0; nu2->bp[3].vec[3] = 1.0; - nu2->type = CU_2D; BLI_addtail(&(cu->nurb), nu2); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9a137bdb7e6..f10226f6f6b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1807,7 +1807,7 @@ static void give_parvert(Object *par, int nr, float *vec) count= 0; while(nu && !found) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index bde4b561f26..985700efda1 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -146,9 +146,10 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) bezt = (BezTriple*)MEM_callocN((onpoints[j])* sizeof(BezTriple),"objfnt_bezt") ; BLI_addtail(&che->nurbsbase, nu); - nu->type= CU_BEZIER+CU_2D; + nu->type= CU_BEZIER; nu->pntsu = onpoints[j]; nu->resolu= 8; + nu->flag= CU_2D; nu->flagu= CU_CYCLIC; nu->bezt = bezt; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0c4835a79b7..db97657a2ee 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9219,6 +9219,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Material *ma; Camera *cam; Mesh *me; + Curve *cu; Scene *sce; Tex *tx; ParticleSettings *part; @@ -9365,6 +9366,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main) //BLI_freelistN(&pidlist); } + + /* type was a mixed flag & enum. move the 2d flag elsewhere */ + for(cu = main->curve.first; cu; cu= cu->id.next) { + Nurb *nu; + + for(nu= cu->nurb.first; nu; nu= nu->next) { + nu->flag |= (nu->type & CU_2D); + nu->type &= CU_TYPE; + } + } } if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index a22e4f66c8d..46cc62fff1c 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1358,7 +1358,7 @@ static void write_curves(WriteData *wd, ListBase *idbase) } nu= cu->nurb.first; while(nu) { - if( (nu->type & 7)==CU_BEZIER) + if(nu->type == CU_BEZIER) writestruct(wd, DATA, "BezTriple", nu->pntsu, nu->bezt); else { writestruct(wd, DATA, "BPoint", nu->pntsu*nu->pntsv, nu->bp); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 4246c889de0..871f00a585c 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -194,7 +194,7 @@ int isNurbsel(Nurb *nu) BPoint *bp; int a; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -219,7 +219,7 @@ int isNurbsel_count(Nurb *nu) BPoint *bp; int a, sel=0; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -247,7 +247,7 @@ void printknots(Object *obedit) int a, num; for(nu= editnurb->first; nu; nu= nu->next) { - if(isNurbsel(nu) && (nu->type & 7)==CU_NURBS) { + if(isNurbsel(nu) && nu->type == CU_NURBS) { if(nu->knotsu) { num= KNOTSU(nu); for(a=0;aknotsu[a]); @@ -300,7 +300,7 @@ void load_editNurb(Object *obedit) newnu= duplicateNurb(nu); BLI_addtail(&(cu->nurb), newnu); - if((nu->type & 7)==CU_NURBS) { + if(nu->type == CU_NURBS) { clamp_nurb_order_u(nu); } } @@ -484,7 +484,7 @@ static void setflagsNurb(ListBase *editnurb, short flag) int a; for(nu= editnurb->first; nu; nu= nu->next) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -511,7 +511,7 @@ static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float ro int a; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_NURBS) { + if(nu->type == CU_NURBS) { bp= nu->bp; a= nu->pntsu*nu->pntsv; @@ -540,7 +540,7 @@ static void translateflagNurb(ListBase *editnurb, short flag, float *vec) int a; for(nu= editnurb->first; nu; nu= nu->next) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -570,7 +570,7 @@ static void weightflagNurb(ListBase *editnurb, short flag, float w, int mode) /* int a; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_NURBS) { + if(nu->type == CU_NURBS) { a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { @@ -834,7 +834,7 @@ static void adduplicateflagNurb(Object *obedit, short flag) nu= editnurb->last; while(nu) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; for(a=0; apntsu; a++) { enda= -1; @@ -1381,7 +1381,7 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short for(nu= editnurb->first; nu; nu= nu->next) { lastsel=0; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; if(next < 0) bezt= (nu->bezt + (a-1)); @@ -1447,7 +1447,7 @@ void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatu for(nu= editnurb->first; nu; nu= nu->next) { sel= 0; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; /* which point? */ @@ -1546,7 +1546,7 @@ static short nurb_has_selected_cps(ListBase *editnurb) int a; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -1616,7 +1616,7 @@ static int hide_exec(bContext *C, wmOperator *op) int a, sel, invert= RNA_boolean_get(op->ptr, "unselected"); for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; sel= 0; @@ -1690,7 +1690,7 @@ static int reveal_exec(bContext *C, wmOperator *op) for(nu= editnurb->first; nu; nu= nu->next) { nu->hide= 0; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -1746,7 +1746,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op) int a; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -1814,7 +1814,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) for(nu= editnurb->first; nu; nu= nu->next) { amount= 0; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { /* Insert a point into a 2D Bezier curve. Endpoints are preserved. Otherwise, all selected and inserted points are @@ -1895,7 +1895,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) calchandlesNurb(nu); } - } /* End of 'if((nu->type & 7)==CU_BEZIER)' */ + } /* End of 'if(nu->type == CU_BEZIER)' */ else if (nu->pntsv==1) { /* All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves @@ -1964,7 +1964,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) } } } /* End of 'else if(nu->pntsv==1)' */ - else if((nu->type & 7)==CU_NURBS) { + else if(nu->type == CU_NURBS) { /* This is a very strange test ... */ /** Subdivide NURB surfaces - nzc 30-5-'00 - @@ -2163,7 +2163,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) MEM_freeN(usel); MEM_freeN(vsel); - } /* End of 'if((nu->type & 7)==CU_NURBS)' */ + } /* End of 'if(nu->type == CU_NURBS)' */ } WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); @@ -2256,7 +2256,7 @@ static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt *bezt= 0; *bp= 0; for(nu1= editnurb->first; nu1; nu1= nu1->next) { - if((nu1->type & 7)==CU_BEZIER) { + if(nu1->type == CU_BEZIER) { bezt1= nu1->bezt; a= nu1->pntsu; while(a--) { @@ -2313,7 +2313,7 @@ static int convertspline(short type, Nurb *nu) BPoint *bp; int a, c, nr; - if((nu->type & 7)==CU_POLY) { + if(nu->type == CU_POLY) { if(type==CU_BEZIER) { /* to Bezier with vecthandles */ nr= nu->pntsu; bezt = @@ -2333,13 +2333,11 @@ static int convertspline(short type, Nurb *nu) MEM_freeN(nu->bp); nu->bp= 0; nu->pntsu= nr; - nu->type &= ~7; - nu->type |= CU_BEZIER; + nu->type = CU_BEZIER; calchandlesNurb(nu); } else if(type==CU_NURBS) { - nu->type &= ~7; - nu->type |= CU_NURBS; + nu->type = CU_NURBS; nu->orderu= 4; nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */ nu->flagu += 4; @@ -2352,7 +2350,7 @@ static int convertspline(short type, Nurb *nu) } } } - else if((nu->type & 7)==CU_BEZIER) { /* Bezier */ + else if(nu->type == CU_BEZIER) { /* Bezier */ if(type==0 || type==4) { /* to Poly or Nurb */ nr= 3*nu->pntsu; nu->bp = MEM_callocN(nr * sizeof(BPoint), "setsplinetype"); @@ -2390,8 +2388,7 @@ static int convertspline(short type, Nurb *nu) nu->pntsv= 1; nu->orderu= 4; nu->orderv= 1; - nu->type &= ~7; - nu->type+= type; + nu->type |= type; if(nu->flagu & CU_CYCLIC) c= nu->orderu-1; else c= 0; if(type== 4) { @@ -2401,9 +2398,9 @@ static int convertspline(short type, Nurb *nu) } } } - else if((nu->type & 7)==CU_NURBS) { - if(type==0) { /* to Poly */ - nu->type &= ~7; + else if(nu->type == CU_NURBS) { + if(type==CU_POLY) { + nu->type = CU_POLY; if(nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */ nu->knotsu= NULL; if(nu->knotsv) MEM_freeN(nu->knotsv); @@ -2438,8 +2435,7 @@ static int convertspline(short type, Nurb *nu) MEM_freeN(nu->knotsu); nu->knotsu= NULL; nu->pntsu= nr; - nu->type &= ~7; - nu->type |= CU_BEZIER; + nu->type = CU_BEZIER; } } } @@ -2799,7 +2795,7 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu } } - if((nu1->type & 7)==CU_NURBS) { + if(nu1->type == CU_NURBS) { /* merge knots */ makeknots(nu1, 1); @@ -2903,7 +2899,7 @@ static int make_segment_exec(bContext *C, wmOperator *op) /* find both nurbs and points, nu1 will be put behind nu2 */ for(nu= editnurb->first; nu; nu= nu->next) { if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic */ - if( (nu->type & 7)==CU_BEZIER ) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; if(nu1==0) { if( BEZSELECTED_HIDDENHANDLES(bezt) ) nu1= nu; @@ -2960,7 +2956,7 @@ static int make_segment_exec(bContext *C, wmOperator *op) if((nu1 && nu2) && (nu1!=nu2)) { if( nu1->type==nu2->type) { - if((nu1->type & 7)==CU_BEZIER) { + if(nu1->type == CU_BEZIER) { bezt = (BezTriple*)MEM_mallocN((nu1->pntsu+nu2->pntsu) * sizeof(BezTriple), "addsegmentN"); memcpy(bezt, nu2->bezt, nu2->pntsu*sizeof(BezTriple)); @@ -2986,7 +2982,7 @@ static int make_segment_exec(bContext *C, wmOperator *op) BLI_remlink(editnurb, nu2); /* now join the knots */ - if((nu1->type & 7)==CU_NURBS) { + if(nu1->type == CU_NURBS) { if(nu1->knotsu==NULL) { makeknots(nu1, 1); } @@ -3266,7 +3262,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3]) findselectedNurbvert(editnurb, &nu, &bezt, &bp); if(bezt==0 && bp==0) return OPERATOR_CANCELLED; - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { /* which bezpoint? */ if(bezt== nu->bezt) { /* first */ BEZ_DESEL(bezt); @@ -3485,7 +3481,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) for(nu= editnurb->first; nu; nu= nu->next) { if( nu->pntsu>1 || nu->pntsv>1) { - if( (nu->type & 7)==CU_POLY ) { + if(nu->type == CU_POLY) { a= nu->pntsu; bp= nu->bp; while(a--) { @@ -3496,7 +3492,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) bp++; } } - else if( (nu->type & 7)==CU_BEZIER ) { + else if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -3508,7 +3504,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) } calchandlesNurb(nu); } - else if(nu->pntsv==1 && (nu->type & 7)==CU_NURBS) { + else if(nu->pntsv==1 && nu->type == CU_NURBS) { if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */ a= nu->pntsu; bp= nu->bp; @@ -3959,7 +3955,7 @@ static int select_less_exec(bContext *C, wmOperator *op) for(nu= editnurb->first; nu; nu= nu->next) { lastsel=0; /* check what type of curve/nurb it is */ - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { @@ -4105,7 +4101,7 @@ static int select_random_exec(bContext *C, wmOperator *op) /* select elements */ for(i=1, nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -4249,7 +4245,7 @@ static int delete_exec(bContext *C, wmOperator *op) nu= editnurb->first; while(nu) { next= nu->next; - if( (nu->type & 7)==CU_BEZIER ) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; if(a) { @@ -4285,7 +4281,7 @@ static int delete_exec(bContext *C, wmOperator *op) /* Never allow the order to exceed the number of points - note, this is ok but changes unselected nurbs, disable for now */ /* - if ((nu!= NULL) && ((nu->type & 7)==CU_NURBS)) { + if ((nu!= NULL) && (nu->type == CU_NURBS)) { clamp_nurb_order_u(nu); } */ @@ -4296,7 +4292,7 @@ static int delete_exec(bContext *C, wmOperator *op) while(nu) { next= nu->next; type= 0; - if( (nu->type & 7)==CU_BEZIER ) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; for(a=0;apntsu;a++) { if( BEZSELECTED_HIDDENHANDLES(bezt) ) { @@ -4339,7 +4335,7 @@ static int delete_exec(bContext *C, wmOperator *op) /* Never allow the order to exceed the number of points\ - note, this is ok but changes unselected nurbs, disable for now */ /* - if ((nu->type & 7)==CU_NURBS) { + if (nu->type == CU_NURBS) { clamp_nurb_order_u(nu); }*/ } @@ -4356,7 +4352,7 @@ static int delete_exec(bContext *C, wmOperator *op) nu1= 0; while(nu) { next= nu->next; - if( (nu->type & 7)==CU_BEZIER ) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; for(a=0; apntsu-1; a++) { if( BEZSELECTED_HIDDENHANDLES(bezt) ) { @@ -4730,7 +4726,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) /* these types call this function to return a Nurb */ if (stype!=CU_PRIM_TUBE && stype!=CU_PRIM_DONUT) { nu = (Nurb*)MEM_callocN(sizeof(Nurb), "addNurbprim"); - nu->type= type; + nu->type= cutype; nu->resolu= 4; nu->resolv= 4; } @@ -4743,6 +4739,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) rename_id((ID *)obedit->data, "Curve"); } if(cutype==CU_BEZIER) { + nu->flag= CU_2D; nu->pntsu= 2; nu->bezt = (BezTriple*)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1"); @@ -4851,6 +4848,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) rename_id((ID *)obedit->data, "CurveCircle"); } if(cutype==CU_BEZIER) { + nu->flag= CU_2D; nu->pntsu= 4; nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1"); nu->flagu= CU_CYCLIC; @@ -5077,7 +5075,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) } /* always do: */ - nu->flag= CU_SMOOTH; + nu->flag |= CU_SMOOTH; test2DNurb(nu); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d226834bc21..9ef250d7963 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -406,11 +406,11 @@ void OBJECT_OT_mesh_add(wmOperatorType *ot) } static EnumPropertyItem prop_curve_types[] = { - {CU_BEZIER|CU_2D|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""}, - {CU_BEZIER|CU_2D|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", ICON_CURVE_BEZCIRCLE, "Bezier Circle", ""}, - {CU_NURBS|CU_2D|CU_PRIM_CURVE, "NURBS_CURVE", ICON_CURVE_NCURVE, "NURBS Curve", ""}, - {CU_NURBS|CU_2D|CU_PRIM_CIRCLE, "NURBS_CIRCLE", ICON_CURVE_NCIRCLE, "NURBS Circle", ""}, - {CU_NURBS|CU_2D|CU_PRIM_PATH, "PATH", ICON_CURVE_PATH, "Path", ""}, + {CU_BEZIER|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""}, + {CU_BEZIER|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", ICON_CURVE_BEZCIRCLE, "Bezier Circle", ""}, + {CU_NURBS|CU_PRIM_CURVE, "NURBS_CURVE", ICON_CURVE_NCURVE, "NURBS Curve", ""}, + {CU_NURBS|CU_PRIM_CIRCLE, "NURBS_CIRCLE", ICON_CURVE_NCIRCLE, "NURBS Circle", ""}, + {CU_NURBS|CU_PRIM_PATH, "PATH", ICON_CURVE_PATH, "Path", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1064,7 +1064,7 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo int *index, a, nr, totvert=0; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -1091,7 +1091,7 @@ static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, flo cent[0]= cent[1]= cent[2]= 0.0; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -1200,7 +1200,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) int index=0, a, nr=0; for(nu= editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -2795,7 +2795,7 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d) nu= editnurb->first; while(nu) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -3705,7 +3705,7 @@ static int object_center_set_exec(bContext *C, wmOperator *op) nu= nu1; while(nu) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; while (a--) { VecSubf(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent); @@ -5742,7 +5742,7 @@ static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, i nu= cu->nurb.first; while(nu) { - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 2d14fbc515e..7acebbdb72e 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -193,7 +193,7 @@ static void stats_object_edit(Object *obedit, SceneStats *stats) int a; for(nu=cu->editnurb->first; nu; nu=nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3b6ca455b48..220952d190f 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1392,7 +1392,7 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb int i; for (nu= cu->editnurb->first; nu; nu=nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { for (i=0; ipntsu; i++) { BezTriple *bezt = &nu->bezt[i]; @@ -3888,7 +3888,7 @@ static void tekenhandlesN(Nurb *nu, short sel) glBegin(GL_LINES); - if( (nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { if(sel) col= nurbcol+4; else col= nurbcol; @@ -3945,7 +3945,7 @@ static void tekenvertsN(Nurb *nu, short sel) bglBegin(GL_POINTS); - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; @@ -3986,7 +3986,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel) nu= nurb; while(nu) { if(nu->hide==0) { - switch(nu->type & 7) { + switch(nu->type) { case CU_POLY: cpack(nurbcol[3]); bp= nu->bp; @@ -4094,7 +4094,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* first non-selected handles */ for(nu=nurb; nu; nu=nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { tekenhandlesN(nu, 0); } } @@ -4102,7 +4102,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, draw_editnurb(ob, nurb, 1); /* selected handles */ for(nu=nurb; nu; nu=nu->next) { - if((nu->type & 7)==1) tekenhandlesN(nu, 1); + if(nu->type == CU_BEZIER) tekenhandlesN(nu, 1); tekenvertsN(nu, 0); } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 39e90a37b3f..2bef37e43e6 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -226,7 +226,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, nu= cu->editnurb->first; while(nu) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -409,7 +409,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, nu= cu->editnurb->first; while(nu) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 73b70ccb532..b4b54cd1d88 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -302,7 +302,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) int totmalloc= 0; for(nu= cu->editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) + if(nu->type == CU_BEZIER) totmalloc += 3*nu->pntsu; else totmalloc += nu->pntsu*nu->pntsv; @@ -311,7 +311,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) nu= cu->editnurb->first; while(nu) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 3f32b707043..d86eddd0a64 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1373,7 +1373,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) /* count total of vertices, check identical as in 2nd loop for making transdata! */ for(nu= cu->editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { for(a=0, bezt= nu->bezt; apntsu; a++, bezt++) { if(bezt->hide==0) { if (G.f & G_HIDDENHANDLES) { @@ -1409,7 +1409,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) td = t->data; for(nu= cu->editnurb->first; nu; nu= nu->next) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { TransData *head, *tail; head = tail = td; for(a=0, bezt= nu->bezt; apntsu; a++, bezt++) { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index e4ec43a8f38..9fa20c2d674 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -252,7 +252,7 @@ int calc_manipulator_stats(const bContext *C) nu= cu->editnurb->first; while(nu) { - if((nu->type & 7)==CU_BEZIER) { + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 8f9d6108e37..9416425704f 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -744,7 +744,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], for (nu = cu->editnurb->first; nu; nu = nu->next) { /* only bezier has a normal */ - if((nu->type & 7) == CU_BEZIER) + if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 0466ea148fd..8cf9fbbaf40 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -236,6 +236,7 @@ typedef struct Curve { /* flag (nurb) */ #define CU_SMOOTH 1 +#define CU_2D 8 /* moved from type since 2.4x */ /* type (nurb) */ #define CU_POLY 0 @@ -243,9 +244,7 @@ typedef struct Curve { #define CU_BSPLINE 2 #define CU_CARDINAL 3 #define CU_NURBS 4 -#define CU_TYPE 7 - -#define CU_2D 8 +#define CU_TYPE (CU_POLY|CU_BEZIER|CU_BSPLINE|CU_CARDINAL|CU_NURBS) /* only for adding */ #define CU_PRIMITIVE 0xF00 diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 8c805c11f78..7de5976e12c 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -142,24 +142,39 @@ static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max) *max= cu->totcol-1; } -static int rna_Nurb_length(PointerRNA *ptr) +static void rna_Curve_2d_set(PointerRNA *ptr, int value) { - Nurb *nu= (Nurb*)ptr->data; - return nu->pntsv>0 ? nu->pntsu*nu->pntsv : nu->pntsu; + Curve *cu= (Curve*)ptr->id.data; + Nurb *nu; + + if(value) { + cu->flag &= ~CU_3D; + for(nu= cu->nurb.first; nu; nu= nu->next) { + nu->flag |= CU_2D; + test2DNurb(nu); + } + } + else { + cu->flag |= CU_3D; + for(nu= cu->nurb.first; nu; nu= nu->next) { + nu->flag &= ~CU_2D; + } + } } -/* grr! mixing CU_2D with type is dodgy */ -static int rna_Nurb_type_get(PointerRNA *ptr) + + +static int rna_Nurb_length(PointerRNA *ptr) { Nurb *nu= (Nurb*)ptr->data; - return nu->type & 7; + return nu->pntsv>0 ? nu->pntsu*nu->pntsv : nu->pntsu; } static void rna_Nurb_type_set(PointerRNA *ptr, int value) { Nurb *nu= (Nurb*)ptr->data; - nu->type &= CU_2D; - nu->type |= value; + nu->type = value; + // XXX - TODO change datatypes } static void rna_BPoint_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) @@ -677,6 +692,7 @@ static void rna_def_curve(BlenderRNA *brna) /* Flags */ prop= RNA_def_property(srna, "curve_2d", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CU_3D); + RNA_def_property_boolean_funcs(prop, NULL, "rna_Curve_2d_set"); RNA_def_property_ui_text(prop, "2D Curve", "Define curve in two dimensions only. Note that fill only works when this is enabled."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); @@ -751,7 +767,7 @@ static void rna_def_curve_nurb(BlenderRNA *brna) // XXX - switching type probably needs comprehensive recalc of data like in 2.4x prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, curve_type_items); - RNA_def_property_enum_funcs(prop, "rna_Nurb_type_get", "rna_Nurb_type_set", NULL); + RNA_def_property_enum_funcs(prop, NULL, "rna_Nurb_type_set", NULL); RNA_def_property_ui_text(prop, "Type", "The interpolation type for this curve element."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); -- cgit v1.2.3 From 00838f05d23cbd2dfefeab10d9d5345bbad25ea6 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 8 Sep 2009 01:18:06 +0000 Subject: use pure py classes instead of a mix of rna stuff for ui. fix a couple of bugs --- release/io/netrender/__init__.py | 8 ++++ release/io/netrender/master.py | 6 ++- release/io/netrender/operators.py | 53 ++++++++++----------- release/io/netrender/slave.py | 5 +- release/io/netrender/ui.py | 96 +++++++++++++-------------------------- 5 files changed, 72 insertions(+), 96 deletions(-) diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py index e0de2726a55..1eb91abb938 100644 --- a/release/io/netrender/__init__.py +++ b/release/io/netrender/__init__.py @@ -7,3 +7,11 @@ import slave import master import utils import ui + +# store temp data in bpy module + +import bpy + +bpy.data.netrender_jobs = [] +bpy.data.netrender_slaves = [] +bpy.data.netrender_blacklist = [] \ No newline at end of file diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 6f360a4e7a9..4afda9ac67b 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -155,11 +155,11 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if not frame: # no such frame - self.send_heat(http.client.NOT_FOUND) + self.send_heat(http.client.NO_CONTENT) return else: # no such job id - self.send_head(http.client.NOT_FOUND) + self.send_head(http.client.NO_CONTENT) return self.send_head() @@ -453,6 +453,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): buf = self.rfile.read(length) + # add same temp file + renames as slave + f = open(file_path, "wb") f.write(buf) f.close() diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index a1208aa1b46..30631b3b23d 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -61,18 +61,17 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): while(len(netsettings.jobs) > 0): netsettings.jobs.remove(0) - + + bpy.data.netrender_jobs = [] + for j in jobs: + bpy.data.netrender_jobs.append(j) netsettings.jobs.add() job = netsettings.jobs[-1] - job_results = j.framesStatus() + j.results = j.framesStatus() # cache frame status - job.id = j.id job.name = j.name - job.length = len(j) - job.done = job_results[DONE] - job.error = job_results[ERROR] return ('FINISHED',) @@ -97,15 +96,13 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator): if netsettings.active_slave_index >= 0: - slave = netrender.slaves[netsettings.active_slave_index] + # deal with data + slave = bpy.data.netrender_slaves.pop(netsettings.active_slave_index) + bpy.data.netrender_blacklist.append(slave) + # deal with rna netsettings.slaves_blacklist.add() - - netsettings.slaves_blacklist[-1].id = slave.id netsettings.slaves_blacklist[-1].name = slave.name - netsettings.slaves_blacklist[-1].address = slave.address - netsettings.slaves_blacklist[-1].last_seen = slave.last_seen - netsettings.slaves_blacklist[-1].stats = slave.stats netsettings.slaves.remove(netsettings.active_slave_index) netsettings.active_slave_index = -1 @@ -133,15 +130,13 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): if netsettings.active_blacklisted_slave_index >= 0: - slave = netsettings.slaves_blacklist[netsettings.active_blacklisted_slave_index] + # deal with data + slave = bpy.data.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index) + bpy.data.netrender_slaves.append(slave) + # deal with rna netsettings.slaves.add() - - netsettings.slaves[-1].id = slave.id netsettings.slaves[-1].name = slave.name - netsettings.slaves[-1].address = slave.address - netsettings.slaves[-1].last_seen = slave.last_seen - netsettings.slaves[-1].stats = slave.stats netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index) netsettings.active_blacklisted_slave_index = -1 @@ -180,19 +175,21 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): while(len(netsettings.slaves) > 0): netsettings.slaves.remove(0) + bpy.data.netrender_slaves = [] + for s in slaves: - for slave in netsettings.slaves_blacklist: + for i in range(len(bpy.data.netrender_blacklist)): + slave = bpy.data.netrender_blacklist[i] if slave.id == s.id: + bpy.data.netrender_blacklist[i] = s + netsettings.slaves_blacklist[i].name = s.name break + else: + bpy.data.netrender_slaves.append(s) - netsettings.slaves.add() - slave = netsettings.slaves[-1] - - slave.id = s.id - slave.name = s.name - slave.stats = s.stats - slave.address = s.address[0] - slave.last_seen = time.ctime(s.last_seen) + netsettings.slaves.add() + slave = netsettings.slaves[-1] + slave.name = s.name return ('FINISHED',) @@ -218,7 +215,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): conn = clientConnection(context.scene) if conn: - job = netsettings.jobs[netsettings.active_job_index] + job = bpy.data.netrender_jobs[netsettings.active_job_index] conn.request("POST", "cancel", headers={"job-id":job.id}) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 3d7153a0c54..8cbfd4ea11f 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -30,13 +30,14 @@ def testFile(conn, JOB_PREFIX, file_path, main_path = None): job_full_path = prefixPath(JOB_PREFIX, file_path, main_path) if not os.path.exists(job_full_path): + temp_path = JOB_PREFIX + "slave.temp.blend" conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id, "job-file":file_path}) response = conn.getresponse() if response.status != http.client.OK: return None # file for job not returned by server, need to return an error code to server - f = open(job_full_path, "wb") + f = open(temp_path, "wb") buf = response.read(1024) while buf: @@ -45,6 +46,8 @@ def testFile(conn, JOB_PREFIX, file_path, main_path = None): f.close() + os.renames(temp_path, job_full_path) + return job_full_path diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index f8179fedbda..8faabe6ff2d 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -6,6 +6,8 @@ import subprocess, shutil, time, hashlib import netrender.slave as slave import netrender.master as master +from netrender.utils import * + VERSION = b"0.3" PATH_PREFIX = "/tmp/" @@ -69,10 +71,10 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): layout = self.layout scene = context.scene - netrender = scene.network_render + netsettings = scene.network_render row = layout.row() - row.template_list(netrender, "slaves", netrender, "active_slave_index", rows=2) + row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2) col = row.column() @@ -80,14 +82,18 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") - if netrender.active_slave_index >= 0 and len(netrender.slaves) > 0: + if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0: + while(len(netsettings.slaves) > 0): + netsettings.slaves.remove(0) + + if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0: layout.itemS() - slave = netrender.slaves[netrender.active_slave_index] + slave = bpy.data.netrender_slaves[netsettings.active_slave_index] layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Address: " + slave.address) - layout.itemL(text="Seen: " + slave.last_seen) + layout.itemL(text="Address: " + slave.address[0]) + layout.itemL(text="Seen: " + time.ctime(slave.last_seen)) layout.itemL(text="Stats: " + slave.stats) bpy.types.register(SCENE_PT_network_slaves) @@ -104,26 +110,29 @@ class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): layout = self.layout scene = context.scene - netrender = scene.network_render + netsettings = scene.network_render row = layout.row() - row.template_list(netrender, "slaves_blacklist", netrender, "active_blacklisted_slave_index", rows=2) + row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2) col = row.column() subcol = col.column(align=True) subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") + if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0: + while(len(netsettings.slaves_blacklist) > 0): + netsettings.slaves_blacklist.remove(0) - if netrender.active_blacklisted_slave_index >= 0 and len(netrender.slaves_blacklist) > 0: + if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0: layout.itemS() - slave = netrender.slaves_blacklist[netrender.active_blacklisted_slave_index] + slave = bpy.data.netrender_blacklist[netsettings.active_blacklisted_slave_index] layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Address: " + slave.address) + layout.itemL(text="Address: " + slave.address[0]) layout.itemL(text="Seen: " + slave.last_seen) - layout.itemL(text="Stats: " + slave.stats) + layout.itemL(text="Stats: " + time.ctime(slave.stats)) bpy.types.register(SCENE_PT_network_slaves_blacklist) @@ -139,10 +148,10 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): layout = self.layout scene = context.scene - netrender = scene.network_render + netsettings = scene.network_render row = layout.row() - row.template_list(netrender, "jobs", netrender, "active_job_index", rows=2) + row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2) col = row.column() @@ -150,16 +159,19 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: + while(len(netsettings.jobs) > 0): + netsettings.jobs.remove(0) - if netrender.active_job_index >= 0 and len(netrender.jobs) > 0: + if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0: layout.itemS() - job = netrender.jobs[netrender.active_job_index] + job = bpy.data.netrender_jobs[netsettings.active_job_index] layout.itemL(text="Name: %s" % job.name) - layout.itemL(text="Length: %04i" % job.length) - layout.itemL(text="Done: %04i" % job.done) - layout.itemL(text="Error: %04i" % job.error) + layout.itemL(text="Length: %04i" % len(job)) + layout.itemL(text="Done: %04i" % job.results[DONE]) + layout.itemL(text="Error: %04i" % job.results[ERROR]) bpy.types.register(SCENE_PT_network_jobs) @@ -264,54 +276,8 @@ NetRenderSlave.StringProperty( attr="name", maxlen = 64, default = "") -NetRenderSlave.StringProperty( attr="address", - name="Address of the slave", - description="", - maxlen = 64, - default = "") - -NetRenderSlave.StringProperty( attr="last_seen", - name="Last time slave was seen by server", - description="", - maxlen = 64, - default = "") - -NetRenderSlave.StringProperty( attr="stats", - name="Hardware stats of the slave", - description="", - maxlen = 128, - default = "") - -NetRenderJob.StringProperty( attr="id", - name="ID of the job", - description="", - maxlen = 64, - default = "") - - NetRenderJob.StringProperty( attr="name", name="Name of the job", description="", maxlen = 128, default = "") - -NetRenderJob.IntProperty( attr="length", - name="Number of frames", - description="", - default = 0, - min= 0, - max=65535) - -NetRenderJob.IntProperty( attr="done", - name="Number of frames rendered", - description="", - default = 0, - min= 0, - max=65535) - -NetRenderJob.IntProperty( attr="error", - name="Number of frames in error", - description="", - default = 0, - min= 0, - max=65535) -- cgit v1.2.3 From 6808e15c8d20819deddd6b175668d11a6c6f454d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 8 Sep 2009 02:09:14 +0000 Subject: 2.5 - Mode Switching Bugfixes This commit some of the many bugs here (it's still not perfect now, but much better than it was): * Moving in/out of Object, Edit, and Pose Modes for Armatures should now work smoothly. Operators should work nicely in the appropriate modes now (select linked might be a bit tempermental still, since it uses mouse-position). * Fixed the 'mysterious' memory leaks when changing modes. These were only caused when using the mode switching menu in the 3D-View. * Went through bullet-proofing some of the operator calling functions against NULL operator id-name strings. --- release/ui/space_view3d.py | 1 + source/blender/editors/armature/poseobject.c | 7 ++-- source/blender/editors/object/object_edit.c | 4 +- .../blender/editors/space_view3d/view3d_header.c | 11 +++++- source/blender/windowmanager/intern/wm_operators.c | 46 +++++++++++++--------- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index ae1edc0295b..4281ff2ccab 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -186,6 +186,7 @@ class VIEW3D_MT_select_POSE(bpy.types.Menu): layout.itemO("pose.select_all_toggle", text="Select/Deselect All") layout.itemO("pose.select_inverse", text="Inverse") layout.itemO("pose.select_constraint_target", text="Constraint Target") + layout.itemO("pose.select_linked", text="Linked") layout.itemS() diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 2673640b213..a4a518bc003 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -125,9 +125,8 @@ void ED_armature_enter_posemode(bContext *C, Base *base) switch (ob->type){ case OB_ARMATURE: - + ob->restore_mode = ob->mode; ob->mode |= OB_MODE_POSE; - base->flag= ob->flag; WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_POSE, NULL); @@ -136,7 +135,7 @@ void ED_armature_enter_posemode(bContext *C, Base *base) return; } - ED_object_toggle_modes(C, ob->mode); + //ED_object_toggle_modes(C, ob->mode); } void ED_armature_exit_posemode(bContext *C, Base *base) @@ -144,8 +143,8 @@ void ED_armature_exit_posemode(bContext *C, Base *base) if(base) { Object *ob= base->object; + ob->restore_mode = ob->mode; ob->mode &= ~OB_MODE_POSE; - base->flag= ob->flag; WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL); } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 9ef250d7963..9e61bbd3fb5 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -7247,7 +7247,7 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *ptr, in static const char *object_mode_op_string(int mode) { - if(mode == OB_MODE_EDIT) + if(mode & OB_MODE_EDIT) return "OBJECT_OT_editmode_toggle"; if(mode == OB_MODE_SCULPT) return "SCULPT_OT_sculptmode_toggle"; @@ -7333,6 +7333,8 @@ void ED_object_toggle_modes(bContext *C, int mode) WM_operator_name_call(C, "PAINT_OT_texture_paint_toggle", WM_OP_EXEC_REGION_WIN, NULL); if(mode & OB_MODE_PARTICLE_EDIT) WM_operator_name_call(C, "PARTICLE_OT_particle_edit_toggle", WM_OP_EXEC_REGION_WIN, NULL); + if(mode & OB_MODE_POSE) + WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_EXEC_REGION_WIN, NULL); } /* game property ops */ diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 45b0ea41215..a633969d557 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1551,12 +1551,18 @@ static char *view3d_modeselect_pup(Scene *scene) if(ob==NULL) return string; /* if active object is editable */ - if ( ((ob->type == OB_MESH) || (ob->type == OB_ARMATURE) + if ( ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_SURF) || (ob->type == OB_FONT) || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) { str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); } + else if (ob->type == OB_ARMATURE) { + if (ob->mode & OB_MODE_POSE) + str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT|OB_MODE_POSE, ICON_EDITMODE_HLT); + else + str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); + } if (ob->type == OB_MESH) { @@ -1715,6 +1721,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) WM_operator_properties_create(&props_ptr, "OBJECT_OT_mode_set"); RNA_enum_set(&props_ptr, "mode", v3d->modeselect); WM_operator_name_call(C, "OBJECT_OT_mode_set", WM_OP_EXEC_REGION_WIN, &props_ptr); + WM_operator_properties_free(&props_ptr); break; case B_AROUND: // XXX handle_view3d_around(); /* copies to other 3d windows */ @@ -2179,7 +2186,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconBut(block, BUT, B_VIEWRENDER, ICON_SCENE, xco,yco,XIC,YIC, NULL, 0, 1.0, 0, 0, "Render this window (Ctrl Click for anim)"); if (ob && (ob->mode & OB_MODE_POSE)) { - xco+= XIC; + xco+= XIC*2; uiBlockBeginAlign(block); uiDefIconButO(block, BUT, "POSE_OT_copy", WM_OP_INVOKE_REGION_WIN, ICON_COPYDOWN, xco,yco,XIC,YIC, NULL); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b51fcfddc47..c7011777dbf 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -91,10 +91,12 @@ wmOperatorType *WM_operatortype_find(const char *idname, int quiet) char idname_bl[OP_MAX_TYPENAME]; // XXX, needed to support python style names without the _OT_ syntax WM_operator_bl_idname(idname_bl, idname); - - for(ot= global_ops.first; ot; ot= ot->next) { - if(strncmp(ot->idname, idname_bl, OP_MAX_TYPENAME)==0) - return ot; + + if (idname_bl[0]) { + for(ot= global_ops.first; ot; ot= ot->next) { + if(strncmp(ot->idname, idname_bl, OP_MAX_TYPENAME)==0) + return ot; + } } if(!quiet) @@ -109,10 +111,12 @@ wmOperatorType *WM_operatortype_exists(const char *idname) char idname_bl[OP_MAX_TYPENAME]; // XXX, needed to support python style names without the _OT_ syntax WM_operator_bl_idname(idname_bl, idname); - - for(ot= global_ops.first; ot; ot= ot->next) { - if(strncmp(ot->idname, idname_bl, OP_MAX_TYPENAME)==0) - return ot; + + if(idname_bl[0]) { + for(ot= global_ops.first; ot; ot= ot->next) { + if(strncmp(ot->idname, idname_bl, OP_MAX_TYPENAME)==0) + return ot; + } } return NULL; } @@ -322,21 +326,25 @@ void WM_operator_py_idname(char *to, const char *from) /* some.op -> SOME_OT_op */ void WM_operator_bl_idname(char *to, const char *from) { - char *sep= strchr(from, '.'); + if (from) { + char *sep= strchr(from, '.'); - if(sep) { - int i, ofs= (sep-from); + if(sep) { + int i, ofs= (sep-from); - for(i=0; i Date: Tue, 8 Sep 2009 03:29:28 +0000 Subject: Re-commit previous brush ui changes. Strangely seemed to get reverted in jahka's rev. 22861 --- release/ui/space_view3d_toolbar.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 43772f7a072..63eceb66ff6 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -357,10 +357,8 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column(align=True) col.item_enumR(settings, "tool", 'DRAW') col.item_enumR(settings, "tool", 'SOFTEN') - if settings.use_projection: - col.item_enumR(settings, "tool", 'CLONE') - else: - col.item_enumR(settings, "tool", 'SMEAR') + col.item_enumR(settings, "tool", 'CLONE') + col.item_enumR(settings, "tool", 'SMEAR') col = layout.column() col.itemR(brush, "color", text="") @@ -546,9 +544,17 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel): # ********** default tools for texturepaint **************** -class VIEW3D_PT_tools_texturepaint(View3DPanel): - __context__ = "texturepaint" - __label__ = "Options" +class VIEW3D_PT_tools_projectpaint(View3DPanel): + __context__ = "projectpaint" + __label__ = "Project Paint" + + def poll(self, context): + return context.tool_settings.image_paint.tool != 'SMEAR' + + def draw_header(self, context): + layout = self.layout + ipaint = context.tool_settings.image_paint + layout.itemR(ipaint, "use_projection", text="") def draw(self, context): layout = self.layout @@ -558,7 +564,6 @@ class VIEW3D_PT_tools_texturepaint(View3DPanel): use_projection= ipaint.use_projection col = layout.column() - col.itemR(ipaint, "use_projection") sub = col.column() sub.active = use_projection sub.itemR(ipaint, "use_occlude") @@ -670,5 +675,5 @@ bpy.types.register(VIEW3D_PT_tools_brush_curve) bpy.types.register(VIEW3D_PT_sculpt_options) bpy.types.register(VIEW3D_PT_tools_vertexpaint) bpy.types.register(VIEW3D_PT_tools_weightpaint) -bpy.types.register(VIEW3D_PT_tools_texturepaint) +bpy.types.register(VIEW3D_PT_tools_projectpaint) bpy.types.register(VIEW3D_PT_tools_particlemode) -- cgit v1.2.3 From 1d0a567023d89b4e397800eeb164512b40336184 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2009 07:35:07 +0000 Subject: Curve/Surface Editing - rename "Nurb" to "Spline" in RNA, eg. bpy.data.curves[0].splines[2].type == 'NURBS' from a user perspective spline is a more generic term while Nurb is misleading when used for beziers and poly lines. - added curve.active_spline property so the python UI can display the last selected curve. - set the active spline when entering editmode (uses first selected spline) - added back Hide Handles as a curve property (removed the global flag), access from the view panel in editmode. - added hide normal option for curve, normal size access for curve and mesh display. - changing orderU/V, endpoints, cyclic, bezierU/V now work in editmode and calls update functions. - entering editmode was crashing with text objects - curve.switch_direction() crashed (own fault from last commit) - Tkey for tilt was overridden by Toolbar, made Tilt Ctrl+T. - OBJECT_OT_mode_set check for compatible modes before running - so curves dont try go into paint mode with V key for eg. --- release/ui/buttons_data_curve.py | 69 ++++++++------ release/ui/space_view3d.py | 24 +++++ release/ui/space_view3d_toolbar.py | 1 + source/blender/blenkernel/BKE_global.h | 1 - source/blender/editors/curve/curve_ops.c | 2 +- source/blender/editors/curve/editcurve.c | 94 ++++++++++++------- source/blender/editors/include/ED_anim_api.h | 3 - source/blender/editors/object/object_edit.c | 44 ++++++++- source/blender/editors/space_info/info_stats.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 28 +++--- .../blender/editors/space_view3d/view3d_select.c | 17 ++-- .../editors/transform/transform_conversions.c | 17 ++-- .../editors/transform/transform_manipulator.c | 2 +- source/blender/makesdna/DNA_curve_types.h | 14 ++- source/blender/makesrna/intern/rna_curve.c | 104 +++++++++++++++++---- source/blender/makesrna/intern/rna_scene.c | 7 ++ 16 files changed, 310 insertions(+), 119 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 46311493ad3..95f9a98da74 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -15,6 +15,14 @@ class DataButtonsPanelCurve(DataButtonsPanel): ''' def poll(self, context): return (context.object and context.object.type == 'CURVE' and context.curve) + +class DataButtonsPanelActive(DataButtonsPanel): + ''' + Same as above but for curves only + ''' + def poll(self, context): + curve = context.curve + return (curve and curve.active_spline) class DATA_PT_context_curve(DataButtonsPanel): __show_header__ = False @@ -46,11 +54,11 @@ class DATA_PT_shape_curve(DataButtonsPanel): space = context.space_data is_surf = (ob.type == 'SURFACE') - row = layout.row() - row.itemR(curve, "curve_2d") - row.itemR(curve, "use_twist_correction") + if not is_surf: + row = layout.row() + row.itemR(curve, "curve_2d") + row.itemR(curve, "use_twist_correction") - split = layout.split() col = split.column() @@ -132,64 +140,71 @@ class DATA_PT_pathanim(DataButtonsPanelCurve): col.itemR(curve, "use_stretch") col.itemR(curve, "use_time_offset", text="Offset Children") -class DATA_PT_current_curve(DataButtonsPanel): - __label__ = "Current Curve" +class DATA_PT_active_spline(DataButtonsPanelActive): + __label__ = "Active Spline" def draw(self, context): layout = self.layout ob = context.object - currentcurve = context.curve.curves[0] # XXX + curve = context.curve + act_spline = curve.active_spline is_surf = (ob.type == 'SURFACE') split = layout.split() col = split.column() col.itemL(text="Cyclic:") - if currentcurve.type == 'NURBS': + if act_spline.type == 'NURBS': col.itemL(text="Bezier:") col.itemL(text="Endpoint:") col.itemL(text="Order:") col.itemL(text="Resolution:") - col = split.column() - col.itemR(currentcurve, "cyclic_u", text="U") + col.itemR(act_spline, "cyclic_u", text="U") - if currentcurve.type == 'NURBS': + if act_spline.type == 'NURBS': sub = col.column() - sub.active = (not currentcurve.cyclic_u) - sub.itemR(currentcurve, "bezier_u", text="U") - sub.itemR(currentcurve, "endpoint_u", text="U") + sub.active = (not act_spline.cyclic_u) + sub.itemR(act_spline, "bezier_u", text="U") + sub.itemR(act_spline, "endpoint_u", text="U") sub = col.column() - sub.itemR(currentcurve, "order_u", text="U") - col.itemR(currentcurve, "resolution_u", text="U") + sub.itemR(act_spline, "order_u", text="U") + col.itemR(act_spline, "resolution_u", text="U") if is_surf: col = split.column() - col.itemR(currentcurve, "cyclic_v", text="V") + col.itemR(act_spline, "cyclic_v", text="V") # its a surface, assume its a nurb. sub = col.column() - sub.active = (not currentcurve.cyclic_v) - sub.itemR(currentcurve, "bezier_v", text="V") - sub.itemR(currentcurve, "endpoint_v", text="V") + sub.active = (not act_spline.cyclic_v) + sub.itemR(act_spline, "bezier_v", text="V") + sub.itemR(act_spline, "endpoint_v", text="V") sub = col.column() - sub.itemR(currentcurve, "resolution_v", text="V") - sub.itemR(currentcurve, "order_v", text="V") + sub.itemR(act_spline, "order_v", text="V") + sub.itemR(act_spline, "resolution_v", text="V") + + + if not is_surf: + split = layout.split() + col = split.column() + col.active = (not curve.curve_2d) + + col.itemL(text="Interpolation:") + col.itemR(act_spline, "tilt_interpolation", text="Tilt") + col.itemR(act_spline, "radius_interpolation", text="Radius") split = layout.split() col = split.column() - col.itemL(text="Interpolation:") - col.itemR(currentcurve, "tilt_interpolation", text="Tilt") - col.itemR(currentcurve, "radius_interpolation", text="Radius") - col.itemR(currentcurve, "smooth") + col.itemR(act_spline, "smooth") bpy.types.register(DATA_PT_context_curve) bpy.types.register(DATA_PT_shape_curve) bpy.types.register(DATA_PT_geometry_curve) bpy.types.register(DATA_PT_pathanim) -bpy.types.register(DATA_PT_current_curve) +bpy.types.register(DATA_PT_active_spline) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 4281ff2ccab..bc133cbff48 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -1209,12 +1209,35 @@ class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel): col.itemL(text="Normals:") col.itemR(mesh, "draw_normals", text="Face") col.itemR(mesh, "draw_vertex_normals", text="Vertex") + col.itemR(context.scene.tool_settings, "normal_size", text="Normal Size") col.itemS() col.itemL(text="Numerics:") col.itemR(mesh, "draw_edge_lenght") col.itemR(mesh, "draw_edge_angle") col.itemR(mesh, "draw_face_area") + + +class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel): + __space_type__ = 'VIEW_3D' + __region_type__ = 'UI' + __label__ = "Curve Display" + + def poll(self, context): + editmesh = context.mode == 'EDIT_CURVE' + return (editmesh) + + def draw(self, context): + layout = self.layout + + curve = context.active_object.data + + col = layout.column() + col.itemL(text="Overlays:") + col.itemR(curve, "draw_handles", text="Handles") + col.itemR(curve, "draw_normals", text="Normals") + col.itemR(context.scene.tool_settings, "normal_size", text="Normal Size") + class VIEW3D_PT_background_image(bpy.types.Panel): __space_type__ = 'VIEW_3D' @@ -1326,4 +1349,5 @@ bpy.types.register(VIEW3D_MT_edit_ARMATURE_roll) bpy.types.register(VIEW3D_PT_3dview_properties) # Panels bpy.types.register(VIEW3D_PT_3dview_display) bpy.types.register(VIEW3D_PT_3dview_meshdisplay) +bpy.types.register(VIEW3D_PT_3dview_curvedisplay) bpy.types.register(VIEW3D_PT_background_image) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 63eceb66ff6..73f97dec750 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -107,6 +107,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel): col.itemO("curve.delete") col.itemO("curve.cyclic_toggle") col.itemO("curve.switch_direction") + col.itemO("curve.spline_type_set") layout.itemL(text="Modeling:") diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 6323258ff43..5d0b89220d5 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -119,7 +119,6 @@ typedef struct Global { #define G_GREASEPENCIL (1 << 17) /* #define G_AUTOMATKEYS (1 << 30) also removed */ -#define G_HIDDENHANDLES (1 << 31) /* used for curves only */ /* G.fileflags */ diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index d3bcdcb69bb..a242e424aa0 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -233,7 +233,7 @@ void ED_keymap_curve(wmWindowManager *wm) WM_keymap_add_item(keymap, "CURVE_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0)->ptr, "mode", TFM_TILT); + RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", TFM_TILT); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, 0, 0)->ptr, "type", 3); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", VKEY, KM_PRESS, 0, 0)->ptr, "type", 2); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 871f00a585c..e346ccafde3 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -86,9 +86,6 @@ /* still need to eradicate a few :( */ #define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name) -/* for curve objects in editmode that can have hidden handles */ -#define BEZSELECTED_HIDDENHANDLES(bezt) ((G.f & G_HIDDENHANDLES) ? (bezt)->f2 & SELECT : BEZSELECTED(bezt)) - float nurbcircle[8][2]= { {0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0}, {0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0} @@ -213,7 +210,7 @@ int isNurbsel(Nurb *nu) return 0; } -int isNurbsel_count(Nurb *nu) +int isNurbsel_count(Curve *cu, Nurb *nu) { BezTriple *bezt; BPoint *bp; @@ -223,7 +220,7 @@ int isNurbsel_count(Nurb *nu) bezt= nu->bezt; a= nu->pntsu; while(a--) { - if (BEZSELECTED_HIDDENHANDLES(bezt)) sel++; + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) sel++; bezt++; } } @@ -269,6 +266,8 @@ void load_editNurb(Object *obedit) if(obedit==NULL) return; + set_actNurb(obedit, NULL); + if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu= obedit->data; Nurb *nu, *newnu; @@ -314,11 +313,13 @@ void load_editNurb(Object *obedit) void make_editNurb(Object *obedit) { ListBase *editnurb= curve_get_editcurve(obedit); - Nurb *nu, *newnu; + Nurb *nu, *newnu, *nu_act= NULL; KeyBlock *actkey; if(obedit==NULL) return; + set_actNurb(obedit, NULL); + if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu= obedit->data; @@ -334,6 +335,12 @@ void make_editNurb(Object *obedit) newnu= duplicateNurb(nu); test2DNurb(newnu); // after join, or any other creation of curve BLI_addtail(editnurb, newnu); + + if (nu_act == NULL && isNurbsel(nu)) { + nu_act= newnu; + set_actNurb(obedit, newnu); + } + nu= nu->next; } @@ -343,8 +350,6 @@ void make_editNurb(Object *obedit) key_to_curve(actkey, cu, editnurb); } } - - set_actNurb(obedit, NULL); } void free_editNurb(Object *obedit) @@ -1609,6 +1614,7 @@ void CURVE_OT_select_all_toggle(wmOperatorType *ot) static int hide_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; BPoint *bp; @@ -1621,11 +1627,11 @@ static int hide_exec(bContext *C, wmOperator *op) a= nu->pntsu; sel= 0; while(a--) { - if(invert == 0 && BEZSELECTED_HIDDENHANDLES(bezt)) { + if(invert == 0 && BEZSELECTED_HIDDENHANDLES(cu, bezt)) { select_beztriple(bezt, DESELECT, 1, HIDDEN); bezt->hide= 1; } - else if(invert && !BEZSELECTED_HIDDENHANDLES(bezt)) { + else if(invert && !BEZSELECTED_HIDDENHANDLES(cu, bezt)) { select_beztriple(bezt, DESELECT, 1, HIDDEN); bezt->hide= 1; } @@ -1739,6 +1745,7 @@ void CURVE_OT_reveal(wmOperatorType *ot) static int select_inverse_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; BPoint *bp; @@ -1752,7 +1759,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op) while(a--) { if(bezt->hide==0) { bezt->f2 ^= SELECT; /* always do the center point */ - if ((G.f & G_HIDDENHANDLES)==0) { + if((cu->drawflag & CU_HIDE_HANDLES)==0) { bezt->f1 ^= SELECT; bezt->f3 ^= SELECT; } @@ -1803,6 +1810,7 @@ void CURVE_OT_select_inverse(wmOperatorType *ot) static int subdivide_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; BezTriple *prevbezt, *bezt, *beztnew, *beztn; @@ -1832,7 +1840,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) bezt= prevbezt+1; } while(a--) { - if( BEZSELECTED_HIDDENHANDLES(prevbezt) && BEZSELECTED_HIDDENHANDLES(bezt) ) amount++; + if( BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) amount++; prevbezt= bezt; bezt++; } @@ -1856,7 +1864,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) memcpy(beztn, prevbezt, sizeof(BezTriple)); beztn++; - if( BEZSELECTED_HIDDENHANDLES(prevbezt) && BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { memcpy(beztn, bezt, sizeof(BezTriple)); /* midpoint subdividing */ @@ -2351,14 +2359,14 @@ static int convertspline(short type, Nurb *nu) } } else if(nu->type == CU_BEZIER) { /* Bezier */ - if(type==0 || type==4) { /* to Poly or Nurb */ + if(type==CU_POLY || type==CU_NURBS) { nr= 3*nu->pntsu; nu->bp = MEM_callocN(nr * sizeof(BPoint), "setsplinetype"); a= nu->pntsu; bezt= nu->bezt; bp= nu->bp; while(a--) { - if(type==0 && bezt->h1==HD_VECT && bezt->h2==HD_VECT) { + if(type==CU_POLY && bezt->h1==HD_VECT && bezt->h2==HD_VECT) { /* vector handle becomes 1 poly vertice */ VECCOPY(bp->vec, bezt->vec[1]); bp->vec[3]= 1.0; @@ -2383,15 +2391,15 @@ static int convertspline(short type, Nurb *nu) bezt++; } MEM_freeN(nu->bezt); - nu->bezt= 0; + nu->bezt= NULL; nu->pntsu= nr; nu->pntsv= 1; nu->orderu= 4; nu->orderv= 1; - nu->type |= type; + nu->type = type; if(nu->flagu & CU_CYCLIC) c= nu->orderu-1; else c= 0; - if(type== 4) { + if(type== CU_NURBS) { nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */ nu->flagu += 4; makeknots(nu, 1); @@ -2464,7 +2472,15 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) } } - return (changed)? OPERATOR_FINISHED: OPERATOR_CANCELLED; + if(changed) { + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } void CURVE_OT_spline_type_set(wmOperatorType *ot) @@ -2472,8 +2488,8 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot) static EnumPropertyItem type_items[]= { {CU_POLY, "POLY", 0, "Poly", ""}, {CU_BEZIER, "BEZIER", 0, "Bezier", ""}, - {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""}, - {CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""}, +// {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""}, +// {CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""}, {CU_NURBS, "NURBS", 0, "NURBS", ""}, {0, NULL, 0, NULL, NULL}}; @@ -2483,6 +2499,7 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot) /* api callbacks */ ot->exec= set_spline_type_exec; + ot->invoke= WM_menu_invoke; ot->poll= ED_operator_editcurve; /* flags */ @@ -2866,6 +2883,7 @@ static int make_segment_exec(bContext *C, wmOperator *op) { /* joins 2 curves */ Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu, *nu1=0, *nu2=0; BezTriple *bezt; @@ -2881,8 +2899,8 @@ static int make_segment_exec(bContext *C, wmOperator *op) if( isNurbsel(nu) ) { if(nu->pntsu>1 && nu->pntsv>1) break; - if(isNurbsel_count(nu)>1) break; - if(isNurbsel_count(nu)==1) { + if(isNurbsel_count(cu, nu)>1) break; + if(isNurbsel_count(cu, nu)==1) { /* only 1 selected, not first or last, a little complex, but intuitive */ if(nu->pntsv==1) { if( (nu->bp->f1 & SELECT) || ((nu->bp+nu->pntsu-1)->f1 & SELECT)); @@ -2902,23 +2920,23 @@ static int make_segment_exec(bContext *C, wmOperator *op) if(nu->type == CU_BEZIER) { bezt= nu->bezt; if(nu1==0) { - if( BEZSELECTED_HIDDENHANDLES(bezt) ) nu1= nu; + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) nu1= nu; else { bezt= bezt+(nu->pntsu-1); - if( BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { nu1= nu; switchdirectionNurb(nu); } } } else if(nu2==0) { - if( BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { nu2= nu; switchdirectionNurb(nu); } else { bezt= bezt+(nu->pntsu-1); - if( BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { nu2= nu; } } @@ -3039,8 +3057,8 @@ void CURVE_OT_make_segment(wmOperatorType *ot) void mouse_nurb(bContext *C, short mval[2], int extend) { Object *obedit= CTX_data_edit_object(C); - ListBase *editnurb= curve_get_editcurve(obedit); Curve *cu= obedit->data; + ListBase *editnurb= curve_get_editcurve(obedit); ViewContext vc; Nurb *nu; BezTriple *bezt=0; @@ -3417,12 +3435,13 @@ void CURVE_OT_vertex_add(wmOperatorType *ot) static int extrude_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; /* first test: curve? */ for(nu= editnurb->first; nu; nu= nu->next) - if(nu->pntsv==1 && isNurbsel_count(nu)==1) + if(nu->pntsv==1 && isNurbsel_count(cu, nu)==1) break; if(obedit->type==OB_CURVE || nu) { @@ -3473,6 +3492,7 @@ void CURVE_OT_extrude(wmOperatorType *ot) static int toggle_cyclic_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; BezTriple *bezt; @@ -3496,7 +3516,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) a= nu->pntsu; bezt= nu->bezt; while(a--) { - if( BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { nu->flagu ^= CU_CYCLIC; break; } @@ -3674,8 +3694,8 @@ void CURVE_OT_select_linked(wmOperatorType *ot) static int select_row_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); - ListBase *editnurb= curve_get_editcurve(obedit); Curve *cu= obedit->data; + ListBase *editnurb= curve_get_editcurve(obedit); static BPoint *last=0; static int direction=0; Nurb *nu; @@ -4224,6 +4244,7 @@ void CURVE_OT_duplicate(wmOperatorType *ot) static int delete_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu, *next, *nu1; BezTriple *bezt, *bezt1, *bezt2; @@ -4250,7 +4271,7 @@ static int delete_exec(bContext *C, wmOperator *op) a= nu->pntsu; if(a) { while(a) { - if( BEZSELECTED_HIDDENHANDLES(bezt) ); + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ); else break; a--; bezt++; @@ -4295,7 +4316,7 @@ static int delete_exec(bContext *C, wmOperator *op) if(nu->type == CU_BEZIER) { bezt= nu->bezt; for(a=0;apntsu;a++) { - if( BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { memmove(bezt, bezt+1, (nu->pntsu-a-1)*sizeof(BezTriple)); nu->pntsu--; a--; @@ -4355,7 +4376,7 @@ static int delete_exec(bContext *C, wmOperator *op) if(nu->type == CU_BEZIER) { bezt= nu->bezt; for(a=0; apntsu-1; a++) { - if( BEZSELECTED_HIDDENHANDLES(bezt) ) { + if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) { bezt1= bezt; bezt2= bezt+1; if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) ; @@ -4706,7 +4727,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) cent[2]-= obedit->obmat[3][2]; if(rv3d) { - if (!(newname) || U.flag & USER_ADD_VIEWALIGNED || !rv3d) + if (!(newname) || U.flag & USER_ADD_VIEWALIGNED) Mat3CpyMat4(imat, rv3d->viewmat); else Mat3One(imat); @@ -5087,6 +5108,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) static int clear_tilt_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); + Curve *cu= obedit->data; ListBase *editnurb= curve_get_editcurve(obedit); Nurb *nu; BezTriple *bezt; @@ -5098,7 +5120,7 @@ static int clear_tilt_exec(bContext *C, wmOperator *op) bezt= nu->bezt; a= nu->pntsu; while(a--) { - if(BEZSELECTED_HIDDENHANDLES(bezt)) bezt->alfa= 0.0; + if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) bezt->alfa= 0.0; bezt++; } } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index af37cd87254..799829a6e87 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -433,9 +433,6 @@ void ED_nla_postop_refresh(bAnimContext *ac); /* ------------- Utility macros ----------------------- */ -/* checks if the given BezTriple is selected */ -#define BEZSELECTED(bezt) (((bezt)->f2 & SELECT) || ((bezt)->f1 & SELECT) || ((bezt)->f3 & SELECT)) - /* provide access to Keyframe Type info in BezTriple * NOTE: this is so that we can change it from being stored in 'hide' */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 9e61bbd3fb5..31a604a79df 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2756,13 +2756,12 @@ void OBJECT_OT_slowparent_clear(wmOperatorType *ot) } /* ******************** **************** */ -// XXX -#define BEZSELECTED_HIDDENHANDLES(bezt) ((G.f & G_HIDDENHANDLES) ? (bezt)->f2 & SELECT : BEZSELECTED(bezt)) /* only in edit mode */ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d) { EditVert *eve; Base *base; + Curve *cu= obedit->data; Nurb *nu; BezTriple *bezt; BPoint *bp; @@ -2799,7 +2798,7 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d) bezt= nu->bezt; a= nu->pntsu; while(a--) { - if(BEZSELECTED_HIDDENHANDLES(bezt)) { + if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) { if(v1==0) v1= nr; else if(v2==0) v2= nr; else if(v3==0) v3= nr; @@ -7264,6 +7263,43 @@ static const char *object_mode_op_string(int mode) return NULL; } +/* checks the mode to be set is compatible with the object + * should be made into a generic function */ +static int object_mode_set_compat(bContext *C, wmOperator *op, Object *ob) +{ + ObjectMode mode = RNA_enum_get(op->ptr, "mode"); + + if(ob) { + switch(ob->type) { + case OB_EMPTY: + case OB_LAMP: + case OB_CAMERA: + if(mode & OB_MODE_OBJECT) + return 1; + return 0; + case OB_MESH: + if(mode & ( OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT)) + return 1; + return 0; + case OB_CURVE: + case OB_SURF: + case OB_FONT: + case OB_MBALL: + if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT)) + return 1; + return 0; + case OB_LATTICE: + if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT)) + return 1; + case OB_ARMATURE: + if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_POSE)) + return 1; + } + } + + return 0; +} + static int object_mode_set_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); @@ -7271,7 +7307,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) ObjectMode restore_mode = ob->mode; int toggle = RNA_boolean_get(op->ptr, "toggle"); - if(!ob) + if(!ob || !object_mode_set_compat(C, op, ob)) return OPERATOR_CANCELLED; /* Exit current mode if it's not the mode we're setting */ diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 7acebbdb72e..60cac0a00fa 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -184,7 +184,7 @@ static void stats_object_edit(Object *obedit, SceneStats *stats) stats->totvert+=2; } } - else if ELEM3(obedit->type, OB_CURVE, OB_SURF, OB_FONT) { + else if ELEM(obedit->type, OB_CURVE, OB_SURF) { /* OB_FONT has no cu->editnurb */ /* Curve Edit */ Curve *cu= obedit->data; Nurb *nu; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 220952d190f..001021e8d4b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1397,7 +1397,8 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb BezTriple *bezt = &nu->bezt[i]; if(bezt->hide==0) { - if (G.f & G_HIDDENHANDLES) { + + if(cu->drawflag & CU_HIDE_HANDLES) { view3d_project_short_clip(vc->ar, bezt->vec[1], s); if (s[0] != IS_CLIPPED) func(userData, nu, NULL, bezt, 1, s[0], s[1]); @@ -2797,7 +2798,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if(solid) { dl= lb->first; if(dl==NULL) return 1; - + if(dl->nors==0) addnormalsDispList(ob, lb); index3_nors_incr= 0; @@ -2838,7 +2839,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } break; case OB_SURF: - + lb= &((Curve *)ob->data)->disp; if(solid) { @@ -3877,14 +3878,14 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj unsigned int nurbcol[8]= { 0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 }; -static void tekenhandlesN(Nurb *nu, short sel) +static void tekenhandlesN(Nurb *nu, short sel, short hide_handles) { BezTriple *bezt; float *fp; unsigned int *col; int a; - if(nu->hide || (G.f & G_HIDDENHANDLES)) return; + if(nu->hide || hide_handles) return; glBegin(GL_LINES); @@ -3928,7 +3929,7 @@ static void tekenhandlesN(Nurb *nu, short sel) glEnd(); } -static void tekenvertsN(Nurb *nu, short sel) +static void tekenvertsN(Nurb *nu, short sel, short hide_handles) { BezTriple *bezt; BPoint *bp; @@ -3951,7 +3952,7 @@ static void tekenvertsN(Nurb *nu, short sel) a= nu->pntsu; while(a--) { if(bezt->hide==0) { - if (G.f & G_HIDDENHANDLES) { + if (hide_handles) { if((bezt->f2 & SELECT)==sel) bglVertex3fv(bezt->vec[1]); } else { if((bezt->f1 & SELECT)==sel) bglVertex3fv(bezt->vec[0]); @@ -4083,6 +4084,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Curve *cu = ob->data; Nurb *nu; BevList *bl; + short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); // XXX retopo_matrix_update(v3d); @@ -4095,22 +4097,24 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* first non-selected handles */ for(nu=nurb; nu; nu=nu->next) { if(nu->type == CU_BEZIER) { - tekenhandlesN(nu, 0); + tekenhandlesN(nu, 0, hide_handles); } } draw_editnurb(ob, nurb, 0); draw_editnurb(ob, nurb, 1); /* selected handles */ for(nu=nurb; nu; nu=nu->next) { - if(nu->type == CU_BEZIER) tekenhandlesN(nu, 1); - tekenvertsN(nu, 0); + if(nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES)==0) + tekenhandlesN(nu, 1, hide_handles); + tekenvertsN(nu, 0, hide_handles); } if(v3d->zbuf) glEnable(GL_DEPTH_TEST); /* direction vectors for 3d curve paths when at its lowest, dont render normals */ - if(cu->flag & CU_3D && ts->normalsize > 0.0015) { + if(cu->flag & CU_3D && ts->normalsize > 0.0015 && (cu->drawflag & CU_HIDE_NORMALS)==0) { + UI_ThemeColor(TH_WIRE); for (bl=cu->bev.first,nu=nurb; nu && bl; bl=bl->next,nu=nu->next) { BevPoint *bevp= (BevPoint *)(bl+1); @@ -4145,7 +4149,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if(v3d->zbuf) glDisable(GL_DEPTH_TEST); for(nu=nurb; nu; nu=nu->next) { - tekenvertsN(nu, 1); + tekenvertsN(nu, 1, hide_handles); } if(v3d->zbuf) glEnable(GL_DEPTH_TEST); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 42954e09060..a7696d9fe31 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -549,13 +549,15 @@ static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { - struct { short (*mcords)[2]; short moves; short select; } *data = userData; - + struct { ViewContext vc; short (*mcords)[2]; short moves; short select; } *data = userData; + if (lasso_inside(data->mcords, data->moves, x, y)) { if (bp) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); } else { - if (G.f & G_HIDDENHANDLES) { + Curve *cu= data->vc.obedit->data; + + if (cu->drawflag & CU_HIDE_HANDLES) { /* can only be beztindex==0 here since handles are hidden */ bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); } else { @@ -573,9 +575,10 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short moves, short select) { - struct { short (*mcords)[2]; short moves; short select; } data; + struct { ViewContext vc; short (*mcords)[2]; short moves; short select; } data; /* set vc->editnurb */ + data.vc = *vc; data.mcords = mcords; data.moves = moves; data.select = select; @@ -1196,7 +1199,9 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp, if (bp) { bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT); } else { - if (G.f & G_HIDDENHANDLES) { + Curve *cu= data->vc.obedit->data; + + if (cu->drawflag & CU_HIDE_HANDLES) { /* can only be beztindex==0 here since handles are hidden */ bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT); } else { @@ -1215,7 +1220,7 @@ static void do_nurbs_box_select(ViewContext *vc, rcti *rect, int select) { struct { ViewContext vc; rcti *rect; int select; } data; - data.vc= *vc; + data.vc = *vc; data.rect = rect; data.select = select; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index d86eddd0a64..504563b797b 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1367,7 +1367,8 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) int a; int count=0, countsel=0; int propmode = t->flag & T_PROP_EDIT; - + short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); + /* to be sure */ if(cu->editnurb==NULL) return; @@ -1376,7 +1377,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) if(nu->type == CU_BEZIER) { for(a=0, bezt= nu->bezt; apntsu; a++, bezt++) { if(bezt->hide==0) { - if (G.f & G_HIDDENHANDLES) { + if (hide_handles) { if(bezt->f2 & SELECT) countsel+=3; if(propmode) count+= 3; } else { @@ -1417,13 +1418,13 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) TransDataCurveHandleFlags *hdata = NULL; if( propmode || - ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) || - ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)==0) + ((bezt->f2 & SELECT) && hide_handles) || + ((bezt->f1 & SELECT) && hide_handles == 0) ) { VECCOPY(td->iloc, bezt->vec[0]); td->loc= bezt->vec[0]; VECCOPY(td->center, bezt->vec[1]); - if (G.f & G_HIDDENHANDLES) { + if (hide_handles) { if(bezt->f2 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; } else { @@ -1478,13 +1479,13 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) tail++; } if( propmode || - ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) || - ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0) + ((bezt->f2 & SELECT) && hide_handles) || + ((bezt->f3 & SELECT) && hide_handles == 0) ) { VECCOPY(td->iloc, bezt->vec[2]); td->loc= bezt->vec[2]; VECCOPY(td->center, bezt->vec[1]); - if (G.f & G_HIDDENHANDLES) { + if (hide_handles) { if(bezt->f2 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; } else { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 9fa20c2d674..93bc02d7180 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -260,7 +260,7 @@ int calc_manipulator_stats(const bContext *C) * if handles are hidden then only check the center points. * If 2 or more are selected then only use the center point too. */ - if (G.f & G_HIDDENHANDLES) { + if (cu->drawflag & CU_HIDE_HANDLES) { if (bezt->f2 & SELECT) { calc_tw_center(scene, bezt->vec[1]); totsel++; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 8cf9fbbaf40..fe601eefa32 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -145,7 +145,7 @@ typedef struct Curve { struct BoundBox *bb; - ListBase nurb; /* actual data */ + ListBase nurb; /* actual data, called splines in rna */ ListBase disp; ListBase *editnurb; /* edited data, not in file, use pointer so we can check for it */ @@ -163,7 +163,9 @@ typedef struct Curve { float size[3]; float rot[3]; - int texflag; + int texflag; /* keep an int because of give_obdata_texspace() */ + + short drawflag, pad[3]; short pathlen, totcol; short flag, bevresol; @@ -211,6 +213,10 @@ typedef struct Curve { /* texflag */ #define CU_AUTOSPACE 1 +/* drawflag */ +#define CU_HIDE_HANDLES (1 << 0) +#define CU_HIDE_NORMALS (1 << 1) + /* flag */ #define CU_3D 1 #define CU_FRONT 2 @@ -289,6 +295,10 @@ typedef enum eBezTriple_KeyframeType { BEZT_KEYTYPE_BREAKDOWN, /* 'breakdown' keyframe */ } eBezTriple_KeyframeType; +/* checks if the given BezTriple is selected */ +#define BEZSELECTED(bezt) (((bezt)->f2 & SELECT) || ((bezt)->f1 & SELECT) || ((bezt)->f3 & SELECT)) +#define BEZSELECTED_HIDDENHANDLES(cu, bezt) (((cu)->drawflag & CU_HIDE_HANDLES) ? (bezt)->f2 & SELECT : BEZSELECTED(bezt)) + /* *************** CHARINFO **************** */ /* flag */ diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 7de5976e12c..3fbdf7aaf7d 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -35,6 +35,8 @@ #include "BKE_font.h" +#include "WM_types.h" + EnumPropertyItem beztriple_handle_type_items[] = { {HD_FREE, "FREE", 0, "Free", ""}, {HD_AUTO, "AUTO", 0, "Auto", ""}, @@ -63,7 +65,6 @@ EnumPropertyItem beztriple_keyframe_type_items[] = { #include "BKE_main.h" #include "WM_api.h" -#include "WM_types.h" StructRNA *rna_Curve_refine(PointerRNA *ptr) { @@ -75,6 +76,22 @@ StructRNA *rna_Curve_refine(PointerRNA *ptr) else return &RNA_Curve; } + +static PointerRNA rna_Curve_active_nurb_get(PointerRNA *ptr) +{ + Curve *cu= (Curve*)ptr->data; + Nurb *nu= NULL; + + if(cu->editnurb) + nu = BLI_findlink(cu->editnurb, cu->actnu); + + if(nu) + return rna_pointer_inherit_refine(ptr, &RNA_Nurb, nu); + + return rna_pointer_inherit_refine(ptr, NULL, NULL); +} + + static void rna_BezTriple_handle1_get(PointerRNA *ptr, float *values) { BezTriple *bt= (BezTriple*)ptr->data; @@ -145,18 +162,22 @@ static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max) static void rna_Curve_2d_set(PointerRNA *ptr, int value) { Curve *cu= (Curve*)ptr->id.data; - Nurb *nu; + Nurb *nu= cu->editnurb ? cu->editnurb->first : cu->nurb.first; if(value) { cu->flag &= ~CU_3D; - for(nu= cu->nurb.first; nu; nu= nu->next) { + for( ; nu; nu= nu->next) { nu->flag |= CU_2D; test2DNurb(nu); + + /* since the handles are moved they need to be auto-located again */ + if(nu->type == CU_BEZIER) + calchandlesNurb(nu); } } else { cu->flag |= CU_3D; - for(nu= cu->nurb.first; nu; nu= nu->next) { + for( ; nu; nu= nu->next) { nu->flag &= ~CU_2D; } } @@ -190,6 +211,39 @@ static void rna_Curve_update_data(bContext *C, PointerRNA *ptr) DAG_id_flush_update(id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } + +static void rna_Nurb_update_handle_data(bContext *C, PointerRNA *ptr) +{ + Nurb *nu= (Nurb*)ptr->data; + + if(nu->type == CU_BEZIER) + calchandlesNurb(nu); + + rna_Curve_update_data(C, ptr); +} + +static void rna_Nurb_update_knot_u(bContext *C, PointerRNA *ptr) +{ + Nurb *nu= (Nurb*)ptr->data; + + clamp_nurb_order_u(nu); + makeknots(nu, 1); + + rna_Curve_update_data(C, ptr); +} + +static void rna_Nurb_update_knot_v(bContext *C, PointerRNA *ptr) +{ + Nurb *nu= (Nurb*)ptr->data; + + clamp_nurb_order_v(nu); + makeknots(nu, 2); + + rna_Curve_update_data(C, ptr); +} + + + #else static void rna_def_bpoint(BlenderRNA *brna) @@ -615,10 +669,26 @@ static void rna_def_curve(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "key"); RNA_def_property_ui_text(prop, "Shape Keys", ""); - prop= RNA_def_property(srna, "curves", PROP_COLLECTION, PROP_NONE); + prop= RNA_def_property(srna, "splines", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "nurb", NULL); RNA_def_property_struct_type(prop, "Nurb"); - RNA_def_property_ui_text(prop, "Curves", "Collection of curves in this curve data object."); + RNA_def_property_ui_text(prop, "Splines", "Collection of splines in this curve data object."); + + prop= RNA_def_property(srna, "active_spline", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Nurb"); + RNA_def_property_pointer_funcs(prop, "rna_Curve_active_nurb_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Active Spline", "The active editmode spline"); + + + prop= RNA_def_property(srna, "draw_handles", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "drawflag", CU_HIDE_HANDLES); + RNA_def_property_ui_text(prop, "Draw Handles", "Display bezier handles in editmode."); + RNA_def_property_update(prop, NC_GEOM|ND_DATA, NULL); + + prop= RNA_def_property(srna, "draw_normals", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "drawflag", CU_HIDE_NORMALS); + RNA_def_property_ui_text(prop, "Draw Normals", "Display 3D curve normals in editmode."); + RNA_def_property_update(prop, NC_GEOM|ND_DATA, NULL); rna_def_path(brna, srna); @@ -738,18 +808,18 @@ static void rna_def_curve_nurb(BlenderRNA *brna) PropertyRNA *prop; srna= RNA_def_struct(brna, "Nurb", NULL); - RNA_def_struct_ui_text(srna, "Nurb", "Element of a curve, either Nurb, Bezier or Polyline or a character with text objects."); + RNA_def_struct_ui_text(srna, "Spline", "Element of a curve, either Nurbs, Bezier or Polyline or a character with text objects."); prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "bp", NULL); RNA_def_property_struct_type(prop, "CurvePoint"); RNA_def_property_collection_funcs(prop, "rna_BPoint_array_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_Nurb_length", 0, 0, 0, 0); - RNA_def_property_ui_text(prop, "Points", "Collection of points for Poly and Nurbs curves."); + RNA_def_property_ui_text(prop, "Points", "Collection of points that make up this poly or nurbs spline."); prop= RNA_def_property(srna, "bezier_points", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "BezierCurvePoint"); RNA_def_property_collection_sdna(prop, NULL, "bezt", "pntsu"); - RNA_def_property_ui_text(prop, "Bezier Points", "Collection of points bezier curves only."); + RNA_def_property_ui_text(prop, "Bezier Points", "Collection of points for bezier curves only."); prop= RNA_def_property(srna, "tilt_interpolation", PROP_ENUM, PROP_NONE); @@ -787,14 +857,14 @@ static void rna_def_curve_nurb(BlenderRNA *brna) prop= RNA_def_property(srna, "order_u", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "orderu"); RNA_def_property_range(prop, 2, 6); - RNA_def_property_ui_text(prop, "Order U", "Nurbs order in the U direction (For curves and surfaces), Higher values let points influence a greater area"); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_ui_text(prop, "Order U", "Nurbs order in the U direction (For splines and surfaces), Higher values let points influence a greater area"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_u"); prop= RNA_def_property(srna, "order_v", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "orderv"); RNA_def_property_range(prop, 2, 6); RNA_def_property_ui_text(prop, "Order V", "Nurbs order in the V direction (For surfaces only), Higher values let points influence a greater area"); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_v"); prop= RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE); @@ -812,7 +882,7 @@ static void rna_def_curve_nurb(BlenderRNA *brna) prop= RNA_def_property(srna, "cyclic_u", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagu", CU_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic U", "Make this curve or surface a closed loop in the U direction."); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_handle_data"); /* only needed for cyclic_u because cyclic_v cant do bezier */ prop= RNA_def_property(srna, "cyclic_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagv", CU_CYCLIC); @@ -824,22 +894,22 @@ static void rna_def_curve_nurb(BlenderRNA *brna) prop= RNA_def_property(srna, "endpoint_u", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagu", 2); RNA_def_property_ui_text(prop, "Endpoint U", "Make this nurbs curve or surface meet the endpoints in the U direction (Cyclic U must be disabled)."); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_u"); prop= RNA_def_property(srna, "endpoint_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagv", 2); RNA_def_property_ui_text(prop, "Endpoint V", "Make this nurbs surface meet the endpoints in the V direction (Cyclic V must be disabled)."); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_v"); prop= RNA_def_property(srna, "bezier_u", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagu", 4); RNA_def_property_ui_text(prop, "Bezier U", "Make this nurbs curve or surface act like a bezier spline in the U direction (Order U must be 3 or 4, Cyclic U must be disabled)."); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_u"); prop= RNA_def_property(srna, "bezier_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flagv", 4); RNA_def_property_ui_text(prop, "Bezier V", "Make this nurbs surface act like a bezier spline in the V direction (Order V must be 3 or 4, Cyclic V must be disabled)."); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_v"); prop= RNA_def_property(srna, "smooth", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index bd29443646d..f196001cc9d 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -458,6 +458,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); + prop= RNA_def_property(srna, "normal_size", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "normalsize"); + RNA_def_property_ui_text(prop, "Normal Size", "Display size for normals in the 3D view."); + RNA_def_property_range(prop, 0.00001, 1000.0); + RNA_def_property_ui_range(prop, 0.01, 10.0, 0.1, 2); + RNA_def_property_update(prop, NC_GEOM|ND_DATA, NULL); + prop= RNA_def_property(srna, "automerge_editing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "automerge", 0); RNA_def_property_ui_text(prop, "AutoMerge Editing", "Automatically merge vertices moved to the same location."); -- cgit v1.2.3 From b9816c98bc0ffaa4992362aca0239c0f6832eccd Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 8 Sep 2009 08:15:56 +0000 Subject: * Volume render weaks/fixes/etc from Alfredo, after code review - General correctness tweaks - Light cache is enabled for all objects now - Metaballs now give density info, for smooth falloff --- .../blender/render/intern/source/convertblender.c | 11 +- .../blender/render/intern/source/volume_precache.c | 6 +- source/blender/render/intern/source/volumetric.c | 162 ++++++++++++++------- 3 files changed, 118 insertions(+), 61 deletions(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 73ff826994a..99825c0c2ff 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3078,9 +3078,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) } need_nmap_tangent= 1; } - - if (ma->material_type == MA_TYPE_VOLUME) - add_volume(re, obr, ma); } } @@ -4273,7 +4270,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * ObjectRen *obr; ObjectInstanceRen *obi; ParticleSystem *psys; - int show_emitter, allow_render= 1, index, psysindex; + int show_emitter, allow_render= 1, index, psysindex, i; index= (dob)? dob->index: 0; @@ -4309,6 +4306,12 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * } else find_dupli_instances(re, obr); + + for (i=1; i<=ob->totcol; i++) { + Material* ma = give_render_material(re, ob, i); + if (ma && ma->material_type == MA_TYPE_VOLUME) + add_volume(re, obr, ma); + } } /* and one render object per particle system */ diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index d5a54759332..15d8643fea4 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -430,13 +430,13 @@ static void *vol_precache_part(void *data) const float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW); for (z= pa->minz; z < pa->maxz; z++) { - co[2] = pa->bbmin[2] + (pa->voxel[2] * z); + co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f)); for (y= pa->miny; y < pa->maxy; y++) { - co[1] = pa->bbmin[1] + (pa->voxel[1] * y); + co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f)); for (x=pa->minx; x < pa->maxx; x++) { - co[0] = pa->bbmin[0] + (pa->voxel[0] * x); + co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f)); // don't bother if the point is not inside the volume mesh if (!point_inside_obi(tree, obi, co)) { diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 4fa31674bbe..bc425c8a1a3 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -44,6 +44,7 @@ #include "DNA_material_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" +#include "DNA_meta_types.h" #include "BKE_global.h" @@ -64,6 +65,11 @@ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* luminance rec. 709 */ +inline float luminance(float* col) +{ + return (0.212671f*col[0] + 0.71516f*col[1] + 0.072169f*col[2]); +} /* tracing */ @@ -211,13 +217,66 @@ static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, fl scatter_col[2] = voxel_sample_trilinear(vp->data_b, vp->res, sample_co); } +/* Meta object density, brute force for now + * (might be good enough anyway, don't need huge number of metaobs to model volumetric objects */ +static float metadensity(Object* ob, float* co) +{ + float mat[4][4], imat[4][4], dens = 0.f; + MetaBall* mb = (MetaBall*)ob->data; + MetaElem* ml; + + /* transform co to meta-element */ + float tco[3] = {co[0], co[1], co[2]}; + Mat4MulMat4(mat, ob->obmat, R.viewmat); + Mat4Invert(imat, mat); + Mat4MulVecfl(imat, tco); + + for (ml = mb->elems.first; ml; ml=ml->next) { + float bmat[3][3], dist2; + + /* element rotation transform */ + float tp[3] = {ml->x - tco[0], ml->y - tco[1], ml->z - tco[2]}; + QuatToMat3(ml->quat, bmat); + Mat3Transp(bmat); // rot.only, so inverse == transpose + Mat3MulVecfl(bmat, tp); + + /* MB_BALL default */ + switch (ml->type) { + case MB_ELIPSOID: + tp[0] /= ml->expx, tp[1] /= ml->expy, tp[2] /= ml->expz; + break; + case MB_CUBE: + tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f); + // no break, xy as plane + case MB_PLANE: + tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f); + // no break, x as tube + case MB_TUBE: + tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f); + } + + /* ml->rad2 is not set */ + dist2 = 1.f - ((tp[0]*tp[0] + tp[1]*tp[1] + tp[2]*tp[2]) / (ml->rad*ml->rad)); + if (dist2 > 0.f) + dens += (ml->flag & MB_NEGATIVE) ? -ml->s*dist2*dist2*dist2 : ml->s*dist2*dist2*dist2; + } + + dens -= mb->thresh; + return (dens < 0.f) ? 0.f : dens; +} + float vol_get_density(struct ShadeInput *shi, float *co) { float density = shi->mat->vol.density; float density_scale = shi->mat->vol.density_scale; - float col[3] = {0.0, 0.0, 0.0}; + + do_volume_tex(shi, co, MAP_DENSITY, NULL, &density); - do_volume_tex(shi, co, MAP_DENSITY, col, &density); + // if meta-object, modulate by metadensity without increasing it + if (shi->obi->obr->ob->type == OB_MBALL) { + const float md = metadensity(shi->obi->obr->ob, co); + if (md < 1.f) density *= md; + } return density * density_scale; } @@ -260,7 +319,6 @@ void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co) absorb_col[2] = (1.0f - absorb_col[2]) * absorption; } - /* phase function - determines in which directions the light * is scattered in the volume relative to incoming direction * and view direction */ @@ -298,70 +356,66 @@ float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w } } -/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. - * Used in the relationship Transmittance = e^(-attenuation) - */ -void vol_get_attenuation_seg(ShadeInput *shi, float *transmission, float stepsize, float *co, float density) +/* Compute transmittance = e^(-attenuation) */ +void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float *co, float density) { /* input density = density at co */ float tau[3] = {0.f, 0.f, 0.f}; - float absorb_col[3]; + float absorb[3]; + const float scatter_dens = vol_get_scattering_fac(shi, co) * density * stepsize; - vol_get_absorption(shi, absorb_col, co); + vol_get_absorption(shi, absorb, co); /* homogenous volume within the sampled distance */ - tau[0] = stepsize * density * absorb_col[0]; - tau[1] = stepsize * density * absorb_col[1]; - tau[2] = stepsize * density * absorb_col[2]; + tau[0] += scatter_dens * absorb[0]; + tau[1] += scatter_dens * absorb[1]; + tau[2] += scatter_dens * absorb[2]; - transmission[0] *= exp(-tau[0]); - transmission[1] *= exp(-tau[1]); - transmission[2] *= exp(-tau[2]); + tr[0] *= exp(-tau[0]); + tr[1] *= exp(-tau[1]); + tr[2] *= exp(-tau[2]); } -/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau. - * Used in the relationship Transmittance = e^(-attenuation) - */ -void vol_get_attenuation(ShadeInput *shi, float *transmission, float *co, float *endco, float density, float stepsize) +/* Compute transmittance = e^(-attenuation) */ +static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float *endco) { - /* input density = density at co */ + float p[3] = {co[0], co[1], co[2]}; + float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]}; + //const float ambtau = -logf(shi->mat->vol.depth_cutoff); // never zero float tau[3] = {0.f, 0.f, 0.f}; - float absorb_col[3]; - int s, nsteps; - float step_vec[3], step_sta[3], step_end[3]; - const float dist = VecLenf(co, endco); - - vol_get_absorption(shi, absorb_col, co); - nsteps = (int)((dist / stepsize) + 0.5); - - VecSubf(step_vec, endco, co); - VecMulf(step_vec, 1.0f / nsteps); - - VecCopyf(step_sta, co); - VecAddf(step_end, step_sta, step_vec); - - for (s = 0; s < nsteps; s++) { - if (s > 0) - density = vol_get_density(shi, step_sta); + float t0 = 0.f; + float t1 = Normalize(step_vec); + float pt0 = t0; + + t0 += shi->mat->vol.shade_stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread)); + p[0] += t0 * step_vec[0]; + p[1] += t0 * step_vec[1]; + p[2] += t0 * step_vec[2]; + VecMulf(step_vec, shi->mat->vol.shade_stepsize); + + for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.shade_stepsize) { + float absorb[3]; + const float d = vol_get_density(shi, p); + const float stepd = (t0 - pt0) * d; + const float scatter_dens = vol_get_scattering_fac(shi, p) * stepd; + vol_get_absorption(shi, absorb, p); - tau[0] += stepsize * density; - tau[1] += stepsize * density; - tau[2] += stepsize * density; + tau[0] += scatter_dens * absorb[0]; + tau[1] += scatter_dens * absorb[1]; + tau[2] += scatter_dens * absorb[2]; - if (s < nsteps-1) { - VecCopyf(step_sta, step_end); - VecAddf(step_end, step_end, step_vec); - } + //if (luminance(tau) >= ambtau) break; + VecAddf(p, p, step_vec); } - VecMulVecf(tau, tau, absorb_col); - transmission[0] *= exp(-tau[0]); - transmission[1] *= exp(-tau[1]); - transmission[2] *= exp(-tau[2]); + /* return transmittance */ + tr[0] = expf(-tau[0]); + tr[1] = expf(-tau[1]); + tr[2] = expf(-tau[2]); } -void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol, float stepsize, float density) +void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol) { float visifac, lv[3], lampdist; float tr[3]={1.0,1.0,1.0}; @@ -383,7 +437,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float * do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE); } - VecMulf(lacol, visifac*lar->energy); + VecMulf(lacol, visifac); if (ELEM(lar->type, LA_SUN, LA_HEMI)) VECCOPY(lv, lar->vec); @@ -411,7 +465,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float * } else atten_co = hitco; - vol_get_attenuation(shi, tr, co, atten_co, density, shade_stepsize); + vol_get_transmittance(shi, tr, co, atten_co); VecMulVecf(lacol, lacol, tr); } @@ -445,7 +499,7 @@ void vol_get_scattering(ShadeInput *shi, float *scatter_col, float *co, float st lar= go->lampren; if (lar) { - vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density); + vol_shade_one_lamp(shi, co, lar, lacol); VecAddf(scatter_col, scatter_col, lacol); } } @@ -490,7 +544,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float if (density > 0.01f) { /* transmittance component (alpha) */ - vol_get_attenuation_seg(shi, tr, stepsize, co, density); + vol_get_transmittance_seg(shi, tr, stepsize, co, density); step_mid[0] = step_sta[0] + (stepvec[0] * 0.5); step_mid[1] = step_sta[1] + (stepvec[1] * 0.5); @@ -654,7 +708,7 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct } density = vol_get_density(shi, startco); - vol_get_attenuation(shi, tr, startco, endco, density, shade_stepsize); + vol_get_transmittance(shi, tr, startco, endco); VecCopyf(shr->combined, tr); shr->combined[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]); -- cgit v1.2.3 From 5ce8b1f70476626aae9a5a818398cf9e55a679af Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 8 Sep 2009 09:41:15 +0000 Subject: 2.5 - FollowPath Constraint + File Loading Bugfix * Added a new option ('Fixed Position') for Follow Path constraint which allows you to constrain an object/bone to some fixed position along the curve. Unlike the default mode of operation, this doesn't depend on time unless you explicitly animate the offset percentage parameter associated with this. * Made old (pre 2.5) files saved with armatures in pose mode load in pose mode again. --- release/ui/buttons_object_constraint.py | 14 +++++++++++--- source/blender/blenkernel/intern/constraint.c | 23 ++++++++++++++++------- source/blender/blenloader/intern/readfile.c | 6 ++++++ source/blender/makesdna/DNA_constraint_types.h | 7 ++++++- source/blender/makesrna/intern/rna_constraint.c | 16 ++++++++++++++-- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py index cdc18e3545c..ff3231a9d61 100644 --- a/release/ui/buttons_object_constraint.py +++ b/release/ui/buttons_object_constraint.py @@ -121,9 +121,17 @@ class ConstraintButtonsPanel(bpy.types.Panel): def FOLLOW_PATH(self, layout, con): self.target_template(layout, con) - row = layout.row() - row.itemR(con, "curve_follow") - row.itemR(con, "offset") + split = layout.split() + + col = split.column() + col.itemR(con, "curve_follow") + + col = split.column() + col.itemR(con, "fixed_position") + if con.fixed_position: + col.itemR(con, "offset_percentage", text="Offset") + else: + col.itemR(con, "offset") row = layout.row() row.itemL(text="Forward:") diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 0f7767a1808..dfbcc51a93c 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1178,17 +1178,26 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr makeDispListCurveTypes(cob->scene, ct->tar, 0); if (cu->path && cu->path->data) { - curvetime= bsystem_time(cob->scene, ct->tar, (float)ctime, 0.0) - data->offset; - -#if 0 // XXX old animation system - if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) { - curvetime /= cu->pathlen; + if ((data->followflag & FOLLOWPATH_STATIC) == 0) { + /* animated position along curve depending on time */ + curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset; + + /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, + * but this will only work if it actually is animated... + * + * we firstly calculate the modulus of cu->ctime/cu->pathlen to clamp ctime within the 0.0 to 1.0 times pathlen + * range, then divide this (the modulus) by pathlen to get a value between 0.0 and 1.0 + */ + curvetime= fmod(cu->ctime, cu->pathlen) / cu->pathlen; CLAMP(curvetime, 0.0, 1.0); } -#endif // XXX old animation system + else { + /* fixed position along curve */ + curvetime= data->offset; // XXX might need a more sensible value + } if ( where_on_path(ct->tar, curvetime, vec, dir) ) { - if (data->followflag) { + if (data->followflag & FOLLOWPATH_FOLLOW) { vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat); Normalize(dir); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index db97657a2ee..618e587d674 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9596,6 +9596,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 2)) { Scene *sce; + Object *ob; for(sce = main->scene.first; sce; sce = sce->id.next) { if(fd->fileflags & G_FILE_ENABLE_ALL_FRAMES) @@ -9628,6 +9629,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->gm.flag |= GAME_DISPLAY_LISTS; } + + for(ob = main->object.first; ob; ob = ob->id.next) { + if(ob->flag & 8192) // OB_POSEMODE = 8192 + ob->mode |= OB_MODE_POSE; + } } /* put 2.50 compatibility code here until next subversion bump */ diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 6fab633b192..a92dc836197 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -64,7 +64,8 @@ typedef struct bConstraint { float enforce; /* Amount of influence exherted by constraint (0.0-1.0) */ float headtail; /* Point along subtarget bone where the actual target is. 0=head (default for all), 1=tail*/ int pad; - struct Ipo *ipo; /* local influence ipo or driver */ + + struct Ipo *ipo; /* local influence ipo or driver */ // XXX depreceated for 2.5... old animation system hack } bConstraint; @@ -449,6 +450,10 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG { #define TRACK_nY 0x04 #define TRACK_nZ 0x05 +/* FollowPath flags */ +#define FOLLOWPATH_FOLLOW 0x01 +#define FOLLOWPATH_STATIC 0x02 + /* bTrackToConstraint->flags */ #define TARGET_Z_UP 0x01 diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index c09a71f752a..83f3042d8ee 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -871,9 +871,15 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); prop= RNA_def_property(srna, "offset", PROP_INT, PROP_TIME); - RNA_def_property_range(prop, -300000.0, 300000.f); + RNA_def_property_range(prop, MINAFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Offset", "Offset from the position corresponding to the time frame."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + prop= RNA_def_property(srna, "offset_percentage", PROP_FLOAT, PROP_PERCENTAGE); + RNA_def_property_float_sdna(prop, NULL, "offset"); // XXX we might be better with another var or some hackery? + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Offset Percentage", "Percentage value defining target position along length of bone."); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); prop= RNA_def_property(srna, "forward", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "trackflag"); @@ -888,8 +894,14 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); prop= RNA_def_property(srna, "curve_follow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "followflag", 1); + RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_FOLLOW); RNA_def_property_ui_text(prop, "Follow Curve", "Object will follow the heading and banking of the curve."); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + // TODO: do we need to do some special trickery to get offset sane for this? + prop= RNA_def_property(srna, "fixed_position", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_STATIC); + RNA_def_property_ui_text(prop, "Fixed Position", "Object will stay locked to a single point somewhere along the length of the curve regardless of time."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); } -- cgit v1.2.3 From 31fec003a1ff611433992c4c7ebc03867afb8d0b Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 8 Sep 2009 11:14:36 +0000 Subject: Fix row/column order in matrix printout function. --- source/blender/python/generic/matrix.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index 37d06d0b531..edb6fb7af63 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -598,18 +598,18 @@ static PyObject *Matrix_repr(MatrixObject * self) return NULL; BLI_strncpy(str,"",1024); - for(x = 0; x < self->rowSize; x++){ + for(x = 0; x < self->colSize; x++){ sprintf(buffer, "["); strcat(str,buffer); - for(y = 0; y < (self->colSize - 1); y++) { - sprintf(buffer, "%.6f, ", self->matrix[x][y]); + for(y = 0; y < (self->rowSize - 1); y++) { + sprintf(buffer, "%.6f, ", self->matrix[y][x]); strcat(str,buffer); } - if(x < (self->rowSize-1)){ - sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[x][y], x); + if(x < (self->colSize-1)){ + sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[y][x], x); strcat(str,buffer); }else{ - sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[x][y], x); + sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[y][x], x); strcat(str,buffer); } } @@ -703,7 +703,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) return -1; if(i >= self->rowSize || i < 0){ - PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad row\n"); + PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad column\n"); return -1; } -- cgit v1.2.3 From ee78c63beea4e68a4211f218c67357610003e488 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Tue, 8 Sep 2009 11:31:15 +0000 Subject: Text UI *Added Text Boxes panel, currently only shows the first textbox. Needs operators for adding/removing *Added Bold/Italic/Underline items *Cleaned up some font UI layout. --- release/ui/buttons_data_text.py | 74 ++++++++++++++++++++---------- source/blender/makesrna/intern/rna_curve.c | 6 +-- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py index aabf218122f..4db5803c4eb 100644 --- a/release/ui/buttons_data_text.py +++ b/release/ui/buttons_data_text.py @@ -38,7 +38,6 @@ class DATA_PT_shape_text(DataButtonsPanel): curve = context.curve space = context.space_data - layout.itemR(curve, "curve_2d") split = layout.split() @@ -76,13 +75,15 @@ class DATA_PT_geometry_text(DataButtonsPanel): col.itemL(text="Modification:") col.itemR(curve, "width") col.itemR(curve, "extrude") - col.itemR(curve, "taper_object") + col.itemL(text="Taper Object:") + col.itemR(curve, "taper_object", text="") col = split.column() col.itemL(text="Bevel:") col.itemR(curve, "bevel_depth", text="Depth") col.itemR(curve, "bevel_resolution", text="Resolution") - col.itemR(curve, "bevel_object") + col.itemL(text="Bevel Object:") + col.itemR(curve, "bevel_object", text="") class DATA_PT_font(DataButtonsPanel): __label__ = "Font" @@ -91,27 +92,39 @@ class DATA_PT_font(DataButtonsPanel): layout = self.layout text = context.curve - + char = context.curve.edit_format + layout.itemR(text, "font") + row = layout.row() + row.itemR(text, "text_size", text="Size") + row.itemR(text, "shear") + split = layout.split() - col = split.column() - # col.itemR(text, "style") - # col.itemR(text, "bold") - # col.itemR(text, "italic") - # col.itemR(text, "underline") - # ToDo: These settings are in a sub struct (Edit Format). - col.itemR(text, "text_size") - col.itemR(text, "shear") - col = split.column() - col.itemR(text, "text_on_curve") - col.itemR(text, "family") + col.itemL(text="Object Font:") + col.itemR(text, "family", text="") + + col = split.column() + col.itemL(text="Text on Curve:") + col.itemR(text, "text_on_curve", text="") + + split = layout.split() + + col = split.column() + col.itemL(text="Character:") + col.itemR(char, "bold") + col.itemR(char, "italic") + col.itemR(char, "underline") +# col.itemR(char, "style") +# col.itemR(char, "wrap") + + col = split.column(align=True) col.itemL(text="Underline:") col.itemR(text, "ul_position", text="Position") - col.itemR(text, "ul_height", text="Height") - # col.itemR(text, "edit_format") + col.itemR(text, "ul_height", text="Thickness") + class DATA_PT_paragraph(DataButtonsPanel): __label__ = "Paragraph" @@ -136,21 +149,32 @@ class DATA_PT_paragraph(DataButtonsPanel): col.itemL(text="Offset:") col.itemR(text, "offset_x", text="X") col.itemR(text, "offset_y", text="Y") - #col.itemR(text, "wrap") -""" + class DATA_PT_textboxes(DataButtonsPanel): - __label__ = "Text Boxes" + __label__ = "Text Boxes" - def draw(self, context): - layout = self.layout + def draw(self, context): + layout = self.layout - text = context.curve -""" + text = context.curve + box = context.curve.textbox + + split = layout.box().split() + + col = split.column(align=True) + col.itemL(text="Dimensions:") + col.itemR(box, "width", text="Width") + col.itemR(box, "height", text="Height") + + col = split.column(align=True) + col.itemL(text="Offset:") + col.itemR(box, "x", text="X") + col.itemR(box, "y", text="Y") bpy.types.register(DATA_PT_context_text) bpy.types.register(DATA_PT_shape_text) bpy.types.register(DATA_PT_geometry_text) bpy.types.register(DATA_PT_font) bpy.types.register(DATA_PT_paragraph) -#bpy.types.register(DATA_PT_textboxes) +bpy.types.register(DATA_PT_textboxes) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 3fbdf7aaf7d..0a796bd431d 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -500,13 +500,13 @@ static void rna_def_font(BlenderRNA *brna, StructRNA *srna) prop= RNA_def_property(srna, "ul_position", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ulpos"); RNA_def_property_range(prop, -0.2f, 0.8f); - RNA_def_property_ui_text(prop, "Underline position", "Vertical position of underline"); + RNA_def_property_ui_text(prop, "Underline Position", "Vertical position of underline"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop= RNA_def_property(srna, "ul_height", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ulheight"); RNA_def_property_range(prop, -0.2f, 0.8f); - RNA_def_property_ui_text(prop, "Underline thickness", ""); + RNA_def_property_ui_text(prop, "Underline Thickness", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop= RNA_def_property(srna, "active_textbox", PROP_INT, PROP_NONE); @@ -518,7 +518,7 @@ static void rna_def_font(BlenderRNA *brna, StructRNA *srna) /* strings */ prop= RNA_def_property(srna, "family", PROP_STRING, PROP_NONE); RNA_def_property_string_maxlength(prop, 21); - RNA_def_property_ui_text(prop, "Family", "Blender uses font from selfmade objects."); + RNA_def_property_ui_text(prop, "Object Font", "Use Blender Objects as font characters. Give font objects a common name followed by the character it represents, eg. familya, familyb etc, and turn on Verts Duplication"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop= RNA_def_property(srna, "str", PROP_STRING, PROP_NONE); -- cgit v1.2.3 From e6965c46fc1305a37a2778fb1746216f3d482295 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Sep 2009 22:46:14 +0000 Subject: patch from Maurice & Patsoko on blenderartist for win32 registry support, moved "import winreg" inline, (so other OS's don't import it), untested but should be ok. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- From the thread It's the version of r23036 + winreg patch from Maurice. About the registry keys: - I have povray 3.6 and 3.7b34 installed on vista32. - In the registry, I have 3 choices : ' CurrentVersion ', ' v3.6 ', and ' v3.7'. - I've modified Maurice's patch by replacing CurrentVersion by v3.6. We have the benefit to have the keys for each version so I prefer use them rather than the 'floating-key-about-which-is-the current-version'. I found more secure like that. --- release/io/engine_render_pov.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/release/io/engine_render_pov.py b/release/io/engine_render_pov.py index 02b8aab4c42..22cf1a36dbb 100644 --- a/release/io/engine_render_pov.py +++ b/release/io/engine_render_pov.py @@ -740,10 +740,13 @@ class PovrayRender(bpy.types.RenderEngine): pov_binary = "povray" if sys.platform=='win32': + import winreg + regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.6\\Windows') + if bitness == 64: - pov_binary = "pvengine64" + pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64' else: - pov_binary = "pvengine" + pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine' if 1: self.process = subprocess.Popen([pov_binary, self.temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE -- cgit v1.2.3 From 850abb3580f97f44562b081bf115c845abf31ca1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2009 00:10:12 +0000 Subject: curve.textboxes collection access for the UI + minor UI tweaks for poly curves --- release/ui/buttons_data_curve.py | 101 ++++++++++++++++------------- release/ui/buttons_data_text.py | 45 +++++++------ source/blender/makesrna/intern/rna_curve.c | 23 ++++--- 3 files changed, 95 insertions(+), 74 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 95f9a98da74..1124dfd1ae8 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -15,7 +15,7 @@ class DataButtonsPanelCurve(DataButtonsPanel): ''' def poll(self, context): return (context.object and context.object.type == 'CURVE' and context.curve) - + class DataButtonsPanelActive(DataButtonsPanel): ''' Same as above but for curves only @@ -80,7 +80,7 @@ class DATA_PT_shape_curve(DataButtonsPanel): sub = col.column(align=True) sub.itemR(curve, "resolution_u", text="Preview U") sub.itemR(curve, "render_resolution_u", text="Render U") - + if is_surf: sub = col.column(align=True) sub.itemR(curve, "resolution_v", text="Preview V") @@ -150,59 +150,70 @@ class DATA_PT_active_spline(DataButtonsPanelActive): curve = context.curve act_spline = curve.active_spline is_surf = (ob.type == 'SURFACE') + is_poly = (act_spline.type == 'POLY') split = layout.split() - col = split.column() - col.itemL(text="Cyclic:") - if act_spline.type == 'NURBS': - col.itemL(text="Bezier:") - col.itemL(text="Endpoint:") - col.itemL(text="Order:") - col.itemL(text="Resolution:") - - col = split.column() - col.itemR(act_spline, "cyclic_u", text="U") + if is_poly: + # These settings are below but its easier to have + # poly's set aside since they use so few settings + col = split.column() + col.itemL(text="Cyclic:") + col.itemR(act_spline, "smooth") + col = split.column() + col.itemR(act_spline, "cyclic_u", text="U") - if act_spline.type == 'NURBS': - sub = col.column() - sub.active = (not act_spline.cyclic_u) - sub.itemR(act_spline, "bezier_u", text="U") - sub.itemR(act_spline, "endpoint_u", text="U") + else: + col = split.column() + col.itemL(text="Cyclic:") + if act_spline.type == 'NURBS': + col.itemL(text="Bezier:") + col.itemL(text="Endpoint:") + col.itemL(text="Order:") - sub = col.column() - sub.itemR(act_spline, "order_u", text="U") - col.itemR(act_spline, "resolution_u", text="U") - - if is_surf: + col.itemL(text="Resolution:") + col = split.column() - col.itemR(act_spline, "cyclic_v", text="V") + col.itemR(act_spline, "cyclic_u", text="U") - # its a surface, assume its a nurb. - sub = col.column() - sub.active = (not act_spline.cyclic_v) - sub.itemR(act_spline, "bezier_v", text="V") - sub.itemR(act_spline, "endpoint_v", text="V") - sub = col.column() - sub.itemR(act_spline, "order_v", text="V") - sub.itemR(act_spline, "resolution_v", text="V") + if act_spline.type == 'NURBS': + sub = col.column() + # sub.active = (not act_spline.cyclic_u) + sub.itemR(act_spline, "bezier_u", text="U") + sub.itemR(act_spline, "endpoint_u", text="U") + + sub = col.column() + sub.itemR(act_spline, "order_u", text="U") + col.itemR(act_spline, "resolution_u", text="U") + + if is_surf: + col = split.column() + col.itemR(act_spline, "cyclic_v", text="V") + + # its a surface, assume its a nurb. + sub = col.column() + sub.active = (not act_spline.cyclic_v) + sub.itemR(act_spline, "bezier_v", text="V") + sub.itemR(act_spline, "endpoint_v", text="V") + sub = col.column() + sub.itemR(act_spline, "order_v", text="V") + sub.itemR(act_spline, "resolution_v", text="V") - - if not is_surf: + + if not is_surf: + split = layout.split() + col = split.column() + col.active = (not curve.curve_2d) + + col.itemL(text="Interpolation:") + col.itemR(act_spline, "tilt_interpolation", text="Tilt") + col.itemR(act_spline, "radius_interpolation", text="Radius") + split = layout.split() col = split.column() - col.active = (not curve.curve_2d) - - col.itemL(text="Interpolation:") - col.itemR(act_spline, "tilt_interpolation", text="Tilt") - col.itemR(act_spline, "radius_interpolation", text="Radius") - - - split = layout.split() - col = split.column() - col.itemR(act_spline, "smooth") - - + col.itemR(act_spline, "smooth") + + bpy.types.register(DATA_PT_context_curve) bpy.types.register(DATA_PT_shape_curve) bpy.types.register(DATA_PT_geometry_curve) diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py index 4db5803c4eb..d0e7ea09a92 100644 --- a/release/ui/buttons_data_text.py +++ b/release/ui/buttons_data_text.py @@ -44,8 +44,10 @@ class DATA_PT_shape_text(DataButtonsPanel): col = split.column() col.itemL(text="Caps:") - col.itemR(curve, "front") - col.itemR(curve, "back") + row = col.row() + row .itemR(curve, "front") + row .itemR(curve, "back") + # col = split.column() col.itemL(text="Textures:") col.itemR(curve, "uv_orco") col.itemR(curve, "auto_texspace") @@ -55,11 +57,12 @@ class DATA_PT_shape_text(DataButtonsPanel): sub = col.column(align=True) sub.itemR(curve, "resolution_u", text="Preview U") sub.itemR(curve, "render_resolution_u", text="Render U") + + # resolution_v is not used for text + sub = col.column(align=True) - sub.itemR(curve, "resolution_v", text="Preview V") - sub.itemR(curve, "render_resolution_v", text="Render V") col.itemL(text="Display:") - col.itemR(curve, "fast") + col.itemR(curve, "fast", text="Fast Editing") class DATA_PT_geometry_text(DataButtonsPanel): __label__ = "Geometry" @@ -93,19 +96,19 @@ class DATA_PT_font(DataButtonsPanel): text = context.curve char = context.curve.edit_format - + layout.itemR(text, "font") row = layout.row() row.itemR(text, "text_size", text="Size") row.itemR(text, "shear") - + split = layout.split() - col = split.column() + col = split.column() col.itemL(text="Object Font:") col.itemR(text, "family", text="") - + col = split.column() col.itemL(text="Text on Curve:") col.itemR(text, "text_on_curve", text="") @@ -158,19 +161,19 @@ class DATA_PT_textboxes(DataButtonsPanel): layout = self.layout text = context.curve - box = context.curve.textbox - - split = layout.box().split() - - col = split.column(align=True) - col.itemL(text="Dimensions:") - col.itemR(box, "width", text="Width") - col.itemR(box, "height", text="Height") - col = split.column(align=True) - col.itemL(text="Offset:") - col.itemR(box, "x", text="X") - col.itemR(box, "y", text="Y") + for box in text.textboxes: + split = layout.box().split() + + col = split.column(align=True) + col.itemL(text="Dimensions:") + col.itemR(box, "width", text="Width") + col.itemR(box, "height", text="Height") + + col = split.column(align=True) + col.itemL(text="Offset:") + col.itemR(box, "x", text="X") + col.itemR(box, "y", text="Y") bpy.types.register(DATA_PT_context_text) bpy.types.register(DATA_PT_shape_text) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 0a796bd431d..91628bab376 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -159,6 +159,14 @@ static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max) *max= cu->totcol-1; } +static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int *max) +{ + Curve *cu= (Curve*)ptr->id.data; + *min= 0; + *max= cu->totbox-1; +} + + static void rna_Curve_2d_set(PointerRNA *ptr, int value) { Curve *cu= (Curve*)ptr->id.data; @@ -509,11 +517,15 @@ static void rna_def_font(BlenderRNA *brna, StructRNA *srna) RNA_def_property_ui_text(prop, "Underline Thickness", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + prop= RNA_def_property(srna, "textboxes", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "tb", "totbox"); + RNA_def_property_struct_type(prop, "TextBox"); + RNA_def_property_ui_text(prop, "Textboxes", ""); + prop= RNA_def_property(srna, "active_textbox", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "actbox"); - RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "The active text box", ""); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Curve_active_textbox_index_range"); /* strings */ prop= RNA_def_property(srna, "family", PROP_STRING, PROP_NONE); @@ -539,12 +551,7 @@ static void rna_def_font(BlenderRNA *brna, StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "vfont"); RNA_def_property_ui_text(prop, "Font", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - - prop= RNA_def_property(srna, "textbox", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "tb"); - RNA_def_property_ui_text(prop, "Textbox", ""); - RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - + prop= RNA_def_property(srna, "edit_format", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "curinfo"); RNA_def_property_ui_text(prop, "Edit Format", "Editing settings character formatting."); -- cgit v1.2.3 From 2e851fdc67a0613cb17436cfe28ebd69fff8c9c2 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 9 Sep 2009 02:25:14 +0000 Subject: frame range restrictions for dependencies, so slaves only receive point cache files for the frames that they need to render (supports step > 1, of course) --- release/io/netrender/client.py | 104 ++++++++++++++++++++++++++++++++++++++ release/io/netrender/master.py | 6 ++- release/io/netrender/model.py | 7 ++- release/io/netrender/operators.py | 3 +- release/io/netrender/slave.py | 5 +- release/io/netrender/utils.py | 75 +-------------------------- 6 files changed, 120 insertions(+), 80 deletions(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index 59cb19c2075..da27a8ecc57 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -7,6 +7,110 @@ import netrender.slave as slave import netrender.master as master from netrender.utils import * + +def clientSendJob(conn, scene, anim = False, chunks = 5): + netsettings = scene.network_render + job = netrender.model.RenderJob() + + if anim: + for f in range(scene.start_frame, scene.end_frame + 1): + job.addFrame(f) + else: + job.addFrame(scene.current_frame) + + filename = bpy.data.filename + job.addFile(filename) + + job_name = netsettings.job_name + path, name = os.path.split(filename) + if job_name == "[default]": + job_name = name + + for lib in bpy.data.libraries: + lib_path = lib.filename + + if lib_path.startswith("//"): + lib_path = path + os.sep + lib_path[2:] + + job.addFile(lib_path) + + root, ext = os.path.splitext(name) + cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that + + print("cache:", cache_path) + + if os.path.exists(cache_path): + caches = {} + pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") + for cache_file in sorted(os.listdir(cache_path)): + match = pattern.match(cache_file) + + if match: + cache_id = match.groups()[0] + cache_frame = int(match.groups()[1]) + + cache_files = caches.get(cache_id, []) + cache_files.append((cache_frame, cache_file)) + caches[cache_id] = cache_files + + for cache in caches.values(): + cache.sort() + + if len(cache) == 1: + cache_frame, cache_file = cache[0] + job.addFile(cache_path + cache_file, cache_frame, cache_frame) + else: + for i in range(len(cache)): + current_item = cache[i] + next_item = cache[i+1] if i + 1 < len(cache) else None + previous_item = cache[i - 1] if i > 0 else None + + current_frame, current_file = current_item + + if not next_item and not previous_item: + job.addFile(cache_path + current_file, current_frame, current_frame) + elif next_item and not previous_item: + next_frame = next_item[0] + job.addFile(cache_path + current_file, current_frame, next_frame - 1) + elif not next_item and previous_item: + previous_frame = previous_item[0] + job.addFile(cache_path + current_file, previous_frame + 1, current_frame) + else: + next_frame = next_item[0] + previous_frame = previous_item[0] + job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) + + print(job.files) + + job.name = job_name + + for slave in scene.network_render.slaves_blacklist: + job.blacklist.append(slave.id) + + job.chunks = netsettings.chunks + job.priority = netsettings.priority + + # try to send path first + conn.request("POST", "job", repr(job.serialize())) + response = conn.getresponse() + + job_id = response.getheader("job-id") + + # if not ACCEPTED (but not processed), send files + if response.status == http.client.ACCEPTED: + for filepath in job.files: + f = open(filepath, "rb") + conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath}) + f.close() + response = conn.getresponse() + + # server will reply with NOT_FOUD until all files are found + + return job_id + +def clientRequestResult(conn, scene, job_id): + conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) + class NetworkRenderEngine(bpy.types.RenderEngine): __idname__ = 'NET_RENDER' __label__ = "Network Render" diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 4afda9ac67b..d938c59a2ec 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -10,8 +10,10 @@ JOB_PAUSED = 1 # paused by user JOB_QUEUED = 2 # ready to be dispatched class MRenderFile: - def __init__(self, filepath): + def __init__(self, filepath, start, end): self.filepath = filepath + self.start = start + self.end = end self.found = False def test(self): @@ -55,7 +57,7 @@ class MRenderJob(netrender.model.RenderJob): # special server properties self.save_path = "" - self.files_map = {path: MRenderFile(path) for path in files} + self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} self.status = JOB_WAITING def save(self): diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 8b919b1fa36..7803ad034a7 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -62,6 +62,9 @@ class RenderJob: self.blacklist = [] self.last_dispatched = 0.0 + def addFile(self, file_path, start=-1, end=-1): + self.files.append((file_path, start, end)) + def addFrame(self, frame_number): frame = RenderFrame(frame_number) self.frames.append(frame) @@ -98,10 +101,12 @@ class RenderJob: return None def serialize(self, frames = None): + min_frame = min((f.number for f in frames)) if frames else -1 + max_frame = max((f.number for f in frames)) if frames else -1 return { "id": self.id, "name": self.name, - "files": self.files, + "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], "frames": [f.serialize() for f in self.frames if not frames or f in frames], "chunks": self.chunks, "priority": self.priority, diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 30631b3b23d..1c6d89c0043 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -3,6 +3,7 @@ import sys, os import http, http.client, http.server, urllib from netrender.utils import * +import netrender.client as client import netrender.model class RENDER_OT_netclientsend(bpy.types.Operator): @@ -27,7 +28,7 @@ class RENDER_OT_netclientsend(bpy.types.Operator): if conn: # Sending file - scene.network_render.job_id = clientSendJob(conn, scene, True) + scene.network_render.job_id = client.clientSendJob(conn, scene, True) return ('FINISHED',) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 8cbfd4ea11f..0435ba3f8cb 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -83,7 +83,7 @@ def render_slave(engine, scene): if not os.path.exists(JOB_PREFIX): os.mkdir(JOB_PREFIX) - job_path = job.files[0] + job_path = job.files[0][0] # data in files have format (path, start, end) main_path, main_file = os.path.split(job_path) job_full_path = testFile(conn, JOB_PREFIX, job_path) @@ -91,7 +91,8 @@ def render_slave(engine, scene): print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) engine.update_stats("", "Render File", main_file, "for job", job.id) - for file_path in job.files[1:]: + for file_path, start, end in job.files[1:]: + print("\t", file_path) testFile(conn, JOB_PREFIX, file_path, main_path) frame_args = [] diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index 62571011bc1..d1b383f7a97 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -6,7 +6,7 @@ import subprocess, shutil, time, hashlib import netrender.model -VERSION = b"0.3" +VERSION = b"0.5" QUEUED = 0 DISPATCHED = 1 @@ -41,79 +41,6 @@ def clientVerifyVersion(conn): return True -def clientSendJob(conn, scene, anim = False, chunks = 5): - netsettings = scene.network_render - job = netrender.model.RenderJob() - - if anim: - for f in range(scene.start_frame, scene.end_frame + 1): - job.addFrame(f) - else: - job.addFrame(scene.current_frame) - - filename = bpy.data.filename - job.files.append(filename) - - job_name = netsettings.job_name - path, name = os.path.split(filename) - if job_name == "[default]": - job_name = name - - for lib in bpy.data.libraries: - lib_path = lib.filename - - if lib_path.startswith("//"): - lib_path = path + os.sep + lib_path[2:] - - job.files.append(lib_path) - - root, ext = os.path.splitext(name) - cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - - print("cache:", cache_path) - - if os.path.exists(cache_path): - pattern = re.compile("[a-zA-Z0-9]+_([0-9]+)_[0-9]+\.bphys") - for cache_name in sorted(os.listdir(cache_path)): - match = pattern.match(cache_name) - - if match: - print("Frame:", int(match.groups()[0]), cache_name) - - job.files.append(cache_path + cache_name) - - #print(job.files) - - job.name = job_name - - for slave in scene.network_render.slaves_blacklist: - job.blacklist.append(slave.id) - - job.chunks = netsettings.chunks - job.priority = netsettings.priority - - # try to send path first - conn.request("POST", "job", repr(job.serialize())) - response = conn.getresponse() - - job_id = response.getheader("job-id") - - # if not ACCEPTED (but not processed), send files - if response.status == http.client.ACCEPTED: - for filepath in job.files: - f = open(filepath, "rb") - conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath}) - f.close() - response = conn.getresponse() - - # server will reply with NOT_FOUD until all files are found - - return job_id - -def clientRequestResult(conn, scene, job_id): - conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) - - def prefixPath(prefix_directory, file_path, prefix_path): if os.path.isabs(file_path): # if an absolute path, make sure path exists, if it doesn't, use relative local path -- cgit v1.2.3 From c29780c12a2eeb53e905c5a5c38a4a5c226738a3 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 9 Sep 2009 07:52:44 +0000 Subject: * Temporary fix to get fluid sim (and fluid control) working properly (without animated parameters). This just fills the fluid sim animation channels with default values for now, but will need to be updated to new animation system. --- source/blender/editors/physics/ed_fluidsim.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source/blender/editors/physics/ed_fluidsim.c b/source/blender/editors/physics/ed_fluidsim.c index 907d3f99f77..093fa3f0a49 100644 --- a/source/blender/editors/physics/ed_fluidsim.c +++ b/source/blender/editors/physics/ed_fluidsim.c @@ -200,6 +200,28 @@ static void fluidsimPrintChannel(FILE *file, float *channel, int paramsize, char static void fluidsimInitChannel(Scene *scene, float **setchannel, int size, float *time, int *icuIds, float *defaults, Ipo* ipo, int entries) { + + int i, j; + char *cstr = NULL; + float *channel = NULL; + + cstr = "fluidsiminit_channelfloat"; + if(entries>1) cstr = "fluidsiminit_channelvec"; + channel = MEM_callocN( size* (entries+1)* sizeof(float), cstr ); + + /* defaults for now */ + for(j=0; j Date: Wed, 9 Sep 2009 11:05:10 +0000 Subject: 2.5: use bone groups icon in UI. --- source/blender/makesrna/intern/rna_pose.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 6c2018c61f4..7d7f37a8f43 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -386,6 +386,7 @@ static void rna_def_bone_group(BlenderRNA *brna) srna= RNA_def_struct(brna, "BoneGroup", NULL); RNA_def_struct_sdna(srna, "bActionGroup"); RNA_def_struct_ui_text(srna, "Bone Group", "Groups of Pose Channels (Bones)."); + RNA_def_struct_ui_icon(srna, ICON_GROUP_BONE); /* name */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); -- cgit v1.2.3 From 8878c30b9b032f1a630c13c5ebb260cb9029ce3c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 11:10:28 +0000 Subject: 2.5: WM_menu_invoke now uses the first enum property it can find, if no enum property named "type" is available. --- source/blender/windowmanager/intern/wm_operators.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index c7011777dbf..ca2fbe23c3e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -448,13 +448,24 @@ void WM_operator_properties_free(PointerRNA *ptr) /* ************ default op callbacks, exported *********** */ /* invoke callback, uses enum property named "type" */ -/* only weak thing is the fixed property name... */ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) { - PropertyRNA *prop= RNA_struct_find_property(op->ptr, "type"); + PropertyRNA *prop; uiPopupMenu *pup; uiLayout *layout; + prop= RNA_struct_find_property(op->ptr, "type"); + + if(!prop) { + RNA_STRUCT_BEGIN(op->ptr, findprop) { + if(RNA_property_type(findprop) == PROP_ENUM) { + prop= findprop; + break; + } + } + RNA_STRUCT_END; + } + if(prop==NULL) { printf("WM_menu_invoke: %s has no \"type\" enum property\n", op->type->idname); } @@ -464,7 +475,7 @@ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) else { pup= uiPupMenuBegin(C, op->type->name, 0); layout= uiPupMenuLayout(pup); - uiItemsEnumO(layout, op->type->idname, "type"); + uiItemsEnumO(layout, op->type->idname, (char*)RNA_property_identifier(prop)); uiPupMenuEnd(C, pup); } -- cgit v1.2.3 From 3daa283604930167be0bc2dad5d1684a871ca254 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 11:52:56 +0000 Subject: 2.5: Object module * Split object_edit.c into multiple files: object_add.c, object_edit.c, object_hook.c, object_relations.c, object_select.c, object_transform.c. * Rename files to have consistent object_ and mball_ prefix: object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c. * Added operators: * vertex group menu and set active * apply location, rotation, scale, visual transform (location is new) * make local * make vertex parent * move to layer * convert to curve/mesh (not finished yet) * Many small fixes for marked issues, but still much code to be cleaned up here... --- projectfiles_vc9/blender/editors/ED_editors.vcproj | 14 +- release/ui/space_info.py | 16 +- source/blender/blenkernel/BKE_animsys.h | 3 + source/blender/blenkernel/intern/anim_sys.c | 26 + source/blender/blenkernel/intern/library.c | 5 +- source/blender/blenlib/intern/util.c | 5 - source/blender/editors/armature/editarmature.c | 46 +- .../editors/armature/editarmature_retarget.c | 4 +- source/blender/editors/armature/meshlaplacian.c | 24 +- source/blender/editors/armature/poseobject.c | 2 +- source/blender/editors/include/ED_armature.h | 4 +- source/blender/editors/include/ED_mball.h | 6 + source/blender/editors/include/ED_mesh.h | 22 +- source/blender/editors/include/ED_object.h | 7 +- source/blender/editors/metaball/editmball.c | 679 -- source/blender/editors/metaball/mball_edit.c | 679 ++ source/blender/editors/object/editconstraint.c | 1418 ---- source/blender/editors/object/editgroup.c | 257 - source/blender/editors/object/editkey.c | 539 -- source/blender/editors/object/editlattice.c | 388 - source/blender/editors/object/object_add.c | 1451 ++++ source/blender/editors/object/object_constraint.c | 1416 ++++ source/blender/editors/object/object_edit.c | 7584 +++----------------- source/blender/editors/object/object_group.c | 364 + source/blender/editors/object/object_hook.c | 608 ++ source/blender/editors/object/object_intern.h | 73 +- source/blender/editors/object/object_lattice.c | 382 + source/blender/editors/object/object_modifier.c | 52 - source/blender/editors/object/object_ops.c | 46 +- source/blender/editors/object/object_relations.c | 1766 +++++ source/blender/editors/object/object_select.c | 974 +++ source/blender/editors/object/object_shapekey.c | 539 ++ source/blender/editors/object/object_transform.c | 926 +++ source/blender/editors/object/object_vgroup.c | 1607 ++--- source/blender/editors/screen/screen_context.c | 6 + source/blender/editors/sculpt_paint/paint_vertex.c | 52 +- source/blender/editors/space_buttons/buttons_ops.c | 127 - source/blender/editors/space_view3d/drawobject.c | 2 +- .../blender/editors/space_view3d/view3d_buttons.c | 2 +- source/blender/editors/util/undo.c | 1 + source/blender/makesrna/RNA_enum_types.h | 2 + source/blender/makesrna/intern/rna_object.c | 16 + .../blender/windowmanager/intern/wm_event_system.c | 2 +- 43 files changed, 11268 insertions(+), 10874 deletions(-) delete mode 100644 source/blender/editors/metaball/editmball.c create mode 100644 source/blender/editors/metaball/mball_edit.c delete mode 100644 source/blender/editors/object/editconstraint.c delete mode 100644 source/blender/editors/object/editgroup.c delete mode 100644 source/blender/editors/object/editkey.c delete mode 100644 source/blender/editors/object/editlattice.c create mode 100644 source/blender/editors/object/object_add.c create mode 100644 source/blender/editors/object/object_constraint.c create mode 100644 source/blender/editors/object/object_group.c create mode 100644 source/blender/editors/object/object_hook.c create mode 100644 source/blender/editors/object/object_lattice.c create mode 100644 source/blender/editors/object/object_relations.c create mode 100644 source/blender/editors/object/object_select.c create mode 100644 source/blender/editors/object/object_shapekey.c create mode 100644 source/blender/editors/object/object_transform.c diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index 9f2fc769e49..db0b851fd74 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -1075,19 +1075,19 @@ Name="object" > + + first; strip; strip=strip->next) { + if(strip->act) make_local_action(strip->act); + if(strip->remap && strip->remap->target) make_local_action(strip->remap->target); + + make_local_strips(&strip->strips); + } +} + +void BKE_animdata_make_local(AnimData *adt) +{ + NlaTrack *nlt; + + if(adt->action) make_local_action(adt->action); + if(adt->tmpact) make_local_action(adt->tmpact); + if(adt->remap && adt->remap->target) make_local_action(adt->remap->target); + + for(nlt=adt->nla_tracks.first; nlt; nlt=nlt->next) + make_local_strips(&nlt->strips); +} + /* *********************************** */ /* KeyingSet API */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index f15552ab40c..02d92a62b59 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -194,7 +194,10 @@ int id_make_local(ID *id, int test) case ID_WV: return 0; /* deprecated */ case ID_LT: - if(!test) make_local_lattice((Lattice*)id); + if(!test) { + make_local_lattice((Lattice*)id); + make_local_key(((Lattice*)id)->key); + } return 1; case ID_LA: if(!test) make_local_lamp((Lamp*)id); diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index acf236d382b..c7bb7a54457 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -77,11 +77,6 @@ #include "BLI_winstuff.h" -/* for duplicate_defgroup */ -#if !(defined vsnprintf) -#define vsnprintf _vsnprintf -#endif - #endif diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 65051c384b3..4f5d8872384 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -239,7 +239,7 @@ static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist) } /* put EditMode back in Object */ -void ED_armature_from_edit(Scene *scene, Object *obedit) +void ED_armature_from_edit(Object *obedit) { bArmature *arm= obedit->data; EditBone *eBone, *neBone; @@ -343,21 +343,19 @@ void ED_armature_from_edit(Scene *scene, Object *obedit) DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); } - - -void apply_rot_armature (Scene *scene, Object *ob, float mat[3][3]) +void ED_armature_apply_transform(Object *ob, float mat[4][4]) { EditBone *ebone; bArmature *arm= ob->data; - float scale = Mat3ToScalef(mat); /* store the scale of the matrix here to use on envelopes */ + float scale = Mat4ToScalef(mat); /* store the scale of the matrix here to use on envelopes */ /* Put the armature into editmode */ ED_armature_to_edit(ob); /* Do the rotations */ for (ebone = arm->edbo->first; ebone; ebone=ebone->next){ - Mat3MulVecfl(mat, ebone->head); - Mat3MulVecfl(mat, ebone->tail); + Mat4MulVecfl(mat, ebone->head); + Mat4MulVecfl(mat, ebone->tail); ebone->rad_head *= scale; ebone->rad_tail *= scale; @@ -365,7 +363,7 @@ void apply_rot_armature (Scene *scene, Object *ob, float mat[3][3]) } /* Turn the list into an armature */ - ED_armature_from_edit(scene, ob); + ED_armature_from_edit(ob); ED_armature_edit_free(ob); } @@ -411,7 +409,7 @@ void docenter_armature (Scene *scene, View3D *v3d, Object *ob, int centermode) } /* Turn the list into an armature */ - ED_armature_from_edit(scene, ob); + ED_armature_from_edit(ob); /* Adjust object location for new centerpoint */ if(centermode && obedit==NULL) { @@ -557,7 +555,7 @@ static int apply_armature_pose2bones_exec (bContext *C, wmOperator *op) } /* convert editbones back to bones */ - ED_armature_from_edit(scene, ob); + ED_armature_from_edit(ob); /* flush positions of posebones */ where_is_pose(scene, ob); @@ -791,7 +789,7 @@ int join_armature_exec(bContext *C, wmOperator *op) DAG_scene_sort(scene); // because we removed object(s) - ED_armature_from_edit(scene, ob); + ED_armature_from_edit(ob); ED_armature_edit_free(ob); WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); @@ -994,7 +992,7 @@ static void separate_armature_bones (Scene *scene, Object *ob, short sel) } /* exit editmode (recalculates pchans too) */ - ED_armature_from_edit(scene, ob); + ED_armature_from_edit(ob); ED_armature_edit_free(ob); } @@ -1037,7 +1035,7 @@ static int separate_armature_exec (bContext *C, wmOperator *op) oldob->mode &= ~OB_MODE_POSE; //oldbase->flag &= ~OB_POSEMODE; - ED_armature_from_edit(scene, obedit); + ED_armature_from_edit(obedit); ED_armature_edit_free(obedit); /* 2) duplicate base */ @@ -4334,7 +4332,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor /* in weightpaint we select the associated vertex group too */ if (ob->mode & OB_MODE_WEIGHT_PAINT) { if (nearBone->flag & BONE_ACTIVE) { - vertexgroup_select_by_name(OBACT, nearBone->name); + ED_vgroup_select_by_name(OBACT, nearBone->name); DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); } } @@ -4445,7 +4443,7 @@ static int bone_skinnable(Object *ob, Bone *bone, void *datap) return 0; } -static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data) +static int ED_vgroup_add_unique_bone(Object *ob, Bone *bone, void *data) { /* This group creates a vertex group to ob that has the * same name as bone (provided the bone is skinnable). @@ -4453,7 +4451,7 @@ static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data) */ if (!(bone->flag & BONE_NO_DEFORM)) { if (!get_named_vertexgroup(ob,bone->name)) { - add_defgroup_name(ob, bone->name); + ED_vgroup_add_name(ob, bone->name); return 1; } } @@ -4497,7 +4495,7 @@ static int dgroup_skinnable(Object *ob, Bone *bone, void *datap) segments = 1; if (!(defgroup = get_named_vertexgroup(ob, bone->name))) - defgroup = add_defgroup_name(ob, bone->name); + defgroup = ED_vgroup_add_name(ob, bone->name); if (data->list != NULL) { hgroup = (bDeformGroup ***) &data->list; @@ -4548,17 +4546,17 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i /* add the vert to the deform group if weight!=0.0 */ if (distance!=0.0) - add_vert_to_defgroup (ob, dgroup, i, distance, WEIGHT_REPLACE); + ED_vgroup_vert_add (ob, dgroup, i, distance, WEIGHT_REPLACE); else - remove_vert_defgroup (ob, dgroup, i); + ED_vgroup_vert_remove (ob, dgroup, i); /* do same for mirror */ if (dgroupflip && dgroupflip[j] && iflip >= 0) { if (distance!=0.0) - add_vert_to_defgroup (ob, dgroupflip[j], iflip, distance, + ED_vgroup_vert_add (ob, dgroupflip[j], iflip, distance, WEIGHT_REPLACE); else - remove_vert_defgroup (ob, dgroupflip[j], iflip); + ED_vgroup_vert_remove (ob, dgroupflip[j], iflip); } } } @@ -4748,10 +4746,10 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par, int mod /* Traverse the bone list, trying to create empty vertex * groups cooresponding to the bone. */ - bone_looper(ob, arm->bonebase.first, NULL, add_defgroup_unique_bone); + bone_looper(ob, arm->bonebase.first, NULL, ED_vgroup_add_unique_bone); if (ob->type == OB_MESH) - create_dverts(ob->data); + ED_vgroup_data_create(ob->data); } else if(mode == ARM_GROUPS_ENVELOPE || mode == ARM_GROUPS_AUTO) { /* Traverse the bone list, trying to create vertex groups @@ -5659,7 +5657,7 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg) if (obedit != NULL) { - ED_armature_from_edit(scene, obedit); + ED_armature_from_edit(obedit); ED_armature_edit_free(obedit); } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 1d87ca8a6df..16e78f7c8d1 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -2732,7 +2732,7 @@ static void adjustGraphs(bContext *C, RigGraph *rigg) /* Turn the list into an armature */ arm->edbo = rigg->editbones; - ED_armature_from_edit(scene, rigg->ob); + ED_armature_from_edit(rigg->ob); ED_undo_push(C, "Retarget Skeleton"); } @@ -2762,7 +2762,7 @@ static void retargetGraphs(bContext *C, RigGraph *rigg) /* Turn the list into an armature */ arm->edbo = rigg->editbones; - ED_armature_from_edit(scene, rigg->ob); + ED_armature_from_edit(rigg->ob); } char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index) diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 1b167518a5a..a6c94bee5b1 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -672,9 +672,9 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, /* clear weights */ if(bbone && firstsegment) { for(a=0; atotvert; a++) { - remove_vert_defgroup(ob, dgrouplist[j], a); + ED_vgroup_vert_remove(ob, dgrouplist[j], a); if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) - remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); + ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]); } } @@ -694,32 +694,32 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, if(bbone) { if(solution > 0.0f) - add_vert_to_defgroup(ob, dgrouplist[j], a, solution, + ED_vgroup_vert_add(ob, dgrouplist[j], a, solution, WEIGHT_ADD); } else { weight= heat_limit_weight(solution); if(weight > 0.0f) - add_vert_to_defgroup(ob, dgrouplist[j], a, weight, + ED_vgroup_vert_add(ob, dgrouplist[j], a, weight, WEIGHT_REPLACE); else - remove_vert_defgroup(ob, dgrouplist[j], a); + ED_vgroup_vert_remove(ob, dgrouplist[j], a); } /* do same for mirror */ if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) { if(bbone) { if(solution > 0.0f) - add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a], + ED_vgroup_vert_add(ob, dgroupflip[j], vertsflipped[a], solution, WEIGHT_ADD); } else { weight= heat_limit_weight(solution); if(weight > 0.0f) - add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a], + ED_vgroup_vert_add(ob, dgroupflip[j], vertsflipped[a], weight, WEIGHT_REPLACE); else - remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); + ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]); } } } @@ -734,16 +734,16 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, /* remove too small vertex weights */ if(bbone && lastsegment) { for(a=0; atotvert; a++) { - weight= get_vert_defgroup(ob, dgrouplist[j], a); + weight= ED_vgroup_vert_weight(ob, dgrouplist[j], a); weight= heat_limit_weight(weight); if(weight <= 0.0f) - remove_vert_defgroup(ob, dgrouplist[j], a); + ED_vgroup_vert_remove(ob, dgrouplist[j], a); if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) { - weight= get_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); + weight= ED_vgroup_vert_weight(ob, dgroupflip[j], vertsflipped[a]); weight= heat_limit_weight(weight); if(weight <= 0.0f) - remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]); + ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]); } } } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index a4a518bc003..0ae92de4407 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1673,7 +1673,7 @@ void pose_activate_flipped_bone(Scene *scene) /* in weightpaint we select the associated vertex group too */ if(ob->mode & OB_MODE_WEIGHT_PAINT) { - vertexgroup_select_by_name(OBACT, name); + ED_vgroup_select_by_name(OBACT, name); DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); } diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 738cbf094cb..8bdfe41ef80 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -95,7 +95,7 @@ void ED_operatortypes_armature(void); void ED_keymap_armature(struct wmWindowManager *wm); /* editarmature.c */ -void ED_armature_from_edit(struct Scene *scene, struct Object *obedit); +void ED_armature_from_edit(struct Object *obedit); void ED_armature_to_edit(struct Object *ob); void ED_armature_edit_free(struct Object *ob); void ED_armature_edit_remake(struct Object *obedit); @@ -116,6 +116,8 @@ void transform_armature_mirror_update(struct Object *obedit); void clear_armature(struct Scene *scene, struct Object *ob, char mode); void docenter_armature (struct Scene *scene, struct View3D *v3d, struct Object *ob, int centermode); +void ED_armature_apply_transform(struct Object *ob, float mat[4][4]); + #define ARM_GROUPS_NAME 1 #define ARM_GROUPS_ENVELOPE 2 #define ARM_GROUPS_AUTO 3 diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index adb50867bf9..49c1d856a27 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -26,6 +26,10 @@ * ***** END GPL LICENSE BLOCK ***** */ +struct bContext; +struct Object; +struct wmWindowManager; + void ED_operatortypes_metaball(void); void ED_keymap_metaball(struct wmWindowManager *wm); @@ -37,3 +41,5 @@ void free_editMball(struct Object *obedit); void make_editMball(struct Object *obedit); void load_editMball(struct Object *obedit); +void undo_push_mball(struct bContext *C, char *name); + diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 0face00f82b..a2dba89ec20 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -157,25 +157,23 @@ void EM_deselect_by_material(struct EditMesh *em, int index); /* editface.c */ struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy); -/* editdeform.c XXX rename functions? */ +/* object_vgroup.c */ #define WEIGHT_REPLACE 1 #define WEIGHT_ADD 2 #define WEIGHT_SUBTRACT 3 -void add_defgroup (Object *ob); -void create_dverts(struct ID *id); -float get_vert_defgroup (Object *ob, struct bDeformGroup *dg, int vertnum); -void remove_vert_defgroup (Object *ob, struct bDeformGroup *dg, int vertnum); -void remove_verts_defgroup (Object *obedit, int allverts); -void vertexgroup_select_by_name(Object *ob, char *name); -void add_vert_to_defgroup (Object *ob, struct bDeformGroup *dg, int vertnum, - float weight, int assignmode); +struct bDeformGroup *ED_vgroup_add(struct Object *ob); +struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, char *name); +void ED_vgroup_select_by_name(struct Object *ob, char *name); +void ED_vgroup_data_create(struct ID *id); -struct bDeformGroup *add_defgroup_name (Object *ob, char *name); -struct MDeformWeight *verify_defweight (struct MDeformVert *dv, int defgroup); -struct MDeformWeight *get_defweight (struct MDeformVert *dv, int defgroup); +void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode); +void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum); +float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum); +struct MDeformWeight *ED_vgroup_weight_verify(struct MDeformVert *dv, int defgroup); +struct MDeformWeight *ED_vgroup_weight_get(struct MDeformVert *dv, int defgroup); #endif /* ED_MESH_H */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index d31f85d08ea..67dc6dada5f 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -89,14 +89,11 @@ void object_test_constraints(struct Object *ob); void ED_object_constraint_rename(struct Object *ob, struct bConstraint *con, char *oldname); void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con); -/* editlattice.c */ +/* object_lattice.c */ void mouse_lattice(struct bContext *C, short mval[2], int extend); void undo_push_lattice(struct bContext *C, char *name); -/* editmball.c */ -void undo_push_mball(struct bContext *C, char *name); - -/* editkey.c */ +/* object_shapekey.c */ void insert_shapekey(struct Scene *scene, struct Object *ob); void delete_key(struct Scene *scene, struct Object *ob); void key_to_mesh(struct KeyBlock *kb, struct Mesh *me); diff --git a/source/blender/editors/metaball/editmball.c b/source/blender/editors/metaball/editmball.c deleted file mode 100644 index 9ab985fb3fb..00000000000 --- a/source/blender/editors/metaball/editmball.c +++ /dev/null @@ -1,679 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_rand.h" - -#include "DNA_meta_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" -#include "DNA_windowmanager_types.h" -#include "DNA_userdef_types.h" - -#include "RNA_define.h" -#include "RNA_access.h" - -#include "BKE_utildefines.h" -#include "BKE_depsgraph.h" -#include "BKE_object.h" -#include "BKE_context.h" - -#include "ED_screen.h" -#include "ED_view3d.h" -#include "ED_transform.h" -#include "ED_util.h" - -#include "WM_api.h" -#include "WM_types.h" - -/* This function is used to free all MetaElems from MetaBall */ -void free_editMball(Object *obedit) -{ -} - -/* This function is called, when MetaBall Object is - * switched from object mode to edit mode */ -void make_editMball(Object *obedit) -{ - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml;/*, *newml;*/ - - ml= mb->elems.first; - - while(ml) { - if(ml->flag & SELECT) mb->lastelem = ml; - ml= ml->next; - } - - mb->editelems = &mb->elems; -} - -/* This function is called, when MetaBall Object switched from - * edit mode to object mode. List od MetaElements is copied - * from object->data->edit_elems to to object->data->elems. */ -void load_editMball(Object *obedit) -{ - MetaBall *mb = (MetaBall*)obedit->data; - - mb->editelems= NULL; - mb->lastelem= NULL; -} - -/* Add metaelem primitive to metaball object (which is in edit mode) */ -MetaElem *add_metaball_primitive(bContext *C, int type, int newname) -{ - Scene *scene= CTX_data_scene(C); - View3D *v3d= CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - Object *obedit= CTX_data_edit_object(C); - MetaBall *mball = (MetaBall*)obedit->data; - MetaElem *ml; - float *curs, mat[3][3], cent[3], imat[3][3], cmat[3][3]; - - if(!obedit) return NULL; - - /* Deselect all existing metaelems */ - ml= mball->editelems->first; - while(ml) { - ml->flag &= ~SELECT; - ml= ml->next; - } - - Mat3CpyMat4(mat, obedit->obmat); - if(v3d) { - curs= give_cursor(scene, v3d); - VECCOPY(cent, curs); - } - else - cent[0]= cent[1]= cent[2]= 0.0f; - - cent[0]-= obedit->obmat[3][0]; - cent[1]-= obedit->obmat[3][1]; - cent[2]-= obedit->obmat[3][2]; - - if (rv3d) { - if (!(newname) || U.flag & USER_ADD_VIEWALIGNED || !rv3d) - Mat3CpyMat4(imat, rv3d->viewmat); - else - Mat3One(imat); - Mat3MulVecfl(imat, cent); - Mat3MulMat3(cmat, imat, mat); - Mat3Inv(imat,cmat); - Mat3MulVecfl(imat, cent); - } - else - Mat3One(imat); - - ml= MEM_callocN(sizeof(MetaElem), "metaelem"); - - ml->x= cent[0]; - ml->y= cent[1]; - ml->z= cent[2]; - ml->quat[0]= 1.0; - ml->quat[1]= 0.0; - ml->quat[2]= 0.0; - ml->quat[3]= 0.0; - ml->rad= 2.0; - ml->s= 2.0; - ml->flag= SELECT | MB_SCALE_RAD; - - switch(type) { - case MB_BALL: - ml->type = MB_BALL; - ml->expx= ml->expy= ml->expz= 1.0; - break; - case MB_TUBE: - ml->type = MB_TUBE; - ml->expx= ml->expy= ml->expz= 1.0; - break; - case MB_PLANE: - ml->type = MB_PLANE; - ml->expx= ml->expy= ml->expz= 1.0; - break; - case MB_ELIPSOID: - ml->type = MB_ELIPSOID; - ml->expx= 1.2f; - ml->expy= 0.8f; - ml->expz= 1.0; - break; - case MB_CUBE: - ml->type = MB_CUBE; - ml->expx= ml->expy= ml->expz= 1.0; - break; - default: - break; - } - - mball->lastelem= ml; - - return ml; -} - -/***************************** Select/Deselect operator *****************************/ - -/* Select or deselect all MetaElements */ -static int select_deselect_all_metaelems_exec(bContext *C, wmOperator *op) -{ - //Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml; - int any_sel= 0; - - /* Is any metaelem selected? */ - ml= mb->editelems->first; - if(ml) { - while(ml) { - if(ml->flag & SELECT) break; - ml= ml->next; - } - if(ml) any_sel= 1; - - ml= mb->editelems->first; - while(ml) { - if(any_sel) ml->flag &= ~SELECT; - else ml->flag |= SELECT; - ml= ml->next; - } - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); - //DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - } - - return OPERATOR_FINISHED; -} - -void MBALL_OT_select_deselect_all_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select/Deselect All"; - ot->idname= "MBALL_OT_select_deselect_all_metaelems"; - - /* callback functions */ - ot->exec= select_deselect_all_metaelems_exec; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/***************************** Select inverse operator *****************************/ - -/* Invert metaball selection */ -static int select_inverse_metaelems_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml; - - ml= mb->editelems->first; - if(ml) { - while(ml) { - if(ml->flag & SELECT) - ml->flag &= ~SELECT; - else - ml->flag |= SELECT; - ml= ml->next; - } - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); - } - - return OPERATOR_FINISHED; -} - -void MBALL_OT_select_inverse_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Inverse"; - ot->idname= "MBALL_OT_select_inverse_metaelems"; - - /* callback functions */ - ot->exec= select_inverse_metaelems_exec; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/***************************** Select random operator *****************************/ - -/* Random metaball selection */ -static int select_random_metaelems_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml; - float percent= RNA_float_get(op->ptr, "percent"); - - if(percent == 0.0) - return OPERATOR_CANCELLED; - - ml= mb->editelems->first; - BLI_srand( BLI_rand() ); /* Random seed */ - - /* Stupid version of random selection. Should be improved. */ - while(ml) { - if(BLI_frand() < percent) - ml->flag |= SELECT; - else - ml->flag &= ~SELECT; - ml= ml->next; - } - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); - - return OPERATOR_FINISHED; -} - - -void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Random..."; - ot->idname= "MBALL_OT_select_random_metaelems"; - - /* callback functions */ - ot->exec= select_random_metaelems_exec; - ot->invoke= WM_operator_props_popup; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of metaelems to select randomly.", 0.0001f, 1.0f); -} - -/***************************** Duplicate operator *****************************/ - -/* Duplicate selected MetaElements */ -static int duplicate_metaelems_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml, *newml; - - ml= mb->editelems->last; - if(ml) { - while(ml) { - if(ml->flag & SELECT) { - newml= MEM_dupallocN(ml); - BLI_addtail(mb->editelems, newml); - mb->lastelem= newml; - ml->flag &= ~SELECT; - } - ml= ml->prev; - } - WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - } - - return OPERATOR_FINISHED; -} - -static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - int retv= duplicate_metaelems_exec(C, op); - - if (retv == OPERATOR_FINISHED) { - RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); - WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); - } - - return retv; -} - - -void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Duplicate"; - ot->idname= "MBALL_OT_duplicate_metaelems"; - - /* callback functions */ - ot->exec= duplicate_metaelems_exec; - ot->invoke= duplicate_metaelems_invoke; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* to give to transform */ - RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); -} - -/***************************** Delete operator *****************************/ - -/* Delete all selected MetaElems (not MetaBall) */ -static int delete_metaelems_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb= (MetaBall*)obedit->data; - MetaElem *ml, *next; - - ml= mb->editelems->first; - if(ml) { - while(ml) { - next= ml->next; - if(ml->flag & SELECT) { - if(mb->lastelem==ml) mb->lastelem= NULL; - BLI_remlink(mb->editelems, ml); - MEM_freeN(ml); - } - ml= next; - } - WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - } - - return OPERATOR_FINISHED; -} - -void MBALL_OT_delete_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Delete"; - ot->idname= "MBALL_OT_delete_metaelems"; - - /* callback functions */ - ot->exec= delete_metaelems_exec; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/***************************** Hide operator *****************************/ - -/* Hide selected MetaElems */ -static int hide_metaelems_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb= (MetaBall*)obedit->data; - MetaElem *ml; - int hide_unselected= RNA_boolean_get(op->ptr, "unselected"); - - ml= mb->editelems->first; - - if(ml) { - /* Hide unselected metaelems */ - if(hide_unselected) { - while(ml){ - if(!(ml->flag & SELECT)) - ml->flag |= MB_HIDE; - ml= ml->next; - } - /* Hide selected metaelems */ - } else { - while(ml){ - if(ml->flag & SELECT) - ml->flag |= MB_HIDE; - ml= ml->next; - } - } - WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - } - - return OPERATOR_FINISHED; -} - -void MBALL_OT_hide_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Hide"; - ot->idname= "MBALL_OT_hide_metaelems"; - - /* callback functions */ - ot->exec= hide_metaelems_exec; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* props */ - RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected."); -} - -/***************************** Unhide operator *****************************/ - -/* Unhide all edited MetaElems */ -static int reveal_metaelems_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mb= (MetaBall*)obedit->data; - MetaElem *ml; - - ml= mb->editelems->first; - - if(ml) { - while(ml) { - ml->flag &= ~MB_HIDE; - ml= ml->next; - } - WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - } - - return OPERATOR_FINISHED; -} - -void MBALL_OT_reveal_metaelems(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Reveal"; - ot->idname= "MBALL_OT_reveal_metaelems"; - - /* callback functions */ - ot->exec= reveal_metaelems_exec; - ot->poll= ED_operator_editmball; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* Select MetaElement with mouse click (user can select radius circle or - * stiffness circle) */ -void mouse_mball(bContext *C, short mval[2], int extend) -{ - static MetaElem *startelem=NULL; - Object *obedit= CTX_data_edit_object(C); - ViewContext vc; - MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml, *act=NULL; - int a, hits; - unsigned int buffer[4*MAXPICKBUF]; - rcti rect; - - view3d_set_viewcontext(C, &vc); - - rect.xmin= mval[0]-12; - rect.xmax= mval[0]+12; - rect.ymin= mval[1]-12; - rect.ymax= mval[1]+12; - - hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect); - - /* does startelem exist? */ - ml= mb->editelems->first; - while(ml) { - if(ml==startelem) break; - ml= ml->next; - } - - if(ml==NULL) startelem= mb->editelems->first; - - if(hits>0) { - ml= startelem; - while(ml) { - for(a=0; aselcol1==buffer[ 4 * a + 3 ]){ - ml->flag |= MB_SCALE_RAD; - act= ml; - } - if(ml->selcol2==buffer[ 4 * a + 3 ]){ - ml->flag &= ~MB_SCALE_RAD; - act= ml; - } - } - if(act) break; - ml= ml->next; - if(ml==NULL) ml= mb->editelems->first; - if(ml==startelem) break; - } - - /* When some metaelem was found, then it is neccessary to select or - * deselet it. */ - if(act) { - if(extend==0) { - /* Deselect all existing metaelems */ - ml= mb->editelems->first; - while(ml) { - ml->flag &= ~SELECT; - ml= ml->next; - } - /* Select only metaelem clicked on */ - act->flag |= SELECT; - } - else { - if(act->flag & SELECT) - act->flag &= ~SELECT; - else - act->flag |= SELECT; - } - mb->lastelem= act; - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); - } - } -} - - -/* ************* undo for MetaBalls ************* */ - -/* free all MetaElems from ListBase */ -static void freeMetaElemlist(ListBase *lb) -{ - MetaElem *ml, *next; - - if(lb==NULL) return; - - ml= lb->first; - while(ml){ - next= ml->next; - BLI_remlink(lb, ml); - MEM_freeN(ml); - ml= next; - } - - lb->first= lb->last= NULL; -} - - -static void undoMball_to_editMball(void *lbu, void *lbe) -{ - ListBase *lb= lbu; - ListBase *editelems= lbe; - MetaElem *ml, *newml; - - freeMetaElemlist(editelems); - - /* copy 'undo' MetaElems to 'edit' MetaElems */ - ml= lb->first; - while(ml){ - newml= MEM_dupallocN(ml); - BLI_addtail(editelems, newml); - ml= ml->next; - } - -} - -static void *editMball_to_undoMball(void *lbe) -{ - ListBase *editelems= lbe; - ListBase *lb; - MetaElem *ml, *newml; - - /* allocate memory for undo ListBase */ - lb= MEM_callocN(sizeof(ListBase), "listbase undo"); - lb->first= lb->last= NULL; - - /* copy contents of current ListBase to the undo ListBase */ - ml= editelems->first; - while(ml){ - newml= MEM_dupallocN(ml); - BLI_addtail(lb, newml); - ml= ml->next; - } - - return lb; -} - -/* free undo ListBase of MetaElems */ -static void free_undoMball(void *lbv) -{ - ListBase *lb= lbv; - - freeMetaElemlist(lb); - MEM_freeN(lb); -} - -ListBase *metaball_get_editelems(Object *ob) -{ - if(ob && ob->type==OB_MBALL) { - struct MetaBall *mb= (struct MetaBall*)ob->data; - return mb->editelems; - } - return NULL; -} - - -static void *get_data(bContext *C) -{ - Object *obedit= CTX_data_edit_object(C); - return metaball_get_editelems(obedit); -} - -/* this is undo system for MetaBalls */ -void undo_push_mball(bContext *C, char *name) -{ - undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); -} - diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c new file mode 100644 index 00000000000..9ab985fb3fb --- /dev/null +++ b/source/blender/editors/metaball/mball_edit.c @@ -0,0 +1,679 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" +#include "DNA_windowmanager_types.h" +#include "DNA_userdef_types.h" + +#include "RNA_define.h" +#include "RNA_access.h" + +#include "BKE_utildefines.h" +#include "BKE_depsgraph.h" +#include "BKE_object.h" +#include "BKE_context.h" + +#include "ED_screen.h" +#include "ED_view3d.h" +#include "ED_transform.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* This function is used to free all MetaElems from MetaBall */ +void free_editMball(Object *obedit) +{ +} + +/* This function is called, when MetaBall Object is + * switched from object mode to edit mode */ +void make_editMball(Object *obedit) +{ + MetaBall *mb = (MetaBall*)obedit->data; + MetaElem *ml;/*, *newml;*/ + + ml= mb->elems.first; + + while(ml) { + if(ml->flag & SELECT) mb->lastelem = ml; + ml= ml->next; + } + + mb->editelems = &mb->elems; +} + +/* This function is called, when MetaBall Object switched from + * edit mode to object mode. List od MetaElements is copied + * from object->data->edit_elems to to object->data->elems. */ +void load_editMball(Object *obedit) +{ + MetaBall *mb = (MetaBall*)obedit->data; + + mb->editelems= NULL; + mb->lastelem= NULL; +} + +/* Add metaelem primitive to metaball object (which is in edit mode) */ +MetaElem *add_metaball_primitive(bContext *C, int type, int newname) +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + Object *obedit= CTX_data_edit_object(C); + MetaBall *mball = (MetaBall*)obedit->data; + MetaElem *ml; + float *curs, mat[3][3], cent[3], imat[3][3], cmat[3][3]; + + if(!obedit) return NULL; + + /* Deselect all existing metaelems */ + ml= mball->editelems->first; + while(ml) { + ml->flag &= ~SELECT; + ml= ml->next; + } + + Mat3CpyMat4(mat, obedit->obmat); + if(v3d) { + curs= give_cursor(scene, v3d); + VECCOPY(cent, curs); + } + else + cent[0]= cent[1]= cent[2]= 0.0f; + + cent[0]-= obedit->obmat[3][0]; + cent[1]-= obedit->obmat[3][1]; + cent[2]-= obedit->obmat[3][2]; + + if (rv3d) { + if (!(newname) || U.flag & USER_ADD_VIEWALIGNED || !rv3d) + Mat3CpyMat4(imat, rv3d->viewmat); + else + Mat3One(imat); + Mat3MulVecfl(imat, cent); + Mat3MulMat3(cmat, imat, mat); + Mat3Inv(imat,cmat); + Mat3MulVecfl(imat, cent); + } + else + Mat3One(imat); + + ml= MEM_callocN(sizeof(MetaElem), "metaelem"); + + ml->x= cent[0]; + ml->y= cent[1]; + ml->z= cent[2]; + ml->quat[0]= 1.0; + ml->quat[1]= 0.0; + ml->quat[2]= 0.0; + ml->quat[3]= 0.0; + ml->rad= 2.0; + ml->s= 2.0; + ml->flag= SELECT | MB_SCALE_RAD; + + switch(type) { + case MB_BALL: + ml->type = MB_BALL; + ml->expx= ml->expy= ml->expz= 1.0; + break; + case MB_TUBE: + ml->type = MB_TUBE; + ml->expx= ml->expy= ml->expz= 1.0; + break; + case MB_PLANE: + ml->type = MB_PLANE; + ml->expx= ml->expy= ml->expz= 1.0; + break; + case MB_ELIPSOID: + ml->type = MB_ELIPSOID; + ml->expx= 1.2f; + ml->expy= 0.8f; + ml->expz= 1.0; + break; + case MB_CUBE: + ml->type = MB_CUBE; + ml->expx= ml->expy= ml->expz= 1.0; + break; + default: + break; + } + + mball->lastelem= ml; + + return ml; +} + +/***************************** Select/Deselect operator *****************************/ + +/* Select or deselect all MetaElements */ +static int select_deselect_all_metaelems_exec(bContext *C, wmOperator *op) +{ + //Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb = (MetaBall*)obedit->data; + MetaElem *ml; + int any_sel= 0; + + /* Is any metaelem selected? */ + ml= mb->editelems->first; + if(ml) { + while(ml) { + if(ml->flag & SELECT) break; + ml= ml->next; + } + if(ml) any_sel= 1; + + ml= mb->editelems->first; + while(ml) { + if(any_sel) ml->flag &= ~SELECT; + else ml->flag |= SELECT; + ml= ml->next; + } + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); + //DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + + return OPERATOR_FINISHED; +} + +void MBALL_OT_select_deselect_all_metaelems(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select/Deselect All"; + ot->idname= "MBALL_OT_select_deselect_all_metaelems"; + + /* callback functions */ + ot->exec= select_deselect_all_metaelems_exec; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/***************************** Select inverse operator *****************************/ + +/* Invert metaball selection */ +static int select_inverse_metaelems_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb = (MetaBall*)obedit->data; + MetaElem *ml; + + ml= mb->editelems->first; + if(ml) { + while(ml) { + if(ml->flag & SELECT) + ml->flag &= ~SELECT; + else + ml->flag |= SELECT; + ml= ml->next; + } + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); + } + + return OPERATOR_FINISHED; +} + +void MBALL_OT_select_inverse_metaelems(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Inverse"; + ot->idname= "MBALL_OT_select_inverse_metaelems"; + + /* callback functions */ + ot->exec= select_inverse_metaelems_exec; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/***************************** Select random operator *****************************/ + +/* Random metaball selection */ +static int select_random_metaelems_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb = (MetaBall*)obedit->data; + MetaElem *ml; + float percent= RNA_float_get(op->ptr, "percent"); + + if(percent == 0.0) + return OPERATOR_CANCELLED; + + ml= mb->editelems->first; + BLI_srand( BLI_rand() ); /* Random seed */ + + /* Stupid version of random selection. Should be improved. */ + while(ml) { + if(BLI_frand() < percent) + ml->flag |= SELECT; + else + ml->flag &= ~SELECT; + ml= ml->next; + } + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); + + return OPERATOR_FINISHED; +} + + +void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Random..."; + ot->idname= "MBALL_OT_select_random_metaelems"; + + /* callback functions */ + ot->exec= select_random_metaelems_exec; + ot->invoke= WM_operator_props_popup; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of metaelems to select randomly.", 0.0001f, 1.0f); +} + +/***************************** Duplicate operator *****************************/ + +/* Duplicate selected MetaElements */ +static int duplicate_metaelems_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb = (MetaBall*)obedit->data; + MetaElem *ml, *newml; + + ml= mb->editelems->last; + if(ml) { + while(ml) { + if(ml->flag & SELECT) { + newml= MEM_dupallocN(ml); + BLI_addtail(mb->editelems, newml); + mb->lastelem= newml; + ml->flag &= ~SELECT; + } + ml= ml->prev; + } + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + + return OPERATOR_FINISHED; +} + +static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + int retv= duplicate_metaelems_exec(C, op); + + if (retv == OPERATOR_FINISHED) { + RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); + WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); + } + + return retv; +} + + +void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Duplicate"; + ot->idname= "MBALL_OT_duplicate_metaelems"; + + /* callback functions */ + ot->exec= duplicate_metaelems_exec; + ot->invoke= duplicate_metaelems_invoke; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* to give to transform */ + RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); +} + +/***************************** Delete operator *****************************/ + +/* Delete all selected MetaElems (not MetaBall) */ +static int delete_metaelems_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb= (MetaBall*)obedit->data; + MetaElem *ml, *next; + + ml= mb->editelems->first; + if(ml) { + while(ml) { + next= ml->next; + if(ml->flag & SELECT) { + if(mb->lastelem==ml) mb->lastelem= NULL; + BLI_remlink(mb->editelems, ml); + MEM_freeN(ml); + } + ml= next; + } + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + + return OPERATOR_FINISHED; +} + +void MBALL_OT_delete_metaelems(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete"; + ot->idname= "MBALL_OT_delete_metaelems"; + + /* callback functions */ + ot->exec= delete_metaelems_exec; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/***************************** Hide operator *****************************/ + +/* Hide selected MetaElems */ +static int hide_metaelems_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb= (MetaBall*)obedit->data; + MetaElem *ml; + int hide_unselected= RNA_boolean_get(op->ptr, "unselected"); + + ml= mb->editelems->first; + + if(ml) { + /* Hide unselected metaelems */ + if(hide_unselected) { + while(ml){ + if(!(ml->flag & SELECT)) + ml->flag |= MB_HIDE; + ml= ml->next; + } + /* Hide selected metaelems */ + } else { + while(ml){ + if(ml->flag & SELECT) + ml->flag |= MB_HIDE; + ml= ml->next; + } + } + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + + return OPERATOR_FINISHED; +} + +void MBALL_OT_hide_metaelems(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Hide"; + ot->idname= "MBALL_OT_hide_metaelems"; + + /* callback functions */ + ot->exec= hide_metaelems_exec; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected."); +} + +/***************************** Unhide operator *****************************/ + +/* Unhide all edited MetaElems */ +static int reveal_metaelems_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mb= (MetaBall*)obedit->data; + MetaElem *ml; + + ml= mb->editelems->first; + + if(ml) { + while(ml) { + ml->flag &= ~MB_HIDE; + ml= ml->next; + } + WM_event_add_notifier(C, NC_GEOM|ND_DATA, mb); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + + return OPERATOR_FINISHED; +} + +void MBALL_OT_reveal_metaelems(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reveal"; + ot->idname= "MBALL_OT_reveal_metaelems"; + + /* callback functions */ + ot->exec= reveal_metaelems_exec; + ot->poll= ED_operator_editmball; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* Select MetaElement with mouse click (user can select radius circle or + * stiffness circle) */ +void mouse_mball(bContext *C, short mval[2], int extend) +{ + static MetaElem *startelem=NULL; + Object *obedit= CTX_data_edit_object(C); + ViewContext vc; + MetaBall *mb = (MetaBall*)obedit->data; + MetaElem *ml, *act=NULL; + int a, hits; + unsigned int buffer[4*MAXPICKBUF]; + rcti rect; + + view3d_set_viewcontext(C, &vc); + + rect.xmin= mval[0]-12; + rect.xmax= mval[0]+12; + rect.ymin= mval[1]-12; + rect.ymax= mval[1]+12; + + hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect); + + /* does startelem exist? */ + ml= mb->editelems->first; + while(ml) { + if(ml==startelem) break; + ml= ml->next; + } + + if(ml==NULL) startelem= mb->editelems->first; + + if(hits>0) { + ml= startelem; + while(ml) { + for(a=0; aselcol1==buffer[ 4 * a + 3 ]){ + ml->flag |= MB_SCALE_RAD; + act= ml; + } + if(ml->selcol2==buffer[ 4 * a + 3 ]){ + ml->flag &= ~MB_SCALE_RAD; + act= ml; + } + } + if(act) break; + ml= ml->next; + if(ml==NULL) ml= mb->editelems->first; + if(ml==startelem) break; + } + + /* When some metaelem was found, then it is neccessary to select or + * deselet it. */ + if(act) { + if(extend==0) { + /* Deselect all existing metaelems */ + ml= mb->editelems->first; + while(ml) { + ml->flag &= ~SELECT; + ml= ml->next; + } + /* Select only metaelem clicked on */ + act->flag |= SELECT; + } + else { + if(act->flag & SELECT) + act->flag &= ~SELECT; + else + act->flag |= SELECT; + } + mb->lastelem= act; + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, mb); + } + } +} + + +/* ************* undo for MetaBalls ************* */ + +/* free all MetaElems from ListBase */ +static void freeMetaElemlist(ListBase *lb) +{ + MetaElem *ml, *next; + + if(lb==NULL) return; + + ml= lb->first; + while(ml){ + next= ml->next; + BLI_remlink(lb, ml); + MEM_freeN(ml); + ml= next; + } + + lb->first= lb->last= NULL; +} + + +static void undoMball_to_editMball(void *lbu, void *lbe) +{ + ListBase *lb= lbu; + ListBase *editelems= lbe; + MetaElem *ml, *newml; + + freeMetaElemlist(editelems); + + /* copy 'undo' MetaElems to 'edit' MetaElems */ + ml= lb->first; + while(ml){ + newml= MEM_dupallocN(ml); + BLI_addtail(editelems, newml); + ml= ml->next; + } + +} + +static void *editMball_to_undoMball(void *lbe) +{ + ListBase *editelems= lbe; + ListBase *lb; + MetaElem *ml, *newml; + + /* allocate memory for undo ListBase */ + lb= MEM_callocN(sizeof(ListBase), "listbase undo"); + lb->first= lb->last= NULL; + + /* copy contents of current ListBase to the undo ListBase */ + ml= editelems->first; + while(ml){ + newml= MEM_dupallocN(ml); + BLI_addtail(lb, newml); + ml= ml->next; + } + + return lb; +} + +/* free undo ListBase of MetaElems */ +static void free_undoMball(void *lbv) +{ + ListBase *lb= lbv; + + freeMetaElemlist(lb); + MEM_freeN(lb); +} + +ListBase *metaball_get_editelems(Object *ob) +{ + if(ob && ob->type==OB_MBALL) { + struct MetaBall *mb= (struct MetaBall*)ob->data; + return mb->editelems; + } + return NULL; +} + + +static void *get_data(bContext *C) +{ + Object *obedit= CTX_data_edit_object(C); + return metaball_get_editelems(obedit); +} + +/* this is undo system for MetaBalls */ +void undo_push_mball(bContext *C, char *name) +{ + undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); +} + diff --git a/source/blender/editors/object/editconstraint.c b/source/blender/editors/object/editconstraint.c deleted file mode 100644 index c1b1062bfc4..00000000000 --- a/source/blender/editors/object/editconstraint.c +++ /dev/null @@ -1,1418 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joshua Leung, Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_dynstr.h" - -#include "DNA_action_types.h" -#include "DNA_armature_types.h" -#include "DNA_constraint_types.h" -#include "DNA_curve_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_text_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_action.h" -#include "BKE_armature.h" -#include "BKE_constraint.h" -#include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_object.h" -#include "BKE_report.h" -#include "BKE_utildefines.h" - -#ifndef DISABLE_PYTHON -#include "BPY_extern.h" -#endif - -#include "WM_api.h" -#include "WM_types.h" - -#include "RNA_access.h" -#include "RNA_define.h" -#include "RNA_enum_types.h" -#include "RNA_types.h" - -#include "ED_object.h" -#include "ED_screen.h" - -#include "UI_interface.h" - -#include "object_intern.h" - -/* XXX */ -static int pupmenu() {return 0;} - -/* -------------- Get Active Constraint Data ---------------------- */ - -/* if object in posemode, active bone constraints, else object constraints */ -ListBase *get_active_constraints (Object *ob) -{ - if (ob == NULL) - return NULL; - - if (ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan; - - pchan = get_active_posechannel(ob); - if (pchan) - return &pchan->constraints; - } - else - return &ob->constraints; - - return NULL; -} - -/* single constraint */ -bConstraint *get_active_constraint (Object *ob) -{ - ListBase *lb= get_active_constraints(ob); - - if (lb) { - bConstraint *con; - - for (con= lb->first; con; con=con->next) { - if (con->flag & CONSTRAINT_ACTIVE) - return con; - } - } - - return NULL; -} -/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */ -/* ------------- PyConstraints ------------------ */ - -/* this callback sets the text-file to be used for selected menu item */ -void validate_pyconstraint_cb (void *arg1, void *arg2) -{ - bPythonConstraint *data = arg1; - Text *text= NULL; - int index = *((int *)arg2); - int i; - - /* exception for no script */ - if (index) { - /* innovative use of a for...loop to search */ - for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next); - } - data->text = text; -} - -#ifndef DISABLE_PYTHON -/* this returns a string for the list of usable pyconstraint script names */ -char *buildmenu_pyconstraints (Text *con_text, int *pyconindex) -{ - DynStr *pupds= BLI_dynstr_new(); - Text *text; - char *str; - char buf[64]; - int i; - - /* add title first */ - sprintf(buf, "Scripts: %%t|[None]%%x0|"); - BLI_dynstr_append(pupds, buf); - - /* init active-index first */ - if (con_text == NULL) - *pyconindex= 0; - - /* loop through markers, adding them */ - for (text=G.main->text.first, i=1; text; i++, text=text->id.next) { - /* this is important to ensure that right script is shown as active */ - if (text == con_text) *pyconindex = i; - - /* only include valid pyconstraint scripts */ - if (BPY_is_pyconstraint(text)) { - BLI_dynstr_append(pupds, text->id.name+2); - - sprintf(buf, "%%x%d", i); - BLI_dynstr_append(pupds, buf); - - if (text->id.next) - BLI_dynstr_append(pupds, "|"); - } - } - - /* convert to normal MEM_malloc'd string */ - str= BLI_dynstr_get_cstring(pupds); - BLI_dynstr_free(pupds); - - return str; -} -#endif /* DISABLE_PYTHON */ - -/* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */ -void update_pyconstraint_cb (void *arg1, void *arg2) -{ - Object *owner= (Object *)arg1; - bConstraint *con= (bConstraint *)arg2; -#ifndef DISABLE_PYTHON - if (owner && con) - BPY_pyconstraint_update(owner, con); -#endif -} - -/* Creates a new constraint, initialises its data, and returns it */ -bConstraint *add_new_constraint (short type) -{ - bConstraint *con; - bConstraintTypeInfo *cti; - - con = MEM_callocN(sizeof(bConstraint), "Constraint"); - - /* Set up a generic constraint datablock */ - con->type = type; - con->flag |= CONSTRAINT_EXPAND; - con->enforce = 1.0f; - - /* Load the data for it */ - cti = constraint_get_typeinfo(con); - if (cti) { - con->data = MEM_callocN(cti->size, cti->structName); - - /* only constraints that change any settings need this */ - if (cti->new_data) - cti->new_data(con->data); - - /* set the name based on the type of constraint */ - strcpy(con->name, cti->name); - } - else - strcpy(con->name, "Const"); - - return con; -} - -/* Adds the given constraint to the Object-level set of constraints for the given Object */ -void add_constraint_to_object (bConstraint *con, Object *ob) -{ - ListBase *list; - list = &ob->constraints; - - if (list) { - unique_constraint_name(con, list); - BLI_addtail(list, con); - - if (proxylocked_constraints_owner(ob, NULL)) - con->flag |= CONSTRAINT_PROXY_LOCAL; - - con->flag |= CONSTRAINT_ACTIVE; - for (con= con->prev; con; con= con->prev) - con->flag &= ~CONSTRAINT_ACTIVE; - } -} - -/* helper function for add_constriant - sets the last target for the active constraint */ -static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index) -{ - bConstraintTypeInfo *cti= constraint_get_typeinfo(con); - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - int num_targets, i; - - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - num_targets= BLI_countlist(&targets); - - if (index < 0) { - if (abs(index) < num_targets) - index= num_targets - abs(index); - else - index= num_targets - 1; - } - else if (index >= num_targets) { - index= num_targets - 1; - } - - for (ct=targets.first, i=0; ct; ct= ct->next, i++) { - if (i == index) { - ct->tar= target; - strcpy(ct->subtarget, subtarget); - break; - } - } - - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(con, &targets, 0); - } -} - -/* ------------- Constraint Sanity Testing ------------------- */ - -/* checks validity of object pointers, and NULLs, - * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag - */ -static void test_constraints (Object *owner, const char substring[]) -{ - bConstraint *curcon; - ListBase *conlist= NULL; - int type; - - if (owner==NULL) return; - - /* Check parents */ - if (strlen(substring)) { - switch (owner->type) { - case OB_ARMATURE: - type = CONSTRAINT_OBTYPE_BONE; - break; - default: - type = CONSTRAINT_OBTYPE_OBJECT; - break; - } - } - else - type = CONSTRAINT_OBTYPE_OBJECT; - - /* Get the constraint list for this object */ - switch (type) { - case CONSTRAINT_OBTYPE_OBJECT: - conlist = &owner->constraints; - break; - case CONSTRAINT_OBTYPE_BONE: - { - Bone *bone; - bPoseChannel *chan; - - bone = get_named_bone( ((bArmature *)owner->data), substring ); - chan = get_pose_channel(owner->pose, substring); - if (bone && chan) { - conlist = &chan->constraints; - } - } - break; - } - - /* Check all constraints - is constraint valid? */ - if (conlist) { - for (curcon = conlist->first; curcon; curcon=curcon->next) { - bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon); - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - - /* clear disabled-flag first */ - curcon->flag &= ~CONSTRAINT_DISABLE; - - if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) { - bKinematicConstraint *data = curcon->data; - - /* bad: we need a separate set of checks here as poletarget is - * optional... otherwise poletarget must exist too or else - * the constraint is deemed invalid - */ - if (exist_object(data->tar) == 0) { - data->tar = NULL; - curcon->flag |= CONSTRAINT_DISABLE; - } - else if (data->tar == owner) { - if (!get_named_bone(get_armature(owner), data->subtarget)) { - curcon->flag |= CONSTRAINT_DISABLE; - } - } - - if (data->poletar) { - if (exist_object(data->poletar) == 0) { - data->poletar = NULL; - curcon->flag |= CONSTRAINT_DISABLE; - } - else if (data->poletar == owner) { - if (!get_named_bone(get_armature(owner), data->polesubtarget)) { - curcon->flag |= CONSTRAINT_DISABLE; - } - } - } - - /* targets have already been checked for this */ - continue; - } - else if (curcon->type == CONSTRAINT_TYPE_ACTION) { - bActionConstraint *data = curcon->data; - - /* validate action */ - if (data->act == NULL) - curcon->flag |= CONSTRAINT_DISABLE; - } - else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) { - bFollowPathConstraint *data = curcon->data; - - /* don't allow track/up axes to be the same */ - if (data->upflag==data->trackflag) - curcon->flag |= CONSTRAINT_DISABLE; - if (data->upflag+3==data->trackflag) - curcon->flag |= CONSTRAINT_DISABLE; - } - else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) { - bTrackToConstraint *data = curcon->data; - - /* don't allow track/up axes to be the same */ - if (data->reserved2==data->reserved1) - curcon->flag |= CONSTRAINT_DISABLE; - if (data->reserved2+3==data->reserved1) - curcon->flag |= CONSTRAINT_DISABLE; - } - else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) { - bLockTrackConstraint *data = curcon->data; - - if (data->lockflag==data->trackflag) - curcon->flag |= CONSTRAINT_DISABLE; - if (data->lockflag+3==data->trackflag) - curcon->flag |= CONSTRAINT_DISABLE; - } - - /* Check targets for constraints */ - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(curcon, &targets); - - /* disable and clear constraints targets that are incorrect */ - for (ct= targets.first; ct; ct= ct->next) { - /* general validity checks (for those constraints that need this) */ - if (exist_object(ct->tar) == 0) { - ct->tar = NULL; - curcon->flag |= CONSTRAINT_DISABLE; - } - else if (ct->tar == owner) { - if (!get_named_bone(get_armature(owner), ct->subtarget)) { - curcon->flag |= CONSTRAINT_DISABLE; - } - } - - /* target checks for specific constraints */ - if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) { - if (ct->tar) { - if (ct->tar->type != OB_CURVE) { - ct->tar= NULL; - curcon->flag |= CONSTRAINT_DISABLE; - } - else { - Curve *cu= ct->tar->data; - - /* auto-set 'Path' setting on curve so this works */ - cu->flag |= CU_PATH; - } - } - } - } - - /* free any temporary targets */ - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(curcon, &targets, 0); - } - } - } -} - -static void test_bonelist_constraints (Object *owner, ListBase *list) -{ - Bone *bone; - - for (bone = list->first; bone; bone = bone->next) { - test_constraints(owner, bone->name); - test_bonelist_constraints(owner, &bone->childbase); - } -} - -void object_test_constraints (Object *owner) -{ - test_constraints(owner, ""); - - if (owner->type==OB_ARMATURE) { - bArmature *arm= get_armature(owner); - - if (arm) - test_bonelist_constraints(owner, &arm->bonebase); - } -} - -/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */ - -/* ---------- Distance-Dependent Constraints ---------- */ -/* StretchTo, Limit Distance */ - -static int stretchto_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); - return (ptr.id.data && ptr.data); -} - -static int stretchto_reset_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); - - /* just set original length to 0.0, which will cause a reset on next recalc */ - RNA_float_set(&ptr, "original_length", 0.0f); - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); - return OPERATOR_FINISHED; -} - -void CONSTRAINT_OT_stretchto_reset (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Reset Original Length"; - ot->idname= "CONSTRAINT_OT_stretchto_reset"; - ot->description= "Reset original length of bone for Stretch To Constraint."; - - ot->exec= stretchto_reset_exec; - ot->poll= stretchto_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - - -static int limitdistance_reset_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); - - /* just set distance to 0.0, which will cause a reset on next recalc */ - RNA_float_set(&ptr, "distance", 0.0f); - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); - return OPERATOR_FINISHED; -} - -static int limitdistance_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); - return (ptr.id.data && ptr.data); -} - -void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Reset Distance"; - ot->idname= "CONSTRAINT_OT_limitdistance_reset"; - ot->description= "Reset limiting distance for Limit Distance Constraint."; - - ot->exec= limitdistance_reset_exec; - ot->poll= limitdistance_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* ------------- Child-Of Constraint ------------------ */ - -static int childof_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); - return (ptr.id.data && ptr.data); -} - -/* ChildOf Constraint - set inverse callback */ -static int childof_set_inverse_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); - Scene *scene= CTX_data_scene(C); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - bChildOfConstraint *data= (bChildOfConstraint *)con->data; - bPoseChannel *pchan= NULL; - - /* try to find a pose channel */ - // TODO: get from context instead? - if (ob && ob->pose) - pchan= get_active_posechannel(ob); - - /* calculate/set inverse matrix */ - if (pchan) { - float pmat[4][4], cinf; - float imat[4][4], tmat[4][4]; - - /* make copy of pchan's original pose-mat (for use later) */ - Mat4CpyMat4(pmat, pchan->pose_mat); - - /* disable constraint for pose to be solved without it */ - cinf= con->enforce; - con->enforce= 0.0f; - - /* solve pose without constraint */ - where_is_pose(scene, ob); - - /* determine effect of constraint by removing the newly calculated - * pchan->pose_mat from the original pchan->pose_mat, thus determining - * the effect of the constraint - */ - Mat4Invert(imat, pchan->pose_mat); - Mat4MulMat4(tmat, imat, pmat); - Mat4Invert(data->invmat, tmat); - - /* recalculate pose with new inv-mat */ - con->enforce= cinf; - where_is_pose(scene, ob); - } - else if (ob) { - Object workob; - /* use what_does_parent to find inverse - just like for normal parenting. - * NOTE: what_does_parent uses a static workob defined in object.c - */ - what_does_parent(scene, ob, &workob); - Mat4Invert(data->invmat, workob.obmat); - } - else - Mat4One(data->invmat); - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); - - return OPERATOR_FINISHED; -} - -void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Set Inverse"; - ot->idname= "CONSTRAINT_OT_childof_set_inverse"; - ot->description= "Set inverse correction for ChildOf constraint."; - - ot->exec= childof_set_inverse_exec; - ot->poll= childof_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* ChildOf Constraint - clear inverse callback */ -static int childof_clear_inverse_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - bChildOfConstraint *data= (bChildOfConstraint *)con->data; - - /* simply clear the matrix */ - Mat4One(data->invmat); - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); - - return OPERATOR_FINISHED; -} - -void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Clear Inverse"; - ot->idname= "CONSTRAINT_OT_childof_clear_inverse"; - ot->description= "Clear inverse correction for ChildOf constraint."; - - ot->exec= childof_clear_inverse_exec; - ot->poll= childof_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/***************************** BUTTONS ****************************/ - -/* Rename the given constraint, con already has the new name */ -void ED_object_constraint_rename(Object *ob, bConstraint *con, char *oldname) -{ - bConstraint *tcon; - ListBase *conlist= NULL; - int from_object= 0; - - /* get context by searching for con (primitive...) */ - for (tcon= ob->constraints.first; tcon; tcon= tcon->next) { - if (tcon==con) - break; - } - - if (tcon) { - conlist= &ob->constraints; - from_object= 1; - } - else if (ob->pose) { - bPoseChannel *pchan; - - for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { - for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) { - if (tcon==con) - break; - } - if (tcon) - break; - } - - if (tcon) { - conlist= &pchan->constraints; - } - } - - if (conlist==NULL) { - printf("rename constraint failed\n"); /* should not happen in UI */ - return; - } - - /* first make sure it's a unique name within context */ - unique_constraint_name(con, conlist); -} - - - - -void ED_object_constraint_set_active(Object *ob, bConstraint *con) -{ - ListBase *lb; - bConstraint *origcon= con; - - /* lets be nice and escape if its active already */ - if(con && (con->flag & CONSTRAINT_ACTIVE)) - return ; - - lb= get_active_constraints(ob); - if(lb == NULL) - return; - - for(con= lb->first; con; con= con->next) { - if(con==origcon) con->flag |= CONSTRAINT_ACTIVE; - else con->flag &= ~CONSTRAINT_ACTIVE; - } -} - -static int constraint_poll(bContext *C) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); - return (ptr.id.data && ptr.data); -} - -static int constraint_delete_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - ListBase *lb; - - /* remove constraint itself */ - lb= get_active_constraints(ob); - free_constraint_data(con); - BLI_freelinkN(lb, con); - - ED_object_constraint_set_active(ob, NULL); - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); - - return OPERATOR_FINISHED; -} - -void CONSTRAINT_OT_delete (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Delete Constraint"; - ot->idname= "CONSTRAINT_OT_delete"; - ot->description= "Remove constraitn from constraint stack."; - - /* callbacks */ - ot->exec= constraint_delete_exec; - ot->poll= constraint_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int constraint_move_down_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - - if (con->next) { - ListBase *conlist= get_active_constraints(ob); - bConstraint *nextCon= con->next; - - /* insert the nominated constraint after the one that used to be after it */ - BLI_remlink(conlist, con); - BLI_insertlinkafter(conlist, nextCon, con); - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void CONSTRAINT_OT_move_down (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Move Constraint Down"; - ot->idname= "CONSTRAINT_OT_move_down"; - ot->description= "Move constraint down constraint stack."; - - /* callbacks */ - ot->exec= constraint_move_down_exec; - ot->poll= constraint_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - - -static int constraint_move_up_exec (bContext *C, wmOperator *op) -{ - PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); - Object *ob= ptr.id.data; - bConstraint *con= ptr.data; - - if (con->prev) { - ListBase *conlist= get_active_constraints(ob); - bConstraint *prevCon= con->prev; - - /* insert the nominated constraint before the one that used to be before it */ - BLI_remlink(conlist, con); - BLI_insertlinkbefore(conlist, prevCon, con); - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void CONSTRAINT_OT_move_up (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Move Constraint Up"; - ot->idname= "CONSTRAINT_OT_move_up"; - ot->description= "Move constraint up constraint stack."; - - /* callbacks */ - ot->exec= constraint_move_up_exec; - ot->poll= constraint_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/***************************** OPERATORS ****************************/ - -/************************ remove constraint operators *********************/ - -static int pose_constraints_clear_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_active_object(C); - - /* free constraints for all selected bones */ - CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) - { - free_constraints(&pchan->constraints); - } - CTX_DATA_END; - - /* do updates */ - DAG_id_flush_update(&ob->id, OB_RECALC_OB); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob); - - return OPERATOR_FINISHED; -} - -void POSE_OT_constraints_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Constraints"; - ot->idname= "POSE_OT_constraints_clear"; - ot->description= "Clear all the constraints for the selected bones."; - - /* callbacks */ - ot->exec= pose_constraints_clear_exec; - ot->poll= ED_operator_posemode; // XXX - do we want to ensure there are selected bones too? -} - - -static int object_constraints_clear_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_active_object(C); - - /* do freeing */ - // TODO: we should free constraints for all selected objects instead (to be more consistent with bones) - free_constraints(&ob->constraints); - - /* do updates */ - DAG_id_flush_update(&ob->id, OB_RECALC_OB); - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_constraints_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Constraints"; - ot->idname= "OBJECT_OT_constraints_clear"; - ot->description= "Clear all the constraints for the active Object only."; - - /* callbacks */ - ot->exec= object_constraints_clear_exec; - ot->poll= ED_operator_object_active; -} - -/************************ add constraint operators *********************/ - -/* get the Object and/or PoseChannel to use as target */ -static short get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, short add) -{ - Object *obact= CTX_data_active_object(C); - bPoseChannel *pchanact= get_active_posechannel(obact); - short only_curve= 0, only_mesh= 0, only_ob= 0; - short found= 0; - - /* clear tar_ob and tar_pchan fields before use - * - assume for now that both always exist... - */ - *tar_ob= NULL; - *tar_pchan= NULL; - - /* check if constraint type doesn't requires a target - * - if so, no need to get any targets - */ - switch (con_type) { - /* no-target constraints --------------------------- */ - /* null constraint - shouldn't even be added! */ - case CONSTRAINT_TYPE_NULL: - /* limit constraints - no targets needed */ - case CONSTRAINT_TYPE_LOCLIMIT: - case CONSTRAINT_TYPE_ROTLIMIT: - case CONSTRAINT_TYPE_SIZELIMIT: - return 0; - - /* restricted target-type constraints -------------- */ - /* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */ - /* curve-based constraints - set the only_curve and only_ob flags */ - case CONSTRAINT_TYPE_TRACKTO: - case CONSTRAINT_TYPE_CLAMPTO: - case CONSTRAINT_TYPE_FOLLOWPATH: - only_curve= 1; - only_ob= 1; - add= 0; - break; - - /* mesh only? */ - case CONSTRAINT_TYPE_SHRINKWRAP: - only_mesh= 1; - only_ob= 1; - add= 0; - break; - - /* object only - add here is ok? */ - case CONSTRAINT_TYPE_RIGIDBODYJOINT: - only_ob= 1; - break; - } - - /* if the active Object is Armature, and we can search for bones, do so... */ - if ((obact->type == OB_ARMATURE) && (only_ob == 0)) { - /* search in list of selected Pose-Channels for target */ - CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) - { - /* just use the first one that we encounter, as long as it is not the active one */ - if (pchan != pchanact) { - *tar_ob= obact; - *tar_pchan= pchan; - found= 1; - - break; - } - } - CTX_DATA_END; - } - - /* if not yet found, try selected Objects... */ - if (found == 0) { - /* search in selected objects context */ - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) - { - /* just use the first object we encounter (that isn't the active object) - * and which fulfills the criteria for the object-target that we've got - */ - if ( (ob != obact) && - ((!only_curve) || (ob->type == OB_CURVE)) && - ((!only_mesh) || (ob->type == OB_MESH)) ) - { - /* set target */ - *tar_ob= ob; - found= 1; - - /* perform some special operations on the target */ - if (only_curve) { - /* Curve-Path option must be enabled for follow-path constraints to be able to work */ - Curve *cu= (Curve *)ob->data; - cu->flag |= CU_PATH; - } - - break; - } - } - CTX_DATA_END; - } - - /* if still not found, add a new empty to act as a target (if allowed) */ - if ((found == 0) && (add)) { - Scene *scene= CTX_data_scene(C); - Base *base= BASACT, *newbase=NULL; - Object *obt; - - /* add new target object */ - obt= add_object(scene, OB_EMPTY); - - /* set layers OK */ - newbase= BASACT; - newbase->lay= base->lay; - obt->lay= newbase->lay; - - /* transform cent to global coords for loc */ - if (pchanact) { - /* since by default, IK targets the tip of the last bone, use the tip of the active PoseChannel - * if adding a target for an IK Constraint - */ - if (con_type == CONSTRAINT_TYPE_KINEMATIC) - VecMat4MulVecfl(obt->loc, obact->obmat, pchanact->pose_tail); - else - VecMat4MulVecfl(obt->loc, obact->obmat, pchanact->pose_head); - } - else - VECCOPY(obt->loc, obact->obmat[3]); - - /* restore, add_object sets active */ - BASACT= base; - base->flag |= SELECT; - - /* make our new target the new object */ - *tar_ob= obt; - found= 1; - } - - /* return whether there's any target */ - return found; -} - -/* used by add constraint operators to add the constraint required */ -static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, short setTarget) -{ - Scene *scene= CTX_data_scene(C); - bPoseChannel *pchan= get_active_posechannel(ob); - bConstraint *con; - - /* check if constraint to be added is valid for the given constraints stack */ - if (type == CONSTRAINT_TYPE_NULL) { - return OPERATOR_CANCELLED; - } - if ( (type == CONSTRAINT_TYPE_RIGIDBODYJOINT) && (list != &ob->constraints) ) { - BKE_report(op->reports, RPT_ERROR, "Rigid Body Joint Constraint can only be added to Objects."); - return OPERATOR_CANCELLED; - } - if ( (type == CONSTRAINT_TYPE_KINEMATIC) && ((!pchan) || (list != &pchan->constraints)) ) { - BKE_report(op->reports, RPT_ERROR, "IK Constraint can only be added to Bones."); - return OPERATOR_CANCELLED; - } - - /* create a new constraint of the type requried, and add it to the active/given constraints list */ - con = add_new_constraint(type); - - if (list) { - bConstraint *coniter; - - /* add new constraint to end of list of constraints before ensuring that it has a unique name - * (otherwise unique-naming code will fail, since it assumes element exists in list) - */ - BLI_addtail(list, con); - unique_constraint_name(con, list); - - /* if the target list is a list on some PoseChannel belonging to a proxy-protected - * Armature layer, we must tag newly added constraints with a flag which allows them - * to persist after proxy syncing has been done - */ - if (proxylocked_constraints_owner(ob, pchan)) - con->flag |= CONSTRAINT_PROXY_LOCAL; - - /* make this constraint the active one - * - since constraint was added at end of stack, we can just go - * through deactivating all previous ones - */ - con->flag |= CONSTRAINT_ACTIVE; - for (coniter= con->prev; coniter; coniter= coniter->prev) - coniter->flag &= ~CONSTRAINT_ACTIVE; - } - - /* get the first selected object/bone, and make that the target - * - apart from the buttons-window add buttons, we shouldn't add in this way - */ - if (setTarget) { - Object *tar_ob= NULL; - bPoseChannel *tar_pchan= NULL; - - /* get the target objects, adding them as need be */ - if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) { - /* method of setting target depends on the type of target we've got - * - by default, just set the first target (distinction here is only for multiple-targetted constraints) - */ - if (tar_pchan) - set_constraint_nth_target(con, tar_ob, tar_pchan->name, 0); - else - set_constraint_nth_target(con, tar_ob, "", 0); - } - } - - /* do type-specific tweaking to the constraint settings */ - switch (type) { - case CONSTRAINT_TYPE_CHILDOF: - { - /* if this constraint is being added to a posechannel, make sure - * the constraint gets evaluated in pose-space */ - if (ob->mode & OB_MODE_POSE) { - con->ownspace = CONSTRAINT_SPACE_POSE; - con->flag |= CONSTRAINT_SPACEONCE; - } - } - break; - - case CONSTRAINT_TYPE_PYTHON: // FIXME: this code is not really valid anymore - { - char *menustr; - int scriptint= 0; -#ifndef DISABLE_PYTHON - /* popup a list of usable scripts */ - menustr = buildmenu_pyconstraints(NULL, &scriptint); - scriptint = pupmenu(menustr); - MEM_freeN(menustr); - - /* only add constraint if a script was chosen */ - if (scriptint) { - /* add constraint */ - validate_pyconstraint_cb(con->data, &scriptint); - - /* make sure target allowance is set correctly */ - BPY_pyconstraint_update(ob, con); - } -#endif - } - default: - break; - } - - /* make sure all settings are valid - similar to above checks, but sometimes can be wrong */ - object_test_constraints(ob); - - if (ob->pose) - update_pose_constraint_flags(ob->pose); - - - /* force depsgraph to get recalculated since new relationships added */ - DAG_scene_sort(scene); /* sort order of objects */ - - if ((ob->type==OB_ARMATURE) && (pchan)) { - ob->pose->flag |= POSE_RECALC; /* sort pose channels */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB); - } - else - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - - /* notifiers for updates */ - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, ob); - - return OPERATOR_FINISHED; -} - -/* ------------------ */ - -/* dummy operator callback */ -static int object_constraint_add_exec(bContext *C, wmOperator *op) -{ - ScrArea *sa= CTX_wm_area(C); - Object *ob; - int type= RNA_enum_get(op->ptr, "type"); - short with_targets= 0; - - /* get active object from context */ - if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - else - ob= CTX_data_active_object(C); - - if (!ob) { - BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to."); - return OPERATOR_CANCELLED; - } - - /* hack: set constraint targets from selected objects in context is allowed when - * operator name included 'with_targets', since the menu doesn't allow multiple properties - */ - if (strstr(op->idname, "with_targets")) - with_targets= 1; - - return constraint_add_exec(C, op, ob, &ob->constraints, type, with_targets); -} - -/* dummy operator callback */ -static int pose_constraint_add_exec(bContext *C, wmOperator *op) -{ - ScrArea *sa= CTX_wm_area(C); - Object *ob; - int type= RNA_enum_get(op->ptr, "type"); - short with_targets= 0; - - /* get active object from context */ - if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - else - ob= CTX_data_active_object(C); - - if (!ob) { - BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to."); - return OPERATOR_CANCELLED; - } - - /* hack: set constraint targets from selected objects in context is allowed when - * operator name included 'with_targets', since the menu doesn't allow multiple properties - */ - if (strstr(op->idname, "with_targets")) - with_targets= 1; - - return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets); -} - -/* ------------------ */ - -void OBJECT_OT_constraint_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Constraint"; - ot->description = "Add a constraint to the active object."; - ot->idname= "OBJECT_OT_constraint_add"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_constraint_add_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); -} - -void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Constraint (with Targets)"; - ot->description = "Add a constraint to the active object, with target (where applicable) set to the selected Objects/Bones."; - ot->idname= "OBJECT_OT_constraint_add_with_targets"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_constraint_add_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); -} - -void POSE_OT_constraint_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Constraint"; - ot->description = "Add a constraint to the active bone."; - ot->idname= "POSE_OT_constraint_add"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= pose_constraint_add_exec; - ot->poll= ED_operator_posemode; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); -} - -void POSE_OT_constraint_add_with_targets(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Constraint (with Targets)"; - ot->description = "Add a constraint to the active bone, with target (where applicable) set to the selected Objects/Bones."; - ot->idname= "POSE_OT_constraint_add_with_targets"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= pose_constraint_add_exec; - ot->poll= ED_operator_posemode; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); -} - -/************************ IK Constraint operators *********************/ -/* NOTE: only for Pose-Channels */ -// TODO: should these be here, or back in editors/armature/poseobject.c again? - -/* present menu with options + validation for targets to use */ -static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *evt) -{ - Object *ob= CTX_data_active_object(C); - bPoseChannel *pchan= get_active_posechannel(ob); - bConstraint *con= NULL; - - uiPopupMenu *pup; - uiLayout *layout; - Object *tar_ob= NULL; - bPoseChannel *tar_pchan= NULL; - - /* must have active bone */ - if (ELEM(NULL, ob, pchan)) { - BKE_report(op->reports, RPT_ERROR, "Must have active bone to add IK Constraint to."); - return OPERATOR_CANCELLED; - } - - /* bone must not have any constraints already */ - for (con= pchan->constraints.first; con; con= con->next) { - if (con->type==CONSTRAINT_TYPE_KINEMATIC) break; - } - if (con) { - BKE_report(op->reports, RPT_ERROR, "Bone already has IK Constraint."); - return OPERATOR_CANCELLED; - } - - /* prepare popup menu to choose targetting options */ - pup= uiPupMenuBegin(C, "Add IK", 0); - layout= uiPupMenuLayout(pup); - - /* the type of targets we'll set determines the menu entries to show... */ - if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) { - /* bone target, or object target? - * - the only thing that matters is that we want a target... - */ - if (tar_pchan) - uiItemBooleanO(layout, "To Active Bone", 0, "POSE_OT_ik_add", "with_targets", 1); - else - uiItemBooleanO(layout, "To Active Object", 0, "POSE_OT_ik_add", "with_targets", 1); - } - else { - /* we have a choice of adding to a new empty, or not setting any target (targetless IK) */ - uiItemBooleanO(layout, "To New Empty Object", 0, "POSE_OT_ik_add", "with_targets", 1); - uiItemBooleanO(layout, "Without Targets", 0, "POSE_OT_ik_add", "with_targets", 0); - } - - /* finish building the menu, and process it (should result in calling self again) */ - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -/* call constraint_add_exec() to add the IK constraint */ -static int pose_ik_add_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_active_object(C); - int with_targets= RNA_boolean_get(op->ptr, "with_targets"); - - /* add the constraint - all necessary checks should have been done by the invoke() callback already... */ - return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets); -} - -void POSE_OT_ik_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add IK to Bone"; - ot->description= "Add IK Constraint to the active Bone."; - ot->idname= "POSE_OT_ik_add"; - - /* api callbacks */ - ot->invoke= pose_ik_add_invoke; - ot->exec= pose_ik_add_exec; - ot->poll= ED_operator_posemode; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "with_targets", 1, "With Targets", "Assign IK Constraint with targets derived from the select bones/objects"); -} - -/* ------------------ */ - -/* remove IK constraints from selected bones */ -static int pose_ik_clear_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_active_object(C); - - /* only remove IK Constraints */ - CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) - { - bConstraint *con, *next; - - // TODO: should we be checking if these contraints were local before we try and remove them? - for (con= pchan->constraints.first; con; con= next) { - next= con->next; - if (con->type==CONSTRAINT_TYPE_KINEMATIC) { - free_constraint_data(con); - BLI_freelinkN(&pchan->constraints, con); - } - } - pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET); - } - CTX_DATA_END; - - /* */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - - /* note, notifier might evolve */ - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); - - return OPERATOR_FINISHED; -} - -void POSE_OT_ik_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Remove IK"; - ot->description= "Remove all IK Constraints from selected bones."; - ot->idname= "POSE_OT_ik_clear"; - - /* api callbacks */ - ot->exec= pose_ik_clear_exec; - ot->poll= ED_operator_posemode; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} diff --git a/source/blender/editors/object/editgroup.c b/source/blender/editors/object/editgroup.c deleted file mode 100644 index 9a184892e71..00000000000 --- a/source/blender/editors/object/editgroup.c +++ /dev/null @@ -1,257 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "DNA_group_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_depsgraph.h" -#include "BKE_group.h" -#include "BKE_global.h" -#include "BKE_context.h" -#include "BKE_main.h" -#include "BKE_report.h" - -#include "ED_view3d.h" -#include "ED_space_api.h" -#include "ED_screen.h" -#include "ED_types.h" -#include "ED_util.h" - -#include "UI_interface.h" -#include "UI_resources.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "RNA_access.h" -#include "RNA_define.h" - -#include "object_intern.h" - -static int objects_add_active_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= OBACT, *obt; - Group *group; - int ok = 0; - - if (!ob) return OPERATOR_CANCELLED; - - /* linking to same group requires its own loop so we can avoid - looking up the active objects groups each time */ - - group= G.main->group.first; - while(group) { - if(object_in_group(ob, group)) { - /* Assign groups to selected objects */ - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - obt= base->object; - add_to_group(group, obt); - obt->flag |= OB_FROMGROUP; - base->flag |= OB_FROMGROUP; - base->object->recalc= OB_RECALC_OB; - ok = 1; - } - CTX_DATA_END; - } - group= group->id.next; - } - - if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups"); - - DAG_scene_sort(CTX_data_scene(C)); - - WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); - - return OPERATOR_FINISHED; - -} - -void GROUP_OT_objects_add_active(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Add Selected To Active Group"; - ot->description = "Add the object to an object group that contains the active object."; - ot->idname= "GROUP_OT_objects_add_active"; - - /* api callbacks */ - ot->exec= objects_add_active_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int objects_remove_active_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= OBACT, *obt; - Group *group; - int ok = 0; - - if (!ob) return OPERATOR_CANCELLED; - - /* linking to same group requires its own loop so we can avoid - looking up the active objects groups each time */ - - group= G.main->group.first; - while(group) { - if(object_in_group(ob, group)) { - /* Assign groups to selected objects */ - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - obt= base->object; - rem_from_group(group, obt); - obt->flag &= ~OB_FROMGROUP; - base->flag &= ~OB_FROMGROUP; - base->object->recalc= OB_RECALC_OB; - ok = 1; - } - CTX_DATA_END; - } - group= group->id.next; - } - - if (!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups"); - - DAG_scene_sort(CTX_data_scene(C)); - - WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); - - return OPERATOR_FINISHED; - -} - -void GROUP_OT_objects_remove_active(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Remove Selected From Active Group"; - ot->description = "Remove the object from an object group that contains the active object."; - ot->idname= "GROUP_OT_objects_remove_active"; - - /* api callbacks */ - ot->exec= objects_remove_active_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int group_remove_exec(bContext *C, wmOperator *op) -{ - Group *group= NULL; - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - group = NULL; - while( (group = find_group(base->object, group)) ) { - rem_from_group(group, base->object); - } - base->object->flag &= ~OB_FROMGROUP; - base->flag &= ~OB_FROMGROUP; - base->object->recalc= OB_RECALC_OB; - } - CTX_DATA_END; - - DAG_scene_sort(CTX_data_scene(C)); - - WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); - - return OPERATOR_FINISHED; - -} - -void GROUP_OT_objects_remove(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Remove From Groups"; - ot->description = "Remove selected objects from all groups."; - ot->idname= "GROUP_OT_objects_remove"; - - /* api callbacks */ - ot->exec= group_remove_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int group_create_exec(bContext *C, wmOperator *op) -{ - Group *group= NULL; - char gid[32]; //group id - - RNA_string_get(op->ptr, "GID", gid); - - group= add_group(gid); - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - add_to_group(group, base->object); - base->object->flag |= OB_FROMGROUP; - base->flag |= OB_FROMGROUP; - base->object->recalc= OB_RECALC_OB; - } - CTX_DATA_END; - - DAG_scene_sort(CTX_data_scene(C)); - - WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); - - return OPERATOR_FINISHED; - -} - -void GROUP_OT_group_create(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Create New Group"; - ot->description = "Create an object group."; - ot->idname= "GROUP_OT_group_create"; - - /* api callbacks */ - ot->exec= group_create_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_string(ot->srna, "GID", "Group", 32, "Name", "Name of the new group"); -} - diff --git a/source/blender/editors/object/editkey.c b/source/blender/editors/object/editkey.c deleted file mode 100644 index 2ec3edd846a..00000000000 --- a/source/blender/editors/object/editkey.c +++ /dev/null @@ -1,539 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Blender Foundation, shapekey support - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include - -#ifndef WIN32 -#include -#else -#include -#endif - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "DNA_action_types.h" -#include "DNA_curve_types.h" -#include "DNA_ipo_types.h" -#include "DNA_key_types.h" -#include "DNA_lattice_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_userdef_types.h" -#include "DNA_view2d_types.h" - -#include "BKE_action.h" -#include "BKE_anim.h" -#include "BKE_context.h" -#include "BKE_curve.h" -#include "BKE_depsgraph.h" -#include "BKE_global.h" -#include "BKE_ipo.h" -#include "BKE_key.h" -#include "BKE_library.h" -#include "BKE_main.h" -#include "BKE_mesh.h" -#include "BKE_object.h" -#include "BKE_utildefines.h" - -#include "BLO_sys_types.h" // for intptr_t support - -#include "ED_object.h" - -#include "RNA_access.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "object_intern.h" - -#if 0 // XXX old animation system -static void default_key_ipo(Scene *scene, Key *key) -{ - IpoCurve *icu; - BezTriple *bezt; - - key->ipo= add_ipo(scene, "KeyIpo", ID_KE); - - icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); - - icu->blocktype= ID_KE; - icu->adrcode= KEY_SPEED; - icu->flag= IPO_VISIBLE|IPO_SELECT|IPO_AUTO_HORIZ; - set_icu_vars(icu); - - BLI_addtail( &(key->ipo->curve), icu); - - icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo"); - icu->totvert= 2; - - bezt->hide= IPO_BEZ; - bezt->f1=bezt->f2= bezt->f3= SELECT; - bezt->h1= bezt->h2= HD_AUTO; - bezt++; - bezt->vec[1][0]= 100.0; - bezt->vec[1][1]= 1.0; - bezt->hide= IPO_BEZ; - bezt->f1=bezt->f2= bezt->f3= SELECT; - bezt->h1= bezt->h2= HD_AUTO; - - calchandles_ipocurve(icu); -} -#endif // XXX old animation system - - -/************************* Mesh ************************/ - -void mesh_to_key(Mesh *me, KeyBlock *kb) -{ - MVert *mvert; - float *fp; - int a; - - if(me->totvert==0) return; - - if(kb->data) MEM_freeN(kb->data); - - kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); - kb->totelem= me->totvert; - - mvert= me->mvert; - fp= kb->data; - for(a=0; atotelem; a++, fp+=3, mvert++) { - VECCOPY(fp, mvert->co); - - } -} - -void key_to_mesh(KeyBlock *kb, Mesh *me) -{ - MVert *mvert; - float *fp; - int a, tot; - - mvert= me->mvert; - fp= kb->data; - - tot= MIN2(kb->totelem, me->totvert); - - for(a=0; aco, fp); - } -} - -static KeyBlock *add_keyblock(Scene *scene, Key *key) -{ - KeyBlock *kb; - float curpos= -0.1; - int tot; - - kb= key->block.last; - if(kb) curpos= kb->pos; - - kb= MEM_callocN(sizeof(KeyBlock), "Keyblock"); - BLI_addtail(&key->block, kb); - kb->type= KEY_CARDINAL; - - tot= BLI_countlist(&key->block); - if(tot==1) strcpy(kb->name, "Basis"); - else sprintf(kb->name, "Key %d", tot-1); - - // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey) - kb->adrcode= tot-1; - - key->totkey++; - if(key->totkey==1) key->refkey= kb; - - kb->slidermin= 0.0f; - kb->slidermax= 1.0f; - - // XXX kb->pos is the confusing old horizontal-line RVK crap in old IPO Editor... - if(key->type == KEY_RELATIVE) - kb->pos= curpos+0.1; - else { -#if 0 // XXX old animation system - curpos= bsystem_time(scene, 0, (float)CFRA, 0.0); - if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) { - curpos /= 100.0; - } - kb->pos= curpos; - - sort_keys(key); -#endif // XXX old animation system - } - return kb; -} - -void insert_meshkey(Scene *scene, Mesh *me, short rel) -{ - Key *key; - KeyBlock *kb; - - if(me->key==NULL) { - me->key= add_key( (ID *)me); - - if(rel) - me->key->type = KEY_RELATIVE; -// else -// default_key_ipo(scene, me->key); // XXX old animation system - } - key= me->key; - - kb= add_keyblock(scene, key); - - mesh_to_key(me, kb); -} - -/************************* Lattice ************************/ - -void latt_to_key(Lattice *lt, KeyBlock *kb) -{ - BPoint *bp; - float *fp; - int a, tot; - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - if(tot==0) return; - - if(kb->data) MEM_freeN(kb->data); - - kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data"); - kb->totelem= tot; - - bp= lt->def; - fp= kb->data; - for(a=0; atotelem; a++, fp+=3, bp++) { - VECCOPY(fp, bp->vec); - } -} - -void key_to_latt(KeyBlock *kb, Lattice *lt) -{ - BPoint *bp; - float *fp; - int a, tot; - - bp= lt->def; - fp= kb->data; - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - tot= MIN2(kb->totelem, tot); - - for(a=0; avec, fp); - } - -} - -/* exported to python... hrms, should not, use object levels! (ton) */ -void insert_lattkey(Scene *scene, Lattice *lt, short rel) -{ - Key *key; - KeyBlock *kb; - - if(lt->key==NULL) { - lt->key= add_key( (ID *)lt); -// default_key_ipo(scene, lt->key); // XXX old animation system - } - key= lt->key; - - kb= add_keyblock(scene, key); - - latt_to_key(lt, kb); -} - -/************************* Curve ************************/ - -void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - float *fp; - int a, tot; - - /* count */ - tot= count_curveverts(nurb); - if(tot==0) return; - - if(kb->data) MEM_freeN(kb->data); - - kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data"); - kb->totelem= tot; - - nu= nurb->first; - fp= kb->data; - while(nu) { - - if(nu->bezt) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - VECCOPY(fp, bezt->vec[0]); - fp+= 3; - VECCOPY(fp, bezt->vec[1]); - fp+= 3; - VECCOPY(fp, bezt->vec[2]); - fp+= 3; - fp[0]= bezt->alfa; - fp+= 3; /* alphas */ - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - VECCOPY(fp, bp->vec); - fp[3]= bp->alfa; - - fp+= 4; - bp++; - } - } - nu= nu->next; - } -} - -void key_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - float *fp; - int a, tot; - - nu= nurb->first; - fp= kb->data; - - tot= count_curveverts(nurb); - - tot= MIN2(kb->totelem, tot); - - while(nu && tot>0) { - - if(nu->bezt) { - bezt= nu->bezt; - a= nu->pntsu; - while(a-- && tot>0) { - VECCOPY(bezt->vec[0], fp); - fp+= 3; - VECCOPY(bezt->vec[1], fp); - fp+= 3; - VECCOPY(bezt->vec[2], fp); - fp+= 3; - bezt->alfa= fp[0]; - fp+= 3; /* alphas */ - - tot-= 3; - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a-- && tot>0) { - VECCOPY(bp->vec, fp); - bp->alfa= fp[3]; - - fp+= 4; - tot--; - bp++; - } - } - nu= nu->next; - } -} - - -void insert_curvekey(Scene *scene, Curve *cu, short rel) -{ - Key *key; - KeyBlock *kb; - - if(cu->key==NULL) { - cu->key= add_key( (ID *)cu); - - if(rel) - cu->key->type = KEY_RELATIVE; -// else -// default_key_ipo(scene, cu->key); // XXX old animation system - } - key= cu->key; - - kb= add_keyblock(scene, key); - - if(cu->editnurb->first) curve_to_key(cu, kb, cu->editnurb); - else curve_to_key(cu, kb, &cu->nurb); -} - -/*********************** add shape key ***********************/ - -void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob) -{ - Key *key; - - if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1); - else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1); - else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1); - - key= ob_get_key(ob); - ob->shapenr= BLI_countlist(&key->block); - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); -} - -/*********************** remove shape key ***********************/ - -int ED_object_shape_key_remove(bContext *C, Scene *scene, Object *ob) -{ - Main *bmain= CTX_data_main(C); - KeyBlock *kb, *rkb; - Key *key; - //IpoCurve *icu; - - key= ob_get_key(ob); - if(key==NULL) - return 0; - - kb= BLI_findlink(&key->block, ob->shapenr-1); - - if(kb) { - for(rkb= key->block.first; rkb; rkb= rkb->next) - if(rkb->relative == ob->shapenr-1) - rkb->relative= 0; - - BLI_remlink(&key->block, kb); - key->totkey--; - if(key->refkey== kb) - key->refkey= key->block.first; - - if(kb->data) MEM_freeN(kb->data); - MEM_freeN(kb); - - for(kb= key->block.first; kb; kb= kb->next) - if(kb->adrcode>=ob->shapenr) - kb->adrcode--; - -#if 0 // XXX old animation system - if(key->ipo) { - - for(icu= key->ipo->curve.first; icu; icu= icu->next) { - if(icu->adrcode==ob->shapenr-1) { - BLI_remlink(&key->ipo->curve, icu); - free_ipo_curve(icu); - break; - } - } - for(icu= key->ipo->curve.first; icu; icu= icu->next) - if(icu->adrcode>=ob->shapenr) - icu->adrcode--; - } -#endif // XXX old animation system - - if(ob->shapenr>1) ob->shapenr--; - } - - if(key->totkey==0) { - if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL; - else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL; - else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL; - - free_libblock_us(&(bmain->key), key); - } - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - - return 1; -} - -/********************** shape key operators *********************/ - -static int shape_key_poll(bContext *C) -{ - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - ID *data= (ob)? ob->data: NULL; - return (ob && !ob->id.lib && data && !data->lib); -} - -static int shape_key_add_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - - ED_object_shape_key_add(C, scene, ob); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_shape_key_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Shape Key"; - ot->idname= "OBJECT_OT_shape_key_add"; - - /* api callbacks */ - ot->poll= shape_key_poll; - ot->exec= shape_key_add_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int shape_key_remove_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - - if(!ED_object_shape_key_remove(C, scene, ob)) - return OPERATOR_CANCELLED; - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_shape_key_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Remove Shape Key"; - ot->idname= "OBJECT_OT_shape_key_remove"; - - /* api callbacks */ - ot->poll= shape_key_poll; - ot->exec= shape_key_remove_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - diff --git a/source/blender/editors/object/editlattice.c b/source/blender/editors/object/editlattice.c deleted file mode 100644 index 3ec1f3af014..00000000000 --- a/source/blender/editors/object/editlattice.c +++ /dev/null @@ -1,388 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "DNA_curve_types.h" -#include "DNA_key_types.h" -#include "DNA_lattice_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_armature.h" -#include "BKE_context.h" -#include "BKE_depsgraph.h" -#include "BKE_global.h" -#include "BKE_key.h" -#include "BKE_lattice.h" -#include "BKE_mesh.h" -#include "BKE_utildefines.h" - -#include "ED_object.h" -#include "ED_screen.h" -#include "ED_view3d.h" -#include "ED_util.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "object_intern.h" - -/********************** Load/Make/Free ********************/ - -void free_editLatt(Object *ob) -{ - Lattice *lt= ob->data; - - if(lt->editlatt) { - if(lt->editlatt->def) - MEM_freeN(lt->editlatt->def); - if(lt->editlatt->dvert) - free_dverts(lt->editlatt->dvert, lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw); - - MEM_freeN(lt->editlatt); - lt->editlatt= NULL; - } -} - -void make_editLatt(Object *obedit) -{ - Lattice *lt= obedit->data; - KeyBlock *actkey; - - free_editLatt(obedit); - - lt= obedit->data; - - actkey= ob_get_keyblock(obedit); - if(actkey) - key_to_latt(actkey, lt); - - lt->editlatt= MEM_dupallocN(lt); - lt->editlatt->def= MEM_dupallocN(lt->def); - - if(lt->dvert) { - int tot= lt->pntsu*lt->pntsv*lt->pntsw; - lt->editlatt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); - copy_dverts(lt->editlatt->dvert, lt->dvert, tot); - } -} - -void load_editLatt(Object *obedit) -{ - Lattice *lt; - KeyBlock *actkey; - BPoint *bp; - float *fp; - int tot; - - lt= obedit->data; - - actkey= ob_get_keyblock(obedit); - - if(actkey) { - /* active key: vertices */ - tot= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - - if(actkey->data) MEM_freeN(actkey->data); - - fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data"); - actkey->totelem= tot; - - bp= lt->editlatt->def; - while(tot--) { - VECCOPY(fp, bp->vec); - fp+= 3; - bp++; - } - } - else { - MEM_freeN(lt->def); - - lt->def= MEM_dupallocN(lt->editlatt->def); - - lt->flag= lt->editlatt->flag; - - lt->pntsu= lt->editlatt->pntsu; - lt->pntsv= lt->editlatt->pntsv; - lt->pntsw= lt->editlatt->pntsw; - - lt->typeu= lt->editlatt->typeu; - lt->typev= lt->editlatt->typev; - lt->typew= lt->editlatt->typew; - } - - if(lt->dvert) { - free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw); - lt->dvert= NULL; - } - - if(lt->editlatt->dvert) { - int tot= lt->pntsu*lt->pntsv*lt->pntsw; - - lt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); - copy_dverts(lt->dvert, lt->editlatt->dvert, tot); - } -} - -/************************** Operators *************************/ - -static void setflagsLatt(Object *obedit, int flag) -{ - Lattice *lt= obedit->data; - BPoint *bp; - int a; - - bp= lt->editlatt->def; - - a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - - while(a--) { - if(bp->hide==0) { - bp->f1= flag; - } - bp++; - } -} - -int de_select_all_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - Lattice *lt= obedit->data; - BPoint *bp; - int a, deselect= 0; - - bp= lt->editlatt->def; - a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - - while(a--) { - if(bp->hide==0) { - if(bp->f1) { - deselect= 1; - break; - } - } - bp++; - } - - if(deselect) - setflagsLatt(obedit, 0); - else - setflagsLatt(obedit, 1); - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_select_all_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select or Deselect All"; - ot->idname= "LATTICE_OT_select_all_toggle"; - - /* api callbacks */ - ot->exec= de_select_all_exec; - ot->poll= ED_operator_editlattice; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -int make_regular_poll(bContext *C) -{ - Object *ob; - - if(ED_operator_editlattice(C)) return 1; - - ob= CTX_data_active_object(C); - return (ob && ob->type==OB_LATTICE); -} - -int make_regular_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_edit_object(C); - Lattice *lt; - - if(ob) { - lt= ob->data; - resizelattice(lt->editlatt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); - } - else { - ob= CTX_data_active_object(C); - lt= ob->data; - resizelattice(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); - } - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - - return OPERATOR_FINISHED; -} - -void LATTICE_OT_make_regular(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Make Regular"; - ot->idname= "LATTICE_OT_make_regular"; - - /* api callbacks */ - ot->exec= make_regular_exec; - ot->poll= make_regular_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/****************************** Mouse Selection *************************/ - -static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y) -{ - struct { BPoint *bp; short dist, select, mval[2]; } *data = userData; - float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y); - - if((bp->f1 & SELECT)==data->select) - temp += 5; - - if(tempdist) { - data->dist = temp; - - data->bp = bp; - } -} - -static BPoint *findnearestLattvert(ViewContext *vc, short mval[2], int sel) -{ - /* sel==1: selected gets a disadvantage */ - /* in nurb and bezt or bp the nearest is written */ - /* return 0 1 2: handlepunt */ - struct { BPoint *bp; short dist, select, mval[2]; } data = {0}; - - data.dist = 100; - data.select = sel; - data.mval[0]= mval[0]; - data.mval[1]= mval[1]; - - lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); - - return data.bp; -} - -void mouse_lattice(bContext *C, short mval[2], int extend) -{ - ViewContext vc; - BPoint *bp= NULL; - - view3d_set_viewcontext(C, &vc); - bp= findnearestLattvert(&vc, mval, 1); - - if(bp) { - if(extend==0) { - setflagsLatt(vc.obedit, 0); - bp->f1 |= SELECT; - } - else - bp->f1 ^= SELECT; /* swap */ - - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); - } -} - -/******************************** Undo *************************/ - -typedef struct UndoLattice { - BPoint *def; - int pntsu, pntsv, pntsw; -} UndoLattice; - -static void undoLatt_to_editLatt(void *data, void *edata) -{ - UndoLattice *ult= (UndoLattice*)data; - Lattice *editlatt= (Lattice *)edata; - int a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; - - memcpy(editlatt->def, ult->def, a*sizeof(BPoint)); -} - -static void *editLatt_to_undoLatt(void *edata) -{ - UndoLattice *ult= MEM_callocN(sizeof(UndoLattice), "UndoLattice"); - Lattice *editlatt= (Lattice *)edata; - - ult->def= MEM_dupallocN(editlatt->def); - ult->pntsu= editlatt->pntsu; - ult->pntsv= editlatt->pntsv; - ult->pntsw= editlatt->pntsw; - - return ult; -} - -static void free_undoLatt(void *data) -{ - UndoLattice *ult= (UndoLattice*)data; - - if(ult->def) MEM_freeN(ult->def); - MEM_freeN(ult); -} - -static int validate_undoLatt(void *data, void *edata) -{ - UndoLattice *ult= (UndoLattice*)data; - Lattice *editlatt= (Lattice *)edata; - - return (ult->pntsu == editlatt->pntsu && - ult->pntsv == editlatt->pntsv && - ult->pntsw == editlatt->pntsw); -} - -static void *get_editlatt(bContext *C) -{ - Object *obedit= CTX_data_edit_object(C); - - if(obedit && obedit->type==OB_LATTICE) { - Lattice *lt= obedit->data; - return lt->editlatt; - } - - return NULL; -} - -/* and this is all the undo system needs to know */ -void undo_push_lattice(bContext *C, char *name) -{ - undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); -} - diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c new file mode 100644 index 00000000000..eaf7d41b9fe --- /dev/null +++ b/source/blender/editors/object/object_add.c @@ -0,0 +1,1451 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2002-2008 full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_fluidsim.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" +#include "DNA_vfont_types.h" + +#include "BLI_arithb.h" +#include "BLI_listbase.h" + +#include "BKE_anim.h" +#include "BKE_armature.h" +#include "BKE_constraint.h" +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_customdata.h" +#include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_lattice.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_object.h" +#include "BKE_particle.h" +#include "BKE_report.h" +#include "BKE_sca.h" +#include "BKE_scene.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_anim_api.h" +#include "ED_armature.h" +#include "ED_curve.h" +#include "ED_mball.h" +#include "ED_mesh.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_transform.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "object_intern.h" + +/************************** Exported *****************************/ + +void ED_object_base_init_from_view(bContext *C, Base *base) +{ + View3D *v3d= CTX_wm_view3d(C); + Scene *scene= CTX_data_scene(C); + Object *ob= base->object; + + if (scene==NULL) + return; + + if (v3d==NULL) { + base->lay = scene->lay; + VECCOPY(ob->loc, scene->cursor); + } + else { + if (v3d->localview) { + base->lay= ob->lay= v3d->layact | v3d->lay; + VECCOPY(ob->loc, v3d->cursor); + } + else { + base->lay= ob->lay= v3d->layact; + VECCOPY(ob->loc, scene->cursor); + } + + if (U.flag & USER_ADD_VIEWALIGNED) { + ARegion *ar= CTX_wm_region(C); + if(ar) { + RegionView3D *rv3d= ar->regiondata; + + rv3d->viewquat[0]= -rv3d->viewquat[0]; + QuatToEul(rv3d->viewquat, ob->rot); + rv3d->viewquat[0]= -rv3d->viewquat[0]; + } + } + } + where_is_object(scene, ob); +} + +/********************* Add Object Operator ********************/ + +void add_object_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menus, only non-editmode stuff */ +{ + /* keep here to get things compile, remove later */ +} + +/* for object add primitive operators */ +static Object *object_add_type(bContext *C, int type) +{ + Scene *scene= CTX_data_scene(C); + Object *ob; + + /* for as long scene has editmode... */ + if (CTX_data_edit_object(C)) + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ + + /* deselects all, sets scene->basact */ + ob= add_object(scene, type); + /* editor level activate, notifiers */ + ED_base_object_activate(C, BASACT); + + /* more editor stuff */ + ED_object_base_init_from_view(C, BASACT); + + DAG_scene_sort(scene); + + return ob; +} + +/* for object add operator */ +static int object_add_exec(bContext *C, wmOperator *op) +{ + object_add_type(C, RNA_int_get(op->ptr, "type")); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Object"; + ot->description = "Add an object to the scene."; + ot->idname= "OBJECT_OT_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_add_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", ""); +} + +/* ***************** add primitives *************** */ +/* ****** work both in and outside editmode ****** */ + +static EnumPropertyItem prop_mesh_types[] = { + {0, "PLANE", ICON_MESH_PLANE, "Plane", ""}, + {1, "CUBE", ICON_MESH_CUBE, "Cube", ""}, + {2, "CIRCLE", ICON_MESH_CIRCLE, "Circle", ""}, + {3, "UVSPHERE", ICON_MESH_UVSPHERE, "UVsphere", ""}, + {4, "ICOSPHERE", ICON_MESH_ICOSPHERE, "Icosphere", ""}, + {5, "CYLINDER", ICON_MESH_TUBE, "Cylinder", ""}, + {6, "CONE", ICON_MESH_CONE, "Cone", ""}, + {0, "", 0, NULL, NULL}, + {7, "GRID", ICON_MESH_GRID, "Grid", ""}, + {8, "MONKEY", ICON_MESH_MONKEY, "Monkey", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int object_add_mesh_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + int newob= 0; + + if(obedit==NULL || obedit->type!=OB_MESH) { + object_add_type(C, OB_MESH); + ED_object_enter_editmode(C, EM_DO_UNDO); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + switch(RNA_enum_get(op->ptr, "type")) { + case 0: + WM_operator_name_call(C, "MESH_OT_primitive_plane_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 1: + WM_operator_name_call(C, "MESH_OT_primitive_cube_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 2: + WM_operator_name_call(C, "MESH_OT_primitive_circle_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 3: + WM_operator_name_call(C, "MESH_OT_primitive_uv_sphere_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 4: + WM_operator_name_call(C, "MESH_OT_primitive_ico_sphere_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 5: + WM_operator_name_call(C, "MESH_OT_primitive_cylinder_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 6: + WM_operator_name_call(C, "MESH_OT_primitive_cone_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 7: + WM_operator_name_call(C, "MESH_OT_primitive_grid_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + case 8: + WM_operator_name_call(C, "MESH_OT_primitive_monkey_add", WM_OP_INVOKE_REGION_WIN, NULL); + break; + } + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_exit_editmode(C, EM_FREEDATA); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + + +void OBJECT_OT_mesh_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Mesh"; + ot->description = "Add a mesh object to the scene."; + ot->idname= "OBJECT_OT_mesh_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_add_mesh_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags: no register or undo, this operator calls operators */ + ot->flag= 0; //OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_mesh_types, 0, "Primitive", ""); +} + +static EnumPropertyItem prop_curve_types[] = { + {CU_BEZIER|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""}, + {CU_BEZIER|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", ICON_CURVE_BEZCIRCLE, "Bezier Circle", ""}, + {CU_NURBS|CU_PRIM_CURVE, "NURBS_CURVE", ICON_CURVE_NCURVE, "NURBS Curve", ""}, + {CU_NURBS|CU_PRIM_CIRCLE, "NURBS_CIRCLE", ICON_CURVE_NCIRCLE, "NURBS Circle", ""}, + {CU_NURBS|CU_PRIM_PATH, "PATH", ICON_CURVE_PATH, "Path", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int object_add_curve_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + ListBase *editnurb; + Nurb *nu; + int newob= 0; + + if(obedit==NULL || obedit->type!=OB_CURVE) { + object_add_type(C, OB_CURVE); + ED_object_enter_editmode(C, 0); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + obedit= CTX_data_edit_object(C); + nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob); + editnurb= curve_get_editcurve(obedit); + BLI_addtail(editnurb, nu); + + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_enter_editmode(C, 0); + ED_object_exit_editmode(C, EM_FREEDATA); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + +static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Object *obedit= CTX_data_edit_object(C); + uiPopupMenu *pup; + uiLayout *layout; + + pup= uiPupMenuBegin(C, op->type->name, 0); + layout= uiPupMenuLayout(pup); + if(!obedit || obedit->type == OB_CURVE) + uiItemsEnumO(layout, op->type->idname, "type"); + else + uiItemsEnumO(layout, "OBJECT_OT_surface_add", "type"); + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_curve_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Curve"; + ot->description = "Add a curve object to the scene."; + ot->idname= "OBJECT_OT_curve_add"; + + /* api callbacks */ + ot->invoke= object_add_curve_invoke; + ot->exec= object_add_curve_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_curve_types, 0, "Primitive", ""); +} + +static EnumPropertyItem prop_surface_types[]= { + {CU_PRIM_CURVE|CU_NURBS, "NURBS_CURVE", ICON_SURFACE_NCURVE, "NURBS Curve", ""}, + {CU_PRIM_CIRCLE|CU_NURBS, "NURBS_CIRCLE", ICON_SURFACE_NCIRCLE, "NURBS Circle", ""}, + {CU_PRIM_PATCH|CU_NURBS, "NURBS_SURFACE", ICON_SURFACE_NSURFACE, "NURBS Surface", ""}, + {CU_PRIM_TUBE|CU_NURBS, "NURBS_TUBE", ICON_SURFACE_NTUBE, "NURBS Tube", ""}, + {CU_PRIM_SPHERE|CU_NURBS, "NURBS_SPHERE", ICON_SURFACE_NSPHERE, "NURBS Sphere", ""}, + {CU_PRIM_DONUT|CU_NURBS, "NURBS_DONUT", ICON_SURFACE_NDONUT, "NURBS Donut", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int object_add_surface_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + ListBase *editnurb; + Nurb *nu; + int newob= 0; + + if(obedit==NULL || obedit->type!=OB_SURF) { + object_add_type(C, OB_SURF); + ED_object_enter_editmode(C, 0); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + obedit= CTX_data_edit_object(C); + nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob); + editnurb= curve_get_editcurve(obedit); + BLI_addtail(editnurb, nu); + + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_exit_editmode(C, EM_FREEDATA); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_surface_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Surface"; + ot->description = "Add a surface object to the scene."; + ot->idname= "OBJECT_OT_surface_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_add_surface_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_surface_types, 0, "Primitive", ""); +} + +static EnumPropertyItem prop_metaball_types[]= { + {MB_BALL, "MBALL_BALL", ICON_META_BALL, "Meta Ball", ""}, + {MB_TUBE, "MBALL_TUBE", ICON_META_TUBE, "Meta Tube", ""}, + {MB_PLANE, "MBALL_PLANE", ICON_META_PLANE, "Meta Plane", ""}, + {MB_CUBE, "MBALL_CUBE", ICON_META_CUBE, "Meta Cube", ""}, + {MB_ELIPSOID, "MBALL_ELLIPSOID", ICON_META_ELLIPSOID, "Meta Ellipsoid", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int object_metaball_add_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + MetaBall *mball; + MetaElem *elem; + int newob= 0; + + if(obedit==NULL || obedit->type!=OB_MBALL) { + object_add_type(C, OB_MBALL); + ED_object_enter_editmode(C, 0); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + obedit= CTX_data_edit_object(C); + elem= (MetaElem*)add_metaball_primitive(C, RNA_enum_get(op->ptr, "type"), newob); + mball= (MetaBall*)obedit->data; + BLI_addtail(mball->editelems, elem); + + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_exit_editmode(C, EM_FREEDATA); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + +static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Object *obedit= CTX_data_edit_object(C); + uiPopupMenu *pup; + uiLayout *layout; + + pup= uiPupMenuBegin(C, op->type->name, 0); + layout= uiPupMenuLayout(pup); + if(!obedit || obedit->type == OB_MBALL) + uiItemsEnumO(layout, op->type->idname, "type"); + else + uiItemsEnumO(layout, "OBJECT_OT_metaball_add", "type"); + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_metaball_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Metaball"; + ot->description= "Add an metaball object to the scene."; + ot->idname= "OBJECT_OT_metaball_add"; + + /* api callbacks */ + ot->invoke= object_metaball_add_invoke; + ot->exec= object_metaball_add_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_metaball_types, 0, "Primitive", ""); +} +static int object_add_text_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + + if(obedit && obedit->type==OB_FONT) + return OPERATOR_CANCELLED; + + object_add_type(C, OB_FONT); + obedit= CTX_data_active_object(C); + + if(U.flag & USER_ADD_EDITMODE) + ED_object_enter_editmode(C, 0); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_text_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Text"; + ot->description = "Add a text object to the scene"; + ot->idname= "OBJECT_OT_text_add"; + + /* api callbacks */ + ot->exec= object_add_text_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_armature_add_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + View3D *v3d= CTX_wm_view3d(C); + RegionView3D *rv3d= NULL; + int newob= 0; + + if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) { + object_add_type(C, OB_ARMATURE); + ED_object_enter_editmode(C, 0); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + if(v3d) + rv3d= CTX_wm_region(C)->regiondata; + + /* v3d and rv3d are allowed to be NULL */ + add_primitive_bone(CTX_data_scene(C), v3d, rv3d); + + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_exit_editmode(C, EM_FREEDATA); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_armature_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Armature"; + ot->description = "Add an armature object to the scene."; + ot->idname= "OBJECT_OT_armature_add"; + + /* api callbacks */ + ot->exec= object_armature_add_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0); + uiLayout *layout= uiPupMenuLayout(pup); + + uiItemMenuEnumO(layout, "Mesh", ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type"); + uiItemMenuEnumO(layout, "Curve", ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type"); + uiItemMenuEnumO(layout, "Surface", ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type"); + uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type"); + uiItemO(layout, "Text", ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add"); + uiItemS(layout); + uiItemO(layout, "Armature", ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add"); + uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LATTICE, "OBJECT_OT_add", "type", OB_LATTICE); + uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_add", "type", OB_EMPTY); + uiItemS(layout); + uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_add", "type", OB_CAMERA); + uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LAMP, "OBJECT_OT_add", "type", OB_LAMP); + + uiPupMenuEnd(C, pup); + + /* this operator is only for a menu, not used further */ + return OPERATOR_CANCELLED; +} + +/* only used as menu */ +void OBJECT_OT_primitive_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Primitive"; + ot->description = "Add a primitive object."; + ot->idname= "OBJECT_OT_primitive_add"; + + /* api callbacks */ + ot->invoke= object_primitive_add_invoke; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= 0; +} + +/**************************** Delete Object *************************/ + +/* remove base from a specific scene */ +/* note: now unlinks constraints as well */ +void ED_base_object_free_and_unlink(Scene *scene, Base *base) +{ + BLI_remlink(&scene->base, base); + free_libblock_us(&G.main->object, base->object); + if(scene->basact==base) scene->basact= NULL; + MEM_freeN(base); +} + +static int object_delete_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + int islamp= 0; + + if(CTX_data_edit_object(C)) + return OPERATOR_CANCELLED; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + + if(base->object->type==OB_LAMP) islamp= 1; + + /* remove from current scene only */ + ED_base_object_free_and_unlink(scene, base); + } + CTX_DATA_END; + + if(islamp) reshadeall_displist(scene); /* only frees displist */ + + DAG_scene_sort(scene); + ED_anim_dag_flush_update(C); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete"; + ot->description = "Delete selected objects."; + ot->idname= "OBJECT_OT_delete"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= object_delete_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/**************************** Copy Utilities ******************************/ + +static void copy_object__forwardModifierLinks(void *userData, Object *ob, + ID **idpoin) +{ + /* this is copied from ID_NEW; it might be better to have a macro */ + if(*idpoin && (*idpoin)->newid) *idpoin = (*idpoin)->newid; +} + +/* after copying objects, copied data should get new pointers */ +static void copy_object_set_idnew(bContext *C, int dupflag) +{ + Object *ob; + Material *ma, *mao; + ID *id; +#if 0 // XXX old animation system + Ipo *ipo; + bActionStrip *strip; +#endif // XXX old animation system + int a; + + /* XXX check object pointers */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob= base->object; + relink_constraints(&ob->constraints); + if (ob->pose){ + bPoseChannel *chan; + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ + relink_constraints(&chan->constraints); + } + } + modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL); + ID_NEW(ob->parent); + ID_NEW(ob->track); + ID_NEW(ob->proxy); + ID_NEW(ob->proxy_group); + +#if 0 // XXX old animation system + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + bActionModifier *amod; + for(amod= strip->modifiers.first; amod; amod= amod->next) + ID_NEW(amod->ob); + } +#endif // XXX old animation system + } + CTX_DATA_END; + + /* materials */ + if( dupflag & USER_DUP_MAT) { + mao= G.main->mat.first; + while(mao) { + if(mao->id.newid) { + + ma= (Material *)mao->id.newid; + + if(dupflag & USER_DUP_TEX) { + for(a=0; amtex[a]) { + id= (ID *)ma->mtex[a]->tex; + if(id) { + ID_NEW_US(ma->mtex[a]->tex) + else ma->mtex[a]->tex= copy_texture(ma->mtex[a]->tex); + id->us--; + } + } + } + } +#if 0 // XXX old animation system + id= (ID *)ma->ipo; + if(id) { + ID_NEW_US(ma->ipo) + else ma->ipo= copy_ipo(ma->ipo); + id->us--; + } +#endif // XXX old animation system + } + mao= mao->id.next; + } + } + +#if 0 // XXX old animation system + /* lamps */ + if( dupflag & USER_DUP_IPO) { + Lamp *la= G.main->lamp.first; + while(la) { + if(la->id.newid) { + Lamp *lan= (Lamp *)la->id.newid; + id= (ID *)lan->ipo; + if(id) { + ID_NEW_US(lan->ipo) + else lan->ipo= copy_ipo(lan->ipo); + id->us--; + } + } + la= la->id.next; + } + } + + /* ipos */ + ipo= G.main->ipo.first; + while(ipo) { + if(ipo->id.lib==NULL && ipo->id.newid) { + Ipo *ipon= (Ipo *)ipo->id.newid; + IpoCurve *icu; + for(icu= ipon->curve.first; icu; icu= icu->next) { + if(icu->driver) { + ID_NEW(icu->driver->ob); + } + } + } + ipo= ipo->id.next; + } +#endif // XXX old animation system + + set_sca_new_poins(); + + clear_id_newpoins(); +} + +/********************* Make Duplicates Real ************************/ + +static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base) +{ + Base *basen; + Object *ob; + ListBase *lb; + DupliObject *dob; + + if(!base && !(base = BASACT)) + return; + + if(!(base->object->transflag & OB_DUPLI)) + return; + + lb= object_duplilist(scene, base->object); + + for(dob= lb->first; dob; dob= dob->next) { + ob= copy_object(dob->ob); + /* font duplis can have a totcol without material, we get them from parent + * should be implemented better... + */ + if(ob->mat==NULL) ob->totcol= 0; + + basen= MEM_dupallocN(base); + basen->flag &= ~OB_FROMDUPLI; + BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */ + basen->object= ob; + ob->ipo= NULL; /* make sure apply works */ + ob->parent= ob->track= NULL; + ob->disp.first= ob->disp.last= NULL; + ob->transflag &= ~OB_DUPLI; + + Mat4CpyMat4(ob->obmat, dob->mat); + ED_object_apply_obmat(ob); + } + + copy_object_set_idnew(C, 0); + + free_object_duplilist(lb); + + base->object->transflag &= ~OB_DUPLI; +} + +static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + clear_id_newpoins(); + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + make_object_duplilist_real(C, scene, base); + } + CTX_DATA_END; + + DAG_scene_sort(scene); + ED_anim_dag_flush_update(C); + WM_event_add_notifier(C, NC_SCENE, scene); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Make Duplicates Real"; + ot->description = "Make dupli objects attached to this object real."; + ot->idname= "OBJECT_OT_duplicates_make_real"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= object_duplicates_make_real_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/**************************** Convert **************************/ + +static EnumPropertyItem convert_target_items[]= { + {OB_CURVE, "CURVE", 0, "Curve", ""}, + {OB_MESH, "MESH", 0, "Mesh", ""}, + {0, NULL, 0, NULL, NULL}}; + +static void curvetomesh(Scene *scene, Object *ob) +{ + Curve *cu= ob->data; + + if(cu->disp.first==0) + makeDispListCurveTypes(scene, ob, 0); /* force creation */ + + nurbs_to_mesh(ob); /* also does users */ + + if(ob->type == OB_MESH) + object_free_modifiers(ob); +} + +static int convert_poll(bContext *C) +{ + Object *obact= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); + + return (!scene->id.lib && obact && scene->obedit != obact && (obact->flag & SELECT)); +} + +static int convert_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Base *basen=NULL, *basact, *basedel=NULL; + Object *ob, *ob1, *obact= CTX_data_active_object(C); + DerivedMesh *dm; + Curve *cu; + Nurb *nu; + MetaBall *mb; + Mesh *me; + int target= RNA_enum_get(op->ptr, "target"); + int keep_original= RNA_boolean_get(op->ptr, "keep_original"); + int a; + + /* don't forget multiple users! */ + + /* reset flags */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob= base->object; + ob->flag &= ~OB_DONE; + } + CTX_DATA_END; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob= base->object; + + if(ob->flag & OB_DONE) + continue; + else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ + ob->flag |= OB_DONE; + basedel = base; + + ob1= copy_object(ob); + ob1->recalc |= OB_RECALC; + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ + basen->object= ob1; + basen->flag |= SELECT; + base->flag &= ~SELECT; + ob->flag &= ~SELECT; + + /* decrement original mesh's usage count */ + me= ob1->data; + me->id.us--; + + /* make a new copy of the mesh */ + ob1->data= copy_mesh(me); + + /* make new mesh data from the original copy */ + dm= mesh_get_derived_final(scene, ob1, CD_MASK_MESH); + /* dm= mesh_create_derived_no_deform(ob1, NULL); this was called original (instead of get_derived). man o man why! (ton) */ + + DM_to_mesh(dm, ob1->data); + + dm->release(dm); + object_free_modifiers(ob1); /* after derivedmesh calls! */ + } + else if(ob->type==OB_FONT) { + ob->flag |= OB_DONE; + + ob->type= OB_CURVE; + cu= ob->data; + + if(cu->vfont) { + cu->vfont->id.us--; + cu->vfont= 0; + } + if(cu->vfontb) { + cu->vfontb->id.us--; + cu->vfontb= 0; + } + if(cu->vfonti) { + cu->vfonti->id.us--; + cu->vfonti= 0; + } + if(cu->vfontbi) { + cu->vfontbi->id.us--; + cu->vfontbi= 0; + } + /* other users */ + if(cu->id.us>1) { + for(ob1= G.main->object.first; ob1; ob1=ob1->id.next) { + if(ob1->data==cu) { + ob1->type= OB_CURVE; + ob1->recalc |= OB_RECALC; + } + } + } + + for(nu=cu->nurb.first; nu; nu=nu->next) + nu->charidx= 0; + + if(target == OB_MESH) + curvetomesh(scene, ob); + } + else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + ob->flag |= OB_DONE; + + if(target == OB_MESH) + curvetomesh(scene, ob); + } + else if(ob->type==OB_MBALL) { + ob= find_basis_mball(scene, ob); + + if(ob->disp.first && !(ob->flag & OB_DONE)) { + ob->flag |= OB_DONE; + basedel = base; + + ob1= copy_object(ob); + ob1->recalc |= OB_RECALC; + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ + basen->object= ob1; + basen->flag |= SELECT; + basedel->flag &= ~SELECT; + ob->flag &= ~SELECT; + + mb= ob1->data; + mb->id.us--; + + ob1->data= add_mesh("Mesh"); + ob1->type= OB_MESH; + + me= ob1->data; + me->totcol= mb->totcol; + if(ob1->totcol) { + me->mat= MEM_dupallocN(mb->mat); + for(a=0; atotcol; a++) id_us_plus((ID *)me->mat[a]); + } + + mball_to_mesh(&ob->disp, ob1->data); + + /* So we can see the wireframe */ + BASACT= basen; // XXX hm + } + else + continue; + } + else + continue; + + /* If the original object is active then make this object active */ + if(basen) { + if(ob == obact) { + ED_base_object_activate(C, basen); + basact = basen; + } + + basen= NULL; + } + + /* delete original if needed */ + if(basedel) { + if(!keep_original) + ED_base_object_free_and_unlink(scene, basedel); + + basedel = NULL; + } + } + CTX_DATA_END; + + /* delete object should renew depsgraph */ + if(!keep_original) + DAG_scene_sort(scene); + + /* texspace and normals */ + if(!basen) BASACT= NULL; // XXX base; + +// XXX ED_object_enter_editmode(C, 0); +// XXX exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ + BASACT= basact; + + DAG_scene_sort(scene); + WM_event_add_notifier(C, NC_SCENE, scene); + + return OPERATOR_FINISHED; +} + +static int convert_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Object *obact= CTX_data_active_object(C); + uiPopupMenu *pup; + uiLayout *layout; + char *title; + + if(obact->type==OB_FONT) { + pup= uiPupMenuBegin(C, "Convert Font to", 0); + layout= uiPupMenuLayout(pup); + + uiItemEnumO(layout, "Curve", 0, op->type->idname, "target", OB_CURVE); + } + else { + if(obact->type == OB_MBALL) + title= "Convert Metaball to"; + else if(obact->type == OB_CURVE) + title= "Convert Curve to"; + else if(obact->type == OB_SURF) + title= "Convert Nurbs Surface to"; + else if(obact->type == OB_MESH) + title= "Convert Modifiers to"; + else + return OPERATOR_CANCELLED; + + pup= uiPupMenuBegin(C, title, 0); + layout= uiPupMenuLayout(pup); + } + + uiItemBooleanO(layout, "Mesh (keep original)", 0, op->type->idname, "keep_original", 1); + uiItemBooleanO(layout, "Mesh (delete original)", 0, op->type->idname, "keep_original", 0); + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_convert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Convert"; + ot->description = "Convert selected objects to another type."; + ot->idname= "OBJECT_OT_convert"; + + /* api callbacks */ + ot->invoke= convert_invoke; + ot->exec= convert_exec; + ot->poll= convert_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to."); + RNA_def_boolean(ot->srna, "keep_original", 0, "Keep Original", "Keep original objects instead of replacing them."); +} + +/************************** Add Duplicate **********************/ + +/* + dupflag: a flag made from constants declared in DNA_userdef_types.h + The flag tells adduplicate() weather to copy data linked to the object, or to reference the existing data. + U.dupflag for default operations or you can construct a flag as python does + if the dupflag is 0 then no data will be copied (linked duplicate) */ + +/* used below, assumes id.new is correct */ +/* leaves selection of base/object unaltered */ +static Base *object_add_duplicate_internal(Scene *scene, Base *base, int dupflag) +{ + Base *basen= NULL; + Material ***matarar; + Object *ob, *obn; + ID *id; + int a, didit; + + ob= base->object; + if(ob->mode & OB_MODE_POSE) { + ; /* nothing? */ + } + else { + obn= copy_object(ob); + obn->recalc |= OB_RECALC; + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ + basen->object= obn; + + if(basen->flag & OB_FROMGROUP) { + Group *group; + for(group= G.main->group.first; group; group= group->id.next) { + if(object_in_group(ob, group)) + add_to_group(group, obn); + } + obn->flag |= OB_FROMGROUP; /* this flag is unset with copy_object() */ + } + + /* duplicates using userflags */ +#if 0 // XXX old animation system + if(dupflag & USER_DUP_IPO) { + bConstraintChannel *chan; + id= (ID *)obn->ipo; + + if(id) { + ID_NEW_US( obn->ipo) + else obn->ipo= copy_ipo(obn->ipo); + id->us--; + } + /* Handle constraint ipos */ + for (chan=obn->constraintChannels.first; chan; chan=chan->next){ + id= (ID *)chan->ipo; + if(id) { + ID_NEW_US( chan->ipo) + else chan->ipo= copy_ipo(chan->ipo); + id->us--; + } + } + } + if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */ + id= (ID *)obn->action; + if (id){ + ID_NEW_US(obn->action) + else{ + obn->action= copy_action(obn->action); + } + id->us--; + } + } +#endif // XXX old animation system + if(dupflag & USER_DUP_MAT) { + for(a=0; atotcol; a++) { + id= (ID *)obn->mat[a]; + if(id) { + ID_NEW_US(obn->mat[a]) + else obn->mat[a]= copy_material(obn->mat[a]); + id->us--; + } + } + } + if(dupflag & USER_DUP_PSYS) { + ParticleSystem *psys; + for(psys=obn->particlesystem.first; psys; psys=psys->next) { + id= (ID*) psys->part; + if(id) { + ID_NEW_US(psys->part) + else psys->part= psys_copy_settings(psys->part); + id->us--; + } + } + } + + id= obn->data; + didit= 0; + + switch(obn->type) { + case OB_MESH: + if(dupflag & USER_DUP_MESH) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_mesh(obn->data); + + if(obn->fluidsimSettings) { + obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; + } + + didit= 1; + } + id->us--; + } + break; + case OB_CURVE: + if(dupflag & USER_DUP_CURVE) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_curve(obn->data); + didit= 1; + } + id->us--; + } + break; + case OB_SURF: + if(dupflag & USER_DUP_SURF) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_curve(obn->data); + didit= 1; + } + id->us--; + } + break; + case OB_FONT: + if(dupflag & USER_DUP_FONT) { + ID_NEW_US2( obn->data ) + else { + obn->data= copy_curve(obn->data); + didit= 1; + } + id->us--; + } + break; + case OB_MBALL: + if(dupflag & USER_DUP_MBALL) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_mball(obn->data); + didit= 1; + } + id->us--; + } + break; + case OB_LAMP: + if(dupflag & USER_DUP_LAMP) { + ID_NEW_US2(obn->data ) + else obn->data= copy_lamp(obn->data); + id->us--; + } + break; + + case OB_ARMATURE: + obn->recalc |= OB_RECALC_DATA; + if(obn->pose) obn->pose->flag |= POSE_RECALC; + + if(dupflag & USER_DUP_ARM) { + ID_NEW_US2(obn->data ) + else { + obn->data= copy_armature(obn->data); + armature_rebuild_pose(obn, obn->data); + didit= 1; + } + id->us--; + } + + break; + + case OB_LATTICE: + if(dupflag!=0) { + ID_NEW_US2(obn->data ) + else obn->data= copy_lattice(obn->data); + id->us--; + } + break; + case OB_CAMERA: + if(dupflag!=0) { + ID_NEW_US2(obn->data ) + else obn->data= copy_camera(obn->data); + id->us--; + } + break; + } + + if(dupflag & USER_DUP_MAT) { + matarar= give_matarar(obn); + if(didit && matarar) { + for(a=0; atotcol; a++) { + id= (ID *)(*matarar)[a]; + if(id) { + ID_NEW_US( (*matarar)[a] ) + else (*matarar)[a]= copy_material((*matarar)[a]); + + id->us--; + } + } + } + } + } + return basen; +} + +/* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */ +/* leaves selection of base/object unaltered */ +Base *ED_object_add_duplicate(Scene *scene, Base *base, int dupflag) +{ + Base *basen; + + clear_id_newpoins(); + clear_sca_new_poins(); /* sensor/contr/act */ + + basen= object_add_duplicate_internal(scene, base, dupflag); + + DAG_scene_sort(scene); + + return basen; +} + +/* contextual operator dupli */ +static int duplicate_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + int linked= RNA_boolean_get(op->ptr, "linked"); + int dupflag= (linked)? 0: U.dupflag; + + clear_id_newpoins(); + clear_sca_new_poins(); /* sensor/contr/act */ + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + Base *basen= object_add_duplicate_internal(scene, base, dupflag); + + /* note that this is safe to do with this context iterator, + the list is made in advance */ + ED_base_object_select(base, BA_DESELECT); + + /* new object becomes active */ + if(BASACT==base) + ED_base_object_activate(C, basen); + + } + CTX_DATA_END; + + copy_object_set_idnew(C, dupflag); + + DAG_scene_sort(scene); + ED_anim_dag_flush_update(C); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Duplicate"; + ot->description = "Duplicate selected objects."; + ot->idname= "OBJECT_OT_duplicate"; + + /* api callbacks */ + ot->exec= duplicate_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* to give to transform */ + RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data."); + RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); +} + +/**************************** Join *************************/ + +static int join_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_active_object(C); + + if(scene->obedit) { + BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode."); + return OPERATOR_CANCELLED; + } + else if(!ob) { + BKE_report(op->reports, RPT_ERROR, "Can't join unless there is an active object."); + return OPERATOR_CANCELLED; + } + else if(object_data_is_libdata(ob)) { + BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata."); + return OPERATOR_CANCELLED; + } + + if(ob->type == OB_MESH) + return join_mesh_exec(C, op); + else if(ELEM(ob->type, OB_CURVE, OB_SURF)) + return join_curve_exec(C, op); + else if(ob->type == OB_ARMATURE) + return join_armature_exec(C, op); + + BKE_report(op->reports, RPT_ERROR, "This object type doesn't support joining."); + + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_join(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Join"; + ot->description = "Join selected objects into active object."; + ot->idname= "OBJECT_OT_join"; + + /* api callbacks */ + ot->exec= join_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c new file mode 100644 index 00000000000..9b073ed5878 --- /dev/null +++ b/source/blender/editors/object/object_constraint.c @@ -0,0 +1,1416 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joshua Leung, Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_dynstr.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_text_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_constraint.h" +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#ifndef DISABLE_PYTHON +#include "BPY_extern.h" +#endif + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" +#include "RNA_types.h" + +#include "ED_object.h" +#include "ED_screen.h" + +#include "UI_interface.h" + +#include "object_intern.h" + +/* -------------- Get Active Constraint Data ---------------------- */ + +/* if object in posemode, active bone constraints, else object constraints */ +ListBase *get_active_constraints (Object *ob) +{ + if (ob == NULL) + return NULL; + + if (ob->mode & OB_MODE_POSE) { + bPoseChannel *pchan; + + pchan = get_active_posechannel(ob); + if (pchan) + return &pchan->constraints; + } + else + return &ob->constraints; + + return NULL; +} + +/* single constraint */ +bConstraint *get_active_constraint (Object *ob) +{ + ListBase *lb= get_active_constraints(ob); + + if (lb) { + bConstraint *con; + + for (con= lb->first; con; con=con->next) { + if (con->flag & CONSTRAINT_ACTIVE) + return con; + } + } + + return NULL; +} +/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */ +/* ------------- PyConstraints ------------------ */ + +/* this callback sets the text-file to be used for selected menu item */ +void validate_pyconstraint_cb (void *arg1, void *arg2) +{ + bPythonConstraint *data = arg1; + Text *text= NULL; + int index = *((int *)arg2); + int i; + + /* exception for no script */ + if (index) { + /* innovative use of a for...loop to search */ + for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next); + } + data->text = text; +} + +#ifndef DISABLE_PYTHON +/* this returns a string for the list of usable pyconstraint script names */ +char *buildmenu_pyconstraints (Text *con_text, int *pyconindex) +{ + DynStr *pupds= BLI_dynstr_new(); + Text *text; + char *str; + char buf[64]; + int i; + + /* add title first */ + sprintf(buf, "Scripts: %%t|[None]%%x0|"); + BLI_dynstr_append(pupds, buf); + + /* init active-index first */ + if (con_text == NULL) + *pyconindex= 0; + + /* loop through markers, adding them */ + for (text=G.main->text.first, i=1; text; i++, text=text->id.next) { + /* this is important to ensure that right script is shown as active */ + if (text == con_text) *pyconindex = i; + + /* only include valid pyconstraint scripts */ + if (BPY_is_pyconstraint(text)) { + BLI_dynstr_append(pupds, text->id.name+2); + + sprintf(buf, "%%x%d", i); + BLI_dynstr_append(pupds, buf); + + if (text->id.next) + BLI_dynstr_append(pupds, "|"); + } + } + + /* convert to normal MEM_malloc'd string */ + str= BLI_dynstr_get_cstring(pupds); + BLI_dynstr_free(pupds); + + return str; +} +#endif /* DISABLE_PYTHON */ + +/* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */ +void update_pyconstraint_cb (void *arg1, void *arg2) +{ + Object *owner= (Object *)arg1; + bConstraint *con= (bConstraint *)arg2; +#ifndef DISABLE_PYTHON + if (owner && con) + BPY_pyconstraint_update(owner, con); +#endif +} + +/* Creates a new constraint, initialises its data, and returns it */ +bConstraint *add_new_constraint (short type) +{ + bConstraint *con; + bConstraintTypeInfo *cti; + + con = MEM_callocN(sizeof(bConstraint), "Constraint"); + + /* Set up a generic constraint datablock */ + con->type = type; + con->flag |= CONSTRAINT_EXPAND; + con->enforce = 1.0f; + + /* Load the data for it */ + cti = constraint_get_typeinfo(con); + if (cti) { + con->data = MEM_callocN(cti->size, cti->structName); + + /* only constraints that change any settings need this */ + if (cti->new_data) + cti->new_data(con->data); + + /* set the name based on the type of constraint */ + strcpy(con->name, cti->name); + } + else + strcpy(con->name, "Const"); + + return con; +} + +/* Adds the given constraint to the Object-level set of constraints for the given Object */ +void add_constraint_to_object (bConstraint *con, Object *ob) +{ + ListBase *list; + list = &ob->constraints; + + if (list) { + unique_constraint_name(con, list); + BLI_addtail(list, con); + + if (proxylocked_constraints_owner(ob, NULL)) + con->flag |= CONSTRAINT_PROXY_LOCAL; + + con->flag |= CONSTRAINT_ACTIVE; + for (con= con->prev; con; con= con->prev) + con->flag &= ~CONSTRAINT_ACTIVE; + } +} + +/* helper function for add_constriant - sets the last target for the active constraint */ +static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index) +{ + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + ListBase targets = {NULL, NULL}; + bConstraintTarget *ct; + int num_targets, i; + + if (cti && cti->get_constraint_targets) { + cti->get_constraint_targets(con, &targets); + num_targets= BLI_countlist(&targets); + + if (index < 0) { + if (abs(index) < num_targets) + index= num_targets - abs(index); + else + index= num_targets - 1; + } + else if (index >= num_targets) { + index= num_targets - 1; + } + + for (ct=targets.first, i=0; ct; ct= ct->next, i++) { + if (i == index) { + ct->tar= target; + strcpy(ct->subtarget, subtarget); + break; + } + } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(con, &targets, 0); + } +} + +/* ------------- Constraint Sanity Testing ------------------- */ + +/* checks validity of object pointers, and NULLs, + * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag + */ +static void test_constraints (Object *owner, const char substring[]) +{ + bConstraint *curcon; + ListBase *conlist= NULL; + int type; + + if (owner==NULL) return; + + /* Check parents */ + if (strlen(substring)) { + switch (owner->type) { + case OB_ARMATURE: + type = CONSTRAINT_OBTYPE_BONE; + break; + default: + type = CONSTRAINT_OBTYPE_OBJECT; + break; + } + } + else + type = CONSTRAINT_OBTYPE_OBJECT; + + /* Get the constraint list for this object */ + switch (type) { + case CONSTRAINT_OBTYPE_OBJECT: + conlist = &owner->constraints; + break; + case CONSTRAINT_OBTYPE_BONE: + { + Bone *bone; + bPoseChannel *chan; + + bone = get_named_bone( ((bArmature *)owner->data), substring ); + chan = get_pose_channel(owner->pose, substring); + if (bone && chan) { + conlist = &chan->constraints; + } + } + break; + } + + /* Check all constraints - is constraint valid? */ + if (conlist) { + for (curcon = conlist->first; curcon; curcon=curcon->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon); + ListBase targets = {NULL, NULL}; + bConstraintTarget *ct; + + /* clear disabled-flag first */ + curcon->flag &= ~CONSTRAINT_DISABLE; + + if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) { + bKinematicConstraint *data = curcon->data; + + /* bad: we need a separate set of checks here as poletarget is + * optional... otherwise poletarget must exist too or else + * the constraint is deemed invalid + */ + if (exist_object(data->tar) == 0) { + data->tar = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (data->tar == owner) { + if (!get_named_bone(get_armature(owner), data->subtarget)) { + curcon->flag |= CONSTRAINT_DISABLE; + } + } + + if (data->poletar) { + if (exist_object(data->poletar) == 0) { + data->poletar = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (data->poletar == owner) { + if (!get_named_bone(get_armature(owner), data->polesubtarget)) { + curcon->flag |= CONSTRAINT_DISABLE; + } + } + } + + /* targets have already been checked for this */ + continue; + } + else if (curcon->type == CONSTRAINT_TYPE_ACTION) { + bActionConstraint *data = curcon->data; + + /* validate action */ + if (data->act == NULL) + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) { + bFollowPathConstraint *data = curcon->data; + + /* don't allow track/up axes to be the same */ + if (data->upflag==data->trackflag) + curcon->flag |= CONSTRAINT_DISABLE; + if (data->upflag+3==data->trackflag) + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) { + bTrackToConstraint *data = curcon->data; + + /* don't allow track/up axes to be the same */ + if (data->reserved2==data->reserved1) + curcon->flag |= CONSTRAINT_DISABLE; + if (data->reserved2+3==data->reserved1) + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) { + bLockTrackConstraint *data = curcon->data; + + if (data->lockflag==data->trackflag) + curcon->flag |= CONSTRAINT_DISABLE; + if (data->lockflag+3==data->trackflag) + curcon->flag |= CONSTRAINT_DISABLE; + } + + /* Check targets for constraints */ + if (cti && cti->get_constraint_targets) { + cti->get_constraint_targets(curcon, &targets); + + /* disable and clear constraints targets that are incorrect */ + for (ct= targets.first; ct; ct= ct->next) { + /* general validity checks (for those constraints that need this) */ + if (exist_object(ct->tar) == 0) { + ct->tar = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + } + else if (ct->tar == owner) { + if (!get_named_bone(get_armature(owner), ct->subtarget)) { + curcon->flag |= CONSTRAINT_DISABLE; + } + } + + /* target checks for specific constraints */ + if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) { + if (ct->tar) { + if (ct->tar->type != OB_CURVE) { + ct->tar= NULL; + curcon->flag |= CONSTRAINT_DISABLE; + } + else { + Curve *cu= ct->tar->data; + + /* auto-set 'Path' setting on curve so this works */ + cu->flag |= CU_PATH; + } + } + } + } + + /* free any temporary targets */ + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(curcon, &targets, 0); + } + } + } +} + +static void test_bonelist_constraints (Object *owner, ListBase *list) +{ + Bone *bone; + + for (bone = list->first; bone; bone = bone->next) { + test_constraints(owner, bone->name); + test_bonelist_constraints(owner, &bone->childbase); + } +} + +void object_test_constraints (Object *owner) +{ + test_constraints(owner, ""); + + if (owner->type==OB_ARMATURE) { + bArmature *arm= get_armature(owner); + + if (arm) + test_bonelist_constraints(owner, &arm->bonebase); + } +} + +/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */ + +/* ---------- Distance-Dependent Constraints ---------- */ +/* StretchTo, Limit Distance */ + +static int stretchto_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); + return (ptr.id.data && ptr.data); +} + +static int stretchto_reset_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); + + /* just set original length to 0.0, which will cause a reset on next recalc */ + RNA_float_set(&ptr, "original_length", 0.0f); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); + return OPERATOR_FINISHED; +} + +void CONSTRAINT_OT_stretchto_reset (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reset Original Length"; + ot->idname= "CONSTRAINT_OT_stretchto_reset"; + ot->description= "Reset original length of bone for Stretch To Constraint."; + + ot->exec= stretchto_reset_exec; + ot->poll= stretchto_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + + +static int limitdistance_reset_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); + + /* just set distance to 0.0, which will cause a reset on next recalc */ + RNA_float_set(&ptr, "distance", 0.0f); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); + return OPERATOR_FINISHED; +} + +static int limitdistance_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); + return (ptr.id.data && ptr.data); +} + +void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reset Distance"; + ot->idname= "CONSTRAINT_OT_limitdistance_reset"; + ot->description= "Reset limiting distance for Limit Distance Constraint."; + + ot->exec= limitdistance_reset_exec; + ot->poll= limitdistance_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ------------- Child-Of Constraint ------------------ */ + +static int childof_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); + return (ptr.id.data && ptr.data); +} + +/* ChildOf Constraint - set inverse callback */ +static int childof_set_inverse_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); + Scene *scene= CTX_data_scene(C); + Object *ob= ptr.id.data; + bConstraint *con= ptr.data; + bChildOfConstraint *data= (bChildOfConstraint *)con->data; + bPoseChannel *pchan= NULL; + + /* try to find a pose channel */ + // TODO: get from context instead? + if (ob && ob->pose) + pchan= get_active_posechannel(ob); + + /* calculate/set inverse matrix */ + if (pchan) { + float pmat[4][4], cinf; + float imat[4][4], tmat[4][4]; + + /* make copy of pchan's original pose-mat (for use later) */ + Mat4CpyMat4(pmat, pchan->pose_mat); + + /* disable constraint for pose to be solved without it */ + cinf= con->enforce; + con->enforce= 0.0f; + + /* solve pose without constraint */ + where_is_pose(scene, ob); + + /* determine effect of constraint by removing the newly calculated + * pchan->pose_mat from the original pchan->pose_mat, thus determining + * the effect of the constraint + */ + Mat4Invert(imat, pchan->pose_mat); + Mat4MulMat4(tmat, imat, pmat); + Mat4Invert(data->invmat, tmat); + + /* recalculate pose with new inv-mat */ + con->enforce= cinf; + where_is_pose(scene, ob); + } + else if (ob) { + Object workob; + /* use what_does_parent to find inverse - just like for normal parenting. + * NOTE: what_does_parent uses a static workob defined in object.c + */ + what_does_parent(scene, ob, &workob); + Mat4Invert(data->invmat, workob.obmat); + } + else + Mat4One(data->invmat); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; +} + +void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Inverse"; + ot->idname= "CONSTRAINT_OT_childof_set_inverse"; + ot->description= "Set inverse correction for ChildOf constraint."; + + ot->exec= childof_set_inverse_exec; + ot->poll= childof_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ChildOf Constraint - clear inverse callback */ +static int childof_clear_inverse_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); + Object *ob= ptr.id.data; + bConstraint *con= ptr.data; + bChildOfConstraint *data= (bChildOfConstraint *)con->data; + + /* simply clear the matrix */ + Mat4One(data->invmat); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; +} + +void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Inverse"; + ot->idname= "CONSTRAINT_OT_childof_clear_inverse"; + ot->description= "Clear inverse correction for ChildOf constraint."; + + ot->exec= childof_clear_inverse_exec; + ot->poll= childof_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/***************************** BUTTONS ****************************/ + +/* Rename the given constraint, con already has the new name */ +void ED_object_constraint_rename(Object *ob, bConstraint *con, char *oldname) +{ + bConstraint *tcon; + ListBase *conlist= NULL; + int from_object= 0; + + /* get context by searching for con (primitive...) */ + for (tcon= ob->constraints.first; tcon; tcon= tcon->next) { + if (tcon==con) + break; + } + + if (tcon) { + conlist= &ob->constraints; + from_object= 1; + } + else if (ob->pose) { + bPoseChannel *pchan; + + for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { + for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) { + if (tcon==con) + break; + } + if (tcon) + break; + } + + if (tcon) { + conlist= &pchan->constraints; + } + } + + if (conlist==NULL) { + printf("rename constraint failed\n"); /* should not happen in UI */ + return; + } + + /* first make sure it's a unique name within context */ + unique_constraint_name(con, conlist); +} + + + + +void ED_object_constraint_set_active(Object *ob, bConstraint *con) +{ + ListBase *lb; + bConstraint *origcon= con; + + /* lets be nice and escape if its active already */ + if(con && (con->flag & CONSTRAINT_ACTIVE)) + return ; + + lb= get_active_constraints(ob); + if(lb == NULL) + return; + + for(con= lb->first; con; con= con->next) { + if(con==origcon) con->flag |= CONSTRAINT_ACTIVE; + else con->flag &= ~CONSTRAINT_ACTIVE; + } +} + +static int constraint_poll(bContext *C) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); + return (ptr.id.data && ptr.data); +} + +static int constraint_delete_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); + Object *ob= ptr.id.data; + bConstraint *con= ptr.data; + ListBase *lb; + + /* remove constraint itself */ + lb= get_active_constraints(ob); + free_constraint_data(con); + BLI_freelinkN(lb, con); + + ED_object_constraint_set_active(ob, NULL); + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; +} + +void CONSTRAINT_OT_delete (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Constraint"; + ot->idname= "CONSTRAINT_OT_delete"; + ot->description= "Remove constraitn from constraint stack."; + + /* callbacks */ + ot->exec= constraint_delete_exec; + ot->poll= constraint_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int constraint_move_down_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); + Object *ob= ptr.id.data; + bConstraint *con= ptr.data; + + if (con->next) { + ListBase *conlist= get_active_constraints(ob); + bConstraint *nextCon= con->next; + + /* insert the nominated constraint after the one that used to be after it */ + BLI_remlink(conlist, con); + BLI_insertlinkafter(conlist, nextCon, con); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void CONSTRAINT_OT_move_down (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Move Constraint Down"; + ot->idname= "CONSTRAINT_OT_move_down"; + ot->description= "Move constraint down constraint stack."; + + /* callbacks */ + ot->exec= constraint_move_down_exec; + ot->poll= constraint_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + + +static int constraint_move_up_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); + Object *ob= ptr.id.data; + bConstraint *con= ptr.data; + + if (con->prev) { + ListBase *conlist= get_active_constraints(ob); + bConstraint *prevCon= con->prev; + + /* insert the nominated constraint before the one that used to be before it */ + BLI_remlink(conlist, con); + BLI_insertlinkbefore(conlist, prevCon, con); + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void CONSTRAINT_OT_move_up (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Move Constraint Up"; + ot->idname= "CONSTRAINT_OT_move_up"; + ot->description= "Move constraint up constraint stack."; + + /* callbacks */ + ot->exec= constraint_move_up_exec; + ot->poll= constraint_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/***************************** OPERATORS ****************************/ + +/************************ remove constraint operators *********************/ + +static int pose_constraints_clear_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + + /* free constraints for all selected bones */ + CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + { + free_constraints(&pchan->constraints); + } + CTX_DATA_END; + + /* do updates */ + DAG_id_flush_update(&ob->id, OB_RECALC_OB); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob); + + return OPERATOR_FINISHED; +} + +void POSE_OT_constraints_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Constraints"; + ot->idname= "POSE_OT_constraints_clear"; + ot->description= "Clear all the constraints for the selected bones."; + + /* callbacks */ + ot->exec= pose_constraints_clear_exec; + ot->poll= ED_operator_posemode; // XXX - do we want to ensure there are selected bones too? +} + + +static int object_constraints_clear_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + + /* do freeing */ + // TODO: we should free constraints for all selected objects instead (to be more consistent with bones) + free_constraints(&ob->constraints); + + /* do updates */ + DAG_id_flush_update(&ob->id, OB_RECALC_OB); + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_constraints_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Constraints"; + ot->idname= "OBJECT_OT_constraints_clear"; + ot->description= "Clear all the constraints for the active Object only."; + + /* callbacks */ + ot->exec= object_constraints_clear_exec; + ot->poll= ED_operator_object_active; +} + +/************************ add constraint operators *********************/ + +/* get the Object and/or PoseChannel to use as target */ +static short get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, short add) +{ + Object *obact= CTX_data_active_object(C); + bPoseChannel *pchanact= get_active_posechannel(obact); + short only_curve= 0, only_mesh= 0, only_ob= 0; + short found= 0; + + /* clear tar_ob and tar_pchan fields before use + * - assume for now that both always exist... + */ + *tar_ob= NULL; + *tar_pchan= NULL; + + /* check if constraint type doesn't requires a target + * - if so, no need to get any targets + */ + switch (con_type) { + /* no-target constraints --------------------------- */ + /* null constraint - shouldn't even be added! */ + case CONSTRAINT_TYPE_NULL: + /* limit constraints - no targets needed */ + case CONSTRAINT_TYPE_LOCLIMIT: + case CONSTRAINT_TYPE_ROTLIMIT: + case CONSTRAINT_TYPE_SIZELIMIT: + return 0; + + /* restricted target-type constraints -------------- */ + /* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */ + /* curve-based constraints - set the only_curve and only_ob flags */ + case CONSTRAINT_TYPE_TRACKTO: + case CONSTRAINT_TYPE_CLAMPTO: + case CONSTRAINT_TYPE_FOLLOWPATH: + only_curve= 1; + only_ob= 1; + add= 0; + break; + + /* mesh only? */ + case CONSTRAINT_TYPE_SHRINKWRAP: + only_mesh= 1; + only_ob= 1; + add= 0; + break; + + /* object only - add here is ok? */ + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + only_ob= 1; + break; + } + + /* if the active Object is Armature, and we can search for bones, do so... */ + if ((obact->type == OB_ARMATURE) && (only_ob == 0)) { + /* search in list of selected Pose-Channels for target */ + CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + { + /* just use the first one that we encounter, as long as it is not the active one */ + if (pchan != pchanact) { + *tar_ob= obact; + *tar_pchan= pchan; + found= 1; + + break; + } + } + CTX_DATA_END; + } + + /* if not yet found, try selected Objects... */ + if (found == 0) { + /* search in selected objects context */ + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) + { + /* just use the first object we encounter (that isn't the active object) + * and which fulfills the criteria for the object-target that we've got + */ + if ( (ob != obact) && + ((!only_curve) || (ob->type == OB_CURVE)) && + ((!only_mesh) || (ob->type == OB_MESH)) ) + { + /* set target */ + *tar_ob= ob; + found= 1; + + /* perform some special operations on the target */ + if (only_curve) { + /* Curve-Path option must be enabled for follow-path constraints to be able to work */ + Curve *cu= (Curve *)ob->data; + cu->flag |= CU_PATH; + } + + break; + } + } + CTX_DATA_END; + } + + /* if still not found, add a new empty to act as a target (if allowed) */ + if ((found == 0) && (add)) { + Scene *scene= CTX_data_scene(C); + Base *base= BASACT, *newbase=NULL; + Object *obt; + + /* add new target object */ + obt= add_object(scene, OB_EMPTY); + + /* set layers OK */ + newbase= BASACT; + newbase->lay= base->lay; + obt->lay= newbase->lay; + + /* transform cent to global coords for loc */ + if (pchanact) { + /* since by default, IK targets the tip of the last bone, use the tip of the active PoseChannel + * if adding a target for an IK Constraint + */ + if (con_type == CONSTRAINT_TYPE_KINEMATIC) + VecMat4MulVecfl(obt->loc, obact->obmat, pchanact->pose_tail); + else + VecMat4MulVecfl(obt->loc, obact->obmat, pchanact->pose_head); + } + else + VECCOPY(obt->loc, obact->obmat[3]); + + /* restore, add_object sets active */ + BASACT= base; + base->flag |= SELECT; + + /* make our new target the new object */ + *tar_ob= obt; + found= 1; + } + + /* return whether there's any target */ + return found; +} + +/* used by add constraint operators to add the constraint required */ +static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, short setTarget) +{ + Scene *scene= CTX_data_scene(C); + bPoseChannel *pchan= get_active_posechannel(ob); + bConstraint *con; + + /* check if constraint to be added is valid for the given constraints stack */ + if (type == CONSTRAINT_TYPE_NULL) { + return OPERATOR_CANCELLED; + } + if ( (type == CONSTRAINT_TYPE_RIGIDBODYJOINT) && (list != &ob->constraints) ) { + BKE_report(op->reports, RPT_ERROR, "Rigid Body Joint Constraint can only be added to Objects."); + return OPERATOR_CANCELLED; + } + if ( (type == CONSTRAINT_TYPE_KINEMATIC) && ((!pchan) || (list != &pchan->constraints)) ) { + BKE_report(op->reports, RPT_ERROR, "IK Constraint can only be added to Bones."); + return OPERATOR_CANCELLED; + } + + /* create a new constraint of the type requried, and add it to the active/given constraints list */ + con = add_new_constraint(type); + + if (list) { + bConstraint *coniter; + + /* add new constraint to end of list of constraints before ensuring that it has a unique name + * (otherwise unique-naming code will fail, since it assumes element exists in list) + */ + BLI_addtail(list, con); + unique_constraint_name(con, list); + + /* if the target list is a list on some PoseChannel belonging to a proxy-protected + * Armature layer, we must tag newly added constraints with a flag which allows them + * to persist after proxy syncing has been done + */ + if (proxylocked_constraints_owner(ob, pchan)) + con->flag |= CONSTRAINT_PROXY_LOCAL; + + /* make this constraint the active one + * - since constraint was added at end of stack, we can just go + * through deactivating all previous ones + */ + con->flag |= CONSTRAINT_ACTIVE; + for (coniter= con->prev; coniter; coniter= coniter->prev) + coniter->flag &= ~CONSTRAINT_ACTIVE; + } + + /* get the first selected object/bone, and make that the target + * - apart from the buttons-window add buttons, we shouldn't add in this way + */ + if (setTarget) { + Object *tar_ob= NULL; + bPoseChannel *tar_pchan= NULL; + + /* get the target objects, adding them as need be */ + if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) { + /* method of setting target depends on the type of target we've got + * - by default, just set the first target (distinction here is only for multiple-targetted constraints) + */ + if (tar_pchan) + set_constraint_nth_target(con, tar_ob, tar_pchan->name, 0); + else + set_constraint_nth_target(con, tar_ob, "", 0); + } + } + + /* do type-specific tweaking to the constraint settings */ + switch (type) { + case CONSTRAINT_TYPE_CHILDOF: + { + /* if this constraint is being added to a posechannel, make sure + * the constraint gets evaluated in pose-space */ + if (ob->mode & OB_MODE_POSE) { + con->ownspace = CONSTRAINT_SPACE_POSE; + con->flag |= CONSTRAINT_SPACEONCE; + } + } + break; + + case CONSTRAINT_TYPE_PYTHON: // FIXME: this code is not really valid anymore + { + char *menustr; + int scriptint= 0; +#ifndef DISABLE_PYTHON + /* popup a list of usable scripts */ + menustr = buildmenu_pyconstraints(NULL, &scriptint); + // XXX scriptint = pupmenu(menustr); + MEM_freeN(menustr); + + /* only add constraint if a script was chosen */ + if (scriptint) { + /* add constraint */ + validate_pyconstraint_cb(con->data, &scriptint); + + /* make sure target allowance is set correctly */ + BPY_pyconstraint_update(ob, con); + } +#endif + } + default: + break; + } + + /* make sure all settings are valid - similar to above checks, but sometimes can be wrong */ + object_test_constraints(ob); + + if (ob->pose) + update_pose_constraint_flags(ob->pose); + + + /* force depsgraph to get recalculated since new relationships added */ + DAG_scene_sort(scene); /* sort order of objects */ + + if ((ob->type==OB_ARMATURE) && (pchan)) { + ob->pose->flag |= POSE_RECALC; /* sort pose channels */ + DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB); + } + else + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + + /* notifiers for updates */ + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, ob); + + return OPERATOR_FINISHED; +} + +/* ------------------ */ + +/* dummy operator callback */ +static int object_constraint_add_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa= CTX_wm_area(C); + Object *ob; + int type= RNA_enum_get(op->ptr, "type"); + short with_targets= 0; + + /* get active object from context */ + if (sa->spacetype == SPACE_BUTS) + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + else + ob= CTX_data_active_object(C); + + if (!ob) { + BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to."); + return OPERATOR_CANCELLED; + } + + /* hack: set constraint targets from selected objects in context is allowed when + * operator name included 'with_targets', since the menu doesn't allow multiple properties + */ + if (strstr(op->idname, "with_targets")) + with_targets= 1; + + return constraint_add_exec(C, op, ob, &ob->constraints, type, with_targets); +} + +/* dummy operator callback */ +static int pose_constraint_add_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa= CTX_wm_area(C); + Object *ob; + int type= RNA_enum_get(op->ptr, "type"); + short with_targets= 0; + + /* get active object from context */ + if (sa->spacetype == SPACE_BUTS) + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + else + ob= CTX_data_active_object(C); + + if (!ob) { + BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to."); + return OPERATOR_CANCELLED; + } + + /* hack: set constraint targets from selected objects in context is allowed when + * operator name included 'with_targets', since the menu doesn't allow multiple properties + */ + if (strstr(op->idname, "with_targets")) + with_targets= 1; + + return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets); +} + +/* ------------------ */ + +void OBJECT_OT_constraint_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Constraint"; + ot->description = "Add a constraint to the active object."; + ot->idname= "OBJECT_OT_constraint_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_constraint_add_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); +} + +void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Constraint (with Targets)"; + ot->description = "Add a constraint to the active object, with target (where applicable) set to the selected Objects/Bones."; + ot->idname= "OBJECT_OT_constraint_add_with_targets"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_constraint_add_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); +} + +void POSE_OT_constraint_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Constraint"; + ot->description = "Add a constraint to the active bone."; + ot->idname= "POSE_OT_constraint_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= pose_constraint_add_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); +} + +void POSE_OT_constraint_add_with_targets(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Constraint (with Targets)"; + ot->description = "Add a constraint to the active bone, with target (where applicable) set to the selected Objects/Bones."; + ot->idname= "POSE_OT_constraint_add_with_targets"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= pose_constraint_add_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", ""); +} + +/************************ IK Constraint operators *********************/ +/* NOTE: only for Pose-Channels */ +// TODO: should these be here, or back in editors/armature/poseobject.c again? + +/* present menu with options + validation for targets to use */ +static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *evt) +{ + Object *ob= CTX_data_active_object(C); + bPoseChannel *pchan= get_active_posechannel(ob); + bConstraint *con= NULL; + + uiPopupMenu *pup; + uiLayout *layout; + Object *tar_ob= NULL; + bPoseChannel *tar_pchan= NULL; + + /* must have active bone */ + if (ELEM(NULL, ob, pchan)) { + BKE_report(op->reports, RPT_ERROR, "Must have active bone to add IK Constraint to."); + return OPERATOR_CANCELLED; + } + + /* bone must not have any constraints already */ + for (con= pchan->constraints.first; con; con= con->next) { + if (con->type==CONSTRAINT_TYPE_KINEMATIC) break; + } + if (con) { + BKE_report(op->reports, RPT_ERROR, "Bone already has IK Constraint."); + return OPERATOR_CANCELLED; + } + + /* prepare popup menu to choose targetting options */ + pup= uiPupMenuBegin(C, "Add IK", 0); + layout= uiPupMenuLayout(pup); + + /* the type of targets we'll set determines the menu entries to show... */ + if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) { + /* bone target, or object target? + * - the only thing that matters is that we want a target... + */ + if (tar_pchan) + uiItemBooleanO(layout, "To Active Bone", 0, "POSE_OT_ik_add", "with_targets", 1); + else + uiItemBooleanO(layout, "To Active Object", 0, "POSE_OT_ik_add", "with_targets", 1); + } + else { + /* we have a choice of adding to a new empty, or not setting any target (targetless IK) */ + uiItemBooleanO(layout, "To New Empty Object", 0, "POSE_OT_ik_add", "with_targets", 1); + uiItemBooleanO(layout, "Without Targets", 0, "POSE_OT_ik_add", "with_targets", 0); + } + + /* finish building the menu, and process it (should result in calling self again) */ + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + +/* call constraint_add_exec() to add the IK constraint */ +static int pose_ik_add_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + int with_targets= RNA_boolean_get(op->ptr, "with_targets"); + + /* add the constraint - all necessary checks should have been done by the invoke() callback already... */ + return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets); +} + +void POSE_OT_ik_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add IK to Bone"; + ot->description= "Add IK Constraint to the active Bone."; + ot->idname= "POSE_OT_ik_add"; + + /* api callbacks */ + ot->invoke= pose_ik_add_invoke; + ot->exec= pose_ik_add_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "with_targets", 1, "With Targets", "Assign IK Constraint with targets derived from the select bones/objects"); +} + +/* ------------------ */ + +/* remove IK constraints from selected bones */ +static int pose_ik_clear_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + + /* only remove IK Constraints */ + CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + { + bConstraint *con, *next; + + // TODO: should we be checking if these contraints were local before we try and remove them? + for (con= pchan->constraints.first; con; con= next) { + next= con->next; + if (con->type==CONSTRAINT_TYPE_KINEMATIC) { + free_constraint_data(con); + BLI_freelinkN(&pchan->constraints, con); + } + } + pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET); + } + CTX_DATA_END; + + /* */ + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + + /* note, notifier might evolve */ + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); + + return OPERATOR_FINISHED; +} + +void POSE_OT_ik_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove IK"; + ot->description= "Remove all IK Constraints from selected bones."; + ot->idname= "POSE_OT_ik_clear"; + + /* api callbacks */ + ot->exec= pose_ik_clear_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 31a604a79df..daa63da03db 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -145,8 +145,6 @@ static void error() {} static void waitcursor(int val) {} static int pupmenu(const char *msg) {return 0;} -static int pupmenu_col(const char *msg, int val) {return 0;} -static int okee(const char *msg) {return 0;} /* port over here */ static bContext *C; @@ -156,6636 +154,1433 @@ static void error_libdata() {} /* --------------------------------- */ -/* simple API for object selection, rather than just using the flag - * this takes into account the 'restrict selection in 3d view' flag. - * deselect works always, the restriction just prevents selection */ - -/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! */ - -void ED_base_object_select(Base *base, short mode) -{ - if (base) { - if (mode==BA_SELECT) { - if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) - if (mode==BA_SELECT) base->flag |= SELECT; - } - else if (mode==BA_DESELECT) { - base->flag &= ~SELECT; - } - base->object->flag= base->flag; - } -} - -/* also to set active NULL */ -void ED_base_object_activate(bContext *C, Base *base) +void ED_object_apply_obmat(Object *ob) { - Scene *scene= CTX_data_scene(C); - Base *tbase; + float mat[3][3], imat[3][3], tmat[3][3]; - /* sets scene->basact */ - BASACT= base; + /* from obmat to loc rot size */ - if(base) { - - /* XXX old signals, remember to handle notifiers now! */ - // select_actionchannel_by_name(base->object->action, "Object", 1); - - /* disable temporal locks */ - for(tbase=FIRSTBASE; tbase; tbase= tbase->next) { - if(base!=tbase && (tbase->object->shapeflag & OB_SHAPE_TEMPLOCK)) { - tbase->object->shapeflag &= ~OB_SHAPE_TEMPLOCK; - DAG_id_flush_update(&tbase->object->id, OB_RECALC_DATA); - } - } - WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); - } - else - WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, NULL); -} + if(ob==NULL) return; + Mat3CpyMat4(mat, ob->obmat); + + VECCOPY(ob->loc, ob->obmat[3]); + Mat3ToEul(mat, ob->rot); + EulToMat3(ob->rot, tmat); -/* exported */ -void ED_object_base_init_from_view(bContext *C, Base *base) -{ - View3D *v3d= CTX_wm_view3d(C); - Scene *scene= CTX_data_scene(C); - Object *ob= base->object; + Mat3Inv(imat, tmat); - if (scene==NULL) - return; + Mat3MulMat3(tmat, imat, mat); + + ob->size[0]= tmat[0][0]; + ob->size[1]= tmat[1][1]; + ob->size[2]= tmat[2][2]; - if (v3d==NULL) { - base->lay = scene->lay; - VECCOPY(ob->loc, scene->cursor); - } - else { - if (v3d->localview) { - base->lay= ob->lay= v3d->layact | v3d->lay; - VECCOPY(ob->loc, v3d->cursor); - } - else { - base->lay= ob->lay= v3d->layact; - VECCOPY(ob->loc, scene->cursor); - } - - if (U.flag & USER_ADD_VIEWALIGNED) { - ARegion *ar= CTX_wm_region(C); - if(ar) { - RegionView3D *rv3d= ar->regiondata; - - rv3d->viewquat[0]= -rv3d->viewquat[0]; - QuatToEul(rv3d->viewquat, ob->rot); - rv3d->viewquat[0]= -rv3d->viewquat[0]; - } - } - } - where_is_object(scene, ob); -} - -/* ******************* add object operator ****************** */ - -static EnumPropertyItem prop_object_types[] = { - {OB_MESH, "MESH", 0, "Mesh", ""}, - {OB_CURVE, "CURVE", 0, "Curve", ""}, - {OB_SURF, "SURFACE", 0, "Surface", ""}, - {OB_MBALL, "META", 0, "Meta", ""}, - {OB_FONT, "TEXT", 0, "Text", ""}, - {0, "", 0, NULL, NULL}, - {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, - {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, - {OB_EMPTY, "EMPTY", 0, "Empty", ""}, - {0, "", 0, NULL, NULL}, - {OB_CAMERA, "CAMERA", 0, "Camera", ""}, - {OB_LAMP, "LAMP", 0, "Lamp", ""}, - {0, NULL, 0, NULL, NULL} -}; - - - -void add_object_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menus, only non-editmode stuff */ -{ - /* keep here to get things compile, remove later */ } -/* for object add primitive operators */ -static Object *object_add_type(bContext *C, int type) +/* ********* clear/set restrict view *********/ +static int object_restrictview_clear_exec(bContext *C, wmOperator *op) { + ScrArea *sa= CTX_wm_area(C); + View3D *v3d= sa->spacedata.first; Scene *scene= CTX_data_scene(C); - Object *ob; - - /* for as long scene has editmode... */ - if (CTX_data_edit_object(C)) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ + Base *base; + int changed = 0; - /* deselects all, sets scene->basact */ - ob= add_object(scene, type); - /* editor level activate, notifiers */ - ED_base_object_activate(C, BASACT); - - /* more editor stuff */ - ED_object_base_init_from_view(C, BASACT); - - DAG_scene_sort(scene); - - return ob; -} + /* XXX need a context loop to handle such cases */ + for(base = FIRSTBASE; base; base=base->next){ + if((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) { + base->flag |= SELECT; + base->object->flag = base->flag; + base->object->restrictflag &= ~OB_RESTRICT_VIEW; + changed = 1; + } + } + if (changed) { + DAG_scene_sort(scene); + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } -/* for object add operator */ -static int object_add_exec(bContext *C, wmOperator *op) -{ - object_add_type(C, RNA_int_get(op->ptr, "type")); - return OPERATOR_FINISHED; } -void OBJECT_OT_object_add(wmOperatorType *ot) +void OBJECT_OT_restrictview_clear(wmOperatorType *ot) { + /* identifiers */ - ot->name= "Add Object"; - ot->description = "Add an object to the scene."; - ot->idname= "OBJECT_OT_object_add"; + ot->name= "Clear Restrict View"; + ot->description = "Reveal the object by setting the restrictview flag."; + ot->idname= "OBJECT_OT_restrictview_clear"; /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_add_exec; - - ot->poll= ED_operator_scene_editable; + ot->exec= object_restrictview_clear_exec; + ot->poll= ED_operator_view3d_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_object_types, 0, "Type", ""); } -/* ***************** add primitives *************** */ -/* ****** work both in and outside editmode ****** */ - -static EnumPropertyItem prop_mesh_types[] = { - {0, "PLANE", ICON_MESH_PLANE, "Plane", ""}, - {1, "CUBE", ICON_MESH_CUBE, "Cube", ""}, - {2, "CIRCLE", ICON_MESH_CIRCLE, "Circle", ""}, - {3, "UVSPHERE", ICON_MESH_UVSPHERE, "UVsphere", ""}, - {4, "ICOSPHERE", ICON_MESH_ICOSPHERE, "Icosphere", ""}, - {5, "CYLINDER", ICON_MESH_TUBE, "Cylinder", ""}, - {6, "CONE", ICON_MESH_CONE, "Cone", ""}, - {0, "", 0, NULL, NULL}, - {7, "GRID", ICON_MESH_GRID, "Grid", ""}, - {8, "MONKEY", ICON_MESH_MONKEY, "Monkey", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int object_add_mesh_exec(bContext *C, wmOperator *op) +static int object_restrictview_set_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - int newob= 0; + Scene *scene= CTX_data_scene(C); + short changed = 0; + int unselected= RNA_boolean_get(op->ptr, "unselected"); - if(obedit==NULL || obedit->type!=OB_MESH) { - object_add_type(C, OB_MESH); - ED_object_enter_editmode(C, EM_DO_UNDO); - newob = 1; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - switch(RNA_enum_get(op->ptr, "type")) { - case 0: - WM_operator_name_call(C, "MESH_OT_primitive_plane_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 1: - WM_operator_name_call(C, "MESH_OT_primitive_cube_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 2: - WM_operator_name_call(C, "MESH_OT_primitive_circle_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 3: - WM_operator_name_call(C, "MESH_OT_primitive_uv_sphere_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 4: - WM_operator_name_call(C, "MESH_OT_primitive_ico_sphere_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 5: - WM_operator_name_call(C, "MESH_OT_primitive_cylinder_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 6: - WM_operator_name_call(C, "MESH_OT_primitive_cone_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 7: - WM_operator_name_call(C, "MESH_OT_primitive_grid_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 8: - WM_operator_name_call(C, "MESH_OT_primitive_monkey_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if(!unselected) { + if (base->flag & SELECT){ + base->flag &= ~SELECT; + base->object->flag = base->flag; + base->object->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (base==BASACT) { + ED_base_object_activate(C, NULL); + } + } + } + else { + if (!(base->flag & SELECT)){ + base->object->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + } + } } - /* userdef */ - if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + CTX_DATA_END; + + if (changed) { + DAG_scene_sort(scene); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - + return OPERATOR_FINISHED; } - -void OBJECT_OT_mesh_add(wmOperatorType *ot) +void OBJECT_OT_restrictview_set(wmOperatorType *ot) { /* identifiers */ - ot->name= "Add Mesh"; - ot->description = "Add a mesh object to the scene."; - ot->idname= "OBJECT_OT_mesh_add"; + ot->name= "Set Restrict View"; + ot->description = "Hide the object by setting the restrictview flag."; + ot->idname= "OBJECT_OT_restrictview_set"; /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_add_mesh_exec; + ot->exec= object_restrictview_set_exec; + ot->poll= ED_operator_view3d_active; - ot->poll= ED_operator_scene_editable; + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - /* flags: no register or undo, this operator calls operators */ - ot->flag= 0; //OPTYPE_REGISTER|OPTYPE_UNDO; + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects."); - RNA_def_enum(ot->srna, "type", prop_mesh_types, 0, "Primitive", ""); } -static EnumPropertyItem prop_curve_types[] = { - {CU_BEZIER|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""}, - {CU_BEZIER|CU_PRIM_CIRCLE, "BEZIER_CIRCLE", ICON_CURVE_BEZCIRCLE, "Bezier Circle", ""}, - {CU_NURBS|CU_PRIM_CURVE, "NURBS_CURVE", ICON_CURVE_NCURVE, "NURBS Curve", ""}, - {CU_NURBS|CU_PRIM_CIRCLE, "NURBS_CIRCLE", ICON_CURVE_NCIRCLE, "NURBS Circle", ""}, - {CU_NURBS|CU_PRIM_PATH, "PATH", ICON_CURVE_PATH, "Path", ""}, - {0, NULL, 0, NULL, NULL} -}; -static int object_add_curve_exec(bContext *C, wmOperator *op) +/* ******************* toggle editmode operator ***************** */ + +void ED_object_exit_editmode(bContext *C, int flag) { + Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - ListBase *editnurb; - Nurb *nu; - int newob= 0; - - if(obedit==NULL || obedit->type!=OB_CURVE) { - object_add_type(C, OB_CURVE); - ED_object_enter_editmode(C, 0); - newob = 1; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + int freedata = flag & EM_FREEDATA; - obedit= CTX_data_edit_object(C); - nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob); - editnurb= curve_get_editcurve(obedit); - BLI_addtail(editnurb, nu); + if(obedit==NULL) return; - /* userdef */ - if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + if(flag & EM_WAITCURSOR) waitcursor(1); + if(obedit->type==OB_MESH) { + Mesh *me= obedit->data; + +// if(EM_texFaceCheck()) + +// if(retopo_mesh_paint_check()) +// retopo_end_okee(); + + if(me->edit_mesh->totvert>MESH_MAX_VERTS) { + error("Too many vertices"); + return; + } + load_editMesh(scene, obedit); + + if(freedata) { + free_editMesh(me->edit_mesh); + MEM_freeN(me->edit_mesh); + me->edit_mesh= NULL; + } + + if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT) + mesh_octree_table(obedit, NULL, NULL, 'e'); + } + else if (obedit->type==OB_ARMATURE) { + ED_armature_from_edit(obedit); + if(freedata) + ED_armature_edit_free(obedit); + } + else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { + load_editNurb(obedit); + if(freedata) free_editNurb(obedit); + } + else if(obedit->type==OB_FONT && freedata) { + load_editText(obedit); + if(freedata) free_editText(obedit); + } + else if(obedit->type==OB_LATTICE) { + load_editLatt(obedit); + if(freedata) free_editLatt(obedit); + } + else if(obedit->type==OB_MBALL) { + load_editMball(obedit); + if(freedata) free_editMball(obedit); } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - -static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - Object *obedit= CTX_data_edit_object(C); - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, op->type->name, 0); - layout= uiPupMenuLayout(pup); - if(!obedit || obedit->type == OB_CURVE) - uiItemsEnumO(layout, op->type->idname, "type"); - else - uiItemsEnumO(layout, "OBJECT_OT_surface_add", "type"); - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} -void OBJECT_OT_curve_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Curve"; - ot->description = "Add a curve object to the scene."; - ot->idname= "OBJECT_OT_curve_add"; - - /* api callbacks */ - ot->invoke= object_add_curve_invoke; - ot->exec= object_add_curve_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_curve_types, 0, "Primitive", ""); -} + /* freedata only 0 now on file saves */ + if(freedata) { + /* for example; displist make is different in editmode */ + scene->obedit= NULL; // XXX for context + + BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH); -static EnumPropertyItem prop_surface_types[]= { - {CU_PRIM_CURVE|CU_NURBS, "NURBS_CURVE", ICON_SURFACE_NCURVE, "NURBS Curve", ""}, - {CU_PRIM_CIRCLE|CU_NURBS, "NURBS_CIRCLE", ICON_SURFACE_NCIRCLE, "NURBS Circle", ""}, - {CU_PRIM_PATCH|CU_NURBS, "NURBS_SURFACE", ICON_SURFACE_NSURFACE, "NURBS Surface", ""}, - {CU_PRIM_TUBE|CU_NURBS, "NURBS_TUBE", ICON_SURFACE_NTUBE, "NURBS Tube", ""}, - {CU_PRIM_SPHERE|CU_NURBS, "NURBS_SPHERE", ICON_SURFACE_NSPHERE, "NURBS Sphere", ""}, - {CU_PRIM_DONUT|CU_NURBS, "NURBS_DONUT", ICON_SURFACE_NDONUT, "NURBS Donut", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int object_add_surface_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - ListBase *editnurb; - Nurb *nu; - int newob= 0; + /* also flush ob recalc, doesn't take much overhead, but used for particles */ + DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); - if(obedit==NULL || obedit->type!=OB_SURF) { - object_add_type(C, OB_SURF); - ED_object_enter_editmode(C, 0); - newob = 1; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + ED_undo_push(C, "Editmode"); - obedit= CTX_data_edit_object(C); - nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob); - editnurb= curve_get_editcurve(obedit); - BLI_addtail(editnurb, nu); + if(flag & EM_WAITCURSOR) waitcursor(0); - /* userdef */ - if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; + + obedit->mode &= ~OB_MODE_EDIT; + ED_object_toggle_modes(C, obedit->restore_mode); } -void OBJECT_OT_surface_add(wmOperatorType *ot) + +void ED_object_enter_editmode(bContext *C, int flag) { - /* identifiers */ - ot->name= "Add Surface"; - ot->description = "Add a surface object to the scene."; - ot->idname= "OBJECT_OT_surface_add"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_add_surface_exec; + Scene *scene= CTX_data_scene(C); + Base *base= CTX_data_active_base(C); + Object *ob; + ScrArea *sa= CTX_wm_area(C); + View3D *v3d= NULL; + int ok= 0; - ot->poll= ED_operator_scene_editable; + if(scene->id.lib) return; + if(base==NULL) return; - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + if(sa && sa->spacetype==SPACE_VIEW3D) + v3d= sa->spacedata.first; - RNA_def_enum(ot->srna, "type", prop_surface_types, 0, "Primitive", ""); -} + if(v3d && (base->lay & v3d->lay)==0) return; + else if(!v3d && (base->lay & scene->lay)==0) return; -static EnumPropertyItem prop_metaball_types[]= { - {MB_BALL, "MBALL_BALL", ICON_META_BALL, "Meta Ball", ""}, - {MB_TUBE, "MBALL_TUBE", ICON_META_TUBE, "Meta Tube", ""}, - {MB_PLANE, "MBALL_PLANE", ICON_META_PLANE, "Meta Plane", ""}, - {MB_CUBE, "MBALL_CUBE", ICON_META_CUBE, "Meta Cube", ""}, - {MB_ELIPSOID, "MBALL_ELLIPSOID", ICON_META_ELLIPSOID, "Meta Ellipsoid", ""}, - {0, NULL, 0, NULL, NULL} -}; + ob = base->object; -static int object_metaball_add_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - MetaBall *mball; - MetaElem *elem; - int newob= 0; - - if(obedit==NULL || obedit->type!=OB_MBALL) { - object_add_type(C, OB_MBALL); - ED_object_enter_editmode(C, 0); - newob = 1; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - obedit= CTX_data_edit_object(C); - elem= (MetaElem*)add_metaball_primitive(C, RNA_enum_get(op->ptr, "type"), newob); - mball= (MetaBall*)obedit->data; - BLI_addtail(mball->editelems, elem); + if(ob==NULL) return; + if(ob->data==NULL) return; - /* userdef */ - if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + if (object_data_is_libdata(ob)) { + error_libdata(); + return; } - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - -static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - Object *obedit= CTX_data_edit_object(C); - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, op->type->name, 0); - layout= uiPupMenuLayout(pup); - if(!obedit || obedit->type == OB_MBALL) - uiItemsEnumO(layout, op->type->idname, "type"); - else - uiItemsEnumO(layout, "OBJECT_OT_metaball_add", "type"); - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -void OBJECT_OT_metaball_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Metaball"; - ot->description= "Add an metaball object to the scene."; - ot->idname= "OBJECT_OT_metaball_add"; + if(flag & EM_WAITCURSOR) waitcursor(1); - /* api callbacks */ - ot->invoke= object_metaball_add_invoke; - ot->exec= object_metaball_add_exec; - ot->poll= ED_operator_scene_editable; + ob->restore_mode = ob->mode; + ED_object_toggle_modes(C, ob->mode); - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_metaball_types, 0, "Primitive", ""); -} -static int object_add_text_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); + ob->mode |= OB_MODE_EDIT; - if(obedit && obedit->type==OB_FONT) - return OPERATOR_CANCELLED; - - object_add_type(C, OB_FONT); - obedit= CTX_data_active_object(C); + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + + if(me->pv) mesh_pmv_off(ob, me); + ok= 1; + scene->obedit= ob; // context sees this + + make_editMesh(scene, ob); - if(U.flag & USER_ADD_EDITMODE) - ED_object_enter_editmode(C, 0); - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene); + } + else if (ob->type==OB_ARMATURE){ + bArmature *arm= base->object->data; + if (!arm) return; + /* + * The function object_data_is_libdata make a problem here, the + * check for ob->proxy return 0 and let blender enter to edit mode + * this causa a crash when you try leave the edit mode. + * The problem is that i can't remove the ob->proxy check from + * object_data_is_libdata that prevent the bugfix #6614, so + * i add this little hack here. + */ + if(arm->id.lib) { + error_libdata(); + return; + } + ok=1; + scene->obedit= ob; + ED_armature_to_edit(ob); + /* to ensure all goes in restposition and without striding */ + DAG_id_flush_update(&ob->id, OB_RECALC); -void OBJECT_OT_text_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Text"; - ot->description = "Add a text object to the scene"; - ot->idname= "OBJECT_OT_text_add"; - - /* api callbacks */ - ot->exec= object_add_text_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene); + } + else if(ob->type==OB_FONT) { + scene->obedit= ob; // XXX for context + ok= 1; + make_editText(ob); -static int object_armature_add_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - View3D *v3d= CTX_wm_view3d(C); - RegionView3D *rv3d= NULL; - int newob= 0; - - if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) { - object_add_type(C, OB_ARMATURE); - ED_object_enter_editmode(C, 0); - newob = 1; + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene); } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - if(v3d) - rv3d= CTX_wm_region(C)->regiondata; - - /* v3d and rv3d are allowed to be NULL */ - add_primitive_bone(CTX_data_scene(C), v3d, rv3d); + else if(ob->type==OB_MBALL) { + scene->obedit= ob; // XXX for context + ok= 1; + make_editMball(ob); - /* userdef */ - if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, scene); + } + else if(ob->type==OB_LATTICE) { + scene->obedit= ob; // XXX for context + ok= 1; + make_editLatt(ob); + + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, scene); + } + else if(ob->type==OB_SURF || ob->type==OB_CURVE) { + ok= 1; + scene->obedit= ob; // XXX for context + make_editNurb(ob); + + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, scene); } - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + if(ok) { + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + } + else { + scene->obedit= NULL; // XXX for context + WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); + } - return OPERATOR_FINISHED; + if(flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode"); + if(flag & EM_WAITCURSOR) waitcursor(0); } -void OBJECT_OT_armature_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Armature"; - ot->description = "Add an armature object to the scene."; - ot->idname= "OBJECT_OT_armature_add"; +static int editmode_toggle_exec(bContext *C, wmOperator *op) +{ - /* api callbacks */ - ot->exec= object_armature_add_exec; - ot->poll= ED_operator_scene_editable; + if(!CTX_data_edit_object(C)) + ED_object_enter_editmode(C, EM_WAITCURSOR); + else + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + return OPERATOR_FINISHED; } -static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event) +static int editmode_toggle_poll(bContext *C) { - uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0); - uiLayout *layout= uiPupMenuLayout(pup); - - uiItemMenuEnumO(layout, "Mesh", ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type"); - uiItemMenuEnumO(layout, "Curve", ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type"); - uiItemMenuEnumO(layout, "Surface", ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type"); - uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type"); - uiItemO(layout, "Text", ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add"); - uiItemS(layout); - uiItemO(layout, "Armature", ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add"); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LATTICE, "OBJECT_OT_object_add", "type", OB_LATTICE); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_object_add", "type", OB_EMPTY); - uiItemS(layout); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_object_add", "type", OB_CAMERA); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LAMP, "OBJECT_OT_object_add", "type", OB_LAMP); - - uiPupMenuEnd(C, pup); - - /* this operator is only for a menu, not used further */ - return OPERATOR_CANCELLED; + Object *ob = CTX_data_active_object(C); + + return ob && (ob->type == OB_MESH || ob->type == OB_ARMATURE || + ob->type == OB_FONT || ob->type == OB_MBALL || + ob->type == OB_LATTICE || ob->type == OB_SURF || + ob->type == OB_CURVE); } -/* only used as menu */ -void OBJECT_OT_primitive_add(wmOperatorType *ot) +void OBJECT_OT_editmode_toggle(wmOperatorType *ot) { + /* identifiers */ - ot->name= "Add Primitive"; - ot->description = "Add a primitive object."; - ot->idname= "OBJECT_OT_primitive_add"; + ot->name= "Toggle Editmode"; + ot->description = "Toggle object's editmode."; + ot->idname= "OBJECT_OT_editmode_toggle"; /* api callbacks */ - ot->invoke= object_primitive_add_invoke; + ot->exec= editmode_toggle_exec; - ot->poll= ED_operator_scene_editable; + ot->poll= editmode_toggle_poll; /* flags */ - ot->flag= 0; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* *************************** */ -/* ******************************* */ - -/* remove base from a specific scene */ -/* note: now unlinks constraints as well */ -void ED_base_object_free_and_unlink(Scene *scene, Base *base) -{ - BLI_remlink(&scene->base, base); - free_libblock_us(&G.main->object, base->object); - if(scene->basact==base) scene->basact= NULL; - MEM_freeN(base); -} - -static int object_delete_exec(bContext *C, wmOperator *op) +static int posemode_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); - int islamp= 0; - - if(CTX_data_edit_object(C)) - return OPERATOR_CANCELLED; + Base *base= CTX_data_active_base(C); - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - - if(base->object->type==OB_LAMP) islamp= 1; + if(base->object->type==OB_ARMATURE) { + if(base->object==CTX_data_edit_object(C)) { + ED_object_exit_editmode(C, EM_FREEDATA); + ED_armature_enter_posemode(C, base); + } + else if(base->object->mode & OB_MODE_POSE) + ED_armature_exit_posemode(C, base); + else + ED_armature_enter_posemode(C, base); - /* remove from current scene only */ - ED_base_object_free_and_unlink(scene, base); + return OPERATOR_FINISHED; } - CTX_DATA_END; - - if(islamp) reshadeall_displist(scene); /* only frees displist */ - - DAG_scene_sort(scene); - ED_anim_dag_flush_update(C); - WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C)); - - return OPERATOR_FINISHED; + return OPERATOR_PASS_THROUGH; } -void OBJECT_OT_delete(wmOperatorType *ot) +void OBJECT_OT_posemode_toggle(wmOperatorType *ot) { - /* identifiers */ - ot->name= "Delete"; - ot->description = "Delete selected objects."; - ot->idname= "OBJECT_OT_delete"; + ot->name= "Toggle Pose Mode"; + ot->idname= "OBJECT_OT_posemode_toggle"; + ot->description= "Enables or disables posing/selecting bones"; /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_delete_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->exec= posemode_exec; + ot->poll= ED_operator_object_active; + /* flag */ + ot->flag= OPTYPE_REGISTER; } +/* *********************** */ -static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin) +void check_editmode(int type) { - ID_NEW(*obpoin); -} + Object *obedit= NULL; // XXX + + if (obedit==NULL || obedit->type==type) return; -static void copy_object__forwardModifierLinks(void *userData, Object *ob, - ID **idpoin) -{ - /* this is copied from ID_NEW; it might be better to have a macro */ - if(*idpoin && (*idpoin)->newid) *idpoin = (*idpoin)->newid; +// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ } +#if 0 +// XXX should be in view3d? -/* after copying objects, copied data should get new pointers */ -static void copy_object_set_idnew(Scene *scene, View3D *v3d, int dupflag) +/* context: ob = lamp */ +/* code should be replaced with proper (custom) transform handles for lamp properties */ +static void spot_interactive(Object *ob, int mode) { - Base *base; - Object *ob; - Material *ma, *mao; - ID *id; -#if 0 // XXX old animation system - Ipo *ipo; - bActionStrip *strip; -#endif // XXX old animation system - int a; - - /* XXX check object pointers */ - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB_BGMODE(v3d, base)) { - ob= base->object; - relink_constraints(&ob->constraints); - if (ob->pose){ - bPoseChannel *chan; - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - relink_constraints(&chan->constraints); - } - } - modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL); - ID_NEW(ob->parent); - ID_NEW(ob->track); - ID_NEW(ob->proxy); - ID_NEW(ob->proxy_group); - -#if 0 // XXX old animation system - for(strip= ob->nlastrips.first; strip; strip= strip->next) { - bActionModifier *amod; - for(amod= strip->modifiers.first; amod; amod= amod->next) - ID_NEW(amod->ob); - } -#endif // XXX old animation system - } - } - - /* materials */ - if( dupflag & USER_DUP_MAT) { - mao= G.main->mat.first; - while(mao) { - if(mao->id.newid) { - - ma= (Material *)mao->id.newid; - - if(dupflag & USER_DUP_TEX) { - for(a=0; amtex[a]) { - id= (ID *)ma->mtex[a]->tex; - if(id) { - ID_NEW_US(ma->mtex[a]->tex) - else ma->mtex[a]->tex= copy_texture(ma->mtex[a]->tex); - id->us--; - } - } - } - } -#if 0 // XXX old animation system - id= (ID *)ma->ipo; - if(id) { - ID_NEW_US(ma->ipo) - else ma->ipo= copy_ipo(ma->ipo); - id->us--; - } -#endif // XXX old animation system - } - mao= mao->id.next; - } - } + Lamp *la= ob->data; + float transfac, dx, dy, ratio, origval; + int keep_running= 1, center2d[2]; + short mval[2], mvalo[2]; -#if 0 // XXX old animation system - /* lamps */ - if( dupflag & USER_DUP_IPO) { - Lamp *la= G.main->lamp.first; - while(la) { - if(la->id.newid) { - Lamp *lan= (Lamp *)la->id.newid; - id= (ID *)lan->ipo; - if(id) { - ID_NEW_US(lan->ipo) - else lan->ipo= copy_ipo(lan->ipo); - id->us--; - } - } - la= la->id.next; - } - } +// getmouseco_areawin(mval); +// getmouseco_areawin(mvalo); - /* ipos */ - ipo= G.main->ipo.first; - while(ipo) { - if(ipo->id.lib==NULL && ipo->id.newid) { - Ipo *ipon= (Ipo *)ipo->id.newid; - IpoCurve *icu; - for(icu= ipon->curve.first; icu; icu= icu->next) { - if(icu->driver) { - ID_NEW(icu->driver->ob); - } - } - } - ipo= ipo->id.next; + project_int(ob->obmat[3], center2d); + if( center2d[0] > 100000 ) { /* behind camera */ +// center2d[0]= curarea->winx/2; +// center2d[1]= curarea->winy/2; } -#endif // XXX old animation system - - set_sca_new_poins(); - - clear_id_newpoins(); - -} -static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent) -{ - EditVert *eve; - int *index, nr, totvert=0; - - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->f & SELECT) totvert++; - } - if(totvert==0) return 0; - - *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); - *tot= totvert; - nr= 0; - cent[0]= cent[1]= cent[2]= 0.0; +// helpline(mval, center2d); - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->f & SELECT) { - *index= nr; index++; - VecAddf(cent, cent, eve->co); - } - nr++; - } + /* ratio is like scaling */ + dx = (float)(center2d[0] - mval[0]); + dy = (float)(center2d[1] - mval[1]); + transfac = (float)sqrt( dx*dx + dy*dy); + if(transfac==0.0f) transfac= 1.0f; - VecMulf(cent, 1.0f/(float)totvert); - - return totvert; -} - -static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent) -{ - MDeformVert *dvert; - EditVert *eve; - int i, totvert=0; - - cent[0]= cent[1]= cent[2]= 0.0; + if(mode==1) + origval= la->spotsize; + else if(mode==2) + origval= la->dist; + else if(mode==3) + origval= la->clipsta; + else + origval= la->clipend; - if(obedit->actdef) { + while (keep_running>0) { - /* find the vertices */ - for(eve= em->verts.first; eve; eve= eve->next) { - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if(dvert) { - for(i=0; itotweight; i++){ - if(dvert->dw[i].def_nr == (obedit->actdef-1)) { - totvert++; - VecAddf(cent, cent, eve->co); - } - } - } - } - if(totvert) { - bDeformGroup *defGroup = BLI_findlink(&obedit->defbase, obedit->actdef-1); - strcpy(name, defGroup->name); - VecMulf(cent, 1.0f/(float)totvert); - return 1; +// getmouseco_areawin(mval); + + /* essential for idling subloop */ + if(mval[0]==mvalo[0] && mval[1]==mvalo[1]) { + PIL_sleep_ms(2); } - } - - return 0; -} + else { + char str[32]; + + dx = (float)(center2d[0] - mval[0]); + dy = (float)(center2d[1] - mval[1]); + ratio = (float)(sqrt( dx*dx + dy*dy))/transfac; + + /* do the trick */ + + if(mode==1) { /* spot */ + la->spotsize = ratio*origval; + CLAMP(la->spotsize, 1.0f, 180.0f); + sprintf(str, "Spot size %.2f\n", la->spotsize); + } + else if(mode==2) { /* dist */ + la->dist = ratio*origval; + CLAMP(la->dist, 0.01f, 5000.0f); + sprintf(str, "Distance %.2f\n", la->dist); + } + else if(mode==3) { /* sta */ + la->clipsta = ratio*origval; + CLAMP(la->clipsta, 0.001f, 5000.0f); + sprintf(str, "Distance %.2f\n", la->clipsta); + } + else if(mode==4) { /* end */ + la->clipend = ratio*origval; + CLAMP(la->clipend, 0.1f, 5000.0f); + sprintf(str, "Clip End %.2f\n", la->clipend); + } -static void select_editmesh_hook(Object *ob, HookModifierData *hmd) -{ - Mesh *me= ob->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - EditVert *eve; - int index=0, nr=0; - - if (hmd->indexar == NULL) - return; - - for(eve= em->verts.first; eve; eve= eve->next, nr++) { - if(nr==hmd->indexar[index]) { - eve->f |= SELECT; - if(index < hmd->totindex-1) index++; - } - } - EM_select_flush(em); + /* cleanup */ + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + /* handle shaded mode */ +// XXX shade_buttons_change_3d(); - BKE_mesh_end_editmesh(me, em); -} + /* DRAW */ + headerprint(str); + force_draw_plus(SPACE_BUTS, 0); -static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar, float *cent) -{ - BPoint *bp; - int *index, nr, totvert=0, a; - - /* count */ - a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; - bp= editlatt->def; - while(a--) { - if(bp->f1 & SELECT) { - if(bp->hide==0) totvert++; +// helpline(mval, center2d); } - bp++; - } - - if(totvert==0) return 0; - - *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); - *tot= totvert; - nr= 0; - cent[0]= cent[1]= cent[2]= 0.0; - - a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; - bp= editlatt->def; - while(a--) { - if(bp->f1 & SELECT) { - if(bp->hide==0) { - *index= nr; index++; - VecAddf(cent, cent, bp->vec); + + while( qtest() ) { + short val; + unsigned short event= extern_qread(&val); + + switch (event){ + case ESCKEY: + case RIGHTMOUSE: + keep_running= 0; + break; + case LEFTMOUSE: + case SPACEKEY: + case PADENTER: + case RETKEY: + if(val) + keep_running= -1; + break; } } - bp++; - nr++; } - - VecMulf(cent, 1.0f/(float)totvert); - - return totvert; -} -static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) -{ - Lattice *lt= obedit->data; - BPoint *bp; - int index=0, nr=0, a; - - /* count */ - a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - bp= lt->editlatt->def; - while(a--) { - if(hmd->indexar[index]==nr) { - bp->f1 |= SELECT; - if(index < hmd->totindex-1) index++; - } - nr++; - bp++; + if(keep_running==0) { + if(mode==1) + la->spotsize= origval; + else if(mode==2) + la->dist= origval; + else if(mode==3) + la->clipsta= origval; + else + la->clipend= origval; } + } +#endif -static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, float *cent) +void special_editmenu(Scene *scene, View3D *v3d) { - ListBase *editnurb= curve_get_editcurve(obedit); - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - int *index, a, nr, totvert=0; - - for(nu= editnurb->first; nu; nu= nu->next) { - if(nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - if(bezt->f1 & SELECT) totvert++; - if(bezt->f2 & SELECT) totvert++; - if(bezt->f3 & SELECT) totvert++; - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - if(bp->f1 & SELECT) totvert++; - bp++; - } - } - } - if(totvert==0) return 0; +// XXX static short numcuts= 2; + Object *ob= OBACT; + Object *obedit= NULL; // XXX + int nr,ret=0; - *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); - *tot= totvert; - nr= 0; - cent[0]= cent[1]= cent[2]= 0.0; + if(ob==NULL) return; - for(nu= editnurb->first; nu; nu= nu->next) { - if(nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - if(bezt->f1 & SELECT) { - *index= nr; index++; - VecAddf(cent, cent, bezt->vec[0]); - } - nr++; - if(bezt->f2 & SELECT) { - *index= nr; index++; - VecAddf(cent, cent, bezt->vec[1]); - } - nr++; - if(bezt->f3 & SELECT) { - *index= nr; index++; - VecAddf(cent, cent, bezt->vec[2]); + if(obedit==NULL) { + + if(ob->mode & OB_MODE_POSE) { +// XXX pose_special_editmenu(); + } + else if(paint_facesel_test(ob)) { + Mesh *me= get_mesh(ob); + MTFace *tface; + MFace *mface; + int a; + + if(me==0 || me->mtface==0) return; + + nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5| TwoSide%x6|Clr Tex%x7| Shared%x8| Light%x9| Invisible%x10| Collision%x11| TwoSide%x12"); + + tface= me->mtface; + mface= me->mface; + for(a=me->totface; a>0; a--, tface++, mface++) { + if(mface->flag & ME_FACE_SEL) { + switch(nr) { + case 1: + tface->mode |= TF_TEX; break; + case 2: + tface->mode |= TF_SHAREDCOL; break; + case 3: + tface->mode |= TF_LIGHT; break; + case 4: + tface->mode |= TF_INVISIBLE; break; + case 5: + tface->mode |= TF_DYNAMIC; break; + case 6: + tface->mode |= TF_TWOSIDE; break; + case 7: + tface->mode &= ~TF_TEX; + tface->tpage= 0; + break; + case 8: + tface->mode &= ~TF_SHAREDCOL; break; + case 9: + tface->mode &= ~TF_LIGHT; break; + case 10: + tface->mode &= ~TF_INVISIBLE; break; + case 11: + tface->mode &= ~TF_DYNAMIC; break; + case 12: + tface->mode &= ~TF_TWOSIDE; break; + } } - nr++; - bezt++; } + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - if(bp->f1 & SELECT) { - *index= nr; index++; - VecAddf(cent, cent, bp->vec); - } - nr++; - bp++; + else if(ob->mode & OB_MODE_VERTEX_PAINT) { + Mesh *me= get_mesh(ob); + + if(me==0 || (me->mcol==NULL && me->mtface==NULL) ) return; + + nr= pupmenu("Specials%t|Shared VertexCol%x1"); + if(nr==1) { + +// XXX do_shared_vertexcol(me); + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } - } - - VecMulf(cent, 1.0f/(float)totvert); - - return totvert; -} - -void ED_object_apply_obmat(Object *ob) -{ - float mat[3][3], imat[3][3], tmat[3][3]; - - /* from obmat to loc rot size */ - - if(ob==NULL) return; - Mat3CpyMat4(mat, ob->obmat); - - VECCOPY(ob->loc, ob->obmat[3]); - - Mat3ToEul(mat, ob->rot); - EulToMat3(ob->rot, tmat); - - Mat3Inv(imat, tmat); - - Mat3MulMat3(tmat, imat, mat); - - ob->size[0]= tmat[0][0]; - ob->size[1]= tmat[1][1]; - ob->size[2]= tmat[2][2]; - -} + else if(ob->mode & OB_MODE_WEIGHT_PAINT) { + Object *par= modifiers_isDeformedByArmature(ob); -int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r) -{ - *indexar= NULL; - *tot= 0; - name[0]= 0; - - switch(obedit->type) { - case OB_MESH: - { - Mesh *me= obedit->data; - EditMesh *em = BKE_mesh_get_editmesh(me); + if(par && (par->mode & OB_MODE_POSE)) { + nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2"); - /* check selected vertices first */ - if( return_editmesh_indexar(em, tot, indexar, cent_r)) { - BKE_mesh_end_editmesh(me, em); - return 1; - } else { - int ret = return_editmesh_vgroup(obedit, em, name, cent_r); - BKE_mesh_end_editmesh(me, em); - return ret; +// XXX if(nr==1 || nr==2) +// XXX pose_adds_vgroups(ob, (nr == 2)); } } - case OB_CURVE: - case OB_SURF: - return return_editcurve_indexar(obedit, tot, indexar, cent_r); - case OB_LATTICE: - { - Lattice *lt= obedit->data; - return return_editlattice_indexar(lt->editlatt, tot, indexar, cent_r); - } - default: - return 0; - } -} + else if(ob->mode & OB_MODE_PARTICLE_EDIT) { +#if 0 + // XXX + ParticleSystem *psys = PE_get_current(ob); + ParticleEditSettings *pset = PE_settings(); -static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) -{ - ListBase *editnurb= curve_get_editcurve(obedit); - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - int index=0, a, nr=0; - - for(nu= editnurb->first; nu; nu= nu->next) { - if(nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - if(nr == hmd->indexar[index]) { - bezt->f1 |= SELECT; - if(indextotindex-1) index++; - } - nr++; - if(nr == hmd->indexar[index]) { - bezt->f2 |= SELECT; - if(indextotindex-1) index++; - } - nr++; - if(nr == hmd->indexar[index]) { - bezt->f3 |= SELECT; - if(indextotindex-1) index++; - } - nr++; - - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - if(nr == hmd->indexar[index]) { - bp->f1 |= SELECT; - if(indextotindex-1) index++; - } - nr++; - bp++; - } - } - } -} - -void object_hook_select(Object *ob, HookModifierData *hmd) -{ - if(ob->type==OB_MESH) select_editmesh_hook(ob, hmd); - else if(ob->type==OB_LATTICE) select_editlattice_hook(ob, hmd); - else if(ob->type==OB_CURVE) select_editcurve_hook(ob, hmd); - else if(ob->type==OB_SURF) select_editcurve_hook(ob, hmd); -} - - -void add_hook(Scene *scene, View3D *v3d, int mode) -{ - ModifierData *md = NULL; - HookModifierData *hmd = NULL; - Object *ob=NULL; - Object *obedit= scene->obedit; // XXX get from context - - if(obedit==NULL) return; - - /* preconditions */ - if(mode==2) { /* selected object */ - Base *base; - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - ob= base->object; - break; - } - } - } - if(ob==NULL) { - error("Requires selected Object"); - return; - } - } - else if(mode!=1) { - int maxlen=0, a, nr; - char *cp; - - /* make pupmenu with hooks */ - for(md=obedit->modifiers.first; md; md= md->next) { - if (md->type==eModifierType_Hook) - maxlen+=32; - } - - if(maxlen==0) { - error("Object has no hooks yet"); - return; - } - - cp= MEM_callocN(maxlen+32, "temp string"); - if(mode==3) strcpy(cp, "Remove %t|"); - else if(mode==4) strcpy(cp, "Reassign %t|"); - else if(mode==5) strcpy(cp, "Select %t|"); - else if(mode==6) strcpy(cp, "Clear Offset %t|"); - - for(md=obedit->modifiers.first; md; md= md->next) { - if (md->type==eModifierType_Hook) { - strcat(cp, md->name); - strcat(cp, " |"); - } - } - - nr= pupmenu(cp); - MEM_freeN(cp); - - if(nr<1) return; - - a= 1; - for(md=obedit->modifiers.first; md; md=md->next) { - if (md->type==eModifierType_Hook) { - if(a==nr) break; - a++; - } - } - - hmd = (HookModifierData*) md; - ob= hmd->object; - } - - /* do it, new hooks or reassign */ - if(mode==1 || mode==2 || mode==4) { - float cent[3]; - int tot, ok, *indexar; - char name[32]; - - ok = object_hook_index_array(obedit, &tot, &indexar, name, cent); - - if(ok==0) { - error("Requires selected vertices or active Vertex Group"); - } - else { - - if(mode==1) { - Base *base= BASACT, *newbase; - - ob= add_object(scene, OB_EMPTY); - /* set layers OK */ - newbase= BASACT; - newbase->lay= base->lay; - ob->lay= newbase->lay; - - /* transform cent to global coords for loc */ - VecMat4MulVecfl(ob->loc, obedit->obmat, cent); - - /* restore, add_object sets active */ - BASACT= base; - } - /* if mode is 2 or 4, ob has been set */ - - /* new hook */ - if(mode==1 || mode==2) { - ModifierData *md = obedit->modifiers.first; - - while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { - md = md->next; - } - - hmd = (HookModifierData*) modifier_new(eModifierType_Hook); - BLI_insertlinkbefore(&obedit->modifiers, md, hmd); - sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2); - } - else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */ - - hmd->object= ob; - hmd->indexar= indexar; - VECCOPY(hmd->cent, cent); - hmd->totindex= tot; - BLI_strncpy(hmd->name, name, 32); - - // TODO: need to take into account bone targets here too now... - if(mode==1 || mode==2) { - /* matrix calculus */ - /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ - /* (parentinv ) */ - - where_is_object(scene, ob); - - Mat4Invert(ob->imat, ob->obmat); - /* apparently this call goes from right to left... */ - Mat4MulSerie(hmd->parentinv, ob->imat, obedit->obmat, NULL, - NULL, NULL, NULL, NULL, NULL); - } - } - } - else if(mode==3) { /* remove */ - BLI_remlink(&obedit->modifiers, md); - modifier_free(md); - } - else if(mode==5) { /* select */ - // FIXME: this is now OBJECT_OT_hook_select - object_hook_select(obedit, hmd); - } - else if(mode==6) { /* clear offset */ - // FIXME: this is now OBJECT_OT_hook_reset operator - where_is_object(scene, ob); /* ob is hook->parent */ - - Mat4Invert(ob->imat, ob->obmat); - /* this call goes from right to left... */ - Mat4MulSerie(hmd->parentinv, ob->imat, obedit->obmat, NULL, - NULL, NULL, NULL, NULL, NULL); - } - - DAG_scene_sort(scene); -} - -void add_hook_menu(Scene *scene, View3D *v3d) -{ - Object *obedit= scene->obedit; // XXX get from context - int mode; - - if(obedit==NULL) return; - - if(modifiers_findByType(obedit, eModifierType_Hook)) - mode= pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6"); - else - mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2"); - - if(mode<1) return; - - /* do operations */ - add_hook(scene, v3d, mode); -} - - - -/* use this when the loc/size/rot of the parent has changed but the children should stay in the same place - * apply-size-rot or object center for eg */ -static void ignore_parent_tx(Scene *scene, Object *ob ) -{ - Object workob; - Object *ob_child; - - /* a change was made, adjust the children to compensate */ - for (ob_child=G.main->object.first; ob_child; ob_child=ob_child->id.next) { - if (ob_child->parent == ob) { - ED_object_apply_obmat(ob_child); - what_does_parent(scene, ob_child, &workob); - Mat4Invert(ob_child->parentinv, workob.obmat); - } - } -} - -/* ******************** clear parent operator ******************* */ - -static EnumPropertyItem prop_clear_parent_types[] = { - {0, "CLEAR", 0, "Clear Parent", ""}, - {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""}, - {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, - {0, NULL, 0, NULL, NULL} -}; - -/* note, poll should check for editable scene */ -static int parent_clear_exec(bContext *C, wmOperator *op) -{ - int type= RNA_enum_get(op->ptr, "type"); - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - - if(type == 0) { - ob->parent= NULL; - } - else if(type == 1) { - ob->parent= NULL; - ob->track= NULL; - ED_object_apply_obmat(ob); - } - else if(type == 2) - Mat4One(ob->parentinv); - - ob->recalc |= OB_RECALC; - } - CTX_DATA_END; - - DAG_scene_sort(CTX_data_scene(C)); - ED_anim_dag_flush_update(C); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_parent_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Clear Parent"; - ot->description = "Clear the object's parenting."; - ot->idname= "OBJECT_OT_parent_clear"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= parent_clear_exec; - - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); -} - -/* ******************** clear track operator ******************* */ - - -static EnumPropertyItem prop_clear_track_types[] = { - {0, "CLEAR", 0, "Clear Track", ""}, - {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""}, - {0, NULL, 0, NULL, NULL} -}; - -/* note, poll should check for editable scene */ -static int object_track_clear_exec(bContext *C, wmOperator *op) -{ - int type= RNA_enum_get(op->ptr, "type"); - - if(CTX_data_edit_object(C)) { - BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode"); - return OPERATOR_CANCELLED; - } - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - ob->track= NULL; - ob->recalc |= OB_RECALC; - - if(type == 1) - ED_object_apply_obmat(ob); - } - CTX_DATA_END; - - DAG_scene_sort(CTX_data_scene(C)); - ED_anim_dag_flush_update(C); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_track_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Clear track"; - ot->description = "Clear tracking constraint or flag from object."; - ot->idname= "OBJECT_OT_track_clear"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_track_clear_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_clear_track_types, 0, "Type", ""); -} - -/* *****************Selection Operators******************* */ -static EnumPropertyItem prop_select_types[] = { - {0, "EXCLUSIVE", 0, "Exclusive", ""}, - {1, "EXTEND", 0, "Extend", ""}, - {0, NULL, 0, NULL, NULL} -}; - -/* ****** Select by Type ****** */ - -static int object_select_by_type_exec(bContext *C, wmOperator *op) -{ - short obtype, seltype; - - obtype = RNA_enum_get(op->ptr, "type"); - seltype = RNA_enum_get(op->ptr, "seltype"); - - if (seltype == 0) { - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); - } - CTX_DATA_END; - } - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(base->object->type==obtype) { - ED_base_object_select(base, BA_SELECT); - } - } - CTX_DATA_END; - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_by_type(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select By Type"; - ot->description = "Select all visible objects that are of a type."; - ot->idname= "OBJECT_OT_select_by_type"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_select_by_type_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "seltype", prop_select_types, 0, "Selection", "Extend selection or clear selection then select"); - RNA_def_enum(ot->srna, "type", prop_object_types, 1, "Type", ""); - -} -/* ****** selection by links *******/ - -static EnumPropertyItem prop_select_linked_types[] = { - {1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... - {2, "OBDATA", 0, "Ob Data", ""}, - {3, "MATERIAL", 0, "Material", ""}, - {4, "TEXTURE", 0, "Texture", ""}, - {5, "DUPGROUP", 0, "Dupligroup", ""}, - {6, "PARTICLE", 0, "Particle System", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int object_select_linked_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob; - void *obdata = NULL; - Material *mat = NULL, *mat1; - Tex *tex=0; - int a, b; - int nr = RNA_enum_get(op->ptr, "type"); - short changed = 0, seltype; - /* events (nr): - * Object Ipo: 1 - * ObData: 2 - * Current Material: 3 - * Current Texture: 4 - * DupliGroup: 5 - * PSys: 6 - */ - - seltype = RNA_enum_get(op->ptr, "seltype"); - - if (seltype == 0) { - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); - } - CTX_DATA_END; - } - - ob= OBACT; - if(ob==0){ - BKE_report(op->reports, RPT_ERROR, "No Active Object"); - return OPERATOR_CANCELLED; - } - - if(nr==1) { - // XXX old animation system - //ipo= ob->ipo; - //if(ipo==0) return OPERATOR_CANCELLED; - return OPERATOR_CANCELLED; - } - else if(nr==2) { - if(ob->data==0) return OPERATOR_CANCELLED; - obdata= ob->data; - } - else if(nr==3 || nr==4) { - mat= give_current_material(ob, ob->actcol); - if(mat==0) return OPERATOR_CANCELLED; - if(nr==4) { - if(mat->mtex[ (int)mat->texact ]) tex= mat->mtex[ (int)mat->texact ]->tex; - if(tex==0) return OPERATOR_CANCELLED; - } - } - else if(nr==5) { - if(ob->dup_group==NULL) return OPERATOR_CANCELLED; - } - else if(nr==6) { - if(ob->particlesystem.first==NULL) return OPERATOR_CANCELLED; - } - else return OPERATOR_CANCELLED; - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(nr==1) { - // XXX old animation system - //if(base->object->ipo==ipo) base->flag |= SELECT; - //changed = 1; - } - else if(nr==2) { - if(base->object->data==obdata) base->flag |= SELECT; - changed = 1; - } - else if(nr==3 || nr==4) { - ob= base->object; - - for(a=1; a<=ob->totcol; a++) { - mat1= give_current_material(ob, a); - if(nr==3) { - if(mat1==mat) base->flag |= SELECT; - changed = 1; - } - else if(mat1 && nr==4) { - for(b=0; bmtex[b]) { - if(tex==mat1->mtex[b]->tex) { - base->flag |= SELECT; - changed = 1; - break; - } - } - } - } - } - } - else if(nr==5) { - if(base->object->dup_group==ob->dup_group) { - base->flag |= SELECT; - changed = 1; - } - } - else if(nr==6) { - /* loop through other, then actives particles*/ - ParticleSystem *psys; - ParticleSystem *psys_act; - - for(psys=base->object->particlesystem.first; psys; psys=psys->next) { - for(psys_act=ob->particlesystem.first; psys_act; psys_act=psys_act->next) { - if (psys->part == psys_act->part) { - base->flag |= SELECT; - changed = 1; - break; - } - } - - if (base->flag & SELECT) { - break; - } - } - } - base->object->flag= base->flag; - } - CTX_DATA_END; - - if (changed) { - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void OBJECT_OT_select_linked(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Linked"; - ot->description = "Select all visible objects that are linked."; - ot->idname= "OBJECT_OT_select_linked"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_select_linked_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", ""); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); - -} - -/* ****** selection grouped *******/ - -static EnumPropertyItem prop_select_grouped_types[] = { - {1, "CHILDREN_RECURSIVE", 0, "Children", ""}, // XXX depreceated animation system stuff... - {2, "CHILDREN", 0, "Immediate Children", ""}, - {3, "PARENT", 0, "Parent", ""}, - {4, "SIBLINGS", 0, "Siblings", "Shared Parent"}, - {5, "TYPE", 0, "Type", "Shared object type"}, - {6, "LAYER", 0, "Layer", "Shared layers"}, - {7, "GROUP", 0, "Group", "Shared group"}, - {8, "HOOK", 0, "Hook", ""}, - {9, "PASS", 0, "Pass", "Render pass Index"}, - {10, "COLOR", 0, "Color", "Object Color"}, - {11, "PROPERTIES", 0, "Properties", "Game Properties"}, - {0, NULL, 0, NULL, NULL} -}; - - -static short select_grouped_children(bContext *C, Object *ob, int recursive) -{ - short changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if (ob == base->object->parent) { - if (!(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - - if (recursive) - changed |= select_grouped_children(C, base->object, 1); - } - } - CTX_DATA_END; - return changed; -} - -static short select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */ -{ - Scene *scene= CTX_data_scene(C); - View3D *v3d= CTX_wm_view3d(C); - - short changed = 0; - Base *baspar, *basact= CTX_data_active_base(C); - - if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */ - - baspar= object_in_scene(basact->object->parent, scene); - - /* can be NULL if parent in other scene */ - if(baspar && BASE_SELECTABLE(v3d, baspar)) { - ED_base_object_select(basact, BA_DESELECT); - ED_base_object_select(baspar, BA_SELECT); - ED_base_object_activate(C, baspar); - changed = 1; - } - return changed; -} - - -#define GROUP_MENU_MAX 24 -static short select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */ -{ - short changed = 0; - Group *group, *ob_groups[GROUP_MENU_MAX]; - //char str[10 + (24*GROUP_MENU_MAX)]; - //char *p = str; - int group_count=0; //, menu, i; - - for ( group=G.main->group.first; - group && group_count < GROUP_MENU_MAX; - group=group->id.next - ) { - if (object_in_group (ob, group)) { - ob_groups[group_count] = group; - group_count++; - } - } - - if (!group_count) - return 0; - - else if (group_count == 1) { - group = ob_groups[0]; - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if (!(base->flag & SELECT) && object_in_group(base->object, group)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; - } -#if 0 // XXX hows this work in 2.5? - /* build the menu. */ - p += sprintf(str, "Groups%%t"); - for (i=0; iid.name+2, i); - } - - menu = pupmenu (str); - if (menu == -1) - return 0; - - group = ob_groups[menu]; - for (base= FIRSTBASE; base; base= base->next) { - if (!(base->flag & SELECT) && object_in_group(base->object, group)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } -#endif - return changed; -} - -static short select_grouped_object_hooks(bContext *C, Object *ob) -{ - Scene *scene= CTX_data_scene(C); - View3D *v3d= CTX_wm_view3d(C); - - short changed = 0; - Base *base; - ModifierData *md; - HookModifierData *hmd; - - for (md = ob->modifiers.first; md; md=md->next) { - if (md->type==eModifierType_Hook) { - hmd= (HookModifierData*) md; - if (hmd->object && !(hmd->object->flag & SELECT)) { - base= object_in_scene(hmd->object, scene); - if (base && (BASE_SELECTABLE(v3d, base))) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - } - } - return changed; -} - -/* Select objects woth the same parent as the active (siblings), - * parent can be NULL also */ -static short select_grouped_siblings(bContext *C, Object *ob) -{ - short changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if ((base->object->parent==ob->parent) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; -} - -static short select_grouped_type(bContext *C, Object *ob) -{ - short changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if ((base->object->type == ob->type) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; -} - -static short select_grouped_layer(bContext *C, Object *ob) -{ - char changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if ((base->lay & ob->lay) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; -} - -static short select_grouped_index_object(bContext *C, Object *ob) -{ - char changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if ((base->object->index == ob->index) && !(base->flag & SELECT)) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; -} - -static short select_grouped_color(bContext *C, Object *ob) -{ - char changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if (!(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005f))) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; -} - -static short objects_share_gameprop(Object *a, Object *b) -{ - bProperty *prop; - /*make a copy of all its properties*/ - - for( prop= a->prop.first; prop; prop = prop->next ) { - if ( get_ob_property(b, prop->name) ) - return 1; - } - return 0; -} - -static short select_grouped_gameprops(bContext *C, Object *ob) -{ - char changed = 0; - - CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { - if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) { - ED_base_object_select(base, BA_SELECT); - changed = 1; - } - } - CTX_DATA_END; - return changed; -} - -static int object_select_grouped_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob; - int nr = RNA_enum_get(op->ptr, "type"); - short changed = 0, seltype; - - seltype = RNA_enum_get(op->ptr, "seltype"); - - if (seltype == 0) { - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); - } - CTX_DATA_END; - } - - ob= OBACT; - if(ob==0){ - BKE_report(op->reports, RPT_ERROR, "No Active Object"); - return OPERATOR_CANCELLED; - } - - if(nr==1) changed = select_grouped_children(C, ob, 1); - else if(nr==2) changed = select_grouped_children(C, ob, 0); - else if(nr==3) changed = select_grouped_parent(C); - else if(nr==4) changed = select_grouped_siblings(C, ob); - else if(nr==5) changed = select_grouped_type(C, ob); - else if(nr==6) changed = select_grouped_layer(C, ob); - else if(nr==7) changed = select_grouped_group(C, ob); - else if(nr==8) changed = select_grouped_object_hooks(C, ob); - else if(nr==9) changed = select_grouped_index_object(C, ob); - else if(nr==10) changed = select_grouped_color(C, ob); - else if(nr==11) changed = select_grouped_gameprops(C, ob); - - if (changed) { - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void OBJECT_OT_select_grouped(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Grouped"; - ot->description = "Select all visible objects grouped by various properties."; - ot->idname= "OBJECT_OT_select_grouped"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_select_grouped_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", ""); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); - -} - -/* ****** selection by layer *******/ - -static int object_select_by_layer_exec(bContext *C, wmOperator *op) -{ - unsigned int layernum; - short seltype; - - seltype = RNA_enum_get(op->ptr, "seltype"); - layernum = RNA_int_get(op->ptr, "layer"); - - if (seltype == 0) { - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); - } - CTX_DATA_END; - } - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(base->lay == (1<< (layernum -1))) - ED_base_object_select(base, BA_SELECT); - } - CTX_DATA_END; - - /* undo? */ - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_by_layer(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "select by layer"; - ot->description = "Select all visible objects on a layer."; - ot->idname= "OBJECT_OT_select_by_layer"; - - /* api callbacks */ - /*ot->invoke = XXX - need a int grid popup*/ - ot->exec= object_select_by_layer_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_int(ot->srna, "layer", 1, 1, 20, "Layer", "", 1, 20); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); -} - -/* ****** invert selection *******/ -static int object_select_inverse_exec(bContext *C, wmOperator *op) -{ - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if (base->flag & SELECT) - ED_base_object_select(base, BA_DESELECT); - else - ED_base_object_select(base, BA_SELECT); - } - CTX_DATA_END; - - /* undo? */ - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_inverse(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Select Inverse"; - ot->description = "Invert selection of all visible objects."; - ot->idname= "OBJECT_OT_select_inverse"; - - /* api callbacks */ - ot->exec= object_select_inverse_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - -} -/* ****** (de)select All *******/ - -static int object_select_de_select_all_exec(bContext *C, wmOperator *op) -{ - - int a=0, ok=0; - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if (base->flag & SELECT) { - ok= a= 1; - break; - } - else ok=1; - } - CTX_DATA_END; - - if (!ok) return OPERATOR_PASS_THROUGH; - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if (a) ED_base_object_select(base, BA_DESELECT); - else ED_base_object_select(base, BA_SELECT); - } - CTX_DATA_END; - - /* undo? */ - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_all_toggle(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "deselect all"; - ot->description = "(de)select all visible objects in scene."; - ot->idname= "OBJECT_OT_select_all_toggle"; - - /* api callbacks */ - ot->exec= object_select_de_select_all_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - -} -/* ****** select mirror *******/ -/* finds the best possible flipped name. For renaming; check for unique names afterwards */ -/* if strip_number: removes number extensions */ -void object_flip_name (char *name) -{ - int len; - char prefix[128]={""}; /* The part before the facing */ - char suffix[128]={""}; /* The part after the facing */ - char replace[128]={""}; /* The replacement string */ - char number[128]={""}; /* The number extension string */ - char *index=NULL; - - len= strlen(name); - if(len<3) return; // we don't do names like .R or .L - - /* We first check the case with a .### extension, let's find the last period */ - if(isdigit(name[len-1])) { - index= strrchr(name, '.'); // last occurrance - if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! - strcpy(number, index); - *index= 0; - len= strlen(name); - } - } - - strcpy (prefix, name); - -#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') - - /* first case; separator . - _ with extensions r R l L */ - if( IS_SEPARATOR(name[len-2]) ) { - switch(name[len-1]) { - case 'l': - prefix[len-1]= 0; - strcpy(replace, "r"); - break; - case 'r': - prefix[len-1]= 0; - strcpy(replace, "l"); - break; - case 'L': - prefix[len-1]= 0; - strcpy(replace, "R"); - break; - case 'R': - prefix[len-1]= 0; - strcpy(replace, "L"); - break; - } - } - /* case; beginning with r R l L , with separator after it */ - else if( IS_SEPARATOR(name[1]) ) { - switch(name[0]) { - case 'l': - strcpy(replace, "r"); - strcpy(suffix, name+1); - prefix[0]= 0; - break; - case 'r': - strcpy(replace, "l"); - strcpy(suffix, name+1); - prefix[0]= 0; - break; - case 'L': - strcpy(replace, "R"); - strcpy(suffix, name+1); - prefix[0]= 0; - break; - case 'R': - strcpy(replace, "L"); - strcpy(suffix, name+1); - prefix[0]= 0; - break; - } - } - else if(len > 5) { - /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ - index = BLI_strcasestr(prefix, "right"); - if (index==prefix || index==prefix+len-5) { - if(index[0]=='r') - strcpy (replace, "left"); - else { - if(index[1]=='I') - strcpy (replace, "LEFT"); - else - strcpy (replace, "Left"); - } - *index= 0; - strcpy (suffix, index+5); - } - else { - index = BLI_strcasestr(prefix, "left"); - if (index==prefix || index==prefix+len-4) { - if(index[0]=='l') - strcpy (replace, "right"); - else { - if(index[1]=='E') - strcpy (replace, "RIGHT"); - else - strcpy (replace, "Right"); - } - *index= 0; - strcpy (suffix, index+4); - } - } - } - -#undef IS_SEPARATOR - - sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); -} - -static int object_select_mirror_exec(bContext *C, wmOperator *op) -{ - char tmpname[32]; - short seltype; - - seltype = RNA_enum_get(op->ptr, "seltype"); - - CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) { - - strcpy(tmpname, primbase->object->id.name+2); - object_flip_name(tmpname); - - CTX_DATA_BEGIN(C, Base*, secbase, visible_bases) { - if(!strcmp(secbase->object->id.name+2, tmpname)) { - ED_base_object_select(secbase, BA_SELECT); - } - } - CTX_DATA_END; - - if (seltype == 0) ED_base_object_select(primbase, BA_DESELECT); - - } - CTX_DATA_END; - - /* undo? */ - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_mirror(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Select Mirror"; - ot->description = "Select the Mirror objects of the selected object eg. L.sword -> R.sword"; - ot->idname= "OBJECT_OT_select_mirror"; - - /* api callbacks */ - ot->exec= object_select_mirror_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); -} -/* ****** random selection *******/ - -static int object_select_random_exec(bContext *C, wmOperator *op) -{ - float percent; - short seltype; - - seltype = RNA_enum_get(op->ptr, "seltype"); - - if (seltype == 0) { - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - ED_base_object_select(base, BA_DESELECT); - } - CTX_DATA_END; - } - percent = RNA_float_get(op->ptr, "percent"); - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if (BLI_frand() < percent) { - ED_base_object_select(base, BA_SELECT); - } - } - CTX_DATA_END; - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_select_random(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Random select"; - ot->description = "Set select on random visible objects."; - ot->idname= "OBJECT_OT_select_random"; - - /* api callbacks */ - /*ot->invoke= object_select_random_invoke XXX - need a number popup ;*/ - ot->exec = object_select_random_exec; - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "percentage of objects to randomly select", 0.0001f, 1.0f); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); -} - -/* ******** Clear object Translation *********** */ - -static int object_location_clear_exec(bContext *C, wmOperator *op) -{ - int armature_clear= 0; - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { - if ((ob->protectflag & OB_LOCK_LOCX)==0) - ob->loc[0]= ob->dloc[0]= 0.0f; - if ((ob->protectflag & OB_LOCK_LOCY)==0) - ob->loc[1]= ob->dloc[1]= 0.0f; - if ((ob->protectflag & OB_LOCK_LOCZ)==0) - ob->loc[2]= ob->dloc[2]= 0.0f; - } - ob->recalc |= OB_RECALC_OB; - } - CTX_DATA_END; - - if(armature_clear==0) /* in this case flush was done */ - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - - -void OBJECT_OT_location_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Clear Location"; - ot->description = "Clear the object's location."; - ot->idname= "OBJECT_OT_location_clear"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_location_clear_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int object_rotation_clear_exec(bContext *C, wmOperator *op) -{ - int armature_clear= 0; - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { - /* eulers can only get cleared if they are not protected */ - if ((ob->protectflag & OB_LOCK_ROTX)==0) - ob->rot[0]= ob->drot[0]= 0.0f; - if ((ob->protectflag & OB_LOCK_ROTY)==0) - ob->rot[1]= ob->drot[1]= 0.0f; - if ((ob->protectflag & OB_LOCK_ROTZ)==0) - ob->rot[2]= ob->drot[2]= 0.0f; - } - ob->recalc |= OB_RECALC_OB; - } - CTX_DATA_END; - - if(armature_clear==0) /* in this case flush was done */ - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - - -void OBJECT_OT_rotation_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Clear Rotation"; - ot->description = "Clear the object's rotation."; - ot->idname= "OBJECT_OT_rotation_clear"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_rotation_clear_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int object_scale_clear_exec(bContext *C, wmOperator *op) -{ - int armature_clear= 0; - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { - if ((ob->protectflag & OB_LOCK_SCALEX)==0) { - ob->dsize[0]= 0.0f; - ob->size[0]= 1.0f; - } - if ((ob->protectflag & OB_LOCK_SCALEY)==0) { - ob->dsize[1]= 0.0f; - ob->size[1]= 1.0f; - } - if ((ob->protectflag & OB_LOCK_SCALEZ)==0) { - ob->dsize[2]= 0.0f; - ob->size[2]= 1.0f; - } - } - ob->recalc |= OB_RECALC_OB; - } - CTX_DATA_END; - - if(armature_clear==0) /* in this case flush was done */ - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_scale_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Clear Scale"; - ot->description = "Clear the object's scale."; - ot->idname= "OBJECT_OT_scale_clear"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_scale_clear_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int object_origin_clear_exec(bContext *C, wmOperator *op) -{ - float *v1, *v3, mat[3][3]; - int armature_clear= 0; - - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(ob->parent) { - v1= ob->loc; - v3= ob->parentinv[3]; - - Mat3CpyMat4(mat, ob->parentinv); - VECCOPY(v3, v1); - v3[0]= -v3[0]; - v3[1]= -v3[1]; - v3[2]= -v3[2]; - Mat3MulVecfl(mat, v3); - } - ob->recalc |= OB_RECALC_OB; - } - CTX_DATA_END; - - if(armature_clear==0) /* in this case flush was done */ - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_origin_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Clear Origin"; - ot->description = "Clear the object's origin."; - ot->idname= "OBJECT_OT_origin_clear"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_origin_clear_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* ********* clear/set restrict view *********/ -static int object_restrictview_clear_exec(bContext *C, wmOperator *op) -{ - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= sa->spacedata.first; - Scene *scene= CTX_data_scene(C); - Base *base; - int changed = 0; - - /* XXX need a context loop to handle such cases */ - for(base = FIRSTBASE; base; base=base->next){ - if((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) { - base->flag |= SELECT; - base->object->flag = base->flag; - base->object->restrictflag &= ~OB_RESTRICT_VIEW; - changed = 1; - } - } - if (changed) { - DAG_scene_sort(scene); - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - } - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_restrictview_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Clear Restrict View"; - ot->description = "Reveal the object by setting the restrictview flag."; - ot->idname= "OBJECT_OT_restrictview_clear"; - - /* api callbacks */ - ot->exec= object_restrictview_clear_exec; - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int object_restrictview_set_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - short changed = 0; - int unselected= RNA_boolean_get(op->ptr, "unselected"); - - CTX_DATA_BEGIN(C, Base*, base, visible_bases) { - if(!unselected) { - if (base->flag & SELECT){ - base->flag &= ~SELECT; - base->object->flag = base->flag; - base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; - if (base==BASACT) { - ED_base_object_activate(C, NULL); - } - } - } - else { - if (!(base->flag & SELECT)){ - base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; - } - } - } - CTX_DATA_END; - - if (changed) { - DAG_scene_sort(scene); - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); - - } - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_restrictview_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Set Restrict View"; - ot->description = "Hide the object by setting the restrictview flag."; - ot->idname= "OBJECT_OT_restrictview_set"; - - /* api callbacks */ - ot->exec= object_restrictview_set_exec; - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects."); - -} -/* ************* Slow Parent ******************* */ -static int object_slowparent_set_exec(bContext *C, wmOperator *op) -{ - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - - if(base->object->parent) base->object->partype |= PARSLOW; - base->object->recalc |= OB_RECALC_OB; - - } - CTX_DATA_END; - - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_slowparent_set(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Set Slow Parent"; - ot->description = "Set the object's slow parent."; - ot->idname= "OBJECT_OT_slow_parent_set"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_slowparent_set_exec; - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int object_slowparent_clear_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - if(base->object->parent) { - if(base->object->partype & PARSLOW) { - base->object->partype -= PARSLOW; - where_is_object(scene, base->object); - base->object->partype |= PARSLOW; - base->object->recalc |= OB_RECALC_OB; - } - } - - } - CTX_DATA_END; - - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_slowparent_clear(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Clear Slow Parent"; - ot->description = "Clear the object's slow parent."; - ot->idname= "OBJECT_OT_slow_parent_clear"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_slowparent_clear_exec; - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} -/* ******************** **************** */ - -/* only in edit mode */ -void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d) -{ - EditVert *eve; - Base *base; - Curve *cu= obedit->data; - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - Object *par, *ob; - int a, v1=0, v2=0, v3=0, v4=0, nr=1; - - /* we need 1 to 3 selected vertices */ - - if(obedit->type==OB_MESH) { - Mesh *me= obedit->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - eve= em->verts.first; - while(eve) { - if(eve->f & 1) { - if(v1==0) v1= nr; - else if(v2==0) v2= nr; - else if(v3==0) v3= nr; - else if(v4==0) v4= nr; - else break; - } - nr++; - eve= eve->next; - } - - BKE_mesh_end_editmesh(me, em); - } - else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) { - ListBase *editnurb= curve_get_editcurve(obedit); - - nu= editnurb->first; - while(nu) { - if(nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) { - if(v1==0) v1= nr; - else if(v2==0) v2= nr; - else if(v3==0) v3= nr; - else if(v4==0) v4= nr; - else break; - } - nr++; - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - if(bp->f1 & SELECT) { - if(v1==0) v1= nr; - else if(v2==0) v2= nr; - else if(v3==0) v3= nr; - else if(v4==0) v4= nr; - else break; - } - nr++; - bp++; - } - } - nu= nu->next; - } - } - else if(obedit->type==OB_LATTICE) { - Lattice *lt= obedit->data; - - a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - bp= lt->editlatt->def; - while(a--) { - if(bp->f1 & SELECT) { - if(v1==0) v1= nr; - else if(v2==0) v2= nr; - else if(v3==0) v3= nr; - else if(v4==0) v4= nr; - else break; - } - nr++; - bp++; - } - } - - if(v4 || !((v1 && v2==0 && v3==0) || (v1 && v2 && v3)) ) { - error("Select either 1 or 3 vertices to parent to"); - return; - } - - if(okee("Make vertex parent")==0) return; - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - - ob= base->object; - ob->recalc |= OB_RECALC; - par= BASACT->object->parent; - - while(par) { - if(par==ob) break; - par= par->parent; - } - if(par) { - error("Loop in parents"); - } - else { - Object workob; - - ob->parent= BASACT->object; - if(v3) { - ob->partype= PARVERT3; - ob->par1= v1-1; - ob->par2= v2-1; - ob->par3= v3-1; - - /* inverse parent matrix */ - what_does_parent(scene, ob, &workob); - Mat4Invert(ob->parentinv, workob.obmat); - } - else { - ob->partype= PARVERT1; - ob->par1= v1-1; - - /* inverse parent matrix */ - what_does_parent(scene, ob, &workob); - Mat4Invert(ob->parentinv, workob.obmat); - } - } - } - } - } - - DAG_scene_sort(scene); -} - - -/* ******************** make proxy operator *********************** */ - -/* present menu listing the possible objects within the group to proxify */ -static void proxy_group_objects_menu (bContext *C, wmOperator *op, Object *ob, Group *group) -{ - uiPopupMenu *pup; - uiLayout *layout; - GroupObject *go; - int len=0; - - /* check if there are any objects within the group to assign for */ - for (go= group->gobject.first; go; go= go->next) { - if (go->ob) len++; - } - if (len==0) return; - - /* now create the menu to draw */ - pup= uiPupMenuBegin(C, "Make Proxy For:", 0); - layout= uiPupMenuLayout(pup); - - for (go= group->gobject.first; go; go= go->next) { - if (go->ob) { - PointerRNA props_ptr; - - /* create operator menu item with relevant properties filled in */ - props_ptr= uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); - RNA_string_set(&props_ptr, "object", go->ob->id.name+2); - RNA_string_set(&props_ptr, "group_object", go->ob->id.name+2); - } - } - - /* display the menu, and be done */ - uiPupMenuEnd(C, pup); -} - -/* set the object to proxify */ -static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); - - /* sanity checks */ - if (!scene || scene->id.lib || !ob) - return OPERATOR_CANCELLED; - - /* Get object to work on - use a menu if we need to... */ - if (ob->dup_group && ob->dup_group->id.lib) { - /* gives menu with list of objects in group */ - proxy_group_objects_menu(C, op, ob, ob->dup_group); - } - else if (ob->id.lib) { - uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); - uiLayout *layout= uiPupMenuLayout(pup); - PointerRNA props_ptr; - - /* create operator menu item with relevant properties filled in */ - props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); - RNA_string_set(&props_ptr, "object", ob->id.name+2); - - /* present the menu and be done... */ - uiPupMenuEnd(C, pup); - } - else { - /* error.. cannot continue */ - BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group"); - } - - /* this invoke just calls another instance of this operator... */ - return OPERATOR_CANCELLED; -} - -static int make_proxy_exec (bContext *C, wmOperator *op) -{ - Object *ob=NULL, *gob=NULL; - Scene *scene= CTX_data_scene(C); - char ob_name[21], gob_name[21]; - - /* get object and group object - * - firstly names - * - then pointers from context - */ - RNA_string_get(op->ptr, "object", ob_name); - RNA_string_get(op->ptr, "group_object", gob_name); - - if (gob_name[0]) { - Group *group; - GroupObject *go; - - /* active object is group object... */ - // FIXME: we should get the nominated name instead - gob= CTX_data_active_object(C); - group= gob->dup_group; - - /* find the object to affect */ - for (go= group->gobject.first; go; go= go->next) { - if ((go->ob) && strcmp(go->ob->id.name+2, gob_name)==0) { - ob= go->ob; - break; - } - } - } - else { - /* just use the active object for now */ - // FIXME: we should get the nominated name instead - ob= CTX_data_active_object(C); - } - - if (ob) { - Object *newob; - Base *newbase, *oldbase= BASACT; - char name[32]; - - /* Add new object for the proxy */ - newob= add_object(scene, OB_EMPTY); - if (gob) - strcpy(name, gob->id.name+2); - else - strcpy(name, ob->id.name+2); - strcat(name, "_proxy"); - rename_id(&newob->id, name); - - /* set layers OK */ - newbase= BASACT; /* add_object sets active... */ - newbase->lay= oldbase->lay; - newob->lay= newbase->lay; - - /* remove base, leave user count of object, it gets linked in object_make_proxy */ - if (gob==NULL) { - BLI_remlink(&scene->base, oldbase); - MEM_freeN(oldbase); - } - - object_make_proxy(newob, ob, gob); - - /* depsgraph flushes are needed for the new data */ - DAG_scene_sort(scene); - DAG_id_flush_update(&newob->id, OB_RECALC); - - WM_event_add_notifier(C, NC_OBJECT, NULL); - } - else { - BKE_report(op->reports, RPT_ERROR, "No object to make proxy for"); - return OPERATOR_CANCELLED; - } - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_proxy_make (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Make Proxy"; - ot->idname= "OBJECT_OT_proxy_make"; - ot->description= "Add empty object to become local replacement data of a library-linked object"; - - /* callbacks */ - ot->invoke= make_proxy_invoke; - ot->exec= make_proxy_exec; - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_string(ot->srna, "object", "", 19, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for."); - RNA_def_string(ot->srna, "group_object", "", 19, "Group Object", "Name of group instancer (if applicable)."); -} - -/* ******************** make parent operator *********************** */ - -#define PAR_OBJECT 0 -#define PAR_ARMATURE 1 -#define PAR_ARMATURE_NAME 2 -#define PAR_ARMATURE_ENVELOPE 3 -#define PAR_ARMATURE_AUTO 4 -#define PAR_BONE 5 -#define PAR_CURVE 6 -#define PAR_FOLLOW 7 -#define PAR_PATH_CONST 8 -#define PAR_LATTICE 9 -#define PAR_VERTEX 10 -#define PAR_TRIA 11 - -static EnumPropertyItem prop_make_parent_types[] = { - {PAR_OBJECT, "OBJECT", 0, "Object", ""}, - {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""}, - {PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""}, - {PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""}, - {PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""}, - {PAR_BONE, "BONE", 0, "Bone", ""}, - {PAR_CURVE, "CURVE", 0, "Curve Deform", ""}, - {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""}, - {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""}, - {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""}, - {PAR_VERTEX, "VERTEX", 0, "Vertex", ""}, - {PAR_TRIA, "TRIA", 0, "Triangle", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int test_parent_loop(Object *par, Object *ob) -{ - /* test if 'ob' is a parent somewhere in par's parents */ - - if(par == NULL) return 0; - if(ob == par) return 1; - - return test_parent_loop(par->parent, ob); -} - -void ED_object_parent(Object *ob, Object *par, int type, const char *substr) -{ - if(!par || test_parent_loop(par, ob)) { - ob->parent= NULL; - ob->partype= PAROBJECT; - ob->parsubstr[0]= 0; - return; - } - - /* this could use some more checks */ - - ob->parent= par; - ob->partype &= ~PARTYPE; - ob->partype |= type; - BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr)); -} - -static int parent_set_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *par= CTX_data_active_object(C); - bPoseChannel *pchan= NULL; - int partype= RNA_enum_get(op->ptr, "type"); - int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); - - par->recalc |= OB_RECALC_OB; - - /* preconditions */ - if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) { - if(par->type!=OB_CURVE) - return OPERATOR_CANCELLED; - else { - Curve *cu= par->data; - - if((cu->flag & CU_PATH)==0) { - cu->flag |= CU_PATH|CU_FOLLOW; - makeDispListCurveTypes(scene, par, 0); /* force creation of path data */ - } - else cu->flag |= CU_FOLLOW; - - /* fall back on regular parenting now */ - partype= PAR_OBJECT; - } - } - else if(partype==PAR_BONE) { - pchan= get_active_posechannel(par); - - if(pchan==NULL) { - error("No active Bone"); - return OPERATOR_CANCELLED; - } - } - - /* context itterator */ - CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - - if(ob!=par) { - - if( test_parent_loop(par, ob) ) { - error("Loop in parents"); - } - else { - Object workob; - - /* apply transformation of previous parenting */ - ED_object_apply_obmat(ob); - - ob->parent= par; - - /* handle types */ - if (pchan) - strcpy (ob->parsubstr, pchan->name); - else - ob->parsubstr[0]= 0; - - /* constraint */ - if(partype==PAR_PATH_CONST) { - bConstraint *con; - bFollowPathConstraint *data; - float cmat[4][4], vec[3]; - - con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH); - strcpy (con->name, "AutoPath"); - - data = con->data; - data->tar = par; - - add_constraint_to_object(con, ob); - - get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob)); - VecSubf(vec, ob->obmat[3], cmat[3]); - - ob->loc[0] = vec[0]; - ob->loc[1] = vec[1]; - } - else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) { - if(partype == PAR_ARMATURE_NAME) - create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_NAME); - else if(partype == PAR_ARMATURE_ENVELOPE) - create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_ENVELOPE); - else if(partype == PAR_ARMATURE_AUTO) - create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_AUTO); - - /* get corrected inverse */ - ob->partype= PAROBJECT; - what_does_parent(scene, ob, &workob); - - ob->partype= PARSKEL; - - Mat4Invert(ob->parentinv, workob.obmat); - } - else { - /* calculate inverse parent matrix */ - what_does_parent(scene, ob, &workob); - Mat4Invert(ob->parentinv, workob.obmat); - } - - ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; - - if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) - ob->partype= PARSKEL; /* note, dna define, not operator property */ - else - ob->partype= PAROBJECT; /* note, dna define, not operator property */ - } - } - } - CTX_DATA_END; - - DAG_scene_sort(CTX_data_scene(C)); - ED_anim_dag_flush_update(C); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); - - return OPERATOR_FINISHED; -} - -static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - Object *ob= CTX_data_active_object(C); - uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", 0); - uiLayout *layout= uiPupMenuLayout(pup); - - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_OBJECT); - - /* ob becomes parent, make the associated menus */ - if(ob->type==OB_ARMATURE) { - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_NAME); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_ENVELOPE); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_AUTO); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_BONE); - } - else if(ob->type==OB_CURVE) { - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_CURVE); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_FOLLOW); - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_PATH_CONST); - } - else if(ob->type == OB_LATTICE) { - uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_LATTICE); - } - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - - -void OBJECT_OT_parent_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Make Parent"; - ot->description = "Set the object's parenting."; - ot->idname= "OBJECT_OT_parent_set"; - - /* api callbacks */ - ot->invoke= parent_set_invoke; - ot->exec= parent_set_exec; - - ot->poll= ED_operator_object_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); -} - -/* *** make track ***** */ -static EnumPropertyItem prop_make_track_types[] = { - {1, "TRACKTO", 0, "TrackTo Constraint", ""}, - {2, "LOCKTRACK", 0, "LockTrack Constraint", ""}, - {3, "OLDTRACK", 0, "Old Track", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int track_set_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - int type= RNA_enum_get(op->ptr, "type"); - - if(type == 1) { - bConstraint *con; - bTrackToConstraint *data; - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - if(base!=BASACT) { - con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO); - strcpy (con->name, "AutoTrack"); - - data = con->data; - data->tar = BASACT->object; - base->object->recalc |= OB_RECALC; - - /* Lamp and Camera track differently by default */ - if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { - data->reserved1 = TRACK_nZ; - data->reserved2 = UP_Y; - } - - add_constraint_to_object(con, base->object); - } - } - CTX_DATA_END; - } - else if(type == 2) { - bConstraint *con; - bLockTrackConstraint *data; - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - if(base!=BASACT) { - con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK); - strcpy (con->name, "AutoTrack"); - - data = con->data; - data->tar = BASACT->object; - base->object->recalc |= OB_RECALC; - - /* Lamp and Camera track differently by default */ - if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { - data->trackflag = TRACK_nZ; - data->lockflag = LOCK_Y; - } - - add_constraint_to_object(con, base->object); - } - } - CTX_DATA_END; - } - else { - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - if(base!=BASACT) { - base->object->track= BASACT->object; - base->object->recalc |= OB_RECALC; - } - } - CTX_DATA_END; - } - DAG_scene_sort(CTX_data_scene(C)); - ED_anim_dag_flush_update(C); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_track_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Make Track"; - ot->description = "Make the object track another object, either by constraint or old way or locked track."; - ot->idname= "OBJECT_OT_track_set"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= track_set_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", ""); -} - -/* ************* Make Dupli Real ********* */ -static void make_object_duplilist_real(Scene *scene, View3D *v3d, Base *base) -{ - Base *basen; - Object *ob; - ListBase *lb; - DupliObject *dob; - - if(!base && !(base = BASACT)) - return; - - if(!(base->object->transflag & OB_DUPLI)) - return; - - lb= object_duplilist(scene, base->object); - - for(dob= lb->first; dob; dob= dob->next) { - ob= copy_object(dob->ob); - /* font duplis can have a totcol without material, we get them from parent - * should be implemented better... - */ - if(ob->mat==NULL) ob->totcol= 0; - - basen= MEM_dupallocN(base); - basen->flag &= ~OB_FROMDUPLI; - BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */ - basen->object= ob; - ob->ipo= NULL; /* make sure apply works */ - ob->parent= ob->track= NULL; - ob->disp.first= ob->disp.last= NULL; - ob->transflag &= ~OB_DUPLI; - - Mat4CpyMat4(ob->obmat, dob->mat); - ED_object_apply_obmat(ob); - } - - copy_object_set_idnew(scene, v3d, 0); - - free_object_duplilist(lb); - - base->object->transflag &= ~OB_DUPLI; -} - - -static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= sa->spacedata.first; - - clear_id_newpoins(); - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - make_object_duplilist_real(scene, v3d, base); - } - CTX_DATA_END; - - DAG_scene_sort(CTX_data_scene(C)); - ED_anim_dag_flush_update(C); - WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C)); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Make Duplicates Real"; - ot->description = "Make dupli objects attached to this object real."; - ot->idname= "OBJECT_OT_duplicates_make_real"; - - /* api callbacks */ - ot->invoke= WM_operator_confirm; - ot->exec= object_duplicates_make_real_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} -/* ******************* Set Object Center ********************** */ - -static EnumPropertyItem prop_set_center_types[] = { - {0, "CENTER", 0, "ObData to Center", "Move object data around Object center"}, - {1, "CENTERNEW", 0, "Center New", "Move Object center to center of object data"}, - {2, "CENTERCURSOR", 0, "Center Cursor", "Move Object Center to position of the 3d cursor"}, - {0, NULL, 0, NULL, NULL} -}; - -/* 0 == do center, 1 == center new, 2 == center cursor */ -static int object_center_set_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= sa->spacedata.first; - Object *obedit= CTX_data_edit_object(C); - Object *ob; - Mesh *me, *tme; - Curve *cu; -/* BezTriple *bezt; - BPoint *bp; */ - Nurb *nu, *nu1; - EditVert *eve; - float cent[3], centn[3], min[3], max[3], omat[3][3]; - int a, total= 0; - int centermode = RNA_enum_get(op->ptr, "type"); - - /* keep track of what is changed */ - int tot_change=0, tot_lib_error=0, tot_multiuser_arm_error=0; - MVert *mvert; - - if(scene->id.lib || v3d==NULL){ - BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed on Lib data"); - return OPERATOR_CANCELLED; - } - if (obedit && centermode > 0) { - BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode"); - return OPERATOR_CANCELLED; - } - cent[0]= cent[1]= cent[2]= 0.0; - - if(obedit) { - - INIT_MINMAX(min, max); - - if(obedit->type==OB_MESH) { - Mesh *me= obedit->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - for(eve= em->verts.first; eve; eve= eve->next) { - if(v3d->around==V3D_CENTROID) { - total++; - VECADD(cent, cent, eve->co); - } - else { - DO_MINMAX(eve->co, min, max); - } - } - - if(v3d->around==V3D_CENTROID) { - VecMulf(cent, 1.0f/(float)total); - } - else { - cent[0]= (min[0]+max[0])/2.0f; - cent[1]= (min[1]+max[1])/2.0f; - cent[2]= (min[2]+max[2])/2.0f; - } - - for(eve= em->verts.first; eve; eve= eve->next) { - VecSubf(eve->co, eve->co, cent); - } - - recalc_editnormals(em); - tot_change++; - DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - BKE_mesh_end_editmesh(me, em); - } - } - - /* reset flags */ - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - base->object->flag &= ~OB_DONE; - } - CTX_DATA_END; - - for (me= G.main->mesh.first; me; me= me->id.next) { - me->flag &= ~ME_ISDONE; - } - - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - if((base->object->flag & OB_DONE)==0) { - base->object->flag |= OB_DONE; - - if(obedit==NULL && (me=get_mesh(base->object)) ) { - if (me->id.lib) { - tot_lib_error++; - } else { - if(centermode==2) { - VECCOPY(cent, give_cursor(scene, v3d)); - Mat4Invert(base->object->imat, base->object->obmat); - Mat4MulVecfl(base->object->imat, cent); - } else { - INIT_MINMAX(min, max); - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - DO_MINMAX(mvert->co, min, max); - } - - cent[0]= (min[0]+max[0])/2.0f; - cent[1]= (min[1]+max[1])/2.0f; - cent[2]= (min[2]+max[2])/2.0f; - } - - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - VecSubf(mvert->co, mvert->co, cent); - } - - if (me->key) { - KeyBlock *kb; - for (kb=me->key->block.first; kb; kb=kb->next) { - float *fp= kb->data; - - for (a=0; atotelem; a++, fp+=3) { - VecSubf(fp, fp, cent); - } - } - } - - me->flag |= ME_ISDONE; - - if(centermode) { - Mat3CpyMat4(omat, base->object->obmat); - - VECCOPY(centn, cent); - Mat3MulVecfl(omat, centn); - base->object->loc[0]+= centn[0]; - base->object->loc[1]+= centn[1]; - base->object->loc[2]+= centn[2]; - - where_is_object(scene, base->object); - ignore_parent_tx(scene, base->object); - - /* other users? */ - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - ob = base->object; - if((ob->flag & OB_DONE)==0) { - tme= get_mesh(ob); - - if(tme==me) { - - ob->flag |= OB_DONE; - ob->recalc= OB_RECALC_OB|OB_RECALC_DATA; - - Mat3CpyMat4(omat, ob->obmat); - VECCOPY(centn, cent); - Mat3MulVecfl(omat, centn); - ob->loc[0]+= centn[0]; - ob->loc[1]+= centn[1]; - ob->loc[2]+= centn[2]; - - where_is_object(scene, ob); - ignore_parent_tx(scene, ob); - - if(tme && (tme->flag & ME_ISDONE)==0) { - mvert= tme->mvert; - for(a=0; atotvert; a++, mvert++) { - VecSubf(mvert->co, mvert->co, cent); - } - - if (tme->key) { - KeyBlock *kb; - for (kb=tme->key->block.first; kb; kb=kb->next) { - float *fp= kb->data; - - for (a=0; atotelem; a++, fp+=3) { - VecSubf(fp, fp, cent); - } - } - } - - tme->flag |= ME_ISDONE; - } - } - } - - ob= ob->id.next; - } - CTX_DATA_END; - } - tot_change++; - } - } - else if (ELEM(base->object->type, OB_CURVE, OB_SURF)) { - - /* weak code here... (ton) */ - if(obedit==base->object) { - ListBase *editnurb= curve_get_editcurve(obedit); - - nu1= editnurb->first; - cu= obedit->data; - } - else { - cu= base->object->data; - nu1= cu->nurb.first; - } - - if (cu->id.lib) { - tot_lib_error++; - } else { - if(centermode==2) { - VECCOPY(cent, give_cursor(scene, v3d)); - Mat4Invert(base->object->imat, base->object->obmat); - Mat4MulVecfl(base->object->imat, cent); - - /* don't allow Z change if curve is 2D */ - if( !( cu->flag & CU_3D ) ) - cent[2] = 0.0; - } - else { - INIT_MINMAX(min, max); - - nu= nu1; - while(nu) { - minmaxNurb(nu, min, max); - nu= nu->next; - } - - cent[0]= (min[0]+max[0])/2.0f; - cent[1]= (min[1]+max[1])/2.0f; - cent[2]= (min[2]+max[2])/2.0f; - } - - nu= nu1; - while(nu) { - if(nu->type == CU_BEZIER) { - a= nu->pntsu; - while (a--) { - VecSubf(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent); - VecSubf(nu->bezt[a].vec[1], nu->bezt[a].vec[1], cent); - VecSubf(nu->bezt[a].vec[2], nu->bezt[a].vec[2], cent); - } - } - else { - a= nu->pntsu*nu->pntsv; - while (a--) - VecSubf(nu->bp[a].vec, nu->bp[a].vec, cent); - } - nu= nu->next; - } - - if(centermode && obedit==0) { - Mat3CpyMat4(omat, base->object->obmat); - - Mat3MulVecfl(omat, cent); - base->object->loc[0]+= cent[0]; - base->object->loc[1]+= cent[1]; - base->object->loc[2]+= cent[2]; - - where_is_object(scene, base->object); - ignore_parent_tx(scene, base->object); - } - - tot_change++; - if(obedit) { - if (centermode==0) { - DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - } - break; - } - } - } - else if(base->object->type==OB_FONT) { - /* get from bb */ - - cu= base->object->data; - - if(cu->bb==0) { - /* do nothing*/ - } else if (cu->id.lib) { - tot_lib_error++; - } else { - cu->xof= -0.5f*( cu->bb->vec[4][0] - cu->bb->vec[0][0]); - cu->yof= -0.5f -0.5f*( cu->bb->vec[0][1] - cu->bb->vec[2][1]); /* extra 0.5 is the height o above line */ - - /* not really ok, do this better once! */ - cu->xof /= cu->fsize; - cu->yof /= cu->fsize; - - tot_change++; - } - } - else if(base->object->type==OB_ARMATURE) { - bArmature *arm = base->object->data; - - if (arm->id.lib) { - tot_lib_error++; - } else if(arm->id.us>1) { - /*error("Can't apply to a multi user armature"); - return;*/ - tot_multiuser_arm_error++; - } else { - /* Function to recenter armatures in editarmature.c - * Bone + object locations are handled there. - */ - docenter_armature(scene, v3d, base->object, centermode); - tot_change++; - - where_is_object(scene, base->object); - ignore_parent_tx(scene, base->object); - - if(obedit) - break; - } - } - base->object->recalc= OB_RECALC_OB|OB_RECALC_DATA; - } - } - CTX_DATA_END; - - if (tot_change) { - ED_anim_dag_flush_update(C); - } - - /* Warn if any errors occured */ - if (tot_lib_error+tot_multiuser_arm_error) { - BKE_reportf(op->reports, RPT_WARNING, "%i Object(s) Not Centered, %i Changed:",tot_lib_error+tot_multiuser_arm_error, tot_change); - if (tot_lib_error) - BKE_reportf(op->reports, RPT_WARNING, "|%i linked library objects",tot_lib_error); - if (tot_multiuser_arm_error) - BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)",tot_multiuser_arm_error); - } - - return OPERATOR_FINISHED; -} -void OBJECT_OT_center_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Set Center"; - ot->description = "Set the object's center, by either moving the data, or set to center of data, or use 3d cursor"; - ot->idname= "OBJECT_OT_center_set"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_center_set_exec; - - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", ""); -} -/* ******************* toggle editmode operator ***************** */ - -void ED_object_exit_editmode(bContext *C, int flag) -{ - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - int freedata = flag & EM_FREEDATA; - - if(obedit==NULL) return; - - if(flag & EM_WAITCURSOR) waitcursor(1); - if(obedit->type==OB_MESH) { - Mesh *me= obedit->data; - -// if(EM_texFaceCheck()) - -// if(retopo_mesh_paint_check()) -// retopo_end_okee(); - - if(me->edit_mesh->totvert>MESH_MAX_VERTS) { - error("Too many vertices"); - return; - } - load_editMesh(scene, obedit); - - if(freedata) { - free_editMesh(me->edit_mesh); - MEM_freeN(me->edit_mesh); - me->edit_mesh= NULL; - } - - if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT) - mesh_octree_table(obedit, NULL, NULL, 'e'); - } - else if (obedit->type==OB_ARMATURE) { - ED_armature_from_edit(scene, obedit); - if(freedata) - ED_armature_edit_free(obedit); - } - else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { - load_editNurb(obedit); - if(freedata) free_editNurb(obedit); - } - else if(obedit->type==OB_FONT && freedata) { - load_editText(obedit); - if(freedata) free_editText(obedit); - } - else if(obedit->type==OB_LATTICE) { - load_editLatt(obedit); - if(freedata) free_editLatt(obedit); - } - else if(obedit->type==OB_MBALL) { - load_editMball(obedit); - if(freedata) free_editMball(obedit); - } - - /* freedata only 0 now on file saves */ - if(freedata) { - /* for example; displist make is different in editmode */ - scene->obedit= NULL; // XXX for context - - BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH); - - /* also flush ob recalc, doesn't take much overhead, but used for particles */ - DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); - - ED_undo_push(C, "Editmode"); - - if(flag & EM_WAITCURSOR) waitcursor(0); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); - } - - obedit->mode &= ~OB_MODE_EDIT; - ED_object_toggle_modes(C, obedit->restore_mode); -} - - -void ED_object_enter_editmode(bContext *C, int flag) -{ - Scene *scene= CTX_data_scene(C); - Base *base= CTX_data_active_base(C); - Object *ob; - ScrArea *sa= CTX_wm_area(C); - View3D *v3d= NULL; - int ok= 0; - - if(scene->id.lib) return; - if(base==NULL) return; - - if(sa && sa->spacetype==SPACE_VIEW3D) - v3d= sa->spacedata.first; - - if(v3d && (base->lay & v3d->lay)==0) return; - else if(!v3d && (base->lay & scene->lay)==0) return; - - ob = base->object; - - if(ob==NULL) return; - if(ob->data==NULL) return; - - if (object_data_is_libdata(ob)) { - error_libdata(); - return; - } - - if(flag & EM_WAITCURSOR) waitcursor(1); - - ob->restore_mode = ob->mode; - ED_object_toggle_modes(C, ob->mode); - - ob->mode |= OB_MODE_EDIT; - - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - - if(me->pv) mesh_pmv_off(ob, me); - ok= 1; - scene->obedit= ob; // context sees this - - make_editMesh(scene, ob); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene); - } - else if (ob->type==OB_ARMATURE){ - bArmature *arm= base->object->data; - if (!arm) return; - /* - * The function object_data_is_libdata make a problem here, the - * check for ob->proxy return 0 and let blender enter to edit mode - * this causa a crash when you try leave the edit mode. - * The problem is that i can't remove the ob->proxy check from - * object_data_is_libdata that prevent the bugfix #6614, so - * i add this little hack here. - */ - if(arm->id.lib) { - error_libdata(); - return; - } - ok=1; - scene->obedit= ob; - ED_armature_to_edit(ob); - /* to ensure all goes in restposition and without striding */ - DAG_id_flush_update(&ob->id, OB_RECALC); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene); - } - else if(ob->type==OB_FONT) { - scene->obedit= ob; // XXX for context - ok= 1; - make_editText(ob); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene); - } - else if(ob->type==OB_MBALL) { - scene->obedit= ob; // XXX for context - ok= 1; - make_editMball(ob); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, scene); - } - else if(ob->type==OB_LATTICE) { - scene->obedit= ob; // XXX for context - ok= 1; - make_editLatt(ob); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, scene); - } - else if(ob->type==OB_SURF || ob->type==OB_CURVE) { - ok= 1; - scene->obedit= ob; // XXX for context - make_editNurb(ob); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, scene); - } - - if(ok) { - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - else { - scene->obedit= NULL; // XXX for context - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); - } - - if(flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode"); - if(flag & EM_WAITCURSOR) waitcursor(0); -} - -static int editmode_toggle_exec(bContext *C, wmOperator *op) -{ - - if(!CTX_data_edit_object(C)) - ED_object_enter_editmode(C, EM_WAITCURSOR); - else - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); - - return OPERATOR_FINISHED; -} - -static int editmode_toggle_poll(bContext *C) -{ - Object *ob = CTX_data_active_object(C); - - return ob && (ob->type == OB_MESH || ob->type == OB_ARMATURE || - ob->type == OB_FONT || ob->type == OB_MBALL || - ob->type == OB_LATTICE || ob->type == OB_SURF || - ob->type == OB_CURVE); -} - -void OBJECT_OT_editmode_toggle(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name= "Toggle Editmode"; - ot->description = "Toggle object's editmode."; - ot->idname= "OBJECT_OT_editmode_toggle"; - - /* api callbacks */ - ot->exec= editmode_toggle_exec; - - ot->poll= editmode_toggle_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* *************************** */ - -static int posemode_exec(bContext *C, wmOperator *op) -{ - Base *base= CTX_data_active_base(C); - - if(base->object->type==OB_ARMATURE) { - if(base->object==CTX_data_edit_object(C)) { - ED_object_exit_editmode(C, EM_FREEDATA); - ED_armature_enter_posemode(C, base); - } - else if(base->object->mode & OB_MODE_POSE) - ED_armature_exit_posemode(C, base); - else - ED_armature_enter_posemode(C, base); - - return OPERATOR_FINISHED; - } - - return OPERATOR_PASS_THROUGH; -} - -void OBJECT_OT_posemode_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Pose Mode"; - ot->idname= "OBJECT_OT_posemode_toggle"; - ot->description= "Enables or disables posing/selecting bones"; - - /* api callbacks */ - ot->exec= posemode_exec; - ot->poll= ED_operator_object_active; - - /* flag */ - ot->flag= OPTYPE_REGISTER; -} - -/* *********************** */ - -void check_editmode(int type) -{ - Object *obedit= NULL; // XXX - - if (obedit==NULL || obedit->type==type) return; - -// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ -} -void movetolayer(Scene *scene, View3D *v3d) -{ - Base *base; - unsigned int lay= 0, local; - int islamp= 0; - - if(scene->id.lib) return; - - for(base= FIRSTBASE; base; base= base->next) { - if (TESTBASE(v3d, base)) lay |= base->lay; - } - if(lay==0) return; - lay &= 0xFFFFFF; - - if(lay==0) return; - - if(v3d->localview) { - /* now we can move out of localview. */ - if (!okee("Move from localview")) return; - for(base= FIRSTBASE; base; base= base->next) { - if (TESTBASE(v3d, base)) { - lay= base->lay & ~v3d->lay; - base->lay= lay; - base->object->lay= lay; - base->object->flag &= ~SELECT; - base->flag &= ~SELECT; - if(base->object->type==OB_LAMP) islamp= 1; - } - } - } else { -// XXX if( movetolayer_buts(&lay, NULL)==0 ) return; - - /* normal non localview operation */ - for(base= FIRSTBASE; base; base= base->next) { - if (TESTBASE(v3d, base)) { - /* upper byte is used for local view */ - local= base->lay & 0xFF000000; - base->lay= lay + local; - base->object->lay= lay; - if(base->object->type==OB_LAMP) islamp= 1; - } - } - } - if(islamp) reshadeall_displist(scene); /* only frees */ - - /* warning, active object may be hidden now */ - - DAG_scene_sort(scene); - -} - - -#if 0 -// XXX should be in view3d? - -/* context: ob = lamp */ -/* code should be replaced with proper (custom) transform handles for lamp properties */ -static void spot_interactive(Object *ob, int mode) -{ - Lamp *la= ob->data; - float transfac, dx, dy, ratio, origval; - int keep_running= 1, center2d[2]; - short mval[2], mvalo[2]; - -// getmouseco_areawin(mval); -// getmouseco_areawin(mvalo); - - project_int(ob->obmat[3], center2d); - if( center2d[0] > 100000 ) { /* behind camera */ -// center2d[0]= curarea->winx/2; -// center2d[1]= curarea->winy/2; - } - -// helpline(mval, center2d); - - /* ratio is like scaling */ - dx = (float)(center2d[0] - mval[0]); - dy = (float)(center2d[1] - mval[1]); - transfac = (float)sqrt( dx*dx + dy*dy); - if(transfac==0.0f) transfac= 1.0f; - - if(mode==1) - origval= la->spotsize; - else if(mode==2) - origval= la->dist; - else if(mode==3) - origval= la->clipsta; - else - origval= la->clipend; - - while (keep_running>0) { - -// getmouseco_areawin(mval); - - /* essential for idling subloop */ - if(mval[0]==mvalo[0] && mval[1]==mvalo[1]) { - PIL_sleep_ms(2); - } - else { - char str[32]; - - dx = (float)(center2d[0] - mval[0]); - dy = (float)(center2d[1] - mval[1]); - ratio = (float)(sqrt( dx*dx + dy*dy))/transfac; - - /* do the trick */ - - if(mode==1) { /* spot */ - la->spotsize = ratio*origval; - CLAMP(la->spotsize, 1.0f, 180.0f); - sprintf(str, "Spot size %.2f\n", la->spotsize); - } - else if(mode==2) { /* dist */ - la->dist = ratio*origval; - CLAMP(la->dist, 0.01f, 5000.0f); - sprintf(str, "Distance %.2f\n", la->dist); - } - else if(mode==3) { /* sta */ - la->clipsta = ratio*origval; - CLAMP(la->clipsta, 0.001f, 5000.0f); - sprintf(str, "Distance %.2f\n", la->clipsta); - } - else if(mode==4) { /* end */ - la->clipend = ratio*origval; - CLAMP(la->clipend, 0.1f, 5000.0f); - sprintf(str, "Clip End %.2f\n", la->clipend); - } - - /* cleanup */ - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - - /* handle shaded mode */ -// XXX shade_buttons_change_3d(); - - /* DRAW */ - headerprint(str); - force_draw_plus(SPACE_BUTS, 0); - -// helpline(mval, center2d); - } - - while( qtest() ) { - short val; - unsigned short event= extern_qread(&val); - - switch (event){ - case ESCKEY: - case RIGHTMOUSE: - keep_running= 0; - break; - case LEFTMOUSE: - case SPACEKEY: - case PADENTER: - case RETKEY: - if(val) - keep_running= -1; - break; - } - } - } - - if(keep_running==0) { - if(mode==1) - la->spotsize= origval; - else if(mode==2) - la->dist= origval; - else if(mode==3) - la->clipsta= origval; - else - la->clipend= origval; - } - -} -#endif - -void special_editmenu(Scene *scene, View3D *v3d) -{ -// XXX static short numcuts= 2; - Object *ob= OBACT; - Object *obedit= NULL; // XXX - int nr,ret=0; - - if(ob==NULL) return; - - if(obedit==NULL) { - - if(ob->mode & OB_MODE_POSE) { -// XXX pose_special_editmenu(); - } - else if(paint_facesel_test(ob)) { - Mesh *me= get_mesh(ob); - MTFace *tface; - MFace *mface; - int a; - - if(me==0 || me->mtface==0) return; - - nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5| TwoSide%x6|Clr Tex%x7| Shared%x8| Light%x9| Invisible%x10| Collision%x11| TwoSide%x12"); - - tface= me->mtface; - mface= me->mface; - for(a=me->totface; a>0; a--, tface++, mface++) { - if(mface->flag & ME_FACE_SEL) { - switch(nr) { - case 1: - tface->mode |= TF_TEX; break; - case 2: - tface->mode |= TF_SHAREDCOL; break; - case 3: - tface->mode |= TF_LIGHT; break; - case 4: - tface->mode |= TF_INVISIBLE; break; - case 5: - tface->mode |= TF_DYNAMIC; break; - case 6: - tface->mode |= TF_TWOSIDE; break; - case 7: - tface->mode &= ~TF_TEX; - tface->tpage= 0; - break; - case 8: - tface->mode &= ~TF_SHAREDCOL; break; - case 9: - tface->mode &= ~TF_LIGHT; break; - case 10: - tface->mode &= ~TF_INVISIBLE; break; - case 11: - tface->mode &= ~TF_DYNAMIC; break; - case 12: - tface->mode &= ~TF_TWOSIDE; break; - } - } - } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - else if(ob->mode & OB_MODE_VERTEX_PAINT) { - Mesh *me= get_mesh(ob); - - if(me==0 || (me->mcol==NULL && me->mtface==NULL) ) return; - - nr= pupmenu("Specials%t|Shared VertexCol%x1"); - if(nr==1) { - -// XXX do_shared_vertexcol(me); - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } - else if(ob->mode & OB_MODE_WEIGHT_PAINT) { - Object *par= modifiers_isDeformedByArmature(ob); - - if(par && (par->mode & OB_MODE_POSE)) { - nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2"); - -// XXX if(nr==1 || nr==2) -// XXX pose_adds_vgroups(ob, (nr == 2)); - } - } - else if(ob->mode & OB_MODE_PARTICLE_EDIT) { -#if 0 - // XXX - ParticleSystem *psys = PE_get_current(ob); - ParticleEditSettings *pset = PE_settings(); - - if(!psys) - return; - - if(pset->selectmode & SCE_SELECT_POINT) - nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5"); - else - nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5"); - - switch(nr) { - case 1: -// XXX if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return; - waitcursor(1); - PE_rekey(); - break; - case 2: - PE_subdivide(); - break; - case 3: - PE_select_root(); - break; - case 4: - PE_select_tip(); - break; - case 5: - PE_remove_doubles(); - break; - } - - DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - if(nr>0) waitcursor(0); -#endif - } - else { - Base *base, *base_select= NULL; - - /* Get the active object mesh. */ - Mesh *me= get_mesh(ob); - - /* Booleans, if the active object is a mesh... */ - if (me && ob->id.lib==NULL) { - - /* Bring up a little menu with the boolean operation choices on. */ - nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6"); - - if (nr > 0) { - /* user has made a choice of a menu element. - All of the boolean functions require 2 mesh objects - we search through the object list to find the other - selected item and make sure it is distinct and a mesh. */ - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base->object != ob) base_select= base; - } - } - - if (base_select) { - if (get_mesh(base_select->object)) { - if(nr <= 3){ - waitcursor(1); -// XXX ret = NewBooleanMesh(BASACT,base_select,nr); - if (ret==0) { - error("An internal error occurred"); - } else if(ret==-1) { - error("Selected meshes must have faces to perform boolean operations"); - } else if (ret==-2) { - error("Both meshes must be a closed mesh"); - } - waitcursor(0); - } else { - BooleanModifierData *bmd = NULL; - bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean); - BLI_addtail(&ob->modifiers, bmd); - bmd->object = base_select->object; - bmd->modifier.mode |= eModifierMode_Realtime; - switch(nr){ - case 4: bmd->operation = eBooleanModifierOp_Intersect; break; - case 5: bmd->operation = eBooleanModifierOp_Union; break; - case 6: bmd->operation = eBooleanModifierOp_Difference; break; - } -// XXX do_common_editbuts(B_CHANGEDEP); - } - } else { - error("Please select 2 meshes"); - } - } else { - error("Please select 2 meshes"); - } - } - - } - else if (ob->type == OB_FONT) { - /* removed until this gets a decent implementation (ton) */ -/* nr= pupmenu("Split %t|Characters%x1"); - if (nr > 0) { - switch(nr) { - case 1: split_font(); - } - } -*/ - } - } - } - else if(obedit->type==OB_MESH) { - } - else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { - } - else if(obedit->type==OB_ARMATURE) { - nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6"); -// if(nr==1) -// XXX subdivide_armature(1); - if(nr==2) { -// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; - waitcursor(1); -// XXX subdivide_armature(numcuts); - } -// else if(nr==3) -// XXX armature_flip_names(); - else if(ELEM3(nr, 4, 5, 6)) { -// XXX armature_autoside_names(nr-4); - } -// else if(nr == 7) -// XXX switch_direction_armature(); - } - else if(obedit->type==OB_LATTICE) { - Lattice *lt= obedit->data; - static float weight= 1.0f; - { // XXX -// XXX if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) { - int a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; - BPoint *bp= lt->editlatt->def; - - while(a--) { - if(bp->f1 & SELECT) - bp->weight= weight; - bp++; - } - } - } - -} - -static void curvetomesh(Scene *scene, Object *ob) -{ - Curve *cu; - DispList *dl; - - ob->flag |= OB_DONE; - cu= ob->data; - - dl= cu->disp.first; - if(dl==0) makeDispListCurveTypes(scene, ob, 0); /* force creation */ - - nurbs_to_mesh(ob); /* also does users */ - if (ob->type != OB_MESH) { - error("can't convert curve to mesh"); - } else { - object_free_modifiers(ob); - } -} - -void convertmenu(Scene *scene, View3D *v3d) -{ - Base *base, *basen=NULL, *basact, *basedel=NULL; - Object *obact, *ob, *ob1; - Object *obedit= NULL; // XXX - Curve *cu; - Nurb *nu; - MetaBall *mb; - Mesh *me; - int ok=0, nr = 0, a; - - if(scene->id.lib) return; - - obact= OBACT; - if (obact == NULL) return; - if(!obact->flag & SELECT) return; - if(obedit) return; - - basact= BASACT; /* will be restored */ - - if(obact->type==OB_FONT) { - nr= pupmenu("Convert Font to%t|Curve%x1|Curve (Single filling group)%x2|Mesh%x3"); - if(nr>0) ok= 1; - } - else if(obact->type==OB_MBALL) { - nr= pupmenu("Convert Metaball to%t|Mesh (keep original)%x1|Mesh (Delete Original)%x2"); - if(nr>0) ok= 1; - } - else if(obact->type==OB_CURVE) { - nr= pupmenu("Convert Curve to%t|Mesh"); - if(nr>0) ok= 1; - } - else if(obact->type==OB_SURF) { - nr= pupmenu("Convert Nurbs Surface to%t|Mesh"); - if(nr>0) ok= 1; - } - else if(obact->type==OB_MESH) { - nr= pupmenu("Convert Modifiers to%t|Mesh (Keep Original)%x1|Mesh (Delete Original)%x2"); - if(nr>0) ok= 1; - } - if(ok==0) return; - - /* don't forget multiple users! */ - - /* reset flags */ - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - base->object->flag &= ~OB_DONE; - } - } - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - - ob= base->object; - - if(ob->flag & OB_DONE); - else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ - DerivedMesh *dm; - - basedel = base; - - ob->flag |= OB_DONE; - - ob1= copy_object(ob); - ob1->recalc |= OB_RECALC; - - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ - basen->object= ob1; - basen->flag |= SELECT; - base->flag &= ~SELECT; - ob->flag &= ~SELECT; - - /* decrement original mesh's usage count */ - me= ob1->data; - me->id.us--; - - /* make a new copy of the mesh */ - ob1->data= copy_mesh(me); - - /* make new mesh data from the original copy */ - dm= mesh_get_derived_final(scene, ob1, CD_MASK_MESH); - /* dm= mesh_create_derived_no_deform(ob1, NULL); this was called original (instead of get_derived). man o man why! (ton) */ - - DM_to_mesh(dm, ob1->data); - - dm->release(dm); - object_free_modifiers(ob1); /* after derivedmesh calls! */ - - /* If the original object is active then make this object active */ - if (ob == obact) { - // XXX ED_base_object_activate(C, basen); - basact = basen; - } - } - else if(ob->type==OB_FONT) { - ob->flag |= OB_DONE; - - ob->type= OB_CURVE; - cu= ob->data; - - if(cu->vfont) { - cu->vfont->id.us--; - cu->vfont= 0; - } - if(cu->vfontb) { - cu->vfontb->id.us--; - cu->vfontb= 0; - } - if(cu->vfonti) { - cu->vfonti->id.us--; - cu->vfonti= 0; - } - if(cu->vfontbi) { - cu->vfontbi->id.us--; - cu->vfontbi= 0; - } - /* other users */ - if(cu->id.us>1) { - ob1= G.main->object.first; - while(ob1) { - if(ob1->data==cu) { - ob1->type= OB_CURVE; - ob1->recalc |= OB_RECALC; - } - ob1= ob1->id.next; - } - } - if (nr==2 || nr==3) { - nu= cu->nurb.first; - while(nu) { - nu->charidx= 0; - nu= nu->next; - } - } - if (nr==3) { - curvetomesh(scene, ob); - } - } - else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { - if(nr==1) { - curvetomesh(scene, ob); - } - } - else if(ob->type==OB_MBALL) { - - if(nr==1 || nr == 2) { - ob= find_basis_mball(scene, ob); - - if(ob->disp.first && !(ob->flag&OB_DONE)) { - basedel = base; - - ob->flag |= OB_DONE; - - ob1= copy_object(ob); - ob1->recalc |= OB_RECALC; - - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: othwise eternal loop */ - basen->object= ob1; - basen->flag |= SELECT; - basedel->flag &= ~SELECT; - ob->flag &= ~SELECT; - - mb= ob1->data; - mb->id.us--; - - ob1->data= add_mesh("Mesh"); - ob1->type= OB_MESH; - - me= ob1->data; - me->totcol= mb->totcol; - if(ob1->totcol) { - me->mat= MEM_dupallocN(mb->mat); - for(a=0; atotcol; a++) id_us_plus((ID *)me->mat[a]); - } - - mball_to_mesh(&ob->disp, ob1->data); - - /* So we can see the wireframe */ - BASACT= basen; - - /* If the original object is active then make this object active */ - if (ob == obact) { - // XXX ED_base_object_activate(C, basen); - basact = basen; - } - - } - } - } - } - if(basedel != NULL && nr == 2) { - ED_base_object_free_and_unlink(scene, basedel); - } - basedel = NULL; - } - - /* delete object should renew depsgraph */ - if(nr==2) - DAG_scene_sort(scene); - - /* texspace and normals */ - if(!basen) BASACT= base; - -// XXX ED_object_enter_editmode(C, 0); -// XXX exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ - BASACT= basact; - - - DAG_scene_sort(scene); -} - -/* Change subdivision or particle properties of mesh object ob, if level==-1 - * then toggle subsurf, else set to level set allows to toggle multiple - * selections */ - -static void object_has_subdivision_particles(Object *ob, int *havesubdiv, int *havepart, int depth) -{ - if(ob->type==OB_MESH) { - if(modifiers_findByType(ob, eModifierType_Subsurf)) - *havesubdiv= 1; - if(modifiers_findByType(ob, eModifierType_ParticleSystem)) - *havepart= 1; - } - - if(ob->dup_group && depth <= 4) { - GroupObject *go; - - for(go= ob->dup_group->gobject.first; go; go= go->next) - object_has_subdivision_particles(go->ob, havesubdiv, havepart, depth+1); - } -} - -static void object_flip_subdivison_particles(Scene *scene, Object *ob, int *set, int level, int mode, int particles, int depth) -{ - ModifierData *md; - - if(ob->type==OB_MESH) { - if(particles) { - for(md=ob->modifiers.first; md; md=md->next) { - if(md->type == eModifierType_ParticleSystem) { - ParticleSystemModifierData *psmd = (ParticleSystemModifierData*)md; - - if(*set == -1) - *set= psmd->modifier.mode&(mode); - - if (*set) - psmd->modifier.mode &= ~(mode); - else - psmd->modifier.mode |= (mode); - } - } - } - else { - md = modifiers_findByType(ob, eModifierType_Subsurf); - - if (md) { - SubsurfModifierData *smd = (SubsurfModifierData*) md; - - if (level == -1) { - if(*set == -1) - *set= smd->modifier.mode&(mode); - - if (*set) - smd->modifier.mode &= ~(mode); - else - smd->modifier.mode |= (mode); - } else { - smd->levels = level; - } - } - else if(depth == 0 && *set != 0) { - SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf); - - BLI_addtail(&ob->modifiers, smd); - - if (level!=-1) { - smd->levels = level; - } - - if(*set == -1) - *set= 1; - } - } - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - - if(ob->dup_group && depth<=4) { - GroupObject *go; - - for(go= ob->dup_group->gobject.first; go; go= go->next) - object_flip_subdivison_particles(scene, go->ob, set, level, mode, particles, depth+1); - } -} - -/* Change subdivision properties of mesh object ob, if -* level==-1 then toggle subsurf, else set to level. -*/ - -void flip_subdivison(Scene *scene, View3D *v3d, int level) -{ - Base *base; - int set= -1; - int mode, pupmode, particles= 0, havesubdiv= 0, havepart= 0; - int alt= 0; // XXX - - if(alt) - mode= eModifierMode_Realtime; - else - mode= eModifierMode_Render|eModifierMode_Realtime; - - if(level == -1) { - if (scene->obedit) { // XXX get from context - object_has_subdivision_particles(scene->obedit, &havesubdiv, &havepart, 0); - } else { - for(base= scene->base.first; base; base= base->next) { - if(((level==-1) && (TESTBASE(v3d, base))) || (TESTBASELIB(v3d, base))) { - object_has_subdivision_particles(base->object, &havesubdiv, &havepart, 0); - } - } - } - } - else - havesubdiv= 1; - - if(havesubdiv && havepart) { - pupmode= pupmenu("Switch%t|Subsurf %x1|Particle Systems %x2"); - if(pupmode <= 0) - return; - else if(pupmode == 2) - particles= 1; - } - else if(havepart) - particles= 1; - - if (scene->obedit) { // XXX get from context - object_flip_subdivison_particles(scene, scene->obedit, &set, level, mode, particles, 0); - } else { - for(base= scene->base.first; base; base= base->next) { - if(((level==-1) && (TESTBASE(v3d, base))) || (TESTBASELIB(v3d, base))) { - object_flip_subdivison_particles(scene, base->object, &set, level, mode, particles, 0); - } - } - } - - ED_anim_dag_flush_update(C); -} - -static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) -{ - bProperty *prop; - Base *base; - int nr, tot=0; - char *str; - - prop= ob->prop.first; - while(prop) { - tot++; - prop= prop->next; - } - - str= MEM_callocN(50 + 33*tot, "copymenu prop"); - - if (tot) - strcpy(str, "Copy Property %t|Replace All|Merge All|%l"); - else - strcpy(str, "Copy Property %t|Clear All (no properties on active)"); - - tot= 0; - prop= ob->prop.first; - while(prop) { - tot++; - strcat(str, "|"); - strcat(str, prop->name); - prop= prop->next; - } - - nr= pupmenu(str); - - if ( nr==1 || nr==2 ) { - for(base= FIRSTBASE; base; base= base->next) { - if((base != BASACT) &&(TESTBASELIB(v3d, base))) { - if (nr==1) { /* replace */ - copy_properties( &base->object->prop, &ob->prop ); - } else { - for(prop = ob->prop.first; prop; prop= prop->next ) { - set_ob_property(base->object, prop); - } - } - } - } - } else if(nr>0) { - prop = BLI_findlink(&ob->prop, nr-4); /* account for first 3 menu items & menu index starting at 1*/ - - if(prop) { - for(base= FIRSTBASE; base; base= base->next) { - if((base != BASACT) &&(TESTBASELIB(v3d, base))) { - set_ob_property(base->object, prop); - } - } - } - } - MEM_freeN(str); - -} - -static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) -{ - Base *base; - - for(base= FIRSTBASE; base; base= base->next) { - if(base->object != ob) { - if(TESTBASELIB(v3d, base)) { - - /* first: free all logic */ - free_sensors(&base->object->sensors); - unlink_controllers(&base->object->controllers); - free_controllers(&base->object->controllers); - unlink_actuators(&base->object->actuators); - free_actuators(&base->object->actuators); - - /* now copy it, this also works without logicbricks! */ - clear_sca_new_poins_ob(ob); - copy_sensors(&base->object->sensors, &ob->sensors); - copy_controllers(&base->object->controllers, &ob->controllers); - copy_actuators(&base->object->actuators, &ob->actuators); - set_sca_new_poins_ob(base->object); - - /* some menu settings */ - base->object->scavisflag= ob->scavisflag; - base->object->scaflag= ob->scaflag; - - /* set the initial state */ - base->object->state= ob->state; - base->object->init_state= ob->init_state; - } - } - } -} - -static void copymenu_modifiers(Scene *scene, View3D *v3d, Object *ob) -{ - Base *base; - int i, event; - char str[512]; - char *errorstr= NULL; - - strcpy(str, "Copy Modifiers %t"); - - sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES); - - for (i=eModifierType_None+1; iflags&eModifierTypeFlag_AcceptsCVs) || - (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { - sprintf(str+strlen(str), "|%s%%x%d", mti->name, i); - } - } - - event = pupmenu(str); - if(event<=0) return; - - for (base= FIRSTBASE; base; base= base->next) { - if(base->object != ob) { - if(TESTBASELIB(v3d, base)) { - ModifierData *md; - - base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA; - - if (base->object->type==ob->type) { - /* copy all */ - if (event==NUM_MODIFIER_TYPES) { - object_free_modifiers(base->object); - - for (md=ob->modifiers.first; md; md=md->next) { - ModifierData *nmd = NULL; - - if(ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue; - - if(md->type == eModifierType_Collision) - continue; - - nmd = modifier_new(md->type); - modifier_copyData(md, nmd); - BLI_addtail(&base->object->modifiers, nmd); - } - - copy_object_particlesystems(base->object, ob); - copy_object_softbody(base->object, ob); - } else { - /* copy specific types */ - ModifierData *md, *mdn; - - /* remove all with type 'event' */ - for (md=base->object->modifiers.first; md; md=mdn) { - mdn= md->next; - if(md->type==event) { - BLI_remlink(&base->object->modifiers, md); - modifier_free(md); - } - } - - /* copy all with type 'event' */ - for (md=ob->modifiers.first; md; md=md->next) { - if (md->type==event) { - - mdn = modifier_new(event); - BLI_addtail(&base->object->modifiers, mdn); - - modifier_copyData(md, mdn); - } - } - - if(event == eModifierType_ParticleSystem) { - object_free_particlesystems(base->object); - copy_object_particlesystems(base->object, ob); - } - else if(event == eModifierType_Softbody) { - object_free_softbody(base->object); - copy_object_softbody(base->object, ob); - } - } - } - else - errorstr= "Did not copy modifiers to other Object types"; - } - } - } - -// if(errorstr) notice(errorstr); - - DAG_scene_sort(scene); - -} - -/* both pointers should exist */ -static void copy_texture_space(Object *to, Object *ob) -{ - float *poin1= NULL, *poin2= NULL; - int texflag= 0; - - if(ob->type==OB_MESH) { - texflag= ((Mesh *)ob->data)->texflag; - poin2= ((Mesh *)ob->data)->loc; - } - else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - texflag= ((Curve *)ob->data)->texflag; - poin2= ((Curve *)ob->data)->loc; - } - else if(ob->type==OB_MBALL) { - texflag= ((MetaBall *)ob->data)->texflag; - poin2= ((MetaBall *)ob->data)->loc; - } - else - return; - - if(to->type==OB_MESH) { - ((Mesh *)to->data)->texflag= texflag; - poin1= ((Mesh *)to->data)->loc; - } - else if (ELEM3(to->type, OB_CURVE, OB_SURF, OB_FONT)) { - ((Curve *)to->data)->texflag= texflag; - poin1= ((Curve *)to->data)->loc; - } - else if(to->type==OB_MBALL) { - ((MetaBall *)to->data)->texflag= texflag; - poin1= ((MetaBall *)to->data)->loc; - } - else - return; - - memcpy(poin1, poin2, 9*sizeof(float)); /* this was noted in DNA_mesh, curve, mball */ - - if(to->type==OB_MESH) ; - else if(to->type==OB_MBALL) tex_space_mball(to); - else tex_space_curve(to->data); - -} - -void copy_attr(Scene *scene, View3D *v3d, short event) -{ - Object *ob; - Base *base; - Curve *cu, *cu1; - Nurb *nu; - int do_scene_sort= 0; - - if(scene->id.lib) return; - - if(!(ob=OBACT)) return; - - if(scene->obedit) { // XXX get from context - /* obedit_copymenu(); */ - return; - } - if(event==9) { - copymenu_properties(scene, v3d, ob); - return; - } - else if(event==10) { - copymenu_logicbricks(scene, v3d, ob); - return; - } - else if(event==24) { - copymenu_modifiers(scene, v3d, ob); - return; - } - - for(base= FIRSTBASE; base; base= base->next) { - if(base != BASACT) { - if(TESTBASELIB(v3d, base)) { - base->object->recalc |= OB_RECALC_OB; - - if(event==1) { /* loc */ - VECCOPY(base->object->loc, ob->loc); - VECCOPY(base->object->dloc, ob->dloc); - } - else if(event==2) { /* rot */ - VECCOPY(base->object->rot, ob->rot); - VECCOPY(base->object->drot, ob->drot); - /* Quats arnt used yet */ - /*VECCOPY(base->object->quat, ob->quat); - VECCOPY(base->object->dquat, ob->dquat);*/ - } - else if(event==3) { /* size */ - VECCOPY(base->object->size, ob->size); - VECCOPY(base->object->dsize, ob->dsize); - } - else if(event==4) { /* drawtype */ - base->object->dt= ob->dt; - base->object->dtx= ob->dtx; - base->object->empty_drawtype= ob->empty_drawtype; - base->object->empty_drawsize= ob->empty_drawsize; - } - else if(event==5) { /* time offs */ - base->object->sf= ob->sf; - } - else if(event==6) { /* dupli */ - base->object->dupon= ob->dupon; - base->object->dupoff= ob->dupoff; - base->object->dupsta= ob->dupsta; - base->object->dupend= ob->dupend; - - base->object->transflag &= ~OB_DUPLI; - base->object->transflag |= (ob->transflag & OB_DUPLI); - - base->object->dup_group= ob->dup_group; - if(ob->dup_group) - id_us_plus((ID *)ob->dup_group); - } - else if(event==7) { /* mass */ - base->object->mass= ob->mass; - } - else if(event==8) { /* damping */ - base->object->damping= ob->damping; - base->object->rdamping= ob->rdamping; - } - else if(event==11) { /* all physical attributes */ - base->object->gameflag = ob->gameflag; - base->object->inertia = ob->inertia; - base->object->formfactor = ob->formfactor; - base->object->damping= ob->damping; - base->object->rdamping= ob->rdamping; - base->object->min_vel= ob->min_vel; - base->object->max_vel= ob->max_vel; - if (ob->gameflag & OB_BOUNDS) { - base->object->boundtype = ob->boundtype; - } - base->object->margin= ob->margin; - base->object->bsoft= copy_bulletsoftbody(ob->bsoft); - - } - else if(event==17) { /* tex space */ - copy_texture_space(base->object, ob); - } - else if(event==18) { /* font settings */ - - if(base->object->type==ob->type) { - cu= ob->data; - cu1= base->object->data; - - cu1->spacemode= cu->spacemode; - cu1->spacing= cu->spacing; - cu1->linedist= cu->linedist; - cu1->shear= cu->shear; - cu1->fsize= cu->fsize; - cu1->xof= cu->xof; - cu1->yof= cu->yof; - cu1->textoncurve= cu->textoncurve; - cu1->wordspace= cu->wordspace; - cu1->ulpos= cu->ulpos; - cu1->ulheight= cu->ulheight; - if(cu1->vfont) cu1->vfont->id.us--; - cu1->vfont= cu->vfont; - id_us_plus((ID *)cu1->vfont); - if(cu1->vfontb) cu1->vfontb->id.us--; - cu1->vfontb= cu->vfontb; - id_us_plus((ID *)cu1->vfontb); - if(cu1->vfonti) cu1->vfonti->id.us--; - cu1->vfonti= cu->vfonti; - id_us_plus((ID *)cu1->vfonti); - if(cu1->vfontbi) cu1->vfontbi->id.us--; - cu1->vfontbi= cu->vfontbi; - id_us_plus((ID *)cu1->vfontbi); - - BKE_text_to_curve(scene, base->object, 0); /* needed? */ - - - strcpy(cu1->family, cu->family); - - base->object->recalc |= OB_RECALC_DATA; - } - } - else if(event==19) { /* bevel settings */ - - if(ELEM(base->object->type, OB_CURVE, OB_FONT)) { - cu= ob->data; - cu1= base->object->data; - - cu1->bevobj= cu->bevobj; - cu1->taperobj= cu->taperobj; - cu1->width= cu->width; - cu1->bevresol= cu->bevresol; - cu1->ext1= cu->ext1; - cu1->ext2= cu->ext2; - - base->object->recalc |= OB_RECALC_DATA; - } - } - else if(event==25) { /* curve resolution */ - - if(ELEM(base->object->type, OB_CURVE, OB_FONT)) { - cu= ob->data; - cu1= base->object->data; - - cu1->resolu= cu->resolu; - cu1->resolu_ren= cu->resolu_ren; - - nu= cu1->nurb.first; - - while(nu) { - nu->resolu= cu1->resolu; - nu= nu->next; - } - - base->object->recalc |= OB_RECALC_DATA; - } - } - else if(event==21){ - if (base->object->type==OB_MESH) { - ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf); - - if (md) { - ModifierData *tmd = modifiers_findByType(base->object, eModifierType_Subsurf); - - if (!tmd) { - tmd = modifier_new(eModifierType_Subsurf); - BLI_addtail(&base->object->modifiers, tmd); - } - - modifier_copyData(md, tmd); - base->object->recalc |= OB_RECALC_DATA; - } - } - } - else if(event==22) { - /* Copy the constraint channels over */ - copy_constraints(&base->object->constraints, &ob->constraints); - - do_scene_sort= 1; - } - else if(event==23) { - base->object->softflag= ob->softflag; - if(base->object->soft) sbFree(base->object->soft); - - base->object->soft= copy_softbody(ob->soft); - - if (!modifiers_findByType(base->object, eModifierType_Softbody)) { - BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody)); - } - } - else if(event==26) { -#if 0 // XXX old animation system - copy_nlastrips(&base->object->nlastrips, &ob->nlastrips); -#endif // XXX old animation system - } - else if(event==27) { /* autosmooth */ - if (base->object->type==OB_MESH) { - Mesh *me= ob->data; - Mesh *cme= base->object->data; - cme->smoothresh= me->smoothresh; - if(me->flag & ME_AUTOSMOOTH) - cme->flag |= ME_AUTOSMOOTH; - else - cme->flag &= ~ME_AUTOSMOOTH; - } - } - else if(event==28) { /* UV orco */ - if(ELEM(base->object->type, OB_CURVE, OB_SURF)) { - cu= ob->data; - cu1= base->object->data; - - if(cu->flag & CU_UV_ORCO) - cu1->flag |= CU_UV_ORCO; - else - cu1->flag &= ~CU_UV_ORCO; - } - } - else if(event==29) { /* protected bits */ - base->object->protectflag= ob->protectflag; - } - else if(event==30) { /* index object */ - base->object->index= ob->index; - } - else if(event==31) { /* object color */ - QUATCOPY(base->object->col, ob->col); - } - } - } - } - - if(do_scene_sort) - DAG_scene_sort(scene); - - ED_anim_dag_flush_update(C); - -} - -void copy_attr_menu(Scene *scene, View3D *v3d) -{ - Object *ob; - short event; - char str[512]; - - if(!(ob=OBACT)) return; - - if (scene->obedit) { // XXX get from context -// if (ob->type == OB_MESH) -// XXX mesh_copy_menu(); - return; - } - - /* Object Mode */ - - /* If you change this menu, don't forget to update the menu in header_view3d.c - * view3d_edit_object_copyattrmenu() and in toolbox.c - */ - - strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|Object Color%x31|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l"); - - strcat (str, "|Object Constraints%x22"); - strcat (str, "|NLA Strips%x26"); - -// XXX if (OB_SUPPORT_MATERIAL(ob)) { -// strcat(str, "|Texture Space%x17"); -// } - - if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19"); - if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28"); - - if((ob->type == OB_FONT) || (ob->type == OB_CURVE)) { - strcat(str, "|Curve Resolution%x25"); - } - - if(ob->type==OB_MESH){ - strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27"); - } - - if(ob->soft) strcat(str, "|Soft Body Settings%x23"); - - strcat(str, "|Pass Index%x30"); - - if(ob->type==OB_MESH || ob->type==OB_CURVE || ob->type==OB_LATTICE || ob->type==OB_SURF){ - strcat(str, "|Modifiers ...%x24"); - } - - event= pupmenu(str); - if(event<= 0) return; - - copy_attr(scene, v3d, event); -} - - -void link_to_scene(unsigned short nr) -{ -#if 0 - Scene *sce= (Scene*) BLI_findlink(&G.main->scene, G.curscreen->scenenr-1); - Base *base, *nbase; - - if(sce==0) return; - if(sce->id.lib) return; - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASE(v3d, base)) { - - nbase= MEM_mallocN( sizeof(Base), "newbase"); - *nbase= *base; - BLI_addhead( &(sce->base), nbase); - id_us_plus((ID *)base->object); - } - } -#endif -} - - -void make_links(Scene *scene, View3D *v3d, short event) -{ - Object *ob, *obt; - Base *base, *nbase, *sbase; - Scene *sce = NULL; - ID *id; - int a; - short nr=0; - char *strp; - - if(!(ob=OBACT)) return; - - if(event==1) { - IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), 0, &nr); - - if(nr == -2) { - MEM_freeN(strp); - -// XXX activate_databrowse((ID *)scene, ID_SCE, 0, B_INFOSCE, &(G.curscreen->scenenr), link_to_scene ); - - return; - } - else { - event= pupmenu_col(strp, 20); - MEM_freeN(strp); - - if(event<= 0) return; - - nr= 1; - sce= G.main->scene.first; - while(sce) { - if(nr==event) break; - nr++; - sce= sce->id.next; - } - if(sce==scene) { - error("This is the current scene"); + if(!psys) return; - } - if(sce==0 || sce->id.lib) return; - - /* remember: is needed below */ - event= 1; - } - } - - /* All non group linking */ - for(base= FIRSTBASE; base; base= base->next) { - if(event==1 || base != BASACT) { - - obt= base->object; - - if(TESTBASE(v3d, base)) { - - if(event==1) { /* to scene */ - - /* test if already linked */ - sbase= sce->base.first; - while(sbase) { - if(sbase->object==base->object) break; - sbase= sbase->next; - } - if(sbase) { /* remove */ - continue; - } - - nbase= MEM_mallocN( sizeof(Base), "newbase"); - *nbase= *base; - BLI_addhead( &(sce->base), nbase); - id_us_plus((ID *)base->object); - } - } - if(TESTBASELIB(v3d, base)) { - if(event==2 || event==5) { /* obdata */ - if(ob->type==obt->type) { - - id= obt->data; - id->us--; - - id= ob->data; - id_us_plus(id); - obt->data= id; - - /* if amount of material indices changed: */ - test_object_materials(obt->data); - - obt->recalc |= OB_RECALC_DATA; - } - } - else if(event==4) { /* ob ipo */ -#if 0 // XXX old animation system - if(obt->ipo) obt->ipo->id.us--; - obt->ipo= ob->ipo; - if(obt->ipo) { - id_us_plus((ID *)obt->ipo); - do_ob_ipo(scene, obt); - } -#endif // XXX old animation system - } - else if(event==6) { - if(ob->dup_group) ob->dup_group->id.us--; - obt->dup_group= ob->dup_group; - if(obt->dup_group) { - id_us_plus((ID *)obt->dup_group); - obt->transflag |= OB_DUPLIGROUP; - } - } - else if(event==3) { /* materials */ - - /* new approach, using functions from kernel */ - for(a=0; atotcol; a++) { - Material *ma= give_current_material(ob, a+1); - assign_material(obt, ma, a+1); /* also works with ma==NULL */ - } - } - } - } - } - - ED_anim_dag_flush_update(C); - -} - -void make_links_menu(Scene *scene, View3D *v3d) -{ - Object *ob; - short event=0; - char str[140]; - - if(!(ob=OBACT)) return; - - strcpy(str, "Make Links %t|To Scene...%x1|%l|Object Ipo%x4"); - - if(ob->type==OB_MESH) - strcat(str, "|Mesh Data%x2|Materials%x3"); - else if(ob->type==OB_CURVE) - strcat(str, "|Curve Data%x2|Materials%x3"); - else if(ob->type==OB_FONT) - strcat(str, "|Text Data%x2|Materials%x3"); - else if(ob->type==OB_SURF) - strcat(str, "|Surface Data%x2|Materials%x3"); - else if(ob->type==OB_MBALL) - strcat(str, "|Materials%x3"); - else if(ob->type==OB_CAMERA) - strcat(str, "|Camera Data%x2"); - else if(ob->type==OB_LAMP) - strcat(str, "|Lamp Data%x2"); - else if(ob->type==OB_LATTICE) - strcat(str, "|Lattice Data%x2"); - else if(ob->type==OB_ARMATURE) - strcat(str, "|Armature Data%x2"); - - event= pupmenu(str); - - if(event<= 0) return; - - make_links(scene, v3d, event); -} -static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, int apply_rot ) -{ - Base *base, *basact; - Object *ob; - bArmature *arm; - Mesh *me; - Curve *cu; - Nurb *nu; - BPoint *bp; - BezTriple *bezt; - MVert *mvert; - float mat[3][3]; - int a, change = 0; - - if (!apply_scale && !apply_rot) { - /* do nothing? */ - error("Nothing to do!"); - return; - } - /* first check if we can execute */ - for (base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - ob= base->object; - if(ob->type==OB_MESH) { - me= ob->data; - - if(me->id.us>1) { - error("Can't apply to a multi user mesh, doing nothing."); - return; - } - } - else if (ob->type==OB_ARMATURE) { - arm= ob->data; - - if(arm->id.us>1) { - error("Can't apply to a multi user armature, doing nothing."); - return; - } - } - else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { - cu= ob->data; - - if(cu->id.us>1) { - error("Can't apply to a multi user curve, doing nothing."); - return; - } - if(cu->key) { - error("Can't apply to a curve with vertex keys, doing nothing."); - return; - } - } - } - } - - /* now execute */ - basact= BASACT; - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - ob= base->object; + if(pset->selectmode & SCE_SELECT_POINT) + nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5"); + else + nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5"); - if(ob->type==OB_MESH) { - /* calculate matrix */ - if (apply_scale && apply_rot) - object_to_mat3(ob, mat); - else if (apply_scale) - object_scale_to_mat3(ob, mat); - else - object_rot_to_mat3(ob, mat); - - /* get object data */ - me= ob->data; - - /* adjust data */ - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - Mat3MulVecfl(mat, mvert->co); - } - - if (me->key) { - KeyBlock *kb; - - for (kb=me->key->block.first; kb; kb=kb->next) { - float *fp= kb->data; - - for (a=0; atotelem; a++, fp+=3) - Mat3MulVecfl(mat, fp); - } - } - - /* adjust transforms */ - if (apply_scale) - ob->size[0]= ob->size[1]= ob->size[2]= 1.0f; - if (apply_rot) - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f; - /*QuatOne(ob->quat);*/ /* Quats arnt used yet */ - - where_is_object(scene, ob); - - /* texspace and normals */ - BASACT= base; -// XXX ED_object_enter_editmode(C, 0); -// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ - BASACT= basact; - - change = 1; - } - else if (ob->type==OB_ARMATURE) { - if (apply_scale && apply_rot) - object_to_mat3(ob, mat); - else if (apply_scale) - object_scale_to_mat3(ob, mat); - else - object_rot_to_mat3(ob, mat); - arm= ob->data; - - /* see checks above */ -// XXX apply_rot_armature(ob, mat); - - /* Reset the object's transforms */ - if (apply_scale) - ob->size[0]= ob->size[1]= ob->size[2]= 1.0; - if (apply_rot) - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; - /*QuatOne(ob->quat); (not used anymore)*/ - - where_is_object(scene, ob); - - change = 1; + switch(nr) { + case 1: +// XXX if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return; + waitcursor(1); + PE_rekey(); + break; + case 2: + PE_subdivide(); + break; + case 3: + PE_select_root(); + break; + case 4: + PE_select_tip(); + break; + case 5: + PE_remove_doubles(); + break; } - else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { - float scale; - if (apply_scale && apply_rot) - object_to_mat3(ob, mat); - else if (apply_scale) - object_scale_to_mat3(ob, mat); - else - object_rot_to_mat3(ob, mat); - scale = Mat3ToScalef(mat); - cu= ob->data; - - /* see checks above */ + + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + if(nr>0) waitcursor(0); +#endif + } + else { + Base *base, *base_select= NULL; + + /* Get the active object mesh. */ + Mesh *me= get_mesh(ob); + + /* Booleans, if the active object is a mesh... */ + if (me && ob->id.lib==NULL) { - nu= cu->nurb.first; - while(nu) { - if(nu->type == CU_BEZIER) { - a= nu->pntsu; - bezt= nu->bezt; - while(a--) { - Mat3MulVecfl(mat, bezt->vec[0]); - Mat3MulVecfl(mat, bezt->vec[1]); - Mat3MulVecfl(mat, bezt->vec[2]); - bezt->radius *= scale; - bezt++; + /* Bring up a little menu with the boolean operation choices on. */ + nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6"); + + if (nr > 0) { + /* user has made a choice of a menu element. + All of the boolean functions require 2 mesh objects + we search through the object list to find the other + selected item and make sure it is distinct and a mesh. */ + + for(base= FIRSTBASE; base; base= base->next) { + if(TESTBASELIB(v3d, base)) { + if(base->object != ob) base_select= base; } } - else { - a= nu->pntsu*nu->pntsv; - bp= nu->bp; - while(a--) { - Mat3MulVecfl(mat, bp->vec); - bp++; + + if (base_select) { + if (get_mesh(base_select->object)) { + if(nr <= 3){ + waitcursor(1); +// XXX ret = NewBooleanMesh(BASACT,base_select,nr); + if (ret==0) { + error("An internal error occurred"); + } else if(ret==-1) { + error("Selected meshes must have faces to perform boolean operations"); + } else if (ret==-2) { + error("Both meshes must be a closed mesh"); + } + waitcursor(0); + } else { + BooleanModifierData *bmd = NULL; + bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean); + BLI_addtail(&ob->modifiers, bmd); + bmd->object = base_select->object; + bmd->modifier.mode |= eModifierMode_Realtime; + switch(nr){ + case 4: bmd->operation = eBooleanModifierOp_Intersect; break; + case 5: bmd->operation = eBooleanModifierOp_Union; break; + case 6: bmd->operation = eBooleanModifierOp_Difference; break; + } +// XXX do_common_editbuts(B_CHANGEDEP); + } + } else { + error("Please select 2 meshes"); } + } else { + error("Please select 2 meshes"); } - nu= nu->next; } - if (apply_scale) - ob->size[0]= ob->size[1]= ob->size[2]= 1.0; - if (apply_rot) - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; - /*QuatOne(ob->quat); (quats arnt used anymore)*/ - - where_is_object(scene, ob); - - /* texspace and normals */ - BASACT= base; -// XXX ED_object_enter_editmode(C, 0); -// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */ - BASACT= basact; - - change = 1; - } else { - continue; + } - - ignore_parent_tx(scene, ob); + else if (ob->type == OB_FONT) { + /* removed until this gets a decent implementation (ton) */ +/* nr= pupmenu("Split %t|Characters%x1"); + if (nr > 0) { + switch(nr) { + case 1: split_font(); + } + } +*/ + } } } - if (change) { + else if(obedit->type==OB_MESH) { + } + else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { + } + else if(obedit->type==OB_ARMATURE) { + nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6"); +// if(nr==1) +// XXX subdivide_armature(1); + if(nr==2) { +// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; + waitcursor(1); +// XXX subdivide_armature(numcuts); + } +// else if(nr==3) +// XXX armature_flip_names(); + else if(ELEM3(nr, 4, 5, 6)) { +// XXX armature_autoside_names(nr-4); + } +// else if(nr == 7) +// XXX switch_direction_armature(); + } + else if(obedit->type==OB_LATTICE) { + Lattice *lt= obedit->data; + static float weight= 1.0f; + { // XXX +// XXX if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) { + int a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; + BPoint *bp= lt->editlatt->def; + + while(a--) { + if(bp->f1 & SELECT) + bp->weight= weight; + bp++; + } + } } -} - -void apply_objects_locrot(Scene *scene, View3D *v3d) -{ - apply_objects_internal(scene, v3d, 1, 1); -} -void apply_objects_scale(Scene *scene, View3D *v3d) -{ - apply_objects_internal(scene, v3d, 1, 0); } -void apply_objects_rot(Scene *scene, View3D *v3d) -{ - apply_objects_internal(scene, v3d, 0, 1); -} +/* Change subdivision or particle properties of mesh object ob, if level==-1 + * then toggle subsurf, else set to level set allows to toggle multiple + * selections */ -void apply_objects_visual_tx( Scene *scene, View3D *v3d ) +static void object_has_subdivision_particles(Object *ob, int *havesubdiv, int *havepart, int depth) { - Base *base; - Object *ob; - int change = 0; - - for (base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - ob= base->object; - where_is_object(scene, ob); - VECCOPY(ob->loc, ob->obmat[3]); - Mat4ToSize(ob->obmat, ob->size); - Mat4ToEul(ob->obmat, ob->rot); - - where_is_object(scene, ob); - - change = 1; - } + if(ob->type==OB_MESH) { + if(modifiers_findByType(ob, eModifierType_Subsurf)) + *havesubdiv= 1; + if(modifiers_findByType(ob, eModifierType_ParticleSystem)) + *havepart= 1; } - if (change) { + + if(ob->dup_group && depth <= 4) { + GroupObject *go; + + for(go= ob->dup_group->gobject.first; go; go= go->next) + object_has_subdivision_particles(go->ob, havesubdiv, havepart, depth+1); } } -/* ************************************** */ +static void object_flip_subdivison_particles(Scene *scene, Object *ob, int *set, int level, int mode, int particles, int depth) +{ + ModifierData *md; + if(ob->type==OB_MESH) { + if(particles) { + for(md=ob->modifiers.first; md; md=md->next) { + if(md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData*)md; -void single_object_users(Scene *scene, View3D *v3d, int flag) -{ - Base *base; - Object *ob, *obn; - - clear_sca_new_poins(); /* sensor/contr/act */ + if(*set == -1) + *set= psmd->modifier.mode&(mode); - /* duplicate (must set newid) */ - for(base= FIRSTBASE; base; base= base->next) { - ob= base->object; - - if( (base->flag & flag)==flag ) { - if(ob->id.lib==NULL && ob->id.us>1) { - /* base gets copy of object */ - obn= copy_object(ob); - base->object= obn; - ob->id.us--; + if (*set) + psmd->modifier.mode &= ~(mode); + else + psmd->modifier.mode |= (mode); + } } } - } - - ID_NEW(scene->camera); - if(v3d) ID_NEW(v3d->camera); - - /* object pointers */ - for(base= FIRSTBASE; base; base= base->next) { - ob= base->object; - if(ob->id.lib==NULL) { - relink_constraints(&base->object->constraints); - if (base->object->pose){ - bPoseChannel *chan; - for (chan = base->object->pose->chanbase.first; chan; chan=chan->next){ - relink_constraints(&chan->constraints); + else { + md = modifiers_findByType(ob, eModifierType_Subsurf); + + if (md) { + SubsurfModifierData *smd = (SubsurfModifierData*) md; + + if (level == -1) { + if(*set == -1) + *set= smd->modifier.mode&(mode); + + if (*set) + smd->modifier.mode &= ~(mode); + else + smd->modifier.mode |= (mode); + } else { + smd->levels = level; + } + } + else if(depth == 0 && *set != 0) { + SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf); + + BLI_addtail(&ob->modifiers, smd); + + if (level!=-1) { + smd->levels = level; } + + if(*set == -1) + *set= 1; } - modifiers_foreachObjectLink(base->object, single_object_users__forwardModifierLinks, NULL); - - ID_NEW(ob->parent); - ID_NEW(ob->track); } + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } - set_sca_new_poins(); -} + if(ob->dup_group && depth<=4) { + GroupObject *go; -void new_id_matar(Material **matar, int totcol) -{ - ID *id; - int a; - - for(a=0; alib==0) { - if(id->newid) { - matar[a]= (Material *)id->newid; - id_us_plus(id->newid); - id->us--; - } - else if(id->us>1) { - matar[a]= copy_material(matar[a]); - id->us--; - id->newid= (ID *)matar[a]; - } - } + for(go= ob->dup_group->gobject.first; go; go= go->next) + object_flip_subdivison_particles(scene, go->ob, set, level, mode, particles, depth+1); } } -void single_obdata_users(Scene *scene, int flag) +/* Change subdivision properties of mesh object ob, if +* level==-1 then toggle subsurf, else set to level. +*/ + +void flip_subdivison(Scene *scene, View3D *v3d, int level) { - Object *ob; - Lamp *la; - Curve *cu; - //Camera *cam; Base *base; - Mesh *me; - ID *id; - int a; - - for(base= FIRSTBASE; base; base= base->next) { - ob= base->object; - if(ob->id.lib==NULL && (base->flag & flag)==flag ) { - id= ob->data; - - if(id && id->us>1 && id->lib==0) { - ob->recalc= OB_RECALC_DATA; - - switch(ob->type) { - case OB_LAMP: - if(id && id->us>1 && id->lib==NULL) { - ob->data= la= copy_lamp(ob->data); - for(a=0; amtex[a]) { - ID_NEW(la->mtex[a]->object); - } - } - } - break; - case OB_CAMERA: - ob->data= copy_camera(ob->data); - break; - case OB_MESH: - me= ob->data= copy_mesh(ob->data); - //if(me && me->key) - // ipo_idnew(me->key->ipo); /* drivers */ - break; - case OB_MBALL: - ob->data= copy_mball(ob->data); - break; - case OB_CURVE: - case OB_SURF: - case OB_FONT: - ob->data= cu= copy_curve(ob->data); - ID_NEW(cu->bevobj); - ID_NEW(cu->taperobj); - break; - case OB_LATTICE: - ob->data= copy_lattice(ob->data); - break; - case OB_ARMATURE: - ob->recalc |= OB_RECALC_DATA; - ob->data= copy_armature(ob->data); - armature_rebuild_pose(ob, ob->data); - break; - default: - printf("ERROR single_obdata_users: %s\n", id->name); - error("Read console"); - return; - } - - id->us--; - id->newid= ob->data; - - } - -#if 0 // XXX old animation system - id= (ID *)ob->action; - if (id && id->us>1 && id->lib==NULL){ - if(id->newid){ - ob->action= (bAction *)id->newid; - id_us_plus(id->newid); - } - else { - ob->action= copy_action(ob->action); - id->us--; - id->newid=(ID *)ob->action; - } - } - id= (ID *)ob->ipo; - if(id && id->us>1 && id->lib==NULL) { - if(id->newid) { - ob->ipo= (Ipo *)id->newid; - id_us_plus(id->newid); - } - else { - ob->ipo= copy_ipo(ob->ipo); - id->us--; - id->newid= (ID *)ob->ipo; - } - ipo_idnew(ob->ipo); /* drivers */ - } - /* other ipos */ - switch(ob->type) { - case OB_LAMP: - la= ob->data; - if(la->ipo && la->ipo->id.us>1) { - la->ipo->id.us--; - la->ipo= copy_ipo(la->ipo); - ipo_idnew(la->ipo); /* drivers */ - } - break; - case OB_CAMERA: - cam= ob->data; - if(cam->ipo && cam->ipo->id.us>1) { - cam->ipo->id.us--; - cam->ipo= copy_ipo(cam->ipo); - ipo_idnew(cam->ipo); /* drivers */ + int set= -1; + int mode, pupmode, particles= 0, havesubdiv= 0, havepart= 0; + int alt= 0; // XXX + + if(alt) + mode= eModifierMode_Realtime; + else + mode= eModifierMode_Render|eModifierMode_Realtime; + + if(level == -1) { + if (scene->obedit) { // XXX get from context + object_has_subdivision_particles(scene->obedit, &havesubdiv, &havepart, 0); + } else { + for(base= scene->base.first; base; base= base->next) { + if(((level==-1) && (TESTBASE(v3d, base))) || (TESTBASELIB(v3d, base))) { + object_has_subdivision_particles(base->object, &havesubdiv, &havepart, 0); } - break; } -#endif // XXX old animation system } } + else + havesubdiv= 1; - me= G.main->mesh.first; - while(me) { - ID_NEW(me->texcomesh); - me= me->id.next; + if(havesubdiv && havepart) { + pupmode= pupmenu("Switch%t|Subsurf %x1|Particle Systems %x2"); + if(pupmode <= 0) + return; + else if(pupmode == 2) + particles= 1; } -} + else if(havepart) + particles= 1; -void single_ipo_users(Scene *scene, int flag) -{ -#if 0 // XXX old animation system - Object *ob; - Base *base; - ID *id; - - for(base= FIRSTBASE; base; base= base->next) { - ob= base->object; - if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) { - ob->recalc= OB_RECALC_DATA; - - id= (ID *)ob->ipo; - if(id && id->us>1 && id->lib==NULL) { - ob->ipo= copy_ipo(ob->ipo); - id->us--; - ipo_idnew(ob->ipo); /* drivers */ + if (scene->obedit) { // XXX get from context + object_flip_subdivison_particles(scene, scene->obedit, &set, level, mode, particles, 0); + } else { + for(base= scene->base.first; base; base= base->next) { + if(((level==-1) && (TESTBASE(v3d, base))) || (TESTBASELIB(v3d, base))) { + object_flip_subdivison_particles(scene, base->object, &set, level, mode, particles, 0); } } } -#endif // XXX old animation system + + ED_anim_dag_flush_update(C); } - -void single_mat_users(Scene *scene, int flag) -{ - Object *ob; + +static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) +{ + bProperty *prop; Base *base; - Material *ma, *man; - Tex *tex; - int a, b; + int nr, tot=0; + char *str; + prop= ob->prop.first; + while(prop) { + tot++; + prop= prop->next; + } - for(base= FIRSTBASE; base; base= base->next) { - ob= base->object; - if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) { + str= MEM_callocN(50 + 33*tot, "copymenu prop"); - for(a=1; a<=ob->totcol; a++) { - ma= give_current_material(ob, a); - if(ma) { - /* do not test for LIB_NEW: this functions guaranteed delivers single_users! */ - - if(ma->id.us>1) { - man= copy_material(ma); - - man->id.us= 0; - assign_material(ob, man, a); + if (tot) + strcpy(str, "Copy Property %t|Replace All|Merge All|%l"); + else + strcpy(str, "Copy Property %t|Clear All (no properties on active)"); -#if 0 // XXX old animation system - if(ma->ipo) { - man->ipo= copy_ipo(ma->ipo); - ma->ipo->id.us--; - ipo_idnew(ma->ipo); /* drivers */ - } -#endif // XXX old animation system - - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - tex= ma->mtex[b]->tex; - if(tex->id.us>1) { - ma->mtex[b]->tex= copy_texture(tex); - tex->id.us--; - } - } - } - - } - } - } - } + tot= 0; + prop= ob->prop.first; + while(prop) { + tot++; + strcat(str, "|"); + strcat(str, prop->name); + prop= prop->next; } -} -void do_single_tex_user(Tex **from) -{ - Tex *tex, *texn; - - tex= *from; - if(tex==0) return; - - if(tex->id.newid) { - *from= (Tex *)tex->id.newid; - id_us_plus(tex->id.newid); - tex->id.us--; - } - else if(tex->id.us>1) { - texn= copy_texture(tex); - tex->id.newid= (ID *)texn; - tex->id.us--; - *from= texn; - } + nr= pupmenu(str); -} - -void single_tex_users_expand() -{ - /* only when 'parent' blocks are LIB_NEW */ - Material *ma; - Lamp *la; - World *wo; - int b; - - ma= G.main->mat.first; - while(ma) { - if(ma->id.flag & LIB_NEW) { - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - do_single_tex_user( &(ma->mtex[b]->tex) ); + if ( nr==1 || nr==2 ) { + for(base= FIRSTBASE; base; base= base->next) { + if((base != BASACT) &&(TESTBASELIB(v3d, base))) { + if (nr==1) { /* replace */ + copy_properties( &base->object->prop, &ob->prop ); + } else { + for(prop = ob->prop.first; prop; prop= prop->next ) { + set_ob_property(base->object, prop); + } } } } - ma= ma->id.next; - } - - la= G.main->lamp.first; - while(la) { - if(la->id.flag & LIB_NEW) { - for(b=0; bmtex[b] && la->mtex[b]->tex) { - do_single_tex_user( &(la->mtex[b]->tex) ); + } else if(nr>0) { + prop = BLI_findlink(&ob->prop, nr-4); /* account for first 3 menu items & menu index starting at 1*/ + + if(prop) { + for(base= FIRSTBASE; base; base= base->next) { + if((base != BASACT) &&(TESTBASELIB(v3d, base))) { + set_ob_property(base->object, prop); } } } - la= la->id.next; } - wo= G.main->world.first; - while(wo) { - if(wo->id.flag & LIB_NEW) { - for(b=0; bmtex[b] && wo->mtex[b]->tex) { - do_single_tex_user( &(wo->mtex[b]->tex) ); - } + MEM_freeN(str); + +} + +static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) +{ + Base *base; + + for(base= FIRSTBASE; base; base= base->next) { + if(base->object != ob) { + if(TESTBASELIB(v3d, base)) { + + /* first: free all logic */ + free_sensors(&base->object->sensors); + unlink_controllers(&base->object->controllers); + free_controllers(&base->object->controllers); + unlink_actuators(&base->object->actuators); + free_actuators(&base->object->actuators); + + /* now copy it, this also works without logicbricks! */ + clear_sca_new_poins_ob(ob); + copy_sensors(&base->object->sensors, &ob->sensors); + copy_controllers(&base->object->controllers, &ob->controllers); + copy_actuators(&base->object->actuators, &ob->actuators); + set_sca_new_poins_ob(base->object); + + /* some menu settings */ + base->object->scavisflag= ob->scavisflag; + base->object->scaflag= ob->scaflag; + + /* set the initial state */ + base->object->state= ob->state; + base->object->init_state= ob->init_state; } } - wo= wo->id.next; } } -void single_mat_users_expand(void) +static void copymenu_modifiers(Scene *scene, View3D *v3d, Object *ob) { - /* only when 'parent' blocks are LIB_NEW */ + Base *base; + int i, event; + char str[512]; + char *errorstr= NULL; - Object *ob; - Mesh *me; - Curve *cu; - MetaBall *mb; - Material *ma; - int a; - - ob= G.main->object.first; - while(ob) { - if(ob->id.flag & LIB_NEW) { - new_id_matar(ob->mat, ob->totcol); - } - ob= ob->id.next; - } + strcpy(str, "Copy Modifiers %t"); - me= G.main->mesh.first; - while(me) { - if(me->id.flag & LIB_NEW) { - new_id_matar(me->mat, me->totcol); - } - me= me->id.next; - } + sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES); - cu= G.main->curve.first; - while(cu) { - if(cu->id.flag & LIB_NEW) { - new_id_matar(cu->mat, cu->totcol); - } - cu= cu->id.next; - } + for (i=eModifierType_None+1; imball.first; - while(mb) { - if(mb->id.flag & LIB_NEW) { - new_id_matar(mb->mat, mb->totcol); - } - mb= mb->id.next; - } + if(ELEM3(i, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue; + + if(i == eModifierType_Collision) + continue; - /* material imats */ - ma= G.main->mat.first; - while(ma) { - if(ma->id.flag & LIB_NEW) { - for(a=0; amtex[a]) { - ID_NEW(ma->mtex[a]->object); - } - } + if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) || + (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { + sprintf(str+strlen(str), "|%s%%x%d", mti->name, i); } - ma= ma->id.next; } -} -void single_user(Scene *scene, View3D *v3d) -{ - int nr; - - if(scene->id.lib) return; + event = pupmenu(str); + if(event<=0) return; - clear_id_newpoins(); - - nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex|Ipos"); - if(nr>0) { - - if(nr==1) single_object_users(scene, v3d, 1); - - else if(nr==2) { - single_object_users(scene, v3d, 1); - single_obdata_users(scene, 1); - } - else if(nr==3) { - single_object_users(scene, v3d, 1); - single_obdata_users(scene, 1); - single_mat_users(scene, 1); /* also tex */ - - } - else if(nr==4) { - single_mat_users(scene, 1); - } - else if(nr==5) { - single_ipo_users(scene, 1); + for (base= FIRSTBASE; base; base= base->next) { + if(base->object != ob) { + if(TESTBASELIB(v3d, base)) { + ModifierData *md; + + base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA; + + if (base->object->type==ob->type) { + /* copy all */ + if (event==NUM_MODIFIER_TYPES) { + object_free_modifiers(base->object); + + for (md=ob->modifiers.first; md; md=md->next) { + ModifierData *nmd = NULL; + + if(ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue; + + if(md->type == eModifierType_Collision) + continue; + + nmd = modifier_new(md->type); + modifier_copyData(md, nmd); + BLI_addtail(&base->object->modifiers, nmd); + } + + copy_object_particlesystems(base->object, ob); + copy_object_softbody(base->object, ob); + } else { + /* copy specific types */ + ModifierData *md, *mdn; + + /* remove all with type 'event' */ + for (md=base->object->modifiers.first; md; md=mdn) { + mdn= md->next; + if(md->type==event) { + BLI_remlink(&base->object->modifiers, md); + modifier_free(md); + } + } + + /* copy all with type 'event' */ + for (md=ob->modifiers.first; md; md=md->next) { + if (md->type==event) { + + mdn = modifier_new(event); + BLI_addtail(&base->object->modifiers, mdn); + + modifier_copyData(md, mdn); + } + } + + if(event == eModifierType_ParticleSystem) { + object_free_particlesystems(base->object); + copy_object_particlesystems(base->object, ob); + } + else if(event == eModifierType_Softbody) { + object_free_softbody(base->object); + copy_object_softbody(base->object, ob); + } + } + } + else + errorstr= "Did not copy modifiers to other Object types"; + } } - - - clear_id_newpoins(); - } + +// if(errorstr) notice(errorstr); + + DAG_scene_sort(scene); + } -/* used for copying scenes */ -void ED_object_single_users(Scene *scene, int full) -{ - single_object_users(scene, NULL, 0); - - if(full) { - single_obdata_users(scene, 0); - single_mat_users_expand(); - single_tex_users_expand(); - } - - clear_id_newpoins(); -} - -/* ************************************************************* */ - -/* helper for below, ma was checked to be not NULL */ -static void make_local_makelocalmaterial(Material *ma) +/* both pointers should exist */ +static void copy_texture_space(Object *to, Object *ob) { - //ID *id; - int b; - - make_local_material(ma); + float *poin1= NULL, *poin2= NULL; + int texflag= 0; - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - make_local_texture(ma->mtex[b]->tex); - } + if(ob->type==OB_MESH) { + texflag= ((Mesh *)ob->data)->texflag; + poin2= ((Mesh *)ob->data)->loc; + } + else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { + texflag= ((Curve *)ob->data)->texflag; + poin2= ((Curve *)ob->data)->loc; + } + else if(ob->type==OB_MBALL) { + texflag= ((MetaBall *)ob->data)->texflag; + poin2= ((MetaBall *)ob->data)->loc; + } + else + return; + + if(to->type==OB_MESH) { + ((Mesh *)to->data)->texflag= texflag; + poin1= ((Mesh *)to->data)->loc; + } + else if (ELEM3(to->type, OB_CURVE, OB_SURF, OB_FONT)) { + ((Curve *)to->data)->texflag= texflag; + poin1= ((Curve *)to->data)->loc; + } + else if(to->type==OB_MBALL) { + ((MetaBall *)to->data)->texflag= texflag; + poin1= ((MetaBall *)to->data)->loc; } + else + return; -#if 0 // XXX old animation system - id= (ID *)ma->ipo; - if(id && id->lib) make_local_ipo(ma->ipo); -#endif // XXX old animation system + memcpy(poin1, poin2, 9*sizeof(float)); /* this was noted in DNA_mesh, curve, mball */ + + if(to->type==OB_MESH) ; + else if(to->type==OB_MBALL) tex_space_mball(to); + else tex_space_curve(to->data); - /* nodetree? XXX */ } -void make_local(Scene *scene, View3D *v3d, int mode) +void copy_attr(Scene *scene, View3D *v3d, short event) { - Base *base; Object *ob; - //bActionStrip *strip; - ParticleSystem *psys; - Material *ma, ***matarar; - Lamp *la; - Curve *cu; - ID *id; - int a, b; + Base *base; + Curve *cu, *cu1; + Nurb *nu; + int do_scene_sort= 0; - /* WATCH: the function new_id(..) re-inserts the id block!!! */ if(scene->id.lib) return; + + if(!(ob=OBACT)) return; - if(mode==3) { - all_local(NULL, 0); /* NULL is all libs */ + if(scene->obedit) { // XXX get from context + /* obedit_copymenu(); */ return; } - else if(mode<1) return; - - clear_id_newpoins(); - - for(base= FIRSTBASE; base; base= base->next) { - if( TESTBASE(v3d, base) ) { - ob= base->object; - if(ob->id.lib) { - make_local_object(ob); - } - } + if(event==9) { + copymenu_properties(scene, v3d, ob); + return; } - - /* maybe object pointers */ - for(base= FIRSTBASE; base; base= base->next) { - if( TESTBASE(v3d, base) ) { - ob= base->object; - if(ob->id.lib==NULL) { - ID_NEW(ob->parent); - ID_NEW(ob->track); - } - } + else if(event==10) { + copymenu_logicbricks(scene, v3d, ob); + return; + } + else if(event==24) { + copymenu_modifiers(scene, v3d, ob); + return; } for(base= FIRSTBASE; base; base= base->next) { - if( TESTBASE(v3d, base) ) { - ob= base->object; - id= ob->data; - - if(id && mode>1) { + if(base != BASACT) { + if(TESTBASELIB(v3d, base)) { + base->object->recalc |= OB_RECALC_OB; - switch(ob->type) { - case OB_LAMP: - make_local_lamp((Lamp *)id); - - la= ob->data; -#if 0 // XXX old animation system - id= (ID *)la->ipo; - if(id && id->lib) make_local_ipo(la->ipo); -#endif // XXX old animation system - break; - case OB_CAMERA: - make_local_camera((Camera *)id); - break; - case OB_MESH: - make_local_mesh((Mesh *)id); - make_local_key( ((Mesh *)id)->key ); - break; - case OB_MBALL: - make_local_mball((MetaBall *)id); - break; - case OB_CURVE: - case OB_SURF: - case OB_FONT: - cu= (Curve *)id; - make_local_curve(cu); -#if 0 // XXX old animation system - id= (ID *)cu->ipo; - if(id && id->lib) make_local_ipo(cu->ipo); -#endif // XXX old animation system - make_local_key( cu->key ); - break; - case OB_LATTICE: - make_local_lattice((Lattice *)id); - make_local_key( ((Lattice *)id)->key ); - break; - case OB_ARMATURE: - make_local_armature ((bArmature *)id); - break; + if(event==1) { /* loc */ + VECCOPY(base->object->loc, ob->loc); + VECCOPY(base->object->dloc, ob->dloc); } - - for(psys=ob->particlesystem.first; psys; psys=psys->next) - make_local_particlesettings(psys->part); - } - -#if 0 // XXX old animation system - id= (ID *)ob->ipo; - if(id && id->lib) make_local_ipo(ob->ipo); - - id= (ID *)ob->action; - if(id && id->lib) make_local_action(ob->action); - - for(strip=ob->nlastrips.first; strip; strip=strip->next) { - if(strip->act && strip->act->id.lib) - make_local_action(strip->act); - } -#endif // XXX old animation system - } - } - - if(mode>1) { - for(base= FIRSTBASE; base; base= base->next) { - if( TESTBASE(v3d, base) ) { - ob= base->object; - if(ob->type==OB_LAMP) { - la= ob->data; - for(b=0; bmtex[b] && la->mtex[b]->tex) { - make_local_texture(la->mtex[b]->tex); - } - } + else if(event==2) { /* rot */ + VECCOPY(base->object->rot, ob->rot); + VECCOPY(base->object->drot, ob->drot); + /* Quats arnt used yet */ + /*VECCOPY(base->object->quat, ob->quat); + VECCOPY(base->object->dquat, ob->dquat);*/ } - else { - - for(a=0; atotcol; a++) { - ma= ob->mat[a]; - if(ma) - make_local_makelocalmaterial(ma); - } - - matarar= (Material ***)give_matarar(ob); - if (matarar) { - for(a=0; atotcol; a++) { - ma= (*matarar)[a]; - if(ma) - make_local_makelocalmaterial(ma); - } - } + else if(event==3) { /* size */ + VECCOPY(base->object->size, ob->size); + VECCOPY(base->object->dsize, ob->dsize); } - } - } - } - -} - -void make_local_menu(Scene *scene, View3D *v3d) -{ - int mode; - - /* If you modify this menu, please remember to update view3d_edit_object_makelocalmenu - * in header_view3d.c and the menu in toolbox.c - */ - - if(scene->id.lib) return; - - mode = pupmenu("Make Local%t|Selected Objects %x1|Selected Objects and Data %x2|All %x3"); - - if (mode <= 0) return; - - make_local(scene, v3d, mode); -} - -/* ************************ ADD DUPLICATE ******************** */ - -/* - dupflag: a flag made from constants declared in DNA_userdef_types.h - The flag tells adduplicate() weather to copy data linked to the object, or to reference the existing data. - U.dupflag for default operations or you can construct a flag as python does - if the dupflag is 0 then no data will be copied (linked duplicate) */ + else if(event==4) { /* drawtype */ + base->object->dt= ob->dt; + base->object->dtx= ob->dtx; + base->object->empty_drawtype= ob->empty_drawtype; + base->object->empty_drawsize= ob->empty_drawsize; + } + else if(event==5) { /* time offs */ + base->object->sf= ob->sf; + } + else if(event==6) { /* dupli */ + base->object->dupon= ob->dupon; + base->object->dupoff= ob->dupoff; + base->object->dupsta= ob->dupsta; + base->object->dupend= ob->dupend; + + base->object->transflag &= ~OB_DUPLI; + base->object->transflag |= (ob->transflag & OB_DUPLI); -/* used below, assumes id.new is correct */ -/* leaves selection of base/object unaltered */ -static Base *object_add_duplicate_internal(Scene *scene, Base *base, int dupflag) -{ - Base *basen= NULL; - Material ***matarar; - Object *ob, *obn; - ID *id; - int a, didit; - - ob= base->object; - if(ob->mode & OB_MODE_POSE) { - ; /* nothing? */ - } - else { - obn= copy_object(ob); - obn->recalc |= OB_RECALC; - - basen= MEM_mallocN(sizeof(Base), "duplibase"); - *basen= *base; - BLI_addhead(&scene->base, basen); /* addhead: prevent eternal loop */ - basen->object= obn; - - if(basen->flag & OB_FROMGROUP) { - Group *group; - for(group= G.main->group.first; group; group= group->id.next) { - if(object_in_group(ob, group)) - add_to_group(group, obn); - } - obn->flag |= OB_FROMGROUP; /* this flag is unset with copy_object() */ - } - - /* duplicates using userflags */ -#if 0 // XXX old animation system - if(dupflag & USER_DUP_IPO) { - bConstraintChannel *chan; - id= (ID *)obn->ipo; - - if(id) { - ID_NEW_US( obn->ipo) - else obn->ipo= copy_ipo(obn->ipo); - id->us--; - } - /* Handle constraint ipos */ - for (chan=obn->constraintChannels.first; chan; chan=chan->next){ - id= (ID *)chan->ipo; - if(id) { - ID_NEW_US( chan->ipo) - else chan->ipo= copy_ipo(chan->ipo); - id->us--; + base->object->dup_group= ob->dup_group; + if(ob->dup_group) + id_us_plus((ID *)ob->dup_group); } - } - } - if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */ - id= (ID *)obn->action; - if (id){ - ID_NEW_US(obn->action) - else{ - obn->action= copy_action(obn->action); + else if(event==7) { /* mass */ + base->object->mass= ob->mass; } - id->us--; - } - } -#endif // XXX old animation system - if(dupflag & USER_DUP_MAT) { - for(a=0; atotcol; a++) { - id= (ID *)obn->mat[a]; - if(id) { - ID_NEW_US(obn->mat[a]) - else obn->mat[a]= copy_material(obn->mat[a]); - id->us--; + else if(event==8) { /* damping */ + base->object->damping= ob->damping; + base->object->rdamping= ob->rdamping; } - } - } - if(dupflag & USER_DUP_PSYS) { - ParticleSystem *psys; - for(psys=obn->particlesystem.first; psys; psys=psys->next) { - id= (ID*) psys->part; - if(id) { - ID_NEW_US(psys->part) - else psys->part= psys_copy_settings(psys->part); - id->us--; + else if(event==11) { /* all physical attributes */ + base->object->gameflag = ob->gameflag; + base->object->inertia = ob->inertia; + base->object->formfactor = ob->formfactor; + base->object->damping= ob->damping; + base->object->rdamping= ob->rdamping; + base->object->min_vel= ob->min_vel; + base->object->max_vel= ob->max_vel; + if (ob->gameflag & OB_BOUNDS) { + base->object->boundtype = ob->boundtype; + } + base->object->margin= ob->margin; + base->object->bsoft= copy_bulletsoftbody(ob->bsoft); + } - } - } - - id= obn->data; - didit= 0; - - switch(obn->type) { - case OB_MESH: - if(dupflag & USER_DUP_MESH) { - ID_NEW_US2( obn->data ) - else { - obn->data= copy_mesh(obn->data); + else if(event==17) { /* tex space */ + copy_texture_space(base->object, ob); + } + else if(event==18) { /* font settings */ + + if(base->object->type==ob->type) { + cu= ob->data; + cu1= base->object->data; + + cu1->spacemode= cu->spacemode; + cu1->spacing= cu->spacing; + cu1->linedist= cu->linedist; + cu1->shear= cu->shear; + cu1->fsize= cu->fsize; + cu1->xof= cu->xof; + cu1->yof= cu->yof; + cu1->textoncurve= cu->textoncurve; + cu1->wordspace= cu->wordspace; + cu1->ulpos= cu->ulpos; + cu1->ulheight= cu->ulheight; + if(cu1->vfont) cu1->vfont->id.us--; + cu1->vfont= cu->vfont; + id_us_plus((ID *)cu1->vfont); + if(cu1->vfontb) cu1->vfontb->id.us--; + cu1->vfontb= cu->vfontb; + id_us_plus((ID *)cu1->vfontb); + if(cu1->vfonti) cu1->vfonti->id.us--; + cu1->vfonti= cu->vfonti; + id_us_plus((ID *)cu1->vfonti); + if(cu1->vfontbi) cu1->vfontbi->id.us--; + cu1->vfontbi= cu->vfontbi; + id_us_plus((ID *)cu1->vfontbi); + + BKE_text_to_curve(scene, base->object, 0); /* needed? */ + + + strcpy(cu1->family, cu->family); + + base->object->recalc |= OB_RECALC_DATA; + } + } + else if(event==19) { /* bevel settings */ + + if(ELEM(base->object->type, OB_CURVE, OB_FONT)) { + cu= ob->data; + cu1= base->object->data; - if(obn->fluidsimSettings) { - obn->fluidsimSettings->orgMesh = (Mesh *)obn->data; - } + cu1->bevobj= cu->bevobj; + cu1->taperobj= cu->taperobj; + cu1->width= cu->width; + cu1->bevresol= cu->bevresol; + cu1->ext1= cu->ext1; + cu1->ext2= cu->ext2; - didit= 1; + base->object->recalc |= OB_RECALC_DATA; } - id->us--; } - break; - case OB_CURVE: - if(dupflag & USER_DUP_CURVE) { - ID_NEW_US2(obn->data ) - else { - obn->data= copy_curve(obn->data); - didit= 1; + else if(event==25) { /* curve resolution */ + + if(ELEM(base->object->type, OB_CURVE, OB_FONT)) { + cu= ob->data; + cu1= base->object->data; + + cu1->resolu= cu->resolu; + cu1->resolu_ren= cu->resolu_ren; + + nu= cu1->nurb.first; + + while(nu) { + nu->resolu= cu1->resolu; + nu= nu->next; + } + + base->object->recalc |= OB_RECALC_DATA; } - id->us--; } - break; - case OB_SURF: - if(dupflag & USER_DUP_SURF) { - ID_NEW_US2( obn->data ) - else { - obn->data= copy_curve(obn->data); - didit= 1; + else if(event==21){ + if (base->object->type==OB_MESH) { + ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf); + + if (md) { + ModifierData *tmd = modifiers_findByType(base->object, eModifierType_Subsurf); + + if (!tmd) { + tmd = modifier_new(eModifierType_Subsurf); + BLI_addtail(&base->object->modifiers, tmd); + } + + modifier_copyData(md, tmd); + base->object->recalc |= OB_RECALC_DATA; + } } - id->us--; } - break; - case OB_FONT: - if(dupflag & USER_DUP_FONT) { - ID_NEW_US2( obn->data ) - else { - obn->data= copy_curve(obn->data); - didit= 1; - } - id->us--; + else if(event==22) { + /* Copy the constraint channels over */ + copy_constraints(&base->object->constraints, &ob->constraints); + + do_scene_sort= 1; } - break; - case OB_MBALL: - if(dupflag & USER_DUP_MBALL) { - ID_NEW_US2(obn->data ) - else { - obn->data= copy_mball(obn->data); - didit= 1; + else if(event==23) { + base->object->softflag= ob->softflag; + if(base->object->soft) sbFree(base->object->soft); + + base->object->soft= copy_softbody(ob->soft); + + if (!modifiers_findByType(base->object, eModifierType_Softbody)) { + BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody)); } - id->us--; } - break; - case OB_LAMP: - if(dupflag & USER_DUP_LAMP) { - ID_NEW_US2(obn->data ) - else obn->data= copy_lamp(obn->data); - id->us--; + else if(event==26) { +#if 0 // XXX old animation system + copy_nlastrips(&base->object->nlastrips, &ob->nlastrips); +#endif // XXX old animation system } - break; - - case OB_ARMATURE: - obn->recalc |= OB_RECALC_DATA; - if(obn->pose) obn->pose->flag |= POSE_RECALC; - - if(dupflag & USER_DUP_ARM) { - ID_NEW_US2(obn->data ) - else { - obn->data= copy_armature(obn->data); - armature_rebuild_pose(obn, obn->data); - didit= 1; - } - id->us--; + else if(event==27) { /* autosmooth */ + if (base->object->type==OB_MESH) { + Mesh *me= ob->data; + Mesh *cme= base->object->data; + cme->smoothresh= me->smoothresh; + if(me->flag & ME_AUTOSMOOTH) + cme->flag |= ME_AUTOSMOOTH; + else + cme->flag &= ~ME_AUTOSMOOTH; } + } + else if(event==28) { /* UV orco */ + if(ELEM(base->object->type, OB_CURVE, OB_SURF)) { + cu= ob->data; + cu1= base->object->data; - break; - - case OB_LATTICE: - if(dupflag!=0) { - ID_NEW_US2(obn->data ) - else obn->data= copy_lattice(obn->data); - id->us--; + if(cu->flag & CU_UV_ORCO) + cu1->flag |= CU_UV_ORCO; + else + cu1->flag &= ~CU_UV_ORCO; + } } - break; - case OB_CAMERA: - if(dupflag!=0) { - ID_NEW_US2(obn->data ) - else obn->data= copy_camera(obn->data); - id->us--; + else if(event==29) { /* protected bits */ + base->object->protectflag= ob->protectflag; } - break; - } - - if(dupflag & USER_DUP_MAT) { - matarar= give_matarar(obn); - if(didit && matarar) { - for(a=0; atotcol; a++) { - id= (ID *)(*matarar)[a]; - if(id) { - ID_NEW_US( (*matarar)[a] ) - else (*matarar)[a]= copy_material((*matarar)[a]); - - id->us--; - } + else if(event==30) { /* index object */ + base->object->index= ob->index; + } + else if(event==31) { /* object color */ + QUATCOPY(base->object->col, ob->col); } } } } - return basen; -} + + if(do_scene_sort) + DAG_scene_sort(scene); -/* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */ -/* leaves selection of base/object unaltered */ -Base *ED_object_add_duplicate(Scene *scene, Base *base, int dupflag) -{ - Base *basen; + ED_anim_dag_flush_update(C); - clear_id_newpoins(); - clear_sca_new_poins(); /* sensor/contr/act */ - - basen= object_add_duplicate_internal(scene, base, dupflag); - - DAG_scene_sort(scene); - - return basen; } -/* contextual operator dupli */ -static int duplicate_exec(bContext *C, wmOperator *op) +void copy_attr_menu(Scene *scene, View3D *v3d) { - Scene *scene= CTX_data_scene(C); - View3D *v3d= CTX_wm_view3d(C); - int linked= RNA_boolean_get(op->ptr, "linked"); - int dupflag= (linked)? 0: U.dupflag; + Object *ob; + short event; + char str[512]; - clear_id_newpoins(); - clear_sca_new_poins(); /* sensor/contr/act */ + if(!(ob=OBACT)) return; - CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - Base *basen= object_add_duplicate_internal(scene, base, dupflag); - - /* XXX context conflict maybe, itterator could solve this? */ - ED_base_object_select(base, BA_DESELECT); - /* new object becomes active */ - if(BASACT==base) - ED_base_object_activate(C, basen); - + if (scene->obedit) { // XXX get from context +// if (ob->type == OB_MESH) +// XXX mesh_copy_menu(); + return; } - CTX_DATA_END; - - /* XXX fix this for context */ - copy_object_set_idnew(scene, v3d, dupflag); - - DAG_scene_sort(scene); - ED_anim_dag_flush_update(C); - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - - return OPERATOR_FINISHED; -} - -static int duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - duplicate_exec(C, op); -// RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); -// WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_duplicate(wmOperatorType *ot) -{ + /* Object Mode */ - /* identifiers */ - ot->name= "Duplicate"; - ot->description = "Duplicate selected objects."; - ot->idname= "OBJECT_OT_duplicate"; + /* If you change this menu, don't forget to update the menu in header_view3d.c + * view3d_edit_object_copyattrmenu() and in toolbox.c + */ - /* api callbacks */ - ot->invoke= duplicate_invoke; - ot->exec= duplicate_exec; + strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|Object Color%x31|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l"); - ot->poll= ED_operator_scene_editable; + strcat (str, "|Object Constraints%x22"); + strcat (str, "|NLA Strips%x26"); - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +// XXX if (OB_SUPPORT_MATERIAL(ob)) { +// strcat(str, "|Texture Space%x17"); +// } - /* to give to transform */ - RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data."); - RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); -} - -/* ************************** JOIN *********************** */ - -static int join_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); - - if(scene->obedit) { - BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode."); - return OPERATOR_CANCELLED; - } - else if(!ob) { - BKE_report(op->reports, RPT_ERROR, "Can't join unless there is an active object."); - return OPERATOR_CANCELLED; - } - else if(object_data_is_libdata(ob)) { - BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata."); - return OPERATOR_CANCELLED; + if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19"); + if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28"); + + if((ob->type == OB_FONT) || (ob->type == OB_CURVE)) { + strcat(str, "|Curve Resolution%x25"); } - if(ob->type == OB_MESH) - return join_mesh_exec(C, op); - else if(ELEM(ob->type, OB_CURVE, OB_SURF)) - return join_curve_exec(C, op); - else if(ob->type == OB_ARMATURE) - return join_armature_exec(C, op); - - BKE_report(op->reports, RPT_ERROR, "This object type doesn't support joining."); - - return OPERATOR_CANCELLED; -} + if(ob->type==OB_MESH){ + strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27"); + } -void OBJECT_OT_join(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Join"; - ot->description = "Join selected objects into active object."; - ot->idname= "OBJECT_OT_join"; + if(ob->soft) strcat(str, "|Soft Body Settings%x23"); - /* api callbacks */ - ot->exec= join_exec; - ot->poll= ED_operator_scene_editable; + strcat(str, "|Pass Index%x30"); - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + if(ob->type==OB_MESH || ob->type==OB_CURVE || ob->type==OB_LATTICE || ob->type==OB_SURF){ + strcat(str, "|Modifiers ...%x24"); + } + + event= pupmenu(str); + if(event<= 0) return; + + copy_attr(scene, v3d, event); } /********************** Smooth/Flat *********************/ @@ -7095,124 +1890,6 @@ void rand_timeoffs(Scene *scene, View3D *v3d) } - -void texspace_edit(Scene *scene, View3D *v3d) -{ - Base *base; - int nr=0; - - /* first test if from visible and selected objects - * texspacedraw is set: - */ - - if(scene->obedit) return; // XXX get from context - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - break; - } - } - - if(base==0) { - return; - } - - nr= pupmenu("Texture Space %t|Grab/Move%x1|Size%x2"); - if(nr<1) return; - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - base->object->dtx |= OB_TEXSPACE; - } - } - - - if(nr==1) { -// XXX initTransform(TFM_TRANSLATION, CTX_TEXTURE); -// XXX Transform(); - } - else if(nr==2) { -// XXX initTransform(TFM_RESIZE, CTX_TEXTURE); -// XXX Transform(); - } - else if(nr==3) { -// XXX initTransform(TFM_ROTATION, CTX_TEXTURE); -// XXX Transform(); - } -} - -/* ******************************************************************** */ -/* Mirror function in Edit Mode */ - -void mirrormenu(void) -{ -// XXX initTransform(TFM_MIRROR, CTX_NO_PET); -// XXX Transform(); -} - -void hookmenu(Scene *scene, View3D *v3d) -{ - /* only called in object mode */ - short event, changed=0; - Object *ob; - Base *base; - ModifierData *md; - HookModifierData *hmd; - - event= pupmenu("Modify Hooks for Selected...%t|Reset Offset%x1|Recenter at Cursor%x2"); - if (event==-1) return; - if (event==2 && !(v3d)) { - error("Cannot perform this operation without a 3d view"); - return; - } - - for (base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - for (md = base->object->modifiers.first; md; md=md->next) { - if (md->type==eModifierType_Hook) { - ob = base->object; - hmd = (HookModifierData*) md; - - /* - * Copied from modifiers_cursorHookCenter and - * modifiers_clearHookOffset, should consolidate - * */ - - if (event==1) { - if(hmd->object) { - Mat4Invert(hmd->object->imat, hmd->object->obmat); - Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); - - changed= 1; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } else { - float *curs = give_cursor(scene, v3d); - float bmat[3][3], imat[3][3]; - - where_is_object(scene, ob); - - Mat3CpyMat4(bmat, ob->obmat); - Mat3Inv(imat, bmat); - - curs= give_cursor(scene, v3d); - hmd->cent[0]= curs[0]-ob->obmat[3][0]; - hmd->cent[1]= curs[1]-ob->obmat[3][1]; - hmd->cent[2]= curs[2]-ob->obmat[3][2]; - Mat3MulVecfl(imat, hmd->cent); - - changed= 1; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } - } - } - } - - if (changed) { - } -} - static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *ptr, int *free) { EnumPropertyItem *input = object_mode_items; @@ -7373,7 +2050,7 @@ void ED_object_toggle_modes(bContext *C, int mode) WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_EXEC_REGION_WIN, NULL); } -/* game property ops */ +/************************ Game Properties ***********************/ static int game_property_new(bContext *C, wmOperator *op) { @@ -7441,3 +2118,4 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot) RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to remove ", 0, INT_MAX); } + diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c new file mode 100644 index 00000000000..c83f3022c7c --- /dev/null +++ b/source/blender/editors/object/object_group.c @@ -0,0 +1,364 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "DNA_group_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_scene.h" + +#include "ED_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "object_intern.h" + +/********************* 3d view operators ***********************/ + +static int objects_add_active_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= OBACT, *obt; + Group *group; + int ok = 0; + + if(!ob) return OPERATOR_CANCELLED; + + /* linking to same group requires its own loop so we can avoid + looking up the active objects groups each time */ + + for(group= G.main->group.first; group; group=group->id.next) { + if(object_in_group(ob, group)) { + /* Assign groups to selected objects */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + obt= base->object; + add_to_group(group, obt); + obt->flag |= OB_FROMGROUP; + base->flag |= OB_FROMGROUP; + base->object->recalc= OB_RECALC_OB; + ok = 1; + } + CTX_DATA_END; + } + } + + if(!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups"); + + DAG_scene_sort(scene); + WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GROUP_OT_objects_add_active(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Selected To Active Group"; + ot->description = "Add the object to an object group that contains the active object."; + ot->idname= "GROUP_OT_objects_add_active"; + + /* api callbacks */ + ot->exec= objects_add_active_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int objects_remove_active_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= OBACT, *obt; + Group *group; + int ok = 0; + + if(!ob) return OPERATOR_CANCELLED; + + /* linking to same group requires its own loop so we can avoid + looking up the active objects groups each time */ + + for(group= G.main->group.first; group; group=group->id.next) { + if(object_in_group(ob, group)) { + /* Assign groups to selected objects */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + obt= base->object; + rem_from_group(group, obt); + obt->flag &= ~OB_FROMGROUP; + base->flag &= ~OB_FROMGROUP; + base->object->recalc= OB_RECALC_OB; + ok = 1; + } + CTX_DATA_END; + } + } + + if(!ok) BKE_report(op->reports, RPT_ERROR, "Active Object contains no groups"); + + DAG_scene_sort(scene); + WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GROUP_OT_objects_remove_active(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Selected From Active Group"; + ot->description = "Remove the object from an object group that contains the active object."; + ot->idname= "GROUP_OT_objects_remove_active"; + + /* api callbacks */ + ot->exec= objects_remove_active_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int group_objects_remove_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Group *group= NULL; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + group = NULL; + while((group = find_group(base->object, group))) + rem_from_group(group, base->object); + + base->object->flag &= ~OB_FROMGROUP; + base->flag &= ~OB_FROMGROUP; + base->object->recalc= OB_RECALC_OB; + } + CTX_DATA_END; + + DAG_scene_sort(scene); + WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GROUP_OT_objects_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove From Groups"; + ot->description = "Remove selected objects from all groups."; + ot->idname= "GROUP_OT_objects_remove"; + + /* api callbacks */ + ot->exec= group_objects_remove_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int group_create_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Group *group= NULL; + char gid[32]; //group id + + RNA_string_get(op->ptr, "GID", gid); + + group= add_group(gid); + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + add_to_group(group, base->object); + base->object->flag |= OB_FROMGROUP; + base->flag |= OB_FROMGROUP; + base->object->recalc= OB_RECALC_OB; + } + CTX_DATA_END; + + DAG_scene_sort(scene); + WM_event_add_notifier(C, NC_GROUP|NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GROUP_OT_group_create(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Create New Group"; + ot->description = "Create an object group."; + ot->idname= "GROUP_OT_group_create"; + + /* api callbacks */ + ot->exec= group_create_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_string(ot->srna, "GID", "Group", 32, "Name", "Name of the new group"); +} + +/****************** properties window operators *********************/ + +static int group_add_exec(bContext *C, wmOperator *op) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Base *base; + Group *group; + int value= RNA_enum_get(op->ptr, "group"); + + if(!ob) + return OPERATOR_CANCELLED; + + base= object_in_scene(ob, scene); + if(!base) + return OPERATOR_CANCELLED; + + if(value == -1) + group= add_group( "Group" ); + else + group= BLI_findlink(&bmain->group, value); + + if(group) { + add_to_group(group, ob); + ob->flag |= OB_FROMGROUP; + base->flag |= OB_FROMGROUP; + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +static EnumPropertyItem group_items[]= { + {-1, "ADD_NEW", 0, "Add New Group", ""}, + {0, NULL, 0, NULL, NULL}}; + +static EnumPropertyItem *group_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + Main *bmain; + Group *group; + int a, totitem= 0; + + if(!C) /* needed for docs */ + return group_items; + + RNA_enum_items_add_value(&item, &totitem, group_items, -1); + + bmain= CTX_data_main(C); + if(bmain->group.first) + RNA_enum_item_add_separator(&item, &totitem); + + for(a=0, group=bmain->group.first; group; group=group->id.next, a++) { + tmp.value= a; + tmp.identifier= group->id.name+2; + tmp.name= group->id.name+2; + RNA_enum_item_add(&item, &totitem, &tmp); + } + + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; +} + +void OBJECT_OT_group_add(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Add Group"; + ot->idname= "OBJECT_OT_group_add"; + + /* api callbacks */ + ot->exec= group_add_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "group", group_items, -1, "Group", "Group to add object to."); + RNA_def_enum_funcs(prop, group_itemf); +} + +static int group_remove_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data; + Base *base; + + if(!ob || !group) + return OPERATOR_CANCELLED; + + base= object_in_scene(ob, scene); + if(!base) + return OPERATOR_CANCELLED; + + rem_from_group(group, ob); + + if(find_group(ob, NULL) == NULL) { + ob->flag &= ~OB_FROMGROUP; + base->flag &= ~OB_FROMGROUP; + } + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_group_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Group"; + ot->idname= "OBJECT_OT_group_remove"; + + /* api callbacks */ + ot->exec= group_remove_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c new file mode 100644 index 00000000000..ab7bcbc989d --- /dev/null +++ b/source/blender/editors/object/object_hook.c @@ -0,0 +1,608 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2002-2008 full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_listbase.h" +#include "BLI_string.h" + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_customdata.h" +#include "BKE_depsgraph.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_object.h" + +#include "ED_curve.h" +#include "ED_mesh.h" +#include "ED_object.h" +#include "ED_view3d.h" + +#include "object_intern.h" + +/* XXX operators for this are not implemented yet */ + +static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent) +{ + EditVert *eve; + int *index, nr, totvert=0; + + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->f & SELECT) totvert++; + } + if(totvert==0) return 0; + + *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); + *tot= totvert; + nr= 0; + cent[0]= cent[1]= cent[2]= 0.0; + + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->f & SELECT) { + *index= nr; index++; + VecAddf(cent, cent, eve->co); + } + nr++; + } + + VecMulf(cent, 1.0f/(float)totvert); + + return totvert; +} + +static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent) +{ + MDeformVert *dvert; + EditVert *eve; + int i, totvert=0; + + cent[0]= cent[1]= cent[2]= 0.0; + + if(obedit->actdef) { + + /* find the vertices */ + for(eve= em->verts.first; eve; eve= eve->next) { + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if(dvert) { + for(i=0; itotweight; i++){ + if(dvert->dw[i].def_nr == (obedit->actdef-1)) { + totvert++; + VecAddf(cent, cent, eve->co); + } + } + } + } + if(totvert) { + bDeformGroup *defGroup = BLI_findlink(&obedit->defbase, obedit->actdef-1); + strcpy(name, defGroup->name); + VecMulf(cent, 1.0f/(float)totvert); + return 1; + } + } + + return 0; +} + +static void select_editmesh_hook(Object *ob, HookModifierData *hmd) +{ + Mesh *me= ob->data; + EditMesh *em= BKE_mesh_get_editmesh(me); + EditVert *eve; + int index=0, nr=0; + + if (hmd->indexar == NULL) + return; + + for(eve= em->verts.first; eve; eve= eve->next, nr++) { + if(nr==hmd->indexar[index]) { + eve->f |= SELECT; + if(index < hmd->totindex-1) index++; + } + } + EM_select_flush(em); + + BKE_mesh_end_editmesh(me, em); +} + +static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar, float *cent) +{ + BPoint *bp; + int *index, nr, totvert=0, a; + + /* count */ + a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; + bp= editlatt->def; + while(a--) { + if(bp->f1 & SELECT) { + if(bp->hide==0) totvert++; + } + bp++; + } + + if(totvert==0) return 0; + + *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); + *tot= totvert; + nr= 0; + cent[0]= cent[1]= cent[2]= 0.0; + + a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; + bp= editlatt->def; + while(a--) { + if(bp->f1 & SELECT) { + if(bp->hide==0) { + *index= nr; index++; + VecAddf(cent, cent, bp->vec); + } + } + bp++; + nr++; + } + + VecMulf(cent, 1.0f/(float)totvert); + + return totvert; +} + +static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) +{ + Lattice *lt= obedit->data; + BPoint *bp; + int index=0, nr=0, a; + + /* count */ + a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; + bp= lt->editlatt->def; + while(a--) { + if(hmd->indexar[index]==nr) { + bp->f1 |= SELECT; + if(index < hmd->totindex-1) index++; + } + nr++; + bp++; + } +} + +static int return_editcurve_indexar(Object *obedit, int *tot, int **indexar, float *cent) +{ + ListBase *editnurb= curve_get_editcurve(obedit); + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int *index, a, nr, totvert=0; + + for(nu= editnurb->first; nu; nu= nu->next) { + if(nu->type == CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->f1 & SELECT) totvert++; + if(bezt->f2 & SELECT) totvert++; + if(bezt->f3 & SELECT) totvert++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->f1 & SELECT) totvert++; + bp++; + } + } + } + if(totvert==0) return 0; + + *indexar= index= MEM_mallocN(4*totvert, "hook indexar"); + *tot= totvert; + nr= 0; + cent[0]= cent[1]= cent[2]= 0.0; + + for(nu= editnurb->first; nu; nu= nu->next) { + if(nu->type == CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(bezt->f1 & SELECT) { + *index= nr; index++; + VecAddf(cent, cent, bezt->vec[0]); + } + nr++; + if(bezt->f2 & SELECT) { + *index= nr; index++; + VecAddf(cent, cent, bezt->vec[1]); + } + nr++; + if(bezt->f3 & SELECT) { + *index= nr; index++; + VecAddf(cent, cent, bezt->vec[2]); + } + nr++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->f1 & SELECT) { + *index= nr; index++; + VecAddf(cent, cent, bp->vec); + } + nr++; + bp++; + } + } + } + + VecMulf(cent, 1.0f/(float)totvert); + + return totvert; +} + +int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r) +{ + *indexar= NULL; + *tot= 0; + name[0]= 0; + + switch(obedit->type) { + case OB_MESH: + { + Mesh *me= obedit->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + /* check selected vertices first */ + if( return_editmesh_indexar(em, tot, indexar, cent_r)) { + BKE_mesh_end_editmesh(me, em); + return 1; + } else { + int ret = return_editmesh_vgroup(obedit, em, name, cent_r); + BKE_mesh_end_editmesh(me, em); + return ret; + } + } + case OB_CURVE: + case OB_SURF: + return return_editcurve_indexar(obedit, tot, indexar, cent_r); + case OB_LATTICE: + { + Lattice *lt= obedit->data; + return return_editlattice_indexar(lt->editlatt, tot, indexar, cent_r); + } + default: + return 0; + } +} + +static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) +{ + ListBase *editnurb= curve_get_editcurve(obedit); + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + int index=0, a, nr=0; + + for(nu= editnurb->first; nu; nu= nu->next) { + if(nu->type == CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(nr == hmd->indexar[index]) { + bezt->f1 |= SELECT; + if(indextotindex-1) index++; + } + nr++; + if(nr == hmd->indexar[index]) { + bezt->f2 |= SELECT; + if(indextotindex-1) index++; + } + nr++; + if(nr == hmd->indexar[index]) { + bezt->f3 |= SELECT; + if(indextotindex-1) index++; + } + nr++; + + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(nr == hmd->indexar[index]) { + bp->f1 |= SELECT; + if(indextotindex-1) index++; + } + nr++; + bp++; + } + } + } +} + +void object_hook_select(Object *ob, HookModifierData *hmd) +{ + if(ob->type==OB_MESH) select_editmesh_hook(ob, hmd); + else if(ob->type==OB_LATTICE) select_editlattice_hook(ob, hmd); + else if(ob->type==OB_CURVE) select_editcurve_hook(ob, hmd); + else if(ob->type==OB_SURF) select_editcurve_hook(ob, hmd); +} + + +void add_hook(Scene *scene, View3D *v3d, int mode) +{ + ModifierData *md = NULL; + HookModifierData *hmd = NULL; + Object *ob=NULL; + Object *obedit= scene->obedit; // XXX get from context + + if(obedit==NULL) return; + + /* preconditions */ + if(mode==2) { /* selected object */ + Base *base; + for(base= FIRSTBASE; base; base= base->next) { + if(TESTBASELIB(v3d, base)) { + if(base!=BASACT) { + ob= base->object; + break; + } + } + } + if(ob==NULL) { + // XXX error("Requires selected Object"); + return; + } + } + else if(mode!=1) { + int maxlen=0, a, nr; + char *cp; + + /* make pupmenu with hooks */ + for(md=obedit->modifiers.first; md; md= md->next) { + if (md->type==eModifierType_Hook) + maxlen+=32; + } + + if(maxlen==0) { + // XXX error("Object has no hooks yet"); + return; + } + + cp= MEM_callocN(maxlen+32, "temp string"); + if(mode==3) strcpy(cp, "Remove %t|"); + else if(mode==4) strcpy(cp, "Reassign %t|"); + else if(mode==5) strcpy(cp, "Select %t|"); + else if(mode==6) strcpy(cp, "Clear Offset %t|"); + + for(md=obedit->modifiers.first; md; md= md->next) { + if (md->type==eModifierType_Hook) { + strcat(cp, md->name); + strcat(cp, " |"); + } + } + + nr= 0; // XXX pupmenu(cp); + MEM_freeN(cp); + + if(nr<1) return; + + a= 1; + for(md=obedit->modifiers.first; md; md=md->next) { + if (md->type==eModifierType_Hook) { + if(a==nr) break; + a++; + } + } + + hmd = (HookModifierData*) md; + ob= hmd->object; + } + + /* do it, new hooks or reassign */ + if(mode==1 || mode==2 || mode==4) { + float cent[3]; + int tot, ok, *indexar; + char name[32]; + + ok = object_hook_index_array(obedit, &tot, &indexar, name, cent); + + if(ok==0) { + // XXX error("Requires selected vertices or active Vertex Group"); + } + else { + + if(mode==1) { + Base *base= BASACT, *newbase; + + ob= add_object(scene, OB_EMPTY); + /* set layers OK */ + newbase= BASACT; + newbase->lay= base->lay; + ob->lay= newbase->lay; + + /* transform cent to global coords for loc */ + VecMat4MulVecfl(ob->loc, obedit->obmat, cent); + + /* restore, add_object sets active */ + BASACT= base; + } + /* if mode is 2 or 4, ob has been set */ + + /* new hook */ + if(mode==1 || mode==2) { + ModifierData *md = obedit->modifiers.first; + + while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { + md = md->next; + } + + hmd = (HookModifierData*) modifier_new(eModifierType_Hook); + BLI_insertlinkbefore(&obedit->modifiers, md, hmd); + sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2); + } + else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */ + + hmd->object= ob; + hmd->indexar= indexar; + VecCopyf(hmd->cent, cent); + hmd->totindex= tot; + BLI_strncpy(hmd->name, name, 32); + + // TODO: need to take into account bone targets here too now... + if(mode==1 || mode==2) { + /* matrix calculus */ + /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ + /* (parentinv ) */ + + where_is_object(scene, ob); + + Mat4Invert(ob->imat, ob->obmat); + /* apparently this call goes from right to left... */ + Mat4MulSerie(hmd->parentinv, ob->imat, obedit->obmat, NULL, + NULL, NULL, NULL, NULL, NULL); + } + } + } + else if(mode==3) { /* remove */ + BLI_remlink(&obedit->modifiers, md); + modifier_free(md); + } + else if(mode==5) { /* select */ + // FIXME: this is now OBJECT_OT_hook_select + object_hook_select(obedit, hmd); + } + else if(mode==6) { /* clear offset */ + // FIXME: this is now OBJECT_OT_hook_reset operator + where_is_object(scene, ob); /* ob is hook->parent */ + + Mat4Invert(ob->imat, ob->obmat); + /* this call goes from right to left... */ + Mat4MulSerie(hmd->parentinv, ob->imat, obedit->obmat, NULL, + NULL, NULL, NULL, NULL, NULL); + } + + DAG_scene_sort(scene); +} + +void add_hook_menu(Scene *scene, View3D *v3d) +{ + Object *obedit= scene->obedit; // XXX get from context + int mode; + + if(obedit==NULL) return; + + if(modifiers_findByType(obedit, eModifierType_Hook)) + mode= 0; // XXX pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6"); + else + mode= 0; // XXX pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2"); + + if(mode<1) return; + + /* do operations */ + add_hook(scene, v3d, mode); +} + +void hookmenu(Scene *scene, View3D *v3d) +{ + /* only called in object mode */ + short event, changed=0; + Object *ob; + Base *base; + ModifierData *md; + HookModifierData *hmd; + + event= 0; // XXX pupmenu("Modify Hooks for Selected...%t|Reset Offset%x1|Recenter at Cursor%x2"); + if (event==-1) return; + if (event==2 && !(v3d)) { + // XXX error("Cannot perform this operation without a 3d view"); + return; + } + + for (base= FIRSTBASE; base; base= base->next) { + if(TESTBASELIB(v3d, base)) { + for (md = base->object->modifiers.first; md; md=md->next) { + if (md->type==eModifierType_Hook) { + ob = base->object; + hmd = (HookModifierData*) md; + + /* + * Copied from modifiers_cursorHookCenter and + * modifiers_clearHookOffset, should consolidate + * */ + + if (event==1) { + if(hmd->object) { + Mat4Invert(hmd->object->imat, hmd->object->obmat); + Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL); + + changed= 1; + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + } + } else { + float *curs = give_cursor(scene, v3d); + float bmat[3][3], imat[3][3]; + + where_is_object(scene, ob); + + Mat3CpyMat4(bmat, ob->obmat); + Mat3Inv(imat, bmat); + + curs= give_cursor(scene, v3d); + hmd->cent[0]= curs[0]-ob->obmat[3][0]; + hmd->cent[1]= curs[1]-ob->obmat[3][1]; + hmd->cent[2]= curs[2]-ob->obmat[3][2]; + Mat3MulVecfl(imat, hmd->cent); + + changed= 1; + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + } + } + } + } + } + + if (changed) { + } +} + diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 8eaa388cdf0..7d52e9c7c56 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -38,15 +38,39 @@ struct HookModifierData; /* internal exports only */ +/* object_transform.c */ +void OBJECT_OT_location_clear(struct wmOperatorType *ot); +void OBJECT_OT_rotation_clear(struct wmOperatorType *ot); +void OBJECT_OT_scale_clear(struct wmOperatorType *ot); +void OBJECT_OT_origin_clear(struct wmOperatorType *ot); +void OBJECT_OT_visual_transform_apply(struct wmOperatorType *ot); +void OBJECT_OT_location_apply(struct wmOperatorType *ot); +void OBJECT_OT_scale_apply(struct wmOperatorType *ot); +void OBJECT_OT_rotation_apply(struct wmOperatorType *ot); +void OBJECT_OT_center_set(struct wmOperatorType *ot); -/* object_edit.c */ -void OBJECT_OT_mode_set(struct wmOperatorType *ot); -void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot); -void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot); +/* object_relations.c */ void OBJECT_OT_parent_set(struct wmOperatorType *ot); void OBJECT_OT_parent_clear(struct wmOperatorType *ot); +void OBJECT_OT_vertex_parent_set(struct wmOperatorType *ot); void OBJECT_OT_track_set(struct wmOperatorType *ot); void OBJECT_OT_track_clear(struct wmOperatorType *ot); +void OBJECT_OT_slow_parent_set(struct wmOperatorType *ot); +void OBJECT_OT_slow_parent_clear(struct wmOperatorType *ot); +void OBJECT_OT_make_local(struct wmOperatorType *ot); +void OBJECT_OT_move_to_layer(struct wmOperatorType *ot); + +/* object_edit.c */ +void OBJECT_OT_mode_set(struct wmOperatorType *ot); +void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot); +void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot); +void OBJECT_OT_restrictview_set(struct wmOperatorType *ot); +void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot); +void OBJECT_OT_proxy_make(struct wmOperatorType *ot); +void OBJECT_OT_shade_smooth(struct wmOperatorType *ot); +void OBJECT_OT_shade_flat(struct wmOperatorType *ot); + +/* object_select.c */ void OBJECT_OT_select_all_toggle(struct wmOperatorType *ot); void OBJECT_OT_select_inverse(struct wmOperatorType *ot); void OBJECT_OT_select_random(struct wmOperatorType *ot); @@ -55,37 +79,28 @@ void OBJECT_OT_select_by_layer(struct wmOperatorType *ot); void OBJECT_OT_select_linked(struct wmOperatorType *ot); void OBJECT_OT_select_grouped(struct wmOperatorType *ot); void OBJECT_OT_select_mirror(struct wmOperatorType *ot); -void OBJECT_OT_location_clear(struct wmOperatorType *ot); -void OBJECT_OT_rotation_clear(struct wmOperatorType *ot); -void OBJECT_OT_scale_clear(struct wmOperatorType *ot); -void OBJECT_OT_origin_clear(struct wmOperatorType *ot); -void OBJECT_OT_restrictview_set(struct wmOperatorType *ot); -void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot); -void OBJECT_OT_slowparent_set(struct wmOperatorType *ot); -void OBJECT_OT_slowparent_clear(struct wmOperatorType *ot); -void OBJECT_OT_center_set(struct wmOperatorType *ot); -void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); -void OBJECT_OT_object_add(struct wmOperatorType *ot); -void OBJECT_OT_duplicate(struct wmOperatorType *ot); -void OBJECT_OT_delete(struct wmOperatorType *ot); -void OBJECT_OT_join(struct wmOperatorType *ot); -void OBJECT_OT_proxy_make(struct wmOperatorType *ot); -void OBJECT_OT_shade_smooth(struct wmOperatorType *ot); -void OBJECT_OT_shade_flat(struct wmOperatorType *ot); +/* object_add.c */ +void OBJECT_OT_add(struct wmOperatorType *ot); void OBJECT_OT_mesh_add(struct wmOperatorType *ot); void OBJECT_OT_curve_add(struct wmOperatorType *ot); void OBJECT_OT_surface_add(struct wmOperatorType *ot); -void OBJECT_OT_metaball_add(wmOperatorType *ot); +void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); - /* only used as menu */ -void OBJECT_OT_primitive_add(struct wmOperatorType *ot); +void OBJECT_OT_primitive_add(struct wmOperatorType *ot); /* only used as menu */ + +void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); +void OBJECT_OT_duplicate(struct wmOperatorType *ot); +void OBJECT_OT_delete(struct wmOperatorType *ot); +void OBJECT_OT_join(struct wmOperatorType *ot); +void OBJECT_OT_convert(struct wmOperatorType *ot); +/* object_hook.c */ int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r); void object_hook_select(Object *obedit, struct HookModifierData *hmd); -/* editlattice.c */ +/* object_lattice.c */ void free_editLatt(Object *ob); void make_editLatt(Object *obedit); void load_editLatt(Object *obedit); @@ -94,7 +109,7 @@ void remake_editLatt(Object *obedit); void LATTICE_OT_select_all_toggle(struct wmOperatorType *ot); void LATTICE_OT_make_regular(struct wmOperatorType *ot); -/* editgroup.c */ +/* object_group.c */ void GROUP_OT_group_create(struct wmOperatorType *ot); void GROUP_OT_objects_remove(struct wmOperatorType *ot); void GROUP_OT_objects_add_active(struct wmOperatorType *ot); @@ -117,7 +132,7 @@ void OBJECT_OT_hook_select(struct wmOperatorType *ot); void OBJECT_OT_hook_assign(struct wmOperatorType *ot); void OBJECT_OT_explode_refresh(struct wmOperatorType *ot); -/* editconstraint.c */ +/* object_constraint.c */ void OBJECT_OT_constraint_add(struct wmOperatorType *ot); void OBJECT_OT_constraint_add_with_targets(struct wmOperatorType *ot); void POSE_OT_constraint_add(struct wmOperatorType *ot); @@ -148,11 +163,13 @@ void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_menu(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); void OBJECT_OT_game_property_new(struct wmOperatorType *ot); void OBJECT_OT_game_property_remove(struct wmOperatorType *ot); -/* editkey.c */ +/* object_shapekey.c */ void OBJECT_OT_shape_key_add(struct wmOperatorType *ot); void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c new file mode 100644 index 00000000000..b35d3908b43 --- /dev/null +++ b/source/blender/editors/object/object_lattice.c @@ -0,0 +1,382 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_curve_types.h" +#include "DNA_key_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_key.h" +#include "BKE_lattice.h" +#include "BKE_mesh.h" +#include "BKE_utildefines.h" + +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_view3d.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "object_intern.h" + +/********************** Load/Make/Free ********************/ + +void free_editLatt(Object *ob) +{ + Lattice *lt= ob->data; + + if(lt->editlatt) { + if(lt->editlatt->def) + MEM_freeN(lt->editlatt->def); + if(lt->editlatt->dvert) + free_dverts(lt->editlatt->dvert, lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw); + + MEM_freeN(lt->editlatt); + lt->editlatt= NULL; + } +} + +void make_editLatt(Object *obedit) +{ + Lattice *lt= obedit->data; + KeyBlock *actkey; + + free_editLatt(obedit); + + lt= obedit->data; + + actkey= ob_get_keyblock(obedit); + if(actkey) + key_to_latt(actkey, lt); + + lt->editlatt= MEM_dupallocN(lt); + lt->editlatt->def= MEM_dupallocN(lt->def); + + if(lt->dvert) { + int tot= lt->pntsu*lt->pntsv*lt->pntsw; + lt->editlatt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); + copy_dverts(lt->editlatt->dvert, lt->dvert, tot); + } +} + +void load_editLatt(Object *obedit) +{ + Lattice *lt; + KeyBlock *actkey; + BPoint *bp; + float *fp; + int tot; + + lt= obedit->data; + + actkey= ob_get_keyblock(obedit); + + if(actkey) { + /* active key: vertices */ + tot= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; + + if(actkey->data) MEM_freeN(actkey->data); + + fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data"); + actkey->totelem= tot; + + bp= lt->editlatt->def; + while(tot--) { + VECCOPY(fp, bp->vec); + fp+= 3; + bp++; + } + } + else { + MEM_freeN(lt->def); + + lt->def= MEM_dupallocN(lt->editlatt->def); + + lt->flag= lt->editlatt->flag; + + lt->pntsu= lt->editlatt->pntsu; + lt->pntsv= lt->editlatt->pntsv; + lt->pntsw= lt->editlatt->pntsw; + + lt->typeu= lt->editlatt->typeu; + lt->typev= lt->editlatt->typev; + lt->typew= lt->editlatt->typew; + } + + if(lt->dvert) { + free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw); + lt->dvert= NULL; + } + + if(lt->editlatt->dvert) { + int tot= lt->pntsu*lt->pntsv*lt->pntsw; + + lt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); + copy_dverts(lt->dvert, lt->editlatt->dvert, tot); + } +} + +/************************** Operators *************************/ + +static void setflagsLatt(Object *obedit, int flag) +{ + Lattice *lt= obedit->data; + BPoint *bp; + int a; + + bp= lt->editlatt->def; + + a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; + + while(a--) { + if(bp->hide==0) { + bp->f1= flag; + } + bp++; + } +} + +int de_select_all_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + Lattice *lt= obedit->data; + BPoint *bp; + int a, deselect= 0; + + bp= lt->editlatt->def; + a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; + + while(a--) { + if(bp->hide==0) { + if(bp->f1) { + deselect= 1; + break; + } + } + bp++; + } + + if(deselect) + setflagsLatt(obedit, 0); + else + setflagsLatt(obedit, 1); + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_all_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select or Deselect All"; + ot->idname= "LATTICE_OT_select_all_toggle"; + + /* api callbacks */ + ot->exec= de_select_all_exec; + ot->poll= ED_operator_editlattice; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +int make_regular_poll(bContext *C) +{ + Object *ob; + + if(ED_operator_editlattice(C)) return 1; + + ob= CTX_data_active_object(C); + return (ob && ob->type==OB_LATTICE); +} + +int make_regular_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_edit_object(C); + Lattice *lt; + + if(ob) { + lt= ob->data; + resizelattice(lt->editlatt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); + } + else { + ob= CTX_data_active_object(C); + lt= ob->data; + resizelattice(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); + } + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_make_regular(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Regular"; + ot->idname= "LATTICE_OT_make_regular"; + + /* api callbacks */ + ot->exec= make_regular_exec; + ot->poll= make_regular_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/****************************** Mouse Selection *************************/ + +static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y) +{ + struct { BPoint *bp; short dist, select, mval[2]; } *data = userData; + float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y); + + if((bp->f1 & SELECT)==data->select) + temp += 5; + + if(tempdist) { + data->dist = temp; + + data->bp = bp; + } +} + +static BPoint *findnearestLattvert(ViewContext *vc, short mval[2], int sel) +{ + /* sel==1: selected gets a disadvantage */ + /* in nurb and bezt or bp the nearest is written */ + /* return 0 1 2: handlepunt */ + struct { BPoint *bp; short dist, select, mval[2]; } data = {0}; + + data.dist = 100; + data.select = sel; + data.mval[0]= mval[0]; + data.mval[1]= mval[1]; + + lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); + + return data.bp; +} + +void mouse_lattice(bContext *C, short mval[2], int extend) +{ + ViewContext vc; + BPoint *bp= NULL; + + view3d_set_viewcontext(C, &vc); + bp= findnearestLattvert(&vc, mval, 1); + + if(bp) { + if(extend==0) { + setflagsLatt(vc.obedit, 0); + bp->f1 |= SELECT; + } + else + bp->f1 ^= SELECT; /* swap */ + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); + } +} + +/******************************** Undo *************************/ + +typedef struct UndoLattice { + BPoint *def; + int pntsu, pntsv, pntsw; +} UndoLattice; + +static void undoLatt_to_editLatt(void *data, void *edata) +{ + UndoLattice *ult= (UndoLattice*)data; + Lattice *editlatt= (Lattice *)edata; + int a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; + + memcpy(editlatt->def, ult->def, a*sizeof(BPoint)); +} + +static void *editLatt_to_undoLatt(void *edata) +{ + UndoLattice *ult= MEM_callocN(sizeof(UndoLattice), "UndoLattice"); + Lattice *editlatt= (Lattice *)edata; + + ult->def= MEM_dupallocN(editlatt->def); + ult->pntsu= editlatt->pntsu; + ult->pntsv= editlatt->pntsv; + ult->pntsw= editlatt->pntsw; + + return ult; +} + +static void free_undoLatt(void *data) +{ + UndoLattice *ult= (UndoLattice*)data; + + if(ult->def) MEM_freeN(ult->def); + MEM_freeN(ult); +} + +static int validate_undoLatt(void *data, void *edata) +{ + UndoLattice *ult= (UndoLattice*)data; + Lattice *editlatt= (Lattice *)edata; + + return (ult->pntsu == editlatt->pntsu && + ult->pntsv == editlatt->pntsv && + ult->pntsw == editlatt->pntsw); +} + +static void *get_editlatt(bContext *C) +{ + Object *obedit= CTX_data_edit_object(C); + + if(obedit && obedit->type==OB_LATTICE) { + Lattice *lt= obedit->data; + return lt->editlatt; + } + + return NULL; +} + +/* and this is all the undo system needs to know */ +void undo_push_lattice(bContext *C, char *name) +{ + undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); +} + diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index aecb778db06..cc8cc420bf7 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -809,58 +809,6 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -#if 0 -typedef struct MenuEntry { - char *name; - int ID; -} MenuEntry; - -static int menuEntry_compare_names(const void *entry1, const void *entry2) -{ - return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name); -} - -static uiBlock *modifiers_add_menu(void *ob_v) -{ - Object *ob = ob_v; - uiBlock *block; - int i, yco=0; - int numEntries = 0; - MenuEntry entries[NUM_MODIFIER_TYPES]; - - block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu", - UI_EMBOSSP, UI_HELV, curarea->win); - uiBlockSetButmFunc(block, modifiers_add, ob); - - for (i=eModifierType_None+1; iflags&eModifierTypeFlag_AcceptsCVs) || - (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { - entries[numEntries].name = mti->name; - entries[numEntries].ID = i; - - ++numEntries; - } - } - - qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names); - - - for(i = 0; i < numEntries; ++i) - uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name, - 0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, ""); - - uiTextBoundsBlock(block, 50); - uiBlockSetDirection(block, UI_DOWN); - - return block; -} -#endif - /******************** hook operators ************************/ static int hook_poll(bContext *C) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 09a27e9e613..bb8c5dc292e 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -64,14 +64,36 @@ void ED_operatortypes_object(void) { wmOperatorType *ot; + + WM_operatortype_append(OBJECT_OT_location_clear); + WM_operatortype_append(OBJECT_OT_rotation_clear); + WM_operatortype_append(OBJECT_OT_scale_clear); + WM_operatortype_append(OBJECT_OT_origin_clear); + WM_operatortype_append(OBJECT_OT_visual_transform_apply); + WM_operatortype_append(OBJECT_OT_location_apply); + WM_operatortype_append(OBJECT_OT_scale_apply); + WM_operatortype_append(OBJECT_OT_rotation_apply); + WM_operatortype_append(OBJECT_OT_center_set); WM_operatortype_append(OBJECT_OT_mode_set); WM_operatortype_append(OBJECT_OT_editmode_toggle); WM_operatortype_append(OBJECT_OT_posemode_toggle); + WM_operatortype_append(OBJECT_OT_proxy_make); + WM_operatortype_append(OBJECT_OT_restrictview_clear); + WM_operatortype_append(OBJECT_OT_restrictview_set); + WM_operatortype_append(OBJECT_OT_shade_smooth); + WM_operatortype_append(OBJECT_OT_shade_flat); + WM_operatortype_append(OBJECT_OT_parent_set); WM_operatortype_append(OBJECT_OT_parent_clear); + WM_operatortype_append(OBJECT_OT_vertex_parent_set); WM_operatortype_append(OBJECT_OT_track_set); WM_operatortype_append(OBJECT_OT_track_clear); + WM_operatortype_append(OBJECT_OT_slow_parent_set); + WM_operatortype_append(OBJECT_OT_slow_parent_clear); + WM_operatortype_append(OBJECT_OT_make_local); + WM_operatortype_append(OBJECT_OT_move_to_layer); + WM_operatortype_append(OBJECT_OT_select_inverse); WM_operatortype_append(OBJECT_OT_select_random); WM_operatortype_append(OBJECT_OT_select_all_toggle); @@ -80,21 +102,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_linked); WM_operatortype_append(OBJECT_OT_select_grouped); WM_operatortype_append(OBJECT_OT_select_mirror); - WM_operatortype_append(OBJECT_OT_location_clear); - WM_operatortype_append(OBJECT_OT_rotation_clear); - WM_operatortype_append(OBJECT_OT_scale_clear); - WM_operatortype_append(OBJECT_OT_origin_clear); - WM_operatortype_append(OBJECT_OT_restrictview_clear); - WM_operatortype_append(OBJECT_OT_restrictview_set); - WM_operatortype_append(OBJECT_OT_slowparent_set); - WM_operatortype_append(OBJECT_OT_slowparent_clear); - WM_operatortype_append(OBJECT_OT_center_set); - WM_operatortype_append(OBJECT_OT_duplicates_make_real); - WM_operatortype_append(OBJECT_OT_duplicate); - WM_operatortype_append(OBJECT_OT_join); - WM_operatortype_append(OBJECT_OT_proxy_make); - WM_operatortype_append(OBJECT_OT_shade_smooth); - WM_operatortype_append(OBJECT_OT_shade_flat); + WM_operatortype_append(GROUP_OT_group_create); WM_operatortype_append(GROUP_OT_objects_remove); WM_operatortype_append(GROUP_OT_objects_add_active); @@ -106,10 +114,14 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_text_add); WM_operatortype_append(OBJECT_OT_surface_add); WM_operatortype_append(OBJECT_OT_armature_add); - WM_operatortype_append(OBJECT_OT_object_add); + WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_primitive_add); WM_operatortype_append(OBJECT_OT_mesh_add); WM_operatortype_append(OBJECT_OT_metaball_add); + WM_operatortype_append(OBJECT_OT_duplicates_make_real); + WM_operatortype_append(OBJECT_OT_duplicate); + WM_operatortype_append(OBJECT_OT_join); + WM_operatortype_append(OBJECT_OT_convert); WM_operatortype_append(OBJECT_OT_modifier_add); WM_operatortype_append(OBJECT_OT_modifier_remove); @@ -151,6 +163,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_deselect); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); WM_operatortype_append(OBJECT_OT_vertex_group_copy); + WM_operatortype_append(OBJECT_OT_vertex_group_menu); + WM_operatortype_append(OBJECT_OT_vertex_group_set_active); WM_operatortype_append(OBJECT_OT_game_property_new); WM_operatortype_append(OBJECT_OT_game_property_remove); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c new file mode 100644 index 00000000000..6fe01cced74 --- /dev/null +++ b/source/blender/editors/object/object_relations.c @@ -0,0 +1,1766 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2002-2008 full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" + +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_listbase.h" +#include "BLI_string.h" + +#include "BKE_action.h" +#include "BKE_animsys.h" +#include "BKE_armature.h" +#include "BKE_context.h" +#include "BKE_constraint.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_lattice.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_sca.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "ED_anim_api.h" +#include "ED_armature.h" +#include "ED_curve.h" +#include "ED_object.h" +#include "ED_screen.h" + +#include "object_intern.h" + +/* ************* XXX **************** */ +static int pupmenu(const char *msg) {return 0;} +static int pupmenu_col(const char *msg, int val) {return 0;} + +/*********************** Make Vertex Parent Operator ************************/ + +static int vertex_parent_set_poll(bContext *C) +{ + return ED_operator_editmesh(C) || ED_operator_editsurfcurve(C) || ED_operator_editlattice(C); +} + +static int vertex_parent_set_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditVert *eve; + Curve *cu; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + Object *par; + int a, v1=0, v2=0, v3=0, v4=0, nr=1; + + /* we need 1 to 3 selected vertices */ + + if(obedit->type==OB_MESH) { + Mesh *me= obedit->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + eve= em->verts.first; + while(eve) { + if(eve->f & 1) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else if(v4==0) v4= nr; + else break; + } + nr++; + eve= eve->next; + } + + BKE_mesh_end_editmesh(me, em); + } + else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) { + ListBase *editnurb= curve_get_editcurve(obedit); + + cu= obedit->data; + + nu= editnurb->first; + while(nu) { + if(nu->type == CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + if(BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else if(v4==0) v4= nr; + else break; + } + nr++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->f1 & SELECT) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else if(v4==0) v4= nr; + else break; + } + nr++; + bp++; + } + } + nu= nu->next; + } + } + else if(obedit->type==OB_LATTICE) { + Lattice *lt= obedit->data; + + a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; + bp= lt->editlatt->def; + while(a--) { + if(bp->f1 & SELECT) { + if(v1==0) v1= nr; + else if(v2==0) v2= nr; + else if(v3==0) v3= nr; + else if(v4==0) v4= nr; + else break; + } + nr++; + bp++; + } + } + + if(v4 || !((v1 && v2==0 && v3==0) || (v1 && v2 && v3)) ) { + BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to"); + return OPERATOR_CANCELLED; + } + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob != obedit) { + ob->recalc |= OB_RECALC; + par= obedit->parent; + + while(par) { + if(par==ob) break; + par= par->parent; + } + if(par) { + BKE_report(op->reports, RPT_ERROR, "Loop in parents"); + } + else { + Object workob; + + ob->parent= BASACT->object; + if(v3) { + ob->partype= PARVERT3; + ob->par1= v1-1; + ob->par2= v2-1; + ob->par3= v3-1; + + /* inverse parent matrix */ + what_does_parent(scene, ob, &workob); + Mat4Invert(ob->parentinv, workob.obmat); + } + else { + ob->partype= PARVERT1; + ob->par1= v1-1; + + /* inverse parent matrix */ + what_does_parent(scene, ob, &workob); + Mat4Invert(ob->parentinv, workob.obmat); + } + } + } + } + CTX_DATA_END; + + DAG_scene_sort(scene); + + WM_event_add_notifier(C, NC_OBJECT, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_parent_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Vertex Parent"; + ot->description = "Parent selected objects to the selected vertices."; + ot->idname= "OBJECT_OT_vertex_parent_set"; + + /* api callbacks */ + ot->poll= vertex_parent_set_poll; + ot->exec= vertex_parent_set_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** Make Proxy Operator *************************/ + +/* present menu listing the possible objects within the group to proxify */ +static void proxy_group_objects_menu (bContext *C, wmOperator *op, Object *ob, Group *group) +{ + uiPopupMenu *pup; + uiLayout *layout; + GroupObject *go; + int len=0; + + /* check if there are any objects within the group to assign for */ + for (go= group->gobject.first; go; go= go->next) { + if (go->ob) len++; + } + if (len==0) return; + + /* now create the menu to draw */ + pup= uiPupMenuBegin(C, "Make Proxy For:", 0); + layout= uiPupMenuLayout(pup); + + for (go= group->gobject.first; go; go= go->next) { + if (go->ob) { + PointerRNA props_ptr; + + /* create operator menu item with relevant properties filled in */ + props_ptr= uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + RNA_string_set(&props_ptr, "object", go->ob->id.name+2); + RNA_string_set(&props_ptr, "group_object", go->ob->id.name+2); + } + } + + /* display the menu, and be done */ + uiPupMenuEnd(C, pup); +} + +/* set the object to proxify */ +static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_active_object(C); + + /* sanity checks */ + if (!scene || scene->id.lib || !ob) + return OPERATOR_CANCELLED; + + /* Get object to work on - use a menu if we need to... */ + if (ob->dup_group && ob->dup_group->id.lib) { + /* gives menu with list of objects in group */ + proxy_group_objects_menu(C, op, ob, ob->dup_group); + } + else if (ob->id.lib) { + uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); + uiLayout *layout= uiPupMenuLayout(pup); + PointerRNA props_ptr; + + /* create operator menu item with relevant properties filled in */ + props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + RNA_string_set(&props_ptr, "object", ob->id.name+2); + + /* present the menu and be done... */ + uiPupMenuEnd(C, pup); + } + else { + /* error.. cannot continue */ + BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group"); + } + + /* this invoke just calls another instance of this operator... */ + return OPERATOR_CANCELLED; +} + +static int make_proxy_exec (bContext *C, wmOperator *op) +{ + Object *ob=NULL, *gob=NULL; + Scene *scene= CTX_data_scene(C); + char ob_name[21], gob_name[21]; + + /* get object and group object + * - firstly names + * - then pointers from context + */ + RNA_string_get(op->ptr, "object", ob_name); + RNA_string_get(op->ptr, "group_object", gob_name); + + if (gob_name[0]) { + Group *group; + GroupObject *go; + + /* active object is group object... */ + // FIXME: we should get the nominated name instead + gob= CTX_data_active_object(C); + group= gob->dup_group; + + /* find the object to affect */ + for (go= group->gobject.first; go; go= go->next) { + if ((go->ob) && strcmp(go->ob->id.name+2, gob_name)==0) { + ob= go->ob; + break; + } + } + } + else { + /* just use the active object for now */ + // FIXME: we should get the nominated name instead + ob= CTX_data_active_object(C); + } + + if (ob) { + Object *newob; + Base *newbase, *oldbase= BASACT; + char name[32]; + + /* Add new object for the proxy */ + newob= add_object(scene, OB_EMPTY); + if (gob) + strcpy(name, gob->id.name+2); + else + strcpy(name, ob->id.name+2); + strcat(name, "_proxy"); + rename_id(&newob->id, name); + + /* set layers OK */ + newbase= BASACT; /* add_object sets active... */ + newbase->lay= oldbase->lay; + newob->lay= newbase->lay; + + /* remove base, leave user count of object, it gets linked in object_make_proxy */ + if (gob==NULL) { + BLI_remlink(&scene->base, oldbase); + MEM_freeN(oldbase); + } + + object_make_proxy(newob, ob, gob); + + /* depsgraph flushes are needed for the new data */ + DAG_scene_sort(scene); + DAG_id_flush_update(&newob->id, OB_RECALC); + + WM_event_add_notifier(C, NC_OBJECT, NULL); + } + else { + BKE_report(op->reports, RPT_ERROR, "No object to make proxy for"); + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_proxy_make (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Proxy"; + ot->idname= "OBJECT_OT_proxy_make"; + ot->description= "Add empty object to become local replacement data of a library-linked object"; + + /* callbacks */ + ot->invoke= make_proxy_invoke; + ot->exec= make_proxy_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "object", "", 19, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for."); + RNA_def_string(ot->srna, "group_object", "", 19, "Group Object", "Name of group instancer (if applicable)."); +} + +/********************** Clear Parent Operator ******************* */ + +static EnumPropertyItem prop_clear_parent_types[] = { + {0, "CLEAR", 0, "Clear Parent", ""}, + {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""}, + {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, + {0, NULL, 0, NULL, NULL} +}; + +/* note, poll should check for editable scene */ +static int parent_clear_exec(bContext *C, wmOperator *op) +{ + int type= RNA_enum_get(op->ptr, "type"); + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + + if(type == 0) { + ob->parent= NULL; + } + else if(type == 1) { + ob->parent= NULL; + ob->track= NULL; + ED_object_apply_obmat(ob); + } + else if(type == 2) + Mat4One(ob->parentinv); + + ob->recalc |= OB_RECALC; + } + CTX_DATA_END; + + DAG_scene_sort(CTX_data_scene(C)); + ED_anim_dag_flush_update(C); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Parent"; + ot->description = "Clear the object's parenting."; + ot->idname= "OBJECT_OT_parent_clear"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= parent_clear_exec; + + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); +} + +/* ******************** Make Parent Operator *********************** */ + +#define PAR_OBJECT 0 +#define PAR_ARMATURE 1 +#define PAR_ARMATURE_NAME 2 +#define PAR_ARMATURE_ENVELOPE 3 +#define PAR_ARMATURE_AUTO 4 +#define PAR_BONE 5 +#define PAR_CURVE 6 +#define PAR_FOLLOW 7 +#define PAR_PATH_CONST 8 +#define PAR_LATTICE 9 +#define PAR_VERTEX 10 +#define PAR_TRIA 11 + +static EnumPropertyItem prop_make_parent_types[] = { + {PAR_OBJECT, "OBJECT", 0, "Object", ""}, + {PAR_ARMATURE, "ARMATURE", 0, "Armature Deform", ""}, + {PAR_ARMATURE_NAME, "ARMATURE_NAME", 0, " With Empty Groups", ""}, + {PAR_ARMATURE_AUTO, "ARMATURE_AUTO", 0, " With Automatic Weights", ""}, + {PAR_ARMATURE_ENVELOPE, "ARMATURE_ENVELOPE", 0, " With Envelope Weights", ""}, + {PAR_BONE, "BONE", 0, "Bone", ""}, + {PAR_CURVE, "CURVE", 0, "Curve Deform", ""}, + {PAR_FOLLOW, "FOLLOW", 0, "Follow Path", ""}, + {PAR_PATH_CONST, "PATH_CONST", 0, "Path Constraint", ""}, + {PAR_LATTICE, "LATTICE", 0, "Lattice Deform", ""}, + {PAR_VERTEX, "VERTEX", 0, "Vertex", ""}, + {PAR_TRIA, "TRIA", 0, "Triangle", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int test_parent_loop(Object *par, Object *ob) +{ + /* test if 'ob' is a parent somewhere in par's parents */ + + if(par == NULL) return 0; + if(ob == par) return 1; + + return test_parent_loop(par->parent, ob); +} + +void ED_object_parent(Object *ob, Object *par, int type, const char *substr) +{ + if(!par || test_parent_loop(par, ob)) { + ob->parent= NULL; + ob->partype= PAROBJECT; + ob->parsubstr[0]= 0; + return; + } + + /* this could use some more checks */ + + ob->parent= par; + ob->partype &= ~PARTYPE; + ob->partype |= type; + BLI_strncpy(ob->parsubstr, substr, sizeof(ob->parsubstr)); +} + +static int parent_set_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *par= CTX_data_active_object(C); + bPoseChannel *pchan= NULL; + int partype= RNA_enum_get(op->ptr, "type"); + int pararm= ELEM4(partype, PAR_ARMATURE, PAR_ARMATURE_NAME, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO); + + par->recalc |= OB_RECALC_OB; + + /* preconditions */ + if(partype==PAR_FOLLOW || partype==PAR_PATH_CONST) { + if(par->type!=OB_CURVE) + return OPERATOR_CANCELLED; + else { + Curve *cu= par->data; + + if((cu->flag & CU_PATH)==0) { + cu->flag |= CU_PATH|CU_FOLLOW; + makeDispListCurveTypes(scene, par, 0); /* force creation of path data */ + } + else cu->flag |= CU_FOLLOW; + + /* fall back on regular parenting now */ + partype= PAR_OBJECT; + } + } + else if(partype==PAR_BONE) { + pchan= get_active_posechannel(par); + + if(pchan==NULL) { + BKE_report(op->reports, RPT_ERROR, "No active Bone"); + return OPERATOR_CANCELLED; + } + } + + /* context itterator */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + + if(ob!=par) { + + if( test_parent_loop(par, ob) ) { + BKE_report(op->reports, RPT_ERROR, "Loop in parents"); + } + else { + Object workob; + + /* apply transformation of previous parenting */ + ED_object_apply_obmat(ob); + + ob->parent= par; + + /* handle types */ + if (pchan) + strcpy (ob->parsubstr, pchan->name); + else + ob->parsubstr[0]= 0; + + /* constraint */ + if(partype==PAR_PATH_CONST) { + bConstraint *con; + bFollowPathConstraint *data; + float cmat[4][4], vec[3]; + + con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH); + strcpy (con->name, "AutoPath"); + + data = con->data; + data->tar = par; + + add_constraint_to_object(con, ob); + + get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob)); + VecSubf(vec, ob->obmat[3], cmat[3]); + + ob->loc[0] = vec[0]; + ob->loc[1] = vec[1]; + } + else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) { + if(partype == PAR_ARMATURE_NAME) + create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_NAME); + else if(partype == PAR_ARMATURE_ENVELOPE) + create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_ENVELOPE); + else if(partype == PAR_ARMATURE_AUTO) + create_vgroups_from_armature(scene, ob, par, ARM_GROUPS_AUTO); + + /* get corrected inverse */ + ob->partype= PAROBJECT; + what_does_parent(scene, ob, &workob); + + ob->partype= PARSKEL; + + Mat4Invert(ob->parentinv, workob.obmat); + } + else { + /* calculate inverse parent matrix */ + what_does_parent(scene, ob, &workob); + Mat4Invert(ob->parentinv, workob.obmat); + } + + ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; + + if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) + ob->partype= PARSKEL; /* note, dna define, not operator property */ + else + ob->partype= PAROBJECT; /* note, dna define, not operator property */ + } + } + } + CTX_DATA_END; + + DAG_scene_sort(CTX_data_scene(C)); + ED_anim_dag_flush_update(C); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Object *ob= CTX_data_active_object(C); + uiPopupMenu *pup= uiPupMenuBegin(C, "Set Parent To", 0); + uiLayout *layout= uiPupMenuLayout(pup); + + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_OBJECT); + + /* ob becomes parent, make the associated menus */ + if(ob->type==OB_ARMATURE) { + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_NAME); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_ENVELOPE); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE_AUTO); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_BONE); + } + else if(ob->type==OB_CURVE) { + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_CURVE); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_FOLLOW); + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_PATH_CONST); + } + else if(ob->type == OB_LATTICE) { + uiItemEnumO(layout, NULL, 0, "OBJECT_OT_parent_set", "type", PAR_LATTICE); + } + + uiPupMenuEnd(C, pup); + + return OPERATOR_CANCELLED; +} + + +void OBJECT_OT_parent_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Parent"; + ot->description = "Set the object's parenting."; + ot->idname= "OBJECT_OT_parent_set"; + + /* api callbacks */ + ot->invoke= parent_set_invoke; + ot->exec= parent_set_exec; + + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); +} + +/************************ Clear Slow Parent Operator *********************/ + +static int object_slow_parent_clear_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->parent) { + if(ob->partype & PARSLOW) { + ob->partype -= PARSLOW; + where_is_object(scene, ob); + ob->partype |= PARSLOW; + ob->recalc |= OB_RECALC_OB; + } + } + } + CTX_DATA_END; + + ED_anim_dag_flush_update(C); + WM_event_add_notifier(C, NC_SCENE, scene); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_slow_parent_clear(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Clear Slow Parent"; + ot->description = "Clear the object's slow parent."; + ot->idname= "OBJECT_OT_slow_parent_clear"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= object_slow_parent_clear_exec; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** Make Slow Parent Operator *********************/ + +static int object_slow_parent_set_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->parent) + ob->partype |= PARSLOW; + + ob->recalc |= OB_RECALC_OB; + + } + CTX_DATA_END; + + ED_anim_dag_flush_update(C); + WM_event_add_notifier(C, NC_SCENE, scene); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_slow_parent_set(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Set Slow Parent"; + ot->description = "Set the object's slow parent."; + ot->idname= "OBJECT_OT_slow_parent_set"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= object_slow_parent_set_exec; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ******************** Clear Track Operator ******************* */ + +static EnumPropertyItem prop_clear_track_types[] = { + {0, "CLEAR", 0, "Clear Track", ""}, + {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation (Clear Track)", ""}, + {0, NULL, 0, NULL, NULL} +}; + +/* note, poll should check for editable scene */ +static int object_track_clear_exec(bContext *C, wmOperator *op) +{ + int type= RNA_enum_get(op->ptr, "type"); + + if(CTX_data_edit_object(C)) { + BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode"); + return OPERATOR_CANCELLED; + } + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + ob->track= NULL; + ob->recalc |= OB_RECALC; + + if(type == 1) + ED_object_apply_obmat(ob); + } + CTX_DATA_END; + + DAG_scene_sort(CTX_data_scene(C)); + ED_anim_dag_flush_update(C); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_track_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear track"; + ot->description = "Clear tracking constraint or flag from object."; + ot->idname= "OBJECT_OT_track_clear"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_track_clear_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_clear_track_types, 0, "Type", ""); +} + +/************************** Make Track Operator *****************************/ + +static EnumPropertyItem prop_make_track_types[] = { + {1, "TRACKTO", 0, "TrackTo Constraint", ""}, + {2, "LOCKTRACK", 0, "LockTrack Constraint", ""}, + {3, "OLDTRACK", 0, "Old Track", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int track_set_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + int type= RNA_enum_get(op->ptr, "type"); + + if(type == 1) { + bConstraint *con; + bTrackToConstraint *data; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base!=BASACT) { + con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO); + strcpy (con->name, "AutoTrack"); + + data = con->data; + data->tar = BASACT->object; + base->object->recalc |= OB_RECALC; + + /* Lamp and Camera track differently by default */ + if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { + data->reserved1 = TRACK_nZ; + data->reserved2 = UP_Y; + } + + add_constraint_to_object(con, base->object); + } + } + CTX_DATA_END; + } + else if(type == 2) { + bConstraint *con; + bLockTrackConstraint *data; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base!=BASACT) { + con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK); + strcpy (con->name, "AutoTrack"); + + data = con->data; + data->tar = BASACT->object; + base->object->recalc |= OB_RECALC; + + /* Lamp and Camera track differently by default */ + if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { + data->trackflag = TRACK_nZ; + data->lockflag = LOCK_Y; + } + + add_constraint_to_object(con, base->object); + } + } + CTX_DATA_END; + } + else { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if(base!=BASACT) { + base->object->track= BASACT->object; + base->object->recalc |= OB_RECALC; + } + } + CTX_DATA_END; + } + DAG_scene_sort(CTX_data_scene(C)); + ED_anim_dag_flush_update(C); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_track_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Track"; + ot->description = "Make the object track another object, either by constraint or old way or locked track."; + ot->idname= "OBJECT_OT_track_set"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= track_set_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", ""); +} + +/************************** Move to Layer Operator *****************************/ + +static unsigned int move_to_layer_init(bContext *C, wmOperator *op) +{ + int values[20], a; + unsigned int lay= 0; + + if(!RNA_property_is_set(op->ptr, "layer")) { + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + lay |= base->lay; + } + CTX_DATA_END; + + for(a=0; a<20; a++) + values[a]= (lay & (1<ptr, "layer", values); + } + else { + RNA_boolean_get_array(op->ptr, "layer", values); + + for(a=0; a<20; a++) + if(values[a]) + lay |= (1 << a); + } + + return lay; +} + +static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + move_to_layer_init(C, op); + return WM_operator_props_popup(C, op, event); +} + +static int move_to_layer_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + unsigned int lay, local; + int islamp= 0; + + lay= move_to_layer_init(C, op); + lay &= 0xFFFFFF; + + if(lay==0) return OPERATOR_CANCELLED; + + if(v3d && v3d->localview) { + /* now we can move out of localview. */ + // XXX if (!okee("Move from localview")) return; + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + lay= base->lay & ~v3d->lay; + base->lay= lay; + base->object->lay= lay; + base->object->flag &= ~SELECT; + base->flag &= ~SELECT; + if(base->object->type==OB_LAMP) islamp= 1; + } + CTX_DATA_END; + } + else { + /* normal non localview operation */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + /* upper byte is used for local view */ + local= base->lay & 0xFF000000; + base->lay= lay + local; + base->object->lay= lay; + if(base->object->type==OB_LAMP) islamp= 1; + } + CTX_DATA_END; + } + + if(islamp) reshadeall_displist(scene); /* only frees */ + + /* warning, active object may be hidden now */ + + WM_event_add_notifier(C, NC_SCENE, scene); + DAG_scene_sort(scene); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_move_to_layer(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Move to Layer"; + ot->description = "Move the object to different layers."; + ot->idname= "OBJECT_OT_move_to_layer"; + + /* api callbacks */ + ot->invoke= move_to_layer_invoke; + ot->exec= move_to_layer_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean_array(ot->srna, "layer", 20, NULL, "Layer", ""); + /* XXX boolean layer subtype, behavior */ +} + +/************************** Link to Scene Operator *****************************/ + +void link_to_scene(unsigned short nr) +{ +#if 0 + Scene *sce= (Scene*) BLI_findlink(&G.main->scene, G.curscreen->scenenr-1); + Base *base, *nbase; + + if(sce==0) return; + if(sce->id.lib) return; + + for(base= FIRSTBASE; base; base= base->next) { + if(TESTBASE(v3d, base)) { + + nbase= MEM_mallocN( sizeof(Base), "newbase"); + *nbase= *base; + BLI_addhead( &(sce->base), nbase); + id_us_plus((ID *)base->object); + } + } +#endif +} + + +void make_links(bContext *C, wmOperator *op, Scene *scene, View3D *v3d, short event) +{ + Object *ob, *obt; + Base *base, *nbase, *sbase; + Scene *sce = NULL; + ID *id; + int a; + short nr=0; + char *strp; + + if(!(ob=OBACT)) return; + + if(event==1) { + IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), 0, &nr); + + if(nr == -2) { + MEM_freeN(strp); + +// XXX activate_databrowse((ID *)scene, ID_SCE, 0, B_INFOSCE, &(G.curscreen->scenenr), link_to_scene ); + + return; + } + else { + event= pupmenu_col(strp, 20); + MEM_freeN(strp); + + if(event<= 0) return; + + nr= 1; + sce= G.main->scene.first; + while(sce) { + if(nr==event) break; + nr++; + sce= sce->id.next; + } + if(sce==scene) { + BKE_report(op->reports, RPT_ERROR, "This is the current scene"); + return; + } + if(sce==0 || sce->id.lib) return; + + /* remember: is needed below */ + event= 1; + } + } + + /* All non group linking */ + for(base= FIRSTBASE; base; base= base->next) { + if(event==1 || base != BASACT) { + + obt= base->object; + + if(TESTBASE(v3d, base)) { + + if(event==1) { /* to scene */ + + /* test if already linked */ + sbase= sce->base.first; + while(sbase) { + if(sbase->object==base->object) break; + sbase= sbase->next; + } + if(sbase) { /* remove */ + continue; + } + + nbase= MEM_mallocN( sizeof(Base), "newbase"); + *nbase= *base; + BLI_addhead( &(sce->base), nbase); + id_us_plus((ID *)base->object); + } + } + if(TESTBASELIB(v3d, base)) { + if(event==2 || event==5) { /* obdata */ + if(ob->type==obt->type) { + + id= obt->data; + id->us--; + + id= ob->data; + id_us_plus(id); + obt->data= id; + + /* if amount of material indices changed: */ + test_object_materials(obt->data); + + obt->recalc |= OB_RECALC_DATA; + } + } + else if(event==4) { /* ob ipo */ +#if 0 // XXX old animation system + if(obt->ipo) obt->ipo->id.us--; + obt->ipo= ob->ipo; + if(obt->ipo) { + id_us_plus((ID *)obt->ipo); + do_ob_ipo(scene, obt); + } +#endif // XXX old animation system + } + else if(event==6) { + if(ob->dup_group) ob->dup_group->id.us--; + obt->dup_group= ob->dup_group; + if(obt->dup_group) { + id_us_plus((ID *)obt->dup_group); + obt->transflag |= OB_DUPLIGROUP; + } + } + else if(event==3) { /* materials */ + + /* new approach, using functions from kernel */ + for(a=0; atotcol; a++) { + Material *ma= give_current_material(ob, a+1); + assign_material(obt, ma, a+1); /* also works with ma==NULL */ + } + } + } + } + } + + ED_anim_dag_flush_update(C); + +} + +void make_links_menu(bContext *C, Scene *scene, View3D *v3d) +{ + Object *ob; + short event=0; + char str[140]; + + if(!(ob=OBACT)) return; + + strcpy(str, "Make Links %t|To Scene...%x1|%l|Object Ipo%x4"); + + if(ob->type==OB_MESH) + strcat(str, "|Mesh Data%x2|Materials%x3"); + else if(ob->type==OB_CURVE) + strcat(str, "|Curve Data%x2|Materials%x3"); + else if(ob->type==OB_FONT) + strcat(str, "|Text Data%x2|Materials%x3"); + else if(ob->type==OB_SURF) + strcat(str, "|Surface Data%x2|Materials%x3"); + else if(ob->type==OB_MBALL) + strcat(str, "|Materials%x3"); + else if(ob->type==OB_CAMERA) + strcat(str, "|Camera Data%x2"); + else if(ob->type==OB_LAMP) + strcat(str, "|Lamp Data%x2"); + else if(ob->type==OB_LATTICE) + strcat(str, "|Lattice Data%x2"); + else if(ob->type==OB_ARMATURE) + strcat(str, "|Armature Data%x2"); + + event= pupmenu(str); + + if(event<= 0) return; + + make_links(C, NULL, scene, v3d, event); +} + +/**************************** Make Single User ********************************/ + +static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin) +{ + ID_NEW(*obpoin); +} + +void single_object_users(Scene *scene, View3D *v3d, int flag) +{ + Base *base; + Object *ob, *obn; + + clear_sca_new_poins(); /* sensor/contr/act */ + + /* duplicate (must set newid) */ + for(base= FIRSTBASE; base; base= base->next) { + ob= base->object; + + if( (base->flag & flag)==flag ) { + if(ob->id.lib==NULL && ob->id.us>1) { + /* base gets copy of object */ + obn= copy_object(ob); + base->object= obn; + ob->id.us--; + } + } + } + + ID_NEW(scene->camera); + if(v3d) ID_NEW(v3d->camera); + + /* object pointers */ + for(base= FIRSTBASE; base; base= base->next) { + ob= base->object; + if(ob->id.lib==NULL) { + relink_constraints(&base->object->constraints); + if (base->object->pose){ + bPoseChannel *chan; + for (chan = base->object->pose->chanbase.first; chan; chan=chan->next){ + relink_constraints(&chan->constraints); + } + } + modifiers_foreachObjectLink(base->object, single_object_users__forwardModifierLinks, NULL); + + ID_NEW(ob->parent); + ID_NEW(ob->track); + } + } + + set_sca_new_poins(); +} + +void new_id_matar(Material **matar, int totcol) +{ + ID *id; + int a; + + for(a=0; alib==0) { + if(id->newid) { + matar[a]= (Material *)id->newid; + id_us_plus(id->newid); + id->us--; + } + else if(id->us>1) { + matar[a]= copy_material(matar[a]); + id->us--; + id->newid= (ID *)matar[a]; + } + } + } +} + +void single_obdata_users(Scene *scene, int flag) +{ + Object *ob; + Lamp *la; + Curve *cu; + //Camera *cam; + Base *base; + Mesh *me; + ID *id; + int a; + + for(base= FIRSTBASE; base; base= base->next) { + ob= base->object; + if(ob->id.lib==NULL && (base->flag & flag)==flag ) { + id= ob->data; + + if(id && id->us>1 && id->lib==0) { + ob->recalc= OB_RECALC_DATA; + + switch(ob->type) { + case OB_LAMP: + if(id && id->us>1 && id->lib==NULL) { + ob->data= la= copy_lamp(ob->data); + for(a=0; amtex[a]) { + ID_NEW(la->mtex[a]->object); + } + } + } + break; + case OB_CAMERA: + ob->data= copy_camera(ob->data); + break; + case OB_MESH: + me= ob->data= copy_mesh(ob->data); + //if(me && me->key) + // ipo_idnew(me->key->ipo); /* drivers */ + break; + case OB_MBALL: + ob->data= copy_mball(ob->data); + break; + case OB_CURVE: + case OB_SURF: + case OB_FONT: + ob->data= cu= copy_curve(ob->data); + ID_NEW(cu->bevobj); + ID_NEW(cu->taperobj); + break; + case OB_LATTICE: + ob->data= copy_lattice(ob->data); + break; + case OB_ARMATURE: + ob->recalc |= OB_RECALC_DATA; + ob->data= copy_armature(ob->data); + armature_rebuild_pose(ob, ob->data); + break; + default: + printf("ERROR single_obdata_users: can't copy %s\n", id->name); + return; + } + + id->us--; + id->newid= ob->data; + + } + +#if 0 // XXX old animation system + id= (ID *)ob->action; + if (id && id->us>1 && id->lib==NULL){ + if(id->newid){ + ob->action= (bAction *)id->newid; + id_us_plus(id->newid); + } + else { + ob->action= copy_action(ob->action); + id->us--; + id->newid=(ID *)ob->action; + } + } + id= (ID *)ob->ipo; + if(id && id->us>1 && id->lib==NULL) { + if(id->newid) { + ob->ipo= (Ipo *)id->newid; + id_us_plus(id->newid); + } + else { + ob->ipo= copy_ipo(ob->ipo); + id->us--; + id->newid= (ID *)ob->ipo; + } + ipo_idnew(ob->ipo); /* drivers */ + } + /* other ipos */ + switch(ob->type) { + case OB_LAMP: + la= ob->data; + if(la->ipo && la->ipo->id.us>1) { + la->ipo->id.us--; + la->ipo= copy_ipo(la->ipo); + ipo_idnew(la->ipo); /* drivers */ + } + break; + case OB_CAMERA: + cam= ob->data; + if(cam->ipo && cam->ipo->id.us>1) { + cam->ipo->id.us--; + cam->ipo= copy_ipo(cam->ipo); + ipo_idnew(cam->ipo); /* drivers */ + } + break; + } +#endif // XXX old animation system + } + } + + me= G.main->mesh.first; + while(me) { + ID_NEW(me->texcomesh); + me= me->id.next; + } +} + +void single_ipo_users(Scene *scene, int flag) +{ +#if 0 // XXX old animation system + Object *ob; + Base *base; + ID *id; + + for(base= FIRSTBASE; base; base= base->next) { + ob= base->object; + if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) { + ob->recalc= OB_RECALC_DATA; + + id= (ID *)ob->ipo; + if(id && id->us>1 && id->lib==NULL) { + ob->ipo= copy_ipo(ob->ipo); + id->us--; + ipo_idnew(ob->ipo); /* drivers */ + } + } + } +#endif // XXX old animation system +} + +void single_mat_users(Scene *scene, int flag) +{ + Object *ob; + Base *base; + Material *ma, *man; + Tex *tex; + int a, b; + + for(base= FIRSTBASE; base; base= base->next) { + ob= base->object; + if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) { + + for(a=1; a<=ob->totcol; a++) { + ma= give_current_material(ob, a); + if(ma) { + /* do not test for LIB_NEW: this functions guaranteed delivers single_users! */ + + if(ma->id.us>1) { + man= copy_material(ma); + + man->id.us= 0; + assign_material(ob, man, a); + +#if 0 // XXX old animation system + if(ma->ipo) { + man->ipo= copy_ipo(ma->ipo); + ma->ipo->id.us--; + ipo_idnew(ma->ipo); /* drivers */ + } +#endif // XXX old animation system + + for(b=0; bmtex[b] && ma->mtex[b]->tex) { + tex= ma->mtex[b]->tex; + if(tex->id.us>1) { + ma->mtex[b]->tex= copy_texture(tex); + tex->id.us--; + } + } + } + + } + } + } + } + } +} + +void do_single_tex_user(Tex **from) +{ + Tex *tex, *texn; + + tex= *from; + if(tex==0) return; + + if(tex->id.newid) { + *from= (Tex *)tex->id.newid; + id_us_plus(tex->id.newid); + tex->id.us--; + } + else if(tex->id.us>1) { + texn= copy_texture(tex); + tex->id.newid= (ID *)texn; + tex->id.us--; + *from= texn; + } +} + +void single_tex_users_expand() +{ + /* only when 'parent' blocks are LIB_NEW */ + Main *bmain= G.main; + Material *ma; + Lamp *la; + World *wo; + int b; + + for(ma= bmain->mat.first; ma; ma=ma->id.next) { + if(ma->id.flag & LIB_NEW) { + for(b=0; bmtex[b] && ma->mtex[b]->tex) { + do_single_tex_user( &(ma->mtex[b]->tex) ); + } + } + } + } + + for(la= bmain->lamp.first; la; la=la->id.next) { + if(la->id.flag & LIB_NEW) { + for(b=0; bmtex[b] && la->mtex[b]->tex) { + do_single_tex_user( &(la->mtex[b]->tex) ); + } + } + } + } + + for(wo= bmain->world.first; wo; wo=wo->id.next) { + if(wo->id.flag & LIB_NEW) { + for(b=0; bmtex[b] && wo->mtex[b]->tex) { + do_single_tex_user( &(wo->mtex[b]->tex) ); + } + } + } + } +} + +static void single_mat_users_expand(void) +{ + /* only when 'parent' blocks are LIB_NEW */ + Main *bmain= G.main; + Object *ob; + Mesh *me; + Curve *cu; + MetaBall *mb; + Material *ma; + int a; + + for(ob=bmain->object.first; ob; ob=ob->id.next) + if(ob->id.flag & LIB_NEW) + new_id_matar(ob->mat, ob->totcol); + + for(me=bmain->mesh.first; me; me=me->id.next) + if(me->id.flag & LIB_NEW) + new_id_matar(me->mat, me->totcol); + + for(cu=bmain->curve.first; cu; cu=cu->id.next) + if(cu->id.flag & LIB_NEW) + new_id_matar(cu->mat, cu->totcol); + + for(mb=bmain->mball.first; mb; mb=mb->id.next) + if(mb->id.flag & LIB_NEW) + new_id_matar(mb->mat, mb->totcol); + + /* material imats */ + for(ma=bmain->mat.first; ma; ma=ma->id.next) + if(ma->id.flag & LIB_NEW) + for(a=0; amtex[a]) + ID_NEW(ma->mtex[a]->object); +} + +void single_user(Scene *scene, View3D *v3d) +{ + int nr; + + if(scene->id.lib) return; + + clear_id_newpoins(); + + nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex|Ipos"); + if(nr>0) { + + if(nr==1) single_object_users(scene, v3d, 1); + + else if(nr==2) { + single_object_users(scene, v3d, 1); + single_obdata_users(scene, 1); + } + else if(nr==3) { + single_object_users(scene, v3d, 1); + single_obdata_users(scene, 1); + single_mat_users(scene, 1); /* also tex */ + + } + else if(nr==4) { + single_mat_users(scene, 1); + } + else if(nr==5) { + single_ipo_users(scene, 1); + } + + + clear_id_newpoins(); + + } +} + +/* used for copying scenes */ +void ED_object_single_users(Scene *scene, int full) +{ + single_object_users(scene, NULL, 0); + + if(full) { + single_obdata_users(scene, 0); + single_mat_users_expand(); + single_tex_users_expand(); + } + + clear_id_newpoins(); +} + +/******************************* Make Local ***********************************/ + +/* helper for below, ma was checked to be not NULL */ +static void make_local_makelocalmaterial(Material *ma) +{ + AnimData *adt; + int b; + + id_make_local(&ma->id, 0); + + for(b=0; bmtex[b] && ma->mtex[b]->tex) + id_make_local(&ma->mtex[b]->tex->id, 0); + + adt= BKE_animdata_from_id(&ma->id); + if(adt) BKE_animdata_make_local(adt); + + /* nodetree? XXX */ +} + +static int make_local_exec(bContext *C, wmOperator *op) +{ + AnimData *adt; + ParticleSystem *psys; + Material *ma, ***matarar; + Lamp *la; + ID *id; + int a, b, mode= RNA_boolean_get(op->ptr, "type"); + + if(mode==3) { + all_local(NULL, 0); /* NULL is all libs */ + WM_event_add_notifier(C, NC_WINDOW, NULL); + return OPERATOR_FINISHED; + } + + clear_id_newpoins(); + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->id.lib) + id_make_local(&ob->id, 0); + } + CTX_DATA_END; + + /* maybe object pointers */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->id.lib==NULL) { + ID_NEW(ob->parent); + ID_NEW(ob->track); + } + } + CTX_DATA_END; + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + id= ob->data; + + if(id && mode>1) { + id_make_local(id, 0); + adt= BKE_animdata_from_id(id); + if(adt) BKE_animdata_make_local(adt); + } + + for(psys=ob->particlesystem.first; psys; psys=psys->next) + id_make_local(&psys->part->id, 0); + + adt= BKE_animdata_from_id(&ob->id); + if(adt) BKE_animdata_make_local(adt); + } + CTX_DATA_END; + + if(mode>1) { + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->type==OB_LAMP) { + la= ob->data; + + for(b=0; bmtex[b] && la->mtex[b]->tex) + id_make_local(&la->mtex[b]->tex->id, 0); + } + else { + for(a=0; atotcol; a++) { + ma= ob->mat[a]; + if(ma) + make_local_makelocalmaterial(ma); + } + + matarar= (Material ***)give_matarar(ob); + if(matarar) { + for(a=0; atotcol; a++) { + ma= (*matarar)[a]; + if(ma) + make_local_makelocalmaterial(ma); + } + } + } + } + CTX_DATA_END; + } + + WM_event_add_notifier(C, NC_WINDOW, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_make_local(wmOperatorType *ot) +{ + static EnumPropertyItem type_items[]= { + {1, "SELECTED_OBJECTS", 0, "Selected Objects", ""}, + {2, "SELECTED_OBJECTS_DATA", 0, "Selected Objects and Data", ""}, + {3, "ALL", 0, "All", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name= "Make Local"; + ot->description = "Make library linked datablocks local to this file."; + ot->idname= "OBJECT_OT_make_local"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= make_local_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); +} + diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c new file mode 100644 index 00000000000..50ba4ab2934 --- /dev/null +++ b/source/blender/editors/object/object_select.c @@ -0,0 +1,974 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2002-2008 full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "DNA_group_types.h" +#include "DNA_material_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_property_types.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" + +#include "BLI_arithb.h" +#include "BLI_listbase.h" +#include "BLI_rand.h" +#include "BLI_string.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_particle.h" +#include "BKE_property.h" +#include "BKE_report.h" +#include "BKE_scene.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_object.h" +#include "ED_screen.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "object_intern.h" + +/************************ Exported **************************/ + +/* simple API for object selection, rather than just using the flag + * this takes into account the 'restrict selection in 3d view' flag. + * deselect works always, the restriction just prevents selection */ + +/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! */ + +void ED_base_object_select(Base *base, short mode) +{ + if (base) { + if (mode==BA_SELECT) { + if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) + if (mode==BA_SELECT) base->flag |= SELECT; + } + else if (mode==BA_DESELECT) { + base->flag &= ~SELECT; + } + base->object->flag= base->flag; + } +} + +/* also to set active NULL */ +void ED_base_object_activate(bContext *C, Base *base) +{ + Scene *scene= CTX_data_scene(C); + Base *tbase; + + /* sets scene->basact */ + BASACT= base; + + if(base) { + + /* XXX old signals, remember to handle notifiers now! */ + // select_actionchannel_by_name(base->object->action, "Object", 1); + + /* disable temporal locks */ + for(tbase=FIRSTBASE; tbase; tbase= tbase->next) { + if(base!=tbase && (tbase->object->shapeflag & OB_SHAPE_TEMPLOCK)) { + tbase->object->shapeflag &= ~OB_SHAPE_TEMPLOCK; + DAG_id_flush_update(&tbase->object->id, OB_RECALC_DATA); + } + } + WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); + } + else + WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, NULL); +} + +/********************** Selection Operators **********************/ + +static EnumPropertyItem prop_select_types[] = { + {0, "EXCLUSIVE", 0, "Exclusive", ""}, + {1, "EXTEND", 0, "Extend", ""}, + {0, NULL, 0, NULL, NULL} +}; + +/************************ Select by Type *************************/ + +static int object_select_by_type_exec(bContext *C, wmOperator *op) +{ + short obtype, seltype; + + obtype = RNA_enum_get(op->ptr, "type"); + seltype = RNA_enum_get(op->ptr, "seltype"); + + if (seltype == 0) { + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + ED_base_object_select(base, BA_DESELECT); + } + CTX_DATA_END; + } + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if(base->object->type==obtype) { + ED_base_object_select(base, BA_SELECT); + } + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_by_type(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select By Type"; + ot->description = "Select all visible objects that are of a type."; + ot->idname= "OBJECT_OT_select_by_type"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_select_by_type_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "seltype", prop_select_types, 0, "Selection", "Extend selection or clear selection then select"); + RNA_def_enum(ot->srna, "type", object_type_items, 1, "Type", ""); + +} + +/*********************** Selection by Links *********************/ + +static EnumPropertyItem prop_select_linked_types[] = { + {1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... + {2, "OBDATA", 0, "Ob Data", ""}, + {3, "MATERIAL", 0, "Material", ""}, + {4, "TEXTURE", 0, "Texture", ""}, + {5, "DUPGROUP", 0, "Dupligroup", ""}, + {6, "PARTICLE", 0, "Particle System", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int object_select_linked_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob; + void *obdata = NULL; + Material *mat = NULL, *mat1; + Tex *tex=0; + int a, b; + int nr = RNA_enum_get(op->ptr, "type"); + short changed = 0, seltype; + /* events (nr): + * Object Ipo: 1 + * ObData: 2 + * Current Material: 3 + * Current Texture: 4 + * DupliGroup: 5 + * PSys: 6 + */ + + seltype = RNA_enum_get(op->ptr, "seltype"); + + if (seltype == 0) { + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + ED_base_object_select(base, BA_DESELECT); + } + CTX_DATA_END; + } + + ob= OBACT; + if(ob==0){ + BKE_report(op->reports, RPT_ERROR, "No Active Object"); + return OPERATOR_CANCELLED; + } + + if(nr==1) { + // XXX old animation system + //ipo= ob->ipo; + //if(ipo==0) return OPERATOR_CANCELLED; + return OPERATOR_CANCELLED; + } + else if(nr==2) { + if(ob->data==0) return OPERATOR_CANCELLED; + obdata= ob->data; + } + else if(nr==3 || nr==4) { + mat= give_current_material(ob, ob->actcol); + if(mat==0) return OPERATOR_CANCELLED; + if(nr==4) { + if(mat->mtex[ (int)mat->texact ]) tex= mat->mtex[ (int)mat->texact ]->tex; + if(tex==0) return OPERATOR_CANCELLED; + } + } + else if(nr==5) { + if(ob->dup_group==NULL) return OPERATOR_CANCELLED; + } + else if(nr==6) { + if(ob->particlesystem.first==NULL) return OPERATOR_CANCELLED; + } + else return OPERATOR_CANCELLED; + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if(nr==1) { + // XXX old animation system + //if(base->object->ipo==ipo) base->flag |= SELECT; + //changed = 1; + } + else if(nr==2) { + if(base->object->data==obdata) base->flag |= SELECT; + changed = 1; + } + else if(nr==3 || nr==4) { + ob= base->object; + + for(a=1; a<=ob->totcol; a++) { + mat1= give_current_material(ob, a); + if(nr==3) { + if(mat1==mat) base->flag |= SELECT; + changed = 1; + } + else if(mat1 && nr==4) { + for(b=0; bmtex[b]) { + if(tex==mat1->mtex[b]->tex) { + base->flag |= SELECT; + changed = 1; + break; + } + } + } + } + } + } + else if(nr==5) { + if(base->object->dup_group==ob->dup_group) { + base->flag |= SELECT; + changed = 1; + } + } + else if(nr==6) { + /* loop through other, then actives particles*/ + ParticleSystem *psys; + ParticleSystem *psys_act; + + for(psys=base->object->particlesystem.first; psys; psys=psys->next) { + for(psys_act=ob->particlesystem.first; psys_act; psys_act=psys_act->next) { + if (psys->part == psys_act->part) { + base->flag |= SELECT; + changed = 1; + break; + } + } + + if (base->flag & SELECT) { + break; + } + } + } + base->object->flag= base->flag; + } + CTX_DATA_END; + + if (changed) { + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select Linked"; + ot->description = "Select all visible objects that are linked."; + ot->idname= "OBJECT_OT_select_linked"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_select_linked_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", ""); + RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); + +} + +/*********************** Selected Grouped ********************/ + +static EnumPropertyItem prop_select_grouped_types[] = { + {1, "CHILDREN_RECURSIVE", 0, "Children", ""}, + {2, "CHILDREN", 0, "Immediate Children", ""}, + {3, "PARENT", 0, "Parent", ""}, + {4, "SIBLINGS", 0, "Siblings", "Shared Parent"}, + {5, "TYPE", 0, "Type", "Shared object type"}, + {6, "LAYER", 0, "Layer", "Shared layers"}, + {7, "GROUP", 0, "Group", "Shared group"}, + {8, "HOOK", 0, "Hook", ""}, + {9, "PASS", 0, "Pass", "Render pass Index"}, + {10, "COLOR", 0, "Color", "Object Color"}, + {11, "PROPERTIES", 0, "Properties", "Game Properties"}, + {0, NULL, 0, NULL, NULL} +}; + +static short select_grouped_children(bContext *C, Object *ob, int recursive) +{ + short changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if (ob == base->object->parent) { + if (!(base->flag & SELECT)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + + if (recursive) + changed |= select_grouped_children(C, base->object, 1); + } + } + CTX_DATA_END; + return changed; +} + +static short select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */ +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + + short changed = 0; + Base *baspar, *basact= CTX_data_active_base(C); + + if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */ + + baspar= object_in_scene(basact->object->parent, scene); + + /* can be NULL if parent in other scene */ + if(baspar && BASE_SELECTABLE(v3d, baspar)) { + ED_base_object_select(basact, BA_DESELECT); + ED_base_object_select(baspar, BA_SELECT); + ED_base_object_activate(C, baspar); + changed = 1; + } + return changed; +} + + +#define GROUP_MENU_MAX 24 +static short select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */ +{ + short changed = 0; + Group *group, *ob_groups[GROUP_MENU_MAX]; + //char str[10 + (24*GROUP_MENU_MAX)]; + //char *p = str; + int group_count=0; //, menu, i; + + for ( group=G.main->group.first; + group && group_count < GROUP_MENU_MAX; + group=group->id.next + ) { + if (object_in_group (ob, group)) { + ob_groups[group_count] = group; + group_count++; + } + } + + if (!group_count) + return 0; + + else if (group_count == 1) { + group = ob_groups[0]; + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if (!(base->flag & SELECT) && object_in_group(base->object, group)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; + } +#if 0 // XXX hows this work in 2.5? + /* build the menu. */ + p += sprintf(str, "Groups%%t"); + for (i=0; iid.name+2, i); + } + + menu = pupmenu (str); + if (menu == -1) + return 0; + + group = ob_groups[menu]; + for (base= FIRSTBASE; base; base= base->next) { + if (!(base->flag & SELECT) && object_in_group(base->object, group)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } +#endif + return changed; +} + +static short select_grouped_object_hooks(bContext *C, Object *ob) +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d= CTX_wm_view3d(C); + + short changed = 0; + Base *base; + ModifierData *md; + HookModifierData *hmd; + + for (md = ob->modifiers.first; md; md=md->next) { + if (md->type==eModifierType_Hook) { + hmd= (HookModifierData*) md; + if (hmd->object && !(hmd->object->flag & SELECT)) { + base= object_in_scene(hmd->object, scene); + if (base && (BASE_SELECTABLE(v3d, base))) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + } + } + return changed; +} + +/* Select objects woth the same parent as the active (siblings), + * parent can be NULL also */ +static short select_grouped_siblings(bContext *C, Object *ob) +{ + short changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if ((base->object->parent==ob->parent) && !(base->flag & SELECT)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; +} + +static short select_grouped_type(bContext *C, Object *ob) +{ + short changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if ((base->object->type == ob->type) && !(base->flag & SELECT)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; +} + +static short select_grouped_layer(bContext *C, Object *ob) +{ + char changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if ((base->lay & ob->lay) && !(base->flag & SELECT)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; +} + +static short select_grouped_index_object(bContext *C, Object *ob) +{ + char changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if ((base->object->index == ob->index) && !(base->flag & SELECT)) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; +} + +static short select_grouped_color(bContext *C, Object *ob) +{ + char changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if (!(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005f))) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; +} + +static short objects_share_gameprop(Object *a, Object *b) +{ + bProperty *prop; + /*make a copy of all its properties*/ + + for( prop= a->prop.first; prop; prop = prop->next ) { + if ( get_ob_property(b, prop->name) ) + return 1; + } + return 0; +} + +static short select_grouped_gameprops(bContext *C, Object *ob) +{ + char changed = 0; + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) { + ED_base_object_select(base, BA_SELECT); + changed = 1; + } + } + CTX_DATA_END; + return changed; +} + +static int object_select_grouped_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob; + int nr = RNA_enum_get(op->ptr, "type"); + short changed = 0, seltype; + + seltype = RNA_enum_get(op->ptr, "seltype"); + + if (seltype == 0) { + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + ED_base_object_select(base, BA_DESELECT); + } + CTX_DATA_END; + } + + ob= OBACT; + if(ob==0){ + BKE_report(op->reports, RPT_ERROR, "No Active Object"); + return OPERATOR_CANCELLED; + } + + if(nr==1) changed = select_grouped_children(C, ob, 1); + else if(nr==2) changed = select_grouped_children(C, ob, 0); + else if(nr==3) changed = select_grouped_parent(C); + else if(nr==4) changed = select_grouped_siblings(C, ob); + else if(nr==5) changed = select_grouped_type(C, ob); + else if(nr==6) changed = select_grouped_layer(C, ob); + else if(nr==7) changed = select_grouped_group(C, ob); + else if(nr==8) changed = select_grouped_object_hooks(C, ob); + else if(nr==9) changed = select_grouped_index_object(C, ob); + else if(nr==10) changed = select_grouped_color(C, ob); + else if(nr==11) changed = select_grouped_gameprops(C, ob); + + if (changed) { + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_select_grouped(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select Grouped"; + ot->description = "Select all visible objects grouped by various properties."; + ot->idname= "OBJECT_OT_select_grouped"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_select_grouped_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", ""); + RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); +} + +/************************* Select by Layer **********************/ + +static int object_select_by_layer_exec(bContext *C, wmOperator *op) +{ + unsigned int layernum; + short seltype; + + seltype = RNA_enum_get(op->ptr, "seltype"); + layernum = RNA_int_get(op->ptr, "layer"); + + if (seltype == 0) { + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + ED_base_object_select(base, BA_DESELECT); + } + CTX_DATA_END; + } + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if(base->lay == (1<< (layernum -1))) + ED_base_object_select(base, BA_SELECT); + } + CTX_DATA_END; + + /* undo? */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_by_layer(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "select by layer"; + ot->description = "Select all visible objects on a layer."; + ot->idname= "OBJECT_OT_select_by_layer"; + + /* api callbacks */ + /*ot->invoke = XXX - need a int grid popup*/ + ot->exec= object_select_by_layer_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_int(ot->srna, "layer", 1, 1, 20, "Layer", "", 1, 20); + RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); +} + +/************************** Select Inverse *************************/ + +static int object_select_inverse_exec(bContext *C, wmOperator *op) +{ + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if (base->flag & SELECT) + ED_base_object_select(base, BA_DESELECT); + else + ED_base_object_select(base, BA_SELECT); + } + CTX_DATA_END; + + /* undo? */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_inverse(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Select Inverse"; + ot->description = "Invert selection of all visible objects."; + ot->idname= "OBJECT_OT_select_inverse"; + + /* api callbacks */ + ot->exec= object_select_inverse_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + +} + +/**************************** (De)select All ****************************/ + +static int object_select_de_select_all_exec(bContext *C, wmOperator *op) +{ + + int a=0, ok=0; + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if (base->flag & SELECT) { + ok= a= 1; + break; + } + else ok=1; + } + CTX_DATA_END; + + if (!ok) return OPERATOR_PASS_THROUGH; + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if (a) ED_base_object_select(base, BA_DESELECT); + else ED_base_object_select(base, BA_SELECT); + } + CTX_DATA_END; + + /* undo? */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_all_toggle(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "deselect all"; + ot->description = "(de)select all visible objects in scene."; + ot->idname= "OBJECT_OT_select_all_toggle"; + + /* api callbacks */ + ot->exec= object_select_de_select_all_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + +} + +/**************************** Select Mirror ****************************/ + +/* finds the best possible flipped name. For renaming; check for unique names afterwards */ +/* if strip_number: removes number extensions */ +void object_flip_name (char *name) +{ + int len; + char prefix[128]={""}; /* The part before the facing */ + char suffix[128]={""}; /* The part after the facing */ + char replace[128]={""}; /* The replacement string */ + char number[128]={""}; /* The number extension string */ + char *index=NULL; + + len= strlen(name); + if(len<3) return; // we don't do names like .R or .L + + /* We first check the case with a .### extension, let's find the last period */ + if(isdigit(name[len-1])) { + index= strrchr(name, '.'); // last occurrance + if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! + strcpy(number, index); + *index= 0; + len= strlen(name); + } + } + + strcpy (prefix, name); + +#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') + + /* first case; separator . - _ with extensions r R l L */ + if( IS_SEPARATOR(name[len-2]) ) { + switch(name[len-1]) { + case 'l': + prefix[len-1]= 0; + strcpy(replace, "r"); + break; + case 'r': + prefix[len-1]= 0; + strcpy(replace, "l"); + break; + case 'L': + prefix[len-1]= 0; + strcpy(replace, "R"); + break; + case 'R': + prefix[len-1]= 0; + strcpy(replace, "L"); + break; + } + } + /* case; beginning with r R l L , with separator after it */ + else if( IS_SEPARATOR(name[1]) ) { + switch(name[0]) { + case 'l': + strcpy(replace, "r"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'r': + strcpy(replace, "l"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'L': + strcpy(replace, "R"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'R': + strcpy(replace, "L"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + } + } + else if(len > 5) { + /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ + index = BLI_strcasestr(prefix, "right"); + if (index==prefix || index==prefix+len-5) { + if(index[0]=='r') + strcpy (replace, "left"); + else { + if(index[1]=='I') + strcpy (replace, "LEFT"); + else + strcpy (replace, "Left"); + } + *index= 0; + strcpy (suffix, index+5); + } + else { + index = BLI_strcasestr(prefix, "left"); + if (index==prefix || index==prefix+len-4) { + if(index[0]=='l') + strcpy (replace, "right"); + else { + if(index[1]=='E') + strcpy (replace, "RIGHT"); + else + strcpy (replace, "Right"); + } + *index= 0; + strcpy (suffix, index+4); + } + } + } + +#undef IS_SEPARATOR + + sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); +} + +static int object_select_mirror_exec(bContext *C, wmOperator *op) +{ + char tmpname[32]; + short seltype; + + seltype = RNA_enum_get(op->ptr, "seltype"); + + CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) { + + strcpy(tmpname, primbase->object->id.name+2); + object_flip_name(tmpname); + + CTX_DATA_BEGIN(C, Base*, secbase, visible_bases) { + if(!strcmp(secbase->object->id.name+2, tmpname)) { + ED_base_object_select(secbase, BA_SELECT); + } + } + CTX_DATA_END; + + if (seltype == 0) ED_base_object_select(primbase, BA_DESELECT); + + } + CTX_DATA_END; + + /* undo? */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_mirror(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Select Mirror"; + ot->description = "Select the Mirror objects of the selected object eg. L.sword -> R.sword"; + ot->idname= "OBJECT_OT_select_mirror"; + + /* api callbacks */ + ot->exec= object_select_mirror_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); +} + +/**************************** Select Random ****************************/ + +static int object_select_random_exec(bContext *C, wmOperator *op) +{ + float percent; + short seltype; + + seltype = RNA_enum_get(op->ptr, "seltype"); + + if (seltype == 0) { + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + ED_base_object_select(base, BA_DESELECT); + } + CTX_DATA_END; + } + percent = RNA_float_get(op->ptr, "percent"); + + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + if (BLI_frand() < percent) { + ED_base_object_select(base, BA_SELECT); + } + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_random(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Random select"; + ot->description = "Set select on random visible objects."; + ot->idname= "OBJECT_OT_select_random"; + + /* api callbacks */ + /*ot->invoke= object_select_random_invoke XXX - need a number popup ;*/ + ot->exec = object_select_random_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "percentage of objects to randomly select", 0.0001f, 1.0f); + RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); +} + + diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c new file mode 100644 index 00000000000..2ec3edd846a --- /dev/null +++ b/source/blender/editors/object/object_shapekey.c @@ -0,0 +1,539 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, shapekey support + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#ifndef WIN32 +#include +#else +#include +#endif + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view2d_types.h" + +#include "BKE_action.h" +#include "BKE_anim.h" +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" + +#include "BLO_sys_types.h" // for intptr_t support + +#include "ED_object.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "object_intern.h" + +#if 0 // XXX old animation system +static void default_key_ipo(Scene *scene, Key *key) +{ + IpoCurve *icu; + BezTriple *bezt; + + key->ipo= add_ipo(scene, "KeyIpo", ID_KE); + + icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); + + icu->blocktype= ID_KE; + icu->adrcode= KEY_SPEED; + icu->flag= IPO_VISIBLE|IPO_SELECT|IPO_AUTO_HORIZ; + set_icu_vars(icu); + + BLI_addtail( &(key->ipo->curve), icu); + + icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo"); + icu->totvert= 2; + + bezt->hide= IPO_BEZ; + bezt->f1=bezt->f2= bezt->f3= SELECT; + bezt->h1= bezt->h2= HD_AUTO; + bezt++; + bezt->vec[1][0]= 100.0; + bezt->vec[1][1]= 1.0; + bezt->hide= IPO_BEZ; + bezt->f1=bezt->f2= bezt->f3= SELECT; + bezt->h1= bezt->h2= HD_AUTO; + + calchandles_ipocurve(icu); +} +#endif // XXX old animation system + + +/************************* Mesh ************************/ + +void mesh_to_key(Mesh *me, KeyBlock *kb) +{ + MVert *mvert; + float *fp; + int a; + + if(me->totvert==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); + kb->totelem= me->totvert; + + mvert= me->mvert; + fp= kb->data; + for(a=0; atotelem; a++, fp+=3, mvert++) { + VECCOPY(fp, mvert->co); + + } +} + +void key_to_mesh(KeyBlock *kb, Mesh *me) +{ + MVert *mvert; + float *fp; + int a, tot; + + mvert= me->mvert; + fp= kb->data; + + tot= MIN2(kb->totelem, me->totvert); + + for(a=0; aco, fp); + } +} + +static KeyBlock *add_keyblock(Scene *scene, Key *key) +{ + KeyBlock *kb; + float curpos= -0.1; + int tot; + + kb= key->block.last; + if(kb) curpos= kb->pos; + + kb= MEM_callocN(sizeof(KeyBlock), "Keyblock"); + BLI_addtail(&key->block, kb); + kb->type= KEY_CARDINAL; + + tot= BLI_countlist(&key->block); + if(tot==1) strcpy(kb->name, "Basis"); + else sprintf(kb->name, "Key %d", tot-1); + + // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey) + kb->adrcode= tot-1; + + key->totkey++; + if(key->totkey==1) key->refkey= kb; + + kb->slidermin= 0.0f; + kb->slidermax= 1.0f; + + // XXX kb->pos is the confusing old horizontal-line RVK crap in old IPO Editor... + if(key->type == KEY_RELATIVE) + kb->pos= curpos+0.1; + else { +#if 0 // XXX old animation system + curpos= bsystem_time(scene, 0, (float)CFRA, 0.0); + if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) { + curpos /= 100.0; + } + kb->pos= curpos; + + sort_keys(key); +#endif // XXX old animation system + } + return kb; +} + +void insert_meshkey(Scene *scene, Mesh *me, short rel) +{ + Key *key; + KeyBlock *kb; + + if(me->key==NULL) { + me->key= add_key( (ID *)me); + + if(rel) + me->key->type = KEY_RELATIVE; +// else +// default_key_ipo(scene, me->key); // XXX old animation system + } + key= me->key; + + kb= add_keyblock(scene, key); + + mesh_to_key(me, kb); +} + +/************************* Lattice ************************/ + +void latt_to_key(Lattice *lt, KeyBlock *kb) +{ + BPoint *bp; + float *fp; + int a, tot; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + if(tot==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data"); + kb->totelem= tot; + + bp= lt->def; + fp= kb->data; + for(a=0; atotelem; a++, fp+=3, bp++) { + VECCOPY(fp, bp->vec); + } +} + +void key_to_latt(KeyBlock *kb, Lattice *lt) +{ + BPoint *bp; + float *fp; + int a, tot; + + bp= lt->def; + fp= kb->data; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + tot= MIN2(kb->totelem, tot); + + for(a=0; avec, fp); + } + +} + +/* exported to python... hrms, should not, use object levels! (ton) */ +void insert_lattkey(Scene *scene, Lattice *lt, short rel) +{ + Key *key; + KeyBlock *kb; + + if(lt->key==NULL) { + lt->key= add_key( (ID *)lt); +// default_key_ipo(scene, lt->key); // XXX old animation system + } + key= lt->key; + + kb= add_keyblock(scene, key); + + latt_to_key(lt, kb); +} + +/************************* Curve ************************/ + +void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, tot; + + /* count */ + tot= count_curveverts(nurb); + if(tot==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data"); + kb->totelem= tot; + + nu= nurb->first; + fp= kb->data; + while(nu) { + + if(nu->bezt) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + VECCOPY(fp, bezt->vec[0]); + fp+= 3; + VECCOPY(fp, bezt->vec[1]); + fp+= 3; + VECCOPY(fp, bezt->vec[2]); + fp+= 3; + fp[0]= bezt->alfa; + fp+= 3; /* alphas */ + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + VECCOPY(fp, bp->vec); + fp[3]= bp->alfa; + + fp+= 4; + bp++; + } + } + nu= nu->next; + } +} + +void key_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, tot; + + nu= nurb->first; + fp= kb->data; + + tot= count_curveverts(nurb); + + tot= MIN2(kb->totelem, tot); + + while(nu && tot>0) { + + if(nu->bezt) { + bezt= nu->bezt; + a= nu->pntsu; + while(a-- && tot>0) { + VECCOPY(bezt->vec[0], fp); + fp+= 3; + VECCOPY(bezt->vec[1], fp); + fp+= 3; + VECCOPY(bezt->vec[2], fp); + fp+= 3; + bezt->alfa= fp[0]; + fp+= 3; /* alphas */ + + tot-= 3; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a-- && tot>0) { + VECCOPY(bp->vec, fp); + bp->alfa= fp[3]; + + fp+= 4; + tot--; + bp++; + } + } + nu= nu->next; + } +} + + +void insert_curvekey(Scene *scene, Curve *cu, short rel) +{ + Key *key; + KeyBlock *kb; + + if(cu->key==NULL) { + cu->key= add_key( (ID *)cu); + + if(rel) + cu->key->type = KEY_RELATIVE; +// else +// default_key_ipo(scene, cu->key); // XXX old animation system + } + key= cu->key; + + kb= add_keyblock(scene, key); + + if(cu->editnurb->first) curve_to_key(cu, kb, cu->editnurb); + else curve_to_key(cu, kb, &cu->nurb); +} + +/*********************** add shape key ***********************/ + +void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob) +{ + Key *key; + + if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1); + else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1); + else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1); + + key= ob_get_key(ob); + ob->shapenr= BLI_countlist(&key->block); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); +} + +/*********************** remove shape key ***********************/ + +int ED_object_shape_key_remove(bContext *C, Scene *scene, Object *ob) +{ + Main *bmain= CTX_data_main(C); + KeyBlock *kb, *rkb; + Key *key; + //IpoCurve *icu; + + key= ob_get_key(ob); + if(key==NULL) + return 0; + + kb= BLI_findlink(&key->block, ob->shapenr-1); + + if(kb) { + for(rkb= key->block.first; rkb; rkb= rkb->next) + if(rkb->relative == ob->shapenr-1) + rkb->relative= 0; + + BLI_remlink(&key->block, kb); + key->totkey--; + if(key->refkey== kb) + key->refkey= key->block.first; + + if(kb->data) MEM_freeN(kb->data); + MEM_freeN(kb); + + for(kb= key->block.first; kb; kb= kb->next) + if(kb->adrcode>=ob->shapenr) + kb->adrcode--; + +#if 0 // XXX old animation system + if(key->ipo) { + + for(icu= key->ipo->curve.first; icu; icu= icu->next) { + if(icu->adrcode==ob->shapenr-1) { + BLI_remlink(&key->ipo->curve, icu); + free_ipo_curve(icu); + break; + } + } + for(icu= key->ipo->curve.first; icu; icu= icu->next) + if(icu->adrcode>=ob->shapenr) + icu->adrcode--; + } +#endif // XXX old animation system + + if(ob->shapenr>1) ob->shapenr--; + } + + if(key->totkey==0) { + if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL; + else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL; + else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL; + + free_libblock_us(&(bmain->key), key); + } + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return 1; +} + +/********************** shape key operators *********************/ + +static int shape_key_poll(bContext *C) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ID *data= (ob)? ob->data: NULL; + return (ob && !ob->id.lib && data && !data->lib); +} + +static int shape_key_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + + ED_object_shape_key_add(C, scene, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_shape_key_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Shape Key"; + ot->idname= "OBJECT_OT_shape_key_add"; + + /* api callbacks */ + ot->poll= shape_key_poll; + ot->exec= shape_key_add_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int shape_key_remove_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + + if(!ED_object_shape_key_remove(C, scene, ob)) + return OPERATOR_CANCELLED; + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_shape_key_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Shape Key"; + ot->idname= "OBJECT_OT_shape_key_remove"; + + /* api callbacks */ + ot->poll= shape_key_poll; + ot->exec= shape_key_remove_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c new file mode 100644 index 00000000000..2b207f2f27c --- /dev/null +++ b/source/blender/editors/object/object_transform.c @@ -0,0 +1,926 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2002-2008 full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_listbase.h" + +#include "BKE_context.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#include "RNA_define.h" +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_anim_api.h" +#include "ED_armature.h" +#include "ED_curve.h" +#include "ED_mesh.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "object_intern.h" + +/*************************** Clear Transformation ****************************/ + +static int object_location_clear_exec(bContext *C, wmOperator *op) +{ + int armature_clear= 0; + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { + if((ob->protectflag & OB_LOCK_LOCX)==0) + ob->loc[0]= ob->dloc[0]= 0.0f; + if((ob->protectflag & OB_LOCK_LOCY)==0) + ob->loc[1]= ob->dloc[1]= 0.0f; + if((ob->protectflag & OB_LOCK_LOCZ)==0) + ob->loc[2]= ob->dloc[2]= 0.0f; + } + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + if(armature_clear==0) /* in this case flush was done */ + ED_anim_dag_flush_update(C); + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_location_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Location"; + ot->description = "Clear the object's location."; + ot->idname= "OBJECT_OT_location_clear"; + + /* api callbacks */ + ot->exec= object_location_clear_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_rotation_clear_exec(bContext *C, wmOperator *op) +{ + int armature_clear= 0; + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { + /* eulers can only get cleared if they are not protected */ + if((ob->protectflag & OB_LOCK_ROTX)==0) + ob->rot[0]= ob->drot[0]= 0.0f; + if((ob->protectflag & OB_LOCK_ROTY)==0) + ob->rot[1]= ob->drot[1]= 0.0f; + if((ob->protectflag & OB_LOCK_ROTZ)==0) + ob->rot[2]= ob->drot[2]= 0.0f; + } + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + if(armature_clear==0) /* in this case flush was done */ + ED_anim_dag_flush_update(C); + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_rotation_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Rotation"; + ot->description = "Clear the object's rotation."; + ot->idname= "OBJECT_OT_rotation_clear"; + + /* api callbacks */ + ot->exec= object_rotation_clear_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_scale_clear_exec(bContext *C, wmOperator *op) +{ + int armature_clear= 0; + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { + if((ob->protectflag & OB_LOCK_SCALEX)==0) { + ob->dsize[0]= 0.0f; + ob->size[0]= 1.0f; + } + if((ob->protectflag & OB_LOCK_SCALEY)==0) { + ob->dsize[1]= 0.0f; + ob->size[1]= 1.0f; + } + if((ob->protectflag & OB_LOCK_SCALEZ)==0) { + ob->dsize[2]= 0.0f; + ob->size[2]= 1.0f; + } + } + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + if(armature_clear==0) /* in this case flush was done */ + ED_anim_dag_flush_update(C); + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_scale_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Scale"; + ot->description = "Clear the object's scale."; + ot->idname= "OBJECT_OT_scale_clear"; + + /* api callbacks */ + ot->exec= object_scale_clear_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int object_origin_clear_exec(bContext *C, wmOperator *op) +{ + float *v1, *v3, mat[3][3]; + int armature_clear= 0; + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + if(ob->parent) { + v1= ob->loc; + v3= ob->parentinv[3]; + + Mat3CpyMat4(mat, ob->parentinv); + VECCOPY(v3, v1); + v3[0]= -v3[0]; + v3[1]= -v3[1]; + v3[2]= -v3[2]; + Mat3MulVecfl(mat, v3); + } + ob->recalc |= OB_RECALC_OB; + } + CTX_DATA_END; + + if(armature_clear==0) /* in this case flush was done */ + ED_anim_dag_flush_update(C); + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_origin_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Origin"; + ot->description = "Clear the object's origin."; + ot->idname= "OBJECT_OT_origin_clear"; + + /* api callbacks */ + ot->exec= object_origin_clear_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/*************************** Apply Transformation ****************************/ + +/* use this when the loc/size/rot of the parent has changed but the children + * should stay in the same place, e.g. for apply-size-rot or object center */ +static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob ) +{ + Object workob; + Object *ob_child; + + /* a change was made, adjust the children to compensate */ + for(ob_child=bmain->object.first; ob_child; ob_child=ob_child->id.next) { + if(ob_child->parent == ob) { + ED_object_apply_obmat(ob_child); + what_does_parent(scene, ob_child, &workob); + Mat4Invert(ob_child->parentinv, workob.obmat); + } + } +} + +static int apply_objects_internal(bContext *C, ReportList *reports, int apply_loc, int apply_scale, int apply_rot) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Object *ob; + bArmature *arm; + Mesh *me; + Curve *cu; + Nurb *nu; + BPoint *bp; + BezTriple *bezt; + MVert *mvert; + float rsmat[3][3], tmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; + int a, change = 0; + + /* first check if we can execute */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob= base->object; + + if(ob->type==OB_MESH) { + me= ob->data; + + if(me->id.us>1) { + BKE_report(reports, RPT_ERROR, "Can't apply to a multi user mesh, doing nothing."); + return OPERATOR_CANCELLED; + } + } + else if(ob->type==OB_ARMATURE) { + arm= ob->data; + + if(arm->id.us>1) { + BKE_report(reports, RPT_ERROR, "Can't apply to a multi user armature, doing nothing."); + return OPERATOR_CANCELLED; + } + } + else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + cu= ob->data; + + if(cu->id.us>1) { + BKE_report(reports, RPT_ERROR, "Can't apply to a multi user curve, doing nothing."); + return OPERATOR_CANCELLED; + } + if(cu->key) { + BKE_report(reports, RPT_ERROR, "Can't apply to a curve with vertex keys, doing nothing."); + return OPERATOR_CANCELLED; + } + } + } + CTX_DATA_END; + + /* now execute */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob= base->object; + + /* calculate rotation/scale matrix */ + if(apply_scale && apply_rot) + object_to_mat3(ob, rsmat); + else if(apply_scale) + object_scale_to_mat3(ob, rsmat); + else if(apply_rot) + object_rot_to_mat3(ob, rsmat); + else + Mat3One(rsmat); + + Mat4CpyMat3(mat, rsmat); + + /* calculate translation */ + if(apply_loc) { + VecCopyf(mat[3], ob->loc); + + if(!(apply_scale && apply_rot)) { + /* correct for scale and rotation that is still applied */ + object_to_mat3(ob, obmat); + Mat3Inv(iobmat, obmat); + Mat3MulMat3(tmat, rsmat, iobmat); + Mat3MulVecfl(tmat, mat[3]); + } + } + + /* apply to object data */ + if(ob->type==OB_MESH) { + me= ob->data; + + /* adjust data */ + mvert= me->mvert; + for(a=0; atotvert; a++, mvert++) + Mat4MulVecfl(mat, mvert->co); + + if(me->key) { + KeyBlock *kb; + + for(kb=me->key->block.first; kb; kb=kb->next) { + float *fp= kb->data; + + for(a=0; atotelem; a++, fp+=3) + Mat4MulVecfl(mat, fp); + } + } + + /* update normals */ + mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); + } + else if (ob->type==OB_ARMATURE) { + ED_armature_apply_transform(ob, mat); + } + else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + cu= ob->data; + + scale = Mat3ToScalef(rsmat); + + for(nu=cu->nurb.first; nu; nu=nu->next) { + if(nu->type == CU_BEZIER) { + a= nu->pntsu; + for(bezt= nu->bezt; a--; bezt++) { + Mat4MulVecfl(mat, bezt->vec[0]); + Mat4MulVecfl(mat, bezt->vec[1]); + Mat4MulVecfl(mat, bezt->vec[2]); + bezt->radius *= scale; + bezt++; + } + } + else { + a= nu->pntsu*nu->pntsv; + for(bp= nu->bp; a--; bp++) + Mat4MulVecfl(mat, bp->vec); + } + } + } + else + continue; + + if(apply_loc) + ob->loc[0]= ob->loc[1]= ob->loc[2]= 0.0f; + if(apply_scale) + ob->size[0]= ob->size[1]= ob->size[2]= 1.0f; + if(apply_rot) + ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f; + + where_is_object(scene, ob); + ignore_parent_tx(bmain, scene, ob); + + DAG_id_flush_update(&ob->id, OB_RECALC_OB|OB_RECALC_DATA); + + change = 1; + } + CTX_DATA_END; + + if(!change) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + return OPERATOR_FINISHED; +} + +static int visual_transform_apply_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + int change = 0; + + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { + where_is_object(scene, ob); + + VECCOPY(ob->loc, ob->obmat[3]); + Mat4ToSize(ob->obmat, ob->size); + Mat4ToEul(ob->obmat, ob->rot); + + where_is_object(scene, ob); + + change = 1; + } + CTX_DATA_END; + + if(!change) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_visual_transform_apply(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Apply Visual Transform"; + ot->description = "Apply the object's visual transformation to its data."; + ot->idname= "OBJECT_OT_visual_transform_apply"; + + /* api callbacks */ + ot->exec= visual_transform_apply_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int location_apply_exec(bContext *C, wmOperator *op) +{ + return apply_objects_internal(C, op->reports, 1, 0, 0); +} + +void OBJECT_OT_location_apply(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Apply Location"; + ot->description = "Apply the object's location to its data."; + ot->idname= "OBJECT_OT_location_apply"; + + /* api callbacks */ + ot->exec= location_apply_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int scale_apply_exec(bContext *C, wmOperator *op) +{ + return apply_objects_internal(C, op->reports, 0, 1, 0); +} + +void OBJECT_OT_scale_apply(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Apply Scale"; + ot->description = "Apply the object's scale to its data."; + ot->idname= "OBJECT_OT_scale_apply"; + + /* api callbacks */ + ot->exec= scale_apply_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int rotation_apply_exec(bContext *C, wmOperator *op) +{ + return apply_objects_internal(C, op->reports, 0, 0, 1); +} + +void OBJECT_OT_rotation_apply(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Apply Rotation"; + ot->description = "Apply the object's rotation to its data."; + ot->idname= "OBJECT_OT_rotation_apply"; + + /* api callbacks */ + ot->exec= rotation_apply_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ Texture Space Transform ****************************/ + +void texspace_edit(Scene *scene, View3D *v3d) +{ + Base *base; + int nr=0; + + /* first test if from visible and selected objects + * texspacedraw is set: + */ + + if(scene->obedit) return; // XXX get from context + + for(base= FIRSTBASE; base; base= base->next) { + if(TESTBASELIB(v3d, base)) { + break; + } + } + + if(base==0) { + return; + } + + nr= 0; // XXX pupmenu("Texture Space %t|Grab/Move%x1|Size%x2"); + if(nr<1) return; + + for(base= FIRSTBASE; base; base= base->next) { + if(TESTBASELIB(v3d, base)) { + base->object->dtx |= OB_TEXSPACE; + } + } + + + if(nr==1) { +// XXX initTransform(TFM_TRANSLATION, CTX_TEXTURE); +// XXX Transform(); + } + else if(nr==2) { +// XXX initTransform(TFM_RESIZE, CTX_TEXTURE); +// XXX Transform(); + } + else if(nr==3) { +// XXX initTransform(TFM_ROTATION, CTX_TEXTURE); +// XXX Transform(); + } +} + +/************************ Mirror Menu ****************************/ + +void mirrormenu(void) +{ +// XXX initTransform(TFM_MIRROR, CTX_NO_PET); +// XXX Transform(); +} + +/********************* Set Object Center ************************/ + +static EnumPropertyItem prop_set_center_types[] = { + {0, "CENTER", 0, "ObData to Center", "Move object data around Object center"}, + {1, "CENTERNEW", 0, "Center New", "Move Object center to center of object data"}, + {2, "CENTERCURSOR", 0, "Center Cursor", "Move Object Center to position of the 3d cursor"}, + {0, NULL, 0, NULL, NULL} +}; + +/* 0 == do center, 1 == center new, 2 == center cursor */ +static int object_center_set_exec(bContext *C, wmOperator *op) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + ScrArea *sa= CTX_wm_area(C); + View3D *v3d= sa->spacedata.first; + Object *obedit= CTX_data_edit_object(C); + Object *ob; + Mesh *me, *tme; + Curve *cu; +/* BezTriple *bezt; + BPoint *bp; */ + Nurb *nu, *nu1; + EditVert *eve; + float cent[3], centn[3], min[3], max[3], omat[3][3]; + int a, total= 0; + int centermode = RNA_enum_get(op->ptr, "type"); + + /* keep track of what is changed */ + int tot_change=0, tot_lib_error=0, tot_multiuser_arm_error=0; + MVert *mvert; + + if(scene->id.lib || v3d==NULL){ + BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed on Lib data"); + return OPERATOR_CANCELLED; + } + if (obedit && centermode > 0) { + BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode"); + return OPERATOR_CANCELLED; + } + cent[0]= cent[1]= cent[2]= 0.0; + + if(obedit) { + + INIT_MINMAX(min, max); + + if(obedit->type==OB_MESH) { + Mesh *me= obedit->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + for(eve= em->verts.first; eve; eve= eve->next) { + if(v3d->around==V3D_CENTROID) { + total++; + VECADD(cent, cent, eve->co); + } + else { + DO_MINMAX(eve->co, min, max); + } + } + + if(v3d->around==V3D_CENTROID) { + VecMulf(cent, 1.0f/(float)total); + } + else { + cent[0]= (min[0]+max[0])/2.0f; + cent[1]= (min[1]+max[1])/2.0f; + cent[2]= (min[2]+max[2])/2.0f; + } + + for(eve= em->verts.first; eve; eve= eve->next) { + VecSubf(eve->co, eve->co, cent); + } + + recalc_editnormals(em); + tot_change++; + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + BKE_mesh_end_editmesh(me, em); + } + } + + /* reset flags */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + base->object->flag &= ~OB_DONE; + } + CTX_DATA_END; + + for (me= G.main->mesh.first; me; me= me->id.next) { + me->flag &= ~ME_ISDONE; + } + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + if((base->object->flag & OB_DONE)==0) { + base->object->flag |= OB_DONE; + + if(obedit==NULL && (me=get_mesh(base->object)) ) { + if (me->id.lib) { + tot_lib_error++; + } else { + if(centermode==2) { + VECCOPY(cent, give_cursor(scene, v3d)); + Mat4Invert(base->object->imat, base->object->obmat); + Mat4MulVecfl(base->object->imat, cent); + } else { + INIT_MINMAX(min, max); + mvert= me->mvert; + for(a=0; atotvert; a++, mvert++) { + DO_MINMAX(mvert->co, min, max); + } + + cent[0]= (min[0]+max[0])/2.0f; + cent[1]= (min[1]+max[1])/2.0f; + cent[2]= (min[2]+max[2])/2.0f; + } + + mvert= me->mvert; + for(a=0; atotvert; a++, mvert++) { + VecSubf(mvert->co, mvert->co, cent); + } + + if (me->key) { + KeyBlock *kb; + for (kb=me->key->block.first; kb; kb=kb->next) { + float *fp= kb->data; + + for (a=0; atotelem; a++, fp+=3) { + VecSubf(fp, fp, cent); + } + } + } + + me->flag |= ME_ISDONE; + + if(centermode) { + Mat3CpyMat4(omat, base->object->obmat); + + VECCOPY(centn, cent); + Mat3MulVecfl(omat, centn); + base->object->loc[0]+= centn[0]; + base->object->loc[1]+= centn[1]; + base->object->loc[2]+= centn[2]; + + where_is_object(scene, base->object); + ignore_parent_tx(bmain, scene, base->object); + + /* other users? */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob = base->object; + if((ob->flag & OB_DONE)==0) { + tme= get_mesh(ob); + + if(tme==me) { + + ob->flag |= OB_DONE; + ob->recalc= OB_RECALC_OB|OB_RECALC_DATA; + + Mat3CpyMat4(omat, ob->obmat); + VECCOPY(centn, cent); + Mat3MulVecfl(omat, centn); + ob->loc[0]+= centn[0]; + ob->loc[1]+= centn[1]; + ob->loc[2]+= centn[2]; + + where_is_object(scene, ob); + ignore_parent_tx(bmain, scene, ob); + + if(tme && (tme->flag & ME_ISDONE)==0) { + mvert= tme->mvert; + for(a=0; atotvert; a++, mvert++) { + VecSubf(mvert->co, mvert->co, cent); + } + + if (tme->key) { + KeyBlock *kb; + for (kb=tme->key->block.first; kb; kb=kb->next) { + float *fp= kb->data; + + for (a=0; atotelem; a++, fp+=3) { + VecSubf(fp, fp, cent); + } + } + } + + tme->flag |= ME_ISDONE; + } + } + } + + ob= ob->id.next; + } + CTX_DATA_END; + } + tot_change++; + } + } + else if (ELEM(base->object->type, OB_CURVE, OB_SURF)) { + + /* weak code here... (ton) */ + if(obedit==base->object) { + ListBase *editnurb= curve_get_editcurve(obedit); + + nu1= editnurb->first; + cu= obedit->data; + } + else { + cu= base->object->data; + nu1= cu->nurb.first; + } + + if (cu->id.lib) { + tot_lib_error++; + } else { + if(centermode==2) { + VECCOPY(cent, give_cursor(scene, v3d)); + Mat4Invert(base->object->imat, base->object->obmat); + Mat4MulVecfl(base->object->imat, cent); + + /* don't allow Z change if curve is 2D */ + if( !( cu->flag & CU_3D ) ) + cent[2] = 0.0; + } + else { + INIT_MINMAX(min, max); + + nu= nu1; + while(nu) { + minmaxNurb(nu, min, max); + nu= nu->next; + } + + cent[0]= (min[0]+max[0])/2.0f; + cent[1]= (min[1]+max[1])/2.0f; + cent[2]= (min[2]+max[2])/2.0f; + } + + nu= nu1; + while(nu) { + if(nu->type == CU_BEZIER) { + a= nu->pntsu; + while (a--) { + VecSubf(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent); + VecSubf(nu->bezt[a].vec[1], nu->bezt[a].vec[1], cent); + VecSubf(nu->bezt[a].vec[2], nu->bezt[a].vec[2], cent); + } + } + else { + a= nu->pntsu*nu->pntsv; + while (a--) + VecSubf(nu->bp[a].vec, nu->bp[a].vec, cent); + } + nu= nu->next; + } + + if(centermode && obedit==0) { + Mat3CpyMat4(omat, base->object->obmat); + + Mat3MulVecfl(omat, cent); + base->object->loc[0]+= cent[0]; + base->object->loc[1]+= cent[1]; + base->object->loc[2]+= cent[2]; + + where_is_object(scene, base->object); + ignore_parent_tx(bmain, scene, base->object); + } + + tot_change++; + if(obedit) { + if (centermode==0) { + DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + } + break; + } + } + } + else if(base->object->type==OB_FONT) { + /* get from bb */ + + cu= base->object->data; + + if(cu->bb==0) { + /* do nothing*/ + } else if (cu->id.lib) { + tot_lib_error++; + } else { + cu->xof= -0.5f*( cu->bb->vec[4][0] - cu->bb->vec[0][0]); + cu->yof= -0.5f -0.5f*( cu->bb->vec[0][1] - cu->bb->vec[2][1]); /* extra 0.5 is the height o above line */ + + /* not really ok, do this better once! */ + cu->xof /= cu->fsize; + cu->yof /= cu->fsize; + + tot_change++; + } + } + else if(base->object->type==OB_ARMATURE) { + bArmature *arm = base->object->data; + + if (arm->id.lib) { + tot_lib_error++; + } else if(arm->id.us>1) { + /*BKE_report(op->reports, RPT_ERROR, "Can't apply to a multi user armature"); + return;*/ + tot_multiuser_arm_error++; + } else { + /* Function to recenter armatures in editarmature.c + * Bone + object locations are handled there. + */ + docenter_armature(scene, v3d, base->object, centermode); + tot_change++; + + where_is_object(scene, base->object); + ignore_parent_tx(bmain, scene, base->object); + + if(obedit) + break; + } + } + base->object->recalc= OB_RECALC_OB|OB_RECALC_DATA; + } + } + CTX_DATA_END; + + if (tot_change) { + ED_anim_dag_flush_update(C); + } + + /* Warn if any errors occured */ + if (tot_lib_error+tot_multiuser_arm_error) { + BKE_reportf(op->reports, RPT_WARNING, "%i Object(s) Not Centered, %i Changed:",tot_lib_error+tot_multiuser_arm_error, tot_change); + if (tot_lib_error) + BKE_reportf(op->reports, RPT_WARNING, "|%i linked library objects",tot_lib_error); + if (tot_multiuser_arm_error) + BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)",tot_multiuser_arm_error); + } + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_center_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Center"; + ot->description = "Set the object's center, by either moving the data, or set to center of data, or use 3d cursor"; + ot->idname= "OBJECT_OT_center_set"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_center_set_exec; + + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", ""); +} + diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1660160b56c..6808b10b49d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -25,8 +25,6 @@ * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** - * Creator-specific support for vertex deformation groups - * Added: apply deform function (ton) */ #include @@ -61,6 +59,7 @@ #include "BKE_utildefines.h" #include "RNA_access.h" +#include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" @@ -68,127 +67,55 @@ #include "ED_mesh.h" #include "ED_view3d.h" +#include "UI_interface.h" + #include "object_intern.h" -/* XXX */ -static void BIF_undo_push() {} -static void error() {} +/************************ Exported Functions **********************/ -static Lattice *def_get_lattice(Object *ob) +static Lattice *vgroup_edit_lattice(Object *ob) { if(ob->type==OB_LATTICE) { Lattice *lt= ob->data; - if(lt->editlatt) - return lt->editlatt; - return lt; - } - return NULL; -} - -/* only in editmode */ -void sel_verts_defgroup (Object *obedit, int select) -{ - EditVert *eve; - Object *ob; - int i; - MDeformVert *dvert; - - ob= obedit; - - if (!ob) - return; - - switch (ob->type){ - case OB_MESH: - { - Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - for (eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if (dvert && dvert->totweight){ - for (i=0; itotweight; i++){ - if (dvert->dw[i].def_nr == (ob->actdef-1)){ - if (select) eve->f |= SELECT; - else eve->f &= ~SELECT; - - break; - } - } - } - } - /* this has to be called, because this function operates on vertices only */ - if(select) EM_select_flush(em); // vertices to edges/faces - else EM_deselect_flush(em); - - BKE_mesh_end_editmesh(me, em); + return (lt->editlatt)? lt->editlatt: lt; } - break; - case OB_LATTICE: - { - Lattice *lt= def_get_lattice(ob); - - if(lt->dvert) { - BPoint *bp; - int a, tot; - - dvert= lt->dvert; - tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; atotweight; i++){ - if (dvert->dw[i].def_nr == (ob->actdef-1)) { - if(select) bp->f1 |= SELECT; - else bp->f1 &= ~SELECT; - - break; - } - } - } - } - } - break; - - default: - break; - } + return NULL; } /* check if deform vertex has defgroup index */ -MDeformWeight *get_defweight (MDeformVert *dv, int defgroup) +MDeformWeight *ED_vgroup_weight_get(MDeformVert *dv, int defgroup) { int i; - if (!dv || defgroup<0) + if(!dv || defgroup<0) return NULL; - for (i=0; itotweight; i++){ - if (dv->dw[i].def_nr == defgroup) + for(i=0; itotweight; i++) + if(dv->dw[i].def_nr == defgroup) return dv->dw+i; - } + return NULL; } -/* Ensures that mv has a deform weight entry for - the specified defweight group */ +/* Ensures that mv has a deform weight entry for the specified defweight group */ /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */ -MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup) +MDeformWeight *ED_vgroup_weight_verify(MDeformVert *dv, int defgroup) { MDeformWeight *newdw; /* do this check always, this function is used to check for it */ - if (!dv || defgroup<0) + if(!dv || defgroup<0) return NULL; - newdw = get_defweight (dv, defgroup); - if (newdw) + newdw = ED_vgroup_weight_get(dv, defgroup); + if(newdw) return newdw; - newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); - if (dv->dw){ - memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); - MEM_freeN (dv->dw); + newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); + if(dv->dw) { + memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); + MEM_freeN(dv->dw); } dv->dw=newdw; @@ -201,16 +128,16 @@ MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup) return dv->dw+(dv->totweight-1); } -bDeformGroup *add_defgroup_name (Object *ob, char *name) +bDeformGroup *ED_vgroup_add_name(Object *ob, char *name) { - bDeformGroup *defgroup; + bDeformGroup *defgroup; - if (!ob) + if(!ob) return NULL; - defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup"); + defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup"); - BLI_strncpy (defgroup->name, name, 32); + BLI_strncpy(defgroup->name, name, 32); BLI_addtail(&ob->defbase, defgroup); unique_vertexgroup_name(defgroup, ob); @@ -220,444 +147,157 @@ bDeformGroup *add_defgroup_name (Object *ob, char *name) return defgroup; } -void add_defgroup (Object *ob) +bDeformGroup *ED_vgroup_add(Object *ob) { - add_defgroup_name (ob, "Group"); + return ED_vgroup_add_name(ob, "Group"); } - -void duplicate_defgroup ( Object *ob ) +void ED_vgroup_data_create(ID *id) { - bDeformGroup *dg, *cdg; - char name[32], s[32]; - MDeformWeight *org, *cpy; - MDeformVert *dvert, *dvert_array=NULL; - int i, idg, icdg, dvert_tot=0; - - if (ob->type != OB_MESH && ob->type != OB_LATTICE) - return; - - dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); - if (!dg) - return; - - if (strstr(dg->name, "_copy")) { - BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */ - } else { - BLI_snprintf (name, 32, "%s_copy", dg->name); - while (get_named_vertexgroup (ob, name)) { - if ((strlen (name) + 6) > 32) { - error ("Error: the name for the new group is > 32 characters"); - return; - } - strcpy (s, name); - BLI_snprintf (name, 32, "%s_copy", s); - } - } + /* create deform verts */ - cdg = copy_defgroup (dg); - strcpy (cdg->name, name); - unique_vertexgroup_name(cdg, ob); - - BLI_addtail (&ob->defbase, cdg); - - idg = (ob->actdef-1); - ob->actdef = BLI_countlist (&ob->defbase); - icdg = (ob->actdef-1); - - if(ob->type == OB_MESH) { - Mesh *me = get_mesh (ob); - dvert_array= me->dvert; - dvert_tot= me->totvert; - } - else if (ob->type == OB_LATTICE) { - Lattice *lt= (Lattice *)ob->data; - dvert_array= lt->dvert; - dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + if(GS(id->name)==ID_ME) { + Mesh *me= (Mesh *)id; + me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); } - - if (!dvert_array) - return; - - for (i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; - org = get_defweight (dvert, idg); - if (org) { - float weight = org->weight; - /* verify_defweight re-allocs org so need to store the weight first */ - cpy = verify_defweight (dvert, icdg); - cpy->weight = weight; - } + else if(GS(id->name)==ID_LT) { + Lattice *lt= (Lattice *)id; + lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert"); } } -static void del_defgroup_update_users(Object *ob, int id) +/* for mesh in object mode + lattice can be in editmode */ +void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) { - ExplodeModifierData *emd; - ModifierData *md; - ParticleSystem *psys; - ClothModifierData *clmd; - ClothSimSettings *clsim; - int a; + /* This routine removes the vertex from the deform + * group with number def_nr. + * + * This routine is meant to be fast, so it is the + * responsibility of the calling routine to: + * a) test whether ob is non-NULL + * b) test whether ob is a mesh + * c) calculate def_nr + */ - /* these cases don't use names to refer to vertex groups, so when - * they get deleted the numbers get out of sync, this corrects that */ + MDeformWeight *newdw; + MDeformVert *dvert= NULL; + int i; - if(ob->soft) { - if(ob->soft->vertgroup == id) - ob->soft->vertgroup= 0; - else if(ob->soft->vertgroup > id) - ob->soft->vertgroup--; + /* get the deform vertices corresponding to the + * vertnum + */ + if(ob->type==OB_MESH) { + if(((Mesh*)ob->data)->dvert) + dvert = ((Mesh*)ob->data)->dvert + vertnum; } + else if(ob->type==OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + + if(lt->dvert) + dvert = lt->dvert + vertnum; + } + + if(dvert==NULL) + return; + + /* for all of the deform weights in the + * deform vert + */ + for(i=dvert->totweight - 1 ; i>=0 ; i--){ - for(md=ob->modifiers.first; md; md=md->next) { - if(md->type == eModifierType_Explode) { - emd= (ExplodeModifierData*)md; - - if(emd->vgroup == id) - emd->vgroup= 0; - else if(emd->vgroup > id) - emd->vgroup--; - } - else if(md->type == eModifierType_Cloth) { - clmd= (ClothModifierData*)md; - clsim= clmd->sim_parms; - - if(clsim) { - if(clsim->vgroup_mass == id) - clsim->vgroup_mass= 0; - else if(clsim->vgroup_mass > id) - clsim->vgroup_mass--; - - if(clsim->vgroup_bend == id) - clsim->vgroup_bend= 0; - else if(clsim->vgroup_bend > id) - clsim->vgroup_bend--; - - if(clsim->vgroup_struct == id) - clsim->vgroup_struct= 0; - else if(clsim->vgroup_struct > id) - clsim->vgroup_struct--; + /* if the def_nr is the same as the one + * for our weight group then remove it + * from this deform vert. + */ + if(dvert->dw[i].def_nr == def_nr) { + dvert->totweight--; + + /* if there are still other deform weights + * attached to this vert then remove this + * deform weight, and reshuffle the others + */ + if(dvert->totweight) { + newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), + "deformWeight"); + if(dvert->dw){ + memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy(newdw+i, dvert->dw+i+1, + sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN(dvert->dw); + } + dvert->dw=newdw; + } + /* if there are no other deform weights + * left then just remove the deform weight + */ + else { + MEM_freeN(dvert->dw); + dvert->dw = NULL; + break; } } } - for(psys=ob->particlesystem.first; psys; psys=psys->next) { - for(a=0; avgroup[a] == id) - psys->vgroup[a]= 0; - else if(psys->vgroup[a] > id) - psys->vgroup[a]--; - } } -void del_defgroup_in_object_mode ( Object *ob ) +/* for Mesh in Object mode */ +/* allows editmode for Lattice */ +void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, int assignmode) { - bDeformGroup *dg; - MDeformVert *dvert, *dvert_array=NULL; - int i, e, dvert_tot=0; - - if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE)) - return; + /* add the vert to the deform group with the + * specified number + */ + MDeformVert *dv= NULL; + MDeformWeight *newdw; + int i; - if(ob->type == OB_MESH) { - Mesh *me = get_mesh (ob); - dvert_array= me->dvert; - dvert_tot= me->totvert; + /* get the vert */ + if(ob->type==OB_MESH) { + if(((Mesh*)ob->data)->dvert) + dv = ((Mesh*)ob->data)->dvert + vertnum; } - else if (ob->type == OB_LATTICE) { - Lattice *lt= (Lattice *)ob->data; - dvert_array= lt->dvert; - dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + else if(ob->type==OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + + if(lt->dvert) + dv = lt->dvert + vertnum; } - dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); - if (!dg) + if(dv==NULL) return; - if (dvert_array) { - for (i = 0; i < dvert_tot; i++) { - dvert = dvert_array + i; - if (dvert) { - if (get_defweight (dvert, (ob->actdef-1))) - remove_vert_defgroup (ob, dg, i); - } - } - - for (i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; - if (dvert) { - for (e = 0; e < dvert->totweight; e++) { - if (dvert->dw[e].def_nr > (ob->actdef-1)) - dvert->dw[e].def_nr--; - } + /* Lets first check to see if this vert is + * already in the weight group -- if so + * lets update it + */ + for(i=0; itotweight; i++){ + + /* if this weight cooresponds to the + * deform group, then add it using + * the assign mode provided + */ + if(dv->dw[i].def_nr == def_nr){ + + switch(assignmode) { + case WEIGHT_REPLACE: + dv->dw[i].weight=weight; + break; + case WEIGHT_ADD: + dv->dw[i].weight+=weight; + if(dv->dw[i].weight >= 1.0) + dv->dw[i].weight = 1.0; + break; + case WEIGHT_SUBTRACT: + dv->dw[i].weight-=weight; + /* if the weight is zero or less then + * remove the vert from the deform group + */ + if(dv->dw[i].weight <= 0.0) + ED_vgroup_nr_vert_remove(ob, def_nr, vertnum); + break; } - } - } - - del_defgroup_update_users(ob, ob->actdef); - - /* Update the active deform index if necessary */ - if (ob->actdef == BLI_countlist(&ob->defbase)) - ob->actdef--; - - /* Remove the group */ - BLI_freelinkN (&ob->defbase, dg); -} - -void del_defgroup (Object *ob) -{ - bDeformGroup *defgroup; - int i; - - if (!ob) - return; - - if (!ob->actdef) - return; - - defgroup = BLI_findlink(&ob->defbase, ob->actdef-1); - if (!defgroup) - return; - - /* Make sure that no verts are using this group */ - remove_verts_defgroup(ob, 1); - - /* Make sure that any verts with higher indices are adjusted accordingly */ - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - EditVert *eve; - MDeformVert *dvert; - - for (eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if (dvert) - for (i=0; itotweight; i++) - if (dvert->dw[i].def_nr > (ob->actdef-1)) - dvert->dw[i].def_nr--; - } - BKE_mesh_end_editmesh(me, em); - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= def_get_lattice(ob); - BPoint *bp; - MDeformVert *dvert= lt->dvert; - int a, tot; - - if (dvert) { - tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; atotweight; i++){ - if (dvert->dw[i].def_nr > (ob->actdef-1)) - dvert->dw[i].def_nr--; - } - } - } - } - - del_defgroup_update_users(ob, ob->actdef); - - /* Update the active deform index if necessary */ - if (ob->actdef==BLI_countlist(&ob->defbase)) - ob->actdef--; - - /* Remove the group */ - BLI_freelinkN (&ob->defbase, defgroup); - - /* remove all dverts */ - if(ob->actdef==0) { - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert= NULL; - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= def_get_lattice(ob); - if (lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert= NULL; - } - } - } -} - -void del_all_defgroups (Object *ob) -{ - /* Sanity check */ - if (ob == NULL) - return; - - /* Remove all DVerts */ - if (ob->type==OB_MESH) { - Mesh *me= ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert= NULL; - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= def_get_lattice(ob); - if (lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert= NULL; - } - } - - /* Remove all DefGroups */ - BLI_freelistN(&ob->defbase); - - /* Fix counters/indices */ - ob->actdef= 0; -} - -void create_dverts(ID *id) -{ - /* create deform verts - */ - - if( GS(id->name)==ID_ME) { - Mesh *me= (Mesh *)id; - me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); - } - else if( GS(id->name)==ID_LT) { - Lattice *lt= (Lattice *)id; - lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert"); - } -} - -/* for mesh in object mode - lattice can be in editmode */ -void remove_vert_def_nr (Object *ob, int def_nr, int vertnum) -{ - /* This routine removes the vertex from the deform - * group with number def_nr. - * - * This routine is meant to be fast, so it is the - * responsibility of the calling routine to: - * a) test whether ob is non-NULL - * b) test whether ob is a mesh - * c) calculate def_nr - */ - - MDeformWeight *newdw; - MDeformVert *dvert= NULL; - int i; - - /* get the deform vertices corresponding to the - * vertnum - */ - if(ob->type==OB_MESH) { - if( ((Mesh*)ob->data)->dvert ) - dvert = ((Mesh*)ob->data)->dvert + vertnum; - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= def_get_lattice(ob); - - if(lt->dvert) - dvert = lt->dvert + vertnum; - } - - if(dvert==NULL) - return; - - /* for all of the deform weights in the - * deform vert - */ - for (i=dvert->totweight - 1 ; i>=0 ; i--){ - - /* if the def_nr is the same as the one - * for our weight group then remove it - * from this deform vert. - */ - if (dvert->dw[i].def_nr == def_nr) { - dvert->totweight--; - - /* if there are still other deform weights - * attached to this vert then remove this - * deform weight, and reshuffle the others - */ - if (dvert->totweight) { - newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), - "deformWeight"); - if (dvert->dw){ - memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); - memcpy (newdw+i, dvert->dw+i+1, - sizeof(MDeformWeight)*(dvert->totweight-i)); - MEM_freeN (dvert->dw); - } - dvert->dw=newdw; - } - /* if there are no other deform weights - * left then just remove the deform weight - */ - else { - MEM_freeN (dvert->dw); - dvert->dw = NULL; - break; - } - } - } - -} - -/* for Mesh in Object mode */ -/* allows editmode for Lattice */ -void add_vert_defnr (Object *ob, int def_nr, int vertnum, - float weight, int assignmode) -{ - /* add the vert to the deform group with the - * specified number - */ - MDeformVert *dv= NULL; - MDeformWeight *newdw; - int i; - - /* get the vert */ - if(ob->type==OB_MESH) { - if(((Mesh*)ob->data)->dvert) - dv = ((Mesh*)ob->data)->dvert + vertnum; - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= def_get_lattice(ob); - - if(lt->dvert) - dv = lt->dvert + vertnum; - } - - if(dv==NULL) - return; - - /* Lets first check to see if this vert is - * already in the weight group -- if so - * lets update it - */ - for (i=0; itotweight; i++){ - - /* if this weight cooresponds to the - * deform group, then add it using - * the assign mode provided - */ - if (dv->dw[i].def_nr == def_nr){ - - switch (assignmode) { - case WEIGHT_REPLACE: - dv->dw[i].weight=weight; - break; - case WEIGHT_ADD: - dv->dw[i].weight+=weight; - if (dv->dw[i].weight >= 1.0) - dv->dw[i].weight = 1.0; - break; - case WEIGHT_SUBTRACT: - dv->dw[i].weight-=weight; - /* if the weight is zero or less then - * remove the vert from the deform group - */ - if (dv->dw[i].weight <= 0.0) - remove_vert_def_nr(ob, def_nr, vertnum); - break; - } - return; + return; } } @@ -665,7 +305,7 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum, * we must take a different form of action ... */ - switch (assignmode) { + switch(assignmode) { case WEIGHT_SUBTRACT: /* if we are subtracting then we don't * need to do anything @@ -677,11 +317,11 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum, /* if we are doing an additive assignment, then * we need to create the deform weight */ - newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), + newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); - if (dv->dw){ - memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); - MEM_freeN (dv->dw); + if(dv->dw){ + memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); + MEM_freeN(dv->dw); } dv->dw=newdw; @@ -694,8 +334,7 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum, } /* called while not in editmode */ -void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, - float weight, int assignmode) +void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight, int assignmode) { /* add the vert to the deform group with the * specified assign mode @@ -706,115 +345,27 @@ void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, * it can't be found */ def_nr = get_defgroup_num(ob, dg); - if (def_nr < 0) return; + if(def_nr < 0) return; /* if there's no deform verts then * create some */ if(ob->type==OB_MESH) { - if (!((Mesh*)ob->data)->dvert) - create_dverts(ob->data); + if(!((Mesh*)ob->data)->dvert) + ED_vgroup_data_create(ob->data); } else if(ob->type==OB_LATTICE) { - if (!((Lattice*)ob->data)->dvert) - create_dverts(ob->data); + if(!((Lattice*)ob->data)->dvert) + ED_vgroup_data_create(ob->data); } /* call another function to do the work */ - add_vert_defnr (ob, def_nr, vertnum, weight, assignmode); -} - -/* Only available in editmode */ -void assign_verts_defgroup (Object *ob, float weight) -{ - EditVert *eve; - bDeformGroup *dg, *eg; - MDeformWeight *newdw; - MDeformVert *dvert; - int i, done; - - if (!ob) - return; - - dg=BLI_findlink(&ob->defbase, ob->actdef-1); - if (!dg){ - error ("No vertex group is active"); - return; - } - - switch (ob->type){ - case OB_MESH: - { - Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) - EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT); - - /* Go through the list of editverts and assign them */ - for (eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if (dvert && (eve->f & 1)){ - done=0; - /* See if this vert already has a reference to this group */ - /* If so: Change its weight */ - done=0; - for (i=0; itotweight; i++){ - eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); - /* Find the actual group */ - if (eg==dg){ - dvert->dw[i].weight= weight; - done=1; - break; - } - } - /* If not: Add the group and set its weight */ - if (!done){ - newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); - if (dvert->dw){ - memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); - MEM_freeN (dvert->dw); - } - dvert->dw=newdw; - - dvert->dw[dvert->totweight].weight= weight; - dvert->dw[dvert->totweight].def_nr= ob->actdef-1; - - dvert->totweight++; - - } - } - } - BKE_mesh_end_editmesh(me, em); - } - break; - case OB_LATTICE: - { - Lattice *lt= def_get_lattice(ob); - BPoint *bp; - int a, tot; - - if(lt->dvert==NULL) - create_dverts(<->id); - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; af1 & SELECT) - add_vert_defnr (ob, ob->actdef-1, a, weight, WEIGHT_REPLACE); - } - } - break; - default: - printf ("Assigning deformation groups to unknown object type\n"); - break; - } - + ED_vgroup_nr_vert_add(ob, def_nr, vertnum, weight, assignmode); } /* mesh object mode, lattice can be in editmode */ -void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) +void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) { /* This routine removes the vertex from the specified * deform group. @@ -824,7 +375,7 @@ void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) /* if the object is NULL abort */ - if (!ob) + if(!ob) return; /* get the deform number that cooresponds @@ -832,28 +383,34 @@ void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) * can not be found. */ def_nr = get_defgroup_num(ob, dg); - if (def_nr < 0) return; + if(def_nr < 0) return; /* call another routine to do the work */ - remove_vert_def_nr (ob, def_nr, vertnum); + ED_vgroup_nr_vert_remove(ob, def_nr, vertnum); } -/* for mesh in object mode lattice can be in editmode */ -static float get_vert_def_nr (Object *ob, int def_nr, int vertnum) +static float get_vert_def_nr(Object *ob, int def_nr, int vertnum) { MDeformVert *dvert= NULL; + EditVert *eve; + Mesh *me; int i; - /* get the deform vertices corresponding to the - * vertnum - */ + /* get the deform vertices corresponding to the vertnum */ if(ob->type==OB_MESH) { - if( ((Mesh*)ob->data)->dvert ) - dvert = ((Mesh*)ob->data)->dvert + vertnum; + me= ob->data; + + if(me->edit_mesh) { + eve= BLI_findlink(&me->edit_mesh->verts, vertnum); + if(!eve) return 0.0f; + dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); + } + else + dvert = me->dvert + vertnum; } else if(ob->type==OB_LATTICE) { - Lattice *lt= def_get_lattice(ob); + Lattice *lt= vgroup_edit_lattice(ob); if(lt->dvert) dvert = lt->dvert + vertnum; @@ -869,23 +426,267 @@ static float get_vert_def_nr (Object *ob, int def_nr, int vertnum) return 0.0f; } -/* mesh object mode, lattice can be in editmode */ -float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) +float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum) { int def_nr; - if(!ob) - return 0.0f; + if(!ob) return 0.0f; def_nr = get_defgroup_num(ob, dg); if(def_nr < 0) return 0.0f; - return get_vert_def_nr (ob, def_nr, vertnum); + return get_vert_def_nr(ob, def_nr, vertnum); +} + +void ED_vgroup_select_by_name(Object *ob, char *name) +{ + bDeformGroup *curdef; + int actdef= 1; + + for(curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){ + if(!strcmp(curdef->name, name)) { + ob->actdef= actdef; + return; + } + } + + ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */ +} + +/********************** Operator Implementations *********************/ + +/* only in editmode */ +static void vgroup_select_verts(Object *ob, int select) +{ + EditVert *eve; + MDeformVert *dvert; + int i; + + if(ob->type == OB_MESH) { + Mesh *me= ob->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + for(eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if(dvert && dvert->totweight){ + for(i=0; itotweight; i++){ + if(dvert->dw[i].def_nr == (ob->actdef-1)){ + if(select) eve->f |= SELECT; + else eve->f &= ~SELECT; + + break; + } + } + } + } + /* this has to be called, because this function operates on vertices only */ + if(select) EM_select_flush(em); // vertices to edges/faces + else EM_deselect_flush(em); + + BKE_mesh_end_editmesh(me, em); + } + else if(ob->type == OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + + if(lt->dvert) { + BPoint *bp; + int a, tot; + + dvert= lt->dvert; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + for(a=0, bp= lt->def; atotweight; i++){ + if(dvert->dw[i].def_nr == (ob->actdef-1)) { + if(select) bp->f1 |= SELECT; + else bp->f1 &= ~SELECT; + + break; + } + } + } + } + } +} + +static void vgroup_duplicate(Object *ob) +{ + bDeformGroup *dg, *cdg; + char name[32], s[32]; + MDeformWeight *org, *cpy; + MDeformVert *dvert, *dvert_array=NULL; + int i, idg, icdg, dvert_tot=0; + + dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); + if(!dg) + return; + + if(strstr(dg->name, "_copy")) { + BLI_strncpy(name, dg->name, 32); /* will be renamed _copy.001... etc */ + } + else { + BLI_snprintf(name, 32, "%s_copy", dg->name); + while(get_named_vertexgroup(ob, name)) { + if((strlen(name) + 6) > 32) { + printf("Internal error: the name for the new vertex group is > 32 characters"); + return; + } + strcpy(s, name); + BLI_snprintf(name, 32, "%s_copy", s); + } + } + + cdg = copy_defgroup(dg); + strcpy(cdg->name, name); + unique_vertexgroup_name(cdg, ob); + + BLI_addtail(&ob->defbase, cdg); + + idg = (ob->actdef-1); + ob->actdef = BLI_countlist(&ob->defbase); + icdg = (ob->actdef-1); + + if(ob->type == OB_MESH) { + Mesh *me = get_mesh(ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if(ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + + if(!dvert_array) + return; + + for(i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; + org = ED_vgroup_weight_get(dvert, idg); + if(org) { + float weight = org->weight; + /* ED_vgroup_weight_verify re-allocs org so need to store the weight first */ + cpy = ED_vgroup_weight_verify(dvert, icdg); + cpy->weight = weight; + } + } +} + +static void vgroup_delete_update_users(Object *ob, int id) +{ + ExplodeModifierData *emd; + ModifierData *md; + ParticleSystem *psys; + ClothModifierData *clmd; + ClothSimSettings *clsim; + int a; + + /* these cases don't use names to refer to vertex groups, so when + * they get deleted the numbers get out of sync, this corrects that */ + + if(ob->soft) { + if(ob->soft->vertgroup == id) + ob->soft->vertgroup= 0; + else if(ob->soft->vertgroup > id) + ob->soft->vertgroup--; + } + + for(md=ob->modifiers.first; md; md=md->next) { + if(md->type == eModifierType_Explode) { + emd= (ExplodeModifierData*)md; + + if(emd->vgroup == id) + emd->vgroup= 0; + else if(emd->vgroup > id) + emd->vgroup--; + } + else if(md->type == eModifierType_Cloth) { + clmd= (ClothModifierData*)md; + clsim= clmd->sim_parms; + + if(clsim) { + if(clsim->vgroup_mass == id) + clsim->vgroup_mass= 0; + else if(clsim->vgroup_mass > id) + clsim->vgroup_mass--; + + if(clsim->vgroup_bend == id) + clsim->vgroup_bend= 0; + else if(clsim->vgroup_bend > id) + clsim->vgroup_bend--; + + if(clsim->vgroup_struct == id) + clsim->vgroup_struct= 0; + else if(clsim->vgroup_struct > id) + clsim->vgroup_struct--; + } + } + } + + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + for(a=0; avgroup[a] == id) + psys->vgroup[a]= 0; + else if(psys->vgroup[a] > id) + psys->vgroup[a]--; + } +} + +static void vgroup_delete_object_mode(Object *ob) +{ + bDeformGroup *dg; + MDeformVert *dvert, *dvert_array=NULL; + int i, e, dvert_tot=0; + + if(ob->type == OB_MESH) { + Mesh *me = get_mesh(ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if(ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + + dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); + if(!dg) + return; + + if(dvert_array) { + for(i = 0; i < dvert_tot; i++) { + dvert = dvert_array + i; + if(dvert) { + if(ED_vgroup_weight_get(dvert, (ob->actdef-1))) + ED_vgroup_vert_remove(ob, dg, i); + } + } + + for(i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; + if(dvert) { + for(e = 0; e < dvert->totweight; e++) { + if(dvert->dw[e].def_nr > (ob->actdef-1)) + dvert->dw[e].def_nr--; + } + } + } + } + + vgroup_delete_update_users(ob, ob->actdef); + + /* Update the active deform index if necessary */ + if(ob->actdef == BLI_countlist(&ob->defbase)) + ob->actdef--; + + /* Remove the group */ + BLI_freelinkN(&ob->defbase, dg); } -/* Only available in editmode */ +/* only in editmode */ /* removes from active defgroup, if allverts==0 only selected vertices */ -void remove_verts_defgroup (Object *ob, int allverts) +static void vgroup_active_remove_verts(Object *ob, int allverts) { EditVert *eve; MDeformVert *dvert; @@ -893,42 +694,35 @@ void remove_verts_defgroup (Object *ob, int allverts) bDeformGroup *dg, *eg; int i; - if (!ob) - return; - dg=BLI_findlink(&ob->defbase, ob->actdef-1); - if (!dg){ - error ("No vertex group is active"); + if(!dg) return; - } - switch (ob->type){ - case OB_MESH: - { + if(ob->type == OB_MESH) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); - for (eve=em->verts.first; eve; eve=eve->next){ + for(eve=em->verts.first; eve; eve=eve->next){ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - if (dvert && dvert->dw && ((eve->f & 1) || allverts)){ - for (i=0; itotweight; i++){ + if(dvert && dvert->dw && ((eve->f & 1) || allverts)){ + for(i=0; itotweight; i++){ /* Find group */ - eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); - if (eg == dg){ + eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); + if(eg == dg){ dvert->totweight--; - if (dvert->totweight){ - newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); + if(dvert->totweight){ + newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); - if (dvert->dw){ - memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); - memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); - MEM_freeN (dvert->dw); + if(dvert->dw){ + memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy(newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN(dvert->dw); } dvert->dw=newdw; } else{ - MEM_freeN (dvert->dw); + MEM_freeN(dvert->dw); dvert->dw=NULL; break; } @@ -938,10 +732,8 @@ void remove_verts_defgroup (Object *ob, int allverts) } BKE_mesh_end_editmesh(me, em); } - break; - case OB_LATTICE: - { - Lattice *lt= def_get_lattice(ob); + else if(ob->type == OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); if(lt->dvert) { BPoint *bp; @@ -949,155 +741,219 @@ void remove_verts_defgroup (Object *ob, int allverts) for(a=0, bp= lt->def; af1 & SELECT)) - remove_vert_defgroup (ob, dg, a); + ED_vgroup_vert_remove(ob, dg, a); } } } - break; - - default: - printf ("Removing deformation groups from unknown object type\n"); - break; - } } -/* Only available in editmode */ -/* removes from all defgroup, if allverts==0 only selected vertices */ -void remove_verts_defgroups(Object *ob, int allverts) +static void vgroup_delete_edit_mode(Object *ob) { - int actdef, defCount; + bDeformGroup *defgroup; + int i; - if (ob == NULL) return; - - actdef= ob->actdef; - defCount= BLI_countlist(&ob->defbase); - - if (defCount == 0) { - error("Object has no vertex groups"); + if(!ob->actdef) return; + + defgroup = BLI_findlink(&ob->defbase, ob->actdef-1); + if(!defgroup) + return; + + /* Make sure that no verts are using this group */ + vgroup_active_remove_verts(ob, 1); + + /* Make sure that any verts with higher indices are adjusted accordingly */ + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + EditVert *eve; + MDeformVert *dvert; + + for(eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if(dvert) + for(i=0; itotweight; i++) + if(dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; + } + BKE_mesh_end_editmesh(me, em); } - - /* To prevent code redundancy, we just use remove_verts_defgroup, but that - * only operates on the active vgroup. So we iterate through all groups, by changing - * active group index - */ - for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++) - remove_verts_defgroup(ob, allverts); + else if(ob->type==OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + BPoint *bp; + MDeformVert *dvert= lt->dvert; + int a, tot; - ob->actdef= actdef; -} + if(dvert) { + tot= lt->pntsu*lt->pntsv*lt->pntsw; + for(a=0, bp= lt->def; atotweight; i++){ + if(dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; + } + } + } + } -void vertexgroup_select_by_name(Object *ob, char *name) -{ - bDeformGroup *curdef; - int actdef= 1; + vgroup_delete_update_users(ob, ob->actdef); + + /* Update the active deform index if necessary */ + if(ob->actdef==BLI_countlist(&ob->defbase)) + ob->actdef--; - if(ob==NULL) return; + /* Remove the group */ + BLI_freelinkN (&ob->defbase, defgroup); - for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){ - if (!strcmp(curdef->name, name)) { - ob->actdef= actdef; - return; + /* remove all dverts */ + if(ob->actdef==0) { + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert= NULL; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + if(lt->dvert) { + MEM_freeN(lt->dvert); + lt->dvert= NULL; + } } } - ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */ } -/* This function provides a shortcut for adding/removing verts from - * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes - * and Lattices. (currently only restricted to those two) - * It is only responsible for - */ -void vgroup_assign_with_menu(Scene *scene, Object *ob) +static int vgroup_object_in_edit_mode(Object *ob) { - VPaint *wp= scene->toolsettings->wpaint; - int defCount; - int mode= 0; + if(ob->type == OB_MESH) + return (((Mesh*)ob->data)->edit_mesh != NULL); + else if(ob->type == OB_LATTICE) + return (((Lattice*)ob->data)->editlatt != NULL); - /* prevent crashes */ - if (wp==NULL || ob==NULL) return; - - defCount= BLI_countlist(&ob->defbase); + return 0; +} + +static void vgroup_delete(Object *ob) +{ + if(vgroup_object_in_edit_mode(ob)) + vgroup_delete_edit_mode(ob); + else + vgroup_delete_object_mode(ob); +} + +static void vgroup_delete_all(Object *ob) +{ + /* Remove all DVerts */ + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert= NULL; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + if(lt->dvert) { + MEM_freeN(lt->dvert); + lt->dvert= NULL; + } + } - /* give user choices of adding to current/new or removing from current */ -// XXX if (defCount && ob->actdef) -// mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4"); -// else -// mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1"); + /* Remove all DefGroups */ + BLI_freelistN(&ob->defbase); - /* handle choices */ - switch (mode) { - case 1: /* add to new group */ - add_defgroup(ob); - assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha); - BIF_undo_push("Assign to vertex group"); - break; - case 2: /* add to current group */ - assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha); - BIF_undo_push("Assign to vertex group"); - break; - case 3: /* remove from current group */ - remove_verts_defgroup(ob, 0); - BIF_undo_push("Remove from vertex group"); - break; - case 4: /* remove from all groups */ - remove_verts_defgroups(ob, 0); - BIF_undo_push("Remove from all vertex groups"); - break; + /* Fix counters/indices */ + ob->actdef= 0; +} + +/* only in editmode */ +static void vgroup_assign_verts(Object *ob, float weight) +{ + EditVert *eve; + bDeformGroup *dg, *eg; + MDeformWeight *newdw; + MDeformVert *dvert; + int i, done; + + dg=BLI_findlink(&ob->defbase, ob->actdef-1); + + if(ob->type == OB_MESH) { + Mesh *me= ob->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) + EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT); + + /* Go through the list of editverts and assign them */ + for(eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if(dvert && (eve->f & 1)){ + done=0; + /* See if this vert already has a reference to this group */ + /* If so: Change its weight */ + done=0; + for(i=0; itotweight; i++){ + eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); + /* Find the actual group */ + if(eg==dg){ + dvert->dw[i].weight= weight; + done=1; + break; + } + } + /* If not: Add the group and set its weight */ + if(!done){ + newdw = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); + if(dvert->dw){ + memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); + MEM_freeN(dvert->dw); + } + dvert->dw=newdw; + + dvert->dw[dvert->totweight].weight= weight; + dvert->dw[dvert->totweight].def_nr= ob->actdef-1; + + dvert->totweight++; + + } + } + } + BKE_mesh_end_editmesh(me, em); + } + else if(ob->type == OB_LATTICE) { + Lattice *lt= vgroup_edit_lattice(ob); + BPoint *bp; + int a, tot; + + if(lt->dvert==NULL) + ED_vgroup_data_create(<->id); + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + for(a=0, bp= lt->def; af1 & SELECT) + ED_vgroup_nr_vert_add(ob, ob->actdef-1, a, weight, WEIGHT_REPLACE); + } } } -/* This function provides a shortcut for commonly used vertex group - * functions - change weight (not implemented), change active group, delete active group, - * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now). - */ -void vgroup_operation_with_menu(Object *ob) +/* only in editmode */ +/* removes from all defgroup, if allverts==0 only selected vertices */ +static void vgroup_remove_verts(Object *ob, int allverts) { - int defCount; - int mode= 0; - - /* prevent crashes and useless cases */ - if (ob==NULL) return; + int actdef, defCount; + actdef= ob->actdef; defCount= BLI_countlist(&ob->defbase); - if (defCount == 0) return; - /* give user choices of adding to current/new or removing from current */ -// XXX if (ob->actdef) -// mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3"); -// else -// mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3"); + if(defCount == 0) + return; - /* handle choices */ - switch (mode) { - case 1: /* change active group*/ - { - char *menustr= NULL; // XXX get_vertexgroup_menustr(ob); - short nr; - - if (menustr) { - nr= 1; // pupmenu(menustr); // XXX - - if ((nr >= 1) && (nr <= defCount)) - ob->actdef= nr; - - MEM_freeN(menustr); - } - } - break; - case 2: /* delete active group */ - { - del_defgroup(ob); - BIF_undo_push("Delete vertex group"); - } - break; - case 3: /* delete all groups */ - { - del_all_defgroups(ob); - BIF_undo_push("Delete all vertex groups"); - } - break; - } + /* To prevent code redundancy, we just use vgroup_active_remove_verts, but that + * only operates on the active vgroup. So we iterate through all groups, by changing + * active group index + */ + for(ob->actdef= 1; ob->actdef <= defCount; ob->actdef++) + vgroup_active_remove_verts(ob, allverts); + + ob->actdef= actdef; } /********************** vertex group operators *********************/ @@ -1106,14 +962,25 @@ static int vertex_group_poll(bContext *C) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; ID *data= (ob)? ob->data: NULL; - return (ob && !ob->id.lib && data && !data->lib); + return (ob && !ob->id.lib && ELEM(ob->type, OB_MESH, OB_LATTICE) && data && !data->lib); +} + +static int vertex_group_poll_edit(bContext *C) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ID *data= (ob)? ob->data: NULL; + + if(!(ob && !ob->id.lib && data && !data->lib)) + return 0; + + return vgroup_object_in_edit_mode(ob); } static int vertex_group_add_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - add_defgroup(ob); + ED_vgroup_add(ob); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -1138,16 +1005,13 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot) static int vertex_group_remove_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Scene *scene= CTX_data_scene(C); - if(scene->obedit == ob) { - del_defgroup(ob); - } - else { - del_defgroup_in_object_mode(ob); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } + if(RNA_boolean_get(op->ptr, "all")) + vgroup_delete_all(ob); + else + vgroup_delete(ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -1166,6 +1030,9 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "all", 0, "All", "Remove from all vertex groups."); } static int vertex_group_assign_exec(bContext *C, wmOperator *op) @@ -1173,7 +1040,10 @@ static int vertex_group_assign_exec(bContext *C, wmOperator *op) ToolSettings *ts= CTX_data_tool_settings(C); Object *ob= CTX_data_edit_object(C); - assign_verts_defgroup(ob, ts->vgroup_weight); + if(RNA_boolean_get(op->ptr, "new")) + ED_vgroup_add(ob); + + vgroup_assign_verts(ob, ts->vgroup_weight); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); @@ -1187,21 +1057,24 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_assign"; /* api callbacks */ - ot->poll= vertex_group_poll; + ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_assign_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "new", 0, "New", "Assign vertex to new vertex group."); } static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - remove_verts_defgroup(ob, 0); + vgroup_remove_verts(ob, 0); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - + return OPERATOR_FINISHED; } @@ -1210,13 +1083,16 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) /* identifiers */ ot->name= "Remove from Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_remove_from"; - + /* api callbacks */ - ot->poll= vertex_group_poll; + ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_remove_from_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "all", 0, "All", "Remove from all vertex groups."); } static int vertex_group_select_exec(bContext *C, wmOperator *op) @@ -1226,7 +1102,7 @@ static int vertex_group_select_exec(bContext *C, wmOperator *op) if(!ob || ob->id.lib) return OPERATOR_CANCELLED; - sel_verts_defgroup(ob, 1); + vgroup_select_verts(ob, 1); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; @@ -1237,9 +1113,9 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot) /* identifiers */ ot->name= "Select Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_select"; - + /* api callbacks */ - ot->poll= vertex_group_poll; + ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_select_exec; /* flags */ @@ -1250,7 +1126,7 @@ static int vertex_group_deselect_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - sel_verts_defgroup(ob, 0); + vgroup_select_verts(ob, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; @@ -1261,9 +1137,9 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) /* identifiers */ ot->name= "Deselect Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_deselect"; - + /* api callbacks */ - ot->poll= vertex_group_poll; + ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_deselect_exec; /* flags */ @@ -1274,11 +1150,11 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - duplicate_defgroup(ob); + vgroup_duplicate(ob); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - + return OPERATOR_FINISHED; } @@ -1287,7 +1163,7 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) /* identifiers */ ot->name= "Copy Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_copy"; - + /* api callbacks */ ot->poll= vertex_group_poll; ot->exec= vertex_group_copy_exec; @@ -1300,25 +1176,25 @@ static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Base *base; + Base *base; int retval= OPERATOR_CANCELLED; - for(base=scene->base.first; base; base= base->next) { - if(base->object->type==ob->type) { - if(base->object!=ob && base->object->data==ob->data) { - BLI_freelistN(&base->object->defbase); - BLI_duplicatelist(&base->object->defbase, &ob->defbase); - base->object->actdef= ob->actdef; + for(base=scene->base.first; base; base= base->next) { + if(base->object->type==ob->type) { + if(base->object!=ob && base->object->data==ob->data) { + BLI_freelistN(&base->object->defbase); + BLI_duplicatelist(&base->object->defbase, &ob->defbase); + base->object->actdef= ob->actdef; - DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); + DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, base->object); WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data); retval = OPERATOR_FINISHED; - } - } - } - + } + } + } + return retval; } @@ -1327,7 +1203,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) /* identifiers */ ot->name= "Copy Vertex Group to Linked"; ot->idname= "OBJECT_OT_vertex_group_copy_to_linked"; - + /* api callbacks */ ot->poll= vertex_group_poll; ot->exec= vertex_group_copy_to_linked_exec; @@ -1336,3 +1212,110 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static EnumPropertyItem vgroup_items[]= { + {0, NULL, 0, NULL, NULL}}; + +static int set_active_group_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + int nr= RNA_enum_get(op->ptr, "group"); + + ob->actdef= nr+1; + + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; +} + +static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + bDeformGroup *def; + int a, totitem= 0; + + if(!C) /* needed for docs */ + return vgroup_items; + + for(a=0, def=ob->defbase.first; def; def=def->next, a++) { + tmp.value= a; + tmp.identifier= def->name; + tmp.name= def->name; + RNA_enum_item_add(&item, &totitem, &tmp); + } + + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; +} + +void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Set Active Vertex Group"; + ot->idname= "OBJECT_OT_vertex_group_set_active"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= set_active_group_exec; + ot->invoke= WM_menu_invoke; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active."); + RNA_def_enum_funcs(prop, vgroup_itemf); +} + +static int vertex_group_menu_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + uiPopupMenu *pup; + uiLayout *layout; + + pup= uiPupMenuBegin(C, "Vertex Groups", 0); + layout= uiPupMenuLayout(pup); + uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); + + if(vgroup_object_in_edit_mode(ob)) { + uiItemBooleanO(layout, "Assign to New Group", 0, "OBJECT_OT_vertex_group_assign", "new", 1); + + if(BLI_countlist(&ob->defbase) && ob->actdef) { + uiItemO(layout, "Assign to Group", 0, "OBJECT_OT_vertex_group_assign"); + uiItemO(layout, "Remove from Group", 0, "OBJECT_OT_vertex_group_remove_from"); + uiItemBooleanO(layout, "Remove from All", 0, "OBJECT_OT_vertex_group_remove_from", "all", 1); + } + } + + if(BLI_countlist(&ob->defbase) && ob->actdef) { + if(vgroup_object_in_edit_mode(ob)) + uiItemS(layout); + + uiItemO(layout, "Set Active Group", 0, "OBJECT_OT_vertex_group_set_active"); + uiItemO(layout, "Remove Group", 0, "OBJECT_OT_vertex_group_remove"); + uiItemBooleanO(layout, "Remove All Groups", 0, "OBJECT_OT_vertex_group_remove", "all", 1); + } + + uiPupMenuEnd(C, pup); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_menu(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Vertex Group Menu"; + ot->idname= "OBJECT_OT_vertex_group_menu"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_menu_exec; +} + diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 1e36a32b9e1..17c51a7b7d3 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -108,6 +108,12 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } + else if(CTX_data_equals(member, "object")) { + if(scene->basact) + CTX_data_id_pointer_set(result, &scene->basact->object->id); + + return 1; + } else if(CTX_data_equals(member, "edit_object")) { /* convenience for now, 1 object per scene in editmode */ if(scene->obedit) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 73589371c4f..25ff57ca87f 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -408,8 +408,8 @@ void clear_wpaint_selectedfaces(Scene *scene) if (!strcmp(curdef->name, name)) break; if(curdef==NULL) { - int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */ - curdef= add_defgroup_name (ob, name); + int olddef= ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */ + curdef= ED_vgroup_add_name (ob, name); ob->actdef= olddef; } @@ -431,9 +431,9 @@ void clear_wpaint_selectedfaces(Scene *scene) faceverts[3]= mface->v4; for (i=0; i<3 || faceverts[i]; i++) { if(!((me->dvert+faceverts[i])->flag)) { - dw= verify_defweight(me->dvert+faceverts[i], vgroup); + dw= ED_vgroup_weight_verify(me->dvert+faceverts[i], vgroup); if(dw) { - uw= verify_defweight(wp->wpaint_prev+faceverts[i], vgroup); + uw= ED_vgroup_weight_verify(wp->wpaint_prev+faceverts[i], vgroup); uw->weight= dw->weight; /* set the undo weight */ dw->weight= paintweight; @@ -442,11 +442,11 @@ void clear_wpaint_selectedfaces(Scene *scene) if(j>=0) { /* copy, not paint again */ if(vgroup_mirror != -1) { - dw= verify_defweight(me->dvert+j, vgroup_mirror); - uw= verify_defweight(wp->wpaint_prev+j, vgroup_mirror); + dw= ED_vgroup_weight_verify(me->dvert+j, vgroup_mirror); + uw= ED_vgroup_weight_verify(wp->wpaint_prev+j, vgroup_mirror); } else { - dw= verify_defweight(me->dvert+j, vgroup); - uw= verify_defweight(wp->wpaint_prev+j, vgroup); + dw= ED_vgroup_weight_verify(me->dvert+j, vgroup); + uw= ED_vgroup_weight_verify(wp->wpaint_prev+j, vgroup); } uw->weight= dw->weight; /* set the undo weight */ dw->weight= paintweight; @@ -963,20 +963,20 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode) fac= MIN4(w1, w2, w3, w4); if(w1==fac) { - dw= get_defweight(me->dvert+mface->v1, ob->actdef-1); + dw= ED_vgroup_weight_get(me->dvert+mface->v1, ob->actdef-1); if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; } else if(w2==fac) { - dw= get_defweight(me->dvert+mface->v2, ob->actdef-1); + dw= ED_vgroup_weight_get(me->dvert+mface->v2, ob->actdef-1); if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; } else if(w3==fac) { - dw= get_defweight(me->dvert+mface->v3, ob->actdef-1); + dw= ED_vgroup_weight_get(me->dvert+mface->v3, ob->actdef-1); if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; } else if(w4==fac) { if(mface->v4) { - dw= get_defweight(me->dvert+mface->v4, ob->actdef-1); + dw= ED_vgroup_weight_get(me->dvert+mface->v4, ob->actdef-1); if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f; } } @@ -995,12 +995,12 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha, int vgroup= ob->actdef-1; if(wp->flag & VP_ONLYVGROUP) { - dw= get_defweight(me->dvert+index, vgroup); - uw= get_defweight(wp->wpaint_prev+index, vgroup); + dw= ED_vgroup_weight_get(me->dvert+index, vgroup); + uw= ED_vgroup_weight_get(wp->wpaint_prev+index, vgroup); } else { - dw= verify_defweight(me->dvert+index, vgroup); - uw= verify_defweight(wp->wpaint_prev+index, vgroup); + dw= ED_vgroup_weight_verify(me->dvert+index, vgroup); + uw= ED_vgroup_weight_verify(wp->wpaint_prev+index, vgroup); } if(dw==NULL || uw==NULL) return; @@ -1012,9 +1012,9 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha, if(j>=0) { /* copy, not paint again */ if(vgroup_mirror != -1) - uw= verify_defweight(me->dvert+j, vgroup_mirror); + uw= ED_vgroup_weight_verify(me->dvert+j, vgroup_mirror); else - uw= verify_defweight(me->dvert+j, vgroup); + uw= ED_vgroup_weight_verify(me->dvert+j, vgroup); uw->weight= dw->weight; } @@ -1070,7 +1070,7 @@ static int set_wpaint(bContext *C, wmOperator *op) /* toggle */ if(pchan->bone->flag & BONE_ACTIVE) break; if(pchan) - vertexgroup_select_by_name(ob, pchan->name); + ED_vgroup_select_by_name(ob, pchan->name); } } else { @@ -1222,7 +1222,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event) /* if nothing was added yet, we make dverts and a vertex deform group */ if (!me->dvert) - create_dverts(&me->id); + ED_vgroup_data_create(&me->id); /* make mode data storage */ wpd= MEM_callocN(sizeof(struct WPaintData), "WPaintData"); @@ -1256,14 +1256,14 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event) if(pchan) { bDeformGroup *dg= get_named_vertexgroup(ob, pchan->name); if(dg==NULL) - dg= add_defgroup_name(ob, pchan->name); /* sets actdef */ + dg= ED_vgroup_add_name(ob, pchan->name); /* sets actdef */ else ob->actdef= get_defgroup_num(ob, dg); } } } if(ob->defbase.first==NULL) { - add_defgroup(ob); + ED_vgroup_add(ob); } // if(ob->lay & v3d->lay); else error("Active object is not in this layer"); @@ -1288,8 +1288,8 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event) if (!strcmp(curdef->name, name)) break; if(curdef==NULL) { - int olddef= ob->actdef; /* tsk, add_defgroup sets the active defgroup */ - curdef= add_defgroup_name (ob, name); + int olddef= ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */ + curdef= ED_vgroup_add_name (ob, name); ob->actdef= olddef; } @@ -1381,10 +1381,10 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P if(mface->v4) (me->dvert+mface->v4)->flag= 1; if(wp->mode==VP_BLUR) { - MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight; + MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = ED_vgroup_weight_verify; if(wp->flag & VP_ONLYVGROUP) - dw_func= get_defweight; + dw_func= ED_vgroup_weight_get; dw= dw_func(me->dvert+mface->v1, ob->actdef-1); if(dw) {paintweight+= dw->weight; totw++;} diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 1567f393d87..0df6f6250ff 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -85,133 +85,6 @@ #include "buttons_intern.h" // own include -/********************** group operators *********************/ - -static int group_add_exec(bContext *C, wmOperator *op) -{ - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Base *base; - Group *group; - int value= RNA_enum_get(op->ptr, "group"); - - if(!ob) - return OPERATOR_CANCELLED; - - base= object_in_scene(ob, scene); - if(!base) - return OPERATOR_CANCELLED; - - if(value == -1) - group= add_group( "Group" ); - else - group= BLI_findlink(&bmain->group, value); - - if(group) { - add_to_group(group, ob); - ob->flag |= OB_FROMGROUP; - base->flag |= OB_FROMGROUP; - } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - - return OPERATOR_FINISHED; -} - -static EnumPropertyItem group_items[]= { - {-1, "ADD_NEW", 0, "Add New Group", ""}, - {0, NULL, 0, NULL, NULL}}; - -static EnumPropertyItem *group_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - EnumPropertyItem tmp = {0, "", 0, "", ""}; - EnumPropertyItem *item= NULL; - Main *bmain; - Group *group; - int a, totitem= 0; - - if(!C) /* needed for docs */ - return group_items; - - RNA_enum_items_add_value(&item, &totitem, group_items, -1); - - bmain= CTX_data_main(C); - if(bmain->group.first) - RNA_enum_item_add_separator(&item, &totitem); - - for(a=0, group=bmain->group.first; group; group=group->id.next, a++) { - tmp.value= a; - tmp.identifier= group->id.name+2; - tmp.name= group->id.name+2; - RNA_enum_item_add(&item, &totitem, &tmp); - } - - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; -} - -void OBJECT_OT_group_add(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name= "Add Group"; - ot->idname= "OBJECT_OT_group_add"; - - /* api callbacks */ - ot->exec= group_add_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - prop= RNA_def_enum(ot->srna, "group", group_items, -1, "Group", "Group to add object to."); - RNA_def_enum_funcs(prop, group_itemf); -} - -static int group_remove_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data; - Base *base; - - if(!ob || !group) - return OPERATOR_CANCELLED; - - base= object_in_scene(ob, scene); - if(!base) - return OPERATOR_CANCELLED; - - rem_from_group(group, ob); - - if(find_group(ob, NULL) == NULL) { - ob->flag &= ~OB_FROMGROUP; - base->flag &= ~OB_FROMGROUP; - } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_group_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Remove Group"; - ot->idname= "OBJECT_OT_group_remove"; - - /* api callbacks */ - ot->exec= group_remove_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /********************** material slot operators *********************/ static int material_slot_add_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 001021e8d4b..20cab3b8aeb 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1198,7 +1198,7 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i if(use_wcol) { float col[3]; - MDeformWeight *mdw= get_defweight (lt->dvert+index, use_wcol-1); + MDeformWeight *mdw= ED_vgroup_weight_get (lt->dvert+index, use_wcol-1); weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2); glColor3fv(col); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 2bef37e43e6..06320f871da 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -899,7 +899,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) Mesh *me= ob->data; int a; for(a=0; atotvert; a++) - remove_vert_defgroup (ob, defGroup, a); + ED_vgroup_vert_remove (ob, defGroup, a); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } } diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 41159397634..d26f7a7a484 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -58,6 +58,7 @@ #include "ED_armature.h" #include "ED_particle.h" #include "ED_curve.h" +#include "ED_mball.h" #include "ED_mesh.h" #include "ED_object.h" #include "ED_screen.h" diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index a59fc8716ec..ccf4b7a2db3 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -56,6 +56,8 @@ extern EnumPropertyItem brush_sculpt_tool_items[]; extern EnumPropertyItem unpack_method_items[]; +extern EnumPropertyItem object_type_items[]; + #endif /* RNA_ENUM_TYPES */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 50ccbc86719..f81b314de6f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -64,6 +64,22 @@ static EnumPropertyItem parent_type_items[] = { {PARBONE, "BONE", 0, "Bone", ""}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem object_type_items[] = { + {OB_MESH, "MESH", 0, "Mesh", ""}, + {OB_CURVE, "CURVE", 0, "Curve", ""}, + {OB_SURF, "SURFACE", 0, "Surface", ""}, + {OB_MBALL, "META", 0, "Meta", ""}, + {OB_FONT, "TEXT", 0, "Text", ""}, + {0, "", 0, NULL, NULL}, + {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, + {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, + {OB_EMPTY, "EMPTY", 0, "Empty", ""}, + {0, "", 0, NULL, NULL}, + {OB_CAMERA, "CAMERA", 0, "Camera", ""}, + {OB_LAMP, "LAMP", 0, "Lamp", ""}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "DNA_key_types.h" diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index c2c90f055b0..3c03d24ca93 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -177,7 +177,7 @@ void wm_event_do_notifiers(bContext *C) do_anim= 1; } } - if(ELEM3(note->category, NC_SCENE, NC_OBJECT, NC_GEOM)) { + if(ELEM4(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE)) { ED_info_stats_clear(CTX_data_scene(C)); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO, NULL); } -- cgit v1.2.3 From 11c5cb452c32cc7dded241d71518d200edecb0b1 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 9 Sep 2009 15:45:12 +0000 Subject: Keyboard shortcuts Moved to modern OS standards for opening, saving, copying, pasting, cutting (text), new document, undo and redo. For Mac users, Cmd is used in addition to the Ctrl-based shortcuts. These changes are made according to an agreement among developers on IRC. --- source/blender/editors/gpencil/gpencil_buttons.c | 2 +- source/blender/editors/screen/screen_ops.c | 6 +--- source/blender/editors/space_text/space_text.c | 32 ++++++++++++---------- source/blender/windowmanager/intern/wm_operators.c | 25 +++++++---------- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 1036b4ccd8f..b25de4d5f1d 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -215,7 +215,7 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl) /* onion-skinning */ subcol= uiLayoutColumn(col, 1); uiItemR(subcol, "Onion Skinning", 0, &ptr, "use_onion_skinning", 0); - uiItemR(subcol, "GStep", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep) + uiItemR(subcol, "Frames", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep) /* additional options... */ subcol= uiLayoutColumn(col, 1); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index cb874ec1447..5403317042f 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3328,7 +3328,7 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0); @@ -3347,11 +3347,7 @@ void ED_keymap_screen(wmWindowManager *wm) /* render */ WM_keymap_add_item(keymap, "SCREEN_OT_render", F12KEY, KM_PRESS, 0, 0); -// WM_keymap_add_item(keymap, "SCREEN_OT_render", RETKEY, KM_PRESS, KM_CTRL, 0); -// WM_keymap_add_item(keymap, "SCREEN_OT_render", RETKEY, KM_PRESS, KM_OSKEY, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_render", F12KEY, KM_PRESS, KM_CTRL, 0)->ptr, "animation", 1); -// RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_render", RETKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "animation", 1); -// RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_render", RETKEY, KM_PRESS, KM_OSKEY|KM_SHIFT, 0)->ptr, "animation", 1); WM_keymap_add_item(keymap, "SCREEN_OT_render_view_cancel", ESCKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "SCREEN_OT_render_view_show", F11KEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 0d08490cfb0..1e37c2d6cb7 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -220,40 +220,44 @@ static void text_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "TEXT_OT_run_script", PKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0); - WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0); - WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_ALT, 0); if(U.uiflag & USER_MMB_PASTE) // XXX not dynamic RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0)->ptr, "selection", 1); WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_OSKEY, 0); - WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "TEXT_OT_indent", TABKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "TEXT_OT_uncomment", DKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "type", LINE_END); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); @@ -268,8 +272,8 @@ static void text_keymap(struct wmWindowManager *wm) RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", HOMEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_END); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", PREV_WORD); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ca2fbe23c3e..0036db3824b 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1918,22 +1918,17 @@ void wm_window_keymap(wmWindowManager *wm) /* note, this doesn't replace existing keymap items */ WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); -// WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_read_homefile", XKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0); - WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0); -// WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_open_mainfile", F1KEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_OSKEY, 0); -// WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_save_mainfile", WKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_OSKEY, 0); -// WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", F2KEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0);//Mac Exception WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); -- cgit v1.2.3 From d4a69283a60ae8f9e834f48ef7c2f3f68b51b73d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 17:34:14 +0000 Subject: 2.5: fix for recent file operator opening wrong item. --- source/blender/windowmanager/intern/wm_operators.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 0036db3824b..8cf47f0c682 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -803,7 +803,7 @@ static int recentfile_exec(bContext *C, wmOperator *op) WM_read_file(C, G.sce, op->reports); } else { - struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-2); + struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-1); if(recent) { WM_event_add_notifier(C, NC_WINDOW, NULL); WM_read_file(C, recent->filename, op->reports); @@ -831,11 +831,11 @@ static EnumPropertyItem *open_recentfile_itemf(bContext *C, PointerRNA *ptr, int EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; struct RecentFile *recent; - int totitem= 0, i, ofs= 0; + int totitem= 0, i; /* dynamically construct enum */ for(recent = G.recent_files.first, i=0; (inext, i++) { - tmp.value= i+ofs+1; + tmp.value= i+1; tmp.identifier= recent->filename; tmp.name= recent->filename; RNA_enum_item_add(&item, &totitem, &tmp); -- cgit v1.2.3 From 9e7c4ce806b8d6dc532c40d5aeaa15dc708e2a10 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 17:39:19 +0000 Subject: 2.5: Layer Buttons * Added RNA subtype for layers. * Shift-click works again. * uiItemR can now also handle armature/bone layers. * Also makes Move to Layer popup work as expected. --- release/ui/buttons_data_armature.py | 4 +- release/ui/buttons_data_bone.py | 2 +- .../blender/editors/interface/interface_layout.c | 60 ++++++++++++++++------ source/blender/editors/object/object_relations.c | 3 +- source/blender/makesrna/RNA_define.h | 2 + source/blender/makesrna/RNA_types.h | 4 ++ source/blender/makesrna/intern/makesrna.c | 2 + source/blender/makesrna/intern/rna_armature.c | 6 +-- source/blender/makesrna/intern/rna_define.c | 28 ++++++++++ source/blender/makesrna/intern/rna_group.c | 2 +- source/blender/makesrna/intern/rna_object.c | 2 +- source/blender/makesrna/intern/rna_rna.c | 2 + source/blender/makesrna/intern/rna_scene.c | 14 ++--- source/blender/windowmanager/intern/wm_operators.c | 4 +- 14 files changed, 96 insertions(+), 39 deletions(-) diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index ff0cc531c67..5924a2eb4ea 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -42,9 +42,9 @@ class DATA_PT_skeleton(DataButtonsPanel): col = split.column() col.itemL(text="Layers:") - col.template_layers(arm, "layer") + col.itemR(arm, "layer", text="") col.itemL(text="Protected Layers:") - col.template_layers(arm, "layer_protection") + col.itemR(arm, "layer_protection", text="") col.itemL(text="Edit Options:") col.itemR(arm, "x_axis_mirror") col.itemR(arm, "auto_ik") diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index 276ca066af5..0d379a4788f 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -98,7 +98,7 @@ class BONE_PT_bone(BoneButtonsPanel): row.itemR(bone, "connected") col.itemL(text="Layers:") - col.template_layers(bone, "layer") + col.itemR(bone, "layer", text="") col = split.column() col.itemL(text="Inherit:") diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index a52afcb1a92..04d575d96d4 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -310,6 +310,30 @@ static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, int a return sub; } +static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) +{ + wmWindow *win= CTX_wm_window(C); + uiBut *but= arg_but, *cbut; + PointerRNA *ptr= &but->rnapoin; + PropertyRNA *prop= but->rnaprop; + int i, index= GET_INT_FROM_POINTER(arg_index); + int shift= win->eventstate->shift; + int len= RNA_property_array_length(ptr, prop); + + if(!shift) { + RNA_property_boolean_set_index(ptr, prop, index, 1); + + for(i=0; iblock->buttons.first; cbut; cbut=cbut->next) + ui_check_but(cbut); + } +} + /* create buttons for an item with an RNA array */ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int h, int expand, int slider) { @@ -318,7 +342,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon PropertyType type; PropertySubType subtype; uiLayout *sub; - int a; + int a, b; /* retrieve type and subtype */ type= RNA_property_type(prop); @@ -332,9 +356,11 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); /* create buttons */ - if(type == PROP_BOOLEAN && len == 20) { + if(type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) { /* special check for layer layout */ int butw, buth, unit; + int cols= (len >= 20)? 2: 1; + int colbuts= len/(2*cols); uiBlockSetCurLayout(block, uiLayoutFree(layout, 0)); @@ -342,21 +368,23 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon butw= unit; buth= unit; - uiBlockBeginAlign(block); - for(a=0; a<5; a++) - uiDefAutoButR(block, ptr, prop, a, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth); - for(a=0; a<5; a++) - uiDefAutoButR(block, ptr, prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth); - uiBlockEndAlign(block); + for(b=0; bbuttonspacex; + for(a=0; abuttonspacex; + } } else if(subtype == PROP_MATRIX) { /* matrix layout */ @@ -784,7 +812,7 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PointerRNA if(!name[0] && icon == 0) h= 0; - if(type == PROP_BOOLEAN && len == 20) + if(ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) h += 2*UI_UNIT_Y; else if(subtype == PROP_MATRIX) h += ceil(sqrt(len))*UI_UNIT_Y; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 6fe01cced74..12cb2b95e06 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1037,8 +1037,7 @@ void OBJECT_OT_move_to_layer(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean_array(ot->srna, "layer", 20, NULL, "Layer", ""); - /* XXX boolean layer subtype, behavior */ + RNA_def_boolean_layer_member(ot->srna, "layer", 20, NULL, "Layer", ""); } /************************** Link to Scene Operator *****************************/ diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 1c6837bbcc8..03b12da1629 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -72,6 +72,8 @@ typedef void StructOrFunctionRNA; PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont, const char *identifier, int default_value, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax); diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index b57cbc3aa2c..c6fed5cd8e6 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -111,6 +111,10 @@ typedef enum PropertySubType { /* pointers */ PROP_NEVER_NULL = 30, + + /* booleans */ + PROP_LAYER = 40, + PROP_LAYER_MEMBER = 41 } PropertySubType; typedef enum PropertyFlag { diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 907eba4018f..cbfd7d326de 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1394,6 +1394,8 @@ static const char *rna_property_subtypename(PropertyType type) case PROP_XYZ: return "PROP_XYZ"; case PROP_RGB: return "PROP_RGB"; case PROP_NEVER_NULL: return "PROP_NEVER_NULL"; + case PROP_LAYER: return "PROP_LAYER"; + case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER"; default: { /* incase we dont have a type preset that includes the subtype */ if(RNA_SUBTYPE_UNIT(type)) { diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 3f4b75508fe..57eb3c1de4a 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -325,7 +325,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); /* flags */ - prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "layer", 1); RNA_def_property_array(prop, 16); if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_layer_get", "rna_EditBone_layer_set"); @@ -569,7 +569,7 @@ void rna_def_armature(BlenderRNA *brna) /* Boolean values */ /* layer */ - prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "layer", 1); RNA_def_property_array(prop, 16); RNA_def_property_ui_text(prop, "Visible Layers", "Armature layer visibility."); @@ -578,7 +578,7 @@ void rna_def_armature(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); /* layer protection */ - prop= RNA_def_property(srna, "layer_protection", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "layer_protection", PROP_BOOLEAN, PROP_LAYER); RNA_def_property_boolean_sdna(prop, NULL, "layer_protected", 1); RNA_def_property_array(prop, 16); RNA_def_property_ui_text(prop, "Layer Proxy Protection", "Protected layers in Proxy Instances are restored to Proxy settings on file reload and undo."); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index e415304ab6c..00cfb17dc84 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -1953,6 +1953,34 @@ PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_, const char *ident return prop; } +PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, + const char *ui_name, const char *ui_description) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER); + if(len != 0) RNA_def_property_array(prop, len); + if(default_value) RNA_def_property_boolean_array_default(prop, default_value); + RNA_def_property_ui_text(prop, ui_name, ui_description); + + return prop; +} + +PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, + const char *ui_name, const char *ui_description) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER); + if(len != 0) RNA_def_property_array(prop, len); + if(default_value) RNA_def_property_boolean_array_default(prop, default_value); + RNA_def_property_ui_text(prop, ui_name, ui_description); + + return prop; +} + PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, const char *ui_name, const char *ui_description) { diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index 18c04fbfb50..31bc6ccc74b 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -63,7 +63,7 @@ void RNA_def_group(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Objects", "A collection of this groups objects."); RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Group_objects_get", 0, 0, 0, 0, 0); - prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_LAYER); RNA_def_property_boolean_sdna(prop, NULL, "layer", 1); RNA_def_property_array(prop, 20); RNA_def_property_ui_text(prop, "Dupli Layers", "Layers visible when this groups is instanced as a dupli."); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index f81b314de6f..ce65ef4d450 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1073,7 +1073,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Mode", "Object interaction mode."); - prop= RNA_def_property(srna, "layers", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "layers", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 1); RNA_def_property_array(prop, 20); RNA_def_property_ui_text(prop, "Layers", "Layers the object is on."); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 57ed5ccef39..b1644405ff3 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -798,6 +798,8 @@ static void rna_def_property(BlenderRNA *brna) {PROP_XYZ, "XYZ", 0, "XYZ", ""}, {PROP_RGB, "RGB", 0, "RGB", ""}, {PROP_NEVER_NULL, "NEVER_NULL", 0, "Never Null", ""}, + {PROP_LAYER, "LAYER", 0, "Layer", ""}, + {PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem unit_items[] = { {PROP_UNIT_NONE, "NONE", 0, "None", ""}, diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f196001cc9d..965796c6d5b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -363,12 +363,6 @@ static void rna_SceneRenderLayer_layer_set(PointerRNA *ptr, const int *values) rl->lay= layer_set(rl->lay, values); } -static void rna_SceneRenderLayer_zmask_layer_set(PointerRNA *ptr, const int *values) -{ - SceneRenderLayer *rl= (SceneRenderLayer*)ptr->data; - rl->lay_zmask= layer_set(rl->lay_zmask, values); -} - static void rna_SceneRenderLayer_pass_update(bContext *C, PointerRNA *ptr) { Scene *scene= (Scene*)ptr->id.data; @@ -597,7 +591,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) else RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* layers */ - prop= RNA_def_property(srna, "visible_layers", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "visible_layers", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 1); RNA_def_property_array(prop, 20); RNA_def_property_ui_text(prop, "Visible Layers", "Scene layers included in this render layer."); @@ -606,12 +600,10 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop= RNA_def_property(srna, "zmask_layers", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "zmask_layers", PROP_BOOLEAN, PROP_LAYER); RNA_def_property_boolean_sdna(prop, NULL, "lay_zmask", 1); RNA_def_property_array(prop, 20); RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers."); - if(scene) RNA_def_property_boolean_funcs(prop, NULL, "rna_SceneRenderLayer_zmask_layer_set"); - else RNA_def_property_boolean_funcs(prop, NULL, "rna_RenderLayer_zmask_layer_set"); if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -1940,7 +1932,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, 0, 0, 0, "rna_Scene_objects_get", 0, 0, 0, 0, 0); /* Layers */ - prop= RNA_def_property(srna, "visible_layers", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "visible_layers", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 1); RNA_def_property_array(prop, 20); RNA_def_property_ui_text(prop, "Visible Layers", "Layers visible when rendering the scene."); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8cf47f0c682..7152d5bcfa2 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -531,7 +531,7 @@ int WM_operator_winactive(bContext *C) } /* op->invoke */ -static void redo_cb(bContext *C, void *arg_op, void *arg2) +static void redo_cb(bContext *C, void *arg_op, int event) { wmOperator *lastop= arg_op; @@ -553,7 +553,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1); - uiBlockSetFunc(block, redo_cb, arg_op, NULL); + uiBlockSetHandleFunc(block, redo_cb, arg_op); if(!op->properties) { IDPropertyTemplate val = {0}; -- cgit v1.2.3 From 4cb53d91ea1843dc0cb2c1d4c846e5a1974a20eb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 18:09:03 +0000 Subject: Small code cleanup related to curves, to avoid cryptic names: renamed set_four_ipo -> key_curve_position_weights renamed set_afgeleide_four_ipo -> key_curve_tangent_weights added key_curve_normal_weights --- source/blender/blenkernel/BKE_key.h | 5 +- source/blender/blenkernel/intern/anim.c | 10 +-- source/blender/blenkernel/intern/curve.c | 4 +- source/blender/blenkernel/intern/key.c | 115 ++++++++++++++++----------- source/blender/blenkernel/intern/lattice.c | 6 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/particle.c | 6 +- source/blender/blenkernel/intern/texture.c | 4 +- source/blender/blenloader/intern/readfile.c | 1 - source/blender/render/intern/source/strand.c | 4 +- 10 files changed, 91 insertions(+), 66 deletions(-) diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index faf8692b89a..94a7a7482e4 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -51,8 +51,9 @@ struct Key *copy_key(struct Key *key); void make_local_key(struct Key *key); void sort_keys(struct Key *key); -void set_four_ipo(float d, float *data, int type); -void set_afgeleide_four_ipo(float d, float *data, int type); +void key_curve_position_weights(float t, float *data, int type); +void key_curve_tangent_weights(float t, float *data, int type); +void key_curve_normal_weights(float t, float *data, int type); /* only exported to curve.c! */ void cp_cu_key(struct Curve *cu, struct KeyBlock *kb, int start, int end); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ffb7ff51b87..e75b31dd892 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -253,7 +253,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK /* note, commented out for follow constraint */ //if(cu->flag & CU_FOLLOW) { - set_afgeleide_four_ipo(1.0f-fac, data, KEY_BSPLINE); + key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE); dir[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ; dir[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ; @@ -268,10 +268,10 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK nu= cu->nurb.first; /* make sure that first and last frame are included in the vectors here */ - if((nu->type & 7)==CU_POLY) set_four_ipo(1.0f-fac, data, KEY_LINEAR); - else if((nu->type & 7)==CU_BEZIER) set_four_ipo(1.0f-fac, data, KEY_LINEAR); - else if(s0==s1 || p2==p3) set_four_ipo(1.0f-fac, data, KEY_CARDINAL); - else set_four_ipo(1.0f-fac, data, KEY_BSPLINE); + if((nu->type & 7)==CU_POLY) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); + else if((nu->type & 7)==CU_BEZIER) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); + else if(s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL); + else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE); vec[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ; vec[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index a1ad5347f7e..86cfe9d4c6f 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1476,7 +1476,7 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * if (nu->tilt_interp==3) { /* May as well support for tilt also 2.47 ease interp */ tilt_array[a] = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac); } else { - set_four_ipo(fac, t, nu->tilt_interp); + key_curve_position_weights(fac, t, nu->tilt_interp); tilt_array[a]= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa; } } @@ -1491,7 +1491,7 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * /* reuse interpolation from tilt if we can */ if (tilt_array==NULL || nu->tilt_interp != nu->radius_interp) { - set_four_ipo(fac, t, nu->radius_interp); + key_curve_position_weights(fac, t, nu->radius_interp); } radius_array[a]= t[0]*pprev->radius + t[1]*prevbezt->radius + t[2]*bezt->radius + t[3]*next->radius; } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 755a41ec4b2..70136afc321 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -258,66 +258,91 @@ void sort_keys(Key *key) /**************** do the key ****************/ +void key_curve_position_weights(float t, float *data, int type) +{ + float t2, t3, fc; + + if(type==KEY_LINEAR) { + data[0]= 0.0f; + data[1]= -t + 1.0f; + data[2]= t; + data[3]= 0.0f; + } + else if(type==KEY_CARDINAL) { + t2= t*t; + t3= t2*t; + fc= 0.71f; + + data[0]= -fc*t3 + 2.0f*fc*t2 - fc*t; + data[1]= (2.0f-fc)*t3 + (fc-3.0f)*t2 + 1.0f; + data[2]= (fc-2.0f)*t3 + (3.0f-2.0f*fc)*t2 + fc*t; + data[3]= fc*t3 - fc*t2; + } + else if(type==KEY_BSPLINE) { + t2= t*t; + t3= t2*t; + + data[0]= -0.16666666f*t3 + 0.5f*t2 - 0.5f*t + 0.16666666f; + data[1]= 0.5f*t3 - t2 + 0.6666666f; + data[2]= -0.5f*t3 + 0.5f*t2 + 0.5f*t + 0.16666666f; + data[3]= 0.16666666f*t3; + } +} -void set_four_ipo(float d, float *data, int type) +/* first derivative */ +void key_curve_tangent_weights(float t, float *data, int type) { - float d2, d3, fc; + float t2, fc; if(type==KEY_LINEAR) { data[0]= 0.0f; - data[1]= 1.0f-d; - data[2]= d; + data[1]= -1.0f; + data[2]= 1.0f; data[3]= 0.0f; } - else { - d2= d*d; - d3= d2*d; + else if(type==KEY_CARDINAL) { + t2= t*t; + fc= 0.71f; - if(type==KEY_CARDINAL) { - - fc= 0.71f; - - data[0]= -fc*d3 +2.0f*fc*d2 -fc*d; - data[1]= (2.0f-fc)*d3 +(fc-3.0f)*d2 +1.0f; - data[2]= (fc-2.0f)*d3 +(3.0f-2.0f*fc)*d2 +fc*d; - data[3]= fc*d3 -fc*d2; - } - else if(type==KEY_BSPLINE) { + data[0]= -3.0f*fc*t2 +4.0f*fc*t - fc; + data[1]= 3.0f*(2.0f-fc)*t2 +2.0f*(fc-3.0f)*t; + data[2]= 3.0f*(fc-2.0f)*t2 +2.0f*(3.0f-2.0f*fc)*t + fc; + data[3]= 3.0f*fc*t2 -2.0f*fc*t; + } + else if(type==KEY_BSPLINE) { + t2= t*t; - data[0]= -0.16666666f*d3 +0.5f*d2 -0.5f*d +0.16666666f; - data[1]= 0.5f*d3 -d2 +0.6666666f; - data[2]= -0.5f*d3 +0.5f*d2 +0.5f*d +0.16666666f; - data[3]= 0.16666666f*d3 ; - } + data[0]= -0.5f*t2 + t - 0.5f; + data[1]= 1.5f*t2 - 2.0f*t; + data[2]= -1.5f*t2 + t + 0.5f; + data[3]= 0.5f*t2; } } -void set_afgeleide_four_ipo(float d, float *data, int type) +/* second derivative */ +void key_curve_normal_weights(float t, float *data, int type) { - float d2, fc; + float fc; if(type==KEY_LINEAR) { - + data[0]= 0.0f; + data[1]= 0.0f; + data[2]= 0.0f; + data[3]= 0.0f; } - else { - d2= d*d; + else if(type==KEY_CARDINAL) { + fc= 0.71f; - if(type==KEY_CARDINAL) { - - fc= 0.71f; - - data[0]= -3.0f*fc*d2 +4.0f*fc*d -fc; - data[1]= 3.0f*(2.0f-fc)*d2 +2.0f*(fc-3.0f)*d; - data[2]= 3.0f*(fc-2.0f)*d2 +2.0f*(3.0f-2.0f*fc)*d +fc; - data[3]= 3.0f*fc*d2 -2.0f*fc*d; - } - else if(type==KEY_BSPLINE) { - - data[0]= -0.16666666f*3.0f*d2 +d -0.5f; - data[1]= 1.5f*d2 -2.0f*d; - data[2]= -1.5f*d2 +d +0.5f; - data[3]= 0.16666666f*3.0f*d2 ; - } + data[0]= -6.0f*fc*t + 4.0f*fc; + data[1]= 6.0f*(2.0f-fc)*t + 2.0f*(fc-3.0f); + data[2]= 6.0f*(fc-2.0f)*t + 2.0f*(3.0f-2.0f*fc); + data[3]= 6.0f*fc*t - 2.0f*fc; + } + else if(type==KEY_BSPLINE) { + data[0]= -1.0f*t + 1.0f; + data[1]= 3.0f*t - 2.0f; + data[2]= -3.0f*t + 1.0f; + data[3]= 1.0f*t; } } @@ -428,10 +453,10 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl) /* interpolation */ - set_four_ipo(d, t, k[1]->type); + key_curve_position_weights(d, t, k[1]->type); if(k[1]->type != k[2]->type) { - set_four_ipo(d, fval, k[2]->type); + key_curve_position_weights(d, fval, k[2]->type); temp= 1.0f-d; t[0]= temp*t[0]+ d*fval[0]; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 6614c657647..07973d0de57 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -367,7 +367,7 @@ void calc_latt_deform(float *co, float weight) u= (vec[0]-lt->fu)/lt->du; ui= (int)floor(u); u -= ui; - set_four_ipo(u, tu, lt->typeu); + key_curve_position_weights(u, tu, lt->typeu); } else { tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0; @@ -378,7 +378,7 @@ void calc_latt_deform(float *co, float weight) v= (vec[1]-lt->fv)/lt->dv; vi= (int)floor(v); v -= vi; - set_four_ipo(v, tv, lt->typev); + key_curve_position_weights(v, tv, lt->typev); } else { tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0; @@ -389,7 +389,7 @@ void calc_latt_deform(float *co, float weight) w= (vec[2]-lt->fw)/lt->dw; wi= (int)floor(w); w -= wi; - set_four_ipo(w, tw, lt->typew); + key_curve_position_weights(w, tw, lt->typew); } else { tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ec068c35c11..572c217e919 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2312,7 +2312,7 @@ void object_handle_update(Object *ob) if(ob->recalc & OB_RECALC_DATA) { - // printf("recalcdata %s\n", ob->id.name+2); + printf("recalc data %s\n", ob->id.name); /* includes all keys and modifiers */ if(ob->type==OB_MESH) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index b5b2c07af9c..e8a84ccceb5 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -873,7 +873,7 @@ static void interpolate_particle(short type, ParticleKey keys[4], float dt, Part VecfCubicInterpol(keys[1].co, keys[1].vel, keys[2].co, keys[2].vel, dt, result->co, result->vel); } else { - set_four_ipo(dt, t, type); + key_curve_position_weights(dt, t, type); weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, result->co); @@ -881,12 +881,12 @@ static void interpolate_particle(short type, ParticleKey keys[4], float dt, Part float temp[3]; if(dt>0.999f){ - set_four_ipo(dt-0.001f, t, type); + key_curve_position_weights(dt-0.001f, t, type); weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp); VECSUB(result->vel, result->co, temp); } else{ - set_four_ipo(dt+0.001f, t, type); + key_curve_position_weights(dt+0.001f, t, type); weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp); VECSUB(result->vel, temp, result->co); } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index be005af7827..f2c2498b39f 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -368,9 +368,9 @@ int do_colorband(ColorBand *coba, float in, float out[4]) CLAMP(fac, 0.0f, 1.0f); if(coba->ipotype==3) - set_four_ipo(fac, t, KEY_CARDINAL); + key_curve_position_weights(fac, t, KEY_CARDINAL); else - set_four_ipo(fac, t, KEY_BSPLINE); + key_curve_position_weights(fac, t, KEY_BSPLINE); out[0]= t[3]*cbd3->r +t[2]*cbd2->r +t[1]*cbd1->r +t[0]*cbd0->r; out[1]= t[3]*cbd3->g +t[2]*cbd2->g +t[1]*cbd1->g +t[0]*cbd0->g; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4e5789d87e8..61192ee0882 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -127,7 +127,6 @@ #include "BKE_global.h" // for G #include "BKE_group.h" #include "BKE_image.h" -#include "BKE_key.h" //void set_four_ipo #include "BKE_lattice.h" #include "BKE_library.h" // for wich_libbase #include "BKE_main.h" // for Main diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 05e36160f0e..88c275d0997 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -122,14 +122,14 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) spoint->dtstrandco *= 0.5f; } else { - set_four_ipo(t, data, type); + key_curve_position_weights(t, data, type); spoint->co[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0]; spoint->co[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1]; spoint->co[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2]; spoint->strandco= (1.0f-t)*sseg->v[1]->strandco + t*sseg->v[2]->strandco; } - set_afgeleide_four_ipo(t, data, type); + key_curve_tangent_weights(t, data, type); spoint->dtco[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0]; spoint->dtco[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1]; spoint->dtco[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2]; -- cgit v1.2.3 From ace94617c73651e78a8d65cbca83400f867a961e Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Wed, 9 Sep 2009 18:18:09 +0000 Subject: 2.5 MSVC projectfiles * small maintenance for split files in editors/object --- projectfiles_vc9/blender/editors/ED_editors.vcproj | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index db0b851fd74..5a6519d3d35 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -1075,29 +1075,33 @@ Name="object" > + + @@ -1107,11 +1111,23 @@ > + + + + + + -- cgit v1.2.3 From 8e2d86169599d652170ebe8b2564650f00f70077 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 9 Sep 2009 18:39:40 +0000 Subject: Smoke: * Enable cache for high res + new preview * Bugfix for smoke banding (in cooperation with N_T) Hint: Work-in-progress regarding collision objects so can be broken, didn't test Hint2: jahka enabled a general particle panel but * bake button doesn't work * step is not supported for cloth * several other things there ;) --- intern/smoke/extern/smoke_API.h | 6 +- intern/smoke/intern/FLUID_3D.cpp | 120 +-- intern/smoke/intern/FLUID_3D_STATIC.cpp | 158 ++-- intern/smoke/intern/WTURBULENCE.cpp | 628 +++++++------- intern/smoke/intern/WTURBULENCE.h | 37 +- intern/smoke/intern/smoke_API.cpp | 13 +- release/ui/buttons_physics_smoke.py | 82 +- source/blender/blenkernel/BKE_pointcache.h | 1 + source/blender/blenkernel/BKE_smoke.h | 4 +- source/blender/blenkernel/intern/pointcache.c | 73 +- source/blender/blenkernel/intern/smoke.c | 956 +++++++++++---------- source/blender/blenloader/intern/readfile.c | 4 +- source/blender/editors/space_view3d/drawobject.c | 59 +- source/blender/editors/space_view3d/drawvolume.c | 48 +- .../blender/editors/space_view3d/view3d_intern.h | 2 +- source/blender/gpu/CMakeLists.txt | 2 +- source/blender/gpu/GPU_draw.h | 2 +- source/blender/gpu/intern/gpu_draw.c | 16 +- source/blender/gpu/intern/gpu_extensions.c | 12 +- source/blender/makesdna/DNA_smoke_types.h | 28 +- source/blender/makesrna/intern/rna_smoke.c | 90 +- 21 files changed, 1184 insertions(+), 1157 deletions(-) diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h index 1a3edce2344..5607df70cf3 100644 --- a/intern/smoke/extern/smoke_API.h +++ b/intern/smoke/extern/smoke_API.h @@ -63,11 +63,11 @@ void smoke_turbulence_free(struct WTURBULENCE *wt); void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid); float *smoke_turbulence_get_density(struct WTURBULENCE *wt); -void smoke_turbulence_get_res(struct WTURBULENCE *wt, unsigned int *res); +void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res); void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type); -void smoke_turbulence_initBlenderRNA(struct WTURBULENCE *wt, float *strength); +void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength); -void smoke_turbulence_dissolve(struct WTURBULENCE *wt, int speed, int log); +void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log); // export void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw); diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 89dd893198b..7574a0ec16e 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -27,9 +27,9 @@ #include // boundary conditions of the fluid domain -#define DOMAIN_BC_FRONT 1 -#define DOMAIN_BC_TOP 0 -#define DOMAIN_BC_LEFT 1 +#define DOMAIN_BC_FRONT 0 // z +#define DOMAIN_BC_TOP 1 // y +#define DOMAIN_BC_LEFT 1 // x #define DOMAIN_BC_BACK DOMAIN_BC_FRONT #define DOMAIN_BC_BOTTOM DOMAIN_BC_TOP #define DOMAIN_BC_RIGHT DOMAIN_BC_LEFT @@ -111,47 +111,42 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) : } // set side obstacles - size_t index; - for (int y = 0; y < _yRes; y++) // z - for (int x = 0; x < _xRes; x++) - { - // front slab - index = x + y * _xRes; - if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1; + int index; + for (int y = 0; y < _yRes; y++) + for (int x = 0; x < _xRes; x++) + { + // front slab + index = x + y * _xRes; + if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1; - // back slab - index += _totalCells - _slabSize; - if(DOMAIN_BC_TOP==1) _obstacles[index] = 1; - } - for (int z = 0; z < _zRes; z++) // y - for (int x = 0; x < _xRes; x++) - { - // bottom slab - index = x + z * _slabSize; - if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1; + // back slab + index += _totalCells - _slabSize; + if(DOMAIN_BC_BACK==1) _obstacles[index] = 1; + } - // top slab - index += _slabSize - _xRes; - if(DOMAIN_BC_BACK==1) _obstacles[index] = 1; - } - for (int z = 0; z < _zRes; z++) // x - for (int y = 0; y < _yRes; y++) - { - // left slab - index = y * _xRes + z * _slabSize; - if(DOMAIN_BC_LEFT==1) _obstacles[index] = 1; + for (int z = 0; z < _zRes; z++) + for (int x = 0; x < _xRes; x++) + { + // bottom slab + index = x + z * _slabSize; + if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1; - // right slab - index += _xRes - 1; - if(DOMAIN_BC_RIGHT==1) _obstacles[index] = 1; - } + // top slab + index += _slabSize - _xRes; + if(DOMAIN_BC_TOP==1) _obstacles[index] = 1; + } - /* - SPHERE *obsSphere = NULL; - obsSphere = new SPHERE(0.375,0.5,0.375, 0.1); // for 4 to 3 domain - addObstacle(obsSphere); - delete obsSphere; - */ + for (int z = 0; z < _zRes; z++) + for (int y = 0; y < _yRes; y++) + { + // left slab + index = y * _xRes + z * _slabSize; + if(DOMAIN_BC_LEFT==1) _obstacles[index] = 1; + + // right slab + index += _xRes - 1; + if(DOMAIN_BC_RIGHT==1) _obstacles[index] = 1; + } } FLUID_3D::~FLUID_3D() @@ -191,7 +186,7 @@ void FLUID_3D::step() for (int i = 0; i < _totalCells; i++) { _xForce[i] = _yForce[i] = _zForce[i] = 0.0f; - _obstacles[i] &= ~2; + // _obstacles[i] &= ~2; } wipeBoundaries(); @@ -232,7 +227,8 @@ void FLUID_3D::step() _totalTime += _dt; _totalSteps++; - memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes); + // todo xxx dg: only clear obstacles, not boundaries + // memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes); } ////////////////////////////////////////////////////////////////////// @@ -270,7 +266,7 @@ void FLUID_3D::artificialDamping(float* field) { ////////////////////////////////////////////////////////////////////// void FLUID_3D::copyBorderAll(float* field) { - size_t index; + int index; for (int y = 0; y < _yRes; y++) for (int x = 0; x < _xRes; x++) { @@ -350,13 +346,13 @@ void FLUID_3D::project() // copy out the boundaries if(DOMAIN_BC_LEFT == 0) setNeumannX(_xVelocity, _res); - else setZeroX(_xVelocity, _res); + else setZeroX(_xVelocity, _res); - if(DOMAIN_BC_TOP == 0) setNeumannZ(_zVelocity, _res); - else setZeroZ(_zVelocity, _res); + if(DOMAIN_BC_TOP == 0) setNeumannY(_yVelocity, _res); + else setZeroY(_yVelocity, _res); - if(DOMAIN_BC_FRONT == 0) setNeumannY(_yVelocity, _res); - else setZeroY(_yVelocity, _res); + if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res); + else setZeroZ(_zVelocity, _res); // calculate divergence index = _slabSize + _xRes + 1; @@ -400,12 +396,16 @@ void FLUID_3D::project() for (y = 1; y < _yRes - 1; y++, index += 2) for (x = 1; x < _xRes - 1; x++, index++) { - if(!_obstacles[index]) + // if(!_obstacles[index]) { _xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx; _yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx; _zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx; - } + }/* + else + { + _xVelocity[index] = _yVelocity[index] = _zVelocity[index] = 0.0f; + }*/ } if (_pressure) delete[] _pressure; @@ -669,13 +669,13 @@ void FLUID_3D::advectMacCormack() Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res); - else setZeroX(_xVelocity, res); + else setZeroX(_xVelocity, res); - if(DOMAIN_BC_TOP == 0) copyBorderZ(_zVelocity, res); - else setZeroZ(_zVelocity, res); + if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res); + else setZeroY(_yVelocity, res); - if(DOMAIN_BC_FRONT == 0) copyBorderY(_yVelocity, res); - else setZeroY(_yVelocity, res); + if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res); + else setZeroZ(_zVelocity, res); SWAP_POINTERS(_xVelocity, _xVelocityOld); SWAP_POINTERS(_yVelocity, _yVelocityOld); @@ -698,13 +698,13 @@ void FLUID_3D::advectMacCormack() advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, _obstacles); if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res); - else setZeroX(_xVelocity, res); + else setZeroX(_xVelocity, res); - if(DOMAIN_BC_TOP == 0) copyBorderZ(_zVelocity, res); - else setZeroZ(_zVelocity, res); + if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res); + else setZeroY(_yVelocity, res); - if(DOMAIN_BC_FRONT == 0) copyBorderY(_yVelocity, res); - else setZeroY(_yVelocity, res); + if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res); + else setZeroZ(_zVelocity, res); setZeroBorder(_density, res); setZeroBorder(_heat, res); diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index 4474129beea..4909c071c3d 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -80,7 +80,7 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value) void FLUID_3D::setNeumannX(float* field, Vec3Int res) { const int slabSize = res[0] * res[1]; - size_t index; + int index; for (int z = 0; z < res[2]; z++) for (int y = 0; y < res[1]; y++) { @@ -92,6 +92,18 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res) index += res[0] - 1; field[index] = field[index - 2]; } + + // fix, force top slab to only allow outwards flux + for (int y = 0; y < res[1]; y++) + for (int z = 0; z < res[2]; z++) + { + // top slab + int index = y * res[0] + z * slabSize; + index += res[0] - 1; + if(field[index]<0.) field[index] = 0.; + index -= 1; + if(field[index]<0.) field[index] = 0.; + } } ////////////////////////////////////////////////////////////////////// @@ -100,18 +112,31 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res) void FLUID_3D::setNeumannY(float* field, Vec3Int res) { const int slabSize = res[0] * res[1]; - size_t index; + int index; for (int z = 0; z < res[2]; z++) for (int x = 0; x < res[0]; x++) { - // front slab + // bottom slab index = x + z * slabSize; field[index] = field[index + 2 * res[0]]; - // back slab + // top slab index += slabSize - res[0]; field[index] = field[index - 2 * res[0]]; } + + // fix, force top slab to only allow outwards flux + for (int z = 0; z < res[2]; z++) + for (int x = 0; x < res[0]; x++) + { + // top slab + int index = x + z * slabSize; + index += slabSize - res[0]; + if(field[index]<0.) field[index] = 0.; + index -= res[0]; + if(field[index]<0.) field[index] = 0.; + } + } ////////////////////////////////////////////////////////////////////// @@ -121,15 +146,15 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res) { const int slabSize = res[0] * res[1]; const int totalCells = res[0] * res[1] * res[2]; - size_t index; + int index; for (int y = 0; y < res[1]; y++) for (int x = 0; x < res[0]; x++) { - // bottom slab + // front slab index = x + y * res[0]; field[index] = field[index + 2 * slabSize]; - // top slab + // back slab index += totalCells - slabSize; field[index] = field[index - 2 * slabSize]; } @@ -139,11 +164,11 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res) for (int x = 0; x < res[0]; x++) { // top slab - index = x + y * res[0]; + int index = x + y * res[0]; index += totalCells - slabSize; - if(field[index]<0.) field[index] = 0.0f; + if(field[index]<0.) field[index] = 0.; index -= slabSize; - if(field[index]<0.) field[index] = 0.0f; + if(field[index]<0.) field[index] = 0.; } } @@ -231,13 +256,14 @@ void FLUID_3D::copyBorderX(float* field, Vec3Int res) void FLUID_3D::copyBorderY(float* field, Vec3Int res) { const int slabSize = res[0] * res[1]; + const int totalCells = res[0] * res[1] * res[2]; int index; for (int z = 0; z < res[2]; z++) for (int x = 0; x < res[0]; x++) { // bottom slab index = x + z * slabSize; - field[index] = field[index + res[0]]; + field[index] = field[index + res[0]]; // top slab index += slabSize - res[0]; field[index] = field[index - res[0]]; @@ -253,7 +279,7 @@ void FLUID_3D::copyBorderZ(float* field, Vec3Int res) { // front slab index = x + y * res[0]; - field[index] = field[index + slabSize]; + field[index] = field[index + slabSize]; // back slab index += totalCells - slabSize; field[index] = field[index - slabSize]; @@ -269,18 +295,21 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const const int xres = res[0]; const int yres = res[1]; const int zres = res[2]; + static int hits = 0; + static int total = 0; const int slabSize = res[0] * res[1]; // scale dt up to grid resolution -#if PARALLEL==1 -#pragma omp parallel for schedule(static) +#if PARALLEL==1 && !_WIN32 +#pragma omp parallel +#pragma omp for schedule(static) #endif for (int z = 0; z < zres; z++) for (int y = 0; y < yres; y++) for (int x = 0; x < xres; x++) { const int index = x + y * xres + z * xres*yres; - + // backtrace float xTrace = x - dt * velx[index]; float yTrace = y - dt * vely[index]; @@ -337,8 +366,8 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const // // comments are the pseudocode from selle's paper ////////////////////////////////////////////////////////////////////// -void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, - float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles) +void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity, + float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles) { float* phiHatN = temp1; float* phiHatN1 = temp2; @@ -359,7 +388,7 @@ void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, con advectFieldSemiLagrange( -1.0*dt, xVelocity, yVelocity, zVelocity, phiHatN1, phiHatN, res); // phiN1 = phiHatN1 + (phiN - phiHatN) / 2 - const int border = 0; + const int border = 0; for (int z = border; z < sz-border; z++) for (int y = border; y < sy-border; y++) for (int x = border; x < sx-border; x++) { @@ -376,7 +405,7 @@ void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, con // if the error estimate was bad, revert to first order clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN1); -} +} ////////////////////////////////////////////////////////////////////// @@ -454,17 +483,18 @@ void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely } ////////////////////////////////////////////////////////////////////// -// Reverts any backtraces that go into boundaries back to first +// Reverts any backtraces that go into boundaries back to first // order -- in this case the error correction term was totally // incorrect ////////////////////////////////////////////////////////////////////// -void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz, - float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection) +void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz, + float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection) { const int sx= res[0]; const int sy= res[1]; const int sz= res[2]; const int slabSize = res[0] * res[1]; + for (int z = 1; z < sz-1; z++) for (int y = 1; y < sy-1; y++) for (int x = 1; x < sx-1; x++) @@ -479,7 +509,7 @@ void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* float zTrace = z - dt * velz[index]; // see if it goes outside the boundaries - bool hasObstacle = + bool hasObstacle = (zTrace < 1.0f) || (zTrace > sz - 2.0f) || (yTrace < 1.0f) || (yTrace > sy - 2.0f) || (xTrace < 1.0f) || (xTrace > sx - 2.0f) || @@ -515,7 +545,7 @@ void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* int z0 = (int)zBackward; int z1 = z0 + 1; if(obstacles && !hasObstacle) { - hasObstacle = hasObstacle || + hasObstacle = hasObstacle || obstacles[x0 + y0 * sx + z0*slabSize] || obstacles[x0 + y1 * sx + z0*slabSize] || obstacles[x1 + y0 * sx + z0*slabSize] || @@ -535,7 +565,7 @@ void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* z0 = (int)zTrace; z1 = z0 + 1; if(obstacles && !hasObstacle) { - hasObstacle = hasObstacle || + hasObstacle = hasObstacle || obstacles[x0 + y0 * sx + z0*slabSize] || obstacles[x0 + y1 * sx + z0*slabSize] || obstacles[x1 + y0 * sx + z0*slabSize] || @@ -577,84 +607,8 @@ void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* u1 * (s0 * (t0 * oldField[i001] + t1 * oldField[i011]) + s1 * (t0 * oldField[i101] + - t1 * oldField[i111])); + t1 * oldField[i111])); } } // xyz } -////////////////////////////////////////////////////////////////////// -// image output -////////////////////////////////////////////////////////////////////// -/* -void FLUID_3D::writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale) { - writeProjectedIntern(field, res, 0,1, prefix, picCnt, scale); -} -void FLUID_3D::writeImageSliceYZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale) { - writeProjectedIntern(field, res, 1,2, prefix, picCnt, scale); -} -void FLUID_3D::writeImageSliceXZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale) { - writeProjectedIntern(field, res, 0,2, prefix, picCnt, scale); -} -*/ - -////////////////////////////////////////////////////////////////////// -// Helper function for projecting densities along a dimension -////////////////////////////////////////////////////////////////////// -/* -static int getOtherDir(int dir1, int dir2) { - switch(dir1) { - case 0: - switch(dir2) { - case 1: return 2; - case 2: return 1; } - break; - case 1: - switch(dir2) { - case 0: return 2; - case 2: return 0; } - break; - case 2: - switch(dir2) { - case 0: return 1; - case 1: return 0; } - break; - default: - return 0; - } - return 0; -} -*/ - -////////////////////////////////////////////////////////////////////// -// average densities along third spatial direction -////////////////////////////////////////////////////////////////////// -/* -void FLUID_3D::writeProjectedIntern(const float *field, Vec3Int res, - int dir1, int dir2, string prefix, int picCnt, float scale) { - const int nitems = res[dir1]*res[dir2]; - const int otherDir = getOtherDir(dir1,dir2); - float *buf = new float[nitems]; - Vec3Int min = Vec3Int(0); - Vec3Int max = res; - - min[otherDir] = 0; - max[otherDir] = res[otherDir]; - float div = 1./(float)MIN3V(res); // normalize for shorter sides, old: res[otherDir]; - div *= 4.; //slightly increase contrast - for(int i=0; i 0) { - _energy[index] = sum / valid; + _energy[index] = sum / (float)valid; obstacles[index] = MARCHED; } } @@ -516,9 +500,9 @@ void WTURBULENCE::computeEnergy(float* xvel, float* yvel, float* zvel, unsigned Vec3 WTURBULENCE::WVelocity(Vec3 orgPos) { // arbitrarily offset evaluation points - const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2,0,0); - const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2,0); - const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2); + const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2.0,0,0); + const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2.0,0); + const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2.0); const float f1y = WNoiseDy(p1, _noiseTile); const float f1z = WNoiseDz(p1, _noiseTile); @@ -542,9 +526,9 @@ Vec3 WTURBULENCE::WVelocity(Vec3 orgPos) Vec3 WTURBULENCE::WVelocityWithJacobian(Vec3 orgPos, float* xUnwarped, float* yUnwarped, float* zUnwarped) { // arbitrarily offset evaluation points - const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2,0,0); - const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2,0); - const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2); + const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2.0,0,0); + const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2.0,0); + const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2.0); Vec3 final; final[0] = WNoiseDx(p1, _noiseTile); @@ -575,44 +559,40 @@ Vec3 WTURBULENCE::WVelocityWithJacobian(Vec3 orgPos, float* xUnwarped, float* yU return ret; } + ////////////////////////////////////////////////////////////////////// // perform an actual noise advection step ////////////////////////////////////////////////////////////////////// void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles) { - // big velocity macCormack fields - float* _bigUx; - float* _bigUy; - float* _bigUz; - - // temp arrays for BFECC and MacCormack - they have more convenient - // names in the actual implementations - float* _tempBig1; - float* _tempBig2; - - // allocate high resolution velocity field. Note that this is only - // necessary because we use MacCormack advection. For semi-Lagrangian - // advection, these arrays are not necessary. - _tempBig1 = new float[_totalCellsBig]; - _tempBig2 = new float[_totalCellsBig]; - - // enlarge timestep to match grid - const float dt = dtOrg * _amplify; - const float invAmp = 1.0f / _amplify; - - _bigUx = new float[_totalCellsBig]; - _bigUy = new float[_totalCellsBig]; - _bigUz = new float[_totalCellsBig]; - - // prepare textures - advectTextureCoordinates(dtOrg, xvel,yvel,zvel, _tempBig1, _tempBig2); + // enlarge timestep to match grid + const float dt = dtOrg * _amplify; + const float invAmp = 1.0f / _amplify; + float *tempBig1 = new float[_totalCellsBig]; + float *tempBig2 = new float[_totalCellsBig]; + float *bigUx = new float[_totalCellsBig]; + float *bigUy = new float[_totalCellsBig]; + float *bigUz = new float[_totalCellsBig]; + float *_energy = new float[_totalCellsSm]; + float *highFreqEnergy = new float[_totalCellsSm]; + float *eigMin = new float[_totalCellsSm]; + float *eigMax = new float[_totalCellsSm]; + + memset(tempBig1, 0, sizeof(float)*_totalCellsBig); + memset(tempBig2, 0, sizeof(float)*_totalCellsBig); + memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm); + memset(eigMin, 0, sizeof(float)*_totalCellsSm); + memset(eigMax, 0, sizeof(float)*_totalCellsSm); + + // prepare textures + advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2); // compute eigenvalues of the texture coordinates - computeEigenvalues(); + computeEigenvalues(eigMin, eigMax); // do wavelet decomposition of energy - computeEnergy(xvel, yvel, zvel, obstacles); - decomposeEnergy(); + computeEnergy(_energy, xvel, yvel, zvel, obstacles); + decomposeEnergy(_energy, highFreqEnergy); // zero out coefficients inside of the obstacle for (int x = 0; x < _totalCellsSm; x++) @@ -647,7 +627,7 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, // retrieve wavelet energy at highest frequency float energy = INTERPOLATE::lerp3d( - _highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm); + highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm); // base amplitude for octave 0 float coefficient = sqrtf(2.0f * fabs(energy)); @@ -656,8 +636,8 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, // add noise to velocity, but only if the turbulence is // sufficiently undeformed, and the energy is large enough // to make a difference - const bool addNoise = _eigMax[indexSmall] < 2. && - _eigMin[indexSmall] > 0.5; + const bool addNoise = eigMax[indexSmall] < 2. && + eigMin[indexSmall] > 0.5; if (addNoise && amplitude > _cullingThreshold) { // base amplitude for octave 0 float amplitudeScaled = amplitude; @@ -679,21 +659,21 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, // If you wanted to save memory, you would instead perform a // semi-Lagrangian backtrace for the current grid cell here. Then // you could just throw the velocity away. - _bigUx[index] = vel[0]; - _bigUy[index] = vel[1]; - _bigUz[index] = vel[2]; + bigUx[index] = vel[0]; + bigUy[index] = vel[1]; + bigUz[index] = vel[2]; // compute the velocity magnitude for substepping later - const float velMag = _bigUx[index] * _bigUx[index] + - _bigUy[index] * _bigUy[index] + - _bigUz[index] * _bigUz[index]; + const float velMag = bigUx[index] * bigUx[index] + + bigUy[index] * bigUy[index] + + bigUz[index] * bigUz[index]; if (velMag > maxVelocity) maxVelocity = velMag; // zero out velocity inside obstacles float obsCheck = INTERPOLATE::lerp3dToFloat( obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm); if (obsCheck > 0.95) - _bigUx[index] = _bigUy[index] = _bigUz[index] = 0.; + bigUx[index] = bigUy[index] = bigUz[index] = 0.; } // prepare density for an advection @@ -701,24 +681,23 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, // based on the maximum velocity present, see if we need to substep, // but cap the maximum number of substeps to 5 - const int maxSubSteps = 25; - const int maxVel = 5; + const int maxSubSteps = 5; maxVelocity = sqrt(maxVelocity) * dt; - int totalSubsteps = (int)(maxVelocity / (float)maxVel); + int totalSubsteps = (int)(maxVelocity / (float)maxSubSteps); totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps; totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; const float dtSubdiv = dt / (float)totalSubsteps; // set boundaries of big velocity grid - FLUID_3D::setZeroX(_bigUx, _resBig); - FLUID_3D::setZeroY(_bigUy, _resBig); - FLUID_3D::setZeroZ(_bigUz, _resBig); + FLUID_3D::setZeroX(bigUx, _resBig); + FLUID_3D::setZeroY(bigUy, _resBig); + FLUID_3D::setZeroZ(bigUz, _resBig); // do the MacCormack advection, with substepping if necessary for(int substep = 0; substep < totalSubsteps; substep++) { - FLUID_3D::advectFieldMacCormack(dtSubdiv, _bigUx, _bigUy, _bigUz, - _densityBigOld, _densityBig, _tempBig1, _tempBig2, _resBig, NULL); + FLUID_3D::advectFieldMacCormack(dtSubdiv, bigUx, bigUy, bigUz, + _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL); if (substep < totalSubsteps - 1) SWAP_POINTERS(_densityBig, _densityBigOld); @@ -730,25 +709,21 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, // reset texture coordinates now in preparation for next timestep // Shouldn't do this before generating the noise because then the // eigenvalues stored do not reflect the underlying texture coordinates - resetTextureCoordinates(); + resetTextureCoordinates(eigMin, eigMax); - // output files - /* - string prefix = string("./amplified.preview/density_bigxy_"); - FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f); - //string df3Prefix = string("./df3/density_big_"); - //IMAGE::dumpDF3(_totalStepsBig, df3Prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); - string pbrtPrefix = string("./pbrt/density_big_"); - IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); - */ - _totalStepsBig++; + delete[] tempBig1; + delete[] tempBig2; + delete[] bigUx; + delete[] bigUy; + delete[] bigUz; + delete[] _energy; + delete[] highFreqEnergy; - delete[] _bigUx; - delete[] _bigUy; - delete[] _bigUz; + delete[] eigMin; + delete[] eigMax; + - delete[] _tempBig1; - delete[] _tempBig2; + _totalStepsBig++; } ////////////////////////////////////////////////////////////////////// @@ -757,257 +732,258 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, ////////////////////////////////////////////////////////////////////// void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles) { - // big velocity macCormack fields - float* _bigUx; - float* _bigUy; - float* _bigUz; - - // temp arrays for BFECC and MacCormack - they have more convenient - // names in the actual implementations - float* _tempBig1; - float* _tempBig2; - - // allocate high resolution velocity field. Note that this is only - // necessary because we use MacCormack advection. For semi-Lagrangian - // advection, these arrays are not necessary. - _tempBig1 = new float[_totalCellsBig]; - _tempBig2 = new float[_totalCellsBig]; - // enlarge timestep to match grid const float dt = dtOrg * _amplify; const float invAmp = 1.0f / _amplify; - - _bigUx = new float[_totalCellsBig]; - _bigUy = new float[_totalCellsBig]; - _bigUz = new float[_totalCellsBig]; + float *tempBig1 = new float[_totalCellsBig]; + float *tempBig2 = new float[_totalCellsBig]; + float *bigUx = new float[_totalCellsBig]; + float *bigUy = new float[_totalCellsBig]; + float *bigUz = new float[_totalCellsBig]; + float *_energy = new float[_totalCellsSm]; + float *highFreqEnergy = new float[_totalCellsSm]; + float *eigMin = new float[_totalCellsSm]; + float *eigMax = new float[_totalCellsSm]; + + memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm); + memset(eigMin, 0, sizeof(float)*_totalCellsSm); + memset(eigMax, 0, sizeof(float)*_totalCellsSm); // prepare textures - advectTextureCoordinates(dtOrg, xvel,yvel,zvel, _tempBig1, _tempBig2); + advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2); // do wavelet decomposition of energy - computeEnergy(xvel, yvel, zvel, obstacles); - decomposeEnergy(); + computeEnergy(_energy, xvel, yvel, zvel, obstacles); - // zero out coefficients inside of the obstacle for (int x = 0; x < _totalCellsSm; x++) if (obstacles[x]) _energy[x] = 0.f; - // parallel region setup - float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. }; - - #if PARALLEL==1 - #pragma omp parallel - #endif - { float maxVelMag1 = 0.; - #if PARALLEL==1 - const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */ - #endif - - // vector noise main loop - #if PARALLEL==1 - #pragma omp for schedule(static) - #endif - for (int zSmall = 0; zSmall < _zResSm; zSmall++) - for (int ySmall = 0; ySmall < _yResSm; ySmall++) - for (int xSmall = 0; xSmall < _xResSm; xSmall++) - { - const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm; - - // compute jacobian - float jacobian[3][3] = { - { minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } , - { minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } , - { minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) } - }; - - // get LU factorization of texture jacobian and apply - // it to unit vectors - JAMA::LU LU = computeLU3x3(jacobian); - float xUnwarped[] = {1.0f, 0.0f, 0.0f}; - float yUnwarped[] = {0.0f, 1.0f, 0.0f}; - float zUnwarped[] = {0.0f, 0.0f, 1.0f}; - float xWarped[] = {1.0f, 0.0f, 0.0f}; - float yWarped[] = {0.0f, 1.0f, 0.0f}; - float zWarped[] = {0.0f, 0.0f, 1.0f}; - bool nonSingular = LU.isNonsingular(); - - #if 0 - // UNUSED - float eigMax = 10.0f; - float eigMin = 0.1f; - #endif + decomposeEnergy(_energy, highFreqEnergy); - if (nonSingular) - { - solveLU3x3(LU, xUnwarped, xWarped); - solveLU3x3(LU, yUnwarped, yWarped); - solveLU3x3(LU, zUnwarped, zWarped); - - // compute the eigenvalues while we have the Jacobian available - Vec3 eigenvalues = Vec3(1.); - computeEigenvalues3x3( &eigenvalues[0], jacobian); - _eigMax[indexSmall] = MAX3V(eigenvalues); - _eigMin[indexSmall] = MIN3V(eigenvalues); - } + // zero out coefficients inside of the obstacle + for (int x = 0; x < _totalCellsSm; x++) + if (obstacles[x]) highFreqEnergy[x] = 0.f; - // make sure to skip one on the beginning and end - int xStart = (xSmall == 0) ? 1 : 0; - int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify; - int yStart = (ySmall == 0) ? 1 : 0; - int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify; - int zStart = (zSmall == 0) ? 1 : 0; - int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify; - - for (int zBig = zStart; zBig < zEnd; zBig++) - for (int yBig = yStart; yBig < yEnd; yBig++) - for (int xBig = xStart; xBig < xEnd; xBig++) - { - const int x = xSmall * _amplify + xBig; - const int y = ySmall * _amplify + yBig; - const int z = zSmall * _amplify + zBig; - - // get unit position for both fine and coarse grid - const Vec3 pos = Vec3(x,y,z); - const Vec3 posSm = pos * invAmp; - - // get grid index for both fine and coarse grid - const int index = x + y *_xResBig + z *_slabSizeBig; - - // get a linearly interpolated velocity and texcoords - // from the coarse grid - Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel, - posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); - Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW, - posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); - - // multiply the texture coordinate by _resSm so that turbulence - // synthesis begins at the first octave that the coarse grid - // cannot capture - Vec3 texCoord = Vec3(uvw[0] * _resSm[0], - uvw[1] * _resSm[1], - uvw[2] * _resSm[2]); - - // retrieve wavelet energy at highest frequency - float energy = INTERPOLATE::lerp3d( - _highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm); - - // base amplitude for octave 0 - float coefficient = sqrtf(2.0f * fabs(energy)); - const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence; - - // add noise to velocity, but only if the turbulence is - // sufficiently undeformed, and the energy is large enough - // to make a difference - const bool addNoise = _eigMax[indexSmall] < 2. && - _eigMin[indexSmall] > 0.5; - - if (addNoise && amplitude > _cullingThreshold) { - // base amplitude for octave 0 - float amplitudeScaled = amplitude; - - for (int octave = 0; octave < _octaves; octave++) - { - // multiply the vector noise times the maximum allowed - // noise amplitude at this octave, and add it to the total - vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled; - - // scale coefficient for next octave - amplitudeScaled *= persistence; - texCoord *= 2.0f; - } - } - - // Store velocity + turbulence in big grid for maccormack step - // - // If you wanted to save memory, you would instead perform a - // semi-Lagrangian backtrace for the current grid cell here. Then - // you could just throw the velocity away. - _bigUx[index] = vel[0]; - _bigUy[index] = vel[1]; - _bigUz[index] = vel[2]; - - // compute the velocity magnitude for substepping later - const float velMag = _bigUx[index] * _bigUx[index] + - _bigUy[index] * _bigUy[index] + - _bigUz[index] * _bigUz[index]; - if (velMag > maxVelMag1) maxVelMag1 = velMag; - - // zero out velocity inside obstacles - float obsCheck = INTERPOLATE::lerp3dToFloat( - obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm); - - if (obsCheck > 0.95) - _bigUx[index] = _bigUy[index] = _bigUz[index] = 0.; - } // xyz - - #if PARALLEL==1 - maxVelMagThreads[id] = maxVelMag1; - #else - maxVelMagThreads[0] = maxVelMag1; - #endif - } - } // omp - - // compute maximum over threads - float maxVelMag = maxVelMagThreads[0]; - #if PARALLEL==1 - for (int i = 1; i < 8; i++) - if (maxVelMag < maxVelMagThreads[i]) - maxVelMag = maxVelMagThreads[i]; - #endif - - // prepare density for an advection - SWAP_POINTERS(_densityBig, _densityBigOld); - - // based on the maximum velocity present, see if we need to substep, - // but cap the maximum number of substeps to 5 - const int maxSubSteps = 25; - const int maxVel = 5; - maxVelMag = sqrt(maxVelMag) * dt; - int totalSubsteps = (int)(maxVelMag / (float)maxVel); - totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps; - // printf("totalSubsteps: %d\n", totalSubsteps); - totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; - const float dtSubdiv = dt / (float)totalSubsteps; - - // set boundaries of big velocity grid - FLUID_3D::setZeroX(_bigUx, _resBig); - FLUID_3D::setZeroY(_bigUy, _resBig); - FLUID_3D::setZeroZ(_bigUz, _resBig); - - // do the MacCormack advection, with substepping if necessary - for(int substep = 0; substep < totalSubsteps; substep++) - { - FLUID_3D::advectFieldMacCormack(dtSubdiv, _bigUx, _bigUy, _bigUz, - _densityBigOld, _densityBig, _tempBig1, _tempBig2, _resBig, NULL); + Vec3Int ressm(_xResSm, _yResSm, _zResSm); + FLUID_3D::setNeumannX(highFreqEnergy, ressm); + FLUID_3D::setNeumannY(highFreqEnergy, ressm); + FLUID_3D::setNeumannZ(highFreqEnergy, ressm); + + // parallel region setup + float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. }; +#if PARALLEL==1 +#pragma omp parallel +#endif + { float maxVelMag1 = 0.; +#if PARALLEL==1 + const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */ +#endif + + // vector noise main loop +#if PARALLEL==1 +#pragma omp for schedule(static) +#endif + for (int zSmall = 0; zSmall < _zResSm; zSmall++) + for (int ySmall = 0; ySmall < _yResSm; ySmall++) + for (int xSmall = 0; xSmall < _xResSm; xSmall++) + { + const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm; + + // compute jacobian + float jacobian[3][3] = { + { minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } , + { minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } , + { minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) } + }; + + // get LU factorization of texture jacobian and apply + // it to unit vectors + JAMA::LU LU = computeLU3x3(jacobian); + float xUnwarped[] = {1.0f, 0.0f, 0.0f}; + float yUnwarped[] = {0.0f, 1.0f, 0.0f}; + float zUnwarped[] = {0.0f, 0.0f, 1.0f}; + float xWarped[] = {1.0f, 0.0f, 0.0f}; + float yWarped[] = {0.0f, 1.0f, 0.0f}; + float zWarped[] = {0.0f, 0.0f, 1.0f}; + bool nonSingular = LU.isNonsingular(); +#if 0 + // UNUSED + float eigMax = 10.0f; + float eigMin = 0.1f; +#endif + if (nonSingular) + { + solveLU3x3(LU, xUnwarped, xWarped); + solveLU3x3(LU, yUnwarped, yWarped); + solveLU3x3(LU, zUnwarped, zWarped); + + // compute the eigenvalues while we have the Jacobian available + Vec3 eigenvalues = Vec3(1.); + computeEigenvalues3x3( &eigenvalues[0], jacobian); + eigMax[indexSmall] = MAX3V(eigenvalues); + eigMin[indexSmall] = MIN3V(eigenvalues); + } + + // make sure to skip one on the beginning and end + int xStart = (xSmall == 0) ? 1 : 0; + int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify; + int yStart = (ySmall == 0) ? 1 : 0; + int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify; + int zStart = (zSmall == 0) ? 1 : 0; + int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify; + + for (int zBig = zStart; zBig < zEnd; zBig++) + for (int yBig = yStart; yBig < yEnd; yBig++) + for (int xBig = xStart; xBig < xEnd; xBig++) + { + const int x = xSmall * _amplify + xBig; + const int y = ySmall * _amplify + yBig; + const int z = zSmall * _amplify + zBig; + + // get unit position for both fine and coarse grid + const Vec3 pos = Vec3(x,y,z); + const Vec3 posSm = pos * invAmp; + + // get grid index for both fine and coarse grid + const int index = x + y *_xResBig + z *_slabSizeBig; + + // get a linearly interpolated velocity and texcoords + // from the coarse grid + Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel, + posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); + Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW, + posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm); + + // multiply the texture coordinate by _resSm so that turbulence + // synthesis begins at the first octave that the coarse grid + // cannot capture + Vec3 texCoord = Vec3(uvw[0] * _resSm[0], + uvw[1] * _resSm[1], + uvw[2] * _resSm[2]); + + // retrieve wavelet energy at highest frequency + float energy = INTERPOLATE::lerp3d( + highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm); + + // base amplitude for octave 0 + float coefficient = sqrtf(2.0f * fabs(energy)); + const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence; + + // add noise to velocity, but only if the turbulence is + // sufficiently undeformed, and the energy is large enough + // to make a difference + const bool addNoise = eigMax[indexSmall] < 2. && + eigMin[indexSmall] > 0.5; + if (addNoise && amplitude > _cullingThreshold) { + // base amplitude for octave 0 + float amplitudeScaled = amplitude; - if (substep < totalSubsteps - 1) - SWAP_POINTERS(_densityBig, _densityBigOld); - } // substep + for (int octave = 0; octave < _octaves; octave++) + { + // multiply the vector noise times the maximum allowed + // noise amplitude at this octave, and add it to the total + vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled; - // wipe the density borders - FLUID_3D::setZeroBorder(_densityBig, _resBig); + // scale coefficient for next octave + amplitudeScaled *= persistence; + texCoord *= 2.0f; + } + } - // reset texture coordinates now in preparation for next timestep - // Shouldn't do this before generating the noise because then the - // eigenvalues stored do not reflect the underlying texture coordinates - resetTextureCoordinates(); + // Store velocity + turbulence in big grid for maccormack step + // + // If you wanted to save memory, you would instead perform a + // semi-Lagrangian backtrace for the current grid cell here. Then + // you could just throw the velocity away. + bigUx[index] = vel[0]; + bigUy[index] = vel[1]; + bigUz[index] = vel[2]; + + // compute the velocity magnitude for substepping later + const float velMag = bigUx[index] * bigUx[index] + + bigUy[index] * bigUy[index] + + bigUz[index] * bigUz[index]; + if (velMag > maxVelMag1) maxVelMag1 = velMag; + + // zero out velocity inside obstacles + float obsCheck = INTERPOLATE::lerp3dToFloat( + obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm); + if (obsCheck > 0.95) + bigUx[index] = bigUy[index] = bigUz[index] = 0.; + } // xyz - // output files - // string prefix = string("./amplified.preview/density_bigxy_"); - // FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f); - //string df3prefix = string("./df3/density_big_"); - //IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); - // string pbrtPrefix = string("./pbrt/density_big_"); - // IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); +#if PARALLEL==1 + maxVelMagThreads[id] = maxVelMag1; +#else + maxVelMagThreads[0] = maxVelMag1; +#endif + } + } // omp + + // compute maximum over threads + float maxVelMag = maxVelMagThreads[0]; +#if PARALLEL==1 + for (int i = 1; i < 8; i++) + if (maxVelMag < maxVelMagThreads[i]) + maxVelMag = maxVelMagThreads[i]; +#endif - _totalStepsBig++; + // prepare density for an advection + SWAP_POINTERS(_densityBig, _densityBigOld); - delete[] _bigUx; - delete[] _bigUy; - delete[] _bigUz; + // based on the maximum velocity present, see if we need to substep, + // but cap the maximum number of substeps to 5 + const int maxSubSteps = 25; + const int maxVel = 5; + maxVelMag = sqrt(maxVelMag) * dt; + int totalSubsteps = (int)(maxVelMag / (float)maxVel); + totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps; + // printf("totalSubsteps: %d\n", totalSubsteps); + totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; + const float dtSubdiv = dt / (float)totalSubsteps; - delete[] _tempBig1; - delete[] _tempBig2; + // set boundaries of big velocity grid + FLUID_3D::setZeroX(bigUx, _resBig); + FLUID_3D::setZeroY(bigUy, _resBig); + FLUID_3D::setZeroZ(bigUz, _resBig); + + // do the MacCormack advection, with substepping if necessary + for(int substep = 0; substep < totalSubsteps; substep++) + { + FLUID_3D::advectFieldMacCormack(dtSubdiv, bigUx, bigUy, bigUz, + _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL); + + if (substep < totalSubsteps - 1) + SWAP_POINTERS(_densityBig, _densityBigOld); + } // substep + + delete[] tempBig1; + delete[] tempBig2; + delete[] bigUx; + delete[] bigUy; + delete[] bigUz; + delete[] _energy; + delete[] highFreqEnergy; + + // wipe the density borders + FLUID_3D::setZeroBorder(_densityBig, _resBig); + + // reset texture coordinates now in preparation for next timestep + // Shouldn't do this before generating the noise because then the + // eigenvalues stored do not reflect the underlying texture coordinates + resetTextureCoordinates(eigMin, eigMax); + + delete[] eigMin; + delete[] eigMax; + + // output files + // string prefix = string("./amplified.preview/density_bigxy_"); + // FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f); + //string df3prefix = string("./df3/density_big_"); + //IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); + // string pbrtPrefix = string("./pbrt/density_big_"); + // IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]); + + _totalStepsBig++; } diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h index c21e002ad48..0aa978e9e52 100644 --- a/intern/smoke/intern/WTURBULENCE.h +++ b/intern/smoke/intern/WTURBULENCE.h @@ -49,10 +49,10 @@ class WTURBULENCE void stepTurbulenceFull(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles); // texcoord functions - void advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *_tempBig1, float *_tempBig2); - void resetTextureCoordinates(); + void advectTextureCoordinates(float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2); + void resetTextureCoordinates(float *_eigMin, float *_eigMax); - void computeEnergy(float* xvel, float* yvel, float* zvel, unsigned char *obstacles); + void computeEnergy(float *energy, float* xvel, float* yvel, float* zvel, unsigned char *obstacles); // evaluate wavelet noise function Vec3 WVelocity(Vec3 p); @@ -63,8 +63,6 @@ class WTURBULENCE inline float* getArrayTcU() { return _tcU; } inline float* getArrayTcV() { return _tcV; } inline float* getArrayTcW() { return _tcW; } - inline float* getArrayEigMin() { return _eigMin; } - inline float* getArrayEigMax() { return _eigMax; } inline Vec3Int getResSm() { return _resSm; } // small resolution inline Vec3Int getResBig() { return _resBig; } @@ -81,15 +79,15 @@ class WTURBULENCE // noise settings float _cullingThreshold; - float _noiseStrength; - float _noiseSizeScale; - bool _uvwAdvection; - bool _uvwReset; - float _noiseTimeanimSpeed; - int _dumpInterval; - int _noiseControlType; + // float _noiseStrength; + // float _noiseSizeScale; + // bool _uvwAdvection; + // bool _uvwReset; + // float _noiseTimeanimSpeed; + // int _dumpInterval; + // nt _noiseControlType; // debug, scale density for projections output images - float _outputScale; + // float _outputScale; // noise resolution int _xResBig; @@ -117,24 +115,15 @@ class WTURBULENCE float* _tcW; float* _tcTemp; - float* _eigMin; // no save -dg - float* _eigMax; // no save -dg - - // wavelet decomposition of velocity energies - float* _energy; // no save -dg - // noise data float* _noiseTile; //float* _noiseTileExt; // step counter int _totalStepsBig; - - // highest frequency component of wavelet decomposition - float* _highFreqEnergy; // no save -dg - void computeEigenvalues(); - void decomposeEnergy(); + void computeEigenvalues(float *_eigMin, float *_eigMax); + void decomposeEnergy(float *energy, float *_highFreqEnergy); }; #endif // WTURBULENCE_H diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index 5a016b51bbe..058831dddbb 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -137,7 +137,7 @@ extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) } } -extern "C" void smoke_turbulence_dissolve(WTURBULENCE *wt, int speed, int log) +extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) { float *density = wt->getDensityBig(); Vec3Int r = wt->getResBig(); @@ -172,7 +172,7 @@ extern "C" void smoke_turbulence_dissolve(WTURBULENCE *wt, int speed, int log) } } -extern "C" void smoke_turbulence_initBlenderRNA(WTURBULENCE *wt, float *strength) +extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) { wt->initBlenderRNA(strength); } @@ -241,13 +241,14 @@ extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt) return wt ? wt->getDensityBig() : NULL; } -extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, unsigned int *res) +extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) { if(wt) { - res[0] = wt->_resBig[0]; - res[1] = wt->_resBig[1]; - res[2] = wt->_resBig[2]; + Vec3Int r = wt->getResBig(); + res[0] = r[0]; + res[1] = r[1]; + res[2] = r[2]; } } diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py index c87f71bff42..83c1ffc2e9a 100644 --- a/release/ui/buttons_physics_smoke.py +++ b/release/ui/buttons_physics_smoke.py @@ -3,11 +3,6 @@ import bpy from buttons_particle import point_cache_ui -def smoke_panel_enabled_low(smd): - if smd.smoke_type == 'TYPE_DOMAIN': - return smd.domain.point_cache.baked==False - return True - class PhysicButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -45,8 +40,6 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel): split.itemL() if md: - - # layout.enabled = smoke_panel_enabled(md) layout.itemR(md, "smoke_type", expand=True) if md.smoke_type == 'TYPE_DOMAIN': @@ -66,7 +59,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel): col.itemR(domain, "dissolve_smoke", text="Dissolve") sub = col.column() sub.active = domain.dissolve_smoke - sub.itemR(domain, "dissolve_speed", text="Speed") + sub.itemR(domain, "dissolve_speed", text="Time") sub.itemR(domain, "dissolve_smoke_log", text="Slow") elif md.smoke_type == 'TYPE_FLOW': @@ -90,14 +83,17 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel): #elif md.smoke_type == 'TYPE_COLL': # layout.itemS() - + class PHYSICS_PT_smoke_groups(PhysicButtonsPanel): __label__ = "Smoke Groups" __default_closed__ = True def poll(self, context): md = context.smoke - return md and (md.smoke_type == 'TYPE_DOMAIN') + if md: + return (md.smoke_type == 'TYPE_DOMAIN') + + return False def draw(self, context): layout = self.layout @@ -116,7 +112,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel): col = split.column() col.itemL(text="Collision Group:") col.itemR(group, "coll_group", text="") - + class PHYSICS_PT_smoke_cache(PhysicButtonsPanel): __label__ = "Smoke Cache" __default_closed__ = True @@ -129,7 +125,7 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel): layout = self.layout md = context.smoke.domain_settings - cache = md.point_cache + cache = md.point_cache_low point_cache_ui(self, cache, cache.baked==False, 0, 1) @@ -152,7 +148,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): md = context.smoke.domain_settings split = layout.split() - + col = split.column() col.itemL(text="Resolution:") col.itemR(md, "amplify", text="Divisions") @@ -161,66 +157,26 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): col.itemL(text="Noise Method:") col.row().itemR(md, "noise_type", text="") col.itemR(md, "strength") - col.itemR(md, "show_highres") + sub.itemR(md, "viewhighres") class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel): - __label__ = "Smoke Cache" + __label__ = "Smoke High Resolution Cache" __default_closed__ = True def poll(self, context): - return (context.smoke) + md = context.smoke + return md and (md.smoke_type == 'TYPE_DOMAIN') and md.domain_settings.highres def draw(self, context): layout = self.layout - md = context.smoke - - cache = md.point_cache - - layout.set_context_pointer("PointCache", cache) - - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index") - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - - row = layout.row() - row.itemR(cache, "name") - - row = layout.row() - row.itemR(cache, "start_frame") - row.itemR(cache, "end_frame") - - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - - subrow = row.row() - subrow.enabled = cache.frames_skipped or cache.outdated - subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") - - row = layout.row() - #row.enabled = smoke_panel_enabled(psys) - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - - row = layout.row() - #row.enabled = smoke_panel_enabled(psys) - - layout.itemL(text=cache.info) - - layout.itemS() + md = context.smoke.domain_settings + cache = md.point_cache_high - row = layout.row() - row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") - + point_cache_ui(self, cache, cache.baked==False, 0, 1) + bpy.types.register(PHYSICS_PT_smoke) bpy.types.register(PHYSICS_PT_smoke_cache) +bpy.types.register(PHYSICS_PT_smoke_highres) bpy.types.register(PHYSICS_PT_smoke_groups) -#bpy.types.register(PHYSICS_PT_smoke_highres) -#bpy.types.register(PHYSICS_PT_smoke_cache_highres) +bpy.types.register(PHYSICS_PT_smoke_cache_highres) diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index b7ab07b0f91..5ae10d736fd 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -232,6 +232,7 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct Soft void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys); void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd); void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd); +void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd); void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob); diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h index fddcf0fea83..0f8e9c5edf5 100644 --- a/source/blender/blenkernel/BKE_smoke.h +++ b/source/blender/blenkernel/BKE_smoke.h @@ -32,13 +32,15 @@ #ifndef BKE_SMOKE_H_ #define BKE_SMOKE_H_ -typedef int (*bresenham_callback) (float *input, int res[3], int *pixel, float *tRay); +typedef float (*bresenham_callback) (float *result, float *input, int res[3], int *pixel, float *tRay, float correct); void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc); void smokeModifier_free (struct SmokeModifierData *smd); void smokeModifier_reset(struct SmokeModifierData *smd); +void smokeModifier_reset_turbulence(struct SmokeModifierData *smd); void smokeModifier_createType(struct SmokeModifierData *smd); +long long smoke_get_mem_req(int xres, int yres, int zres, int amplify); #endif /* BKE_SMOKE_H_ */ diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 912acc4786f..1ab1daf1782 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -471,6 +471,19 @@ static int ptcache_totpoint_smoke(void *smoke_v) return 0; } +/* Smoke functions */ +static int ptcache_totpoint_smoke_turbulence(void *smoke_v) +{ + SmokeModifierData *smd= (SmokeModifierData *)smoke_v; + SmokeDomainSettings *sds = smd->domain; + + if(sds->wt) { + return sds->res_wt[0]*sds->res_wt[1]*sds->res_wt[2]; + } + else + return 0; +} + // forward decleration static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size); @@ -521,7 +534,7 @@ static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned i } static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v) -{ +{ SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; @@ -535,7 +548,7 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v) smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); - ptcache_compress_write(pf, (unsigned char *)sds->view3d, in_len*4, out, mode); + ptcache_compress_write(pf, (unsigned char *)sds->shadow, in_len, out, mode); ptcache_compress_write(pf, (unsigned char *)dens, in_len, out, mode); ptcache_compress_write(pf, (unsigned char *)densold, in_len, out, mode); ptcache_compress_write(pf, (unsigned char *)heat, in_len, out, mode); @@ -554,36 +567,36 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v) return 1; } - return 0; } -/* static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; if(sds->wt) { - unsigned int res_big[3]; - size_t res = sds->res[0]*sds->res[1]*sds->res[2]; + unsigned int res_big_array[3]; + unsigned int res_big; + unsigned int res = sds->res[0]*sds->res[1]*sds->res[2]; float *dens, *densold, *tcu, *tcv, *tcw; unsigned int in_len = sizeof(float)*(unsigned int)res; - unsigned int in_len_big = sizeof(float) * (unsigned int)res_big; + unsigned int in_len_big; unsigned char *out; int mode; - smoke_turbulence_get_res(sds->wt, res_big); - mode = res_big[0]*res_big[1]*res_big[2] >= 1000000 ? 2 : 1; + smoke_turbulence_get_res(sds->wt, res_big_array); + res_big = res_big_array[0]*res_big_array[1]*res_big_array[2]; + mode = res_big >= 1000000 ? 2 : 1; + in_len_big = sizeof(float) * (unsigned int)res_big; smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer"); - ptcache_compress_write(pf, (unsigned char *)dens, in_len_big, out, mode); ptcache_compress_write(pf, (unsigned char *)densold, in_len_big, out, mode); - MEM_freeN(out); + out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer"); ptcache_compress_write(pf, (unsigned char *)tcu, in_len, out, mode); ptcache_compress_write(pf, (unsigned char *)tcv, in_len, out, mode); @@ -594,7 +607,6 @@ static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v) } return 0; } -*/ // forward decleration static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size); @@ -649,7 +661,7 @@ static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v) smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); - ptcache_compress_read(pf, (unsigned char *)sds->view3d, out_len*4); + ptcache_compress_read(pf, (unsigned char *)sds->shadow, out_len); ptcache_compress_read(pf, (unsigned char*)dens, out_len); ptcache_compress_read(pf, (unsigned char*)densold, out_len); ptcache_compress_read(pf, (unsigned char*)heat, out_len); @@ -666,26 +678,32 @@ static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v) } } -/* static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; if(sds->fluid) { - unsigned int res[3]; + unsigned int res = sds->res[0]*sds->res[1]*sds->res[2]; + unsigned int res_big, res_big_array[3]; float *dens, *densold, *tcu, *tcv, *tcw; unsigned int out_len = sizeof(float)*(unsigned int)res; + unsigned int out_len_big; - smoke_turbulence_get_res(sds->wt, res); + smoke_turbulence_get_res(sds->wt, res_big_array); + res_big = res_big_array[0]*res_big_array[1]*res_big_array[2]; + out_len_big = sizeof(float) * (unsigned int)res_big; smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); - ptcache_compress_read(pf, (unsigned char*)dens, out_len); - + ptcache_compress_read(pf, (unsigned char*)dens, out_len_big); + ptcache_compress_read(pf, (unsigned char*)densold, out_len_big); + + ptcache_compress_read(pf, (unsigned char*)tcu, out_len); + ptcache_compress_read(pf, (unsigned char*)tcv, out_len); + ptcache_compress_read(pf, (unsigned char*)tcw, out_len); } } -*/ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd) { @@ -716,7 +734,7 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo pid->write_header= ptcache_write_basic_header; pid->read_header= ptcache_read_basic_header; - pid->data_types= (1<data_types= (1<info_types= 0; } @@ -736,13 +754,13 @@ void BKE_ptcache_id_from_smoke_turbulence(PTCacheID *pid, struct Object *ob, str pid->cache_ptr= &sds->point_cache[1]; pid->ptcaches= &sds->ptcaches[1]; - pid->totpoint= pid->totwrite= ptcache_totpoint_smoke; + pid->totpoint= pid->totwrite= ptcache_totpoint_smoke_turbulence; pid->write_elem= NULL; pid->read_elem= NULL; - pid->read_stream = ptcache_read_smoke; - pid->write_stream = ptcache_write_smoke; + pid->read_stream = ptcache_read_smoke_turbulence; + pid->write_stream = ptcache_write_smoke_turbulence; pid->interpolate_elem= NULL; @@ -820,6 +838,10 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md); BLI_addtail(lb, pid); + + pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); + BKE_ptcache_id_from_smoke_turbulence(pid, ob, (SmokeModifierData*)md); + BLI_addtail(lb, pid); } } } @@ -1824,6 +1846,8 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); + else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) + smokeModifier_reset(pid->calldata); } if(clear) BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0); @@ -1878,6 +1902,9 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode) { BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md); reset |= BKE_ptcache_id_reset(scene, &pid, mode); + + BKE_ptcache_id_from_smoke_turbulence(&pid, ob, (SmokeModifierData*)md); + reset |= BKE_ptcache_id_reset(scene, &pid, mode); } } } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 223d48012df..026ccf4fc7d 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -92,10 +92,10 @@ static void tend ( void ) { QueryPerformanceCounter ( &liCurrentTime ); } -//static double tval() -//{ -// return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); -//} +static double tval() +{ + return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); +} #else #include static struct timeval _tstart, _tend; @@ -125,7 +125,6 @@ struct SmokeModifierData; // forward declerations static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct); void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); -void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light); #define TRI_UVOFFSET (1./4.) @@ -167,6 +166,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive // calc other res with max_res provided VECSUB(size, max, min); + // prevent crash when initializing a plane as domain if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) return 0; @@ -215,22 +215,28 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive // dt max is 0.1 smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, 0.1); smd->time = scene->r.cfra; - smd->domain->firstframe = smd->time; - if(!smd->domain->wt && (smd->domain->flags & MOD_SMOKE_HIGHRES)) + if(smd->domain->flags & MOD_SMOKE_HIGHRES) { - smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise); - smoke_turbulence_initBlenderRNA(smd->domain->wt, &smd->domain->strength); + smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise); + smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1); + smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1); + smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1); + smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1); + printf("smd->domain->amplify: %d\n", smd->domain->amplify); + printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n"); } - if(!smd->domain->view3d) - { - // TVox is for transparency - smd->domain->view3d = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2]*4, "Smoke_tVox"); - } + if(!smd->domain->shadow) + smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow"); smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta)); + if(smd->domain->wt) + { + smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength)); + printf("smoke_initWaveletBlenderRNA\n"); + } return 1; } else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) @@ -270,13 +276,11 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive SmokeCollSettings *scs = smd->coll; MVert *mvert = dm->getVertArray(dm); MFace *mface = dm->getFaceArray(dm); - size_t i = 0; - int divs = 0; + int i = 0, divs = 0; int *tridivs = NULL; float cell_len = 1.0 / 50.0; // for res = 50 - size_t newdivs = 0; - //size_t max_points = 0; - size_t quads = 0, facecounter = 0; + int newdivs = 0; + int quads = 0, facecounter = 0; // copy obmat Mat4CpyMat4(scs->mat, ob->obmat); @@ -314,7 +318,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive int again = 0; do { - size_t j, k; + int j, k; int divs1 = tridivs[3 * facecounter + 0]; int divs2 = tridivs[3 * facecounter + 1]; //int divs3 = tridivs[3 * facecounter + 2]; @@ -521,10 +525,10 @@ void smokeModifier_freeDomain(SmokeModifierData *smd) { if(smd->domain) { - // free visualisation buffers - if(smd->domain->view3d) - MEM_freeN(smd->domain->view3d); - + if(smd->domain->shadow) + MEM_freeN(smd->domain->shadow); + smd->domain->shadow = NULL; + if(smd->domain->fluid) smoke_free(smd->domain->fluid); @@ -583,41 +587,46 @@ void smokeModifier_freeCollision(SmokeModifierData *smd) } } +void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) +{ + if(smd && smd->domain && smd->domain->wt) + { + smoke_turbulence_free(smd->domain->wt); + smd->domain->wt = NULL; + } + + smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID; + smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED; + smd->domain->point_cache[1]->simframe= 0; + smd->domain->point_cache[1]->last_exact= 0; +} + void smokeModifier_reset(struct SmokeModifierData *smd) { if(smd) { if(smd->domain) { - if(smd->domain->view3d) - MEM_freeN(smd->domain->view3d); - smd->domain->view3d = NULL; - - smd->domain->tex = NULL; + if(smd->domain->shadow) + MEM_freeN(smd->domain->shadow); + smd->domain->shadow = NULL; if(smd->domain->fluid) { smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; } - - if(smd->domain->wt) - { - smoke_turbulence_free(smd->domain->wt); - smd->domain->wt = NULL; - } - + smd->domain->point_cache[0]->flag &= ~PTCACHE_SIMULATION_VALID; smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED; smd->domain->point_cache[0]->simframe= 0; smd->domain->point_cache[0]->last_exact= 0; - smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID; - smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED; - smd->domain->point_cache[1]->simframe= 0; - smd->domain->point_cache[1]->last_exact= 0; + smokeModifier_reset_turbulence(smd); - // printf("reset_domain\n"); + smd->time = -1; + + // printf("reset domain end\n"); } else if(smd->flow) { @@ -685,22 +694,21 @@ void smokeModifier_createType(struct SmokeModifierData *smd) /* set some standard values */ smd->domain->fluid = NULL; + smd->domain->wt = NULL; smd->domain->eff_group = NULL; smd->domain->fluid_group = NULL; smd->domain->coll_group = NULL; smd->domain->maxres = 32; + smd->domain->amplify = 1; + smd->domain->omega = 1.0; smd->domain->alpha = -0.001; smd->domain->beta = 0.1; smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG; - smd->domain->diss_speed = 5; - smd->domain->strength = 2.0f; - smd->domain->amplify = 1; + smd->domain->strength = 2.0; smd->domain->noise = MOD_SMOKE_NOISEWAVE; - smd->domain->wt = NULL; - + smd->domain->diss_speed = 5; // init 3dview buffer - smd->domain->view3d = NULL; - smd->domain->tex = NULL; + smd->domain->viewsettings = 0; } else if(smd->type & MOD_SMOKE_TYPE_FLOW) { @@ -734,9 +742,314 @@ void smokeModifier_createType(struct SmokeModifierData *smd) } } -// forward declaration -void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm); +// forward decleration +void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); +static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); +static int get_lamp(Scene *scene, float *light) +{ + Base *base_tmp = NULL; + for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) + { + if(base_tmp->object->type == OB_LAMP) + { + Lamp *la = (Lamp *)base_tmp->object->data; + + if(la->type == LA_LOCAL) + { + VECCOPY(light, base_tmp->object->obmat[3]); + return 1; + } + } + } + return 0; +} + +static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) +{ + SmokeDomainSettings *sds = smd->domain; + GroupObject *go = NULL; + Base *base = NULL; + + // do flows and fluids + if(1) + { + Object *otherobj = NULL; + ModifierData *md = NULL; + if(sds->fluid_group) // we use groups since we have 2 domains + go = sds->fluid_group->gobject.first; + else + base = scene->base.first; + while(base || go) + { + otherobj = NULL; + if(sds->fluid_group) + { + if(go->ob) + otherobj = go->ob; + } + else + otherobj = base->object; + if(!otherobj) + { + if(sds->fluid_group) + go = go->next; + else + base= base->next; + + continue; + } + + md = modifiers_findByType(otherobj, eModifierType_Smoke); + + // check for active smoke modifier + if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) + { + SmokeModifierData *smd2 = (SmokeModifierData *)md; + + // check for initialized smoke object + if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + { + // we got nice flow object + SmokeFlowSettings *sfs = smd2->flow; + + if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected + { + ParticleSystem *psys = sfs->psys; + ParticleSettings *part=psys->part; + ParticleData *pa = NULL; + int p = 0; + float *density = smoke_get_density(sds->fluid); + float *bigdensity = smoke_turbulence_get_density(sds->wt); + float *heat = smoke_get_heat(sds->fluid); + float *velocity_x = smoke_get_velocity_x(sds->fluid); + float *velocity_y = smoke_get_velocity_y(sds->fluid); + float *velocity_z = smoke_get_velocity_z(sds->fluid); + unsigned char *obstacle = smoke_get_obstacle(sds->fluid); + int bigres[3]; + + // mostly copied from particle code + for(p=0, pa=psys->particles; ptotpart; p++, pa++) + { + int cell[3]; + size_t i = 0; + size_t index = 0; + int badcell = 0; + if(pa->alive == PARS_KILLED) continue; + else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue; + else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue; + else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue; + // VECCOPY(pos, pa->state.co); + // Mat4MulVecfl (ob->imat, pos); + // 1. get corresponding cell + get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0); + // check if cell is valid (in the domain boundary) + for(i = 0; i < 3; i++) + { + if((cell[i] > sds->res[i] - 1) || (cell[i] < 0)) + { + badcell = 1; + break; + } + } + if(badcell) + continue; + // 2. set cell values (heat, density and velocity) + index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); + if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow + { + // heat[index] += sfs->temp * 0.1; + // density[index] += sfs->density * 0.1; + heat[index] = sfs->temp; + density[index] = sfs->density; + + /* + velocity_x[index] = pa->state.vel[0]; + velocity_y[index] = pa->state.vel[1]; + velocity_z[index] = pa->state.vel[2]; + */ + + // obstacle[index] |= 2; + // we need different handling for the high-res feature + if(bigdensity) + { + // init all surrounding cells according to amplification, too + int i, j, k; + + smoke_turbulence_get_res(smd->domain->wt, bigres); + + for(i = 0; i < smd->domain->amplify + 1; i++) + for(j = 0; j < smd->domain->amplify + 1; j++) + for(k = 0; k < smd->domain->amplify + 1; k++) + { + index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k); + bigdensity[index] = sfs->density; + } + } + } + else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow + { + heat[index] = 0.f; + density[index] = 0.f; + velocity_x[index] = 0.f; + velocity_y[index] = 0.f; + velocity_z[index] = 0.f; + // we need different handling for the high-res feature + if(bigdensity) + { + // init all surrounding cells according to amplification, too + int i, j, k; + smoke_turbulence_get_res(smd->domain->wt, bigres); + + for(i = 0; i < smd->domain->amplify + 1; i++) + for(j = 0; j < smd->domain->amplify + 1; j++) + for(k = 0; k < smd->domain->amplify + 1; k++) + { + index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k); + bigdensity[index] = 0.f; + } + } + } // particles loop + } + } + else + { + /* + for() + { + // no psys + BVHTreeNearest nearest; + nearest.index = -1; + nearest.dist = FLT_MAX; + + BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh); + }*/ + } + } + } + if(sds->fluid_group) + go = go->next; + else + base= base->next; + } + } + + // do effectors + /* + if(sds->eff_group) + { + for(go = sds->eff_group->gobject.first; go; go = go->next) + { + if(go->ob) + { + if(ob->pd) + { + + } + } + } + } + */ + + // do collisions + if(1) + { + Object *otherobj = NULL; + ModifierData *md = NULL; + + if(sds->coll_group) // we use groups since we have 2 domains + go = sds->coll_group->gobject.first; + else + base = scene->base.first; + + while(base || go) + { + otherobj = NULL; + if(sds->coll_group) + { + if(go->ob) + otherobj = go->ob; + } + else + otherobj = base->object; + if(!otherobj) + { + if(sds->coll_group) + go = go->next; + else + base= base->next; + continue; + } + md = modifiers_findByType(otherobj, eModifierType_Smoke); + + // check for active smoke modifier + if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) + { + SmokeModifierData *smd2 = (SmokeModifierData *)md; + + if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) + { + // we got nice collision object + SmokeCollSettings *scs = smd2->coll; + size_t i, j; + unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid); + + for(i = 0; i < scs->numpoints; i++) + { + int badcell = 0; + size_t index = 0; + int cell[3]; + + // 1. get corresponding cell + get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, &scs->points[3 * i], cell, 0); + + // check if cell is valid (in the domain boundary) + for(j = 0; j < 3; j++) + if((cell[j] > sds->res[j] - 1) || (cell[j] < 0)) + { + badcell = 1; + break; + } + + if(badcell) + continue; + // 2. set cell values (heat, density and velocity) + index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); + + // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]); + // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index); + obstacles[index] = 1; + // for moving gobstacles + /* + const LbmFloat maxVelVal = 0.1666; + const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5; + + LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); + { + const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5; + USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz); + if(usqr>maxusqr) { + // cutoff at maxVelVal + for(int jj=0; jj<3; jj++) { + if(objvel[jj]>0.) objvel[jj] = maxVelVal; + if(objvel[jj]<0.) objvel[jj] = -maxVelVal; + } + } + } + const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) ); + const LbmVec oldov=objvel; // debug + objvel = vec2L((*pNormals)[n]) *dp; + */ + } + } + } + if(sds->coll_group) + go = go->next; + else + base= base->next; + } + } +} void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) { if((smd->type & MOD_SMOKE_TYPE_FLOW)) @@ -788,16 +1101,15 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) { - PointCache *cache; + PointCache *cache = NULL; PTCacheID pid; + PointCache *cache_wt = NULL; + PTCacheID pid_wt; float timescale; - int cache_result = 0; - int startframe, endframe, framenr; + int cache_result = 0, cache_result_wt = 0; + int startframe, endframe, framenr, badloading = 0; SmokeDomainSettings *sds = smd->domain; - float light[3] = {0.0,0.0,0.0}; - int have_lamp = 0; - - // printf("smd->type & MOD_SMOKE_TYPE_DOMAIN\n"); + float light[3]; framenr = scene->r.cfra; @@ -806,51 +1118,26 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM BKE_ptcache_id_from_smoke(&pid, ob, smd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); + cache_wt = sds->point_cache[1]; + BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd); + /* handle continuous simulation with the play button */ if(BKE_ptcache_get_continue_physics()) { - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - cache->last_exact= 0; - - if(!smokeModifier_init(smd, ob, scene, dm)) - return; - - if(!smd->domain->fluid) - return; - - smoke_simulate_domain(smd, scene, ob, dm); - - { - Base *base_tmp = NULL; - - for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) - { - if(base_tmp->object->type == OB_LAMP) - { - Lamp *la = (Lamp *)base_tmp->object->data; - - if(la->type == LA_LOCAL) - { - VECCOPY(light, base_tmp->object->obmat[3]); - have_lamp = 1; - break; - } - } - } - } - - smoke_prepare_View(smd, (float)framenr, light, have_lamp); - + // TODO return; } - + if(framenr < startframe) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; cache->last_exact= 0; + cache_wt->flag &= ~PTCACHE_SIMULATION_VALID; + cache_wt->simframe= 0; + cache_wt->last_exact= 0; + // we got back in time, reset smoke in this case (TODO: use cache later) // smd->time = scene->r.cfra; // smokeModifier_reset(smd); @@ -860,14 +1147,25 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM else if(framenr > endframe) { framenr = endframe; + + // we load last valid frame here + // and don't update the smd->time variable later + badloading = 1; } if(!(cache->flag & PTCACHE_SIMULATION_VALID)) { - // printf("reseting\n"); BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); } - + if(!(cache_wt->flag & PTCACHE_SIMULATION_VALID)) + { + BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED); + } + + if(smd->time == -1 && framenr!= startframe) + return; + + if(!smokeModifier_init(smd, ob, scene, dm)) return; @@ -875,7 +1173,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM return; /* try to read from cache */ - cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec); + cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec); // printf("cache_result: %d\n", cache_result); if(cache_result == PTCACHE_READ_EXACT) @@ -886,417 +1184,148 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM cache->simframe= framenr; sds->v3dnum = framenr; + if(!badloading) + smd->time = scene->r.cfra; + + // check for wt cache + if(sds->wt) + { + cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec); + // printf("cache_result_wt: %d\n", cache_result_wt); + + // error handling + if(cache_result_wt == PTCACHE_READ_EXACT) + { + cache_wt->flag |= PTCACHE_SIMULATION_VALID; + cache_wt->simframe= framenr; + } + else if(cache_result_wt==PTCACHE_READ_OLD) + { + BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE); + cache_wt->flag |= PTCACHE_SIMULATION_VALID; + } + else if(ob->id.lib || (cache_wt->flag & PTCACHE_BAKED)) + { + // if baked and nothing in cache, do nothing + cache_wt->flag &= ~PTCACHE_SIMULATION_VALID; + cache_wt->simframe= 0; + cache_wt->last_exact= 0; + } + } + // printf("PTCACHE_READ_EXACT\n"); return; } else if(cache_result==PTCACHE_READ_OLD) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); - - // printf("PTCACHE_READ_OLD\n"); - cache->flag |= PTCACHE_SIMULATION_VALID; + + BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE); + cache_wt->flag |= PTCACHE_SIMULATION_VALID; } else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { - /* if baked and nothing in cache, do nothing */ + // if baked and nothing in cache, do nothing cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; cache->last_exact= 0; + cache_wt->flag &= ~PTCACHE_SIMULATION_VALID; + cache_wt->simframe= 0; + cache_wt->last_exact= 0; + // printf("PTCACHE_BAKED\n"); return; } - else if((cache_result==0) && (startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID)) + /* + else if((cache_result==0) && ((startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID || (framenr == smd->time)))) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; cache->last_exact= 0; return; - } - + }*/ + + // printf("framenr: %d, time: %f\n", framenr, smd->time); + /* do simulation */ // low res cache->flag |= PTCACHE_SIMULATION_VALID; cache->simframe= framenr; - smoke_simulate_domain(smd, scene, ob, dm); - if(sds->wt) - smoke_turbulence_step(sds->wt, sds->fluid); - { - Base *base_tmp = NULL; - - for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) - { - if(base_tmp->object->type == OB_LAMP) - { - Lamp *la = (Lamp *)base_tmp->object->data; - - if(la->type == LA_LOCAL) - { - VECCOPY(light, base_tmp->object->obmat[3]); - have_lamp = 1; - break; - } - } - } + cache_wt->flag |= PTCACHE_SIMULATION_VALID; + cache_wt->simframe= framenr; } - - smoke_prepare_View(smd, (float)framenr, light, have_lamp); - - BKE_ptcache_write_cache(&pid, framenr); - - // printf("Writing cache_low, %d\n", framenr); - - - tend(); - // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() ); - } -} - -void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) -{ - GroupObject *go = NULL; - Base *base = NULL; - SmokeDomainSettings *sds = smd->domain; - - tstart(); - - if(sds->flags & MOD_SMOKE_DISSOLVE) - smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - - // do flows and fluids - if(1) - { - Object *otherobj = NULL; - ModifierData *md = NULL; - - if(sds->fluid_group) // we use groups since we have 2 domains - go = sds->fluid_group->gobject.first; - else - base = scene->base.first; - - while(base || go) - { - otherobj = NULL; - - if(sds->fluid_group) - { - if(go->ob) - otherobj = go->ob; - } - else - otherobj = base->object; - - if(!otherobj) - { - if(sds->fluid_group) - go = go->next; - else - base= base->next; - - continue; - } - - md = modifiers_findByType(otherobj, eModifierType_Smoke); - - // check for active smoke modifier - if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) - { - SmokeModifierData *smd2 = (SmokeModifierData *)md; - // check for initialized smoke object - if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) - { - // we got nice flow object - SmokeFlowSettings *sfs = smd2->flow; - - if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected - { - ParticleSystem *psys = sfs->psys; - ParticleSettings *part=psys->part; - ParticleData *pa = NULL; - int p = 0; - float *density = smoke_get_density(sds->fluid); - // float *bigdensity = smoke_turbulence_get_density(sds->wt); - float *heat = smoke_get_heat(sds->fluid); - float *velocity_x = smoke_get_velocity_x(sds->fluid); - float *velocity_y = smoke_get_velocity_y(sds->fluid); - float *velocity_z = smoke_get_velocity_z(sds->fluid); - unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - - // debug printf("found flow psys\n"); - - // mostly copied from particle code - for(p=0, pa=psys->particles; ptotpart; p++, pa++) - { - int cell[3]; - size_t i = 0; - size_t index = 0; - int badcell = 0; - - if(pa->alive == PARS_KILLED) continue; - else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue; - else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue; - else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue; - - // VECCOPY(pos, pa->state.co); - // Mat4MulVecfl (ob->imat, pos); - - // 1. get corresponding cell - get_cell(sds->p0, sds->res, sds->dx, pa->state.co, cell, 0); - - // check if cell is valid (in the domain boundary) - for(i = 0; i < 3; i++) - { - if((cell[i] > sds->res[i] - 1) || (cell[i] < 0)) - { - badcell = 1; - break; - } - } - - if(badcell) - continue; - - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow - { - // heat[index] += sfs->temp * 0.1; - // density[index] += sfs->density * 0.1; - - heat[index] = sfs->temp; - density[index] = sfs->density; - - /* - velocity_x[index] = pa->state.vel[0]; - velocity_y[index] = pa->state.vel[1]; - velocity_z[index] = pa->state.vel[2]; - */ - obstacle[index] |= 2; - } - else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow - { - heat[index] = 0.f; - density[index] = 0.f; - velocity_x[index] = 0.f; - velocity_y[index] = 0.f; - velocity_z[index] = 0.f; - } - } - } - else - { - /* - for() - { - // no psys - BVHTreeNearest nearest; - - nearest.index = -1; - nearest.dist = FLT_MAX; - - BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh); - }*/ - } - } - } + tstart(); - if(sds->fluid_group) - go = go->next; - else - base= base->next; - } - } - - // do effectors - /* - if(sds->eff_group) - { - for(go = sds->eff_group->gobject.first; go; go = go->next) - { - if(go->ob) - { - if(ob->pd) - { - - } - } + if(sds->flags & MOD_SMOKE_DISSOLVE) + { + smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); } - } - */ - - // do collisions - if(1) - { - Object *otherobj = NULL; - ModifierData *md = NULL; - if(sds->coll_group) // we use groups since we have 2 domains - go = sds->coll_group->gobject.first; - else - base = scene->base.first; + smoke_calc_domain(scene, ob, smd); + + // set new time + smd->time = scene->r.cfra; - while(base || go) + // frame 1 is start, don't simulate anything + if(smd->time == 1) { - otherobj = NULL; - - if(sds->coll_group) - { - if(go->ob) - otherobj = go->ob; - } - else - otherobj = base->object; + // set new time + smd->time = scene->r.cfra; - if(!otherobj) - { - if(sds->coll_group) - go = go->next; - else - base= base->next; + BKE_ptcache_write_cache(&pid, framenr); + if(sds->wt) + BKE_ptcache_write_cache(&pid_wt, framenr); - continue; - } - - md = modifiers_findByType(otherobj, eModifierType_Smoke); - - // check for active smoke modifier - if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) - { - SmokeModifierData *smd2 = (SmokeModifierData *)md; + if(get_lamp(scene, light)) + smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) - { - // we got nice collision object - SmokeCollSettings *scs = smd2->coll; - size_t i, j; - unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid); + return; + } - for(i = 0; i < scs->numpoints; i++) - { - int badcell = 0; - size_t index = 0; - int cell[3]; + // simulate the actual smoke (c++ code in intern/smoke) + smoke_step(sds->fluid, smd->time); + BKE_ptcache_write_cache(&pid, framenr); - // 1. get corresponding cell - get_cell(sds->p0, sds->res, sds->dx, &scs->points[3 * i], cell, 0); - - // check if cell is valid (in the domain boundary) - for(j = 0; j < 3; j++) - if((cell[j] > sds->res[j] - 1) || (cell[j] < 0)) - { - badcell = 1; - break; - } - - if(badcell) - continue; + if(sds->wt) + { - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - - // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]); - // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index); - - obstacles[index] = 1; + if(sds->flags & MOD_SMOKE_DISSOLVE) + smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - // for moving gobstacles - /* - const LbmFloat maxVelVal = 0.1666; - const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5; + smoke_turbulence_step(sds->wt, sds->fluid); + BKE_ptcache_write_cache(&pid_wt, framenr); + } - LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); { - const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5; - USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz); - if(usqr>maxusqr) { - // cutoff at maxVelVal - for(int jj=0; jj<3; jj++) { - if(objvel[jj]>0.) objvel[jj] = maxVelVal; - if(objvel[jj]<0.) objvel[jj] = -maxVelVal; - } - } } - - const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) ); - const LbmVec oldov=objvel; // debug - objvel = vec2L((*pNormals)[n]) *dp; - */ - } - } - } + if(get_lamp(scene, light)) + smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); - if(sds->coll_group) - go = go->next; - else - base= base->next; - } + tend(); + // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() ); } - - // set new time - smd->time = scene->r.cfra; - - // simulate the actual smoke (c++ code in intern/smoke) - smoke_step(sds->fluid, smd->time); } -static int calc_voxel_transp(float *input, int res[3], int *pixel, float *tRay) +static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) { const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); // T_ray *= T_vox - *tRay *= input[index*4]; - - return *tRay; -} - -// forward decleration -void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb); - -// update necessary information for 3dview -void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light) -{ - float *density = NULL; - int x, y, z; - size_t cells, i; - SmokeDomainSettings *sds = smd->domain; - - // update 3dview - density = smoke_get_density(smd->domain->fluid); - for(x = 0; x < smd->domain->res[0]; x++) - for(y = 0; y < smd->domain->res[1]; y++) - for(z = 0; z < smd->domain->res[2]; z++) - { - size_t index; - - index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z); - // Transparency computation - // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4 - // T_vox = exp(-C_ext * h) - // C_ext/sigma_t = density * C_ext - smd->domain->view3d[index * 4] = smd->domain->view3d[index * 4 + 1] = - smd->domain->view3d[index * 4 + 2] = exp(-density[index] * 7.0 * smd->domain->dx); - smd->domain->view3d[index * 4 + 3] = 1.0 - smd->domain->view3d[index * 4]; - - } - - if(have_light) + *tRay *= exp(input[index]*correct); + + if(result[index] < 0.0f) { - smoke_calc_transparency(sds->view3d, sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp); +#pragma omp critical + result[index] = *tRay; + } - cells = smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2]; - for(i = 0; i < cells; i++) - { - smd->domain->view3d[i * 4] = smd->domain->view3d[i * 4 + 1] = - smd->domain->view3d[i * 4 + 2] = smd->domain->view3d[i * 4 + 1] * smd->domain->view3d[i * 4 + 0]; - } - } - smd->domain->v3dnum = framenr; + return *tRay; } long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) @@ -1317,7 +1346,7 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) return totalMB; } -static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *input, int res[3]) +static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct) { int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2; int pixel[3]; @@ -1344,8 +1373,8 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dy2 - l; err_2 = dz2 - l; for (i = 0; i < l; i++) { - if(cb(input, res, pixel, tRay) < 0.0) - return; + if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + break; if (err_1 > 0) { pixel[1] += y_inc; err_1 -= dx2; @@ -1362,8 +1391,8 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dx2 - m; err_2 = dz2 - m; for (i = 0; i < m; i++) { - if(cb(input, res, pixel, tRay) < 0.0f) - return; + if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + break; if (err_1 > 0) { pixel[0] += x_inc; err_1 -= dy2; @@ -1380,8 +1409,8 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dy2 - n; err_2 = dx2 - n; for (i = 0; i < n; i++) { - if(cb(input, res, pixel, tRay) < 0.0f) - return; + if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + break; if (err_1 > 0) { pixel[1] += y_inc; err_1 -= dz2; @@ -1395,7 +1424,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f pixel[2] += z_inc; } } - cb(input, res, pixel, tRay); + cb(result, input, res, pixel, tRay, correct); } static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct) @@ -1419,12 +1448,12 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int } } -void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb) +void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) { int x, y, z; float bv[6]; - // x + memset(result, -1, sizeof(float)*res[0]*res[1]*res[2]); // x bv[0] = p0[0]; bv[1] = p1[0]; // y @@ -1434,7 +1463,7 @@ void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], fl bv[4] = p0[2]; bv[5] = p1[2]; -// #pragma omp parallel for schedule(static) private(y, z) +#pragma omp parallel for schedule(static) private(y, z) for(x = 0; x < res[0]; x++) for(y = 0; y < res[1]; y++) for(z = 0; z < res[2]; z++) @@ -1447,6 +1476,8 @@ void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], fl index = smoke_get_index(x, res[0], y, res[1], z); + if(result[index] >= 0.0f) + continue; voxelCenter[0] = p0[0] + dx * x + dx * 0.5; voxelCenter[1] = p0[1] + dx * y + dx * 0.5; voxelCenter[2] = p0[2] + dx * z + dx * 0.5; @@ -1463,10 +1494,11 @@ void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], fl get_cell(p0, res, dx, light, cell, 1); } - bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, res); + bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct); // convention -> from a RGBA float array, use G value for tRay - result[index*4 + 1] = tRay; +// #pragma omp critical + result[index] = tRay; } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 618e587d674..b6fc9f7af12 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3685,8 +3685,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->domain->smd = smd; smd->domain->fluid = NULL; - smd->domain->view3d = NULL; - smd->domain->tex = NULL; + // smd->domain->view3d = NULL; + // smd->domain->tex = NULL; direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0])); direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1])); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 20cab3b8aeb..7ed029f3eaf 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5310,13 +5310,60 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* draw code for smoke */ + if((md = modifiers_findByType(ob, eModifierType_Smoke))) { - md = modifiers_findByType(ob, eModifierType_Smoke); - if (md) { - SmokeModifierData *smd = (SmokeModifierData *)md; - if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && smd->domain->fluid) { - GPU_create_smoke(smd); - draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res); + SmokeModifierData *smd = (SmokeModifierData *)md; + + // draw collision objects + if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll) + { + /*SmokeCollSettings *scs = smd->coll; + if(scs->points) + { + size_t i; + + wmLoadMatrix(rv3d->viewmat); + + if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + + + // glPointSize(3.0); + bglBegin(GL_POINTS); + + for(i = 0; i < scs->numpoints; i++) + { + bglVertex3fv(&scs->points[3*i]); + } + + bglEnd(); + glPointSize(1.0); + + wmMultMatrix(ob->obmat); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + if(col) cpack(col); + + } + */ + } + + // only draw domains + if(smd->domain && smd->domain->fluid) + { + if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) + { + smd->domain->tex = NULL; + GPU_create_smoke(smd, 0); + draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); + GPU_free_smoke(smd); + } + else if(smd->domain->wt || (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) + { + smd->domain->tex = NULL; + GPU_create_smoke(smd, 1); + draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow); GPU_free_smoke(smd); } } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 342acfe92b3..c8eda10566c 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -191,7 +191,7 @@ static int larger_pow2(int n) return n*2; } -void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3]) +void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3], float dx, GPUTexture *tex_shadow) { Object *ob = base->object; RegionView3D *rv3d= ar->regiondata; @@ -204,6 +204,27 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture float cor[3] = {1.,1.,1.}; int gl_depth = 0, gl_blend = 0; + /* Fragment program to calculate the 3dview of smoke */ + /* using 2 textures, density and shadow */ + const char *text = "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" + "TEMP temp, shadow, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "MUL value, temp, darkness;\n" + "MUL value, value, dx;\n" + "MUL value, value, f;\n" + "EX2 temp, -value.r;\n" + "SUB temp.a, 1.0, temp.r;\n" + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MOV result.color, temp;\n" + "END\n"; + unsigned int prog; + glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); @@ -234,7 +255,23 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture } } + if(GLEW_ARB_fragment_program) + { + glGenProgramsARB(1, &prog); + glEnable(GL_FRAGMENT_PROGRAM_ARB); + + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text); + + // cell spacing + glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0); + // custom parameter for smoke style (higher = thicker) + glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); + } + GPU_texture_bind(tex, 0); + if(tex_shadow) + GPU_texture_bind(tex_shadow, 1); if (!GLEW_ARB_texture_non_power_of_two) { cor[0] = (float)res[0]/(float)larger_pow2(res[0]); @@ -289,8 +326,17 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture n++; } + if(tex_shadow) + GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); + if(GLEW_ARB_fragment_program) + { + glDisable(GL_FRAGMENT_PROGRAM_ARB); + glDeleteProgramsARB(1, &prog); + } + + MEM_freeN(points); if(!gl_blend) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index e5e85cf9d16..00b0b5c4fd1 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -157,7 +157,7 @@ ARegion *view3d_has_buttons_region(ScrArea *sa); ARegion *view3d_has_tools_region(ScrArea *sa); /* draw_volume.c */ -void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, int res[3]); +void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, int res[3], float dx, struct GPUTexture *tex_shadow); #endif /* ED_VIEW3D_INTERN_H */ diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 85f4233a251..279596e5ad7 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -28,7 +28,7 @@ FILE(GLOB SRC intern/*.c) SET(INC . ../blenlib ../blenkernel ../makesdna ../include - ../../../extern/glew/include ../../../intern/guardedalloc ../imbuf) + ../../../extern/glew/include ../../../intern/guardedalloc ../../../intern/smoke/extern ../imbuf) BLENDERLIB(bf_gpu "${SRC}" "${INC}") diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 00d0e3131e5..fabe1420e83 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -115,7 +115,7 @@ void GPU_free_images(void); /* smoke drawing functions */ void GPU_free_smoke(struct SmokeModifierData *smd); -void GPU_create_smoke(struct SmokeModifierData *smd); +void GPU_create_smoke(struct SmokeModifierData *smd, int highres); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index a81c7e03455..75e8073aafd 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -64,6 +64,8 @@ #include "GPU_material.h" #include "GPU_draw.h" +#include "smoke_API.h" + /* These are some obscure rendering functions shared between the * game engine and the blender, in this module to avoid duplicaten * and abstract them away from the rest a bit */ @@ -754,13 +756,21 @@ void GPU_free_smoke(SmokeModifierData *smd) if(smd->domain->tex) GPU_texture_free(smd->domain->tex); smd->domain->tex = NULL; + + if(smd->domain->tex_shadow) + GPU_texture_free(smd->domain->tex_shadow); + smd->domain->tex_shadow = NULL; } } -void GPU_create_smoke(SmokeModifierData *smd) +void GPU_create_smoke(SmokeModifierData *smd, int highres) { - if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->view3d); + if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex && !highres) + smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid)); + else if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex && highres) + smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt)); + + smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow); } void GPU_free_image(Image *ima) diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 850b46dc28c..d7b54e425fd 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -346,17 +346,17 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) tex->number = 0; glBindTexture(tex->target, tex->bindcode); - type = GL_UNSIGNED_BYTE; - format = GL_RGBA; - internalformat = GL_RGBA8; + type = GL_FLOAT; // GL_UNSIGNED_BYTE + format = GL_RED; + internalformat = GL_RED; - if (fpixels) - pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); + //if (fpixels) + // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, 0); if (fpixels) { - glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, pixels); + glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels); } glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor); diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index 7c6c7fab9e4..4e4714cdaa1 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -38,9 +38,8 @@ #define MOD_SMOKE_NOISEWAVE (1<<0) #define MOD_SMOKE_NOISEFFT (1<<1) #define MOD_SMOKE_NOISECURL (1<<2) - /* viewsettings */ -#define MOD_SMOKE_SHOWHIGHRES (1<<0) /* show high resolution */ +#define MOD_SMOKE_VIEW_SHOWBIG (1<<0) typedef struct SmokeDomainSettings { struct SmokeModifierData *smd; /* for fast RNA access */ @@ -48,35 +47,34 @@ typedef struct SmokeDomainSettings { struct Group *fluid_group; struct Group *eff_group; // effector group for e.g. wind force struct Group *coll_group; // collision objects group + struct WTURBULENCE *wt; // WTURBULENCE object, if active struct GPUTexture *tex; - float *view3d; /* voxel data for display */ - unsigned int v3dnum; /* number of frame in view3d buffer */ + struct GPUTexture *tex_wt; + struct GPUTexture *tex_shadow; + float *shadow; float p0[3]; /* start point of BB */ float p1[3]; /* end point of BB */ float dx; /* edge length of one cell */ - float firstframe; - float lastframe; + float omega; /* smoke color - from 0 to 1 */ float temp; /* fluid temperature */ float tempAmb; /* ambient temperature */ float alpha; float beta; int res[3]; /* domain resolution */ + int amplify; /* wavelet amplification */ int maxres; /* longest axis on the BB gets this resolution assigned */ int flags; /* show up-res or low res, etc */ + int pad; int viewsettings; + short noise; /* noise type: wave, curl, anisotropic */ short diss_percent; - short pad; int diss_speed;/* in frames */ - struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */ - struct ListBase ptcaches[2]; - struct WTURBULENCE *wt; // WTURBULENCE object, if active - int pad3; float strength; int res_wt[3]; - int maxres_wt; - short noise; /* noise type: wave, curl, anisotropic */ - short pad2; - int amplify; + float dx_wt; + int v3dnum; + struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */ + struct ListBase ptcaches[2]; } SmokeDomainSettings; diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index b3192b110f4..943129c7169 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -46,7 +46,6 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_particle.h" -#include "BKE_pointcache.h" #include "ED_object.h" @@ -79,15 +78,6 @@ static void rna_Smoke_reset_dependancy(bContext *C, PointerRNA *ptr) rna_Smoke_dependency_update(C, ptr); } -#if 0 -static void rna_Smoke_redraw(bContext *C, PointerRNA *ptr) -{ - SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data; - - settings->flags |= MOD_SMOKE_VIEW_REDRAWNICE; -} -#endif - static char *rna_SmokeDomainSettings_path(PointerRNA *ptr) { SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data; @@ -139,6 +129,29 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Max Res", "Maximal resolution used in the fluid domain."); RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + prop= RNA_def_property(srna, "amplify", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "amplify"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_range(prop, 1, 10, 1, 0); + RNA_def_property_ui_text(prop, "Amplification", "Enhance the resolution of smoke by this factor using noise."); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + + prop= RNA_def_property(srna, "highres", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGHRES); + RNA_def_property_ui_text(prop, "High res", "Enable high resolution (using amplification)."); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + + prop= RNA_def_property(srna, "viewhighres", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "viewsettings", MOD_SMOKE_VIEW_SHOWBIG); + RNA_def_property_ui_text(prop, "Show High Resolution", "Show high resolution (using amplification)."); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + + prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "noise"); + RNA_def_property_enum_items(prop, prop_noise_type_items); + RNA_def_property_ui_text(prop, "Noise Method", "Noise method which is used for creating the high resolution"); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "alpha"); RNA_def_property_range(prop, -5.0, 5.0); @@ -174,61 +187,36 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this group."); RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset_dependancy"); + prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "strength"); + RNA_def_property_range(prop, 1.0, 10.0); + RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2); + RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise"); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + prop= RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "diss_speed"); RNA_def_property_range(prop, 1.0, 100.0); RNA_def_property_ui_range(prop, 1.0, 1000.0, 1, 0); RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); - - prop= RNA_def_property(srna, "highres", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGHRES); - RNA_def_property_ui_text(prop, "High Resolution Smoke", "Enable high resolution smoke"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL); + RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "dissolve_smoke", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE); RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "dissolve_smoke_log", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG); RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x "); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, 0, NULL); - prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache_low", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "point_cache[0]"); - RNA_def_property_struct_type(prop, "PointCache"); RNA_def_property_ui_text(prop, "Point Cache", ""); - prop= RNA_def_property(srna, "show_highres", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "viewsettings", MOD_SMOKE_SHOWHIGHRES); - RNA_def_property_ui_text(prop, "High res", "Show high resolution (using amplification)."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); - - prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "noise"); - RNA_def_property_enum_items(prop, prop_noise_type_items); - RNA_def_property_ui_text(prop, "Noise Method", "Noise method which is used for creating the high resolution"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); - - prop= RNA_def_property(srna, "amplify", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "amplify"); - RNA_def_property_range(prop, 1, 10); - RNA_def_property_ui_range(prop, 1, 10, 1, 0); - RNA_def_property_ui_text(prop, "Amplification", "Enhance the resolution of smoke by this factor using noise."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); - - prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "strength"); - RNA_def_property_range(prop, 1.0, 10.0); - RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2); - RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); - - prop= RNA_def_property(srna, "point_cache_turbulence", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache_high", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]"); - RNA_def_property_struct_type(prop, "PointCache"); RNA_def_property_ui_text(prop, "Point Cache", ""); } @@ -247,26 +235,26 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.001, 1); RNA_def_property_ui_range(prop, 0.001, 1.0, 1.0, 4); RNA_def_property_ui_text(prop, "Density", ""); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL); + RNA_def_property_update(prop, 0, NULL); // NC_OBJECT|ND_MODIFIER prop= RNA_def_property(srna, "temperature", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "temp"); RNA_def_property_range(prop, -10, 10); RNA_def_property_ui_range(prop, -10, 10, 1, 1); RNA_def_property_ui_text(prop, "Temp. Diff.", "Temperature difference to ambientt temperature."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL); + RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "psys", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "psys"); RNA_def_property_struct_type(prop, "ParticleSystem"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object."); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset_dependancy"); + RNA_def_property_update(prop, 0, "rna_Smoke_reset_dependancy"); prop= RNA_def_property(srna, "outflow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "type", MOD_SMOKE_FLOW_TYPE_OUTFLOW); RNA_def_property_ui_text(prop, "Outflow", "Deletes smoke from simulation"); - RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL); + RNA_def_property_update(prop, 0, NULL); } static void rna_def_smoke_coll_settings(BlenderRNA *brna) -- cgit v1.2.3 From 939b72247d536de0f09b526403c91cb7044cccca Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 9 Sep 2009 19:31:43 +0000 Subject: 2.5: * Scons compile fix for recent smoke commit. --- source/blender/gpu/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index e55fbe973f8..7e700c177e4 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -4,7 +4,7 @@ Import ('env') sources = env.Glob('intern/*.c') incs = '../blenlib ../blenkernel ../makesdna ../include' -incs += ' #/extern/glew/include #intern/guardedalloc ../imbuf .' +incs += ' #/extern/glew/include #intern/guardedalloc #intern/smoke/extern ../imbuf .' incs += ' ' + env['BF_OPENGL_INC'] -- cgit v1.2.3 From 297a53ebf833ebee7de8bd66a11d7cfe19f3ea8e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 19:40:46 +0000 Subject: RNA: multidimensional & dyanmic array changes * Disable setting array length of dynamic array for now, this was not implemented correct, and it's not really needed now. * Allow all dimensions to be dynamic size, not just the first. * Change storage of multidimensional to be simpler. * Rename API functions to be more compact. * Fix some bugs in the implementation. * RenderLayer.rect and RenderPass.rect use a multidimensional dynamic array now. --- source/blender/makesrna/RNA_access.h | 5 +- source/blender/makesrna/RNA_define.h | 8 +- source/blender/makesrna/intern/makesrna.c | 234 ++++++++++-------- source/blender/makesrna/intern/rna_access.c | 273 +++++++++++++-------- source/blender/makesrna/intern/rna_define.c | 116 +++++---- .../blender/makesrna/intern/rna_internal_types.h | 19 +- source/blender/makesrna/intern/rna_mesh.c | 52 ++-- source/blender/makesrna/intern/rna_object.c | 4 +- source/blender/makesrna/intern/rna_render.c | 62 +++-- source/blender/makesrna/intern/rna_rna.c | 2 +- source/blender/python/intern/bpy_array.c | 69 +++--- source/blender/python/intern/bpy_rna.c | 8 +- 12 files changed, 475 insertions(+), 377 deletions(-) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 4107c1346e5..05f39d73842 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -586,10 +586,9 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop); int RNA_property_flag(PropertyRNA *prop); int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop); -int RNA_property_multidimensional_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension); -int RNA_property_dynamic_array_set_length(PointerRNA *ptr, PropertyRNA *prop, int length); +int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension); +int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]); char RNA_property_array_item_char(PropertyRNA *prop, int index); -unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short dim_size[]); int RNA_property_string_maxlength(PropertyRNA *prop); diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 03b12da1629..42c5343dbff 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -90,7 +90,7 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc); PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); -PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont, const char *identifier, int len, int rowsize, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); +PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont, const char *identifier, int rows, int columns, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, @@ -128,8 +128,8 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, void RNA_def_property_flag(PropertyRNA *prop, int flag); void RNA_def_property_clear_flag(PropertyRNA *prop, int flag); -void RNA_def_property_array(PropertyRNA *prop, int arraylength); -void RNA_def_property_multidimensional_array(PropertyRNA *prop, int arraylength, unsigned short arraydimension, unsigned short dimsize[]); +void RNA_def_property_array(PropertyRNA *prop, int length); +void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, int length[]); void RNA_def_property_range(PropertyRNA *prop, double min, double max); void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item); @@ -153,7 +153,7 @@ void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive); void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *updatefunc); void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable); -void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength, const char *setlength); +void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength); void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set); void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range); void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range); diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index cbfd7d326de..a3c4af26478 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -306,11 +306,10 @@ static void rna_int_print(FILE *f, int num) static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, const char *manualfunc) { char *func; - int i; if(prop->flag & PROP_IDPROPERTY) return NULL; - + if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { fprintf(stderr, "rna_def_property_get_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); @@ -373,8 +372,11 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr break; } default: - if(prop->arraylength) { - fprintf(f, "void %s(PointerRNA *ptr, %s values[%d])\n", func, rna_type_type(prop), prop->arraylength); + if(prop->arraydimension) { + if(prop->flag & PROP_DYNAMIC) + fprintf(f, "void %s(PointerRNA *ptr, %s values[])\n", func, rna_type_type(prop)); + else + fprintf(f, "void %s(PointerRNA *ptr, %s values[%d])\n", func, rna_type_type(prop), prop->totarraylength); fprintf(f, "{\n"); if(manualfunc) { @@ -383,27 +385,38 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr else { rna_print_data_get(f, dp); - for(i=0; iarraylength; i++) { - if(dp->dnaarraylength == 1) { - if(prop->type == PROP_BOOLEAN && dp->booleanbit) - fprintf(f, " values[%d]= (%s(data->%s & (%d<<%d)) != 0);\n", i, (dp->booleannegative)? "!": "", dp->dnaname, dp->booleanbit, i); - else - fprintf(f, " values[%d]= (%s)%s((&data->%s)[%d]);\n", i, rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname, i); - } - else { - if(prop->type == PROP_BOOLEAN && dp->booleanbit) { - fprintf(f, " values[%d]= (%s(data->%s[%d] & ", i, (dp->booleannegative)? "!": "", dp->dnaname, i); - rna_int_print(f, dp->booleanbit); - fprintf(f, ") != 0);\n"); - } - else if(rna_color_quantize(prop, dp)) - fprintf(f, " values[%d]= (%s)(data->%s[%d]*(1.0f/255.0f));\n", i, rna_type_type(prop), dp->dnaname, i); - else if(dp->dnatype) - fprintf(f, " values[%d]= (%s)%s(((%s*)data->%s)[%d]);\n", i, rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnatype, dp->dnaname, i); - else - fprintf(f, " values[%d]= (%s)%s((data->%s)[%d]);\n", i, rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname, i); + if(prop->flag & PROP_DYNAMIC) { + char *lenfunc= rna_alloc_function_name(srna->identifier, prop->identifier, "get_length"); + fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); + fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc); + fprintf(f, " for(i=0; itotarraylength); + } + + if(dp->dnaarraylength == 1) { + if(prop->type == PROP_BOOLEAN && dp->booleanbit) + fprintf(f, " values[i]= (%s(data->%s & (%d<booleannegative)? "!": "", dp->dnaname, dp->booleanbit); + else + fprintf(f, " values[i]= (%s)%s((&data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname); + } + else { + if(prop->type == PROP_BOOLEAN && dp->booleanbit) { + fprintf(f, " values[i]= (%s(data->%s[i] & ", (dp->booleannegative)? "!": "", dp->dnaname); + rna_int_print(f, dp->booleanbit); + fprintf(f, ") != 0);\n"); } + else if(rna_color_quantize(prop, dp)) + fprintf(f, " values[i]= (%s)(data->%s[i]*(1.0f/255.0f));\n", rna_type_type(prop), dp->dnaname); + else if(dp->dnatype) + fprintf(f, " values[i]= (%s)%s(((%s*)data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnatype, dp->dnaname); + else + fprintf(f, " values[i]= (%s)%s((data->%s)[i]);\n", rna_type_type(prop), (dp->booleannegative)? "!": "", dp->dnaname); } + fprintf(f, " }\n"); } fprintf(f, "}\n\n"); } @@ -438,13 +451,13 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr return func; } -static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array, int i) +static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array) { if(prop->type == PROP_INT) { IntPropertyRNA *iprop= (IntPropertyRNA*)prop; if(iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) { - if(array) fprintf(f, "CLAMPIS(values[%d], ", i); + if(array) fprintf(f, "CLAMPIS(values[i], "); else fprintf(f, "CLAMPIS(value, "); rna_int_print(f, iprop->hardmin); fprintf(f, ", "); rna_int_print(f, iprop->hardmax); fprintf(f, ");\n"); @@ -455,7 +468,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array, int i) FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; if(fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) { - if(array) fprintf(f, "CLAMPIS(values[%d], ", i); + if(array) fprintf(f, "CLAMPIS(values[i], "); else fprintf(f, "CLAMPIS(value, "); rna_float_print(f, fprop->hardmin); fprintf(f, ", "); rna_float_print(f, fprop->hardmax); fprintf(f, ");\n"); @@ -464,7 +477,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array, int i) } if(array) - fprintf(f, "values[%d];\n", i); + fprintf(f, "values[i];\n"); else fprintf(f, "value;\n"); } @@ -472,7 +485,6 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array, int i) static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc) { char *func; - int i; if(!(prop->flag & PROP_EDITABLE)) return NULL; @@ -532,8 +544,11 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr break; } default: - if(prop->arraylength) { - fprintf(f, "void %s(PointerRNA *ptr, const %s values[%d])\n", func, rna_type_type(prop), prop->arraylength); + if(prop->arraydimension) { + if(prop->flag & PROP_DYNAMIC) + fprintf(f, "void %s(PointerRNA *ptr, const %s values[])\n", func, rna_type_type(prop)); + else + fprintf(f, "void %s(PointerRNA *ptr, const %s values[%d])\n", func, rna_type_type(prop), prop->totarraylength); fprintf(f, "{\n"); if(manualfunc) { @@ -542,38 +557,49 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr else { rna_print_data_get(f, dp); - for(i=0; iarraylength; i++) { - if(dp->dnaarraylength == 1) { - if(prop->type == PROP_BOOLEAN && dp->booleanbit) { - fprintf(f, " if(%svalues[%d]) data->%s |= (%d<<%d);\n", (dp->booleannegative)? "!": "", i, dp->dnaname, dp->booleanbit, i); - fprintf(f, " else data->%s &= ~(%d<<%d);\n", dp->dnaname, dp->booleanbit, i); - } - else { - fprintf(f, " (&data->%s)[%d]= %s", dp->dnaname, i, (dp->booleannegative)? "!": ""); - rna_clamp_value(f, prop, 1, i); - } + if(prop->flag & PROP_DYNAMIC) { + char *lenfunc= rna_alloc_function_name(srna->identifier, prop->identifier, "set_length"); + fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); + fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc); + fprintf(f, " for(i=0; itotarraylength); + } + + if(dp->dnaarraylength == 1) { + if(prop->type == PROP_BOOLEAN && dp->booleanbit) { + fprintf(f, " if(%svalues[i]) data->%s |= (%d<booleannegative)? "!": "", dp->dnaname, dp->booleanbit); + fprintf(f, " else data->%s &= ~(%d<dnaname, dp->booleanbit); + } + else { + fprintf(f, " (&data->%s)[i]= %s", dp->dnaname, (dp->booleannegative)? "!": ""); + rna_clamp_value(f, prop, 1); + } + } + else { + if(prop->type == PROP_BOOLEAN && dp->booleanbit) { + fprintf(f, " if(%svalues[i]) data->%s[i] |= ", (dp->booleannegative)? "!": "", dp->dnaname); + rna_int_print(f, dp->booleanbit); + fprintf(f, ";\n"); + fprintf(f, " else data->%s[i] &= ~", dp->dnaname); + rna_int_print(f, dp->booleanbit); + fprintf(f, ";\n"); + } + else if(rna_color_quantize(prop, dp)) { + fprintf(f, " data->%s[i]= FTOCHAR(values[i]);\n", dp->dnaname); } else { - if(prop->type == PROP_BOOLEAN && dp->booleanbit) { - fprintf(f, " if(%svalues[%d]) data->%s[%d] |= ", (dp->booleannegative)? "!": "", i, dp->dnaname, i); - rna_int_print(f, dp->booleanbit); - fprintf(f, ";\n"); - fprintf(f, " else data->%s[%d] &= ~", dp->dnaname, i); - rna_int_print(f, dp->booleanbit); - fprintf(f, ";\n"); - } - else if(rna_color_quantize(prop, dp)) { - fprintf(f, " data->%s[%d]= FTOCHAR(values[%d]);\n", dp->dnaname, i, i); - } - else { - if(dp->dnatype) - fprintf(f, " ((%s*)data->%s)[%d]= %s", dp->dnatype, dp->dnaname, i, (dp->booleannegative)? "!": ""); - else - fprintf(f, " (data->%s)[%d]= %s", dp->dnaname, i, (dp->booleannegative)? "!": ""); - rna_clamp_value(f, prop, 1, i); - } + if(dp->dnatype) + fprintf(f, " ((%s*)data->%s)[i]= %s", dp->dnatype, dp->dnaname, (dp->booleannegative)? "!": ""); + else + fprintf(f, " (data->%s)[i]= %s", dp->dnaname, (dp->booleannegative)? "!": ""); + rna_clamp_value(f, prop, 1); } } + fprintf(f, " }\n"); } fprintf(f, "}\n\n"); } @@ -602,7 +628,7 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr } else { fprintf(f, " data->%s= %s", dp->dnaname, (dp->booleannegative)? "!": ""); - rna_clamp_value(f, prop, 0, 0); + rna_clamp_value(f, prop, 0); } } fprintf(f, "}\n\n"); @@ -819,7 +845,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) case PROP_BOOLEAN: { BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; - if(!prop->arraylength) { + if(!prop->arraydimension) { if(!bprop->get && !bprop->set && !dp->booleanbit) rna_set_raw_property(dp, prop); @@ -835,7 +861,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) case PROP_INT: { IntPropertyRNA *iprop= (IntPropertyRNA*)prop; - if(!prop->arraylength) { + if(!prop->arraydimension) { if(!iprop->get && !iprop->set) rna_set_raw_property(dp, prop); @@ -854,7 +880,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) case PROP_FLOAT: { FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; - if(!prop->arraylength) { + if(!prop->arraydimension) { if(!fprop->get && !fprop->set) rna_set_raw_property(dp, prop); @@ -953,23 +979,23 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR switch(prop->type) { case PROP_BOOLEAN: case PROP_INT: { - if(!prop->arraylength) { + if(!prop->arraydimension) { fprintf(f, "int %sget(PointerRNA *ptr);\n", func); //fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func); } else { - fprintf(f, "void %sget(PointerRNA *ptr, int values[%d]);\n", func, prop->arraylength); + fprintf(f, "void %sget(PointerRNA *ptr, int values[%d]);\n", func, prop->totarraylength); //fprintf(f, "void %sset(PointerRNA *ptr, const int values[%d]);\n", func, prop->arraylength); } break; } case PROP_FLOAT: { - if(!prop->arraylength) { + if(!prop->arraydimension) { fprintf(f, "float %sget(PointerRNA *ptr);\n", func); //fprintf(f, "void %sset(PointerRNA *ptr, float value);\n", func); } else { - fprintf(f, "void %sget(PointerRNA *ptr, float values[%d]);\n", func, prop->arraylength); + fprintf(f, "void %sget(PointerRNA *ptr, float values[%d]);\n", func, prop->totarraylength); //fprintf(f, "void %sset(PointerRNA *ptr, const float values[%d]);\n", func, prop->arraylength); } break; @@ -1043,24 +1069,24 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property switch(prop->type) { case PROP_BOOLEAN: { - if(!prop->arraylength) + if(!prop->arraydimension) fprintf(f, "\tbool %s(void);", prop->identifier); else - fprintf(f, "\tArray %s(void);", prop->arraylength, prop->identifier); + fprintf(f, "\tArray %s(void);", prop->totarraylength, prop->identifier); break; } case PROP_INT: { - if(!prop->arraylength) + if(!prop->arraydimension) fprintf(f, "\tint %s(void);", prop->identifier); else - fprintf(f, "\tArray %s(void);", prop->arraylength, prop->identifier); + fprintf(f, "\tArray %s(void);", prop->totarraylength, prop->identifier); break; } case PROP_FLOAT: { - if(!prop->arraylength) + if(!prop->arraydimension) fprintf(f, "\tfloat %s(void);", prop->identifier); else - fprintf(f, "\tArray %s(void);", prop->arraylength, prop->identifier); + fprintf(f, "\tArray %s(void);", prop->totarraylength, prop->identifier); break; } case PROP_ENUM: { @@ -1118,24 +1144,24 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe switch(prop->type) { case PROP_BOOLEAN: { - if(!prop->arraylength) + if(!prop->arraydimension) fprintf(f, "\tBOOLEAN_PROPERTY(%s, %s)", srna->identifier, prop->identifier); else - fprintf(f, "\tBOOLEAN_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier); + fprintf(f, "\tBOOLEAN_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->totarraylength, prop->identifier); break; } case PROP_INT: { - if(!prop->arraylength) + if(!prop->arraydimension) fprintf(f, "\tINT_PROPERTY(%s, %s)", srna->identifier, prop->identifier); else - fprintf(f, "\tINT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier); + fprintf(f, "\tINT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->totarraylength, prop->identifier); break; } case PROP_FLOAT: { - if(!prop->arraylength) + if(!prop->arraydimension) fprintf(f, "\tFLOAT_PROPERTY(%s, %s)", srna->identifier, prop->identifier); else - fprintf(f, "\tFLOAT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier); + fprintf(f, "\tFLOAT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->totarraylength, prop->identifier); break; } case PROP_ENUM: { @@ -1198,7 +1224,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm= dfunc->cont.properties.first; for(; dparm; dparm= dparm->next) { - if(dparm->prop->arraylength > 0) + if(dparm->prop->arraydimension) ptrstr= "*"; else if(dparm->prop==func->ret) ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "*": ""; @@ -1225,7 +1251,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA for(; dparm; dparm= dparm->next) { if(dparm->prop==func->ret) fprintf(f, "\t_retdata= _data;\n"); - else if(dparm->prop->arraylength) + else if(dparm->prop->arraydimension) fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); else if(dparm->prop->type == PROP_POINTER) { if(dparm->prop->flag & PROP_RNAPTR) @@ -1280,7 +1306,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA if(func->ret) { dparm= rna_find_parameter_def(func->ret); - ptrstr= (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) || (dparm->prop->arraylength > 0))? "*": ""; + ptrstr= (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) || (dparm->prop->arraydimension))? "*": ""; fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->ret->identifier); } } @@ -1522,7 +1548,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA /* return type */ for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) { if(dparm->prop==func->ret) { - if(dparm->prop->arraylength) + if(dparm->prop->arraydimension) fprintf(f, "XXX no array return types yet"); /* XXX not supported */ else if(dparm->prop->type == PROP_POINTER && !(dparm->prop->flag & PROP_RNAPTR)) fprintf(f, "%s%s *", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); @@ -1569,8 +1595,8 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA if(!first) fprintf(f, ", "); first= 0; - if(dparm->prop->arraylength) - fprintf(f, "%s%s %s[%d]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier, dparm->prop->arraylength); + if(dparm->prop->arraydimension) + fprintf(f, "%s%s %s[%d]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier, dparm->prop->totarraylength); else if(dparm->prop->type == PROP_POINTER) fprintf(f, "%s%s *%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier); else @@ -1653,15 +1679,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; unsigned int i; - if(prop->arraylength) { - fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->arraylength); + if(prop->arraydimension) { + fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->totarraylength); - for(i=0; iarraylength; i++) { + for(i=0; itotarraylength; i++) { if(bprop->defaultarray) fprintf(f, "%d", bprop->defaultarray[i]); else fprintf(f, "%d", bprop->defaultvalue); - if(i != prop->arraylength-1) + if(i != prop->totarraylength-1) fprintf(f, ", "); } @@ -1673,15 +1699,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr IntPropertyRNA *iprop= (IntPropertyRNA*)prop; unsigned int i; - if(prop->arraylength) { - fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->arraylength); + if(prop->arraydimension) { + fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->totarraylength); - for(i=0; iarraylength; i++) { + for(i=0; itotarraylength; i++) { if(iprop->defaultarray) fprintf(f, "%d", iprop->defaultarray[i]); else fprintf(f, "%d", iprop->defaultvalue); - if(i != prop->arraylength-1) + if(i != prop->totarraylength-1) fprintf(f, ", "); } @@ -1693,15 +1719,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; unsigned int i; - if(prop->arraylength) { - fprintf(f, "static float rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->arraylength); + if(prop->arraydimension) { + fprintf(f, "static float rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->totarraylength); - for(i=0; iarraylength; i++) { + for(i=0; itotarraylength; i++) { if(fprop->defaultarray) rna_float_print(f, fprop->defaultarray[i]); else rna_float_print(f, fprop->defaultvalue); - if(i != prop->arraylength-1) + if(i != prop->totarraylength-1) fprintf(f, ", "); } @@ -1725,15 +1751,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr rna_print_c_string(f, prop->name); fprintf(f, ",\n\t"); rna_print_c_string(f, prop->description); fprintf(f, ",\n\t"); fprintf(f, "%d,\n", prop->icon); - fprintf(f, "\t%s, %s|%s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), prop->arraylength); - { - int i; - int tot= sizeof(prop->dimsize) / sizeof(prop->dimsize[0]); - fprintf(f, "\t%s, %s, %d, {", rna_function_string(prop->getlength), rna_function_string(prop->setlength), (int)prop->arraydimension); - for(i= 0; i < tot; i++) { - fprintf(f, i == tot - 1 ? "%d},\n" : "%d, ", (int)prop->dimsize[i]); - } - } + fprintf(f, "\t%s, %s|%s, %s, %d, {%d, %d, %d}, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), rna_function_string(prop->getlength), prop->arraydimension, prop->arraylength[0], prop->arraylength[1], prop->arraylength[2], prop->totarraylength); fprintf(f, "\t%s, %d, %s,\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable)); if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop); @@ -1744,7 +1762,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_BOOLEAN: { BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %d, ", rna_function_string(bprop->get), rna_function_string(bprop->set), rna_function_string(bprop->getarray), rna_function_string(bprop->setarray), bprop->defaultvalue); - if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); + if(prop->arraydimension) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; } @@ -1757,7 +1775,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr rna_int_print(f, iprop->hardmax); fprintf(f, ", "); rna_int_print(f, iprop->step); fprintf(f, ", "); rna_int_print(f, iprop->defaultvalue); fprintf(f, ", "); - if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); + if(prop->arraydimension) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; } @@ -1771,7 +1789,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr rna_float_print(f, fprop->step); fprintf(f, ", "); rna_int_print(f, (int)fprop->precision); fprintf(f, ", "); rna_float_print(f, fprop->defaultvalue); fprintf(f, ", "); - if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); + if(prop->arraydimension) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; } diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index f37fa01480c..417ace6a455 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -209,7 +209,41 @@ static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name) return NULL; } -static int rna_idproperty_verify_valid(PropertyRNA *prop, IDProperty *idprop) +static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop) +{ + if(prop->magic == RNA_MAGIC) { + int arraylen[RNA_MAX_ARRAY_DIMENSION]; + return (prop->getlength)? prop->getlength(ptr, arraylen): prop->totarraylength; + } + else { + IDProperty *idprop= (IDProperty*)prop; + + if(idprop->type == IDP_ARRAY) + return idprop->len; + else + return 0; + } +} + +static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[]) +{ + if(prop->magic == RNA_MAGIC) { + if(prop->getlength) + prop->getlength(ptr, length); + else + memcpy(length, prop->arraylength, prop->arraydimension*sizeof(int)); + } + else { + IDProperty *idprop= (IDProperty*)prop; + + if(idprop->type == IDP_ARRAY) + length[0]= idprop->len; + else + length[0]= 0; + } +} + +static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop) { /* this verifies if the idproperty actually matches the property * description and otherwise removes it. this is to ensure that @@ -222,7 +256,7 @@ static int rna_idproperty_verify_valid(PropertyRNA *prop, IDProperty *idprop) return 0; break; case IDP_ARRAY: - if(prop->arraylength != idprop->len) + if(rna_ensure_property_array_length(ptr, prop) != idprop->len) return 0; if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT) @@ -283,7 +317,7 @@ IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr) if((*prop)->flag & PROP_IDPROPERTY) { IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier); - if(idprop && !rna_idproperty_verify_valid(*prop, idprop)) { + if(idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) { IDProperty *group= RNA_struct_idproperties(ptr, 0); IDP_RemFromGroup(group, idprop); @@ -310,7 +344,7 @@ IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr) } } -PropertyRNA *rna_ensure_property(PropertyRNA *prop) +static PropertyRNA *rna_ensure_property(PropertyRNA *prop) { /* the quick version if we don't need the idproperty */ @@ -327,7 +361,7 @@ PropertyRNA *rna_ensure_property(PropertyRNA *prop) } } -const char *rna_ensure_property_identifier(PropertyRNA *prop) +static const char *rna_ensure_property_identifier(PropertyRNA *prop) { if(prop->magic == RNA_MAGIC) return prop->identifier; @@ -335,7 +369,7 @@ const char *rna_ensure_property_identifier(PropertyRNA *prop) return ((IDProperty*)prop)->name; } -const char *rna_ensure_property_name(PropertyRNA *prop) +static const char *rna_ensure_property_name(PropertyRNA *prop) { if(prop->magic == RNA_MAGIC) return prop->name; @@ -343,21 +377,6 @@ const char *rna_ensure_property_name(PropertyRNA *prop) return ((IDProperty*)prop)->name; } -int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop) -{ - if(prop->magic == RNA_MAGIC) { - return prop->getlength ? prop->getlength(ptr) : prop->arraylength; - } - else { - IDProperty *idprop= (IDProperty*)prop; - - if(idprop->type == IDP_ARRAY) - return idprop->len; - else - return 0; - } -} - /* Structs */ const char *RNA_struct_identifier(StructRNA *type) @@ -555,51 +574,25 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop) return rna_ensure_property_array_length(ptr, prop); } -int RNA_property_dynamic_array_set_length(PointerRNA *ptr, PropertyRNA *prop, int length) +/* used by BPY to make an array from the python object */ +int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]) { - /* length 0 is not allowed */ - if (!length) - return 0; - - if (prop->getlength) { - if (prop->setlength) - return prop->setlength(ptr, length); - else - /* length cannot be changed */ - return 0; - } - else - prop->arraylength= length; /* function parameters only? */ + PropertyRNA *rprop= rna_ensure_property(prop); - return 1; -} + if(length && rprop->arraydimension > 1) + rna_ensure_property_multi_array_length(ptr, prop, length); -/* used by BPY to make an array from the python object */ -unsigned short RNA_property_array_dimension(PropertyRNA *prop, unsigned short dimsize[]) -{ - if (dimsize && prop->arraydimension > 1) { - memcpy(dimsize, prop->dimsize, sizeof(prop->dimsize[0]) * (prop->arraydimension - 1)); - } - return prop->arraydimension; + return rprop->arraydimension; } /* Return the size of Nth dimension. */ -int RNA_property_multidimensional_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim) +int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim) { - unsigned short i; - int len; + int len[RNA_MAX_ARRAY_DIMENSION]; - if (dim == 0) { - len= RNA_property_array_length(ptr, prop); + rna_ensure_property_multi_array_length(ptr, prop, len); - for (i= 0; i < prop->arraydimension - 1; i++) - len /= prop->dimsize[i]; - } - else { - len= prop->dimsize[dim - 1]; - } - - return len; + return len[dim]; } char RNA_property_array_item_char(PropertyRNA *prop, int index) @@ -902,27 +895,40 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val IDProperty *idprop; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(prop->arraylength == 0) + if(prop->arraydimension == 0) values[0]= RNA_property_boolean_get(ptr, prop); else memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len); } - else if(prop->arraylength == 0) + else if(prop->arraydimension == 0) values[0]= RNA_property_boolean_get(ptr, prop); else if(bprop->getarray) bprop->getarray(ptr, values); else if(bprop->defaultarray) - memcpy(values, bprop->defaultarray, sizeof(int)*prop->arraylength); + memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength); else - memset(values, 0, sizeof(int)*prop->arraylength); + memset(values, 0, sizeof(int)*prop->totarraylength); } int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index) { - int tmp[RNA_MAX_ARRAY]; + int tmp[RNA_MAX_ARRAY_LENGTH]; + int len= rna_ensure_property_array_length(ptr, prop); + + if(len <= RNA_MAX_ARRAY_LENGTH) { + RNA_property_boolean_get_array(ptr, prop, tmp); + return tmp[index]; + } + else { + int *tmparray, value; - RNA_property_boolean_get_array(ptr, prop, tmp); - return tmp[index]; + tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index"); + RNA_property_boolean_get_array(ptr, prop, tmparray); + value= tmparray[index]; + MEM_freeN(tmparray); + + return value; + } } void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values) @@ -931,12 +937,12 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in IDProperty *idprop; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(prop->arraylength == 0) + if(prop->arraydimension == 0) IDP_Int(idprop)= values[0]; else memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len); } - else if(prop->arraylength == 0) + else if(prop->arraydimension == 0) RNA_property_boolean_set(ptr, prop, values[0]); else if(bprop->setarray) bprop->setarray(ptr, values); @@ -944,7 +950,7 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in IDPropertyTemplate val = {0}; IDProperty *group; - val.array.len= prop->arraylength; + val.array.len= prop->totarraylength; val.array.type= IDP_INT; group= RNA_struct_idproperties(ptr, 1); @@ -958,11 +964,23 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value) { - int tmp[RNA_MAX_ARRAY]; + int tmp[RNA_MAX_ARRAY_LENGTH]; + int len= rna_ensure_property_array_length(ptr, prop); + + if(len <= RNA_MAX_ARRAY_LENGTH) { + RNA_property_boolean_get_array(ptr, prop, tmp); + tmp[index]= value; + RNA_property_boolean_set_array(ptr, prop, tmp); + } + else { + int *tmparray; - RNA_property_boolean_get_array(ptr, prop, tmp); - tmp[index]= value; - RNA_property_boolean_set_array(ptr, prop, tmp); + tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index"); + RNA_property_boolean_get_array(ptr, prop, tmparray); + tmparray[index]= value; + RNA_property_boolean_set_array(ptr, prop, tmparray); + MEM_freeN(tmparray); + } } int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop) @@ -1005,27 +1023,40 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values) IDProperty *idprop; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(prop->arraylength == 0) + if(prop->arraydimension == 0) values[0]= RNA_property_int_get(ptr, prop); else memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len); } - else if(prop->arraylength == 0) + else if(prop->arraydimension == 0) values[0]= RNA_property_int_get(ptr, prop); else if(iprop->getarray) iprop->getarray(ptr, values); else if(iprop->defaultarray) - memcpy(values, iprop->defaultarray, sizeof(int)*prop->arraylength); + memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength); else - memset(values, 0, sizeof(int)*prop->arraylength); + memset(values, 0, sizeof(int)*prop->totarraylength); } int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index) { - int tmp[RNA_MAX_ARRAY]; + int tmp[RNA_MAX_ARRAY_LENGTH]; + int len= rna_ensure_property_array_length(ptr, prop); + + if(len <= RNA_MAX_ARRAY_LENGTH) { + RNA_property_int_get_array(ptr, prop, tmp); + return tmp[index]; + } + else { + int *tmparray, value; + + tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index"); + RNA_property_int_get_array(ptr, prop, tmparray); + value= tmparray[index]; + MEM_freeN(tmparray); - RNA_property_int_get_array(ptr, prop, tmp); - return tmp[index]; + return value; + } } void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values) @@ -1034,12 +1065,12 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v IDProperty *idprop; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(prop->arraylength == 0) + if(prop->arraydimension == 0) IDP_Int(idprop)= values[0]; else memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\ } - else if(prop->arraylength == 0) + else if(prop->arraydimension == 0) RNA_property_int_set(ptr, prop, values[0]); else if(iprop->setarray) iprop->setarray(ptr, values); @@ -1047,7 +1078,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v IDPropertyTemplate val = {0}; IDProperty *group; - val.array.len= prop->arraylength; + val.array.len= prop->totarraylength; val.array.type= IDP_INT; group= RNA_struct_idproperties(ptr, 1); @@ -1061,11 +1092,23 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value) { - int tmp[RNA_MAX_ARRAY]; + int tmp[RNA_MAX_ARRAY_LENGTH]; + int len= rna_ensure_property_array_length(ptr, prop); - RNA_property_int_get_array(ptr, prop, tmp); - tmp[index]= value; - RNA_property_int_set_array(ptr, prop, tmp); + if(len <= RNA_MAX_ARRAY_LENGTH) { + RNA_property_int_get_array(ptr, prop, tmp); + tmp[index]= value; + RNA_property_int_set_array(ptr, prop, tmp); + } + else { + int *tmparray; + + tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index"); + RNA_property_int_get_array(ptr, prop, tmparray); + tmparray[index]= value; + RNA_property_int_set_array(ptr, prop, tmparray); + MEM_freeN(tmparray); + } } float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop) @@ -1118,7 +1161,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val int i; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(prop->arraylength == 0) + if(prop->arraydimension == 0) values[0]= RNA_property_float_get(ptr, prop); else if(idprop->subtype == IDP_FLOAT) { memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len); @@ -1128,22 +1171,36 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val values[i]= (float)(((double*)IDP_Array(idprop))[i]); } } - else if(prop->arraylength == 0) + else if(prop->arraydimension == 0) values[0]= RNA_property_float_get(ptr, prop); else if(fprop->getarray) fprop->getarray(ptr, values); else if(fprop->defaultarray) - memcpy(values, fprop->defaultarray, sizeof(float)*prop->arraylength); + memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength); else - memset(values, 0, sizeof(float)*prop->arraylength); + memset(values, 0, sizeof(float)*prop->totarraylength); } float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index) { - float tmp[RNA_MAX_ARRAY]; + float tmp[RNA_MAX_ARRAY_LENGTH]; + int len= rna_ensure_property_array_length(ptr, prop); + + if(len <= RNA_MAX_ARRAY_LENGTH) { + RNA_property_float_get_array(ptr, prop, tmp); + return tmp[index]; + } + else { + float *tmparray, value; + + tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index"); + RNA_property_float_get_array(ptr, prop, tmparray); + value= tmparray[index]; + MEM_freeN(tmparray); + + return value; + } - RNA_property_float_get_array(ptr, prop, tmp); - return tmp[index]; } void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values) @@ -1153,7 +1210,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa int i; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(prop->arraylength == 0) + if(prop->arraydimension == 0) IDP_Double(idprop)= values[0]; else if(idprop->subtype == IDP_FLOAT) { memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len); @@ -1163,7 +1220,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa ((double*)IDP_Array(idprop))[i]= values[i]; } } - else if(prop->arraylength == 0) + else if(prop->arraydimension == 0) RNA_property_float_set(ptr, prop, values[0]); else if(fprop->setarray) { fprop->setarray(ptr, values); @@ -1172,7 +1229,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa IDPropertyTemplate val = {0}; IDProperty *group; - val.array.len= prop->arraylength; + val.array.len= prop->totarraylength; val.array.type= IDP_FLOAT; group= RNA_struct_idproperties(ptr, 1); @@ -1186,11 +1243,23 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value) { - float tmp[RNA_MAX_ARRAY]; + float tmp[RNA_MAX_ARRAY_LENGTH]; + int len= rna_ensure_property_array_length(ptr, prop); - RNA_property_float_get_array(ptr, prop, tmp); - tmp[index]= value; - RNA_property_float_set_array(ptr, prop, tmp); + if(len <= RNA_MAX_ARRAY_LENGTH) { + RNA_property_float_get_array(ptr, prop, tmp); + tmp[index]= value; + RNA_property_float_set_array(ptr, prop, tmp); + } + else { + float *tmparray; + + tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index"); + RNA_property_float_get_array(ptr, prop, tmparray); + tmparray[index]= value; + RNA_property_float_set_array(ptr, prop, tmparray); + MEM_freeN(tmparray); + } } void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value) @@ -2912,15 +2981,15 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, if(!(parm->flag & PROP_REQUIRED)) { switch(parm->type) { case PROP_BOOLEAN: - if(parm->arraylength) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size); + if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size); else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size); break; case PROP_INT: - if(parm->arraylength) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size); + if(parm->arraydimension) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size); else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size); break; case PROP_FLOAT: - if(parm->arraylength) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size); + if(parm->arraydimension) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size); else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size); break; case PROP_ENUM: diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 00cfb17dc84..8d05cbde74c 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -1001,18 +1001,18 @@ void RNA_def_property_clear_flag(PropertyRNA *prop, int flag) prop->flag &= ~flag; } -void RNA_def_property_array(PropertyRNA *prop, int arraylength) +void RNA_def_property_array(PropertyRNA *prop, int length) { StructRNA *srna= DefRNA.laststruct; - if(arraylength<0) { + if(length<0) { fprintf(stderr, "RNA_def_property_array: %s.%s, array length must be zero of greater.\n", srna->identifier, prop->identifier); DefRNA.error= 1; return; } - if(arraylength>RNA_MAX_ARRAY) { - fprintf(stderr, "RNA_def_property_array: %s.%s, array length must be smaller than %d.\n", srna->identifier, prop->identifier, RNA_MAX_ARRAY); + if(length>RNA_MAX_ARRAY_LENGTH) { + fprintf(stderr, "RNA_def_property_array: %s.%s, array length must be smaller than %d.\n", srna->identifier, prop->identifier, RNA_MAX_ARRAY_LENGTH); DefRNA.error= 1; return; } @@ -1021,35 +1021,53 @@ void RNA_def_property_array(PropertyRNA *prop, int arraylength) case PROP_BOOLEAN: case PROP_INT: case PROP_FLOAT: - prop->arraylength= arraylength; + prop->arraylength[0]= length; + prop->totarraylength= length; + prop->arraydimension= 1; break; default: fprintf(stderr, "RNA_def_property_array: %s.%s, only boolean/int/float can be array.\n", srna->identifier, prop->identifier); DefRNA.error= 1; break; } - - prop->arraydimension= 1; } -void RNA_def_property_multidimensional_array(PropertyRNA *prop, int arraylength, unsigned short dimension, unsigned short dimsize[]) +void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, int length[]) { StructRNA *srna= DefRNA.laststruct; + int i; if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) { - fprintf(stderr, "RNA_def_property_multidimensional_array: %s.%s, array dimension must be between 1 and %d.\n", srna->identifier, prop->identifier, RNA_MAX_ARRAY_DIMENSION); + fprintf(stderr, "RNA_def_property_multi_array: %s.%s, array dimension must be between 1 and %d.\n", srna->identifier, prop->identifier, RNA_MAX_ARRAY_DIMENSION); DefRNA.error= 1; return; } - RNA_def_property_array(prop, arraylength); + switch(prop->type) { + case PROP_BOOLEAN: + case PROP_INT: + case PROP_FLOAT: + break; + default: + fprintf(stderr, "RNA_def_property_multi_array: %s.%s, only boolean/int/float can be array.\n", srna->identifier, prop->identifier); + DefRNA.error= 1; + break; + } prop->arraydimension= dimension; + prop->totarraylength= 0; - /* TODO make sure dimsize values are sane */ + if(length) { + memcpy(prop->arraylength, length, sizeof(int)*dimension); - if (dimension > 1) - memcpy(prop->dimsize, dimsize, sizeof(dimsize[0]) * (dimension - 1)); + prop->totarraylength= length[0]; + for(i=1; itotarraylength *= length[i]; + } + else + memset(prop->arraylength, 0, sizeof(prop->arraylength)); + + /* TODO make sure arraylength values are sane */ } void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description) @@ -1422,10 +1440,15 @@ static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *stru } } - if(smember.arraylength > 1) - prop->arraylength= smember.arraylength; - else - prop->arraylength= 0; + if(smember.arraylength > 1) { + prop->arraylength[0]= smember.arraylength; + prop->totarraylength= smember.arraylength; + prop->arraydimension= 1; + } + else { + prop->arraydimension= 0; + prop->totarraylength= 0; + } dp->dnastructname= structname; dp->dnastructfromname= ds->dnafromname; @@ -1545,8 +1568,10 @@ void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const } if((dp=rna_def_property_sdna(prop, structname, propname))) { - if(prop->arraylength) { - prop->arraylength= 0; + if(prop->arraydimension) { + prop->arraydimension= 0; + prop->totarraylength= 0; + if(!DefRNA.silent) { fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, array not supported for enum type.\n", structname, propname); DefRNA.error= 1; @@ -1585,9 +1610,10 @@ void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, con } if((dp=rna_def_property_sdna(prop, structname, propname))) { - if(prop->arraylength) { - sprop->maxlength= prop->arraylength; - prop->arraylength= 0; + if(prop->arraydimension) { + sprop->maxlength= prop->totarraylength; + prop->arraydimension= 0; + prop->totarraylength= 0; } } } @@ -1609,8 +1635,10 @@ void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, co } if((dp=rna_def_property_sdna(prop, structname, propname))) { - if(prop->arraylength) { - prop->arraylength= 0; + if(prop->arraydimension) { + prop->arraydimension= 0; + prop->totarraylength= 0; + if(!DefRNA.silent) { fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, array not supported for pointer type.\n", structname, propname); DefRNA.error= 1; @@ -1637,8 +1665,9 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, } if((dp=rna_def_property_sdna(prop, structname, propname))) { - if(prop->arraylength && !lengthpropname) { - prop->arraylength= 0; + if(prop->arraydimension && !lengthpropname) { + prop->arraydimension= 0; + prop->totarraylength= 0; if(!DefRNA.silent) { fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, array of collections not supported.\n", structname, propname); @@ -1662,8 +1691,9 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, if(lengthpropname[0] == 0 || rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) { if(lengthpropname[0] == 0) { - dp->dnalengthfixed= prop->arraylength; - prop->arraylength= 0; + dp->dnalengthfixed= prop->totarraylength; + prop->arraydimension= 0; + prop->totarraylength= 0; } else { dp->dnalengthstructname= structname; @@ -1710,7 +1740,7 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func) prop->update= (UpdateFunc)func; } -void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength, const char *setlength) +void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength) { if(!DefRNA.preprocess) { fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n"); @@ -1724,7 +1754,6 @@ void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getleng } if(getlength) prop->getlength= (PropArrayLengthGetFunc)getlength; - if(setlength) prop->setlength= (PropArrayLengthSetFunc)setlength; } void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set) @@ -1740,7 +1769,7 @@ void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const ch case PROP_BOOLEAN: { BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; - if(prop->arraylength) { + if(prop->arraydimension) { if(get) bprop->getarray= (PropBooleanArrayGetFunc)get; if(set) bprop->setarray= (PropBooleanArraySetFunc)set; } @@ -1770,7 +1799,7 @@ void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char * case PROP_INT: { IntPropertyRNA *iprop= (IntPropertyRNA*)prop; - if(prop->arraylength) { + if(prop->arraydimension) { if(get) iprop->getarray= (PropIntArrayGetFunc)get; if(set) iprop->setarray= (PropIntArraySetFunc)set; } @@ -1801,7 +1830,7 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char case PROP_FLOAT: { FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; - if(prop->arraylength) { + if(prop->arraydimension) { if(get) fprop->getarray= (PropFloatArrayGetFunc)get; if(set) fprop->setarray= (PropFloatArraySetFunc)set; } @@ -2152,15 +2181,15 @@ PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identif } -PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int len, int rowsize, const float *default_value, +PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int rows, int columns, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) { ContainerRNA *cont= cont_; PropertyRNA *prop; - unsigned short dimsize[1]= {rowsize}; + int length[2]= {rows, columns}; prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX); - if(len != 0) RNA_def_property_multidimensional_array(prop, len, 2, dimsize); + RNA_def_property_multi_array(prop, 2, length); if(default_value) RNA_def_property_float_array_default(prop, default_value); if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); RNA_def_property_ui_text(prop, ui_name, ui_description); @@ -2357,10 +2386,9 @@ void RNA_def_function_ui_description(FunctionRNA *func, const char *description) int rna_parameter_size(PropertyRNA *parm) { PropertyType ptype= parm->type; - int len= parm->arraylength; + int len= parm->totarraylength; /* only supports fixed length at the moment */ if(len > 0) { - if (parm->flag & PROP_DYNAMIC) return sizeof(void *); @@ -2508,8 +2536,8 @@ void RNA_def_property_duplicate_pointers(PropertyRNA *prop) BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; if(bprop->defaultarray) { - iarray= MEM_callocN(sizeof(int)*prop->arraylength, "RNA_def_property_store"); - memcpy(iarray, bprop->defaultarray, sizeof(int)*prop->arraylength); + iarray= MEM_callocN(sizeof(int)*prop->totarraylength, "RNA_def_property_store"); + memcpy(iarray, bprop->defaultarray, sizeof(int)*prop->totarraylength); bprop->defaultarray= iarray; } break; @@ -2518,8 +2546,8 @@ void RNA_def_property_duplicate_pointers(PropertyRNA *prop) IntPropertyRNA *iprop= (IntPropertyRNA*)prop; if(iprop->defaultarray) { - iarray= MEM_callocN(sizeof(int)*prop->arraylength, "RNA_def_property_store"); - memcpy(iarray, iprop->defaultarray, sizeof(int)*prop->arraylength); + iarray= MEM_callocN(sizeof(int)*prop->totarraylength, "RNA_def_property_store"); + memcpy(iarray, iprop->defaultarray, sizeof(int)*prop->totarraylength); iprop->defaultarray= iarray; } break; @@ -2544,8 +2572,8 @@ void RNA_def_property_duplicate_pointers(PropertyRNA *prop) FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; if(fprop->defaultarray) { - farray= MEM_callocN(sizeof(float)*prop->arraylength, "RNA_def_property_store"); - memcpy(farray, fprop->defaultarray, sizeof(float)*prop->arraylength); + farray= MEM_callocN(sizeof(float)*prop->totarraylength, "RNA_def_property_store"); + memcpy(farray, fprop->defaultarray, sizeof(float)*prop->totarraylength); fprop->defaultarray= farray; } break; diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index 2bd89dbd3bf..645bc50ed89 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -40,9 +40,9 @@ struct IDProperty; struct GHash; #ifdef UNIT_TEST -#define RNA_MAX_ARRAY 64 +#define RNA_MAX_ARRAY_LENGTH 64 #else -#define RNA_MAX_ARRAY 32 +#define RNA_MAX_ARRAY_LENGTH 32 #endif #define RNA_MAX_ARRAY_DIMENSION 3 @@ -55,8 +55,7 @@ typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int creat typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr); typedef char *(*StructPathFunc)(struct PointerRNA *ptr); -typedef int (*PropArrayLengthGetFunc)(struct PointerRNA *ptr); -typedef int (*PropArrayLengthSetFunc)(struct PointerRNA *ptr, int length); +typedef int (*PropArrayLengthGetFunc)(struct PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]); typedef int (*PropBooleanGetFunc)(struct PointerRNA *ptr); typedef void (*PropBooleanSetFunc)(struct PointerRNA *ptr, int value); typedef void (*PropBooleanArrayGetFunc)(struct PointerRNA *ptr, int *values); @@ -137,15 +136,13 @@ struct PropertyRNA { PropertyType type; /* subtype, 'interpretation' of the property */ PropertySubType subtype; - /* if an array this is > 0, specifying the length */ - unsigned int arraylength; /* if non-NULL, overrides arraylength. Must not return 0? */ PropArrayLengthGetFunc getlength; - /* if NULL, length cannot be changed by a user */ - PropArrayLengthSetFunc setlength; - unsigned short arraydimension; - /* dimension sizes for dimensions greater than 1, first dimension size is not specified */ - unsigned short dimsize[RNA_MAX_ARRAY_DIMENSION - 1]; + /* dimension of array */ + unsigned int arraydimension; + /* array lengths lengths for all dimensions (when arraydimension > 0) */ + unsigned int arraylength[RNA_MAX_ARRAY_DIMENSION]; + unsigned int totarraylength; /* callback for updates on change */ UpdateFunc update; diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index efd0046d827..78fb8ede3ee 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -423,14 +423,11 @@ static int rna_CustomDataData_numverts(PointerRNA *ptr, int type) return 0; } -static int rna_MeshTextureFace_uv_get_length(PointerRNA *ptr) +static int rna_MeshTextureFace_uv_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { - return rna_CustomDataData_numverts(ptr, CD_MTFACE) * 2; -} - -static int rna_MeshTextureFace_uv_set_length(PointerRNA *ptr, int length) -{ - return length == rna_MeshTextureFace_uv_get_length(ptr); + length[0]= rna_CustomDataData_numverts(ptr, CD_MTFACE); + length[1]= 2; + return length[0]*length[1]; } static void rna_MeshTextureFace_uv_get(PointerRNA *ptr, float *values) @@ -711,35 +708,22 @@ static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value) tf->tpage= (struct Image*)id; } -static int rna_MeshFace_verts_get_length(PointerRNA *ptr) +static int rna_MeshFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { MFace *face= (MFace*)ptr->data; + if(face) - return face->v4 ? 4 : 3; + length[0]= (face->v4)? 4: 3; else - return 4; // XXX rna_raw_access wants the length of a dummy face. this needs fixing. - Campbell -} + length[0]= 4; // XXX rna_raw_access wants the length of a dummy face. this needs fixing. - Campbell -static int rna_MeshFace_verts_set_length(PointerRNA *ptr, int length) -{ - MFace *face= (MFace*)ptr->data; - if (length == 3) { - face->v4= 0; - } - else if(length == 4) { - face->v4= 1; - } - else - return 0; - - return 1; + return length[0]; } static void rna_MeshFace_verts_get(PointerRNA *ptr, int *values) { MFace *face= (MFace*)ptr->data; - int verts[4] = {face->v1, face->v2, face->v3, face->v4}; - memcpy(values, verts, (face->v4 ? 4 : 3) * sizeof(int)); + memcpy(values, &face->v1, (face->v4 ? 4 : 3) * sizeof(int)); } static void rna_MeshFace_verts_set(PointerRNA *ptr, const int *values) @@ -982,19 +966,11 @@ static void rna_def_mface(BlenderRNA *brna) RNA_def_struct_path_func(srna, "rna_MeshFace_path"); RNA_def_struct_ui_icon(srna, ICON_FACESEL); - /* - // XXX allows creating invalid meshes - prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "v1"); - RNA_def_property_array(prop, 4); - RNA_def_property_ui_text(prop, "Vertices", "Vertex indices"); - */ - // XXX allows creating invalid meshes prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED); RNA_def_property_array(prop, 4); RNA_def_property_flag(prop, PROP_DYNAMIC); - RNA_def_property_dynamic_array_funcs(prop, "rna_MeshFace_verts_get_length", "rna_MeshFace_verts_set_length"); + RNA_def_property_dynamic_array_funcs(prop, "rna_MeshFace_verts_get_length"); RNA_def_property_int_funcs(prop, "rna_MeshFace_verts_get", "rna_MeshFace_verts_set", NULL); RNA_def_property_ui_text(prop, "Vertices", "Vertex indices"); @@ -1037,7 +1013,7 @@ static void rna_def_mtface(BlenderRNA *brna) {TF_ALPHA, "ALPHA", 0, "Alpha", "Render polygon transparent, depending on alpha channel of the texture"}, {TF_CLIP, "CLIPALPHA", 0, "Clip Alpha", "Use the images alpha values clipped with no blending (binary alpha)"}, {0, NULL, 0, NULL, NULL}}; - unsigned short uv_dim[1]= {2}; + int uv_dim[]= {4, 2}; srna= RNA_def_struct(brna, "MeshTextureFaceLayer", NULL); RNA_def_struct_ui_text(srna, "Mesh Texture Face Layer", "Layer of texture faces in a Mesh datablock."); @@ -1183,9 +1159,9 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop= RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE); - RNA_def_property_multidimensional_array(prop, 4 * 2, 2, uv_dim); + RNA_def_property_multi_array(prop, 2, uv_dim); RNA_def_property_flag(prop, PROP_DYNAMIC); - RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTextureFace_uv_get_length", "rna_MeshTextureFace_uv_set_length"); + RNA_def_property_dynamic_array_funcs(prop, "rna_MeshTextureFace_uv_get_length"); RNA_def_property_float_funcs(prop, "rna_MeshTextureFace_uv_get", "rna_MeshTextureFace_uv_set", NULL); RNA_def_property_ui_text(prop, "UV", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index ce65ef4d450..3d43dfdfc2c 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1046,7 +1046,7 @@ static void rna_def_object(BlenderRNA *brna) {OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing."}, {0, NULL, 0, NULL, NULL}}; - unsigned short matrix_dimsize[]= {4}; + int matrix_dimsize[]= {4, 4}; srna= RNA_def_struct(brna, "Object", "ID"); RNA_def_struct_ui_text(srna, "Object", "Object datablock defining an object in a scene.."); @@ -1210,7 +1210,7 @@ static void rna_def_object(BlenderRNA *brna) /* matrix */ prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "obmat"); - RNA_def_property_multidimensional_array(prop, 16, 2, matrix_dimsize); + RNA_def_property_multi_array(prop, 2, matrix_dimsize); RNA_def_property_ui_text(prop, "Matrix", "Transformation matrix."); /* collections */ diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 9137e596da1..a67831715a2 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -170,40 +170,51 @@ static void rna_RenderLayer_passes_begin(CollectionPropertyIterator *iter, Point rna_iterator_listbase_begin(iter, &rl->passes, NULL); } -static float rna_RenderValue_value_get(PointerRNA *ptr) +static int rna_RenderLayer_rect_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { - return *(float*)ptr->data; -} + RenderLayer *rl= (RenderLayer*)ptr->data; -static void rna_RenderValue_value_set(PointerRNA *ptr, float value) -{ - *(float*)ptr->data= value; + length[0]= rl->rectx*rl->recty; + length[1]= 4; + + return length[0]*length[1]; } -static void rna_RenderLayer_rect_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static void rna_RenderLayer_rect_get(PointerRNA *ptr, float *values) { RenderLayer *rl= (RenderLayer*)ptr->data; - rna_iterator_array_begin(iter, (void*)rl->rectf, sizeof(float), rl->rectx*rl->recty*4, 0, NULL); + memcpy(values, rl->rectf, sizeof(float)*rl->rectx*rl->recty*4); } -static int rna_RenderLayer_rect_length(PointerRNA *ptr) +static void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values) { RenderLayer *rl= (RenderLayer*)ptr->data; - return rl->rectx*rl->recty*4; + memcpy(rl->rectf, values, sizeof(float)*rl->rectx*rl->recty*4); } -static void rna_RenderPass_rect_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +static int rna_RenderPass_rect_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) { RenderPass *rpass= (RenderPass*)ptr->data; - rna_iterator_array_begin(iter, (void*)rpass->rect, sizeof(float), rpass->rectx*rpass->recty*rpass->channels, 0, NULL); + + length[0]= rpass->rectx*rpass->recty; + length[1]= rpass->channels; + + return length[0]*length[1]; } -static int rna_RenderPass_rect_length(PointerRNA *ptr) +static void rna_RenderPass_rect_get(PointerRNA *ptr, float *values) { RenderPass *rpass= (RenderPass*)ptr->data; - return rpass->rectx*rpass->recty*rpass->channels; + printf("rect get\n"); + memcpy(values, rpass->rect, sizeof(float)*rpass->rectx*rpass->recty*rpass->channels); } +static void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values) +{ + RenderPass *rpass= (RenderPass*)ptr->data; + printf("rect set\n"); + memcpy(rpass->rect, values, sizeof(float)*rpass->rectx*rpass->recty*rpass->channels); +} #else // RNA_RUNTIME @@ -324,16 +335,11 @@ static void rna_def_render_layer(BlenderRNA *brna) RNA_def_property_struct_type(prop, "RenderPass"); RNA_def_property_collection_funcs(prop, "rna_RenderLayer_passes_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0, 0); - prop= RNA_def_property(srna, "rect", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "RenderValue"); - RNA_def_property_collection_funcs(prop, "rna_RenderLayer_rect_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_RenderLayer_rect_length", 0, 0, 0, 0); - - /* value */ - srna= RNA_def_struct(brna, "RenderValue", NULL); - RNA_def_struct_ui_text(srna, "Render Value", ""); - - prop= RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs(prop, "rna_RenderValue_value_get", "rna_RenderValue_value_set", NULL); + prop= RNA_def_property(srna, "rect", PROP_FLOAT, PROP_NONE); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_multi_array(prop, 2, NULL); + RNA_def_property_dynamic_array_funcs(prop, "rna_RenderLayer_rect_get_length"); + RNA_def_property_float_funcs(prop, "rna_RenderLayer_rect_get", "rna_RenderLayer_rect_set", NULL); RNA_define_verify_sdna(1); } @@ -383,9 +389,11 @@ static void rna_def_render_pass(BlenderRNA *brna) RNA_def_property_enum_items(prop, pass_type_items); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - prop= RNA_def_property(srna, "rect", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "RenderValue"); - RNA_def_property_collection_funcs(prop, "rna_RenderPass_rect_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_RenderPass_rect_length", 0, 0, 0, 0); + prop= RNA_def_property(srna, "rect", PROP_FLOAT, PROP_NONE); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_multi_array(prop, 2, NULL); + RNA_def_property_dynamic_array_funcs(prop, "rna_RenderPass_rect_get_length"); + RNA_def_property_float_funcs(prop, "rna_RenderPass_rect_get", "rna_RenderPass_rect_set", NULL); RNA_define_verify_sdna(1); } diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index b1644405ff3..8df6398f1f4 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -430,7 +430,7 @@ static int rna_Property_array_length_get(PointerRNA *ptr) { PropertyRNA *prop= (PropertyRNA*)ptr->data; rna_idproperty_check(&prop, ptr); - return prop->arraylength; + return prop->totarraylength; } static int rna_Property_registered_get(PointerRNA *ptr) diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index 9db4b20d011..f11c95e7ed5 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -36,9 +36,6 @@ #define MAX_ARRAY_DIMENSION 10 -/* convenient way to access array dimension size */ -#define DIMSIZE(a) (dimsize[a - 1]) - typedef void (*ItemConvertFunc)(PyObject *, char *); typedef int (*ItemTypeCheckFunc)(PyObject *); typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *); @@ -59,7 +56,7 @@ typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *) /* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */ /* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */ -static int validate_array_type(PyObject *seq, unsigned short dim, unsigned short totdim, unsigned short dimsize[], +static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[], ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix) { int i; @@ -79,13 +76,13 @@ static int validate_array_type(PyObject *seq, unsigned short dim, unsigned short ok= 0; } /* arr[3][4][5] - DIMSIZE(1)=4 - DIMSIZE(2)=5 + dimsize[1]=4 + dimsize[2]=5 dim=0 */ - else if (PySequence_Length(item) != DIMSIZE(dim + 1)) { - /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)DIMSIZE(dim + 1)); */ - PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", error_prefix, (int)dim + 1, (int)DIMSIZE(dim + 1)); + else if (PySequence_Length(item) != dimsize[dim + 1]) { + /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)dimsize[dim + 1]); */ + PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", error_prefix, (int)dim + 1, (int)dimsize[dim + 1]); ok= 0; } else if (!validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix)) { @@ -140,23 +137,28 @@ static int count_items(PyObject *seq) /* Modifies property array length if needed and PROP_DYNAMIC flag is set. */ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix) { - unsigned short dimsize[MAX_ARRAY_DIMENSION]; + int dimsize[MAX_ARRAY_DIMENSION]; int tot, totdim, len; tot= count_items(rvalue); - totdim= RNA_property_array_dimension(prop, dimsize); + totdim= RNA_property_array_dimension(ptr, prop, dimsize); if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { - /* length is flexible */ if (RNA_property_array_length(ptr, prop) != tot) { +#if 0 + /* length is flexible */ if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) { /* BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); return 0; } - - len= tot; +#else + PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); + return 0; +#endif } + + len= tot; } else { /* length is a constraint */ @@ -173,8 +175,8 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA arr[2] = x dimsize={4, 5} - DIMSIZE(1) = 4 - DIMSIZE(2) = 5 + dimsize[1] = 4 + dimsize[2] = 5 lvalue_dim=0, totdim=3 arr[2][3] = x @@ -183,7 +185,7 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA arr[2][3][4] = x lvalue_dim=2 */ for (i= lvalue_dim; i < totdim; i++) - len *= DIMSIZE(i); + len *= dimsize[i]; } if (tot != len) { @@ -200,8 +202,8 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix) { - unsigned short dimsize[MAX_ARRAY_DIMENSION]; - int totdim= RNA_property_array_dimension(prop, dimsize); + int dimsize[MAX_ARRAY_DIMENSION]; + int totdim= RNA_property_array_dimension(ptr, prop, dimsize); /* validate type first because length validation may modify property array length */ @@ -211,10 +213,10 @@ static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); } -static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, unsigned short dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index) +static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index) { unsigned int i; - int totdim= RNA_property_array_dimension(prop, NULL); + int totdim= RNA_property_array_dimension(ptr, prop, NULL); for (i= 0; i < PySequence_Length(seq); i++) { PyObject *item= PySequence_GetItem(seq, i); @@ -244,14 +246,15 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, unsi static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix) { - unsigned short totdim, dim_size[MAX_ARRAY_DIMENSION]; + int totdim, dim_size[MAX_ARRAY_DIMENSION]; int totitem; char *data= NULL; - totdim= RNA_property_array_dimension(prop, dim_size); + totdim= RNA_property_array_dimension(ptr, prop, dim_size); - if (!validate_array(py, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix)) + if (!validate_array(py, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix)) { return 0; + } if (totitem) { if (!param_data || RNA_property_flag(prop) & PROP_DYNAMIC) @@ -279,10 +282,10 @@ static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *p static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix) { - unsigned short totdim, dimsize[MAX_ARRAY_DIMENSION]; + int totdim, dimsize[MAX_ARRAY_DIMENSION]; int totitem, i; - totdim= RNA_property_array_dimension(prop, dimsize); + totdim= RNA_property_array_dimension(ptr, prop, dimsize); /* convert index */ @@ -297,7 +300,7 @@ static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, i lvalue_dim++; for (i= lvalue_dim; i < totdim; i++) - index *= DIMSIZE(i); + index *= dimsize[i]; index += arrayoffset; @@ -428,9 +431,9 @@ static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop { PyObject *tuple; int i, len; - int totdim= RNA_property_array_dimension(prop, NULL); + int totdim= RNA_property_array_dimension(ptr, prop, NULL); - len= RNA_property_multidimensional_array_length(ptr, prop, dim); + len= RNA_property_multi_array_length(ptr, prop, dim); tuple= PyTuple_New(len); @@ -459,11 +462,11 @@ static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) { int totdim, i, len; - unsigned short dimsize[MAX_ARRAY_DIMENSION]; + int dimsize[MAX_ARRAY_DIMENSION]; BPy_PropertyRNA *ret= NULL; /* just in case check */ - len= RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim); + len= RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim); if (index >= len || index < 0) { /* this shouldn't happen because higher level funcs must check for invalid index */ if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len); @@ -472,7 +475,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) return NULL; } - totdim= RNA_property_array_dimension(self->prop, dimsize); + totdim= RNA_property_array_dimension(&self->ptr, self->prop, dimsize); if (self->arraydim + 1 < totdim) { ret= (BPy_PropertyRNA*)pyrna_prop_CreatePyObject(&self->ptr, self->prop); @@ -487,7 +490,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyRNA *self, int index) index = offset + 3 * 5 */ for (i= self->arraydim + 1; i < totdim; i++) - index *= DIMSIZE(i); + index *= dimsize[i]; ret->arrayoffset= self->arrayoffset + index; } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index f2ffd5e0358..dd6bc35fc0a 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -141,7 +141,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) len= RNA_property_array_length(ptr, prop); type= RNA_property_type(prop); subtype= RNA_property_subtype(prop); - totdim= RNA_property_array_dimension(prop, NULL); + totdim= RNA_property_array_dimension(ptr, prop, NULL); if (type != PROP_FLOAT) return NULL; @@ -748,7 +748,7 @@ static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *va PropertyRNA *prop= self->prop; int type = RNA_property_type(prop); - totdim= RNA_property_array_dimension(prop, NULL); + totdim= RNA_property_array_dimension(ptr, prop, NULL); if (totdim > 1) { /* char error_str[512]; */ @@ -807,8 +807,8 @@ static int pyrna_py_to_prop_index(BPy_PropertyRNA *self, int index, PyObject *va //---------------sequence------------------------------------------- static int pyrna_prop_array_length(BPy_PropertyRNA *self) { - if (RNA_property_array_dimension(self->prop, NULL) > 1) - return RNA_property_multidimensional_array_length(&self->ptr, self->prop, self->arraydim); + if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) + return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim); else return RNA_property_array_length(&self->ptr, self->prop); } -- cgit v1.2.3 From ceaae73d5ee108728af65669193f595e7c14f10c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 19:42:53 +0000 Subject: 2.5: fix compilation of smoke commit for Makesfiles as well. --- source/blender/gpu/intern/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/gpu/intern/Makefile b/source/blender/gpu/intern/Makefile index 3a3ac20ff6c..2637bff44ac 100644 --- a/source/blender/gpu/intern/Makefile +++ b/source/blender/gpu/intern/Makefile @@ -47,6 +47,7 @@ CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../makesdna CPPFLAGS += -I../../imbuf CPPFLAGS += -I../../blenkernel +CPPFLAGS += -I$(NAN_SMOKE)/include CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I../ -- cgit v1.2.3 From a3a414a63103be1d9886a53ce70ba2b5ddd7f564 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 9 Sep 2009 19:43:05 +0000 Subject: Keyboard shortcuts Made Mac-specific keys only appear on the Mac. This has the added benefit that it shows the Mac key shortcuts in menus. --- source/blender/editors/screen/screen_ops.c | 17 ++++++++--- .../blender/editors/space_console/space_console.c | 13 ++++---- source/blender/editors/space_text/space_text.c | 35 +++++++++++----------- source/blender/makesrna/intern/rna_wm.c | 8 ++--- source/blender/windowmanager/intern/wm_operators.c | 26 +++++++++------- 5 files changed, 56 insertions(+), 43 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5403317042f..75da8f5fe06 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3327,8 +3327,11 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_region_foursplit", SKEY, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0); + #ifdef __APPLE__ + WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_OSKEY, 0); + #endif WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0); @@ -3340,10 +3343,13 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "FILE_OT_cancel", ESCKEY, KM_PRESS, 0, 0); /* undo */ - WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_CTRL, 0); + #ifdef __APPLE__ WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_OSKEY, 0); - WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0); + #endif + WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + /* render */ WM_keymap_add_item(keymap, "SCREEN_OT_render", F12KEY, KM_PRESS, 0, 0); @@ -3352,8 +3358,11 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_render_view_show", F11KEY, KM_PRESS, 0, 0); /* user prefs */ - WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_CTRL, 0); + #ifdef __APPLE__ WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_OSKEY, 0); + #endif + WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_CTRL, 0); + /* Anim Playback ------------------------------------------------ */ keymap= WM_keymap_listbase(wm, "Frames", 0, 0); diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 7e0dfe94432..dfaaa269970 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -233,14 +233,13 @@ void console_keymap(struct wmWindowManager *wm) { ListBase *keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0); - /* + #ifdef __APPLE__ RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); - RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); - RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); - - RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END); - RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", EKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "type", LINE_END); - */ + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END); + #endif + + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 1e37c2d6cb7..1f919fc9cd7 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -210,34 +210,38 @@ static void text_keymap(struct wmWindowManager *wm) { ListBase *keymap= WM_keymap_listbase(wm, "Text", SPACE_TEXT, 0); + #ifdef __APPLE__ + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); + WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT|KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0); + #endif + WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_reload", RKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT|KM_OSKEY, 0); WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_OSKEY, 0); WM_keymap_add_item(keymap, "TEXT_OT_run_script", PKEY, KM_PRESS, KM_ALT, 0); - - + WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception - WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception - WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception - WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_ALT, 0); if(U.uiflag & USER_MMB_PASTE) // XXX not dynamic RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0)->ptr, "selection", 1); WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0); @@ -246,17 +250,16 @@ static void text_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "TEXT_OT_to_3d_object", MKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception + WM_keymap_add_item(keymap, "TEXT_OT_indent", TABKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TEXT_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "TEXT_OT_uncomment", DKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception + RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "type", LINE_END); @@ -272,8 +275,6 @@ static void text_keymap(struct wmWindowManager *wm) RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", HOMEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_END); - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception - RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);//Mac Exception RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", PREV_WORD); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 148af2c28e9..af3ac4a0a82 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -377,22 +377,22 @@ static void rna_def_event(BlenderRNA *brna) prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shift", 1); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Shift", "True when the shift key is held."); + RNA_def_property_ui_text(prop, "Shift", "True when the Shift key is held."); prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 1); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Ctrl", "True when the shift key is held."); + RNA_def_property_ui_text(prop, "Ctrl", "True when the Ctrl key is held."); prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "alt", 1); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Alt", "True when the shift key is held."); + RNA_def_property_ui_text(prop, "Alt", "True when the Alt/Option key is held."); prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "oskey", 1); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "OS Key", "True when the shift key is held."); + RNA_def_property_ui_text(prop, "OS Key", "True when the Cmd key is held."); } static void rna_def_window(BlenderRNA *brna) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7152d5bcfa2..0913d58258f 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -531,7 +531,7 @@ int WM_operator_winactive(bContext *C) } /* op->invoke */ -static void redo_cb(bContext *C, void *arg_op, int event) +static void redo_cb(bContext *C, void *arg_op, void *arg2) { wmOperator *lastop= arg_op; @@ -553,7 +553,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1); - uiBlockSetHandleFunc(block, redo_cb, arg_op); + uiBlockSetFunc(block, redo_cb, arg_op, NULL); if(!op->properties) { IDPropertyTemplate val = {0}; @@ -803,7 +803,7 @@ static int recentfile_exec(bContext *C, wmOperator *op) WM_read_file(C, G.sce, op->reports); } else { - struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-1); + struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-2); if(recent) { WM_event_add_notifier(C, NC_WINDOW, NULL); WM_read_file(C, recent->filename, op->reports); @@ -831,11 +831,11 @@ static EnumPropertyItem *open_recentfile_itemf(bContext *C, PointerRNA *ptr, int EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; struct RecentFile *recent; - int totitem= 0, i; + int totitem= 0, i, ofs= 0; /* dynamically construct enum */ for(recent = G.recent_files.first, i=0; (inext, i++) { - tmp.value= i+1; + tmp.value= i+ofs+1; tmp.identifier= recent->filename; tmp.name= recent->filename; RNA_enum_item_add(&item, &totitem, &tmp); @@ -1918,19 +1918,23 @@ void wm_window_keymap(wmWindowManager *wm) /* note, this doesn't replace existing keymap items */ WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + #ifdef __APPLE__ + WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0); + WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_OSKEY, 0); + #endif WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_OSKEY, 0);//Mac Exception WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0);//Mac Exception + WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); /* debug/testing */ WM_keymap_verify_item(keymap, "WM_OT_ten_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); -- cgit v1.2.3 From b1bbfda8a55ca5cf41319ca8a65993cd154fab01 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 19:43:42 +0000 Subject: 2.5: small text tweak for empty object buttons. --- release/ui/buttons_data_empty.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/ui/buttons_data_empty.py b/release/ui/buttons_data_empty.py index 98c9b88e9f5..c07f3136fae 100644 --- a/release/ui/buttons_data_empty.py +++ b/release/ui/buttons_data_empty.py @@ -17,7 +17,7 @@ class DATA_PT_empty(DataButtonsPanel): ob = context.object - layout.itemR(ob, "empty_draw_type") - layout.itemR(ob, "empty_draw_size") + layout.itemR(ob, "empty_draw_type", text="Draw Type") + layout.itemR(ob, "empty_draw_size", text="Draw Size") bpy.types.register(DATA_PT_empty) -- cgit v1.2.3 From 2fabd68deb4840ac2112f467d2eaa7efa95fd9da Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 9 Sep 2009 19:52:10 +0000 Subject: * Small code cleanup. --- release/ui/buttons_physics_smoke.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py index 83c1ffc2e9a..8d86a6ef2d6 100644 --- a/release/ui/buttons_physics_smoke.py +++ b/release/ui/buttons_physics_smoke.py @@ -90,10 +90,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel): def poll(self, context): md = context.smoke - if md: - return (md.smoke_type == 'TYPE_DOMAIN') - - return False + return md and (md.smoke_type == 'TYPE_DOMAIN') def draw(self, context): layout = self.layout -- cgit v1.2.3 From 25f4fe5d13c76fa8604931f4f61044c26cc29795 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Sep 2009 19:59:52 +0000 Subject: RNA: fix for last commit, 0 size arrays are not very useful.. --- source/blender/makesrna/intern/makesrna.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index a3c4af26478..d0c7824dc9d 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1679,7 +1679,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; unsigned int i; - if(prop->arraydimension) { + if(prop->arraydimension && prop->totarraylength) { fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->totarraylength); for(i=0; itotarraylength; i++) { @@ -1699,7 +1699,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr IntPropertyRNA *iprop= (IntPropertyRNA*)prop; unsigned int i; - if(prop->arraydimension) { + if(prop->arraydimension && prop->totarraylength) { fprintf(f, "static int rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->totarraylength); for(i=0; itotarraylength; i++) { @@ -1719,7 +1719,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; unsigned int i; - if(prop->arraydimension) { + if(prop->arraydimension && prop->totarraylength) { fprintf(f, "static float rna_%s%s_%s_default[%d] = {", srna->identifier, strnest, prop->identifier, prop->totarraylength); for(i=0; itotarraylength; i++) { @@ -1762,7 +1762,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_BOOLEAN: { BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %d, ", rna_function_string(bprop->get), rna_function_string(bprop->set), rna_function_string(bprop->getarray), rna_function_string(bprop->setarray), bprop->defaultvalue); - if(prop->arraydimension) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); + if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; } @@ -1775,7 +1775,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr rna_int_print(f, iprop->hardmax); fprintf(f, ", "); rna_int_print(f, iprop->step); fprintf(f, ", "); rna_int_print(f, iprop->defaultvalue); fprintf(f, ", "); - if(prop->arraydimension) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); + if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; } @@ -1789,7 +1789,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr rna_float_print(f, fprop->step); fprintf(f, ", "); rna_int_print(f, (int)fprop->precision); fprintf(f, ", "); rna_float_print(f, fprop->defaultvalue); fprintf(f, ", "); - if(prop->arraydimension) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); + if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; } -- cgit v1.2.3 From 434af76286152c001d9df0d6da8048fb6da85696 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 9 Sep 2009 20:56:49 +0000 Subject: support for external images, blacklisting slaves on errors and proper job termination on cancel --- release/io/netrender/client.py | 18 +++++++++++--- release/io/netrender/master.py | 54 +++++++++++++++++++++++++----------------- release/io/netrender/slave.py | 3 +++ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index da27a8ecc57..0c60bd1603c 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -26,6 +26,9 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): if job_name == "[default]": job_name = name + ########################### + # LIBRARIES + ########################### for lib in bpy.data.libraries: lib_path = lib.filename @@ -34,11 +37,13 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): job.addFile(lib_path) + ########################### + # POINT CACHES + ########################### + root, ext = os.path.splitext(name) cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - print("cache:", cache_path) - if os.path.exists(cache_path): caches = {} pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") @@ -80,7 +85,14 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): previous_frame = previous_item[0] job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) - print(job.files) + ########################### + # IMAGES + ########################### + for image in bpy.data.images: + if image.source == "FILE" and not image.packed_file: + job.addFile(image.filename) + + # print(job.files) job.name = job_name diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index d938c59a2ec..78e9243bc9d 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -477,33 +477,43 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): print("writing result file") self.server.stats("", "Receiving render result") - job_id = self.headers['job-id'] + slave_id = self.headers['slave-id'] - job = self.server.getJobByID(job_id) + slave = self.server.updateSlave(slave_id) - if job: - job_frame = int(self.headers['job-frame']) - job_result = int(self.headers['job-result']) - job_time = float(self.headers['job-time']) + if slave: # only if slave id is valid + job_id = self.headers['job-id'] - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() - - del buf - job = self.server.getJobByID(job_id) - frame = job[job_frame] - frame.status = job_result - frame.time = job_time - - self.server.updateSlave(self.headers['slave-id']) - self.send_head() - else: # job not found + if job: + job_frame = int(self.headers['job-frame']) + job_result = int(self.headers['job-result']) + job_time = float(self.headers['job-time']) + + frame = job[job_frame] + + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() + + del buf + elif job_result == ERROR: + # blacklist slave on this job on error + job.blacklist.append(slave.id) + + frame.status = job_result + frame.time = job_time + + self.server.updateSlave(self.headers['slave-id']) + + self.send_head() + else: # job not found + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "log": diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 0435ba3f8cb..c12c846231d 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -119,6 +119,9 @@ def render_slave(engine, scene): run_t = current_t if cancelled: + # kill process if needed + if process.poll() == None: + process.terminate() continue # to next frame total_t = time.time() - start_t -- cgit v1.2.3 From aec894939f3cb18c30a01bf97a6512cabcb32a4b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Sep 2009 23:11:43 +0000 Subject: - off by 1 error with console command line memory re-allocation. - documenting vgroups crashed. --- source/blender/editors/object/object_vgroup.c | 4 ++-- source/blender/editors/space_console/console_ops.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 6808b10b49d..2b17a6cbe54 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1230,13 +1230,13 @@ static int set_active_group_exec(bContext *C, wmOperator *op) static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob; EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; bDeformGroup *def; int a, totitem= 0; - if(!C) /* needed for docs */ + if(!C || !(ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data)) /* needed for docs */ return vgroup_items; for(a=0, def=ob->defbase.first; def; def=def->next, a++) { diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 3d0d284b501..2120b97becf 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -190,7 +190,7 @@ ConsoleLine *console_history_verify(const bContext *C) static void console_line_verify_length(ConsoleLine *ci, int len) { /* resize the buffer if needed */ - if(len > ci->len_alloc) { + if(len >= ci->len_alloc) { int new_len= len * 2; /* new length */ char *new_line= MEM_callocN(new_len, "console line"); memcpy(new_line, ci->line, ci->len); -- cgit v1.2.3 From e8b3f86bcb53ddef442e15f350fafb762a143400 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 9 Sep 2009 23:52:48 +0000 Subject: Smoke: * Bugfix for non-working high res display * Bugfix for smoke disappearing on 2nd frame --- release/ui/buttons_physics_smoke.py | 9 ++++++--- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/blenkernel/intern/smoke.c | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py index 8d86a6ef2d6..6aee152e92a 100644 --- a/release/ui/buttons_physics_smoke.py +++ b/release/ui/buttons_physics_smoke.py @@ -90,7 +90,10 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel): def poll(self, context): md = context.smoke - return md and (md.smoke_type == 'TYPE_DOMAIN') + if md: + return (md.smoke_type == 'TYPE_DOMAIN') + + return False def draw(self, context): layout = self.layout @@ -145,7 +148,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): md = context.smoke.domain_settings split = layout.split() - + col = split.column() col.itemL(text="Resolution:") col.itemR(md, "amplify", text="Divisions") @@ -154,7 +157,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel): col.itemL(text="Noise Method:") col.row().itemR(md, "noise_type", text="") col.itemR(md, "strength") - sub.itemR(md, "viewhighres") + col.itemR(md, "viewhighres") class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel): __label__ = "Smoke High Resolution Cache" diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 1ab1daf1782..5a14277d63b 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1847,7 +1847,7 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset(pid->calldata); + smokeModifier_reset_turbulence(pid->calldata); } if(clear) BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 026ccf4fc7d..fe5541211ce 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1157,14 +1157,13 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); } - if(!(cache_wt->flag & PTCACHE_SIMULATION_VALID)) + if(sds->wt && !(cache_wt->flag & PTCACHE_SIMULATION_VALID)) { BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED); } if(smd->time == -1 && framenr!= startframe) return; - if(!smokeModifier_init(smd, ob, scene, dm)) return; @@ -1287,6 +1286,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM if(get_lamp(scene, light)) smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + // printf("smd->time: %f\n", smd->time); return; } -- cgit v1.2.3 From abe48562b8b8940dbb81914f96323b90d99b4802 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Thu, 10 Sep 2009 00:32:59 +0000 Subject: Remove smoke from COMLIB, already in PULIB. --- source/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Makefile b/source/Makefile index d9acd4bf059..dab037d1749 100644 --- a/source/Makefile +++ b/source/Makefile @@ -113,7 +113,6 @@ COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sdl.a COMLIB += $(NAN_SAMPLERATE)/lib/$(DEBUG_DIR)libsamplerate.a COMLIB += $(NAN_LZO)/lib/$(DEBUG_DIR)libminilzo.a COMLIB += $(NAN_LZMA)/lib/$(DEBUG_DIR)liblzma.a -COMLIB += $(NAN_SMOKE)/lib/$(DEBUG_DIR)/libsmoke.a ifeq ($(WITH_FFMPEG),true) COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_ffmpeg.a -- cgit v1.2.3 From b74eaeba73d4c659208e4f8398291da1dd38cd0b Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 10 Sep 2009 01:14:21 +0000 Subject: 2.5 Node RNA: * Added Property ranges for Nodes. --- source/blender/makesrna/intern/rna_nodetree.c | 84 +++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 9062cec3828..b3046ad1364 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -396,6 +396,7 @@ static void def_cmp_alpha_over(StructRNA *srna) prop = RNA_def_property(srna, "premul", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "x"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Premul", "Mix Factor"); } @@ -419,38 +420,46 @@ static void def_cmp_blur(StructRNA *srna) prop = RNA_def_property(srna, "sizex", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sizex"); + RNA_def_property_range(prop, 0, 256); RNA_def_property_ui_text(prop, "Size X", ""); prop = RNA_def_property(srna, "sizey", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sizey"); + RNA_def_property_range(prop, 1, 256); RNA_def_property_ui_text(prop, "Size Y", ""); prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "samples"); + RNA_def_property_range(prop, 1, 256); RNA_def_property_ui_text(prop, "Samples", ""); prop = RNA_def_property(srna, "max_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "maxspeed"); + RNA_def_property_range(prop, 1, 1024); RNA_def_property_ui_text(prop, "Max Speed", ""); prop = RNA_def_property(srna, "min_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "minspeed"); + RNA_def_property_range(prop, 1, 1024); RNA_def_property_ui_text(prop, "Min Speed", ""); - + prop = RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "relative", 1); RNA_def_property_ui_text(prop, "Relative", ""); prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fac"); + RNA_def_property_range(prop, 0.0f, 2.0f); RNA_def_property_ui_text(prop, "Factor", ""); prop = RNA_def_property(srna, "factor_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "percentx"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Relative Size X", ""); prop = RNA_def_property(srna, "factor_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "percenty"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Relative Size Y", ""); prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); @@ -506,10 +515,12 @@ static void def_cmp_map_value(StructRNA *srna) prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "loc"); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Offset", ""); prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Size", ""); prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE); @@ -522,10 +533,12 @@ static void def_cmp_map_value(StructRNA *srna) prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Minimum", ""); prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Maximum", ""); } @@ -580,14 +593,17 @@ static void def_cmp_image(StructRNA *srna) prop = RNA_def_property(srna, "frames", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "frames"); + RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Frames", "Number of images used in animation"); prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sfra"); + RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start Frame", ""); prop = RNA_def_property(srna, "offset", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "offset"); + RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation"); prop = RNA_def_property(srna, "cyclic", PROP_BOOLEAN, PROP_NONE); @@ -604,6 +620,7 @@ static void def_cmp_image(StructRNA *srna) prop = RNA_def_property(srna, "layer", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "layer"); + RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Layer", ""); /* } */ @@ -692,10 +709,12 @@ static void def_cmp_output_file(StructRNA *srna) prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sfra"); + RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start Frame", ""); prop = RNA_def_property(srna, "end", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "efra"); + RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "End Frame", ""); } @@ -748,18 +767,22 @@ static void def_cmp_diff_matte(StructRNA *srna) prop = RNA_def_property(srna, "tolerance1", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Channel 1 Tolerance", ""); prop = RNA_def_property(srna, "tolerance2", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Channel 2 Tolerance", ""); prop = RNA_def_property(srna, "tolerance3", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t3"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Channel 3 Tolerance", ""); prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fstrength"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Falloff", ""); } @@ -783,6 +806,7 @@ static void def_cmp_color_spill(StructRNA *srna) prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 0.0f, 0.5f); RNA_def_property_ui_text(prop, "Amount", "How much the selected channel is affected by"); } @@ -794,22 +818,27 @@ static void def_cmp_chroma(StructRNA *srna) prop = RNA_def_property(srna, "acceptance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 1.0f, 80.0f); RNA_def_property_ui_text(prop, "Acceptance", "Tolerance for a color to be considered a keying color"); prop = RNA_def_property(srna, "cutoff", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); + RNA_def_property_range(prop, 0.0f, 30.0f); RNA_def_property_ui_text(prop, "Cutoff", "Tolerance below which colors will be considered as exact matches"); prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fsize"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Lift", "Alpha lift"); prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fstrength"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gain", "Alpha gain"); prop = RNA_def_property(srna, "shadow_adjust", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t3"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Shadow Adjust", "Adjusts the brightness of any shadows captured"); /* TODO: @@ -844,10 +873,12 @@ static void def_cmp_channel_matte(StructRNA *srna) prop = RNA_def_property(srna, "high", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque"); prop = RNA_def_property(srna, "low", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Low", "Values lower than this setting are 100% keyed"); /* TODO: @@ -889,8 +920,9 @@ static void def_cmp_splitviewer(StructRNA *srna) RNA_def_property_ui_text(prop, "Axis", ""); /* TODO: percentage */ - prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "custom1"); + RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Factor", ""); } @@ -900,6 +932,7 @@ static void def_cmp_id_mask(StructRNA *srna) prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); + RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Index", "Pass index number to convert to alpha"); } @@ -908,8 +941,9 @@ static void def_cmp_map_uv(StructRNA *srna) PropertyRNA *prop; /* TODO: percentage */ - prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "custom1"); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Alpha", ""); } @@ -938,6 +972,7 @@ static void def_cmp_defocus(StructRNA *srna) /* TODO: angle in degrees */ prop = RNA_def_property(srna, "angle", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rotation"); + RNA_def_property_range(prop, 0, 90); RNA_def_property_ui_text(prop, "Angle", "Bokeh shape rotation offset in degrees"); prop = RNA_def_property(srna, "gamma_correction", PROP_BOOLEAN, PROP_NONE); @@ -947,14 +982,17 @@ static void def_cmp_defocus(StructRNA *srna) /* TODO */ prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fstop"); + RNA_def_property_range(prop, 0.0f, 128.0f); RNA_def_property_ui_text(prop, "fStop", "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius"); prop = RNA_def_property(srna, "max_blur", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "maxblur"); + RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_ui_text(prop, "Max Blur", "blur limit, maximum CoC radius, 0=no limit"); prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bthresh"); + RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Threshold", "CoC radius threshold, prevents background bleed on in-focus midground, 0=off"); prop = RNA_def_property(srna, "preview", PROP_BOOLEAN, PROP_NONE); @@ -963,6 +1001,7 @@ static void def_cmp_defocus(StructRNA *srna) prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "samples"); + RNA_def_property_range(prop, 16, 256); RNA_def_property_ui_text(prop, "Samples", "Number of samples (16=grainy, higher=less noise)"); prop = RNA_def_property(srna, "use_zbuffer", PROP_BOOLEAN, PROP_NONE); @@ -971,6 +1010,7 @@ static void def_cmp_defocus(StructRNA *srna) prop = RNA_def_property(srna, "z_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_text(prop, "Z-Scale", "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1"); } @@ -982,10 +1022,12 @@ static void def_cmp_luma_matte(StructRNA *srna) prop = RNA_def_property(srna, "high", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque"); prop = RNA_def_property(srna, "low", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Low", "Values lower than this setting are 100% keyed"); /* TODO: keep low less than high */ @@ -1017,18 +1059,22 @@ static void def_cmp_crop(StructRNA *srna) prop = RNA_def_property(srna, "x1", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "x1"); + RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "X1", ""); prop = RNA_def_property(srna, "x2", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "x2"); + RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "X2", ""); prop = RNA_def_property(srna, "y1", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "y1"); + RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Y1", ""); prop = RNA_def_property(srna, "y2", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "y2"); + RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Y2", ""); } @@ -1040,6 +1086,7 @@ static void def_cmp_dblur(StructRNA *srna) prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "iter"); + RNA_def_property_range(prop, 1, 128); RNA_def_property_ui_text(prop, "Iterations", ""); prop = RNA_def_property(srna, "wrap", PROP_BOOLEAN, PROP_NONE); @@ -1048,26 +1095,32 @@ static void def_cmp_dblur(StructRNA *srna) prop = RNA_def_property(srna, "center_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "center_x"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Center X", ""); prop = RNA_def_property(srna, "center_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "center_y"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Center Y", ""); prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "distance"); + RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Distance", ""); prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "angle"); + RNA_def_property_range(prop, 0.0f, 360.0f); RNA_def_property_ui_text(prop, "Angle", ""); prop = RNA_def_property(srna, "spin", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spin"); + RNA_def_property_range(prop, -360.0f, 360.0f); RNA_def_property_ui_text(prop, "Spin", ""); prop = RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "zoom"); + RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Zoom", ""); } @@ -1079,16 +1132,18 @@ static void def_cmp_bilateral_blur(StructRNA *srna) prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "iter"); + RNA_def_property_range(prop, 1, 128); RNA_def_property_ui_text(prop, "Iterations", ""); prop = RNA_def_property(srna, "sigma_color", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sigma_color"); + RNA_def_property_range(prop, 0.01f, 3.0f); RNA_def_property_ui_text(prop, "Color Sigma", ""); prop = RNA_def_property(srna, "sigma_space", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sigma_space"); - RNA_def_property_ui_text(prop, "Space Sigma", ""); - + RNA_def_property_range(prop, 0.01f, 30.0f); + RNA_def_property_ui_text(prop, "Space Sigma", ""); } static void def_cmp_premul_key(StructRNA *srna) @@ -1141,30 +1196,37 @@ static void def_cmp_glare(StructRNA *srna) prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "iter"); + RNA_def_property_range(prop, 2, 5); RNA_def_property_ui_text(prop, "Iterations", ""); prop = RNA_def_property(srna, "color_modulation", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "colmod"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Color Modulation", ""); prop = RNA_def_property(srna, "mix", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "mix"); + RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Mix", "-1 is original image only, 0 is exact 50/50 mix, 1 is processed image only"); prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "threshold"); + RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_text(prop, "Threshold", "The glare filter will only be applied to pixels brighter than this value"); prop = RNA_def_property(srna, "streaks", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "angle"); + RNA_def_property_range(prop, 2, 16); RNA_def_property_ui_text(prop, "Streaks", "Total number of streaks"); prop = RNA_def_property(srna, "angle_offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "angle_ofs"); + RNA_def_property_range(prop, 0.0f, 180.0f); RNA_def_property_ui_text(prop, "Angle Offset", "Streak angle offset in degrees"); prop = RNA_def_property(srna, "fade", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fade"); + RNA_def_property_range(prop, 0.75f, 1.0f); RNA_def_property_ui_text(prop, "Fade", "Streak fade-out factor"); prop = RNA_def_property(srna, "rotate_45", PROP_BOOLEAN, PROP_NONE); @@ -1173,6 +1235,7 @@ static void def_cmp_glare(StructRNA *srna) prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "size"); + RNA_def_property_range(prop, 6, 9); RNA_def_property_ui_text(prop, "Size", "Glow/glare size (not actual size; relative to initial size of bright area of pixels)"); /* TODO */ @@ -1199,32 +1262,39 @@ static void def_cmp_tonemap(StructRNA *srna) prop = RNA_def_property(srna, "key", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "key"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Key", "The value the average luminance is mapped to"); prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "offset"); + RNA_def_property_range(prop, 0.001f, 10.0f); RNA_def_property_ui_text(prop, "Offset", "Normally always 1, but can be used as an extra control to alter the brightness curve"); prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "gamma"); + RNA_def_property_range(prop, 0.001f, 3.0f); RNA_def_property_ui_text(prop, "Gamma", "If not used, set to 1"); /* TODO: } else { */ prop = RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "f"); + RNA_def_property_range(prop, -8.0f, 8.0f); RNA_def_property_ui_text(prop, "Intensity", "If less than zero, darkens image; otherwise, makes it brighter"); prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "m"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Contrast", "Set to 0 to use estimate from input image"); prop = RNA_def_property(srna, "adaptation", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "a"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Adaptation", "If 0, global; if 1, based on pixel intensity"); prop = RNA_def_property(srna, "correction", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "c"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Color Correction", "If 0, same for all channels; if 1, each independent"); } @@ -1280,18 +1350,22 @@ static void def_tex_bricks(StructRNA *srna) prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "custom3"); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Offset Amount", ""); prop = RNA_def_property(srna, "offset_frequency", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); + RNA_def_property_range(prop, 2, 99); RNA_def_property_ui_text(prop, "Offset Frequency", "Offset every N rows"); prop = RNA_def_property(srna, "squash", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "custom4"); + RNA_def_property_range(prop, 0.0f, 99.0f); RNA_def_property_ui_text(prop, "Squash Amount", ""); prop = RNA_def_property(srna, "squash_frequency", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); + RNA_def_property_range(prop, 2, 99); RNA_def_property_ui_text(prop, "Squash Frequency", "Squash every N rows"); } -- cgit v1.2.3 From d6a706dee9b59e32ca9c60645680ea4170e6c1d4 Mon Sep 17 00:00:00 2001 From: Robert Holcomb Date: Thu, 10 Sep 2009 01:55:10 +0000 Subject: Inno installer script to build windows installer. First draft-still needs some work. Creates a baseline functional installer from a build. Requires Inno and Inno ISTool --- release/windows/inno/blender.iss | 92 +++++++++++++++++++++++++++++++++++++ release/windows/inno/copyright.txt | 56 ++++++++++++++++++++++ release/windows/inno/header.bmp | Bin 0 -> 25818 bytes release/windows/inno/installer.bmp | Bin 0 -> 154542 bytes release/windows/inno/installer.ico | Bin 0 -> 25214 bytes 5 files changed, 148 insertions(+) create mode 100644 release/windows/inno/blender.iss create mode 100644 release/windows/inno/copyright.txt create mode 100644 release/windows/inno/header.bmp create mode 100644 release/windows/inno/installer.bmp create mode 100644 release/windows/inno/installer.ico diff --git a/release/windows/inno/blender.iss b/release/windows/inno/blender.iss new file mode 100644 index 00000000000..5faf5b47406 --- /dev/null +++ b/release/windows/inno/blender.iss @@ -0,0 +1,92 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + + +[Setup] +#define VERSION "2.49b" + +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{C45CB76D-AD5F-49CC-86DE-72B168A6A888} +AppName=Blender +AppVerName=Blender {#VERSION} +AppPublisher=Blender Foundation +AppPublisherURL=http://www.blender.org +AppSupportURL=http://www.blender.org +AppUpdatesURL=http://www.blender.org +DefaultDirName={pf}\Blender +DefaultGroupName=Blender Foundation +AllowNoIcons=true +LicenseFile=.\copyright.txt +OutputBaseFilename=blender-{#VERSION} +Compression=lzma +SolidCompression=true +ChangesAssociations=true +WizardImageFile=.\installer.bmp +WizardSmallImageFile=.\header.bmp +SetupIconFile=.\installer.ico +MinVersion=,5.01.2600sp1 +PrivilegesRequired=none +AllowRootDirectory=true +ShowLanguageDialog=auto + +[Dirs] +Name: {userdocs}\Blender; Flags: uninsneveruninstall; Tasks: ; Languages: + +[Languages] +Name: english; MessagesFile: compiler:Default.isl + +[Tasks] +Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked +Name: quicklaunchicon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked + +[Files] +Source: ..\..\..\..\build\bin\release\blender.exe; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\blender.html; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\BlenderQuickStart.pdf; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\copyright.txt; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\GPL-license.txt; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\Python-license.txt; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\release_249.txt; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\*.dll; DestDir: {app}; Flags: ignoreversion +Source: ..\..\..\..\build\bin\release\plugins\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs +Source: ..\..\..\..\build\bin\release\.blender\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: {group}\Blender; Filename: {app}\blender.exe +Name: {group}\ReleaseNotes; Filename: {app}\release_249.txt +Name: {group}\Blender.org; Filename: {app}\blender.html +Name: {group}\Copyright; Filename: {app}\copyright.txt +Name: {group}\GPL; Filename: {app}\GPL-license.txt +Name: {group}\Uninstall; Filename: {uninstallexe}; Tasks: ; Languages: +Name: {commondesktop}\Blender; Filename: {app}\blender.exe; Tasks: desktopicon +Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Blender; Filename: {app}\blender.exe; Tasks: quicklaunchicon + +[Registry] +Root: HKCR; Subkey: .blend; ValueType: string; ValueName: ; ValueData: BlenderFile; Flags: uninsdeletevalue +Root: HKCR; Subkey: BlenderFile; ValueType: string; ValueName: ; ValueData: Blender File; Flags: uninsdeletekey +Root: HKCR; Subkey: BlenderFile\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\blender.exe,0 +Root: HKCR; Subkey: BlenderFile\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\blender.exe"" ""%1""" + +[Run] +Filename: {app}\blender.exe; Description: {cm:LaunchProgram,Blender}; Flags: nowait postinstall skipifsilent + + +[_ISToolDownload] + +[UninstallDelete] +Name: {app}\blender.exe; Type: files +Name: {app}\*.dll; Type: files +Name: {app}\blender.html; Type: files; Tasks: ; Languages: +Name: {app}\BlenderQuickStart.pdf; Type: files +Name: {app}\copyright.txt; Type: files +Name: {app}\GPL-license.txt; Type: files +Name: {app}\Python-license.txt; Type: files +Name: {app}\release_249.txt; Type: files +Name: {app}\.blender\*; Type: filesandordirs +Name: {app}\plugins\*; Type: filesandordirs +Name: {app}\.blender; Type: dirifempty +Name: {app}\plugins; Type: dirifempty +Name: {app}; Type: dirifempty diff --git a/release/windows/inno/copyright.txt b/release/windows/inno/copyright.txt new file mode 100644 index 00000000000..4e67c2561d3 --- /dev/null +++ b/release/windows/inno/copyright.txt @@ -0,0 +1,56 @@ +BLENDER CREATOR LICENSE AGREEMENT + +IMPORTANT: PLEASE READ CAREFULLY BEFORE USING THE BLENDER CREATOR SOFTWARE. + +This License Agreement for the Blender Creator software ("License Agreement") is an agreement between NaN Technologies B.V., Meerenakkerplein 11, 5652 BJ Eindhoven, the Netherlands ("NaN") and you (either an individual or a legal entity) ("You") with respect to the software product which this License Agreement accompanies (the "Software"). + +By installing, copying or otherwise using the Software, You agree to be bound by the terms of this License Agreement. If You do not agree to the terms of this License Agreement do not install or use the Software. + + +1. Grant of License + +Subject to the provisions of this License Agreement, NaN grants You a limited, non-exclusive, personal, non-sublicenseable, non-transferable, revocable license to use the Software at any computer You own or use. + +2. License Restrictions + +Except as expressly provided under this License Agreement, or without prior written consent from NaN, or without permission by law, You may not: (a) remove or alter any proprietary, copyright or trademark notices in or on the Software; (b) modify, decompile, disassemble or reverse-engineer the Software; (c) sublicense, rent, lease, lend, assign or otherwise transfer rights to the Software. + +3. Permitted copying and electronic distribution of Software + +You are hereby granted permission to copy and distribute the Software without written agreement from NaN, only for non-commercial purposes. Distributing the Software within a restricted non-public environment, such as using a local network in a company or a local network of a university, is considered a 'non-commercial purpose'. This entire License Agreement must appear in and/or accompany all copies of the Software. +Distributing the Software 'bundled' in with ANY product is considered to be a 'commercial purpose'. + +4. Intellectual Property Rights and Ownership + +Title and ownership to all rights, including intellectual property rights, in and to the Software shall at all times solely and exclusively remain with NaN. The Software is protected by national and international (copyright) laws and treaties. All rights not expressly granted herein are reserved to NaN. + +5. Disclaimer of Warranties + +NaN provides you with the Software "as is" and with all faults. NaN explicitly disclaims all warranties and guarantees and does not make any representations with respect to the Software, whether express, implied, or statutory, including, but not limited to any (if any) warranties of or related to: fitness for a particular purpose, title, non-infringement, lack of viruses, accuracy or completeness of responses, results, lack of negligence or lack of workmanlike effort, and correspondence to description. The entire risk arising out of use or performance of the Software remains with You. + +6. Limitation of Liability + +In no event shall NaN or its employees, agents or suppliers be liable for any direct, indirect, consequential, incidental, special, punitive, or other damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, claims of third parties, damages as a result of injury to any person, or any other loss) arising out of or in connection with the license granted under this License Agreement or the use of or inability to use the Software, even if NaN has been advised of the possibility of such damages. + +7. User warning and indemnification + +WARNING: use of the Software and use of any works that are (partially) created with the Software (the "Works") may cause physical or psychological reactions from You or from third parties, which may result in damages, injuries, losses and/or other negative consequences. You acknowledge that NaN can not be held liable for any such damages, injuries, losses and/or other negative consequences. You acknowledge that it is your obligation to investigate, prevent and/or minimize such reactions prior to having third parties use the Works. + +You shall indemnify and hold harmless NaN from and against all actions, claims, demands, proceedings, losses, damages, costs, charges and expenses, including but not limited to legal fees and expenses, arising out of or in connection with (i) the use of the Software by You and (ii) the use of any Works created with the Software by You or any third parties. + +8. Term and Termination + +This License Agreement and the license granted hereunder is effective until terminated. This License Agreement shall terminate automatically and forthwith if You fail to comply with the terms of this License Agreement. Upon termination, You shall cease the use of the Software, remove the Software from (the memory of) your computer and destroy all copies of the Software. + +9. Entire Agreement + +This License Agreement is the entire agreement between NaN and You in respect of the subject matter of the License Agreement. This License Agreement supersedes all prior written or oral agreements, proposals or understandings, and any other communications between NaN and You relating to the subject matter of this License Agreement. + +10. Enforceability + +If any provision of this License Agreement is held to be unenforceable by a court of competent jurisdiction for any reason, such provision shall be adapted or amended only to the extent necessary to make it enforceable, and the remainder of the License Agreement shall remain in effect. + +11. Governing law and disputes + +This License Agreement and all disputes arising from it will be governed by the laws of The Netherlands. All disputes arising in connection with this Agreement that cannot be settled amicably shall be brought before the competent court in Amsterdam, the Netherlands, to which jurisdiction NaN and You hereby irrevocably consent. + diff --git a/release/windows/inno/header.bmp b/release/windows/inno/header.bmp new file mode 100644 index 00000000000..b631ba73933 Binary files /dev/null and b/release/windows/inno/header.bmp differ diff --git a/release/windows/inno/installer.bmp b/release/windows/inno/installer.bmp new file mode 100644 index 00000000000..10fb01454a4 Binary files /dev/null and b/release/windows/inno/installer.bmp differ diff --git a/release/windows/inno/installer.ico b/release/windows/inno/installer.ico new file mode 100644 index 00000000000..922c9d472d9 Binary files /dev/null and b/release/windows/inno/installer.ico differ -- cgit v1.2.3 From 2fc4ee354574d52200544eec00aed95442cf4d04 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Sep 2009 02:57:25 +0000 Subject: Curve cleanup Renamed BevPoint's members * x,y,z -> vec[3]; compatible with other functions. * f1 -> split_tag; used by displist to set the splitting flag. * f2 -> dupe_tag; used in curve.c to remove duplicates. BevList * flag -> dupe_nr; was being used as a counter for duplicate points. * use arithb.c functions where possible. * arrays for coords, tilt and radius were being allocated, then copied into the BevPoint's, now write directly into the values without allocing/freeing arrays. --- source/blender/blenkernel/BKE_curve.h | 2 +- source/blender/blenkernel/intern/anim.c | 28 ++-- source/blender/blenkernel/intern/armature.c | 8 +- source/blender/blenkernel/intern/colortools.c | 4 +- source/blender/blenkernel/intern/curve.c | 225 +++++++++----------------- source/blender/blenkernel/intern/displist.c | 40 ++--- source/blender/makesdna/DNA_curve_types.h | 6 +- source/blender/python/api2_2x/Geometry.c | 2 +- source/blender/src/drawipo.c | 4 +- source/blender/src/drawobject.c | 6 +- 10 files changed, 127 insertions(+), 198 deletions(-) diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 79f4708fd41..2aa8e35391f 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -70,7 +70,7 @@ void minmaxNurb( struct Nurb *nu, float *min, float *max); void makeknots( struct Nurb *nu, short uv); void makeNurbfaces(struct Nurb *nu, float *coord_array, int rowstride); -void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu); +void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu, int stride); void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride); float *make_orco_curve( struct Object *ob); float *make_orco_surf( struct Object *ob); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index e75b31dd892..2e08763821f 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -86,11 +86,11 @@ void free_path(Path *path) void calc_curvepath(Object *ob) { BevList *bl; - BevPoint *bevp, *bevpn, *bevpfirst, *bevplast, *tempbevp; + BevPoint *bevp, *bevpn, *bevpfirst, *bevplast; Curve *cu; Nurb *nu; Path *path; - float *fp, *dist, *maxdist, x, y, z; + float *fp, *dist, *maxdist, xyz[3]; float fac, d=0, fac1, fac2; int a, tot, cycl=0; float *ft; @@ -129,19 +129,12 @@ void calc_curvepath(Object *ob) *fp= 0; for(a=0; ax - bevp->x; - y= bevpfirst->y - bevp->y; - z= bevpfirst->z - bevp->z; - } - else { - tempbevp = bevp+1; - x= (tempbevp)->x - bevp->x; - y= (tempbevp)->y - bevp->y; - z= (tempbevp)->z - bevp->z; - } - *fp= *(fp-1)+ (float)sqrt(x*x+y*y+z*z); + if(cycl && a==tot-1) + VecSubf(xyz, bevpfirst->vec, bevp->vec); + else + VecSubf(xyz, (bevp+1)->vec, bevp->vec); + *fp= *(fp-1)+VecLength(xyz); bevp++; } @@ -178,14 +171,11 @@ void calc_curvepath(Object *ob) fac2= *(fp)-d; fac1= fac2/fac1; fac2= 1.0f-fac1; - - ft[0]= fac1*bevp->x+ fac2*(bevpn)->x; - ft[1]= fac1*bevp->y+ fac2*(bevpn)->y; - ft[2]= fac1*bevp->z+ fac2*(bevpn)->z; + + VecLerpf(ft, bevp->vec, bevpn->vec, fac2); ft[3]= fac1*bevp->alfa+ fac2*(bevpn)->alfa; ft+= 4; - } MEM_freeN(dist); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 1577eb4f850..9a73b3355ce 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -654,10 +654,10 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) if(bone->segments > MAX_BBONE_SUBDIV) bone->segments= MAX_BBONE_SUBDIV; - forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4); - forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4); - forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4); - forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4); + forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4*sizeof(float)); + forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4*sizeof(float)); + forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4*sizeof(float)); + forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4*sizeof(float)); equalize_bezier(data[0], bone->segments); // note: does stride 4! diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 1bc34aea9a1..96ff3264822 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -413,8 +413,8 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) for(a=0; atotpoint-1; a++, fp += 2*CM_RESOL) { correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a+1].vec[0], bezt[a+1].vec[1]); - forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2); - forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2); + forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2*sizeof(float)); + forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2*sizeof(float)); } /* store first and last handle for extrapolation, unit length */ diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 86cfe9d4c6f..4d10308be20 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -64,7 +64,6 @@ #include "BKE_library.h" #include "BKE_key.h" - /* globals */ extern ListBase editNurb; /* editcurve.c */ @@ -813,7 +812,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) MEM_freeN(jend); } -void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu) +void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu, int stride) /* coord_array has to be 3*4*pntsu*resolu in size and zero-ed * tilt_array and radius_array will be written to if valid */ { @@ -897,10 +896,10 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu } } - coord_fp+= 3; + coord_fp = (float *)(((char *)coord_fp) + stride); - if (tilt_fp) tilt_fp++; - if (radius_fp) radius_fp++; + if (tilt_fp) tilt_fp = (float *)(((char *)tilt_fp) + stride); + if (radius_fp) radius_fp = (float *)(((char *)radius_fp) + stride); u+= ustep; } @@ -931,7 +930,7 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i for(a=0; a<=it; a++) { *p= q0; - p+= stride; + p = (float *)(((char *)p)+stride); q0+= q1; q1+= q2; q2+= q3; @@ -1350,8 +1349,8 @@ static short bevelinside(BevList *bl1,BevList *bl2) /* take first vertex of possible hole */ bevp= (BevPoint *)(bl2+1); - hvec1[0]= bevp->x; - hvec1[1]= bevp->y; + hvec1[0]= bevp->vec[0]; + hvec1[1]= bevp->vec[1]; hvec1[2]= 0.0; VECCOPY(hvec2,hvec1); hvec2[0]+=1000; @@ -1364,16 +1363,16 @@ static short bevelinside(BevList *bl1,BevList *bl2) prevbevp= bevp+(nr-1); while(nr--) { - min= prevbevp->y; - max= bevp->y; + min= prevbevp->vec[0]; + max= bevp->vec[1]; if(maxy; + max= prevbevp->vec[1]; } if(min!=max) { if(min<=hvec1[1] && max>=hvec1[1]) { /* there's a transition, calc intersection point */ - mode= cu_isectLL(&(prevbevp->x),&(bevp->x),hvec1,hvec2,0,1,&lab,&mu,vec); + mode= cu_isectLL(prevbevp->vec, bevp->vec, hvec1, hvec2, 0, 1, &lab, &mu, vec); /* if lab==0.0 or lab==1.0 then the edge intersects exactly a transition only allow for one situation: we choose lab= 1.0 */ @@ -1446,12 +1445,15 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si } -static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu) +static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu, int stride) { BezTriple *pprev, *next, *last; float fac, dfac, t[4]; int a; + if(tilt_array==NULL && radius_array==NULL) + return; + last= nu->bezt+(nu->pntsu-1); /* returns a point */ @@ -1474,11 +1476,13 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * for(a=0; atilt_interp==3) { /* May as well support for tilt also 2.47 ease interp */ - tilt_array[a] = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac); + *tilt_array = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac); } else { key_curve_position_weights(fac, t, nu->tilt_interp); - tilt_array[a]= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa; + *tilt_array= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa; } + + tilt_array = (float *)(((char *)tilt_array) + stride); } if (radius_array) { @@ -1486,15 +1490,17 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * /* Support 2.47 ease interp * Note! - this only takes the 2 points into account, * giving much more localized results to changes in radius, sometimes you want that */ - radius_array[a] = prevbezt->radius + (bezt->radius - prevbezt->radius)*(3.0f*fac*fac - 2.0f*fac*fac*fac); + *radius_array = prevbezt->radius + (bezt->radius - prevbezt->radius)*(3.0f*fac*fac - 2.0f*fac*fac*fac); } else { /* reuse interpolation from tilt if we can */ if (tilt_array==NULL || nu->tilt_interp != nu->radius_interp) { key_curve_position_weights(fac, t, nu->radius_interp); } - radius_array[a]= t[0]*pprev->radius + t[1]*prevbezt->radius + t[2]*bezt->radius + t[3]*next->radius; + *radius_array= t[0]*pprev->radius + t[1]*prevbezt->radius + t[2]*bezt->radius + t[3]*next->radius; } + + radius_array = (float *)(((char *)radius_array) + stride); } } } @@ -1514,8 +1520,6 @@ void makeBevelList(Object *ob) BevList *bl, *blnew, *blnext; BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; float min, inp, x1, x2, y1, y2, vec[3], vec_prev[3], q[4], quat[4], quat_prev[4], cross[3]; - float *coord_array, *tilt_array=NULL, *radius_array=NULL, *coord_fp, *tilt_fp=NULL, *radius_fp=NULL; - float *v1, *v2; struct bevelsort *sortdata, *sd, *sd1; int a, b, nr, poly, resolu, len=0; int do_tilt, do_radius; @@ -1558,17 +1562,15 @@ void makeBevelList(Object *ob) if(nu->flagu & CU_CYCLIC) bl->poly= 0; else bl->poly= -1; bl->nr= len; - bl->flag= 0; + bl->dupe_nr= 0; bevp= (BevPoint *)(bl+1); bp= nu->bp; while(len--) { - bevp->x= bp->vec[0]; - bevp->y= bp->vec[1]; - bevp->z= bp->vec[2]; + VECCOPY(bevp->vec, bp->vec); bevp->alfa= bp->alfa; bevp->radius= bp->radius; - bevp->f1= SELECT; + bevp->split_tag= TRUE; bevp++; bp++; } @@ -1594,88 +1596,52 @@ void makeBevelList(Object *ob) bezt++; } - coord_array= coord_fp= MEM_mallocN(3*sizeof(float)*(resolu+1), "makeBevelCoords"); - - if(do_tilt) - tilt_array= tilt_fp= MEM_callocN(sizeof(float)*(resolu+1), "makeBevelTilt"); - - if (do_radius) - radius_array= radius_fp= MEM_callocN(sizeof(float)*(resolu+1), "nakeBevelRadius"); - while(a--) { if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) { - - bevp->x= prevbezt->vec[1][0]; - bevp->y= prevbezt->vec[1][1]; - bevp->z= prevbezt->vec[1][2]; + + VECCOPY(bevp->vec, prevbezt->vec[1]); bevp->alfa= prevbezt->alfa; bevp->radius= prevbezt->radius; - bevp->f1= SELECT; - bevp->f2= 0; + bevp->split_tag= TRUE; + bevp->dupe_tag= FALSE; bevp++; bl->nr++; - bl->flag= 1; + bl->dupe_nr= 1; } else { - v1= prevbezt->vec[1]; - v2= bezt->vec[0]; - /* always do all three, to prevent data hanging around */ - forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], coord_array, resolu, 3); - forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], coord_array+1, resolu, 3); - forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], coord_array+2, resolu, 3); + int j; + + /* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */ + for(j=0; j<3; j++) { + forward_diff_bezier( prevbezt->vec[1][j], prevbezt->vec[2][j], + bezt->vec[0][j], bezt->vec[1][j], + &(bevp->vec[j]), resolu, sizeof(BevPoint)); + } - if (do_tilt || do_radius) - alfa_bezpart(prevbezt, bezt, nu, tilt_array, radius_array, resolu); + /* if both arrays are NULL do nothiong */ + alfa_bezpart( prevbezt, bezt, nu, + do_tilt ? &bevp->alfa : NULL, + do_radius ? &bevp->radius : NULL, + resolu, sizeof(BevPoint)); /* indicate with handlecodes double points */ if(prevbezt->h1==prevbezt->h2) { - if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->f1= SELECT; + if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->split_tag= TRUE; } else { - if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->f1= SELECT; - else if(prevbezt->h2==0 || prevbezt->h2==HD_VECT) bevp->f1= SELECT; - } - - nr= resolu; - - coord_fp = coord_array; - tilt_fp = tilt_array; - radius_fp = radius_array; - - while(nr--) { - bevp->x= coord_fp[0]; - bevp->y= coord_fp[1]; - bevp->z= coord_fp[2]; - coord_fp+=3; - - if (do_tilt) { - bevp->alfa= *tilt_fp; - tilt_fp++; - } - - if (do_radius) { - bevp->radius= *radius_fp; - radius_fp++; - } - bevp++; + if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->split_tag= TRUE; + else if(prevbezt->h2==0 || prevbezt->h2==HD_VECT) bevp->split_tag= TRUE; } bl->nr+= resolu; - + bevp+= resolu; } prevbezt= bezt; bezt++; } - MEM_freeN(coord_array); - if (do_tilt) MEM_freeN(tilt_array); - if (do_radius) MEM_freeN(radius_array); - coord_array = tilt_array = radius_array = NULL; - if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic: endpoint */ - bevp->x= prevbezt->vec[1][0]; - bevp->y= prevbezt->vec[1][1]; - bevp->z= prevbezt->vec[1][2]; + VECCOPY(bevp->vec, prevbezt->vec[1]); bevp->alfa= prevbezt->alfa; bevp->radius= prevbezt->radius; bl->nr++; @@ -1688,45 +1654,15 @@ void makeBevelList(Object *ob) bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList3"); BLI_addtail(&(cu->bev), bl); bl->nr= len; - bl->flag= 0; + bl->dupe_nr= 0; if(nu->flagu & CU_CYCLIC) bl->poly= 0; else bl->poly= -1; bevp= (BevPoint *)(bl+1); - - coord_array= coord_fp= MEM_callocN(3*sizeof(float)*len, "makeBevelCoords"); /* has to be zero-ed */ - - if(do_tilt) - tilt_array= tilt_fp= MEM_callocN(sizeof(float)*len, "makeBevelTilt"); - - if (do_radius) - radius_array= radius_fp= MEM_callocN(sizeof(float)*len, "nakeBevelRadius"); - - makeNurbcurve(nu, coord_array, tilt_array, radius_array, resolu); - while(len--) { - bevp->x= coord_fp[0]; - bevp->y= coord_fp[1]; - bevp->z= coord_fp[2]; - coord_fp+=3; - - if (do_tilt) { - bevp->alfa= *tilt_fp; - tilt_fp++; - } - - if (do_radius) { - bevp->radius= *radius_fp; - radius_fp++; - } - - - bevp->f1= bevp->f2= 0; - bevp++; - } - MEM_freeN(coord_array); - if (do_tilt) MEM_freeN(tilt_array); - if (do_radius) MEM_freeN(radius_array); - coord_array = tilt_array = radius_array = NULL; + makeNurbcurve( nu, &bevp->vec[0], + do_tilt ? &bevp->alfa : NULL, + do_radius ? &bevp->radius : NULL, + resolu, sizeof(BevPoint)); } } } @@ -1742,11 +1678,11 @@ void makeBevelList(Object *ob) bevp0= bevp1+(nr-1); nr--; while(nr--) { - if( fabs(bevp0->x-bevp1->x)<0.00001 ) { - if( fabs(bevp0->y-bevp1->y)<0.00001 ) { - if( fabs(bevp0->z-bevp1->z)<0.00001 ) { - bevp0->f2= SELECT; - bl->flag++; + if( fabs(bevp0->vec[0]-bevp1->vec[0])<0.00001 ) { + if( fabs(bevp0->vec[1]-bevp1->vec[1])<0.00001 ) { + if( fabs(bevp0->vec[2]-bevp1->vec[2])<0.00001 ) { + bevp0->dupe_tag= TRUE; + bl->dupe_nr++; } } } @@ -1759,8 +1695,8 @@ void makeBevelList(Object *ob) bl= cu->bev.first; while(bl) { blnext= bl->next; - if(bl->nr && bl->flag) { - nr= bl->nr- bl->flag+1; /* +1 because vectorbezier sets flag too */ + if(bl->nr && bl->dupe_nr) { + nr= bl->nr- bl->dupe_nr+1; /* +1 because vectorbezier sets flag too */ blnew= MEM_mallocN(sizeof(BevList)+nr*sizeof(BevPoint), "makeBevelList4"); memcpy(blnew, bl, sizeof(BevList)); blnew->nr= 0; @@ -1770,7 +1706,7 @@ void makeBevelList(Object *ob) bevp1= (BevPoint *)(blnew+1); nr= bl->nr; while(nr--) { - if(bevp0->f2==0) { + if(bevp0->dupe_tag==0) { memcpy(bevp1, bevp0, sizeof(BevPoint)); bevp1++; blnew->nr++; @@ -1778,7 +1714,7 @@ void makeBevelList(Object *ob) bevp0++; } MEM_freeN(bl); - blnew->flag= 0; + blnew->dupe_nr= 0; } bl= blnext; } @@ -1807,8 +1743,8 @@ void makeBevelList(Object *ob) bevp= (BevPoint *)(bl+1); nr= bl->nr; while(nr--) { - if(min>bevp->x) { - min= bevp->x; + if(min>bevp->vec[0]) { + min= bevp->vec[0]; bevp1= bevp; } bevp++; @@ -1823,8 +1759,7 @@ void makeBevelList(Object *ob) if(bevp1== bevp) bevp2= (BevPoint *)(bl+1); else bevp2= bevp1+1; - inp= (bevp1->x- bevp0->x)*(bevp0->y- bevp2->y) - +(bevp0->y- bevp1->y)*(bevp0->x- bevp2->x); + inp= (bevp1->vec[0]- bevp0->vec[0]) * (bevp0->vec[1]- bevp2->vec[1]) + (bevp0->vec[1]- bevp1->vec[1]) * (bevp0->vec[0]- bevp2->vec[0]); if(inp>0.0) sd->dir= 1; else sd->dir= 0; @@ -1879,8 +1814,8 @@ void makeBevelList(Object *ob) bevp2= (BevPoint *)(bl+1); bevp1= bevp2+1; - x1= bevp1->x- bevp2->x; - y1= bevp1->y- bevp2->y; + x1= bevp1->vec[0]- bevp2->vec[0]; + y1= bevp1->vec[1]- bevp2->vec[1]; calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa)); bevp2->sina= bevp1->sina; @@ -1889,7 +1824,7 @@ void makeBevelList(Object *ob) if(cu->flag & CU_3D) { /* 3D */ float quat[4], q[4]; - VecSubf(vec, &bevp1->x, &bevp2->x); + VecSubf(vec, bevp1->vec, bevp2->vec); vectoquat(vec, 5, 1, quat); @@ -1924,7 +1859,7 @@ void makeBevelList(Object *ob) while(nr--) { /* Normalizes */ - VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x); + VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); if(bl->nr==nr+1) { /* first time */ vectoquat(vec, 5, 1, quat); @@ -1976,7 +1911,7 @@ void makeBevelList(Object *ob) nr= bl->nr; while(nr--) { - VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x); + VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); quat_tmp1= (float *)bevp1->mat; quat_tmp2= quat_tmp1+4; @@ -1989,10 +1924,10 @@ void makeBevelList(Object *ob) QuatToMat3(quat, bevp1->mat); /* generic */ - x1= bevp1->x- bevp0->x; - x2= bevp1->x- bevp2->x; - y1= bevp1->y- bevp0->y; - y2= bevp1->y- bevp2->y; + x1= bevp1->vec[0]- bevp0->vec[0]; + x2= bevp1->vec[0]- bevp2->vec[0]; + y1= bevp1->vec[1]- bevp0->vec[1]; + y2= bevp1->vec[1]- bevp2->vec[1]; calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); @@ -2014,7 +1949,7 @@ void makeBevelList(Object *ob) if(cu->flag & CU_3D) { /* 3D */ /* Normalizes */ - VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x); + VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */ vectoquat(vec, 5, 1, quat); @@ -2039,10 +1974,10 @@ void makeBevelList(Object *ob) QuatToMat3(quat, bevp1->mat); } - x1= bevp1->x- bevp0->x; - x2= bevp1->x- bevp2->x; - y1= bevp1->y- bevp0->y; - y2= bevp1->y- bevp2->y; + x1= bevp1->vec[0]- bevp0->vec[0]; + x2= bevp1->vec[0]- bevp2->vec[0]; + y1= bevp1->vec[1]- bevp0->vec[1]; + y2= bevp1->vec[1]- bevp2->vec[1]; calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index afc769b0966..c55dc8addb1 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -804,7 +804,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) DispList *dl; BezTriple *bezt, *prevbezt; BPoint *bp; - float *data, *v1, *v2; + float *data; int a, len, resolu; nu= nubase->first; @@ -869,11 +869,15 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) data+= 3; } else { - v1= prevbezt->vec[1]; - v2= bezt->vec[0]; - forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, resolu, 3); - forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, resolu, 3); - forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, resolu, 3); + int j; + for(j=0; j<3; j++) { + forward_diff_bezier( prevbezt->vec[1][j], + prevbezt->vec[2][j], + bezt->vec[0][j], + bezt->vec[1][j], + data+j, resolu, 3*sizeof(float)); + } + data+= 3*resolu; } @@ -900,7 +904,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) data= dl->verts; if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, NULL, NULL, resolu); + makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float)); } else if((nu->type & 7)==CU_POLY) { len= nu->pntsu; @@ -1397,7 +1401,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender, int forOrco if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, NULL, NULL, nu->resolu); + makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float)); } else { len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv); @@ -1508,9 +1512,9 @@ void makeDispListCurveTypes(Object *ob, int forOrco) bevp= (BevPoint *)(bl+1); data= dl->verts; while(a--) { - data[0]= bevp->x+widfac*bevp->sina; - data[1]= bevp->y+widfac*bevp->cosa; - data[2]= bevp->z; + data[0]= bevp->vec[0]+widfac*bevp->sina; + data[1]= bevp->vec[1]+widfac*bevp->cosa; + data[2]= bevp->vec[2]; bevp++; data+=3; } @@ -1550,7 +1554,7 @@ void makeDispListCurveTypes(Object *ob, int forOrco) fac = calc_taper(cu->taperobj, a, bl->nr); } - if (bevp->f1) { + if (bevp->split_tag) { dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F); } @@ -1566,14 +1570,14 @@ void makeDispListCurveTypes(Object *ob, int forOrco) Mat3MulVecfl(bevp->mat, vec); - data[0]= bevp->x+ fac*vec[0]; - data[1]= bevp->y+ fac*vec[1]; - data[2]= bevp->z+ fac*vec[2]; + data[0]= bevp->vec[0] + fac*vec[0]; + data[1]= bevp->vec[1] + fac*vec[1]; + data[2]= bevp->vec[2] + fac*vec[2]; } else { - data[0]= bevp->x+ fac*(widfac+fp1[1])*bevp->sina; - data[1]= bevp->y+ fac*(widfac+fp1[1])*bevp->cosa; - data[2]= bevp->z+ fac*fp1[2]; + data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina; + data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa; + data[2]= bevp->vec[2] + fac*fp1[2]; } } } diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 60dba9ce018..65d8cc6fbc6 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -60,7 +60,7 @@ typedef struct Path { # typedef struct BevList { struct BevList *next, *prev; - int nr, flag; + int nr, dupe_nr; short poly, hole; } BevList; @@ -68,8 +68,8 @@ typedef struct BevList { # # typedef struct BevPoint { - float x, y, z, alfa, radius, sina, cosa, mat[3][3]; - short f1, f2; + float vec[3], mat[3][3], alfa, radius, sina, cosa; + short split_tag, dupe_tag; } BevPoint; /* Keyframes on IPO curves and Points on Bezier Curves/Paths are generally BezTriples */ diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c index e5679ea6ed7..4297453c91e 100644 --- a/source/blender/python/api2_2x/Geometry.c +++ b/source/blender/python/api2_2x/Geometry.c @@ -509,7 +509,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "BezierInterp"); for(i=0; imat[2][2]; glBegin(GL_LINE_STRIP); - glVertex3f(bevp->x - ox - dx, bevp->y - oy - dy, bevp->z - oz - dz); - glVertex3f(bevp->x, bevp->y, bevp->z); - glVertex3f(bevp->x + ox - dx, bevp->y + oy - dy, bevp->z + oz - dz); + glVertex3f(bevp->vec[0] - ox - dx, bevp->vec[1] - oy - dy, bevp->vec[2] - oz - dz); + glVertex3fv(bevp->vec); + glVertex3f(bevp->vec[0] + ox - dx, bevp->vec[1] + oy - dy, bevp->vec[2] + oz - dz); glEnd(); bevp += skip+1; -- cgit v1.2.3 From dac27004b863da96c57b071fc0479680e06a9725 Mon Sep 17 00:00:00 2001 From: Robert Holcomb Date: Thu, 10 Sep 2009 03:00:50 +0000 Subject: committing patch #19252-Soft/Linear Light blend modes+Darken mode bug fix --- source/blender/blenkernel/intern/material.c | 51 +++++++++++++++++++++------ source/blender/editors/space_node/drawnode.c | 2 +- source/blender/makesdna/DNA_material_types.h | 2 ++ source/blender/makesdna/DNA_texture_types.h | 2 ++ source/blender/makesrna/intern/rna_material.c | 2 ++ source/blender/makesrna/intern/rna_texture.c | 2 ++ source/blender/render/intern/source/texture.c | 25 ++++++++++++- 7 files changed, 73 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 53de570b55e..e6f9ac2f404 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1031,15 +1031,15 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) } break; case MA_RAMP_DARK: - tmp= fac*col[0]; - if(tmp < *r) *r= tmp; - if(g) { - tmp= fac*col[1]; - if(tmp < *g) *g= tmp; - tmp= fac*col[2]; - if(tmp < *b) *b= tmp; - } - break; + tmp=col[0]+((1-col[0])*facm); + if(tmp < *r) *r= tmp; + if(g) { + tmp=col[1]+((1-col[1])*facm); + if(tmp < *g) *g= tmp; + tmp=col[2]+((1-col[2])*facm); + if(tmp < *b) *b= tmp; + } + break; case MA_RAMP_LIGHT: tmp= fac*col[0]; if(tmp > *r) *r= tmp; @@ -1169,8 +1169,37 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) } } break; - } - + case MA_RAMP_SOFT: + if (g){ + float scr, scg, scb; + + /* first calculate non-fac based Screen mix */ + scr = 1.0 - ((1.0 - col[0])) * (1.0 - *r); + scg = 1.0 - ((1.0 - col[1])) * (1.0 - *g); + scb = 1.0 - ((1.0 - col[2])) * (1.0 - *b); + + *r = facm*(*r) + fac*(((1.0 - *r) * col[0] * (*r)) + (*r * scr)); + *g = facm*(*g) + fac*(((1.0 - *g) * col[1] * (*g)) + (*g * scg)); + *b = facm*(*b) + fac*(((1.0 - *b) * col[2] * (*b)) + (*b * scb)); + } + break; + case MA_RAMP_LINEAR: + if (col[0] > 0.5) + *r = *r + fac*(2*(col[0]-0.5)); + else + *r = *r + fac*(2*(col[0]) - 1); + if (g){ + if (col[1] > 0.5) + *g = *g + fac*(2*(col[1]-0.5)); + else + *g = *g + fac*(2*(col[1]) -1); + if (col[2] > 0.5) + *b = *b + fac*(2*(col[2]-0.5)); + else + *b = *b + fac*(2*(col[2]) - 1); + } + break; + } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 2f64108384e..7617f328fd9 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -247,7 +247,7 @@ static int node_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf /* blend type */ uiBlockBeginAlign(block); - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Overlay %x9|Divide %x5|Difference %x6|Darken %x7|Lighten %x8|Dodge %x10|Burn %x11|Color %x15|Value %x14|Saturation %x13|Hue %x12", + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Overlay %x9|Divide %x5|Difference %x6|Darken %x7|Lighten %x8|Dodge %x10|Burn %x11|Color %x15|Value %x14|Saturation %x13|Hue %x12|Soft Light %x16|Linear Light %x17", (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin -(a_but?20:0), 20, &node->custom1, 0, 0, 0, 0, ""); uiButSetFunc(bt, node_but_title_cb, node, bt); diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index f268c117065..55e3c9107e4 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -279,6 +279,8 @@ typedef struct Material { #define MA_RAMP_SAT 13 #define MA_RAMP_VAL 14 #define MA_RAMP_COLOR 15 +#define MA_RAMP_SOFT 16 +#define MA_RAMP_LINEAR 17 /* texco */ #define TEXCO_ORCO 1 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 4df63ee9cd9..c13c0522004 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -448,6 +448,8 @@ typedef struct TexMapping { #define MTEX_BLEND_VAL 12 #define MTEX_BLEND_COLOR 13 #define MTEX_NUM_BLENDTYPES 14 +#define MTEX_SOFT_LIGHT 15 +#define MTEX_LIN_LIGHT 16 /* brush_map_mode */ #define MTEX_MAP_MODE_FIXED 0 diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 651aeae217e..cd1159bc138 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -616,6 +616,8 @@ static void rna_def_material_colors(StructRNA *srna) {MA_RAMP_SAT, "SATURATION", 0, "Saturation", ""}, {MA_RAMP_VAL, "VALUE", 0, "Value", ""}, {MA_RAMP_COLOR, "COLOR", 0, "Color", ""}, + {MA_RAMP_SOFT, "SOFT LIGHT", 0, "Soft Light", ""}, + {MA_RAMP_LINEAR, "LINEAR LIGHT", 0, "Linear Light", ""}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem prop_ramp_input_items[] = { diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index b11e5c6c12f..f6835f3e7b5 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -374,6 +374,8 @@ static void rna_def_mtex(BlenderRNA *brna) {MTEX_BLEND_SAT, "SATURATION", 0, "Saturation", ""}, {MTEX_BLEND_VAL, "VALUE", 0, "Value", ""}, {MTEX_BLEND_COLOR, "COLOR", 0, "Color", ""}, + {MTEX_SOFT_LIGHT, "SOFT LIGHT", 0, "Soft Light", ""}, + {MTEX_LIN_LIGHT , "LINEAR LIGHT", 0, "Linear Light", ""}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem prop_map_mode_items[] = { diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 4d4a2c04808..2d2c01e0bf1 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1455,12 +1455,22 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg VECCOPY(in, out); ramp_blend(MA_RAMP_COLOR, in, in+1, in+2, fact, tex); break; + case MTEX_SOFT_LIGHT: + fact*= facg; + VECCOPY(in, out); + ramp_blend(MA_RAMP_SOFT, in, in+1, in+2, fact, tex); + break; + case MTEX_LIN_LIGHT: + fact*= facg; + VECCOPY(in, out); + ramp_blend(MA_RAMP_LINEAR, in, in+1, in+2, fact, tex); + break; } } float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip) { - float in=0.0, facm, col; + float in=0.0, facm, col, scf; fact*= facg; facm= 1.0-fact; @@ -1505,6 +1515,19 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen col= fact*tex; if(col > out) in= col; else in= out; break; + + case MTEX_SOFT_LIGHT: + col= fact*tex; + scf=1.0 - (1.0 - tex) * (1.0 - out); + in= facm*out + fact * ((1.0 - out) * tex * out) + (out * scf); + break; + + case MTEX_LIN_LIGHT: + if (tex > 0.5) + in = out + fact*(2*(tex - 0.5)); + else + in = out + fact*(2*tex - 1); + break; } return in; -- cgit v1.2.3 From fa4ee2be849b6236d61e482106ed9e20f20f21de Mon Sep 17 00:00:00 2001 From: Robert Holcomb Date: Thu, 10 Sep 2009 04:12:22 +0000 Subject: Added Levels Node (histogram, with mean/std deviation outputs) Added RGB space distance matte Node Added HSV color matte Node Fixed Image difference matte Node to use image differences instead of RGB space distance Fixed luminance node for low end values being read wrong Fixed CMP_util copy/swap functions not accounting for all channels Fixed UI for difference matte Node Added RNA for new nodes --- source/blender/blenkernel/BKE_node.h | 7 +- source/blender/blenkernel/intern/node.c | 9 +- source/blender/editors/space_node/drawnode.c | 119 +++++--- source/blender/makesrna/intern/rna_nodetree.c | 60 ++-- .../blender/makesrna/intern/rna_nodetree_types.h | 5 +- source/blender/nodes/CMP_node.h | 7 +- .../nodes/intern/CMP_nodes/CMP_channelMatte.c | 4 +- .../nodes/intern/CMP_nodes/CMP_chromaMatte.c | 4 +- .../nodes/intern/CMP_nodes/CMP_colorMatte.c | 132 ++++++++ .../blender/nodes/intern/CMP_nodes/CMP_diffMatte.c | 174 ++++------- .../nodes/intern/CMP_nodes/CMP_distanceMatte.c | 145 +++++++++ source/blender/nodes/intern/CMP_nodes/CMP_levels.c | 337 +++++++++++++++++++++ .../nodes/intern/CMP_nodes/CMP_lummaMatte.c | 2 +- source/blender/nodes/intern/CMP_util.c | 26 +- source/blender/nodes/intern/CMP_util.h | 5 +- 15 files changed, 838 insertions(+), 198 deletions(-) create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c create mode 100644 source/blender/nodes/intern/CMP_nodes/CMP_levels.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 40afa1dba36..cbb37918d04 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -25,7 +25,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Bob Holcomb. * * ***** END GPL LICENSE BLOCK ***** */ @@ -325,7 +325,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_COMBYUVA 234 #define CMP_NODE_DIFF_MATTE 235 #define CMP_NODE_COLOR_SPILL 236 -#define CMP_NODE_CHROMA 237 +#define CMP_NODE_CHROMA_MATTE 237 #define CMP_NODE_CHANNEL_MATTE 238 #define CMP_NODE_FLIP 239 #define CMP_NODE_SPLITVIEWER 240 @@ -345,6 +345,9 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_DBLUR 254 #define CMP_NODE_BILATERALBLUR 255 #define CMP_NODE_PREMULKEY 256 +#define CMP_NODE_DIST_MATTE 257 +#define CMP_NODE_VIEW_LEVELS 258 +#define CMP_NODE_COLOR_MATTE 259 #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 bd6919dc115..90ea53d4364 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Bob Holcomb. * * ***** END GPL LICENSE BLOCK ***** */ @@ -2597,7 +2597,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) if(outsocket_exists(lnode->new_node, lsock->new_sock)) { lsock->new_sock->ns.data= lsock->ns.data; lsock->ns.data= NULL; - lsock->new_sock= NULL; + lsock->new_sock= NULL; } } } @@ -2932,6 +2932,7 @@ static void registerCompositNodes(ListBase *ntypelist) nodeRegisterType(ntypelist, &cmp_node_viewer); nodeRegisterType(ntypelist, &cmp_node_splitviewer); nodeRegisterType(ntypelist, &cmp_node_output_file); + nodeRegisterType(ntypelist, &cmp_node_view_levels); nodeRegisterType(ntypelist, &cmp_node_curve_rgb); nodeRegisterType(ntypelist, &cmp_node_mix_rgb); @@ -2971,7 +2972,9 @@ static void registerCompositNodes(ListBase *ntypelist) nodeRegisterType(ntypelist, &cmp_node_premulkey); nodeRegisterType(ntypelist, &cmp_node_diff_matte); - nodeRegisterType(ntypelist, &cmp_node_chroma); + nodeRegisterType(ntypelist, &cmp_node_distance_matte); + nodeRegisterType(ntypelist, &cmp_node_chroma_matte); + nodeRegisterType(ntypelist, &cmp_node_color_matte); nodeRegisterType(ntypelist, &cmp_node_channel_matte); nodeRegisterType(ntypelist, &cmp_node_color_spill); nodeRegisterType(ntypelist, &cmp_node_luma_matte); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 7617f328fd9..98de32a105a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): David Millan Escriva, Juho Vepsäläinen + * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb * * ***** END GPL LICENSE BLOCK ***** */ @@ -1647,45 +1647,35 @@ static int node_composit_buts_dilateerode(uiBlock *block, bNodeTree *ntree, bNod static int node_composit_buts_diff_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { if(block) { - short sx= (butr->xmax-butr->xmin)/4; - short dx= (butr->xmax-butr->xmin)/3; NodeChroma *c= node->storage; uiBlockBeginAlign(block); - /*color space selectors*/ - uiDefButS(block, ROW,B_NODE_EXEC,"RGB", - butr->xmin,butr->ymin+60,sx,20, - &node->custom1,1,1, 0, 0, "RGB Color Space"); - uiDefButS(block, ROW,B_NODE_EXEC,"HSV", - butr->xmin+sx,butr->ymin+60,sx,20, - &node->custom1,1,2, 0, 0, "HSV Color Space"); - uiDefButS(block, ROW,B_NODE_EXEC,"YUV", - butr->xmin+2*sx,butr->ymin+60,sx,20, - &node->custom1,1,3, 0, 0, "YUV Color Space"); - uiDefButS(block, ROW,B_NODE_EXEC,"YCC", - butr->xmin+3*sx,butr->ymin+60,sx,20, - &node->custom1,1,4, 0, 0, "YCbCr Color Space"); - /*channel tolorences*/ - uiDefButF(block, NUM, B_NODE_EXEC, " ", - butr->xmin, butr->ymin+40, dx, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Channel 1 Tolerance"); - uiDefButF(block, NUM, B_NODE_EXEC, " ", - butr->xmin+dx, butr->ymin+40, dx, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Channel 2 Tolorence"); - uiDefButF(block, NUM, B_NODE_EXEC, " ", - butr->xmin+2*dx, butr->ymin+40, dx, 20, - &c->t3, 0.0f, 1.0f, 100, 0, "Channel 3 Tolorence"); - /*falloff parameters*/ - /* - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Falloff Size ", + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->fsize, 0.0f, 1.0f, 100, 0, ""); - */ - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Falloff: ", + &c->t1, 0.0f, 1.0f, 100, 0, "Color differences below this threshold are keyed."); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Color differences below this additional threshold are partially keyed."); + uiBlockEndAlign(block); + } + return 40; +} + +static int node_composit_buts_distance_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeChroma *c= node->storage; + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->fstrength, 0.0f, 1.0f, 100, 0, ""); + &c->t1, 0.0f, 1.0f, 100, 0, "Color distances below this threshold are keyed."); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Color distances below this additional threshold are partially keyed."); + uiBlockEndAlign(block); } - return 80; + return 40; } static int node_composit_buts_color_spill(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) @@ -1717,6 +1707,7 @@ static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNo if(block) { short dx=(butr->xmax-butr->xmin)/2; NodeChroma *c= node->storage; + uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ", @@ -1736,6 +1727,7 @@ static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNo uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured"); + uiBlockEndAlign(block); if(c->t2 > c->t1) c->t2=c->t1; @@ -1743,6 +1735,28 @@ static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNo return 80; } +static int node_composit_buts_color_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeChroma *c= node->storage; + uiBlockBeginAlign(block); + + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "H: ", + butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 0.25f, 100, 0, "Hue tolerance for colors to be considered a keying color"); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "S: ", + butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Saturation Tolerance for the color"); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "V: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t3, 0.0f, 1.0f, 100, 0, "Value Tolerance for the color"); + + uiBlockEndAlign(block); + } + return 60; +} + + static int node_composit_buts_channel_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { if(block) { @@ -1977,6 +1991,29 @@ static int node_composit_buts_premulkey(uiBlock *block, bNodeTree *ntree, bNode return 20; } +static int node_composit_buts_view_levels(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + short sx= (butr->xmax-butr->xmin)/5; + + /*color space selectors*/ + uiBlockBeginAlign(block); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"C", + butr->xmin,butr->ymin,sx,20,&node->custom1,1,1, 0, 0, "Combined RGB"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"R", + butr->xmin+sx,butr->ymin,sx,20,&node->custom1,1,2, 0, 0, "Red Channel"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"G", + butr->xmin+2*sx,butr->ymin,sx,20,&node->custom1,1,3, 0, 0, "Green Channel"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"B", + butr->xmin+3*sx,butr->ymin,sx,20,&node->custom1,1,4, 0, 0, "Blue Channel"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"L", + butr->xmin+4*sx,butr->ymin,sx,20,&node->custom1,1,5, 0, 0, "Luminenc Channel"); + uiBlockEndAlign(block); + } + return 20; +} + + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2070,17 +2107,22 @@ static void node_composit_set_butfunc(bNodeType *ntype) break; case CMP_NODE_OUTPUT_FILE: ntype->butfunc= node_composit_buts_file_output; - break; - + break; case CMP_NODE_DIFF_MATTE: ntype->butfunc=node_composit_buts_diff_matte; break; + case CMP_NODE_DIST_MATTE: + ntype->butfunc=node_composit_buts_distance_matte; + break; case CMP_NODE_COLOR_SPILL: ntype->butfunc=node_composit_buts_color_spill; break; - case CMP_NODE_CHROMA: + case CMP_NODE_CHROMA_MATTE: ntype->butfunc=node_composit_buts_chroma_matte; break; + case CMP_NODE_COLOR_MATTE: + ntype->butfunc=node_composit_buts_color_matte; + break; case CMP_NODE_SCALE: ntype->butfunc= node_composit_buts_scale; break; @@ -2105,6 +2147,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_PREMULKEY: ntype->butfunc= node_composit_buts_premulkey; break; + case CMP_NODE_VIEW_LEVELS: + ntype->butfunc=node_composit_buts_view_levels; + break; default: ntype->butfunc= NULL; } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b3046ad1364..3fd358a1c16 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -747,43 +747,63 @@ static void def_cmp_scale(StructRNA *srna) static void def_cmp_diff_matte(StructRNA *srna) { PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeChroma", "storage"); + + /* TODO: nicer wrapping for tolerances */ - static EnumPropertyItem color_space_items[] = { - {1, "RGB", 0, "RGB", ""}, - {2, "HSV", 0, "HSV", ""}, - {3, "YUV", 0, "YUV", ""}, - {4, "YCC", 0, "YCbCr", ""}, - {0, NULL, 0, NULL, NULL} - }; + prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed."); - prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, color_space_items); - RNA_def_property_ui_text(prop, "Color Space", ""); + prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "t2"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed."); +} + +static void def_cmp_color_matte(StructRNA *srna) +{ + PropertyRNA *prop; RNA_def_struct_sdna_from(srna, "NodeChroma", "storage"); /* TODO: nicer wrapping for tolerances */ - prop = RNA_def_property(srna, "tolerance1", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "h", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Channel 1 Tolerance", ""); + RNA_def_property_ui_text(prop, "H", "Hue tolerance for colors to be considered a keying color"); - prop = RNA_def_property(srna, "tolerance2", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "s", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Channel 2 Tolerance", ""); + RNA_def_property_ui_text(prop, "S", "Saturation Tolerance for the color"); - prop = RNA_def_property(srna, "tolerance3", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "v", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t3"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Channel 3 Tolerance", ""); + RNA_def_property_ui_text(prop, "V", "Value Tolerance for the color"); +} + +static void def_cmp_distance_matte(StructRNA *srna) +{ + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeChroma", "storage"); + + /* TODO: nicer wrapping for tolerances */ + + prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "t1"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed."); prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "fstrength"); + RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Falloff", ""); + RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed."); } static void def_cmp_color_spill(StructRNA *srna) @@ -810,7 +830,7 @@ static void def_cmp_color_spill(StructRNA *srna) RNA_def_property_ui_text(prop, "Amount", "How much the selected channel is affected by"); } -static void def_cmp_chroma(StructRNA *srna) +static void def_cmp_chroma_matte(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 47a7be163b1..be4f131a6d6 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -82,7 +82,7 @@ DefNode( CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYU DefNode( CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" ) DefNode( CompositorNode, CMP_NODE_DIFF_MATTE, def_cmp_diff_matte, "DIFF_MATTE", DiffMatte, "Difference Key", "" ) DefNode( CompositorNode, CMP_NODE_COLOR_SPILL, def_cmp_color_spill, "COLOR_SPILL", ColorSpill, "Color Spill", "" ) -DefNode( CompositorNode, CMP_NODE_CHROMA, def_cmp_chroma, "CHROMA", Chroma, "Chroma Key", "" ) +DefNode( CompositorNode, CMP_NODE_CHROMA_MATTE, def_cmp_chroma_matte, "CHROMA_MATTE", ChromaMatte, "Chroma Key", "" ) DefNode( CompositorNode, CMP_NODE_CHANNEL_MATTE, def_cmp_channel_matte, "CHANNEL_MATTE", ChannelMatte, "Channel Key", "" ) DefNode( CompositorNode, CMP_NODE_FLIP, def_cmp_flip, "FLIP", Flip, "Flip", "" ) DefNode( CompositorNode, CMP_NODE_SPLITVIEWER, def_cmp_splitviewer, "SPLITVIEWER", SplitViewer, "Split Viewer", "" ) @@ -104,6 +104,9 @@ DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMU DefNode( CompositorNode, CMP_NODE_GLARE, def_cmp_glare, "GLARE", Glare, "Glare", "" ) DefNode( CompositorNode, CMP_NODE_TONEMAP, def_cmp_tonemap, "TONEMAP", Tonemap, "Tonemap", "" ) DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lensdist", "" ) +DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, 0, "LEVELS", Levels, "Levels", "" ) +DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Matte", "" ) +DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" ) 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/CMP_node.h b/source/blender/nodes/CMP_node.h index 020bbdebfa2..041bf1c8361 100644 --- a/source/blender/nodes/CMP_node.h +++ b/source/blender/nodes/CMP_node.h @@ -25,7 +25,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Bob Holcomb. * * ***** END GPL LICENSE BLOCK ***** */ @@ -49,6 +49,7 @@ extern bNodeType cmp_node_composite; extern bNodeType cmp_node_viewer; extern bNodeType cmp_node_splitviewer; extern bNodeType cmp_node_output_file; +extern bNodeType cmp_node_view_levels; extern bNodeType cmp_node_curve_rgb; extern bNodeType cmp_node_mix_rgb; @@ -88,7 +89,9 @@ extern bNodeType cmp_node_combycca; extern bNodeType cmp_node_premulkey; extern bNodeType cmp_node_diff_matte; -extern bNodeType cmp_node_chroma; +extern bNodeType cmp_node_distance_matte; +extern bNodeType cmp_node_chroma_matte; +extern bNodeType cmp_node_color_matte; extern bNodeType cmp_node_channel_matte; extern bNodeType cmp_node_color_spill; extern bNodeType cmp_node_luma_matte; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c index d0cc4e5b88d..b0a2531ac1f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Bob Holcomb * * ***** END GPL LICENSE BLOCK ***** */ @@ -180,7 +180,7 @@ static void node_composit_init_channel_matte(bNode *node) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage=c; - c->t1= 0.0f; + c->t1= 1.0f; c->t2= 0.0f; c->t3= 0.0f; c->fsize= 0.0f; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c index 6a40018e659..28b81fe9f47 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c @@ -172,9 +172,9 @@ static void node_composit_init_chroma_matte(bNode *node) c->fstrength= 1.0f; }; -bNodeType cmp_node_chroma={ +bNodeType cmp_node_chroma_matte={ /* *next,*prev */ NULL, NULL, - /* type code */ CMP_NODE_CHROMA, + /* type code */ CMP_NODE_CHROMA_MATTE, /* name */ "Chroma Key", /* width+range */ 200, 80, 300, /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c new file mode 100644 index 00000000000..0a4d3fceff9 --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c @@ -0,0 +1,132 @@ +/** + * $Id: CMP_colorMatte.c 12931 2007-12-17 18:20:48Z theeth $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Bob Holcomb + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../CMP_util.h" + +/* ******************* Color Key ********************************************************** */ +static bNodeSocketType cmp_node_color_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static bNodeSocketType cmp_node_color_out[]={ + {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static void do_color_key(bNode *node, float *out, float *in) +{ + NodeChroma *c; + c=node->storage; + + + VECCOPY(out, in); + + if(fabs(in[0]-c->key[0]) < c->t1 && + fabs(in[1]-c->key[1]) < c->t2 && + fabs(in[2]-c->key[2]) < c->t3) + { + out[3]=0.0; /*make transparent*/ + } + + else { /*pixel is outside key color */ + out[3]=in[3]; /* make pixel just as transparent as it was before */ + } +} + +static void node_composit_exec_color_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + CompBuf *cbuf; + CompBuf *colorbuf; + NodeChroma *c; + + if(in[0]->hasinput==0) return; + if(in[0]->data==NULL) return; + if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; + + cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + + colorbuf= dupalloc_compbuf(cbuf); + + c=node->storage; + + /*convert rgbbuf to hsv*/ + composit1_pixel_processor(node, colorbuf, cbuf, in[0]->vec, do_rgba_to_hsva, CB_RGBA); + + /*convert key to hsv*/ + do_rgba_to_hsva(node, c->key, in[1]->vec); + + + /*per pixel color key*/ + composit1_pixel_processor(node, colorbuf, colorbuf, in[0]->vec, do_color_key, CB_RGBA); + + /*convert back*/ + composit1_pixel_processor(node, colorbuf, colorbuf, in[0]->vec, do_hsva_to_rgba, CB_RGBA); + + out[0]->data= colorbuf; + if(out[1]->hasoutput) + out[1]->data= valbuf_from_rgbabuf(colorbuf, CHAN_A); + + generate_preview(node, colorbuf); + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); +}; + +static void node_composit_init_color_matte(bNode *node) +{ + NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node color"); + node->storage= c; + c->t1= 0.01f; + c->t2= 0.1f; + c->t3= 0.1f; + c->fsize= 0.0f; + c->fstrength= 1.0f; +}; + +bNodeType cmp_node_color_matte={ + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_COLOR_MATTE, + /* name */ "Color Key", + /* width+range */ 200, 80, 300, + /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ cmp_node_color_in, + /* output sock */ cmp_node_color_out, + /* storage */ "NodeChroma", + /* execfunc */ node_composit_exec_color_matte, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_color_matte, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL +}; + + diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c index ade2111f246..68a1bcd5471 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Bob Holcomb * * ***** END GPL LICENSE BLOCK ***** */ @@ -31,8 +31,8 @@ /* ******************* channel Difference Matte ********************************* */ static bNodeSocketType cmp_node_diff_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Image 1", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Image 2", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, {-1,0,""} }; @@ -44,157 +44,85 @@ static bNodeSocketType cmp_node_diff_matte_out[]={ /* note, keyvals is passed on from caller as stack array */ /* might have been nicer as temp struct though... */ -static void do_diff_matte(bNode *node, float *colorbuf, float *inbuf, float *keyvals) +static void do_diff_matte(bNode *node, float *colorbuf, float *imbuf1, float *imbuf2) { NodeChroma *c= (NodeChroma *)node->storage; - float *keymin= keyvals; - float *keymax= keyvals+3; - float *key= keyvals+6; - float tolerance= keyvals[9]; - float distance, alpha; + float tolerence=c->t1; + float falloff=c->t2; + float difference; + float alpha; - /*process the pixel if it is close to the key or already transparent*/ - if(((colorbuf[0]>keymin[0] && colorbuf[0]keymin[1] && colorbuf[1]keymin[2] && colorbuf[2] inbuf[3]) alpha= inbuf[3]; - if(alpha > c->fstrength) alpha= 0.0f; - - /*clamp*/ - if (alpha>1.0f) alpha=1.0f; - if (alpha<0.0f) alpha=0.0f; - - /*premultiplied picture*/ - colorbuf[3]= alpha; + difference=fabs(imbuf2[0]-imbuf1[0])+ + fabs(imbuf2[1]-imbuf1[1])+ + fabs(imbuf2[2]-imbuf1[2]); + + /*average together the distances*/ + difference=difference/3.0; + + VECCOPY(colorbuf, imbuf1); + + /*make 100% transparent*/ + if(difference < tolerence){ + colorbuf[3]=0.0; } + /*in the falloff region, make partially transparent */ + else if(difference < falloff+tolerence){ + difference=difference-tolerence; + alpha=difference/falloff; + /*only change if more transparent than before */ + if(alpha < imbuf1[3]) { + colorbuf[3]=alpha; + } + else { /* leave as before */ + colorbuf[3]=imbuf1[3]; + } + } else { /*foreground object*/ - colorbuf[3]= inbuf[3]; + colorbuf[3]= imbuf1[3]; } } static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - /* - Losely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and - uses a differnt difference function (suggested in forums of vfxtalk.com). - */ - CompBuf *workbuf; - CompBuf *inbuf; + CompBuf *outbuf; + CompBuf *imbuf1; + CompBuf *imbuf2; NodeChroma *c; - float keyvals[10]; - float *keymin= keyvals; - float *keymax= keyvals+3; - float *key= keyvals+6; - float *tolerance= keyvals+9; - float t[3]; /*is anything connected?*/ if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; /*must have an image imput*/ if(in[0]->data==NULL) return; + if(in[1]->data==NULL) return; - inbuf=typecheck_compbuf(in[0]->data, CB_RGBA); + imbuf1=typecheck_compbuf(in[0]->data, CB_RGBA); + imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA); c=node->storage; - workbuf=dupalloc_compbuf(inbuf); - - /*use the input color*/ - key[0]= in[1]->vec[0]; - key[1]= in[1]->vec[1]; - key[2]= in[1]->vec[2]; - - /*get the tolerances from the UI*/ - t[0]=c->t1; - t[1]=c->t2; - t[2]=c->t3; - - /*convert to colorspace*/ - switch(node->custom1) { - case 1: /*RGB*/ - break; - case 2: /*HSV*/ - /*convert the key (in place)*/ - rgb_to_hsv(key[0], key[1], key[2], &key[0], &key[1], &key[2]); - composit1_pixel_processor(node, workbuf, inbuf, in[1]->vec, do_rgba_to_hsva, CB_RGBA); - break; - case 3: /*YUV*/ - rgb_to_yuv(key[0], key[1], key[2], &key[0], &key[1], &key[2]); - composit1_pixel_processor(node, workbuf, inbuf, in[1]->vec, do_rgba_to_yuva, CB_RGBA); - break; - case 4: /*YCC*/ - rgb_to_ycc(key[0], key[1], key[2], &key[0], &key[1], &key[2]); - composit1_pixel_processor(node, workbuf, inbuf, in[1]->vec, do_rgba_to_ycca, CB_RGBA); - /*account for ycc is on a 0..255 scale*/ - t[0]= c->t1*255.0; - t[1]= c->t2*255.0; - t[2]= c->t3*255.0; - break; - default: - break; - } - - /*find min/max tolerances*/ - keymin[0]= key[0]-t[0]; - keymin[1]= key[1]-t[1]; - keymin[2]= key[2]-t[2]; - keymax[0]= key[0]+t[0]; - keymax[1]= key[1]+t[1]; - keymax[2]= key[2]+t[2]; - - /*tolerance*/ - *tolerance= sqrt((t[0])*(t[0])+ - (t[1])*(t[1])+ - (t[2])*(t[2])); + outbuf=dupalloc_compbuf(imbuf1); /* note, processor gets a keyvals array passed on as buffer constant */ - composit2_pixel_processor(node, workbuf, workbuf, in[0]->vec, NULL, keyvals, do_diff_matte, CB_RGBA, CB_VAL); + composit2_pixel_processor(node, outbuf, imbuf1, in[0]->vec, imbuf2, in[1]->vec, do_diff_matte, CB_RGBA, CB_RGBA); - /*convert back to RGB colorspace*/ - switch(node->custom1) { - case 1: /*RGB*/ - composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_copy_rgba, CB_RGBA); - break; - case 2: /*HSV*/ - composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_hsva_to_rgba, CB_RGBA); - break; - case 3: /*YUV*/ - composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA); - break; - case 4: /*YCC*/ - composit1_pixel_processor(node, workbuf, workbuf, in[1]->vec, do_ycca_to_rgba, CB_RGBA); - break; - default: - break; - } - - out[0]->data=workbuf; + out[0]->data=outbuf; if(out[1]->hasoutput) - out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A); - generate_preview(node, workbuf); + out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A); + generate_preview(node, outbuf); + + if(imbuf1!=in[0]->data) + free_compbuf(imbuf1); - if(inbuf!=in[0]->data) - free_compbuf(inbuf); + if(imbuf2!=in[1]->data) + free_compbuf(imbuf2); } static void node_composit_init_diff_matte(bNode *node) { NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); node->storage= c; - c->t1= 0.01f; - c->t2= 0.01f; - c->t3= 0.01f; - c->fsize= 0.0f; - c->fstrength= 0.0f; - node->custom1= 1; /* RGB */ + c->t1= 0.1f; + c->t2= 0.1f; } bNodeType cmp_node_diff_matte={ diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c new file mode 100644 index 00000000000..921ac869cb8 --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c @@ -0,0 +1,145 @@ +/** + * $Id: CMP_diffMatte.c 12931 2007-12-17 18:20:48Z theeth $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Bob Holcomb + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../CMP_util.h" + +/* ******************* channel Distance Matte ********************************* */ +static bNodeSocketType cmp_node_distance_matte_in[]={ + {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static bNodeSocketType cmp_node_distance_matte_out[]={ + {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +/* note, keyvals is passed on from caller as stack array */ +/* might have been nicer as temp struct though... */ +static void do_distance_matte(bNode *node, float *out, float *in) +{ + NodeChroma *c= (NodeChroma *)node->storage; + float tolerence=c->t1; + float falloff=c->t2; + float distance; + float alpha; + + distance=sqrt((c->key[0]-in[0])*(c->key[0]-in[0]) + + (c->key[1]-in[1])*(c->key[1]-in[1]) + + (c->key[2]-in[2])*(c->key[2]-in[2])); + + VECCOPY(out, in); + + /*make 100% transparent */ + if(distance < tolerence) { + out[3]=0.0; + } + /*in the falloff region, make partially transparent */ + else if(distance < falloff+tolerence){ + distance=distance-tolerence; + alpha=distance/falloff; + /*only change if more transparent than before */ + if(alpha < in[3]) { + out[3]=alpha; + } + else { /* leave as before */ + out[3]=in[3]; + } + } + else { + out[3]=in[3]; + } +} + +static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* + Losely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and + uses a differnt difference function (suggested in forums of vfxtalk.com). + */ + CompBuf *workbuf; + CompBuf *inbuf; + NodeChroma *c; + + /*is anything connected?*/ + if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; + /*must have an image imput*/ + if(in[0]->data==NULL) return; + + inbuf=typecheck_compbuf(in[0]->data, CB_RGBA); + + c=node->storage; + workbuf=dupalloc_compbuf(inbuf); + + /*use the input color*/ + c->key[0]= in[1]->vec[0]; + c->key[1]= in[1]->vec[1]; + c->key[2]= in[1]->vec[2]; + + /* note, processor gets a keyvals array passed on as buffer constant */ + composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA); + + + out[0]->data=workbuf; + if(out[1]->hasoutput) + out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A); + generate_preview(node, workbuf); + + if(inbuf!=in[0]->data) + free_compbuf(inbuf); +} + +static void node_composit_init_distance_matte(bNode *node) +{ + NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); + node->storage= c; + c->t1= 0.1f; + c->t2= 0.1f; +} + +bNodeType cmp_node_distance_matte={ + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_DIST_MATTE, + /* name */ "Distance Key", + /* width+range */ 200, 80, 250, + /* class+opts */ NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ cmp_node_distance_matte_in, + /* output sock */ cmp_node_distance_matte_out, + /* storage */ "NodeChroma", + /* execfunc */ node_composit_exec_distance_matte, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_distance_matte, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL +}; + + diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c new file mode 100644 index 00000000000..414c535789e --- /dev/null +++ b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c @@ -0,0 +1,337 @@ +/** + * $Id: CMP_levels.c 12931 2007-12-17 18:20:48Z theeth $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Bob Holcomb. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../CMP_util.h" + + +/* **************** LEVELS ******************** */ +static bNodeSocketType cmp_node_view_levels_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_view_levels_out[]={ + {SOCK_VALUE, 0,"Mean",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {SOCK_VALUE, 0,"Std Dev",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + {-1,0,""} +}; + +static void rgb_tobw(float r, float g, float b, float* out) +{ + *out= r*0.35f + g*0.45f + b*0.2f; +} + +static void fill_bins(bNode* node, CompBuf* in, int* bins) +{ + float value[4]; + int ivalue; + int x,y; + + /*fill bins */ + for(y=0; yy; y++) { + for(x=0; xx; x++) { + + /* get the pixel */ + qd_getPixel(in, x, y, value); + + if(value[3] > 0.0) { /* don't count transparent pixels */ + switch(node->custom1) { + case 1: { /* all colors */ + rgb_tobw(value[0],value[1],value[2], &value[0]); + value[0]=value[0]*255; /* scale to 0-255 range */ + ivalue=(int)value[0]; + break; + } + case 2: { /* red channel */ + value[0]=value[0]*255; /* scale to 0-255 range */ + ivalue=(int)value[0]; + break; + } + case 3: { /* green channel */ + value[1]=value[1]*255; /* scale to 0-255 range */ + ivalue=(int)value[1]; + break; + } + case 4: /*blue channel */ + { + value[2]=value[2]*255; /* scale to 0-255 range */ + ivalue=(int)value[2]; + break; + } + case 5: /* luminence */ + { + rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); + value[0]=value[0]*255; /* scale to 0-255 range */ + ivalue=(int)value[0]; + break; + } + } /*end switch */ + + /*clip*/ + if(ivalue<0) ivalue=0; + if(ivalue>255) ivalue=255; + + /*put in the correct bin*/ + bins[ivalue]+=1; + } /*end if alpha */ + } + } +} + +static float brightness_mean(bNode* node, CompBuf* in) +{ + float sum=0.0; + int numPixels=0.0; + int x,y; + float value[4]; + + for(x=0; x< in->x; x++) { + for(y=0; y < in->y; y++) { + + /* get the pixel */ + qd_getPixel(in, x, y, value); + + if(value[3] > 0.0) { /* don't count transparent pixels */ + numPixels++; + switch(node->custom1) + { + case 1: + { + rgb_tobw(value[0],value[1],value[2], &value[0]); + sum+=value[0]; + break; + } + case 2: + { + sum+=value[0]; + break; + } + case 3: + { + sum+=value[1]; + break; + } + case 4: + { + sum+=value[2]; + break; + } + case 5: + { + rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); + sum+=value[0]; + break; + } + } + } + } + } + + return sum/numPixels; +} + +static float brightness_standard_deviation(bNode* node, CompBuf* in, float mean) +{ + float sum=0.0; + int numPixels=0.0; + int x,y; + float value[4]; + + for(x=0; x< in->x; x++) { + for(y=0; y < in->y; y++) { + + /* get the pixel */ + qd_getPixel(in, x, y, value); + + if(value[3] > 0.0) { /* don't count transparent pixels */ + numPixels++; + switch(node->custom1) + { + case 1: + { + rgb_tobw(value[0],value[1],value[2], &value[0]); + sum+=(value[0]-mean)*(value[0]-mean); + break; + } + case 2: + { + sum+=value[0]; + sum+=(value[0]-mean)*(value[0]-mean); + break; + } + case 3: + { + sum+=value[1]; + sum+=(value[1]-mean)*(value[1]-mean); + break; + } + case 4: + { + sum+=value[2]; + sum+=(value[2]-mean)*(value[2]-mean); + break; + } + case 5: + { + rgb_to_yuv(value[0],value[1],value[2], &value[0], &value[1], &value[2]); + sum+=(value[0]-mean)*(value[0]-mean); + break; + } + } + } + } + } + + + return sqrt(sum/(float)(numPixels-1)); +} + +static void draw_histogram(bNode *node, CompBuf *out, int* bins) +{ + int x,y; + float color[4]; + float value; + int max; + + /* find max value */ + max=0; + for(x=0; x<256; x++) { + if(bins[x]>max) max=bins[x]; + } + + /*draw histogram in buffer */ + for(x=0; xx; x++) { + for(y=0;yy; y++) { + + /* get normalized value (0..255) */ + value=((float)bins[x]/(float)max)*255.0; + + if(y < (int)value) { /*if the y value is below the height of the bar for this line then draw with the color */ + switch (node->custom1) { + case 1: { /* draw in black */ + color[0]=0.0; color[1]=0.0; color[2]=0.0; color[3]=1.0; + break; + } + case 2: { /* draw in red */ + color[0]=1.0; color[1]=0.0; color[2]=0.0; color[3]=1.0; + break; + } + case 3: { /* draw in green */ + color[0]=0.0; color[1]=1.0; color[2]=0.0; color[3]=1.0; + break; + } + case 4: { /* draw in blue */ + color[0]=0.0; color[1]=0.0; color[2]=1.0; color[3]=1.0; + break; + } + case 5: { /* draw in white */ + color[0]=1.0; color[1]=1.0; color[2]=1.0; color[3]=1.0; + break; + } + } + } + else{ + color[0]=0.8; color[1]=0.8; color[2]=0.8; color[3]=1.0; + } + + /* set the color */ + qd_setPixel(out, x, y, color); + } + } +} + +static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + CompBuf* cbuf; + CompBuf* histogram; + float mean, std_dev; + int bins[256]; + int x; + + if(in[0]->hasinput==0) return; + if(in[0]->data==NULL) return; + + histogram=alloc_compbuf(256, 256, CB_RGBA, 1); + cbuf=typecheck_compbuf(in[0]->data, CB_RGBA); + + /*initalize bins*/ + for(x=0; x<256; x++) { + bins[x]=0; + } + + /*fill bins */ + fill_bins(node, in[0]->data, bins); + + /* draw the histogram chart */ + draw_histogram(node, histogram, bins); + + /* calculate the average brightness and contrast */ + mean=brightness_mean(node, in[0]->data); + std_dev=brightness_standard_deviation(node, in[0]->data, mean); + + /* Printf debuging ;) + printf("Mean: %f\n", mean); + printf("Std Dev: %f\n", std_dev); + */ + + if(out[0]->hasoutput) + out[0]->vec[0]= mean; + if(out[1]->hasoutput) + out[1]->vec[0]= std_dev; + + generate_preview(node, histogram); + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + free_compbuf(histogram); +} + +static void node_composit_init_view_levels(bNode* node) +{ + node->custom1=1; /*All channels*/ +} + +bNodeType cmp_node_view_levels= { + /* *next,*prev */ NULL, NULL, + /* type code */ CMP_NODE_VIEW_LEVELS, + /* name */ "Levels", + /* widthrange */ 140, 100, 320, + /* classopts */ NODE_CLASS_OUTPUT, NODE_OPTIONS|NODE_PREVIEW, + /* input sock */ cmp_node_view_levels_in, + /* output sock */ cmp_node_view_levels_out, + /* storage */ "ImageUser", + /* execfunc */ node_composit_exec_view_levels, + /* butfunc */ NULL, + /* initfunc */ node_composit_init_view_levels, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, + /* id */ NULL + +}; + diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c index 9aebd999b29..350def76736 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Bob Holcomb . * * ***** END GPL LICENSE BLOCK ***** */ diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c index f9805645115..b396d5549d7 100644 --- a/source/blender/nodes/intern/CMP_util.c +++ b/source/blender/nodes/intern/CMP_util.c @@ -1104,9 +1104,23 @@ void qd_getPixel(CompBuf* src, int x, int y, float* col) { if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) { float* bc = &src->rect[(x + y*src->x)*src->type]; - col[0] = bc[0], col[1] = bc[1], col[2] = bc[2]; + switch(src->type){ + /* these fallthrough to get all the channels */ + case CB_RGBA: col[3]=bc[3]; + case CB_VEC3: col[2]=bc[2]; + case CB_VEC2: col[1]=bc[1]; + case CB_VAL: col[0]=bc[0]; + } + } + else { + switch(src->type){ + /* these fallthrough to get all the channels */ + case CB_RGBA: col[3]=0.0; + case CB_VEC3: col[2]=0.0; + case CB_VEC2: col[1]=0.0; + case CB_VAL: col[0]=0.0; + } } - else col[0] = col[1] = col[2] = 0.f; } // sets pixel (x, y) to color col @@ -1114,7 +1128,13 @@ void qd_setPixel(CompBuf* src, int x, int y, float* col) { if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) { float* bc = &src->rect[(x + y*src->x)*src->type]; - bc[0] = col[0], bc[1] = col[1], bc[2] = col[2]; + switch(src->type){ + /* these fallthrough to get all the channels */ + case CB_RGBA: bc[3]=col[3]; + case CB_VEC3: bc[2]=col[2]; + case CB_VEC2: bc[1]=col[1]; + case CB_VAL: bc[0]=col[0]; + } } } diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 19e41f5c118..2a2dc97ed73 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -168,7 +168,7 @@ typedef float fRGB[4]; /* clear color */ #define fRGB_clear(c) { c[0]=c[1]=c[2]=0.f; } /* copy c2 to c1 */ -#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; } +#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; c1[3]=c2[3]; } /* add c2 to c1 */ #define fRGB_add(c1, c2) { c1[0]+=c2[0]; c1[1]+=c2[1]; c1[2]+=c2[2]; } /* subtract c2 from c1 */ @@ -186,7 +186,8 @@ typedef float fRGB[4]; /* 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[2]; c1[2]=c2[2]; c2[2]=_t;\ + _t=c1[3]; c1[3]=c2[3]; c3[3]=_t;} void qd_getPixel(CompBuf* src, int x, int y, float* col); void qd_setPixel(CompBuf* src, int x, int y, float* col); -- cgit v1.2.3 From 96de4cd9a82d69b576e2829f4c867b656d6fc049 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 10 Sep 2009 10:35:51 +0000 Subject: Smoke: * Bugfix for loading saved files --- source/blender/blenloader/intern/readfile.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b6fc9f7af12..37031f4f82a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3685,8 +3685,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->domain->smd = smd; smd->domain->fluid = NULL; - // smd->domain->view3d = NULL; - // smd->domain->tex = NULL; + smd->domain->wt = NULL; + smd->domain->shadow = NULL; + smd->domain->tex = NULL; + smd->domain->tex_shadow = NULL; + smd->domain->tex_wt = NULL; direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0])); direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1])); -- cgit v1.2.3 From 15d77f17a40398a63f95e16607deb81257c02698 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Sep 2009 11:04:53 +0000 Subject: 2.5: UV Edit * Make mirror operator and menus work. * Added TFM_OT_mirror transform operator specific for mirror. * Assign image from image space when unwrapping in 3d view. --- source/blender/editors/transform/transform.c | 20 ++++++---- source/blender/editors/transform/transform_ops.c | 25 ++++++++++++- source/blender/editors/uvedit/uvedit_ops.c | 45 ----------------------- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 33 +++++++++++++++-- source/blender/makesrna/intern/rna_access.c | 2 +- 5 files changed, 67 insertions(+), 58 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 1f568be3e10..f049566d640 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1257,13 +1257,16 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) int constraint_axis[3] = {0, 0, 0}; int proportional = 0; - if (t->flag & T_AUTOVALUES) - { - RNA_float_set_array(op->ptr, "value", t->auto_values); - } - else + if (RNA_struct_find_property(op->ptr, "value")) { - RNA_float_set_array(op->ptr, "value", t->values); + if (t->flag & T_AUTOVALUES) + { + RNA_float_set_array(op->ptr, "value", t->auto_values); + } + else + { + RNA_float_set_array(op->ptr, "value", t->values); + } } /* XXX convert stupid flag to enum */ @@ -4145,7 +4148,10 @@ int Mirror(TransInfo *t, short mval[2]) recalcData(t); - ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)"); + if(t->flag & T_2D_EDIT) + ED_area_headerprint(t->sa, "Select a mirror axis (X, Y)"); + else + ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)"); } return 1; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 08d22faf7e7..4ae0bca3284 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -98,6 +98,7 @@ char OP_WARP[] = "TFM_OT_warp"; char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten"; char OP_TILT[] = "TFM_OT_tilt"; char OP_TRACKBALL[] = "TFM_OT_trackball"; +char OP_MIRROR[] = "TFM_OT_mirror"; TransformModeItem transform_modes[] = @@ -111,6 +112,7 @@ TransformModeItem transform_modes[] = {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN}, {OP_TILT, TFM_TILT}, {OP_TRACKBALL, TFM_TRACKBALL}, + {OP_MIRROR, TFM_MIRROR}, {NULL, 0} }; @@ -528,6 +530,25 @@ void TFM_OT_tosphere(struct wmOperatorType *ot) RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); } +void TFM_OT_mirror(struct wmOperatorType *ot) +{ + /* identifiers */ + 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; + + /* api callbacks */ + ot->invoke = transform_invoke; + ot->exec = transform_exec; + ot->modal = transform_modal; + ot->cancel = transform_cancel; + ot->poll = ED_operator_areaactive; + + Properties_Proportional(ot); + Properties_Constraints(ot); +} + void TFM_OT_transform(struct wmOperatorType *ot) { static EnumPropertyItem transform_mode_types[] = { @@ -595,6 +616,7 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_shrink_fatten); WM_operatortype_append(TFM_OT_tilt); WM_operatortype_append(TFM_OT_trackball); + WM_operatortype_append(TFM_OT_mirror); WM_operatortype_append(TFM_OT_select_orientation); } @@ -699,8 +721,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); - km = WM_keymap_add_item(keymap, "TFM_OT_transform", MKEY, KM_PRESS, 0, 0); - RNA_int_set(km->ptr, "mode", TFM_MIRROR); + km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, 0, 0); break; default: break; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index a44421e8145..9051300e117 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -942,50 +942,6 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2] EM_free_uv_vert_map(vmap); } -/* ******************** mirror operator **************** */ - -static int mirror_exec(bContext *C, wmOperator *op) -{ - float mat[3][3]; - int axis; - - Mat3One(mat); - axis= RNA_enum_get(op->ptr, "axis"); - - if(axis == 'x') { - /* XXX initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM); - BIF_setSingleAxisConstraint(mat[0], " on X axis"); - Transform(); */ - } - else { - /* XXX initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM); - BIF_setSingleAxisConstraint(mat[1], " on Y axis"); - Transform(); */ - } - - return OPERATOR_FINISHED; -} - -void UV_OT_mirror(wmOperatorType *ot) -{ - static EnumPropertyItem axis_items[] = { - {'x', "MIRROR_X", 0, "Mirror X", "Mirror UVs over X axis."}, - {'y', "MIRROR_Y", 0, "Mirror Y", "Mirror UVs over Y axis."}, - {0, NULL, 0, NULL, NULL}}; - - /* identifiers */ - ot->name= "Mirror"; - ot->idname= "UV_OT_mirror"; - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* api callbacks */ - ot->exec= mirror_exec; - ot->poll= ED_operator_uvedit; - - /* properties */ - RNA_def_enum(ot->srna, "axis", axis_items, 'x', "Axis", "Axis to mirror UV locations over."); -} - /* ******************** align operator **************** */ static void weld_align_uv(bContext *C, int tool) @@ -3092,7 +3048,6 @@ void ED_operatortypes_uvedit(void) WM_operatortype_append(UV_OT_snap_selection); WM_operatortype_append(UV_OT_align); - WM_operatortype_append(UV_OT_mirror); WM_operatortype_append(UV_OT_stitch); WM_operatortype_append(UV_OT_weld); WM_operatortype_append(UV_OT_pin); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index c18c9f8e022..b20d390fb4d 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -44,6 +44,7 @@ #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_mesh.h" #include "BKE_utildefines.h" @@ -75,6 +76,11 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); EditFace *efa; MTFace *tf; + Image *ima; + bScreen *sc; + ScrArea *sa; + SpaceLink *slink; + SpaceImage *sima; if(ED_uvedit_test(obedit)) { BKE_mesh_end_editmesh(obedit->data, em); @@ -88,10 +94,31 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) BKE_mesh_end_editmesh(obedit->data, em); return 0; } + + ima= CTX_data_edit_image(C); + + if(!ima) { + /* no image in context in the 3d view, we find first image window .. */ + sc= CTX_wm_screen(C); + + for(sa=sc->areabase.first; sa; sa=sa->next) { + slink= sa->spacedata.first; + if(slink->spacetype == SPACE_IMAGE) { + sima= (SpaceImage*)slink; + + ima= sima->image; + if(ima) { + if(ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE) + ima= NULL; + else + break; + } + } + } + } - // XXX this image is not in context in 3d view .. only - // way to get would be to find the first image window? - ED_uvedit_assign_image(scene, obedit, CTX_data_edit_image(C), NULL); + if(ima) + ED_uvedit_assign_image(scene, obedit, ima, NULL); /* select new UV's */ for(efa=em->faces.first; efa; efa=efa->next) { diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 417ace6a455..e4bda24cf20 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2748,7 +2748,7 @@ int RNA_property_is_set(PointerRNA *ptr, const char *name) return (rna_idproperty_find(ptr, name) != NULL); } else { - printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name); + // printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name); return 0; } } -- cgit v1.2.3 From cfb6f35f9fd2905b7d51b78258f98ab45d2c5ced Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Sep 2009 14:20:21 +0000 Subject: UI: * layout.itemR now has icon_only option to show only icon in e.g. enums buttons, for uv editor header. * Automatic key shortcuts in menus now show the shortcut even if operator properties don't match. Not sure this will work well everywhere, but seems to be working ok for now. * Open recent now show shorter filenames instead of the whole file path. * Tweak object Duplicate menu item. --- release/ui/space_image.py | 18 ++++++---- release/ui/space_view3d.py | 2 +- source/blender/blenlib/BLI_fileops.h | 1 + source/blender/blenlib/intern/fileops.c | 25 ++++++++++++++ source/blender/editors/include/UI_interface.h | 1 + .../blender/editors/interface/interface_layout.c | 31 +++++++++-------- source/blender/editors/interface/interface_utils.c | 7 +++- source/blender/editors/object/object_add.c | 2 +- source/blender/editors/object/object_ops.c | 2 +- source/blender/windowmanager/intern/wm_keymap.c | 40 +++++++++++++++------- source/blender/windowmanager/intern/wm_operators.c | 2 +- 11 files changed, 91 insertions(+), 40 deletions(-) diff --git a/release/ui/space_image.py b/release/ui/space_image.py index 3f82727da47..0d0fd86ef8c 100644 --- a/release/ui/space_image.py +++ b/release/ui/space_image.py @@ -126,9 +126,9 @@ class IMAGE_MT_uvs_transform(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.item_enumO("tfm.transform", "mode", 'TRANSLATION') - layout.item_enumO("tfm.transform", "mode", 'ROTATION') - layout.item_enumO("tfm.transform", "mode", 'RESIZE') + layout.itemO("tfm.translate") + layout.itemO("tfm.rotate") + layout.itemO("tfm.resize") class IMAGE_MT_uvs_mirror(bpy.types.Menu): __space_type__ = 'IMAGE_EDITOR' @@ -136,9 +136,13 @@ class IMAGE_MT_uvs_mirror(bpy.types.Menu): def draw(self, context): layout = self.layout + layout.operator_context = "EXEC_REGION_WIN" - layout.item_enumO("uv.mirror", "axis", 'MIRROR_X') # "X Axis", M, - layout.item_enumO("uv.mirror", "axis", 'MIRROR_Y') # "Y Axis", M, + props= layout.itemO("tfm.mirror", text="X Axis", properties=True) + props.constraint_axis[0]= True + + props= layout.itemO("tfm.mirror", text="Y Axis", properties=True) + props.constraint_axis[1]= True class IMAGE_MT_uvs_weldalign(bpy.types.Menu): __space_type__ = 'IMAGE_EDITOR' @@ -233,14 +237,14 @@ class IMAGE_HT_header(bpy.types.Header): if show_uvedit: uvedit = sima.uv_editor - layout.itemR(uvedit, "pivot", text="") + layout.itemR(uvedit, "pivot", text="", icon_only=True) layout.itemR(settings, "uv_sync_selection", text="") if settings.uv_sync_selection: layout.itemR(settings, "mesh_selection_mode", text="", expand=True) else: layout.itemR(settings, "uv_selection_mode", text="", expand=True) - layout.itemR(uvedit, "sticky_selection_mode", text="") + layout.itemR(uvedit, "sticky_selection_mode", text="", icon_only=True) pass row = layout.row(align=True) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index bc133cbff48..df6579542d4 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -410,7 +410,7 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu): layout.itemS() - layout.itemO("object.duplicate") + layout.itemO("object.duplicate_move") layout.item_booleanO("object.duplicate", "linked", True, text="Duplicate Linked") layout.itemO("object.delete", text="Delete...") layout.itemO("object.proxy_make", text="Make Proxy...") diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index 0c1cdbc4d3a..b79920b188b 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -54,6 +54,7 @@ char *BLI_last_slash(const char *string); int BLI_add_slash(char *string); void BLI_del_slash(char *string); char *first_slash(char *string); +const char *BLI_short_filename(const char *string); /* only for the sane unix world: direct calls to system functions :( */ #ifndef WIN32 diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index e7dc9b0eb1f..15277c438f4 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -84,6 +84,31 @@ char *BLI_last_slash(const char *string) { else return lfslash; } +static const char *last_slash_len(const char *string, int len) { + int a; + + for(a=len-1; a>=0; a--) + if(string[a] == '/' || string[a] == '\\') + return &string[a]; + + return NULL; +} + +const char *BLI_short_filename(const char *string) { + const char *ls, *lls; + + ls= last_slash_len(string, strlen(string)); + if(!ls) + return string; + + lls= last_slash_len(string, ls-string); + + if(lls) + return lls+1; + else + return ls+1; +} + /* adds a slash if there isnt one there alredy */ int BLI_add_slash(char *string) { int len = strlen(string); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index e2338078a8a..b45ab2d4997 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -589,6 +589,7 @@ void UI_exit(void); #define UI_ITEM_R_EXPAND 2 #define UI_ITEM_R_SLIDER 4 #define UI_ITEM_R_TOGGLE 8 +#define UI_ITEM_R_ICON_ONLY 16 uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style); void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 04d575d96d4..bf449dba597 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -443,7 +443,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon uiBlockSetCurLayout(block, layout); } -static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, char *uiname, int x, int y, int w, int h) +static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, char *uiname, int x, int y, int w, int h, int icon_only) { EnumPropertyItem *item; const char *identifier; @@ -463,7 +463,7 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, value= item[a].value; itemw= ui_text_icon_width(block->curlayout, name, icon, 0); - if(icon && strcmp(name, "") != 0) + if(icon && strcmp(name, "") != 0 && !icon_only) uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); else if(icon) uiDefIconButR(block, ROW, 0, icon, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); @@ -477,7 +477,7 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, } /* create label + button for RNA property */ -static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h) +static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h, int icon_only) { uiLayout *sub; uiBut *but; @@ -506,7 +506,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i but= uiDefIconButO(block, BUT, "BUTTONS_OT_file_browse", WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, "Browse for file or directory."); } else - but= uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h); + but= uiDefAutoButR(block, ptr, prop, index, (icon_only)? "": NULL, icon, x, y, w, h); uiBlockSetCurLayout(block, layout); return but; @@ -788,7 +788,7 @@ void uiItemO(uiLayout *layout, char *name, int icon, char *opname) /* RNA property items */ -static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int *r_w, int *r_h) +static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int icon_only, int *r_w, int *r_h) { PropertyType type; PropertySubType subtype; @@ -799,9 +799,9 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PointerRNA subtype= RNA_property_subtype(prop); len= RNA_property_array_length(ptr, prop); - if(ELEM3(type, PROP_STRING, PROP_POINTER, PROP_ENUM) && !name[0]) + if(ELEM3(type, PROP_STRING, PROP_POINTER, PROP_ENUM) && !name[0] && !icon_only) name= "non-empty text"; - else if(type == PROP_BOOLEAN && !name[0]) + else if(type == PROP_BOOLEAN && !name[0] && !icon_only) icon= ICON_DOT; w= ui_text_icon_width(layout, name, icon, 0); @@ -823,7 +823,7 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PointerRNA if(type == PROP_BOOLEAN && strcmp(name, "") != 0) w += UI_UNIT_X/5; else if(type == PROP_ENUM) - w += UI_UNIT_X/2; + w += UI_UNIT_X/4; else if(type == PROP_FLOAT || type == PROP_INT) w += UI_UNIT_X*3; } @@ -838,7 +838,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper uiBut *but; PropertyType type; char namestr[UI_MAX_NAME_STR]; - int len, w, h, slider, toggle, expand; + int len, w, h, slider, toggle, expand, icon_only; if(!ptr->data || !prop) return; @@ -872,9 +872,10 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper slider= (flag & UI_ITEM_R_SLIDER); toggle= (flag & UI_ITEM_R_TOGGLE); expand= (flag & UI_ITEM_R_EXPAND); + icon_only= (flag & UI_ITEM_R_ICON_ONLY); /* get size */ - ui_item_rna_size(layout, name, icon, ptr, prop, index, &w, &h); + ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, &w, &h); /* array property */ if(index == RNA_NO_INDEX && len > 0) @@ -883,7 +884,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) { char *identifier= (char*)RNA_property_identifier(prop); - if(icon && strcmp(name, "") != 0) + if(icon && strcmp(name, "") != 0 && !icon_only) uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); else if(icon) uiDefIconButR(block, ROW, 0, icon, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); @@ -892,10 +893,10 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper } /* expanded enum */ else if(type == PROP_ENUM && expand) - ui_item_enum_row(layout, block, ptr, prop, name, 0, 0, w, h); + ui_item_enum_row(layout, block, ptr, prop, name, 0, 0, w, h, icon_only); /* property with separate label */ else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) { - but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h); + but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, icon_only); ui_but_add_search(but, ptr, prop, NULL, NULL); } /* single button */ @@ -1160,8 +1161,8 @@ void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *p /* create button */ block= uiLayoutGetBlock(layout); - ui_item_rna_size(layout, name, icon, ptr, prop, 0, &w, &h); - but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h); + ui_item_rna_size(layout, name, icon, ptr, prop, 0, 0, &w, &h); + but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h, 0); ui_but_add_search(but, ptr, prop, searchptr, searchprop); } diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 5b44f6544d1..63f81c9e46c 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -108,7 +108,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); break; case PROP_ENUM: - but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + if(icon && name && strcmp(name, "") == 0) + but= uiDefIconButR(block, MENU, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + else if(icon) + but= uiDefIconTextButR(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + else + but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); break; case PROP_STRING: if(icon && name && strcmp(name, "") == 0) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index eaf7d41b9fe..f4c8c63c480 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1122,7 +1122,7 @@ void OBJECT_OT_convert(wmOperatorType *ot) RNA_def_boolean(ot->srna, "keep_original", 0, "Keep Original", "Keep original objects instead of replacing them."); } -/************************** Add Duplicate **********************/ +/**************************** Duplicate ************************/ /* dupflag: a flag made from constants declared in DNA_userdef_types.h diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index bb8c5dc292e..ddcecdeb1f1 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -176,7 +176,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(LATTICE_OT_make_regular); /* macros */ - ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); + ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); if(ot) { WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate"); WM_operatortype_macro_define(ot, "TFM_OT_translate"); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index ad0dd786791..5566aeba260 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -242,33 +242,41 @@ static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len) return str; } -static wmKeymapItem *wm_keymap_item_find_handlers(ListBase *handlers, const char *opname, int opcontext, IDProperty *properties) +static wmKeymapItem *wm_keymap_item_find_handlers(ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props) { wmEventHandler *handler; wmKeymapItem *kmi; /* find keymap item in handlers */ - for(handler=handlers->first; handler; handler=handler->next) - if(handler->keymap) - for(kmi=handler->keymap->first; kmi; kmi=kmi->next) - if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) - if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) + for(handler=handlers->first; handler; handler=handler->next) { + if(handler->keymap) { + for(kmi=handler->keymap->first; kmi; kmi=kmi->next) { + if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) { + if(compare_props) { + if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) + return kmi; + } + else return kmi; + } + } + } + } return NULL; } -static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, int opcontext, IDProperty *properties) +static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, int opcontext, IDProperty *properties, int compare_props) { wmKeymapItem *found= NULL; /* look into multiple handler lists to find the item */ if(CTX_wm_window(C)) - found= wm_keymap_item_find_handlers(&CTX_wm_window(C)->handlers, opname, opcontext, properties); + found= wm_keymap_item_find_handlers(&CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props); if(CTX_wm_area(C) && found==NULL) - found= wm_keymap_item_find_handlers(&CTX_wm_area(C)->handlers, opname, opcontext, properties); + found= wm_keymap_item_find_handlers(&CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props); if(found==NULL) { if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) { @@ -279,12 +287,12 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, break; if(ar) - found= wm_keymap_item_find_handlers(&ar->handlers, opname, opcontext, properties); + found= wm_keymap_item_find_handlers(&ar->handlers, opname, opcontext, properties, compare_props); } } else { if(CTX_wm_region(C)) - found= wm_keymap_item_find_handlers(&CTX_wm_region(C)->handlers, opname, opcontext, properties); + found= wm_keymap_item_find_handlers(&CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props); } } @@ -293,7 +301,10 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, char *WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, IDProperty *properties, char *str, int len) { - wmKeymapItem *found= wm_keymap_item_find(C, opname, opcontext, properties); + wmKeymapItem *found= wm_keymap_item_find(C, opname, opcontext, properties, 1); + + if(!found) + found= wm_keymap_item_find(C, opname, opcontext, properties, 0); if(found) { wm_keymap_item_to_string(found, str, len); @@ -306,7 +317,10 @@ char *WM_key_event_operator_string(const bContext *C, const char *opname, int op /* searches context and changes keymap item, if found */ void WM_key_event_operator_change(const bContext *C, const char *opname, int opcontext, IDProperty *properties, short key, short modifier) { - wmKeymapItem *found= wm_keymap_item_find(C, opname, opcontext, properties); + wmKeymapItem *found= wm_keymap_item_find(C, opname, opcontext, properties, 1); + + if(!found) + found= wm_keymap_item_find(C, opname, opcontext, properties, 0); if(found) { keymap_event_set(found, key, KM_PRESS, modifier, 0); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 0913d58258f..6debe5a8825 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -837,7 +837,7 @@ static EnumPropertyItem *open_recentfile_itemf(bContext *C, PointerRNA *ptr, int for(recent = G.recent_files.first, i=0; (inext, i++) { tmp.value= i+ofs+1; tmp.identifier= recent->filename; - tmp.name= recent->filename; + tmp.name= BLI_short_filename(recent->filename); RNA_enum_item_add(&item, &totitem, &tmp); } -- cgit v1.2.3 From bfe57bb0850a8cd19274a0b97e95ec4bae802360 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 10 Sep 2009 18:58:31 +0000 Subject: Added repeat operations to the toolbar. --- release/ui/space_view3d_toolbar.py | 72 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 73f97dec750..9dd2df14492 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -40,6 +40,13 @@ class VIEW3D_PT_tools_objectmode(View3DPanel): col = layout.column(align=True) col.itemO("anim.insert_keyframe_menu", text="Insert") col.itemO("anim.delete_keyframe_v3d", text="Remove") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_mesh **************** @@ -83,6 +90,13 @@ class VIEW3D_PT_tools_meshedit(View3DPanel): col.itemO("uv.mapping_menu", text="Unwrap") col.itemO("mesh.uvs_rotate") col.itemO("mesh.uvs_mirror") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_curve **************** @@ -114,6 +128,13 @@ class VIEW3D_PT_tools_curveedit(View3DPanel): col = layout.column(align=True) col.itemO("curve.extrude") col.itemO("curve.subdivide") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_surface **************** @@ -144,6 +165,13 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel): col = layout.column(align=True) col.itemO("curve.extrude") col.itemO("curve.subdivide") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_text **************** @@ -153,14 +181,26 @@ class VIEW3D_PT_tools_textedit(View3DPanel): def draw(self, context): layout = self.layout - + + layout.itemL(text="Text Edit:") + col = layout.column(align=True) col.itemO("font.text_copy", text="Copy") + col.itemO("font.text_cut", text="Cut") col.itemO("font.text_paste", text="Paste") - col = layout.column() + layout.itemL(text="Style:") + + col = layout.column(align=True) col.itemO("font.case_set") col.itemO("font.style_toggle") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_armature **************** @@ -187,6 +227,13 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel): layout.itemL(text="Modeling:") layout.itemO("armature.extrude") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_mball **************** @@ -203,6 +250,13 @@ class VIEW3D_PT_tools_mballedit(View3DPanel): col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for editmode_lattice **************** @@ -219,6 +273,13 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel): col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for posemode **************** @@ -259,6 +320,13 @@ class VIEW3D_PT_tools_posemode(View3DPanel): col = layout.column(align=True) col.itemO("poselib.pose_add", text="Add") col.itemO("poselib.pose_remove", text="Remove") + + layout.itemL(text="Repeat:") + + col = layout.column(align=True) + col.itemO("screen.repeat_last") + col.itemO("screen.repeat_history", text="History...") + col.itemO("screen.redo_last", text="Tweak...") # ********** default tools for paint modes **************** -- cgit v1.2.3 From e19537efccce4a8fd15f5b2b2baa51c4edef3b4e Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Thu, 10 Sep 2009 20:31:15 +0000 Subject: SVN maintenance. --- source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c | 2 +- source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c | 2 +- source/blender/nodes/intern/CMP_nodes/CMP_levels.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c index 0a4d3fceff9..470d04d9dcc 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c @@ -1,5 +1,5 @@ /** - * $Id: CMP_colorMatte.c 12931 2007-12-17 18:20:48Z theeth $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c index 921ac869cb8..f24aedd6661 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c @@ -1,5 +1,5 @@ /** - * $Id: CMP_diffMatte.c 12931 2007-12-17 18:20:48Z theeth $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c index 414c535789e..28b769a8a97 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c @@ -1,5 +1,5 @@ /** - * $Id: CMP_levels.c 12931 2007-12-17 18:20:48Z theeth $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From fcc5884c252ae10b07a6f8c5e1c5990e9aa4e7c5 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 10 Sep 2009 20:41:18 +0000 Subject: operator to fetch frames from a job in the list, decorator for rna registration --- release/io/netrender/client.py | 13 ++++----- release/io/netrender/operators.py | 61 +++++++++++++++++++++++++++++++++++---- release/io/netrender/ui.py | 19 +++++------- release/io/netrender/utils.py | 8 +++++ 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index 0c60bd1603c..bcfff8f5db5 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -120,9 +120,10 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): return job_id -def clientRequestResult(conn, scene, job_id): - conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) +def requestResult(conn, job_id, frame): + conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(frame)}) +@rnaType class NetworkRenderEngine(bpy.types.RenderEngine): __idname__ = 'NET_RENDER' __label__ = "Network Render" @@ -164,17 +165,17 @@ class NetworkRenderEngine(bpy.types.RenderEngine): self.update_stats("", "Network render waiting for results") - clientRequestResult(conn, scene, job_id) + requestResult(conn, job_id, scene.current_frame) response = conn.getresponse() if response.status == http.client.NO_CONTENT: netsettings.job_id = clientSendJob(conn, scene) - clientRequestResult(conn, scene, job_id) + requestResult(conn, job_id, scene.current_frame) while response.status == http.client.ACCEPTED and not self.test_break(): print("waiting") time.sleep(1) - clientRequestResult(conn, scene, job_id) + requestResult(conn, job_id, scene.current_frame) response = conn.getresponse() if response.status != http.client.OK: @@ -200,5 +201,3 @@ class NetworkRenderEngine(bpy.types.RenderEngine): conn.close() -bpy.types.register(NetworkRenderEngine) - diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 1c6d89c0043..ccecef670d4 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -6,6 +6,7 @@ from netrender.utils import * import netrender.client as client import netrender.model +@rnaOperator class RENDER_OT_netclientsend(bpy.types.Operator): ''' Operator documentation text, will be used for the operator tooltip and python docs. @@ -35,6 +36,7 @@ class RENDER_OT_netclientsend(bpy.types.Operator): def invoke(self, context, event): return self.execute(context) +@rnaOperator class RENDER_OT_netclientstatus(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientstatus" @@ -79,6 +81,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): def invoke(self, context, event): return self.execute(context) +@rnaOperator class RENDER_OT_netclientblacklistslave(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientblacklistslave" @@ -113,6 +116,7 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator): def invoke(self, context, event): return self.execute(context) +@rnaOperator class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientwhitelistslave" @@ -148,6 +152,7 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): return self.execute(context) +@rnaOperator class RENDER_OT_netclientslaves(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientslaves" @@ -197,6 +202,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): def invoke(self, context, event): return self.execute(context) +@rnaOperator class RENDER_OT_netclientcancel(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientcancel" @@ -228,9 +234,52 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): def invoke(self, context, event): return self.execute(context) -bpy.ops.add(RENDER_OT_netclientsend) -bpy.ops.add(RENDER_OT_netclientstatus) -bpy.ops.add(RENDER_OT_netclientslaves) -bpy.ops.add(RENDER_OT_netclientblacklistslave) -bpy.ops.add(RENDER_OT_netclientwhitelistslave) -bpy.ops.add(RENDER_OT_netclientcancel) \ No newline at end of file +@rnaOperator +class netclientdownload(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientdownload" + __label__ = "Net Render Client Download" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + netsettings = context.scene.network_render + return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 + + def execute(self, context): + netsettings = context.scene.network_render + rd = context.scene.render_data + + conn = clientConnection(context.scene) + + if conn: + job = bpy.data.netrender_jobs[netsettings.active_job_index] + + for frame in job.frames: + client.requestResult(conn, job.id, frame.number) + response = conn.getresponse() + + if response.status != http.client.OK: + print("missing", frame.number) + continue + + print("got back", frame.number) + + f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + conn.close() + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) \ No newline at end of file diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 8faabe6ff2d..12ac10b551f 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -28,6 +28,7 @@ class RenderButtonsPanel(bpy.types.Panel): return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) # Setting panel, use in the scene for now. +@rnaType class SCENE_PT_network_settings(RenderButtonsPanel): __label__ = "Network Settings" COMPAT_ENGINES = set(['NET_RENDER']) @@ -57,8 +58,8 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col.itemR(scene.network_render, "priority") col.itemR(scene.network_render, "job_name") col.itemO("render.netclientsend", text="send job to server") -bpy.types.register(SCENE_PT_network_settings) +@rnaType class SCENE_PT_network_slaves(RenderButtonsPanel): __label__ = "Slaves Status" COMPAT_ENGINES = set(['NET_RENDER']) @@ -96,8 +97,7 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): layout.itemL(text="Seen: " + time.ctime(slave.last_seen)) layout.itemL(text="Stats: " + slave.stats) -bpy.types.register(SCENE_PT_network_slaves) - +@rnaType class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): __label__ = "Slaves Blacklist" COMPAT_ENGINES = set(['NET_RENDER']) @@ -133,9 +133,8 @@ class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): layout.itemL(text="Address: " + slave.address[0]) layout.itemL(text="Seen: " + slave.last_seen) layout.itemL(text="Stats: " + time.ctime(slave.stats)) - -bpy.types.register(SCENE_PT_network_slaves_blacklist) +@rnaType class SCENE_PT_network_jobs(RenderButtonsPanel): __label__ = "Jobs" COMPAT_ENGINES = set(['NET_RENDER']) @@ -158,6 +157,7 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): subcol = col.column(align=True) subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: while(len(netsettings.jobs) > 0): @@ -172,22 +172,19 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): layout.itemL(text="Length: %04i" % len(job)) layout.itemL(text="Done: %04i" % job.results[DONE]) layout.itemL(text="Error: %04i" % job.results[ERROR]) - -bpy.types.register(SCENE_PT_network_jobs) +@rnaType class NetRenderSettings(bpy.types.IDPropertyGroup): pass +@rnaType class NetRenderSlave(bpy.types.IDPropertyGroup): pass +@rnaType class NetRenderJob(bpy.types.IDPropertyGroup): pass -bpy.types.register(NetRenderSettings) -bpy.types.register(NetRenderSlave) -bpy.types.register(NetRenderJob) - bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings") NetRenderSettings.StringProperty( attr="server_address", diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index d1b383f7a97..db6646e6916 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -13,6 +13,14 @@ DISPATCHED = 1 DONE = 2 ERROR = 3 +def rnaType(rna_type): + bpy.types.register(rna_type) + return rna_type + +def rnaOperator(rna_op): + bpy.ops.add(rna_op) + return rna_op + def clientConnection(scene): netrender = scene.network_render -- cgit v1.2.3 From e9587a89faf33aa0c1383b59f006be4cc7443a5a Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Thu, 10 Sep 2009 22:32:33 +0000 Subject: Hair dynamics with cloth simulation - Hair dynamics have their own panel in particle settings with the settings from cloth panel that apply to hair. - Basic internal friction force to quickly emulate self collisions and volume preservation. (Still very early code, but gives some idea of what's possible). - Softbody simulation is no longer used for hair. * Old files with sb dynamics should just load the hair without dynamics so new dynamics can be applied. * Invasion of particles exceptions in sb code is finally over. - Collisions with other objects are disabled for now and will be worked out in the future. Other changes/fixes: - Particle mode editing flag wasn't saved properly. - Some old files with edited hair didn't load correctly. - Disabled delete & specials menu in particle mode for non-hair editing. - Fixed yet one more cloth & softbody pointcache update issue. - Disconnect/connect hair now uses only the deformed mesh so it works correctly also for subsurfed emitters. - Hair editing now updates correctly with a moving emitter. --- release/ui/buttons_particle.py | 54 +++- source/blender/blenkernel/BKE_cloth.h | 3 +- source/blender/blenkernel/BKE_particle.h | 2 +- source/blender/blenkernel/intern/cloth.c | 45 ++- source/blender/blenkernel/intern/implicit.c | 88 +++++- source/blender/blenkernel/intern/object.c | 7 +- source/blender/blenkernel/intern/particle.c | 209 +++++++------- source/blender/blenkernel/intern/particle_system.c | 305 ++++++++++++-------- source/blender/blenkernel/intern/pointcache.c | 33 +-- source/blender/blenkernel/intern/softbody.c | 307 ++++----------------- source/blender/blenloader/intern/readfile.c | 32 ++- source/blender/blenloader/intern/writefile.c | 9 +- source/blender/editors/physics/editparticle.c | 48 +++- source/blender/editors/space_buttons/buttons_ops.c | 26 +- source/blender/editors/space_view3d/drawobject.c | 6 + source/blender/makesdna/DNA_cloth_types.h | 2 +- source/blender/makesdna/DNA_object_force.h | 2 - source/blender/makesdna/DNA_particle_types.h | 15 +- source/blender/makesrna/intern/rna_cloth.c | 10 +- source/blender/makesrna/intern/rna_particle.c | 39 ++- 20 files changed, 672 insertions(+), 570 deletions(-) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index b0051453b29..1d496e19121 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -154,8 +154,10 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): if psys.edited==True: if psys.global_hair: layout.itemO("particle.connect_hair") + layout.itemL(text="Hair is disconnected.") else: layout.itemO("particle.disconnect_hair") + layout.itemL(text="") elif part.type=='REACTOR': split.enabled = particle_panel_enabled(psys) split.itemR(psys, "reactor_target_object") @@ -212,6 +214,53 @@ class PARTICLE_PT_emission(ParticleButtonsPanel): elif part.distribution=='GRID': row.itemR(part, "grid_resolution") +class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel): + __label__ = "Hair dynamics" + __default_closed__ = True + + def poll(self, context): + psys = context.particle_system + if psys==None: return False + if psys.settings==None: return False + return psys.settings.type == 'HAIR' + + def draw_header(self, context): + #cloth = context.cloth.collision_settings + + #self.layout.active = cloth_panel_enabled(context.cloth) + #self.layout.itemR(cloth, "enable_collision", text="") + psys = context.particle_system + self.layout.itemR(psys, "hair_dynamics", text="") + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings + cloth = psys.cloth.settings + + layout.enabled = psys.hair_dynamics + + split = layout.split() + + col = split.column() + col.itemL(text="Quality:") + col.itemR(cloth, "quality", text="Steps",slider=True) + col.itemL(text="Gravity:") + col.itemR(cloth, "gravity", text="") + + col = split.column() + col.itemL(text="Material:") + sub = col.column(align=True) + sub.itemR(cloth, "pin_stiffness", text="Stiffness") + sub.itemR(cloth, "mass") + col.itemL(text="Damping:") + sub = col.column(align=True) + sub.itemR(cloth, "spring_damping", text="Spring") + sub.itemR(cloth, "air_damping", text="Air") + + layout.itemR(cloth, "internal_friction", slider="True") + class PARTICLE_PT_cache(ParticleButtonsPanel): __label__ = "Cache" __default_closed__ = True @@ -223,14 +272,14 @@ class PARTICLE_PT_cache(ParticleButtonsPanel): phystype = psys.settings.physics_type if phystype == 'NO' or phystype == 'KEYED': return False - return psys.settings.type in ('EMITTER', 'REACTOR') + return psys.settings.type in ('EMITTER', 'REACTOR') or (psys.settings.type == 'HAIR' and psys.hair_dynamics) def draw(self, context): layout = self.layout psys = context.particle_system - point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), 1, 0) + point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0) class PARTICLE_PT_initial(ParticleButtonsPanel): __label__ = "Velocity" @@ -897,6 +946,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel): #row.itemR(psys, "vertex_group_field_negate", text="") bpy.types.register(PARTICLE_PT_particles) +bpy.types.register(PARTICLE_PT_hair_dynamics) bpy.types.register(PARTICLE_PT_cache) bpy.types.register(PARTICLE_PT_emission) bpy.types.register(PARTICLE_PT_initial) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index bc4585106e6..e5b3adbd0c0 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -176,7 +176,8 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */ - CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12) /* edit cache in editmode */ + CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12), /* edit cache in editmode */ + CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS = (1 << 13) /* don't allow spring compression */ } CLOTH_SIMSETTINGS_FLAGS; /* COLLISION FLAGS */ diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 15896477a6a..c22778f5a30 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -208,7 +208,7 @@ void psys_free_boid_rules(struct ListBase *list); void psys_free_settings(struct ParticleSettings *part); void free_child_path_cache(struct ParticleSystem *psys); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); -void free_hair(struct ParticleSystem *psys, int softbody); +void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics); void free_keyed_keys(struct ParticleSystem *psys); void psys_free_particles(struct ParticleSystem *psys); void psys_free(struct Object * ob, struct ParticleSystem * psys); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 8be8df8e63b..d25c329f49f 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -496,9 +496,11 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, if(!do_init_cloth(ob, clmd, result, framenr)) return result; - if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) { + if(framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + do_init_cloth(ob, clmd, result, framenr); cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; cache->flag &= ~PTCACHE_REDO_NEEDED; return result; } @@ -530,36 +532,25 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, return result; } - if(framenr == startframe) { - implicit_set_positions(clmd); + /* if on second frame, write cache for first frame */ + if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) + BKE_ptcache_write_cache(&pid, startframe); - cache->simframe= framenr; - cache->flag |= PTCACHE_SIMULATION_VALID; + clmd->sim_parms->timescale *= framenr - cache->simframe; - /* don't write cache on first frame, but on second frame write - * cache for frame 1 and 2 */ - } - else { - /* if on second frame, write cache for first frame */ - if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) - BKE_ptcache_write_cache(&pid, startframe); + /* do simulation */ + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->simframe= framenr; - clmd->sim_parms->timescale *= framenr - cache->simframe; - - /* do simulation */ - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - - if(!do_step_cloth(ob, clmd, result, framenr)) { - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - cache->last_exact= 0; - } - else - BKE_ptcache_write_cache(&pid, framenr); - - cloth_to_object (ob, clmd, result); + if(!do_step_cloth(ob, clmd, result, framenr)) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + cache->last_exact= 0; } + else + BKE_ptcache_write_cache(&pid, framenr); + + cloth_to_object (ob, clmd, result); return result; } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index fc5213d5532..0bce71b57eb 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1183,7 +1183,8 @@ DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,fl //return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k; mul_fvectorT_fvector(to, dir, dir); sub_fmatrix_fmatrix(to, I, to); - mul_fmatrix_S(to, (((L/length)> 1.0f) ? (1.0f): (L/length))); + + mul_fmatrix_S(to, (L/length)); sub_fmatrix_fmatrix(to, to, I); mul_fmatrix_S(to, -k); } @@ -1218,6 +1219,8 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; float scaling = 0.0; + + int no_compress = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1254,7 +1257,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, // calculate force of structural + shear springs if((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR)) { - if(length > L) // only on elonglation + if(length > L || no_compress) { s->flags |= CLOTH_SPRING_FLAG_NEEDED; @@ -1393,6 +1396,84 @@ float calculateVertexWindForce(float wind[3], float vertexnormal[3]) return (INPR(wind, vertexnormal)); } +typedef struct HairGridVert { + float velocity[3]; + float density; +} HairGridVert; +/* Smoothing of hair velocities: + * adapted from + Volumetric Methods for Simulation and Rendering of Hair + by Lena Petrovic, Mark Henne and John Anderson + * Pixar Technical Memo #06-08, Pixar Animation Studios + */ +static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX, lfVector *lV, int numverts) +{ + /* TODO: this is an initial implementation and should be made much better in due time */ + + /* 10x10x10 grid gives nice initial results */ + HairGridVert grid[10][10][10]; + float gmin[3], gmax[3], density; + int v = 0; + int i = 0; + int j = 0; + int k = 0; + lfVector temp; + + INIT_MINMAX(gmin, gmax); + + for(i = 0; i < numverts; i++) + DO_MINMAX(lX[i], gmin, gmax); + + /* initialize grid */ + for(i = 0; i < 10; i++) { + for(j = 0; j < 10; j++) { + for(k = 0; k < 10; k++) { + grid[i][j][k].velocity[0] = 0.0f; + grid[i][j][k].velocity[1] = 0.0f; + grid[i][j][k].velocity[2] = 0.0f; + grid[i][j][k].density = 0.0f; + } + } + } + + /* gather velocities & density */ + for(v = 0; v < numverts; v++) { + i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f ); + j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f ); + k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f ); + + grid[i][j][k].velocity[0] += lV[v][0]; + grid[i][j][k].velocity[1] += lV[v][1]; + grid[i][j][k].velocity[2] += lV[v][2]; + grid[i][j][k].density += 1.0f; + } + + /* divide velocity with density */ + for(i = 0; i < 10; i++) { + for(j = 0; j < 10; j++) { + for(k = 0; k < 10; k++) { + density = grid[i][j][k].density; + if(density > 0.0f) { + grid[i][j][k].velocity[0] /= density; + grid[i][j][k].velocity[1] /= density; + grid[i][j][k].velocity[2] /= density; + } + } + } + } + + /* calculate forces */ + for(v = 0; v < numverts; v++) { + i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f ); + j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f ); + k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f ); + + /* 2.0f is an experimental value that seems to give good results */ + lF[v][0] += 2.0f * smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]); + lF[v][1] += 2.0f * smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]); + lF[v][2] += 2.0f * smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]); + } +} static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M) { /* Collect forces and derivatives: F,dFdX,dFdV */ @@ -1416,6 +1497,9 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, init_lfvector(lF, gravity, numverts); + if(clmd->sim_parms->velocity_smooth > 0.0f) + hair_velocity_smoothing(clmd->sim_parms->velocity_smooth, lF, lX, lV, numverts); + /* multiply lF with mass matrix // force = mass * acceleration (in this case: gravity) */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index f10226f6f6b..a0004aaae49 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1113,9 +1113,10 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) } } - if(psys->soft) { - psysn->soft= copy_softbody(psys->soft); - psysn->soft->particles = psysn; + if(psys->clmd) { + ClothModifierData *nclmd = modifier_new(eModifierType_Cloth); + modifier_copyData((ModifierData*)psys->clmd, (ModifierData*)nclmd); + psys->hair_in_dm = psys->hair_out_dm = NULL; } BLI_duplicatelist(&psysn->targets, &psys->targets); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 0ba2f357a1f..3b2125a7973 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -366,7 +366,7 @@ void psys_free_settings(ParticleSettings *part) boid_free_settings(part->boids); } -void free_hair(ParticleSystem *psys, int softbody) +void free_hair(Object *ob, ParticleSystem *psys, int dynamics) { PARTICLE_P; @@ -382,10 +382,28 @@ void free_hair(ParticleSystem *psys, int softbody) psys->flag &= ~PSYS_HAIR_DONE; - if(softbody && psys->soft) { - sbFree(psys->soft); - psys->soft = NULL; + if(psys->clmd) { + if(dynamics) { + BKE_ptcache_free_list(&psys->ptcaches); + psys->clmd->point_cache = psys->pointcache = NULL; + psys->clmd->ptcaches.first = psys->clmd->ptcaches.first = NULL; + + modifier_free((ModifierData*)psys->clmd); + + psys->clmd = NULL; + } + else { + cloth_free_modifier(ob, psys->clmd); + } } + + if(psys->hair_in_dm) + psys->hair_in_dm->release(psys->hair_in_dm); + psys->hair_in_dm = NULL; + + if(psys->hair_out_dm) + psys->hair_out_dm->release(psys->hair_out_dm); + psys->hair_out_dm = NULL; } void free_keyed_keys(ParticleSystem *psys) { @@ -468,6 +486,8 @@ void psys_free(Object *ob, ParticleSystem * psys) psys_free_path_cache(psys, NULL); + free_hair(ob, psys, 1); + psys_free_particles(psys); if(psys->edit && psys->free_edit) @@ -976,11 +996,11 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic typedef struct ParticleInterpolationData { HairKey *hkey[2]; + DerivedMesh *dm; + MVert *mvert[2]; + int keyed; ParticleKey *kkey[2]; - - SoftBody *soft; - BodyPoint *bp[2]; PointCache *cache; @@ -1049,12 +1069,12 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->birthtime = key->time; pind->dietime = (key + pa->totkey - 1)->time; - } - //if(pind->soft) { - // pind->bp[0] = pind->soft->bpoint + pa->bpi; - // pind->bp[1] = pind->soft->bpoint + pa->bpi + 1; - //} + if(pind->dm) { + pind->mvert[0] = CDDM_get_vert(pind->dm, pa->hair_index); + pind->mvert[1] = pind->mvert[0] + 1; + } + } } static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey) { @@ -1069,9 +1089,10 @@ static void hair_to_particle(ParticleKey *key, HairKey *hkey) VECCOPY(key->co, hkey->co); key->time = hkey->time; } -static void bp_to_particle(ParticleKey *key, BodyPoint *bp, HairKey *hkey) + +static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey) { - VECCOPY(key->co, bp->pos); + VECCOPY(key->co, mvert->co); key->time = hkey->time; } @@ -1145,7 +1166,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData while(pind->hkey[1]->time < real_t) { pind->hkey[1]++; - pind->bp[1]++; + pind->mvert[1]++; } pind->hkey[0] = pind->hkey[1] - 1; @@ -1156,10 +1177,10 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData edit_to_particle(keys + 1, pind->ekey[0]); edit_to_particle(keys + 2, pind->ekey[1]); } - else if(pind->soft) { - pind->bp[0] = pind->bp[1] - 1; - bp_to_particle(keys + 1, pind->bp[0], pind->hkey[0]); - bp_to_particle(keys + 2, pind->bp[1], pind->hkey[1]); + else if(pind->dm) { + pind->mvert[0] = pind->mvert[1] - 1; + mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]); + mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]); } else if(pind->keyed) { memcpy(keys + 1, pind->kkey[0], sizeof(ParticleKey)); @@ -1181,11 +1202,11 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData else edit_to_particle(keys, pind->ekey[0]); } - else if(pind->soft) { + else if(pind->dm) { if(pind->hkey[0] != pa->hair) - bp_to_particle(keys, pind->bp[0] - 1, pind->hkey[0] - 1); + mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1); else - bp_to_particle(keys, pind->bp[0], pind->hkey[0]); + mvert_to_particle(keys, pind->mvert[0], pind->hkey[0]); } else { if(pind->hkey[0] != pa->hair) @@ -1200,11 +1221,11 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData else edit_to_particle(keys + 3, pind->ekey[1]); } - else if(pind->soft) { + else if(pind->dm) { if(pind->hkey[1] != pa->hair + pa->totkey - 1) - bp_to_particle(keys + 3, pind->bp[1] + 1, pind->hkey[1] + 1); + mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1); else - bp_to_particle(keys + 3, pind->bp[1], pind->hkey[1]); + mvert_to_particle(keys + 3, pind->mvert[1], pind->hkey[1]); } else { if(pind->hkey[1] != pa->hair + pa->totkey - 1) @@ -2110,7 +2131,11 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup) { float *vg=0; - if(psys->vgroup[vgroup]){ + if(vgroup < 0) { + /* hair dynamics pinning vgroup */ + + } + else if(psys->vgroup[vgroup]){ MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); if(dvert){ int totvert=dm->getNumVerts(dm), i; @@ -2639,12 +2664,11 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleSettings *part = psys->part; ParticleEditSettings *pset = &scene->toolsettings->particle; + + DerivedMesh *hair_dm = psys->hair_out_dm; ParticleData *pa = psys->particles; ParticleKey result; - - SoftBody *soft = NULL; - BodyPoint *bp[2] = {NULL, NULL}; Material *ma; ParticleInterpolationData pind; @@ -2663,7 +2687,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra int keyed, baked; /* we don't have anything valid to create paths from so let's quit here */ - if(!(psys->flag & PSYS_HAIR_DONE) && !(psys->flag & PSYS_KEYED) && !(psys->pointcache->flag & PTCACHE_BAKED)) + if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) return; if(psys_in_edit_mode(scene, psys)) @@ -2673,24 +2697,18 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra BLI_srandom(psys->seed); keyed = psys->flag & PSYS_KEYED; - baked = psys->pointcache->flag & PTCACHE_BAKED; + baked = !hair_dm && psys->pointcache->flag & PTCACHE_BAKED; /* clear out old and create new empty path cache */ psys_free_path_cache(psys, psys->edit); cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1); - if(psys->soft && psys->softflag & OB_SB_ENABLE) { - soft = psys->soft; - if(!soft->bpoint) - soft= NULL; - } - psys->lattice = psys_get_lattice(scene, ob, psys); ma= give_current_material(ob, psys->part->omat); if(ma && (psys->part->draw & PART_DRAW_MAT_COL)) VECCOPY(col, &ma->r) - if(psys->part->from!=PART_FROM_PARTICLE) { + if(psys->part->from!=PART_FROM_PARTICLE && !(psys->flag & PSYS_GLOBAL_HAIR)) { if(!(psys->part->flag & PART_CHILD_EFFECT)) vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR); @@ -2700,11 +2718,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra /*---first main loop: create all actual particles' paths---*/ for(i=0; iflag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) { - if(soft) - bp[0] += pa->totkey; /* TODO use of initialized value? */ + if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; - } if(!psys->totchild) { BLI_srandom(psys->seed + i); @@ -2715,9 +2730,9 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra pind.keyed = keyed; pind.cache = baked ? psys->pointcache : NULL; - pind.soft = soft; pind.epoint = NULL; pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); + pind.dm = hair_dm; memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); @@ -2759,10 +2774,12 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); - /* keyed, baked and softbody are allready in global space */ - if(!keyed && !baked && !soft && !(psys->flag & PSYS_GLOBAL_HAIR)) { + /* dynamic hair is in object space */ + /* keyed and baked are allready in global space */ + if(hair_dm) + Mat4MulVecfl(ob->obmat, result.co); + else if(!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR)) Mat4MulVecfl(hairmat, result.co); - } VECCOPY(ca->co, result.co); VECCOPY(ca->col, col); @@ -2778,64 +2795,66 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra effector*= psys_particle_value_from_verts(psmd->dm,psys->part->from,pa,vg_effector); for(k=0, ca=cache[i]; k<=steps; k++, ca++) { + if(!(psys->flag & PSYS_GLOBAL_HAIR)) { /* apply effectors */ - if(!(psys->part->flag & PART_CHILD_EFFECT) && k) - do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec); + if(!(psys->part->flag & PART_CHILD_EFFECT) && k) + do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec); - /* apply guide curves to path data */ - if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0) - /* ca is safe to cast, since only co and vel are used */ - do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors); + /* apply guide curves to path data */ + if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0) + /* ca is safe to cast, since only co and vel are used */ + do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors); - /* apply lattice */ - if(psys->lattice) - calc_latt_deform(psys->lattice, ca->co, 1.0f); + /* apply lattice */ + if(psys->lattice) + calc_latt_deform(psys->lattice, ca->co, 1.0f); - /* figure out rotation */ - - if(k) { - float cosangle, angle, tangent[3], normal[3], q[4]; - - if(k == 1) { - /* calculate initial tangent for incremental rotations */ - VECSUB(tangent, ca->co, (ca - 1)->co); - VECCOPY(prev_tangent, tangent); - Normalize(prev_tangent); - - /* First rotation is based on emitting face orientation. */ - /* This is way better than having flipping rotations resulting */ - /* from using a global axis as a rotation pole (vec_to_quat()). */ - /* It's not an ideal solution though since it disregards the */ - /* initial tangent, but taking that in to account will allow */ - /* the possibility of flipping again. -jahka */ - Mat3ToQuat_is_ok(rotmat, (ca-1)->rot); - } - else { - VECSUB(tangent, ca->co, (ca - 1)->co); - Normalize(tangent); - - cosangle= Inpf(tangent, prev_tangent); - - /* note we do the comparison on cosangle instead of - * angle, since floating point accuracy makes it give - * different results across platforms */ - if(cosangle > 0.999999f) { - QUATCOPY((ca - 1)->rot, (ca - 2)->rot); + /* figure out rotation */ + + if(k) { + float cosangle, angle, tangent[3], normal[3], q[4]; + + if(k == 1) { + /* calculate initial tangent for incremental rotations */ + VECSUB(tangent, ca->co, (ca - 1)->co); + VECCOPY(prev_tangent, tangent); + Normalize(prev_tangent); + + /* First rotation is based on emitting face orientation. */ + /* This is way better than having flipping rotations resulting */ + /* from using a global axis as a rotation pole (vec_to_quat()). */ + /* It's not an ideal solution though since it disregards the */ + /* initial tangent, but taking that in to account will allow */ + /* the possibility of flipping again. -jahka */ + Mat3ToQuat_is_ok(rotmat, (ca-1)->rot); } else { - angle= saacos(cosangle); - Crossf(normal, prev_tangent, tangent); - VecRotToQuat(normal, angle, q); - QuatMul((ca - 1)->rot, q, (ca - 2)->rot); + VECSUB(tangent, ca->co, (ca - 1)->co); + Normalize(tangent); + + cosangle= Inpf(tangent, prev_tangent); + + /* note we do the comparison on cosangle instead of + * angle, since floating point accuracy makes it give + * different results across platforms */ + if(cosangle > 0.999999f) { + QUATCOPY((ca - 1)->rot, (ca - 2)->rot); + } + else { + angle= saacos(cosangle); + Crossf(normal, prev_tangent, tangent); + VecRotToQuat(normal, angle, q); + QuatMul((ca - 1)->rot, q, (ca - 2)->rot); + } + + VECCOPY(prev_tangent, tangent); } - VECCOPY(prev_tangent, tangent); + if(k == steps) + QUATCOPY(ca->rot, (ca - 1)->rot); } - if(k == steps) - QUATCOPY(ca->rot, (ca - 1)->rot); } - /* set velocity */ @@ -2913,9 +2932,9 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf pind.keyed = 0; pind.cache = NULL; - pind.soft = NULL; pind.epoint = point; pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0; + pind.dm = NULL; memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); @@ -3783,8 +3802,8 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i pa = psys->particles + p; pind.keyed = keyed; pind.cache = cached ? psys->pointcache : NULL; - pind.soft = NULL; pind.epoint = NULL; + pind.dm = psys->hair_out_dm; init_particle_interpolation(ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1931b89af38..88b85bcfa29 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -73,7 +73,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_object.h" #include "BKE_material.h" -#include "BKE_softbody.h" +#include "BKE_cloth.h" #include "BKE_depsgraph.h" #include "BKE_lattice.h" #include "BKE_pointcache.h" @@ -126,7 +126,7 @@ void psys_reset(ParticleSystem *psys, int mode) PARTICLE_P; if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) { - if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->edit && psys->edit->edited))) { + if(mode == PSYS_RESET_ALL || !(psys->flag & PSYS_EDITED)) { psys_free_particles(psys); psys->totpart= 0; @@ -3432,6 +3432,190 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa /************************************************/ /* Hair */ /************************************************/ +/* check if path cache or children need updating and do it if needed */ +static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) +{ + ParticleSettings *part=psys->part; + ParticleEditSettings *pset=&scene->toolsettings->particle; + int distr=0,alloc=0,skip=0; + + if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET) + alloc=1; + + if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))) + distr=1; + + if(distr){ + if(alloc) + realloc_particles(ob,psys,psys->totpart); + + if(get_psys_tot_child(scene, psys)) { + /* don't generate children while computing the hair keys */ + if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { + distribute_particles(scene, ob, psys, PART_FROM_CHILD); + + if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) + psys_find_parents(ob,psmd,psys); + } + } + } + + if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) + skip = 1; /* only hair, keyed and baked stuff can have paths */ + else if(part->ren_as != PART_DRAW_PATH) + skip = 1; /* particle visualization must be set as path */ + else if(!psys->renderdata) { + if(part->draw_as != PART_DRAW_REND) + skip = 1; /* draw visualization */ + else if(psys->pointcache->flag & PTCACHE_BAKING) + skip = 1; /* no need to cache paths while baking dynamics */ + else if(psys_in_edit_mode(scene, psys)) { + if((pset->flag & PE_DRAW_PART)==0) + skip = 1; + else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0) + skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */ + } + } + + if(!skip) { + psys_cache_paths(scene, ob, psys, cfra); + + /* for render, child particle paths are computed on the fly */ + if(part->childtype) { + if(!psys->totchild) + skip = 1; + else if((psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DONE)==0) + skip = 1; + + if(!skip) + psys_cache_child_paths(scene, ob, psys, cfra, 0); + } + } + else if(psys->pathcache) + psys_free_path_cache(psys, NULL); +} + +static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd) +{ + DerivedMesh *dm = psys->hair_in_dm; + MVert *mvert = NULL; + MEdge *medge = NULL; + MDeformVert *dvert = NULL; + HairKey *key; + PARTICLE_P; + int totpoint = 0; + int totedge; + int k; + float hairmat[4][4]; + + if(!psys->clmd) { + psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth); + psys->clmd->sim_parms->goalspring = 0.0f; + psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS; + psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF; + } + + /* create a dm from hair vertices */ + LOOP_PARTICLES + totpoint += pa->totkey; + + totedge = totpoint - psys->totpart; + + if(dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) { + dm->release(dm); + dm = psys->hair_in_dm = NULL; + } + + if(!dm) { + dm = psys->hair_in_dm = CDDM_new(totpoint, totedge, 0); + DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL); + } + + mvert = CDDM_get_verts(dm); + medge = CDDM_get_edges(dm); + dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT); + + psys->clmd->sim_parms->vgroup_mass = 1; + + /* make vgroup for pin roots etc.. */ + psys->particles->hair_index = 0; + LOOP_PARTICLES { + if(p) + pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey; + + psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat); + + for(k=0, key=pa->hair; ktotkey; k++,key++) { + VECCOPY(mvert->co, key->co); + Mat4MulVecfl(hairmat, mvert->co); + mvert++; + + if(k) { + medge->v1 = pa->hair_index + k - 1; + medge->v2 = pa->hair_index + k; + medge++; + } + + if(dvert) { + if(!dvert->totweight) { + dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight"); + dvert->totweight = 1; + } + + /* no special reason for the 0.5 */ + /* just seems like a nice value from experiments */ + dvert->dw->weight = k ? 0.5f : 1.0f; + dvert++; + } + } + } + + if(psys->hair_out_dm) + psys->hair_out_dm->release(psys->hair_out_dm); + + psys->clmd->point_cache = psys->pointcache; + + psys->hair_out_dm = clothModifier_do(psys->clmd, scene, ob, dm, 0, 0); +} +static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) +{ + ParticleSettings *part = psys->part; + PARTICLE_P; + float disp = (float)get_current_display_percentage(psys)/100.0f; + + BLI_srandom(psys->seed); + + LOOP_PARTICLES { + if(BLI_frand() > disp) + pa->flag |= PARS_NO_DISP; + else + pa->flag &= ~PARS_NO_DISP; + } + + if(psys->recalc & PSYS_RECALC_RESET) { + /* need this for changing subsurf levels */ + psys_calc_dmcache(ob, psmd->dm, psys); + + if(psys->clmd) + cloth_free_modifier(ob, psys->clmd); + } + + if(psys->effectors.first) + psys_end_effectors(psys); + + /* dynamics with cloth simulation */ + if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) + do_hair_dynamics(scene, ob, psys, psmd); + + psys_init_effectors(scene, ob, part->eff_group, psys); + if(psys->effectors.first) + precalc_effectors(scene, ob,psys,psmd,cfra); + + psys_update_path_cache(scene, ob,psmd,psys,cfra); + + psys->flag |= PSYS_HAIR_UPDATED; +} + static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){ HairKey *key, *root; PARTICLE_P; @@ -3692,79 +3876,6 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic BLI_kdtree_free(tree); } -/* check if path cache or children need updating and do it if needed */ -static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) -{ - ParticleSettings *part=psys->part; - ParticleEditSettings *pset=&scene->toolsettings->particle; - int distr=0,alloc=0; - - if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET) - alloc=1; - - if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))) - distr=1; - - if(distr){ - if(alloc) - realloc_particles(ob,psys,psys->totpart); - - if(get_psys_tot_child(scene, psys)) { - /* don't generate children while computing the hair keys */ - if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { - distribute_particles(scene, ob, psys, PART_FROM_CHILD); - - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) - psys_find_parents(ob,psmd,psys); - } - } - } - - if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR - || (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){ - - psys_cache_paths(scene, ob, psys, cfra); - - /* for render, child particle paths are computed on the fly */ - if(part->childtype) { - if(((psys->totchild!=0)) || (psys_in_edit_mode(scene, psys) && (pset->flag&PE_DRAW_PART))) - if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) - psys_cache_child_paths(scene, ob, psys, cfra, 0); - } - } - else if(psys->pathcache) - psys_free_path_cache(psys, NULL); -} - -static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) -{ - ParticleSettings *part = psys->part; - PARTICLE_P; - float disp = (float)get_current_display_percentage(psys)/100.0f; - - BLI_srandom(psys->seed); - - LOOP_PARTICLES { - if(BLI_frand() > disp) - pa->flag |= PARS_NO_DISP; - else - pa->flag &= ~PARS_NO_DISP; - } - - if(psys->recalc & PSYS_RECALC_RESET) - /* need this for changing subsurf levels */ - psys_calc_dmcache(ob, psmd->dm, psys); - - if(psys->effectors.first) - psys_end_effectors(psys); - - psys_init_effectors(scene, ob, part->eff_group, psys); - if(psys->effectors.first) - precalc_effectors(scene, ob,psys,psmd,cfra); - - psys_update_path_cache(scene, ob,psmd,psys,cfra); -} - /* updates cached particles' alive & other flags etc..*/ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) { @@ -3889,14 +4000,12 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys) BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); } else { - free_hair(psys, 1); + free_hair(ob, psys, 1); CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime)); CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime)); } - psys->softflag= 0; - psys_reset(psys, PSYS_RESET_ALL); } void psys_check_boid_data(ParticleSystem *psys) @@ -4082,7 +4191,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle framedelta= framenr - cache->simframe; /* set suitable cache range automatically */ - if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0) + if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0 && !(psys->flag & PSYS_HAIR_DYNAMICS)) psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe); BKE_ptcache_id_from_particles(&pid, ob, psys); @@ -4307,39 +4416,9 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle } } -static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys) -{ - SoftBody *sb; - short softflag; - - if(!(psys->softflag & OB_SB_ENABLE)) - return; - - /* let's replace the object's own softbody with the particle softbody */ - /* a temporary solution before cloth simulation is implemented, jahka */ - - /* save these */ - sb= ob->soft; - softflag= ob->softflag; - - /* swich to new ones */ - ob->soft= psys->soft; - ob->softflag= psys->softflag; - - /* do softbody */ - sbObjectStep(scene, ob, (float)scene->r.cfra, NULL, psys_count_keys(psys)); - - /* return things back to normal */ - psys->soft= ob->soft; - psys->softflag= ob->softflag; - - ob->soft= sb; - ob->softflag= softflag; -} - static int hair_needs_recalc(ParticleSystem *psys) { - if((!psys->edit || !psys->edit->edited) && + if(!(psys->flag & PSYS_EDITED) && (!psys->edit || !psys->edit->edited) && ((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET)) { return 1; } @@ -4380,7 +4459,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) float hcfra=0.0f; int i; - free_hair(psys, 0); + free_hair(ob, psys, 0); /* first step is negative so particles get killed and reset */ psys->cfra= 1.0f; @@ -4394,10 +4473,6 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) psys->flag |= PSYS_HAIR_DONE; } - /* handle softbody hair */ - if(psys->part->type==PART_HAIR && psys->soft) - psys_to_softbody(scene, ob, psys); - /* the main particle system step */ system_step(scene, ob, psys, psmd, cfra); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 5a14277d63b..f351f8a4335 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -382,8 +382,6 @@ static int ptcache_totpoint_cloth(void *cloth_v) /* Creating ID's */ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb) { - ParticleSystemModifierData *psmd; - memset(pid, 0, sizeof(PTCacheID)); pid->ob= ob; @@ -406,12 +404,7 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb) pid->data_types= (1<info_types= 0; - if(sb->particles) { - psmd= psys_get_modifier(ob, sb->particles); - // pid->stack_index= modifiers_indexInObject(ob, (ModifierData*)psmd); XXX TODO - get other index DG - } - else - pid->stack_index = pid->cache->index; + pid->stack_index = pid->cache->index; } void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys) @@ -426,7 +419,8 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p pid->cache_ptr= &psys->pointcache; pid->ptcaches= &psys->ptcaches; - pid->flag |= PTCACHE_VEL_PER_SEC; + if(psys->part->type != PART_HAIR) + pid->flag |= PTCACHE_VEL_PER_SEC; pid->write_elem= ptcache_write_particle; pid->write_stream = NULL; @@ -816,12 +810,6 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob) pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); BKE_ptcache_id_from_particles(pid, ob, psys); BLI_addtail(lb, pid); - - if(psys->soft) { - pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID"); - BKE_ptcache_id_from_softbody(pid, ob, psys->soft); - BLI_addtail(lb, pid); - } } } @@ -1828,9 +1816,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) else if(mode == PTCACHE_RESET_OUTDATED) { reset = 1; - if(cache->flag & PTCACHE_OUTDATED) - if(!(cache->flag & PTCACHE_BAKED)) - clear= 1; + if(cache->flag & PTCACHE_OUTDATED && !(cache->flag & PTCACHE_BAKED)) { + clear= 1; + cache->flag &= ~PTCACHE_OUTDATED; + } } if(reset) { @@ -1873,10 +1862,10 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode) } for(psys=ob->particlesystem.first; psys; psys=psys->next) { - /* Baked softbody hair has to be checked first, because we don't want to reset */ - /* particles or softbody in that case -jahka */ - if(psys->soft) { - BKE_ptcache_id_from_softbody(&pid, ob, psys->soft); + /* Baked cloth hair has to be checked first, because we don't want to reset */ + /* particles or cloth in that case -jahka */ + if(psys->clmd) { + BKE_ptcache_id_from_cloth(&pid, ob, psys->clmd); if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED))) reset |= BKE_ptcache_id_reset(scene, &pid, mode); else diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index fdbfe154fae..450a64d72eb 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -58,7 +58,6 @@ variables on the UI for now #include "DNA_curve_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" /* here is the softbody struct */ -#include "DNA_particle_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -76,7 +75,6 @@ variables on the UI for now #include "BKE_global.h" #include "BKE_key.h" #include "BKE_object.h" -#include "BKE_particle.h" #include "BKE_softbody.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -494,32 +492,21 @@ static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *h while (base) { /*Only proceed for mesh object in same layer */ if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) { - int particles=0; ob= base->object; if((vertexowner) && (ob == vertexowner)) { - if(vertexowner->soft->particles){ - particles=1; - } - else { - /* if vertexowner is given we don't want to check collision with owner object */ - base = base->next; - continue; - } + /* if vertexowner is given we don't want to check collision with owner object */ + base = base->next; + continue; } /*+++ only with deflecting set */ if(ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == 0) { DerivedMesh *dm= NULL; - if(particles) { - dm = psys_get_modifier(ob,psys_get_current(ob))->dm; - } - else { - if(ob->softflag & OB_SB_COLLFINAL) /* so maybe someone wants overkill to collide with subsurfed */ - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - else - dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); - } + if(ob->softflag & OB_SB_COLLFINAL) /* so maybe someone wants overkill to collide with subsurfed */ + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + else + dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); if(dm){ ccd_Mesh *ccdmesh = ccd_mesh_make(ob, dm); @@ -3571,107 +3558,6 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob) } } - -static void springs_from_particles(Object *ob) -{ - ParticleSystem *psys; - ParticleSystemModifierData *psmd=0; - ParticleData *pa=0; - HairKey *key=0; - SoftBody *sb; - BodyPoint *bp; - BodySpring *bs; - int a,k; - float hairmat[4][4]; - - if(ob && ob->soft && ob->soft->particles) { - psys= ob->soft->particles; - sb= ob->soft; - psmd = psys_get_modifier(ob, psys); - - bp= sb->bpoint; - for(a=0, pa=psys->particles; atotpart; a++, pa++) { - for(k=0, key=pa->hair; ktotkey; k++, bp++, key++) { - VECCOPY(bp->origS, key->co); - - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); - - Mat4MulVecfl(hairmat, bp->origS); - } - } - - for(a=0, bs=sb->bspring; atotspring; a++, bs++) - bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS); - } -} - -static void particles_to_softbody(Scene *scene, Object *ob) -{ - SoftBody *sb; - BodyPoint *bp; - BodySpring *bs; - ParticleData *pa; - HairKey *key; - ParticleSystem *psys= ob->soft->particles; - float goalfac; - int a, k, curpoint; - int totpoint= psys_count_keys(psys); - int totedge= totpoint-psys->totpart; - - /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */ - renew_softbody(scene, ob, totpoint, totedge); - - /* find first BodyPoint index for each particle */ - if(psys->totpart > 0) { -// psys->particles->bpi = 0; -// for(a=1, pa=psys->particles+1; atotpart; a++, pa++) -// pa->bpi = (pa-1)->bpi + (pa-1)->totkey; - } - - /* we always make body points */ - sb= ob->soft; - bp= sb->bpoint; - bs= sb->bspring; - goalfac= ABS(sb->maxgoal - sb->mingoal); - - if((ob->softflag & OB_SB_GOAL)) { - for(a=0, pa=psys->particles; atotpart; a++, pa++) { - for(k=0, key=pa->hair; ktotkey; k++,bp++,key++) { - if(k) { - bp->goal= key->weight; - bp->goal= sb->mingoal + bp->goal*goalfac; - bp->goal= (float)pow(bp->goal, 4.0f); - } - else{ - /* hair roots are allways fixed fully to goal */ - bp->goal= 1.0f; - } - } - } - } - - bp= sb->bpoint; - curpoint=0; - for(a=0, pa=psys->particles; atotpart; a++, curpoint++, pa++) { - for(k=0; ktotkey-1; k++,bs++,curpoint++) { - bs->v1=curpoint; - bs->v2=curpoint+1; - bs->strength= 1.0; - bs->order=1; - } - } - - build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */ - /* insert *other second order* springs if desired */ - if(sb->secondspring > 0.0000001f) { - add_2nd_order_springs(ob,sb->secondspring*10.0); /* exploits the the first run of build_bps_springlist(ob);*/ - build_bps_springlist(ob); /* yes we need to do it again*/ - } - springs_from_particles(ob); /* write the 'rest'-lenght of the springs */ - if(ob->softflag & OB_SB_SELF) - calculate_collision_balls(ob); -} - /* copies softbody result back in object */ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, int local) { @@ -3795,44 +3681,16 @@ void sbSetInterruptCallBack(int (*f)(void)) static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts) { - ParticleSystemModifierData *psmd= NULL; - ParticleData *pa= NULL; - HairKey *key= NULL; BodyPoint *bp; - float hairmat[4][4]; int a; - /* update the vertex locations */ - if(sb->particles && sb->particles->totpart>0) { - psmd= psys_get_modifier(ob,sb->particles); - - pa= sb->particles->particles; - key= pa->hair; - - psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); - } - for(a=0,bp=sb->bpoint; aorigS, bp->origE); /* copy the position of the goals at desired end time */ - if(sb->particles) { - if(key == pa->hair + pa->totkey) { - pa++; - key = pa->hair; - - psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); - } - VECCOPY(bp->origE, key->co); - Mat4MulVecfl(hairmat,bp->origE); - - key++; - } - else{ - VECCOPY(bp->origE, vertexCos[a]); - /* vertexCos came from local world, go global */ - Mat4MulVecfl(ob->obmat, bp->origE); - } + VECCOPY(bp->origE, vertexCos[a]); + /* vertexCos came from local world, go global */ + Mat4MulVecfl(ob->obmat, bp->origE); /* just to be save give bp->origT a defined value will be calulated in interpolate_exciter()*/ VECCOPY(bp->origT, bp->origE); @@ -3841,37 +3699,12 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts) { - ParticleSystemModifierData *psmd= NULL; - HairKey *key= NULL; - ParticleData *pa= NULL; BodyPoint *bp; - float hairmat[4][4]; int a; - if(sb->particles && sb->particles->totpart>0) { - psmd= psys_get_modifier(ob, sb->particles); - pa= sb->particles->particles; - key= pa->hair; - - psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); - } - for(a=0,bp=sb->bpoint; aparticles) { - if(key == pa->hair + pa->totkey) { - pa++; - key = pa->hair; - - psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat); - } - VECCOPY(bp->pos, key->co); - Mat4MulVecfl(hairmat, bp->pos); - key++; - } - else { - VECCOPY(bp->pos, vertexCos[a]); - Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/ - } + VECCOPY(bp->pos, vertexCos[a]); + Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/ VECCOPY(bp->origS, bp->pos); VECCOPY(bp->origE, bp->pos); VECCOPY(bp->origT, bp->pos); @@ -3900,20 +3733,18 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int sb_new_scratch(sb); /* make a new */ sb->scratch->needstobuildcollider=1; - if((sb->particles)==0) { - /* copy some info to scratch */ - switch(ob->type) { - case OB_MESH: - if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob); - break; - case OB_LATTICE: - break; - case OB_CURVE: - case OB_SURF: - break; - default: - break; - } + /* copy some info to scratch */ + switch(ob->type) { + case OB_MESH: + if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob); + break; + case OB_LATTICE: + break; + case OB_CURVE: + case OB_SURF: + break; + default: + break; } } @@ -4049,8 +3880,6 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) /* simulates one step. framenr is in frames */ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts) { - ParticleSystemModifierData *psmd=0; - ParticleData *pa=0; SoftBody *sb= ob->soft; PointCache *cache; PTCacheID pid; @@ -4091,25 +3920,20 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(sb->bpoint == NULL || ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) { - if(sb->particles){ - particles_to_softbody(scene, ob); - } - else { - switch(ob->type) { - case OB_MESH: - mesh_to_softbody(scene, ob); - break; - case OB_LATTICE: - lattice_to_softbody(scene, ob); - break; - case OB_CURVE: - case OB_SURF: - curve_surf_to_softbody(scene, ob); - break; - default: - renew_softbody(scene, ob, numVerts, 0); - break; - } + switch(ob->type) { + case OB_MESH: + mesh_to_softbody(scene, ob); + break; + case OB_LATTICE: + lattice_to_softbody(scene, ob); + break; + case OB_CURVE: + case OB_SURF: + curve_surf_to_softbody(scene, ob); + break; + default: + renew_softbody(scene, ob, numVerts, 0); + break; } softbody_update_positions(ob, sb, vertexCos, numVerts); @@ -4127,8 +3951,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i softbody_update_positions(ob, sb, vertexCos, numVerts); softbody_step(scene, ob, sb, dtime); - if(sb->particles==0) - softbody_to_object(ob, vertexCos, numVerts, 0); + softbody_to_object(ob, vertexCos, numVerts, 0); return; } @@ -4136,14 +3959,14 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i /* still no points? go away */ if(sb->totpoint==0) return; - if(sb->particles){ - psmd= psys_get_modifier(ob, sb->particles); - pa= sb->particles->particles; - } - - if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) { + if(framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + + /* first frame, no simulation to do, just set the positions */ + softbody_update_positions(ob, sb, vertexCos, numVerts); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; cache->flag &= ~PTCACHE_REDO_NEEDED; return; } @@ -4152,8 +3975,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i cache_result = BKE_ptcache_read_cache(&pid, framenr, scene->r.frs_sec); if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { - if(sb->particles==0) - softbody_to_object(ob, vertexCos, numVerts, sb->local); + softbody_to_object(ob, vertexCos, numVerts, sb->local); cache->simframe= framenr; cache->flag |= PTCACHE_SIMULATION_VALID; @@ -4174,36 +3996,23 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i return; } - if(framenr == startframe) { - /* first frame, no simulation to do, just set the positions */ - softbody_update_positions(ob, sb, vertexCos, numVerts); - - cache->simframe= framenr; - cache->flag |= PTCACHE_SIMULATION_VALID; + /* if on second frame, write cache for first frame */ + if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) + BKE_ptcache_write_cache(&pid, startframe); - /* don't write cache on first frame, but on second frame write - * cache for frame 1 and 2 */ - } - else { - /* if on second frame, write cache for first frame */ - if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) - BKE_ptcache_write_cache(&pid, startframe); + softbody_update_positions(ob, sb, vertexCos, numVerts); - softbody_update_positions(ob, sb, vertexCos, numVerts); + /* checking time: */ + dtime = framedelta*timescale; - /* checking time: */ - dtime = framedelta*timescale; + softbody_step(scene, ob, sb, dtime); - softbody_step(scene, ob, sb, dtime); - - if(sb->particles==0) - softbody_to_object(ob, vertexCos, numVerts, 0); + softbody_to_object(ob, vertexCos, numVerts, 0); - /* do simulation */ - cache->simframe= framenr; - cache->flag |= PTCACHE_SIMULATION_VALID; + /* do simulation */ + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; - BKE_ptcache_write_cache(&pid, framenr); - } + BKE_ptcache_write_cache(&pid, framenr); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 37031f4f82a..5b45a4219c7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3114,17 +3114,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->child=newdataadr(fd,psys->child); psys->effectors.first=psys->effectors.last=0; - psys->soft= newdataadr(fd, psys->soft); - if(psys->soft) { - SoftBody *sb = psys->soft; - sb->particles = psys; - sb->bpoint= NULL; // init pointers so it gets rebuilt nicely - sb->bspring= NULL; - sb->scratch= NULL; - - direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache); - } - link_list(fd, &psys->targets); psys->edit = NULL; @@ -3137,6 +3126,23 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache); + if(psys->clmd) { + psys->clmd = newdataadr(fd, psys->clmd); + psys->clmd->clothObject = NULL; + + psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms); + psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms); + + if(psys->clmd->sim_parms) { + if(psys->clmd->sim_parms->presets > 10) + psys->clmd->sim_parms->presets = 0; + } + + psys->hair_in_dm = psys->hair_out_dm = NULL; + + psys->clmd->point_cache = psys->pointcache; + } + psys->tree = NULL; } return; @@ -8342,8 +8348,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ob->soft->pointcache= BKE_ptcache_add(&ob->soft->ptcaches); for(psys=ob->particlesystem.first; psys; psys=psys->next) { - if(psys->soft && !psys->soft->pointcache) - psys->soft->pointcache= BKE_ptcache_add(&psys->soft->ptcaches); + //if(psys->soft && !psys->soft->pointcache) + // psys->soft->pointcache= BKE_ptcache_add(&psys->soft->ptcaches); if(!psys->pointcache) psys->pointcache= BKE_ptcache_add(&psys->ptcaches); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 46cc62fff1c..98db27182ab 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -660,8 +660,13 @@ static void write_particlesystems(WriteData *wd, ListBase *particles) writestruct(wd, DATA, "ParticleTarget", 1, pt); if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child); - writestruct(wd, DATA, "SoftBody", 1, psys->soft); - if(psys->soft) write_pointcaches(wd, &psys->soft->ptcaches); + + if(psys->clmd) { + writestruct(wd, DATA, "ClothModifierData", 1, psys->clmd); + writestruct(wd, DATA, "ClothSimSettings", 1, psys->clmd->sim_parms); + writestruct(wd, DATA, "ClothCollSettings", 1, psys->clmd->coll_parms); + } + write_pointcaches(wd, &psys->ptcaches); } } diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 0f5e677b912..5acdcb40613 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -120,6 +120,20 @@ static int PE_poll(bContext *C) return (edit && (ob->mode & OB_MODE_PARTICLE_EDIT)); } +static int PE_hair_poll(bContext *C) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_active_object(C); + PTCacheEdit *edit; + + if(!scene || !ob) + return 0; + + edit= PE_get_current(scene, ob); + + return (edit && edit->psys && (ob->mode & OB_MODE_PARTICLE_EDIT)); +} + static int PE_poll_3dview(bContext *C) { return PE_poll(C) && CTX_wm_area(C)->spacetype == SPACE_VIEW3D && @@ -169,6 +183,8 @@ int PE_start_edit(PTCacheEdit *edit) { if(edit) { edit->edited = 1; + if(edit->psys) + edit->psys->flag |= PSYS_EDITED; return 1; } @@ -218,9 +234,16 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) if(psys->flag & PSYS_CURRENT) { if(psys->part && psys->part->type == PART_HAIR) { - if(!psys->edit && psys->flag & PSYS_HAIR_DONE) - PE_create_particle_edit(scene, ob, NULL, psys); - edit = psys->edit; + if(psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) { + if(!psys->pointcache->edit) + PE_create_particle_edit(scene, ob, pid->cache, NULL); + edit = pid->cache->edit; + } + else { + if(!psys->edit && psys->flag & PSYS_HAIR_DONE) + PE_create_particle_edit(scene, ob, NULL, psys); + edit = psys->edit; + } } else { if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) @@ -2387,7 +2410,7 @@ void PARTICLE_OT_delete(wmOperatorType *ot) /* api callbacks */ ot->exec= delete_exec; ot->invoke= WM_menu_invoke; - ot->poll= PE_poll; + ot->poll= PE_hair_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -3858,6 +3881,7 @@ static int clear_edited_exec(bContext *C, wmOperator *op) psys->recalc |= PSYS_RECALC_RESET; psys->flag &= ~PSYS_GLOBAL_HAIR; + psys->flag &= ~PSYS_EDITED; psys_reset(psys, PSYS_RESET_DEPSGRAPH); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); @@ -3894,15 +3918,13 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) pup= uiPupMenuBegin(C, "Specials", 0); layout= uiPupMenuLayout(pup); - if(edit->psys) { - uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); - if(pset->selectmode & SCE_SELECT_POINT) { - uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide"); - uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first"); - uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last"); - } - uiItemO(layout, NULL, 0, "PARTICLE_OT_remove_doubles"); + uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); + if(pset->selectmode & SCE_SELECT_POINT) { + uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide"); + uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first"); + uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last"); } + uiItemO(layout, NULL, 0, "PARTICLE_OT_remove_doubles"); uiPupMenuEnd(C, pup); @@ -3917,7 +3939,7 @@ void PARTICLE_OT_specials_menu(wmOperatorType *ot) /* api callbacks */ ot->invoke= specials_menu_invoke; - ot->poll= PE_poll; + ot->poll= PE_hair_poll; } /**************************** registration **********************************/ diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 0df6f6250ff..bc9b05dc12e 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -54,6 +54,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -728,6 +729,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) PTCacheEdit *edit = psys->edit; PTCacheEditPoint *point = edit ? edit->points : NULL; PTCacheEditKey *ekey = NULL; + DerivedMesh *dm = NULL; HairKey *key; int i, k; float hairmat[4][4]; @@ -738,13 +740,18 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) if(!psys->part || psys->part->type != PART_HAIR) return; + if(psmd->dm->deformedOnly) + dm= psmd->dm; + else + dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + for(i=0; itotpart; i++,pa++) { if(point) { ekey = point->keys; point++; } - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, dm, psys->part->from, pa, hairmat); for(k=0,key=pa->hair; ktotkey; k++,key++) { Mat4MulVecfl(hairmat,key->co); @@ -758,6 +765,9 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) psys_free_path_cache(psys, psys->edit); + if(!psmd->dm->deformedOnly) + dm->release(dm); + psys->flag |= PSYS_GLOBAL_HAIR; PE_update_object(scene, ob, 0); @@ -814,8 +824,8 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) BVHTreeFromMesh bvhtree; BVHTreeNearest nearest; MFace *mface; - DerivedMesh *dm = CDDM_copy(psmd->dm); - int numverts = dm->getNumVerts (dm); + DerivedMesh *dm = NULL; + int numverts; int i, k; float hairmat[4][4], imat[4][4]; float v[4][3], vec[3]; @@ -823,6 +833,13 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) if(!psys || !psys->part || psys->part->type != PART_HAIR) return; + if(psmd->dm->deformedOnly) + dm= psmd->dm; + else + dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + + numverts = dm->getNumVerts (dm); + memset( &bvhtree, 0, sizeof(bvhtree) ); /* convert to global coordinates */ @@ -881,7 +898,8 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) } free_bvhtree_from_mesh(&bvhtree); - dm->release(dm); + if(!psmd->dm->deformedOnly) + dm->release(dm); psys_free_path_cache(psys, psys->edit); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 7ed029f3eaf..aa9c28dbef2 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3727,6 +3727,12 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj float nosel_col[3]; float *pathcol = NULL, *pcol; + + if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) { + PE_update_object(scene, ob, 0); + edit->psys->flag &= ~PSYS_HAIR_UPDATED; + } + /* create path and child path cache if it doesn't exist already */ if(edit->pathcache==0) psys_cache_edit_paths(scene, ob, edit, CFRA); diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 33984582d7f..5cfecf7cc01 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -68,6 +68,7 @@ typedef struct ClothSimSettings float defgoal; float goalspring; float goalfrict; + float velocity_smooth; /* smoothing of velocities for hair */ int stepsPerFrame; /* Number of time steps per frame. */ int flags; /* flags, see CSIMSETT_FLAGS enum above. */ int preroll; /* How many frames of simulation to do before we start. */ @@ -78,7 +79,6 @@ typedef struct ClothSimSettings short vgroup_struct; /* vertex group for scaling structural stiffness */ short presets; /* used for presets on GUI */ short pad; - int pad2; } ClothSimSettings; diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 5696f82ab0d..986a75f1a96 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -184,8 +184,6 @@ typedef struct BulletSoftBody { typedef struct SoftBody { - struct ParticleSystem *particles; /* particlesystem softbody */ - /* dynamic data */ int totpoint, totspring; struct BodyPoint *bpoint; /* not saved in file */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index d4dc3df0965..6a0a0e1d912 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -105,7 +105,7 @@ typedef struct ParticleData { short flag; short alive; /* the life state of a particle */ short loop; /* how many times particle life has looped */ - short rt; + short hair_index; } ParticleData; typedef struct ParticleSettings { @@ -202,7 +202,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in struct ParticleCacheKey **childcache; /* child cache (runtime) */ ListBase pathcachebufs, childcachebufs; /* buffers for the above */ - struct SoftBody *soft; /* hair softbody */ + struct ClothModifierData *clmd; /* cloth simulation for hair */ + struct DerivedMesh *hair_in_dm, *hair_out_dm; /* input/output for cloth simulation */ struct Object *target_ob; struct Object *lattice; @@ -216,9 +217,9 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in float imat[4][4]; /* used for duplicators */ float cfra, tree_frame; - int seed; + int seed, rt; int flag, totpart, totchild, totcached, totchildcache; - short recalc, target_psys, totkeyed, softflag, bakespace, rt2; + short recalc, target_psys, totkeyed, bakespace; char bb_uvname[3][32]; /* billboard uv name */ @@ -411,16 +412,16 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in /* psys->flag */ #define PSYS_CURRENT 1 #define PSYS_GLOBAL_HAIR 2 -//#define PSYS_BAKE_UI 4 +#define PSYS_HAIR_DYNAMICS 4 #define PSYS_KEYED_TIMING 8 #define PSYS_ENABLED 16 /* deprecated */ -//#define PSYS_FIRST_KEYED 32 +#define PSYS_HAIR_UPDATED 32 /* signal for updating hair particle mode */ #define PSYS_DRAWING 64 //#define PSYS_SOFT_BAKE 128 #define PSYS_DELETE 256 /* remove particlesystem as soon as possible */ #define PSYS_HAIR_DONE 512 #define PSYS_KEYED 1024 -//#define PSYS_EDITED 2048 +#define PSYS_EDITED 2048 //#define PSYS_PROTECT_CACHE 4096 #define PSYS_DISABLED 8192 diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 38086502d6f..22cc2e2c9c3 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -152,7 +152,7 @@ static char *rna_ClothSettings_path(PointerRNA *ptr) Object *ob= (Object*)ptr->id.data; ModifierData *md= modifiers_findByType(ob, eModifierType_Cloth); - return BLI_sprintfN("modifiers[%s].settings", md->name); + return md ? BLI_sprintfN("modifiers[%s].settings", md->name) : NULL; } static char *rna_ClothCollisionSettings_path(PointerRNA *ptr) @@ -160,7 +160,7 @@ static char *rna_ClothCollisionSettings_path(PointerRNA *ptr) Object *ob= (Object*)ptr->id.data; ModifierData *md= modifiers_findByType(ob, eModifierType_Cloth); - return BLI_sprintfN("modifiers[%s].collision_settings", md->name); + return md ? BLI_sprintfN("modifiers[%s].collision_settings", md->name) : NULL; } #else @@ -207,6 +207,12 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction."); RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop= RNA_def_property(srna, "internal_friction", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "velocity_smooth"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Internal Friction", ""); + RNA_def_property_update(prop, 0, "rna_cloth_update"); + /* mass */ prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 719e6f43eed..e6f0a462f03 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -33,6 +33,7 @@ #include "rna_internal.h" +#include "DNA_modifier_types.h" #include "DNA_particle_types.h" #include "DNA_object_force.h" #include "DNA_object_types.h" @@ -96,7 +97,9 @@ EnumPropertyItem part_hair_ren_as_items[] = { #ifdef RNA_RUNTIME #include "BKE_context.h" +#include "BKE_cloth.h" #include "BKE_depsgraph.h" +#include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -249,6 +252,21 @@ static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr) WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } +static void rna_Particle_hair_dynamics(bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + ParticleSystem *psys = (ParticleSystem*)ptr->data; + + if(psys && !psys->clmd) { + psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth); + psys->clmd->sim_parms->goalspring = 0.0f; + psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS; + psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF; + rna_Particle_redo(C, ptr); + } + else + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); +} static PointerRNA rna_particle_settings_get(PointerRNA *ptr) { Object *ob= (Object*)ptr->id.data; @@ -467,7 +485,7 @@ static int rna_ParticleSystem_edited_get(PointerRNA *ptr) ParticleSystem *psys= (ParticleSystem*)ptr->data; if(psys->part && psys->part->type==PART_HAIR) - return (psys->edit && psys->edit->edited); + return (psys->flag & PSYS_EDITED || (psys->edit && psys->edit->edited)); else return (psys->pointcache->edit && psys->pointcache->edit->edited); } @@ -1876,19 +1894,22 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* hair */ - prop= RNA_def_property(srna, "softbody", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "soft"); - RNA_def_property_ui_text(prop, "Soft Body", "Soft body settings for hair physics simulation."); - - prop= RNA_def_property(srna, "use_softbody", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "softflag", OB_SB_ENABLE); - RNA_def_property_ui_text(prop, "Use Soft Body", "Enable use of soft body for hair physics simulation."); - prop= RNA_def_property(srna, "global_hair", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_GLOBAL_HAIR); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Global Hair", "Hair keys are in global coordinate space"); + prop= RNA_def_property(srna, "hair_dynamics", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_HAIR_DYNAMICS); + RNA_def_property_ui_text(prop, "Hair Dynamics", "Enable hair dynamics using cloth simulation."); + RNA_def_property_update(prop, 0, "rna_Particle_hair_dynamics"); + + prop= RNA_def_property(srna, "cloth", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "clmd"); + RNA_def_property_struct_type(prop, "ClothModifier"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Cloth", "Cloth dynamics for hair"); + /* reactor */ prop= RNA_def_property(srna, "reactor_target_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "target_ob"); -- cgit v1.2.3 From d1314c3db541a8919eb8414d1718bdee273a8a9f Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 10 Sep 2009 23:46:42 +0000 Subject: * we currently can have *four* different sound devices, instead of 3. --- intern/audaspace/intern/AUD_C-API.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 7a624aa53fd..45faebc7e97 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -67,7 +67,7 @@ typedef AUD_ReadDevice AUD_Device; #endif static AUD_IDevice* AUD_device = NULL; -static int AUD_available_devices[3]; +static int AUD_available_devices[4]; static AUD_I3DDevice* AUD_3ddevice = NULL; int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize) -- cgit v1.2.3 From 71907c7e4c7c20575edcb50ec29025284a9f9bed Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Fri, 11 Sep 2009 00:23:08 +0000 Subject: Disconnect hair was using wrong derived mesh for the space conversion. --- source/blender/editors/space_buttons/buttons_ops.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index bc9b05dc12e..176611377eb 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -729,7 +729,6 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) PTCacheEdit *edit = psys->edit; PTCacheEditPoint *point = edit ? edit->points : NULL; PTCacheEditKey *ekey = NULL; - DerivedMesh *dm = NULL; HairKey *key; int i, k; float hairmat[4][4]; @@ -740,18 +739,13 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) if(!psys->part || psys->part->type != PART_HAIR) return; - if(psmd->dm->deformedOnly) - dm= psmd->dm; - else - dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); - for(i=0; itotpart; i++,pa++) { if(point) { ekey = point->keys; point++; } - psys_mat_hair_to_global(ob, dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); for(k=0,key=pa->hair; ktotkey; k++,key++) { Mat4MulVecfl(hairmat,key->co); @@ -765,9 +759,6 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) psys_free_path_cache(psys, psys->edit); - if(!psmd->dm->deformedOnly) - dm->release(dm); - psys->flag |= PSYS_GLOBAL_HAIR; PE_update_object(scene, ob, 0); -- cgit v1.2.3 From fc11700628b56d77cfd57c35c04e07e00d46b10e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 11 Sep 2009 00:49:54 +0000 Subject: 2.5 - Bugfix for curve-following animation not working Optimisation for not working with AnimData when there were no actions meant that the special hack to set this value didn't get set. --- source/blender/blenkernel/intern/anim_sys.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 0e8450025da..2d6a97c48ae 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1450,7 +1450,6 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re * 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a * standard 'root') block are overridden by a larger 'user' */ -// FIXME?: we currently go over entire 'main' database... void BKE_animsys_evaluate_all_animation (Main *main, float ctime) { ID *id; @@ -1474,8 +1473,11 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) * when there are no actions, don't go over database and loop over heaps of datablocks, * which should ultimately be empty, since it is not possible for now to have any animation * without some actions, and drivers wouldn't get affected by any state changes + * + * however, if there are some curves, we will need to make sure that their 'ctime' property gets + * set correctly, so this optimisation must be skipped in that case... */ - if (main->action.first == NULL) { + if ((main->action.first == NULL) && (main->curve.first == NULL)) { if (G.f & G_DEBUG) printf("\tNo Actions, so no animation needs to be evaluated...\n"); @@ -1509,6 +1511,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) * value of the curve gets set in case there's no animation for that * - it needs to be set before animation is evaluated just so that * animation can successfully override... + * - it shouldn't get set when calculating drivers... */ for (id= main->curve.first; id; id= id->next) { AnimData *adt= BKE_animdata_from_id(id); -- cgit v1.2.3 From 40576677b1dff5373d5b673b599ea9beb094b1ea Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 11 Sep 2009 09:09:54 +0000 Subject: 2.5: Two Bugfixes * Mesh Deform modifier now correctly shows Bind/Unbind buttons. Previously, only Bind got shown... * Selecting keyframes in the Graph Editor using Border Select now allows the keyframes to be editable afterwards. Previously, the curves weren't getting selected afterwards, therefore, the poll operators would skip those curves. --- release/ui/buttons_data_modifier.py | 11 +++++++---- source/blender/editors/space_graph/graph_select.c | 9 ++++++++- source/blender/makesrna/intern/rna_modifier.c | 12 +++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py index 2835f55f71a..754e8ce106e 100644 --- a/release/ui/buttons_data_modifier.py +++ b/release/ui/buttons_data_modifier.py @@ -242,10 +242,13 @@ class DATA_PT_modifiers(DataButtonsPanel): layout.itemS() - layout.itemO("object.meshdeform_bind", text="Bind") - row = layout.row() - row.itemR(md, "precision") - row.itemR(md, "dynamic") + if md.is_bound: + layout.itemO("object.meshdeform_bind", text="Unbind") + else: + layout.itemO("object.meshdeform_bind", text="Bind") + row = layout.row() + row.itemR(md, "precision") + row.itemR(md, "dynamic") def MIRROR(self, layout, ob, md): layout.itemR(md, "merge_limit") diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 43f35862315..728c9310a47 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -234,6 +234,7 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho /* loop over data, doing border select */ for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(ac, ale); + FCurve *fcu= (FCurve *)ale->key_data; /* set horizontal range (if applicable) */ if (mode != BEZT_OK_VALUERANGE) { @@ -253,7 +254,13 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho } /* select keyframes that are in the appropriate places */ - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_fcurve_keys_bezier_loop(&bed, fcu, ok_cb, select_cb, NULL); + + /* select the curve too + * NOTE: this should really only happen if the curve got touched... + */ + if (selectmode == SELECT_ADD) + fcu->flag |= FCURVE_SELECTED; } /* cleanup */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 28223d2f80b..32e34559f1f 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -384,6 +384,11 @@ static void rna_ArrayModifier_curve_set(PointerRNA *ptr, PointerRNA value) modifier_object_set(&((ArrayModifierData*)ptr->data)->curve_ob, OB_CURVE, value); } +static int rna_MeshDeformModifier_is_bound_get(PointerRNA *ptr) +{ + return (((MeshDeformModifierData*)ptr->data)->bindcos != NULL); +} + static PointerRNA rna_SoftBodyModifier_settings_get(PointerRNA *ptr) { Object *ob= (Object*)ptr->id.data; @@ -1368,7 +1373,12 @@ static void rna_def_modifier_meshdeform(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, "rna_MeshDeformModifier_object_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); - + + prop= RNA_def_property(srna, "is_bound", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_MeshDeformModifier_is_bound_get", NULL); + RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to control cage."); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop= RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MDEF_INVERT_VGROUP); RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence."); -- cgit v1.2.3 From d5009eb1423c3c0359cbc85c7346412c597b8663 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 11 Sep 2009 12:05:09 +0000 Subject: 2.5 Rotations: As a experiment, enabling Axis-Angle for Bones The support for this is really quite hacky, and I might disable this later if we cannot get some parts to work nicely. Some notes: * This is currently stored in the same variable that quaternions are stored in, since they both have 4 components. However, in RNA, I've added 2 properties specially for this. * There are some shearing issues using certain axes - i.e. (1,1,0) - that will need to be checked on. * Transform code is really quite temporary for this. Just a quick demo of what can be done... --- release/ui/buttons_data_bone.py | 4 ++ source/blender/blenkernel/intern/armature.c | 8 ++- source/blender/editors/transform/transform.c | 11 +++- .../editors/transform/transform_conversions.c | 4 +- source/blender/makesrna/intern/rna_pose.c | 74 ++++++++++++++++++++-- source/blender/windowmanager/intern/wm_files.c | 2 +- 6 files changed, 92 insertions(+), 11 deletions(-) diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index 0d379a4788f..5aac44bbc94 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -58,6 +58,10 @@ class BONE_PT_transform(BoneButtonsPanel): col = row.column() if pchan.rotation_mode == 'QUATERNION': col.itemR(pchan, "rotation", text="Rotation") + elif pchan.rotation_mode == 'AXIS_ANGLE': + col.itemL(text="Rotation") + col.itemR(pchan, "rotation_angle", text="Angle") + col.itemR(pchan, "rotation_axis", text="Axis") else: col.itemR(pchan, "euler_rotation", text="Rotation") diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 95c4c2966c6..0c18817f8be 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1986,11 +1986,15 @@ void chan_calc_mat(bPoseChannel *chan) /* get scaling matrix */ SizeToMat3(chan->size, smat); - /* rotations may either be quats or eulers (no rotation modes for now...) */ + /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */ if (chan->rotmode > 0) { - /* euler rotations (will cause gimble lock... no rotation order to solve that yet) */ + /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */ EulOToMat3(chan->eul, chan->rotmode, rmat); } + else if (chan->rotmode == PCHAN_ROT_AXISANGLE) { + /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ + VecRotToMat3(&chan->quat[1], chan->quat[0], rmat); + } else { /* quats are normalised before use to eliminate scaling issues */ NormalQuat(chan->quat); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index f049566d640..ac5d688cd1c 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2663,7 +2663,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* rotation */ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself - /* euler or quaternion? */ + /* euler or quaternion/axis-angle? */ if (td->flag & TD_USEQUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); @@ -2672,6 +2672,15 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short QuatMul(td->ext->quat, quat, td->ext->iquat); /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); + + /* if axis-angle, we now convert the quat representation to axis-angle again + * - this means that the math above is not totally correct, but it works well enough so far... + */ + if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + /* make temp copy (since stored in same place) */ + QuatCopy(quat, td->ext->quat); + QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); + } } else { float eulmat[3][3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 504563b797b..7a37ffdeeca 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -552,8 +552,9 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ob = ob; td->flag = TD_SELECTED; - if (pchan->rotmode == PCHAN_ROT_QUAT) + if ((pchan->rotmode == PCHAN_ROT_QUAT) || (pchan->rotmode == PCHAN_ROT_AXISANGLE)) { + // XXX: for now, axis-angle will be treated like for quats (the only difference is the normalisation) td->flag |= TD_USEQUAT; } if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) @@ -587,6 +588,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->quat= pchan->quat; QUATCOPY(td->ext->iquat, pchan->quat); + td->rotOrder= pchan->rotmode; } diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 7d7f37a8f43..0a88b084307 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -110,26 +110,64 @@ IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create) return pchan->prop; } +/* rotation - euler angles */ static void rna_PoseChannel_euler_rotation_get(PointerRNA *ptr, float *value) { bPoseChannel *pchan= ptr->data; - - if(pchan->rotmode == PCHAN_ROT_QUAT) + + if(pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float m[3][3]; + + /* go through a 3x3 matrix */ + VecRotToMat3(&pchan->quat[1], pchan->quat[0], m); + Mat3ToEul(m, value); + } + else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers when using axis-angle... */ QuatToEul(pchan->quat, value); else VECCOPY(value, pchan->eul); } +/* rotation - euler angles */ static void rna_PoseChannel_euler_rotation_set(PointerRNA *ptr, const float *value) { bPoseChannel *pchan= ptr->data; - - if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers when using quats... */ + + if(pchan->rotmode == PCHAN_ROT_AXISANGLE) { /* default XYZ eulers when using axis-angle... */ + float q[4]; + + /* convert to temp quat, then to axis angle (since stored in same var) */ + EulToQuat((float *)value, q); + QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); + } + else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers when using quats... */ EulToQuat((float*)value, pchan->quat); else VECCOPY(pchan->eul, value); } +/* rotation - axis angle only */ +static void rna_PoseChannel_rotation_axis_get(PointerRNA *ptr, float *value) +{ + bPoseChannel *pchan= ptr->data; + + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + /* axis is stord in quat for now */ + VecCopyf(value, &pchan->quat[1]); + } +} + +/* rotation - axis angle only */ +static void rna_PoseChannel_rotation_axis_set(PointerRNA *ptr, const float *value) +{ + bPoseChannel *pchan= ptr->data; + + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + /* axis is stored in quat for now */ + VecCopyf(&pchan->quat[1], (float *)value); + } +} + static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) { bPoseChannel *pchan= ptr->data; @@ -185,6 +223,12 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) QuatCopy(q, pchan->quat); QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); } + + /* when converting to axis-angle, we need a special exception for the case when there is no axis */ + if (IS_EQ(pchan->quat[1], pchan->quat[2]) && IS_EQ(pchan->quat[2], pchan->quat[3])) { + /* for now, rotate around y-axis then (so that it simply becomes the roll) */ + pchan->quat[2]= 1.0f; + } } /* finally, set the new rotation type */ @@ -421,7 +465,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) {PCHAN_ROT_YZX, "YZX", 0, "YZX Euler", "YZX Rotation Order. Prone to Gimbal Lock"}, {PCHAN_ROT_ZXY, "ZXY", 0, "ZXY Euler", "ZXY Rotation Order. Prone to Gimbal Lock"}, {PCHAN_ROT_ZYX, "ZYX", 0, "ZYX Euler", "ZYX Rotation Order. Prone to Gimbal Lock"}, - //{PCHAN_ROT_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."}, + {PCHAN_ROT_AXISANGLE, "AXIS_ANGLE", 0, "Axis Angle", "Axis Angle (W+XYZ). Defines a rotation around some axis defined by 3D-Vector."}, {0, NULL, 0, NULL, NULL}}; StructRNA *srna; @@ -493,6 +537,18 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Rotation", "Rotation in Quaternions."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); + prop= RNA_def_property(srna, "rotation_angle", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "quat[0]"); + RNA_def_property_ui_text(prop, "Rotation Angle", "Angle of Rotation for Axis-Angle rotation representation."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); + + prop= RNA_def_property(srna, "rotation_axis", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "quat"); + RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_axis_get", "rna_PoseChannel_rotation_axis_set", NULL); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Rotation Axis", "Axis for Axis-Angle rotation representation."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); + prop= RNA_def_property(srna, "euler_rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "eul"); RNA_def_property_float_funcs(prop, "rna_PoseChannel_euler_rotation_get", "rna_PoseChannel_euler_rotation_set", NULL); @@ -662,8 +718,14 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface."); + RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation (with three components) in the interface."); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); + + //prop= RNA_def_property(srna, "lock_rotation_4d", PROP_BOOLEAN, PROP_XYZ); + //RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTW); + //RNA_def_property_array(prop, 4); + //RNA_def_property_ui_text(prop, "Lock Rotation (4D)", "Lock editing of rotations (with four components) in the interface."); + //RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "lock_scale", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_SCALEX); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index a6e38a61e0f..9694a8fa1c6 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -281,7 +281,7 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) /* called on startup, (context entirely filled with NULLs) */ -/* or called for 'Erase All' */ +/* or called for 'New File' */ /* op can be NULL */ int WM_read_homefile(bContext *C, wmOperator *op) { -- cgit v1.2.3 From baf12d3d1712235f94bf7db27aed21421d74efea Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 11 Sep 2009 12:44:09 +0000 Subject: 2.5 - Rotation work (axis angle bugfixes + cleanups) * Made transform work better with axis-angle * Corrected the rotation-type handling code in a few places --- source/blender/editors/armature/editarmature.c | 12 ++++++++++ source/blender/editors/armature/poselib.c | 16 ++++--------- source/blender/editors/armature/poseobject.c | 14 ++++++++--- .../blender/editors/space_view3d/view3d_buttons.c | 26 ++++++++++++++++++--- source/blender/editors/transform/transform.c | 27 +++++++++++++++------- .../editors/transform/transform_conversions.c | 3 +-- 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 4f5d8872384..3b6c9e9d13d 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4856,9 +4856,13 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) QUATCOPY(quat1, pchan->quat); QuatToEul(pchan->quat, oldeul); } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + continue; // XXX + } else { VECCOPY(oldeul, pchan->eul); } + eul[0]= eul[1]= eul[2]= 0.0f; if (pchan->protectflag & OB_LOCK_ROTX) @@ -4875,6 +4879,9 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) QuatMulf(pchan->quat, -1.0f); } } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + // TODO... + } else { VECCOPY(pchan->eul, eul); } @@ -4884,6 +4891,11 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) pchan->quat[1]=pchan->quat[2]=pchan->quat[3]= 0.0f; pchan->quat[0]= 1.0f; } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + /* by default, make rotation of 0 radians around y-axis (roll) */ + pchan->quat[0]=pchan->quat[1]=pchan->quat[3]= 0.0f; + pchan->quat[2]= 1.0f; + } else { pchan->eul[0]= pchan->eul[1]= pchan->eul[2]= 0.0f; } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 56d714fd058..46d08afa656 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -278,8 +278,7 @@ void poselib_validate_act (bAction *act) /* ************************************************************* */ /* Pointers to the builtin KeyingSets that we want to use */ -static KeyingSet *poselib_ks_locrotscale = NULL; /* quaternion rotations */ -static KeyingSet *poselib_ks_locrotscale2 = NULL; /* euler rotations */ // XXX FIXME... +static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll need*/ static short poselib_ks_need_init= 1; /* have the above been obtained yet? */ /* Make sure the builtin KeyingSets are initialised properly @@ -290,13 +289,9 @@ static void poselib_get_builtin_keyingsets (void) /* only if we haven't got these yet */ // FIXME: this assumes that we will always get the builtin sets... if (poselib_ks_need_init) { - /* LocRotScale (quaternions) */ + /* LocRotScale (quaternions or eulers depending on context) */ poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - /* LocRotScale (euler) */ - //ks_locrotscale2= ANIM_builtin_keyingset_get_named(ks_locrotscale, "LocRotScale"); - poselib_ks_locrotscale2= poselib_ks_locrotscale; // FIXME: for now, just use the same one... - /* clear flag requesting init */ poselib_ks_need_init= 0; } @@ -410,11 +405,8 @@ static int poselib_add_exec (bContext *C, wmOperator *op) /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ cks.pchan= pchan; - /* KeyingSet to use depends on rotation mode */ - if (pchan->rotmode) - modify_keyframes(C, &dsources, act, poselib_ks_locrotscale2, MODIFYKEY_MODE_INSERT, (float)frame); - else - modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); + /* KeyingSet to use depends on rotation mode (but that's handled by the templates code) */ + modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); } } } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 0ae92de4407..9a404e24e12 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -812,10 +812,17 @@ void pose_copy_menu(Scene *scene) armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat); - if (pchan->rotmode > 0) - Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode); - else + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float tmp_quat[4]; + + /* need to convert to quat first (in temp var)... */ + Mat4ToQuat(delta_mat, tmp_quat); + QuatToAxisAngle(tmp_quat, &pchan->quat[1], &pchan->quat[0]); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) Mat4ToQuat(delta_mat, pchan->quat); + else + Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode); } break; case 11: /* Visual Size */ @@ -991,6 +998,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) pchan->flag= chan->flag; /* check if rotation modes are compatible (i.e. do they need any conversions) */ + // FIXME: add axis-angle here too... if (pchan->rotmode == chan->rotmode) { /* copy the type of rotation in use */ if (pchan->rotmode > 0) { diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 06320f871da..d78928921e5 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -511,8 +511,17 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 140, 140, 19, bone->name, 1, 31, 0, 0, ""); uiButSetFunc(but, validate_bonebutton_cb, bone, NULL); uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob); - - QuatToEulO(pchan->quat, tfp->ob_eul, pchan->rotmode); // XXX? + + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float quat[4]; + /* convert to euler, passing through quats... */ + AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]); + QuatToEul(quat, tfp->ob_eul); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) + QuatToEul(pchan->quat, tfp->ob_eul); + else + VecCopyf(tfp->ob_eul, pchan->eul); tfp->ob_eul[0]*= 180.0/M_PI; tfp->ob_eul[1]*= 180.0/M_PI; tfp->ob_eul[2]*= 180.0/M_PI; @@ -841,7 +850,18 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) eul[0]= M_PI*tfp->ob_eul[0]/180.0; eul[1]= M_PI*tfp->ob_eul[1]/180.0; eul[2]= M_PI*tfp->ob_eul[2]/180.0; - EulOToQuat(eul, pchan->rotmode, pchan->quat); // xxx? + + if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float quat[4]; + /* convert to axis-angle, passing through quats */ + EulToQuat(eul, quat); + QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]); + } + else if (pchan->rotmode == PCHAN_ROT_QUAT) + EulToQuat(eul, pchan->quat); + else + VecCopyf(pchan->eul, eul); + } /* no break, pass on */ case B_ARMATUREPANEL2: diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ac5d688cd1c..6405e87c4c0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2673,14 +2673,25 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); - /* if axis-angle, we now convert the quat representation to axis-angle again - * - this means that the math above is not totally correct, but it works well enough so far... - */ - if (td->rotOrder == PCHAN_ROT_AXISANGLE) { - /* make temp copy (since stored in same place) */ - QuatCopy(quat, td->ext->quat); - QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); - } + } + else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + /* calculate effect based on quats */ + float iquat[4]; + + /* td->ext->(i)quat is in axis-angle form, not quats! */ + AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]); + + Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); + Mat3ToQuat(fmat, quat); // Actual transform + + QuatMul(td->ext->quat, quat, iquat); + + /* this function works on end result */ + protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); + + /* make temp copy (since stored in same place) */ + QuatCopy(quat, td->ext->quat); + QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); } else { float eulmat[3][3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7a37ffdeeca..e0d058f160f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -552,9 +552,8 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ob = ob; td->flag = TD_SELECTED; - if ((pchan->rotmode == PCHAN_ROT_QUAT) || (pchan->rotmode == PCHAN_ROT_AXISANGLE)) + if (pchan->rotmode == PCHAN_ROT_QUAT) { - // XXX: for now, axis-angle will be treated like for quats (the only difference is the normalisation) td->flag |= TD_USEQUAT; } if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) -- cgit v1.2.3 From 4908a84825cc4e0dc8f931ce4a13edf84b230232 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 11 Sep 2009 14:31:05 +0000 Subject: Added in runtime path for python since were using a dynamic lib. (for Makefiles on linux) Kent --- source/nan_link.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/nan_link.mk b/source/nan_link.mk index 7211ba21e48..52e5c5de9ed 100644 --- a/source/nan_link.mk +++ b/source/nan_link.mk @@ -97,7 +97,7 @@ ifeq ($(OS),linux) COMMENT = "MESA 3.1" LLIBS = -L$(NAN_MESA)/lib -L/usr/X11R6/lib -lXmu -lXext -lX11 -lXi LLIBS += -lutil -lc -lm -ldl -lpthread - LLIBS += -lpython$(NAN_PYTHON_VERSION) + LLIBS += -L$(NAN_PYTHON)/lib -Wl,-rpath -Wl,$(NAN_PYTHON)/lib -lpython$(NAN_PYTHON_VERSION) LOPTS = -export-dynamic DADD = -lGL -lGLU SADD = $(NAN_MESA)/lib/libGL.a $(NAN_MESA)/lib/libGLU.a -- cgit v1.2.3 From 042d3e595693ce0c280b46d13db921afbcf105a4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 11 Sep 2009 14:56:54 +0000 Subject: 2.5: fix for merge, forward_diff_bezier needed to be updated. --- source/blender/editors/interface/interface_widgets.c | 4 ++-- source/blender/editors/space_graph/graph_draw.c | 4 ++-- source/blender/editors/space_node/drawnode.c | 4 ++-- source/blender/python/generic/Geometry.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index f0085f71373..2385b5ad15c 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1647,8 +1647,8 @@ static int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) vec[2][0]= vec[3][0]-dist; vec[2][1]= vec[3][1]; - forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, 2); - forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, 2); + forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2); + forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2); return 1; } diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index f3aa0fac42b..9ae7e8263ee 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -675,8 +675,8 @@ static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid) correct_bezpart(v1, v2, v3, v4); - forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, 3); - forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data+1, resol, 3); + forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float)*3); + forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data+1, resol, sizeof(float)*3); for (fp= data; resol; resol--, fp+= 3) glVertex2fv(fp); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 98de32a105a..05adb5b75ca 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2598,8 +2598,8 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa else { /* always do all three, to prevent data hanging around */ - forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, 2); - forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, 2); + forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2); + forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2); return 1; } diff --git a/source/blender/python/generic/Geometry.c b/source/blender/python/generic/Geometry.c index 70295d1c2d9..f7b7ee866f0 100644 --- a/source/blender/python/generic/Geometry.c +++ b/source/blender/python/generic/Geometry.c @@ -523,7 +523,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "BezierInterp"); for(i=0; i Date: Fri, 11 Sep 2009 15:35:30 +0000 Subject: curve twist * added new twist method - "Tangent", suggested by Martin. the nice thing about this is its stable no matter how you rotate the data, rotation is local to each segment. * added smooth option that smooths the twisting (before applying user twist), to workaround Z-Up and Tangent's ugly curve twisting. Id prefer not to have this however it makes tangent much nicer. Possibly tangent can be improved some other way and this can be removed. A smooth value of 1.0 will iterate over and smooth the twisting by the resolution value of the spline. * Minimum-Twist method now corrects for cyclic twist by taking the roll difference between first and last, then increasingly counter rotate each segment over the entire curve. Previously it calculated from both directions and blended them. details * BevPoints use quats rather then 3x3 matrix. * added BevPoint direction "dir" and tangent "tan" used only for 3D curves. * don't calculate BevPoint->cosa, BevPoint->sina for 3D curves. * split bevel tilt calculation into functions. * nurbs curves currently don't generate tangents and wont work with tangent twist method. * some of the use of quats should be optimized. * smoothing is not animation safe, the higher the smoothing the higher the likelyhood of flipping. --- release/ui/buttons_data_curve.py | 8 +- source/blender/blenkernel/BKE_utildefines.h | 1 + source/blender/blenkernel/intern/curve.c | 607 ++++++++++++++++------- source/blender/blenkernel/intern/displist.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 22 +- source/blender/makesdna/DNA_curve_types.h | 16 +- source/blender/makesrna/intern/rna_curve.c | 24 +- 7 files changed, 480 insertions(+), 200 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 1124dfd1ae8..010acd1479d 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -56,8 +56,7 @@ class DATA_PT_shape_curve(DataButtonsPanel): if not is_surf: row = layout.row() - row.itemR(curve, "curve_2d") - row.itemR(curve, "use_twist_correction") + row.itemR(curve, "curve_2d") split = layout.split() @@ -86,6 +85,11 @@ class DATA_PT_shape_curve(DataButtonsPanel): sub.itemR(curve, "resolution_v", text="Preview V") sub.itemR(curve, "render_resolution_v", text="Render V") + # XXX - put somewhere nicer. + row= layout.row() + row.itemR(curve, "twist_mode") + row.itemR(curve, "twist_smooth") # XXX - may not be kept + # col.itemL(text="Display:") # col.itemL(text="HANDLES") diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 76e0da98f69..4d43518901e 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -107,6 +107,7 @@ #define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} #define VECSUB2D(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1);} #define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);} +#define VECSUBFAC(v1,v2,v3,fac) {*(v1)= *(v2) - *(v3)*(fac); *(v1+1)= *(v2+1) - *(v3+1)*(fac); *(v1+2)= *(v2+2) - *(v3+2)*(fac);} #define QUATADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac); *(v1+3)= *(v2+3) + *(v3+3)*(fac);} #define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] ) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 802809b11e5..2b8c91fcbed 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -975,7 +975,26 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i q1+= q2; q2+= q3; } -} +} + +void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride) +{ + /* note that these are not purpendicular to the curve + * they need to be rotated for this, + * + * This could also be optimized like forward_diff_bezier */ + int a; + for(a=0; a<=it; a++) { + float t = (float)a / (float)it; + + int i; + for(i=0; i<3; i++) { + p[i]= (-6*t + 6)*p0[i] + (18*t - 12)*p1[i] + (-18*t + 6)*p2[i] + (6*t)*p3[i]; + } + Normalize(p); + p = (float *)(((char *)p)+stride); + } +} /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -1545,6 +1564,348 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * } } +/* make_bevel_list_3D_* funcs, at a minimum these must + * fill in the bezp->quat and bezp->dir values */ + +/* correct non-cyclic cases by copying direction and rotation + * values onto the first & last end-points */ +static void bevel_list_cyclic_fix(BevList *bl) +{ + BevPoint *bevp, *bevp1; + + bevp= (BevPoint *)(bl+1); + bevp1= bevp+1; + QUATCOPY(bevp->quat, bevp1->quat); + VECCOPY(bevp->dir, bevp1->dir); + VECCOPY(bevp->tan, bevp1->tan); + bevp= (BevPoint *)(bl+1); + bevp+= (bl->nr-1); + bevp1= bevp-1; + QUATCOPY(bevp->quat, bevp1->quat); + VECCOPY(bevp->dir, bevp1->dir); + VECCOPY(bevp->tan, bevp1->tan); +} +/* utility for make_bevel_list_3D_* funcs */ +static void bevel_list_calc_bisect(BevList *bl) +{ + BevPoint *bevp2, *bevp1, *bevp0; + int nr; + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + /* totally simple */ + VecBisect3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } +} +static void bevel_list_flip_tangents(BevList *bl) +{ + BevPoint *bevp2, *bevp1, *bevp0; + int nr; + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + if(VecAngle2(bevp0->tan, bevp1->tan) > 90) + VecNegf(bevp1->tan); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } +} +/* apply user tilt */ +static void bevel_list_apply_tilt(BevList *bl) +{ + BevPoint *bevp2, *bevp1, *bevp0; + int nr; + float q[4]; + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + AxisAngleToQuat(q, bevp1->dir, bevp1->alfa); + QuatMul(bevp1->quat, q, bevp1->quat); + NormalQuat(bevp1->quat); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } +} +/* smooth quats, this function should be optimized, it can get slow with many iterations. */ +static void bevel_list_smooth(BevList *bl, int smooth_iter) +{ + BevPoint *bevp2, *bevp1, *bevp0; + int nr; + + float q[4]; + float bevp0_quat[4]; + int a; + + for(a=0; a < smooth_iter; a++) { + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + + if(bl->poly== -1) { /* check its not cyclic */ + /* skip the first point */ + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + nr--; + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + nr--; + + } + + QUATCOPY(bevp0_quat, bevp0->quat); + + while(nr--) { + /* interpolate quats */ + float zaxis[3] = {0,0,1}, cross[3], q2[4]; + QuatInterpol(q, bevp0_quat, bevp2->quat, 0.5); + NormalQuat(q); + + QuatMulVecf(q, zaxis); + Crossf(cross, zaxis, bevp1->dir); + AxisAngleToQuat(q2, cross, NormalizedVecAngle2(zaxis, bevp1->dir)); + NormalQuat(q2); + + QUATCOPY(bevp0_quat, bevp1->quat); + QuatMul(q, q2, q); + QuatInterpol(bevp1->quat, bevp1->quat, q, 0.5); + NormalQuat(bevp1->quat); + + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } + } +} + +static void make_bevel_list_3D_zup(BevList *bl) +{ + BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ + int nr; + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + /* totally simple */ + VecBisect3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec); + vectoquat(bevp1->dir, 5, 1, bevp1->quat); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } +} + +static void make_bevel_list_3D_minimum_twist(BevList *bl) +{ + BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ + int nr; + float q[4]; + + float cross_tmp[3]; + + bevel_list_calc_bisect(bl); + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + + if(nr+4 > bl->nr) { /* first time and second time, otherwise first point adjusts last */ + vectoquat(bevp1->dir, 5, 1, bevp1->quat); + } + else { + float angle= NormalizedVecAngle2(bevp0->dir, bevp1->dir); + + if(angle > 0.0f) { /* otherwise we can keep as is */ + Crossf(cross_tmp, bevp0->dir, bevp1->dir); + AxisAngleToQuat(q, cross_tmp, angle); + QuatMul(bevp1->quat, q, bevp0->quat); + } + else { + QUATCOPY(bevp1->quat, bevp0->quat); + } + } + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } + + if(bl->poly != -1) { /* check for cyclic */ + + /* Need to correct for the start/end points not matching + * do this by calculating the tilt angle difference, then apply + * the rotation gradually over the entire curve + * + * note that the split is between last and second last, rather then first/last as youd expect. + * + * real order is like this + * 0,1,2,3,4 --> 1,2,3,4,0 + * + * this is why we compare last with second last + * */ + float vec_1[3]= {0,1,0}, vec_2[3]= {0,1,0}, angle, ang_fac, cross_tmp[3]; + + BevPoint *bevp_first; + BevPoint *bevp_last; + + + bevp_first= (BevPoint *)(bl+1); + bevp_first+= bl->nr-1; + bevp_last = bevp_first; + bevp_last--; + + /* quats and vec's are normalized, should not need to re-normalize */ + QuatMulVecf(bevp_first->quat, vec_1); + QuatMulVecf(bevp_last->quat, vec_2); + Normalize(vec_1); + Normalize(vec_2); + + /* align the vector, can avoid this and it looks 98% OK but + * better to align the angle quat roll's before comparing */ + { + Crossf(cross_tmp, bevp_last->dir, bevp_first->dir); + angle = NormalizedVecAngle2(bevp_first->dir, bevp_last->dir); + AxisAngleToQuat(q, cross_tmp, angle); + QuatMulVecf(q, vec_2); + } + + angle= NormalizedVecAngle2(vec_1, vec_2); + + /* flip rotation if needs be */ + Crossf(cross_tmp, vec_1, vec_2); + Normalize(cross_tmp); + if(NormalizedVecAngle2(bevp_first->dir, cross_tmp) < 90/(180.0/M_PI)) + angle = -angle; + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + ang_fac= angle * (1.0f-((float)nr/bl->nr)); /* also works */ + + AxisAngleToQuat(q, bevp1->dir, ang_fac); + QuatMul(bevp1->quat, q, bevp1->quat); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } + } +} + +static void make_bevel_list_3D_tangent(BevList *bl) +{ + BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ + int nr; + + float bevp0_tan[3], cross_tmp[3]; + + bevel_list_calc_bisect(bl); + if(bl->poly== -1) /* check its not cyclic */ + bevel_list_cyclic_fix(bl); // XXX - run this now so tangents will be right before doing the flipping + bevel_list_flip_tangents(bl); + + /* correct the tangents */ + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + nr= bl->nr; + while(nr--) { + + Crossf(cross_tmp, bevp1->tan, bevp1->dir); + Crossf(bevp1->tan, cross_tmp, bevp1->dir); + Normalize(bevp1->tan); + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } + + + /* now for the real twist calc */ + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+(bl->nr-1); + bevp0= bevp1-1; + + VECCOPY(bevp0_tan, bevp0->tan); + + nr= bl->nr; + while(nr--) { + + /* make perpendicular, modify tan in place, is ok */ + float cross_tmp[3]; + float zero[3] = {0,0,0}; + + Crossf(cross_tmp, bevp1->tan, bevp1->dir); + Normalize(cross_tmp); + triatoquat(zero, cross_tmp, bevp1->tan, bevp1->quat); /* XXX - could be faster */ + + bevp0= bevp1; + bevp1= bevp2; + bevp2++; + } +} + +void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode) +{ + switch(twist_mode) { + case CU_TWIST_TANGENT: + make_bevel_list_3D_tangent(bl); + break; + case CU_TWIST_MINIMUM: + make_bevel_list_3D_minimum_twist(bl); + break; + default: /* CU_TWIST_Z_UP default, pre 2.49c */ + make_bevel_list_3D_zup(bl); + } + + if(bl->poly== -1) /* check its not cyclic */ + bevel_list_cyclic_fix(bl); + + if(smooth_iter) + bevel_list_smooth(bl, smooth_iter); + + bevel_list_apply_tilt(bl); +} + + + void makeBevelList(Object *ob) { /* @@ -1559,7 +1920,7 @@ void makeBevelList(Object *ob) BPoint *bp; BevList *bl, *blnew, *blnext; BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; - float min, inp, x1, x2, y1, y2, vec[3], vec_prev[3], q[4], quat[4], quat_prev[4], cross[3]; + float min, inp, x1, x2, y1, y2; struct bevelsort *sortdata, *sd, *sd1; int a, b, nr, poly, resolu, len=0; int do_tilt, do_radius; @@ -1664,7 +2025,15 @@ void makeBevelList(Object *ob) do_tilt ? &bevp->alfa : NULL, do_radius ? &bevp->radius : NULL, resolu, sizeof(BevPoint)); + + if(cu->twist_mode==CU_TWIST_TANGENT) { + forward_diff_bezier_cotangent( + prevbezt->vec[1], prevbezt->vec[2], + bezt->vec[0], bezt->vec[1], + bevp->tan, resolu, sizeof(BevPoint)); + } + /* indicate with handlecodes double points */ if(prevbezt->h1==prevbezt->h2) { if(prevbezt->h1==0 || prevbezt->h1==HD_VECT) bevp->split_tag= TRUE; @@ -1843,208 +2212,90 @@ void makeBevelList(Object *ob) MEM_freeN(sortdata); } - /* STEP 4: COSINES */ - bl= cu->bev.first; - while(bl) { - - if(bl->nr < 2) { - /* do nothing */ - } - else if(bl->nr==2) { /* 2 pnt, treat separate */ - bevp2= (BevPoint *)(bl+1); - bevp1= bevp2+1; - - x1= bevp1->vec[0]- bevp2->vec[0]; - y1= bevp1->vec[1]- bevp2->vec[1]; - - calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa)); - bevp2->sina= bevp1->sina; - bevp2->cosa= bevp1->cosa; + /* STEP 4: 2D-COSINES or 3D ORIENTATION */ + if((cu->flag & CU_3D)==0) { /* 3D */ + bl= cu->bev.first; + while(bl) { - if(cu->flag & CU_3D) { /* 3D */ - float quat[4], q[4]; - - VecSubf(vec, bevp1->vec, bevp2->vec); - - vectoquat(vec, 5, 1, quat); - - AxisAngleToQuat(q, vec, bevp1->alfa); - QuatMul(quat, q, quat); - - QuatToMat3(quat, bevp1->mat); - Mat3CpyMat3(bevp2->mat, bevp1->mat); + if(bl->nr < 2) { + /* do nothing */ } + else if(bl->nr==2) { /* 2 pnt, treat separate */ + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+1; - } /* this has to be >2 points */ - else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) { - - /* Special case, cyclic curve with no twist. tricky... */ - - float quat[4], q[4], cross[3]; - - /* correcting a cyclic curve is more complicated, need to be corrected from both ends */ - float *quat_tmp1, *quat_tmp2; /* store a quat in the matrix temporarily */ - int iter_dir; - BevPoint *bevp_start= (BevPoint *)(bl+1); - - /* loop over the points twice, once up, once back, accumulate the quat rotations - * in both directions, then blend them in the 3rd loop and apply the tilt */ - for(iter_dir = 0; iter_dir < 2; iter_dir++) { + x1= bevp1->vec[0]- bevp2->vec[0]; + y1= bevp1->vec[1]- bevp2->vec[1]; + calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa)); + bevp2->sina= bevp1->sina; + bevp2->cosa= bevp1->cosa; + } + else { bevp2= (BevPoint *)(bl+1); bevp1= bevp2+(bl->nr-1); bevp0= bevp1-1; nr= bl->nr; while(nr--) { - - /* Normalizes */ - VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); + x1= bevp1->vec[0]- bevp0->vec[0]; + x2= bevp1->vec[0]- bevp2->vec[0]; + y1= bevp1->vec[1]- bevp0->vec[1]; + y2= bevp1->vec[1]- bevp2->vec[1]; - if(bl->nr==nr+1) { /* first time */ - vectoquat(vec, 5, 1, quat); - } - else { - float angle = NormalizedVecAngle2(vec_prev, vec); - - if(angle > 0.0f) { /* otherwise we can keep as is */ - Crossf(cross, vec_prev, vec); - AxisAngleToQuat(q, cross, angle); - QuatMul(quat, q, quat_prev); - } - else { - QUATCOPY(quat, quat_prev); - } - } - QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ - VECCOPY(vec_prev, vec); - - if(iter_dir==0) { /* up, first time */ - quat_tmp1= (float *)bevp1->mat; + calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); - bevp0= bevp1; - bevp1= bevp2; - bevp2++; - } - else { /* down second time */ - quat_tmp1= ((float *)bevp1->mat)+4; - - bevp2= bevp1; - bevp1= bevp0; - bevp0--; - - /* wrap around */ - if (bevp0 < bevp_start) - bevp0= bevp_start+(bl->nr-1); - } - - QUATCOPY(quat_tmp1, quat); + bevp0= bevp1; + bevp1= bevp2; + bevp2++; } - } - - /* Now interpolate the 2 quats and apply tilt */ - bevp2= (BevPoint *)(bl+1); - bevp1= bevp2+(bl->nr-1); - bevp0= bevp1-1; - - nr= bl->nr; - while(nr--) { - - VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); - - quat_tmp1= (float *)bevp1->mat; - quat_tmp2= quat_tmp1+4; - - /* blend the 2 rotations gathered from both directions */ - QuatInterpol(quat, quat_tmp1, quat_tmp2, 1.0 - (((float)nr)/bl->nr)); - - AxisAngleToQuat(q, vec, bevp1->alfa); - QuatMul(quat, q, quat); - QuatToMat3(quat, bevp1->mat); - - /* generic */ - x1= bevp1->vec[0]- bevp0->vec[0]; - x2= bevp1->vec[0]- bevp2->vec[0]; - y1= bevp1->vec[1]- bevp0->vec[1]; - y2= bevp1->vec[1]- bevp2->vec[1]; - - calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); - - bevp0= bevp1; - bevp1= bevp2; - bevp2++; - } - } - else { - /* Any curve with 3 or more points */ - - bevp2= (BevPoint *)(bl+1); - bevp1= bevp2+(bl->nr-1); - bevp0= bevp1-1; - - nr= bl->nr; - while(nr--) { - - if(cu->flag & CU_3D) { /* 3D */ - - /* Normalizes */ - VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); - - if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */ - vectoquat(vec, 5, 1, quat); - } - else { - float angle = NormalizedVecAngle2(vec_prev, vec); - - if(angle > 0.0f) { /* otherwise we can keep as is */ - Crossf(cross, vec_prev, vec); - AxisAngleToQuat(q, cross, angle); - QuatMul(quat, q, quat_prev); - } - else { - QUATCOPY(quat, quat_prev); - } - } - QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ - VECCOPY(vec_prev, vec); - - AxisAngleToQuat(q, vec, bevp1->alfa); - QuatMul(quat, q, quat); - QuatToMat3(quat, bevp1->mat); - } - - x1= bevp1->vec[0]- bevp0->vec[0]; - x2= bevp1->vec[0]- bevp2->vec[0]; - y1= bevp1->vec[1]- bevp0->vec[1]; - y2= bevp1->vec[1]- bevp2->vec[1]; - - calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); - - - bevp0= bevp1; - bevp1= bevp2; - bevp2++; - } - - /* correct non-cyclic cases */ - if(bl->poly== -1) { - if(bl->nr>2) { + /* correct non-cyclic cases */ + if(bl->poly== -1) { bevp= (BevPoint *)(bl+1); bevp1= bevp+1; bevp->sina= bevp1->sina; bevp->cosa= bevp1->cosa; - Mat3CpyMat3(bevp->mat, bevp1->mat); bevp= (BevPoint *)(bl+1); bevp+= (bl->nr-1); bevp1= bevp-1; bevp->sina= bevp1->sina; bevp->cosa= bevp1->cosa; - Mat3CpyMat3(bevp->mat, bevp1->mat); } } + bl= bl->next; + } + } + else { /* 3D Curves */ + bl= cu->bev.first; + while(bl) { + + if(bl->nr < 2) { + /* do nothing */ + } + else if(bl->nr==2) { /* 2 pnt, treat separate */ + float q[4]; + + bevp2= (BevPoint *)(bl+1); + bevp1= bevp2+1; + + /* simple quat/dir */ + VecSubf(bevp1->dir, bevp1->vec, bevp2->vec); + Normalize(bevp1->dir); + + vectoquat(bevp1->dir, 5, 1, bevp1->quat); + + AxisAngleToQuat(q, bevp1->dir, bevp1->alfa); + QuatMul(bevp1->quat, q, bevp1->quat); + NormalQuat(bevp1->quat); + VECCOPY(bevp2->dir, bevp1->dir); + QUATCOPY(bevp2->quat, bevp1->quat); + } + else { + make_bevel_list_3D(bl, (int)(resolu*cu->twist_smooth), cu->twist_mode); + } + bl= bl->next; } - bl= bl->next; } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 99baa17b582..d87dbc833c5 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1599,7 +1599,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) vec[1]= fp1[2]; vec[2]= 0.0; - Mat3MulVecfl(bevp->mat, vec); + QuatMulVecf(bevp->quat, vec); data[0]= bevp->vec[0] + fac*vec[0]; data[1]= bevp->vec[1] + fac*vec[1]; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 53fd6972641..69bc8e1f67e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4129,21 +4129,21 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, while (nr-->0) { /* accounts for empty bevel lists */ float fac= bevp->radius * ts->normalsize; - float ox,oy,oz; // Offset perpendicular to the curve - float dx,dy,dz; // Delta along the curve + float vec_a[3] = { fac,0, 0}; // Offset perpendicular to the curve + float vec_b[3] = {-fac,0, 0}; // Delta along the curve + + QuatMulVecf(bevp->quat, vec_a); + QuatMulVecf(bevp->quat, vec_b); + VecAddf(vec_a, vec_a, bevp->vec); + VecAddf(vec_b, vec_b, bevp->vec); - ox = fac*bevp->mat[0][0]; - oy = fac*bevp->mat[0][1]; - oz = fac*bevp->mat[0][2]; - - dx = fac*bevp->mat[2][0]; - dy = fac*bevp->mat[2][1]; - dz = fac*bevp->mat[2][2]; + VECSUBFAC(vec_a, vec_a, bevp->dir, fac); + VECSUBFAC(vec_b, vec_b, bevp->dir, fac); glBegin(GL_LINE_STRIP); - glVertex3f(bevp->vec[0] - ox - dx, bevp->vec[1] - oy - dy, bevp->vec[2] - oz - dz); + glVertex3fv(vec_a); glVertex3fv(bevp->vec); - glVertex3f(bevp->vec[0] + ox - dx, bevp->vec[1] + oy - dy, bevp->vec[2] + oz - dz); + glVertex3fv(vec_b); glEnd(); bevp += skip+1; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 3a7cf874dbd..013491187ae 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -71,7 +71,9 @@ typedef struct BevList { # # typedef struct BevPoint { - float vec[3], mat[3][3], alfa, radius, sina, cosa; + float vec[3], alfa, radius; + float sina, cosa; /* 2D Only */ + float dir[3], tan[3], quat[4]; /* 3D Only */ short split_tag, dupe_tag; } BevPoint; @@ -165,7 +167,8 @@ typedef struct Curve { int texflag; /* keep an int because of give_obdata_texspace() */ - short drawflag, pad[3]; + short drawflag, twist_mode, pad[2]; + float twist_smooth, pad2; short pathlen, totcol; short flag, bevresol; @@ -174,7 +177,7 @@ typedef struct Curve { /* default */ short resolu, resolv; short resolu_ren, resolv_ren; - + /* edit, index in nurb list */ int actnu; /* edit, last selected bpoint */ @@ -231,7 +234,12 @@ typedef struct Curve { #define CU_RETOPO 1024 #define CU_DS_EXPAND 2048 -#define CU_NO_TWIST 4096 +/* twist mode */ +#define CU_TWIST_Z_UP 0 +// #define CU_TWIST_Y_UP 1 // not used yet +// #define CU_TWIST_X_UP 2 +#define CU_TWIST_MINIMUM 3 +#define CU_TWIST_TANGENT 4 /* spacemode */ #define CU_LEFT 0 diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 91628bab376..d09546231d5 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -664,6 +664,12 @@ static void rna_def_curve(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem curve_twist_mode_items[] = { + {CU_TWIST_Z_UP, "Z_UP", 0, "Z-Up", "Use Z-Up axis to calculate the curve twist at each point"}, + {CU_TWIST_MINIMUM, "MINIMUM", 0, "Minimum", "Use the least twist over the entire curve"}, + {CU_TWIST_TANGENT, "TANGENT", 0, "Tangent", "Use the tangent to calculate twist"}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "Curve", "ID"); RNA_def_struct_ui_text(srna, "Curve", "Curve datablock storing curves, splines and NURBS."); RNA_def_struct_ui_icon(srna, ICON_CURVE_DATA); @@ -782,12 +788,22 @@ static void rna_def_curve(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_BACK); RNA_def_property_ui_text(prop, "Back", "Draw filled back for extruded/beveled curves."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - - prop= RNA_def_property(srna, "use_twist_correction", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_NO_TWIST); - RNA_def_property_ui_text(prop, "Minimal Twist", "Correct for twisting."); + + prop= RNA_def_property(srna, "twist_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "twist_mode"); + RNA_def_property_enum_items(prop, curve_twist_mode_items); + RNA_def_property_ui_text(prop, "Twist Method", "The type of tilt calculation for 3D Curves."); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + + // XXX - would be nice to have a better way to do this, only add for testing. + prop= RNA_def_property(srna, "twist_smooth", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "twist_smooth"); + RNA_def_property_ui_range(prop, 0, 100.0, 0.1, 0); + RNA_def_property_ui_text(prop, "Twist Smooth", "Smoothing iteration for tangents"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + + prop= RNA_def_property(srna, "retopo", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_RETOPO); RNA_def_property_ui_text(prop, "Retopo", "Turn on the re-topology tool."); -- cgit v1.2.3 From 6c3c748daa9b53cd6f36809b856dcccb24e8afaf Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 11 Sep 2009 18:31:51 +0000 Subject: client code wasn't modified to follow changes in the model --- release/io/netrender/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index bcfff8f5db5..d059387cfcf 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -110,7 +110,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): # if not ACCEPTED (but not processed), send files if response.status == http.client.ACCEPTED: - for filepath in job.files: + for filepath, start, end in job.files: f = open(filepath, "rb") conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath}) f.close() -- cgit v1.2.3 From 16547da5a98651c99f7bda088144292d4eba3904 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 11 Sep 2009 20:06:09 +0000 Subject: 2.5, Fix for bug #19296: render window escape incorrectly opens file browser. --- source/blender/editors/screen/area.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 9a116bf95c0..2cdb75e28e3 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1034,7 +1034,12 @@ void ED_area_prevspace(bContext *C) } #endif - ED_area_newspace(C, sa, sl->next->spacetype); + /* workaround for case of double prevspace, render window + with a file browser on top of it */ + if(sl->next->spacetype == SPACE_FILE && sl->next->next) + ED_area_newspace(C, sa, sl->next->next->spacetype); + else + ED_area_newspace(C, sa, sl->next->spacetype); } else { ED_area_newspace(C, sa, SPACE_INFO); -- cgit v1.2.3 From f0eb02a36b5a04d18a1a587b1e36419daa6a6f23 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 11 Sep 2009 21:02:31 +0000 Subject: 2.5 Revert some changes from commit 23090. Make sure you update SVN before you commit!! --- source/blender/windowmanager/intern/wm_operators.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 6debe5a8825..77f4fe25606 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -803,7 +803,7 @@ static int recentfile_exec(bContext *C, wmOperator *op) WM_read_file(C, G.sce, op->reports); } else { - struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-2); + struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-1); if(recent) { WM_event_add_notifier(C, NC_WINDOW, NULL); WM_read_file(C, recent->filename, op->reports); @@ -831,11 +831,11 @@ static EnumPropertyItem *open_recentfile_itemf(bContext *C, PointerRNA *ptr, int EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; struct RecentFile *recent; - int totitem= 0, i, ofs= 0; + int totitem= 0, i; /* dynamically construct enum */ for(recent = G.recent_files.first, i=0; (inext, i++) { - tmp.value= i+ofs+1; + tmp.value= i+1; tmp.identifier= recent->filename; tmp.name= BLI_short_filename(recent->filename); RNA_enum_item_add(&item, &totitem, &tmp); -- cgit v1.2.3 From 83074d0b3758c1b2d2811974726d4dd33f3034da Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 12 Sep 2009 05:06:28 +0000 Subject: 2.5 - More work on Axis-Angle Rotations * Added a few new methods for axis-angle conversions, and used these instead of manually performing those steps elsewhere * Axis-angles to other representations now get their axes normalised to make sure that odd scaling doesn't occur. * Made a few more tools work with axis-angles properly --- source/blender/blenkernel/intern/armature.c | 2 +- source/blender/blenlib/BLI_arithb.h | 21 +++-- source/blender/blenlib/intern/arithb.c | 89 +++++++++++++++++++++- source/blender/editors/animation/keyingsets.c | 2 +- source/blender/editors/armature/editarmature.c | 1 + source/blender/editors/armature/poseobject.c | 29 ++++++- source/blender/editors/transform/transform.c | 12 +-- .../editors/transform/transform_conversions.c | 4 + source/blender/makesrna/intern/rna_pose.c | 36 ++------- 9 files changed, 149 insertions(+), 47 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 0c18817f8be..c880925aa94 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1993,7 +1993,7 @@ void chan_calc_mat(bPoseChannel *chan) } else if (chan->rotmode == PCHAN_ROT_AXISANGLE) { /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ - VecRotToMat3(&chan->quat[1], chan->quat[0], rmat); + AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat); } else { /* quats are normalised before use to eliminate scaling issues */ diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 71604758b80..8eb4d5972e3 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -342,8 +342,6 @@ void Mat4AddMat4(float m1[][4], float m2[][4], float m3[][4]); void VecUpMat3old(float *vec, float mat[][3], short axis); void VecUpMat3(float *vec, float mat[][3], short axis); -void VecRotToMat3(float *vec, float phi, float mat[][3]); -void VecRotToMat4(float *vec, float phi, float mat[][4]); void VecCopyf(float *v1, float *v2); int VecLen(int *v1, int *v2); @@ -376,10 +374,23 @@ void Vec2Subf(float *v, float *v1, float *v2); void Vec2Copyf(float *v1, float *v2); void Vec2Lerpf(float *target, float *a, float *b, float t); -void AxisAngleToQuat(float *q, float *axis, float angle); -void QuatToAxisAngle(float *q, float *axis, float *angle); +void AxisAngleToQuat(float q[4], float axis[3], float angle); +void QuatToAxisAngle(float q[4], float axis[3], float *angle); +void AxisAngleToEulO(float axis[3], float angle, float eul[3], short order); +void EulOToAxisAngle(float eul[3], short order, float axis[3], float *angle); +void AxisAngleToMat3(float axis[3], float angle, float mat[3][3]); +void AxisAngleToMat4(float axis[3], float angle, float mat[4][4]); +void Mat3ToAxisAngle(float mat[3][3], float axis[3], float *angle); +void Mat4ToAxisAngle(float mat[4][4], float axis[3], float *angle); + +void Mat3ToVecRot(float mat[3][3], float axis[3], float *angle); +void Mat4ToVecRot(float mat[4][4], float axis[3], float *angle); +void VecRotToMat3(float *vec, float phi, float mat[][3]); +void VecRotToMat4(float *vec, float phi, float mat[][4]); + void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]); void vectoquat(float *vec, short axis, short upflag, float *q); +void Mat3ToQuat_is_ok(float wmat[][3], float *q); void VecReflect(float *out, float *v1, float *v2); void VecBisect3(float *v, float *v1, float *v2, float *v3); @@ -460,8 +471,6 @@ void VecStar(float mat[][3],float *vec); short EenheidsMat(float mat[][3]); -void Mat3ToQuat_is_ok(float wmat[][3], float *q); - void i_ortho(float left, float right, float bottom, float top, float nearClip, float farClip, float matrix[][4]); void i_polarview(float dist, float azimuth, float incidence, float twist, float Vm[][4]); void i_translate(float Tx, float Ty, float Tz, float mat[][4]); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 96056ba7783..1839380f953 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -3278,7 +3278,7 @@ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) /* ************ AXIS ANGLE *************** */ /* Axis angle to Quaternions */ -void AxisAngleToQuat(float *q, float *axis, float angle) +void AxisAngleToQuat(float q[4], float axis[3], float angle) { float nor[3]; float si; @@ -3315,6 +3315,90 @@ void QuatToAxisAngle(float q[4], float axis[3], float *angle) axis[2]= q[3] / si; } +/* Axis Angle to Euler Rotation */ +void AxisAngleToEulO(float axis[3], float angle, float eul[3], short order) +{ + float q[4]; + + /* use quaternions as intermediate representation for now... */ + AxisAngleToQuat(q, axis, angle); + QuatToEulO(q, eul, order); +} + +/* Euler Rotation to Axis Angle */ +void EulOToAxisAngle(float eul[3], short order, float axis[3], float *angle) +{ + float q[4]; + + /* use quaternions as intermediate representation for now... */ + EulOToQuat(eul, order, q); + QuatToAxisAngle(q, axis, angle); +} + +/* axis angle to 3x3 matrix - safer version (normalisation of axis performed) */ +void AxisAngleToMat3(float axis[3], float angle, float mat[3][3]) +{ + float nor[3]; + + /* normalise the axis first (to remove unwanted scaling) */ + VecCopyf(nor, axis); + Normalize(nor); + + /* now convert this to a 3x3 matrix */ + VecRotToMat3(nor, angle, mat); +} + +/* axis angle to 4x4 matrix - safer version (normalisation of axis performed) */ +void AxisAngleToMat4(float axis[3], float angle, float mat[4][4]) +{ + float nor[3]; + + /* normalise the axis first (to remove unwanted scaling) */ + VecCopyf(nor, axis); + Normalize(nor); + + /* now convert this to a 4x4 matrix */ + VecRotToMat4(nor, angle, mat); +} + +/* 3x3 matrix to axis angle (alias around the other call) */ +void Mat3ToAxisAngle(float mat[3][3], float axis[3], float *angle) +{ + /* note different order of calling args... */ + Mat3ToVecRot(axis, angle, mat); +} + +/* 4x4 matrix to axis angle (alias around the other call) */ +void Mat4ToAxisAngle(float mat[4][4], float axis[3], float *angle) +{ + /* note different order of calling args... */ + Mat4ToVecRot(axis, angle, mat); +} + +/* ************ AXIS ANGLE (unchecked) *************** */ + +/* 3x3 matrix to axis angle */ +void Mat3ToVecRot(float mat[3][3], float axis[3], float *angle) +{ + float q[4]; + + /* use quaternions as intermediate representation */ + // TODO: it would be nicer to go straight there... + Mat3ToQuat(mat, q); + QuatToAxisAngle(q, axis, angle); +} + +/* 4x4 matrix to axis angle */ +void Mat4ToVecRot(float mat[4][4], float axis[3], float *angle) +{ + float q[4]; + + /* use quaternions as intermediate representation */ + // TODO: it would be nicer to go straight there... + Mat4ToQuat(mat, q); + QuatToAxisAngle(q, axis, angle); +} + /* axis angle to 3x3 matrix */ void VecRotToMat3(float *vec, float phi, float mat[][3]) { @@ -3339,7 +3423,6 @@ void VecRotToMat3(float *vec, float phi, float mat[][3]) mat[2][0]= vz*vx*(1.0f-co)+vy*si; mat[2][1]= vy*vz*(1.0f-co)-vx*si; mat[2][2]= vz2+co*(1.0f-vz2); - } /* axis angle to 4x4 matrix */ @@ -3374,6 +3457,8 @@ void VecRotToQuat(float *vec, float phi, float *quat) } } +/* ************ VECTORS *************** */ + /* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */ void VecBisect3(float *out, float *v1, float *v2, float *v3) { diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 2639d49b5be..60efcce4e73 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -1177,7 +1177,7 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet * /* if this path is exactly "rotation", and the rotation mode is set to eulers, * use "euler_rotation" instead so that rotations will be keyed correctly */ - if (strcmp(ksp->rna_path, "rotation")==0 && (cks->pchan->rotmode)) + if (strcmp(ksp->rna_path, "rotation")==0 && (cks->pchan->rotmode > 0)) BLI_dynstr_append(pathds, "euler_rotation"); else BLI_dynstr_append(pathds, ksp->rna_path); diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 3b6c9e9d13d..e2293b65878 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4865,6 +4865,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) eul[0]= eul[1]= eul[2]= 0.0f; + // TODO: for 4 channel rotations, we need special flags for those too... if (pchan->protectflag & OB_LOCK_ROTX) eul[0]= oldeul[0]; if (pchan->protectflag & OB_LOCK_ROTY) diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 9a404e24e12..b473b9ee226 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1009,12 +1009,25 @@ static int pose_paste_exec (bContext *C, wmOperator *op) } } else if (pchan->rotmode > 0) { - /* quat to euler */ - QuatToEulO(chan->quat, pchan->eul, pchan->rotmode); + /* quat/axis-angle to euler */ + if (chan->rotmode == PCHAN_ROT_AXISANGLE) + AxisAngleToEulO(&chan->quat[1], chan->quat[0], pchan->eul, pchan->rotmode); + else + QuatToEulO(chan->quat, pchan->eul, pchan->rotmode); + } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + /* quat/euler to axis angle */ + if (chan->rotmode > 0) + EulOToAxisAngle(chan->eul, chan->rotmode, &pchan->quat[1], &pchan->quat[0]); + else + QuatToAxisAngle(chan->quat, &pchan->quat[1], &pchan->quat[0]); } else { - /* euler to quat */ - EulOToQuat(chan->eul, chan->rotmode, pchan->quat); + /* euler/axis-angle to quat */ + if (chan->rotmode > 0) + EulOToQuat(chan->eul, chan->rotmode, pchan->quat); + else + AxisAngleToQuat(pchan->quat, &chan->quat[1], chan->quat[0]); } /* paste flipped pose? */ @@ -1026,6 +1039,14 @@ static int pose_paste_exec (bContext *C, wmOperator *op) pchan->eul[1] *= -1; pchan->eul[2] *= -1; } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + float eul[3]; + + AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], eul, EULER_ORDER_DEFAULT); + eul[1]*= -1; + eul[2]*= -1; + EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]); + } else { float eul[3]; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6405e87c4c0..467f5c59e3d 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1614,7 +1614,8 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu { /* quaternions get limited with euler... */ /* this function only does the delta rotation */ - + + // FIXME: need special checks for quality here... if(protectflag) { float eul[3], oldeul[3], quat1[4]; @@ -2686,12 +2687,13 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short QuatMul(td->ext->quat, quat, iquat); - /* this function works on end result */ - protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); - /* make temp copy (since stored in same place) */ - QuatCopy(quat, td->ext->quat); + QuatCopy(quat, td->ext->quat); // this is just a 4d vector copying function QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); + + /* this function works on end result */ + // TODO: we really need a specialised version of this for axis-angle that doesn't try to do quats... + protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } else { float eulmat[3][3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e0d058f160f..6386c0d4eb7 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -509,6 +509,8 @@ static short apply_targetless_ik(Object *ob) /* rotation */ if (parchan->rotmode > 0) Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode); + else if (parchan->rotmode == PCHAN_ROT_AXISANGLE) + Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]); else Mat3ToQuat(rmat3, parchan->quat); @@ -517,6 +519,8 @@ static short apply_targetless_ik(Object *ob) if (data->flag & CONSTRAINT_IK_STRETCH) { if (parchan->rotmode > 0) EulOToMat3(parchan->eul, parchan->rotmode, qrmat); + else if (parchan->rotmode == PCHAN_ROT_AXISANGLE) + AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat); else QuatToMat3(parchan->quat, qrmat); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 0a88b084307..d143c94ebb1 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -115,14 +115,9 @@ static void rna_PoseChannel_euler_rotation_get(PointerRNA *ptr, float *value) { bPoseChannel *pchan= ptr->data; - if(pchan->rotmode == PCHAN_ROT_AXISANGLE) { - float m[3][3]; - - /* go through a 3x3 matrix */ - VecRotToMat3(&pchan->quat[1], pchan->quat[0], m); - Mat3ToEul(m, value); - } - else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers when using axis-angle... */ + if(pchan->rotmode == PCHAN_ROT_AXISANGLE) /* default XYZ eulers */ + AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], value, EULER_ORDER_DEFAULT); + else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers */ QuatToEul(pchan->quat, value); else VECCOPY(value, pchan->eul); @@ -133,14 +128,9 @@ static void rna_PoseChannel_euler_rotation_set(PointerRNA *ptr, const float *val { bPoseChannel *pchan= ptr->data; - if(pchan->rotmode == PCHAN_ROT_AXISANGLE) { /* default XYZ eulers when using axis-angle... */ - float q[4]; - - /* convert to temp quat, then to axis angle (since stored in same var) */ - EulToQuat((float *)value, q); - QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); - } - else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers when using quats... */ + if(pchan->rotmode == PCHAN_ROT_AXISANGLE) /* default XYZ eulers */ + EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]); + else if(pchan->rotmode == PCHAN_ROT_QUAT) /* default XYZ eulers */ EulToQuat((float*)value, pchan->quat); else VECCOPY(pchan->eul, value); @@ -177,13 +167,7 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) if (value > 0) { /* to euler */ if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { /* axis-angle to euler */ - float m[3][3]; - - /* convert to 3x3 matrix, then to euler - * - axis angle is stored in quats - */ - VecRotToMat3(&pchan->quat[1], pchan->quat[0], m); - Mat3ToEulO(m, pchan->eul, value); + AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], pchan->eul, value); } else if (pchan->rotmode == PCHAN_ROT_QUAT) { /* quat to euler */ @@ -209,11 +193,7 @@ static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) else { /* to axis-angle */ if (pchan->rotmode > 0) { /* euler to axis angle */ - float q[4]; - - /* convert to temp quat, then to axis angle (since stored in same var) */ - EulOToQuat(pchan->eul, pchan->rotmode, q); - QuatToAxisAngle(q, &pchan->quat[1], &pchan->quat[0]); + EulOToAxisAngle(pchan->eul, pchan->rotmode, &pchan->quat[1], &pchan->quat[0]); } else if (pchan->rotmode == PCHAN_ROT_QUAT) { /* quat to axis angle */ -- cgit v1.2.3 From 3a9d99e3e86a44ee7c9abf144c7b03fe246adc37 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 12 Sep 2009 10:21:55 +0000 Subject: Rotation Math: Replaced a few function calls with inlined code for nicer performance. --- source/blender/blenlib/intern/arithb.c | 52 ++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 1839380f953..dc7f908123f 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -3338,44 +3338,66 @@ void EulOToAxisAngle(float eul[3], short order, float axis[3], float *angle) /* axis angle to 3x3 matrix - safer version (normalisation of axis performed) */ void AxisAngleToMat3(float axis[3], float angle, float mat[3][3]) { - float nor[3]; + float nor[3], nsi[3], co, si, ico; /* normalise the axis first (to remove unwanted scaling) */ VecCopyf(nor, axis); Normalize(nor); /* now convert this to a 3x3 matrix */ - VecRotToMat3(nor, angle, mat); + co= (float)cos(angle); + si= (float)sin(angle); + + ico= (1.0f - co); + nsi[0]= nor[0]*si; + nsi[1]= nor[1]*si; + nsi[2]= nor[2]*si; + + mat[0][0] = ((nor[0] * nor[0]) * ico) + co; + mat[0][1] = ((nor[0] * nor[1]) * ico) + nsi[2]; + mat[0][2] = ((nor[0] * nor[2]) * ico) - nsi[1]; + mat[1][0] = ((nor[0] * nor[1]) * ico) - nsi[2]; + mat[1][1] = ((nor[1] * nor[1]) * ico) + co; + mat[1][2] = ((nor[1] * nor[2]) * ico) + nsi[0]; + mat[2][0] = ((nor[0] * nor[2]) * ico) + nsi[1]; + mat[2][1] = ((nor[1] * nor[2]) * ico) - nsi[0]; + mat[2][2] = ((nor[2] * nor[2]) * ico) + co; } /* axis angle to 4x4 matrix - safer version (normalisation of axis performed) */ void AxisAngleToMat4(float axis[3], float angle, float mat[4][4]) { - float nor[3]; - - /* normalise the axis first (to remove unwanted scaling) */ - VecCopyf(nor, axis); - Normalize(nor); + float tmat[3][3]; - /* now convert this to a 4x4 matrix */ - VecRotToMat4(nor, angle, mat); + AxisAngleToMat3(axis, angle, mat); + Mat4One(mat); + Mat4CpyMat3(mat, tmat); } -/* 3x3 matrix to axis angle (alias around the other call) */ +/* 3x3 matrix to axis angle (see Mat4ToVecRot too) */ void Mat3ToAxisAngle(float mat[3][3], float axis[3], float *angle) { - /* note different order of calling args... */ - Mat3ToVecRot(axis, angle, mat); + float q[4]; + + /* use quaternions as intermediate representation */ + // TODO: it would be nicer to go straight there... + Mat3ToQuat(mat, q); + QuatToAxisAngle(q, axis, angle); } -/* 4x4 matrix to axis angle (alias around the other call) */ +/* 4x4 matrix to axis angle (see Mat4ToVecRot too) */ void Mat4ToAxisAngle(float mat[4][4], float axis[3], float *angle) { - /* note different order of calling args... */ - Mat4ToVecRot(axis, angle, mat); + float q[4]; + + /* use quaternions as intermediate representation */ + // TODO: it would be nicer to go straight there... + Mat4ToQuat(mat, q); + QuatToAxisAngle(q, axis, angle); } /* ************ AXIS ANGLE (unchecked) *************** */ +// TODO: the following calls should probably be depreceated sometime /* 3x3 matrix to axis angle */ void Mat3ToVecRot(float mat[3][3], float axis[3], float *angle) -- cgit v1.2.3 From ad43aaf881652a10a47a850277bfe3d376a82433 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 12 Sep 2009 12:30:23 +0000 Subject: 2.5 - Rotation Locking for Bones * Added Transform Locks panel. The layout for rotation I'm not satisfied with yet, though it is the best alternative so far. * Rotations can now be locked per-component for quats/axis-angle instead of going through eulers. This is currently enabled by the checkbox for the 'label' of the Lock Rotation column. - The naming of the property in RNA + the way this is presented in the UI can get some work done. - The setting for the 'w' component for quats/axis-angle is currently a separate flag in RNA, since I can't figure out how to lump this in under the 'lock_rotation' property instead (i.e. getting that to be either 3 or 4 components, depending on whether per-component locking is enabled). - Editing values directly should not be possible when these locks are set... * Fixed some tools which made use of this --- release/ui/buttons_data_bone.py | 30 ++++++ source/blender/editors/armature/editarmature.c | 80 +++++++++------- source/blender/editors/armature/poseobject.c | 1 - source/blender/editors/transform/transform.c | 123 +++++++++++++++++++------ source/blender/makesdna/DNA_object_types.h | 2 + source/blender/makesrna/intern/rna_pose.c | 17 ++-- 6 files changed, 186 insertions(+), 67 deletions(-) diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index 5aac44bbc94..a0121821e55 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -71,6 +71,35 @@ class BONE_PT_transform(BoneButtonsPanel): col = layout.column(align=True) col.itemL(text="Euler:") col.row().itemR(pchan, "euler_rotation", text="") + +class BONE_PT_transform_locks(BoneButtonsPanel): + __label__ = "Transform Locks" + + def poll(self, context): + return context.bone + + def draw(self, context): + layout = self.layout + + ob = context.object + bone = context.bone + pchan = ob.pose.pose_channels[context.bone.name] + + row = layout.row() + col = row.column() + col.itemR(pchan, "lock_location") + col.active = not (bone.parent and bone.connected) + + col = row.column() + if pchan.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'): + col.itemR(pchan, "lock_rotations_4d", text="Lock Rotation") + if pchan.lock_rotations_4d: + col.itemR(pchan, "lock_rotation_w", text="W") + col.itemR(pchan, "lock_rotation", text="") + else: + col.itemR(pchan, "lock_rotation", text="Rotation") + + row.column().itemR(pchan, "lock_scale") class BONE_PT_bone(BoneButtonsPanel): __label__ = "Bone" @@ -243,6 +272,7 @@ class BONE_PT_deform(BoneButtonsPanel): bpy.types.register(BONE_PT_context_bone) bpy.types.register(BONE_PT_transform) +bpy.types.register(BONE_PT_transform_locks) bpy.types.register(BONE_PT_bone) bpy.types.register(BONE_PT_deform) bpy.types.register(BONE_PT_inverse_kinematics) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index e2293b65878..7d196d23c98 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4849,42 +4849,56 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) /* only clear those channels that are not locked */ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) { - if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ)) { - float eul[3], oldeul[3], quat1[4]; - - if (pchan->rotmode == PCHAN_ROT_QUAT) { - QUATCOPY(quat1, pchan->quat); - QuatToEul(pchan->quat, oldeul); - } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { - continue; // XXX + if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) { + /* check if convert to eulers for locking... */ + if (pchan->protectflag & OB_LOCK_ROT4D) { + /* perform clamping on a component by component basis */ + if ((pchan->protectflag & OB_LOCK_ROTW) == 0) + pchan->quat[0]= (pchan->rotmode == PCHAN_ROT_AXISANGLE) ? 0.0f : 1.0f; + if ((pchan->protectflag & OB_LOCK_ROTX) == 0) + pchan->quat[1]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTY) == 0) + pchan->quat[2]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) + pchan->quat[3]= 0.0f; } else { - VECCOPY(oldeul, pchan->eul); - } - - eul[0]= eul[1]= eul[2]= 0.0f; - - // TODO: for 4 channel rotations, we need special flags for those too... - if (pchan->protectflag & OB_LOCK_ROTX) - eul[0]= oldeul[0]; - if (pchan->protectflag & OB_LOCK_ROTY) - eul[1]= oldeul[1]; - if (pchan->protectflag & OB_LOCK_ROTZ) - eul[2]= oldeul[2]; - - if (pchan->rotmode == PCHAN_ROT_QUAT) { - EulToQuat(eul, pchan->quat); - /* quaternions flip w sign to accumulate rotations correctly */ - if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) { - QuatMulf(pchan->quat, -1.0f); + /* perform clamping using euler form (3-components) */ + float eul[3], oldeul[3], quat1[4]; + + if (pchan->rotmode == PCHAN_ROT_QUAT) { + QUATCOPY(quat1, pchan->quat); + QuatToEul(pchan->quat, oldeul); + } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT); + } + else { + VECCOPY(oldeul, pchan->eul); + } + + eul[0]= eul[1]= eul[2]= 0.0f; + + if (pchan->protectflag & OB_LOCK_ROTX) + eul[0]= oldeul[0]; + if (pchan->protectflag & OB_LOCK_ROTY) + eul[1]= oldeul[1]; + if (pchan->protectflag & OB_LOCK_ROTZ) + eul[2]= oldeul[2]; + + if (pchan->rotmode == PCHAN_ROT_QUAT) { + EulToQuat(eul, pchan->quat); + /* quaternions flip w sign to accumulate rotations correctly */ + if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) { + QuatMulf(pchan->quat, -1.0f); + } + } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT); + } + else { + VECCOPY(pchan->eul, eul); } - } - else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { - // TODO... - } - else { - VECCOPY(pchan->eul, eul); } } else { diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index b473b9ee226..7d7f54309a8 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -998,7 +998,6 @@ static int pose_paste_exec (bContext *C, wmOperator *op) pchan->flag= chan->flag; /* check if rotation modes are compatible (i.e. do they need any conversions) */ - // FIXME: add axis-angle here too... if (pchan->rotmode == chan->rotmode) { /* copy the type of rotation in use */ if (pchan->rotmode > 0) { diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 467f5c59e3d..e877f1fecae 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1610,29 +1610,88 @@ static void protectedRotateBits(short protectflag, float *eul, float *oldeul) eul[2]= oldeul[2]; } -static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat) + +/* this function only does the delta rotation */ +/* axis-angle is usually internally stored as quats... */ +static void protectedAxisAngleBits(short protectflag, float *quat, float *oldquat) { - /* quaternions get limited with euler... */ - /* this function only does the delta rotation */ + /* check that protection flags are set */ + if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0) + return; - // FIXME: need special checks for quality here... - if(protectflag) { + if (protectflag & OB_LOCK_ROT4D) { + /* axis-angle getting limited as 4D entities that they are... */ + if (protectflag & OB_LOCK_ROTW) + quat[0]= oldquat[0]; + if (protectflag & OB_LOCK_ROTX) + quat[1]= oldquat[1]; + if (protectflag & OB_LOCK_ROTY) + quat[2]= oldquat[2]; + if (protectflag & OB_LOCK_ROTZ) + quat[3]= oldquat[3]; + } + else { + /* axis-angle get limited with euler... */ float eul[3], oldeul[3], quat1[4]; + + QUATCOPY(quat1, quat); + AxisAngleToEulO(quat+1, quat[0], eul, EULER_ORDER_DEFAULT); + AxisAngleToEulO(oldquat+1, oldquat[0], oldeul, EULER_ORDER_DEFAULT); + + if (protectflag & OB_LOCK_ROTX) + eul[0]= oldeul[0]; + if (protectflag & OB_LOCK_ROTY) + eul[1]= oldeul[1]; + if (protectflag & OB_LOCK_ROTZ) + eul[2]= oldeul[2]; + + EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, quat+1, quat); + + /* when converting to axis-angle, we need a special exception for the case when there is no axis */ + if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) { + /* for now, rotate around y-axis then (so that it simply becomes the roll) */ + quat[2]= 1.0f; + } + } +} +/* this function only does the delta rotation */ +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) + return; + + if (protectflag & OB_LOCK_ROT4D) { + /* quaternions getting limited as 4D entities that they are... */ + if (protectflag & OB_LOCK_ROTW) + quat[0]= oldquat[0]; + if (protectflag & OB_LOCK_ROTX) + quat[1]= oldquat[1]; + if (protectflag & OB_LOCK_ROTY) + quat[2]= oldquat[2]; + if (protectflag & OB_LOCK_ROTZ) + quat[3]= oldquat[3]; + } + else { + /* quaternions get limited with euler... (compatability mode) */ + float eul[3], oldeul[3], quat1[4]; + QUATCOPY(quat1, quat); QuatToEul(quat, eul); QuatToEul(oldquat, oldeul); - - if(protectflag & OB_LOCK_ROTX) + + if (protectflag & OB_LOCK_ROTX) eul[0]= oldeul[0]; - if(protectflag & OB_LOCK_ROTY) + if (protectflag & OB_LOCK_ROTY) eul[1]= oldeul[1]; - if(protectflag & OB_LOCK_ROTZ) + if (protectflag & OB_LOCK_ROTZ) eul[2]= oldeul[2]; - + EulToQuat(eul, quat); + /* quaternions flip w sign to accumulate rotations correctly */ - if( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) { + if ( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) { QuatMulf(quat, -1.0f); } } @@ -1733,17 +1792,24 @@ static void constraintRotLim(TransInfo *t, TransData *td) else return; } - else if (td->tdi) { + else if (td->tdi) { // XXX depreceated /* ipo-keys eulers */ TransDataIpokey *tdi= td->tdi; float eul[3]; - + eul[0]= tdi->rotx[0]; eul[1]= tdi->roty[0]; eul[2]= tdi->rotz[0]; - + EulOToMat4(eul, td->rotOrder, cob.matrix); } + else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + /* axis angle */ + if (td->ext) + AxisAngleToMat4(&td->ext->quat[1], td->ext->quat[0], cob.matrix); + else + return; + } else { /* eulers */ if (td->ext) @@ -1751,22 +1817,22 @@ static void constraintRotLim(TransInfo *t, TransData *td) else return; } - + /* Evaluate valid constraints */ 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; float tmat[4][4]; - + /* only use it if it's tagged for this purpose */ if ((data->flag2 & LIMIT_TRANSFORM)==0) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1777,10 +1843,10 @@ static void constraintRotLim(TransInfo *t, TransData *td) /* skip... incompatable spacetype */ continue; } - + /* do constraint */ cti->evaluate_constraint(con, &cob, NULL); - + /* convert spaces again */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1789,7 +1855,7 @@ static void constraintRotLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ if (td->flag & TD_USEQUAT) { /* quats */ @@ -1799,13 +1865,17 @@ static void constraintRotLim(TransInfo *t, TransData *td) /* ipo-keys eulers */ TransDataIpokey *tdi= td->tdi; float eul[3]; - + Mat4ToEulO(cob.matrix, eul, td->rotOrder); - + tdi->rotx[0]= eul[0]; tdi->roty[0]= eul[1]; tdi->rotz[0]= eul[2]; } + else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + /* axis angle */ + Mat4ToAxisAngle(cob.matrix, &td->ext->quat[1], &td->ext->quat[0]); + } else { /* eulers */ Mat4ToEulO(cob.matrix, td->ext->rot, td->rotOrder); @@ -2688,12 +2758,11 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short QuatMul(td->ext->quat, quat, iquat); /* make temp copy (since stored in same place) */ - QuatCopy(quat, td->ext->quat); // this is just a 4d vector copying function + QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); /* this function works on end result */ - // TODO: we really need a specialised version of this for axis-angle that doesn't try to do quats... - protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); + protectedAxisAngleBits(td->protectflag, td->ext->quat, td->ext->iquat); } else { float eulmat[3][3]; @@ -2714,7 +2783,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short protectedRotateBits(td->protectflag, eul, td->ext->irot); VECCOPY(td->ext->rot, eul); } - + constraintRotLim(t, td); } } diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index d1e70c16408..a89f8e1fb2e 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -515,6 +515,8 @@ extern Object workob; #define OB_LOCK_SCALEY 128 #define OB_LOCK_SCALEZ 256 #define OB_LOCK_SCALE 448 +#define OB_LOCK_ROTW 512 +#define OB_LOCK_ROT4D 1024 /* ob->mode */ typedef enum ObjectMode { diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index d143c94ebb1..3a03e7a624d 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -698,14 +698,19 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation (with three components) in the interface."); + RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface."); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); - //prop= RNA_def_property(srna, "lock_rotation_4d", PROP_BOOLEAN, PROP_XYZ); - //RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTW); - //RNA_def_property_array(prop, 4); - //RNA_def_property_ui_text(prop, "Lock Rotation (4D)", "Lock editing of rotations (with four components) in the interface."); - //RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); + // XXX this is sub-optimal - it really should be included above, but due to technical reasons we can't do this! + prop= RNA_def_property(srna, "lock_rotation_w", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTW); + RNA_def_property_ui_text(prop, "Lock Rotation (4D Angle)", "Lock editing of 'angle' component of four-component rotations in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); + // XXX this needs a better name + prop= RNA_def_property(srna, "lock_rotations_4d", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROT4D); + RNA_def_property_ui_text(prop, "Lock Rotations (4D)", "Lock editing of four component rotations by components (instead of as Eulers)."); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); prop= RNA_def_property(srna, "lock_scale", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_SCALEX); -- cgit v1.2.3 From 0bc8fd08e79d18507851714a15a18dc1054a4e3a Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sat, 12 Sep 2009 12:34:33 +0000 Subject: Blender 2.5 MSVC 9 projectfiles * maintenance: ** nodes/intern/CMP_nodes/CMP_colorMatte.c ** nodes/intern/CMP_nodes/CMP_distanceMatte.c ** nodes/intern/CMP_nodes/CMP_levels.c * smoke include dir added to GL_gpu library --- projectfiles_vc9/blender/gpu/BL_gpu.vcproj | 12 ++++++------ projectfiles_vc9/blender/nodes/nodes.vcproj | 12 ++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj index eb404e27f24..1daf345f638 100644 --- a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj +++ b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj @@ -43,7 +43,7 @@ + + @@ -384,6 +388,10 @@ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_displace.c" > + + @@ -420,6 +428,10 @@ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_lensdist.c" > + + -- cgit v1.2.3 From 2ca79ec1def97a24e64722613edc6fb5fb714314 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 12 Sep 2009 12:54:43 +0000 Subject: 2.5 Notifier: * Added a general Refresh Tag for the Property-Buttons area, needed if more than 1 property window with the same content is open. Not all RNA properties have a ND_ Notifier yet, so i guess this is the best solution for now. --- source/blender/editors/space_buttons/space_buttons.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 385f55b71c1..d4ad77daca7 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -319,6 +319,9 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) /* context changes */ switch(wmn->category) { case NC_SCENE: + /* lazy general redraw tag here, in case more than 1 propertie window is opened + Not all RNA props have a ND_sub notifier(yet) */ + ED_area_tag_redraw(sa); switch(wmn->data) { case ND_FRAME: case ND_MODE: @@ -333,10 +336,14 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) } break; case NC_OBJECT: + ED_area_tag_redraw(sa); + /* lazy general redraw tag here, in case more than 1 propertie window is opened + Not all RNA props have a ND_ notifier(yet) */ switch(wmn->data) { case ND_TRANSFORM: case ND_BONE_ACTIVE: case ND_BONE_SELECT: + case ND_MODIFIER: case ND_CONSTRAINT: ED_area_tag_redraw(sa); break; @@ -356,7 +363,6 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) break; case NC_MATERIAL: ED_area_tag_redraw(sa); - switch(wmn->data) { case ND_SHADING: case ND_SHADING_DRAW: -- cgit v1.2.3 -- cgit v1.2.3 From e271b033400c89d6f218a30043737b11785309c4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 13:25:38 +0000 Subject: simple error in recent arithb.c commit, have Mathutils.RotationMatrix use AxisAngleToMat3 --- source/blender/blenlib/intern/arithb.c | 2 +- source/blender/python/generic/Mathutils.c | 38 +++---------------------------- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index dc7f908123f..f0dba4255ad 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -3369,7 +3369,7 @@ void AxisAngleToMat4(float axis[3], float angle, float mat[4][4]) { float tmat[3][3]; - AxisAngleToMat3(axis, angle, mat); + AxisAngleToMat3(axis, angle, tmat); Mat4One(mat); Mat4CpyMat3(mat, tmat); } diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index f53fd66ba99..32262276d0a 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -353,7 +353,7 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) VectorObject *vec = NULL; char *axis = NULL; int matSize; - float angle = 0.0f, norm = 0.0f, cosAngle = 0.0f, sinAngle = 0.0f; + float angle = 0.0f; float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; @@ -437,40 +437,8 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) mat[8] = 1.0f; } else if((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) { //arbitrary rotation - //normalize arbitrary axis - norm = (float) sqrt(vec->vec[0] * vec->vec[0] + - vec->vec[1] * vec->vec[1] + - vec->vec[2] * vec->vec[2]); - vec->vec[0] /= norm; - vec->vec[1] /= norm; - vec->vec[2] /= norm; - - if (isnan(vec->vec[0]) || isnan(vec->vec[1]) || isnan(vec->vec[2])) { - /* zero length vector, return an identity matrix, could also return an error */ - mat[0]= mat[4] = mat[8] = 1.0f; - } else { - /* create matrix */ - cosAngle = (float) cos(angle); - sinAngle = (float) sin(angle); - mat[0] = ((vec->vec[0] * vec->vec[0]) * (1 - cosAngle)) + - cosAngle; - mat[1] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) + - (vec->vec[2] * sinAngle); - mat[2] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) - - (vec->vec[1] * sinAngle); - mat[3] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) - - (vec->vec[2] * sinAngle); - mat[4] = ((vec->vec[1] * vec->vec[1]) * (1 - cosAngle)) + - cosAngle; - mat[5] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) + - (vec->vec[0] * sinAngle); - mat[6] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) + - (vec->vec[1] * sinAngle); - mat[7] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) - - (vec->vec[0] * sinAngle); - mat[8] = ((vec->vec[2] * vec->vec[2]) * (1 - cosAngle)) + - cosAngle; - } + AxisAngleToMat3(vec->vec, angle, (float *)mat); + } else { PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n"); return NULL; -- cgit v1.2.3 From 3f9d3b2a0b61fee0b51b3b867033b5488c17cc35 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sat, 12 Sep 2009 13:27:26 +0000 Subject: commit of mempool 64-bit fix for 2.5-er, trunk as well --- source/blender/blenlib/intern/BLI_mempool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 7ac7b8b1791..485ba7cbd08 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -56,7 +56,10 @@ BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk) BLI_freenode *lasttail = NULL, *curnode = NULL; int i,j, maxchunks; char *addr; - + + if (esize < sizeof(void*)) + esize = sizeof(void*); + /*allocate the pool structure*/ pool = MEM_mallocN(sizeof(BLI_mempool),"memory pool"); pool->esize = esize; -- cgit v1.2.3 From d16bde417fb985eb348cdbf2314e324fa9d098a9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 14:12:37 +0000 Subject: new struct PathPoint for each path element (replaces float[4]), Paths now store radius and quaternion Added optional quat and radius args to anim.c's where_on_path(...), currently unused. also cleanup some warnings. --- source/blender/blenkernel/BKE_anim.h | 2 +- source/blender/blenkernel/intern/anim.c | 64 +++++++++++++++------- source/blender/blenkernel/intern/constraint.c | 8 +-- source/blender/blenkernel/intern/font.c | 4 +- source/blender/blenkernel/intern/lattice.c | 14 +++-- source/blender/blenkernel/intern/object.c | 4 +- source/blender/blenkernel/intern/particle.c | 5 +- source/blender/blenkernel/intern/particle_system.c | 2 +- source/blender/blenkernel/intern/smoke.c | 1 + source/blender/blenlib/BLI_arithb.h | 2 +- source/blender/blenlib/intern/arithb.c | 16 +++--- source/blender/editors/space_view3d/drawobject.c | 4 +- source/blender/makesdna/DNA_curve_types.h | 11 +++- 13 files changed, 88 insertions(+), 49 deletions(-) diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 5ea511738ad..4b1e758da54 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -51,7 +51,7 @@ typedef struct DupliObject { void free_path(struct Path *path); void calc_curvepath(struct Object *ob); int interval_test(int min, int max, int p1, int cycl); -int where_on_path(struct Object *ob, float ctime, float *vec, float *dir); +int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius); struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob); void free_object_duplilist(struct ListBase *lb); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 4b1cc36edeb..8cb88cdb786 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -87,15 +87,16 @@ void free_path(Path *path) void calc_curvepath(Object *ob) { BevList *bl; - BevPoint *bevp, *bevpn, *bevpfirst, *bevplast, *tempbevp; + BevPoint *bevp, *bevpn, *bevpfirst, *bevplast; + PathPoint *pp; Curve *cu; Nurb *nu; Path *path; float *fp, *dist, *maxdist, xyz[3]; float fac, d=0, fac1, fac2; int a, tot, cycl=0; - float *ft; + /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ @@ -145,7 +146,7 @@ void calc_curvepath(Object *ob) /* the path verts in path->data */ /* now also with TILT value */ - ft= path->data = (float *)MEM_callocN(16*path->len, "pathdata"); + pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell bevp= bevpfirst; bevpn= bevp+1; @@ -175,10 +176,13 @@ void calc_curvepath(Object *ob) fac1= fac2/fac1; fac2= 1.0f-fac1; - VecLerpf(ft, bevp->vec, bevpn->vec, fac2); - ft[3]= fac1*bevp->alfa+ fac2*(bevpn)->alfa; + VecLerpf(pp->vec, bevp->vec, bevpn->vec, fac2); + pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa; + pp->radius= fac1*bevp->radius + fac2*bevpn->radius; + QuatInterpol(pp->quat, bevp->quat, bevpn->quat, fac2); + NormalQuat(pp->quat); - ft+= 4; + pp++; } MEM_freeN(dist); @@ -202,13 +206,14 @@ int interval_test(int min, int max, int p1, int cycl) /* warning, *vec needs FOUR items! */ /* ctime is normalized range <0-1> */ -int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK */ +int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */ { Curve *cu; Nurb *nu; BevList *bl; Path *path; - float *fp, *p0, *p1, *p2, *p3, fac; + PathPoint *pp, *p0, *p1, *p2, *p3; + float fac; float data[4]; int cycl=0, s0, s1, s2, s3; @@ -219,7 +224,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK return 0; } path= cu->path; - fp= path->data; + pp= path->data; /* test for cyclic */ bl= cu->bev.first; @@ -238,19 +243,19 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK s2= interval_test(0, path->len-1-cycl, s1+1, cycl); s3= interval_test(0, path->len-1-cycl, s1+2, cycl); - p0= fp + 4*s0; - p1= fp + 4*s1; - p2= fp + 4*s2; - p3= fp + 4*s3; + p0= pp + s0; + p1= pp + s1; + p2= pp + s2; + p3= pp + s3; /* note, commented out for follow constraint */ //if(cu->flag & CU_FOLLOW) { key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE); - dir[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ; - dir[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ; - dir[2]= data[0]*p0[2] + data[1]*p1[2] + data[2]*p2[2] + data[3]*p3[2] ; + dir[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; + dir[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; + dir[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* make compatible with vectoquat */ dir[0]= -dir[0]; @@ -266,11 +271,30 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK else if(s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL); else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE); - vec[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ; - vec[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ; - vec[2]= data[0]*p0[2] + data[1]*p1[2] + data[2]*p2[2] + data[3]*p3[2] ; + vec[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; /* X */ + vec[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; /* Y */ + vec[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* Z */ + vec[3]= data[0]*p0->vec[3] + data[1]*p1->vec[3] + data[2]*p2->vec[3] + data[3]*p3->vec[3] ; /* Tilt, should not be needed since we have quat still used */ + /* Need to verify the quat interpolation is correct - XXX */ + + if (quat) { + float totfac, q1[4], q2[4]; + + totfac= data[0]+data[1]; + QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac); + NormalQuat(q1); + + totfac= data[2]+data[3]; + QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac); + NormalQuat(q2); + + totfac = data[0]+data[1]+data[2]+data[3]; + QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac); + NormalQuat(quat); + } - vec[3]= data[0]*p0[3] + data[1]*p1[3] + data[2]*p2[3] + data[3]*p3[3] ; + if(radius) + *radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius; return 1; } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index dfbcc51a93c..6ab9f5844b1 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1174,7 +1174,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr */ /* only happens on reload file, but violates depsgraph still... fix! */ - if (cu->path==NULL || cu->path->data==NULL) + if (cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(cob->scene, ct->tar, 0); if (cu->path && cu->path->data) { @@ -1196,7 +1196,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr curvetime= data->offset; // XXX might need a more sensible value } - if ( where_on_path(ct->tar, curvetime, vec, dir) ) { + if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) { if (data->followflag & FOLLOWPATH_FOLLOW) { vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat); @@ -2864,7 +2864,7 @@ static void clampto_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain */ /* only happens on reload file, but violates depsgraph still... fix! */ - if (cu->path==NULL || cu->path->data==NULL) + if (cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(cob->scene, ct->tar, 0); } @@ -2975,7 +2975,7 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta } /* 3. position on curve */ - if (where_on_path(ct->tar, curvetime, vec, dir) ) { + if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) { Mat4One(totmat); VECCOPY(totmat[3], vec); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 5ce021e3931..411b2448dea 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -1039,8 +1039,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode) /* calc the right loc AND the right rot separately */ /* vec, tvec need 4 items */ - where_on_path(cu->textoncurve, ctime, vec, tvec); - where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec); + where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL); + where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL); VecMulf(vec, sizefac); diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 801511de532..e2c2723d036 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -472,7 +472,7 @@ static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc } /* this makes sure we can extend for non-cyclic. *vec needs 4 items! */ -static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir) /* returns OK */ +static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */ { Curve *cu= ob->data; BevList *bl; @@ -490,21 +490,25 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir) else ctime1= ctime; /* vec needs 4 items */ - if(where_on_path(ob, ctime1, vec, dir)) { + if(where_on_path(ob, ctime1, vec, dir, quat, radius)) { if(cycl==0) { Path *path= cu->path; float dvec[3]; if(ctime < 0.0) { - VecSubf(dvec, path->data+4, path->data); + VecSubf(dvec, path->data[1].vec, path->data[0].vec); VecMulf(dvec, ctime*(float)path->len); VECADD(vec, vec, dvec); + if(quat) QUATCOPY(quat, path->data[0].quat); + if(radius) *radius= path->data[0].radius; } else if(ctime > 1.0) { - VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8); + VecSubf(dvec, path->data[path->len-1].vec, path->data[path->len-2].vec); VecMulf(dvec, (ctime-1.0)*(float)path->len); VECADD(vec, vec, dvec); + if(quat) QUATCOPY(quat, path->data[path->len-1].quat); + if(radius) *radius= path->data[path->len-1].radius; } } return 1; @@ -575,7 +579,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C } #endif // XXX old animation system - if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */ + if( where_on_path_deform(par, fac, loc, dir, NULL, NULL)) { /* returns OK */ float q[4], mat[3][3], quat[4]; if(cd->no_rot_axis) /* set by caller */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a0004aaae49..f04512cffc9 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1114,7 +1114,7 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) } if(psys->clmd) { - ClothModifierData *nclmd = modifier_new(eModifierType_Cloth); + ClothModifierData *nclmd = (ClothModifierData *)modifier_new(eModifierType_Cloth); modifier_copyData((ModifierData*)psys->clmd, (ModifierData*)nclmd); psys->hair_in_dm = psys->hair_out_dm = NULL; } @@ -1694,7 +1694,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) /* vec: 4 items! */ - if( where_on_path(par, ctime, vec, dir) ) { + if( where_on_path(par, ctime, vec, dir, NULL, NULL) ) { if(cu->flag & CU_FOLLOW) { vectoquat(dir, ob->trackflag, ob->upflag, quat); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 964201ccb26..404203c4508 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -60,6 +60,7 @@ #include "BKE_anim.h" #include "BKE_boids.h" +#include "BKE_cloth.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_lattice.h" @@ -1974,9 +1975,9 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase } if(pd->flag & PFIELD_GUIDE_PATH_ADD) - where_on_path(eob, f_force*guidetime, guidevec, guidedir); + where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, NULL); else - where_on_path(eob, guidetime, guidevec, guidedir); + where_on_path(eob, guidetime, guidevec, guidedir, NULL, NULL); Mat4MulVecfl(ec->ob->obmat,guidevec); Mat4Mul3Vecfl(ec->ob->obmat,guidedir); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 88b85bcfa29..3796e3e0ba5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2536,7 +2536,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa && part->phystype!=PART_PHYS_BOIDS) { float vec[4]; - where_on_path(ec->ob, 0.0, vec, vec2); + where_on_path(ec->ob, 0.0, vec, vec2, NULL, NULL); Mat4MulVecfl(ec->ob->obmat,vec); Mat4Mul3Vecfl(ec->ob->obmat,vec2); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index fe5541211ce..af79fd74ae8 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -38,6 +38,7 @@ #include #include #include "stdio.h" +#include "string.h" /* memset */ #include "BLI_linklist.h" #include "BLI_rand.h" diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 8eb4d5972e3..40076755fa0 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -299,7 +299,7 @@ void Mat3MulMat3(float *m1, float *m3, float *m2); #endif void Mat4MulMat34(float (*m1)[4], float (*m3)[3], float (*m2)[4]); void Mat4CpyMat4(float m1[][4], float m2[][4]); -void Mat4SwapMat4(float *m1, float *m2); +void Mat4SwapMat4(float m1[][4], float m2[][4]); void Mat3CpyMat3(float m1[][3], float m2[][3]); void Mat3MulSerie(float answ[][3], diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index f0dba4255ad..9a05cd75ad0 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -614,17 +614,17 @@ void Mat4CpyMat4(float m1[][4], float m2[][4]) memcpy(m1, m2, 4*4*sizeof(float)); } -void Mat4SwapMat4(float *m1, float *m2) +void Mat4SwapMat4(float m1[][4], float m2[][4]) { float t; - int i; + int i, j; - for(i=0;i<16;i++) { - t= *m1; - *m1= *m2; - *m2= t; - m1++; - m2++; + for(i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + t = m1[i][j]; + m1[i][j] = m2[i][j]; + m2[i][j] = t; + } } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 69bc8e1f67e..e886bbbd5f2 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4546,13 +4546,13 @@ static void draw_forcefield(Scene *scene, Object *ob) /*path end*/ setlinestyle(3); - where_on_path(ob, 1.0f, guidevec1, guidevec2); + where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL); UI_ThemeColorBlend(curcol, TH_BACK, 0.5); drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat); /*path beginning*/ setlinestyle(0); - where_on_path(ob, 0.0f, guidevec1, guidevec2); + where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL); UI_ThemeColorBlend(curcol, TH_BACK, 0.5); drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 013491187ae..8473f91a7f7 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -49,12 +49,21 @@ struct AnimData; struct SelBox; struct EditFont; +/* These two Lines with # tell makesdna this struct can be excluded. */ +# +# +typedef struct PathPoint { + float vec[4]; /* grr, cant get rid of tilt yet */ + float quat[4]; + float radius; +} PathPoint; + /* These two Lines with # tell makesdna this struct can be excluded. */ # # typedef struct Path { int len; - float *data; + struct PathPoint *data; float totdist; } Path; -- cgit v1.2.3 From f130f16fef38d40ee492ccb4ff1ad0708329ae3c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 16:25:49 +0000 Subject: Use curve radius for paths - use_radius option, off by default for 2.4x files, on by default on new curves. - curve deform modifiers (think tentacles) - follow path (parent mode and constraint) - curve guides - added back Alt+S to scale point radius - Mat3Scale and Mat4Scale arithb.c functions to make a new uniform scale matrix. - TODO, effectors, looks like they have no way to scale from the radius yet. --- release/ui/buttons_data_curve.py | 1 + release/ui/buttons_object_constraint.py | 7 +++-- source/blender/blenkernel/intern/constraint.c | 33 +++++++++++++++------- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/lattice.c | 13 +++++++-- source/blender/blenkernel/intern/object.c | 11 ++++++-- source/blender/blenkernel/intern/particle.c | 16 ++++++----- source/blender/blenkernel/intern/particle_system.c | 6 ++-- source/blender/blenlib/BLI_arithb.h | 3 ++ source/blender/blenlib/intern/arithb.c | 20 +++++++++++++ source/blender/editors/curve/curve_ops.c | 1 + source/blender/makesdna/DNA_constraint_types.h | 1 + source/blender/makesdna/DNA_curve_types.h | 1 + source/blender/makesrna/intern/rna_constraint.c | 9 ++++-- source/blender/makesrna/intern/rna_curve.c | 5 ++++ 15 files changed, 99 insertions(+), 30 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 010acd1479d..1a5e56b02a4 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -142,6 +142,7 @@ class DATA_PT_pathanim(DataButtonsPanelCurve): col = split.column() col.itemR(curve, "use_stretch") + col.itemR(curve, "use_radius") col.itemR(curve, "use_time_offset", text="Offset Children") class DATA_PT_active_spline(DataButtonsPanelActive): diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py index ff3231a9d61..c8f7e467a18 100644 --- a/release/ui/buttons_object_constraint.py +++ b/release/ui/buttons_object_constraint.py @@ -124,11 +124,12 @@ class ConstraintButtonsPanel(bpy.types.Panel): split = layout.split() col = split.column() - col.itemR(con, "curve_follow") + col.itemR(con, "use_curve_follow") + col.itemR(con, "use_curve_radius") col = split.column() - col.itemR(con, "fixed_position") - if con.fixed_position: + col.itemR(con, "use_fixed_position") + if con.use_fixed_position: col.itemR(con, "offset_percentage", text="Offset") else: col.itemR(con, "offset") diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 6ab9f5844b1..e5c0b3947de 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1162,7 +1162,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr if (VALID_CONS_TARGET(ct)) { Curve *cu= ct->tar->data; - float q[4], vec[4], dir[3], quat[4], x1; + float q[4], vec[4], dir[3], quat[4], radius, x1; float totmat[4][4]; float curvetime; @@ -1196,7 +1196,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr curvetime= data->offset; // XXX might need a more sensible value } - if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) { + if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) { if (data->followflag & FOLLOWPATH_FOLLOW) { vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat); @@ -1210,6 +1210,14 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr QuatToMat4(quat, totmat); } + + if (data->followflag & FOLLOWPATH_RADIUS) { + float tmat[4][4], rmat[4][4]; + Mat4Scale(tmat, radius); + Mat4MulMat4(rmat, totmat, tmat); + Mat4CpyMat4(totmat, rmat); + } + VECCOPY(totmat[3], vec); Mat4MulSerie(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1227,7 +1235,8 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase /* only evaluate if there is a target */ if (VALID_CONS_TARGET(ct)) { float obmat[4][4]; - float size[3], obsize[3]; + float size[3]; + bFollowPathConstraint *data= con->data; /* get Object local transform (loc/rot/size) to determine transformation from path */ //object_to_mat4(ob, obmat); @@ -1240,13 +1249,17 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase Mat4MulSerie(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL); /* un-apply scaling caused by path */ - Mat4ToSize(cob->matrix, obsize); - if (obsize[0]) - VecMulf(cob->matrix[0], size[0] / obsize[0]); - if (obsize[1]) - VecMulf(cob->matrix[1], size[1] / obsize[1]); - if (obsize[2]) - VecMulf(cob->matrix[2], size[2] / obsize[2]); + if ((data->followflag & FOLLOWPATH_RADIUS)==0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */ + float obsize[3]; + + Mat4ToSize(cob->matrix, obsize); + if (obsize[0]) + VecMulf(cob->matrix[0], size[0] / obsize[0]); + if (obsize[1]) + VecMulf(cob->matrix[1], size[1] / obsize[1]); + if (obsize[2]) + VecMulf(cob->matrix[2], size[2] / obsize[2]); + } } } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 2b8c91fcbed..eec3cb73d8a 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -136,7 +136,7 @@ Curve *add_curve(char *name, int type) cu= alloc_libblock(&G.main->curve, ID_CU, name); cu->size[0]= cu->size[1]= cu->size[2]= 1.0; - cu->flag= CU_FRONT+CU_BACK; + cu->flag= CU_FRONT|CU_BACK|CU_PATH_RADIUS; cu->pathlen= 100; cu->resolu= cu->resolv= 12; cu->width= 1.0; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index e2c2723d036..730a12bea09 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -524,7 +524,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp) { Curve *cu= par->data; - float fac, loc[4], dir[3], cent[3]; + float fac, loc[4], dir[3], cent[3], radius; short upflag, index; if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) { @@ -579,7 +579,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C } #endif // XXX old animation system - if( where_on_path_deform(par, fac, loc, dir, NULL, NULL)) { /* returns OK */ + if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */ float q[4], mat[3][3], quat[4]; if(cd->no_rot_axis) /* set by caller */ @@ -599,7 +599,14 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C QuatMul(quat, q, quat); } QuatToMat3(quat, mat); - + + if(cu->flag & CU_PATH_RADIUS) { + float tmat[3][3], rmat[3][3]; + Mat3Scale(tmat, radius); + Mat3MulMat3(rmat, mat, tmat); + Mat3CpyMat3(mat, rmat); + } + /* local rotation */ Mat3MulVecfl(mat, cent); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index f04512cffc9..8fe7beeb247 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1646,7 +1646,7 @@ int enable_cu_speed= 1; static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) { Curve *cu; - float q[4], vec[4], dir[3], quat[4], x1, ctime; + float q[4], vec[4], dir[3], quat[4], radius, x1, ctime; float timeoffs = 0.0, sf_orig = 0.0; Mat4One(mat); @@ -1694,7 +1694,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) /* vec: 4 items! */ - if( where_on_path(par, ctime, vec, dir, NULL, NULL) ) { + if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) { if(cu->flag & CU_FOLLOW) { vectoquat(dir, ob->trackflag, ob->upflag, quat); @@ -1711,6 +1711,13 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) QuatToMat4(quat, mat); } + if(cu->flag & CU_PATH_RADIUS) { + float tmat[4][4], rmat[4][4]; + Mat4Scale(tmat, radius); + Mat4MulMat4(rmat, mat, tmat); + Mat4CpyMat4(mat, rmat); + } + VECCOPY(mat[3], vec); } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 404203c4508..2d3e3210afc 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1932,7 +1932,7 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase ParticleKey key, par; float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0; - float guidevec[4], guidedir[3], rot2[4], temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f}; + float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f}; float veffect[3]={0.0,0.0,0.0}, guidetime; effect[0]=effect[1]=effect[2]=0.0; @@ -1975,9 +1975,9 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase } if(pd->flag & PFIELD_GUIDE_PATH_ADD) - where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, NULL); + where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius); else - where_on_path(eob, guidetime, guidevec, guidedir, NULL, NULL); + where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius); Mat4MulVecfl(ec->ob->obmat,guidevec); Mat4Mul3Vecfl(ec->ob->obmat,guidedir); @@ -2007,10 +2007,12 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase /* curve taper */ if(cu->taperobj) VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100)); - /* TODO */ - //else{ - ///* curve size*/ - //} + + else{ /* curve size*/ + if(cu->flag & CU_PATH_RADIUS) { + VecMulf(pa_loc, radius); + } + } par.co[0]=par.co[1]=par.co[2]=0.0f; VECCOPY(key.co,pa_loc); do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3796e3e0ba5..fb12cfe3147 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2526,7 +2526,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ParticleSettings *part=psys->part; PARTICLE_P; int totpart; - float vec2[3],loc[3],*co=0; + float vec2[3],loc[3],radius,*co=0; for(ec= lb->first; ec; ec= ec->next) { PartDeflect *pd= ec->ob->pd; @@ -2536,7 +2536,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa && part->phystype!=PART_PHYS_BOIDS) { float vec[4]; - where_on_path(ec->ob, 0.0, vec, vec2, NULL, NULL); + where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius); Mat4MulVecfl(ec->ob->obmat,vec); Mat4Mul3Vecfl(ec->ob->obmat,vec2); @@ -2544,6 +2544,8 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa QUATCOPY(ec->firstloc,vec); VECCOPY(ec->firstdir,vec2); + /* TODO - use 'radius' to adjust the effector */ + totpart=psys->totpart; if(totpart){ diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 40076755fa0..c2d707f60f0 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -320,6 +320,9 @@ void Mat3Clr(float *m); void Mat3One(float m[][3]); void Mat4One(float m[][4]); +void Mat3Scale(float m[][3], float scale); +void Mat4Scale(float m[][4], float scale); + void Mat3Ortho(float mat[][3]); void Mat4Ortho(float mat[][4]); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 9a05cd75ad0..9e769e19674 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -854,6 +854,26 @@ void Mat3One(float m[][3]) m[2][0]= m[2][1]= 0.0; } +void Mat4Scale(float m[][4], float scale) +{ + + m[0][0]= m[1][1]= m[2][2]= scale; + m[3][3]= 1.0; + m[0][1]= m[0][2]= m[0][3]= 0.0; + m[1][0]= m[1][2]= m[1][3]= 0.0; + m[2][0]= m[2][1]= m[2][3]= 0.0; + m[3][0]= m[3][1]= m[3][2]= 0.0; +} + +void Mat3Scale(float m[][3], float scale) +{ + + m[0][0]= m[1][1]= m[2][2]= scale; + m[0][1]= m[0][2]= 0.0; + m[1][0]= m[1][2]= 0.0; + m[2][0]= m[2][1]= 0.0; +} + void Mat4MulVec( float mat[][4], int *vec) { int x,y; diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index a242e424aa0..8a90dace40b 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -234,6 +234,7 @@ void ED_keymap_curve(wmWindowManager *wm) WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0); RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", TFM_TILT); + RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_CURVE_SHRINKFATTEN); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, 0, 0)->ptr, "type", 3); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", VKEY, KM_PRESS, 0, 0)->ptr, "type", 2); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index a92dc836197..70430af3fc8 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -453,6 +453,7 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG { /* FollowPath flags */ #define FOLLOWPATH_FOLLOW 0x01 #define FOLLOWPATH_STATIC 0x02 +#define FOLLOWPATH_RADIUS 0x04 /* bTrackToConstraint->flags */ #define TARGET_Z_UP 0x01 diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 8473f91a7f7..109a9528de2 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -242,6 +242,7 @@ typedef struct Curve { #define CU_FAST 512 /* Font: no filling inside editmode */ #define CU_RETOPO 1024 #define CU_DS_EXPAND 2048 +#define CU_PATH_RADIUS 4096 /* make use of the path radius if this is enabled (default for new curves) */ /* twist mode */ #define CU_TWIST_Z_UP 0 diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 83f3042d8ee..815023ee315 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -893,16 +893,21 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Up Axis", "Axis that points upward."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); - prop= RNA_def_property(srna, "curve_follow", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_curve_follow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_FOLLOW); RNA_def_property_ui_text(prop, "Follow Curve", "Object will follow the heading and banking of the curve."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); // TODO: do we need to do some special trickery to get offset sane for this? - prop= RNA_def_property(srna, "fixed_position", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_fixed_position", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_STATIC); RNA_def_property_ui_text(prop, "Fixed Position", "Object will stay locked to a single point somewhere along the length of the curve regardless of time."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + prop= RNA_def_property(srna, "use_curve_radius", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_RADIUS); + RNA_def_property_ui_text(prop, "Curve Radius", "Objects scale by the curve radius."); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); } static void rna_def_constraint_stretch_to(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index d09546231d5..da4abe81f24 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -426,6 +426,11 @@ static void rna_def_path(BlenderRNA *brna, StructRNA *srna) RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_OFFS_PATHDIST); RNA_def_property_ui_text(prop, "Offset Path Distance", "Children will use TimeOffs value as path distance offset."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + + prop= RNA_def_property(srna, "use_radius", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_PATH_RADIUS); + RNA_def_property_ui_text(prop, "Radius", "Option for paths: apply the curve radius with path following it and deforming."); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); } static void rna_def_nurbs(BlenderRNA *brna, StructRNA *srna) -- cgit v1.2.3 From f9eb93bc7bd8351864cc4787953e2faf7d4cfd30 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 17:16:12 +0000 Subject: many docstrings from Ron Walker and Luca (mindrones on IRC), only did a spot check on these, may need adjusting later. --- source/blender/editors/curve/editfont.c | 17 +++ source/blender/editors/metaball/mball_edit.c | 7 ++ source/blender/editors/object/object_lattice.c | 2 + source/blender/editors/sculpt_paint/paint_ops.c | 1 + source/blender/editors/sculpt_paint/paint_utils.c | 1 + source/blender/editors/space_buttons/buttons_ops.c | 29 ++++- .../editors/space_sequencer/sequencer_add.c | 2 +- .../editors/space_sequencer/sequencer_buttons.c | 1 + .../editors/space_sequencer/sequencer_edit.c | 52 ++++++--- .../editors/space_sequencer/sequencer_select.c | 20 +++- source/blender/editors/space_text/text_ops.c | 124 +++++++++++---------- source/blender/editors/space_time/time_ops.c | 2 + .../blender/editors/space_view3d/view3d_buttons.c | 2 +- source/blender/editors/space_view3d/view3d_view.c | 1 + source/blender/editors/uvedit/uvedit_unwrap_ops.c | 1 + source/blender/windowmanager/intern/wm_jobs.c | 1 + source/blender/windowmanager/intern/wm_operators.c | 26 ++++- 17 files changed, 191 insertions(+), 98 deletions(-) diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index ae34f30a4f1..a9736f3f88d 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -317,6 +317,7 @@ void FONT_OT_insert_lorem(wmOperatorType *ot) { /* identifiers */ ot->name= "Insert Lorem"; + ot->description= "Insert placeholder text."; ot->idname= "FONT_OT_insert_lorem"; /* api callbacks */ @@ -404,6 +405,7 @@ void FONT_OT_file_paste(wmOperatorType *ot) { /* identifiers */ ot->name= "Paste File"; + ot->description= "Paste contents from file."; ot->idname= "FONT_OT_file_paste"; /* api callbacks */ @@ -452,6 +454,7 @@ void FONT_OT_buffer_paste(wmOperatorType *ot) { /* identifiers */ ot->name= "Paste Buffer"; + ot->description= "Paste text from OS buffer."; ot->idname= "FONT_OT_buffer_paste"; /* api callbacks */ @@ -648,6 +651,7 @@ void FONT_OT_style_set(wmOperatorType *ot) { /* identifiers */ ot->name= "Set Style"; + ot->description= "Set font style."; ot->idname= "FONT_OT_style_set"; /* api callbacks */ @@ -685,6 +689,7 @@ void FONT_OT_style_toggle(wmOperatorType *ot) { /* identifiers */ ot->name= "Toggle Style"; + ot->description= "Toggle font style."; ot->idname= "FONT_OT_style_toggle"; /* api callbacks */ @@ -727,6 +732,7 @@ void FONT_OT_text_copy(wmOperatorType *ot) { /* identifiers */ ot->name= "Copy Text"; + ot->description= "Copy selected text to clipboard."; ot->idname= "FONT_OT_text_copy"; /* api callbacks */ @@ -757,6 +763,7 @@ void FONT_OT_text_cut(wmOperatorType *ot) { /* identifiers */ ot->name= "Cut Text"; + ot->description= "Cut selected text to clipboard."; ot->idname= "FONT_OT_text_cut"; /* api callbacks */ @@ -814,6 +821,7 @@ void FONT_OT_text_paste(wmOperatorType *ot) { /* identifiers */ ot->name= "Paste Text"; + ot->description= "Paste text from clipboard."; ot->idname= "FONT_OT_text_paste"; /* api callbacks */ @@ -949,6 +957,7 @@ void FONT_OT_move(wmOperatorType *ot) { /* identifiers */ ot->name= "Move Cursor"; + ot->description= "Move cursor to position type."; ot->idname= "FONT_OT_move"; /* api callbacks */ @@ -975,6 +984,7 @@ void FONT_OT_move_select(wmOperatorType *ot) { /* identifiers */ ot->name= "Move Select"; + ot->description= "Make selection from current cursor position to new cursor position type."; ot->idname= "FONT_OT_move_select"; /* api callbacks */ @@ -1016,6 +1026,7 @@ void FONT_OT_change_spacing(wmOperatorType *ot) { /* identifiers */ ot->name= "Change Spacing"; + ot->description= "Change font spacing."; ot->idname= "FONT_OT_change_spacing"; /* api callbacks */ @@ -1060,6 +1071,7 @@ void FONT_OT_change_character(wmOperatorType *ot) { /* identifiers */ ot->name= "Change Character"; + ot->description= "Change font character code."; ot->idname= "FONT_OT_change_character"; /* api callbacks */ @@ -1102,6 +1114,7 @@ void FONT_OT_line_break(wmOperatorType *ot) { /* identifiers */ ot->name= "Line Break"; + ot->description= "Insert line break at cursor position."; ot->idname= "FONT_OT_line_break"; /* api callbacks */ @@ -1191,6 +1204,7 @@ void FONT_OT_delete(wmOperatorType *ot) { /* identifiers */ ot->name= "Delete"; + ot->description= "Delete text by cursor position."; ot->idname= "FONT_OT_delete"; /* api callbacks */ @@ -1332,6 +1346,7 @@ void FONT_OT_text_insert(wmOperatorType *ot) { /* identifiers */ ot->name= "Insert Text"; + ot->description= "Insert text at cursor position."; ot->idname= "FONT_OT_text_insert"; /* api callbacks */ @@ -1467,6 +1482,7 @@ void FONT_OT_case_set(wmOperatorType *ot) { /* identifiers */ ot->name= "Set Case"; + ot->description= "Set font case."; ot->idname= "FONT_OT_case_set"; /* api callbacks */ @@ -1509,6 +1525,7 @@ void FONT_OT_case_toggle(wmOperatorType *ot) { /* identifiers */ ot->name= "Toggle Case"; + ot->description= "Toggle font case."; ot->idname= "FONT_OT_case_toggle"; /* api callbacks */ diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 9ab985fb3fb..6ad7fbabfcb 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -223,6 +223,7 @@ void MBALL_OT_select_deselect_all_metaelems(wmOperatorType *ot) { /* identifiers */ ot->name= "Select/Deselect All"; + ot->description= "(de)select all metaelements."; ot->idname= "MBALL_OT_select_deselect_all_metaelems"; /* callback functions */ @@ -261,6 +262,7 @@ void MBALL_OT_select_inverse_metaelems(wmOperatorType *ot) { /* identifiers */ ot->name= "Inverse"; + ot->description= "Select inverse of (un)selected metaelements."; ot->idname= "MBALL_OT_select_inverse_metaelems"; /* callback functions */ @@ -306,6 +308,7 @@ void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Random..."; + ot->description= "Randomly select metaelements."; ot->idname= "MBALL_OT_select_random_metaelems"; /* callback functions */ @@ -364,6 +367,7 @@ void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) { /* identifiers */ ot->name= "Duplicate"; + ot->description= "Delete selected metaelement(s)."; ot->idname= "MBALL_OT_duplicate_metaelems"; /* callback functions */ @@ -409,6 +413,7 @@ void MBALL_OT_delete_metaelems(wmOperatorType *ot) { /* identifiers */ ot->name= "Delete"; + ot->description= "Delete selected metaelement(s)."; ot->idname= "MBALL_OT_delete_metaelems"; /* callback functions */ @@ -458,6 +463,7 @@ void MBALL_OT_hide_metaelems(wmOperatorType *ot) { /* identifiers */ ot->name= "Hide"; + ot->description= "Hide (un)selected metaelement(s)."; ot->idname= "MBALL_OT_hide_metaelems"; /* callback functions */ @@ -498,6 +504,7 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot) { /* identifiers */ ot->name= "Reveal"; + ot->description= "Reveal all hidden metaelements."; ot->idname= "MBALL_OT_reveal_metaelems"; /* callback functions */ diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index b35d3908b43..bd8171e8593 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -206,6 +206,7 @@ void LATTICE_OT_select_all_toggle(wmOperatorType *ot) { /* identifiers */ ot->name= "Select or Deselect All"; + ot->description= "Toggle (de)select all UVW control points."; ot->idname= "LATTICE_OT_select_all_toggle"; /* api callbacks */ @@ -251,6 +252,7 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) { /* identifiers */ ot->name= "Make Regular"; + ot->description= "Set UVW control points a uniform distance apart."; ot->idname= "LATTICE_OT_make_regular"; /* api callbacks */ diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index c38b36007e9..19b46f5a941 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -66,6 +66,7 @@ void BRUSH_OT_add(wmOperatorType *ot) { /* identifiers */ ot->name= "Add Brush"; + ot->description= "Add brush by mode type."; ot->idname= "BRUSH_OT_add"; /* api callbacks */ diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 23bc119afb4..13fbd2179b8 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -214,6 +214,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot) {0, NULL, 0, NULL, NULL}}; ot->name= "Preset"; + ot->description= "Set brush shape."; ot->idname= "BRUSH_OT_curve_preset"; ot->exec= brush_curve_preset_exec; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 176611377eb..481c2d6cfc3 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -106,6 +106,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot) /* identifiers */ ot->name= "Add Material Slot"; ot->idname= "OBJECT_OT_material_slot_add"; + ot->description="Add a new material slot or duplicate the selected one."; /* api callbacks */ ot->exec= material_slot_add_exec; @@ -132,6 +133,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot) /* identifiers */ ot->name= "Remove Material Slot"; ot->idname= "OBJECT_OT_material_slot_remove"; + ot->description="Remove the selected material slot."; /* api callbacks */ ot->exec= material_slot_remove_exec; @@ -190,6 +192,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot) /* identifiers */ ot->name= "Assign Material Slot"; ot->idname= "OBJECT_OT_material_slot_assign"; + ot->description="Assign the material in the selected material slot to the selected vertices."; /* api callbacks */ ot->exec= material_slot_assign_exec; @@ -273,6 +276,7 @@ void OBJECT_OT_material_slot_select(wmOperatorType *ot) /* identifiers */ ot->name= "Select Material Slot"; ot->idname= "OBJECT_OT_material_slot_select"; + ot->description="Select vertices assigned to the selected material slot."; /* api callbacks */ ot->exec= material_slot_select_exec; @@ -291,6 +295,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot) /* identifiers */ ot->name= "Deselect Material Slot"; ot->idname= "OBJECT_OT_material_slot_deselect"; + ot->description="Deselect vertices assigned to the selected material slot."; /* api callbacks */ ot->exec= material_slot_deselect_exec; @@ -338,6 +343,7 @@ void MATERIAL_OT_new(wmOperatorType *ot) /* identifiers */ ot->name= "New Material"; ot->idname= "MATERIAL_OT_new"; + ot->description="Add a new material."; /* api callbacks */ ot->exec= new_material_exec; @@ -390,6 +396,7 @@ void TEXTURE_OT_new(wmOperatorType *ot) /* identifiers */ ot->name= "New Texture"; ot->idname= "TEXTURE_OT_new"; + ot->description="Add a new texture."; /* api callbacks */ ot->exec= new_texture_exec; @@ -426,6 +433,7 @@ void WORLD_OT_new(wmOperatorType *ot) /* identifiers */ ot->name= "New World"; ot->idname= "WORLD_OT_new"; + ot->description= "Add a new world."; /* api callbacks */ ot->exec= new_world_exec; @@ -457,6 +465,7 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot) /* identifiers */ ot->name= "Add Particle System Slot"; ot->idname= "OBJECT_OT_particle_system_add"; + ot->description="Add a particle system."; /* api callbacks */ ot->exec= particle_system_add_exec; @@ -484,6 +493,7 @@ void OBJECT_OT_particle_system_remove(wmOperatorType *ot) /* identifiers */ ot->name= "Remove Particle System Slot"; ot->idname= "OBJECT_OT_particle_system_remove"; + ot->description="Remove the selected particle system."; /* api callbacks */ ot->exec= particle_system_remove_exec; @@ -541,6 +551,7 @@ void PARTICLE_OT_new(wmOperatorType *ot) /* identifiers */ ot->name= "New Particle Settings"; ot->idname= "PARTICLE_OT_new"; + ot->description="Add new particle settings."; /* api callbacks */ ot->exec= new_particle_settings_exec; @@ -588,6 +599,7 @@ void PARTICLE_OT_new_target(wmOperatorType *ot) /* identifiers */ ot->name= "New Particle Target"; ot->idname= "PARTICLE_OT_new_target"; + ot->description="Add a new particle target."; /* api callbacks */ ot->exec= new_particle_target_exec; @@ -635,6 +647,7 @@ void PARTICLE_OT_remove_target(wmOperatorType *ot) /* identifiers */ ot->name= "Remove Particle Target"; ot->idname= "PARTICLE_OT_remove_target"; + ot->description="Remove the selected particle target."; /* api callbacks */ ot->exec= remove_particle_target_exec; @@ -673,9 +686,9 @@ static int target_move_up_exec(bContext *C, wmOperator *op) void PARTICLE_OT_target_move_up(wmOperatorType *ot) { ot->name= "Move Up Target"; - ot->description= "Move particle target up in the list."; ot->idname= "PARTICLE_OT_target_move_up"; - + ot->description= "Move particle target up in the list."; + ot->exec= target_move_up_exec; /* flags */ @@ -711,9 +724,9 @@ static int target_move_down_exec(bContext *C, wmOperator *op) void PARTICLE_OT_target_move_down(wmOperatorType *ot) { ot->name= "Move Down Target"; - ot->description= "Move particle target down in the list."; ot->idname= "PARTICLE_OT_target_move_down"; - + ot->description= "Move particle target down in the list."; + ot->exec= target_move_down_exec; /* flags */ @@ -795,7 +808,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) ot->name= "Disconnect Hair"; ot->description= "Disconnect hair from the emitter mesh."; ot->idname= "PARTICLE_OT_disconnect_hair"; - + ot->exec= disconnect_hair_exec; /* flags */ @@ -930,7 +943,7 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot) ot->name= "Connect Hair"; ot->description= "Connect hair to the emitter mesh."; ot->idname= "PARTICLE_OT_connect_hair"; - + ot->exec= connect_hair_exec; /* flags */ @@ -958,6 +971,7 @@ void SCENE_OT_render_layer_add(wmOperatorType *ot) /* identifiers */ ot->name= "Add Render Layer"; ot->idname= "SCENE_OT_render_layer_add"; + ot->description="Add a render layer."; /* api callbacks */ ot->exec= render_layer_add_exec; @@ -1003,6 +1017,7 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot) /* identifiers */ ot->name= "Remove Render Layer"; ot->idname= "SCENE_OT_render_layer_remove"; + ot->description="Remove the selected render layer."; /* api callbacks */ ot->exec= render_layer_remove_exec; @@ -1036,6 +1051,7 @@ void BUTTONS_OT_toolbox(wmOperatorType *ot) /* identifiers */ ot->name= "Toolbox"; ot->idname= "BUTTONS_OT_toolbox"; + ot->description="Toolbar panel? DOC_BROKEN"; /* api callbacks */ ot->invoke= toolbox_invoke; @@ -1104,6 +1120,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot) /* identifiers */ ot->name= "File Browse"; ot->idname= "BUTTONS_OT_file_browse"; + ot->description="Open a file browser."; /* api callbacks */ ot->invoke= file_browse_invoke; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index e6d50976957..8a1b3bf3465 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -662,7 +662,7 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) /* identifiers */ ot->name= "Add Effect Strip"; ot->idname= "SEQUENCER_OT_effect_strip_add"; - ot->description= "Add an effect to the sequencer, most are applied ontop of existing strips"; + ot->description= "Add an effect to the sequencer, most are applied on top of existing strips"; /* api callbacks */ ot->invoke= sequencer_add_effect_strip_invoke; diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index cc4f5cf5ce3..789843f5490 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -126,6 +126,7 @@ void SEQUENCER_OT_properties(wmOperatorType *ot) { ot->name= "Properties"; ot->idname= "SEQUENCER_OT_properties"; + ot->description= "Open sequencer properties panel."; ot->exec= sequencer_properties; ot->poll= ED_operator_sequencer_active; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 1555784f470..4e71e4883d1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1461,7 +1461,8 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot) /* identifiers */ ot->name= "Snap strips"; ot->idname= "SEQUENCER_OT_snap"; - + ot->description="Frame where selected strips will be snapped."; + /* api callbacks */ ot->invoke= sequencer_snap_invoke; ot->exec= sequencer_snap_exec; @@ -1471,7 +1472,7 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will snaped", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX); } /* mute operator */ @@ -1514,7 +1515,8 @@ void SEQUENCER_OT_mute(struct wmOperatorType *ot) /* identifiers */ ot->name= "Mute Strips"; ot->idname= "SEQUENCER_OT_mute"; - + ot->description="Mute selected strips."; + /* api callbacks */ ot->exec= sequencer_mute_exec; @@ -1567,7 +1569,8 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot) /* identifiers */ ot->name= "UnMute Strips"; ot->idname= "SEQUENCER_OT_unmute"; - + ot->description="UnMute unselected rather than selected strips."; + /* api callbacks */ ot->exec= sequencer_unmute_exec; @@ -1606,7 +1609,8 @@ void SEQUENCER_OT_lock(struct wmOperatorType *ot) /* identifiers */ ot->name= "Lock Strips"; ot->idname= "SEQUENCER_OT_lock"; - + ot->description="Lock the active strip so that it can't be transformed."; + /* api callbacks */ ot->exec= sequencer_lock_exec; @@ -1642,7 +1646,8 @@ void SEQUENCER_OT_unlock(struct wmOperatorType *ot) /* identifiers */ ot->name= "UnLock Strips"; ot->idname= "SEQUENCER_OT_unlock"; - + ot->description="Unlock the active strip so that it can't be transformed."; + /* api callbacks */ ot->exec= sequencer_unlock_exec; @@ -1678,7 +1683,8 @@ void SEQUENCER_OT_reload(struct wmOperatorType *ot) /* identifiers */ ot->name= "Reload Strips"; ot->idname= "SEQUENCER_OT_reload"; - + ot->description="Reload strips in the sequencer."; + /* api callbacks */ ot->exec= sequencer_reload_exec; @@ -1709,7 +1715,8 @@ void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot) /* identifiers */ ot->name= "Refresh Sequencer"; ot->idname= "SEQUENCER_OT_refresh_all"; - + ot->description="Refresh the sequencer editor."; + /* api callbacks */ ot->exec= sequencer_refresh_all_exec; @@ -1806,7 +1813,8 @@ void SEQUENCER_OT_cut(struct wmOperatorType *ot) /* identifiers */ ot->name= "Cut Strips"; ot->idname= "SEQUENCER_OT_cut"; - + ot->description="Cut the selected strips."; + /* api callbacks */ ot->invoke= sequencer_cut_invoke; ot->exec= sequencer_cut_exec; @@ -1817,7 +1825,7 @@ void SEQUENCER_OT_cut(struct wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be cut", INT_MIN, INT_MAX); - RNA_def_enum(ot->srna, "type", prop_cut_types, SEQ_CUT_SOFT, "Type", "the type of cut operation to perform on strips"); + RNA_def_enum(ot->srna, "type", prop_cut_types, SEQ_CUT_SOFT, "Type", "The type of cut operation to perform on strips"); RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side that remains selected after cutting"); } @@ -1856,7 +1864,8 @@ void SEQUENCER_OT_duplicate(wmOperatorType *ot) /* identifiers */ ot->name= "Duplicate"; ot->idname= "SEQUENCER_OT_duplicate"; - + ot->description="Duplicate the selected strips."; + /* api callbacks */ ot->invoke= sequencer_add_duplicate_invoke; ot->exec= sequencer_add_duplicate_exec; @@ -1938,7 +1947,8 @@ void SEQUENCER_OT_delete(wmOperatorType *ot) /* identifiers */ ot->name= "Erase Strips"; ot->idname= "SEQUENCER_OT_delete"; - + ot->description="Erase selected strips from the sequencer."; + /* api callbacks */ ot->invoke= WM_operator_confirm; ot->exec= sequencer_delete_exec; @@ -2031,7 +2041,8 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) /* identifiers */ ot->name= "Separate Images"; ot->idname= "SEQUENCER_OT_images_separate"; - + ot->description="On image sequences strips, it return a strip for each image."; + /* api callbacks */ ot->invoke= WM_operator_confirm; ot->exec= sequencer_separate_images_exec; @@ -2103,7 +2114,8 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot) /* identifiers */ ot->name= "Toggle Meta Strip"; ot->idname= "SEQUENCER_OT_meta_toggle"; - + ot->description="Toggle a metastrip (to edit enclosed strips)."; + /* api callbacks */ ot->exec= sequencer_meta_toggle_exec; @@ -2207,7 +2219,8 @@ void SEQUENCER_OT_meta_make(wmOperatorType *ot) /* identifiers */ ot->name= "Make Meta Strip"; ot->idname= "SEQUENCER_OT_meta_make"; - + ot->description="Group selected strips into a metastrip."; + /* api callbacks */ ot->invoke= WM_operator_confirm; ot->exec= sequencer_meta_make_exec; @@ -2276,7 +2289,8 @@ void SEQUENCER_OT_meta_separate(wmOperatorType *ot) /* identifiers */ ot->name= "UnMeta Strip"; ot->idname= "SEQUENCER_OT_meta_separate"; - + ot->description="Put the contents of a metastrip back in the sequencer."; + /* api callbacks */ ot->invoke= WM_operator_confirm; ot->exec= sequencer_meta_separate_exec; @@ -2342,7 +2356,8 @@ void SEQUENCER_OT_view_all(wmOperatorType *ot) /* identifiers */ ot->name= "View All"; ot->idname= "SEQUENCER_OT_view_all"; - + ot->description="View all the strips in the sequencer."; + /* api callbacks */ ot->exec= sequencer_view_all_exec; @@ -2422,7 +2437,8 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot) /* identifiers */ ot->name= "View Selected"; ot->idname= "SEQUENCER_OT_view_selected"; - + ot->description="Zoom the sequencer on the selected strips."; + /* api callbacks */ ot->exec= sequencer_view_selected_exec; diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index dda5837e5f5..747e1609213 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -232,7 +232,8 @@ void SEQUENCER_OT_select_all_toggle(struct wmOperatorType *ot) /* identifiers */ ot->name= "(De)Select All"; ot->idname= "SEQUENCER_OT_select_all_toggle"; - + ot->description="Select or deselect all strips."; + /* api callbacks */ ot->exec= sequencer_deselect_exec; @@ -272,7 +273,8 @@ void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot) /* identifiers */ ot->name= "Select Inverse"; ot->idname= "SEQUENCER_OT_select_inverse"; - + ot->description="Select unselected strips."; + /* api callbacks */ ot->exec= sequencer_select_inverse_exec; @@ -448,6 +450,7 @@ void SEQUENCER_OT_select(wmOperatorType *ot) /* identifiers */ ot->name= "Activate/Select"; ot->idname= "SEQUENCER_OT_select"; + ot->description="Select a strip (last selected becomes the \"active strip\")."; /* api callbacks */ ot->invoke= sequencer_select_invoke; @@ -533,6 +536,7 @@ void SEQUENCER_OT_select_more(wmOperatorType *ot) /* identifiers */ ot->name= "Select More"; ot->idname= "SEQUENCER_OT_select_more"; + ot->description="DOC_BROKEN"; /* api callbacks */ ot->exec= sequencer_select_more_exec; @@ -562,6 +566,7 @@ void SEQUENCER_OT_select_less(wmOperatorType *ot) /* identifiers */ ot->name= "Select less"; ot->idname= "SEQUENCER_OT_select_less"; + ot->description="DOC_BROKEN"; /* api callbacks */ ot->exec= sequencer_select_less_exec; @@ -616,6 +621,7 @@ void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot) /* identifiers */ ot->name= "Select pick linked"; ot->idname= "SEQUENCER_OT_select_linked_pick"; + ot->description="DOC_BROKEN"; /* api callbacks */ ot->invoke= sequencer_select_linked_pick_invoke; @@ -650,7 +656,8 @@ void SEQUENCER_OT_select_linked(wmOperatorType *ot) /* identifiers */ ot->name= "Select linked"; ot->idname= "SEQUENCER_OT_select_linked"; - + ot->description="DOC_BROKEN"; + /* api callbacks */ ot->exec= sequencer_select_linked_exec; ot->poll= ED_operator_sequencer_active; @@ -701,7 +708,8 @@ void SEQUENCER_OT_select_handles(wmOperatorType *ot) /* identifiers */ ot->name= "Select Handles"; ot->idname= "SEQUENCER_OT_select_handles"; - + ot->description="DOC_BROKEN"; + /* api callbacks */ ot->exec= sequencer_select_handles_exec; ot->poll= ED_operator_sequencer_active; @@ -737,7 +745,8 @@ void SEQUENCER_OT_select_active_side(wmOperatorType *ot) /* identifiers */ ot->name= "Select Active Side"; ot->idname= "SEQUENCER_OT_select_active_side"; - + ot->description="DOC_BROKEN"; + /* api callbacks */ ot->exec= sequencer_select_active_side_exec; ot->poll= ED_operator_sequencer_active; @@ -799,6 +808,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot) /* identifiers */ ot->name= "Border Select"; ot->idname= "SEQUENCER_OT_select_border"; + ot->description="Enable border select mode."; /* api callbacks */ ot->invoke= WM_border_select_invoke; diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 7751355a14d..3411d9114df 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -176,9 +176,9 @@ void TEXT_OT_new(wmOperatorType *ot) { /* identifiers */ ot->name= "New"; - ot->description= "Create a new text data block."; ot->idname= "TEXT_OT_new"; - + ot->description= "Create a new text data block."; + /* api callbacks */ ot->exec= new_exec; ot->poll= text_new_poll; @@ -224,8 +224,8 @@ void TEXT_OT_open(wmOperatorType *ot) { /* identifiers */ ot->name= "Open"; - ot->description= "Open a new text data block."; ot->idname= "TEXT_OT_open"; + ot->description= "Open a new text data block."; /* api callbacks */ ot->exec= open_exec; @@ -262,9 +262,9 @@ void TEXT_OT_reload(wmOperatorType *ot) { /* identifiers */ ot->name= "Reload"; - ot->description= "Reload active text data block from its file."; ot->idname= "TEXT_OT_reload"; - + ot->description= "Reload active text data block from its file."; + /* api callbacks */ ot->exec= reload_exec; ot->invoke= WM_operator_confirm; @@ -302,9 +302,9 @@ void TEXT_OT_unlink(wmOperatorType *ot) { /* identifiers */ ot->name= "Unlink"; - ot->description= "Unlink active text data block."; ot->idname= "TEXT_OT_unlink"; - + ot->description= "Unlink active text data block."; + /* api callbacks */ ot->exec= unlink_exec; ot->invoke= WM_operator_confirm; @@ -333,8 +333,8 @@ void TEXT_OT_make_internal(wmOperatorType *ot) { /* identifiers */ ot->name= "Make Internal"; - ot->description= "Make active text file internal."; ot->idname= "TEXT_OT_make_internal"; + ot->description= "Make active text file internal."; /* api callbacks */ ot->exec= make_internal_exec; @@ -402,8 +402,8 @@ void TEXT_OT_save(wmOperatorType *ot) { /* identifiers */ ot->name= "Save"; - ot->description= "Save active text data block."; ot->idname= "TEXT_OT_save"; + ot->description= "Save active text data block."; /* api callbacks */ ot->exec= save_exec; @@ -458,9 +458,9 @@ void TEXT_OT_save_as(wmOperatorType *ot) { /* identifiers */ ot->name= "Save As"; - ot->description= "Save active text file with options."; ot->idname= "TEXT_OT_save_as"; - + ot->description= "Save active text file with options."; + /* api callbacks */ ot->exec= save_as_exec; ot->invoke= save_as_invoke; @@ -496,9 +496,9 @@ void TEXT_OT_run_script(wmOperatorType *ot) { /* identifiers */ ot->name= "Run Script"; - ot->description= "Run active script."; ot->idname= "TEXT_OT_run_script"; - + ot->description= "Run active script."; + /* api callbacks */ ot->exec= run_script_exec; ot->poll= text_edit_poll; @@ -552,9 +552,9 @@ void TEXT_OT_refresh_pyconstraints(wmOperatorType *ot) { /* identifiers */ ot->name= "Refresh PyConstraints"; - ot->description= "Refresh all pyconstraints."; ot->idname= "TEXT_OT_refresh_pyconstraints"; - + ot->description= "Refresh all pyconstraints."; + /* api callbacks */ ot->exec= refresh_pyconstraints_exec; ot->poll= text_edit_poll; @@ -674,9 +674,9 @@ void TEXT_OT_paste(wmOperatorType *ot) { /* identifiers */ ot->name= "Paste"; - ot->description= "Paste text from clipboard."; ot->idname= "TEXT_OT_paste"; - + ot->description= "Paste text from clipboard."; + /* api callbacks */ ot->exec= paste_exec; ot->poll= text_edit_poll; @@ -715,8 +715,8 @@ void TEXT_OT_copy(wmOperatorType *ot) { /* identifiers */ ot->name= "Copy"; - ot->description= "Copy selected text to clipboard."; ot->idname= "TEXT_OT_copy"; + ot->description= "Copy selected text to clipboard."; /* api callbacks */ ot->exec= copy_exec; @@ -746,9 +746,9 @@ void TEXT_OT_cut(wmOperatorType *ot) { /* identifiers */ ot->name= "Cut"; - ot->description= "Cut selected text to clipboard."; ot->idname= "TEXT_OT_cut"; - + ot->description= "Cut selected text to clipboard."; + /* api callbacks */ ot->exec= cut_exec; ot->poll= text_edit_poll; @@ -782,9 +782,9 @@ void TEXT_OT_indent(wmOperatorType *ot) { /* identifiers */ ot->name= "Indent"; - ot->description= "Indent selected text."; ot->idname= "TEXT_OT_indent"; - + ot->description= "Indent selected text."; + /* api callbacks */ ot->exec= indent_exec; ot->poll= text_edit_poll; @@ -818,9 +818,9 @@ void TEXT_OT_unindent(wmOperatorType *ot) { /* identifiers */ ot->name= "Unindent"; - ot->description= "Unindent selected text."; ot->idname= "TEXT_OT_unindent"; - + ot->description= "Unindent selected text."; + /* api callbacks */ ot->exec= unindent_exec; ot->poll= text_edit_poll; @@ -859,9 +859,9 @@ void TEXT_OT_line_break(wmOperatorType *ot) { /* identifiers */ ot->name= "Line Break"; - ot->description= "Insert line break at cursor position."; ot->idname= "TEXT_OT_line_break"; - + ot->description= "Insert line break at cursor position."; + /* api callbacks */ ot->exec= line_break_exec; ot->poll= text_edit_poll; @@ -892,9 +892,9 @@ void TEXT_OT_comment(wmOperatorType *ot) { /* identifiers */ ot->name= "Comment"; - ot->description= "Convert selected text to comment."; ot->idname= "TEXT_OT_comment"; - + ot->description= "Convert selected text to comment."; + /* api callbacks */ ot->exec= comment_exec; ot->poll= text_edit_poll; @@ -926,9 +926,9 @@ void TEXT_OT_uncomment(wmOperatorType *ot) { /* identifiers */ ot->name= "Uncomment"; - ot->description= "Convert selected comment to text."; ot->idname= "TEXT_OT_uncomment"; - + ot->description= "Convert selected comment to text."; + /* api callbacks */ ot->exec= uncomment_exec; ot->poll= text_edit_poll; @@ -1068,9 +1068,9 @@ void TEXT_OT_convert_whitespace(wmOperatorType *ot) { /* identifiers */ ot->name= "Convert Whitespace"; - ot->description= "Convert whitespaces by type."; ot->idname= "TEXT_OT_convert_whitespace"; - + ot->description= "Convert whitespaces by type."; + /* api callbacks */ ot->exec= convert_whitespace_exec; ot->poll= text_edit_poll; @@ -1099,9 +1099,9 @@ void TEXT_OT_select_all(wmOperatorType *ot) { /* identifiers */ ot->name= "Select All"; - ot->description= "Select all text."; ot->idname= "TEXT_OT_select_all"; - + ot->description= "Select all text."; + /* api callbacks */ ot->exec= select_all_exec; ot->poll= text_edit_poll; @@ -1127,9 +1127,9 @@ void TEXT_OT_select_line(wmOperatorType *ot) { /* identifiers */ ot->name= "Select Line"; - ot->description= "Select text by line."; ot->idname= "TEXT_OT_select_line"; - + ot->description= "Select text by line."; + /* api clinebacks */ ot->exec= select_line_exec; ot->poll= text_edit_poll; @@ -1165,9 +1165,9 @@ void TEXT_OT_previous_marker(wmOperatorType *ot) { /* identifiers */ ot->name= "Previous Marker"; - ot->description= "Move to previous marker."; ot->idname= "TEXT_OT_previous_marker"; - + ot->description= "Move to previous marker."; + /* api callbacks */ ot->exec= previous_marker_exec; ot->poll= text_edit_poll; @@ -1203,9 +1203,9 @@ void TEXT_OT_next_marker(wmOperatorType *ot) { /* identifiers */ ot->name= "Next Marker"; - ot->description= "Move to next marker"; ot->idname= "TEXT_OT_next_marker"; - + ot->description= "Move to next marker"; + /* api callbacks */ ot->exec= next_marker_exec; ot->poll= text_edit_poll; @@ -1231,9 +1231,9 @@ void TEXT_OT_markers_clear(wmOperatorType *ot) { /* identifiers */ ot->name= "Clear All Markers"; - ot->description= "Clear all markers."; ot->idname= "TEXT_OT_markers_clear"; - + ot->description= "Clear all markers."; + /* api callbacks */ ot->exec= clear_all_markers_exec; ot->poll= text_edit_poll; @@ -1515,8 +1515,8 @@ void TEXT_OT_move(wmOperatorType *ot) { /* identifiers */ ot->name= "Move Cursor"; - ot->description= "Move cursor to position type."; ot->idname= "TEXT_OT_move"; + ot->description= "Move cursor to position type."; /* api callbacks */ ot->exec= move_exec; @@ -1542,8 +1542,8 @@ void TEXT_OT_move_select(wmOperatorType *ot) { /* identifiers */ ot->name= "Move Select"; - ot->description= "Make selection from current cursor position to new cursor position type."; ot->idname= "TEXT_OT_move_select"; + ot->description= "Make selection from current cursor position to new cursor position type."; /* api callbacks */ ot->exec= move_select_exec; @@ -1582,9 +1582,9 @@ void TEXT_OT_jump(wmOperatorType *ot) { /* identifiers */ ot->name= "Jump"; - ot->description= "Jump cursor to line."; ot->idname= "TEXT_OT_jump"; - + ot->description= "Jump cursor to line."; + /* api callbacks */ ot->exec= jump_exec; ot->poll= text_edit_poll; @@ -1635,8 +1635,8 @@ void TEXT_OT_delete(wmOperatorType *ot) { /* identifiers */ ot->name= "Delete"; - ot->description= "Delete text by cursor position."; ot->idname= "TEXT_OT_delete"; + ot->description= "Delete text by cursor position."; /* api callbacks */ ot->exec= delete_exec; @@ -1665,6 +1665,7 @@ void TEXT_OT_overwrite_toggle(wmOperatorType *ot) /* identifiers */ ot->name= "Toggle Overwrite"; ot->idname= "TEXT_OT_overwrite_toggle"; + ot->description= "Toggle overwrite while typing."; /* api callbacks */ ot->exec= toggle_overwrite_exec; @@ -1819,8 +1820,8 @@ void TEXT_OT_scroll(wmOperatorType *ot) /*don't really see the difference between this and scroll_bar. Both do basically the same thing (aside from keymaps).*/ - ot->description= "Scroll text screen."; ot->idname= "TEXT_OT_scroll"; + ot->description= "Scroll text screen."; /* api callbacks */ ot->exec= scroll_exec; @@ -1871,8 +1872,8 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot) /*don't really see the difference between this and scroll. Both do basically the same thing (aside from keymaps).*/ - ot->description= "Scroll text screen."; ot->idname= "TEXT_OT_scroll_bar"; + ot->description= "Scroll text screen."; /* api callbacks */ ot->invoke= scroll_bar_invoke; @@ -2147,8 +2148,8 @@ void TEXT_OT_cursor_set(wmOperatorType *ot) { /* identifiers */ ot->name= "Set Cursor"; - ot->description= "Set cursor selection."; ot->idname= "TEXT_OT_cursor_set"; + ot->description= "Set cursor selection."; /* api callbacks */ ot->invoke= set_cursor_invoke; @@ -2204,6 +2205,7 @@ void TEXT_OT_line_number(wmOperatorType *ot) /* identifiers */ ot->name= "Line Number"; ot->idname= "TEXT_OT_line_number"; + ot->description= "The current line number."; /* api callbacks */ ot->invoke= line_number_invoke; @@ -2271,8 +2273,8 @@ void TEXT_OT_insert(wmOperatorType *ot) { /* identifiers */ ot->name= "Insert"; - ot->description= "Insert text at cursor position."; ot->idname= "TEXT_OT_insert"; + ot->description= "Insert text at cursor position."; /* api callbacks */ ot->exec= insert_exec; @@ -2376,9 +2378,9 @@ void TEXT_OT_find(wmOperatorType *ot) { /* identifiers */ ot->name= "Find"; - ot->description= "Find specified text."; ot->idname= "TEXT_OT_find"; - + ot->description= "Find specified text."; + /* api callbacks */ ot->exec= find_exec; ot->poll= text_space_edit_poll; @@ -2395,8 +2397,8 @@ void TEXT_OT_replace(wmOperatorType *ot) { /* identifiers */ ot->name= "Replace"; - ot->description= "Replace text with specified text."; ot->idname= "TEXT_OT_replace"; + ot->description= "Replace text with the specified text."; /* api callbacks */ ot->exec= replace_exec; @@ -2414,9 +2416,9 @@ void TEXT_OT_mark_all(wmOperatorType *ot) { /* identifiers */ ot->name= "Mark All"; - ot->description= "Mark all specified text."; ot->idname= "TEXT_OT_mark_all"; - + ot->description= "Mark all specified text."; + /* api callbacks */ ot->exec= mark_all_exec; ot->poll= text_space_edit_poll; @@ -2444,9 +2446,9 @@ void TEXT_OT_find_set_selected(wmOperatorType *ot) { /* identifiers */ ot->name= "Find Set Selected"; - ot->description= "Find specified text and set as selected."; ot->idname= "TEXT_OT_find_set_selected"; - + ot->description= "Find specified text and set as selected."; + /* api callbacks */ ot->exec= find_set_selected_exec; ot->poll= text_space_edit_poll; @@ -2471,9 +2473,9 @@ void TEXT_OT_replace_set_selected(wmOperatorType *ot) { /* identifiers */ ot->name= "Replace Set Selected"; - ot->description= "Replace text with specified text and set as selected."; ot->idname= "TEXT_OT_replace_set_selected"; - + ot->description= "Replace text with specified text and set as selected."; + /* api callbacks */ ot->exec= replace_set_selected_exec; ot->poll= text_space_edit_poll; @@ -2634,8 +2636,8 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot) { /* identifiers */ ot->name= "To 3D Object"; - ot->description= "Create 3d text object from active text data block."; ot->idname= "TEXT_OT_to_3d_object"; + ot->description= "Create 3d text object from active text data block."; /* api callbacks */ ot->exec= to_3d_object_exec; diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index b47afaf0cde..a833cca095c 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -84,6 +84,7 @@ void TIME_OT_start_frame_set (wmOperatorType *ot) /* identifiers */ ot->name= "Set Start Frame"; ot->idname= "TIME_OT_start_frame_set"; + ot->description="Set the start frame."; /* api callbacks */ ot->exec= time_set_sfra_exec; @@ -122,6 +123,7 @@ void TIME_OT_end_frame_set (wmOperatorType *ot) /* identifiers */ ot->name= "Set End Frame"; ot->idname= "TIME_OT_end_frame_set"; + ot->description="Set the end frame."; /* api callbacks */ ot->exec= time_set_efra_exec; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index d78928921e5..54a8c375e69 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1471,7 +1471,7 @@ static int view3d_properties(bContext *C, wmOperator *op) void VIEW3D_OT_properties(wmOperatorType *ot) { ot->name= "Properties"; - ot->description= "Display the properties panel."; + ot->description= "Toggles the properties panel display."; ot->idname= "VIEW3D_OT_properties"; ot->exec= view3d_properties; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 808d1635b37..7831d604ddf 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -376,6 +376,7 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot) /* identifiers */ ot->name= "Smooth View"; ot->idname= "VIEW3D_OT_smoothview"; + ot->description="The time to animate the change of view (in milliseconds)"; /* api callbacks */ ot->invoke= view3d_smoothview_invoke; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index b20d390fb4d..ccdc51430bc 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -412,6 +412,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) ot->name= "Minimize Stretch"; ot->idname= "UV_OT_minimize_stretch"; ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->description="DOC_BROKEN"; /* api callbacks */ ot->exec= minimize_stretch_exec; diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 0fd658dbb64..bef3268920d 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -373,6 +373,7 @@ void WM_OT_jobs_timer(wmOperatorType *ot) /* identifiers */ ot->name= "Jobs timer"; ot->idname= "WM_OT_jobs_timer"; + ot->description="Jobs timer operator."; /* api callbacks */ ot->invoke= wm_jobs_timer; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 77f4fe25606..37cd424ac18 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -646,6 +646,7 @@ static void WM_OT_debug_menu(wmOperatorType *ot) { ot->name= "Debug Menu"; ot->idname= "WM_OT_debug_menu"; + ot->description= "Open a popup to set the debug level."; ot->invoke= wm_debug_menu_invoke; ot->exec= wm_debug_menu_exec; @@ -760,7 +761,8 @@ static void WM_OT_window_duplicate(wmOperatorType *ot) { ot->name= "Duplicate Window"; ot->idname= "WM_OT_window_duplicate"; - + ot->description="Duplicate the current Blender window."; + ot->exec= wm_window_duplicate_op; ot->poll= WM_operator_winactive; } @@ -769,7 +771,8 @@ static void WM_OT_save_homefile(wmOperatorType *ot) { ot->name= "Save User Settings"; ot->idname= "WM_OT_save_homefile"; - + ot->description="Make the current file the default .blend file."; + ot->invoke= WM_operator_confirm; ot->exec= WM_write_homefile; ot->poll= WM_operator_winactive; @@ -779,6 +782,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot) { ot->name= "Reload Start-Up File"; ot->idname= "WM_OT_read_homefile"; + ot->description="Open the default file (doesn't save the current file)."; ot->invoke= WM_operator_confirm; ot->exec= WM_read_homefile; @@ -855,6 +859,7 @@ static void WM_OT_open_recentfile(wmOperatorType *ot) ot->name= "Open Recent File"; ot->idname= "WM_OT_open_recentfile"; + ot->description="Open recent files list."; ot->invoke= wm_recentfile_invoke; ot->exec= recentfile_exec; @@ -919,6 +924,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot) { ot->name= "Open Blender File"; ot->idname= "WM_OT_open_mainfile"; + ot->description="Open a Blender file."; ot->invoke= wm_open_mainfile_invoke; ot->exec= wm_open_mainfile_exec; @@ -957,6 +963,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) { ot->name= "Recover Last Session"; ot->idname= "WM_OT_recover_last_session"; + ot->description="Open the last closed file (\"quit.blend\")."; ot->exec= wm_recover_last_session_exec; ot->poll= WM_operator_winactive; @@ -1014,6 +1021,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) { ot->name= "Save As Blender File"; ot->idname= "WM_OT_save_as_mainfile"; + ot->description="Save the current file in the desired location."; ot->invoke= wm_save_as_mainfile_invoke; ot->exec= wm_save_as_mainfile_exec; @@ -1043,6 +1051,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) { ot->name= "Save Blender File"; ot->idname= "WM_OT_save_mainfile"; + ot->description="Save the current Blender file."; ot->invoke= wm_save_mainfile_invoke; ot->exec= wm_save_as_mainfile_exec; @@ -1057,11 +1066,12 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot) { - ot->name= "Toggle Fullscreen"; - ot->idname= "WM_OT_window_fullscreen_toggle"; + ot->name= "Toggle Fullscreen"; + ot->idname= "WM_OT_window_fullscreen_toggle"; + ot->description="Toggle the current window fullscreen."; - ot->exec= wm_window_fullscreen_toggle_op; - ot->poll= WM_operator_winactive; + ot->exec= wm_window_fullscreen_toggle_op; + ot->poll= WM_operator_winactive; } static int wm_exit_blender_op(bContext *C, wmOperator *op) @@ -1077,6 +1087,7 @@ static void WM_OT_exit_blender(wmOperatorType *ot) { ot->name= "Exit Blender"; ot->idname= "WM_OT_exit_blender"; + ot->description= "Quit Blender."; ot->invoke= WM_operator_confirm; ot->exec= wm_exit_blender_op; @@ -1326,6 +1337,7 @@ void WM_OT_circle_gesture(wmOperatorType *ot) { ot->name= "Circle Gesture"; ot->idname= "WM_OT_circle_gesture"; + ot->description="Enter rotate mode with a circular gesture."; ot->invoke= WM_gesture_circle_invoke; ot->modal= WM_gesture_circle_modal; @@ -1539,6 +1551,7 @@ void WM_OT_lasso_gesture(wmOperatorType *ot) ot->name= "Lasso Gesture"; ot->idname= "WM_OT_lasso_gesture"; + ot->description="Select objects within the lasso as you move the pointer."; ot->invoke= WM_gesture_lasso_invoke; ot->modal= WM_gesture_lasso_modal; @@ -1864,6 +1877,7 @@ static void WM_OT_ten_timer(wmOperatorType *ot) ot->name= "Ten Timer"; ot->idname= "WM_OT_ten_timer"; + ot->description="Ten Timer operator."; ot->invoke= WM_menu_invoke; ot->exec= ten_timer_exec; -- cgit v1.2.3 From 5392a90e2862df43fd82d5fbe24faaf3ca6888c9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 18:09:59 +0000 Subject: - adding curves didnt work if EnterEditmode option was off. - adding a curve in editmode now is 3D, if the curve its added in is 3D. --- source/blender/editors/curve/editcurve.c | 5 +++-- source/blender/editors/object/object_add.c | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index e346ccafde3..edcfb46c270 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4704,6 +4704,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) float *curs, cent[3],vec[3],imat[3][3],mat[3][3]; float fac,cmat[3][3], grid; int a, b, cutype, stype; + int force_3d = ((Curve *)obedit->data)->flag & CU_3D; /* could be adding to an existing 3D curve */ cutype= type & CU_TYPE; // poly, bezier, nurbs, etc stype= type & CU_PRIMITIVE; @@ -4760,7 +4761,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) rename_id((ID *)obedit->data, "Curve"); } if(cutype==CU_BEZIER) { - nu->flag= CU_2D; + if (!force_3d) nu->flag |= CU_2D; nu->pntsu= 2; nu->bezt = (BezTriple*)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1"); @@ -4869,7 +4870,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) rename_id((ID *)obedit->data, "CurveCircle"); } if(cutype==CU_BEZIER) { - nu->flag= CU_2D; + if (!force_3d) nu->flag |= CU_2D; nu->pntsu= 4; nu->bezt= callocstructN(BezTriple, 4, "addNurbprim1"); nu->flagu= CU_CYCLIC; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index f4c8c63c480..833d3914e47 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -307,7 +307,6 @@ static int object_add_curve_exec(bContext *C, wmOperator *op) /* userdef */ if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_enter_editmode(C, 0); ED_object_exit_editmode(C, EM_FREEDATA); } -- cgit v1.2.3 From 0fb9380b03c2cb403e54e342da36c23a27c75597 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 18:52:26 +0000 Subject: - adding nurbs sufraces messed up when adding with both editmode and align to view disabled. - Vkey was being caught by the vertex paint mode, blocking it for curve edit where it sets the handle type. Now mode keys pass through if they dont apply to the object type. - set handles had invalid default --- source/blender/editors/curve/editcurve.c | 4 ++-- source/blender/editors/object/object_edit.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index edcfb46c270..8dabe24de91 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2546,7 +2546,7 @@ void CURVE_OT_handle_type_set(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type"); + RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "Spline type"); } /***************** make segment operator **********************/ @@ -4728,7 +4728,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) cent[2]-= obedit->obmat[3][2]; if(rv3d) { - if (!(newname) || U.flag & USER_ADD_VIEWALIGNED) + if (!newname && U.flag & USER_ADD_VIEWALIGNED) Mat3CpyMat4(imat, rv3d->viewmat); else Mat3One(imat); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index daa63da03db..aaf6ed387c7 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1985,7 +1985,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) int toggle = RNA_boolean_get(op->ptr, "toggle"); if(!ob || !object_mode_set_compat(C, op, ob)) - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH; /* Exit current mode if it's not the mode we're setting */ if(ob->mode != OB_MODE_OBJECT && ob->mode != mode) -- cgit v1.2.3 From c1e2e3fea2dd1b22cf22a9dca4d88bde2d280ab6 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sat, 12 Sep 2009 19:11:34 +0000 Subject: As discussed with Campbell on IRC: Made some UI operators not register themselves in the console. This made macro creation a pain because the operator list would have tons of splits and other UI commends mixed in with actual data manipulation. Moved Repeat Last from Ctrl-R to Shift-R so it doesn't conflict with loop cut, whenever it is added. --- source/blender/editors/screen/screen_ops.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 75da8f5fe06..bb9d940edca 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1261,7 +1261,7 @@ static void SCREEN_OT_area_split(wmOperatorType *ot) ot->modal= area_split_modal; ot->poll= ED_operator_areaactive; - ot->flag= OPTYPE_REGISTER|OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING; /* rna */ RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", ""); @@ -2127,7 +2127,7 @@ static void SCREEN_OT_region_foursplit(wmOperatorType *ot) // ot->invoke= WM_operator_confirm; ot->exec= region_foursplit_exec; ot->poll= ED_operator_areaactive; - ot->flag= OPTYPE_REGISTER; + ot->flag= 0; } @@ -2165,7 +2165,7 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot) ot->exec= region_flip_exec; ot->poll= ED_operator_areaactive; - ot->flag= OPTYPE_REGISTER; + ot->flag= 0; } @@ -3327,10 +3327,8 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_region_foursplit", SKEY, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0); - #ifdef __APPLE__ - WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_OSKEY, 0); - #endif - WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_CTRL, 0); + + WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0); -- cgit v1.2.3 From 9a25d22326060395b09cd6d81d7b4ac080bafb8f Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sat, 12 Sep 2009 19:54:39 +0000 Subject: 2.5 filebrowser Appending and Linking * Linking Operator, invokes filebrowser for Append/Link * Separated the append/link function into three parts: ** BLO_library_append_begin finds main for appending ** BLO_library_append_named_part appends one Object,Group, Material, ... ** BLO_library_append_end actually reads and expands the libraries NOTE 1: I also changed the returned properties for the filebrowser operators to the following convention: "path" - the full path to a file or directory, means what is in directory + filename buttons in filebrowser "directory" - the content of the directory button in filebrowser "filename" - the content of the filename button in filebrowser Usually only path should be required, but in some cases it might be more convenient to retrieve the parts separately. Ton, Brecht: If you have time to take a look, let me know if anything needs to be fixed. --- projectfiles_vc9/blender/loader/BLO_loader.vcproj | 234 ++++++------- release/io/export_ply.py | 2 +- release/ui/space_info.py | 3 + source/blender/blenkernel/BKE_library.h | 1 + source/blender/blenkernel/intern/library.c | 11 + source/blender/blenloader/BLO_readfile.h | 19 +- source/blender/blenloader/intern/readfile.c | 241 ++++++++------ source/blender/editors/curve/editfont.c | 2 +- source/blender/editors/screen/screendump.c | 22 +- source/blender/editors/sound/sound_ops.c | 8 +- source/blender/editors/space_buttons/buttons_ops.c | 6 +- source/blender/editors/space_file/file_ops.c | 30 +- source/blender/editors/space_file/file_panels.c | 6 + source/blender/editors/space_file/filelist.c | 369 ++++++++++++++++++++- source/blender/editors/space_file/filelist.h | 12 +- source/blender/editors/space_file/filesel.c | 49 +-- source/blender/editors/space_file/space_file.c | 5 +- source/blender/editors/space_image/image_ops.c | 20 +- source/blender/editors/space_info/info_ops.c | 10 +- source/blender/editors/space_script/script_edit.c | 8 +- source/blender/editors/space_script/script_ops.c | 2 +- .../editors/space_sequencer/sequencer_add.c | 42 +-- source/blender/editors/space_text/text_ops.c | 16 +- source/blender/makesdna/DNA_space_types.h | 7 +- source/blender/makesrna/RNA_define.h | 1 + source/blender/makesrna/RNA_types.h | 1 + source/blender/makesrna/intern/rna_define.c | 14 + source/blender/windowmanager/WM_api.h | 4 +- .../blender/windowmanager/intern/wm_event_system.c | 10 +- source/blender/windowmanager/intern/wm_operators.c | 207 ++++++++++-- 30 files changed, 993 insertions(+), 369 deletions(-) diff --git a/projectfiles_vc9/blender/loader/BLO_loader.vcproj b/projectfiles_vc9/blender/loader/BLO_loader.vcproj index a8cec5ecf76..e8b155875d0 100644 --- a/projectfiles_vc9/blender/loader/BLO_loader.vcproj +++ b/projectfiles_vc9/blender/loader/BLO_loader.vcproj @@ -469,123 +469,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/release/io/export_ply.py b/release/io/export_ply.py index c293119d3c8..7a3253b2d16 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -242,7 +242,7 @@ class EXPORT_OT_ply(bpy.types.Operator): # to the class instance from the operator settings before calling. __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""), bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True), bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True), bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True), diff --git a/release/ui/space_info.py b/release/ui/space_info.py index 97243f857a6..6b2a457e89d 100644 --- a/release/ui/space_info.py +++ b/release/ui/space_info.py @@ -59,6 +59,9 @@ class INFO_MT_file(bpy.types.Menu): layout.itemO("wm.save_as_mainfile", text="Save As...") layout.itemO("screen.userpref_show", text="User Preferences...") + layout.itemS() + layout.operator_context = "INVOKE_AREA" + layout.itemO("wm.link_append", text="Append or Link") layout.itemS() layout.itemM("INFO_MT_file_import") diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 54722dac910..0e978128cf6 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -77,6 +77,7 @@ void IPOnames_to_pupstring(char **str, char *title, char *extraops, struct ListB void flag_listbase_ids(ListBase *lb, short flag, short value); void flag_all_listbases_ids(short flag, short value); +void recalc_all_library_objects(struct Main *main); void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) ); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 02d92a62b59..da7692d0cdb 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -455,6 +455,17 @@ void flag_all_listbases_ids(short flag, short value) while(a--) flag_listbase_ids(lbarray[a], flag, value); } +void recalc_all_library_objects(struct Main *main) +{ + /* DISPLISTS? */ + Object *ob= main->object.first; + while(ob) { + if(ob->id.lib) { + ob->recalc |= OB_RECALC; + } + ob= ob->id.next; + } +} /* note: MAX_LIBARRAY define should match this code */ int set_listbasepointers(Main *main, ListBase **lb) diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 4fafac29a6f..6e2772efea4 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -36,7 +36,6 @@ extern "C" { struct bScreen; struct direntry; -struct FileList; struct LinkNode; struct Main; struct MemFile; @@ -45,6 +44,7 @@ struct Scene; struct SpaceFile; struct SpaceImaSel; struct UserDef; +struct bContext; typedef struct BlendHandle BlendHandle; @@ -197,12 +197,23 @@ BLO_blendhandle_close( /***/ -char *BLO_gethome(void); +#define GROUP_MAX 32 + int BLO_has_bfile_extension(char *str); -void BLO_library_append(BlendHandle **libfiledata, struct direntry* filelist, int totfile, - char *dir, char* file, short flag, int idcode, struct Main *mainvar, struct Scene *scene, struct ReportList *reports); +/* return ok when a blenderfile, in dir is the filename, + * in group the type of libdata + */ +int BLO_is_a_library(char *path, char *dir, char *group); + +struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, char *dir); +void BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, char *name, int idcode, short flag); +void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag); + +/* deprecated */ +#if 0 void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports); +#endif BlendFileData* blo_read_blendafterruntime(int file, char *name, int actualsize, struct ReportList *reports); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 99285fefb4d..83abd5c2b4d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -113,6 +113,7 @@ #include "BKE_cloth.h" #include "BKE_colortools.h" #include "BKE_constraint.h" +#include "BKE_context.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_deform.h" @@ -1065,6 +1066,46 @@ int BLO_has_bfile_extension(char *str) return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend")||BLI_testextensie(str, ".blend.gz")); } +int BLO_is_a_library(char *path, char *dir, char *group) +{ + /* return ok when a blenderfile, in dir is the filename, + * in group the type of libdata + */ + int len; + char *fd; + + strcpy(dir, path); + len= strlen(dir); + if(len<7) return 0; + if( dir[len-1] != '/' && dir[len-1] != '\\') return 0; + + group[0]= 0; + dir[len-1]= 0; + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + + if(fd==0) return 0; + *fd= 0; + if(BLO_has_bfile_extension(fd+1)) { + /* the last part of the dir is a .blend file, no group follows */ + *fd= '/'; /* put back the removed slash separating the dir and the .blend file name */ + } + else { + char *gp = fd+1; // in case we have a .blend file, gp points to the group + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + if (!fd || !BLO_has_bfile_extension(fd+1)) return 0; + + /* now we know that we are in a blend file and it is safe to + assume that gp actually points to a group */ + if (BLI_streq("Screen", gp)==0) + BLI_strncpy(group, gp, GROUP_MAX); + } + return 1; +} + /* ************** OLD POINTERS ******************* */ static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */ @@ -10729,8 +10770,9 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is } -static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode, short flag) +static void append_named_part(const bContext *C, Main *mainl, FileData *fd, char *name, int idcode, short flag) { + Scene *scene= CTX_data_scene(C); Object *ob; Base *base; BHead *bhead; @@ -10746,9 +10788,9 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n if(strcmp(idname+2, name)==0) { - id= is_yet_read(fd, mainvar, bhead); + id= is_yet_read(fd, mainl, bhead); if(id==NULL) { - read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL); + read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL); } else { printf("append: already linked\n"); @@ -10763,13 +10805,18 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n base= MEM_callocN( sizeof(Base), "app_nam_part"); BLI_addtail(&scene->base, base); - if(id==NULL) ob= mainvar->object.last; + if(id==NULL) ob= mainl->object.last; else ob= (Object *)id; - /* XXX use context to find view3d->lay */ - //if((flag & FILE_ACTIVELAY)) { - // scene->lay; - //} + /* link at active layer (view3d->lay if in context, else scene->lay */ + if((flag & FILE_ACTIVELAY)) { + View3D *v3d = CTX_wm_view3d(C); + if (v3d) { + ob->lay = v3d->layact; + } else { + ob->lay = scene->lay; + } + } base->lay= ob->lay; base->object= ob; ob->id.us++; @@ -10788,6 +10835,12 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n } } +void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, char *name, int idcode, short flag) +{ + FileData *fd= (FileData*)(*bh); + append_named_part(C, mainl, fd, name, idcode, flag); +} + static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) { BHead *bhead; @@ -10810,11 +10863,10 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) /* common routine to append/link something from a library */ -static Library* library_append(Main *mainvar, Scene *scene, char* file, char *dir, int idcode, - int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag) +static Main* library_append_begin(const bContext *C, FileData **fd, char *dir) { + Main *mainvar= CTX_data_main(C); Main *mainl; - Library *curlib; /* make mains */ blo_split_main(&(*fd)->mainlist, mainvar); @@ -10824,19 +10876,69 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di mainl->versionfile= (*fd)->fileversion; /* needed for do_version */ - curlib= mainl->curlib; + return mainl; +} + +Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir) +{ + FileData *fd= (FileData*)(*bh); + return library_append_begin(C, &fd, dir); +} + +static void append_do_cursor(Scene *scene, Library *curlib, short flag) +{ + Base *centerbase; + Object *ob; + float *curs, centerloc[3], vec[3], min[3], max[3]; + int count= 0; + + /* when not linking (appending)... */ + if(flag & FILE_LINK) + return; + + /* we're not appending at cursor */ + if((flag & FILE_ATCURSOR) == 0) + return; - if(totsel==0) { - append_named_part(*fd, mainl, scene, file, idcode, flag); + /* find the center of everything appended */ + INIT_MINMAX(min, max); + centerbase= (scene->base.first); + while(centerbase) { + if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) { + VECCOPY(vec, centerbase->object->loc); + DO_MINMAX(vec, min, max); + count++; + } + centerbase= centerbase->next; } - else { - int a; - for(a=0; acursor; + VECSUB(centerloc,curs,centerloc); + + /* now translate the center of the objects */ + centerbase= (scene->base.first); + while(centerbase) { + if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) { + ob= centerbase->object; + ob->loc[0] += centerloc[0]; + ob->loc[1] += centerloc[1]; + ob->loc[2] += centerloc[2]; } + centerbase= centerbase->next; } +} + +static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag) +{ + Main *mainvar= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); /* make main consistant */ expand_main(*fd, mainl); @@ -10844,6 +10946,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di /* do this when expand found other libs */ read_libraries(*fd, &(*fd)->mainlist); + /* make the lib path relative if required */ if(flag & FILE_STRINGCODE) { /* use the full path, this could have been read by other library even */ @@ -10866,7 +10969,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di if (flag & FILE_LINK) { give_base_to_objects(mainvar, scene, NULL, 0); } else { - give_base_to_objects(mainvar, scene, curlib, 1); + give_base_to_objects(mainvar, scene, mainl->curlib, 1); } } else { give_base_to_objects(mainvar, scene, NULL, 0); @@ -10882,14 +10985,23 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di *fd = NULL; } - return curlib; + append_do_cursor(scene, mainl->curlib, flag); +} + +void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag) +{ + FileData *fd= (FileData*)(*bh); + library_append_end(C, mainl, &fd, idcode, flag); + *bh= (BlendHandle*)fd; } /* this is a version of BLO_library_append needed by the BPython API, so * scripts can load data from .blend files -- see Blender.Library module.*/ /* append to scene */ /* this should probably be moved into the Python code anyway */ - +/* tentatively removed, Python should be able to use the split functions too: */ +/* BLO_library_append_begin, BLO_library_append_end, BLO_library_append_named_part */ +#if 0 void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports) { @@ -10906,88 +11018,7 @@ void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, *bh= (BlendHandle*)fd; } - -/* append to scene */ -void BLO_library_append(BlendHandle** bh, struct direntry* filelist, int totfile, - char *dir, char* file, short flag, int idcode, Main *mainvar, Scene *scene, ReportList *reports) -{ - FileData *fd= (FileData*)(*bh); - Library *curlib; - Base *centerbase; - Object *ob; - int a, totsel=0; - - /* are there files selected? */ - for(a=0; areports= reports; - curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag ); - if(fd) fd->reports= NULL; - - *bh= (BlendHandle*)fd; - - /* when not linking (appending)... */ - if((flag & FILE_LINK)==0) { - if(flag & FILE_ATCURSOR) { - float *curs, centerloc[3], vec[3], min[3], max[3]; - int count= 0; - - INIT_MINMAX(min, max); - - centerbase= (scene->base.first); - while(centerbase) { - if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) { - VECCOPY(vec, centerbase->object->loc); - DO_MINMAX(vec, min, max); - count++; - } - centerbase= centerbase->next; - } - if(count) { - centerloc[0]= (min[0]+max[0])/2; - centerloc[1]= (min[1]+max[1])/2; - centerloc[2]= (min[2]+max[2])/2; - curs = scene->cursor; - VECSUB(centerloc,curs,centerloc); - - centerbase= (scene->base.first); - while(centerbase) { - if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) { - ob= centerbase->object; - ob->loc[0] += centerloc[0]; - ob->loc[1] += centerloc[1]; - ob->loc[2] += centerloc[2]; - } - centerbase= centerbase->next; - } - } - } - } -} +#endif /* ************* READ LIBRARY ************** */ diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index a9736f3f88d..868c5902670 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -417,7 +417,7 @@ void FONT_OT_file_paste(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL); } /******************* paste buffer operator ********************/ diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 5ae1bdf84aa..fb3da4a5353 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -73,24 +73,24 @@ static int screenshot_exec(bContext *C, wmOperator *op) if(scd && scd->dumprect) { Scene *scene= CTX_data_scene(C); ImBuf *ibuf; - char filename[FILE_MAX]; + char path[FILE_MAX]; - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "path", path); - strcpy(G.ima, filename); - BLI_convertstringcode(filename, G.sce); + strcpy(G.ima, path); + BLI_convertstringcode(path, G.sce); /* BKE_add_image_extension() checks for if extension was already set */ if(scene->r.scemode & R_EXTENSION) - if(strlen(filename)r.imtype); + if(strlen(path)r.imtype); ibuf= IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0, 0); ibuf->rect= scd->dumprect; if(scene->r.planes == 8) IMB_cspace(ibuf, rgb_to_bw); - BKE_write_ibuf(scene, ibuf, filename, scene->r.imtype, scene->r.subimtype, scene->r.quality); + BKE_write_ibuf(scene, ibuf, path, scene->r.imtype, scene->r.subimtype, scene->r.quality); IMB_freeImBuf(ibuf); @@ -149,10 +149,10 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *event) scd->dumprect= dumprect; op->customdata= scd; - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return screenshot_exec(C, op); - RNA_string_set(op->ptr, "filename", G.ima); + RNA_string_set(op->ptr, "path", G.ima); WM_event_add_fileselect(C, op); @@ -173,7 +173,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot) ot->flag= 0; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL); RNA_def_boolean(ot->srna, "full", 1, "Full Screen", ""); } @@ -327,7 +327,7 @@ void SCREEN_OT_screencast(wmOperatorType *ot) ot->flag= 0; - RNA_def_property(ot->srna, "filename", PROP_STRING, PROP_FILEPATH); + RNA_def_property(ot->srna, "path", PROP_STRING, PROP_FILEPATH); RNA_def_boolean(ot->srna, "full", 1, "Full Screen", ""); } diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 303ca0eaefd..1121a3bcbcd 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -66,13 +66,13 @@ static int open_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char path[FILE_MAX]; bSound *sound; AUD_SoundInfo info; - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "path", path); - sound = sound_new_file(CTX_data_main(C), filename); + sound = sound_new_file(CTX_data_main(C), path); if (sound==NULL || sound->handle == NULL) { BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); @@ -114,7 +114,7 @@ void SOUND_OT_open(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory."); } diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 481c2d6cfc3..9b335b86163 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -1069,10 +1069,10 @@ static int file_browse_exec(bContext *C, wmOperator *op) FileBrowseOp *fbo= op->customdata; char *str; - if (RNA_property_is_set(op->ptr, "filename")==0 || fbo==NULL) + if (RNA_property_is_set(op->ptr, "path")==0 || fbo==NULL) return OPERATOR_CANCELLED; - str= RNA_string_get_alloc(op->ptr, "filename", 0, 0); + str= RNA_string_get_alloc(op->ptr, "path", 0, 0); RNA_property_string_set(&fbo->ptr, fbo->prop, str); RNA_property_update(C, &fbo->ptr, fbo->prop); MEM_freeN(str); @@ -1128,6 +1128,6 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot) ot->cancel= file_browse_cancel; /* properties */ - WM_operator_properties_filesel(ot, 0); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL); } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index e1a6e346ce2..5d3c2c766a3 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -520,9 +520,11 @@ int file_exec(bContext *C, wmOperator *unused) wmOperator *op= sfile->op; sfile->op = NULL; + RNA_string_set(op->ptr, "filename", sfile->params->file); BLI_strncpy(name, sfile->params->dir, sizeof(name)); + RNA_string_set(op->ptr, "directory", name); strcat(name, sfile->params->file); - RNA_string_set(op->ptr, "filename", name); + RNA_string_set(op->ptr, "path", name); /* some ops have multiple files to select */ { @@ -872,11 +874,13 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot) int file_filenum_exec(bContext *C, wmOperator *op) { SpaceFile *sfile= CTX_wm_space_file(C); + ScrArea *sa= CTX_wm_area(C); int inc = RNA_int_get(op->ptr, "increment"); if(sfile->params && (inc != 0)) { BLI_newname(sfile->params->file, inc); - WM_event_add_notifier(C, NC_WINDOW, NULL); + ED_area_tag_redraw(sa); + // WM_event_add_notifier(C, NC_WINDOW, NULL); } return OPERATOR_FINISHED; @@ -916,6 +920,24 @@ int file_rename_exec(bContext *C, wmOperator *op) } +int file_rename_poll(bContext *C) +{ + int poll = ED_operator_file_active(C); + SpaceFile *sfile= CTX_wm_space_file(C); + + if (sfile && sfile->params) { + if (sfile->params->active_file < 0) { + poll= 0; + } else { + char dir[FILE_MAX], group[FILE_MAX]; + if (filelist_islibrary(sfile->files, dir, group)) poll= 0; + } + } + else + poll= 0; + return poll; +} + void FILE_OT_rename(struct wmOperatorType *ot) { /* identifiers */ @@ -924,7 +946,7 @@ void FILE_OT_rename(struct wmOperatorType *ot) /* api callbacks */ ot->exec= file_rename_exec; - ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ + ot->poll= file_rename_poll; } @@ -938,6 +960,8 @@ int file_delete_poll(bContext *C) if (sfile->params->active_file < 0) { poll= 0; } else { + char dir[FILE_MAX], group[FILE_MAX]; + if (filelist_islibrary(sfile->files, dir, group)) poll= 0; file = filelist_file(sfile->files, sfile->params->active_file); if (file && S_ISDIR(file->type)) poll= 0; } diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 24c3f9b4ca1..2d351016893 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -181,6 +181,12 @@ static void file_panel_operator(const bContext *C, Panel *pa) RNA_STRUCT_BEGIN(op->ptr, prop) { if(strcmp(RNA_property_identifier(prop), "rna_type") == 0) continue; + if(strcmp(RNA_property_identifier(prop), "type") == 0) + continue; + if(strcmp(RNA_property_identifier(prop), "path") == 0) + continue; + if(strcmp(RNA_property_identifier(prop), "directory") == 0) + continue; if(strcmp(RNA_property_identifier(prop), "filename") == 0) continue; if(strcmp(RNA_property_identifier(prop), "display") == 0) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 538c1e4fce7..23f24f26dc0 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -60,6 +60,7 @@ #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_report.h" #include "BLO_readfile.h" #include "DNA_space_types.h" @@ -109,7 +110,6 @@ typedef struct FileList { struct direntry *filelist; int *fidx; - int numfiles; int numfiltered; char dir[FILE_MAX]; @@ -118,6 +118,12 @@ typedef struct FileList short hide_dot; unsigned int filter; short changed; + + struct BlendHandle *libfiledata; + short hide_parent; + + void (*read)(struct FileList *); + ListBase loadimages; ListBase threads; } FileList; @@ -277,12 +283,20 @@ static int compare_extension(const void *a1, const void *a2) { void filelist_filter(FileList* filelist) { + /* char dir[FILE_MAX], group[GROUP_MAX]; XXXXX */ int num_filtered = 0; int i, j; if (!filelist->filelist) return; + /* XXXXX TODO: check if the filter can be handled outside the filelist + if ( ( (filelist->type == FILE_LOADLIB) && BIF_filelist_islibrary(filelist, dir, group)) + || (filelist->type == FILE_MAIN) ) { + filelist->filter = 0; + } + */ + if (!filelist->filter) { if (filelist->fidx) { MEM_freeN(filelist->fidx); @@ -438,23 +452,29 @@ void folderlist_free(ListBase* folderlist) folderlist= NULL; } +static void filelist_read_main(struct FileList* filelist); +static void filelist_read_library(struct FileList* filelist); +static void filelist_read_dir(struct FileList* filelist); + //------------------FILELIST------------------------// -struct FileList* filelist_new() +struct FileList* filelist_new(short type) { FileList* p = MEM_callocN( sizeof(FileList), "filelist" ); - return p; -} - -struct FileList* filelist_copy(struct FileList* filelist) -{ - FileList* p = filelist_new(); - BLI_strncpy(p->dir, filelist->dir, FILE_MAX); - p->filelist = NULL; - p->fidx = NULL; + switch(type) { + case FILE_MAIN: + p->read = filelist_read_main; + break; + case FILE_LOADLIB: + p->read = filelist_read_library; + break; + default: + p->read = filelist_read_dir; + } return p; } + void filelist_free(struct FileList* filelist) { int i; @@ -493,6 +513,18 @@ void filelist_free(struct FileList* filelist) filelist->hide_dot =0; } +void filelist_freelib(struct FileList* filelist) +{ + if(filelist->libfiledata) + BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= 0; +} + +struct BlendHandle *filelist_lib(struct FileList* filelist) +{ + return filelist->libfiledata; +} + int filelist_numfiles(struct FileList* filelist) { return filelist->numfiltered; @@ -733,16 +765,16 @@ void filelist_setfilter(struct FileList* filelist, unsigned int filter) filelist->filter = filter; } -void filelist_readdir(struct FileList* filelist) +static void filelist_read_dir(struct FileList* filelist) { char wdir[FILE_MAX]; - if (!filelist) return; + filelist->fidx = 0; filelist->filelist = 0; BLI_getwdN(wdir); - + BLI_cleanup_dir(G.sce, filelist->dir); BLI_hide_dot_files(filelist->hide_dot); filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist)); @@ -750,12 +782,50 @@ void filelist_readdir(struct FileList* filelist) chdir(wdir); filelist_setfiletypes(filelist, G.have_quicktime); filelist_filter(filelist); - + if (!filelist->threads.first) { BLI_init_threads(&filelist->threads, exec_loadimages, 2); } } +static void filelist_read_main(struct FileList* filelist) +{ + if (!filelist) return; + filelist_from_main(filelist); +} + +static void filelist_read_library(struct FileList* filelist) +{ + if (!filelist) return; + BLI_cleanup_dir(G.sce, filelist->dir); + filelist_from_library(filelist); + if(!filelist->libfiledata) { + int num; + struct direntry *file; + filelist_read_dir(filelist); + file = filelist->filelist; + for(num=0; numnumfiles; num++, file++) { + if(BLO_has_bfile_extension(file->relname)) { + char name[FILE_MAXDIR+FILE_MAXFILE]; + + BLI_strncpy(name, filelist->dir, sizeof(name)); + strcat(name, file->relname); + + /* prevent current file being used as acceptable dir */ + if (BLI_streq(G.main->name, name)==0) { + file->type &= ~S_IFMT; + file->type |= S_IFDIR; + } + } + } + } +} + +void filelist_readdir(struct FileList* filelist) +{ + filelist->read(filelist); +} + int filelist_empty(struct FileList* filelist) { return filelist->filelist == 0; @@ -937,3 +1007,272 @@ void filelist_sort(struct FileList* filelist, short sort) filelist_filter(filelist); } + + +int filelist_islibrary(struct FileList* filelist, char* dir, char* group) +{ + return BLO_is_a_library(filelist->dir, dir, group); +} + +static int groupname_to_code(char *group) +{ + char buf[32]; + char *lslash; + + BLI_strncpy(buf, group, 31); + lslash= BLI_last_slash(buf); + if (lslash) + lslash[0]= '\0'; + + return BLO_idcode_from_name(buf); +} + +void filelist_from_library(struct FileList* filelist) +{ + LinkNode *l, *names, *previews; + struct ImBuf* ima; + int ok, i, nnames, idcode; + char filename[FILE_MAXDIR+FILE_MAXFILE]; + char dir[FILE_MAX], group[GROUP_MAX]; + + /* name test */ + ok= filelist_islibrary(filelist, dir, group); + if (!ok) { + /* free */ + if(filelist->libfiledata) BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= 0; + return; + } + + BLI_strncpy(filename, G.sce, sizeof(filename)); // G.sce = last file loaded, for UI + + /* there we go */ + /* for the time being only read filedata when libfiledata==0 */ + if (filelist->libfiledata==0) { + filelist->libfiledata= BLO_blendhandle_from_file(dir); + if(filelist->libfiledata==0) return; + } + + idcode= groupname_to_code(group); + + // memory for strings is passed into filelist[i].relname + // and free'd in freefilelist + previews = NULL; + if (idcode) { + previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode); + names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode); + /* ugh, no rewind, need to reopen */ + BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= BLO_blendhandle_from_file(dir); + + } else { + names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata); + } + + nnames= BLI_linklist_length(names); + + filelist->numfiles= nnames + 1; + filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist)); + memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist)); + + filelist->filelist[0].relname= BLI_strdup(".."); + filelist->filelist[0].type |= S_IFDIR; + + for (i=0, l= names; inext) { + char *blockname= l->link; + + filelist->filelist[i + 1].relname= BLI_strdup(blockname); + if (!idcode) + filelist->filelist[i + 1].type |= S_IFDIR; + } + + if(previews) { + for (i=0, l= previews; inext) { + PreviewImage *img= l->link; + + if (img) { + unsigned int w = img->w[PREVIEW_MIPMAP_LARGE]; + unsigned int h = img->h[PREVIEW_MIPMAP_LARGE]; + unsigned int *rect = img->rect[PREVIEW_MIPMAP_LARGE]; + + /* first allocate imbuf for copying preview into it */ + if (w > 0 && h > 0 && rect) { + ima = IMB_allocImBuf(w, h, 32, IB_rect, 0); + memcpy(ima->rect, rect, w*h*sizeof(unsigned int)); + filelist->filelist[i + 1].image = ima; + filelist->filelist[i + 1].flags = IMAGEFILE; + } + } + } + } + + BLI_linklist_free(names, free); + if (previews) BLI_linklist_free(previews, (void(*)(void*)) MEM_freeN); + + filelist_sort(filelist, FILE_SORT_ALPHA); + + BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change + + filelist->filter = 0; + filelist_filter(filelist); +} + +void filelist_hideparent(struct FileList* filelist, short hide) +{ + filelist->hide_parent = hide; +} + +void filelist_from_main(struct FileList *filelist) +{ + ID *id; + struct direntry *files, *firstlib = NULL; + ListBase *lb; + int a, fake, idcode, ok, totlib, totbl; + + // filelist->type = FILE_MAIN; // XXXXX TODO: add modes to filebrowser + + if(filelist->dir[0]=='/') filelist->dir[0]= 0; + + if(filelist->dir[0]) { + idcode= groupname_to_code(filelist->dir); + if(idcode==0) filelist->dir[0]= 0; + } + + if( filelist->dir[0]==0) { + + /* make directories */ + filelist->numfiles= 23; + filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)); + + for(a=0; anumfiles; a++) { + memset( &(filelist->filelist[a]), 0 , sizeof(struct direntry)); + filelist->filelist[a].type |= S_IFDIR; + } + + filelist->filelist[0].relname= BLI_strdup(".."); + filelist->filelist[2].relname= BLI_strdup("Scene"); + filelist->filelist[3].relname= BLI_strdup("Object"); + filelist->filelist[4].relname= BLI_strdup("Mesh"); + filelist->filelist[5].relname= BLI_strdup("Curve"); + filelist->filelist[6].relname= BLI_strdup("Metaball"); + filelist->filelist[7].relname= BLI_strdup("Material"); + filelist->filelist[8].relname= BLI_strdup("Texture"); + filelist->filelist[9].relname= BLI_strdup("Image"); + filelist->filelist[10].relname= BLI_strdup("Ika"); + filelist->filelist[11].relname= BLI_strdup("Wave"); + filelist->filelist[12].relname= BLI_strdup("Lattice"); + filelist->filelist[13].relname= BLI_strdup("Lamp"); + filelist->filelist[14].relname= BLI_strdup("Camera"); + filelist->filelist[15].relname= BLI_strdup("Ipo"); + filelist->filelist[16].relname= BLI_strdup("World"); + filelist->filelist[17].relname= BLI_strdup("Screen"); + filelist->filelist[18].relname= BLI_strdup("VFont"); + filelist->filelist[19].relname= BLI_strdup("Text"); + filelist->filelist[20].relname= BLI_strdup("Armature"); + filelist->filelist[21].relname= BLI_strdup("Action"); + filelist->filelist[22].relname= BLI_strdup("NodeTree"); + filelist_sort(filelist, FILE_SORT_ALPHA); + } + else { + + /* make files */ + idcode= groupname_to_code(filelist->dir); + + lb= wich_libbase(G.main, idcode ); + if(lb==0) return; + + id= lb->first; + filelist->numfiles= 0; + while(id) { + /* XXXXX TODO: the selection of the ipo blocktype might go somewhere else? + if(filelist->has_func && idcode==ID_IP) { + if(filelist->ipotype== ((Ipo *)id)->blocktype) filelist->numfiles++; + } + else */ + if (!filelist->hide_dot || id->name[2] != '.') { + filelist->numfiles++; + } + + id= id->next; + } + + /* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */ + if (!filelist->hide_parent) filelist->numfiles+= 1; + filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)); + + files = filelist->filelist; + + if (!filelist->hide_parent) { + memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry)); + filelist->filelist[0].relname= BLI_strdup(".."); + filelist->filelist[0].type |= S_IFDIR; + + files++; + } + + id= lb->first; + totlib= totbl= 0; + + while(id) { +#if 0 + // XXXXX TODO: this is deprecated, checks for correct IPO block? + ok= 0; + if(filelist->has_func && idcode==ID_IP) { + if(filelist->ipotype== ((Ipo *)id)->blocktype) ok= 1; + } + else ok= 1; +#endif + ok = 1; + if(ok) { + if (!filelist->hide_dot || id->name[2] != '.') { + memset( files, 0 , sizeof(struct direntry)); + if(id->lib==NULL) + files->relname= BLI_strdup(id->name+2); + else { + files->relname= MEM_mallocN(FILE_MAXDIR+FILE_MAXFILE+32, "filename for lib"); + sprintf(files->relname, "%s | %s", id->lib->name, id->name+2); + } + /* files->type |= S_IFDIR; */ +#if 0 // XXXXX TODO show the selection status of the objects + if(!filelist->has_func) { /* F4 DATA BROWSE */ + if(idcode==ID_OB) { + if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE; + } + else if(idcode==ID_SCE) { + if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE; + } + } +#endif + files->nr= totbl+1; + files->poin= id; + fake= id->flag & LIB_FAKEUSER; + if(idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) { + files->flags |= IMAGEFILE; + } + if(id->lib && fake) sprintf(files->extra, "LF %d", id->us); + else if(id->lib) sprintf(files->extra, "L %d", id->us); + else if(fake) sprintf(files->extra, "F %d", id->us); + else sprintf(files->extra, " %d", id->us); + + if(id->lib) { + if(totlib==0) firstlib= files; + totlib++; + } + + files++; + } + totbl++; + } + + id= id->next; + } + + /* only qsort of library blocks */ + if(totlib>1) { + qsort(firstlib, totlib, sizeof(struct direntry), compare_name); + } + } + filelist->filter = 0; + filelist_filter(filelist); +} + diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index dd3c2c766c1..a8d909f899e 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -42,12 +42,13 @@ struct FolderList; struct direntry; struct BlendHandle; struct Scene; +struct Main; struct rcti; +struct ReportList; -struct FileList * filelist_new(); +struct FileList * filelist_new(short type); void filelist_init_icons(); void filelist_free_icons(); -struct FileList * filelist_copy(struct FileList* filelist); int filelist_find(struct FileList* filelist, char *file); void filelist_free(struct FileList* filelist); void filelist_sort(struct FileList* filelist, short sort); @@ -71,6 +72,13 @@ int filelist_empty(struct FileList* filelist); void filelist_parent(struct FileList* filelist); void filelist_setfiletypes(struct FileList* filelist, short has_quicktime); + +int filelist_islibrary (struct FileList* filelist, char* dir, char* group); +void filelist_from_main(struct FileList* filelist); +void filelist_from_library(struct FileList* filelist); +void filelist_freelib(struct FileList* filelist); +void filelist_hideparent(struct FileList* filelist, short hide); + struct ListBase * folderlist_new(); void folderlist_free(struct ListBase* folderlist); void folderlist_popdir(struct ListBase* folderlist, char *dir); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index f300505933f..b0bd3a9a5e7 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -123,6 +123,22 @@ short ED_fileselect_set_params(SpaceFile *sfile) /* set the parameters from the operator, if it exists */ if (op) { BLI_strncpy(params->title, op->type->name, sizeof(params->title)); + + params->type = RNA_int_get(op->ptr, "type"); + + if (RNA_property_is_set(op->ptr, "path")) { + RNA_string_get(op->ptr, "path", name); + if (params->type == FILE_LOADLIB) { + BLI_strncpy(params->dir, name, sizeof(params->dir)); + BLI_cleanup_dir(G.sce, params->dir); + } else { + /* if operator has path set, use it, otherwise keep the last */ + BLI_convertstringcode(name, G.sce); + BLI_split_dirfile(name, dir, file); + BLI_strncpy(params->file, file, sizeof(params->file)); + BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ + } + } params->filter = 0; params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0; params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0; @@ -136,21 +152,18 @@ short ED_fileselect_set_params(SpaceFile *sfile) if (params->filter != 0) params->flag |= FILE_FILTER; - params->flag |= FILE_HIDE_DOT; - + if (params->type == FILE_LOADLIB) { + params->flag |= FILE_HIDE_DOT; + params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0; + params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; + params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; + } + if(params->filter & (IMAGEFILE|MOVIEFILE)) params->display= FILE_IMGDISPLAY; else params->display= FILE_SHORTDISPLAY; - /* if operator has path set, use it, otherwise keep the last */ - if (RNA_property_is_set(op->ptr, "filename")) { - RNA_string_get(op->ptr, "filename", name); - BLI_convertstringcode(name, G.sce); - BLI_split_dirfile(name, dir, file); - BLI_strncpy(params->file, file, sizeof(params->file)); - BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ - } } else { /* default values, if no operator */ params->flag |= FILE_HIDE_DOT; @@ -357,19 +370,15 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar void file_change_dir(struct SpaceFile *sfile) { if (sfile->params) { - if (BLI_exists(sfile->params->dir)) { - filelist_setdir(sfile->files, sfile->params->dir); + filelist_setdir(sfile->files, sfile->params->dir); - if(folderlist_clear_next(sfile)) - folderlist_free(sfile->folders_next); + if(folderlist_clear_next(sfile)) + folderlist_free(sfile->folders_next); - folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + folderlist_pushdir(sfile->folders_prev, sfile->params->dir); - filelist_free(sfile->files); - sfile->params->active_file = -1; - } else { - BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX); - } + filelist_free(sfile->files); + sfile->params->active_file = -1; } } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 722fa475727..f71defe3949 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -119,6 +119,7 @@ static void file_free(SpaceLink *sl) SpaceFile *sfile= (SpaceFile *) sl; if(sfile->files) { + filelist_freelib(sfile->files); filelist_free(sfile->files); MEM_freeN(sfile->files); sfile->files= NULL; @@ -165,7 +166,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ sfilen->op = NULL; /* file window doesn't own operators */ - sfilen->files = filelist_new(); + sfilen->files = filelist_new(sfileo->params->type); if(sfileo->folders_prev) sfilen->folders_prev = MEM_dupallocN(sfileo->folders_prev); @@ -190,7 +191,7 @@ static void file_refresh(const bContext *C, ScrArea *sa) if (!sfile->folders_prev) sfile->folders_prev = folderlist_new(); if (!sfile->files) { - sfile->files = filelist_new(); + sfile->files = filelist_new(params->type); file_change_dir(sfile); params->active_file = -1; // added this so it opens nicer (ton) } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index bee06e6892f..806d0d7ce52 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -609,7 +609,7 @@ static const EnumPropertyItem image_file_type_items[] = { static void image_filesel(bContext *C, wmOperator *op, const char *path) { - RNA_string_set(op->ptr, "filename", path); + RNA_string_set(op->ptr, "path", path); WM_event_add_fileselect(C, op); } @@ -623,7 +623,7 @@ static int open_exec(bContext *C, wmOperator *op) Image *ima= NULL; char str[FILE_MAX]; - RNA_string_get(op->ptr, "filename", str); + RNA_string_get(op->ptr, "path", str); ima= BKE_add_image_file(str, scene->r.cfra); if(!ima) @@ -640,7 +640,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) SpaceImage *sima= CTX_wm_space_image(C); char *path= (sima->image)? sima->image->name: U.textudir; - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return open_exec(C, op); image_filesel(C, op, path); @@ -663,7 +663,7 @@ void IMAGE_OT_open(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL); } /******************** replace image operator ********************/ @@ -676,7 +676,7 @@ static int replace_exec(bContext *C, wmOperator *op) if(!sima->image) return OPERATOR_CANCELLED; - RNA_string_get(op->ptr, "filename", str); + RNA_string_get(op->ptr, "path", str); BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */ BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD); @@ -693,7 +693,7 @@ static int replace_invoke(bContext *C, wmOperator *op, wmEvent *event) if(!sima->image) return OPERATOR_CANCELLED; - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return replace_exec(C, op); image_filesel(C, op, path); @@ -716,7 +716,7 @@ void IMAGE_OT_replace(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL); } /******************** save image as operator ********************/ @@ -801,7 +801,7 @@ static int save_as_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; sima->imtypenr= RNA_enum_get(op->ptr, "file_type"); - RNA_string_get(op->ptr, "filename", str); + RNA_string_get(op->ptr, "path", str); save_image_doit(C, sima, scene, op, str); @@ -815,7 +815,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event) ImBuf *ibuf= ED_space_image_buffer(sima); Scene *scene= CTX_data_scene(C); - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return save_as_exec(C, op); if(!ima) @@ -861,7 +861,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot) /* properties */ RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as."); - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL); } /******************** save image operator ********************/ diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 640c968742c..f4d8682b8ea 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -300,11 +300,11 @@ void FILE_OT_report_missing_files(wmOperatorType *ot) static int find_missing_files_exec(bContext *C, wmOperator *op) { - char *filename; + char *path; - filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0); - findMissingFiles(filename); - MEM_freeN(filename); + path= RNA_string_get_alloc(op->ptr, "path", NULL, 0); + findMissingFiles(path); + MEM_freeN(path); return OPERATOR_FINISHED; } @@ -330,7 +330,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - WM_operator_properties_filesel(ot, 0); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL); } #if 0 diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index 88b8dccc6c9..c17793b28f8 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -64,10 +64,10 @@ static int run_pyfile_exec(bContext *C, wmOperator *op) ARegion *ar= CTX_wm_region(C); - char filename[512]; - RNA_string_get(op->ptr, "filename", filename); + char path[512]; + RNA_string_get(op->ptr, "path", path); #ifndef DISABLE_PYTHON - if(BPY_run_python_script(C, filename, NULL, op->reports)) { + if(BPY_run_python_script(C, path, NULL, op->reports)) { ED_region_tag_redraw(ar); return OPERATOR_FINISHED; } @@ -85,7 +85,7 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot) ot->exec= run_pyfile_exec; ot->poll= ED_operator_areaactive; - RNA_def_string_file_path(ot->srna, "filename", "", 512, "Filename", ""); + RNA_def_string_file_path(ot->srna, "path", "", 512, "Path", ""); } static int run_ui_scripts_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c index aa35ba54b7f..270cc1ffd8f 100644 --- a/source/blender/editors/space_script/script_ops.c +++ b/source/blender/editors/space_script/script_ops.c @@ -68,7 +68,7 @@ void script_keymap(wmWindowManager *wm) ListBase *keymap= WM_keymap_listbase(wm, "Script", SPACE_SCRIPT, 0); /* TODO - this is just while we have no way to load a text datablock */ - RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "filename", "test.py"); + RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "path", "test.py"); WM_keymap_add_item(keymap, "SCRIPT_OT_python_run_ui_scripts", PKEY, KM_PRESS, KM_SHIFT, 0); } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 8a1b3bf3465..bd5259ddb52 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -289,7 +289,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) Editing *ed= seq_give_editing(scene, TRUE); struct anim *an; - char filename[FILE_MAX]; + char path[FILE_MAX]; Sequence *seq, *soundseq=NULL; /* generic strip vars */ Strip *strip; @@ -301,12 +301,12 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) channel= RNA_int_get(op->ptr, "channel"); sound = RNA_boolean_get(op->ptr, "sound"); - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "path", path); - an = openanim(filename, IB_rect); + an = openanim(path, IB_rect); if (an==NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Filename \"%s\" could not be loaded as a movie", filename); + BKE_reportf(op->reports, RPT_ERROR, "File \"%s\" could not be loaded as a movie", path); return OPERATOR_CANCELLED; } @@ -323,7 +323,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); - BLI_split_dirfile_basic(filename, strip->dir, se->name); + BLI_split_dirfile_basic(path, strip->dir, se->name); RNA_string_get(op->ptr, "name", seq->name); @@ -332,7 +332,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) if(sound) { - soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, filename); + soundseq = sequencer_add_sound_strip(C, NULL, start_frame, channel+1, path); if(soundseq != NULL) RNA_string_get(op->ptr, "name", soundseq->name); } @@ -376,7 +376,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie"); } @@ -384,7 +384,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) /* add sound operator */ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char path[FILE_MAX]; Scene *scene= CTX_data_scene(C); Sequence *seq; /* generic strip vars */ int start_frame, channel; /* operator props */ @@ -392,9 +392,9 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op) start_frame= RNA_int_get(op->ptr, "start_frame"); channel= RNA_int_get(op->ptr, "channel"); - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "path", path); - seq = sequencer_add_sound_strip(C, op, start_frame, channel, filename); + seq = sequencer_add_sound_strip(C, op, start_frame, channel, path); if(seq == NULL) return OPERATOR_CANCELLED; @@ -442,7 +442,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory."); } @@ -455,7 +455,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) int tot_images; - char filename[FILE_MAX]; + char path[FILE_MAX]; Sequence *seq; /* generic strip vars */ Strip *strip; @@ -466,14 +466,14 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) start_frame= RNA_int_get(op->ptr, "start_frame"); channel= RNA_int_get(op->ptr, "channel"); - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "path", path); seq = alloc_sequence(ed->seqbasep, start_frame, channel); seq->type= SEQ_IMAGE; /* basic defaults */ seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); - BLI_split_dirfile_basic(filename, strip->dir, NULL); + BLI_split_dirfile_basic(path, strip->dir, NULL); tot_images= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); @@ -490,7 +490,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) RNA_END; } else { - BLI_split_dirfile_basic(filename, NULL, se->name); + BLI_split_dirfile_basic(path, NULL, se->name); } RNA_string_get(op->ptr, "name", seq->name); @@ -538,7 +538,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); @@ -606,15 +606,15 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); if (seq->type==SEQ_PLUGIN) { - char filename[FILE_MAX]; - RNA_string_get(op->ptr, "filename", filename); + char path[FILE_MAX]; + RNA_string_get(op->ptr, "path", path); - sh.init_plugin(seq, filename); + sh.init_plugin(seq, path); if(seq->plugin==NULL) { BLI_remlink(ed->seqbasep, seq); seq_free_sequence(scene, seq); - BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", filename); + BKE_reportf(op->reports, RPT_ERROR, "Sequencer plugin \"%s\" could not load.", path); return OPERATOR_CANCELLED; } } @@ -673,7 +673,7 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, 0); + WM_operator_properties_filesel(ot, 0, FILE_SPECIAL); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME); RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 3411d9114df..3568f50dfe1 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -192,7 +192,7 @@ static int open_exec(bContext *C, wmOperator *op) Text *text; char str[FILE_MAX]; - RNA_string_get(op->ptr, "filename", str); + RNA_string_get(op->ptr, "path", str); text= add_text(str, G.sce); @@ -211,10 +211,10 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) Text *text= CTX_data_edit_text(C); char *path= (text && text->name)? text->name: G.sce; - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return open_exec(C, op); - RNA_string_set(op->ptr, "filename", path); + RNA_string_set(op->ptr, "path", path); WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; @@ -233,7 +233,7 @@ void TEXT_OT_open(wmOperatorType *ot) ot->poll= text_new_poll; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL); } /******************* reload operator *********************/ @@ -420,7 +420,7 @@ static int save_as_exec(bContext *C, wmOperator *op) if(!text) return OPERATOR_CANCELLED; - RNA_string_get(op->ptr, "filename", str); + RNA_string_get(op->ptr, "path", str); if(text->name) MEM_freeN(text->name); text->name= BLI_strdup(str); @@ -438,7 +438,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event) Text *text= CTX_data_edit_text(C); char *str; - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return save_as_exec(C, op); if(text->name) @@ -448,7 +448,7 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event) else str= G.sce; - RNA_string_set(op->ptr, "filename", str); + RNA_string_set(op->ptr, "path", str); WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; @@ -467,7 +467,7 @@ void TEXT_OT_save_as(wmOperatorType *ot) ot->poll= text_edit_poll; /* properties */ - WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE|PYSCRIPTFILE, FILE_SPECIAL); } /******************* run script operator *********************/ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 6fdc3a7787b..5c1b363aa39 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -154,24 +154,23 @@ typedef struct FileSelectParams { char dir[240]; /* directory */ char file[80]; /* file */ - short flag; /* settings for filter, hiding files and display mode */ + short type; /* XXXXX for now store type here, should be moved to the operator */ + short flag; /* settings for filter, hiding dots files,... */ short sort; /* sort order */ short display; /* display mode flag */ short filter; /* filter when (flags & FILE_FILTER) is true */ /* XXX - temporary, better move to filelist */ short active_bookmark; - short pad; int active_file; int selstate; + /* short /* XXX --- still unused -- */ short f_fp; /* show font preview */ short menu; /* currently selected option in pupmenu */ char fp_str[8]; /* string to use for font preview */ - char *pupmenu; /* allows menu for save options - result stored in menup */ - /* XXX --- end unused -- */ } FileSelectParams; diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 42c5343dbff..595562503aa 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -83,6 +83,7 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont, const char *identifier PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); +PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description); void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc); diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index c6fed5cd8e6..e7fe86afd03 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -89,6 +89,7 @@ typedef enum PropertySubType { /* strings */ PROP_FILEPATH = 1, PROP_DIRPATH = 2, + PROP_FILENAME = 3, /* numbers */ PROP_UNSIGNED = 13, diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 8d05cbde74c..6bca237e02f 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2113,6 +2113,20 @@ PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *ide return prop; } +PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, + const char *ui_name, const char *ui_description) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME); + if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen); + if(default_value) RNA_def_property_string_default(prop, default_value); + RNA_def_property_ui_text(prop, ui_name, ui_description); + + return prop; +} + PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description) { diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 544804b26d6..6610c5d8931 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -139,7 +139,7 @@ void WM_event_window_timer_sleep(struct wmWindow *win, struct wmTimer *timer, i int WM_menu_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* invoke callback, confirm menu + exec */ int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event); - /* invoke callback, file selector "filename" unset + exec */ + /* invoke callback, file selector "path" unset + exec */ int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* poll callback, context checks */ int WM_operator_winactive (struct bContext *C); @@ -169,7 +169,7 @@ int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int con void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_free(struct PointerRNA *ptr); -void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter); +void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type); /* operator as a python command (resultuing string must be free'd) */ char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 3c03d24ca93..79441f33610 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -895,9 +895,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa switch(event->val) { case EVT_FILESELECT_OPEN: case EVT_FILESELECT_FULL_OPEN: - { - char *dir= NULL; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); - + { if(event->val==EVT_FILESELECT_OPEN) ED_area_newspace(C, handler->op_area, SPACE_FILE); else @@ -908,8 +906,6 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa sfile->op= handler->op; ED_fileselect_set_params(sfile); - dir = NULL; - MEM_freeN(path); action= WM_HANDLER_BREAK; } @@ -920,7 +916,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa { /* XXX validate area and region? */ bScreen *screen= CTX_wm_screen(C); - char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); + char *path= RNA_string_get_alloc(handler->op->ptr, "path", NULL, 0); if(screen != handler->filescreen) ED_screen_full_prevspace(C); @@ -1250,7 +1246,7 @@ void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval) } } -/* operator is supposed to have a filled "filename" property */ +/* operator is supposed to have a filled "path" property */ /* optional property: filetype (XXX enum?) */ /* Idea is to keep a handler alive on window queue, owning the operator. diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 37cd424ac18..66724b57ff8 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -46,12 +46,16 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" /*for WM_operator_pystring */ +#include "BLO_readfile.h" + #include "BKE_blender.h" #include "BKE_context.h" +#include "BKE_depsgraph.h" #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_utildefines.h" @@ -496,10 +500,10 @@ int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } -/* op->invoke, opens fileselect if filename property not set, otherwise executes */ +/* op->invoke, opens fileselect if path property not set, otherwise executes */ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) { - if (RNA_property_is_set(op->ptr, "filename")) { + if (RNA_property_is_set(op->ptr, "path")) { return WM_operator_call(C, op); } else { @@ -509,9 +513,11 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) } /* default properties for fileselect */ -void WM_operator_properties_filesel(wmOperatorType *ot, int filter) +void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type) { - RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "Path to file."); + RNA_def_string_file_path(ot->srna, "path", "", FILE_MAX, "FilePath", "Path to file."); + RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "FileName", "Name of the file."); + RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Directory of the file."); RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", ""); RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", ""); @@ -521,6 +527,10 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter) RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", ""); RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); + + RNA_def_int(ot->srna, "type", type, FILE_LOADLIB, FILE_SPECIAL, + "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file.", + FILE_LOADLIB, FILE_SPECIAL); } /* op->poll */ @@ -891,7 +901,7 @@ static void load_set_load_ui(wmOperator *op) static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { - RNA_string_set(op->ptr, "filename", G.sce); + RNA_string_set(op->ptr, "path", G.sce); load_set_load_ui(op); WM_event_add_fileselect(C, op); @@ -901,9 +911,9 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) static int wm_open_mainfile_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char path[FILE_MAX]; - RNA_string_get(op->ptr, "filename", filename); + RNA_string_get(op->ptr, "path", path); load_set_load_ui(op); if(RNA_boolean_get(op->ptr, "load_ui")) @@ -915,7 +925,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op) // do it before for now, but is this correct with multiple windows? WM_event_add_notifier(C, NC_WINDOW, NULL); - WM_read_file(C, filename, op->reports); + WM_read_file(C, path, op->reports); return 0; } @@ -930,11 +940,168 @@ static void WM_OT_open_mainfile(wmOperatorType *ot) ot->exec= wm_open_mainfile_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER); RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file."); } +static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (RNA_property_is_set(op->ptr, "path")) { + return WM_operator_call(C, op); + } + else { + /* XXX solve where to get last linked library from */ + RNA_string_set(op->ptr, "path", G.lib); + WM_event_add_fileselect(C, op); + return OPERATOR_RUNNING_MODAL; + } +} + +static short wm_link_append_flag(wmOperator *op) +{ + short flag = 0; + if (RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT; + if (RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY; + if (RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE; + if (RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK; + return flag; +} + +#define GROUP_MAX 32 + + +static void make_library_local(const char *libname, Main *main) +{ + struct Library *lib; + + /* and now find the latest append lib file */ + lib= main->library.first; + while(lib) { + if (BLI_streq(libname, lib->filename)) break; + lib= lib->id.next; + } + + /* make local */ + if(lib) { + all_local(lib, 1); + /* important we unset, otherwise these object wont + * link into other scenes from this blend file */ + flag_all_listbases_ids(LIB_APPEND_TAG, 0); + } +} + +static int wm_link_append_exec(bContext *C, wmOperator *op) +{ + char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX]; + int idcode; + BlendHandle *bh; + struct Main *main= CTX_data_main(C); + struct Scene *scene= CTX_data_scene(C); + struct Main *mainl= 0; + + struct ScrArea *sa= CTX_wm_area(C); + PropertyRNA *prop; + int totfiles=0; + short flag; + + name[0] = '\0'; + RNA_string_get(op->ptr, "filename", name); + RNA_string_get(op->ptr, "directory", dir); + + if ( BLO_is_a_library(dir, libname, group)==0 ) { + BKE_report(op->reports, RPT_ERROR, "Not a library"); + return OPERATOR_FINISHED; + } else if (group[0]==0) { + BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); + return OPERATOR_FINISHED; + } else if (BLI_streq(main->name, libname)) { + BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library"); + return OPERATOR_FINISHED; + } + + /* check if something is indicated for append/link */ + prop = RNA_struct_find_property(op->ptr, "files"); + if (prop) { + totfiles= RNA_property_collection_length(op->ptr, prop); + if (totfiles == 0) { + if (name[0] == '\0') { + BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); + return OPERATOR_FINISHED; + } + } + } else if (name[0] == '\0') { + BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); + return OPERATOR_FINISHED; + } + + /* now we have or selected, or an indicated file */ + if (RNA_boolean_get(op->ptr, "autoselect")) + scene_deselect_all(scene); + + bh = BLO_blendhandle_from_file(libname); + idcode = BLO_idcode_from_name(group); + + flag = wm_link_append_flag(op); + + if((flag & FILE_LINK)==0) { + /* tag everything, all untagged data can be made local */ + flag_all_listbases_ids(LIB_APPEND_TAG, 1); + } + + /* here appending/linking starts */ + mainl = BLO_library_append_begin(C, &bh, libname); + if (totfiles == 0) { + BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag); + } else { + RNA_BEGIN(op->ptr, itemptr, "files") { + RNA_string_get(&itemptr, "name", name); + BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag); + } + RNA_END; + } + BLO_library_append_end(C, mainl, &bh, idcode, flag); + + /* DISPLISTS? */ + recalc_all_library_objects(main); + + /* Append, rather than linking */ + if ((flag & FILE_LINK)==0) { + make_library_local(main, libname); + } + + /* do we need to do this? */ + if(scene) + DAG_scene_sort(scene); + + BLO_blendhandle_close(bh); + BLI_strncpy(G.lib, dir, FILE_MAX); + + WM_event_add_notifier(C, NC_WINDOW, NULL); + + return OPERATOR_FINISHED; +} + +static void WM_OT_link_append(wmOperatorType *ot) +{ + ot->name= "Link/Append from Library"; + ot->idname= "WM_OT_link_append"; + ot->description= "Link or Append from a Library .blend file"; + + ot->invoke= wm_link_append_invoke; + ot->exec= wm_link_append_exec; + ot->poll= WM_operator_winactive; + + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB); + + RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending."); + RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects."); + RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer."); + RNA_def_boolean(ot->srna, "relative_paths", 1, "Relative Paths", "Store the library path as a relative path to current .blend file."); + + RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); +} + static int wm_recover_last_session_exec(bContext *C, wmOperator *op) { char scestr[FILE_MAX], filename[FILE_MAX]; @@ -987,7 +1154,7 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even BLI_strncpy(name, G.sce, FILE_MAX); untitled(name); - RNA_string_set(op->ptr, "filename", name); + RNA_string_set(op->ptr, "path", name); WM_event_add_fileselect(C, op); @@ -997,20 +1164,20 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even /* function used for WM_OT_save_mainfile too */ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char path[FILE_MAX]; int compress; save_set_compress(op); compress= RNA_boolean_get(op->ptr, "compress"); - if(RNA_property_is_set(op->ptr, "filename")) - RNA_string_get(op->ptr, "filename", filename); + if(RNA_property_is_set(op->ptr, "path")) + RNA_string_get(op->ptr, "path", path); else { - BLI_strncpy(filename, G.sce, FILE_MAX); - untitled(filename); + BLI_strncpy(path, G.sce, FILE_MAX); + untitled(path); } - WM_write_file(C, filename, compress, op->reports); + WM_write_file(C, path, compress, op->reports); WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL); @@ -1027,7 +1194,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) ot->exec= wm_save_as_mainfile_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file."); } @@ -1041,7 +1208,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) BLI_strncpy(name, G.sce, FILE_MAX); untitled(name); - RNA_string_set(op->ptr, "filename", name); + RNA_string_set(op->ptr, "path", name); uiPupMenuSaveOver(C, op, name); return OPERATOR_RUNNING_MODAL; @@ -1057,7 +1224,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) ot->exec= wm_save_as_mainfile_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file."); } @@ -1913,6 +2080,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_exit_blender); WM_operatortype_append(WM_OT_open_recentfile); WM_operatortype_append(WM_OT_open_mainfile); + WM_operatortype_append(WM_OT_link_append); WM_operatortype_append(WM_OT_recover_last_session); WM_operatortype_append(WM_OT_jobs_timer); WM_operatortype_append(WM_OT_save_as_mainfile); @@ -1944,6 +2112,7 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); -- cgit v1.2.3 From 5ac5988448b89ecfdff955499743169c4e8a369e Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sat, 12 Sep 2009 20:18:54 +0000 Subject: Bugfix: Append crashed because of wrong parameters passed. --- source/blender/windowmanager/intern/wm_operators.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 66724b57ff8..54ba18e3df5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1067,7 +1067,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) /* Append, rather than linking */ if ((flag & FILE_LINK)==0) { - make_library_local(main, libname); + make_library_local(libname, main); } /* do we need to do this? */ -- cgit v1.2.3 From 26942cd78936d9f160478aff3d6df11514c9d50d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sat, 12 Sep 2009 20:47:53 +0000 Subject: Pointcache: * Flagging object caches as outdated and use PTCACHE_RESET_OUTDATED as reset event --- source/blender/editors/object/object_edit.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index aaf6ed387c7..e5a8df8cb26 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -334,10 +334,20 @@ void ED_object_exit_editmode(bContext *C, int flag) /* freedata only 0 now on file saves */ if(freedata) { + ListBase pidlist; + PTCacheID *pid; + /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context + + /* flag object caches as outdated */ + BKE_ptcache_ids_from_object(&pidlist, obedit); + 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; + } - BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH); + BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED); /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); -- cgit v1.2.3 From fb599348d39d940d722b79864dd8d171d5ed973a Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 12 Sep 2009 23:56:30 +0000 Subject: * Removed the grey overlapping 'region manipulation' triangles. - They were causing unnecessary visual noise, breaking up the lines of the region edges - Now you can just drag anywhere on a region edge to resize it, like existing area edges - To minimise a region, click once on the region edge, or resize it down to nothing. For minimised regions, a (+) icon will appear, which you can click to restore it to the size it was before it was minimised. --- source/blender/editors/include/ED_screen_types.h | 2 +- source/blender/editors/screen/area.c | 171 ++++++++++++++-------- source/blender/editors/screen/screen_ops.c | 22 ++- source/blender/editors/space_view3d/view3d_draw.c | 2 +- 4 files changed, 118 insertions(+), 79 deletions(-) diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index 72afe7704b4..dcdc9e417e4 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -59,7 +59,7 @@ typedef struct AZone { /* internal */ short do_draw; /* for draw */ - short x1, y1, x2, y2, x3, y3; + short x1, y1, x2, y2; /* for clip */ rcti rect; } AZone; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 2cdb75e28e3..93348d9d556 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -159,14 +159,8 @@ void ED_area_overdraw_flush(bContext *C, ScrArea *sa, ARegion *ar) for(az= sa->actionzones.first; az; az= az->next) { int xs, ys; - if(az->type==AZONE_AREA) { - xs= (az->x1+az->x2)/2; - ys= (az->y1+az->y2)/2; - } - else { - xs= az->x3; - ys= az->y3; - } + xs= (az->x1+az->x2)/2; + ys= (az->y1+az->y2)/2; /* test if inside */ if(BLI_in_rcti(&ar->winrct, xs, ys)) { @@ -196,25 +190,42 @@ static void area_draw_azone(short x1, short y1, short x2, short y2) fdrawline(xmin, ymax-2*dy+1, xmax-2*dx+1, ymin); } + static void region_draw_azone(ScrArea *sa, AZone *az) { - if(az->ar==NULL) return; + GLUquadricObj *qobj = gluNewQuadric(); + short midx = az->x1 + (az->x2 - az->x1)/2; + short midy = az->y1 + (az->y2 - az->y1)/2; - UI_SetTheme(sa->spacetype, az->ar->type->regionid); + if(az->ar==NULL) return; - UI_ThemeColor(TH_BACK); - glBegin(GL_TRIANGLES); - glVertex2s(az->x1, az->y1); - glVertex2s(az->x2, az->y2); - glVertex2s(az->x3, az->y3); - glEnd(); + /* only display action zone icons when the region is hidden */ + if (!(az->ar->flag & RGN_FLAG_HIDDEN)) return; - UI_ThemeColorShade(TH_BACK, 50); - sdrawline(az->x1, az->y1, az->x3, az->y3); + glPushMatrix(); + glTranslatef(midx, midy, 0.); - UI_ThemeColorShade(TH_BACK, -50); - sdrawline(az->x2, az->y2, az->x3, az->y3); + /* outlined circle */ + glEnable(GL_LINE_SMOOTH); + + glColor4f(1.f, 1.f, 1.f, 0.8f); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluDisk( qobj, 0.0, 4.25f, 16, 1); + + glColor4f(0.2f, 0.2f, 0.2f, 0.9f); + + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluDisk( qobj, 0.0, 4.25f, 16, 1); + + glDisable(GL_LINE_SMOOTH); + + glPopMatrix(); + gluDeleteQuadric(qobj); + + /* + */ + sdrawline(midx, midy-2, midx, midy+3); + sdrawline(midx-2, midy, midx+3, midy); } @@ -235,10 +246,11 @@ void ED_area_overdraw(bContext *C) AZone *az; for(az= sa->actionzones.first; az; az= az->next) { if(az->do_draw) { - if(az->type==AZONE_AREA) + if(az->type==AZONE_AREA) { area_draw_azone(az->x1, az->y1, az->x2, az->y2); - else if(az->type==AZONE_REGION) + } else if(az->type==AZONE_REGION) { region_draw_azone(sa, az); + } az->do_draw= 0; } @@ -449,72 +461,103 @@ static void area_azone_initialize(ScrArea *sa) BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); } -static void region_azone_initialize(ScrArea *sa, ARegion *ar, char edge) +#define AZONEPAD_EDGE 4 +#define AZONEPAD_ICON 6 +static void region_azone_edge(AZone *az, ARegion *ar) { - AZone *az, *azt; - - az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); - BLI_addtail(&(sa->actionzones), az); - az->type= AZONE_REGION; - az->ar= ar; - az->edge= edge; - - if(edge=='t') { - az->x1= ar->winrct.xmin+AZONESPOT; - az->y1= ar->winrct.ymax; - az->x2= ar->winrct.xmin+2*AZONESPOT; + if(az->edge=='t') { + az->x1= ar->winrct.xmin; + az->y1= ar->winrct.ymax - AZONEPAD_EDGE; + az->x2= ar->winrct.xmax; az->y2= ar->winrct.ymax; - az->x3= (az->x1+az->x2)/2; - az->y3= az->y2+AZONESPOT/2; - BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y3); } - else if(edge=='b') { - az->x1= ar->winrct.xmin+AZONESPOT; - az->y1= ar->winrct.ymin; - az->x2= ar->winrct.xmin+2*AZONESPOT; + else if(az->edge=='b') { + az->x1= ar->winrct.xmin; + az->y1= ar->winrct.ymin + AZONEPAD_EDGE; + az->x2= ar->winrct.xmax; az->y2= ar->winrct.ymin; - az->x3= (az->x1+az->x2)/2; - az->y3= az->y2-AZONESPOT/2; - BLI_init_rcti(&az->rect, az->x1, az->x2, az->y3, az->y1); } - else if(edge=='l') { + else if(az->edge=='l') { az->x1= ar->winrct.xmin; - az->y1= ar->winrct.ymax-AZONESPOT; - az->x2= ar->winrct.xmin; - az->y2= ar->winrct.ymax-2*AZONESPOT; - az->x3= az->x2-AZONESPOT/2; - az->y3= (az->y1+az->y2)/2; - BLI_init_rcti(&az->rect, az->x3, az->x1, az->y1, az->y2); + az->y1= ar->winrct.ymin; + az->x2= ar->winrct.xmin + AZONEPAD_EDGE; + az->y2= ar->winrct.ymax; } - else { // if(edge=='r') { + else { // if(az->edge=='r') { az->x1= ar->winrct.xmax; - az->y1= ar->winrct.ymax-AZONESPOT; - az->x2= ar->winrct.xmax; - az->y2= ar->winrct.ymax-2*AZONESPOT; - az->x3= az->x2+AZONESPOT/2; - az->y3= (az->y1+az->y2)/2; - BLI_init_rcti(&az->rect, az->x1, az->x3, az->y1, az->y2); + az->y1= ar->winrct.ymin; + az->x2= ar->winrct.xmax - AZONEPAD_EDGE; + az->y2= ar->winrct.ymax; + } + + BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); +} + +static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar) +{ + AZone *azt; + + if(az->edge=='t') { + az->x1= ar->winrct.xmax - AZONEPAD_ICON; + az->y1= ar->winrct.ymax + AZONEPAD_ICON; + az->x2= ar->winrct.xmax - 2*AZONEPAD_ICON; + az->y2= ar->winrct.ymax + 2*AZONEPAD_ICON; + } + else if(az->edge=='b') { + az->x1= ar->winrct.xmin + AZONEPAD_ICON; + az->y1= ar->winrct.ymin - AZONEPAD_ICON; + az->x2= ar->winrct.xmin + 2*AZONEPAD_ICON; + az->y2= ar->winrct.ymin - 2*AZONEPAD_ICON; } + else if(az->edge=='l') { + az->x1= ar->winrct.xmin - 2*AZONEPAD_ICON; + az->y1= ar->winrct.ymax - 3*AZONEPAD_ICON; + az->x2= ar->winrct.xmin - AZONEPAD_ICON; + az->y2= ar->winrct.ymax - 2*AZONEPAD_ICON; + } + else { // if(az->edge=='r') { + az->x1= ar->winrct.xmax + AZONEPAD_ICON; + az->y1= ar->winrct.ymax - 3*AZONEPAD_ICON; + az->x2= ar->winrct.xmax + 2*AZONEPAD_ICON; + az->y2= ar->winrct.ymax - 2*AZONEPAD_ICON; + } + + BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); /* if more azones on 1 spot, set offset */ for(azt= sa->actionzones.first; azt; azt= azt->next) { if(az!=azt) { if( ABS(az->x1-azt->x1) < 2 && ABS(az->y1-azt->y1) < 2) { - if(edge=='t' || edge=='b') { + if(az->edge=='t' || az->edge=='b') { az->x1+= AZONESPOT; az->x2+= AZONESPOT; - az->x3+= AZONESPOT; - BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y3); + BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); } else { az->y1-= AZONESPOT; az->y2-= AZONESPOT; - az->y3-= AZONESPOT; - BLI_init_rcti(&az->rect, az->x1, az->x3, az->y1, az->y2); + BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); } } } } +} + +static void region_azone_initialize(ScrArea *sa, ARegion *ar, char edge) +{ + AZone *az; + + az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); + BLI_addtail(&(sa->actionzones), az); + az->type= AZONE_REGION; + az->ar= ar; + az->edge= edge; + + if (ar->flag & RGN_FLAG_HIDDEN) { + region_azone_icon(sa, az, ar); + } else { + region_azone_edge(az, ar); + } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index bb9d940edca..0ac50d85ff4 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -396,15 +396,7 @@ AZone *is_in_area_actionzone(ScrArea *sa, int x, int y) break; } else if(az->type == AZONE_REGION) { - float v1[2], v2[2], v3[2], pt[2]; - - v1[0]= az->x1; v1[1]= az->y1; - v2[0]= az->x2; v2[1]= az->y2; - v3[0]= az->x3; v3[1]= az->y3; - pt[0]= x; pt[1]=y; - - if(IsPointInTri2D(v1, v2, v3, pt)) - break; + break; } } } @@ -1273,7 +1265,9 @@ static void SCREEN_OT_area_split(wmOperatorType *ot) /* ************** scale region edge operator *********************************** */ typedef struct RegionMoveData { + AZone *az; ARegion *ar; + ScrArea *sa; int bigger, smaller, origval; int origx, origy; char edge; @@ -1290,7 +1284,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= rmd; + rmd->az = az; rmd->ar= az->ar; + rmd->sa = sad->sa1; rmd->edge= az->edge; rmd->origx= event->x; rmd->origy= event->y; @@ -1322,8 +1318,8 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) if(rmd->edge=='l') delta= -delta; rmd->ar->type->minsizex= rmd->origval + delta; CLAMP(rmd->ar->type->minsizex, 0, 1000); - if(rmd->ar->type->minsizex < 10) { - rmd->ar->type->minsizex= 10; + if(rmd->ar->type->minsizex < 24) { + rmd->ar->type->minsizex= rmd->origval; rmd->ar->flag |= RGN_FLAG_HIDDEN; } else @@ -1334,8 +1330,8 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) if(rmd->edge=='b') delta= -delta; rmd->ar->type->minsizey= rmd->origval + delta; CLAMP(rmd->ar->type->minsizey, 0, 1000); - if(rmd->ar->type->minsizey < 10) { - rmd->ar->type->minsizey= 10; + if(rmd->ar->type->minsizey < 24) { + rmd->ar->type->minsizey= rmd->origval; rmd->ar->flag |= RGN_FLAG_HIDDEN; } else diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 66113ec4941..8571d3601c6 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -742,7 +742,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) if (printable) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(10, ar->winy-20, 0.0f, printable); + BLF_draw_default(20, ar->winy-20, 0.0f, printable); } if (v3d->localview) { -- cgit v1.2.3 From 57ec59fb85a08371d360e9633e8f14ec3f882534 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 13 Sep 2009 02:14:41 +0000 Subject: Compile fix: silencing warning due to /*.../* in a header (It's strange seeing/making commits in trunk again after ignoring it as 'inferior' stuff for over a year now XD) --- source/blender/makesdna/DNA_space_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 5c1b363aa39..97ddb291136 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -165,7 +165,7 @@ typedef struct FileSelectParams { int active_file; int selstate; - /* short + /* short */ /* XXX --- still unused -- */ short f_fp; /* show font preview */ short menu; /* currently selected option in pupmenu */ -- cgit v1.2.3 From 896ada37ac2d9913f514a772b8e2356bac2b32ab Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sun, 13 Sep 2009 03:08:46 +0000 Subject: * Gave the region icons a bit more padding for the clickable area --- source/blender/editors/screen/area.c | 10 +++++----- source/blender/editors/space_view3d/view3d_draw.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 93348d9d556..81f06611c39 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -462,7 +462,7 @@ static void area_azone_initialize(ScrArea *sa) } #define AZONEPAD_EDGE 4 -#define AZONEPAD_ICON 6 +#define AZONEPAD_ICON 8 static void region_azone_edge(AZone *az, ARegion *ar) { if(az->edge=='t') { @@ -511,15 +511,15 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar) } else if(az->edge=='l') { az->x1= ar->winrct.xmin - 2*AZONEPAD_ICON; - az->y1= ar->winrct.ymax - 3*AZONEPAD_ICON; + az->y1= ar->winrct.ymax - 2*AZONEPAD_ICON; az->x2= ar->winrct.xmin - AZONEPAD_ICON; - az->y2= ar->winrct.ymax - 2*AZONEPAD_ICON; + az->y2= ar->winrct.ymax - AZONEPAD_ICON; } else { // if(az->edge=='r') { az->x1= ar->winrct.xmax + AZONEPAD_ICON; - az->y1= ar->winrct.ymax - 3*AZONEPAD_ICON; + az->y1= ar->winrct.ymax - 2*AZONEPAD_ICON; az->x2= ar->winrct.xmax + 2*AZONEPAD_ICON; - az->y2= ar->winrct.ymax - 2*AZONEPAD_ICON; + az->y2= ar->winrct.ymax - AZONEPAD_ICON; } BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 8571d3601c6..918aebda8e1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -742,7 +742,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) if (printable) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(20, ar->winy-20, 0.0f, printable); + BLF_draw_default(22, ar->winy-17, 0.0f, printable); } if (v3d->localview) { -- cgit v1.2.3 From 82a7b73d5aa4706d77028663ab35c0180d508751 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 13 Sep 2009 03:30:51 +0000 Subject: 2.5 - UI Bugfixes * Loading newly saved files (where linked-libs were used) crashed. However, libraries still don't get loaded correctly yet for some reason... * Pointer layout-items now draw without their UI text if their name is set to "" (i.e. text=""), making the ones with icons appear normal. This is kindof a hack, since it would be better to expose icon_only, but this way is less work. --- source/blender/blenloader/intern/readfile.c | 3 ++- source/blender/makesrna/intern/rna_ui_api.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 83abd5c2b4d..c2d745bfc8e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -11062,9 +11062,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) printf("read library: lib %s\n", mainptr->curlib->name); fd= blo_openblenderfile(mainptr->curlib->filename, &reports); - fd->reports= basefd->reports; if (fd) { + fd->reports= basefd->reports; + if (fd->libmap) oldnewmap_free(fd->libmap); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 20948843f8a..ab2dfe5e33c 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -44,6 +44,9 @@ static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, flag |= (slider)? UI_ITEM_R_SLIDER: 0; flag |= (expand)? UI_ITEM_R_EXPAND: 0; flag |= (toggle)? UI_ITEM_R_TOGGLE: 0; + + // XXX: an 'icon_only' prop should be added instead, but for now, this makes ptrs look ok + flag |= (name && name[0]==0)? UI_ITEM_R_ICON_ONLY: 0; uiItemR(layout, name, icon, ptr, propname, flag); } -- cgit v1.2.3 From 69496abf1d91829afdfcb807e06a2f48f19ffbc3 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 13 Sep 2009 03:56:30 +0000 Subject: Crash Fix: Sequencer Add->Effects->... menu crashed. Unfortunately, this menu is now empty, but this shows that the sequencer code is probably doing something funky... http://dpaste.com/92865/ --- source/blender/editors/interface/interface_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index bf449dba597..6211c79beca 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -718,7 +718,7 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch /* enum lookup */ if((prop= RNA_struct_find_property(&ptr, propname))) { RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); - if(RNA_enum_value_from_id(item, value_str, &value)==0) { + if(item==NULL || RNA_enum_value_from_id(item, value_str, &value)==0) { if(free) MEM_freeN(item); printf("uiItemEnumO_string: %s.%s, enum %s not found.\n", RNA_struct_identifier(ptr.type), propname, value_str); return; -- cgit v1.2.3 From b1e418db20cb854a933f0dcf9689a9104b99be7d Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 13 Sep 2009 07:00:44 +0000 Subject: 2.5 filebrowser fix operator property name 'type' was used by sequencer for strip effect type. Changed to 'filemode' for file browser. --- source/blender/editors/space_file/file_panels.c | 2 +- source/blender/editors/space_file/filesel.c | 2 +- source/blender/windowmanager/intern/wm_operators.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 2d351016893..1b54277c383 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -181,7 +181,7 @@ static void file_panel_operator(const bContext *C, Panel *pa) RNA_STRUCT_BEGIN(op->ptr, prop) { if(strcmp(RNA_property_identifier(prop), "rna_type") == 0) continue; - if(strcmp(RNA_property_identifier(prop), "type") == 0) + if(strcmp(RNA_property_identifier(prop), "filemode") == 0) continue; if(strcmp(RNA_property_identifier(prop), "path") == 0) continue; diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index b0bd3a9a5e7..e22e9f8e023 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -124,7 +124,7 @@ short ED_fileselect_set_params(SpaceFile *sfile) if (op) { BLI_strncpy(params->title, op->type->name, sizeof(params->title)); - params->type = RNA_int_get(op->ptr, "type"); + params->type = RNA_int_get(op->ptr, "filemode"); if (RNA_property_is_set(op->ptr, "path")) { RNA_string_get(op->ptr, "path", name); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 54ba18e3df5..b57edcb4dfc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -528,7 +528,7 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type) RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); - RNA_def_int(ot->srna, "type", type, FILE_LOADLIB, FILE_SPECIAL, + RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL, "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file.", FILE_LOADLIB, FILE_SPECIAL); } -- cgit v1.2.3 From 90ea3964fd7d1167fde6662543e7a49e048c8084 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 07:35:31 +0000 Subject: remove minimal twist from 2.4x, is too much in development which changed in 2.5, better keep in 2.5x then try have them in sync. --- source/blender/blenkernel/intern/curve.c | 142 +++--------------------------- source/blender/makesdna/DNA_curve_types.h | 2 - source/blender/src/buttons_editing.c | 3 +- 3 files changed, 14 insertions(+), 133 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 4d10308be20..d7dae21c961 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1835,106 +1835,6 @@ void makeBevelList(Object *ob) Mat3CpyMat3(bevp2->mat, bevp1->mat); } - } /* this has to be >2 points */ - else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) { - - /* Special case, cyclic curve with no twist. tricky... */ - - float quat[4], q[4], cross[3]; - - /* correcting a cyclic curve is more complicated, need to be corrected from both ends */ - float *quat_tmp1, *quat_tmp2; /* store a quat in the matrix temporarily */ - int iter_dir; - BevPoint *bevp_start= (BevPoint *)(bl+1); - - /* loop over the points twice, once up, once back, accumulate the quat rotations - * in both directions, then blend them in the 3rd loop and apply the tilt */ - for(iter_dir = 0; iter_dir < 2; iter_dir++) { - - bevp2= (BevPoint *)(bl+1); - bevp1= bevp2+(bl->nr-1); - bevp0= bevp1-1; - - nr= bl->nr; - while(nr--) { - - /* Normalizes */ - VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); - - if(bl->nr==nr+1) { /* first time */ - vectoquat(vec, 5, 1, quat); - } - else { - float angle = NormalizedVecAngle2(vec_prev, vec); - - if(angle > 0.0f) { /* otherwise we can keep as is */ - Crossf(cross, vec_prev, vec); - AxisAngleToQuat(q, cross, angle); - QuatMul(quat, q, quat_prev); - } - else { - QUATCOPY(quat, quat_prev); - } - } - QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ - VECCOPY(vec_prev, vec); - - if(iter_dir==0) { /* up, first time */ - quat_tmp1= (float *)bevp1->mat; - - bevp0= bevp1; - bevp1= bevp2; - bevp2++; - } - else { /* down second time */ - quat_tmp1= ((float *)bevp1->mat)+4; - - bevp2= bevp1; - bevp1= bevp0; - bevp0--; - - /* wrap around */ - if (bevp0 < bevp_start) - bevp0= bevp_start+(bl->nr-1); - } - - QUATCOPY(quat_tmp1, quat); - } - } - - /* Now interpolate the 2 quats and apply tilt */ - - bevp2= (BevPoint *)(bl+1); - bevp1= bevp2+(bl->nr-1); - bevp0= bevp1-1; - - nr= bl->nr; - while(nr--) { - - VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); - - quat_tmp1= (float *)bevp1->mat; - quat_tmp2= quat_tmp1+4; - - /* blend the 2 rotations gathered from both directions */ - QuatInterpol(quat, quat_tmp1, quat_tmp2, 1.0 - (((float)nr)/bl->nr)); - - AxisAngleToQuat(q, vec, bevp1->alfa); - QuatMul(quat, q, quat); - QuatToMat3(quat, bevp1->mat); - - /* generic */ - x1= bevp1->vec[0]- bevp0->vec[0]; - x2= bevp1->vec[0]- bevp2->vec[0]; - y1= bevp1->vec[1]- bevp0->vec[1]; - y2= bevp1->vec[1]- bevp2->vec[1]; - - calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); - - bevp0= bevp1; - bevp1= bevp2; - bevp2++; - } } else { /* Any curve with 3 or more points */ @@ -1951,21 +1851,8 @@ void makeBevelList(Object *ob) /* Normalizes */ VecBisect3(vec, bevp0->vec, bevp1->vec, bevp2->vec); - if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */ - vectoquat(vec, 5, 1, quat); - } - else { - float angle = NormalizedVecAngle2(vec_prev, vec); - - if(angle > 0.0f) { /* otherwise we can keep as is */ - Crossf(cross, vec_prev, vec); - AxisAngleToQuat(q, cross, angle); - QuatMul(quat, q, quat_prev); - } - else { - QUATCOPY(quat, quat_prev); - } - } + vectoquat(vec, 5, 1, quat); + QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */ VECCOPY(vec_prev, vec); @@ -1981,7 +1868,6 @@ void makeBevelList(Object *ob) calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa)); - bevp0= bevp1; bevp1= bevp2; bevp2++; @@ -1989,19 +1875,17 @@ void makeBevelList(Object *ob) /* correct non-cyclic cases */ if(bl->poly== -1) { - if(bl->nr>2) { - bevp= (BevPoint *)(bl+1); - bevp1= bevp+1; - bevp->sina= bevp1->sina; - bevp->cosa= bevp1->cosa; - Mat3CpyMat3(bevp->mat, bevp1->mat); - bevp= (BevPoint *)(bl+1); - bevp+= (bl->nr-1); - bevp1= bevp-1; - bevp->sina= bevp1->sina; - bevp->cosa= bevp1->cosa; - Mat3CpyMat3(bevp->mat, bevp1->mat); - } + bevp= (BevPoint *)(bl+1); + bevp1= bevp+1; + bevp->sina= bevp1->sina; + bevp->cosa= bevp1->cosa; + Mat3CpyMat3(bevp->mat, bevp1->mat); + bevp= (BevPoint *)(bl+1); + bevp+= (bl->nr-1); + bevp1= bevp-1; + bevp->sina= bevp1->sina; + bevp->cosa= bevp1->cosa; + Mat3CpyMat3(bevp->mat, bevp1->mat); } } bl= bl->next; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 65d8cc6fbc6..f8b307ddf88 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -205,8 +205,6 @@ typedef struct Curve { #define CU_FAST 512 /* Font: no filling inside editmode */ #define CU_RETOPO 1024 -#define CU_NO_TWIST 4096 - /* spacemode */ #define CU_LEFT 0 #define CU_MIDDLE 1 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 1e37fd0b9f8..2f9eac67d94 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3671,8 +3671,7 @@ static void editing_panel_curve_type(Object *ob, Curve *cu) uiBlockSetCol(block, TH_BUT_SETTING1); uiDefButBitS(block, TOG, CU_BACK, B_MAKEDISP, "Back", 760,115,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled back for extruded/beveled curves"); uiDefButBitS(block, TOG, CU_FRONT, B_MAKEDISP, "Front",810,115,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled front for extruded/beveled curves"); - uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,115,30,19, &cu->flag, 0, 0, 0, 0, "Allow Curve to be 3d, it doesn't fill then"); - uiDefIconButBitS(block, TOG, CU_NO_TWIST, B_MAKEDISP, ICON_AUTO, 890,115,20,19, &cu->flag, 0.0, 0.0, 0, 0, "Avoid twisting artifacts for 3D beveled/extruded curves"); + uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,115,50,19, &cu->flag, 0, 0, 0, 0, "Allow Curve to be 3d, it doesn't fill then"); } } -- cgit v1.2.3 From 2951a845b1f40ff11776fbf24bdc0055093f9c49 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 08:07:15 +0000 Subject: =?UTF-8?q?Patch=20[#19315],=20Fix=20for=20Jpeg2000=20alpha=20chan?= =?UTF-8?q?nel=20bug=20[#19280]=20thanks=20to=20Albertas=20Vy=C5=A1niauska?= =?UTF-8?q?s=20(thezbyg)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/blender/imbuf/intern/jp2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 6217cd6bea2..2583a155d6a 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -230,7 +230,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags) 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[2].data[index] + signed_offsets[3]) / float_divs[3]; + rect_float[3]= (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3]; else rect_float[3]= 1.0f; } @@ -260,7 +260,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags) rect[2]= image->comps[2].data[index] + signed_offsets[2]; if (image->numcomps >= 4) - rect[3]= image->comps[2].data[index] + signed_offsets[3]; + rect[3]= image->comps[3].data[index] + signed_offsets[3]; else rect[3]= 255; } -- cgit v1.2.3 From 7eea0b647cbfa7cadec14b07b696bf10830189e8 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 13 Sep 2009 08:08:50 +0000 Subject: 2.5 filebrowser Fix crash when loading old files with filebrowser UI Partial Fix for invoking filebrowser via spacetype pupmenu: reset directory in filelist Make paths relative in 'path' return when requested by 'relative_paths' property in operator --- source/blender/editors/space_file/file_ops.c | 4 ++++ source/blender/editors/space_file/filesel.c | 8 +++++++- source/blender/editors/space_file/space_file.c | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 5d3c2c766a3..e51fd421c8c 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -524,6 +524,10 @@ int file_exec(bContext *C, wmOperator *unused) BLI_strncpy(name, sfile->params->dir, sizeof(name)); RNA_string_set(op->ptr, "directory", name); strcat(name, sfile->params->file); + + if ( RNA_boolean_get(op->ptr, "relative_paths") ) { + BLI_makestringcode(G.sce, name); + } RNA_string_set(op->ptr, "path", name); /* some ops have multiple files to select */ diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index e22e9f8e023..f226b3de260 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -117,6 +117,8 @@ short ED_fileselect_set_params(SpaceFile *sfile) BLI_strncpy(sfile->params->file, file, sizeof(sfile->params->file)); BLI_make_file_string(G.sce, sfile->params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ } + + ED_fileselect_reset_params(sfile); params = sfile->params; @@ -173,13 +175,17 @@ short ED_fileselect_set_params(SpaceFile *sfile) } /* new params, refresh file list */ - if(sfile->files) filelist_free(sfile->files); + if(sfile->files) { + filelist_free(sfile->files); + filelist_setdir(sfile->files, params->dir); + } return 1; } void ED_fileselect_reset_params(SpaceFile *sfile) { + sfile->params->type = FILE_UNIX; sfile->params->flag = 0; sfile->params->title[0] = '\0'; } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index f71defe3949..bceeec1cb55 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -166,7 +166,8 @@ static SpaceLink *file_duplicate(SpaceLink *sl) /* clear or remove stuff from old */ sfilen->op = NULL; /* file window doesn't own operators */ - sfilen->files = filelist_new(sfileo->params->type); + if (sfileo->params) + sfilen->files = filelist_new(sfileo->params->type); if(sfileo->folders_prev) sfilen->folders_prev = MEM_dupallocN(sfileo->folders_prev); -- cgit v1.2.3 From 3a62892a955375b5716f84eab9d0c25c2ea58560 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 08:17:22 +0000 Subject: Patch [#19293] NearSensor: Changing distance and resetDistance from Python did not take effect immediately from Frank Papenmeier (hodka) --- from the submission Changing the distance and resetDistance Properties of a NearSensor from Python did only take effect, once there was a collision within the old radius. Reason: The radius of the PHY_IPhysicsController was not set to the new values. Solution: It is set at the end of the CheckResetDistance function. I moved the relevant code snippet from the Evaluate function into a new function called SetPhysCtrlRadius in order to avoid duplicating code doing the same thing. --- source/gameengine/Ketsji/KX_NearSensor.cpp | 33 +++++++++++++++++------------- source/gameengine/Ketsji/KX_NearSensor.h | 3 +++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index b71215645b4..a016a61a377 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -144,6 +144,22 @@ KX_NearSensor::~KX_NearSensor() delete m_client_info; } +void KX_NearSensor::SetPhysCtrlRadius() +{ + if (m_bTriggered) + { + if (m_physCtrl) + { + m_physCtrl->SetRadius(m_ResetMargin); + } + } else + { + if (m_physCtrl) + { + m_physCtrl->SetRadius(m_Margin); + } + } +} bool KX_NearSensor::Evaluate() { @@ -153,20 +169,9 @@ bool KX_NearSensor::Evaluate() if (m_bTriggered != m_bLastTriggered) { m_bLastTriggered = m_bTriggered; - if (m_bTriggered) - { - if (m_physCtrl) - { - m_physCtrl->SetRadius(m_ResetMargin); - } - } else - { - if (m_physCtrl) - { - m_physCtrl->SetRadius(m_Margin); - } - - } + + SetPhysCtrlRadius(); + result = true; } diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 88292242a5d..bbe7c158a0f 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -70,6 +70,7 @@ public: virtual void SynchronizeTransform(); virtual CValue* GetReplica(); virtual void ProcessReplica(); + virtual void SetPhysCtrlRadius(); virtual bool Evaluate(); virtual void ReParent(SCA_IObject* parent); @@ -96,6 +97,8 @@ public: if (sensor->m_Margin > sensor->m_ResetMargin) sensor->m_ResetMargin = sensor->m_Margin; + sensor->SetPhysCtrlRadius(); + return 0; } -- cgit v1.2.3 From a917abee898b9d1a5ea9628391f095807b092cf3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 08:41:13 +0000 Subject: [#19290] Blender.Load(filename) -> FILE_MAXDIR to FILE_MAXDIR + FILE_MAXFILE and unused argument removed only changed the FILE_MAXDIR -> FILE_MAXDIR + FILE_MAXFILE part since its possible scripts use this undocumented arg. --- source/blender/python/api2_2x/Blender.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index fd316eb484f..282d8d5d87d 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -615,7 +615,7 @@ static PyObject *Blender_Load( PyObject * self, PyObject * args ) "expected filename and optional int or nothing as arguments" ); if( fname ) { - if( strlen( fname ) > FILE_MAXDIR ) /* G.main->name's max length */ + if( strlen( fname ) > FILE_MAXDIR + FILE_MAXFILE ) /* G.main->name's max length */ return EXPP_ReturnPyObjError( PyExc_AttributeError, "filename too long!" ); else if( !BLI_exists( fname ) ) -- cgit v1.2.3 From f9694287d9a9a2ca5d031d6fbf4aa05045944ecc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 08:50:54 +0000 Subject: svn merge https://svn.blender.org/svnroot/bf-blender/branches/blender2.4 -r23172:HEAD merging now to save confusion later since the changes between last merge and 23172 shouldn't be merged. brings 2.4 and trunk in sync aside from sequencer edits from Peter. --- source/blender/imbuf/intern/jp2.c | 4 ++-- source/gameengine/Ketsji/KX_NearSensor.cpp | 33 +++++++++++++++++------------- source/gameengine/Ketsji/KX_NearSensor.h | 3 +++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 6217cd6bea2..2583a155d6a 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -230,7 +230,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags) 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[2].data[index] + signed_offsets[3]) / float_divs[3]; + rect_float[3]= (float)(image->comps[3].data[index] + signed_offsets[3]) / float_divs[3]; else rect_float[3]= 1.0f; } @@ -260,7 +260,7 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, int size, int flags) rect[2]= image->comps[2].data[index] + signed_offsets[2]; if (image->numcomps >= 4) - rect[3]= image->comps[2].data[index] + signed_offsets[3]; + rect[3]= image->comps[3].data[index] + signed_offsets[3]; else rect[3]= 255; } diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index f7baacdfa61..c6a6304cb2c 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -142,6 +142,22 @@ KX_NearSensor::~KX_NearSensor() delete m_client_info; } +void KX_NearSensor::SetPhysCtrlRadius() +{ + if (m_bTriggered) + { + if (m_physCtrl) + { + m_physCtrl->SetRadius(m_ResetMargin); + } + } else + { + if (m_physCtrl) + { + m_physCtrl->SetRadius(m_Margin); + } + } +} bool KX_NearSensor::Evaluate() { @@ -151,20 +167,9 @@ bool KX_NearSensor::Evaluate() if (m_bTriggered != m_bLastTriggered) { m_bLastTriggered = m_bTriggered; - if (m_bTriggered) - { - if (m_physCtrl) - { - m_physCtrl->SetRadius(m_ResetMargin); - } - } else - { - if (m_physCtrl) - { - m_physCtrl->SetRadius(m_Margin); - } - - } + + SetPhysCtrlRadius(); + result = true; } diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 03d6f830579..4f0247d209d 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -68,6 +68,7 @@ public: virtual void SynchronizeTransform(); virtual CValue* GetReplica(); virtual void ProcessReplica(); + virtual void SetPhysCtrlRadius(); virtual bool Evaluate(); virtual void ReParent(SCA_IObject* parent); @@ -91,6 +92,8 @@ public: if (sensor->m_Margin > sensor->m_ResetMargin) sensor->m_ResetMargin = sensor->m_Margin; + sensor->SetPhysCtrlRadius(); + return 0; } -- cgit v1.2.3 From 78bb6ce0347234d9103453d1242ec8e397d3eb7f Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 13 Sep 2009 09:41:00 +0000 Subject: 2.5 filebrowser * Fix for space init when loading with pupmenu (without operator) - parameters now get reset * experimental: made new director operator jump directly into renaming --- source/blender/editors/space_file/file_ops.c | 4 +++- source/blender/editors/space_file/filesel.c | 3 ++- source/blender/editors/space_file/space_file.c | 16 +++++++++++++++- source/blender/makesdna/DNA_space_types.h | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index e51fd421c8c..9705a36fc75 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -705,7 +705,9 @@ int file_directory_new_exec(bContext *C, wmOperator *unused) BLI_join_dirfile(tmpstr, tmpstr, tmpdir); } BLI_recurdir_fileops(tmpstr); - if (!BLI_exists(tmpstr)) { + if (BLI_exists(tmpstr)) { + BLI_strncpy(sfile->params->renamefile, tmpdir, FILE_MAXFILE); + } else { filelist_free(sfile->files); filelist_parent(sfile->files); BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), FILE_MAX); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index f226b3de260..085eecd2a7d 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -154,8 +154,9 @@ short ED_fileselect_set_params(SpaceFile *sfile) if (params->filter != 0) params->flag |= FILE_FILTER; + params->flag |= FILE_HIDE_DOT; + if (params->type == FILE_LOADLIB) { - params->flag |= FILE_HIDE_DOT; params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0; params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index bceeec1cb55..47839ea0342 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_rand.h" +#include "BLI_storage_types.h" #include "BKE_colortools.h" #include "BKE_context.h" @@ -154,6 +155,9 @@ static void file_free(SpaceLink *sl) /* spacetype; init callback, area size changes, screen set, etc */ static void file_init(struct wmWindowManager *wm, ScrArea *sa) { + SpaceFile *sfile= (SpaceFile*)sa->spacedata.first; + MEM_freeN(sfile->params); + sfile->params = 0; printf("file_init\n"); } @@ -203,7 +207,17 @@ static void file_refresh(const bContext *C, ScrArea *sa) filelist_readdir(sfile->files); } if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort); - + + if (params->renamefile[0] != '\0') { + int idx = filelist_find(sfile->files, params->renamefile); + if (idx >= 0) { + struct direntry *file= filelist_file(sfile->files, idx); + if (file) { + file->flags |= EDITING; + } + } + params->renamefile[0] = '\0'; + } if (sfile->layout) sfile->layout->dirty= 1; } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 97ddb291136..806d12815b5 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -153,6 +153,7 @@ typedef struct FileSelectParams { char title[24]; /* title, also used for the text of the execute button */ char dir[240]; /* directory */ char file[80]; /* file */ + char renamefile[80]; short type; /* XXXXX for now store type here, should be moved to the operator */ short flag; /* settings for filter, hiding dots files,... */ -- cgit v1.2.3 From 16a7fe1314bb82850a2d410089b6665eb8154f26 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 13 Sep 2009 12:32:57 +0000 Subject: Smoke: * Bugfix for drawing issues when having the domain transformed (editmode + object mode, both were buggy) --- source/blender/editors/space_view3d/drawobject.c | 4 +- source/blender/editors/space_view3d/drawvolume.c | 115 +++++++++++++++++---- .../blender/editors/space_view3d/view3d_intern.h | 2 +- 3 files changed, 97 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index e886bbbd5f2..c02d45ca798 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5362,14 +5362,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) { smd->domain->tex = NULL; GPU_create_smoke(smd, 0); - draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); + draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); GPU_free_smoke(smd); } else if(smd->domain->wt || (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { smd->domain->tex = NULL; GPU_create_smoke(smd, 1); - draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow); + draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res_wt, smd->domain->dx_wt, smd->domain->tex_shadow); GPU_free_smoke(smd); } } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index c8eda10566c..2c2ab2cbdec 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -129,20 +129,20 @@ static float cv[][3] = { // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] static float edges[12][2][3] = { - {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - - {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, - - {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}, - {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}} + {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + + {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, + + {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, + {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; int intersect_edges(float *points, float a, float b, float c, float d) @@ -154,7 +154,7 @@ int intersect_edges(float *points, float a, float b, float c, float d) for (i=0; i<12; i++) { t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d) / (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]); - if ((t>0)&&(t<2)) { + if ((t>0)&&(t<1)) { points[numpoints * 3 + 0] = edges[i][0][0] + edges[i][1][0]*t; points[numpoints * 3 + 1] = edges[i][0][1] + edges[i][1][1]*t; points[numpoints * 3 + 2] = edges[i][0][2] + edges[i][1][2]*t; @@ -191,7 +191,7 @@ static int larger_pow2(int n) return n*2; } -void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3], float dx, GPUTexture *tex_shadow) +void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) { Object *ob = base->object; RegionView3D *rv3d= ar->regiondata; @@ -225,11 +225,82 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture "END\n"; unsigned int prog; + + float size[3]; + + VECSUB(size, max, min); + + // maxx, maxy, maxz + cv[0][0] = max[0]; + cv[0][1] = max[1]; + cv[0][2] = max[2]; + // minx, maxy, maxz + cv[1][0] = min[0]; + cv[1][1] = max[1]; + cv[1][2] = max[2]; + // minx, miny, maxz + cv[2][0] = min[0]; + cv[2][1] = min[1]; + cv[2][2] = max[2]; + // maxx, miny, maxz + cv[3][0] = max[0]; + cv[3][1] = min[1]; + cv[3][2] = max[2]; + + // maxx, maxy, minz + cv[4][0] = max[0]; + cv[4][1] = max[1]; + cv[4][2] = min[2]; + // minx, maxy, minz + cv[5][0] = min[0]; + cv[5][1] = max[1]; + cv[5][2] = min[2]; + // minx, miny, minz + cv[6][0] = min[0]; + cv[6][1] = min[1]; + cv[6][2] = min[2]; + // maxx, miny, minz + cv[7][0] = max[0]; + cv[7][1] = min[1]; + cv[7][2] = min[2]; + + VECCOPY(edges[0][0], cv[4]); // maxx, maxy, minz + VECCOPY(edges[1][0], cv[5]); // minx, maxy, minz + VECCOPY(edges[2][0], cv[6]); // minx, miny, minz + VECCOPY(edges[3][0], cv[7]); // maxx, miny, minz + + VECCOPY(edges[4][0], cv[3]); // maxx, miny, maxz + VECCOPY(edges[5][0], cv[2]); // minx, miny, maxz + VECCOPY(edges[6][0], cv[6]); // minx, miny, minz + VECCOPY(edges[7][0], cv[7]); // maxx, miny, minz + + VECCOPY(edges[8][0], cv[1]); // minx, maxy, maxz + VECCOPY(edges[9][0], cv[2]); // minx, miny, maxz + VECCOPY(edges[10][0], cv[6]); // minx, miny, minz + VECCOPY(edges[11][0], cv[5]); // minx, maxy, minz + + // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); + + edges[0][1][2] = size[2]; + edges[1][1][2] = size[2]; + edges[2][1][2] = size[2]; + edges[3][1][2] = size[2]; + + edges[4][1][1] = size[1]; + edges[5][1][1] = size[1]; + edges[6][1][1] = size[1]; + edges[7][1][1] = size[1]; + + edges[8][1][0] = size[0]; + edges[9][1][0] = size[0]; + edges[10][1][0] = size[0]; + edges[11][1][0] = size[0]; + glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); wmLoadMatrix(rv3d->viewmat); - wmMultMatrix(ob->obmat); + // wmMultMatrix(ob->obmat); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); @@ -248,13 +319,15 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture y = cv[i][1] + viewnormal[1]; z = cv[i][2] + viewnormal[2]; - if ((x>=-1.0f)&&(x<=1.0f) - &&(y>=-1.0f)&&(y<=1.0f) - &&(z>=-1.0f)&&(z<=1.0f)) { + if ((x>=min[0])&&(x<=max[0]) + &&(y>=min[1])&&(y<=max[1]) + &&(z>=min[2])&&(z<=max[2])) { break; } } + // printf("i: %d\n", i); + if(GLEW_ARB_fragment_program) { glGenProgramsARB(1, &prog); @@ -318,7 +391,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture glBegin(GL_POLYGON); for (i = 0; i < numpoints; i++) { glColor3f(1.0, 1.0, 1.0); - glTexCoord3d((points[i * 3 + 0] + 1.0)*cor[0]/2.0, (points[i * 3 + 1] + 1)*cor[1]/2.0, (points[i * 3 + 2] + 1.0)*cor[2]/2.0); + glTexCoord3d((points[i * 3 + 0] - min[0] )*cor[0]/size[0], (points[i * 3 + 1] - min[1])*cor[1]/size[1], (points[i * 3 + 2] - min[2])*cor[2]/size[2]); glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]); } glEnd(); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 00b0b5c4fd1..7dbea44b68b 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -157,7 +157,7 @@ ARegion *view3d_has_buttons_region(ScrArea *sa); ARegion *view3d_has_tools_region(ScrArea *sa); /* draw_volume.c */ -void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, int res[3], float dx, struct GPUTexture *tex_shadow); +void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, float *min, float *max, int res[3], float dx, struct GPUTexture *tex_shadow); #endif /* ED_VIEW3D_INTERN_H */ -- cgit v1.2.3 From ca986a6874412aacbe9ec31a0cf94285f3d9ad41 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 13 Sep 2009 12:34:00 +0000 Subject: 2 Animation Fixes: * Auto-keyframing for Paste Poses and PoseLib works again. Unfortunately, it doesn't take into account whether the transforms were changed or not... * 'Stick to View' setting for Grease Pencil has now been inverted, since the old order was confusing. --- source/blender/editors/armature/poselib.c | 65 +++++++++------------------- source/blender/editors/armature/poseobject.c | 51 ++++++++++++---------- source/blender/makesrna/intern/rna_gpencil.c | 2 +- 3 files changed, 51 insertions(+), 67 deletions(-) diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 46d08afa656..c332a297e57 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -278,24 +278,7 @@ void poselib_validate_act (bAction *act) /* ************************************************************* */ /* Pointers to the builtin KeyingSets that we want to use */ -static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll need*/ -static short poselib_ks_need_init= 1; /* have the above been obtained yet? */ - -/* Make sure the builtin KeyingSets are initialised properly - * (only gets called on first run of poselib_add_current_pose). - */ -static void poselib_get_builtin_keyingsets (void) -{ - /* only if we haven't got these yet */ - // FIXME: this assumes that we will always get the builtin sets... - if (poselib_ks_need_init) { - /* LocRotScale (quaternions or eulers depending on context) */ - poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - - /* clear flag requesting init */ - poselib_ks_need_init= 0; - } -} +static KeyingSet *poselib_ks_locrotscale = NULL; /* the only keyingset we'll need */ /* ----- */ @@ -390,9 +373,6 @@ static int poselib_add_exec (bContext *C, wmOperator *op) /* validate name */ BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), 64); - /* make sure we've got KeyingSets to use */ - poselib_get_builtin_keyingsets(); - /* init common-key-source for use by KeyingSets */ memset(&cks, 0, sizeof(bCommonKeySrc)); cks.id= &ob->id; @@ -406,6 +386,8 @@ static int poselib_add_exec (bContext *C, wmOperator *op) cks.pchan= pchan; /* KeyingSet to use depends on rotation mode (but that's handled by the templates code) */ + if (poselib_ks_locrotscale == NULL) + poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); } } @@ -756,13 +738,20 @@ static void poselib_apply_pose (tPoseLib_PreviewData *pld) } /* Auto-keys/tags bones affected by the pose used from the poselib */ -static void poselib_keytag_pose (Scene *scene, tPoseLib_PreviewData *pld) +static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData *pld) { bPose *pose= pld->pose; bPoseChannel *pchan; bAction *act= pld->act; bActionGroup *agrp; + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; + + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &pld->ob->id; + /* start tagging/keying */ for (agrp= act->groups.first; agrp; agrp= agrp->next) { /* only for selected action channels */ @@ -770,28 +759,17 @@ static void poselib_keytag_pose (Scene *scene, tPoseLib_PreviewData *pld) pchan= get_pose_channel(pose, agrp->name); if (pchan) { -#if 0 // XXX old animation system // TODO: use a standard autokeying function in future (to allow autokeying-editkeys to work) - if (IS_AUTOKEY_MODE(NORMAL)) { - ID *id= &pld->ob->id; + if (IS_AUTOKEY_MODE(scene, NORMAL)) { + /* Set keys on pose + * - KeyingSet to use depends on rotation mode + * (but that's handled by the templates code) + */ + // TODO: for getting the KeyingSet used, we should really check which channels were affected + if (poselib_ks_locrotscale == NULL) + poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - /* Set keys on pose */ - if (pchan->flag & POSE_ROT) { - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0); - } - if (pchan->flag & POSE_SIZE) { - insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0); - } - if (pchan->flag & POSE_LOC) { - insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0); - } + modify_keyframes(C, &dsources, NULL, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); /* clear any unkeyed tags */ if (pchan->bone) @@ -802,7 +780,6 @@ static void poselib_keytag_pose (Scene *scene, tPoseLib_PreviewData *pld) if (pchan->bone) pchan->bone->flag |= BONE_UNKEYED; } -#endif // XXX old animation system } } @@ -1345,7 +1322,7 @@ static void poselib_preview_cleanup (bContext *C, wmOperator *op) } else if (pld->state == PL_PREVIEW_CONFIRM) { /* tag poses as appropriate */ - poselib_keytag_pose(scene, pld); + poselib_keytag_pose(C, scene, pld); /* change active pose setting */ act->active_marker= BLI_findindex(&act->markers, marker) + 1; diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 7d7f54309a8..bab7111dbd7 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -961,6 +961,11 @@ void POSE_OT_copy (wmOperatorType *ot) /* ---- */ +/* Pointers to the builtin KeyingSets that we want to use */ +static KeyingSet *posePaste_ks_locrotscale = NULL; /* the only keyingset we'll need */ + +/* ---- */ + static int pose_paste_exec (bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); @@ -969,6 +974,13 @@ static int pose_paste_exec (bContext *C, wmOperator *op) char name[32]; int flip= RNA_boolean_get(op->ptr, "flipped"); + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; + + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &ob->id; + /* sanity checks */ if ELEM(NULL, ob, ob->pose) return OPERATOR_CANCELLED; @@ -1045,6 +1057,13 @@ static int pose_paste_exec (bContext *C, wmOperator *op) eul[1]*= -1; eul[2]*= -1; EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]); + + // experimental method (uncomment to test): +#if 0 + /* experimental method: just flip the orientation of the axis on x/y axes */ + pchan->quat[1] *= -1; + pchan->quat[2] *= -1; +#endif } else { float eul[3]; @@ -1056,28 +1075,16 @@ static int pose_paste_exec (bContext *C, wmOperator *op) } } -#if 0 // XXX old animation system - if (autokeyframe_cfra_can_key(ob)) { - ID *id= &ob->id; + if (autokeyframe_cfra_can_key(scene, &ob->id)) { + /* Set keys on pose + * - KeyingSet to use depends on rotation mode + * (but that's handled by the templates code) + */ + // TODO: for getting the KeyingSet used, we should really check which channels were affected + if (posePaste_ks_locrotscale == NULL) + posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - /* Set keys on pose */ - // TODO: make these use keyingsets.... - if (chan->flag & POSE_ROT) { - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0); - } - if (chan->flag & POSE_SIZE) { - insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0); - } - if (chan->flag & POSE_LOC) { - insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0); - insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0); - } + modify_keyframes(C, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); /* clear any unkeyed tags */ if (chan->bone) @@ -1088,7 +1095,6 @@ static int pose_paste_exec (bContext *C, wmOperator *op) if (chan->bone) chan->bone->flag |= BONE_UNKEYED; } -#endif // XXX old animation system } } } @@ -1975,6 +1981,7 @@ void ARMATURE_OT_bone_layers (wmOperatorType *ot) RNA_def_boolean_array(ot->srna, "layers", 16, NULL, "Layers", "Armature layers that bone belongs to."); } +/* ********************************************** */ #if 0 // XXX old sys diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 72e77e93607..15f5ef7884f 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -233,7 +233,7 @@ void rna_def_gpencil_data(BlenderRNA *brna) /* Flags */ prop= RNA_def_property(srna, "view_space_draw", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN); RNA_def_property_ui_text(prop, "Stick to View", "Newly drawn strokes get added in view space (i.e. sketches stick to data when view is manipulated)."); } -- cgit v1.2.3 From 06a2ee4afed4237398b69ddf253e29a730b2f9f0 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 13 Sep 2009 12:35:35 +0000 Subject: Smoke: * Making edge and vertex arrays local to avoid problems --- source/blender/editors/space_view3d/drawvolume.c | 52 ++++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 2c2ab2cbdec..48f2145c03c 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -121,31 +121,7 @@ struct GPUTexture; -/* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */ -static float cv[][3] = { - {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, - {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} -}; - -// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] -static float edges[12][2][3] = { - {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, - - {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, - - {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, - {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} -}; - -int intersect_edges(float *points, float a, float b, float c, float d) +int intersect_edges(float *points, float a, float b, float c, float d, float edges[12][2][3]) { int i; float t; @@ -204,6 +180,30 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture float cor[3] = {1.,1.,1.}; int gl_depth = 0, gl_blend = 0; + /* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */ + float cv[][3] = { + {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, + {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} + }; + + // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] + float edges[12][2][3] = { + {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, + + {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, + + {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, + {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} + }; + /* Fragment program to calculate the 3dview of smoke */ /* using 2 textures, density and shadow */ const char *text = "!!ARBfp1.0\n" @@ -368,7 +368,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture float p0[3]; // intersect_edges returns the intersection points of all cube edges with // the given plane that lie within the cube - numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d); + numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d, edges); if (numpoints > 2) { VECCOPY(p0, points); -- cgit v1.2.3 From 716953f0c1e968f00083c6bfc0bc53e6ba6c80d5 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 13 Sep 2009 13:38:23 +0000 Subject: Pointcache / Smoke: * Disable "step" setting for smoke on GUI --- release/ui/buttons_particle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index 1d496e19121..1bbd64c9b0f 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -57,7 +57,8 @@ def point_cache_ui(self, cache, enabled, particles, smoke): row = layout.row() row.enabled = enabled row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - row.itemR(cache, "step"); + if not smoke: + row.itemR(cache, "step"); if not smoke: row = layout.row() -- cgit v1.2.3 From cfc8d66ab08a0449b0ad553c598416787f614b3a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 13 Sep 2009 13:39:06 +0000 Subject: Smoke: * Report console error if gfx card does not support smoke drawing --- source/blender/editors/space_view3d/drawvolume.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 48f2145c03c..cc4cb4771e7 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -341,6 +341,8 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture // custom parameter for smoke style (higher = thicker) glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); } + else + printf("Your gfx card does not support 3dview smoke drawing."); GPU_texture_bind(tex, 0); if(tex_shadow) -- cgit v1.2.3 From 4c92ca02f7a283e1f0e69ab3e0b6bdcc755a0deb Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 13 Sep 2009 15:23:50 +0000 Subject: Update project files --- projectfiles_vc9/blender/blender.sln | 2 -- projectfiles_vc9/blender/blender.vcproj | 2 +- projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj | 17 +---------------- projectfiles_vc9/blender/src/BL_src.vcproj | 2 +- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/projectfiles_vc9/blender/blender.sln b/projectfiles_vc9/blender/blender.sln index ac4c7f60c95..93796f7660d 100644 --- a/projectfiles_vc9/blender/blender.sln +++ b/projectfiles_vc9/blender/blender.sln @@ -4,7 +4,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj", ProjectSection(ProjectDependencies) = postProject {E5F2F004-C704-4DCC-A08F-6EB1E38EAB9F} = {E5F2F004-C704-4DCC-A08F-6EB1E38EAB9F} {6E24BF09-9653-4166-A871-F65CC9E98A9B} = {6E24BF09-9653-4166-A871-F65CC9E98A9B} - {F9850C15-FF0A-429E-9D47-89FB433C9BD8} = {F9850C15-FF0A-429E-9D47-89FB433C9BD8} {A90C4918-4B21-4277-93BD-AF65F30951D9} = {A90C4918-4B21-4277-93BD-AF65F30951D9} {FB88301F-F725-401B-ACD7-D2ABBF333B71} = {FB88301F-F725-401B-ACD7-D2ABBF333B71} {98330220-47A6-42E0-9DE4-AD0FF5D204D6} = {98330220-47A6-42E0-9DE4-AD0FF5D204D6} @@ -43,7 +42,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj", {213356A9-3A1F-41DA-9819-1297BCD17DEE} = {213356A9-3A1F-41DA-9819-1297BCD17DEE} {727F90AC-ABE6-40BF-8937-C2F2F1D13DEA} = {727F90AC-ABE6-40BF-8937-C2F2F1D13DEA} {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} - {A1CCF5B0-08E1-4F00-B417-8BFAC34E5E90} = {A1CCF5B0-08E1-4F00-B417-8BFAC34E5E90} {E90C7BC2-CF30-4A60-A8F2-0050D592E358} = {E90C7BC2-CF30-4A60-A8F2-0050D592E358} {8B8D4FC3-3234-4E54-8376-5AB83D00D164} = {8B8D4FC3-3234-4E54-8376-5AB83D00D164} {9991A3C3-83FE-4AFE-9E18-9D01CB57E879} = {9991A3C3-83FE-4AFE-9E18-9D01CB57E879} diff --git a/projectfiles_vc9/blender/blender.vcproj b/projectfiles_vc9/blender/blender.vcproj index 0ffbcd9aa67..b59197973c5 100644 --- a/projectfiles_vc9/blender/blender.vcproj +++ b/projectfiles_vc9/blender/blender.vcproj @@ -168,7 +168,7 @@ @@ -553,10 +554,6 @@ RelativePath="..\..\..\source\blender\blenlib\intern\jitter.c" > - - @@ -593,10 +590,6 @@ RelativePath="..\..\..\source\blender\blenlib\intern\util.c" > - - @@ -702,14 +695,6 @@ RelativePath="..\..\..\source\blender\blenlib\BLI_winstuff.h" > - - - - diff --git a/projectfiles_vc9/blender/src/BL_src.vcproj b/projectfiles_vc9/blender/src/BL_src.vcproj index ad8ccc4a94b..dc2f8092b87 100644 --- a/projectfiles_vc9/blender/src/BL_src.vcproj +++ b/projectfiles_vc9/blender/src/BL_src.vcproj @@ -119,7 +119,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu" - PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG" + PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG" BasicRuntimeChecks="3" RuntimeLibrary="1" DefaultCharIsUnsigned="true" -- cgit v1.2.3 From e903632c1053f041a33ddb1b27d5cb938a7ee38b Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sun, 13 Sep 2009 16:15:26 +0000 Subject: after some discussion, this is the replacement for the old loopcut tool: edge ring select displays a preview of the edge ring, and you can move the mouse with ctrl-alt held down and change the edge ring selection. --- source/blender/blenkernel/BKE_utildefines.h | 49 ++++ source/blender/editors/mesh/editmesh_loop.c | 1 + source/blender/editors/mesh/loopcut.c | 400 ++++++++++++++++++++++++++++ source/blender/editors/mesh/mesh_intern.h | 2 + source/blender/editors/mesh/mesh_ops.c | 11 +- 5 files changed, 458 insertions(+), 5 deletions(-) create mode 100644 source/blender/editors/mesh/loopcut.c diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 4d43518901e..7d8cb41db82 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -193,5 +193,54 @@ #define SET_INT_IN_POINTER(i) ((void*)(intptr_t)(i)) #define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i)) +/*little array macro library. example of usage: + +int *arr = NULL; +V_DECLARE(arr); +int i; + +for (i=0; i<10; i++) { + V_GROW(arr); + arr[i] = something; +} +V_FREE(arr); + +arrays are buffered, using double-buffering (so on each reallocation, +the array size is doubled). supposedly this should give good Big Oh +behaviour, though it may not be the best in practice. +*/ + +#define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp + +/*in the future, I plan on having V_DECLARE allocate stack memory it'll + use at first, and switch over to heap when it needs more. that'll mess + up cases where you'd want to use this API to build a dynamic list for + non-local use, so all such cases should use this macro.*/ +#define V_DYNDECLARE(vec) V_DECLARE(vec) + +/*this returns the entire size of the array, including any buffering.*/ +#define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec))) + +/*this returns the logical size of the array, not including buffering.*/ +#define V_COUNT(vec) _##vec##_count + +/*grow the array by one. zeroes the new elements.*/ +#define V_GROW(vec) \ + V_SIZE(vec) > _##vec##_count ? _##vec##_count++ : \ + ((_##vec##_tmp = MEM_callocN(sizeof(*vec)*(_##vec##_count*2+2), #vec " " __FILE__ " ")),\ + (vec && memcpy(_##vec##_tmp, vec, sizeof(*vec) * _##vec##_count)),\ + (vec && (MEM_freeN(vec),1)),\ + (vec = _##vec##_tmp),\ + _##vec##_count++) + +#define V_FREE(vec) if (vec) MEM_freeN(vec); + +/*resets the logical size of an array to zero, but doesn't + free the memory.*/ +#define V_RESET(vec) _##vec##_count=0 + +/*set the count of the array*/ +#define V_SETCOUNT(vec, count) _##vec##_count = (count) + #endif diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c index 4c3e76f2285..c98b387d28a 100644 --- a/source/blender/editors/mesh/editmesh_loop.c +++ b/source/blender/editors/mesh/editmesh_loop.c @@ -199,6 +199,7 @@ static void edgering_sel(EditMesh *em, EditEdge *startedge, int select, int prev } } } + void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts) { ViewContext vc; // XXX diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c new file mode 100644 index 00000000000..c7e10d5809f --- /dev/null +++ b/source/blender/editors/mesh/loopcut.c @@ -0,0 +1,400 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Joseph Eagar, Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include + +#include "DNA_ID.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_userdef_types.h" +#include "DNA_windowmanager_types.h" +#include "DNA_object_types.h" + +#include "MEM_guardedalloc.h" + +#include "PIL_time.h" + +#include "BLI_blenlib.h" +#include "BLI_dynstr.h" /*for WM_operator_pystring */ +#include "BLI_editVert.h" + +#include "BKE_blender.h" +#include "BKE_context.h" +#include "BKE_scene.h" +#include "BKE_utildefines.h" +#include "BKE_mesh.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" /* for paint cursor */ + +#include "IMB_imbuf_types.h" + +#include "ED_screen.h" +#include "ED_util.h" +#include "ED_space_api.h" +#include "ED_view3d.h" +#include "ED_mesh.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "mesh_intern.h" + +/* ringsel operator */ + +/* struct for properties used while drawing */ +typedef struct tringselOpData { + ARegion *ar; /* region that ringsel was activated in */ + void *draw_handle; /* for drawing preview loop */ + + float (*edges)[2][3]; + int totedge; + + ViewContext vc; + + Object *ob; + EditMesh *em; + EditEdge *eed; + + int extend; +} tringselOpData; + +/* modal loop selection drawing callback */ +static void ringsel_draw(const bContext *C, ARegion *ar, void *arg) +{ + int i; + tringselOpData *lcd = arg; + + glDisable(GL_DEPTH_TEST); + + glPushMatrix(); + glMultMatrixf(lcd->ob->obmat); + + glColor3ub(255, 0, 255); + glBegin(GL_LINES); + for (i=0; itotedge; i++) { + glVertex3fv(lcd->edges[i][0]); + glVertex3fv(lcd->edges[i][1]); + } + glEnd(); + + glPopMatrix(); + glEnable(GL_DEPTH_TEST); +} + +static void edgering_sel(tringselOpData *lcd, int previewlines, int select) +{ + EditMesh *em = lcd->em; + EditEdge *startedge = lcd->eed; + EditEdge *eed; + EditFace *efa; + EditVert *v[2][2]; + float (*edges)[2][3] = NULL; + V_DYNDECLARE(edges); + float co[2][3]; + int looking=1, i, j=0, tot=0; + + if (!startedge) + return; + + if (lcd->edges) { + MEM_freeN(lcd->edges); + lcd->edges = NULL; + lcd->totedge = 0; + } + + if (!lcd->extend) { + EM_clear_flag_all(lcd->em, SELECT); + } + + /* in eed->f1 we put the valence (amount of faces in edge) */ + /* in eed->f2 we put tagged flag as correct loop */ + /* in efa->f1 we put tagged flag as correct to select */ + + for(eed= em->edges.first; eed; eed= eed->next) { + eed->f1= 0; + eed->f2= 0; + } + + for(efa= em->faces.first; efa; efa= efa->next) { + efa->f1= 0; + if(efa->h==0) { + efa->e1->f1++; + efa->e2->f1++; + efa->e3->f1++; + if(efa->e4) efa->e4->f1++; + } + } + + // tag startedge OK + startedge->f2= 1; + + while(looking) { + looking= 0; + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->e4 && efa->f1==0 && efa->h == 0) { // not done quad + if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok + + // if edge tagged, select opposing edge and mark face ok + if(efa->e1->f2) { + efa->e3->f2= 1; + efa->f1= 1; + looking= 1; + } + else if(efa->e2->f2) { + efa->e4->f2= 1; + efa->f1= 1; + looking= 1; + } + if(efa->e3->f2) { + efa->e1->f2= 1; + efa->f1= 1; + looking= 1; + } + if(efa->e4->f2) { + efa->e2->f2= 1; + efa->f1= 1; + looking= 1; + } + } + } + } + } + + if(previewlines > 0 && !select){ + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->v4 == NULL) { continue; } + if(efa->h == 0){ + if(efa->e1->f2 == 1){ + if(efa->e1->h == 1 || efa->e3->h == 1 ) + continue; + + v[0][0] = efa->v1; + v[0][1] = efa->v2; + v[1][0] = efa->v4; + v[1][1] = efa->v3; + } else if(efa->e2->f2 == 1){ + if(efa->e2->h == 1 || efa->e4->h == 1) + continue; + v[0][0] = efa->v2; + v[0][1] = efa->v3; + v[1][0] = efa->v1; + v[1][1] = efa->v4; + } else { continue; } + + for(i=1;i<=previewlines;i++){ + co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0]; + co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1]; + co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2]; + + co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0])*(i/((float)previewlines+1))+v[1][0]->co[0]; + co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1])*(i/((float)previewlines+1))+v[1][0]->co[1]; + co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2]; + + V_GROW(edges); + VECCOPY(edges[tot][0], co[0]); + VECCOPY(edges[tot][1], co[1]); + tot++; + } + } + } + } else { + select = (startedge->f & SELECT) == 0; + + /* select the edges */ + for(eed= em->edges.first; eed; eed= eed->next) { + if(eed->f2) EM_select_edge(eed, select); + } + } + + lcd->edges = edges; + lcd->totedge = tot; +} + +static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *ar) +{ + if (lcd->eed) + edgering_sel(lcd, 1, 0); +} + +static void ringsel_finish(bContext *C, wmOperator *op) +{ + tringselOpData *lcd= op->customdata; + + if (lcd->eed); + edgering_sel(lcd, 0, 1); +} + +/* called when modal loop selection is done... */ +static void ringsel_exit (bContext *C, wmOperator *op) +{ + tringselOpData *lcd= op->customdata; + + /* deactivate the extra drawing stuff in 3D-View */ + ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle); + + if (lcd->edges) + MEM_freeN(lcd->edges); + + ED_region_tag_redraw(lcd->ar); + + /* free the custom data */ + MEM_freeN(lcd); + op->customdata= NULL; +} + +/* called when modal loop selection gets set up... */ +static int ringsel_init (bContext *C, wmOperator *op) +{ + tringselOpData *lcd; + + /* alloc new customdata */ + lcd= op->customdata= MEM_callocN(sizeof(tringselOpData), "ringsel Modal Op Data"); + + /* assign the drawing handle for drawing preview line... */ + lcd->ar= CTX_wm_region(C); + lcd->draw_handle= ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST); + lcd->ob = CTX_data_edit_object(C); + lcd->em= BKE_mesh_get_editmesh((Mesh *)lcd->ob->data); + lcd->extend = RNA_boolean_get(op->ptr, "extend"); + em_setup_viewcontext(C, &lcd->vc); + + ED_region_tag_redraw(lcd->ar); + + return 1; +} + +static int ringsel_cancel (bContext *C, wmOperator *op) +{ + /* this is just a wrapper around exit() */ + ringsel_exit(C, op); + return OPERATOR_CANCELLED; +} + +static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + ScrArea *sa = CTX_wm_area(C); + tringselOpData *lcd; + EditEdge *edge; + int dist = 75; + + view3d_operator_needs_opengl(C); + + if (!ringsel_init(C, op)) + return OPERATOR_CANCELLED; + + /* add a modal handler for this operator - handles loop selection */ + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + + lcd = op->customdata; + lcd->vc.mval[0] = evt->mval[0]; + lcd->vc.mval[1] = evt->mval[1]; + + edge = findnearestedge(&lcd->vc, &dist); + if (edge != lcd->eed) { + lcd->eed = edge; + ringsel_find_edge(lcd, C, lcd->ar); + } + + return OPERATOR_RUNNING_MODAL; +} + +static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) +{ + tringselOpData *lcd= op->customdata; + + view3d_operator_needs_opengl(C); + + switch (event->type) { + case RIGHTMOUSE: + case LEFTMOUSE: /* confirm */ // XXX hardcoded + if (event->val == 0) { + /* finish */ + ED_region_tag_redraw(lcd->ar); + + ringsel_finish(C, op); + ringsel_exit(C, op); + + return OPERATOR_FINISHED; + } + + ED_region_tag_redraw(lcd->ar); + break; + case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ + int dist = 75; + EditEdge *edge; + + lcd->vc.mval[0] = event->mval[0]; + lcd->vc.mval[1] = event->mval[1]; + edge = findnearestedge(&lcd->vc, &dist); + + if (edge != lcd->eed) { + lcd->eed = edge; + ringsel_find_edge(lcd, C, lcd->ar); + } + + ED_region_tag_redraw(lcd->ar); + break; + } + } + + /* keep going until the user confirms */ + return OPERATOR_RUNNING_MODAL; +} + +// naming is whatever this should use... +void MESH_OT_edgering_select (wmOperatorType *ot) +{ + /* description */ + ot->name= "Loop Cut"; + ot->idname= "MESH_OT_edgering_select"; + ot->description= "Add a new loop between existing loops."; + + /* callbacks */ + ot->invoke= ringsel_invoke; + ot->modal= ringsel_modal; + ot->cancel= ringsel_cancel; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection"); +} diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 905a51a1bb0..887474414b3 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -242,5 +242,7 @@ void MESH_OT_vertex_color_remove(struct wmOperatorType *ot); void MESH_OT_sticky_add(struct wmOperatorType *ot); void MESH_OT_sticky_remove(struct wmOperatorType *ot); +void MESH_OT_edgering_select(struct wmOperatorType *ot); + #endif // MESH_INTERN_H diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index c545f7d70d6..3cdf1d47817 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -320,6 +320,8 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_face_specials); WM_operatortype_append(MESH_OT_specials); + WM_operatortype_append(MESH_OT_edgering_select); + /* macros */ ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_duplicate"); @@ -332,7 +334,7 @@ void ED_operatortypes_mesh(void) ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_extrude"); WM_operatortype_macro_define(ot, "TFM_OT_translate"); - + } /* note mesh keymap also for other space? */ @@ -346,11 +348,10 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); RNA_boolean_set(kmi->ptr, "extend", 1); - kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "ring", 1); - kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0); + + kmi= WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0); + kmi= WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0); RNA_boolean_set(kmi->ptr, "extend", 1); - RNA_boolean_set(kmi->ptr, "ring", 1); WM_keymap_add_item(keymap, "MESH_OT_select_shortest_path", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); -- cgit v1.2.3 From 5c6eb9c4fad5871efc1d1c3d258b3ba65c221ea9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 17:38:43 +0000 Subject: replace curve.curve_2d True/False with curve.dimensions (2D/3D) enum suggested by William. --- release/ui/buttons_data_curve.py | 6 +++--- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/makesrna/intern/rna_curve.c | 31 ++++++++++++++++++------------ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 1a5e56b02a4..94ad073d0bb 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -56,7 +56,7 @@ class DATA_PT_shape_curve(DataButtonsPanel): if not is_surf: row = layout.row() - row.itemR(curve, "curve_2d") + row.itemR(curve, "dimensions", expand=True) split = layout.split() @@ -64,7 +64,7 @@ class DATA_PT_shape_curve(DataButtonsPanel): if not is_surf: sub = col.column() - sub.active = curve.curve_2d + sub.active = (curve.dimensions=='2D') sub.itemL(text="Caps:") row = sub.row() row.itemR(curve, "front") @@ -208,7 +208,7 @@ class DATA_PT_active_spline(DataButtonsPanelActive): if not is_surf: split = layout.split() col = split.column() - col.active = (not curve.curve_2d) + col.active = (curve.dimensions=='3D') col.itemL(text="Interpolation:") col.itemR(act_spline, "tilt_interpolation", text="Tilt") diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 0ac50d85ff4..dba882200ce 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3329,7 +3329,7 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0); - RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", F7KEY, KM_PRESS, 0, 0)->ptr, "filename", "test.py"); + RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", F7KEY, KM_PRESS, 0, 0)->ptr, "path", "test.py"); WM_keymap_verify_item(keymap, "SCRIPT_OT_python_run_ui_scripts", F8KEY, KM_PRESS, 0, 0); /* files */ diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index da4abe81f24..121812c189c 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -167,12 +167,18 @@ static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int } -static void rna_Curve_2d_set(PointerRNA *ptr, int value) +static void rna_Curve_dimension_set(PointerRNA *ptr, int value) { Curve *cu= (Curve*)ptr->id.data; Nurb *nu= cu->editnurb ? cu->editnurb->first : cu->nurb.first; - if(value) { + if(value==CU_3D) { + cu->flag |= CU_3D; + for( ; nu; nu= nu->next) { + nu->flag &= ~CU_2D; + } + } + else { cu->flag &= ~CU_3D; for( ; nu; nu= nu->next) { nu->flag |= CU_2D; @@ -183,12 +189,6 @@ static void rna_Curve_2d_set(PointerRNA *ptr, int value) calchandlesNurb(nu); } } - else { - cu->flag |= CU_3D; - for( ; nu; nu= nu->next) { - nu->flag &= ~CU_2D; - } - } } @@ -675,6 +675,11 @@ static void rna_def_curve(BlenderRNA *brna) {CU_TWIST_TANGENT, "TANGENT", 0, "Tangent", "Use the tangent to calculate twist"}, {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem curve_axis_items[]= { + {0, "2D", 0, "2D", "Clamp the Z axis of of the curve"}, + {CU_3D, "3D", 0, "3D", "Allow editing on the Z axis of this curve, also alows tilt and curve radius to be used."}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "Curve", "ID"); RNA_def_struct_ui_text(srna, "Curve", "Curve datablock storing curves, splines and NURBS."); RNA_def_struct_ui_icon(srna, ICON_CURVE_DATA); @@ -778,10 +783,12 @@ static void rna_def_curve(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); /* Flags */ - prop= RNA_def_property(srna, "curve_2d", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CU_3D); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Curve_2d_set"); - RNA_def_property_ui_text(prop, "2D Curve", "Define curve in two dimensions only. Note that fill only works when this is enabled."); + + prop= RNA_def_property(srna, "dimensions", PROP_ENUM, PROP_NONE); /* as an enum */ + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, curve_axis_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_Curve_dimension_set", NULL); + RNA_def_property_ui_text(prop, "Dimensions", "Select 2D or 3D curve type."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop= RNA_def_property(srna, "front", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From d47e1fee328d816e8f5c308556986669fc262616 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 13 Sep 2009 17:52:36 +0000 Subject: == FFMPEG == This fixes the underlying problem of the DV crashings - within blender code. Problem was, that we tried to seek on decode errors. (Unintentionally, curposition wasn't advanced in that case). That triggered a bug within ffmpeg, that made blender crash. My workaround fix for 2.49 actually only prevented the crash, but didn't stop ffmpeg from only decoding black frames after that point... (The patch also cleans up the color conversion a little bit, by using PIX_FMT_RGBA (still need to find a way to make it work with video files that actually *have* an alpha channel. At least, latest FFMPEG-SVN swscaler has the ability to use alpha.) Looks like we can remove extern/ffmpeg now... --- source/blender/imbuf/intern/anim.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index a2dbdfbe483..1aaba620f3a 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -608,7 +608,7 @@ static int startffmpeg(struct anim * anim) { anim->pFrameDeinterlaced = avcodec_alloc_frame(); anim->pFrameRGB = avcodec_alloc_frame(); - if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y) + if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y) != anim->x * anim->y * 4) { fprintf (stderr, "ffmpeg has changed alloc scheme ... ARGHHH!\n"); @@ -642,7 +642,7 @@ static int startffmpeg(struct anim * anim) { anim->pCodecCtx->pix_fmt, anim->pCodecCtx->width, anim->pCodecCtx->height, - PIX_FMT_BGR32, + PIX_FMT_RGBA, SWS_FAST_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL); @@ -671,11 +671,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { if (anim == 0) return (0); - ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0); + ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect, 0); avpicture_fill((AVPicture*) anim->pFrameRGB, (unsigned char*) ibuf->rect, - PIX_FMT_BGR32, anim->x, anim->y); + PIX_FMT_RGBA, anim->x, anim->y); if (position != anim->curposition + 1) { if (position > anim->curposition + 1 @@ -748,6 +748,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { if (frameFinished && !pos_found) { if (packet.dts >= pts_to_search) { pos_found = 1; + anim->curposition = position; } } @@ -811,21 +812,21 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { for (y = 0; y < h; y++) { unsigned char tmp[4]; - unsigned long * tmp_l = - (unsigned long*) tmp; + unsigned int * tmp_l = + (unsigned int*) tmp; tmp[3] = 0xff; for (x = 0; x < w; x++) { - tmp[0] = bottom[3]; - tmp[1] = bottom[2]; - tmp[2] = bottom[1]; + tmp[0] = bottom[0]; + tmp[1] = bottom[1]; + tmp[2] = bottom[2]; - bottom[0] = top[3]; - bottom[1] = top[2]; - bottom[2] = top[1]; + bottom[0] = top[0]; + bottom[1] = top[1]; + bottom[2] = top[2]; bottom[3] = 0xff; - *(unsigned long*) top + *(unsigned int*) top = *tmp_l; bottom +=4; @@ -848,8 +849,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { 0, 0, 0 }; int i; unsigned char* r; - - + sws_scale(anim->img_convert_ctx, input->data, input->linesize, @@ -857,8 +857,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { anim->pCodecCtx->height, dst2, dstStride2); - - /* workaround: sws_scale + + /* workaround: sws_scale sets alpha = 0... */ r = (unsigned char*) ibuf->rect; @@ -867,7 +867,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { r[3] = 0xff; r+=4; } - + av_free_packet(&packet); break; } -- cgit v1.2.3 From 8c6176b84688fae585952992676d56903113c040 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 13 Sep 2009 18:09:13 +0000 Subject: use Py_SetPythonHome rather then setting environment vars PYTHONHOME and PYTHONPATH --- source/blender/python/intern/bpy_interface.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index a85bcd011a6..a850809b4a5 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -259,8 +259,17 @@ void BPY_start_python_path(void) /* set the environment path */ printf("found bundled python: %s\n", py_path_bundle); +#if 0 BLI_setenv("PYTHONHOME", py_path_bundle); BLI_setenv("PYTHONPATH", py_path_bundle); +#endif + + { + static wchar_t py_path_bundle_wchar[FILE_MAXDIR]; + + mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); + Py_SetPythonHome(py_path_bundle_wchar); + } } -- cgit v1.2.3 From 334fefc12a9e0cd4b135190021fd222fbccc83ae Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 13 Sep 2009 19:22:36 +0000 Subject: == FFMPEG == fixes 2.4-branch according to trunk: update anim->curposition even if video frame decoding failed. Fixes nasty issues with DV-decoding on broken frames. Also: cleans up color conversion a little bit. --- source/blender/imbuf/intern/anim.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 3e09eb5e306..1aaba620f3a 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -608,7 +608,7 @@ static int startffmpeg(struct anim * anim) { anim->pFrameDeinterlaced = avcodec_alloc_frame(); anim->pFrameRGB = avcodec_alloc_frame(); - if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y) + if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y) != anim->x * anim->y * 4) { fprintf (stderr, "ffmpeg has changed alloc scheme ... ARGHHH!\n"); @@ -642,7 +642,7 @@ static int startffmpeg(struct anim * anim) { anim->pCodecCtx->pix_fmt, anim->pCodecCtx->width, anim->pCodecCtx->height, - PIX_FMT_BGR32, + PIX_FMT_RGBA, SWS_FAST_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL); @@ -671,11 +671,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { if (anim == 0) return (0); - ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0); + ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect, 0); avpicture_fill((AVPicture*) anim->pFrameRGB, (unsigned char*) ibuf->rect, - PIX_FMT_BGR32, anim->x, anim->y); + PIX_FMT_RGBA, anim->x, anim->y); if (position != anim->curposition + 1) { if (position > anim->curposition + 1 @@ -748,6 +748,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { if (frameFinished && !pos_found) { if (packet.dts >= pts_to_search) { pos_found = 1; + anim->curposition = position; } } @@ -778,7 +779,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { } } - if (G.order == B_ENDIAN) { + if (ENDIAN_ORDER == B_ENDIAN) { int * dstStride = anim->pFrameRGB->linesize; uint8_t** dst = anim->pFrameRGB->data; @@ -811,21 +812,21 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { for (y = 0; y < h; y++) { unsigned char tmp[4]; - unsigned long * tmp_l = - (unsigned long*) tmp; + unsigned int * tmp_l = + (unsigned int*) tmp; tmp[3] = 0xff; for (x = 0; x < w; x++) { - tmp[0] = bottom[3]; - tmp[1] = bottom[2]; - tmp[2] = bottom[1]; + tmp[0] = bottom[0]; + tmp[1] = bottom[1]; + tmp[2] = bottom[2]; - bottom[0] = top[3]; - bottom[1] = top[2]; - bottom[2] = top[1]; + bottom[0] = top[0]; + bottom[1] = top[1]; + bottom[2] = top[2]; bottom[3] = 0xff; - *(unsigned long*) top + *(unsigned int*) top = *tmp_l; bottom +=4; @@ -848,8 +849,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { 0, 0, 0 }; int i; unsigned char* r; - - + sws_scale(anim->img_convert_ctx, input->data, input->linesize, @@ -857,8 +857,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { anim->pCodecCtx->height, dst2, dstStride2); - - /* workaround: sws_scale + + /* workaround: sws_scale sets alpha = 0... */ r = (unsigned char*) ibuf->rect; @@ -867,7 +867,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { r[3] = 0xff; r+=4; } - + av_free_packet(&packet); break; } -- cgit v1.2.3 From be7eeb888af6cebe5d4162faa6e1b7551312410a Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sun, 13 Sep 2009 19:37:51 +0000 Subject: Sculpt UI *Changed Sculpt Modes Flip Direction to an enum so that you can explicitly choose Add or Subtract. *Expanded the sculpt tool list. I realize Nicolas has a longer term plan for the brush tools, but at least now it's useable again. --- release/ui/space_view3d_toolbar.py | 8 +++++--- source/blender/makesrna/intern/rna_brush.c | 14 ++++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 9dd2df14492..40ebb6883f0 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -399,7 +399,9 @@ class VIEW3D_PT_tools_brush(PaintPanel): elif context.sculpt_object and settings.brush: col = layout.column() col.itemS() - + col.itemR(brush, "sculpt_tool", expand=True) + col.itemS() + row = col.row(align=True) row.itemR(brush, "size", slider=True) row.itemR(brush, "size_pressure", toggle=True, text="") @@ -412,13 +414,13 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column() if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'): - col.itemR(brush, "flip_direction") + col.row().itemR(brush, "direction", expand=True) if brush.sculpt_tool == 'LAYER': col.itemR(brush, "persistent") col.itemO("sculpt.set_persistent_base") - col.itemR(brush, "sculpt_tool") + # Texture Paint Mode # diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 448a2046855..612863e1ab9 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -104,6 +104,11 @@ void rna_def_brush(BlenderRNA *brna) {IMB_BLEND_ERASE_ALPHA, "ERASE_ALPHA", 0, "Erase Alpha", "Erase alpha while painting."}, {IMB_BLEND_ADD_ALPHA, "ADD_ALPHA", 0, "Add Alpha", "Add alpha while painting."}, {0, NULL, 0, NULL, NULL}}; + + static const EnumPropertyItem prop_flip_direction_items[]= { + {0, "ADD", 0, "Add", "Add effect of brush"}, + {BRUSH_DIR_IN, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"}, + {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Brush", "ID"); RNA_def_struct_ui_text(srna, "Brush", "Brush datablock for storing brush settings for painting and sculpting."); @@ -117,6 +122,11 @@ void rna_def_brush(BlenderRNA *brna) prop= RNA_def_property(srna, "sculpt_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, brush_sculpt_tool_items); RNA_def_property_ui_text(prop, "Sculpt Tool", ""); + + prop= RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_flip_direction_items); + RNA_def_property_ui_text(prop, "Direction", "Mapping type to use for this image in the game engine."); /* number values */ prop= RNA_def_property(srna, "size", PROP_INT, PROP_NONE); @@ -192,10 +202,6 @@ void rna_def_brush(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ANCHORED); RNA_def_property_ui_text(prop, "Anchored", "Keep the brush anchored to the initial location."); - prop= RNA_def_property(srna, "flip_direction", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_DIR_IN); - RNA_def_property_ui_text(prop, "Flip Direction", "Move vertices in the opposite direction."); - prop= RNA_def_property(srna, "space", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE); RNA_def_property_ui_text(prop, "Space", "Limit brush application to the distance specified by spacing."); -- cgit v1.2.3 From 529e021a1fb7d767fde9353bfe3f9a9047b1c159 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 13 Sep 2009 19:39:04 +0000 Subject: BGE bug #19294: applying torque on a dynamic object turns it into a rigid body. --- source/gameengine/Physics/Bullet/CcdPhysicsController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 7f84b06cc3c..41842e977bb 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1072,7 +1072,7 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque { //workaround for incompatibility between 'DYNAMIC' game object, and angular factor //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque - const btVector3& angFac = body->getAngularFactor(); + const btVector3 angFac = body->getAngularFactor(); btVector3 tmpFac(1,1,1); body->setAngularFactor(tmpFac); body->applyTorque(torque); -- cgit v1.2.3 From f8657be654f89c6a4826ef8dd3e2275dfe2d4a5a Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 13 Sep 2009 20:59:25 +0000 Subject: *Ray counters (number of BB/primitive tests/hits and other raytrace counters) can now be enabled/disabled at compile-time. #define RE_RAYCOUNTER (/source/blender/render/extern/include/RE_raytrace.h) *Some other small organization on code (will be disable as this only matters for testing and developping) --- source/blender/render/extern/include/RE_raytrace.h | 41 ++------------ source/blender/render/intern/include/raycounter.h | 66 ++++++++++++++++++++++ source/blender/render/intern/include/rayobject.h | 51 +++++++++++++---- source/blender/render/intern/raytrace/bvh.h | 1 + source/blender/render/intern/source/rayobject.c | 2 +- .../render/intern/source/rayobject_raycounter.c | 1 + source/blender/render/intern/source/rayshade.c | 6 ++ source/blender/render/intern/source/shadeinput.c | 5 ++ 8 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 source/blender/render/intern/include/raycounter.h diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 8fc3a96ca99..0bdecb333e8 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -35,43 +35,12 @@ extern "C" { #endif +//#define RE_RAYCOUNTER /* enable counters per ray, usefull for measuring raytrace structures performance */ #define RE_RAY_LCTS_MAX_SIZE 256 #define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ //#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */ -#define RE_RAYCOUNTER - - -#ifdef RE_RAYCOUNTER - -typedef struct RayCounter RayCounter; -struct RayCounter -{ - - struct - { - unsigned long long test, hit; - - } faces, bb, simd_bb, raycast, raytrace_hint, rayshadow_last_hit; -}; - -/* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ -#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).raycounter) -void RE_RC_INFO (RayCounter *rc); -void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); -#define RE_RC_COUNT(var) (var)++ - -extern RayCounter re_rc_counter[]; - -#else - -#define RE_RC_INIT(isec,shi) -#define RE_RC_INFO(rc) -#define RE_RC_MERGE(dest,src) -#define RE_RC_COUNT(var) - -#endif /* Internals about raycasting structures can be found on intern/raytree.h */ @@ -79,6 +48,7 @@ typedef struct RayObject RayObject; typedef struct Isect Isect; typedef struct RayHint RayHint; typedef struct RayTraceHint RayTraceHint; +typedef struct RayCounter RayCounter; struct DerivedMesh; struct Mesh; @@ -95,17 +65,17 @@ void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max); /* void RE_rayobject_hint_cone(RayObject *r, RayHint *hint, float *); */ /* RayObject constructors */ - RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_bvh_create(int size); /* raytrace/rayobject_bvh.c */ RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ -RayObject* RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_vbvh.c */ -RayObject* RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_vbvh.c */ +RayObject* RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_qbvh.c */ +RayObject* RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_svbvh.c */ RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ + typedef struct LCTSHint LCTSHint; struct LCTSHint { @@ -166,7 +136,6 @@ struct Isect #ifdef RE_RAYCOUNTER RayCounter *raycounter; #endif - }; /* ray types */ diff --git a/source/blender/render/intern/include/raycounter.h b/source/blender/render/intern/include/raycounter.h new file mode 100644 index 00000000000..06579b366ee --- /dev/null +++ b/source/blender/render/intern/include/raycounter.h @@ -0,0 +1,66 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYCOUNTER_H +#define RE_RAYCOUNTER_H + +#include "RE_raytrace.h" + + +#ifdef RE_RAYCOUNTER + +typedef struct RayCounter RayCounter; +struct RayCounter +{ + + struct + { + unsigned long long test, hit; + + } faces, bb, simd_bb, raycast, raytrace_hint, rayshadow_last_hit; +}; + +/* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ +#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).raycounter) +void RE_RC_INFO (RayCounter *rc); +void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); +#define RE_RC_COUNT(var) (var)++ + +extern RayCounter re_rc_counter[]; + +#else + +# define RE_RC_INIT(isec,shi) +# define RE_RC_INFO(rc) +# define RE_RC_MERGE(dest,src) +# define RE_RC_COUNT(var) + +#endif + + +#endif diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 36b0d2692c0..2a9b42d22fe 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -67,7 +67,7 @@ extern "C" { 0 Self (reserved for each structure) 1 RayFace 2 RayObject (generic with API callbacks) - 3 unused + 3 RayObject_Vlak 0 means it's reserved and has it own meaning inside each ray acceleration structure (this way each structure can use the allign offset to determine if a node represents a @@ -77,6 +77,35 @@ extern "C" { described on RE_raytrace.h */ +/* used to align a given ray object */ +#define RE_rayobject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) + +/* used to unalign a given ray object */ +#define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) +#define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) +#define RE_rayobject_unalignRayVlak(o) ((RayObject*)(((intptr_t)o)|3)) + +/* used to test the type of ray object */ +#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) +#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) +#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) +#define RE_rayobject_isRayVlak(o) ((((intptr_t)o)&3) == 3) + + +/* + * This ray object represents faces directly from a given VlakRen structure. + * Thus allowing to save memory, but making code dependant on render structures +typedef struct RayVlak +{ + struct ObjectInstanceRen *ob; + struct VlakRen *face; +} RayVlak; + */ + +/* + * This ray object represents a triangle or a quad face. + * All data needed to realize intersection is "localy" available. + */ typedef struct RayFace { float v1[4], v2[4], v3[4], v4[3]; @@ -87,7 +116,15 @@ typedef struct RayFace } RayFace; #define RE_rayface_isQuad(a) ((a)->quad) +/* Loads a VlakRen on a RayFace */ +void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr); + + +/* + * This rayobject represents a generic object. With it's own callbacks for raytrace operations. + * It's suitable to implement things like LOD. + */ struct RayObject { struct RayObjectAPI *api; @@ -114,18 +151,8 @@ typedef struct RayObjectAPI } RayObjectAPI; -#define RE_rayobject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) -#define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) -#define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) -#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) -#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) -#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) -/* - * Loads a VlakRen on a RayFace - */ -void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr); /* * Extend min/max coords so that the rayobject is inside them @@ -152,6 +179,8 @@ int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as float RE_rayobject_cost(RayObject *r); + + #define ISECT_EPSILON ((float)FLT_EPSILON) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 7d3479e5331..f0302ddba3a 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -27,6 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ #include "rayobject.h" +#include "raycounter.h" #include "MEM_guardedalloc.h" #include "rayobject_rtbuild.h" #include "rayobject_hint.h" diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 73711272935..05308361fdb 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -34,7 +34,7 @@ #include "RE_raytrace.h" #include "render_types.h" #include "rayobject.h" - +#include "raycounter.h" /* * Determines the distance that the ray must travel to hit the bounding volume of the given node diff --git a/source/blender/render/intern/source/rayobject_raycounter.c b/source/blender/render/intern/source/rayobject_raycounter.c index b47df607c10..a82a21348c1 100644 --- a/source/blender/render/intern/source/rayobject_raycounter.c +++ b/source/blender/render/intern/source/rayobject_raycounter.c @@ -27,6 +27,7 @@ * ***** END GPL LICENSE BLOCK ***** */ #include "rayobject.h" +#include "raycounter.h" #ifdef RE_RAYCOUNTER diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 8733b89b88a..7e2cb4c6992 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -58,6 +58,7 @@ #include "RE_raytrace.h" #include "rayobject.h" +#include "raycounter.h" #define RAY_TRA 1 #define RAY_TRAFLIP 2 @@ -338,6 +339,9 @@ void makeraytree(Render *re) { float min[3], max[3], sub[3]; int i; + + re->i.infostr= "Make raytree"; + re->stats_draw(re->sdh, &re->i); BENCH(makeraytree_single(re), tree_build); @@ -351,6 +355,8 @@ void makeraytree(Render *re) sub[i] = max[i]-min[i]; } re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] ); + + re->i.infostr= "Raytree finished"; } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 0da2f0b1c9d..496d187cf05 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -44,6 +44,7 @@ #include "BKE_node.h" /* local include */ +#include "raycounter.h" #include "renderpipeline.h" #include "render_types.h" #include "renderdatabase.h" @@ -175,7 +176,9 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) float alpha; /* ------ main shading loop -------- */ +#ifdef RE_RAYCOUNTER memset(&shi->raycounter, 0, sizeof(shi->raycounter)); +#endif if(shi->mat->nodetree && shi->mat->use_nodes) { ntreeShaderExecTree(shi->mat->nodetree, shi, shr); @@ -221,6 +224,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) shr->z= -shi->co[2]; /* RAYHITS */ +/* if(1 || shi->passflag & SCE_PASS_RAYHITS) { shr->rayhits[0] = (float)shi->raycounter.faces.test; @@ -229,6 +233,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr) shr->rayhits[3] = 1.0; RE_RC_MERGE(&re_rc_counter[shi->thread], &shi->raycounter); } + */ } /* **************************************************************************** */ -- cgit v1.2.3 From 7e7a6a193e48ce8a34e11eebefbf2423c9c6b444 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sun, 13 Sep 2009 21:36:24 +0000 Subject: *Changed some userpref options to enums. *Tweaked curve UI slightly. --- release/ui/buttons_data_curve.py | 12 ++++++----- release/ui/buttons_data_text.py | 8 +++---- release/ui/space_userpref.py | 10 ++++----- source/blender/makesrna/intern/rna_userdef.c | 32 ++++++++++++++++++---------- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 94ad073d0bb..70904239d86 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -96,27 +96,29 @@ class DATA_PT_shape_curve(DataButtonsPanel): # col.itemL(text="NORMALS") # col.itemR(curve, "vertex_normal_flip") -class DATA_PT_geometry_curve(DataButtonsPanelCurve): - __label__ = "Geometry " +class DATA_PT_geometry_curve(DataButtonsPanel): + __label__ = "Geometry" def draw(self, context): layout = self.layout curve = context.curve - + split = layout.split() col = split.column() col.itemL(text="Modification:") col.itemR(curve, "width") col.itemR(curve, "extrude") - col.itemR(curve, "taper_object", icon='ICON_OUTLINER_OB_CURVE') + col.itemL(text="Taper Object:") + col.itemR(curve, "taper_object", text="") col = split.column() col.itemL(text="Bevel:") col.itemR(curve, "bevel_depth", text="Depth") col.itemR(curve, "bevel_resolution", text="Resolution") - col.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE') + col.itemL(text="Bevel Object:") + col.itemR(curve, "bevel_object", text="") class DATA_PT_pathanim(DataButtonsPanelCurve): diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py index d0e7ea09a92..2959f60a5f5 100644 --- a/release/ui/buttons_data_text.py +++ b/release/ui/buttons_data_text.py @@ -36,9 +36,7 @@ class DATA_PT_shape_text(DataButtonsPanel): ob = context.object curve = context.curve - space = context.space_data - - layout.itemR(curve, "curve_2d") + space = context.space_data split = layout.split() @@ -55,8 +53,8 @@ class DATA_PT_shape_text(DataButtonsPanel): col = split.column() col.itemL(text="Resolution:") sub = col.column(align=True) - sub.itemR(curve, "resolution_u", text="Preview U") - sub.itemR(curve, "render_resolution_u", text="Render U") + sub.itemR(curve, "resolution_u", text="Preview") + sub.itemR(curve, "render_resolution_u", text="Render") # resolution_v is not used for text diff --git a/release/ui/space_userpref.py b/release/ui/space_userpref.py index 1e7a9b581d4..cfdabadcee1 100644 --- a/release/ui/space_userpref.py +++ b/release/ui/space_userpref.py @@ -156,15 +156,15 @@ class USERPREF_PT_edit(bpy.types.Panel): sub = col.split(percentage=0.85) sub1 = sub.column() - sub1.itemL(text="Materials:") - sub1.itemR(edit, "material_linked_object", text="Linked to Object") - sub1.itemR(edit, "material_linked_obdata", text="Linked to ObData") + sub1.itemL(text="Link Materials To:") + sub1.row().itemR(edit, "material_link", expand=True) sub1.itemS() sub1.itemS() sub1.itemS() sub1.itemL(text="New Objects:") sub1.itemR(edit, "enter_edit_mode") - sub1.itemR(edit, "align_to_view") + sub1.itemL(text="Align To:") + sub1.row().itemR(edit, "object_align", expand=True) sub1.itemS() sub1.itemS() sub1.itemS() @@ -185,9 +185,9 @@ class USERPREF_PT_edit(bpy.types.Panel): sub1.itemL(text="Grease Pencil:") sub1.itemR(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance") sub1.itemR(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance") - sub1.itemR(edit, "grease_pencil_smooth_stroke", text="Smooth Stroke") # sub1.itemR(edit, "grease_pencil_simplify_stroke", text="Simplify Stroke") sub1.itemR(edit, "grease_pencil_eraser_radius", text="Eraser Radius") + sub1.itemR(edit, "grease_pencil_smooth_stroke", text="Smooth Stroke") col = split.column() sub = col.split(percentage=0.85) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ffc3f1696fc..1a000525fda 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1766,28 +1766,38 @@ static void rna_def_userdef_edit(BlenderRNA *brna) {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""}, {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem material_link_items[]= { + {0, "OBDATA", 0, "ObData", "Toggle whether the material is linked to object data or the object block."}, + {USER_MAT_ON_OB, "OBJECT", 0, "Object", "Toggle whether the material is linked to object data or the object block."}, + {0, NULL, 0, NULL, NULL}}; + + static const EnumPropertyItem object_align_items[]= { + {0, "WORLD", 0, "World", "Align newly added objects facing the 3D View direction"}, + {USER_ADD_VIEWALIGNED, "VIEW", 0, "View", "Align newly added objects to the world coordinates"}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "UserPreferencesEdit", NULL); RNA_def_struct_sdna(srna, "UserDef"); RNA_def_struct_nested(brna, srna, "UserPreferences"); RNA_def_struct_ui_text(srna, "Edit Methods", "Settings for interacting with Blender data."); /* Edit Methods */ - prop= RNA_def_property(srna, "material_linked_object", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_MAT_ON_OB); - RNA_def_property_ui_text(prop, "Material Linked Object", "Toggle whether the material is linked to object data or the object block."); - - prop= RNA_def_property(srna, "material_linked_obdata", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_MAT_ON_OB); - RNA_def_property_ui_text(prop, "Material Linked ObData", "Toggle whether the material is linked to object data or the object block."); + + prop= RNA_def_property(srna, "material_link", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, material_link_items); + RNA_def_property_ui_text(prop, "Material Link To", "Toggle whether the material is linked to object data or the object block"); + + prop= RNA_def_property(srna, "object_align", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, object_align_items); + RNA_def_property_ui_text(prop, "Align Object To", "Align newly added objects facing the 3D View direction or the world coordinates"); prop= RNA_def_property(srna, "enter_edit_mode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_ADD_EDITMODE); RNA_def_property_ui_text(prop, "Enter Edit Mode", "Enter Edit Mode automatically after adding a new object."); - prop= RNA_def_property(srna, "align_to_view", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_ADD_VIEWALIGNED); - RNA_def_property_ui_text(prop, "Align To View", "Align newly added objects facing the 3D View direction."); - prop= RNA_def_property(srna, "drag_immediately", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_DRAGIMMEDIATE); RNA_def_property_ui_text(prop, "Drag Immediately", "Moving things with a mouse drag doesn't require a click to confirm (Best for tablet users)."); -- cgit v1.2.3 From a4532b202b960fcff3049fa047c8e828802e91ce Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sun, 13 Sep 2009 22:08:27 +0000 Subject: Prepare for removal of FFMPEG from extern. make clean and full rebuild recommended. --- extern/Makefile | 9 --------- source/nan_definitions.mk | 12 +++--------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/extern/Makefile b/extern/Makefile index 1bebf1e1994..b81fbd2b91a 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -32,15 +32,6 @@ SOURCEDIR = extern DIR = $(OCGDIR)/extern DIRS = glew/src -ifeq ($(WITH_FFMPEG), true) -ifeq ($(NAN_FFMPEG), $(LCGDIR)/ffmpeg) - DIRS += ffmpeg -endif -ifeq ($(NAN_FFMPEG), $(LCGDIR)/gcc/ffmpeg) - DIRS += ffmpeg -endif -endif - # Cloth requires it #ifneq ($(NAN_NO_KETSJI), true) DIRS += bullet2 diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index f8afc7f3fa6..8c47bcf11c1 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -138,9 +138,9 @@ ifndef CONFIG_GUESS endif ifeq ($(NAN_USE_FFMPEG_CONFIG), true) - export NAN_FFMPEG ?= $(shell ffmpeg-config --prefix) - export NAN_FFMPEGLIBS ?= $(shell ffmpeg-config --libs avformat avcodec) - export NAN_FFMPEGCFLAGS ?= $(shell ffmpeg-config --cflags) + export NAN_FFMPEG = $(shell pkg-config --variable=prefix libavcodec) # Assume they are all in the same prefix + export NAN_FFMPEGLIBS = $(shell pkg-config --libs libavcodec libavdevice libavformat libswscale libavutil) + export NAN_FFMPEGCFLAGS = $(shell pkg-config --cflags libavcodec libavdevice libavformat libswscale libavutil) endif # Platform Dependent settings go below: @@ -336,12 +336,6 @@ ifndef CONFIG_GUESS export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags) export NAN_SAMPLERATE ?= /usr -ifneq ($(NAN_USE_FFMPEG_CONFIG), true) - export NAN_FFMPEG ?= /usr - export NAN_FFMPEGLIBS ?= -L$(NAN_FFMPEG)/lib -lavformat -lavcodec -lavutil -lswscale -lavdevice -ldts -lz - export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include -endif - ifeq ($(WITH_OPENEXR), true) export NAN_OPENEXR ?= $(shell pkg-config --variable=prefix OpenEXR ) export NAN_OPENEXR_INC ?= $(shell pkg-config --cflags OpenEXR ) -- cgit v1.2.3 From 492f6589c4857d207810f7b546817c2ae35184c8 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sun, 13 Sep 2009 22:33:47 +0000 Subject: New 'icon_only' wasn't actually exposed in the ui api, causing errors in the py scripts, so I added it to ItemR. Also reverted Joshua's temporary fix, which didn't seem to help much and was making the render engine menu too small. --- source/blender/makesrna/intern/rna_ui_api.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index ab2dfe5e33c..e3cae8ab453 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -37,17 +37,15 @@ #ifdef RNA_RUNTIME -static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle) +static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle, int icon_only) { int flag= 0; flag |= (slider)? UI_ITEM_R_SLIDER: 0; flag |= (expand)? UI_ITEM_R_EXPAND: 0; flag |= (toggle)? UI_ITEM_R_TOGGLE: 0; + flag |= (icon_only)? UI_ITEM_R_ICON_ONLY: 0; - // XXX: an 'icon_only' prop should be added instead, but for now, this makes ptrs look ok - flag |= (name && name[0]==0)? UI_ITEM_R_ICON_ONLY: 0; - uiItemR(layout, name, icon, ptr, propname, flag); } @@ -148,6 +146,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); RNA_def_boolean(func, "slider", 0, "", "Use slider widget for numeric values."); RNA_def_boolean(func, "toggle", 0, "", "Use toggle widget for boolean values."); + RNA_def_boolean(func, "icon_only", 0, "", "Only show the property's icon, with no text"); func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); api_ui_item_rna_common(func); -- cgit v1.2.3 From ccf847585d3f075a16ca05ed41498c9e9e7ffb6a Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sun, 13 Sep 2009 22:34:47 +0000 Subject: Make compiler easily to override (CC & CCC) and clean up whitespace. --- source/nan_compile.mk | 140 +++++++++++++++++++++++++------------------------- source/nan_warn.mk | 23 ++++----- 2 files changed, 81 insertions(+), 82 deletions(-) diff --git a/source/nan_compile.mk b/source/nan_compile.mk index c62b4f2681b..8d4da1e2790 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -62,27 +62,27 @@ ifdef NAN_DEBUG CCFLAGS += $(NAN_DEBUG) endif -REL_CFLAGS += -DNDEBUG -REL_CCFLAGS += -DNDEBUG -DBG_CFLAGS += -g -DBG_CCFLAGS += -g +REL_CFLAGS += -DNDEBUG +REL_CCFLAGS += -DNDEBUG +DBG_CFLAGS += -g +DBG_CCFLAGS += -g # OS dependent parts --------------------------------------------------- ifeq ($(OS),darwin) - CC = gcc - CCC = g++ - ifeq ($(CPU),powerpc) - CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - else - CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - endif -# REL_CFLAGS += -O -# REL_CCFLAGS += -O2 - CPPFLAGS += -D_THREAD_SAFE - NAN_DEPEND = true + CC ?= gcc + CCC ?= g++ + ifeq ($(CPU),powerpc) + CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + else + CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + endif +# REL_CFLAGS += -O +# REL_CCFLAGS += -O2 + CPPFLAGS += -D_THREAD_SAFE + NAN_DEPEND = true OPENGL_HEADERS = /System/Library/Frameworks/OpenGL.framework AR = ar ARFLAGS = ruv @@ -91,28 +91,28 @@ ifeq ($(OS),darwin) endif ifeq ($(OS),freebsd) - CC = gcc - CCC = g++ + CC ?= gcc + CCC ?= g++ JAVAC = javac JAVAH = javah - CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 - CPPFLAGS += -D_THREAD_SAFE - NAN_DEPEND = true + CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + REL_CFLAGS += -O2 + REL_CCFLAGS += -O2 + CPPFLAGS += -D_THREAD_SAFE + NAN_DEPEND = true OPENGL_HEADERS = /usr/X11R6/include JAVA_HEADERS = /usr/local/jdk1.3.1/include JAVA_SYSTEM_HEADERS = /usr/local/jdk1.3.1/include/freebsd - AR = ar + AR = ar ARFLAGS = ruv ARFLAGSQUIET = ru endif ifeq ($(OS),irix) ifeq ($(IRIX_USE_GCC),true) - CC = gcc - CCC = g++ + CC ?= gcc + CCC ?= g++ CFLAGS += -fPIC -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4 CCFLAGS += -fPIC -fpermissive -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4 REL_CFLAGS += -O2 @@ -121,16 +121,16 @@ ifeq ($(OS),irix) DBG_CFLAGS += -g3 -gdwarf-2 -ggdb DBG_CCFLAGS += -g3 -gdwarf-2 -ggdb else - CC = cc - CCC = CC - CFLAGS += -n32 -mips3 -Xcpluscomm - CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std + CC ?= cc + CCC ?= CC + CFLAGS += -n32 -mips3 -Xcpluscomm + CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std ifdef MIPS73_ISOHEADERS - CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS) + CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS) else - CCFLAGS += -LANG:libc_in_namespace_std=off + CCFLAGS += -LANG:libc_in_namespace_std=off endif - REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 + REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 REL_CCFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 endif OPENGL_HEADERS = /usr/include @@ -141,14 +141,14 @@ ifeq ($(OS),irix) endif ifeq ($(OS),linux) - CC = gcc - CCC = g++ -# CFLAGS += -pipe - CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -# CCFLAGS += -pipe - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 + CC ?= gcc + CCC ?= g++ +# CFLAGS += -pipe +# CCFLAGS += -pipe + CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + REL_CFLAGS += -O2 + REL_CCFLAGS += -O2 NAN_DEPEND = true ifeq ($(CPU),alpha) CFLAGS += -mieee @@ -160,11 +160,11 @@ ifeq ($(OS),linux) endif ifeq ($(OS),openbsd) - CC = gcc - CCC = g++ - CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - REL_CFLAGS += -O2 + CC ?= gcc + CCC ?= g++ + CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + REL_CFLAGS += -O2 REL_CCFLAGS += -O2 NAN_DEPEND = true CPPFLAGS += -D__FreeBSD__ @@ -177,30 +177,30 @@ endif ifeq ($(OS),solaris) # Adding gcc flag to $CC is not good, however if its not there makesdna wont build - Campbell ifeq (x86_64, $(findstring x86_64, $(CPU))) - CC = gcc -m64 - CCC = g++ -m64 + CC ?= gcc -m64 + CCC ?= g++ -m64 else - CC = gcc - CCC = g++ - #CC = cc - #CCC = CC + CC ?= gcc + CCC ?= g++ + #CC ?= cc + #CCC ?= CC endif JAVAC = javac JAVAH = javah - CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -# CFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned" -# CCFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned" + CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing +# CFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -KPIC -DPIC -xchar=unsigned" +# CCFLAGS += "-fast -xdepend -xarch=v8plus -xO3 -xlibmil -xlibmopt -features=tmplife -norunpath -KPIC -DPIC -xchar=unsigned" # Note, you might still want to compile a 32 bit binary if you have a 64bit system. if so remove the following lines # ifeq ($(findstring 64,$(CPU)), 64) -# CFLAGS += -m64 -# CCFLAGS += -m64 +# CFLAGS += -m64 +# CCFLAGS += -m64 # endif - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 + REL_CFLAGS += -O2 + REL_CCFLAGS += -O2 NAN_DEPEND = true # ifeq ($(CPU),sparc) @@ -211,7 +211,7 @@ ifeq ($(OS),solaris) JAVA_SYSTEM_HEADERS = /usr/java/include/solaris else # OPENGL_HEADERS = /usr/X11/include/mesa - OPENGL_HEADERS = /usr/X11/include/ + OPENGL_HEADERS = /usr/X11/include/ endif AR = ar ARFLAGS = ruv @@ -220,8 +220,8 @@ endif ifeq ($(OS),windows) ifeq ($(FREE_WINDOWS),true) - CC = gcc - CCC = g++ + CC ?= gcc + CCC ?= g++ CFLAGS += -pipe -mno-cygwin -mwindows -funsigned-char -fno-strict-aliasing CCFLAGS += -pipe -mno-cygwin -mwindows -funsigned-char -fno-strict-aliasing CPPFLAGS += -DFREE_WINDOWS @@ -233,16 +233,16 @@ ifeq ($(OS),windows) AR = ar ARFLAGS = ruv ARFLAGSQUIET = ru - WINRC = $(wildcard *.rc) + WINRC = $(wildcard *.rc) RANLIB = ranlib else - CC = $(SRCHOME)/tools/cygwin/cl_wrapper.pl - CCC = $(SRCHOME)/tools/cygwin/cl_wrapper.pl + CC ?= $(SRCHOME)/tools/cygwin/cl_wrapper.pl + CCC ?= $(SRCHOME)/tools/cygwin/cl_wrapper.pl JAVAC = $(SRCHOME)/tools/cygwin/java_wrapper.pl -c JAVAH = $(SRCHOME)/tools/cygwin/java_wrapper.pl -h - REL_CFLAGS += /O2 + REL_CFLAGS += /O2 REL_CCFLAGS += /O2 -GX - DBG_CFLAGS += /Fd$(DIR)/debug/ + DBG_CFLAGS += /Fd$(DIR)/debug/ DBG_CCFLAGS += /Fd$(DIR)/debug/ CFLAGS += /MT CCFLAGS += /MT diff --git a/source/nan_warn.mk b/source/nan_warn.mk index 5841cdf5908..b685c13604d 100644 --- a/source/nan_warn.mk +++ b/source/nan_warn.mk @@ -52,16 +52,15 @@ else # # Irix warning info # - # 1001 # the source file does not end w/ a newline - # 1110 # unreachable statement - # 1201 # trailing comma in enums is nonstandard - # 1209 # constant controlling expressions - # 1355 # extra semicolon is ignored - # 1424 # unreferenced template paramaters - # 1681 # virtual function override - # 3201 # unreferenced formal paramaters + # 1001 # the source file does not end w/ a newline + # 1110 # unreachable statement + # 1201 # trailing comma in enums is nonstandard + # 1209 # constant controlling expressions + # 1355 # extra semicolon is ignored + # 1424 # unreferenced template paramaters + # 1681 # virtual function override + # 3201 # unreferenced formal paramaters # - LEVEL_1_C_WARNINGS = -fullwarn -woff 1001,1110,1201,1209,1355,1424,1681,3201 endif endif @@ -79,7 +78,7 @@ else ifeq ($(CCC),CC) ifeq ($(OS),irix) # MIPSpro Compilers - # see warning descriptions above + # see warning descriptions above LEVEL_1_CPP_WARNINGS = -woff 1001,1110,1201,1209,1355,1424,1681,3201 endif endif @@ -111,7 +110,7 @@ else ifeq ($(CC),cc) ifeq ($(OS),irix) # MIPSpro Compilers - # see warning descriptions above + # see warning descriptions above LEVEL_2_C_WARNINGS = -fullwarn -woff 1001,1209,1424,3201 endif ifeq ($(OS),solaris) @@ -148,7 +147,7 @@ else ifeq ($(CCC),CC) ifeq ($(OS),irix) # MIPSpro Compilers - # see warning descriptions above + # see warning descriptions above LEVEL_2_CPP_WARNINGS = -fullwarn -woff 1209,1424,3201 endif endif -- cgit v1.2.3 From cf20399993566ce15b4af8c558394eb3a6e391c8 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 13 Sep 2009 23:58:03 +0000 Subject: Pointcache: * reset on object transformations --- source/blender/editors/transform/transform_conversions.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 6386c0d4eb7..776f2e47d1e 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4946,8 +4946,18 @@ void special_aftertrans_update(TransInfo *t) ob= base->object; if (base->flag & SELECT && (t->mode != TFM_DUMMY)) { + ListBase pidlist; + PTCacheID *pid; + + /* flag object caches as outdated */ + BKE_ptcache_ids_from_object(&pidlist, ob); + 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; + } + /* pointcache refresh */ - if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) + if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED)) ob->recalc |= OB_RECALC_DATA; /* Needed for proper updating of "quick cached" dynamics. */ -- cgit v1.2.3 From 9f5e42ff7622b5b2dd0ef711769ecc541126efb5 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 00:01:08 +0000 Subject: Smoke: * Totally new try to get cache running * Didn't try "bake" and such things yet Hint * Very verbose yet * Please do only test new blend files, not old ones! Please give me feedback on my blog about the old crashers. --- intern/smoke/intern/FLUID_3D.cpp | 3 + intern/smoke/intern/FLUID_3D.h | 2 +- intern/smoke/intern/FLUID_3D_STATIC.cpp | 18 ++- intern/smoke/intern/smoke_API.cpp | 3 +- source/blender/blenkernel/intern/smoke.c | 188 ++++++------------------------- 5 files changed, 50 insertions(+), 164 deletions(-) diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 7574a0ec16e..8a32eaa2e68 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -182,6 +182,9 @@ void FLUID_3D::initBlenderRNA(float *alpha, float *beta) ////////////////////////////////////////////////////////////////////// void FLUID_3D::step() { + // addSmokeTestCase(_density, _res); + // addSmokeTestCase(_heat, _res); + // wipe forces for (int i = 0; i < _totalCells; i++) { diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h index 9d9e7318204..a7be7f58335 100644 --- a/intern/smoke/intern/FLUID_3D.h +++ b/intern/smoke/intern/FLUID_3D.h @@ -47,7 +47,7 @@ class FLUID_3D void initVectorNoise(int amplify); void addSmokeColumn(); - static void addSmokeTestCase(float* field, Vec3Int res, float value); + static void addSmokeTestCase(float* field, Vec3Int res); void step(); void addObstacle(OBSTACLE* obstacle); diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index 4909c071c3d..2d3ec125c2b 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -44,8 +44,8 @@ void FLUID_3D::addSmokeColumn() { // generic static version, so that it can be applied to the // WTURBULENCE grid as well ////////////////////////////////////////////////////////////////////// -/* -void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value) + +void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res) { const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res); float dx = 1.0f / (float)maxRes; @@ -57,22 +57,22 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value) float heighMin = 0.05; float heighMax = 0.10; - for (int y = 0; y < res[1]; y++) - for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[1]); z++) + for (int y = 0; y < res[2]; y++) + for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++) for (int x = 0; x < res[0]; x++) { float xLength = x * dx - xTotal * 0.4f; - float yLength = y * dx - zTotal * 0.5f; + float yLength = y * dx - yTotal * 0.5f; float radius = sqrtf(xLength * xLength + yLength * yLength); if (radius < 0.075f * xTotal) { int index = x + y * res[0] + z * slabSize; - field[index] = value; + field[index] = 1.0f; } } } -*/ + ////////////////////////////////////////////////////////////////////// // set x direction to Neumann boundary conditions @@ -295,12 +295,10 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const const int xres = res[0]; const int yres = res[1]; const int zres = res[2]; - static int hits = 0; - static int total = 0; const int slabSize = res[0] * res[1]; // scale dt up to grid resolution -#if PARALLEL==1 && !_WIN32 +#if PARALLEL==1 #pragma omp parallel #pragma omp for schedule(static) #endif diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index 058831dddbb..67df6e805d8 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -81,8 +81,7 @@ extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr) extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid) { - if(wt) - wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); + wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); } extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index af79fd74ae8..67744ab56a2 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -167,6 +167,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive // calc other res with max_res provided VECSUB(size, max, min); + printf("size: %f, %f, %f\n", size[0], size[1], size[2]); + // prevent crash when initializing a plane as domain if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) return 0; @@ -210,6 +212,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive } } + printf("smd->domain->dx: %f\n", smd->domain->dx); + // TODO: put in failsafe if res<=0 - dg // printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]); @@ -595,11 +599,6 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) smoke_turbulence_free(smd->domain->wt); smd->domain->wt = NULL; } - - smd->domain->point_cache[1]->flag &= ~PTCACHE_SIMULATION_VALID; - smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED; - smd->domain->point_cache[1]->simframe= 0; - smd->domain->point_cache[1]->last_exact= 0; } void smokeModifier_reset(struct SmokeModifierData *smd) @@ -617,17 +616,15 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; } - - smd->domain->point_cache[0]->flag &= ~PTCACHE_SIMULATION_VALID; + smd->domain->point_cache[0]->flag |= PTCACHE_OUTDATED; - smd->domain->point_cache[0]->simframe= 0; - smd->domain->point_cache[0]->last_exact= 0; + smd->domain->point_cache[1]->flag |= PTCACHE_OUTDATED; smokeModifier_reset_turbulence(smd); smd->time = -1; - // printf("reset domain end\n"); + printf("reset domain end\n"); } else if(smd->flow) { @@ -841,7 +838,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue; // VECCOPY(pos, pa->state.co); // Mat4MulVecfl (ob->imat, pos); - // 1. get corresponding cell + // 1. get corresponding cell get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0); // check if cell is valid (in the domain boundary) for(i = 0; i < 3; i++) @@ -1102,214 +1099,103 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) { + SmokeDomainSettings *sds = smd->domain; + float light[3]; PointCache *cache = NULL; PTCacheID pid; PointCache *cache_wt = NULL; PTCacheID pid_wt; + int startframe, endframe, framenr; float timescale; int cache_result = 0, cache_result_wt = 0; - int startframe, endframe, framenr, badloading = 0; - SmokeDomainSettings *sds = smd->domain; - float light[3]; framenr = scene->r.cfra; - cache = sds->point_cache[0]; + printf("time: %d\n", scene->r.cfra); + + if(framenr == smd->time) + return; + cache = sds->point_cache[0]; BKE_ptcache_id_from_smoke(&pid, ob, smd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); cache_wt = sds->point_cache[1]; BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd); - /* handle continuous simulation with the play button */ - if(BKE_ptcache_get_continue_physics()) - { - // TODO - return; - } - if(framenr < startframe) - { - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - cache->last_exact= 0; - - cache_wt->flag &= ~PTCACHE_SIMULATION_VALID; - cache_wt->simframe= 0; - cache_wt->last_exact= 0; - - // we got back in time, reset smoke in this case (TODO: use cache later) - // smd->time = scene->r.cfra; - // smokeModifier_reset(smd); - return; - } - else if(framenr > endframe) - { - framenr = endframe; - // we load last valid frame here - // and don't update the smd->time variable later - badloading = 1; - } + if(framenr > endframe) + return; - if(!(cache->flag & PTCACHE_SIMULATION_VALID)) + if(!smd->domain->fluid) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - } - if(sds->wt && !(cache_wt->flag & PTCACHE_SIMULATION_VALID)) - { BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED); } - if(smd->time == -1 && framenr!= startframe) - return; - if(!smokeModifier_init(smd, ob, scene, dm)) + { + printf("bad smokeModifier_init\n"); return; - - if(!smd->domain->fluid) - return; + } /* try to read from cache */ cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec); - // printf("cache_result: %d\n", cache_result); + printf("cache_result: %d\n", cache_result); if(cache_result == PTCACHE_READ_EXACT) { - SmokeDomainSettings *sds = smd->domain; - cache->flag |= PTCACHE_SIMULATION_VALID; cache->simframe= framenr; - sds->v3dnum = framenr; - - if(!badloading) - smd->time = scene->r.cfra; - // check for wt cache if(sds->wt) { cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec); - // printf("cache_result_wt: %d\n", cache_result_wt); - - // error handling + if(cache_result_wt == PTCACHE_READ_EXACT) { cache_wt->flag |= PTCACHE_SIMULATION_VALID; cache_wt->simframe= framenr; } - else if(cache_result_wt==PTCACHE_READ_OLD) - { - BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE); - cache_wt->flag |= PTCACHE_SIMULATION_VALID; - } - else if(ob->id.lib || (cache_wt->flag & PTCACHE_BAKED)) - { - // if baked and nothing in cache, do nothing - cache_wt->flag &= ~PTCACHE_SIMULATION_VALID; - cache_wt->simframe= 0; - cache_wt->last_exact= 0; - } } - - // printf("PTCACHE_READ_EXACT\n"); return; } - else if(cache_result==PTCACHE_READ_OLD) - { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); - cache->flag |= PTCACHE_SIMULATION_VALID; - - BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_FREE); - cache_wt->flag |= PTCACHE_SIMULATION_VALID; - } - else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) - { - // if baked and nothing in cache, do nothing - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - cache->last_exact= 0; - - cache_wt->flag &= ~PTCACHE_SIMULATION_VALID; - cache_wt->simframe= 0; - cache_wt->last_exact= 0; - - // printf("PTCACHE_BAKED\n"); - return; - } - /* - else if((cache_result==0) && ((startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID || (framenr == smd->time)))) - { - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - cache->last_exact= 0; - - return; - }*/ - - // printf("framenr: %d, time: %f\n", framenr, smd->time); - /* do simulation */ - - // low res - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - - if(sds->wt) - { - cache_wt->flag |= PTCACHE_SIMULATION_VALID; - cache_wt->simframe= framenr; - } - - tstart(); - - if(sds->flags & MOD_SMOKE_DISSOLVE) - { - smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - } + tstart(); smoke_calc_domain(scene, ob, smd); // set new time smd->time = scene->r.cfra; - // frame 1 is start, don't simulate anything - if(smd->time == 1) - { - // set new time - smd->time = scene->r.cfra; - - BKE_ptcache_write_cache(&pid, framenr); - if(sds->wt) - BKE_ptcache_write_cache(&pid_wt, framenr); - - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + /* do simulation */ - // printf("smd->time: %f\n", smd->time); - return; - } + // low res + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->simframe= framenr; // simulate the actual smoke (c++ code in intern/smoke) - smoke_step(sds->fluid, smd->time); + if(framenr!=startframe) + smoke_step(sds->fluid, smd->time); BKE_ptcache_write_cache(&pid, framenr); if(sds->wt) { + if(framenr!=startframe) + smoke_turbulence_step(sds->wt, sds->fluid); - if(sds->flags & MOD_SMOKE_DISSOLVE) - smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - - smoke_turbulence_step(sds->wt, sds->fluid); + cache_wt->flag |= PTCACHE_SIMULATION_VALID; + cache_wt->simframe= framenr; BKE_ptcache_write_cache(&pid_wt, framenr); } if(get_lamp(scene, light)) smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); - + tend(); - // printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() ); + printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() ); } } -- cgit v1.2.3 From a11ef8030aecfe80e4718b6000ea32d2bbc062a9 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 14 Sep 2009 05:00:03 +0000 Subject: 2.5 mesh cleanup: merge tools all work again --- source/blender/editors/mesh/editmesh_tools.c | 60 ++++++++++++++++++++++++---- source/blender/makesdna/DNA_modifier_types.h | 5 ++- source/blender/windowmanager/intern/wm.c | 6 ++- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 5a4397256de..9c8e8e11e86 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -98,8 +98,6 @@ static void waitcursor(int val) {} static int pupmenu() {return 0;} static int qtest() {return 0;} #define add_numbut(a, b, c, d, e, f, g) {} -static int snap_sel_to_curs() {return 0;} -static int snap_to_center() {return 0;} /* XXX */ @@ -5735,13 +5733,59 @@ int merge_firstlast(EditMesh *em, int first, int uvmerge) return removedoublesflag(em, 1, 0, MERGELIMIT); } -int merge_target(EditMesh *em, int target, int uvmerge) +void em_snap_to_center(EditMesh *em) +{ + EditVert *eve; + float cent[3] = {0.0f, 0.0f, 0.0f}; + int i=0; + + for (eve=em->verts.first; eve; eve=eve->next) { + if (eve->f & SELECT) { + VecAddf(cent, cent, eve->co); + i++; + } + } + + if (!i) + return; + + VecMulf(cent, 1.0f / (float)i); + + for (eve=em->verts.first; eve; eve=eve->next) { + if (eve->f & SELECT) { + VECCOPY(eve->co, cent); + } + } +} + +void em_snap_to_cursor(EditMesh *em, bContext *C) +{ + Scene *scene = CTX_data_scene(C); + Object *ob= CTX_data_edit_object(C); + View3D *v3d = CTX_wm_view3d(C); + EditVert *eve; + float co[3], *vco, invmat[4][4]; + + Mat4Invert(invmat, ob->obmat); + + vco = give_cursor(scene, v3d); + VECCOPY(co, vco); + Mat4MulVecfl(invmat, co); + + for (eve=em->verts.first; eve; eve=eve->next) { + if (eve->f & SELECT) { + VECCOPY(eve->co, co); + } + } +} + +int merge_target(bContext *C, EditMesh *em, int target, int uvmerge) { EditVert *eve; // XXX not working - if(target) snap_sel_to_curs(); - else snap_to_center(); + if(target) em_snap_to_cursor(em, C); + else em_snap_to_center(em); if(uvmerge && CustomData_has_layer(&em->fdata, CD_MTFACE)){ for(eve=em->verts.first; eve; eve=eve->next) eve->f1 = 0; @@ -5763,10 +5807,10 @@ static int merge_exec(bContext *C, wmOperator *op) switch(RNA_enum_get(op->ptr, "type")) { case 3: - count = merge_target(em, 0, uvs); + count = merge_target(C, em, 0, uvs); break; case 4: - count = merge_target(em, 1, uvs); + count = merge_target(C, em, 1, uvs); break; case 1: count = merge_firstlast(em, 0, uvs); @@ -5774,7 +5818,7 @@ static int merge_exec(bContext *C, wmOperator *op) case 6: count = merge_firstlast(em, 1, uvs); break; - case 2: + case 5: count = collapseEdges(em); break; } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index be7452c4ae1..d58488ce82d 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -469,8 +469,9 @@ typedef struct BooleanModifierData { int operation, pad; } BooleanModifierData; -#define MOD_MDEF_INVERT_VGROUP (1<<0) -#define MOD_MDEF_DYNAMIC_BIND (1<<1) +#define MOD_MDEF_INVERT_VGROUP (1<<0) +#define MOD_MDEF_DYNAMIC_BIND (1<<1) +#define MOD_MDEF_USE_FINAL (1<<2) typedef struct MDefInfluence { int vertex; diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 38cf39c2081..651394d51af 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -75,9 +75,11 @@ void WM_operator_free(wmOperator *op) } if(op->macro.first) { - wmOperator *opm; - for(opm= op->macro.first; opm; opm= opm->next) + wmOperator *opm, *opmnext; + for(opm= op->macro.first; opm; opm= opmnext) { + opmnext = opm->next; WM_operator_free(opm); + } } MEM_freeN(op); -- cgit v1.2.3 From 894c1e98ad398d3970ea928c0a9db8f34e5dbef4 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 14 Sep 2009 06:06:01 +0000 Subject: remove doubles uses an operator property for the merge distance. it no longer reports number of merged verts to the user, as this violates operator nonmodality and messes up last operator panel workflow. --- source/blender/editors/mesh/editmesh_tools.c | 7 +++++-- source/blender/editors/mesh/mesh_ops.c | 10 +++++++++- source/blender/makesdna/DNA_modifier_types.h | 1 - 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9c8e8e11e86..7698faf3178 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -486,13 +486,14 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op) EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); char msg[100]; - int cnt = removedoublesflag(em,1,0,ts->doublimit); + int cnt = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); + /*XXX this messes up last operator panel if(cnt) { sprintf(msg, "Removed %d vertices", cnt); BKE_report(op->reports, RPT_INFO, msg); - } + }*/ DAG_id_flush_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); @@ -514,6 +515,8 @@ void MESH_OT_remove_doubles(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_float(ot->srna, "limit", 0.00001f, 0.000001f, 50.0f, "Merge Threshold", "Minimum distance between merged verts", 0.00001f, 10.0f); } // XXX is this needed? diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 3cdf1d47817..5be39a3e4f1 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -335,6 +335,12 @@ void ED_operatortypes_mesh(void) WM_operatortype_macro_define(ot, "MESH_OT_extrude"); WM_operatortype_macro_define(ot, "TFM_OT_translate"); + /*combining operators with invoke and exec portions doesn't work yet. + + ot= WM_operatortype_append_macro("MESH_OT_loopcut", "Loopcut", OPTYPE_UNDO|OPTYPE_REGISTER); + WM_operatortype_macro_define(ot, "MESH_OT_edgering_select"); + WM_operatortype_macro_define(ot, "MESH_OT_subdivide"); + */ } /* note mesh keymap also for other space? */ @@ -343,6 +349,8 @@ void ED_keymap_mesh(wmWindowManager *wm) ListBase *keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0); wmKeymapItem *kmi; + //WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0); + /* selecting */ /* standard mouse selection goes via space_view3d */ WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); @@ -354,7 +362,7 @@ void ED_keymap_mesh(wmWindowManager *wm) RNA_boolean_set(kmi->ptr, "extend", 1); WM_keymap_add_item(keymap, "MESH_OT_select_shortest_path", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); - + WM_keymap_add_item(keymap, "MESH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index d58488ce82d..54433fd4254 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -471,7 +471,6 @@ typedef struct BooleanModifierData { #define MOD_MDEF_INVERT_VGROUP (1<<0) #define MOD_MDEF_DYNAMIC_BIND (1<<1) -#define MOD_MDEF_USE_FINAL (1<<2) typedef struct MDefInfluence { int vertex; -- cgit v1.2.3 From 84e17862cd02b0ad018a0269bcfce623a9eae417 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 14 Sep 2009 06:31:20 +0000 Subject: * boundbox display option was missing from object properties --- release/ui/buttons_object.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/release/ui/buttons_object.py b/release/ui/buttons_object.py index af2c7cfb58a..9e043cfeaf3 100644 --- a/release/ui/buttons_object.py +++ b/release/ui/buttons_object.py @@ -92,10 +92,14 @@ class OBJECT_PT_display(ObjectButtonsPanel): layout = self.layout ob = context.object - - row = layout.row() - row.itemR(ob, "max_draw_type", text="Type") - row.itemR(ob, "draw_bounds_type", text="Bounds") + + split = layout.split() + col = split.column() + col.itemR(ob, "max_draw_type", text="Type") + col = split.column() + row = col.row() + row.itemR(ob, "draw_bounds", text="Bounds") + row.itemR(ob, "draw_bounds_type", text="") flow = layout.column_flow() flow.itemR(ob, "draw_name", text="Name") -- cgit v1.2.3 From 1b446d2902e8101d45fd6ec2c201a010930f8ad2 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 14 Sep 2009 06:59:37 +0000 Subject: to sphere transform hotkey is now alt-shift-s, since ctrl-shift-s was taken by save as. --- source/blender/editors/transform/transform_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 4ae0bca3284..8d7e8f20ad5 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -641,7 +641,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0); - km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0); km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0); -- cgit v1.2.3 From 48732cf01738e733db7457aa20e8b4a2cfa3feb0 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 14 Sep 2009 07:33:00 +0000 Subject: knife 'mode' is now leftclick with ctrl-x held down, instead of ctrl-alt --- source/blender/editors/mesh/mesh_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 5be39a3e4f1..606614cd1f1 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -431,7 +431,7 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_fgon_make", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_fgon_clear", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); - WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, XKEY); /* menus */ WM_keymap_add_item(keymap, "MESH_OT_vertex_specials", VKEY, KM_PRESS, KM_CTRL, 0); -- cgit v1.2.3 From cbb9815b0df6b7f8e57cedcc5d133ade66275074 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 14 Sep 2009 08:38:04 +0000 Subject: updated .b.blend; show toolbar by default now, made the view3d clip start saner, and turend on grab manipulator --- source/blender/editors/datafiles/B.blend.c | 5657 ++++++++++++++-------------- 1 file changed, 2923 insertions(+), 2734 deletions(-) diff --git a/source/blender/editors/datafiles/B.blend.c b/source/blender/editors/datafiles/B.blend.c index 980a9ee1697..b469f0c24cb 100644 --- a/source/blender/editors/datafiles/B.blend.c +++ b/source/blender/editors/datafiles/B.blend.c @@ -1,759 +1,858 @@ /* DataToC output of file */ -int datatoc_B_blend_size= 94308; +int datatoc_B_blend_size= 100360; char datatoc_B_blend[]= { - 66, 76, 69, 78, - 68, 69, 82, 45,118, 50, 53, 48, 82, 69, 78, 68, 32, 0, 0, 0, 80,187,118,198,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, 40, 0, 0, 0, 64,187,118,198,255,127, 0, 0,185, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 48, 0, 0, 0, 0, -250, 0, 0, 0, 1, 0, 0, 1,208,233, 90, 2, 0, 0, 0, 0, 96,130, 91, 2, 0, 0, 0, 0, 0, 16, 0, 0,128, 32, 4, 0, - 87, 77, 0, 0,224, 0, 0, 0,144,231, 90, 2, 0, 0, 0, 0, 75, 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, 1, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -176,232, 90, 2, 0, 0, 0, 0,176,232, 90, 2, 0, 0, 0, 0,176,232, 90, 2, 0, 0, 0, 0,176,232, 90, 2, 0, 0, 0, 0, - 3, 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, 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,144,131,100, 2, 0, 0, 0, 0,176,167,177, 2, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0, -176,232, 90, 2, 0, 0, 0, 0, 76, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -224,186, 91, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,208,233, 90, 2, 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, - 5, 0, 30, 0,118, 7, 97, 4, 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,131,100, 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,240, 14,119, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,224,180, 2, 0, 0, 0, 0,224,224,180, 2, 0, 0, 0, 0, - 64,132,100, 2, 0, 0, 0, 0,176,133,100, 2, 0, 0, 0, 0,112,134,100, 2, 0, 0, 0, 0,144,191,100, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0,208, 0, 0, 0,208,233, 90, 2, 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, 83, 82, 83, 99,114,101,101,110, 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,224,234, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, - 32,240, 90, 2, 0, 0, 0, 0,144,247, 90, 2, 0, 0, 0, 0, 0,248, 90, 2, 0, 0, 0, 0,160,111, 91, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,130, 91, 2, 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, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80,149,150, 0, 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, -224,234, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 64,235, 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, 68, 65, 84, 65, 32, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, -180, 0, 0, 0, 1, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 97, 4, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, - 0,236, 90, 2, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 97, 4, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, -160,235, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 96,236, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, -180, 0, 0, 0, 1, 0, 0, 0, 32,237, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 7, 70, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 32,237, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, -128,237, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0,128,237, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, - 32,237, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 80, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, -224,237, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,128,237, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, -180, 0, 0, 0, 1, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 6, 70, 4, 1, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, - 0,239, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 32, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0, -160,238, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6,100, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, - 96,239, 90, 2, 0, 0, 0, 0,180, 0, 0, 0, 1, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 80, 3, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, -180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -118, 7, 80, 3, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 32,240, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -144,240, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,144,240, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 0,241, 90, 2, 0, 0, 0, 0, 32,240, 90, 2, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 0,241, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -112,241, 90, 2, 0, 0, 0, 0,144,240, 90, 2, 0, 0, 0, 0,160,235, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,112,241, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -224,241, 90, 2, 0, 0, 0, 0, 0,241, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,224,241, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 80,242, 90, 2, 0, 0, 0, 0,112,241, 90, 2, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 80,242, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -192,242, 90, 2, 0, 0, 0, 0,224,241, 90, 2, 0, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,192,242, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 48,243, 90, 2, 0, 0, 0, 0, 80,242, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 48,243, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -160,243, 90, 2, 0, 0, 0, 0,192,242, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,160,243, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 16,244, 90, 2, 0, 0, 0, 0, 48,243, 90, 2, 0, 0, 0, 0,224,234, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 16,244, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -128,244, 90, 2, 0, 0, 0, 0,160,243, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,128,244, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -240,244, 90, 2, 0, 0, 0, 0, 16,244, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,240,244, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 96,245, 90, 2, 0, 0, 0, 0,128,244, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 96,245, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -208,245, 90, 2, 0, 0, 0, 0,240,244, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,208,245, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 64,246, 90, 2, 0, 0, 0, 0, 96,245, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 64,246, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -176,246, 90, 2, 0, 0, 0, 0,208,245, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,176,246, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 32,247, 90, 2, 0, 0, 0, 0, 64,246, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, 32,247, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, -144,247, 90, 2, 0, 0, 0, 0,176,246, 90, 2, 0, 0, 0, 0, 0,236, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0,144,247, 90, 2, 0, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32,247, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 0, 0, 0, 0,248, 90, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, -192,251, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 64,235, 90, 2, 0, 0, 0, 0, -160,235, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 7, 0, 0, - 71, 4, 0, 0, 97, 4, 0, 0, 7, 7,119, 7, 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0,112,153, 76, 2, 0, 0, 0, 0, -208,129, 91, 2, 0, 0, 0, 0,208,129, 91, 2, 0, 0, 0, 0,224,248, 90, 2, 0, 0, 0, 0, 80,250, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 78,100, 2, 0, 0, 0, 0, 64,153,118, 2, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0,224,248, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 80,250, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,106, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,238, 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,118, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, - 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,119, 7, - 26, 0,119, 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, 0, 0, 0, 0, - 0, 0, 0, 0,118, 7, 0, 0, 71, 4, 0, 0, 96, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -119, 7, 26, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,155, 76, 2, 0, 0, 0, 0, - 96,164,100, 2, 0, 0, 0, 0, 96,164,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -208,138,100, 2, 0, 0, 0, 0, 64,140,100, 2, 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, 80,250, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -224,248, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,240, 68, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 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, 0, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 6, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 97, 4, 0, 0, 97, 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, 1, 0, 0, 0, 0, 0, 0, 0, 96,154, 76, 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, - 68, 65, 84, 65,160, 0, 0, 0,192,251, 90, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0,176, 81, 91, 2, 0, 0, 0, 0, - 0,248, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, 96,239, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, - 0,236, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, 0, 0, 0, 0, 79, 3, 0, 0, - 4, 4,106, 1, 80, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,149, 76, 2, 0, 0, 0, 0,240, 72, 91, 2, 0, 0, 0, 0, - 80, 80, 91, 2, 0, 0, 0, 0,160,252, 90, 2, 0, 0, 0, 0, 16,254, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,160,158,118, 2, 0, 0, 0, 0, 96,169,118, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, -160,252, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 16,254, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,193, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,181, 67, 0, 0, 0, 0, 0, 0,248, 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,105, 1, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,106, 1, 31, 0,106, 1, 31, 0, 0, 0, - 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, 6, 0, 0,118, 7, 0, 0, - 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1, 31, 0, 3, 0, 1, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,152, 76, 2, 0, 0, 0, 0,112,176,178, 2, 0, 0, 0, 0, -112,176,178, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,143,100, 2, 0, 0, 0, 0, - 32,146,100, 2, 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, - 16,254, 90, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,252, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0,128,172, 67, 0,192, 71,196, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,172, 67, 0,192, 71,196, 0, 0, 0, 0, - 89, 1, 0, 0,106, 1, 0, 0, 18, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, - 0, 0, 0, 0, 88, 1, 0, 0, 18, 0, 0, 0, 48, 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, 4, 6, 0,106, 1, 49, 3, 89, 1, 31, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,160, 90,119, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, - 31, 0, 0, 0, 79, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1, 49, 3, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144,150, 76, 2, 0, 0, 0, 0,176,210,178, 2, 0, 0, 0, 0, - 96, 53,180, 2, 0, 0, 0, 0,128,255, 90, 2, 0, 0, 0, 0, 96, 55,180, 2, 0, 0, 0, 0, 80,148,100, 2, 0, 0, 0, 0, -240,151,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 1, 0, 0, -240, 72, 91, 2, 0, 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0, 80, 80, 91, 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, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0,128,236,177, 2, 0, 0, 0, 0, -255, 20, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0, 48, 74, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0,160, 75, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 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, 0, 0, 0, 0, 89, 6, 0, 0,108, 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, 20, 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, 68, 65, 84, 65, 40, 1, 0, 0,160, 75, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 74, 91, 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, + 66, 76, 69, 78, 68, 69, 82, 95, +118, 50, 53, 48, 82, 69, 78, 68, 32, 0, 0, 0,208,245, 18, 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, 32, 0, 0, 0, +200,245, 18, 0,192, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 51, 3, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 1, 72, 22, 11, 7, +160, 33, 10, 7, 0, 16, 0, 0,128, 32, 4, 0, 87, 77, 0, 0,140, 0, 0, 0,192, 75, 10, 7, 86, 1, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,254, 14, 7,160,147,103, 2,160,254, 14, 7, +160,254, 14, 7, 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, 2, 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,224,183,102, 2,216, 85, 5, 7, 68, 65, 84, 65,148, 0, 0, 0,160,254, 14, 7, 87, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 99, 2, 1, 0, 0, 0, 0, 0, 0, 0, 72, 22, 11, 7, 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, 62, 0, 34, 0, +186, 4,254, 2, 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 1, 0, 0, 0, 0, 0,232, 44, 99, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,144, 76, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,208,229, 25, 7,176,202, 25, 7,152, 43, 99, 2, +184,231, 9, 7,200, 45, 5, 7, 56, 90, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0,140, 0, 0, 0, 72, 22, 11, 7, +186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 83, 99,114,101,101,110, + 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,208, 79, 10, 7, +176,183, 3, 7,232,192, 3, 7, 96,201, 2, 7,120,255, 14, 7, 72,136, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,160, 33, 10, 7, + 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16,111, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,208, 79, 10, 7, +187, 0, 0, 0, 1, 0, 0, 0,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0,120, 63, 11, 7,187, 0, 0, 0, 1, 0, 0, 0, 8, 11, 11, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0,254, 2, + 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 8, 11, 11, 7,187, 0, 0, 0, 1, 0, 0, 0,200, 32, 4, 7,120, 63, 11, 7, + 0, 0, 0, 0,186, 4,254, 2, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,200, 32, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, +232,251, 3, 7, 8, 11, 11, 7, 0, 0, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,232,251, 3, 7, +187, 0, 0, 0, 1, 0, 0, 0, 48, 16, 4, 7,200, 32, 4, 7, 0, 0, 0, 0, 0, 0,227, 2, 1, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0, 48, 16, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,216, 43, 4, 7,232,251, 3, 7, 0, 0, 0, 0,186, 4,227, 2, + 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,216, 43, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,160, 34, 4, 7, 48, 16, 4, 7, + 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,160, 34, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, + 88,147, 4, 7,216, 43, 4, 7, 0, 0, 0, 0,186, 4, 60, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 88,147, 4, 7, +187, 0, 0, 0, 1, 0, 0, 0,136,121, 4, 7,160, 34, 4, 7, 0, 0, 0, 0,216, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0,136,121, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,104, 25, 4, 7, 88,147, 4, 7, 0, 0, 0, 0,216, 3,227, 2, + 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,104, 25, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, 64,160, 4, 7,136,121, 4, 7, + 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 64,160, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, + 32, 26, 15, 7,104, 25, 4, 7, 0, 0, 0, 0,216, 3, 72, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 32, 26, 15, 7, +187, 0, 0, 0, 1, 0, 0, 0,176,183, 3, 7, 64,160, 4, 7, 0, 0, 0, 0,216, 3, 72, 2, 0, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0,176,183, 3, 7,187, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 26, 15, 7, 0, 0, 0, 0,186, 4, 72, 2, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,232,192, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 24,226, 3, 7, 0, 0, 0, 0, + 8, 11, 11, 7,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 24,226, 3, 7,188, 0, 0, 0, + 1, 0, 0, 0, 88, 14, 4, 7,232,192, 3, 7,232,251, 3, 7,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 88, 14, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, 0,180, 3, 7, 24,226, 3, 7, 48, 16, 4, 7, 8, 11, 11, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,180, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,104,163, 3, 7, + 88, 14, 4, 7,232,251, 3, 7, 48, 16, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,104,163, 3, 7, +188, 0, 0, 0, 1, 0, 0, 0,248,203, 3, 7, 0,180, 3, 7, 88,147, 4, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0,248,203, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 16,191, 3, 7,104,163, 3, 7,200, 32, 4, 7, + 88,147, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 16,191, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, +144, 23, 4, 7,248,203, 3, 7,232,251, 3, 7,136,121, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, +144, 23, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, 0,118, 4, 7, 16,191, 3, 7, 48, 16, 4, 7,136,121, 4, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,118, 4, 7,188, 0, 0, 0, 1, 0, 0, 0,144,109, 4, 7,144, 23, 4, 7, +104, 25, 4, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,144,109, 4, 7,188, 0, 0, 0, + 1, 0, 0, 0, 40,178, 3, 7, 0,118, 4, 7,232,251, 3, 7,104, 25, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 40,178, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,200,170, 3, 7,144,109, 4, 7,136,121, 4, 7, 64,160, 4, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,200,170, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,176,242, 3, 7, + 40,178, 3, 7, 88,147, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,176,242, 3, 7, +188, 0, 0, 0, 1, 0, 0, 0, 56,248, 3, 7,200,170, 3, 7,104, 25, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0, 56,248, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 80, 38, 4, 7,176,242, 3, 7, 88,147, 4, 7, + 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 80, 38, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, +232,133, 3, 7, 56,248, 3, 7,136,121, 4, 7, 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, +232,133, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,160,210, 2, 7, 80, 38, 4, 7,176,183, 3, 7, 48, 16, 4, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,160,210, 2, 7,188, 0, 0, 0, 1, 0, 0, 0, 96,201, 2, 7,232,133, 3, 7, +176,183, 3, 7,200, 32, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 96,201, 2, 7,188, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0,160,210, 2, 7,176,183, 3, 7, 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 96, 0, 0, 0,120,255, 14, 7,190, 0, 0, 0, 1, 0, 0, 0, 24, 23, 11, 7, 0, 0, 0, 0,232,251, 3, 7,120, 63, 11, 7, + 8, 11, 11, 7, 48, 16, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0,186, 4, 0, 0,228, 2, 0, 0,254, 2, 0, 0, 7, 7,187, 4, + 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 56,150, 92, 2,152,180,102, 2,152,180,102, 2, 32,173, 11, 7,112,158, 24, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 40, 47, 5, 7, 8, 48, 5, 7, 68, 65, 84, 65,248, 0, 0, 0, 32,173, 11, 7,191, 0, 0, 0, + 1, 0, 0, 0,112,158, 24, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,157, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 96,151, 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,186, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, + 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, + 10, 0,187, 4, 26, 0,187, 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,186, 4, 0, 0,228, 2, 0, 0,253, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +187, 4, 26, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,151, 92, 2,184,191, 25, 7, +184,191, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,216, 49, 5, 7, 96, 50, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +248, 0, 0, 0,112,158, 24, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32,173, 11, 7, 0, 0, 0, 0, 0, 32,240, 68, + 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 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, 0, 63, 0, 0, 0, 64, + 10, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 6, 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, 0, 0, 0, 0,254, 2, 0, 0,254, 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, 1, 0, 0, 0, + 0, 0, 0, 0,224,150, 92, 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, 68, 65, 84, 65, 96, 0, 0, 0, 24, 23, 11, 7,190, 0, 0, 0, 1, 0, 0, 0,200, 33, 11, 7, +120,255, 14, 7, 88,147, 4, 7, 32, 26, 15, 7,176,183, 3, 7,200, 32, 4, 7, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, + 0, 0, 0, 0, 71, 2, 0, 0, 4, 4,226, 0, 72, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,147, 92, 2,192,160, 9, 7, +120,148, 10, 7,128,237, 11, 7,184,238, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0,232, 50, 5, 7,200, 51, 5, 7, 68, 65, 84, 65, +248, 0, 0, 0,128,237, 11, 7,191, 0, 0, 0, 1, 0, 0, 0,184,238, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 67, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 98, 67, 0, 0, 0, 0, 0, 0,248, 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,225, 0, 0, 0, + 0, 0, 0, 0, 30, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,226, 0, 31, 0,226, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0, 31, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,152,149, 92, 2,160,145,246, 6,160,145,246, 6, 0, 0, 0, 0, 0, 0, 0, 0,152, 53, 5, 7,168, 54, 5, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,184,238, 11, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +128,237, 11, 7, 0, 0, 0, 0, 0, 0, 80, 67, 0, 0, 68,196, 0, 0, 0, 0, 0, 0, 0, 0,254,255, 80, 67,255,191, 5,196, + 0, 0, 0, 0,209, 0, 0, 0,226, 0, 0, 0, 18, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 18, 0, 0, 0, 40, 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, 4, 6, 0,226, 0, 41, 2,209, 0, + 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176, 63,100, 2, 1, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, + 31, 0, 0, 0, 71, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0, 41, 2, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,148, 92, 2, 88, 22, 6, 7, 16,102, 5, 7,248, 24, 11, 7, + 72,159, 9, 7,144, 56, 5, 7, 40, 58, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,248, 24, 11, 7, +189, 0, 0, 0, 1, 0, 0, 0,112, 26, 11, 7, 0, 0, 0, 0,200,148, 92, 2, 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,208, 0, 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, + 68, 65, 84, 65, 56, 1, 0, 0,112, 26, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,232, 27, 11, 7,248, 24, 11, 7,232,164, 2, 7, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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,208, 0, 61, 0, 0, 0, 0, 0, 0, 0, 2, 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, 68, 65, 84, 65, 56, 1, 0, 0,232, 27, 11, 7,189, 0, 0, 0, 1, 0, 0, 0, + 96, 29, 11, 7,112, 26, 11, 7,192,166, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 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, 68, 65, 84, 65, 56, 1, 0, 0, + 96, 29, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,216, 30, 11, 7,232, 27, 11, 7,152,168, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, + 69, 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, 0, 83, 67, 69, 78, + 69, 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, 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,165,254, +208, 0,178, 0, 0, 0, 0, 0, 0, 0, 2, 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, 89, 6, 0, 0,108, 7, 0, 0, 26, 0, 0, 0, 80, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,216, 30, 11, 7,189, 0, 0, 0, 1, 0, 0, 0, 80, 32, 11, 7, 96, 29, 11, 7, +112,170, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 0, 16, 77, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, 16, 77, 91, 2, 0, 0, 0, 0, -146, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128, -226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, -184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, - 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, -184,175, 31, 65, 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, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 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, 83,254,208, 0, 58, 0, 20, 0, 0, 0, 0, 0, 2, 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, 68, 65, 84, 65, 56, 1, 0, 0, 80, 32, 11, 7,189, 0, 0, 0, + 1, 0, 0, 0,104,153, 9, 7,216, 30, 11, 7, 72,172, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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,213,253,208, 0,102, 0, 0, 0, 0, 0, + 0, 0, 2, 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, 68, 65, 84, 65, + 56, 1, 0, 0,104,153, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,224,154, 9, 7, 80, 32, 11, 7, 32,174, 2, 7, 0, 0, 0, 0, + 83, 67, 69, 78, 69, 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, 0, - 68, 65, 84, 65, 32, 1, 0, 0, 80, 80, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -240, 72, 91, 2, 0, 0, 0, 0, 48, 74, 91, 2, 0, 0, 0, 0,160, 75, 91, 2, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0, -159, 0, 0, 0, 0, 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, 68, 65, 84, 65,160, 0, 0, 0, -176, 81, 91, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 94, 91, 2, 0, 0, 0, 0,192,251, 90, 2, 0, 0, 0, 0, -224,234, 90, 2, 0, 0, 0, 0,160,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0,224,237, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 15, 15, 12, 6,100, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0,240,118, 76, 2, 0, 0, 0, 0,112, 85, 91, 2, 0, 0, 0, 0,160, 92, 91, 2, 0, 0, 0, 0, -144, 82, 91, 2, 0, 0, 0, 0, 0, 84, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192,174,118, 2, 0, 0, 0, 0,176,185,118, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,144, 82, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 84, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,104, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,193, 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, 11, 6, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,224,202, 68, 0, 0,200, 65, 0,224,202, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 12, 6, 26, 0, 12, 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, 0, 0, 0, 0, 0, 0, 0, 0, 11, 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, 12, 6, 26, 0, 5, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,208,120, 76, 2, 0, 0, 0, 0,208,218,179, 2, 0, 0, 0, 0,208,218,179, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,155,100, 2, 0, 0, 0, 0, 96,156,100, 2, 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, 0, 84, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 82, 91, 2, 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, 11, 6, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0, - 18, 0, 0, 0, 73, 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, 12, 6, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 6, 0, 0, 26, 0, 0, 0, 99, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 74, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,224,119, 76, 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,144,158,100, 2, 0, 0, 0, 0,160,163,100, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,200, 0, 0, 0,112, 85, 91, 2, 0, 0, 0, 0, -162, 0, 0, 0, 1, 0, 0, 0,160, 92, 91, 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, 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, 1, 0, 0, 0, 6, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,128, 86, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0,240, 87, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,203, 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, 87, 6, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 88, 6, 26, 0, 88, 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, 0, 0, 0, 0, 0, 0, 0, 0, 87, 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, 88, 6, 26, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 83, 67, 69, 78, 69, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,240, 87, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 86, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 84,253,208, 0,105, 0, 0, 0, 0, 0, 0, 0, 2, 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, 68, 65, 84, 65, 56, 1, 0, 0,224,154, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 88,156, 9, 7, +104,153, 9, 7,208,177, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 6, 0, 0, 26, 0, 0, 0, 55, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 6, 30, 0, 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, 60,253,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 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, 96, 89, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, 96, 89, 91, 2, 0, 0, 0, 0, -146, 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, 87,213,108, 66, - 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,128, 0, 0, 0,128, -226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, - 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, -184,175, 31, 65, 0, 0, 32, 65,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 91,138, 60, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, - 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, - 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, -184,175, 31, 65, 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, 68, 65, 84, 65, 56, 1, 0, 0, 88,156, 9, 7, +189, 0, 0, 0, 1, 0, 0, 0,208,157, 9, 7,224,154, 9, 7,168,179, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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, 36,253,208, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 2, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 52,149,147, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 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, + 68, 65, 84, 65, 56, 1, 0, 0,208,157, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 72,159, 9, 7, 88,156, 9, 7,128,181, 2, 7, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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, 12,253,208, 0, 0, 0, 20, 0, 0, 0, 4, 0, 2, 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, - 68, 65, 84, 65, 32, 1, 0, 0,160, 92, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -112, 85, 91, 2, 0, 0, 0, 0,128, 86, 91, 2, 0, 0, 0, 0,240, 87, 91, 2, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0, -159, 0, 0, 0, 0, 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, 68, 65, 84, 65,160, 0, 0, 0, - 0, 94, 91, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0,160,111, 91, 2, 0, 0, 0, 0,176, 81, 91, 2, 0, 0, 0, 0, -160,238, 90, 2, 0, 0, 0, 0, 96,236, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0, 0,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,101, 0, 0, 0, 69, 4, 0, 0, 1, 1, 12, 6,225, 3, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0,192,121, 76, 2, 0, 0, 0, 0, 64,110, 91, 2, 0, 0, 0, 0, 64,110, 91, 2, 0, 0, 0, 0, -224, 94, 91, 2, 0, 0, 0, 0,144,105, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48,188,118, 2, 0, 0, 0, 0,224,204,118, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,224, 94, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 80, 96, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,128,193, 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, 11, 6, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 12, 6, 26, 0, 12, 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, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 0, 0,101, 0, 0, 0,126, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 26, 0, 7, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,112,130, 76, 2, 0, 0, 0, 0,128, 47,182, 2, 0, 0, 0, 0,128, 47,182, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,167,100, 2, 0, 0, 0, 0,192,170,100, 2, 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, 80, 96, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0,144,105, 91, 2, 0, 0, 0, 0,224, 94, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, - 0, 64, 55,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 67, 0, 0, 41,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,219, 0, 0, 0, - 0, 0, 0, 0,163, 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, - 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 0, 6, 0,220, 0,164, 2,220, 0,164, 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, 11, 6, 0, 0, 11, 6, 0, 0,127, 0, 0, 0, 69, 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, - 1, 0, 0, 0, 0, 0, 0, 0,160,123, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 97, 91, 2, 0, 0, 0, 0, 0,104, 91, 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, 68, 65, 84, 65, 40, 1, 0, 0,144,105, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 96, 91, 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, 11, 6, 0, 0,127, 0, 0, 0, 69, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6,199, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,176,122, 76, 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,240,172,100, 2, 0, 0, 0, 0, 96,186,100, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, 0,107, 91, 2, 0, 0, 0, 0, -146, 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,167, 29,224, 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,238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62, -244,217, 46,191, 0, 0, 0, 0,228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, 60,138,193, 0, 0,128, 63,236, 4, 53, 63,244, 4, 53, 63, 0, 0, 24, 53, 0, 0, 0, 0,137,103, 59,190,118,103, 59, 62, -227, 70,119, 63, 0, 0, 0, 0,238,217, 46, 63,221,217, 46,191,213,131,132, 62, 0, 0, 0, 0,186,213, 60, 65,168,213, 60,193, -221, 28,143, 64, 0, 0,128, 63,102,253, 69, 63,120, 16,164,190,194,219, 46,191,247,217, 46,191,120,253, 69, 63, 67, 16,164, 62, -191,219, 46, 63,244,217, 46, 63, 67,228, 68, 50,189,122,216, 63, 53,133,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, - 13, 21,138, 65,152, 60,138, 65, 15,132, 37, 63,166,125, 37, 63, 0, 96,160, 55, 0,128,139, 54, 97, 17,214,189, 77, 17,214, 61, - 92, 58, 13, 63, 0, 0,184,179,168,135, 19,196,155,135, 19, 68, 34,158, 95,195,235, 0, 72,194,116, 93, 19, 68,103, 93, 19,196, - 42, 94, 95, 67,248, 2, 72, 66,238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62, -244,217, 46,191, 0, 0, 0, 0,228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -152, 60,138,193, 0, 0,128, 63,102,253, 69, 63,120, 16,164,190,194,219, 46,191,247,217, 46,191,120,253, 69, 63, 67, 16,164, 62, -191,219, 46, 63,244,217, 46, 63, 67,228, 68, 50,189,122,216, 63, 53,133,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, - 13, 21,138, 65,152, 60,138, 65, 55,243,195, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55,243,195, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55,243,195, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,128, 63,122,163, 59, 63,235,250, 15,191,221,141,110,190,230,113,155,190,152, 60,138, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 21,212,154, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 72,159, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,208,157, 9, 7, 88,183, 2, 7, 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,244,252,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 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, - 68, 65, 84, 65, 32, 1, 0, 0, 64,110, 91, 2, 0, 0, 0, 0,147, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 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, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0, -159, 0, 0, 0, 0, 0, 0, 0, 3, 0,255,255, 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, 68, 65, 84, 65,160, 0, 0, 0, -160,111, 91, 2, 0, 0, 0, 0,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 91, 2, 0, 0, 0, 0, - 96,239, 90, 2, 0, 0, 0, 0, 64,238, 90, 2, 0, 0, 0, 0,192,236, 90, 2, 0, 0, 0, 0,192,239, 90, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, 81, 3, 0, 0, 69, 4, 0, 0, 3, 3,106, 1,245, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32,116, 76, 2, 0, 0, 0, 0, 96,115, 91, 2, 0, 0, 0, 0,112,128, 91, 2, 0, 0, 0, 0, -128,112, 91, 2, 0, 0, 0, 0,240,113, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96,207,118, 2, 0, 0, 0, 0,144, 82,119, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 1, 0, 0,128,112, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0,240,113, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,181, 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,105, 1, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 66, 67, 0, 0,200, 65, 0, 0, 66, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,106, 1, 26, 0,106, 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, 0, 0, 0, 0, 13, 6, 0, 0,118, 7, 0, 0, 81, 3, 0, 0,106, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1, 26, 0, 9, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 76, 2, 0, 0, 0, 0,128, 5,182, 2, 0, 0, 0, 0,128, 5,182, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,190,100, 2, 0, 0, 0, 0,208,190,100, 2, 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,240,113, 91, 2, 0, 0, 0, 0, -184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,112, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,131, 67, - 0, 0,194,194, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,172, 67, 0, 0, 73,195, 0, 0, 0, 0, 89, 1, 0, 0,106, 1, 0, 0, - 18, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 88, 1, 0, 0, - 18, 0, 0, 0,218, 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, 0, 4, 6, 0,106, 1,219, 0, 89, 1,201, 0, 0, 0, 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, 6, 0, 0,118, 7, 0, 0,107, 3, 0, 0, 69, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 1,219, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16,117, 76, 2, 0, 0, 0, 0,192, 43,182, 2, 0, 0, 0, 0,192, 43,182, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193,100, 2, 0, 0, 0, 0, 48,195,100, 2, 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, 96,115, 91, 2, 0, 0, 0, 0, -156, 0, 0, 0, 1, 0, 0, 0, 16,121, 91, 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, 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,224, 8,182, 2, 0, 0, 0, 0, -224, 8,182, 2, 0, 0, 0, 0,208,116, 91, 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, 1, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,208,116, 91, 2, 0, 0, 0, 0, -207, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 32,117, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,208, 0, 0, 0, - 32,117, 91, 2, 0, 0, 0, 0,206, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0, - 19, 0, 0, 0, 1, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0, 20, 0, 0, 0, 1, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0, - 21, 0, 1, 0, 1, 0, 1, 0, 96,130, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 48,145, 91, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0,176,157, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,128,173, 91, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0,128,167, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,224,171, 91, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 16,163, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,176,140, 91, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,208,139, 91, 2, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 1, 0, 0, 48,118, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0,160,119, 91, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 55, 0, 0, 67, 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,194, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, - 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,195, 0, - 26, 0,195, 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, - 53, 4, 0, 0,247, 4, 0, 0, 69, 2, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 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, 68, 65, 84, 65,224, 0, 0, 0, +192,160, 9, 7,158, 0, 0, 0, 1, 0, 0, 0,120,148, 10, 7, 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, - 68, 65, 84, 65, 40, 1, 0, 0,160,119, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48,118, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,150, 67, 0,192,116,196, 0, 0, 0, 0, 0, 0, 0, 0,205, 85,150, 67, -223,204, 35,196, 26, 85,207,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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0,155, 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, 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 4, 6, 0,195, 0, -156, 0,195, 0,156, 0, 0, 0, 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, 4, 0, 0,247, 4, 0, 0, 95, 2, 0, 0,250, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 0, 1, 0, 0, 16,121, 91, 2, 0, 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0,112,128, 91, 2, 0, 0, 0, 0, - 96,115, 91, 2, 0, 0, 0, 0, 48,118, 91, 2, 0, 0, 0, 0,160,119, 91, 2, 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, 2, 0, 1, 0, 0, 0, 0, 0, 80,175, 11, 7, +255, 20, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,224,161, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, + 40,144, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, + 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, + 26, 0, 20, 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, 89, 6, 0, 0, +108, 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, 20, 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, 68, 65, 84, 65,248, 0, 0, 0, + 40,144, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,224,161, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 68, 65, 84, 65, 40, 1, 0, 0, - 80,122, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0,192,123, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 67, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 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, 19, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 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, 0, 0, 0, 0, 89, 6, 0, 0,108, 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, 20, 1, 26, 0, 0, 0, 1, 0, + 96,145, 10, 7, 68, 65, 84, 65,216, 2, 0, 0, 96,145, 10, 7,152, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, + 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, + 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, + 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,148, 10, 7,153, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0,192,160, 9, 7,224,161, 9, 7, 40,144, 10, 7, 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, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 0, 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, 68, 65, 84, 65, 96, 0, 0, 0,200, 33, 11, 7, +190, 0, 0, 0, 1, 0, 0, 0, 48,124, 9, 7, 24, 23, 11, 7,208, 79, 10, 7,104, 25, 4, 7, 64,160, 4, 7, 88,147, 4, 7, + 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 15, 15,216, 3, 72, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,123, 92, 2, 24,152, 10, 7, 0,123, 9, 7,168,149, 10, 7,224,150, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, +176, 58, 5, 7,144, 59, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,168,149, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,224,150, 10, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,128, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 56, 0, 0,118, 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,215, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,224,202, 68, 0, 0,200, 65, 0,224,202, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,216, 3, 26, 0,216, 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, 0, 0, 0, 0,215, 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,216, 3, 26, 0, 5, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,124, 92, 2,248, 23, 6, 7,248, 23, 6, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 96, 61, 5, 7,112, 62, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,224,150, 10, 7, +191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168,149, 10, 7, 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,215, 3, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 18, 0, 0, 0, 45, 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,216, 3, 46, 0, 0, 0, 0, 0, 0, 0, 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, 3, 0, 0, 26, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,216, 3, 46, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,123, 92, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 64, 5, 7,120, 66, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,180, 0, 0, 0, 24,152, 10, 7,168, 0, 0, 0, 1, 0, 0, 0, 0,123, 9, 7, 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, + 1, 0, 0, 0, 6, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 16,153, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,176,118, 9, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,203, 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, 87, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 88, 6, 26, 0, 88, 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, 0, 0, 0, 0, 87, 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, 88, 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, 68, 65, 84, 65, 40, 1, 0, 0, -192,123, 91, 2, 0, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,122, 91, 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, 89, 6, 0, 0,108, 7, 0, 0, - 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 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,248, 0, 0, 0,176,118, 9, 7, +191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16,153, 10, 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, 48,125, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,248, 2, 0, 0, - 48,125, 91, 2, 0, 0, 0, 0,146, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, - 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, - 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, - 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, - 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 87, 6, 0, 0, 26, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 88, 6, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 9, 7, + 68, 65, 84, 65,216, 2, 0, 0,232,119, 9, 7,152, 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, 87,213,108, 66, 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,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 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,184,175, 31, 65, 0, 0, 32, 65,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,224, 91,138, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195, +115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 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,184,175, 31, 65, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52,149,147, 58, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 32, 1, 0, 0,112,128, 91, 2, 0, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16,121, 91, 2, 0, 0, 0, 0, 80,122, 91, 2, 0, 0, 0, 0,192,123, 91, 2, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 64,153, 91, 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, 68, 65, 84, 65,240, 0, 0, 0, 0,123, 9, 7,153, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 24,152, 10, 7, 16,153, 10, 7,176,118, 9, 7, 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, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 0, 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, 68, 65, 84, 65, 96, 0, 0, 0, 48,124, 9, 7,190, 0, 0, 0, + 1, 0, 0, 0, 72,136, 9, 7,200, 33, 11, 7,104, 25, 4, 7,232,251, 3, 7,136,121, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, + 0, 0, 0, 0,215, 3, 0, 0, 73, 0, 0, 0,226, 2, 0, 0, 1, 1,216, 3,154, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +232,124, 92, 2, 24,135, 9, 7, 24,135, 9, 7,208,124, 9, 7,160,229, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 5, 7, + 48, 69, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,208,124, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 8,126, 9, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 90, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,118, 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,215, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,216, 3, 26, 0,216, 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, 0, 0, 0, 0,215, 3, 0, 0, 73, 0, 0, 0, + 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3, 26, 0, 7, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,132, 92, 2, 32, 77,104, 2, 32, 77,104, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71, 5, 7,152, 72, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 8,126, 9, 7,191, 0, 0, 0, + 1, 0, 0, 0, 48,130, 9, 7,208,124, 9, 7, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0,251,195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 67, 0, 0,251,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 7, 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, 18, 0, 0, 0, 7, 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, 4, + 6, 0,160, 0, 8, 2,143, 0,246, 1, 0, 0, 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,219, 0, 0, 0,226, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +160, 0, 8, 2, 8, 0, 5, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,129, 92, 2, 72,117,101, 2, +136, 52,102, 2, 64,127, 9, 7,184,128, 9, 7,128, 74, 5, 7, 24, 76, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 56, 1, 0, 0, 64,127, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,184,128, 9, 7, 0, 0, 0, 0,224,129, 92, 2, 0, 0, 0, 0, + 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115,104,101,108,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, + 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115,104,101,108,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, + 84,111,111,108, 32, 83,104,101,108,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,196,255,143, 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, 68, 65, 84, 65, 56, 1, 0, 0,184,128, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 64,127, 9, 7, 80,129, 4, 7, 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, 27,254,143, 0,145, 1, 0, 0, 0, 0, 0, 0, 7, 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, - 83, 67, 0, 0,192, 5, 0, 0, 96,130, 91, 2, 0, 0, 0, 0,144, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 64,153, 91, 2, 0, 0, 0, 0, 48,145, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96,136, 91, 2, 0, 0, 0, 0, 64,137, 91, 2, 0, 0, 0, 0, 96,136, 91, 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, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,137, 91, 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, 68, 65, 84, 65,248, 0, 0, 0, 48,130, 9, 7, +191, 0, 0, 0, 1, 0, 0, 0,152,219, 10, 7, 8,126, 9, 7, 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, + 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 99, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,160, 0,120, 0, 9, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,130, 92, 2, +120, 73, 25, 7,120, 73, 25, 7, 32,218, 10, 7, 32,218, 10, 7, 0, 78, 5, 7,152, 79, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 56, 1, 0, 0, 32,218, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,131, 92, 2, + 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, 0, 0, 0, 0, 68,172, 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,100, 0, 0, 0,100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 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, 0, 0, 0, 0, - 1, 0, 0, 0, 6, 0, 25, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 0, 0, 24, 0, 17, 0, 0, 0, 0, 0, 90, 0, 0, 0, - 0, 0, 0, 0, 81, 0, 0, 0, 23, 0, 33, 0, 0, 0,128, 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, 0, 0, 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,139, 91, 2, 0, 0, 0, 0, 48,139, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, - 0, 0,200, 66, 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, 0, 0, 0, 0, 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,105,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, 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, 47, 47, 98, 97, 99,107, 98,117, -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, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,152,219, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, +160,229, 10, 7, 48,130, 9, 7, 0, 0, 0, 0, 0, 0, 75, 67, 0,128,118,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 67, + 0,128, 27,196, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 18, 0, 0, 0,127, 2, 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, 18, 0, 0, 0,127, 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,220, 0, +128, 2,203, 0,110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, +215, 3, 0, 0, 99, 0, 0, 0,226, 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, 1, 0, 0, 0, 0, 0, 0, 0, 48,126, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, +208,220, 10, 7, 40,228, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, +208,220, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 72,222, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, + 51, 68, 95, 80, 84, 95,111, 98,106,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, + 51, 68, 95, 80, 84, 95,111, 98,106,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 84,114, 97,110, +115,102,111,114,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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,255, +203, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 72,222, 10, 7,189, 0, 0, 0, 1, 0, 0, 0,192,223, 10, 7,208,220, 10, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 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, 86, 73, 69, 87, 51, 68, 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, 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,200,254,203, 0, 58, 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, 68, 65, 84, 65, 56, 1, 0, 0,192,223, 10, 7,189, 0, 0, 0, + 1, 0, 0, 0, 56,225, 10, 7, 72,222, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100, +118,105,101,119, 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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100, +118,105,101,119, 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, 86,105,101,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,253,203, 0, 47, 1, 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, 68, 65, 84, 65, + 56, 1, 0, 0, 56,225, 10, 7,189, 0, 0, 0, 1, 0, 0, 0,176,226, 10, 7,192,223, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,100,105,115,112,108, 97,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, + 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,100,105,115,112,108, 97,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, + 68,105,115,112,108, 97,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, 66,252,203, 0, 39, 1, 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, 68, 65, 84, 65, 56, 1, 0, 0,176,226, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 40,228, 10, 7, + 56,225, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115, +104,100,105,115,112,108, 97,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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115, +104,100,105,115,112,108, 97,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, 77,101,115,104, 32, 68,105,115,112,108, 97,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,254,250,203, 0,104, 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, 68, 65, 84, 65, 56, 1, 0, 0, 40,228, 10, 7, +189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,176,226, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, + 84, 95, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97,103,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, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97,103,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, 66, 97, 99,107,103,114,111,117, +110,100, 32, 73,109, 97,103,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, 42,252,203, 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, + 68, 65, 84, 65,248, 0, 0, 0,160,229, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,152,219, 10, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 0, 0, 99, 0, 0, 0,226, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3,128, 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,144,125, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 81, 5, 7, + 40, 84, 5, 7, 0, 0, 0, 0, 0,132, 9, 7, 68, 65, 84, 65,216, 2, 0, 0, 0,132, 9, 7,152, 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, 1, 64,215, 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, +238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0, +228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63, +236, 4, 53, 63,244, 4, 53, 63, 0, 0, 24, 53, 0, 0, 0, 0,137,103, 59,190,118,103, 59, 62,227, 70,119, 63, 0, 0, 0, 0, +238,217, 46, 63,221,217, 46,191,213,131,132, 62, 0, 0, 0, 0,186,213, 60, 65,168,213, 60,193,221, 28,143, 64, 0, 0,128, 63, +100,253, 69, 63,248,146,157,190,223,235, 46,191,247,217, 46,191,119,253, 69, 63,197,146,157, 62,220,235, 46, 63,244,217, 46, 63, + 65,228, 68, 50,109,234,207, 63,107,145,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65, +252,128, 37, 63,186,128, 37, 63, 0, 0,180, 53, 0, 0, 60, 52,154,225,222,189,131,225,222, 61,139, 11, 19, 63, 0, 0,144, 51, + 25,255,107,194, 1,255,107, 66,239,218,178,193,208,247,159,192,220, 91,105, 66,197, 91,105,194, 49,219,176, 65, 50, 8,160, 64, +238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0, +228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63, +100,253, 69, 63,248,146,157,190,223,235, 46,191,247,217, 46,191,119,253, 69, 63,197,146,157, 62,220,235, 46, 63,244,217, 46, 63, + 65,228, 68, 50,109,234,207, 63,107,145,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65, +166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, +122,163, 59, 63,235,250, 15,191,221,141,110,190,230,113,155,190,152, 60,138, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83,146,243, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, + 24,135, 9, 7,153, 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, + 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 12, 66, + 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,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, 16, 0, 0, 0, 7, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0,255,255, + 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, 68, 65, 84, 65, + 96, 0, 0, 0, 72,136, 9, 7,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48,124, 9, 7, 32, 26, 15, 7,136,121, 4, 7, + 48, 16, 4, 7,176,183, 3, 7, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 73, 2, 0, 0,226, 2, 0, 0, 3, 3,226, 0, +154, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,121, 92, 2, 88,139, 9, 7, 24,238, 10, 7,232,136, 9, 7, 32,138, 9, 7, + 0, 0, 0, 0, 0, 0, 0, 0,120, 86, 5, 7, 88, 87, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,232,136, 9, 7,191, 0, 0, 0, + 1, 0, 0, 0, 32,138, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, + 0, 0, 98, 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,225, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 66, 67, + 0, 0,200, 65, 0, 0, 66, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, + 10, 0,226, 0, 26, 0,226, 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, +217, 3, 0, 0,186, 4, 0, 0, 73, 2, 0, 0, 98, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +226, 0, 26, 0, 11, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,122, 92, 2, 96,150, 25, 7, + 96,150, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0, 40, 89, 5, 7,176, 89, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +248, 0, 0, 0, 32,138, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,232,136, 9, 7, 0, 0, 0, 0, 0,128,131, 67, + 0, 0,228,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 67, 0, 0,220,194, 0, 0, 0, 0,209, 0, 0, 0,226, 0, 0, 0, + 18, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, + 18, 0, 0, 0,127, 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, 0, 4, 6, 0,226, 0,128, 0,209, 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,217, 3, 0, 0,186, 4, 0, 0, 99, 2, 0, 0,226, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0,128, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,192,121, 92, 2,200,170, 25, 7,200,170, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,152, 91, 5, 7,168, 92, 5, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 1, 0, 0, 88,139, 9, 7,162, 0, 0, 0, 1, 0, 0, 0,112,231, 10, 7, + 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,176,125, 25, 7,176,125, 25, 7, +216,143, 12, 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, 1, 0, 0, 0, + 68, 65, 84, 65, 12, 0, 0, 0,216,143, 12, 7,214, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0,160,140, 9, 7, + 68, 65, 84, 65,156, 0, 0, 0,160,140, 9, 7,213, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,160, 33, 10, 7, + 19, 0, 0, 0, 1, 0, 1, 0,160, 33, 10, 7, 20, 0, 0, 0, 1, 0, 1, 0,160, 33, 10, 7, 21, 0, 1, 0, 1, 0, 1, 0, +160, 33, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0, 64, 39, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0,224,195, 9, 7, 0, 0, 0, 0, + 1, 0, 1, 0, 48, 21, 12, 7, 0, 0, 0, 0, 1, 0, 1, 0, 48,203, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,224, 45, 10, 7, + 0, 0, 0, 0, 1, 0, 1, 0,136,199, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,208,240, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0, + 56,192, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,240,143, 9, 7, 68, 65, 84, 65,248, 0, 0, 0,128,141, 9, 7,191, 0, 0, 0, + 1, 0, 0, 0,184,142, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 55, + 0, 0, 67, 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,194, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,137, 67, + 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, + 10, 0,195, 0, 26, 0,195, 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, + 53, 4, 0, 0,247, 4, 0, 0, 69, 2, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +195, 0, 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, 68, 65, 84, 65, +248, 0, 0, 0,184,142, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128,141, 9, 7, 0, 0, 0, 0, 0, 0,150, 67, + 0,192,116,196, 0, 0, 0, 0, 0, 0, 0, 0,205, 85,150, 67,223,204, 35,196, 26, 85,207,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, + 0, 0, 0, 0,155, 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, + 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 4, 6, 0,195, 0,156, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 4, 0, 0,247, 4, 0, 0, 95, 2, 0, 0,250, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,224, 0, 0, 0,112,231, 10, 7,158, 0, 0, 0, 1, 0, 0, 0, 24,238, 10, 7, + 88,139, 9, 7,128,141, 9, 7,184,142, 9, 7, 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, 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, 31, 1, 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, 68, 65, 84, 65, +248, 0, 0, 0,144,232, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,200,233, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 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, 89, 6, 0, 0,108, 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, 20, 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, 68, 65, 84, 65,248, 0, 0, 0,200,233, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +144,232, 10, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, + 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 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, -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, - 6, 0, 0, 0, 16, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,235, 10, 7, 68, 65, 84, 65,216, 2, 0, 0, 0,235, 10, 7, +152, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128, +226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, +184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, + 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, +184,175, 31, 65, 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, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,176,191, 66, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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, 28, 65, 0, 0, 0, 0, 32, 0, 0, 0,128, 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,128, 2,224, 1, 60, 0, 32, 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,128, 7, 56, 4, 68, 65, 84, 65, 40, 0, 0, 0, - 96,136, 91, 2, 0, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0,208,136, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 6, 3,227, 1,176,157, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, -208,136, 91, 2, 0, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0, 64,137, 91, 2, 0, 0, 0, 0, 96,136, 91, 2, 0, 0, 0, 0, - 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,228, 3, 33, 3, 16,163, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 40, 0, 0, 0, - 64,137, 91, 2, 0, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,136, 91, 2, 0, 0, 0, 0, - 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 97, 3, 61, 3, 64,153, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 64, 1, 0, 0, -176,137, 91, 2, 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,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 80, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0,100, 0, 10, 0, 0, 0, - 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, - 50, 0, 50, 0, 10, 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, - 0, 0, 0, 0, 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, 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, 68, 65, 84, 65, 88, 0, 0, 0, 48,139, 91, 2, 0, 0, 0, 0, -129, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 32, 82,101,110,100,101,114, - 76, 97,121,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,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,152, 0, 0, 0,208,139, 91, 2, 0, 0, 0, 0, 29, 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, 1, 0, 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,145,137, 68, 66,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66, -161, 14,234, 64, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0,232, 1, 0, 0,176,140, 91, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 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, 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, -224,142, 91, 2, 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, - 64, 11, 3, 0, 1, 0, 0, 0, 0, 0, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24,238, 10, 7,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,112,231, 10, 7,144,232, 10, 7, +200,233, 10, 7, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, + 0, 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, 83, 67, 0, 0, 92, 5, 0, 0,160, 33, 10, 7,150, 0, 0, 0, 1, 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, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,192, 9, 7, 64, 39, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, +120,188, 2, 7, 48,241, 2, 7,120,188, 2, 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,192,144, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,224,142, 91, 2, 0, 0, 0, 0, - 54, 1, 0, 0, 1, 0, 0, 0, 1, 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, 96,144, 91, 2, 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, 72,239, 10, 7,152,230,101, 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,172, 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,100, 0, 0, 0,100, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 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, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 25, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 0, 0, + 24, 0, 17, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 23, 0, 33, 0, 0, 0,128, 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, 0, 0, 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,231, 9, 7, 48,231, 9, 7, 0, 0, 0, 0, + 0, 0,200, 66, 0, 0,200, 66, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 98, 97, + 99,107, 98,117,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 96,144, 91, 2, 0, 0, 0, 0, 52, 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,192,144, 91, 2, 0, 0, 0, 0, - 19, 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,216, 1, 0, 0, 48,145, 91, 2, 0, 0, 0, 0, -123, 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, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,128, 62, 0, 0,128, 62, 0, 0, 0, 0,205,204,204, 61,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,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, 0, 0, 0, 0, 0, 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, 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, - 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, 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, 31, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 88, 0, 0,176, 0, 0, 0, 80,147, 91, 2, 0, 0, 0, 0, 27, 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, 88, 84,101,120,116, 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, 7, 0, 0, 0, 1, 0, 0, 0, 64,148, 91, 2, 0, 0, 0, 0, 64,148, 91, 2, 0, 0, 0, 0, - 64,148, 91, 2, 0, 0, 0, 0, 64,148, 91, 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,149, 91, 2, 0, 0, 0, 0,255,255,255,255, 0, 4, 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, 64,148, 91, 2, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,148, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0,176,148, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 1, 0, 79, 66, 0, 0, 40, 4, 0, 0, 64,153, 91, 2, 0, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0,176,157, 91, 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, 79, 66, 67, 97, -109,101,114, 97, 0, 97,109,101,114, 97, 46, 48, 48, 49, 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, 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,208,139, 91, 2, 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, 6, 0, 0, 0, 16, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 11, 7, 1, 0, 0, 0, 1, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 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, 28, 65, 0, 0, 0, 0, 32, 0, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, +128, 0, 5, 0, 60, 0, 5, 0, 1, 0, 5, 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, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 5, 0,128, 7, 56, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 28, 0, 0, 0,120,188, 2, 7, +128, 0, 0, 0, 1, 0, 0, 0,136,223, 2, 7, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,236, 1, 64, 1, +224,195, 9, 7, 68, 65, 84, 65, 28, 0, 0, 0,136,223, 2, 7,128, 0, 0, 0, 1, 0, 0, 0, 48,241, 2, 7,120,188, 2, 7, + 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,121, 2, 10, 2,136,199, 9, 7, 68, 65, 84, 65, 28, 0, 0, 0, 48,241, 2, 7, +128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,136,223, 2, 7, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 38, 2, 28, 2, + 56,192, 9, 7, 68, 65, 84, 65, 72, 1, 0, 0, 72,239, 10, 7,147, 0, 0, 0, 1, 0, 0, 0, 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, 0, 0, 0, 0, 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, 80, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, 50, 0, 50, 0, 10, 0, 0, 0, + 50, 0,100, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, + 50, 0, 50, 0, 10, 0, 0, 0, 50, 0, 50, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 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, 48,231, 9, 7,133, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 32, 82,101, +110,100,101,114, 76, 97,121,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,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, +120, 0, 0, 0,240,143, 9, 7, 29, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 63,145,137, 68, 66,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66, +161, 14,234, 64, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0,124, 1, 0, 0,208,240, 10, 7, 41, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 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, 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,144,242, 10, 7, + 2, 0, 0, 0, 46, 26,128, 63, 25, 4,240, 65, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64, 64, 11, 3, 0, 1, 0, 0, 0, + 0, 0, 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,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, - 42,254,141, 63,192, 57, 49, 60, 34,159, 80, 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, 0, 0,128, 63,157,190,215, 49, -167,170, 4, 52, 0, 0, 0,128,129,116,157,178, 1, 0,128, 63, 33, 69, 15, 51, 0, 0, 0,128, 73,254, 67, 51,243, 97,106, 49, - 0, 0,128, 63, 0, 0, 0,128, 3, 0, 64, 52,183,164,157, 39, 0, 0,128, 53, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, - 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 79, 66, 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, 2, 0, 1, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 4, 7, 68, 65, 84, 65, 8, 1, 0, 0, +144,242, 10, 7, 64, 1, 0, 0, 1, 0, 0, 0, 1, 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,112,236, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 79, 66, 0, 0, 40, 4, 0, 0,176,157, 91, 2, 0, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 16,163, 91, 2, - 0, 0, 0, 0, 64,153, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67,117, + 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,112,236, 2, 7, + 62, 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, 32, 0, 0, 0, 0, 42, 4, 7, 19, 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, 87, 79, 0, 0,104, 1, 0, 0, 64, 39, 10, 7, +127, 0, 0, 0, 1, 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, 1, 0, 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,128, 62, 0, 0,128, 62, 0, 0, 0, 0,205,204,204, 61,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,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, 0, 0, 0, 0, 0, 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, 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, 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, 84, 88, 0, 0,120, 0, 0, 0,232, 40, 10, 7, 27, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 84,101,120,116, 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, 7, 0, 0, 0, + 1, 0, 0, 0, 96,142, 2, 7, 96,142, 2, 7, 96,142, 2, 7, 96,142, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,160, 41, 10, 7,255,255,255,255, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 96,142, 2, 7, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,248, 11, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0,104,248, 11, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 79, 66, 0, 0,100, 3, 0, 0, 56,192, 9, 7,118, 0, 0, 0, 1, 0, 0, 0,224,195, 9, 7, 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, 1, 0, 0, 4, + 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,240,143, 9, 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,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, 42,254,141, 63,192, 57, 49, 60, 34,159, 80, 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, 0, 0,128, 63,125,103,133, 51,176,219,194,178, 0, 0, 0, 0,190, 32, 66, 51, 1, 0,128, 63, +168,200,153, 51, 0, 0, 0, 0, 32,206, 18,179,126,126,149, 50, 1, 0,128, 63, 0, 0, 0, 0,241,251,133, 52,172,182, 27,180, +174,236,252, 51, 0, 0,128, 63, 0, 0,128, 63,157,190,215, 49,167,170, 4, 52, 0, 0, 0,128,129,116,157,178, 1, 0,128, 63, + 33, 69, 15, 51, 0, 0, 0,128, 73,254, 67, 51,243, 97,106, 49, 0, 0,128, 63, 0, 0, 0,128, 3, 0, 64, 52,183,164,157, 39, + 0, 0,128, 53, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 79, 66, 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, 2, 0, 1, 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, 0, 0, 0, 0, 0, 0, 1, 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, 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, 79, 66, 0, 0,100, 3, 0, 0, +224,195, 9, 7,118, 0, 0, 0, 1, 0, 0, 0,136,199, 9, 7, 56,192, 9, 7, 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, 1, 0, 0, 4, 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, 0, 0, 80,193,181, 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,128,173, 91, 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,192,162, 91, 2, 0, 0, 0, 0,112,162, 91, 2, 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, 0, 0, 0, 0, 0,128, 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,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,222,149, 47, 63, 52, 70, 58, 63, -179, 56, 49,188, 0, 0, 0,128, 86,126,162,190,227,251,159, 62, 56, 53,101, 63, 0, 0, 0,128, 7,165, 39, 63,149, 84, 28,191, - 50,247,227, 62, 0, 0, 0,128,110,101,239, 64,151, 62,208,192, 77,255,170, 64, 0, 0,128, 63, 1, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 79, 66, 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, 4, 0, 1, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,204,180, 2, 0, 0, 0, 0,160,185,181, 2, - 0, 0, 0, 0, 25, 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, 68, 65, 84, 65, 8, 0, 0, 0,192,162, 91, 2, 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,112,162, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 79, 66, 0, 0, 40, 4, 0, 0, 16,163, 91, 2, 0, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -176,157, 91, 2, 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, 1, 0, 0, 4, 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,176,140, 91, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,229,123, 38, 63, - 87, 43, 98, 61,229,229,238, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184,149, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 21, 12, 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,224,127, 10, 7, +168,144, 9, 7, 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, 0, 0, 0, 0, 0,128, 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,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, 53,236,148,190,222,102, 69,191, 37,255, 16, 63, - 0, 0, 0,128, 24,134,116, 63, 57,174, 76,190,240,161, 95, 62, 0, 0, 0,128,235, 13, 98,189, 34,194, 26, 63,166,111, 75, 63, - 0, 0, 0,128,208, 19, 13, 63,234, 65,102,190, 10, 10,231,192, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, - 5, 0, 1, 0, 0, 0, 68, 0, 79, 66, 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, 4, 0, 1, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 77, 65, 0, 0,224, 2, 0, 0,128,167, 91, 2, 0, 0, 0, 0, 41, 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, 65, 77, 97,116,101,114,105, - 97,108, 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,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, 0, 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, 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, 0, 0, 3, 0, 1, 3, 3, 0, 1, 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,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,160,170, 91, 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,112,171, 91, 2, 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,205,204, 76, 63, -205,204, 76, 63,205,204, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, -160,170, 91, 2, 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -224,171, 91, 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,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, +222,149, 47, 63, 52, 70, 58, 63,179, 56, 49,188, 0, 0, 0,128, 86,126,162,190,227,251,159, 62, 56, 53,101, 63, 0, 0, 0,128, + 7,165, 39, 63,149, 84, 28,191, 50,247,227, 62, 0, 0, 0,128,110,101,239, 64,151, 62,208,192, 77,255,170, 64, 0, 0,128, 63, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 79, 66, 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, 4, 0, 1, 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, 0, 0,128, 63, 0, 64, 1, 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,120,137, 25, 7,152,143, 25, 7, 25, 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, 68, 65, 84, 65, 4, 0, 0, 0,224,127, 10, 7, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,168,144, 9, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 79, 66, 0, 0,100, 3, 0, 0,136,199, 9, 7,118, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,224,195, 9, 7, 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, 1, 0, 0, 4, + 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,208,240, 10, 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,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,229,123, 38, 63, 87, 43, 98, 61,229,229,238, 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, 35,233,134, 49,251,110, 17,179, 0, 0, 0, 0, 49,158,141, 50, 1, 0,128, 63, +126,214,237, 50, 0, 0, 0, 0,155,248, 28,178,199,139, 96,177,254,255,127, 63, 0, 0, 0, 0, 80,136,159,178,192, 4,158,178, +209,114,143,179, 0, 0,128, 63, 53,236,148,190,222,102, 69,191, 37,255, 16, 63, 0, 0, 0,128, 24,134,116, 63, 57,174, 76,190, +240,161, 95, 62, 0, 0, 0,128,235, 13, 98,189, 34,194, 26, 63,166,111, 75, 63, 0, 0, 0,128,208, 19, 13, 63,234, 65,102,190, + 10, 10,231,192, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 68, 0, 79, 66, 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, 4, 0, 1, 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, 0, 0, 0, 0, 0, 64, 1, 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, 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, 77, 65, 0, 0,184, 2, 0, 0, + 48,203, 9, 7, 44, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 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, 1, 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,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 10,215, 35, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +205,204, 76, 62,205,204, 76, 62, 0, 0, 8, 0, 1, 0, 50, 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, 0, 0, + 67, 0, 0, 3, 3, 0, 1, 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,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,128, 63, 0, 0,128, 63, 40,206, 9, 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, 56,144, 2, 7, 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,205,204, 76, 63,205,204, 76, 63,205,204, 76, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 40,206, 9, 7, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0,224, 45, 10, 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, 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,144, 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,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0,128, 63,205,204, 76, 62, 0, 0, 0, 0, - 68, 65, 84, 65, 40, 0, 0, 0,112,171, 91, 2, 0, 0, 0, 0, 19, 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, - 84, 69, 0, 0, 88, 1, 0, 0,224,171, 91, 2, 0, 0, 0, 0, 37, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63, 0, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0,128, 63, +205,204, 76, 62, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,144, 2, 7, 19, 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, 84, 69, 0, 0, + 40, 1, 0, 0,224, 45, 10, 7, 39, 0, 0, 0, 1, 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, 1, 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, 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, @@ -761,93 +860,83 @@ char datatoc_B_blend[]= { 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, 1, 0, 0, 0, 2, 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, 77, 69, 0, 0, 24, 1, 0, 0, + 48, 21, 12, 7, 54, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 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,131, 2, 7, 80, 27, 12, 7, 0, 0, 0, 0, + 0, 0, 0, 0,248,206, 9, 7, 72, 47, 10, 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,136, 22, 12, 7, 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 24, 12, 7, + 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 25, 12, 7, 1, 0, 0, 0, 5, 0, 0, 0, + 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 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, 0, 0, 0, 0, 67, 0, 0, 0, 30, 0, 4, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 80,131, 2, 7, 0, 0, 0, 0, 1, 0, 0, 0, 48,203, 9, 7, 68, 65, 84, 65, + 84, 1, 0, 0,136, 22, 12, 7, 67, 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, 77, 69, 0, 0,144, 1, 0, 0,128,173, 91, 2, 0, 0, 0, 0, - 51, 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, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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,182, 91, 2, 0, 0, 0, 0, - 48,182, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,177, 91, 2, 0, 0, 0, 0, -176,179, 91, 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, 80,175, 91, 2, 0, 0, 0, 0, - 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,178, 91, 2, 0, 0, 0, 0, - 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,180, 91, 2, 0, 0, 0, 0, - 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 67, 0, 0, 0, 30, 0, 4, 0, - 1, 0, 1, 0, 1, 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, -240,182, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128,167, 91, 2, 0, 0, 0, 0, 68, 65, 84, 65,104, 1, 0, 0, - 80,175, 91, 2, 0, 0, 0, 0, 57, 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,177, 91, 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,248,206, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,192, 0, 0, 0, - 0,177, 91, 2, 0, 0, 0, 0, 57, 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,255, 0, 3, 0, 0, 0, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182, 26,182,255, 0, 3, 0, 0, 0, - 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182,255, 0, 3, 0, 0, 0,250,255,127,191, 3, 0,128, 63, - 0, 0,128,191, 26,182,230, 73, 26,182,255, 0, 3, 0, 0, 0, 4, 0,128, 63,247,255,127, 63, 0, 0,128, 63,230, 73,230, 73, -230, 73,255, 0, 3, 0, 0, 0,245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,230, 73,255, 0, 3, 0, 0, 0, - 3, 0,128,191,250,255,127,191, 0, 0,128, 63, 26,182, 26,182,230, 73,255, 0, 3, 0, 0, 0,255,255,127,191, 0, 0,128, 63, - 0, 0,128, 63, 26,182,230, 73,230, 73,255, 0, 3, 0, 0, 0, 68, 65, 84, 65,104, 1, 0, 0, 0,178, 91, 2, 0, 0, 0, 0, - 57, 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,176,179, 91, 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, 68, 65, 84, 65,192, 0, 0, 0,248,206, 9, 7, 60, 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,255,127, 1, 0, 0, 0, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182, + 26,182,255,127, 1, 0, 0, 0, 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182,255,127, 1, 0, 0, 0, +250,255,127,191, 3, 0,128, 63, 0, 0,128,191, 26,182,230, 73, 26,182,255,127, 1, 0, 0, 0, 4, 0,128, 63,247,255,127, 63, + 0, 0,128, 63,230, 73,230, 73,230, 73,255,127, 1, 0, 0, 0,245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182, +230, 73,255,127, 1, 0, 0, 0, 3, 0,128,191,250,255,127,191, 0, 0,128, 63, 26,182, 26,182,230, 73,255,127, 1, 0, 0, 0, +255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73,230, 73,255,127, 1, 0, 0, 0, 68, 65, 84, 65, 84, 1, 0, 0, + 32, 24, 12, 7, 67, 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, 72, 47, 10, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,176,179, 91, 2, 0, 0, 0, 0, - 54, 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,104, 1, 0, 0, -128,180, 91, 2, 0, 0, 0, 0, 57, 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, 48,182, 91, 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, + 68, 65, 84, 65,144, 0, 0, 0, 72, 47, 10, 7, 57, 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, 84, 1, 0, 0,184, 25, 12, 7, 67, 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, 80, 27, 12, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, - 48,182, 91, 2, 0, 0, 0, 0, 53, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, - 0, 0, 0, 2, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0, - 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, - 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 2, 85, 83, 69, 82, 64, 11, 0, 0, 32, 94,154, 1, 0, 0, 0, 0,178, 0, 0, 0, 1, 0, 0, 0, - 33,152, 1, 0, 63, 2, 0, 0, 5, 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, 68, 65, 84, 65,120, 0, 0, 0, 80, 27, 12, 7, 56, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, + 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 2, 85, 83, 69, 82, 56, 11, 0, 0, + 0, 2, 68, 1,185, 0, 0, 0, 1, 0, 0, 0, 33,152, 1, 0, 63, 2, 0, 0, 5, 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, 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, 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, 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, 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, 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, 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, @@ -865,9 +954,9 @@ char datatoc_B_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, 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, 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, @@ -875,1002 +964,1047 @@ char datatoc_B_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, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 48, 52, 6, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0,192,194, 91, 2, 0, 0, 0, 0, -192,215, 91, 2, 0, 0, 0, 0,240,195,100, 2, 0, 0, 0, 0,240,195,100, 2, 0, 0, 0, 0, 80, 51,101, 2, 0, 0, 0, 0, - 80, 51,101, 2, 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, 0, 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, 0, 0, 25, 0, 15, 0,120, 0, 60, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, 6, 0, 15, 0, - 8, 0, 10, 0,250, 0, 0, 0,100, 0,100, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 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, - 68, 65, 84, 65,192, 20, 0, 0,192,194, 91, 2, 0, 0, 0, 0,176, 0, 0, 0, 1, 0, 0, 0,192,215, 91, 2, 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, 25, 0,231,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,255,255,255,255,255,255,255,255, 0, 0, 0,255, - 0, 0, 38, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90,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,145,145,145,245, 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,180,180,180,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,130,130,130,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,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,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,145,145,145,245, 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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,145,145,145,245, 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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, - 3, 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,145,145,145,245, 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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, - 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,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, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, -255,255,255, 10,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,110,110,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,145,145,145,245, 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,132,132,132,255, 0, 0, 0,255, - 0, 0, 0,255,255,255,255,255, 94, 94, 94,255,172,172,172,255, 17, 27, 60,100, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, - 0, 0, 0, 40,195,195,195,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, - 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,255,255,255,128, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255, -200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, -150,150,150,255,129,131,144,255,127,127,127,255,142,138,145,255,120,145,120,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,255,255,255,128, 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,145,145,145,245, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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, 68, 65, 84, 65,192, 20, 0, 0, -192,215, 91, 2, 0, 0, 0, 0,176, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,194, 91, 2, 0, 0, 0, 0, - 82,111,117,110,100,101,100, 0, 0,101,119, 32, 85,115,101,114, 32, 84,104,101,109,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, 2, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 48, 52, 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 8, 0, 0, 2, 0, 0, 0, 68,172, 0, 0, 36, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0,168, 3, 10, 7, 40,207, 13, 7, 48, 93, 5, 7, + 48, 93, 5, 7,128, 94, 5, 7,128, 94, 5, 7, 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, 0, 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, 0, 0, 25, 0, 15, 0,120, 0, 60, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, + 6, 0, 15, 0, 8, 0, 10, 0,250, 0, 0, 0,100, 0,100, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 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, 68, 65, 84, 65,200, 21, 0, 0,168, 3, 10, 7,183, 0, 0, 0, 1, 0, 0, 0, 40,207, 13, 7, 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, 25, 0,231,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, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 46,124,217,204,255,255,255,255,255,255,255,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,255,255,255,255,255,255,255,255, 0, 0, 0,255, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,175,175,175, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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, -107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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, - 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, - 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255, -255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60, -255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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,255,140, 25,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 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,255,255,255,128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90,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, +165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,180,180,180,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,130,130,130,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,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, +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,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 82, 96,110,255, +124,137,150,255, 3, 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,255,255,255,128, + 0, 0, 0,255,255,133, 0,255, 3, 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,255,140, 25,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100,255,130, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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, -107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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, -107,107,107,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,100,143,143,143,100, 96,192, 64,255, 94, 94, 94,255, - 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255,255,255,255,255,255,255,255,255, -255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 82, 96,110,255, -124,137,150,255, 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, -255,255,255,255,255,130, 0,255, 2, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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, -158,158,158,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, - 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255, -255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 79,101, 73,255,135,177,125,255,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,143,143,143,255,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -228,156,198,204,255,255,170,204, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 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, -107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,143,143,143,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, - 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255, -255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,255,255,255,170,255, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 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,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255, +124,137,150,255, 3, 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,255,255,255,128, + 0, 0, 0,255,255,133, 0,255, 3, 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,255,140, 25,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,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, 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,195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, - 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255, -255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, -255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 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, +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, + 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,255,140, 25,255, 16, 64, 16,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,255,255,255, 10,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 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,255,255,255,128, - 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, -195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -143,143,143,255,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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, -153,153,153,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,153,153,153,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 88, 88, 88,255, - 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255, -255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 2, 0, 0, 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, - 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, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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, -158,158,158,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, - 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255, -255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255, -107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255, - 0, 0, 0, 0, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,110,110,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,132,132,132,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, + 94, 94, 94,255,172,172,172,255, 17, 27, 60,100, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,195,195,195,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 4, 0, 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,255,255,255,128, + 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,255,140, 25,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 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,255,255,255,128, + 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,255,140, 25,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255, 127,127,127,255,142,138,145,255,120,145,120,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, -100,100,100,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, -145,145,145,245, 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, - 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, - 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255, -255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60, -255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 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, +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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, +255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, - 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, 68, 78, 65, 49,224,211, 0, 0, 96,169,184, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, 78, 65, 77, 69,102, 10, 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,119, 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, 51, 50, - 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, 50, 52, 93, 0,117,115, 0,105, 99,111,110, 95,105,100, 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, 50, 52, 48, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 52, 48, 93, 0,116,111,116, 0,112, 97,100, 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,112, 97,100, 48, 0,112, 97, -100, 49, 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,112, 97,100, 50, - 0, 42,119,101,105,103,104,116,115, 0,118,103,114,111,117,112, 91, 51, 50, 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, 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,112, 97,115,115,101,112, 97,114,116, 97,108,112,104, 97, 0, 97,110,103,108,101, 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,104,105,102,116,120, 0,115,104,105,102,116,121, 0, 89, 70, 95,100,111,102,100,105, -115,116, 0, 89, 70, 95, 97,112,101,114,116,117,114,101, 0, 89, 70, 95, 98,107,104,116,121,112,101, 0, 89, 70, 95, 98,107,104, - 98,105, 97,115, 0, 89, 70, 95, 98,107,104,114,111,116, 0, 42,100,111,102, 95,111, 98, 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,109,101,110,117,110,114, 0, - 42,115, 99,101,110,101, 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,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, 42,114,101,110,100,101,114, 95,116,101,120,116, 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, 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, - 51, 50, 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,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,112, 97,100, 91, 50, 93, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114, - 0, 99,111,108,102, 97, 99, 0,110,111,114,102, 97, 99, 0,118, 97,114,102, 97, 99, 0,100,105,115,112,102, 97, 99, 0,119, 97, -114,112,102, 97, 99, 0,110, 97,109,101, 91, 49, 54, 48, 93, 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,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,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,101,120,116,101,110,100, - 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, 99,111, 98, 97, 0, 42,101,110,118, 0,117,115,101, 95,110,111,100,101,115, 0, -112, 97,100, 91, 55, 93, 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,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,102, 97,108,108,111,102,102, 95,116,121,112,101, 0,115,104, 97,100,115,112, -111,116,115,105,122,101, 0, 98,105, 97,115, 0,115,111,102,116, 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, 0, 89, 70, 95,110,117,109,112,104,111,116, -111,110,115, 0, 89, 70, 95,110,117,109,115,101, 97,114, 99,104, 0, 89, 70, 95,112,104,100,101,112,116,104, 0, 89, 70, 95,117, -115,101,113,109, 99, 0, 89, 70, 95, 98,117,102,115,105,122,101, 0, 89, 70, 95,112, 97,100, 0, 89, 70, 95, 99, 97,117,115,116, -105, 99, 98,108,117,114, 0, 89, 70, 95,108,116,114, 97,100,105,117,115, 0, 89, 70, 95,103,108,111,119,105,110,116, 0, 89, 70, - 95,103,108,111,119,111,102,115, 0, 89, 70, 95,103,108,111,119,116,121,112,101, 0, 89, 70, 95,112, 97,100, 50, 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, 91, 51, 93, 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,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, 51, 50, 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, 89, 70, 95, 97,114, 0, 89, 70, 95, 97,103, 0, - 89, 70, 95, 97, 98, 0, 89, 70, 95,100,115, 99, 97,108,101, 0, 89, 70, 95,100,112,119,114, 0, 89, 70, 95,100,115,109,112, 0, - 89, 70, 95,112,114,101,115,101,116, 0, 89, 70, 95,100,106,105,116, 0,103,112,117,109, 97,116,101,114,105, 97,108, 0,110, 97, -109,101, 91, 50, 53, 54, 93, 0, 42, 98, 98, 0,105, 49, 0,106, 49, 0,107, 49, 0,105, 50, 0,106, 50, 0,107, 50, 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,116,111,116, 99,111,108, 0,119,105, + 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,255,140, 25,255, + 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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, + 68, 65, 84, 65,200, 21, 0, 0, 40,207, 13, 7,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168, 3, 10, 7, 82,111,117,110, +100,101,100, 0, 0,101,119, 32, 85,115,101,114, 32, 84,104,101,109,101, 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, 25, 0,231,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, 0, 0, 0, 0, + 0, 0, 0, 0, 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, +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, 46,124,217,204,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, + 0, 0, 0, 0, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,175,175,175, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, +127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,107,107,107,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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, 0, 0, 0, 51, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255, +217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, + 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 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,255,255,255,128, 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,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, +127,112,112,100,255,130, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,107,107,107,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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,107,107,107,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,100,143,143,143,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255, +255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255,255,255,255,255,255,255,255,255,255,130, 0,255, + 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 82, 96,110,255,124,137,150,255, + 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,255,255,255,255, +255,130, 0,255, 2, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, +127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,158,158,158,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255, +255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, + 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255, +178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255, +135,177,125,255,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,143,143,143,255,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,204, +255,255,170,204, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 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,107,107,107,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,143,143,143,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255, +255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, + 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,255,255,255,170,255, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, +127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 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, 81,105,135,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, 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,195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255, +255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, + 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,255,133, 0,255, + 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 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,255,255,255,128, 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,195,195,195,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255, +127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,153,153,153,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,153,153,153,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 88, 88, 88,255, 0, 0, 0,255, +255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, + 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, + 2, 0, 0, 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, 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,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, +127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,158,158,158,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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,150, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255, +255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, + 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, +127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255, 0, 0, 0, 0, + 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255,127,127,127,255, +142,138,145,255,120,145,120,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,100,100,100,255, + 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, + 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, 0, 0, 0, 51, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255, +217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, + 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 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,255,255,255,128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0,255,255,255,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 68, 78, 65, 49, + 28,222, 0, 0, 32, 80, 6, 7, 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, 78, 65, 77, 69,212, 10, 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,119, 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, 51, 50, 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, 50, 52, 93, 0,117,115, 0,105, 99,111,110, 95,105, +100, 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, 50, 52, 48, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 52, 48, 93, 0,116,111,116, 0, +112, 97,100, 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,112, 97,100, 48, 0,112, 97,100, 49, 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,112, 97,100, 50, 0, 42,119,101,105,103,104,116,115, 0,118,103,114,111,117,112, 91, 51, 50, 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, 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,112, 97,115,115,101,112, 97,114,116, 97,108,112,104, + 97, 0, 97,110,103,108,101, 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,104,105,102,116,120, 0,115,104,105,102,116,121, 0, + 89, 70, 95,100,111,102,100,105,115,116, 0, 89, 70, 95, 97,112,101,114,116,117,114,101, 0, 89, 70, 95, 98,107,104,116,121,112, +101, 0, 89, 70, 95, 98,107,104, 98,105, 97,115, 0, 89, 70, 95, 98,107,104,114,111,116, 0, 42,100,111,102, 95,111, 98, 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,109,101,110,117,110,114, 0, 42,115, 99,101,110,101, 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,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, 42,114,101,110,100,101,114, 95,116,101,120,116, 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, 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, 51, 50, 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,112, 97,100, 91, 55, 93, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114, 0, 99,111,108,102, + 97, 99, 0,110,111,114,102, 97, 99, 0,118, 97,114,102, 97, 99, 0,100,105,115,112,102, 97, 99, 0,119, 97,114,112,102, 97, 99, + 0,110, 97,109,101, 91, 49, 54, 48, 93, 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, 42,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,112,100,112, 97,100, 50, 91, 50, 93, 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, 42, 99,111, 98, 97, 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,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, 50, 52, 48, 93, 0, 42,100, 97,116, 97,115,101,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, +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,101,120,116,101,110,100, 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,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,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, 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, 0, 89, 70, 95,110,117,109,112,104, +111,116,111,110,115, 0, 89, 70, 95,110,117,109,115,101, 97,114, 99,104, 0, 89, 70, 95,112,104,100,101,112,116,104, 0, 89, 70, + 95,117,115,101,113,109, 99, 0, 89, 70, 95, 98,117,102,115,105,122,101, 0, 89, 70, 95,112, 97,100, 0, 89, 70, 95, 99, 97,117, +115,116,105, 99, 98,108,117,114, 0, 89, 70, 95,108,116,114, 97,100,105,117,115, 0, 89, 70, 95,103,108,111,119,105,110,116, 0, + 89, 70, 95,103,108,111,119,111,102,115, 0, 89, 70, 95,103,108,111,119,116,121,112,101, 0, 89, 70, 95,112, 97,100, 50, 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, 91, 51, 93, 0,100,101,110,115,105, +116,121, 0,101,109,105,115,115,105,111,110, 0, 97, 98,115,111,114,112,116,105,111,110, 0,115, 99, 97,116,116,101,114,105,110, +103, 0,101,109,105,115,115,105,111,110, 95, 99,111,108, 91, 51, 93, 0, 97, 98,115,111,114,112,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,112, +104, 97,115,101,102,117,110, 99, 95,116,121,112,101, 0,118,112, 97,100, 91, 51, 93, 0,112,104, 97,115,101,102,117,110, 99, 95, +103, 0,115,116,101,112,115,105,122,101, 0,115,104, 97,100,101, 95,115,116,101,112,115,105,122,101, 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,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,116,101,112,115, 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,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, 51, 50, 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, 89, 70, 95, 97,114, 0, 89, 70, 95, 97,103, 0, 89, 70, 95, 97, 98, 0, + 89, 70, 95,100,115, 99, 97,108,101, 0, 89, 70, 95,100,112,119,114, 0, 89, 70, 95,100,115,109,112, 0, 89, 70, 95,112,114,101, +115,101,116, 0, 89, 70, 95,100,106,105,116, 0,103,112,117,109, 97,116,101,114,105, 97,108, 0,110, 97,109,101, 91, 50, 53, 54, + 93, 0, 42, 98, 98, 0,105, 49, 0,106, 49, 0,107, 49, 0,105, 50, 0,106, 50, 0,107, 50, 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,114, 97,100,105,117,115, 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,104, 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,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, 98,112, 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,101,102,102,101, 99,116, 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,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,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, 97, 99,116, 95,102, 97, 99,101, 0, - 99,117, 98,101,109, 97,112,115,105,122,101, 0,100,114, 97,119,102,108, 97,103, 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, 42,109,114, 0, 42, -112,118, 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,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,105,110,100,101, -120, 0,102, 0,105, 0,115, 91, 50, 53, 54, 93, 0,116,111,116,100,105,115,112, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0, -118, 91, 52, 93, 0,109,105,100, 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, 42,118,101,114,116, 95,109, 97,112, 0, 42,101,100,103,101, 95,109, 97,112, 0, 42,111, -108,100, 95,102, 97, 99,101,115, 0, 42,111,108,100, 95,101,100,103,101,115, 0, 42,101,114,114,111,114, 0,109,111,100,105,102, -105,101,114, 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,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, - 51, 50, 93, 0, 42,116,101,120,116,117,114,101, 0,115,116,114,101,110,103,116,104, 0,100,105,114,101, 99,116,105,111,110, 0, -109,105,100,108,101,118,101,108, 0,116,101,120,109, 97,112,112,105,110,103, 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, 51, 50, 93, 0,117,118,108, 97,121,101,114, 95,116,109,112, 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,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,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, 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, 97, 98,115,111,114,112,116,105,111,110, 0,116,105,109,101, 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,110,101,101,100, 98,105,110,100, 0, 42, 98,105,110, -100,119,101,105,103,104,116,115, 0, 42, 98,105,110,100, 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,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, -115,121,115, 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, 42,117,110,100,111, 95,118,101,114,116,115, 0, -117,110,100,111, 95,118,101,114,116,115, 95,116,111,116, 0,117,110,100,111, 95,115,105,103,110, 97,108, 0,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, 51, 50, 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,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, -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, 51, 50, 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, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 0,100,101,102, 98, 97,115,101, 0,109,111, -100,105,102,105,101,114,115, 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,114,111,116, 91, 51, 93, 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,108, 97,121, 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,105,112,111,119,105,110, 0,115, 99, - 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0, 98,111,117,110,100,116,121,112,101, 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,115,105,122,101,102, 97, 99, 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,100,116, - 0,100,116,120, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,112, 97,100, 49, 91, 53, 93, 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,112,100, 0, 42,115,111,102,116, 0, 42,100,117,112, 95,103,114, -111,117,112, 0,102,108,117,105,100,115,105,109, 70,108, 97,103, 0,114,101,115,116,114,105, 99,116,102,108, 97,103, 0,115,104, - 97,112,101,110,114, 0,115,104, 97,112,101,102,108, 97,103, 0,114,101, 99, 97,108, 99,111, 0, 98,111,100,121, 95,116,121,112, -101, 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,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, 99,117,114,105,110,100,101,120, 0, - 97, 99,116,105,118,101, 0,100,101,102,108,101, 99,116, 0,102,111,114, 99,101,102,105,101,108,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,102, 95,115,116,114,101,110,103,116,104, 0,102, 95,112,111,119, -101,114, 0,102, 95,100,105,115,116, 0,102, 95,100, 97,109,112, 0,109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116, - 0,109, 97,120,114, 97,100, 0,109,105,110,114, 97,100, 0,102, 95,112,111,119,101,114, 95,114, 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, -116,101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110,107, 95, 97,120,105,115, 0,114,116, 50, 0, 42,114,110,103, - 0,102, 95,110,111,105,115,101, 0,102,114, 97,109,101, 0,116,111,116,112,111,105,110,116, 0, 42,120,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,110, 97,109,101, 91, 54, 52, 93, 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, 50, 52, 48, 93, 0, -109,101,109, 95, 99, 97, 99,104,101, 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, 42,112, 97,114,116,105, 99,108,101,115, 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, 51, 50, 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, 51, 50, 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, 51, 50, 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,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,120, 0,103,114, 97,118,121, 0,103,114, 97,118,122, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69,110, -100, 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, 83,117,114,102, 97, 99,101, 0, - 42,109,101,115,104, 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 50, 52, 48, 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, 83,117,114,102, 78,111, -114,109, 97,108,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,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0, -104,111,114,107, 0,122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,122,101,110,107, 0, 97,109, 98,107, 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,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, 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,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, 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, 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,102,102, 99,111,100,101, 99,100, 97, -116, 97, 0, 97,117,100,105,111, 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,114,116, 49, 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,119,105,110,112,111,115, 0, -112,108, 97,110,101,115, 0,105,109,116,121,112,101, 0,115,117, 98,105,109,116,121,112,101, 0,113,117, 97,108,105,116,121, 0, -100,105,115,112,108, 97,121,109,111,100,101, 0,114,112, 97,100, 49, 0,114,112, 97,100, 50, 0,115, 99,101,109,111,100,101, 0, -114,101,110,100,101,114,101,114, 0,111, 99,114,101,115, 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,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, 71, 73,113,117, 97,108,105,116, -121, 0, 71, 73, 99, 97, 99,104,101, 0, 71, 73,109,101,116,104,111,100, 0, 71, 73,112,104,111,116,111,110,115, 0, 71, 73,100, -105,114,101, 99,116, 0, 89, 70, 95, 65, 65, 0, 89, 70,101,120,112,111,114,116,120,109,108, 0, 89, 70, 95,110,111, 98,117,109, -112, 0, 89, 70, 95, 99,108, 97,109,112,114,103, 98, 0,121,102,112, 97,100, 49, 0, 71, 73,100,101,112,116,104, 0, 71, 73, 99, - 97,117,115,100,101,112,116,104, 0, 71, 73,112,105,120,101,108,115,112,101,114,115, 97,109,112,108,101, 0, 71, 73,112,104,111, -116,111,110, 99,111,117,110,116, 0, 71, 73,109,105,120,112,104,111,116,111,110,115, 0, 71, 73,112,104,111,116,111,110,114, 97, -100,105,117,115, 0, 89, 70, 95,114, 97,121,100,101,112,116,104, 0, 89, 70, 95, 65, 65,112, 97,115,115,101,115, 0, 89, 70, 95, - 65, 65,115, 97,109,112,108,101,115, 0,121,102,112, 97,100, 50, 0, 71, 73,115,104, 97,100,111,119,113,117, 97,108,105,116,121, - 0, 71, 73,114,101,102,105,110,101,109,101,110,116, 0, 71, 73,112,111,119,101,114, 0, 71, 73,105,110,100,105,114,112,111,119, -101,114, 0, 89, 70, 95,103, 97,109,109, 97, 0, 89, 70, 95,101,120,112,111,115,117,114,101, 0, 89, 70, 95,114, 97,121, 98,105, - 97,115, 0, 89, 70, 95, 65, 65,112,105,120,101,108,115,105,122,101, 0, 89, 70, 95, 65, 65,116,104,114,101,115,104,111,108,100, - 0, 98, 97, 99,107, 98,117,102, 91, 49, 54, 48, 93, 0,112,105, 99, 91, 49, 54, 48, 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, 49, 54, 48, 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,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,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,112, 97,100, 49, 49, 0,102,114, 97,109,105,110,103, - 0,100,111,109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0, 42, 98,114,117,115,104, 0,116,111,111,108, 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, 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,100,114, 97,119, 95, -116,105,109,101,100, 0,115,101,108,101, 99,116,109,111,100,101, 0,110, 97,109,101, 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93, - 91, 51, 93, 0, 42,115,101,115,115,105,111,110, 0,112,105,118,111,116, 91, 51, 93, 0,116,101,120,115,101,112, 0,116, 97, 98, -108,101,116, 95,115,105,122,101, 0,116, 97, 98,108,101,116, 95,115,116,114,101,110,103,116,104, 0,112, 97,100, 91, 53, 93, 0, -103, 97,109,109, 97, 0,109,117,108, 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, 42,118,112, 97,105,110,116, 0, 42,119,112, 97,105,110,116, 0, 42,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,112, 97,100, 91, 50, 93, 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,114,101,116,111,112,111, 95,109,111,100,101, - 0,114,101,116,111,112,111, 95,112, 97,105,110,116, 95,116,111,111,108, 0,108,105,110,101, 95,100,105,118, 0,101,108,108,105, -112,115,101, 95,100,105,118, 0,114,101,116,111,112,111, 95,104,111,116,115,112,111,116, 0,109,117,108,116,105,114,101,115, 95, -115,117, 98,100,105,118, 95,116,121,112,101, 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,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,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, 42, - 99, 97,109,101,114, 97, 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, 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,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 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,106,117,109,112,102,114, 97,109,101, 0,102,114, - 97,109,101, 95,115,116,101,112, 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, 98,108,101,110,100, 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,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,118,105,101,119, 98,117,116, 0,108, 97,115,116,109,111,100,101, 0,114,102,108, - 97,103, 0,118,105,101,119,108,111, 99,107, 0,112,101,114,115,112, 0,118,105,101,119, 0, 99,108,105,112, 91, 54, 93, 91, 52, - 93, 0, 42, 99,108,105,112, 98, 98, 0, 42,103,112,100, 0, 42,108,111, 99, 97,108,118,100, 0, 42,114,105, 0, 42,114,101,116, -111,112,111, 95,118,105,101,119, 95,100, 97,116, 97, 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,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,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,108, 97,121, 95,117,115,101,100, 0, 42,111, 98, 95, - 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 0,111, 98, 95, 99,101,110,116,114,101, 95, 98,111,110,101, 91, 51, 50, 93, - 0,108, 97,121, 97, 99,116, 0,100,114, 97,119,116,121,112,101, 0,108,111, 99, 97,108,118,105,101,119, 0,115, 99,101,110,101, -108,111, 99,107, 0, 97,114,111,117,110,100, 0,102,108, 97,103, 50, 0,112,105,118,111,116, 95,108, 97,115,116, 0,103,114,105, -100, 0,103,114,105,100,118,105,101,119, 0,112, 97,100,102, 0,110,101, 97,114, 0,102, 97,114, 0,103,114,105,100,108,105,110, -101,115, 0,103,114,105,100,102,108, 97,103, 0,103,114,105,100,115,117, 98,100,105,118, 0,109,111,100,101,115,101,108,101, 99, -116, 0,107,101,121,102,108, 97,103,115, 0,116,119,116,121,112,101, 0,116,119,109,111,100,101, 0,116,119,102,108, 97,103, 0, -116,119,100,114, 97,119,102,108, 97,103, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 0, 97,102,116,101,114, -100,114, 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 0,110,100,111,102,109,111,100,101, 0,110,100,111,102,102,105,108,116, -101,114, 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, 99,117,114,115,111,114, 91, 50, 93, 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, 42,115, 99,114,101,101,110, 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,112,105,110, 0,108,111, 99, -107, 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,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,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, 50, 52, 93, 0,100,105,114, 91, 50, 52, 48, 93, 0,102,105,108,101, 91, 56, 48, 93, 0, -115,111,114,116, 0,100,105,115,112,108, 97,121, 0, 97, 99,116,105,118,101, 95, 98,111,111,107,109, 97,114,107, 0, 97, 99,116, -105,118,101, 95,102,105,108,101, 0,115,101,108,115,116, 97,116,101, 0,102, 95,102,112, 0,109,101,110,117, 0,102,112, 95,115, -116,114, 91, 56, 93, 0, 42,112,117,112,109,101,110,117, 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,108, -111, 97,100,105,109, 97,103,101, 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,115,101, 97,114, 99,104, 95,102,108, 97,103,115, 0,100,111, 95, 0,111,117,116,108,105,110,101,118,105,115, 0,115,116,111, -114,101,102,108, 97,103, 0, 42, 99,117,109, 97,112, 0,105,109, 97,110,114, 0, 99,117,114,116,105,108,101, 0,105,109,116,121, -112,101,110,114, 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, 99, -101,110,116,120, 0, 99,101,110,116,121, 0, 42,116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, 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, -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, 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, 50, 53, 54, 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,114,101, -100,114, 97,119,115, 0, 42,105,100, 0, 97,115,112,101, 99,116, 0, 42, 99,117,114,102,111,110,116, 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,110,117,109,116,105, -108,101,115,120, 0,110,117,109,116,105,108,101,115,121, 0,118,105,101,119,114,101, 99,116, 0, 98,111,111,107,109, 97,114,107, -114,101, 99,116, 0,115, 99,114,111,108,108,112,111,115, 0,115, 99,114,111,108,108,104,101,105,103,104,116, 0,115, 99,114,111, -108,108, 97,114,101, 97, 0,114,101,116,118, 97,108, 0,112,114,118, 95,119, 0,112,114,118, 95,104, 0, 40, 42,114,101,116,117, -114,110,102,117,110, 99, 41, 40, 41, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99, 95,101,118,101,110,116, 41, 40, 41, 0, - 40, 42,114,101,116,117,114,110,102,117,110, 99, 95, 97,114,103,115, 41, 40, 41, 0, 42, 97,114,103, 49, 0, 42, 97,114,103, 50, - 0, 42,109,101,110,117,112, 0, 42,105,109,103, 0,108,101,110, 95, 97,108,108,111, 99, 0, 99,117,114,115,111,114, 0,114,112, -116, 95,109, 97,115,107, 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, 56, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 53, 54, 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,112, 97,100, 91, 49, 93, 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,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,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, 98,111,120, 0,119, 99,111,108, 95,115, 99,114,111,108,108, 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,105, 99,111,110,102,105,108,101, 91, 56, 48, 93, - 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, 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, 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,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,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,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,118,101,114,116,101,120, 95,115,105,122,101, 0, -102, 97, 99,101,100,111,116, 95,115,105,122,101, 0, 98,112, 97,100, 91, 50, 93, 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,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,104,112, 97,100, 91, 51, 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,115,110,100, 0,116, - 97, 99,116, 0,116,110,108, 97, 0,116,115,101,113, 0,116,105,109, 97, 0,116,105,109, 97,115,101,108, 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, 97,114,109, 91, 50, 48, - 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, 49, 54, 48, 93, 0,102,111,110,116,100,105,114, 91, 49, 54, 48, 93, 0,114,101,110,100,101,114,100,105,114, 91, 49, - 54, 48, 93, 0,116,101,120,116,117,100,105,114, 91, 49, 54, 48, 93, 0,112,108,117,103,116,101,120,100,105,114, 91, 49, 54, 48, - 93, 0,112,108,117,103,115,101,113,100,105,114, 91, 49, 54, 48, 93, 0,112,121,116,104,111,110,100,105,114, 91, 49, 54, 48, 93, - 0,115,111,117,110,100,100,105,114, 91, 49, 54, 48, 93, 0,121,102,101,120,112,111,114,116,100,105,114, 91, 49, 54, 48, 93, 0, -118,101,114,115,105,111,110,115, 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,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,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,119,109, -112, 97,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,110,100,111,102, 95,112, 97,110, 0,110,100,111,102, 95,114,111,116, 97,116,101, 0, 99,117,114,115,115,105,122, -101, 0,105,112,111, 95,110,101,119, 0,118,101,114,115,101,109, 97,115,116,101,114, 91, 49, 54, 48, 93, 0,118,101,114,115,101, -117,115,101,114, 91, 49, 54, 48, 93, 0,103,108, 97,108,112,104, 97, 99,108,105,112, 0, 97,117,116,111,107,101,121, 95,102,108, - 97,103, 0, 99,111, 98, 97, 95,119,101,105,103,104,116, 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,102,117,108,108, 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,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,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,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, 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,110, - 97,109,101, 91, 56, 48, 93, 0, 42,105, 98,117,102, 0, 42,105, 98,117,102, 95, 99,111,109,112, 0, 42,115,101, 49, 0, 42,115, -101, 50, 0, 42,115,101, 51, 0,110,114, 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,115, 97,116,117,114, - 97,116,105,111,110, 0,100,105,114, 91, 49, 54, 48, 93, 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,111,114,120, 0,111,114,121, 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,116,115,116,114, -105,112,100, 97,116, 97, 0, 42,116,115,116,114,105,112,100, 97,116, 97, 95,115,116, 97,114,116,115,116,105,108,108, 0, 42,116, -115,116,114,105,112,100, 97,116, 97, 95,101,110,100,115,116,105,108,108, 0, 42,105, 98,117,102, 95,115,116, 97,114,116,115,116, -105,108,108, 0, 42,105, 98,117,102, 95,101,110,100,115,116,105,108,108, 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,104, 97,110,100,115,105,122,101, 0, 97,110,105,109, 95,112,114, -101,115,101,101,107, 0, 42,115,116,114,105,112, 0,102, 97, 99,102, 48, 0,102, 97, 99,102, 49, 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,104,100, 97,117,100, -105,111, 0,108,101,118,101,108, 0,112, 97,110, 0,115, 99,101,110,101,110,114, 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, 50, 53, 54, 93, 0, 97, 99,116, 95, -115,111,117,110,100,100,105,114, 91, 50, 53, 54, 93, 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, 83, 99, 97,108,101,120, 70,105,110, 0, 83, 99, 97,108,101,121, 70,105,110, 0,120, 73,110,105, - 0,120, 70,105,110, 0,121, 73,110,105, 0,121, 70,105,110, 0,114,111,116, 73,110,105, 0,114,111,116, 70,105,110, 0,105,110, -116,101,114,112,111,108, 97,116,105,111,110, 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, 51, 50, 93, 0,118,103,114,111,117,112,110, 97,109,101, 95,118, 91, 51, 50, 93, 0, 42,107,101,121,115, - 0,109,105,110,102, 97, 99, 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, 51, 50, 93, 0,116,111,103,103,108,101, 78, 97,109,101, 91, 51, 50, 93, 0,118, - 97,108,117,101, 91, 51, 50, 93, 0,109, 97,120,118, 97,108,117,101, 91, 51, 50, 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, 51, 50, 93, 0,100, 97,109,112,116,105,109,101,114, 0, -112,114,111,112,110, 97,109,101, 91, 51, 50, 93, 0,109, 97,116,110, 97,109,101, 91, 51, 50, 93, 0, 97,120,105,115,102,108, 97, -103, 0, 42,102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 51, 50, 93, 0, 98,111,100,121, 91, 51, - 50, 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,109,111,100,117,108,101, 91, 54, 52, 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, 51, 50, 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,115,110,100,110,114, 0,112, 97,100, 49, 91, 50, 93, 0,109, 97,107,101, 99,111,112,121, 0, - 99,111,112,121,109, 97,100,101, 0,112, 97,100, 50, 91, 49, 93, 0,116,114, 97, 99,107, 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,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, 98,117,116,115,116, 97, 0, - 98,117,116,101,110,100, 0,109,105,110, 0,109, 97,120, 0,118,105,115,105,102, 97, 99, 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, 51, 50, 93, 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, 51, 50, 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,103,111, 0, - 97, 99, 99,101,108,108,101,114, 97,116,105,111,110, 0,109, 97,120,115,112,101,101,100, 0,109, 97,120,114,111,116,115,112,101, -101,100, 0,109, 97,120,116,105,108,116,115,112,101,101,100, 0,116,105,108,116,100, 97,109,112, 0,115,112,101,101,100,100, 97, -109,112, 0, 42,115, 97,109,112,108,101, 0, 42,115,116,114,101, 97,109, 0, 42,110,101,119,112, 97, 99,107,101,100,102,105,108, -101, 0, 42,115,110,100, 95,115,111,117,110,100, 0,112, 97,110,110,105,110,103, 0, 97,116,116,101,110,117, 97,116,105,111,110, - 0,112,105,116, 99,104, 0,109,105,110, 95,103, 97,105,110, 0,109, 97,120, 95,103, 97,105,110, 0,100,105,115,116, 97,110, 99, -101, 0,115,116,114,101, 97,109,108,101,110, 0, 99,104, 97,110,110,101,108,115, 0,104,105,103,104,112,114,105,111, 0,112, 97, -100, 91, 49, 48, 93, 0,103, 97,105,110, 0,100,111,112,112,108,101,114,102, 97, 99,116,111,114, 0,100,111,112,112,108,101,114, -118,101,108,111, 99,105,116,121, 0,110,117,109,115,111,117,110,100,115, 98,108,101,110,100,101,114, 0,110,117,109,115,111,117, -110,100,115,103, 97,109,101,101,110,103,105,110,101, 0, 42, 97,114,101, 97, 0, 42,108, 97,109,112,114,101,110, 0,103,111, 98, +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,104, 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,112, 97,100, 91, 50, 93, 0, +116,119,105,115,116, 95,115,109,111,111,116,104, 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, 98,112, 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,101,102,102,101, 99,116, 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,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,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, 97, 99,116, 95,102, 97, 99,101, + 0, 99,117, 98,101,109, 97,112,115,105,122,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, 42,109,114, 0, 42,112,118, 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,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,105,110,100,101,120, 0,102, 0,105, 0,115, 91, + 50, 53, 54, 93, 0,116,111,116,100,105,115,112, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0,118, 91, 52, 93, 0,109,105,100, + 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, 42,118,101,114,116, 95,109, 97,112, 0, 42,101,100,103,101, 95,109, 97,112, 0, 42,111,108,100, 95,102, 97, 99,101,115, + 0, 42,111,108,100, 95,101,100,103,101,115, 0, 42,101,114,114,111,114, 0,109,111,100,105,102,105,101,114, 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,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, 51, 50, 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, 42,116,101,120,116,117,114,101, 0,115,116, +114,101,110,103,116,104, 0,100,105,114,101, 99,116,105,111,110, 0,109,105,100,108,101,118,101,108, 0,116,101,120,109, 97,112, +112,105,110,103, 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, 51, 50, + 93, 0,117,118,108, 97,121,101,114, 95,116,109,112, 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,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, 51, 50, 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, 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,110,101,101,100, 98,105,110,100, 0, 42, 98,105,110,100,119,101,105,103,104,116,115, + 0, 42, 98,105,110,100, 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,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,115,121,115, 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, 42,117,110,100,111, 95,118,101,114,116,115, 0,117,110,100,111, 95,118,101,114,116,115, 95,116,111,116, + 0,117,110,100,111, 95,115,105,103,110, 97,108, 0,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, 51, 50, 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, +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, 51, 50, 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, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 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,114,111, +116, 91, 51, 93, 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, +108, 97,121, 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,105,112,111,119,105,110, 0,115, 99, 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0, 98,111,117, +110,100,116,121,112,101, 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,115,105,122,101,102, 97, 99, 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,100,116, 0,100,116,120, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0, +112, 97,100, 49, 91, 53, 93, 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,102,108,117,105,100,115,105,109, 70,108, 97,103, 0,114,101,115,116,114,105, 99, +116,102,108, 97,103, 0,115,104, 97,112,101,110,114, 0,115,104, 97,112,101,102,108, 97,103, 0,114,101, 99, 97,108, 99,111, 0, + 98,111,100,121, 95,116,121,112,101, 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,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, 99,117,114,105,110,100,101,120, 0, 97, 99,116,105,118,101, 0,100,101,102,108,101, 99,116, 0,102,111, +114, 99,101,102,105,101,108,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,102, + 95,115,116,114,101,110,103,116,104, 0,102, 95,112,111,119,101,114, 0,102, 95,100,105,115,116, 0,102, 95,100, 97,109,112, 0, +109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116, 0,109, 97,120,114, 97,100, 0,109,105,110,114, 97,100, 0,102, 95, +112,111,119,101,114, 95,114, 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,116,101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110, +107, 95, 97,120,105,115, 0,114,116, 50, 0, 42,114,110,103, 0,102, 95,110,111,105,115,101, 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,105,110,100,101,120, 95, 97,114,114, 97,121, 0, 42, +100, 97,116, 97, 91, 56, 93, 0, 42, 99,117,114, 91, 56, 93, 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,110, 97,109,101, 91, 54, 52, 93, 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, 50, 52, 48, 93, 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, 51, 50, 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, 51, 50, 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, 51, + 50, 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,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,120, 0,103, +114, 97,118,121, 0,103,114, 97,118,122, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69,110,100, 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, 83,117,114,102, 97, 99,101, 0, 42,109,101,115,104, + 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 50, 52, 48, 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, 83,117,114,102, 78,111,114,109, 97,108,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,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,104,111,114,107, 0, +122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,122,101,110,107, 0, 97,109, 98,107, 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,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, 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,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, 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, 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,102,102, 99,111,100,101, 99,100, 97,116, 97, 0, 97,117, +100,105,111, 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,114,116, 49, 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,119,105,110,112,111,115, 0,112,108, 97,110,101, +115, 0,105,109,116,121,112,101, 0,115,117, 98,105,109,116,121,112,101, 0,113,117, 97,108,105,116,121, 0,100,105,115,112,108, + 97,121,109,111,100,101, 0,114,112, 97,100, 49, 0,114,112, 97,100, 50, 0,115, 99,101,109,111,100,101, 0,114,101,110,100,101, +114,101,114, 0,111, 99,114,101,115, 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,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, 71, 73,113,117, 97,108,105,116,121, 0, 71, 73, 99, + 97, 99,104,101, 0, 71, 73,109,101,116,104,111,100, 0, 71, 73,112,104,111,116,111,110,115, 0, 71, 73,100,105,114,101, 99,116, + 0, 89, 70, 95, 65, 65, 0, 89, 70,101,120,112,111,114,116,120,109,108, 0, 89, 70, 95,110,111, 98,117,109,112, 0, 89, 70, 95, + 99,108, 97,109,112,114,103, 98, 0,121,102,112, 97,100, 49, 0, 71, 73,100,101,112,116,104, 0, 71, 73, 99, 97,117,115,100,101, +112,116,104, 0, 71, 73,112,105,120,101,108,115,112,101,114,115, 97,109,112,108,101, 0, 71, 73,112,104,111,116,111,110, 99,111, +117,110,116, 0, 71, 73,109,105,120,112,104,111,116,111,110,115, 0, 71, 73,112,104,111,116,111,110,114, 97,100,105,117,115, 0, + 89, 70, 95,114, 97,121,100,101,112,116,104, 0, 89, 70, 95, 65, 65,112, 97,115,115,101,115, 0, 89, 70, 95, 65, 65,115, 97,109, +112,108,101,115, 0,121,102,112, 97,100, 50, 0, 71, 73,115,104, 97,100,111,119,113,117, 97,108,105,116,121, 0, 71, 73,114,101, +102,105,110,101,109,101,110,116, 0, 71, 73,112,111,119,101,114, 0, 71, 73,105,110,100,105,114,112,111,119,101,114, 0, 89, 70, + 95,103, 97,109,109, 97, 0, 89, 70, 95,101,120,112,111,115,117,114,101, 0, 89, 70, 95,114, 97,121, 98,105, 97,115, 0, 89, 70, + 95, 65, 65,112,105,120,101,108,115,105,122,101, 0, 89, 70, 95, 65, 65,116,104,114,101,115,104,111,108,100, 0, 98, 97, 99,107, + 98,117,102, 91, 49, 54, 48, 93, 0,112,105, 99, 91, 49, 54, 48, 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, 49, 54, 48, 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,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,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,109, 97,116,109,111,100,101, 0,102,114, 97,109,105,110,103, 0,100,111, +109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0, 42, 42, 98,114,117,115,104,101,115, 0, 97, 99,116,105,118,101, 95, 98, +114,117,115,104, 95,105,110,100,101,120, 0, 98,114,117,115,104, 95, 99,111,117,110,116, 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,116, +111,111,108, 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, 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,110, 97,109,101, 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93, 91, 51, 93, 0,112, +105,118,111,116, 91, 51, 93, 0,116, 97, 98,108,101,116, 95,115,105,122,101, 0,116, 97, 98,108,101,116, 95,115,116,114,101,110, +103,116,104, 0,103, 97,109,109, 97, 0,109,117,108, 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, 42,118,112, 97,105,110,116, 0, 42,119,112, 97,105,110,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,112, 97,100, 91, 50, 93, 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,114,101, +116,111,112,111, 95,109,111,100,101, 0,114,101,116,111,112,111, 95,112, 97,105,110,116, 95,116,111,111,108, 0,108,105,110,101, + 95,100,105,118, 0,101,108,108,105,112,115,101, 95,100,105,118, 0,114,101,116,111,112,111, 95,104,111,116,115,112,111,116, 0, +109,117,108,116,105,114,101,115, 95,115,117, 98,100,105,118, 95,116,121,112,101, 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,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,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, 42, 99, 97,109, +101,114, 97, 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, 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,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0,115,111,117,110,100, 95,104, 97,110,100,108, +101,115, 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,106, +117,109,112,102,114, 97,109,101, 0,102,114, 97,109,101, 95,115,116,101,112, 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, 98,108,101,110,100, 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,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,118,105,101,119, + 98,117,116, 0,108, 97,115,116,109,111,100,101, 0,114,102,108, 97,103, 0,118,105,101,119,108,111, 99,107, 0,112,101,114,115, +112, 0,118,105,101,119, 0, 99,108,105,112, 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,116,111,112,111, 95,118,105,101,119, 95,100, 97,116, 97, 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,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,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,108, 97, +121, 95,117,115,101,100, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 0,111, 98, 95, 99,101,110,116, +114,101, 95, 98,111,110,101, 91, 51, 50, 93, 0,108, 97,121, 97, 99,116, 0,100,114, 97,119,116,121,112,101, 0,108,111, 99, 97, +108,118,105,101,119, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0,112,105,118,111,116, 95,108, 97,115, +116, 0,103,114,105,100, 0,103,114,105,100,118,105,101,119, 0,112, 97,100,102, 0,110,101, 97,114, 0,102, 97,114, 0,103,114, +105,100,108,105,110,101,115, 0,103,114,105,100,102,108, 97,103, 0,103,114,105,100,115,117, 98,100,105,118, 0,109,111,100,101, +115,101,108,101, 99,116, 0,107,101,121,102,108, 97,103,115, 0,116,119,116,121,112,101, 0,116,119,109,111,100,101, 0,116,119, +102,108, 97,103, 0,116,119,100,114, 97,119,102,108, 97,103, 0, 99,117,115,116,111,109,100, 97,116, 97, 95,109, 97,115,107, 0, + 97,102,116,101,114,100,114, 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 0,110,100,111,102,109,111,100,101, 0,110,100,111, +102,102,105,108,116,101,114, 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, 99,117,114,115,111,114, 91, 50, 93, 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, 42,115, 99,114,101,101,110, 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,112,105, +110, 0,108,111, 99,107, 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,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,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, 50, 52, 93, 0,100,105,114, 91, 50, 52, 48, 93, 0,102,105,108,101, + 91, 56, 48, 93, 0,114,101,110, 97,109,101,102,105,108,101, 91, 56, 48, 93, 0,115,111,114,116, 0,100,105,115,112,108, 97,121, + 0, 97, 99,116,105,118,101, 95, 98,111,111,107,109, 97,114,107, 0, 97, 99,116,105,118,101, 95,102,105,108,101, 0,115,101,108, +115,116, 97,116,101, 0,102, 95,102,112, 0,109,101,110,117, 0,102,112, 95,115,116,114, 91, 56, 93, 0, 42,112,117,112,109,101, +110,117, 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,108,111, 97,100,105,109, 97,103,101, 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,115,101, 97,114, 99,104, 95,102,108, 97,103, +115, 0,100,111, 95, 0,111,117,116,108,105,110,101,118,105,115, 0,115,116,111,114,101,102,108, 97,103, 0, 42, 99,117,109, 97, +112, 0,105,109, 97,110,114, 0, 99,117,114,116,105,108,101, 0,105,109,116,121,112,101,110,114, 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, 99,101,110,116,120, 0, 99,101,110,116,121, 0, 42, +116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, 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,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, 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, 50, 53, 54, 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,114,101,100,114, 97,119,115, 0, 42,105,100, 0, 97,115, +112,101, 99,116, 0, 42, 99,117,114,102,111,110,116, 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,110,117,109,116,105,108,101,115,120, 0,110,117,109,116,105,108,101, +115,121, 0,118,105,101,119,114,101, 99,116, 0, 98,111,111,107,109, 97,114,107,114,101, 99,116, 0,115, 99,114,111,108,108,112, +111,115, 0,115, 99,114,111,108,108,104,101,105,103,104,116, 0,115, 99,114,111,108,108, 97,114,101, 97, 0,114,101,116,118, 97, +108, 0,112,114,118, 95,119, 0,112,114,118, 95,104, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99, 41, 40, 41, 0, 40, 42, +114,101,116,117,114,110,102,117,110, 99, 95,101,118,101,110,116, 41, 40, 41, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99, + 95, 97,114,103,115, 41, 40, 41, 0, 42, 97,114,103, 49, 0, 42, 97,114,103, 50, 0, 42,109,101,110,117,112, 0, 42,105,109,103, + 0,108,101,110, 95, 97,108,108,111, 99, 0, 99,117,114,115,111,114, 0,114,112,116, 95,109, 97,115,107, 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, 56, 93, 0,102,105,108,101,110, 97,109,101, + 91, 50, 53, 54, 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,112, 97,100, 91, 49, 93, 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,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,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, 98,111, +120, 0,119, 99,111,108, 95,115, 99,114,111,108,108, 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,105, 99,111,110,102,105,108,101, 91, 56, 48, 93, 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, 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, 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,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,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,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,118,101,114,116,101,120, 95,115,105,122,101, 0,102, 97, 99,101,100,111,116, 95,115,105,122,101, + 0, 98,112, 97,100, 91, 50, 93, 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,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,104,112, 97, +100, 91, 51, 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,115,110,100, 0,116, 97, 99,116, 0,116,110,108, 97, 0,116,115,101, +113, 0,116,105,109, 97, 0,116,105,109, 97,115,101,108, 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, 97,114,109, 91, 50, 48, 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, 49, 54, 48, 93, 0,102,111,110,116,100,105,114, 91, 49, 54, 48, 93, 0,114,101,110,100,101,114,100,105,114, 91, 49, 54, 48, + 93, 0,116,101,120,116,117,100,105,114, 91, 49, 54, 48, 93, 0,112,108,117,103,116,101,120,100,105,114, 91, 49, 54, 48, 93, 0, +112,108,117,103,115,101,113,100,105,114, 91, 49, 54, 48, 93, 0,112,121,116,104,111,110,100,105,114, 91, 49, 54, 48, 93, 0,115, +111,117,110,100,100,105,114, 91, 49, 54, 48, 93, 0,121,102,101,120,112,111,114,116,100,105,114, 91, 49, 54, 48, 93, 0,118,101, +114,115,105,111,110,115, 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,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,119,109,112, 97,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,110,100,111,102, 95,112, 97,110, 0,110,100,111,102, 95, +114,111,116, 97,116,101, 0, 99,117,114,115,115,105,122,101, 0,105,112,111, 95,110,101,119, 0,118,101,114,115,101,109, 97,115, +116,101,114, 91, 49, 54, 48, 93, 0,118,101,114,115,101,117,115,101,114, 91, 49, 54, 48, 93, 0,103,108, 97,108,112,104, 97, 99, +108,105,112, 0, 99,111, 98, 97, 95,119,101,105,103,104,116, 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,102,117,108,108, 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,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,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,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, 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, +110, 97,109,101, 91, 56, 48, 93, 0, 42,105, 98,117,102, 0, 42,105, 98,117,102, 95, 99,111,109,112, 0, 42,115,101, 49, 0, 42, +115,101, 50, 0, 42,115,101, 51, 0,110,114, 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,115, 97,116,117, +114, 97,116,105,111,110, 0,100,105,114, 91, 49, 54, 48, 93, 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,111,114,120, 0,111,114,121, 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,116,115,116, +114,105,112,100, 97,116, 97, 0, 42,116,115,116,114,105,112,100, 97,116, 97, 95,115,116, 97,114,116,115,116,105,108,108, 0, 42, +116,115,116,114,105,112,100, 97,116, 97, 95,101,110,100,115,116,105,108,108, 0, 42,105, 98,117,102, 95,115,116, 97,114,116,115, +116,105,108,108, 0, 42,105, 98,117,102, 95,101,110,100,115,116,105,108,108, 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,104, 97,110,100,115,105,122,101, 0, 97,110,105,109, 95,112, +114,101,115,101,101,107, 0, 42,115,116,114,105,112, 0,102, 97, 99,102, 48, 0,102, 97, 99,102, 49, 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,111,117,110, +100, 95,104, 97,110,100,108,101, 0,108,101,118,101,108, 0,112, 97,110, 0,115, 99,101,110,101,110,114, 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, 50, 53, 54, + 93, 0, 97, 99,116, 95,115,111,117,110,100,100,105,114, 91, 50, 53, 54, 93, 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, 83, 99, 97,108,101,120, 70,105,110, 0, 83, 99, 97,108,101,121, 70,105, +110, 0,120, 73,110,105, 0,120, 70,105,110, 0,121, 73,110,105, 0,121, 70,105,110, 0,114,111,116, 73,110,105, 0,114,111,116, + 70,105,110, 0,105,110,116,101,114,112,111,108, 97,116,105,111,110, 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, 51, 50, 93, 0,118,103,114,111,117,112,110, 97,109,101, 95,118, 91, 51, 50, 93, + 0, 42,107,101,121,115, 0,109,105,110,102, 97, 99, 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, 51, 50, 93, 0,116,111,103,103,108,101, 78, 97,109,101, + 91, 51, 50, 93, 0,118, 97,108,117,101, 91, 51, 50, 93, 0,109, 97,120,118, 97,108,117,101, 91, 51, 50, 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, 51, 50, 93, 0,100, 97,109,112, +116,105,109,101,114, 0,112,114,111,112,110, 97,109,101, 91, 51, 50, 93, 0,109, 97,116,110, 97,109,101, 91, 51, 50, 93, 0, 97, +120,105,115,102,108, 97,103, 0, 42,102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 51, 50, 93, 0, + 98,111,100,121, 91, 51, 50, 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,109,111,100,117,108,101, 91, 54, 52, 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, 51, 50, 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,115,110,100,110,114, 0,112, 97,100, 49, 91, 50, 93, 0,112,105,116, + 99,104, 0,115,111,117,110,100, 51, 68, 0,109, 97,107,101, 99,111,112,121, 0, 99,111,112,121,109, 97,100,101, 0,112, 97,100, + 50, 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,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, 98,117,116,115,116, 97, 0, 98,117,116,101,110,100, 0,109,105,110, 0,109, 97,120, 0,118,105,115, +105,102, 97, 99, 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, 51, 50, 93, + 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, 51, 50, 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,103,111, 0, 97, 99, 99,101,108,108,101,114, 97,116,105,111,110, 0,109, 97,120,115, +112,101,101,100, 0,109, 97,120,114,111,116,115,112,101,101,100, 0,109, 97,120,116,105,108,116,115,112,101,101,100, 0,116,105, +108,116,100, 97,109,112, 0,115,112,101,101,100,100, 97,109,112, 0, 42,115,111,117,114, 99,101, 0,102,114, 97,109,101,115,107, +105,112, 0,109,117,116,101, 0, 99,104, 97,110,103,101,100, 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, 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, 97,114,101, 97, 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, 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, @@ -1879,321 +2013,347 @@ char datatoc_B_blend[]= { 98, 97,115,101, 0, 42,101,100, 98,111, 0, 42,115,107,101,116, 99,104, 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,114,111,112, 0, 99,111,110,115,116,102, -108, 97,103, 0,105,107,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120, - 0, 42, 98,111,110,101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0, 42, 98, 95, 98,111,110,101, 95,109, 97,116, -115, 0, 42,100,117, 97,108, 95,113,117, 97,116, 0, 42, 98, 95, 98,111,110,101, 95,100,117, 97,108, 95,113,117, 97,116,115, 0, -101,117,108, 91, 51, 93, 0,114,111,116,109,111,100,101, 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, 42, 99,117,115,116,111,109, 0, 99,104, - 97,110, 98, 97,115,101, 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, 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, 42,115,111,117,114, 99,101, 0,102,105,108,116,101, -114,102,108, 97,103, 0, 97,100,115, 0, 97, 99,116,110,114, 0, 97, 99,116,119,105,100,116,104, 0,116,105,109,101,115,108,105, -100,101, 0, 42,103,114,112, 0,116,101,109,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, 42,116, 97,114, 0,115,117, - 98,116, 97,114,103,101,116, 91, 51, 50, 93, 0,109, 97,116,114,105,120, 91, 52, 93, 91, 52, 93, 0,115,112, 97, 99,101, 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, 51, 50, 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,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,122,109,105,110, 0,122,109, 97,120, - 0,112, 97,100, 91, 57, 93, 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,115, 99, 97,108,101, 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, 42,110,101,119, 95,115,111, 99,107, 0,110,115, 0,108,105,109,105,116, 0,115,116, - 97, 99,107, 95,105,110,100,101,120, 0,105,110,116,101,114,110, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 95,101,120,116, - 0,108,111, 99,120, 0,108,111, 99,121, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, 95,105,110,100,101,120, 0, 42,116, -111,115,111, 99,107, 0, 42,108,105,110,107, 0, 42,110,101,119, 95,110,111,100,101, 0,117,115,101,114,110, 97,109,101, 91, 51, - 50, 93, 0,108, 97,115,116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97,103,101, 0,109,105,110,105,119,105, -100,116,104, 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,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,110,111,100,101,115, 0,108,105,110,107,115, 0, - 42,115,116, 97, 99,107, 0, 42,116,104,114,101, 97,100,115,116, 97, 99,107, 0,105,110,105,116, 0,115,116, 97, 99,107,115,105, -122,101, 0, 99,117,114, 95,105,110,100,101,120, 0, 97,108,108,116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0, 42, -115,101,108,105,110, 0, 42,115,101,108,111,117,116, 0, 40, 42,116,105,109,101, 99,117,114,115,111,114, 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,116, 99,104, 0, 42,115,100,104, 0, 99,121, 99,108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101, -115, 0,109,105,110,115,112,101,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, 99,117,114,118,101,100, 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, -105,116,101,114, 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,115, 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,120, 49, 0,120, 50, 0,121, 49, 0,121, 50, 0, 99,111,108,110, 97,109,101, 91, 51, - 50, 93, 0, 98,107,116,121,112,101, 0,114,111,116, 97,116,105,111,110, 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, 42,100,105, 99,116, 0, 42,110,111, -100,101, 0, 97,110,103,108,101, 95,111,102,115, 0, 99,111,108,109,111,100, 0,109,105,120, 0,116,104,114,101,115,104,111,108, -100, 0,102, 97,100,101, 0,109, 0, 99, 0,106,105,116, 0,112,114,111,106, 0,102,105,116, 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, 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,111,102,102,115,101,116, 91, 50, 93, - 0, 99,108,111,110,101, 0,105,110,110,101,114,114, 97,100,105,117,115, 0,114, 97,116,101, 0,114,103, 98, 91, 51, 93, 0,114, -111,116, 0,115, 99,117,108,112,116, 95,116,111,111,108, 0, 97, 99,116,105,118,101, 95,114,110,100, 0, 97, 99,116,105,118,101, + 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, 42,112,114,111,112, 0, 99,111,110,115,116,102,108, 97, +103, 0,105,107,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120, 0, 42, + 98,111,110,101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0, 42, 98, 95, 98,111,110,101, 95,109, 97,116,115, 0, + 42,100,117, 97,108, 95,113,117, 97,116, 0, 42, 98, 95, 98,111,110,101, 95,100,117, 97,108, 95,113,117, 97,116,115, 0,101,117, +108, 91, 51, 93, 0,114,111,116,109,111,100,101, 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, 42, 99,117,115,116,111,109, 0, 99,104, 97,110, + 98, 97,115,101, 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, 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,102,105,108,116,101,114, +102,108, 97,103, 0, 97,100,115, 0, 97, 99,116,110,114, 0, 97, 99,116,119,105,100,116,104, 0,116,105,109,101,115,108,105,100, +101, 0, 42,103,114,112, 0,116,101,109,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, 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, + 51, 50, 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,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,122,109,105,110, 0,122,109, 97,120, 0,112, 97,100, 91, 57, + 93, 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,115, 99, 97,108,101, 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, 42,110,101,119, 95,115,111, 99,107, 0,110,115, 0,108,105,109,105,116, 0,115,116, 97, 99,107, 95,105,110, +100,101,120, 0,105,110,116,101,114,110, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 95,101,120,116, 0,108,111, 99,120, 0, +108,111, 99,121, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, 95,105,110,100,101,120, 0, 42,116,111,115,111, 99,107, 0, + 42,108,105,110,107, 0, 42,110,101,119, 95,110,111,100,101, 0,117,115,101,114,110, 97,109,101, 91, 51, 50, 93, 0,108, 97,115, +116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97,103,101, 0,109,105,110,105,119,105,100,116,104, 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,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,110,111,100,101,115, 0,108,105,110,107,115, 0, 42,115,116, 97, 99,107, + 0, 42,116,104,114,101, 97,100,115,116, 97, 99,107, 0,105,110,105,116, 0,115,116, 97, 99,107,115,105,122,101, 0, 99,117,114, + 95,105,110,100,101,120, 0, 97,108,108,116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0, 42,115,101,108,105,110, 0, + 42,115,101,108,111,117,116, 0, 40, 42,116,105,109,101, 99,117,114,115,111,114, 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,116, 99, +104, 0, 42,115,100,104, 0, 99,121, 99,108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,115, 0,109,105,110,115, +112,101,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, 99,117,114, +118,101,100, 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,105,116,101,114, 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, +115, 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,120, 49, 0,120, 50, 0,121, 49, 0,121, 50, 0, 99,111,108,110, 97,109,101, 91, 51, 50, 93, 0, 98,107,116, +121,112,101, 0,114,111,116, 97,116,105,111,110, 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, 42,100,105, 99,116, 0, 42,110,111,100,101, 0, 97,110,103, +108,101, 95,111,102,115, 0, 99,111,108,109,111,100, 0,109,105,120, 0,116,104,114,101,115,104,111,108,100, 0,102, 97,100,101, + 0,109, 0, 99, 0,106,105,116, 0,112,114,111,106, 0,102,105,116, 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, 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,111,102,102,115,101,116, 91, 50, 93, 0, 99,108,111,110,101, + 0,105,110,110,101,114,114, 97,100,105,117,115, 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,116,111,111,108, 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,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,101,100,105,116,102, -108, 97,103, 0,118,101,108, 91, 51, 93, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 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,114, 97, -110,100, 91, 51, 93, 0, 42,115,116,105, 99,107, 95,111, 98, 0,112,114,101,118, 95,115,116, 97,116,101, 0, 42,104, 97,105,114, - 0, 42, 98,111,105,100, 0,114, 95,114,111,116, 91, 52, 93, 0,114, 95, 97,118,101, 91, 51, 93, 0,114, 95,118,101, 91, 51, 93, - 0,100,105,101,116,105,109,101, 0,115,105,122,101,109,117,108, 0,110,117,109, 95,100,109, 99, 97, 99,104,101, 0, 98,112,105, - 0, 97,108,105,118,101, 0,108,111,111,112, 0, 42, 98,111,105,100,115, 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,100,114, 97, -119, 95,115,116,101,112, 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,115,105,109,112, -108,105,102,121, 95,102,108, 97,103, 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,106,105,116,102, 97, 99, 0, -101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114,101,115, 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, 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,114,101, 97, 99,116,115,104, 97,112,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,100, 97,109,112,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,102, 97, 99, 0, 99,108,117,109,112,112,111,119, 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, 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, -101,102,102,101, 99,116,111,114, 95,119,101,105,103,104,116, 91, 49, 48, 93, 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,101,100,105,116, 0, 40, - 42,102,114,101,101, 95,101,100,105,116, 41, 40, 41, 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,116, 97,114,103,101,116, 95,111, 98, 0, 42,108, 97,116,116,105, 99,101, 0,101,102,102,101, 99,116,111,114, -115, 0,114,101, 97, 99,116,101,118,101,110,116,115, 0,116,114,101,101, 95,102,114, 97,109,101, 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, 51, 50, 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,116,114,101,101, 0, 42, 99, 97, 99,104,101, 0, 67,100,105,115, 0, 67,118, -105, 0, 91, 51, 93, 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,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,112,114,101,115,101,116,115, 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,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, 42,112,111,105,110,116,115, 0,116,111,116,112,111,105,110,116,115, - 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, 42,116,121,112,101,115, -116,114, 0, 42,109,101,115,115, 97,103,101, 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,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, -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,107,101,121,109, 97,112,115, 0, 42,103,104,111,115,116,119,105,110, 0, 42,110,101,119,115, 99, -114,101,101,110, 0,115, 99,114,101,101,110,110, 97,109,101, 91, 51, 50, 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, 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,116,105,109,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, 42,112,116,114, 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,112,114,111,112,118, 97,108,117,101, 0,105,110, 97, 99,116,105,118, -101, 0,109, 97,112,116,121,112,101, 0,107,101,121,109, 97,112, 0,110, 97,109,101,105,100, 91, 54, 52, 93, 0,115,112, 97, 99, -101,105,100, 0,114,101,103,105,111,110,105,100, 0,105,115, 95,109,111,100, 97,108, 0, 42,105,116,101,109,115, 0, 42, 99,117, -115,116,111,109,100, 97,116, 97, 0, 42,114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0,109,118, 97, -108, 91, 50, 93, 0,112,114,101,118,120, 0,112,114,101,118,121, 0,117,110,105, 99,111,100,101, 0, 97,115, 99,105,105, 0, 42, -107,101,121,109, 97,112, 95,105,100,110, 97,109,101, 0, 99,117,115,116,111,109, 0, 99,117,115,116,111,109,100, 97,116, 97,102, -114,101,101, 0, 42,101,100, 97,116, 97, 0,105,110,102,108,117,101,110, 99,101, 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, 42,114, -110, 97, 95,112, 97,116,104, 0, 97,114,114, 97,121, 95,105,110,100,101,120, 0,101,120,112,114,101,115,115,105,111,110, 91, 50, - 53, 54, 93, 0,118,101, 99, 91, 50, 93, 0, 42,102,112,116, 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,103,114,111,117,112, 91, 54, 52, 93, 0,105, -100,116,121,112,101, 0,116,101,109,112,108, 97,116,101,115, 0,103,114,111,117,112,109,111,100,101, 0,112, 97,116,104,115, 0, -107,101,121,105,110,103,102,108, 97,103, 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,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, 99, 99,117,114, 97, 99,121, 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, 0, 0, - 84, 89, 80, 69,168, 1, 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,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,105, 0,118,101, 99, 50,102, 0,118,101, 99, 50,100, 0,118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51, -100, 0,118,101, 99, 52,105, 0,118,101, 99, 52,102, 0,118,101, 99, 52,100, 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, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97,112,112,105,110, -103, 0, 76, 97,109,112, 0, 67,117,114,118,101, 77, 97,112,112,105,110,103, 0, 87, 97,118,101, 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, 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, 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, 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, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 0, 77, 68,101,102,111,114,109, 87, -101,105,103,104,116, 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111,112, 67,111,108, 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, 77, 68,105,115,112,115, - 0, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 32, 40, 49, 60, 60, 49, 41, 32, 35,100,101, -102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 32, 40, 49, 60, 60, 50, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, - 71, 79, 78, 32, 40, 49, 60, 60, 51, 41, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, - 82, 32, 40, 49, 60, 60, 53, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, 71, 69, 32, 40, 49, - 60, 60, 55, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 32, 40, 49, 60, 60, 56, 41, - 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 32, 40, 49, 60, 60, 57, 41, 32, 32, 32, 35,100,101,102,105, -110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 50, - 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, - 69, 95, 70, 76, 73, 80, 86, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 89, 32, 49, 54, 32, - 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 32, 51, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, - 80, 82, 79, 74, 89, 90, 32, 54, 52, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 32, 49, 32, 35,100,101, -102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 49, 32, 52, - 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 52, - 86, 49, 32, 56, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 32, 49, 32, 35,100,101,102,105,110, -101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 32, 50, 32, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 83, 69, -108, 32, 48, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, - 95, 70, 83, 69, 76, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, 49, 32, 32, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, - 76, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, - 70, 95, 83, 69, 76, 51, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 32, 51, 50, 32, 35,100,101, -102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 32, 54, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 89, 78, - 65, 77, 73, 67, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, 32, 50, 32, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, - 86, 69, 82, 84, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 32, 49, 54, 32, 35,100,101,102,105, -110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 73, - 76, 69, 83, 32, 49, 50, 56, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 32, 50, 53, - 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 32, 53, 49, 50, 32, 35,100,101,102,105,110,101, - 32, 84, 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 32, 49, 48, 50, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, - 67, 79, 76, 32, 50, 48, 52, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 32, 52, - 48, 57, 54, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 32, 56, 49, 57, 50, 32, 35,100,101,102, -105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 32, 49, 54, 51, 56, 52, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, - 83, 79, 76, 73, 68, 32, 48, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 32, 49, 32, 35,100,101,102,105,110,101, - 32, 84, 70, 95, 65, 76, 80, 72, 65, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80, 32, 52, 32, 32, 32, - 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 32, 51, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, - 82, 69, 67, 65, 84, 69, 68, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, - 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 32, 52, 32, 35,100,101, -102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, - 95, 80, 73, 78, 49, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 32, 51, 50, 32, 35,100,101,102, -105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 52, 32, 49, - 50, 56, 32, 35,101,110,100,105,102, 32, 32, 99,104, 97,114, 32,117,115,101, 95, 99,111,108, 44, 32,102,108, 97,103, 59, 10, 10, - 9, 47, 42, 32, 83,112,101, 99,105, 97,108, 32,108,101,118,101,108, 32, 49, 32,100, 97,116, 97, 32,116,104, 97,116, 32, 99, 97, -110,110,111,116, 32, 98,101, 32,109,111,100,105,102,105,101,100, 32,102,114,111,109, 32,111,116,104,101,114, 32,108,101,118,101, -108,115, 32, 42, 47, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,118,100, 97,116, 97, 59, 10, 9, 67,117,115,116,111,109, - 68, 97,116, 97, 32,102,100, 97,116, 97, 59, 10, 9,115,104,111,114,116, 32, 42,101,100,103,101, 95,102,108, 97,103,115, 59, 10, - 9, 99,104, 97,114, 32, 42,101,100,103,101, 95, 99,114,101, 97,115,101,115, 59, 10,125, 32, 77,117,108,116,105,114,101,115, 59, - 10, 10, 47, 42, 42, 32, 69,110,100, 32, 77,117,108,116,105,114,101,115, 32, 42, 42, 47, 10, 10,116,121,112,101,100,101,102, 32, -115,116,114,117, 99,116, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 32,123, 10, 9,117,110,115,105, -103,110,101,100, 32,105,110,116, 32, 42,118,101,114,116, 95,109, 97,112, 59, 32, 47, 42, 32,118,101,114,116, 95,109, 97,112, 91, - 79,108,100, 32, 73,110,100,101,120, 93, 61, 32, 78,101,119, 32, 73,110,100,101,120, 32, 42, 47, 10, 9,105,110,116, 32, 42,101, -100,103,101, 95,109, 97,112, 59, 32, 47, 42, 32,101,100,103,101, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, - 32, 78,101,119, 32, 73,110,100,101,120, 44, 32, 45, 49, 61, 32,104,105,100,100,101,110, 32, 42, 47, 10, 9, 77, 70, 97, 99,101, - 32, 42,111,108,100, 95,102, 97, 99,101,115, 59, 10, 9, 77, 69,100,103,101, 32, 42,111,108,100, 95,101,100,103,101,115, 59, 10, - 9,117,110,115,105,103,110,101,100, 32,105,110,116, 32,116,111,116,102, 97, 99,101, 44, 32,116,111,116,101,100,103,101, 44, 32, -116,111,116,118,101,114,116, 44, 32,112, 97,100, 59, 10,125, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116, -121, 59, 10, 10, 47, 42, 32,109,118,101,114,116, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 32, 42, 47, - 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 83, 84, 9, 50, 10, 35,100,101,102,105,110,101, - 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 77, 80, 9, 52, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 72, 73, 68, 69, - 9, 9, 9, 49, 54, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 69, 82, 84, 95, 77, 69, 82, 71, 69, 68, 9, 9, 40, 49, - 60, 60, 54, 41, 10, 10, 47, 42, 32,109,101,100,103,101, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 42, - 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 9, 9, 9, 40, 49, 60, 60, 49, 41, 10, 35, -100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 9, 9, 9, 9, 40, 49, 60, 60, 50, 41, 10, 35,100,101,102,105,110,101, - 32, 77, 69, 95, 70, 71, 79, 78, 9, 9, 9, 9, 40, 49, 60, 60, 51, 41, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,114,101,115,101, -114,118,101, 32, 49, 54, 32,102,111,114, 32, 77, 69, 95, 72, 73, 68, 69, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, - 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 9, 9, 40, 49, 60, 60, 53, 41, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, - 79, 79, 83, 69, 69, 68, 71, 69, 9, 9, 40, 49, 60, 60, 55, 41, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, - 95, 76, 65, 83, 84, 9, 9, 40, 49, 60, 60, 56, 41, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 9, 9, - 9, 40, 49, 60, 60, 57, 41, 10, 10, 47, 42, 32,112,117,110,111, 32, 61, 32,118,101,114,116,101,120,110,111,114,109, 97,108, 32, - 40,109,102, 97, 99,101, 41, 32, 42, 47, 10, 47, 42, 32,114,101,110,100,101,114, 32, 97,115,115,117,109,101,115, 32,102,108,105, -112,115, 32,116,111, 32, 98,101, 32,111,114,100,101,114,101,100, 32,108,105,107,101, 32,116,104,105,115, 32, 42, 47, 10, 35,100, -101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 9, 9, 49, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, - 73, 80, 86, 50, 9, 9, 50, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 9, 9, 52, 10, 35,100,101, -102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 9, 9, 56, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, - 74, 88, 89, 9, 9, 49, 54, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 9, 9, 51, 50, 10, 35,100, -101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 89, 90, 9, 9, 54, 52, 10, 10, 47, 42, 32,101,100, 99,111,100,101, 32, 40, -109,102, 97, 99,101, 41, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 9, 9, 9, 49, 10, 35,100, -101,102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 9, 9, 9, 50, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, - 49, 9, 9, 9, 52, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 9, 9, 9, 52, 10, 35,100,101,102,105,110, -101, 32, 77, 69, 95, 86, 52, 86, 49, 9, 9, 9, 56, 10, 10, 47, 42, 32,102,108, 97,103, 32, 40,109,102, 97, 99,101, 41, 32, 42, - 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 9, 9, 9, 49, 10, 35,100,101,102,105,110,101, 32, - 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 9, 9, 9, 50, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,102,108, 97,103, 32, 77, 69, - 95, 72, 73, 68, 69, 61, 61, 49, 54, 32,105,115, 32,117,115,101,100, 32,104,101,114,101, 32,116,111,111, 32, 42, 47, 32, 10, 47, - 42, 32,109,115,101,108,101, 99,116, 45, 62,116,121,112,101, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 83, - 69,108, 9, 48, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 10, 35,100,101,102,105,110,101, 32, 77, - 69, 95, 70, 83, 69, 76, 32, 50, 10, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,102,108, 97,103, 32, 42, 47, 10, 35,100,101, -102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 9, 49, 32, 47, 42, 32,117,115,101, 32, 77, 70, 97, 99,101, 32,104,105, -100,101, 32,102,108, 97,103, 32, 40, 97,102,116,101,114, 32, 50, 46, 52, 51, 41, 44, 32,115,104,111,117,108,100, 32, 98,101, 32, - 97, 98,108,101, 32,116,111, 32,114,101,117,115,101, 32, 97,102,116,101,114, 32, 50, 46, 52, 52, 32, 42, 47, 10, 35,100,101,102, -105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 9, 50, 32, 47, 42, 32,100,101,112,114,101, 99, 97,116,101,100, 33, 32, 42, - 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 9, 9, 52, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, - 83, 69, 76, 50, 9, 9, 56, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 51, 9, 9, 49, 54, 10, 35,100,101,102, -105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 9, 9, 51, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 9, - 9, 54, 52, 32, 47, 42, 32,117,110,117,115,101,100, 44, 32,115, 97,109,101, 32, 97,115, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, - 32, 42, 47, 10, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,109,111,100,101, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 9, 9, 49, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, - 82, 84, 9, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 9, 9, 9, 52, 10, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 83, 72, 65, 82, 69, 68, 86, 69, 82, 84, 9, 56, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, - 9, 9, 49, 54, 10, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 9, 54, 52, 10, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 84, 73, 76, 69, 83, 9, 9, 49, 50, 56, 9, 9, 47, 42, 32,100,101,112,114,101, 99, 97,116, -101,100, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 9, 50, 53, 54, 10, 35, -100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 9, 9, 53, 49, 50, 10, 35,100,101,102,105,110,101, 32, 84, - 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 9, 49, 48, 50, 52, 10, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, 67, - 79, 76, 9, 9, 50, 48, 52, 56, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 9, 52, - 48, 57, 54, 9, 47, 42, 32,119,105,116,104, 32, 90, 32, 97,120,105,115, 32, 99,111,110,115,116,114, 97,105,110,116, 32, 42, 47, - 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 9, 9, 56, 49, 57, 50, 10, 35,100,101,102,105,110,101, - 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 9, 9, 49, 54, 51, 56, 52, 10, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,116,114, - 97,110,115,112, 44, 32,118, 97,108,117,101,115, 32, 49, 45, 52, 32, 97,114,101, 32,117,115,101,100, 32, 97,115, 32,102,108, 97, -103,115, 32,105,110, 32,116,104,101, 32, 71, 76, 44, 32, 87, 65, 82, 78, 73, 78, 71, 44, 32, 84, 70, 95, 83, 85, 66, 32, 99, 97, -110,116, 32,119,111,114,107, 32,119,105,116,104, 32,116,104,105,115, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, - 83, 79, 76, 73, 68, 9, 48, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 9, 9, 49, 10, 35,100,101,102,105,110, -101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 9, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80, 9, 9, 52, 32, - 47, 42, 32, 99,108,105,112,109, 97,112, 32, 97,108,112,104, 97, 47, 98,105,110, 97,114,121, 32, 97,108,112,104, 97, 32, 97,108, -108, 32,111,114, 32,110,111,116,104,105,110,103, 33, 32, 42, 47, 10, 10, 47, 42, 32,115,117, 98, 32,105,115, 32,110,111,116, 32, - 97,118, 97,105,108, 97, 98,108,101, 32,105,110, 32,116,104,101, 32,117,115,101,114, 32,105,110,116,101,114,102, 97, 99,101, 32, - 97,110,121,109,111,114,101, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 9, 9, 51, 10, 10, 10, 47, - 42, 32,109,116,102, 97, 99,101, 45, 62,117,110,119,114, 97,112, 32, 42, 47, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, - 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 9, 49, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, - 69, 68, 50, 9, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 9, 52, 10, 35, -100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 9, 56, 10, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 80, 73, 78, 49, 9, 9, 32, 32, 32, 32, 49, 54, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 9, - 9, 32, 32, 32, 32, 51, 50, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 9, 32, 32, 32, 9, 9, 54, 52, 10, - 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 52, 9, 32, 32, 32, 32, 9, 49, 50, 56, 10, 10, 35,101,110,100,105,102, - 10,105,110, 79, 67, 75, 33,116, 95,102, 97, 99,101, 59, 32, 32, 32, 32, 32,129, 71, 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,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, 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, +108, 97,103, 0,118,101,108, 91, 51, 93, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 0, 42,103,114,111,117,110,100, + 0,103,114, 97,118,105,116,121, 91, 51, 93, 0,119, 97,110,100,101,114, 91, 51, 93, 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,114, 97,110,100, 91, + 51, 93, 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, 97,108,105,118,101, 0,108,111,111,112, 0,104, 97,105,114, 95,105,110, +100,101,120, 0, 42, 98,111,105,100,115, 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,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,115,105,109,112,108,105,102,121, 95,102,108, 97,103, 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,106,105,116,102, 97, 99, 0,101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114,101,115, 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, 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,114,101, 97, 99,116,115,104, 97,112,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,100, 97,109,112,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,102, 97, 99, 0, 99,108,117,109, +112,112,111,119, 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, 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,101,102,102,101, 99,116,111,114, 95,119,101,105,103,104,116, 91, 49, 48, + 93, 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,101,102,102,101, 99, +116,111,114,115, 0,114,101, 97, 99,116,101,118,101,110,116,115, 0,116,114,101,101, 95,102,114, 97,109,101, 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, 51, 50, 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,116,114,101,101, 0, 67,100,105,115, 0, 67,118,105, 0, 91, 51, + 93, 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,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,112,114,101, +115,101,116,115, 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,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, 42,116,121,112,101,115,116,114, 0, 42,109,101, +115,115, 97,103,101, 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,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,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,107,101,121,109, 97,112,115, 0, 42,103,104,111,115,116,119,105,110, 0, 42,110,101,119,115, 99,114,101,101,110, 0,115, + 99,114,101,101,110,110, 97,109,101, 91, 51, 50, 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, 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,116,105, +109,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, 42,112,116,114, 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,112,114,111,112,118, 97,108,117,101, 0,105,110, 97, 99,116,105,118,101, 0,109, 97,112,116, +121,112,101, 0,107,101,121,109, 97,112, 0,110, 97,109,101,105,100, 91, 54, 52, 93, 0,115,112, 97, 99,101,105,100, 0,114,101, +103,105,111,110,105,100, 0,105,115, 95,109,111,100, 97,108, 0, 42,105,116,101,109,115, 0, 42, 99,117,115,116,111,109,100, 97, +116, 97, 0, 42,114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0,109,118, 97,108, 91, 50, 93, 0,112, +114,101,118,120, 0,112,114,101,118,121, 0,117,110,105, 99,111,100,101, 0, 97,115, 99,105,105, 0, 42,107,101,121,109, 97,112, + 95,105,100,110, 97,109,101, 0, 99,117,115,116,111,109, 0, 99,117,115,116,111,109,100, 97,116, 97,102,114,101,101, 0, 42,101, +100, 97,116, 97, 0,105,110,102,108,117,101,110, 99,101, 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, 42,114,110, 97, 95,112, 97,116, +104, 0, 97,114,114, 97,121, 95,105,110,100,101,120, 0,101,120,112,114,101,115,115,105,111,110, 91, 50, 53, 54, 93, 0,118,101, + 99, 91, 50, 93, 0, 42,102,112,116, 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,103,114,111,117,112, 91, 54, 52, 93, 0,105,100,116,121,112,101, 0, +116,101,109,112,108, 97,116,101,115, 0,103,114,111,117,112,109,111,100,101, 0,112, 97,116,104,115, 0,107,101,121,105,110,103, +102,108, 97,103, 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, 99, 99,117,114, 97, 99,121, 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, 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, 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,118,101, +108,111, 99,105,116,121, 91, 51, 93, 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,110,117,109,112,111,105,110,116,115, 0, 0, 0, 0, 84, 89, 80, 69,182, 1, 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,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,105, 0,118,101, 99, 50,102, 0,118,101, 99, 50,100, 0, +118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51,100, 0,118,101, 99, 52,105, 0,118,101, 99, 52,102, 0,118,101, + 99, 52,100, 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, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, 86,111,120,101,108, 68, 97, +116, 97, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97,112,112,105,110,103, 0, 76, 97,109,112, 0, 67,117,114, +118,101, 77, 97,112,112,105,110,103, 0, 87, 97,118,101, 0, 86,111,108,117,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, 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, 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, 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, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 0, 77, 68,101, +102,111,114,109, 87,101,105,103,104,116, 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111, +112, 67,111,108, 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, 77, + 68,105,115,112,115, 0, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 32, 40, 49, 60, 60, 49, + 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 32, 40, 49, 60, 60, 50, 41, 32, 35,100,101,102,105,110,101, + 32, 77, 69, 95, 70, 71, 79, 78, 32, 40, 49, 60, 60, 51, 41, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, + 82, 69, 78, 68, 69, 82, 32, 40, 49, 60, 60, 53, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, + 71, 69, 32, 40, 49, 60, 60, 55, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 32, 40, + 49, 60, 60, 56, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 32, 40, 49, 60, 60, 57, 41, 32, 32, 32, + 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, + 76, 73, 80, 86, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 32, 52, 32, 35,100,101,102, +105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, + 89, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 32, 51, 50, 32, 35,100,101,102,105,110, +101, 32, 77, 69, 95, 80, 82, 79, 74, 89, 90, 32, 54, 52, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 32, + 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, + 51, 86, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 32, 52, 32, 35,100,101,102,105,110,101, 32, + 77, 69, 95, 86, 52, 86, 49, 32, 56, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 32, 49, 32, 35, +100,101,102,105,110,101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 32, 50, 32, 32, 32, 35,100,101,102,105,110,101, 32, 77, + 69, 95, 86, 83, 69,108, 32, 48, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 32, 35,100,101,102,105, +110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, + 49, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 83, 69, 76, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 32, 56, 32, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 83, 69, 76, 51, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 32, 51, + 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 32, 54, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 68, 89, 78, 65, 77, 73, 67, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, + 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, + 72, 65, 82, 69, 68, 86, 69, 82, 84, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 32, 49, 54, 32, + 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 84, 73, 76, 69, 83, 32, 49, 50, 56, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, + 82, 68, 32, 50, 53, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 32, 53, 49, 50, 32, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 32, 49, 48, 50, 52, 32, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 79, 66, 67, 79, 76, 32, 50, 48, 52, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, + 82, 68, 50, 32, 52, 48, 57, 54, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 32, 56, 49, 57, 50, + 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 32, 49, 54, 51, 56, 52, 32, 32, 35,100,101,102,105,110, +101, 32, 84, 70, 95, 83, 79, 76, 73, 68, 32, 48, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 32, 49, 32, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80, + 32, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 32, 51, 32, 32, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, + 67, 65, 84, 69, 68, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 32, + 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 32, 56, 32, 35,100,101,102,105, +110,101, 32, 84, 70, 95, 80, 73, 78, 49, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 32, 51, 50, + 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, + 73, 78, 52, 32, 49, 50, 56, 32, 35,101,110,100,105,102, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 59, 13, 10, 13, 10, +116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 77,117,108,116,105,114,101,115, 32,123, 13, 10, 9, 76,105,115,116, + 66, 97,115,101, 32,108,101,118,101,108,115, 59, 13, 10, 9, 77, 86,101,114,116, 32, 42,118,101,114,116,115, 59, 13, 10, 13, 10, + 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,108,101,118,101,108, 95, 99,111,117,110,116, 44, 32, 99,117,114,114, +101,110,116, 44, 32,110,101,119,108,118,108, 44, 32,101,100,103,101,108,118,108, 44, 32,112,105,110,108,118,108, 44, 32,114,101, +110,100,101,114,108,118,108, 59, 13, 10, 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,117,115,101, 95, 99,111,108, + 44, 32,102,108, 97,103, 59, 13, 10, 13, 10, 9, 47, 42, 32, 83,112,101, 99,105, 97,108, 32,108,101,118,101,108, 32, 49, 32,100, + 97,116, 97, 32,116,104, 97,116, 32, 99, 97,110,110,111,116, 32, 98,101, 32,109,111,100,105,102,105,101,100, 32,102,114,111,109, + 32,111,116,104,101,114, 32,108,101,118,101,108,115, 32, 42, 47, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,118,100, + 97,116, 97, 59, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,102,100, 97,116, 97, 59, 13, 10, 9,115,104,111,114,116, + 32, 42,101,100,103,101, 95,102,108, 97,103,115, 59, 13, 10, 9, 99,104, 97,114, 32, 42,101,100,103,101, 95, 99,114,101, 97,115, +101,115, 59, 13, 10,125, 32, 77,117,108,116,105,114,101,115, 59, 13, 10, 13, 10, 47, 42, 42, 32, 69,110,100, 32, 77,117,108,116, +105,114,101,115, 32, 42, 42, 47, 13, 10, 13, 10,116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 80, 97,114,116,105, + 97,108, 86,105,115,105, 98,105,108,105,116,121, 32,123, 13, 10, 9,117,110,115,105,103,110,101,100, 32,105,110,116, 32, 42,118, +101,114,116, 95,109, 97,112, 59, 32, 47, 42, 32,118,101,114,116, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, + 32, 78,101,119, 32, 73,110,100,101,120, 32, 42, 47, 13, 10, 9,105,110,116, 32, 42,101,100,103,101, 95,109, 97,112, 59, 32, 47, + 42, 32,101,100,103,101, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, 32, 78,101,119, 32, 73,110,100,101,120, + 44, 32, 45, 49, 61, 32,104,105,100,100,101,110, 32, 42, 47, 13, 10, 9, 77, 70, 97, 99,101, 32, 42,111,108,100, 95,102, 97, 99, +101,115, 59, 13, 10, 9, 77, 69,100,103,101, 32, 42,111,108,100, 95,101,100,103,101,115, 59, 13, 10, 9,117,110,115,105,103,110, +101,100, 32,105,110,116, 32,116,111,116,102, 97, 99,101, 44, 32,116,111,116,101,100,103,101, 44, 32,116,111,116,118,101,114,116, + 44, 32,112, 97,100, 59, 13, 10,125, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 59, 13, 10, 13, 10, + 47, 42, 32,109,118,101,114,116, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 32, 42, 47, 13, 10, 35,100, +101,102,105,110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 83, 84, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, + 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 77, 80, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 72, 73, 68, 69, 9, + 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 69, 82, 84, 95, 77, 69, 82, 71, 69, 68, 9, 9, 40, 49, + 60, 60, 54, 41, 13, 10, 13, 10, 47, 42, 32,109,101,100,103,101, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, + 41, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 9, 9, 9, 40, 49, 60, 60, 49, + 41, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 9, 9, 9, 9, 40, 49, 60, 60, 50, 41, 13, 10, 35,100, +101,102,105,110,101, 32, 77, 69, 95, 70, 71, 79, 78, 9, 9, 9, 9, 40, 49, 60, 60, 51, 41, 13, 10, 9, 9, 9, 9, 9, 9, 47, + 42, 32,114,101,115,101,114,118,101, 32, 49, 54, 32,102,111,114, 32, 77, 69, 95, 72, 73, 68, 69, 32, 42, 47, 13, 10, 35,100,101, +102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 9, 9, 40, 49, 60, 60, 53, 41, 13, 10, 35,100,101,102, +105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, 71, 69, 9, 9, 40, 49, 60, 60, 55, 41, 13, 10, 35,100,101,102,105,110, +101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 9, 9, 40, 49, 60, 60, 56, 41, 13, 10, 35,100,101,102,105,110,101, 32, + 77, 69, 95, 83, 72, 65, 82, 80, 9, 9, 9, 40, 49, 60, 60, 57, 41, 13, 10, 13, 10, 47, 42, 32,112,117,110,111, 32, 61, 32,118, +101,114,116,101,120,110,111,114,109, 97,108, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10, 47, 42, 32,114,101,110,100,101, +114, 32, 97,115,115,117,109,101,115, 32,102,108,105,112,115, 32,116,111, 32, 98,101, 32,111,114,100,101,114,101,100, 32,108,105, +107,101, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 9, 9, 49, + 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 50, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, + 77, 69, 95, 70, 76, 73, 80, 86, 51, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 9, + 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 89, 9, 9, 49, 54, 13, 10, 35,100,101,102,105, +110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 9, 9, 51, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, + 74, 89, 90, 9, 9, 54, 52, 13, 10, 13, 10, 47, 42, 32,101,100, 99,111,100,101, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, + 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, + 95, 86, 50, 86, 51, 9, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 49, 9, 9, 9, 52, 13, 10, + 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, + 86, 52, 86, 49, 9, 9, 9, 56, 13, 10, 13, 10, 47, 42, 32,102,108, 97,103, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10, + 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77, + 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 9, 9, 9, 50, 13, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,102,108, 97,103, 32, 77, 69, + 95, 72, 73, 68, 69, 61, 61, 49, 54, 32,105,115, 32,117,115,101,100, 32,104,101,114,101, 32,116,111,111, 32, 42, 47, 32, 13, 10, + 47, 42, 32,109,115,101,108,101, 99,116, 45, 62,116,121,112,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, + 86, 83, 69,108, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 13, 10, 35,100,101,102,105, +110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,102,108, 97,103, 32, + 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 9, 49, 32, 47, 42, 32,117,115,101, 32, 77, + 70, 97, 99,101, 32,104,105,100,101, 32,102,108, 97,103, 32, 40, 97,102,116,101,114, 32, 50, 46, 52, 51, 41, 44, 32,115,104,111, +117,108,100, 32, 98,101, 32, 97, 98,108,101, 32,116,111, 32,114,101,117,115,101, 32, 97,102,116,101,114, 32, 50, 46, 52, 52, 32, + 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 9, 50, 32, 47, 42, 32,100,101,112,114,101, + 99, 97,116,101,100, 33, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 9, 9, 52, 13, 10, 35, +100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 9, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, + 76, 51, 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 9, 9, 51, 50, 13, 10, 35,100,101, +102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 9, 9, 54, 52, 32, 47, 42, 32,117,110,117,115,101,100, 44, 32,115, 97,109,101, + 32, 97,115, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,109, +111,100,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 9, 9, 49, 13, 10, 35, +100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 84, 69, 88, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 86, 69, 82, 84, + 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 9, 9, 49, 54, 13, 10, 13, 10, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, + 84, 73, 76, 69, 83, 9, 9, 49, 50, 56, 9, 9, 47, 42, 32,100,101,112,114,101, 99, 97,116,101,100, 32, 42, 47, 13, 10, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 9, 50, 53, 54, 13, 10, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 9, 9, 53, 49, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73, + 83, 73, 66, 76, 69, 9, 49, 48, 50, 52, 13, 10, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, 67, 79, 76, 9, 9, + 50, 48, 52, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 9, 52, 48, 57, 54, + 9, 47, 42, 32,119,105,116,104, 32, 90, 32, 97,120,105,115, 32, 99,111,110,115,116,114, 97,105,110,116, 32, 42, 47, 13, 10, 35, +100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 9, 9, 56, 49, 57, 50, 13, 10, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 66, 77, 70, 79, 78, 84, 9, 9, 49, 54, 51, 56, 52, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,116, +114, 97,110,115,112, 44, 32,118, 97,108,117,101,115, 32, 49, 45, 52, 32, 97,114,101, 32,117,115,101,100, 32, 97,115, 32,102,108, + 97,103,115, 32,105,110, 32,116,104,101, 32, 71, 76, 44, 32, 87, 65, 82, 78, 73, 78, 71, 44, 32, 84, 70, 95, 83, 85, 66, 32, 99, + 97,110,116, 32,119,111,114,107, 32,119,105,116,104, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 83, 79, 76, 73, 68, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 9, 9, 49, 13, 10, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, + 80, 9, 9, 52, 32, 47, 42, 32, 99,108,105,112,109, 97,112, 32, 97,108,112,104, 97, 47, 98,105,110, 97,114,121, 32, 97,108,112, +104, 97, 32, 97,108,108, 32,111,114, 32,110,111,116,104,105,110,103, 33, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,115,117, 98, 32, +105,115, 32,110,111,116, 32, 97,118, 97,105,108, 97, 98,108,101, 32,105,110, 32,116,104,101, 32,117,115,101,114, 32,105,110,116, +101,114,102, 97, 99,101, 32, 97,110,121,109,111,114,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, + 66, 9, 9, 51, 13, 10, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,117,110,119,114, 97,112, 32, 42, 47, 13, 10, + 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 9, 49, 13, 10, 35,100,101,102,105,110, +101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 50, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, + 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, + 84, 69, 68, 52, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 49, 9, 9, 32, 32, 32, 32, 49, 54, 13, + 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 9, 9, 32, 32, 32, 32, 51, 50, 13, 10, 35,100,101,102,105,110, +101, 32, 84, 70, 95, 80, 73, 78, 51, 9, 32, 32, 32, 9, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, + 78, 52, 9, 32, 32, 32, 32, 9, 49, 50, 56, 13, 10, 13, 10, 35,101,110,100,105,102, 13, 10,104, 79, 67, 75, 33,109, 98,101,114, + 97, 2, 67, 3,191, 16, 8, 1,232, 80,100, 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,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, @@ -2206,749 +2366,778 @@ char datatoc_B_blend[]= { 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, 76, 97,116,116,105, 99,101, 0, 98, 68,101,102,111,114,109, 71,114, -111,117,112, 0, 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 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, 82, 78, 71, - 0, 80, 84, 67, 97, 99,104,101, 77,101,109, 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, 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, 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, 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, 71, 97,109,101, 68, 97,116, 97, - 0, 84,105,109,101, 77, 97,114,107,101,114, 0, 73,109, 97,103,101, 80, 97,105,110,116, 83,101,116,116,105,110,103,115, 0, 66, -114,117,115,104, 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, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110, - 0, 83, 99,117,108,112,116, 0, 83, 99,117,108,112,116, 83,101,115,115,105,111,110, 0, 86, 80, 97,105,110,116, 0, 84,111,111, -108, 83,101,116,116,105,110,103,115, 0, 98, 83,116, 97,116,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, 66, 71,112,105, 99, 0, 82,101,103,105,111,110, 86,105,101,119, 51, 68, - 0, 98, 71, 80,100, 97,116, 97, 0, 82,101,110,100,101,114, 73,110,102,111, 0, 82,101,116,111,112,111, 86,105,101,119, 68, 97, -116, 97, 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, 98, 83, 99,114,101,101,110, 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,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, 0, 83,112, 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103, -105, 99, 0, 83,112, 97, 99,101, 73,109, 97, 83,101,108, 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,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, 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, 83,111,108,105,100, 76,105,103,104,116, 0, 85,115,101,114, 68,101, -102, 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, 84, 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,104,100, 97,117,100,105,111, 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, 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, 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 98, 67, 68, 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, 70,114,101,101, 67, 97,109,101, -114, 97, 0, 98, 83, 97,109,112,108,101, 0, 98, 83,111,117,110,100, 76,105,115,116,101,110,101,114, 0, 83,112, 97, 99,101, 83, -111,117,110,100, 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, 80,111,115,101, 67,104, 97,110,110,101,108, 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, 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, 77,105,110, 77, 97,120, 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, 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, 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, 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, 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, 0, 98, 78,111,100,101, 80,114,101,118,105,101,119, 0, 98, 78,111,100,101, 84,121,112,101, 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, 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, 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, 72, 97,105,114, 75,101,121, 0, 80, 97,114,116,105, 99,108, -101, 75,101,121, 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, 97,116, 97, 0, 66,111,105,100, 68, 97,116, 97, 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, 69,100, -105,116, 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, 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, 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, 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,109, 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, 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, 68,114,105,118,101,114, 84, 97,114,103,101,116, 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, 84, 76, 69, 78, 1, 0, 1, 0, - 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 16, 0, 24, 0, 16, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, - 12, 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 32, 0, 96, 0, 72, 0, 72, 2, 0, 0, 40, 0,144, 0, 40, 4,112, 0, - 36, 0, 56, 0,112, 0,128, 0,168, 0, 88, 0, 40, 0, 48, 0,176, 0, 16, 0,152, 0, 40, 0,192, 5,184, 1, 0, 0, 0, 0, - 0, 0,144, 0, 88, 1,120, 1, 24, 0, 8, 3,200, 0, 0, 0,232, 0,136, 0,232, 1, 56, 1, 80, 0,224, 2,104, 0, 88, 1, - 0, 0,128, 0,104, 0,200, 0, 80, 0, 8, 0, 16, 0,200, 1, 0, 0, 0, 0, 0, 0,144, 1, 20, 0, 48, 0, 64, 0, 24, 0, - 12, 0, 16, 0, 4, 0, 8, 0, 8, 0, 0, 0, 32, 0,112, 0, 48, 0, 8, 0, 16, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1, - 32, 0, 16, 0, 0, 0, 16, 0, 64, 0, 24, 0, 12, 0, 64, 0, 72, 0, 96, 0,112, 0,120, 0, 88, 0,120, 0,152, 0, 88, 0, - 80, 0,128, 0, 80, 0,176, 0,216, 0, 80, 0,112, 0,128, 0,216, 0,128, 0,208, 0, 72, 0,112, 0, 0, 0,136, 0, 32, 0, -232, 1,152, 0, 0, 0,112, 0, 0, 0, 0, 0, 88, 0, 8, 0, 8, 0, 8, 1,104, 0,216, 1, 96, 0, 88, 0, 88, 0, 88, 0, -184, 1,136, 0,128, 0,232, 0, 48, 0,144, 0, 72, 0,120, 0,136, 0, 16, 1,224, 0, 0, 0, 40, 0, 16, 0, 0, 0, 0, 0, - 0, 0,216, 1, 40, 0,184, 0,152, 0, 56, 0, 16, 0, 88, 0, 24, 4, 64, 0, 24, 0, 16, 0, 88, 0, 88, 0, 24, 0, 40, 1, - 8, 0, 88, 0, 88, 0, 40, 0, 0, 0, 48, 0, 64, 1, 32, 0, 48, 2, 0, 0, 0, 0, 64, 0,248, 2,104, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 32, 1, 56, 0,152, 0, 72, 0,208, 0,240, 0, 32, 0, 0, 1,240, 0,128, 1,104, 0, 0, 0,144, 0, - 0, 0, 40, 1, 16, 0, 16, 0,168, 0,224, 0,144, 2,120, 2, 64, 0,200, 0, 32, 1, 72, 0,208, 2, 40, 0,112, 0, 24, 1, - 32, 0,232, 0, 32, 0, 32, 0, 80, 2, 16, 1, 16, 0,192, 20, 56, 0, 64, 11, 32, 0, 40, 0, 80, 1, 0, 0, 0, 0,160, 0, - 0, 0, 40, 1, 0, 0, 40, 0, 80, 0, 48, 0, 16, 0, 8, 0, 52, 0, 0, 1, 32, 1,200, 1, 8, 1, 72, 1, 0, 0, 32, 0, - 12, 0, 24, 0, 48, 0, 16, 0, 24, 0, 24, 0, 32, 0, 72, 1, 0, 0, 64, 0, 64, 0, 48, 0, 8, 0, 48, 0, 72, 0,104, 0, - 40, 0, 8, 0, 72, 0, 44, 0, 40, 0,108, 0, 72, 0, 96, 0,104, 0, 60, 0,128, 0, 80, 0, 80, 0, 16, 0, 96, 0, 32, 0, - 20, 0, 88, 0, 24, 0, 80, 0,112, 0, 84, 0, 32, 0, 96, 0, 64, 0, 56, 0,112, 0,140, 0, 4, 0, 24, 0, 16, 0, 8, 0, - 40, 0, 0, 0, 88, 0,224, 0, 40, 0, 24, 1,168, 0,232, 1,120, 0, 8, 1, 88, 0, 56, 0, 80, 0,128, 0, 80, 0,112, 0, - 56, 0, 48, 0, 48, 0, 72, 0, 48, 0, 72, 0, 48, 0, 24, 0, 56, 0,104, 0, 16, 0,112, 0, 96, 0, 28, 0, 28, 0, 28, 0, - 56, 0, 24, 0, 72, 0,168, 0, 40, 0,144, 0, 56, 0, 0, 1, 0, 0, 0, 0, 16, 0, 40, 0, 28, 0, 12, 0, 12, 0, 16, 1, - 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 16, 0, 24, 0, 32, 0, 8, 0, 32, 0, 12, 0, 56, 0, 24, 0, 72, 0, 24, 0, - 56, 0, 72, 0, 40, 0,248, 0, 20, 0, 8, 2,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 40, 0,192, 0, 40, 0, - 32, 0,224, 0,224, 0, 72, 0, 0, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,104, 0, 24, 0, 24, 0, 16, 0, 24, 0, 8, 0, - 16, 0, 24, 0, 20, 0,104, 0, 32, 1, 16, 0,104, 0, 0, 1, 40, 0,200, 0,104, 0,112, 0,104, 0, 32, 0, 80, 0, 56, 0, - 80, 0, 64, 0,104, 0, 72, 0, 64, 0,128, 0, 83, 84, 82, 67,112, 1, 0, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1, 0, - 11, 0, 3, 0, 11, 0, 0, 0, 11, 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0, 9, 0, 4, 0, 13, 0, 2, 0, - 2, 0, 5, 0, 2, 0, 6, 0, 14, 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, - 16, 0, 2, 0, 8, 0, 5, 0, 8, 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 18, 0, 3, 0, - 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 20, 0, 4, 0, - 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, - 7, 0, 8, 0, 22, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0, 23, 0, 4, 0, 4, 0, 9, 0, - 4, 0, 10, 0, 4, 0, 11, 0, 4, 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, - 25, 0, 4, 0, 9, 0, 13, 0, 12, 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0, 26, 0, 0, 0, 26, 0, 1, 0, - 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19, 0, 0, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0, 4, 0, 23, 0, 4, 0, 24, 0, - 27, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0, 2, 0, 28, 0, 2, 0, 19, 0, - 4, 0, 29, 0, 26, 0, 30, 0, 28, 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, - 4, 0, 36, 0, 4, 0, 37, 0, 28, 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, - 2, 0, 43, 0, 4, 0, 44, 0, 31, 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 17, 0, 2, 0, 19, 0, - 0, 0, 48, 0, 33, 0, 21, 0, 33, 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0, 24, 0, 51, 0, 24, 0, 52, 0, - 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0, 2, 0, 19, 0, 2, 0, 57, 0, - 7, 0, 11, 0, 7, 0, 12, 0, 4, 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0, 31, 0, 62, 0, 36, 0, 7, 0, - 27, 0, 31, 0, 12, 0, 63, 0, 24, 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0, 2, 0, 37, 0, 37, 0, 16, 0, - 37, 0, 0, 0, 37, 0, 1, 0, 7, 0, 67, 0, 7, 0, 61, 0, 2, 0, 17, 0, 2, 0, 47, 0, 2, 0, 68, 0, 2, 0, 19, 0, - 4, 0, 69, 0, 4, 0, 70, 0, 9, 0, 2, 0, 7, 0, 71, 0, 0, 0, 20, 0, 0, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0, - 38, 0, 13, 0, 27, 0, 31, 0, 39, 0, 75, 0, 37, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0, 7, 0, 61, 0, 12, 0, 79, 0, - 36, 0, 80, 0, 27, 0, 81, 0, 2, 0, 17, 0, 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 19, 0, 40, 0, 6, 0, 40, 0, 0, 0, - 40, 0, 1, 0, 0, 0, 84, 0, 0, 0, 85, 0, 4, 0, 23, 0, 4, 0, 86, 0, 41, 0, 10, 0, 41, 0, 0, 0, 41, 0, 1, 0, - 4, 0, 87, 0, 4, 0, 88, 0, 4, 0, 89, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, 0, 90, 0, 0, 0, 91, 0, 0, 0, 92, 0, - 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 93, 0, 4, 0, 90, 0, 4, 0, 94, 0, 12, 0, 95, 0, 40, 0, 96, 0, 40, 0, 97, 0, - 4, 0, 98, 0, 4, 0, 99, 0, 12, 0,100, 0, 0, 0,101, 0, 4, 0,102, 0, 4, 0,103, 0, 9, 0,104, 0, 8, 0,105, 0, - 43, 0, 3, 0, 4, 0,106, 0, 4, 0,107, 0, 9, 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 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, 2, 0,119, 0, 2, 0,120, 0, 7, 0,121, 0, 36, 0, 80, 0, - 32, 0,122, 0, 45, 0, 13, 0, 4, 0,123, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 2, 0,127, 0, 2, 0,128, 0, - 2, 0, 19, 0, 2, 0,129, 0, 2, 0,130, 0, 2, 0,131, 0, 2, 0,132, 0, 2, 0,133, 0, 46, 0,134, 0, 47, 0, 32, 0, - 27, 0, 31, 0, 0, 0, 34, 0, 12, 0,135, 0, 48, 0,136, 0, 49, 0,137, 0, 50, 0,138, 0, 2, 0,129, 0, 2, 0, 19, 0, - 2, 0,139, 0, 2, 0, 17, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, 0,140, 0, 2, 0,141, 0, 2, 0,142, 0, 2, 0,143, 0, - 2, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 4, 0,147, 0, 4, 0,148, 0, 43, 0,149, 0, 30, 0,150, 0, 0, 0,151, 0, - 7, 0,152, 0, 4, 0,153, 0, 2, 0,154, 0, 2, 0,155, 0, 2, 0,156, 0, 2, 0,157, 0, 7, 0,158, 0, 7, 0,159, 0, - 51, 0, 31, 0, 2, 0,160, 0, 2, 0,161, 0, 2, 0,162, 0, 2, 0,163, 0, 32, 0,164, 0, 52, 0,165, 0, 0, 0,166, 0, - 0, 0,167, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 7, 0,171, 0, 7, 0,172, 0, 2, 0,173, 0, 2, 0,174, 0, - 2, 0,175, 0, 2, 0,176, 0, 2, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 7, 0,180, 0, 7, 0,181, 0, 7, 0,182, 0, - 7, 0,183, 0, 7, 0,184, 0, 7, 0, 57, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0,187, 0, 7, 0,188, 0, 7, 0,189, 0, - 53, 0, 15, 0, 0, 0,190, 0, 9, 0,191, 0, 0, 0,192, 0, 0, 0,193, 0, 4, 0,194, 0, 4, 0,195, 0, 9, 0,196, 0, - 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, 4, 0,200, 0, 9, 0,201, 0, 9, 0,202, 0, 4, 0,203, 0, 4, 0, 37, 0, - 54, 0, 6, 0, 7, 0,180, 0, 7, 0,181, 0, 7, 0,182, 0, 7, 0,204, 0, 7, 0, 67, 0, 4, 0, 64, 0, 55, 0, 5, 0, - 2, 0, 19, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0,205, 0, 54, 0,199, 0, 56, 0, 17, 0, 32, 0,164, 0, 47, 0,206, 0, - 57, 0,207, 0, 7, 0,208, 0, 7, 0,209, 0, 2, 0, 17, 0, 2, 0,210, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,211, 0, - 4, 0,212, 0, 2, 0,213, 0, 2, 0,214, 0, 4, 0,129, 0, 4, 0,140, 0, 2, 0,215, 0, 2, 0,216, 0, 52, 0, 59, 0, - 27, 0, 31, 0, 39, 0, 75, 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, 7, 0,227, 0, 7, 0,228, 0, 7, 0,229, 0, 7, 0,230, 0, - 7, 0,231, 0, 7, 0,232, 0, 7, 0,233, 0, 7, 0,234, 0, 7, 0,235, 0, 7, 0,236, 0, 2, 0,237, 0, 2, 0,238, 0, - 2, 0,239, 0, 2, 0,240, 0, 2, 0,241, 0, 2, 0,242, 0, 2, 0,243, 0, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,210, 0, - 7, 0,244, 0, 7, 0,245, 0, 7, 0,246, 0, 7, 0,247, 0, 4, 0,248, 0, 4, 0,249, 0, 2, 0,250, 0, 2, 0,251, 0, - 2, 0,252, 0, 2, 0,127, 0, 4, 0, 23, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 7, 0,253, 0, 7, 0,254, 0, - 7, 0,186, 0, 45, 0,255, 0, 58, 0, 0, 1, 36, 0, 80, 0, 47, 0,206, 0, 53, 0, 1, 1, 55, 0, 2, 1, 56, 0, 3, 1, - 30, 0,150, 0, 0, 0, 4, 1, 0, 0, 5, 1, 59, 0, 8, 0, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0,172, 0, 4, 0, 19, 0, - 7, 0, 8, 1, 7, 0, 9, 1, 7, 0, 10, 1, 32, 0, 45, 0, 60, 0, 82, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 4, 0, 11, 1, 2, 0,174, 0, 2, 0, 12, 1, 7, 0,180, 0, 7, 0,181, 0, 7, 0,182, 0, 7, 0,183, 0, - 7, 0, 13, 1, 7, 0, 14, 1, 7, 0, 15, 1, 7, 0, 16, 1, 7, 0, 17, 1, 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1, - 7, 0, 21, 1, 7, 0, 22, 1, 7, 0, 23, 1, 61, 0, 24, 1, 2, 0, 25, 1, 2, 0, 70, 0, 7, 0,110, 0, 7, 0,111, 0, - 7, 0, 26, 1, 7, 0, 27, 1, 7, 0, 28, 1, 2, 0, 29, 1, 2, 0, 30, 1, 2, 0, 31, 1, 2, 0, 32, 1, 0, 0, 33, 1, - 0, 0, 34, 1, 2, 0, 35, 1, 2, 0, 36, 1, 2, 0, 37, 1, 2, 0, 38, 1, 2, 0, 39, 1, 7, 0, 40, 1, 7, 0, 41, 1, - 7, 0, 42, 1, 7, 0, 43, 1, 2, 0, 44, 1, 2, 0, 43, 0, 2, 0, 45, 1, 2, 0, 46, 1, 2, 0, 47, 1, 2, 0, 48, 1, - 7, 0, 49, 1, 7, 0, 50, 1, 7, 0, 51, 1, 7, 0, 52, 1, 7, 0, 53, 1, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, - 7, 0, 57, 1, 7, 0, 58, 1, 7, 0, 59, 1, 7, 0, 60, 1, 2, 0, 61, 1, 2, 0, 62, 1, 4, 0, 63, 1, 4, 0, 64, 1, - 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 67, 1, 2, 0, 68, 1, 7, 0, 69, 1, 7, 0, 70, 1, 7, 0, 71, 1, 7, 0, 72, 1, - 2, 0, 73, 1, 2, 0, 74, 1, 36, 0, 80, 0, 51, 0, 75, 1, 2, 0, 76, 1, 2, 0, 77, 1, 30, 0,150, 0, 62, 0, 2, 0, - 27, 0, 31, 0, 36, 0, 80, 0, 63, 0,129, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 78, 1, 2, 0, 19, 0, 7, 0,180, 0, - 7, 0,181, 0, 7, 0,182, 0, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1, 7, 0, 84, 1, - 7, 0, 85, 1, 7, 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 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, 7, 0,100, 1, - 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, - 0, 0,109, 1, 0, 0,110, 1, 7, 0,111, 1, 7, 0,112, 1, 2, 0,113, 1, 2, 0,114, 1, 7, 0,115, 1, 7, 0,116, 1, - 7, 0,117, 1, 7, 0,118, 1, 2, 0,119, 1, 2, 0,120, 1, 4, 0, 11, 1, 4, 0,121, 1, 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, 0, 0,136, 1, 7, 0,137, 1, 7, 0,138, 1, 7, 0,139, 1, - 4, 0,140, 1, 0, 0,141, 1, 0, 0, 45, 1, 0, 0,142, 1, 0, 0, 4, 1, 2, 0,143, 1, 2, 0,144, 1, 2, 0, 76, 1, - 2, 0,145, 1, 2, 0,146, 1, 2, 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,160, 0, 2, 0,161, 0, 55, 0,153, 1, 55, 0,154, 1, 0, 0,155, 1, 0, 0,156, 1, 0, 0,157, 1, 0, 0,158, 1, - 2, 0,159, 1, 2, 0,160, 1, 7, 0,161, 1, 7, 0,162, 1, 51, 0, 75, 1, 58, 0, 0, 1, 36, 0, 80, 0, 64, 0,163, 1, - 30, 0,150, 0, 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1, 7, 0,167, 1, 7, 0,168, 1, 2, 0,169, 1, 2, 0, 70, 0, - 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, 2, 0,179, 1, 2, 0,180, 1, 7, 0,181, 1, 7, 0,182, 1, 7, 0,183, 1, 7, 0,184, 1, 7, 0,185, 1, - 4, 0,186, 1, 4, 0,187, 1, 4, 0,188, 1, 12, 0,189, 1, 65, 0, 4, 0, 27, 0, 31, 0, 0, 0,190, 1, 66, 0, 2, 0, - 43, 0,149, 0, 67, 0, 26, 0, 67, 0, 0, 0, 67, 0, 1, 0, 68, 0,191, 1, 4, 0,192, 1, 4, 0,193, 1, 4, 0,194, 1, - 4, 0,195, 1, 4, 0,196, 1, 4, 0,197, 1, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,198, 1, 2, 0,199, 1, 7, 0, 5, 0, - 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,200, 1, 7, 0,201, 1, 7, 0,202, 1, 7, 0,203, 1, 7, 0,204, 1, 7, 0,205, 1, - 7, 0,206, 1, 7, 0, 23, 0, 7, 0,207, 1, 7, 0,208, 1, 69, 0, 17, 0, 27, 0, 31, 0, 68, 0,191, 1, 12, 0,209, 1, - 12, 0,210, 1, 12, 0,211, 1, 36, 0, 80, 0, 63, 0,212, 1, 2, 0, 19, 0, 2, 0,213, 1, 4, 0,173, 0, 7, 0, 6, 1, - 7, 0,172, 0, 7, 0, 7, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 67, 0,217, 1, 35, 0, 11, 0, 7, 0,218, 1, - 7, 0,219, 1, 7, 0,220, 1, 7, 0,221, 1, 2, 0, 55, 0, 0, 0,222, 1, 0, 0,223, 1, 0, 0,224, 1, 0, 0,225, 1, - 0, 0,226, 1, 0, 0,227, 1, 34, 0, 7, 0, 7, 0,228, 1, 7, 0,219, 1, 7, 0,220, 1, 2, 0,224, 1, 2, 0,227, 1, - 7, 0,221, 1, 7, 0, 37, 0, 70, 0, 21, 0, 70, 0, 0, 0, 70, 0, 1, 0, 2, 0, 17, 0, 2, 0,229, 1, 2, 0,227, 1, - 2, 0, 19, 0, 2, 0,230, 1, 2, 0,231, 1, 2, 0,232, 1, 2, 0,233, 1, 2, 0,234, 1, 2, 0,235, 1, 2, 0,236, 1, - 2, 0,237, 1, 7, 0,238, 1, 7, 0,239, 1, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0,240, 1, 2, 0,241, 1, 4, 0,242, 1, - 71, 0, 5, 0, 2, 0,243, 1, 2, 0,229, 1, 0, 0, 19, 0, 0, 0, 37, 0, 2, 0, 70, 0, 72, 0, 4, 0, 7, 0, 5, 0, - 7, 0, 6, 0, 7, 0, 8, 0, 7, 0,244, 1, 73, 0, 62, 0, 27, 0, 31, 0, 39, 0, 75, 0, 68, 0,191, 1, 12, 0,245, 1, - 12, 0,210, 1, 12, 0,246, 1, 32, 0,247, 1, 32, 0,248, 1, 32, 0,249, 1, 36, 0, 80, 0, 74, 0,250, 1, 38, 0,251, 1, - 63, 0,212, 1, 12, 0,252, 1, 7, 0, 6, 1, 7, 0,172, 0, 7, 0, 7, 1, 4, 0,173, 0, 2, 0,253, 1, 2, 0,213, 1, - 2, 0, 19, 0, 2, 0,254, 1, 7, 0,255, 1, 7, 0, 0, 2, 7, 0, 1, 2, 2, 0,232, 1, 2, 0,233, 1, 2, 0, 2, 2, - 2, 0, 3, 2, 4, 0, 4, 2, 34, 0, 5, 2, 2, 0, 23, 0, 2, 0, 95, 0, 2, 0, 67, 0, 2, 0, 6, 2, 7, 0, 7, 2, - 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 7, 0, 11, 2, 7, 0, 12, 2, 7, 0, 13, 2, 7, 0, 14, 2, 7, 0, 15, 2, - 7, 0, 16, 2, 0, 0, 17, 2, 75, 0, 18, 2, 76, 0, 19, 2, 0, 0, 20, 2, 65, 0, 21, 2, 65, 0, 22, 2, 65, 0, 23, 2, - 65, 0, 24, 2, 4, 0, 25, 2, 7, 0, 26, 2, 4, 0, 27, 2, 4, 0, 28, 2, 72, 0, 29, 2, 4, 0, 30, 2, 4, 0, 31, 2, - 71, 0, 32, 2, 71, 0, 33, 2, 77, 0, 39, 0, 27, 0, 31, 0, 68, 0,191, 1, 12, 0, 34, 2, 36, 0, 80, 0, 38, 0,251, 1, - 63, 0,212, 1, 78, 0, 35, 2, 79, 0, 36, 2, 80, 0, 37, 2, 81, 0, 38, 2, 82, 0, 39, 2, 83, 0, 40, 2, 84, 0, 41, 2, - 85, 0, 42, 2, 77, 0, 43, 2, 86, 0, 44, 2, 87, 0, 45, 2, 88, 0, 46, 2, 88, 0, 47, 2, 88, 0, 48, 2, 4, 0, 54, 0, - 4, 0, 49, 2, 4, 0, 50, 2, 4, 0, 51, 2, 4, 0, 52, 2, 4, 0,173, 0, 7, 0, 6, 1, 7, 0,172, 0, 7, 0, 7, 1, - 7, 0, 53, 2, 4, 0, 54, 2, 2, 0, 55, 2, 2, 0, 19, 0, 2, 0, 56, 2, 2, 0, 57, 2, 2, 0,213, 1, 2, 0, 58, 2, - 89, 0, 59, 2, 90, 0, 60, 2, 80, 0, 8, 0, 9, 0, 61, 2, 7, 0, 62, 2, 4, 0, 63, 2, 0, 0, 19, 0, 0, 0, 64, 2, - 2, 0, 11, 1, 2, 0, 65, 2, 2, 0, 66, 2, 78, 0, 7, 0, 4, 0, 67, 2, 4, 0, 68, 2, 4, 0, 69, 2, 4, 0, 70, 2, - 2, 0,229, 1, 0, 0, 71, 2, 0, 0, 19, 0, 82, 0, 5, 0, 4, 0, 67, 2, 4, 0, 68, 2, 0, 0, 72, 2, 0, 0, 73, 2, - 2, 0, 19, 0, 91, 0, 2, 0, 4, 0, 74, 2, 7, 0,220, 1, 83, 0, 3, 0, 91, 0, 75, 2, 4, 0, 76, 2, 4, 0, 19, 0, - 81, 0, 6, 0, 7, 0, 77, 2, 2, 0, 78, 2, 2, 0,229, 1, 0, 0, 19, 0, 0, 0, 73, 2, 0, 0,179, 0, 84, 0, 4, 0, - 0, 0,204, 0, 0, 0,180, 0, 0, 0,181, 0, 0, 0,182, 0, 92, 0, 6, 0, 47, 0, 61, 2, 0, 0, 19, 0, 0, 0, 64, 2, - 2, 0, 11, 1, 2, 0, 65, 2, 2, 0, 66, 2, 93, 0, 1, 0, 7, 0, 79, 2, 94, 0, 5, 0, 0, 0,204, 0, 0, 0,180, 0, - 0, 0,181, 0, 0, 0,182, 0, 4, 0, 37, 0, 85, 0, 1, 0, 7, 0, 80, 2, 86, 0, 2, 0, 4, 0, 81, 2, 4, 0, 17, 0, - 79, 0, 7, 0, 7, 0, 62, 2, 47, 0, 61, 2, 0, 0, 19, 0, 0, 0, 64, 2, 2, 0, 11, 1, 2, 0, 65, 2, 2, 0, 66, 2, - 95, 0, 1, 0, 7, 0, 82, 2, 96, 0, 1, 0, 4, 0, 83, 2, 97, 0, 1, 0, 0, 0, 84, 2, 98, 0, 1, 0, 7, 0, 62, 2, - 99, 0, 3, 0, 4, 0, 85, 2, 0, 0, 92, 0, 7, 0, 86, 2,101, 0, 4, 0, 7, 0,204, 0, 7, 0,180, 0, 7, 0,181, 0, - 7, 0,182, 0,102, 0, 1, 0,101, 0, 63, 2,103, 0, 5, 0, 4, 0, 87, 2, 4, 0, 88, 2, 0, 0, 19, 0, 0, 0,229, 1, - 0, 0,179, 0,104, 0, 2, 0, 4, 0, 89, 2, 4, 0, 88, 2,105, 0, 10, 0,105, 0, 0, 0,105, 0, 1, 0,103, 0, 90, 2, -102, 0, 91, 2,104, 0, 92, 2, 4, 0, 54, 0, 4, 0, 50, 2, 4, 0, 49, 2, 4, 0, 37, 0, 81, 0, 93, 2, 89, 0, 14, 0, - 12, 0, 94, 2, 81, 0, 93, 2, 0, 0, 95, 2, 0, 0, 96, 2, 0, 0, 97, 2, 0, 0, 98, 2, 0, 0, 99, 2, 0, 0,100, 2, - 0, 0,101, 2, 0, 0, 19, 0, 88, 0, 46, 2, 88, 0, 48, 2, 2, 0,102, 2, 0, 0,103, 2, 90, 0, 8, 0, 4, 0,104, 2, - 4, 0,105, 2, 78, 0,106, 2, 82, 0,107, 2, 4, 0, 50, 2, 4, 0, 49, 2, 4, 0, 54, 0, 4, 0, 37, 0,106, 0, 7, 0, -106, 0, 0, 0,106, 0, 1, 0, 4, 0, 17, 0, 4, 0, 11, 1, 0, 0, 20, 0, 46, 0,134, 0, 0, 0,108, 2,107, 0, 7, 0, -106, 0,109, 2, 2, 0,110, 2, 2, 0, 94, 2, 2, 0,111, 2, 2, 0, 90, 0, 9, 0,112, 2, 9, 0,113, 2,108, 0, 3, 0, -106, 0,109, 2, 32, 0,164, 0, 0, 0, 20, 0,109, 0, 5, 0,106, 0,109, 2, 32, 0,164, 0, 0, 0, 20, 0, 2, 0,114, 2, - 0, 0,115, 2,110, 0, 5, 0,106, 0,109, 2, 7, 0, 88, 0, 7, 0,116, 2, 4, 0,117, 2, 4, 0,118, 2,111, 0, 5, 0, -106, 0,109, 2, 32, 0,119, 2, 0, 0, 72, 0, 4, 0, 11, 1, 4, 0, 19, 0,112, 0, 13, 0,106, 0,109, 2, 32, 0,120, 2, - 32, 0,121, 2, 32, 0,122, 2, 32, 0,123, 2, 7, 0,124, 2, 7, 0,125, 2, 7, 0,116, 2, 7, 0,126, 2, 4, 0,127, 2, - 4, 0,128, 2, 4, 0, 90, 0, 4, 0,129, 2,113, 0, 5, 0,106, 0,109, 2, 2, 0,130, 2, 2, 0, 19, 0, 7, 0,131, 2, - 32, 0,132, 2,114, 0, 3, 0,106, 0,109, 2, 7, 0,133, 2, 4, 0, 90, 0,115, 0, 10, 0,106, 0,109, 2, 7, 0,134, 2, - 4, 0,135, 2, 4, 0, 37, 0, 2, 0, 90, 0, 2, 0,136, 2, 2, 0,137, 2, 2, 0,138, 2, 7, 0,139, 2, 0, 0,140, 2, -116, 0, 3, 0,106, 0,109, 2, 7, 0, 37, 0, 4, 0, 17, 0,117, 0, 11, 0,106, 0,109, 2, 52, 0,141, 2, 7, 0,142, 2, - 4, 0,143, 2, 0, 0,140, 2, 7, 0,144, 2, 4, 0,145, 2, 32, 0,146, 2, 0, 0,147, 2, 4, 0,148, 2, 4, 0, 37, 0, -118, 0, 10, 0,106, 0,109, 2, 32, 0,149, 2, 47, 0,150, 2, 4, 0, 90, 0, 4, 0,151, 2, 7, 0,152, 2, 7, 0,153, 2, - 0, 0,147, 2, 4, 0,148, 2, 4, 0, 37, 0,119, 0, 3, 0,106, 0,109, 2, 7, 0,154, 2, 4, 0,155, 2,120, 0, 5, 0, -106, 0,109, 2, 7, 0,156, 2, 0, 0,140, 2, 2, 0, 19, 0, 2, 0,157, 2,121, 0, 8, 0,106, 0,109, 2, 32, 0,164, 0, - 7, 0,156, 2, 7, 0,221, 1, 7, 0,106, 0, 0, 0,140, 2, 2, 0, 19, 0, 2, 0, 17, 0,122, 0, 21, 0,106, 0,109, 2, - 32, 0,158, 2, 0, 0,140, 2, 52, 0,141, 2, 32, 0,146, 2, 2, 0, 19, 0, 2, 0, 37, 0, 7, 0,159, 2, 7, 0,160, 2, - 7, 0,161, 2, 7, 0,255, 1, 7, 0,162, 2, 7, 0,163, 2, 7, 0,164, 2, 7, 0,165, 2, 4, 0,145, 2, 4, 0,148, 2, - 0, 0,147, 2, 7, 0,166, 2, 7, 0,167, 2, 7, 0, 43, 0,123, 0, 7, 0,106, 0,109, 2, 2, 0,168, 2, 2, 0,169, 2, - 4, 0, 70, 0, 32, 0,164, 0, 7, 0,170, 2, 0, 0,140, 2,124, 0, 9, 0,106, 0,109, 2, 32, 0,164, 0, 7, 0,171, 2, - 7, 0,172, 2, 7, 0,165, 2, 4, 0,173, 2, 4, 0,174, 2, 7, 0,175, 2, 0, 0, 20, 0,125, 0, 1, 0,106, 0,109, 2, -126, 0, 6, 0,106, 0,109, 2, 46, 0,134, 0,127, 0,176, 2,128, 0,177, 2,129, 0,178, 2,130, 0,179, 2,131, 0, 14, 0, -106, 0,109, 2, 81, 0,180, 2, 81, 0,181, 2, 81, 0,182, 2, 81, 0,183, 2, 81, 0,184, 2, 81, 0,185, 2, 78, 0,186, 2, - 4, 0,187, 2, 4, 0,188, 2, 2, 0,189, 2, 2, 0, 37, 0, 7, 0,190, 2,132, 0,191, 2,133, 0, 7, 0,106, 0,109, 2, - 81, 0,180, 2, 81, 0,192, 2,134, 0,193, 2,135, 0,191, 2, 4, 0,194, 2, 4, 0,187, 2,136, 0, 4, 0,106, 0,109, 2, - 32, 0,164, 0, 4, 0,195, 2, 4, 0, 37, 0,137, 0, 2, 0, 4, 0,196, 2, 7, 0,220, 1,138, 0, 2, 0, 4, 0,125, 0, - 4, 0,197, 2,139, 0, 20, 0,106, 0,109, 2, 32, 0,164, 0, 0, 0,140, 2, 2, 0,198, 2, 2, 0,199, 2, 2, 0, 19, 0, - 2, 0, 37, 0, 7, 0,200, 2, 7, 0,201, 2, 4, 0, 54, 0, 4, 0,202, 2,138, 0,203, 2,137, 0,204, 2, 4, 0,205, 2, - 4, 0,206, 2, 4, 0,207, 2, 4, 0,197, 2, 7, 0,208, 2, 7, 0,209, 2, 7, 0,210, 2,140, 0, 8, 0,106, 0,109, 2, -141, 0,211, 2,134, 0,193, 2, 4, 0,212, 2, 4, 0,213, 2, 4, 0,214, 2, 2, 0, 19, 0, 2, 0, 57, 0,142, 0, 8, 0, -106, 0,109, 2, 32, 0, 45, 0, 2, 0,215, 2, 2, 0, 19, 0, 2, 0,130, 2, 2, 0, 57, 0, 7, 0,216, 2, 7, 0,217, 2, -143, 0, 5, 0,106, 0,109, 2, 4, 0,218, 2, 2, 0, 19, 0, 2, 0,219, 2, 7, 0,220, 2,144, 0, 7, 0,106, 0,109, 2, - 81, 0,221, 2, 4, 0,222, 2, 0, 0,223, 2, 0, 0,224, 2, 0, 0,225, 2, 0, 0,226, 2,145, 0, 3, 0,106, 0,109, 2, -146, 0,227, 2,130, 0,179, 2,147, 0, 10, 0,106, 0,109, 2, 32, 0,228, 2, 32, 0,229, 2, 0, 0,230, 2, 7, 0,231, 2, - 2, 0,232, 2, 2, 0,233, 2, 0, 0,234, 2, 0, 0,235, 2, 0, 0,115, 2,148, 0, 9, 0,106, 0,109, 2, 32, 0,236, 2, - 0, 0,230, 2, 7, 0,237, 2, 7, 0,238, 2, 0, 0, 11, 1, 0, 0,130, 2, 0, 0,239, 2, 0, 0, 37, 0,149, 0, 27, 0, - 27, 0, 31, 0, 2, 0,230, 1, 2, 0,231, 1, 2, 0,240, 2, 2, 0, 19, 0, 2, 0,241, 2, 2, 0,242, 2, 2, 0,243, 2, - 2, 0, 70, 0, 0, 0,244, 2, 0, 0,245, 2, 0, 0,246, 2, 0, 0, 17, 0, 4, 0, 37, 0, 7, 0,247, 2, 7, 0,248, 2, - 7, 0,249, 2, 7, 0,250, 2, 7, 0,251, 2, 7, 0,252, 2, 34, 0,253, 2, 36, 0, 80, 0, 38, 0,251, 1, 83, 0, 40, 2, - 7, 0,254, 2, 7, 0,255, 2,149, 0, 0, 3,150, 0, 3, 0,150, 0, 0, 0,150, 0, 1, 0, 0, 0, 20, 0, 68, 0, 3, 0, - 7, 0, 1, 3, 4, 0, 19, 0, 4, 0, 37, 0, 32, 0,111, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 2, 3, - 4, 0, 3, 3, 4, 0, 4, 3, 4, 0, 5, 3, 0, 0, 6, 3, 32, 0, 38, 0, 32, 0, 7, 3, 32, 0, 8, 3, 32, 0, 9, 3, - 32, 0, 10, 3, 36, 0, 80, 0, 74, 0,250, 1, 68, 0,191, 1,151, 0, 11, 3,151, 0, 12, 3,152, 0, 13, 3, 9, 0, 2, 0, - 12, 0, 14, 3, 12, 0, 34, 2, 12, 0,210, 1, 12, 0, 15, 3, 12, 0, 16, 3, 63, 0,212, 1, 0, 0, 17, 3, 4, 0,213, 1, - 4, 0, 18, 3, 7, 0, 6, 1, 7, 0, 19, 3, 7, 0, 20, 3, 7, 0,172, 0, 7, 0, 21, 3, 7, 0, 7, 1, 7, 0, 22, 3, - 7, 0, 23, 3, 7, 0,171, 2, 7, 0, 24, 3, 7, 0,208, 0, 4, 0, 25, 3, 2, 0, 19, 0, 2, 0, 26, 3, 2, 0, 27, 3, - 2, 0, 28, 3, 2, 0, 29, 3, 2, 0, 30, 3, 2, 0, 31, 3, 2, 0, 32, 3, 2, 0, 33, 3, 2, 0, 34, 3, 2, 0, 35, 3, - 2, 0, 36, 3, 4, 0, 37, 3, 4, 0, 38, 3, 4, 0, 39, 3, 4, 0, 40, 3, 7, 0, 41, 3, 7, 0, 26, 2, 7, 0, 42, 3, - 7, 0, 43, 3, 7, 0, 44, 3, 7, 0, 45, 3, 7, 0, 46, 3, 7, 0, 47, 3, 7, 0, 48, 3, 7, 0, 49, 3, 7, 0, 50, 3, - 7, 0, 51, 3, 0, 0, 52, 3, 0, 0, 53, 3, 0, 0, 54, 3, 0, 0, 55, 3, 7, 0, 56, 3, 7, 0, 57, 3, 12, 0, 58, 3, - 12, 0, 59, 3, 12, 0, 60, 3, 12, 0, 61, 3, 7, 0, 62, 3, 2, 0, 81, 2, 2, 0, 63, 3, 7, 0, 63, 2, 4, 0, 64, 3, - 4, 0, 65, 3,153, 0, 66, 3, 2, 0, 67, 3, 2, 0,215, 0, 7, 0, 68, 3, 12, 0, 69, 3, 12, 0, 70, 3, 12, 0, 71, 3, - 12, 0, 72, 3,154, 0, 73, 3,155, 0, 74, 3, 64, 0, 75, 3, 2, 0, 76, 3, 2, 0, 77, 3, 2, 0, 78, 3, 2, 0, 79, 3, - 7, 0, 55, 2, 2, 0, 80, 3, 2, 0, 81, 3,146, 0, 82, 3,134, 0, 83, 3,134, 0, 84, 3, 4, 0, 85, 3, 4, 0, 86, 3, - 4, 0, 87, 3, 4, 0, 70, 0, 12, 0, 88, 3,156, 0, 14, 0,156, 0, 0, 0,156, 0, 1, 0, 32, 0, 38, 0, 7, 0,171, 2, - 7, 0, 8, 1, 7, 0,172, 2, 7, 0,165, 2, 0, 0, 20, 0, 4, 0,173, 2, 4, 0,174, 2, 4, 0, 89, 3, 2, 0, 17, 0, - 2, 0, 90, 3, 7, 0,175, 2,154, 0, 36, 0, 2, 0, 91, 3, 2, 0, 92, 3, 2, 0, 19, 0, 2, 0,165, 2, 7, 0, 93, 3, - 7, 0, 94, 3, 7, 0, 95, 3, 7, 0, 96, 3, 7, 0, 97, 3, 7, 0, 98, 3, 7, 0, 99, 3, 7, 0,100, 3, 7, 0,101, 3, - 7, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 7, 0,105, 3, 7, 0,106, 3, 7, 0,107, 3, 7, 0,108, 3, 7, 0,109, 3, - 7, 0,110, 3, 7, 0,111, 3, 7, 0,112, 3, 7, 0,113, 3, 7, 0,114, 3, 7, 0,115, 3, 7, 0,116, 3, 2, 0,117, 3, - 2, 0,118, 3, 2, 0,119, 3, 2, 0,120, 3, 52, 0,165, 0,157, 0,121, 3, 7, 0,122, 3, 4, 0,118, 2,158, 0, 6, 0, -158, 0, 0, 0,158, 0, 1, 0, 4, 0,123, 3, 4, 0,124, 3, 7, 0, 2, 0, 9, 0,125, 3,130, 0, 15, 0, 4, 0, 19, 0, - 4, 0,126, 3, 4, 0,127, 3, 4, 0,128, 3, 4, 0,129, 3, 4, 0,130, 3, 4, 0,131, 3, 4, 0,124, 3, 4, 0, 81, 2, - 4, 0, 57, 0, 0, 0,132, 3, 0, 0,133, 3, 0, 0,134, 3, 0, 0,135, 3, 12, 0,136, 3,159, 0, 1, 0, 7, 0,228, 1, -153, 0, 30, 0, 4, 0, 19, 0, 7, 0,137, 3, 7, 0,138, 3, 7, 0,139, 3, 4, 0,140, 3, 4, 0,141, 3, 4, 0,142, 3, - 4, 0,143, 3, 7, 0,144, 3, 7, 0,145, 3, 7, 0,146, 3, 7, 0,147, 3, 7, 0,148, 3, 7, 0,149, 3, 7, 0,150, 3, - 7, 0,151, 3, 7, 0,152, 3, 7, 0,153, 3, 7, 0,154, 3, 7, 0,155, 3, 7, 0,156, 3, 7, 0,157, 3, 7, 0,158, 3, - 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, 4, 0,162, 3, 4, 0,163, 3, 7, 0,164, 3, 7, 0, 48, 3,155, 0, 49, 0, -141, 0,165, 3, 4, 0,124, 3, 4, 0,166, 3,160, 0,167, 3,161, 0,168, 3, 0, 0, 37, 0, 0, 0,169, 3, 2, 0,170, 3, - 7, 0,171, 3, 0, 0,172, 3, 7, 0,173, 3, 7, 0,174, 3, 7, 0,175, 3, 7, 0,176, 3, 7, 0,177, 3, 7, 0,178, 3, - 7, 0,179, 3, 7, 0,180, 3, 7, 0,181, 3, 2, 0,182, 3, 0, 0,183, 3, 2, 0,184, 3, 7, 0,185, 3, 7, 0,186, 3, - 0, 0,187, 3, 4, 0,126, 0, 4, 0,188, 3, 4, 0,189, 3, 2, 0,190, 3, 2, 0,191, 3,159, 0,192, 3, 4, 0,193, 3, - 4, 0, 82, 0, 7, 0,194, 3, 7, 0,195, 3, 7, 0,196, 3, 7, 0,197, 3, 2, 0,198, 3, 2, 0,199, 3, 2, 0,200, 3, - 2, 0,201, 3, 2, 0,202, 3, 2, 0,203, 3, 2, 0,204, 3, 2, 0,205, 3,162, 0,206, 3, 7, 0,207, 3, 7, 0,208, 3, -130, 0,209, 3,146, 0, 48, 0, 2, 0, 17, 0, 2, 0,210, 3, 2, 0,211, 3, 2, 0,212, 3, 7, 0,213, 3, 2, 0,214, 3, - 2, 0,215, 3, 7, 0,216, 3, 2, 0,217, 3, 2, 0,218, 3, 7, 0,219, 3, 7, 0,220, 3, 7, 0,221, 3, 7, 0,222, 3, - 7, 0,223, 3, 7, 0,224, 3, 4, 0,225, 3, 7, 0,226, 3, 7, 0,227, 3, 7, 0,228, 3, 77, 0,229, 3, 77, 0,230, 3, - 77, 0,231, 3, 0, 0,232, 3, 7, 0,233, 3, 7, 0,234, 3, 36, 0, 80, 0, 2, 0,235, 3, 0, 0,236, 3, 0, 0,237, 3, - 7, 0,238, 3, 4, 0,239, 3, 7, 0,240, 3, 7, 0,241, 3, 4, 0,242, 3, 4, 0, 19, 0, 7, 0,243, 3, 7, 0,244, 3, - 7, 0,245, 3, 81, 0,246, 3, 7, 0,247, 3, 7, 0,248, 3, 7, 0,249, 3, 7, 0,250, 3, 7, 0,251, 3, 7, 0,252, 3, - 7, 0,253, 3, 4, 0,254, 3,163, 0, 73, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,174, 0, 2, 0, 12, 1, 2, 0, 45, 1, - 2, 0,255, 3, 7, 0, 0, 4, 7, 0, 1, 4, 7, 0, 2, 4, 7, 0, 3, 4, 7, 0, 4, 4, 7, 0, 5, 4, 7, 0, 6, 4, - 7, 0, 7, 4, 7, 0, 85, 1, 7, 0, 87, 1, 7, 0, 86, 1, 7, 0, 8, 4, 4, 0, 9, 4, 7, 0, 10, 4, 7, 0, 11, 4, - 7, 0, 12, 4, 7, 0, 13, 4, 7, 0, 14, 4, 7, 0, 15, 4, 7, 0, 16, 4, 2, 0, 17, 4, 2, 0, 11, 1, 2, 0, 18, 4, - 2, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 2, 0, 22, 4, 2, 0, 23, 4, 7, 0, 24, 4, 7, 0, 25, 4, 7, 0, 26, 4, - 7, 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, 2, 0, 36, 4, 2, 0, 37, 4, 2, 0, 38, 4, 2, 0, 39, 4, 7, 0, 40, 4, 7, 0, 41, 4, 7, 0, 42, 4, - 7, 0, 43, 4, 2, 0, 44, 4, 2, 0, 45, 4, 2, 0, 46, 4, 2, 0, 47, 4, 7, 0, 48, 4, 7, 0, 49, 4, 7, 0, 50, 4, - 7, 0, 51, 4, 2, 0, 52, 4, 2, 0, 53, 4, 2, 0, 54, 4, 2, 0, 19, 0, 7, 0, 55, 4, 7, 0, 56, 4, 36, 0, 80, 0, - 51, 0, 75, 1, 2, 0, 76, 1, 2, 0, 77, 1, 30, 0,150, 0,164, 0, 8, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0, 25, 3, - 4, 0, 57, 4, 4, 0, 19, 0, 2, 0, 58, 4, 2, 0, 59, 4, 32, 0,164, 0,165, 0, 13, 0, 9, 0, 60, 4, 9, 0, 61, 4, - 4, 0, 62, 4, 4, 0, 63, 4, 4, 0, 64, 4, 4, 0, 65, 4, 4, 0, 66, 4, 4, 0, 67, 4, 4, 0, 68, 4, 4, 0, 69, 4, - 4, 0, 70, 4, 4, 0, 37, 0, 0, 0, 71, 4,166, 0, 5, 0, 9, 0, 72, 4, 9, 0, 73, 4, 4, 0, 74, 4, 4, 0, 70, 0, - 0, 0, 75, 4,167, 0, 13, 0, 4, 0, 17, 0, 4, 0, 76, 4, 4, 0, 77, 4, 4, 0, 78, 4, 4, 0, 79, 4, 4, 0, 80, 4, - 4, 0, 90, 0, 4, 0, 81, 4, 4, 0, 82, 4, 4, 0, 83, 4, 4, 0, 84, 4, 4, 0, 85, 4, 26, 0, 30, 0,168, 0, 4, 0, - 4, 0, 86, 4, 7, 0, 87, 4, 2, 0, 19, 0, 2, 0, 77, 1,169, 0, 11, 0,169, 0, 0, 0,169, 0, 1, 0, 0, 0, 20, 0, - 63, 0, 88, 4, 64, 0, 89, 4, 4, 0, 25, 3, 4, 0, 90, 4, 4, 0, 91, 4, 4, 0, 37, 0, 4, 0, 92, 4, 4, 0, 93, 4, -170, 0,132, 0,165, 0, 94, 4,166, 0, 95, 4,167, 0, 96, 4,168, 0, 97, 4, 4, 0,194, 2, 4, 0,126, 0, 4, 0,188, 3, - 4, 0, 98, 4, 4, 0, 99, 4, 4, 0,100, 4, 4, 0,101, 4, 2, 0, 19, 0, 2, 0,102, 4, 7, 0, 26, 2, 7, 0,103, 4, - 7, 0,104, 4, 7, 0,105, 4, 7, 0,106, 4, 7, 0,107, 4, 2, 0,108, 4, 2, 0,109, 4, 2, 0,110, 4, 2, 0,111, 4, - 2, 0,214, 0, 2, 0,112, 4, 2, 0,113, 4, 2, 0,120, 3, 2, 0,114, 4, 2, 0,115, 4, 2, 0, 32, 1, 2, 0,106, 0, - 2, 0,116, 4, 2, 0,117, 4, 2, 0,118, 4, 2, 0,119, 4, 2, 0,120, 4, 2, 0,121, 4, 2, 0,122, 4, 2, 0,123, 4, - 2, 0,124, 4, 2, 0, 33, 1, 2, 0,125, 4, 2, 0,126, 4, 2, 0,127, 4, 2, 0,128, 4, 4, 0,129, 4, 4, 0, 11, 1, - 2, 0,130, 4, 2, 0,131, 4, 2, 0,132, 4, 2, 0,133, 4, 2, 0,134, 4, 2, 0,135, 4, 24, 0,136, 4, 24, 0,137, 4, - 23, 0,138, 4, 12, 0,139, 4, 2, 0,140, 4, 2, 0, 37, 0, 7, 0,141, 4, 7, 0,142, 4, 7, 0,143, 4, 7, 0,144, 4, - 4, 0,145, 4, 7, 0,146, 4, 7, 0,147, 4, 7, 0,148, 4, 7, 0,149, 4, 2, 0,150, 4, 2, 0,151, 4, 2, 0,152, 4, - 2, 0,153, 4, 2, 0,154, 4, 2, 0,155, 4, 7, 0,156, 4, 7, 0,157, 4, 7, 0,158, 4, 2, 0,159, 4, 2, 0,160, 4, - 2, 0,161, 4, 2, 0,162, 4, 2, 0,163, 4, 2, 0,164, 4, 2, 0,165, 4, 2, 0,166, 4, 2, 0,167, 4, 2, 0,168, 4, - 4, 0,169, 4, 4, 0,170, 4, 4, 0,171, 4, 4, 0,172, 4, 4, 0,173, 4, 7, 0,174, 4, 4, 0,175, 4, 4, 0,176, 4, - 4, 0,177, 4, 4, 0,178, 4, 7, 0,179, 4, 7, 0,180, 4, 7, 0,181, 4, 7, 0,182, 4, 7, 0,183, 4, 7, 0,184, 4, - 7, 0,185, 4, 7, 0,186, 4, 7, 0,187, 4, 0, 0,188, 4, 0, 0,189, 4, 4, 0,190, 4, 2, 0,191, 4, 2, 0,160, 1, - 0, 0,192, 4, 7, 0,193, 4, 7, 0,194, 4, 4, 0,195, 4, 4, 0,196, 4, 7, 0,197, 4, 7, 0,198, 4, 2, 0,199, 4, - 2, 0,200, 4, 7, 0,201, 4, 2, 0,202, 4, 2, 0,203, 4, 4, 0,204, 4, 2, 0,205, 4, 2, 0,206, 4, 2, 0,207, 4, - 2, 0,208, 4, 7, 0,209, 4, 7, 0, 70, 0, 42, 0,210, 4, 0, 0,211, 4,171, 0, 9, 0,171, 0, 0, 0,171, 0, 1, 0, - 0, 0, 20, 0, 2, 0,212, 4, 2, 0,213, 4, 2, 0,214, 4, 2, 0, 43, 0, 7, 0,215, 4, 7, 0, 70, 0,172, 0, 7, 0, - 2, 0,135, 2, 2, 0, 11, 1, 2, 0,109, 0, 2, 0,216, 4, 7, 0,217, 4, 7, 0, 70, 0, 42, 0,218, 4,173, 0, 5, 0, - 7, 0,219, 4, 0, 0, 17, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0,160, 1,174, 0, 24, 0, 7, 0, 15, 4, 7, 0, 16, 4, - 2, 0, 11, 1, 2, 0,220, 4, 2, 0, 18, 4, 2, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 2, 0, 22, 4, 2, 0, 23, 4, -173, 0,221, 4, 2, 0,108, 4, 2, 0,109, 4, 2, 0,110, 4, 2, 0,111, 4, 2, 0,214, 0, 2, 0,112, 4, 2, 0,113, 4, - 2, 0,120, 3,172, 0,222, 4, 2, 0,223, 4, 2, 0,114, 4, 2, 0,117, 4, 2, 0,118, 4,175, 0, 5, 0,175, 0, 0, 0, -175, 0, 1, 0, 4, 0,123, 3, 0, 0,132, 3, 4, 0, 19, 0,176, 0, 6, 0,177, 0,224, 4, 2, 0, 19, 0, 2, 0,225, 4, - 2, 0,226, 4, 2, 0,227, 4, 9, 0,228, 4,178, 0, 4, 0, 2, 0,106, 0, 2, 0,142, 2, 2, 0,126, 3, 2, 0,229, 4, -179, 0, 10, 0, 2, 0, 19, 0, 2, 0,230, 4, 2, 0,231, 4, 2, 0,232, 4,178, 0,233, 4, 9, 0,228, 4, 7, 0,234, 4, - 4, 0,235, 4, 4, 0,236, 4, 4, 0, 37, 0,180, 0, 4, 0,180, 0, 0, 0,180, 0, 1, 0, 0, 0,237, 4, 7, 0,238, 4, -181, 0, 8, 0,182, 0,239, 4,177, 0,224, 4, 7, 0,240, 4, 4, 0, 90, 0, 0, 0,241, 4, 0, 0,242, 4, 0, 0,243, 4, - 0, 0,244, 4,183, 0, 9, 0,177, 0,224, 4, 7, 0,245, 4, 7, 0,246, 4, 2, 0, 11, 1, 2, 0, 19, 0, 4, 0, 36, 0, - 4, 0,247, 4, 83, 0,248, 4, 9, 0,228, 4,184, 0, 72, 0,183, 0,249, 4,183, 0,250, 4,181, 0,251, 4, 7, 0,252, 4, - 2, 0,253, 4, 2, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 2, 0,126, 3, 2, 0, 1, 5, 7, 0, 2, 5, 7, 0, 3, 5, - 7, 0, 4, 5, 2, 0, 5, 5, 2, 0,236, 4, 2, 0, 6, 5, 2, 0, 7, 5, 2, 0, 8, 5, 2, 0, 9, 5, 7, 0, 10, 5, - 7, 0, 11, 5, 7, 0, 12, 5, 2, 0, 13, 5, 2, 0, 14, 5, 2, 0, 15, 5, 2, 0, 16, 5, 2, 0, 17, 5, 2, 0, 18, 5, - 2, 0, 19, 5,176, 0, 20, 5,179, 0, 21, 5, 7, 0, 22, 5, 7, 0, 23, 5, 7, 0, 24, 5, 2, 0, 25, 5, 2, 0, 70, 0, - 0, 0, 26, 5, 0, 0, 27, 5, 0, 0, 28, 5, 0, 0, 29, 5, 0, 0, 30, 5, 0, 0, 31, 5, 2, 0, 32, 5, 7, 0, 33, 5, - 7, 0, 34, 5, 7, 0, 35, 5, 7, 0, 36, 5, 7, 0, 37, 5, 7, 0, 38, 5, 7, 0, 39, 5, 7, 0, 40, 5, 7, 0, 41, 5, - 7, 0, 42, 5, 2, 0, 43, 5, 0, 0, 44, 5, 0, 0, 45, 5, 0, 0, 46, 5, 0, 0, 47, 5, 32, 0, 48, 5, 0, 0, 49, 5, - 0, 0, 50, 5, 0, 0, 51, 5, 0, 0, 52, 5, 0, 0, 53, 5, 0, 0, 54, 5, 0, 0, 55, 5, 0, 0, 56, 5, 2, 0, 57, 5, - 2, 0, 58, 5, 2, 0, 59, 5, 2, 0, 60, 5, 2, 0, 61, 5,185, 0, 8, 0, 4, 0, 62, 5, 4, 0, 63, 5, 4, 0, 64, 5, - 4, 0, 65, 5, 4, 0, 66, 5, 4, 0, 67, 5, 4, 0, 54, 0, 4, 0, 50, 2, 46, 0, 34, 0, 27, 0, 31, 0, 39, 0, 75, 0, - 32, 0, 68, 5,163, 0, 69, 5, 46, 0, 70, 5, 47, 0,206, 0, 12, 0, 71, 5,164, 0, 72, 5, 32, 0, 73, 5, 7, 0, 74, 5, - 7, 0, 75, 5, 7, 0, 76, 5, 7, 0, 77, 5, 4, 0, 25, 3, 2, 0, 19, 0, 2, 0, 4, 1, 58, 0, 0, 1,186, 0, 78, 5, -184, 0, 79, 5,187, 0, 80, 5,170, 0,180, 0,168, 0, 97, 4, 12, 0,100, 0, 12, 0, 81, 5,188, 0, 82, 5, 2, 0, 83, 5, - 2, 0, 84, 5, 2, 0,215, 0, 2, 0, 85, 5, 4, 0, 86, 5, 4, 0, 87, 5, 12, 0, 88, 5,173, 0,221, 4,174, 0, 89, 5, -189, 0, 6, 0, 47, 0,206, 0, 45, 0,255, 0, 7, 0, 14, 2, 7, 0, 15, 2, 7, 0,106, 0, 7, 0, 90, 5,190, 0, 35, 0, - 7, 0, 91, 5, 7, 0, 92, 5, 7, 0, 93, 5, 7, 0, 94, 5, 7, 0, 95, 5, 7, 0, 96, 5, 7, 0, 97, 5, 7, 0, 98, 5, - 7, 0, 99, 5, 7, 0, 18, 1, 7, 0,100, 5, 7, 0,101, 5, 7, 0,102, 5, 7, 0,103, 5, 7, 0,171, 0, 2, 0,104, 5, - 2, 0,105, 5, 4, 0,106, 5, 2, 0,107, 5, 2, 0,108, 5, 2, 0,109, 5, 2, 0,110, 5, 7, 0,111, 5, 68, 0,112, 5, -191, 0,113, 5,190, 0,114, 5,192, 0,115, 5,193, 0,116, 5,194, 0,117, 5,195, 0,118, 5,196, 0,119, 5, 7, 0,120, 5, - 2, 0,121, 5, 2, 0,122, 5, 4, 0,160, 1,197, 0, 54, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, - 7, 0,125, 5, 2, 0,126, 5, 7, 0, 99, 5, 7, 0, 18, 1, 7, 0, 43, 0, 4, 0,127, 5, 2, 0,109, 5, 2, 0,110, 5, - 32, 0, 68, 5, 32, 0,128, 5,189, 0,129, 5,197, 0,114, 5, 0, 0,130, 5, 4, 0, 25, 3, 4, 0,131, 5, 2, 0,132, 5, - 2, 0,133, 5, 2, 0,134, 5, 2, 0,135, 5, 2, 0,160, 1, 2, 0, 19, 0, 2, 0,136, 5, 2, 0,137, 5, 7, 0,112, 0, - 7, 0,138, 5, 7, 0,139, 5, 7, 0,140, 5, 7, 0,141, 5, 7, 0,142, 5, 7, 0,171, 0, 7, 0, 74, 5, 2, 0,143, 5, - 2, 0, 62, 1, 2, 0,144, 5, 2, 0,145, 5, 2, 0,146, 5, 2, 0,147, 5, 2, 0,148, 5, 2, 0,149, 5, 2, 0,150, 5, - 2, 0,151, 5, 4, 0,152, 5, 12, 0,153, 5, 2, 0,154, 5, 2, 0, 64, 2, 2, 0,155, 5, 0, 0,156, 5, 0, 0,157, 5, - 9, 0,158, 5,191, 0,113, 5,199, 0, 25, 0, 24, 0, 36, 0, 24, 0, 64, 0, 23, 0,159, 5, 23, 0,160, 5, 23, 0,161, 5, - 7, 0,162, 5, 7, 0,163, 5, 7, 0,164, 5, 7, 0,165, 5, 2, 0,166, 5, 2, 0,167, 5, 2, 0,168, 5, 2, 0,169, 5, - 2, 0,170, 5, 2, 0, 19, 0, 2, 0,171, 5, 2, 0,172, 5, 2, 0,173, 5, 2, 0,174, 5, 2, 0,175, 5, 2, 0,135, 5, - 7, 0,176, 5, 7, 0,177, 5, 4, 0,178, 5, 4, 0,179, 5,198, 0, 6, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, - 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,200, 0, 8, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, - 7, 0,125, 5, 2, 0,126, 5,201, 0,180, 5, 46, 0,134, 0,202, 0, 14, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, - 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,203, 0,182, 5, 12, 0,183, 5, 2, 0, 11, 1, 2, 0, 19, 0, - 2, 0,184, 5, 0, 0,185, 5, 0, 0,186, 5,204, 0, 20, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, - 7, 0,125, 5, 2, 0,126, 5,192, 0,115, 5,199, 0,181, 5, 2, 0,187, 5, 2, 0,188, 5, 2, 0,189, 5, 2, 0,190, 5, - 2, 0,171, 5, 2, 0,191, 5, 0, 0, 19, 0, 0, 0, 77, 1, 9, 0,250, 1, 4, 0,192, 5, 4, 0,193, 5, 27, 0,194, 5, -205, 0, 16, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5, - 7, 0, 14, 2, 7, 0, 15, 2, 2, 0,187, 5, 2, 0,195, 5, 2, 0,196, 5, 2, 0,197, 5, 4, 0, 19, 0, 7, 0,198, 5, -191, 0,113, 5,206, 0, 15, 0, 0, 0,199, 5, 0, 0,200, 5, 0, 0,201, 5, 2, 0, 19, 0, 2, 0,202, 5, 2, 0,203, 5, - 2, 0,103, 1, 2, 0,204, 5, 2, 0, 37, 0, 4, 0,205, 5, 4, 0,206, 5, 2, 0,207, 5, 2, 0,208, 5, 0, 0,209, 5, - 0, 0,210, 5,207, 0, 16, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 4, 0, 37, 0,206, 0,211, 5, -208, 0,212, 5, 12, 0,213, 5, 12, 0,214, 5,209, 0,215, 5,196, 0,216, 5,210, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5, - 2, 0,220, 5, 2, 0, 70, 0,211, 0, 17, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, - 2, 0,126, 5,199, 0,181, 5, 12, 0,221, 5,212, 0,222, 5, 0, 0,223, 5,213, 0,224, 5, 4, 0,225, 5, 4, 0,226, 5, - 2, 0, 19, 0, 2, 0,227, 5, 2, 0,228, 5, 2, 0, 37, 0,214, 0, 29, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, - 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, 47, 0,150, 2, 45, 0,255, 0, 61, 0,229, 5, 2, 0,133, 0, 2, 0,230, 5, - 2, 0, 70, 0, 2, 0,231, 5, 4, 0, 19, 0, 2, 0,232, 5, 2, 0,186, 5, 2, 0,185, 5, 2, 0,160, 1, 0, 0,233, 5, - 0, 0,234, 5, 0, 0,235, 5, 0, 0,135, 5, 7, 0, 14, 2, 7, 0, 15, 2, 7, 0,198, 5, 7, 0, 62, 1, 7, 0,236, 5, - 7, 0,237, 5,191, 0,113, 5,215, 0, 11, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, - 2, 0,126, 5, 2, 0,184, 5, 2, 0, 19, 0, 4, 0, 37, 0,203, 0,182, 5,199, 0,181, 5,216, 0, 27, 0,198, 0, 0, 0, -198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, 42, 0,238, 5, 4, 0,239, 5, 4, 0,240, 5, - 2, 0, 90, 0, 2, 0,133, 0, 2, 0,241, 5, 0, 0,242, 5, 0, 0,243, 5, 4, 0,244, 5, 4, 0,245, 5, 4, 0,246, 5, - 4, 0,247, 5, 2, 0,248, 5, 2, 0,249, 5, 7, 0,250, 5, 23, 0,251, 5, 23, 0,252, 5, 4, 0,253, 5, 4, 0,254, 5, - 0, 0,255, 5, 0, 0, 0, 6,217, 0, 10, 0, 27, 0, 31, 0, 9, 0, 1, 6, 9, 0, 2, 6, 9, 0, 3, 6, 9, 0, 4, 6, - 9, 0, 5, 6, 4, 0, 90, 0, 4, 0, 6, 6, 0, 0, 7, 6, 0, 0, 8, 6,218, 0, 10, 0,198, 0, 0, 0,198, 0, 1, 0, - 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,217, 0, 9, 6, 2, 0, 90, 0, 2, 0,133, 0, 4, 0, 43, 0, 9, 0, 10, 6, -219, 0, 8, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5,199, 0,181, 5, 4, 0, 19, 0, - 4, 0, 11, 6,220, 0, 23, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, -199, 0,181, 5, 27, 0, 12, 6, 27, 0, 81, 0, 2, 0, 19, 0, 2, 0,133, 0, 7, 0, 13, 6, 9, 0, 14, 6, 7, 0, 14, 2, - 7, 0, 15, 2, 7, 0, 15, 6, 7, 0, 16, 6, 58, 0, 0, 1, 58, 0, 17, 6, 4, 0, 18, 6, 2, 0, 19, 6, 2, 0, 37, 0, -191, 0,113, 5,221, 0, 10, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, - 2, 0, 19, 0, 2, 0, 34, 3, 4, 0, 37, 0,191, 0,113, 5,222, 0, 42, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, - 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,208, 0,212, 5, 0, 0,199, 5, 0, 0,200, 5, 0, 0,201, 5, - 2, 0, 17, 0, 2, 0,208, 5, 2, 0, 19, 0, 2, 0,202, 5, 9, 0, 14, 6, 4, 0,205, 5, 4, 0, 20, 6, 4, 0, 21, 6, - 4, 0,206, 5, 23, 0, 22, 6, 23, 0, 23, 6, 7, 0, 24, 6, 7, 0, 25, 6, 7, 0, 26, 6, 7, 0, 13, 6, 2, 0, 27, 6, - 2, 0,205, 0, 2, 0,103, 1, 2, 0,204, 5, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 28, 6, 2, 0, 29, 6, 9, 0, 30, 6, - 9, 0, 31, 6, 9, 0, 32, 6, 9, 0, 33, 6, 9, 0, 34, 6, 2, 0, 35, 6, 0, 0,210, 5, 57, 0, 36, 6,223, 0, 7, 0, -223, 0, 0, 0,223, 0, 1, 0, 4, 0, 37, 6, 4, 0, 23, 0, 0, 0, 84, 0, 4, 0, 38, 6, 4, 0, 17, 0,224, 0, 13, 0, -198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5, 4, 0, 17, 0, 4, 0, 39, 6, - 4, 0, 19, 0, 4, 0,241, 5, 12, 0, 40, 6, 12, 0, 41, 6, 0, 0, 42, 6,225, 0, 7, 0,225, 0, 0, 0,225, 0, 1, 0, - 0, 0, 43, 6, 2, 0, 44, 6, 2, 0, 45, 6, 2, 0, 46, 6, 2, 0, 37, 0,226, 0, 12, 0, 2, 0, 45, 6, 2, 0, 47, 6, - 2, 0, 48, 6, 0, 0,115, 2, 2, 0, 49, 6, 2, 0, 50, 6, 2, 0, 51, 6, 2, 0, 52, 6, 2, 0, 53, 6, 2, 0,171, 5, - 7, 0, 54, 6, 7, 0, 55, 6,227, 0, 18, 0,227, 0, 0, 0,227, 0, 1, 0, 0, 0,132, 3,226, 0, 56, 6,226, 0, 57, 6, -226, 0, 58, 6,226, 0, 59, 6, 7, 0, 60, 6, 2, 0, 61, 6, 2, 0, 62, 6, 2, 0, 63, 6, 2, 0, 64, 6, 2, 0, 65, 6, - 2, 0, 66, 6, 2, 0, 67, 6, 2, 0, 68, 6, 2, 0, 69, 6, 2, 0, 70, 6,228, 0, 10, 0, 0, 0, 71, 6, 0, 0, 72, 6, - 0, 0, 73, 6, 0, 0, 74, 6, 0, 0, 75, 6, 0, 0, 76, 6, 2, 0, 77, 6, 2, 0, 78, 6, 2, 0, 79, 6, 2, 0, 37, 0, -229, 0, 8, 0, 0, 0, 80, 6, 0, 0, 81, 6, 0, 0, 82, 6, 0, 0, 83, 6, 0, 0, 84, 6, 0, 0, 85, 6, 7, 0, 90, 5, - 7, 0, 37, 0,230, 0, 17, 0,228, 0, 86, 6,228, 0, 87, 6,228, 0, 88, 6,228, 0, 89, 6,228, 0, 90, 6,228, 0, 91, 6, -228, 0, 92, 6,228, 0, 93, 6,228, 0, 94, 6,228, 0, 95, 6,228, 0, 96, 6,228, 0, 97, 6,228, 0, 98, 6,228, 0, 99, 6, -228, 0,100, 6,229, 0,101, 6, 0, 0,102, 6,231, 0, 71, 0, 0, 0,103, 6, 0, 0,104, 6, 0, 0, 75, 6, 0, 0,105, 6, - 0, 0,106, 6, 0, 0,107, 6, 0, 0,108, 6, 0, 0,109, 6, 0, 0,110, 6, 0, 0,111, 6, 0, 0,112, 6, 0, 0,113, 6, - 0, 0,114, 6, 0, 0,115, 6, 0, 0,116, 6, 0, 0,117, 6, 0, 0,118, 6, 0, 0,119, 6, 0, 0,120, 6, 0, 0,121, 6, - 0, 0,122, 6, 0, 0,123, 6, 0, 0,124, 6, 0, 0,125, 6, 0, 0,126, 6, 0, 0,127, 6, 0, 0,128, 6, 0, 0,129, 6, - 0, 0,130, 6, 0, 0,131, 6, 0, 0,132, 6, 0, 0,133, 6, 0, 0,134, 6, 0, 0,135, 6, 0, 0,136, 6, 0, 0,137, 6, - 0, 0,138, 6, 0, 0,139, 6, 0, 0,140, 6, 0, 0,141, 6, 0, 0,142, 6, 0, 0,143, 6, 0, 0,144, 6, 0, 0,145, 6, - 0, 0,146, 6, 0, 0,147, 6, 0, 0,148, 6, 0, 0,149, 6, 0, 0,150, 6, 0, 0,151, 6, 0, 0,152, 6, 0, 0,153, 6, - 0, 0,154, 6, 0, 0,155, 6, 0, 0,156, 6, 0, 0,157, 6, 0, 0,158, 6, 0, 0,159, 6, 0, 0,160, 6, 0, 0,161, 6, - 0, 0,162, 6, 0, 0,163, 6, 0, 0,164, 6, 0, 0,165, 6, 0, 0,166, 6, 0, 0,167, 6, 0, 0,168, 6, 0, 0,169, 6, - 0, 0,170, 6, 0, 0,171, 6, 0, 0, 92, 0,232, 0, 5, 0, 0, 0,172, 6, 0, 0,127, 6, 0, 0,129, 6, 2, 0, 19, 0, - 2, 0, 37, 0,233, 0, 21, 0,233, 0, 0, 0,233, 0, 1, 0, 0, 0, 20, 0,230, 0,173, 6,231, 0,174, 6,231, 0,175, 6, -231, 0,176, 6,231, 0,177, 6,231, 0,178, 6,231, 0,179, 6,231, 0,180, 6,231, 0,181, 6,231, 0,182, 6,231, 0,183, 6, -231, 0,184, 6,231, 0,185, 6,231, 0,186, 6,231, 0,187, 6,231, 0,188, 6,231, 0,189, 6,232, 0,190, 6,234, 0, 5, 0, - 4, 0, 19, 0, 4, 0, 37, 0, 7, 0, 63, 2, 7, 0,191, 6, 7, 0,228, 1,235, 0, 67, 0, 4, 0, 19, 0, 4, 0,192, 6, - 4, 0,193, 6, 0, 0,194, 6, 0, 0,195, 6, 0, 0,196, 6, 0, 0,197, 6, 0, 0,198, 6, 0, 0,199, 6, 0, 0,200, 6, - 0, 0,201, 6, 0, 0,202, 6, 2, 0,203, 6, 2, 0, 37, 0, 4, 0,204, 6, 4, 0,205, 6, 4, 0,206, 6, 4, 0,207, 6, - 2, 0,208, 6, 2, 0,209, 6, 4, 0,210, 6, 4, 0, 40, 6, 4, 0,211, 6, 2, 0,212, 6, 2, 0,213, 6, 2, 0,214, 6, - 2, 0,215, 6, 12, 0,216, 6, 12, 0,217, 6, 12, 0,218, 6, 2, 0,219, 6, 2, 0,220, 6, 2, 0,221, 6, 2, 0,222, 6, - 2, 0,223, 6, 2, 0,224, 6, 2, 0,225, 6, 2, 0,226, 6,234, 0,227, 6, 2, 0,228, 6, 2, 0,229, 6, 2, 0,230, 6, - 2, 0,231, 6, 2, 0,232, 6, 2, 0,233, 6, 2, 0,234, 6, 2, 0,235, 6, 4, 0,236, 6, 4, 0,237, 6, 2, 0,238, 6, - 2, 0,239, 6, 2, 0,240, 6, 2, 0,241, 6, 2, 0,242, 6, 2, 0,243, 6, 2, 0,244, 6, 2, 0,245, 6, 2, 0,246, 6, - 2, 0,247, 6, 2, 0,248, 6, 2, 0,249, 6, 0, 0,250, 6, 0, 0,251, 6, 7, 0,252, 6, 2, 0, 25, 5, 2, 0,253, 6, - 55, 0,254, 6,201, 0, 21, 0, 27, 0, 31, 0, 12, 0,255, 6, 12, 0, 0, 7, 12, 0, 1, 7, 12, 0,123, 5, 46, 0,134, 0, - 46, 0, 2, 7, 2, 0, 3, 7, 2, 0, 4, 7, 2, 0, 5, 7, 2, 0, 6, 7, 2, 0, 7, 7, 2, 0, 8, 7, 2, 0, 9, 7, - 2, 0, 37, 0, 2, 0, 10, 7, 2, 0, 11, 7, 4, 0, 70, 0,196, 0, 12, 7, 9, 0, 13, 7, 2, 0, 14, 7,236, 0, 5, 0, -236, 0, 0, 0,236, 0, 1, 0,236, 0, 15, 7, 13, 0, 16, 7, 4, 0, 19, 0,237, 0, 7, 0,237, 0, 0, 0,237, 0, 1, 0, -236, 0, 17, 7,236, 0, 18, 7, 2, 0,137, 4, 2, 0, 19, 0, 4, 0, 37, 0,238, 0, 23, 0,238, 0, 0, 0,238, 0, 1, 0, -239, 0, 19, 7,240, 0,217, 5, 0, 0, 20, 7, 0, 0, 21, 7, 0, 0, 22, 7, 2, 0, 23, 7, 2, 0, 24, 7, 2, 0, 25, 7, - 2, 0, 26, 7, 2, 0, 27, 7, 2, 0, 37, 0, 2, 0, 19, 0, 2, 0, 28, 7, 2, 0, 29, 7, 2, 0, 30, 7, 4, 0, 31, 7, -238, 0, 32, 7, 9, 0, 33, 7, 4, 0, 34, 7, 4, 0, 35, 7, 0, 0, 36, 7,241, 0, 22, 0,241, 0, 0, 0,241, 0, 1, 0, -236, 0, 17, 7,236, 0, 18, 7,236, 0, 37, 7,236, 0, 38, 7,201, 0, 39, 7, 23, 0, 52, 0, 0, 0,124, 5, 0, 0, 40, 7, - 2, 0,172, 5, 2, 0,173, 5, 2, 0, 41, 7, 2, 0, 37, 0, 2, 0, 6, 7, 2, 0, 38, 6, 2, 0, 19, 0,242, 0, 19, 7, - 12, 0, 42, 7, 12, 0,123, 5, 12, 0, 43, 7, 12, 0, 44, 7,243, 0, 21, 0,243, 0, 0, 0,243, 0, 1, 0,199, 0,181, 5, - 23, 0, 45, 7, 23, 0, 46, 7, 2, 0,172, 5, 2, 0,173, 5, 2, 0, 47, 7, 2, 0, 48, 7, 2, 0, 49, 7, 2, 0, 19, 0, - 7, 0, 10, 2, 2, 0, 5, 7, 2, 0, 9, 7, 4, 0, 43, 0,244, 0, 19, 7, 12, 0, 50, 7, 12, 0, 51, 7, 12, 0, 43, 7, - 0, 0, 52, 7, 9, 0, 53, 7,245, 0, 11, 0, 0, 0, 54, 7, 2, 0, 55, 7, 2, 0, 56, 7, 2, 0, 57, 7, 2, 0, 58, 7, - 2, 0,126, 4, 2, 0,121, 4,201, 0, 59, 7, 46, 0, 60, 7, 4, 0, 61, 7, 4, 0, 62, 7,246, 0, 1, 0, 0, 0, 63, 7, -247, 0, 8, 0, 57, 0, 64, 7, 57, 0, 65, 7,247, 0, 66, 7,247, 0, 67, 7,247, 0, 68, 7, 2, 0,129, 0, 2, 0, 19, 0, - 4, 0, 69, 7,248, 0, 4, 0, 4, 0,239, 5, 4, 0, 70, 7, 4, 0,244, 5, 4, 0, 71, 7,249, 0, 2, 0, 4, 0, 72, 7, - 4, 0, 73, 7,250, 0, 7, 0, 7, 0, 74, 7, 7, 0, 75, 7, 7, 0, 76, 7, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0, 10, 4, - 7, 0, 77, 7,251, 0, 6, 0, 0, 0, 78, 7, 0, 0,201, 5, 49, 0,137, 0, 2, 0,106, 0, 2, 0,125, 4, 4, 0, 37, 0, -252, 0, 21, 0,252, 0, 0, 0,252, 0, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0, 79, 7, 4, 0, 80, 7, - 4, 0, 81, 7,246, 0, 82, 7, 0, 0, 78, 7, 4, 0, 83, 7, 4, 0, 84, 7,251, 0, 8, 3,248, 0, 85, 7,249, 0, 86, 7, -250, 0, 87, 7,247, 0, 88, 7,247, 0, 89, 7,247, 0, 90, 7, 57, 0, 91, 7, 57, 0, 92, 7,253, 0, 12, 0, 0, 0,190, 1, - 9, 0,191, 0, 0, 0,192, 0, 4, 0,195, 0, 4, 0,203, 0, 9, 0,196, 0, 7, 0,198, 0, 7, 0,199, 0, 9, 0, 93, 7, - 9, 0, 94, 7, 9, 0,200, 0, 9, 0,202, 0,254, 0, 43, 0,254, 0, 0, 0,254, 0, 1, 0, 9, 0, 95, 7, 9, 0, 26, 0, - 0, 0, 27, 0, 4, 0, 19, 0, 4, 0, 17, 0, 4, 0, 23, 0, 4, 0, 88, 0, 4, 0, 96, 7, 4, 0, 97, 7, 4, 0, 80, 7, - 4, 0, 81, 7, 4, 0, 98, 7, 4, 0,214, 0, 4, 0, 99, 7, 4, 0,100, 7, 7, 0,246, 4, 7, 0,101, 7, 4, 0,126, 0, - 4, 0,102, 7,252, 0,103, 7, 36, 0, 80, 0, 46, 0,134, 0, 49, 0,137, 0, 7, 0,104, 7, 7, 0,105, 7,253, 0, 1, 1, -254, 0,106, 7,254, 0,107, 7,254, 0,108, 7, 12, 0,109, 7,255, 0,110, 7, 0, 1,111, 7, 7, 0,112, 7, 7, 0,113, 7, - 4, 0,114, 7, 7, 0,115, 7, 9, 0,116, 7, 4, 0,117, 7, 4, 0,118, 7, 4, 0,119, 7, 7, 0,120, 7, 1, 1, 4, 0, - 1, 1, 0, 0, 1, 1, 1, 0, 12, 0,121, 7,254, 0,122, 7,186, 0, 6, 0, 12, 0,123, 7, 12, 0,109, 7, 12, 0,124, 7, -254, 0,125, 7, 0, 0,126, 7, 0, 0,127, 7, 2, 1, 4, 0, 7, 0,128, 7, 7, 0,109, 0, 2, 0,129, 7, 2, 0,130, 7, - 3, 1, 6, 0, 7, 0,131, 7, 7, 0,132, 7, 7, 0,133, 7, 7, 0,134, 7, 4, 0,135, 7, 4, 0,136, 7, 4, 1, 12, 0, - 7, 0,137, 7, 7, 0,138, 7, 7, 0,139, 7, 7, 0,140, 7, 7, 0,141, 7, 7, 0,142, 7, 7, 0,143, 7, 7, 0,144, 7, - 7, 0,145, 7, 7, 0,146, 7, 4, 0,154, 2, 4, 0,147, 7, 5, 1, 2, 0, 7, 0,219, 4, 7, 0, 37, 0, 6, 1, 5, 0, - 7, 0,148, 7, 7, 0,149, 7, 4, 0, 90, 0, 4, 0,116, 2, 4, 0,150, 7, 7, 1, 6, 0, 7, 1, 0, 0, 7, 1, 1, 0, - 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,151, 7, 2, 0, 57, 0, 8, 1, 8, 0, 8, 1, 0, 0, 8, 1, 1, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 2, 0,151, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0,126, 0, 9, 1, 45, 0, 9, 1, 0, 0, 9, 1, 1, 0, - 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,151, 7, 2, 0,210, 0, 2, 0,182, 3, 2, 0,152, 7, 7, 0,153, 7, 7, 0, 89, 0, - 7, 0,167, 2, 4, 0,154, 7, 4, 0, 82, 0, 4, 0,118, 2, 7, 0,155, 7, 7, 0,156, 7, 7, 0,157, 7, 7, 0,158, 7, - 7, 0,159, 7, 7, 0,160, 7, 7, 0,164, 2, 7, 0,254, 0, 7, 0,161, 7, 7, 0,162, 7, 7, 0, 37, 0, 7, 0,163, 7, - 7, 0,164, 7, 7, 0,165, 7, 2, 0,166, 7, 2, 0,167, 7, 2, 0,168, 7, 2, 0,169, 7, 2, 0,170, 7, 2, 0,171, 7, - 2, 0,172, 7, 2, 0,173, 7, 2, 0,136, 5, 2, 0,174, 7, 2, 0,210, 1, 2, 0,175, 7, 0, 0,176, 7, 0, 0,177, 7, - 7, 0,208, 0, 10, 1,178, 7, 64, 0,163, 1, 11, 1, 16, 0, 11, 1, 0, 0, 11, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, - 2, 0,151, 7, 2, 0,210, 0, 7, 0,159, 2, 7, 0,160, 2, 7, 0,161, 2, 7, 0,255, 1, 7, 0,162, 2, 7, 0,163, 2, - 7, 0,179, 7, 7, 0,164, 2, 7, 0,166, 2, 7, 0,167, 2,213, 0, 5, 0, 2, 0, 17, 0, 2, 0, 69, 7, 2, 0, 19, 0, - 2, 0,180, 7, 27, 0, 12, 6,212, 0, 3, 0, 4, 0, 69, 0, 4, 0,181, 7,213, 0, 2, 0, 12, 1, 7, 0, 12, 1, 0, 0, - 12, 1, 1, 0, 0, 0, 20, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 22, 0, 9, 0,182, 7, 13, 1, 5, 0, 0, 0, 20, 0, - 7, 0, 18, 1, 7, 0,183, 7, 4, 0,184, 7, 4, 0, 37, 0, 14, 1, 4, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 43, 0, - 2, 0, 70, 0, 15, 1, 4, 0, 0, 0, 20, 0, 63, 0,185, 7, 7, 0, 18, 1, 7, 0, 37, 0, 16, 1, 6, 0, 2, 0,186, 7, - 2, 0,187, 7, 2, 0, 17, 0, 2, 0,188, 7, 0, 0,189, 7, 0, 0,190, 7, 17, 1, 5, 0, 4, 0, 17, 0, 4, 0, 37, 0, - 0, 0, 20, 0, 0, 0,191, 7, 0, 0,192, 7, 18, 1, 3, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0, 19, 1, 4, 0, - 2, 0,193, 7, 2, 0,194, 7, 2, 0, 19, 0, 2, 0, 37, 0, 20, 1, 6, 0, 0, 0, 20, 0, 0, 0,195, 7, 2, 0,196, 7, - 2, 0,164, 2, 2, 0, 11, 1, 2, 0, 70, 0, 21, 1, 5, 0, 0, 0, 20, 0, 7, 0,109, 0, 7, 0, 12, 4, 2, 0, 19, 0, - 2, 0,130, 2, 22, 1, 3, 0, 0, 0, 20, 0, 4, 0,118, 2, 4, 0,193, 7, 23, 1, 7, 0, 0, 0, 20, 0, 7, 0, 12, 4, - 0, 0,197, 7, 0, 0,198, 7, 2, 0, 11, 1, 2, 0, 43, 0, 4, 0,199, 7, 24, 1, 3, 0, 32, 0,200, 7, 0, 0,201, 7, - 0, 0,202, 7, 25, 1, 18, 0, 25, 1, 0, 0, 25, 1, 1, 0, 2, 0, 17, 0, 2, 0,203, 7, 2, 0, 19, 0, 2, 0,204, 7, - 2, 0,205, 7, 2, 0,206, 7, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 20, 0, 9, 0, 2, 0, 26, 1,207, 7, 32, 0, 45, 0, - 2, 0,229, 4, 2, 0,112, 7, 2, 0,208, 7, 2, 0, 37, 0, 27, 1, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0, 0, 0,209, 7, - 2, 0, 19, 0, 2, 0,130, 2, 2, 0,210, 7, 4, 0,211, 7, 4, 0,212, 7, 4, 0,213, 7, 4, 0,214, 7, 4, 0,215, 7, - 28, 1, 1, 0, 0, 0,216, 7, 29, 1, 4, 0, 42, 0,238, 5, 0, 0,217, 7, 4, 0, 11, 1, 4, 0, 19, 0, 26, 1, 18, 0, - 26, 1, 0, 0, 26, 1, 1, 0, 26, 1,218, 7, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,219, 7, 2, 0,206, 7, 2, 0,203, 7, - 2, 0,220, 7, 2, 0, 70, 0, 2, 0,160, 1, 0, 0, 20, 0, 9, 0, 2, 0, 30, 1,207, 7, 25, 1,221, 7, 2, 0, 15, 0, - 2, 0,222, 7, 4, 0,223, 7, 31, 1, 3, 0, 4, 0,190, 2, 4, 0, 37, 0, 32, 0, 45, 0, 32, 1, 12, 0,151, 0,224, 7, - 2, 0, 17, 0, 2, 0, 19, 0, 4, 0,153, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0,225, 7, 2, 0,226, 7, 2, 0,227, 7, - 2, 0,228, 7, 2, 0,229, 7, 7, 0,230, 7, 33, 1, 10, 0, 2, 0, 19, 0, 2, 0,231, 7, 4, 0,153, 7, 4, 0, 89, 0, - 2, 0,232, 7,255, 0,110, 7, 2, 0, 17, 0, 2, 0,233, 7, 2, 0,234, 7, 2, 0,235, 7, 34, 1, 7, 0, 2, 0, 19, 0, - 2, 0,231, 7, 4, 0,153, 7, 4, 0, 89, 0, 2, 0, 17, 0, 2, 0,236, 7, 7, 0,139, 3, 35, 1, 11, 0, 4, 0,190, 2, - 2, 0, 17, 0, 2, 0, 19, 0, 32, 0, 45, 0, 77, 0,237, 7, 0, 0, 20, 0, 7, 0,238, 7, 7, 0,239, 7, 7, 0, 42, 3, - 2, 0,240, 7, 2, 0,241, 7, 36, 1, 5, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 37, 0, 46, 0,134, 0, 32, 0, 68, 5, - 37, 1, 5, 0, 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 20, 0, 0, 0,191, 7, 32, 0, 45, 0, 38, 1, 13, 0, 2, 0, 19, 0, - 2, 0, 17, 0, 2, 0,203, 7, 2, 0, 43, 3, 7, 0,242, 7, 7, 0,243, 7, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0, 19, 3, - 7, 0, 22, 3, 7, 0,244, 7, 7, 0,245, 7, 32, 0,246, 7, 39, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,153, 7, - 4, 0, 89, 0, 0, 0, 20, 0, 0, 0,225, 7, 2, 0, 43, 0, 2, 0, 64, 0, 2, 0,247, 7, 2, 0,248, 7, 40, 1, 8, 0, - 32, 0, 45, 0, 7, 0,161, 2, 7, 0,249, 7, 7, 0,250, 7, 7, 0,156, 2, 2, 0, 19, 0, 2, 0,130, 2, 7, 0,251, 7, - 41, 1, 12, 0, 2, 0, 17, 0, 2, 0, 11, 1, 2, 0, 19, 0, 2, 0,164, 2, 2, 0,190, 2, 2, 0,252, 7, 4, 0, 37, 0, - 7, 0,253, 7, 7, 0,254, 7, 7, 0,255, 7, 7, 0, 0, 8, 0, 0, 1, 8, 42, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, - 4, 0,153, 7, 4, 0, 89, 0, 0, 0, 20, 0, 2, 0, 77, 1, 2, 0, 64, 0, 2, 0,247, 7, 2, 0,248, 7, 64, 0,163, 1, - 43, 1, 7, 0, 4, 0,118, 2, 4, 0, 2, 8, 4, 0, 3, 8, 4, 0, 4, 8, 7, 0, 5, 8, 7, 0, 6, 8, 0, 0,197, 7, - 44, 1, 7, 0, 0, 0, 7, 8, 32, 0, 8, 8, 0, 0,201, 7, 2, 0, 9, 8, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0,202, 7, - 45, 1, 6, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,153, 7, 4, 0, 89, 0, 0, 0, 10, 8, 0, 0, 11, 8, 46, 1, 1, 0, - 4, 0, 19, 0, 47, 1, 6, 0, 0, 0, 92, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 12, 8, 7, 0, 13, 8, 42, 0,238, 5, - 48, 1, 4, 0, 0, 0,179, 0, 2, 0, 19, 0, 4, 0, 17, 0, 32, 0, 45, 0, 49, 1, 2, 0, 4, 0, 17, 0, 4, 0,161, 5, - 30, 1, 10, 0, 30, 1, 0, 0, 30, 1, 1, 0, 30, 1,218, 7, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,203, 7, 2, 0, 14, 8, - 0, 0, 20, 0, 9, 0, 2, 0, 32, 0, 45, 0, 50, 1, 10, 0, 7, 0, 42, 3, 7, 0, 15, 8, 7, 0, 16, 8, 7, 0, 17, 8, - 7, 0, 18, 8, 4, 0, 19, 0, 7, 0,252, 7, 7, 0, 19, 8, 7, 0, 20, 8, 7, 0, 37, 0,255, 0, 20, 0, 27, 0, 31, 0, - 0, 0,190, 0, 51, 1, 21, 8, 9, 0, 22, 8, 43, 0,149, 0, 43, 0, 23, 8, 9, 0, 24, 8, 36, 0, 80, 0, 7, 0,139, 3, - 7, 0, 25, 8, 7, 0, 26, 8, 7, 0, 27, 8, 7, 0, 28, 8, 7, 0, 29, 8, 7, 0, 30, 8, 4, 0, 90, 0, 4, 0, 31, 8, - 0, 0, 32, 8, 0, 0, 33, 8, 0, 0, 34, 8, 52, 1, 6, 0, 27, 0, 31, 0, 7, 0, 35, 8, 7, 0, 36, 8, 7, 0, 37, 8, - 2, 0, 38, 8, 2, 0, 39, 8, 53, 1, 15, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, 4, 0,124, 5, 7, 0,125, 5, -241, 0, 40, 8,199, 0,181, 5,255, 0,110, 7, 2, 0, 11, 1, 2, 0,231, 7, 2, 0, 14, 2, 2, 0, 15, 2, 2, 0, 19, 0, - 2, 0,186, 5, 4, 0, 70, 0, 54, 1, 6, 0, 54, 1, 0, 0, 54, 1, 1, 0, 32, 0, 45, 0, 9, 0, 41, 8, 4, 0,215, 0, - 4, 0, 37, 0, 64, 0, 4, 0, 27, 0, 31, 0, 12, 0, 42, 8, 4, 0,131, 0, 7, 0, 43, 8, 55, 1, 25, 0, 55, 1, 0, 0, - 55, 1, 1, 0, 55, 1, 38, 0, 12, 0, 44, 8, 0, 0, 20, 0, 7, 0, 45, 8, 7, 0, 46, 8, 7, 0, 47, 8, 7, 0, 48, 8, - 4, 0, 19, 0, 7, 0, 49, 8, 7, 0, 50, 8, 7, 0, 51, 8, 7, 0, 18, 1, 7, 0,220, 1, 7, 0, 52, 8, 7, 0,116, 2, - 7, 0, 53, 8, 7, 0, 54, 8, 7, 0, 55, 8, 7, 0, 56, 8, 7, 0, 57, 8, 7, 0,172, 0, 2, 0,131, 0, 2, 0, 6, 5, - 56, 1, 21, 0, 27, 0, 31, 0, 12, 0, 58, 8, 12, 0, 59, 8, 12, 0, 60, 8, 9, 0, 61, 8, 4, 0, 19, 0, 4, 0,132, 5, - 2, 0,168, 2, 2, 0,192, 5, 2, 0,131, 0, 2, 0, 62, 8, 2, 0, 63, 8, 2, 0, 64, 8, 2, 0, 65, 8, 2, 0, 66, 8, - 4, 0, 67, 8, 4, 0, 68, 8, 4, 0, 69, 8, 4, 0, 70, 8, 4, 0, 71, 8, 4, 0, 72, 8, 57, 1, 38, 0, 57, 1, 0, 0, - 57, 1, 1, 0, 26, 0, 73, 8, 12, 0, 69, 3, 0, 0, 20, 0, 2, 0, 19, 0, 2, 0, 74, 8, 2, 0, 75, 8, 2, 0, 76, 8, - 2, 0, 28, 3, 2, 0, 77, 8, 4, 0,253, 1, 4, 0, 69, 8, 4, 0, 70, 8, 55, 1, 78, 8, 57, 1, 38, 0, 57, 1, 79, 8, - 12, 0, 80, 8, 9, 0, 81, 8, 9, 0, 82, 8, 9, 0, 83, 8, 7, 0, 6, 1, 7, 0,172, 0, 7, 0, 84, 8, 7, 0,200, 1, - 2, 0, 85, 8, 2, 0, 37, 0, 7, 0, 86, 8, 7, 0, 87, 8, 7, 0, 24, 3, 7, 0, 88, 8, 7, 0, 89, 8, 7, 0, 90, 8, - 7, 0, 91, 8, 7, 0, 92, 8, 7, 0, 93, 8, 7, 0,250, 1, 32, 0, 94, 8,152, 0, 9, 0, 12, 0, 95, 8, 2, 0, 19, 0, - 2, 0, 96, 8, 7, 0, 26, 2, 7, 0, 97, 8, 7, 0, 98, 8, 12, 0, 99, 8, 4, 0,100, 8, 4, 0, 37, 0, 58, 1, 7, 0, - 58, 1, 0, 0, 58, 1, 1, 0, 12, 0, 32, 8, 4, 0, 19, 0, 4, 0,101, 8, 0, 0,132, 3,232, 0,102, 8,151, 0, 7, 0, - 27, 0, 31, 0, 12, 0,103, 8, 12, 0, 95, 8, 12, 0,104, 8, 12, 0,100, 0, 4, 0, 19, 0, 4, 0,105, 8,203, 0, 4, 0, - 27, 0,106, 8, 12, 0, 95, 8, 4, 0,107, 8, 4, 0, 19, 0, 59, 1, 17, 0,198, 0, 0, 0,198, 0, 1, 0, 12, 0,123, 5, - 4, 0,124, 5, 7, 0,125, 5, 2, 0,126, 5,199, 0,181, 5,151, 0, 11, 3,203, 0,108, 8, 0, 0, 11, 1, 0, 0,184, 5, - 2, 0, 19, 0, 2, 0,109, 8, 2, 0,185, 5, 2, 0,186, 5, 2, 0,110, 8, 7, 0,111, 8, 60, 1, 8, 0, 60, 1, 0, 0, - 60, 1, 1, 0, 58, 1,112, 8, 36, 0, 80, 0, 12, 0, 14, 3, 4, 0, 19, 0, 0, 0, 20, 0, 4, 0,113, 8, 61, 1, 5, 0, - 61, 1, 0, 0, 61, 1, 1, 0, 36, 0, 80, 0, 2, 0, 19, 0, 0, 0,114, 8, 62, 1, 12, 0, 62, 1, 0, 0, 62, 1, 1, 0, - 9, 0, 2, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0,115, 8, 0, 0,116, 8, 0, 0,114, 8, 7, 0,117, 8, 7, 0,118, 8, - 4, 0, 37, 0, 36, 0, 80, 0, 63, 1, 9, 0, 63, 1, 0, 0, 63, 1, 1, 0, 32, 0,119, 8, 0, 0,120, 8, 7, 0,121, 8, - 2, 0,122, 8, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0, 37, 0, 64, 1, 7, 0, 42, 0,238, 5, 26, 0, 73, 8, 4, 0, 19, 0, - 4, 0,123, 8, 12, 0,124, 8, 32, 0,119, 8, 0, 0,120, 8, 65, 1, 12, 0, 32, 0,119, 8, 2, 0,125, 8, 2, 0, 19, 0, - 2, 0,126, 8, 2, 0,127, 8, 0, 0,120, 8, 32, 0,128, 8, 0, 0,129, 8, 7, 0,130, 8, 7, 0,220, 1, 7, 0,131, 8, - 7, 0,132, 8, 66, 1, 6, 0, 32, 0,119, 8, 4, 0,133, 8, 4, 0,134, 8, 4, 0, 90, 0, 4, 0, 37, 0, 0, 0,120, 8, - 67, 1, 4, 0, 32, 0,119, 8, 4, 0, 19, 0, 4, 0,133, 8, 0, 0,120, 8, 68, 1, 4, 0, 32, 0,119, 8, 4, 0, 19, 0, - 4, 0,133, 8, 0, 0,120, 8, 69, 1, 10, 0, 32, 0,119, 8, 4, 0,135, 8, 7, 0,125, 0, 4, 0, 19, 0, 2, 0,234, 5, - 2, 0,136, 8, 2, 0, 43, 0, 2, 0, 70, 0, 7, 0,137, 8, 0, 0,120, 8, 70, 1, 4, 0, 32, 0,119, 8, 4, 0, 19, 0, - 4, 0,133, 8, 0, 0,120, 8, 71, 1, 10, 0, 32, 0,119, 8, 2, 0, 17, 0, 2, 0,190, 3, 4, 0, 88, 0, 4, 0, 89, 0, - 7, 0,249, 7, 7, 0,250, 7, 4, 0, 37, 0,151, 0,224, 7, 0, 0,120, 8, 72, 1, 4, 0, 32, 0,119, 8, 4, 0, 29, 3, - 4, 0,138, 8, 0, 0,120, 8, 73, 1, 5, 0, 32, 0,119, 8, 7, 0,125, 0, 4, 0,139, 8, 4, 0, 29, 3, 4, 0, 30, 3, - 74, 1, 6, 0, 32, 0,119, 8, 4, 0,140, 8, 4, 0,141, 8, 7, 0,142, 8, 7, 0,143, 8, 0, 0,120, 8, 75, 1, 16, 0, - 32, 0,119, 8, 32, 0, 79, 8, 4, 0, 17, 0, 7, 0,144, 8, 7, 0,145, 8, 7, 0,146, 8, 7, 0,147, 8, 7, 0,148, 8, - 7, 0,149, 8, 7, 0,150, 8, 7, 0,151, 8, 7, 0,152, 8, 2, 0, 19, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, - 76, 1, 3, 0, 32, 0,119, 8, 4, 0, 19, 0, 4, 0,136, 5, 77, 1, 5, 0, 32, 0,119, 8, 4, 0, 19, 0, 4, 0, 37, 0, - 7, 0,153, 8, 0, 0,120, 8, 78, 1, 10, 0, 32, 0,119, 8, 0, 0,120, 8, 2, 0,154, 8, 2, 0,155, 8, 0, 0,156, 8, - 0, 0,157, 8, 7, 0,158, 8, 7, 0,159, 8, 7, 0,160, 8, 7, 0,161, 8, 79, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, - 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,162, 8, 7, 0,163, 8, 2, 0, 19, 0, 2, 0,136, 5, 80, 1, 8, 0, 7, 0, 9, 0, - 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,162, 8, 7, 0,163, 8, 2, 0, 19, 0, 2, 0,136, 5, 81, 1, 8, 0, - 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,162, 8, 7, 0,163, 8, 2, 0, 19, 0, 2, 0,136, 5, - 82, 1, 7, 0, 32, 0,119, 8, 0, 0,120, 8, 7, 0, 18, 1, 7, 0, 28, 1, 2, 0, 19, 0, 2, 0, 11, 1, 4, 0, 37, 0, - 83, 1, 5, 0, 32, 0,228, 2, 7, 0, 18, 1, 2, 0,232, 2, 0, 0,234, 2, 0, 0,164, 8, 84, 1, 10, 0, 84, 1, 0, 0, - 84, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0,165, 8, 7, 0,217, 0, 7, 0,218, 0, 2, 0, 32, 8, 2, 0,166, 8, - 32, 0, 45, 0, 85, 1, 22, 0, 85, 1, 0, 0, 85, 1, 1, 0, 2, 0, 19, 0, 2, 0, 11, 1, 2, 0,167, 8, 2, 0,168, 8, - 36, 0, 80, 0,151, 0,224, 7, 32, 0,164, 0, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,169, 8, 7, 0,170, 8, 7, 0,171, 8, - 7, 0,172, 8, 7, 0,157, 2, 7, 0,173, 8, 7, 0,226, 7, 7, 0,174, 8, 0, 0,175, 8, 0, 0,176, 8, 12, 0, 16, 3, - 86, 1, 8, 0, 7, 0,228, 1, 7, 0,249, 7, 7, 0,250, 7, 9, 0, 2, 0, 2, 0,177, 8, 2, 0,178, 8, 2, 0,179, 8, - 2, 0,180, 8, 87, 1, 18, 0, 87, 1, 0, 0, 87, 1, 1, 0, 87, 1,181, 8, 0, 0, 20, 0, 86, 1,182, 8, 2, 0, 17, 0, - 2, 0, 19, 0, 2, 0,183, 8, 2, 0,184, 8, 2, 0,185, 8, 2, 0,186, 8, 4, 0, 43, 0, 7, 0,187, 8, 7, 0,188, 8, - 4, 0,189, 8, 4, 0,190, 8, 87, 1,191, 8, 88, 1,192, 8, 89, 1, 33, 0, 89, 1, 0, 0, 89, 1, 1, 0, 89, 1,193, 8, - 0, 0, 20, 0, 0, 0,194, 8, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 79, 7, 2, 0,112, 7, 2, 0,195, 8, 2, 0,133, 0, - 2, 0,184, 8, 2, 0, 69, 7, 12, 0,219, 7, 12, 0,196, 8, 27, 0, 12, 6, 9, 0,197, 8, 7, 0,187, 8, 7, 0,188, 8, - 7, 0,255, 1, 7, 0,198, 8, 2, 0,199, 8, 2, 0,200, 8, 7, 0,201, 8, 7, 0,202, 8, 2, 0,203, 8, 2, 0,204, 8, - 9, 0,205, 8, 24, 0,206, 8, 24, 0,207, 8, 24, 0,208, 8, 90, 1,150, 0, 91, 1,209, 8, 88, 1, 8, 0, 88, 1, 0, 0, - 88, 1, 1, 0, 89, 1,210, 8, 89, 1,211, 8, 87, 1,212, 8, 87, 1,191, 8, 4, 0, 19, 0, 4, 0, 37, 0, 58, 0, 20, 0, - 27, 0, 31, 0, 39, 0, 75, 0, 12, 0,213, 8, 12, 0,214, 8, 86, 1,215, 8, 12, 0,216, 8, 4, 0, 17, 0, 4, 0,217, 8, - 4, 0,218, 8, 4, 0,219, 8, 12, 0,220, 8, 91, 1,221, 8, 87, 1,222, 8, 87, 1,223, 8, 9, 0,224, 8, 9, 0,225, 8, - 4, 0,226, 8, 9, 0,227, 8, 9, 0,228, 8, 9, 0,229, 8, 92, 1, 6, 0, 4, 0,124, 0, 4, 0,126, 0, 4, 0, 69, 7, - 0, 0,230, 8, 0, 0,231, 8, 2, 0, 37, 0, 93, 1, 16, 0, 2, 0, 25, 7, 2, 0, 26, 7, 2, 0,232, 8, 2, 0, 16, 8, - 2, 0,233, 8, 2, 0, 68, 0, 7, 0,156, 2, 7, 0,234, 8, 7, 0,235, 8, 2, 0, 32, 1, 0, 0,236, 8, 0, 0,245, 4, - 2, 0,237, 8, 2, 0, 37, 0, 4, 0,238, 8, 4, 0,239, 8, 94, 1, 9, 0, 7, 0,240, 8, 7, 0,241, 8, 7, 0, 30, 8, - 7, 0,109, 0, 7, 0,242, 8, 7, 0,198, 5, 2, 0,243, 8, 0, 0,244, 8, 0, 0, 37, 0, 95, 1, 4, 0, 7, 0,245, 8, - 7, 0,246, 8, 2, 0,243, 8, 2, 0, 37, 0, 96, 1, 3, 0, 7, 0,247, 8, 7, 0,248, 8, 7, 0, 15, 0, 97, 1, 7, 0, - 0, 0,190, 1, 2, 0,123, 4, 2, 0,124, 4, 2, 0,125, 4, 2, 0, 76, 4, 4, 0,126, 0, 4, 0,188, 3, 98, 1, 7, 0, - 7, 0,249, 8, 7, 0,250, 8, 7, 0,251, 8, 7, 0, 10, 2, 7, 0,252, 8, 7, 0,253, 8, 7, 0,254, 8, 99, 1, 4, 0, - 2, 0,255, 8, 2, 0, 0, 9, 2, 0, 1, 9, 2, 0, 2, 9,100, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,101, 1, 2, 0, - 0, 0,166, 0, 0, 0, 3, 9,102, 1, 1, 0, 0, 0, 20, 0,103, 1, 10, 0, 0, 0, 4, 9, 0, 0, 5, 9, 0, 0,191, 5, - 0, 0, 6, 9, 2, 0,232, 8, 2, 0, 7, 9, 7, 0, 8, 9, 7, 0, 9, 9, 7, 0, 10, 9, 7, 0,173, 8,104, 1, 2, 0, - 9, 0, 11, 9, 9, 0, 12, 9,105, 1, 11, 0, 0, 0,125, 4, 0, 0, 17, 0, 0, 0,243, 8, 0, 0,109, 0, 0, 0, 13, 9, - 0, 0,106, 0, 0, 0,179, 0, 7, 0, 14, 9, 7, 0, 15, 9, 7, 0, 16, 9, 7, 0, 17, 9,106, 1, 8, 0, 7, 0,186, 7, - 7, 0,125, 0, 7, 0,245, 4, 7, 0, 82, 2, 7, 0, 18, 9, 7, 0,204, 0, 7, 0, 19, 9, 4, 0, 17, 0,107, 1, 4, 0, - 2, 0, 20, 9, 2, 0, 21, 9, 2, 0, 22, 9, 2, 0, 37, 0,108, 1, 1, 0, 0, 0, 20, 0,109, 1, 4, 0, 7, 0, 5, 0, - 7, 0, 6, 0, 2, 0, 19, 0, 2, 0, 23, 9,110, 1, 10, 0, 2, 0,124, 3, 2, 0, 19, 0, 7, 0, 12, 4, 7, 0, 24, 9, - 7, 0, 25, 9, 7, 0, 26, 9, 7, 0, 27, 9,109, 1, 28, 9,109, 1, 29, 9,109, 1, 30, 9, 61, 0, 9, 0, 4, 0, 19, 0, - 4, 0, 64, 0, 24, 0, 31, 9, 24, 0, 32, 9,110, 1, 33, 9, 7, 0, 34, 9, 7, 0, 35, 9, 7, 0, 36, 9, 7, 0, 37, 9, -111, 1, 4, 0, 47, 0,150, 2, 7, 0, 38, 9, 7, 0, 93, 1, 7, 0, 37, 0,177, 0, 17, 0, 27, 0, 31, 0,111, 1, 39, 9, - 61, 0, 28, 9, 51, 0, 75, 1, 2, 0, 19, 0, 2, 0, 90, 5, 4, 0,106, 0, 7, 0, 40, 9, 7, 0, 7, 2, 7, 0, 41, 9, - 7, 0, 42, 9, 7, 0, 93, 1, 7, 0, 43, 9, 2, 0, 45, 1, 0, 0, 44, 9, 0, 0,117, 3, 0, 0, 92, 0,112, 1, 10, 0, - 4, 0, 17, 0, 4, 0,125, 0, 4, 0, 19, 0, 4, 0, 90, 3, 4, 0, 45, 9, 4, 0, 46, 9, 4, 0, 47, 9, 0, 0, 92, 0, - 0, 0, 20, 0, 9, 0, 2, 0, 88, 0, 6, 0,112, 1, 48, 9, 4, 0, 49, 9, 4, 0, 50, 9, 4, 0, 51, 9, 4, 0, 37, 0, - 9, 0, 52, 9,113, 1, 5, 0, 7, 0, 77, 2, 7, 0,190, 2, 7, 0,220, 1, 2, 0, 53, 9, 2, 0, 37, 0,114, 1, 5, 0, - 7, 0, 77, 2, 7, 0, 54, 9, 7, 0, 55, 9, 7, 0, 56, 9, 7, 0,190, 2,115, 1, 7, 0, 4, 0, 57, 9, 4, 0, 58, 9, - 4, 0, 59, 9, 7, 0, 60, 9, 7, 0, 61, 9, 7, 0, 62, 9, 7, 0, 63, 9,116, 1, 8, 0,116, 1, 0, 0,116, 1, 1, 0, - 32, 0, 45, 0, 4, 0,215, 2, 2, 0, 19, 0, 2, 0, 11, 1, 7, 0,190, 2, 7, 0,194, 7,117, 1, 24, 0, 32, 0, 64, 9, -114, 1, 86, 3,114, 1, 65, 9,113, 1, 66, 9,114, 1,178, 7,118, 1, 67, 9, 7, 0, 68, 9, 7, 0, 69, 9, 7, 0, 70, 9, - 7, 0, 61, 9, 7, 0, 62, 9, 7, 0,190, 2, 7, 0,167, 2, 7, 0, 71, 9, 7, 0,106, 0, 7, 0, 72, 9, 4, 0, 57, 9, - 4, 0, 73, 9, 4, 0, 82, 0, 4, 0, 74, 9, 2, 0, 19, 0, 2, 0, 75, 9, 2, 0, 76, 9, 2, 0,120, 3,119, 1,107, 0, - 27, 0, 31, 0, 39, 0, 75, 0,120, 1, 77, 9, 4, 0, 19, 0, 2, 0, 17, 0, 2, 0,154, 8, 2, 0, 78, 9, 2, 0, 79, 9, - 2, 0, 85, 8, 2, 0, 80, 9, 2, 0, 81, 9, 2, 0, 82, 9, 2, 0, 83, 9, 2, 0, 84, 9, 2, 0, 85, 9, 2, 0, 86, 9, - 2, 0,120, 3, 2, 0, 87, 9, 2, 0, 88, 9, 2, 0, 89, 9, 2, 0, 90, 9, 2, 0, 91, 9, 2, 0, 92, 9, 2, 0,210, 1, - 2, 0,171, 7, 2, 0,147, 7, 2, 0, 93, 9, 2, 0, 94, 9, 2, 0,118, 3, 2, 0,119, 3, 2, 0, 95, 9, 2, 0, 96, 9, - 2, 0, 97, 9, 2, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9, 7, 0,101, 9, 2, 0,102, 9, 2, 0,103, 9, 7, 0,104, 9, - 7, 0,105, 9, 7, 0,106, 9, 7, 0,153, 7, 7, 0, 89, 0, 7, 0,167, 2, 7, 0,159, 7, 7, 0,107, 9, 7, 0,108, 9, - 7, 0,109, 9, 4, 0,154, 7, 4, 0,152, 7, 4, 0,110, 9, 7, 0,155, 7, 7, 0,156, 7, 7, 0,157, 7, 7, 0,111, 9, - 7, 0,112, 9, 7, 0,113, 9, 7, 0,114, 9, 7, 0,115, 9, 7, 0,116, 9, 7, 0,117, 9, 7, 0,118, 9, 7, 0, 42, 3, - 7, 0,106, 0, 7, 0,119, 9, 7, 0,120, 9, 7, 0,121, 9, 7, 0,122, 9, 7, 0,123, 9, 7, 0,124, 9, 7, 0,125, 9, - 4, 0,126, 9, 4, 0,127, 9, 7, 0,128, 9, 7, 0,129, 9, 7, 0,130, 9, 7, 0,131, 9, 7, 0,132, 9, 7, 0,133, 9, - 7, 0,134, 9, 7, 0,114, 3, 7, 0,112, 3, 7, 0,113, 3, 7, 0,135, 9, 7, 0,136, 9, 7, 0,137, 9, 7, 0,138, 9, - 7, 0,139, 9, 7, 0,140, 9, 7, 0,141, 9, 7, 0,142, 9, 7, 0,143, 9, 7, 0,144, 9, 7, 0,145, 9, 7, 0,146, 9, - 7, 0,147, 9, 4, 0,148, 9, 4, 0,149, 9, 7, 0,150, 9, 64, 0, 75, 3, 64, 0,151, 9, 32, 0,152, 9, 32, 0,153, 9, - 36, 0, 80, 0,154, 0, 73, 3,154, 0,154, 9,141, 0, 41, 0,141, 0, 0, 0,141, 0, 1, 0,119, 1,155, 9,117, 1,165, 3, -115, 1, 79, 8,121, 1,156, 9, 9, 0,157, 9,122, 1,158, 9,122, 1,159, 9, 12, 0,160, 9, 12, 0,161, 9,155, 0, 74, 3, - 32, 0,162, 9, 32, 0,163, 9, 32, 0, 38, 0, 12, 0,164, 9, 12, 0,165, 9, 12, 0,124, 8, 0, 0, 20, 0, 7, 0,208, 0, - 7, 0,194, 2, 7, 0,166, 9, 4, 0,118, 2, 4, 0, 19, 0, 4, 0,154, 7, 4, 0,167, 9, 4, 0,168, 9, 4, 0,169, 9, - 2, 0,215, 0, 2, 0,170, 9, 2, 0,171, 9, 2, 0, 67, 3, 2, 0,172, 9, 2, 0,120, 3, 0, 0,173, 9, 2, 0,174, 9, - 2, 0,175, 9, 2, 0,176, 9, 9, 0,177, 9,130, 0,209, 3,123, 1,178, 9,128, 0, 34, 0,124, 1,179, 9, 7, 0,179, 3, - 7, 0,180, 9, 7, 0,181, 9, 7, 0, 15, 4, 7, 0,182, 9, 7, 0, 52, 3, 7, 0, 42, 3, 7, 0,183, 9, 7, 0, 9, 2, - 7, 0,184, 9, 7, 0,185, 9, 7, 0,186, 9, 7, 0,187, 9, 7, 0,188, 9, 7, 0,189, 9, 7, 0,180, 3, 7, 0,190, 9, - 7, 0,191, 9, 7, 0,192, 9, 7, 0,181, 3, 7, 0,177, 3, 7, 0,178, 3, 4, 0,193, 9, 4, 0, 90, 0, 4, 0,194, 9, - 4, 0,195, 9, 2, 0,196, 9, 2, 0,197, 9, 2, 0,198, 9, 2, 0,199, 9, 2, 0,200, 9, 2, 0, 37, 0, 4, 0, 70, 0, -129, 0, 8, 0,124, 1,201, 9, 7, 0,202, 9, 7, 0,203, 9, 7, 0,164, 1, 7, 0,204, 9, 4, 0, 90, 0, 2, 0,205, 9, - 2, 0,206, 9,125, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,207, 9,126, 1, 6, 0,126, 1, 0, 0, -126, 1, 1, 0,125, 1,208, 9, 4, 0,209, 9, 2, 0,210, 9, 2, 0, 19, 0,127, 1, 5, 0,127, 1, 0, 0,127, 1, 1, 0, - 12, 0,211, 9, 4, 0,212, 9, 4, 0, 19, 0,128, 1, 9, 0,128, 1, 0, 0,128, 1, 1, 0, 12, 0,124, 0,127, 1,213, 9, - 4, 0, 19, 0, 2, 0,210, 9, 2, 0,214, 9, 7, 0, 91, 0, 0, 0,215, 9,191, 0, 6, 0, 27, 0, 31, 0, 12, 0,139, 4, - 4, 0, 19, 0, 2, 0,216, 9, 2, 0,217, 9, 9, 0,218, 9,129, 1, 7, 0,129, 1, 0, 0,129, 1, 1, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 4, 0, 23, 0, 0, 0,219, 9, 0, 0,220, 9,130, 1, 5, 0, 12, 0,221, 9, 4, 0,222, 9, 4, 0,223, 9, - 4, 0, 19, 0, 4, 0, 37, 0,131, 1, 13, 0, 27, 0, 31, 0,132, 1,224, 9,132, 1,225, 9, 12, 0,226, 9, 4, 0,227, 9, - 2, 0,228, 9, 2, 0, 37, 0, 12, 0,229, 9, 12, 0,230, 9,130, 1,231, 9, 12, 0,232, 9, 12, 0,233, 9, 12, 0,234, 9, -132, 1, 30, 0,132, 1, 0, 0,132, 1, 1, 0, 9, 0,235, 9, 4, 0, 4, 7, 4, 0, 37, 0,201, 0,180, 5,201, 0,236, 9, - 0, 0,237, 9, 2, 0,238, 9, 2, 0,239, 9, 2, 0, 25, 7, 2, 0, 26, 7, 2, 0,240, 9, 2, 0,241, 9, 2, 0, 90, 3, - 2, 0, 38, 6, 2, 0,242, 9, 2, 0,243, 9, 4, 0,160, 1,133, 1,244, 9,134, 1,245, 9,135, 1,246, 9, 4, 0,247, 9, - 4, 0,248, 9, 9, 0,249, 9, 12, 0,250, 9, 12, 0,230, 9, 12, 0, 43, 7, 12, 0,251, 9, 12, 0,252, 9,136, 1, 16, 0, -136, 1, 0, 0,136, 1, 1, 0, 0, 0,253, 9,137, 1,254, 9, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0,255, 9, 2, 0, 0, 10, - 2, 0, 1, 10, 2, 0, 2, 10, 2, 0, 3, 10, 2, 0, 4, 10, 2, 0, 5, 10, 2, 0, 6, 10, 2, 0, 70, 0, 2, 0,160, 1, -138, 1, 9, 0,138, 1, 0, 0,138, 1, 1, 0, 12, 0, 7, 10, 0, 0, 8, 10, 2, 0, 9, 10, 2, 0, 10, 10, 2, 0, 11, 10, - 2, 0, 37, 0, 9, 0, 12, 10,209, 0, 10, 0,209, 0, 0, 0,209, 0, 1, 0, 0, 0,253, 9, 26, 0, 30, 0,139, 1, 19, 7, - 9, 0, 13, 10,137, 1,254, 9,130, 1, 14, 10, 12, 0, 15, 10,209, 0, 16, 10,133, 1, 23, 0,133, 1, 0, 0,133, 1, 1, 0, - 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 5, 0, 2, 0, 6, 0, 2, 0, 17, 10, 2, 0, 18, 10, 2, 0, 19, 10, 2, 0, 20, 10, - 0, 0, 21, 10, 0, 0, 37, 0, 2, 0,255, 9, 2, 0, 0, 10, 2, 0, 1, 10, 2, 0, 2, 10, 2, 0, 3, 10, 2, 0, 43, 0, - 0, 0, 22, 10, 2, 0, 23, 10, 2, 0, 24, 10, 4, 0, 70, 0, 9, 0, 13, 10,140, 1, 8, 0,140, 1, 0, 0,140, 1, 1, 0, - 9, 0, 2, 0, 9, 0, 25, 10, 0, 0,132, 3, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0, 26, 10,141, 1, 5, 0, 7, 0, 27, 10, - 4, 0, 28, 10, 4, 0, 29, 10, 4, 0, 11, 1, 4, 0, 19, 0,142, 1, 6, 0, 7, 0, 30, 10, 7, 0, 31, 10, 7, 0, 32, 10, - 7, 0, 33, 10, 4, 0, 17, 0, 4, 0, 19, 0,143, 1, 5, 0, 7, 0,249, 7, 7, 0,250, 7, 7, 0,190, 2, 2, 0,224, 1, - 2, 0,225, 1,144, 1, 5, 0,143, 1, 2, 0, 4, 0, 54, 0, 7, 0, 34, 10, 7, 0,249, 7, 7, 0,250, 7,145, 1, 4, 0, - 2, 0, 35, 10, 2, 0, 36, 10, 2, 0, 37, 10, 2, 0, 38, 10,146, 1, 2, 0, 42, 0, 9, 6, 26, 0, 73, 8,147, 1, 3, 0, - 24, 0, 39, 10, 4, 0, 19, 0, 4, 0, 37, 0,148, 1, 6, 0, 7, 0,106, 0, 7, 0,142, 2, 7, 0, 40, 10, 7, 0, 37, 0, - 2, 0,214, 0, 2, 0, 41, 10,149, 1, 7, 0,149, 1, 0, 0,149, 1, 1, 0, 27, 0, 12, 6, 0, 0, 42, 10, 4, 0, 43, 10, - 4, 0, 90, 0, 0, 0,132, 3,150, 1, 6, 0, 12, 0,124, 8, 0, 0, 44, 10, 7, 0, 61, 0, 7, 0, 26, 10, 4, 0, 17, 0, - 4, 0, 19, 0,151, 1, 3, 0, 7, 0, 45, 10, 4, 0, 19, 0, 4, 0, 37, 0,152, 1, 15, 0,152, 1, 0, 0,152, 1, 1, 0, - 58, 1,112, 8,150, 1, 62, 0, 12, 0, 16, 3, 35, 0, 50, 0,151, 1, 46, 10, 4, 0, 54, 0, 7, 0, 61, 0, 2, 0, 19, 0, - 2, 0,252, 0, 4, 0, 43, 10, 0, 0, 42, 10, 4, 0, 47, 10, 7, 0, 48, 10,153, 1, 2, 0, 0, 0, 49, 10, 0, 0, 50, 10, -154, 1, 4, 0,154, 1, 0, 0,154, 1, 1, 0,151, 0,228, 2, 12, 0, 51, 10,155, 1, 24, 0,155, 1, 0, 0,155, 1, 1, 0, - 12, 0, 52, 10,151, 0,224, 7,154, 1, 53, 10, 12, 0, 54, 10, 12, 0, 16, 3, 0, 0,132, 3, 7, 0, 26, 10, 7, 0, 55, 10, - 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,169, 8, 7, 0,170, 8, 7, 0,157, 2, 7, 0,173, 8, 7, 0,226, 7, 7, 0,174, 8, - 2, 0, 56, 10, 2, 0, 57, 10, 2, 0, 43, 0, 2, 0, 17, 0, 4, 0, 19, 0, 4, 0, 70, 0,156, 1, 6, 0,156, 1, 0, 0, -156, 1, 1, 0, 12, 0, 52, 10, 4, 0, 19, 0, 4, 0, 81, 2, 0, 0,132, 3,157, 1, 10, 0,157, 1, 0, 0,157, 1, 1, 0, - 27, 0, 12, 6, 0, 0, 58, 10, 4, 0, 59, 10, 4, 0, 60, 10, 0, 0, 42, 10, 4, 0, 43, 10, 2, 0, 19, 0, 2, 0, 61, 10, -158, 1, 6, 0,158, 1, 0, 0,158, 1, 1, 0, 12, 0, 62, 10, 0, 0,132, 3, 4, 0, 19, 0, 4, 0, 63, 10,159, 1, 5, 0, -159, 1, 0, 0,159, 1, 1, 0, 0, 0, 42, 10, 4, 0, 43, 10, 7, 0,134, 2, 39, 0, 9, 0,151, 0, 11, 3,151, 0, 64, 10, -154, 1, 53, 10, 12, 0, 65, 10,155, 1, 66, 10, 12, 0, 67, 10, 12, 0, 68, 10, 4, 0, 19, 0, 4, 0,215, 0,160, 1, 2, 0, - 27, 0, 31, 0, 39, 0, 75, 0,161, 1, 5, 0,161, 1, 0, 0,161, 1, 1, 0, 4, 0, 17, 0, 4, 0, 19, 0, 0, 0, 20, 0, -162, 1, 6, 0,161, 1, 69, 10, 32, 0, 45, 0, 4, 0, 70, 10, 7, 0, 71, 10, 4, 0, 72, 10, 4, 0, 32, 8,163, 1, 3, 0, -161, 1, 69, 10, 4, 0, 70, 10, 7, 0, 73, 10,164, 1, 8, 0,161, 1, 69, 10, 32, 0, 45, 0, 7, 0, 6, 1, 7, 0, 74, 10, - 7, 0,194, 2, 7, 0, 30, 8, 4, 0, 70, 10, 4, 0, 75, 10,165, 1, 5, 0,161, 1, 69, 10, 7, 0, 76, 10, 7, 0,112, 7, - 7, 0,163, 2, 7, 0, 57, 0,166, 1, 3, 0,161, 1, 69, 10, 7, 0, 30, 8, 7, 0, 77, 10,118, 1, 4, 0, 7, 0, 78, 10, - 7, 0,121, 9, 2, 0, 79, 10, 2, 0, 11, 1,167, 1, 14, 0,167, 1, 0, 0,167, 1, 1, 0, 12, 0, 80, 10, 12, 0, 81, 10, - 12, 0, 82, 10, 0, 0, 20, 0, 4, 0, 31, 0, 4, 0, 19, 0, 4, 0, 83, 10, 7, 0, 84, 10, 4, 0, 72, 10, 4, 0, 32, 8, - 7, 0,139, 3, 7, 0,165, 2,120, 1, 23, 0, 4, 0, 70, 10, 4, 0, 85, 10, 7, 0, 86, 10, 7, 0, 57, 0, 7, 0, 87, 10, - 7, 0,161, 2, 7, 0, 78, 10, 7, 0, 88, 10, 7, 0,142, 2, 7, 0, 89, 10, 7, 0, 12, 4, 7, 0, 90, 10, 7, 0, 91, 10, - 7, 0, 92, 10, 7, 0, 93, 10, 7, 0, 94, 10, 7, 0, 95, 10, 7, 0, 96, 10, 7, 0, 97, 10, 7, 0, 98, 10, 7, 0, 99, 10, - 7, 0,100, 10, 12, 0,101, 10, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 97,116, 97, 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, + 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, 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, 82, 78, 71, 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, 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, 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, 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, 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, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110, 0, 83, 99,117,108,112,116, + 0, 86, 80, 97,105,110,116, 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, 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, 66, 71,112,105, 99, 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,116,111,112,111, 86,105,101,119, 68, 97,116, 97, 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, 98, 83, 99,114,101,101,110, 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,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, 0, 83,112, + 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,105, 99, 0, 83,112, 97, 99,101, 73,109, 97, 83,101,108, 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,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, 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, 83,111,108,105,100, 76,105,103,104,116, 0, 85,115,101,114, 68,101,102, 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, 84, 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, 83,111,117,110,100, 72, 97,110,100,108,101, 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, 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, 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 83,111,117,110,100, 51, 68, 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, 70,114,101,101, 67, 97,109,101,114, 97, + 0, 83,112, 97, 99,101, 83,111,117,110,100, 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, 77,111,116,105,111,110, 80, 97, +116,104, 0, 98, 65,110,105,109, 86,105,122, 83,101,116,116,105,110,103,115, 0, 98, 80,111,115,101, 67,104, 97,110,110,101,108, + 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, 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, 77,105,110, 77, 97,120, 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, 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, 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, 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, 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, 0, 98, 78,111,100,101, 80,114, +101,118,105,101,119, 0, 98, 78,111,100,101, 84,121,112,101, 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, 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, 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, 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, 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, 97,116, 97, 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, 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, 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, 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,109, 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, 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, 68,114,105,118,101,114, 84, + 97,114,103,101,116, 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, 0, 0, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 0, 12, 0, + 8, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, 12, 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 20, 0, 76, 0, 52, 0, + 40, 2, 0, 0, 32, 0,140, 0,100, 3, 92, 0, 36, 0, 56, 0, 84, 0,112, 0,124, 0, 56, 0, 24, 0, 40, 0,120, 0, 12, 0, +120, 0, 36, 0, 92, 5,128, 1, 0, 0, 0, 0, 0, 0,144, 0, 40, 1, 84, 1, 24, 0, 8, 3,168, 0, 0, 0, 76, 0,128, 1, + 24, 1,140, 0,132, 0,124, 1, 8, 1, 56, 0, 88, 0,184, 2, 76, 0, 60, 1, 0, 0,108, 0,104, 0,148, 0, 56, 0, 8, 0, + 16, 0, 92, 1, 0, 0, 0, 0, 0, 0, 24, 1, 20, 0, 44, 0, 60, 0, 24, 0, 12, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0, + 24, 0, 76, 0, 32, 0, 8, 0, 12, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 12, 0, 0, 0, 16, 0, 64, 0, 24, 0, + 12, 0, 40, 0, 56, 0, 72, 0, 92, 0,100, 0, 72, 0,100, 0,120, 0, 68, 0, 64, 0,112, 0, 64, 0, 76, 0,176, 0, 48, 0, +168, 0,152, 0,156, 0, 64, 0, 96, 0,108, 0,188, 0,104, 0,216, 0, 56, 0, 84, 0, 0, 0,132, 0, 28, 0,240, 1,104, 0, + 0, 0, 80, 0, 0, 0, 0, 0, 68, 0, 8, 0, 8, 0,220, 0, 80, 0, 76, 0, 68, 0, 68, 0, 64, 0,164, 1,112, 0,108, 0, +188, 0, 40, 0, 0, 0, 92, 0, 56, 0, 72, 0,120, 0,128, 0,252, 0,208, 0, 0, 0, 92, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0,104, 1, 28, 0,176, 0,144, 0, 52, 0, 16, 0, 72, 0, 0, 4, 56, 0, 20, 0, 16, 0, 92, 0, 80, 0, 24, 0,196, 0, + 36, 0, 8, 0,100, 0, 80, 0, 48, 0, 52, 0, 72, 1, 32, 0, 8, 0, 24, 2, 0, 0, 0, 0, 56, 0,216, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,240, 0, 40, 0,148, 0, 48, 0,140, 0,208, 0, 20, 0,224, 0,216, 0,204, 1, 60, 0, 0, 0,112, 0, + 0, 0, 4, 1, 12, 0, 12, 0,136, 0,200, 0,124, 2, 80, 2, 40, 0,180, 0,244, 0, 52, 0,148, 2, 28, 0, 80, 0, 24, 0, + 16, 1, 32, 0,224, 0, 32, 0, 32, 0, 80, 2, 16, 1, 16, 0,200, 21, 56, 0, 56, 11, 20, 0, 24, 0, 56, 1, 0, 0, 0, 0, + 96, 0, 0, 0,248, 0, 0, 0, 32, 0, 80, 0, 28, 0, 16, 0, 8, 0, 52, 0,252, 0,240, 0,168, 1,196, 0, 8, 1, 48, 0, + 16, 0, 12, 0, 24, 0, 48, 0, 16, 0, 20, 0, 16, 0, 24, 0, 56, 1, 0, 0, 56, 0, 52, 0, 48, 0, 8, 0, 44, 0, 72, 0, +104, 0, 40, 0, 8, 0, 72, 0, 44, 0, 40, 0,108, 0, 68, 0, 76, 0, 80, 0, 60, 0,128, 0, 76, 0, 60, 0, 12, 0, 92, 0, + 68, 0, 32, 0, 80, 0, 16, 0, 76, 0,108, 0, 84, 0, 28, 0, 96, 0, 60, 0, 56, 0,108, 0,140, 0, 4, 0, 20, 0, 12, 0, + 8, 0, 40, 0,196, 0, 24, 0, 4, 1,124, 0, 16, 0, 20, 0, 24, 0,172, 1,104, 0,228, 0, 64, 0, 44, 0, 64, 0,116, 0, + 60, 0,104, 0, 52, 0, 44, 0, 44, 0, 68, 0, 44, 0, 64, 0, 44, 0, 20, 0, 52, 0, 96, 0, 12, 0,108, 0, 92, 0, 28, 0, + 28, 0, 28, 0, 52, 0, 20, 0, 60, 0,140, 0, 36, 0,120, 0, 32, 0,208, 0, 0, 0, 0, 0, 16, 0, 40, 0, 28, 0, 12, 0, + 12, 0, 16, 1, 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 8, 0, 24, 0, 32, 0, 8, 0, 32, 0, 12, 0, 44, 0, 20, 0, + 68, 0, 24, 0, 56, 0, 52, 0, 20, 0, 72, 0, 28, 0,180, 0,208, 1, 96, 0, 0, 0, 0, 0, 0, 0, 16, 0, 20, 0, 24, 0, +172, 0, 24, 0, 24, 0,140, 0,148, 0, 56, 0, 0, 0, 0, 0,100, 0, 0, 0, 92, 0, 0, 0, 88, 0, 20, 0, 24, 0, 16, 0, + 20, 0, 8, 0, 8, 0, 24, 0, 20, 0, 88, 0, 24, 1, 16, 0, 68, 0, 0, 1, 20, 0,160, 0, 88, 0, 96, 0, 88, 0, 20, 0, + 56, 0, 48, 0, 68, 0, 56, 0, 92, 0, 64, 0, 56, 0, 96, 0, 0, 0, 0, 0, 83, 84, 82, 67,126, 1, 0, 0, 10, 0, 2, 0, + 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 3, 0, 11, 0, 0, 0, 11, 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0, + 9, 0, 4, 0, 13, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, 14, 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0, + 7, 0, 5, 0, 7, 0, 6, 0, 16, 0, 2, 0, 8, 0, 5, 0, 8, 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0, + 4, 0, 7, 0, 18, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0, + 8, 0, 7, 0, 20, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0, + 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 8, 0, 22, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0, + 23, 0, 4, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 4, 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0, + 7, 0, 11, 0, 7, 0, 12, 0, 25, 0, 4, 0, 9, 0, 13, 0, 12, 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0, + 26, 0, 0, 0, 26, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19, 0, 0, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0, + 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0, + 2, 0, 28, 0, 2, 0, 19, 0, 4, 0, 29, 0, 26, 0, 30, 0, 28, 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0, + 0, 0, 34, 0, 0, 0, 35, 0, 4, 0, 36, 0, 4, 0, 37, 0, 28, 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0, + 2, 0, 41, 0, 2, 0, 42, 0, 2, 0, 43, 0, 4, 0, 44, 0, 31, 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, + 2, 0, 17, 0, 2, 0, 19, 0, 0, 0, 48, 0, 33, 0, 21, 0, 33, 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0, + 24, 0, 51, 0, 24, 0, 52, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0, + 2, 0, 19, 0, 2, 0, 57, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0, + 31, 0, 62, 0, 36, 0, 7, 0, 27, 0, 31, 0, 12, 0, 63, 0, 24, 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0, + 2, 0, 37, 0, 37, 0, 16, 0, 37, 0, 0, 0, 37, 0, 1, 0, 7, 0, 67, 0, 7, 0, 61, 0, 2, 0, 17, 0, 2, 0, 47, 0, + 2, 0, 68, 0, 2, 0, 19, 0, 4, 0, 69, 0, 4, 0, 70, 0, 9, 0, 2, 0, 7, 0, 71, 0, 0, 0, 20, 0, 0, 0, 72, 0, + 7, 0, 73, 0, 7, 0, 74, 0, 38, 0, 13, 0, 27, 0, 31, 0, 39, 0, 75, 0, 37, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0, + 7, 0, 61, 0, 12, 0, 79, 0, 36, 0, 80, 0, 27, 0, 81, 0, 2, 0, 17, 0, 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 19, 0, + 40, 0, 6, 0, 40, 0, 0, 0, 40, 0, 1, 0, 0, 0, 84, 0, 0, 0, 85, 0, 4, 0, 23, 0, 4, 0, 86, 0, 41, 0, 10, 0, + 41, 0, 0, 0, 41, 0, 1, 0, 4, 0, 87, 0, 4, 0, 88, 0, 4, 0, 89, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, 0, 90, 0, + 0, 0, 91, 0, 0, 0, 92, 0, 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 93, 0, 4, 0, 90, 0, 4, 0, 94, 0, 12, 0, 95, 0, + 40, 0, 96, 0, 40, 0, 97, 0, 4, 0, 98, 0, 4, 0, 99, 0, 12, 0,100, 0, 0, 0,101, 0, 4, 0,102, 0, 4, 0,103, 0, + 9, 0,104, 0, 8, 0,105, 0, 43, 0, 3, 0, 4, 0,106, 0, 4, 0,107, 0, 9, 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0, + 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 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, 2, 0,119, 0, 2, 0,120, 0, + 7, 0,121, 0, 36, 0, 80, 0, 32, 0,122, 0, 45, 0, 13, 0, 4, 0,123, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, + 2, 0,127, 0, 2, 0,128, 0, 2, 0, 19, 0, 2, 0,129, 0, 2, 0,130, 0, 2, 0,131, 0, 2, 0,132, 0, 2, 0,133, 0, + 46, 0,134, 0, 47, 0, 32, 0, 27, 0, 31, 0, 0, 0, 34, 0, 12, 0,135, 0, 48, 0,136, 0, 49, 0,137, 0, 50, 0,138, 0, + 2, 0,129, 0, 2, 0, 19, 0, 2, 0,139, 0, 2, 0, 17, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, 0,140, 0, 2, 0,141, 0, + 2, 0,142, 0, 2, 0,143, 0, 2, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 4, 0,147, 0, 4, 0,148, 0, 43, 0,149, 0, + 30, 0,150, 0, 0, 0,151, 0, 7, 0,152, 0, 4, 0,153, 0, 2, 0,154, 0, 2, 0,155, 0, 2, 0,156, 0, 2, 0,157, 0, + 7, 0,158, 0, 7, 0,159, 0, 51, 0, 33, 0, 2, 0,160, 0, 2, 0,161, 0, 2, 0,162, 0, 2, 0,163, 0, 32, 0,164, 0, + 52, 0,165, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 7, 0,171, 0, 7, 0,172, 0, + 7, 0,173, 0, 2, 0,174, 0, 2, 0,175, 0, 2, 0,176, 0, 2, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 0, 0,180, 0, + 0, 0,181, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0, 57, 0, 7, 0,187, 0, + 7, 0,188, 0, 7, 0,189, 0, 7, 0,190, 0, 7, 0,191, 0, 53, 0, 15, 0, 0, 0,192, 0, 9, 0,193, 0, 0, 0,194, 0, + 0, 0,195, 0, 4, 0,196, 0, 4, 0,197, 0, 9, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 7, 0,201, 0, 4, 0,202, 0, + 9, 0,203, 0, 9, 0,204, 0, 4, 0,205, 0, 4, 0, 37, 0, 54, 0, 6, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, + 7, 0,206, 0, 7, 0, 67, 0, 4, 0, 64, 0, 55, 0, 5, 0, 2, 0, 19, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0,207, 0, + 54, 0,201, 0, 56, 0, 17, 0, 32, 0,164, 0, 47, 0,208, 0, 57, 0,209, 0, 7, 0,210, 0, 7, 0,211, 0, 2, 0, 17, 0, + 2, 0,212, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,213, 0, 4, 0,214, 0, 2, 0,215, 0, 2, 0,216, 0, 4, 0,129, 0, + 4, 0,140, 0, 2, 0,217, 0, 2, 0,218, 0, 58, 0, 23, 0, 2, 0, 19, 0, 2, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0, + 2, 0,139, 0, 2, 0,222, 0, 4, 0,223, 0, 4, 0,224, 0, 32, 0,164, 0, 59, 0,225, 0, 2, 0,226, 0, 2, 0,227, 0, + 2, 0,228, 0, 9, 0,229, 0, 7, 0,230, 0, 7, 0,231, 0, 2, 0,232, 0, 2, 0,233, 0, 2, 0,234, 0, 2, 0,235, 0, + 7, 0,236, 0, 7, 0,237, 0, 55, 0,238, 0, 60, 0, 10, 0, 4, 0,239, 0, 4, 0,240, 0, 2, 0,241, 0, 2, 0, 19, 0, + 4, 0, 37, 0, 32, 0,164, 0, 7, 0,242, 0, 4, 0,243, 0, 0, 0,244, 0, 7, 0,245, 0, 52, 0, 61, 0, 27, 0, 31, 0, + 39, 0, 75, 0, 7, 0,246, 0, 7, 0,247, 0, 7, 0,248, 0, 7, 0,249, 0, 7, 0,250, 0, 7, 0,251, 0, 7, 0,252, 0, + 7, 0,253, 0, 7, 0,254, 0, 7, 0,255, 0, 7, 0, 0, 1, 7, 0, 1, 1, 7, 0, 2, 1, 7, 0, 3, 1, 7, 0, 4, 1, + 7, 0, 5, 1, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0, 8, 1, 7, 0, 9, 1, 2, 0, 10, 1, 2, 0, 11, 1, 2, 0, 12, 1, + 2, 0, 13, 1, 2, 0, 14, 1, 2, 0, 15, 1, 2, 0, 16, 1, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,212, 0, 7, 0, 17, 1, + 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1, 4, 0, 21, 1, 4, 0, 22, 1, 2, 0, 23, 1, 2, 0, 24, 1, 2, 0, 25, 1, + 2, 0,127, 0, 4, 0, 23, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 7, 0, 26, 1, 7, 0, 27, 1, 7, 0,188, 0, + 45, 0, 28, 1, 61, 0, 29, 1, 36, 0, 80, 0, 47, 0,208, 0, 53, 0, 30, 1, 55, 0,238, 0, 56, 0, 31, 1, 30, 0,150, 0, + 58, 0, 32, 1, 60, 0, 33, 1, 0, 0, 34, 1, 0, 0,181, 0, 62, 0, 8, 0, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0,172, 0, + 4, 0, 19, 0, 7, 0, 37, 1, 7, 0, 38, 1, 7, 0, 39, 1, 32, 0, 45, 0, 63, 0, 82, 0, 27, 0, 31, 0, 39, 0, 75, 0, + 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 40, 1, 2, 0,175, 0, 2, 0, 41, 1, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, + 7, 0,185, 0, 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, 7, 0, 52, 1, 64, 0, 53, 1, 2, 0,219, 0, 2, 0, 70, 0, 7, 0,110, 0, + 7, 0,111, 0, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, 2, 0, 57, 1, 2, 0, 58, 1, 2, 0, 59, 1, 2, 0, 60, 1, + 0, 0, 61, 1, 0, 0, 62, 1, 2, 0, 63, 1, 2, 0, 64, 1, 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 67, 1, 7, 0, 68, 1, + 7, 0, 69, 1, 7, 0, 70, 1, 7, 0, 71, 1, 2, 0, 72, 1, 2, 0, 43, 0, 2, 0, 73, 1, 2, 0, 74, 1, 2, 0, 75, 1, + 2, 0, 76, 1, 7, 0, 77, 1, 7, 0, 78, 1, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1, + 7, 0, 84, 1, 7, 0, 85, 1, 7, 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 2, 0, 89, 1, 2, 0, 90, 1, 4, 0, 91, 1, + 4, 0, 92, 1, 2, 0, 93, 1, 2, 0, 94, 1, 2, 0, 95, 1, 2, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, + 7, 0,100, 1, 2, 0,101, 1, 2, 0,102, 1, 36, 0, 80, 0, 51, 0,103, 1, 2, 0,104, 1, 2, 0,105, 1, 30, 0,150, 0, + 65, 0, 2, 0, 27, 0, 31, 0, 36, 0, 80, 0, 66, 0, 20, 0, 7, 0,106, 1, 7, 0,107, 1, 7, 0,108, 1, 7, 0,109, 1, + 7, 0,110, 1, 7, 0,111, 1, 7, 0,112, 1, 7, 0,113, 1, 2, 0,114, 1, 2, 0,115, 1, 7, 0,116, 1, 7, 0,117, 1, + 7, 0,118, 1, 2, 0,119, 1, 2, 0,120, 1, 2, 0,121, 1, 2, 0,122, 1, 7, 0,123, 1, 7, 0,124, 1, 4, 0,125, 1, + 67, 0,130, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,126, 1, 2, 0, 19, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, + 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, 7, 0,138, 1, 7, 0,139, 1, 7, 0,140, 1, 7, 0,141, 1, 7, 0,142, 1, + 7, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 7, 0,146, 1, 66, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, 7, 0,150, 1, + 7, 0,151, 1, 7, 0,152, 1, 7, 0,153, 1, 7, 0,154, 1, 2, 0,155, 1, 2, 0,156, 1, 2, 0,157, 1, 0, 0,158, 1, + 0, 0,159, 1, 7, 0,160, 1, 7, 0,161, 1, 2, 0,162, 1, 2, 0,163, 1, 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1, + 7, 0,167, 1, 2, 0,168, 1, 2, 0,169, 1, 4, 0, 40, 1, 4, 0,170, 1, 2, 0,171, 1, 2, 0,172, 1, 2, 0,173, 1, + 2, 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, 7, 0,184, 1, 0, 0,185, 1, 7, 0,186, 1, 7, 0,187, 1, 7, 0,188, 1, 4, 0,189, 1, + 0, 0,190, 1, 0, 0, 73, 1, 0, 0,191, 1, 0, 0, 34, 1, 2, 0,192, 1, 2, 0,193, 1, 2, 0,104, 1, 2, 0,194, 1, + 2, 0,195, 1, 2, 0,196, 1, 7, 0,197, 1, 7, 0,198, 1, 7, 0,199, 1, 7, 0,200, 1, 7, 0,201, 1, 2, 0,160, 0, + 2, 0,161, 0, 55, 0,202, 1, 55, 0,203, 1, 0, 0,204, 1, 0, 0,205, 1, 0, 0,206, 1, 0, 0,207, 1, 2, 0,208, 1, + 2, 0,209, 1, 7, 0,210, 1, 7, 0,211, 1, 51, 0,103, 1, 61, 0, 29, 1, 36, 0, 80, 0, 68, 0,212, 1, 30, 0,150, 0, + 7, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 7, 0,217, 1, 2, 0,218, 1, 2, 0, 70, 0, 7, 0,219, 1, + 7, 0,220, 1, 7, 0,221, 1, 7, 0,222, 1, 7, 0,223, 1, 7, 0,224, 1, 7, 0,225, 1, 7, 0,226, 1, 7, 0,227, 1, + 2, 0,228, 1, 2, 0,229, 1, 7, 0,230, 1, 7, 0,231, 1, 7, 0,232, 1, 7, 0,233, 1, 7, 0,234, 1, 4, 0,235, 1, + 4, 0,236, 1, 4, 0,237, 1, 12, 0,238, 1, 69, 0, 4, 0, 27, 0, 31, 0, 0, 0,239, 1, 70, 0, 2, 0, 43, 0,149, 0, + 71, 0, 26, 0, 71, 0, 0, 0, 71, 0, 1, 0, 72, 0,240, 1, 4, 0,241, 1, 4, 0,242, 1, 4, 0,243, 1, 4, 0,244, 1, + 4, 0,245, 1, 4, 0,246, 1, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,247, 1, 2, 0,248, 1, 7, 0, 5, 0, 7, 0, 6, 0, + 7, 0, 7, 0, 7, 0,249, 1, 7, 0,250, 1, 7, 0,251, 1, 7, 0,252, 1, 7, 0,253, 1, 7, 0,254, 1, 7, 0,255, 1, + 7, 0, 23, 0, 7, 0, 0, 2, 7, 0, 1, 2, 73, 0, 19, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0,240, 1, 12, 0, 2, 2, + 12, 0, 3, 2, 12, 0, 4, 2, 36, 0, 80, 0, 67, 0, 5, 2, 0, 0, 19, 0, 0, 0, 6, 2, 2, 0, 7, 2, 4, 0,174, 0, + 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 71, 0, 11, 2, 35, 0, 11, 0, + 7, 0, 12, 2, 7, 0, 13, 2, 7, 0, 14, 2, 7, 0,221, 0, 2, 0, 55, 0, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 17, 2, + 0, 0, 18, 2, 0, 0, 19, 2, 0, 0, 20, 2, 34, 0, 7, 0, 7, 0, 21, 2, 7, 0, 13, 2, 7, 0, 14, 2, 2, 0, 17, 2, + 2, 0, 20, 2, 7, 0,221, 0, 7, 0, 37, 0, 74, 0, 21, 0, 74, 0, 0, 0, 74, 0, 1, 0, 2, 0, 17, 0, 2, 0, 22, 2, + 2, 0, 20, 2, 2, 0, 19, 0, 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 27, 2, 2, 0, 28, 2, + 2, 0, 29, 2, 2, 0, 30, 2, 7, 0, 31, 2, 7, 0, 32, 2, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0, 33, 2, 2, 0, 34, 2, + 4, 0, 35, 2, 75, 0, 5, 0, 2, 0, 36, 2, 2, 0, 22, 2, 0, 0, 19, 0, 0, 0, 37, 0, 2, 0, 70, 0, 76, 0, 4, 0, + 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 8, 0, 7, 0, 37, 2, 77, 0, 67, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0,240, 1, + 12, 0, 38, 2, 12, 0, 3, 2, 12, 0, 39, 2, 32, 0, 40, 2, 32, 0, 41, 2, 32, 0, 42, 2, 36, 0, 80, 0, 78, 0, 43, 2, + 38, 0, 44, 2, 67, 0, 5, 2, 12, 0, 45, 2, 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 4, 0,174, 0, 2, 0, 46, 2, + 2, 0, 47, 2, 2, 0, 48, 2, 7, 0, 49, 2, 7, 0, 70, 0, 2, 0, 50, 2, 2, 0, 7, 2, 2, 0, 19, 0, 2, 0, 51, 2, + 7, 0, 52, 2, 7, 0, 53, 2, 7, 0, 54, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 55, 2, 2, 0, 56, 2, 4, 0, 57, 2, + 34, 0, 58, 2, 2, 0, 23, 0, 2, 0, 95, 0, 2, 0, 67, 0, 2, 0, 59, 2, 7, 0, 60, 2, 7, 0, 61, 2, 7, 0, 62, 2, + 7, 0, 63, 2, 7, 0, 64, 2, 7, 0, 65, 2, 7, 0, 66, 2, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 69, 2, 0, 0, 70, 2, + 79, 0, 71, 2, 80, 0, 72, 2, 0, 0, 73, 2, 69, 0, 74, 2, 69, 0, 75, 2, 69, 0, 76, 2, 69, 0, 77, 2, 4, 0, 78, 2, + 7, 0, 79, 2, 4, 0, 80, 2, 4, 0, 81, 2, 76, 0, 82, 2, 4, 0, 83, 2, 4, 0, 84, 2, 75, 0, 85, 2, 75, 0, 86, 2, + 81, 0, 39, 0, 27, 0, 31, 0, 72, 0,240, 1, 12, 0, 87, 2, 36, 0, 80, 0, 38, 0, 44, 2, 67, 0, 5, 2, 82, 0, 88, 2, + 83, 0, 89, 2, 84, 0, 90, 2, 85, 0, 91, 2, 86, 0, 92, 2, 87, 0, 93, 2, 88, 0, 94, 2, 89, 0, 95, 2, 81, 0, 96, 2, + 90, 0, 97, 2, 91, 0, 98, 2, 92, 0, 99, 2, 92, 0,100, 2, 92, 0,101, 2, 4, 0, 54, 0, 4, 0,102, 2, 4, 0,103, 2, + 4, 0,104, 2, 4, 0,105, 2, 4, 0,174, 0, 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 7, 0,106, 2, 4, 0, 46, 2, + 2, 0,107, 2, 2, 0, 19, 0, 2, 0,108, 2, 2, 0,109, 2, 2, 0, 7, 2, 2, 0,110, 2, 93, 0,111, 2, 94, 0,112, 2, + 84, 0, 8, 0, 9, 0,113, 2, 7, 0,114, 2, 4, 0,115, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, + 2, 0,118, 2, 82, 0, 7, 0, 4, 0,119, 2, 4, 0,120, 2, 4, 0,121, 2, 4, 0,122, 2, 2, 0, 22, 2, 0, 0,123, 2, + 0, 0, 19, 0, 86, 0, 5, 0, 4, 0,119, 2, 4, 0,120, 2, 0, 0,124, 2, 0, 0,125, 2, 2, 0, 19, 0, 95, 0, 2, 0, + 4, 0,126, 2, 7, 0, 14, 2, 87, 0, 3, 0, 95, 0,127, 2, 4, 0,128, 2, 4, 0, 19, 0, 85, 0, 6, 0, 7, 0,129, 2, + 2, 0,130, 2, 2, 0, 22, 2, 0, 0, 19, 0, 0, 0,125, 2, 0, 0, 48, 2, 88, 0, 4, 0, 0, 0,206, 0, 0, 0,182, 0, + 0, 0,183, 0, 0, 0,184, 0, 96, 0, 6, 0, 47, 0,113, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, + 2, 0,118, 2, 97, 0, 1, 0, 7, 0,131, 2, 98, 0, 5, 0, 0, 0,206, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0,184, 0, + 4, 0, 37, 0, 89, 0, 1, 0, 7, 0,132, 2, 90, 0, 2, 0, 4, 0,133, 2, 4, 0, 17, 0, 83, 0, 7, 0, 7, 0,114, 2, + 47, 0,113, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, 2, 0,118, 2, 99, 0, 1, 0, 7, 0,134, 2, +100, 0, 1, 0, 4, 0,135, 2,101, 0, 1, 0, 0, 0,136, 2,102, 0, 1, 0, 7, 0,114, 2,103, 0, 3, 0, 4, 0,137, 2, + 0, 0, 92, 0, 7, 0,138, 2,105, 0, 4, 0, 7, 0,206, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0,106, 0, 1, 0, +105, 0,115, 2,107, 0, 5, 0, 4, 0,139, 2, 4, 0,140, 2, 0, 0, 19, 0, 0, 0, 22, 2, 0, 0, 48, 2,108, 0, 2, 0, + 4, 0,141, 2, 4, 0,140, 2,109, 0, 10, 0,109, 0, 0, 0,109, 0, 1, 0,107, 0,142, 2,106, 0,143, 2,108, 0,144, 2, + 4, 0, 54, 0, 4, 0,103, 2, 4, 0,102, 2, 4, 0, 37, 0, 85, 0,145, 2, 93, 0, 14, 0, 12, 0,146, 2, 85, 0,145, 2, + 0, 0,147, 2, 0, 0,148, 2, 0, 0,149, 2, 0, 0,150, 2, 0, 0,151, 2, 0, 0,152, 2, 0, 0,153, 2, 0, 0, 19, 0, + 92, 0, 99, 2, 92, 0,101, 2, 2, 0,154, 2, 0, 0,155, 2, 94, 0, 8, 0, 4, 0,156, 2, 4, 0,157, 2, 82, 0,158, 2, + 86, 0,159, 2, 4, 0,103, 2, 4, 0,102, 2, 4, 0, 54, 0, 4, 0, 37, 0,110, 0, 7, 0,110, 0, 0, 0,110, 0, 1, 0, + 4, 0, 17, 0, 4, 0, 40, 1, 0, 0, 20, 0, 46, 0,134, 0, 0, 0,160, 2,111, 0, 7, 0,110, 0,161, 2, 2, 0,162, 2, + 2, 0,146, 2, 2, 0,163, 2, 2, 0, 90, 0, 9, 0,164, 2, 9, 0,165, 2,112, 0, 3, 0,110, 0,161, 2, 32, 0,164, 0, + 0, 0, 20, 0,113, 0, 5, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0, 20, 0, 2, 0,166, 2, 0, 0,167, 2,114, 0, 5, 0, +110, 0,161, 2, 7, 0, 88, 0, 7, 0,168, 2, 4, 0,169, 2, 4, 0,170, 2,115, 0, 5, 0,110, 0,161, 2, 32, 0,171, 2, + 0, 0, 72, 0, 4, 0, 40, 1, 4, 0, 19, 0,116, 0, 13, 0,110, 0,161, 2, 32, 0,172, 2, 32, 0,173, 2, 32, 0,174, 2, + 32, 0,175, 2, 7, 0,176, 2, 7, 0,177, 2, 7, 0,168, 2, 7, 0,178, 2, 4, 0,179, 2, 4, 0,180, 2, 4, 0, 90, 0, + 4, 0,181, 2,117, 0, 5, 0,110, 0,161, 2, 2, 0,182, 2, 2, 0, 19, 0, 7, 0,183, 2, 32, 0,184, 2,118, 0, 3, 0, +110, 0,161, 2, 7, 0,185, 2, 4, 0, 90, 0,119, 0, 10, 0,110, 0,161, 2, 7, 0,186, 2, 4, 0,187, 2, 4, 0, 37, 0, + 2, 0, 90, 0, 2, 0,188, 2, 2, 0,189, 2, 2, 0,190, 2, 7, 0,191, 2, 0, 0,192, 2,120, 0, 3, 0,110, 0,161, 2, + 7, 0, 37, 0, 4, 0, 17, 0,121, 0, 6, 0,110, 0,161, 2,122, 0,193, 2,123, 0,194, 2,124, 0,195, 2, 7, 0,196, 2, + 4, 0, 17, 0,125, 0, 11, 0,110, 0,161, 2, 52, 0,197, 2, 7, 0,198, 2, 4, 0,199, 2, 0, 0,192, 2, 7, 0,200, 2, + 4, 0,201, 2, 32, 0,202, 2, 0, 0,203, 2, 4, 0,204, 2, 4, 0, 37, 0,126, 0, 10, 0,110, 0,161, 2, 32, 0,205, 2, + 47, 0,206, 2, 4, 0, 90, 0, 4, 0,207, 2, 7, 0,208, 2, 7, 0,209, 2, 0, 0,203, 2, 4, 0,204, 2, 4, 0, 37, 0, +127, 0, 3, 0,110, 0,161, 2, 7, 0,210, 2, 4, 0,211, 2,128, 0, 5, 0,110, 0,161, 2, 7, 0,212, 2, 0, 0,192, 2, + 2, 0, 19, 0, 2, 0,213, 2,129, 0, 8, 0,110, 0,161, 2, 32, 0,164, 0, 7, 0,212, 2, 7, 0,221, 0, 7, 0,106, 0, + 0, 0,192, 2, 2, 0, 19, 0, 2, 0, 17, 0,130, 0, 21, 0,110, 0,161, 2, 32, 0,214, 2, 0, 0,192, 2, 52, 0,197, 2, + 32, 0,202, 2, 2, 0, 19, 0, 2, 0, 37, 0, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 7, 0, 52, 2, 7, 0,218, 2, + 7, 0,219, 2, 7, 0,220, 2, 7, 0,221, 2, 4, 0,201, 2, 4, 0,204, 2, 0, 0,203, 2, 7, 0,222, 2, 7, 0,223, 2, + 7, 0, 43, 0,131, 0, 7, 0,110, 0,161, 2, 2, 0,224, 2, 2, 0,225, 2, 4, 0, 70, 0, 32, 0,164, 0, 7, 0,226, 2, + 0, 0,192, 2,132, 0, 10, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0,227, 2, 7, 0,228, 2, 7, 0,229, 2, 7, 0,221, 2, + 4, 0,230, 2, 4, 0,231, 2, 7, 0,232, 2, 0, 0, 20, 0,133, 0, 1, 0,110, 0,161, 2,134, 0, 7, 0,110, 0,161, 2, + 46, 0,134, 0,135, 0,233, 2,136, 0,234, 2,137, 0,235, 2,138, 0,236, 2, 12, 0,237, 2,139, 0, 14, 0,110, 0,161, 2, + 85, 0,238, 2, 85, 0,239, 2, 85, 0,240, 2, 85, 0,241, 2, 85, 0,242, 2, 85, 0,243, 2, 82, 0,244, 2, 4, 0,245, 2, + 4, 0,246, 2, 2, 0,108, 1, 2, 0, 37, 0, 7, 0,196, 2,140, 0,247, 2,141, 0, 7, 0,110, 0,161, 2, 85, 0,238, 2, + 85, 0,248, 2,142, 0,249, 2,143, 0,247, 2, 4, 0,250, 2, 4, 0,245, 2,144, 0, 4, 0,110, 0,161, 2, 32, 0,164, 0, + 4, 0,251, 2, 4, 0, 37, 0,145, 0, 2, 0, 4, 0,252, 2, 7, 0, 14, 2,146, 0, 2, 0, 4, 0,125, 0, 4, 0,253, 2, +147, 0, 20, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0,192, 2, 2, 0,254, 2, 2, 0,255, 2, 2, 0, 19, 0, 2, 0, 37, 0, + 7, 0, 0, 3, 7, 0, 1, 3, 4, 0, 54, 0, 4, 0, 2, 3,146, 0, 3, 3,145, 0, 4, 3, 4, 0, 5, 3, 4, 0, 6, 3, + 4, 0, 7, 3, 4, 0,253, 2, 7, 0, 8, 3, 7, 0, 9, 3, 7, 0, 10, 3,148, 0, 8, 0,110, 0,161, 2, 59, 0,225, 0, +142, 0,249, 2, 4, 0, 11, 3, 4, 0, 12, 3, 4, 0, 13, 3, 2, 0, 19, 0, 2, 0, 57, 0,149, 0, 8, 0,110, 0,161, 2, + 32, 0, 45, 0, 2, 0, 14, 3, 2, 0, 19, 0, 2, 0,182, 2, 2, 0, 57, 0, 7, 0, 15, 3, 7, 0, 16, 3,150, 0, 5, 0, +110, 0,161, 2, 4, 0, 17, 3, 2, 0, 19, 0, 2, 0, 18, 3, 7, 0, 19, 3,151, 0, 7, 0,110, 0,161, 2, 85, 0, 20, 3, + 4, 0, 21, 3, 0, 0, 22, 3, 0, 0, 23, 3, 0, 0, 24, 3, 0, 0, 25, 3,152, 0, 3, 0,110, 0,161, 2,153, 0, 26, 3, +138, 0,236, 2,154, 0, 10, 0,110, 0,161, 2, 32, 0, 27, 3, 32, 0, 28, 3, 0, 0, 29, 3, 7, 0, 30, 3, 2, 0, 31, 3, + 2, 0, 32, 3, 0, 0, 33, 3, 0, 0, 34, 3, 0, 0,167, 2,155, 0, 9, 0,110, 0,161, 2, 32, 0, 35, 3, 0, 0, 29, 3, + 7, 0, 36, 3, 7, 0, 37, 3, 0, 0, 40, 1, 0, 0,182, 2, 0, 0, 38, 3, 0, 0, 37, 0,156, 0, 27, 0, 27, 0, 31, 0, + 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 39, 3, 2, 0, 19, 0, 2, 0, 40, 3, 2, 0, 41, 3, 2, 0, 42, 3, 2, 0, 70, 0, + 0, 0, 43, 3, 0, 0, 44, 3, 0, 0, 45, 3, 0, 0, 17, 0, 4, 0, 37, 0, 7, 0, 46, 3, 7, 0, 47, 3, 7, 0, 48, 3, + 7, 0, 49, 3, 7, 0, 50, 3, 7, 0, 51, 3, 34, 0, 52, 3, 36, 0, 80, 0, 38, 0, 44, 2, 87, 0, 93, 2, 7, 0, 53, 3, + 7, 0, 54, 3,156, 0, 55, 3,157, 0, 3, 0,157, 0, 0, 0,157, 0, 1, 0, 0, 0, 20, 0, 72, 0, 3, 0, 7, 0, 56, 3, + 4, 0, 19, 0, 4, 0, 37, 0, 32, 0,116, 0, 27, 0, 31, 0, 39, 0, 75, 0,158, 0, 57, 3, 2, 0, 17, 0, 2, 0, 58, 3, + 4, 0, 59, 3, 4, 0, 60, 3, 4, 0, 61, 3, 0, 0, 62, 3, 32, 0, 38, 0, 32, 0, 63, 3, 32, 0, 64, 3, 32, 0, 65, 3, + 32, 0, 66, 3, 36, 0, 80, 0, 78, 0, 43, 2, 72, 0,240, 1,159, 0, 67, 3,159, 0, 68, 3,160, 0, 69, 3, 9, 0, 2, 0, +161, 0, 70, 3, 12, 0, 71, 3, 12, 0, 87, 2, 12, 0, 3, 2, 12, 0, 72, 3, 12, 0, 73, 3, 4, 0, 40, 1, 4, 0, 74, 3, + 67, 0, 5, 2, 0, 0, 75, 3, 4, 0, 7, 2, 4, 0, 76, 3, 7, 0, 35, 1, 7, 0, 77, 3, 7, 0, 78, 3, 7, 0,172, 0, + 7, 0, 79, 3, 7, 0, 36, 1, 7, 0, 80, 3, 7, 0, 81, 3, 7, 0,228, 2, 7, 0, 82, 3, 7, 0,210, 0, 4, 0, 83, 3, + 2, 0, 19, 0, 2, 0, 84, 3, 2, 0, 85, 3, 2, 0, 86, 3, 2, 0, 87, 3, 2, 0, 88, 3, 2, 0, 89, 3, 2, 0, 90, 3, + 2, 0, 91, 3, 2, 0, 92, 3, 2, 0, 93, 3, 2, 0, 94, 3, 4, 0, 95, 3, 4, 0, 96, 3, 4, 0, 97, 3, 4, 0, 98, 3, + 7, 0, 99, 3, 7, 0, 79, 2, 7, 0,100, 3, 7, 0,101, 3, 7, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 7, 0,105, 3, + 7, 0,106, 3, 7, 0,107, 3, 7, 0,108, 3, 7, 0,109, 3, 0, 0,110, 3, 0, 0,111, 3, 0, 0,112, 3, 0, 0,113, 3, + 7, 0,114, 3, 7, 0,115, 3, 12, 0,116, 3, 12, 0,117, 3, 12, 0,118, 3, 12, 0,119, 3, 7, 0,120, 3, 2, 0,133, 2, + 2, 0,121, 3, 7, 0,115, 2, 4, 0,122, 3, 4, 0,123, 3,162, 0,124, 3, 2, 0,125, 3, 2, 0,217, 0, 7, 0,126, 3, + 12, 0,127, 3, 12, 0,128, 3, 12, 0,129, 3, 12, 0,130, 3,163, 0, 32, 1,164, 0,131, 3, 68, 0,132, 3, 2, 0,133, 3, + 2, 0,134, 3, 2, 0,135, 3, 2, 0,136, 3, 7, 0,107, 2, 2, 0,137, 3, 2, 0,138, 3,153, 0,139, 3,142, 0,140, 3, +142, 0,141, 3, 4, 0,142, 3, 4, 0,143, 3, 4, 0,144, 3, 4, 0, 70, 0, 12, 0,145, 3, 12, 0,146, 3,165, 0, 14, 0, +165, 0, 0, 0,165, 0, 1, 0, 32, 0, 38, 0, 7, 0,228, 2, 7, 0, 37, 1, 7, 0,229, 2, 7, 0,221, 2, 0, 0, 20, 0, + 4, 0,230, 2, 4, 0,231, 2, 4, 0,147, 3, 2, 0, 17, 0, 2, 0,148, 3, 7, 0,232, 2,163, 0, 36, 0, 2, 0,149, 3, + 2, 0,150, 3, 2, 0, 19, 0, 2, 0,221, 2, 7, 0,151, 3, 7, 0,152, 3, 7, 0,153, 3, 7, 0,154, 3, 7, 0,155, 3, + 7, 0,156, 3, 7, 0,157, 3, 7, 0,158, 3, 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, 7, 0,162, 3, 7, 0,163, 3, + 7, 0,164, 3, 7, 0,165, 3, 7, 0,166, 3, 7, 0,167, 3, 7, 0,168, 3, 7, 0,169, 3, 7, 0,170, 3, 7, 0,171, 3, + 7, 0,172, 3, 7, 0,173, 3, 7, 0,174, 3, 2, 0,175, 3, 2, 0,176, 3, 2, 0,177, 3, 2, 0,178, 3, 52, 0,165, 0, +166, 0,179, 3, 7, 0,180, 3, 4, 0,170, 2,167, 0, 9, 0,167, 0, 0, 0,167, 0, 1, 0, 4, 0,181, 3, 4, 0,182, 3, + 4, 0,183, 3, 4, 0, 19, 0, 4, 0,184, 3, 9, 0,185, 3, 9, 0,186, 3,138, 0, 19, 0,138, 0, 0, 0,138, 0, 1, 0, + 4, 0, 19, 0, 4, 0,187, 3, 4, 0,188, 3, 4, 0,189, 3, 4, 0,190, 3, 4, 0,191, 3, 4, 0,192, 3, 4, 0,182, 3, + 4, 0,133, 2, 4, 0, 57, 0, 0, 0,193, 3, 0, 0,194, 3, 0, 0,195, 3, 0, 0,196, 3, 12, 0,197, 3,168, 0,198, 3, + 9, 0,199, 3,169, 0, 1, 0, 7, 0, 21, 2,162, 0, 30, 0, 4, 0, 19, 0, 7, 0,200, 3, 7, 0,201, 3, 7, 0,202, 3, + 4, 0,203, 3, 4, 0,204, 3, 4, 0,205, 3, 4, 0,206, 3, 7, 0,207, 3, 7, 0,208, 3, 7, 0,209, 3, 7, 0,210, 3, + 7, 0,211, 3, 7, 0,212, 3, 7, 0,213, 3, 7, 0,214, 3, 7, 0,215, 3, 7, 0,216, 3, 7, 0,217, 3, 7, 0,218, 3, + 7, 0,219, 3, 7, 0,220, 3, 7, 0,221, 3, 7, 0,222, 3, 7, 0,223, 3, 7, 0,224, 3, 4, 0,225, 3, 4, 0,226, 3, + 7, 0,227, 3, 7, 0,106, 3,164, 0, 49, 0, 4, 0,182, 3, 4, 0,228, 3,170, 0,229, 3,171, 0,230, 3, 0, 0, 37, 0, + 0, 0,231, 3, 2, 0,232, 3, 7, 0,233, 3, 0, 0,234, 3, 7, 0,235, 3, 7, 0,236, 3, 7, 0,237, 3, 7, 0,238, 3, + 7, 0,239, 3, 7, 0,240, 3, 7, 0,241, 3, 7, 0,242, 3, 7, 0,243, 3, 2, 0,244, 3, 0, 0,245, 3, 2, 0,246, 3, + 7, 0,247, 3, 7, 0,248, 3, 0, 0,249, 3, 4, 0,126, 0, 4, 0,250, 3, 4, 0,251, 3, 2, 0,252, 3, 2, 0,253, 3, +169, 0,254, 3, 4, 0,255, 3, 4, 0, 82, 0, 7, 0, 0, 4, 7, 0, 1, 4, 7, 0, 2, 4, 7, 0, 3, 4, 2, 0, 4, 4, + 2, 0, 5, 4, 2, 0, 6, 4, 2, 0, 7, 4, 2, 0, 8, 4, 2, 0, 9, 4, 2, 0, 10, 4, 2, 0, 11, 4,172, 0, 12, 4, + 7, 0, 13, 4, 7, 0, 14, 4,138, 0, 15, 4, 12, 0,237, 2,153, 0, 48, 0, 2, 0, 17, 0, 2, 0, 16, 4, 2, 0, 17, 4, + 2, 0, 18, 4, 7, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 7, 0, 22, 4, 2, 0, 23, 4, 2, 0, 24, 4, 7, 0, 25, 4, + 7, 0, 26, 4, 7, 0, 27, 4, 7, 0, 28, 4, 7, 0, 29, 4, 7, 0, 30, 4, 4, 0, 31, 4, 7, 0, 32, 4, 7, 0, 33, 4, + 7, 0, 34, 4, 81, 0, 35, 4, 81, 0, 36, 4, 81, 0, 37, 4, 0, 0, 38, 4, 7, 0, 39, 4, 7, 0, 40, 4, 36, 0, 80, 0, + 2, 0, 41, 4, 0, 0, 42, 4, 0, 0, 43, 4, 7, 0, 44, 4, 4, 0, 45, 4, 7, 0, 46, 4, 7, 0, 47, 4, 4, 0, 48, 4, + 4, 0, 19, 0, 7, 0, 49, 4, 7, 0, 50, 4, 7, 0, 51, 4, 85, 0, 52, 4, 7, 0, 53, 4, 7, 0, 54, 4, 7, 0, 55, 4, + 7, 0, 56, 4, 7, 0, 57, 4, 7, 0, 58, 4, 7, 0, 59, 4, 4, 0, 60, 4,173, 0, 73, 0, 27, 0, 31, 0, 39, 0, 75, 0, + 2, 0,175, 0, 2, 0, 41, 1, 2, 0, 73, 1, 2, 0, 61, 4, 7, 0, 62, 4, 7, 0, 63, 4, 7, 0, 64, 4, 7, 0, 65, 4, + 7, 0, 66, 4, 7, 0, 67, 4, 7, 0, 68, 4, 7, 0, 69, 4, 7, 0,133, 1, 7, 0,135, 1, 7, 0,134, 1, 7, 0, 70, 4, + 4, 0, 71, 4, 7, 0, 72, 4, 7, 0, 73, 4, 7, 0, 74, 4, 7, 0, 75, 4, 7, 0, 76, 4, 7, 0, 77, 4, 7, 0, 78, 4, + 2, 0, 79, 4, 2, 0, 40, 1, 2, 0, 80, 4, 2, 0, 81, 4, 2, 0, 82, 4, 2, 0, 83, 4, 2, 0, 84, 4, 2, 0, 85, 4, + 7, 0, 86, 4, 7, 0, 87, 4, 7, 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, 2, 0, 98, 4, 2, 0, 99, 4, 2, 0,100, 4, 2, 0,101, 4, + 7, 0,102, 4, 7, 0,103, 4, 7, 0,104, 4, 7, 0,105, 4, 2, 0,106, 4, 2, 0,107, 4, 2, 0,108, 4, 2, 0,109, 4, + 7, 0,110, 4, 7, 0,111, 4, 7, 0,112, 4, 7, 0,113, 4, 2, 0,114, 4, 2, 0,115, 4, 2, 0,116, 4, 2, 0, 19, 0, + 7, 0,117, 4, 7, 0,118, 4, 36, 0, 80, 0, 51, 0,103, 1, 2, 0,104, 1, 2, 0,105, 1, 30, 0,150, 0,174, 0, 8, 0, +174, 0, 0, 0,174, 0, 1, 0, 4, 0, 83, 3, 4, 0,119, 4, 4, 0, 19, 0, 2, 0,120, 4, 2, 0,121, 4, 32, 0,164, 0, +175, 0, 13, 0, 9, 0,122, 4, 9, 0,123, 4, 4, 0,124, 4, 4, 0,125, 4, 4, 0,126, 4, 4, 0,127, 4, 4, 0,128, 4, + 4, 0,129, 4, 4, 0,130, 4, 4, 0,131, 4, 4, 0,132, 4, 4, 0, 37, 0, 0, 0,133, 4,176, 0, 5, 0, 9, 0,134, 4, + 9, 0,135, 4, 4, 0,136, 4, 4, 0, 70, 0, 0, 0,137, 4,177, 0, 13, 0, 4, 0, 17, 0, 4, 0,138, 4, 4, 0,139, 4, + 4, 0,140, 4, 4, 0,141, 4, 4, 0,142, 4, 4, 0, 90, 0, 4, 0,143, 4, 4, 0,144, 4, 4, 0,145, 4, 4, 0,146, 4, + 4, 0,147, 4, 26, 0, 30, 0,178, 0, 4, 0, 4, 0,148, 4, 7, 0,149, 4, 2, 0, 19, 0, 2, 0,105, 1,179, 0, 11, 0, +179, 0, 0, 0,179, 0, 1, 0, 0, 0, 20, 0, 67, 0,150, 4, 68, 0,151, 4, 4, 0, 83, 3, 4, 0,152, 4, 4, 0,153, 4, + 4, 0, 37, 0, 4, 0,154, 4, 4, 0,155, 4,180, 0,132, 0,175, 0,156, 4,176, 0,157, 4,177, 0,158, 4,178, 0,159, 4, + 4, 0,250, 2, 4, 0,126, 0, 4, 0,250, 3, 4, 0,160, 4, 4, 0,161, 4, 4, 0,162, 4, 4, 0,163, 4, 2, 0, 19, 0, + 2, 0,164, 4, 7, 0, 79, 2, 7, 0,165, 4, 7, 0,166, 4, 7, 0,167, 4, 7, 0,168, 4, 7, 0,169, 4, 2, 0,170, 4, + 2, 0,171, 4, 2, 0,172, 4, 2, 0,173, 4, 2, 0,216, 0, 2, 0,174, 4, 2, 0,175, 4, 2, 0,178, 3, 2, 0,176, 4, + 2, 0,177, 4, 2, 0, 60, 1, 2, 0,106, 0, 2, 0,178, 4, 2, 0,179, 4, 2, 0,180, 4, 2, 0,181, 4, 2, 0,182, 4, + 2, 0,183, 4, 2, 0,184, 4, 2, 0,185, 4, 2, 0,186, 4, 2, 0, 61, 1, 2, 0,187, 4, 2, 0,188, 4, 2, 0,189, 4, + 2, 0,190, 4, 4, 0,191, 4, 4, 0, 40, 1, 2, 0,192, 4, 2, 0,193, 4, 2, 0,194, 4, 2, 0,195, 4, 2, 0,196, 4, + 2, 0,197, 4, 24, 0,198, 4, 24, 0,199, 4, 23, 0,200, 4, 12, 0,201, 4, 2, 0,202, 4, 2, 0, 37, 0, 7, 0,203, 4, + 7, 0,204, 4, 7, 0,205, 4, 7, 0,206, 4, 4, 0,207, 4, 7, 0,208, 4, 7, 0,209, 4, 7, 0,210, 4, 7, 0,211, 4, + 2, 0,212, 4, 2, 0,213, 4, 2, 0,214, 4, 2, 0,215, 4, 2, 0,216, 4, 2, 0,217, 4, 7, 0,218, 4, 7, 0,219, 4, + 7, 0,220, 4, 2, 0,221, 4, 2, 0,222, 4, 2, 0,223, 4, 2, 0,224, 4, 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4, + 2, 0,228, 4, 2, 0,229, 4, 2, 0,230, 4, 4, 0,231, 4, 4, 0,232, 4, 4, 0,233, 4, 4, 0,234, 4, 4, 0,235, 4, + 7, 0,236, 4, 4, 0,237, 4, 4, 0,238, 4, 4, 0,239, 4, 4, 0,240, 4, 7, 0,241, 4, 7, 0,242, 4, 7, 0,243, 4, + 7, 0,244, 4, 7, 0,245, 4, 7, 0,246, 4, 7, 0,247, 4, 7, 0,248, 4, 7, 0,249, 4, 0, 0,250, 4, 0, 0,251, 4, + 4, 0,252, 4, 2, 0,253, 4, 2, 0,209, 1, 0, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 4, 0, 1, 5, 4, 0, 2, 5, + 7, 0, 3, 5, 7, 0, 4, 5, 2, 0, 5, 5, 2, 0, 6, 5, 7, 0, 7, 5, 2, 0, 8, 5, 2, 0, 9, 5, 4, 0, 10, 5, + 2, 0, 11, 5, 2, 0, 12, 5, 2, 0, 13, 5, 2, 0, 14, 5, 7, 0, 15, 5, 7, 0, 70, 0, 42, 0, 16, 5, 0, 0, 17, 5, +181, 0, 9, 0,181, 0, 0, 0,181, 0, 1, 0, 0, 0, 20, 0, 2, 0, 18, 5, 2, 0, 19, 5, 2, 0, 20, 5, 2, 0, 43, 0, + 7, 0, 21, 5, 7, 0, 70, 0,182, 0, 7, 0, 2, 0,187, 2, 2, 0, 40, 1, 2, 0,109, 0, 2, 0, 22, 5, 7, 0, 23, 5, + 7, 0, 70, 0, 42, 0, 24, 5,183, 0, 5, 0, 7, 0, 25, 5, 0, 0, 17, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0,209, 1, +184, 0, 26, 0, 7, 0, 77, 4, 7, 0, 78, 4, 2, 0, 40, 1, 2, 0, 19, 0, 2, 0, 26, 5, 2, 0,105, 1, 2, 0, 80, 4, + 2, 0, 81, 4, 2, 0, 82, 4, 2, 0, 83, 4, 2, 0, 84, 4, 2, 0, 85, 4,183, 0, 27, 5, 2, 0,170, 4, 2, 0,171, 4, + 2, 0,172, 4, 2, 0,173, 4, 2, 0,216, 0, 2, 0,174, 4, 2, 0,175, 4, 2, 0,178, 3,182, 0, 28, 5, 2, 0, 29, 5, + 2, 0,176, 4, 2, 0,179, 4, 2, 0,180, 4,185, 0, 5, 0,185, 0, 0, 0,185, 0, 1, 0, 4, 0,181, 3, 0, 0,193, 3, + 4, 0, 19, 0,186, 0, 6, 0,187, 0, 30, 5, 4, 0, 31, 5, 4, 0, 32, 5, 9, 0, 33, 5, 0, 0, 34, 5, 4, 0, 37, 0, +188, 0, 6, 0,186, 0, 35, 5, 2, 0, 19, 0, 2, 0, 36, 5, 2, 0, 37, 5, 2, 0, 38, 5, 9, 0, 39, 5,189, 0, 4, 0, + 2, 0,106, 0, 2, 0,198, 2, 2, 0,187, 3, 2, 0, 40, 5,190, 0, 14, 0, 2, 0, 19, 0, 2, 0, 41, 5, 2, 0, 42, 5, + 2, 0, 43, 5,189, 0, 44, 5, 9, 0, 39, 5, 7, 0, 45, 5, 7, 0, 57, 0, 4, 0, 46, 5, 4, 0, 47, 5, 4, 0, 48, 5, + 4, 0, 49, 5, 46, 0,134, 0, 32, 0,164, 0,191, 0, 4, 0,191, 0, 0, 0,191, 0, 1, 0, 0, 0, 50, 5, 7, 0, 51, 5, +192, 0, 6, 0,186, 0, 35, 5, 7, 0, 52, 5, 4, 0, 90, 0, 0, 0, 53, 5, 0, 0, 54, 5, 0, 0,167, 2,193, 0, 9, 0, +186, 0, 35, 5, 7, 0, 55, 5, 7, 0, 56, 5, 2, 0, 40, 1, 2, 0, 19, 0, 4, 0, 36, 0, 4, 0, 57, 5, 87, 0, 58, 5, + 9, 0, 39, 5,194, 0, 72, 0,193, 0, 59, 5,193, 0, 60, 5,192, 0, 57, 3, 7, 0, 61, 5, 2, 0, 62, 5, 2, 0, 63, 5, + 7, 0, 64, 5, 7, 0, 65, 5, 2, 0,187, 3, 2, 0, 66, 5, 7, 0, 67, 5, 7, 0, 68, 5, 7, 0, 69, 5, 2, 0, 70, 5, + 2, 0, 46, 5, 2, 0, 71, 5, 2, 0, 72, 5, 2, 0, 73, 5, 2, 0, 74, 5, 7, 0, 75, 5, 7, 0, 76, 5, 7, 0, 77, 5, + 2, 0, 78, 5, 2, 0, 79, 5, 2, 0, 80, 5, 2, 0, 81, 5, 2, 0, 82, 5, 2, 0, 83, 5, 2, 0, 84, 5,188, 0, 85, 5, +190, 0, 86, 5, 7, 0, 87, 5, 7, 0, 88, 5, 7, 0, 89, 5, 2, 0, 90, 5, 2, 0, 91, 5, 0, 0, 92, 5, 0, 0, 93, 5, + 0, 0, 94, 5, 0, 0, 95, 5, 0, 0, 96, 5, 0, 0, 97, 5, 2, 0, 98, 5, 7, 0, 99, 5, 7, 0,100, 5, 7, 0,101, 5, + 7, 0,102, 5, 7, 0,103, 5, 7, 0,104, 5, 7, 0,105, 5, 7, 0,106, 5, 7, 0,107, 5, 7, 0,108, 5, 2, 0,109, 5, + 0, 0,110, 5, 0, 0,111, 5, 0, 0,112, 5, 0, 0,113, 5, 32, 0,114, 5, 0, 0,115, 5, 0, 0,116, 5, 0, 0,117, 5, + 0, 0,118, 5, 0, 0,119, 5, 0, 0,120, 5, 0, 0,121, 5, 0, 0,122, 5, 2, 0,123, 5, 2, 0,124, 5, 2, 0,125, 5, + 2, 0,126, 5, 2, 0,127, 5,195, 0, 8, 0, 4, 0,128, 5, 4, 0,129, 5, 4, 0,130, 5, 4, 0,131, 5, 4, 0,132, 5, + 4, 0,133, 5, 4, 0, 54, 0, 4, 0,103, 2,196, 0, 3, 0, 7, 0,134, 5, 2, 0,135, 5, 2, 0, 19, 0, 46, 0, 37, 0, + 27, 0, 31, 0, 39, 0, 75, 0, 32, 0,136, 5,173, 0,137, 5, 46, 0,138, 5, 47, 0,208, 0, 12, 0,139, 5,174, 0,140, 5, + 32, 0,141, 5, 7, 0,142, 5, 7, 0,143, 5, 7, 0,144, 5, 7, 0,145, 5, 4, 0, 83, 3, 2, 0, 19, 0, 2, 0, 34, 1, + 61, 0, 29, 1,197, 0,146, 5,194, 0,147, 5,198, 0,148, 5,180, 0,182, 0,178, 0,159, 4, 12, 0,100, 0, 12, 0,149, 5, + 12, 0,150, 5,199, 0,151, 5, 2, 0,152, 5, 2, 0,153, 5, 2, 0,217, 0, 2, 0,154, 5, 4, 0,155, 5, 4, 0,156, 5, + 12, 0,157, 5,183, 0, 27, 5,184, 0,158, 5,196, 0,159, 5,161, 0, 70, 3,200, 0, 6, 0, 47, 0,208, 0, 45, 0, 28, 1, + 7, 0, 67, 2, 7, 0, 68, 2, 7, 0,106, 0, 7, 0,160, 5,201, 0, 35, 0, 7, 0,161, 5, 7, 0,162, 5, 7, 0,163, 5, + 7, 0,164, 5, 7, 0,165, 5, 7, 0,166, 5, 7, 0,167, 5, 7, 0,168, 5, 7, 0,169, 5, 7, 0, 47, 1, 7, 0,170, 5, + 7, 0,171, 5, 7, 0,172, 5, 7, 0,173, 5, 7, 0,171, 0, 2, 0,174, 5, 2, 0,175, 5, 4, 0,176, 5, 2, 0,177, 5, + 2, 0,178, 5, 2, 0,179, 5, 2, 0,180, 5, 7, 0,181, 5, 72, 0,182, 5,161, 0, 70, 3,201, 0,183, 5,202, 0,184, 5, +203, 0,185, 5,204, 0,186, 5,205, 0,187, 5,206, 0,188, 5, 7, 0,189, 5, 2, 0,190, 5, 2, 0,191, 5, 4, 0,209, 1, +207, 0, 54, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 7, 0,169, 5, + 7, 0, 47, 1, 7, 0, 43, 0, 4, 0,196, 5, 2, 0,179, 5, 2, 0,180, 5, 32, 0,136, 5, 32, 0,197, 5,200, 0,198, 5, +207, 0,183, 5, 0, 0,199, 5, 4, 0, 83, 3, 4, 0,200, 5, 2, 0,201, 5, 2, 0,202, 5, 2, 0,203, 5, 2, 0,204, 5, + 2, 0,209, 1, 2, 0, 19, 0, 2, 0, 6, 2, 2, 0,205, 5, 7, 0,112, 0, 7, 0,206, 5, 7, 0,207, 5, 7, 0,208, 5, + 7, 0,209, 5, 7, 0,210, 5, 7, 0,171, 0, 7, 0,142, 5, 2, 0,211, 5, 2, 0, 90, 1, 2, 0,212, 5, 2, 0,213, 5, + 2, 0,214, 5, 2, 0,215, 5, 2, 0,216, 5, 2, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5, 4, 0,220, 5, 12, 0,221, 5, + 2, 0,222, 5, 2, 0,116, 2, 2, 0,223, 5, 0, 0,224, 5, 0, 0,225, 5, 9, 0,226, 5,161, 0, 70, 3,209, 0, 25, 0, + 24, 0, 36, 0, 24, 0, 64, 0, 23, 0,227, 5, 23, 0,228, 5, 23, 0,229, 5, 7, 0,230, 5, 7, 0,231, 5, 7, 0,232, 5, + 7, 0,233, 5, 2, 0,234, 5, 2, 0,235, 5, 2, 0,236, 5, 2, 0,237, 5, 2, 0,238, 5, 2, 0, 19, 0, 2, 0,239, 5, + 2, 0,240, 5, 2, 0,241, 5, 2, 0,242, 5, 2, 0,243, 5, 2, 0,204, 5, 7, 0,244, 5, 7, 0,245, 5, 4, 0,246, 5, + 4, 0,247, 5,208, 0, 6, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, +210, 0, 8, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,211, 0,248, 5, + 46, 0,134, 0,212, 0, 14, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, +209, 0,249, 5,213, 0,250, 5, 12, 0,251, 5, 2, 0, 40, 1, 2, 0, 19, 0, 2, 0,252, 5, 0, 0,253, 5, 0, 0,254, 5, +214, 0, 20, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,202, 0,184, 5, +209, 0,249, 5, 2, 0,255, 5, 2, 0, 0, 6, 2, 0, 1, 6, 2, 0, 2, 6, 2, 0,239, 5, 2, 0, 3, 6, 0, 0, 19, 0, + 0, 0,105, 1, 9, 0, 43, 2, 4, 0, 4, 6, 4, 0, 5, 6, 27, 0, 6, 6,215, 0, 16, 0,208, 0, 0, 0,208, 0, 1, 0, + 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, 7, 0, 67, 2, 7, 0, 68, 2, 2, 0,255, 5, + 2, 0, 7, 6, 2, 0, 8, 6, 2, 0, 9, 6, 4, 0, 19, 0, 7, 0, 10, 6,161, 0, 70, 3,216, 0, 16, 0, 0, 0, 11, 6, + 0, 0, 12, 6, 0, 0, 13, 6, 0, 0, 14, 6, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 15, 6, 2, 0, 16, 6, 2, 0,152, 1, + 2, 0, 17, 6, 4, 0, 18, 6, 4, 0, 19, 6, 2, 0, 20, 6, 2, 0, 21, 6, 0, 0, 22, 6, 0, 0, 23, 6,217, 0, 16, 0, +208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 4, 0, 37, 0,216, 0, 24, 6,218, 0, 25, 6, 12, 0, 26, 6, + 12, 0, 27, 6,219, 0, 28, 6,206, 0, 29, 6,220, 0, 30, 6, 2, 0, 31, 6, 2, 0, 32, 6, 2, 0, 33, 6, 2, 0, 70, 0, +221, 0, 17, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, + 12, 0, 34, 6,222, 0, 35, 6, 0, 0, 36, 6,223, 0, 37, 6, 4, 0, 38, 6, 4, 0, 39, 6, 2, 0, 19, 0, 2, 0, 40, 6, + 2, 0, 41, 6, 2, 0, 37, 0,224, 0, 29, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, + 2, 0,195, 5, 47, 0,206, 2, 45, 0, 28, 1, 64, 0, 42, 6, 2, 0,133, 0, 2, 0, 43, 6, 2, 0, 70, 0, 2, 0, 44, 6, + 4, 0, 19, 0, 2, 0, 45, 6, 2, 0,254, 5, 2, 0,253, 5, 2, 0,209, 1, 0, 0, 46, 6, 0, 0, 47, 6, 0, 0, 48, 6, + 0, 0,204, 5, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 10, 6, 7, 0, 90, 1, 7, 0, 49, 6, 7, 0, 50, 6,161, 0, 70, 3, +225, 0, 11, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 2, 0,252, 5, + 2, 0, 19, 0, 4, 0, 37, 0,213, 0,250, 5,209, 0,249, 5,226, 0, 27, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, + 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 42, 0, 51, 6, 4, 0, 52, 6, 4, 0, 53, 6, 2, 0, 90, 0, 2, 0,133, 0, + 2, 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, 62, 6, 7, 0, 63, 6, 23, 0, 64, 6, 23, 0, 65, 6, 4, 0, 66, 6, 4, 0, 67, 6, 0, 0, 68, 6, 0, 0, 69, 6, +227, 0, 10, 0, 27, 0, 31, 0, 9, 0, 70, 6, 9, 0, 71, 6, 9, 0, 72, 6, 9, 0, 73, 6, 9, 0, 74, 6, 4, 0, 90, 0, + 4, 0, 75, 6, 0, 0, 76, 6, 0, 0, 77, 6,228, 0, 10, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, + 7, 0,194, 5,227, 0, 78, 6, 2, 0, 90, 0, 2, 0,133, 0, 4, 0, 43, 0, 9, 0, 79, 6,229, 0, 8, 0,208, 0, 0, 0, +208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,209, 0,249, 5, 4, 0, 19, 0, 4, 0, 80, 6,230, 0, 23, 0, +208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, 27, 0, 81, 6, + 27, 0, 81, 0, 2, 0, 19, 0, 2, 0,133, 0, 7, 0, 82, 6, 9, 0, 83, 6, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 84, 6, + 7, 0, 85, 6, 61, 0, 29, 1, 61, 0, 86, 6, 4, 0, 87, 6, 2, 0, 88, 6, 2, 0, 37, 0,161, 0, 70, 3,231, 0, 10, 0, +208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 2, 0, 19, 0, 2, 0, 92, 3, + 4, 0, 37, 0,161, 0, 70, 3,232, 0, 42, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, + 2, 0,195, 5,209, 0,249, 5,218, 0, 25, 6, 0, 0, 11, 6, 0, 0, 12, 6, 0, 0, 13, 6, 2, 0, 17, 0, 2, 0, 21, 6, + 2, 0, 19, 0, 2, 0, 15, 6, 9, 0, 83, 6, 4, 0, 18, 6, 4, 0, 89, 6, 4, 0, 90, 6, 4, 0, 19, 6, 23, 0, 91, 6, + 23, 0, 92, 6, 7, 0, 93, 6, 7, 0, 94, 6, 7, 0, 95, 6, 7, 0, 82, 6, 2, 0, 96, 6, 2, 0,207, 0, 2, 0,152, 1, + 2, 0, 17, 6, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 97, 6, 2, 0, 98, 6, 9, 0, 99, 6, 9, 0,100, 6, 9, 0,101, 6, + 9, 0,102, 6, 9, 0,103, 6, 2, 0,104, 6, 0, 0, 23, 6, 57, 0,105, 6,233, 0, 7, 0,233, 0, 0, 0,233, 0, 1, 0, + 4, 0,106, 6, 4, 0, 23, 0, 0, 0, 84, 0, 4, 0,107, 6, 4, 0, 17, 0,234, 0, 13, 0,208, 0, 0, 0,208, 0, 1, 0, + 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 4, 0, 17, 0, 4, 0,108, 6, 4, 0, 19, 0, 4, 0, 54, 6, + 12, 0,109, 6, 12, 0,110, 6, 0, 0,111, 6,235, 0, 5, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, + 4, 0, 37, 0,236, 0, 7, 0,236, 0, 0, 0,236, 0, 1, 0, 0, 0,112, 6, 2, 0,113, 6, 2, 0,114, 6, 2, 0,115, 6, + 2, 0, 37, 0,237, 0, 12, 0, 2, 0,114, 6, 2, 0,116, 6, 2, 0,117, 6, 0, 0,167, 2, 2, 0,118, 6, 2, 0,119, 6, + 2, 0,120, 6, 2, 0,121, 6, 2, 0,122, 6, 2, 0,239, 5, 7, 0,123, 6, 7, 0,124, 6,238, 0, 18, 0,238, 0, 0, 0, +238, 0, 1, 0, 0, 0,193, 3,237, 0,125, 6,237, 0,126, 6,237, 0,127, 6,237, 0,128, 6, 7, 0,129, 6, 2, 0,130, 6, + 2, 0,131, 6, 2, 0,132, 6, 2, 0,133, 6, 2, 0,134, 6, 2, 0,135, 6, 2, 0,136, 6, 2, 0,137, 6, 2, 0,138, 6, + 2, 0,139, 6,239, 0, 10, 0, 0, 0,140, 6, 0, 0,141, 6, 0, 0,142, 6, 0, 0,143, 6, 0, 0,144, 6, 0, 0,145, 6, + 2, 0,146, 6, 2, 0,147, 6, 2, 0,148, 6, 2, 0, 37, 0,240, 0, 8, 0, 0, 0,149, 6, 0, 0,150, 6, 0, 0,151, 6, + 0, 0,152, 6, 0, 0,153, 6, 0, 0,154, 6, 7, 0,160, 5, 7, 0, 37, 0,241, 0, 17, 0,239, 0,155, 6,239, 0,156, 6, +239, 0,157, 6,239, 0,158, 6,239, 0,159, 6,239, 0,160, 6,239, 0,161, 6,239, 0,162, 6,239, 0,163, 6,239, 0,164, 6, +239, 0,165, 6,239, 0,166, 6,239, 0,167, 6,239, 0,168, 6,239, 0,169, 6,240, 0,170, 6, 0, 0,171, 6,242, 0, 71, 0, + 0, 0,172, 6, 0, 0,173, 6, 0, 0,144, 6, 0, 0,174, 6, 0, 0,175, 6, 0, 0,176, 6, 0, 0,177, 6, 0, 0,178, 6, + 0, 0,179, 6, 0, 0,180, 6, 0, 0,181, 6, 0, 0,182, 6, 0, 0,183, 6, 0, 0,184, 6, 0, 0,185, 6, 0, 0,186, 6, + 0, 0,187, 6, 0, 0,188, 6, 0, 0,189, 6, 0, 0,190, 6, 0, 0,191, 6, 0, 0,192, 6, 0, 0,193, 6, 0, 0,194, 6, + 0, 0,195, 6, 0, 0,196, 6, 0, 0,197, 6, 0, 0,198, 6, 0, 0,199, 6, 0, 0,200, 6, 0, 0,201, 6, 0, 0,202, 6, + 0, 0,203, 6, 0, 0,204, 6, 0, 0,205, 6, 0, 0,206, 6, 0, 0,207, 6, 0, 0,208, 6, 0, 0,209, 6, 0, 0,210, 6, + 0, 0,211, 6, 0, 0,212, 6, 0, 0,213, 6, 0, 0,214, 6, 0, 0,215, 6, 0, 0,216, 6, 0, 0,217, 6, 0, 0,218, 6, + 0, 0,219, 6, 0, 0,220, 6, 0, 0,221, 6, 0, 0,222, 6, 0, 0,223, 6, 0, 0,224, 6, 0, 0,225, 6, 0, 0,226, 6, + 0, 0,227, 6, 0, 0,228, 6, 0, 0,229, 6, 0, 0,230, 6, 0, 0,231, 6, 0, 0,232, 6, 0, 0,233, 6, 0, 0,234, 6, + 0, 0,235, 6, 0, 0,236, 6, 0, 0,237, 6, 0, 0,238, 6, 0, 0,239, 6, 0, 0,240, 6, 0, 0, 92, 0,243, 0, 5, 0, + 0, 0,241, 6, 0, 0,196, 6, 0, 0,198, 6, 2, 0, 19, 0, 2, 0, 37, 0,244, 0, 22, 0,244, 0, 0, 0,244, 0, 1, 0, + 0, 0, 20, 0,241, 0,242, 6,242, 0,243, 6,242, 0,244, 6,242, 0,245, 6,242, 0,246, 6,242, 0,247, 6,242, 0,248, 6, +242, 0,249, 6,242, 0,250, 6,242, 0,251, 6,242, 0,252, 6,242, 0,253, 6,242, 0,254, 6,242, 0,255, 6,242, 0, 0, 7, +242, 0, 1, 7,242, 0, 2, 7,242, 0, 3, 7,243, 0, 4, 7,245, 0, 5, 0, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,115, 2, + 7, 0, 5, 7, 7, 0, 21, 2,246, 0, 71, 0, 4, 0, 19, 0, 4, 0, 6, 7, 4, 0, 7, 7, 0, 0, 8, 7, 0, 0, 9, 7, + 0, 0, 10, 7, 0, 0, 11, 7, 0, 0, 12, 7, 0, 0, 13, 7, 0, 0, 14, 7, 0, 0, 15, 7, 0, 0, 16, 7, 2, 0, 17, 7, + 2, 0, 37, 0, 4, 0, 18, 7, 4, 0, 19, 7, 4, 0, 20, 7, 4, 0, 21, 7, 2, 0, 22, 7, 2, 0, 23, 7, 4, 0, 24, 7, + 4, 0, 25, 7, 4, 0, 26, 7, 4, 0, 27, 7, 4, 0, 28, 7, 4, 0,109, 6, 4, 0, 29, 7, 2, 0, 30, 7, 2, 0, 31, 7, + 2, 0, 32, 7, 2, 0, 33, 7, 12, 0, 34, 7, 12, 0, 35, 7, 12, 0, 36, 7, 2, 0, 37, 7, 2, 0, 38, 7, 2, 0, 39, 7, + 2, 0, 40, 7, 2, 0, 41, 7, 2, 0, 42, 7, 2, 0, 43, 7, 2, 0, 44, 7,245, 0, 45, 7, 2, 0, 46, 7, 2, 0, 47, 7, + 2, 0, 48, 7, 2, 0, 49, 7, 2, 0, 50, 7, 2, 0, 51, 7, 2, 0, 52, 7, 2, 0, 53, 7, 4, 0, 54, 7, 4, 0, 55, 7, + 2, 0, 56, 7, 2, 0, 57, 7, 2, 0, 58, 7, 2, 0, 59, 7, 2, 0, 60, 7, 2, 0, 61, 7, 2, 0, 62, 7, 2, 0, 63, 7, + 2, 0, 64, 7, 2, 0, 65, 7, 2, 0, 66, 7, 2, 0, 67, 7, 0, 0, 68, 7, 0, 0, 69, 7, 7, 0, 70, 7, 2, 0, 90, 5, + 2, 0, 91, 5, 55, 0, 71, 7,211, 0, 21, 0, 27, 0, 31, 0, 12, 0, 72, 7, 12, 0, 73, 7, 12, 0, 74, 7, 12, 0,192, 5, + 46, 0,134, 0, 46, 0, 75, 7, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 79, 7, 2, 0, 80, 7, 2, 0, 81, 7, + 2, 0, 82, 7, 2, 0, 37, 0, 2, 0, 83, 7, 2, 0, 84, 7, 4, 0, 70, 0,206, 0, 85, 7, 9, 0, 86, 7, 2, 0, 87, 7, +247, 0, 5, 0,247, 0, 0, 0,247, 0, 1, 0,247, 0, 88, 7, 13, 0, 89, 7, 4, 0, 19, 0,248, 0, 7, 0,248, 0, 0, 0, +248, 0, 1, 0,247, 0, 90, 7,247, 0, 91, 7, 2, 0,199, 4, 2, 0, 19, 0, 4, 0, 37, 0,249, 0, 23, 0,249, 0, 0, 0, +249, 0, 1, 0,250, 0, 92, 7,251, 0, 30, 6, 0, 0, 93, 7, 0, 0, 94, 7, 0, 0, 95, 7, 2, 0, 96, 7, 2, 0, 97, 7, + 2, 0, 98, 7, 2, 0, 99, 7, 2, 0,100, 7, 2, 0, 37, 0, 2, 0, 19, 0, 2, 0,101, 7, 2, 0,102, 7, 2, 0,103, 7, + 4, 0,104, 7,249, 0,105, 7, 9, 0,106, 7, 4, 0,107, 7, 4, 0,108, 7, 0, 0,109, 7,252, 0, 22, 0,252, 0, 0, 0, +252, 0, 1, 0,247, 0, 90, 7,247, 0, 91, 7,247, 0,110, 7,247, 0,111, 7,211, 0,112, 7, 23, 0, 52, 0, 0, 0,193, 5, + 0, 0,113, 7, 2, 0,240, 5, 2, 0,241, 5, 2, 0,114, 7, 2, 0, 37, 0, 2, 0, 79, 7, 2, 0,107, 6, 2, 0, 19, 0, +253, 0, 92, 7, 12, 0,115, 7, 12, 0,192, 5, 12, 0,116, 7, 12, 0,117, 7,254, 0, 21, 0,254, 0, 0, 0,254, 0, 1, 0, +209, 0,249, 5, 23, 0,118, 7, 23, 0,119, 7, 2, 0,240, 5, 2, 0,241, 5, 2, 0,120, 7, 2, 0,121, 7, 2, 0,122, 7, + 2, 0, 19, 0, 7, 0, 63, 2, 2, 0, 78, 7, 2, 0, 82, 7, 4, 0, 43, 0,255, 0, 92, 7, 12, 0,123, 7, 12, 0,124, 7, + 12, 0,116, 7, 0, 0,125, 7, 9, 0,126, 7, 0, 1, 11, 0, 0, 0,127, 7, 2, 0,128, 7, 2, 0,129, 7, 2, 0,130, 7, + 2, 0,131, 7, 2, 0,188, 4, 2, 0,183, 4,211, 0,132, 7, 46, 0,133, 7, 4, 0,134, 7, 4, 0,135, 7, 1, 1, 1, 0, + 0, 0,136, 7, 2, 1, 8, 0, 57, 0,137, 7, 57, 0,138, 7, 2, 1,139, 7, 2, 1,140, 7, 2, 1,141, 7, 2, 0,129, 0, + 2, 0, 19, 0, 4, 0,142, 7, 3, 1, 4, 0, 4, 0, 52, 6, 4, 0,143, 7, 4, 0, 57, 6, 4, 0,144, 7, 4, 1, 2, 0, + 4, 0,145, 7, 4, 0,146, 7, 5, 1, 7, 0, 7, 0,147, 7, 7, 0,148, 7, 7, 0,149, 7, 4, 0, 19, 0, 4, 0, 37, 0, + 7, 0, 72, 4, 7, 0,150, 7, 6, 1, 6, 0, 0, 0,151, 7, 0, 0, 13, 6, 49, 0,137, 0, 2, 0,106, 0, 2, 0,187, 4, + 4, 0, 37, 0, 7, 1, 21, 0, 7, 1, 0, 0, 7, 1, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0,152, 7, + 4, 0,153, 7, 4, 0,154, 7, 1, 1,155, 7, 0, 0,151, 7, 4, 0,156, 7, 4, 0,157, 7, 6, 1, 64, 3, 3, 1,158, 7, + 4, 1,159, 7, 5, 1,160, 7, 2, 1,161, 7, 2, 1,162, 7, 2, 1,163, 7, 57, 0,164, 7, 57, 0,165, 7, 8, 1, 12, 0, + 0, 0,239, 1, 9, 0,193, 0, 0, 0,194, 0, 4, 0,197, 0, 4, 0,205, 0, 9, 0,198, 0, 7, 0,200, 0, 7, 0,201, 0, + 9, 0,166, 7, 9, 0,167, 7, 9, 0,202, 0, 9, 0,204, 0, 9, 1, 43, 0, 9, 1, 0, 0, 9, 1, 1, 0, 9, 0,168, 7, + 9, 0, 26, 0, 0, 0, 27, 0, 4, 0, 19, 0, 4, 0, 17, 0, 4, 0, 23, 0, 4, 0, 88, 0, 4, 0,169, 7, 4, 0,170, 7, + 4, 0,153, 7, 4, 0,154, 7, 4, 0,171, 7, 4, 0,216, 0, 4, 0,172, 7, 4, 0,173, 7, 7, 0, 56, 5, 7, 0,174, 7, + 4, 0,126, 0, 4, 0,175, 7, 7, 1,176, 7, 36, 0, 80, 0, 46, 0,134, 0, 49, 0,137, 0, 7, 0,177, 7, 7, 0,178, 7, + 8, 1, 30, 1, 9, 1,179, 7, 9, 1,180, 7, 9, 1,181, 7, 12, 0,182, 7, 10, 1,183, 7, 11, 1,184, 7, 7, 0,185, 7, + 7, 0,186, 7, 4, 0,187, 7, 7, 0,188, 7, 9, 0,189, 7, 4, 0,190, 7, 4, 0,191, 7, 4, 0,192, 7, 7, 0,193, 7, + 12, 1, 4, 0, 12, 1, 0, 0, 12, 1, 1, 0, 12, 0,194, 7, 9, 1,195, 7,197, 0, 6, 0, 12, 0,196, 7, 12, 0,182, 7, + 12, 0,197, 7, 9, 1,198, 7, 0, 0,199, 7, 0, 0,200, 7, 13, 1, 4, 0, 7, 0,201, 7, 7, 0,109, 0, 2, 0,202, 7, + 2, 0,203, 7, 14, 1, 6, 0, 7, 0,204, 7, 7, 0,205, 7, 7, 0,206, 7, 7, 0,207, 7, 4, 0,208, 7, 4, 0,209, 7, + 15, 1, 12, 0, 7, 0,210, 7, 7, 0,211, 7, 7, 0,212, 7, 7, 0,213, 7, 7, 0,214, 7, 7, 0,215, 7, 7, 0,216, 7, + 7, 0,217, 7, 7, 0,218, 7, 7, 0,219, 7, 4, 0,210, 2, 4, 0,220, 7, 16, 1, 2, 0, 7, 0, 25, 5, 7, 0, 37, 0, + 17, 1, 5, 0, 7, 0,221, 7, 7, 0,222, 7, 4, 0, 90, 0, 4, 0,168, 2, 4, 0,223, 7, 18, 1, 6, 0, 18, 1, 0, 0, + 18, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0, 57, 0, 19, 1, 8, 0, 19, 1, 0, 0, 19, 1, 1, 0, + 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0,126, 0, 20, 1, 45, 0, 20, 1, 0, 0, + 20, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0,212, 0, 2, 0,244, 3, 2, 0,225, 7, 7, 0,226, 7, + 7, 0, 89, 0, 7, 0,223, 2, 4, 0,227, 7, 4, 0, 82, 0, 4, 0,170, 2, 7, 0,228, 7, 7, 0,229, 7, 7, 0,230, 7, + 7, 0,231, 7, 7, 0,232, 7, 7, 0,233, 7, 7, 0,220, 2, 7, 0, 27, 1, 7, 0,234, 7, 7, 0,235, 7, 7, 0, 37, 0, + 7, 0,236, 7, 7, 0,237, 7, 7, 0,238, 7, 2, 0,239, 7, 2, 0,240, 7, 2, 0,241, 7, 2, 0,242, 7, 2, 0,243, 7, + 2, 0,244, 7, 2, 0,245, 7, 2, 0,246, 7, 2, 0, 6, 2, 2, 0,247, 7, 2, 0, 3, 2, 2, 0,248, 7, 0, 0,249, 7, + 0, 0,250, 7, 7, 0,210, 0, 21, 1,251, 7, 68, 0,212, 1, 22, 1, 16, 0, 22, 1, 0, 0, 22, 1, 1, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 2, 0,224, 7, 2, 0,212, 0, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 7, 0, 52, 2, 7, 0,218, 2, + 7, 0,219, 2, 7, 0,252, 7, 7, 0,220, 2, 7, 0,222, 2, 7, 0,223, 2,223, 0, 5, 0, 2, 0, 17, 0, 2, 0,142, 7, + 2, 0, 19, 0, 2, 0,253, 7, 27, 0, 81, 6,222, 0, 3, 0, 4, 0, 69, 0, 4, 0,254, 7,223, 0, 2, 0, 23, 1, 7, 0, + 23, 1, 0, 0, 23, 1, 1, 0, 0, 0, 20, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 22, 0, 9, 0,255, 7, 24, 1, 5, 0, + 0, 0, 20, 0, 7, 0, 47, 1, 7, 0, 0, 8, 4, 0, 1, 8, 4, 0, 37, 0, 25, 1, 4, 0, 2, 0, 17, 0, 2, 0, 19, 0, + 2, 0, 43, 0, 2, 0, 70, 0, 26, 1, 4, 0, 0, 0, 20, 0, 67, 0, 2, 8, 7, 0, 47, 1, 7, 0, 37, 0, 27, 1, 6, 0, + 2, 0, 3, 8, 2, 0, 4, 8, 2, 0, 17, 0, 2, 0, 5, 8, 0, 0, 6, 8, 0, 0, 7, 8, 28, 1, 5, 0, 4, 0, 17, 0, + 4, 0, 37, 0, 0, 0, 20, 0, 0, 0, 8, 8, 0, 0, 9, 8, 29, 1, 3, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0, + 30, 1, 4, 0, 2, 0, 10, 8, 2, 0, 11, 8, 2, 0, 19, 0, 2, 0, 37, 0, 31, 1, 6, 0, 0, 0, 20, 0, 0, 0, 12, 8, + 2, 0, 13, 8, 2, 0,220, 2, 2, 0, 40, 1, 2, 0, 70, 0, 32, 1, 5, 0, 0, 0, 20, 0, 7, 0,109, 0, 7, 0, 74, 4, + 2, 0, 19, 0, 2, 0,182, 2, 33, 1, 3, 0, 0, 0, 20, 0, 4, 0,170, 2, 4, 0, 10, 8, 34, 1, 7, 0, 0, 0, 20, 0, + 7, 0, 74, 4, 0, 0, 14, 8, 0, 0, 15, 8, 2, 0, 40, 1, 2, 0, 43, 0, 4, 0, 16, 8, 35, 1, 3, 0, 32, 0, 17, 8, + 0, 0, 18, 8, 0, 0, 19, 8, 36, 1, 18, 0, 36, 1, 0, 0, 36, 1, 1, 0, 2, 0, 17, 0, 2, 0, 20, 8, 2, 0, 19, 0, + 2, 0, 21, 8, 2, 0, 22, 8, 2, 0, 23, 8, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 20, 0, 9, 0, 2, 0, 37, 1, 24, 8, + 32, 0, 45, 0, 2, 0, 40, 5, 2, 0,185, 7, 2, 0, 25, 8, 2, 0, 37, 0, 38, 1, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0, + 0, 0, 26, 8, 2, 0, 19, 0, 2, 0,182, 2, 2, 0, 27, 8, 4, 0, 28, 8, 4, 0, 29, 8, 4, 0, 30, 8, 4, 0, 31, 8, + 4, 0, 32, 8, 39, 1, 1, 0, 0, 0, 33, 8, 40, 1, 4, 0, 42, 0, 51, 6, 0, 0, 34, 8, 4, 0, 40, 1, 4, 0, 19, 0, + 37, 1, 18, 0, 37, 1, 0, 0, 37, 1, 1, 0, 37, 1, 35, 8, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 36, 8, 2, 0, 23, 8, + 2, 0, 20, 8, 2, 0, 37, 8, 2, 0, 70, 0, 2, 0,209, 1, 0, 0, 20, 0, 9, 0, 2, 0, 41, 1, 24, 8, 36, 1, 38, 8, + 2, 0, 15, 0, 2, 0, 39, 8, 4, 0, 40, 8, 42, 1, 3, 0, 4, 0,196, 2, 4, 0, 37, 0, 32, 0, 45, 0, 43, 1, 12, 0, +159, 0, 41, 8, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0, 42, 8, 2, 0, 43, 8, + 2, 0, 44, 8, 2, 0, 45, 8, 2, 0, 46, 8, 7, 0, 47, 8, 44, 1, 13, 0, 2, 0, 19, 0, 2, 0, 48, 8, 4, 0,226, 7, + 4, 0, 89, 0, 2, 0, 49, 8, 7, 0,202, 3, 7, 0, 50, 8, 10, 1,183, 7, 45, 1, 51, 8, 2, 0, 17, 0, 2, 0, 52, 8, + 2, 0, 53, 8, 2, 0, 54, 8, 46, 1, 11, 0, 4, 0,196, 2, 2, 0, 17, 0, 2, 0, 19, 0, 32, 0, 45, 0, 81, 0, 55, 8, + 0, 0, 20, 0, 7, 0, 56, 8, 7, 0, 57, 8, 7, 0,100, 3, 2, 0, 58, 8, 2, 0, 59, 8, 47, 1, 5, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 4, 0, 37, 0, 46, 0,134, 0, 32, 0,136, 5, 48, 1, 5, 0, 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 20, 0, + 0, 0, 8, 8, 32, 0, 45, 0, 49, 1, 13, 0, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0, 20, 8, 2, 0,101, 3, 7, 0, 60, 8, + 7, 0, 61, 8, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0, 77, 3, 7, 0, 80, 3, 7, 0, 62, 8, 7, 0, 63, 8, 32, 0, 64, 8, + 50, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0, 42, 8, 2, 0, 43, 0, + 2, 0, 64, 0, 2, 0, 65, 8, 2, 0, 66, 8, 51, 1, 8, 0, 32, 0, 45, 0, 7, 0,217, 2, 7, 0, 67, 8, 7, 0, 68, 8, + 7, 0,212, 2, 2, 0, 19, 0, 2, 0,182, 2, 7, 0, 69, 8, 52, 1, 12, 0, 2, 0, 17, 0, 2, 0, 40, 1, 2, 0, 19, 0, + 2, 0,220, 2, 2, 0,196, 2, 2, 0, 70, 8, 4, 0, 37, 0, 7, 0, 71, 8, 7, 0, 72, 8, 7, 0, 73, 8, 7, 0, 74, 8, + 0, 0, 75, 8, 53, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 2, 0,105, 1, + 2, 0, 64, 0, 2, 0, 65, 8, 2, 0, 66, 8, 68, 0,212, 1, 54, 1, 7, 0, 4, 0,170, 2, 4, 0, 76, 8, 4, 0, 77, 8, + 4, 0, 78, 8, 7, 0, 79, 8, 7, 0, 80, 8, 0, 0, 14, 8, 55, 1, 7, 0, 0, 0, 81, 8, 32, 0, 82, 8, 0, 0, 18, 8, + 2, 0, 83, 8, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0, 19, 8, 56, 1, 6, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, + 4, 0, 89, 0, 0, 0, 84, 8, 0, 0, 85, 8, 57, 1, 1, 0, 4, 0, 19, 0, 58, 1, 6, 0, 0, 0, 92, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 4, 0, 86, 8, 7, 0, 87, 8, 42, 0, 51, 6, 59, 1, 4, 0, 0, 0, 48, 2, 2, 0, 19, 0, 4, 0, 17, 0, + 32, 0, 45, 0, 60, 1, 2, 0, 4, 0, 17, 0, 4, 0,229, 5, 41, 1, 10, 0, 41, 1, 0, 0, 41, 1, 1, 0, 41, 1, 35, 8, + 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 20, 8, 2, 0, 88, 8, 0, 0, 20, 0, 9, 0, 2, 0, 32, 0, 45, 0, 61, 1, 10, 0, + 7, 0,100, 3, 7, 0, 89, 8, 7, 0, 90, 8, 7, 0, 91, 8, 7, 0, 92, 8, 4, 0, 19, 0, 7, 0, 70, 8, 7, 0, 93, 8, + 7, 0, 94, 8, 7, 0, 37, 0, 11, 1, 12, 0, 11, 1, 0, 0, 11, 1, 1, 0, 10, 1, 95, 8, 9, 0,193, 0, 4, 0,143, 3, + 4, 0,189, 3, 4, 0,190, 3, 4, 0, 96, 8, 4, 0, 97, 8, 4, 0, 98, 8, 7, 0,202, 3, 7, 0, 37, 0, 45, 1, 8, 0, + 7, 0, 99, 8, 7, 0,100, 8, 7, 0,101, 8, 7, 0,102, 8, 7, 0,103, 8, 7, 0,104, 8, 7, 0,105, 8, 7, 0,106, 8, + 10, 1, 15, 0, 27, 0, 31, 0, 0, 0,192, 0, 43, 0,149, 0, 9, 0,193, 0, 43, 0,107, 8, 36, 0, 80, 0, 7, 0,202, 3, + 7, 0,108, 8, 7, 0, 50, 8, 7, 0, 99, 8, 7, 0,100, 8, 7, 0,109, 8, 4, 0, 90, 0, 4, 0, 98, 8, 9, 0,110, 8, + 62, 1, 15, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,252, 0,111, 8,209, 0,249, 5, + 10, 1,183, 7, 2, 0, 40, 1, 2, 0, 48, 8, 2, 0, 67, 2, 2, 0, 68, 2, 2, 0, 19, 0, 2, 0,254, 5, 4, 0, 70, 0, + 63, 1, 6, 0, 63, 1, 0, 0, 63, 1, 1, 0, 32, 0, 45, 0, 9, 0,112, 8, 4, 0,217, 0, 4, 0, 37, 0, 68, 0, 4, 0, + 27, 0, 31, 0, 12, 0,113, 8, 4, 0,131, 0, 7, 0,114, 8, 64, 1, 25, 0, 64, 1, 0, 0, 64, 1, 1, 0, 64, 1, 38, 0, + 12, 0,115, 8, 0, 0, 20, 0, 7, 0,116, 8, 7, 0,117, 8, 7, 0,118, 8, 7, 0,119, 8, 4, 0, 19, 0, 7, 0,120, 8, + 7, 0,121, 8, 7, 0,122, 8, 7, 0, 47, 1, 7, 0, 14, 2, 7, 0,123, 8, 7, 0,168, 2, 7, 0,124, 8, 7, 0,125, 8, + 7, 0,126, 8, 7, 0,127, 8, 7, 0,128, 8, 7, 0,172, 0, 2, 0,131, 0, 2, 0, 71, 5, 65, 1, 21, 0, 27, 0, 31, 0, + 12, 0,129, 8, 12, 0,130, 8, 12, 0,131, 8, 9, 0,132, 8, 4, 0, 19, 0, 4, 0,201, 5, 2, 0,224, 2, 2, 0, 4, 6, + 2, 0,131, 0, 2, 0,133, 8, 2, 0,134, 8, 2, 0,135, 8, 2, 0,136, 8, 2, 0,137, 8, 4, 0,138, 8, 4, 0,139, 8, + 4, 0,140, 8, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 66, 1, 2, 0, 7, 0,129, 2, 4, 0, 19, 0, 67, 1, 5, 0, + 66, 1,144, 8, 4, 0,168, 2, 4, 0,145, 8, 4, 0,146, 8, 4, 0, 19, 0, 68, 1, 6, 0, 4, 0, 37, 0, 4, 0, 4, 6, + 4, 0,140, 8, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 69, 1, 38, 0, 69, 1, 0, 0, 69, 1, 1, 0, 26, 0,147, 8, + 12, 0,127, 3, 0, 0, 20, 0, 2, 0, 19, 0, 2, 0,148, 8, 2, 0,149, 8, 2, 0,150, 8, 2, 0, 86, 3, 2, 0,151, 8, + 4, 0, 50, 2, 4, 0,140, 8, 4, 0,141, 8, 64, 1,152, 8, 69, 1, 38, 0, 69, 1,153, 8, 12, 0,154, 8, 9, 0,155, 8, + 9, 0,156, 8, 9, 0,157, 8, 7, 0, 35, 1, 7, 0,172, 0, 7, 0,158, 8, 7, 0,249, 1, 2, 0,159, 8, 2, 0, 37, 0, + 7, 0,160, 8, 7, 0,161, 8, 7, 0, 82, 3, 7, 0,162, 8, 7, 0,163, 8, 7, 0,164, 8, 7, 0,165, 8, 7, 0,166, 8, + 7, 0,167, 8, 7, 0, 43, 2, 32, 0,168, 8,160, 0, 9, 0, 12, 0,169, 8, 2, 0, 19, 0, 2, 0,170, 8, 7, 0, 79, 2, + 7, 0,171, 8, 7, 0,172, 8, 12, 0,173, 8, 4, 0,174, 8, 4, 0, 37, 0, 70, 1, 7, 0, 70, 1, 0, 0, 70, 1, 1, 0, + 12, 0,175, 8, 4, 0, 19, 0, 4, 0,176, 8, 0, 0,193, 3,243, 0,177, 8,159, 0, 7, 0, 27, 0, 31, 0, 12, 0,178, 8, + 12, 0,169, 8, 12, 0,179, 8, 12, 0,100, 0, 4, 0, 19, 0, 4, 0,180, 8,213, 0, 4, 0, 27, 0, 95, 8, 12, 0,169, 8, + 4, 0,181, 8, 4, 0, 19, 0, 71, 1, 17, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, + 2, 0,195, 5,209, 0,249, 5,159, 0, 67, 3,213, 0,182, 8, 0, 0, 40, 1, 0, 0,252, 5, 2, 0, 19, 0, 2, 0,183, 8, + 2, 0,253, 5, 2, 0,254, 5, 2, 0,184, 8, 7, 0,185, 8, 72, 1, 8, 0, 72, 1, 0, 0, 72, 1, 1, 0, 70, 1,186, 8, + 36, 0, 80, 0, 12, 0, 71, 3, 4, 0, 19, 0, 0, 0, 20, 0, 4, 0,187, 8, 73, 1, 5, 0, 73, 1, 0, 0, 73, 1, 1, 0, + 36, 0, 80, 0, 2, 0, 19, 0, 0, 0,188, 8, 74, 1, 12, 0, 74, 1, 0, 0, 74, 1, 1, 0, 9, 0, 2, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 0, 0,189, 8, 0, 0,190, 8, 0, 0,188, 8, 7, 0,191, 8, 7, 0,192, 8, 4, 0, 37, 0, 36, 0, 80, 0, + 75, 1, 9, 0, 75, 1, 0, 0, 75, 1, 1, 0, 32, 0,193, 8, 0, 0,227, 2, 7, 0,194, 8, 2, 0,195, 8, 2, 0, 19, 0, + 2, 0, 17, 0, 2, 0,196, 8, 76, 1, 7, 0, 42, 0, 51, 6, 26, 0,147, 8, 4, 0, 19, 0, 4, 0,197, 8, 12, 0,198, 8, + 32, 0,193, 8, 0, 0,227, 2, 77, 1, 12, 0, 32, 0,193, 8, 2, 0,199, 8, 2, 0, 19, 0, 2, 0,200, 8, 2, 0,201, 8, + 0, 0,227, 2, 32, 0,202, 8, 0, 0,203, 8, 7, 0,204, 8, 7, 0, 14, 2, 7, 0,205, 8, 7, 0,206, 8, 78, 1, 6, 0, + 32, 0,193, 8, 4, 0,207, 8, 4, 0,208, 8, 4, 0, 90, 0, 4, 0, 37, 0, 0, 0,227, 2, 79, 1, 4, 0, 32, 0,193, 8, + 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, 80, 1, 4, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, + 81, 1, 10, 0, 32, 0,193, 8, 4, 0,209, 8, 7, 0,125, 0, 4, 0, 19, 0, 2, 0, 47, 6, 2, 0,210, 8, 2, 0, 43, 0, + 2, 0, 70, 0, 7, 0,211, 8, 0, 0,227, 2, 82, 1, 4, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, + 83, 1, 10, 0, 32, 0,193, 8, 2, 0, 17, 0, 2, 0,252, 3, 4, 0, 88, 0, 4, 0, 89, 0, 7, 0, 67, 8, 7, 0, 68, 8, + 4, 0, 37, 0,159, 0, 41, 8, 0, 0,227, 2, 84, 1, 4, 0, 32, 0,193, 8, 4, 0, 87, 3, 4, 0,212, 8, 0, 0,227, 2, + 85, 1, 5, 0, 32, 0,193, 8, 7, 0,125, 0, 4, 0,213, 8, 4, 0, 87, 3, 4, 0, 88, 3, 86, 1, 6, 0, 32, 0,193, 8, + 4, 0,214, 8, 4, 0,215, 8, 7, 0,216, 8, 7, 0,217, 8, 0, 0,227, 2, 87, 1, 16, 0, 32, 0,193, 8, 32, 0,153, 8, + 4, 0, 17, 0, 7, 0,218, 8, 7, 0,219, 8, 7, 0,220, 8, 7, 0,221, 8, 7, 0,222, 8, 7, 0,223, 8, 7, 0,224, 8, + 7, 0,225, 8, 7, 0,226, 8, 2, 0, 19, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, 88, 1, 3, 0, 32, 0,193, 8, + 4, 0, 19, 0, 4, 0, 6, 2, 89, 1, 5, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,227, 8, 0, 0,227, 2, + 90, 1, 10, 0, 32, 0,193, 8, 0, 0,227, 2, 2, 0,228, 8, 2, 0,229, 8, 0, 0,230, 8, 0, 0,231, 8, 7, 0,232, 8, + 7, 0,233, 8, 7, 0,234, 8, 7, 0,235, 8, 91, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, + 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 92, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, + 7, 0, 12, 0, 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 93, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, + 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 94, 1, 7, 0, 32, 0,193, 8, + 0, 0,227, 2, 7, 0, 47, 1, 7, 0, 56, 1, 2, 0, 19, 0, 2, 0, 40, 1, 4, 0, 37, 0, 95, 1, 5, 0, 32, 0, 27, 3, + 7, 0, 47, 1, 2, 0, 31, 3, 0, 0, 33, 3, 0, 0,238, 8, 96, 1, 10, 0, 96, 1, 0, 0, 96, 1, 1, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 0, 0,239, 8, 7, 0,246, 0, 7, 0,247, 0, 2, 0,175, 8, 2, 0,240, 8, 32, 0, 45, 0, 97, 1, 22, 0, + 97, 1, 0, 0, 97, 1, 1, 0, 2, 0, 19, 0, 2, 0, 40, 1, 2, 0,241, 8, 2, 0,242, 8, 36, 0, 80, 0,159, 0, 41, 8, + 32, 0,164, 0, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,243, 8, 7, 0,244, 8, 7, 0,245, 8, 7, 0,246, 8, 7, 0,213, 2, + 7, 0,247, 8, 7, 0, 43, 8, 7, 0,248, 8, 0, 0,249, 8, 0, 0,250, 8, 12, 0, 73, 3, 98, 1, 8, 0, 7, 0, 21, 2, + 7, 0, 67, 8, 7, 0, 68, 8, 9, 0, 2, 0, 2, 0,251, 8, 2, 0,252, 8, 2, 0,253, 8, 2, 0,254, 8, 99, 1, 18, 0, + 99, 1, 0, 0, 99, 1, 1, 0, 99, 1,255, 8, 0, 0, 20, 0, 98, 1, 0, 9, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 1, 9, + 2, 0, 2, 9, 2, 0, 3, 9, 2, 0, 4, 9, 4, 0, 43, 0, 7, 0, 5, 9, 7, 0, 6, 9, 4, 0, 7, 9, 4, 0, 8, 9, + 99, 1, 9, 9,100, 1, 10, 9,101, 1, 33, 0,101, 1, 0, 0,101, 1, 1, 0,101, 1, 11, 9, 0, 0, 20, 0, 0, 0, 12, 9, + 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,152, 7, 2, 0,185, 7, 2, 0, 13, 9, 2, 0,133, 0, 2, 0, 2, 9, 2, 0,142, 7, + 12, 0, 36, 8, 12, 0, 14, 9, 27, 0, 81, 6, 9, 0, 15, 9, 7, 0, 5, 9, 7, 0, 6, 9, 7, 0, 52, 2, 7, 0, 16, 9, + 2, 0, 17, 9, 2, 0, 18, 9, 7, 0, 19, 9, 7, 0, 20, 9, 2, 0, 21, 9, 2, 0, 22, 9, 9, 0, 23, 9, 24, 0, 24, 9, + 24, 0, 25, 9, 24, 0, 26, 9,102, 1,150, 0,103, 1, 27, 9,100, 1, 8, 0,100, 1, 0, 0,100, 1, 1, 0,101, 1, 28, 9, +101, 1, 29, 9, 99, 1, 30, 9, 99, 1, 9, 9, 4, 0, 19, 0, 4, 0, 37, 0, 61, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0, + 12, 0, 31, 9, 12, 0, 32, 9, 98, 1, 33, 9, 12, 0, 34, 9, 4, 0, 17, 0, 4, 0, 35, 9, 4, 0, 36, 9, 4, 0, 37, 9, + 12, 0, 38, 9,103, 1, 39, 9, 99, 1, 40, 9, 99, 1, 41, 9, 9, 0, 42, 9, 9, 0, 43, 9, 4, 0, 44, 9, 9, 0, 45, 9, + 9, 0, 46, 9, 9, 0, 47, 9,104, 1, 6, 0, 4, 0,124, 0, 4, 0,126, 0, 4, 0,142, 7, 0, 0, 48, 9, 0, 0, 49, 9, + 2, 0, 37, 0,105, 1, 16, 0, 2, 0, 98, 7, 2, 0, 99, 7, 2, 0, 50, 9, 2, 0, 90, 8, 2, 0, 51, 9, 2, 0, 68, 0, + 7, 0,212, 2, 7, 0, 52, 9, 7, 0, 53, 9, 2, 0, 60, 1, 0, 0, 54, 9, 0, 0, 55, 5, 2, 0, 55, 9, 2, 0, 37, 0, + 4, 0, 56, 9, 4, 0, 57, 9,106, 1, 9, 0, 7, 0, 58, 9, 7, 0, 59, 9, 7, 0,109, 8, 7, 0,109, 0, 7, 0, 60, 9, + 7, 0, 10, 6, 2, 0, 61, 9, 0, 0, 62, 9, 0, 0, 37, 0,107, 1, 4, 0, 7, 0, 63, 9, 7, 0, 64, 9, 2, 0, 61, 9, + 2, 0, 37, 0,108, 1, 3, 0, 7, 0, 65, 9, 7, 0, 66, 9, 7, 0, 15, 0,109, 1, 7, 0, 0, 0,239, 1, 2, 0,185, 4, + 2, 0,186, 4, 2, 0,187, 4, 2, 0,138, 4, 4, 0,126, 0, 4, 0,250, 3,110, 1, 7, 0, 7, 0, 67, 9, 7, 0, 68, 9, + 7, 0, 69, 9, 7, 0, 63, 2, 7, 0, 70, 9, 7, 0, 71, 9, 7, 0, 72, 9,111, 1, 4, 0, 2, 0, 73, 9, 2, 0, 74, 9, + 2, 0, 75, 9, 2, 0, 76, 9,112, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,113, 1, 2, 0, 0, 0,166, 0, 0, 0, 77, 9, +114, 1, 1, 0, 0, 0, 20, 0,115, 1, 10, 0, 0, 0, 78, 9, 0, 0, 79, 9, 0, 0, 3, 6, 0, 0, 80, 9, 2, 0, 50, 9, + 2, 0, 81, 9, 7, 0, 82, 9, 7, 0, 83, 9, 7, 0, 84, 9, 7, 0,247, 8,116, 1, 2, 0, 9, 0, 85, 9, 9, 0, 86, 9, +117, 1, 11, 0, 0, 0,187, 4, 0, 0, 17, 0, 0, 0, 61, 9, 0, 0,109, 0, 0, 0, 87, 9, 0, 0,106, 0, 0, 0, 48, 2, + 7, 0, 88, 9, 7, 0, 89, 9, 7, 0, 90, 9, 7, 0, 91, 9,118, 1, 8, 0, 7, 0, 3, 8, 7, 0,125, 0, 7, 0, 55, 5, + 7, 0,134, 2, 7, 0, 92, 9, 7, 0,206, 0, 7, 0, 93, 9, 4, 0, 17, 0,119, 1, 4, 0, 2, 0, 94, 9, 2, 0, 95, 9, + 2, 0, 96, 9, 2, 0, 37, 0,120, 1, 1, 0, 0, 0, 20, 0,121, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 19, 0, + 2, 0, 97, 9,122, 1, 10, 0, 2, 0,182, 3, 2, 0, 19, 0, 7, 0, 74, 4, 7, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9, + 7, 0,101, 9,121, 1,102, 9,121, 1,103, 9,121, 1,104, 9, 64, 0, 9, 0, 4, 0, 19, 0, 4, 0, 64, 0, 24, 0,105, 9, + 24, 0,106, 9,122, 1,107, 9, 7, 0,108, 9, 7, 0,109, 9, 7, 0,110, 9, 7, 0,111, 9,123, 1, 4, 0, 47, 0,206, 2, + 7, 0,112, 9, 7, 0,141, 1, 7, 0, 37, 0,187, 0, 17, 0, 27, 0, 31, 0,123, 1,113, 9, 64, 0,102, 9, 51, 0,103, 1, + 2, 0, 19, 0, 2, 0,160, 5, 4, 0,106, 0, 7, 0,114, 9, 7, 0, 60, 2, 4, 0,115, 9, 7, 0,116, 9, 7, 0,117, 9, + 7, 0,118, 9, 7, 0,141, 1, 2, 0, 73, 1, 0, 0,119, 9, 0, 0,139, 6,124, 1, 10, 0, 4, 0, 17, 0, 4, 0,125, 0, + 4, 0, 19, 0, 4, 0,148, 3, 4, 0,120, 9, 4, 0,121, 9, 4, 0,122, 9, 0, 0, 92, 0, 0, 0, 20, 0, 9, 0, 2, 0, + 92, 0, 6, 0,124, 1,123, 9, 4, 0,124, 9, 4, 0,125, 9, 4, 0,126, 9, 4, 0, 37, 0, 9, 0,127, 9,125, 1, 5, 0, + 7, 0,129, 2, 7, 0,196, 2, 7, 0, 14, 2, 2, 0,128, 9, 2, 0, 37, 0,126, 1, 5, 0, 7, 0,129, 2, 7, 0,129, 9, + 7, 0,130, 9, 7, 0,131, 9, 7, 0,196, 2,127, 1, 5, 0, 32, 0,132, 9,128, 1, 22, 0, 7, 0,133, 9, 7, 0,134, 9, + 7, 0, 57, 0,129, 1, 7, 0, 4, 0,135, 9, 4, 0,136, 9, 4, 0,137, 9, 7, 0,138, 9, 7, 0,139, 9, 7, 0,140, 9, + 7, 0,141, 9,130, 1, 8, 0,130, 1, 0, 0,130, 1, 1, 0, 32, 0, 45, 0, 4, 0, 14, 3, 2, 0, 19, 0, 2, 0, 40, 1, + 7, 0,196, 2, 7, 0, 11, 8,131, 1, 18, 0,126, 1,143, 3,126, 1,142, 9,125, 1,143, 9,126, 1,251, 7,127, 1,144, 9, + 4, 0, 82, 0, 7, 0,196, 2, 7, 0,223, 2, 7, 0,145, 9, 4, 0,135, 9, 4, 0,146, 9, 7, 0,139, 9, 7, 0,140, 9, + 7, 0,106, 0, 2, 0, 19, 0, 2, 0,147, 9, 2, 0,148, 9, 2, 0,149, 9,132, 1,107, 0, 27, 0, 31, 0, 39, 0, 75, 0, +133, 1,150, 9, 4, 0, 19, 0, 2, 0, 17, 0, 2, 0,228, 8, 2, 0,151, 9, 2, 0,152, 9, 2, 0,159, 8, 2, 0,153, 9, + 2, 0,154, 9, 2, 0,155, 9, 2, 0,156, 9, 2, 0,157, 9, 2, 0,158, 9, 2, 0,159, 9, 2, 0,178, 3, 2, 0, 48, 5, + 2, 0,160, 9, 2, 0,161, 9, 2, 0,162, 9, 2, 0,163, 9, 2, 0,164, 9, 2, 0, 3, 2, 2, 0,244, 7, 2, 0,220, 7, + 2, 0,165, 9, 2, 0,166, 9, 2, 0,176, 3, 2, 0,177, 3, 2, 0,167, 9, 2, 0,168, 9, 2, 0,169, 9, 2, 0,170, 9, + 7, 0,171, 9, 7, 0,172, 9, 7, 0,173, 9, 2, 0,174, 9, 2, 0,175, 9, 7, 0,176, 9, 7, 0,177, 9, 7, 0,178, 9, + 7, 0,226, 7, 7, 0, 89, 0, 7, 0,223, 2, 7, 0,232, 7, 7, 0,179, 9, 7, 0,180, 9, 7, 0,181, 9, 4, 0,227, 7, + 4, 0,225, 7, 4, 0,182, 9, 7, 0,228, 7, 7, 0,229, 7, 7, 0,230, 7, 7, 0,183, 9, 7, 0,184, 9, 7, 0,185, 9, + 7, 0,186, 9, 7, 0,187, 9, 7, 0,188, 9, 7, 0,189, 9, 7, 0,190, 9, 7, 0,100, 3, 7, 0,106, 0, 7, 0,191, 9, + 7, 0,192, 9, 7, 0,193, 9, 7, 0,194, 9, 7, 0,195, 9, 7, 0,196, 9, 7, 0,197, 9, 4, 0,198, 9, 4, 0,199, 9, + 7, 0,200, 9, 7, 0,201, 9, 7, 0,202, 9, 7, 0,203, 9, 7, 0,204, 9, 7, 0,205, 9, 7, 0,206, 9, 7, 0,172, 3, + 7, 0,170, 3, 7, 0,171, 3, 7, 0,207, 9, 7, 0,208, 9, 7, 0,209, 9, 7, 0,210, 9, 7, 0,211, 9, 7, 0,212, 9, + 7, 0,213, 9, 7, 0,214, 9, 7, 0,215, 9, 7, 0,216, 9, 7, 0,217, 9, 7, 0,218, 9, 7, 0,219, 9, 4, 0,220, 9, + 4, 0,221, 9, 7, 0,222, 9, 68, 0,132, 3, 68, 0,223, 9, 32, 0,224, 9, 32, 0,225, 9, 36, 0, 80, 0,163, 0, 32, 1, +163, 0,226, 9, 59, 0, 43, 0, 59, 0, 0, 0, 59, 0, 1, 0,132, 1,227, 9,131, 1,228, 9,129, 1,153, 8,168, 0,198, 3, + 9, 0,199, 3,134, 1,229, 9,134, 1,230, 9, 12, 0,231, 9, 12, 0,232, 9,134, 0,233, 9,142, 0,234, 9,142, 0,235, 9, + 32, 0,236, 9, 32, 0,237, 9, 32, 0, 38, 0, 12, 0,238, 9, 12, 0,239, 9, 12, 0,198, 8, 0, 0, 20, 0, 7, 0,210, 0, + 7, 0,250, 2, 7, 0,240, 9, 4, 0,170, 2, 4, 0, 57, 0, 4, 0, 19, 0, 4, 0,227, 7, 4, 0,241, 9, 4, 0,242, 9, + 4, 0,243, 9, 2, 0,217, 0, 2, 0,244, 9, 2, 0,245, 9, 2, 0,246, 9, 0, 0,247, 9, 2, 0,248, 9, 2, 0,249, 9, + 2, 0,250, 9, 9, 0,251, 9,138, 0, 15, 4, 12, 0,237, 2,135, 1,252, 9,136, 0, 34, 0,136, 1,110, 8, 7, 0,241, 3, + 7, 0,253, 9, 7, 0,254, 9, 7, 0, 77, 4, 7, 0,255, 9, 7, 0,110, 3, 7, 0,100, 3, 7, 0, 0, 10, 7, 0, 62, 2, + 7, 0, 1, 10, 7, 0, 2, 10, 7, 0, 3, 10, 7, 0, 4, 10, 7, 0, 5, 10, 7, 0, 6, 10, 7, 0,242, 3, 7, 0, 7, 10, + 7, 0, 8, 10, 7, 0, 9, 10, 7, 0,243, 3, 7, 0,239, 3, 7, 0,240, 3, 7, 0, 10, 10, 4, 0, 11, 10, 4, 0, 90, 0, + 4, 0, 12, 10, 4, 0, 13, 10, 2, 0, 14, 10, 2, 0, 15, 10, 2, 0, 16, 10, 2, 0, 17, 10, 2, 0, 18, 10, 2, 0, 37, 0, +137, 0, 8, 0,136, 1, 19, 10, 7, 0, 20, 10, 7, 0, 21, 10, 7, 0,213, 1, 7, 0, 22, 10, 4, 0, 90, 0, 2, 0, 23, 10, + 2, 0, 24, 10,137, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 25, 10,138, 1, 6, 0,138, 1, 0, 0, +138, 1, 1, 0,137, 1,144, 8, 4, 0,223, 0, 2, 0, 26, 10, 2, 0, 19, 0,139, 1, 5, 0,139, 1, 0, 0,139, 1, 1, 0, + 12, 0, 27, 10, 4, 0, 28, 10, 4, 0, 19, 0,140, 1, 9, 0,140, 1, 0, 0,140, 1, 1, 0, 12, 0,124, 0,139, 1, 29, 10, + 4, 0, 19, 0, 2, 0, 26, 10, 2, 0, 30, 10, 7, 0, 91, 0, 0, 0, 31, 10,161, 0, 6, 0, 27, 0, 31, 0, 12, 0,201, 4, + 4, 0, 19, 0, 2, 0, 32, 10, 2, 0, 33, 10, 9, 0, 34, 10,141, 1, 7, 0,141, 1, 0, 0,141, 1, 1, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 4, 0, 23, 0, 0, 0, 35, 10, 0, 0, 36, 10,142, 1, 5, 0, 12, 0, 37, 10, 4, 0, 38, 10, 4, 0, 39, 10, + 4, 0, 19, 0, 4, 0, 37, 0,143, 1, 13, 0, 27, 0, 31, 0,144, 1, 40, 10,144, 1, 41, 10, 12, 0, 42, 10, 4, 0, 43, 10, + 2, 0, 44, 10, 2, 0, 37, 0, 12, 0, 45, 10, 12, 0, 46, 10,142, 1, 47, 10, 12, 0, 48, 10, 12, 0, 49, 10, 12, 0, 50, 10, +144, 1, 30, 0,144, 1, 0, 0,144, 1, 1, 0, 9, 0, 51, 10, 4, 0, 77, 7, 4, 0, 37, 0,211, 0,248, 5,211, 0, 52, 10, + 0, 0, 53, 10, 2, 0, 54, 10, 2, 0, 55, 10, 2, 0, 98, 7, 2, 0, 99, 7, 2, 0, 56, 10, 2, 0, 57, 10, 2, 0,148, 3, + 2, 0,107, 6, 2, 0, 58, 10, 2, 0, 59, 10, 4, 0,209, 1,145, 1, 60, 10,146, 1, 61, 10,147, 1, 62, 10, 4, 0, 63, 10, + 4, 0, 64, 10, 9, 0, 65, 10, 12, 0, 66, 10, 12, 0, 46, 10, 12, 0,116, 7, 12, 0, 67, 10, 12, 0, 68, 10,148, 1, 16, 0, +148, 1, 0, 0,148, 1, 1, 0, 0, 0, 69, 10,149, 1, 70, 10, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 71, 10, 2, 0, 72, 10, + 2, 0, 73, 10, 2, 0, 74, 10, 2, 0, 75, 10, 2, 0, 76, 10, 2, 0, 77, 10, 2, 0, 78, 10, 2, 0, 70, 0, 2, 0,209, 1, +150, 1, 9, 0,150, 1, 0, 0,150, 1, 1, 0, 12, 0, 79, 10, 0, 0, 80, 10, 2, 0, 81, 10, 2, 0, 82, 10, 2, 0, 83, 10, + 2, 0, 37, 0, 9, 0, 84, 10,219, 0, 12, 0,219, 0, 0, 0,219, 0, 1, 0, 0, 0, 69, 10, 26, 0, 30, 0,151, 1, 92, 7, + 9, 0, 85, 10,149, 1, 70, 10,142, 1, 86, 10, 12, 0, 87, 10,219, 0, 88, 10, 2, 0, 19, 0, 2, 0,105, 1,145, 1, 23, 0, +145, 1, 0, 0,145, 1, 1, 0, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 5, 0, 2, 0, 6, 0, 2, 0, 89, 10, 2, 0, 90, 10, + 2, 0, 91, 10, 2, 0, 92, 10, 0, 0, 93, 10, 0, 0, 37, 0, 2, 0, 71, 10, 2, 0, 72, 10, 2, 0, 73, 10, 2, 0, 74, 10, + 2, 0, 75, 10, 2, 0, 43, 0, 0, 0, 94, 10, 2, 0, 95, 10, 2, 0, 96, 10, 4, 0, 70, 0, 9, 0, 85, 10,152, 1, 8, 0, +152, 1, 0, 0,152, 1, 1, 0, 9, 0, 2, 0, 9, 0, 97, 10, 0, 0,193, 3, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0, 98, 10, +153, 1, 5, 0, 7, 0, 99, 10, 4, 0,100, 10, 4, 0,101, 10, 4, 0, 40, 1, 4, 0, 19, 0,154, 1, 6, 0, 7, 0,102, 10, + 7, 0,103, 10, 7, 0,104, 10, 7, 0,105, 10, 4, 0, 17, 0, 4, 0, 19, 0,155, 1, 5, 0, 7, 0, 67, 8, 7, 0, 68, 8, + 7, 0,196, 2, 2, 0, 17, 2, 2, 0, 18, 2,156, 1, 5, 0,155, 1, 2, 0, 4, 0, 54, 0, 7, 0,106, 10, 7, 0, 67, 8, + 7, 0, 68, 8,157, 1, 4, 0, 2, 0,107, 10, 2, 0,108, 10, 2, 0,109, 10, 2, 0,110, 10,158, 1, 2, 0, 42, 0, 78, 6, + 26, 0,147, 8,159, 1, 3, 0, 24, 0,111, 10, 4, 0, 19, 0, 4, 0, 37, 0,160, 1, 6, 0, 7, 0,106, 0, 7, 0,198, 2, + 7, 0,112, 10, 7, 0, 37, 0, 2, 0,216, 0, 2, 0,113, 10,161, 1, 7, 0,161, 1, 0, 0,161, 1, 1, 0, 27, 0, 81, 6, + 0, 0,114, 10, 4, 0,115, 10, 4, 0, 90, 0, 0, 0,193, 3,162, 1, 6, 0, 12, 0,198, 8, 0, 0,116, 10, 7, 0, 61, 0, + 7, 0, 98, 10, 4, 0, 17, 0, 4, 0, 19, 0,163, 1, 3, 0, 7, 0,117, 10, 4, 0, 19, 0, 4, 0, 37, 0,164, 1, 15, 0, +164, 1, 0, 0,164, 1, 1, 0, 70, 1,186, 8,162, 1, 62, 0, 12, 0, 73, 3, 35, 0, 50, 0,163, 1,118, 10, 4, 0, 54, 0, + 7, 0, 61, 0, 2, 0, 19, 0, 2, 0, 25, 1, 4, 0,115, 10, 0, 0,114, 10, 4, 0,119, 10, 7, 0,120, 10,165, 1, 2, 0, + 0, 0,121, 10, 0, 0,122, 10,166, 1, 4, 0,166, 1, 0, 0,166, 1, 1, 0,159, 0, 27, 3, 12, 0,123, 10,167, 1, 24, 0, +167, 1, 0, 0,167, 1, 1, 0, 12, 0,124, 10,159, 0, 41, 8,166, 1,125, 10, 12, 0,126, 10, 12, 0, 73, 3, 0, 0,193, 3, + 7, 0, 98, 10, 7, 0,127, 10, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,243, 8, 7, 0,244, 8, 7, 0,213, 2, 7, 0,247, 8, + 7, 0, 43, 8, 7, 0,248, 8, 2, 0,128, 10, 2, 0,129, 10, 2, 0, 43, 0, 2, 0, 17, 0, 4, 0, 19, 0, 4, 0, 70, 0, +168, 1, 6, 0,168, 1, 0, 0,168, 1, 1, 0, 12, 0,124, 10, 4, 0, 19, 0, 4, 0,133, 2, 0, 0,193, 3,169, 1, 10, 0, +169, 1, 0, 0,169, 1, 1, 0, 27, 0, 81, 6, 0, 0,130, 10, 4, 0,131, 10, 4, 0,132, 10, 0, 0,114, 10, 4, 0,115, 10, + 2, 0, 19, 0, 2, 0,133, 10,170, 1, 6, 0,170, 1, 0, 0,170, 1, 1, 0, 12, 0,134, 10, 0, 0,193, 3, 4, 0, 19, 0, + 4, 0,135, 10,171, 1, 5, 0,171, 1, 0, 0,171, 1, 1, 0, 0, 0,114, 10, 4, 0,115, 10, 7, 0,186, 2, 39, 0, 12, 0, +159, 0, 67, 3,159, 0,136, 10,166, 1,125, 10, 12, 0,137, 10,167, 1,138, 10, 12, 0,139, 10, 12, 0,140, 10, 4, 0, 19, 0, + 4, 0,217, 0, 2, 0,141, 10, 2, 0,142, 10, 7, 0,143, 10,172, 1, 2, 0, 27, 0, 31, 0, 39, 0, 75, 0,173, 1, 5, 0, +173, 1, 0, 0,173, 1, 1, 0, 4, 0, 17, 0, 4, 0, 19, 0, 0, 0, 20, 0,174, 1, 6, 0,173, 1,144, 10, 32, 0, 45, 0, + 4, 0,145, 10, 7, 0,146, 10, 4, 0,147, 10, 4, 0,175, 8,175, 1, 3, 0,173, 1,144, 10, 4, 0,145, 10, 7, 0,148, 10, +176, 1, 8, 0,173, 1,144, 10, 32, 0, 45, 0, 7, 0, 35, 1, 7, 0,149, 10, 7, 0,250, 2, 7, 0,109, 8, 4, 0,145, 10, + 4, 0,150, 10,177, 1, 5, 0,173, 1,144, 10, 7, 0,151, 10, 7, 0,185, 7, 7, 0,219, 2, 7, 0, 57, 0,178, 1, 3, 0, +173, 1,144, 10, 7, 0,109, 8, 7, 0,152, 10,128, 1, 4, 0, 7, 0,153, 10, 7, 0,193, 9, 2, 0,154, 10, 2, 0, 40, 1, +179, 1, 14, 0,179, 1, 0, 0,179, 1, 1, 0, 12, 0,155, 10, 12, 0,156, 10, 12, 0,157, 10, 0, 0, 20, 0, 4, 0, 31, 0, + 4, 0, 19, 0, 4, 0,158, 10, 7, 0,159, 10, 4, 0,147, 10, 4, 0,175, 8, 7, 0,202, 3, 7, 0,221, 2,133, 1, 23, 0, + 4, 0,145, 10, 4, 0,160, 10, 7, 0,161, 10, 7, 0, 57, 0, 7, 0,162, 10, 7, 0,217, 2, 7, 0,153, 10, 7, 0,163, 10, + 7, 0,198, 2, 7, 0,164, 10, 7, 0, 74, 4, 7, 0,165, 10, 7, 0,166, 10, 7, 0,167, 10, 7, 0,168, 10, 7, 0,169, 10, + 7, 0,170, 10, 7, 0,171, 10, 7, 0,172, 10, 7, 0,173, 10, 7, 0,174, 10, 7, 0,175, 10, 12, 0,176, 10,122, 0, 33, 0, +121, 0,177, 10,180, 1,178, 10, 68, 0,179, 10, 68, 0,223, 9, 68, 0,180, 10,181, 1,181, 10, 48, 0,165, 0, 48, 0,182, 10, + 48, 0,183, 10, 7, 0,184, 10, 7, 0,185, 10, 7, 0,186, 10, 7, 0,187, 10, 7, 0,188, 10, 7, 0,187, 8, 7, 0,189, 10, + 7, 0,141, 1, 7, 0,190, 10, 4, 0,191, 10, 4, 0,192, 10, 4, 0,193, 10, 4, 0, 90, 0, 4, 0, 37, 0, 4, 0,194, 10, + 2, 0,195, 10, 2, 0,196, 10, 4, 0,197, 10, 7, 0,198, 2, 4, 0,198, 10, 7, 0,199, 10, 4, 0,200, 10,138, 0,201, 10, + 12, 0,202, 10,123, 0, 11, 0,121, 0,177, 10, 59, 0,225, 0, 7, 0,106, 1, 7, 0,187, 8, 7, 0,203, 10, 7, 0,204, 10, + 2, 0,205, 10, 2, 0,206, 10, 2, 0,207, 10, 2, 0, 17, 0, 4, 0, 37, 0,124, 0, 13, 0,121, 0,177, 10,140, 0,247, 2, +142, 0,249, 2, 7, 0,144, 8, 7, 0,208, 10, 7, 0,209, 10, 7, 0, 37, 1, 7, 0,210, 10, 4, 0,211, 10, 4, 0,245, 2, + 2, 0, 17, 0, 2, 0, 37, 0, 4, 0, 70, 0, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -- cgit v1.2.3 From 0338b05a64184ce1a439a418ebc4e315185c1eec Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 08:47:13 +0000 Subject: =?UTF-8?q?Three=20node=20selection=20operators=20added,=20patch?= =?UTF-8?q?=20by=20Micha=C5=82=20Ziu=C5=82ek,=20thanks!=20*=20Select=20all?= =?UTF-8?q?=20*=20Select=20linked=20to=20*=20Select=20linked=20from?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- release/ui/space_node.py | 9 +- source/blender/editors/space_node/node_edit.c | 46 +-------- source/blender/editors/space_node/node_intern.h | 5 +- source/blender/editors/space_node/node_ops.c | 8 +- source/blender/editors/space_node/node_select.c | 120 +++++++++++++++++++++++- 5 files changed, 136 insertions(+), 52 deletions(-) diff --git a/release/ui/space_node.py b/release/ui/space_node.py index 6ac1ac84f35..55b2065084b 100644 --- a/release/ui/space_node.py +++ b/release/ui/space_node.py @@ -74,11 +74,10 @@ class NODE_MT_select(bpy.types.Menu): layout.itemO("node.select_border") - # XXX - # layout.itemS() - # layout.itemO("node.select_all") - # layout.itemO("node.select_linked_from") - # layout.itemO("node.select_linked_to") + layout.itemS() + layout.itemO("node.select_all") + layout.itemO("node.select_linked_from") + layout.itemO("node.select_linked_to") class NODE_MT_node(bpy.types.Menu): __space_type__ = 'NODE_EDITOR' diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index bc81c25d106..159a4036914 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1229,27 +1229,14 @@ Material *editnode_get_active_material(Material *ma) /* no undo here! */ -void node_deselectall(SpaceNode *snode, int swap) +void node_deselectall(SpaceNode *snode) { bNode *node; - if(swap) { - for(node= snode->edittree->nodes.first; node; node= node->next) - if(node->flag & SELECT) - break; - if(node==NULL) { - for(node= snode->edittree->nodes.first; node; node= node->next) - node->flag |= SELECT; - return; - } - /* else pass on to deselect */ - } - for(node= snode->edittree->nodes.first; node; node= node->next) node->flag &= ~SELECT; } - int node_has_hidden_sockets(bNode *node) { bNodeSocket *sock; @@ -1606,7 +1593,7 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float { bNode *node= NULL, *gnode; - node_deselectall(snode, 0); + node_deselectall(snode); if(type>=NODE_DYNAMIC_MENU) { node= nodeAddNodeType(snode->edittree, type, NULL, NULL); @@ -2091,32 +2078,6 @@ void node_insert_key(SpaceNode *snode) } } -void node_select_linked(SpaceNode *snode, int out) -{ - bNodeLink *link; - bNode *node; - - /* NODE_TEST is the free flag */ - for(node= snode->edittree->nodes.first; node; node= node->next) - node->flag &= ~NODE_TEST; - - for(link= snode->edittree->links.first; link; link= link->next) { - if(out) { - if(link->fromnode->flag & NODE_SELECT) - link->tonode->flag |= NODE_TEST; - } - else { - if(link->tonode->flag & NODE_SELECT) - link->fromnode->flag |= NODE_TEST; - } - } - - for(node= snode->edittree->nodes.first; node; node= node->next) - if(node->flag & NODE_TEST) - node->flag |= NODE_SELECT; - -} - /* makes a link between selected output and input sockets */ void node_make_link(SpaceNode *snode) { @@ -2451,9 +2412,6 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(fromlib) fromlib= -1; else toolbox_n_add(); } - else if(G.qual==0) { - node_deselectall(snode, 1); - } break; case BKEY: if(G.qual==0) diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 5c66c902797..6fdaeca7701 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -58,6 +58,9 @@ void node_keymap(wmWindowManager *wm); /* node_select.c */ void NODE_OT_select(struct wmOperatorType *ot); void NODE_OT_select_extend(struct wmOperatorType *ot); +void NODE_OT_select_all(wmOperatorType *ot); +void NODE_OT_select_linked_to(wmOperatorType *ot); +void NODE_OT_select_linked_from(wmOperatorType *ot); void NODE_OT_visibility_toggle(struct wmOperatorType *ot); void NODE_OT_view_all(struct wmOperatorType *ot); void NODE_OT_select_border(struct wmOperatorType *ot); @@ -76,7 +79,7 @@ void snode_set_context(SpaceNode *snode, Scene *scene); void snode_make_group_editable(SpaceNode *snode, bNode *gnode); void snode_home(ScrArea *sa, ARegion *ar, SpaceNode *snode); void node_set_active(SpaceNode *snode, bNode *node); -void node_deselectall(SpaceNode *snode, int swap); +void node_deselectall(SpaceNode *snode); void snode_composite_job(const struct bContext *C, ScrArea *sa); bNode *snode_get_editgroup(SpaceNode *snode); void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index f78abb28313..af857d57634 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -51,6 +51,9 @@ void node_operatortypes(void) { WM_operatortype_append(NODE_OT_select); WM_operatortype_append(NODE_OT_select_extend); + WM_operatortype_append(NODE_OT_select_all); + WM_operatortype_append(NODE_OT_select_linked_to); + WM_operatortype_append(NODE_OT_select_linked_from); WM_operatortype_append(NODE_OT_visibility_toggle); WM_operatortype_append(NODE_OT_view_all); WM_operatortype_append(NODE_OT_select_border); @@ -59,7 +62,6 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_resize); WM_operatortype_append(NODE_OT_links_cut); WM_operatortype_append(NODE_OT_duplicate); - } void node_keymap(struct wmWindowManager *wm) @@ -82,6 +84,10 @@ void node_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_delete", XKEY, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "NODE_OT_select_all", AKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_select_linked_to", LKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "NODE_OT_select_linked_from", LKEY, KM_PRESS, 0, 0); transform_keymap_for_space(wm, keymap, SPACE_NODE); } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 73becc1ebe8..94e17b56a02 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -83,7 +83,7 @@ static void node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short } if(node) { if((extend & KM_SHIFT)==0) - node_deselectall(snode, 0); + node_deselectall(snode); if(extend & KM_SHIFT) { if(node->flag & SELECT) @@ -291,3 +291,121 @@ void NODE_OT_select_border(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", prop_select_types, 0, "Type", ""); } + +/* ****** Select/Deselect All ****** */ + +static int node_select_all_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *first = snode->edittree->nodes.first; + bNode *node; + int count= 0; + + for(node=first; node; node=node->next) + if(node->flag & NODE_SELECT) + count++; + + if(count) { + for(node=first; node; node=node->next) + node->flag &= ~NODE_SELECT; + } + else { + for(node=first; node; node=node->next) + node->flag |= NODE_SELECT; + } + + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + return OPERATOR_FINISHED; +} + +void NODE_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select/Deselect All"; + ot->description = "(De)select all nodes."; + ot->idname = "NODE_OT_select_all"; + + /* api callbacks */ + ot->exec = node_select_all_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ****** Select Linked To ****** */ + +static int node_select_linked_to_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeLink *link; + bNode *node; + + for (node=snode->edittree->nodes.first; node; node=node->next) + node->flag &= ~NODE_TEST; + + for (link=snode->edittree->links.first; link; link=link->next) + if (link->fromnode->flag & NODE_SELECT) + link->tonode->flag |= NODE_TEST; + + for (node=snode->edittree->nodes.first; node; node=node->next) + if (node->flag & NODE_TEST) + node->flag |= NODE_SELECT; + + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + return OPERATOR_FINISHED; +} + +void NODE_OT_select_linked_to(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked To"; + ot->description = "Select nodes linked to the selected ones."; + ot->idname = "NODE_OT_select_linked_to"; + + /* api callbacks */ + ot->exec = node_select_linked_to_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* ****** Select Linked From ****** */ + +static int node_select_linked_from_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeLink *link; + bNode *node; + + for(node=snode->edittree->nodes.first; node; node=node->next) + node->flag &= ~NODE_TEST; + + for(link=snode->edittree->links.first; link; link=link->next) + if(link->tonode->flag & NODE_SELECT) + link->fromnode->flag |= NODE_TEST; + + for(node=snode->edittree->nodes.first; node; node=node->next) + if(node->flag & NODE_TEST) + node->flag |= NODE_SELECT; + + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + return OPERATOR_FINISHED; +} + +void NODE_OT_select_linked_from(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked From"; + ot->description = "Select nodes linked from the selected ones."; + ot->idname = "NODE_OT_select_linked_from"; + + /* api callbacks */ + ot->exec = node_select_linked_from_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + -- cgit v1.2.3 From ce70ed260b45c48ee43e5f13b372cc0d68f76be4 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 10:21:41 +0000 Subject: Smoke: * Bugifx for no shadow on startframe when loaded from cache --- source/blender/blenkernel/intern/smoke.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 67744ab56a2..6485e367b78 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1179,6 +1179,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM // simulate the actual smoke (c++ code in intern/smoke) if(framenr!=startframe) smoke_step(sds->fluid, smd->time); + + // create shadows before writing cache so we get nice shadows for sstartframe, too + if(get_lamp(scene, light)) + smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + BKE_ptcache_write_cache(&pid, framenr); if(sds->wt) @@ -1191,9 +1196,6 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM BKE_ptcache_write_cache(&pid_wt, framenr); } - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); - tend(); printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() ); } -- cgit v1.2.3 From b0a3224d898fdf58afe6c548dd53307172126856 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 10:37:13 +0000 Subject: Smoke: * put another drawing method in to test for broken --- source/blender/editors/space_view3d/drawobject.c | 47 +++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c02d45ca798..2c4d72f64ab 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5360,12 +5360,57 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) { if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { +// #if0 smd->domain->tex = NULL; GPU_create_smoke(smd, 0); draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); GPU_free_smoke(smd); +// #endif +#if 0 + int x, y, z; + float *density = smoke_get_density(smd->domain->fluid); + + wmLoadMatrix(rv3d->viewmat); + // wmMultMatrix(ob->obmat); + + if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + + + // glPointSize(3.0); + bglBegin(GL_POINTS); + + for(x = 0; x < smd->domain->res[0]; x++) + for(y = 0; y < smd->domain->res[1]; y++) + for(z = 0; z < smd->domain->res[2]; z++) + { + float tmp[3]; + int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z); + + if(density[index] > FLT_EPSILON) + { + float color[3]; + VECCOPY(tmp, smd->domain->p0); + tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5; + tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5; + tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5; + color[0] = color[1] = color[2] = 1.0; // density[index]; + glColor3fv(color); + bglVertex3fv(tmp); + } + } + + bglEnd(); + glPointSize(1.0); + + wmMultMatrix(ob->obmat); + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + if(col) cpack(col); +#endif } - else if(smd->domain->wt || (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) + else if(smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { smd->domain->tex = NULL; GPU_create_smoke(smd, 1); -- cgit v1.2.3 From f896b905ace685148dccad9ddfbda92ae1c65d85 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 14 Sep 2009 10:56:40 +0000 Subject: Bugfixes: * #19338: Crash when using Convert operator Uninitialised var (basact) * Spacebar when in 3D-View EditMode for Text gets overridden by Search Menu. I've tried adding a fix there, but it doesn't seem to work. Woraround for now is shift-space for entering text. * Fixed some compiled warnings in wm_operators.c about naming of var named 'main' --- source/blender/editors/object/object_add.c | 2 +- source/blender/windowmanager/intern/wm_operators.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 833d3914e47..ee9af61f516 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -885,7 +885,7 @@ static int convert_poll(bContext *C) static int convert_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Base *basen=NULL, *basact, *basedel=NULL; + Base *basen=NULL, *basact=NULL, *basedel=NULL; Object *ob, *ob1, *obact= CTX_data_active_object(C); DerivedMesh *dm; Curve *cu; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b57edcb4dfc..c01ce5b6e35 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -34,6 +34,7 @@ #include #include "DNA_ID.h" +#include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" @@ -751,6 +752,7 @@ int wm_search_menu_poll(bContext *C) if(CTX_wm_window(C)==NULL) return 0; if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_CONSOLE) return 0; // XXX - so we can use the shortcut in the console if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_TEXT) return 0; // XXX - so we can use the spacebar in the text editor + if(CTX_data_edit_object(C) && CTX_data_edit_object(C)->type==OB_CURVE) return 0; // XXX - so we can use the spacebar for entering text return 1; } @@ -996,11 +998,10 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX]; int idcode; BlendHandle *bh; - struct Main *main= CTX_data_main(C); + struct Main *mainvar= CTX_data_main(C); struct Scene *scene= CTX_data_scene(C); struct Main *mainl= 0; - struct ScrArea *sa= CTX_wm_area(C); PropertyRNA *prop; int totfiles=0; short flag; @@ -1015,7 +1016,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) } else if (group[0]==0) { BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); return OPERATOR_FINISHED; - } else if (BLI_streq(main->name, libname)) { + } else if (BLI_streq(mainvar->name, libname)) { BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library"); return OPERATOR_FINISHED; } @@ -1063,11 +1064,11 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) BLO_library_append_end(C, mainl, &bh, idcode, flag); /* DISPLISTS? */ - recalc_all_library_objects(main); + recalc_all_library_objects(mainvar); /* Append, rather than linking */ if ((flag & FILE_LINK)==0) { - make_library_local(libname, main); + make_library_local(libname, mainvar); } /* do we need to do this? */ -- cgit v1.2.3 From e838af4d57ea1f0eef4fd62bfb0a8d6e320c72e0 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 14 Sep 2009 11:12:44 +0000 Subject: Bugfix #19337: Crash when tweaking knife operator Knife operator now doesn't crash, but repeat operator for this won't work now since the appropriate 3D-View context info is not set when the mouse is in the Tools region (i.e. when using repeat operator in the tools panels). --- source/blender/editors/mesh/editmesh_loop.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c index c98b387d28a..28103828dd4 100644 --- a/source/blender/editors/mesh/editmesh_loop.c +++ b/source/blender/editors/mesh/editmesh_loop.c @@ -60,6 +60,7 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv #include "BKE_library.h" #include "BKE_mesh.h" #include "BKE_object.h" +#include "BKE_report.h" #include "BKE_utildefines.h" #include "PIL_time.h" @@ -637,6 +638,10 @@ static int knife_cut_exec(bContext *C, wmOperator *op) int len=0; short numcuts=1, mode= RNA_int_get(op->ptr, "type"); + /* edit-object needed for matrix, and ar->regiondata for projections to work */ + if (ELEM3(NULL, obedit, ar, ar->regiondata)) + return OPERATOR_CANCELLED; + if (EM_nvertices_selected(em) < 2) { error("No edges are selected to operate on"); BKE_mesh_end_editmesh(obedit->data, em); -- cgit v1.2.3 From d0aa03737eff52b1c54644cb5e9d3d68daa2986c Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 14 Sep 2009 11:25:33 +0000 Subject: * Fix for typo in icon_only commit, causing RNA property buttons text to be doubled up brecht: I think this is right now...? :) --- source/blender/editors/interface/interface_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 6211c79beca..242ba31ccd4 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -506,7 +506,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i but= uiDefIconButO(block, BUT, "BUTTONS_OT_file_browse", WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, "Browse for file or directory."); } else - but= uiDefAutoButR(block, ptr, prop, index, (icon_only)? "": NULL, icon, x, y, w, h); + but= uiDefAutoButR(block, ptr, prop, index, (!icon_only)? "": NULL, icon, x, y, w, h); uiBlockSetCurLayout(block, layout); return but; -- cgit v1.2.3 From 75d4a836b8427f1d71f41d037390352bffeafee4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 12:16:35 +0000 Subject: UI: don't hide Object menu in 3d view header when there is no active object, to avoid buttons jumping too much. Also small change in collision panel code. --- release/ui/buttons_physics_field.py | 8 +++----- release/ui/space_view3d.py | 2 ++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/release/ui/buttons_physics_field.py b/release/ui/buttons_physics_field.py index 58033d2c431..252b3bdb08a 100644 --- a/release/ui/buttons_physics_field.py +++ b/release/ui/buttons_physics_field.py @@ -184,18 +184,16 @@ class PHYSICS_PT_collision(PhysicButtonsPanel): #row.itemR(md, "render", text="") #row.itemR(md, "realtime", text="") - coll = md.settings + settings = md.settings else: # add modifier split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add") split.itemL() - coll = None + settings = None - if coll: - settings = context.object.collision - + if settings: layout.active = settings.enabled split = layout.split() diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index df6579542d4..2539ded18bf 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -34,6 +34,8 @@ class VIEW3D_HT_header(bpy.types.Header): if mode_string not in ['PAINT_WEIGHT', 'PAINT_TEXTURE']: sub.itemM("VIEW3D_MT_%s" % mode_string) + else: + sub.itemM("VIEW3D_MT_OBJECT") layout.template_header_3D() -- cgit v1.2.3 From 8d3955c28d4f3db7026dc7f1a33a421a727f89d3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 12:26:34 +0000 Subject: Depsgraph: * Move function to compute visible screen layers to BKE. * Use this now in the depsgraph, was still using this all layers to flush. Still missing a way to get the current scene in background mode.. * Also two more function to not require a scene pointer anymore: * DAG_object_update_flags is now DAG_id_update_flags. * DAG_ids_flush_update is now available next to DAG_scene_flush_update. --- source/blender/blenkernel/BKE_depsgraph.h | 13 ++-- source/blender/blenkernel/BKE_screen.h | 6 +- source/blender/blenkernel/intern/depsgraph.c | 75 +++++++++++++++++----- source/blender/blenkernel/intern/screen.c | 21 ++++++ source/blender/editors/animation/anim_deps.c | 14 +--- .../editors/armature/editarmature_retarget.c | 2 - source/blender/editors/include/ED_screen.h | 1 - source/blender/editors/preview/previewrender.c | 3 +- source/blender/editors/screen/screen_edit.c | 19 +----- 9 files changed, 96 insertions(+), 58 deletions(-) diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index e242ead3b87..17a4749f704 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -96,19 +96,24 @@ void draw_all_deps(void); /* ********** API *************** */ /* Note that the DAG never executes changes in Objects, only sets flags in Objects */ + /* (re)-create dependency graph for scene */ void DAG_scene_sort(struct Scene *sce); /* flag all objects that need recalc because they're animated */ void DAG_scene_update_flags(struct Scene *sce, unsigned int lay); - /* flag all objects that need recalc because they're animated, influencing this object only */ -void DAG_object_update_flags(struct Scene *sce, struct Object *ob, unsigned int lay); - /* flushes all recalc flags in objects down the dependency tree */ void DAG_scene_flush_update(struct Scene *sce, unsigned int lay, int time); + + /* flag all IDs that need recalc because they're animated, influencing + this ID only. only for objects currently */ +void DAG_id_update_flags(struct ID *id); /* flushes all recalc flags for this object down the dependency tree, - but not the DAG only supports objects and object data currently */ + but note the DAG only supports objects and object data currently */ void DAG_id_flush_update(struct ID *id, short flag); + /* when setting manual RECALC flags, call this afterwards */ +void DAG_ids_flush_update(int time); + /* (re)-create dependency graph for armature pose */ void DAG_pose_sort(struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 4fcb7c881be..ee04d4f47bc 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -230,11 +230,11 @@ void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2); /* area/regions */ struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar); void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar); +void BKE_screen_area_free(struct ScrArea *sa); -void BKE_screen_area_free(struct ScrArea *sa); - +/* screen */ void free_screen(struct bScreen *sc); - +unsigned int BKE_screen_visible_layers(struct bScreen *screen); #endif diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 6a14762e0ed..58f3db50d0f 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -78,6 +78,7 @@ #include "BKE_pointcache.h" #include "BKE_utildefines.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "MEM_guardedalloc.h" @@ -2142,30 +2143,58 @@ void DAG_scene_update_flags(Scene *scene, unsigned int lay) } -void DAG_id_flush_update(ID *id, short flag) +static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay) { - Main *bmain= G.main; wmWindowManager *wm; wmWindow *win; - Scene *sce; - Object *obt, *ob= NULL; - short idtype; /* only one scene supported currently, making more scenes work correctly requires changes beyond just the dependency graph */ + *sce= NULL; + *lay= 0; + if((wm= bmain->wm.first)) { - /* if we have a windowmanager, use sce from first window */ + /* if we have a windowmanager, look into windows */ for(win=wm->windows.first; win; win=win->next) { - sce= (win->screen)? win->screen->scene: NULL; - - if(sce) - break; + if(win->screen) { + if(!*sce) *sce= win->screen->scene; + *lay |= BKE_screen_visible_layers(win->screen); + } } } - else + else { /* if not, use the first sce */ - sce= bmain->scene.first; + *sce= bmain->scene.first; + if(*sce) *lay= (*sce)->lay; + + /* XXX for background mode, we should get the scen + from somewhere, for the -S option, but it's in + the context, how to get it here? */ + } +} + +void DAG_ids_flush_update(int time) +{ + Main *bmain= G.main; + Scene *sce; + unsigned int lay; + + dag_current_scene_layers(bmain, &sce, &lay); + + if(sce) + DAG_scene_flush_update(sce, lay, time); +} + +void DAG_id_flush_update(ID *id, short flag) +{ + Main *bmain= G.main; + Scene *sce; + Object *obt, *ob= NULL; + short idtype; + unsigned int lay; + + dag_current_scene_layers(bmain, &sce, &lay); if(!id || !sce || !sce->theDag) return; @@ -2213,10 +2242,7 @@ void DAG_id_flush_update(ID *id, short flag) } /* flush to other objects that depend on this one */ -// XXX if(G.curscreen) -// DAG_scene_flush_update(sce, dag_screen_view3d_layers(), 0); -// else - DAG_scene_flush_update(sce, sce->lay, 0); + DAG_scene_flush_update(sce, lay, 0); } /* recursively descends tree, each node only checked once */ @@ -2251,10 +2277,25 @@ static int parent_check_node(DagNode *node, int curtime) /* all nodes that influence this object get tagged, for calculating the exact position of this object at a given timeframe */ -void DAG_object_update_flags(Scene *sce, Object *ob, unsigned int lay) +void DAG_id_update_flags(ID *id) { + Main *bmain= G.main; + Scene *sce; DagNode *node; DagAdjList *itA; + Object *ob; + unsigned int lay; + + dag_current_scene_layers(bmain, &sce, &lay); + + if(!id || !sce || !sce->theDag) + return; + + /* objects only currently */ + if(GS(id->name) != ID_OB) + return; + + ob= (Object*)id; /* tag nodes unchecked */ for(node = sce->theDag->DagNode.first; node; node= node->next) diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index cc740d7fb3d..661d0da1550 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -33,8 +33,10 @@ #include "MEM_guardedalloc.h" +#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_view3d_types.h" #include "BLI_blenlib.h" @@ -321,4 +323,23 @@ void free_screen(bScreen *sc) BLI_freelistN(&sc->areabase); } +/* for depsgraph */ +unsigned int BKE_screen_visible_layers(bScreen *screen) +{ + ScrArea *sa; + unsigned int layer= 0; + + if(!screen) + return layer; + + /* get all used view3d layers */ + for(sa= screen->areabase.first; sa; sa= sa->next) + if(sa->spacetype==SPACE_VIEW3D) + layer |= ((View3D *)sa->spacedata.first)->lay; + + if(!layer) + return screen->scene->lay; + + return layer; +} diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index af2355b91a5..62341a5d6ae 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -43,6 +43,7 @@ #include "BKE_depsgraph.h" #include "BKE_main.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "BKE_utildefines.h" #include "RNA_access.h" @@ -57,26 +58,17 @@ /* ***************** depsgraph calls and anim updates ************* */ /* ***************** only these can be called from editors ******** */ -/* generic update flush, reads from context Screen (layers) and scene */ -/* this is for compliancy, later it can do all windows etc */ void ED_anim_dag_flush_update(const bContext *C) { - Scene *scene= CTX_data_scene(C); - bScreen *screen= CTX_wm_screen(C); - - DAG_scene_flush_update(scene, ED_screen_view3d_layers(screen), 0); + DAG_ids_flush_update(0); } /* flushes changes from object to all relations in scene */ void ED_anim_object_flush_update(const bContext *C, Object *ob) { - Scene *scene= CTX_data_scene(C); - bScreen *screen= CTX_wm_screen(C); - - DAG_object_update_flags(scene, ob, ED_screen_view3d_layers(screen)); + DAG_id_update_flags(&ob->id); } - /* **************************** pose <-> action syncing ******************************** */ /* Summary of what needs to be synced between poses and actions: * 1) Flags diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 16e78f7c8d1..4d65059c4c6 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -2716,7 +2716,6 @@ static void finishRetarget(RigGraph *rigg) static void adjustGraphs(bContext *C, RigGraph *rigg) { - Scene *scene = CTX_data_scene(C); bArmature *arm= rigg->ob->data; RigArc *arc; @@ -2739,7 +2738,6 @@ static void adjustGraphs(bContext *C, RigGraph *rigg) static void retargetGraphs(bContext *C, RigGraph *rigg) { - Scene *scene = CTX_data_scene(C); bArmature *arm= rigg->ob->data; ReebGraph *reebg = rigg->link_mesh; RigNode *inode; diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 0153b3c9bdb..697565184f3 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -104,7 +104,6 @@ void ED_screen_new_window(struct bContext *C, struct rcti *position, int type); /* anim */ void ED_update_for_newframe(const struct bContext *C, int mute); -unsigned int ED_screen_view3d_layers(struct bScreen *screen); void ED_operatortypes_screen(void); void ED_keymap_screen(struct wmWindowManager *wm); diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index 714ebcef0fb..710ac3d6553 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -88,7 +88,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_anim_api.h" #include "ED_previewrender.h" #include "ED_view3d.h" @@ -736,7 +735,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa) /* database can have created render-resol data... */ if(rstats->convertdone) - ED_anim_dag_flush_update(C); // <--- only current scene XXX + DAG_scene_flush_update(scene, scene->lay, 0); //printf("dbase update\n"); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index aa36675fb90..5d938ba36cc 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1580,23 +1580,6 @@ void ED_screen_animation_timer_update(bContext *C, int redraws) } } -unsigned int ED_screen_view3d_layers(bScreen *screen) -{ - if(screen) { - unsigned int layer= screen->scene->lay; /* as minimum this */ - ScrArea *sa; - - /* get all used view3d layers */ - for(sa= screen->areabase.first; sa; sa= sa->next) { - if(sa->spacetype==SPACE_VIEW3D) - layer |= ((View3D *)sa->spacedata.first)->lay; - } - return layer; - } - return 0; -} - - /* results in fully updated anim system */ void ED_update_for_newframe(const bContext *C, int mute) { @@ -1607,7 +1590,7 @@ void ED_update_for_newframe(const bContext *C, int mute) /* this function applies the changes too */ /* XXX future: do all windows */ - scene_update_for_newframe(scene, ED_screen_view3d_layers(screen)); /* BKE_scene.h */ + scene_update_for_newframe(scene, BKE_screen_visible_layers(screen)); /* BKE_scene.h */ //if ( (CFRA>1) && (!mute) && (scene->r.audio.flag & AUDIO_SCRUB)) // audiostream_scrub( CFRA ); -- cgit v1.2.3 From 6cee5201ec580f48b16efdd0a5620c52e86ce70e Mon Sep 17 00:00:00 2001 From: William Reynish Date: Mon, 14 Sep 2009 12:28:59 +0000 Subject: Third widget commit ;) Thanks to Broken for finding the bug. --- .../blender/editors/interface/interface_widgets.c | 65 +++++++++++++++++----- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 2385b5ad15c..90b2c920613 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -129,17 +129,21 @@ static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820}, {0.219306 , -0.238501}, {-0.393286 , -0.110949}, {-0.024699 , 0.013908}, {0.343805 , 0.147431}, {-0.272855 , 0.269918}, {0.095909 , 0.388710}}; -static float num_tria_vert[19][2]= { +static float num_tria_vert[3][2]= { +{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353}}; + +static int num_tria_face[1][3]= { +{0, 1, 2}}; + +static float scroll_circle_vert[16][2]= { {0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107}, {-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107}, {-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107}, -{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}, -{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.729843, -0.008353}}; +{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}}; -static int num_tria_face[19][3]= { -{13, 14, 18}, {17, 5, 6}, {12, 13, 18}, {17, 6, 7}, {15, 18, 14}, {16, 4, 5}, {16, 5, 17}, {18, 11, 12}, -{18, 17, 10}, {18, 10, 11}, {17, 9, 10}, {15, 0, 18}, {18, 0, 16}, {3, 4, 16}, {8, 9, 17}, {8, 17, 7}, -{2, 3, 16}, {1, 2, 16}, {16, 0, 1}}; +static int scroll_circle_face[14][3]= { +{0, 1, 2}, {2, 0, 3}, {3, 0, 15}, {3, 15, 4}, {4, 15, 14}, {4, 14, 5}, {5, 14, 13}, {5, 13, 6}, +{6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9}}; static float menu_tria_vert[6][2]= { {-0.41, 0.16}, {0.41, 0.16}, {0, 0.82}, @@ -451,15 +455,50 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha i2=0; i1= 1; } - for(a=0; a<19; a++) { + for(a=0; a<3; a++) { tria->vec[a][0]= sizex*num_tria_vert[a][i1] + centx; tria->vec[a][1]= sizey*num_tria_vert[a][i2] + centy; } - tria->tot= 19; + tria->tot= 1; tria->index= num_tria_face; } +static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where) +{ + float centx, centy, sizex, sizey, minsize; + int a, i1=0, i2=1; + + minsize= MIN2(rect->xmax-rect->xmin, rect->ymax-rect->ymin); + + /* center position and size */ + centx= (float)rect->xmin + 0.5f*minsize; + centy= (float)rect->ymin + 0.5f*minsize; + sizex= sizey= -0.5f*triasize*minsize; + + if(where=='r') { + centx= (float)rect->xmax - 0.5f*minsize; + sizex= -sizex; + } + else if(where=='t') { + centy= (float)rect->ymax - 0.5f*minsize; + sizey= -sizey; + i2=0; i1= 1; + } + else if(where=='b') { + sizex= -sizex; + i2=0; i1= 1; + } + + for(a=0; a<16; a++) { + tria->vec[a][0]= sizex*scroll_circle_vert[a][i1] + centx; + tria->vec[a][1]= sizey*scroll_circle_vert[a][i2] + centy; + } + + tria->tot= 14; + tria->index= scroll_circle_face; +} + static void widget_trias_draw(uiWidgetTrias *tria) { int a; @@ -1736,12 +1775,12 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat wcol->item[3]= 255; if(horizontal) { - widget_num_tria(&wtb.tria1, slider, 0.6f, 'l'); - widget_num_tria(&wtb.tria2, slider, 0.6f, 'r'); + widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'l'); + widget_scroll_circle(&wtb.tria2, slider, 0.6f, 'r'); } else { - widget_num_tria(&wtb.tria1, slider, 0.6f, 'b'); - widget_num_tria(&wtb.tria2, slider, 0.6f, 't'); + widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'b'); + widget_scroll_circle(&wtb.tria2, slider, 0.6f, 't'); } } widgetbase_draw(&wtb, wcol); -- cgit v1.2.3 From 4539bb9a98efb33044bb54fd9e906e280fdc26bd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 12:30:49 +0000 Subject: Link/Append, small changes: * Added separate menu items for Link and Append. * Change some OPERATOR_FINISHED to OPERATOR_CANCELLED. * Remove some IPO specific hacks, these are no longer ID blocks, so not necessary to take into account. * Some comment and code formatting tweaks. --- release/ui/space_info.py | 3 +- source/blender/blenkernel/intern/library.c | 14 +- source/blender/editors/space_file/filelist.c | 13 -- source/blender/windowmanager/intern/wm_operators.c | 146 +++++++++++---------- 4 files changed, 83 insertions(+), 93 deletions(-) diff --git a/release/ui/space_info.py b/release/ui/space_info.py index 6b2a457e89d..9fc35c46f29 100644 --- a/release/ui/space_info.py +++ b/release/ui/space_info.py @@ -61,7 +61,8 @@ class INFO_MT_file(bpy.types.Menu): layout.itemS() layout.operator_context = "INVOKE_AREA" - layout.itemO("wm.link_append", text="Append or Link") + layout.itemO("wm.link_append", text="Link") + layout.item_booleanO("wm.link_append", "link", False, text="Append") layout.itemS() layout.itemM("INFO_MT_file_import") diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index da7692d0cdb..45869a317e8 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -455,16 +455,14 @@ void flag_all_listbases_ids(short flag, short value) while(a--) flag_listbase_ids(lbarray[a], flag, value); } -void recalc_all_library_objects(struct Main *main) +void recalc_all_library_objects(Main *main) { - /* DISPLISTS? */ - Object *ob= main->object.first; - while(ob) { - if(ob->id.lib) { + Object *ob; + + /* flag for full recalc */ + for(ob=main->object.first; ob; ob=ob->id.next) + if(ob->id.lib) ob->recalc |= OB_RECALC; - } - ob= ob->id.next; - } } /* note: MAX_LIBARRAY define should match this code */ diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 23f24f26dc0..c0b16e639c0 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1184,11 +1184,6 @@ void filelist_from_main(struct FileList *filelist) id= lb->first; filelist->numfiles= 0; while(id) { - /* XXXXX TODO: the selection of the ipo blocktype might go somewhere else? - if(filelist->has_func && idcode==ID_IP) { - if(filelist->ipotype== ((Ipo *)id)->blocktype) filelist->numfiles++; - } - else */ if (!filelist->hide_dot || id->name[2] != '.') { filelist->numfiles++; } @@ -1214,14 +1209,6 @@ void filelist_from_main(struct FileList *filelist) totlib= totbl= 0; while(id) { -#if 0 - // XXXXX TODO: this is deprecated, checks for correct IPO block? - ok= 0; - if(filelist->has_func && idcode==ID_IP) { - if(filelist->ipotype== ((Ipo *)id)->blocktype) ok= 1; - } - else ok= 1; -#endif ok = 1; if(ok) { if (!filelist->hide_dot || id->name[2] != '.') { diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index c01ce5b6e35..ad490bb599a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -247,7 +247,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag) ot->idname= idname; ot->name= name; - ot->flag= OPTYPE_MACRO | flag; + ot->flag= OPTYPE_MACRO|flag; ot->exec= wm_macro_exec; ot->invoke= wm_macro_invoke; @@ -542,7 +542,7 @@ int WM_operator_winactive(bContext *C) } /* op->invoke */ -static void redo_cb(bContext *C, void *arg_op, void *arg2) +static void redo_cb(bContext *C, void *arg_op, int event) { wmOperator *lastop= arg_op; @@ -564,7 +564,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1); - uiBlockSetFunc(block, redo_cb, arg_op, NULL); + uiBlockSetHandleFunc(block, redo_cb, arg_op); if(!op->properties) { IDPropertyTemplate val = {0}; @@ -881,21 +881,9 @@ static void WM_OT_open_recentfile(wmOperatorType *ot) RNA_def_enum_funcs(prop, open_recentfile_itemf); } -/* ********* main file *********** */ +/* *************** open file **************** */ -static void untitled(char *name) -{ - if (G.save_over == 0 && strlen(name) < FILE_MAX-16) { - char *c= BLI_last_slash(name); - - if (c) - strcpy(&c[1], "untitled.blend"); - else - strcpy(name, "untitled.blend"); - } -} - -static void load_set_load_ui(wmOperator *op) +static void open_set_load_ui(wmOperator *op) { if(!RNA_property_is_set(op->ptr, "load_ui")) RNA_boolean_set(op->ptr, "load_ui", !(U.flag & USER_FILENOUI)); @@ -904,7 +892,7 @@ static void load_set_load_ui(wmOperator *op) static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { RNA_string_set(op->ptr, "path", G.sce); - load_set_load_ui(op); + open_set_load_ui(op); WM_event_add_fileselect(C, op); @@ -916,7 +904,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op) char path[FILE_MAX]; RNA_string_get(op->ptr, "path", path); - load_set_load_ui(op); + open_set_load_ui(op); if(RNA_boolean_get(op->ptr, "load_ui")) G.fileflags &= ~G_FILE_NO_UI; @@ -947,9 +935,11 @@ static void WM_OT_open_mainfile(wmOperatorType *ot) RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file."); } +/* **************** link/append *************** */ + static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if (RNA_property_is_set(op->ptr, "path")) { + if(RNA_property_is_set(op->ptr, "path")) { return WM_operator_call(C, op); } else { @@ -962,27 +952,24 @@ static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event) static short wm_link_append_flag(wmOperator *op) { - short flag = 0; - if (RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT; - if (RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY; - if (RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE; - if (RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK; - return flag; -} + short flag= 0; -#define GROUP_MAX 32 + if(RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT; + if(RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY; + if(RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE; + if(RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK; + return flag; +} -static void make_library_local(const char *libname, Main *main) +static void wm_link_make_library_local(Main *main, const char *libname) { - struct Library *lib; + Library *lib; /* and now find the latest append lib file */ - lib= main->library.first; - while(lib) { - if (BLI_streq(libname, lib->filename)) break; - lib= lib->id.next; - } + for(lib= main->library.first; lib; lib=lib->id.next) + if(BLI_streq(libname, lib->filename)) + break; /* make local */ if(lib) { @@ -995,49 +982,51 @@ static void make_library_local(const char *libname, Main *main) static int wm_link_append_exec(bContext *C, wmOperator *op) { - char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX]; - int idcode; + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Main *mainl= 0; BlendHandle *bh; - struct Main *mainvar= CTX_data_main(C); - struct Scene *scene= CTX_data_scene(C); - struct Main *mainl= 0; - PropertyRNA *prop; - int totfiles=0; + char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX]; + int idcode, totfiles=0; short flag; name[0] = '\0'; RNA_string_get(op->ptr, "filename", name); RNA_string_get(op->ptr, "directory", dir); - if ( BLO_is_a_library(dir, libname, group)==0 ) { + /* test if we have a valid data */ + if(BLO_is_a_library(dir, libname, group) == 0) { BKE_report(op->reports, RPT_ERROR, "Not a library"); - return OPERATOR_FINISHED; - } else if (group[0]==0) { + return OPERATOR_CANCELLED; + } + else if(group[0] == 0) { BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); - return OPERATOR_FINISHED; - } else if (BLI_streq(mainvar->name, libname)) { + return OPERATOR_CANCELLED; + } + else if(BLI_streq(bmain->name, libname)) { BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library"); - return OPERATOR_FINISHED; + return OPERATOR_CANCELLED; } /* check if something is indicated for append/link */ prop = RNA_struct_find_property(op->ptr, "files"); - if (prop) { + if(prop) { totfiles= RNA_property_collection_length(op->ptr, prop); - if (totfiles == 0) { - if (name[0] == '\0') { + if(totfiles == 0) { + if(name[0] == '\0') { BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); - return OPERATOR_FINISHED; + return OPERATOR_CANCELLED; } } - } else if (name[0] == '\0') { + } + else if(name[0] == '\0') { BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); - return OPERATOR_FINISHED; + return OPERATOR_CANCELLED; } /* now we have or selected, or an indicated file */ - if (RNA_boolean_get(op->ptr, "autoselect")) + if(RNA_boolean_get(op->ptr, "autoselect")) scene_deselect_all(scene); bh = BLO_blendhandle_from_file(libname); @@ -1045,16 +1034,16 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) flag = wm_link_append_flag(op); - if((flag & FILE_LINK)==0) { - /* tag everything, all untagged data can be made local */ + /* tag everything, all untagged data can be made local */ + if((flag & FILE_LINK)==0) flag_all_listbases_ids(LIB_APPEND_TAG, 1); - } /* here appending/linking starts */ mainl = BLO_library_append_begin(C, &bh, libname); - if (totfiles == 0) { + if(totfiles == 0) { BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag); - } else { + } + else { RNA_BEGIN(op->ptr, itemptr, "files") { RNA_string_get(&itemptr, "name", name); BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag); @@ -1063,17 +1052,16 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) } BLO_library_append_end(C, mainl, &bh, idcode, flag); - /* DISPLISTS? */ - recalc_all_library_objects(mainvar); + /* mark all library linked objects to be updated */ + recalc_all_library_objects(bmain); - /* Append, rather than linking */ - if ((flag & FILE_LINK)==0) { - make_library_local(libname, mainvar); - } + /* append, rather than linking */ + if((flag & FILE_LINK)==0) + wm_link_make_library_local(bmain, libname); - /* do we need to do this? */ - if(scene) - DAG_scene_sort(scene); + /* recreate dependency graph to include new objects */ + DAG_scene_sort(scene); + DAG_ids_flush_update(0); BLO_blendhandle_close(bh); BLI_strncpy(G.lib, dir, FILE_MAX); @@ -1103,6 +1091,8 @@ static void WM_OT_link_append(wmOperatorType *ot) RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); } +/* *************** recover last session **************** */ + static int wm_recover_last_session_exec(bContext *C, wmOperator *op) { char scestr[FILE_MAX], filename[FILE_MAX]; @@ -1137,6 +1127,20 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) ot->poll= WM_operator_winactive; } +/* *************** save file as **************** */ + +static void untitled(char *name) +{ + if(G.save_over == 0 && strlen(name) < FILE_MAX-16) { + char *c= BLI_last_slash(name); + + if(c) + strcpy(&c[1], "untitled.blend"); + else + strcpy(name, "untitled.blend"); + } +} + static void save_set_compress(wmOperator *op) { if(!RNA_property_is_set(op->ptr, "compress")) { @@ -1199,7 +1203,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file."); } -/* *************** Save file directly ******** */ +/* *************** save file directly ******** */ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { @@ -2113,7 +2117,7 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); + WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); -- cgit v1.2.3 From 733b20f695ab43fb979963b82683aceedf25b8c8 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Mon, 14 Sep 2009 13:31:58 +0000 Subject: *Changed texture blend property Flip XY to a proper enum. *Minor adjustments to lamp UI *Fixed issue #19319 (missing notifier) --- release/ui/buttons_data_lamp.py | 26 +++++++++++++------------- release/ui/buttons_texture.py | 5 ++++- source/blender/makesrna/intern/rna_lamp.c | 2 +- source/blender/makesrna/intern/rna_texture.c | 11 +++++++++-- source/blender/makesrna/intern/rna_world.c | 1 + 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/release/ui/buttons_data_lamp.py b/release/ui/buttons_data_lamp.py index 808a205b1b8..d5aaa5ad679 100644 --- a/release/ui/buttons_data_lamp.py +++ b/release/ui/buttons_data_lamp.py @@ -75,7 +75,7 @@ class DATA_PT_lamp(DataButtonsPanel): col.itemR(lamp, "diffuse") class DATA_PT_sunsky(DataButtonsPanel): - __label__ = "Sun/Sky" + __label__ = "Sky & Atmosphere" def poll(self, context): lamp = context.lamp @@ -86,9 +86,8 @@ class DATA_PT_sunsky(DataButtonsPanel): lamp = context.lamp.sky - row = layout.row() - row.itemR(lamp, "sky") - row.itemR(lamp, "atmosphere") + layout.itemR(lamp, "sky") + row = layout.row() row.active = lamp.sky or lamp.atmosphere @@ -98,38 +97,39 @@ class DATA_PT_sunsky(DataButtonsPanel): col = split.column() col.active = lamp.sky - col.itemL(text="Blend Mode:") - sub = col.column(align=True) + col.itemL(text="Blending:") + sub = col.column() sub.itemR(lamp, "sky_blend_type", text="") sub.itemR(lamp, "sky_blend", text="Factor") col.itemL(text="Color Space:") - sub = col.column(align=True) - sub.itemR(lamp, "sky_color_space", text="") + sub = col.column() + sub.row().itemR(lamp, "sky_color_space", expand=True) sub.itemR(lamp, "sky_exposure", text="Exposure") col = split.column() col.active = lamp.sky col.itemL(text="Horizon:") - sub = col.column(align=True) + sub = col.column() sub.itemR(lamp, "horizon_brightness", text="Brightness") sub.itemR(lamp, "spread", text="Spread") col.itemL(text="Sun:") - sub = col.column(align=True) + sub = col.column() sub.itemR(lamp, "sun_brightness", text="Brightness") sub.itemR(lamp, "sun_size", text="Size") sub.itemR(lamp, "backscattered_light", slider=True,text="Back Light") layout.itemS() + layout.itemR(lamp, "atmosphere") + split = layout.split() col = split.column() col.active = lamp.atmosphere - col.itemL(text="Sun:") - col.itemR(lamp, "sun_intensity", text="Intensity") - col.itemL(text="Scale Distance:") + col.itemL(text="Intensity:") + col.itemR(lamp, "sun_intensity", text="Sun") col.itemR(lamp, "atmosphere_distance_factor", text="Distance") col = split.column() diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index 90ce40b4832..3cea47a236e 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -381,7 +381,10 @@ class TEXTURE_PT_blend(TextureTypePanel): tex = context.texture layout.itemR(tex, "progression") - layout.itemR(tex, "flip_axis") + sub = layout.row() + + sub.active = (tex.progression in ('LINEAR', 'QUADRATIC', 'EASING', 'RADIAL')) + sub.itemR(tex, "flip_axis", expand=True) class TEXTURE_PT_stucci(TextureTypePanel): __label__ = "Stucci" diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 57aa1ba2736..dc59a75edbc 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -431,7 +431,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) prop= RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shdwr"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Shadow Color", "Color of shadows casted by the lamp."); + RNA_def_property_ui_text(prop, "Shadow Color", "Color of shadows cast by the lamp."); RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL); prop= RNA_def_property(srna, "only_shadow", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index f6835f3e7b5..ce65dc37e5b 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -835,6 +835,11 @@ static void rna_def_texture_blend(BlenderRNA *brna) {TEX_RAD, "RADIAL", 0, "Radial", "Creates a radial progression"}, {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_flip_axis_items[]= { + {0, "HORIZONTAL", 0, "Horizontal", "Flips the texture's X and Y axis"}, + {TEX_FLIPBLEND, "VERTICAL", 0, "Vertical", "Flips the texture's X and Y axis"}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "BlendTexture", "Texture"); RNA_def_struct_ui_text(srna, "Blend Texture", "Procedural color blending texture."); RNA_def_struct_sdna(srna, "Tex"); @@ -845,10 +850,12 @@ static void rna_def_texture_blend(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Progression", "Sets the style of the color blending"); RNA_def_property_update(prop, NC_TEXTURE, NULL); - prop= RNA_def_property(srna, "flip_axis", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_FLIPBLEND); + prop= RNA_def_property(srna, "flip_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_flip_axis_items); RNA_def_property_ui_text(prop, "Flip Axis", "Flips the texture's X and Y axis"); RNA_def_property_update(prop, NC_TEXTURE, NULL); + } static void rna_def_texture_stucci(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 0ed5016ccd2..d2eebbc61aa 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -431,6 +431,7 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "ambr"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Ambient Color", ""); + RNA_def_property_update(prop, NC_WORLD, NULL); /* exp, range */ prop= RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE); -- cgit v1.2.3 From c8af263e5d8d9d41a757e8438cdcf3b64d57e0c0 Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Mon, 14 Sep 2009 14:55:49 +0000 Subject: Reverted Mesh.verts from dynamic array since it breaks foreach_set used by import scripts. Did a few fixes in scripts to reflect recent RNA changes. --- release/io/export_obj.py | 6 +++--- release/io/export_x3d.py | 2 +- release/io/import_3ds.py | 3 ++- release/io/import_obj.py | 2 +- source/blender/makesrna/intern/rna_mesh.c | 3 +++ source/blender/python/intern/bpy_array.c | 2 +- source/blender/python/intern/bpy_rna.c | 8 +------- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index b2d4af7c517..d52ee8ec158 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -118,8 +118,8 @@ def write_mtl(scene, filename, copy_images): if mat: file.write('Ns %.6f\n' % ((mat.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_reflection for c in mat.diffuse_color]) ) # Diffuse - file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_reflection for c in mat.specular_color]) ) # Specular + file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_intensity for c in mat.diffuse_color]) ) # Diffuse + file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_intensity for c in mat.specular_color]) ) # Specular if hasattr(mat, "ior"): file.write('Ni %.6f\n' % mat.ior) # Refraction index else: @@ -129,7 +129,7 @@ def write_mtl(scene, filename, copy_images): # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. if mat.shadeless: file.write('illum 0\n') # ignore lighting - elif mat.specular_reflection == 0: + elif mat.specular_intensity == 0: file.write('illum 1\n') # no specular. else: file.write('illum 2\n') # light normaly diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py index 30a4b1483b0..3661d78a343 100644 --- a/release/io/export_x3d.py +++ b/release/io/export_x3d.py @@ -770,7 +770,7 @@ class x3d_class: for i in range(alltexture): tex = alltextures[i] - if tex.type != 'IMAGE': + if tex.type != 'IMAGE' or tex.image == None: continue namemat = tex.name diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py index 0269219b63d..f2dc99d5b7e 100644 --- a/release/io/import_3ds.py +++ b/release/io/import_3ds.py @@ -463,7 +463,8 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH): ''' if contextMatrix_rot: - ob.matrix = [x for row in contextMatrix_rot for x in row] + # ob.matrix = [x for row in contextMatrix_rot for x in row] + ob.matrix = contextMatrix_rot # ob.setMatrix(contextMatrix_rot) importedObjects.append(ob) diff --git a/release/io/import_obj.py b/release/io/import_obj.py index 484be6d54b4..34f6575dba2 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -715,7 +715,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l # face_mapping= me.faces.extend([f[0] for f in faces], indexList=True) if verts_tex and me.faces: - me.add_uv_layer() + me.add_uv_texture() # me.faceUV= 1 # TEXMODE= Mesh.FaceModes['TEX'] diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index e1744bb3d23..f1a46b199b4 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -981,10 +981,13 @@ static void rna_def_mface(BlenderRNA *brna) // XXX allows creating invalid meshes prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "v1"); RNA_def_property_array(prop, 4); + /* RNA_def_property_flag(prop, PROP_DYNAMIC); RNA_def_property_dynamic_array_funcs(prop, "rna_MeshFace_verts_get_length"); RNA_def_property_int_funcs(prop, "rna_MeshFace_verts_get", "rna_MeshFace_verts_set", NULL); + */ RNA_def_property_ui_text(prop, "Vertices", "Vertex indices"); prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED); diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index f11c95e7ed5..4459c7c313f 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -1,5 +1,5 @@ /** - * + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 8395e5c82e4..49105422325 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -545,9 +545,6 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v int len = RNA_property_array_length(ptr, prop); if (len > 0) { - /* char error_str[512]; */ - int ok= 1; - #ifdef USE_MATHUTILS if(MatrixObject_Check(value)) { MatrixObject *mat = (MatrixObject*)value; @@ -559,10 +556,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment expected a sequence instead of %.200s instance.", error_prefix, Py_TYPE(value)->tp_name); return -1; } - /* done getting the length */ - ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix); - - if (!ok) { + else if (!pyrna_py_to_array(ptr, prop, data, value, error_prefix)) { /* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */ return -1; } -- cgit v1.2.3 From a3ce413f44ba13b5e95e53d3dc11a92a16ac1dd5 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 14 Sep 2009 16:00:42 +0000 Subject: Bugfix with py operator api and modal operators. Modal operators would keep a reference to Reports locally allocated in the api functions, which would crash and burn later when the operator would actually stop. This commit introduces a flag at the Reports level that can be used to indicate that it needs to be freed (on top of the flag already existing in the operator, which I guess could be removed). Reports for operators called through python are only persisted if they indicate that they are running modal. --- source/blender/makesdna/DNA_windowmanager_types.h | 1 + source/blender/python/intern/bpy_operator.c | 15 ++++++++++----- source/blender/windowmanager/intern/wm.c | 2 +- source/blender/windowmanager/intern/wm_event_system.c | 5 +++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 10f83c8b9ec..c3bbb759aff 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -80,6 +80,7 @@ typedef enum ReportType { enum ReportListFlags { RPT_PRINT = 1, RPT_STORE = 2, + RPT_FREE = 4, }; typedef struct Report { struct Report *next, *prev; diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 062db42e0e9..0c1d974c978 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -79,16 +79,21 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) if (error_val==0) { - ReportList reports; + ReportList *reports; - BKE_reports_init(&reports, RPT_STORE); + reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); + BKE_reports_init(reports, RPT_STORE); - WM_operator_call_py(C, ot, context, &ptr, &reports); + WM_operator_call_py(C, ot, context, &ptr, reports); - if(BPy_reports_to_error(&reports)) + if(BPy_reports_to_error(reports)) error_val = -1; - BKE_reports_clear(&reports); + BKE_reports_clear(reports); + if ((reports->flag & RPT_FREE) == 0) + { + MEM_freeN(reports); + } } WM_operator_properties_free(&ptr); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 651394d51af..0a91c5078b7 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -69,7 +69,7 @@ void WM_operator_free(wmOperator *op) MEM_freeN(op->properties); } - if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) { + if(op->reports && ((op->flag & OPERATOR_REPORT_FREE) || (op->reports->flag & RPT_FREE))) { BKE_reports_clear(op->reports); MEM_freeN(op->reports); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 79441f33610..28814937ebe 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -555,6 +555,11 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA retval= wm_operator_call_internal(C, ot, context, properties, reports); + if (retval & OPERATOR_RUNNING_MODAL) + { + reports->flag |= RPT_FREE; + } + return retval; } -- cgit v1.2.3 From b3c49521787cd71918674b0fb5bbc88daeb199aa Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 14 Sep 2009 16:30:53 +0000 Subject: netrender: add "Animation on network" button to send job to master and gather the results in one step. --- release/io/netrender/operators.py | 34 ++++++++++++++++++++++++++++++++++ release/io/netrender/ui.py | 1 + 2 files changed, 35 insertions(+) diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index ccecef670d4..655afa6631f 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -6,6 +6,39 @@ from netrender.utils import * import netrender.client as client import netrender.model +@rnaOperator +class RENDER_OT_netclientanim(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "render.netclientanim" + __label__ = "Net Render Client Anim" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + scene = context.scene + + conn = clientConnection(scene) + + if conn: + # Sending file + scene.network_render.job_id = client.clientSendJob(conn, scene, True) + conn.close() + + bpy.ops.screen.render('INVOKE_AREA', animation=True) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + @rnaOperator class RENDER_OT_netclientsend(bpy.types.Operator): ''' @@ -30,6 +63,7 @@ class RENDER_OT_netclientsend(bpy.types.Operator): if conn: # Sending file scene.network_render.job_id = client.clientSendJob(conn, scene, True) + conn.close() return ('FINISHED',) diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 12ac10b551f..eee95bdac19 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -48,6 +48,7 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col = split.column() + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") col.itemR(scene.network_render, "mode") col.itemR(scene.network_render, "server_address") col.itemR(scene.network_render, "server_port") -- cgit v1.2.3 From cd211af417d1785ab0b526ae45c551286b5c89c6 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 16:43:13 +0000 Subject: Smoke: * Introduce a better check for fragment support --- source/blender/editors/space_view3d/drawobject.c | 4 ++-- source/blender/editors/space_view3d/drawvolume.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 2c4d72f64ab..40eb74e8062 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5360,7 +5360,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) { if(!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { -// #if0 +// #if 0 smd->domain->tex = NULL; GPU_create_smoke(smd, 0); draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->p0, smd->domain->p1, smd->domain->res, smd->domain->dx, smd->domain->tex_shadow); @@ -5395,7 +5395,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5; tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5; tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5; - color[0] = color[1] = color[2] = 1.0; // density[index]; + color[0] = color[1] = color[2] = density[index]; glColor3fv(color); bglVertex3fv(tmp); } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index cc4cb4771e7..3a79caed821 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -328,10 +328,10 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture // printf("i: %d\n", i); - if(GLEW_ARB_fragment_program) + if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) { - glGenProgramsARB(1, &prog); glEnable(GL_FRAGMENT_PROGRAM_ARB); + glGenProgramsARB(1, &prog); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text); @@ -342,7 +342,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); } else - printf("Your gfx card does not support 3dview smoke drawing."); + printf("Your gfx card does not support 3dview smoke drawing.\n"); GPU_texture_bind(tex, 0); if(tex_shadow) -- cgit v1.2.3 From 131c713fc163a8c404e10616438799f274b19a70 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 16:46:34 +0000 Subject: Smoke: * Fixing some gcc warnings --- source/blender/blenkernel/intern/pointcache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index f351f8a4335..7725efe3885 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -570,9 +570,9 @@ static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v) SmokeDomainSettings *sds = smd->domain; if(sds->wt) { - unsigned int res_big_array[3]; - unsigned int res_big; - unsigned int res = sds->res[0]*sds->res[1]*sds->res[2]; + int res_big_array[3]; + int res_big; + int res = sds->res[0]*sds->res[1]*sds->res[2]; float *dens, *densold, *tcu, *tcv, *tcw; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned int in_len_big; @@ -678,8 +678,8 @@ static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v) SmokeDomainSettings *sds = smd->domain; if(sds->fluid) { - unsigned int res = sds->res[0]*sds->res[1]*sds->res[2]; - unsigned int res_big, res_big_array[3]; + int res = sds->res[0]*sds->res[1]*sds->res[2]; + int res_big, res_big_array[3]; float *dens, *densold, *tcu, *tcv, *tcw; unsigned int out_len = sizeof(float)*(unsigned int)res; unsigned int out_len_big; -- cgit v1.2.3 From ba5df38d66cd70d64084456ac882df0cae19d880 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 14 Sep 2009 16:52:06 +0000 Subject: use static functions where possible for some local functions. --- source/blender/blenfont/intern/blf.c | 2 +- source/blender/blenfont/intern/blf_dir.c | 2 +- source/blender/blenfont/intern/blf_font.c | 2 +- source/blender/blenfont/intern/blf_glyph.c | 2 +- source/blender/blenkernel/intern/action.c | 6 ++-- source/blender/blenkernel/intern/anim_sys.c | 2 +- source/blender/blenkernel/intern/brush.c | 2 +- source/blender/blenkernel/intern/cloth.c | 10 +++--- source/blender/blenkernel/intern/collision.c | 16 ++++----- source/blender/blenkernel/intern/curve.c | 8 ++--- source/blender/blenkernel/intern/displist.c | 2 +- source/blender/blenkernel/intern/fcurve.c | 6 ++-- source/blender/blenkernel/intern/font.c | 2 +- source/blender/blenkernel/intern/implicit.c | 22 ++++++------ source/blender/blenkernel/intern/ipo.c | 2 +- source/blender/blenkernel/intern/modifier.c | 42 +++++++++++----------- source/blender/blenkernel/intern/multires.c | 4 +-- source/blender/blenkernel/intern/nla.c | 2 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/packedFile.c | 2 +- source/blender/blenkernel/intern/particle_system.c | 2 +- source/blender/blenkernel/intern/sequence.c | 20 +++++------ source/blender/blenkernel/intern/smoke.c | 10 +++--- source/blender/blenkernel/intern/writeffmpeg.c | 2 +- source/blender/blenlib/intern/BLI_kdopbvh.c | 4 +-- source/blender/blenlib/intern/BLI_kdtree.c | 2 +- source/blender/blenlib/intern/arithb.c | 16 ++++----- source/blender/blenlib/intern/freetypefont.c | 4 +-- source/blender/blenlib/intern/graph.c | 6 ++-- source/blender/blenlib/intern/noise.c | 12 +++---- source/blender/blenlib/intern/threads.c | 2 +- source/blender/makesrna/intern/rna_action.c | 4 +-- source/blender/makesrna/intern/rna_animation.c | 4 +-- source/blender/makesrna/intern/rna_armature.c | 2 +- source/blender/makesrna/intern/rna_brush.c | 2 +- source/blender/makesrna/intern/rna_constraint.c | 2 +- source/blender/makesrna/intern/rna_curve.c | 2 +- source/blender/makesrna/intern/rna_define.c | 6 ++-- source/blender/makesrna/intern/rna_fcurve.c | 10 +++--- source/blender/makesrna/intern/rna_gpencil.c | 12 +++---- source/blender/makesrna/intern/rna_group.c | 2 +- source/blender/makesrna/intern/rna_main_api.c | 4 +-- source/blender/makesrna/intern/rna_material.c | 8 ++--- source/blender/makesrna/intern/rna_meta.c | 4 +-- source/blender/makesrna/intern/rna_nla.c | 6 ++-- source/blender/makesrna/intern/rna_nodetree.c | 2 +- source/blender/makesrna/intern/rna_object_api.c | 2 +- source/blender/makesrna/intern/rna_pose.c | 10 +++--- source/blender/makesrna/intern/rna_scene.c | 6 ++-- source/blender/makesrna/intern/rna_sensor.c | 30 ++++++++-------- source/blender/makesrna/intern/rna_sequence.c | 2 +- source/blender/makesrna/intern/rna_space.c | 10 +++--- source/blender/makesrna/intern/rna_texture.c | 4 +-- source/blender/makesrna/intern/rna_wm.c | 2 +- source/blender/windowmanager/intern/wm_operators.c | 2 +- 55 files changed, 178 insertions(+), 178 deletions(-) diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 8cb237a19ac..db88d84d0b5 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -102,7 +102,7 @@ void BLF_exit(void) blf_font_exit(); } -int blf_search(char *name) +static int blf_search(char *name) { FontBLF *font; int i; diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c index b4d902ff428..aac6cd7d2fc 100644 --- a/source/blender/blenfont/intern/blf_dir.c +++ b/source/blender/blenfont/intern/blf_dir.c @@ -51,7 +51,7 @@ static ListBase global_font_dir= { NULL, NULL }; -DirBLF *blf_dir_find(const char *path) +static DirBLF *blf_dir_find(const char *path) { DirBLF *p; diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 2cd72809579..0a3dd259f6c 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -453,7 +453,7 @@ void blf_font_free(FontBLF *font) MEM_freeN(font); } -void blf_font_fill(FontBLF *font) +static void blf_font_fill(FontBLF *font) { font->aspect= 1.0f; font->pos[0]= 0.0f; diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index f3db3ddc9a5..7d1e43a38df 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -136,7 +136,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc) MEM_freeN(gc); } -void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) +static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) { int tot_mem, i; unsigned char *buf; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 47de044ea25..2bde61818bf 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -214,7 +214,7 @@ bAction *copy_action (bAction *src) /* Get the active action-group for an Action */ -bActionGroup *get_active_actiongroup (bAction *act) +static bActionGroup *get_active_actiongroup (bAction *act) { bActionGroup *agrp= NULL; @@ -1165,7 +1165,7 @@ typedef struct NlaIpoChannel { int type; } NlaIpoChannel; -void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime) +static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime) { bActionChannel *achan= get_action_channel(act, name); IpoCurve *icu; @@ -1258,7 +1258,7 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int } } -int execute_ipochannels(ListBase *lb) +static int execute_ipochannels(ListBase *lb) { NlaIpoChannel *nic; int count = 0; diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 2d6a97c48ae..643aa6bc779 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -438,7 +438,7 @@ void BKE_keyingsets_free (ListBase *list) * - path: original path string (as stored in F-Curve data) * - dst: destination string to write data to */ -short animsys_remap_path (AnimMapper *remap, char *path, char **dst) +static short animsys_remap_path (AnimMapper *remap, char *path, char **dst) { /* is there a valid remapping table to use? */ //if (remap) { diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index bce4e1120be..76a26762abe 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -711,7 +711,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i } } -void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos) +static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos) { Brush *brush= painter->brush; BrushPainterCache *cache= &painter->cache; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d25c329f49f..9ee6be903fa 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -95,7 +95,7 @@ static CM_SOLVER_DEF solvers [] = static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first); -int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); +static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ); @@ -155,7 +155,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->goalfrict = 0.0f; } -BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) +static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) { unsigned int i; BVHTree *bvhtree; @@ -196,7 +196,7 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) return bvhtree; } -BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) +static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) { unsigned int i; BVHTree *bvhtree; @@ -998,7 +998,7 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in return 0; } -void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist) +static void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist) { unsigned int i = 0; @@ -1031,7 +1031,7 @@ void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgeli BLI_edgehash_free ( cloth->edgehash, NULL ); } -int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) +static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { Cloth *cloth = clmd->clothObject; ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 37e9c93a108..8ef1c285370 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -313,7 +313,7 @@ gsl_poly_solve_quadratic (double a, double b, double c, * See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation" * page 4, left column */ -int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] ) +static int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] ) { int num_sols = 0; @@ -427,7 +427,7 @@ int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3 // w3 is not perfect -void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 ) +static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 ) { double tempV1[3], tempV2[3], tempV4[3]; double a,b,c,d,e,f; @@ -726,7 +726,7 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap return collpair; } -int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) +static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { int result = 0; Cloth *cloth1; @@ -891,7 +891,7 @@ static void findClosestPointsEE(float *x1, float *x2, float *x3, float *x4, floa } // calculates the distance of 2 edges -float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal) +static float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal) { float line1[3], line2[3], cross[3]; float length; @@ -1065,7 +1065,7 @@ float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3 return 0; } -int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) +static int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) { EdgeCollPair edgecollpair; Cloth *cloth1=NULL; @@ -1275,7 +1275,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat return result; } -int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) +static int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { Cloth *cloth1; cloth1 = clmd->clothObject; @@ -1392,7 +1392,7 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu return objs; } -void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap) +static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap) { int i; @@ -1405,7 +1405,7 @@ void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModi } } -int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index) +static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index) { Cloth *cloth = clmd->clothObject; int i=0, j = 0, numfaces = 0, numverts = 0; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index eec3cb73d8a..ea3fce9ffaf 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -68,7 +68,7 @@ /* globals */ /* local */ -int cu_isectLL(float *v1, float *v2, float *v3, float *v4, +static int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec); @@ -977,7 +977,7 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i } } -void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride) +static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride) { /* note that these are not purpendicular to the curve * they need to be rotated for this, @@ -1363,7 +1363,7 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp) } } -int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec) +static int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, float *labda, float *mu, float *vec) { /* return: -1: colliniar @@ -1882,7 +1882,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) } } -void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode) +static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode) { switch(twist_mode) { case CU_TWIST_TANGENT: diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index d87dbc833c5..266a528dc57 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1131,7 +1131,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) } -void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase) +static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase) { if(cu->flag & CU_3D) return; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 31f6e2c6067..54d2f85457f 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -916,7 +916,7 @@ void correct_bezpart (float *v1, float *v2, float *v3, float *v4) } /* find root ('zero') */ -int findzero (float x, float q0, float q1, float q2, float q3, float *o) +static int findzero (float x, float q0, float q1, float q2, float q3, float *o) { double c0, c1, c2, c3, a, b, c, p, q, d, t, phi; int nr= 0; @@ -1010,7 +1010,7 @@ int findzero (float x, float q0, float q1, float q2, float q3, float *o) } } -void berekeny (float f1, float f2, float f3, float f4, float *o, int b) +static void berekeny (float f1, float f2, float f3, float f4, float *o, int b) { float t, c0, c1, c2, c3; int a; @@ -1026,7 +1026,7 @@ void berekeny (float f1, float f2, float f3, float f4, float *o, int b) } } -void berekenx (float *f, float *o, int b) +static void berekenx (float *f, float *o, int b) { float t, c0, c1, c2, c3; int a; diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 411b2448dea..4e05bf45d3d 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -129,7 +129,7 @@ wcsleninu8(wchar_t *src) } int -utf8slen(char *src) +static utf8slen(char *src) { int size = 0, index = 0; unsigned char c; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 0bce71b57eb..956a5851827 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -43,7 +43,7 @@ #include static LARGE_INTEGER _itstart, _itend; static LARGE_INTEGER ifreq; -void itstart(void) +static void itstart(void) { static int first = 1; if(first) { @@ -52,7 +52,7 @@ void itstart(void) } QueryPerformanceCounter(&_itstart); } -void itend(void) +static void itend(void) { QueryPerformanceCounter(&_itend); } @@ -74,7 +74,7 @@ double itval() { gettimeofday(&_itstart, &itz); } -void itend(void) +static void itend(void) { gettimeofday(&_itend,&itz); } @@ -155,7 +155,7 @@ DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vec /* printf vector[3] on console: for debug output */ -void print_fvector(float m3[3]) +static void print_fvector(float m3[3]) { printf("%f\n%f\n%f\n\n",m3[0],m3[1],m3[2]); } @@ -297,7 +297,7 @@ DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], f // 3x3 matrix /////////////////////////// /* printf 3x3 matrix on console: for debug output */ -void print_fmatrix(float m3[3][3]) +static void print_fmatrix(float m3[3][3]) { printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]); printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]); @@ -496,7 +496,7 @@ DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float fro // SPARSE SYMMETRIC big matrix with 3x3 matrix entries /////////////////////////// /* printf a big matrix on console: for debug output */ -void print_bfmatrix(fmatrix3x3 *m3) +static void print_bfmatrix(fmatrix3x3 *m3) { unsigned int i = 0; @@ -887,7 +887,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) } } -int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) +static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) { // Solves for unknown X in equation AX=B unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100; @@ -970,7 +970,7 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv) } /* // version 1.3 -int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv) +static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv) { unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100; float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0; @@ -1038,7 +1038,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma } */ // version 1.4 -int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI) +static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI) { unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100; float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0; @@ -1391,7 +1391,7 @@ static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n) n[2]= n1[0]*n2[1]-n1[1]*n2[0]; } -float calculateVertexWindForce(float wind[3], float vertexnormal[3]) +static float calculateVertexWindForce(float wind[3], float vertexnormal[3]) { return (INPR(wind, vertexnormal)); } @@ -1595,7 +1595,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, // printf("\n"); } -void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *M, fmatrix3x3 *bigI) +static void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *M, fmatrix3x3 *bigI) { unsigned int numverts = dFdV[0].vcount; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 2f0e0931588..62f44d92d25 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -820,7 +820,7 @@ static char *particle_adrcodes_to_paths (int adrcode, int *array_index) * - array_index - index in property's array (if applicable) to use * - return - the allocated path... */ -char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index) +static char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index) { DynStr *path= BLI_dynstr_new(); char *propname=NULL, *rpath=NULL; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f06173264ee..4f2264a052f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -214,7 +214,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tcmd->name, cmd->name, 32); } -CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md) { CurveModifierData *cmd = (CurveModifierData *)md; CustomDataMask dataMask = 0; @@ -290,7 +290,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tlmd->name, lmd->name, 32); } -CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md) { LatticeModifierData *lmd = (LatticeModifierData *)md; CustomDataMask dataMask = 0; @@ -1104,7 +1104,7 @@ static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sc } } -float vertarray_size(MVert *mvert, int numVerts, int axis) +static float vertarray_size(MVert *mvert, int numVerts, int axis) { int i; float min_co, max_co; @@ -1771,7 +1771,7 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, S /* finds the best possible flipped name. For renaming; check for unique names afterwards */ /* if strip_number: removes number extensions */ -void vertgroup_flip_name (char *name, int strip_number) +static void vertgroup_flip_name (char *name, int strip_number) { int len; char prefix[128]={""}; /* The part before the facing */ @@ -3401,7 +3401,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32); } -CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md) { BevelModifierData *bmd = (BevelModifierData *)md; CustomDataMask dataMask = 0; @@ -3481,7 +3481,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32); } -CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; CustomDataMask dataMask = 0; @@ -3825,7 +3825,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target) tumd->aspecty = umd->aspecty; } -CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; @@ -4278,7 +4278,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tsmd->defgrp_name, smd->defgrp_name, 32); } -int smoothModifier_isDisabled(ModifierData *md) +static int smoothModifier_isDisabled(ModifierData *md) { SmoothModifierData *smd = (SmoothModifierData*) md; short flag; @@ -4291,7 +4291,7 @@ int smoothModifier_isDisabled(ModifierData *md) return 0; } -CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md) { SmoothModifierData *smd = (SmoothModifierData *)md; CustomDataMask dataMask = 0; @@ -4508,7 +4508,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32); } -int castModifier_isDisabled(ModifierData *md) +static int castModifier_isDisabled(ModifierData *md) { CastModifierData *cmd = (CastModifierData*) md; short flag; @@ -4520,7 +4520,7 @@ int castModifier_isDisabled(ModifierData *md) return 0; } -CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md) { CastModifierData *cmd = (CastModifierData *)md; CustomDataMask dataMask = 0; @@ -5151,7 +5151,7 @@ static void waveModifier_updateDepgraph( } } -CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md) { WaveModifierData *wmd = (WaveModifierData *)md; CustomDataMask dataMask = 0; @@ -5487,7 +5487,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tamd->defgrp_name, amd->defgrp_name, 32); } -CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; @@ -5602,7 +5602,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target) strncpy(thmd->subtarget, hmd->subtarget, 32); } -CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md) { HookModifierData *hmd = (HookModifierData *)md; CustomDataMask dataMask = 0; @@ -5947,7 +5947,7 @@ static void clothModifier_updateDepgraph( } } -CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; @@ -6371,7 +6371,7 @@ static DerivedMesh *booleanModifier_applyModifier( return derivedData; } -CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE); @@ -6419,7 +6419,7 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ tpsmd->psys = psmd->psys; } -CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md) { ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; CustomDataMask dataMask = 0; @@ -6832,7 +6832,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md) { return 1; } -CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md) { ExplodeModifierData *emd= (ExplodeModifierData*) md; CustomDataMask dataMask = 0; @@ -7746,7 +7746,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target) tmmd->object = mmd->object; } -CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md) { MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; CustomDataMask dataMask = 0; @@ -8126,7 +8126,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target) tsmd->subsurfLevels = smd->subsurfLevels; } -CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md) +static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; CustomDataMask dataMask = 0; @@ -9137,7 +9137,7 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek) return i; } -int modifiers_usesPointCache(Object *ob) +static int modifiers_usesPointCache(Object *ob) { ModifierData *md = ob->modifiers.first; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 37e7e55050a..e7159b82d49 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -596,7 +596,7 @@ static void find_displacer_edges(MultiresDisplacer *d, DerivedMesh *dm, Displace } /* Returns in out the corners [0-3] that use v1 and v2 */ -void find_face_corners(MFace *f, int v1, int v2, int out[2]) +static void find_face_corners(MFace *f, int v1, int v2, int out[2]) { int i, end = f->v4 ? 4 : 3; @@ -1259,7 +1259,7 @@ struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, i ***************************/ /* Does not actually free lvl itself */ -void multires_free_level(MultiresLevel *lvl) +static void multires_free_level(MultiresLevel *lvl) { if(lvl) { if(lvl->faces) MEM_freeN(lvl->faces); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 480c79fbc1a..83ee71bfe40 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -1048,7 +1048,7 @@ short BKE_nlastrip_within_bounds (NlaStrip *strip, float min, float max) /* Is the given NLA-strip the first one to occur for the given AnimData block */ // TODO: make this an api method if necesary, but need to add prefix first -short nlastrip_is_first (AnimData *adt, NlaStrip *strip) +static short nlastrip_is_first (AnimData *adt, NlaStrip *strip) { NlaTrack *nlt; NlaStrip *ns; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8fe7beeb247..ed4e82cb3c6 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1406,7 +1406,7 @@ int object_data_is_libdata(Object *ob) /* *************** PROXY **************** */ /* when you make proxy, ensure the exposed layers are extern */ -void armature_set_id_extern(Object *ob) +static void armature_set_id_extern(Object *ob) { bArmature *arm= ob->data; bPoseChannel *pchan; diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index bd0b1a5e36e..0de97b9c703 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -236,7 +236,7 @@ void packAll(Main *bmain, ReportList *reports) // attempt to create a function that generates an unique filename // this will work when all funtions in fileops.c understand relative filenames... -char *find_new_name(char *name) +static char *find_new_name(char *name) { char tempname[FILE_MAXDIR + FILE_MAXFILE]; char *newname; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index fb12cfe3147..72b580a4543 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2252,7 +2252,7 @@ void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys) BKE_ptcache_disk_to_mem(&pid); } -void psys_clear_temp_pointcache(ParticleSystem *psys) +static void psys_clear_temp_pointcache(ParticleSystem *psys) { if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0) return; diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c index c6b714c3125..7f3e2789232 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequence.c @@ -127,7 +127,7 @@ void new_tstripdata(Sequence *seq) /* free */ -void free_proxy_seq(Sequence *seq) +static void free_proxy_seq(Sequence *seq) { if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) { IMB_free_anim(seq->strip->proxy->anim); @@ -682,7 +682,7 @@ void clear_scene_in_allseqs(Scene *sce) } } -char *give_seqname_by_type(int type) +static char *give_seqname_by_type(int type) { switch(type) { case SEQ_META: return "Meta"; @@ -949,7 +949,7 @@ static TStripElem* alloc_tstripdata(int len, const char * name) return se; } -TStripElem *give_tstripelem(Sequence *seq, int cfra) +static TStripElem *give_tstripelem(Sequence *seq, int cfra) { TStripElem *se; int nr; @@ -1297,7 +1297,7 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re se->ibuf = 0; } -void seq_proxy_rebuild(Scene *scene, Sequence * seq) +static void seq_proxy_rebuild(Scene *scene, Sequence * seq) { int cfra; float rsize = seq->strip->proxy->size; @@ -2623,7 +2623,7 @@ ImBuf *give_ibuf_seq(Scene *scene, int rectx, int recty, int cfra, int chanshown } /* check used when we need to change seq->blend_mode but not to effect or audio strips */ -int seq_can_blend(Sequence *seq) +static int seq_can_blend(Sequence *seq) { if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) { return 1; @@ -2749,7 +2749,7 @@ static void *seq_prefetch_thread(void * This_) return 0; } -void seq_start_threads(Scene *scene) +static void seq_start_threads(Scene *scene) { int i; @@ -2782,7 +2782,7 @@ void seq_start_threads(Scene *scene) BLI_init_threads(0, 0, 0); } -void seq_stop_threads() +static void seq_stop_threads() { PrefetchThread *tslot; PrefetchQueueElem *e; @@ -2850,7 +2850,7 @@ void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown, pthread_mutex_unlock(&wakeup_lock); } -void seq_wait_for_prefetch_ready() +static void seq_wait_for_prefetch_ready() { PrefetchThread *tslot; @@ -2984,7 +2984,7 @@ static void free_anim_seq(Sequence *seq) } } -void free_imbuf_seq_except(Scene *scene, int cfra) +static void free_imbuf_seq_except(Scene *scene, int cfra) { Editing *ed= seq_give_editing(scene, FALSE); Sequence *seq; @@ -3178,7 +3178,7 @@ void free_imbuf_seq() } #endif -void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) +static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) { /* force update of all sequences with this ipo, on ipo changes */ Editing *ed= seq_give_editing(scene, FALSE); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 6485e367b78..66aaa97af55 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -526,7 +526,7 @@ void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *faces, int } } -void smokeModifier_freeDomain(SmokeModifierData *smd) +static void smokeModifier_freeDomain(SmokeModifierData *smd) { if(smd->domain) { @@ -550,7 +550,7 @@ void smokeModifier_freeDomain(SmokeModifierData *smd) } } -void smokeModifier_freeFlow(SmokeModifierData *smd) +static void smokeModifier_freeFlow(SmokeModifierData *smd) { if(smd->flow) { @@ -567,7 +567,7 @@ void smokeModifier_freeFlow(SmokeModifierData *smd) } } -void smokeModifier_freeCollision(SmokeModifierData *smd) +static void smokeModifier_freeCollision(SmokeModifierData *smd) { if(smd->coll) { @@ -741,7 +741,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd) } // forward decleration -void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); +static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); static int get_lamp(Scene *scene, float *light) { @@ -1337,7 +1337,7 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int } } -void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) +static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) { int x, y, z; float bv[6]; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index e7164dc4794..9e86dcbe491 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -613,7 +613,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex } /* essential functions -- start, append, end */ -void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) +static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) { /* Handle to the output file */ AVFormatContext* of; diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 61d9cce1a58..48bbfc12370 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -329,7 +329,7 @@ static void sort(BVHNode **a0, int begin, int end, int axis) bvh_insertionsort(a, begin, end, axis); } } -void sort_along_axis(BVHTree *tree, int start, int end, int axis) +static void sort_along_axis(BVHTree *tree, int start, int end, int axis) { sort(tree->nodes, start, end, axis); } @@ -337,7 +337,7 @@ void sort_along_axis(BVHTree *tree, int start, int end, int axis) //after a call to this function you can expect one of: // every node to left of a[n] are smaller or equal to it // every node to the right of a[n] are greater or equal to it -int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ +static int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ int begin = _begin, end = _end, cut; while(end-begin > 3) { diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 1f3a861ba6a..ccf79ed42dc 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -337,7 +337,7 @@ int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTree return found; } -int range_compare(const void * a, const void * b) +static int range_compare(const void * a, const void * b) { const KDTreeNearest *kda = a; const KDTreeNearest *kdb = b; diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 9e769e19674..339a7250295 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -4093,19 +4093,19 @@ void spheremap(float x, float y, float z, float *u, float *v) /* proposed api by ton and zr, not used yet */ #if 0 /* ***************** m1 = m2 ***************** */ -void cpy_m3_m3(float m1[][3], float m2[][3]) +static void cpy_m3_m3(float m1[][3], float m2[][3]) { memcpy(m1[0], m2[0], 9*sizeof(float)); } /* ***************** m1 = m2 ***************** */ -void cpy_m4_m4(float m1[][4], float m2[][4]) +static void cpy_m4_m4(float m1[][4], float m2[][4]) { memcpy(m1[0], m2[0], 16*sizeof(float)); } /* ***************** identity matrix ***************** */ -void ident_m4(float m[][4]) +static void ident_m4(float m[][4]) { m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0; @@ -4116,7 +4116,7 @@ void ident_m4(float m[][4]) } /* ***************** m1 = m2 (pre) * m3 (post) ***************** */ -void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +static void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) { float m[3][3]; @@ -4136,7 +4136,7 @@ void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) } /* ***************** m1 = m2 (pre) * m3 (post) ***************** */ -void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +static void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) { float m[4][4]; @@ -4164,7 +4164,7 @@ void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) } /* ***************** m1 = inverse(m2) ***************** */ -void inv_m3_m3(float m1[][3], float m2[][3]) +static void inv_m3_m3(float m1[][3], float m2[][3]) { short a,b; float det; @@ -4187,7 +4187,7 @@ void inv_m3_m3(float m1[][3], float m2[][3]) } /* ***************** m1 = inverse(m2) ***************** */ -int inv_m4_m4(float inverse[][4], float mat[][4]) +static int inv_m4_m4(float inverse[][4], float mat[][4]) { int i, j, k; double temp; @@ -4240,7 +4240,7 @@ int inv_m4_m4(float inverse[][4], float mat[][4]) } /* ***************** v1 = v2 * mat ***************** */ -void mul_v3_v3m4(float *v1, float *v2, float mat[][4]) +static void mul_v3_v3m4(float *v1, float *v2, float mat[][4]) { float x, y; diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 985700efda1..cb5632df569 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -65,7 +65,7 @@ static FT_Library library; static FT_Error err; -void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) +static void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) { // Blender struct Nurb *nu; @@ -275,7 +275,7 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) } } -int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) +static int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) { // Freetype2 FT_Face face; diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index cc15c499290..49a3cad53f1 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -354,7 +354,7 @@ void BLI_ReflagSubgraph(BGraph *graph, int old_subgraph, int new_subgraph) /*************************************** CYCLE DETECTION ***********************************************/ -int detectCycle(BNode *node, BArc *src_arc) +static int detectCycle(BNode *node, BArc *src_arc) { int value = 0; @@ -520,7 +520,7 @@ void BLI_calcGraphLength(BGraph *graph) /********************************* SYMMETRY DETECTION **************************************************/ -void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit); +static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit); void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3]) { @@ -935,7 +935,7 @@ static void markdownSecondarySymmetry(BGraph *graph, BNode *node, int depth, int } } -void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit) +static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit) { int i; diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 0bd30a69d05..66e9a65dba5 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -42,9 +42,9 @@ #endif /* local */ -float noise3_perlin(float vec[3]); -float turbulence_perlin(float *point, float lofreq, float hifreq); -float turbulencep(float noisesize, float x, float y, float z, int nr); +static float noise3_perlin(float vec[3]); +static float turbulence_perlin(float *point, float lofreq, float hifreq); +static float turbulencep(float noisesize, float x, float y, float z, int nr); #define HASHVEC(x,y,z) hashvectf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255] @@ -915,7 +915,7 @@ float g[512+2][3]= { r1 = r0 - 1.; -float noise3_perlin(float vec[3]) +static float noise3_perlin(float vec[3]) { int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v; @@ -976,7 +976,7 @@ float noise3_perlin(float vec[3]) return 1.5 * lerp(sz, c, d); /* interpolate in z */ } -float turbulence_perlin(float *point, float lofreq, float hifreq) +static float turbulence_perlin(float *point, float lofreq, float hifreq) { float freq, t, p[3]; @@ -1029,7 +1029,7 @@ float BLI_hnoisep(float noisesize, float x, float y, float z) return noise3_perlin(vec); } -float turbulencep(float noisesize, float x, float y, float z, int nr) +static float turbulencep(float noisesize, float x, float y, float z, int nr) { float vec[3]; diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index ed3e07b7f7e..ce9f9adeb90 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -316,7 +316,7 @@ typedef struct WorkParam { int index; } WorkParam; -void *exec_work_fnct(void *v_param) +static void *exec_work_fnct(void *v_param) { WorkParam *p = (WorkParam*)v_param; void *value; diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index e376d3125e3..99090b62938 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -38,7 +38,7 @@ #else -void rna_def_action_group(BlenderRNA *brna) +static void rna_def_action_group(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -76,7 +76,7 @@ void rna_def_action_group(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Custom Color", "Index of custom color set."); } -void rna_def_action(BlenderRNA *brna) +static void rna_def_action(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index e4bea893992..a8d3a6edaae 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -93,7 +93,7 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value) #else -void rna_def_keyingset_path(BlenderRNA *brna) +static void rna_def_keyingset_path(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -132,7 +132,7 @@ void rna_def_keyingset_path(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Entire Array", "When an 'array/vector' type is chosen (Location, Rotation, Color, etc.), entire array is to be used."); } -void rna_def_keyingset(BlenderRNA *brna) +static void rna_def_keyingset(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 57eb3c1de4a..dcf89b7ac1e 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -520,7 +520,7 @@ static void rna_def_edit_bone(BlenderRNA *brna) RNA_define_verify_sdna(1); } -void rna_def_armature(BlenderRNA *brna) +static void rna_def_armature(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 612863e1ab9..70daa3690da 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -89,7 +89,7 @@ static void rna_Brush_active_texture_set(PointerRNA *ptr, PointerRNA value) #else -void rna_def_brush(BlenderRNA *brna) +static void rna_def_brush(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 815023ee315..04d56eb666e 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -89,7 +89,7 @@ EnumPropertyItem space_object_items[] = { #include "ED_object.h" -StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr) +static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr) { bConstraint *con= (bConstraint*)ptr->data; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 121812c189c..4a5af56d64a 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -66,7 +66,7 @@ EnumPropertyItem beztriple_keyframe_type_items[] = { #include "WM_api.h" -StructRNA *rna_Curve_refine(PointerRNA *ptr) +static StructRNA *rna_Curve_refine(PointerRNA *ptr) { Curve *cu= (Curve*)ptr->data; short obtype= curve_type(cu); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 6bca237e02f..0b54d4a8e14 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -66,7 +66,7 @@ void rna_addtail(ListBase *listbase, void *vlink) listbase->last = link; } -void rna_remlink(ListBase *listbase, void *vlink) +static void rna_remlink(ListBase *listbase, void *vlink) { Link *link= vlink; @@ -155,7 +155,7 @@ PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop) return NULL; } -PropertyDefRNA *rna_find_property_def(PropertyRNA *prop) +static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop) { PropertyDefRNA *dprop; @@ -239,7 +239,7 @@ PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm) return NULL; } -ContainerDefRNA *rna_find_container_def(ContainerRNA *cont) +static ContainerDefRNA *rna_find_container_def(ContainerRNA *cont) { StructDefRNA *ds; FunctionDefRNA *dfunc; diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index bafe83f1812..2802665c639 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -52,7 +52,7 @@ EnumPropertyItem fmodifier_type_items[] = { /* --------- */ -StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) +static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) { FModifier *fcm= (FModifier *)ptr->data; @@ -460,7 +460,7 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna) /* --------- */ -void rna_def_fmodifier(BlenderRNA *brna) +static void rna_def_fmodifier(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -510,7 +510,7 @@ void rna_def_fmodifier(BlenderRNA *brna) /* *********************** */ -void rna_def_drivertarget(BlenderRNA *brna) +static void rna_def_drivertarget(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -536,7 +536,7 @@ void rna_def_drivertarget(BlenderRNA *brna) RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property used (if applicable)"); } -void rna_def_channeldriver(BlenderRNA *brna) +static void rna_def_channeldriver(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -590,7 +590,7 @@ static void rna_def_fpoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Point", "Point coordinates"); } -void rna_def_fcurve(BlenderRNA *brna) +static void rna_def_fcurve(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 15f5ef7884f..2a4ff112c3c 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -48,7 +48,7 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr) return 1; } -void rna_GPencilLayer_active_set(PointerRNA *ptr, int value) +static void rna_GPencilLayer_active_set(PointerRNA *ptr, int value) { bGPdata *gpd= ptr->id.data; bGPDlayer *gpl= ptr->data; @@ -68,7 +68,7 @@ void rna_GPencilLayer_active_set(PointerRNA *ptr, int value) #else -void rna_def_gpencil_stroke_point(BlenderRNA *brna) +static void rna_def_gpencil_stroke_point(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -88,7 +88,7 @@ void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it."); } -void rna_def_gpencil_stroke(BlenderRNA *brna) +static void rna_def_gpencil_stroke(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -107,7 +107,7 @@ void rna_def_gpencil_stroke(BlenderRNA *brna) // TODO... } -void rna_def_gpencil_frame(BlenderRNA *brna) +static void rna_def_gpencil_frame(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -138,7 +138,7 @@ void rna_def_gpencil_frame(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Selected", "Frame is selected for editing in the DopeSheet."); } -void rna_def_gpencil_layer(BlenderRNA *brna) +static void rna_def_gpencil_layer(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -215,7 +215,7 @@ void rna_def_gpencil_layer(BlenderRNA *brna) } -void rna_def_gpencil_data(BlenderRNA *brna) +static void rna_def_gpencil_data(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index 31bc6ccc74b..dddc2062f07 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -33,7 +33,7 @@ #ifdef RNA_RUNTIME -PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter) +static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter) { ListBaseIterator *internal= iter->internal; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 6d56b2b00f9..d0a3789b9d8 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -40,14 +40,14 @@ #include "DNA_mesh_types.h" -Mesh *rna_Main_add_mesh(Main *main, char *name) +static Mesh *rna_Main_add_mesh(Main *main, char *name) { Mesh *me= add_mesh(name); me->id.us--; return me; } -void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) +static void rna_Main_remove_mesh(Main *main, ReportList *reports, Mesh *me) { if(me->id.us == 0) free_libblock(&main->mesh, me); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index cd1159bc138..e23333713c4 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -212,7 +212,7 @@ static void rna_Material_use_specular_ramp_set(PointerRNA *ptr, int value) ma->ramp_spec= add_colorband(0); } -void rna_Material_use_nodes_set(PointerRNA *ptr, int value) +static void rna_Material_use_nodes_set(PointerRNA *ptr, int value) { Material *ma= (Material*)ptr->data; @@ -1267,7 +1267,7 @@ static void rna_def_material_sss(BlenderRNA *brna) RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); } -void rna_def_material_specularity(StructRNA *srna) +static void rna_def_material_specularity(StructRNA *srna) { PropertyRNA *prop; @@ -1327,7 +1327,7 @@ void rna_def_material_specularity(StructRNA *srna) RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); } -void rna_def_material_strand(BlenderRNA *brna) +static void rna_def_material_strand(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -1394,7 +1394,7 @@ void rna_def_material_strand(BlenderRNA *brna) RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); } -void rna_def_material_physics(BlenderRNA *brna) +static void rna_def_material_physics(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index f3160a7bb18..1a4e4da886b 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -67,7 +67,7 @@ static void rna_MetaBall_update_data(bContext *C, PointerRNA *ptr) #else -void rna_def_metaelement(BlenderRNA *brna) +static void rna_def_metaelement(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -143,7 +143,7 @@ void rna_def_metaelement(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_MetaBall_update_data"); } -void rna_def_metaball(BlenderRNA *brna) +static void rna_def_metaball(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 690a198f12c..20d1a898303 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -47,7 +47,7 @@ /* temp constant defined for these funcs only... */ #define NLASTRIP_MIN_LEN_THRESH 0.1f -void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value) +static void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value) { NlaStrip *data= (NlaStrip *)ptr->data; @@ -280,7 +280,7 @@ EnumPropertyItem nla_mode_extend_items[] = { {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."}, {0, NULL, 0, NULL, NULL}}; -void rna_def_nlastrip(BlenderRNA *brna) +static void rna_def_nlastrip(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -433,7 +433,7 @@ void rna_def_nlastrip(BlenderRNA *brna) // - sync length } -void rna_def_nlatrack(BlenderRNA *brna) +static void rna_def_nlatrack(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 3fd358a1c16..99f61c7a724 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -39,7 +39,7 @@ #ifdef RNA_RUNTIME -StructRNA *rna_Node_refine(struct PointerRNA *ptr) +static StructRNA *rna_Node_refine(struct PointerRNA *ptr) { bNode *node = (bNode*)ptr->data; diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 3541bc2b1b0..6545898c1ab 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -43,7 +43,7 @@ #include "DNA_scene_types.h" /* copied from init_render_mesh (render code) */ -Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene) +static Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene) { CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; DerivedMesh *dm; diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 3a03e7a624d..b568fb38dfb 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -98,7 +98,7 @@ static void rna_BoneGroup_color_set_set(PointerRNA *ptr, int value) } } -IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create) +static IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create) { bPoseChannel *pchan= ptr->data; @@ -323,7 +323,7 @@ static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, in *max= MAX2(0, *max); } -void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index) +static void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index) { bPose *pose= (bPose*)ptr->data; bActionGroup *grp; @@ -334,7 +334,7 @@ void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index) else BLI_strncpy(value, "", sizeof(grp->name)); // XXX if invalid pointer, won't this crash? } -int rna_pose_bgroup_name_index_length(PointerRNA *ptr, int index) +static int rna_pose_bgroup_name_index_length(PointerRNA *ptr, int index) { bPose *pose= (bPose*)ptr->data; bActionGroup *grp; @@ -343,7 +343,7 @@ int rna_pose_bgroup_name_index_length(PointerRNA *ptr, int index) return (grp)? strlen(grp->name): 0; } -void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, short *index) +static void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, short *index) { bPose *pose= (bPose*)ptr->data; bActionGroup *grp; @@ -359,7 +359,7 @@ void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, short *i *index= 0; } -void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen) +static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen) { bPose *pose= (bPose*)ptr->data; bActionGroup *grp; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 965796c6d5b..15329b126d3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -70,7 +70,7 @@ EnumPropertyItem prop_mode_items[] ={ #include "RE_pipeline.h" -PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter) +static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter) { ListBaseIterator *internal= iter->internal; @@ -371,7 +371,7 @@ static void rna_SceneRenderLayer_pass_update(bContext *C, PointerRNA *ptr) ntreeCompositForceHidden(scene->nodetree, scene); } -void rna_Scene_use_nodes_set(PointerRNA *ptr, int value) +static void rna_Scene_use_nodes_set(PointerRNA *ptr, int value) { Scene *scene= (Scene*)ptr->data; @@ -784,7 +784,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) else RNA_def_property_clear_flag(prop, PROP_EDITABLE); } -void rna_def_scene_game_data(BlenderRNA *brna) +static void rna_def_scene_game_data(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c index 53bd230870f..a5d76fdb039 100644 --- a/source/blender/makesrna/intern/rna_sensor.c +++ b/source/blender/makesrna/intern/rna_sensor.c @@ -73,7 +73,7 @@ static StructRNA* rna_Sensor_refine(struct PointerRNA *ptr) #else -void rna_def_sensor(BlenderRNA *brna) +static void rna_def_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -129,14 +129,14 @@ void rna_def_sensor(BlenderRNA *brna) RNA_def_property_range(prop, 0, 10000); } -void rna_def_always_sensor(BlenderRNA *brna) +static void rna_def_always_sensor(BlenderRNA *brna) { StructRNA *srna; srna= RNA_def_struct(brna, "AlwaysSensor", "Sensor"); RNA_def_struct_ui_text(srna, "Always Sensor", "Sensor to generate continuous pulses."); } -void rna_def_near_sensor(BlenderRNA *brna) +static void rna_def_near_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -160,7 +160,7 @@ void rna_def_near_sensor(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 10000.0f); } -void rna_def_mouse_sensor(BlenderRNA *brna) +static void rna_def_mouse_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -186,7 +186,7 @@ void rna_def_mouse_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Mouse Event", "Specify the type of event this mouse sensor should trigger on."); } -void rna_def_touch_sensor(BlenderRNA *brna) +static void rna_def_touch_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -201,7 +201,7 @@ void rna_def_touch_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Material", "Only look for floors with this material."); } -void rna_def_keyboard_sensor(BlenderRNA *brna) +static void rna_def_keyboard_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -240,7 +240,7 @@ void rna_def_keyboard_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "All Keys", "Trigger this sensor on any keystroke."); } -void rna_def_property_sensor(BlenderRNA *brna) +static void rna_def_property_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -278,7 +278,7 @@ void rna_def_property_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Maximum Value", "Specify maximum value in Interval type."); } -void rna_def_actuator_sensor(BlenderRNA *brna) +static void rna_def_actuator_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -292,7 +292,7 @@ void rna_def_actuator_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Actuator", "Actuator name, actuator active state modifications will be detected."); } -void rna_def_delay_sensor(BlenderRNA *brna) +static void rna_def_delay_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -314,7 +314,7 @@ void rna_def_delay_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Repeat", "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics."); } -void rna_def_collision_sensor(BlenderRNA *brna) +static void rna_def_collision_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -341,7 +341,7 @@ void rna_def_collision_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Collision Type", "Toggle collision on material or property."); } -void rna_def_radar_sensor(BlenderRNA *brna) +static void rna_def_radar_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -376,7 +376,7 @@ void rna_def_radar_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Distance", "Depth of the radar cone."); } -void rna_def_random_sensor(BlenderRNA *brna) +static void rna_def_random_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -390,7 +390,7 @@ void rna_def_random_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Seed", "Initial seed of the generator. (Choose 0 for not random)."); } -void rna_def_ray_sensor(BlenderRNA *brna) +static void rna_def_ray_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -438,7 +438,7 @@ void rna_def_ray_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Axis", "Specify along which axis the ray is cast."); } -void rna_def_message_sensor(BlenderRNA *brna) +static void rna_def_message_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; @@ -451,7 +451,7 @@ void rna_def_message_sensor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Subject", "Optional subject filter: only accept messages with this subject, or empty for all."); } -void rna_def_joystick_sensor(BlenderRNA *brna) +static void rna_def_joystick_sensor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index 9f016f73694..4e12aab853e 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -514,7 +514,7 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_function_return(func, RNA_def_pointer(func, "elem", "SequenceElement", "", "strip element of the current frame")); } -void rna_def_editor(BlenderRNA *brna) +static void rna_def_editor(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 542f6e2aeda..bb01ab9a9c7 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -211,7 +211,7 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, P /* Space Text Editor */ -void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value) +static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value) { SpaceText *st= (SpaceText*)(ptr->data); @@ -219,7 +219,7 @@ void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value) st->left= 0; } -void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value) +static void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value) { SpaceText *st= (SpaceText*)(ptr->data); @@ -227,7 +227,7 @@ void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value) st->top= 0; } -void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value) +static void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value) { SpaceFile *sfile= (SpaceFile*)(ptr->data); @@ -236,7 +236,7 @@ void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value) /* Space Properties */ -StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr) +static StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr) { SpaceButs *sbuts= (SpaceButs*)(ptr->data); @@ -246,7 +246,7 @@ StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr) return &RNA_ID; } -void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) +static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) { SpaceButs *sbuts= (SpaceButs*)(ptr->data); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index ce65dc37e5b..7a81138a3be 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -55,7 +55,7 @@ static EnumPropertyItem texture_filter_items[] = { #include "BKE_texture.h" #include "ED_node.h" -StructRNA *rna_Texture_refine(struct PointerRNA *ptr) +static StructRNA *rna_Texture_refine(struct PointerRNA *ptr) { Tex *tex= (Tex*)ptr->data; @@ -202,7 +202,7 @@ static void rna_Texture_use_color_ramp_set(PointerRNA *ptr, int value) tex->coba= add_colorband(0); } -void rna_Texture_use_nodes_set(PointerRNA *ptr, int v) +static void rna_Texture_use_nodes_set(PointerRNA *ptr, int v) { Tex *tex= (Tex*)ptr->data; diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index af3ac4a0a82..53532e3f383 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -197,7 +197,7 @@ static StructRNA *rna_OperatorProperties_refine(PointerRNA *ptr) return ptr->type; } -IDProperty *rna_OperatorProperties_idproperties(PointerRNA *ptr, int create) +static IDProperty *rna_OperatorProperties_idproperties(PointerRNA *ptr, int create) { if(create && !ptr->data) { IDPropertyTemplate val = {0}; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ad490bb599a..86a02e2731a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -747,7 +747,7 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) } /* op->poll */ -int wm_search_menu_poll(bContext *C) +static int wm_search_menu_poll(bContext *C) { if(CTX_wm_window(C)==NULL) return 0; if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_CONSOLE) return 0; // XXX - so we can use the shortcut in the console -- cgit v1.2.3 From bee18c57d4b674282bf8d51ec0491a79e6b13faa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 14 Sep 2009 17:13:58 +0000 Subject: fix warning --- source/blender/python/generic/Mathutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index 32262276d0a..d354aea6614 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -437,7 +437,7 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) mat[8] = 1.0f; } else if((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) { //arbitrary rotation - AxisAngleToMat3(vec->vec, angle, (float *)mat); + AxisAngleToMat3(vec->vec, angle, (float (*)[3])mat); } else { PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n"); -- cgit v1.2.3 From c6107e0c7602db46ee535542a205d1afcccaebfb Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 17:22:51 +0000 Subject: Smoke: * Only simulate smoke when starting from startframe --- source/blender/blenkernel/intern/smoke.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 66aaa97af55..99d4176c937 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1123,17 +1123,22 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM cache_wt = sds->point_cache[1]; BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd); + if(!smd->domain->fluid) + { + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED); + } + if(framenr < startframe) return; if(framenr > endframe) return; - if(!smd->domain->fluid) - { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED); - } + if(!smd->domain->fluid && (framenr != startframe)) + return; + + // printf("startframe: %d, framenr: %d\n", startframe, framenr); if(!smokeModifier_init(smd, ob, scene, dm)) { -- cgit v1.2.3 From 725c30f6063354182628e4adbb563eadb4980222 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 19:12:29 +0000 Subject: 2.5 Bugfixes #19345: can't get out of grayed out pointer field. #19342: item_pointerR fields can't be cleared with one item. #19341: fix hanging tooltips when manipulating regions. #19339: context panel still allowed tabbing, but it has no header. #19334: editing SSS settings crashed previewrender. #19330: object mode could not be switched on from the header menu. --- source/blender/blenkernel/intern/material.c | 6 ++-- source/blender/blenloader/intern/readfile.c | 9 ++++++ source/blender/editors/include/ED_screen.h | 1 + .../blender/editors/interface/interface_handlers.c | 32 ++++++++++++++-------- source/blender/editors/interface/interface_panel.c | 1 + .../blender/editors/interface/interface_regions.c | 2 +- source/blender/editors/object/object_edit.c | 19 ++++++------- source/blender/editors/screen/area.c | 13 +++++++++ source/blender/editors/screen/screen_ops.c | 16 ++++++----- source/blender/editors/space_file/file_ops.c | 10 ++----- source/blender/editors/space_graph/graph_buttons.c | 10 ++----- source/blender/editors/space_image/image_buttons.c | 10 ++----- source/blender/editors/space_logic/logic_buttons.c | 10 ++----- source/blender/editors/space_nla/nla_buttons.c | 10 ++----- .../editors/space_sequencer/sequencer_buttons.c | 10 ++----- source/blender/editors/space_text/text_header.c | 11 +------- source/blender/editors/space_view3d/space_view3d.c | 2 ++ .../blender/editors/space_view3d/view3d_buttons.c | 10 ++----- source/blender/editors/space_view3d/view3d_snap.c | 12 ++++---- .../blender/editors/space_view3d/view3d_toolbar.c | 10 ++----- source/blender/render/intern/source/pipeline.c | 2 +- source/blender/render/intern/source/sss.c | 13 ++++++--- 22 files changed, 108 insertions(+), 111 deletions(-) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index e6f9ac2f404..1667bd97102 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -159,9 +159,9 @@ void init_material(Material *ma) ma->sss_radius[0]= 1.0f; ma->sss_radius[1]= 1.0f; ma->sss_radius[2]= 1.0f; - ma->sss_col[0]= 0.8f; - ma->sss_col[1]= 0.8f; - ma->sss_col[2]= 0.8f; + ma->sss_col[0]= 1.0f; + ma->sss_col[1]= 1.0f; + ma->sss_col[2]= 1.0f; ma->sss_error= 0.05f; ma->sss_scale= 0.1f; ma->sss_ior= 1.3f; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c2d745bfc8e..d0264002214 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4861,6 +4861,10 @@ static void view3d_split_250(View3D *v3d, ListBase *regions) QUATCOPY(rv3d->viewquat, v3d->viewquat); } } + + /* this was not initialized correct always */ + if(v3d->twtype == 0) + v3d->twtype= V3D_MANIP_TRANSLATE; } static void direct_link_screen(FileData *fd, bScreen *sc) @@ -9687,6 +9691,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put 2.50 compatibility code here until next subversion bump */ { + Scene *sce; + + for(sce = main->scene.first; sce; sce = sce->id.next) + if(sce->unit.scale_length == 0.0f) + sce->unit.scale_length= 1.0f; } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 697565184f3..63b6a067389 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -58,6 +58,7 @@ void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar); void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, char *context, int contextnr); void ED_region_header_init(struct ARegion *ar); void ED_region_header(const struct bContext *C, struct ARegion *ar); +void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar); void region_scissor_winrct(struct ARegion *ar, struct rcti *winrct); /* spaces */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 259ccba6b89..466c1d08ba3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1440,16 +1440,20 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa for(but= actbut->next; but; but= but->next) { if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { - data->postbut= but; - data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; - return; + if(!(but->flag & UI_BUT_DISABLED)) { + data->postbut= but; + data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; + return; + } } } for(but= block->buttons.first; but!=actbut; but= but->next) { if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { - data->postbut= but; - data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; - return; + if(!(but->flag & UI_BUT_DISABLED)) { + data->postbut= but; + data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; + return; + } } } } @@ -1464,16 +1468,20 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa for(but= actbut->prev; but; but= but->prev) { if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { - data->postbut= but; - data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; - return; + if(!(but->flag & UI_BUT_DISABLED)) { + data->postbut= but; + data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; + return; + } } } for(but= block->buttons.last; but!=actbut; but= but->prev) { if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { - data->postbut= but; - data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; - return; + if(!(but->flag & UI_BUT_DISABLED)) { + data->postbut= but; + data->posttype= BUTTON_ACTIVATE_TEXT_EDITING; + return; + } } } } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 05001109b53..776122380bf 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -990,6 +990,7 @@ static void test_add_new_tabs(ARegion *ar) } if(pasel==NULL || palap==NULL) return; + if(palap->type && palap->type->flag & PNL_NO_HEADER) return; /* the overlapped panel becomes a tab */ palap->paneltab= pasel; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 1d911fef418..dfcdea59f68 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -758,7 +758,7 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset) data->active= a+1; if(cpoin) cpoin[0]= '|'; } - if(data->items.totitem==1) + if(data->items.totitem==1 && but->editstr[0]) data->active= 1; } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index e5a8df8cb26..c734a7c606d 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1957,29 +1957,26 @@ static int object_mode_set_compat(bContext *C, wmOperator *op, Object *ob) ObjectMode mode = RNA_enum_get(op->ptr, "mode"); if(ob) { + if(mode == OB_MODE_OBJECT) + return 1; + switch(ob->type) { - case OB_EMPTY: - case OB_LAMP: - case OB_CAMERA: - if(mode & OB_MODE_OBJECT) - return 1; - return 0; case OB_MESH: - if(mode & ( OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT)) + if(mode & (OB_MODE_EDIT|OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT)) return 1; return 0; case OB_CURVE: case OB_SURF: case OB_FONT: case OB_MBALL: - if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT)) + if(mode & (OB_MODE_EDIT)) return 1; return 0; case OB_LATTICE: - if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT)) + if(mode & (OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT)) return 1; case OB_ARMATURE: - if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_POSE)) + if(mode & (OB_MODE_EDIT|OB_MODE_POSE)) return 1; } } @@ -2036,7 +2033,7 @@ void OBJECT_OT_mode_set(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - prop= RNA_def_enum(ot->srna, "mode", object_mode_items, 0, "Mode", ""); + prop= RNA_def_enum(ot->srna, "mode", object_mode_items, OB_MODE_OBJECT, "Mode", ""); RNA_def_enum_funcs(prop, object_mode_set_itemsf); RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", ""); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 81f06611c39..8940f560677 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -916,6 +916,19 @@ void ED_region_init(bContext *C, ARegion *ar) } +void ED_region_toggle_hidden(bContext *C, ARegion *ar) +{ + ScrArea *sa= CTX_wm_area(C); + + ar->flag ^= RGN_FLAG_HIDDEN; + ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ + + if(ar->flag & RGN_FLAG_HIDDEN) + WM_event_remove_handlers(C, &ar->handlers); + + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); +} /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */ /* area vertices were set */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index dba882200ce..f32b11812cf 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1320,10 +1320,11 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) CLAMP(rmd->ar->type->minsizex, 0, 1000); if(rmd->ar->type->minsizex < 24) { rmd->ar->type->minsizex= rmd->origval; - rmd->ar->flag |= RGN_FLAG_HIDDEN; + if(!(rmd->ar->flag & RGN_FLAG_HIDDEN)) + ED_region_toggle_hidden(C, rmd->ar); } - else - rmd->ar->flag &= ~RGN_FLAG_HIDDEN; + else if(rmd->ar->flag & RGN_FLAG_HIDDEN) + ED_region_toggle_hidden(C, rmd->ar); } else { delta= event->y - rmd->origy; @@ -1332,10 +1333,11 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) CLAMP(rmd->ar->type->minsizey, 0, 1000); if(rmd->ar->type->minsizey < 24) { rmd->ar->type->minsizey= rmd->origval; - rmd->ar->flag |= RGN_FLAG_HIDDEN; + if(!(rmd->ar->flag & RGN_FLAG_HIDDEN)) + ED_region_toggle_hidden(C, rmd->ar); } - else - rmd->ar->flag &= ~RGN_FLAG_HIDDEN; + else if(rmd->ar->flag & RGN_FLAG_HIDDEN) + ED_region_toggle_hidden(C, rmd->ar); } WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); @@ -1346,7 +1348,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) if(event->val==0) { if(ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) { - rmd->ar->flag ^= RGN_FLAG_HIDDEN; + ED_region_toggle_hidden(C, rmd->ar); WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } MEM_freeN(op->customdata); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 9705a36fc75..d2d1d11ec5c 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -855,13 +855,9 @@ int file_bookmark_toggle_exec(bContext *C, wmOperator *unused) ScrArea *sa= CTX_wm_area(C); ARegion *ar= file_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index fb995285ab7..9aa02b45950 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -427,13 +427,9 @@ static int graph_properties(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= graph_has_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 21fccdc65f8..647b9a4b51f 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -1452,13 +1452,9 @@ static int image_properties(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= image_has_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c index 58c1eddb6c1..304c3601cdd 100644 --- a/source/blender/editors/space_logic/logic_buttons.c +++ b/source/blender/editors/space_logic/logic_buttons.c @@ -124,13 +124,9 @@ static int logic_properties(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= logic_has_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 8532d78aa06..a5ba63fd15d 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -458,13 +458,9 @@ static int nla_properties(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= nla_has_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 789843f5490..72cbacd9b6d 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -112,13 +112,9 @@ static int sequencer_properties(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= sequencer_has_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c index 089436cfcf9..d0a02f558e1 100644 --- a/source/blender/editors/space_text/text_header.c +++ b/source/blender/editors/space_text/text_header.c @@ -186,15 +186,6 @@ ARegion *text_has_properties_region(ScrArea *sa) return arnew; } -void text_toggle_properties_region(bContext *C, ScrArea *sa, ARegion *ar) -{ - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); -} - static int properties_poll(bContext *C) { return (CTX_wm_space_text(C) != NULL); @@ -206,7 +197,7 @@ static int properties_exec(bContext *C, wmOperator *op) ARegion *ar= text_has_properties_region(sa); if(ar) - text_toggle_properties_region(C, sa, ar); + ED_region_toggle_hidden(C, ar); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 2250c2e7718..05bf1c80b43 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -190,6 +190,8 @@ static SpaceLink *view3d_new(const bContext *C) v3d->lens= 35.0f; v3d->near= 0.01f; v3d->far= 500.0f; + + v3d->twtype= V3D_MANIP_TRANSLATE; /* header */ ar= MEM_callocN(sizeof(ARegion), "header for view3d"); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 54a8c375e69..1ff5dca7307 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1458,13 +1458,9 @@ static int view3d_properties(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= view3d_has_buttons_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index b4b54cd1d88..767f18649fa 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -1122,13 +1122,13 @@ static int snap_menu_invoke(bContext *C, wmOperator *unused, wmEvent *event) uiPopupMenu *pup= uiPupMenuBegin(C, "Snap", 0); uiLayout *layout= uiPupMenuLayout(pup); - uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_grid"); - uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_cursor"); - uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_selected_to_center"); + uiItemO(layout, "Selected to Grid", 0, "VIEW3D_OT_snap_selected_to_grid"); + uiItemO(layout, "Selected to Cursor", 0, "VIEW3D_OT_snap_selected_to_cursor"); + uiItemO(layout, "Selected to Center", 0, "VIEW3D_OT_snap_selected_to_center"); uiItemS(layout); - uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_cursor_to_selected"); - uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_cursor_to_grid"); - uiItemO(layout, NULL, 0, "VIEW3D_OT_snap_cursor_to_active"); + uiItemO(layout, "Cursor to Selected", 0, "VIEW3D_OT_snap_cursor_to_selected"); + uiItemO(layout, "Cursor to Grid", 0, "VIEW3D_OT_snap_cursor_to_grid"); + uiItemO(layout, "Cursor to Active", 0, "VIEW3D_OT_snap_cursor_to_active"); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 58248f675da..46341f53c26 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -309,13 +309,9 @@ static int view3d_toolbar(bContext *C, wmOperator *op) ScrArea *sa= CTX_wm_area(C); ARegion *ar= view3d_has_tools_region(sa); - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } + if(ar) + ED_region_toggle_hidden(C, ar); + return OPERATOR_FINISHED; } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index a6b089c6029..8ef52991ca2 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1526,7 +1526,7 @@ static void threaded_tile_processor(Render *re) if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { RE_FreeRenderResult(re->result); - if(re->sss_points) + if(re->sss_points && render_display_draw_enabled(re)) re->result= new_render_result(re, &re->disprect, 0, 0); else if(re->r.scemode & R_FULL_SAMPLE) re->result= new_full_sample_buffers_exr(re); diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index bd022e768f8..29f4d7729fe 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -872,12 +872,17 @@ static void sss_create_tree_mat(Render *re, Material *mat) re->sss_points= &points; re->sss_mat= mat; re->i.partsdone= 0; - re->result= NULL; - RE_TileProcessor(re, 0, !(re->r.mode & R_PREVIEWBUTS)); - RE_FreeRenderResult(re->result); + if(!(re->r.scemode & R_PREVIEWBUTS)) + re->result= NULL; + + RE_TileProcessor(re, 0, 1); + + if(!(re->r.scemode & R_PREVIEWBUTS)) { + RE_FreeRenderResult(re->result); + re->result= rr; + } - re->result= rr; re->i.partsdone= partsdone; re->sss_mat= NULL; re->sss_points= NULL; -- cgit v1.2.3 From f302ebeb670f021d627388ab7f0e1fc682183250 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 19:49:40 +0000 Subject: 2.5 Bugfixes #19343: vertex paint blur was not working. shared vcol was disabled for speed, but blurring still needs it. Also fixed brushes with size > 64 not working correct. #19314: non-zbuffer selection did not work with background image, drawing it made the WM matrix go out of sync. Forgot to mention these in previous commit: * Manipulator type was not properly initialized, .B.blend update helps, but still needed version patch & correct setting for new space. * Added a utility function for the toggling region hide, instead of duplicating the code. * SSS preview render preprocessing pass now also uses multiple threads. * Added version patch for unit scale, was still 0.0. --- source/blender/editors/sculpt_paint/paint_vertex.c | 8 +++++++- source/blender/editors/space_view3d/view3d_draw.c | 14 ++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 25ff57ca87f..2375e4e70ec 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -710,7 +710,9 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x if(totface+4>=MAXINDEX) return 0; - if(size>64.0) size= 64.0; + /* brecht: disabled this because it obviously failes for + brushes with size > 64, why is this here? */ + /*if(size>64.0) size= 64.0;*/ ibuf= view3d_read_backbuf(vc, x-size, y-size, x+size, y+size); if(ibuf) { @@ -1732,6 +1734,10 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P } Mat4SwapMat4(vc->rv3d->persmat, mat); + + /* was disabled because it is slow, but necessary for blur */ + if(vp->mode == VP_BLUR) + do_shared_vertexcol(me); ED_region_tag_redraw(vc->ar); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 918aebda8e1..f8584b14e2b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1416,12 +1416,9 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - -// glaDefine2DArea(&ar->winrct); + /* need to use wm push/pop matrix because ED_region_pixelspace + uses the wm functions too, otherwise gets out of sync */ + wmPushMatrix(); ED_region_pixelspace(ar); glEnable(GL_BLEND); @@ -1433,10 +1430,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) glPixelZoom(1.0, 1.0); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + wmPopMatrix(); glDisable(GL_BLEND); if(v3d->zbuf) glEnable(GL_DEPTH_TEST); -- cgit v1.2.3 From 1b2344a1f1c2d1a8e0a914c1eb46bf4e36323c66 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Mon, 14 Sep 2009 20:17:56 +0000 Subject: Also set utf8 encoded hint for window title. --- intern/ghost/intern/GHOST_WindowX11.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 88ae8afd0ce..3aff9d64a17 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -294,7 +294,7 @@ GHOST_WindowX11( } // Create some hints for the window manager on how - // we want this window treated. + // we want this window treated. XSizeHints * xsizehints = XAllocSizeHints(); xsizehints->flags = USPosition | USSize; @@ -514,7 +514,7 @@ GHOST_WindowX11:: getXWindow( ){ return m_window; -} +} bool GHOST_WindowX11:: @@ -528,7 +528,17 @@ GHOST_WindowX11:: setTitle( const STR_String& title ){ + Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0); + Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0); + XChangeProperty(m_display, m_window, + name, utf8str, 8, PropModeReplace, + (const unsigned char*) title.ReadPtr(), + strlen(title.ReadPtr())); + +// This should convert to valid x11 string +// and getTitle would need matching change XStoreName(m_display,m_window,title); + XFlush(m_display); } -- cgit v1.2.3 From be69305d85f09079c80df23b30c7a7c8f3663ab6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 14 Sep 2009 20:48:05 +0000 Subject: 2.5 Bugfixes #19302: the spin operator did not redo correct when changing properties. Actually the problem was somewhere else, the search menu always did an unnecessary undo push, which conflicted with an operator undo push with the same name. Only in the case of "Spin" was this noticed, because it's name is so short and you actually type it completely. #19328: swapping areas could crash when dragging mouse outside the window. Attempted fix for #19331, #19335 as well, where backspace and some other keys give square characters instead of working as expected. Couldn't reproducable here, so please test. --- source/blender/editors/include/UI_interface.h | 1 + source/blender/editors/interface/interface.c | 3 +++ source/blender/editors/interface/interface_handlers.c | 3 +-- source/blender/editors/interface/interface_layout.c | 2 +- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/windowmanager/intern/wm_event_system.c | 2 +- 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b45ab2d4997..921aa60f9b2 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -146,6 +146,7 @@ typedef struct uiLayout uiLayout; #define UI_BUT_DRIVEN (1<<22) #define UI_BUT_INACTIVE (1<<23) #define UI_BUT_LAST_ACTIVE (1<<24) +#define UI_BUT_UNDO (1<<25) #define UI_PANEL_WIDTH 340 #define UI_COMPACT_PANEL_WIDTH 160 diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 3c6e12905d6..221618b340e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2264,6 +2264,9 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short } } + if(!ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, SEARCH_MENU)) + but->flag |= UI_BUT_UNDO; + BLI_addtail(&block->buttons, but); if(block->curlayout) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 466c1d08ba3..152695c9162 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -292,8 +292,7 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but) uiAfterFunc *after; char *str= NULL; - if ELEM6(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX); - else { + if(but->flag & UI_BUT_UNDO) { /* define which string to use for undo */ if ELEM(but->type, LINK, INLINK) str= "Add button link"; else if ELEM(but->type, MENU, ICONTEXTROW) str= but->drawstr; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 242ba31ccd4..b6afc4daa9b 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1107,7 +1107,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN but->hardmax= MAX2(but->hardmax, 256); but->rnasearchpoin= *searchptr; but->rnasearchprop= searchprop; - but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT; + but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT|UI_BUT_UNDO; uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index f32b11812cf..0bb1969ce3c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -605,7 +605,7 @@ static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event) break; case LEFTMOUSE: /* release LMB */ if(event->val==0) { - if(sad->sa1 == sad->sa2) { + if(!sad->sa2 || sad->sa1 == sad->sa2) { return area_swap_cancel(C, op); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 28814937ebe..b5ecc6f4d58 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -715,7 +715,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) /* the matching rules */ if(kmitype==KM_TEXTINPUT) - if(ISKEYBOARD(winevent->type)) return 1; + if(ISKEYBOARD(winevent->type) && winevent->ascii) return 1; if(kmitype!=KM_ANY) if(winevent->type!=kmitype) return 0; -- cgit v1.2.3 From 524a8e32b157a4a8e8eafcb47bed378838342a19 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 21:55:48 +0000 Subject: Smoke: * Fixing compile warning --- source/blender/editors/space_view3d/drawvolume.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 3a79caed821..a81174ff768 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -223,7 +223,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture "MUL temp.b, temp.b, shadow.r;\n" "MOV result.color, temp;\n" "END\n"; - unsigned int prog; + GLuint prog; float size[3]; @@ -328,7 +328,7 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture // printf("i: %d\n", i); - if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) + if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) { glEnable(GL_FRAGMENT_PROGRAM_ARB); glGenProgramsARB(1, &prog); -- cgit v1.2.3 From 41ed712ea3937d8baf601131df4f2063e8997764 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 14 Sep 2009 22:27:10 +0000 Subject: Smoke: * Bugfix for non working 3dview Credits: Thanks to Wahooney, jesterKing and a big thanks to Matt/broken for hunting this down! --- source/blender/gpu/intern/gpu_extensions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index d7b54e425fd..4a31df04627 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -348,7 +348,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) type = GL_FLOAT; // GL_UNSIGNED_BYTE format = GL_RED; - internalformat = GL_RED; + internalformat = GL_INTENSITY; //if (fpixels) // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); -- cgit v1.2.3 From aa8163e399e43ea08491bfc2740d6c9c8e0075d1 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Mon, 14 Sep 2009 23:00:58 +0000 Subject: Revert endianess test to 2.49 style. Reported by jms. --- source/blender/imbuf/intern/anim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 1aaba620f3a..ffc511b9bd8 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -779,7 +779,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { } } - if (ENDIAN_ORDER == B_ENDIAN) { + if (G.order == B_ENDIAN) { int * dstStride = anim->pFrameRGB->linesize; uint8_t** dst = anim->pFrameRGB->data; -- cgit v1.2.3 From 223bc8aee1c6f0c1e6d16d0edd8cf23387c33a3f Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 15 Sep 2009 03:54:13 +0000 Subject: * Added RNA path functionality to fluidsim modifier settings, to allow keying of fluidsim settings properties. Note: Although the properties can be animated with the RNA system, the values are not exported to the actual fluid sim yet, that can come later. --- source/blender/blenkernel/intern/fluidsim.c | 1 + source/blender/blenloader/intern/readfile.c | 13 +++++++++++++ source/blender/makesdna/DNA_object_fluidsim.h | 1 + source/blender/makesrna/intern/rna_fluidsim.c | 9 +++++++++ 4 files changed, 24 insertions(+) diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index ad9e481ffd2..aa163b821c8 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -80,6 +80,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd) if(!fss) return; + fss->fmd = fluidmd; fss->type = OB_FLUIDSIM_ENABLE; fss->show_advancedoptions = 0; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d0264002214..bb7262c01d4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9692,10 +9692,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put 2.50 compatibility code here until next subversion bump */ { Scene *sce; + Object *ob; for(sce = main->scene.first; sce; sce = sce->id.next) if(sce->unit.scale_length == 0.0f) sce->unit.scale_length= 1.0f; + + for(ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + + /* add backwards pointer for fluidsim modifier RNA access */ + for (md=ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Fluidsim) { + FluidsimModifierData *fluidmd= (FluidsimModifierData*) md; + fluidmd->fss->fmd = fluidmd; + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h index 09288b24c20..da55fb1d47c 100644 --- a/source/blender/makesdna/DNA_object_fluidsim.h +++ b/source/blender/makesdna/DNA_object_fluidsim.h @@ -41,6 +41,7 @@ struct Ipo; struct MVert; typedef struct FluidsimSettings { + struct FluidsimModifierData *fmd; /* for fast RNA access */ /* domain,fluid or obstacle */ short type; /* display advanced options in fluid sim tab (on=1,off=0)*/ diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index a62002365c9..c415b3d716a 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -151,6 +151,14 @@ static int rna_DomainFluidSettings_memory_estimate_length(PointerRNA *ptr) return 32; } +static char *rna_FluidSettings_path(PointerRNA *ptr) +{ + FluidsimSettings *fss = (FluidsimSettings*)ptr->data; + ModifierData *md= (ModifierData *)fss->fmd; + + return BLI_sprintfN("modifiers[%s].settings", md->name); +} + #else static void rna_def_fluidsim_slip(StructRNA *srna) @@ -509,6 +517,7 @@ void RNA_def_fluidsim(BlenderRNA *brna) srna= RNA_def_struct(brna, "FluidSettings", NULL); RNA_def_struct_sdna(srna, "FluidsimSettings"); RNA_def_struct_refine_func(srna, "rna_FluidSettings_refine"); + RNA_def_struct_path_func(srna, "rna_FluidSettings_path"); RNA_def_struct_ui_text(srna, "Fluid Simulation Settings", "Fluid simulation settings for an object taking part in the simulation."); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); -- cgit v1.2.3 From 689b77ba9df8b618e0d7b58feda9161317361d74 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Sep 2009 10:01:20 +0000 Subject: - new property attribute - default_array, which returns a variable size array useful to get the defaults for operator & function arrays. - updated python api to check for array types rather then the length since a variable length array can be 1 or 0 length. - python docgen added .0 to the end of floats which messed up values like 1e-05 --- source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_access.c | 17 ++++++ source/blender/makesrna/intern/rna_particle.c | 2 +- source/blender/makesrna/intern/rna_rna.c | 80 +++++++++++++++++++++++++-- source/blender/python/epy_doc_gen.py | 2 +- source/blender/python/intern/bpy_rna.c | 62 ++++++++++----------- 6 files changed, 125 insertions(+), 39 deletions(-) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 05f39d73842..ca3ac62ba00 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -586,6 +586,7 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop); int RNA_property_flag(PropertyRNA *prop); int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop); +int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop); int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension); int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]); char RNA_property_array_item_char(PropertyRNA *prop, int index); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index e4bda24cf20..9472cdb300c 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -225,6 +225,18 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop) } } +static int rna_ensure_property_array_check(PointerRNA *ptr, PropertyRNA *prop) +{ + if(prop->magic == RNA_MAGIC) { + return (prop->getlength || prop->totarraylength) ? 1:0; + } + else { + IDProperty *idprop= (IDProperty*)prop; + + return idprop->type == IDP_ARRAY ? 1:0; + } +} + static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[]) { if(prop->magic == RNA_MAGIC) { @@ -574,6 +586,11 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop) return rna_ensure_property_array_length(ptr, prop); } +int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop) +{ + return rna_ensure_property_array_check(ptr, prop); +} + /* used by BPY to make an array from the python object */ int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]) { diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index e6f0a462f03..bbbb13c6e97 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -254,7 +254,7 @@ static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr) } static void rna_Particle_hair_dynamics(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); + /* Scene *scene = CTX_data_scene(C); */ ParticleSystem *psys = (ParticleSystem*)ptr->data; if(psys && !psys->clmd) { diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 8df6398f1f4..196d25ada86 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -458,6 +458,62 @@ static int rna_IntProperty_default_get(PointerRNA *ptr) rna_idproperty_check(&prop, ptr); return ((IntPropertyRNA*)prop)->defaultvalue; } +/* int/float/bool */ +static int rna_NumberProperty_default_array_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION]) +{ + PropertyRNA *prop= (PropertyRNA*)ptr->data; + rna_idproperty_check(&prop, ptr); + + length[0]= prop->totarraylength; + + return length[0]; +} +static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values) +{ + PropertyRNA *prop= (PropertyRNA*)ptr->data; + IntPropertyRNA *nprop= (IntPropertyRNA*)prop; + rna_idproperty_check(&prop, ptr); + + if(nprop->defaultarray) { + memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int)); + } + else { + int i; + for(i=0; i < prop->totarraylength; i++) + values[i]= nprop->defaultvalue; + } +} +static void rna_BoolProperty_default_array_get(PointerRNA *ptr, int *values) +{ + PropertyRNA *prop= (PropertyRNA*)ptr->data; + BooleanPropertyRNA *nprop= (BooleanPropertyRNA*)prop; + rna_idproperty_check(&prop, ptr); + + if(nprop->defaultarray) { + memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int)); + } + else { + int i; + for(i=0; i < prop->totarraylength; i++) + values[i]= nprop->defaultvalue; + } +} +static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values) +{ + PropertyRNA *prop= (PropertyRNA*)ptr->data; + FloatPropertyRNA *nprop= (FloatPropertyRNA*)prop; + rna_idproperty_check(&prop, ptr); + + if(nprop->defaultarray) { + memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(float)); + } + else { + int i; + for(i=0; i < prop->totarraylength; i++) + values[i]= nprop->defaultvalue; + } +} + static int rna_IntProperty_hard_min_get(PointerRNA *ptr) { PropertyRNA *prop= (PropertyRNA*)ptr->data; @@ -932,13 +988,27 @@ static void rna_def_number_property(StructRNA *srna, PropertyType type) } -#if 0 // XXX - Variable length arrays prop= RNA_def_property(srna, "default_array", type, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL); - else RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL); - RNA_def_property_ui_text(prop, "Default", "Default value for this number"); -#endif + RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION); /* no fixed default length, important its not 0 though */ + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_dynamic_array_funcs(prop, "rna_NumberProperty_default_array_get_length"); /* same for all types */ + + switch(type) { + case PROP_BOOLEAN: + RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_array_get", NULL); + break; + case PROP_INT: + RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL); + break; + case PROP_FLOAT: + RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL); + break; + default: + break; + } + RNA_def_property_ui_text(prop, "Default Array", "Default value for this array"); + prop= RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py index c2ef6bbc0d0..4ff5c8102e2 100644 --- a/source/blender/python/epy_doc_gen.py +++ b/source/blender/python/epy_doc_gen.py @@ -225,7 +225,7 @@ def write_func(rna, ident, out, func_type): elif rna_prop_type=='float': if length==0: val_str= '%g' % val - if '.' not in val_str: + if '.' not in val_str and '-' not in val_str: # value could be 1e-05 val_str += '.0' else: # array diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index dd6bc35fc0a..820f96f1e81 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -349,9 +349,8 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) { PyObject *ret; int type = RNA_property_type(prop); - int len = RNA_property_array_length(ptr, prop); - if (len > 0) { + if (RNA_property_array_check(ptr, prop)) { return pyrna_py_from_array(ptr, prop); } @@ -521,9 +520,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v { /* XXX hard limits should be checked here */ int type = RNA_property_type(prop); - int len = RNA_property_array_length(ptr, prop); - if (len > 0) { + + if (RNA_property_array_check(ptr, prop)) { + /* char error_str[512]; */ int ok= 1; @@ -819,13 +819,11 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self ) if (RNA_property_type(self->prop) == PROP_COLLECTION) { len = RNA_property_collection_length(&self->ptr, self->prop); - } else { + } else if (RNA_property_array_check(&self->ptr, self->prop)) { len = pyrna_prop_array_length(self); - - if (len==0) { /* not an array*/ - PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types"); - return -1; - } + } else { + PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types"); + len = -1; /* error value */ } return len; @@ -979,7 +977,7 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) { if (RNA_property_type(self->prop) == PROP_COLLECTION) { return prop_subscript_collection(self, key); - } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */ + } else if (RNA_property_array_check(&self->ptr, self->prop)) { return prop_subscript_array(self, key); } @@ -1681,32 +1679,31 @@ static PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args) PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) { /* Try get values from a collection */ - PyObject *ret = pyrna_prop_values(self); + PyObject *ret; - if (ret==NULL) { - /* collection did not work, try array */ + if(RNA_property_array_check(&self->ptr, self->prop)) { int len = pyrna_prop_array_length(self); + int i; + PyErr_Clear(); + ret = PyList_New(len); - if (len) { - int i; - PyErr_Clear(); - ret = PyList_New(len); - - for (i=0; i < len; i++) { - PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i)); - } + for (i=0; i < len; i++) { + PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i)); } } - - if (ret) { - /* we know this is a list so no need to PyIter_Check */ - PyObject *iter = PyObject_GetIter(ret); - Py_DECREF(ret); - return iter; + else if (ret = pyrna_prop_values(self)) { + /* do nothing */ + } + else { + PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" ); + return NULL; } - PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" ); - return NULL; + + /* we know this is a list so no need to PyIter_Check */ + PyObject *iter = PyObject_GetIter(ret); + Py_DECREF(ret); + return iter; } static struct PyMethodDef pyrna_struct_methods[] = { @@ -1776,11 +1773,12 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) { PyObject *ret; int type = RNA_property_type(prop); - int len = RNA_property_array_length(ptr, prop); int a; - if(len > 0) { + if(RNA_property_array_check(ptr, prop)) { + int len = RNA_property_array_length(ptr, prop); + /* resolve the array from a new pytype */ ret = PyTuple_New(len); -- cgit v1.2.3 From 9a2cd02ae4baf4f759f076e1db4db4c8c2e69a39 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 15 Sep 2009 10:23:44 +0000 Subject: UI: renamed 3dview menus to be lower case, not too important now, but once these become extensible we need consistent names. --- release/ui/space_view3d.py | 272 ++++++++++++++++++++++----------------------- 1 file changed, 136 insertions(+), 136 deletions(-) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 2539ded18bf..33f9fbb853d 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -25,17 +25,17 @@ class VIEW3D_HT_header(bpy.types.Header): # Select Menu if mode_string not in ('EDIT_TEXT', 'SCULPT', 'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'): - sub.itemM("VIEW3D_MT_select_%s" % mode_string) + sub.itemM("VIEW3D_MT_select_%s" % mode_string.lower()) if edit_object: - sub.itemM("VIEW3D_MT_edit_%s" % edit_object.type) + sub.itemM("VIEW3D_MT_edit_%s" % edit_object.type.lower()) elif object: ob_mode_string = object.mode if mode_string not in ['PAINT_WEIGHT', 'PAINT_TEXTURE']: - sub.itemM("VIEW3D_MT_%s" % mode_string) + sub.itemM("VIEW3D_MT_%s" % mode_string.lower()) else: - sub.itemM("VIEW3D_MT_OBJECT") + sub.itemM("VIEW3D_MT_object") layout.template_header_3D() @@ -155,7 +155,7 @@ class VIEW3D_MT_view_cameras(bpy.types.Menu): # ********** Select menus, suffix from context.mode ********** -class VIEW3D_MT_select_OBJECT(bpy.types.Menu): +class VIEW3D_MT_select_object(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -174,7 +174,7 @@ class VIEW3D_MT_select_OBJECT(bpy.types.Menu): layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...") layout.itemO("object.select_grouped", text="Select Grouped...") -class VIEW3D_MT_select_POSE(bpy.types.Menu): +class VIEW3D_MT_select_pose(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -205,7 +205,7 @@ class VIEW3D_MT_select_POSE(bpy.types.Menu): props.extend = True props.direction = 'CHILD' -class VIEW3D_MT_select_PARTICLE(bpy.types.Menu): +class VIEW3D_MT_select_particle(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -224,7 +224,7 @@ class VIEW3D_MT_select_PARTICLE(bpy.types.Menu): layout.itemO("particle.select_more") layout.itemO("particle.select_less") -class VIEW3D_MT_select_EDIT_MESH(bpy.types.Menu): +class VIEW3D_MT_select_edit_mesh(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -268,7 +268,7 @@ class VIEW3D_MT_select_EDIT_MESH(bpy.types.Menu): layout.itemO("mesh.loop_to_region") layout.itemO("mesh.region_to_loop") -class VIEW3D_MT_select_EDIT_CURVE(bpy.types.Menu): +class VIEW3D_MT_select_edit_curve(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -297,7 +297,7 @@ class VIEW3D_MT_select_EDIT_CURVE(bpy.types.Menu): layout.itemO("curve.select_more") layout.itemO("curve.select_less") -class VIEW3D_MT_select_EDIT_SURFACE(bpy.types.Menu): +class VIEW3D_MT_select_edit_surface(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -323,7 +323,7 @@ class VIEW3D_MT_select_EDIT_SURFACE(bpy.types.Menu): layout.itemO("curve.select_more") layout.itemO("curve.select_less") -class VIEW3D_MT_select_EDIT_METABALL(bpy.types.Menu): +class VIEW3D_MT_select_edit_metaball(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -341,7 +341,7 @@ class VIEW3D_MT_select_EDIT_METABALL(bpy.types.Menu): layout.itemO("mball.select_random_metaelems") -class VIEW3D_MT_select_EDIT_LATTICE(bpy.types.Menu): +class VIEW3D_MT_select_edit_lattice(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -354,7 +354,7 @@ class VIEW3D_MT_select_EDIT_LATTICE(bpy.types.Menu): layout.itemO("lattice.select_all_toggle", text="Select/Deselect All") -class VIEW3D_MT_select_EDIT_ARMATURE(bpy.types.Menu): +class VIEW3D_MT_select_edit_armature(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -383,7 +383,7 @@ class VIEW3D_MT_select_EDIT_ARMATURE(bpy.types.Menu): props.extend = True props.direction = 'CHILD' -class VIEW3D_MT_select_FACE(bpy.types.Menu):# XXX no matching enum +class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum __space_type__ = 'VIEW_3D' __label__ = "Select" @@ -394,7 +394,7 @@ class VIEW3D_MT_select_FACE(bpy.types.Menu):# XXX no matching enum # ********** Object menu ********** -class VIEW3D_MT_OBJECT(bpy.types.Menu): +class VIEW3D_MT_object(bpy.types.Menu): __space_type__ = 'VIEW_3D' __context__ = "objectmode" __label__ = "Object" @@ -402,7 +402,7 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.itemM("VIEW3D_MT_OBJECT_clear") + layout.itemM("VIEW3D_MT_object_clear") layout.itemM("VIEW3D_MT_snap") layout.itemS() @@ -419,10 +419,10 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_OBJECT_parent") - layout.itemM("VIEW3D_MT_OBJECT_track") - layout.itemM("VIEW3D_MT_OBJECT_group") - layout.itemM("VIEW3D_MT_OBJECT_constraints") + layout.itemM("VIEW3D_MT_object_parent") + layout.itemM("VIEW3D_MT_object_track") + layout.itemM("VIEW3D_MT_object_group") + layout.itemM("VIEW3D_MT_object_constraints") layout.itemS() @@ -430,9 +430,9 @@ class VIEW3D_MT_OBJECT(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_OBJECT_showhide") + layout.itemM("VIEW3D_MT_object_showhide") -class VIEW3D_MT_OBJECT_clear(bpy.types.Menu): +class VIEW3D_MT_object_clear(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Clear" @@ -444,7 +444,7 @@ class VIEW3D_MT_OBJECT_clear(bpy.types.Menu): layout.itemO("object.scale_clear", text="Scale") layout.itemO("object.origin_clear", text="Origin") -class VIEW3D_MT_OBJECT_parent(bpy.types.Menu): +class VIEW3D_MT_object_parent(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Parent" @@ -454,7 +454,7 @@ class VIEW3D_MT_OBJECT_parent(bpy.types.Menu): layout.itemO("object.parent_set", text="Set") layout.itemO("object.parent_clear", text="Clear") -class VIEW3D_MT_OBJECT_track(bpy.types.Menu): +class VIEW3D_MT_object_track(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Track" @@ -464,7 +464,7 @@ class VIEW3D_MT_OBJECT_track(bpy.types.Menu): layout.itemO("object.track_set", text="Set") layout.itemO("object.track_clear", text="Clear") -class VIEW3D_MT_OBJECT_group(bpy.types.Menu): +class VIEW3D_MT_object_group(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Group" @@ -479,7 +479,7 @@ class VIEW3D_MT_OBJECT_group(bpy.types.Menu): layout.itemO("group.objects_add_active") layout.itemO("group.objects_remove_active") -class VIEW3D_MT_OBJECT_constraints(bpy.types.Menu): +class VIEW3D_MT_object_constraints(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Constraints" @@ -489,7 +489,7 @@ class VIEW3D_MT_OBJECT_constraints(bpy.types.Menu): layout.itemO("object.constraint_add_with_targets") layout.itemO("object.constraints_clear") -class VIEW3D_MT_OBJECT_showhide(bpy.types.Menu): +class VIEW3D_MT_object_showhide(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" @@ -502,7 +502,7 @@ class VIEW3D_MT_OBJECT_showhide(bpy.types.Menu): # ********** Vertex paint menu ********** -class VIEW3D_MT_PAINT_VERTEX(bpy.types.Menu): +class VIEW3D_MT_paint_vertex(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Paint" @@ -517,7 +517,7 @@ class VIEW3D_MT_PAINT_VERTEX(bpy.types.Menu): # ********** Sculpt menu ********** -class VIEW3D_MT_SCULPT(bpy.types.Menu): +class VIEW3D_MT_sculpt(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Sculpt" @@ -553,7 +553,7 @@ class VIEW3D_MT_SCULPT(bpy.types.Menu): # ********** Particle menu ********** -class VIEW3D_MT_PARTICLE(bpy.types.Menu): +class VIEW3D_MT_particle(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Particle" @@ -576,14 +576,14 @@ class VIEW3D_MT_PARTICLE(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_PARTICLE_showhide") + layout.itemM("VIEW3D_MT_particle_showhide") -class VIEW3D_MT_PARTICLE_showhide(VIEW3D_MT_showhide): +class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide): _operator_name = "particle" # ********** Pose Menu ********** -class VIEW3D_MT_POSE(bpy.types.Menu): +class VIEW3D_MT_pose(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Pose" @@ -595,7 +595,7 @@ class VIEW3D_MT_POSE(bpy.types.Menu): if arm.drawtype in ('BBONE', 'ENVELOPE'): layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale Envelope Distance") - layout.itemM("VIEW3D_MT_POSE_transform") + layout.itemM("VIEW3D_MT_pose_transform") layout.itemS() @@ -614,14 +614,14 @@ class VIEW3D_MT_POSE(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_POSE_pose") - layout.itemM("VIEW3D_MT_POSE_motion") - layout.itemM("VIEW3D_MT_POSE_group") + layout.itemM("VIEW3D_MT_pose_pose") + layout.itemM("VIEW3D_MT_pose_motion") + layout.itemM("VIEW3D_MT_pose_group") layout.itemS() - layout.itemM("VIEW3D_MT_POSE_ik") - layout.itemM("VIEW3D_MT_POSE_constraints") + layout.itemM("VIEW3D_MT_pose_ik") + layout.itemM("VIEW3D_MT_pose_constraints") layout.itemS() @@ -640,10 +640,10 @@ class VIEW3D_MT_POSE(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_POSE_showhide") + layout.itemM("VIEW3D_MT_pose_showhide") layout.item_menu_enumO("pose.flags_set", 'mode', text="Bone Settings") -class VIEW3D_MT_POSE_transform(bpy.types.Menu): +class VIEW3D_MT_pose_transform(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Clear Transform" @@ -658,7 +658,7 @@ class VIEW3D_MT_POSE_transform(bpy.types.Menu): layout.itemL(text="Origin") -class VIEW3D_MT_POSE_pose(bpy.types.Menu): +class VIEW3D_MT_pose_pose(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Pose Library" @@ -673,7 +673,7 @@ class VIEW3D_MT_POSE_pose(bpy.types.Menu): layout.itemO("poselib.pose_rename", text="Rename Pose...") layout.itemO("poselib.pose_remove", text="Remove Pose...") -class VIEW3D_MT_POSE_motion(bpy.types.Menu): +class VIEW3D_MT_pose_motion(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Motion Paths" @@ -683,7 +683,7 @@ class VIEW3D_MT_POSE_motion(bpy.types.Menu): layout.itemO("pose.paths_calculate", text="Calculate") layout.itemO("pose.paths_clear", text="Clear") -class VIEW3D_MT_POSE_group(bpy.types.Menu): +class VIEW3D_MT_pose_group(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Bone Groups" @@ -698,7 +698,7 @@ class VIEW3D_MT_POSE_group(bpy.types.Menu): layout.itemO("pose.group_unassign") -class VIEW3D_MT_POSE_ik(bpy.types.Menu): +class VIEW3D_MT_pose_ik(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Inverse Kinematics" @@ -708,7 +708,7 @@ class VIEW3D_MT_POSE_ik(bpy.types.Menu): layout.itemO("pose.ik_add") layout.itemO("pose.ik_clear") -class VIEW3D_MT_POSE_constraints(bpy.types.Menu): +class VIEW3D_MT_pose_constraints(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Constraints" @@ -718,13 +718,13 @@ class VIEW3D_MT_POSE_constraints(bpy.types.Menu): layout.itemO("pose.constraint_add_with_targets", text="Add (With Targets)...") layout.itemO("pose.constraints_clear") -class VIEW3D_MT_POSE_showhide(VIEW3D_MT_showhide): +class VIEW3D_MT_pose_showhide(VIEW3D_MT_showhide): _operator_name = "pose" # ********** Edit Menus, suffix from ob.type ********** # Edit MESH -class VIEW3D_MT_edit_MESH(bpy.types.Menu): +class VIEW3D_MT_edit_mesh(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Mesh" @@ -752,10 +752,10 @@ class VIEW3D_MT_edit_MESH(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_edit_MESH_vertices") - layout.itemM("VIEW3D_MT_edit_MESH_edges") - layout.itemM("VIEW3D_MT_edit_MESH_faces") - layout.itemM("VIEW3D_MT_edit_MESH_normals") + layout.itemM("VIEW3D_MT_edit_mesh_vertices") + layout.itemM("VIEW3D_MT_edit_mesh_edges") + layout.itemM("VIEW3D_MT_edit_mesh_faces") + layout.itemM("VIEW3D_MT_edit_mesh_normals") layout.itemS() @@ -765,9 +765,9 @@ class VIEW3D_MT_edit_MESH(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_edit_MESH_showhide") + layout.itemM("VIEW3D_MT_edit_mesh_showhide") -class VIEW3D_MT_edit_MESH_vertices(bpy.types.Menu): +class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Vertices" @@ -784,7 +784,7 @@ class VIEW3D_MT_edit_MESH_vertices(bpy.types.Menu): layout.itemO("mesh.vertices_smooth") layout.itemO("mesh.remove_doubles") -class VIEW3D_MT_edit_MESH_edges(bpy.types.Menu): +class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Edges" @@ -809,7 +809,7 @@ class VIEW3D_MT_edit_MESH_edges(bpy.types.Menu): layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW") layout.item_enumO("mesh.edge_rotate", "direction", 'CCW', text="Rotate Edge CCW") -class VIEW3D_MT_edit_MESH_faces(bpy.types.Menu): +class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Faces" @@ -831,7 +831,7 @@ class VIEW3D_MT_edit_MESH_faces(bpy.types.Menu): layout.itemO("mesh.faces_shade_smooth") layout.itemO("mesh.faces_shade_flat") -class VIEW3D_MT_edit_MESH_normals(bpy.types.Menu): +class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Normals" @@ -845,13 +845,13 @@ class VIEW3D_MT_edit_MESH_normals(bpy.types.Menu): layout.itemO("mesh.flip_normals") -class VIEW3D_MT_edit_MESH_showhide(VIEW3D_MT_showhide): +class VIEW3D_MT_edit_mesh_showhide(VIEW3D_MT_showhide): _operator_name = "mesh" -# Edit CURVE +# Edit Curve -# draw_CURVE is used by VIEW3D_MT_edit_CURVE and VIEW3D_MT_edit_SURFACE -def draw_CURVE(self, context): +# draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface +def draw_curve(self, context): layout = self.layout settings = context.tool_settings @@ -869,8 +869,8 @@ def draw_CURVE(self, context): layout.itemS() - layout.itemM("VIEW3D_MT_edit_CURVE_ctrlpoints") - layout.itemM("VIEW3D_MT_edit_CURVE_segments") + layout.itemM("VIEW3D_MT_edit_curve_ctrlpoints") + layout.itemM("VIEW3D_MT_edit_curve_segments") layout.itemS() @@ -879,15 +879,15 @@ def draw_CURVE(self, context): layout.itemS() - layout.itemM("VIEW3D_MT_edit_CURVE_showhide") + layout.itemM("VIEW3D_MT_edit_curve_showhide") -class VIEW3D_MT_edit_CURVE(bpy.types.Menu): +class VIEW3D_MT_edit_curve(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Curve" - draw = draw_CURVE + draw = draw_curve -class VIEW3D_MT_edit_CURVE_ctrlpoints(bpy.types.Menu): +class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Control Points" @@ -905,7 +905,7 @@ class VIEW3D_MT_edit_CURVE_ctrlpoints(bpy.types.Menu): layout.item_menu_enumO("curve.handle_type_set", "type") -class VIEW3D_MT_edit_CURVE_segments(bpy.types.Menu): +class VIEW3D_MT_edit_curve_segments(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Segments" @@ -915,18 +915,18 @@ class VIEW3D_MT_edit_CURVE_segments(bpy.types.Menu): layout.itemO("curve.subdivide") layout.itemO("curve.switch_direction") -class VIEW3D_MT_edit_CURVE_showhide(VIEW3D_MT_showhide): +class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide): _operator_name = "curve" # Edit SURFACE -class VIEW3D_MT_edit_SURFACE(bpy.types.Menu): +class VIEW3D_MT_edit_surface(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Surface" - draw = draw_CURVE + draw = draw_curve # Edit TEXT -class VIEW3D_MT_edit_TEXT(bpy.types.Menu): +class VIEW3D_MT_edit_text(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Text" @@ -937,9 +937,9 @@ class VIEW3D_MT_edit_TEXT(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_edit_TEXT_chars") + layout.itemm("view3d_mt_edit_text_chars") -class VIEW3D_MT_edit_TEXT_chars(bpy.types.Menu): +class VIEW3D_MT_edit_text_chars(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Special Characters" @@ -974,7 +974,7 @@ class VIEW3D_MT_edit_TEXT_chars(bpy.types.Menu): layout.item_stringO("font.text_insert", "text", b'\xC2\xA1'.decode(), text="Spanish Exclamation Mark|Alt !") # Edit META -class VIEW3D_MT_edit_META(bpy.types.Menu): +class VIEW3D_MT_edit_meta(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Metaball" @@ -1002,9 +1002,9 @@ class VIEW3D_MT_edit_META(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_edit_META_showhide") + layout.itemM("VIEW3D_MT_edit_meta_showhide") -class VIEW3D_MT_edit_META_showhide(bpy.types.Menu): +class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" @@ -1016,7 +1016,7 @@ class VIEW3D_MT_edit_META_showhide(bpy.types.Menu): layout.item_booleanO("mball.hide_metaelems", "unselected", True, text="Hide Unselected") # Edit LATTICE -class VIEW3D_MT_edit_LATTICE(bpy.types.Menu): +class VIEW3D_MT_edit_lattice(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Lattice" @@ -1037,7 +1037,7 @@ class VIEW3D_MT_edit_LATTICE(bpy.types.Menu): layout.item_menu_enumR(settings, "proportional_editing_falloff") # Edit ARMATURE -class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu): +class VIEW3D_MT_edit_armature(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Armature" @@ -1048,7 +1048,7 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu): arm = edit_object.data layout.itemM("VIEW3D_MT_snap") - layout.itemM("VIEW3D_MT_edit_ARMATURE_roll") + layout.itemM("VIEW3D_MT_edit_armature_roll") if arm.drawtype == 'ENVELOPE': layout.item_enumO("tfm.transform", "mode", 'BONESIZE', text="Scale Envelope Distance") @@ -1088,13 +1088,13 @@ class VIEW3D_MT_edit_ARMATURE(bpy.types.Menu): layout.itemS() - layout.itemM("VIEW3D_MT_edit_ARMATURE_parent") + layout.itemM("VIEW3D_MT_edit_armature_parent") layout.itemS() layout.item_menu_enumO("armature.flags_set", "mode", text="Bone Settings") -class VIEW3D_MT_edit_ARMATURE_parent(bpy.types.Menu): +class VIEW3D_MT_edit_armature_parent(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Parent" @@ -1104,7 +1104,7 @@ class VIEW3D_MT_edit_ARMATURE_parent(bpy.types.Menu): layout.itemO("armature.parent_set", text="Make") layout.itemO("armature.parent_clear", text="Clear") -class VIEW3D_MT_edit_ARMATURE_roll(bpy.types.Menu): +class VIEW3D_MT_edit_armature_roll(bpy.types.Menu): __space_type__ = 'VIEW_3D' __label__ = "Bone Roll" @@ -1285,68 +1285,68 @@ bpy.types.register(VIEW3D_MT_view_navigation) bpy.types.register(VIEW3D_MT_view_align) bpy.types.register(VIEW3D_MT_view_cameras) -bpy.types.register(VIEW3D_MT_select_OBJECT) # Select Menus -bpy.types.register(VIEW3D_MT_select_POSE) -bpy.types.register(VIEW3D_MT_select_PARTICLE) -bpy.types.register(VIEW3D_MT_select_EDIT_MESH) -bpy.types.register(VIEW3D_MT_select_EDIT_CURVE) -bpy.types.register(VIEW3D_MT_select_EDIT_SURFACE) -bpy.types.register(VIEW3D_MT_select_EDIT_METABALL) -bpy.types.register(VIEW3D_MT_select_EDIT_LATTICE) -bpy.types.register(VIEW3D_MT_select_EDIT_ARMATURE) -bpy.types.register(VIEW3D_MT_select_FACE) # XXX todo - -bpy.types.register(VIEW3D_MT_OBJECT) # Object Menu -bpy.types.register(VIEW3D_MT_OBJECT_clear) -bpy.types.register(VIEW3D_MT_OBJECT_parent) -bpy.types.register(VIEW3D_MT_OBJECT_track) -bpy.types.register(VIEW3D_MT_OBJECT_group) -bpy.types.register(VIEW3D_MT_OBJECT_constraints) -bpy.types.register(VIEW3D_MT_OBJECT_showhide) - -bpy.types.register(VIEW3D_MT_SCULPT) # Sculpt Menu - -bpy.types.register(VIEW3D_MT_PAINT_VERTEX) - -bpy.types.register(VIEW3D_MT_PARTICLE) # Particle Menu -bpy.types.register(VIEW3D_MT_PARTICLE_showhide) - -bpy.types.register(VIEW3D_MT_POSE) # POSE Menu -bpy.types.register(VIEW3D_MT_POSE_transform) -bpy.types.register(VIEW3D_MT_POSE_pose) -bpy.types.register(VIEW3D_MT_POSE_motion) -bpy.types.register(VIEW3D_MT_POSE_group) -bpy.types.register(VIEW3D_MT_POSE_ik) -bpy.types.register(VIEW3D_MT_POSE_constraints) -bpy.types.register(VIEW3D_MT_POSE_showhide) +bpy.types.register(VIEW3D_MT_select_object) # Select Menus +bpy.types.register(VIEW3D_MT_select_pose) +bpy.types.register(VIEW3D_MT_select_particle) +bpy.types.register(VIEW3D_MT_select_edit_mesh) +bpy.types.register(VIEW3D_MT_select_edit_curve) +bpy.types.register(VIEW3D_MT_select_edit_surface) +bpy.types.register(VIEW3D_MT_select_edit_metaball) +bpy.types.register(VIEW3D_MT_select_edit_lattice) +bpy.types.register(VIEW3D_MT_select_edit_armature) +bpy.types.register(VIEW3D_MT_select_face) # XXX todo + +bpy.types.register(VIEW3D_MT_object) # Object Menu +bpy.types.register(VIEW3D_MT_object_clear) +bpy.types.register(VIEW3D_MT_object_parent) +bpy.types.register(VIEW3D_MT_object_track) +bpy.types.register(VIEW3D_MT_object_group) +bpy.types.register(VIEW3D_MT_object_constraints) +bpy.types.register(VIEW3D_MT_object_showhide) + +bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu + +bpy.types.register(VIEW3D_MT_paint_vertex) + +bpy.types.register(VIEW3D_MT_particle) # Particle Menu +bpy.types.register(VIEW3D_MT_particle_showhide) + +bpy.types.register(VIEW3D_MT_pose) # POSE Menu +bpy.types.register(VIEW3D_MT_pose_transform) +bpy.types.register(VIEW3D_MT_pose_pose) +bpy.types.register(VIEW3D_MT_pose_motion) +bpy.types.register(VIEW3D_MT_pose_group) +bpy.types.register(VIEW3D_MT_pose_ik) +bpy.types.register(VIEW3D_MT_pose_constraints) +bpy.types.register(VIEW3D_MT_pose_showhide) bpy.types.register(VIEW3D_MT_snap) # Edit Menus -bpy.types.register(VIEW3D_MT_edit_MESH) -bpy.types.register(VIEW3D_MT_edit_MESH_vertices) -bpy.types.register(VIEW3D_MT_edit_MESH_edges) -bpy.types.register(VIEW3D_MT_edit_MESH_faces) -bpy.types.register(VIEW3D_MT_edit_MESH_normals) -bpy.types.register(VIEW3D_MT_edit_MESH_showhide) +bpy.types.register(VIEW3D_MT_edit_mesh) +bpy.types.register(VIEW3D_MT_edit_mesh_vertices) +bpy.types.register(VIEW3D_MT_edit_mesh_edges) +bpy.types.register(VIEW3D_MT_edit_mesh_faces) +bpy.types.register(VIEW3D_MT_edit_mesh_normals) +bpy.types.register(VIEW3D_MT_edit_mesh_showhide) -bpy.types.register(VIEW3D_MT_edit_CURVE) -bpy.types.register(VIEW3D_MT_edit_CURVE_ctrlpoints) -bpy.types.register(VIEW3D_MT_edit_CURVE_segments) -bpy.types.register(VIEW3D_MT_edit_CURVE_showhide) +bpy.types.register(VIEW3D_MT_edit_curve) +bpy.types.register(VIEW3D_MT_edit_curve_ctrlpoints) +bpy.types.register(VIEW3D_MT_edit_curve_segments) +bpy.types.register(VIEW3D_MT_edit_curve_showhide) -bpy.types.register(VIEW3D_MT_edit_SURFACE) +bpy.types.register(VIEW3D_MT_edit_surface) -bpy.types.register(VIEW3D_MT_edit_TEXT) -bpy.types.register(VIEW3D_MT_edit_TEXT_chars) +bpy.types.register(VIEW3D_MT_edit_text) +bpy.types.register(VIEW3D_MT_edit_text_chars) -bpy.types.register(VIEW3D_MT_edit_META) -bpy.types.register(VIEW3D_MT_edit_META_showhide) +bpy.types.register(VIEW3D_MT_edit_meta) +bpy.types.register(VIEW3D_MT_edit_meta_showhide) -bpy.types.register(VIEW3D_MT_edit_LATTICE) +bpy.types.register(VIEW3D_MT_edit_lattice) -bpy.types.register(VIEW3D_MT_edit_ARMATURE) -bpy.types.register(VIEW3D_MT_edit_ARMATURE_parent) -bpy.types.register(VIEW3D_MT_edit_ARMATURE_roll) +bpy.types.register(VIEW3D_MT_edit_armature) +bpy.types.register(VIEW3D_MT_edit_armature_parent) +bpy.types.register(VIEW3D_MT_edit_armature_roll) bpy.types.register(VIEW3D_PT_3dview_properties) # Panels bpy.types.register(VIEW3D_PT_3dview_display) -- cgit v1.2.3 From c8618348e0feab2f28d348b539b8a6420301be1f Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 15 Sep 2009 10:26:36 +0000 Subject: Smoke: * Less verbose * More OpenGL error messages (on blender -d) --- source/blender/blenkernel/intern/smoke.c | 16 ++++++++-------- source/blender/editors/space_view3d/drawvolume.c | 2 ++ source/blender/gpu/intern/gpu_extensions.c | 9 +++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 99d4176c937..1b6b4d4838e 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -167,7 +167,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive // calc other res with max_res provided VECSUB(size, max, min); - printf("size: %f, %f, %f\n", size[0], size[1], size[2]); + // printf("size: %f, %f, %f\n", size[0], size[1], size[2]); // prevent crash when initializing a plane as domain if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) @@ -212,7 +212,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive } } - printf("smd->domain->dx: %f\n", smd->domain->dx); + // printf("smd->domain->dx: %f\n", smd->domain->dx); // TODO: put in failsafe if res<=0 - dg @@ -228,8 +228,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1); smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1); smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1); - printf("smd->domain->amplify: %d\n", smd->domain->amplify); - printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n"); + // printf("smd->domain->amplify: %d\n", smd->domain->amplify); + // printf("(smd->domain->flags & MOD_SMOKE_HIGHRES)\n"); } if(!smd->domain->shadow) @@ -240,7 +240,7 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive if(smd->domain->wt) { smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength)); - printf("smoke_initWaveletBlenderRNA\n"); + // printf("smoke_initWaveletBlenderRNA\n"); } return 1; } @@ -624,7 +624,7 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smd->time = -1; - printf("reset domain end\n"); + // printf("reset domain end\n"); } else if(smd->flow) { @@ -1111,7 +1111,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM framenr = scene->r.cfra; - printf("time: %d\n", scene->r.cfra); + // printf("time: %d\n", scene->r.cfra); if(framenr == smd->time) return; @@ -1148,7 +1148,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM /* try to read from cache */ cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec); - printf("cache_result: %d\n", cache_result); + // printf("cache_result: %d\n", cache_result); if(cache_result == PTCACHE_READ_EXACT) { diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index a81174ff768..0bdc65b5461 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -347,6 +347,8 @@ void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture GPU_texture_bind(tex, 0); if(tex_shadow) GPU_texture_bind(tex_shadow, 1); + else + printf("No volume shadow\n"); if (!GLEW_ARB_texture_non_power_of_two) { cor[0] = (float)res[0]/(float)larger_pow2(res[0]); diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 4a31df04627..55e4b337a77 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -346,6 +346,8 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) tex->number = 0; glBindTexture(tex->target, tex->bindcode); + GPU_print_error("3D glBindTexture"); + type = GL_FLOAT; // GL_UNSIGNED_BYTE format = GL_RED; internalformat = GL_INTENSITY; @@ -355,16 +357,23 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, 0); + GPU_print_error("3D glTexImage3D"); + if (fpixels) { glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels); + GPU_print_error("3D glTexSubImage3D"); } + glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor); + GPU_print_error("3D GL_TEXTURE_BORDER_COLOR"); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + GPU_print_error("3D GL_LINEAR"); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); + GPU_print_error("3D GL_CLAMP_TO_BORDER"); if (pixels) MEM_freeN(pixels); -- cgit v1.2.3 From daa968df227438ea592fc0702f1e4727dfc9357d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Sep 2009 10:52:36 +0000 Subject: - opening the file selector was freeing a NULL pointer - some warnings in last commit. --- source/blender/editors/space_file/space_file.c | 6 ++++-- source/blender/python/intern/bpy_rna.c | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 47839ea0342..68eeb8718a2 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -156,8 +156,10 @@ static void file_free(SpaceLink *sl) static void file_init(struct wmWindowManager *wm, ScrArea *sa) { SpaceFile *sfile= (SpaceFile*)sa->spacedata.first; - MEM_freeN(sfile->params); - sfile->params = 0; + if(sfile->params) { + MEM_freeN(sfile->params); + sfile->params = 0; + } printf("file_init\n"); } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 820f96f1e81..c2335bea995 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1680,6 +1680,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) { /* Try get values from a collection */ PyObject *ret; + PyObject *iter; if(RNA_property_array_check(&self->ptr, self->prop)) { int len = pyrna_prop_array_length(self); @@ -1691,7 +1692,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i)); } } - else if (ret = pyrna_prop_values(self)) { + else if ((ret = pyrna_prop_values(self))) { /* do nothing */ } else { @@ -1701,7 +1702,7 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) /* we know this is a list so no need to PyIter_Check */ - PyObject *iter = PyObject_GetIter(ret); + iter = PyObject_GetIter(ret); Py_DECREF(ret); return iter; } -- cgit v1.2.3 From 8513ab471c0b2ae1e84f9b14e932e080a7fdd32c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Sep 2009 10:59:42 +0000 Subject: didnt change all filename's to path's --- release/io/export_ply.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release/io/export_ply.py b/release/io/export_ply.py index 7a3253b2d16..491ffe6b9df 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -256,10 +256,10 @@ class EXPORT_OT_ply(bpy.types.Operator): def execute(self, context): # print("Selected: " + context.active_object.name) - if not self.filename: + if not self.path: raise Exception("filename not set") - write(self.filename, context.scene, context.active_object,\ + write(self.path, context.scene, context.active_object,\ EXPORT_APPLY_MODIFIERS = self.use_modifiers, EXPORT_NORMALS = self.use_normals, EXPORT_UV = self.use_uvs, @@ -277,6 +277,6 @@ class EXPORT_OT_ply(bpy.types.Operator): bpy.ops.add(EXPORT_OT_ply) if __name__ == "__main__": - bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply") + bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply") -- cgit v1.2.3 From 499e6f0067ff629fcc7705e5552d5d35ff587ab3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 15 Sep 2009 11:35:10 +0000 Subject: 2.5: node group/ungroup/edit operators, patch by Michal Ziulek, with some small changes. --- release/ui/space_node.py | 9 +- source/blender/editors/space_node/node_draw.c | 2 +- source/blender/editors/space_node/node_edit.c | 234 ++++++++++++++++-------- source/blender/editors/space_node/node_intern.h | 5 +- source/blender/editors/space_node/node_ops.c | 7 + 5 files changed, 169 insertions(+), 88 deletions(-) diff --git a/release/ui/space_node.py b/release/ui/space_node.py index 55b2065084b..b32e6a9f61a 100644 --- a/release/ui/space_node.py +++ b/release/ui/space_node.py @@ -98,11 +98,10 @@ class NODE_MT_node(bpy.types.Menu): # XXX # layout.itemS() # layout.itemO("node.make_link") - # layout.itemS() - # layout.itemO("node.edit_group") - # layout.itemO("node.ungroup") - # layout.itemO("node.group") - # layout.itemO("node.make_link") + layout.itemS() + layout.itemO("node.group_edit") + layout.itemO("node.group_ungroup") + layout.itemO("node.group_make") layout.itemS() diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index f3df7a29c2e..a872413b4e1 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -601,7 +601,7 @@ static void do_node_internal_buttons(bContext *C, void *node_v, int event) //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); } else { - node= snode_get_editgroup(snode); + node= node_tree_get_editgroup(snode->nodetree); if(node) NodeTagIDChanged(snode->nodetree, node->id); } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 159a4036914..4fd6995b8fd 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -58,6 +58,7 @@ #include "BKE_material.h" #include "BKE_paint.h" #include "BKE_texture.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_utildefines.h" @@ -84,6 +85,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "UI_interface.h" #include "UI_view2d.h" #include "node_intern.h" @@ -327,12 +329,12 @@ static void set_node_imagepath(char *str) /* called from fileselect */ #endif /* 0 */ -bNode *snode_get_editgroup(SpaceNode *snode) +bNode *node_tree_get_editgroup(bNodeTree *nodetree) { bNode *gnode; /* get the groupnode */ - for(gnode= snode->nodetree->nodes.first; gnode; gnode= gnode->next) + for(gnode= nodetree->nodes.first; gnode; gnode= gnode->next) if(gnode->flag & NODE_GROUP_EDIT) break; return gnode; @@ -441,7 +443,7 @@ static void composit_node_event(SpaceNode *snode, short event) addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); } else { - node= snode_get_editgroup(snode); + node= node_tree_get_editgroup(snode->nodetree); if(node) NodeTagIDChanged(snode->nodetree, node->id); @@ -722,7 +724,7 @@ void node_set_active(SpaceNode *snode, bNode *node) NodeTagChanged(snode->edittree, node); /* if inside group, tag entire group */ - gnode= snode_get_editgroup(snode); + gnode= node_tree_get_editgroup(snode->nodetree); if(gnode) NodeTagIDChanged(snode->nodetree, gnode->id); @@ -753,6 +755,8 @@ void node_set_active(SpaceNode *snode, bNode *node) #endif /* 0 */ } +/* ***************** Edit Group operator ************* */ + void snode_make_group_editable(SpaceNode *snode, bNode *gnode) { bNode *node; @@ -768,12 +772,9 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode) } if(gnode && gnode->type==NODE_GROUP && gnode->id) { - if(gnode->id->lib) { - // XXX if(okee("Make Group Local")) - // ntreeMakeLocal((bNodeTree *)gnode->id); - // else - return; - } + if(gnode->id->lib) + ntreeMakeLocal((bNodeTree *)gnode->id); + gnode->flag |= NODE_GROUP_EDIT; snode->edittree= (bNodeTree *)gnode->id; @@ -794,43 +795,102 @@ void snode_make_group_editable(SpaceNode *snode, bNode *gnode) // XXX BIF_preview_changed(-1); /* temp hack to force texture preview to update */ } +} + +static int node_group_edit_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + + gnode= nodeGetActive(snode->edittree); + snode_make_group_editable(snode, gnode); + + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + + return OPERATOR_FINISHED; +} + +static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *gnode; + + gnode= nodeGetActive(snode->edittree); + if(gnode && gnode->type==NODE_GROUP && gnode->id && gnode->id->lib) { + uiPupMenuOkee(C, op->type->idname, "Make group local?"); + return OPERATOR_CANCELLED; + } + + return node_group_edit_exec(C, op); +} + +void NODE_OT_group_edit(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Edit Group"; + ot->description = "Edit node group."; + ot->idname = "NODE_OT_group_edit"; - // allqueue(REDRAWNODE, 0); + /* api callbacks */ + ot->invoke = node_group_edit_invoke; + ot->exec = node_group_edit_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } -#if 0 +/* ******************** Ungroup operator ********************** */ -void node_ungroup(SpaceNode *snode) +static int node_group_ungroup_exec(bContext *C, wmOperator *op) { + SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; /* are we inside of a group? */ - gnode= snode_get_editgroup(snode); + gnode= node_tree_get_editgroup(snode->nodetree); if(gnode) snode_make_group_editable(snode, NULL); gnode= nodeGetActive(snode->edittree); - if(gnode==NULL) return; + if(gnode==NULL) + return OPERATOR_CANCELLED; - if(gnode->type!=NODE_GROUP) - error("Not a group"); - else { - if(nodeGroupUnGroup(snode->edittree, gnode)) { - - // allqueue(REDRAWNODE, 0); - } - else - error("Can't ungroup"); + if(gnode->type!=NODE_GROUP) { + BKE_report(op->reports, RPT_ERROR, "Not a group"); + return OPERATOR_CANCELLED; + } + else if(!nodeGroupUnGroup(snode->edittree, gnode)) { + BKE_report(op->reports, RPT_ERROR, "Can't ungroup"); + return OPERATOR_CANCELLED; } + + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_ungroup(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Ungroup"; + ot->description = "Ungroup selected nodes."; + ot->idname = "NODE_OT_group_ungroup"; + + /* api callbacks */ + ot->exec = node_group_ungroup_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } -#endif /* 0 */ /* when links in groups change, inputs/outputs change, nodes added/deleted... */ -static void snode_verify_groups(SpaceNode *snode) +static void node_tree_verify_groups(bNodeTree *nodetree) { bNode *gnode; - gnode= snode_get_editgroup(snode); + gnode= node_tree_get_editgroup(nodetree); /* does all materials */ if(gnode) @@ -1263,7 +1323,7 @@ static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node) sock->flag &= ~SOCK_HIDDEN; } else { - bNode *gnode= snode_get_editgroup(snode); + bNode *gnode= node_tree_get_editgroup(snode->nodetree); /* hiding inside group should not break links in other group users */ if(gnode) { @@ -1291,7 +1351,7 @@ static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node) } // allqueue(REDRAWNODE, 1); - snode_verify_groups(snode); + node_tree_verify_groups(snode->nodetree); } @@ -1418,7 +1478,7 @@ void node_active_link_viewer(SpaceNode *snode) float mx=0, my=0; // XXX short mval[2]; - gnode= snode_get_editgroup(snode); + gnode= node_tree_get_editgroup(snode->nodetree); if(gnode==NULL) return 0; // XXX getmouseco_areawin(mval); @@ -1618,13 +1678,13 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float node->locy= locy + 60.0f; // arbitrary.. so its visible node->flag |= SELECT; - gnode= snode_get_editgroup(snode); + gnode= node_tree_get_editgroup(snode->nodetree); if(gnode) { node->locx -= gnode->locx; node->locy -= gnode->locy; } - snode_verify_groups(snode); + node_tree_verify_groups(snode->nodetree); node_set_active(snode, node); if(snode->nodetree->type==NTREE_COMPOSIT) { @@ -1654,7 +1714,7 @@ void node_mute(SpaceNode *snode) bNode *node; /* no disabling inside of groups */ - if(snode_get_editgroup(snode)) + if(node_tree_get_editgroup(snode->nodetree)) return; for(node= snode->edittree->nodes.first; node; node= node->next) { @@ -1680,7 +1740,7 @@ int node_duplicate_exec(bContext *C, wmOperator *op) ntreeCopyTree(snode->edittree, 1); /* 1 == internally selected nodes */ ntreeSolveOrder(snode->edittree); - snode_verify_groups(snode); + node_tree_verify_groups(snode->nodetree); snode_handle_recalc(C, snode); return OPERATOR_FINISHED; @@ -1891,7 +1951,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) } ntreeSolveOrder(snode->edittree); - snode_verify_groups(snode); + node_tree_verify_groups(snode->nodetree); snode_handle_recalc(C, snode); MEM_freeN(op->customdata); @@ -2000,35 +2060,6 @@ void NODE_OT_link(wmOperatorType *ot) } -void node_delete(SpaceNode *snode) -{ - bNode *node, *next; - bNodeSocket *sock; - - for(node= snode->edittree->nodes.first; node; node= next) { - next= node->next; - if(node->flag & SELECT) { - /* set selin and selout NULL if the sockets belong to a node to be deleted */ - for(sock= node->inputs.first; sock; sock= sock->next) - if(snode->edittree->selin == sock) snode->edittree->selin= NULL; - - for(sock= node->outputs.first; sock; sock= sock->next) - if(snode->edittree->selout == sock) snode->edittree->selout= NULL; - - /* check id user here, nodeFreeNode is called for free dbase too */ - if(node->id) - node->id->us--; - nodeFreeNode(snode->edittree, node); - } - } - - snode_verify_groups(snode); - // NODE_FIX_ME - // snode_handle_recalc(snode); - // allqueue(REDRAWNODE, 1); -} - - void node_hide(SpaceNode *snode) { bNode *node; @@ -2098,7 +2129,7 @@ void node_make_link(SpaceNode *snode) else return; ntreeSolveOrder(snode->edittree); - snode_verify_groups(snode); + node_tree_verify_groups(snode->nodetree); // XXX snode_handle_recalc(snode); } @@ -2153,7 +2184,7 @@ static int cut_links_exec(bContext *C, wmOperator *op) } ntreeSolveOrder(snode->edittree); - snode_verify_groups(snode); + node_tree_verify_groups(snode->nodetree); snode_handle_recalc(C, snode); return OPERATOR_FINISHED; @@ -2253,15 +2284,16 @@ void imagepaint_composite_tags(bNodeTree *ntree, Image *image, ImageUser *iuser) } } -/* ********************** */ +/* ****************** Make Group operator ******************* */ -void node_make_group(SpaceNode *snode) +static int node_group_make_exec(bContext *C, wmOperator *op) { + SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; if(snode->edittree!=snode->nodetree) { -// XXX error("Can not add a new Group in a Group"); - return; + BKE_report(op->reports, RPT_ERROR, "Can not add a new Group in a Group"); + return OPERATOR_CANCELLED; } /* for time being... is too complex to handle */ @@ -2271,20 +2303,39 @@ void node_make_group(SpaceNode *snode) if(gnode->type==CMP_NODE_R_LAYERS) break; } + if(gnode) { -// XXX error("Can not add RenderLayer in a Group"); - return; + BKE_report(op->reports, RPT_ERROR, "Can not add RenderLayer in a Group"); + return OPERATOR_CANCELLED; } } gnode= nodeMakeGroupFromSelected(snode->nodetree); if(gnode==NULL) { -// XXX error("Can not make Group"); + BKE_report(op->reports, RPT_ERROR, "Can not make Group"); + return OPERATOR_CANCELLED; } else { nodeSetActive(snode->nodetree, gnode); ntreeSolveOrder(snode->nodetree); } + + return OPERATOR_FINISHED; +} + +void NODE_OT_group_make(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Group"; + ot->description = "Make group from selected nodes."; + ot->idname = "NODE_OT_group_make"; + + /* api callbacks */ + ot->exec = node_group_make_exec; + ot->poll = ED_operator_node_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } #if 0 @@ -2498,29 +2549,50 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) } #endif -static int node_delete_selection_exec(bContext *C, wmOperator *op) +/* ****************** Delete operator ******************* */ + +static int node_delete_exec(bContext *C, wmOperator *op) { SpaceNode *snode= CTX_wm_space_node(C); - ARegion *ar= CTX_wm_region(C); + bNode *node, *next; + bNodeSocket *sock; + + for(node= snode->edittree->nodes.first; node; node= next) { + next= node->next; + if(node->flag & SELECT) { + /* set selin and selout NULL if the sockets belong to a node to be deleted */ + for(sock= node->inputs.first; sock; sock= sock->next) + if(snode->edittree->selin == sock) snode->edittree->selin= NULL; + + for(sock= node->outputs.first; sock; sock= sock->next) + if(snode->edittree->selout == sock) snode->edittree->selout= NULL; + + /* check id user here, nodeFreeNode is called for free dbase too */ + if(node->id) + node->id->us--; + nodeFreeNode(snode->edittree, node); + } + } - node_delete(snode); - ED_region_tag_redraw(ar); + node_tree_verify_groups(snode->nodetree); + + // NODE_FIX_ME + // snode_handle_recalc(snode); + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); /* Do we need to pass the scene? */ return OPERATOR_FINISHED; } -/* operators */ - void NODE_OT_delete(wmOperatorType *ot) { - /* identifiers */ ot->name= "Delete"; + ot->description = "Delete selected nodes."; ot->idname= "NODE_OT_delete"; /* api callbacks */ - ot->exec= node_delete_selection_exec; + ot->exec= node_delete_exec; ot->poll= ED_operator_node_active; /* flags */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 6fdaeca7701..2a929472c68 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -81,7 +81,7 @@ void snode_home(ScrArea *sa, ARegion *ar, SpaceNode *snode); void node_set_active(SpaceNode *snode, bNode *node); void node_deselectall(SpaceNode *snode); void snode_composite_job(const struct bContext *C, ScrArea *sa); -bNode *snode_get_editgroup(SpaceNode *snode); +bNode *node_tree_get_editgroup(bNodeTree *ntree); void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag); void NODE_OT_duplicate(struct wmOperatorType *ot); @@ -89,6 +89,9 @@ void NODE_OT_link(struct wmOperatorType *ot); void NODE_OT_delete(struct wmOperatorType *ot); void NODE_OT_resize(struct wmOperatorType *ot); void NODE_OT_links_cut(struct wmOperatorType *ot); +void NODE_OT_group_make(struct wmOperatorType *ot); +void NODE_OT_group_ungroup(struct wmOperatorType *ot); +void NODE_OT_group_edit(struct wmOperatorType *ot); // XXXXXX diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index af857d57634..a10cabfa983 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -62,6 +62,9 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_resize); WM_operatortype_append(NODE_OT_links_cut); WM_operatortype_append(NODE_OT_duplicate); + WM_operatortype_append(NODE_OT_group_make); + WM_operatortype_append(NODE_OT_group_ungroup); + WM_operatortype_append(NODE_OT_group_edit); } void node_keymap(struct wmWindowManager *wm) @@ -88,6 +91,10 @@ void node_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "NODE_OT_select_all", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_select_linked_to", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_select_linked_from", LKEY, KM_PRESS, 0, 0); + + 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_edit", TABKEY, KM_PRESS, 0, 0); transform_keymap_for_space(wm, keymap, SPACE_NODE); } -- cgit v1.2.3 From e6b5a2e99ee1e7bb7cb13526ba7e126ebcd0649d Mon Sep 17 00:00:00 2001 From: William Reynish Date: Tue, 15 Sep 2009 12:45:05 +0000 Subject: UI tweaks *Cleaned up Transform panel in n-key area. It's now single column so that this view can be nice and slim, while you can still access everything. This is especially important in edit mode where you cannot change the transform values numerically from the Properties. Transform properties don't seem to work for Metaball edit yet, so wasn't able to test this *Removed some lingering tools in curve transform and put them in the toolbar instead. *Improved alignment in toolbar *Made Image Properties use regular checkmark toggle buttons *Added Delete as an alternative to X key, as it was in 2.4x --- release/ui/space_view3d.py | 15 +- release/ui/space_view3d_toolbar.py | 120 ++++----- source/blender/editors/metaball/mball_ops.c | 1 + source/blender/editors/object/object_ops.c | 3 +- source/blender/editors/space_image/image_buttons.c | 14 +- source/blender/editors/space_node/node_ops.c | 1 + source/blender/editors/space_view3d/space_view3d.c | 2 +- .../blender/editors/space_view3d/view3d_buttons.c | 279 +++++++++++---------- 8 files changed, 219 insertions(+), 216 deletions(-) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 33f9fbb853d..62b7fa0d91f 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -1136,16 +1136,17 @@ class VIEW3D_PT_3dview_properties(bpy.types.Panel): scene = context.scene col = layout.column() - col.itemR(view, "camera") + col.itemL(text="Camera:") + col.itemR(view, "camera", text="") col.itemR(view, "lens") - layout.itemL(text="Clip:") col = layout.column(align=True) + col.itemL(text="Clip:") col.itemR(view, "clip_start", text="Start") col.itemR(view, "clip_end", text="End") - layout.itemL(text="Grid:") col = layout.column(align=True) + col.itemL(text="Grid:") col.itemR(view, "grid_lines", text="Lines") col.itemR(view, "grid_spacing", text="Spacing") col.itemR(view, "grid_subdivisions", text="Subdivisions") @@ -1156,7 +1157,8 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel): __space_type__ = 'VIEW_3D' __region_type__ = 'UI' __label__ = "Display" - + __default_closed__ = True + def poll(self, context): view = context.space_data return (view) @@ -1177,7 +1179,7 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel): layout.itemS() - layout.itemO("screen.region_foursplit") + layout.itemO("screen.region_foursplit", text="Toggle Quad View") col = layout.column() col.itemR(view, "lock_rotation") @@ -1272,9 +1274,10 @@ class VIEW3D_PT_background_image(bpy.types.Panel): #col.itemR(bg, "image_user") col.itemR(bg, "size") col.itemR(bg, "transparency", slider=True) - col.itemL(text="Offset:") + col = layout.column(align=True) + col.itemL(text="Offset:") col.itemR(bg, "offset_x", text="X") col.itemR(bg, "offset_y", text="Y") diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 40ebb6883f0..fe0f4ca5a21 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -14,36 +14,32 @@ class VIEW3D_PT_tools_objectmode(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") - col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - layout.itemL(text="Object:") - col = layout.column(align=True) + col.itemL(text="Object:") col.itemO("object.duplicate") col.itemO("object.delete") active_object= context.active_object if active_object and active_object.type == 'MESH': - layout.itemL(text="Shading:") - + col = layout.column(align=True) + col.itemL(text="Shading:") col.itemO("object.shade_smooth", text="Smooth") col.itemO("object.shade_flat", text="Flat") - layout.itemL(text="Keyframes:") - col = layout.column(align=True) + col.itemL(text="Keyframes:") col.itemO("anim.insert_keyframe_menu", text="Insert") col.itemO("anim.delete_keyframe_v3d", text="Remove") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -57,43 +53,37 @@ class VIEW3D_PT_tools_meshedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") - col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - layout.itemL(text="Mesh:") - col = layout.column(align=True) + col.itemL(text="Mesh:") col.itemO("mesh.duplicate") col.itemO("mesh.delete") - layout.itemL(text="Modeling:") - col = layout.column(align=True) + col.itemL(text="Modeling:") col.itemO("mesh.extrude") col.itemO("mesh.subdivide") col.itemO("mesh.spin") col.itemO("mesh.screw") - layout.itemL(text="Shading:") - col = layout.column(align=True) + col.itemL(text="Shading:") col.itemO("mesh.faces_shade_smooth", text="Smooth") col.itemO("mesh.faces_shade_flat", text="Flat") - layout.itemL(text="UV Mapping:") - col = layout.column(align=True) + col.itemL(text="UV Mapping:") col.itemO("uv.mapping_menu", text="Unwrap") col.itemO("mesh.uvs_rotate") col.itemO("mesh.uvs_mirror") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -107,31 +97,34 @@ class VIEW3D_PT_tools_curveedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") - col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - - layout.itemL(text="Curve:") col = layout.column(align=True) + col.itemL(text="Curve:") col.itemO("curve.duplicate") col.itemO("curve.delete") col.itemO("curve.cyclic_toggle") col.itemO("curve.switch_direction") col.itemO("curve.spline_type_set") - layout.itemL(text="Modeling:") - col = layout.column(align=True) + col.itemL(text="Handles:") + col.item_enumO("curve.handle_type_set", "type", 'AUTOMATIC') + col.item_enumO("curve.handle_type_set", "type", 'VECTOR') + col.item_enumO("curve.handle_type_set", "type", 'ALIGN') + col.item_enumO("curve.handle_type_set", "type", 'FREE_ALIGN') + + col = layout.column(align=True) + col.itemL(text="Modeling:") col.itemO("curve.extrude") col.itemO("curve.subdivide") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -145,30 +138,26 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") - col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - layout.itemL(text="Curve:") - col = layout.column(align=True) + col.itemL(text="Curve:") col.itemO("curve.duplicate") col.itemO("curve.delete") col.itemO("curve.cyclic_toggle") col.itemO("curve.switch_direction") - layout.itemL(text="Modeling:") - col = layout.column(align=True) + col.itemL(text="Modeling:") col.itemO("curve.extrude") col.itemO("curve.subdivide") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -182,22 +171,21 @@ class VIEW3D_PT_tools_textedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Text Edit:") + col = layout.column(align=True) + col.itemL(text="Text Edit:") col.itemO("font.text_copy", text="Copy") col.itemO("font.text_cut", text="Cut") col.itemO("font.text_paste", text="Paste") - layout.itemL(text="Style:") - col = layout.column(align=True) + col.itemL(text="Style:") col.itemO("font.case_set") col.itemO("font.style_toggle") - - layout.itemL(text="Repeat:") - + col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -211,26 +199,26 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") + col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - - layout.itemL(text="Bones:") col = layout.column(align=True) + col.itemL(text="Bones:") col.itemO("armature.bone_primitive_add", text="Add") col.itemO("armature.duplicate", text="Duplicate") col.itemO("armature.delete", text="Delete") - layout.itemL(text="Modeling:") - layout.itemO("armature.extrude") - - layout.itemL(text="Repeat:") + col = layout.column(align=True) + col.itemL(text="Modeling:") + col.itemO("armature.extrude") col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -244,16 +232,14 @@ class VIEW3D_PT_tools_mballedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") - col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -267,16 +253,14 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") - col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") @@ -290,40 +274,36 @@ class VIEW3D_PT_tools_posemode(View3DPanel): def draw(self, context): layout = self.layout - layout.itemL(text="Transform:") + col = layout.column(align=True) + col.itemL(text="Transform:") col.itemO("tfm.translate") col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") - layout.itemL(text="Bones:") - col = layout.column(align=True) + col.itemL(text="Bones:") col.itemO("pose.hide", text="Hide") col.itemO("pose.reveal", text="Reveal") - layout.itemL(text="Keyframes:") - col = layout.column(align=True) + layout.itemL(text="Keyframes:") col.itemO("anim.insert_keyframe_menu", text="Insert") col.itemO("anim.delete_keyframe_v3d", text="Remove") - layout.itemL(text="Pose:") - col = layout.column(align=True) + col.itemL(text="Pose:") col.itemO("pose.copy", text="Copy") col.itemO("pose.paste", text="Paste") - layout.itemL(text="Library:") - col = layout.column(align=True) + col.itemL(text="Library:") col.itemO("poselib.pose_add", text="Add") col.itemO("poselib.pose_remove", text="Remove") - layout.itemL(text="Repeat:") - col = layout.column(align=True) + col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c index 38593af372f..b469bb3e400 100644 --- a/source/blender/editors/metaball/mball_ops.c +++ b/source/blender/editors/metaball/mball_ops.c @@ -60,6 +60,7 @@ void ED_keymap_metaball(wmWindowManager *wm) RNA_enum_set(WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MBALL_OT_duplicate_metaelems", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "MBALL_OT_select_deselect_all_metaelems", AKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index ddcecdeb1f1..6ee43765475 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -227,7 +227,8 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, 0, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); - WM_keymap_verify_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "OBJECT_OT_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1); diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 647b9a4b51f..456e802194e 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -1326,14 +1326,14 @@ void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, I /* fields */ - but= uiDefButBitS(block, TOGBUT, IMA_FIELDS, imagechanged, "Fields", 0, 80, 200, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); + but= uiDefButBitS(block, OPTION, IMA_FIELDS, imagechanged, "Fields", 0, 80, 200, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); uiButSetFunc(but, image_field_test, ima, iuser); - uiDefButBitS(block, TOGBUT, IMA_STD_FIELD, B_NOP, "Odd", 0, 55, 200, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); + uiDefButBitS(block, OPTION, IMA_STD_FIELD, B_NOP, "Odd", 0, 55, 200, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); uiBlockSetFunc(block, image_reload_cb, ima, iuser); - uiDefButBitS(block, TOGBUT, IMA_ANTIALI, B_NOP, "Anti", 0, 5, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); - uiDefButBitS(block, TOGBUT, IMA_DO_PREMUL, imagechanged, "Premul", 0, -20, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); + uiDefButBitS(block, OPTION, IMA_ANTIALI, B_NOP, "Anti-Aliasing", 0, 5, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); + uiDefButBitS(block, OPTION, IMA_DO_PREMUL, imagechanged, "Premultiply", 0, -20, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { @@ -1356,9 +1356,9 @@ void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, I uiDefButI(block, NUM, imagechanged, "Offset:", 220, 30, 200, 20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); uiDefButS(block, NUM, imagechanged, "Fields:", 0, 30, 200, 20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)"); - uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 220, 5, 200, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); + uiDefButBitS(block, OPTION, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 220, 5, 200, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); - uiDefButS(block, TOG, imagechanged, "Cyclic", 220, -20, 200, 20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); + uiDefButS(block, OPTION, imagechanged, "Cyclic", 220, -20, 200, 20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); uiBlockSetFunc(block, NULL, iuser, NULL); } @@ -1372,7 +1372,7 @@ void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, I uiDefButS(block, NUM, imagechanged, "Y:", 220, 35,200,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y"); uiBlockEndAlign(block); - uiDefButS(block, TOGBUT, imagechanged, "UV Test grid", 220,10,200,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); + uiDefButS(block, OPTION, imagechanged, "UV Test grid", 220,10,200,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); uiBlockSetFunc(block, NULL, NULL, NULL); } } diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index a10cabfa983..4c2fbf7b9dc 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -87,6 +87,7 @@ void node_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_select_all", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_select_linked_to", LKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 05bf1c80b43..b5e5de928b5 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -912,7 +912,7 @@ void ED_spacetype_view3d(void) /* regions: listview/buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 220; // XXX + art->minsizex= 180; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= view3d_buttons_area_listener; art->init= view3d_buttons_area_init; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 1ff5dca7307..7d4e3337fe3 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -302,60 +302,68 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, if((ob->parent) && (ob->partype == PARBONE)) but_y = 135; else but_y = 150; - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); - uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); - uiBlockEndAlign(block); + memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); if(tot==1) { uiDefBut(block, LABEL, 0, "Vertex:", 0, 130, 200, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); - if(totw==1) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 0, 50, 200, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, ""); - uiBlockEndAlign(block); - - if(defstr[0]) { - uiDefBut(block, LABEL, 1, "Vertex Deform Groups", 0, 40, 200, 20, NULL, 0.0, 0.0, 0, 0, ""); - + + if(totw==1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NOP, "Weight:", 10, 20, 150, 20, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value"); - uiDefButI(block, MENU, B_REDR, defstr, 160, 20, 140, 20, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group"); + uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); + uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); + if(totweight) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); + } + else { + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); + uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); + uiBlockEndAlign(block); + if(totweight) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); } - else if(totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); - } else { - uiDefBut(block, LABEL, 0, "Median:", 0, 130, 200, 20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Median:", 0, 130, 200, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); - if(totw==tot) + if(totw==tot) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, ""); - uiBlockEndAlign(block); - if(totweight) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal"); - } - - if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */ - uiBlockBeginAlign(block); - uiDefBut(block, BUT,B_SETPT_AUTO,"Auto", 10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)"); - uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)"); - uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)"); - uiDefBut(block, BUT,B_SETPT_FREE,"Free", 227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)"); - uiBlockEndAlign(block); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); + uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); + uiBlockEndAlign(block); + if(totweight) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal"); + uiBlockEndAlign(block); + } + else { + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); + uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); + uiBlockEndAlign(block); + if(totweight) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal"); + uiBlockEndAlign(block); + } } - + if(totedge==1) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, ""); else if(totedge>1) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:", 0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, ""); } else { // apply @@ -503,14 +511,6 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer)) break; } - if (!pchan || !bone) return; - - if((ob->parent) && (ob->partype == PARBONE)) - but= uiDefBut (block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, bone->name, 1, 31, 0, 0, ""); - else - but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 140, 140, 19, bone->name, 1, 31, 0, 0, ""); - uiButSetFunc(but, validate_bonebutton_cb, bone, NULL); - uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob); if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { float quat[4]; @@ -526,29 +526,43 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float tfp->ob_eul[1]*= 180.0/M_PI; tfp->ob_eul[2]*= 180.0/M_PI; + uiDefBut(block, LABEL, 0, "Location:", 0, 240, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 10,140,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:", 30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 10,120,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:", 30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 10,100,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:", 30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, ""); - + uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:", 0, 220, 120, 19, pchan->loc, -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:", 0, 200, 120, 19, pchan->loc+1, -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:", 0, 180, 120, 19, pchan->loc+2, -lim, lim, 100, 3, ""); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 10,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:", 30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 10,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:", 30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 10,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:", 30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, ""); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 125, 220, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Location value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 125, 200, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Location value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 180, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed"); + uiBlockEndAlign(block); + + uiDefBut(block, LABEL, 0, "Rotation:", 0, 160, 100, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_ARMATUREPANEL3, "X:", 0, 140, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL3, "Y:", 0, 120, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL3, "Z:", 0, 100, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, ""); + uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 160,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:", 180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 160,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:", 180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 160,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:", 180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, ""); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 125, 140, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Rotation value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 125, 120, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 125, 100, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed"); + uiBlockEndAlign(block); + + uiDefBut(block, LABEL, 0, "Scale:", 0, 80, 100, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:", 0, 60, 120, 19, pchan->size, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:", 0, 40, 120, 19, pchan->size+1, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:", 0, 20, 120, 19, pchan->size+2, -lim, lim, 10, 3, ""); + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 125, 60, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects X Scale value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 125, 40, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects Y Scale value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 125, 20, 25, 19, &(pchan->protectflag), 0, 0, 0, 0, "Protects z Scale value from being Transformed"); uiBlockEndAlign(block); } @@ -585,34 +599,31 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if (!ebone) return; - if((ob->parent) && (ob->partype == PARBONE)) - but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, ""); - else - but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 150, 140, 19, ebone->name, 1, 31, 0, 0, ""); - uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL); - + uiDefBut(block, LABEL, 0, "Head:", 0, 210, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:", 10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:", 10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:", 10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 190, 100, 19, ebone->head, -lim, lim, 10, 3, "X Location of the head end of the bone"); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Y:", 0, 170, 100, 19, ebone->head+1, -lim, lim, 10, 3, "Y Location of the head end of the bone"); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Z:", 0, 150, 100, 19, ebone->head+2, -lim, lim, 10, 3, "Z Location of the head end of the bone"); + if (ebone->parent && ebone->flag & BONE_CONNECTED ) + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:", 0, 130, 100, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "Head radius. Visualize with the Envelope display option"); + else + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:", 0, 130, 100, 19, &ebone->rad_head, 0, lim, 10, 3, "Head radius. Visualize with the Envelope display option"); + uiBlockEndAlign(block); + + uiBlockEndAlign(block); + uiDefBut(block, LABEL, 0, "Tail:", 0, 110, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:", 160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:", 160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:", 160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 90, 100, 19, ebone->tail, -lim, lim, 10, 3, "X Location of the tail end of the bone"); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Y:", 0, 70, 100, 19, ebone->tail+1, -lim, lim, 10, 3, "Y Location of the tail end of the bone"); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Z:", 0, 50, 100, 19, ebone->tail+2, -lim, lim, 10, 3, "Z Location of the tail end of the bone"); + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Radius:", 0, 30, 100, 19, &ebone->rad_tail, 0, lim, 10, 3, "Tail radius. Visualize with the Envelope display option"); uiBlockEndAlign(block); tfp->ob_eul[0]= 180.0*ebone->roll/M_PI; - uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, ""); - - uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, B_REDR, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode"); - + uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 0, 0, 100, 19, tfp->ob_eul, -lim, lim, 1000, 3, "Bone rotation around head-tail axis"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, ""); - if (ebone->parent && ebone->flag & BONE_CONNECTED ) - uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:", 10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, ""); - else - uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:", 10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, ""); - uiBlockEndAlign(block); + + } static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim) @@ -1083,19 +1094,8 @@ static void view3d_panel_object(const bContext *C, Panel *pa) if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) { } else { - //bt= uiDefBut(block, TEX, B_IDNAME, "OB: ", 10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, ""); - //uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL); - if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) { - // uiBlockBeginAlign(block); - // uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object"); - if((ob->parent) && (ob->partype == PARBONE)) { - // bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, ""); - // uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent); - } - else { - strcpy(ob->parsubstr, ""); - } + strcpy(ob->parsubstr, ""); uiBlockEndAlign(block); } } @@ -1113,14 +1113,18 @@ static void view3d_panel_object(const bContext *C, Panel *pa) else { BoundBox *bb = NULL; - uiDefBut(block, LABEL, 0, "Location:", 10, 170, 100, 20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Location:", 0, 300, 100, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 0, 280, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "Y:", 0, 260, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "Z:", 0, 240, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, ""); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 10,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 10,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANEL, "Y:", 30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 10,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANEL, "Z:", 30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, ""); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED, 125, 280, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Location value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED, 125, 260, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Location value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 240, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed"); + uiBlockEndAlign(block); tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI; tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI; @@ -1128,40 +1132,53 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiBlockBeginAlign(block); if ((ob->parent) && (ob->partype == PARBONE)) { - uiDefBut(block, LABEL, 0, "Rotation:", 160, 170, 100, 20, 0, 0, 0, 0, 0, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 160,90,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, ""); + uiDefBut(block, LABEL, 0, "Rotation:", 0, 220, 100, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 0, 200, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 0, 180, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 0, 160, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, ""); + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 125, 200, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Rotation from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 125, 180, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 125, 160, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed"); + uiBlockEndAlign(block); } else { - uiDefBut(block, LABEL, 0, "Rotation:", 160, 170, 100, 20, 0, 0, 0, 0, 0, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 160,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, ""); + uiDefBut(block, LABEL, 0, "Rotation:", 0, 220, 100, 20, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_OBJECTPANELROT, "X:", 0, 200, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:", 0, 180, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:", 0, 160, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, ""); + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED, 125, 200, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Rotation value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED, 125, 180, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Rotation value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED, 125, 160, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Rotation value from being Transformed"); + uiBlockEndAlign(block); } tfp->ob_scale[0]= ob->size[0]; tfp->ob_scale[1]= ob->size[1]; tfp->ob_scale[2]= ob->size[2]; - uiDefBut(block, LABEL, 0, "Scale:", 10, 90, 100, 20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Scale:", 0, 140, 100, 20, 0, 0, 0, 0, 0, ""); + uiDefButS(block, OPTION, B_REDR, "Link", 60, 140, 50, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions"); uiBlockBeginAlign(block); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 10, 70, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELSCALE, "X:", 30, 70, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 10, 50, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Y:", 30, 50, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, ""); - uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 10, 30, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed"); - uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Z:", 30, 30, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELSCALE, "X:", 0, 120, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Y:", 0, 100, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Z:", 0, 80, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, ""); uiBlockEndAlign(block); - uiDefButS(block, TOG, B_REDR, "Link Scale", 10, 0, 140, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions"); + uiBlockBeginAlign(block); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 125, 120, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects X Scale value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 125, 100, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Y Scale value from being Transformed"); + uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 125, 80, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Scale value from being Transformed"); + + bb= object_get_boundbox(ob); if (bb) { @@ -1175,19 +1192,19 @@ static void view3d_panel_object(const bContext *C, Panel *pa) if ((ob->parent) && (ob->partype == PARBONE)) { - uiDefBut(block, LABEL, 0, "Dimensions:", 160, 90, 100, 20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Dimensions:", 0, 60, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size"); - uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size"); - uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size"); + uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 0, 40, 150, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate X bounding box size"); + uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 0, 20, 150, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate Y bounding box size"); + uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 0, 0, 150, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate Z bounding box size"); } else { - uiDefBut(block, LABEL, 0, "Dimensions:", 160, 90, 100, 20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Dimensions:", 0, 60, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size"); - uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size"); - uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size"); + uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:", 0, 40, 150, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate X bounding box size"); + uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:", 0, 20, 150, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate Y bounding box size"); + uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:", 0, 0, 150, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate Z bounding box size"); } uiBlockEndAlign(block); -- cgit v1.2.3 From 971e984b083c1d0a44d257294f18e2750522853a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 15 Sep 2009 13:28:36 +0000 Subject: Update MSVC project files --- projectfiles_vc9/blender/editors/ED_editors.vcproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index 5a6519d3d35..81d80436a00 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -1214,6 +1214,10 @@ RelativePath="..\..\..\source\blender\editors\mesh\editmesh_tools.c" > + + -- cgit v1.2.3 From 0a8fa9ff70af7e2262584d12ef8305c27bdf7cc8 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 15 Sep 2009 16:05:59 +0000 Subject: Smoke: * This should make low res bake too if high res gets baked --- source/blender/blenkernel/intern/pointcache.c | 19 +++++++++++++++++++ source/blender/blenkernel/intern/smoke.c | 1 + 2 files changed, 20 insertions(+) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 7725efe3885..d685bc29568 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2119,6 +2119,25 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) if((cache->flag & PTCACHE_BAKED)==0) { if(pid->type==PTCACHE_TYPE_PARTICLES) psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe); + else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) { + /* get all pids from the object and search for smoke low res */ + ListBase pidlist2; + PTCacheID *pid2; + BKE_ptcache_ids_from_object(&pidlist2, pid->ob); + for(pid2=pidlist2.first; pid2; pid2=pid2->next) { + if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN) + { + if(pid2->cache && !(pid2->cache->flag & PTCACHE_BAKED)) { + if(bake || pid2->cache->flag & PTCACHE_REDO_NEEDED) + BKE_ptcache_id_clear(pid2, PTCACHE_CLEAR_ALL, 0); + if(bake) { + pid2->cache->flag |= PTCACHE_BAKING; + pid2->cache->flag &= ~PTCACHE_BAKED; + } + } + } + } + } if(bake || cache->flag & PTCACHE_REDO_NEEDED) BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 1b6b4d4838e..62463b3d555 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1182,6 +1182,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM cache->simframe= framenr; // simulate the actual smoke (c++ code in intern/smoke) + // DG: interesting commenting this line + deactivating loading of noise files if(framenr!=startframe) smoke_step(sds->fluid, smd->time); -- cgit v1.2.3 From fd664970f17b71764753ffe3fb87388f40c91da2 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 15 Sep 2009 16:25:53 +0000 Subject: Completely move freeing flag to report, operator flag is uneeded. Also bugfix for py operators. Reports need to be kept alive when operator is registered. --- source/blender/makesdna/DNA_windowmanager_types.h | 1 - source/blender/windowmanager/intern/wm.c | 2 +- source/blender/windowmanager/intern/wm_event_system.c | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index c3bbb759aff..4274cb7ebc0 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -298,7 +298,6 @@ typedef struct wmOperator { #define OPERATOR_PASS_THROUGH 8 /* wmOperator flag */ -#define OPERATOR_REPORT_FREE 1 /* ************** wmEvent ************************ */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 0a91c5078b7..4405b52888d 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -69,7 +69,7 @@ void WM_operator_free(wmOperator *op) MEM_freeN(op->properties); } - if(op->reports && ((op->flag & OPERATOR_REPORT_FREE) || (op->reports->flag & RPT_FREE))) { + if(op->reports && (op->reports->flag & RPT_FREE)) { BKE_reports_clear(op->reports); MEM_freeN(op->reports); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index b5ecc6f4d58..306b99dcfcc 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -349,8 +349,7 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P } else { op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); - BKE_reports_init(op->reports, RPT_STORE); - op->flag |= OPERATOR_REPORT_FREE; + BKE_reports_init(op->reports, RPT_STORE|RPT_FREE); } /* recursive filling of operator macro list */ @@ -555,7 +554,8 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA retval= wm_operator_call_internal(C, ot, context, properties, reports); - if (retval & OPERATOR_RUNNING_MODAL) + /* keep the reports around if needed later */ + if (retval & OPERATOR_RUNNING_MODAL || ot->flag & OPTYPE_REGISTER) { reports->flag |= RPT_FREE; } -- cgit v1.2.3 From 22274d38079f7e1e1e0bf24e777c333961ed18f7 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 15 Sep 2009 19:53:18 +0000 Subject: More automatic stuff. Server can now be set to broadcast on local network (every 10s, approximately 20 bytes of data) where client and slave can pick up its existence. This is on by default. Default ip address is now "[default]", which means for the master that it will listen to all interface and for the clients and slave that they will automatically work out the master's address from its broadcast. --- release/io/netrender/client.py | 13 +++++++------ release/io/netrender/master.py | 24 +++++++++++++++++++++-- release/io/netrender/operators.py | 41 +++++++++++++++++++++++++++++++++++++-- release/io/netrender/slave.py | 27 ++++++++++++++++++-------- release/io/netrender/ui.py | 24 +++++++++++++++++------ release/io/netrender/utils.py | 7 +++++-- 6 files changed, 110 insertions(+), 26 deletions(-) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index d059387cfcf..a6cfb4e020d 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -138,12 +138,12 @@ class NetworkRenderEngine(bpy.types.RenderEngine): print("UNKNOWN OPERATION MODE") def render_master(self, scene): - server_address = (scene.network_render.server_address, scene.network_render.server_port) - httpd = master.RenderMasterServer(server_address, master.RenderHandler, scene.network_render.path) - httpd.timeout = 1 - httpd.stats = self.update_stats - while not self.test_break(): - httpd.handle_request() + netsettings = scene.network_render + + address = "" if netsettings.server_address == "[default]" else netsettings.server_address + + master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break) + def render_slave(self, scene): slave.render_slave(self, scene) @@ -152,6 +152,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): netsettings = scene.network_render self.update_stats("", "Network render client initiation") + conn = clientConnection(scene) if conn: diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 78e9243bc9d..13e8b399d6c 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -1,5 +1,5 @@ import sys, os -import http, http.client, http.server, urllib +import http, http.client, http.server, urllib, socket import subprocess, shutil, time, hashlib from netrender.utils import * @@ -529,7 +529,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_frame = int(self.headers['job-frame']) buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".log", 'wb') + f = open(job.save_path + "%04d" % job_frame + ".log", 'ab') f.write(buf) f.close() @@ -613,3 +613,23 @@ class RenderMasterServer(http.server.HTTPServer): return job, job.getFrames() return None, None + +def runMaster(address, broadcast, path, update_stats, test_break): + httpd = RenderMasterServer(address, RenderHandler, path) + httpd.timeout = 1 + httpd.stats = update_stats + + if broadcast: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + + start_time = time.time() + + while not test_break(): + httpd.handle_request() + + if broadcast: + if time.time() - start_time >= 10: # need constant here + print("broadcasting address") + s.sendto(bytes("%s:%i" % address, encoding='utf8'), 0, ('',address[1])) + start_time = time.time() diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 655afa6631f..928c2b9efaf 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -1,6 +1,6 @@ import bpy import sys, os -import http, http.client, http.server, urllib +import http, http.client, http.server, urllib, socket from netrender.utils import * import netrender.client as client @@ -316,4 +316,41 @@ class netclientdownload(bpy.types.Operator): return ('FINISHED',) def invoke(self, context, event): - return self.execute(context) \ No newline at end of file + return self.execute(context) + +@rnaOperator +class netclientscan(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientscan" + __label__ = "Net Render Client Scan" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + s.settimeout(30) + + s.bind(('', netsettings.server_port)) + + try: + buf, address = s.recvfrom(128) + + print("received:", buf) + + netsettings.server_address = address[0] + except socket.timeout: + print("no server info") + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index c12c846231d..1dcb608931e 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -105,6 +105,8 @@ def render_slave(engine, scene): process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + headers = {"job-id":job.id, "slave-id":slave_id} + cancelled = False stdout = bytes() run_t = time.time() @@ -113,10 +115,18 @@ def render_slave(engine, scene): current_t = time.time() cancelled = engine.test_break() if current_t - run_t > CANCEL_POLL_SPEED: + + # update logs. Eventually, it should support one log file for many frames + for frame in job.frames: + headers["job-frame"] = str(frame.number) + conn.request("PUT", "log", stdout, headers=headers) + response = conn.getresponse() + + stdout = bytes() + + run_t = current_t if testCancel(conn, job.id): cancelled = True - else: - run_t = current_t if cancelled: # kill process if needed @@ -132,6 +142,13 @@ def render_slave(engine, scene): print("status", status) + # flush the rest of the logs + if stdout: + for frame in job.frames: + headers["job-frame"] = str(frame.number) + conn.request("PUT", "log", stdout, headers=headers) + response = conn.getresponse() + headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} if status == 0: # non zero status is error @@ -150,12 +167,6 @@ def render_slave(engine, scene): # send error result back to server conn.request("PUT", "render", headers=headers) response = conn.getresponse() - - for frame in job.frames: - headers["job-frame"] = str(frame.number) - # send log in any case - conn.request("PUT", "log", stdout, headers=headers) - response = conn.getresponse() else: if timeout < MAX_TIMEOUT: timeout += INCREMENT_TIMEOUT diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index eee95bdac19..df2b6288fb0 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -48,17 +48,24 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col = split.column() - col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") + if scene.network_render.mode == "RENDER_CLIENT": + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") + col.itemR(scene.network_render, "mode") + col.itemR(scene.network_render, "path") col.itemR(scene.network_render, "server_address") col.itemR(scene.network_render, "server_port") - col.itemR(scene.network_render, "path") + + if scene.network_render.mode == "RENDER_MASTER": + col.itemR(scene.network_render, "server_broadcast") + else: + col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="") if scene.network_render.mode == "RENDER_CLIENT": - col.itemR(scene.network_render, "chunks") - col.itemR(scene.network_render, "priority") - col.itemR(scene.network_render, "job_name") col.itemO("render.netclientsend", text="send job to server") + col.itemR(scene.network_render, "job_name") + col.itemR(scene.network_render, "priority") + col.itemR(scene.network_render, "chunks") @rnaType class SCENE_PT_network_slaves(RenderButtonsPanel): @@ -192,7 +199,7 @@ NetRenderSettings.StringProperty( attr="server_address", name="Server address", description="IP or name of the master render server", maxlen = 128, - default = "127.0.0.1") + default = "[default]") NetRenderSettings.IntProperty( attr="server_port", name="Server port", @@ -201,6 +208,11 @@ NetRenderSettings.IntProperty( attr="server_port", min=1, max=65535) +NetRenderSettings.BoolProperty( attr="server_broadcast", + name="Broadcast server address", + description="broadcast server address on local network", + default = True) + NetRenderSettings.StringProperty( attr="path", name="Path", description="Path for temporary files", diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index db6646e6916..72a29472748 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -22,9 +22,12 @@ def rnaOperator(rna_op): return rna_op def clientConnection(scene): - netrender = scene.network_render + netsettings = scene.network_render - conn = http.client.HTTPConnection(netrender.server_address, netrender.server_port) + if netsettings.server_address == "[default]": + bpy.ops.render.netclientscan() + + conn = http.client.HTTPConnection(netsettings.server_address, netsettings.server_port) if clientVerifyVersion(conn): return conn -- cgit v1.2.3 From 063d806f152e003b662a0e22a19c27a4afbfb7fa Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Tue, 15 Sep 2009 20:47:34 +0000 Subject: 2.5 filebrowser bugfix #1: SpaceFile->files needs to be deleted on exec and cancel of the filebrowser and in init to ensure correct setting of the read function. bugfix #2: SpaceFile->params needs to be set in file_init otherwise Python can't access params in header ui. --- source/blender/editors/space_file/file_ops.c | 10 ++++++++++ source/blender/editors/space_file/filesel.c | 7 +------ source/blender/editors/space_file/space_file.c | 6 ++++++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index d2d1d11ec5c..0e0ad88906e 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -496,6 +496,12 @@ int file_cancel_exec(bContext *C, wmOperator *unused) WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_CANCEL); sfile->op = NULL; + if (sfile->files) { + filelist_free(sfile->files); + MEM_freeN(sfile->files); + sfile->files= NULL; + } + return OPERATOR_FINISHED; } @@ -567,6 +573,10 @@ int file_exec(bContext *C, wmOperator *unused) BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs"); fsmenu_write_file(fsmenu_get(), name); WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC); + + filelist_free(sfile->files); + MEM_freeN(sfile->files); + sfile->files= NULL; } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 085eecd2a7d..a0787ef989d 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -169,18 +169,13 @@ short ED_fileselect_set_params(SpaceFile *sfile) } else { /* default values, if no operator */ + params->type = FILE_UNIX; params->flag |= FILE_HIDE_DOT; params->display = FILE_SHORTDISPLAY; params->filter = 0; params->sort = FILE_SORT_ALPHA; } - /* new params, refresh file list */ - if(sfile->files) { - filelist_free(sfile->files); - filelist_setdir(sfile->files, params->dir); - } - return 1; } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 68eeb8718a2..27948618d03 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -159,6 +159,12 @@ static void file_init(struct wmWindowManager *wm, ScrArea *sa) if(sfile->params) { MEM_freeN(sfile->params); sfile->params = 0; + ED_fileselect_set_params(sfile); + if (sfile->files) { + filelist_free(sfile->files); + MEM_freeN(sfile->files); + sfile->files= NULL; + } } printf("file_init\n"); } -- cgit v1.2.3 From 581cb64f2ccdd49790fe06834d95e08f92c7308f Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 15 Sep 2009 22:34:10 +0000 Subject: Make verification of committed .mo files optional. --- po/Makefile | 2 ++ source/nan_definitions.mk | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/po/Makefile b/po/Makefile index 425efbc08b3..b656a00fb38 100644 --- a/po/Makefile +++ b/po/Makefile @@ -50,9 +50,11 @@ LINGUAS_DEST= $(foreach LINGUA, $(LINGUAS),$(DIR)$(LINGUA)/LC_MESSAGES/blender.m $(DIR)%/LC_MESSAGES/blender.mo: %.po mkdir -p $(@D) msgfmt -o $@ $< +ifeq ($(BF_VERIFY_MO_FILES), true) @cmp $@ $(NANBLENDERHOME)/bin/.blender/locale/$(basename $<)/LC_MESSAGES/blender.mo \ || ( echo Mismatch between generated and commited $(basename $<).mo catalog && \ rm -f $@ && false ) +endif all debug:: $(LINGUAS_DEST) # Just trigger the deps diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index 8c47bcf11c1..6d4a7139d5b 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -143,6 +143,9 @@ ifndef CONFIG_GUESS export NAN_FFMPEGCFLAGS = $(shell pkg-config --cflags libavcodec libavdevice libavformat libswscale libavutil) endif + # Compare recreated .mo files with committed ones + export BF_VERIFY_MO_FILES ?= true + # Platform Dependent settings go below: ifeq ($(OS),darwin) @@ -309,6 +312,9 @@ ifndef CONFIG_GUESS # enable l10n export INTERNATIONAL ?= true + # Different endianess will make it fail, rely on other plataforms for checks + export BF_VERIFY_MO_FILES = false + else ifeq ($(OS),linux) -- cgit v1.2.3 From 0befb9b01d354b66403c1606c7533a3ec0da64d4 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 15 Sep 2009 23:37:20 +0000 Subject: Sync names with real content. --- release/datafiles/splash.jpg | Bin 197165 -> 0 bytes release/datafiles/splash.png | Bin 0 -> 197165 bytes source/blender/editors/datafiles/splash.jpg.c | 2483 ------------------------- source/blender/editors/datafiles/splash.png.c | 2483 +++++++++++++++++++++++++ source/blender/editors/include/ED_datafiles.h | 4 +- 5 files changed, 2485 insertions(+), 2485 deletions(-) delete mode 100644 release/datafiles/splash.jpg create mode 100644 release/datafiles/splash.png delete mode 100644 source/blender/editors/datafiles/splash.jpg.c create mode 100644 source/blender/editors/datafiles/splash.png.c diff --git a/release/datafiles/splash.jpg b/release/datafiles/splash.jpg deleted file mode 100644 index e35a26a2c23..00000000000 Binary files a/release/datafiles/splash.jpg and /dev/null differ diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png new file mode 100644 index 00000000000..e35a26a2c23 Binary files /dev/null and b/release/datafiles/splash.png differ diff --git a/source/blender/editors/datafiles/splash.jpg.c b/source/blender/editors/datafiles/splash.jpg.c deleted file mode 100644 index c1ca8b575e6..00000000000 --- a/source/blender/editors/datafiles/splash.jpg.c +++ /dev/null @@ -1,2483 +0,0 @@ -/* DataToC output of file */ - -int datatoc_splash_jpg_size= 79258; -char datatoc_splash_jpg[]= { -255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 1, 0, 72, 0, 72, 0, 0,255,225, 0, 22, 69,120, -105,102, 0, 0, 77, 77, 0, 42, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,255,219, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, - 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,255,219, 0, 67, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,255,192, 0, 17, - 8, 1, 15, 1,245, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1,255,196, 0, 31, 0, 0, 1, 3, 5, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 7, 10, 3, 5, 6, 8, 9, 2, 1, 11,255,196, 0,103, 16, 0, 1, 3, 3, 2, 4, 3, 4, 6, 4, 7, - 11, 5, 9, 13, 9, 1, 2, 3, 4, 5, 6, 17, 0, 7, 8, 18, 33, 49, 19, 65, 81, 9, 20, 34, 97, 10, 21,113,129,145,240, 35, - 50,161,193, 22, 23, 24, 66,177,209,225, 25, 26, 36, 40, 51, 56, 73, 82, 98,232,241, 72,104,105,136,168, 41, 52, 57, 67, 84, 88, -120,150,178, 37, 38, 68, 83, 87,115,130,135,147,152,181,200,210, 54, 89, 99,114,146,184,213,214,215,255,196, 0, 29, 1, 0, 0, - 6, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 6, 7, 1, 4, 8, 9,255,196, 0, 80, 17, 0, 2, 1, - 2, 4, 4, 3, 4, 6, 7, 5, 7, 0, 7, 9, 0, 1, 2, 3, 4, 17, 0, 5, 18, 33, 6, 19, 49, 65, 7, 34, 81, 20, 97,113, -240, 8, 35, 50,129,161,209, 21, 66, 82,145,177,193,210, 36, 51, 98,162,225, 9, 67, 83, 84,114,130,241, 52, 56, 68, 85,116,148, -211, 22, 23, 24,115,131,146,147,180,181,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,159,198,150,150,150,134, 6, 22, -150,150,190,100,122,143,199, 67, 3, 31,116,203,220, 60, 68,108,181,171,123, 70,219,170,254,224,209, 41,183,140,167, 25,101, 20, -135,189,241, 73,101,249, 28,165,136,243,170, 77, 69, 84, 74,116,149,133,163,149,185, 15,180,226,185,211,132,158, 97,151,159, 35, -212,126, 35, 92,108,227, 63,131, 43,145, 85,251,143,120, 54,213, 18,235,236, 86, 37,191, 87,185,237,148,243, 72,170, 67,146,224, - 11,147, 81,162,128, 57,167, 69, 42, 5, 75,143,213,230,242, 75, 94, 34, 50,148, 86,158, 42,113, 39, 27,112,159, 14, 38,119,193, - 60, 55, 23, 19,212, 81,204,173, 89, 4,134, 67, 34,209,128,198, 87,130, 56,138,188,146, 2, 0,242,151, 49,169, 50,114,101, 1, -128,179,188, 40,225,158, 7,226,222, 37,108,143,142, 56,150,110, 23,166,172,133,150,142,120,196, 98, 54,173, 44,162, 36,158, 73, - 85,146, 56,200, 44,124,193, 4,140, 4,124,232,139, 41, 61,145,109,196, 58,132,173,181, 37,104, 80,200, 82, 72, 32,131,243, 26, -247,174, 11,240,211,199, 61,219,180,206, 66,179, 55, 36, 79,186,108,118, 29, 68, 54,166, 58, 92,122,228,181,217, 65, 13, 22,219, - 47, 30,106,157, 61,174, 95,242, 14, 16,243, 97, 37, 45, 44,128,150,181,219,219, 46,247,181,247, 6,129, 2,231,180, 43, 48,171, -148,106,139, 65,216,211, 33, 58, 29, 65,232, 57,219,113, 63,172,203,233, 86, 66,219, 88, 74,208,160, 66,146, 14,147,240,211,197, -174, 19,241, 67, 46, 53, 25, 37, 79,179,102,180,202, 13, 86, 95, 49, 2,166,156,244, 38,219, 9, 97,213,178,207, 29,212,220, 7, - 17,201,120,194,158, 38,248, 69,197,190, 22,102, 66,159, 60,166,246,156,166,165,136,165,204, 33, 4,210,212,142,160, 95,115, 12, -218,119,104, 36,179, 11, 18,134, 72,237, 33,202,244,180,180,181,103,226,173,194,210,210,210,208,192,194,210,210,210,208,192,194, -210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210, -215, 13,125,163,254,220, 13,158,224,130,240,159,178,214, 5,156,238,249,111,173, 45,150, 21,116, 81,219,173,155,110,200,219,199, - 39,194, 98,116, 8,215, 53,192,138,116,167,170,213,245, 68,151, 17,255, 0,171, 32,177,132, 50,233, 76,186,132, 39,249, 26, 91, -214, 67,195,217,207, 19,102, 9,149,228,116, 47, 95, 90,224,177, 85, 42,161, 80, 16, 11,200,238, 85, 35, 64, 72, 5,157,128,185, - 10, 46,204, 1, 98,226, 46, 38,200,248, 79, 45,124,219,136, 51, 20,203,104, 81,130, 6, 96,204,206,237,114,169, 28,104, 26, 73, - 28,128, 78,148, 86, 58, 85,152,128,170,196,119, 43, 75, 80,124, 63, 73,159,141,131, 84, 83,195,103, 56, 94, 20, 82,242,212,138, -127,240,103,117, 13, 77, 44, 20,171,195,105, 85,127,227,115,194, 91,193,101, 37, 75, 16,146, 20, 1, 1,180,147,204, 58,247,192, - 39,183,219,102,184,168,189,173,253,156,222,171, 32,236, 38,233,221, 18,227,210,109, 58,154,110, 6,238, 13,182,188,107,111,132, -162, 53, 29,138,204,184,113, 36,218,181,233,114, 84, 26,131, 10, 91, 82, 88,144,233, 68,118,234,107,152,244,120,206,205,115,175, - 7,248,243, 35,161,151, 49,169,202, 86,166,150,157, 75,200,105,230,142,102,141, 64,185,102,140, 17, 33, 10, 55, 98,138,225, 64, - 44,108,160,156, 64,178, 47, 27,188, 58,226, 12,194, 28,174,151, 57,106, 90,186,150, 9, 16,169,134, 72, 82, 71, 38,202,171, 35, - 3, 26,179, 27, 5, 18, 50, 22, 36, 42,130,196, 12, 72, 35, 75, 94, 80,180,173, 41, 90, 8, 82, 84, 1, 73, 29, 65, 7,204, 29, -122,213, 97,139,107, 11, 75, 75, 94, 29,117,182, 91,113,231,156, 67, 76,180,133, 56,235,174, 41, 40,109,182,208,146,165,184,226, -212, 64, 66, 2, 65, 36,147,128, 6, 78,134, 6, 61,233,107,140, 28, 63,123, 94,236,238, 39,253,160,119,151, 9,219, 61,108,210, - 43,219, 63,103, 88,247, 29, 77,157,231, 77, 86, 91,178,239, 43,178,215,171, 80,169,213, 69,219, 84,214,227,166, 57,178,252,106, -195,236,197,150, 92,117, 83,126,173,247,214, 23,238,178, 89, 3,231,181,219,218,129,127,123, 56, 15, 15,137,177,182,194,209,220, -115,188,169,221, 85, 85, 13,213, 86,172,210,254,165,254, 47, 78,219,136, 94,225,245, 74, 79,188,123,199,240,222, 95,139,226,126, -167,184,183,201,250,202,212,182, 30, 7,226,105,179,220,183,134,191, 71,242,179,156,218, 1, 81, 12, 50, 72,136,121, 70, 41, 38, - 5,203, 48, 17,183, 46, 39, 37, 28,171,130, 52,149, 12,109,136, 92,222, 32,240,164, 60, 61,154,241, 87,233, 46,118, 69,147, 78, -105,167,158, 56,228,145,121,162,104,160, 34, 48,170, 90, 84,230,202,138, 36,140, 50, 48, 58,149,138,139,227,180, 26, 90,134, 23, -247,207,155,251,255, 0,155, 30,209,127,235, 93,227,255, 0,232,210,254,249,243,127,127,243, 99,218, 47,253,107,188,127,253, 26, -152,127,247, 29,226, 55,254,233,139,255, 0,155,166,255, 0,234, 98, 19,255, 0,226, 11,194,239,253,245, 55,255, 0, 37, 87,255, - 0,210,196,207,116,181,166,252, 3,241, 57, 89,226,255, 0,133,157,171,223,235,138,219,165,218, 85,203,250,153, 89,157, 81,183, -232,178,101,204,165,211,157,166, 93, 53,202, 3,109,195,147, 56,120,175, 33,108, 82,154,113, 69,125, 66,221, 80, 29, 0,214,228, -106,172,174,163,168,203,171,107, 50,250,180, 17,213, 80, 75, 36, 50,168, 33,128,146, 39, 40,224, 48, 36, 16, 25, 72,184, 36, 30, -160,219, 22,246, 95, 93, 77,154, 80, 80,230, 84,110,100,163,204, 97,138,120,152,130,165,163,153, 22, 68, 37, 88, 6, 82, 85,129, - 32,128, 71, 66, 47,133,165,165,165,173, 92,110, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105, -105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,107, - 3,168,110, 45, 6, 60,249,116,122, 75, 21,123,182,183, 5,239,118,155, 75,181, 41,174, 85, 12, 9, 92,174,168,197,170, 85,150, -166,169,212,105, 67,194, 32,183, 54,108,117,130,164,229, 32, 40, 29, 12, 12,103,154, 90,104,166,239, 21, 38,143, 91,167,219,119, - 13,169,123,209, 43,245,152, 83, 39,208,233, 9,165, 83, 46,121,213,134, 41,225,159,126, 83, 12, 88,181,170,177,130,134,188, 97, -151, 38,251,171, 42,228, 95, 35,139,228, 86, 47,143, 95, 53, 54,130,157,111,109,119, 6, 76, 70,208, 28,118, 91, 44, 90, 40, 45, -183,221,106, 77, 58, 85,222,220,217, 43, 74,114, 75,108,197,113,213, 99,149,182,214,178, 18, 70, 6, 28, 29, 45, 88,232, 23, 37, - 18,231,136,236,202, 36,244, 76,110, 60,135, 33,205, 97, 77,191, 18,125, 54,115, 56, 47, 83,234,212,201,141, 55, 38,149, 80, 64, - 82, 10,216,146,211, 78,164, 45, 36,160, 5, 2,111,154, 24, 24, 90, 90, 90, 90, 24, 24, 90, 90, 90, 90, 24, 24, 99,120,143,168, -110,117, 51,103,174,233, 91, 65, 29,201, 23,200,138,203,116,255, 0,119,109,167,170, 12, 69,114, 67,104,169, 72,165, 50,240, 40, -118,166,136, 69,226,200, 32,144,175,137, 0,184, 17,174, 20, 60,223, 25, 18, 95,121,199,215,190,238, 72, 83,138, 83,202, 92,139, -187,156,186,165, 18,178,175,210,126,183, 54,117, 36,133, 36, 40, 16,160, 8, 61, 8, 35, 32,253,218,208,158, 40, 56,198,176, 54, - 85,185,246,165,163, 22,151,119,238,105, 66,153, 92, 54,212,151,168,214,187,171, 78, 67,245,249, 12, 43,244,179, 83,148,148,194, -109, 65,206,185,121,108,167,148, 47,157, 60,116,224,190, 27,204, 99,139,140, 56,175,196,124,203,131,114,188,170, 14, 66,193, 75, - 56, 17, 77, 38,167,144,114, 96,182,185, 42,165,190,146, 16, 51, 50, 70,132,233, 84,102,199, 72,120, 15,198,220, 77,151, 75, 55, - 7,112,151,134,185,103, 26,102,153,172,252,246,158,170, 2,101,134, 61, 49,198,121,211,223, 68,116,145, 17,172, 23,210,170,242, - 53,139, 51,170,227,143,215, 53,223,196,133,153,238,191,194,219,167,117,237,195, 59,196,247, 52,214,107,151, 20, 5,201, 13, 99, -196, 83, 45,200,148,149, 45, 41, 42, 0,144, 49,147,140,231, 88,195, 91,199,188,114, 93,109,134, 55, 39,112,100, 60,226,194, 90, -101,171,158,186,235,142, 44,159,133, 40,109, 50,201, 90,179,216, 0, 78,177,155,198,244,186,247, 18,225,151,114, 93,181,137,181, -218,221, 69,209,207, 34, 82,202,131,105, 39, 13, 68,134,194,112,136,145, 17,156, 33,166,210,148, 36,118, 25, 36,157,221,188, 47, - 45,145,246,104,112,186,239, 19, 59,221, 70, 93,217,123,214,159,133, 73,179,173, 8,106,140,213,106,227,187, 42,177, 94,153, 78, -181,233, 18, 37,182,177, 72,167,177, 22, 51,207,212,167,150,214, 25,110, 59,132, 37,229,170, 52,119,121, 7,194,159, 15,120,203, -198,222, 60,159,134,248, 23,136, 51,106,108,146, 23, 75,212, 85,212,201, 45, 66,164,141,162, 37, 49,195, 36, 81, 52,243,178,187, - 44, 97,214, 56,145, 92,188,204,177,150,110,196,241,107,196,110, 10,240, 51,128, 32,226,126, 62,225,252,162,167, 58,153, 28,251, - 61, 37, 52,112,211, 51, 70,161,230, 97, 36,209,203, 42,211,192,172,138,210, 20,105, 37,118,141, 82, 21,105, 2,174,163, 72,218, -189,222,170,162, 69,126, 85,135,123,206, 76,183, 23, 46, 77, 77,218, 13, 81,227, 33,199,137, 91,146, 29,120,199, 37,106, 82,148, - 73, 81,238, 73, 58,203,118, 91,127, 55, 47,135,155,149,114,173,233, 18, 19, 1,201, 8, 23, 5,159, 86, 18, 27,166,212,210,217, -229, 80,122, 50,192, 84, 10,130, 81,144,135,219, 1,196,246, 80, 91,101, 77,171,150, 85, 47,164,143,198, 35,151, 97,170, 81,118, -183, 97,169, 54,130, 37,133,179,102, 61,111, 92, 53, 14,120, 40, 95,195, 22, 93,192,171,133,185, 46, 62,166,176, 22,235, 65,161, -204, 74,144,218, 6, 18, 59,121,195,151, 16, 59, 31,237,121,225,250,232,188,108,251, 74, 62,216,241, 35,181,232,138,205,221,106, - 37,246,165,173,185,210, 97,201,126,152,244, 42,139,108,182,186,213,159, 85, 16,103, 34, 50,222,109, 50, 33,200,136,182, 92, 7, -194, 14,201,234,207, 16,126,128,222, 38,248, 71,147,143, 16,120, 59,138,106, 38,207, 50,127,174,217,162, 46,210, 29,204,124,216, -156,104,105,141,227, 9, 42, 77, 79, 51,176,134, 89, 64,146,237,200,222, 28,127,180, 43,194,191, 25, 51,195,225,207, 24,112,181, - 60, 89, 30,113,245, 32, 50,202, 17, 98, 29, 36, 17, 76,191, 88,176,139, 72,205, 19,193, 81, 10, 35, 77, 20, 76, 99, 32,118, 27, - 96,248,137,177,183,250,218, 21,123,106, 66,161,213,225, 37,166,235,214,228,213,160, 84,232,242,156, 78, 64,113, 41, 56,147, 13, -101, 43,240,159, 71,192,224, 65, 7,149,105, 90, 19,106,226, 39,139,222, 29,184, 78,110,198,145,196, 38,229, 82,246,206, 6,226, -214, 42, 20, 27, 86,171, 91,137, 84, 93, 38, 85, 78,151, 17,153,211, 89,157, 82,131, 5,214,105, 13,162, 43,237,171,196,148,182, - 91, 86, 72, 74,138,129, 26,224,102,199,110,133,115, 99,247, 86,135,116,199, 84,134, 26,129, 81,250,170,231,166, 5,148, 9,180, -119, 95, 17,234,144,223,108, 28, 41,230,185, 75,173,103, 33, 47,197, 65,236, 8, 56,167,210,118,170,198,173,240,251,194, 53, 82, - 35,168,126, 52,237,202,189, 36,178,235,106, 10,109,214,222,179,169,238, 54,226, 20, 58, 41, 37, 10, 4, 31, 67,171, 87,232,151, -199,112,248,245, 61, 22, 67,196,119,203,243,234, 9,141, 61,127,179,133, 66,234,105,230,150, 10,168,209,213,213, 57,175, 11,164, -177,216,133,120,223, 78,133,116, 11, 85,125, 48,120, 26,127,163,229, 30, 99,196, 92, 52, 23, 49,200,107, 97, 90,156,188, 84,150, -112,140, 42, 96,138,162,146, 87, 70, 70,147,148,147, 35,197, 32, 96, 89, 36,143, 86,182, 71, 38, 80,214, 61,247,102,238,101,169, - 68,190,118,250,231,162, 94, 86,117,203, 5,186,157, 2,229,183,106, 17,170,180, 90,196, 7, 74,146,220,186,125, 66, 35,138,110, - 83, 5, 72, 80,230, 66,136,202, 72,238, 8,214, 89,168, 64,112,175,237,189,221,253,134,225,159,102,120,123,225,163,133,105,251, -189, 82,218,155, 26, 53, 58,249,186, 43,172, 93, 53, 88,104,168, 59, 62,163, 61,244, 83, 40, 54, 52,101, 57, 18,156,216,146, 0, -149, 42, 82, 84,242,185,200,142,216, 71, 50,250, 53,193,103,210, 48,176, 55,151,114, 45,253,161,226,123,106,154,216,235,138,230, -171,179,111,210,175,154, 45,102, 69, 70,198, 98,189, 45,246,226, 66,166, 92,208, 43, 49,218,153,107, 54,228,197,120, 94,244,183, -101, 50,219,175, 32, 72, 17,218, 11,121, 61, 57,156,120, 63,198,153,119,233, 74,154,108,168,214, 80, 80, 73, 45,180,205, 3,212, -154,116,102,229,204,244,233, 33,144,107,140, 7,210, 20,181,143,217, 29,185,103, 35,241,187,128,243, 63,209, 20,149, 89,184,162, -204,179, 40,225, 7, 84, 53, 9, 74, 42, 93, 19,153, 2, 84,188, 98, 35,203,145,140,122,139,232,184,251,102,226,253,250,171,113, - 37,195,245, 6,251,107,107,171, 91,211,182, 52,173,200,122,165, 79,163, 51, 98,207,189,104, 17,110,183,106,213,101, 50,154, 93, - 53, 20, 39,167, 9, 42,157, 33, 82, 99,134, 90, 13,243,184, 95, 72, 64, 60,195, 47, 80, 32,128, 65, 4, 17,144, 71, 98, 53, 2, -158, 50, 84,211,191, 72, 26,128,243, 1, 10, 14,113, 65,195,147,232, 82, 80,159,137,193, 34,193, 91, 78,246,248,156, 5, 45,144, -174,224,164, 16,122, 13,118, 87,143, 15,111, 68, 62, 31,247, 89,238, 25,120, 83,218,134, 55,231,120,232,117, 24,214,189,203, 90, -170, 59, 86,145,107, 83,239, 39, 22, 24,122,204,183,168, 86,222, 39,222, 53,230, 36, 56,219, 82, 84,212,136,236,177, 41, 11,138, -145, 33,196, 56, 91, 91, 48,240,167, 51,118,225, 88,120,116,201,154,212,103,249,106,102, 51,243, 57,112,197, 76,172, 19, 86,169, - 89,130, 8,193,123, 6, 98, 25,182, 0, 19,182, 17,203, 60, 97,202,145, 56,190,163,137,196,121, 61, 47, 14,230,178,101,148,252, -190,100,210,213,186,151,211,162, 37, 82,237, 35, 4,185, 84, 5, 84, 92,179, 1,190, 36,133,165,168,139,220,190,218,255, 0,106, -111, 13,237, 80,239,190, 41,184, 29,183,169, 27, 89, 90,168, 69,138,228,225, 66,187,237, 23, 16,167,193,117, 20,246, 46, 35, 90, -169, 70,163, 85,156,101, 14,120, 77, 84, 34,149,172,182,172, 54, 74, 84, 7, 85, 46,223,109,143, 13, 22,231, 5,182, 47, 26,148, -171,102,247,187,237, 43,183,112,233,251, 83, 88,178, 40,166,138,205,225,100, 95, 50, 40, 85,218,228,250, 85,194,221, 66,123,108, -120, 76, 51, 65,115,145,214,150,161, 37,154,132, 89, 13, 39,195,116,242,177,215,248,105,197,180, 35, 47,120,168,226,205,105,243, - 57,189,158, 25,168,170, 33,169,137,167,177, 60,146,241,185, 8,246, 6,193,244,130, 65, 0,146, 8,196,131, 46,241, 91,131, 43, -206,100,147, 87, 77,147,212,229, 48,251, 76,240,215,211, 79, 73, 50,211,220, 14,112,142, 68, 5,227,187, 45,202,106, 32, 16, 72, - 0,223, 29,148,210,212, 92,183, 35,233, 31,162,243,160,209,233,124, 25,112,161,184,187,163,185, 51, 34, 63, 58,227,131,120, 83, -170,147,233,118,147, 44,202,113,150,152,250,163,111,196,153,119, 10,221,142, 27,116,188,153, 48,153, 96,159, 12,248,202, 37, 72, -198,248, 54,250, 69,151,109,251,190,214,214,200,241,107,178, 86,230,220,166,238,185, 96,217,113, 46,235, 45, 87, 21, 53,219, 86, -231,169,204, 77, 62,159, 26,239,181,110,153, 50, 30, 76, 37,212, 94,142,195,174,178,251, 78, 69, 46,135, 23, 29,196,133, 99,108, -248, 71,199,171, 65, 85, 94,249, 46,143, 99, 86,119,128,205, 7,180,136,210,247,113, 0,144,200, 87, 98, 84, 91, 83,129,116, 86, - 4, 95, 68,120,211,225,211,102, 52,121,116,121,233,147,219,157, 99,142,160, 83,212,123, 33,145,237,166, 51, 80, 99, 17,134,243, - 0,198,250, 99, 38,210, 50,144,109, 43, 29,120,113,198,217,109,199,157, 90, 91,105,164, 45,199, 28, 89, 9, 67,109,161, 37, 75, - 90,212,122, 37, 33, 32,146,124,128,215, 14,253,164,222,219,221,157,224, 86,233, 59, 61,101,218, 15,111, 86,249, 34,155, 14,165, - 92,161, 49, 88, 69, 18,210,176, 89,169,199,110,101, 41,155,170,176,220,103,222,151, 90,126, 19,172,190,154,124, 86,130,209, 30, - 75, 79, 63, 37,143, 17,182,220,230, 77,175,244,142, 56,132,142,220,122,222,253,112, 91,245, 86,205, 92,140,191, 79, 85,221,100, - 38,245,165, 74,102, 61, 69,151, 99,183, 46,153, 83,187,226,187, 77,174,184,128,224, 80,100, 59, 27,198, 13,148,165,214,201,230, - 8,229, 94, 22,113,190,113,150, 83,230,244,153, 69,168,170,198,168,121,147, 65, 20,147,169, 23, 6, 24,228,145, 93,245, 13,211, - 97,172, 88,173,193, 4,175,156,120,191,192, 25, 38,109, 81,146,214,231,119,174,163, 58,103,229, 65, 81, 52, 84,237,123, 17, 52, -177, 70,232,133, 78,207,185,229,155,135,210, 65, 2, 71,219, 95,199,191, 8,187,217,187,147,118, 59,104, 55,194,208,220,189,198, -166,208,234, 87, 13, 70,153,102, 59, 46,189, 76,133, 76,164,205,137, 79,158,183,238, 88, 81, 85, 78, 18, 91,151, 54, 58, 11, 41, -148,167, 73, 89, 33, 4, 37, 68,109,254,160, 19,244,127,110,123,126,214,227,115,113,175, 26,237, 82, 45, 14,212,183,182, 43,113, - 46, 74,213,102,160,164,196,131, 73,183,233, 85,139,126,167, 62,165, 57,121, 34, 52, 86, 32, 48,235,174, 30,161, 9,104,247,198, -186,103,185, 63, 72, 83,125,183,147,120, 38,237, 23,179,215,133,198,183, 45,182,164, 77, 98,145,112,222, 16,174, 10,229,197,113, -192,167, 58, 82,245,199, 30,212,183,230, 68,102,215,162, 45, 1, 42, 11,168, 75,116,161,181,165, 79,248, 14, 57,225, 53, 36,226, - 95, 8,115, 26, 94, 38,172,201,120,104, 61, 93, 6, 89, 75, 4,245, 53,117,114,195, 4, 81, 25, 67,146,100,145,185,104,163,202, - 74,160,212,224, 2, 73, 32, 18, 34,220, 41,227, 94, 89, 89,194,148, 57,247, 21,178, 81,102, 57,181,101, 69, 61, 45, 29, 20, 83, -212, 77, 48,132,160, 2, 56,151,153, 35,155,184, 12,231, 66, 18, 85, 64, 4,128,101,135,165,168,156,219,158,223, 30, 44,184,114, -221, 75,123,111,253,161,252, 36, 55,183,244, 42,247,131, 37,117,235, 78,155, 93,160, 92, 80,232,239,201, 68,119,171,244,186,109, -102,169, 54,159,121,211,227, 40, 44, 58,212, 57,113,220,230, 73, 71,139,226, 0,218,186, 89,198, 87,182,211,135, 30, 14,235, 27, - 75, 6,163,102,223, 59,171, 70,222, 93,176,167,238,197,161,117, 88, 18, 40, 31, 82,200,182,106,181, 25,180,248, 5, 70,177, 61, -135,125,225,126,226,183, 10,124, 49,200,151, 18,149,128,224, 82, 83, 20,171,240,211,140,105,171,114,250, 40,178,177,152,182,106, -143, 37, 52,148,179, 67, 60, 19,172, 66,242, 24,230, 71,208, 74, 13,202,146, 26,219,128, 70,248,152,209,120,173,192,245,116, 57, -149,124,217,177,202,215, 39,120,227,171,138,178, 9,169,234, 41,218, 83,166, 46,100, 14,156,192, 28,236, 25, 67, 45,246, 36, 29, -177,217,173,112,163,112,253,133, 28, 55, 95,188,105,212,248,162,173,202,171,215,108,187,186,163, 93,190, 47,125,152,175,202,157, - 87,160,214,183, 90,175, 85,141, 82,118,228,122,179, 46,114,165,201,181,228, 73,126,179, 50,101, 17,245, 57, 25,115, 93,105,180, - 56, 41, 5,116,160,202,240,191,237,190,220,158, 50,248,231,219, 77,158,218, 29,130,147,111,112,189, 93,145,119,193,184,247, 10, -229,165,214,170, 87,151,189,209,182,206,237,185,233,142,205,168,210,100,170,143,106, 52,237,203, 71,166, 71,110, 59,134, 83,174, -180,249, 30, 48,117,228, 33,185, 31,161, 92,200, 74,187,115, 37, 42,199,166, 64, 58, 74,170, 30, 49,240,218,181,169, 26,169,242, - 74,252,226,140, 25, 82, 41, 81,156, 65, 43,200,129, 36, 40, 91,149, 48,104,217,133,136,150, 59,130, 25, 75, 17,133,169, 38,224, -127, 20,232, 22,181,105, 35,207,242,236,146,184,136,164,154, 23, 84, 53, 16,164,110, 94, 33, 32, 83, 44, 44,178,170,155,131, 20, -182, 33,149,130,131,134,126,151,176,123, 71, 74,180, 27,176,226,237,253,162,205,158,136,126,226, 45,102,173,218, 59, 86,224,136, - 80, 27, 49, 69, 13,184, 98, 40,143,200, 0,228, 13,114,224, 99, 24,212, 4,189,180, 92, 57,109,223, 10,156,122, 93,182,174,205, -192,141,105,218,119, 45,169,102,238,133, 50,218,161,145, 14,159,102,213,171,255, 0, 88, 69,169,211,168,140,199,193,165, 66, 53, -106, 19,243,227,176,217, 74, 34,138,178, 89,140,150,163, 54,195, 77,254,136, 21, 90,173, 54,133, 75,169, 86,235, 51,225,210,168, -244,120, 19, 42,149, 90,165, 66, 67, 81, 32, 83,105,180,248,238, 75,157, 62,108,183,214,148, 70,136,204, 86, 93,113,199, 22,160, -132, 33,181, 41, 68, 0, 78,191, 57, 62, 35,175,107,151,218,161,237, 50,184, 37,109,235, 50,196, 29,229,220,202, 77,141,183,190, - 43, 14,184,170, 30,215, 90, 80,163, 80, 97,220,243, 97, 43, 10,140,219,118,133, 14,117,126,160,198, 73,109,217, 50,144,146,162, - 19,155, 39,192, 39,174,139, 62,226, 12,218,122,167,135, 34,160,161,145,235, 29,217,140, 69,217,213,208,184, 38,197,194, 71, 52, -154,236, 88, 42,184,189,156,131, 86,125, 35,211, 47,155,135,120,111, 38,167,164, 73,184,135, 50,204, 35,142,133, 17, 84, 74, 17, - 81,146, 64,132, 0, 66, 51,201, 4,122, 1, 10, 89,144,218,233,113, 61,206, 11,119, 14,189,187, 28, 40,240,239,185, 23, 75,138, -118,228,190,118, 83,107,110,250,243,171, 32,173,202,197,203, 99,208,235, 85, 53,168,134,209,146,102,205,124,159,129, 61, 79,234, -167,176,217,253, 55, 59, 75,100,210,182,231,110,237, 11, 38,133, 20, 65,162,218,246,245, 30,223,164, 66, 7,152, 68,165, 81,169, -241,233,212,232,193, 88, 25, 13,196,142,210,123, 15,213,211,141,170, 34,178, 72,102,172,170,154,158, 62, 77, 60,178, 59, 34,126, -202, 51, 18,171,255, 0,106,144, 62,236,116, 69, 12, 83,193, 69, 71, 5, 76,188,250,152, 98,141, 36,127,219,117, 64, 29,191,238, - 96, 79,223,133,168,165,123,119,125,170,238,209, 91,175,240, 39,195,117,192,235,151, 29, 77, 14, 81,120,135,190, 40, 15,243,187, - 74,135, 49, 41,105,123, 57,111, 76,138,162,181,214,165, 33,194, 46, 23, 26, 41, 49,152, 90, 40,225, 78, 63, 38,166,204, 61,237, -246,205,251, 82,224,240, 79,182,174,108,238,209, 85,161,203,226,135,116, 40,142,253, 82,227, 78, 37,255, 0,226,146,206,156,167, -161,191,184, 53, 54, 18, 8, 53,247,252, 41,108, 80, 99, 56, 82, 61,229,165,212,159, 75,177,161, 8,147,185, 93,236,136,246, 94, -213,106,214,149,199,198,255, 0, 17,212,217,179,238, 10,173,173,115,221, 27, 61, 64,185, 22,228,217,136, 85, 70,147, 62,106,247, - 98,229, 19,146,183,100,220, 18,214,234,221,164,120,203, 82,154,110, 66,170,174, 5,201,122, 11,177,110, 14, 3,225,236,179,135, -178,212,241, 23,140, 33,215, 71, 11,133,202,168,154,193,235,170,175,228,151, 73,191,212,196,192,178,146, 8, 37, 76,132, 21, 68, - 89,105, 31, 17,120,151, 54,226,108,214, 79, 12, 56, 34,126, 93,116,209,151,206, 43,214,229, 40, 41, 45,231,132, 50,145,245,242, -169, 10,202, 8, 32, 50,196, 8,105, 29,161,210,223,163,211,255, 0,132, 11,255, 0,169, 75,243,255, 0,199,236,141,116, 43,233, - 74,255, 0,148,224, 99,255, 0,154,226, 91,255, 0,107, 96, 53,207, 95,163,211,255, 0,132, 11,255, 0,169, 75,243,255, 0,199, -236,141,116, 43,233, 74,255, 0,148,224, 99,255, 0,154,226, 91,255, 0,107, 96, 53,106,102,159,250,197,112,231,255, 0, 5, 39, -255, 0,208,175,197, 59,147,255, 0,234,195,197, 95,252,124,127,255, 0,161,150,227,167,222,201,206, 30,246, 78,244,224, 27,134, -234,253,209,181,155,125, 93,172,206,219,232,206,205,170, 85,108,219,118,161, 80,150,239,214, 85, 36,151,101, 76,151, 78, 91,146, - 29,229, 74, 71, 50,212, 78, 0,235,174,142,127, 36,254, 28,127,249, 20,218,239,253, 65,181,127,255, 0, 21,168, 67,236,206,242, -251,107,106, 27, 11,183,118,135, 14,118,230,248,218,123, 35, 96,219, 49,169,246,138,246,239,108,225, 81, 63,132, 20,246, 12,185, - 95, 92,181,113, 85,232,203,170, 93,234,124,188,224,255, 0, 4,146,236, 21, 45,180,166, 60,100, 57,144,172,147,102,189,184,158, -209,254, 22,247, 41, 54,175, 17, 19,170,123,167, 72,160, 84, 35,193,188,246,187,121,108,216, 86,109,253, 75, 99,149,165,201, 68, - 43,134, 21, 2, 5, 86,143, 93, 49, 75,106,105, 85, 86,234, 49,190, 62,117, 68, 87,136, 87,168, 78,113,225, 63, 21,230,217,158, -127, 91,147,241, 53, 5,117, 75, 84,212,207,236, 81, 87, 72,103, 68,121,153,145, 24, 4,229,164,150,101, 82,174,202,138,219,115, - 58, 98,193,200,252,101,224,252,151, 41,225,202, 12,239,133, 51, 44,186,145, 41,105, 96,246,233,178,248,197, 59,201, 28, 17,171, -186,157,124,201, 35,186,179, 6, 68,121, 25, 70,174, 95,164,237,173, 75, 62,218,177,233, 17,168, 22,157, 22,153,111,209, 33, 37, -105,135, 73,163,193,139, 77,167, 68, 67,142,173,231, 17, 26, 20, 54,144,211, 9, 83,206, 56,178, 16,144, 10,156, 82,143, 82, 78, -178, 93, 49, 28, 53,113, 19,183, 28, 85,108,189,139,190,123, 87, 80,118,125,159,125,210, 5, 74, 19,114,219,105,138,157, 46, 99, - 18, 31,167,214, 40, 85,152,204,188,226, 34,214, 96, 85,226, 78,135, 45,180, 56,227,105,126, 18,252, 55, 93,108,161,197, 62,250, -231,250,168,106, 41,170,106, 41,234,227,104,170,224,119, 73, 85,193, 14,178, 43, 21,117,112,119, 12, 24, 16,215,222,247,190, 58, - 70,146,122, 90,170, 74,106,154, 41, 18,106, 58,136,209,225,120,200, 40,209, 58,134,141,144,141,138, 50,144, 84,141,172, 69,176, -180,180,180,180,134, 54, 48,180,180,180,180, 48, 48,180,180,181,192,111,104, 5,251,125, 80, 56,143,220,198, 45,253,213,169, 89, - 9,183, 54,167,110,238, 27,118, 11,123,151,122, 90, 50,220,172,139,138,158,153, 72,178, 45,251,125,102, 37,197,116, 63, 9, 82, - 82,182, 38, 6, 89, 68,111, 26, 95,138, 30,142,216, 47, 57, 30, 78,249,221, 99, 81,164,226, 6, 84, 47,168,169,111,215, 68,181, -129, 7,171,130, 78,246, 0,236, 78,216,215,169,168, 20,209,243, 10,234, 23,181,175,110,196,255, 0, 44,119,231, 75, 81,244,103, -138, 29,229,219,186,190,226, 38,204,169, 55,100, 67,220,238, 34,247, 45,250,213,217,125, 65,164,205,147,104,206,165,216,118, 61, - 94,129,106,212, 95,186,100,197,162, 91,207, 73,151, 86,156,153, 30, 59,169, 82,141, 53,244,196,109,181, 55,135,114,241,198,191, - 22, 21,107, 15,123,247, 58, 21,239,182, 80, 41,252, 61,195,225,246, 85, 90,221,164,217,177,110, 10,125,254,238,232, 42, 29, 18, -168, 34,221, 38,172, 62,174,129,245,162, 36,204, 82,163, 52,225, 82,101,134, 98,190,203,109, 37,110, 59,183, 5,230, 62, 70, 90, -152, 57,114,114,192, 44,206, 14,169, 36, 72,144, 16,168,246,213, 43,132, 6,228, 91,204,218, 84,223, 8, 12,198, 29,193, 70,184, -191, 64, 58, 0, 88,157,200,232,162,231,111,112,185,199,119, 52,181, 31,219,163,138, 13,215,187,247, 63,109,175,153, 87,125, 18, -185,126,217, 23,151, 19, 82,104,252, 60,211, 45,201, 52,233,150, 71,240, 34,193,174,162,217,167,220,143,211,222, 93, 66,233,145, - 84,147, 75,108,134,220, 72,230,113,130,136,203, 97, 74,115,194,187,218, 60,116,241, 71, 94,159,183, 22,253, 63,112, 54,166,175, - 63,117,119, 39,104,237,104,115,229, 80,109,233,245, 11, 49,235,225,117,154,109,106,149, 86,182, 45, 90,232,117,138, 91, 85, 35, - 79, 91,126,254,228,106,167, 37, 61,109,158, 66,226,214,144,220, 23,153, 8,213,214,162, 27,132,212,225,139,174,147,174, 69, 33, - 78,131,172, 1, 25,109,118, 10,194,252,179, 32, 1,136, 25,140, 58,136, 42,221,108, 45, 99,125,129,245,219,115,107,117, 29,237, -142,245,233,107,147,209,223,222, 43, 46,151,189,123,171, 87,168, 91,247, 45,193, 96,238,236,107, 86,163,184, 18,175, 13,204,135, - 26,223, 51,155,219,155,122,229,185,225,109, 4,121,171,160, 11, 66,149, 6,229,173, 86, 75, 18,101,144,211, 81, 94, 47, 30, 86, -130,245,116,153,197,253,205,104,175,125,224,212,119, 98,196,186,104,182, 78,217,238,236,253,159,220, 25, 80,109,250, 84, 61,204, -189,109, 75,111,110,106,180, 88,240, 28,129, 37, 16, 46,122,140, 59,158,240,173,209,164, 71,165, 4,181, 37,202, 9,253, 10, 30, - 67,199, 90, 31,253,157,169,144,255, 0,100,153, 42,109, 96,108, 24, 93,173, 25, 33,108, 27, 96, 37, 66, 3,232,144,141, 71,151, -101, 98, 20,246,180, 31,222, 41, 75,252, 58,110, 5,250,122, 30,151, 3,109,247, 24,234,110,150,185,121,125,113, 27,190,246,141, - 14,226,220,138, 85,122,149, 95,137, 79,221, 29,192,219, 42, 86,219,187,104, 69,247, 57, 66,135,195,181,213,186,212,122,171,149, -122,104, 85, 74, 93, 76, 92,212, 56,173,120, 13,169,182, 94,140,242,153, 95,134,178, 36,161,188,127,125,171, 86,214,225,238, 11, - 22,199, 16, 84,107,178,163,121, 39,108,124, 29,207, 68,141,169,183,108, 72,233,163,237,245,233, 92,170,211,106, 53,186,204, 89, - 52,202, 39, 35,139,138,182, 99, 49, 2,101, 90, 83, 81,212,194,240,184,239, 73, 25,143,134,171, 36, 66,194,104,254,198,161,110, - 97, 23, 14,138,202,199, 64, 11,164, 54,162,119, 6,214, 93, 86, 98,161,171, 35, 6,218, 79, 91,118,238, 9, 4, 11,239,126,158, -238,246,218,253,134,210,215, 23,168,252, 66,238,173,122,152,237,253, 54,243, 85,110,231,171, 76,225,138,243,161,236,203, 18,102, -193,102,123,213,219, 34,129, 34,173, 62,218,133, 2,172,137,173,218,242, 46,180,203,140,244, 86, 80,236, 39,101,213,208,220,211, - 33,228,132,186,236, 80,248,135,221,139,146,237,218,187, 18,214,222,123,102,243,129,185, 51,246,200,220,219,133,110,217,182,220, -151, 54,246,175,118, 89, 27,207,114,220, 59,126,196, 88,238, 61, 5,154,162,127,128,148, 71,161,179, 83, 67,181, 56, 13,161,255, - 0,172, 27,152,151,144, 18,105,120, 98,178, 37,118, 51,199,104,151, 83,147,204, 1,108,138,237,184, 67,125, 33,173,125,181, 16, - 66,106,107,129,133,173,141,136, 1, 79,155,167, 77,247, 32,119,239,248,119,182, 58,147,171, 69,118,187, 74,182,233,114,107, 21, -153,105,135, 2, 47,132,149,185,225,188,251,206,189, 33,212, 71,139, 18, 28, 72,205,173,217,211,223,148,235, 45, 49, 29,148, 45, -231,222,121, 13, 52,133,184,180,164,182, 60, 63, 94, 23, 13,249,180,118,173,203,117,202,141, 58,225,125,219,146,149, 84,168, 68, -134,221, 57,154,140,139,106,235,174,219, 34,165,238, 12,168,183, 13,217, 13, 81,219,121,198,219,253, 26, 28,125, 73,108, 37, 1, - 41, 13, 62,232,111,214,218, 88, 87, 53,221, 90,189,235,241,103, 84, 54,214, 35,223,192,237,191,166,243,212, 43,146,234,168,162, -210,230,214,174, 85,210,219,108, 4, 84, 20,139,146, 5, 54, 10,228, 56,219,108, 55,239, 43,109,212,137,238, 41, 44, 50,192,240, -207, 45, 59, 88,201, 19,178, 27,116,186,146, 13,137,182,215, 29, 72, 27,117,198,210,176,101, 86, 29, 24, 3,251,247,199,221,233, -222,106,181,159, 75,167, 84,174,234, 93, 66,210,177,231, 69,184,235,115,168,180, 74,161,155,188,183, 37,187,104, 81,151, 91,175, - 70,163, 80, 40,200, 81,166, 32, 83, 84,169, 82,149, 18, 91,178,216,139, 78, 83, 11,126,159, 42,107, 42,103,136,187,179,237, 34, -226,147,119,235, 63,197,223, 8,251,124,189,158,219,184, 97, 16, 40,176,233,212,196, 92,251,157, 84,166,150,212,167,102,185, 76, -180, 34, 77,106,221,117,114, 22, 2, 25,135, 45, 15, 52,181, 45,110,204,125, 71,175,108,182, 23,109,174,187,130,169, 84,222,157, -223,125,186,149,249,123, 65,247,101,210, 60,100,212,104, 54, 69,155, 36, 7,224,237,133,176,149, 2,203,148,166,146,166,158,173, -205,109, 3,235,170,160, 43, 86, 98, 69,134,211, 59, 51,104,216,150, 77,129, 77,110,141, 99, 90, 54,213,159, 74,109, 41, 66,105, -246,205, 18,155, 68,137,132,126,169, 91, 20,232,205,165,197,117, 57, 82,129, 81, 36,146, 73, 39, 78,217,109, 94, 95,150, 60,146, - 85, 80,254,145,169, 22,208, 11, 40,141, 58,223, 82,180,114, 93,186, 91, 96, 71, 98,164, 27,234,212,195, 81, 80, 21, 35,159,217, -227,223, 81, 0,150, 61, 45, 98, 25,108, 58,223,168,247, 17,136,175,109,165,111,136, 46, 22,110, 90,253,251,188, 55,190,238, 65, -226, 39,118,227, 73, 22,188, 43,214,173, 93, 15,170,216,230,151, 29, 53, 11,198, 13, 89,199, 26,118,108,119, 24,169, 38,135, 69, - 37,232,207,174, 19,213,119,127,239, 68, 64,213, 43,151,138,189,231,148,233, 93,203,191,247,220,103, 10,148,232,142,246,226, 85, -105, 32, 96,149, 21, 51, 79,141, 84,100, 37, 35,175, 68, 55,129,142,128,107,190, 92, 81,109,158,214,113, 35, 67,184,108,237,202, -102, 60, 43, 2,198,163,212, 42,247, 21,248,211, 49,155,173, 80, 37,183,202,252,118,173,218,155,209,221, 83, 79,170,117, 53,160, -227, 77, 36,169,228, 67,121, 32,178,242,233,207, 57,194,234, 71, 15,220, 39, 90, 75,109,193, 77,191,119, 2,124, 94, 96,220,151, -161,219,182,108,103,243,144, 18,185, 21,119,174, 89,106,100,163, 0,129,224,171,201, 60,131, 83,252,135, 54,165,204,160,150,105, - 50,197,106,184,152, 41, 60,176,194,223,170, 17,180, 5, 22, 29, 67, 58,155,146,119,189,240,193, 93, 73, 45, 59,170, 45, 73,228, -176,184, 26,172,111,176, 36,139,220,223,181,129,216, 91,107, 91, 29, 21,246,100,113, 47,186, 91,235,125,110, 4, 59,162, 92, 75, -222,214,164, 89,244,136,116,189,196,146,195,109, 87,221, 69, 6,164,227, 77, 68,157, 83,101,164,170,228,142,252,250,245, 93,166, - 94,150, 12,132,127, 7, 30, 90, 93,113,183, 73, 87,102,245,197, 62, 8,247, 59,106,118,179,113, 23,103, 90,182, 36, 75, 2, 30, -235, 85,168,116, 25, 13,199,172,212,107, 14, 87, 43,209,216,152,205,189, 33,239,126, 9,109,170,147,105,114, 75, 75, 16,216,138, -219,177, 93, 46, 62,219,134, 27, 74, 71,107, 53, 4,226,104,132,121,180,197, 40,197, 20,114, 5,101, 80, 0, 13,113,230,112, 20, -149, 23,107,139, 2,109,109,247,185, 47,153,107, 22,165, 75,205,206,101,184, 39,115,107,116, 27,128,122, 88,239,235,233,133,165, -165,165,168,254, 55,240,180, 29, 66,161, 2,147, 6, 93, 78,169, 50, 45, 58,157, 2, 59,178,166,206,154,251,113,162, 68,140,194, - 11,143, 72,147, 33,229, 4,178,202, 80,149, 21, 41, 68, 0, 6, 73,209,154,212,158, 53,182,250,255, 0,220,189,141,169,219,187, -118,235,139,169,181, 89,166,213,106,148,134,158, 12, 59,113, 81, 32, 51, 52,201,162,180,181, 16,149, 58,102, 59, 6, 74, 80,165, - 0,225,167, 6,243,149, 0, 88,184,159, 52,173,201, 56,123, 58,205,242,220,170, 76,242,191, 45,166,150,104,105, 34,254,242,162, - 68, 66,203, 18,216, 19,118, 35,162,171, 57, 23, 8,172,214, 82,253,194,249, 85, 14,121,196, 89, 38, 79,153,230,209,228, 89,126, -101, 83, 12, 51, 86, 75,253,221, 60,114, 56, 87,149,174, 85,108,160,245,102, 84, 6,197,221, 86,236, 52,131,138, 95,104, 4,186, -199,214, 54, 22,197, 77,122, 13, 40,151,161,213,183, 5, 41, 91, 51,234, 13,245,109,214,109,116, 44, 5, 64,138,174,191,225,138, - 1,245,164,254,133, 45,116,112,232,102,217,108,157,245,187,134,183, 88,166,198,146,138, 37, 30, 21, 78,171, 88,184,102, 54,243, -205,188,244, 72,207, 77,118, 44,101, 40,243, 79,168,186,180, 97, 88, 36, 32,185,206,226,129, 32, 43,100, 54, 19,129,203,238,248, -173,181, 55,114, 41,115,173, 91,118, 27,233,241,105,111,225,154,189, 85, 72, 80,230,100,242, 40,251,132, 63, 37, 44,159, 21, 64, -225,180,167, 62, 34,123,107,102,109,165,171,100,219,108, 91, 52,106, 68, 40,116,214, 97, 24, 34, 35, 12, 33,184,233,142,182,203, -107,104, 54, 7, 80,164,169, 92,196,228,168,168,149, 18, 73, 58,227, 46, 26,240,155,196, 15, 27,243,131,198,254, 48,212, 79,148, -100,169,175,216,178,205, 50, 64,197, 79,217, 84,129,142,186, 74, 91,129,173,223,251, 93, 72, 91,234, 0,172,216,237, 78, 38,241, -115,195,223, 3, 50, 97,192,254, 13, 83, 65,156,103,114, 20, 53,217,166,164,168, 64, 71,218,103,168, 81,162,174,168,169,109, 8, -159,217, 41, 75, 17,164,144,208,226, 44, 52,185, 13,195,169,211,165,188,142,118, 98,207,137, 33,212, 30,203,109,137, 13,184,226, - 8,249,165, 36,125,250,127,189,191, 59, 1,126,241, 15,193, 94,202,238,238,208,211,167, 93,244,109,151,184,170,119,101,215, 68, -161,176,236,233,235,179,175, 10, 4, 24,142, 93, 76, 66,140, 20,185, 76,211, 95,167, 69, 50, 66, 18,165,179, 30,166,244,130, 3, - 76, 60,164,211,226,127,101, 42, 59, 29,186,181,187,117,109, 62,187,118,168,251,213,155, 78,162,182,200,106, 93, 34, 91,202, 95, -186,135, 57, 66, 85, 38, 43,203, 84,119, 64,193,253, 26, 87,128,151, 18, 75,183,195, 79, 26, 53,221,151,166,139, 34,240,164,187, -122,109,226,148,224,141, 17, 46,182,154,189, 13,183,212,165, 72,102, 2,165, 31, 10,109, 61, 74, 90,213,238,238,148, 4, 41,106, - 40,113, 41, 37, 5,151,232,189,226,236,127, 70,191, 20,115,188,175,140,233,189,135,151, 83, 26, 73, 43,163, 50, 69, 61, 47, 62, - 45, 50,104, 12,254,207, 83, 5, 76,154, 39,141, 95, 65, 49, 74, 20,198,204,234,241,244,170,240,114, 79,164,247,132,249, 46, 99, -193,117, 94,220, 37,165,149,227,137, 29, 21,229,130,168,211,204, 26, 46, 97, 84,246,154, 89,233,163,215, 79, 35, 71,204, 2, 88, -139, 9, 21, 81,160, 87,169,110,253, 27, 78, 31,247, 14,201, 78,246,241, 53,120, 64,159,107,237,173,207,108, 82,237,139, 90, 69, - 85,167,160,179,114, 68,163, 76,149, 92,175,220,241,144,248, 79,137, 70,138, 26,139, 29,153, 56, 45,188,228,137, 73,109, 71,193, - 94,122, 95, 89,143,236,147,185,110, 37,110, 61,103,134,205,190,118,245,118, 71,214, 47,186,246,201, 80, 28,168, 63, 81,230,241, - 76,135,214,152, 94,233, 38,103,139,215,198,113, 69,124,221,121,181,134,239,223, 25, 43,190,109,119, 54,195,105,109,159,226,243, -110, 28, 97, 16,106, 24, 17,153,172,214,169,236, 0,134,169,158, 5, 63,244, 20,106, 55, 34, 82, 21, 29,165, 56,167, 82, 2, 22, -180,183,204,210,189, 25,241,187,233,237,225,100,220, 3,152, 80,112,253, 92, 57,166, 99,153, 70,182,130, 10,152,234,164,119, 86, - 89, 18, 33,201, 5, 97, 70,145, 87,153, 52,237, 25, 88,195,132,133,228, 42, 7,154, 94, 3,127,179,211,197,122, 79, 17,114,220, -207,136,233,166,203, 50,220,174, 70,250,249,233,164,165,141, 17,213,163,121,155,158,193,230,117,141,219,151, 5, 58,200, 30, 82, -133,230, 72,149,201,211,219,222,171, 18,185,121,221,181,168, 8, 8,131, 86,185,107,149, 40,105, 74,121, 64,139, 58,167, 42, 76, -127,132,143,135,244, 78, 35,167,207, 77, 71,183,193, 83,207, 4, 92, 7,166,161,226,120,232,185,171,137, 62, 46,121,194, 5,131, - 73,240, 82,160,174,160,134, 66, 7,221,173,145,216,173,173,169,238,230,227,208,109,120,108, 60,170,120,148,204,234,252,180, 33, - 69,184,116,136,238,161, 82, 57,156, 72,194, 30,120,132,178,214,123,173,224,113,202,149, 17,210, 31,105, 23,179, 6, 31,180, 15, -107, 54,119,111,211,186, 82,118,157, 59, 83,112, 85,238, 6, 95,131,103, 71,187, 17, 86, 21,122, 52,122, 72,130, 99,187,113, 83, -133, 57, 44,166, 58, 86,149,165, 78,133, 5, 20, 20, 12, 5,107,144,127,217,239, 11,228,156,117,155,248,159,196, 50, 53, 6, 69, - 81, 49,167, 14, 35,118, 89, 36,209, 81, 36,238,145,198, 25,217, 98,121, 98,141, 74,171, 13, 82, 58,223,200,246,236,191,246,140, -186,241, 7,135,185, 87,133,124, 53, 18,230, 60, 67, 79, 0,168, 49,153, 35, 86,142, 62,101, 52,112, 70,242, 72,200,138,210,199, - 20,210,176,118, 83,166, 56,218,223, 88,151,102,125,130,112,118, 42,169,192, 62,220,155, 3,248, 58,253,211, 14, 69,121,189,216, -141, 20,197,250,250, 61,248,229,122,168, 93,114,229,109, 39,197, 75,206, 82, 17, 78, 84, 37, 57,240,170, 2, 88, 75, 71, 8, 80, - 17,173,246,250, 13,156, 87,180, 78,224,103,100, 28,162, 63, 88,110,202,179, 25,220,245,218, 78, 69,118, 49,221,175,121,170, 25, -141,184,237, 53, 69,181,220, 41,161, 42,215, 76,222, 83,227, 38, 98, 92, 68,140, 74, 75,192,117, 38,227,250, 54,119,189,161, 79, -164, 73,216, 46, 46,110,123, 78,180,253, 25,154,101,232,154,149, 18,165, 73,135, 95,154,143, 16, 72,168,192,114,215,185, 18,237, - 62, 19,168, 82, 1,129, 35,223, 2, 20,149, 45, 50,202, 86, 27, 67,243,193,111,209,227,219,173,146,220,107,127,118,119,231,112, -164,239, 85,205,109, 84,218,174, 81,173,207,169, 81, 69,178, 35, 87, 35, 60,153, 16,234,149,118, 37,204,149, 42,232,125,153, 9, - 75,205, 33,229,199,142, 93, 0,191, 29,240,156, 31, 80, 50,110, 36,240,255, 0,133,248,167,136,120,250,159,140,167,206,102,204, -197, 81,139, 47, 20,147,199, 51, 60,242, 9, 52, 75, 52,159, 86,209,161, 80, 35, 44, 16, 5,210,199,204,186, 91,202,188,243,133, -252, 73,226,222, 17,225,159, 14,106,120, 26,159, 34,131, 42, 52,130,108,204,214,211, 75, 2,165, 60, 92,190,100, 48, 71,245,171, - 35,134, 38, 64,165,201,109,106, 60,175,173,120,101,186,226,227, 30,216,222, 31,145,113,169,212,222, 13,238, 7, 6,204,215,213, - 43,196, 18, 19,114,181,106,109,123, 85, 19, 47,197,202,132,164,212,146,231,141,205,215,196, 74,201,235,211, 90,121,178,118,150, -251, 86,248,244,118,209,176, 55, 14,149,181, 28, 67, 63,187,123,137, 77,165, 94, 87,124,150,160,183, 79,191, 68,251,137,138,172, - 71,101, 79,167,202, 75, 85,121,111,253, 99, 25,144,182,148,167, 95,150,150,144,124, 71, 18, 12,191, 55,139,216,145, 27,114,184, -246,164,241,181, 23,126,103,210, 85, 77,220,141,186,220, 36,237,202,118,242, 36,168,229, 86, 2,232,107, 69, 32, 92,230,240,109, - 65,169, 66,136,128, 94,247, 2,166,125,229, 68, 33,194,145,159,188,127,251, 8,246,135,139,155,230, 86,246,237,181,237, 81,216, -221,230,170,248, 18,174,153,244,186, 83, 85,171, 78,238,170, 68,109,180, 49, 90,169, 81, 81, 50, 35,244,171,136,165,166,146,236, -232,146,128,119,194, 75,143, 69,117,254,103, 75,214, 91,226,215, 8, 67, 22, 85,150,205, 86, 35,138,175, 35,134,138,121,205, 36, -147, 69, 73, 85, 26,176,229,203, 3,162,251, 69, 57,230, 48, 97, 30,180,109, 10,167,202,197,149,139, 52,240,103,141,106, 37,205, -243, 72,104,140,147, 80,241, 4,245,244,244,226,182, 40, 37,173,163,149,163, 60,200,170, 35,145,189,154,161,121, 42, 80,203,203, -117,214,204, 6,181, 8,220,174,226, 71,130,207,107,101, 91,105,167,218,220, 83,113,207,179,208,246,122,238,169,208,173,233,177, -183, 54,243,164,208,173,170,181,102,101, 69,135,109,234, 98,103,201,178, 88, 45,207, 85, 69,134,150,209, 67,168, 82, 61,221, 78, -173, 73,109,181,173, 58,117,197, 87, 1,155,253,192,167,179,178,235,160,238,229,199,101,215,173,141,200,226,147,102,174,107, 61, - 22, 93, 90,117, 86, 35,117, 8, 59,103,187,240,170,243,222, 92,168, 76,160, 38, 69, 61,202, 40,109,109,115,248,137,137,146,174, - 80,141,116,161,143,163,193,196, 46,228,213,168, 20,254, 34,120,219,187,111,155, 38,221,113,180,211,233, 77,199,185,174, 25,241, - 97,167, 8,114, 37, 29,203,202,228,122, 53,190,165, 48, 57, 82,234, 35,200, 8, 29, 60, 21,142,154,234,183, 19,126,200,187, 31, -124, 56, 36,218,238, 11,108,125,198,175,109,125,165,181, 87,181, 22,242,163, 87, 39,211,158,220,106,188,245,210,168,215, 85, 46, - 68, 42,129,170,215,224,171,196,147, 34,233,147, 37,110,182,234, 91,105, 81,195, 44, 70,109,146,148, 54,214,158, 34,228,185, 53, - 87, 15, 81, 71,196,212, 85,249,107, 87, 71, 81, 94,180, 57, 43, 81, 65, 18, 68, 85,227,149, 89,109, 43, 77,170, 53, 86, 9, 12, -154,144,144, 89, 2,128,238,210,120, 95,158,231,148,156, 75,152, 73,194,149,249,118,106,153,124,148,217,123,102, 25,242,215, 84, - 77, 36,193,146, 72,157, 90,240,164, 26,100,118, 66,243, 71,165,192, 96,175,172,152,216,127,163,207,182, 54, 85, 63,129, 26, 5, -213, 18,131, 1,186,245,225,121, 94,117, 27,146,168, 35, 51,239,213,105, 84,250,195,212,170,127,190, 73, 8, 11,121,152,244,248, -205, 54,202, 20, 74, 90, 10, 95, 32, 5,107, 39,133, 62,218,203,122,129,108,123, 96,109,245,210, 41,177,105,109,213,209,195,221, -118,176, 97,180,134, 12,218,147,149, 56,208,159,168, 62, 91, 3,158, 81,133, 78,134,130,179,241, 17, 25, 57, 61, 53, 47, 47,103, -175, 7, 75,224,115,135,139,127, 97,141,234,237,254,138, 5, 74,189, 81, 77,202,253, 13,187,113,201,102,185, 84,122,164,166,141, - 41,170,164,208,194, 90, 47,114, 3,239, 11, 42, 8,230, 56,206, 53,160, 92,119,251, 21,218,227, 43,139,138, 79, 20,201,223,169, -214, 59,244,232, 27,125, 4,217,141,109,212,106,251, 11, 22, 36,247, 38,120,191, 94,185,121,196, 82, 76,164, 44, 39,151,221, 15, -128, 83,205,151,129,228, 17,110, 24,227,108,134,131,196,238, 46,226, 60,195, 51,120,242,140,217, 51, 4,134,110, 92,238, 92, 77, - 42, 52, 0,198,177,153, 20,104, 81, 96,232, 2, 5, 0,233,176, 24,151,241,111, 0,241, 22, 99,225, 63, 5,112,190, 91,148,164, -153,214, 76,249,107,207, 8,150,157, 4,109, 4, 46,181, 12, 36,105, 22, 38, 58,216,234, 40,236, 92,177, 35, 85,201,196, 94,166, -255, 0, 4,227,251,102,171,138,226,141, 80,145,106,127, 43,106,227,151,155,183,111,130, 40, 41,134,253,197, 45,203,106, 77,100, -206, 72,103,248, 45,250, 74, 26,201, 88, 17,189,203,148,159,208,106,118,219,255, 0, 77,225,202, 23, 11,155,155, 59,120,151,101, -141,146,115,108, 43,142,220,242,235, 79, 83, 77, 2, 85,186,237, 13,231, 25, 76, 37,173, 94, 28,153, 78, 35,192,250,189, 49,242, -243,146, 21, 28, 67, 5,242,214,185,225,237, 10,246, 37,236,223, 28, 51,160,110, 93, 50,230,159,180,155,231, 14,139, 6,141, 84, -188,169, 20,168,245,170, 53,231, 14,149, 20, 69,166, 34,238,183, 93,151, 24,202,168, 48,195,108,176,204,230, 36,178,250, 35, 54, -134, 94, 76,166,217,142,134,185,163, 99,253, 27,221,214,159, 80,165, 91,187,205,197,181,110,187,181,116,121, 33,246,109, 11, 90, -155, 92, 73,125,180,171, 33,152,105,184, 43,142,194,160,169, 67,169,117,184,146, 84,156, 20,165, 25, 60,195,123, 59,206,248, 23, -142, 41, 56, 79, 52,204, 56,182,110, 23,174,225,202,104,160,154,140, 82, 79, 49, 38, 34,167, 93, 35,197,104,209,156,173,149,152, -146, 20, 70, 93, 84,165,153,191, 32,200, 60, 65,240,254,183,140,178,156,183,130,224,226,234, 14, 40,171,154,162, 10,227, 91, 4, - 0, 9,129, 81, 29,108,114,131, 35,162, 6,187,162,128, 11, 25, 66, 51,137, 46,188, 20,224,130, 37,122,161,107,241,207, 22,205, - 68,229,213,151,193,189,253, 34, 59,113,121,149, 53, 84, 40, 55,206,223, 79,185,147,150,134, 72, 22,172,106,177,123, 29, 60, 36, - 57,159,135, 58,112,125,151, 27,107,197,206,231,238,109,253, 66,224,219,124,109,173,154,220,132, 90,144,164, 85,209, 87,159, 18, - 13, 86,231,182,219,170,182,183,153,164,123,205, 6,114,159,102, 44,244,195,114, 64,108, 32,164, 58,218,149,148,246,148,183, 0, - 30,195,186,103, 4, 59,219, 95,221, 41, 91,210,238,236, 81,174, 43, 18,191, 97, 78,179,235, 27,115, 6,133, 5,234,101,126, 92, - 7,229, 25,178,149,117,212, 19, 61,159,118,131,224,173,133,199, 8,117, 50, 23,206,113,240,235, 95,184,128,250, 57, 52, 5,238, - 92,237,211,224,251,126,238,109,132,155, 34,168,253, 90,157,107, 61, 18,125, 66, 21,175, 38, 90,150,227,236,218, 87, 93, 26,179, - 18,165, 71,166,165, 75, 33,152,239, 9,107,109, 10, 40, 18,121, 2, 82, 39,213,158, 45,112, 93,125,119, 19,229,145,230,113,193, - 73,155,199, 76,244,245,181, 20, 18,212,211,115,163, 69, 71,134,162,150, 72,214, 70, 81,203, 66,172, 80,165,217,219, 82,178,174, -170,226,135,193,142, 59,203,114,254, 18,205,101,202,100,158,183, 36,150,174, 58,154, 26, 92,198, 42, 74,174, 68,178, 51,199, 61, - 45, 92, 82, 52,106,228, 72,225,215,152, 30,200,138, 85,149,155, 79, 63,120,152,246,113,123, 73,247,246,235,219,109,167,226,139, -140,141,138,188,175,178,213,122,187,181,118, 29,241,126, 64,166,221,115, 99, 73, 93, 54,159,112, 78,182, 41,145,237, 56,210,106, - 13, 56,228,106,115,110, 33, 60,254, 41,132, 84,218, 23,238,207, 41,173, 31,246,169,108, 70,229,240,207, 70,224,147, 98,119,114, -163, 71,170,222,187,125,195,213,118,150,252,234, 12,137, 18,233, 70,139, 43,118,239, 89,244, 56,177,164,203, 97,167, 29, 12, 68, -146, 91, 60,200, 72, 79, 32, 74, 71, 40, 26,238, 94,204,253, 30, 26,228,253,212,164,238,167, 22,156, 77, 94,219,207, 82,164, 79, -131, 56,192,167, 63, 93,167, 79,170,174,154,224,118, 27, 85, 91,234,181, 93,149, 83, 76, 20,173, 8, 10,106, 34, 99, 59,203,144, -220,182,137,206,183, 63,218, 81,236,103,137,199,254,225,237,141,254,141,242,159,182, 63,197,206,219,177,183,108, 80,227,216, 76, - 93,200,157, 30, 61,114,165, 89,102,162,106, 82,110,248, 10,142,176,154,138,153, 45, 22,157,230, 12, 37,207, 23, 42, 41,211, 54, - 91,226,118, 67,149,113, 15, 14, 82, 84,113, 37, 61,110, 65,151, 37, 76,179, 61, 46, 80,244,112, 67, 83, 36, 82,198,139, 2, 70, - 26, 87, 71,230,182,191,169, 81,168, 7, 46,218,138,163,238,105,225, 55, 17,103, 28, 53,197, 21,180,220, 43, 85, 67,196,121,172, -148,176,195, 29,102,117, 29,117, 68,244,145,205, 12,142,213, 15, 41, 72, 99,120,249, 43,203,250,242,218, 47, 24,141,116,134,125, -234,246,125,236,206,223,237,103, 9,155, 11, 64,179,173,250,125, 38, 3, 59, 97,100,212, 92, 17,163, 54,202,230, 85,234,214,237, - 54,167, 88,172, 76, 82, 19,151,234, 82,234, 82,100, 72,125,213,100,173,199,207,100,132,164,111, 48, 24, 24, 29,135, 65,166,203, -102,236, 37,237,126,216, 88,187,122,185,202,169,155, 50,212,183,173,113, 82, 83, 9,138,169,233,160, 82, 33,210,147, 53, 81,146, -234,196,117, 58,152,129,101,176,181,132, 21,242,133, 40, 12,150, 11,143, 78, 49,236,142, 6, 56,109,189,119,206,237,247,106,133, - 98, 35, 63, 80,109,189,164,235,165,183,175,125,198,171, 71,147,252, 28,183,209,200,180,173, 16, 18,168,242, 38, 84, 93, 65,230, -143, 77,165,203,121,176,183, 80,219, 78,115,121,134,183, 63,207, 30, 26, 53,122,250,236,222,165,132, 99,114,242,188,210, 27, 18, - 91,123,146,215, 98,214,176,185,107, 0,113,212, 98,122, 30, 27,225,232,231,174,100,203,178,252,150,145, 76,135, 96,145, 71, 12, - 64, 48, 1,118,178,133,178,170,222,230,193, 65, 36, 12,113, 23,233, 10,251, 69,127,139,219, 56,240, 51,180,149,207, 14,246,220, - 58, 76, 90,158,253,213,105,238,225,251,107,110,170, 45,166, 69, 35,111,195,236,175,154, 61, 90,224, 64, 68,138,131,100,165, 72, -161,165,182, 28,109,216,245,192,166,197,250, 63, 62,207,199, 44, 27, 45,238, 46,247, 46,142,166,111, 45,207,164, 38, 30,218,192, -168, 71, 90, 31,183,118,209,231,218,148, 43,105,105,228, 15, 10,125,126, 68,104,146, 26, 88, 10, 34,147, 18, 26,217,112, 38,161, - 37,189,113, 27,217,255, 0,195, 62,227,251, 81,184,218,174,223,155,197, 50,161,115,219, 13, 92,234,221, 61,253,186, 37, 37,214, -218,174, 63, 83,168,185, 34,149, 99, 68, 49,148,129, 0, 85, 37, 71,114, 43, 76, 50,166,145, 6,141, 74,151,238,188,134, 52,102, -151,250, 18,218,182,237, 58,213,161,211,168,148,168,145,160,194,167,196,143, 18, 60, 88,140,183, 30, 52,118, 35,180,150,153,143, - 29,134, 82, 16,203, 8,109, 41, 74, 16,144, 18,148,164, 37, 32, 0, 53,117,113,253,101, 39, 0,112,165, 23,134, 89, 44,193,243, - 42,197, 90,140,226,116,234,236,225, 88, 67,126,160, 61,151,202,108, 86,153, 34, 86,213,206,123,208,254, 27, 80,214,248,145,198, - 53,254, 44,103,208, 52,121, 85, 11, 61, 54, 73, 76,251,132, 68, 44,166,123,116, 38, 59,183,152, 92, 53, 84,146,178,149,228, 32, - 25, 10, 82, 18,144,148,140, 4,128, 0,244, 3,160,215, 62, 61,164, 30,208, 29,190,246,125,108, 68,221,193,174,166, 21,195,185, -183, 74,103,208,246,111,110, 92,144, 91,126,238,186,153,142,218,156,168, 84,144,203,169,118, 61,155, 75, 18,162, 72,171, 73, 65, - 65, 8,121,152,108,172, 76,155, 21, 42,223,186,157, 78,157, 69,167, 84, 43, 21,138,132, 42, 77, 34,147, 10, 85, 74,169, 84,169, - 74, 98, 13, 58,155, 78,130,195,146,166,207,159, 54, 83,137,106, 28, 38, 99, 52,235,142,186,226,146,134,208,218,150,181, 4,130, - 71, 9,184,174,225,239,128,223,109, 5,235,103,196,178,120,186,133, 90,187,118, 26,145,116,193, 93,191,180, 87, 53,159, 80,147, - 34,153,115,212,232,158,253, 88,147, 10,183, 72,146,245, 74,148,212,218, 52, 38,155,157, 7,154, 22,102, 37, 42,117, 74,117,156, -212,252, 35, 69,149,207,156, 82,213,241, 20, 21, 13,195, 52, 45,174,178, 72, 34,146, 64,163, 75, 24,163,145,145, 78,133,154, 64, -177,177,184,109, 37,180,144, 64, 34,228,227, 92,195, 55,166,201, 42,232,248, 98,122,101,226,188,193,116, 80,199, 81, 52, 81, 22, - 98,202, 37,146, 53,145,135, 49,160,137,154, 69, 91, 50,235, 85, 12, 10,155, 24,223,112, 43, 69,217,158, 45,184,165,187,120,165, -246,138,241, 35,182,116,170,123, 23, 91,119, 61, 74,223,220,203,198,221,164,212,247, 82,240, 90,154,145, 18, 4,155,122, 83,169, - 76, 13,179,165,195,106, 27, 94,232,150, 88,134,243,109, 69,164,194,109, 80,163,204,105,153,125,220, 94,209,127,103,156, 61,184, -186,232, 52, 94, 47, 56,125,117,247,237, 26,244, 24,113, 99,110, 45,186, 93,145, 37,234, 60,166, 35,176,203,104,151,241, 45, 78, - 41, 9, 74, 64,234, 84, 0,215, 43,127,189,146,225,251,255, 0,151,141,236,252,108, 47,255, 0,212,117, 98,186, 62,141, 70,193, - 80,109,171,134,184,206,250,111, 75,206,209,168,117,106,171, 77, 58,108, 79, 9,215, 41,240, 31,150,134,220,228,180,193,240,212, -166, 64, 56, 32,224,156, 28,234,227,226,156,231,194,238, 48,205, 41, 42,234,248,179, 49,165,167,161, 88,226,165,164,134,136, 37, - 61, 52,107,164,104,141, 76,102,218,138,130,204,119, 54, 10, 44,136,138, 40,222, 15,200,252, 93,224,124,162,178,142,139,131, 50, -202,202,154,247,146,106,202,201,235,245,213, 85, 72,218,137,121, 92, 72, 47,160, 51, 4, 81,176,187, 49,187,187,179,241,151,216, -125,188,123, 87,177,188,108,155,223,120,111,251, 87,109,173, 15,226,150,243,164,127, 8,239, 10,196, 74, 37, 35,235, 57,181,155, - 69,248,144, 61,246,107,137, 71,189, 56,212, 57, 74, 66, 51,149, 6, 20, 64,192, 58,156, 37,241,179, 92, 40,241,203,106,237, 46, -225,220,246,214,221,239,165,175,107, 85,218,191,118,150,241,196,122,245, 54, 52,165,184,202, 93,157, 69,169, 68,120, 38,161, 71, -146,245, 54, 31,189, 67,112,189, 2,106,233, 81,140,168,239, 42, 43, 5,184, 0,123, 51,184, 59,180,120,227,226, 73,123, 35,122, - 92,215, 45,167, 72,254, 47,238, 75,185, 21, 91, 80,210,133, 79,223,104,181, 43,126, 19, 17,149,245,197, 62, 75, 62,234,182,234, -239, 21,254,143,159,153,164,114,168, 12,131,250, 11,240,185,177,214,207, 9,155, 29,181,187, 7, 78,186,100,213, 41,118,141, 53, - 54,133,175, 62,230,151, 77, 98,183, 95,122, 59, 21, 90,234,227,165,168,172,176,212,202,144,167,198,170, 72, 83,113,218, 4, 70, -167, 60,241, 64,109,167, 22, 49,227,201,203,105, 56,158,154,191, 47,204,234, 97,226,113, 20, 74,241,160, 40,145,211,114,230, 28, -196,153, 44,218,218,229, 29,117,125,130,110, 45,140,253, 29, 23, 52,173,225, 42,188,187, 50,202,105,103,225, 38,158,102, 73,100, - 43, 36,146, 85,137, 41,207, 41,224,123,174,133, 0, 58, 57, 91,243, 2,216,220, 12, 63,180,219,118,145, 74,138,212, 72,144,152, - 67, 77, 33, 40, 72, 13,164, 97, 41, 24, 0, 0, 58, 12, 1,168,214,125, 36,238, 26, 44,170,175, 15, 59,113,196,205, 42,137, 14, - 22,224,216, 59,137, 73,176,171, 53,136,200, 98, 51,213, 75, 2,242,167, 86,221, 76, 42,145, 5, 42,168, 46, 29,213, 78,163, 42, - 16, 60,230, 50, 42,243,249, 18, 18,251,170, 18,111, 4, 30,160,228,122,141, 71, 19,233, 42,111, 69,183,107,112,145,182,219, 37, -239,241,156,189,119, 91,118,169,119, 3, 20,143, 17,179, 37,155, 43,111,169, 53,105, 85,170,210,208, 57,148,210, 5,199, 87,180, -163, 53,144,128,239,189,200, 40, 89,247,119, 16,170,219,194,167,174, 95, 16,120, 99,216, 11, 9, 94,160, 7,211,125,224, 42,220, -240,214,234,188,157,100,223,109,175,219, 22,175,140, 41,151,191,134,156, 91,250, 68, 41,133, 41,137,143, 85,182,168, 14,158,207, -166,253, 27,157,160, 45,183,222,221,240,212,253, 25, 45,199,171,212,118,115,136, 29,176,151, 33,247,169, 54,142,229, 80,110,122, - 75,110,168, 41,184,138,190, 45,181, 67,159, 26, 49, 42, 42, 67, 62, 61,152,135,139,120, 8, 14, 76, 91,137,202,221,112,234, 82, - 58,139,207,209,155,219, 90,149, 31, 99,247,187,115,230, 71,118, 60, 91,231,115,160,208,105,106,117,183, 80, 38,192,177,109,214, - 20,185,241,212,165,114,187, 24,213,110,170,156,110,100,164, 31, 22,152,242, 20,163,202, 2,101, 13,163,120,178,105,219,196, 78, - 41, 52,214,229,243,208, 27,116,230, 8, 34, 19,125,252,208,250,189,247,193, 60, 25, 90,149,240,199,132, 5, 93,249,190,206,228, - 95,175, 40,212, 76, 97,251,185, 38, 61, 63,225,181,182,194,210,210,210,213,119,139, 59, 11, 75, 75, 75, 67, 3, 11, 86,231,168, -244,137, 50,219,159, 34,151, 78,126,123, 74,105,109, 77,122, 12,103,101,180,182, 20, 20,202,155,146,182,138,208,164, 40, 2,146, - 20, 10, 72,200,193,213,199, 75, 89, 4,141,193,177,247, 96, 98,222,186, 77, 45,198,165,199,114,155, 79,113,137,239,123,196,230, - 87, 14, 50,154,153, 32, 41, 11, 15,203,109, 77,226, 67,220,237,182,121,150, 10,178,128,115,144, 52,195, 92,219,245,176,182,149, -122,185,103,220,245, 58,117, 38,177, 14,165, 62,137, 88,166,205,183,100,165, 18, 94,180,182,226, 54,233, 43,153,126,224, 91,159, - 5,155, 45,232,238,197, 88, 82,208,167,241, 10, 62,100,128,214,182, 39, 90,175,186,220, 34,237,174,239, 92, 87,189,203,114,202, -174,179, 62,249,180,173,155, 70,114, 96, 73, 97,182,233,177,104, 55, 4, 90,205, 74,117, 39,196, 97, 70, 44,234,189, 58,155, 70, -165,212,213,146,151,233,244,134, 89,229, 24, 36,239,229,230,133,166, 97,152,203, 44,112, 21,216,197, 98,193,245, 40, 4,130, 13, -194,173,216,141,137,210, 0, 32,219, 9, 75,204, 10, 12, 42,165,129,253,111, 75, 29,135,199, 97,247,227,225,226,159,135, 84, 56, -170,163,213, 95,119,172, 38, 13,219, 88,247,105, 22,125, 85,171,145, 66,203,155, 66,162,214, 18,136,138,166,123,195,149, 5, 46, -227,166, 8,173,167, 43,148,194,220,113,158,102,153,112,164,250, 39, 17,220, 62, 92, 21, 58, 93, 58,145, 81,141, 34,185, 94,151, - 97,212,226,211,133,167, 80,106,170,170,149,249,112,215, 45,203,118, 92,198, 28,166,133,197,168, 51, 86,164, 85,125,241,199,121, - 87, 1,181,165,233, 10,109, 15,161, 74,182,220, 60, 32,109,125,201,123,215, 47,185,174, 86, 27,170, 87, 55, 43,109, 55, 45,216, -204, 61, 29, 48, 33,205,219,106, 84,138, 75, 84, 24, 49,212,193, 12, 91,213, 70,167, 84,156,170,176, 58,201,118,122,151,204, 20, -134,139,116,232, 92, 31,109,165,187,120,209,239,138, 92,218,235, 53,202, 30,226,110,142,227, 66,113, 79, 68,117,145, 63,115,169, -177,233,206, 81,214,211,177,136, 85, 10,144,168, 20,183,233, 12,118,138,245, 57, 11,202,185,222, 14, 56,145,195,220,178, 86,106, -161, 46,139,128, 74,144, 27, 78,161, 30,201,246, 67,125, 94,175,251,237,109,176,143,246,189, 67,202,133,111,239,189,175,107,245, -235,111, 53,190,235,247,192,151, 23, 20,214,213,149,120,238,245,161,112, 90,149, 90,123,118, 93,223,110,218,116,155,146, 37, 34, -165, 34,213,175, 92, 87,142,216, 91,119,181, 10, 5,199, 93,102, 0, 98,139, 83,155, 86,172,154, 91, 40,230,144, 74,145, 17, 79, -169,147, 50, 58, 23,100,166,241,143,176,110, 91,118,252,155,150, 60,202,122, 85,111, 48,244,196,211,236,186,197,114,218,166, 92, -206, 88,209,239, 59,138,199,163,207,137, 73, 87,214, 85,120,214,244,153,202, 90, 88,103,194,117, 48,100, 69, 14, 42, 91,110,197, - 77,226,167,194, 53, 62,224,168,214,164, 92,187,177,184,117,202, 93,207, 86,176,238,171,166,132,252, 75, 34, 52, 75,138,247,219, -171, 22,218,178,232, 23,101, 70,124, 75, 81, 19, 90,146,100, 90,180,154,171,241, 99, 73, 98, 19,149, 8,201,195, 8,139,207, 29, -204, 89,174, 3, 54,230, 28, 89, 84,218, 93,213,112, 83,169, 85, 8, 13,183, 62, 50,109,173,179,153, 84,126,170,109,166, 45,137, -213, 38,111, 9,246, 59,149,202,124, 73, 44,199, 68,199, 96,199,169,183, 24, 77, 91,133, 9, 76, 55, 93,134,181,227, 28, 52, 99, - 65, 52,210, 44,161, 35,212, 99, 50, 88,176,141, 85,236, 90, 50, 67, 23,214,214,210, 86,214,179,139,144, 10, 77,101,201, 85, 4, - 92,245,183, 75,220,116, 61,133,133,239,123,246, 56,201,110, 78, 45, 54,210,143, 71,187, 69, 26,206,190,106, 23,221,159, 10,239, -174, 77,176,164,109,229,114,157, 93,162,200,181,109, 26, 5,194,253,122,230, 66,160, 17,111,208,220,164,222, 86,170, 68,245, 41, - 75, 91, 85,192,134, 91,117,109,188,218, 1,107,139,222, 30, 41,208,160, 38,182,212,154, 96, 81, 98, 34,164, 83,236,138,173, 86, -132,229,233, 73,143, 2, 77, 86,210,160,202,167, 82,150,229,102,224,167, 57, 85,155,240,177, 28,130,105,117, 4, 48,181,191, 26, - 67, 73,200,239, 78, 20,232,247, 93,227,184,151,181, 59,113,239,187, 58,175,186, 16,107, 20, 59,177, 20, 6,109, 25, 81, 38, 91, - 85,235, 26,194,177,234,148, 36, 49,113, 91, 83, 67, 13,174, 54,221, 80,228,162, 75,124,147, 24,118, 76,180,176,251,104,120,114, - 97, 71,129, 29,185,102, 75,134,157,116, 87,233,212,215,107,237,221,142,192,102,217,219, 23,234, 46,220,107,153, 26,125, 70, 66, -175, 41, 86, 50,235,200,165, 73,156,220,169, 11,130,138,162, 26, 67,243,150, 16, 68, 68,166, 32,196, 67,134,204, 81,243,102,154, - 55, 96, 25,172, 90,225,180,141, 75,126, 89, 22, 86,190,141,141,197,203, 50,155, 12, 6,246,205, 70,202,164, 3,177,176,251,143, -218,190,227,175,167, 96,112,231, 92,188, 65,108,253,156,237, 21, 85,234, 37,205, 77,117, 54,204, 75,162,127,188,109,197,114, 52, -173,190,178,220,185,255, 0,131,148,235,130,242,141, 38,152,219,246,149, 21,117,198, 37, 41,160,227, 97,192,213, 50, 76,191, 5, - 44,199,113,212,227,232,226,211,100, 21, 21,169,244,186, 61,249, 82, 97,202,109,126,252,241,169,187, 81,118,165, 40,183,173,245, - 24,119, 77,250, 28,149, 70,101, 47, 81,162,201,144, 35, 61, 61,165, 56, 94,122, 73,102, 57,144,174,112,155,149,235,194,253, 54, -254,147, 62, 77,127,114,247, 1, 75,185,109,201,150, 53,252,136,169,180, 27, 69,243,183,234,190,107,183,181, 30,208,169,151,173, -119, 21, 76,139, 79, 23, 21, 86,150,196,154,122,162,203,114,155, 49,212, 72,121,217, 74, 76,164, 52,251,165,194,237,235, 26,209, -179,173,109,147,172, 76,141, 81,133,182, 87,238,208, 87, 46,106,213,219, 71,163, 71,122,208,188,167,211, 39,166, 53,106,131, 47, -109,107,104,172, 50,153,222,250,242,158,167, 46,147, 80, 97,184,166, 59, 47,172,204, 15, 66, 37, 60, 57, 12,220,152,228,168,144, - 77, 35, 16,197,159, 68,106,161, 88,234,102,104,191,104, 88, 1,114, 84,173,192,114,193,114,237, 84,161,152, 32, 33, 64,176, 2, -228,155,141,128, 13,233,248,131,216, 12,110,107,245,216,236,216,210,174,155,102, 19, 51, 24,254, 12, 74,185,104,144, 74,126,174, -102,127,139, 76,118,175, 5,151, 65,108,123,159,142,181,183,206, 74,121,146, 94, 82,148, 50, 14,180,215,116,165,219,144, 32,213, -182,215,234, 10, 53,122,167, 42,135, 42,149,118,221,213, 70,214,169, 21,107,134,188,202,229, 86,106, 18, 4, 96,219,174,148,212, - 36,135,144,147, 32, 54,202,144, 24,109,164, 55, 29,160,157,199,135,107, 57, 22,193,139,100,166,162,160,236,107, 61,139, 88, 85, -154, 99,195, 80,113,154, 42,105, 34,162,212,101, 58,174, 69,115, 39,197, 74, 10,206, 14, 19,204,123,235,144, 59,209, 19,116,167, - 75,115,110,234, 52,115,107,213, 46,219,210,159, 99,220,151,204, 58,236, 73,212,214, 41,117,135,213, 18,124,250, 47,142,152,243, - 99,207,171, 72, 8,129, 8,201,140,219, 77, 59, 90,111,154, 74,212,166,148,189, 76,174, 26,121,106,106, 29,239, 34, 68, 9, 80, -110, 46, 9,181,201,219,183, 91,237,190,248, 60,236,234,136, 7,148,183, 95,203, 29, 10,217,141,236,135,113,237,133,155, 34,137, -104, 94, 55, 7,131, 64,143, 79,110,109, 18,136,236,138, 4,185, 20, 96,229, 38, 91, 17,174, 7,228, 6, 36,186,204,216, 18, 99, -188,239, 63, 35,146, 34,186,166, 84,235, 74,109,197,229,117,203,231,113,228, 81, 38, 76, 27,115, 80,181,169, 66, 35,130,109, 86, -161, 91,167,203,170,192,109,238,102,132,198,233, 52, 53, 63, 33,184, 44,146,133,204,125, 1, 82, 99, 70,241, 95,139, 22, 83,173, - 37,181,115,182,167,188,183, 37,129, 6,159,182,219, 79, 95,118,221,177,236,232, 45,208,224,166,152,212, 39, 19, 54, 68, 95,130, - 92,184,146,164, 69, 83,145,233,254, 40, 83,113,195,107, 72,113,182, 68,151, 7,140,251,152,109,170, 91,157,184,213,165,133, 85, - 47,171,178,127, 33,230, 75,114,171,213, 23, 35,250,156,199, 84,159, 15,147, 25,200, 41,229,229,200, 61, 52,228,156, 45, 83, 33, - 46,213, 9, 12,109,184,184, 98,214, 61, 46, 54,177,183, 93,246,239,141,118,204, 17,118,208, 89,135, 93,192, 23,247,125,248,187, -241, 61,191, 16,171, 20,120, 91, 43,100, 59, 38, 45, 50,223,155,227,110,163,143,165,182,103,212,183, 14, 41,104,204,160,206,247, - 98, 91,122,157, 79, 90, 99, 41,149, 50,183, 97,190,216,132,184, 46, 57, 2, 52, 39,156,210, 5, 41, 40, 66,220, 89, 66, 27,109, - 42, 90,220, 95,192,219,105, 72,202,150,226,212,112,218, 7, 82, 73, 32, 0, 59,247,214,204, 79,218,105, 60, 77, 67,171,238, 54, -206,186,245, 31,112, 40,173, 83,169, 53,218, 12, 24,116,183,153,221, 11,113,130,220, 51,122, 91, 76, 85, 22,150, 26, 76, 26,164, -146,195, 50, 28, 10, 83,241,203,235,111,199,134,228, 45,102,150, 23,179, 43,113,174,103,163, 78,220,186,172, 10, 83, 3,192,117, -104,185,234,127,195, 25,237, 41, 32,164,174, 53,175, 72, 83, 84,104,143,114, 21,146,164,150,212, 20,190,185,198, 4,179, 46,173, -203, 50,156,190, 58,121,100, 74, 87,131,103, 86, 97,169,159, 98, 92, 0, 11,184,125,138,176, 91,105, 32,109,107, 6,154,136,106, -106,106, 25,213, 76,161,250, 16, 54, 3,176, 36,216, 2, 58, 17,126,183, 62,252, 48, 60, 43,109,125, 79,127,119,214,218,118,158, -185, 44,218, 22,100,195, 85, 21,152, 78,173,176, 24,129, 33,164,215, 46, 72, 51, 89, 87,232,220,113,192,221, 34,148,242, 50,174, -121,115,101, 55,205, 29,104,115, 82, 78,211, 25,177, 59, 3,102,236, 21,187, 50,139,108,185, 46,165, 62,173, 33,153, 53,170,245, - 73, 17,145, 54,114,162,180, 89,135, 17,150,162,180,148, 67,165,176,133, 61,224,176, 57,202, 21, 37,197, 41,197,149,100, 62,122, -131,113, 6,106,185,165, 96,104,175,236,208, 11, 33, 34,197,137,182,166, 35,168,189,128, 0,244, 85, 23,220,156, 61, 80,210,154, -104,136,127,239, 28,220,251,189, 7,243, 39,212,156, 45, 45, 45, 45, 48,227,119, 11, 95, 8, 4, 16, 70, 65,232, 65,215,221, 45, - 12, 12, 83, 67, 45, 53,146,219,104, 65, 61,202, 82, 1, 63,128,213, 77, 45, 45, 12, 12, 51,123,215,177,246, 78,250, 90,142,219, - 55,132, 15, 17, 77,169, 82, 41, 53, 88,229, 45, 85, 40,211,185, 57, 19, 46,159, 36,164,248,107,198, 2,208,160,166,221, 72,229, -113, 10, 24,199, 21, 55, 95,128,189,229,176,101,201,126,218,136,213,251, 65, 75,139, 49,164, 82,249, 99, 86, 27,103, 36,161, 50, -233, 82, 22, 57,221, 9,192,203, 14, 59,205,140,242,163, 60,162, 65,250,242,180, 33,192, 82,180,165, 96,247, 10, 0,143,219,170, -147,196,127, 5, 56, 23,196,226,149, 89,229, 28,148,121,204, 74, 17, 43,169, 25, 98,168,208, 62,202, 73,169, 94, 41,209,127, 84, - 75, 27, 50, 11,136,217, 1, 55,183,188, 54,241,191,143, 60, 47, 87,165,200,171, 99,172,201,165,114,239, 65, 86,173, 45, 54,179, -246,158, 61, 46,146,192,237,250,198, 41, 21, 92,216,200,174, 64,180, 88,213,177,251,198,219,222, 2,182,186,252, 11, 10,228,255, - 0,246, 90,178, 91,207,151,233,189,211,147, 31, 62,108,117,239,167,207,108,248, 36,222, 91,238,100,115, 87,165,127, 3,105, 10, -113, 62, 60,170,176,241,106, 37,172,142,111,119,166, 48,172,135, 49,156,120,203,100, 12,103,174, 48,100, 58,105,148,245, 30, 99, - 13,130,123,231,195, 26, 33,168,236, 50, 48,211, 77,182, 63,217, 72, 31,208, 53, 83,100,223, 67,239, 15,232,107, 82,167, 52,206, -115, 28,238,154, 50, 15,179,179, 69, 4,111, 99,246,100,120, 99, 18,149, 61,249,111, 17,244, 97,139,115, 58,250, 99,248,133, 95, - 67, 37, 46, 85,146,229,217, 29, 76,128,143,104, 85,150,162, 68,184,251, 81,164,210, 24,131, 14,220,200,229, 95,240,156,107,150, -193,112,227,103,236,125, 9,184, 52,136,161,218,131,220,143, 84,106,146,130, 29,168, 84,101, 37, 56, 15, 74,120, 32, 14, 80, 10, -130, 27, 64, 13,182, 9, 8, 72,201, 39,100,244,180,181,212,185, 94, 87,151,100,153,125, 38, 85,148,209, 71,151,101,180, 40, 35, -134, 24,148, 36,113,160,232, 21, 70,221,110, 73,234,204, 75, 49, 36,147,142, 85,205,115, 92,203, 59,204,106,243,108,222,182, 76, -199, 50,175,115, 36,211,204,197,228,145,207, 82,204,119,233, 96, 7, 69, 80, 21, 64, 0, 0,180,180,180,181,191,134,252, 45, 45, - 45, 45, 12, 12, 45, 45, 45, 45, 12, 12, 45, 45, 45, 45, 12, 12, 45, 45, 45, 45, 12, 12,104, 15, 16,151, 95, 24, 54,239, 17,123, - 83,103,109, 12, 84,212, 54, 75,118, 69,182, 47, 27,216,219,148, 90,131,187, 24,189,180,184,101, 92,219,132, 23, 42, 76, 82, 37, -139,234,202,151, 77,160,210,125,241,138,135,213,181, 58,116,137,140,248, 9, 90, 64,231,117, 43,136,239,106,117,199, 89,185,105, -117, 10, 52,219, 42, 68,189,220,218,235, 50,177, 79,135,177,151,213,106,118,216, 64,186,248,146,182,109, 10,197, 94,196,168,220, - 27, 33, 79,182,247, 3,109, 33,236,132,171,166,163, 88,171, 53,117,221,106,132,229, 62, 29, 72,212, 41,241, 36, 73,106, 28,131, - 84,132, 47, 28,201, 10,199,108,140,227, 84, 76, 88,197, 69, 69,150,202,143,115,203,215,203,250,134,165, 20, 60, 69, 77, 73, 4, -113, 75,195,212, 85,111, 18,196, 57,143, 18,150,102,142, 70, 98,238, 24, 50,182,184,244, 70,234, 2,130, 99, 89, 13,218, 73,249, -209, 44,195,134, 42,235,106, 36,154, 46, 37,175,163,142, 87,148,152,210,102, 8,171, 36,106,161, 35, 42,200,203,203,148, 73, 42, - 49, 44, 87,154,209,139, 36,116,252,158, 18,111, 54,228,113,174,250,120,178,217,207,122,222, 77,206,102,216,218,235, 50,169,182, -183,141, 11, 96,170,118,165,187, 86,174, 81, 46, 93,174,102,187,109,151, 87,181,116,241,125,223,117,200,235,187,229, 59, 34,206, -174, 87,232,109, 83,149, 52, 24,150,188,232,144,226,189,121,221,222, 37,189,160,182,229,237,191,208,108, 59, 58,250,169,203,183, -173,190, 38,157,179,108,216,155, 3, 85,170, 88,180,107, 78,206,216,154,213,197,195,166,226,216,251,164,154, 35,177,247, 99,117, - 46, 45,225,139,109,211,166, 90,113,234, 19,223, 67, 85,233,113, 87,111, 66, 52,228,205,149,220, 51, 22, 58,149,204, 89, 65, 80, - 24, 4,167,168, 30,131,211, 95, 12, 72,196,133, 22, 91, 42, 29, 1,229, 25, 3,211, 75,197,197, 20,136,176,163,240,229, 36,235, - 18,176, 33,145, 44,210, 60, 84,241,180,133, 86, 48,170, 73,131,152, 2, 42,144,206,124,197, 76,130, 93,105,120, 70,177,218,103, -143,138, 43, 96,121, 93, 72, 43, 36,132,172,105, 45, 76,169, 24,102,149,157,128, 21, 28,178,100,103, 82,136, 60,129,132, 70, 29, - 28,224,214,249,226, 54,181, 83,222,219, 55,136, 39, 43, 85,241,100, 94,246,107, 27,119,127, 86,246,245,141,190,145,120, 91, 23, -102,204,109,181,247, 91,109,168,212,184, 17,169,213,150, 40,215,245,201,118,208,253,234, 19, 64,161,116, 5, 67,154,165,207,141, - 37, 70, 41, 62,217,106,175, 29, 60,104,113, 79, 93,164, 80,248, 84,226,128,108,102,199,212,235,214, 38,211,193,135,178, 27,169, - 46,147,113, 46, 44,255, 0,115,185,183, 61, 15,199,182, 20,196,245, 87, 38,211,216, 92, 23,154, 60,130,143, 6,156,148,254,148, -200,113,217,206, 33,150,155, 57, 67,105, 73,237,144, 49,211,211, 67,187, 77,128,242,138,221,136,195,139, 61,212,180, 5, 19,247, -157,111,240,175, 28,175, 11,103,243,113, 12, 25, 5, 53, 85, 91, 66,177, 70,164,152,227,133,180, 34, 75, 44,105, 26,133, 87,155, - 75, 19,164, 5, 65, 35,170, 0,166,216,110,227, 15, 15,159,139,248,110, 14, 25,168,226, 74,186, 58, 36,153,165,149,192, 89,101, -157, 4,143, 36, 48,202,242,146,204,144,234, 80, 53, 18,206, 99,141,156,150, 92,126,116,252, 63,207,246,190,240,179,111, 84, 45, -109,128,218, 78, 44,118,210,133, 86,172, 61, 95,169,195,163,240,195,113, 77,114,125, 93,248,145, 32,174,108,185,213,189,175,149, - 33,245,136,112, 98,182,132,169,210,134,210,214, 16,148,229, 89,216, 95,229,123,244,129, 63,242,126, 52, 63,251,173,204,255, 0, -254, 61,169,231,253, 81, 76,255, 0,200, 99,127,246, 73,254,173, 47,170, 41,159,249, 12,111,254,201, 63,213,169,173, 79,140,244, -149,147,203, 85, 89,225,206, 77, 85, 85, 49,212,242, 73, 10,188,142,118,221,157,162, 44,199,110,164,147,211,211, 16, 58, 95, 2, -107,104,105,226,164,162,241, 71, 60,163,164,128,105, 72,162,157,227,141, 23,246, 81, 18, 80,170, 58,236, 0, 27,226, 37,155,115, -253,212,126, 49,125,153,188,113,237,174,247,198,222,153, 59,193, 46,175, 96, 72,219,250, 22,228,109,202,182,202,225,187,172,138, - 21, 82,137,114,222,246,157,180,203,246,205, 29, 85, 20,205,129, 74,154,216, 8, 67,198, 83,220,180,197, 40, 34, 90,211,174,108, -123, 29, 56, 93,226,149, 28,122,109, 85,237, 78,219,189,198,219,219,123,106,234,245,201,187,145,114,220,214,181,114,217,129, 10, -149, 34,223,173, 81,102, 90, 18, 69,110, 36,113, 58,173, 81,126, 98, 97,251,154, 2,223,101, 46, 57, 49, 77,165, 17, 22,226, 63, - 64, 22, 96,195,143,159, 6, 51, 45,115, 12, 43,145, 0,100,124,245, 69,170, 85, 61,151,140,134,162, 50,135,137, 36,184,148, 36, - 40,147,243,198,154,161,241,114,174,151, 42,226,204,162,135,135, 40,168,169, 56,157,157,130, 68,186, 35,166,230,211, 71, 75, 40, - 72,213, 66, 72,165, 35, 14,129,130,132,145,152,182,181, 58,112,239, 63,130,212, 85,153,191, 6,103, 85,252, 79, 95, 95, 91,194, - 43, 26,151,149,181,201, 87,201,170,146,174, 18,242,179, 23,141,131,202, 81,202,150, 47, 18,162,175, 45,134,178, 91, 28,254, 11, - 94, 39,235,248,104,231,255, 0,249,185, 70,127,110,177,109,192,143, 34, 93,135,122,196,136,195,210,165, 74,180,238, 40,241,163, - 71,105,111, 72,145, 33,234, 68,198,217, 97,134, 91, 73, 83,175, 45,197, 37, 41, 74, 65, 82,148,160, 0, 36,235, 46,210, 35, 32, -131,216,244, 58,169, 35,115, 27,163,129,114,132, 31,220,111,139,166, 68, 18, 35,161, 54, 14, 8,253,226,216,132, 15,176,167,134, -142, 35,182,159,142,131,114,110,159, 15,251,217,182,150,232,218, 43,214,152,107,251,129,181, 87,213,153, 69,250,202, 85,110,207, -118, 45, 59,235, 91,142,131, 25,143,127,113,168,178, 84,219, 62, 39,136,180,199,112,165, 36, 33, 68,117, 47,219,205,195, 55, 28, -251,238, 54, 30,243,225,142, 29, 70,225,177,182, 89, 85,139,166,109,187, 96,220, 82, 40,155,167, 77,220,121,146, 24,110, 13,239, - 72,138,151, 99, 46,172,220, 26, 44, 70, 24,129,245,108,167, 42,145,159,169,206, 83,113, 11, 78,151, 83, 34,132,192,132,135, 60, -100,198,101, 46,147,146,224, 64, 11,207,219,162, 84,132,172, 20,173, 41, 82, 79,112,160, 8, 63,113,213,149,152,120,159,153, 87, -113,173, 39, 27,140,170,149, 43,105, 34, 16,136, 36, 15, 44, 37,116, 73, 27, 19,114,172, 24,164,140, 1, 7,202,108,119,232,106, -156,179,194, 76,171, 47,224, 42,222, 1,108,226,174, 74, 26,217,140,230,162, 50,144,206,175,174, 41, 20, 11, 43,161, 85,120,148, -144, 65,212, 46, 54,216,136, 25,208, 61,170, 30,218,237,168,164, 39,110,107,112,119, 42,161, 86,167,180,154,124, 73,123,145,195, -123,147,175,152, 73, 79, 52,102, 82,236,185, 86,131, 14,213,229, 7, 80,172, 61, 80,106, 99,238,173, 39,196,113,206,163, 77,149, -151,192,119,180,211,218, 97,189, 44,110, 46,255, 0, 64,220,170, 74,107, 38, 36, 90,246,237,239,133, 26, 85,175, 26,139,111, 48, -234,221,106,157,101, 88, 47,198,128,235,144, 71,143, 49,200,112, 41, 20,248,116,144,252,135, 28,117,248,190, 58,222, 95,232, 6, -237, 2,142,250,185,220,129, 29, 74,245,240,211,253, 90, 50, 61, 62, 20, 79,251,222, 43, 45, 99,205, 8, 0,254, 56,212,132,120, -202,153,122,212, 79,195, 92, 13,149,240,246,109, 84,165, 90,170, 40,213,156,106,234, 81, 86, 56,128,223,205,165,153,208,176, 5, -209,237, 99, 26, 62, 5,190,100,244,176,113, 87,136, 57,191, 19,100,212,110,174,148,114,202,202,135, 79, 64,238,210,202, 78,215, - 82,200,169, 32, 82, 66, 58, 94,248,215,190, 20,248,114,178,184, 89,217, 43, 15,102, 44, 56, 70, 37,191,100,208,163,210,163, 45, -222, 85, 76,168, 74, 82,220,153, 87,173, 84,156, 72, 1,218,172,250,188,153,211, 37, 41, 41, 74, 21, 34,123,133,180, 33, 28,168, - 78,200,105,105,106,151,168,168,158,174,121,234,170,101,105,234, 42, 93,164,145,216,221,157,220,150,102, 98,119, 44,204, 73, 39, -185, 56,189,233,169,169,232,233,169,232,233, 97, 90,122, 90, 84, 88,227,141, 5,149, 35, 69, 10,136,160,108, 21, 84, 0, 7, 96, - 48,180,180,180,180,142, 23,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194, -210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,214, 53,117,217,246,213,239, 67,171,219,183, 69, 34, 21, - 94,149, 91,165, 79,163, 84, 24,146,195,107,113,112, 42,113, 93,135, 45,182, 95, 41,231,142,178,203,206,114,173, 5, 42, 66,136, - 82, 72, 80, 7, 89, 46,150,178, 24,169, 5, 77,136,238, 48, 8, 7, 98, 46, 49,196,171,235,133,221,241,219,202,252,170, 5, 5, -186,133,255, 0,110, 54,227,142, 91,183, 24,180, 43, 87, 5, 89,218, 66,156, 34, 28, 91,130,109, 22,174,210, 93,171,176,128, 27, -113,199, 24,105,215,249, 3,170, 47, 40,169,247, 49, 56,124, 52,111,189,235, 81,137, 67,173, 91, 85,184,244, 57,175, 52,212,250, -127,240, 58,177,105,211,231, 52,181, 0, 89,174,220, 21,122,163,202, 77, 11,186,164,199, 97, 13, 46, 66, 17,224,173,197,178,183, - 24,123,188, 58, 90,146,167, 20, 85,172, 74,141, 2, 59,168,182,162, 91,115,107, 92,168, 54,223,184,232,119,216, 13,176,222,114, -248,203, 92, 57, 11,126,155,126, 7,249,225,157,217,141,156,160,236,245,178,138, 85, 60, 53, 50,183, 53, 12, 57, 94,173,134, 82, -202,230,190,210, 57, 90,139, 21,176, 63,193,105, 44, 36,169, 17,217, 29, 0, 37,106,202,214,163,167,139, 75, 75, 81,233,166,150, -162, 87,154,103, 50, 73, 33,185, 39,231, 96, 58, 0, 54, 3, 97,182, 55,149, 85, 20, 42,139, 42,244,194,210,210,210,210, 88, 54, - 22,150,150,150,134, 6, 32,111,253,251,111,253, 25,127,246,206,255, 0,117, 13, 84, 31, 77,167, 61,189,153,157,251,127,142,111, -251,168,234, 6,201, 25, 61, 71, 79,216,116, 66, 7, 92,227,160,237,253, 29,191, 61,180,202,213,149, 2,195, 94,231,220,191,150, - 52,249,178,126,215,224, 63, 44, 79, 25, 63, 77,151, 39,255, 0, 6,119,218,127,150,103,111,251, 41,107,223,247,236, 95,244,103, -255, 0,219, 47,253,212,245, 4, 4, 2, 7, 95, 63, 47,223,170,169, 25, 61,186,122,250, 31, 81,243,210,126,219, 83,255, 0, 19, -240, 95,203, 24,230,201,127,181,183,192, 98,119,163,233,176,103, 24,246,104, 30,163,167,248,229,121,231, 24,255, 0, 53, 62,250, -168, 62,154,225, 35,175,179, 71, 31, 47,229,149,254,234,154,130, 42, 65,207, 67,215,212,255, 0, 96,209, 9,238, 1, 57,207, 66, -113,249,198,136,213,245, 67, 97, 37,143,253, 43,249, 99, 60,217, 45,187,126, 3,242,196,238, 7,211, 87,201,199,247, 52,251,255, - 0,207, 39,240,255, 0,146,174,190,171,233,171,114,130,127,185,167,159,151,242,200,255, 0,117, 93, 65, 69, 9,235,159,151, 79, -207,231,190,171, 4,115, 15,151,207,215,229,233,211, 26, 76,230, 21,118, 63, 93,254, 85,254,156, 37,237, 18,245,215,248, 15,203, - 19,165, 79,211, 89, 73, 4,159,102,170, 83,233,158, 50,135,207,254,106,191, 45, 18,215,211, 80,241, 19,205,253,205, 94, 80,123, -127,142, 62,115,255, 0,101,109, 65, 56, 67,100,168, 18,128,163,223,185,239,242, 25,237,223, 87, 54,211,203,202, 0, 0,118, 29, - 49,229,158,131,238,210,103, 49,173, 22,250,254,191,225, 79,233,198, 13, 68,189,155,240, 31,150, 39, 74,159,166,146, 79,127,102, -191, 47,111,249, 99,122,255, 0,213, 99, 85, 71,211, 69,207,250, 54, 71, 94,199,249, 98,244,199,175,249,172,106, 11,137, 0,145, -159, 63, 79,199,240,209, 41, 7,203, 0,118, 57,237,143, 77, 96,230, 85,191,241,191,202,159,211,140,123, 76,223,183,248, 15,203, - 19,158,254,253, 11,254,141,175,251, 98,127,186,206,189,143,166,127,144, 15,247, 54,241,159,249,225,255, 0,186,214,160,208,144, - 8,234,123,244,199,237,253,218, 36, 39, 29,124,250,119, 29,189,116,145,205, 43,199,251,255, 0,242, 39,187,252, 56,199,180,205, -109,218,196,123,135,229,137,201,143,166,116, 79,250, 55, 15,111,252,240,187,127,217,107, 94,199,211, 56, 39,191,179,119, 29, 51, -254,120, 95,111,127,241, 91,233,219, 80,111, 66,135,111, 60,254, 7, 24,209, 8,238,125, 72,239,223, 31,119,231,182,138,115, 90, -253,254,190,214,255, 0, 10,127, 78, 11,237, 51,116, 50, 88,250,233, 31,150, 39, 26, 62,153,166,112, 71,179,131, 57,237,142, 48, - 63,221,115, 94,135,211, 49, 57, 0,251, 55,241,156,227,252,112, 51,219,254,171,154,131,194, 82, 70, 48, 64,232, 51,143, 33,242, -252, 52, 66, 49,158,191, 96,244,255, 0,142,136,115,108,195,114, 42, 46, 7,248, 19,250, 48, 95,107,159,246,255, 0, 5,252,177, - 56, 65,244,203, 15,159,179,135, 31,245,191,207,255, 0,149,221,122,254,252,175,166,127,185,197,246,143,229,127,219,211,254, 75, -218,132, 10,112, 10,114,160, 9, 29, 7,168, 61,127,167, 94,243,144, 72,238,122,100,244,207,207, 69,253, 47,152,255, 0,204,127, -146, 63,233,198, 13, 93, 64,255, 0,121,248, 47,229,137,189,127,126, 89,255, 0, 71, 16,255, 0,239,127,229,235,254,107,186, 95, -223,150,127,209,197,255, 0,107,255, 0,247, 93,212, 32,130, 70, 78, 83,156,121,142,227,167, 97,235,175,129, 39, 36, 96,158,227, -228, 15,174,116, 63, 75,230, 63,243, 31,228, 79,233,198, 61,174,163,175, 50,254,235, 47,229,137,191,255, 0,126, 86,112, 79,247, - 56,187, 99, 63,227,127,235,216,255, 0,154,238,144,250,101,100,228, 15,103, 9,200, 56,255, 0, 59,241,143,159, 95,228,189,168, - 65, 28, 19,201,158,160, 12,125,189, 71, 93,124,228, 56, 61, 58,142,199,215,215, 67,244,190, 96,127,246,143,242, 39,244,227, 34, -170,163,188,157, 61,195,242,196,224, 26,250,101, 42,117,105, 66,125,155,238,173, 74, 90, 16,134,216,226,229,114, 31,117,110, 45, - 45,180,204,120,237,112,184, 87, 34, 67,142,173, 8,109,180, 2,183, 28,113, 40, 64, 42, 80, 26,145,125,139,237, 28,187,106,123, -107, 97, 92,219,161,195,163, 59, 99,184,215, 61,173, 2,228,186,182,189,141,220, 55,106,172, 25, 85, 68,137, 81,173,154,141,204, -118,206,154,106, 53,248,244,231,225,154,131,105,167, 50,136,178,214,252, 70,220,146, 35,151,215,249,251,123, 18,120, 79,167,111, -111, 18,114,247,186,251,163, 49, 85,218,222, 24,163,210,111, 53,194,156,128,245, 62,228,222, 74,163,175, 29,169,183,157, 96,172, - 9,108, 83,222,131, 80,184,101, 52,174,132,209, 41,225, 89, 75,196, 25,105, 85,110, 39,101, 73,126,161, 41,197,174, 75,239,169, -114,139,171,241, 63,239,176,162,251,170, 86,121,157, 65, 89,113, 67, 7, 35,169, 4, 18,115, 82,113,247,137,217,238, 79, 87, 22, - 91,147,230, 34, 26,136,198,185,156, 69, 79, 33, 23,221, 80, 44,145, 56, 6,222, 98,116,157,153,122,110, 71, 99,125, 27, 60, 13, -161,241, 3, 47,175,226,174, 50,162,122,236,146, 71, 48, 81, 64, 36,150, 14,107, 70,214,150,114,244,239, 20,133,117,222, 36, 93, - 65,110,172, 77,203, 45,186,186,215,180, 61,151,139, 72, 78,210, 40, 56,230, 50,147,125, 47,149, 37, 77,151, 65,231,254, 5, 97, - 72, 9,229,201,242,231, 29, 51,240,235, 38,139,199, 80,146,160,145,181,193, 5,104, 75,168,255, 0,223,202, 78, 90, 39,195, 82, -214, 13,164, 11,120,116,164, 96,142,161, 65, 94,120,215, 37, 97,212,227,199,149, 78, 9,151, 17,105,146, 42, 43,109,228,184,158, - 66,150,152, 96,162, 49, 81, 60,133,229, 15, 16,124, 93, 73, 25,192,198,117,127,135,119,198,133, 85,181,154, 92,152,232, 50, 28, -186,224, 45, 77,133,168,134,145, 77,106,160,134,156, 25,228,241,210,136, 43, 91,107, 60,205,168,199, 90, 80, 50,188, 26,248,120, -191,199, 91,223, 62,222,224, 91,217,168,122, 27,111,255, 0,163,123,205,183,183,173,183,183, 70,215,125, 26,252, 47,211,253,139, -131,216, 17, 28,143,189,110,104,215, 17,164,174,118, 53,123,111, 17, 95, 80, 78,224,219, 29,102,143,198,144,125,124,131,109, 74, - 72, 74, 85,145,120,165,105,198, 84,135, 7, 50,109,142,133, 46,164,167, 31,102,112, 78, 53,145,195,226,200, 74,117, 13, 42,195, - 67, 36,164, 41,197, 27,185, 11, 13, 21, 41, 73,194,147,252, 30, 10, 94, 8, 28,197, 41, 32, 5,103, 39,166,121,115, 2,240,167, - 70, 20, 80,180,187,134,229,185, 73,145, 29,134,150,242,101, 73,157, 30, 64, 97,134,152, 42,230,117,245, 61, 19,152,140,164, 39, - 42, 42, 1, 32,105,211,165, 85, 16,235,177,228, 37,200,205, 55, 48,170, 47,130,211,169,144,168,175,186,194,157, 76, 57, 13,129, -240,203, 11,104,243,140, 39,147,168, 74, 84, 64,202,195,197,222, 56, 99,182,126, 45,113,183,178,209,131, 98, 7, 66,105,253,247, -233,115,110,128, 3,138,247, 55,240, 35,129, 40,195, 21,225,118,129, 72,107, 19, 85, 94,119, 82,194,219,213, 27,146,171,175, 96, - 71,152,124, 11,113,237, 58,246,213,110,191,179,158,220,176, 55, 74, 7, 3, 3,126,182, 34,238,121,155,106,229,220,202, 87, 17, - 78, 89, 19,118,199,113,165,190,239,212,246,205,239,105,183,176,245,193, 6,220,171, 67, 74, 62,167,174,138,129,141, 46,106, 28, -166,201,143, 6, 89,138,153,124,121, 63, 76,188,131,211,217,192, 8,233,212,113,129,228,124,255, 0,205,115,211, 93,240,187,108, - 11, 23,121, 44, 27,215,104,183, 62,212,167,238, 22,218,110, 61,183, 91,177,239,203, 66,160,208, 85, 46,224,160, 85, 98, 2,253, - 61,213,161,121,131, 48, 56,162,244, 73, 72, 34, 68, 57,212,248,242,227, 45,183,153,109, 73,252,231,120,230,246,106,239,183, 6, - 60, 82, 94,220, 62, 83,108,205,193,221, 91, 81,182, 13,241,179, 87,213,187,104,220, 55, 36,155,231,104,106,242,164, 10, 21, 78, -166,154, 13, 41,239, 10,232,165,186,219,212,154,235,124,169,228,168,210, 87, 32, 1, 30,100,114,171, 79,131, 60, 72,204,115,136, - 37,165,205, 43, 2, 87, 83,141, 66, 67, 28, 72,146,161, 61,172,129, 53,165,192,178,216, 50, 16, 84, 54,151,115,201,126, 41,240, - 67,240,133, 90, 87,229,108, 70, 77, 84,193, 66, 19,169,160,115,246, 86,238, 90, 66,143,111, 41,114, 72,109,181, 29, 64, 44,156, -255, 0,191, 47,234, 71,247, 56, 71, 65,159,243,192,245,237,255, 0, 37,221,124,254,252,192,255, 0,251,184, 58,127,233,129,251, -191,146,230,161, 89, 94,176, 47,187, 81,114, 17,117,216,247,149,174, 99,171,195,147,252, 35,181,171,244, 20,198,115,152,128,219, -235,171,211, 88, 13, 56, 84, 8, 9, 81, 4,144, 64, 7, 88,123, 74, 75,159, 19, 69, 14,164, 21, 0,180, 45, 46, 36, 20,146, 20, - 9,109, 68, 2, 15,124,246,212,249, 51,218,185, 55,142,181, 92,123,132,103,248, 46, 42, 15,110,150,246, 51, 0,111,208,133,191, -238,181,241, 56, 81,244,203,137,239,236,225,192, 29,201,226,255, 0,215,254,171,186,248,126,153,120, 29, 15,179,135,175,203,139, -254,159,143,242, 93,212, 32, 71,158, 48, 9,235,223,204,253,191,118,188,167, 39,161,193,199, 83,242, 36,159,221,165,127, 75,230, - 63,243, 31,228, 79,233,193,189,170,162,223,222,111,255, 0, 72,252,177, 56, 1,244,203,201, 56, 30,206, 14,191,250, 95,255, 0, -186,238,190, 43,233,152, 4,128,127,185,195,159, 80, 56,191,234, 62,223,241, 93,212, 32,142,124,128,239,248,116,243,251,245,224, - 2, 84,115,211, 3,186,122,117, 63,111,200,157, 15,210,249,143,252,199,249, 19,250,113,159,106,159,254, 39,224, 63, 44, 78, 11, -251,242,241,128,127,185,197,247,127, 43,254,191,183,133,221, 47,239,203,198, 79,253,206, 35,129,231,252,175,186,125,255, 0,226, -187,211, 80,130, 66, 58,149, 12,115,116, 4,159, 63,159,111,206, 53,240,167,226,206, 58,142,135, 29,189, 58,232,126,151,204,127, -230, 63,200,159,211,129,237,117, 31,183,248, 47,229,137,190, 15,166, 96, 9, 35,251,156, 36, 99,204,241,125,223,236,255, 0, 21, -237,123, 31, 76,184, 28,127,220,226,239,156,127,141,247,167,127,249, 47,106, 16, 24,207,151,108,247,244,199, 92,126,124,181,244, -117,192,232, 61, 63,183,166,135,233,124,199,254, 99,252,145,255, 0, 78, 49,237, 85, 23, 31, 89,248, 47,229,137,191,143,166, 88, - 79,250, 56,122,245,233,252,175,255, 0,163,252, 87,122,235,233,250,101,100,119,246,112,227, 63,243,191,235,248,127, 37,221, 66, - 19, 3,190, 50, 71, 94,159,213,159,150,190,247, 32,249,119,193, 25,253,190, 93,244, 63, 75,230, 63,243, 31,228,143,250,112, 61, -170,163,254, 39,224,191,150, 38,238,126,153,113, 31,232,224, 56,245,254, 87,248,253,159,201,119,166,169, 43,233,153, 17,254,141, -252,140,227, 63,203, 3, 30, 93,255, 0,205,115, 80,137, 32,156,156, 0, 51,142,224,117,245, 61,123,245,213, 5, 32, 17,128, 51, -158,253,127, 63,145,172,254,151,204, 44,127,180,111,255, 0, 68,127,211,140,251, 84,255, 0,183,248, 15,203, 19,121, 63, 76,212, -130,113,236,221, 39, 7, 31,231,129,248,255, 0,201,111, 95, 15,211, 55, 35,183,179,120, 30,153,255, 0, 60, 47,217,254,107,125, -245, 7,245,128, 51,129,133,119,198, 14, 62,255, 0, 77, 10,172,140,244, 29,122,244,245, 31,111,111,237,209,151, 54,175,239, 83, -123,255, 0,129, 63,167, 25,246,169,251,191,224, 63, 44, 78, 33, 95, 76,228,167,253, 27,185, 30,191,203, 11,253,214,245, 72,253, - 51,220, 28,127,115,115, 63,245,194,255, 0,117,175, 77, 65,216,247,233,128,113,149, 30,227, 30,127,111,150,188, 16,112,114, 0, -207, 92, 14,248,249,244,232, 59,232,227, 53,175, 32, 30,127, 95,240,167,244,224,235, 81, 49, 23, 50,126, 3,242,196,226, 85,244, -208, 57,127,209,181,145,235,252,176,255, 0,221,103, 84,207,211, 67, 35,253, 27, 63,135, 24,191,238,177,168, 57, 45, 35, 56,193, -193, 29,252,191, 31, 95,234,208,235, 73, 57,230, 30,125,255, 0,163, 74, 46,103, 90,127,223,127,149, 63,167, 0,212,205,183,155, -175,184,126, 88,156,137,250,105, 24,200,254,230,199,108, 99,252,113,123,255, 0,217, 99, 84,213,244,210,249,127,209,175,159,250, -227,126,239,228,175,168, 52, 41, 61, 72, 62, 89,255, 0,142,168, 41, 56, 62,164,103, 31,126, 58,232,227, 50,173,255, 0,141,127, -251, 83,250,113,145, 81, 41,232,255, 0,128,252,177, 57,179,244,211,113,219,217,173,147,233,252,177,255, 0,221, 95, 94, 15,211, - 80,198,127,238,106,246,242,254, 88,253,127,254,213,181, 6, 5,142,164,147,229,220,116,200,251, 71, 97,211, 84,150, 6, 51,159, -179,211,246,104,227, 48,172,218,243, 94,253,244,175,244,227, 62,209, 55,237,254, 3,242,196,231,207,211, 85, 32,103,251,154,121, -199,252,242,113,255, 0,229, 87, 84,149,244,214, 72,255, 0, 70,150, 71,254,153, 61,191,236,169,168, 45,169, 56,237,219,247,143, - 95,191, 67, 44,117, 35, 3,175, 92,104,195, 48,171,190,242,237,255, 0, 74,254, 88, 56,158, 75,253,187,253,195,221,238,196,233, -215,244,215,249, 15,254, 13, 12,143, 95,229,149,251,191,146,159,174,168, 31,166,202, 57,185, 71,179, 56,159, 60,255, 0, 44,190, -159,179,133, 62,250,130,147,205,243,116, 35,207,203,167,159, 76,103,203,250,244, 42,153, 60,221,200, 3,183,150, 62,206,158,154, - 88, 86,212,216,125,109,255, 0,237, 95,203, 6,231, 73,183,159,240, 24,157,183,247,236,196,140,143,102,104,199,110,188,102,224, -231,211, 31,201, 71, 94, 15,211,105,229,239,236,204,199,253,115,191,221, 71, 80, 71, 82, 0,206, 51,208,227,167, 94,222,154, 25, -105, 72, 7, 35,174,124,242,122,252,243,246,104,235, 89, 57, 27,203,191,192,126, 88,199, 58, 77,183,189,253,195, 19,188,254,253, -183,254,140,191,251,103,127,186,134,150,160,120, 80, 60,142, 63,111,239,210,209,253,170,163,254, 39,224,191,150, 13,205,147,246, -191, 1,249, 99,234, 65, 0, 3,249,235,162,146, 15, 64,123,244, 31,156,106,138, 70, 79,203,207,243,246,232,132, 12,159,179,175, -223,157,105, 22,185,191, 75,116,194,120,174, 1, 61,189,113,249,249,106,176, 0, 96,121,121,254,253, 83, 70,122,244,200, 36, 12, -231,183,231, 58,174,144, 14,115,158,131, 61, 52, 76, 12,123, 74, 74, 73,234, 49,249,252, 52, 66, 7, 76,250,254,204,106,130, 50, - 71, 92,224,158,153,235,223,231,231,253,154, 41,180,246, 7,203,169,252,253,186, 65,141,205,241,131,176,191,166, 43,163, 29,135, -197,143, 79,159,217,162,144,140,142,131, 3,207,237,253,231, 84, 17,208,244, 3,175,125, 20,140,253,223,191, 68, 98, 69,192,194, - 36, 91,248,227,210, 7, 98, 79, 83,230,122,244,253,253,180, 72,193, 3,207,211,167,159,110,218,164,145,147,246,117,209, 9,237, -140,128, 1,200,251, 71,223,219, 73, 49,185,233,108, 99, 21, 18, 0,193,193,235,223, 61,241,233,162, 83,140, 14,157, 60,134,124, -191,118,168,164,115, 31,219,247,116,237,162, 80,158,163,167, 65,235,162,147, 97,115,219, 4,244, 23,177,255, 0,199,207,250, 98, -170, 64,242, 3,229,162, 82, 9,192,249,119,249,252,245,118,183, 45,171,130,238,172, 83,173,203, 86,135, 85,184,238, 26,180,164, -196,164, 80,104, 52,233,117,122,213, 90, 99,129,106, 68, 58,109, 46,158,203,143,206,146,164,161,100, 33,180, 40,242,182,165, 16, - 2, 73,213,222,187, 99, 94,182,156,151, 98, 93, 54,117,215,108, 74, 96,148, 63, 30,227,182,235,180, 39, 90, 90, 78, 20, 28, 77, - 82,158,215, 41,230, 7, 90,109, 60, 43, 32,137,165, 81, 43, 11,133, 36,106,181,237,123,117,183,107,224,250, 36,229,180,162, 54, - 49, 41,179, 56, 83,164, 27, 94,197,173,164, 27, 88,218,247,182,248,198, 80,144,123,128, 8,207, 65,220,156,249,122,157, 86, 70, - 62, 33,143,179,215,239,252, 63,110,188, 32, 18, 50,217, 14, 1,220,161, 73,115,211,185, 65, 56,237,162, 27, 73, 86, 58,128,125, - 7,127, 95, 61,101,136,223,126,191,127,195, 26,250,131, 11,131,127,120,239,138,168, 73, 56,233,212, 12, 30,190, 64,234,179,125, - 79,108,128, 65, 3,191,221,251, 53,245, 40,236, 58,103,190,122,253,191,187, 85,144,140, 43,169, 3,207,228,114, 15, 95,217,164, -240, 49, 84, 39, 42,193,232, 59,129,129,148,140,118,207,225,175, 74,108,245, 4,242,143, 47, 81,233,175,160,149,103, 24, 10,245, - 30, 99,243,231,175, 67,174, 2,178, 51,230, 48,123,121,159,195,246,235, 24,199,195,174, 40,165, 56,206, 85,212,156,142,157,254, -204,246,215,148,164, 2, 50,163,223,238,235,242,243, 58,172,224,201, 29,122,122,142,157, 51,140,159,151, 93, 92,168,148, 58,189, -195, 84,167, 81, 40,116,202,141,102,177, 88,152,213, 58,145, 73,165, 65,153, 85,171, 85,170, 18, 20, 16,196, 10, 77, 42, 3, 46, - 72,169,206, 90,136, 8,101,134,214,226,179,209, 58,195, 50,162,150,118, 10,171,185, 39, 96, 48, 91,133, 2,231, 97,181,254, 54, -183,239,197,153, 93,240, 57, 64, 30,106, 3,174, 51,128, 61, 53,233, 88, 67, 69,215, 84, 27,101, 56,241, 29, 89, 8,105, 40,238, -165, 21,172,129,140,103, 82, 39,224,247,232,242,113, 5,186, 44,209,175,126, 45,110,120,252, 41,109,245, 65, 45, 76, 98,212,168, -192,137,115,111,205,126, 34,210,167, 80,219, 22, 95,189, 38, 13,132,167, 80,143,133, 85,151,221,152, 18,178, 69, 47,152, 99, 82, - 25,217,126, 4,125,158,220, 32, 70,111,248,177,225,226,214,187,174,202, 84,112,204,221,208,222,132,198,220,171,212,205,121,104, - 12, 72,241,238, 54,151, 77,163,211,164, 45, 56,103,220,169,241,154,109, 74,229, 79, 82, 64,134,103, 28,115,148,101,101,145, 24, -213,204,187, 89, 14,215,247,144, 9,248, 27, 91,212,226,216,224,191, 5,184,251,142, 12,111,150,229, 38,134,142, 80, 8,158,164, - 20, 4, 18, 0,100,140,217,216, 94,195,204, 99,185,176, 23, 36, 3,170,254,203, 46, 26, 46, 77,165,224, 39,102,233,180,203, 98, -123, 55, 94,240,135,247,210,247,144,229, 50, 82, 28,149, 42,249, 17,191,130, 80, 39,169,184,229, 79,197,133, 96,194,183,154,100, -100, 99,197,117, 73, 37, 43, 81, 86,234, 87,236,203,238,132,204, 33, 46,221,170, 32,138,139, 45, 45,243, 6, 98, 99, 20,165,137, -143,123,195,179, 60, 34, 27, 65,240,249, 15, 57, 79, 42,214, 17,130, 72, 35, 99,155,223, 42,234,221,136,202,101,194,143, 66,171, -184,105,112,211, 76, 5,132,211,101,181, 28,123,180,100, 71, 82, 83,238,168, 82, 80,227, 9, 67, 73, 8, 14, 54,132, 97,180, 20, -130, 37, 39,125, 42,234,171,170,153, 34,124,151,131,206,170, 19, 32, 54, 57,101,207,141,200,137,172, 48, 57,190, 37, 8,222, 27, -165, 60,170, 39, 42, 9, 10,109, 42, 35,158,243, 89,104,243,106,250,186,249, 38,156,203, 86,236,231,104,202,139,157,149, 87, 85, -236, 1, 10,190,110,130,198,230,248,244,231,129,168,248,183,129,184,107, 38,225,202, 14, 30,163,155, 47,200,105, 99, 77, 38, 89, -121,146,114,215, 68,146, 59, 8,236,178, 22, 87,121, 1, 82, 69,181, 95, 73, 7, 26, 81, 90,169, 61, 79,168,208,167,204, 91, 44, -184,170,148,168, 83, 66, 11,141, 70,124, 78,167, 84, 35, 51, 29,198, 66,130, 11, 8,121,168,165, 36,146,181, 41, 14, 44, 21, 40, -224, 88,100, 92,178, 84,252, 41, 12, 58,134,169,236,223, 20, 56, 17, 31, 91,158, 31,213,209,106, 45, 85,162,212, 38, 53,239, 67, -159,220,194,222,100,171, 9, 37, 41,111, 45,133, 37,120,214,238,238, 21,145,110,110,237, 53,104,141, 18,147, 65,187,160,213,226, - 84,226, 75, 44, 52,154, 77, 70,163,111,200,247,152,240,235,208,227,114,167,192,113, 14, 20, 25, 44,164, 59, 28,191,226, 56,135, -145,206,141,115, 74,240, 69, 70,139, 58,226, 93, 94,157, 42,151, 38,217,171,209,163,191, 18, 75, 72, 91,241,167,211,107,148, 86, -235, 13,120,141,225, 15,143,117,147,200,218,176,158,118,242,164,158, 78,241, 42,202,121,105,230, 69, 46, 37,138, 83,229, 96, 54, - 39, 96, 53, 11, 27, 48,191,217, 61,150,247, 32, 99,163,184, 11, 53,202,248,178,154, 72,228,131,244,126,105, 66,170,147,211, 72, -202,218, 17,229, 26, 94, 18, 8, 15, 27, 23,116, 14,187, 34, 6, 89, 17, 67,170, 54,206, 82,238,185,177,160,198, 76,229,153, 13, -208,110, 74, 4,198,235, 44, 56,149,128, 69,106, 35, 41,155, 33, 8,201, 46, 37,233,173,153, 1,226, 91, 60,203, 41, 39,176,223, -221,171,219,215,238, 40,178, 42,213,233, 10,163,209,233,181, 8,142, 38,114, 84,251,110,185, 54, 35,209, 31, 13,197, 91,138, 79, -143,206,150,212, 57,242,124, 38,229, 16, 84, 73,240,213,204, 75, 50,143, 87,173, 84,164, 89, 20,181,168, 46,225,151, 26,159, 71, -109, 65, 14,184,229,111,223,226,166, 53, 41,224,179,148, 64,114, 79,132, 90,113, 73,200,104,184,146,174,118,146, 79,101,175,201, -205,219,204,155,102,128,180, 26,125, 18, 28,150, 98,195,105, 10, 14, 85, 92,139, 49, 44, 74,113, 69,160, 66,149, 34, 98, 36, 58, - 20, 83,202,178,235,104, 56, 3, 26,125,225,170,120,167,231,215, 85,141,112,211,105, 68, 66,108, 25,200, 98, 1, 35,204, 2,129, -118, 32,139,221, 73,211,171, 88,164, 60,112,168,124,170,167, 38,200,178,103, 72, 51, 44,237,231,149,166, 81,253,213, 50, 10, 79, -172, 10, 67, 42,201, 44,175, 42,128,126,168, 90, 67,176, 82, 27, 44,157,124, 91, 86,163,172,210, 40,209, 33, 66,112,182,149, 48, -228,143, 4,186,243,202,144,134,136, 71, 50, 71, 59,195,196, 43,253, 81,128,121,143, 54, 9,213, 9,123,191, 49,153,245, 55, 35, -206,109,168,116,233,113, 41,236,173,165,115,203,126,108,150, 24,126, 66, 34,165,149,164, 32, 41,215,163,182,233, 78, 22,166,155, - 90,143, 48,108,145,165, 85, 75,154, 37, 70,161, 46,164,219,243,155,165,183, 95,162, 83, 41,204,184,183, 31,120, 38, 3,190, 45, -101,232,203,231, 40, 76,115, 83, 50,127, 74, 20,164,143,112, 40,242, 9, 31, 98, 92, 79, 79,129, 78,140,203, 11,121,138,245, 72, -215,101,185, 49,196, 39,158, 19, 18, 21, 36,165,158, 84,115,163,196,105,234,116,116, 44,252, 60,143,172,114,249,234,105,237,243, -234, 88,226,151,149, 96, 84, 34, 93, 22,215, 29,128, 4, 3,181,141,183,216,168,177,185,166,163,240,166,136, 67, 12,245,145, 53, - 84,238, 0,153,166,177, 96,204, 18, 87, 55,144,155,186, 70,146, 43, 45,216,107,212, 1, 59, 91,122,169, 91,167, 70,186,227,184, -197,203, 10,131, 87,163,189, 10, 69, 85,214,171,148, 90, 69,113,166, 35, 70, 56,136,137, 81,234,204,184,151,100,173,214,164,200, -104, 6,254, 24,254, 26,193, 30, 33,214,177,238,127, 2, 62,206, 30, 34,208,151,119,167,131, 14, 31,170, 51,171, 76, 70,150,170, -189, 2,208,133,100, 93, 16,152,156,135, 92, 15,166,232,176, 13, 54, 74,101,165,135, 57,220, 33, 69, 97,249, 39,169,192, 0, 26, - 93,210, 95,153, 46,142,195, 48,212,207,240,138, 76,170,188,247,144, 86,212,166, 41,209, 88, 17,109,147,200,217,240, 91,113,230, - 10, 86,128,162,166, 98,165, 96, 97,201, 9, 78,178,250, 69, 65,249,177,152,150,228,245, 53, 78,141,239,234,159, 40,211,220,125, -234,189,102,123,128,204,166,210,121, 79, 70,152, 89, 40,114, 90,121,185, 11, 65,166,199,232,221,121,189,200,179, 42,152, 93, 92, - 75,230,181,135,235, 18,204, 69,152,107,221, 75, 2, 72,234, 69,174, 46, 14, 32, 60, 65,225, 38, 67, 80,102,246,156,185, 96,142, - 64,186, 65, 26,216, 43, 6, 40, 6,149,221,157,212, 46,150, 93, 69, 68,110,116,131, 41,199, 40, 55,231,232,175,112, 39,186, 52, -233,149,158, 27,247,143,120, 56,116,174,173,153, 18, 34,210,174, 57,144,247,130,194,102, 74,185,149, 26, 52,200, 23, 10,162, 86, - 96,176, 86,182,130,146,213, 93,197,161,183, 1, 8, 39,149, 38, 53, 60,110,123, 1,189,162, 92, 20, 64,171,222, 82,246,226, 47, - 16,123, 65, 75, 15, 72,127,116,120,126, 77, 82,239, 20,202,115, 40, 46,174,117,219,183,111, 65, 69,126,215, 97, 8,232,243,169, -139, 58, 27, 74, 74,185,166,114,142, 99,250, 18,209, 46,181,183,224, 68,113,102, 52,106,107,177, 37,200, 76, 89,105,113,113,218, - 56,118, 12, 55,101, 50, 10,230, 23, 86, 85, 37,215,208, 22,167,192, 67, 77,169, 69,206,125,108,205,177,123,137, 81,132,228, 77, -240,230, 79,154,105,244,170, 68,172, 70,170, 45, 44,243, 23,229,205,128,165,133,198, 42, 67,110, 60,176,176,144,220, 86,155, 75, -156,175,184, 82, 37,249,111, 22, 85, 64,218, 42, 36, 46,150,235,171, 86,247,176,186,185, 5,172, 47,228,140,198, 46, 44, 72,234, -121,147,139, 60, 39, 92,176,153,168,117, 68,140,198,218, 71,144, 3, 98,138, 64,212,159,103, 84,140,214, 0, 32, 12, 28,131,124, -126, 50,105,198, 21,146, 20, 2,150,143,132,228, 7, 26, 81,109,214,212, 65,248, 92, 74,194,146,164,156, 20,169, 37, 42, 0,131, -165,219,161,234, 58, 18, 58,228,124,254, 71, 95,166,111,180,163,216, 17,194, 7, 31,240,238, 45,193,218,248,212,110, 26,248,173, -144,137, 82,206,229, 89, 52, 54, 25,176,183, 2,186,219, 40,113, 49,183,135,111,169, 74,106, 53, 73,215,223,228, 75,245,122,111, -187,214,152, 50, 20,235,206, 84, 2, 61,217,127,158,255, 0, 24,156, 20,241, 33,192,134,239,206,217, 30, 38, 54,238,125,139,118, -182,211,245, 43,118,166,211,159, 90,217,123,137,109, 53, 37,113,155,187,182,234,235,101,180,177,115, 80,148,226, 64,116, 0,220, -200, 46,171,221,234, 49, 34, 72, 30, 25,177,178,252,214,159, 48,137, 36,141,135,159,161, 6,234, 78,231, 77,251, 48, 0,221, 90, -199,202,197,117, 32,214,105,170,234, 26,172,186, 65, 29, 84,101, 65, 54, 87,177, 10,215, 32, 13,141,138,150,236, 14,199,245, 75, -111,141, 87,232, 7, 78,223, 46,186,240,164,147,156, 28, 3,215, 4,145,249,235,175, 68,129,142,189, 7, 76, 99,191,151,125, 32, - 65, 39, 61, 71, 76, 36,140,103,167,252,116,233,141, 78,248,166, 18, 9,199, 92,122,143, 95,234,239,175,161, 36,250,244,200, 30, - 93,115,158,191,142,170,121,127,171,248,116,215,196,144, 1,202,147,156,231,167, 92,228,232, 96,111,143,129, 56, 33, 89,201, 25, -230,243,242,215,164,117, 4,143,135, 25, 61,115,251, 63, 29,125,233,140,254,206,216,252,245,215,209,215,246, 12, 1,220,121,253, -253, 52, 48, 58,123,176,136,207, 68,245,233,231,142,164,103,246,106,130,219,198, 9,242, 61, 70,124,244, 78, 14, 58,140,121, 2, - 70, 49,246,252,191,175, 84,207,110,131, 39,246,103, 63,212,127,167, 88, 6,255, 0, 17,140,224, 37,160,224,249,103,215,184,207, -168,252,247,208,170, 64, 0,231, 36, 18,123,250,252,190, 90,184, 57,205,158,184, 61, 58,231,190,125, 58,121,245,208,238, 32,242, -231, 4,117,232, 58,231,175,203,236,214, 65,232,122, 99, 32,158,221, 78, 45,197, 1, 39, 32,245, 29, 49,158,152,199,174,188, 20, -231, 36, 28,121, 28,159,179,207,240,209, 42, 73,234, 20, 7, 79,245,123,146,126,126, 67,174,168,242, 12, 40,100, 99,166, 0,243, -235,158,231, 75,169,184,235,131,168, 34,219,109,243,243,111,195, 3, 40, 3,212,147,129,248,125,186,160, 70, 70, 63, 35, 70, 41, - 35, 56, 30,153, 63, 44, 13, 12,180,144, 73, 3,167,246,126,206,186, 81, 79,108, 24,216,116, 23,254, 71, 0,184, 0, 32,116,206, -122,159,217,215, 31,158,154,162,160, 78, 58,100,103,175,175,221,163, 20,147,230, 7,221,216,158,250, 25, 89,201,230, 56, 39,183, -207,211, 31,119,244,105, 92, 1,208, 95,113,129, 22,128,114, 64,199,200,249,250,140,104,117, 35,166, 6, 1,239,246,103,200,244, -209,138,206, 65, 56,207,160,242,208,199,169,200,207, 95, 92, 14,221, 63,118,149, 7,160, 39,167,207, 95,158,248, 54, 5, 87, 76, -228,103, 25,253,159,187, 66,172,116,206, 15, 78,216,253,164,244,237,211, 70,172,100,142,152,235,220, 30,253,124,255, 0, 62,122, - 25,196,228,156,100, 1,208,227,182, 79,228,104,248, 50,250, 91,127, 92, 91,215,128,112, 14, 73, 39,167,161, 29,123,232,115,223, -168,235,158,191,184,104,199, 19,144, 83,211, 62,126,189, 61, 63, 13, 12, 80, 70, 78,114,125, 15,225,223, 58, 89,122, 97, 81,107, - 3,210,216, 29,105,243, 25,206,133, 90, 72, 39,183,153,251, 62,223,150,116,105, 25,251,186,250,103,228,126, 90, 25,105,206, 73, -200, 62,126,125, 59,253,250, 85, 79, 91,157,176, 69,216,144,119,183,250, 96, 34, 48,113,165,175,107, 73, 39, 35,175,224, 52,180, -174, 15,113,220,216,227,234, 49,143,233,209, 40, 24, 3,231,215,243,247,106,128,198, 6, 1, 31, 35,223, 85,211,204, 59,128, 49, -233,223, 61, 58,233, 18,118, 3,231,221,140,226,178, 60,250,253,223,191, 85,209,220,253,157,189,127, 63,191, 84, 81,143, 33,215, -204,234,178, 6,122,231,177,237,249,242,254,173, 16,157,137,190, 6, 8, 78,112,112, 70, 7,124,143,196,244,243,233,162, 27,234, -126,239,234,213, 4,125,189,188,191,126,189, 18, 64, 86, 14, 8, 30,125, 1,207,244,255, 0,102,181,216,133,193, 78,224,142,199, - 7, 54,115,211, 61, 62,206,158,126, 99, 69,164, 14,128, 16,123, 15,151,236,213,189,146,233, 74, 78, 19,142,153,251,112, 63,171, - 71, 55,223,162,122,140, 28,224,246,249,233, 34,215,194, 71,174, 43,165, 61, 65, 57,232,123, 99,191,167,237,209, 9, 0,142,169, -249,103, 39,175,175,217,170, 64, 18, 71,145,233,231,230,123,231,229,170,232,200, 36,116, 29,135,203,168,243, 62,103,182,176, 73, - 61,123, 96,167, 21,209,156, 1,208, 14,195,241,243,249,104,148, 3,216,156,228,224,103,250,117, 65,160, 72, 29, 58, 3,231,163, - 16, 58,231,175,203,211,211, 73,191,175,207,108, 99,107,145,181,206, 58,159,236,114,180, 36,215,120,223,178,238,166, 92,121,134, - 54,178,207,191,175,249, 50,154, 42, 65,101,248,212, 39,104, 52,196,151, 17,213,181, 46,101, 96,132,144, 65,248, 62,103, 82,170, -147,119, 79,171, 52, 99,214, 12, 27,130, 56,200, 92, 43,154,147, 73,175,197,113, 32,149, 96,181, 85,136,238, 83,215,166,114, 61, -117, 30,111, 98, 93, 13, 12,206,226,110,249, 80, 74, 93,129,102,217,118,147, 11, 61, 22,147, 89,172,205,170, 73, 66, 84, 58,128, -180, 66,104, 17,242,215,110, 85, 89, 62, 34, 74, 78, 18,162, 18,178, 78, 2, 72, 24,243,252, 53,207,158, 33,214, 52,188, 67, 60, - 91,218,146, 56,163, 6,254,160, 73,191,190,242, 16, 55,233,143, 67,190,140,252, 57, 24,240,222, 10,185, 97, 89, 6,113, 87, 87, - 57, 12, 1, 4, 44,130,152, 2, 8,181,138,211,143,223,140, 91,113,184, 80,224,223,122, 90,127,248,197,225,195,111,141, 78, 74, - 74, 28,185,236, 6,100,109,189,210,202,149,255, 0,194, 25,155,109, 45,182, 30,116, 14,184,114, 58,193, 35, 36, 29,114,235,126, - 61,136,232,153, 30,101,195,194, 78,234, 11,142, 74, 18,167, 81,180, 59,192,184, 84, 27,145,224,126, 38,225,219, 27,129, 13, 41, -129, 85,124,254,171,109, 79,106, 42,220, 56, 5,240, 78, 79, 93,141,126, 51,110,161,151, 93, 72, 82,213,250, 21,147,128,162,159, -242,172,156,116, 75,192, 96,143,245,128,214,109,101, 34,179,125, 87, 98,219,150,188, 73,117, 58,171,235, 8, 75,113, 88,113,228, -190,130,160,148, 6,130, 7,194,176,163,212,158,137, 41,207,108,226, 37, 67,197, 89,254, 85, 44,107, 65, 92,242,128,109,202,127, -172,140,251,130, 53,244,131,234,154, 77,174, 21,133,241,105,113, 79,128,254, 26,113,109, 13, 76,249,182, 65, 22, 83, 80, 16,177, -174,164, 11, 73, 52,123,127,120,210, 70,162, 57,108,123, 78,146,165,250,169,223, 16,133,191,246,226,251,218,171,186,173, 97,110, - 77,165,112,216,183,165, 5,229, 49, 86,182,110,106,115,212,202,172, 69, 5, 40, 7, 80,219,163,150,100, 37,129,150,164, 48,167, - 88,117, 63, 19,110, 40, 29, 97,233,193,243, 24, 29,250,143,184,116,215,232,143,190, 62,204, 45,147,226, 95,110, 34,219, 28, 90, - 85,225, 64,173,211, 34, 4,217, 87, 45, 7,192,123,116,108, 57, 14, 35,197, 13,193,172,182,131,239, 52,194,172,248,180,249,101, -232,171,201,194, 80,172, 40,106, 85,157,236, 48,246, 94, 89, 49, 96, 11,150,111, 16, 59,185, 80, 43, 83, 18, 93,168,222, 84,251, - 54,159, 41,214,155,241, 92, 81,129, 64,166,133,196, 36,117, 74, 67,170,207,108,116,206,173,202, 63, 17, 40,214,142, 55,205,233, - 13, 21,112,217,227, 87,141,135,185,128, 46, 29, 67,117,210,202, 74,244,212,246,213,142, 20,207,126,143,124, 95, 14,119, 61, 31, - 6,200, 56,195, 36, 55,104,107, 68,114, 83, 2, 59,199, 46,168,204, 70, 69,177,250,200,100,120,157,124,223, 84, 73,137, 96,225, -130, 70,121, 22, 8,237,202,133, 96,250, 28,227, 72,168, 32, 0, 58,146,113,140, 31, 63,151,222, 53, 61,230,125,146,190,201, 76, - 62,208,225,254,252, 87,128,217,112,248,251,193,118,173,197, 4, 39,152,242,173, 11, 29,115,211, 32,117,193,211, 69,186, 94,193, -159,103, 5,247, 75, 55, 6,222,220,187,247,177,170,142,168,178, 84,212, 27,150,141,124,210, 39, 70, 74,144,228,182,226,199,187, -233,222, 60, 23, 11, 1,196, 7, 82,242,195,107,113, 42,240,151,142, 83,177, 77,226, 46, 75, 83, 47, 41, 81,193,177, 55,242,216, - 0, 46, 73,185, 22,183,223,238,190, 25,235,190,143,254, 42,229,177,123, 69, 87, 14,170,171, 21, 80, 22,161, 11, 51, 57, 1, 84, - 2,160, 93,137, 3,114, 63,142, 35, 1,192, 79,179,155,127,248,252,190,165,208,246,210,151, 26,220,219,219, 90, 68, 49,185,187, -209,119,179, 45,157,189,219,184,210,112,227,112,228, 57, 29, 33,219,162,244,145, 27,153, 80, 40, 80, 57,165, 61,128,236,151, 33, -196, 10,146, 38,173,194, 71, 5, 92, 32,251, 61,109,198,127,137, 11, 71,248,111,187,134, 47,186, 92,156, 68, 95,208,233,213, 77, -203,169,188,166,210,220,230, 45,176,210, 20,198,221, 91, 60,222, 42,147, 78,163,161, 14,132, 16,169, 50,102, 40, 41,100,251, 2, - 70,221,108,222,222,208,118, 35,135,219, 98,141,182,187, 99,183, 80,221, 22,253,169, 5,240, 28,175,120,202,109,117, 43,158,224, -172,168, 42, 69,193,113,212,166, 35,154,109, 86, 73,117,239,122, 88, 75,220,172, 22,219, 70, 15, 39,112, 35,202,153, 34,108, 9, - 83, 16,228,242,167, 30,167,205, 67,209,101, 60,247, 40, 75,203,132,133,184, 16,103,115, 6,213,204,193,117,183,249,130, 73, 35, - 5, 53, 87, 20,120,131, 91,154, 84, 73, 73, 68,198,158,137, 73, 10, 65,221,198,214,239,181,250,134,185,234, 8, 61,113,217, 30, - 12,253, 20, 41, 50,184,169,243,158, 45,133,115, 76,244, 44,114,114,236, 90, 10,109,118,101, 69, 7,109, 69,110, 68,166,247, 32, -244, 91, 5,122, 46, 93,207,151,112,185, 82, 84,201,237, 85,196,152,174,184, 88,241, 23,239,197, 8,146,129,239,112,210,195,217, -143, 82, 97,220,134,151,240, 7,148,160,230, 82, 64, 42,108, 46, 11,170, 52,200,142, 42,108,229, 75,154, 25, 10,128,251,176,220, - 69, 62,231,164,248,160, 73,129, 34, 43, 32,148, 79,109,191, 21,101,149, 97,198,164, 54, 36, 52,149, 5,184, 19, 97,136,251,117, -212, 9,207, 47,222, 75, 83,204, 70,166,198,109, 84,203,178,149, 49, 96, 25, 28,237,178,132,166, 28, 66,181,167, 45,188,144, 84, -217, 47, 45,181,163,161,199,231,178,168,238, 61, 67,174,165, 50, 30, 68,210,138,101, 69, 41, 66,226,214, 24,154,175, 18, 68, 23, - 25,200, 16, 43,237, 53,206, 89, 40, 41,101,229, 18,227, 11, 67,153,107, 85,228,149, 94,103,214, 88,177,181,218,251, 49,190,198, -219, 19,126,194,199,107,117, 59, 14,220,202, 56,115, 41,161,100,166,134, 46, 65,164,220,199, 24, 80,202, 6,149, 99, 29,208, 93, - 86,200,179, 38,148,109, 12,205,160, 36,107, 36, 87,151,170,161,165, 46,223,113,167,151, 78,170, 42, 43,148,218,139,143,133, 60, -212,244, 50,100,136,203,150,242,135,136,250, 60, 22,164,198,112,144,183, 19, 29, 76, 58,165, 45, 0,185,112,131, 94,118, 83,239, - 68, 41,110,145, 84,110, 85, 61, 77, 75,109,178, 94,166,215,169,104, 8, 67,209,226,188, 8,118, 28,136,175, 69,146,129,147,227, -180,167,144,130,160, 73, 24,237, 74,148, 41,180,184,241,225,200,118,224,181,231, 71,136, 98, 84,161,159, 30,183,110, 75,101,207, -122,101,135, 67,139, 34,171, 78, 67,173,161, 72,116, 98, 92, 85,128,204,132, 60,193,241, 18, 44,199,101, 84, 85,252, 43,112,177, - 42, 84, 4, 52, 95, 52,245, 4,179, 84,167,160, 46, 60,163,202, 84, 82,137,173,158,119, 35, 43, 36, 50,180, 41,160, 2, 22, 0, - 48,114,196,178,177, 80, 55,211,178,238, 64,223,114,118,234, 70,226,196,234,190,160,112,250, 40,232,234, 98, 13, 29,180, 72, 74, -135, 58,129, 51,142, 88, 77,113,191,149, 76,133, 66, 76,142, 54, 49,137, 46,240,201,115,180,187,121,113,159,112,167, 74,168,126, -134,164, 39, 75, 21,246,192, 76,150, 24,152,101, 59, 6,160, 22,251,164, 23, 22, 86, 34,169, 37, 64, 41, 77,186,215,114,156,150, - 43,139, 43, 97,169, 85,218,101,105,162, 25, 69,219,106, 92, 52,234,159, 51,106,114, 59,213,187, 98, 11,114, 96,186,162,129,133, - 58,105, 47, 71, 91,228,165, 74,112,210, 83,241, 18,146, 11,135,106,214, 98, 78,172, 73,102, 43,177,164, 67,184,105,116,249, 76, -184,164, 4, 42, 59,240, 23,245, 98,155,113,151,208, 49, 37,216,174, 66, 88, 82,250, 45,200,200,202,137, 72, 26,161,196, 82,249, - 44,237,191,114,123, 77,202,228,191, 13, 50,108,176,183, 27, 75,109,213, 41, 83,161, 73, 7, 42, 42, 37,230,219,111,224, 71, 41, - 82,129, 72, 56, 26, 82,178,211, 80,176, 96,117, 33, 87, 27,130, 65, 15,123,139,250, 43, 17,247,133,176, 59,154,251, 35,230,229, - 30, 34,101,181, 84,209,154,121,115, 5,168,137,162, 38,222, 89,169,228,145, 35,177, 23,211, 13, 74, 42,128,222, 98,209, 33, 93, -247, 45,207, 13,114,155,103,122, 54,250,161, 33,214, 94,250,215,234,202,139,111,115, 54,235, 9,117,115, 33, 84, 25,247,117,161, - 36,186, 75,171,142,226, 92, 32,132,169, 8,234, 2,250,244,178,232,151, 46, 85, 85, 97, 46,180,218,152,141, 41,185, 10, 82,146, -133, 56, 87, 49,135, 28, 75,206, 54,128, 82,149,182,149,114,148,252, 73, 40, 42, 25, 63,173,202,173,165,149,245, 27, 59,105, 37, -133,198,106, 75, 46,199, 11,153,201,226, 56,179, 68,204,101, 51,206,133, 4,148,184,138,122, 64,229,229,233,145,221, 56, 61, 81, -185, 75, 51, 27,159, 80,109, 41,125,186,148, 24,239, 53, 37,180,135, 92,106, 52,136,171,113, 78,165, 68,140, 37, 16,223, 89, 4, -156,167,195, 25, 30,171,240,236,165,105,234,169,128, 26,161,150,226,251, 18, 25,116,220,216,131,250,167,125,192, 39,222,113, 12, -241,161, 4,252, 89,144,102,166, 63, 45, 69, 19,211,173,192, 32, 52, 53, 5, 73,183,217, 0,172,167, 96,196,253, 93,251,227, 89, -170,116,137,115, 41,150,180, 88,239, 52,228,155,128,190,219,171,105, 45,132, 20, 84,125,242,101,110, 97,109,192, 60, 15, 6, 4, -169, 41, 7,205,101, 42, 4, 30,100,235, 48, 98,100,183,170,109, 55, 77,129, 26, 53, 90, 77, 38,159, 64,165, 69,109,165, 59, 30, - 52,118, 31, 90,205,199, 80, 1,144, 68, 88,139, 74, 3, 44,182, 0,117, 80,218,100,243, 23, 20, 81,245,170, 20,128,229,191, 57, -231, 18,227,180,170, 21, 94, 83,170,231,105, 13,211, 41, 41,129, 19,194, 45,180, 74, 72,152,162,162,165,171, 24, 90,155, 91,121, - 64, 1, 10,190, 89,208,106, 49,147, 38,123,140,190, 42,215, 59,205, 63, 4, 41, 77, 7,232,116,248, 77, 39,221, 90,229, 3, 45, - 60,220, 25, 11,121, 77,164,169,180,203,154, 2,178,180,171, 50, 56, 55,242,106, 47,163,123,251,137,182,215, 39,127,128, 23, 32, -147,183, 70, 90,252,198, 22,163,102,103,142,115, 15, 52,168, 39, 72, 47, 37, 68,133,131, 88,139,196,145, 68,178, 49, 42, 54, 4, - 38,158,106, 17,126,147, 14,157, 74,146,213, 34,214,106,160, 3,145, 23, 72, 93, 65,214,154,147, 60, 45,214,208,171,150,181,227, - 40,145, 58,176,135, 20, 0, 88, 40, 71,191, 85, 50,133, 16,199, 40,204,233,149,217, 16, 81, 74,106,213,167,196, 41,166, 68, 93, - 61,218,202,202,222,163, 83, 36,180,202,163, 63,224, 83, 73, 82,235, 51,209, 30, 63, 41, 12,169, 45,248,223, 4,213,169, 74, 90, - 53,128,211,101, 42, 82,164, 55,109,135, 89,147, 41, 74,163,196,152,181, 2,229, 14,132,196,169,105,114, 84,194,235, 37, 15,213, -165,203, 74,222,142,144, 8, 75,184,116,146, 25,235,123, 77,126, 53, 26,159, 50,222,163, 82, 34, 87,170,209, 34,199,165,211, 98, -196,145, 42, 52, 27, 97,182,148, 76,169,143,206,119,244, 45, 5, 21,254,145, 74, 46, 58,167, 16,167, 2, 71, 51,139,214,220,104, - 21,172, 65, 37,238, 69,201, 58,119, 82, 55, 23, 34,254, 81,127, 40,177, 82, 54, 23, 48,154,250, 57, 42, 21,105,164,129,171,170, - 20,141, 98, 87, 0,144,254, 73, 38,170, 44,234,129, 19, 88,176,146, 78, 89, 34,103,179,171,162, 77,157, 81,164,143,123,163, 8, - 73,114, 60, 56, 14, 56, 25,153, 92, 82, 27, 64,113,230,129,159,116,212,234,141,165, 30, 35,232,150,149, 34, 26,138, 67, 35,195, -229,195, 64,160,161,215,163,214,229, 61,114,193,118, 3, 18,169,144,234,116,244, 83,105,213, 73,128, 42,170,162,244,180, 53, 84, -173, 73,139, 52,114,195,114, 72, 17,209, 13, 46,130, 91, 66,252, 80,144,164,132,233,150,102,139, 89,170,162, 58, 42, 11,109, 2, -156,194, 86,221, 33,181,251,181, 38, 42,218, 67, 77,174, 97,127,153, 78,214, 92, 14, 2,191, 29,239, 13,182, 62, 55, 80,210, 57, -121,206,113, 74,153, 54,127,189, 8,203, 67,140,225,184,143, 85,220,123,222,211, 87,121,197,162, 59, 80,232,138, 96,225,196, 37, -231, 93,231,158,158,124,173,226,166, 18,183, 1,113, 59,104,206, 7,217,212,166,214, 54, 39,125,193,177,184,189,190,201, 2,219, -129,115,109, 36, 64,115,202, 58,106,133,145,131,199, 51,172,111, 27,220,150, 84, 18, 57, 32,181,236, 38,119,102,187, 2,172,173, -245,138,161,227,115, 42,109, 53,183, 89,113,151,211, 75,165,167, 49, 32,171,220, 30, 90, 20,243,205, 83,164, 33,100, 75, 87,189, -190,190,121, 21, 18,250, 71, 48, 94, 91,105, 75, 43,121, 74,230,229, 45,103, 23,124, 32,112,213,237, 11,217, 74,166,193,241, 37, -103,179,117, 80, 93,247,138,133,163,115, 83, 94, 17,183, 11,108, 46,100,165,216,113, 47, 43, 30,236, 12, 41,116, 27,141,183,211, -202, 18,144,184,181, 22,208, 98,204,139, 46, 18,220,104,135, 30,225, 76, 56, 81,105,212,133, 48, 41,180,229, 70,162,206,126, 38, - 92, 98,148,206, 66,164,193,166,164, 45,105,171,200, 68,140,120,203, 37, 97, 47, 60,174,114,244,144, 80, 29,171, 42,165, 30,155, - 49, 51, 37,181, 81, 79,132, 15,185,196,151,151,234,114, 30, 44,248, 41,113,104, 4,248,238,184,148,190,180,184, 74,188, 52,182, - 16,234,154, 81, 58,124,203,115, 9,169, 39, 2, 57, 12,104,246, 82,172, 26,204,163, 72, 34,253, 44, 52, 92, 91,236,149, 12,133, -109,183, 62,241,103, 9, 69, 81, 77, 83, 52,208,150, 44, 27, 66,145,121, 36, 63,181, 37,206,204,250,129, 61,116,169,212, 89,131, - 43,201,249,104,123, 74,253,155,155,225,236,203,226, 10,102,204,110,202, 63,132, 86,125,198,138,149,127,100,183,134,155, 1,112, -237,173,219,177,225,202, 67, 75,152,211, 60,203, 77, 6,247,167,123,204, 54,107,180, 85,184,167, 33, 62,251,114, 35,170, 69, 54, - 84, 73, 46,115,200, 36,167, 25,234, 60,137, 61, 71,217,242,198,191, 92,191,104, 95, 2, 27, 99,237, 47,225, 82,247,225,235,116, -208,197, 6,191, 47, 55, 54,209,110, 43, 17, 27,149, 84,218, 45,211,165,197,120, 90,215,101, 56,171, 11,149, 13, 70, 66,225,214, - 96,115,165, 21, 26, 85, 74, 92, 66,166,214,227, 79, 55,249, 64,239, 46,206,238, 55, 15,155,187,185,155, 17,187,212, 5, 91, 27, -163,180, 55,157,106,194,190,104,165,101,216,241,171,116, 57, 30, 18,166,211, 37, 16, 5, 70,131, 54, 18,226, 79,167, 74, 70, 81, - 42, 5, 78, 52,132, 18, 28, 26,183,178,186,229,171,129, 84, 73,169,212,119, 35, 85,129, 0,134,181,188,202, 72, 5,128,210,110, -164,121,139, 34,115,126, 99,150,201,150, 78,208,177,215, 21,236,173,125, 91,218,250, 75,126,181,187, 55,113,190,246, 44, 91, 95, -135,148,129,156,147,147,205,212, 31,144,244, 3, 58,243,202,158,132, 96,121,118,234, 51,223,167,152,213, 84,132,144, 83,212,144, -122,231,250, 71, 93,121,229, 7,168,206, 61, 58,103,231,212,233,216,126,242, 48,223,133,202,123,243, 12,118,207,203,183,111, 61, - 32, 14,126, 17,140, 14,161, 90,245,202, 0,199,235, 2,114, 60,191,110,190, 5, 15,139, 57,201, 32,114,253,216,239,161,239,192, -233,108,123, 39,162,135, 78,189, 62,195,246,249,106,136, 10, 78,112, 73, 80, 61,113,230, 62, 64,254,122,234,166, 18, 83,202,122, -103,184,207, 81,130, 49,223,236,215,174, 80, 6, 9,201,199, 47,111, 46,189, 71,203, 89,192, 63, 27, 96, 53, 1,149, 31, 49,140, -143,183,211, 84, 10,122,103,152,159, 49,204,115,211,229,233,253,186, 57,109,140, 0, 0, 42, 35,161, 61,188,137,207,221,161, 86, - 58,145,216,118,198, 58,231, 30, 93,116, 48, 63,158, 1,112, 96,228,246, 63,119,203, 84, 21,220, 28,101, 35,160,235,242,245, 31, -102,138, 90, 22,121, 72,232, 51,231,247,231,247,104,117, 39, 61, 58, 2, 59, 96,249,104,234, 64,191,160,198, 65, 55,247,255, 0, - 60, 14,160, 50, 60,137, 24,206, 58,103,203, 61, 58,234,146,135,124,156,121, 99,160, 31, 51,219,236,252,116, 73,206, 49,128, 51, -231,231,251,123,106,130,209,216,142,152, 32,159, 63,195, 75, 14,184, 84, 94,215, 29, 79,250, 96, 55, 19,215, 9, 7,190, 79,166, -113,212,157, 10,180,231,174, 51,219, 30,163,230, 61,124,245,112, 94, 8, 35, 56,199,150, 58,254, 63, 97,208,174, 36,246, 79, 78, -132,250,231,203,175,160,237,165,148,155, 11,141,240, 1, 23,176,233,128,148,158,253,122,158,192,247,206,126,126, 93,116, 42,219, - 61,126, 33,142,248, 29,128,238, 64,251,180, 98,130, 72,235,144,115,140, 99, 39,215, 61,190, 90, 29,105, 56, 32,252,142,124,190, -223,195, 58, 58,223,238,254, 95, 39, 6,192,106, 72, 24,199,207,169,245, 30, 90,160,176, 6, 79, 92,227,183,145,249,118,249,104, -165,167, 61,148, 78, 62, 93,254,239, 93, 12,179,220, 30,157, 60,198,115,242,249,127,110,150,193,148,246,192, 42, 80,207, 64,115, -230, 7, 95,188,250,119,213, 21, 12,100, 99, 63,179,231,162,150,129,220, 12,103, 57, 35,191,246,104,101, 2, 7, 81,158,249, 35, -174,127,183, 74, 39,124, 40,187,129,129,212, 62, 68,122,250,125,199, 84, 23,140,143, 92,117,213,117, 19,215,184, 4,231,175, 66, - 79,245,106,130,251,142,158, 93,255, 0,118,149, 29,122, 95, 24, 34,198,227,107,126,239,159,158,216, 20,140, 18, 59,227, 75, 95, - 85,250,199, 75, 75, 13,192, 56, 53,129,222,221,113,224, 31, 34, 70,125, 6,170,115,117, 4, 36,146,112,146, 71,252, 62, 67, 84, - 57, 57,156, 74,190, 46,131,167,126,189, 72,198, 14,138, 73, 72, 0,249,103,174,123,247,243,198,181,201, 39,189,191, 44, 27,238, -190, 43,164,129,129,211, 63,236,245,233,243, 58, 32, 97, 35, 36,140, 31, 65,231,246,249,232,100,242,133, 16, 14, 78, 58,158,157, - 7,144, 58, 37, 4, 36, 28,167,155, 7,168,239,223,182,147, 44,119, 29,113,140, 86, 9, 88, 80, 33, 67,148,142,189, 58,147,229, -223,183,125, 16, 27, 14, 36, 37, 73,206, 14, 71,113,233,215, 84,146,114, 59, 96,121,126,113,162,219, 33, 61, 20,122,227,203, 61, -135,228,105, 51,107,111,211, 4, 38,221, 6,253,190,126, 24,172,132,132,167, 25,192, 31, 46,167,238,209,141,168,114,132,252,186, - 31, 95,234, 58, 17, 41, 24, 32,168,146,115,128, 59,159,179,174,138,108, 18,115,203,216, 12,131,215, 0,103,174,144,194, 71,174, - 42,227,160,207, 92,117,206, 62,223, 33,242,209, 40,194,176, 79, 64,124,186,245, 61,190,239,236,213, 16, 1, 81, 29, 64,242,237, -249,245,209, 45,130, 6, 1,237,228,113,147,251, 59,104, 99, 7,241,193, 13,224,100, 14,158,159,183, 68, 33,125,121,112,122,103, - 36,117, 25,207,111,219,170, 8,237,156, 12,250,116,207,217,159, 61,101, 86,165,169,113,222,213,218, 85,175,104,208,234,151, 29, -199, 92,154,205, 58,143, 67,162, 64,145, 83,170,213,103, 62,174, 86,162,193,129, 17,181, 57, 37,226, 79, 92, 12, 36, 30,101, 16, -144, 78,144,150, 68,141, 93,157,130, 34,110, 73, 54, 0, 1,212,158,192, 96, 14,194,219,159, 78,228,237, 97,234, 73,216,119, 56, -239, 95,177,184, 52,198,205,241, 34,250, 82,145, 37,219,203,111,154,116,243, 97, 74,140,138, 52,229,161, 36,121, 36, 56,165, 99, - 62,127,102,186,125, 58,178,168,165,224,240,108,180,227,106, 45,243,168,133, 3,219,224, 41,253, 99,156, 28,124,181,130,123, 43, - 61,153,123,231,176,246, 46,230, 76,226, 66, 69, 19,109, 99,238,172,123,102, 85,189,105, 61, 82,102,161,115, 83, 77, 53, 47, 41, -114,110, 56,241, 22, 91,166,201, 83, 79, 37, 41, 96, 41, 78, 35, 7,156,131,211, 91,183,187, 60, 21, 87,216,164,202,171,216, 55, - 44, 43,172,211, 80,185, 34,157, 13,254, 73,133,108,167,153, 73,110, 58,212,124, 76,167,200,119,206,185,175,140,211,219,115,250, -250,186,121,150,106, 87, 41,102, 86, 4,217, 99, 69, 62, 95,180, 64, 96, 69,237, 98, 6,161,177, 7, 30,160,125, 30, 51, 92,167, - 42,240,231,133, 50, 92,240,205,148,102, 10, 42, 3,172,240, 74,138,188,202,201,222, 50,206,202, 2,106, 70, 70,243, 90,193,183, -223, 26, 33, 89,187, 38, 56,211,173, 73, 82, 68,134, 29,100, 33,180, 43,195,241,146,165,129, 30,115, 42, 79, 82,234, 84, 82, 20, - 61, 53,220,158, 22,104,113,246,115, 98,169, 87, 66,163,180,230,226,223, 48,159,157,245,162,217,109,215,233, 84,130, 15,134,212, - 53,167, 42, 99,197, 78, 84,181,167,226,199, 98, 53, 30, 10,163,245, 54,234,111,196,144,202,209, 82,166, 75, 80,109,137, 72, 83, - 78, 49, 38, 59,153,147, 79,146,210,250,165,126, 35,100, 96,227, 24,215,127,118,138,242,164,110, 62,192,109,157,106,149, 47, 30, -229, 76, 54,197, 89, 17,150, 68,186,101, 86, 23, 51,106, 97,104, 7, 45,130, 23,217, 88,202,117, 28,118, 20, 81, 23,136,105,153, -198,204, 58,139,149,189,143,111, 45,236, 65,254, 3, 29, 5,199,185,104,158, 14, 29,203,164, 80,217,101, 77, 86,170,133, 93,209, -180,199,170, 20, 96, 14,241,187, 6, 37,127, 93,148, 45,136,181,242,106,229,223, 42,176, 31,122, 91,235, 11,114, 43,173, 63, 43, -152,169,199,159,143,135,153, 45,243, 30,101,243,182,162,159,187,215, 88,194,171,109, 42, 52, 22,155,105,229, 73,168, 62, 22,203, -206, 5, 45,198,219, 49,203, 37, 62, 31, 54,124, 70,223, 9,248,135, 92, 47,174,172,242, 97, 74,133, 54,150,235,136, 92,152,237, - 58,252, 89, 13, 45, 92,139, 46, 50,219,136, 74, 20, 9,248, 28, 41, 32,143, 62,190,122,188, 83, 18,164, 54,242,101, 71, 65,114, - 44, 22,132, 53, 40,114,187, 30, 75,239, 23, 82, 65, 72,234,224, 65, 70,125,121,117, 30, 87, 45,172,129,168,158,155,237,126,135, -115,211,189,187,236, 62, 56,127,142,130,130,138,154, 49, 79, 24,120,134,234,170,193,123,180, 96, 91,169, 10, 66, 18, 15,151, 77, -128, 4,226,231, 71,140,106,110,203,144, 95, 44, 50,131, 42, 92,249, 46, 56,161,202,196, 32,136,201,141, 24, 96, 36,190,183,201, -194, 51,149, 21, 28,117,214,187,111,102,251,181, 33,243,106, 81,228, 61, 14, 37, 33, 97,130,251, 50, 21, 30, 63, 51,105,194,152, - 98,106,148, 82, 95, 81,200, 60,195,245,138,142, 20, 14, 19,125,222, 75,250, 78,218,216,238,219,180,169,142, 42,187, 85,231,169, -204, 91,107,109, 14,183, 50,106, 86,182, 24,105,167,112,133,173,168,202, 43, 80,230, 79,199, 45, 56, 33, 67, 58,228,228,187,229, -250,132,217, 47, 75, 67,178, 96, 58,242, 83, 61,164, 56,226,208,226,208,181,175,198,125, 46,167,157, 35,226,117, 68, 43,152, 40, - 32, 32, 40,140,101,246, 58, 73, 18,147,146,135, 76,211,128,242,145,107,170,177,186,198, 9,237,250,205,184,185,216,218,219,233, -112,238, 72, 56,183, 63,169,204,229, 28,252,143,135,165, 49, 82, 40, 35,235,170, 18,203, 36,204,173, 96,202,132, 24, 98, 13,183, -146, 66,118, 56,218,122,181,245, 81,114,145, 37,110, 60,103,198, 97,207,125,165, 84, 31, 79,131, 90,163,190,219, 97, 10,108, 48, - 26, 9,169, 66, 90, 80,227, 47,128, 80,181, 33,204,169, 42, 79, 34,145,144, 27,238, 36,202, 77, 46, 61, 71,146,158, 91, 77, 34, - 80,129, 80,121,196,192,149, 37,107, 67,234,250,134,230,105, 96,211,223,104,169, 92,205,169, 77, 58,128, 83,145,140, 41, 90,141, - 75,174,173, 77,251,204, 9, 44,170,156,220,176,219,244,224,164,200,165, 79,117,183, 20,184,138, 75,160,173,218,100,118, 89, 33, - 75, 40,230, 73, 95, 94, 82, 7, 38,179,218,117,105, 35,154,151, 61,164,211, 34, 50,180, 74,121,186,147,237,205,163, 21, 60,162, - 29,110, 35,204,164, 37,216,238, 48,180,134,146,248, 5,180,189,243,232,211, 62, 92,169,112,162,228, 27,221,109,123,121,123, 16, -109,110,225, 46, 44,215,186, 62,199,161,242,220,190,156, 36,113,114, 47,203,109,107,162,234,192,145,231, 26, 47,177,110,190, 75, - 27, 13, 65,145,137, 24,220,138, 82,100, 86,167, 67, 85, 85, 5,217, 21, 54, 83, 26,153, 91,143, 41, 84,218,173, 77,175, 19,157, - 16,100, 78,167,184,142,105,169, 96,169, 46,243, 41,104,121,178, 22,223, 34,202,155, 23,250,140,137, 20,138,148,138,125, 82, 20, -234,253, 56, 69,122, 35,244,247, 86,135, 43,244,199,152,112, 33,197, 60,228, 96,159,173,226,132, 50, 84,121,113, 53,165,176,135, - 82,167, 71,194, 53,242, 20, 11,121, 84,166, 35,198,155, 38, 4, 37,169, 19, 41,142,209, 42, 19,225,165,233, 62, 34, 25,142,226, - 80, 30,113, 17,157, 66,149,252,196,164, 18,216, 82, 84,115,167, 38,148,205,126,152,227, 49, 97,220, 38,171, 81, 86, 91, 68, 26, -187, 13,248, 14, 69, 97, 62, 35,143,138,156,112, 22,101, 41, 15, 18, 22,226, 10,194,136,230,230,233,134,127, 42, 6, 37,206,199, -117,101, 43,181,186,143,180, 75, 2,110, 73, 96, 5,128,176, 42, 44,157, 77, 28, 1,181, 71, 86,166, 56,195,160,133,227,150, 34, - 10, 48, 60,200,165, 70,147,146,168,163,204, 71, 45, 85,148, 2,193, 25,163,195,167,111,214, 86,203,172,196,137, 45,186,155,174, -161, 10,167, 73,203, 62,227, 94,136,211,232, 33,202,160, 82,127,192,238, 54, 24, 88, 10,120, 37, 1,208,149, 43,151,151,153,182, -170,166, 34,105,117, 25,181, 40,161, 79,194,159, 53, 78,221,148, 2,130,244,202, 62, 11,173,203,168,196,140,210,177,239,188,139, - 79,188, 52,148,143, 25, 25,113,159,210,140,171, 8,167, 26, 85, 94, 65,131, 35,235, 11,102,226,130, 87, 49,132, 48,166, 27,155, - 34,167, 24, 20, 49, 81,133, 37, 81,151, 26,170, 90,112, 31, 21,124,188,252,170, 13,201, 72, 73,201,204,105,149, 74,157, 57,200, -147,110, 38,154,139, 18, 67,205,195,153,115, 70,104, 51, 79,155, 83, 70, 23, 21, 85, 85, 0,161, 70,146,242,249, 2, 78, 76,126, -101,128,219,173,128,148,235, 34, 80,196, 0,231, 83, 92, 1,220, 90,204, 10,145,112, 0,185, 42, 1, 2,236,108, 45, 99,136,197, -109, 57,134, 90,147, 78, 60,243,173,165,136,149, 15, 48,189,215,148, 86,241,202,190, 93, 81,152,134,165,148, 13, 11,202,242, 35, -169,110,248,110,177, 16, 67, 42,158,104,128,170, 20,215, 22,194,141,110,142,176,131, 25,131,225, 54, 11,133, 84,196,180, 99,164, - 18, 82,252, 36, 58, 2, 73, 90,181,243,137,137,169, 94,219, 91, 8,140,165,159, 30,241,143, 84, 66,139,156,202,240, 96,192, 62, - 18,156, 82,206,124, 78, 89,140,129,203,241, 21, 30, 76, 19,163,109,106, 99,148,203,129,215,161, 22,149, 70,170, 36, 45,108,171, - 31,224, 53, 5,243, 58,217,101,215, 79,193, 25, 79,185, 33, 32, 39, 1,165,190, 66, 50,135, 15, 45,187,123,227, 46,167, 87,178, - 45,198, 26,115,194,143, 66,171,214,144, 26, 91,156,200,171, 26,148,118, 84,145, 31,151, 10, 8,167,198, 11, 4, 31,135,197,207, -235, 37, 39, 74,201, 56, 20,179, 48,220, 2,160, 89,137, 27, 48,218,251, 92,218,224, 27,108,182,181,237,189, 90,213,112,199,197, -185, 37, 66, 63, 50, 26, 82,245, 33,186, 21, 2, 41, 29,149,214,224, 41, 89,127, 85, 64, 0,155,129,164,168,195,121,106,210,157, - 49, 16,180, 67,123,221,105, 23,132,151, 98,143, 8,133,181, 9,233, 2,160,114,132,149, 41,152,202, 77, 80, 0,122, 20,224,133, -140, 19,174,145,216, 85, 22,174,139, 58,117, 20,167,255, 0,116, 45,215,218,183, 92,253, 48,116, 59, 66,168, 71,135, 84,162,201, - 91,137, 33, 46,115, 83,165, 76,101, 96,101, 41, 92, 44,103,200,106,117,145,110,169,112,231, 15, 1,196,123,195, 84,153, 12,178, - 20,148, 41, 94, 28, 38,226,200,119,157,100,120, 95,165,138, 1,112,228,146,114,114,161,173,186,219, 8, 70,145, 86,150,137, 9, - 45, 70,158,138, 76, 55,148,216, 65,109, 45,150, 86,152,239,128, 57, 65, 12, 75,229,234,122,225,213,148,244,209,114,119,104,171, - 4,128,125, 92,254, 87,191, 96,110,192,158,223,104, 2,109,189,142,214,189,197,123,226,102,115, 14,101,151,130,175,170,167, 41, -126,116, 54, 59,220, 24,181, 41, 23,243, 93, 94, 65, 97,177,125, 39,160, 56,182, 92, 20, 69, 77,185,225,210,208,218, 12,121,177, -214,245,101,132,175,147, 20,200,207,169, 77, 67, 12,161, 64,187,239, 14, 55, 24, 58, 82,112,164,176,232,229, 32,231, 94, 29, 77, - 69,138,133, 70, 29, 29,163, 30,174,236, 24, 12, 74,171,176,182, 29, 93, 18,157, 80, 46,135, 10, 99,172, 22,209, 86,126, 34, 28, -247, 86, 74,249, 90, 42, 50,212,149, 37,164,133, 61,149, 74, 50, 96,174,108,231,227,148, 73,104, 70, 98, 34, 90,232,251,142, 52, -174, 65, 30, 63, 46, 28,230,126, 90,201,119, 25, 60,138,113, 64,225,189, 82,183,173,152,148,155,102,178,203,203, 68,215,166, 72, -114,183, 95,156,227,173,149, 84,171, 51, 30, 74, 27, 67, 12,173, 36, 52,203, 81,219,102, 60, 68,130,144,203,109,165, 36,133,120, -138,212,193, 31, 77,212,144, 72, 34,198,251, 27,245, 44, 15,154,214, 6,230,224,239,182,149, 3, 21, 18,113, 76, 43, 65, 3, 50, -137,214, 49, 12, 40,135,117,121, 29,209,158, 71,223, 75, 42, 46,136,204,108, 8,145,132, 74,193,144, 72, 75, 74,213, 54, 21, 45, - 76, 91,246,218, 94,139, 17,193, 28, 86, 29, 14, 46,115,208,212,249, 67, 77, 64,167, 72,144, 20,185,149,135,226,180,158,101,145, -202,195, 40, 83,141,144,227,200, 2,245, 21,216, 52, 92,248, 96, 70,161, 83,252,103, 98,197,145, 15,156,115, 78,109, 49, 66,157, -109, 1,110,205,152,167, 16,175,119, 65,203,206,130,172,229, 69, 42, 23, 85,184,213, 38,116,122, 77, 49, 30,243,112, 48,191,122, -156,175, 0,120, 52,218,131,205, 97, 18,106, 83,146,149, 4,194, 76, 0,146, 91, 88,241,164,101, 41,109,188,184, 10,126, 34,216, - 84, 0,137,213,234,155,149, 73,236,160, 76, 76,164,176,212,104,116,198,150,183, 7,131, 18, 42, 93,229,167,198,253, 69, 23,214, - 76,149,151, 57, 71,195,200,157,109, 69, 33, 82,243, 60,133,180,234,176,248,250,244,211,107, 91,226, 72,211,167,112,188,181,209, - 76,160,213,204,197,106, 0, 96, 24,179, 79, 82,204, 72, 51,121,144,128, 10,249, 98,149,218,225, 28,149, 89, 27,152,205, 94,144, -220,249, 80,209, 79,171, 70, 91, 20,181,184,135, 92,141, 50, 72, 14, 84, 76,118, 19, 36, 34,177, 25,151, 21,138,119,187,114, 19, - 21, 68, 12,117,150,149,132,150,213,150, 54, 98,220,136, 16,188,119,163, 67,101, 5,113,196,105, 72,165,185, 82,119,197, 5,126, -248,228,114,219,144,233,141, 70, 67,104,106, 56, 82,124, 82, 79,136,218, 88, 9,105, 88,156,247,222,169, 82,227,191, 45,232,212, -218, 11, 78, 71, 98, 59,143,161,113, 39, 84, 75, 46,153, 13, 76,172, 45,229,243, 37,135, 29,104,251,180, 52,101,110, 6,210,236, -148,169, 74, 12,138,140, 74,153, 50, 51,206, 33,177, 76,164,162, 59, 73,171, 73, 72,104, 78,168,197,125,231,124, 63, 6, 48,109, -102,142,200, 60,234, 28,229, 82, 93, 7,244,104,105, 39, 91,241,105,141, 99, 37,254,169,195, 11, 90,214,220,144, 53, 30,151,233, -216, 2, 62,226,207, 81, 79, 37, 64, 53, 1,150,150,100,144,129,164,144,145, 57, 33,117, 0, 73,102,157,197,144,162,146,201,229, -185, 91, 7,133,199,163,200,101, 79,198,131, 70,106, 76,183, 83, 33, 17, 40,212,166, 60, 24,241,189,234, 27,101,247,106, 85,121, - 13, 51,138, 77, 9,190, 85, 34, 58,146,217, 82,185,213,225,182,227,202,108, 33,244,163, 51, 30,132, 13,122,179, 61, 46,206,167, -178,218,106, 21, 83, 17,198,105,113, 16,255, 0,130,203, 84,152, 48,121,220,112, 58, 60, 70,144,219, 72, 14,202,154,226, 91, 75, -137,117,229,164, 37,133,166, 84,233, 54,205, 18,152, 42, 78, 72, 74,100, 38,109, 70,157, 75,167,176,101,215,110,185, 45,168,183, - 26, 21, 45,132, 58, 22,233, 81, 25, 47, 73, 45, 70,101, 9, 42,121,228, 37, 28,165,217,183, 32,206,171, 85,105,149,250,165, 82, -149, 14, 75, 94, 12,218, 69,174,167, 26, 93, 42,136,182,199, 51,171,157, 33,213,135,234, 53, 63, 17,100,187, 57, 41,104, 33, 40, - 8,142,218, 24, 74,121,221,169, 86, 22, 72,193,212,205, 96,202, 46, 67, 48,184, 22, 31,101,130,133,184, 4, 88, 49, 35, 72,181, -216, 86, 28, 81, 1,116,150, 73, 25,169,242,225,205, 66,229, 73,146,164,163,105,104,209,130,181,131, 0, 76,135, 75, 68,143,118, -149,228,145, 98,129, 95,138, 36,233,202,152,138,141, 93,169,141, 69, 80, 30,227, 5,244, 43,222, 82,165, 36,243, 74,171,176,208, - 41,106,160,226,222, 82, 83, 28,169, 98, 40, 10, 73, 90,220,201, 68, 52,254,150,111, 2,144,225,187,179,158,209,187, 10,132,211, - 79,213,165, 82,118, 15,137, 25, 20,246,210,148, 75, 91,140,190,246,200, 95,117, 36, 32,115, 57, 41, 10,102,175,109,202,146,122, - 41, 18,232,108, 40,225,134,134,166, 17, 71,172, 75,173,183,254, 28,202,224,136, 19,125,223,220,189,237,247, 37, 21,179, 37,214, - 81, 80,121,191, 1, 45, 16,166,130, 31,105, 33,106, 75, 76,149, 56,163,206,177,200,205,113,141,195,133, 51,141, 78, 12,248,147, -225,150,176,148, 59, 23,119,182,166,230,182,237, 57, 15, 97,150,105,151,140, 70, 87, 85,176,107,200, 50, 27,253, 3,177,111, 58, - 93,191, 49,181, 28, 41, 2, 57, 60,193, 74,200,158,100,149,102, 22,210,191, 88,166,198,203,123,107, 2,250, 84, 17,179, 17,170, - 37, 36, 88, 6, 45,176, 1,135, 60,241, 94, 80,210,197, 55, 50, 52,167,146, 27, 38,149,177,141,119,250,189, 44, 46, 13,254,219, - 16,222,117, 4,220,220,223,242, 16, 41, 10, 0,121,103, 35, 29, 63, 35,174,144, 0,146,129,231,232,122,252,251,246,242,213,103, -105,213, 58, 52,201,244, 90,252, 69,192,174,208,170, 53, 26, 21,114, 3,128,135, 96, 86,232,211, 30,166, 85,233,238,115, 96,133, -177, 82,139, 41,165,103,205,147,175, 33, 3, 57, 79,194, 14, 78,124,199,203,236,212,253, 72, 96, 25, 78,160, 70,198,251, 27,216, -220, 31, 76, 83,251,247, 22, 56,241,142, 65,215,160,207, 76,143, 35,229,243,210, 78, 79,144, 72, 39,250,186,145,142,218,250, 74, -136, 25,198,115,208,129,220,124,245,247, 36,146,124,191,217,244,236,126,205,103,127,191, 3, 30, 72,200,230,229,206, 58,121, 15, -199,215,251,117,236, 5, 31,245, 72,242, 7,190, 62,223, 76,233,114,133,144,114,164,245,198, 7, 65,219,215,238,215,190, 92,127, - 56,224,103, 31, 47,191,211, 67,221,233,129,138, 43, 71,124,156, 15,196, 14,221,186,244,208,171, 3, 3,191,166, 64,201,249,119, -249,234,232,212, 41,147, 22,132, 71,105, 74, 46,186,134, 91, 32, 16, 29,125,194, 18,211, 12,249,188,250,213,209, 40, 72, 43, 89, - 56, 72, 39,166,186, 71,195,191,178, 43,142,110, 36, 99,196,171,219, 27, 61, 83,178,237, 25, 97,151, 26,188,247, 98, 90, 54,206, -131, 38, 59,229, 63,225, 52,182,171,241,205, 66,178,148, 52,175, 16,166, 60, 5,115, 36, 97, 43,202,147,157,121,171, 41,169,236, - 37,148, 43, 55, 69,234,199,224,162,228,159,112,198,205, 37, 29, 93,124,188,138, 26, 89, 43, 38, 29, 86, 36,103, 32,122,182,144, -116,143,123, 88,123,241,204, 5,140,156, 36,231, 29,252,135,224,124,251,232,117, 0, 14, 70, 1, 7, 7,183,159,203,207,166,117, -177,124, 80,240,223,126,112,157,189,183,214,195,110,107, 49,211,119,216, 53, 54, 96,207,155, 77, 84,151,104,213,200,115,224,199, -169,209,174, 75,118, 76,184,204,185, 50,223,157, 79,148,219,177,157,113,166,212, 74, 28, 66,144, 20,218,181,174,203,234, 48, 7, -159, 79, 94,255, 0,111, 83,141,108, 83,203, 28,200,146,198,218,163,144, 2, 58,142,190,160,216,223,220, 69,240,155,199, 36, 18, -203, 12,200, 98,158, 22,100,116, 59, 50,178,157, 44,164, 14,132, 16, 65,247,140, 12,160, 58, 18,122, 12,253,253, 63,179, 67,171, -168,200, 61, 58,140,249,227,207,167,231,182,138, 63,173,208, 17,223,167,203, 25,201,252, 53, 69, 64, 1,142,253,115,246, 15, 67, -173,144,108, 65,244,198, 70,227,125,199,254, 48, 26,129,245, 28,189,186,140,125,224,250,245,208,171,192,201, 25, 7,255, 0,104, -122,103, 69,184, 70, 72, 57, 0, 30,195, 29,124,186,126, 31,179, 66, 47, 62,163, 30,158,121,249,116,210,202, 73, 23, 56, 0,108, - 61, 54,192,202,193,193,193, 4,247,206,116, 58,199,159,175, 67,233,162, 87,235,229,140,122, 96,250,252,244, 58,129,201,200,200, -251,113,131,219, 56,209,199,198,216, 54, 6, 88, 0,100, 39,175,203,167,231,251, 52, 43,131, 39, 36, 2, 64,236, 58,254, 63, 61, - 22,231, 76,100,244,201,251, 60,134,132, 80, 30,188,221,127,104,193,245,251, 52,170,155,223,107, 91, 25, 22,223, 2, 44, 12, 18, - 70, 49,219,212,117,237,161, 87,243,234, 15,111, 44, 31, 92,249,249,232,197,140,103,249,222,127,105,251, 6,133,115, 24,236,123, -246,244,239,223,229,165,147, 10,139, 27,123,190,126,126,252, 12,188,246,199, 76,103, 62,152,254,142,154, 13,206,249,201, 78, 51, -156,140,231,211, 31, 46,250, 49,194, 2,122,244,243,207,151, 79, 93, 90,212,167,148,162, 20, 50,159, 34,158,248, 35,184,244,210, -152, 2,247, 55,232, 48, 59,171, 82, 85,220,156,231,177,199, 79,179, 75, 84,137, 89, 82,129, 64,192, 61, 9,238,125,123,157, 45, - 11,159, 92,102,195,211, 7, 1,145,228, 49,230,115,215,175,153,251,245, 85, 41,199, 65,212,158,255, 0,159, 77, 82, 78,114, 7, -145,207, 79, 35,223,203,237, 26, 37, 0,231, 61, 49,231,219,242, 53,130, 1,198,113, 85,164, 37, 39, 24, 29, 70, 51,230,123,121, -232,129,156,245, 31, 8, 29,193,235,233,231,223,190,169,163, 29,176, 58,117, 7, 26,244,121,242, 2, 82, 20, 60,250,224,142,189, -251,246,210, 76, 0,248,223, 3, 5, 39, 29, 51,146, 59,252,240,123,103,174,138, 64,206, 8, 35, 31,183,240,208,109, 54, 70, 78, - 78, 73,235,147,144, 6, 78, 6, 51,215, 70,163, 57,233,142,157,199,203,229,162, 27,218,255, 0,203,124, 17,187,155,224,134,240, -161,156,231,174, 64,235,211, 29, 63,164,104,132,168,143, 60, 14,199, 24,243,245,249,127, 86,168,160, 96,103,207,203,243,246,141, - 16,132,224,228,245, 7,174, 63,160,231,215, 73, 16, 5,253,223, 39, 9, 28, 86, 71,127, 62,223,143,231, 58, 44, 1,220,122, 99, -160,192,252, 52, 58, 82, 7,219,143,207,238,213, 86,242,162, 60,134,112, 57,142, 0,243, 42, 62,128, 12,232,167, 5, 97,182,231, -108,101, 54,149,175, 93,188,238, 42, 37,171,108, 82,103,215,174, 43,142,169, 10,139, 68,162,210,216, 92,170,133, 82,169, 80,121, - 49,225, 64,134,195, 96,151, 31,113,229,164,118,194, 70, 84, 72, 0,157, 78, 55,217,195,236,235,180, 56, 5,219,136,183,189,229, - 6,143,114,241,101,120,210,144,245,197,112,186,195, 83, 99,109,101, 38,115, 41,113, 22, 77,152,167, 82, 66, 42, 9, 66,147,245, -132,212, 0,227,174,130,132,144,210, 64, 58, 65,236, 48,224, 78,145,183,150, 91, 28,115,238,229, 25, 47, 93, 23, 10,101,211,120, -127,163, 84,163,165, 73,163,211, 57, 87, 30,165,184, 46, 48,226, 73, 76,201, 4, 45,184,107, 35, 40,101, 37,105, 33, 78,103, 93, -206,171,207,168, 77,158,242,214,234,165,120,206, 45,240,239, 57, 83,188,203, 36,252, 62,157, 9,239,170, 51,196, 46, 48,105, 37, -147, 42,160,151, 76, 16,146, 37, 96,109,169,129, 27, 92,118, 83,208,119, 32,181,143,145,135,112,125, 25,188, 13,143, 54, 16,113, -223, 19, 82,137, 17,172,244, 16, 72, 60,170,157,125,165,213,191, 93,246, 49,126,194, 16,247,212,254, 92,102,175, 95,155, 82, 46, -162,100,151,208,236,151, 84, 86,135,157, 83,143, 45, 96,146, 94,142,181, 28,149, 31,231, 39, 61,245, 66,141,115,205,137, 57,175, - 1,247, 75, 76, 35,195, 76,148, 41, 72,125, 46, 37, 67,149, 50, 80, 63, 89,178,122,100,246, 29,245,245,218, 59,147,164, 45, 78, - 62,215, 50,202,148,134,101,254,133,244, 62,145,140,180,188,124, 11, 56,232, 71, 67,171, 83,148,233, 49,170, 13,190,247,248, 44, -245,182, 90,104, 56,144,150, 39, 33, 63, 10,154,125, 67,225,241, 20,158,202,245,193,243,213, 56,106, 88,146,193,203,105,235,239, - 59, 19,191,201,199,127,158, 23,202,218,157,233,146, 24,236, 81,136, 80, 46, 1, 43,107,143, 46,174,130,197,183, 3,169,212, 47, -102, 23,138, 45,142,166,222, 16, 42, 27,183,108,211, 81, 10,232,163, 70,247,155,186,155, 13,174, 83, 92,132, 0, 8,170,165,134, -192, 6,115, 39, 5,106, 72,203,136, 86, 73,233,166,207,131,205,208,115,108,174, 89,118,133,206,234,163,216, 59,146,166, 20,169, - 42, 82,136,161, 93, 77,252, 49, 42, 33, 4,225,182,215,204,148,185,216, 20,171, 61,198,186, 27,110,114,132,166, 53, 69,148, 59, - 30, 90, 23, 25,101,236,171,154, 43,201,240,223,133, 36, 17,241, 35,145, 74,229, 39,161,215, 63,238,253,167,145,106,238,109,193, -110,177, 27,154,158,103,166,165, 71,109,208, 75, 65,135,207,188, 66,117,149,227,252,159, 41,228,233,219, 3, 75,181, 66,188,109, - 27,157, 72,221, 61,223,199, 99,123,219,220, 65,219,108, 51,192, 88,210, 85,228, 53,174, 76,116,104, 30,157,201,185,229, 35, 0, - 2, 19,125,224,147, 75, 37,239,101, 33, 13,213, 69,250,103,114, 80, 10,102,173, 46, 58,164,199,113,180,212,163,184,159,141, 18, - 38,180,144, 27,150,219,136,255, 0, 40,194,218,193,244,234, 52, 13, 53,152, 76, 85,228, 75,126, 75,175, 83,218,112,212,170, 11, -111, 28,170,135, 77,132,169, 78,242,115, 15,209,175, 45,242,143,153,236,117,227, 97,231, 85,171,148, 38,109,155,155,154, 91, 20, -248,232,126,139, 84, 87,199, 38, 34, 85,134,223,163, 74, 82,186,185, 28, 40,126,141, 95,205, 7, 30, 67, 69,110,125, 33,219, 19, -109,119, 58,172, 90, 66, 93,116, 66,166,211,214,225, 63,160,250,214, 82, 3,169, 64,233,241,150, 27,112, 39,168, 3,155, 62, 88, - 58,244,144,243,106,233,148, 11,197, 35,128,123,129,109,205,246,238, 6,199,184,235,108, 71, 42,184,155,216,242,188,198,154,162, - 95,237,180,208,232,140, 11, 90, 66,236,136,172,189,245, 3,160,145,212, 16,122,249, 73,227,159, 17,187,137, 50,231,190,101, 63, - 18,112,228,140,252,162,176, 30, 62, 10,228, 73, 82,164, 22, 95, 72, 63, 2, 91, 10, 66, 22,112, 8, 82, 66,185,126, 28, 29, 79, -145, 81, 80,168, 42, 68,213, 63, 12, 37,188, 63, 45,130,209,128,132,156,150, 26, 75,203, 73, 74,254, 39, 10,138, 92, 67,124,164, -229, 42, 25, 25,186,221,245, 35, 87,185, 43, 18,155, 90,227, 77,126,164,251,143, 7,129,118, 51,188,178, 11,120,144,148,242,135, - 91,232, 71, 50, 10, 92, 36, 36, 39,211, 88,139,213,131, 77,117,196,212, 27, 16,219, 83,220,225,196,169, 47,211,101,161, 71,194, - 11, 92,133, 4,174, 9, 66,203,105,113,183,145,240,248,193,124,202,108,130, 38, 34, 59,179, 29,137,125,253,230,246, 63,127,165, -250, 13,186, 11,218,248,225,108,186, 60,159, 36,202,104, 33, 80,239, 79, 18, 6,232, 36, 44,108,206, 88,216,171,134,102, 58,137, -189,193,232,183,182, 51,138,107,197,167, 35,145, 32,194, 75,137, 45,162,170,204,129, 26, 59,172, 0, 57, 16,250, 88, 42, 67,173, -168, 44,132, 33, 97,105, 81, 89,194,193,192, 15, 21,183, 34, 93,189, 17,133,173,196,213, 88,150,133,188,239, 51, 44,199,149, 29, - 45,142, 86,210, 82,135, 2, 38, 68,112,144,144,148,168, 41, 39, 32,133, 0, 2, 89,200, 80,154,117,109,186,212,100,199,139, 80, -101, 13, 33,216, 78,199,114, 51,238, 37, 74, 91, 78,189, 27,148,178,231, 80,164,172,130, 9, 41,201,238, 14,179,250, 11, 83,227, -182,194,154,145, 2,161, 25,212,187, 44,196, 66,213, 18,124,111, 5,107,100,166, 20,148,169,198,211, 12,115,175,153, 42, 74, 80, - 70, 78, 78, 51,166,186,192,172,178, 6,109,136,220,117,189,189,227,117,177, 30,160, 27,119,233,139, 14,158,162, 39,142, 0,101, - 66, 93,128, 10,247, 70,216,130,108,214,176, 96,108, 65,243, 95,175,187, 27, 7,111,210, 27,168,182,211,116,199,151, 78, 75,232, -110, 83,209,169,177, 26,125, 10,125, 72, 91,143,187, 34, 34,142, 34,172, 0,129,128,132, 45, 73, 72, 9, 43, 56, 80,206,163,202, -184,216,125,223, 26,158,154,225, 56, 80,114,142,180, 69,150,162,178,150,227, 46, 61, 62,106,200, 76,129,146, 74, 91,146, 28, 87, - 54, 67,121, 73,211, 37, 69,159, 9, 83, 19, 42,175, 34,171, 13,106, 74,227,154,156, 84,200, 79,185,120,108,229,135, 25,169, 81, -213,250, 96,176,134,208,128, 65, 64,248,130,145,141, 58,116, 74,219,236,148,159,175, 97, 86, 33,180,182, 20, 87, 17,108,199,169, -180,216, 91,106, 47, 79,130,128, 61,245,230,208,113,204,207, 34,215,156,148,247,212, 94,170, 25,163,109,148, 76,140, 5,245, 41, -218,254,142, 8,213,107,116, 44, 47, 97,229, 55,198,205, 75, 85, 29, 71,255, 0, 73, 68, 85, 96,178,164,159,111, 98,202,179, 71, -229, 98, 69,134,130,202, 77,238, 0, 83, 96,239, 82,107, 84,106,164,152,205,214, 16,245, 17, 75,247,101, 22, 43, 1,232, 83,105, -203,136,165, 50,229, 98, 34,151,202, 17,226, 61,202,145,202,178, 48,162,146,142,250,216,251,105,128,186, 36,170,100,211, 22, 67, - 77,176,209,122, 60,214,153,145, 30,167, 10, 65,240,214,164,164,158, 79, 13, 73, 45,115, 37,224,181, 33,120, 81,230, 79, 42,131, - 59, 69, 16,106,201,139, 50, 64,129, 87,142,243,161,150,146, 80,211,168, 90, 71,134,148, 54,236, 25, 3,150, 43,129, 5,101,229, - 41, 92,199,162, 51,130,112,245,208,236,136, 14, 52, 88,165, 63, 50,139, 34, 51,197,246, 98, 51,239, 14, 83,216, 91,139,113,121, - 76, 73,110,172, 58,223, 48, 72, 13,160,134,135,112,144, 6,154,194, 70, 23,117,229,143,129,216,236, 71, 80, 47, 96,118,184, 4, -222,231,114, 6, 41,222, 44,205,105, 4, 73, 28,205, 45, 7, 45,193,177,250,212,141,149,187, 31, 44,137,107,144,124,172,109,102, -184,117, 1,243, 59, 82,158,154, 90, 88,167,200,142,181,210,164,169,181, 70, 81, 89,144,237, 61,164, 97, 8,142, 95, 89, 89,114, -156,227,128, 6,143, 58,148,202,185,146,172,161, 73, 41, 58,230,163,187, 82,190,163,190,164, 15,240, 15,170, 97, 12,245, 79, 47, -184,169, 46, 41,174,193, 14,169,111,140,231,161, 40,198,122,227, 89, 5, 18, 3,176,154,143, 6,166,202, 9, 1, 73,143, 61,174, -116,199,117, 99, 11,126, 47,134, 18, 84,193,229, 10, 37, 10, 37,180,225, 64, 40, 28, 13,100,168,166,120,245,217, 15,133,120,168, -146,220, 87,219, 46, 28,171, 6, 52,112,158,128,225, 60,175, 70, 87,197,205,140, 40, 16,112, 64,214, 42,193, 90,101, 10,126,211, -169,184,233,123, 31,188,110, 72,220, 3,125,207, 67,138, 55, 49,206,155,219,234, 42,132,129,216,197, 32, 46, 15,145,195, 50, 2, -235,191, 86, 80, 85,250, 18, 70,227, 86,166, 57,149,157,109,178,148,183,224, 71, 1,183, 35,200,142,217, 40, 25, 72,109,212,201, - 82,185, 20,122,144,165,158,100,158,128,171, 25,198, 50,253,209, 40,136, 75,137, 56, 90, 16,244,102,139,216, 60,229, 92,174, 20, -160, 14,224, 59,241,225, 62,105,200,244,214, 51,107,195,108,165,151, 16,146, 22, 20,133, 20, 2, 74, 64,121, 60,138, 65, 87, 76, - 96,117,207,114, 8,243, 3, 79, 5, 53,182,146, 64, 57,193,111,145, 35,178, 84, 80,226, 28,232,165,126,162,177,219, 31,234, 19, -220,105,223, 44,132,121, 88,223, 77,198,253,250,119, 62,253,247,252,113, 75,113, 30,119, 60,175, 32, 4,249,186,239,191, 91,252, - 54,176,222,214,184,191,174, 50, 89, 20,195, 81,143, 72,144,180,173, 79,134, 84,226,176, 3,206, 10,131, 10, 49,156,120,149, 12, -182, 3, 33,100, 31, 37,188, 73,238, 14,172, 46, 81, 36,215,106, 78,136, 82, 13, 46,159, 29,244,173,218,140, 98, 3,147, 86,130, -148, 42,159, 79,101,212,148,184, 90, 82, 9,117,242, 64, 39,157,182, 86, 64, 39, 89,163,142, 4,210, 26,113,106,112, 18,169,104, -109, 13,148, 32,151, 20,219, 9, 95, 85,156,163, 43, 88, 5, 64, 16, 3,157, 50, 73,215,199, 43, 45, 65, 83,113, 91, 14,161,136, -145, 25, 84,196,198, 1,231, 22, 91, 74, 20,150,219,107, 33, 42,116,156, 18,165, 16, 57, 84, 58,142,131, 82, 86,141,140,129, 80, - 14, 99, 42, 29,250, 93,128, 39, 98, 55,238, 64,233, 99,214,219, 98,176,130,186,186, 61, 66,153, 3,200, 12,138,151, 0,172,107, -174,228,216,130, 24,139,170,168, 32,128, 73,218,246, 35, 9,159, 71,167,209,161,120, 20,248,236,194,134,100,203, 91,178, 29, 95, -186,251,203,202, 90, 28,149, 81,118, 76,215,143,188, 39,196, 74,202,151, 33, 97, 35,155,151,196, 40, 72,195, 37, 84,174, 73,169, - 84,154,106,129, 77, 18,105, 49, 10,229, 68,157, 80,241,218,102,167, 32,224, 55, 84, 90, 25,111,222,102,198, 15, 5,251,154, 64, -109, 11,229, 46,180,231, 39, 33, 15,133, 74, 59,117,246,189,234,168,242, 95,136,212,199, 36,199,182,218,105,167,105,241,249, 74, -146,211,181,151, 92, 73, 53, 87, 2,149,206,150, 9, 76, 54,221, 64, 80,109,197, 32, 43, 88,189, 94,149, 6, 43,205,191, 86,230, -247,217,135,221,162,211,216,142,170,140,185,124,205,173, 45, 70,131, 10, 58,124,106,140,226, 75,124,160, 0,202, 50, 8, 82, 18, - 57,198,220, 72,224,134,210, 45,176,191, 96,122, 95,208, 6,189,206,219,216, 29,247,196,207, 33,174,134,153,155,219, 85,171,171, -156, 48,220,187, 89,207, 83, 96, 67, 75, 32, 91,221,193, 17, 45,216,175, 48, 50,178,224, 84, 74, 44,154,236,184,109, 72,113,234, -237,116,165,197,177, 54, 82,143,185,194,138,164,184,249, 16,105,241,143, 44,103,208,121, 50,164,146,226,240,182,220,119, 4,235, - 37,164, 65,153, 92, 80,137,106, 70,139, 82,125,151,164,197,155, 93,168,123,196,123, 46,150,251, 8,240,252, 17,238, 40, 42,185, -170,222, 34,155, 80,141, 16,150, 88,230, 75,114,101, 51,130,141,103,113,118,222, 84,228,199,126,232, 95,240,106,136, 16,215,189, -218, 86,235,201, 53,185, 52,220,146, 81,114, 92,236, 97, 49, 90,112,128, 36,194,166, 1,146,181, 52,236,199,138, 84, 53,147, 85, -149, 73,182, 92,129, 6,223,109, 81,169,207,198,147, 79,163, 83, 41,232, 5, 82, 81, 29,145,152,108,180,165, 54, 91,134,211,156, -200,113,210, 18,218, 3,193,103,153, 99, 39,101,145,165, 85,144, 39, 49,211,208,128,187,218,251,146, 58, 53,134,171, 94,215, 4, - 88,173,147,175,226,120,170,103,246,122, 6, 21,149, 44, 27, 66,168,189, 44, 37, 67, 23, 6, 68, 33, 36, 54, 58,210, 58,127,236, -202,171,173,165,149, 12,145, 11, 77, 10,223,167, 90, 47,203,153, 93,154, 39,203,117,178,229, 86,225,153, 22, 43, 10, 90,217, 97, -108,173,148, 73,109,194,197, 34,138,149,128, 98,176,158, 86, 18,160,180, 32,169,197, 18,171,243, 12, 71,188, 39, 42,174,205, 61, - 18, 45, 72,169, 45, 52,144,181, 82, 30,158,238, 86,184,179,219,134,160,218,163, 82,146,160,225,109, 14, 58,219,178, 20, 76,135, -249, 18, 91,109, 56,227,176, 25,153, 75,137, 81,185,166,184,212, 78, 68,193,165, 81, 33, 56, 20,195, 85, 39, 10, 11, 82,165, 48, -193, 47, 87,234,137,240,209,202,128,158, 72,168, 70, 91, 66, 74,214,240,187,209,162, 25,147, 29,241, 80,243, 20, 40, 45,185, 21, -234,107,146, 57,170,243,146,235,172,178,227, 19,125,225,132, 36,196, 91,197, 42, 68,112,151, 28, 82, 94, 80,113,210, 62, 13, 58, -210,106, 66,183, 75, 35, 17,168,117, 97,109,198,228, 16,111,212,237,190,224, 90,197,113, 23,172,103,117,158,190, 74,182,147, 48, - 80, 99,105, 64,211, 10, 1,101,209, 78,168, 99, 38,107,105,141, 52, 17, 20, 68,221,110,162, 55, 14,212, 81, 18,171, 73, 69, 54, -151, 80,170,193,183,229,135,231, 85, 42,149, 41, 47, 79,143, 80,247, 20, 52,203, 16, 98,229,240,126,168,115,170, 31,125, 39,149, -208,202, 26, 10, 40,231,230,113,232, 15, 68,139, 87,166, 53, 26, 60,198, 94,122, 51, 68, 71,148,250,148, 25,103, 63,162, 83,229, - 41, 41, 99, 37, 69, 44,160, 37, 60,201,103,152,129,206, 20, 27,135, 43, 8,141, 22,153, 2,220,110, 28,171,174,170,134, 89,142, -153,169, 66, 35,209, 88,108,174, 57,126, 80,125, 99,220, 96,135, 91,113, 92,141,161, 33,199, 27, 75,101, 92,216, 34,241, 2, 53, - 62,152,134,101, 34,161, 49,233,206,169,137,117, 56,178,156, 90,231, 45,245,190, 29,112,130,215,199,159, 17, 9,113, 10, 64, 72, -240,130, 80, 82, 83,212, 76,105, 31,217,222, 25, 64,230,104, 8,110,162,224, 1,102,223, 85,193, 99,246,172,183, 96, 73,103, 47, -101, 81, 84,230, 84,205, 52, 18,164,134, 72,163,156,202, 35,140,221,164,118, 98, 85,165,150,214,109, 39, 74,162, 72,246, 71,229, - 5, 65, 26,139,159,203,207,219, 83,176,204,240,223,237, 79,227, 35,111, 41,204, 69,139, 67,175,238, 80,222, 59, 98, 36, 38,195, -113,161,208,183,162,149, 7,112,132, 52,182,144, 3,101,170,213,102,182,215, 40,232,148,176,158,221,135, 48, 73, 36,100, 96, 99, -184, 61,250,246,212,159, 62,150, 45,137, 6,222,246,135,108,254,224, 66, 67,137,123,117, 56, 94,183,220,168,135, 22,209, 74,230, - 88, 87,181,215, 66,109,109,161,180, 2,209, 52,250,172, 0,176,165, 45, 68,165, 61, 64, 1, 34, 48, 64,228, 21, 18, 15,251, 56, -236,115,211, 86, 37, 3,171, 82, 68, 23,236, 70, 90, 53,182,195, 76,108,209,131,111, 66, 22,227,189,136,190,247,199, 60,230, 49, -152,171,170, 80,253,162,193,143,184,200,162, 66, 62,237, 86,255, 0, 76,120, 41,206, 48,160,113,145,142,217,207,150, 15,125,123, - 0,227,148, 14, 92,116, 63,209,247,244,215,220, 39, 25, 35,191, 83,230, 71,159,125, 87,109,178,242,146,134, 70, 92, 87, 96,172, - 36, 4,128, 84,165, 45, 71,162, 80, 0, 36,146,112, 0,201,233,173,195,210,228,218,223,187, 26, 93,174,118,199,134, 90,117,213, - 33,166,208,167, 28, 90,185, 80,132, 2,165, 40,158,192, 1,174,165,240, 33,236,163,226, 11,141,133,195,187,161,181, 31,108, 54, - 57,185,170,102,161,188,215,148, 9, 46,210, 42,138,140,234, 81, 54,157,182,214,243, 78, 53, 39,113, 42,232,234,133, 62,203,140, - 81,226,186,164,251,205, 65, 68, 45,141,111,127,178,155,217, 11, 7,117,232,244, 30, 38,184,174,161,203,107,103,231,248, 21,109, -173,218, 73,190,241, 78,168,239, 51, 13,168,169,155,182,242,228, 90, 36, 81,246,136,186,131,238,144,210, 90,151,113,134,203,171, - 91, 20,149, 36,203,150,181, 2, 36, 72,241, 41,180,202,125, 62, 5, 42,149, 74,131, 14,149, 68,162, 82,162, 70,166,209,168,180, -168,109, 37,152, 52,202, 93, 50, 19, 72, 98,155, 79, 98, 58, 66, 90, 97,150,208,219,105, 24, 66, 83,166, 25,243, 9, 42, 36, 48, -211, 63, 42, 59,216,200, 44, 75, 90,215, 17,131,112, 7, 91,187, 2, 54,178,171, 92,178, 89,124, 43,192, 18,102, 49, 69,153,103, - 74,240,208,200, 3, 69, 2,157, 18, 76,166,196, 60,141,179, 69, 19, 15,178, 22,210, 56, 58,131, 70,186, 89,244,203,132,143,102, - 23, 8,220, 37,199,165,207,176,182,222, 37,237,184,240,218, 71,188,239, 38,234, 68,167,221, 55,203,178, 8, 5,199,104, 48,157, -143,245,101,141, 16,184, 57,155,143, 75,138,210,217, 36,230, 83,228,243,158,151, 69,160,187, 49,126, 36,133, 58,235,129, 35, 46, - 60, 86,226,143, 94,131,153, 68,246, 24, 3,200,118,213,202,135, 74,248, 27, 28,132,168,164, 41, 71, 3, 60,167,178,137,239,204, -123, 15, 64, 52,232,211,232,248, 74, 64, 64, 35, 29, 71,146, 73,235,146,113,212, 96,254,205,107, 90, 40, 75,114,198,159, 86, 38, -236,109,251, 76, 73, 38,219,253,162,109,208, 91, 22,226, 81, 83,208,192,148,180,116,233, 71, 78,189, 18, 53, 84, 94,219,144,182, -187, 30,236,110,205,212,155,226, 36,191, 73,131,133,184, 14,237,254,198,241,107, 70,166, 37,170,205, 10,172,246,199,238, 12,230, - 90, 72, 51,232,213, 6,101, 92, 59,127, 50,122,210, 50,227,241,167, 51, 87,134,218,213,158, 86,166, 6,193, 0, 1,168,116,169, - 41, 33, 39,204,245,237,215, 39,203,251,117,250, 82,251,111,182,226,159,122,123, 47,248,158, 68,212,183,205,103,209,237,109,192, -166, 56,164,149,248, 53, 59, 98,234,166, 45,165,183,223,145, 74, 98,100,132,103,253, 85,145,219, 95,154,217, 61, 0, 4, 2, 74, -134, 8, 61, 7, 49,198, 52,227,147, 73,255, 0,165, 66, 15,216,112,195,220, 36, 0,159,222,225,201,223,169,197, 33,199,180,137, - 77,196, 45, 34, 0, 5,116, 17, 74, 69,250,190,167,136,155,109, 98,194, 32,222,246, 36,247,192,206,116, 56, 35,174, 1,207,238, -253,186, 25, 65, 61,243,212,246,243, 7, 26, 53,192, 0,199, 55, 83,220,158,189,254, 95,142,132, 88, 87, 83,128, 65,237,142,152, -192,193, 56,199,174,159,241, 15,192, 46, 18, 50, 66,124,241,246,227,185,249,232, 98, 58,147,216,252,251, 39,236, 30, 90, 53,207, - 47,191, 65, 58, 65,207,175,110,189,250, 16, 14, 52,178,244, 30,252, 20,218,254,159,207,182, 5,112,227, 39,190, 51,142,131, 31, -120,199, 78,154, 17, 68,242,243, 31,159, 40,251,126,126,154, 37, 72, 61,249,137,198,122,121,118,238,122,245,213, 5,161, 68,100, - 16,191, 34,124,135,231,247,232,227,183,207,254, 48,111,134, 5, 42, 36, 16, 71,124,114,231,182, 61,126,122, 29, 68,103, 25,234, - 1,232, 6, 0,235,229,162, 84,147,145,215,246,116, 0,106,130,240, 62,121,237,229,142,217,251,124,180,162,141,133,183, 31, 63, - 61,177,144, 1, 62,151,192,138, 73, 25,229, 57,201, 57,255, 0,103,240,208,221,251,232,197, 2, 50, 70, 0,235,156, 30,227, 61, - 50, 61,116, 50,192, 29,129,245, 39,203,236,252,116,170,117,249,219, 10, 40, 4,116,183,200,197,185,230,249,199, 41, 42,198, 70, - 82, 58,103, 25,238, 71,150,116, 51,141,184, 1,235,202, 2,112,144, 0, 36,143,159,167,158,174, 42, 0, 30,132,158,249,207,174, -132,121,178,164,158, 85,169, 7, 39, 24,254,119,219,234, 51,165,176,110,158,235,226,222, 82,148,255, 0,148, 36,147,212, 99,211, -208,244,239,165,175, 69,181,182, 0, 82,148,225, 61, 73,192,233,242,239,165,161, 99,233,140,227,210, 7, 92,249, 15,233,252,157, - 20,130, 49,129,223,185,251,245, 65, 32,224, 12,117,234, 63, 19,255, 0, 13, 86, 64,238,124,199, 76,122,104, 96, 96,148,167, 3, -175, 66,127, 28,126,227,253, 90,168,210, 0,200, 56, 61,207, 79,158, 58,231,243,223, 84,210, 73,233,142,131,166,126,239,219,162, - 91, 73, 57,233,223,215,207,166,147,112, 55, 61,255, 0,241,129,143, 96,121,224,159,199,161,251,180, 91, 63, 23,113,203,215, 25, -238,123, 13, 83,109, 35,160,235,215,175,223,141, 18,148,131,208,116,233,158,223,102,147,193, 77,141,238,118,193, 72, 79,216,122, -118,249,250,227,203,207, 85,146, 1, 56, 61, 61, 49,251, 7,109, 14,216,230,198,125, 50,122, 99, 68,160, 2, 64,198,125, 63,225, -164, 90,192,144, 62,122, 97, 28, 86, 29, 14, 58,140,121,159, 62,158,186,218,174, 11,120,121,159,197, 23, 18,123, 87,179,145,130, -147, 79,185,110, 40,206,220,178, 66, 73, 76, 27, 74,150,164,207,184,229,172,143,213, 6,158,202,219, 7,253,105, 35, 90,172, 1, -206,113,144, 59,143,159,245,234, 71,254,193,173,178, 98,146,141,245,226, 34,165, 22, 63,188, 82,169,144,118,234,211,150,250, 66, -158, 98, 93, 83, 19,235,142, 70,200,253, 26,253,223,221, 91, 42, 24, 61,198,152, 56,151, 50, 57, 86, 77, 91, 84,173,166, 80,186, - 80,142,161,155,107,143,122,130, 91,254,220, 76, 56, 7,134, 79, 24,113,142, 65,195,218, 75, 67, 95, 58,243,173,255, 0, 2, 48, -101,152, 92,116,213, 26, 20, 7,179, 48,196,149,103,214, 45,203,102,139, 77,179,109,136,172, 83,237,139, 54,149, 2,215,182,224, - 65, 9,106, 37, 62,145, 72,142,136, 76,165, 49,147,211, 5, 45,100,145,212,231, 39, 86,118,235, 42,143,200,227, 47, 37,210,234, - 18, 24, 83,124,167, 5,120, 37, 7, 39,169, 39, 31,142,154, 22,235,241,228,173,213, 7, 98,188,149,229,164,178,233,228, 89, 82, -186, 30,101,122, 21,107, 39,167, 33,181,182,204, 85, 70,113,109, 7, 2,195,161,204,169,167, 50, 20, 18,130, 15,196, 61, 53,201, - 85,114,187,206,236,205,119,148,147,111,221,239,252,122, 91,240,246,231,132, 50, 26, 12,191, 43,166,165,142, 30, 84, 80,168, 93, - 32, 13, 58, 85, 84,105,177,176, 1,109,176, 91, 3,211, 99,135,136,196,145, 38, 52,105,210, 76,121, 79,186, 10, 76,117,169, 45, -200, 65, 31,170,160, 65,233,140,104,132,199, 66,144,161, 62, 50,221,107,148,150,150,164,248,168,109, 67, 33, 74, 86, 6, 71,200, -131,160, 41,209,224, 56, 99,202,116, 72, 15, 50,217, 66,222,125, 75, 64,192, 24, 0,163,205, 35,215,229,172,162, 35,108, 56,218, -125,222,104, 97,121,193, 42, 81,113, 50, 18,162, 73, 1,181,118, 3, 58, 69,199,148,148, 66,227,107,244,216,237,190,219,127, 28, - 18,170, 83, 9, 43,230,178, 30,161, 74, 4,185, 54, 11,164,181,128, 27, 95, 77,200, 59,139, 97, 81,169,202,247,134,228, 67, 90, - 39, 71, 36, 55, 34, 19,199, 15, 6,193, 24, 91, 89,234,160, 7,109, 86,220,221,191, 69, 90, 85,181,115, 68, 96, 46, 68, 6,140, - 7,138,147,149,150, 82,160,166,208,188,140,168, 39, 39, 25,242,233,167, 58,137, 71,166,201,142,194,201,142,212,216,196, 6,229, - 50,121, 11,153, 61, 65, 3,161,199,207, 78,207,240,125,201,244,162,195,141,165,106, 65, 67,236,188,216,248, 92, 90, 48, 74, 84, - 7, 98, 83,144,126,221,106,152,228,100,145, 44, 64,101, 22,223,184,183, 79,141,173,235, 98,111,138,187,136,120,137, 99,171,130, -101, 58, 30, 38,100,109, 86, 82,202,195, 78,228, 88, 56, 32,141,236,172, 58, 16,109,124, 91,182, 90,193,101,183,152, 82, 35,165, - 30,248,200,113, 65, 41, 9, 79,140, 82, 57,198, 49,211,152,245,251, 78,155,223,104, 77, 33,251, 91,135,122,140,200,202, 44, 42, - 69,199, 77,109, 75, 9, 39,197,247,120, 85, 7, 27,105,208, 6, 86,128,176,147,145,219,151, 56, 58,220,141,174,167, 53, 29,232, -216, 70, 58, 14,152,232,133,143,214, 72, 31,205, 26, 97,253,170,148,143, 23,133, 86,229, 70, 46,101,187,202, 15, 56,105, 57, 89, - 75,148,154,162, 84, 79, 78,191,171,143, 92,159, 93, 75, 50, 90,104,205, 42,203,166,242, 70,111,241,189,135,243,239,235,142,124, -204,184,154,105,248,255, 0, 33,161,119,211, 75, 85, 83, 4,100,118,176,147, 86,254,237,133,254, 24,136, 5, 65,227, 38, 82,145, -202,226, 39, 41,110,184,151,185,156,241, 27, 46, 17,149,180,210, 23,200,250, 75,169,109, 32, 45, 42, 64,235,207,202,174,244,225, - 84,213, 6, 69, 67,223,225,189, 84,158,167,131,113,207,129, 29,150,216,138, 80,148,182,153,212,240,151, 19, 0,248,133,126,240, -180,243,120,152, 79,110,128, 7, 61,166, 95, 74, 93, 83,147, 93,247,105, 92,175, 73,101,190, 69, 71,105, 74,202,153, 10,108,130, -212,142,100,163, 40, 88,230, 36,130,160, 83,202, 52, 77, 26, 68,232,229, 30, 27, 79,123,184, 37, 79,205,166,196,101, 85,116,182, - 73, 71, 35,108, 72, 90, 68,166,220, 46, 4, 56,180, 23, 84,209, 5, 97, 7, 3,149,225,214,234,123,129,216,253,221,239,113,176, - 23, 3,174,219, 95,167,161,116,245, 3,200,177,221,159,162,132,176, 97,182,229, 73, 27,128, 53, 11,223,179, 1,176, 39, 14, 61, -179,110, 49, 87, 92,138,164, 73,146,233,178,165,150, 16,227, 84, 69, 42, 50, 94,109, 10, 71, 71, 96,168, 22, 37,159,133,105, 75, -193, 9, 83,132,168, 41, 95, 14,158, 74, 45, 26,235,147, 34, 76,184,244,134,171, 40,104,204, 83,146, 41,175, 68,162, 76,140, 26, -117, 76,161, 51,233,207, 31, 0,115,161,149,165, 62, 10,135, 57, 87,234, 12,157, 54,148,138,123, 5, 81,133,159, 38,108, 39, 22, -195,242,231, 68, 66,152,157, 2, 68,128,208, 83,174, 57, 5,247, 3,144, 18,140,142,105, 41, 91,107, 89, 89, 79,134, 84,158,109, -108,157,156,170,253, 2, 24,110, 77, 1, 74, 65,106, 28,151,106, 52, 57, 77,206,132,236,118,255, 0, 72,150,159,167,169, 41,148, -219,202,116, 37,124,170,241, 18,165, 16, 50, 10,136,212,110,190, 89, 0,102, 91, 57, 54, 10,173, 96,125, 45,246,150,247,176,217, - 88,139,245,185,184,195,137,205,164,100, 34,153, 99,169,146, 43, 14, 92,202, 82, 66,118,230,106, 62, 73, 25, 71, 75,134,111, 41, - 23, 70, 4, 1,238,148,138, 91, 79,179, 2,163, 42,161,107, 43,221,217,145, 13, 23, 52, 5,211, 28, 76,196,148,190, 35,243,188, -223,129, 37,188,163,195,105,198, 94, 1,193,212, 37, 68,105,199,141,108,212,103, 60,153,146,233, 80,100,164, 73,113, 42,158,134, -163,128, 66,210,128,223, 59,193,178, 90, 87, 40, 29, 82, 74,185, 79, 84,231,174,179,235, 33,170, 93, 82, 77, 65,154,147, 17, 46, - 76,178,176, 41, 85, 40,140, 45,104,144,248, 64, 74, 13, 62,115,105,115, 41,101, 46,164,185,225,171,144, 31,132,142,153,120,104, -155, 91,103, 58,196,127,118,165, 59,108,201,150,211, 50,140,139, 86,167, 83,165,188,209, 10, 66, 17, 17,112, 22,243,140, 60, 16, - 72, 81,231, 97,105,115,147,153, 93,245, 22,146,172,134,180,138,209, 72, 58,244, 55,189,174, 71,217, 35,212,143, 54,251,139, 30, -173,181,252,117, 14, 86,239, 28,240, 77, 72,225, 81,117, 42, 44,182, 50, 45,220,171, 22,130, 84,251, 42, 72, 28,237, 90, 65, 85, - 58, 66,227, 1,178,236,216, 17,129,148,194,170,116,121,146, 79,188, 38, 93, 38, 95,133, 10, 82,217, 78, 91, 18, 24,229,114, 60, -196,167,194, 87,134, 28,105, 10,115,149, 65, 71, 7, 26,218,107,126,109, 90, 10,162,154,132,152, 21, 33, 32, 55,133, 48,201,165, -212, 26, 80, 33, 63, 20,102,159,113,167,222, 82, 65, 82,130, 11,105, 73, 39,225,199, 46,172,180, 45,177,175,198,113,230,233,151, -117, 62,124, 98,178,148,183, 92,183,144,196,137, 9, 81,248,202,103, 82, 28, 65,109, 73,194,146, 20, 24,229, 74,149,158, 83,170, -151,157, 90, 22,218, 91,117,139,187,113, 17, 73,181,172,155, 85,134,101,215,110,181,213, 99,253, 77, 72, 98, 68,134,161, 70, 15, -171,149, 18, 12,199,165, 63, 30, 59, 44, 48,211,146,228, 58,240, 75, 8,112,149, 16,164, 80,243, 60,247, 50, 62,199,125,199,193, - 73, 23,219, 99,125,143, 82, 0,239, 80,241, 39, 21, 71,196,149,209, 83, 82,212,174,107, 81, 80,226, 56,226, 80,230,162, 70,147, -234,226,138, 33, 50, 71, 80,238,238, 21, 99,138, 13,122,152,170,128,194,195, 15, 28,122,147,162, 40,105,244, 58,132, 37,223, 18, - 3,231,194,234,242, 86, 28,114, 59,165, 43, 30, 26,249,214,164,228,128,219,188,202,202,185,192,213,242, 37, 81,151, 30,143, 37, -197, 57,226, 48, 3, 43, 43, 9, 11, 44,184,174,102,157, 83, 95,206, 90, 22, 66, 70, 64,200, 86,124,137, 13, 21,189,112, 82, 46, - 11,114,151,114, 91,117,216,119, 21,175,113, 83, 33, 86,232,117,120,238,174, 76,106,173, 26, 82, 67,145,101, 66,125,192, 11,141, - 45, 4,130,146,128,164, 41, 37,183, 57, 92, 66,210, 3,147,114,251,147,205, 46, 54, 83,202,178, 2, 20,226, 80,132,161, 96,169, - 73, 10, 36,120,173,129,204,140,147,204, 20, 64,198, 59,150,162, 37,117, 42, 5,134,194,253,108, 65,216,110,125, 71, 75, 11,250, - 92,139, 85, 45, 11, 75, 83, 85, 72,209,180, 51,196,206,140,172, 25, 25, 24, 29, 14,146, 35, 0,209,184, 32,134, 82, 46, 24, 18, - 55, 26, 78,240, 90,213, 31,208,130, 86, 9, 4, 18,130, 72, 73,229, 80, 42,230,108,126,177,199, 46,112, 65, 25,207, 93, 58,209, - 39,130, 16,145,159,214, 81, 60,157, 65,194, 72, 0,114,156,158,128, 96, 14,165, 71, 30,128,234, 46,217,220,212,153,116,202,237, -193,112,215,105,214,197,177,108, 64,126,171, 91,175,213, 37,166, 53, 46,151, 79,136, 18,100, 76,145, 41, 67,244, 76, 39, 45,163, -148, 5, 41,199, 22,134,154, 11, 82,210,147,121,177, 56,210,225,140,221, 20,202, 80,185, 43,180,231, 43, 85, 4,209,236,251,142, -240,181,165,219, 54,109,110,224,123,244, 52,198,233,213,121,111, 56,150,164,191, 39, 34, 8,154,220, 70,223,145,203,133,133,114, - 37, 82, 44,159, 40,174,158,140, 87,178, 8,168, 83,237, 72, 72, 38,202, 69,200, 91,220,219, 97,125,133,250,145,136, 77,103, 11, -113, 14, 98,249,179,100,188, 59, 93,159, 12,160, 94,161,169,105,165,154, 56,137, 78, 96, 87,150, 53,100, 83,203, 28,198, 91,150, - 88,129,148,174,133, 36,110,229,114, 79,128,205, 58,148,133, 31, 26, 20,100, 59, 45, 60,196,132,212, 39, 20,202,122, 50, 84, 70, - 84, 27, 10,142,218,188,129,109, 73,206, 70, 5,137,201, 14, 46, 63, 35,110,172, 30, 98,236,137, 60,136, 43, 66,208, 65, 73, 5, -196,225,111,114,171,166, 73,229, 9, 25,193, 3, 88, 95,215,200,158,183, 30, 67,206, 41, 43,116,248,202,117,107,231, 82,249,143, - 62, 86,165,101, 75, 43, 42,230, 4, 2, 9, 87, 55,198, 14,178, 38, 92, 98, 67, 32, 20,251,201, 8, 88,240, 16,146,164, 41, 67, -178,192, 65,194,147,145,216,231, 10,198,125,116,226,139,237, 51,153,109,101,216, 45,137,176, 85, 0, 40, 38,219,249, 64,243, 91, -246,186, 2, 70, 32,113, 80,251, 44, 81, 44,131, 83,130, 89,141,129,187, 49,212,196,131,181,139, 18, 64, 38,192, 90,228,140, 52, - 23, 71, 18,155, 27,182,247,133, 23,109,175,221,230,219,141,180,184,238, 72,209,228,209,169,247,213,194,220, 10,181, 86, 20,201, - 78, 65,135, 62, 60,103,163,251,172, 38, 37, 75,102, 75, 81,164,214, 36, 66,142,250,153, 91,141,169,214,146, 84,119, 30,147, 66, -165, 80,195,147, 41,232, 38,166,235,108, 25,149,121, 74, 76,250,173, 65, 50, 26, 67,141,184, 37,252, 94, 36, 34,194,208,182,218, -140, 81, 20,180, 82, 89, 10,109, 73, 89,131, 15,180, 99,113, 31,190,120,217,226,105,247, 21, 37, 48,237,189,193,122,201,132,220, -231, 27, 90,216,183,172, 58, 52, 11, 98, 37, 40,182,149, 41, 9,140,210,225,202, 12,167,155,149,105,150,162,177,158,154,222,143, -101, 55,180,158,109,129,120, 91, 92, 38,241, 1,118, 84,165,108,197,201, 83,133, 67,218, 59,194,177, 84,117, 3,105,238, 58,130, -145, 22,145,102,215, 42, 78,168,190, 54,130,167, 53,198, 99,180,128,239,129, 65,155, 33,153, 40, 74, 41,207, 76, 66, 18,163,204, - 18,106,169,105,103,136, 44,113,146,169, 37,205,135,152, 11, 55, 64, 21,137,251, 98,218, 65, 1,129, 26,156,119,103,137,223, 65, - 12,230,155,192,222, 23,241, 67,129,120,142,163, 57,207,166,202,105,115, 92,243, 34,120, 80,201, 36, 83,210, 71, 89, 57,203, 94, - 45, 47, 81, 37, 18,146,173, 69, 62,179, 89,161,231,164,145, 39, 16,209, 79, 40,202,229,206,203, 50, 92,167,210,208,107, 18,249, - 17,239,226, 44,119,234, 17,224,182,163,206,183, 36, 8,104, 87,141, 37, 68, 5, 37,149,169, 33,190,156,196,116, 73, 21, 52,233, - 79,123,195,137,167, 34,158,186,130, 89,101,234,213, 77, 81,234, 87, 35, 64,168, 41,152,136,167, 35, 45,198,233,144,132,186,180, -161,158,159,161, 42, 57,214,118,211,109, 82,144, 99,162, 60,122,107, 81,146,184,210, 98, 6,209, 25, 12,173,165,168, 41,185, 13, -180,145,149,165,224,224, 89, 57, 61,193, 61, 53,141, 63,114, 33,233, 11, 85, 22, 2,170, 6, 42, 84,212,185, 46,120, 80,168,201, -117, 77,148,182, 88,156,160,181, 73,125, 4,163, 41,105, 11, 32, 40,146,226, 20, 64,212,177, 40,249,104,218,136, 93, 29, 1,247, -238, 71,235, 92,237,232, 58, 18, 54,181,252,231,165,168, 98,130, 44,186,134,201, 24, 5,166,121, 54, 99,112, 87, 94,233, 10,130, -202,186, 81,249,136, 78,144,193,201, 44, 84,122, 5, 38, 28, 86,234,113,156,144,169,205,161,212, 57, 82,170,201, 76,201, 45, 60, -163,153,137,113,197,182,159,113,143,202,130, 20,219, 0, 33, 33, 33, 36,173, 0,232, 37,215, 92,148,250,153,181,195,113, 24,204, - 83,252, 40,144,178,220,218,116,212, 96,205, 77,188,203,169,196,146,181,168, 6,221,112, 41,150,139,220,205,165, 69, 32,139, 44, -136,107,113,106,122,179, 49,215,100, 48,241,113, 20,248,234,113,186,107, 6, 70, 20,166,155,136, 28,230,125, 10, 89, 0,151, 66, -148,164,164,149, 30,184, 24,253,199,122, 66,165, 47,234,152,208, 81, 88,170, 60,133,169,134,151, 37, 17, 89,142,182,144,160,195, -138,116, 16,184,175,115,146, 26,228, 35,152, 2,144, 10, 70,182, 97, 64, 14,163,229,113,223,173,246,245,220,141,236, 46,119,233, -208,144,112,239, 75,150, 79, 93, 50,162,150,205,103,109, 68,106,254,230, 52,186,181,201,144,170,200,168, 55, 28,194,177, 0, 89, - 74, 58, 49,195,130,197, 46,151, 71,143, 89,156,136, 50, 16,226,147,239, 45,220,146,230, 75, 91,181, 22,228,134, 85, 46, 53, 65, - 42,116,169,215, 27, 81,116, 21,143,136, 56,176, 83,223, 69,209,101,194,118,104,120,212,188,105, 41,116,182,242, 25, 83,206,149, - 54,218,214,160,181,186,242,194,131,168,108,182, 83,205,250,200,108, 3,147,240,233,134,126, 83,142,181, 21,235,160,213, 20,137, -105,109,136,245, 1, 33,149, 69,131, 86, 73, 74,228,162, 18,225, 47,194, 98, 66,176,143,133,208, 29, 73, 36,133, 44,128, 52,237, - 91, 17,157, 91,145, 84,244,169,143,180,227, 68, 21, 75,109,133,243, 33,111,129, 20, 74,114, 56,241, 39,182, 84,174, 82, 70, 20, -165,173, 69, 57,239,167,120,101, 42,241,198, 6,146, 55,181,138,219,126,164, 14,187, 16, 5,245, 16, 5,201, 45,115,133, 51, 76, -165,169, 40,229,154,170,189,170,102,150,227, 88, 37,145,130, 42,169, 88,221,140,154,183, 83,169, 71, 40, 43,236,138, 6,155,195, -227,233,107,174,155, 39,136,190, 10, 30, 97,107,118,164, 56,127,220, 70,158,146,160, 16,217,132,155,246,143,200,210,154, 35,155, -222, 4,191,120, 37, 71, 9, 82, 86, 10, 64,235,168,152,132,228, 28,164,164, 19,215,231,143, 77, 73,155,233, 79, 95,204, 87,248, -240,217,189,185, 66,217,147, 47,105,120,111,164,154,148,182,157, 83,138,126, 70,226,221,245,186,220, 86,150,133,146, 80,148, 83, -104,144,212,158,249, 18,186,147,129,168,234,237,246,223,222, 27,165,119,219,150, 21,133,110, 86,174,219,186,237,172, 68,160, 91, -118,213,189, 79,122,169, 91,174, 86, 39, 44, 34, 53, 58,153, 1,128, 75,239, 43,226, 82,212, 74, 91,101,180, 45,231,150,219, 72, - 90,211, 98,229, 79,202,203,150, 89, 92, 34,171, 76, 88,147,176, 28,199, 55,185,216, 11,111,185,252, 49,198, 60, 76,139,250,126, -189, 32, 28,197,102,132, 46,145,114,196,195, 16, 0, 0, 1, 44, 73,181,128, 4,182,214, 7,108, 96,193, 42, 89, 72, 66,114, 71, -100,165, 36,149, 99,176, 0,119, 58,237,167,177,211,217,215, 3,138,221,197,169,239, 54,241,210, 85, 43,135, 45,155,171,194, 77, -122,148,248, 83,108,110,166,227, 37, 13, 84,169, 27, 94,149,140, 21,219,145, 99, 42, 44,251,145, 77,156,169,135,162, 82,185,144, -185,207, 4,246, 39,129,175,163,187,181, 22, 69, 46,141,184, 92,116,214,164,223, 87,121,101,186,140,141,132,177,171,110,211,108, - 90, 17, 41, 14, 34,153,125,223, 20,181,162,117,229, 60, 3,201, 42, 45, 53,216, 84,224,161,200,151,229, 4,149, 43,177, 76, 91, - 27,113,181,244, 24,150, 14,210, 88, 54,166,216,237,189,188,185, 31, 81,216,214, 37, 26, 21, 6,221,166, 25,110,243, 75,144,204, - 24,141,132,174,107,238,225,201, 18, 29, 43,126, 67,129, 42,121,215, 23,130, 27,243, 44,205,164,167, 43, 26, 24,161, 39,118, 99, -165,220,118, 10,191,105, 84,157,152,182,150,181,202,117, 86, 19,158, 18,240,238,182,106,218, 90,236,242, 5,138,150, 59, 56,166, - 62,103,145,133,180, 9, 71,217, 84,185, 12,200, 75, 22,182,135, 80, 11, 12,100, 74,154,169,242,176,132, 54,203,109, 54,195, 44, - 71,140,203, 81,226, 70,137, 29,164,179, 10, 4, 72,236,165, 45,195,134,212,102, 91, 75,109,182,148,182,219, 76,161, 8, 74, 80, - 18,144,232, 90,112, 2,249, 93,117, 25, 66,146,209, 71, 66, 22,162,163,134,241,211,245,150,177,159,152, 58,106,104,113, 92, 82, -188, 39, 22, 57,159,117,107,144,172,114,134,208,144, 20,235, 77,249,242, 37, 62, 27, 96,249,156,159,144,217, 59, 62,158, 23, 33, -162,160,146, 26, 67, 60,168,236,129, 33,209,134,130,134, 48, 2, 26, 35, 31, 51,211, 77,180, 46,116, 52,199,224, 54,176, 30,128, - 14,214, 29,134,219,219, 98, 14, 47,113, 78, 21, 72, 3, 87,123,254,238,135,222,126,240, 59, 91, 14,157, 22,158, 26,105,164,172, - 5,168, 4,243,159,213,231,121,125,145,208, 99, 30, 93, 60,129,211,139, 26, 35,109, 54, 49,133, 17,220, 16, 79, 83,232, 60,250, -246, 31,187, 86,138,100, 68,165, 73, 8,229, 81,142, 64, 42, 86,112,183, 22,144, 21,130, 15, 85, 36, 19,242, 28,218,203,218, 78, - 49,240,169, 41, 70, 66, 74,122,165, 68,142,170,207,160, 57, 72,251,254, 88,216, 14, 90,230,251, 15,244,249,254,125, 48,211, 87, -166, 54,210, 5,205,133,251,123,192,239,235,247, 3,211, 99,142, 83,123,105,234,144, 40, 62,204, 78, 45,213, 56,172, 10,158,223, -193,161, 68,109,166,214,234,222,168,213,110,106, 44,120, 49,210,219,105,230, 42, 83,161,103,253,144,131,228, 53,249,148, 74,163, - 86, 33,178, 31,157, 73,168, 68, 97, 73, 37, 15, 75,136,244,102,150,130,114, 10, 29,117,176,149,119,242, 39, 7,166,117,250,228, -239, 21, 54,139,113, 81,162, 91, 21,234, 77, 58,187, 2,167, 53,185, 83, 41, 53,168, 81, 42,144, 36, 71,167, 16,227,102, 68, 9, -141, 45,167,146, 37,173,178,146,164,171, 5, 25,232, 70,154, 39,182,131,105, 43,148,145, 68,173,237, 86,217, 86,168,230, 58,226, -138, 93, 86,195,181,102,211,147, 24,131,204,194, 99,191, 75, 41,109,188, 19,219,175, 94,132, 30,186,205, 29,108,244,181, 21, 13, - 12,113,200,178,104, 7, 83, 48, 55, 91,237,178,176,177,213,114,119, 55,218,198,215,196, 43,137,120, 6,163,136,230,167,205,151, - 49, 90, 53, 72, 22, 32,134, 2,250,180,203, 43,106, 45,205, 75, 41, 46, 64,178,159,179,125,239,183,228,250,227,101, 60,188,224, -140,142,128,244,207,144,199,168,198, 48,126,122, 21,192, 0, 3,155, 35, 57,233,215,215,166,191, 65, 78, 47,125,129,220, 19,241, - 21, 2,167, 90,218,170, 35,252, 48,110, 99,233,144,252, 74,205,131, 29,202,134,222,212,103,172, 18,132, 92, 59,119, 53,242,134, - 99, 45,220,115, 59, 76,122, 43,169, 25, 41,109, 88,229, 48,230,227,131,217,183,196,255, 0, 1,119, 35,112,119,146,205, 19,108, - 74,180,247, 33,217,251,193,104,151,171, 59,105,118,144,165,248, 44, 49, 88, 13, 5,219,245,162,132,229, 84,234,138, 35,202, 73, -200,108, 58,145,204,100,244,217,164, 82,178,199, 50, 26,105, 9, 0, 92,221, 24,250, 43,250,158,193,130,177,236,164, 11,226,164, -206,184, 91, 56,200, 65,146,174, 1, 45, 32,219,159, 17, 47, 24,222,195, 93,194,188,123,216, 93,212, 33, 36, 42,187, 28,115,229, -210,158,163,169, 24, 62, 96,119,253,255, 0,215,160,212, 66,187,167, 24,232, 58,249,116,198, 49,219,174,141,117, 3,152,133,229, - 39, 56, 41,199, 80,122,227, 65,120, 97,165,169, 73,201, 43,238, 14, 79, 41,235,146, 61, 52,244, 14,192, 1,182, 35,160, 31, 92, - 14,231, 32, 73, 74,186,231,203, 24,251,137,244,208,101, 3,148, 32, 40,165, 57,236, 60,201,209,133, 63, 26,186,168,231,201, 71, -225, 29,187,121, 13, 81, 86, 50,122, 16,115,246, 12,124,177,163,142,222,236,103, 3, 40, 3,211, 29,186, 30,189,241,215, 57,208, -203, 24, 36, 15, 67,140,252,199,207,203, 69, 47,208,103,166,115,229,147,129,215, 62,186, 25, 64,244,230, 29,124,143,175,113,215, -212,233, 85,189,129,245,235,243,240,198, 69,172,126,125, 48, 42,129,193, 30,127,147,161, 85,246,156, 17,215,204, 2, 8,199,217, -162,148, 58,146, 20,122,103,207,167,159, 83,161, 92, 42,235,233,230, 71,159, 95,232,210,139,215,173,176,170,143, 95,157,176, 50, -206, 15, 76, 31, 80, 71,224,126,220,104, 85,168,227, 28,189,125, 61,126,206,154, 37,100,103, 3,200,156,244,243,249,232,117,227, - 57,235,233,242,251,180,182, 50,126, 54, 56, 25, 99,175,159, 81,231,229,242,210,215,178,172,119,200,244,198, 14,127, 31, 61, 45, - 40, 47, 97,229,191,200,255, 0, 79,155,224,126, 56,162,144, 64, 30,191,143,158,170,163, 62,125,137,232,115,220,250,106,159,236, -213, 69, 35,156,131,204, 71,166, 63, 63,156,233, 54,219,160,220, 99, 35,227,108, 20,131,208, 14,228,121, 99,231,251,116, 80, 56, - 35,184,249,250,104, 22, 57,146, 8, 81,234, 59, 31, 80, 60,243,247,232,209,216,117,207,207, 68,223, 77,200,244,254, 88, 24, 45, - 24,207, 92,231,203, 69, 35,207,183,239,208,173,124,207, 92,126,127,118,138, 64,232, 79,221,249,252,249,105, 44, 16,142,190,251, - 15,145,130, 80, 58,103,215,250,244, 66, 49,140,129,215,212,247,207,245,106,146, 48, 57, 79,150, 7,252,116, 64,193,232, 49,223, - 31, 97,210, 44, 79, 91,236,127,211,253, 48,153,183, 97,138,128, 40, 5,103,208,224,119,235,169,123,123, 41,104,112,173, 78, 2, -173,121, 73,134,167,220,191,111,139,158,183, 80,116, 97, 14, 1, 26, 65,131, 29, 41,199,146, 91,142, 0, 58,136,106, 65,193, 4, -140,224,156,227,211,175, 77, 75,111,217,163,113,199,172,240, 9,183,233,105,231,146,187, 86,241,187, 45,249,133,131,143, 9,213, - 78,114, 75, 97,196,121, 2,219,168, 32,158,224,244,213,121,226, 65,147,244, 28, 33, 13,148,206,186,191,254, 57, 45,142,131,250, - 49, 71, 12,158, 42,209,137,118,101,162,169, 41,214,225,249,148,226,226,196, 27,233, 45,211,181,251, 99,118,128, 83,114,214,210, -153,146,220,116,144,235,125, 10,212,129,205,144, 20,161,156,249,105,224,180,100,161, 50, 35, 25,130, 74, 80, 57, 85,206, 20,176, - 26,230,198, 22,164, 30,253,198,153, 40,181, 49,238,232, 92,122,195, 47, 73, 82,210,211, 81,100, 39,149,110,184,178, 82,218, 1, - 61,252,180,248,219,242,107, 80,222,162, 71,155, 77, 98,169, 61,192,124,102, 35, 56,130, 91,108,254,170, 94, 72,254,110, 58,245, -215, 54,213, 70,193,217,152,217,148,130,111,182,219,117,233,112,127, 28,123, 9,151,215,172, 84,113,194,236,164,181,215,237,232, -114,116,222,246,144, 11,142,228,222,194,248,216, 58, 84,210,135, 89,145,227, 49, 81,108,184, 26, 12,189,132,132,180,123, 21,146, - 58,249,103, 78, 29, 49,216,145,157, 46,202,141, 0, 50,165, 99,153,162,151, 0, 10,255, 0, 80, 14,216,207, 93, 55, 22,253, 58, -116,249, 14,180,186, 68,194,162,227,110, 41, 40,100, 22,154, 72,236,208, 41,238, 63,167, 78,237, 50,222,105,197, 50,210,160,203, - 5, 43,248,209,238,139, 82, 16,172,254,170, 84, 6, 15, 64,123,246,209, 97,137,100, 58,121,100, 21, 38,219,129,125,253,251,159, -203,124, 66, 51,202,138, 53, 13,169,202,221,119, 10,203,112,189, 71,216, 96, 1, 27,139,233,177,239,124, 60, 54,123, 86,252,196, -161, 45,162, 50,155,229, 7,170, 74, 10,129,238, 6, 71,112,116,252,211,104,240,209, 29, 41,140,174, 68, 20,228, 53,207,204,217, - 24,234, 19,232,174,250,105,109, 74, 83,112,209, 24, 57, 24, 70, 14, 44, 8,200,152, 24,136,167,206,112,124, 36,200, 90, 75,189, - 71,243,115,233,167,174,148,195,204, 73,247,101,182,182, 20,172, 18,219,237, 41, 33, 67,200,161, 67,203,168,237,167,136,114,230, -101,187, 11,252, 13,192,191, 66,125,255, 0,150, 57,147,139,234,195, 84,202, 96,169,114,138, 75, 0,206, 26,224,108, 77,134,219, -119, 54,216,237,113,131,109,233, 2,149, 48,165, 68,165, 30, 38, 65, 7,177,206, 58, 19,172, 11,142,250,104,187,248, 72,189,156, -100,243,201,160,212,173,234,211, 33, 37, 75, 0, 55, 52,196,120,156,116, 8,228,153,212,158,131, 26,214,142, 52, 56,200,162,240, -178,104,182,149, 18,205,170,110, 30,239, 93,144, 68,251,106,214,167,179, 37,200,145,162, 56,240,138,204,250,159,186, 52,167, 29, - 74,229, 97, 13,180,210, 74,150, 65,201, 72, 25,215, 24,110,255, 0,109,214,236, 89,181,169,123, 63,196,206,212,209,225,216,219, -139, 33, 54,133,121,152,140,200,163, 86,236,207,172, 95, 67, 44,213, 92, 50, 29, 90, 28,247, 39,220,142,243,241,228,161, 37,109, - 48,160, 22,133, 16,160,237,150,210, 77, 74, 30, 57, 24, 4,148, 29, 42, 55,123,122,233, 0,155, 3,252,176,190, 77,224,151, 30, -113,173, 21, 7, 27,228,116, 52,241,195,151,149,172,136, 84,213,193, 77, 53, 92, 16, 72,162, 73, 41,163,149,129,100, 44, 12,107, - 36,134, 56,222, 75, 34,185, 39, 28,240,171, 81, 92, 18,235, 15,189, 50, 83, 15,182,251,205,242,193, 1,135, 11,172,188,227,129, -215, 90,116, 41, 15,167,152, 55,128,160,127, 87,190,113,171,197,186,251, 84,199, 27,110,231, 91, 11, 8,109,105,102,164,211,204, -152, 75, 4,120,205, 50,166, 93, 67,142, 51, 33,194, 84,147,146,190, 85, 0, 82,178, 59,103,187,207, 96, 84,168,155,135, 92,164, -148,251,168,139, 80,118, 74,101, 49,206,195,115, 26, 83,165,196,200, 97,164,164,165, 44,172,160, 41, 39, 56, 83,110, 36,144, 0, -213, 45,183,165,251,180,225, 57,214, 41,211,231, 46, 59,134, 32,155, 57,137, 75, 47, 56,165, 48,251,207, 7, 20,216, 97,211,207, - 28, 22,210,121,212,147,204,148,242,228,105,122,137, 21, 98, 46,198,247, 22, 0, 1,112,118, 0, 3,218,222,150,216,220,157,247, -199, 91,101, 89,173, 61, 78, 87, 77, 84, 36, 38, 42,136, 21,215, 65,180,182, 96, 28, 89,154,203,123,157,181, 30,246, 5,126,214, - 30, 11, 94,207,114,229,117,201,237, 69,164,202,120,197,143, 54, 85, 82,157, 37,183,147, 22, 59,235,108, 65,134,165, 70,194,224, - 61,226, 33, 45,144,231, 55, 47,196,226,209,149,116,219,107, 39,110,107,207,161,154, 43, 53, 69,192,105,220, 59, 45, 51,224, 51, - 86, 64,151,226,135,152,104,200, 64, 67,211, 90, 7, 24, 74, 94, 41,111, 9,230, 0,233,156,176,182,201, 77,169, 18,170,137,115, -223, 42,193,152,112, 99, 91,243,158,143, 35,199, 74,144,226, 36, 74,147, 13,192,137,144, 80,224, 4,151, 2,137, 82,194, 64, 37, - 56, 27,217,102, 90,215,133, 41, 49, 27,133, 84, 98,165, 57,224,159,142,189, 5,146, 26,113, 35,153,236,152,138,109, 46,169, 69, - 25, 87,137,133,140,117, 36, 18, 53, 10,175,145,203, 5,138, 80,109,208, 48, 59, 17, 96, 8,190,160,123,246, 0,108, 20, 27, 91, - 12, 57,247, 17, 10,106,116,134,130,190,154, 78, 89, 80,156,196, 87, 1,193, 91, 30, 97, 18,163,152,205,238,197, 65, 6,218, 88, - 22,108, 90,237,237,189,152,234,185, 95,164, 89,245,210,228,149, 56,245, 82,107, 53, 74,100,246, 35, 52,164,165,243, 25, 77,135, -115,204,242, 70,121, 29, 74,177,211,148, 96, 43, 79, 29,187, 98, 95,172, 58,106, 17,164, 80, 67, 45, 56, 12, 74,109, 70,100,217, -240, 85, 24,171,153, 44, 69,113,113, 82,236, 53, 20, 4,149, 21, 41, 69, 5, 39, 41, 86, 6,179,123,118,157, 92,141, 29, 16,156, -183,161,203,117,169, 45, 41, 85, 8,181, 70, 27,109, 47,173,212,248,236, 71,106, 84, 99,132,175, 36, 36,133,242,100,225, 68, 4, -141, 58,241, 37,169, 36,181, 81,162,206,163,163,196, 75,109,173,245,177, 34, 3, 69, 39,152,189,239,177, 10,146,225, 89, 79,232, -208,128, 73,194,129, 72, 61,117,169, 79, 70,103, 39,152, 2,179,118,234, 61,230,215,211,210,196,129, 98, 64, 29,141,241, 79,103, -220,101,153, 30,114, 70,144, 85, 43, 2, 13,228, 73, 14,130, 64, 58, 33,230, 2,133,252,192,233,140, 21,185, 0,130, 72,108,110, -143, 14,191, 8,188, 39,209, 80,234, 30, 65,115,252, 6,171, 17,212, 71, 73, 7,149, 40, 68,198,155,113,192, 74, 65, 61,137, 39, -175,124,235,131,126,216,205,247,152,111,141,190,225,194,146,243,176,233,118,141, 10,155,186,215,228, 17, 33,165,138,133,245,119, - 54,244,107, 38, 20,208,210,212, 86,213, 50,201, 6, 83, 77, 44,254,130, 77,220,242,193, 10, 9, 34, 68, 98,167, 69,113,239,115, - 98,162,209,150,227,169,100,164, 50,250, 30,142,153, 10, 67,104, 47,161,113,185,149,250,217,193,234, 7,124,117, 58,132,167,180, - 11,114,157,191, 56,207,226,110,235, 91,220,193,123,191,119, 82,161,167, 35, 13,210,109, 57,205,218, 52,134, 80,174, 65,250, 54, -233,246,252,102,210, 48, 48,150,250,247, 58,147, 81,229,101, 16,136,212, 49,107,111,110,151,247,223,215,107,145,238, 29,206, 45, - 63,161,246, 88,153,247,139,149,156, 79,155,208, 8,233,184, 47, 46,150,174, 32,203, 38,147, 89, 80,241, 82,211,189,164,119, 95, - 36, 18,213,200,157, 74, 75, 28,114, 11, 50,130, 59,157,236,172,221, 24,215,231, 13, 23, 37,147, 81,118, 25,168,236,189,253, 46, -152,218, 93,144,151,101, 53,102,223,141,191,116, 91,190, 19,107, 28,209, 97, 71,172, 69,186,152, 65,253, 80,165, 4,167, 7, 26, -218,107,158,228,161,191, 61,218,125, 49, 94,245, 40,172, 37,210,202,148, 67, 42, 11,229, 81,117,224, 57, 60,114, 15, 92, 2,160, -149, 14,100,228,234, 49,124, 2,239,229, 79,110, 55,233,155, 77,234,234,233,116, 45,237,130,141,181,173,200,114, 66, 99, 70,106, -181, 46,104,159, 98, 79,117,194,147,225, 52,221,203, 17,152,171,112, 17,134,171,110,142, 96, 9,204,138,108,186, 50,226,248, 65, -230, 94, 18,210,234,138,218,116, 40, 56,144,201,253, 42,228, 2,144, 82,232,125, 39,155,155,185, 24,199,163, 70,113, 75, 61, 53, - 66,211, 24,192,102, 80,250,173,177, 4,158,128,236,109,107, 27,244,244, 55,216,120,245,195,212, 92, 51,226,119, 20,241, 60, 83, - 51,208,241, 68,223,164, 41, 96, 4,170, 44,179, 42,251,111, 53,134,197,189,176, 77, 41,141,108,170,146,160, 98, 5,181, 97, 28, - 75,220,181, 26, 38,200,211,104,247, 69, 74,235,183,182,170,177,190,251, 65, 11,117,110,107, 14,159, 10,179,117, 91,182, 75,207, -220, 78,183, 82,133, 14,168, 4, 79,171,216,186,153,183, 21, 41, 82,210, 98, 36, 41, 9,115, 46,170, 58, 78,196,185,236,244,224, -218,187,107, 59,115,220,156, 71,239,126,228,237,173, 2,138,187,170,107, 84,230, 45, 75, 86, 5,193, 65,109,135,229, 52,252, 91, -142,223,106, 82,213, 70,114, 67,192,198,106, 35, 40,154,243,242, 91,140,151, 91,112,244,112,233,245, 17, 14, 44,120,174, 52,203, -140, 76,104,179, 45,183, 16,135, 25,122, 52,130,142,120,210,155,117, 36, 60,203,137, 64, 5,181,165, 73, 88, 7, 57,232, 53,131, -111, 20,122,181,183,183, 23,101,181,105,248, 52,138, 5, 74, 76, 74,251,148,250,116, 97, 1, 16,222,167, 60,106, 47, 70,165, 53, - 21, 77,181, 6,159, 41,244,182,244,150, 67,100, 56,236,116,184, 10, 10,220, 42, 89, 95, 56,135, 46,142, 10, 39,138, 88, 81,180, -202, 38, 14, 74,164,134,226, 72,138, 50,168,146, 61,200, 73, 86, 72,223,161, 85,177,213, 91,112,255, 0,139,220, 97, 77, 6, 89, -195,156, 53,196, 21, 60, 22,207,152, 77, 60,242,208,138, 52, 21, 75, 82,148,144,150,121, 38,162,154,174,158,178, 4,129,185,117, - 52,245, 41,169, 36, 80, 81, 94, 4,118, 96,232,187,243,188, 52, 58, 53,183, 22,179,113, 84,169, 53,196, 81,160,251,245, 41,201, - 62,244,245, 37, 30, 24, 17,105,181, 9, 10,121,208,245, 77,152, 9,140,153, 37,110, 58,225,146,151,148,235,139,112, 41,106,217, -189,151,227, 46,253,131,118,219,180,250,252,122,125,201, 79,118,165, 17,114,150,164, 24,178,216,166,197,117, 15,212, 36, 41,109, -252, 46,145, 13,149,146, 84,156, 16,146,163,211, 58,229, 18,107,239, 62,242,147, 37,199, 31, 91,206,242,186,241,117,192,165, 58, -115,211, 39,155,149,210,121, 78, 15,117, 43,161,198,175,245,237,208,133,180,123, 77,185, 27,181, 83,195,175,211, 41, 12,109,245, -155, 17,197,165, 15, 85, 55, 47,117, 95, 93,149,109, 82, 48,149,164,169,198,162, 73,174, 84, 86, 89,234,134,109,247, 20,190, 92, -115, 20, 34,161,174,138,166, 35, 73, 52,177, 73, 35, 11, 42,177, 35,177,251, 38,224,129,110,227,176,216, 3,139, 63, 49,225,124, -159, 58,137,168,171, 50,122, 67, 83,155,200,176,199,104,150, 37, 89,170,228, 17, 68, 21,129,214,136, 36,145, 64, 37,137, 84, 80, - 88,147,124,113, 55,116,247, 70, 69,253,187,251,165,124,248,206, 6,183, 3,113, 47,219,205,230,124,103, 29,108, 53,115, 87, 43, - 21, 40,234, 47,172,146,232, 75, 18, 90, 9, 39, 39, 13, 39, 9,232, 14,172, 14,214,153,120, 48,183, 78, 92,152, 57,157, 10, 37, - 43,109,167, 26, 13,184,150,207, 80,131,206,176,172, 30,169, 9, 5, 24, 32,105,155,145, 77,159, 79,177, 55,214,248,122, 99,102, - 14,214,238, 37, 54,195,167, 33,244, 45,181,207,144,221, 5,213,204, 44, 21, 16,151,138, 88,241,164,244, 32,167,198, 64, 82, 64, - 41,200, 53, 27,141, 40,118,147, 76, 15, 45,169, 62, 12, 25,243, 2, 86, 20,234, 16,197, 62, 19, 65,165,164,117,229,247,167,138, - 73, 61, 22,177,202, 7, 66, 69,171, 7, 12,211, 48,141, 68, 97,196, 42, 34,118,176,243,125, 68, 82, 27,237,230, 26,101, 64, 77, -183, 59, 94,221,125, 38,200,188, 76,203,114,202, 54,165,142, 67, 20,116, 65, 22, 8,217,183, 68, 90,250,204,182, 21, 7,236,171, - 60,153,116,228, 2, 70,148, 58,202,134,186, 15,209, 95,217,213,187,149,126, 36, 56, 44,216,253,206,187,174, 26,157,110,227,126, -218,126,193,186,149,240,199, 84,155,163,109, 39,191,101, 84, 39,204,125,144, 23, 80,149, 50,149, 75,163, 76,121,231, 85,202,227, -245, 23,148, 15, 58,213,173,192,169,181, 57,184,233, 69, 62, 75, 17,217,117,148, 54, 25,157, 8, 41, 77,184, 20, 57, 18, 85, 21, -196, 40, 55,148, 36,167, 33,106,235,158,185, 26,226,103,176,146,232,171, 73,224,105,202, 90,107, 52,248, 49, 97,111,182,232,183, - 25,185,145,221,148,239,233,169,118, 36,151, 91, 74,223,144,136,236, 44, 74, 46, 41, 40,108,169, 68,173,101, 73,230, 86,187, 41, - 49,154,218,209,205, 42,173, 52, 52,180,165, 74, 68, 70, 98, 69,116,182, 9, 42, 83, 15,150, 84, 82,172,173, 43,228, 0,100, 3, -231,140,166,170, 86,154, 21,107,179,160, 10, 88,238,110,160,139,147,114, 77,254, 59,238,122,227,195,207, 25,248,114,151,135,188, -100,241, 27, 44,203,158, 10, 60,158,155, 59,204, 26,142,156, 69,166, 56,105,158,169,228,130, 24,163, 88,121, 65, 97,137,146, 53, - 32,147,100, 5,141,201,182, 5, 94, 69,230, 10, 94,145, 46,158,251, 79, 45,104,148,212, 6, 23, 14, 74,219,229, 12, 45,182, 36, - 58,225, 37,149, 97, 25,231, 83,121, 7,151,152,115,103, 88,171,145,168,116,244,134, 97,194,115,222,240,219,142,210,234,106,145, - 26, 99, 65,211,209,246,222,146, 74,159,116, 16, 64, 41,113, 93,130, 80,224, 61, 53,146,220, 18, 42,169, 71,189, 65,175, 23,224, - 43,196,110,100,138,180, 52, 73,141, 20,132,150,219,121,201, 49,146,211,140, 32,184, 66, 20, 84, 8, 65, 74, 73,198,117,138, 87, - 28,148,234,162, 34,187, 74,117,192,134,195,141, 85,221,124,204,165, 74, 66, 64, 8,106, 33,105, 1,113,212,225, 81, 86, 31, 66, - 49,205,221, 67, 11,214,189,142,171, 48,185,237,109,186,218,221,251, 94,219,220,117, 0,118,198,190, 89,205,228, 83,161,104,226, -136,234,212,180,224,194,199, 64, 4, 7,140,136,249,140,128,157,144,137, 21, 72,107,233, 54, 57, 45, 21,111, 50,239,128,212,167, -155,106, 99,237, 53, 50, 5, 82, 58,170,112,130, 22,133,248,114,226,201, 82, 20, 84,194, 84,162, 75, 79,133, 20,150,202,144,180, -144, 70,158,219, 70,151, 29,231,155,118, 60,104,204, 22, 63,193,222,142,151, 20,169, 10,146,203,194, 58,208,195,190, 63,232,220, - 83,255, 0, 26, 27, 64, 12,165, 9, 10,230, 9, 32,105,148,162, 91,141, 33,248, 83, 89,126, 99, 48,230,182, 20,180,198,150,244, -129, 79,113, 60,188,170,101,153,170,115,222, 32,173, 37, 93,149,240, 99,149,124,169, 9, 89,109,184,249,226, 98, 31, 5,220, 21, -239,191, 17, 15,200,136,155,150,213,178,166,210,246,246, 59, 73,141, 4, 86, 55, 54,239,228,181,236, 42, 83, 8, 90,185, 31,124, -220, 21, 40,178,202, 18,149,144,213, 45,220,101, 41, 86,157,232,209,181,169, 10,100,111, 40, 23, 59,177, 54,181,129, 23, 4,146, - 58, 1,212,220, 92, 98, 11,198,117,212,212,212,243, 58,213, 20, 77, 12,210, 54,146, 52,132, 30,109, 96, 29,244,170,155,187, 57, - 42, 0, 96,197, 77,204, 4,253,172,219,203, 47,139, 95,105,175, 18,183,101,176,204,138,245, 61,141,200,141,179, 22, 18, 41, 9, - 93, 86, 93,102,147,182,162, 46,222,210,152,166, 51, 24, 19, 62,108,219,142, 29, 80,176,134,211,151, 87, 57, 0, 2, 78, 76,168, -189,147, 30,205, 59,119,129,141,189,137,185,219,145, 71,167,212,120,177,191,168, 72,110,225,150,239,131, 57,157,155,182, 42,104, -109,241,183, 54,188,132,130,150,171,238,183,225,154,253, 69,162, 22,251,224,192,105, 98, 36,114, 29,230,127,176,159,128, 53, 76, -144,190, 60,247,198,152,229, 94,166,106,149, 39, 54, 34, 21,106, 58, 84, 43, 87,116,135,159, 77,209,188,211,162, 60,140, 58,227, - 18,159,150,197, 29,103, 9, 19, 37, 74,154,140,150,153, 34, 80,232,121,231, 86, 94,194,151,206, 84,165,229, 89, 83,132,156,149, -100,255, 0, 59,169,238,117, 52,214,174,144,192, 15,246,106, 75, 42,129,210, 73, 19,102,115,254, 20, 96,116, 95,171,221,172, 52, -163, 53, 11,192,252, 48,106,170,102,226,204,206, 29, 53, 57,147,188,180,145, 48,254,234, 41, 9,101,148,237, 96,238,166,209,126, -196, 86, 97,188,158, 91,213,199, 90, 49,104, 79,128,238, 30,144,121, 9, 61,192,192,201, 10,245,242,251,181,174, 71,196,148,241, -192, 74,219,247,143, 25,101,101, 88, 83,109,158,100, 32,143,231,159, 20,183,140,231,245,116,231,222,179, 3,236,178,194, 18,160, -158, 67,240,159,214,231, 63, 8,200,245,230, 7,246,107, 16,183,233,171,125,220,148, 41, 94, 26,193, 82, 72, 56, 30, 24, 42, 25, - 7,182, 93, 82,127,254,159,144,211, 69, 97,106,138,152,227, 83,176,254, 38,222,238,150,252, 15, 81,139, 78, 53, 68, 46, 72,176, - 83,107,124, 58,253,247,191,243,198,113,108,211, 19,227,169,194,215, 63,134,203, 99, 5, 93, 27,101,146, 22,246, 14, 62, 37, 45, -242, 7,255, 0, 71, 91, 55,104, 83,196, 88,200, 91,141, 21, 62,226,125,225,196,142,201,144,233, 1,182,178,161,208, 1,200, 7, -158, 18,112, 52,218,218, 20, 34, 11, 72, 82, 48,167, 29, 66, 86,162, 9, 37,168,227,198,115, 36,249,169,100, 15,158,126,122,216, - 74, 93, 56,165,176,160, 48, 80,160,230, 79, 96,234,193,228, 24,207, 80,150,250,245,243, 58,216,145,194,132,133, 59,122,123,247, -233,252, 61, 58,123,176,171,188,113,197,169,205,134,223,126,214, 23,251,250,216,250, 19,223, 23,184, 45, 45, 45,164,250,130,146, - 81,130,165, 58, 79,198,161,205,211,205, 71, 39, 29,135,217,171,242, 82,161,202,146, 14, 66, 64, 79, 92, 18,112, 18,132, 16, 7, - 82, 71,151,110,167,174, 79, 64,225, 49,204, 6, 74,148, 8,194, 60,151,142,203, 80, 0,244,206, 50, 62, 95,110,173, 87,197, 93, - 84, 74, 17, 76,101,242,212,170,171, 93, 62,154, 51,254, 77,126, 25, 50,166, 56,148,245, 8,102, 57, 81, 78, 59,184,180, 13, 2, -252,184,139,157,194,142,158,167,111,226,127,215, 17,237, 18, 87, 87, 69, 75, 8, 13, 45, 67,233, 30,130,251,146,127,194,160, 22, -111, 64, 9,233,134, 94,191, 60,214,174, 57,178,155, 80, 92, 88,138,250,178, 34,146, 73, 75,205,197, 89,247,133,181,215,245, 87, - 40,172, 41, 93,185, 91, 30, 93,117,113,101,178,148, 36, 20,167, 60,185, 33, 32,115,124,125,242,123, 32, 17,235,228, 58,103, 58, - 6,155, 5, 49,217, 1, 3, 41, 72, 72, 43, 80,202,251,124, 13,167, 57,231,230, 87,116,142,188,202,202,181,122,119,157,164,242, -182,128, 48,114, 74,210, 29, 82,148,174,231,149, 4, 14,112,122, 96,156, 36, 12,232, 82,130, 20, 22,181,207, 83,241,235,252,127, -134, 38,117,241,198,136,144, 66, 60,145, 40, 65,126,182, 80, 5,205,187,158,167,191,125,177,107,145,209, 56, 56, 42,192, 31, 7, - 50,136, 81, 39,245,114, 6,113,145,215,212,143, 62,186,109,183, 18,195,178,183, 58,203,185,118,235,114, 45, 74, 13,245, 98, 93, -244,185, 20,123,178,204,185,224,179, 84,161,215, 41,210,208, 90, 83, 50,227,188,143,209,202, 66, 15, 51, 50, 26, 45,202,140,234, - 80,244,119, 91, 90, 65, 46, 20,133,132,149, 18,121, 66, 82,146,158,167,227, 3, 9, 11,231,233,205,133, 28,116,233,240,231,231, -171, 4,167,130,146, 70,115,130, 7, 41,230, 1,190, 97,133,140,168,119,230, 25, 87, 47,167, 66,115,128,228,164, 50,233, 32, 21, - 35,161, 23, 7,226, 15, 81,234, 45,238,196, 78,170, 0,218,129, 93, 72,247, 12, 8, 22, 32,141,193, 7, 98, 10,220, 16,110, 45, -112,118,216,254,127, 62,215,111,101, 5,107,129, 75,173,157,208,218,223,173, 46,126, 22, 47,170,217,166,219, 21, 73,139,114,161, - 95,218,219,154, 98, 29,148,206,220,223, 83, 66, 63,194, 24, 91, 77,191,245, 45, 81, 88, 76,246, 99,150, 29,196,198,148, 28,226, - 11,202,192,207,250,185,206, 65,252, 7,207,183,227,175,213, 99,121,118,187,111,119,183,109,239,125,163,221, 75,114, 53,215,183, - 27,137, 66,147,110, 93,212, 9, 73, 66,132,168, 18, 70, 89,155, 1,197, 28,211,235,208,230, 33,137,116,249, 72, 41, 92,105,113, -154, 90, 84, 7, 50, 85,249,178,113,225,194, 13,235,193, 55, 17,215,238,197, 93,238,191, 80,167, 82,159, 69,111,111,238,242,201, -110, 45,251,182,117,197,186,245,165,117,196,233,203,239, 75,138,218,226,212, 26, 24, 84,122,141, 58, 75, 74, 74, 64, 71, 51,238, - 85, 86,192,138, 57,152,176,223,150,204,110, 72, 29, 81,137,234,203,216,159, 51, 46,237,118, 86, 99, 65,113,143, 12,174, 75, 50, -215, 81, 41, 25,101, 83,105, 43,215,145, 46,237,160, 27,127,116,226,230, 50,126,201, 86, 67, 97,203,213,166, 30, 57, 89, 86, 50, - 57, 63, 91, 35,175,110,154,250,115,156,144,122,249,254,255, 0,158,190,132, 99,161, 63, 14, 7, 46, 51,204,122,121,244,234,117, -245, 72,229, 29, 50,113,234,114, 6,127,226, 52,254, 46,118,196, 36, 11, 11,116,192,142, 40,231,160, 24, 29,207,175,231,166,135, - 82,137,238, 64,232,124,241,143,179, 68, 44, 19,211, 24,237,156, 99,160,245, 31,126, 52, 50,128,235,212,121,128, 78, 49,215,207, -246,105, 68, 59, 91,211, 6,181,253,109,251,240, 59,128, 1,240,171,174,122,121,121,246,207,159,246,104,101,244,200,243, 35,246, - 1,147,162, 21,140, 28,140,254,113,161,148,112, 8,235,215, 56,237,248,125,154, 85,112,176,189,136, 39, 3,168, 0, 15,145, 62, - 99,204,143, 35,249,242,208,203,229,235,235,211,242,126,225,162, 87,140,117,249,224,122,159,158,135, 88,233,231,247,118,251,254, -237, 44, 58,142,248,193,237,183, 67,243,247, 96, 69, 12, 31,183,175,217,165,175,171,198,113,140,126,255, 0,187,241,210,210,202, - 77,133,197,207,221,131, 99,202,112, 72, 7,242,117, 92, 15, 35,128, 60,190, 67,250,245, 69, 3, 39,236, 25,209, 40,239,246, 15, -207,219,164,143,175,174, 6, 42,164,124, 64, 14,131,166, 15,207,236,243,242,209, 35,215, 56,198, 62,220,124,191, 62,122,164,143, - 51,208,255, 0, 72,235,253, 31,213,170,160,100,227, 56,233,145,243,252,254,237, 17,175,109,186,223, 3, 4,160,140,231, 62, 93, -207, 79, 77, 22,130, 49,143, 63,233,251, 52, 26, 72, 30, 64,143,179,183,217,162, 1, 74,146, 72, 61, 65,252,115,142,159,159, 93, - 35,140, 48,184,235,108, 20,140, 18, 1,239,158,135,203,239,209,169, 7,166, 14, 79,145,253,186, 1,158,132, 17,149, 14,196, 19, -140,124,243,251,180,122, 72, 79, 76,145,211,160,233,147,164, 9, 36,220,225, 54, 29,199,206,216, 33, 4,224,142,153, 29, 85,219, -183,166,164, 73,236,110,220, 31,173,246,111,125,182,170, 68,175, 13,251,106,189, 68,191,169,177,199,196,183, 33, 84,227, 24, 21, - 2,134,250,229, 41,151, 17, 57, 35, 63,229, 6,117, 29,198,252,179,144,122, 1,230, 79,219,211, 93, 44,246, 85,110,228, 13,175, -226,214,210,164,215,229, 24,246,198,234,192,168,237,157, 95,227,228,108, 75,174, 32, 59,111,188,224, 39, 4, 38,172,195,104, 4, -246,247,157, 70,120,186,135,219,242, 26,232,130,234,146, 37,230, 46,215,221, 14,166,255, 0, 32, 97,247,226,198,240,131,136,227, -225, 95, 18, 56, 87, 54,157,180, 83,123, 64,167,148,237, 97, 29, 72, 48,220,223,107, 43,186, 57,255, 0,166,248,146, 36, 30,101, -188, 76,200, 92,160,148,190,196,228, 14, 82,218,114, 10, 92, 8,242, 87, 93,108,205,136,136, 94, 60,105,208,170, 83, 26,151, 9, -191, 29, 82,222, 74,157, 92,231, 64, 7,195, 90, 79, 64,192,244,244, 26,103, 63,131,149,104,117, 26,148, 68,184,195,109, 83,228, -173,134,209, 44, 2,226,202, 22, 82, 16,178, 79,234,114,242,159,179, 79,213,149, 33,113, 88, 77, 61,112, 27,121,229,248,106,149, - 58, 39, 41,101,148, 19,213, 63, 32, 79, 66, 62,237,115, 51,211,150,121, 6,155,219,175, 91,109,181,133,253,226,219,123,241,235, - 75,241, 11, 79, 76,188,137, 11, 48, 93,149, 89,118, 13,107,151, 89, 1,176, 11,212, 3, 98, 79, 75,219, 27, 67,183,181, 74,244, -214,231, 56,229, 74,158,135, 38, 41, 14, 18,160,166,156, 74, 16,156, 36, 32,118, 65, 62,159,191, 89,190,241,113, 11,110,112,191, -176,215,206,245, 95, 6, 20,202, 61,145, 74, 92,138,101, 45, 18,130,100, 92,247, 68,212,150, 40,116, 70,185,198, 84, 94,156,164, -120,132, 3,202,211,110, 40,118,198,137,219,165, 83,139, 76,133, 80, 28, 90,114,210,212,240,109, 10,241, 74, 15, 76,167,253, 94, -159,126,117,202, 47,164, 21, 92,174, 69,225,135,102, 32,209,169,178,160, 90,181,125,216,152,229,206,180, 71, 8,142,167,224, 81, - 11,148,102, 36,173,177,132,143, 17,201, 42, 66, 85,208,148,156,117, 26,113,203,168, 3, 58,157, 54,103, 33,125,118, 36, 94,196, -237,222,227,213,182,195, 70, 89, 79, 69,197, 92, 91,144,112,245,125, 61,168, 43,234, 1,157,252,177,147, 20, 49, 60,207, 26,149, - 58,245, 75, 28, 77, 18,149, 55, 93, 87, 27,139,227,130,123,191,198,175, 16, 27,247,184, 53, 45,208,191,119, 70,231, 85, 90,163, - 41,199,233,180,154, 61,106,117, 46,133,107,211, 84,247, 52, 26, 77, 22,153, 17,228, 34, 20,118, 27, 40, 72, 87, 47, 57, 41, 37, -106, 42, 36,235,167, 28, 15,251,109,119,107, 98,106,116,123, 7,136,169,179,119,107,102, 31,113,136, 72,172, 74, 90,101,223,214, - 83, 75, 33,180, 78,165,212, 93, 60,213,120,109,143,137,113,159, 82,138,146,217, 13,173, 11,198,163,142,186,235,108,188,164,169, -213,165,121, 56, 0,143,231, 19,148, 16, 58,242,145,159, 46,186, 6,109,204,220, 84,151,229, 73, 75, 76,165, 69, 13,186,181,124, - 13,149,252, 65,167, 20,122, 32, 43,175, 41, 61, 51,208, 28,156, 25, 60, 92, 63, 80, 37, 67, 1, 49, 19,208,129,189,141,182,255, - 0, 21,246,184, 55, 7,184, 56,236,142, 32,151,195,140,255, 0,133,223,133,248,147,134,104, 42, 50, 10, 88,196,113,162,172,112, -123, 24, 69,210,178, 83, 74,129,100,164,145, 7,247,111, 27, 39, 75, 54,164, 44,167,244, 98,220,125,244,218,109,207,181, 44, 93, -211,218,219,134,218,187, 42, 87, 53, 36, 51, 69,220, 10, 51, 17,100, 76, 69,191, 35,149,215, 40, 82,159,113, 5,234, 52,228, 57, -209,198, 86, 27,121,151, 16,161,243, 44, 38,219,240, 59,195,109,247,187, 50,119,219,118,236,200,251,153,118, 75,170, 65,173, 67, -182,174,118,154,153,103,210,171, 16,188, 32,197, 90, 69, 61,192, 77,102, 97, 83, 13, 41, 94, 54, 91, 36,117, 74,129, 58,135, 95, - 6,188,107,223,252, 45,110, 43, 52,233, 52,170,149,203, 96,222, 20,101,215, 83,103, 60,250,190,174,187,227,193, 5,199, 38, 91, -143, 44,148,196,174,178,208,123,149, 72,234,165, 37, 41, 87, 50, 84, 70,166, 95,193, 71, 19,251, 57,196,190,221, 82,183, 35,102, -111, 8,119, 37, 13,224,211, 21,170, 59,206,165,155,154,207,170,129,201, 34,143,114, 82,138,185,226,186,219,193, 72, 75,184,240, -221, 9,202, 85,215, 26,134,231,185, 70,123, 75,158, 38,105, 42,145, 71,202, 88,163,146, 50, 90, 29, 18, 16,197, 88, 92,133,119, -146, 38,219,245,140,108,190,102, 70, 11,198, 92, 75,194, 16,120, 95, 13,105,224,204,246,176, 46,111, 21, 85, 20,213, 74,239, 79, - 89,200,142, 74,121, 30,138,165, 99, 8,209,242, 82,106, 70, 89, 32,229,195, 52, 53, 48, 77, 24, 84,168, 68, 26,105,237, 7,217, - 19, 64,220,153,215, 20, 88,210,156,133, 88,145, 38,124, 79,119,101, 69,163, 18,166,128,243,109, 37, 40, 1, 44,161,169, 41,117, -174,100,245, 74, 25, 74, 0, 3, 3, 90, 51, 69,177,226,173,138, 60,234,204,122, 85, 38,221,129, 41, 51,103,211,161,176, 94,110, - 91,208,250,114, 84,204,148,115, 56,210,150,121,194, 65, 70, 22, 18, 73, 35, 82, 72,226, 42,210,160,110,117,160,197,162,168,115, - 29,188,213, 74,168, 86, 45, 9, 77, 65,126, 76, 10,156,120,126, 17,171,208,229, 78,105, 60,176,167,150, 84,151,226,161,194, 60, -101, 71,113,182,200, 89, 26,226, 82, 54,226, 82, 43,245, 56, 55, 19,146,165, 82,168,173,189, 53,234,122,121,219,167,174, 92, 53, - 21,161,215,162,173,172, 60,148, 33, 24, 82, 73, 88,113, 92,185,201,201, 27,117,108,244,241,194, 26, 80, 4,200,175,177, 5,212, -177, 33,144,129,246, 88,144, 74,234,211,113,184,242,225,135,128,248,146,174,159, 42,143, 44,172,115, 72,249,120, 15, 20,146, 35, - 63, 50,152, 72,218, 26, 20, 93,164,179,172,144,173,201, 8,234, 67,105,179, 12, 29,182,244,136,190,236,139,162, 43,211, 44,218, - 8,144,234,232,245, 56, 11, 17,235, 21,134,156,116,152, 20,134, 80,176,164, 56,209, 72, 43,143,200,135, 22,133,101, 74,113, 57, -214,238,237,187,251,130,203, 76, 67,151, 72,167, 84, 98,133,170, 91,213, 42,148,233, 12, 76,138,192, 82,148,219,210, 68,113,202, -170,138,219,193, 89, 73, 67,106, 72, 42, 40,200,248,181,222,133, 7,252, 38, 61, 94,168,236, 48,218, 34,198,106,222,121,215, 12, - 42, 5,177, 73, 72,109,202,131, 44, 54,165, 4,166,172,236,131,241, 5,128, 23,219,155,149, 1, 39,109, 54,169, 47,214,159,141, - 78, 48, 42, 53, 11, 73,106,126, 99,142,173,244,196,145,119,169,196,182,166,100,201, 84,167, 3,137,162,161,194, 72,100, 6,202, -154, 9, 82,143,134, 60, 50,195, 58,115, 25,121,138, 2, 2, 5,250,155,236, 2,134,216,220, 95,168,238, 13,133,186, 73,115,220, -216,213, 80, 74,207, 75, 13, 76, 72,128,234,144,106, 49, 40, 80,161, 99,149, 74, 52,149, 4,141,198,181, 87,112,116,142, 90,187, -151,130,212,169,221, 85,192, 81, 71,162, 69,143, 17,233,177, 66,234,213,121,210, 29,109,249,104, 83,136, 47,211, 99,197,142,149, - 42, 58, 27, 13,132,100,161, 42, 4, 36, 14,234,214,192, 82,168,207, 6,100, 72,146,243,115, 36,115, 37,223,120, 83, 66, 40,134, -150,151,200,182,225, 67,103,224,109,191, 19,152,143,214, 95, 97,205,166,202,221,175,203,122,100, 42,117, 14, 27, 48, 96, 45,217, -109,187, 93,144,132, 73,164,149, 65, 11,113,200,212, 8,170, 80, 21,149,224, 37, 41,120,242, 70, 10, 10, 9, 83,160, 99, 78, 43, -116,232,146, 18,162,237, 86,169, 54, 43, 79, 52,133, 63, 42,172,182,163, 42, 83,190, 32,120,165,166, 16,210, 27, 75, 65, 69,178, - 18,158, 64,162, 82, 50, 81,157,111, 81, 68, 21,129, 8, 22,227,101,189,237,123,109,114, 1,185,236,109,232, 47,107,226,137,226, -141, 77, 41, 30,203, 30, 87, 20,158, 96,168, 26,121,138, 19,111,172,118,118,179, 18,159,221,137, 20, 88,110,150, 85,193, 53, 73, -145,226,170, 46,101,196, 76,164,184, 28,240, 12,134,153, 95, 43, 10, 74,155, 46,181,207,144,121,194, 7, 62, 9, 82,143, 47,108, -234, 4, 62,210, 58, 72,219,158, 58,184,155,183, 37, 40,183, 29,237,225,189,234, 44, 58, 57,127,200,220,181, 35,117,198, 37, 8, - 56,229,118,159, 89, 74,128,242, 87, 67,131,157, 78,142,170,138, 83,209,158, 69, 30, 52, 6,160, 54,228,136,114, 46, 38, 99, 50, -181,206,146,133,248, 78, 67,166, 72,113, 37, 82, 16,149,149, 37,199,134, 91, 66,242, 26, 11, 88, 90,147, 16,207,164, 3,178,234, -161,113, 5,183,251,173, 73,167,134,104, 59,189, 97,210,168, 85, 9, 52,211,200,236, 43,223,109,162, 38,218,168,185, 41,231, 21, -137, 21, 23,168, 70,202,152,128, 87,226, 56, 92, 95,235,114,171, 51, 28,157, 98,150,190, 8,100,110, 92, 83,221, 79,199, 69,239, -185,177,177, 27, 15,128,189,142, 45, 63,163,127, 17,212,112,127, 20,113, 29, 53, 38,185,106,243,156,177,196, 81, 58,133,230,212, - 82, 85, 83, 84, 44,108,169,172,160, 52,166,171, 97,169,163, 3, 91,114,200, 24,226, 4,154,196,244,219,106,220, 88, 18, 36,123, -230,213,238,117, 58,151,184,116,120,110,184,212,168,118,117, 66, 76, 20,196,186,144,180, 43,157,136,145,234, 12,197, 91,146, 81, -132, 70,114, 83, 75, 43, 75,110,100, 74,151,217,207,198,213, 39,137, 54,238, 61,133,221, 10,180, 42,127, 21,123, 72,167,219,169, -193,146,168,241, 90,223,139, 2, 44,118,170, 52, 45,207,178, 66, 74, 81, 80,184, 88,183,166,211,141,199, 76,103,157,106, 33, 53, -232,129,216,210,102,162, 20, 59,161,215,121,234, 81, 43, 84, 91,170,177,103,222,204, 45,171, 98,241,138,155,114,161, 89, 69, 74, -148,180, 59, 78,143, 92,122,151, 17,151, 83,112, 82,132, 69,184,196,200,129,133, 59, 38, 25,125,133,176,243,141,180,149,244, 87, -132,222, 13,248,140,184, 47,203, 39,113,120,121,171,199,191,238, 93,185, 98, 53,251,111, 91,251, 99, 85,166,215,175, 87, 41,240, - 42,241,155,165,214,182,154, 47,191, 41, 91,145,104,211,234, 42, 83, 92,148,103, 83, 85,163,199,117, 84,250,197, 33,136,225, 97, -185,206,113,194,121,109,101, 27, 45,125, 80,163,171, 2, 95, 99, 38, 41,121,134,115,162, 78, 66,144,133, 38,141,138,205,202, 84, -102,150,120,231,139,150,134, 90,104,163,158, 75,196,249,142,105,226,180,212, 89,118, 93,165,163,138,170,138, 74,220,202, 74,236, -184,209, 80,208,200,239, 65, 46, 97, 87, 27,213, 71, 85, 72,252,182,203, 23, 53,133,225,134, 42, 12,195, 41,170,210,211, 69,154, -203, 85,150,205,166,227,165, 61, 6, 5, 54, 97, 74,156, 18,227, 69,110, 35,140,180,165,169,249, 82,156, 67, 13, 71,138,218, 85, -241,185,226,184,218, 91, 31, 9, 82,214, 50,122,244, 11,114,111, 27,114,131,182,251,199, 34,255, 0,136,154, 45,247,176,245, 58, - 22,218,111, 22,216,181, 81,143, 85,184, 45,221,195,188, 89,183,161, 89, 20, 42,100,159,117, 96, 92,148,187,141,187,194,223,118, -133, 84,102, 59,113,170, 72,126, 72,105, 41,114, 12,164, 55, 75, 99,119,122,224,174, 51,245, 7, 19,219, 89,112,112,215,186,220, - 60,220,144,175, 61,215, 77,193,108, 87,174,237,159,151,101,211,226, 77,189, 33,110,173,151, 93,162, 70,144,154,221,142, 81, 76, -164, 63, 80,165, 60,241,153, 77, 68,215, 72,114,100, 8,147, 31,135,146,113, 71,183, 59,103, 34, 92, 13,253,110,235,173,110,165, -205,184,176,173,202,147,143,193,221, 91, 86, 92, 45,209,191,156,186,104, 59,129,181, 86,205,199,245, 20,121, 48,102,109,181,175, -123,214, 32, 86,104, 82, 40,181, 28,208,209, 13, 52, 53,191, 38,135, 86,101,109,214, 19, 84,229,188, 53, 74,207,159,161,161,167, -175,150, 56, 86,121,140,113,211, 67,100, 55, 51,107,101,157, 73,146, 72,180,145, 11, 42,168,147,153,162,197,146,162,201, 56,112, -210,113,141, 46, 79,196, 20,245, 18, 53, 58,173, 84, 67, 46, 95,106,106,245, 73, 41,170, 2,208,207, 24, 52,245, 80, 86, 80, 37, - 72,165,150,158,114, 90,122,170, 9,135,212,151, 87,227, 20,104, 45, 87, 24, 85, 86,218,241, 42,148, 71,110, 43,170,211, 76,212, - 52,150,132,106,245,151,114, 85,109, 11,162,129, 84,104,168,251,149,106,157,112,209, 42,113,229, 48,188, 58,218,227,142,108, 33, - 77,169, 90, 21,237, 94,168,222, 22,133,223,195,254,202, 10, 93, 82, 93,177,180, 43,183,183,154,236,164, 81, 20,153,146, 98,238, -125,229, 73,129, 91,163,213,175,116, 52,191, 22, 53, 66, 29,188,253,173, 71,167, 81, 57, 76,150,133,213, 81,149, 33, 81,220,148, -211, 74,150,182,225,218, 92, 50,112,247,195,165,153, 77,165, 90,219,117, 99, 91,150, 60, 43,174,244,174,223, 49,109, 27,134,228, -218,202,205,255, 0,107,212,149, 18,116,251,243,114,104,207,201,168, 51,121, 72,220, 7,211, 38,169, 13,184,115,170,215,251,244, -217,244, 88,238, 70,155, 37,169, 49,121, 20,212, 93,185,118,222,225, 46,203,225,223, 98,183, 23,120,253,160,252,116, 84, 55,118, -117,213,191, 91,223, 72,247, 69,219,219,105,184, 23,221, 98, 20,254, 44,230,237,204, 42,236,138,109, 42, 84,217,212,251,153,118, - 17,144, 93, 52,138,101,143, 85,175,174, 58,252, 58,125, 67, 79,254, 28, 54, 93,153,214,174,113, 79, 20,121,133, 44, 97,185,112, - 9,150,105,100, 73, 41, 86, 94, 92, 38, 35, 21,167, 43, 81, 29, 57,169,144, 44, 20,142, 37,170,101,154, 49, 70,106,111,238, 14, -168,151,137,248,115,244,207, 19,210,215,101,116,144,212,140,186,131, 48,134,146, 36,164,139, 59,164,121,107,219, 53,204, 26,181, -229,163,139, 38,160,162,201,235, 36,205,169, 85,235,234,125,154,190, 36,140, 9,162,154, 90, 72,169,213, 45,253,208,118,151, 97, - 90, 91,181, 38, 13,167,103, 94,215,213,102,231,174, 55, 49,215, 31,172,238, 77,247, 17,216,119, 14,228, 45, 49,233,233, 9, 77, - 46, 21, 66, 69,159, 70, 41,134,135, 99,193,140,211, 84,180,200,231,102, 82,155, 18,155, 83,131,120, 85,111,219,154, 3, 50,105, -148,169, 19,160,193,160,214,170,113,194,103,214, 98,211,229,168,183, 62,159, 72, 66,178, 89,147, 84, 14,152,173,252, 45,248, 13, - 54,178, 84,149,147,169,133,123, 64,189,146, 86,255, 0, 13,187,109,182,187,145, 64,219,248,219,185, 14,215,178,234,116, 13,218, -222, 42,148,217, 2, 53, 42,184,204, 22,226,237,117,131, 14,206,132,240,114,194,225,222,157, 83, 53,138,149,106,161, 29, 14, 73, -171, 86, 42,171,153, 89,124,169,230,121, 34,177,182, 91, 65,116,111, 46,243,196,218,253,171,247,251,206,183,116,213,106,146,228, -110, 45, 77,182, 89,136,139,118, 28,148,197,186,119, 9, 54,243, 47, 6,109,107, 54,152,143, 26, 45, 38, 35,139,255, 0, 5,141, - 9, 78,190, 85, 41,232,140,170,115, 83, 86,212,245, 25,140, 21,212, 63,162,231,161,141, 36,125, 43,202,166, 45, 35,172,211, 73, - 10, 63,152,169, 40,176, 6,149,220,186,195,120,162,104,238, 34,191,184, 15, 62,224,252,219,132,178,206, 51,225,190, 45, 60, 75, -193,102,174,190, 55,168,174,180,249,164,116,185,109, 52,249, 86, 93, 75,153, 84,195, 32,246,103,141,107, 43,115,158, 82,101,249, - 74,150,205,227,150,183, 49,167,173,118,253, 35, 52,143, 98,189, 5, 54,159,179,243,109, 77,101, 98, 4,221,196,190,119, 71,112, - 90,102,181, 21, 8,139, 91,164,212,174, 88,182,196, 10,140, 85, 56, 18,219,240,220,254, 9,200, 41,115, 33, 74,231, 82,146,146, -218,155, 42,234,187,209, 27,163,184,237, 90, 72,168, 42,130,200,240,165, 64,143, 38, 82,158,160,173, 74, 13, 9, 84,182,157,124, - 46, 93, 57, 73, 90, 10,152, 73, 43,100,172, 41,160,180,115, 32, 49, 27, 9, 77,177,109, 93,139,217,139, 99,111,227, 72,143,183, -214,214,217,218,118,173,163, 6,173,153, 19, 88,131,108,210, 99,208,101, 65,174,135, 83,148,212,157,159, 79,150,244,181, 20,148, -123,204,229, 43,177, 57,114,208,124, 17, 57,202, 83, 14,170, 36, 5,137, 85, 10, 36,185, 75, 84, 55, 96,202, 71, 42,132,120,171, -113,106,241,219,116,146,219,173, 15, 11,186, 85,148,168,114,194,132,136,200,173, 31,158, 54, 80, 65, 3,168, 34,224,129,232, 65, -213,184,220,116, 23,199, 0,113,150,101, 55, 20,241,127, 20,113, 19,235,165, 25,245,125, 85, 67,198,196,108,179, 84,182,152,185, -133,129, 73,145, 89, 34, 14,220,203, 72, 8,103,229,150, 86,247, 81,110, 91, 49,167, 78,161,215, 37,212,219,113,213,165,218, 85, - 69,240,244, 26,132, 54,129, 11, 49,228,181, 29, 46, 66,168,140,245, 75,156,193,124,161,183, 27, 28,201, 86,190, 81,155,125,104, -135, 34, 12,114,220,121, 41, 40, 98,157, 53,228,170, 35,114, 20,230, 86,221, 26, 80,200,167, 40,169,103,158, 59,169, 8,202,112, -128,131,144, 60,211,163, 71,152,183,230, 83,229,191, 4,133,169,153, 76,134,179, 60,198, 89,109,232, 14,212,225, 62, 86,221, 65, - 13,185,148,165,196,101, 78, 32,243, 37,209,130, 19,153,208,146,134, 81, 41, 19, 11, 49,214, 86, 24,121,165,178,165, 69,168, 40, - 31,135, 1, 64,169, 46,149, 41, 36, 40,254,144, 5, 36,146,188,100, 38,134, 48, 25,152,141,172, 46, 77,136,220, 27,250,141,253, -222,226,122,130,193, 89, 80, 41,169,164,139, 72,146, 84, 43,112,200, 85,236, 84, 40, 87, 84, 1, 94,219, 21,144, 93,244,155, 22, - 69,101,209,125,183,168,209, 97,190,250,204, 70,152, 5, 64,200,140,166,150,203,176, 87,241,151, 94,136,160,178,134,218, 89,230, - 82,128,202,114,162,164,100, 2, 53, 28,111,107, 60, 59,251,143, 63,104, 23, 11,126,205,170, 3, 53,106, 46,201,109,173, 53, 27, -255, 0,189,117,166,249,216,137, 90,147, 49, 18,105,172,202, 66,146,174, 71, 98, 81, 45,102,106, 49, 24, 42,193, 53,155,189,229, -160, 5,197, 73,215,123, 47,141,211, 98,142,167,173,155, 89,193, 42,229, 25,106, 76,148,165, 47, 71,180, 91,112, 5,120,181, 23, - 14, 83, 34,182, 58,174, 44, 18,162,180, 43,149,249, 92,173,165, 40,113,184,160,218,118,243, 51,158,189,219,161, 64, 93,228,170, - 58,109,137, 55, 99,177,210,229,194,253,186,103, 61, 86, 93, 46, 69, 85,196,248,174,194, 85, 90, 68,169, 42, 65, 86, 20,243,235, - 89,234,113,167, 76,190, 73, 36,154, 36, 66, 2,174,204,196,216,168, 96, 86,235, 97,187,142,171,113,179, 0, 79, 96, 43, 78, 39, -200,167,207,168, 64,172,169, 48,195, 60,176,243, 35, 59,153,169,213,129,145, 9,184, 40,178,128, 35,189,201,120,217,238, 72, 33, -152, 74, 45,191,110,218, 20, 10, 5,159,104, 82,163, 80,109, 43, 50,145, 78,182,173,138, 20, 36, 37,152,116,202, 37, 38, 58, 33, - 65,136,219,104, 24, 24, 97,176,165, 43,186,214,165, 45, 89, 82,137,214, 66,192, 44, 56, 50, 64, 66,255, 0, 84,246, 74, 22,174, -188,167,230, 79,109,121, 92,114, 87,226,132,243, 5, 16,162,145,156, 45, 62, 69, 56,238,161,231,246,106,239, 2, 58, 29,109,109, -140, 45, 4,158,231,170, 65, 29, 58, 31, 49,251,181, 41, 93,150,200, 52, 42,216, 5,236,161, 64, 0, 1,233,167,107, 95,107, 15, -118, 6,132,133, 20,133,242, 45,129, 0, 88, 1,181,128, 29, 5,187, 14,150,219,160,198, 15, 92,140,185,115,138, 64, 42, 71,192, - 48, 51,148,245, 42, 81, 7,237,199,237,198,179, 75, 74,130,162,174,110, 64,124, 66, 48,124,213,215,155,149, 64,142,249, 35,240, -215,148, 83, 60, 73,124,161, 36,156,132,103,190,121, 71, 64,125,124,254,243,173,128,177,237,177,134,150,166,134, 7, 42,186,224, -143, 44, 12,121, 14,154, 67,202,160,201,111, 49,218,255, 0, 63,127,239,196,120,213, 0, 90,237,117,185, 55,251,239,238,249,252, - 47,182,197,185,224,181,226,148, 36, 57,202,148, 5,148,228,167,152, 5, 58, 79, 79, 76, 14,157,180,226, 8,126,236,203,104,229, - 60,234, 39, 41, 0,168,144,160, 20,178, 64, 31,173,203,129,242,206,178,138, 93, 27,145,148, 5, 35,225, 35, 39, 61,212, 7,196, - 78, 60,251, 1,143, 61,123,145, 19,153, 69, 69, 4, 41,106, 8, 66, 83,212,227, 32, 37, 32,103,190, 59,159, 85,124,134,144,177, -221,137,249,239,127,225,134,106,140,228, 77, 49,141, 79,213,198,127,211,243, 54,237,139, 84,118, 89,109, 14, 61, 41,212, 70,139, - 13,135, 37,204,148,176, 18,212,104,172, 36,184,227,206, 40,246,108, 37, 56,249,146, 7,158,181,250,179, 86,126,239,172,200,171, -165,165, 49, 78,105, 40,133, 70,101,239,129, 48, 41,109,171,225, 88, 0,126,146, 83,234,203,139, 61, 57, 66,130,124,177,167, 30, -243,170, 10,151, 53,173, 13,126, 37, 62, 51,173,185, 94,117, 25,228,155, 49,165, 7, 24,164,151, 19,254, 82, 35, 74, 8, 47, 36, -116, 83,129, 32,146, 1, 26,196,209, 13,152,192,120,189, 72, 36,248,109,160, 56, 2,128, 5, 63,163, 79, 92,103, 3, 39,160,236, - 58,233, 61, 70,161,194,166,241, 70,119, 63,180,195,227,217,127, 22,248, 41,196,175,135,160, 90, 56,228,204, 39, 66,107,106,150, -209, 41, 6,241,194,108, 75, 91, 99,174, 91, 3,191,217,140, 1,191, 54, 69,192, 76, 50, 27,111, 13, 54, 73, 64, 9, 75,139, 82, -155, 0, 43,169, 44,128, 9, 62, 93, 64,193, 61,206,129,152, 95, 41, 82,138,208, 22, 65, 72, 12,164, 32,165, 0, 36,148,163,152, -144,217,234,147,145,223, 36,228, 96, 13, 93,159, 83,174,103,149, 32, 40,182,126, 55, 51,206,132,145,201,240,161, 7, 35, 62, 99, - 32,129,158,249,214, 55, 45,212, 37, 96, 41, 41,120,167,152, 0,148, 0,129,149,167, 39,148,225, 32,224,247, 61, 71,166,116,224, -158, 91,109,185, 27,219,231,253,127,117,240,237, 35,179,146, 77,153,143,253,199,183,115,176,223,225,139, 75,238,163,147,144, 21, - 40, 96,142,116,142,164,165, 71,170,222, 82,187, 31,136, 4,140,243, 1,229,215, 88,252,183, 65, 72, 11, 82, 74,126, 16, 8, 28, -184, 82, 72, 9, 66, 86,188, 18, 18,124,176, 62,100,224,157, 92, 39, 56,224, 82,146, 23,204,162,174, 95, 9, 9, 79, 55, 83,240, - 40,169, 64,252, 33, 36,252, 92,160,245,192,214, 45, 49,208,142,112, 21,241,171,170, 65, 78, 85,128, 50, 82, 74,129,229, 60,160, -143,187,169,234, 53,176,135,175,112, 15,243, 31,187,175,201,195, 45, 82, 13,247,235,252, 62,255, 0,187,182,253,175,139, 84,247, - 82,160,163,130, 9, 39, 36,167,159,175,196, 10,138, 66,176, 19,215,191,145, 57, 25,215, 6, 61,188, 92, 35, 69,226, 19,132,201, - 91,199,110, 82,195,187,161,195, 10,102, 93,241, 28,140,192,126,125,115,105,170, 47, 48,214,226,219,142,184,128, 86,242, 33, 44, -195,173,196, 64,207, 34,224, 76,242,116,235,186,178,222, 24, 37, 41, 81,237,144, 82,160, 20, 48, 84, 0, 3,162,199, 82, 58,245, - 31,127, 70,250,191, 79,164,215, 96, 84, 40, 85,216,173, 79,160,215, 96, 84, 40, 53,232, 14,182,151, 35,203,161,214, 98, 61, 73, -173, 66,121,165,116,117,135,105,115,166, 54, 71,126, 85,224, 28,246,216, 14,203,105, 35, 63, 89, 25, 12,191, 17, 98, 47,238, 61, - 15,184,145,176, 59,197,243, 92,186, 44,214,138,175, 46,156,218, 42,180, 41,114, 7,145,137, 5, 36,183,172,110, 22, 65,210,229, -109,238,199,229,128, 82, 2,137,239,143, 49,212, 31,152,199,126,154,248,172,145,219,166, 51,147,251,191, 13, 61,188, 74,237, 67, -251, 7,196, 22,245,108,212,198, 21, 21, 91,103,185, 87,117,161, 21,133,168,173, 72,164, 83, 42,242, 5, 1, 65, 71,170,194,232, - 46, 83, 92, 10,235,144,230,114,115,146,198,169,106, 88, 4, 43,155,166, 71, 76,119,245, 30,186,153,211,202,179,197, 12,202,124, -178,168, 97,235, 98, 1,254,120,230,119,142, 72,157,226,149,116, 75, 17, 42,227,209,212,233,101,251,152, 17,138, 46, 16, 70, 51, -235,156, 28, 99,251,116, 42,177,142,195,148,103, 30,125,187,147,243,213,117,168, 30,224, 12,142,248,206, 79,217,161, 87,208, 31, - 60,156,126,255, 0,221,173,192, 44, 0,244,192, 29,190, 56, 29, 89,193,233,255, 0, 14,253, 52, 34,142,113,223,207,184, 3,240, -209,107,237,223, 29, 71,231,243,233,161,156, 32, 2, 51,147,231,142,191, 62,154, 85, 7,124, 42, 44,119,192,171, 35,203, 63,126, -113,231,228,117, 69,125,179,147,255, 0, 31, 93, 87, 95, 55,158, 49,229,249,245,208,235,199,207, 62, 94,159,126,149, 2,228, 99, - 29, 0, 3,231,255, 0, 24, 21,103,175,216, 49,159, 93, 45, 37,254,183,221,211, 75, 74,139,128, 0, 31,142, 13,143,168,198, 79, -124,227,238,199, 79,219,162,145,140,118,235,230,113,251,254,205, 8,223, 83,147,145,208,244,251,241,215, 69, 35,177,235,231,219, -247,232,141,107, 47,108, 12, 18,142,199,167,223,235,249,253,250,169,158,221,250,124,254,126, 94,154,164,140,245,233,211,215,247, -124,245,237, 36, 40,144, 15, 99,131,223,161,210, 78, 54,248, 96, 99,223,140,142,249, 24, 0,103, 25,202, 78,139,108,149,129,212, - 0,124,241,215,168,233,211,239,253,154, 16,180, 1, 56, 0, 36,228,159, 79, 44,147,243,254,189, 86,109, 65, 36, 14,184,198, 2, -143,203,212,253,218, 64,155,117,192,193,237, 39,151, 3,175, 66,123,119, 63, 63,144,209, 8, 95, 51,137, 73, 78, 57,115,241, 30, -221, 60,178,126,122, 8, 60,140,148,130, 85,216,224,117, 87,159,124,253,167,240,209, 63, 11,137,248,186, 28,252, 35,168,207,219, -248,233, 22,234,113,131,235,243,233,139,187, 64, 43,162,136, 63, 49,147,235,233,247,106,247, 70,169,212,104, 85, 90,117,110,145, - 41,200, 53, 90, 68,248,117, 58, 92,198,148, 80,236, 90,141, 62, 75, 82,225, 74,109, 67,170, 84,137, 44,180,175,184,141, 88,152, - 10,229, 79, 96, 48, 57,177,219, 35,167, 79,219,162,211,156, 40,118, 30, 71,184,249,245,242,233,162,144, 24, 21, 97,112,118, 32, -239,132, 15,196,169, 30,155, 16, 71,112, 71, 67,137,193,240,233,185, 20, 62, 44,120,124,219, 61,240,167, 76, 71,191, 84,105,140, - 81, 55, 14,155, 5, 64, 73,165,223,148, 54,155,135, 89,139, 53, 8, 57,103,197,121,191, 25, 25,253,100, 72, 65, 4,131,173,161, -180,210,245, 40,183, 10, 44, 52,248, 14,171,153,247, 36, 40,150,208,211,100, 16,181,171,201, 93, 7, 79, 83,168,161,123, 40,248, -226,137,194,214,237,191, 97,110, 76,199, 6,196,111, 20,202,117, 42,239,113,106, 82,155,179,174, 82, 83, 18,135,123,178,146,127, - 69, 25, 42,113, 12, 78,199,254, 43,149,211,158, 67,169,140, 46,220,104,182,207,128,184,210,104, 79,178,197, 70,159, 80,128,226, - 36, 70,171, 65,146,132,189, 18, 92,121, 77,168,165,248,174, 52,182,212, 10, 73, 7,155, 84, 39, 16,240,233,203,115, 25, 99, 88, -201,130, 67,170, 35,216,169, 61, 47,220,173,244,155,247,243, 17,102, 24,239,143, 11, 60, 80,110, 39,225,218, 88,107,103, 15,152, -229,170,144,213, 33, 98, 60,234, 0, 89,236, 55, 34,117, 93, 98,219,115, 3,198, 8,209,135, 82,196,175,212,218,113,133,198, 84, -117, 38, 71, 32, 67, 78,101, 4,182,142,157, 7,255, 0, 22,125,124,255, 0, 13,121,226,147, 97,169,220,100,236, 45,251,195,253, -214, 96, 83, 89,184, 96, 55, 58,221,184,156, 71,138, 45,139,210,151,207, 34,220,169,161, 93,196,113, 36,248, 82,113,221,137, 11, -244,198,172,116, 62,102,100,181, 29,160, 61,231,149, 60,142, 99,224,101,164,246, 3, 29,128, 25,233,173,128,164, 74, 18, 99,198, - 73,116,183, 25,181,114, 60,178, 57, 76,151, 16, 50,162,162, 14,124, 60,129,246,235, 82,158, 2,165,118,210,203, 98, 45,216,245, -190,219, 94,253, 7,223,139, 66,108,214,122, 57,232,179, 76,177, 18,150,182,141,214,104,102,243, 49, 73, 35, 33,209,244,220,171, -217,133,180,176,210,230,225,188,151,199,230,211,196, 86,208,238, 55, 15,155,153,121,237, 22,231, 81,100,219,215,221,143, 82,149, - 79,168, 71,125,106,110, 52,230, 88, 90,132,122,157, 46,106,128, 76,202,124,136,220,143, 71,121, 63, 11,141,186,146, 8, 36,141, -107, 90,238,137,210, 99,242, 84,194, 39,208,228,243, 69,156,165,101, 50, 16,209, 35,156,184, 17,212, 56,158,138, 66,198, 72,229, - 26,253, 19,125,160,126,206, 29,169,246,133, 88,112,226,214,219,129,100,111, 5,191, 18, 68, 91, 19,116,219,132, 28,148,220, 38, -208,181, 53, 65,186, 99,180, 66,170,182,233,119, 30, 25, 39,198,138, 86,165, 50,121, 74,144, 97, 29,196,223,179,219,138,238, 14, -171, 85, 42, 30,238,109, 69,202,253,158,137,146, 26,165, 95,150,229, 61,202,229,149, 91,134,219,133, 41,155, 18,173, 13,165, 6, - 91, 82, 48,172, 57,202,180,231, 5, 26,179,178, 42,250, 57,225, 72,106,149, 86,169, 74,233, 44,116,220, 29,175, 27,118,123,216, -133,216,130, 59,142,146,250,158, 42,173,226,215, 74,204,190,189,178,218,167,133,214,182,141,111, 32, 18,142,242, 68,219, 84,208, -202,162, 69,119,250,199, 68, 58, 38, 17,181,158, 86, 98,205, 98,245,184,155,179,246,190,133,117, 81, 43,212, 69,205, 93,107,111, -171,201,247,180,220, 22,125, 75,170,221,143, 77,172, 67, 70, 41, 51,212, 66,147,225, 62,180,195,146,121,152,117, 41, 82,145,153, - 39,123, 14, 56,116,186,118,163,136, 57,119,139, 91,231,181, 82,105,117, 56,211, 85,187, 59, 81, 50,174,154, 46,225, 86, 41,142, -178,236, 71, 96, 81, 44, 39,154, 15, 79,169,138,138,154,146,169,140,169,198,154,240,202,146,121, 8,214,156,123, 19,246,162,147, -184,219,245,181,214,173, 74,157,114, 91,212, 68, 94,177, 46, 9, 87,209,164, 82, 35,166,152,213, 40, 26,147,148,152, 53,249, 12, -182,135,161, 77, 92,118,163,188,212,150,221, 87, 43,171, 72, 10, 95, 41,212,194,248,217,224, 59, 96,239,203,211,110,184,157,163, -220,219,119,195,142,224,236,189, 90, 53,199,112,238,141,180,213, 54,131, 86,184,173, 90, 80,241,158,162,204,105,137, 44, 68,247, -146,216,120, 38, 83,136, 82,185, 95, 91,106, 14, 36,132,105, 42,177, 85, 95, 69,196, 84,180,235, 13, 45, 13, 59, 8,229, 63, 84, -100,153,228, 44,254,209,101,229, 8,180, 29, 45, 34, 57,120,102, 98,238, 84, 54,248,177,115, 46, 32,224,110, 24,171,225,142, 26, -226,122,217,198,119,199, 25, 21, 76,116,245,242, 71, 93, 93, 67,144, 67, 83, 72,217,122,208,154, 38,146,170, 74,254,122,137, 97, -203,171, 80,123,126, 86, 13, 50,114,230,134, 52, 43,104,160,110, 52,106,229, 82,239,218, 10,165,197, 42,143, 92,155,112, 63, 79, -182,109,170,172, 86, 42, 53, 42,212, 72,110,166, 83, 17, 83, 38, 18,137,166,133, 50,164,172, 60, 85,240,145,228,123, 92,248,153, -225, 90,117,139, 14,223,186,217,144,212,184,247, 13, 37,217,245,234, 50, 30, 68,154,188, 47,118, 5,245,153, 13, 36, 5, 84,225, -248, 64, 45,114, 16,133, 4,120, 5,183,210,145,135, 23,170, 17,120,166,246,122,210,239, 8,251,245, 73,221, 42,108,202,125, 54, - 85,110, 12,136,116, 25,110, 42,164,252,181,186,183, 36, 84,100, 71,157,200,243,176,212,251, 97, 40,154,128, 27, 80, 87, 42, 0, - 73,215, 28,248,248,246,138,238,223, 31, 27,209,100, 13,189,190,175, 61,174,217, 13,133,184,168,247,110,220, 46,215,168, 72,182, - 43, 50,175, 26, 23,136,134,174, 58,133, 66, 41, 14,213, 96, 61,144,143,113,148, 85, 17,198,121,155,117,149,165, 68, 30, 78,240, -151, 41,171,203,168,248,214,139,140,242,218,147, 61, 39, 46,146,154,176, 74, 94, 58,115, 70,238,237,110,102,210,194,237, 49, 74, -101,167,176,152,106,242, 71,253,233, 17,120, 7,226,111,137,188, 85,195,180,126, 29,112,252,188, 55,150, 71, 72,245, 89,147,103, -144, 54, 91, 11,230, 13, 18, 65,236,212,236,144, 84, 78,202,220,184,170, 37,144,199, 57,137, 21,156, 76,199,149, 3,245, 94,101, -153, 14, 91, 11,118,106, 60, 38, 42, 50, 98,248, 52,232,255, 0,224, 76,210,169,176,210, 23, 58, 67, 75, 75,170,196,215, 65, 90, - 66,200, 82,134, 70, 57,121,122,190,116, 74, 93, 58,224,113, 52,104,137,117, 22,180, 38, 41,236, 84,166,201,117,250,127,189,196, -138,202,165, 63, 77,135, 61,213, 5, 70,128,166,194, 12,199, 18,144,165,140,160, 16,130,179,166,155,101, 55,170,133,187,214,166, -214,220, 55, 67, 20, 74, 22,231,223,150, 76, 91,182, 85,181, 1,133, 66,160,215,231,197,159, 82,164,204,170, 90, 80,221, 39,244, - 42,118,154,185, 47,211,155, 89,114, 42,164,175,221,144,228, 84, 39,195,216, 74,124, 72,107, 67,204, 60,133,205, 66,221, 76,153, -140,248,200,105, 21,106,162,212,144,195,107,125, 39,244,116,228, 20,254,149, 32,124, 73, 74, 16, 82,160,149, 5, 73,200, 40,225, - 8, 33,133,138,157,182, 82, 3, 95, 73,181,137,216,116,212, 13,238,110, 49, 90,230,167, 55,225,188,207, 50,225,188,237,100,164, -205,114, 10,186,138,102, 10, 67, 66,181, 20,181, 15, 75, 52,145, 56, 33,102, 11, 36, 14,177,206, 9, 14, 84, 59, 29,188,174, 84, - 59,173,112, 93,143, 85,131, 21,160,229,114, 44, 58, 45,153, 66, 12, 7, 27,139, 74, 91,136,101,170,139,205, 35,148, 83,216, 89, -109, 47,175,160, 45,198, 97,150, 17,149, 40,129,153,191, 33,138, 45, 46, 76, 10,157, 73, 53,234,220,249, 45, 83,233,211, 28,109, - 44, 82,226, 34,114,131, 18, 43, 40,129, 31,153, 48, 97, 70, 47, 36,186,181,120,174, 58,242, 82,209, 95, 50,212, 18,208, 73, 83, - 80, 80,204,199,127,194, 85, 21,242, 79,187, 56,168,170,169,212,221,108, 50, 91,138,234,193,240,227,178,130, 24,101, 57,229,108, - 41, 75, 86, 74, 20, 9,139,172, 74,165, 58,245,126,172,220, 89,142, 26,131,177,226,196,130, 86,202, 30,125,154,122,189,198,155, - 17,167, 0, 8,166,198,149,239, 78, 60,238, 79,139,135, 31, 80, 75,139, 70,183,210, 72,208, 37,152, 14,131,107,157,246,216,129, -183, 77,134,221,141,183, 54,195, 12,185,100, 85,145,194,212,139,125, 68,121, 69,150, 73, 36, 70, 28,168,213,141,221, 80, 38,242, -239,121, 25,155,153,118, 55,137,194,174, 84, 41,148, 85,183, 64,162,120, 21, 9, 84,184, 49,145, 29, 46, 45, 79, 64,165, 64,110, - 50,132,154,165, 69,214,148, 82,194,220, 74,138,147, 28,101,231,150,232,192, 66, 9, 86,185, 17,237, 36,216, 24,156, 79,108, 45, - 91,106,157,145, 17,119,146,170, 52,251,163,110,235,115,214,150, 35,192,191,179, 38, 60, 55, 42, 47,160, 19, 2,219,168,211, 29, -118,157, 56,164, 20, 50,202,227,203, 3,158, 10, 73,232,220,233,143,193,167,180,203, 82, 67,210, 37,192,145, 88,170, 20, 52,150, -230, 54,253, 90,120,113, 41,119,149, 69, 38,115,235, 1, 12,182, 7,193, 25, 9, 82,185,130, 82,117,175,119,139, 85,218,217,157, -245,121, 66, 42,143,213, 32,176,154,170,185, 28,143, 69, 75, 2,115,178,106, 74,141,250,175, 22, 25,108,248, 12, 35, 8, 91,142, - 54,181,252, 5,122, 88,213,203, 28,145, 75, 78,229, 37,167, 97, 34,183,236,148, 33,148,223, 96, 69,197,183,176, 63,102,214,216, - 58,240,190, 68,114,250,243,152, 23, 19,199, 8,114,242, 72, 72,231, 22,188,108,205,176,101,137,213,157,138,160, 37,149,131,121, -245, 2, 96,171,183, 20,137,123, 31,191,149, 91, 47,123,232, 85, 27, 62, 93, 6,181, 34,220,190,237,155,214,132,186,220, 88,179, -217,150,220, 71,128,149, 75,125,138,149,169, 90, 75,203, 96,211,110, 42, 91,143,176,165,184,194,229,195,126, 59,201,121, 83,127, -216,175,102,198,192,241,189,192, 78,211, 93,151,173, 66,131, 11,121,110, 27,122,109, 78,202,226,103,134,152,244,170, 29,255, 0, -106, 75, 77, 80,127, 7,147,118,200,183,170, 81,169, 27,137,124, 65,102, 20, 38,171, 53, 4, 24,110,205,241, 18,226,164,123,227, - 13,202,211, 37,186,124, 33,108, 79, 16, 66,211,103,113,182,182,139,118, 84,173, 7,156,166,216,183, 99,192, 67,187, 32,202, 95, - 52,202,236,231,238, 88,201, 46,213,173,214,193, 83,203,133, 49, 50, 99,173,245,243, 52,203, 11,115,159, 93, 2,225, 42,126,233, -240,185,105, 84,108, 74, 45, 95,108, 43, 59, 35, 69, 97,250,141, 10,138,230,217, 90,251, 48,139, 9,233, 47,173, 83,167, 92, 23, -133,177, 85, 69, 46,182,212,244, 48,183, 86,228,216,112,223, 43,138, 95,241, 29,230,228, 19,170, 78, 41,201,115, 12,218,154,183, - 54,203,228, 66,244,207, 79, 57, 83,174, 48,118,211, 36,113,139, 51,236,182,144,200,197,209, 89, 4, 74, 66, 18,100,220, 71,196, - 25,253, 47,135,176,101, 60, 41,197, 99, 32,207,114, 92,228,102, 52,138,194,116,168,154, 25, 34,146, 41,169,214,165, 68,180,176, -199, 36,210, 6,122, 3, 28, 20,213, 45, 28,143, 83, 37, 84,238, 34,143, 74,120, 89,225,111,121,247,111,121,238, 89,155,225,184, -220, 82,237,142,251,112,146,253, 17,207,229,239, 14,200,188, 40,150,199, 16, 91, 53,100,203,106,223,161,219, 59,177,105,238, 28, - 8,141,191,184, 84,122,123,188,237, 86, 66, 93,102,187, 65,135, 61,155,146,157, 54, 68,117, 85,170, 29, 5,246,132,237, 76,171, - 94,215,181, 54,235,103,182,227, 99,237,219, 50,147,100,221,151,117,186,253, 38,155, 38,143,114, 90, 87, 4,106,212, 53,220,242, -118,242,194,180,160,179, 75,166, 81, 39, 84,235,112, 68,217,140, 61,226, 50,212,247, 22, 89,118, 35, 77,235, 83,184,202,246,199, -112,111, 70,219,122,181, 6,171,108, 65,226,231,125,105,213,122,204, 75, 11,108,236, 27,130,252,141,176,118,155, 98, 2, 33,193, -175,238,213,251, 13, 81, 98,223, 52,197,206, 75,206,187, 71,165, 38,170,196,168,241,155,138, 85, 9,111, 46, 98, 52, 47,111,189, -188,183, 37,209,109, 10,103, 17, 22, 2,110,109,194,146,227,138,131,118,219,246,163,116, 11, 98,132,235,103, 52,122, 75,118,253, -157, 38, 77, 80, 90, 17,210,101,178,248,116,206,118, 75, 83,212, 28,101,175, 1,149,162, 45,226,190, 70,185,231, 0,203,149,228, -121,123,231,153,198,105, 91, 28,230, 88, 16, 36,112,211, 70,154,212, 24, 39,149,165, 18, 74,198, 72, 89, 35,105,100, 12, 41,231, -158,112, 57,145,137,231, 10,100, 94, 51,241, 87, 23,112,111, 30,211,112, 52,153, 38, 73,225,242, 10, 90,124,155, 50,146, 42,116, - 99, 45, 52,112,243,178,218,153, 12, 21, 85, 52,171, 42,205, 88,212,181,201, 75,149,209, 37, 91, 81,100,148, 51, 81, 75, 49, 50, - 6,217,173,183,155,188, 84,118,173,158, 32,172,235, 87,118, 54,166,179,183,149,203,134,222,225,242, 30,215, 80,233, 54,151,241, -165,100,213,106,245,122,156,138,221,227, 2,160,150, 46, 42,164,235,130,161, 57, 86,251,132, 51, 77,169, 64,173,174,167, 38, 59, - 85, 4, 56, 26, 3,109,118,123,135, 41,252, 96,110,135, 23,245,109,254,221,189,165,168,219,173, 91,123, 97, 87,216,251,190,175, -183,219, 85, 99,219,212,155,126,209,183,217,137,183, 10,131, 66,169, 76,169,205,176,225, 70,165,194, 83,180,116,125, 88,219,175, -148,178,243,175,199, 75,173, 59, 29, 61,249,246,206,238, 94,228,237, 61,211,181,155,117, 97, 50,205, 62,247,110,151, 14,183,114, - 57, 71,149,102, 55,111,211, 40,145,161,125, 74,213, 25, 54,141,222,227,180,202,188,130,169, 82, 23, 30,151, 57,136, 16,218, 83, -108, 72, 50, 38, 25, 64,114, 67,110, 47,253,229,176,174, 10,205,199,103,238,253,237, 99, 85,238,119,154,122,231,157, 75,174,215, - 74,238, 7, 25, 46,152,207,214,220,157, 58, 73,170, 74,109, 18, 30, 75,110,190, 29,121,180, 44,165, 42, 9,232, 21,240,162,151, - 56,225, 46, 16,143, 36,205,178, 88,214,186,130,176,206,181, 50,212,206, 37,168,141, 97,228, 37, 63, 46, 9,201, 90, 37, 96,103, -142, 25,155, 74,243, 26,157, 97,150, 33,237, 83,203,114,127,162,199,141,220, 86,188, 75, 85,151,241,125, 31, 2,167, 23,193, 83, -150, 54, 91, 79, 78,166,152,101, 85,109, 75, 81, 85, 61, 59, 60, 98,150,158,166,174,122, 58, 72, 42,106,150,136,102, 51,123, 10, - 85,205,152, 73, 43, 44, 16,206,123,218, 61,196,127, 12, 59,235,177, 53, 46, 29,169, 86,189, 55,136,234,109,215, 88,166, 26,197, - 38, 53,233,116,109,198,223, 91,198,222, 80,171,209,234,119, 5,221, 67,164, 25,151, 10, 5, 85,136, 33,154, 93, 49, 37, 18, 15, -233,100,202, 97,150,139,131,132,251, 87,179,251, 79,179,194,224,147,101,216,244,202, 5, 90,229,159, 17,119,149,211, 72,110, 69, - 46,248,110,163, 29,217, 43,129, 66,171, 79,122,116,167, 35, 90, 76, 72,147, 37,216,236, 37,215, 98,203,117,126,245, 45, 50,100, -114,186,222,133,219, 60, 77,113, 16,220,102, 29,123,136, 11,214,170, 86,194,217,230,148,229, 46, 98, 20,211,128,115, 50,125,254, -146,190,100,228,116,200, 4, 30,163, 7,187,151, 72,226,234,249,165, 72,105,119,173, 54,145,119,199, 91,105,138, 42,209,169,240, -173,203,214, 44,100,188,211,178, 16,205,110,152,208,135,112, 48,176,215,197, 10,171, 13,109,124, 69,109,200, 97, 95, 24,214,226, -126, 46,204,248,131, 53,169,253, 34,207, 26, 53,144, 71, 4, 79, 21, 56, 17,133, 22,229,150,231, 57, 26, 1, 47, 34,187, 2, 44, - 52,198,170,139, 50,202,126,130,126, 47,120,111,192,109,194,252, 57,154,229,220, 65,148, 9,205,116,180,137,154,214, 10,186,170, -162, 10,137,109, 91, 69, 71,150,198,235, 25, 10, 22, 25,169,163,100, 69,105,125,166,116, 70,126,237,240,173,188,242,233, 18,100, -237, 93,235, 42, 60,202,109,114, 92,138,190,220,221,209,196,104,148,181, 76, 74, 16,170,157,149, 92,105,110,132,210, 43,242, 74, - 19, 42,158,164,115,198,158,234, 36, 48,143, 6, 66,144,210,247,177, 85,202,124, 85, 41, 50, 23,238,234, 96,171,220, 84,131,201, - 81,167,186,242, 66,220,103,194,112,116,136,167, 49,204,218,135, 38,114,149, 36,142, 82,142, 24,109,205,249,100,111,109,188,154, -141,169, 87,121,132, 69,149, 25,154,133, 12, 70,102, 35,244,170,162,202,228,211,227,215,160,171,156, 70, 90,220,109,197,198,112, - 60, 25,150,134, 86, 98, 60,242,193, 74, 54, 70, 21,203,185,137, 49, 41,209, 55, 38,242,181,228,211, 26, 17,157,129, 46,114, 42, -180,121, 76,135,128,240,207,214,112,156,148,134, 86, 18, 75, 79, 49, 33, 50,163,165,120,248,146, 57, 73,105,106,159,147, 26, 7, - 37, 20,121, 74,249,129, 29,199, 81,176, 38,192,147,176,176, 11,229, 39, 28,113,196, 92, 57, 81,148,103, 21,249,110,121, 69, 46, - 69,155, 81,200,201, 87, 73, 60,114, 67, 44, 19, 46,155,235,139, 65,117, 46,165, 73, 11, 30,131,175, 80,250,185, 64,199, 74,170, -247,117,187,111, 83,215, 94,171,203,137, 65,135, 79, 67,143,174,161,207, 41, 13, 62,140, 15, 16, 83, 24,105,167, 37, 84, 28, 81, - 82,130,227, 69,105,245, 45, 71, 41, 66,191, 91, 76,133, 87,124,171,187,130, 29,167,217, 76,213,237,251,106, 66,189,205,119,162, - 28, 98, 37,199, 86,142, 16,162,185, 54,235, 12, 41,106,181,161,242, 45, 99,199,119,154,162, 48, 80, 81, 16,158,154,182,205, 62, -117, 86,178,221, 66,238,151, 81,166,214,156, 82,227, 66,168, 73,171, 77,171,198,152, 82,188,180,236, 27,145,222, 95,115, 36,148, -242, 70, 81,136,160, 29, 56, 67,138, 29, 54, 42,202,179,153,139, 37,154,143, 44,138, 93, 90,115, 13,179, 42, 84, 55, 84,228, 58, -130,154, 32,177, 34,167, 76,116,248, 83,164,158, 85, 21, 58, 66, 29,194,202, 84,242,134, 53,191, 74, 37,168,148, 34, 92,139,239, -126,187,219,125,133,150,228,146, 47, 98, 55,179, 1,136, 86,103, 62, 91, 69, 8, 36,153,106, 8, 60,182,111, 58, 40,216,157, 54, - 98, 36, 0,234,243,171, 58, 3,101,229,106,179, 43,139,104, 91, 70, 44,120,176,217, 45, 59, 21,146,164, 50,232, 71, 43,133,111, -117, 90,230,100,144,252,149, 40,149, 41,210, 74,150,181, 21, 44,149,171, 39, 97,160,209,196, 74, 98,138,211,204, 1,101, 39, 41, -232,160, 84, 80, 91, 86,122, 5,117,207,217,171, 93,167, 74,230,109,190,118,227,151, 50, 18, 67, 73, 80,101,207,212, 10, 45,182, -190,169, 65, 32, 16, 14, 72, 61, 50,113,157, 59,206,211,128,167,184,215,134, 84,218,139, 67, 9,202,136, 9, 81,207,134, 79,235, - 28, 17,243,252,113,169,165, 53, 56,166, 68,176, 35, 72, 23,245, 29, 5,183,191, 78,155,254, 24,174,234,171, 13, 76,138,146,157, -228,111, 49,216, 94,228,111,219,173,201, 22,181,250,250,130,207, 61, 76, 83, 78,129,201,136,206, 30,102,214, 63,241, 74, 61,219, - 81,242, 79, 81,141, 92, 33, 83, 11, 11, 43, 74, 70, 79,235,128, 48,146,159, 95,183, 89,187, 48, 16,248,113,190, 78,100,130, 82, -160,176, 65, 32, 28, 5, 99,215,168,252, 53, 65,216,162, 34,146,199,235, 39, 31, 2,200,193,233,215,144,231, 79, 81,206,164,117, -233,252,125,253,240,213, 89,206, 82,241,176,243, 14,190,132,117, 7,227,110,189,143, 94,183,197,134,155, 9, 14, 77, 73, 35,160, -115, 31,105,236,123,140,118,214,207,217,208, 91, 67, 45, 2, 19,212, 36, 12, 14,163,212,156,142,135,247,233,135,163, 69, 10,155, -158, 95,135,196,200, 0,103, 57,200,252,115,173,138,183, 84,150, 18,214, 79, 47, 42, 82, 64,200,200,192, 25, 63, 34, 51,173,102, -107,129,181,255, 0,158, 33, 53,234,201, 4,224,108,194,246,251,207,207,175,124, 57,232,109,180, 51,202, 72,248,130,113,142,248, - 78, 0, 31, 35,235,246,233,191,188, 42,206, 66,108,193,167,132,253,103, 41,181, 0, 71,255, 0, 2,140,174,134, 73, 35,245, 92, - 39, 33, 30,121,235,229,171,141, 90,228,106, 11, 32, 52, 80,236,183, 73, 12, 70, 4,229, 74, 7, 30, 43,152, 63, 3, 41, 29, 84, -123, 28,224,100,235, 5, 13,173,197, 57, 46, 67,138,125,249, 46,120,146, 95, 88,253,117,156, 97, 40, 39,245, 91, 0,225, 35,176, - 29,180,142,179, 80,220,168,205,149,126,211, 15,223,164, 16,122,250,158,195,208,145,134,108,155, 45,116,149,107,106,210,241, 41, -186,161,255, 0,120,194,221, 71,236, 47,127,218, 35, 79, 77, 86,176, 66,163, 8,205,225,197, 43, 56, 37,105, 65, 56, 36,252, 75, - 82,212,174,171,112,149, 28,156,245,207, 93, 15, 45,216,241, 57,146, 57, 27, 56,200, 72,192, 89, 78, 15, 85,168,159,128, 99, 39, -226, 63, 33,223, 89, 20,167,114,130, 10,130, 80, 72,248, 26, 31, 30, 65, 0, 16,165, 3,208,231,174, 61, 61, 53,129,212,188, 52, - 7, 20, 82,214, 78, 74,148,226,186,164,228, 18, 84,181,103, 36,244,238,122, 30,157, 53,185, 26, 44,106,170,160, 1,238,236, 54, -253,214,249,247,206,169,100,122,153, 25,234, 36,251, 71,160,233,212,122,216,124,236,119,197,146,116,196, 43,156, 23, 20,234,176, - 66, 83, 24, 44, 50, 18, 79, 66,235,132,167,159, 61, 50, 50, 18, 9,206, 15, 83,172, 58,116,165, 37, 64, 4,182,218, 73,199, 59, -139, 10, 82, 73, 66,186, 33, 13, 30, 94, 96,174,108,228,231,168,198,123,139,140,202,131, 79, 30, 70,148,227,238, 33, 74, 65,102, - 43, 97,196, 54,147,211,226, 81, 41, 74,129, 0,103,226, 56,236, 70, 51,172, 78,114,228,243, 5, 43,193,100,115,243, 36,120,134, - 75,201,194,128, 42, 71, 54, 17,204, 60,206, 74,114,122, 18,116,112,214,210, 59,223,241,219,240,190,226,251,116,251,158,201,176, - 10, 23, 73, 61,143, 95,141,182, 61, 58, 16,167,226,118,197, 23,220, 24, 42, 82,202,147,250, 50,234,130,146,217, 45, 36,168,133, - 45, 94, 71,175,197,215,174, 49,223,174,177,233, 50,208, 66,131,105, 61,214, 66, 64, 78,114, 64, 32,244, 61, 27, 42, 36,100, 30, - 80, 0, 29,250,232,185,104, 66, 49, 33,199, 21,150,220, 43, 66,158, 90,158, 9, 94, 72,229, 74, 84,180,165, 36,173, 63,234,146, -156,146, 6,173,114, 20, 80,180,165, 72, 80,112, 20,145,206,164, 41, 92,139, 1, 96,182,144,172, 56,130, 20, 14, 50, 0, 39, 56, -233,141, 46,141, 98, 54,244,254, 95, 29,247,198,133, 76, 90,206,166, 58,175,233,178,237, 97,238,254, 93,189,215,178,204, 42, 33, - 93, 64, 42,248,136, 81, 57,235,147,209, 95,205, 61, 51,156,117,229,239,140,107, 16,158, 7, 42,147,206, 74,138, 85,241,171,148, - 17,140, 96,145,216, 96, 12,125,253, 6,178,233, 89, 1, 42, 89, 0,224,140, 40, 16,146,179,204,164, 55,201,216, 60,158,153, 29, -114, 59,100,118,197,106, 10,207, 40, 35,170, 73,230, 36,114,149,103,155,161, 9, 87, 86,241,147,231,213, 88,193, 58, 92, 49,218, -223,135,110,159,187,221,238,253,216,103,145, 0, 34,219,123,186,124,143,147,136, 13,251,114,237,134,237,143,105, 46,242, 73, 13, - 22,133,233,109,109,125,248,227,197, 1, 40,126, 69,118,199,166,197,148,182,249, 0,241, 0,122,146,174,101, 31,136,168,158, 98, - 78,117,200,194,180,168,126,137,101, 88,239,233,246,107,183,127, 72, 24,180,175,104, 99,158, 27,161,215, 19,195,254,205, 37,246, -129,255, 0, 34,180,195,184,124, 52,148, 17,150,202,152, 45,175,169,201, 11, 7, 0, 99, 92, 70, 83,105,199, 81,140,246,229,242, -249, 29, 75,178,155,181, 13, 41, 59,217,109,211,176, 36,116,235,219,242,199, 51,241, 50, 44,124, 69,158, 34,159, 47,181,212, 31, -255, 0,116,172,199,247, 18,113, 76,168, 40,116, 72, 29, 62, 47, 63,188,117,208,235, 35, 24,207, 92,244,254,221, 86, 40, 35, 62, -152,207, 95,232,251,116, 51,133, 67,168, 78, 71, 81,243,251,244,236, 6,194,221, 48,206,160, 29,173,211,161,253,216,162,179,229, -143,191,211,175,217,170, 11, 0,227,176,245,245,199,175,207,160, 58,244,188,254,177,201, 82,124,188,177,231,246, 29, 81, 39, 39, - 58, 93, 70,194,221, 63,158, 20, 24,164,230, 60,136,232, 72,244, 39,183,109, 12,178, 9, 61,242, 59,122, 30,223,214,116, 74,241, -130, 73, 3, 7,167,246,245,213,189,240,234,136,240,212,148, 97, 95, 22, 70, 74,128,236, 58,249,233, 68,235,140, 3,126,155,227, -193, 36,156,254,113,165,175, 10, 63,237, 99,238,206,116,180,125, 62,182,191,207,191, 25,199,180,146, 15, 65,159,151,174,171,165, - 93,142, 58,142,227, 61, 70,135, 31,120,254,145,251,117, 92, 96,245, 30,127, 46,250, 37,188,191, 15,195,231,231,124, 12, 86,241, - 19,156,117,235,231,142,159,126,136,111, 10,193, 74,187, 28, 99, 24,201, 62,191,136,252, 53, 65, 9, 0,131,220,244,251, 58,232, -164,225, 61,178, 7, 94,221,254,236,246,210, 76, 24,139,124,252,223, 25,219,239,197, 69,160,168,119,233,221, 93, 78, 6, 49,216, -125,186, 33,164,115, 36, 40,247, 29, 66, 71,160,233,235,170, 64,133, 15,207,113,215, 69, 36,242,224,244,244, 35,208,105, 34, 0, - 39,190, 49,143,104,101, 42,238, 57, 85,215,168,198, 72,251,188,244,123,104, 72, 72, 24,201, 79, 78,191,187,166,132, 65, 39,226, - 72, 25,244, 39,167,152,251,180, 90, 22,144, 1, 87,195,147,231,252,236,250,124,244,153, 23,216,158,159,233,140, 17,124, 28,214, - 58,114,244, 24, 61, 62, 93,191,167, 70, 32, 12,103, 39,230, 60,137,199, 94,154, 13,178, 23,215,168, 29,253, 59, 99,250,245, 93, - 11, 73, 95, 47,114, 62,127,102,127,103,150,147,194, 39,221,190, 13,108,129,145,140,228, 16,160, 70, 82,164,158,133, 36,121,130, - 9,200,212,133,253,149, 30,214, 40,187, 66,197,191,195, 39, 20,245,169, 15,236,235,143,162, 14,220,110,140,213,189, 54,163,181, -211,100,184, 17, 30,135,114, 58,162,165,203,177,148,226,240,211,164,149, 65,206, 21,150, 70, 83, 30,118,242, 14,122,121,126,206, -218, 33, 39, 37, 68,227,168,229, 32,128, 82, 65,232, 65, 7,184, 56,237,231,157, 55,102, 89,109, 54,103, 78,208, 84, 37,251,171, - 11,106, 86,236, 71,240, 32,236, 71, 81,211, 14,249, 22,123,153,112,230, 99, 22,103,149,205,202,158, 63, 43, 43, 92,199, 44,100, -130,209, 74,160,141, 72,214, 29,195, 41, 1,144,171, 0, 71,233,189, 78,163,199,149, 6, 5,118,137, 50,159, 88,161, 86, 97,179, - 50,145,112,209,228,179, 81,164,214, 32,202, 66, 93,106,101, 62,161, 25, 74,109,214,150,210,146, 82, 66,186,115,105,198,165,210, -220, 45, 54,156, 0,210, 18,130, 16,156,144,132,160,130,113,234,163,215, 63,102,191, 63,142, 13, 61,168,188, 90,112, 88, 35, 91, -187,121,119,179,119,109,106,165, 54,185,123, 83,184, 1,218,213,172,195, 74,112, 25, 31,193,231,222,112,191,110, 58,164, 21,224, - 48,176,215, 49, 7,195,198,117, 59, 45,161,226,130,149,124,109,157,131,126, 59,105, 34, 25,190,109, 42, 53,196,184,241, 30, 15, -198,138,237, 78, 35, 82, 31,140,211,167,245,219, 66,220, 41, 7,190, 19,170,167, 56,203,165,200,101,140, 85,149,104,230,213,203, -101,189,155, 78,155,220,117, 82, 3, 46,198,227,123, 43,181,137,199, 98,248,121,226, 4, 60,107, 28,144, 81,211, 52, 25,134, 94, -168,243,195, 33, 13,165, 88,233, 15, 20,151, 2, 68,212, 8, 23, 84,117,184,212,128, 27,157,174,166,211,138,218,110, 68,166,202, - 12,226,136,177,129,232,166,216, 72,248,148, 83,159,213, 41, 3, 58,199,247,101,136,115, 44,202,189,191, 58, 53, 62,165, 75,147, - 13,232,255, 0, 85, 84,225, 70,168,193,124, 22,212, 1, 92, 57,109,173, 42, 25,207, 92,107, 7, 94,247, 82,222, 44,120, 49, 37, - 54,166,153, 62, 27, 97,162,180,183,147,212, 19,228,122,244,251, 53,166, 60, 82,241,139, 69,219,203, 98, 69, 54,140,180, 86,247, - 30,234,150,139, 66,201,183, 25,149, 29,233,234,185, 42,196, 70,134,169,113,219, 89,247, 70,154, 91,161,107, 46,114,242,132,100, -244,206,153,205, 97,168, 2,158, 4, 44,100,219,125,135, 64, 78,228,219,222, 73,244,222,221,174, 76,131, 35,204,179,124,218,130, -135, 45,164, 51, 85,202,227, 76,106, 62,206,255, 0,109,219,126, 90, 70,190,103,145,136, 84, 93, 78, 72, 23,191, 48,247,123,113, - 54,107, 98,106,146,105, 9,180, 41, 21,123,162,141, 80,151, 62,153,110, 91,228, 81,105,212,218,178,156,241, 34, 77,169, 72,130, -226, 75, 2, 57,229, 90, 91, 71, 95, 19, 25, 61, 49,174,102,239,183, 16, 27,245,196,245, 64, 82,110,171,182,181, 46,217, 96, 6, - 35,218,212,137, 51, 32,219,108,198,105, 92,201, 85, 69,199, 30, 6,166,164,128, 10,220,112,144, 72,251, 53,214,202, 31,178,178, -163,118, 58,154,214,227,110,196,250,141,229, 94, 90,234,215, 82,232,240, 89,168, 70,166, 84,170, 4,190,168, 41,121,249, 0, 76, - 90, 29,119,151, 56, 9,248, 73, 25,214,146,202,219, 91, 51,104,184,161,111,104, 55, 2,101, 83,114, 54,198,194,191,169, 77,110, - 68,221,177,164, 63, 85,175,214,237, 88,241,211, 82,147, 76,141, 78,128, 22, 91, 87,142,150, 98,205, 74, 85,132,248,171,248,142, - 53,173,150, 83, 84, 83,203, 81, 44,142,139,160, 27, 2,160,233, 3,114,117, 16, 12,141,127, 70, 80, 9, 35,125,241,233,239,130, - 41,224, 38,103, 13,117, 54, 67,153,205,226, 87, 28,112,190, 95, 45,125, 92,210, 83, 86,187,242,226, 42,178,174, 80,149,113,165, - 44, 65,229,100,134, 4,141,150,122,141, 81, 51, 73,162,237, 30,168,196,225,210,109,131,180,183,158,251, 93,182,173, 90, 77,131, - 96, 89,181, 75,242,173, 86, 98, 49,102, 9,183, 41, 18, 99, 82,213, 61,169,147, 28,108, 26,115,213,233,208, 41,241,139, 73, 89, -155, 50, 88, 98, 57, 82,144,225, 71, 44,173,110, 47,174,107,174,254, 98, 13, 58,249, 85, 6,131, 87,171, 39,220, 44,241,181,244, -153,180,166, 32, 5,149,154,122, 42,162,227, 19, 75,165,128, 71,188, 56,178,174,115,204, 82,145,128, 36, 3,237,235,223,234,222, -215,112, 55,182,219, 31, 86, 98, 61,181,187,220,112, 95,208,183,126,253,180, 97, 54,220, 21,109,191, 13,155, 89, 33,113, 54, 95, -106,218,165, 50, 18, 40,148,150,231,154,107,198, 55, 42, 67,242, 41,179, 93,113, 42,113, 74, 86,162, 97,177, 48,209, 39,113,161, - 58, 64, 13,211,225, 75,148, 51,140, 36,165,190, 84,143,159, 65,171, 75,135,178,168,107,242, 90,172,214,180, 51, 59,234, 16,134, - 17,190,133, 64, 20, 55,158, 54, 2, 70,146,225,136, 0,174,157, 43, 97,185,243, 63,233, 63,244,231,241, 66,159,196,102,225, 15, - 14, 51, 37,224,188,143,132, 9,142,161,114,156,207, 55,165,122,154,211,180,201, 83, 95,148,230, 89,116,181,212,212,192, 8,224, - 5,150, 25,142,186,190, 84,124,245,138, 25,117,109,141,230,157,201,225, 47, 99,174,184,147, 81, 37,251, 42,185,185, 27,109,239, -116,234,109, 66,219,122, 4,155, 82,247,170, 85, 97,120, 77, 63, 82,121,198, 42, 45, 83,110,106, 65,247,182, 36,165, 14,184,226, -150,194, 25, 9,113, 3,110,182,151,139,125,212,183,132,104, 23,139,113, 55, 18,137, 24, 33, 42,171,202,150,138, 77,231, 10, 58, - 80,148, 41,215,106,105,101,113,238, 23, 2, 0,109, 6, 99, 41,127,224, 0,190, 84,115,174, 89,251, 50,110,182,111,109,161,226, - 3,101, 36, 58,211,149,138, 21, 94,218,222,203, 78, 35,202, 81, 46, 82,231,199, 69,129,126,193,167,180, 63, 93,214,103,194,179, -170, 50, 48, 15, 42,103, 21,168, 17,147,174,130,217,182, 49, 51,154, 91,177,188,102,144,164, 58, 35,144,191,242,169, 25, 99,159, -148,124, 72, 7,226,207, 80, 49,207,131,216, 83, 92, 69, 69, 29, 6, 99, 95, 73, 34,235, 8,250,148,236, 9, 14, 17,197,138,133, - 2,215,210,116,217,110,164, 91, 97,105,119,134, 62, 33,208,248,151,225,118, 89,196, 28, 81, 28, 85,249,213, 91,213,189, 89, 99, - 36,143,237,143, 83, 41,169,117,146, 89,165,169, 6,105,139, 75,170, 73,228,145,245,134,150, 73, 9, 44,122, 97,110,111,221,149, -120, 67,165,189, 58,161, 34,214,201,105,134,233, 55,148, 69, 83, 11, 50,221, 90, 92, 68, 40,213, 72,110,200,135, 46, 73, 41,108, -171, 14,167,245, 84,130, 65,200,211,166, 94,171, 84,102, 51, 47,194,143, 89,131, 9, 5,184,240,105, 85, 40,147,218, 74,222, 40, - 89, 97,227, 2, 67,137, 97, 78,252, 5,254,110, 85,114,132, 39, 9, 72, 32,233, 93, 14,201,122, 65,143, 22,156,212, 69, 86,100, - 46, 44,135, 38, 57,135, 33,219,180,231, 22,234, 83, 60,161,192, 10,170,170, 8,144, 33,178, 71,233, 29, 30,242,191,208,181,133, -191,182,125,129, 22,137, 24,184,219, 16,105,244,122,116,229, 24,172,196,140,227, 51,106, 82, 37,172, 0, 92,153,226, 37,249,213, - 57, 83, 22,165, 18,225, 82,222,113, 69, 74, 9, 71,234, 68, 9,208,198,209, 94,219,218,228, 15, 83,112, 65,184, 62,227,110,189, -109,178,169, 62, 83, 5,218,149,249, 37,181, 42,198, 87, 89, 80,199,253,217, 86, 70, 70, 98,204, 20,146, 89,197,201,101, 22,230, - 59,242, 41,215, 69, 77, 73,128,236, 67, 18, 58,167,154,138,231, 60, 4,102,158,150, 80, 82,130,218,157,115, 45,198,101,174, 84, -165, 1, 68,114, 52,130,156, 99, 89, 45, 34,212,134,228, 73, 16,146,227,205,181, 1,201, 78, 77,171, 38, 42,218,143,227,144, 4, -201, 12,201,115, 36, 71, 12, 32,165, 43, 3,226,248,212,144, 10,146, 53,126,180,172,233, 73,154,154,212,168,202, 93,197, 80, 97, -136,104,140,211,242,100,192,162,196,109,194,166, 41,208,221,148,163,201,135, 23,227, 62,232, 78, 95,127, 36, 0,218, 27, 1,238, -160, 90,138,170,136,112, 34,196,122,116, 24,179, 26, 97,224,201, 66,151, 91,158, 22,121, 26, 8,112, 2,184,136,155,133, 28, 30, - 89, 15, 32, 1,204,132,117,220,138, 25,100, 69,141, 33, 42, 95,185,185, 36,108, 64,216, 41, 3,125, 76,119, 96, 54,234,214, 58, - 53,249,220, 11, 78,232,142,144,194,128, 23,101, 1, 6,175,214, 62,103,112,219,249, 82,197, 84,238,108, 17,110, 52,139,118, 47, - 29,184,225,215,110, 42,187,173,184,204,207, 72, 80, 85,167,183,182, 36, 9,173, 70,184,111,106,192, 66,170,116,219,106,146,227, -200, 80,164, 50,235, 10, 77, 66,191, 84,117, 10,106,153, 79,228, 73,241, 36,174, 36,119,184, 21,190, 59,243,185,156, 69, 84,159, -170,238, 77,125,233,212, 64,224,114,153, 96, 80,157,149, 74,219, 91,113,168,200, 9,139, 79,161,218,173,191,225,204,247,118,130, - 18,103,207, 18,106, 18, 92, 10,125,231,194,214, 80,151,139,218, 61,196, 11, 91,199,196,197,237, 22,149, 81, 84,157,189,217,229, -191,180,182, 2, 88, 11, 17,100, 68,160,212, 84,221,239,112,178,210, 9,241,102,214,111,225, 52,151, 48, 84,168,148,168, 76,161, - 74,109,180,160,115,231,137,235,103,118, 56,127,147,104,217, 55,156,251,107,111,175,235,178,220,141,117, 86,109, 75,154,123,113, -238, 29,183,163, 87, 2, 87,106,211,239, 74, 50,150,145, 64,189,234,148,231, 29,158,154, 36,149,174,165, 75,167,166, 52,138,188, - 24,138,159, 21,133,236, 83,112,252,185,180,169, 8,169, 20,176,234, 0, 18, 88, 7,176, 39, 89,211,114,119, 4, 70,189, 44,161, -148, 22,190,159, 75,188, 43,225,207, 12,190,140,158, 22,229, 62, 49,120,177, 11,207,199,124, 79, 74, 43, 96,166,138,138, 92,199, - 54,166,167,120, 99,153, 50,252,166,134, 37,121,162,150, 40, 36,137,243,154,231,228, 65, 75, 44,172,185,141,117, 61, 12, 49,202, - 64,184,109,119,103,132,181, 74,129, 79,134,194,135, 43,190,237, 21,191, 29,100, 96, 37, 40,117, 73, 82, 99, 35, 32,124, 88, 42, - 63,170, 53,226,221,219, 54,154,144,210,159,144,184,110,188,191, 9,111, 50,130,176,158,110, 80, 84,251,171,202,128, 1, 93, 73, -229, 25, 56, 37, 0,140,233,155,215,238,236,178, 81,245, 6,230,196,184, 38, 72,117,114,146,204, 10,157, 18,124,222, 68, 55,238, -229, 13,192, 85, 62, 51,171,139,134,207, 35, 41,140,233,231,202,146,147,144,117, 96,166,239,230,251, 91, 78,170, 52,187,154,100, -238, 69,175,198,143, 95,161, 83,106, 18,154,101, 79,165,231,152,117,164, 67,133, 45,134,212, 82, 91,194,156, 5, 45, 44,164, 2, - 66, 84,155, 34,147,133,243, 36,165, 20,116,217,188, 35,151,238,126, 97, 4,254,177,125, 68,239,211, 82,223,173,172, 0, 24,167, -179, 47,246,170,125, 30,232,243,104, 31,139,124, 24,227,142, 30,161,169,102,142,147, 50,172,203, 50,121, 41,229, 42, 69,218, 3, - 30,118,241,202, 0,243,200, 41, 94,165,129, 22, 42, 88,227,163,116,203, 17, 8,185, 93,183,106,208,252, 38,221, 75,239, 69, 82, -148,212, 98,226, 86,217,118, 44,165,167, 9, 65,101,223, 60,148,144,181, 96,168, 43, 0,252,174, 91,214,181,183, 10,117, 86,179, - 50,153, 73,166, 83,194,214,252,233, 83,209, 26, 43, 44,162, 64,140,219,206, 58,234,210,112,235,191, 11, 64,100, 44,244, 4,168, -145,172,123, 98,119,186,189,184,148,118,141, 70,148,197, 50,191,111,207, 66,201,167,161,249, 52,249,241, 42,212,229, 7,204, 15, -126, 66, 92,110, 3,140,161, 73,118, 19,202, 81, 97,108,148,161,199, 27, 91, 78,107, 86,119,238,216,221, 43,230,252,250,182, 13, - 58,183, 46,147, 70, 13, 38, 4, 56,116,185,179,162, 69, 46,180,223,141, 81,142,184,140, 41,147, 41,114, 84,242, 75,171, 82, 84, -194, 91, 72,230, 64, 90,214,181, 33,200,201,170, 43, 89, 94,208, 24,128, 15,166, 66, 20,216, 3,112,111, 96, 88,110, 78,159,118, -155,220, 99,160, 60, 98,250, 99,112,207,134,255, 0, 71, 46, 29,250, 64,120, 83,195, 50,248,169,148,241,245, 69, 30, 93,144,193, - 67, 79, 83, 28, 82,215, 85,189,122,153,115, 32,105,154,178,134, 26,105,168,101,163,146,156,211,189, 75,102,130, 44,173, 68,114, - 77,207, 71,110, 15, 18, 59, 61, 18,251,183, 45,234,180,107,233,187, 1,250,171, 17,238,235,214,213,164, 83,170,247, 53, 22,146, -247, 59,114, 43, 22,149,141, 85,159, 17,119,100,134, 63, 68,234,163,187, 34, 18,164, 53,206,152,138,117,244,161,183, 58,193, 87, -225, 15,135,235,154,206,165, 93,187, 71,198, 37,215,186, 16,174, 74, 84,106,197,183,252, 7,217, 27,135,115, 66,233,111,133,248, - 82,110, 88, 27,108,185, 18, 44, 98,226,138,217, 76, 74,176, 98,168,211,208, 31, 14, 67,113, 0, 40,199,138, 77, 58,219,219, 50, -244,105,201,133,114, 94, 12, 56,227, 82,225, 41,246,106, 20,107,126, 74, 1, 10, 21,105,145, 29, 83, 87, 29,105,183,135, 90, 99, - 14, 24,108,168,230,161, 33,210,145, 21,121,134,197,241,157,196,167, 13,119,204,187,239,101,247, 94,228,180,103, 85, 93, 74,238, -122, 27,239, 11,130,196,190, 89, 74, 3, 65,139,247,111,234,106, 52,187,152, 37,129,200,203,193,152,211, 98, 54, 3,112,101,197, -108, 4,133,235, 56, 58, 10,228, 87,202, 71,178,152,134,242, 75,119, 19, 27,222,225, 88,150, 31,254, 96, 54, 34,214,141,213,129, - 30, 77, 63,251, 74,190,146, 28, 63,196,245, 21, 94, 41,241, 81, 90,138,137,238,120,103,135,232,114, 90, 51,145,166,250,161,204, - 42,243, 28,191, 56,115, 80,172, 17, 36,201,106, 30,171, 49,165, 99, 58,215,215,101, 85,180,199, 46,155,165, 84,250,206,231,112, -167,186, 84,202,229, 58, 84, 41,147,169,133,248,238,197,175, 91,119, 93, 18,221,187,232,146, 84,224,168,218,183,125,171,122, 80, -169,146, 69, 62, 91, 77,165,197, 50,182,199,186,202, 90, 37,197,125,153, 76,161,221, 73, 67,102,161,181,186, 27, 75, 97,238,133, -149, 75,174, 53,111,223, 86,211, 87,109, 54,213,185, 35, 77,146,237, 17,137, 14,200,167, 84,169, 77, 86, 23, 24,190,212,104, 85, - 56,114,217, 98, 72, 75,241,159,101,166,228, 0, 16,240, 9,226,206,213,123,125,246,154,253,183, 26,179,248,203,225,125,202,139, - 46,178,168,179,235,251,104,229, 22,255, 0,179,166, 52, 82,164, 41,247,246,211,115,158,110,161, 69,150,180,149,143, 14,155, 84, -150,134,210,172, 54,180,249,236,206,213,123, 69, 61,143,214,236,216, 85,123,123,115, 55,238,195,166,195,122, 53,197, 19,108, 46, - 26, 79, 16, 44,236,253, 26,226,128,250,223,131, 85,141,183, 84,234,188,232,106,173,199, 90,212, 89,142,137, 15, 83, 81,144,125, -209,101, 40,228,141, 47, 10,102,180,149, 86,154,156, 24, 92, 29,108,129,135,154,226,204, 2, 44,137,115,111, 54,226,254, 93,182, - 24,147,120,185,244,188,240,119,233, 7,195,249, 54,103, 93, 17,224,159, 17,114, 33,203,106,209, 45, 37, 92,121,173, 8, 71, 34, -150,170, 58,150,200,101,166,150, 41,220, 61, 44,139, 5, 76,112,171,213, 71, 20,136, 39, 4,118, 6, 29,186,134,194, 27,148,195, -193, 62, 44, 68,187, 21,106,102, 84, 30, 70, 85,205,142, 80,158, 87,201, 81, 7,153,192, 0,192, 80, 64,211,149, 66,165,180,203, -136, 67,104,240, 27, 90,130,130, 17,226, 37,166,148,162, 1, 67, 73, 94, 66, 83,252,227,140, 39, 39,160,215, 35, 46,223,110, 95, -179,178,219,105,233,244,219,195,120, 47,233,139, 89,112, 67,182,118,102,191, 77,247,149, 21,115, 41,196,213,175, 41,244,200,241, - 80, 85,142,139,201,194,137, 9,207, 77,115,159,136,255, 0,164,222,229,137, 30,163, 15,134,190, 13,228, 85,153, 9, 87,213, 91, -165,191, 87,204,167, 45, 40,174, 45, 76,182,204,169, 86, 14,216,198,101,228,255, 0,133,202,109,178,212,219,137,132, 41,194,148, -158, 96,180,131, 37,202,248,118,182, 90,133,138, 42,118,185,221,117,133, 75,133, 32, 29,216,168,185,189,236, 14,163,109,129, 0, -219,143,243, 63, 16,184, 90,150, 55,105,115,232, 42,165, 31,169, 77, 42,212,177, 32, 14,130, 18,226,224, 0, 53, 57, 0,216,238, - 55,196,195, 45, 68, 22,211,205,146,176,133, 54,151, 20,132, 15,133,229,231,144, 40,224, 37, 5, 65, 39,151,155,148, 18,158,152, -235,167, 48, 77, 75,205,166, 35, 10,241, 36,158, 64,164, 52, 60, 79, 9, 9,207, 48, 83,160,114,149,103,148, 96,103,182, 73,215, -230, 7, 43,219,203,237, 79,157,190,246,230,253, 61,196,180,212, 75,181, 94,156,213, 51,101,233,182,221, 22,223,225,210, 69, 2, -168,227, 11,169,218,181,125,167,162,176,212,122,212, 25, 8,142,218,126,176,154,244,170,211, 68, 7, 88,168,182,234, 82,177,213, -203,167,233, 12,113,211,199,133,235,182,188, 54,240, 99,176,227,101,238,251,254, 37, 46,135, 81,183,246,214,113,190,247, 95,112, - 47, 39, 98, 37,203,129, 54,157,199, 86,136,195, 22, 53,140,193,106, 91,252,225,149,204, 98, 19, 75,118, 84,180,165, 7, 18,169, -178, 74,170, 69, 51, 56, 73,209, 23, 81,210,224, 42,219,115,204, 50, 5,109, 34,219,149, 87, 3,115,219, 16, 36,241, 71, 32,204, - 22, 85,167,138,163,219, 12,129, 32,128, 37,228,152,177, 1,116, 88,216, 92,246,107, 17,218,230,195, 19,125,171, 92,246,205, 30, - 90, 32, 84,171,244,168,149, 5, 16, 61,205, 83, 89,247,180,147,216, 56,218, 23,148,121,247,198,178,122,125, 22, 5,114, 40,154, -138,154, 22,210,134, 80, 99,180,183,112, 79,162,136, 1, 95,118,123,235,152,220, 17,123, 63,247, 3,103,237, 26, 77,219,197, 85, -255, 0, 51,114,119,174,160,202, 42, 21, 90, 12, 74,180,170,149,181,104,202,120, 37,197,211,222,171, 73, 81,114,229,171,182,181, - 40, 63, 37, 88,100,184,149,120, 41,228,194,143, 75,153,101, 48,185, 91,107,153,134,155, 1, 8,109,165, 41, 41, 74, 64, 1, 32, - 4,224, 99, 3, 80,103, 78, 51,204,101,157,185,180, 57, 21, 10,146, 34, 81, 20,149, 19,184,236,206, 95,148,177,131,216,104, 15, -110,168,167,108, 60,209,182,123, 57,246,138,169,146,133, 91,117,142, 38,105,152,127,215, 43, 89, 24,145,251, 10, 7,241,197, 84, -154,117, 14, 91, 72, 18,147, 35, 46,114, 97,104, 83,107, 42, 39, 25, 0,249,254,115,167, 66, 11,229, 77,120,141, 0,191,209, 21, - 33, 25,229,241, 84, 82, 74, 83,146, 59,103, 90,221, 94, 77, 82,101,118,154,148,130,244, 86,221,202,228,255, 0, 60, 39,160,229, - 89,254,119,200,247,211,203, 6,164, 88,105,150, 65,236,148,131,147,213, 56, 24,206, 62,221, 45,195,237,153,206, 43,169, 51,119, - 73,100,164,125, 34, 72,211, 64, 97, 96,110, 1,191, 81,243,214,210, 12,210,138, 24, 41, 40,102, 89, 57,178,213, 33,105, 1, 32, -244, 32,111, 96, 45,125,246,219,221,139,140, 97, 48, 58,236,154,131, 46,153, 46,146, 87,204,146, 82,132, 15,242,109, 36,167,167, -132, 6, 59,119,206,190,200,170,100,132,160, 21, 41, 56, 1, 36,134,210,133,100,156,114,158,195,191,225,170,166,170,211,105,248, -149,212,255, 0, 59, 56, 36,156,100, 15, 64,113,246,235, 24,171,213,226, 60, 10,142, 60, 84,244, 75,137,232,164,103,245, 65, 82, - 71, 80, 58,100,117, 7, 79,209, 82,242,147, 69, 59,116,245, 27,159, 93,250,111,240,235,241,195,116, 85,144, 77, 56, 50,195,229, - 27,121,122, 40, 22, 2,202,123, 1,254, 33,247,226,229, 38, 74,212,210,138,159, 75, 96, 2, 2, 89, 3,156,146, 72,192, 46,118, -242,234, 6,176,138,131,208,130,143, 59,105,144,180,243, 97,114, 84,183, 74, 71,117, 30, 85,124, 41, 72, 32,103,160,201,234, 15, - 82, 53,100,169,214,165, 52,218,131, 78,182, 91, 7, 5,229,115, 43, 41, 62,101, 9,253, 85, 99, 29,115,128,122, 16, 53,132, 78, -168,190,250,242,169,137, 87, 33, 4, 48, 26, 80,111, 0, 28,172,132,175,226, 56, 4,128,162, 71,159, 77, 32,237, 34, 54,153, 1, - 86, 59,239,247,110, 15,243,248,219,221, 40,164,162, 89, 84,201, 21, 66,136,191,195,112,122,116, 32, 11,143,131, 90,221, 78,196, - 28, 93,170, 53, 86,220, 45,182,214,121,193, 56, 75, 24,202, 63,156,175,242,120, 8, 79,194, 49,147,208,172,140,107, 28,144,185, - 14,165,196,243, 54,128,227,107, 95, 40, 1,247,148, 10, 82,160,148, 36,114,161,156, 18,146,126, 53, 99, 7,225,193, 26, 21,201, -165,223,209,170, 87, 43, 69,196,145,224,199,109, 32, 21,142, 84, 37, 68,147,135, 50, 73, 61, 7,235, 99, 61,180, 42,150, 9, 83, -110, 45,199,193, 66,138, 91, 83,156,173,178, 57, 84,149, 20,132, 36, 4, 47, 4,158,234, 33, 74, 7,212,107, 34, 85, 36, 91,174, -195,111,187, 14, 2, 4,136, 88, 88, 50,239,114, 9,216,252, 64,239,107,131,210,253,111, 96,106,135, 9,241, 91, 90,152,154,224, - 81, 10,117,183, 66,150,132,132, 32,132,199, 90, 18, 18,211, 62, 25,202,136,229, 86, 80, 71, 55, 78,180, 86,211,138, 90,218,109, -210,132,173, 42, 40,195, 97,226,160,188,146,149, 61,202, 17, 24,252, 7, 4,147,128,148,146,114,179,143,162, 72, 66, 20, 93, 82, - 91, 32,243,151, 0, 13,184,226,121, 87,250, 54,210,216, 3, 57, 40,248,112, 84, 48,188,119,233,112,142, 86,234, 29, 75,124,173, -161,158,235,112,133, 50, 75,156,174, 56,246, 66,135, 48, 3, 10, 10, 0,128, 64, 10, 4, 29,108, 70,250,118,191,227,252,183,237, -110,134,223,125,175,163, 80,140,221,139, 15, 94,194,214,251,186,251,205,239,140,110,108, 82,150,189,228, 33,212, 54,225, 10,142, - 29,108, 40,168, 1,209, 40, 65, 63, 3, 28,169, 5, 42,200,193, 95, 80, 71,124, 14,168, 18,210, 86, 21,203,202, 82,160, 8, 0, -169, 41, 24, 9, 81, 60,184, 87,196,165,224, 12, 28, 28,231,190,156,202,203, 43,100, 60,180,187, 46, 83,142,128, 90, 68,167, 20, - 70, 74,148,144,167, 1,235,149, 35,157, 71,249,216, 72, 0, 37, 61,155,106,154, 76,153, 41,136,149, 4,169,231,163,196, 66,202, -129, 9,117,245, 33,158, 98,160,112, 71,136,224, 32,158,132,126, 26, 84, 48, 2,250,134,223,233,191,126,157,125,253,112,216,241, - 18,202,161, 65, 55, 29, 0,222,246,181,135,238, 29,126,252, 64, 99,219,127,112,181,112,123, 74,183,173,166, 28, 82,255, 0,130, -214,206,212, 89,178, 82,176, 66, 90,159, 67,176,105, 47, 75, 67, 68,147,204,215,137, 82, 24, 35,204, 30,154,228,170,206, 51,216, -231,166, 58, 99,237,251, 53,183, 60,121,238, 60, 93,220,227, 99,138,189,200,132,233,122,157,114,111,133,244,154,114,249,150,180, -154,125, 6,168,171, 94, 25,104,172,228, 50, 89,161,161, 72, 29,130, 92, 0,116, 26,212,101,246, 56, 61, 59, 96,227, 63,241,212, -247, 43,140,165, 5, 18,176,179, 8,144,144,122,130, 84, 18, 62, 32,155, 28,114,150,121, 50, 85,103,185,197, 66, 29, 81,207, 87, - 80,202,123, 21, 51, 57, 82, 15,189,108,126,252, 8,178, 15, 79, 76,232,117,245, 36,142,192,224,252,191,179, 85,214,174,254,137, -207,231,246,104,101,224, 28,231,161,235,248,233,200,126,252,104, 1,220,109,129,221,230,199, 97,142,189,189, 51,215, 63,159, 61, - 14, 64, 0, 96,247, 29,126, 71, 68,169, 89, 62,120,252,245,208,202,238, 79,204,253,154, 92,108, 5,240, 48, 58,192,202,135, 67, -215,243,231,249,198,133, 81, 3, 57,249,224,119,237,229,162, 28, 39,169,249,249,126,125, 52, 26,200,251,199,127,179, 74, 45,198, -227,126,216,200,253,248,160,178, 50, 58, 3,211,207, 63,184,253,186, 90,240,163,147,159,195,236,210,210,184, 24,175,170,168, 61, - 49,215,167,225,161, 16,112,122,156,116,213, 97,248,103,161,251, 51,164,216, 90,227,174,173,255, 0, 60,100,245, 38,214,190, 14, - 73, 56, 0,142,152,239,145,247,116,213, 66,176, 7, 82,172,142,216,249,246,207,222, 52, 58, 84, 83,211, 29, 7,111,236, 58,242, - 80,162,174,101, 47, 8, 61,128,206, 71,222, 7,174,116,131,222,222,236,101, 69,254,127,150, 46,141,168, 96, 0, 57,137,206, 73, -254,145,243,192,215,213, 44,173, 73, 8, 39, 9, 56, 87,124,103,247,245,254,141, 80,105,188,242,146,174, 81,158,128,117, 61, 49, -215, 25,244,209,205,167, 57,192,206,127,164,117,237,249,237,164,172, 79,207,166, 48,109,219, 21, 90, 56, 35, 35, 32,143, 46,221, - 61,125, 15,125, 28, 57, 72, 79,160, 62,127,205,251, 62,125,244, 50,121,112, 0,252,253,190,154, 37,176, 85,142,192,124,135,244, -231,207,166,177, 97,123,227, 24,184,178, 15, 76,159, 82, 63,163,247,234,184, 24, 57, 24,201, 57, 7, 31,135,219,161, 16,175, 35, -231,219,250, 49,162,146,113,220,245,232, 65,198, 59,246,199,175,246,233, 22, 22, 36, 97, 50,187,220,155,223,231,255, 0, 56, 37, - 43, 8,199, 58,186,159, 32, 59,244,249,104,146,238, 70,113,140,249,250,227,183,159, 77, 4,113,144,190,153, 63, 44,227,184,200, -252, 53, 81, 36,116, 32,231, 29,201,251,125, 7,150,146, 98, 58,223,225,130,219,221,123,117,193, 41,119, 24,248,249, 64, 32,224, -227,175, 94,160,122,244,206,167, 39,236,166,220,118,247,115,129,157,165,148,252,148, 73,171, 88, 74,169,237,245, 93, 33, 73, 46, - 54,186, 44,133, 38, 1,113, 61, 74, 65,132,228,126, 92,227, 35,168,212, 42,118,215,108,110,189,211,185, 98,219, 86,181, 49, 83, -231, 73, 5,229,186,227,137,139, 78,167,194, 66,128,145, 85,173, 84, 93, 79,135, 74,164,183,252,247,156,234,162, 66, 26, 67,174, -148,160,203, 23,217, 2,214,215,112,241,106,238,110,209,215,119,102,143, 34,181, 87,151, 2,239,168, 76,172, 75,110,139,108, 53, - 53,136,201,133, 34, 21,179,239,238, 5,184,218, 82,218, 11,139,119,149,215, 15,196, 91, 66,126, 17, 4,227, 9,104,167,142,154, -137,228, 6,169, 95, 86,155, 95, 74, 21, 96, 75,158,136, 11, 5, 3, 81, 26,142,194,230,246,184, 60, 26,124,214,135,136,167,204, - 41,105,100,124,178, 88, 36,167,158, 80, 44,129,137, 73, 35, 0,159,180,193,212, 2, 20, 18,129,238,218, 65, 23,235,214,231, 75, -174,219, 59, 83,184, 21,235, 93,151, 30,184,224, 91,147, 13, 27,193,104,188,236,105,178, 18, 35, 38,162,134, 82, 50,234,163, 33, -213,188, 0,207, 86, 70,181,171,102,120, 8,183,217,222,155,115,124, 46, 59,138, 53,229,105,208,108, 90,123, 86, 21, 10, 66,223, -155, 42,179,121,215, 33,166, 69,211,124,221,210, 95,234,244,211, 45,231, 83, 25,177,128,216,198,122,164,107,107,162,239,150,195, - 32,148, 57,188,187,110,233,193, 75,141, 34,227,167, 60,130,146, 48,180, 45, 33,226, 20, 8, 39, 35,207, 26, 14,226,227, 7,134, - 29,183,182,107,183, 12,173,200,163,213,169,246,180, 23, 39,205,163, 89,141,125,115, 86, 84,102,186,172, 83,169,144,129, 84,133, -127,178,128,126,237, 65,225,142,150,158, 82,226,162, 33,169,116, 0, 89,111,114, 69,200, 23, 59,157,133,183, 61,135, 91, 99,179, -242,190, 62,226, 28,135, 33,205,114,204,161,165,203, 70,109,205,246,202,132, 82, 30, 74, 87,138, 56,249, 76,250,117, 70,177, 5, -155, 76,136,234,116, 85, 84, 45,129,101, 97,144,207,224,179,103,238,181, 56,183, 81,123,208,158,152,250,158,156,245,169,125,220, - 20,116, 60,235,202, 42,121,197, 48,137, 42, 66,150, 73, 60,184, 78, 0, 56,244,208, 91,129,114,240,113,236,166,216,187,155,114, -235, 20,202,117,183, 21,229,201,153, 69,162,189, 37,138,222,236,111, 13,232,227, 74, 84, 26, 29, 62,109, 77, 74,149, 44, 56,247, - 39,140,233, 40,139, 17,165, 41,231,112, 0,207, 27,248,128,250, 66,114,226, 82,170, 52,190, 16,184,115,190, 43, 19, 3, 14, 52, -141,201,220,155,106,174, 41, 84,247,112, 66,100,195,183, 41,209, 86,185, 78,160, 14, 96, 30,113, 8, 56,248,186,103, 81,143,226, - 11,136,157,247,226,127,114,100,238, 30,253,238, 45,126,244,188,158,105,214,162,199,173, 62,168,205, 81,169,238, 40,172,211,168, - 86,223,192,221, 6,154, 50, 7, 43, 76,160,168, 1,206,181,158,186,127,203, 56,124,207, 46,161, 18,211, 34,253,166, 54, 14, 6, -215,180,103,204, 24,247, 50, 42,129,179, 89,197,215, 20,239, 27,253, 36,248,135,244, 13, 71, 12, 80,113, 94, 97,196, 20,179,105, - 38, 7,168,168,108,188, 50,127,118,243,135, 96,181, 38, 34,111, 20, 96, 58,169,220, 60,100, 95, 24, 39,180,115,137,253,201,226, -247,127,170,251,223,186, 82, 27,254, 16, 94, 74,118,124, 26, 44, 87, 92,118,155,105, 91, 81,121,162, 91, 54,141, 31,196, 63, 13, - 58, 13, 59, 9,230,192, 47, 62,243,210, 23,241,186,117,175, 92, 57,196, 97,202,237,211, 57,208,178,252, 42, 34,147, 24, 1,211, - 46,149, 5, 18, 60,253, 6,173,251,228,231, 53,219, 29,128, 65,247, 42, 12, 6, 79, 41,200, 5, 73, 4,129,215,191,174,178, 14, - 26,216,118, 93,122,230,134,202,121,164,204,167, 68,139, 29, 9,238,183,223,119,194,101, 41,207,153,113,104, 31,126,172,212,141, - 41,120,124,197, 24,209, 26, 34,128, 46,118, 28,192,119, 59,147,183, 82, 73, 39,169, 36,239,142, 53, 53,117, 21,115,214, 86, 85, - 74,211,213, 84,180,178, 72,231,118,103, 42,204, 73,176,238,123, 0, 0,232, 0, 27, 98,109, 63, 71,223,128,234,125,203,195, 15, - 16,156, 74,220,244,174,123,199,114, 99,200,218,237,155,145, 45,177,136,116,123, 98, 92, 90,221,217, 83,134,149,167,225, 85, 82, -187, 18, 29, 56,186, 15,197, 30,152,164, 14,138, 57,216,168,246, 17,161,213, 31,142,228,117, 50, 90,146,235, 97, 10,230, 75,225, - 8, 56,228,115,185, 67,169,229, 41,229,239,204,112, 8, 58,236,151, 0,219, 99, 15, 98,184, 76,225,239,107,105,113, 83, 17,187, - 99,109,109,231,167,180,148,132, 41, 85,138,164, 38,234,181,105, 14,116, 28,206,174,124,199,201, 39,174,123,233,168,226, 23,134, -171,150, 93,110,226,220, 91, 38, 61, 58,161, 65,144,255, 0,214,146,168, 44, 62,182, 43,237,206,148,240,247,152, 52,168, 9,103, -146,167,207, 53,197, 58,202, 3,136, 63,166, 80, 94, 2, 65, 52,151, 19,209, 54, 99, 28, 89,138, 38,170,131,118,127, 82,142,117, - 40, 61, 55,137, 74,160,247, 13,239,215, 29,145,225,180,210,240,102, 89, 6, 69, 36,194, 24, 42,163, 73,100,212,214, 95,105,101, - 94,110,228,237,169,174, 22,254,128,108, 0, 3, 82,108,234, 84,116, 52,134,210,201, 41,147, 33, 50, 29, 8,240,203,143,186, 2, - 0, 83,220,201,207, 58, 67, 40, 7, 36, 0, 19,132,156,107, 99,104, 52, 8,210, 93, 98,116,150,210, 36,193,113, 47, 65, 13,129, -225,199,203,101,135,198, 79,235, 74,113,133, 41, 10, 89, 5, 32, 16,148,242,167, 36,170, 87, 15, 59,203, 71, 82, 20,230,223, 76, -148,128,134,151,205, 74,153, 75,168, 33,105,194, 64, 39, 19,144,162, 0, 37, 71, 41, 4, 99, 28,189,244,241,218,123, 83,186, 79, - 41,180, 35,109,238,133, 20,114,133, 45,113,162, 37, 61, 14, 28, 74,221,114,104, 72, 79, 81,147,216,245,198,162, 81,100,213, 74, - 64,146,146, 66, 91,182,134,244, 22,232, 13,237,215,211,210,214, 24,178, 78,125, 70,186,229,108,198, 24,237,177,102,158, 32, 0, - 54, 4, 18, 91, 96, 64, 3,222, 5,177,113,161,208, 12,134, 16,211, 10, 90, 34,143,242,202,115,224,151, 49,158,230, 50, 29, 74, -147,238,236, 18,160, 10,191, 89, 64,114, 35, 1, 74, 86,178,171,163,112,237,237,158, 85,185, 95,170,208,239,234,203,242, 38,132, - 82,227,109,214,216,222,251,153, 34, 51,212,224,196,176,253,106,153, 99,209,229, 46,149, 79, 64,228, 45, 41,208,217,144,176, 88, -142,149,168, 40, 7,150,209,216, 45,211,158,164, 57, 54,149, 73,183,217, 80,229, 46,213,234, 77, 72,113, 41, 0,142,127,114,166, -182,234,138,136, 63, 8,231, 66,124,250,119,214,136,251,111,106,123,151,194, 15,179, 87,116,183, 91,103,247, 82,225,178,183, 81, - 55, 54,223, 91, 16,111, 43,121,168,212,249,212,202,101,201,112,177, 6,177, 22,136,227,168,117,112,106, 47,198, 43, 67,115,185, -253,229,144, 74,152, 83, 75,194,132,166,147,135,179, 55,167,146,177,104,218, 8,163, 49,131, 44,171,101, 82,242, 36,105,101, 37, - 93,174,238, 0,210, 13,137,213,184,190, 34, 25,199,137,124, 27,150, 48, 25,157, 89,207,105, 98, 73,154, 90, 74, 25,209,101,153, - 68, 78,197, 69, 87, 38,162, 8,201, 42, 11,115, 17,137, 23, 64, 22,225,150, 51,124,116,238, 62,206,240, 93,121,221, 53,125,139, - 98,254,183,183,166,236,173,213, 46,123, 18,139,190, 78, 91,107,223,205,183,143,115, 74,157, 85, 27,132,254,217,209, 34,200,137, -176,244,148, 57, 59,154,223,149,118,189, 34,254,168, 6,195,212,202, 37, 1,178,229,101, 17,220,184, 46,123,134,236,174, 85,110, -107,134,183, 87,184,110, 58,228,233,117, 42,229,201, 93,156,253, 74,191, 90,168,206,125,114, 39, 77,169, 84,100,184, 86,235,239, - 72, 90,214,224, 4, 37, 74, 86, 72, 39, 36,218, 42,181, 73,149,138,165, 74,181, 92,157, 58,167, 88,172,212,165, 86, 43, 53,106, -148,217, 85, 42,173, 98,179, 80,115,198,159, 87,171,212,230,186,183,234,149, 55,158, 37, 78,200,125,199, 29,112,245, 90,142, 6, -128,109,101,110, 97, 36, 6,179,241,128, 71, 49, 62,185,242, 26,176,114, 30, 31,163,201, 33,178, 14,117, 76,191,106, 66, 5,197, -194,141, 9,251, 40, 52,128, 22,229,136, 85,214,206, 85, 72,164,252,120,250, 73,120,157,244,128,204,169, 36,227, 28,238, 99,195, -217, 60,113, 67, 69,150,137,165,120, 17, 41,193, 88,102,171,119, 98,213,213,195, 83,191,180, 77,245,112, 73, 61, 64,160,130,138, - 25,228,133,136, 90,148,234, 57, 93, 9,121, 9, 80, 90, 91,144,148,188,144,176,114,149,165, 14, 2, 18,224, 80, 4, 40, 96,130, - 50, 8, 58,204,169,155,143,113,209,211, 21,169,110,192,185,160, 68, 11, 17,232,183,173, 53,187,170,154,198, 82, 82, 61,205,249, -174, 9,212,229, 15,255, 0,131, 48, 54, 63,248,163,211, 24, 96,228, 10, 88,201, 41, 7,162,137,244,238, 63, 57,213, 53,164, 43, - 36, 14,185,200,252,159,150,159, 39,166,130,161, 52, 77, 10,202,163,166,160, 13,137,238, 13,174,167,222, 44, 71, 99,138,111,135, -120,167,136,248, 74,170,106,190, 27,206,170, 50,105, 42,192, 74,133,134, 66,176,213, 68, 13,249, 53,148,230,244,245,180,228,253, -170,106,184,166,129,255, 0, 94, 54, 24,116,231,239,189,238,150, 89,133, 64,254, 15,237,252, 36,248,206,123,141,131, 77, 48, 29, -151, 33,230,210,209,151, 80,170, 84,195,206,184,250, 26, 64,229, 8, 74, 50,160,149, 45,107, 8,109, 8,177,171,117,119, 10,108, - 7,169,170,189,110,207,170,159, 74,208,253, 57, 21,201,173, 71,113, 46,161, 40,144,133, 73, 74,196,165, 54,232, 78, 92,111,222, - 60, 37,149,168,148,124, 74,206, 0,166,219,230, 33,120, 36,117,206,124,251,143,219,175,170, 91, 74, 90, 19,207,241, 32, 19,200, -147,240,156,250,254,205, 37, 29, 21, 36, 32,133,167, 64, 24,223,236,130,111,182,228,145,114, 71, 98, 73, 54,218,248,156,102,190, - 58,120,209,157,242, 99,172,241, 87, 62,130,146,154,148, 80,197, 71, 69,153,213,101,153,108, 20, 34, 40,225, 52, 84,185, 86, 89, - 37, 30, 91, 75, 70,241, 68,139, 37, 45, 45, 36, 84,242,232, 13, 44,108,196,177,172,227,188,193, 37, 92,169, 75,105, 8,109,150, -208, 16,219,109,131,209, 13,161, 0, 37,180,228,147,128, 7, 82, 79,114,117, 72,146,163,205,129,140, 14, 81,216,140,129,158,184, -237,223, 94, 84,177,158,216, 4,224, 31, 32, 73,237,246,107,233, 9, 80, 79, 50,129,198, 79,194, 64, 35,215, 61,126,205,109, 95, -111, 47,109,189,216,170, 85, 2,233, 91,105, 10, 6,221, 0, 3,160, 30,158,131,165,177,229,212,133,160,131,128,125,112, 51,211, -236,243,208,105, 11,230, 60,201, 8,109,191,139,226,248, 78, 71,159,207,251,116,122, 20, 20, 50, 7,145,200, 61,199,151, 95,191, - 67,169, 36, 55,151, 49,215,161,201, 4,252,137, 0,246,233,161,179,111,219, 6,177, 6,221,251,126,255, 0,227,138,110,123,186, -192, 82,130,150, 8,200,194, 73, 3,182, 73, 31, 61, 75,227,232,215,112,195, 99,223,219, 35,198, 38,227,110,133,131,105,238, 13, -175,184,202,183,248,125, 93,173,121, 80, 32, 92, 54,253,118,207, 69, 45,203,170,246,167, 78,131, 84, 97,109,174, 60,137,213,122, - 35, 78,132,242,171, 48, 16,160,164,173,180, 40, 68, 24,149,143, 8, 54,158,138, 74,147,205,144,144,181, 99, 24, 3, 29, 15,109, - 77,123,217,103,184,103,103,189,143,246,187,116, 6,164, 81,171,123,149,186,219,227, 85,173,205, 79, 52,105,170,164, 82,174,168, -214,139, 78,199,144,180,167,195,143, 48, 82, 93, 67, 79,160,169, 10,102, 26,210,135, 57,138,185, 98,156, 99,155,193,146,101, 73, - 89, 80, 12,138, 37, 10,177,139, 6,150, 66,173,201,141, 9,232, 76,161, 9, 36, 16,136, 25,200, 33, 72,197,129,225,126, 86,115, -110, 47,162,164, 72,185,210,136,228,101, 7,117,187, 20,132,234,244, 26,101,111,190,214,223, 28,193,223, 63, 97, 79, 4,115,184, -194,185,209,179, 27,239,185, 54,175, 14,116,135,150, 47, 93,165,163, 83,105,149,186,237,191,122,205, 66,164,162,196,218,237,215, -185, 31,144,220,155, 36, 48,243, 62, 60,137,208, 39,207,167, 56,164, 69,140,229, 65, 78,120,204,111, 6,212,251, 26,125,155,123, -125, 58,216,185,109,203, 55,136,138,110,227, 80, 37,198,122,216,220, 26, 55, 21,119,221,175,121,219,245,200,177,194,145,114, 81, -170, 86,149, 42, 2,105, 21,166,212, 60, 80,227, 40, 75, 45,172,132,134,150,223,194,108, 27, 71,113,203,157, 91,184, 42,197, 34, - 81,147,122, 93, 21, 71, 34,115, 36, 46, 82,152,170, 10,100, 82,181,243,128,150,154, 17, 84,177,200, 6, 11,105, 81, 80, 1, 58, -222,155, 74,229,118,163, 38,164,121, 90,136,212, 8,204, 83, 34,180,202,131,110,158, 98, 36, 84,159, 83, 97, 28,172, 45, 43, 91, -109, 37, 72,230, 95, 43, 74, 4,164,144, 53, 71,103,220, 99,198,175, 58,200,217,245, 68, 48,132, 0,197, 3,242, 22,221, 8, 44, -154,100,147,169, 93, 83,188,174, 86,218,156,144,111,212,220, 79,225, 79, 9,228, 78,100,161,201,225, 89, 2,172,143, 33, 82, 89, -164,178,130,234, 9,180,107,204, 58,149, 35, 85, 80,157, 55, 14,113,212,219, 99,136,234,228,106,101, 18,155, 87, 66, 43,171,106, - 35, 20,230,230,213, 86,165, 86,106, 81,233,145,219,143,245,157, 94,162,202, 82, 39,213,158, 8, 74,228, 72,240,144, 31,125,213, -185,225,160,171,151, 78,181,189,187, 22,141,226,232,140,220,143,169,234, 75,115,193,110, 28,247, 27, 75, 82, 94,236, 27,137, 40, - 30, 71, 22, 72,232,147,202,162,122, 0, 78,185, 81, 30,244,240, 36, 85, 11, 97, 75,143, 66,134,205, 38, 36,144,114,151,170,110, -182,100, 75, 96, 4,171,162,144,234,163,165, 65, 32,245, 74,178, 8, 26, 10, 61,219, 41,136, 17,203,239, 31,124,142,204,154,156, -175, 13,210,158, 95,136, 52,201,108,142,169, 62, 50,148,126, 69,191,150,148,202,184,199, 54,167,208, 37,169, 53,106, 7,153,101, -243, 27, 0,162,250,143,152, 27,234, 59,146, 0,182,199, 21,248,142,186,130, 68, 16, 73,204, 22, 91,197, 37,200, 58,148,200, 0, - 63,105,108,186, 23, 99,179, 29,212,244, 27,233,106,113,119,182,151,183, 20,183,231, 10, 22, 90, 95,184,110,205,174,179, 85,117, -110, 45,213, 17,214, 92,183,173,234,168,126, 51, 38,204, 66,193,230,145, 91,105, 50,153,247,130, 7, 35, 78, 18,214, 74,210,172, -108,130,235,136, 99,157,106, 88,230, 57, 24,206,126, 30,184, 29,122, 99, 35,174,184,239,193,253,153,180, 27, 99,196,214,228,110, -244, 17, 42,218,187,248,132,179, 97,219,181,104, 40,144,201,180,230,222, 73,172,174,167, 38,226,195,235, 46,192,175,213,208,195, -104,125, 33, 94,236,228,180, 23,194, 91,114, 74,129,232,125,205,113, 42, 50,221, 64,113, 73, 41, 74,147,200, 62, 21,165,105, 39, - 60,201, 61,142, 2,178, 62, 90,181,184,106,180,102,212,111, 59, 48, 18, 60,132, 50, 0, 46,130,202, 66,144, 55,247,134, 61, 71, -223,105,215, 25, 75,194, 85,210,100,173,193,144,212,211,209, 46, 91, 68,149,130,172,222, 99,154, 8,239, 94,118,188, 98, 35, 41, - 2, 1, 17,229,242, 66,157,152,184, 14,149, 74,248,109,178, 71,136, 2,123,168,115, 2, 14, 14, 57,186,118, 32,228, 31, 62,191, - 45, 97, 51, 47, 98, 23,151, 29, 87,134,165, 30, 85, 12,144, 73, 56, 9, 36, 28,115,140,128, 50, 48,190,217,242,214,190, 84,238, -181,120,174, 53,206, 10,138, 20,251,121, 81,248,208, 14, 28,111, 62,153, 35,167,145, 94,177,148, 93,188,217,104,175,152, 41, 36, -165, 46, 12,115, 32, 15,137, 25, 36, 18,180, 96,127,181,202,144,175, 93, 74, 99,129, 80,108,110,126, 63, 15,221,249,252,113, 22, -167,164, 88,198,195, 87, 75,254, 23,239,215,227,252,142, 54,149,187,161, 46,158,100,184, 10, 85,203,158,101, 4,148,156,144,121, -194,199,192,114, 21,229,141, 90, 42,114,158, 91,107,145, 76, 8,113,208, 10,213, 17, 74, 45,161,212,100,229, 76, 41, 32,144,224, -234,174, 78,161, 92,159, 14, 20,113,166, 18, 37,213,201,202, 92,120, 40, 0, 57, 92, 36, 41, 65, 39, 56, 67,160,145,146, 15, 76, -158,152, 57, 32, 19,157,102,144,110, 4,175,225, 82,207, 50, 70, 72, 4,148,117, 57,200,207, 83,144, 6, 64,237,203,243,234,149, - 69, 58, 78,154, 36, 23,244, 61,193,236,111,235,211,249,140,110, 67, 81, 45, 20,162,104, 13,237,177, 83,114,174, 63,101,198,215, - 30,253,136,189,193, 83,190, 47,109,215,101,185,200,130,228,102,194, 92, 90, 75,164, 58,231, 42,146, 73,229, 80,113, 35, 60,189, -138,136,248, 74,128, 86, 58,234,234,212,199,221, 1, 78,200, 88, 33, 68, 16,142,102, 27, 82, 21,132,242, 40, 55,146, 82,112, 59, - 17,133, 39, 33, 64,231, 88, 13,198,183, 11, 6,169, 79, 9, 91,204, 2,185,108,130,176,149,181,132,149,201, 71,135,250,206,161, -180,146,226,123,173, 0,158,139, 29,113,232,181,233,174, 28,169, 77,128,142, 71, 27, 45,169,120, 83, 43, 79, 55, 50,121,143,249, - 64, 84,147,211,161, 24,193,202,134, 98,211, 43, 81,204, 98,153,246,107,216,216, 88,131,109,238, 59,250,223,241, 6,248,157, 80, -188,121,165, 42,212, 83, 34, 68,192,217,212,145,169, 24,117,235,185,235,117, 35,175,186,197, 67,227, 22, 64, 10, 60,141,168,243, -128, 10,146, 74,212, 91, 65, 32, 37, 74, 41, 42, 91, 32,227,252,152,234, 9,207, 49, 35, 87,149, 84, 92,140,217, 90, 25, 74, 60, -117, 4, 33, 47,165,213,199,195,201, 42,109,160,129,149,198,144,226,142, 19,206, 49,147,240,163,148,243,105,158,139, 82, 82,138, - 1,113, 92,142, 19,203, 33,183,156,229, 70, 87,204,203,109,242,184,163, 29,174,101,225, 33, 28,203, 82,148,148,148,231, 35, 87, -196, 84,214,134,138,188, 73, 40,112,151,217, 83,209,203,109,180,180,164,252, 94, 34, 22,162,183,100,103, 28,223,168, 83,130,148, -143,136,157, 47, 28,195,190,192, 88, 95,247,119,235,183,190,247,177,191, 77,244, 42,224,209,114, 95, 93,183,232,119,183,196,245, - 29, 59, 16, 63, 12,178,167, 82,117,101,214,158,116,143, 5, 24, 90, 23,206,135,176,149, 30,171, 28,152, 67,133,148, 37, 68,130, - 72, 82,136,233,216,106,111, 20,187,199, 75,216, 78, 31,183,187,123,107, 14, 3, 11,107, 54,178,243,187,194, 90, 57,118, 69, 74, - 29, 37,232,118,227, 17, 80,181, 15, 26, 67,151, 45, 70,140,218, 83,159,252, 98,186,121,105,253,153, 86, 47, 7, 9,115, 32, 43, - 45, 41,124,222, 48,200, 88, 62, 39, 83,200,159,140,117, 57, 42,192,233,231,168,229,253, 33,126, 36,209,101,112,247,183,156, 51, - 81,166, 20,220,123,253,118,139,190,234,105, 14,114,189, 19,107, 54,170,107, 47, 14,101, 54,172, 24,245, 77,192,149, 76,140,166, - 92,229,230,106,223,125, 65, 36, 5, 99,118,157, 26,170,122,122, 52, 39, 85, 75, 0,125, 66,117,118, 29, 62,202, 6, 59,122,116, -190,198, 41,159, 87,166, 83,147,230, 89,163, 16,134,138, 38,100,189,183,152,128,144,169, 29,124,210,178, 41,223, 96, 73,219, 16, -244, 92,153, 82,150,236,202,131,161,234,140,247,159,157, 80,125, 32, 97,234,132,215,151, 38,107,224, 96,116, 92,167, 94, 87,207, -155, 66,172,131,211,207, 61,115,246,127,110,136,115,169, 29,135,115,161, 87,230,174,152,245,239,216,121,254,124,181,105,160, 0, - 11,108, 63, 45,182,199, 34, 42,236, 13,205,207,174,253, 14, 6, 86, 50,113,249, 63, 47,150,135, 81, 10,242,192,235,159,159,204, -250,104,133,250,130, 20, 72,252,244, 26, 21, 71,161, 62,125, 79,223,165, 20, 18, 70, 21,192,234, 32,117,249,224,103,231,246,124, -180, 51,131, 57,234, 1, 4,245,209, 90, 17,194, 14,122,247, 57,199,203,231,165,199, 81,129,129, 85,211,167, 82, 79,115,242,244, -199,166,116, 42,200,207,108,117,199,219,215,207, 68,185,242,238, 7,159,111, 95,223,160,150, 79,126,152, 61,193,243, 61,127, 63, -118,148, 65, 97,210,247,249,255, 0, 92, 12, 82, 36, 2,122,129,247,254,255, 0, 61, 45, 81, 95,235,119,242,252, 62, 95,159, 93, - 45, 31, 3,108, 86, 29,251,103,229,162, 52, 42, 87,219, 61, 15,145,199, 76,131,229,170,129, 68,158, 94,108,116,207,111,159, 94, -190,189,244, 71, 2,221,108, 70, 14,195,173,190, 63,195, 7, 54,123, 21,125,223, 63, 67,162, 7, 95, 35,246,121,232, 38,240, 58, -100,147,243,252,247,254,173, 22,149,245,244, 62, 94,126, 95,102,146,193, 58,116, 56, 41,161,203,212,156, 99,200,252,243,216,104, -214,200,243, 0,253,248, 39, 64,165, 89, 29,191, 17,231,231,131,157, 86,108, 20, 44,168,172, 16,172, 1,159, 47,179,238,210,109, -233,109,135,242,198,113,112, 10,193, 1, 67, 4,249,129,223,237, 35,243,215, 68,167, 3,168,200, 39,161, 29,191,102,122,118,208, -169, 81, 32, 12, 12,140,119,237,140, 1,140,143, 60,232,128,172,100,156,100, 96,228, 96,147,246, 99,229,253, 58, 79, 24,193,141, -168,119, 61,113,211,239,233,131,248,104,132, 28,224,245, 56,235,243,233,235,143, 45, 0,133,103, 3,168, 4,250, 14,255, 0,105, -213,126,108, 17,133, 41, 57,207,234,250,255, 0,195, 72, 55, 94,183,198, 45,251,240, 96,194,212, 65,206, 15, 99,156, 99,167, 83, -223,166,178,107, 86,133, 46,228,174, 83,168, 84,230,131,242,231,203,102, 43, 41, 89,195, 69,215, 20,122,190,224,255, 0, 37, 29, - 13,165,110, 56,175,230,182,210,136,235,140,226,141,149,172,148, 40,242,164,140,243, 0,115,229,231,167, 83,107,106,201,163,215, - 27,102, 59,168,106,161, 80, 68,168, 17,165,168, 14,120,254,244,202,121,148,223, 55,119,212,203,110,165, 63, 53,159, 44,231, 74, -177,164,138,154,105, 34, 0,200,138, 72,248,250,159,147,183, 77,240,231,146,208,195,153,231, 25, 94, 91, 81, 57,166,167,174,158, - 24,157,199, 85, 87,117, 86, 43,125,181, 16,108,183,219, 81, 23,218,248,222,138,101,205,111,109, 53,188,139, 14,206, 6, 92,185, -106, 97,219,158,165, 20, 33,169,181,218,147,105,229, 75,211,229, 39,172,106,107, 74, 42, 76, 88,249,229,105,177,148,165, 78,169, -197,168,202, 52, 58,189,201, 45,107,152,251,134, 43,136,241, 26,136,133, 56,212, 96, 73,206, 22, 82,160,183,187,255, 0, 56,129, -159,230,233,172,181,109,231,101, 77,113,174, 96, 84,151, 11,234, 90,143, 58,214,238,114,165,184,181, 28,173,106, 39,185,234,115, -211,167, 77,109, 61,163, 22, 44, 22, 27, 91,137, 83,171, 74,128, 82, 1,207,234,158,188,201, 56, 29,255, 0, 15,232,173, 43,102, -142,152, 57, 86,230,207, 39,153,152,245, 98,109,185,219,238, 30,131, 97,176,176,238, 92,135,135, 96,160,165,130,158,154,139,217, -233,169,194,164, 80, 40,217, 20, 91,173,247,102, 39,119, 98,117, 51, 18,204, 75, 18,113,157, 88, 27, 77, 6,162,243, 10, 91, 45, -173,210, 17,204,134,249,192, 79, 80, 63,214,237,246,249, 13,116,123, 98,182, 58, 4, 74,205, 30,167, 79,136,195, 21, 8,242, 27, -109,110,132, 5, 41, 73, 87,235,167, 43, 4, 56,130,140,228, 96,131,208, 99, 90,225,182, 40, 67,142, 48, 16,148,176,211,139,108, -165, 13,164, 41,196,146, 1, 0, 28, 0,122,103,200,227, 93, 65,218,186,205,175,107,194, 23, 45,203, 58, 29, 22,218,182, 96, 72, -174,220,149,170,131,237,177, 22,155, 74,165,199, 84,185,211,101,200,116,132,182,210, 35, 52,242,142, 78,112,156, 0, 78, 6,171, - 12,238,173,234,222, 88,228,156,164,106, 9, 35,215,160, 2,195,177, 61,189, 58, 92,224,103,185,230,105,150, 32,167,167,102, 26, -193, 82, 7,165,183, 6,219, 90,219, 1,190, 56,205,197,103,181,207,127,173, 13,203,184,118,215,133,170,141, 31,104,108,203, 18, -227,169,219,114,110, 38,173, 59,114,175,120,222, 85,138, 12,199, 41,181,154,156,153, 53,154,123,241,232,148,133, 84,163, 74,110, - 60, 86, 88, 82,220,105,176,227,238,146,190, 68,232,182,233,123, 64,184,141,223,154, 60,154, 6,249, 57,181,123,167, 78,146, 84, -227, 18,107,187, 67, 98, 81,110, 42,116,165, 0,145, 34,159,117,218,148,120,114, 99,114,227,163,101, 42, 70, 84,115,229,173, 86, -221,155,170, 61,231,185, 27,133,121, 69, 66, 4, 43,174,251,188, 46,104, 37,150,148,210, 87, 78,184, 46,106,173, 86,152,226, 26, - 95, 86,138,160, 76,140, 84,147,241, 37, 74, 32,128, 65, 26,194,202,138, 27, 72, 66, 66,146,164,249,147,216,250,231,207, 87, 69, - 31, 7,240,224,142,134,170,163, 33,165,108,202, 5, 70, 19,180, 17,154,132,144, 1,186,205,167,154,132, 27,219, 75, 46,158,139, -101,216,113, 46,113,196, 25,150,101,152,213,213, 75, 88,211,164,146,185, 69, 33, 74, 4,212,116, 0, 45,109,150,194,253, 77,174, -196,146, 78, 25, 29,226, 14, 57,121,205,113,232,130, 3,142,211,225,184, 35,161,210,251, 60,158, 24,194,153,113, 74, 39,194,232, - 48, 51,240,246,211,245,236,251,162,194,185,248,143,179, 45,121, 83, 19, 21,250,213,203,107,181, 9,165, 71,118, 87,191,186,213, -102, 27,130, 3, 81,152, 66,148,243,239, 41, 41,105, 3, 24, 5,238,101,124, 41, 58,101,247,161,159, 22,181, 69,168, 39, 42,110, -109, 13,166,193,234, 48,228,124, 36,164,245,239,145,174,129,251, 9,174,186, 5,165,237, 66,225,233,203,134,153, 75,169,179, 93, -122,232,183,105,102,171, 29,185, 77,211,107,245, 27,114,161,245, 77, 90, 19,110,130,148, 84,153,121,149, 6, 86, 70, 82, 94, 37, - 63, 16, 4, 76,106,145,166,225,202,216,163,115, 19,154,118, 0,141,244, 17,182,175, 48,111,179,107,216,131,211,124, 55,240,245, - 50,102,121,237, 29, 36,238, 33, 74,218,128,140, 64, 27,115, 13,172,189, 64, 38,246, 91,130, 3, 17,112, 70,216,253, 60,108,203, -170, 61, 38,218,163, 69,169,210,215, 6,123, 52,168, 12, 42, 18, 30, 74,149, 13, 45,197,109, 30, 2,136,232, 84,156, 96,142,195, - 24,211,173, 99,205,135, 95, 67,163,195, 82,216,105,226,174, 71,124,148,149, 2, 51,235,129,141,105, 44, 90,227,175,203,110, 58, -159, 60,234,145,200,227,139, 86,113,133,225, 74, 81,201,236,156,159,187,231,170, 28, 4,113, 50,246,254,220,188, 78,211, 27,167, -174,157, 67,217,253,200, 98,198,160, 62,226, 84,149,213,154,110, 59,134, 85, 65, 74, 80,193, 38, 67, 46,128,145,156, 36,167, 56, -206,171,117,160,130,138,122, 97,237, 82,206,210, 2,164, 74,193,245,233, 0,234, 42, 2,170,144,127,100, 1,189,173,233,213,116, - 57, 94,103,152,229, 89,246,102,140,213, 17,228,201, 12,179, 73, 36,128, 58, 9,234, 18,153, 52, 40,182,162,210, 72,183, 8, 0, - 85, 5,141,128, 24,234, 84, 22, 97,190,160,211,140,160, 37, 73, 9, 37, 39,151, 35,203, 4,118, 61, 53,114,153, 78,153, 71,107, -235, 40, 14, 61, 50,158,222, 60, 88,104, 36,186,207,108, 43,161,248,155, 29, 63, 29, 97, 20,201,202, 47,103,152,116,235,202, 79, -126,158, 94,167,229,242,211,203,110,200,247,142, 86,186, 45, 43, 28,139, 74,199, 69, 36,140, 40, 28,142,185,211,232,142, 26,149, -210,124,143,250,172, 54, 32,246,233,212,123,143,108, 87, 57,193,168,203, 88, 74,126,186, 30,174,140,110, 24, 27, 95,115,186,183, -163, 11, 88,251,182, 38, 90,149,147, 81,103, 43,113, 42, 36,101, 41, 4, 97, 63,236,131,246,106, 57,159, 74,191,116, 98, 90,254, -207, 59, 39,109,189,229, 13,212,183,107,126, 44,232,173, 70, 10, 79,139, 34,151,103,194,170,220, 21, 37, 33, 4,228,182,151, 83, - 3,152,129,211,196, 79, 81,158,178, 30,102,146,109,219,145, 41, 96, 40, 65,169, 43,197,142,145,209, 8,117, 68, 7, 25, 3,237, - 80, 32,127,181,168, 24,253, 41,190, 42,105,187,177,198, 54,217,240,225,110, 85, 81, 54,139,195,101,145, 34,125,214,152,206, 7, - 99,181,184,187,128,182, 37, 59, 9,124,170,199,189,197,183, 98, 83,146,176,122,161, 83, 8, 58, 74, 58,202,145, 17,201,101, 26, -102,168,170,131, 88,244, 90,105, 22,173,158,223,176,226, 5,136,155, 90,243, 32,234,192, 98, 1,158, 71, 76,139, 85, 95, 79,189, - 36,176, 18,155, 91,205, 48,228,232,235,246,147, 91,189,183, 39,148,198,196, 2,113, 23,105, 12,224,142, 92,114,128, 57,115,230, - 60,193, 31,158,218,166,220,116, 96,148,167, 35,185, 0, 30,135,231,131,219, 70, 58, 91,112,228,147,129,219,200,129,212,245, 26, -163,239, 1,162,164,182, 58, 16, 2,148, 48,123,246,233,248,234, 69,123,110, 78,199,253, 49, 95,238,192, 91,182, 41,184,218,146, -112, 2, 85,145,205,128,115,240,232,117,175,166, 2,185, 84,122,144,123,252,146, 48, 58,249,126, 26,246,165,183,205,207,226,242, - 41, 68, 0,146,160, 57,188,186,141, 8,236,164,182,248, 10, 66, 79, 40,192, 24,234, 78, 51,205,246,235, 5,182,178,131,140,233, - 61,206, 62, 37, 37,100,130, 84,143, 85, 20,247,251, 9,215,196, 52,218, 22, 28,108, 23, 20, 73, 10, 73, 32, 16, 58,117, 3, 29, -117,111, 83,203,146,247, 41,116,161,190, 96,162,140,245, 64, 79,113,246,247,209,173,134,220,112, 58,130,174, 68,156, 21, 96,167, - 56, 29,142,124,186,235, 23, 38,226,214,237,108, 24, 0, 8,223,231,108, 84,202, 80,181, 45, 75, 37, 10,236,140, 14, 84, 19,208, - 21, 19,249,206,145,240, 91, 89, 35, 4,168, 2,181, 39, 36, 1,143, 63,207,219,175, 14,180,248, 91,135,225, 44, 44, 19,203,230, -113,158,202, 35,190,147, 72, 75,188,184, 10, 97,180,167,149, 94,101, 68,116,193,200,235,219, 67,113,176,234, 62,253,255, 0,241, -140, 88, 27,158,199,247, 99,223,138,128,176, 16, 74,202,192,200, 64,234, 51,216,159,151,174,144, 56,112,168,255, 0,226,210, 65, - 39,211,169,193, 30,191,219,161,201, 91, 97,101, 11,229, 33,124,169,112,164, 97, 67, 25, 41,193, 29, 62,221, 18,149, 30, 64, 28, - 41, 83,138,201, 81,233,203,131,211, 7,167, 95,158,178,160,129,238,248, 99, 4, 11,219,211,111,159,187, 23, 91,122,216,174,223, -151, 45,171,103, 91, 30, 48,173, 94, 23, 45, 2,211,161,169,134,124,101,166,185,117,214,160,219,116, 71, 18,206, 63, 72,148,213, -170,176,202,135,110, 84,156,234,116,188, 70, 90, 86,214,200,237,141,191,195,253,145, 22, 45, 26,196,217,203, 30,212,219, 59,118, -140,216, 15, 52,105,182, 85, 52,210,220,144,228,146, 7,188, 57, 58,187, 14,173, 81,121,213,101,199,100, 86,221,117,213, 5,175, - 81, 5,246,122, 41,151,120,231,225, 49,165, 45,167, 25, 70,253,237,171,138,109, 68, 6,138,152,185, 35, 72, 66, 58,164,128, 60, - 86, 81,140,142,248, 24,212,167,184,174,185,213, 80,146,133, 73, 46,189, 42,116,101,176,243,171,116,136,206,165, 92,181, 24,242, - 29, 66,122, 56,175,137,244, 12,128,174,102,202,115,202, 19,170, 83,197, 9,101,168,206,184,107, 46, 36,242, 99,215, 57,177, 27, -176, 33,119, 7,246, 0,242,159,241,145,183,126,148,250, 56,229,176,205,157, 87,230, 36, 3, 52, 82, 67, 18,237,186, 42,142,113, - 96, 78,222,114, 22,253,238,138, 65,198,134,236,221,125, 48,227, 85,230, 51, 33,182, 20, 46,139,193, 78, 71,146, 11,172,173, 49, -107,213, 39, 22,218,176, 65,104, 45,181, 17,240, 28,231, 10, 57,192,214,224, 91, 87, 56, 52,186,124, 87, 37, 60,195, 17, 27,114, -181, 86,168, 52,165, 33,208,211,232, 84,135, 35,180, 82,172, 45,194,149, 57,206, 62, 17,225,181,156,149, 19,174,110, 88, 21,191, -119,114,244,165,183,202, 67, 27,155,118,199, 87, 58,178, 4, 89, 50, 96,212,208,176,140,117, 30, 4,208, 18, 6,122, 47,168, 24, -193,216,148,220,233, 17, 19, 8, 58,234,126,185,152,195,115,214,218,208, 94, 77, 49, 13,178,244,133,248,196, 0,223,193, 29,180, - 33, 36,116, 68,133,242,242,101, 71, 81,250,188,185,106, 15, 67,113, 99,239,183,107,245,232, 9,183,107,219,224, 58,227, 63,165, -142,190,158, 48, 77,158,254, 98, 55,217,118, 36, 14,246, 5,200, 7,112, 64, 22, 35,166,219,210, 47,185, 82,233, 80,131,107,114, - 60,217, 83, 30,159, 55, 1, 97, 10,126, 99,143, 59,200, 93, 39, 36,248, 79, 52,216, 74,146, 85,208,149, 28,227, 87, 58,150,229, - 67,154,202, 4, 96, 35, 72,171, 77,110, 44, 73,100, 36,180,229, 58,157,136,136, 91,136, 10,230,111,157,193, 37,215, 17,208,101, -244,168,228,117,214,181, 64,187,158,122, 93, 82, 99, 15, 54,251, 37,214,153,128, 31,117, 72,105,199, 39,177,225, 23,146,164,156, - 48,194, 20,135,157, 91,128,140, 41,148,243,100, 17,156, 82,117,230,220,185,110, 46,150,234,204, 86,210,213, 38, 18,207, 68,178, -246, 20,194,221,232, 57,159, 45, 69, 67,133, 75, 72, 8, 74,217, 4,243, 28,107, 65,114,134, 28,192, 19, 72,150,215,216,116,216, -247, 29,143,240, 35,215, 20,246,103,146, 44,245, 78,252,176,174,237,171, 80, 54,208, 8, 14, 67, 30,182, 4,169, 0,130, 8,141, -150,215, 27,108,165, 82,240, 65, 91,130, 60,226,182,132,167,101,192,151, 29,238, 83, 25, 20,197,120, 81,158, 74,218, 87,253,240, - 30, 74,156, 5, 56, 40, 82,144, 70, 78, 52,237, 90, 94,211,206, 31,238, 61,215, 87, 13,251,187,120,211,246, 99,125,216,166,219, - 53, 27, 46, 70,225,213,169,180,173,188,223,218, 29,126, 20,116,211,238, 11, 14,254,117,214,224,219,183,114,235, 2,165, 77,157, -110,215,151, 5,255, 0,172, 41,143, 26,124,233,201, 95,132,215, 47,235,155,134,253, 49,169,137,139, 33, 17,217, 13,120,112, 82, - 15, 49,240, 35, 44,163,195,112,169, 32,252,110,120,100, 14,255, 0, 6, 84, 78,117,197,111,105,134,220,238, 93,231, 65,219, 45, -247,167,109,213,197, 90,217,251, 58,155,114,237,149,225,186, 16,105,102,169,111,209,111, 26,133,206,237,223, 6,220,186, 37, 68, - 46, 57, 71, 74,105,117,120,239,199,126, 99, 76,195, 90,234,170,101,153, 10,125, 14,182,139, 3,128,178,227, 14,113,200,102, 49, -197, 94,146, 41, 26,186, 58, 14,100, 76, 1, 54,102, 4, 50,105,239,205,107, 48,109,241, 25,226,106, 58,222, 29,225,154,236,230, -154,152, 85, 54, 88,209,177,136, 41, 60,216,218,101,137,193, 42, 24,198,232,143,175, 85,138,168,137,139, 93, 73, 6,112,183, 37, - 78,163, 2, 75,208,150,135,161,212, 82,216,153, 17,169,141,173,151,176,166,195,172,115, 50,232, 25,142,243, 42,192, 88,248, 20, -135, 67,169, 82,146, 1,214, 30,110,102,229, 6,164, 37,229,248, 15,167,153, 14, 21,167,199,131, 45,149, 41,178,218,193,232,133, - 37,208,234, 20,133, 14,138, 74,146,161,200,172,136, 53,240,131,237,106,226,159,133, 24, 84, 59, 53,218,219, 59,239,178, 52,133, -176, 33,109, 62,233,213, 42,115, 87,110, 83,210, 19,207, 27,108,183, 21,133,187, 86,176, 89, 90, 16,222, 98,161, 83,232,235, 9, -248,233, 74,207, 48,145,223, 13,254,212,238, 15,184,152,159, 78,162,209, 47,183, 54,118,249,175,188,219, 14,237, 94,249, 74,164, -218,245, 37, 92, 79,169, 49, 99, 27, 63,112,216,112, 91,183,164,105,106, 74, 80,226, 84,253, 38,123,107, 83, 14,125, 94,162,183, - 66,108,186,204,183, 48,166,102,149, 71, 62,156, 30,169,168,233, 30,174,159,105, 0, 23, 14,192, 50,168, 43,245,131, 77,196, 95, -135,248,215,135,243,244,142, 40, 42,125,147, 48, 63,251, 60,246, 73, 9, 31,170,141,253,220,164,236, 80, 35,107,102, 86, 28,176, - 93, 65,235,149, 54,227,231, 82,252, 98,143,120,111, 30, 50, 3,153, 10, 74,242,148,190,207, 95,141,149, 1,219,201, 64,160,158, -157, 92, 10, 45,120, 41, 72, 30, 42,210,211,129, 60,138, 36, 39,194, 40, 56, 9,201,199, 34, 15,194, 82,125, 71, 47, 98, 51,173, - 78, 57, 42, 4,150,225, 74, 68,136, 85, 24,204, 38, 66, 27,148,194,153, 91,140, 60,112,210,188, 53,165, 42, 92, 71, 18,144, 65, - 31, 2,199, 43,141, 41, 93, 9,204,232,245,213, 45, 41,192, 82, 28, 24, 15, 5,245, 67,125, 1,240,211,143,214, 37, 36, 97, 93, -148, 8, 56, 7, 58,212, 89, 53, 45,155,126,155,250,244,189,247,220,131,214,195,222, 7, 80, 36, 83, 0,111,109,143, 66, 55,176, -233,219,176,244,244,232,113,182,208,103, 41,109, 2,130, 8, 28,170, 10, 7, 24, 72, 25,194,155, 35,170,130,179,216, 16,115,215, - 3, 58,111, 43, 10,114,143, 57, 62, 8, 83,116,247,138,158,104, 35, 42,247, 7, 50, 75,237, 35, 36,226, 62, 87,206, 17,241, 16, - 21,132,140, 32, 1,125,182,231,180,168, 76, 58, 9, 40, 84,116,130,133, 30, 98,133, 5, 4,164,144,145,213, 29,122,131,213, 61, - 0, 36, 29, 13,118, 6,157,142,165,164,161, 74, 66,131,137, 36, 16, 75,137, 11,198, 66, 58, 1,225,133,117, 7,177,199, 76,105, -179, 52,167, 21, 20,206, 20, 94, 88,188,203,247, 14,159,247, 13,175,219, 99,141,204,138,188,229,245,233,172,222,154,164,132,144, -123,143, 71,223, 96, 84,155,244, 59,106, 94,135,127, 84,218,177, 40, 8,109, 77,171,152, 21,173,176,163,224,169, 71,153, 72,125, - 10, 73,232,160, 71, 80,122,228,147,140,224,235, 37,102,160, 10, 82,164,185,132, 45, 57, 74,215,202,149, 96,228, 37, 5, 93, 73, - 30, 65, 68,115, 96,128, 73,233,134, 98,157, 41, 13, 56, 75, 78,101, 30, 32, 41,200, 60,139,109,106, 31,174,223, 79,137, 36, 30, -189,207, 76,140,117,214, 72,221,101, 45,182,162,165, 36, 32,100,243, 41, 75, 81, 70,115,204, 0,245,193,235,219, 60,157,117, 24, -134, 67,166,254,131,225,214,223,195,240,185, 63, 9,141,122, 6,118, 85, 58,239,247, 92,246,191,191,212,255, 0,166, 51, 26,229, -207, 71,161, 82,171, 21,250,253, 86, 21, 10,222,160,210,170, 53,218,245,110,162,164,183, 78,161,208,104,176,228, 85, 43,117,153, -206, 45, 73, 9,137, 18,151, 18, 91,238,228,225, 72,142,160,158,165, 57,252,241,248,236,226,198,175,198,143, 19,187,139,190,210, -211, 34, 37,167, 54, 67, 54,134,209, 80, 36, 40,149, 91,187, 67,106, 59, 42, 29,153, 29,224, 82, 63,247, 86,123, 78,203,172, 84, - 21,128,163, 54,224,117, 10,232,210,117,219,143,110, 55, 31,168,247, 9,220, 13,237, 45,117,106,153, 60, 65,155,196,245,118,153, - 33, 73,250,186,148,129, 22,167,110,108,123, 50,218, 88,204,249,174, 8,181, 59,157,180,158,102, 99, 49, 2,144,247, 42,222,154, -216,140, 58,201, 42, 87, 55, 92,245, 24,242, 62, 93, 51,208, 99, 86, 23, 10,101,174,168,115, 74,133,179,204,161, 98, 4,110, 35, -184, 38, 79,255, 0, 83,109, 63,224, 1,129, 34, 76,115,135,139, 28, 75, 29, 69, 68,124, 51, 69, 46,168,168, 95, 93, 91, 41,184, -105,192,178, 67,126,252,133, 36,200, 55,250,214,208, 64,120,119,164,226,207, 66, 6, 58, 99, 61,253,127,110,168, 40,146, 14, 79, -145, 3,176,234,117,236,175, 32,140,119,245,254,173, 14,178, 50, 7,166,115,251, 53, 54,197, 56, 6,195,215,223,143, 26, 25,222, -163,190,112,127,103, 95,199,190,136, 80, 4, 28,249,117,233,242,208,171,236, 62,223,191, 74,170,144, 55, 30,252, 27, 3,172, 12, - 19,233,219,241, 26, 21,194,122,100, 96, 15, 50,122, 99,167,203, 68, 45, 88, 7,168,198,127, 12,119,207,207, 39,246,104, 39, 14, - 65,238,122,244,207, 92,117,243,209,240, 49, 73,194,122,158,135,167, 78,221,191,225,160,214, 70, 49,230,127,175, 85,214,124,179, -246,254,237, 12,162,115,131,131,230, 15,203, 74,168,176, 3,231,255, 0, 56, 24,164,161,156,124, 57,251,241,165,175, 42, 81, 4, -128,123,105,104,248, 61,215,161,234, 61,195, 9, 4, 17,131,140,142,223,159,183, 85, 65,193, 7,254, 56,208,233, 56, 57,252,117, - 84, 28,245,242,237,243,207,245,104, 16, 14,221,176,115,176,176,216,246,251,173,130,144,113,212,117, 31,209,147,251, 52, 64, 81, - 7, 3, 57,199, 92, 12,227,237,208,169, 35,151, 56,237,220,122,227,174,171,161, 97, 64, 96, 17,233,247, 31,233,206,144, 35,125, -251,225, 50, 15,218,181,186,127, 44, 28,217, 61,137,207, 79,219,211, 69,160,115, 4,228,115, 96,228, 12,227,183,110,191,142,129, - 66,176,164,143, 53, 1,246,117,209,136, 61,199,167, 81,162,144, 13,182,219, 5,193,232, 56,201, 61,187,103,231,233,170,157, 57, -128,201,237,219,190,122,158,195, 61,244, 58, 14, 70, 85,219,229,220,254, 78,137, 78, 6, 9,248,142, 58, 30,199,229,215, 73,176, - 32,251,176, 49, 85,178, 80, 71, 49, 24, 29,179,128,122,159,234,206,170,161,228,172,227, 5, 63, 51,208,106,130,129, 57, 36, 12, - 43,246, 12,103,250, 53,245, 33, 41, 28,169, 39,168,200, 39,169,243, 62,154,215,113,110,214,192,193, 69, 75, 80, 41, 11, 40, 72, -242, 79,235, 44,117,198, 14,142,138, 84,193, 74,208,181,165,208, 82,164,172, 44,165,214,212,133, 5,182,227,107, 79, 84, 56,149, - 0, 82, 71,108,122,116,213,184, 21,116, 32, 12, 36, 16,175, 92,121, 99,240, 58, 41, 11, 82,192,198, 50,156, 1,158,159,143,207, - 73,144, 8, 32,238, 14, 5,200, 32,131, 98, 8, 32,251,198,227,247, 28,108, 53,141,190,213,107,108,134, 43,180,182,171,204,124, - 41, 19, 35, 60,136, 85, 18,145,128, 11,205,175, 13,186,160, 60,210,164,149, 28,156, 13,108,141,181,197, 54,220, 70, 82,197, 66, -151,116,195,121, 72,202,146,221, 49,185,109,229, 32,244, 75,141, 75, 60,221,199, 95, 93,115,201, 4,164,124, 94,189,207, 82, 7, -168,253,186, 37,176, 66,144, 22, 84,164,142,169, 32,227,161,236, 8,243,244,251,245, 28,174,225,188,174,181,153,164,137,162,103, -235,203,114,160,244,191,151,117, 31,114,140, 91,121, 55,141,220,125,147,211,199, 74,107,169,243, 88,225, 80,170,107, 41,214, 89, - 52,139, 90,242,161,142, 87, 35,177,119,115,110,248,235,133,191,199,206,218,219, 45, 52,170,125,157,118,214,229, 55,146,132,186, -136,148,166,213,201,219,244,179,102,224, 18, 71,250,170, 3, 29,180,196,241, 5,199, 86,232,111,197, 1,251, 8, 50,221,147,182, -143, 56,211,211,237, 58, 60,167,100, 74,185,156,140,226, 94,138,213,215, 87, 83,109,251,229, 61,183,144,219,158,226,195,104,140, -227,141,161,111,151,249, 82,145,162, 3,148,130, 92, 5,192, 20, 20,148,231,148, 55,212,227, 4, 14,186, 61,162, 86,176,146,225, - 80, 56,228,194,113,201,219,161,207,235,116, 56,211,117, 47, 5,112,245, 21, 84,117,201, 69,207,170,132,134, 71,149,218, 77, 12, - 8, 33,149, 73,229,134, 82, 46,173,163, 82,145,169, 72, 32, 28, 53,241, 15,138,188, 97,196,116,243, 82,213, 84,195, 69, 77, 80, - 10,200,180,176, 44, 69,212,245, 83, 35, 25, 38, 10,219,134, 85,145, 85,193, 42,192,169, 32,158,135, 75,235,241, 20,165,243,156, -130,149,228,227,191,234,252,191,175, 69, 53,226, 20,169,146, 9, 42, 80, 87, 50,134, 0, 79, 79,192,118,208,142, 44, 52,130, 84, -175,137, 56,248,146, 49,143, 64,122,117,233,170,145,222, 81, 66, 66, 73,248,178, 73, 87, 82, 79,108, 12,246, 29, 53, 36, 61, 54, - 29, 62, 70, 43, 94,183, 35,123, 91,175,205,241,136,238,148, 54,166, 91, 20,250,139, 88, 47,209,166,170, 59,233, 79,254, 76,255, - 0, 80,172, 99,160,230, 39,240, 58,198,120,103,221, 57,187, 25,196,150,199,238,244, 21,134, 94,176, 55, 62,210,175,186,181, 28, - 15,112,143, 87,142,138,146, 84,113,217, 84,215,101, 39,255, 0,165,167,117,218,108,106,205, 62,177, 68, 90, 2, 93,157, 79,120, -165, 71,245, 68,134, 82, 86,218,243,228,123,254, 61,245,167, 85, 38, 11,109,188,210,135,233,152, 91,140,184,160,122,120,145,212, - 83,145,142,255, 0,171,251,117,187, 66, 18,104,170, 41, 36,251, 18,234, 83,255, 0, 68,162,196,254,253, 93,251,227, 20,149, 82, -101,249,133, 45,100, 91, 73, 4,145,202,189, 62,212,108,174, 63, 16, 49,250,180,211,238,200,245, 37, 67,171,211,156, 15,194,174, - 65,129, 89,167, 45, 4, 20,189, 10,173, 21,153,145,214,133,121,160,178,242,122,249,231,190,180,239,217, 89,188,242,168, 28,101, -113,223,195, 53, 74,165, 21,248,241,110,200, 59,151,105, 48,148, 54,212,150, 99, 85, 66, 25,171, 70, 90,211,133, 72, 8,121,198, -149,215, 37, 35, 61,129,214,138,112,241,237, 18,181,246,247,217, 85,195,199, 23, 55,221,185, 92,188, 87,110,170,222,216,155,158, -135, 70,113,168, 85, 74,133,213, 66,154,237,182,137,209,228,212, 2, 90,247, 81, 18, 12,119,150,178,172, 40, 40,165, 36,172, 99, - 92, 76,225,195,218, 43,112,108,191,180, 68,241,163, 87,137, 53,218, 13,213,121, 85, 13,251,109, 69,117, 79, 59,252, 93,220,210, - 61,214, 85, 57,148,140, 9,179,169,240, 12, 87, 90, 24,253, 35,176,207, 39, 85,140,213, 94,201, 95, 89, 89, 81, 50, 68, 88,229, - 41, 44, 77, 97,114,211,137, 33, 50, 70,130,251,177,141, 24, 11,126,210,130,124,216,234, 92,247,139,178,110, 30,135,135, 86, 26, -240,171,156,212, 69, 53, 68, 96, 18, 70, 89, 60, 14, 18, 89, 46, 45,161,102,104,166, 0, 18,247,167,107, 0, 6,255, 0,166, 5, - 42,103, 57, 65, 82,185, 64, 32,133,247,194,134, 58, 28,253,191,183, 79,189,167, 40,130,133, 15,136,130, 15, 48,207, 92,244,234, - 62,127,191, 90,215,182,213,122, 45,249,108, 90, 55,197,175, 49, 85, 11, 94,248,160,211,110, 91,114,123,145,228,195, 92,170, 77, - 82, 51,114,163, 41,232, 51, 90,109,232,174,134,220, 0,165,196, 37, 67, 29,181,181, 22,173, 32,176,218, 22,172, 0, 58,144, 15, - 48, 35,161,232, 51,211,182,149,165,204, 0,210,250,182, 96, 8, 55,216,131,107, 17,234, 8,177, 7,208,223, 12,252,106,244,209, - 69, 44, 79,229,112, 89, 74,158,160,131,165,148,142,161,131, 2, 8,234, 8, 32,216,139, 99, 84,189,166, 92, 73, 94, 92, 36,240, - 71,190, 60, 72,109,253,170,139,190,243,218,251, 81,202,181, 6,152,247, 63,185,197,151, 53,246,105,136,172, 84, 2, 7, 50,224, - 67, 84,180,200,117, 35, 4,165,140, 2,158,227,242,123,220, 13,193,188,183,102,246,187, 55, 70,255, 0,174,202,185,175,125,193, -184,106,119,117,217, 95,154,225, 92,154,165,106,179, 33, 82,165,200, 61,127, 70,202, 74,130, 26, 64,248, 91,109,180, 33, 32, 37, - 35, 95,176,103, 17, 91, 65, 79,226, 3, 96, 55,155,100,106, 73,104,195,221, 29,180,188, 44,162,167,194, 11, 49,228,215,104,147, - 33, 65,146,176,160, 71, 43, 83, 28, 97,207,145,107, 58,252,126,111,173,183,174,109,101,223,114,237,205,200,243, 14, 87,172,107, -134,183,104, 86, 21, 21,196,191, 31,235, 27,118,163, 34,153, 41,108, 62,142,143, 50,181,199, 42, 74,135,250,248,242,211,205, 11, - 23,205,103,169,168,185,146,170,158, 46, 83,159, 68,102, 90,132, 67,211,202, 69, 43,202,122,183, 50, 37, 98,121,105,106, 87, 55, - 74,198,201,233,231,141, 79,232,234, 57,204, 82, 16, 6,132,158, 85, 50, 83,153, 27,174,169, 99, 74,129, 10, 55,149, 68, 19,180, -118, 47, 41, 56, 67,100,168,171,151,155, 61, 79, 95, 60,122, 15, 61, 35,130,164,243, 43,195,200,232, 85,144,149, 30,190,103,160, -235,163,138, 10, 81,148,161, 61, 1, 57,207,196, 1,237,229,215, 58,179, 73, 73,100, 1, 32,169,109,175, 10,108,133,117, 65, 61, - 64, 35,211,190,164, 33, 71, 78,184,138, 6, 12,221,108,127,211,249, 99,203,205, 18,188,146,148,164, 30,157,114,114, 49,212,122, -121,235,227,237, 45,212, 2, 7, 84,167,184, 57,230,251,255, 0,214,210,105,196,231,225,201, 72, 78,112, 71,161,193,239,249,235, -162,163, 54,227,231, 9,229,102, 56, 25, 86,126, 37, 18, 58,142,158,154, 26, 64,223,165,177,147,211,115,112, 58,252,252,223, 22, -213, 70,117,150,146,176,201, 81, 88,230, 39, 35,152, 1,253, 61,115,159,248,104,168,146,144,231,232,202,255, 0, 85, 56, 40,229, - 0, 30,157, 78,124,245,114, 83, 5, 65, 72, 11,202,122,142,131, 4, 30,196,245,208, 41,136,220, 55, 57,130, 80,160,172,229, 74, - 5, 71, 24, 57,192, 61,188,255, 0, 13,102,195,174, 10, 13,246,245,219,231,231,243,194, 75,106, 66,138,139,202,121, 62, 73, 39, - 41, 64,244,249,235,195,175,165, 29, 16,164,129,215, 3,176, 10,244,237,242, 58, 13,247, 86, 20,162,210,241,205,219, 9,199, 76, -118, 57,252,252,244, 57,121,183, 22, 18,162,114, 8, 46, 36,167,166,122, 30,132,122,147,160, 1, 61,122,224,218,109,176, 59,124, -252,244,193, 73, 62, 42,249,210,160,160, 6, 10, 58, 4,243,117,237,215,174,169,202,116,144,148,163, 9, 35, 41,232,112, 73, 35, - 26,244,226,149,225, 44, 52,218, 83,202, 50, 6,112, 73, 3,166, 20, 60,186,106,200, 38, 56, 22,159, 25, 41, 42, 74,136,229, 35, - 39,237,230, 7, 25, 25,253,154,205,172, 79, 99,140,129,115,240,254,120,124,184,115,189,156,218,173,243,217,253,196,140,226,154, -114,201,221, 29,189,186,157,144, 2, 28, 76,104,148, 91,202,137, 62,170,234,144,226,146, 10, 19, 71,106,164, 78, 72,192,235,229, -214, 89,252, 84, 79,135, 38,165, 91,167, 64,144,125,222, 21, 90, 83,212,194, 9,203,148,103,102,202,149, 75,147, 29,226,231,198, -199,134,165,180, 86,174, 83,250, 48, 82,145,204,117, 12,134, 36, 32, 58, 89,144,219,141, 68,148, 28, 97,215, 25,112,135,124, 41, - 13,150, 30, 13,148,156,182,191, 13,197,224,142,160,224,143, 93, 73,106,193,222, 9,123,221,195,158,213,110, 37, 84, 5,220,177, -173,145, 99,221,170, 9, 90, 82,245,211, 97, 33,139, 66,186,235,106,113, 41, 18, 89,144,221, 38,151, 80,109,206,169,241,170, 79, - 3,133,165, 68,213,126, 32,229,133,243, 12,131, 53, 81,228,136,205, 3,157,175,169,213, 36,139,223,107, 71, 40,244, 5,135, 82, -109,142,146,250, 55,230, 49,199,158,230,217, 92,205,165,166,142, 42,152,199,111,171, 99, 12,173,241,188,212,235,255, 0,117,239, -229,177,215, 10, 45,116,211,119, 43,112,233,170, 37,182,230, 76,183, 43,177, 16, 48, 67,141,212,104,203,167, 84, 84,210, 85,250, -200,247,186, 39, 42,135, 76,169,127, 17,201, 25,126, 41,181,229, 37, 94,246,130,227,139, 83, 98,158,134,210,180,160,134,139,132, -169, 8,228,234, 57,157, 60,196,119, 33,160, 58, 3,173, 54,220,106,162,232,187,147, 64,173, 32,128,221,114,157, 86,182,101,168, - 2,112,236, 98,110, 58, 71, 42, 0,200, 82,156,139, 85,108,168, 12, 37, 47, 14, 99,215, 89,237, 42,241,122, 42, 89,121,149,120, -143, 68,240,228, 71, 67,193, 97, 42,112, 20,248,104, 82,146, 14, 81,149, 36, 43, 61,130,149,202, 79, 77, 54,154, 98,201, 79, 48, - 93,157, 23,215,245, 64,140,254,242,183,247, 3,113,214,216,234,185,107, 85, 90,190,153,200,103,134, 73, 8,185,181,196,141,207, - 0,122,217, 95, 77,199,166, 54, 18,161, 94,151, 79,143,238,201, 90,156, 74, 11,144,195, 67, 45,167,222,100,242,185, 41,107, 79, - 47, 68,161,128,211, 94, 17, 4,143,139,237,214, 33, 94,188,163, 65,166, 48,194, 95, 91,117, 54,202,144,132, 54,165,128,183, 95, -199,188,184,162,159,133, 33, 12,114, 39, 3,184,113, 99, 62, 90,108,110,125,200,155, 57,192,243,237, 54,135, 98, 37, 65,105,104, -184, 83, 38, 67,170, 74,157,117,106, 82, 65,231, 43, 42, 36,158,164, 28,103,182,152, 91,179,113, 22,203, 82, 31,144,227,141,177, - 29,133, 60,243,188,138,117,126, 27,202,229, 79,134,132,140,173,213,186,224, 64,230, 35, 28,249, 82,146,156,168,109, 83, 80,180, -133, 70,155,131,247,250, 91,173,253,215,233,123,143,190, 31,153,230, 40,116,234, 94, 76,155, 11, 13,199,112,250,136, 0, 48,181, -193, 30,164,142,215, 14, 21,209,121,205, 91,172,198,128, 37,214, 37,203,151, 18,147, 71,162, 69, 74,158,159, 91,173, 84, 31, 76, - 74, 61, 38, 10, 82, 57,149, 46, 76,199,210,132, 36,116, 79,141,204,122, 13, 72,111,103,182,153,253,140,217, 59, 59,105,234,166, - 43,245,214, 40,146,102,238, 75,165,136,243,169,213, 75,230,241,120, 86, 47, 54, 36,211,230,178,227, 21, 26, 75, 53, 55, 26,167, - 24,207,180,236,119, 35,210, 16, 22,218,146,117, 21, 91, 99,137, 58,134,192,111, 54,211,110, 76,122, 84, 42,181,197,100,221,246, -174,224,205,167, 84,216, 19,169,212,123, 66, 37, 89, 42,151, 77, 97,181, 39,195,159,114, 79,128,212,245,169,240, 22,212,111,116, -105, 13,225, 69, 58,152,173,218,236, 42,179,108, 87,233, 14,186,253, 46,181, 6,157,112, 82, 30,120, 56,211,238,209,110, 10,124, -106,204, 5, 62,219,128, 41, 18, 61,194,107, 60,193, 64, 44, 45, 4, 30,186,117,106,119,163, 48,188,177,253, 92,232,116, 31,218, -177, 26,182, 29, 0, 5,108,118, 44, 24,145,181,142, 35,114,231,116, 85,239,152,101,148,181,162, 92,195, 43,146, 35, 87, 18,135, -188, 13, 42, 22,128, 23, 42, 35, 98, 66,200, 24, 35, 57,137,208,164,161, 30,202,120, 41,197,183,177,147, 96, 55,194,117, 82,245, -225,250,163, 11,134,125,197,158,169, 14,206,182,216,166, 75,169,236, 93,114,190,156,248,141,189,108,196, 90,166,237,169,121,196, -181,250,106, 40,147, 79, 30, 49,116, 81,219, 78,117, 26, 30, 33,248, 90,223,142, 22,238, 53, 90,251,235,183, 21, 75, 77,169,146, -228, 66,162, 92,232, 13, 87,118,250,239,240, 22,241, 75,150,189,233, 78, 11,167,214, 10,153, 99,198, 17,203,141,204,109,181,161, - 79, 69,104,144, 53, 62, 58,210, 27,142,235,239, 21,135, 25, 12,160, 78,108, 32,130, 2, 20,150,218,156,215,108, 60,148,173, 41, - 88, 7, 42, 65, 24, 28,201, 25,193,174,203,122,131,116,219,213,139,110,241,182,232, 55,173,161,112, 70, 84, 43,170,207,186,169, - 84,234,253,183,113,211,152,109, 97, 46, 84,104,245, 86, 28,142,237, 70, 59, 5,226,196,128,132,200, 66, 22,182,154,125,146, 80, -180,201,178,222, 38,170,167,211, 29, 71,246,200, 86,223,104,218, 69, 29, 1, 87,177,189,186,233, 96,214, 30, 85, 40, 0, 56,170, -184,143,195,156,143, 60, 18, 84, 69, 23,232,156,193,247, 18,194,160, 70,237,183,247,176,221, 84,146, 79,219, 83, 27,110, 29,203, -146,109, 13, 30, 23, 61,163, 28,100,240,219, 38,149,107,237,182,228, 73,189,236,148, 58,150,218,218, 61,216, 67,151,221,136,166, -144,210, 25,240, 41, 6,169, 45, 53, 11, 53, 66, 58, 57, 80,186, 76,248, 97,190, 98,160,218,142,164,109,178,158,214,237,167,175, - 65,161,127, 41,109,181,191,248, 74,174, 85,212,196, 72,247,141,118,159, 86,189,184,118,184, 38, 56,243,200, 67, 20,205,205,163, - 65, 92,187,103,244,108,243,134, 42,113, 37,120, 42,121, 41,114,160, 80, 84,117,167,220, 73,251, 19,182,242,247,150,245,217,194, - 29,220,173,162,186,165, 45,185,180,237,176,187,166,214,235, 27,115, 85,154,242,203,141, 53,105,221,169,247,138,213,131, 33,111, - 58, 60, 24,243, 19, 85,132,218, 80, 19,227,198, 71,195,173, 7,218,190, 57,120,161,246,121,238,117,107,135, 46, 42, 54,246,212, -222,125,182, 66,215, 76,220,221,149,190,133,155,115,191, 81,182,165,170, 84, 41, 82,173,155,198,146,212,216, 50,159,240,155,121, -200,241,235, 44, 76, 97,206, 80,135,152,140,178,151, 90,121,170,146, 44,222, 17, 46, 79, 77, 21,101, 90,144,210, 68,210, 26, 90, -141, 23, 26,157, 24, 36,177, 72,226,224,221,193, 66, 60,166,100, 39,106,230,105,184,247,129,158, 20,172,144,102, 25, 56, 96,130, - 73, 11, 77, 13,172, 72, 85,114, 4,208,176, 63,238,220,198, 0, 12,193, 90,219,205,107,111, 55, 22,222,185,109,106, 77,203,105, - 92,212, 27,170,209,172,183,227,209, 46,123, 90,179, 79,185, 45,186,219, 47,160, 44, 55, 78,175, 80,230, 63, 25,215,130, 20, 20, -227, 72,116,188,206, 64,121,180, 19,141,103,175, 87,204,134,148,133, 47,152,148,124, 42, 90,135, 81,202, 0, 79, 42,142, 57,128, -233,159,246, 64, 39, 57, 58,138, 47, 16, 27, 71,120,112, 95, 98,211, 61,164, 94,203, 13,207,174,217,124, 50,238, 29,187,102,110, - 70,229,240,243,119,189, 42, 85,155, 77,162,222,245, 72, 16, 41,117, 22,108,155,169,231, 90,184,109, 7,235, 46,162,151, 58,152, -243,203,175,208,101,130,245, 6,171, 58,144, 89,145, 18, 68,155, 3,127,214,247,155, 98,118,115,120,231, 91,109, 90,114,247, 99, -108,236,173,194,145,108,177, 83, 77, 90, 45,188,253,219, 67,139, 87,122,147, 14,164,243,190, 44,248, 45,185, 37, 98, 59,143,101, -242,194,155, 18, 15,188, 7, 73,143,214,196, 35,167,138,170, 9,185,212,211, 51, 37,153,116, 75, 28,128, 41, 49, 75, 29,205,152, - 95,170,150, 83,177,218,235,123, 43,134,115,213,207,218, 72,189,141,233,170,169,213, 93,148,221,209,145,142,149,120,220, 40,189, -200,177, 4, 41, 27, 0, 8,185,198,215,109,149, 22, 37,219,112, 75,167, 73,165, 92, 21,191,118,183,110, 26,195, 20,107, 85,228, - 68,174, 84,165, 82,105,206,202, 98, 44, 87, 92,162,212, 48,165, 45,180,169,192,152,142,168,161, 4, 36, 36,229, 99, 64, 56,226, -223, 77,219,218,203, 74,243,176,184,111,131,100,212,184,131,106,210,106,188,182,174,237,198,176,104,236,108,117, 26,191,107,238, - 45,231, 67,159,114, 83,238, 42,188, 53,220, 59,203, 46,201,218,125,206,169,219, 54,146, 99,166,100,164,216,146,234, 18,227,161, - 2,157, 2,167,204, 14, 62, 61,170,123,199,195,134,245,239, 23, 13,187,105,102,194,182,165, 83,246,238,171,105, 84,183, 81, 53, -244,170,245,137, 87,220,107, 45,183,233,117,187, 54, 41,166, 73,133, 64,143, 76,250,217,135,130,156, 67,211,229, 61, 20,165, 50, - 32,160,164,235,150,155,127,199,229, 2,218,166,220, 17, 47,141,155,184,239,201,213, 27, 39,106,105,180,122,212,125,229,250,134, -170,214,227,109, 78,199,111,230,200, 68,190,174,249,149,109,181,172,187,121, 82,106, 16, 56,129,184, 42,147, 41, 97,218,124,229, - 79,183,224, 36,215,213, 28,203,110, 70,206, 69,195,144, 85, 69, 5, 70, 98,154,105,203, 23, 84, 82, 9,145, 88, 2,188,203, 43, - 29, 22,223, 64,107,155,217,130, 11,134,211,227, 63, 18,206, 91, 83, 89,150,100, 83,153,115, 5, 2, 9,166,100,112, 41,101, 77, - 75, 50,195,172,141, 83, 43,150, 83, 39, 47, 66,149,186, 60,183, 82,141,110,225,240, 39,196,221,155, 81,191,231,222,141, 89,213, - 55,237, 88,247,245,205,127,221,171,222,173,181,185, 61,226,240,182,175, 86,237, 91,186,211,159, 89, 98,236,113,202,246,245, 75, -190,106,209,152,110,218,100, 61,112, 84, 36,212, 28, 91, 16, 22,220,105,170,139,127,159,236,242,222,186, 77, 26,239,166, 87,232, -112,233,215,213,183,115, 90,106,118,188, 55, 27,106, 92,217,154, 61,128,237, 3,137,199,119, 10,177,114,223, 77,221,139, 75, 53, -122, 53,223,195, 53,253, 73,112, 71,241, 98,181, 54,200,172, 83,221,113,115,223,163, 51, 57,230,147,199, 5,183,187,182,199, 20, -139,188,118,233,203, 98,159, 84,186,183,115,137, 91, 34, 52, 27,238, 84,170,188, 61,236,220, 94, 32, 44,203,171,108, 40,237, 75, -107,110, 95,141, 88,160, 80,145, 95,186, 77, 97,137,205, 83, 25,174,211,162,188, 99, 84, 40,149, 52, 64,143, 46,157, 75,218, 83, -101, 77,186,105, 19,162,236, 45,249,108,218, 84, 43,254,198,220, 58,109, 34,211,226, 14,155, 2,237, 19,173,203,215,141, 77,199, -186,173,217,247,125, 99, 98,170, 16,170,182,125,110,232,227, 78,236,167,187, 2, 77, 5,212,166,211,181,219,161, 84, 87, 88,151, - 81,153, 91, 22, 42,173, 58,216, 2, 66,109,243,176,249,247,227,159,188,172,197,153,181, 23,220,146, 73, 36,158,189,183, 55,238, -119,191, 83,134, 79,133, 94, 26, 54,163,119, 40, 23,245, 15,114,220,191,142,226,213, 56,139,225,227,133,189,165,172,237,181,249, - 97,155, 30,221,191,119,242,131,196, 96,167, 93,151,172, 39,236,250,202, 55, 62,208,102,241,218,107, 53,128,138, 37,126,130,149, - 83,107, 53, 9,204, 84,230, 17, 17,189, 55,212,190, 3,248,146,172,211,160,212,169,214,189,181, 33,186,142,219,211,247, 54, 44, - 95,227, 14,196,106,162,186,125, 98,181,178,180, 58, 45,166,105,207, 92, 9,120,110,100,217, 28, 70,108,107,177,109,190, 79,173, -221, 99,115, 41,203, 76, 94, 97, 37, 17,242,109,137,226,246,211,217,104,251,163, 81,127,101, 62,187,186,171,187,235,180,188, 70, -108,210,237,235,249, 22, 93,137,180,219,153,179, 84,221,245,137,101, 55, 93,179, 23, 99,212,230,110, 13,155, 14,126,244, 71,153, - 30,155, 22,183,110, 58,135, 44,136,172,191, 58, 84,105, 79,178,151,218, 87,181, 90,244, 52,109,183, 49,108, 26,164,171,191,110, - 45, 11, 30,153, 2,181,115,110, 83,149,219, 97,171,198,196,221, 46, 9,183, 14, 21,126,223,177, 98,217, 80,152,183,109,137, 17, -184, 39,182,216,149, 73,247,169,115, 94,157,126,212, 38,174,188,170,109, 62,145, 66,136,100, 17, 21, 93, 71,204, 47,211,227,220, -219,115,111,195,225,108, 1,107, 11,252,252,239,134,106, 63,179,199,115,133,155,125,215,171,187,135,179,118,237,197,106,110,150, -201,109,205, 10,223,153,185,246, 52,250, 21,249, 15,122,172, 61,215,189,169, 23, 85,173,123,210,110, 87,226, 85,161,161,221,180, - 69, 50, 35, 16,154,153,245,133, 70,101, 86, 39,143, 18,101,191, 50, 43,173, 61,131,193, 94,250,238,142,241,110, 54,200, 89,144, -172,105,247,150,215, 94, 63,197,253,209, 54,126,230, 88,150,253,156,245,230,245,238,157,187,165, 91,118,205,231,112, 87,162,211, -175, 26,213, 74,234, 15,179, 73,139, 75,126, 92,138,179, 48,164, 75,167,183, 38, 43, 46, 58,157,172,107,218, 71,106,187,184,205, - 93,151, 6,202,110, 37,197,110,209,175, 29,134,190,172,246, 39,241, 13, 5,253,203,160, 93, 60, 62,109,135, 18,118,213,139,112, - 73,220, 10,142,200, 73,165, 84,170,177,119, 63,136, 8, 23, 60, 70,218,180,225,210,217,143,182,241, 40,114,169,117, 3, 80,155, - 86, 12, 7, 9,252, 89,216,124, 52,223,247, 21,199, 92,217,203,159,115,109, 71,183, 27,106,119, 94,200,183,218,221,216, 86, 93, -205,110,222, 91, 37,184,134,249,219,247, 46, 91,196,109, 93, 86, 53,227, 71, 49,101, 84,161,213,227,179, 69,164, 59, 61,217, 13, - 76,139, 38,154,150, 85, 17,245,109, 21,212, 94,194,230,253,122,118,237,252, 63,118, 51,229,219,231,249, 97,202,188, 61,155,155, -199,118,239,117,185,183,155, 45,111,219, 48,169,151,253,165,181,247, 29,144,197,255, 0,186, 86, 69,154,185,177,175,167, 54,191, -110,233, 53, 41,149, 43,218,189, 9,184,108,215,247,190,249,155, 69,160, 50,234,210,253, 65,250, 53, 77,200,172, 42,159, 74,151, - 45,166,227,134, 30, 29,118,127,120,246,186,191, 46,244, 59,148,198,229, 93, 91,162,198,209,109, 69, 98,214,187, 45,122, 85,145, -109,220,147, 54,155,112,111,218, 69, 66,255, 0,180,170,251,125, 80,157,121, 82,101,220,150,181, 18,154,240,167,215,104, 46, 83, -162, 85, 36,212, 19,245,147,172, 55, 5,237,158,182,189,170,118,111,241,175,183,251,177,186, 92, 50,213, 47,138,213,133, 67,216, - 27,113, 74,181,183,186, 14,223, 84,174,122, 47, 11,119,174,202,223, 59, 29, 14,226,170,191,178,245,148,204,114,158,230,219,222, - 52, 89,210, 61,212, 74,157,109,221,244, 74,100,119,233,207,218,140,207,171,105,175, 15, 60, 86,219, 59, 19,183, 23, 37,185, 55, -107, 42,215,157,246,197,244,141,202,218,155,189,189,196,135,110,218,246, 85,232,222,219,222,187,117, 26,163,120, 88,142,109,229, - 70, 70,225, 69,136,139,192, 85, 33, 71,143, 94,160, 33, 53, 10, 36,116,205, 53, 8, 43,126, 27,135, 2, 45, 74,111,229,107,222, -224,251,173,219,227,235,252,241,159, 47, 99,243,255, 0,140,109,229,209,192, 61,139, 67,254, 54, 13, 55,134, 30, 56,238,159,226, -247,134,189,165,221,155, 88, 82,239, 26, 58,127,141, 58,134,224, 29,184,254, 17,110,133,181,238,252, 37, 74,228,217,202, 39,240, -190,165,239, 17, 99,253,100,191,208, 49,227,221, 17,185, 92,241,117, 46,135,178,187, 35, 81, 28, 31,213, 31,183,183,186,171, 31, -122,172,157,204, 93,241,102,218,215,157,151, 58,233,188,119, 54,204,184,111, 91, 90,206,160,237,157, 94,102,218, 53, 31,110,232, - 55, 5,201, 73,181, 97, 62,229, 82, 21,212,253, 17,170,156,202,136, 53,143, 5,170,122,233,238,255, 0, 21,182, 21,251, 73,221, - 38,109, 61,163,187,173, 42,230,243,109,206,204,217,215,189, 66,226,221,186, 53,235, 74,102,187,180, 15, 88,202,106,225,181, 40, -212,205,160,161, 61, 71,164,207,141,102,114, 42,155, 50,125, 77,232,203,169,120,130,166,250, 89,240,157,111,237,173,252,177, 83, - 70,217,139, 67,114,246,121,205,192,178,182,194,199,221,235, 38,179, 78,133,124, 51,107,215,171,138,221, 10,189,205, 93,167, 93, - 54,173,114, 93,149, 85,143,101, 93, 20, 42,173,118, 11,240,157,147, 78,174, 70,121,218, 70, 95,139,225,190, 91,109, 66, 82,230, -223, 59,143,119,166, 50, 8,184, 3,231,127,135,166, 49, 78, 42,118,162,139,177,156, 68,238,246,208, 80, 63,132, 77, 83,182,246, -242,168, 91, 74,166, 93,239, 65,153,117,219,117, 40, 41,100, 86,172,219,150,169, 75,166,194,137, 94,175, 81, 43, 42,159, 72,151, - 83,133, 10, 28, 42,156,138, 35,149, 8, 81, 34,197,146,211, 13,173, 88,184,129,221,147,190, 91,193,122,238,130, 40, 10,181,162, - 92,146,233,172,210,109,231,107, 47, 92,147, 40,244, 11,118,135, 75,181,237,216, 53, 75,142, 68, 40,170,184,107, 72,161, 81,105, -222,253, 60, 68,134,137,147, 11,242, 90,133, 13,183, 81, 21,165,172, 21, 55, 58, 70,221,186,116,193,180,169,223,215, 31,255,217, -}; - diff --git a/source/blender/editors/datafiles/splash.png.c b/source/blender/editors/datafiles/splash.png.c new file mode 100644 index 00000000000..bbce480ecba --- /dev/null +++ b/source/blender/editors/datafiles/splash.png.c @@ -0,0 +1,2483 @@ +/* DataToC output of file */ + +int datatoc_splash_png_size= 79258; +char datatoc_splash_png[]= { +255,216,255,224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 1, 0, 72, 0, 72, 0, 0,255,225, 0, 22, 69,120, +105,102, 0, 0, 77, 77, 0, 42, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,255,219, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,255,219, 0, 67, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,255,192, 0, 17, + 8, 1, 15, 1,245, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1,255,196, 0, 31, 0, 0, 1, 3, 5, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 7, 10, 3, 5, 6, 8, 9, 2, 1, 11,255,196, 0,103, 16, 0, 1, 3, 3, 2, 4, 3, 4, 6, 4, 7, + 11, 5, 9, 13, 9, 1, 2, 3, 4, 5, 6, 17, 0, 7, 8, 18, 33, 49, 19, 65, 81, 9, 20, 34, 97, 10, 21,113,129,145,240, 35, + 50,161,193, 22, 23, 24, 66,177,209,225, 25, 26, 36, 40, 51, 56, 73, 82, 98,232,241, 72,104,105,136,168, 41, 52, 57, 67, 84, 88, +120,150,178, 37, 38, 68, 83, 87,115,130,135,147,152,181,200,210, 54, 89, 99,114,146,184,213,214,215,255,196, 0, 29, 1, 0, 0, + 6, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 6, 7, 1, 4, 8, 9,255,196, 0, 80, 17, 0, 2, 1, + 2, 4, 4, 3, 4, 6, 7, 5, 7, 0, 7, 9, 0, 1, 2, 3, 4, 17, 0, 5, 18, 33, 6, 19, 49, 65, 7, 34, 81, 20, 97,113, +240, 8, 35, 50,129,161,209, 21, 66, 82,145,177,193,210, 36, 51, 98,162,225, 9, 67, 83, 84,114,130,241, 52, 56, 68, 85,116,148, +211, 22, 23, 24,115,131,146,147,180,181,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,159,198,150,150,150,134, 6, 22, +150,150,190,100,122,143,199, 67, 3, 31,116,203,220, 60, 68,108,181,171,123, 70,219,170,254,224,209, 41,183,140,167, 25,101, 20, +135,189,241, 73,101,249, 28,165,136,243,170, 77, 69, 84, 74,116,149,133,163,149,185, 15,180,226,185,211,132,158, 97,151,159, 35, +212,126, 35, 92,108,227, 63,131, 43,145, 85,251,143,120, 54,213, 18,235,236, 86, 37,191, 87,185,237,148,243, 72,170, 67,146,224, + 11,147, 81,162,128, 57,167, 69, 42, 5, 75,143,213,230,242, 75, 94, 34, 50,148, 86,158, 42,113, 39, 27,112,159, 14, 38,119,193, + 60, 55, 23, 19,212, 81,204,173, 89, 4,134, 67, 34,209,128,198, 87,130, 56,138,188,146, 2, 0,242,151, 49,169, 50,114,101, 1, +128,179,188, 40,225,158, 7,226,222, 37,108,143,142, 56,150,110, 23,166,172,133,150,142,120,196, 98, 54,173, 44,162, 36,158, 73, + 85,146, 56,200, 44,124,193, 4,140, 4,124,232,139, 41, 61,145,109,196, 58,132,173,181, 37,104, 80,200, 82, 72, 32,131,243, 26, +247,174, 11,240,211,199, 61,219,180,206, 66,179, 55, 36, 79,186,108,118, 29, 68, 54,166, 58, 92,122,228,181,217, 65, 13, 22,219, + 47, 30,106,157, 61,174, 95,242, 14, 16,243, 97, 37, 45, 44,128,150,181,219,219, 46,247,181,247, 6,129, 2,231,180, 43, 48,171, +148,106,139, 65,216,211, 33, 58, 29, 65,232, 57,219,113, 63,172,203,233, 86, 66,219, 88, 74,208,160, 66,146, 14,147,240,211,197, +174, 19,241, 67, 46, 53, 25, 37, 79,179,102,180,202, 13, 86, 95, 49, 2,166,156,244, 38,219, 9, 97,213,178,207, 29,212,220, 7, + 17,201,120,194,158, 38,248, 69,197,190, 22,102, 66,159, 60,166,246,156,166,165,136,165,204, 33, 4,210,212,142,160, 95,115, 12, +218,119,104, 36,179, 11, 18,134, 72,237, 33,202,244,180,180,181,103,226,173,194,210,210,210,208,192,194,210,210,210,208,192,194, +210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210, +215, 13,125,163,254,220, 13,158,224,130,240,159,178,214, 5,156,238,249,111,173, 45,150, 21,116, 81,219,173,155,110,200,219,199, + 39,194, 98,116, 8,215, 53,192,138,116,167,170,213,245, 68,151, 17,255, 0,171, 32,177,132, 50,233, 76,186,132, 39,249, 26, 91, +214, 67,195,217,207, 19,102, 9,149,228,116, 47, 95, 90,224,177, 85, 42,161, 80, 16, 11,200,238, 85, 35, 64, 72, 5,157,128,185, + 10, 46,204, 1, 98,226, 46, 38,200,248, 79, 45,124,219,136, 51, 20,203,104, 81,130, 6, 96,204,206,237,114,169, 28,104, 26, 73, + 28,128, 78,148, 86, 58, 85,152,128,170,196,119, 43, 75, 80,124, 63, 73,159,141,131, 84, 83,195,103, 56, 94, 20, 82,242,212,138, +127,240,103,117, 13, 77, 44, 20,171,195,105, 85,127,227,115,194, 91,193,101, 37, 75, 16,146, 20, 1, 1,180,147,204, 58,247,192, + 39,183,219,102,184,168,189,173,253,156,222,171, 32,236, 38,233,221, 18,227,210,109, 58,154,110, 6,238, 13,182,188,107,111,132, +162, 53, 29,138,204,184,113, 36,218,181,233,114, 84, 26,131, 10, 91, 82, 88,144,233, 68,118,234,107,152,244,120,206,205,115,175, + 7,248,243, 35,161,151, 49,169,202, 86,166,150,157, 75,200,105,230,142,102,141, 64,185,102,140, 17, 33, 10, 55, 98,138,225, 64, + 44,108,160,156, 64,178, 47, 27,188, 58,226, 12,194, 28,174,151, 57,106, 90,186,150, 9, 16,169,134, 72, 82, 71, 38,202,171, 35, + 3, 26,179, 27, 5, 18, 50, 22, 36, 42,130,196, 12, 72, 35, 75, 94, 80,180,173, 41, 90, 8, 82, 84, 1, 73, 29, 65, 7,204, 29, +122,213, 97,139,107, 11, 75, 75, 94, 29,117,182, 91,113,231,156, 67, 76,180,133, 56,235,174, 41, 40,109,182,208,146,165,184,226, +212, 64, 66, 2, 65, 36,147,128, 6, 78,134, 6, 61,233,107,140, 28, 63,123, 94,236,238, 39,253,160,119,151, 9,219, 61,108,210, + 43,219, 63,103, 88,247, 29, 77,157,231, 77, 86, 91,178,239, 43,178,215,171, 80,169,213, 69,219, 84,214,227,166, 57,178,252,106, +195,236,197,150, 92,117, 83,126,173,247,214, 23,238,178, 89, 3,231,181,219,218,129,127,123, 56, 15, 15,137,177,182,194,209,220, +115,188,169,221, 85, 85, 13,213, 86,172,210,254,165,254, 47, 78,219,136, 94,225,245, 74, 79,188,123,199,240,222, 95,139,226,126, +167,184,183,201,250,202,212,182, 30, 7,226,105,179,220,183,134,191, 71,242,179,156,218, 1, 81, 12, 50, 72,136,121, 70, 41, 38, + 5,203, 48, 17,183, 46, 39, 37, 28,171,130, 52,149, 12,109,136, 92,222, 32,240,164, 60, 61,154,241, 87,233, 46,118, 69,147, 78, +105,167,158, 56,228,145,121,162,104,160, 34, 48,170, 90, 84,230,202,138, 36,140, 50, 48, 58,149,138,139,227,180, 26, 90,134, 23, +247,207,155,251,255, 0,155, 30,209,127,235, 93,227,255, 0,232,210,254,249,243,127,127,243, 99,218, 47,253,107,188,127,253, 26, +152,127,247, 29,226, 55,254,233,139,255, 0,155,166,255, 0,234, 98, 19,255, 0,226, 11,194,239,253,245, 55,255, 0, 37, 87,255, + 0,210,196,207,116,181,166,252, 3,241, 57, 89,226,255, 0,133,157,171,223,235,138,219,165,218, 85,203,250,153, 89,157, 81,183, +232,178,101,204,165,211,157,166, 93, 53,202, 3,109,195,147, 56,120,175, 33,108, 82,154,113, 69,125, 66,221, 80, 29, 0,214,228, +106,172,174,163,168,203,171,107, 50,250,180, 17,213, 80, 75, 36, 50,168, 33,128,146, 39, 40,224, 48, 36, 16, 25, 72,184, 36, 30, +160,219, 22,246, 95, 93, 77,154, 80, 80,230, 84,110,100,163,204, 97,138,120,152,130,165,163,153, 22, 68, 37, 88, 6, 82, 85,129, + 32,128, 71, 66, 47,133,165,165,165,173, 92,110, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105, +105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,105,104, 96, 97,105,105,107, + 3,168,110, 45, 6, 60,249,116,122, 75, 21,123,182,183, 5,239,118,155, 75,181, 41,174, 85, 12, 9, 92,174,168,197,170, 85,150, +166,169,212,105, 67,194, 32,183, 54,108,117,130,164,229, 32, 40, 29, 12, 12,103,154, 90,104,166,239, 21, 38,143, 91,167,219,119, + 13,169,123,209, 43,245,152, 83, 39,208,233, 9,165, 83, 46,121,213,134, 41,225,159,126, 83, 12, 88,181,170,177,130,134,188, 97, +151, 38,251,171, 42,228, 95, 35,139,228, 86, 47,143, 95, 53, 54,130,157,111,109,119, 6, 76, 70,208, 28,118, 91, 44, 90, 40, 45, +183,221,106, 77, 58, 85,222,220,217, 43, 74,114, 75,108,197,113,213, 99,149,182,214,178, 18, 70, 6, 28, 29, 45, 88,232, 23, 37, + 18,231,136,236,202, 36,244, 76,110, 60,135, 33,205, 97, 77,191, 18,125, 54,115, 56, 47, 83,234,212,201,141, 55, 38,149, 80, 64, + 82, 10,216,146,211, 78,164, 45, 36,160, 5, 2,111,154, 24, 24, 90, 90, 90, 90, 24, 24, 90, 90, 90, 90, 24, 24, 99,120,143,168, +110,117, 51,103,174,233, 91, 65, 29,201, 23,200,138,203,116,255, 0,119,109,167,170, 12, 69,114, 67,104,169, 72,165, 50,240, 40, +118,166,136, 69,226,200, 32,144,175,137, 0,184, 17,174, 20, 60,223, 25, 18, 95,121,199,215,190,238, 72, 83,138, 83,202, 92,139, +187,156,186,165, 18,178,175,210,126,183, 54,117, 36,133, 36, 40, 16,160, 8, 61, 8, 35, 32,253,218,208,158, 40, 56,198,176, 54, + 85,185,246,165,163, 22,151,119,238,105, 66,153, 92, 54,212,151,168,214,187,171, 78, 67,245,249, 12, 43,244,179, 83,148,148,194, +109, 65,206,185,121,108,167,148, 47,157, 60,116,224,190, 27,204, 99,139,140, 56,175,196,124,203,131,114,188,170, 14, 66,193, 75, + 56, 17, 77, 38,167,144,114, 96,182,185, 42,165,190,146, 16, 51, 50, 70,132,233, 84,102,199, 72,120, 15,198,220, 77,151, 75, 55, + 7,112,151,134,185,103, 26,102,153,172,252,246,158,170, 2,101,134, 61, 49,198,121,211,223, 68,116,145, 17,172, 23,210,170,242, + 53,139, 51,170,227,143,215, 53,223,196,133,153,238,191,194,219,167,117,237,195, 59,196,247, 52,214,107,151, 20, 5,201, 13, 99, +196, 83, 45,200,148,149, 45, 41, 42, 0,144, 49,147,140,231, 88,195, 91,199,188,114, 93,109,134, 55, 39,112,100, 60,226,194, 90, +101,171,158,186,235,142, 44,159,133, 40,109, 50,201, 90,179,216, 0, 78,177,155,198,244,186,247, 18,225,151,114, 93,181,137,181, +218,221, 69,209,207, 34, 82,202,131,105, 39, 13, 68,134,194,112,136,145, 17,156, 33,166,210,148, 36,118, 25, 36,157,221,188, 47, + 45,145,246,104,112,186,239, 19, 59,221, 70, 93,217,123,214,159,133, 73,179,173, 8,106,140,213,106,227,187, 42,177, 94,153, 78, +181,233, 18, 37,182,177, 72,167,177, 22, 51,207,212,167,150,214, 25,110, 59,132, 37,229,170, 52,119,121, 7,194,159, 15,120,203, +198,222, 60,159,134,248, 23,136, 51,106,108,146, 23, 75,212, 85,212,201, 45, 66,164,141,162, 37, 49,195, 36, 81, 52,243,178,187, + 44, 97,214, 56,145, 92,188,204,177,150,110,196,241,107,196,110, 10,240, 51,128, 32,226,126, 62,225,252,162,167, 58,153, 28,251, + 61, 37, 52,112,211, 51, 70,161,230, 97, 36,209,203, 42,211,192,172,138,210, 20,105, 37,118,141, 82, 21,105, 2,174,163, 72,218, +189,222,170,162, 69,126, 85,135,123,206, 76,183, 23, 46, 77, 77,218, 13, 81,227, 33,199,137, 91,146, 29,120,199, 37,106, 82,148, + 73, 81,238, 73, 58,203,118, 91,127, 55, 47,135,155,149,114,173,233, 18, 19, 1,201, 8, 23, 5,159, 86, 18, 27,166,212,210,217, +229, 80,122, 50,192, 84, 10,130, 81,144,135,219, 1,196,246, 80, 91,101, 77,171,150, 85, 47,164,143,198, 35,151, 97,170, 81,118, +183, 97,169, 54,130, 37,133,179,102, 61,111, 92, 53, 14,120, 40, 95,195, 22, 93,192,171,133,185, 46, 62,166,176, 22,235, 65,161, +204, 74,144,218, 6, 18, 59,121,195,151, 16, 59, 31,237,121,225,250,232,188,108,251, 74, 62,216,241, 35,181,232,138,205,221,106, + 37,246,165,173,185,210, 97,201,126,152,244, 42,139,108,182,186,213,159, 85, 16,103, 34, 50,222,109, 50, 33,200,136,182, 92, 7, +194, 14,201,234,207, 16,126,128,222, 38,248, 71,147,143, 16,120, 59,138,106, 38,207, 50,127,174,217,162, 46,210, 29,204,124,216, +156,104,105,141,227, 9, 42, 77, 79, 51,176,134, 89, 64,146,237,200,222, 28,127,180, 43,194,191, 25, 51,195,225,207, 24,112,181, + 60, 89, 30,113,245, 32, 50,202, 17, 98, 29, 36, 17, 76,191, 88,176,139, 72,205, 19,193, 81, 10, 35, 77, 20, 76, 99, 32,118, 27, + 96,248,137,177,183,250,218, 21,123,106, 66,161,213,225, 37,166,235,214,228,213,160, 84,232,242,156, 78, 64,113, 41, 56,147, 13, +101, 43,240,159, 71,192,224, 65, 7,149,105, 90, 19,106,226, 39,139,222, 29,184, 78,110,198,145,196, 38,229, 82,246,206, 6,226, +214, 42, 20, 27, 86,171, 91,137, 84, 93, 38, 85, 78,151, 17,153,211, 89,157, 82,131, 5,214,105, 13,162, 43,237,171,196,148,182, + 91, 86, 72, 74,138,129, 26,224,102,199,110,133,115, 99,247, 86,135,116,199, 84,134, 26,129, 81,250,170,231,166, 5,148, 9,180, +119, 95, 17,234,144,223,108, 28, 41,230,185, 75,173,103, 33, 47,197, 65,236, 8, 56,167,210,118,170,198,173,240,251,194, 53, 82, + 35,168,126, 52,237,202,189, 36,178,235,106, 10,109,214,222,179,169,238, 54,226, 20, 58, 41, 37, 10, 4, 31, 67,171, 87,232,151, +199,112,248,245, 61, 22, 67,196,119,203,243,234, 9,141, 61,127,179,133, 66,234,105,230,150, 10,168,209,213,213, 57,175, 11,164, +177,216,133,120,223, 78,133,116, 11, 85,125, 48,120, 26,127,163,229, 30, 99,196, 92, 52, 23, 49,200,107, 97, 90,156,188, 84,150, +112,140, 42, 96,138,162,146, 87, 70, 70,147,148,147, 35,197, 32, 96, 89, 36,143, 86,182, 71, 38, 80,214, 61,247,102,238,101,169, + 68,190,118,250,231,162, 94, 86,117,203, 5,186,157, 2,229,183,106, 17,170,180, 90,196, 7, 74,146,220,186,125, 66, 35,138,110, + 83, 5, 72, 80,230, 66,136,202, 72,238, 8,214, 89,168, 64,112,175,237,189,221,253,134,225,159,102,120,123,225,163,133,105,251, +189, 82,218,155, 26, 53, 58,249,186, 43,172, 93, 53, 88,104,168, 59, 62,163, 61,244, 83, 40, 54, 52,101, 57, 18,156,216,146, 0, +149, 42, 82, 84,242,185,200,142,216, 71, 50,250, 53,193,103,210, 48,176, 55,151,114, 45,253,161,226,123,106,154,216,235,138,230, +171,179,111,210,175,154, 45,102, 69, 70,198, 98,189, 45,246,226, 66,166, 92,208, 43, 49,218,153,107, 54,228,197,120, 94,244,183, +101, 50,219,175, 32, 72, 17,218, 11,121, 61, 57,156,120, 63,198,153,119,233, 74,154,108,168,214, 80, 80, 73, 45,180,205, 3,212, +154,116,102,229,204,244,233, 33,144,107,140, 7,210, 20,181,143,217, 29,185,103, 35,241,187,128,243, 63,209, 20,149, 89,184,162, +204,179, 40,225, 7, 84, 53, 9, 74, 42, 93, 19,153, 2, 84,188, 98, 35,203,145,140,122,139,232,184,251,102,226,253,250,171,113, + 37,195,245, 6,251,107,107,171, 91,211,182, 52,173,200,122,165, 79,163, 51, 98,207,189,104, 17,110,183,106,213,101, 50,154, 93, + 53, 20, 39,167, 9, 42,157, 33, 82, 99,134, 90, 13,243,184, 95, 72, 64, 60,195, 47, 80, 32,128, 65, 4, 17,144, 71, 98, 53, 2, +158, 50, 84,211,191, 72, 26,128,243, 1, 10, 14,113, 65,195,147,232, 82, 80,159,137,193, 34,193, 91, 78,246,248,156, 5, 45,144, +174,224,164, 16,122, 13,118, 87,143, 15,111, 68, 62, 31,247, 89,238, 25,120, 83,218,134, 55,231,120,232,117, 24,214,189,203, 90, +170, 59, 86,145,107, 83,239, 39, 22, 24,122,204,183,168, 86,222, 39,222, 53,230, 36, 56,219, 82, 84,212,136,236,177, 41, 11,138, +145, 33,196, 56, 91, 91, 48,240,167, 51,118,225, 88,120,116,201,154,212,103,249,106,102, 51,243, 57,112,197, 76,172, 19, 86,169, + 89,130, 8,193,123, 6, 98, 25,182, 0, 19,182, 17,203, 60, 97,202,145, 56,190,163,137,196,121, 61, 47, 14,230,178,101,148,252, +190,100,210,213,186,151,211,162, 37, 82,237, 35, 4,185, 84, 5, 84, 92,179, 1,190, 36,133,165,168,139,220,190,218,255, 0,106, +111, 13,237, 80,239,190, 41,184, 29,183,169, 27, 89, 90,168, 69,138,228,225, 66,187,237, 23, 16,167,193,117, 20,246, 46, 35, 90, +169, 70,163, 85,156,101, 14,120, 77, 84, 34,149,172,182,172, 54, 74, 84, 7, 85, 46,223,109,143, 13, 22,231, 5,182, 47, 26,148, +171,102,247,187,237, 43,183,112,233,251, 83, 88,178, 40,166,138,205,225,100, 95, 50, 40, 85,218,228,250, 85,194,221, 66,123,108, +120, 76, 51, 65,115,145,214,150,161, 37,154,132, 89, 13, 39,195,116,242,177,215,248,105,197,180, 35, 47,120,168,226,205,105,243, + 57,189,158, 25,168,170, 33,169,137,167,177, 60,146,241,185, 8,246, 6,193,244,130, 65, 0,146, 8,196,131, 46,241, 91,131, 43, +206,100,147, 87, 77,147,212,229, 48,251, 76,240,215,211, 79, 73, 50,211,220, 14,112,142, 68, 5,227,187, 45,202,106, 32, 16, 72, + 0,223, 29,148,210,212, 92,183, 35,233, 31,162,243,160,209,233,124, 25,112,161,184,187,163,185, 51, 34, 63, 58,227,131,120, 83, +170,147,233,118,147, 44,202,113,150,152,250,163,111,196,153,119, 10,221,142, 27,116,188,153, 48,153, 96,159, 12,248,202, 37, 72, +198,248, 54,250, 69,151,109,251,190,214,214,200,241,107,178, 86,230,220,166,238,185, 96,217,113, 46,235, 45, 87, 21, 53,219, 86, +231,169,204, 77, 62,159, 26,239,181,110,153, 50, 30, 76, 37,212, 94,142,195,174,178,251, 78, 69, 46,135, 23, 29,196,133, 99,108, +248, 71,199,171, 65, 85, 94,249, 46,143, 99, 86,119,128,205, 7,180,136,210,247,113, 0,144,200, 87, 98, 84, 91, 83,129,116, 86, + 4, 95, 68,120,211,225,211,102, 52,121,116,121,233,147,219,157, 99,142,160, 83,212,123, 33,145,237,166, 51, 80, 99, 17,134,243, + 0,198,250, 99, 38,210, 50,144,109, 43, 29,120,113,198,217,109,199,157, 90, 91,105,164, 45,199, 28, 89, 9, 67,109,161, 37, 75, + 90,212,122, 37, 33, 32,146,124,128,215, 14,253,164,222,219,221,157,224, 86,233, 59, 61,101,218, 15,111, 86,249, 34,155, 14,165, + 92,161, 49, 88, 69, 18,210,176, 89,169,199,110,101, 41,155,170,176,220,103,222,151, 90,126, 19,172,190,154,124, 86,130,209, 30, + 75, 79, 63, 37,143, 17,182,220,230, 77,175,244,142, 56,132,142,220,122,222,253,112, 91,245, 86,205, 92,140,191, 79, 85,221,100, + 38,245,165, 74,102, 61, 69,151, 99,183, 46,153, 83,187,226,187, 77,174,184,128,224, 80,100, 59, 27,198, 13,148,165,214,201,230, + 8,229, 94, 22,113,190,113,150, 83,230,244,153, 69,168,170,198,168,121,147, 65, 20,147,169, 23, 6, 24,228,145, 93,245, 13,211, + 97,172, 88,173,193, 4,175,156,120,191,192, 25, 38,109, 81,146,214,231,119,174,163, 58,103,229, 65, 81, 52, 84,237,123, 17, 52, +177, 70,232,133, 78,207,185,229,155,135,210, 65, 2, 71,219, 95,199,191, 8,187,217,187,147,118, 59,104, 55,194,208,220,189,198, +166,208,234, 87, 13, 70,153,102, 59, 46,189, 76,133, 76,164,205,137, 79,158,183,238, 88, 81, 85, 78, 18, 91,151, 54, 58, 11, 41, +148,167, 73, 89, 33, 4, 37, 68,109,254,160, 19,244,127,110,123,126,214,227,115,113,175, 26,237, 82, 45, 14,212,183,182, 43,113, + 46, 74,213,102,160,164,196,131, 73,183,233, 85,139,126,167, 62,165, 57,121, 34, 52, 86, 32, 48,235,174, 30,161, 9,104,247,198, +186,103,185, 63, 72, 83,125,183,147,120, 38,237, 23,179,215,133,198,183, 45,182,164, 77, 98,145,112,222, 16,174, 10,229,197,113, +192,167, 58, 82,245,199, 30,212,183,230, 68,102,215,162, 45, 1, 42, 11,168, 75,116,161,181,165, 79,248, 14, 57,225, 53, 36,226, + 95, 8,115, 26, 94, 38,172,201,120,104, 61, 93, 6, 89, 75, 4,245, 53,117,114,195, 4, 81, 25, 67,146,100,145,185,104,163,202, + 74,160,212,224, 2, 73, 32, 18, 34,220, 41,227, 94, 89, 89,194,148, 57,247, 21,178, 81,102, 57,181,101, 69, 61, 45, 29, 20, 83, +212, 77, 48,132,160, 2, 56,151,153, 35,155,184, 12,231, 66, 18, 85, 64, 4,128,101,135,165,168,156,219,158,223, 30, 44,184,114, +221, 75,123,111,253,161,252, 36, 55,183,244, 42,247,131, 37,117,235, 78,155, 93,160, 92, 80,232,239,201, 68,119,171,244,186,109, +102,169, 54,159,121,211,227, 40, 44, 58,212, 57,113,220,230, 73, 71,139,226, 0,218,186, 89,198, 87,182,211,135, 30, 14,235, 27, + 75, 6,163,102,223, 59,171, 70,222, 93,176,167,238,197,161,117, 88, 18, 40, 31, 82,200,182,106,181, 25,180,248, 5, 70,177, 61, +135,125,225,126,226,183, 10,124, 49,200,151, 18,149,128,224, 82, 83, 20,171,240,211,140,105,171,114,250, 40,178,177,152,182,106, +143, 37, 52,148,179, 67, 60, 19,172, 66,242, 24,230, 71,208, 74, 13,202,146, 26,219,128, 70,248,152,209,120,173,192,245,116, 57, +149,124,217,177,202,215, 39,120,227,171,138,178, 9,169,234, 41,218, 83,166, 46,100, 14,156,192, 28,236, 25, 67, 45,246, 36, 29, +177,217,173,112,163,112,253,133, 28, 55, 95,188,105,212,248,162,173,202,171,215,108,187,186,163, 93,190, 47,125,152,175,202,157, + 87,160,214,183, 90,175, 85,141, 82,118,228,122,179, 46,114,165,201,181,228, 73,126,179, 50,101, 17,245, 57, 25,115, 93,105,180, + 56, 41, 5,116,160,202,240,191,237,190,220,158, 50,248,231,219, 77,158,218, 29,130,147,111,112,189, 93,145,119,193,184,247, 10, +229,165,214,170, 87,151,189,209,182,206,237,185,233,142,205,168,210,100,170,143,106, 52,237,203, 71,166, 71,110, 59,134, 83,174, +180,249, 30, 48,117,228, 33,185, 31,161, 92,200, 74,187,115, 37, 42,199,166, 64, 58, 74,170, 30, 49,240,218,181,169, 26,169,242, + 74,252,226,140, 25, 82, 41, 81,156, 65, 43,200,129, 36, 40, 91,149, 48,104,217,133,136,150, 59,130, 25, 75, 17,133,169, 38,224, +127, 20,232, 22,181,105, 35,207,242,236,146,184,136,164,154, 23, 84, 53, 16,164,110, 94, 33, 32, 83, 44, 44,178,170,155,131, 20, +182, 33,149,130,131,134,126,151,176,123, 71, 74,180, 27,176,226,237,253,162,205,158,136,126,226, 45,102,173,218, 59, 86,224,136, + 80, 27, 49, 69, 13,184, 98, 40,143,200, 0,228, 13,114,224, 99, 24,212, 4,189,180, 92, 57,109,223, 10,156,122, 93,182,174,205, +192,141,105,218,119, 45,169,102,238,133, 50,218,161,145, 14,159,102,213,171,255, 0, 88, 69,169,211,168,140,199,193,165, 66, 53, +106, 19,243,227,176,217, 74, 34,138,178, 89,140,150,163, 54,195, 77,254,136, 21, 90,173, 54,133, 75,169, 86,235, 51,225,210,168, +244,120, 19, 42,149, 90,165, 66, 67, 81, 32, 83,105,180,248,238, 75,157, 62,108,183,214,148, 70,136,204, 86, 93,113,199, 22,160, +132, 33,181, 41, 68, 0, 78,191, 57, 62, 35,175,107,151,218,161,237, 50,184, 37,109,235, 50,196, 29,229,220,202, 77,141,183,190, + 43, 14,184,170, 30,215, 90, 80,163, 80, 97,220,243, 97, 43, 10,140,219,118,133, 14,117,126,160,198, 73,109,217, 50,144,146,162, + 19,155, 39,192, 39,174,139, 62,226, 12,218,122,167,135, 34,160,161,145,235, 29,217,140, 69,217,213,208,184, 38,197,194, 71, 52, +154,236, 88, 42,184,189,156,131, 86,125, 35,211, 47,155,135,120,111, 38,167,164, 73,184,135, 50,204, 35,142,133, 17, 84, 74, 17, + 81,146, 64,132, 0, 66, 51,201, 4,122, 1, 10, 89,144,218,233,113, 61,206, 11,119, 14,189,187, 28, 40,240,239,185, 23, 75,138, +118,228,190,118, 83,107,110,250,243,171, 32,173,202,197,203, 99,208,235, 85, 53,168,134,209,146,102,205,124,159,129, 61, 79,234, +167,176,217,253, 55, 59, 75,100,210,182,231,110,237, 11, 38,133, 20, 65,162,218,246,245, 30,223,164, 66, 7,152, 68,165, 81,169, +241,233,212,232,193, 88, 25, 13,196,142,210,123, 15,213,211,141,170, 34,178, 72,102,172,170,154,158, 62, 77, 60,178, 59, 34,126, +202, 51, 18,171,255, 0,106,144, 62,236,116, 69, 12, 83,193, 69, 71, 5, 76,188,250,152, 98,141, 36,127,219,117, 64, 29,191,238, + 96, 79,223,133,168,165,123,119,125,170,238,209, 91,175,240, 39,195,117,192,235,151, 29, 77, 14, 81,120,135,190, 40, 15,243,187, + 74,135, 49, 41,105,123, 57,111, 76,138,162,181,214,165, 33,194, 46, 23, 26, 41, 49,152, 90, 40,225, 78, 63, 38,166,204, 61,237, +246,205,251, 82,224,240, 79,182,174,108,238,209, 85,161,203,226,135,116, 40,142,253, 82,227, 78, 37,255, 0,226,146,206,156,167, +161,191,184, 53, 54, 18, 8, 53,247,252, 41,108, 80, 99, 56, 82, 61,229,165,212,159, 75,177,161, 8,147,185, 93,236,136,246, 94, +213,106,214,149,199,198,255, 0, 17,212,217,179,238, 10,173,173,115,221, 27, 61, 64,185, 22,228,217,136, 85, 70,147, 62,106,247, + 98,229, 19,146,183,100,220, 18,214,234,221,164,120,203, 82,154,110, 66,170,174, 5,201,122, 11,177,110, 14, 3,225,236,179,135, +178,212,241, 23,140, 33,215, 71, 11,133,202,168,154,193,235,170,175,228,151, 73,191,212,196,192,178,146, 8, 37, 76,132, 21, 68, + 89,105, 31, 17,120,151, 54,226,108,214, 79, 12, 56, 34,126, 93,116,209,151,206, 43,214,229, 40, 41, 45,231,132, 50,145,245,242, +169, 10,202, 8, 32, 50,196, 8,105, 29,161,210,223,163,211,255, 0,132, 11,255, 0,169, 75,243,255, 0,199,236,141,116, 43,233, + 74,255, 0,148,224, 99,255, 0,154,226, 91,255, 0,107, 96, 53,207, 95,163,211,255, 0,132, 11,255, 0,169, 75,243,255, 0,199, +236,141,116, 43,233, 74,255, 0,148,224, 99,255, 0,154,226, 91,255, 0,107, 96, 53,106,102,159,250,197,112,231,255, 0, 5, 39, +255, 0,208,175,197, 59,147,255, 0,234,195,197, 95,252,124,127,255, 0,161,150,227,167,222,201,206, 30,246, 78,244,224, 27,134, +234,253,209,181,155,125, 93,172,206,219,232,206,205,170, 85,108,219,118,161, 80,150,239,214, 85, 36,151,101, 76,151, 78, 91,146, + 29,229, 74, 71, 50,212, 78, 0,235,174,142,127, 36,254, 28,127,249, 20,218,239,253, 65,181,127,255, 0, 21,168, 67,236,206,242, +251,107,106, 27, 11,183,118,135, 14,118,230,248,218,123, 35, 96,219, 49,169,246,138,246,239,108,225, 81, 63,132, 20,246, 12,185, + 95, 92,181,113, 85,232,203,170, 93,234,124,188,224,255, 0, 4,146,236, 21, 45,180,166, 60,100, 57,144,172,147,102,189,184,158, +209,254, 22,247, 41, 54,175, 17, 19,170,123,167, 72,160, 84, 35,193,188,246,187,121,108,216, 86,109,253, 75, 99,149,165,201, 68, + 43,134, 21, 2, 5, 86,143, 93, 49, 75,106,105, 85, 86,234, 49,190, 62,117, 68, 87,136, 87,168, 78,113,225, 63, 21,230,217,158, +127, 91,147,241, 53, 5,117, 75, 84,212,207,236, 81, 87, 72,103, 68,121,153,145, 24, 4,229,164,150,101, 82,174,202,138,219,115, + 58, 98,193,200,252,101,224,252,151, 41,225,202, 12,239,133, 51, 44,186,145, 41,105, 96,246,233,178,248,197, 59,201, 28, 17,171, +186,157,124,201, 35,186,179, 6, 68,121, 25, 70,174, 95,164,237,173, 75, 62,218,177,233, 17,168, 22,157, 22,153,111,209, 33, 37, +105,135, 73,163,193,139, 77,167, 68, 67,142,173,231, 17, 26, 20, 54,144,211, 9, 83,206, 56,178, 16,144, 10,156, 82,143, 82, 78, +178, 93, 49, 28, 53,113, 19,183, 28, 85,108,189,139,190,123, 87, 80,118,125,159,125,210, 5, 74, 19,114,219,105,138,157, 46, 99, + 18, 31,167,214, 40, 85,152,204,188,226, 34,214, 96, 85,226, 78,135, 45,180, 56,227,105,126, 18,252, 55, 93,108,161,197, 62,250, +231,250,168,106, 41,170,106, 41,234,227,104,170,224,119, 73, 85,193, 14,178, 43, 21,117,112,119, 12, 24, 16,215,222,247,190, 58, + 70,146,122, 90,170, 74,106,154, 41, 18,106, 58,136,209,225,120,200, 40,209, 58,134,141,144,141,138, 50,144, 84,141,172, 69,176, +180,180,180,180,134, 54, 48,180,180,180,180, 48, 48,180,180,181,192,111,104, 5,251,125, 80, 56,143,220,198, 45,253,213,169, 89, + 9,183, 54,167,110,238, 27,118, 11,123,151,122, 90, 50,220,172,139,138,158,153, 72,178, 45,251,125,102, 37,197,116, 63, 9, 82, + 82,182, 38, 6, 89, 68,111, 26, 95,138, 30,142,216, 47, 57, 30, 78,249,221, 99, 81,164,226, 6, 84, 47,168,169,111,215, 68,181, +129, 7,171,130, 78,246, 0,236, 78,216,215,169,168, 20,209,243, 10,234, 23,181,175,110,196,255, 0, 44,119,231, 75, 81,244,103, +138, 29,229,219,186,190,226, 38,204,169, 55,100, 67,220,238, 34,247, 45,250,213,217,125, 65,164,205,147,104,206,165,216,118, 61, + 94,129,106,212, 95,186,100,197,162, 91,207, 73,151, 86,156,153, 30, 59,169, 82,141, 53,244,196,109,181, 55,135,114,241,198,191, + 22, 21,107, 15,123,247, 58, 21,239,182, 80, 41,252, 61,195,225,246, 85, 90,221,164,217,177,110, 10,125,254,238,232, 42, 29, 18, +168, 34,221, 38,172, 62,174,129,245,162, 36,204, 82,163, 52,225, 82,101,134, 98,190,203,109, 37,110, 59,183, 5,230, 62, 70, 90, +152, 57,114,114,192, 44,206, 14,169, 36, 72,144, 16,168,246,213, 43,132, 6,228, 91,204,218, 84,223, 8, 12,198, 29,193, 70,184, +191, 64, 58, 0, 88,157,200,232,162,231,111,112,185,199,119, 52,181, 31,219,163,138, 13,215,187,247, 63,109,175,153, 87,125, 18, +185,126,217, 23,151, 19, 82,104,252, 60,211, 45,201, 52,233,150, 71,240, 34,193,174,162,217,167,220,143,211,222, 93, 66,233,145, + 84,147, 75,108,134,220, 72,230,113,130,136,203, 97, 74,115,194,187,218, 60,116,241, 71, 94,159,183, 22,253, 63,112, 54,166,175, + 63,117,119, 39,104,237,104,115,229, 80,109,233,245, 11, 49,235,225,117,154,109,106,149, 86,182, 45, 90,232,117,138, 91, 85, 35, + 79, 91,126,254,228,106,167, 37, 61,109,158, 66,226,214,144,220, 23,153, 8,213,214,162, 27,132,212,225,139,174,147,174, 69, 33, + 78,131,172, 1, 25,109,118, 10,194,252,179, 32, 1,136, 25,140, 58,136, 42,221,108, 45, 99,125,129,245,219,115,107,117, 29,237, +142,245,233,107,147,209,223,222, 43, 46,151,189,123,171, 87,168, 91,247, 45,193, 96,238,236,107, 86,163,184, 18,175, 13,204,135, + 26,223, 51,155,219,155,122,229,185,225,109, 4,121,171,160, 11, 66,149, 6,229,173, 86, 75, 18,101,144,211, 81, 94, 47, 30, 86, +130,245,116,153,197,253,205,104,175,125,224,212,119, 98,196,186,104,182, 78,217,238,236,253,159,220, 25, 80,109,250, 84, 61,204, +189,109, 75,111,110,106,180, 88,240, 28,129, 37, 16, 46,122,140, 59,158,240,173,209,164, 71,165, 4,181, 37,202, 9,253, 10, 30, + 67,199, 90, 31,253,157,169,144,255, 0,100,153, 42,109, 96,108, 24, 93,173, 25, 33,108, 27, 96, 37, 66, 3,232,144,141, 71,151, +101, 98, 20,246,180, 31,222, 41, 75,252, 58,110, 5,250,122, 30,151, 3,109,247, 24,234,110,150,185,121,125,113, 27,190,246,141, + 14,226,220,138, 85,122,149, 95,137, 79,221, 29,192,219, 42, 86,219,187,104, 69,247, 57, 66,135,195,181,213,186,212,122,171,149, +122,104, 85, 74, 93, 76, 92,212, 56,173,120, 13,169,182, 94,140,242,153, 95,134,178, 36,161,188,127,125,171, 86,214,225,238, 11, + 22,199, 16, 84,107,178,163,121, 39,108,124, 29,207, 68,141,169,183,108, 72,233,163,237,245,233, 92,170,211,106, 53,186,204, 89, + 52,202, 39, 35,139,138,182, 99, 49, 2,101, 90, 83, 81,212,194,240,184,239, 73, 25,143,134,171, 36, 66,194,104,254,198,161,110, + 97, 23, 14,138,202,199, 64, 11,164, 54,162,119, 6,214, 93, 86, 98,161,171, 35, 6,218, 79, 91,118,238, 9, 4, 11,239,126,158, +238,246,218,253,134,210,215, 23,168,252, 66,238,173,122,152,237,253, 54,243, 85,110,231,171, 76,225,138,243,161,236,203, 18,102, +193,102,123,213,219, 34,129, 34,173, 62,218,133, 2,172,137,173,218,242, 46,180,203,140,244, 86, 80,236, 39,101,213,208,220,211, + 33,228,132,186,236, 80,248,135,221,139,146,237,218,187, 18,214,222,123,102,243,129,185, 51,246,200,220,219,133,110,217,182,220, +151, 54,246,175,118, 89, 27,207,114,220, 59,126,196, 88,238, 61, 5,154,162,127,128,148, 71,161,179, 83, 67,181, 56, 13,161,255, + 0,172, 27,152,151,144, 18,105,120, 98,178, 37,118, 51,199,104,151, 83,147,204, 1,108,138,237,184, 67,125, 33,173,125,181, 16, + 66,106,107,129,133,173,141,136, 1, 79,155,167, 77,247, 32,119,239,248,119,182, 58,147,171, 69,118,187, 74,182,233,114,107, 21, +153,105,135, 2, 47,132,149,185,225,188,251,206,189, 33,212, 71,139, 18, 28, 72,205,173,217,211,223,148,235, 45, 49, 29,148, 45, +231,222,121, 13, 52,133,184,180,164,182, 60, 63, 94, 23, 13,249,180,118,173,203,117,202,141, 58,225,125,219,146,149, 84,168, 68, +134,221, 57,154,140,139,106,235,174,219, 34,165,238, 12,168,183, 13,217, 13, 81,219,121,198,219,253, 26, 28,125, 73,108, 37, 1, + 41, 13, 62,232,111,214,218, 88, 87, 53,221, 90,189,235,241,103, 84, 54,214, 35,223,192,237,191,166,243,212, 43,146,234,168,162, +210,230,214,174, 85,210,219,108, 4, 84, 20,139,146, 5, 54, 10,228, 56,219,108, 55,239, 43,109,212,137,238, 41, 44, 50,192,240, +207, 45, 59, 88,201, 19,178, 27,116,186,146, 13,137,182,215, 29, 72, 27,117,198,210,176,101, 86, 29, 24, 3,251,247,199,221,233, +222,106,181,159, 75,167, 84,174,234, 93, 66,210,177,231, 69,184,235,115,168,180, 74,161,155,188,183, 37,187,104, 81,151, 91,175, + 70,163, 80, 40,200, 81,166, 32, 83, 84,169, 82,149, 18, 91,178,216,139, 78, 83, 11,126,159, 42,107, 42,103,136,187,179,237, 34, +226,147,119,235, 63,197,223, 8,251,124,189,158,219,184, 97, 16, 40,176,233,212,196, 92,251,157, 84,166,150,212,167,102,185, 76, +180, 34, 77,106,221,117,114, 22, 2, 25,135, 45, 15, 52,181, 45,110,204,125, 71,175,108,182, 23,109,174,187,130,169, 84,222,157, +223,125,186,149,249,123, 65,247,101,210, 60,100,212,104, 54, 69,155, 36, 7,224,237,133,176,149, 2,203,148,166,146,166,158,173, +205,109, 3,235,170,160, 43, 86, 98, 69,134,211, 59, 51,104,216,150, 77,129, 77,110,141, 99, 90, 54,213,159, 74,109, 41, 66,105, +246,205, 18,155, 68,137,132,126,169, 91, 20,232,205,165,197,117, 57, 82,129, 81, 36,146, 73, 39, 78,217,109, 94, 95,150, 60,146, + 85, 80,254,145,169, 22,208, 11, 40,141, 58,223, 82,180,114, 93,186, 91, 96, 71, 98,164, 27,234,212,195, 81, 80, 21, 35,159,217, +227,223, 81, 0,150, 61, 45, 98, 25,108, 58,223,168,247, 17,136,175,109,165,111,136, 46, 22,110, 90,253,251,188, 55,190,238, 65, +226, 39,118,227, 73, 22,188, 43,214,173, 93, 15,170,216,230,151, 29, 53, 11,198, 13, 89,199, 26,118,108,119, 24,169, 38,135, 69, + 37,232,207,174, 19,213,119,127,239, 68, 64,213, 43,151,138,189,231,148,233, 93,203,191,247,220,103, 10,148,232,142,246,226, 85, +105, 32, 96,149, 21, 51, 79,141, 84,100, 37, 35,175, 68, 55,129,142,128,107,190, 92, 81,109,158,214,113, 35, 67,184,108,237,202, +102, 60, 43, 2,198,163,212, 42,247, 21,248,211, 49,155,173, 80, 37,183,202,252,118,173,218,155,209,221, 83, 79,170,117, 53,160, +227, 77, 36,169,228, 67,121, 32,178,242,233,207, 57,194,234, 71, 15,220, 39, 90, 75,109,193, 77,191,119, 2,124, 94, 96,220,151, +161,219,182,108,103,243,144, 18,185, 21,119,174, 89,106,100,163, 0,129,224,171,201, 60,131, 83,252,135, 54,165,204,160,150,105, + 50,197,106,184,152, 41, 60,176,194,223,170, 17,180, 5, 22, 29, 67, 58,155,146,119,189,240,193, 93, 73, 45, 59,170, 45, 73,228, +176,184, 26,172,111,176, 36,139,220,223,181,129,216, 91,107, 91, 29, 21,246,100,113, 47,186, 91,235,125,110, 4, 59,162, 92, 75, +222,214,164, 89,244,136,116,189,196,146,195,109, 87,221, 69, 6,164,227, 77, 68,157, 83,101,164,170,228,142,252,250,245, 93,166, + 94,150, 12,132,127, 7, 30, 90, 93,113,183, 73, 87,102,245,197, 62, 8,247, 59,106,118,179,113, 23,103, 90,182, 36, 75, 2, 30, +235, 85,168,116, 25, 13,199,172,212,107, 14, 87, 43,209,216,152,205,189, 33,239,126, 9,109,170,147,105,114, 75, 75, 16,216,138, +219,177, 93, 46, 62,219,134, 27, 74, 71,107, 53, 4,226,104,132,121,180,197, 40,197, 20,114, 5,101, 80, 0, 13,113,230,112, 20, +149, 23,107,139, 2,109,109,247,185, 47,153,107, 22,165, 75,205,206,101,184, 39,115,107,116, 27,128,122, 88,239,235,233,133,165, +165,165,168,254, 55,240,180, 29, 66,161, 2,147, 6, 93, 78,169, 50, 45, 58,157, 2, 59,178,166,206,154,251,113,162, 68,140,194, + 11,143, 72,147, 33,229, 4,178,202, 80,149, 21, 41, 68, 0, 6, 73,209,154,212,158, 53,182,250,255, 0,220,189,141,169,219,187, +118,235,139,169,181, 89,166,213,106,148,134,158, 12, 59,113, 81, 32, 51, 52,201,162,180,181, 16,149, 58,102, 59, 6, 74, 80,165, + 0,225,167, 6,243,149, 0, 88,184,159, 52,173,201, 56,123, 58,205,242,220,170, 76,242,191, 45,166,150,104,105, 34,254,242,162, + 68, 66,203, 18,216, 19,118, 35,162,171, 57, 23, 8,172,214, 82,253,194,249, 85, 14,121,196, 89, 38, 79,153,230,209,228, 89,126, +101, 83, 12, 51, 86, 75,253,221, 60,114, 56, 87,149,174, 85,108,160,245,102, 84, 6,197,221, 86,236, 52,131,138, 95,104, 4,186, +199,214, 54, 22,197, 77,122, 13, 40,151,161,213,183, 5, 41, 91, 51,234, 13,245,109,214,109,116, 44, 5, 64,138,174,191,225,138, + 1,245,164,254,133, 45,116,112,232,102,217,108,157,245,187,134,183, 88,166,198,146,138, 37, 30, 21, 78,171, 88,184,102, 54,243, +205,188,244, 72,207, 77,118, 44,101, 40,243, 79,168,186,180, 97, 88, 36, 32,185,206,226,129, 32, 43,100, 54, 19,129,203,238,248, +173,181, 55,114, 41,115,173, 91,118, 27,233,241,105,111,225,154,189, 85, 72, 80,230,100,242, 40,251,132, 63, 37, 44,159, 21, 64, +225,180,167, 62, 34,123,107,102,109,165,171,100,219,108, 91, 52,106, 68, 40,116,214, 97, 24, 34, 35, 12, 33,184,233,142,182,203, +107,104, 54, 7, 80,164,169, 92,196,228,168,168,149, 18, 73, 58,227, 46, 26,240,155,196, 15, 27,243,131,198,254, 48,212, 79,148, +100,169,175,216,178,205, 50, 64,197, 79,217, 84,129,142,186, 74, 91,129,173,223,251, 93, 72, 91,234, 0,172,216,237, 78, 38,241, +115,195,223, 3, 50, 97,192,254, 13, 83, 65,156,103,114, 20, 53,217,166,164,168, 64, 71,218,103,168, 81,162,174,168,169,109, 8, +159,217, 41, 75, 17,164,144,208,226, 44, 52,185, 13,195,169,211,165,188,142,118, 98,207,137, 33,212, 30,203,109,137, 13,184,226, + 8,249,165, 36,125,250,127,189,191, 59, 1,126,241, 15,193, 94,202,238,238,208,211,167, 93,244,109,151,184,170,119,101,215, 68, +161,176,236,233,235,179,175, 10, 4, 24,142, 93, 76, 66,140, 20,185, 76,211, 95,167, 69, 50, 66, 18,165,179, 30,166,244,130, 3, + 76, 60,164,211,226,127,101, 42, 59, 29,186,181,187,117,109, 62,187,118,168,251,213,155, 78,162,182,200,106, 93, 34, 91,202, 95, +186,135, 57, 66, 85, 38, 43,203, 84,119, 64,193,253, 26, 87,128,151, 18, 75,183,195, 79, 26, 53,221,151,166,139, 34,240,164,187, +122,109,226,148,224,141, 17, 46,182,154,189, 13,183,212,165, 72,102, 2,165, 31, 10,109, 61, 74, 90,213,238,238,148, 4, 41,106, + 40,113, 41, 37, 5,151,232,189,226,236,127, 70,191, 20,115,188,175,140,233,189,135,151, 83, 26, 73, 43,163, 50, 69, 61, 47, 62, + 45, 50,104, 12,254,207, 83, 5, 76,154, 39,141, 95, 65, 49, 74, 20,198,204,234,241,244,170,240,114, 79,164,247,132,249, 46, 99, +193,117, 94,220, 37,165,149,227,137, 29, 21,229,130,168,211,204, 26, 46, 97, 84,246,154, 89,233,163,215, 79, 35, 71,204, 2, 88, +139, 9, 21, 81,160, 87,169,110,253, 27, 78, 31,247, 14,201, 78,246,241, 53,120, 64,159,107,237,173,207,108, 82,237,139, 90, 69, + 85,167,160,179,114, 68,163, 76,149, 92,175,220,241,144,248, 79,137, 70,138, 26,139, 29,153, 56, 45,188,228,137, 73,109, 71,193, + 94,122, 95, 89,143,236,147,185,110, 37,110, 61,103,134,205,190,118,245,118, 71,214, 47,186,246,201, 80, 28,168, 63, 81,230,241, + 76,135,214,152, 94,233, 38,103,139,215,198,113, 69,124,221,121,181,134,239,223, 25, 43,190,109,119, 54,195,105,109,159,226,243, +110, 28, 97, 16,106, 24, 17,153,172,214,169,236, 0,134,169,158, 5, 63,244, 20,106, 55, 34, 82, 21, 29,165, 56,167, 82, 2, 22, +180,183,204,210,189, 25,241,187,233,237,225,100,220, 3,152, 80,112,253, 92, 57,166, 99,153, 70,182,130, 10,152,234,164,119, 86, + 89, 18, 33,201, 5, 97, 70,145, 87,153, 52,237, 25, 88,195,132,133,228, 42, 7,154, 94, 3,127,179,211,197,122, 79, 17,114,220, +207,136,233,166,203, 50,220,174, 70,250,249,233,164,165,141, 17,213,163,121,155,158,193,230,117,141,219,151, 5, 58,200, 30, 82, +133,230, 72,149,201,211,219,222,171, 18,185,121,221,181,168, 8, 8,131, 86,185,107,149, 40,105, 74,121, 64,139, 58,167, 42, 76, +127,132,143,135,244, 78, 35,167,207, 77, 71,183,193, 83,207, 4, 92, 7,166,161,226,120,232,185,171,137, 62, 46,121,194, 5,131, + 73,240, 82,160,174,160,134, 66, 7,221,173,145,216,173,173,169,238,230,227,208,109,120,108, 60,170,120,148,204,234,252,180, 33, + 69,184,116,136,238,161, 82, 57,156, 72,194, 30,120,132,178,214,123,173,224,113,202,149, 17,210, 31,105, 23,179, 6, 31,180, 15, +107, 54,119,111,211,186, 82,118,157, 59, 83,112, 85,238, 6, 95,131,103, 71,187, 17, 86, 21,122, 52,122, 72,130, 99,187,113, 83, +133, 57, 44,166, 58, 86,149,165, 78,133, 5, 20, 20, 12, 5,107,144,127,217,239, 11,228,156,117,155,248,159,196, 50, 53, 6, 69, + 81, 49,167, 14, 35,118, 89, 36,209, 81, 36,238,145,198, 25,217, 98,121, 98,141, 74,171, 13, 82, 58,223,200,246,236,191,246,140, +186,241, 7,135,185, 87,133,124, 53, 18,230, 60, 67, 79, 0,168, 49,153, 35, 86,142, 62,101, 52,112, 70,242, 72,200,138,210,199, + 20,210,176,118, 83,166, 56,218,223, 88,151,102,125,130,112,118, 42,169,192, 62,220,155, 3,248, 58,253,211, 14, 69,121,189,216, +141, 20,197,250,250, 61,248,229,122,168, 93,114,229,109, 39,197, 75,206, 82, 17, 78, 84, 37, 57,240,170, 2, 88, 75, 71, 8, 80, + 17,173,246,250, 13,156, 87,180, 78,224,103,100, 28,162, 63, 88,110,202,179, 25,220,245,218, 78, 69,118, 49,221,175,121,170, 25, +141,184,237, 53, 69,181,220, 41,161, 42,215, 76,222, 83,227, 38, 98, 92, 68,140, 74, 75,192,117, 38,227,250, 54,119,189,161, 79, +164, 73,216, 46, 46,110,123, 78,180,253, 25,154,101,232,154,149, 18,165, 73,135, 95,154,143, 16, 72,168,192,114,215,185, 18,237, + 62, 19,168, 82, 1,129, 35,223, 2, 20,149, 45, 50,202, 86, 27, 67,243,193,111,209,227,219,173,146,220,107,127,118,119,231,112, +164,239, 85,205,109, 84,218,174, 81,173,207,169, 81, 69,178, 35, 87, 35, 60,153, 16,234,149,118, 37,204,149, 42,232,125,153, 9, + 75,205, 33,229,199,142, 93, 0,191, 29,240,156, 31, 80, 50,110, 36,240,255, 0,133,248,167,136,120,250,159,140,167,206,102,204, +197, 81,139, 47, 20,147,199, 51, 60,242, 9, 52, 75, 52,159, 86,209,161, 80, 35, 44, 16, 5,210,199,204,186, 91,202,188,243,133, +252, 73,226,222, 17,225,159, 14,106,120, 26,159, 34,131, 42, 52,130,108,204,214,211, 75, 2,165, 60, 92,190,100, 48, 71,245,171, + 35,134, 38, 64,165,201,109,106, 60,175,173,120,101,186,226,227, 30,216,222, 31,145,113,169,212,222, 13,238, 7, 6,204,215,213, + 43,196, 18, 19,114,181,106,109,123, 85, 19, 47,197,202,132,164,212,146,231,141,205,215,196, 74,201,235,211, 90,121,178,118,150, +251, 86,248,244,118,209,176, 55, 14,149,181, 28, 67, 63,187,123,137, 77,165, 94, 87,124,150,160,183, 79,191, 68,251,137,138,172, + 71,101, 79,167,202, 75, 85,121,111,253, 99, 25,144,182,148,167, 95,150,150,144,124, 71, 18, 12,191, 55,139,216,145, 27,114,184, +246,164,241,181, 23,126,103,210, 85, 77,220,141,186,220, 36,237,202,118,242, 36,168,229, 86, 2,232,107, 69, 32, 92,230,240,109, + 65,169, 66,136,128, 94,247, 2,166,125,229, 68, 33,194,145,159,188,127,251, 8,246,135,139,155,230, 86,246,237,181,237, 81,216, +221,230,170,248, 18,174,153,244,186, 83, 85,171, 78,238,170, 68,109,180, 49, 90,169, 81, 81, 50, 35,244,171,136,165,166,146,236, +232,146,128,119,194, 75,143, 69,117,254,103, 75,214, 91,226,215, 8, 67, 22, 85,150,205, 86, 35,138,175, 35,134,138,121,205, 36, +147, 69, 73, 85, 26,176,229,203, 3,162,251, 69, 57,230, 48, 97, 30,180,109, 10,167,202,197,149,139, 52,240,103,141,106, 37,205, +243, 72,104,140,147, 80,241, 4,245,244,244,226,182, 40, 37,173,163,149,163, 60,200,170, 35,145,189,154,161,121, 42, 80,203,203, +117,214,204, 6,181, 8,220,174,226, 71,130,207,107,101, 91,105,167,218,220, 83,113,207,179,208,246,122,238,169,208,173,233,177, +183, 54,243,164,208,173,170,181,102,101, 69,135,109,234, 98,103,201,178, 88, 45,207, 85, 69,134,150,209, 67,168, 82, 61,221, 78, +173, 73,109,181,173, 58,117,197, 87, 1,155,253,192,167,179,178,235,160,238,229,199,101,215,173,141,200,226,147,102,174,107, 61, + 22, 93, 90,117, 86, 35,117, 8, 59,103,187,240,170,243,222, 92,168, 76,160, 38, 69, 61,202, 40,109,109,115,248,137,137,146,174, + 80,141,116,161,143,163,193,196, 46,228,213,168, 20,254, 34,120,219,187,111,155, 38,221,113,180,211,233, 77,199,185,174, 25,241, + 97,167, 8,114, 37, 29,203,202,228,122, 53,190,165, 48, 57, 82,234, 35,200, 8, 29, 60, 21,142,154,234,183, 19,126,200,187, 31, +124, 56, 36,218,238, 11,108,125,198,175,109,125,165,181, 87,181, 22,242,163, 87, 39,211,158,220,106,188,245,210,168,215, 85, 46, + 68, 42,129,170,215,224,171,196,147, 34,233,147, 37,110,182,234, 91,105, 81,195, 44, 70,109,146,148, 54,214,158, 34,228,185, 53, + 87, 15, 81, 71,196,212, 85,249,107, 87, 71, 81, 94,180, 57, 43, 81, 65, 18, 68, 85,227,149, 89,109, 43, 77,170, 53, 86, 9, 12, +154,144,144, 89, 2,128,238,210,120, 95,158,231,148,156, 75,152, 73,194,149,249,118,106,153,124,148,217,123,102, 25,242,215, 84, + 77, 36,193,146, 72,157, 90,240,164, 26,100,118, 66,243, 71,165,192, 96,175,172,152,216,127,163,207,182, 54, 85, 63,129, 26, 5, +213, 18,131, 1,186,245,225,121, 94,117, 27,146,168, 35, 51,239,213,105, 84,250,195,212,170,127,190, 73, 8, 11,121,152,244,248, +205, 54,202, 20, 74, 90, 10, 95, 32, 5,107, 39,133, 62,218,203,122,129,108,123, 96,109,245,210, 41,177,105,109,213,209,195,221, +118,176, 97,180,134, 12,218,147,149, 56,208,159,168, 62, 91, 3,158, 81,133, 78,134,130,179,241, 17, 25, 57, 61, 53, 47, 47,103, +175, 7, 75,224,115,135,139,127, 97,141,234,237,254,138, 5, 74,189, 81, 77,202,253, 13,187,113,201,102,185, 84,122,164,166,141, + 41,170,164,208,194, 90, 47,114, 3,239, 11, 42, 8,230, 56,206, 53,160, 92,119,251, 21,218,227, 43,139,138, 79, 20,201,223,169, +214, 59,244,232, 27,125, 4,217,141,109,212,106,251, 11, 22, 36,247, 38,120,191, 94,185,121,196, 82, 76,164, 44, 39,151,221, 15, +128, 83,205,151,129,228, 17,110, 24,227,108,134,131,196,238, 46,226, 60,195, 51,120,242,140,217, 51, 4,134,110, 92,238, 92, 77, + 42, 52, 0,198,177,153, 20,104, 81, 96,232, 2, 5, 0,233,176, 24,151,241,111, 0,241, 22, 99,225, 63, 5,112,190, 91,148,164, +153,214, 76,249,107,207, 8,150,157, 4,109, 4, 46,181, 12, 36,105, 22, 38, 58,216,234, 40,236, 92,177, 35, 85,201,196, 94,166, +255, 0, 4,227,251,102,171,138,226,141, 80,145,106,127, 43,106,227,151,155,183,111,130, 40, 41,134,253,197, 45,203,106, 77,100, +206, 72,103,248, 45,250, 74, 26,201, 88, 17,189,203,148,159,208,106,118,219,255, 0, 77,225,202, 23, 11,155,155, 59,120,151,101, +141,146,115,108, 43,142,220,242,235, 79, 83, 77, 2, 85,186,237, 13,231, 25, 76, 37,173, 94, 28,153, 78, 35,192,250,189, 49,242, +243,146, 21, 28, 67, 5,242,214,185,225,237, 10,246, 37,236,223, 28, 51,160,110, 93, 50,230,159,180,155,231, 14,139, 6,141, 84, +188,169, 20,168,245,170, 53,231, 14,149, 20, 69,166, 34,238,183, 93,151, 24,202,168, 48,195,108,176,204,230, 36,178,250, 35, 54, +134, 94, 76,166,217,142,134,185,163, 99,253, 27,221,214,159, 80,165, 91,187,205,197,181,110,187,181,116,121, 33,246,109, 11, 90, +155, 92, 73,125,180,171, 33,152,105,184, 43,142,194,160,169, 67,169,117,184,146, 84,156, 20,165, 25, 60,195,123, 59,206,248, 23, +142, 41, 56, 79, 52,204, 56,182,110, 23,174,225,202,104,160,154,140, 82, 79, 49, 38, 34,167, 93, 35,197,104,209,156,173,149,152, +146, 20, 70, 93, 84,165,153,191, 32,200, 60, 65,240,254,183,140,178,156,183,130,224,226,234, 14, 40,171,154,162, 10,227, 91, 4, + 0, 9,129, 81, 29,108,114,131, 35,162, 6,187,162,128, 11, 25, 66, 51,137, 46,188, 20,224,130, 37,122,161,107,241,207, 22,205, + 68,229,213,151,193,189,253, 34, 59,113,121,149, 53, 84, 40, 55,206,223, 79,185,147,150,134, 72, 22,172,106,177,123, 29, 60, 36, + 57,159,135, 58,112,125,151, 27,107,197,206,231,238,109,253, 66,224,219,124,109,173,154,220,132, 90,144,164, 85,209, 87,159, 18, + 13, 86,231,182,219,170,182,183,153,164,123,205, 6,114,159,102, 44,244,195,114, 64,108, 32,164, 58,218,149,148,246,148,183, 0, + 30,195,186,103, 4, 59,219, 95,221, 41, 91,210,238,236, 81,174, 43, 18,191, 97, 78,179,235, 27,115, 6,133, 5,234,101,126, 92, + 7,229, 25,178,149,117,212, 19, 61,159,118,131,224,173,133,199, 8,117, 50, 23,206,113,240,235, 95,184,128,250, 57, 52, 5,238, + 92,237,211,224,251,126,238,109,132,155, 34,168,253, 90,157,107, 61, 18,125, 66, 21,175, 38, 90,150,227,236,218, 87, 93, 26,179, + 18,165, 71,166,165, 75, 33,152,239, 9,107,109, 10, 40, 18,121, 2, 82, 39,213,158, 45,112, 93,125,119, 19,229,145,230,113,193, + 73,155,199, 76,244,245,181, 20, 18,212,211,115,163, 69, 71,134,162,150, 72,214, 70, 81,203, 66,172, 80,165,217,219, 82,178,174, +170,226,135,193,142, 59,203,114,254, 18,205,101,202,100,158,183, 36,150,174, 58,154, 26, 92,198, 42, 74,174, 68,178, 51,199, 61, + 45, 92, 82, 52,106,228, 72,225,215,152, 30,200,138, 85,149,155, 79, 63,120,152,246,113,123, 73,247,246,235,219,109,167,226,139, +140,141,138,188,175,178,213,122,187,181,118, 29,241,126, 64,166,221,115, 99, 73, 93, 54,159,112, 78,182, 41,145,237, 56,210,106, + 13, 56,228,106,115,110, 33, 60,254, 41,132, 84,218, 23,238,207, 41,173, 31,246,169,108, 70,229,240,207, 70,224,147, 98,119,114, +163, 71,170,222,187,125,195,213,118,150,252,234, 12,137, 18,233, 70,139, 43,118,239, 89,244, 56,177,164,203, 97,167, 29, 12, 68, +146, 91, 60,200, 72, 79, 32, 74, 71, 40, 26,238, 94,204,253, 30, 26,228,253,212,164,238,167, 22,156, 77, 94,219,207, 82,164, 79, +131, 56,192,167, 63, 93,167, 79,170,174,154,224,118, 27, 85, 91,234,181, 93,149, 83, 76, 20,173, 8, 10,106, 34, 99, 59,203,144, +220,182,137,206,183, 63,218, 81,236,103,137,199,254,225,237,141,254,141,242,159,182, 63,197,206,219,177,183,108, 80,227,216, 76, + 93,200,157, 30, 61,114,165, 89,102,162,106, 82,110,248, 10,142,176,154,138,153, 45, 22,157,230, 12, 37,207, 23, 42, 41,211, 54, + 91,226,118, 67,149,113, 15, 14, 82, 84,113, 37, 61,110, 65,151, 37, 76,179, 61, 46, 80,244,112, 67, 83, 36, 82,198,139, 2, 70, + 26, 87, 71,230,182,191,169, 81,168, 7, 46,218,138,163,238,105,225, 55, 17,103, 28, 53,197, 21,180,220, 43, 85, 67,196,121,172, +148,176,195, 29,102,117, 29,117, 68,244,145,205, 12,142,213, 15, 41, 72, 99,120,249, 43,203,250,242,218, 47, 24,141,116,134,125, +234,246,125,236,206,223,237,103, 9,155, 11, 64,179,173,250,125, 38, 3, 59, 97,100,212, 92, 17,163, 54,202,230, 85,234,214,237, + 54,167, 88,172, 76, 82, 19,151,234, 82,234, 82,100, 72,125,213,100,173,199,207,100,132,164,111, 48, 24, 24, 29,135, 65,166,203, +102,236, 37,237,126,216, 88,187,122,185,202,169,155, 50,212,183,173,113, 82, 83, 9,138,169,233,160, 82, 33,210,147, 53, 81,146, +234,196,117, 58,152,129,101,176,181,132, 21,242,133, 40, 12,150, 11,143, 78, 49,236,142, 6, 56,109,189,119,206,237,247,106,133, + 98, 35, 63, 80,109,189,164,235,165,183,175,125,198,171, 71,147,252, 28,183,209,200,180,173, 16, 18,168,242, 38, 84, 93, 65,230, +143, 77,165,203,121,176,183, 80,219, 78,115,121,134,183, 63,207, 30, 26, 53,122,250,236,222,165,132, 99,114,242,188,210, 27, 18, + 91,123,146,215, 98,214,176,185,107, 0,113,212, 98,122, 30, 27,225,232,231,174,100,203,178,252,150,145, 76,135, 96,145, 71, 12, + 64, 48, 1,118,178,133,178,170,222,230,193, 65, 36, 12,113, 23,233, 10,251, 69,127,139,219, 56,240, 51,180,149,207, 14,246,220, + 58, 76, 90,158,253,213,105,238,225,251,107,110,170, 45,166, 69, 35,111,195,236,175,154, 61, 90,224, 64, 68,138,131,100,165, 72, +161,165,182, 28,109,216,245,192,166,197,250, 63, 62,207,199, 44, 27, 45,238, 46,247, 46,142,166,111, 45,207,164, 38, 30,218,192, +168, 71, 90, 31,183,118,209,231,218,148, 43,105,105,228, 15, 10,125,126, 68,104,146, 26, 88, 10, 34,147, 18, 26,217,112, 38,161, + 37,189,113, 27,217,255, 0,195, 62,227,251, 81,184,218,174,223,155,197, 50,161,115,219, 13, 92,234,221, 61,253,186, 37, 37,214, +218,174, 63, 83,168,185, 34,149, 99, 68, 49,148,129, 0, 85, 37, 71,114, 43, 76, 50,166,145, 6,141, 74,151,238,188,134, 52,102, +151,250, 18,218,182,237, 58,213,161,211,168,148,168,145,160,194,167,196,143, 18, 60, 88,140,183, 30, 52,118, 35,180,150,153,143, + 29,134, 82, 16,203, 8,109, 41, 74, 16,144, 18,148,164, 37, 32, 0, 53,117,113,253,101, 39, 0,112,165, 23,134, 89, 44,193,243, + 42,197, 90,140,226,116,234,236,225, 88, 67,126,160, 61,151,202,108, 86,153, 34, 86,213,206,123,208,254, 27, 80,214,248,145,198, + 53,254, 44,103,208, 52,121, 85, 11, 61, 54, 73, 76,251,132, 68, 44,166,123,116, 38, 59,183,152, 92, 53, 84,146,178,149,228, 32, + 25, 10, 82, 18,144,148,140, 4,128, 0,244, 3,160,215, 62, 61,164, 30,208, 29,190,246,125,108, 68,221,193,174,166, 21,195,185, +183, 74,103,208,246,111,110, 92,144, 91,126,238,186,153,142,218,156,168, 84,144,203,169,118, 61,155, 75, 18,162, 72,171, 73, 65, + 65, 8,121,152,108,172, 76,155, 21, 42,223,186,157, 78,157, 69,167, 84, 43, 21,138,132, 42, 77, 34,147, 10, 85, 74,169, 84,169, + 74, 98, 13, 58,155, 78,130,195,146,166,207,159, 54, 83,137,106, 28, 38, 99, 52,235,142,186,226,146,134,208,218,150,181, 4,130, + 71, 9,184,174,225,239,128,223,109, 5,235,103,196,178,120,186,133, 90,187,118, 26,145,116,193, 93,191,180, 87, 53,159, 80,147, + 34,153,115,212,232,158,253, 88,147, 10,183, 72,146,245, 74,148,212,218, 52, 38,155,157, 7,154, 22,102, 37, 42,117, 74,117,156, +212,252, 35, 69,149,207,156, 82,213,241, 20, 21, 13,195, 52, 45,174,178, 72, 34,146, 64,163, 75, 24,163,145,145, 78,133,154, 64, +177,177,184,109, 37,180,144, 64, 34,228,227, 92,195, 55,166,201, 42,232,248, 98,122,101,226,188,193,116, 80,199, 81, 52, 81, 22, + 98,202, 37,146, 53,145,135, 49,160,137,154, 69, 91, 50,235, 85, 12, 10,155, 24,223,112, 43, 69,217,158, 45,184,165,187,120,165, +246,138,241, 35,182,116,170,123, 23, 91,119, 61, 74,223,220,203,198,221,164,212,247, 82,240, 90,154,145, 18, 4,155,122, 83,169, + 76, 13,179,165,195,106, 27, 94,232,150, 88,134,243,109, 69,164,194,109, 80,163,204,105,153,125,220, 94,209,127,103,156, 61,184, +186,232, 52, 94, 47, 56,125,117,247,237, 26,244, 24,113, 99,110, 45,186, 93,145, 37,234, 60,166, 35,176,203,104,151,241, 45, 78, + 41, 9, 74, 64,234, 84, 0,215, 43,127,189,146,225,251,255, 0,151,141,236,252,108, 47,255, 0,212,117, 98,186, 62,141, 70,193, + 80,109,171,134,184,206,250,111, 75,206,209,168,117,106,171, 77, 58,108, 79, 9,215, 41,240, 31,150,134,220,228,180,193,240,212, +166, 64, 56, 32,224,156, 28,234,227,226,156,231,194,238, 48,205, 41, 42,234,248,179, 49,165,167,161, 88,226,165,164,134,136, 37, + 61, 52,107,164,104,141, 76,102,218,138,130,204,119, 54, 10, 44,136,138, 40,222, 15,200,252, 93,224,124,162,178,142,139,131, 50, +202,202,154,247,146,106,202,201,235,245,213, 85, 72,218,137,121, 92, 72, 47,160, 51, 4, 81,176,187, 49,187,187,179,241,151,216, +125,188,123, 87,177,188,108,155,223,120,111,251, 87,109,173, 15,226,150,243,164,127, 8,239, 10,196, 74, 37, 35,235, 57,181,155, + 69,248,144, 61,246,107,137, 71,189, 56,212, 57, 74, 66, 51,149, 6, 20, 64,192, 58,156, 37,241,179, 92, 40,241,203,106,237, 46, +225,220,246,214,221,239,165,175,107, 85,218,191,118,150,241,196,122,245, 54, 52,165,184,202, 93,157, 69,169, 68,120, 38,161, 71, +146,245, 54, 31,189, 67,112,189, 2,106,233, 81,140,168,239, 42, 43, 5,184, 0,123, 51,184, 59,180,120,227,226, 73,123, 35,122, + 92,215, 45,167, 72,254, 47,238, 75,185, 21, 91, 80,210,133, 79,223,104,181, 43,126, 19, 17,149,245,197, 62, 75, 62,234,182,234, +239, 21,254,143,159,153,164,114,168, 12,131,250, 11,240,185,177,214,207, 9,155, 29,181,187, 7, 78,186,100,213, 41,118,141, 53, + 54,133,175, 62,230,151, 77, 98,183, 95,122, 59, 21, 90,234,227,165,168,172,176,212,202,144,167,198,170, 72, 83,113,218, 4, 70, +167, 60,241, 64,109,167, 22, 49,227,201,203,105, 56,158,154,191, 47,204,234, 97,226,113, 20, 74,241,160, 40,145,211,114,230, 28, +196,153, 44,218,218,229, 29,117,125,130,110, 45,140,253, 29, 23, 52,173,225, 42,188,187, 50,202,105,103,225, 38,158,102, 73,100, + 43, 36,146, 85,137, 41,207, 41,224,123,174,133, 0, 58, 57, 91,243, 2,216,220, 12, 63,180,219,118,145, 74,138,212, 72,144,152, + 67, 77, 33, 40, 72, 13,164, 97, 41, 24, 0, 0, 58, 12, 1,168,214,125, 36,238, 26, 44,170,175, 15, 59,113,196,205, 42,137, 14, + 22,224,216, 59,137, 73,176,171, 53,136,200, 98, 51,213, 75, 2,242,167, 86,221, 76, 42,145, 5, 42,168, 46, 29,213, 78,163, 42, + 16, 60,230, 50, 42,243,249, 18, 18,251,170, 18,111, 4, 30,160,228,122,141, 71, 19,233, 42,111, 69,183,107,112,145,182,219, 37, +239,241,156,189,119, 91,118,169,119, 3, 20,143, 17,179, 37,155, 43,111,169, 53,105, 85,170,210,208, 57,148,210, 5,199, 87,180, +163, 53,144,128,239,189,200, 40, 89,247,119, 16,170,219,194,167,174, 95, 16,120, 99,216, 11, 9, 94,160, 7,211,125,224, 42,220, +240,214,234,188,157,100,223,109,175,219, 22,175,140, 41,151,191,134,156, 91,250, 68, 41,133, 41,137,143, 85,182,168, 14,158,207, +166,253, 27,157,160, 45,183,222,221,240,212,253, 25, 45,199,171,212,118,115,136, 29,176,151, 33,247,169, 54,142,229, 80,110,122, + 75,110,168, 41,184,138,190, 45,181, 67,159, 26, 49, 42, 42, 67, 62, 61,152,135,139,120, 8, 14, 76, 91,137,202,221,112,234, 82, + 58,139,207,209,155,219, 90,149, 31, 99,247,187,115,230, 71,118, 60, 91,231,115,160,208,105,106,117,183, 80, 38,192,177,109,214, + 20,185,241,212,165,114,187, 24,213,110,170,156,110,100,164, 31, 22,152,242, 20,163,202, 2,101, 13,163,120,178,105,219,196, 78, + 41, 52,214,229,243,208, 27,116,230, 8, 34, 19,125,252,208,250,189,247,193, 60, 25, 90,149,240,199,132, 5, 93,249,190,206,228, + 95,175, 40,212, 76, 97,251,185, 38, 61, 63,225,181,182,194,210,210,210,213,119,139, 59, 11, 75, 75, 75, 67, 3, 11, 86,231,168, +244,137, 50,219,159, 34,151, 78,126,123, 74,105,109, 77,122, 12,103,101,180,182, 20, 20,202,155,146,182,138,208,164, 40, 2,146, + 20, 10, 72,200,193,213,199, 75, 89, 4,141,193,177,247, 96, 98,222,186, 77, 45,198,165,199,114,155, 79,113,137,239,123,196,230, + 87, 14, 50,154,153, 32, 41, 11, 15,203,109, 77,226, 67,220,237,182,121,150, 10,178,128,115,144, 52,195, 92,219,245,176,182,149, +122,185,103,220,245, 58,117, 38,177, 14,165, 62,137, 88,166,205,183,100,165, 18, 94,180,182,226, 54,233, 43,153,126,224, 91,159, + 5,155, 45,232,238,197, 88, 82,208,167,241, 10, 62,100,128,214,182, 39, 90,175,186,220, 34,237,174,239, 92, 87,189,203,114,202, +174,179, 62,249,180,173,155, 70,114, 96, 73, 97,182,233,177,104, 55, 4, 90,205, 74,117, 39,196, 97, 70, 44,234,189, 58,155, 70, +165,212,213,146,151,233,244,134, 89,229, 24, 36,239,229,230,133,166, 97,152,203, 44,112, 21,216,197, 98,193,245, 40, 4,130, 13, +194,173,216,141,137,210, 0, 32,219, 9, 75,204, 10, 12, 42,165,129,253,111, 75, 29,135,199, 97,247,227,225,226,159,135, 84, 56, +170,163,213, 95,119,172, 38, 13,219, 88,247,105, 22,125, 85,171,145, 66,203,155, 66,162,214, 18,136,138,166,123,195,149, 5, 46, +227,166, 8,173,167, 43,148,194,220,113,158,102,153,112,164,250, 39, 17,220, 62, 92, 21, 58, 93, 58,145, 81,141, 34,185, 94,151, + 97,212,226,211,133,167, 80,106,170,170,149,249,112,215, 45,203,118, 92,198, 28,166,133,197,168, 51, 86,164, 85,125,241,199,121, + 87, 1,181,165,233, 10,109, 15,161, 74,182,220, 60, 32,109,125,201,123,215, 47,185,174, 86, 27,170, 87, 55, 43,109, 55, 45,216, +204, 61, 29, 48, 33,205,219,106, 84,138, 75, 84, 24, 49,212,193, 12, 91,213, 70,167, 84,156,170,176, 58,201,118,122,151,204, 20, +134,139,116,232, 92, 31,109,165,187,120,209,239,138, 92,218,235, 53,202, 30,226,110,142,227, 66,113, 79, 68,117,145, 63,115,169, +177,233,206, 81,214,211,177,136, 85, 10,144,168, 20,183,233, 12,118,138,245, 57, 11,202,185,222, 14, 56,145,195,220,178, 86,106, +161, 46,139,128, 74,144, 27, 78,161, 30,201,246, 67,125, 94,175,251,237,109,176,143,246,189, 67,202,133,111,239,189,175,107,245, +235,111, 53,190,235,247,192,151, 23, 20,214,213,149,120,238,245,161,112, 90,149, 90,123,118, 93,223,110,218,116,155,146, 37, 34, +165, 34,213,175, 92, 87,142,216, 91,119,181, 10, 5,199, 93,102, 0, 98,139, 83,155, 86,172,154, 91, 40,230,144, 74,145, 17, 79, +169,147, 50, 58, 23,100,166,241,143,176,110, 91,118,252,155,150, 60,202,122, 85,111, 48,244,196,211,236,186,197,114,218,166, 92, +206, 88,209,239, 59,138,199,163,207,137, 73, 87,214, 85,120,214,244,153,202, 90, 88,103,194,117, 48,100, 69, 14, 42, 91,110,197, + 77,226,167,194, 53, 62,224,168,214,164, 92,187,177,184,117,202, 93,207, 86,176,238,171,166,132,252, 75, 34, 52, 75,138,247,219, +171, 22,218,178,232, 23,101, 70,124, 75, 81, 19, 90,146,100, 90,180,154,171,241, 99, 73, 98, 19,149, 8,201,195, 8,139,207, 29, +204, 89,174, 3, 54,230, 28, 89, 84,218, 93,213,112, 83,169, 85, 8, 13,183, 62, 50,109,173,179,153, 84,126,170,109,166, 45,137, +213, 38,111, 9,246, 59,149,202,124, 73, 44,199, 68,199, 96,199,169,183, 24, 77, 91,133, 9, 76, 55, 93,134,181,227, 28, 52, 99, + 65, 52,210, 44,161, 35,212, 99, 50, 88,176,141, 85,236, 90, 50, 67, 23,214,214,210, 86,214,179,139,144, 10, 77,101,201, 85, 4, + 92,245,183, 75,220,116, 61,133,133,239,123,246, 56,201,110, 78, 45, 54,210,143, 71,187, 69, 26,206,190,106, 23,221,159, 10,239, +174, 77,176,164,109,229,114,157, 93,162,200,181,109, 26, 5,194,253,122,230, 66,160, 17,111,208,220,164,222, 86,170, 68,245, 41, + 75, 91, 85,192,134, 91,117,109,188,218, 1,107,139,222, 30, 41,208,160, 38,182,212,154, 96, 81, 98, 34,164, 83,236,138,173, 86, +132,229,233, 73,143, 2, 77, 86,210,160,202,167, 82,150,229,102,224,167, 57, 85,155,240,177, 28,130,105,117, 4, 48,181,191, 26, + 67, 73,200,239, 78, 20,232,247, 93,227,184,151,181, 59,113,239,187, 58,175,186, 16,107, 20, 59,177, 20, 6,109, 25, 81, 38, 91, + 85,235, 26,194,177,234,148, 36, 49,113, 91, 83, 67, 13,174, 54,221, 80,228,162, 75,124,147, 24,118, 76,180,176,251,104,120,114, + 97, 71,129, 29,185,102, 75,134,157,116, 87,233,212,215,107,237,221,142,192,102,217,219, 23,234, 46,220,107,153, 26,125, 70, 66, +175, 41, 86, 50,235,200,165, 73,156,220,169, 11,130,138,162, 26, 67,243,150, 16, 68, 68,166, 32,196, 67,134,204, 81,243,102,154, + 55, 96, 25,172, 90,225,180,141, 75,126, 89, 22, 86,190,141,141,197,203, 50,155, 12, 6,246,205, 70,202,164, 3,177,176,251,143, +218,190,227,175,167, 96,112,231, 92,188, 65,108,253,156,237, 21, 85,234, 37,205, 77,117, 54,204, 75,162,127,188,109,197,114, 52, +173,190,178,220,185,255, 0,131,148,235,130,242,141, 38,152,219,246,149, 21,117,198, 37, 41,160,227, 97,192,213, 50, 76,191, 5, + 44,199,113,212,227,232,226,211,100, 21, 21,169,244,186, 61,249, 82, 97,202,109,126,252,241,169,187, 81,118,165, 40,183,173,245, + 24,119, 77,250, 28,149, 70,101, 47, 81,162,201,144, 35, 61, 61,165, 56, 94,122, 73,102, 57,144,174,112,155,149,235,194,253, 54, +254,147, 62, 77,127,114,247, 1, 75,185,109,201,150, 53,252,136,169,180, 27, 69,243,183,234,190,107,183,181, 30,208,169,151,173, +119, 21, 76,139, 79, 23, 21, 86,150,196,154,122,162,203,114,155, 49,212, 72,121,217, 74, 76,164, 52,251,165,194,237,235, 26,209, +179,173,109,147,172, 76,141, 81,133,182, 87,238,208, 87, 46,106,213,219, 71,163, 71,122,208,188,167,211, 39,166, 53,106,131, 47, +109,107,104,172, 50,153,222,250,242,158,167, 46,147, 80, 97,184,166, 59, 47,172,204, 15, 66, 37, 60, 57, 12,220,152,228,168,144, + 77, 35, 16,197,159, 68,106,161, 88,234,102,104,191,104, 88, 1,114, 84,173,192,114,193,114,237, 84,161,152, 32, 33, 64,176, 2, +228,155,141,128, 13,233,248,131,216, 12,110,107,245,216,236,216,210,174,155,102, 19, 51, 24,254, 12, 74,185,104,144, 74,126,174, +102,127,139, 76,118,175, 5,151, 65,108,123,159,142,181,183,206, 74,121,146, 94, 82,148, 50, 14,180,215,116,165,219,144, 32,213, +182,215,234, 10, 53,122,167, 42,135, 42,149,118,221,213, 70,214,169, 21,107,134,188,202,229, 86,106, 18, 4, 96,219,174,148,212, + 36,135,144,147, 32, 54,202,144, 24,109,164, 55, 29,160,157,199,135,107, 57, 22,193,139,100,166,162,160,236,107, 61,139, 88, 85, +154, 99,195, 80,113,154, 42,105, 34,162,212,101, 58,174, 69,115, 39,197, 74, 10,206, 14, 19,204,123,235,144, 59,209, 19,116,167, + 75,115,110,234, 52,115,107,213, 46,219,210,159, 99,220,151,204, 58,236, 73,212,214, 41,117,135,213, 18,124,250, 47,142,152,243, + 99,207,171, 72, 8,129, 8,201,140,219, 77, 59, 90,111,154, 74,212,166,148,189, 76,174, 26,121,106,106, 29,239, 34, 68, 9, 80, +110, 46, 9,181,201,219,183, 91,237,190,248, 60,236,234,136, 7,148,183, 95,203, 29, 10,217,141,236,135,113,237,133,155, 34,137, +104, 94, 55, 7,131, 64,143, 79,110,109, 18,136,236,138, 4,185, 20, 96,229, 38, 91, 17,174, 7,228, 6, 36,186,204,216, 18, 99, +188,239, 63, 35,146, 34,186,166, 84,235, 74,109,197,229,117,203,231,113,228, 81, 38, 76, 27,115, 80,181,169, 66, 35,130,109, 86, +161, 91,167,203,170,192,109,238,102,132,198,233, 52, 53, 63, 33,184, 44,146,133,204,125, 1, 82, 99, 70,241, 95,139, 22, 83,173, + 37,181,115,182,167,188,183, 37,129, 6,159,182,219, 79, 95,118,221,177,236,232, 45,208,224,166,152,212, 39, 19, 54, 68, 95,130, + 92,184,146,164, 69, 83,145,233,254, 40, 83,113,195,107, 72,113,182, 68,151, 7,140,251,152,109,170, 91,157,184,213,165,133, 85, + 47,171,178,127, 33,230, 75,114,171,213, 23, 35,250,156,199, 84,159, 15,147, 25,200, 41,229,229,200, 61, 52,228,156, 45, 83, 33, + 46,213, 9, 12,109,184,184, 98,214, 61, 46, 54,177,183, 93,246,239,141,118,204, 17,118,208, 89,135, 93,192, 23,247,125,248,187, +241, 61,191, 16,171, 20,120, 91, 43,100, 59, 38, 45, 50,223,155,227,110,163,143,165,182,103,212,183, 14, 41,104,204,160,206,247, + 98, 91,122,157, 79, 90, 99, 41,149, 50,183, 97,190,216,132,184, 46, 57, 2, 52, 39,156,210, 5, 41, 40, 66,220, 89, 66, 27,109, + 42, 90,220, 95,192,219,105, 72,202,150,226,212,112,218, 7, 82, 73, 32, 0, 59,247,214,204, 79,218,105, 60, 77, 67,171,238, 54, +206,186,245, 31,112, 40,173, 83,169, 53,218, 12, 24,116,183,153,221, 11,113,130,220, 51,122, 91, 76, 85, 22,150, 26, 76, 26,164, +146,195, 50, 28, 10, 83,241,203,235,111,199,134,228, 45,102,150, 23,179, 43,113,174,103,163, 78,220,186,172, 10, 83, 3,192,117, +104,185,234,127,195, 25,237, 41, 32,164,174, 53,175, 72, 83, 84,104,143,114, 21,146,164,150,212, 20,190,185,198, 4,179, 46,173, +203, 50,156,190, 58,121,100, 74, 87,131,103, 86, 97,169,159, 98, 92, 0, 11,184,125,138,176, 91,105, 32,109,107, 6,154,136,106, +106,106, 25,213, 76,161,250, 16, 54, 3,176, 36,216, 2, 58, 17,126,183, 62,252, 48, 60, 43,109,125, 79,127,119,214,218,118,158, +185, 44,218, 22,100,195, 85, 21,152, 78,173,176, 24,129, 33,164,215, 46, 72, 51, 89, 87,232,220,113,192,221, 34,148,242, 50,174, +121,115,101, 55,205, 29,104,115, 82, 78,211, 25,177, 59, 3,102,236, 21,187, 50,139,108,185, 46,165, 62,173, 33,153, 53,170,245, + 73, 17,145, 54,114,162,180, 89,135, 17,150,162,180,148, 67,165,176,133, 61,224,176, 57,202, 21, 37,197, 41,197,149,100, 62,122, +131,113, 6,106,185,165, 96,104,175,236,208, 11, 33, 34,197,137,182,166, 35,168,189,128, 0,244, 85, 23,220,156, 61, 80,210,154, +104,136,127,239, 28,220,251,189, 7,243, 39,212,156, 45, 45, 45, 45, 48,227,119, 11, 95, 8, 4, 16, 70, 65,232, 65,215,221, 45, + 12, 12, 83, 67, 45, 53,146,219,104, 65, 61,202, 82, 1, 63,128,213, 77, 45, 45, 12, 12, 51,123,215,177,246, 78,250, 90,142,219, + 55,132, 15, 17, 77,169, 82, 41, 53, 88,229, 45, 85, 40,211,185, 57, 19, 46,159, 36,164,248,107,198, 2,208,160,166,221, 72,229, +113, 10, 24,199, 21, 55, 95,128,189,229,176,101,201,126,218,136,213,251, 65, 75,139, 49,164, 82,249, 99, 86, 27,103, 36,161, 50, +233, 82, 22, 57,221, 9,192,203, 14, 59,205,140,242,163, 60,162, 65,250,242,180, 33,192, 82,180,165, 96,247, 10, 0,143,219,170, +147,196,127, 5, 56, 23,196,226,149, 89,229, 28,148,121,204, 74, 17, 43,169, 25, 98,168,208, 62,202, 73,169, 94, 41,209,127, 84, + 75, 27, 50, 11,136,217, 1, 55,183,188, 54,241,191,143, 60, 47, 87,165,200,171, 99,172,201,165,114,239, 65, 86,173, 45, 54,179, +246,158, 61, 46,146,192,237,250,198, 41, 21, 92,216,200,174, 64,180, 88,213,177,251,198,219,222, 2,182,186,252, 11, 10,228,255, + 0,246, 90,178, 91,207,151,233,189,211,147, 31, 62,108,117,239,167,207,108,248, 36,222, 91,238,100,115, 87,165,127, 3,105, 10, +113, 62, 60,170,176,241,106, 37,172,142,111,119,166, 48,172,135, 49,156,120,203,100, 12,103,174, 48,100, 58,105,148,245, 30, 99, + 13,130,123,231,195, 26, 33,168,236, 50, 48,211, 77,182, 63,217, 72, 31,208, 53, 83,100,223, 67,239, 15,232,107, 82,167, 52,206, +115, 28,238,154, 50, 15,179,179, 69, 4,111, 99,246,100,120, 99, 18,149, 61,249,111, 17,244, 97,139,115, 58,250, 99,248,133, 95, + 67, 37, 46, 85,146,229,217, 29, 76,128,143,104, 85,150,162, 68,184,251, 81,164,210, 24,131, 14,220,200,229, 95,240,156,107,150, +193,112,227,103,236,125, 9,184, 52,136,161,218,131,220,143, 84,106,146,130, 29,168, 84,101, 37, 56, 15, 74,120, 32, 14, 80, 10, +130, 27, 64, 13,182, 9, 8, 72,201, 39,100,244,180,181,212,185, 94, 87,151,100,153,125, 38, 85,148,209, 71,151,101,180, 40, 35, +134, 24,148, 36,113,160,232, 21, 70,221,110, 73,234,204, 75, 49, 36,147,142, 85,205,115, 92,203, 59,204,106,243,108,222,182, 76, +199, 50,175,115, 36,211,204,197,228,145,207, 82,204,119,233, 96, 7, 69, 80, 21, 64, 0, 0,180,180,180,181,191,134,252, 45, 45, + 45, 45, 12, 12, 45, 45, 45, 45, 12, 12, 45, 45, 45, 45, 12, 12, 45, 45, 45, 45, 12, 12,104, 15, 16,151, 95, 24, 54,239, 17,123, + 83,103,109, 12, 84,212, 54, 75,118, 69,182, 47, 27,216,219,148, 90,131,187, 24,189,180,184,101, 92,219,132, 23, 42, 76, 82, 37, +139,234,202,151, 77,160,210,125,241,138,135,213,181, 58,116,137,140,248, 9, 90, 64,231,117, 43,136,239,106,117,199, 89,185,105, +117, 10, 52,219, 42, 68,189,220,218,235, 50,177, 79,135,177,151,213,106,118,216, 64,186,248,146,182,109, 10,197, 94,196,168,220, + 27, 33, 79,182,247, 3,109, 33,236,132,171,166,163, 88,171, 53,117,221,106,132,229, 62, 29, 72,212, 41,241, 36, 73,106, 28,131, + 84,132, 47, 28,201, 10,199,108,140,227, 84, 76, 88,197, 69, 69,150,202,143,115,203,215,203,250,134,165, 20, 60, 69, 77, 73, 4, +113, 75,195,212, 85,111, 18,196, 57,143, 18,150,102,142, 70, 98,238, 24, 50,182,184,244, 70,234, 2,130, 99, 89, 13,218, 73,249, +209, 44,195,134, 42,235,106, 36,154, 46, 37,175,163,142, 87,148,152,210,102, 8,171, 36,106,161, 35, 42,200,203,203,148, 73, 42, + 49, 44, 87,154,209,139, 36,116,252,158, 18,111, 54,228,113,174,250,120,178,217,207,122,222, 77,206,102,216,218,235, 50,169,182, +183,141, 11, 96,170,118,165,187, 86,174, 81, 46, 93,174,102,187,109,151, 87,181,116,241,125,223,117,200,235,187,229, 59, 34,206, +174, 87,232,109, 83,149, 52, 24,150,188,232,144,226,189,121,221,222, 37,189,160,182,229,237,191,208,108, 59, 58,250,169,203,183, +173,190, 38,157,179,108,216,155, 3, 85,170, 88,180,107, 78,206,216,154,213,197,195,166,226,216,251,164,154, 35,177,247, 99,117, + 46, 45,225,139,109,211,166, 90,113,234, 19,223, 67, 85,233,113, 87,111, 66, 52,228,205,149,220, 51, 22, 58,149,204, 89, 65, 80, + 24, 4,167,168, 30,131,211, 95, 12, 72,196,133, 22, 91, 42, 29, 1,229, 25, 3,211, 75,197,197, 20,136,176,163,240,229, 36,235, + 18,176, 33,145, 44,210, 60, 84,241,180,133, 86, 48,170, 73,131,152, 2, 42,144,206,124,197, 76,130, 93,105,120, 70,177,218,103, +143,138, 43, 96,121, 93, 72, 43, 36,132,172,105, 45, 76,169, 24,102,149,157,128, 21, 28,178,100,103, 82,136, 60,129,132, 70, 29, + 28,224,214,249,226, 54,181, 83,222,219, 55,136, 39, 43, 85,241,100, 94,246,107, 27,119,127, 86,246,245,141,190,145,120, 91, 23, +102,204,109,181,247, 91,109,168,212,184, 17,169,213,150, 40,215,245,201,118,208,253,234, 19, 64,161,116, 5, 67,154,165,207,141, + 37, 70, 41, 62,217,106,175, 29, 60,104,113, 79, 93,164, 80,248, 84,226,128,108,102,199,212,235,214, 38,211,193,135,178, 27,169, + 46,147,113, 46, 44,255, 0,115,185,183, 61, 15,199,182, 20,196,245, 87, 38,211,216, 92, 23,154, 60,130,143, 6,156,148,254,148, +200,113,217,206, 33,150,155, 57, 67,105, 73,237,144, 49,211,211, 67,187, 77,128,242,138,221,136,195,139, 61,212,180, 5, 19,247, +157,111,240,175, 28,175, 11,103,243,113, 12, 25, 5, 53, 85, 91, 66,177, 70,164,152,227,133,180, 34, 75, 44,105, 26,133, 87,155, + 75, 19,164, 5, 65, 35,170, 0,166,216,110,227, 15, 15,159,139,248,110, 14, 25,168,226, 74,186, 58, 36,153,165,149,192, 89,101, +157, 4,143, 36, 48,202,242,146,204,144,234, 80, 53, 18,206, 99,141,156,150, 92,126,116,252, 63,207,246,190,240,179,111, 84, 45, +109,128,218, 78, 44,118,210,133, 86,172, 61, 95,169,195,163,240,195,113, 77,114,125, 93,248,145, 32,174,108,185,213,189,175,149, + 33,245,136,112, 98,182,132,169,210,134,210,214, 16,148,229, 89,216, 95,229,123,244,129, 63,242,126, 52, 63,251,173,204,255, 0, +254, 61,169,231,253, 81, 76,255, 0,200, 99,127,246, 73,254,173, 47,170, 41,159,249, 12,111,254,201, 63,213,169,173, 79,140,244, +149,147,203, 85, 89,225,206, 77, 85, 85, 49,212,242, 73, 10,188,142,118,221,157,162, 44,199,110,164,147,211,211, 16, 58, 95, 2, +107,104,105,226,164,162,241, 71, 60,163,164,128,105, 72,162,157,227,141, 23,246, 81, 18, 80,170, 58,236, 0, 27,226, 37,155,115, +253,212,126, 49,125,153,188,113,237,174,247,198,222,153, 59,193, 46,175, 96, 72,219,250, 22,228,109,202,182,202,225,187,172,138, + 21, 82,137,114,222,246,157,180,203,246,205, 29, 85, 20,205,129, 74,154,216, 8, 67,198, 83,220,180,197, 40, 34, 90,211,174,108, +123, 29, 56, 93,226,149, 28,122,109, 85,237, 78,219,189,198,219,219,123,106,234,245,201,187,145,114,220,214,181,114,217,129, 10, +149, 34,223,173, 81,102, 90, 18, 69,110, 36,113, 58,173, 81,126, 98, 97,251,154, 2,223,101, 46, 57, 49, 77,165, 17, 22,226, 63, + 64, 22, 96,195,143,159, 6, 51, 45,115, 12, 43,145, 0,100,124,245, 69,170, 85, 61,151,140,134,162, 50,135,137, 36,184,148, 36, + 40,147,243,198,154,161,241,114,174,151, 42,226,204,162,135,135, 40,168,169, 56,157,157,130, 68,186, 35,166,230,211, 71, 75, 40, + 72,213, 66, 72,165, 35, 14,129,130,132,145,152,182,181, 58,112,239, 63,130,212, 85,153,191, 6,103, 85,252, 79, 95, 95, 91,194, + 43, 26,151,149,181,201, 87,201,170,146,174, 18,242,179, 23,141,131,202, 81,202,150, 47, 18,162,175, 45,134,178, 91, 28,254, 11, + 94, 39,235,248,104,231,255, 0,249,185, 70,127,110,177,109,192,143, 34, 93,135,122,196,136,195,210,165, 74,180,238, 40,241,163, + 71,105,111, 72,145, 33,234, 68,198,217, 97,134, 91, 73, 83,175, 45,197, 37, 41, 74, 65, 82,148,160, 0, 36,235, 46,210, 35, 32, +131,216,244, 58,169, 35,115, 27,163,129,114,132, 31,220,111,139,166, 68, 18, 35,161, 54, 14, 8,253,226,216,132, 15,176,167,134, +142, 35,182,159,142,131,114,110,159, 15,251,217,182,150,232,218, 43,214,152,107,251,129,181, 87,213,153, 69,250,202, 85,110,207, +118, 45, 59,235, 91,142,131, 25,143,127,113,168,178, 84,219, 62, 39,136,180,199,112,165, 36, 33, 68,117, 47,219,205,195, 55, 28, +251,238, 54, 30,243,225,142, 29, 70,225,177,182, 89, 85,139,166,109,187, 96,220, 82, 40,155,167, 77,220,121,146, 24,110, 13,239, + 72,138,151, 99, 46,172,220, 26, 44, 70, 24,129,245,108,167, 42,145,159,169,206, 83,113, 11, 78,151, 83, 34,132,192,132,135, 60, +100,198,101, 46,147,146,224, 64, 11,207,219,162, 84,132,172, 20,173, 41, 82, 79,112,160, 8, 63,113,213,149,152,120,159,153, 87, +113,173, 39, 27,140,170,149, 43,105, 34, 16,136, 36, 15, 44, 37,116, 73, 27, 19,114,172, 24,164,140, 1, 7,202,108,119,232,106, +156,179,194, 76,171, 47,224, 42,222, 1,108,226,174, 74, 26,217,140,230,162, 50,144,206,175,174, 41, 20, 11, 43,161, 85,120,148, +144, 65,212, 46, 54,216,136, 25,208, 61,170, 30,218,237,168,164, 39,110,107,112,119, 42,161, 86,167,180,154,124, 73,123,145,195, +123,147,175,152, 73, 79, 52,102, 82,236,185, 86,131, 14,213,229, 7, 80,172, 61, 80,106, 99,238,173, 39,196,113,206,163, 77,149, +151,192,119,180,211,218, 97,189, 44,110, 46,255, 0, 64,220,170, 74,107, 38, 36, 90,246,237,239,133, 26, 85,175, 26,139,111, 48, +234,221,106,157,101, 88, 47,198,128,235,144, 71,143, 49,200,112, 41, 20,248,116,144,252,135, 28,117,248,190, 58,222, 95,232, 6, +237, 2,142,250,185,220,129, 29, 74,245,240,211,253, 90, 50, 61, 62, 20, 79,251,222, 43, 45, 99,205, 8, 0,254, 56,212,132,120, +202,153,122,212, 79,195, 92, 13,149,240,246,109, 84,165, 90,170, 40,213,156,106,234, 81, 86, 56,128,223,205,165,153,208,176, 5, +209,237, 99, 26, 62, 5,190,100,244,176,113, 87,136, 57,191, 19,100,212,110,174,148,114,202,202,135, 79, 64,238,210,202, 78,215, + 82,200,169, 32, 82, 66, 58, 94,248,215,190, 20,248,114,178,184, 89,217, 43, 15,102, 44, 56, 70, 37,191,100,208,163,210,163, 45, +222, 85, 76,168, 74, 82,220,153, 87,173, 84,156, 72, 1,218,172,250,188,153,211, 37, 41, 41, 74, 21, 34,123,133,180, 33, 28,168, + 78,200,105,105,106,151,168,168,158,174,121,234,170,101,105,234, 42, 93,164,145,216,221,157,220,150,102, 98,119, 44,204, 73, 39, +185, 56,189,233,169,169,232,233,169,232,233, 97, 90,122, 90, 84, 88,227,141, 5,149, 35, 69, 10,136,160,108, 21, 84, 0, 7, 96, + 48,180,180,180,180,142, 23,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194, +210,210,210,208,192,194,210,210,210,208,192,194,210,210,210,208,192,194,214, 53,117,217,246,213,239, 67,171,219,183, 69, 34, 21, + 94,149, 91,165, 79,163, 84, 24,146,195,107,113,112, 42,113, 93,135, 45,182, 95, 41,231,142,178,203,206,114,173, 5, 42, 66,136, + 82, 72, 80, 7, 89, 46,150,178, 24,169, 5, 77,136,238, 48, 8, 7, 98, 46, 49,196,171,235,133,221,241,219,202,252,170, 5, 5, +186,133,255, 0,110, 54,227,142, 91,183, 24,180, 43, 87, 5, 89,218, 66,156, 34, 28, 91,130,109, 22,174,210, 93,171,176,128, 27, +113,199, 24,105,215,249, 3,170, 47, 40,169,247, 49, 56,124, 52,111,189,235, 81,137, 67,173, 91, 85,184,244, 57,175, 52,212,250, +127,240, 58,177,105,211,231, 52,181, 0, 89,174,220, 21,122,163,202, 77, 11,186,164,199, 97, 13, 46, 66, 17,224,173,197,178,183, + 24,123,188, 58, 90,146,167, 20, 85,172, 74,141, 2, 59,168,182,162, 91,115,107, 92,168, 54,223,184,232,119,216, 13,176,222,114, +248,203, 92, 57, 11,126,155,126, 7,249,225,157,217,141,156,160,236,245,178,138, 85, 60, 53, 50,183, 53, 12, 57, 94,173,134, 82, +202,230,190,210, 57, 90,139, 21,176, 63,193,105, 44, 36,169, 17,217, 29, 0, 37,106,202,214,163,167,139, 75, 75, 81,233,166,150, +162, 87,154,103, 50, 73, 33,185, 39,231, 96, 58, 0, 54, 3, 97,182, 55,149, 85, 20, 42,139, 42,244,194,210,210,210,210, 88, 54, + 22,150,150,150,134, 6, 32,111,253,251,111,253, 25,127,246,206,255, 0,117, 13, 84, 31, 77,167, 61,189,153,157,251,127,142,111, +251,168,234, 6,201, 25, 61, 71, 79,216,116, 66, 7, 92,227,160,237,253, 29,191, 61,180,202,213,149, 2,195, 94,231,220,191,150, + 52,249,178,126,215,224, 63, 44, 79, 25, 63, 77,151, 39,255, 0, 6,119,218,127,150,103,111,251, 41,107,223,247,236, 95,244,103, +255, 0,219, 47,253,212,245, 4, 4, 2, 7, 95, 63, 47,223,170,169, 25, 61,186,122,250, 31, 81,243,210,126,219, 83,255, 0, 19, +240, 95,203, 24,230,201,127,181,183,192, 98,119,163,233,176,103, 24,246,104, 30,163,167,248,229,121,231, 24,255, 0, 53, 62,250, +168, 62,154,225, 35,175,179, 71, 31, 47,229,149,254,234,154,130, 42, 65,207, 67,215,212,255, 0, 96,209, 9,238, 1, 57,207, 66, +113,249,198,136,213,245, 67, 97, 37,143,253, 43,249, 99, 60,217, 45,187,126, 3,242,196,238, 7,211, 87,201,199,247, 52,251,255, + 0,207, 39,240,255, 0,146,174,190,171,233,171,114,130,127,185,167,159,151,242,200,255, 0,117, 93, 65, 69, 9,235,159,151, 79, +207,231,190,171, 4,115, 15,151,207,215,229,233,211, 26, 76,230, 21,118, 63, 93,254, 85,254,156, 37,237, 18,245,215,248, 15,203, + 19,165, 79,211, 89, 73, 4,159,102,170, 83,233,158, 50,135,207,254,106,191, 45, 18,215,211, 80,241, 19,205,253,205, 94, 80,123, +127,142, 62,115,255, 0,101,109, 65, 56, 67,100,168, 18,128,163,223,185,239,242, 25,237,223, 87, 54,211,203,202, 0, 0,118, 29, + 49,229,158,131,238,210,103, 49,173, 22,250,254,191,225, 79,233,198, 13, 68,189,155,240, 31,150, 39, 74,159,166,146, 79,127,102, +191, 47,111,249, 99,122,255, 0,213, 99, 85, 71,211, 69,207,250, 54, 71, 94,199,249, 98,244,199,175,249,172,106, 11,137, 0,145, +159, 63, 79,199,240,209, 41, 7,203, 0,118, 57,237,143, 77, 96,230, 85,191,241,191,202,159,211,140,123, 76,223,183,248, 15,203, + 19,158,254,253, 11,254,141,175,251, 98,127,186,206,189,143,166,127,144, 15,247, 54,241,159,249,225,255, 0,186,214,160,208,144, + 8,234,123,244,199,237,253,218, 36, 39, 29,124,250,119, 29,189,116,145,205, 43,199,251,255, 0,242, 39,187,252, 56,199,180,205, +109,218,196,123,135,229,137,201,143,166,116, 79,250, 55, 15,111,252,240,187,127,217,107, 94,199,211, 56, 39,191,179,119, 29, 51, +254,120, 95,111,127,241, 91,233,219, 80,111, 66,135,111, 60,254, 7, 24,209, 8,238,125, 72,239,223, 31,119,231,182,138,115, 90, +253,254,190,214,255, 0, 10,127, 78, 11,237, 51,116, 50, 88,250,233, 31,150, 39, 26, 62,153,166,112, 71,179,131, 57,237,142, 48, + 63,221,115, 94,135,211, 49, 57, 0,251, 55,241,156,227,252,112, 51,219,254,171,154,131,194, 82, 70, 48, 64,232, 51,143, 33,242, +252, 52, 66, 49,158,191, 96,244,255, 0,142,136,115,108,195,114, 42, 46, 7,248, 19,250, 48, 95,107,159,246,255, 0, 5,252,177, + 56, 65,244,203, 15,159,179,135, 31,245,191,207,255, 0,149,221,122,254,252,175,166,127,185,197,246,143,229,127,219,211,254, 75, +218,132, 10,112, 10,114,160, 9, 29, 7,168, 61,127,167, 94,243,144, 72,238,122,100,244,207,207, 69,253, 47,152,255, 0,204,127, +146, 63,233,198, 13, 93, 64,255, 0,121,248, 47,229,137,189,127,126, 89,255, 0, 71, 16,255, 0,239,127,229,235,254,107,186, 95, +223,150,127,209,197,255, 0,107,255, 0,247, 93,212, 32,130, 70, 78, 83,156,121,142,227,167, 97,235,175,129, 39, 36, 96,158,227, +228, 15,174,116, 63, 75,230, 63,243, 31,228, 79,233,198, 61,174,163,175, 50,254,235, 47,229,137,191,255, 0,126, 86,112, 79,247, + 56,187, 99, 63,227,127,235,216,255, 0,154,238,144,250,101,100,228, 15,103, 9,200, 56,255, 0, 59,241,143,159, 95,228,189,168, + 65, 28, 19,201,158,160, 12,125,189, 71, 93,124,228, 56, 61, 58,142,199,215,215, 67,244,190, 96,127,246,143,242, 39,244,227, 34, +170,163,188,157, 61,195,242,196,224, 26,250,101, 42,117,105, 66,125,155,238,173, 74, 90, 16,134,216,226,229,114, 31,117,110, 45, + 45,180,204,120,237,112,184, 87, 34, 67,142,173, 8,109,180, 2,183, 28,113, 40, 64, 42, 80, 26,145,125,139,237, 28,187,106,123, +107, 97, 92,219,161,195,163, 59, 99,184,215, 61,173, 2,228,186,182,189,141,220, 55,106,172, 25, 85, 68,137, 81,173,154,141,204, +118,206,154,106, 53,248,244,231,225,154,131,105,167, 50,136,178,214,252, 70,220,146, 35,151,215,249,251,123, 18,120, 79,167,111, +111, 18,114,247,186,251,163, 49, 85,218,222, 24,163,210,111, 53,194,156,128,245, 62,228,222, 74,163,175, 29,169,183,157, 96,172, + 9,108, 83,222,131, 80,184,101, 52,174,132,209, 41,225, 89, 75,196, 25,105, 85,110, 39,101, 73,126,161, 41,197,174, 75,239,169, +114,139,171,241, 63,239,176,162,251,170, 86,121,157, 65, 89,113, 67, 7, 35,169, 4, 18,115, 82,113,247,137,217,238, 79, 87, 22, + 91,147,230, 34, 26,136,198,185,156, 69, 79, 33, 23,221, 80, 44,145, 56, 6,222, 98,116,157,153,122,110, 71, 99,125, 27, 60, 13, +161,241, 3, 47,175,226,174, 50,162,122,236,146, 71, 48, 81, 64, 36,150, 14,107, 70,214,150,114,244,239, 20,133,117,222, 36, 93, + 65,110,172, 77,203, 45,186,186,215,180, 61,151,139, 72, 78,210, 40, 56,230, 50,147,125, 47,149, 37, 77,151, 65,231,254, 5, 97, + 72, 9,229,201,242,231, 29, 51,240,235, 38,139,199, 80,146,160,145,181,193, 5,104, 75,168,255, 0,223,202, 78, 90, 39,195, 82, +214, 13,164, 11,120,116,164, 96,142,161, 65, 94,120,215, 37, 97,212,227,199,149, 78, 9,151, 17,105,146, 42, 43,109,228,184,158, + 66,150,152, 96,162, 49, 81, 60,133,229, 15, 16,124, 93, 73, 25,192,198,117,127,135,119,198,133, 85,181,154, 92,152,232, 50, 28, +186,224, 45, 77,133,168,134,145, 77,106,160,134,156, 25,228,241,210,136, 43, 91,107, 60,205,168,199, 90, 80, 50,188, 26,248,120, +191,199, 91,223, 62,222,224, 91,217,168,122, 27,111,255, 0,163,123,205,183,183,173,183,183, 70,215,125, 26,252, 47,211,253,139, +131,216, 17, 28,143,189,110,104,215, 17,164,174,118, 53,123,111, 17, 95, 80, 78,224,219, 29,102,143,198,144,125,124,131,109, 74, + 72, 74, 85,145,120,165,105,198, 84,135, 7, 50,109,142,133, 46,164,167, 31,102,112, 78, 53,145,195,226,200, 74,117, 13, 42,195, + 67, 36,164, 41,197, 27,185, 11, 13, 21, 41, 73,194,147,252, 30, 10, 94, 8, 28,197, 41, 32, 5,103, 39,166,121,115, 2,240,167, + 70, 20, 80,180,187,134,229,185, 73,145, 29,134,150,242,101, 73,157, 30, 64, 97,134,152, 42,230,117,245, 61, 19,152,140,164, 39, + 42, 42, 1, 32,105,211,165, 85, 16,235,177,228, 37,200,205, 55, 48,170, 47,130,211,169,144,168,175,186,194,157, 76, 57, 13,129, +240,203, 11,104,243,140, 39,147,168, 74, 84, 64,202,195,197,222, 56, 99,182,126, 45,113,183,178,209,131, 98, 7, 66,105,253,247, +233,115,110,128, 3,138,247, 55,240, 35,129, 40,195, 21,225,118,129, 72,107, 19, 85, 94,119, 82,194,219,213, 27,146,171,175, 96, + 71,152,124, 11,113,237, 58,246,213,110,191,179,158,220,176, 55, 74, 7, 3, 3,126,182, 34,238,121,155,106,229,220,202, 87, 17, + 78, 89, 19,118,199,113,165,190,239,212,246,205,239,105,183,176,245,193, 6,220,171, 67, 74, 62,167,174,138,129,141, 46,106, 28, +166,201,143, 6, 89,138,153,124,121, 63, 76,188,131,211,217,192, 8,233,212,113,129,228,124,255, 0,205,115,211, 93,240,187,108, + 11, 23,121, 44, 27,215,104,183, 62,212,167,238, 22,218,110, 61,183, 91,177,239,203, 66,160,208, 85, 46,224,160, 85, 98, 2,253, + 61,213,161,121,131, 48, 56,162,244, 73, 72, 34, 68, 57,212,248,242,227, 45,183,153,109, 73,252,231,120,230,246,106,239,183, 6, + 60, 82, 94,220, 62, 83,108,205,193,221, 91, 81,182, 13,241,179, 87,213,187,104,220, 55, 36,155,231,104,106,242,164, 10, 21, 78, +166,154, 13, 41,239, 10,232,165,186,219,212,154,235,124,169,228,168,210, 87, 32, 1, 30,100,114,171, 79,131, 60, 72,204,115,136, + 37,165,205, 43, 2, 87, 83,141, 66, 67, 28, 72,146,161, 61,172,129, 53,165,192,178,216, 50, 16, 84, 54,151,115,201,126, 41,240, + 67,240,133, 90, 87,229,108, 70, 77, 84,193, 66, 19,169,160,115,246, 86,238, 90, 66,143,111, 41,114, 72,109,181, 29, 64, 44,156, +255, 0,191, 47,234, 71,247, 56, 71, 65,159,243,192,245,237,255, 0, 37,221,124,254,252,192,255, 0,251,184, 58,127,233,129,251, +191,146,230,161, 89, 94,176, 47,187, 81,114, 17,117,216,247,149,174, 99,171,195,147,252, 35,181,171,244, 20,198,115,152,128,219, +235,171,211, 88, 13, 56, 84, 8, 9, 81, 4,144, 64, 7, 88,123, 74, 75,159, 19, 69, 14,164, 21, 0,180, 45, 46, 36, 20,146, 20, + 9,109, 68, 2, 15,124,246,212,249, 51,218,185, 55,142,181, 92,123,132,103,248, 46, 42, 15,110,150,246, 51, 0,111,208,133,191, +238,181,241, 56, 81,244,203,137,239,236,225,192, 29,201,226,255, 0,215,254,171,186,248,126,153,120, 29, 15,179,135,175,203,139, +254,159,143,242, 93,212, 32, 71,158, 48, 9,235,223,204,253,191,118,188,167, 39,161,193,199, 83,242, 36,159,221,165,127, 75,230, + 63,243, 31,228, 79,233,193,189,170,162,223,222,111,255, 0, 72,252,177, 56, 1,244,203,201, 56, 30,206, 14,191,250, 95,255, 0, +186,238,190, 43,233,152, 4,128,127,185,195,159, 80, 56,191,234, 62,223,241, 93,212, 32,142,124,128,239,248,116,243,251,245,224, + 2, 84,115,211, 3,186,122,117, 63,111,200,157, 15,210,249,143,252,199,249, 19,250,113,159,106,159,254, 39,224, 63, 44, 78, 11, +251,242,241,128,127,185,197,247,127, 43,254,191,183,133,221, 47,239,203,198, 79,253,206, 35,129,231,252,175,186,125,255, 0,226, +187,211, 80,130, 66, 58,149, 12,115,116, 4,159, 63,159,111,206, 53,240,167,226,206, 58,142,135, 29,189, 58,232,126,151,204,127, +230, 63,200,159,211,129,237,117, 31,183,248, 47,229,137,190, 15,166, 96, 9, 35,251,156, 36, 99,204,241,125,223,236,255, 0, 21, +237,123, 31, 76,184, 28,127,220,226,239,156,127,141,247,167,127,249, 47,106, 16, 24,207,151,108,247,244,199, 92,126,124,181,244, +117,192,232, 61, 63,183,166,135,233,124,199,254, 99,252,145,255, 0, 78, 49,237, 85, 23, 31, 89,248, 47,229,137,191,143,166, 88, + 79,250, 56,122,245,233,252,175,255, 0,163,252, 87,122,235,233,250,101,100,119,246,112,227, 63,243,191,235,248,127, 37,221, 66, + 19, 3,190, 50, 71, 94,159,213,159,150,190,247, 32,249,119,193, 25,253,190, 93,244, 63, 75,230, 63,243, 31,228,143,250,112, 61, +170,163,254, 39,224,191,150, 38,238,126,153,113, 31,232,224, 56,245,254, 87,248,253,159,201,119,166,169, 43,233,153, 17,254,141, +252,140,227, 63,203, 3, 30, 93,255, 0,205,115, 80,137, 32,156,156, 0, 51,142,224,117,245, 61,123,245,213, 5, 32, 17,128, 51, +158,253,127, 63,145,172,254,151,204, 44,127,180,111,255, 0, 68,127,211,140,251, 84,255, 0,183,248, 15,203, 19,121, 63, 76,212, +130,113,236,221, 39, 7, 31,231,129,248,255, 0,201,111, 95, 15,211, 55, 35,183,179,120, 30,153,255, 0, 60, 47,217,254,107,125, +245, 7,245,128, 51,129,133,119,198, 14, 62,255, 0, 77, 10,172,140,244, 29,122,244,245, 31,111,111,237,209,151, 54,175,239, 83, +123,255, 0,129, 63,167, 25,246,169,251,191,224, 63, 44, 78, 33, 95, 76,228,167,253, 27,185, 30,191,203, 11,253,214,245, 72,253, + 51,220, 28,127,115,115, 63,245,194,255, 0,117,175, 77, 65,216,247,233,128,113,149, 30,227, 30,127,111,150,188, 16,112,114, 0, +207, 92, 14,248,249,244,232, 59,232,227, 53,175, 32, 30,127, 95,240,167,244,224,235, 81, 49, 23, 50,126, 3,242,196,226, 85,244, +208, 57,127,209,181,145,235,252,176,255, 0,221,103, 84,207,211, 67, 35,253, 27, 63,135, 24,191,238,177,168, 57, 45, 35, 56,193, +193, 29,252,191, 31, 95,234,208,235, 73, 57,230, 30,125,255, 0,163, 74, 46,103, 90,127,223,127,149, 63,167, 0,212,205,183,155, +175,184,126, 88,156,137,250,105, 24,200,254,230,199,108, 99,252,113,123,255, 0,217, 99, 84,213,244,210,249,127,209,175,159,250, +227,126,239,228,175,168, 52, 41, 61, 72, 62, 89,255, 0,142,168, 41, 56, 62,164,103, 31,126, 58,232,227, 50,173,255, 0,141,127, +251, 83,250,113,145, 81, 41,232,255, 0,128,252,177, 57,179,244,211,113,219,217,173,147,233,252,177,255, 0,221, 95, 94, 15,211, + 80,198,127,238,106,246,242,254, 88,253,127,254,213,181, 6, 5,142,164,147,229,220,116,200,251, 71, 97,211, 84,150, 6, 51,159, +179,211,246,104,227, 48,172,218,243, 94,253,244,175,244,227, 62,209, 55,237,254, 3,242,196,231,207,211, 85, 32,103,251,154,121, +199,252,242,113,255, 0,229, 87, 84,149,244,214, 72,255, 0, 70,150, 71,254,153, 61,191,236,169,168, 45,169, 56,237,219,247,143, + 95,191, 67, 44,117, 35, 3,175, 92,104,195, 48,171,190,242,237,255, 0, 74,254, 88, 56,158, 75,253,187,253,195,221,238,196,233, +215,244,215,249, 15,254, 13, 12,143, 95,229,149,251,191,146,159,174,168, 31,166,202, 57,185, 71,179, 56,159, 60,255, 0, 44,190, +159,179,133, 62,250,130,147,205,243,116, 35,207,203,167,159, 76,103,203,250,244, 42,153, 60,221,200, 3,183,150, 62,206,158,154, + 88, 86,212,216,125,109,255, 0,237, 95,203, 6,231, 73,183,159,240, 24,157,183,247,236,196,140,143,102,104,199,110,188,102,224, +231,211, 31,201, 71, 94, 15,211,105,229,239,236,204,199,253,115,191,221, 71, 80, 71, 82, 0,206, 51,208,227,167, 94,222,154, 25, +105, 72, 7, 35,174,124,242,122,252,243,246,104,235, 89, 57, 27,203,191,192,126, 88,199, 58, 77,183,189,253,195, 19,188,254,253, +183,254,140,191,251,103,127,186,134,150,160,120, 80, 60,142, 63,111,239,210,209,253,170,163,254, 39,224,191,150, 13,205,147,246, +191, 1,249, 99,234, 65, 0, 3,249,235,162,146, 15, 64,123,244, 31,156,106,138, 70, 79,203,207,243,246,232,132, 12,159,179,175, +223,157,105, 22,185,191, 75,116,194,120,174, 1, 61,189,113,249,249,106,176, 0, 96,121,121,254,253, 83, 70,122,244,200, 36, 12, +231,183,231, 58,174,144, 14,115,158,131, 61, 52, 76, 12,123, 74, 74, 73,234, 49,249,252, 52, 66, 7, 76,250,254,204,106,130, 50, + 71, 92,224,158,153,235,223,231,231,253,154, 41,180,246, 7,203,169,252,253,186, 65,141,205,241,131,176,191,166, 43,163, 29,135, +197,143, 79,159,217,162,144,140,142,131, 3,207,237,253,231, 84, 17,208,244, 3,175,125, 20,140,253,223,191, 68, 98, 69,192,194, + 36, 91,248,227,210, 7, 98, 79, 83,230,122,244,253,253,180, 72,193, 3,207,211,167,159,110,218,164,145,147,246,117,209, 9,237, +140,128, 1,200,251, 71,223,219, 73, 49,185,233,108, 99, 21, 18, 0,193,193,235,223, 61,241,233,162, 83,140, 14,157, 60,134,124, +191,118,168,164,115, 31,219,247,116,237,162, 80,158,163,167, 65,235,162,147, 97,115,219, 4,244, 23,177,255, 0,199,207,250, 98, +170, 64,242, 3,229,162, 82, 9,192,249,119,249,252,245,118,183, 45,171,130,238,172, 83,173,203, 86,135, 85,184,238, 26,180,164, +196,164, 80,104, 52,233,117,122,213, 90, 99,129,106, 68, 58,109, 46,158,203,143,206,146,164,161,100, 33,180, 40,242,182,165, 16, + 2, 73,213,222,187, 99, 94,182,156,151, 98, 93, 54,117,215,108, 74, 96,148, 63, 30,227,182,235,180, 39, 90, 90, 78, 20, 28, 77, + 82,158,215, 41,230, 7, 90,109, 60, 43, 32,137,165, 81, 43, 11,133, 36,106,181,237,123,117,183,107,224,250, 36,229,180,162, 54, + 49, 41,179, 56, 83,164, 27, 94,197,173,164, 27, 88,218,247,182,248,198, 80,144,123,128, 8,207, 65,220,156,249,122,157, 86, 70, + 62, 33,143,179,215,239,252, 63,110,188, 32, 18, 50,217, 14, 1,220,161, 73,115,211,185, 65, 56,237,162, 27, 73, 86, 58,128,125, + 7,127, 95, 61,101,136,223,126,191,127,195, 26,250,131, 11,131,127,120,239,138,168, 73, 56,233,212, 12, 30,190, 64,234,179,125, + 79,108,128, 65, 3,191,221,251, 53,245, 40,236, 58,103,190,122,253,191,187, 85,144,140, 43,169, 3,207,228,114, 15, 95,217,164, +240, 49, 84, 39, 42,193,232, 59,129,129,148,140,118,207,225,175, 74,108,245, 4,242,143, 47, 81,233,175,160,149,103, 24, 10,245, + 30, 99,243,231,175, 67,174, 2,178, 51,230, 48,123,121,159,195,246,235, 24,199,195,174, 40,165, 56,206, 85,212,156,142,157,254, +204,246,215,148,164, 2, 50,163,223,238,235,242,243, 58,172,224,201, 29,122,122,142,157, 51,140,159,151, 93, 92,168,148, 58,189, +195, 84,167, 81, 40,116,202,141,102,177, 88,152,213, 58,145, 73,165, 65,153, 85,171, 85,170, 18, 20, 16,196, 10, 77, 42, 3, 46, + 72,169,206, 90,136, 8,101,134,214,226,179,209, 58,195, 50,162,150,118, 10,171,185, 39, 96, 48, 91,133, 2,231, 97,181,254, 54, +183,239,197,153, 93,240, 57, 64, 30,106, 3,174, 51,128, 61, 53,233, 88, 67, 69,215, 84, 27,101, 56,241, 29, 89, 8,105, 40,238, +165, 21,172,129,140,103, 82, 39,224,247,232,242,113, 5,186, 44,209,175,126, 45,110,120,252, 41,109,245, 65, 45, 76, 98,212,168, +192,137,115,111,205,126, 34,210,167, 80,219, 22, 95,189, 38, 13,132,167, 80,143,133, 85,151,221,152, 18,178, 69, 47,152, 99, 82, + 25,217,126, 4,125,158,220, 32, 70,111,248,177,225,226,214,187,174,202, 84,112,204,221,208,222,132,198,220,171,212,205,121,104, + 12, 72,241,238, 54,151, 77,163,211,164, 45, 56,103,220,169,241,154,109, 74,229, 79, 82, 64,134,103, 28,115,148,101,101,145, 24, +213,204,187, 89, 14,215,247,144, 9,248, 27, 91,212,226,216,224,191, 5,184,251,142, 12,111,150,229, 38,134,142, 80, 8,158,164, + 20, 4, 18, 0,100,140,217,216, 94,195,204, 99,185,176, 23, 36, 3,170,254,203, 46, 26, 46, 77,165,224, 39,102,233,180,203, 98, +123, 55, 94,240,135,247,210,247,144,229, 50, 82, 28,149, 42,249, 17,191,130, 80, 39,169,184,229, 79,197,133, 96,194,183,154,100, +100, 99,197,117, 73, 37, 43, 81, 86,234, 87,236,203,238,132,204, 33, 46,221,170, 32,138,139, 45, 45,243, 6, 98, 99, 20,165,137, +143,123,195,179, 60, 34, 27, 65,240,249, 15, 57, 79, 42,214, 17,130, 72, 35, 99,155,223, 42,234,221,136,202,101,194,143, 66,171, +184,105,112,211, 76, 5,132,211,101,181, 28,123,180,100, 71, 82, 83,238,168, 82, 80,227, 9, 67, 73, 8, 14, 54,132, 97,180, 20, +130, 37, 39,125, 42,234,171,170,153, 34,124,151,131,206,170, 19, 32, 54, 57,101,207,141,200,137,172, 48, 57,190, 37, 8,222, 27, +165, 60,170, 39, 42, 9, 10,109, 42, 35,158,243, 89,104,243,106,250,186,249, 38,156,203, 86,236,231,104,202,139,157,149, 87, 85, +236, 1, 10,190,110,130,198,230,248,244,231,129,168,248,183,129,184,107, 38,225,202, 14, 30,163,155, 47,200,105, 99, 77, 38, 89, +121,146,114,215, 68,146, 59, 8,236,178, 22, 87,121, 1, 82, 69,181, 95, 73, 7, 26, 81, 90,169, 61, 79,168,208,167,204, 91, 44, +184,170,148,168, 83, 66, 11,141, 70,124, 78,167, 84, 35, 51, 29,198, 66,130, 11, 8,121,168,165, 36,146,181, 41, 14, 44, 21, 40, +224, 88,100, 92,178, 84,252, 41, 12, 58,134,169,236,223, 20, 56, 17, 31, 91,158, 31,213,209,106, 45, 85,162,212, 38, 53,239, 67, +159,220,194,222,100,171, 9, 37, 41,111, 45,133, 37,120,214,238,238, 21,145,110,110,237, 53,104,141, 18,147, 65,187,160,213,226, + 84,226, 75, 44, 52,154, 77, 70,163,111,200,247,152,240,235,208,227,114,167,192,113, 14, 20, 25, 44,164, 59, 28,191,226, 56,135, +145,206,141,115, 74,240, 69, 70,139, 58,226, 93, 94,157, 42,151, 38,217,171,209,163,191, 18, 75, 72, 91,241,167,211,107,148, 86, +235, 13,120,141,225, 15,143,117,147,200,218,176,158,118,242,164,158, 78,241, 42,202,121,105,230, 69, 46, 37,138, 83,229, 96, 54, + 39, 96, 53, 11, 27, 48,191,217, 61,150,247, 32, 99,163,184, 11, 53,202,248,178,154, 72,228,131,244,126,105, 66,170,147,211, 72, +202,218, 17,229, 26, 94, 18, 8, 15, 27, 23,116, 14,187, 34, 6, 89, 17, 67,170, 54,206, 82,238,185,177,160,198, 76,229,153, 13, +208,110, 74, 4,198,235, 44, 56,149,128, 69,106, 35, 41,155, 33, 8,201, 46, 37,233,173,153, 1,226, 91, 60,203, 41, 39,176,223, +221,171,219,215,238, 40,178, 42,213,233, 10,163,209,233,181, 8,142, 38,114, 84,251,110,185, 54, 35,209, 31, 13,197, 91,138, 79, +143,206,150,212, 57,242,124, 38,229, 16, 84, 73,240,213,204, 75, 50,143, 87,173, 84,164, 89, 20,181,168, 46,225,151, 26,159, 71, +109, 65, 14,184,229,111,223,226,166, 53, 41,224,179,148, 64,114, 79,132, 90,113, 73,200,104,184,146,174,118,146, 79,101,175,201, +205,219,204,155,102,128,180, 26,125, 18, 28,150, 98,195,105, 10, 14, 85, 92,139, 49, 44, 74,113, 69,160, 66,149, 34, 98, 36, 58, + 20, 83,202,178,235,104, 56, 3, 26,125,225,170,120,167,231,215, 85,141,112,211,105, 68, 66,108, 25,200, 98, 1, 35,204, 2,129, +118, 32,139,221, 73,211,171, 88,164, 60,112,168,124,170,167, 38,200,178,103, 72, 51, 44,237,231,149,166, 81,253,213, 50, 10, 79, +172, 10, 67, 42,201, 44,175, 42,128,126,168, 90, 67,176, 82, 27, 44,157,124, 91, 86,163,172,210, 40,209, 33, 66,112,182,149, 48, +228,143, 4,186,243,202,144,134,136, 71, 50, 71, 59,195,196, 43,253, 81,128,121,143, 54, 9,213, 9,123,191, 49,153,245, 55, 35, +206,109,168,116,233,113, 41,236,173,165,115,203,126,108,150, 24,126, 66, 34,165,149,164, 32, 41,215,163,182,233, 78, 22,166,155, + 90,143, 48,108,145,165, 85, 75,154, 37, 70,161, 46,164,219,243,155,165,183, 95,162, 83, 41,204,184,183, 31,120, 38, 3,190, 45, +101,232,203,231, 40, 76,115, 83, 50,127, 74, 20,164,143,112, 40,242, 9, 31, 98, 92, 79, 79,129, 78,140,203, 11,121,138,245, 72, +215,101,185, 49,196, 39,158, 19, 18, 21, 36,165,158, 84,115,163,196,105,234,116,116, 44,252, 60,143,172,114,249,234,105,237,243, +234, 88,226,151,149, 96, 84, 34, 93, 22,215, 29,128, 4, 3,181,141,183,216,168,177,185,166,163,240,166,136, 67, 12,245,145, 53, + 84,238, 0,153,166,177, 96,204, 18, 87, 55,144,155,186, 70,146, 43, 45,216,107,212, 1, 59, 91,122,169, 91,167, 70,186,227,184, +197,203, 10,131, 87,163,189, 10, 69, 85,214,171,148, 90, 69,113,166, 35, 70, 56,136,137, 81,234,204,184,151,100,173,214,164,200, +104, 6,254, 24,254, 26,193, 30, 33,214,177,238,127, 2, 62,206, 30, 34,208,151,119,167,131, 14, 31,170, 51,171, 76, 70,150,170, +189, 2,208,133,100, 93, 16,152,156,135, 92, 15,166,232,176, 13, 54, 74,101,165,135, 57,220, 33, 69, 97,249, 39,169,192, 0, 26, + 93,210, 95,153, 46,142,195, 48,212,207,240,138, 76,170,188,247,144, 86,212,166, 41,209, 88, 17,109,147,200,217,240, 91,113,230, + 10, 86,128,162,166, 98,165, 96, 97,201, 9, 78,178,250, 69, 65,249,177,152,150,228,245, 53, 78,141,239,234,159, 40,211,220,125, +234,189,102,123,128,204,166,210,121, 79, 70,152, 89, 40,114, 90,121,185, 11, 65,166,199,232,221,121,189,200,179, 42,152, 93, 92, + 75,230,181,135,235, 18,204, 69,152,107,221, 75, 2, 72,234, 69,174, 46, 14, 32, 60, 65,225, 38, 67, 80,102,246,156,185, 96,142, + 64,186, 65, 26,216, 43, 6, 40, 6,149,221,157,212, 46,150, 93, 69, 68,110,116,131, 41,199, 40, 55,231,232,175,112, 39,186, 52, +233,149,158, 27,247,143,120, 56,116,174,173,153, 18, 34,210,174, 57,144,247,130,194,102, 74,185,149, 26, 52,200, 23, 10,162, 86, + 96,176, 86,182,130,146,213, 93,197,161,183, 1, 8, 39,149, 38, 53, 60,110,123, 1,189,162, 92, 20, 64,171,222, 82,246,226, 47, + 16,123, 65, 75, 15, 72,127,116,120,126, 77, 82,239, 20,202,115, 40, 46,174,117,219,183,111, 65, 69,126,215, 97, 8,232,243,169, +139, 58, 27, 74, 74,185,166,114,142, 99,250, 18,209, 46,181,183,224, 68,113,102, 52,106,107,177, 37,200, 76, 89,105,113,113,218, + 56,118, 12, 55,101, 50, 10,230, 23, 86, 85, 37,215,208, 22,167,192, 67, 77,169, 69,206,125,108,205,177,123,137, 81,132,228, 77, +240,230, 79,154,105,244,170, 68,172, 70,170, 45, 44,243, 23,229,205,128,165,133,198, 42, 67,110, 60,176,176,144,220, 86,155, 75, +156,175,184, 82, 37,249,111, 22, 85, 64,218, 42, 36, 46,150,235,171, 86,247,176,186,185, 5,172, 47,228,140,198, 46, 44, 72,234, +121,147,139, 60, 39, 92,176,153,168,117, 68,140,198,218, 71,144, 3, 98,138, 64,212,159,103, 84,140,214, 0, 32, 12, 28,131,124, +126, 50,105,198, 21,146, 20, 2,150,143,132,228, 7, 26, 81,109,214,212, 65,248, 92, 74,194,146,164,156, 20,169, 37, 42, 0,131, +165,219,161,234, 58, 18, 58,228,124,254, 71, 95,166,111,180,163,216, 17,194, 7, 31,240,238, 45,193,218,248,212,110, 26,248,173, +144,137, 82,206,229, 89, 52, 54, 25,176,183, 2,186,219, 40,113, 49,183,135,111,169, 74,106, 53, 73,215,223,228, 75,245,122,111, +187,214,152, 50, 20,235,206, 84, 2, 61,217,127,158,255, 0, 24,156, 20,241, 33,192,134,239,206,217, 30, 38, 54,238,125,139,118, +182,211,245, 43,118,166,211,159, 90,217,123,137,109, 53, 37,113,155,187,182,234,235,101,180,177,115, 80,148,226, 64,116, 0,220, +200, 46,171,221,234, 49, 34, 72, 30, 25,177,178,252,214,159, 48,137, 36,141,135,159,161, 6,234, 78,231, 77,251, 48, 0,221, 90, +199,202,197,117, 32,214,105,170,234, 26,172,186, 65, 29, 84,101, 65, 54, 87,177, 10,215, 32, 13,141,138,150,236, 14,199,245, 75, +111,141, 87,232, 7, 78,223, 46,186,240,164,147,156, 28, 3,215, 4,145,249,235,175, 68,129,142,189, 7, 76, 99,191,151,125, 32, + 65, 39, 61, 71, 76, 36,140,103,167,252,116,233,141, 78,248,166, 18, 9,199, 92,122,143, 95,234,239,175,161, 36,250,244,200, 30, + 93,115,158,191,142,170,121,127,171,248,116,215,196,144, 1,202,147,156,231,167, 92,228,232, 96,111,143,129, 56, 33, 89,201, 25, +230,243,242,215,164,117, 4,143,135, 25, 61,115,251, 63, 29,125,233,140,254,206,216,252,245,215,209,215,246, 12, 1,220,121,253, +253, 52, 48, 58,123,176,136,207, 68,245,233,231,142,164,103,246,106,130,219,198, 9,242, 61, 70,124,244, 78, 14, 58,140,121, 2, + 70, 49,246,252,191,175, 84,207,110,131, 39,246,103, 63,212,127,167, 88, 6,255, 0, 17,140,224, 37,160,224,249,103,215,184,207, +168,252,247,208,170, 64, 0,231, 36, 18,123,250,252,190, 90,184, 57,205,158,184, 61, 58,231,190,125, 58,121,245,208,238, 32,242, +231, 4,117,232, 58,231,175,203,236,214, 65,232,122, 99, 32,158,221, 78, 45,197, 1, 39, 32,245, 29, 49,158,152,199,174,188, 20, +231, 36, 28,121, 28,159,179,207,240,209, 42, 73,234, 20, 7, 79,245,123,146,126,126, 67,174,168,242, 12, 40,100, 99,166, 0,243, +235,158,231, 75,169,184,235,131,168, 34,219,109,243,243,111,195, 3, 40, 3,212,147,129,248,125,186,160, 70, 70, 63, 35, 70, 41, + 35, 56, 30,153, 63, 44, 13, 12,180,144, 73, 3,167,246,126,206,186, 81, 79,108, 24,216,116, 23,254, 71, 0,184, 0, 32,116,206, +122,159,217,215, 31,158,154,162,160, 78, 58,100,103,175,175,221,163, 20,147,230, 7,221,216,158,250, 25, 89,201,230, 56, 39,183, +207,211, 31,119,244,105, 92, 1,208, 95,113,129, 22,128,114, 64,199,200,249,250,140,104,117, 35,166, 6, 1,239,246,103,200,244, +209,138,206, 65, 56,207,160,242,208,199,169,200,207, 95, 92, 14,221, 63,118,149, 7,160, 39,167,207, 95,158,248, 54, 5, 87, 76, +228,103, 25,253,159,187, 66,172,116,206, 15, 78,216,253,164,244,237,211, 70,172,100,142,152,235,220, 30,253,124,255, 0, 62,122, + 25,196,228,156,100, 1,208,227,182, 79,228,104,248, 50,250, 91,127, 92, 91,215,128,112, 14, 73, 39,167,161, 29,123,232,115,223, +168,235,158,191,184,104,199, 19,144, 83,211, 62,126,189, 61, 63, 13, 12, 80, 70, 78,114,125, 15,225,223, 58, 89,122, 97, 81,107, + 3,210,216, 29,105,243, 25,206,133, 90, 72, 39,183,153,251, 62,223,150,116,105, 25,251,186,250,103,228,126, 90, 25,105,206, 73, +200, 62,126,125, 59,253,250, 85, 79, 91,157,176, 69,216,144,119,183,250, 96, 34, 48,113,165,175,107, 73, 39, 35,175,224, 52,180, +174, 15,113,220,216,227,234, 49,143,233,209, 40, 24, 3,231,215,243,247,106,128,198, 6, 1, 31, 35,223, 85,211,204, 59,128, 49, +233,223, 61, 58,233, 18,118, 3,231,221,140,226,178, 60,250,253,223,191, 85,209,220,253,157,189,127, 63,191, 84, 81,143, 33,215, +204,234,178, 6,122,231,177,237,249,242,254,173, 16,157,137,190, 6, 8, 78,112,112, 70, 7,124,143,196,244,243,233,162, 27,234, +126,239,234,213, 4,125,189,188,191,126,189, 18, 64, 86, 14, 8, 30,125, 1,207,244,255, 0,102,181,216,133,193, 78,224,142,199, + 7, 54,115,211, 61, 62,206,158,126, 99, 69,164, 14,128, 16,123, 15,151,236,213,189,146,233, 74, 78, 19,142,153,251,112, 63,171, + 71, 55,223,162,122,140, 28,224,246,249,233, 34,215,194, 71,174, 43,165, 61, 65, 57,232,123, 99,191,167,237,209, 9, 0,142,169, +249,103, 39,175,175,217,170, 64, 18, 71,145,233,231,230,123,231,229,170,232,200, 36,116, 29,135,203,168,243, 62,103,182,176, 73, + 61,123, 96,167, 21,209,156, 1,208, 14,195,241,243,249,104,148, 3,216,156,228,224,103,250,117, 65,160, 72, 29, 58, 3,231,163, + 16, 58,231,175,203,211,211, 73,191,175,207,108, 99,107,145,181,206, 58,159,236,114,180, 36,215,120,223,178,238,166, 92,121,134, + 54,178,207,191,175,249, 50,154, 42, 65,101,248,212, 39,104, 52,196,151, 17,213,181, 46,101, 96,132,144, 65,248, 62,103, 82,170, +147,119, 79,171, 52, 99,214, 12, 27,130, 56,200, 92, 43,154,147, 73,175,197,113, 32,149, 96,181, 85,136,238, 83,215,166,114, 61, +117, 30,111, 98, 93, 13, 12,206,226,110,249, 80, 74, 93,129,102,217,118,147, 11, 61, 22,147, 89,172,205,170, 73, 66, 84, 58,128, +180, 66,104, 17,242,215,110, 85, 89, 62, 34, 74, 78, 18,162, 18,178, 78, 2, 72, 24,243,252, 53,207,158, 33,214, 52,188, 67, 60, + 91,218,146, 56,163, 6,254,160, 73,191,190,242, 16, 55,233,143, 67,190,140,252, 57, 24,240,222, 10,185, 97, 89, 6,113, 87, 87, + 57, 12, 1, 4, 44,130,152, 2, 8,181,138,211,143,223,140, 91,113,184, 80,224,223,122, 90,127,248,197,225,195,111,141, 78, 74, + 74, 28,185,236, 6,100,109,189,210,202,149,255, 0,194, 25,155,109, 45,182, 30,116, 14,184,114, 58,193, 35, 36, 29,114,235,126, + 61,136,232,153, 30,101,195,194, 78,234, 11,142, 74, 18,167, 81,180, 59,192,184, 84, 27,145,224,126, 38,225,219, 27,129, 13, 41, +129, 85,124,254,171,109, 79,106, 42,220, 56, 5,240, 78, 79, 93,141,126, 51,110,161,151, 93, 72, 82,213,250, 21,147,128,162,159, +242,172,156,116, 75,192, 96,143,245,128,214,109,101, 34,179,125, 87, 98,219,150,188, 73,117, 58,171,235, 8, 75,113, 88,113,228, +190,130,160,148, 6,130, 7,194,176,163,212,158,137, 41,207,108,226, 37, 67,197, 89,254, 85, 44,107, 65, 92,242,128,109,202,127, +172,140,251,130, 53,244,131,234,154, 77,174, 21,133,241,105,113, 79,128,254, 26,113,109, 13, 76,249,182, 65, 22, 83, 80, 16,177, +174,164, 11, 73, 52,123,127,120,210, 70,162, 57,108,123, 78,146,165,250,169,223, 16,133,191,246,226,251,218,171,186,173, 97,110, + 77,165,112,216,183,165, 5,229, 49, 86,182,110,106,115,212,202,172, 69, 5, 40, 7, 80,219,163,150,100, 37,129,150,164, 48,167, + 88,117, 63, 19,110, 40, 29, 97,233,193,243, 24, 29,250,143,184,116,215,232,143,190, 62,204, 45,147,226, 95,110, 34,219, 28, 90, + 85,225, 64,173,211, 34, 4,217, 87, 45, 7,192,123,116,108, 57, 14, 35,197, 13,193,172,182,131,239, 52,194,172,248,180,249,101, +232,171,201,194, 80,172, 40,106, 85,157,236, 48,246, 94, 89, 49, 96, 11,150,111, 16, 59,185, 80, 43, 83, 18, 93,168,222, 84,251, + 54,159, 41,214,155,241, 92, 81,129, 64,166,133,196, 36,117, 74, 67,170,207,108,116,206,173,202, 63, 17, 40,214,142, 55,205,233, + 13, 21,112,217,227, 87,141,135,185,128, 46, 29, 67,117,210,202, 74,244,212,246,213,142, 20,207,126,143,124, 95, 14,119, 61, 31, + 6,200, 56,195, 36, 55,104,107, 68,114, 83, 2, 59,199, 46,168,204, 70, 69,177,250,200,100,120,157,124,223, 84, 73,137, 96,225, +130, 70,121, 22, 8,237,202,133, 96,250, 28,227, 72,168, 32, 0, 58,146,113,140, 31, 63,151,222, 53, 61,230,125,146,190,201, 76, + 62,208,225,254,252, 87,128,217,112,248,251,193,118,173,197, 4, 39,152,242,173, 11, 29,115,211, 32,117,193,211, 69,186, 94,193, +159,103, 5,247, 75, 55, 6,222,220,187,247,177,170,142,168,178, 84,212, 27,150,141,124,210, 39, 70, 74,144,228,182,226,199,187, +233,222, 60, 23, 11, 1,196, 7, 82,242,195,107,113, 42,240,151,142, 83,177, 77,226, 46, 75, 83, 47, 41, 81,193,177, 55,242,216, + 0, 46, 73,185, 22,183,223,238,190, 25,235,190,143,254, 42,229,177,123, 69, 87, 14,170,171, 21, 80, 22,161, 11, 51, 57, 1, 84, + 2,160, 93,137, 3,114, 63,142, 35, 1,192, 79,179,155,127,248,252,190,165,208,246,210,151, 26,220,219,219, 90, 68, 49,185,187, +209,119,179, 45,157,189,219,184,210,112,227,112,228, 57, 29, 33,219,162,244,145, 27,153, 80, 40, 80, 57,165, 61,128,236,151, 33, +196, 10,146, 38,173,194, 71, 5, 92, 32,251, 61,109,198,127,137, 11, 71,248,111,187,134, 47,186, 92,156, 68, 95,208,233,213, 77, +203,169,188,166,210,220,230, 45,176,210, 20,198,221, 91, 60,222, 42,147, 78,163,161, 14,132, 16,169, 50,102, 40, 41,100,251, 2, + 70,221,108,222,222,208,118, 35,135,219, 98,141,182,187, 99,183, 80,221, 22,253,169, 5,240, 28,175,120,202,109,117, 43,158,224, +172,168, 42, 69,193,113,212,166, 35,154,109, 86, 73,117,239,122, 88, 75,220,172, 22,219, 70, 15, 39,112, 35,202,153, 34,108, 9, + 83, 16,228,242,167, 30,167,205, 67,209,101, 60,247, 40, 75,203,132,133,184, 16,103,115, 6,213,204,193,117,183,249,130, 73, 35, + 5, 53, 87, 20,120,131, 91,154, 84, 73, 73, 68,198,158,137, 73, 10, 65,221,198,214,239,181,250,134,185,234, 8, 61,113,217, 30, + 12,253, 20, 41, 50,184,169,243,158, 45,133,115, 76,244, 44,114,114,236, 90, 10,109,118,101, 69, 7,109, 69,110, 68,166,247, 32, +244, 91, 5,122, 46, 93,207,151,112,185, 82, 84,201,237, 85,196,152,174,184, 88,241, 23,239,197, 8,146,129,239,112,210,195,217, +143, 82, 97,220,134,151,240, 7,148,160,230, 82, 64, 42,108, 46, 11,170, 52,200,142, 42,108,229, 75,154, 25, 10,128,251,176,220, + 69, 62,231,164,248,160, 73,129, 34, 43, 32,148, 79,109,191, 21,101,149, 97,198,164, 54, 36, 52,149, 5,184, 19, 97,136,251,117, +212, 9,207, 47,222, 75, 83,204, 70,166,198,109, 84,203,178,149, 49, 96, 25, 28,237,178,132,166, 28, 66,181,167, 45,188,144, 84, +217, 47, 45,181,163,161,199,231,178,168,238, 61, 67,174,165, 50, 30, 68,210,138,101, 69, 41, 66,226,214, 24,154,175, 18, 68, 23, + 25,200, 16, 43,237, 53,206, 89, 40, 41,101,229, 18,227, 11, 67,153,107, 85,228,149, 94,103,214, 88,177,181,218,251, 49,190,198, +219, 19,126,194,199,107,117, 59, 14,220,202, 56,115, 41,161,100,166,134, 46, 65,164,220,199, 24, 80,202, 6,149, 99, 29,208, 93, + 86,200,179, 38,148,109, 12,205,160, 36,107, 36, 87,151,170,161,165, 46,223,113,167,151, 78,170, 42, 43,148,218,139,143,133, 60, +212,244, 50,100,136,203,150,242,135,136,250, 60, 22,164,198,112,144,183, 19, 29, 76, 58,165, 45, 0,185,112,131, 94,118, 83,239, + 68, 41,110,145, 84,110, 85, 61, 77, 75,109,178, 94,166,215,169,104, 8, 67,209,226,188, 8,118, 28,136,175, 69,146,129,147,227, +180,167,144,130,160, 73, 24,237, 74,148, 41,180,184,241,225,200,118,224,181,231, 71,136, 98, 84,161,159, 30,183,110, 75,101,207, +122,101,135, 67,139, 34,171, 78, 67,173,161, 72,116, 98, 92, 85,128,204,132, 60,193,241, 18, 44,199,101, 84, 85,252, 43,112,177, + 42, 84, 4, 52, 95, 52,245, 4,179, 84,167,160, 46, 60,163,202, 84, 82,137,173,158,119, 35, 43, 36, 50,180, 41,160, 2, 22, 0, + 48,114,196,178,177, 80, 55,211,178,238, 64,223,114,118,234, 70,226,196,234,190,160,112,250, 40,232,234, 98, 13, 29,180, 72, 74, +135, 58,129, 51,142, 88, 77,113,191,149, 76,133, 66, 76,142, 54, 49,137, 46,240,201,115,180,187,121,113,159,112,167, 74,168,126, +134,164, 39, 75, 21,246,192, 76,150, 24,152,101, 59, 6,160, 22,251,164, 23, 22, 86, 34,169, 37, 64, 41, 77,186,215,114,156,150, + 43,139, 43, 97,169, 85,218,101,105,162, 25, 69,219,106, 92, 52,234,159, 51,106,114, 59,213,187, 98, 11,114, 96,186,162,129,133, + 58,105, 47, 71, 91,228,165, 74,112,210, 83,241, 18,146, 11,135,106,214, 98, 78,172, 73,102, 43,177,164, 67,184,105,116,249, 76, +184,164, 4, 42, 59,240, 23,245, 98,155,113,151,208, 49, 37,216,174, 66, 88, 82,250, 45,200,200,202,137, 72, 26,161,196, 82,249, + 44,237,191,114,123, 77,202,228,191, 13, 50,108,176,183, 27, 75,109,213, 41, 83,161, 73, 7, 42, 42, 37,230,219,111,224, 71, 41, + 82,129, 72, 56, 26, 82,178,211, 80,176, 96,117, 33, 87, 27,130, 65, 15,123,139,250, 43, 17,247,133,176, 59,154,251, 35,230,229, + 30, 34,101,181, 84,209,154,121,115, 5,168,137,162, 38,222, 89,169,228,145, 35,177, 23,211, 13, 74, 42,128,222, 98,209, 33, 93, +247, 45,207, 13,114,155,103,122, 54,250,161, 33,214, 94,250,215,234,202,139,111,115, 54,235, 9,117,115, 33, 84, 25,247,117,161, + 36,186, 75,171,142,226, 92, 32,132,169, 8,234, 2,250,244,178,232,151, 46, 85, 85, 97, 46,180,218,152,141, 41,185, 10, 82,146, +133, 56, 87, 49,135, 28, 75,206, 54,128, 82,149,182,149,114,148,252, 73, 40, 42, 25, 63,173,202,173,165,149,245, 27, 59,105, 37, +133,198,106, 75, 46,199, 11,153,201,226, 56,179, 68,204,101, 51,206,133, 4,148,184,138,122, 64,229,229,233,145,221, 56, 61, 81, +185, 75, 51, 27,159, 80,109, 41,125,186,148, 24,239, 53, 37,180,135, 92,106, 52,136,171,113, 78,165, 68,140, 37, 16,223, 89, 4, +156,167,195, 25, 30,171,240,236,165,105,234,169,128, 26,161,150,226,251, 18, 25,116,220,216,131,250,167,125,192, 39,222,113, 12, +241,161, 4,252, 89,144,102,166, 63, 45, 69, 19,211,173,192, 32, 52, 53, 5, 73,183,217, 0,172,167, 96,196,253, 93,251,227, 89, +170,116,137,115, 41,150,180, 88,239, 52,228,155,128,190,219,171,105, 45,132, 20, 84,125,242,101,110, 97,109,192, 60, 15, 6, 4, +169, 41, 7,205,101, 42, 4, 30,100,235, 48, 98,100,183,170,109, 55, 77,129, 26, 53, 90, 77, 38,159, 64,165, 69,109,165, 59, 30, + 52,118, 31, 90,205,199, 80, 1,144, 68, 88,139, 74, 3, 44,182, 0,117, 80,218,100,243, 23, 20, 81,245,170, 20,128,229,191, 57, +231, 18,227,180,170, 21, 94, 83,170,231,105, 13,211, 41, 41,129, 19,194, 45,180, 74, 72,152,162,162,165,171, 24, 90,155, 91,121, + 64, 1, 10,190, 89,208,106, 49,147, 38,123,140,190, 42,215, 59,205, 63, 4, 41, 77, 7,232,116,248, 77, 39,221, 90,229, 3, 45, + 60,220, 25, 11,121, 77,164,169,180,203,154, 2,178,180,171, 50, 56, 55,242,106, 47,163,123,251,137,182,215, 39,127,128, 23, 32, +147,183, 70, 90,252,198, 22,163,102,103,142,115, 15, 52,168, 39, 72, 47, 37, 68,133,131, 88,139,196,145, 68,178, 49, 42, 54, 4, + 38,158,106, 17,126,147, 14,157, 74,146,213, 34,214,106,160, 3,145, 23, 72, 93, 65,214,154,147, 60, 45,214,208,171,150,181,227, + 40,145, 58,176,135, 20, 0, 88, 40, 71,191, 85, 50,133, 16,199, 40,204,233,149,217, 16, 81, 74,106,213,167,196, 41,166, 68, 93, + 61,218,202,202,222,163, 83, 36,180,202,163, 63,224, 83, 73, 82,235, 51,209, 30, 63, 41, 12,169, 45,248,223, 4,213,169, 74, 90, + 53,128,211,101, 42, 82,164, 55,109,135, 89,147, 41, 74,163,196,152,181, 2,229, 14,132,196,169,105,114, 84,194,235, 37, 15,213, +165,203, 74,222,142,144, 8, 75,184,116,146, 25,235,123, 77,126, 53, 26,159, 50,222,163, 82, 34, 87,170,209, 34,199,165,211, 98, +196,145, 42, 52, 27, 97,182,148, 76,169,143,206,119,244, 45, 5, 21,254,145, 74, 46, 58,167, 16,167, 2, 71, 51,139,214,220,104, + 21,172, 65, 37,238, 69,201, 58,119, 82, 55, 23, 34,254, 81,127, 40,177, 82, 54, 23, 48,154,250, 57, 42, 21,105,164,129,171,170, + 20,141, 98, 87, 0,144,254, 73, 38,170, 44,234,129, 19, 88,176,146, 78, 89, 34,103,179,171,162, 77,157, 81,164,143,123,163, 8, + 73,114, 60, 56, 14, 56, 25,153, 92, 82, 27, 64,113,230,129,159,116,212,234,141,165, 30, 35,232,150,149, 34, 26,138, 67, 35,195, +229,195, 64,160,161,215,163,214,229, 61,114,193,118, 3, 18,169,144,234,116,244, 83,105,213, 73,128, 42,170,162,244,180, 53, 84, +173, 73,139, 52,114,195,114, 72, 17,209, 13, 46,130, 91, 66,252, 80,144,164,132,233,150,102,139, 89,170,162, 58, 42, 11,109, 2, +156,194, 86,221, 33,181,251,181, 38, 42,218, 67, 77,174, 97,127,153, 78,214, 92, 14, 2,191, 29,239, 13,182, 62, 55, 80,210, 57, +121,206,113, 74,153, 54,127,189, 8,203, 67,140,225,184,143, 85,220,123,222,211, 87,121,197,162, 59, 80,232,138, 96,225,196, 37, +231, 93,231,158,158,124,173,226,166, 18,183, 1,113, 59,104,206, 7,217,212,166,214, 54, 39,125,193,177,184,189,190,201, 2,219, +129,115,109, 36, 64,115,202, 58,106,133,145,131,199, 51,172,111, 27,220,150, 84, 18, 57, 32,181,236, 38,119,102,187, 2,172,173, +245,138,161,227,115, 42,109, 53,183, 89,113,151,211, 75,165,167, 49, 32,171,220, 30, 90, 20,243,205, 83,164, 33,100, 75, 87,189, +190,190,121, 21, 18,250, 71, 48, 94, 91,105, 75, 43,121, 74,230,229, 45,103, 23,124, 32,112,213,237, 11,217, 74,166,193,241, 37, +103,179,117, 80, 93,247,138,133,163,115, 83, 94, 17,183, 11,108, 46,100,165,216,113, 47, 43, 30,236, 12, 41,116, 27,141,183,211, +202, 18,144,184,181, 22,208, 98,204,139, 46, 18,220,104,135, 30,225, 76, 56, 81,105,212,133, 48, 41,180,229, 70,162,206,126, 38, + 92, 98,148,206, 66,164,193,166,164, 45,105,171,200, 68,140,120,203, 37, 97, 47, 60,174,114,244,144, 80, 29,171, 42,165, 30,155, + 49, 51, 37,181, 81, 79,132, 15,185,196,151,151,234,114, 30, 44,248, 41,113,104, 4,248,238,184,148,190,180,184, 74,188, 52,182, + 16,234,154, 81, 58,124,203,115, 9,169, 39, 2, 57, 12,104,246, 82,172, 26,204,163, 72, 34,253, 44, 52, 92, 91,236,149, 12,133, +109,183, 62,241,103, 9, 69, 81, 77, 83, 52,208,150, 44, 27, 66,145,121, 36, 63,181, 37,206,204,250,129, 61,116,169,212, 89,131, + 43,201,249,104,123, 74,253,155,155,225,236,203,226, 10,102,204,110,202, 63,132, 86,125,198,138,149,127,100,183,134,155, 1,112, +237,173,219,177,225,202, 67, 75,152,211, 60,203, 77, 6,247,167,123,204, 54,107,180, 85,184,167, 33, 62,251,114, 35,170, 69, 54, + 84, 73, 46,115,200, 36,167, 25,234, 60,137, 61, 71,217,242,198,191, 92,191,104, 95, 2, 27, 99,237, 47,225, 82,247,225,235,116, +208,197, 6,191, 47, 55, 54,209,110, 43, 17, 27,149, 84,218, 45,211,165,197,120, 90,215,101, 56,171, 11,149, 13, 70, 66,225,214, + 96,115,165, 21, 26, 85, 74, 92, 66,166,214,227, 79, 55,249, 64,239, 46,206,238, 55, 15,155,187,185,155, 17,187,212, 5, 91, 27, +163,180, 55,157,106,194,190,104,165,101,216,241,171,116, 57, 30, 18,166,211, 37, 16, 5, 70,131, 54, 18,226, 79,167, 74, 70, 81, + 42, 5, 78, 52,132, 18, 28, 26,183,178,186,229,171,129, 84, 73,169,212,119, 35, 85,129, 0,134,181,188,202, 72, 5,128,210,110, +164,121,139, 34,115,126, 99,150,201,150, 78,208,177,215, 21,236,173,125, 91,218,250, 75,126,181,187, 55,113,190,246, 44, 91, 95, +135,148,129,156,147,147,205,212, 31,144,244, 3, 58,243,202,158,132, 96,121,118,234, 51,223,167,152,213, 84,132,144, 83,212,144, +122,231,250, 71, 93,121,229, 7,168,206, 61, 58,103,231,212,233,216,126,242, 48,223,133,202,123,243, 12,118,207,203,183,111, 61, + 32, 14,126, 17,140, 14,161, 90,245,202, 0,199,235, 2,114, 60,191,110,190, 5, 15,139, 57,201, 32,114,253,216,239,161,239,192, +233,108,123, 39,162,135, 78,189, 62,195,246,249,106,136, 10, 78,112, 73, 80, 61,113,230, 62, 64,254,122,234,166, 18, 83,202,122, +103,184,207, 81,130, 49,223,236,215,174, 80, 6, 9,201,199, 47,111, 46,189, 71,203, 89,192, 63, 27, 96, 53, 1,149, 31, 49,140, +143,183,211, 84, 10,122,103,152,159, 49,204,115,211,229,233,253,186, 57,109,140, 0, 0, 42, 35,161, 61,188,137,207,221,161, 86, + 58,145,216,118,198, 58,231, 30, 93,116, 48, 63,158, 1,112, 96,228,246, 63,119,203, 84, 21,220, 28,101, 35,160,235,242,245, 31, +102,138, 90, 22,121, 72,232, 51,231,247,231,247,104,117, 39, 61, 58, 2, 59, 96,249,104,234, 64,191,160,198, 65, 55,247,255, 0, + 60, 14,160, 50, 60,137, 24,206, 58,103,203, 61, 58,234,146,135,124,156,121, 99,160, 31, 51,219,236,252,116, 73,206, 49,128, 51, +231,231,251,123,106,130,209,216,142,152, 32,159, 63,195, 75, 14,184, 84, 94,215, 29, 79,250, 96, 55, 19,215, 9, 7,190, 79,166, +113,212,157, 10,180,231,174, 51,219, 30,163,230, 61,124,245,112, 94, 8, 35, 56,199,150, 58,254, 63, 97,208,174, 36,246, 79, 78, +132,250,231,203,175,160,237,165,148,155, 11,141,240, 1, 23,176,233,128,148,158,253,122,158,192,247,206,126,126, 93,116, 42,219, + 61,126, 33,142,248, 29,128,238, 64,251,180, 98,130, 72,235,144,115,140, 99, 39,215, 61,190, 90, 29,105, 56, 32,252,142,124,190, +223,195, 58, 58,223,238,254, 95, 39, 6,192,106, 72, 24,199,207,169,245, 30, 90,160,176, 6, 79, 92,227,183,145,249,118,249,104, +165,167, 61,148, 78, 62, 93,254,239, 93, 12,179,220, 30,157, 60,198,115,242,249,127,110,150,193,148,246,192, 42, 80,207, 64,115, +230, 7, 95,188,250,119,213, 21, 12,100, 99, 63,179,231,162,150,129,220, 12,103, 57, 35,191,246,104,101, 2, 7, 81,158,249, 35, +174,127,183, 74, 39,124, 40,187,129,129,212, 62, 68,122,250,125,199, 84, 23,140,143, 92,117,213,117, 19,215,184, 4,231,175, 66, + 79,245,106,130,251,142,158, 93,255, 0,118,149, 29,122, 95, 24, 34,198,227,107,126,239,159,158,216, 20,140, 18, 59,227, 75, 95, + 85,250,199, 75, 75, 13,192, 56, 53,129,222,221,113,224, 31, 34, 70,125, 6,170,115,117, 4, 36,146,112,146, 71,252, 62, 67, 84, + 57, 57,156, 74,190, 46,131,167,126,189, 72,198, 14,138, 73, 72, 0,249,103,174,123,247,243,198,181,201, 39,189,191, 44, 27,238, +190, 43,164,129,129,211, 63,236,245,233,243, 58, 32, 97, 35, 36,140, 31, 65,231,246,249,232,100,242,133, 16, 14, 78, 58,158,157, + 7,144, 58, 37, 4, 36, 28,167,155, 7,168,239,223,182,147, 44,119, 29,113,140, 86, 9, 88, 80, 33, 67,148,142,189, 58,147,229, +223,183,125, 16, 27, 14, 36, 37, 73,206, 14, 71,113,233,215, 84,146,114, 59, 96,121,126,113,162,219, 33, 61, 20,122,227,203, 61, +135,228,105, 51,107,111,211, 4, 38,221, 6,253,190,126, 24,172,132,132,167, 25,192, 31, 46,167,238,209,141,168,114,132,252,186, + 31, 95,234, 58, 17, 41, 24, 32,168,146,115,128, 59,159,179,174,138,108, 18,115,203,216, 12,131,215, 0,103,174,144,194, 71,174, + 42,227,160,207, 92,117,206, 62,223, 33,242,209, 40,194,176, 79, 64,124,186,245, 61,190,239,236,213, 16, 1, 81, 29, 64,242,237, +249,245,209, 45,130, 6, 1,237,228,113,147,251, 59,104, 99, 7,241,193, 13,224,100, 14,158,159,183, 68, 33,125,121,112,122,103, + 36,117, 25,207,111,219,170, 8,237,156, 12,250,116,207,217,159, 61,101, 86,165,169,113,222,213,218, 85,175,104,208,234,151, 29, +199, 92,154,205, 58,143, 67,162, 64,145, 83,170,213,103, 62,174, 86,162,193,129, 17,181, 57, 37,226, 79, 92, 12, 36, 30,101, 16, +144, 78,144,150, 68,141, 93,157,130, 34,110, 73, 54, 0, 1,212,158,192, 96, 14,194,219,159, 78,228,237, 97,234, 73,216,119, 56, +239, 95,177,184, 52,198,205,241, 34,250, 82,145, 37,219,203,111,154,116,243, 97, 74,140,138, 52,229,161, 36,121, 36, 56,165, 99, + 62,127,102,186,125, 58,178,168,165,224,240,108,180,227,106, 45,243,168,133, 3,219,224, 41,253, 99,156, 28,124,181,130,123, 43, + 61,153,123,231,176,246, 46,230, 76,226, 66, 69, 19,109, 99,238,172,123,102, 85,189,105, 61, 82,102,161,115, 83, 77, 53, 47, 41, +114,110, 56,241, 22, 91,166,201, 83, 79, 37, 41, 96, 41, 78, 35, 7,156,131,211, 91,183,187, 60, 21, 87,216,164,202,171,216, 55, + 44, 43,172,211, 80,185, 34,157, 13,254, 73,133,108,167,153, 73,110, 58,212,124, 76,167,200,119,206,185,175,140,211,219,115,250, +250,186,121,150,106, 87, 41,102, 86, 4,217, 99, 69, 62, 95,180, 64, 96, 69,237, 98, 6,161,177, 7, 30,160,125, 30, 51, 92,167, + 42,240,231,133, 50, 92,240,205,148,102, 10, 42, 3,172,240, 74,138,188,202,201,222, 50,206,202, 2,106, 70, 70,243, 90,193,183, +223, 26, 33, 89,187, 38, 56,211,173, 73, 82, 68,134, 29,100, 33,180, 43,195,241,146,165,129, 30,115, 42, 79, 82,234, 84, 82, 20, + 61, 53,220,158, 22,104,113,246,115, 98,169, 87, 66,163,180,230,226,223, 48,159,157,245,162,217,109,215,233, 84,130, 15,134,212, + 53,167, 42, 99,197, 78, 84,181,167,226,199, 98, 53, 30, 10,163,245, 54,234,111,196,144,202,209, 82,166, 75, 80,109,137, 72, 83, + 78, 49, 38, 59,153,147, 79,146,210,250,165,126, 35,100, 96,227, 24,215,127,118,138,242,164,110, 62,192,109,157,106,149, 47, 30, +229, 76, 54,197, 89, 17,150, 68,186,101, 86, 23, 51,106, 97,104, 7, 45,130, 23,217, 88,202,117, 28,118, 20, 81, 23,136,105,153, +198,204, 58,139,149,189,143,111, 45,236, 65,254, 3, 29, 5,199,185,104,158, 14, 29,203,164, 80,217,101, 77, 86,170,133, 93,209, +180,199,170, 20, 96, 14,241,187, 6, 37,127, 93,148, 45,136,181,242,106,229,223, 42,176, 31,122, 91,235, 11,114, 43,173, 63, 43, +152,169,199,159,143,135,153, 45,243, 30,101,243,182,162,159,187,215, 88,194,171,109, 42, 52, 22,155,105,229, 73,168, 62, 22,203, +206, 5, 45,198,219, 49,203, 37, 62, 31, 54,124, 70,223, 9,248,135, 92, 47,174,172,242, 97, 74,133, 54,150,235,136, 92,152,237, + 58,252, 89, 13, 45, 92,139, 46, 50,219,136, 74, 20, 9,248, 28, 41, 32,143, 62,190,122,188, 83, 18,164, 54,242,101, 71, 65,114, + 44, 22,132, 53, 40,114,187, 30, 75,239, 23, 82, 65, 72,234,224, 65, 70,125,121,117, 30, 87, 45,172,129,168,158,155,237,126,135, +115,211,189,187,236, 62, 56,127,142,130,130,138,154, 49, 79, 24,120,134,234,170,193,123,180, 96, 91,169, 10, 66, 18, 15,151, 77, +128, 4,226,231, 71,140,106,110,203,144, 95, 44, 50,131, 42, 92,249, 46, 56,161,202,196, 32,136,201,141, 24, 96, 36,190,183,201, +194, 51,149, 21, 28,117,214,187,111,102,251,181, 33,243,106, 81,228, 61, 14, 37, 33, 97,130,251, 50, 21, 30, 63, 51,105,194,152, + 98,106,148, 82, 95, 81,200, 60,195,245,138,142, 20, 14, 19,125,222, 75,250, 78,218,216,238,219,180,169,142, 42,187, 85,231,169, +204, 91,107,109, 14,183, 50,106, 86,182, 24,105,167,112,133,173,168,202, 43, 80,230, 79,199, 45, 56, 33, 67, 58,228,228,187,229, +250,132,217, 47, 75, 67,178, 96, 58,242, 83, 61,164, 56,226,208,226,208,181,175,198,125, 46,167,157, 35,226,117, 68, 43,152, 40, + 32, 32, 40,140,101,246, 58, 73, 18,147,146,135, 76,211,128,242,145,107,170,177,186,198, 9,237,250,205,184,185,216,218,219,233, +112,238, 72, 56,183, 63,169,204,229, 28,252,143,135,165, 49, 82, 40, 35,235,170, 18,203, 36,204,173, 96,202,132, 24, 98, 13,183, +146, 66,118, 56,218,122,181,245, 81,114,145, 37,110, 60,103,198, 97,207,125,165, 84, 31, 79,131, 90,163,190,219, 97, 10,108, 48, + 26, 9,169, 66, 90, 80,227, 47,128, 80,181, 33,204,169, 42, 79, 34,145,144, 27,238, 36,202, 77, 46, 61, 71,146,158, 91, 77, 34, + 80,129, 80,121,196,192,149, 37,107, 67,234,250,134,230,105, 96,211,223,104,169, 92,205,169, 77, 58,128, 83,145,140, 41, 90,141, + 75,174,173, 77,251,204, 9, 44,170,156,220,176,219,244,224,164,200,165, 79,117,183, 20,184,138, 75,160,173,218,100,118, 89, 33, + 75, 40,230, 73, 95, 94, 82, 7, 38,179,218,117,105, 35,154,151, 61,164,211, 34, 50,180, 74,121,186,147,237,205,163, 21, 60,162, + 29,110, 35,204,164, 37,216,238, 48,180,134,146,248, 5,180,189,243,232,211, 62, 92,169,112,162,228, 27,221,109,123,121,123, 16, +109,110,225, 46, 44,215,186, 62,199,161,242,220,190,156, 36,113,114, 47,203,109,107,162,234,192,145,231, 26, 47,177,110,190, 75, + 27, 13, 65,145,137, 24,220,138, 82,100, 86,167, 67, 85, 85, 5,217, 21, 54, 83, 26,153, 91,143, 41, 84,218,173, 77,175, 19,157, + 16,100, 78,167,184,142,105,169, 96,169, 46,243, 41,104,121,178, 22,223, 34,202,155, 23,250,140,137, 20,138,148,138,125, 82, 20, +234,253, 56, 69,122, 35,244,247, 86,135, 43,244,199,152,112, 33,197, 60,228, 96,159,173,226,132, 50, 84,121,113, 53,165,176,135, + 82,167, 71,194, 53,242, 20, 11,121, 84,166, 35,198,155, 38, 4, 37,169, 19, 41,142,209, 42, 19,225,165,233, 62, 34, 25,142,226, + 80, 30,113, 17,157, 66,149,252,196,164, 18,216, 82, 84,115,167, 38,148,205,126,152,227, 49, 97,220, 38,171, 81, 86, 91, 68, 26, +187, 13,248, 14, 69, 97, 62, 35,143,138,156,112, 22,101, 41, 15, 18, 22,226, 10,194,136,230,230,233,134,127, 42, 6, 37,206,199, +117,101, 43,181,186,143,180, 75, 2,110, 73, 96, 5,128,176, 42, 44,157, 77, 28, 1,181, 71, 86,166, 56,195,160,133,227,150, 34, + 10, 48, 60,200,165, 70,147,146,168,163,204, 71, 45, 85,148, 2,193, 25,163,195,167,111,214, 86,203,172,196,137, 45,186,155,174, +161, 10,167, 73,203, 62,227, 94,136,211,232, 33,202,160, 82,127,192,238, 54, 24, 88, 10,120, 37, 1,208,149, 43,151,151,153,182, +170,166, 34,105,117, 25,181, 40,161, 79,194,159, 53, 78,221,148, 2,130,244,202, 62, 11,173,203,168,196,140,210,177,239,188,139, + 79,188, 52,148,143, 25, 25,113,159,210,140,171, 8,167, 26, 85, 94, 65,131, 35,235, 11,102,226,130, 87, 49,132, 48,166, 27,155, + 34,167, 24, 20, 49, 81,133, 37, 81,151, 26,170, 90,112, 31, 21,124,188,252,170, 13,201, 72, 73,201,204,105,149, 74,157, 57,200, +147,110, 38,154,139, 18, 67,205,195,153,115, 70,104, 51, 79,155, 83, 70, 23, 21, 85, 85, 0,161, 70,146,242,249, 2, 78, 76,126, +101,128,219,173,128,148,235, 34, 80,196, 0,231, 83, 92, 1,220, 90,204, 10,145,112, 0,185, 42, 1, 2,236,108, 45, 99,136,197, +109, 57,134, 90,147, 78, 60,243,173,165,136,149, 15, 48,189,215,148, 86,241,202,190, 93, 81,152,134,165,148, 13, 11,202,242, 35, +169,110,248,110,177, 16, 67, 42,158,104,128,170, 20,215, 22,194,141,110,142,176,131, 25,131,225, 54, 11,133, 84,196,180, 99,164, + 18, 82,252, 36, 58, 2, 73, 90,181,243,137,137,169, 94,219, 91, 8,140,165,159, 30,241,143, 84, 66,139,156,202,240, 96,192, 62, + 18,156, 82,206,124, 78, 89,140,129,203,241, 21, 30, 76, 19,163,109,106, 99,148,203,129,215,161, 22,149, 70,170, 36, 45,108,171, + 31,224, 53, 5,243, 58,217,101,215, 79,193, 25, 79,185, 33, 32, 39, 1,165,190, 66, 50,135, 15, 45,187,123,227, 46,167, 87,178, + 45,198, 26,115,194,143, 66,171,214,144, 26, 91,156,200,171, 26,148,118, 84,145, 31,151, 10, 8,167,198, 11, 4, 31,135,197,207, +235, 37, 39, 74,201, 56, 20,179, 48,220, 2,160, 89,137, 27, 48,218,251, 92,218,224, 27,108,182,181,237,189, 90,213,112,199,197, +185, 37, 66, 63, 50, 26, 82,245, 33,186, 21, 2, 41, 29,149,214,224, 41, 89,127, 85, 64, 0,155,129,164,168,195,121,106,210,157, + 49, 16,180, 67,123,221,105, 23,132,151, 98,143, 8,133,181, 9,233, 2,160,114,132,149, 41,152,202, 77, 80, 0,122, 20,224,133, +140, 19,174,145,216, 85, 22,174,139, 58,117, 20,167,255, 0,116, 45,215,218,183, 92,253, 48,116, 59, 66,168, 71,135, 84,162,201, + 91,137, 33, 46,115, 83,165, 76,101, 96,101, 41, 92, 44,103,200,106,117,145,110,169,112,231, 15, 1,196,123,195, 84,153, 12,178, + 20,148, 41, 94, 28, 38,226,200,119,157,100,120, 95,165,138, 1,112,228,146,114,114,161,173,186,219, 8, 70,145, 86,150,137, 9, + 45, 70,158,138, 76, 55,148,216, 65,109, 45,150, 86,152,239,128, 57, 65, 12, 75,229,234,122,225,213,148,244,209,114,119,104,171, + 4,128,125, 92,254, 87,191, 96,110,192,158,223,104, 2,109,189,142,214,189,197,123,226,102,115, 14,101,151,130,175,170,167, 41, +126,116, 54, 59,220, 24,181, 41, 23,243, 93, 94, 65, 97,177,125, 39,160, 56,182, 92, 20, 69, 77,185,225,210,208,218, 12,121,177, +214,245,101,132,175,147, 20,200,207,169, 77, 67, 12,161, 64,187,239, 14, 55, 24, 58, 82,112,164,176,232,229, 32,231, 94, 29, 77, + 69,138,133, 70, 29, 29,163, 30,174,236, 24, 12, 74,171,176,182, 29, 93, 18,157, 80, 46,135, 10, 99,172, 22,209, 86,126, 34, 28, +247, 86, 74,249, 90, 42, 50,212,149, 37,164,133, 61,149, 74, 50, 96,174,108,231,227,148, 73,104, 70, 98, 34, 90,232,251,142, 52, +174, 65, 30, 63, 46, 28,230,126, 90,201,119, 25, 60,138,113, 64,225,189, 82,183,173,152,148,155,102,178,203,203, 68,215,166, 72, +114,183, 95,156,227,173,149, 84,171, 51, 30, 74, 27, 67, 12,173, 36, 52,203, 81,219,102, 60, 68,130,144,203,109,165, 36,133,120, +138,212,193, 31, 77,212,144, 72, 34,198,251, 27,245, 44, 15,154,214, 6,230,224,239,182,149, 3, 21, 18,113, 76, 43, 65, 3, 50, +137,214, 49, 12, 40,135,117,121, 29,209,158, 71,223, 75, 42, 46,136,204,108, 8,145,132, 74,193,144, 72, 75, 74,213, 54, 21, 45, + 76, 91,246,218, 94,139, 17,193, 28, 86, 29, 14, 46,115,208,212,249, 67, 77, 64,167, 72,144, 20,185,149,135,226,180,158,101,145, +202,195, 40, 83,141,144,227,200, 2,245, 21,216, 52, 92,248, 96, 70,161, 83,252,103, 98,197,145, 15,156,115, 78,109, 49, 66,157, +109, 1,110,205,152,167, 16,175,119, 65,203,206,130,172,229, 69, 42, 23, 85,184,213, 38,116,122, 77, 49, 30,243,112, 48,191,122, +156,175, 0,120, 52,218,131,205, 97, 18,106, 83,146,149, 4,194, 76, 0,146, 91, 88,241,164,101, 41,109,188,184, 10,126, 34,216, + 84, 0,137,213,234,155,149, 73,236,160, 76, 76,164,176,212,104,116,198,150,183, 7,131, 18, 42, 93,229,167,198,253, 69, 23,214, + 76,149,151, 57, 71,195,200,157,109, 69, 33, 82,243, 60,133,180,234,176,248,250,244,211,107, 91,226, 72,211,167,112,188,181,209, + 76,160,213,204,197,106, 0, 96, 24,179, 79, 82,204, 72, 51,121,144,128, 10,249, 98,149,218,225, 28,149, 89, 27,152,205, 94,144, +220,249, 80,209, 79,171, 70, 91, 20,181,184,135, 92,141, 50, 72, 14, 84, 76,118, 19, 36, 34,177, 25,151, 21,138,119,187,114, 19, + 21, 68, 12,117,150,149,132,150,213,150, 54, 98,220,136, 16,188,119,163, 67,101, 5,113,196,105, 72,165,185, 82,119,197, 5,126, +248,228,114,219,144,233,141, 70, 67,104,106, 56, 82,124, 82, 79,136,218, 88, 9,105, 88,156,247,222,169, 82,227,191, 45,232,212, +218, 11, 78, 71, 98, 59,143,161,113, 39, 84, 75, 46,153, 13, 76,172, 45,229,243, 37,135, 29,104,251,180, 52,101,110, 6,210,236, +148,169, 74, 12,138,140, 74,153, 50, 51,206, 33,177, 76,164,162, 59, 73,171, 73, 72,104, 78,168,197,125,231,124, 63, 6, 48,109, +102,142,200, 60,234, 28,229, 82, 93, 7,244,104,105, 39, 91,241,105,141, 99, 37,254,169,195, 11, 90,214,220,144, 53, 30,151,233, +216, 2, 62,226,207, 81, 79, 37, 64, 53, 1,150,150,100,144,129,164,144,145, 57, 33,117, 0, 73,102,157,197,144,162,146,201,229, +185, 91, 7,133,199,163,200,101, 79,198,131, 70,106, 76,183, 83, 33, 17, 40,212,166, 60, 24,241,189,234, 27,101,247,106, 85,121, + 13, 51,138, 77, 9,190, 85, 34, 58,146,217, 82,185,213,225,182,227,202,108, 33,244,163, 51, 30,132, 13,122,179, 61, 46,206,167, +178,218,106, 21, 83, 17,198,105,113, 16,255, 0,130,203, 84,152, 48,121,220,112, 58, 60, 70,144,219, 72, 14,202,154,226, 91, 75, +137,117,229,164, 37,133,166, 84,233, 54,205, 18,152, 42, 78, 72, 74,100, 38,109, 70,157, 75,167,176,101,215,110,185, 45,168,183, + 26, 21, 45,132, 58, 22,233, 81, 25, 47, 73, 45, 70,101, 9, 42,121,228, 37, 28,165,217,183, 32,206,171, 85,105,149,250,165, 82, +149, 14, 75, 94, 12,218, 69,174,167, 26, 93, 42,136,182,199, 51,171,157, 33,213,135,234, 53, 63, 17,100,187, 57, 41,104, 33, 40, + 8,142,218, 24, 74,121,221,169, 86, 22, 72,193,212,205, 96,202, 46, 67, 48,184, 22, 31,101,130,133,184, 4, 88, 49, 35, 72,181, +216, 86, 28, 81, 1,116,150, 73, 25,169,242,225,205, 66,229, 73,146,164,163,105,104,209,130,181,131, 0, 76,135, 75, 68,143,118, +149,228,145, 98,129, 95,138, 36,233,202,152,138,141, 93,169,141, 69, 80, 30,227, 5,244, 43,222, 82,165, 36,243, 74,171,176,208, + 41,106,160,226,222, 82, 83, 28,169, 98, 40, 10, 73, 90,220,201, 68, 52,254,150,111, 2,144,225,187,179,158,209,187, 10,132,211, + 79,213,165, 82,118, 15,137, 25, 20,246,210,148, 75, 91,140,190,246,200, 95,117, 36, 32,115, 57, 41, 10,102,175,109,202,146,122, + 41, 18,232,108, 40,225,134,134,166, 17, 71,172, 75,173,183,254, 28,202,224,136, 19,125,223,220,189,237,247, 37, 21,179, 37,214, + 81, 80,121,191, 1, 45, 16,166,130, 31,105, 33,106, 75, 76,149, 56,163,206,177,200,205,113,141,195,133, 51,141, 78, 12,248,147, +225,150,176,148, 59, 23,119,182,166,230,182,237, 57, 15, 97,150,105,151,140, 70, 87, 85,176,107,200, 50, 27,253, 3,177,111, 58, + 93,191, 49,181, 28, 41, 2, 57, 60,193, 74,200,158,100,149,102, 22,210,191, 88,166,198,203,123,107, 2,250, 84, 17,179, 17,170, + 37, 36, 88, 6, 45,176, 1,135, 60,241, 94, 80,210,197, 55, 50, 52,167,146, 27, 38,149,177,141,119,250,189, 44, 46, 13,254,219, + 16,222,117, 4,220,220,223,242, 16, 41, 10, 0,121,103, 35, 29, 63, 35,174,144, 0,146,129,231,232,122,252,251,246,242,213,103, +105,213, 58, 52,201,244, 90,252, 69,192,174,208,170, 53, 26, 21,114, 3,128,135, 96, 86,232,211, 30,166, 85,233,238,115, 96,133, +177, 82,139, 41,165,103,205,147,175, 33, 3, 57, 79,194, 14, 78,124,199,203,236,212,253, 72, 96, 25, 78,160, 70,198,251, 27,216, +220, 31, 76, 83,251,247, 22, 56,241,142, 65,215,160,207, 76,143, 35,229,243,210, 78, 79,144, 72, 39,250,186,145,142,218,250, 74, +136, 25,198,115,208,129,220,124,245,247, 36,146,124,191,217,244,236,126,205,103,127,191, 3, 30, 72,200,230,229,206, 58,121, 15, +199,215,251,117,236, 5, 31,245, 72,242, 7,190, 62,223, 76,233,114,133,144,114,164,245,198, 7, 65,219,215,238,215,190, 92,127, + 56,224,103, 31, 47,191,211, 67,221,233,129,138, 43, 71,124,156, 15,196, 14,221,186,244,208,171, 3, 3,191,166, 64,201,249,119, +249,234,232,212, 41,147, 22,132, 71,105, 74, 46,186,134, 91, 32, 16, 29,125,194, 18,211, 12,249,188,250,213,209, 40, 72, 43, 89, + 56, 72, 39,166,186, 71,195,191,178, 43,142,110, 36, 99,196,171,219, 27, 61, 83,178,237, 25, 97,151, 26,188,247, 98, 90, 54,206, +131, 38, 59,229, 63,225, 52,182,171,241,205, 66,178,148, 52,175, 16,166, 60, 5,115, 36, 97, 43,202,147,157,121,171, 41,169,236, + 37,148, 43, 55, 69,234,199,224,162,228,159,112,198,205, 37, 29, 93,124,188,138, 26, 89, 43, 38, 29, 86, 36,103, 32,122,182,144, +116,143,123, 88,123,241,204, 5,140,156, 36,231, 29,252,135,224,124,251,232,117, 0, 14, 70, 1, 7, 7,183,159,203,207,166,117, +177,124, 80,240,223,126,112,157,189,183,214,195,110,107, 49,211,119,216, 53, 54, 96,207,155, 77, 84,151,104,213,200,115,224,199, +169,209,174, 75,118, 76,184,204,185, 50,223,157, 79,148,219,177,157,113,166,212, 74, 28, 66,144, 20,218,181,174,203,234, 48, 7, +159, 79, 94,255, 0,111, 83,141,108, 83,203, 28,200,146,198,218,163,144, 2, 58,142,190,160,216,223,220, 69,240,155,199, 36, 18, +203, 12,200, 98,158, 22,100,116, 59, 50,178,157, 44,164, 14,132, 16, 65,247,140, 12,160, 58, 18,122, 12,253,253, 63,179, 67,171, +168,200, 61, 58,140,249,227,207,167,231,182,138, 63,173,208, 17,223,167,203, 25,201,252, 53, 69, 64, 1,142,253,115,246, 15, 67, +173,144,108, 65,244,198, 70,227,125,199,254, 48, 26,129,245, 28,189,186,140,125,224,250,245,208,171,192,201, 25, 7,255, 0,104, +122,103, 69,184, 70, 72, 57, 0, 30,195, 29,124,186,126, 31,179, 66, 47, 62,163, 30,158,121,249,116,210,202, 73, 23, 56, 0,108, + 61, 54,192,202,193,193,193, 4,247,206,116, 58,199,159,175, 67,233,162, 87,235,229,140,122, 96,250,252,244, 58,129,201,200,200, +251,113,131,219, 56,209,199,198,216, 54, 6, 88, 0,100, 39,175,203,167,231,251, 52, 43,131, 39, 36, 2, 64,236, 58,254, 63, 61, + 22,231, 76,100,244,201,251, 60,134,132, 80, 30,188,221,127,104,193,245,251, 52,170,155,223,107, 91, 25, 22,223, 2, 44, 12, 18, + 70, 49,219,212,117,237,161, 87,243,234, 15,111, 44, 31, 92,249,249,232,197,140,103,249,222,127,105,251, 6,133,115, 24,236,123, +246,244,239,223,229,165,147, 10,139, 27,123,190,126,126,252, 12,188,246,199, 76,103, 62,152,254,142,154, 13,206,249,201, 78, 51, +156,140,231,211, 31, 46,250, 49,194, 2,122,244,243,207,151, 79, 93, 90,212,167,148,162, 20, 50,159, 34,158,248, 35,184,244,210, +152, 2,247, 55,232, 48, 59,171, 82, 85,220,156,231,177,199, 79,179, 75, 84,137, 89, 82,129, 64,192, 61, 9,238,125,123,157, 45, + 11,159, 92,102,195,211, 7, 1,145,228, 49,230,115,215,175,153,251,245, 85, 41,199, 65,212,158,255, 0,159, 77, 82, 78,114, 7, +145,207, 79, 35,223,203,237, 26, 37, 0,231, 61, 49,231,219,242, 53,130, 1,198,113, 85,164, 37, 39, 24, 29, 70, 51,230,123,121, +232,129,156,245, 31, 8, 29,193,235,233,231,223,190,169,163, 29,176, 58,117, 7, 26,244,121,242, 2, 82, 20, 60,250,224,142,189, +251,246,210, 76, 0,248,223, 3, 5, 39, 29, 51,146, 59,252,240,123,103,174,138, 64,206, 8, 35, 31,183,240,208,109, 54, 70, 78, + 78, 73,235,147,144, 6, 78, 6, 51,215, 70,163, 57,233,142,157,199,203,229,162, 27,218,255, 0,203,124, 17,187,155,224,134,240, +161,156,231,174, 64,235,211, 29, 63,164,104,132,168,143, 60, 14,199, 24,243,245,249,127, 86,168,160, 96,103,207,203,243,246,141, + 16,132,224,228,245, 7,174, 63,160,231,215, 73, 16, 5,253,223, 39, 9, 28, 86, 71,127, 62,223,143,231, 58, 44, 1,220,122, 99, +160,192,252, 52, 58, 82, 7,219,143,207,238,213, 86,242,162, 60,134,112, 57,142, 0,243, 42, 62,128, 12,232,167, 5, 97,182,231, +108,101, 54,149,175, 93,188,238, 42, 37,171,108, 82,103,215,174, 43,142,169, 10,139, 68,162,210,216, 92,170,133, 82,169, 80,121, + 49,225, 64,134,195, 96,151, 31,113,229,164,118,194, 70, 84, 72, 0,157, 78, 55,217,195,236,235,180, 56, 5,219,136,183,189,229, + 6,143,114,241,101,120,210,144,245,197,112,186,195, 83, 99,109,101, 38,115, 41,113, 22, 77,152,167, 82, 66, 42, 9, 66,147,245, +132,212, 0,227,174,130,132,144,210, 64, 58, 65,236, 48,224, 78,145,183,150, 91, 28,115,238,229, 25, 47, 93, 23, 10,101,211,120, +127,163, 84,163,165, 73,163,211, 57, 87, 30,165,184, 46, 48,226, 73, 76,201, 4, 45,184,107, 35, 40,101, 37,105, 33, 78,103, 93, +206,171,207,168, 77,158,242,214,234,165,120,206, 45,240,239, 57, 83,188,203, 36,252, 62,157, 9,239,170, 51,196, 46, 48,105, 37, +147, 42,160,151, 76, 16,146, 37, 96,109,169,129, 27, 92,118, 83,208,119, 32,181,143,145,135,112,125, 25,188, 13,143, 54, 16,113, +223, 19, 82,137, 17,172,244, 16, 72, 60,170,157,125,165,213,191, 93,246, 49,126,194, 16,247,212,254, 92,102,175, 95,155, 82, 46, +162,100,151,208,236,151, 84, 86,135,157, 83,143, 45, 96,146, 94,142,181, 28,149, 31,231, 39, 61,245, 66,141,115,205,137, 57,175, + 1,247, 75, 76, 35,195, 76,148, 41, 72,125, 46, 37, 67,149, 50, 80, 63, 89,178,122,100,246, 29,245,245,218, 59,147,164, 45, 78, + 62,215, 50,202,148,134,101,254,133,244, 62,145,140,180,188,124, 11, 56,232, 71, 67,171, 83,148,233, 49,170, 13,190,247,248, 44, +245,182, 90,104, 56,144,150, 39, 33, 63, 10,154,125, 67,225,241, 20,158,202,245,193,243,213, 56,106, 88,146,193,203,105,235,239, + 59, 19,191,201,199,127,158, 23,202,218,157,233,146, 24,236, 81,136, 80, 46, 1, 43,107,143, 46,174,130,197,183, 3,169,212, 47, +102, 23,138, 45,142,166,222, 16, 42, 27,183,108,211, 81, 10,232,163, 70,247,155,186,155, 13,174, 83, 92,132, 0, 8,170,165,134, +192, 6,115, 39, 5,106, 72,203,136, 86, 73,233,166,207,131,205,208,115,108,174, 89,118,133,206,234,163,216, 59,146,166, 20,169, + 42, 82,136,161, 93, 77,252, 49, 42, 33, 4,225,182,215,204,148,185,216, 20,171, 61,198,186, 27,110,114,132,166, 53, 69,148, 59, + 30, 90, 23, 25,101,236,171,154, 43,201,240,223,133, 36, 17,241, 35,145, 74,229, 39,161,215, 63,238,253,167,145,106,238,109,193, +110,177, 27,154,158,103,166,165, 71,109,208, 75, 65,135,207,188, 66,117,149,227,252,159, 41,228,233,219, 3, 75,181, 66,188,109, + 27,157, 72,221, 61,223,199, 99,123,219,220, 65,219,108, 51,192, 88,210, 85,228, 53,174, 76,116,104, 30,157,201,185,229, 35, 0, + 2, 19,125,224,147, 75, 37,239,101, 33, 13,213, 69,250,103,114, 80, 10,102,173, 46, 58,164,199,113,180,212,163,184,159,141, 18, + 38,180,144, 27,150,219,136,255, 0, 40,194,218,193,244,234, 52, 13, 53,152, 76, 85,228, 75,126, 75,175, 83,218,112,212,170, 11, +111, 28,170,135, 77,132,169, 78,242,115, 15,209,175, 45,242,143,153,236,117,227, 97,231, 85,171,148, 38,109,155,155,154, 91, 20, +248,232,126,139, 84, 87,199, 38, 34, 85,134,223,163, 74, 82,186,185, 28, 40,126,141, 95,205, 7, 30, 67, 69,110,125, 33,219, 19, +109,119, 58,172, 90, 66, 93,116, 66,166,211,214,225, 63,160,250,214, 82, 3,169, 64,233,241,150, 27,112, 39,168, 3,155, 62, 88, + 58,244,144,243,106,233,148, 11,197, 35,128,123,129,109,205,246,238, 6,199,184,235,108, 71, 42,184,155,216,242,188,198,154,162, + 95,237,180,208,232,140, 11, 90, 66,236,136,172,189,245, 3,160,145,212, 16,122,249, 73,227,159, 17,187,137, 50,231,190,101, 63, + 18,112,228,140,252,162,176, 30, 62, 10,228, 73, 82,164, 22, 95, 72, 63, 2, 91, 10, 66, 22,112, 8, 82, 66,185,126, 28, 29, 79, +145, 81, 80,168, 42, 68,213, 63, 12, 37,188, 63, 45,130,209,128,132,156,150, 26, 75,203, 73, 74,254, 39, 10,138, 92, 67,124,164, +229, 42, 25, 25,186,221,245, 35, 87,185, 43, 18,155, 90,227, 77,126,164,251,143, 7,129,118, 51,188,178, 11,120,144,148,242,135, + 91,232, 71, 50, 10, 92, 36, 36, 39,211, 88,139,213,131, 77,117,196,212, 27, 16,219, 83,220,225,196,169, 47,211,101,161, 71,194, + 11, 92,133, 4,174, 9, 66,203,105,113,183,145,240,248,193,124,202,108,130, 38, 34, 59,179, 29,137,125,253,230,246, 63,127,165, +250, 13,186, 11,218,248,225,108,186, 60,159, 36,202,104, 33, 80,239, 79, 18, 6,232, 36, 44,108,206, 88,216,171,134,102, 58,137, +189,193,232,183,182, 51,138,107,197,167, 35,145, 32,194, 75,137, 45,162,170,204,129, 26, 59,172, 0, 57, 16,250, 88, 42, 67,173, +168, 44,132, 33, 97,105, 81, 89,194,193,192, 15, 21,183, 34, 93,189, 17,133,173,196,213, 88,150,133,188,239, 51, 44,199,149, 29, + 45,142, 86,210, 82,135, 2, 38, 68,112,144,144,148,168, 41, 39, 32,133, 0, 2, 89,200, 80,154,117,109,186,212,100,199,139, 80, +101, 13, 33,216, 78,199,114, 51,238, 37, 74, 91, 78,189, 27,148,178,231, 80,164,172,130, 9, 41,201,238, 14,179,250, 11, 83,227, +182,194,154,145, 2,161, 25,212,187, 44,196, 66,213, 18,124,111, 5,107,100,166, 20,148,169,198,211, 12,115,175,153, 42, 74, 80, + 70, 78, 78, 51,166,186,192,172,178, 6,109,136,220,117,189,189,227,117,177, 30,160, 27,119,233,139, 14,158,162, 39,142, 0,101, + 66, 93,128, 10,247, 70,216,130,108,214,176, 96,108, 65,243, 95,175,187, 27, 7,111,210, 27,168,182,211,116,199,151, 78, 75,232, +110, 83,209,169,177, 26,125, 10,125, 72, 91,143,187, 34, 34,142, 34,172, 0,129,128,132, 45, 73, 72, 9, 43, 56, 80,206,163,202, +184,216,125,223, 26,158,154,225, 56, 80,114,142,180, 69,150,162,178,150,227, 46, 61, 62,106,200, 76,129,146, 74, 91,146, 28, 87, + 54, 67,121, 73,211, 37, 69,159, 9, 83, 19, 42,175, 34,171, 13,106, 74,227,154,156, 84,200, 79,185,120,108,229,135, 25,169, 81, +213,250, 96,176,134,208,128, 65, 64,248,130,145,141, 58,116, 74,219,236,148,159,175, 97, 86, 33,180,182, 20, 87, 17,108,199,169, +180,216, 91,106, 47, 79,130,128, 61,245,230,208,113,204,207, 34,215,156,148,247,212, 94,170, 25,163,109,148, 76,140, 5,245, 41, +218,254,142, 8,213,107,116, 44, 47, 97,229, 55,198,205, 75, 85, 29, 71,255, 0, 73, 68, 85, 96,178,164,159,111, 98,202,179, 71, +229, 98, 69,134,130,202, 77,238, 0, 83, 96,239, 82,107, 84,106,164,152,205,214, 16,245, 17, 75,247,101, 22, 43, 1,232, 83,105, +203,136,165, 50,229, 98, 34,151,202, 17,226, 61,202,145,202,178, 48,162,146,142,250,216,251,105,128,186, 36,170,100,211, 22, 67, + 77,176,209,122, 60,214,153,145, 30,167, 10, 65,240,214,164,164,158, 79, 13, 73, 45,115, 37,224,181, 33,120, 81,230, 79, 42,131, + 59, 69, 16,106,201,139, 50, 64,129, 87,142,243,161,150,146, 80,211,168, 90, 71,134,148, 54,236, 25, 3,150, 43,129, 5,101,229, + 41, 92,199,162, 51,130,112,245,208,236,136, 14, 52, 88,165, 63, 50,139, 34, 51,197,246, 98, 51,239, 14, 83,216, 91,139,113,121, + 76, 73,110,172, 58,223, 48, 72, 13,160,134,135,112,144, 6,154,194, 70, 23,117,229,143,129,216,236, 71, 80, 47, 96,118,184, 4, +222,231,114, 6, 41,222, 44,205,105, 4, 73, 28,205, 45, 7, 45,193,177,250,212,141,149,187, 31, 44,137,107,144,124,172,109,102, +184,117, 1,243, 59, 82,158,154, 90, 88,167,200,142,181,210,164,169,181, 70, 81, 89,144,237, 61,164, 97, 8,142, 95, 89, 89,114, +156,227,128, 6,143, 58,148,202,185,146,172,161, 73, 41, 58,230,163,187, 82,190,163,190,164, 15,240, 15,170, 97, 12,245, 79, 47, +184,169, 46, 41,174,193, 14,169,111,140,231,161, 40,198,122,227, 89, 5, 18, 3,176,154,143, 6,166,202, 9, 1, 73,143, 61,174, +116,199,117, 99, 11,126, 47,134, 18, 84,193,229, 10, 37, 10, 37,180,225, 64, 40, 28, 13,100,168,166,120,245,217, 15,133,120,168, +146,220, 87,219, 46, 28,171, 6, 52,112,158,128,225, 60,175, 70, 87,197,205,140, 40, 16,112, 64,214, 42,193, 90,101, 10,126,211, +169,184,233,123, 31,188,110, 72,220, 3,125,207, 67,138, 55, 49,206,155,219,234, 42,132,129,216,197, 32, 46, 15,145,195, 50, 2, +235,191, 86, 80, 85,250, 18, 70,227, 86,166, 57,149,157,109,178,148,183,224, 71, 1,183, 35,200,142,217, 40, 25, 72,109,212,201, + 82,185, 20,122,144,165,158,100,158,128,171, 25,198, 50,253,209, 40,136, 75,137, 56, 90, 16,244,102,139,216, 60,229, 92,174, 20, +160, 14,224, 59,241,225, 62,105,200,244,214, 51,107,195,108,165,151, 16,146, 22, 20,133, 20, 2, 74, 64,121, 60,138, 65, 87, 76, + 96,117,207,114, 8,243, 3, 79, 5, 53,182,146, 64, 57,193,111,145, 35,178, 84, 80,226, 28,232,165,126,162,177,219, 31,234, 19, +220,105,223, 44,132,121, 88,223, 77,198,253,250,119, 62,253,247,252,113, 75,113, 30,119, 60,175, 32, 4,249,186,239,191, 91,252, + 54,176,222,214,184,191,174, 50, 89, 20,195, 81,143, 72,144,180,173, 79,134, 84,226,176, 3,206, 10,131, 10, 49,156,120,149, 12, +182, 3, 33,100, 31, 37,188, 73,238, 14,172, 46, 81, 36,215,106, 78,136, 82, 13, 46,159, 29,244,173,218,140, 98, 3,147, 86,130, +148, 42,159, 79,101,212,148,184, 90, 82, 9,117,242, 64, 39,157,182, 86, 64, 39, 89,163,142, 4,210, 26,113,106,112, 18,169,104, +109, 13,148, 32,151, 20,219, 9, 95, 85,156,163, 43, 88, 5, 64, 16, 3,157, 50, 73,215,199, 43, 45, 65, 83,113, 91, 14,161,136, +145, 25, 84,196,198, 1,231, 22, 91, 74, 20,150,219,107, 33, 42,116,156, 18,165, 16, 57, 84, 58,142,131, 82, 86,141,140,129, 80, + 14, 99, 42, 29,250, 93,128, 39, 98, 55,238, 64,233, 99,214,219, 98,176,130,186,186, 61, 66,153, 3,200, 12,138,151, 0,172,107, +174,228,216,130, 24,139,170,168, 32,128, 73,218,246, 35, 9,159, 71,167,209,161,120, 20,248,236,194,134,100,203, 91,178, 29, 95, +186,251,203,202, 90, 28,149, 81,118, 76,215,143,188, 39,196, 74,202,151, 33, 97, 35,155,151,196, 40, 72,195, 37, 84,174, 73,169, + 84,154,106,129, 77, 18,105, 49, 10,229, 68,157, 80,241,218,102,167, 32,224, 55, 84, 90, 25,111,222,102,198, 15, 5,251,154, 64, +109, 11,229, 46,180,231, 39, 33, 15,133, 74, 59,117,246,189,234,168,242, 95,136,212,199, 36,199,182,218,105,167,105,241,249, 74, +146,211,181,151, 92, 73, 53, 87, 2,149,206,150, 9, 76, 54,221, 64, 80,109,197, 32, 43, 88,189, 94,149, 6, 43,205,191, 86,230, +247,217,135,221,162,211,216,142,170,140,185,124,205,173, 45, 70,131, 10, 58,124,106,140,226, 75,124,160, 0,202, 50, 8, 82, 18, + 57,198,220, 72,224,134,210, 45,176,191, 96,122, 95,208, 6,189,206,219,216, 29,247,196,207, 33,174,134,153,155,219, 85,171,171, +156, 48,220,187, 89,207, 83, 96, 67, 75, 32, 91,221,193, 17, 45,216,175, 48, 50,178,224, 84, 74, 44,154,236,184,109, 72,113,234, +237,116,165,197,177, 54, 82,143,185,194,138,164,184,249, 16,105,241,143, 44,103,208,121, 50,164,146,226,240,182,220,119, 4,235, + 37,164, 65,153, 92, 80,137,106, 70,139, 82,125,151,164,197,155, 93,168,123,196,123, 46,150,251, 8,240,252, 17,238, 40, 42,185, +170,222, 34,155, 80,141, 16,150, 88,230, 75,114,101, 51,130,141,103,113,118,222, 84,228,199,126,232, 95,240,106,136, 16,215,189, +218, 86,235,201, 53,185, 52,220,146, 81,114, 92,236, 97, 49, 90,112,128, 36,194,166, 1,146,181, 52,236,199,138, 84, 53,147, 85, +149, 73,182, 92,129, 6,223,109, 81,169,207,198,147, 79,163, 83, 41,232, 5, 82, 81, 29,145,152,108,180,165, 54, 91,134,211,156, +200,113,210, 18,218, 3,193,103,153, 99, 39,101,145,165, 85,144, 39, 49,211,208,128,187,218,251,146, 58, 53,134,171, 94,215, 4, + 88,173,147,175,226,120,170,103,246,122, 6, 21,149, 44, 27, 66,168,189, 44, 37, 67, 23, 6, 68, 33, 36, 54, 58,210, 58,127,236, +202,171,173,165,149, 12,145, 11, 77, 10,223,167, 90, 47,203,153, 93,154, 39,203,117,178,229, 86,225,153, 22, 43, 10, 90,217, 97, +108,173,148, 73,109,194,197, 34,138,149,128, 98,176,158, 86, 18,160,180, 32,169,197, 18,171,243, 12, 71,188, 39, 42,174,205, 61, + 18, 45, 72,169, 45, 52,144,181, 82, 30,158,238, 86,184,179,219,134,160,218,163, 82,146,160,225,109, 14, 58,219,178, 20, 76,135, +249, 18, 91,109, 56,227,176, 25,153, 75,137, 81,185,166,184,212, 78, 68,193,165, 81, 33, 56, 20,195, 85, 39, 10, 11, 82,165, 48, +193, 47, 87,234,137,240,209,202,128,158, 72,168, 70, 91, 66, 74,214,240,187,209,162, 25,147, 29,241, 80,243, 20, 40, 45,185, 21, +234,107,146, 57,170,243,146,235,172,178,227, 19,125,225,132, 36,196, 91,197, 42, 68,112,151, 28, 82, 94, 80,113,210, 62, 13, 58, +210,106, 66,183, 75, 35, 17,168,117, 97,109,198,228, 16,111,212,237,190,224, 90,197,113, 23,172,103,117,158,190, 74,182,147, 48, + 80, 99,105, 64,211, 10, 1,101,209, 78,168, 99, 38,107,105,141, 52, 17, 20, 68,221,110,162, 55, 14,212, 81, 18,171, 73, 69, 54, +151, 80,170,193,183,229,135,231, 85, 42,149, 41, 47, 79,143, 80,247, 20, 52,203, 16, 98,229,240,126,168,115,170, 31,125, 39,149, +208,202, 26, 10, 40,231,230,113,232, 15, 68,139, 87,166, 53, 26, 60,198, 94,122, 51, 68, 71,148,250,148, 25,103, 63,162, 83,229, + 41, 41, 99, 37, 69, 44,160, 37, 60,201,103,152,129,206, 20, 27,135, 43, 8,141, 22,153, 2,220,110, 28,171,174,170,134, 89,142, +153,169, 66, 35,209, 88,108,174, 57,126, 80,125, 99,220, 96,135, 91,113, 92,141,161, 33,199, 27, 75,101, 92,216, 34,241, 2, 53, + 62,152,134,101, 34,161, 49,233,206,169,137,117, 56,178,156, 90,231, 45,245,190, 29,112,130,215,199,159, 17, 9,113, 10, 64, 72, +240,130, 80, 82, 83,212, 76,105, 31,217,222, 25, 64,230,104, 8,110,162,224, 1,102,223, 85,193, 99,246,172,183, 96, 73,103, 47, +101, 81, 84,230, 84,205, 52, 18,164,134, 72,163,156,202, 35,140,221,164,118, 98, 85,165,150,214,109, 39, 74,162, 72,246, 71,229, + 5, 65, 26,139,159,203,207,219, 83,176,204,240,223,237, 79,227, 35,111, 41,204, 69,139, 67,175,238, 80,222, 59, 98, 36, 38,195, +113,161,208,183,162,149, 7,112,132, 52,182,144, 3,101,170,213,102,182,215, 40,232,148,176,158,221,135, 48, 73, 36,100, 96, 99, +184, 61,250,246,212,159, 62,150, 45,137, 6,222,246,135,108,254,224, 66, 67,137,123,117, 56, 94,183,220,168,135, 22,209, 74,230, + 88, 87,181,215, 66,109,109,161,180, 2,209, 52,250,172, 0,176,165, 45, 68,165, 61, 64, 1, 34, 48, 64,228, 21, 18, 15,251, 56, +236,115,211, 86, 37, 3,171, 82, 68, 23,236, 70, 90, 53,182,195, 76,108,209,131,111, 66, 22,227,189,136,190,247,199, 60,230, 49, +152,171,170, 80,253,162,193,143,184,200,162, 66, 62,237, 86,255, 0, 76,120, 41,206, 48,160,113,145,142,217,207,150, 15,125,123, + 0,227,148, 14, 92,116, 63,209,247,244,215,220, 39, 25, 35,191, 83,230, 71,159,125, 87,109,178,242,146,134, 70, 92, 87, 96,172, + 36, 4,128, 84,165, 45, 71,162, 80, 0, 36,146,112, 0,201,233,173,195,210,228,218,223,187, 26, 93,174,118,199,134, 90,117,213, + 33,166,208,167, 28, 90,185, 80,132, 2,165, 40,158,192, 1,174,165,240, 33,236,163,226, 11,141,133,195,187,161,181, 31,108, 54, + 57,185,170,102,161,188,215,148, 9, 46,210, 42,138,140,234, 81, 54,157,182,214,243, 78, 53, 39,113, 42,232,234,133, 62,203,140, + 81,226,186,164,251,205, 65, 68, 45,141,111,127,178,155,217, 11, 7,117,232,244, 30, 38,184,174,161,203,107,103,231,248, 21,109, +173,218, 73,190,241, 78,168,239, 51, 13,168,169,155,182,242,228, 90, 36, 81,246,136,186,131,238,144,210, 90,151,113,134,203,171, + 91, 20,149, 36,203,150,181, 2, 36, 72,241, 41,180,202,125, 62, 5, 42,149, 74,131, 14,149, 68,162, 82,162, 70,166,209,168,180, +168,109, 37,152, 52,202, 93, 50, 19, 72, 98,155, 79, 98, 58, 66, 90, 97,150,208,219,105, 24, 66, 83,166, 25,243, 9, 42, 36, 48, +211, 63, 42, 59,216,200, 44, 75, 90,215, 17,131,112, 7, 91,187, 2, 54,178,171, 92,178, 89,124, 43,192, 18,102, 49, 69,153,103, + 74,240,208,200, 3, 69, 2,157, 18, 76,166,196, 60,141,179, 69, 19, 15,178, 22,210, 56, 58,131, 70,186, 89,244,203,132,143,102, + 23, 8,220, 37,199,165,207,176,182,222, 37,237,184,240,218, 71,188,239, 38,234, 68,167,221, 55,203,178, 8, 5,199,104, 48,157, +143,245,101,141, 16,184, 57,155,143, 75,138,210,217, 36,230, 83,228,243,158,151, 69,160,187, 49,126, 36,133, 58,235,129, 35, 46, + 60, 86,226,143, 94,131,153, 68,246, 24, 3,200,118,213,202,135, 74,248, 27, 28,132,168,164, 41, 71, 3, 60,167,178,137,239,204, +123, 15, 64, 52,232,211,232,248, 74, 64, 64, 35, 29, 71,146, 73,235,146,113,212, 96,254,205,107, 90, 40, 75,114,198,159, 86, 38, +236,109,251, 76, 73, 38,219,253,162,109,208, 91, 22,226, 81, 83,208,192,148,180,116,233, 71, 78,189, 18, 53, 84, 94,219,144,182, +187, 30,236,110,205,212,155,226, 36,191, 73,131,133,184, 14,237,254,198,241,107, 70,166, 37,170,205, 10,172,246,199,238, 12,230, + 90, 72, 51,232,213, 6,101, 92, 59,127, 50,122,210, 50,227,241,167, 51, 87,134,218,213,158, 86,166, 6,193, 0, 1,168,116,169, + 41, 33, 39,204,245,237,215, 39,203,251,117,250, 82,251,111,182,226,159,122,123, 47,248,158, 68,212,183,205,103,209,237,109,192, +166, 56,164,149,248, 53, 59, 98,234,166, 45,165,183,223,145, 74, 98,100,132,103,253, 85,145,219, 95,154,217, 61, 0, 4, 2, 74, +134, 8, 61, 7, 49,198, 52,227,147, 73,255, 0,165, 66, 15,216,112,195,220, 36, 0,159,222,225,201,223,169,197, 33,199,180,137, + 77,196, 45, 34, 0, 5,116, 17, 74, 69,250,190,167,136,155,109, 98,194, 32,222,246, 36,247,192,206,116, 56, 35,174, 1,207,238, +253,186, 25, 65, 61,243,212,246,243, 7, 26, 53,192, 0,199, 55, 83,220,158,189,254, 95,142,132, 88, 87, 83,128, 65,237,142,152, +192,193, 56,199,174,159,241, 15,192, 46, 18, 50, 66,124,241,246,227,185,249,232, 98, 58,147,216,252,251, 39,236, 30, 90, 53,207, + 47,191, 65, 58, 65,207,175,110,189,250, 16, 14, 52,178,244, 30,252, 20,218,254,159,207,182, 5,112,227, 39,190, 51,142,131, 31, +120,199, 78,154, 17, 68,242,243, 31,159, 40,251,126,126,154, 37, 72, 61,249,137,198,122,121,118,238,122,245,213, 5,161, 68,100, + 16,191, 34,124,135,231,247,232,227,183,207,254, 48,111,134, 5, 42, 36, 16, 71,124,114,231,182, 61,126,122, 29, 68,103, 25,234, + 1,232, 6, 0,235,229,162, 84,147,145,215,246,116, 0,106,130,240, 62,121,237,229,142,217,251,124,180,162,141,133,183, 31, 63, + 61,177,144, 1, 62,151,192,138, 73, 25,229, 57,201, 57,255, 0,103,240,208,221,251,232,197, 2, 50, 70, 0,235,156, 30,227, 61, + 50, 61,116, 50,192, 29,129,245, 39,203,236,252,116,170,117,249,219, 10, 40, 4,116,183,200,197,185,230,249,199, 41, 42,198, 70, + 82, 58,103, 25,238, 71,150,116, 51,141,184, 1,235,202, 2,112,144, 0, 36,143,159,167,158,174, 42, 0, 30,132,158,249,207,174, +132,121,178,164,158, 85,169, 7, 39, 24,254,119,219,234, 51,165,176,110,158,235,226,222, 82,148,255, 0,148, 36,147,212, 99,211, +208,244,239,165,175, 69,181,182, 0, 82,148,225, 61, 73,192,233,242,239,165,161, 99,233,140,227,210, 7, 92,249, 15,233,252,157, + 20,130, 49,129,223,185,251,245, 65, 32,224, 12,117,234, 63, 19,255, 0, 13, 86, 64,238,124,199, 76,122,104, 96, 96,148,167, 3, +175, 66,127, 28,126,227,253, 90,168,210, 0,200, 56, 61,207, 79,158, 58,231,243,223, 84,210, 73,233,142,131,166,126,239,219,162, + 91, 73, 57,233,223,215,207,166,147,112, 55, 61,255, 0,241,129,143, 96,121,224,159,199,161,251,180, 91, 63, 23,113,203,215, 25, +238,123, 13, 83,109, 35,160,235,215,175,223,141, 18,148,131,208,116,233,158,223,102,147,193, 77,141,238,118,193, 72, 79,216,122, +118,249,250,227,203,207, 85,146, 1, 56, 61, 61, 49,251, 7,109, 14,216,230,198,125, 50,122, 99, 68,160, 2, 64,198,125, 63,225, +164, 90,192,144, 62,122, 97, 28, 86, 29, 14, 58,140,121,159, 62,158,186,218,174, 11,120,121,159,197, 23, 18,123, 87,179,145,130, +147, 79,185,110, 40,206,220,178, 66, 73, 76, 27, 74,150,164,207,184,229,172,143,213, 6,158,202,219, 7,253,105, 35, 90,172, 1, +206,113,144, 59,143,159,245,234, 71,254,193,173,178, 98,146,141,245,226, 34,165, 22, 63,188, 82,169,144,118,234,211,150,250, 66, +158, 98, 93, 83, 19,235,142, 70,200,253, 26,253,223,221, 91, 42, 24, 61,198,152, 56,151, 50, 57, 86, 77, 91, 84,173,166, 80,186, + 80,142,161,155,107,143,122,130, 91,254,220, 76, 56, 7,134, 79, 24,113,142, 65,195,218, 75, 67, 95, 58,243,173,255, 0, 2, 48, +101,152, 92,116,213, 26, 20, 7,179, 48,196,149,103,214, 45,203,102,139, 77,179,109,136,172, 83,237,139, 54,149, 2,215,182,224, + 65, 9,106, 37, 62,145, 72,142,136, 76,165, 49,147,211, 5, 45,100,145,212,231, 39, 86,118,235, 42,143,200,227, 47, 37,210,234, + 18, 24, 83,124,167, 5,120, 37, 7, 39,169, 39, 31,142,154, 22,235,241,228,173,213, 7, 98,188,149,229,164,178,233,228, 89, 82, +186, 30,101,122, 21,107, 39,167, 33,181,182,204, 85, 70,113,109, 7, 2,195,161,204,169,167, 50, 20, 18,130, 15,196, 61, 53,201, + 85,114,187,206,236,205,119,148,147,111,221,239,252,122, 91,240,246,231,132, 50, 26, 12,191, 43,166,165,142, 30, 84, 80,168, 93, + 32, 13, 58, 85, 84,105,177,176, 1,109,176, 91, 3,211, 99,135,136,196,145, 38, 52,105,210, 76,121, 79,186, 10, 76,117,169, 45, +200, 65, 31,170,160, 65,233,140,104,132,199, 66,144,161, 62, 50,221,107,148,150,150,164,248,168,109, 67, 33, 74, 86, 6, 71,200, +131,160, 41,209,224, 56, 99,202,116, 72, 15, 50,217, 66,222,125, 75, 64,192, 24, 0,163,205, 35,215,229,172,162, 35,108, 56,218, +125,222,104, 97,121,193, 42, 81,113, 50, 18,162, 73, 1,181,118, 3, 58, 69,199,148,148, 66,227,107,244,216,237,190,219,127, 28, + 18,170, 83, 9, 43,230,178, 30,161, 74, 4,185, 54, 11,164,181,128, 27, 95, 77,200, 59,139, 97, 81,169,202,247,134,228, 67, 90, + 39, 71, 36, 55, 34, 19,199, 15, 6,193, 24, 91, 89,234,160, 7,109, 86,220,221,191, 69, 90, 85,181,115, 68, 96, 46, 68, 6,140, + 7,138,147,149,150, 82,160,166,208,188,140,168, 39, 39, 25,242,233,167, 58,137, 71,166,201,142,194,201,142,212,216,196, 6,229, + 50,121, 11,153, 61, 65, 3,161,199,207, 78,207,240,125,201,244,162,195,141,165,106, 65, 67,236,188,216,248, 92, 90, 48, 74, 84, + 7, 98, 83,144,126,221,106,152,228,100,145, 44, 64,101, 22,223,184,183, 79,141,173,235, 98,111,138,187,136,120,137, 99,171,130, +101, 58, 30, 38,100,109, 86, 82,202,195, 78,228, 88, 56, 32,141,236,172, 58, 16,109,124, 91,182, 90,193,101,183,152, 82, 35,165, + 30,248,200,113, 65, 41, 9, 79,140, 82, 57,198, 49,211,152,245,251, 78,155,223,104, 77, 33,251, 91,135,122,140,200,202, 44, 42, + 69,199, 77,109, 75, 9, 39,197,247,120, 85, 7, 27,105,208, 6, 86,128,176,147,145,219,151, 56, 58,220,141,174,167, 53, 29,232, +216, 70, 58, 14,152,232,133,143,214, 72, 31,205, 26, 97,253,170,148,143, 23,133, 86,229, 70, 46,101,187,202, 15, 56,105, 57, 89, + 75,148,154,162, 84, 79, 78,191,171,143, 92,159, 93, 75, 50, 90,104,205, 42,203,166,242, 70,111,241,189,135,243,239,235,142,124, +204,184,154,105,248,255, 0, 33,161,119,211, 75, 85, 83, 4,100,118,176,147, 86,254,237,133,254, 24,136, 5, 65,227, 38, 82,145, +202,226, 39, 41,110,184,151,185,156,241, 27, 46, 17,149,180,210, 23,200,250, 75,169,109, 32, 45, 42, 64,235,207,202,174,244,225, + 84,213, 6, 69, 67,223,225,189, 84,158,167,131,113,207,129, 29,150,216,138, 80,148,182,153,212,240,151, 19, 0,248,133,126,240, +180,243,120,152, 79,110,128, 7, 61,166, 95, 74, 93, 83,147, 93,247,105, 92,175, 73,101,190, 69, 71,105, 74,202,153, 10,108,130, +212,142,100,163, 40, 88,230, 36,130,160, 83,202, 52, 77, 26, 68,232,229, 30, 27, 79,123,184, 37, 79,205,166,196,101, 85,116,182, + 73, 71, 35,108, 72, 90, 68,166,220, 46, 4, 56,180, 23, 84,209, 5, 97, 7, 3,149,225,214,234,123,129,216,253,221,239,113,176, + 23, 3,174,219, 95,167,161,116,245, 3,200,177,221,159,162,132,176, 97,182,229, 73, 27,128, 53, 11,223,179, 1,176, 39, 14, 61, +179,110, 49, 87, 92,138,164, 73,146,233,178,165,150, 16,227, 84, 69, 42, 50, 94,109, 10, 71, 71, 96,168, 22, 37,159,133,105, 75, +193, 9, 83,132,168, 41, 95, 14,158, 74, 45, 26,235,147, 34, 76,184,244,134,171, 40,104,204, 83,146, 41,175, 68,162, 76,140, 26, +117, 76,161, 51,233,207, 31, 0,115,161,149,165, 62, 10,135, 57, 87,234, 12,157, 54,148,138,123, 5, 81,133,159, 38,108, 39, 22, +195,242,231, 68, 66,152,157, 2, 68,128,208, 83,174, 57, 5,247, 3,144, 18,140,142,105, 41, 91,107, 89, 89, 79,134, 84,158,109, +108,157,156,170,253, 2, 24,110, 77, 1, 74, 65,106, 28,151,106, 52, 57, 77,206,132,236,118,255, 0, 72,150,159,167,169, 41,148, +219,202,116, 37,124,170,241, 18,165, 16, 50, 10,136,212,110,190, 89, 0,102, 91, 57, 54, 10,173, 96,125, 45,246,150,247,176,217, + 88,139,245,185,184,195,137,205,164,100, 34,153, 99,169,146, 43, 14, 92,202, 82, 66,118,230,106, 62, 73, 25, 71, 75,134,111, 41, + 23, 70, 4, 1,238,148,138, 91, 79,179, 2,163, 42,161,107, 43,221,217,145, 13, 23, 52, 5,211, 28, 76,196,148,190, 35,243,188, +223,129, 37,188,163,195,105,198, 94, 1,193,212, 37, 68,105,199,141,108,212,103, 60,153,146,233, 80,100,164, 73,113, 42,158,134, +163,128, 66,210,128,223, 59,193,178, 90, 87, 40, 29, 82, 74,185, 79, 84,231,174,179,235, 33,170, 93, 82, 77, 65,154,147, 17, 46, + 76,178,176, 41, 85, 40,140, 45,104,144,248, 64, 74, 13, 62,115,105,115, 41,101, 46,164,185,225,171,144, 31,132,142,153,120,104, +155, 91,103, 58,196,127,118,165, 59,108,201,150,211, 50,140,139, 86,167, 83,165,188,209, 10, 66, 17, 17,112, 22,243,140, 60, 16, + 72, 81,231, 97,105,115,147,153, 93,245, 22,146,172,134,180,138,209, 72, 58,244, 55,189,174, 71,217, 35,212,143, 54,251,139, 30, +173,181,252,117, 14, 86,239, 28,240, 77, 72,225, 81,117, 42, 44,182, 50, 45,220,171, 22,130, 84,251, 42, 72, 28,237, 90, 65, 85, + 58, 66,227, 1,178,236,216, 17,129,148,194,170,116,121,146, 79,188, 38, 93, 38, 95,133, 10, 82,217, 78, 91, 18, 24,229,114, 60, +196,167,194, 87,134, 28,105, 10,115,149, 65, 71, 7, 26,218,107,126,109, 90, 10,162,154,132,152, 21, 33, 32, 55,133, 48,201,165, +212, 26, 80, 33, 63, 20,102,159,113,167,222, 82, 65, 82,130, 11,105, 73, 39,225,199, 46,172,180, 45,177,175,198,113,230,233,151, +117, 62,124, 98,178,148,183, 92,183,144,196,137, 9, 81,248,202,103, 82, 28, 65,109, 73,194,146, 20, 24,229, 74,149,158, 83,170, +151,157, 90, 22,218, 91,117,139,187,113, 17, 73,181,172,155, 85,134,101,215,110,181,213, 99,253, 77, 72, 98, 68,134,161, 70, 15, +171,149, 18, 12,199,165, 63, 30, 59, 44, 48,211,146,228, 58,240, 75, 8,112,149, 16,164, 80,243, 60,247, 50, 62,199,125,199,193, + 73, 23,219, 99,125,143, 82, 0,239, 80,241, 39, 21, 71,196,149,209, 83, 82,212,174,107, 81, 80,226, 56,226, 80,230,162, 70,147, +234,226,138, 33, 50, 71, 80,238,238, 21, 99,138, 13,122,152,170,128,194,195, 15, 28,122,147,162, 40,105,244, 58,132, 37,223, 18, + 3,231,194,234,242, 86, 28,114, 59,165, 43, 30, 26,249,214,164,228,128,219,188,202,202,185,192,213,242, 37, 81,151, 30,143, 37, +197, 57,226, 48, 3, 43, 43, 9, 11, 44,184,174,102,157, 83, 95,206, 90, 22, 66, 70, 64,200, 86,124,137, 13, 21,189,112, 82, 46, + 11,114,151,114, 91,117,216,119, 21,175,113, 83, 33, 86,232,117,120,238,174, 76,106,173, 26, 82, 67,145,101, 66,125,192, 11,141, + 45, 4,130,146,128,164, 41, 37,183, 57, 92, 66,210, 3,147,114,251,147,205, 46, 54, 83,202,178, 2, 20,226, 80,132,161, 96,169, + 73, 10, 36,120,173,129,204,140,147,204, 20, 64,198, 59,150,162, 37,117, 42, 5,134,194,253,108, 65,216,110,125, 71, 75, 11,250, + 92,139, 85, 45, 11, 75, 83, 85, 72,209,180, 51,196,206,140,172, 25, 25, 24, 29, 14,146, 35, 0,209,184, 32,134, 82, 46, 24, 18, + 55, 26, 78,240, 90,213, 31,208,130, 86, 9, 4, 18,130, 72, 73,229, 80, 42,230,108,126,177,199, 46,112, 65, 25,207, 93, 58,209, + 39,130, 16,145,159,214, 81, 60,157, 65,194, 72, 0,114,156,158,128, 96, 14,165, 71, 30,128,234, 46,217,220,212,153,116,202,237, +193,112,215,105,214,197,177,108, 64,126,171, 91,175,213, 37,166, 53, 46,151, 79,136, 18,100, 76,145, 41, 67,244, 76, 39, 45,163, +148, 5, 41,199, 22,134,154, 11, 82,210,147,121,177, 56,210,225,140,221, 20,202, 80,185, 43,180,231, 43, 85, 4,209,236,251,142, +240,181,165,219, 54,109,110,224,123,244, 52,198,233,213,121,111, 56,150,164,191, 39, 34, 8,154,220, 70,223,145,203,133,133,114, + 37, 82, 44,159, 40,174,158,140, 87,178, 8,168, 83,237, 72, 72, 38,202, 69,200, 91,220,219, 97,125,133,250,145,136, 77,103, 11, +113, 14, 98,249,179,100,188, 59, 93,159, 12,160, 94,161,169,105,165,154, 56,137, 78, 96, 87,150, 53,100, 83,203, 28,198, 91,150, + 88,129,148,174,133, 36,110,229,114, 79,128,205, 58,148,133, 31, 26, 20,100, 59, 45, 60,196,132,212, 39, 20,202,122, 50, 84, 70, + 84, 27, 10,142,218,188,129,109, 73,206, 70, 5,137,201, 14, 46, 63, 35,110,172, 30, 98,236,137, 60,136, 43, 66,208, 65, 73, 5, +196,225,111,114,171,166, 73,229, 9, 25,193, 3, 88, 95,215,200,158,183, 30, 67,206, 41, 43,116,248,202,117,107,231, 82,249,143, + 62, 86,165,101, 75, 43, 42,230, 4, 2, 9, 87, 55,198, 14,178, 38, 92, 98, 67, 32, 20,251,201, 8, 88,240, 16,146,164, 41, 67, +178,192, 65,194,147,145,216,231, 10,198,125,116,226,139,237, 51,153,109,101,216, 45,137,176, 85, 0, 40, 38,219,249, 64,243, 91, +246,186, 2, 70, 32,113, 80,251, 44, 81, 44,131, 83,130, 89,141,129,187, 49,212,196,131,181,139, 18, 64, 38,192, 90,228,140, 52, + 23, 71, 18,155, 27,182,247,133, 23,109,175,221,230,219,141,180,184,238, 72,209,228,209,169,247,213,194,220, 10,181, 86, 20,201, + 78, 65,135, 62, 60,103,163,251,172, 38, 37, 75,102, 75, 81,164,214, 36, 66,142,250,153, 91,141,169,214,146, 84,119, 30,147, 66, +165, 80,195,147, 41,232, 38,166,235,108, 25,149,121, 74, 76,250,173, 65, 50, 26, 67,141,184, 37,252, 94, 36, 34,194,208,182,218, +140, 81, 20,180, 82, 89, 10,109, 73, 89,131, 15,180, 99,113, 31,190,120,217,226,105,247, 21, 37, 48,237,189,193,122,201,132,220, +231, 27, 90,216,183,172, 58, 52, 11, 98, 37, 40,182,149, 41, 9,140,210,225,202, 12,167,155,149,105,150,162,177,158,154,222,143, +101, 55,180,158,109,129,120, 91, 92, 38,241, 1,118, 84,165,108,197,201, 83,133, 67,218, 59,194,177, 84,117, 3,105,238, 58,130, +145, 22,145,102,215, 42, 78,168,190, 54,130,167, 53,198, 99,180,128,239,129, 65,155, 33,153, 40, 74, 41,207, 76, 66, 18,163,204, + 18,106,169,105,103,136, 44,113,146,169, 37,205,135,152, 11, 55, 64, 21,137,251, 98,218, 65, 1,129, 26,156,119,103,137,223, 65, + 12,230,155,192,222, 23,241, 67,129,120,142,163, 57,207,166,202,105,115, 92,243, 34,120, 80,201, 36, 83,210, 71, 89, 57,203, 94, + 45, 47, 81, 37, 18,146,173, 69, 62,179, 89,161,231,164,145, 39, 16,209, 79, 40,202,229,206,203, 50, 92,167,210,208,107, 18,249, + 17,239,226, 44,119,234, 17,224,182,163,206,183, 36, 8,104, 87,141, 37, 68, 5, 37,149,169, 33,190,156,196,116, 73, 21, 52,233, + 79,123,195,137,167, 34,158,186,130, 89,101,234,213, 77, 81,234, 87, 35, 64,168, 41,152,136,167, 35, 45,198,233,144,132,186,180, +161,158,159,161, 42, 57,214,118,211,109, 82,144, 99,162, 60,122,107, 81,146,184,210, 98, 6,209, 25, 12,173,165,168, 41,185, 13, +180,145,149,165,224,224, 89, 57, 61,193, 61, 53,141, 63,114, 33,233, 11, 85, 22, 2,170, 6, 42, 84,212,185, 46,120, 80,168,201, +117, 77,148,182, 88,156,160,181, 73,125, 4,163, 41,105, 11, 32, 40,146,226, 20, 64,212,177, 40,249,104,218,136, 93, 29, 1,247, +238, 71,235, 92,237,232, 58, 18, 54,181,252,231,165,168, 98,130, 44,186,134,201, 24, 5,166,121, 54, 99,112, 87, 94,233, 10,130, +202,186, 81,249,136, 78,144,193,201, 44, 84,122, 5, 38, 28, 86,234,113,156,144,169,205,161,212, 57, 82,170,201, 76,201, 45, 60, +163,153,137,113,197,182,159,113,143,202,130, 20,219, 0, 33, 33, 33, 36,173, 0,232, 37,215, 92,148,250,153,181,195,113, 24,204, + 83,252, 40,144,178,220,218,116,212, 96,205, 77,188,203,169,196,146,181,168, 6,221,112, 41,150,139,220,205,165, 69, 32,139, 44, +136,107,113,106,122,179, 49,215,100, 48,241,113, 20,248,234,113,186,107, 6, 70, 20,166,155,136, 28,230,125, 10, 89, 0,151, 66, +148,164,164,149, 30,184, 24,253,199,122, 66,165, 47,234,152,208, 81, 88,170, 60,133,169,134,151, 37, 17, 89,142,182,144,160,195, +138,116, 16,184,175,115,146, 26,228, 35,152, 2,144, 10, 70,182, 97, 64, 14,163,229,113,223,173,246,245,220,141,236, 46,119,233, +208,144,112,239, 75,150, 79, 93, 50,162,150,205,103,109, 68,106,254,230, 52,186,181,201,144,170,200,168, 55, 28,194,177, 0, 89, + 74, 58, 49,195,130,197, 46,151, 71,143, 89,156,136, 50, 16,226,147,239, 45,220,146,230, 75, 91,181, 22,228,134, 85, 46, 53, 65, + 42,116,169,215, 27, 81,116, 21,143,136, 56,176, 83,223, 69,209,101,194,118,104,120,212,188,105, 41,116,182,242, 25, 83,206,149, + 54,218,214,160,181,186,242,194,131,168,108,182, 83,205,250,200,108, 3,147,240,233,134,126, 83,142,181, 21,235,160,213, 20,137, +105,109,136,245, 1, 33,149, 69,131, 86, 73, 74,228,162, 18,225, 47,194, 98, 66,176,143,133,208, 29, 73, 36,133, 44,128, 52,237, + 91, 17,157, 91,145, 84,244,169,143,180,227, 68, 21, 75,109,133,243, 33,111,129, 20, 74,114, 56,241, 39,182, 84,174, 82, 70, 20, +165,173, 69, 57,239,167,120,101, 42,241,198, 6,146, 55,181,138,219,126,164, 14,187, 16, 5,245, 16, 5,201, 45,115,133, 51, 76, +165,169, 40,229,154,170,189,170,102,150,227, 88, 37,145,130, 42,169, 88,221,140,154,183, 83,169, 71, 40, 43,236,138, 6,155,195, +227,233,107,174,155, 39,136,190, 10, 30, 97,107,118,164, 56,127,220, 70,158,146,160, 16,217,132,155,246,143,200,210,154, 35,155, +222, 4,191,120, 37, 71, 9, 82, 86, 10, 64,235,168,152,132,228, 28,164,164, 19,215,231,143, 77, 73,155,233, 79, 95,204, 87,248, +240,217,189,185, 66,217,147, 47,105,120,111,164,154,148,182,157, 83,138,126, 70,226,221,245,186,220, 86,150,133,146, 80,148, 83, +104,144,212,158,249, 18,186,147,129,168,234,237,246,223,222, 27,165,119,219,150, 21,133,110, 86,174,219,186,237,172, 68,160, 91, +118,213,189, 79,122,169, 91,174, 86, 39, 44, 34, 53, 58,153, 1,128, 75,239, 43,226, 82,212, 74, 91,101,180, 45,231,150,219, 72, + 90,211, 98,229, 79,202,203,150, 89, 92, 34,171, 76, 88,147,176, 28,199, 55,185,216, 11,111,185,252, 49,198, 60, 76,139,250,126, +189, 32, 28,197,102,132, 46,145,114,196,195, 16, 0, 0, 1, 44, 73,181,128, 4,182,214, 7,108, 96,193, 42, 89, 72, 66,114, 71, +100,165, 36,149, 99,176, 0,119, 58,237,167,177,211,217,215, 3,138,221,197,169,239, 54,241,210, 85, 43,135, 45,155,171,194, 77, +122,148,248, 83,108,110,166,227, 37, 13, 84,169, 27, 94,149,140, 21,219,145, 99, 42, 44,251,145, 77,156,169,135,162, 82,185,144, +185,207, 4,246, 39,129,175,163,187,181, 22, 69, 46,141,184, 92,116,214,164,223, 87,121,101,186,140,141,132,177,171,110,211,108, + 90, 17, 41, 14, 34,153,125,223, 20,181,162,117,229, 60, 3,201, 42, 45, 53,216, 84,224,161,200,151,229, 4,149, 43,177, 76, 91, + 27,113,181,244, 24,150, 14,210, 88, 54,166,216,237,189,188,185, 31, 81,216,214, 37, 26, 21, 6,221,166, 25,110,243, 75,144,204, + 24,141,132,174,107,238,225,201, 18, 29, 43,126, 67,129, 42,121,215, 23,130, 27,243, 44,205,164,167, 43, 26, 24,161, 39,118, 99, +165,220,118, 10,191,105, 84,157,152,182,150,181,202,117, 86, 19,158, 18,240,238,182,106,218, 90,236,242, 5,138,150, 59, 56,166, + 62,103,145,133,180, 9, 71,217, 84,185, 12,200, 75, 22,182,135, 80, 11, 12,100, 74,154,169,242,176,132, 54,203,109, 54,195, 44, + 71,140,203, 81,226, 70,137, 29,164,179, 10, 4, 72,236,165, 45,195,134,212,102, 91, 75,109,182,148,182,219, 76,161, 8, 74, 80, + 18,144,232, 90,112, 2,249, 93,117, 25, 66,146,209, 71, 66, 22,162,163,134,241,211,245,150,177,159,152, 58,106,104,113, 92, 82, +188, 39, 22, 57,159,117,107,144,172,114,134,208,144, 20,235, 77,249,242, 37, 62, 27, 96,249,156,159,144,217, 59, 62,158, 23, 33, +162,160,146, 26, 67, 60,168,236,129, 33,209,134,130,134, 48, 2, 26, 35, 31, 51,211, 77,180, 46,116, 52,199,224, 54,176, 30,128, + 14,214, 29,134,219,219, 98, 14, 47,113, 78, 21, 72, 3, 87,123,254,238,135,222,126,240, 59, 91, 14,157, 22,158, 26,105,164,172, + 5,168, 4,243,159,213,231,121,125,145,208, 99, 30, 93, 60,129,211,139, 26, 35,109, 54, 49,133, 17,220, 16, 79, 83,232, 60,250, +246, 31,187, 86,138,100, 68,165, 73, 8,229, 81,142, 64, 42, 86,112,183, 22,144, 21,130, 15, 85, 36, 19,242, 28,218,203,218, 78, + 49,240,169, 41, 70, 66, 74,122,165, 68,142,170,207,160, 57, 72,251,254, 88,216, 14, 90,230,251, 15,244,249,254,125, 48,211, 87, +166, 54,210, 5,205,133,251,123,192,239,235,247, 3,211, 99,142, 83,123,105,234,144, 40, 62,204, 78, 45,213, 56,172, 10,158,223, +193,161, 68,109,166,214,234,222,168,213,110,106, 44,120, 49,210,219,105,230, 42, 83,161,103,253,144,131,228, 53,249,148, 74,163, + 86, 33,178, 31,157, 73,168, 68, 97, 73, 37, 15, 75,136,244,102,150,130,114, 10, 29,117,176,149,119,242, 39, 7,166,117,250,228, +239, 21, 54,139,113, 81,162, 91, 21,234, 77, 58,187, 2,167, 53,185, 83, 41, 53,168, 81, 42,144, 36, 71,167, 16,227,102, 68, 9, +141, 45,167,146, 37,173,178,146,164,171, 5, 25,232, 70,154, 39,182,131,105, 43,148,145, 68,173,237, 86,217, 86,168,230, 58,226, +138, 93, 86,195,181,102,211,147, 24,131,204,194, 99,191, 75, 41,109,188, 19,219,175, 94,132, 30,186,205, 29,108,244,181, 21, 13, + 12,113,200,178,104, 7, 83, 48, 55, 91,237,178,176,177,213,114,119, 55,218,198,215,196, 43,137,120, 6,163,136,230,167,205,151, + 49, 90, 53, 72, 22, 32,134, 2,250,180,203, 43,106, 45,205, 75, 41, 46, 64,178,159,179,125,239,183,228,250,227,101, 60,188,224, +140,142,128,244,207,144,199,168,198, 48,126,122, 21,192, 0, 3,155, 35, 57,233,215,215,166,191, 65, 78, 47,125,129,220, 19,241, + 21, 2,167, 90,218,170, 35,252, 48,110, 99,233,144,252, 74,205,131, 29,202,134,222,212,103,172, 18,132, 92, 59,119, 53,242,134, + 99, 45,220,115, 59, 76,122, 43,169, 25, 41,109, 88,229, 48,230,227,131,217,183,196,255, 0, 1,119, 35,112,119,146,205, 19,108, + 74,180,247, 33,217,251,193,104,151,171, 59,105,118,144,165,248, 44, 49, 88, 13, 5,219,245,162,132,229, 84,234,138, 35,202, 73, +200,108, 58,145,204,100,244,217,164, 82,178,199, 50, 26,105, 9, 0, 92,221, 24,250, 43,250,158,193,130,177,236,164, 11,226,164, +206,184, 91, 56,200, 65,146,174, 1, 45, 32,219,159, 17, 47, 24,222,195, 93,194,188,123,216, 93,212, 33, 36, 42,187, 28,115,229, +210,158,163,169, 24, 62, 96,119,253,255, 0,215,160,212, 66,187,167, 24,232, 58,249,116,198, 49,219,174,141,117, 3,152,133,229, + 39, 56, 41,199, 80,122,227, 65,120, 97,165,169, 73,201, 43,238, 14, 79, 41,235,146, 61, 52,244, 14,192, 1,182, 35,160, 31, 92, + 14,231, 32, 73, 74,186,231,203, 24,251,137,244,208,101, 3,148, 32, 40,165, 57,236, 60,201,209,133, 63, 26,186,168,231,201, 71, +225, 29,187,121, 13, 81, 86, 50,122, 16,115,246, 12,124,177,163,142,222,236,103, 3, 40, 3,211, 29,186, 30,189,241,215, 57,208, +203, 24, 36, 15, 67,140,252,199,207,203, 69, 47,208,103,166,115,229,147,129,215, 62,186, 25, 64,244,230, 29,124,143,175,113,215, +212,233, 85,189,129,245,235,243,240,198, 69,172,126,125, 48, 42,129,193, 30,127,147,161, 85,246,156, 17,215,204, 2, 8,199,217, +162,148, 58,146, 20,122,103,207,167,159, 83,161, 92, 42,235,233,230, 71,159, 95,232,210,139,215,173,176,170,143, 95,157,176, 50, +206, 15, 76, 31, 80, 71,224,126,220,104, 85,168,227, 28,189,125, 61,126,206,154, 37,100,103, 3,200,156,244,243,249,232,117,227, + 57,235,233,242,251,180,182, 50,126, 54, 56, 25, 99,175,159, 81,231,229,242,210,215,178,172,119,200,244,198, 14,127, 31, 61, 45, + 40, 47, 97,229,191,200,255, 0, 79,155,224,126, 56,162,144, 64, 30,191,143,158,170,163, 62,125,137,232,115,220,250,106,159,236, +213, 69, 35,156,131,204, 71,166, 63, 63,156,233, 54,219,160,220, 99, 35,227,108, 20,131,208, 14,228,121, 99,231,251,116, 80, 56, + 35,184,249,250,104, 22, 57,146, 8, 81,234, 59, 31, 80, 60,243,247,232,209,216,117,207,207, 68,223, 77,200,244,254, 88, 24, 45, + 24,207, 92,231,203, 69, 35,207,183,239,208,173,124,207, 92,126,127,118,138, 64,232, 79,221,249,252,249,105, 44, 16,142,190,251, + 15,145,130, 80, 58,103,215,250,244, 66, 49,140,129,215,212,247,207,245,106,146, 48, 57, 79,150, 7,252,116, 64,193,232, 49,223, + 31, 97,210, 44, 79, 91,236,127,211,253, 48,153,183, 97,138,128, 40, 5,103,208,224,119,235,169,123,123, 41,104,112,173, 78, 2, +173,121, 73,134,167,220,191,111,139,158,183, 80,116, 97, 14, 1, 26, 65,131, 29, 41,199,146, 91,142, 0, 58,136,106, 65,193, 4, +140,224,156,227,211,175, 77, 75,111,217,163,113,199,172,240, 9,183,233,105,231,146,187, 86,241,187, 45,249,133,131,143, 9,213, + 78,114, 75, 97,196,121, 2,219,168, 32,158,224,244,213,121,226, 65,147,244, 28, 33, 13,148,206,186,191,254, 57, 45,142,131,250, + 49, 71, 12,158, 42,209,137,118,101,162,169, 41,214,225,249,148,226,226,196, 27,233, 45,211,181,251, 99,118,128, 83,114,214,210, +153,146,220,116,144,235,125, 10,212,129,205,144, 20,161,156,249,105,224,180,100,161, 50, 35, 25,130, 74, 80, 57, 85,206, 20,176, + 26,230,198, 22,164, 30,253,198,153, 40,181, 49,238,232, 92,122,195, 47, 73, 82,210,211, 81,100, 39,149,110,184,178, 82,218, 1, + 61,252,180,248,219,242,107, 80,222,162, 71,155, 77, 98,169, 61,192,124,102, 35, 56,130, 91,108,254,170, 94, 72,254,110, 58,245, +215, 54,213, 70,193,217,152,217,148,130,111,182,219,117,233,112,127, 28,123, 9,151,215,172, 84,113,194,236,164,181,215,237,232, +114,116,222,246,144, 11,142,228,222,194,248,216, 58, 84,210,135, 89,145,227, 49, 81,108,184, 26, 12,189,132,132,180,123, 21,146, + 58,249,103, 78, 29, 49,216,145,157, 46,202,141, 0, 50,165, 99,153,162,151, 0, 10,255, 0, 80, 14,216,207, 93, 55, 22,253, 58, +116,249, 14,180,186, 68,194,162,227,110, 41, 40,100, 22,154, 72,236,208, 41,238, 63,167, 78,237, 50,222,105,197, 50,210,160,203, + 5, 43,248,209,238,139, 82, 16,172,254,170, 84, 6, 15, 64,123,246,209, 97,137,100, 58,121,100, 21, 38,219,129,125,253,251,159, +203,124, 66, 51,202,138, 53, 13,169,202,221,119, 10,203,112,189, 71,216, 96, 1, 27,139,233,177,239,124, 60, 54,123, 86,252,196, +161, 45,162, 50,155,229, 7,170, 74, 10,129,238, 6, 71,112,116,252,211,104,240,209, 29, 41,140,174, 68, 20,228, 53,207,204,217, + 24,234, 19,232,174,250,105,109, 74, 83,112,209, 24, 57, 24, 70, 14, 44, 8,200,152, 24,136,167,206,112,124, 36,200, 90, 75,189, + 71,243,115,233,167,174,148,195,204, 73,247,101,182,182, 20,172, 18,219,237, 41, 33, 67,200,161, 67,203,168,237,167,136,114,230, +101,187, 11,252, 13,192,191, 66,125,255, 0,150, 57,147,139,234,195, 84,202, 96,169,114,138, 75, 0,206, 26,224,108, 77,134,219, +119, 54,216,237,113,131,109,233, 2,149, 48,165, 68,165, 30, 38, 65, 7,177,206, 58, 19,172, 11,142,250,104,187,248, 72,189,156, +100,243,201,160,212,173,234,211, 33, 37, 75, 0, 55, 52,196,120,156,116, 8,228,153,212,158,131, 26,214,142, 52, 56,200,162,240, +178,104,182,149, 18,205,170,110, 30,239, 93,144, 68,251,106,214,167,179, 37,200,145,162, 56,240,138,204,250,159,186, 52,167, 29, + 74,229, 97, 13,180,210, 74,150, 65,201, 72, 25,215, 24,110,255, 0,109,214,236, 89,181,169,123, 63,196,206,212,209,225,216,219, +139, 33, 54,133,121,152,140,200,163, 86,236,207,172, 95, 67, 44,213, 92, 50, 29, 90, 28,247, 39,220,142,243,241,228,161, 37,109, + 48,160, 22,133, 16,160,237,150,210, 77, 74, 30, 57, 24, 4,148, 29, 42, 55,123,122,233, 0,155, 3,252,176,190, 77,224,151, 30, +113,173, 21, 7, 27,228,116, 52,241,195,151,149,172,136, 84,213,193, 77, 53, 92, 16, 72,162, 73, 41,163,149,129,100, 44, 12,107, + 36,134, 56,222, 75, 34,185, 39, 28,240,171, 81, 92, 18,235, 15,189, 50, 83, 15,182,251,205,242,193, 1,135, 11,172,188,227,129, +215, 90,116, 41, 15,167,152, 55,128,160,127, 87,190,113,171,197,186,251, 84,199, 27,110,231, 91, 11, 8,109,105,102,164,211,204, +152, 75, 4,120,205, 50,166, 93, 67,142, 51, 33,194, 84,147,146,190, 85, 0, 82,178, 59,103,187,207, 96, 84,168,155,135, 92,164, +148,251,168,139, 80,118, 74,101, 49,206,195,115, 26, 83,165,196,200, 97,164,164,165, 44,172,160, 41, 39, 56, 83,110, 36,144, 0, +213, 45,183,165,251,180,225, 57,214, 41,211,231, 46, 59,134, 32,155, 57,137, 75, 47, 56,165, 48,251,207, 7, 20,216, 97,211,207, + 28, 22,210,121,212,147,204,148,242,228,105,122,137, 21, 98, 46,198,247, 22, 0, 1,112,118, 0, 3,218,222,150,216,220,157,247, +199, 91,101, 89,173, 61, 78, 87, 77, 84, 36, 38, 42,136, 21,215, 65,180,182, 96, 28, 89,154,203,123,157,181, 30,246, 5,126,214, + 30, 11, 94,207,114,229,117,201,237, 69,164,202,120,197,143, 54, 85, 82,157, 37,183,147, 22, 59,235,108, 65,134,165, 70,194,224, + 61,226, 33, 45,144,231, 55, 47,196,226,209,149,116,219,107, 39,110,107,207,161,154, 43, 53, 69,192,105,220, 59, 45, 51,224, 51, + 86, 64,151,226,135,152,104,200, 64, 67,211, 90, 7, 24, 74, 94, 41,111, 9,230, 0,233,156,176,182,201, 77,169, 18,170,137,115, +223, 42,193,152,112, 99, 91,243,158,143, 35,199, 74,144,226, 36, 74,147, 13,192,137,144, 80,224, 4,151, 2,137, 82,194, 64, 37, + 56, 27,217,102, 90,215,133, 41, 49, 27,133, 84, 98,165, 57,224,159,142,189, 5,146, 26,113, 35,153,236,152,138,109, 46,169, 69, + 25, 87,137,133,140,117, 36, 18, 53, 10,175,145,203, 5,138, 80,109,208, 48, 59, 17, 96, 8,190,160,123,246, 0,108, 20, 27, 91, + 12, 57,247, 17, 10,106,116,134,130,190,154, 78, 89, 80,156,196, 87, 1,193, 91, 30, 97, 18,163,152,205,238,197, 65, 6,218, 88, + 22,108, 90,237,237,189,152,234,185, 95,164, 89,245,210,228,149, 56,245, 82,107, 53, 74,100,246, 35, 52,164,165,243, 25, 77,135, +115,204,242, 70,121, 29, 74,177,211,148, 96, 43, 79, 29,187, 98, 95,172, 58,106, 17,164, 80, 67, 45, 56, 12, 74,109, 70,100,217, +240, 85, 24,171,153, 44, 69,113,113, 82,236, 53, 20, 4,149, 21, 41, 69, 5, 39, 41, 86, 6,179,123,118,157, 92,141, 29, 16,156, +183,161,203,117,169, 45, 41, 85, 8,181, 70, 27,109, 47,173,212,248,236, 71,106, 84, 99,132,175, 36, 36,133,242,100,225, 68, 4, +141, 58,241, 37,169, 36,181, 81,162,206,163,163,196, 75,109,173,245,177, 34, 3, 69, 39,152,189,239,177, 10,146,225, 89, 79,232, +208,128, 73,194,129, 72, 61,117,169, 79, 70,103, 39,152, 2,179,118,234, 61,230,215,211,210,196,129, 98, 64, 29,141,241, 79,103, +220,101,153, 30,114, 70,144, 85, 43, 2, 13,228, 73, 14,130, 64, 58, 33,230, 2,133,252,192,233,140, 21,185, 0,130, 72,108,110, +143, 14,191, 8,188, 39,209, 80,234, 30, 65,115,252, 6,171, 17,212, 71, 73, 7,149, 40, 68,198,155,113,192, 74, 65, 61,137, 39, +175,124,235,131,126,216,205,247,152,111,141,190,225,194,146,243,176,233,118,141, 10,155,186,215,228, 17, 33,165,138,133,245,119, + 54,244,107, 38, 20,208,210,212, 86,213, 50,201, 6, 83, 77, 44,254,130, 77,220,242,193, 10, 9, 34, 68, 98,167, 69,113,239,115, + 98,162,209,150,227,169,100,164, 50,250, 30,142,153, 10, 67,104, 47,161,113,185,149,250,217,193,234, 7,124,117, 58,132,167,180, + 11,114,157,191, 56,207,226,110,235, 91,220,193,123,191,119, 82,161,167, 35, 13,210,109, 57,205,218, 52,134, 80,174, 65,250, 54, +233,246,252,102,210, 48, 48,150,250,247, 58,147, 81,229,101, 16,136,212, 49,107,111,110,151,247,223,215,107,145,238, 29,206, 45, + 63,161,246, 88,153,247,139,149,156, 79,155,208, 8,233,184, 47, 46,150,174, 32,203, 38,147, 89, 80,241, 82,211,189,164,119, 95, + 36, 18,213,200,157, 74, 75, 28,114, 11, 50,130, 59,157,236,172,221, 24,215,231, 13, 23, 37,147, 81,118, 25,168,236,189,253, 46, +152,218, 93,144,151,101, 53,102,223,141,191,116, 91,190, 19,107, 28,209, 97, 71,172, 69,186,152, 65,253, 80,165, 4,167, 7, 26, +218,107,158,228,161,191, 61,218,125, 49, 94,245, 40,172, 37,210,202,148, 67, 42, 11,229, 81,117,224, 57, 60,114, 15, 92, 2,160, +149, 14,100,228,234, 49,124, 2,239,229, 79,110, 55,233,155, 77,234,234,233,116, 45,237,130,141,181,173,200,114, 66, 99, 70,106, +181, 46,104,159, 98, 79,117,194,147,225, 52,221,203, 17,152,171,112, 17,134,171,110,142, 96, 9,204,138,108,186, 50,226,248, 65, +230, 94, 18,210,234,138,218,116, 40, 56,144,201,253, 42,228, 2,144, 82,232,125, 39,155,155,185, 24,199,163, 70,113, 75, 61, 53, + 66,211, 24,192,102, 80,250,173,177, 4,158,128,236,109,107, 27,244,244, 55,216,120,245,195,212, 92, 51,226,119, 20,241, 60, 83, + 51,208,241, 68,223,164, 41, 96, 4,170, 44,179, 42,251,111, 53,134,197,189,176, 77, 41,141,108,170,146,160, 98, 5,181, 97, 28, + 75,220,181, 26, 38,200,211,104,247, 69, 74,235,183,182,170,177,190,251, 65, 11,117,110,107, 14,159, 10,179,117, 91,182, 75,207, +220, 78,183, 82,133, 14,168, 4, 79,171,216,186,153,183, 21, 41, 82,210, 98, 36, 41, 9,115, 46,170, 58, 78,196,185,236,244,224, +218,187,107, 59,115,220,156, 71,239,126,228,237,173, 2,138,187,170,107, 84,230, 45, 75, 86, 5,193, 65,109,135,229, 52,252, 91, +142,223,106, 82,213, 70,114, 67,192,198,106, 35, 40,154,243,242, 91,140,151, 91,112,244,112,233,245, 17, 14, 44,120,174, 52,203, +140, 76,104,179, 45,183, 16,135, 25,122, 52,130,142,120,210,155,117, 36, 60,203,137, 64, 5,181,165, 73, 88, 7, 57,232, 53,131, +111, 20,122,181,183,183, 23,101,181,105,248, 52,138, 5, 74, 76, 74,251,148,250,116, 97, 1, 16,222,167, 60,106, 47, 70,165, 53, + 21, 77,181, 6,159, 41,244,182,244,150, 67,100, 56,236,116,184, 10, 10,220, 42, 89, 95, 56,135, 46,142, 10, 39,138, 88, 81,180, +202, 38, 14, 74,164,134,226, 72,138, 50,168,146, 61,200, 73, 86, 72,223,161, 85,177,213, 91,112,255, 0,139,220, 97, 77, 6, 89, +195,156, 53,196, 21, 60, 22,207,152, 77, 60,242,208,138, 52, 21, 75, 82,148,144,150,121, 38,162,154,174,158,178, 4,129,185,117, + 52,245, 41,169, 36, 80, 81, 94, 4,118, 96,232,187,243,188, 52, 58, 53,183, 22,179,113, 84,169, 53,196, 81,160,251,245, 41,201, + 62,244,245, 37, 30, 24, 17,105,181, 9, 10,121,208,245, 77,152, 9,140,153, 37,110, 58,225,146,151,148,235,139,112, 41,106,217, +189,151,227, 46,253,131,118,219,180,250,252,122,125,201, 79,118,165, 17,114,150,164, 24,178,216,166,197,117, 15,212, 36, 41,109, +252, 46,145, 13,149,146, 84,156, 16,146,163,211, 58,229, 18,107,239, 62,242,147, 37,199, 31, 91,206,242,186,241,117,192,165, 58, +115,211, 39,155,149,210,121, 78, 15,117, 43,161,198,175,245,237,208,133,180,123, 77,185, 27,181, 83,195,175,211, 41, 12,109,245, +155, 17,197,165, 15, 85, 55, 47,117, 95, 93,149,109, 82, 48,149,164,169,198,162, 73,174, 84, 86, 89,234,134,109,247, 20,190, 92, +115, 20, 34,161,174,138,166, 35, 73, 52,177, 73, 35, 11, 42,177, 35,177,251, 38,224,129,110,227,176,216, 3,139, 63, 49,225,124, +159, 58,137,168,171, 50,122, 67, 83,155,200,176,199,104,150, 37, 89,170,228, 17, 68, 21,129,214,136, 36,145, 64, 37,137, 84, 80, + 88,147,124,113, 55,116,247, 70, 69,253,187,251,165,124,248,206, 6,183, 3,113, 47,219,205,230,124,103, 29,108, 53,115, 87, 43, + 21, 40,234, 47,172,146,232, 75, 18, 90, 9, 39, 39, 13, 39, 9,232, 14,172, 14,214,153,120, 48,183, 78, 92,152, 57,157, 10, 37, + 43,109,167, 26, 13,184,150,207, 80,131,206,176,172, 30,169, 9, 5, 24, 32,105,155,145, 77,159, 79,177, 55,214,248,122, 99,102, + 14,214,238, 37, 54,195,167, 33,244, 45,181,207,144,221, 5,213,204, 44, 21, 16,151,138, 88,241,164,244, 32,167,198, 64, 82, 64, + 41,200, 53, 27,141, 40,118,147, 76, 15, 45,169, 62, 12, 25,243, 2, 86, 20,234, 16,197, 62, 19, 65,165,164,117,229,247,167,138, + 73, 61, 22,177,202, 7, 66, 69,171, 7, 12,211, 48,141, 68, 97,196, 42, 34,118,176,243,125, 68, 82, 27,237,230, 26,101, 64, 77, +183, 59, 94,221,125, 38,200,188, 76,203,114,202, 54,165,142, 67, 20,116, 65, 22, 8,217,183, 68, 90,250,204,182, 21, 7,236,171, + 60,153,116,228, 2, 70,148, 58,202,134,186, 15,209, 95,217,213,187,149,126, 36, 56, 44,216,253,206,187,174, 26,157,110,227,126, +218,126,193,186,149,240,199, 84,155,163,109, 39,191,101, 84, 39,204,125,144, 23, 80,149, 50,149, 75,163, 76,121,231, 85,202,227, +245, 23,148, 15, 58,213,173,192,169,181, 57,184,233, 69, 62, 75, 17,217,117,148, 54, 25,157, 8, 41, 77,184, 20, 57, 18, 85, 21, +196, 40, 55,148, 36,167, 33,106,235,158,185, 26,226,103,176,146,232,171, 73,224,105,202, 90,107, 52,248, 49, 97,111,182,232,183, + 25,185,145,221,148,239,233,169,118, 36,151, 91, 74,223,144,136,236, 44, 74, 46, 41, 40,108,169, 68,173,101, 73,230, 86,187, 41, + 49,154,218,209,205, 42,173, 52, 52,180,165, 74, 68, 70, 98, 69,116,182, 9, 42, 83, 15,150, 84, 82,172,173, 43,228, 0,100, 3, +231,140,166,170, 86,154, 21,107,179,160, 10, 88,238,110,160,139,147,114, 77,254, 59,238,122,227,195,207, 25,248,114,151,135,188, +100,241, 27, 44,203,158, 10, 60,158,155, 59,204, 26,142,156, 69,166, 56,105,158,169,228,130, 24,163, 88,121, 65, 97,137,146, 53, + 32,147,100, 5,141,201,182, 5, 94, 69,230, 10, 94,145, 46,158,251, 79, 45,104,148,212, 6, 23, 14, 74,219,229, 12, 45,182, 36, + 58,225, 37,149, 97, 25,231, 83,121, 7,151,152,115,103, 88,171,145,168,116,244,134, 97,194,115,222,240,219,142,210,234,106,145, + 26, 99, 65,211,209,246,222,146, 74,159,116, 16, 64, 41,113, 93,130, 80,224, 61, 53,146,220, 18, 42,169, 71,189, 65,175, 23,224, + 43,196,110,100,138,180, 52, 73,141, 20,132,150,219,121,201, 49,146,211,140, 32,184, 66, 20, 84, 8, 65, 74, 73,198,117,138, 87, + 28,148,234,162, 34,187, 74,117,192,134,195,141, 85,221,124,204,165, 74, 66, 64, 8,106, 33,105, 1,113,212,225, 81, 86, 31, 66, + 49,205,221, 67, 11,214,189,142,171, 48,185,237,109,186,218,221,251, 94,219,220,117, 0,118,198,190, 89,205,228, 83,161,104,226, +136,234,212,180,224,194,199, 64, 4, 7,140,136,249,140,128,157,144,137, 21, 72,107,233, 54, 57, 45, 21,111, 50,239,128,212,167, +155,106, 99,237, 53, 50, 5, 82, 58,170,112,130, 22,133,248,114,226,201, 82, 20, 84,194, 84,162, 75, 79,133, 20,150,202,144,180, +144, 70,158,219, 70,151, 29,231,155,118, 60,104,204, 22, 63,193,222,142,151, 20,169, 10,146,203,194, 58,208,195,190, 63,232,220, + 83,255, 0, 26, 27, 64, 12,165, 9, 10,230, 9, 32,105,148,162, 91,141, 33,248, 83, 89,126, 99, 48,230,182, 20,180,198,150,244, +129, 79,113, 60,188,170,101,153,170,115,222, 32,173, 37, 93,149,240, 99,149,124,169, 9, 89,109,184,249,226, 98, 31, 5,220, 21, +239,191, 17, 15,200,136,155,150,213,178,166,210,246,246, 59, 73,141, 4, 86, 55, 54,239,228,181,236, 42, 83, 8, 90,185, 31,124, +220, 21, 40,178,202, 18,149,144,213, 45,220,101, 41, 86,157,232,209,181,169, 10,100,111, 40, 23, 59,177, 54,181,129, 23, 4,146, + 58, 1,212,220, 92, 98, 11,198,117,212,212,212,243, 58,213, 20, 77, 12,210, 54,146, 52,132, 30,109, 96, 29,244,170,155,187, 57, + 42, 0, 96,197, 77,204, 4,253,172,219,203, 47,139, 95,105,175, 18,183,101,176,204,138,245, 61,141,200,141,179, 22, 18, 41, 9, + 93, 86, 93,102,147,182,162, 46,222,210,152,166, 51, 24, 19, 62,108,219,142, 29, 80,176,134,211,151, 87, 57, 0, 2, 78, 76,168, +189,147, 30,205, 59,119,129,141,189,137,185,219,145, 71,167,212,120,177,191,168, 72,110,225,150,239,131, 57,157,155,182, 42,104, +109,241,183, 54,188,132,130,150,171,238,183,225,154,253, 69,162, 22,251,224,192,105, 98, 36,114, 29,230,127,176,159,128, 53, 76, +144,190, 60,247,198,152,229, 94,166,106,149, 39, 54, 34, 21,106, 58, 84, 43, 87,116,135,159, 77,209,188,211,162, 60,140, 58,227, + 18,159,150,197, 29,103, 9, 19, 37, 74,154,140,150,153, 34, 80,232,121,231, 86, 94,194,151,206, 84,165,229, 89, 83,132,156,149, +100,255, 0, 59,169,238,117, 52,214,174,144,192, 15,246,106, 75, 42,129,210, 73, 19,102,115,254, 20, 96,116, 95,171,221,172, 52, +163, 53, 11,192,252, 48,106,170,102,226,204,206, 29, 53, 57,147,188,180,145, 48,254,234, 41, 9,101,148,237, 96,238,166,209,126, +196, 86, 97,188,158, 91,213,199, 90, 49,104, 79,128,238, 30,144,121, 9, 61,192,192,201, 10,245,242,251,181,174, 71,196,148,241, +192, 74,219,247,143, 25,101,101, 88, 83,109,158,100, 32,143,231,159, 20,183,140,231,245,116,231,222,179, 3,236,178,194, 18,160, +158, 67,240,159,214,231, 63, 8,200,245,230, 7,246,107, 16,183,233,171,125,220,148, 41, 94, 26,193, 82, 72, 56, 30, 24, 42, 25, + 7,182, 93, 82,127,254,159,144,211, 69, 97,106,138,152,227, 83,176,254, 38,222,238,150,252, 15, 81,139, 78, 53, 68, 46, 72,176, + 83,107,124, 58,253,247,191,243,198,113,108,211, 19,227,169,194,215, 63,134,203, 99, 5, 93, 27,101,146, 22,246, 14, 62, 37, 45, +242, 7,255, 0, 71, 91, 55,104, 83,196, 88,200, 91,141, 21, 62,226,125,225,196,142,201,144,233, 1,182,178,161,208, 1,200, 7, +158, 18,112, 52,218,218, 20, 34, 11, 72, 82, 48,167, 29, 66, 86,162, 9, 37,168,227,198,115, 36,249,169,100, 15,158,126,122,216, + 74, 93, 56,165,176,160, 48, 80,160,230, 79, 96,234,193,228, 24,207, 80,150,250,245,243, 58,216,145,194,132,133, 59,122,123,247, +233,252, 61, 58,123,176,171,188,113,197,169,205,134,223,126,214, 23,251,250,216,250, 19,223, 23,184, 45, 45, 45,164,250,130,146, + 81,130,165, 58, 79,198,161,205,211,205, 71, 39, 29,135,217,171,242, 82,161,202,146, 14, 66, 64, 79, 92, 18,112, 18,132, 16, 7, + 82, 71,151,110,167,174, 79, 64,225, 49,204, 6, 74,148, 8,194, 60,151,142,203, 80, 0,244,206, 50, 62, 95,110,173, 87,197, 93, + 84, 74, 17, 76,101,242,212,170,171, 93, 62,154, 51,254, 77,126, 25, 50,166, 56,148,245, 8,102, 57, 81, 78, 59,184,180, 13, 2, +252,184,139,157,194,142,158,167,111,226,127,215, 17,237, 18, 87, 87, 69, 75, 8, 13, 45, 67,233, 30,130,251,146,127,194,160, 22, +111, 64, 9,233,134, 94,191, 60,214,174, 57,178,155, 80, 92, 88,138,250,178, 34,146, 73, 75,205,197, 89,247,133,181,215,245, 87, + 40,172, 41, 93,185, 91, 30, 93,117,113,101,178,148, 36, 20,167, 60,185, 33, 32,115,124,125,242,123, 32, 17,235,228, 58,103, 58, + 6,155, 5, 49,217, 1, 3, 41, 72, 72, 43, 80,202,251,124, 13,167, 57,231,230, 87,116,142,188,202,202,181,122,119,157,164,242, +182,128, 48,114, 74,210, 29, 82,148,174,231,149, 4, 14,112,122, 96,156, 36, 12,232, 82,130, 20, 22,181,207, 83,241,235,252,127, +134, 38,117,241,198,136,144, 66, 60,145, 40, 65,126,182, 80, 5,205,187,158,167,191,125,177,107,145,209, 56, 56, 42,192, 31, 7, + 50,136, 81, 39,245,114, 6,113,145,215,212,143, 62,186,109,183, 18,195,178,183, 58,203,185,118,235,114, 45, 74, 13,245, 98, 93, +244,185, 20,123,178,204,185,224,179, 84,161,215, 41,210,208, 90, 83, 50,227,188,143,209,202, 66, 15, 51, 50, 26, 45,202,140,234, + 80,244,119, 91, 90, 65, 46, 20,133,132,149, 18,121, 66, 82,146,158,167,227, 3, 9, 11,231,233,205,133, 28,116,233,240,231,231, +171, 4,167,130,146, 70,115,130, 7, 41,230, 1,190, 97,133,140,168,119,230, 25, 87, 47,167, 66,115,128,228,164, 50,233, 32, 21, + 35,161, 23, 7,226, 15, 81,234, 45,238,196, 78,170, 0,218,129, 93, 72,247, 12, 8, 22, 32,141,193, 7, 98, 10,220, 16,110, 45, +112,118,216,254,127, 62,215,111,101, 5,107,129, 75,173,157,208,218,223,173, 46,126, 22, 47,170,217,166,219, 21, 73,139,114,161, + 95,218,219,154, 98, 29,148,206,220,223, 83, 66, 63,194, 24, 91, 77,191,245, 45, 81, 88, 76,246, 99,150, 29,196,198,148, 28,226, + 11,202,192,207,250,185,206, 65,252, 7,207,183,227,175,213, 99,121,118,187,111,119,183,109,239,125,163,221, 75,114, 53,215,183, + 27,137, 66,147,110, 93,212, 9, 73, 66,132,168, 18, 70, 89,155, 1,197, 28,211,235,208,230, 33,137,116,249, 72, 41, 92,105,113, +154, 90, 84, 7, 50, 85,249,178,113,225,194, 13,235,193, 55, 17,215,238,197, 93,238,191, 80,167, 82,159, 69,111,111,238,242,201, +110, 45,251,182,117,197,186,245,165,117,196,233,203,239, 75,138,218,226,212, 26, 24, 84,122,141, 58, 75, 74, 74, 64, 71, 51,238, + 85, 86,192,138, 57,152,176,223,150,204,110, 72, 29, 81,137,234,203,216,159, 51, 46,237,118, 86, 99, 65,113,143, 12,174, 75, 50, +215, 81, 41, 25,101, 83,105, 43,215,145, 46,237,160, 27,127,116,226,230, 50,126,201, 86, 67, 97,203,213,166, 30, 57, 89, 86, 50, + 57, 63, 91, 35,175,110,154,250,115,156,144,122,249,254,255, 0,158,190,132, 99,161, 63, 14, 7, 46, 51,204,122,121,244,234,117, +245, 72,229, 29, 50,113,234,114, 6,127,226, 52,254, 46,118,196, 36, 11, 11,116,192,142, 40,231,160, 24, 29,207,175,231,166,135, + 82,137,238, 64,232,124,241,143,179, 68, 44, 19,211, 24,237,156, 99,160,245, 31,126, 52, 50,128,235,212,121,128, 78, 49,215,207, +246,105, 68, 59, 91,211, 6,181,253,109,251,240, 59,128, 1,240,171,174,122,121,121,246,207,159,246,104,101,244,200,243, 35,246, + 1,147,162, 21,140, 28,140,254,113,161,148,112, 8,235,215, 56,237,248,125,154, 85,112,176,189,136, 39, 3,168, 0, 15,145, 62, + 99,204,143, 35,249,242,208,203,229,235,235,211,242,126,225,162, 87,140,117,249,224,122,159,158,135, 88,233,231,247,118,251,254, +237, 44, 58,142,248,193,237,183, 67,243,247, 96, 69, 12, 31,183,175,217,165,175,171,198,113,140,126,255, 0,187,241,210,210,202, + 77,133,197,207,221,131, 99,202,112, 72, 7,242,117, 92, 15, 35,128, 60,190, 67,250,245, 69, 3, 39,236, 25,209, 40,239,246, 15, +207,219,164,143,175,174, 6, 42,164,124, 64, 14,131,166, 15,207,236,243,242,209, 35,215, 56,198, 62,220,124,191, 62,122,164,143, + 51,208,255, 0, 72,235,253, 31,213,170,160,100,227, 56,233,145,243,252,254,237, 17,175,109,186,223, 3, 4,160,140,231, 62, 93, +207, 79, 77, 22,130, 49,143, 63,233,251, 52, 26, 72, 30, 64,143,179,183,217,162, 1, 74,146, 72, 61, 65,252,115,142,159,159, 93, + 35,140, 48,184,235,108, 20,140, 18, 1,239,158,135,203,239,209,169, 7,166, 14, 79,145,253,186, 1,158,132, 17,149, 14,196, 19, +140,124,243,251,180,122, 72, 79, 76,145,211,160,233,147,164, 9, 36,220,225, 54, 29,199,206,216, 33, 4,224,142,153, 29, 85,219, +183,166,164, 73,236,110,220, 31,173,246,111,125,182,170, 68,175, 13,251,106,189, 68,191,169,177,199,196,183, 33, 84,227, 24, 21, + 2,134,250,229, 41,151, 17, 57, 35, 63,229, 6,117, 29,198,252,179,144,122, 1,230, 79,219,211, 93, 44,246, 85,110,228, 13,175, +226,214,210,164,215,229, 24,246,198,234,192,168,237,157, 95,227,228,108, 75,174, 32, 59,111,188,224, 39, 4, 38,172,195,104, 4, +246,247,157, 70,120,186,135,219,242, 26,232,130,234,146, 37,230, 46,215,221, 14,166,255, 0, 32, 97,247,226,198,240,131,136,227, +225, 95, 18, 56, 87, 54,157,180, 83,123, 64,167,148,237, 97, 29, 72, 48,220,223,107, 43,186, 57,255, 0,166,248,146, 36, 30,101, +188, 76,200, 92,160,148,190,196,228, 14, 82,218,114, 10, 92, 8,242, 87, 93,108,205,136,136, 94, 60,105,208,170, 83, 26,151, 9, +191, 29, 82,222, 74,157, 92,231, 64, 7,195, 90, 79, 64,192,244,244, 26,103, 63,131,149,104,117, 26,148, 68,184,195,109, 83,228, +173,134,209, 44, 2,226,202, 22, 82, 16,178, 79,234,114,242,159,179, 79,213,149, 33,113, 88, 77, 61,112, 27,121,229,248,106,149, + 58, 39, 41,101,148, 19,213, 63, 32, 79, 66, 62,237,115, 51,211,150,121, 6,155,219,175, 91,109,181,133,253,226,219,123,241,235, + 75,241, 11, 79, 76,188,137, 11, 48, 93,149, 89,118, 13,107,151, 89, 1,176, 11,212, 3, 98, 79, 75,219, 27, 67,183,181, 74,244, +214,231, 56,229, 74,158,135, 38, 41, 14, 18,160,166,156, 74, 16,156, 36, 32,118, 65, 62,159,191, 89,190,241,113, 11,110,112,191, +176,215,206,245, 95, 6, 20,202, 61,145, 74, 92,138,101, 45, 18,130,100, 92,247, 68,212,150, 40,116, 70,185,198, 84, 94,156,164, +120,132, 3,202,211,110, 40,118,198,137,219,165, 83,139, 76,133, 80, 28, 90,114,210,212,240,109, 10,241, 74, 15, 76,167,253, 94, +159,126,117,202, 47,164, 21, 92,174, 69,225,135,102, 32,209,169,178,160, 90,181,125,216,152,229,206,180, 71, 8,142,167,224, 81, + 11,148,102, 36,173,177,132,143, 17,201, 42, 66, 85,208,148,156,117, 26,113,203,168, 3, 58,157, 54,103, 33,125,118, 36, 94,196, +237,222,227,213,182,195, 70, 89, 79, 69,197, 92, 91,144,112,245,125, 61,168, 43,234, 1,157,252,177,147, 20, 49, 60,207, 26,149, + 58,245, 75, 28, 77, 18,149, 55, 93, 87, 27,139,227,130,123,191,198,175, 16, 27,247,184, 53, 45,208,191,119, 70,231, 85, 90,163, + 41,199,233,180,154, 61,106,117, 46,133,107,211, 84,247, 52, 26, 77, 22,153, 17,228, 34, 20,118, 27, 40, 72, 87, 47, 57, 41, 37, +106, 42, 36,235,167, 28, 15,251,109,119,107, 98,106,116,123, 7,136,169,179,119,107,102, 31,113,136, 72,172, 74, 90,101,223,214, + 83, 75, 33,180, 78,165,212, 93, 60,213,120,109,143,137,113,159, 82,138,146,217, 13,173, 11,198,163,142,186,235,108,188,164,169, +213,165,121, 56, 0,143,231, 19,148, 16, 58,242,145,159, 46,186, 6,109,204,220, 84,151,229, 73, 75, 76,165, 69, 13,186,181,124, + 13,149,252, 65,167, 20,122, 32, 43,175, 41, 61, 51,208, 28,156, 25, 60, 92, 63, 80, 37, 67, 1, 49, 19,208,129,189,141,182,255, + 0, 21,246,184, 55, 7,184, 56,236,142, 32,151,195,140,255, 0,133,223,133,248,147,134,104, 42, 50, 10, 88,196,113,162,172,112, +123, 24, 69,210,178, 83, 74,129,100,164,145, 7,247,111, 27, 39, 75, 54,164, 44,167,244, 98,220,125,244,218,109,207,181, 44, 93, +211,218,219,134,218,187, 42, 87, 53, 36, 51, 69,220, 10, 51, 17,100, 76, 69,191, 35,149,215, 40, 82,159,113, 5,234, 52,228, 57, +209,198, 86, 27,121,151, 16,161,243, 44, 38,219,240, 59,195,109,247,187, 50,119,219,118,236,200,251,153,118, 75,170, 65,173, 67, +182,174,118,154,153,103,210,171, 16,188, 32,197, 90, 69, 61,192, 77,102, 97, 83, 13, 41, 94, 54, 91, 36,117, 74,129, 58,135, 95, + 6,188,107,223,252, 45,110, 43, 52,233, 52,170,149,203, 96,222, 20,101,215, 83,103, 60,250,190,174,187,227,193, 5,199, 38, 91, +143, 44,148,196,174,178,208,123,149, 72,234,165, 37, 41, 87, 50, 84, 70,166, 95,193, 71, 19,251, 57,196,190,221, 82,183, 35,102, +111, 8,119, 37, 13,224,211, 21,170, 59,206,165,155,154,207,170,129,201, 34,143,114, 82,138,185,226,186,219,193, 72, 75,184,240, +221, 9,202, 85,215, 26,134,231,185, 70,123, 75,158, 38,105, 42,145, 71,202, 88,163,146, 50, 90, 29, 18, 16,197, 88, 92,133,119, +146, 38,219,245,140,108,190,102, 70, 11,198, 92, 75,194, 16,120, 95, 13,105,224,204,246,176, 46,111, 21, 85, 20,213, 74,239, 79, + 89,200,142, 74,121, 30,138,165, 99, 8,209,242, 82,106, 70, 89, 32,229,195, 52, 53, 48, 77, 24, 84,168, 68, 26,105,237, 7,217, + 19, 64,220,153,215, 20, 88,210,156,133, 88,145, 38,124, 79,119,101, 69,163, 18,166,128,243,109, 37, 40, 1, 44,161,169, 41,117, +174,100,245, 74, 25, 74, 0, 3, 3, 90, 51, 69,177,226,173,138, 60,234,204,122, 85, 38,221,129, 41, 51,103,211,161,176, 94,110, + 91,208,250,114, 84,204,148,115, 56,210,150,121,194, 65, 70, 22, 18, 73, 35, 82, 72,226, 42,210,160,110,117,160,197,162,168,115, + 29,188,213, 74,168, 86, 45, 9, 77, 65,126, 76, 10,156,120,126, 17,171,208,229, 78,105, 60,176,167,150, 84,151,226,161,194, 60, +101, 71,113,182,200, 89, 26,226, 82, 54,226, 82, 43,245, 56, 55, 19,146,165, 82,168,173,189, 53,234,122,121,219,167,174, 92, 53, + 21,161,215,162,173,172, 60,148, 33, 24, 82, 73, 88,113, 92,185,201,201, 27,117,108,244,241,194, 26, 80, 4,200,175,177, 5,212, +177, 33,144,129,246, 88,144, 74,234,211,113,184,242,225,135,128,248,146,174,159, 42,143, 44,172,115, 72,249,120, 15, 20,146, 35, + 63, 50,152, 72,218, 26, 20, 93,164,179,172,144,173,201, 8,234, 67,105,179, 12, 29,182,244,136,190,236,139,162, 43,211, 44,218, + 8,144,234,232,245, 56, 11, 17,235, 21,134,156,116,152, 20,134, 80,176,164, 56,209, 72, 43,143,200,135, 22,133,101, 74,113, 57, +214,238,237,187,251,130,203, 76, 67,151, 72,167, 84, 98,133,170, 91,213, 42,148,233, 12, 76,138,192, 82,148,219,210, 68,113,202, +170,138,219,193, 89, 73, 67,106, 72, 42, 40,200,248,181,222,133, 7,252, 38, 61, 94,168,236, 48,218, 34,198,106,222,121,215, 12, + 42, 5,177, 73, 72,109,202,131, 44, 54,165, 4,166,172,236,131,241, 5,128, 23,219,155,149, 1, 39,109, 54,169, 47,214,159,141, + 78, 48, 42, 53, 11, 73,106,126, 99,142,173,244,196,145,119,169,196,182,166,100,201, 84,167, 3,137,162,161,194, 72,100, 6,202, +154, 9, 82,143,134, 60, 50,195, 58,115, 25,121,138, 2, 2, 5,250,155,236, 2,134,216,220, 95,168,238, 13,133,186, 73,115,220, +216,213, 80, 74,207, 75, 13, 76, 72,128,234,144,106, 49, 40, 80,161, 99,149, 74, 52,149, 4,141,198,181, 87,112,116,142, 90,187, +151,130,212,169,221, 85,192, 81, 71,162, 69,143, 17,233,177, 66,234,213,121,210, 29,109,249,104, 83,136, 47,211, 99,197,142,149, + 42, 58, 27, 13,132,100,161, 42, 4, 36, 14,234,214,192, 82,168,207, 6,100, 72,146,243,115, 36,115, 37,223,120, 83, 66, 40,134, +150,151,200,182,225, 67,103,224,109,191, 19,152,143,214, 95, 97,205,166,202,221,175,203,122,100, 42,117, 14, 27, 48, 96, 45,217, +109,187, 93,144,132, 73,164,149, 65, 11,113,200,212, 8,170, 80, 21,149,224, 37, 41,120,242, 70, 10, 10, 9, 83,160, 99, 78, 43, +116,232,146, 18,162,237, 86,169, 54, 43, 79, 52,133, 63, 42,172,182,163, 42, 83,190, 32,120,165,166, 16,210, 27, 75, 65, 69,178, + 18,158, 64,162, 82, 50, 81,157,111, 81, 68, 21,129, 8, 22,227,101,189,237,123,109,114, 1,185,236,109,232, 47,107,226,137,226, +141, 77, 41, 30,203, 30, 87, 20,158, 96,168, 26,121,138, 19,111,172,118,118,179, 18,159,221,137, 20, 88,110,150, 85,193, 53, 73, +145,226,170, 46,101,196, 76,164,184, 28,240, 12,134,153, 95, 43, 10, 74,155, 46,181,207,144,121,194, 7, 62, 9, 82,143, 47,108, +234, 4, 62,210, 58, 72,219,158, 58,184,155,183, 37, 40,183, 29,237,225,189,234, 44, 58, 57,127,200,220,181, 35,117,198, 37, 8, + 56,229,118,159, 89, 74,128,242, 87, 67,131,157, 78,142,170,138, 83,209,158, 69, 30, 52, 6,160, 54,228,136,114, 46, 38, 99, 50, +181,206,146,133,248, 78, 67,166, 72,113, 37, 82, 16,149,149, 37,199,134, 91, 66,242, 26, 11, 88, 90,147, 16,207,164, 3,178,234, +161,113, 5,183,251,173, 73,167,134,104, 59,189, 97,210,168, 85, 9, 52,211,200,236, 43,223,109,162, 38,218,168,185, 41,231, 21, +137, 21, 23,168, 70,202,152,128, 87,226, 56, 92, 95,235,114,171, 51, 28,157, 98,150,190, 8,100,110, 92, 83,221, 79,199, 69,239, +185,177,177, 27, 15,128,189,142, 45, 63,163,127, 17,212,112,127, 20,113, 29, 53, 38,185,106,243,156,177,196, 81, 58,133,230,212, + 82, 85, 83, 84, 44,108,169,172,160, 52,166,171, 97,169,163, 3, 91,114,200, 24,226, 4,154,196,244,219,106,220, 88, 18, 36,123, +230,213,238,117, 58,151,184,116,120,110,184,212,168,118,117, 66, 76, 20,196,186,144,180, 43,157,136,145,234, 12,197, 91,146, 81, +132, 70,114, 83, 75, 43, 75,110,100, 74,151,217,207,198,213, 39,137, 54,238, 61,133,221, 10,180, 42,127, 21,123, 72,167,219,169, +193,146,168,241, 90,223,139, 2, 44,118,170, 52, 45,207,178, 66, 74, 81, 80,184, 88,183,166,211,141,199, 76,103,157,106, 33, 53, +232,129,216,210,102,162, 20, 59,161,215,121,234, 81, 43, 84, 91,170,177,103,222,204, 45,171, 98,241,138,155,114,161, 89, 69, 74, +148,180, 59, 78,143, 92,122,151, 17,151, 83,112, 82,132, 69,184,196,200,129,133, 59, 38, 25,125,133,176,243,141,180,149,244, 87, +132,222, 13,248,140,184, 47,203, 39,113,120,121,171,199,191,238, 93,185, 98, 53,251,111, 91,251, 99, 85,166,215,175, 87, 41,240, + 42,241,155,165,214,182,154, 47,191, 41, 91,145,104,211,234, 42, 83, 92,148,103, 83, 85,163,199,117, 84,250,197, 33,136,225, 97, +185,206,113,194,121,109,101, 27, 45,125, 80,163,171, 2, 95, 99, 38, 41,121,134,115,162, 78, 66,144,133, 38,141,138,205,202, 84, +102,150,120,231,139,150,134, 90,104,163,158, 75,196,249,142,105,226,180,212, 89,118, 93,165,163,138,170,138, 74,220,202, 74,236, +184,209, 80,208,200,239, 65, 46, 97, 87, 27,213, 71, 85, 72,252,182,203, 23, 53,133,225,134, 42, 12,195, 41,170,210,211, 69,154, +203, 85,150,205,166,227,165, 61, 6, 5, 54, 97, 74,156, 18,227, 69,110, 35,140,180,165,169,249, 82,156, 67, 13, 71,138,218, 85, +241,185,226,184,218, 91, 31, 9, 82,214, 50,122,244, 11,114,111, 27,114,131,182,251,199, 34,255, 0,136,154, 45,247,176,245, 58, + 22,218,111, 22,216,181, 81,143, 85,184, 45,221,195,188, 89,183,161, 89, 20, 42,100,159,117, 96, 92,148,187,141,187,194,223,118, +133, 84,102, 59,113,170, 72,126, 72,105, 41,114, 12,164, 55, 75, 99,119,122,224,174, 51,245, 7, 19,219, 89,112,112,215,186,220, + 60,220,144,175, 61,215, 77,193,108, 87,174,237,159,151,101,211,226, 77,189, 33,110,173,151, 93,162, 70,144,154,221,142, 81, 76, +164, 63, 80,165, 60,241,153, 77, 68,215, 72,114,100, 8,147, 31,135,146,113, 71,183, 59,103, 34, 92, 13,253,110,235,173,110,165, +205,184,176,173,202,147,143,193,221, 91, 86, 92, 45,209,191,156,186,104, 59,129,181, 86,205,199,245, 20,121, 48,102,109,181,175, +123,214, 32, 86,104, 82, 40,181, 28,208,209, 13, 52, 53,191, 38,135, 86,101,109,214, 19, 84,229,188, 53, 74,207,159,161,161,167, +175,150, 56, 86,121,140,113,211, 67,100, 55, 51,107,101,157, 73,146, 72,180,145, 11, 42,168,147,153,162,197,146,162,201, 56,112, +210,113,141, 46, 79,196, 20,245, 18, 53, 58,173, 84, 67, 46, 95,106,106,245, 73, 41,170, 2,208,207, 24, 52,245, 80, 86, 80, 37, + 72,165,150,158,114, 90,122,170, 9,135,212,151, 87,227, 20,104, 45, 87, 24, 85, 86,218,241, 42,148, 71,110, 43,170,211, 76,212, + 52,150,132,106,245,151,114, 85,109, 11,162,129, 84,104,168,251,149,106,157,112,209, 42,113,229, 48,188, 58,218,227,142,108, 33, + 77,169, 90, 21,237, 94,168,222, 22,133,223,195,254,202, 10, 93, 82, 93,177,180, 43,183,183,154,236,164, 81, 20,153,146, 98,238, +125,229, 73,129, 91,163,213,175,116, 52,191, 22, 53, 66, 29,188,253,173, 71,167, 81, 57, 76,150,133,213, 81,149, 33, 81,220,148, +211, 74,150,182,225,218, 92, 50,112,247,195,165,153, 77,165, 90,219,117, 99, 91,150, 60, 43,174,244,174,223, 49,109, 27,134,228, +218,202,205,255, 0,107,212,149, 18,116,251,243,114,104,207,201,168, 51,121, 72,220, 7,211, 38,169, 13,184,115,170,215,251,244, +217,244, 88,238, 70,155, 37,169, 49,121, 20,212, 93,185,118,222,225, 46,203,225,223, 98,183, 23,120,253,160,252,116, 84, 55,118, +117,213,191, 91,223, 72,247, 69,219,219,105,184, 23,221, 98, 20,254, 44,230,237,204, 42,236,138,109, 42, 84,217,212,251,153,118, + 17,144, 93, 52,138,101,143, 85,175,174, 58,252, 58,125, 67, 79,254, 28, 54, 93,153,214,174,113, 79, 20,121,133, 44, 97,185,112, + 9,150,105,100, 73, 41, 86, 94, 92, 38, 35, 21,167, 43, 81, 29, 57,169,144, 44, 20,142, 37,170,101,154, 49, 70,106,111,238, 14, +168,151,137,248,115,244,207, 19,210,215,101,116,144,212,140,186,131, 48,134,146, 36,164,139, 59,164,121,107,219, 53,204, 26,181, +229,163,139, 38,160,162,201,235, 36,205,169, 85,235,234,125,154,190, 36,140, 9,162,154, 90, 72,169,213, 45,253,208,118,151, 97, + 90, 91,181, 38, 13,167,103, 94,215,213,102,231,174, 55, 49,215, 31,172,238, 77,247, 17,216,119, 14,228, 45, 49,233,233, 9, 77, + 46, 21, 66, 69,159, 70, 41,134,135, 99,193,140,211, 84,180,200,231,102, 82,155, 18,155, 83,131,120, 85,111,219,154, 3, 50,105, +148,169, 19,160,193,160,214,170,113,194,103,214, 98,211,229,168,183, 62,159, 72, 66,178, 89,147, 84, 14,152,173,252, 45,248, 13, + 54,178, 84,149,147,169,133,123, 64,189,146, 86,255, 0, 13,187,109,182,187,145, 64,219,248,219,185, 14,215,178,234,116, 13,218, +222, 42,148,217, 2, 53, 42,184,204, 22,226,237,117,131, 14,206,132,240,114,194,225,222,157, 83, 53,138,149,106,161, 29, 14, 73, +171, 86, 42,171,153, 89,124,169,230,121, 34,177,182, 91, 65,116,111, 46,243,196,218,253,171,247,251,206,183,116,213,106,146,228, +110, 45, 77,182, 89,136,139,118, 28,148,197,186,119, 9, 54,243, 47, 6,109,107, 54,152,143, 26, 45, 38, 35,139,255, 0, 5,141, + 9, 78,190, 85, 41,232,140,170,115, 83, 86,212,245, 25,140, 21,212, 63,162,231,161,141, 36,125, 43,202,166, 45, 35,172,211, 73, + 10, 63,152,169, 40,176, 6,149,220,186,195,120,162,104,238, 34,191,184, 15, 62,224,252,219,132,178,206, 51,225,190, 45, 60, 75, +193,102,174,190, 55,168,174,180,249,164,116,185,109, 52,249, 86, 93, 75,153, 84,195, 32,246,103,141,107, 43,115,158, 82,101,249, + 74,150,205,227,150,183, 49,167,173,118,253, 35, 52,143, 98,189, 5, 54,159,179,243,109, 77,101, 98, 4,221,196,190,119, 71,112, + 90,102,181, 21, 8,139, 91,164,212,174, 88,182,196, 10,140, 85, 56, 18,219,240,220,254, 9,200, 41,115, 33, 74,231, 82,146,146, +218,155, 42,234,187,209, 27,163,184,237, 90, 72,168, 42,130,200,240,165, 64,143, 38, 82,158,160,173, 74, 13, 9, 84,182,157,124, + 46, 93, 57, 73, 90, 10,152, 73, 43,100,172, 41,160,180,115, 32, 49, 27, 9, 77,177,109, 93,139,217,139, 99,111,227, 72,143,183, +214,214,217,218,118,173,163, 6,173,153, 19, 88,131,108,210, 99,208,101, 65,174,135, 83,148,212,157,159, 79,150,244,181, 20,148, +123,204,229, 43,177, 57,114,208,124, 17, 57,202, 83, 14,170, 36, 5,137, 85, 10, 36,185, 75, 84, 55, 96,202, 71, 42,132,120,171, +113,106,241,219,116,146,219,173, 15, 11,186, 85,148,168,114,194,132,136,200,173, 31,158, 54, 80, 65, 3,168, 34,224,129,232, 65, +213,184,220,116, 23,199, 0,113,150,101, 55, 20,241,127, 20,113, 19,235,165, 25,245,125, 85, 67,198,196,108,179, 84,182,152,185, +133,129, 73,145, 89, 34, 14,220,203, 72, 8,103,229,150, 86,247, 81,110, 91, 49,167, 78,161,215, 37,212,219,113,213,165,218, 85, + 69,240,244, 26,132, 54,129, 11, 49,228,181, 29, 46, 66,168,140,245, 75,156,193,124,161,183, 27, 28,201, 86,190, 81,155,125,104, +135, 34, 12,114,220,121, 41, 40, 98,157, 53,228,170, 35,114, 20,230, 86,221, 26, 80,200,167, 40,169,103,158, 59,169, 8,202,112, +128,131,144, 60,211,163, 71,152,183,230, 83,229,191, 4,133,169,153, 76,134,179, 60,198, 89,109,232, 14,212,225, 62, 86,221, 65, + 13,185,148,165,196,101, 78, 32,243, 37,209,130, 19,153,208,146,134, 81, 41, 19, 11, 49,214, 86, 24,121,165,178,165, 69,168, 40, + 31,135, 1, 64,169, 46,149, 41, 36, 40,254,144, 5, 36,146,188,100, 38,134, 48, 25,152,141,172, 46, 77,136,220, 27,250,141,253, +222,226,122,130,193, 89, 80, 41,169,164,139, 72,146, 84, 43,112,200, 85,236, 84, 40, 87, 84, 1, 94,219, 21,144, 93,244,155, 22, + 69,101,209,125,183,168,209, 97,190,250,204, 70,152, 5, 64,200,140,166,150,203,176, 87,241,151, 94,136,160,178,134,218, 89,230, + 82,128,202,114,162,164,100, 2, 53, 28,111,107, 60, 59,251,143, 63,104, 23, 11,126,205,170, 3, 53,106, 46,201,109,173, 53, 27, +255, 0,189,117,166,249,216,137, 90,147, 49, 18,105,172,202, 66,146,174, 71, 98, 81, 45,102,106, 49, 24, 42,193, 53,155,189,229, +160, 5,197, 73,215,123, 47,141,211, 98,142,167,173,155, 89,193, 42,229, 25,106, 76,148,165, 47, 71,180, 91,112, 5,120,181, 23, + 14, 83, 34,182, 58,174, 44, 18,162,180, 43,149,249, 92,173,165, 40,113,184,160,218,118,243, 51,158,189,219,161, 64, 93,228,170, + 58,109,137, 55, 99,177,210,229,194,253,186,103, 61, 86, 93, 46, 69, 85,196,248,174,194, 85, 90, 68,169, 42, 65, 86, 20,243,235, + 89,234,113,167, 76,190, 73, 36,154, 36, 66, 2,174,204,196,216,168, 96, 86,235, 97,187,142,171,113,179, 0, 79, 96, 43, 78, 39, +200,167,207,168, 64,172,169, 48,195, 60,176,243, 35, 59,153,169,213,129,145, 9,184, 40,178,128, 35,189,201,120,217,238, 72, 33, +152, 74, 45,191,110,218, 20, 10, 5,159,104, 82,163, 80,109, 43, 50,145, 78,182,173,138, 20, 36, 37,152,116,202, 37, 38, 58, 33, + 65,136,219,104, 24, 24, 97,176,165, 43,186,214,165, 45, 89, 82,137,214, 66,192, 44, 56, 50, 64, 66,255, 0, 84,246, 74, 22,174, +188,167,230, 79,109,121, 92,114, 87,226,132,243, 5, 16,162,145,156, 45, 62, 69, 56,238,161,231,246,106,239, 2, 58, 29,109,109, +140, 45, 4,158,231,170, 65, 29, 58, 31, 49,251,181, 41, 93,150,200, 52, 42,216, 5,236,161, 64, 0, 1,233,167,107, 95,107, 15, +118, 6,132,133, 20,133,242, 45,129, 0, 88, 1,181,128, 29, 5,187, 14,150,219,160,198, 15, 92,140,185,115,138, 64, 42, 71,192, + 48, 51,148,245, 42, 81, 7,237,199,237,198,179, 75, 74,130,162,174,110, 64,124, 66, 48,124,213,215,155,149, 64,142,249, 35,240, +215,148, 83, 60, 73,124,161, 36,156,132,103,190,121, 71, 64,125,124,254,243,173,128,177,237,177,134,150,166,134, 7, 42,186,224, +143, 44, 12,121, 14,154, 67,202,160,201,111, 49,218,255, 0, 63,127,239,196,120,213, 0, 90,237,117,185, 55,251,239,238,249,252, + 47,182,197,185,224,181,226,148, 36, 57,202,148, 5,148,228,167,152, 5, 58, 79, 79, 76, 14,157,180,226, 8,126,236,203,104,229, + 60,234, 39, 41, 0,168,144,160, 20,178, 64, 31,173,203,129,242,206,178,138, 93, 27,145,148, 5, 35,225, 35, 39, 61,212, 7,196, + 78, 60,251, 1,143, 61,123,145, 19,153, 69, 69, 4, 41,106, 8, 66, 83,212,227, 32, 37, 32,103,190, 59,159, 85,124,134,144,177, +221,137,249,239,127,225,134,106,140,228, 77, 49,141, 79,213,198,127,211,243, 54,237,139, 84,118, 89,109, 14, 61, 41,212, 70,139, + 13,135, 37,204,148,176, 18,212,104,172, 36,184,227,206, 40,246,108, 37, 56,249,146, 7,158,181,250,179, 86,126,239,172,200,171, +165,165, 49, 78,105, 40,133, 70,101,239,129, 48, 41,109,171,225, 88, 0,126,146, 83,234,203,139, 61, 57, 66,130,124,177,167, 30, +243,170, 10,151, 53,173, 13,126, 37, 62, 51,173,185, 94,117, 25,228,155, 49,165, 7, 24,164,151, 19,254, 82, 35, 74, 8, 47, 36, +116, 83,129, 32,146, 1, 26,196,209, 13,152,192,120,189, 72, 36,248,109,160, 56, 2,128, 5, 63,163, 79, 92,103, 3, 39,160,236, + 58,233, 61, 70,161,194,166,241, 70,119, 63,180,195,227,217,127, 22,248, 41,196,175,135,160, 90, 56,228,204, 39, 66,107,106,150, +209, 41, 6,241,194,108, 75, 91, 99,174, 91, 3,191,217,140, 1,191, 54, 69,192, 76, 50, 27,111, 13, 54, 73, 64, 9, 75,139, 82, +155, 0, 43,169, 44,128, 9, 62, 93, 64,193, 61,206,129,152, 95, 41, 82,138,208, 22, 65, 72, 12,164, 32,165, 0, 36,148,163,152, +144,217,234,147,145,223, 36,228, 96, 13, 93,159, 83,174,103,149, 32, 40,182,126, 55, 51,206,132,145,201,240,161, 7, 35, 62, 99, + 32,129,158,249,214, 55, 45,212, 37, 96, 41, 41,120,167,152, 0,148, 0,129,149,167, 39,148,225, 32,224,247, 61, 71,166,116,224, +158, 91,109,185, 27,219,231,253,127,117,240,237, 35,179,146, 77,153,143,253,199,183,115,176,223,225,139, 75,238,163,147,144, 21, + 40, 96,142,116,142,164,165, 71,170,222, 82,187, 31,136, 4,140,243, 1,229,215, 88,252,183, 65, 72, 11, 82, 74,126, 16, 8, 28, +184, 82, 72, 9, 66, 86,188, 18, 18,124,176, 62,100,224,157, 92, 39, 56,224, 82,146, 23,204,162,174, 95, 9, 9, 79, 55, 83,240, + 40,169, 64,252, 33, 36,252, 92,160,245,192,214, 45, 49,208,142,112, 21,241,171,170, 65, 78, 85,128, 50, 82, 74,129,229, 60,160, +143,187,169,234, 53,176,135,175,112, 15,243, 31,187,175,201,195, 45, 82, 13,247,235,252, 62,255, 0,187,182,253,175,139, 84,247, + 82,160,163,130, 9, 39, 36,167,159,175,196, 10,138, 66,176, 19,215,191,145, 57, 25,215, 6, 61,188, 92, 35, 69,226, 19,132,201, + 91,199,110, 82,195,187,161,195, 10,102, 93,241, 28,140,192,126,125,115,105,170, 47, 48,214,226,219,142,184,128, 86,242, 33, 44, +195,173,196, 64,207, 34,224, 76,242,116,235,186,178,222, 24, 37, 41, 81,237,144, 82,160, 20, 48, 84, 0, 3,162,199, 82, 58,245, + 31,127, 70,250,191, 79,164,215, 96, 84, 40, 85,216,173, 79,160,215, 96, 84, 40, 53,232, 14,182,151, 35,203,161,214, 98, 61, 73, +173, 66,121,165,116,117,135,105,115,166, 54, 71,126, 85,224, 28,246,216, 14,203,105, 35, 63, 89, 25, 12,191, 17, 98, 47,238, 61, + 15,184,145,176, 59,197,243, 92,186, 44,214,138,175, 46,156,218, 42,180, 41,114, 7,145,137, 5, 36,183,172,110, 22, 65,210,229, +109,238,199,229,128, 82, 2,137,239,143, 49,212, 31,152,199,126,154,248,172,145,219,166, 51,147,251,191, 13, 61,188, 74,237, 67, +251, 7,196, 22,245,108,212,198, 21, 21, 91,103,185, 87,117,161, 21,133,168,173, 72,164, 83, 42,242, 5, 1, 65, 71,170,194,232, + 46, 83, 92, 10,235,144,230,114,115,146,198,169,106, 88, 4, 43,155,166, 71, 76,119,245, 30,186,153,211,202,179,197, 12,202,124, +178,168, 97,235, 98, 1,254,120,230,119,142, 72,157,226,149,116, 75, 17, 42,227,209,212,233,101,251,152, 17,138, 46, 16, 70, 51, +235,156, 28, 99,251,116, 42,177,142,195,148,103, 30,125,187,147,243,213,117,168, 30,224, 12,142,248,206, 79,217,161, 87,208, 31, + 60,156,126,255, 0,221,173,192, 44, 0,244,192, 29,190, 56, 29, 89,193,233,255, 0, 14,253, 52, 34,142,113,223,207,184, 3,240, +209,107,237,223, 29, 71,231,243,233,161,156, 32, 2, 51,147,231,142,191, 62,154, 85, 7,124, 42, 44,119,192,171, 35,203, 63,126, +113,231,228,117, 69,125,179,147,255, 0, 31, 93, 87, 95, 55,158, 49,229,249,245,208,235,199,207, 62, 94,159,126,149, 2,228, 99, + 29, 0, 3,231,255, 0, 24, 21,103,175,216, 49,159, 93, 45, 37,254,183,221,211, 75, 74,139,128, 0, 31,142, 13,143,168,198, 79, +124,227,238,199, 79,219,162,145,140,118,235,230,113,251,254,205, 8,223, 83,147,145,208,244,251,241,215, 69, 35,177,235,231,219, +247,232,141,107, 47,108, 12, 18,142,199,167,223,235,249,253,250,169,158,221,250,124,254,126, 94,154,164,140,245,233,211,215,247, +124,245,237, 36, 40,144, 15, 99,131,223,161,210, 78, 54,248, 96, 99,223,140,142,249, 24, 0,103, 25,202, 78,139,108,149,129,212, + 0,124,241,215,168,233,211,239,253,154, 16,180, 1, 56, 0, 36,228,159, 79, 44,147,243,254,189, 86,109, 65, 36, 14,184,198, 2, +143,203,212,253,218, 64,155,117,192,193,237, 39,151, 3,175, 66,123,119, 63, 63,144,209, 8, 95, 51,137, 73, 78, 57,115,241, 30, +221, 60,178,126,122, 8, 60,140,148,130, 85,216,224,117, 87,159,124,253,167,240,209, 63, 11,137,248,186, 28,252, 35,168,207,219, +248,233, 22,234,113,131,235,243,233,139,187, 64, 43,162,136, 63, 49,147,235,233,247,106,247, 70,169,212,104, 85, 90,117,110,145, + 41,200, 53, 90, 68,248,117, 58, 92,198,148, 80,236, 90,141, 62, 75, 82,225, 74,109, 67,170, 84,137, 44,180,175,184,141, 88,152, + 10,229, 79, 96, 48, 57,177,219, 35,167, 79,219,162,211,156, 40,118, 30, 71,184,249,245,242,233,162,144, 24, 21, 97,112,118, 32, +239,132, 15,196,169, 30,155, 16, 71,112, 71, 67,137,193,240,233,185, 20, 62, 44,120,124,219, 61,240,167, 76, 71,191, 84,105,140, + 81, 55, 14,155, 5, 64, 73,165,223,148, 54,155,135, 89,139, 53, 8, 57,103,197,121,191, 25, 25,253,100, 72, 65, 4,131,173,161, +180,210,245, 40,183, 10, 44, 52,248, 14,171,153,247, 36, 40,150,208,211,100, 16,181,171,201, 93, 7, 79, 83,168,161,123, 40,248, +226,137,194,214,237,191, 97,110, 76,199, 6,196,111, 20,202,117, 42,239,113,106, 82,155,179,174, 82, 83, 18,135,123,178,146,127, + 69, 25, 42,113, 12, 78,199,254, 43,149,211,158, 67,169,140, 46,220,104,182,207,128,184,210,104, 79,178,197, 70,159, 80,128,226, + 36, 70,171, 65,146,132,189, 18, 92,121, 77,168,165,248,174, 52,182,212, 10, 73, 7,155, 84, 39, 16,240,233,203,115, 25, 99, 88, +201,130, 67,170, 35,216,169, 61, 47,220,173,244,155,247,243, 17,102, 24,239,143, 11, 60, 80,110, 39,225,218, 88,107,103, 15,152, +229,170,144,213, 33, 98, 60,234, 0, 89,236, 55, 34,117, 93, 98,219,115, 3,198, 8,209,135, 82,196,175,212,218,113,133,198, 84, +117, 38, 71, 32, 67, 78,101, 4,182,142,157, 7,255, 0, 22,125,124,255, 0, 13,121,226,147, 97,169,220,100,236, 45,251,195,253, +214, 96, 83, 89,184, 96, 55, 58,221,184,156, 71,138, 45,139,210,151,207, 34,220,169,161, 93,196,113, 36,248, 82,113,221,137, 11, +244,198,172,116, 62,102,100,181, 29,160, 61,231,149, 60,142, 99,224,101,164,246, 3, 29,128, 25,233,173,128,164, 74, 18, 99,198, + 73,116,183, 25,181,114, 60,178, 57, 76,151, 16, 50,162,162, 14,124, 60,129,246,235, 82,158, 2,165,118,210,203, 98, 45,216,245, +190,219, 94,253, 7,223,139, 66,108,214,122, 57,232,179, 76,177, 18,150,182,141,214,104,102,243, 49, 73, 35, 33,209,244,220,171, +217,133,180,176,210,230,225,188,151,199,230,211,196, 86,208,238, 55, 15,155,153,121,237, 22,231, 81,100,219,215,221,143, 82,149, + 79,168, 71,125,106,110, 52,230, 88, 90,132,122,157, 46,106,128, 76,202,124,136,220,143, 71,121, 63, 11,141,186,146, 8, 36,141, +107, 90,238,137,210, 99,242, 84,194, 39,208,228,243, 69,156,165,101, 50, 16,209, 35,156,184, 17,212, 56,158,138, 66,198, 72,229, + 26,253, 19,125,160,126,206, 29,169,246,133, 88,112,226,214,219,129,100,111, 5,191, 18, 68, 91, 19,116,219,132, 28,148,220, 38, +208,181, 53, 65,186, 99,180, 66,170,182,233,119, 30, 25, 39,198,138, 86,165, 50,121, 74,144, 97, 29,196,223,179,219,138,238, 14, +171, 85, 42, 30,238,109, 69,202,253,158,137,146, 26,165, 95,150,229, 61,202,229,149, 91,134,219,133, 41,155, 18,173, 13,165, 6, + 91, 82, 48,172, 57,202,180,231, 5, 26,179,178, 42,250, 57,225, 72,106,149, 86,169, 74,233, 44,116,220, 29,175, 27,118,123,216, +133,216,130, 59,142,146,250,158, 42,173,226,215, 74,204,190,189,178,218,167,133,214,182,141,111, 32, 18,142,242, 68,219, 84,208, +202,162, 69,119,250,199, 68, 58, 38, 17,181,158, 86, 98,205, 98,245,184,155,179,246,190,133,117, 81, 43,212, 69,205, 93,107,111, +171,201,247,180,220, 22,125, 75,170,221,143, 77,172, 67, 70, 41, 51,212, 66,147,225, 62,180,195,146,121,152,117, 41, 82,145,153, + 39,123, 14, 56,116,186,118,163,136, 57,119,139, 91,231,181, 82,105,117, 56,211, 85,187, 59, 81, 50,174,154, 46,225, 86, 41,142, +178,236, 71, 96, 81, 44, 39,154, 15, 79,169,138,138,154,146,169,140,169,198,154,240,202,146,121, 8,214,156,123, 19,246,162,147, +184,219,245,181,214,173, 74,157,114, 91,212, 68, 94,177, 46, 9, 87,209,164, 82, 35,166,152,213, 40, 26,147,148,152, 53,249, 12, +182,135,161, 77, 92,118,163,188,212,150,221, 87, 43,171, 72, 10, 95, 41,212,194,248,217,224, 59, 96,239,203,211,110,184,157,163, +220,219,119,195,142,224,236,189, 90, 53,199,112,238,141,180,213, 54,131, 86,184,173, 90, 80,241,158,162,204,105,137, 44, 68,247, +146,216,120, 38, 83,136, 82,185, 95, 91,106, 14, 36,132,105, 42,177, 85, 95, 69,196, 84,180,235, 13, 45, 13, 59, 8,229, 63, 84, +100,153,228, 44,254,209,101,229, 8,180, 29, 45, 34, 57,120,102, 98,238, 84, 54,248,177,115, 46, 32,224,110, 24,171,225,142, 26, +226,122,217,198,119,199, 25, 21, 76,116,245,242, 71, 93, 93, 67,144, 67, 83, 72,217,122,208,154, 38,146,170, 74,254,122,137, 97, +203,171, 80,123,126, 86, 13, 50,114,230,134, 52, 43,104,160,110, 52,106,229, 82,239,218, 10,165,197, 42,143, 92,155,112, 63, 79, +182,109,170,172, 86, 42, 53, 42,212, 72,110,166, 83, 17, 83, 38, 18,137,166,133, 50,164,172, 60, 85,240,145,228,123, 92,248,153, +225, 90,117,139, 14,223,186,217,144,212,184,247, 13, 37,217,245,234, 50, 30, 68,154,188, 47,118, 5,245,153, 13, 36, 5, 84,225, +248, 64, 45,114, 16,133, 4,120, 5,183,210,145,135, 23,170, 17,120,166,246,122,210,239, 8,251,245, 73,221, 42,108,202,125, 54, + 85,110, 12,136,116, 25,110, 42,164,252,181,186,183, 36, 84,100, 71,157,200,243,176,212,251, 97, 40,154,128, 27, 80, 87, 42, 0, + 73,215, 28,248,248,246,138,238,223, 31, 27,209,100, 13,189,190,175, 61,174,217, 13,133,184,168,247,110,220, 46,215,168, 72,182, + 43, 50,175, 26, 23,136,134,174, 58,133, 66, 41, 14,213, 96, 61,144,143,113,148, 85, 17,198,121,155,117,149,165, 68, 30, 78,240, +151, 41,171,203,168,248,214,139,140,242,218,147, 61, 39, 46,146,154,176, 74, 94, 58,115, 70,238,237,110,102,210,194,237, 49, 74, +101,167,176,152,106,242, 71,253,233, 17,120, 7,226,111,137,188, 85,195,180,126, 29,112,252,188, 55,150, 71, 72,245, 89,147,103, +144, 54, 91, 11,230, 13, 18, 65,236,212,236,144, 84, 78,202,220,184,170, 37,144,199, 57,137, 21,156, 76,199,149, 3,245, 94,101, +153, 14, 91, 11,118,106, 60, 38, 42, 50, 98,248, 52,232,255, 0,224, 76,210,169,176,210, 23, 58, 67, 75, 75,170,196,215, 65, 90, + 66,200, 82,134, 70, 57,121,122,190,116, 74, 93, 58,224,113, 52,104,137,117, 22,180, 38, 41,236, 84,166,201,117,250,127,189,196, +138,202,165, 63, 77,135, 61,213, 5, 70,128,166,194, 12,199, 18,144,165,140,160, 16,130,179,166,155,101, 55,170,133,187,214,166, +214,220, 55, 67, 20, 74, 22,231,223,150, 76, 91,182, 85,181, 1,133, 66,160,215,231,197,159, 82,164,204,170, 90, 80,221, 39,244, + 42,118,154,185, 47,211,155, 89,114, 42,164,175,221,144,228, 84, 39,195,216, 74,124, 72,107, 67,204, 60,133,205, 66,221, 76,153, +140,248,200,105, 21,106,162,212,144,195,107,125, 39,244,116,228, 20,254,149, 32,124, 73, 74, 16, 82,160,149, 5, 73,200, 40,225, + 8, 33,133,138,157,182, 82, 3, 95, 73,181,137,216,116,212, 13,238,110, 49, 90,230,167, 55,225,188,207, 50,225,188,237,100,164, +205,114, 10,186,138,102, 10, 67, 66,181, 20,181, 15, 75, 52,145, 56, 33,102, 11, 36, 14,177,206, 9, 14, 84, 59, 29,188,174, 84, + 59,173,112, 93,143, 85,131, 21,160,229,114, 44, 58, 45,153, 66, 12, 7, 27,139, 74, 91,136,101,170,139,205, 35,148, 83,216, 89, +109, 47,175,160, 45,198, 97,150, 17,149, 40,129,153,191, 33,138, 45, 46, 76, 10,157, 73, 53,234,220,249, 45, 83,233,211, 28,109, + 44, 82,226, 34,114,131, 18, 43, 40,129, 31,153, 48, 97, 70, 47, 36,186,181,120,174, 58,242, 82,209, 95, 50,212, 18,208, 73, 83, + 80, 80,204,199,127,194, 85, 21,242, 79,187, 56,168,170,169,212,221,108, 50, 91,138,234,193,240,227,178,130, 24,101, 57,229,108, + 41, 75, 86, 74, 20, 9,139,172, 74,165, 58,245,126,172,220, 89,142, 26,131,177,226,196,130, 86,202, 30,125,154,122,189,198,155, + 17,167, 0, 8,166,198,149,239, 78, 60,238, 79,139,135, 31, 80, 75,139, 70,183,210, 72,208, 37,152, 14,131,107,157,246,216,129, +183, 77,134,221,141,183, 54,195, 12,185,100, 85,145,194,212,139,125, 68,121, 69,150, 73, 36, 70, 28,168,213,141,221, 80, 38,242, +239,121, 25,155,153,118, 55,137,194,174, 84, 41,148, 85,183, 64,162,120, 21, 9, 84,184, 49,145, 29, 46, 45, 79, 64,165, 64,110, + 50,132,154,165, 69,214,148, 82,194,220, 74,138,147, 28,101,231,150,232,192, 66, 9, 86,185, 17,237, 36,216, 24,156, 79,108, 45, + 91,106,157,145, 17,119,146,170, 52,251,163,110,235,115,214,150, 35,192,191,179, 38, 60, 55, 42, 47,160, 19, 2,219,168,211, 29, +118,157, 56,164, 20, 50,202,227,203, 3,158, 10, 73,232,220,233,143,193,167,180,203, 82, 67,210, 37,192,145, 88,170, 20, 52,150, +230, 54,253, 90,120,113, 41,119,149, 69, 38,115,235, 1, 12,182, 7,193, 25, 9, 82,185,130, 82,117,175,119,139, 85,218,217,157, +245,121, 66, 42,143,213, 32,176,154,170,185, 28,143, 69, 75, 2,115,178,106, 74,141,250,175, 22, 25,108,248, 12, 35, 8, 91,142, + 54,181,252, 5,122, 88,213,203, 28,145, 75, 78,229, 37,167, 97, 34,183,236,148, 33,148,223, 96, 69,197,183,176, 63,102,214,216, + 58,240,190, 68,114,250,243,152, 23, 19,199, 8,114,242, 72, 72,231, 22,188,108,205,176,101,137,213,157,138,160, 37,149,131,121, +245, 2, 96,171,183, 20,137,123, 31,191,149, 91, 47,123,232, 85, 27, 62, 93, 6,181, 34,220,190,237,155,214,132,186,220, 88,179, +217,150,220, 71,128,149, 75,125,138,149,169, 90, 75,203, 96,211,110, 42, 91,143,176,165,184,194,229,195,126, 59,201,121, 83,127, +216,175,102,198,192,241,189,192, 78,211, 93,151,173, 66,131, 11,121,110, 27,122,109, 78,202,226,103,134,152,244,170, 29,255, 0, +106, 75, 77, 80,127, 7,147,118,200,183,170, 81,169, 27,137,124, 65,102, 20, 38,171, 53, 4, 24,110,205,241, 18,226,164,123,227, + 13,202,211, 37,186,124, 33,108, 79, 16, 66,211,103,113,182,182,139,118, 84,173, 7,156,166,216,183, 99,192, 67,187, 32,202, 95, + 52,202,236,231,238, 88,201, 46,213,173,214,193, 83,203,133, 49, 50, 99,173,245,243, 52,203, 11,115,159, 93, 2,225, 42,126,233, +240,185,105, 84,108, 74, 45, 95,108, 43, 59, 35, 69, 97,250,141, 10,138,230,217, 90,251, 48,139, 9,233, 47,173, 83,167, 92, 23, +133,177, 85, 69, 46,182,212,244, 48,183, 86,228,216,112,223, 43,138, 95,241, 29,230,228, 19,170, 78, 41,201,115, 12,218,154,183, + 54,203,228, 66,244,207, 79, 57, 83,174, 48,118,211, 36,113,139, 51,236,182,144,200,197,209, 89, 4, 74, 66, 18,100,220, 71,196, + 25,253, 47,135,176,101, 60, 41,197, 99, 32,207,114, 92,228,102, 52,138,194,116,168,154, 25, 34,146, 41,169,214,165, 68,180,176, +199, 36,210, 6,122, 3, 28, 20,213, 45, 28,143, 83, 37, 84,238, 34,143, 74,120, 89,225,111,121,247,111,121,238, 89,155,225,184, +220, 82,237,142,251,112,146,253, 17,207,229,239, 14,200,188, 40,150,199, 16, 91, 53,100,203,106,223,161,219, 59,177,105,238, 28, + 8,141,191,184, 84,122,123,188,237, 86, 66, 93,102,187, 65,135, 61,155,146,157, 54, 68,117, 85,170, 29, 5,246,132,237, 76,171, + 94,215,181, 54,235,103,182,227, 99,237,219, 50,147,100,221,151,117,186,253, 38,155, 38,143,114, 90, 87, 4,106,212, 53,220,242, +118,242,194,180,160,179, 75,166, 81, 39, 84,235,112, 68,217,140, 61,226, 50,212,247, 22, 89,118, 35, 77,235, 83,184,202,246,199, +112,111, 70,219,122,181, 6,171,108, 65,226,231,125,105,213,122,204, 75, 11,108,236, 27,130,252,141,176,118,155, 98, 2, 33,193, +175,238,213,251, 13, 81, 98,223, 52,197,206, 75,206,187, 71,165, 38,170,196,168,241,155,138, 85, 9,111, 46, 98, 52, 47,111,189, +188,183, 37,209,109, 10,103, 17, 22, 2,110,109,194,146,227,138,131,118,219,246,163,116, 11, 98,132,235,103, 52,122, 75,118,253, +157, 38, 77, 80, 90, 17,210,101,178,248,116,206,118, 75, 83,212, 28,101,175, 1,149,162, 45,226,190, 70,185,231, 0,203,149,228, +121,123,231,153,198,105, 91, 28,230, 88, 16, 36,112,211, 70,154,212, 24, 39,149,165, 18, 74,198, 72, 89, 35,105,100, 12, 41,231, +158,112, 57,145,137,231, 10,100, 94, 51,241, 87, 23,112,111, 30,211,112, 52,153, 38, 73,225,242, 10, 90,124,155, 50,146, 42,116, + 99, 45, 52,112,243,178,218,153, 12, 21, 85, 52,171, 42,205, 88,212,181,201, 75,149,209, 37, 91, 81,100,148, 51, 81, 75, 49, 50, + 6,217,173,183,155,188, 84,118,173,158, 32,172,235, 87,118, 54,166,179,183,149,203,134,222,225,242, 30,215, 80,233, 54,151,241, +165,100,213,106,245,122,156,138,221,227, 2,160,150, 46, 42,164,235,130,161, 57, 86,251,132, 51, 77,169, 64,173,174,167, 38, 59, + 85, 4, 56, 26, 3,109,118,123,135, 41,252, 96,110,135, 23,245,109,254,221,189,165,168,219,173, 91,123, 97, 87,216,251,190,175, +183,219, 85, 99,219,212,155,126,209,183,217,137,183, 10,131, 66,169, 76,169,205,176,225, 70,165,194, 83,180,116,125, 88,219,175, +148,178,243,175,199, 75,173, 59, 29, 61,249,246,206,238, 94,228,237, 61,211,181,155,117, 97, 50,205, 62,247,110,151, 14,183,114, + 57, 71,149,102, 55,111,211, 40,145,161,125, 74,213, 25, 54,141,222,227,180,202,188,130,169, 82, 23, 30,151, 57,136, 16,218, 83, +108, 72, 50, 38, 25, 64,114, 67,110, 47,253,229,176,174, 10,205,199,103,238,253,237, 99, 85,238,119,154,122,231,157, 75,174,215, + 74,238, 7, 25, 46,152,207,214,220,157, 58, 73,170, 74,109, 18, 30, 75,110,190, 29,121,180, 44,165, 42, 9,232, 21,240,162,151, + 56,225, 46, 16,143, 36,205,178, 88,214,186,130,176,206,181, 50,212,206, 37,168,141, 97,228, 37, 63, 46, 9,201, 90, 37, 96,103, +142, 25,155, 74,243, 26,157, 97,150, 33,237, 83,203,114,127,162,199,141,220, 86,188, 75, 85,151,241,125, 31, 2,167, 23,193, 83, +150, 54, 91, 79, 78,166,152,101, 85,109, 75, 81, 85, 61, 59, 60, 98,150,158,166,174,122, 58, 72, 42,106,150,136,102, 51,123, 10, + 85,205,152, 73, 43, 44, 16,206,123,218, 61,196,127, 12, 59,235,177, 53, 46, 29,169, 86,189, 55,136,234,109,215, 88,166, 26,197, + 38, 53,233,116,109,198,223, 91,198,222, 80,171,209,234,119, 5,221, 67,164, 25,151, 10, 5, 85,136, 33,154, 93, 49, 37, 18, 15, +233,100,202, 97,150,139,131,132,251, 87,179,251, 79,179,194,224,147,101,216,244,202, 5, 90,229,159, 17,119,149,211, 72,110, 69, + 46,248,110,163, 29,217, 43,129, 66,171, 79,122,116,167, 35, 90, 76, 72,147, 37,216,236, 37,215, 98,203,117,126,245, 45, 50,100, +114,186,222,133,219, 60, 77,113, 16,220,102, 29,123,136, 11,214,170, 86,194,217,230,148,229, 46, 98, 20,211,128,115, 50,125,254, +146,190,100,228,116,200, 4, 30,163, 7,187,151, 72,226,234,249,165, 72,105,119,173, 54,145,119,199, 91,105,138, 42,209,169,240, +173,203,214, 44,100,188,211,178, 16,205,110,152,208,135,112, 48,176,215,197, 10,171, 13,109,124, 69,109,200, 97, 95, 24,214,226, +126, 46,204,248,131, 53,169,253, 34,207, 26, 53,144, 71, 4, 79, 21, 56, 17,133, 22,229,150,231, 57, 26, 1, 47, 34,187, 2, 44, + 52,198,170,139, 50,202,126,130,126, 47,120,111,192,109,194,252, 57,154,229,220, 65,148, 9,205,116,180,137,154,214, 10,186,170, +162, 10,137,109, 91, 69, 71,150,198,235, 25, 10, 22, 25,169,163,100, 69,105,125,166,116, 70,126,237,240,173,188,242,233, 18,100, +237, 93,235, 42, 60,202,109,114, 92,138,190,220,221,209,196,104,148,181, 76, 74, 16,170,157,149, 92,105,110,132,210, 43,242, 74, + 19, 42,158,164,115,198,158,234, 36, 48,143, 6, 66,144,210,247,177, 85,202,124, 85, 41, 50, 23,238,234, 96,171,220, 84,131,201, + 81,167,186,242, 66,220,103,194,112,116,136,167, 49,204,218,135, 38,114,149, 36,142, 82,142, 24,109,205,249,100,111,109,188,154, +141,169, 87,121,132, 69,149, 25,154,133, 12, 70,102, 35,244,170,162,202,228,211,227,215,160,171,156, 70, 90,220,109,197,198,112, + 60, 25,150,134, 86, 98, 60,242,193, 74, 54, 70, 21,203,185,137, 49, 41,209, 55, 38,242,181,228,211, 26, 17,157,129, 46,114, 42, +180,121, 76,135,128,240,207,214,112,156,148,134, 86, 18, 75, 79, 49, 33, 50,163,165,120,248,146, 57, 73,105,106,159,147, 26, 7, + 37, 20,121, 74,249,129, 29,199, 81,176, 38,192,147,176,176, 11,229, 39, 28,113,196, 92, 57, 81,148,103, 21,249,110,121, 69, 46, + 69,155, 81,200,201, 87, 73, 60,114, 67, 44, 19, 46,155,235,139, 65,117, 46,165, 73, 11, 30,131,175, 80,250,185, 64,199, 74,170, +247,117,187,111, 83,215, 94,171,203,137, 65,135, 79, 67,143,174,161,207, 41, 13, 62,140, 15, 16, 83, 24,105,167, 37, 84, 28, 81, + 82,130,227, 69,105,245, 45, 71, 41, 66,191, 91, 76,133, 87,124,171,187,130, 29,167,217, 76,213,237,251,106, 66,189,205,119,162, + 28, 98, 37,199, 86,142, 16,162,185, 54,235, 12, 41,106,181,161,242, 45, 99,199,119,154,162, 48, 80, 81, 16,158,154,182,205, 62, +117, 86,178,221, 66,238,151, 81,166,214,156, 82,227, 66,168, 73,171, 77,171,198,152, 82,188,180,236, 27,145,222, 95,115, 36,148, +242, 70, 81,136,160, 29, 56, 67,138, 29, 54, 42,202,179,153,139, 37,154,143, 44,138, 93, 90,115, 13,179, 42, 84, 55, 84,228, 58, +130,154, 32,177, 34,167, 76,116,248, 83,164,158, 85, 21, 58, 66, 29,194,202, 84,242,134, 53,191, 74, 37,168,148, 34, 92,139,239, +126,187,219,125,133,150,228,146, 47, 98, 55,179, 1,136, 86,103, 62, 91, 69, 8, 36,153,106, 8, 60,182,111, 58, 40,216,157, 54, + 98, 36, 0,234,243,171, 58, 3,101,229,106,179, 43,139,104, 91, 70, 44,120,176,217, 45, 59, 21,146,164, 50,232, 71, 43,133,111, +117, 90,230,100,144,252,149, 40,149, 41,210, 74,150,181, 21, 44,149,171, 39, 97,160,209,196, 74, 98,138,211,204, 1,101, 39, 41, +232,160, 84, 80, 91, 86,122, 5,117,207,217,171, 93,167, 74,230,109,190,118,227,151, 50, 18, 67, 73, 80,101,207,212, 10, 45,182, +190,169, 65, 32, 16, 14, 72, 61, 50,113,157, 59,206,211,128,167,184,215,134, 84,218,139, 67, 9,202,136, 9, 81,207,134, 79,235, + 28, 17,243,252,113,169,165, 53, 56,166, 68,176, 35, 72, 23,245, 29, 5,183,191, 78,155,254, 24,174,234,171, 13, 76,138,146,157, +228,111, 49,216, 94,228,111,219,173,201, 22,181,250,250,130,207, 61, 76, 83, 78,129,201,136,206, 30,102,214, 63,241, 74, 61,219, + 81,242, 79, 81,141, 92, 33, 83, 11, 11, 43, 74, 70, 79,235,128, 48,146,159, 95,183, 89,187, 48, 16,248,113,190, 78,100,130, 82, +160,176, 65, 32, 28, 5, 99,215,168,252, 53, 65,216,162, 34,146,199,235, 39, 31, 2,200,193,233,215,144,231, 79, 81,206,164,117, +233,252,125,253,240,213, 89,206, 82,241,176,243, 14,190,132,117, 7,227,110,189,143, 94,183,197,134,155, 9, 14, 77, 73, 35,160, +115, 31,105,236,123,140,118,214,207,217,208, 91, 67, 45, 2, 19,212, 36, 12, 14,163,212,156,142,135,247,233,135,163, 69, 10,155, +158, 95,135,196,200, 0,103, 57,200,252,115,173,138,183, 84,150, 18,214, 79, 47, 42, 82, 64,200,200,192, 25, 63, 34, 51,173,102, +107,129,181,255, 0,158, 33, 53,234,201, 4,224,108,194,246,251,207,207,175,124, 57,232,109,180, 51,202, 72,248,130,113,142,248, + 78, 0, 31, 35,235,246,233,191,188, 42,206, 66,108,193,167,132,253,103, 41,181, 0, 71,255, 0, 2,140,174,134, 73, 35,245, 92, + 39, 33, 30,121,235,229,171,141, 90,228,106, 11, 32, 52, 80,236,183, 73, 12, 70, 4,229, 74, 7, 30, 43,152, 63, 3, 41, 29, 84, +123, 28,224,100,235, 5, 13,173,197, 57, 46, 67,138,125,249, 46,120,146, 95, 88,253,117,156, 97, 40, 39,245, 91, 0,225, 35,176, + 29,180,142,179, 80,220,168,205,149,126,211, 15,223,164, 16,122,250,158,195,208,145,134,108,155, 45,116,149,107,106,210,241, 41, +186,161,255, 0,120,194,221, 71,236, 47,127,218, 35, 79, 77, 86,176, 66,163, 8,205,225,197, 43, 56, 37,105, 65, 56, 36,252, 75, + 82,212,174,171,112,149, 28,156,245,207, 93, 15, 45,216,241, 57,146, 57, 27, 56,200, 72,192, 89, 78, 15, 85,168,159,128, 99, 39, +226, 63, 33,223, 89, 20,167,114,130, 10,130, 80, 72,248, 26, 31, 30, 65, 0, 16,165, 3,208,231,174, 61, 61, 53,129,212,188, 52, + 7, 20, 82,214, 78, 74,148,226,186,164,228, 18, 84,181,103, 36,244,238,122, 30,157, 53,185, 26, 44,106,170,160, 1,238,236, 54, +253,214,249,247,206,169,100,122,153, 25,234, 36,251, 71,160,233,212,122,216,124,236,119,197,146,116,196, 43,156, 23, 20,234,176, + 66, 83, 24, 44, 50, 18, 79, 66,235,132,167,159, 61, 50, 50, 18, 9,206, 15, 83,172, 58,116,165, 37, 64, 4,182,218, 73,199, 59, +139, 10, 82, 73, 66,186, 33, 13, 30, 94, 96,174,108,228,231,168,198,123,139,140,202,131, 79, 30, 70,148,227,238, 33, 74, 65,102, + 43, 97,196, 54,147,211,226, 81, 41, 74,129, 0,103,226, 56,236, 70, 51,172, 78,114,228,243, 5, 43,193,100,115,243, 36,120,134, + 75,201,194,128, 42, 71, 54, 17,204, 60,206, 74,114,122, 18,116,112,214,210, 59,223,241,219,240,190,226,251,116,251,158,201,176, + 10, 23, 73, 61,143, 95,141,182, 61, 58, 16,167,226,118,197, 23,220, 24, 42, 82,202,147,250, 50,234,130,146,217, 45, 36,168,133, + 45, 94, 71,175,197,215,174, 49,223,174,177,233, 50,208, 66,131,105, 61,214, 66, 64, 78,114, 64, 32,244, 61, 27, 42, 36,100, 30, + 80, 0, 29,250,232,185,104, 66, 49, 33,199, 21,150,220, 43, 66,158, 90,158, 9, 94, 72,229, 74, 84,180,165, 36,173, 63,234,146, +156,146, 6,173,114, 20, 80,180,165, 72, 80,112, 20,145,206,164, 41, 92,139, 1, 96,182,144,172, 56,130, 20, 14, 50, 0, 39, 56, +233,141, 46,141, 98, 54,244,254, 95, 29,247,198,133, 76, 90,206,166, 58,175,233,178,237, 97,238,254, 93,189,215,178,204, 42, 33, + 93, 64, 42,248,136, 81, 57,235,147,209, 95,205, 61, 51,156,117,229,239,140,107, 16,158, 7, 42,147,206, 74,138, 85,241,171,148, + 17,140, 96,145,216, 96, 12,125,253, 6,178,233, 89, 1, 42, 89, 0,224,140, 40, 16,146,179,204,164, 55,201,216, 60,158,153, 29, +114, 59,100,118,197,106, 10,207, 40, 35,170, 73,230, 36,114,149,103,155,161, 9, 87, 86,241,147,231,213, 88,193, 58, 92, 49,218, +223,135,110,159,187,221,238,253,216,103,145, 0, 34,219,123,186,124,143,147,136, 13,251,114,237,134,237,143,105, 46,242, 73, 13, + 22,133,233,109,109,125,248,227,197, 1, 40,126, 69,118,199,166,197,148,182,249, 0,241, 0,122,146,174,101, 31,136,168,158, 98, + 78,117,200,194,180,168,126,137,101, 88,239,233,246,107,183,127, 72, 24,180,175,104, 99,158, 27,161,215, 19,195,254,205, 37,246, +129,255, 0, 34,180,195,184,124, 52,148, 17,150,202,152, 45,175,169,201, 11, 7, 0, 99, 92, 70, 83,105,199, 81,140,246,229,242, +249, 29, 75,178,155,181, 13, 41, 59,217,109,211,176, 36,116,235,219,242,199, 51,241, 50, 44,124, 69,158, 34,159, 47,181,212, 31, +255, 0,116,172,199,247, 18,113, 76,168, 40,116, 72, 29, 62, 47, 63,188,117,208,235, 35, 24,207, 92,244,254,221, 86, 40, 35, 62, +152,207, 95,232,251,116, 51,133, 67,168, 78, 71, 81,243,251,244,236, 6,194,221, 48,206,160, 29,173,211,161,253,216,162,179,229, +143,191,211,175,217,170, 11, 0,227,176,245,245,199,175,207,160, 58,244,188,254,177,201, 82,124,188,177,231,246, 29, 81, 39, 39, + 58, 93, 70,194,221, 63,158, 20, 24,164,230, 60,136,232, 72,244, 39,183,109, 12,178, 9, 61,242, 59,122, 30,223,214,116, 74,241, +130, 73, 3, 7,167,246,245,213,189,240,234,136,240,212,148, 97, 95, 22, 70, 74,128,236, 58,249,233, 68,235,140, 3,126,155,227, +193, 36,156,254,113,165,175, 10, 63,237, 99,238,206,116,180,125, 62,182,191,207,191, 25,199,180,146, 15, 65,159,151,174,171,165, + 93,142, 58,142,227, 61, 70,135, 31,120,254,145,251,117, 92, 96,245, 30,127, 46,250, 37,188,191, 15,195,231,231,124, 12, 86,241, + 19,156,117,235,231,142,159,126,136,111, 10,193, 74,187, 28, 99, 24,201, 62,191,136,252, 53, 65, 9, 0,131,220,244,251, 58,232, +164,225, 61,178, 7, 94,221,254,236,246,210, 76, 24,139,124,252,223, 25,219,239,197, 69,160,168,119,233,221, 93, 78, 6, 49,216, +125,186, 33,164,115, 36, 40,247, 29, 66, 71,160,233,235,170, 64,133, 15,207,113,215, 69, 36,242,224,244,244, 35,208,105, 34, 0, + 39,190, 49,143,104,101, 42,238, 57, 85,215,168,198, 72,251,188,244,123,104, 72, 72, 24,201, 79, 78,191,187,166,132, 65, 39,226, + 72, 25,244, 39,167,152,251,180, 90, 22,144, 1, 87,195,147,231,252,236,250,124,244,153, 23,216,158,159,233,140, 17,124, 28,214, + 58,114,244, 24, 61, 62, 93,191,167, 70, 32, 12,103, 39,230, 60,137,199, 94,154, 13,178, 23,215,168, 29,253, 59, 99,250,245, 93, + 11, 73, 95, 47,114, 62,127,102,127,103,150,147,194, 39,221,190, 13,108,129,145,140,228, 16,160, 70, 82,164,158,133, 36,121,130, + 9,200,212,133,253,149, 30,214, 40,187, 66,197,191,195, 39, 20,245,169, 15,236,235,143,162, 14,220,110,140,213,189, 54,163,181, +211,100,184, 17, 30,135,114, 58,162,165,203,177,148,226,240,211,164,149, 65,206, 21,150, 70, 83, 30,118,242, 14,122,121,126,206, +218, 33, 39, 37, 68,227,168,229, 32,128, 82, 65,232, 65, 7,184, 56,237,231,157, 55,102, 89,109, 54,103, 78,208, 84, 37,251,171, + 11,106, 86,236, 71,240, 32,236, 71, 81,211, 14,249, 22,123,153,112,230, 99, 22,103,149,205,202,158, 63, 43, 43, 92,199, 44,100, +130,209, 74,160,141, 72,214, 29,195, 41, 1,144,171, 0, 71,233,189, 78,163,199,149, 6, 5,118,137, 50,159, 88,161, 86, 97,179, + 50,145,112,209,228,179, 81,164,214, 32,202, 66, 93,106,101, 62,161, 25, 74,109,214,150,210,146, 82, 66,186,115,105,198,165,210, +220, 45, 54,156, 0,210, 18,130, 16,156,144,132,160,130,113,234,163,215, 63,102,191, 63,142, 13, 61,168,188, 90,112, 88, 35, 91, +187,121,119,179,119,109,106,165, 54,185,123, 83,184, 1,218,213,172,195, 74,112, 25, 31,193,231,222,112,191,110, 58,164, 21,224, + 48,176,215, 49, 7,195,198,117, 59, 45,161,226,130,149,124,109,157,131,126, 59,105, 34, 25,190,109, 42, 53,196,184,241, 30, 15, +198,138,237, 78, 35, 82, 31,140,211,167,245,219, 66,220, 41, 7,190, 19,170,167, 56,203,165,200,101,140, 85,149,104,230,213,203, +101,189,155, 78,155,220,117, 82, 3, 46,198,227,123, 43,181,137,199, 98,248,121,226, 4, 60,107, 28,144, 81,211, 52, 25,134, 94, +168,243,195, 33, 13,165, 88,233, 15, 20,151, 2, 68,212, 8, 23, 84,117,184,212,128, 27,157,174,166,211,138,218,110, 68,166,202, + 12,226,136,177,129,232,166,216, 72,248,148, 83,159,213, 41, 3, 58,199,247,101,136,115, 44,202,189,191, 58, 53, 62,165, 75,147, + 13,232,255, 0, 85, 84,225, 70,168,193,124, 22,212, 1, 92, 57,109,173, 42, 25,207, 92,107, 7, 94,247, 82,222, 44,120, 49, 37, + 54,166,153, 62, 27, 97,162,180,183,147,212, 19,228,122,244,251, 53,166, 60, 82,241,139, 69,219,203, 98, 69, 54,140,180, 86,247, + 30,234,150,139, 66,201,183, 25,149, 29,233,234,185, 42,196, 70,134,169,113,219, 89,247, 70,154, 91,161,107, 46,114,242,132,100, +244,206,153,205, 97,168, 2,158, 4, 44,100,219,125,135, 64, 78,228,219,222, 73,244,222,221,174, 76,131, 35,204,179,124,218,130, +135, 45,164, 51, 85,202,227, 76,106, 62,206,255, 0,109,219,126, 90, 70,190,103,145,136, 84, 93, 78, 72, 23,191, 48,247,123,113, + 54,107, 98,106,146,105, 9,180, 41, 21,123,162,141, 80,151, 62,153,110, 91,228, 81,105,212,218,178,156,241, 34, 77,169, 72,130, +226, 75, 2, 57,229, 90, 91, 71, 95, 19, 25, 61, 49,174,102,239,183, 16, 27,245,196,245, 64, 82,110,171,182,181, 46,217, 96, 6, + 35,218,212,137, 51, 32,219,108,198,105, 92,201, 85, 69,199, 30, 6,166,164,128, 10,220,112,144, 72,251, 53,214,202, 31,178,178, +163,118, 58,154,214,227,110,196,250,141,229, 94, 90,234,215, 82,232,240, 89,168, 70,166, 84,170, 4,190,168, 41,121,249, 0, 76, + 90, 29,119,151, 56, 9,248, 73, 25,214,146,202,219, 91, 51,104,184,161,111,104, 55, 2,101, 83,114, 54,198,194,191,169, 77,110, + 68,221,177,164, 63, 85,175,214,237, 88,241,211, 82,147, 76,141, 78,128, 22, 91, 87,142,150, 98,205, 74, 85,132,248,171,248,142, + 53,173,150, 83, 84, 83,203, 81, 44,142,139,160, 27, 2,160,233, 3,114,117, 16, 12,141,127, 70, 80, 9, 35,125,241,233,239,130, + 41,224, 38,103, 13,117, 54, 67,153,205,226, 87, 28,112,190, 95, 45,125, 92,210, 83, 86,187,242,226, 42,178,174, 80,149,113,165, + 44, 65,229,100,134, 4,141,150,122,141, 81, 51, 73,162,237, 30,168,196,225,210,109,131,180,183,158,251, 93,182,173, 90, 77,131, + 96, 89,181, 75,242,173, 86, 98, 49,102, 9,183, 41, 18, 99, 82,213, 61,169,147, 28,108, 26,115,213,233,208, 41,241,139, 73, 89, +155, 50, 88, 98, 57, 82,144,225, 71, 44,173,110, 47,174,107,174,254, 98, 13, 58,249, 85, 6,131, 87,171, 39,220, 44,241,181,244, +153,180,166, 32, 5,149,154,122, 42,162,227, 19, 75,165,128, 71,188, 56,178,174,115,204, 82,145,128, 36, 3,237,235,223,234,222, +215,112, 55,182,219, 31, 86, 98, 61,181,187,220,112, 95,208,183,126,253,180, 97, 54,220, 21,109,191, 13,155, 89, 33,113, 54, 95, +106,218,165, 50, 18, 40,148,150,231,154,107,198, 55, 42, 67,242, 41,179, 93,113, 42,113, 74, 86,162, 97,177, 48,209, 39,113,161, + 58, 64, 13,211,225, 75,148, 51,140, 36,165,190, 84,143,159, 65,171, 75,135,178,168,107,242, 90,172,214,180, 51, 59,234, 16,134, + 17,190,133, 64, 20, 55,158, 54, 2, 70,146,225,136, 0,174,157, 43, 97,185,243, 63,233, 63,244,231,241, 66,159,196,102,225, 15, + 14, 51, 37,224,188,143,132, 9,142,161,114,156,207, 55,165,122,154,211,180,201, 83, 95,148,230, 89,116,181,212,212,192, 8,224, + 5,150, 25,142,186,190, 84,124,245,138, 25,117,109,141,230,157,201,225, 47, 99,174,184,147, 81, 37,251, 42,185,185, 27,109,239, +116,234,109, 66,219,122, 4,155, 82,247,170, 85, 97,120, 77, 63, 82,121,198, 42, 45, 83,110,106, 65,247,182, 36,165, 14,184,226, +150,194, 25, 9,113, 3,110,182,151,139,125,212,183,132,104, 23,139,113, 55, 18,137, 24, 33, 42,171,202,150,138, 77,231, 10, 58, + 80,148, 41,215,106,105,101,113,238, 23, 2, 0,109, 6, 99, 41,127,224, 0,190, 84,115,174, 89,251, 50,110,182,111,109,161,226, + 3,101, 36, 58,211,149,138, 21, 94,218,222,203, 78, 35,202, 81, 46, 82,231,199, 69,129,126,193,167,180, 63, 93,214,103,194,179, +170, 50, 48, 15, 42,103, 21,168, 17,147,174,130,217,182, 49, 51,154, 91,177,188,102,144,164, 58, 35,144,191,242,169, 25, 99,159, +148,124, 72, 7,226,207, 80, 49,207,131,216, 83, 92, 69, 69, 29, 6, 99, 95, 73, 34,235, 8,250,148,236, 9, 14, 17,197,138,133, + 2,215,210,116,217,110,164, 91, 97,105,119,134, 62, 33,208,248,151,225,118, 89,196, 28, 81, 28, 85,249,213, 91,213,189, 89, 99, + 36,143,237,143, 83, 41,169,117,146, 89,165,169, 6,105,139, 75,170, 73,228,145,245,134,150, 73, 9, 44,122, 97,110,111,221,149, +120, 67,165,189, 58,161, 34,214,201,105,134,233, 55,148, 69, 83, 11, 50,221, 90, 92, 68, 40,213, 72,110,200,135, 46, 73, 41,108, +171, 14,167,245, 84,130, 65,200,211,166, 94,171, 84,102, 51, 47,194,143, 89,131, 9, 5,184,240,105, 85, 40,147,218, 74,222, 40, + 89, 97,227, 2, 67,137, 97, 78,252, 5,254,110, 85,114,132, 39, 9, 72, 32,233, 93, 14,201,122, 65,143, 22,156,212, 69, 86,100, + 46, 44,135, 38, 57,135, 33,219,180,231, 22,234, 83, 60,161,192, 10,170,170, 8,144, 33,178, 71,233, 29, 30,242,191,208,181,133, +191,182,125,129, 22,137, 24,184,219, 16,105,244,122,116,229, 24,172,196,140,227, 51,106, 82, 37,172, 0, 92,153,226, 37,249,213, + 57, 83, 22,165, 18,225, 82,222,113, 69, 74, 9, 71,234, 68, 9,208,198,209, 94,219,218,228, 15, 83,112, 65,184, 62,227,110,189, +109,178,169, 62, 83, 5,218,149,249, 37,181, 42,198, 87, 89, 80,199,253,217, 86, 70, 70, 98,204, 20,146, 89,197,201,101, 22,230, + 59,242, 41,215, 69, 77, 73,128,236, 67, 18, 58,167,154,138,231, 60, 4,102,158,150, 80, 82,130,218,157,115, 45,198,101,174, 84, +165, 1, 68,114, 52,130,156, 99, 89, 45, 34,212,134,228, 73, 16,146,227,205,181, 1,201, 78, 77,171, 38, 42,218,143,227,144, 4, +201, 12,201,115, 36, 71, 12, 32,165, 43, 3,226,248,212,144, 10,146, 53,126,180,172,233, 73,154,154,212,168,202, 93,197, 80, 97, +136,104,140,211,242,100,192,162,196,109,194,166, 41,208,221,148,163,201,135, 23,227, 62,232, 78, 95,127, 36, 0,218, 27, 1,238, +160, 90,138,170,136,112, 34,196,122,116, 24,179, 26, 97,224,201, 66,151, 91,158, 22,121, 26, 8,112, 2,184,136,155,133, 28, 30, + 89, 15, 32, 1,204,132,117,220,138, 25,100, 69,141, 33, 42, 95,185,185, 36,108, 64,216, 41, 3,125, 76,119, 96, 54,234,214, 58, + 53,249,220, 11, 78,232,142,144,194,128, 23,101, 1, 6,175,214, 62,103,112,219,249, 82,197, 84,238,108, 17,110, 52,139,118, 47, + 29,184,225,215,110, 42,187,173,184,204,207, 72, 80, 85,167,183,182, 36, 9,173, 70,184,111,106,192, 66,170,116,219,106,146,227, +200, 80,164, 50,235, 10, 77, 66,191, 84,117, 10,106,153, 79,228, 73,241, 36,174, 36,119,184, 21,190, 59,243,185,156, 69, 84,159, +170,238, 77,125,233,212, 64,224,114,153, 96, 80,157,149, 74,219, 91,113,168,200, 9,139, 79,161,218,173,191,225,204,247,118,130, + 18,103,207, 18,106, 18, 92, 10,125,231,194,214, 80,151,139,218, 61,196, 11, 91,199,196,197,237, 22,149, 81, 84,157,189,217,229, +191,180,182, 2, 88, 11, 17,100, 68,160,212, 84,221,239,112,178,210, 9,241,102,214,111,225, 52,151, 48, 84,168,148,168, 76,161, + 74,109,180,160,115,231,137,235,103,118, 56,127,147,104,217, 55,156,251,107,111,175,235,178,220,141,117, 86,109, 75,154,123,113, +238, 29,183,163, 87, 2, 87,106,211,239, 74, 50,150,145, 64,189,234,148,231, 29,158,154, 36,149,174,165, 75,167,166, 52,138,188, + 24,138,159, 21,133,236, 83,112,252,185,180,169, 8,169, 20,176,234, 0, 18, 88, 7,176, 39, 89,211,114,119, 4, 70,189, 44,161, +148, 22,190,159, 75,188, 43,225,207, 12,190,140,158, 22,229, 62, 49,120,177, 11,207,199,124, 79, 74, 43, 96,166,138,138, 92,199, + 54,166,167,120, 99,153, 50,252,166,134, 37,121,162,150, 40, 36,137,243,154,231,228, 65, 75, 44,172,185,141,117, 61, 12, 49,202, + 64,184,109,119,103,132,181, 74,129, 79,134,194,135, 43,190,237, 21,191, 29,100, 96, 37, 40,117, 73, 82, 99, 35, 32,124, 88, 42, + 63,170, 53,226,221,219, 54,154,144,210,159,144,184,110,188,191, 9,111, 50,130,176,158,110, 80, 84,251,171,202,128, 1, 93, 73, +229, 25, 56, 37, 0,140,233,155,215,238,236,178, 81,245, 6,230,196,184, 38, 72,117,114,146,204, 10,157, 18,124,222, 68, 55,238, +229, 13,192, 85, 62, 51,171,139,134,207, 35, 41,140,233,231,202,146,147,144,117, 96,166,239,230,251, 91, 78,170, 52,187,154,100, +238, 69,175,198,143, 95,161, 83,106, 18,154,101, 79,165,231,152,117,164, 67,133, 45,134,212, 82, 91,194,156, 5, 45, 44,164, 2, + 66, 84,155, 34,147,133,243, 36,165, 20,116,217,188, 35,151,238,126, 97, 4,254,177,125, 68,239,211, 82,223,173,172, 0, 24,167, +179, 47,246,170,125, 30,232,243,104, 31,139,124, 24,227,142, 30,161,169,102,142,147, 50,172,203, 50,121, 41,229, 42, 69,218, 3, + 30,118,241,202, 0,243,200, 41, 94,165,129, 22, 42, 88,227,163,116,203, 17, 8,185, 93,183,106,208,252, 38,221, 75,239, 69, 82, +148,212, 98,226, 86,217,118, 44,165,167, 9, 65,101,223, 60,148,144,181, 96,168, 43, 0,252,174, 91,214,181,183, 10,117, 86,179, + 50,153, 73,166, 83,194,214,252,233, 83,209, 26, 43, 44,162, 64,140,219,206, 58,234,210,112,235,191, 11, 64,100, 44,244, 4,168, +145,172,123, 98,119,186,189,184,148,118,141, 70,148,197, 50,191,111,207, 66,201,167,161,249, 52,249,241, 42,212,229, 7,204, 15, +126, 66, 92,110, 3,140,161, 73,118, 19,202, 81, 97,108,148,161,199, 27, 91, 78,107, 86,119,238,216,221, 43,230,252,250,182, 13, + 58,183, 46,147, 70, 13, 38, 4, 56,116,185,179,162, 69, 46,180,223,141, 81,142,184,140, 41,147, 41,114, 84,242, 75,171, 82, 84, +194, 91, 72,230, 64, 90,214,181, 33,200,201,170, 43, 89, 94,208, 24,128, 15,166, 66, 20,216, 3,112,111, 96, 88,110, 78,159,118, +155,220, 99,160, 60, 98,250, 99,112,207,134,255, 0, 71, 46, 29,250, 64,120, 83,195, 50,248,169,148,241,245, 69, 30, 93,144,193, + 67, 79, 83, 28, 82,215, 85,189,122,153,115, 32,105,154,178,134, 26,105,168,101,163,146,156,211,189, 75,102,130, 44,173, 68,114, + 77,207, 71,110, 15, 18, 59, 61, 18,251,183, 45,234,180,107,233,187, 1,250,171, 17,238,235,214,213,164, 83,170,247, 53, 22,146, +247, 59,114, 43, 22,149,141, 85,159, 17,119,100,134, 63, 68,234,163,187, 34, 18,164, 53,206,152,138,117,244,161,183, 58,193, 87, +225, 15,135,235,154,206,165, 93,187, 71,198, 37,215,186, 16,174, 74, 84,106,197,183,252, 7,217, 27,135,115, 66,233,111,133,248, + 82,110, 88, 27,108,185, 18, 44, 98,226,138,217, 76, 74,176, 98,168,211,208, 31, 14, 67,113, 0, 40,199,138, 77, 58,219,219, 50, +244,105,201,133,114, 94, 12, 56,227, 82,225, 41,246,106, 20,107,126, 74, 1, 10, 21,105,145, 29, 83, 87, 29,105,183,135, 90, 99, + 14, 24,108,168,230,161, 33,210,145, 21,121,134,197,241,157,196,167, 13,119,204,187,239,101,247, 94,228,180,103, 85, 93, 74,238, +122, 27,239, 11,130,196,190, 89, 74, 3, 65,139,247,111,234,106, 52,187,152, 37,129,200,203,193,152,211, 98, 54, 3,112,101,197, +108, 4,133,235, 56, 58, 10,228, 87,202, 71,178,152,134,242, 75,119, 19, 27,222,225, 88,150, 31,254, 96, 54, 34,214,141,213,129, + 30, 77, 63,251, 74,190,146, 28, 63,196,245, 21, 94, 41,241, 81, 90,138,137,238,120,103,135,232,114, 90, 51,145,166,250,161,204, + 42,243, 28,191, 56,115, 80,172, 17, 36,201,106, 30,171, 49,165, 99, 58,215,215,101, 85,180,199, 46,155,165, 84,250,206,231,112, +167,186, 84,202,229, 58, 84, 41,147,169,133,248,238,197,175, 91,119, 93, 18,221,187,232,146, 84,224,168,218,183,125,171,122, 80, +169,146, 69, 62, 91, 77,165,197, 50,182,199,186,202, 90, 37,197,125,153, 76,161,221, 73, 67,102,161,181,186, 27, 75, 97,238,133, +149, 75,174, 53,111,223, 86,211, 87,109, 54,213,185, 35, 77,146,237, 17,137, 14,200,167, 84,169, 77, 86, 23, 24,190,212,104, 85, + 56,114,217, 98, 72, 75,241,159,101,166,228, 0, 16,240, 9,226,206,213,123,125,246,154,253,183, 26,179,248,203,225,125,202,139, + 46,178,168,179,235,251,104,229, 22,255, 0,179,166, 52, 82,164, 41,247,246,211,115,158,110,161, 69,150,180,149,143, 14,155, 84, +150,134,210,172, 54,180,249,236,206,213,123, 69, 61,143,214,236,216, 85,123,123,115, 55,238,195,166,195,122, 53,197, 19,108, 46, + 26, 79, 16, 44,236,253, 26,226,128,250,223,131, 85,141,183, 84,234,188,232,106,173,199, 90,212, 89,142,137, 15, 83, 81,144,125, +209,101, 40,228,141, 47, 10,102,180,149, 86,154,156, 24, 92, 29,108,129,135,154,226,204, 2, 44,137,115,111, 54,226,254, 93,182, + 24,147,120,185,244,188,240,119,233, 7,195,249, 54,103, 93, 17,224,159, 17,114, 33,203,106,209, 45, 37, 92,121,173, 8, 71, 34, +150,170, 58,150,200,101,166,150, 41,220, 61, 44,139, 5, 76,112,171,213, 71, 20,136, 39, 4,118, 6, 29,186,134,194, 27,148,195, +193, 62, 44, 68,187, 21,106,102, 84, 30, 70, 85,205,142, 80,158, 87,201, 81, 7,153,192, 0,192, 80, 64,211,149, 66,165,180,203, +136, 67,104,240, 27, 90,130,130, 17,226, 37,166,148,162, 1, 67, 73, 94, 66, 83,252,227,140, 39, 39,160,215, 35, 46,223,110, 95, +179,178,219,105,233,244,219,195,120, 47,233,139, 89,112, 67,182,118,102,191, 77,247,149, 21,115, 41,196,213,175, 41,244,200,241, + 80, 85,142,139,201,194,137, 9,207, 77,115,159,136,255, 0,164,222,229,137, 30,163, 15,134,190, 13,228, 85,153, 9, 87,213, 91, +165,191, 87,204,167, 45, 40,174, 45, 76,182,204,169, 86, 14,216,198,101,228,255, 0,133,202,109,178,212,219,137,132, 41,194,148, +158, 96,180,131, 37,202,248,118,182, 90,133,138, 42,118,185,221,117,133, 75,133, 32, 29,216,168,185,189,236, 14,163,109,129, 0, +219,143,243, 63, 16,184, 90,150, 55,105,115,232, 42,165, 31,169, 77, 42,212,177, 32, 14,130, 18,226,224, 0, 53, 57, 0,216,238, + 55,196,195, 45, 68, 22,211,205,146,176,133, 54,151, 20,132, 15,133,229,231,144, 40,224, 37, 5, 65, 39,151,155,148, 18,158,152, +235,167, 48, 77, 75,205,166, 35, 10,241, 36,158, 64,164, 52, 60, 79, 9, 9,207, 48, 83,160,114,149,103,148, 96,103,182, 73,215, +230, 7, 43,219,203,237, 79,157,190,246,230,253, 61,196,180,212, 75,181, 94,156,213, 51,101,233,182,221, 22,223,225,210, 69, 2, +168,227, 11,169,218,181,125,167,162,176,212,122,212, 25, 8,142,218,126,176,154,244,170,211, 68, 7, 88,168,182,234, 82,177,213, +203,167,233, 12,113,211,199,133,235,182,188, 54,240, 99,176,227,101,238,251,254, 37, 46,135, 81,183,246,214,113,190,247, 95,112, + 47, 39, 98, 37,203,129, 54,157,199, 86,136,195, 22, 53,140,193,106, 91,252,225,149,204, 98, 19, 75,118, 84,180,165, 7, 18,169, +178, 74,170, 69, 51, 56, 73,209, 23, 81,210,224, 42,219,115,204, 50, 5,109, 34,219,149, 87, 3,115,219, 16, 36,241, 71, 32,204, + 22, 85,167,138,163,219, 12,129, 32,128, 37,228,152,177, 1,116, 88,216, 92,246,107, 17,218,230,195, 19,125,171, 92,246,205, 30, + 90, 32, 84,171,244,168,149, 5, 16, 61,205, 83, 89,247,180,147,216, 56,218, 23,148,121,247,198,178,122,125, 22, 5,114, 40,154, +138,154, 22,210,134, 80, 99,180,183,112, 79,162,136, 1, 95,118,123,235,152,220, 17,123, 63,247, 3,103,237, 26, 77,219,197, 85, +255, 0, 51,114,119,174,160,202, 42, 21, 90, 12, 74,180,170,149,181,104,202,120, 37,197,211,222,171, 73, 81,114,229,171,182,181, + 40, 63, 37, 88,100,184,149,120, 41,228,194,143, 75,153,101, 48,185, 91,107,153,134,155, 1, 8,109,165, 41, 41, 74, 64, 1, 32, + 4,224, 99, 3, 80,103, 78, 51,204,101,157,185,180, 57, 21, 10,146, 34, 81, 20,149, 19,184,236,206, 95,148,177,131,216,104, 15, +110,168,167,108, 60,209,182,123, 57,246,138,169,146,133, 91,117,142, 38,105,152,127,215, 43, 89, 24,145,251, 10, 7,241,197, 84, +154,117, 14, 91, 72, 18,147, 35, 46,114, 97,104, 83,107, 42, 39, 25, 0,249,254,115,167, 66, 11,229, 77,120,141, 0,191,209, 21, + 33, 25,229,241, 84, 82, 74, 83,146, 59,103, 90,221, 94, 77, 82,101,118,154,148,130,244, 86,221,202,228,255, 0, 60, 39,160,229, + 89,254,119,200,247,211,203, 6,164, 88,105,150, 65,236,148,131,147,213, 56, 24,206, 62,221, 45,195,237,153,206, 43,169, 51,119, + 73,100,164,125, 34, 72,211, 64, 97, 96,110, 1,191, 81,243,214,210, 12,210,138, 24, 41, 40,102, 89, 57,178,213, 33,105, 1, 32, +244, 32,111, 96, 45,125,246,219,221,139,140, 97, 48, 58,236,154,131, 46,153, 46,146, 87,204,146, 82,132, 15,242,109, 36,167,167, +132, 6, 59,119,206,190,200,170,100,132,160, 21, 41, 56, 1, 36,134,210,133,100,156,114,158,195,191,225,170,166,170,211,105,248, +149,212,255, 0, 59, 56, 36,156,100, 15, 64,113,246,235, 24,171,213,226, 60, 10,142, 60, 84,244, 75,137,232,164,103,245, 65, 82, + 71, 80, 58,100,117, 7, 79,209, 82,242,147, 69, 59,116,245, 27,159, 93,250,111,240,235,241,195,116, 85,144, 77, 56, 50,195,229, + 27,121,122, 40, 22, 2,202,123, 1,254, 33,247,226,229, 38, 74,212,210,138,159, 75, 96, 2, 2, 89, 3,156,146, 72,192, 46,118, +242,234, 6,176,138,131,208,130,143, 59,105,144,180,243, 97,114, 84,183, 74, 71,117, 30, 85,124, 41, 72, 32,103,160,201,234, 15, + 82, 53,100,169,214,165, 52,218,131, 78,182, 91, 7, 5,229,115, 43, 41, 62,101, 9,253, 85, 99, 29,115,128,122, 16, 53,132, 78, +168,190,250,242,169,137, 87, 33, 4, 48, 26, 80,111, 0, 28,172,132,175,226, 56, 4,128,162, 71,159, 77, 32,237, 34, 54,153, 1, + 86, 59,239,247,110, 15,243,248,219,221, 40,164,162, 89, 84,201, 21, 66,136,191,195,112,122,116, 32, 11,143,131, 90,221, 78,196, + 28, 93,170, 53, 86,220, 45,182,214,121,193, 56, 75, 24,202, 63,156,175,242,120, 8, 79,194, 49,147,208,172,140,107, 28,144,185, + 14,165,196,243, 54,128,227,107, 95, 40, 1,247,148, 10, 82,160,148, 36,114,161,156, 18,146,126, 53, 99, 7,225,193, 26, 21,201, +165,223,209,170, 87, 43, 69,196,145,224,199,109, 32, 21,142, 84, 37, 68,147,135, 50, 73, 61, 7,235, 99, 61,180, 42,150, 9, 83, +110, 45,199,193, 66,138, 91, 83,156,173,178, 57, 84,149, 20,132, 36, 4, 47, 4,158,234, 33, 74, 7,212,107, 34, 85, 36, 91,174, +195,111,187, 14, 2, 4,136, 88, 88, 50,239,114, 9,216,252, 64,239,107,131,210,253,111, 96,106,135, 9,241, 91, 90,152,154,224, + 81, 10,117,183, 66,150,132,132, 32,132,199, 90, 18, 18,211, 62, 25,202,136,229, 86, 80, 71, 55, 78,180, 86,211,138, 90,218,109, +210,132,173, 42, 40,195, 97,226,160,188,146,149, 61,202, 17, 24,252, 7, 4,147,128,148,146,114,179,143,162, 72, 66, 20, 93, 82, + 91, 32,243,151, 0, 13,184,226,121, 87,250, 54,210,216, 3, 57, 40,248,112, 84, 48,188,119,233,112,142, 86,234, 29, 75,124,173, +161,158,235,112,133, 50, 75,156,174, 56,246, 66,135, 48, 3, 10, 10, 0,128, 64, 10, 4, 29,108, 70,250,118,191,227,252,183,237, +110,134,223,125,175,163, 80,140,221,139, 15, 94,194,214,251,186,251,205,239,140,110,108, 82,150,189,228, 33,212, 54,225, 10,142, + 29,108, 40,168, 1,209, 40, 65, 63, 3, 28,169, 5, 42,200,193, 95, 80, 71,124, 14,168, 18,210, 86, 21,203,202, 82,160, 8, 0, +169, 41, 24, 9, 81, 60,184, 87,196,165,224, 12, 28, 28,231,190,156,202,203, 43,100, 60,180,187, 46, 83,142,128, 90, 68,167, 20, + 70, 74,148,144,167, 1,235,149, 35,157, 71,249,216, 72, 0, 37, 61,155,106,154, 76,153, 41,136,149, 4,169,231,163,196, 66,202, +129, 9,117,245, 33,158, 98,160,112, 71,136,224, 32,158,132,126, 26, 84, 48, 2,250,134,223,233,191,126,157,125,253,112,216,241, + 18,202,161, 65, 55, 29, 0,222,246,181,135,238, 29,126,252, 64, 99,219,127,112,181,112,123, 74,183,173,166, 28, 82,255, 0,130, +214,206,212, 89,178, 82,176, 66, 90,159, 67,176,105, 47, 75, 67, 68,147,204,215,137, 82, 24, 35,204, 30,154,228,170,206, 51,216, +231,166, 58, 99,237,251, 53,183, 60,121,238, 60, 93,220,227, 99,138,189,200,132,233,122,157,114,111,133,244,154,114,249,150,180, +154,125, 6,168,171, 94, 25,104,172,228, 50, 89,161,161, 72, 29,130, 92, 0,116, 26,212,101,246, 56, 61, 59, 96,227, 63,241,212, +247, 43,140,165, 5, 18,176,179, 8,144,144,122,130, 84, 18, 62, 32,155, 28,114,150,121, 50, 85,103,185,197, 66, 29, 81,207, 87, + 80,202,123, 21, 51, 57, 82, 15,189,108,126,252, 8,178, 15, 79, 76,232,117,245, 36,142,192,224,252,191,179, 85,214,174,254,137, +207,231,246,104,101,224, 28,231,161,235,248,233,200,126,252,104, 1,220,109,129,221,230,199, 97,142,189,189, 51,215, 63,159, 61, + 14, 64, 0, 96,247, 29,126, 71, 68,169, 89, 62,120,252,245,208,202,238, 79,204,253,154, 92,108, 5,240, 48, 58,192,202,135, 67, +215,243,231,249,198,133, 81, 3, 57,249,224,119,237,229,162, 28, 39,169,249,249,126,125, 52, 26,200,251,199,127,179, 74, 45,198, +227,126,216,200,253,248,160,178, 50, 58, 3,211,207, 63,184,253,186, 90,240,163,147,159,195,236,210,210,184, 24,175,170,168, 61, + 49,215,167,225,161, 16,112,122,156,116,213, 97,248,103,161,251, 51,164,216, 90,227,174,173,255, 0, 60,100,245, 38,214,190, 14, + 73, 56, 0,142,152,239,145,247,116,213, 66,176, 7, 82,172,142,216,249,246,207,222, 52, 58, 84, 83,211, 29, 7,111,236, 58,242, + 80,162,174,101, 47, 8, 61,128,206, 71,222, 7,174,116,131,222,222,236,101, 69,254,127,150, 46,141,168, 96, 0, 57,137,206, 73, +254,145,243,192,215,213, 44,173, 73, 8, 39, 9, 56, 87,124,103,247,245,254,141, 80,105,188,242,146,174, 81,158,128,117, 61, 49, +215, 25,244,209,205,167, 57,192,206,127,164,117,237,249,237,164,172, 79,207,166, 48,109,219, 21, 90, 56, 35, 35, 32,143, 46,221, + 61,125, 15,125, 28, 57, 72, 79,160, 62,127,205,251, 62,125,244, 50,121,112, 0,252,253,190,154, 37,176, 85,142,192,124,135,244, +231,207,166,177, 97,123,227, 24,184,178, 15, 76,159, 82, 63,163,247,234,184, 24, 57, 24,201, 57, 7, 31,135,219,161, 16,175, 35, +231,219,250, 49,162,146,113,220,245,232, 65,198, 59,246,199,175,246,233, 22, 22, 36, 97, 50,187,220,155,223,231,255, 0, 56, 37, + 43, 8,199, 58,186,159, 32, 59,244,249,104,146,238, 70,113,140,249,250,227,183,159, 77, 4,113,144,190,153, 63, 44,227,184,200, +252, 53, 81, 36,116, 32,231, 29,201,251,125, 7,150,146, 98, 58,223,225,130,219,221,123,117,193, 41,119, 24,248,249, 64, 32,224, +227,175, 94,160,122,244,206,167, 39,236,166,220,118,247,115,129,157,165,148,252,148, 73,171, 88, 74,169,237,245, 93, 33, 73, 46, + 54,186, 44,133, 38, 1,113, 61, 74, 65,132,228,126, 92,227, 35,168,212, 42,118,215,108,110,189,211,185, 98,219, 86,181, 49, 83, +231, 73, 5,229,186,227,137,139, 78,167,194, 66,128,145, 85,173, 84, 93, 79,135, 74,164,183,252,247,156,234,162, 66, 26, 67,174, +148,160,203, 23,217, 2,214,215,112,241,106,238,110,209,215,119,102,143, 34,181, 87,151, 2,239,168, 76,172, 75,110,139,108, 53, + 53,136,201,133, 34, 21,179,239,238, 5,184,218, 82,218, 11,139,119,149,215, 15,196, 91, 66,126, 17, 4,227, 9,104,167,142,154, +137,228, 6,169, 95, 86,155, 95, 74, 21, 96, 75,158,136, 11, 5, 3, 81, 26,142,194,230,246,184, 60, 26,124,214,135,136,167,204, + 41,105,100,124,178, 88, 36,167,158, 80, 44,129,137, 73, 35, 0,159,180,193,212, 2, 20, 18,129,238,218, 65, 23,235,214,231, 75, +174,219, 59, 83,184, 21,235, 93,151, 30,184,224, 91,147, 13, 27,193,104,188,236,105,178, 18, 35, 38,162,134, 82, 50,234,163, 33, +213,188, 0,207, 86, 70,181,171,102,120, 8,183,217,222,155,115,124, 46, 59,138, 53,229,105,208,108, 90,123, 86, 21, 10, 66,223, +155, 42,179,121,215, 33,166, 69,211,124,221,210, 95,234,244,211, 45,231, 83, 25,177,128,216,198,122,164,107,107,162,239,150,195, + 32,148, 57,188,187,110,233,193, 75,141, 34,227,167, 60,130,146, 48,180, 45, 33,226, 20, 8, 39, 35,207, 26, 14,226,227, 7,134, + 29,183,182,107,183, 12,173,200,163,213,169,246,180, 23, 39,205,163, 89,141,125,115, 86, 84,102,186,172, 83,169,144,129, 84,133, +127,178,128,126,237, 65,225,142,150,158, 82,226,162, 33,169,116, 0, 89,111,114, 69,200, 23, 59,157,133,183, 61,135, 91, 99,179, +242,190, 62,226, 28,135, 33,205,114,204,161,165,203, 70,109,205,246,202,132, 82, 30, 74, 87,138, 56,249, 76,250,117, 70,177, 5, +155, 76,136,234,116, 85, 84, 45,129,101, 97,144,207,224,179,103,238,181, 56,183, 81,123,208,158,152,250,158,156,245,169,125,220, + 20,116, 60,235,202, 42,121,197, 48,137, 42, 66,150, 73, 60,184, 78, 0, 56,244,208, 91,129,114,240,113,236,166,216,187,155,114, +235, 20,202,117,183, 21,229,201,153, 69,162,189, 37,138,222,236,111, 13,232,227, 74, 84, 26, 29, 62,109, 77, 74,149, 44, 56,247, + 39,140,233, 40,139, 17,165, 41,231,112, 0,207, 27,248,128,250, 66,114,226, 82,170, 52,190, 16,184,115,190, 43, 19, 3, 14, 52, +141,201,220,155,106,174, 41, 84,247,112, 66,100,195,183, 41,209, 86,185, 78,160, 14, 96, 30,113, 8, 56,248,186,103, 81,143,226, + 11,136,157,247,226,127,114,100,238, 30,253,238, 45,126,244,188,158,105,214,162,199,173, 62,168,205, 81,169,238, 40,172,211,168, + 86,223,192,221, 6,154, 50, 7, 43, 76,160,168, 1,206,181,158,186,127,203, 56,124,207, 46,161, 18,211, 34,253,166, 54, 14, 6, +215,180,103,204, 24,247, 50, 42,129,179, 89,197,215, 20,239, 27,253, 36,248,135,244, 13, 71, 12, 80,113, 94, 97,196, 20,179,105, + 38, 7,168,168,108,188, 50,127,118,243,135, 96,181, 38, 34,111, 20, 96, 58,169,220, 60,100, 95, 24, 39,180,115,137,253,201,226, +247,127,170,251,223,186, 82, 27,254, 16, 94, 74,118,124, 26, 44, 87, 92,118,155,105, 91, 81,121,162, 91, 54,141, 31,196, 63, 13, + 58, 13, 59, 9,230,192, 47, 62,243,210, 23,241,186,117,175, 92, 57,196, 97,202,237,211, 57,208,178,252, 42, 34,147, 24, 1,211, + 46,149, 5, 18, 60,253, 6,173,251,228,231, 53,219, 29,128, 65,247, 42, 12, 6, 79, 41,200, 5, 73, 4,129,215,191,174,178, 14, + 26,216,118, 93,122,230,134,202,121,164,204,167, 68,139, 29, 9,238,183,223,119,194,101, 41,207,153,113,104, 31,126,172,212,141, + 41,120,124,197, 24,209, 26, 34,128, 46,118, 28,192,119, 59,147,183, 82, 73, 39,169, 36,239,142, 53, 53,117, 21,115,214, 86, 85, + 74,211,213, 84,180,178, 72,231,118,103, 42,204, 73,176,238,123, 0, 0,232, 0, 27, 98,109, 63, 71,223,128,234,125,203,195, 15, + 16,156, 74,220,244,174,123,199,114, 99,200,218,237,155,145, 45,177,136,116,123, 98, 92, 90,221,217, 83,134,149,167,225, 85, 82, +187, 18, 29, 56,186, 15,197, 30,152,164, 14,138, 57,216,168,246, 17,161,213, 31,142,228,117, 50, 90,146,235, 97, 10,230, 75,225, + 8, 56,228,115,185, 67,169,229, 41,229,239,204,112, 8, 58,236,151, 0,219, 99, 15, 98,184, 76,225,239,107,105,113, 83, 17,187, + 99,109,109,231,167,180,148,132, 41, 85,138,164, 38,234,181,105, 14,116, 28,206,174,124,199,201, 39,174,123,233,168,226, 23,134, +171,150, 93,110,226,220, 91, 38, 61, 58,161, 65,144,255, 0,214,146,168, 44, 62,182, 43,237,206,148,240,247,152, 52,168, 9,103, +146,167,207, 53,197, 58,202, 3,136, 63,166, 80, 94, 2, 65, 52,151, 19,209, 54, 99, 28, 89,138, 38,170,131,118,127, 82,142,117, + 40, 61, 55,137, 74,160,247, 13,239,215, 29,145,225,180,210,240,102, 89, 6, 69, 36,194, 24, 42,163, 73,100,212,214, 95,105,101, + 94,110,228,237,169,174, 22,254,128,108, 0, 3, 82,108,234, 84,116, 52,134,210,201, 41,147, 33, 50, 29, 8,240,203,143,186, 2, + 0, 83,220,201,207, 58, 67, 40, 7, 36, 0, 19,132,156,107, 99,104, 52, 8,210, 93, 98,116,150,210, 36,193,113, 47, 65, 13,129, +225,199,203,101,135,198, 79,235, 74,113,133, 41, 10, 89, 5, 32, 16,148,242,167, 36,170, 87, 15, 59,203, 71, 82, 20,230,223, 76, +148,128,134,151,205, 74,153, 75,168, 33,105,194, 64, 39, 19,144,162, 0, 37, 71, 41, 4, 99, 28,189,244,241,218,123, 83,186, 79, + 41,180, 35,109,238,133, 20,114,133, 45,113,162, 37, 61, 14, 28, 74,221,114,104, 72, 79, 81,147,216,245,198,162, 81,100,213, 74, + 64,146,146, 66, 91,182,134,244, 22,232, 13,237,215,211,210,214, 24,178, 78,125, 70,186,229,108,198, 24,237,177,102,158, 32, 0, + 54, 4, 18, 91, 96, 64, 3,222, 5,177,113,161,208, 12,134, 16,211, 10, 90, 34,143,242,202,115,224,151, 49,158,230, 50, 29, 74, +147,238,236, 18,160, 10,191, 89, 64,114, 35, 1, 74, 86,178,171,163,112,237,237,158, 85,185, 95,170,208,239,234,203,242, 38,132, + 82,227,109,214,216,222,251,153, 34, 51,212,224,196,176,253,106,153, 99,209,229, 46,149, 79, 64,228, 45, 41,208,217,144,176, 88, +142,149,168, 40, 7,150,209,216, 45,211,158,164, 57, 54,149, 73,183,217, 80,229, 46,213,234, 77, 72,113, 41, 0,142,127,114,166, +182,234,138,136, 63, 8,231, 66,124,250,119,214,136,251,111,106,123,151,194, 15,179, 87,116,183, 91,103,247, 82,225,178,183, 81, + 55, 54,223, 91, 16,111, 43,121,168,212,249,212,202,101,201,112,177, 6,177, 22,136,227,168,117,112,106, 47,198, 43, 67,115,185, +253,229,144, 74,152, 83, 75,194,132,166,147,135,179, 55,167,146,177,104,218, 8,163, 49,131, 44,171,101, 82,242, 36,105,101, 37, + 93,174,238, 0,210, 13,137,213,184,190, 34, 25,199,137,124, 27,150, 48, 25,157, 89,207,105, 98, 73,154, 90, 74, 25,209,101,153, + 68, 78,197, 69, 87, 38,162, 8,201, 42, 11,115, 17,137, 23, 64, 22,225,150, 51,124,116,238, 62,206,240, 93,121,221, 53,125,139, + 98,254,183,183,166,236,173,213, 46,123, 18,139,190, 78, 91,107,223,205,183,143,115, 74,157, 85, 27,132,254,217,209, 34,200,137, +176,244,148, 57, 59,154,223,149,118,189, 34,254,168, 6,195,212,202, 37, 1,178,229,101, 17,220,184, 46,123,134,236,174, 85,110, +107,134,183, 87,184,110, 58,228,233,117, 42,229,201, 93,156,253, 74,191, 90,168,206,125,114, 39, 77,169, 84,100,184, 86,235,239, + 72, 90,214,224, 4, 37, 74, 86, 72, 39, 36,218, 42,181, 73,149,138,165, 74,181, 92,157, 58,167, 88,172,212,165, 86, 43, 53,106, +148,217, 85, 42,173, 98,179, 80,115,198,159, 87,171,212,230,186,183,234,149, 55,158, 37, 78,200,125,199, 29,112,245, 90,142, 6, +128,109,101,110, 97, 36, 6,179,241,128, 71, 49, 62,185,242, 26,176,114, 30, 31,163,201, 33,178, 14,117, 76,191,106, 66, 5,197, +194,141, 9,251, 40, 52,128, 22,229,136, 85,214,206, 85, 72,164,252,120,250, 73,120,157,244,128,204,169, 36,227, 28,238, 99,195, +217, 60,113, 67, 69,150,137,165,120, 17, 41,193, 88,102,171,119, 98,213,213,195, 83,191,180, 77,245,112, 73, 61, 64,160,130,138, + 25,228,133,136, 90,148,234, 57, 93, 9,121, 9, 80, 90, 91,144,148,188,144,176,114,149,165, 14, 2, 18,224, 80, 4, 40, 96,130, + 50, 8, 58,204,169,155,143,113,209,211, 21,169,110,192,185,160, 68, 11, 17,232,183,173, 53,187,170,154,198, 82, 82, 61,205,249, +174, 9,212,229, 15,255, 0,131, 48, 54, 63,248,163,211, 24, 96,228, 10, 88,201, 41, 7,162,137,244,238, 63, 57,213, 53,164, 43, + 36, 14,185,200,252,159,150,159, 39,166,130,161, 52, 77, 10,202,163,166,160, 13,137,238, 13,174,167,222, 44, 71, 99,138,111,135, +120,167,136,248, 74,170,106,190, 27,206,170, 50,105, 42,192, 74,133,134, 66,176,213, 68, 13,249, 53,148,230,244,245,180,228,253, +170,106,184,166,129,255, 0, 94, 54, 24,116,231,239,189,238,150, 89,133, 64,254, 15,237,252, 36,248,206,123,141,131, 77, 48, 29, +151, 33,230,210,209,151, 80,170, 84,195,206,184,250, 26, 64,229, 8, 74, 50,160,149, 45,107, 8,109, 8,177,171,117,119, 10,108, + 7,169,170,189,110,207,170,159, 74,208,253, 57, 21,201,173, 71,113, 46,161, 40,144,133, 73, 74,196,165, 54,232, 78, 92,111,222, + 60, 37,149,168,148,124, 74,206, 0,166,219,230, 33,120, 36,117,206,124,251,143,219,175,170, 91, 74, 90, 19,207,241, 32, 19,200, +147,240,156,250,254,205, 37, 29, 21, 36, 32,133,167, 64, 24,223,236,130,111,182,228,145,114, 71, 98, 73, 54,218,248,156,102,190, + 58,120,209,157,242, 99,172,241, 87, 62,130,146,154,148, 80,197, 71, 69,153,213,101,153,108, 20, 34, 40,225, 52, 84,185, 86, 89, + 37, 30, 91, 75, 70,241, 68,139, 37, 45, 45, 36, 84,242,232, 13, 44,108,196,177,172,227,188,193, 37, 92,169, 75,105, 8,109,150, +208, 16,219,109,131,209, 13,161, 0, 37,180,228,147,128, 7, 82, 79,114,117, 72,146,163,205,129,140, 14, 81,216,140,129,158,184, +237,223, 94, 84,177,158,216, 4,224, 31, 32, 73,237,246,107,233, 9, 80, 79, 50,129,198, 79,194, 64, 35,215, 61,126,205,109, 95, +111, 47,109,189,216,170, 85, 2,233, 91,105, 10, 6,221, 0, 3,160, 30,158,131,165,177,229,212,133,160,131,128,125,112, 51,211, +236,243,208,105, 11,230, 60,201, 8,109,191,139,226,248, 78, 71,159,207,251,116,122, 20, 20, 50, 7,145,200, 61,199,151, 95,191, + 67,169, 36, 55,151, 49,215,161,201, 4,252,137, 0,246,233,161,179,111,219, 6,177, 6,221,251,126,255, 0,227,138,110,123,186, +192, 82,130,150, 8,200,194, 73, 3,182, 73, 31, 61, 75,227,232,215,112,195, 99,223,219, 35,198, 38,227,110,133,131,105,238, 13, +175,184,202,183,248,125, 93,173,121, 80, 32, 92, 54,253,118,207, 69, 45,203,170,246,167, 78,131, 84, 97,109,174, 60,137,213,122, + 35, 78,132,242,171, 48, 16,160,164,173,180, 40, 68, 24,149,143, 8, 54,158,138, 74,147,205,144,144,181, 99, 24, 3, 29, 15,109, + 77,123,217,103,184,103,103,189,143,246,187,116, 6,164, 81,171,123,149,186,219,227, 85,173,205, 79, 52,105,170,164, 82,174,168, +214,139, 78,199,144,180,167,195,143, 48, 82, 93, 67, 79,160,169, 10,102, 26,210,135, 57,138,185, 98,156, 99,155,193,146,101, 73, + 89, 80, 12,138, 37, 10,177,139, 6,150, 66,173,201,141, 9,232, 76,161, 9, 36, 16,136, 25,200, 33, 72,197,129,225,126, 86,115, +110, 47,162,164, 72,185,210,136,228,101, 7,117,187, 20,132,234,244, 26,101,111,190,214,223, 28,193,223, 63, 97, 79, 4,115,184, +194,185,209,179, 27,239,185, 54,175, 14,116,135,150, 47, 93,165,163, 83,105,149,186,237,191,122,205, 66,164,162,196,218,237,215, +185, 31,144,220,155, 36, 48,243, 62, 60,137,208, 39,207,167, 56,164, 69,140,229, 65, 78,120,204,111, 6,212,251, 26,125,155,123, +125, 58,216,185,109,203, 55,136,138,110,227, 80, 37,198,122,216,220, 26, 55, 21,119,221,175,121,219,245,200,177,194,145,114, 81, +170, 86,149, 42, 2,105, 21,166,212, 60, 80,227, 40, 75, 45,172,132,134,150,223,194,108, 27, 71,113,203,157, 91,184, 42,197, 34, + 81,147,122, 93, 21, 71, 34,115, 36, 46, 82,152,170, 10,100, 82,181,243,128,150,154, 17, 84,177,200, 6, 11,105, 81, 80, 1, 58, +222,155, 74,229,118,163, 38,164,121, 90,136,212, 8,204, 83, 34,180,202,131,110,158, 98, 36, 84,159, 83, 97, 28,172, 45, 43, 91, +109, 37, 72,230, 95, 43, 74, 4,164,144, 53, 71,103,220, 99,198,175, 58,200,217,245, 68, 48,132, 0,197, 3,242, 22,221, 8, 44, +154,100,147,169, 93, 83,188,174, 86,218,156,144,111,212,220, 79,225, 79, 9,228, 78,100,161,201,225, 89, 2,172,143, 33, 82, 89, +164,178,130,234, 9,180,107,204, 58,149, 35, 85, 80,157, 55, 14,113,212,219, 99,136,234,228,106,101, 18,155, 87, 66, 43,171,106, + 35, 20,230,230,213, 86,165, 86,106, 81,233,145,219,143,245,157, 94,162,202, 82, 39,213,158, 8, 74,228, 72,240,144, 31,125,213, +185,225,160,171,151, 78,181,189,187, 22,141,226,232,140,220,143,169,234, 75,115,193,110, 28,247, 27, 75, 82, 94,236, 27,137, 40, + 30, 71, 22, 72,232,147,202,162,122, 0, 78,185, 81, 30,244,240, 36, 85, 11, 97, 75,143, 66,134,205, 38, 36,144,114,151,170,110, +182,100, 75, 96, 4,171,162,144,234,163,165, 65, 32,245, 74,178, 8, 26, 10, 61,219, 41,136, 17,203,239, 31,124,142,204,154,156, +175, 13,210,158, 95,136, 52,201,108,142,169, 62, 50,148,126, 69,191,150,148,202,184,199, 54,167,208, 37,169, 53,106, 7,153,101, +243, 27, 0,162,250,143,152, 27,234, 59,146, 0,182,199, 21,248,142,186,130, 68, 16, 73,204, 22, 91,197, 37,200, 58,148,200, 0, + 63,105,108,186, 23, 99,179, 29,212,244, 27,233,106,113,119,182,151,183, 20,183,231, 10, 22, 90, 95,184,110,205,174,179, 85,117, +110, 45,213, 17,214, 92,183,173,234,168,126, 51, 38,204, 66,193,230,145, 91,105, 50,153,247,130, 7, 35, 78, 18,214, 74,210,172, +108,130,235,136, 99,157,106, 88,230, 57, 24,206,126, 30,184, 29,122, 99, 35,174,184,239,193,253,153,180, 27, 99,196,214,228,110, +244, 17, 42,218,187,248,132,179, 97,219,181,104, 40,144,201,180,230,222, 73,172,174,167, 38,226,195,235, 46,192,175,213,208,195, +104,125, 33, 94,236,228,180, 23,194, 91,114, 74,129,232,125,205,113, 42, 50,221, 64,113, 73, 41, 74,147,200, 62, 21,165,105, 39, + 60,201, 61,142, 2,178, 62, 90,181,184,106,180,102,212,111, 59, 48, 18, 60,132, 50, 0, 46,130,202, 66,144, 55,247,134, 61, 71, +223,105,215, 25, 75,194, 85,210,100,173,193,144,212,211,209, 46, 91, 68,149,130,172,222, 99,154, 8,239, 94,118,188, 98, 35, 41, + 2, 1, 17,229,242, 66,157,152,184, 14,149, 74,248,109,178, 71,136, 2,123,168,115, 2, 14, 14, 57,186,118, 32,228, 31, 62,191, + 45, 97, 51, 47, 98, 23,151, 29, 87,134,165, 30, 85, 12,144, 73, 56, 9, 36, 28,115,140,128, 50, 48,190,217,242,214,190, 84,238, +181,120,174, 53,206, 10,138, 20,251,121, 81,248,208, 14, 28,111, 62,153, 35,167,145, 94,177,148, 93,188,217,104,175,152, 41, 36, +165, 46, 12,115, 32, 15,137, 25, 36, 18,180, 96,127,181,202,144,175, 93, 74, 99,129, 80,108,110,126, 63, 15,221,249,252,113, 22, +167,164, 88,198,195, 87, 75,254, 23,239,215,227,252,142, 54,149,187,161, 46,158,100,184, 10, 85,203,158,101, 4,148,156,144,121, +194,199,192,114, 21,229,141, 90, 42,114,158, 91,107,145, 76, 8,113,208, 10,213, 17, 74, 45,161,212,100,229, 76, 41, 32,144,224, +234,174, 78,161, 92,159, 14, 20,113,166, 18, 37,213,201,202, 92,120, 40, 0, 57, 92, 36, 41, 65, 39, 56, 67,160,145,146, 15, 76, +158,152, 57, 32, 19,157,102,144,110, 4,175,225, 82,207, 50, 70, 72, 4,148,117, 57,200,207, 83,144, 6, 64,237,203,243,234,149, + 69, 58, 78,154, 36, 23,244, 61,193,236,111,235,211,249,140,110, 67, 81, 45, 20,162,104, 13,237,177, 83,114,174, 63,101,198,215, + 30,253,136,189,193, 83,190, 47,109,215,101,185,200,130,228,102,194, 92, 90, 75,164, 58,231, 42,146, 73,229, 80,113, 35, 60,189, +138,136,248, 74,128, 86, 58,234,234,212,199,221, 1, 78,200, 88, 33, 68, 16,142,102, 27, 82, 21,132,242, 40, 55,146, 82,112, 59, + 17,133, 39, 33, 64,231, 88, 13,198,183, 11, 6,169, 79, 9, 91,204, 2,185,108,130,176,149,181,132,149,201, 71,135,250,206,161, +180,146,226,123,173, 0,158,139, 29,113,232,181,233,174, 28,169, 77,128,142, 71, 27, 45,169,120, 83, 43, 79, 55, 50,121,143,249, + 64, 84,147,211,161, 24,193,202,134, 98,211, 43, 81,204, 98,153,246,107,216,216, 88,131,109,238, 59,250,223,241, 6,248,157, 80, +188,121,165, 42,212, 83, 34, 68,192,217,212,145,169, 24,117,235,185,235,117, 35,175,186,197, 67,227, 22, 64, 10, 60,141,168,243, +128, 10,146, 74,212, 91, 65, 32, 37, 74, 41, 42, 91, 32,227,252,152,234, 9,207, 49, 35, 87,149, 84, 92,140,217, 90, 25, 74, 60, +117, 4, 33, 47,165,213,199,195,201, 42,109,160,129,149,198,144,226,142, 19,206, 49,147,240,163,148,243,105,158,139, 82, 82,138, + 1,113, 92,142, 19,203, 33,183,156,229, 70, 87,204,203,109,242,184,163, 29,174,101,225, 33, 28,203, 82,148,148,148,231, 35, 87, +196, 84,214,134,138,188, 73, 40,112,151,217, 83,209,203,109,180,180,164,252, 94, 34, 22,162,183,100,103, 28,223,168, 83,130,148, +143,136,157, 47, 28,195,190,192, 88, 95,247,119,235,183,190,247,177,191, 77,244, 42,224,209,114, 95, 93,183,232,119,183,196,245, + 29, 59, 16, 63, 12,178,167, 82,117,101,214,158,116,143, 5, 24, 90, 23,206,135,176,149, 30,171, 28,152, 67,133,148, 37, 68,130, + 72, 82,136,233,216,106,111, 20,187,199, 75,216, 78, 31,183,187,123,107, 14, 3, 11,107, 54,178,243,187,194, 90, 57,118, 69, 74, + 29, 37,232,118,227, 17, 80,181, 15, 26, 67,151, 45, 70,140,218, 83,159,252, 98,186,121,105,253,153, 86, 47, 7, 9,115, 32, 43, + 45, 41,124,222, 48,200, 88, 62, 39, 83,200,159,140,117, 57, 42,192,233,231,168,229,253, 33,126, 36,209,101,112,247,183,156, 51, + 81,166, 20,220,123,253,118,139,190,234,105, 14,114,189, 19,107, 54,170,107, 47, 14,101, 54,172, 24,245, 77,192,149, 76,140,166, + 92,229,230,106,223,125, 65, 36, 5, 99,118,157, 26,170,122,122, 52, 39, 85, 75, 0,125, 66,117,118, 29, 62,202, 6, 59,122,116, +190,198, 41,159, 87,166, 83,147,230, 89,163, 16,134,138, 38,100,189,183,152,128,144,169, 29,124,210,178, 41,223, 96, 73,219, 16, +244, 92,153, 82,150,236,202,131,161,234,140,247,159,157, 80,125, 32, 97,234,132,215,151, 38,107,224, 96,116, 92,167, 94, 87,207, +155, 66,172,131,211,207, 61,115,246,127,110,136,115,169, 29,135,115,161, 87,230,174,152,245,239,216,121,254,124,181,105,160, 0, + 11,108, 63, 45,182,199, 34, 42,236, 13,205,207,174,253, 14, 6, 86, 50,113,249, 63, 47,150,135, 81, 10,242,192,235,159,159,204, +250,104,133,250,130, 20, 72,252,244, 26, 21, 71,161, 62,125, 79,223,165, 20, 18, 70, 21,192,234, 32,117,249,224,103,231,246,124, +180, 51,131, 57,234, 1, 4,245,209, 90, 17,194, 14,122,247, 57,199,203,231,165,199, 81,129,129, 85,211,167, 82, 79,115,242,244, +199,166,116, 42,200,207,108,117,199,219,215,207, 68,185,242,238, 7,159,111, 95,223,160,150, 79,126,152, 61,193,243, 61,127, 63, +118,148, 65, 97,210,247,249,255, 0, 92, 12, 82, 36, 2,122,129,247,254,255, 0, 61, 45, 81, 95,235,119,242,252, 62, 95,159, 93, + 45, 31, 3,108, 86, 29,251,103,229,162, 52, 42, 87,219, 61, 15,145,199, 76,131,229,170,129, 68,158, 94,108,116,207,111,159, 94, +190,189,244, 71, 2,221,108, 70, 14,195,173,190, 63,195, 7, 54,123, 21,125,223, 63, 67,162, 7, 95, 35,246,121,232, 38,240, 58, +100,147,243,252,247,254,173, 22,149,245,244, 62, 94,126, 95,102,146,193, 58,116, 56, 41,161,203,212,156, 99,200,252,243,216,104, +214,200,243, 0,253,248, 39, 64,165, 89, 29,191, 17,231,231,131,157, 86,108, 20, 44,168,172, 16,172, 1,159, 47,179,238,210,109, +233,109,135,242,198,113,112, 10,193, 1, 67, 4,249,129,223,237, 35,243,215, 68,167, 3,168,200, 39,161, 29,191,102,122,118,208, +169, 81, 32, 12, 12,140,119,237,140, 1,140,143, 60,232,128,172,100,156,100, 96,228, 96,147,246, 99,229,253, 58, 79, 24,193,141, +168,119, 61,113,211,239,233,131,248,104,132, 28,224,245, 56,235,243,233,235,143, 45, 0,133,103, 3,168, 4,250, 14,255, 0,105, +213,126,108, 17,133, 41, 57,207,234,250,255, 0,195, 72, 55, 94,183,198, 45,251,240, 96,194,212, 65,206, 15, 99,156, 99,167, 83, +223,166,178,107, 86,133, 46,228,174, 83,168, 84,230,131,242,231,203,102, 43, 41, 89,195, 69,215, 20,122,190,224,255, 0, 37, 29, + 13,165,110, 56,175,230,182,210,136,235,140,226,141,149,172,148, 40,242,164,140,243, 0,115,229,231,167, 83,107,106,201,163,215, + 27,102, 59,168,106,161, 80, 68,168, 17,165,168, 14,120,254,244,202,121,148,223, 55,119,212,203,110,165, 63, 53,159, 44,231, 74, +177,164,138,154,105, 34, 0,200,138, 72,248,250,159,147,183, 77,240,231,146,208,195,153,231, 25, 94, 91, 81, 57,166,167,174,158, + 24,157,199, 85, 87,117, 86, 43,125,181, 16,108,183,219, 81, 23,218,248,222,138,101,205,111,109, 53,188,139, 14,206, 6, 92,185, +106, 97,219,158,165, 20, 33,169,181,218,147,105,229, 75,211,229, 39,172,106,107, 74, 42, 76, 88,249,229,105,177,148,165, 78,169, +197,168,202, 52, 58,189,201, 45,107,152,251,134, 43,136,241, 26,136,133, 56,212, 96, 73,206, 22, 82,160,183,187,255, 0, 56,129, +159,230,233,172,181,109,231,101, 77,113,174, 96, 84,151, 11,234, 90,143, 58,214,238,114,165,184,181, 28,173,106, 39,185,234,115, +211,167, 77,109, 61,163, 22, 44, 22, 27, 91,137, 83,171, 74,128, 82, 1,207,234,158,188,201, 56, 29,255, 0, 15,232,173, 43,102, +142,152, 57, 86,230,207, 39,153,152,245, 98,109,185,219,238, 30,131, 97,176,176,238, 92,135,135, 96,160,165,130,158,154,139,217, +233,169,194,164, 80, 40,217, 20, 91,173,247,102, 39,119, 98,117, 51, 18,204, 75, 18,113,157, 88, 27, 77, 6,162,243, 10, 91, 45, +173,210, 17,204,134,249,192, 79, 80, 63,214,237,246,249, 13,116,123, 98,182, 58, 4, 74,205, 30,167, 79,136,195, 21, 8,242, 27, +109,110,132, 5, 41, 73, 87,235,167, 43, 4, 56,130,140,228, 96,131,208, 99, 90,225,182, 40, 67,142, 48, 16,148,176,211,139,108, +165, 13,164, 41,196,146, 1, 0, 28, 0,122,103,200,227, 93, 65,218,186,205,175,107,194, 23, 45,203, 58, 29, 22,218,182, 96, 72, +174,220,149,170,131,237,177, 22,155, 74,165,199, 84,185,211,101,200,116,132,182,210, 35, 52,242,142, 78,112,156, 0, 78, 6,171, + 12,238,173,234,222, 88,228,156,164,106, 9, 35,215,160, 2,195,177, 61,189, 58, 92,224,103,185,230,105,150, 32,167,167,102, 26, +193, 82, 7,165,183, 6,219, 90,219, 1,190, 56,205,197,103,181,207,127,173, 13,203,184,118,215,133,170,141, 31,104,108,203, 18, +227,169,219,114,110, 38,173, 59,114,175,120,222, 85,138, 12,199, 41,181,154,156,153, 53,154,123,241,232,148,133, 84,163, 74,110, + 60, 86, 88, 82,220,105,176,227,238,146,190, 68,232,182,233,123, 64,184,141,223,154, 60,154, 6,249, 57,181,123,167, 78,146, 84, +227, 18,107,187, 67, 98, 81,110, 42,116,165, 0,145, 34,159,117,218,148,120,114, 99,114,227,163,101, 42, 70, 84,115,229,173, 86, +221,155,170, 61,231,185, 27,133,121, 69, 66, 4, 43,174,251,188, 46,104, 37,150,148,210, 87, 78,184, 46,106,173, 86,152,226, 26, + 95, 86,138,160, 76,140, 84,147,241, 37, 74, 32,128, 65, 26,194,202,138, 27, 72, 66, 66,146,164,249,147,216,250,231,207, 87, 69, + 31, 7,240,224,142,134,170,163, 33,165,108,202, 5, 70, 19,180, 17,154,132,144, 1,186,205,167,154,132, 27,219, 75, 46,158,139, +101,216,113, 46,113,196, 25,150,101,152,213,213, 75, 88,211,164,146,185, 69, 33, 74, 4,212,116, 0, 45,109,150,194,253, 77,174, +196,146, 78, 25, 29,226, 14, 57,121,205,113,232,130, 3,142,211,225,184, 35,161,210,251, 60,158, 24,194,153,113, 74, 39,194,232, + 48, 51,240,246,211,245,236,251,162,194,185,248,143,179, 45,121, 83, 19, 21,250,213,203,107,181, 9,165, 71,118, 87,191,186,213, +102, 27,130, 3, 81,152, 66,148,243,239, 41, 41,105, 3, 24, 5,238,101,124, 41, 58,101,247,161,159, 22,181, 69,168, 39, 42,110, +109, 13,166,193,234, 48,228,124, 36,164,245,239,145,174,129,251, 9,174,186, 5,165,237, 66,225,233,203,134,153, 75,169,179, 93, +122,232,183,105,102,171, 29,185, 77,211,107,245, 27,114,161,245, 77, 90, 19,110,130,148, 84,153,121,149, 6, 86, 70, 82, 94, 37, + 63, 16, 4, 76,106,145,166,225,202,216,163,115, 19,154,118, 0,141,244, 17,182,175, 48,111,179,107,216,131,211,124, 55,240,245, + 50,102,121,237, 29, 36,238, 33, 74,218,128,140, 64, 27,115, 13,172,189, 64, 38,246, 91,130, 3, 17,112, 70,216,253, 60,108,203, +170, 61, 38,218,163, 69,169,210,215, 6,123, 52,168, 12, 42, 18, 30, 74,149, 13, 45,197,109, 30, 2,136,232, 84,156, 96,142,195, + 24,211,173, 99,205,135, 95, 67,163,195, 82,216,105,226,174, 71,124,148,149, 2, 51,235,129,141,105, 44, 90,227,175,203,110, 58, +159, 60,234,145,200,227,139, 86,113,133,225, 74, 81,201,236,156,159,187,231,170, 28, 4,113, 50,246,254,220,188, 78,211, 27,167, +174,157, 67,217,253,200, 98,198,160, 62,226, 84,149,213,154,110, 59,134, 85, 65, 74, 80,193, 38, 67, 46,128,145,156, 36,167, 56, +206,171,117,160,130,138,122, 97,237, 82,206,210, 2,164, 74,193,245,233, 0,234, 42, 2,170,144,127,100, 1,189,173,233,213,116, + 57, 94,103,152,229, 89,246,102,140,213, 17,228,201, 12,179, 73, 36,128, 58, 9,234, 18,153, 52, 40,182,162,210, 72,183, 8, 0, + 85, 5,141,128, 24,234, 84, 22, 97,190,160,211,140,160, 37, 73, 9, 37, 39,151, 35,203, 4,118, 61, 53,114,153, 78,153, 71,107, +235, 40, 14, 61, 50,158,222, 60, 88,104, 36,186,207,108, 43,161,248,155, 29, 63, 29, 97, 20,201,202, 47,103,152,116,235,202, 79, +126,158, 94,167,229,242,211,203,110,200,247,142, 86,186, 45, 43, 28,139, 74,199, 69, 36,140, 40, 28,142,185,211,232,142, 26,149, +210,124,143,250,172, 54, 32,246,233,212,123,143,108, 87, 57,193,168,203, 88, 74,126,186, 30,174,140,110, 24, 27, 95,115,186,183, +163, 11, 88,251,182, 38, 90,149,147, 81,103, 43,113, 42, 36,101, 41, 4, 97, 63,236,131,246,106, 57,159, 74,191,116, 98, 90,254, +207, 59, 39,109,189,229, 13,212,183,107,126, 44,232,173, 70, 10, 79,139, 34,151,103,194,170,220, 21, 37, 33, 4,228,182,151, 83, + 3,152,129,211,196, 79, 81,158,178, 30,102,146,109,219,145, 41, 96, 40, 65,169, 43,197,142,145,209, 8,117, 68, 7, 25, 3,237, + 80, 32,127,181,168, 24,253, 41,190, 42,105,187,177,198, 54,217,240,225,110, 85, 81, 54,139,195,101,145, 34,125,214,152,206, 7, + 99,181,184,187,128,182, 37, 59, 9,124,170,199,189,197,183, 98, 83,146,176,122,161, 83, 8, 58, 74, 58,202,145, 17,201,101, 26, +102,168,170,131, 88,244, 90,105, 22,173,158,223,176,226, 5,136,155, 90,243, 32,234,192, 98, 1,158, 71, 76,139, 85, 95, 79,189, + 36,176, 18,155, 91,205, 48,228,232,235,246,147, 91,189,183, 39,148,198,196, 2,113, 23,105, 12,224,142, 92,114,128, 57,115,230, + 60,193, 31,158,218,166,220,116, 96,148,167, 35,185, 0, 30,135,231,131,219, 70, 58, 91,112,228,147,129,219,200,129,212,245, 26, +163,239, 1,162,164,182, 58, 16, 2,148, 48,123,246,233,248,234, 69,123,110, 78,199,253, 49, 95,238,192, 91,182, 41,184,218,146, +112, 2, 85,145,205,128,115,240,232,117,175,166, 2,185, 84,122,144,123,252,146, 48, 58,249,126, 26,246,165,183,205,207,226,242, + 41, 68, 0,146,160, 57,188,186,141, 8,236,164,182,248, 10, 66, 79, 40,192, 24,234, 78, 51,205,246,235, 5,182,178,131,140,233, + 61,206, 62, 37, 37,100,130, 84,143, 85, 20,247,251, 9,215,196, 52,218, 22, 28,108, 23, 20, 73, 10, 73, 32, 16, 58,117, 3, 29, +117,111, 83,203,146,247, 41,116,161,190, 96,162,140,245, 64, 79,113,246,247,209,173,134,220,112, 58,130,174, 68,156, 21, 96,167, + 56, 29,142,124,186,235, 23, 38,226,214,237,108, 24, 0, 8,223,231,108, 84,202, 80,181, 45, 75, 37, 10,236,140, 14, 84, 19,208, + 21, 19,249,206,145,240, 91, 89, 35, 4,168, 2,181, 39, 36, 1,143, 63,207,219,175, 14,180,248, 91,135,225, 44, 44, 19,203,230, +113,158,202, 35,190,147, 72, 75,188,184, 10, 97,180,167,149, 94,101, 68,116,193,200,235,219, 67,113,176,234, 62,253,255, 0,241, +140, 88, 27,158,199,247, 99,223,138,128,176, 16, 74,202,192,200, 64,234, 51,216,159,151,174,144, 56,112,168,255, 0,226,210, 65, + 39,211,169,193, 30,191,219,161,201, 91, 97,101, 11,229, 33,124,169,112,164, 97, 67, 25, 41,193, 29, 62,221, 18,149, 30, 64, 28, + 41, 83,138,201, 81,233,203,131,211, 7,167, 95,158,178,160,129,238,248, 99, 4, 11,219,211,111,159,187, 23, 91,122,216,174,223, +151, 45,171,103, 91, 30, 48,173, 94, 23, 45, 2,211,161,169,134,124,101,166,185,117,214,160,219,116, 71, 18,206, 63, 72,148,213, +170,176,202,135,110, 84,156,234,116,188, 70, 90, 86,214,200,237,141,191,195,253,145, 22, 45, 26,196,217,203, 30,212,219, 59,118, +140,216, 15, 52,105,182, 85, 52,210,220,144,228,146, 7,188, 57, 58,187, 14,173, 81,121,213,101,199,100, 86,221,117,213, 5,175, + 81, 5,246,122, 41,151,120,231,225, 49,165, 45,167, 25, 70,253,237,171,138,109, 68, 6,138,152,185, 35, 72, 66, 58,164,128, 60, + 86, 81,140,142,248, 24,212,167,184,174,185,213, 80,146,133, 73, 46,189, 42,116,101,176,243,171,116,136,206,165, 92,181, 24,242, + 29, 66,122, 56,175,137,244, 12,128,174,102,202,115,202, 19,170, 83,197, 9,101,168,206,184,107, 46, 36,242, 99,215, 57,177, 27, +176, 33,119, 7,246, 0,242,159,241,145,183,126,148,250, 56,229,176,205,157, 87,230, 36, 3, 52, 82, 67, 18,237,186, 42,142,113, + 96, 78,222,114, 22,253,238,138, 65,198,134,236,221,125, 48,227, 85,230, 51, 33,182, 20, 46,139,193, 78, 71,146, 11,172,173, 49, +107,213, 39, 22,218,176, 65,104, 45,181, 17,240, 28,231, 10, 57,192,214,224, 91, 87, 56, 52,186,124, 87, 37, 60,195, 17, 27,114, +181, 86,168, 52,165, 33,208,211,232, 84,135, 35,180, 82,172, 45,194,149, 57,206, 62, 17,225,181,156,149, 19,174,110, 88, 21,191, +119,114,244,165,183,202, 67, 27,155,118,199, 87, 58,178, 4, 89, 50, 96,212,208,176,140,117, 30, 4,208, 18, 6,122, 47,168, 24, +193,216,148,220,233, 17, 19, 8, 58,234,126,185,152,195,115,214,218,208, 94, 77, 49, 13,178,244,133,248,196, 0,223,193, 29,180, + 33, 36,116, 68,133,242,242,101, 71, 81,250,188,185,106, 15, 67,113, 99,239,183,107,245,232, 9,183,107,219,224, 58,227, 63,165, +142,190,158, 48, 77,158,254, 98, 55,217,118, 36, 14,246, 5,200, 7,112, 64, 22, 35,166,219,210, 47,185, 82,233, 80,131,107,114, + 60,217, 83, 30,159, 55, 1, 97, 10,126, 99,143, 59,200, 93, 39, 36,248, 79, 52,216, 74,146, 85,208,149, 28,227, 87, 58,150,229, + 67,154,202, 4, 96, 35, 72,171, 77,110, 44, 73,100, 36,180,229, 58,157,136,136, 91,136, 10,230,111,157,193, 37,215, 17,208,101, +244,168,228,117,214,181, 64,187,158,122, 93, 82, 99, 15, 54,251, 37,214,153,128, 31,117, 72,105,199, 39,177,225, 23,146,164,156, + 48,194, 20,135,157, 91,128,140, 41,148,243,100, 17,156, 82,117,230,220,185,110, 46,150,234,204, 86,210,213, 38, 18,207, 68,178, +246, 20,194,221,232, 57,159, 45, 69, 67,133, 75, 72, 8, 74,217, 4,243, 28,107, 65,114,134, 28,192, 19, 72,150,215,216,116,216, +247, 29,143,240, 35,215, 20,246,103,146, 44,245, 78,252,176,174,237,171, 80, 54,208, 8, 14, 67, 30,182, 4,169, 0,130, 8,141, +150,215, 27,108,165, 82,240, 65, 91,130, 60,226,182,132,167,101,192,151, 29,238, 83, 25, 20,197,120, 81,158, 74,218, 87,253,240, + 30, 74,156, 5, 56, 40, 82,144, 70, 78, 52,237, 90, 94,211,206, 31,238, 61,215, 87, 13,251,187,120,211,246, 99,125,216,166,219, + 53, 27, 46, 70,225,213,169,180,173,188,223,218, 29,126, 20,116,211,238, 11, 14,254,117,214,224,219,183,114,235, 2,165, 77,157, +110,215,151, 5,255, 0,172, 41,143, 26,124,233,201, 95,132,215, 47,235,155,134,253, 49,169,137,139, 33, 17,217, 13,120,112, 82, + 15, 49,240, 35, 44,163,195,112,169, 32,252,110,120,100, 14,255, 0, 6, 84, 78,117,197,111,105,134,220,238, 93,231, 65,219, 45, +247,167,109,213,197, 90,217,251, 58,155,114,237,149,225,186, 16,105,102,169,111,209,111, 26,133,206,237,223, 6,220,186, 37, 68, + 46, 57, 71, 74,105,117,120,239,199,126, 99, 76,195, 90,234,170,101,153, 10,125, 14,182,139, 3,128,178,227, 14,113,200,102, 49, +197, 94,146, 41, 26,186, 58, 14,100, 76, 1, 54,102, 4, 50,105,239,205,107, 48,109,241, 25,226,106, 58,222, 29,225,154,236,230, +154,152, 85, 54, 88,209,177,136, 41, 60,216,218,101,137,193, 42, 24,198,232,143,175, 85,138,168,137,139, 93, 73, 6,112,183, 37, + 78,163, 2, 75,208,150,135,161,212, 82,216,153, 17,169,141,173,151,176,166,195,172,115, 50,232, 25,142,243, 42,192, 88,248, 20, +135, 67,169, 82,146, 1,214, 30,110,102,229, 6,164, 37,229,248, 15,167,153, 14, 21,167,199,131, 45,149, 41,178,218,193,232,133, + 37,208,234, 20,133, 14,138, 74,146,161,200,172,136, 53,240,131,237,106,226,159,133, 24, 84, 59, 53,218,219, 59,239,178, 52,133, +176, 33,109, 62,233,213, 42,115, 87,110, 83,210, 19,207, 27,108,183, 21,133,187, 86,176, 89, 90, 16,222, 98,161, 83,232,235, 9, +248,233, 74,207, 48,145,223, 13,254,212,238, 15,184,152,159, 78,162,209, 47,183, 54,118,249,175,188,219, 14,237, 94,249, 74,164, +218,245, 37, 92, 79,169, 49, 99, 27, 63,112,216,112, 91,183,164,105,106, 74, 80,226, 84,253, 38,123,107, 83, 14,125, 94,162,183, + 66,108,186,204,183, 48,166,102,149, 71, 62,156, 30,169,168,233, 30,174,159,105, 0, 23, 14,192, 50,168, 43,245,131, 77,196, 95, +135,248,215,135,243,244,142, 40, 42,125,147, 48, 63,251, 60,246, 73, 9, 31,170,141,253,220,164,236, 80, 35,107,102, 86, 28,176, + 93, 65,235,149, 54,227,231, 82,252, 98,143,120,111, 30, 50, 3,153, 10, 74,242,148,190,207, 95,141,149, 1,219,201, 64,160,158, +157, 92, 10, 45,120, 41, 72, 30, 42,210,211,129, 60,138, 36, 39,194, 40, 56, 9,201,199, 34, 15,194, 82,125, 71, 47, 98, 51,173, + 78, 57, 42, 4,150,225, 74, 68,136, 85, 24,204, 38, 66, 27,148,194,153, 91,140, 60,112,210,188, 53,165, 42, 92, 71, 18,144, 65, + 31, 2,199, 43,141, 41, 93, 9,204,232,245,213, 45, 41,192, 82, 28, 24, 15, 5,245, 67,125, 1,240,211,143,214, 37, 36, 97, 93, +148, 8, 56, 7, 58,212, 89, 53, 45,155,126,155,250,244,189,247,220,131,214,195,222, 7, 80, 36, 83, 0,111,109,143, 66, 55,176, +233,219,176,244,244,232,113,182,208,103, 41,109, 2,130, 8, 28,170, 10, 7, 24, 72, 25,194,155, 35,170,130,179,216, 16,115,215, + 3, 58,111, 43, 10,114,143, 57, 62, 8, 83,116,247,138,158,104, 35, 42,247, 7, 50, 75,237, 35, 36,226, 62, 87,206, 17,241, 16, + 21,132,140, 32, 1,125,182,231,180,168, 76, 58, 9, 40, 84,116,130,133, 30, 98,133, 5, 4,164,144,145,213, 29,122,131,213, 61, + 0, 36, 29, 13,118, 6,157,142,165,164,161, 74, 66,131,137, 36, 16, 75,137, 11,198, 66, 58, 1,225,133,117, 7,177,199, 76,105, +179, 52,167, 21, 20,206, 20, 94, 88,188,203,247, 14,159,247, 13,175,219, 99,141,204,138,188,229,245,233,172,222,154,164,132,144, +123,143, 71,223, 96, 84,155,244, 59,106, 94,135,127, 84,218,177, 40, 8,109, 77,171,152, 21,173,176,163,224,169, 71,153, 72,125, + 10, 73,232,160, 71, 80,122,228,147,140,224,235, 37,102,160, 10, 82,164,185,132, 45, 57, 74,215,202,149, 96,228, 37, 5, 93, 73, + 30, 65, 68,115, 96,128, 73,233,134, 98,157, 41, 13, 56, 75, 78,101, 30, 32, 41,200, 60,139,109,106, 31,174,223, 79,137, 36, 30, +189,207, 76,140,117,214, 72,221,101, 45,182,162,165, 36, 32,100,243, 41, 75, 81, 70,115,204, 0,245,193,235,219, 60,157,117, 24, +134, 67,166,254,131,225,214,223,195,240,185, 63, 9,141,122, 6,118, 85, 58,239,247, 92,246,191,191,212,255, 0,166, 51, 26,229, +207, 71,161, 82,171, 21,250,253, 86, 21, 10,222,160,210,170, 53,218,245,110,162,164,183, 78,161,208,104,176,228, 85, 43,117,153, +206, 45, 73, 9,137, 18,151, 18, 91,238,228,225, 72,142,160,158,165, 57,252,241,248,236,226,198,175,198,143, 19,187,139,190,210, +211, 34, 37,167, 54, 67, 54,134,209, 80, 36, 40,149, 91,187, 67,106, 59, 42, 29,153, 29,224, 82, 63,247, 86,123, 78,203,172, 84, + 21,128,163, 54,224,117, 10,232,210,117,219,143,110, 55, 31,168,247, 9,220, 13,237, 45,117,106,153, 60, 65,155,196,245,118,153, + 33, 73,250,186,148,129, 22,167,110,108,123, 50,218, 88,204,249,174, 8,181, 59,157,180,158,102, 99, 49, 2,144,247, 42,222,154, +216,140, 58,201, 42, 87, 55, 92,245, 24,242, 62, 93, 51,208, 99, 86, 23, 10,101,174,168,115, 74,133,179,204,161, 98, 4,110, 35, +184, 38, 79,255, 0, 83,109, 63,224, 1,129, 34, 76,115,135,139, 28, 75, 29, 69, 68,124, 51, 69, 46,168,168, 95, 93, 91, 41,184, +105,192,178, 67,126,252,133, 36,200, 55,250,214,208, 64,120,119,164,226,207, 66, 6, 58, 99, 61,253,127,110,168, 40,146, 14, 79, +145, 3,176,234,117,236,175, 32,140,119,245,254,173, 14,178, 50, 7,166,115,251, 53, 54,197, 56, 6,195,215,223,143, 26, 25,222, +163,190,112,127,103, 95,199,190,136, 80, 4, 28,249,117,233,242,208,171,236, 62,223,191, 74,170,144, 55, 30,252, 27, 3,172, 12, + 19,233,219,241, 26, 21,194,122,100, 96, 15, 50,122, 99,167,203, 68, 45, 88, 7,168,198,127, 12,119,207,207, 39,246,104, 39, 14, + 65,238,122,244,207, 92,117,243,209,240, 49, 73,194,122,158,135,167, 78,221,191,225,160,214, 70, 49,230,127,175, 85,214,124,179, +246,254,237, 12,162,115,131,131,230, 15,203, 74,168,176, 3,231,255, 0, 56, 24,164,161,156,124, 57,251,241,165,175, 42, 81, 4, +128,123,105,104,248, 61,215,161,234, 61,195, 9, 4, 17,131,140,142,223,159,183, 85, 65,193, 7,254, 56,208,233, 56, 57,252,117, + 84, 28,245,242,237,243,207,245,104, 16, 14,221,176,115,176,176,216,246,251,173,130,144,113,212,117, 31,209,147,251, 52, 64, 81, + 7, 3, 57,199, 92, 12,227,237,208,169, 35,151, 56,237,220,122,227,174,171,161, 97, 64, 96, 17,233,247, 31,233,206,144, 35,125, +251,225, 50, 15,218,181,186,127, 44, 28,217, 61,137,207, 79,219,211, 69,160,115, 4,228,115, 96,228, 12,227,183,110,191,142,129, + 66,176,164,143, 53, 1,246,117,209,136, 61,199,167, 81,162,144, 13,182,219, 5,193,232, 56,201, 61,187,103,231,233,170,157, 57, +128,201,237,219,190,122,158,195, 61,244, 58, 14, 70, 85,219,229,220,254, 78,137, 78, 6, 9,248,142, 58, 30,199,229,215, 73,176, + 32,251,176, 49, 85,178, 80, 71, 49, 24, 29,179,128,122,159,234,206,170,161,228,172,227, 5, 63, 51,208,106,130,129, 57, 36, 12, + 43,246, 12,103,250, 53,245, 33, 41, 28,169, 39,168,200, 39,169,243, 62,154,215,113,110,214,192,193, 69, 75, 80, 41, 11, 40, 72, +242, 79,235, 44,117,198, 14,142,138, 84,193, 74,208,181,165,208, 82,164,172, 44,165,214,212,133, 5,182,227,107, 79, 84, 56,149, + 0, 82, 71,108,122,116,213,184, 21,116, 32, 12, 36, 16,175, 92,121, 99,240, 58, 41, 11, 82,192,198, 50,156, 1,158,159,143,207, + 73,144, 8, 32,238, 14, 5,200, 32,131, 98, 8, 32,251,198,227,247, 28,108, 53,141,190,213,107,108,134, 43,180,182,171,204,124, + 41, 19, 35, 60,136, 85, 18,145,128, 11,205,175, 13,186,160, 60,210,164,149, 28,156, 13,108,141,181,197, 54,220, 70, 82,197, 66, +151,116,195,121, 72,202,146,221, 49,185,109,229, 32,244, 75,141, 75, 60,221,199, 95, 93,115,201, 4,164,124, 94,189,207, 82, 7, +168,253,186, 37,176, 66,144, 22, 84,164,142,169, 32,227,161,236, 8,243,244,251,245, 28,174,225,188,174,181,153,164,137,162,103, +235,203,114,160,244,191,151,117, 31,114,140, 91,121, 55,141,220,125,147,211,199, 74,107,169,243, 88,225, 80,170,107, 41,214, 89, + 52,139, 90,242,161,142, 87, 35,177,119,115,110,248,235,133,191,199,206,218,219, 45, 52,170,125,157,118,214,229, 55,146,132,186, +136,148,166,213,201,219,244,179,102,224, 18, 71,250,170, 3, 29,180,196,241, 5,199, 86,232,111,197, 1,251, 8, 50,221,147,182, +143, 56,211,211,237, 58, 60,167,100, 74,185,156,140,226, 94,138,213,215, 87, 83,109,251,229, 61,183,144,219,158,226,195,104,140, +227,141,161,111,151,249, 82,145,162, 3,148,130, 92, 5,192, 20, 20,148,231,148, 55,212,227, 4, 14,186, 61,162, 86,176,146,225, + 80, 56,228,194,113,201,219,161,207,235,116, 56,211,117, 47, 5,112,245, 21, 84,117,201, 69,207,170,132,134, 71,149,218, 77, 12, + 8, 33,149, 73,229,134, 82, 46,173,163, 82,145,169, 72, 32, 28, 53,241, 15,138,188, 97,196,116,243, 82,213, 84,195, 69, 77, 80, + 10,200,180,176, 44, 69,212,245, 83, 35, 25, 38, 10,219,134, 85,145, 85,193, 42,192,169, 32,158,135, 75,235,241, 20,165,243,156, +130,149,228,227,191,234,252,191,175, 69, 53,226, 20,169,146, 9, 42, 80, 87, 50,134, 0, 79, 79,192,118,208,142, 44, 52,130, 84, +175,137, 56,248,146, 49,143, 64,122,117,233,170,145,222, 81, 66, 66, 73,248,178, 73, 87, 82, 79,108, 12,246, 29, 53, 36, 61, 54, + 29, 62, 70, 43, 94,183, 35,123, 91,175,205,241,136,238,148, 54,166, 91, 20,250,139, 88, 47,209,166,170, 59,233, 79,254, 76,255, + 0, 80,172, 99,160,230, 39,240, 58,198,120,103,221, 57,187, 25,196,150,199,238,244, 21,134, 94,176, 55, 62,210,175,186,181, 28, + 15,112,143, 87,142,138,146, 84,113,217, 84,215,101, 39,255, 0,165,167,117,218,108,106,205, 62,177, 68, 90, 2, 93,157, 79,120, +165, 71,245, 68,134, 82, 86,218,243,228,123,254, 61,245,167, 85, 38, 11,109,188,210,135,233,152, 91,140,184,160,122,120,145,212, + 83,145,142,255, 0,171,251,117,187, 66, 18,104,170, 41, 36,251, 18,234, 83,255, 0, 68,162,196,254,253, 93,251,227, 20,149, 82, +101,249,133, 45,100, 91, 73, 4,145,202,189, 62,212,108,174, 63, 16, 49,250,180,211,238,200,245, 37, 67,171,211,156, 15,194,174, + 65,129, 89,167, 45, 4, 20,189, 10,173, 21,153,145,214,133,121,160,178,242,122,249,231,190,180,239,217, 89,188,242,168, 28,101, +113,223,195, 53, 74,165, 21,248,241,110,200, 59,151,105, 48,148, 54,212,150, 99, 85, 66, 25,171, 70, 90,211,133, 72, 8,121,198, +149,215, 37, 35, 61,129,214,138,112,241,237, 18,181,246,247,217, 85,195,199, 23, 55,221,185, 92,188, 87,110,170,222,216,155,158, +135, 70,113,168, 85, 74,133,213, 66,154,237,182,137,209,228,212, 2, 90,247, 81, 18, 12,119,150,178,172, 40, 40,165, 36,172, 99, + 92, 76,225,195,218, 43,112,108,191,180, 68,241,163, 87,137, 53,218, 13,213,121, 85, 13,251,109, 69,117, 79, 59,252, 93,220,210, + 61,214, 85, 57,148,140, 9,179,169,240, 12, 87, 90, 24,253, 35,176,207, 39, 85,140,213, 94,201, 95, 89, 89, 81, 50, 68, 88,229, + 41, 44, 77, 97,114,211,137, 33, 50, 70,130,251,177,141, 24, 11,126,210,130,124,216,234, 92,247,139,178,110, 30,135,135, 86, 26, +240,171,156,212, 69, 53, 68, 96, 18, 70, 89, 60, 14, 18, 89, 46, 45,161,102,104,166, 0, 18,247,167,107, 0, 6,255, 0,166, 5, + 42,103, 57, 65, 82,185, 64, 32,133,247,194,134, 58, 28,253,191,183, 79,189,167, 40,130,133, 15,136,130, 15, 48,207, 92,244,234, + 62,127,191, 90,215,182,213,122, 45,249,108, 90, 55,197,175, 49, 85, 11, 94,248,160,211,110, 91,114,123,145,228,195, 92,170, 77, + 82, 51,114,163, 41,232, 51, 90,109,232,174,134,220, 0,165,196, 37, 67, 29,181,181, 22,173, 32,176,218, 22,172, 0, 58,144, 15, + 48, 35,161,232, 51,211,182,149,165,204, 0,210,250,182, 96, 8, 55,216,131,107, 17,234, 8,177, 7,208,223, 12,252,106,244,209, + 69, 44, 79,229,112, 89, 74,158,160,131,165,148,142,161,131, 2, 8,234, 8, 32,216,139, 99, 84,189,166, 92, 73, 94, 92, 36,240, + 71,190, 60, 72,109,253,170,139,190,243,218,251, 81,202,181, 6,152,247, 63,185,197,151, 53,246,105,136,172, 84, 2, 7, 50,224, + 67, 84,180,200,117, 35, 4,165,140, 2,158,227,242,123,220, 13,193,188,183,102,246,187, 55, 70,255, 0,174,202,185,175,125,193, +184,106,119,117,217, 95,154,225, 92,154,165,106,179, 33, 82,165,200, 61,127, 70,202, 74,130, 26, 64,248, 91,109,180, 33, 32, 37, + 35, 95,176,103, 17, 91, 65, 79,226, 3, 96, 55,155,100,106, 73,104,195,221, 29,180,188, 44,162,167,194, 11, 49,228,215,104,147, + 33, 65,146,176,160, 71, 43, 83, 28, 97,207,145,107, 58,252,126,111,173,183,174,109,101,223,114,237,205,200,243, 14, 87,172,107, +134,183,104, 86, 21, 21,196,191, 31,235, 27,118,163, 34,153, 41,108, 62,142,143, 50,181,199, 42, 74,135,250,248,242,211,205, 11, + 23,205,103,169,168,185,146,170,158, 46, 83,159, 68,102, 90,132, 67,211,202, 69, 43,202,122,183, 50, 37, 98,121,105,106, 87, 55, + 74,198,201,233,231,141, 79,232,234, 57,204, 82, 16, 6,132,158, 85, 50, 83,153, 27,174,169, 99, 74,129, 10, 55,149, 68, 19,180, +118, 47, 41, 56, 67,100,168,171,151,155, 61, 79, 95, 60,122, 15, 61, 35,130,164,243, 43,195,200,232, 85,144,149, 30,190,103,160, +235,163,138, 10, 81,148,161, 61, 1, 57,207,196, 1,237,229,215, 58,179, 73, 73,100, 1, 32,169,109,175, 10,108,133,117, 65, 61, + 64, 35,211,190,164, 33, 71, 78,184,138, 6, 12,221,108,127,211,249, 99,203,205, 18,188,146,148,164, 30,157,114,114, 49,212,122, +121,235,227,237, 45,212, 2, 7, 84,167,184, 57,230,251,255, 0,214,210,105,196,231,225,201, 72, 78,112, 71,161,193,239,249,235, +162,163, 54,227,231, 9,229,102, 56, 25, 86,126, 37, 18, 58,142,158,154, 26, 64,223,165,177,147,211,115,112, 58,252,252,223, 22, +213, 70,117,150,146,176,201, 81, 88,230, 39, 35,152, 1,253, 61,115,159,248,104,168,146,144,231,232,202,255, 0, 85, 56, 40,229, + 0, 30,157, 78,124,245,114, 83, 5, 65, 72, 11,202,122,142,131, 4, 30,196,245,208, 41,136,220, 55, 57,130, 80,160,172,229, 74, + 5, 71, 24, 57,192, 61,188,255, 0, 13,102,195,174, 10, 13,246,245,219,231,231,243,194, 75,106, 66,138,139,202,121, 62, 73, 39, + 41, 64,244,249,235,195,175,165, 29, 16,164,129,215, 3,176, 10,244,237,242, 58, 13,247, 86, 20,162,210,241,205,219, 9,199, 76, +118, 57,252,252,244, 57,121,183, 22, 18,162,114, 8, 46, 36,167,166,122, 30,132,122,147,160, 1, 61,122,224,218,109,176, 59,124, +252,244,193, 73, 62, 42,249,210,160,160, 6, 10, 58, 4,243,117,237,215,174,169,202,116,144,148,163, 9, 35, 41,232,112, 73, 35, + 26,244,226,149,225, 44, 52,218, 83,202, 50, 6,112, 73, 3,166, 20, 60,186,106,200, 38, 56, 22,159, 25, 41, 42, 74,136,229, 35, + 39,237,230, 7, 25, 25,253,154,205,172, 79, 99,140,129,115,240,254,120,124,184,115,189,156,218,173,243,217,253,196,140,226,154, +114,201,221, 29,189,186,157,144, 2, 28, 76,104,148, 91,202,137, 62,170,234,144,226,146, 10, 19, 71,106,164, 78, 72,192,235,229, +214, 89,252, 84, 79,135, 38,165, 91,167, 64,144,125,222, 21, 90, 83,212,194, 9,203,148,103,102,202,149, 75,147, 29,226,231,198, +199,134,165,180, 86,174, 83,250, 48, 82,145,204,117, 12,134, 36, 32, 58, 89,144,219,141, 68,148, 28, 97,215, 25,112,135,124, 41, + 13,150, 30, 13,148,156,182,191, 13,197,224,142,160,224,143, 93, 73,106,193,222, 9,123,221,195,158,213,110, 37, 84, 5,220,177, +173,145, 99,221,170, 9, 90, 82,245,211, 97, 33,139, 66,186,235,106,113, 41, 18, 89,144,221, 38,151, 80,109,206,169,241,170, 79, + 3,133,165, 68,213,126, 32,229,133,243, 12,131, 53, 81,228,136,205, 3,157,175,169,213, 36,139,223,107, 71, 40,244, 5,135, 82, +109,142,146,250, 55,230, 49,199,158,230,217, 92,205,165,166,142, 42,152,199,111,171, 99, 12,173,241,188,212,235,255, 0,117,239, +229,177,215, 10, 45,116,211,119, 43,112,233,170, 37,182,230, 76,183, 43,177, 16, 48, 67,141,212,104,203,167, 84, 84,210, 85,250, +200,247,186, 39, 42,135, 76,169,127, 17,201, 25,126, 41,181,229, 37, 94,246,130,227,139, 83, 98,158,134,210,180,160,134,139,132, +169, 8,228,234, 57,157, 60,196,119, 33,160, 58, 3,173, 54,220,106,162,232,187,147, 64,173, 32,128,221,114,157, 86,182,101,168, + 2,112,236, 98,110, 58, 71, 42, 0,200, 82,156,139, 85,108,168, 12, 37, 47, 14, 99,215, 89,237, 42,241,122, 42, 89,121,149,120, +143, 68,240,228, 71, 67,193, 97, 42,112, 20,248,104, 82,146, 14, 81,149, 36, 43, 61,130,149,202, 79, 77, 54,154, 98,201, 79, 48, + 93,157, 23,215,245, 64,140,254,242,183,247, 3,113,214,216,234,185,107, 85, 90,190,153,200,103,134, 73, 8,185,181,196,141,207, + 0,122,217, 95, 77,199,166, 54, 18,161, 94,151, 79,143,238,201, 90,156, 74, 11,144,195, 67, 45,167,222,100,242,185, 41,107, 79, + 47, 68,161,128,211, 94, 17, 4,143,139,237,214, 33, 94,188,163, 65,166, 48,194, 95, 91,117, 54,202,144,132, 54,165,128,183, 95, +199,188,184,162,159,133, 33, 12,114, 39, 3,184,113, 99, 62, 90,108,110,125,200,155, 57,192,243,237, 54,135, 98, 37, 65,105,104, +184, 83, 38, 67,170, 74,157,117,106, 82, 65,231, 43, 42, 36,158,164, 28,103,182,152, 91,179,113, 22,203, 82, 31,144,227,141,177, + 29,133, 60,243,188,138,117,126, 27,202,229, 79,134,132,140,173,213,186,224, 64,230, 35, 28,249, 82,146,156,168,109, 83, 80,180, +133, 70,155,131,247,250, 91,173,253,215,233,123,143,190, 31,153,230, 40,116,234, 94, 76,155, 11, 13,199,112,250,136, 0, 48,181, +193, 30,164,142,215, 14, 21,209,121,205, 91,172,198,128, 37,214, 37,203,151, 18,147, 71,162, 69, 74,158,159, 91,173, 84, 31, 76, + 74, 61, 38, 10, 82, 57,149, 46, 76,199,210,132, 36,116, 79,141,204,122, 13, 72,111,103,182,153,253,140,217, 59, 59,105,234,166, + 43,245,214, 40,146,102,238, 75,165,136,243,169,213, 75,230,241,120, 86, 47, 54, 36,211,230,178,227, 21, 26, 75, 53, 55, 26,167, + 24,207,180,236,119, 35,210, 16, 22,218,146,117, 21, 91, 99,137, 58,134,192,111, 54,211,110, 76,122, 84, 42,181,197,100,221,246, +174,224,205,167, 84,216, 19,169,212,123, 66, 37, 89, 42,151, 77, 97,181, 39,195,159,114, 79,128,212,245,169,240, 22,212,111,116, +105, 13,225, 69, 58,152,173,218,236, 42,179,108, 87,233, 14,186,253, 46,181, 6,157,112, 82, 30,120, 56,211,238,209,110, 10,124, +106,204, 5, 62,219,128, 41, 18, 61,194,107, 60,193, 64, 44, 45, 4, 30,186,117,106,119,163, 48,188,177,253, 92,232,116, 31,218, +177, 26,182, 29, 0, 5,108,118, 44, 24,145,181,142, 35,114,231,116, 85,239,152,101,148,181,162, 92,195, 43,146, 35, 87, 18,135, +188, 13, 42, 22,128, 23, 42, 35, 98, 66,200, 24, 35, 57,137,208,164,161, 30,202,120, 41,197,183,177,147, 96, 55,194,117, 82,245, +225,250,163, 11,134,125,197,158,169, 14,206,182,216,166, 75,169,236, 93,114,190,156,248,141,189,108,196, 90,166,237,169,121,196, +181,250,106, 40,147, 79, 30, 49,116, 81,219, 78,117, 26, 30, 33,248, 90,223,142, 22,238, 53, 90,251,235,183, 21, 75, 77,169,146, +228, 66,162, 92,232, 13, 87,118,250,239,240, 22,241, 75,150,189,233, 78, 11,167,214, 10,153, 99,198, 17,203,141,204,109,181,161, + 79, 69,104,144, 53, 62, 58,210, 27,142,235,239, 21,135, 25, 12,160, 78,108, 32,130, 2, 20,150,218,156,215,108, 60,148,173, 41, + 88, 7, 42, 65, 24, 28,201, 25,193,174,203,122,131,116,219,213,139,110,241,182,232, 55,173,161,112, 70, 84, 43,170,207,186,169, + 84,234,253,183,113,211,152,109, 97, 46, 84,104,245, 86, 28,142,237, 70, 59, 5,226,196,128,132,200, 66, 22,182,154,125,146, 80, +180,201,178,222, 38,170,167,211, 29, 71,246,200, 86,223,104,218, 69, 29, 1, 87,177,189,186,233, 96,214, 30, 85, 40, 0, 56,170, +184,143,195,156,143, 60, 18, 84, 69, 23,232,156,193,247, 18,194,160, 70,237,183,247,176,221, 84,146, 79,219, 83, 27,110, 29,203, +146,109, 13, 30, 23, 61,163, 28,100,240,219, 38,149,107,237,182,228, 73,189,236,148, 58,150,218,218, 61,216, 67,151,221,136,166, +144,210, 25,240, 41, 6,169, 45, 53, 11, 53, 66, 58, 57, 80,186, 76,248, 97,190, 98,160,218,142,164,109,178,158,214,237,167,175, + 65,161,127, 41,109,181,191,248, 74,174, 85,212,196, 72,247,141,118,159, 86,189,184,118,184, 38, 56,243,200, 67, 20,205,205,163, + 65, 92,187,103,244,108,243,134, 42,113, 37,120, 42,121, 41,114,160, 80, 84,117,167,220, 73,251, 19,182,242,247,150,245,217,194, + 29,220,173,162,186,165, 45,185,180,237,176,187,166,214,235, 27,115, 85,154,242,203,141, 53,105,221,169,247,138,213,131, 33,111, + 58, 60, 24,243, 19, 85,132,218, 80, 19,227,198, 71,195,173, 7,218,190, 57,120,161,246,121,238,117,107,135, 46, 42, 54,246,212, +222,125,182, 66,215, 76,220,221,149,190,133,155,115,191, 81,182,165,170, 84, 41, 82,173,155,198,146,212,216, 50,159,240,155,121, +200,241,235, 44, 76, 97,206, 80,135,152,140,178,151, 90,121,170,146, 44,222, 17, 46, 79, 77, 21,101, 90,144,210, 68,210, 26, 90, +141, 23, 26,157, 24, 36,177, 72,226,224,221,193, 66, 60,166,100, 39,106,230,105,184,247,129,158, 20,172,144,102, 25, 56, 96,130, + 73, 11, 77, 13,172, 72, 85,114, 4,208,176, 63,238,220,198, 0, 12,193, 90,219,205,107,111, 55, 22,222,185,109,106, 77,203,105, + 92,212, 27,170,209,172,183,227,209, 46,123, 90,179, 79,185, 45,186,219, 47,160, 44, 55, 78,175, 80,230, 63, 25,215,130, 20, 20, +227, 72,116,188,206, 64,121,180, 19,141,103,175, 87,204,134,148,133, 47,152,148,124, 42, 90,135, 81,202, 0, 79, 42,142, 57,128, +233,159,246, 64, 39, 57, 58,138, 47, 16, 27, 71,120,112, 95, 98,211, 61,164, 94,203, 13,207,174,217,124, 50,238, 29,187,102,110, + 70,229,240,243,119,189, 42, 85,155, 77,162,222,245, 72, 16, 41,117, 22,108,155,169,231, 90,184,109, 7,235, 46,162,151, 58,152, +243,203,175,208,101,130,245, 6,171, 58,144, 89,145, 18, 68,155, 3,127,214,247,155, 98,118,115,120,231, 91,109, 90,114,247, 99, +108,236,173,194,145,108,177, 83, 77, 90, 45,188,253,219, 67,139, 87,122,147, 14,164,243,190, 44,248, 45,185, 37, 98, 59,143,101, +242,194,155, 18, 15,188, 7, 73,143,214,196, 35,167,138,170, 9,185,212,211, 51, 37,153,116, 75, 28,128, 41, 49, 75, 29,205,152, + 95,170,150, 83,177,218,235,123, 43,134,115,213,207,218, 72,189,141,233,170,169,213, 93,148,221,209,145,142,149,120,220, 40,189, +200,177, 4, 41, 27, 0, 8,185,198,215,109,149, 22, 37,219,112, 75,167, 73,165, 92, 21,191,118,183,110, 26,195, 20,107, 85,228, + 68,174, 84,165, 82,105,206,202, 98, 44, 87, 92,162,212, 48,165, 45,180,169,192,152,142,168,161, 4, 36, 36,229, 99, 64, 56,226, +223, 77,219,218,203, 74,243,176,184,111,131,100,212,184,131,106,210,106,188,182,174,237,198,176,104,236,108,117, 26,191,107,238, + 45,231, 67,159,114, 83,238, 42,188, 53,220, 59,203, 46,201,218,125,206,169,219, 54,146, 99,166,100,164,216,146,234, 18,227,161, + 2,157, 2,167,204, 14, 62, 61,170,123,199,195,134,245,239, 23, 13,187,105,102,194,182,165, 83,246,238,171,105, 84,183, 81, 53, +244,170,245,137, 87,220,107, 45,183,233,117,187, 54, 41,166, 73,133, 64,143, 76,250,217,135,130,156, 67,211,229, 61, 20,165, 50, + 32,160,164,235,150,155,127,199,229, 2,218,166,220, 17, 47,141,155,184,239,201,213, 27, 39,106,105,180,122,212,125,229,250,134, +170,214,227,109, 78,199,111,230,200, 68,190,174,249,149,109,181,172,187,121, 82,106, 16, 56,129,184, 42,147, 41, 97,218,124,229, + 79,183,224, 36,215,213, 28,203,110, 70,206, 69,195,144, 85, 69, 5, 70, 98,154,105,203, 23, 84, 82, 9,145, 88, 2,188,203, 43, + 29, 22,223, 64,107,155,217,130, 11,134,211,227, 63, 18,206, 91, 83, 89,150,100, 83,153,115, 5, 2, 9,166,100,112, 41,101, 77, + 75, 50,195,172,141, 83, 43,150, 83, 39, 47, 66,149,186, 60,183, 82,141,110,225,240, 39,196,221,155, 81,191,231,222,141, 89,213, + 55,237, 88,247,245,205,127,221,171,222,173,181,185, 61,226,240,182,175, 86,237, 91,186,211,159, 89, 98,236,113,202,246,245, 75, +190,106,209,152,110,218,100, 61,112, 84, 36,212, 28, 91, 16, 22,220,105,170,139,127,159,236,242,222,186, 77, 26,239,166, 87,232, +112,233,215,213,183,115, 90,106,118,188, 55, 27,106, 92,217,154, 61,128,237, 3,137,199,119, 10,177,114,223, 77,221,139, 75, 53, +122, 53,223,195, 53,253, 73,112, 71,241, 98,181, 54,200,172, 83,221,113,115,223,163, 51, 57,230,147,199, 5,183,187,182,199, 20, +139,188,118,233,203, 98,159, 84,186,183,115,137, 91, 34, 52, 27,238, 84,170,188, 61,236,220, 94, 32, 44,203,171,108, 40,237, 75, +107,110, 95,141, 88,160, 80,145, 95,186, 77, 97,137,205, 83, 25,174,211,162,188, 99, 84, 40,149, 52, 64,143, 46,157, 75,218, 83, +101, 77,186,105, 19,162,236, 45,249,108,218, 84, 43,254,198,220, 58,109, 34,211,226, 14,155, 2,237, 19,173,203,215,141, 77,199, +186,173,217,247,125, 99, 98,170, 16,170,182,125,110,232,227, 78,236,167,187, 2, 77, 5,212,166,211,181,219,161, 84, 87, 88,151, + 81,153, 91, 22, 42,173, 58,216, 2, 66,109,243,176,249,247,227,159,188,172,197,153,181, 23,220,146, 73, 36,158,189,183, 55,238, +119,191, 83,134, 79,133, 94, 26, 54,163,119, 40, 23,245, 15,114,220,191,142,226,213, 56,139,225,227,133,189,165,172,237,181,249, + 97,155, 30,221,191,119,242,131,196, 96,167, 93,151,172, 39,236,250,202, 55, 62,208,102,241,218,107, 53,128,138, 37,126,130,149, + 83,107, 53, 9,204, 84,230, 17, 17,189, 55,212,190, 3,248,146,172,211,160,212,169,214,189,181, 33,186,142,219,211,247, 54, 44, + 95,227, 14,196,106,162,186,125, 98,181,178,180, 58, 45,166,105,207, 92, 9,120,110,100,217, 28, 70,108,107,177,109,190, 79,173, +221, 99,115, 41,203, 76, 94, 97, 37, 17,242,109,137,226,246,211,217,104,251,163, 81,127,101, 62,187,186,171,187,235,180,188, 70, +108,210,237,235,249, 22, 93,137,180,219,153,179, 84,221,245,137,101, 55, 93,179, 23, 99,212,230,110, 13,155, 14,126,244, 71,153, + 30,155, 22,183,110, 58,135, 44,136,172,191, 58, 84,105, 79,178,151,218, 87,181, 90,244, 52,109,183, 49,108, 26,164,171,191,110, + 45, 11, 30,153, 2,181,115,110, 83,149,219, 97,171,198,196,221, 46, 9,183, 14, 21,126,223,177, 98,217, 80,152,183,109,137, 17, +184, 39,182,216,149, 73,247,169,115, 94,157,126,212, 38,174,188,170,109, 62,145, 66,136,100, 17, 21, 93, 71,204, 47,211,227,220, +219,115,111,195,225,108, 1,107, 11,252,252,239,134,106, 63,179,199,115,133,155,125,215,171,187,135,179,118,237,197,106,110,150, +201,109,205, 10,223,153,185,246, 52,250, 21,249, 15,122,172, 61,215,189,169, 23, 85,173,123,210,110, 87,226, 85,161,161,221,180, + 69, 50, 35, 16,154,153,245,133, 70,101, 86, 39,143, 18,101,191, 50, 43,173, 61,131,193, 94,250,238,142,241,110, 54,200, 89,144, +172,105,247,150,215, 94, 63,197,253,209, 54,126,230, 88,150,253,156,245,230,245,238,157,187,165, 91,118,205,231,112, 87,162,211, +175, 26,213, 74,234, 15,179, 73,139, 75,126, 92,138,179, 48,164, 75,167,183, 38, 43, 46, 58,157,172,107,218, 71,106,187,184,205, + 93,151, 6,202,110, 37,197,110,209,175, 29,134,190,172,246, 39,241, 13, 5,253,203,160, 93, 60, 62,109,135, 18,118,213,139,112, + 73,220, 10,142,200, 73,165, 84,170,177,119, 63,136, 8, 23, 60, 70,218,180,225,210,217,143,182,241, 40,114,169,117, 3, 80,155, + 86, 12, 7, 9,252, 89,216,124, 52,223,247, 21,199, 92,217,203,159,115,109, 71,183, 27,106,119, 94,200,183,218,221,216, 86, 93, +205,110,222, 91, 37,184,134,249,219,247, 46, 91,196,109, 93, 86, 53,227, 71, 49,101, 84,161,213,227,179, 69,164, 59, 61,217, 13, + 76,139, 38,154,150, 85, 17,245,109, 21,212, 94,194,230,253,122,118,237,252, 63,118, 51,229,219,231,249, 97,202,188, 61,155,155, +199,118,239,117,185,183,155, 45,111,219, 48,169,151,253,165,181,247, 29,144,197,255, 0,186, 86, 69,154,185,177,175,167, 54,191, +110,233, 53, 41,149, 43,218,189, 9,184,108,215,247,190,249,155, 69,160, 50,234,210,253, 65,250, 53, 77,200,172, 42,159, 74,151, + 45,166,227,134, 30, 29,118,127,120,246,186,191, 46,244, 59,148,198,229, 93, 91,162,198,209,109, 69, 98,214,187, 45,122, 85,145, +109,220,147, 54,155,112,111,218, 69, 66,255, 0,180,170,251,125, 80,157,121, 82,101,220,150,181, 18,154,240,167,215,104, 46, 83, +162, 85, 36,212, 19,245,147,172, 55, 5,237,158,182,189,170,118,111,241,175,183,251,177,186, 92, 50,213, 47,138,213,133, 67,216, + 27,113, 74,181,183,186, 14,223, 84,174,122, 47, 11,119,174,202,223, 59, 29, 14,226,170,191,178,245,148,204,114,158,230,219,222, + 52, 89,210, 61,212, 74,157,109,221,244, 74,100,119,233,207,218,140,207,171,105,175, 15, 60, 86,219, 59, 19,183, 23, 37,185, 55, +107, 42,215,157,246,197,244,141,202,218,155,189,189,196,135,110,218,246, 85,232,222,219,222,187,117, 26,163,120, 88,142,109,229, + 70, 70,225, 69,136,139,192, 85, 33, 71,143, 94,160, 33, 53, 10, 36,116,205, 53, 8, 43,126, 27,135, 2, 45, 74,111,229,107,222, +224,251,173,219,227,235,252,241,159, 47, 99,243,255, 0,140,109,229,209,192, 61,139, 67,254, 54, 13, 55,134, 30, 56,238,159,226, +247,134,189,165,221,155, 88, 82,239, 26, 58,127,141, 58,134,224, 29,184,254, 17,110,133,181,238,252, 37, 74,228,217,202, 39,240, +190,165,239, 17, 99,253,100,191,208, 49,227,221, 17,185, 92,241,117, 46,135,178,187, 35, 81, 28, 31,213, 31,183,183,186,171, 31, +122,172,157,204, 93,241,102,218,215,157,151, 58,233,188,119, 54,204,184,111, 91, 90,206,160,237,157, 94,102,218, 53, 31,110,232, + 55, 5,201, 73,181, 97, 62,229, 82, 21,212,253, 17,170,156,202,136, 53,143, 5,170,122,233,238,255, 0, 21,182, 21,251, 73,221, + 38,109, 61,163,187,173, 42,230,243,109,206,204,217,215,189, 66,226,221,186, 53,235, 74,102,187,180, 15, 88,202,106,225,181, 40, +212,205,160,161, 61, 71,164,207,141,102,114, 42,155, 50,125, 77,232,203,169,120,130,166,250, 89,240,157,111,237,173,252,177, 83, + 70,217,139, 67,114,246,121,205,192,178,182,194,199,221,235, 38,179, 78,133,124, 51,107,215,171,138,221, 10,189,205, 93,167, 93, + 54,173,114, 93,149, 85,143,101, 93, 20, 42,173,118, 11,240,157,147, 78,174, 70,121,218, 70, 95,139,225,190, 91,109, 66, 82,230, +223, 59,143,119,166, 50, 8,184, 3,231,127,135,166, 49, 78, 42,118,162,139,177,156, 68,238,246,208, 80, 63,132, 77, 83,182,246, +242,168, 91, 74,166, 93,239, 65,153,117,219,117, 40, 41,100, 86,172,219,150,169, 75,166,194,137, 94,175, 81, 43, 42,159, 72,151, + 83,133, 10, 28, 42,156,138, 35,149, 8, 81, 34,197,146,211, 13,173, 88,184,129,221,147,190, 91,193,122,238,130, 40, 10,181,162, + 92,146,233,172,210,109,231,107, 47, 92,147, 40,244, 11,118,135, 75,181,237,216, 53, 75,142, 68, 40,170,184,107, 72,161, 81,105, +222,253, 60, 68,134,137,147, 11,242, 90,133, 13,183, 81, 21,165,172, 21, 55, 58, 70,221,186,116,193,180,169,223,215, 31,255,217, +}; + diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index 5d24b93418b..993cbceae18 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -40,8 +40,8 @@ extern char datatoc_blenderbuttons[]; extern int datatoc_prvicons_size; extern char datatoc_prvicons[]; -extern int datatoc_splash_jpg_size; -extern char datatoc_splash_jpg[]; +extern int datatoc_splash_png_size; +extern char datatoc_splash_png[]; extern int datatoc_Bfont_size; extern char datatoc_Bfont[]; -- cgit v1.2.3 From be613fd9ddf02aca2d619b6aaa615fff5a02661b Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 16 Sep 2009 00:59:55 +0000 Subject: OSX should use libsndfile in /lib, not /usr --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7196049f964..c881dec03db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -409,7 +409,7 @@ IF(APPLE) ENDIF(WITH_JACK) IF(WITH_SNDFILE) - SET(SNDFILE /usr) + SET(SNDFILE ${LIBDIR}/sndfile) SET(SNDFILE_INC ${SNDFILE}/include) SET(SNDFILE_LIB sndfile) SET(SNDFILE_LIBPATH ${SNDFILE}/lib) -- cgit v1.2.3 From 51f1e822900fbae5b239ddfcfd488eccbbbcc31b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Sep 2009 01:15:30 +0000 Subject: Object mode Selection options brought back for view3d.select - 'center', while Ctrl is held select objects from their center location - 'enumerate', while Alt is held, give a list of objects under the mouse - Object selection menu now uses icons with names - operator object.select_name(name, extend=False) - keybindings so combinations of Ctrl/Alt/Shift can be used (like in 2.4x) - logic text input field was using deprecated ID_SCRIPT rather then ID_TXT details - added comments to DNA_ID.h ID types - removed unused ID types Sector and Life - added uiIconFromID() to get an icon from the object. - using name for selection is weak but currently there isnt a really good way to do this. --- source/blender/blenloader/intern/readblenentry.c | 2 - source/blender/editors/include/UI_interface.h | 2 + source/blender/editors/interface/interface_utils.c | 59 +++++++++ source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_select.c | 53 ++++++++ source/blender/editors/space_logic/logic_window.c | 2 +- source/blender/editors/space_view3d/view3d_ops.c | 20 ++- .../blender/editors/space_view3d/view3d_select.c | 140 +++++++++++++-------- source/blender/makesdna/DNA_ID.h | 65 +++++----- 10 files changed, 255 insertions(+), 90 deletions(-) diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 9cd45a268da..3d21bb54e2b 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -99,7 +99,6 @@ static IDType idtypes[]= { { ID_IP, "Ipo", IDTYPE_FLAGS_ISLINKABLE}, { ID_KE, "Key", 0}, { ID_LA, "Lamp", IDTYPE_FLAGS_ISLINKABLE}, - { ID_LF, "Life", 0}, { ID_LI, "Library", 0}, { ID_LT, "Lattice", IDTYPE_FLAGS_ISLINKABLE}, { ID_MA, "Material", IDTYPE_FLAGS_ISLINKABLE}, @@ -110,7 +109,6 @@ static IDType idtypes[]= { { ID_SCE, "Scene", IDTYPE_FLAGS_ISLINKABLE}, { ID_SCR, "Screen", 0}, { ID_SEQ, "Sequence", 0}, - { ID_SE, "Sector", 0}, { ID_SO, "Sound", IDTYPE_FLAGS_ISLINKABLE}, { ID_TE, "Texture", IDTYPE_FLAGS_ISLINKABLE}, { ID_TXT, "Text", IDTYPE_FLAGS_ISLINKABLE}, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 921aa60f9b2..77c4e4d3475 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -420,6 +420,8 @@ uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int short x1, short y1, short x2, short y2, void *idpp, char *tip); int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID *id, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events); +int uiIconFromID(struct ID *id); + uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip); uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip); uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 63f81c9e46c..539c71cc497 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -33,6 +33,7 @@ #include "DNA_color_types.h" #include "DNA_listBase.h" #include "DNA_material_types.h" +#include "DNA_lamp_types.h"" #include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_texture_types.h" @@ -509,6 +510,64 @@ int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID *id, int id_code, return x; } +/* currently only object-data types */ +int uiIconFromID(ID *id) +{ + if (id==NULL) + return 0; + + switch(GS(id->name)) { + case ID_OB: + { + Object *ob= (Object *)id; + + switch(ob->type) { + case OB_EMPTY: + return ICON_EMPTY_DATA; + case OB_CURVE: + return ICON_CURVE_DATA; + case OB_SURF: + return ICON_SURFACE_DATA; + case OB_FONT: + return ICON_FONT_DATA; + } + + return uiIconFromID(ob->data); + } + case ID_ME: + return ICON_MESH_DATA; + case ID_AR: + return ICON_ARMATURE_DATA; + case ID_MB: + return ICON_META_DATA; + case ID_CA: + return ICON_CAMERA_DATA; + case ID_LT: + return ICON_LATTICE_DATA; + case ID_CU: + return ICON_CURVE_DATA; + case ID_LA: + { + Lamp *la= (Lamp *)id; + switch(la->type) { + case LA_LOCAL: + return ICON_LAMP_POINT; + case LA_SUN: + return ICON_LAMP_SUN; + case LA_SPOT: + return ICON_LAMP_SPOT; + case LA_HEMI: + return ICON_LAMP_HEMI; + case LA_AREA: + return ICON_LAMP_AREA; + } + return ICON_LAMP_DATA; + } + } + + return 0; +} + /* ****************************** default button callbacks ******************* */ /* ************ LEGACY WARNING, only to get things work with 2.48 code! ****** */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 7d52e9c7c56..315b6632051 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -79,6 +79,7 @@ void OBJECT_OT_select_by_layer(struct wmOperatorType *ot); void OBJECT_OT_select_linked(struct wmOperatorType *ot); void OBJECT_OT_select_grouped(struct wmOperatorType *ot); void OBJECT_OT_select_mirror(struct wmOperatorType *ot); +void OBJECT_OT_select_name(struct wmOperatorType *ot); /* object_add.c */ void OBJECT_OT_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 6ee43765475..dce09d47b2c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -102,6 +102,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_linked); WM_operatortype_append(OBJECT_OT_select_grouped); WM_operatortype_append(OBJECT_OT_select_mirror); + WM_operatortype_append(OBJECT_OT_select_name); /* XXX - weak, not compat with linked objects */ WM_operatortype_append(GROUP_OT_group_create); WM_operatortype_append(GROUP_OT_objects_remove); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 50ba4ab2934..cfd65ad18ec 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -923,6 +923,59 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot) RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); } + +static int object_select_name_exec(bContext *C, wmOperator *op) +{ + char *name= RNA_string_get_alloc(op->ptr, "name", NULL, 0); + short extend= RNA_boolean_get(op->ptr, "extend"); + short changed = 0; + + if(!extend) { + CTX_DATA_BEGIN(C, Base*, base, visible_bases) { + ED_base_object_select(base, BA_DESELECT); + } + CTX_DATA_END; + } + + CTX_DATA_BEGIN(C, Base*, base, selectable_bases) { + if(strcmp(name, base->object->id.name+2)==0) { + ED_base_object_select(base, BA_SELECT); + changed= 1; + } + } + CTX_DATA_END; + + MEM_freeN(name); + + /* undo? */ + if(changed) { + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void OBJECT_OT_select_name(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Select Name"; + ot->description = "Select an object with this name"; + ot->idname= "OBJECT_OT_select_name"; + + /* api callbacks */ + ot->exec= object_select_name_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_string(ot->srna, "name", "", 0, "Name", "Object name to select."); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first."); +} + /**************************** Select Random ****************************/ static int object_select_random_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 3040d73bda9..4afa56582a2 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1534,7 +1534,7 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco uiBlockBeginAlign(block); uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+4,yco-23, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)"); if(pc->mode==0) - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script"); + uiDefIDPoinBut(block, test_scriptpoin_but, ID_TXT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script"); else { uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used"); uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-23, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting"); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 7da2e591b10..e179809adc9 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -201,7 +201,25 @@ void view3d_keymap(wmWindowManager *wm) /* selection*/ WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "center", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "enumerate", TRUE); + + /* selection key-combinations */ + km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + RNA_boolean_set(km->ptr, "center", TRUE); + RNA_boolean_set(km->ptr, "extend", TRUE); + km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0); + RNA_boolean_set(km->ptr, "center", TRUE); + RNA_boolean_set(km->ptr, "enumerate", TRUE); + km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0); + RNA_boolean_set(km->ptr, "extend", TRUE); + RNA_boolean_set(km->ptr, "enumerate", TRUE); + km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL|KM_ALT, 0); + RNA_boolean_set(km->ptr, "center", TRUE); + RNA_boolean_set(km->ptr, "extend", TRUE); + RNA_boolean_set(km->ptr, "enumerate", TRUE); + WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index a7696d9fe31..c639b445f9e 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -53,6 +53,7 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BLI_rand.h" +#include "BLI_linklist.h" #include "BKE_action.h" #include "BKE_context.h" @@ -845,56 +846,87 @@ static void deselectall_except(Scene *scene, Base *b) /* deselect all except b } } -static Base *mouse_select_menu(ViewContext *vc, unsigned int *buffer, int hits, short *mval) +static Base *mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, short *mval, short extend) { - Scene *scene= vc->scene; - View3D *v3d= vc->v3d; - Base *baseList[SEL_MENU_SIZE]={NULL}; /*baseList is used to store all possible bases to bring up a menu */ - Base *base; short baseCount = 0; - char menuText[20 + SEL_MENU_SIZE*32] = "Select Object%t"; /* max ob name = 22 */ - char str[32]; - - for(base=FIRSTBASE; base; base= base->next) { - if (BASE_SELECTABLE(v3d, base)) { - baseList[baseCount] = NULL; - - /* two selection methods, the CTRL select uses max dist of 15 */ - if(buffer) { - int a; - for(a=0; aselcol==buffer[ (4 * a) + 3 ]) baseList[baseCount] = base; - } - } - else { - int temp, dist=15; - - project_short(vc->ar, base->object->obmat[3], &base->sx); - - temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]); - if(tempselcol==buffer[ (4 * a) + 3 ]) + ok= TRUE; } + } + else { + int temp, dist=15; + + project_short(vc->ar, base->object->obmat[3], &base->sx); - if(baseList[baseCount]) { - if (baseCount < SEL_MENU_SIZE) { - baseList[baseCount] = base; - sprintf(str, "|%s %%x%d", base->object->id.name+2, baseCount+1); /* max ob name == 22 */ - strcat(menuText, str); - baseCount++; - } - } + temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]); + if(temp < dist) + ok= TRUE; + } + + if(ok) { + baseCount++; + BLI_linklist_prepend(&linklist, base); + + if (baseCount==SEL_MENU_SIZE) + break; } } + CTX_DATA_END; + + if(baseCount) + - if(baseCount<=1) return baseList[0]; + if(baseCount==0) { + return NULL; + } + if(baseCount == 1) { + Base *base= (Base *)linklist->link; + BLI_linklist_free(linklist, NULL); + return base; + } else { - baseCount = -1; // XXX = pupmenu(menuText); - - if (baseCount != -1) { /* If nothing is selected then dont do anything */ - return baseList[baseCount-1]; + /* UI */ + uiPopupMenu *pup= uiPupMenuBegin(C, "Select Object", 0); + uiLayout *layout= uiPupMenuLayout(pup); + uiLayout *split= uiLayoutSplit(layout, 0); + uiLayout *column= uiLayoutColumn(split, 0); + LinkNode *node; + + node= linklist; + while(node) { + Base *base=node->link; + Object *ob= base->object; + char *name= ob->id.name+2; + /* annoying!, since we need to set 2 props cant use this. */ + /* uiItemStringO(column, name, 0, "OBJECT_OT_select_name", "name", name); */ + + { + PointerRNA ptr; + + WM_operator_properties_create(&ptr, "OBJECT_OT_select_name"); + RNA_string_set(&ptr, "name", name); + RNA_boolean_set(&ptr, "extend", extend); + uiItemFullO(column, name, uiIconFromID((ID *)ob), "OBJECT_OT_select_name", ptr.data, WM_OP_EXEC_DEFAULT, 0); + } + + node= node->next; } - else return NULL; + + uiPupMenuEnd(C, pup); + + BLI_linklist_free(linklist, NULL); + return NULL; } } @@ -958,14 +990,13 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff /* mval is region coords */ -static void mouse_select(bContext *C, short *mval, short extend, short obcenter) +static void mouse_select(bContext *C, short *mval, short extend, short obcenter, short enumerate) { ViewContext vc; ARegion *ar= CTX_wm_region(C); View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL; - unsigned int buffer[4*MAXPICKBUF]; int temp, a, dist=100; short hits; @@ -981,10 +1012,9 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter) if(vc.obedit==NULL && obcenter) { /* note; shift+alt goes to group-flush-selecting */ - /* XXX solve */ - if(0) - basact= mouse_select_menu(&vc, NULL, 0, mval); - else { + if(enumerate) { + basact= mouse_select_menu(C, &vc, NULL, 0, mval, extend); + } else { base= startbase; while(base) { if (BASE_SELECTABLE(v3d, base)) { @@ -1006,6 +1036,8 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter) } } else { + unsigned int buffer[4*MAXPICKBUF]; + /* if objects have posemode set, the bones are in the same selection buffer */ hits= mixed_bones_object_selectbuffer(&vc, buffer, mval); @@ -1016,9 +1048,9 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter) for(a=0; aptr, "extend"); + short center= RNA_boolean_get(op->ptr, "center"); + short enumerate= RNA_boolean_get(op->ptr, "enumerate"); view3d_operator_needs_opengl(C); @@ -1590,7 +1624,7 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) PE_mouse_particles(C, event->mval, extend); else - mouse_select(C, event->mval, extend, 0); + mouse_select(C, event->mval, extend, center, enumerate); /* allowing tweaks */ return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED; @@ -1611,7 +1645,9 @@ void VIEW3D_OT_select(wmOperatorType *ot) ot->flag= OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first."); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first."); + RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting (object mode only)."); + RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only)."); } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 9e5212e159f..0c38421a3f5 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -155,40 +155,37 @@ typedef struct PreviewImage { #endif /* ID from database */ -#define ID_SCE MAKE_ID2('S', 'C') -#define ID_LI MAKE_ID2('L', 'I') -#define ID_OB MAKE_ID2('O', 'B') -#define ID_ME MAKE_ID2('M', 'E') -#define ID_CU MAKE_ID2('C', 'U') -#define ID_MB MAKE_ID2('M', 'B') -#define ID_MA MAKE_ID2('M', 'A') -#define ID_TE MAKE_ID2('T', 'E') -#define ID_IM MAKE_ID2('I', 'M') -#define ID_IK MAKE_ID2('I', 'K') -#define ID_WV MAKE_ID2('W', 'V') -#define ID_LT MAKE_ID2('L', 'T') -#define ID_SE MAKE_ID2('S', 'E') -#define ID_LF MAKE_ID2('L', 'F') -#define ID_LA MAKE_ID2('L', 'A') -#define ID_CA MAKE_ID2('C', 'A') -#define ID_IP MAKE_ID2('I', 'P') -#define ID_KE MAKE_ID2('K', 'E') -#define ID_WO MAKE_ID2('W', 'O') -#define ID_SCR MAKE_ID2('S', 'R') -#define ID_SCRN MAKE_ID2('S', 'N') -#define ID_VF MAKE_ID2('V', 'F') -#define ID_TXT MAKE_ID2('T', 'X') -#define ID_SO MAKE_ID2('S', 'O') -#define ID_GR MAKE_ID2('G', 'R') -#define ID_ID MAKE_ID2('I', 'D') -#define ID_AR MAKE_ID2('A', 'R') -#define ID_AC MAKE_ID2('A', 'C') -#define ID_SCRIPT MAKE_ID2('P', 'Y') -#define ID_NT MAKE_ID2('N', 'T') -#define ID_BR MAKE_ID2('B', 'R') -#define ID_PA MAKE_ID2('P', 'A') -#define ID_GD MAKE_ID2('G', 'D') -#define ID_WM MAKE_ID2('W', 'M') +#define ID_SCE MAKE_ID2('S', 'C') /* Scene */ +#define ID_LI MAKE_ID2('L', 'I') /* Library */ +#define ID_OB MAKE_ID2('O', 'B') /* Object */ +#define ID_ME MAKE_ID2('M', 'E') /* Mesh */ +#define ID_CU MAKE_ID2('C', 'U') /* Curve */ +#define ID_MB MAKE_ID2('M', 'B') /* MetaBall */ +#define ID_MA MAKE_ID2('M', 'A') /* Material */ +#define ID_TE MAKE_ID2('T', 'E') /* Texture */ +#define ID_IM MAKE_ID2('I', 'M') /* Image */ +#define ID_WV MAKE_ID2('W', 'V') /* Wave (unused) */ +#define ID_LT MAKE_ID2('L', 'T') /* Lattice */ +#define ID_LA MAKE_ID2('L', 'A') /* Lamp */ +#define ID_CA MAKE_ID2('C', 'A') /* Camera */ +#define ID_IP MAKE_ID2('I', 'P') /* Ipo (depreciated, replaced by FCurves) */ +#define ID_KE MAKE_ID2('K', 'E') /* Key (shape key) */ +#define ID_WO MAKE_ID2('W', 'O') /* World */ +#define ID_SCR MAKE_ID2('S', 'R') /* Screen */ +#define ID_SCRN MAKE_ID2('S', 'N') /* (depreciated?) */ +#define ID_VF MAKE_ID2('V', 'F') /* VectorFont */ +#define ID_TXT MAKE_ID2('T', 'X') /* Text */ +#define ID_SO MAKE_ID2('S', 'O') /* Sound */ +#define ID_GR MAKE_ID2('G', 'R') /* Group */ +#define ID_ID MAKE_ID2('I', 'D') /* (internal use only) */ +#define ID_AR MAKE_ID2('A', 'R') /* Armature */ +#define ID_AC MAKE_ID2('A', 'C') /* Action */ +#define ID_SCRIPT MAKE_ID2('P', 'Y') /* Script (depreciated) */ +#define ID_NT MAKE_ID2('N', 'T') /* NodeTree */ +#define ID_BR MAKE_ID2('B', 'R') /* Brush */ +#define ID_PA MAKE_ID2('P', 'A') /* ParticleSettings */ +#define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */ +#define ID_WM MAKE_ID2('W', 'M') /* WindowManager */ /* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */ #define ID_SEQ MAKE_ID2('S', 'Q') -- cgit v1.2.3 From 8df1bb99f96fe9981a73c131b6637998fca8862f Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 16 Sep 2009 03:10:25 +0000 Subject: * enable high res smoke rendering in voxeldata texture --- source/blender/render/intern/source/voxeldata.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 17858e55e3d..9318d37620c 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -167,12 +167,10 @@ void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) SmokeModifierData *smd = (SmokeModifierData *)md; if(smd->domain && smd->domain->fluid) { - //int big = (smd->domain->flags & MOD_SMOKE_HIGHRES); - int big=0; - if (big) { - //smoke_turbulence_get_res(smd->domain->wt, vd->resol); - //vd->dataset = smoke_turbulence_get_density(smd->domain->wt); + if (smd->domain->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_get_res(smd->domain->wt, vd->resol); + vd->dataset = smoke_turbulence_get_density(smd->domain->wt); } else { VECCOPY(vd->resol, smd->domain->res); vd->dataset = smoke_get_density(smd->domain->fluid); -- cgit v1.2.3 From cc100eadc5386a55965bacfa22afbb23c1541be5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Sep 2009 06:02:56 +0000 Subject: Operator cheat sheet (from the help menu) writes all operators (including PyOperators) and their default values into a textblock. Useful for an overview and checking consistancy. eg. http://www.pasteall.org/7918/python added rna functions text.clear() and text.write(str) --- release/ui/bpy_ops.py | 6 ++- release/ui/space_info.py | 30 +++++++++++++++ source/blender/blenkernel/BKE_text.h | 4 +- source/blender/blenkernel/intern/text.c | 32 ++++++++++++++-- source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_text.c | 2 + source/blender/makesrna/intern/rna_text_api.c | 49 ++++++++++++++++++++++++ source/blender/python/intern/bpy_operator.c | 54 +++++++++++++++++++++++++++ 8 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 source/blender/makesrna/intern/rna_text_api.c diff --git a/release/ui/bpy_ops.py b/release/ui/bpy_ops.py index dff8125fca1..83c2e82bf6c 100644 --- a/release/ui/bpy_ops.py +++ b/release/ui/bpy_ops.py @@ -3,6 +3,7 @@ from bpy.__ops__ import add as op_add from bpy.__ops__ import remove as op_remove from bpy.__ops__ import dir as op_dir from bpy.__ops__ import call as op_call +from bpy.__ops__ import as_string as op_as_string from bpy.__ops__ import get_rna as op_get_rna # Keep in sync with WM_types.h @@ -130,7 +131,10 @@ class bpy_ops_submodule_op(object): return op_get_rna(self.idname()) - def __repr__(self): + def __repr__(self): # useful display, repr(op) + return op_as_string(self.idname()) + + def __str__(self): # used for print(...) return "" % (self.module, self.func, id(self)) import bpy diff --git a/release/ui/space_info.py b/release/ui/space_info.py index 9fc35c46f29..6e32cf9b071 100644 --- a/release/ui/space_info.py +++ b/release/ui/space_info.py @@ -188,6 +188,9 @@ class INFO_MT_help(bpy.types.Menu): layout.itemO("help.blender_eshop") layout.itemO("help.developer_community") layout.itemO("help.user_community") + layout.itemS() + layout.itemO("help.operator_cheat_sheet") + bpy.types.register(INFO_HT_header) bpy.types.register(INFO_MT_file) @@ -246,10 +249,37 @@ class HELP_OT_user_community(HelpOperator): __label__ = "User Community" __URL__ = 'http://www.blender.org/community/user-community/' +class HELP_OT_operator_cheat_sheet(bpy.types.Operator): + __idname__ = "help.operator_cheat_sheet" + __label__ = "Operator Cheet Sheet (new textblock)" + def execute(self, context): + op_strings = [] + tot = 0 + for op_module_name in dir(bpy.ops): + op_module = getattr(bpy.ops, op_module_name) + for op_submodule_name in dir(op_module): + op = getattr(op_module, op_submodule_name) + text = repr(op) + if text.startswith('bpy.ops.'): + op_strings.append(text) + tot += 1 + + op_strings.append('') + + bpy.ops.text.new() # XXX - assumes new text is always at the end! + textblock = bpy.data.texts[-1] + textblock.write('# %d Operators\n\n' % tot) + textblock.write('\n'.join(op_strings)) + textblock.name = "OperatorList.txt" + print("See OperatorList.txt textblock") + return ('FINISHED',) + + bpy.ops.add(HELP_OT_manual) bpy.ops.add(HELP_OT_release_logs) bpy.ops.add(HELP_OT_blender_website) bpy.ops.add(HELP_OT_blender_eshop) bpy.ops.add(HELP_OT_developer_community) bpy.ops.add(HELP_OT_user_community) +bpy.ops.add(HELP_OT_operator_cheat_sheet) diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index bd14053d121..07e05756ea3 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -48,6 +48,8 @@ int reopen_text (struct Text *text); struct Text* add_text (char *file, const char *relpath); struct Text* copy_text (struct Text *ta); void unlink_text (struct Main *bmain, struct Text *text); +void clear_text(struct Text *text); +void write_text(struct Text *text, char *str); char* txt_to_buf (struct Text *text); void txt_clean_text (struct Text *text); @@ -74,7 +76,7 @@ void txt_delete_selected (struct Text *text); void txt_sel_all (struct Text *text); void txt_sel_line (struct Text *text); char* txt_sel_to_buf (struct Text *text); -void txt_insert_buf (struct Text *text, char *in_buffer); +void txt_insert_buf (struct Text *text, const char *in_buffer); void txt_print_undo (struct Text *text); void txt_undo_add_toop (struct Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc); void txt_do_undo (struct Text *text); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index dac426de4eb..350b0acba9d 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -130,8 +130,10 @@ undo position static void txt_pop_first(Text *text); static void txt_pop_last(Text *text); static void txt_undo_add_op(Text *text, int op); -static void txt_undo_add_block(Text *text, int op, char *buf); +static void txt_undo_add_block(Text *text, int op, const char *buf); static void txt_delete_line(Text *text, TextLine *line); +static void txt_delete_sel (Text *text); +static void txt_make_dirty (Text *text); /***/ @@ -537,6 +539,30 @@ void unlink_text(Main *bmain, Text *text) text->id.us= 0; } +void clear_text(Text *text) /* called directly from rna */ +{ + int oldstate; + + oldstate = txt_get_undostate( ); + txt_set_undostate( 1 ); + txt_sel_all( text ); + txt_delete_sel(text); + txt_set_undostate( oldstate ); + + txt_make_dirty(text); +} + +void write_text(Text *text, char *str) /* called directly from rna */ +{ + int oldstate; + + oldstate = txt_get_undostate( ); + txt_insert_buf( text, str ); + txt_move_eof( text, 0 ); + txt_set_undostate( oldstate ); + + txt_make_dirty(text); +} /*****************************/ /* Editing utility functions */ @@ -1315,7 +1341,7 @@ char *txt_sel_to_buf (Text *text) return buf; } -void txt_insert_buf(Text *text, char *in_buffer) +void txt_insert_buf(Text *text, const char *in_buffer) { int i=0, l=0, j, u, len; TextLine *add; @@ -1544,7 +1570,7 @@ static void txt_undo_add_op(Text *text, int op) text->undo_buf[text->undo_pos+1]= 0; } -static void txt_undo_add_block(Text *text, int op, char *buf) +static void txt_undo_add_block(Text *text, int op, const char *buf) { int length; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 7de80843f27..4d8ef7082b6 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -205,6 +205,7 @@ void RNA_api_main(struct StructRNA *srna); void RNA_api_mesh(struct StructRNA *srna); void RNA_api_object(struct StructRNA *srna); void RNA_api_scene(struct StructRNA *srna); +void RNA_api_text(struct StructRNA *srna); void RNA_api_ui_layout(struct StructRNA *srna); void RNA_api_wm(struct StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c index cd39c317bc5..22cf7e7aeae 100644 --- a/source/blender/makesrna/intern/rna_text.c +++ b/source/blender/makesrna/intern/rna_text.c @@ -223,6 +223,8 @@ static void rna_def_text(BlenderRNA *brna) prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "TextMarker"); RNA_def_property_ui_text(prop, "Markers", "Text markers highlighting part of the text."); + + RNA_api_text(srna); } void RNA_def_text(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_text_api.c b/source/blender/makesrna/intern/rna_text_api.c new file mode 100644 index 00000000000..b048a6b59d0 --- /dev/null +++ b/source/blender/makesrna/intern/rna_text_api.c @@ -0,0 +1,49 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + + +#include "RNA_define.h" +#include "RNA_types.h" + +#ifdef RNA_RUNTIME + +#else + +void RNA_api_text(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *prop; + + func= RNA_def_function(srna, "clear", "clear_text"); + RNA_def_function_ui_description(func, "clear the text block."); + + func= RNA_def_function(srna, "write", "write_text"); + RNA_def_function_ui_description(func, "write text at the cursor location and advance to the end of the text block."); + prop= RNA_def_string(func, "text", "Text", 0, "", "New text for this datablock."); + RNA_def_property_flag(prop, PROP_REQUIRED); +} + +#endif diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 0c1d974c978..69a7e554452 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -118,6 +118,58 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) Py_RETURN_NONE; } +static PyObject *pyop_as_string( PyObject * self, PyObject * args) +{ + wmOperatorType *ot; + PointerRNA ptr; + + char *opname; + PyObject *kw= NULL; /* optional args */ + int all_args = 1; + int error_val= 0; + + char *buf; + PyObject *pybuf; + + bContext *C = BPy_GetContext(); + + if (!PyArg_ParseTuple(args, "s|O!i:bpy.__ops__.as_string", &opname, &PyDict_Type, &kw, &all_args)) + return NULL; + + ot= WM_operatortype_find(opname, TRUE); + + if (ot == NULL) { + PyErr_Format( PyExc_SystemError, "bpy.__ops__.as_string: operator \"%s\"could not be found", opname); + return NULL; + } + + /* WM_operator_properties_create(&ptr, opname); */ + /* Save another lookup */ + RNA_pointer_create(NULL, ot->srna, NULL, &ptr); + + if(kw && PyDict_Size(kw)) + error_val= pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: "); + + if (error_val==0) + buf= WM_operator_pystring(C, ot, &ptr, all_args); + + WM_operator_properties_free(&ptr); + + if (error_val==-1) { + return NULL; + } + + if(buf) { + pybuf= PyUnicode_FromString(buf); + MEM_freeN(buf); + } + else { + pybuf= PyUnicode_FromString(""); + } + + return pybuf; +} + static PyObject *pyop_dir(PyObject *self) { PyObject *list = PyList_New(0), *name; @@ -162,6 +214,7 @@ static PyObject *pyop_getrna(PyObject *self, PyObject *value) PyObject *BPY_operator_module( void ) { static PyMethodDef pyop_call_meth = {"call", (PyCFunction) pyop_call, METH_VARARGS, NULL}; + static PyMethodDef pyop_as_string_meth ={"as_string", (PyCFunction) pyop_as_string, METH_VARARGS, NULL}; static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL}; static PyMethodDef pyop_getrna_meth = {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL}; static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL}; @@ -171,6 +224,7 @@ PyObject *BPY_operator_module( void ) PyDict_SetItemString(PySys_GetObject("modules"), "bpy.__ops__", submodule); PyModule_AddObject( submodule, "call", PyCFunction_New(&pyop_call_meth, NULL) ); + PyModule_AddObject( submodule, "as_string",PyCFunction_New(&pyop_as_string_meth,NULL) ); PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) ); PyModule_AddObject( submodule, "get_rna", PyCFunction_New(&pyop_getrna_meth, NULL) ); PyModule_AddObject( submodule, "add", PyCFunction_New(&pyop_add_meth, NULL) ); -- cgit v1.2.3 From e03b8b7be7c34450b0e419bbf1d8dfb78a8439b1 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 16 Sep 2009 09:55:06 +0000 Subject: loopcut tool. hold down ctrl-r, then leftclick. due to current limitations on operator design, there isn't any built-in edge sliding to this tool. --- source/blender/editors/mesh/loopcut.c | 67 +++++++++++++++++++++++++++---- source/blender/editors/mesh/mesh_intern.h | 1 + source/blender/editors/mesh/mesh_ops.c | 17 ++++---- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index c7e10d5809f..dfdb713d345 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -93,6 +93,7 @@ typedef struct tringselOpData { EditEdge *eed; int extend; + int do_cut; } tringselOpData; /* modal loop selection drawing callback */ @@ -258,8 +259,14 @@ static void ringsel_finish(bContext *C, wmOperator *op) { tringselOpData *lcd= op->customdata; - if (lcd->eed); + if (lcd->eed) { edgering_sel(lcd, 0, 1); + if (lcd->do_cut) { + EditMesh *em = BKE_mesh_get_editmesh(lcd->ob->data); + esubdivideflag(lcd->ob, em, SELECT, 0.0f, + 0.0f, 0, 1, SUBDIV_SELECT_LOOPCUT); + } + } } /* called when modal loop selection is done... */ @@ -281,7 +288,7 @@ static void ringsel_exit (bContext *C, wmOperator *op) } /* called when modal loop selection gets set up... */ -static int ringsel_init (bContext *C, wmOperator *op) +static int ringsel_init (bContext *C, wmOperator *op, int do_cut) { tringselOpData *lcd; @@ -293,7 +300,8 @@ static int ringsel_init (bContext *C, wmOperator *op) lcd->draw_handle= ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST); lcd->ob = CTX_data_edit_object(C); lcd->em= BKE_mesh_get_editmesh((Mesh *)lcd->ob->data); - lcd->extend = RNA_boolean_get(op->ptr, "extend"); + lcd->extend = do_cut ? 0 : RNA_boolean_get(op->ptr, "extend"); + lcd->do_cut = do_cut; em_setup_viewcontext(C, &lcd->vc); ED_region_tag_redraw(lcd->ar); @@ -317,7 +325,36 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) view3d_operator_needs_opengl(C); - if (!ringsel_init(C, op)) + if (!ringsel_init(C, op, 0)) + return OPERATOR_CANCELLED; + + /* add a modal handler for this operator - handles loop selection */ + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + + lcd = op->customdata; + lcd->vc.mval[0] = evt->mval[0]; + lcd->vc.mval[1] = evt->mval[1]; + + edge = findnearestedge(&lcd->vc, &dist); + if (edge != lcd->eed) { + lcd->eed = edge; + ringsel_find_edge(lcd, C, lcd->ar); + } + + return OPERATOR_RUNNING_MODAL; +} + + +static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + ScrArea *sa = CTX_wm_area(C); + tringselOpData *lcd; + EditEdge *edge; + int dist = 75; + + view3d_operator_needs_opengl(C); + + if (!ringsel_init(C, op, 1)) return OPERATOR_CANCELLED; /* add a modal handler for this operator - handles loop selection */ @@ -379,13 +416,12 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } -// naming is whatever this should use... void MESH_OT_edgering_select (wmOperatorType *ot) { /* description */ - ot->name= "Loop Cut"; + ot->name= "Edge Ring Select"; ot->idname= "MESH_OT_edgering_select"; - ot->description= "Add a new loop between existing loops."; + ot->description= "Select an edge ring"; /* callbacks */ ot->invoke= ringsel_invoke; @@ -398,3 +434,20 @@ void MESH_OT_edgering_select (wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection"); } + +void MESH_OT_loopcut (wmOperatorType *ot) +{ + /* description */ + ot->name= "Loop Cut"; + ot->idname= "MESH_OT_loopcut"; + ot->description= "Add a new loop between existing loops."; + + /* callbacks */ + ot->invoke= ringcut_invoke; + ot->modal= ringsel_modal; + ot->cancel= ringsel_cancel; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; +} diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 887474414b3..11a974f2c49 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -243,6 +243,7 @@ void MESH_OT_sticky_add(struct wmOperatorType *ot); void MESH_OT_sticky_remove(struct wmOperatorType *ot); void MESH_OT_edgering_select(struct wmOperatorType *ot); +void MESH_OT_loopcut(struct wmOperatorType *ot); #endif // MESH_INTERN_H diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 606614cd1f1..6da42f28af4 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -321,8 +321,17 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_specials); WM_operatortype_append(MESH_OT_edgering_select); + WM_operatortype_append(MESH_OT_loopcut); /* macros */ + + /*combining operators with invoke and exec portions doesn't work yet. + + ot= WM_operatortype_append_macro("MESH_OT_loopcut", "Loopcut", OPTYPE_UNDO|OPTYPE_REGISTER); + WM_operatortype_macro_define(ot, "MESH_OT_edgering_select"); + WM_operatortype_macro_define(ot, "MESH_OT_subdivide"); + */ + ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_duplicate"); WM_operatortype_macro_define(ot, "TFM_OT_translate"); @@ -335,12 +344,6 @@ void ED_operatortypes_mesh(void) WM_operatortype_macro_define(ot, "MESH_OT_extrude"); WM_operatortype_macro_define(ot, "TFM_OT_translate"); - /*combining operators with invoke and exec portions doesn't work yet. - - ot= WM_operatortype_append_macro("MESH_OT_loopcut", "Loopcut", OPTYPE_UNDO|OPTYPE_REGISTER); - WM_operatortype_macro_define(ot, "MESH_OT_edgering_select"); - WM_operatortype_macro_define(ot, "MESH_OT_subdivide"); - */ } /* note mesh keymap also for other space? */ @@ -349,7 +352,7 @@ void ED_keymap_mesh(wmWindowManager *wm) ListBase *keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0); wmKeymapItem *kmi; - //WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MESH_OT_loopcut", ACTIONMOUSE, KM_PRESS, KM_CTRL, RKEY); /* selecting */ /* standard mouse selection goes via space_view3d */ -- cgit v1.2.3 From 103e11359d3838ac944f2a8895a41cc26ab9e74b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Sep 2009 10:09:57 +0000 Subject: - rna/python api object.create_render_mesh(...) support for getting a mesh from metaballs and curves (bevel, surface, text etc). - povray converts curves to meshes on export, (metaballs don't need meshing). - use 'extend' bool rather then 'seltype' enum for object_select operators for consistency. --- release/io/engine_render_pov.py | 2 +- source/blender/editors/object/object_select.c | 61 ++++++++-------- source/blender/editors/space_node/node_select.c | 8 -- .../blender/editors/space_view3d/view3d_select.c | 2 +- source/blender/makesrna/intern/rna_object_api.c | 85 +++++++++++++++++++--- 5 files changed, 105 insertions(+), 53 deletions(-) diff --git a/release/io/engine_render_pov.py b/release/io/engine_render_pov.py index 22cf1a36dbb..c1cd84c8978 100644 --- a/release/io/engine_render_pov.py +++ b/release/io/engine_render_pov.py @@ -275,7 +275,7 @@ def write_pov(filename, scene=None, info_callback = None): for ob in sel: ob_num+= 1 - if ob.type in ('LAMP', 'CAMERA', 'EMPTY'): + if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META'): continue me = ob.data diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index cfd65ad18ec..432aaf2d2cb 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -53,6 +53,7 @@ #include "BKE_property.h" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_utildefines.h" #include "WM_api.h" #include "WM_types.h" @@ -117,22 +118,16 @@ void ED_base_object_activate(bContext *C, Base *base) /********************** Selection Operators **********************/ -static EnumPropertyItem prop_select_types[] = { - {0, "EXCLUSIVE", 0, "Exclusive", ""}, - {1, "EXTEND", 0, "Extend", ""}, - {0, NULL, 0, NULL, NULL} -}; - /************************ Select by Type *************************/ static int object_select_by_type_exec(bContext *C, wmOperator *op) { - short obtype, seltype; + short obtype, extend; obtype = RNA_enum_get(op->ptr, "type"); - seltype = RNA_enum_get(op->ptr, "seltype"); + extend= RNA_boolean_get(op->ptr, "extend"); - if (seltype == 0) { + if (extend == 0) { CTX_DATA_BEGIN(C, Base*, base, visible_bases) { ED_base_object_select(base, BA_DESELECT); } @@ -166,9 +161,9 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_enum(ot->srna, "seltype", prop_select_types, 0, "Selection", "Extend selection or clear selection then select"); + /* properties */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); RNA_def_enum(ot->srna, "type", object_type_items, 1, "Type", ""); - } /*********************** Selection by Links *********************/ @@ -192,7 +187,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) Tex *tex=0; int a, b; int nr = RNA_enum_get(op->ptr, "type"); - short changed = 0, seltype; + short changed = 0, extend; /* events (nr): * Object Ipo: 1 * ObData: 2 @@ -202,9 +197,9 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) * PSys: 6 */ - seltype = RNA_enum_get(op->ptr, "seltype"); + extend= RNA_boolean_get(op->ptr, "extend"); - if (seltype == 0) { + if (extend == 0) { CTX_DATA_BEGIN(C, Base*, base, visible_bases) { ED_base_object_select(base, BA_DESELECT); } @@ -327,9 +322,9 @@ void OBJECT_OT_select_linked(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* properties */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", ""); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); - } /*********************** Selected Grouped ********************/ @@ -575,11 +570,11 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); Object *ob; int nr = RNA_enum_get(op->ptr, "type"); - short changed = 0, seltype; + short changed = 0, extend; - seltype = RNA_enum_get(op->ptr, "seltype"); + extend= RNA_boolean_get(op->ptr, "extend"); - if (seltype == 0) { + if (extend == 0) { CTX_DATA_BEGIN(C, Base*, base, visible_bases) { ED_base_object_select(base, BA_DESELECT); } @@ -628,8 +623,8 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", ""); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); } /************************* Select by Layer **********************/ @@ -637,12 +632,12 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot) static int object_select_by_layer_exec(bContext *C, wmOperator *op) { unsigned int layernum; - short seltype; + short extend; - seltype = RNA_enum_get(op->ptr, "seltype"); + extend= RNA_boolean_get(op->ptr, "extend"); layernum = RNA_int_get(op->ptr, "layer"); - if (seltype == 0) { + if (extend == 0) { CTX_DATA_BEGIN(C, Base*, base, visible_bases) { ED_base_object_select(base, BA_DESELECT); } @@ -676,8 +671,9 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* properties */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); RNA_def_int(ot->srna, "layer", 1, 1, 20, "Layer", "", 1, 20); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); } /************************** Select Inverse *************************/ @@ -878,9 +874,9 @@ void object_flip_name (char *name) static int object_select_mirror_exec(bContext *C, wmOperator *op) { char tmpname[32]; - short seltype; + short extend; - seltype = RNA_enum_get(op->ptr, "seltype"); + extend= RNA_boolean_get(op->ptr, "extend"); CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) { @@ -894,7 +890,7 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - if (seltype == 0) ED_base_object_select(primbase, BA_DESELECT); + if (extend == 0) ED_base_object_select(primbase, BA_DESELECT); } CTX_DATA_END; @@ -920,7 +916,7 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first."); } @@ -981,11 +977,11 @@ void OBJECT_OT_select_name(wmOperatorType *ot) static int object_select_random_exec(bContext *C, wmOperator *op) { float percent; - short seltype; + short extend; - seltype = RNA_enum_get(op->ptr, "seltype"); + extend= RNA_boolean_get(op->ptr, "extend"); - if (seltype == 0) { + if (extend == 0) { CTX_DATA_BEGIN(C, Base*, base, visible_bases) { ED_base_object_select(base, BA_DESELECT); } @@ -1020,8 +1016,9 @@ void OBJECT_OT_select_random(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* properties */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "percentage of objects to randomly select", 0.0001f, 1.0f); - RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select"); } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 94e17b56a02..94691dd0ed2 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -224,12 +224,6 @@ void NODE_OT_select(wmOperatorType *ot) /* ****** Border Select ****** */ -static EnumPropertyItem prop_select_types[] = { - {NODE_EXCLUSIVE, "EXCLUSIVE", 0, "Exclusive", ""}, /* right mouse */ - {NODE_EXTEND, "EXTEND", 0, "Extend", ""}, /* left mouse */ - {0, NULL, 0, NULL, NULL} -}; - static int node_borderselect_exec(bContext *C, wmOperator *op) { SpaceNode *snode= CTX_wm_space_node(C); @@ -288,8 +282,6 @@ void NODE_OT_select_border(wmOperatorType *ot) RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); - - RNA_def_enum(ot->srna, "type", prop_select_types, 0, "Type", ""); } /* ****** Select/Deselect All ****** */ diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c639b445f9e..b1fec793b09 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1592,7 +1592,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); - RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first."); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first."); } /* ****** Mouse Select ****** */ diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 6545898c1ab..cfbd363e358 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -38,30 +38,92 @@ #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" +#include "BKE_displist.h" +#include "BKE_object.h" +#include "BKE_main.h" #include "DNA_mesh_types.h" +#include "DNA_curve_types.h" #include "DNA_scene_types.h" /* copied from init_render_mesh (render code) */ -static Mesh *rna_Object_create_render_mesh(Object *ob, Scene *scene) +static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, Scene *scene) { CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; + Object *tmpobj = NULL; DerivedMesh *dm; Mesh *me; - /* TODO: other types */ - if(ob->type != OB_MESH) - return NULL; + switch(ob->type) { + case OB_FONT: + case OB_CURVE: + case OB_SURF: + { + int cage = 0; //XXX -todo + Curve *tmpcu = NULL; + + /* copies object and modifiers (but not the data) */ + tmpobj= copy_object( ob ); + tmpcu = (Curve *)tmpobj->data; + tmpcu->id.us--; + + /* if getting the original caged mesh, delete object modifiers */ + if( cage ) + object_free_modifiers(tmpobj); + + /* copies the data */ + tmpobj->data = copy_curve( (Curve *) ob->data ); + +#if 0 + /* copy_curve() sets disp.first null, so currently not need */ + { + Curve *cu; + cu = (Curve *)tmpobj->data; + if( cu->disp.first ) + MEM_freeN( cu->disp.first ); + cu->disp.first = NULL; + } - dm= mesh_create_derived_render(scene, ob, mask); +#endif - if(!dm) - return NULL; + /* get updated display list, and convert to a mesh */ + makeDispListCurveTypes( scene, tmpobj, 0 ); + nurbs_to_mesh( tmpobj ); - me= add_mesh("tmp_render_mesh"); - me->id.us--; /* we don't assign it to anything */ - DM_to_mesh(dm, me); - dm->release(dm); + /* nurbs_to_mesh changes the type tp a mesh, check it worked */ + if (tmpobj->type != OB_MESH) { + free_libblock_us( &(CTX_data_main(C)->object), tmpobj ); + printf("cant convert curve to mesh. Does the curve have any segments?" ); // XXX use report api + } + me = tmpobj->data; + free_libblock_us( &(CTX_data_main(C)->object), tmpobj ); + break; + } + case OB_MBALL: + /* metaballs don't have modifiers, so just convert to mesh */ + ob = find_basis_mball( ob ); + /* todo, re-generatre for render-res */ + // metaball_polygonize(scene, ob) + me = add_mesh("Mesh"); + mball_to_mesh( &ob->disp, me ); + break; + case OB_MESH: + { + dm= mesh_create_derived_render(scene, ob, mask); + // dm= mesh_create_derived_view(scene, ob, mask); + + if(!dm) + return NULL; + + me= add_mesh("tmp_render_mesh"); + me->id.us--; /* we don't assign it to anything */ + DM_to_mesh(dm, me); + dm->release(dm); + break; + } + default: + return NULL; + } { /* update the material */ @@ -94,6 +156,7 @@ void RNA_api_object(StructRNA *srna) func= RNA_def_function(srna, "create_render_mesh", "rna_Object_create_render_mesh"); RNA_def_function_ui_description(func, "Create a Mesh datablock with all modifiers applied."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); prop= RNA_def_pointer(func, "scene", "Scene", "", ""); RNA_def_property_flag(prop, PROP_REQUIRED); prop= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); -- cgit v1.2.3 From 42af96ed4277de4e275094229cad83329c33cf62 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 16 Sep 2009 14:02:01 +0000 Subject: use platform.uname instead of os.uname (suggested by Carsten on the ml), it's more portable --- release/io/netrender/slave.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 1dcb608931e..cec5439fc63 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -1,4 +1,4 @@ -import sys, os +import sys, os, platform import http, http.client, http.server, urllib import subprocess, time @@ -10,10 +10,10 @@ MAX_TIMEOUT = 10 INCREMENT_TIMEOUT = 1 def slave_Info(): - sysname, nodename, release, version, machine = os.uname() + sysname, nodename, release, version, machine, processor = platform.uname() slave = netrender.model.RenderSlave() slave.name = nodename - slave.stats = sysname + " " + release + " " + machine + slave.stats = sysname + " " + release + " " + machine + " " + processor return slave def testCancel(conn, job_id): -- cgit v1.2.3 From 9fea9d065d80b12b3750c8fe777114c0522a105c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 14:45:10 +0000 Subject: 2.5: fix bug in Levels node, giving NULL pointer free warnings. --- source/blender/nodes/intern/CMP_nodes/CMP_levels.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c index 28b769a8a97..6056e9a28f4 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c @@ -329,8 +329,8 @@ bNodeType cmp_node_view_levels= { /* execfunc */ node_composit_exec_view_levels, /* butfunc */ NULL, /* initfunc */ node_composit_init_view_levels, - /* freestoragefunc */ node_free_standard_storage, - /* copystoragefunc */ node_copy_standard_storage, + /* freestoragefunc */ NULL, + /* copystoragefunc */ NULL, /* id */ NULL }; -- cgit v1.2.3 From b5b0a62c9715130ac371356cd2511371e14b9d40 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 16 Sep 2009 15:00:35 +0000 Subject: netrender: default temp path on windows to something more useful --- release/io/netrender/ui.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index df2b6288fb0..2ec0b62de4a 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -213,11 +213,18 @@ NetRenderSettings.BoolProperty( attr="server_broadcast", description="broadcast server address on local network", default = True) -NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "/tmp/") +if os.name == 'nt': + NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = "C:/tmp/") +else: + NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = "/tmp/") NetRenderSettings.StringProperty( attr="job_name", name="Job name", -- cgit v1.2.3 From 7c5695c8011d128d7a40b28bf2146fdaab063dbe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Sep 2009 15:55:00 +0000 Subject: - bpy.data.sounds was a collection of ID's rather then Sounds - last commit, missed include for rna_object_api.c & bad args to find_basis_mball - use enum for GHOST tablet type None/Stylus/Eraser, had duplicate definition for these in C. Only tested X11, may need to cast to an int for other OS's. --- intern/ghost/GHOST_Types.h | 8 +++++++- intern/ghost/intern/GHOST_SystemX11.cpp | 6 +++--- intern/ghost/intern/GHOST_WindowCarbon.cpp | 2 +- intern/ghost/intern/GHOST_WindowWin32.cpp | 4 ++-- intern/ghost/intern/GHOST_WindowX11.cpp | 2 +- source/blender/editors/interface/interface_handlers.c | 2 +- source/blender/makesrna/intern/rna_main.c | 4 ++-- source/blender/makesrna/intern/rna_object_api.c | 3 ++- source/blender/windowmanager/WM_types.h | 6 +----- source/blender/windowmanager/intern/wm_event_system.c | 4 ++-- source/blender/windowmanager/wm_event_types.h | 2 +- 11 files changed, 23 insertions(+), 20 deletions(-) diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 2441251dc33..73ed0bdd1fa 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -64,8 +64,14 @@ typedef enum * the pen's angle in 3D space vertically downwards on to the XY plane * --Matt */ +typedef enum { + GHOST_kTabletModeNone = 0, + GHOST_kTabletModeStylus, + GHOST_kTabletModeEraser +} GHOST_TTabletMode; + typedef struct GHOST_TabletData { - char Active; /* 0=None, 1=Stylus, 2=Eraser */ + GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */ float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */ float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */ float Ytilt; /* as above */ diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 5dba76adb02..9f6f3b4d5b0 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -684,12 +684,12 @@ GHOST_SystemX11::processEvent(XEvent *xe) { XProximityNotifyEvent* data = (XProximityNotifyEvent*)xe; if(data->deviceid == window->GetXTablet().StylusID) - window->GetXTablet().CommonData.Active= 1; + window->GetXTablet().CommonData.Active= GHOST_kTabletModeStylus; else if(data->deviceid == window->GetXTablet().EraserID) - window->GetXTablet().CommonData.Active= 2; + window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser; } else if(xe->type == window->GetXTablet().ProxOutEvent) - window->GetXTablet().CommonData.Active= 0; + window->GetXTablet().CommonData.Active= GHOST_kTabletModeNone; break; } diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp index 87bb86a37e7..362e949a0a4 100644 --- a/intern/ghost/intern/GHOST_WindowCarbon.cpp +++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp @@ -183,7 +183,7 @@ GHOST_WindowCarbon::GHOST_WindowCarbon( updateDrawingContext(); activateDrawingContext(); - m_tablet.Active = 0; + m_tablet.Active = GHOST_kTabletModeNone; } } diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 366adb3ab86..7cc75979030 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -244,7 +244,7 @@ GHOST_WindowWin32::GHOST_WindowWin32( m_tablet = fpWTOpen( m_hWnd, &lc, TRUE ); if (m_tablet) { m_tabletData = new GHOST_TabletData(); - m_tabletData->Active = 0; + m_tabletData->Active = GHOST_kTabletModeNone; } } } @@ -704,7 +704,7 @@ void GHOST_WindowWin32::processWin32TabletInitEvent() } } - m_tabletData->Active = 0; + m_tabletData->Active = GHOST_kTabletModeNone; } } } diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 3aff9d64a17..708256f75f5 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -425,7 +425,7 @@ void GHOST_WindowX11::initXInputDevices() XDeviceInfo* device_info = XListInputDevices(m_display, &device_count); m_xtablet.StylusDevice = 0; m_xtablet.EraserDevice = 0; - m_xtablet.CommonData.Active= 0; + m_xtablet.CommonData.Active= GHOST_kTabletModeNone; /* Install our error handler to override Xlib's termination behavior */ old_handler = XSetErrorHandler(ApplicationErrorHandler) ; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 152695c9162..1041418b059 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2116,7 +2116,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton wmTabletData *wmtab= event->customdata; /* de-sensitise based on tablet pressure */ - if (ELEM(wmtab->Active, DEV_STYLUS, DEV_ERASER)) + if (wmtab->Active != EVT_TABLET_NONE) fac *= wmtab->Pressure; } diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 344135acaff..910a15890cb 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -259,9 +259,9 @@ void RNA_def_main(BlenderRNA *brna) {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", NULL, NULL}, {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", NULL, NULL}, {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL, NULL}, - {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks.", NULL, NULL}, + {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED).", NULL, NULL}, {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", NULL, NULL}, - {"sounds", "ID", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", NULL, NULL}, + {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", NULL, NULL}, {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", NULL, NULL}, {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", NULL, NULL}, {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", NULL, NULL}, diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index cfbd363e358..e51dcbe3c57 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -40,6 +40,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_object.h" +#include "BKE_mball.h" #include "BKE_main.h" #include "DNA_mesh_types.h" @@ -101,7 +102,7 @@ static Mesh *rna_Object_create_render_mesh(Object *ob, bContext *C, Scene *scene } case OB_MBALL: /* metaballs don't have modifiers, so just convert to mesh */ - ob = find_basis_mball( ob ); + ob = find_basis_mball(scene, ob); /* todo, re-generatre for render-res */ // metaball_polygonize(scene, ob) me = add_mesh("Mesh"); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 806f5409b0a..c24cf783063 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -276,12 +276,8 @@ typedef struct wmGesture { } wmGesture; /* ************** custom wmEvent data ************** */ - -#define DEV_STYLUS 1 -#define DEV_ERASER 2 - typedef struct wmTabletData { - int Active; /* 0=None, 1=Stylus, 2=Eraser */ + int Active; /* 0=EVT_TABLET_NONE, 1=EVT_TABLET_STYLUS, 2=EVT_TABLET_ERASER */ float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */ float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */ float Ytilt; /* as above */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 306b99dcfcc..9d5bd13ea25 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1498,10 +1498,10 @@ static void update_tablet_data(wmWindow *win, wmEvent *event) const GHOST_TabletData *td= GHOST_GetTabletData(win->ghostwin); /* if there's tablet data from an active tablet device then add it */ - if ((td != NULL) && td->Active) { + if ((td != NULL) && td->Active != GHOST_kTabletModeNone) { struct wmTabletData *wmtab= MEM_mallocN(sizeof(wmTabletData), "customdata tablet"); - wmtab->Active = td->Active; + wmtab->Active = (int)td->Active; wmtab->Pressure = td->Pressure; wmtab->Xtilt = td->Xtilt; wmtab->Ytilt = td->Ytilt; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 3da621bda85..b331e036b9e 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -40,7 +40,7 @@ #define EVT_DATA_GESTURE 2 #define EVT_DATA_TIMER 3 -/* tablet active */ +/* tablet active, matches GHOST_TTabletMode */ #define EVT_TABLET_NONE 0 #define EVT_TABLET_STYLUS 1 #define EVT_TABLET_ERASER 2 -- cgit v1.2.3 From 6b5ba700594051b834008020b9371601ee52268c Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 16 Sep 2009 17:13:03 +0000 Subject: 2.5 Ghost Compile Fix for windows. Patch by b333rt. Thanks! --- intern/ghost/intern/GHOST_WindowWin32.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 7cc75979030..e2caf31edee 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -720,15 +720,15 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam) switch (pkt.pkCursor) { case 0: /* first device */ case 3: /* second device */ - m_tabletData->Active = 0; /* puck - not yet supported */ + m_tabletData->Active = GHOST_kTabletModeNone; /* puck - not yet supported */ break; case 1: case 4: - m_tabletData->Active = 1; /* stylus */ + m_tabletData->Active = GHOST_kTabletModeStylus; /* stylus */ break; case 2: case 5: - m_tabletData->Active = 2; /* eraser */ + m_tabletData->Active = GHOST_kTabletModeEraser; /* eraser */ break; } if (m_maxPressure > 0) { -- cgit v1.2.3 From feff78170d088bc2c2b5c0824c247895ea0987b1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 18:04:01 +0000 Subject: RNA * PROP_NEVER_NULL is now a flag instead of a subtype. * It works for function parameters too now, so setting this flag can help avoid NULL checks in the function. * Renamed LocalLamp to PointLamp, making it consistent with the UI name. * Set icons for the different lamp struct types. --- source/blender/makesrna/RNA_access.h | 2 +- source/blender/makesrna/RNA_types.h | 4 +- source/blender/makesrna/intern/makesrna.c | 1 - source/blender/makesrna/intern/rna_access.c | 13 ++- source/blender/makesrna/intern/rna_brush.c | 3 +- source/blender/makesrna/intern/rna_define.c | 4 +- source/blender/makesrna/intern/rna_key.c | 6 +- source/blender/makesrna/intern/rna_lamp.c | 18 ++-- source/blender/makesrna/intern/rna_material.c | 23 +++-- source/blender/makesrna/intern/rna_modifier.c | 21 +++-- source/blender/makesrna/intern/rna_object.c | 3 +- source/blender/makesrna/intern/rna_particle.c | 10 +- source/blender/makesrna/intern/rna_pose.c | 6 +- source/blender/makesrna/intern/rna_rna.c | 1 - source/blender/makesrna/intern/rna_scene.c | 12 ++- source/blender/makesrna/intern/rna_screen.c | 6 +- source/blender/makesrna/intern/rna_smoke.c | 6 +- source/blender/makesrna/intern/rna_space.c | 9 +- source/blender/makesrna/intern/rna_text.c | 6 +- source/blender/makesrna/intern/rna_ui_api.c | 14 +-- source/blender/makesrna/intern/rna_userdef.c | 129 +++++++++++++++++--------- source/blender/makesrna/intern/rna_wm.c | 6 +- source/blender/makesrna/intern/rna_world.c | 9 +- source/blender/python/intern/bpy_rna.c | 9 +- 24 files changed, 208 insertions(+), 113 deletions(-) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index ca3ac62ba00..40f640473db 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -249,7 +249,6 @@ extern StructRNA RNA_LimitDistanceConstraint; extern StructRNA RNA_LimitLocationConstraint; extern StructRNA RNA_LimitRotationConstraint; extern StructRNA RNA_LimitScaleConstraint; -extern StructRNA RNA_LocalLamp; extern StructRNA RNA_LockedTrackConstraint; extern StructRNA RNA_MagicTexture; extern StructRNA RNA_Main; @@ -329,6 +328,7 @@ extern StructRNA RNA_PointCache; extern StructRNA RNA_PointDensity; extern StructRNA RNA_PointDensityTexture; extern StructRNA RNA_PointerProperty; +extern StructRNA RNA_PointLamp; extern StructRNA RNA_Pose; extern StructRNA RNA_PoseChannel; extern StructRNA RNA_Property; diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index e7fe86afd03..353c859cf27 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -110,9 +110,6 @@ typedef enum PropertySubType { PROP_XYZ = 28, PROP_RGB = 29, - /* pointers */ - PROP_NEVER_NULL = 30, - /* booleans */ PROP_LAYER = 40, PROP_LAYER_MEMBER = 41 @@ -149,6 +146,7 @@ typedef enum PropertyFlag { /* pointers */ PROP_ID_REFCOUNT = 64, + PROP_NEVER_NULL = 262144, /* internal flags */ PROP_BUILTIN = 128, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index d0c7824dc9d..c734cdfec87 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1419,7 +1419,6 @@ static const char *rna_property_subtypename(PropertyType type) case PROP_ACCELERATION: return "PROP_ACCELERATION"; case PROP_XYZ: return "PROP_XYZ"; case PROP_RGB: return "PROP_RGB"; - case PROP_NEVER_NULL: return "PROP_NEVER_NULL"; case PROP_LAYER: return "PROP_LAYER"; case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER"; default: { diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 9472cdb300c..738d52bfbcd 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1409,10 +1409,17 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop) void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value) { - PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop; + IDProperty *idprop; + + if((idprop=rna_idproperty_check(&prop, ptr))) { + /* not supported */ + } + else { + PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop; - if(pprop->set) - pprop->set(ptr, ptr_value); + if(pprop->set && !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL)) + pprop->set(ptr, ptr_value); + } } void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 70daa3690da..eea29381b92 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -219,7 +219,8 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_FIXED_TEX); RNA_def_property_ui_text(prop, "Fixed Texture", "Keep texture origin in fixed position.");*/ - prop= RNA_def_property(srna, "curve", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_ui_text(prop, "Curve", "Editable falloff curve."); /* texture */ diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 0b54d4a8e14..45517546c16 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -134,7 +134,7 @@ PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop) if(!DefRNA.preprocess) { /* we should never get here */ - fprintf(stderr, "rna_find_property_def: only at preprocess time.\n"); + fprintf(stderr, "rna_find_struct_property_def: only at preprocess time.\n"); return NULL; } @@ -155,6 +155,7 @@ PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop) return NULL; } +#if 0 static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop) { PropertyDefRNA *dprop; @@ -175,6 +176,7 @@ static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop) return NULL; } +#endif FunctionDefRNA *rna_find_function_def(FunctionRNA *func) { diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index fbe339fe7f3..e66ee683e61 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -414,7 +414,8 @@ static void rna_def_key(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Key", "Shape keys datablock containing different shapes of geometric datablocks."); RNA_def_struct_ui_icon(srna, ICON_SHAPEKEY_DATA); - prop= RNA_def_property(srna, "reference_key", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "reference_key", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_sdna(prop, NULL, "refkey"); RNA_def_property_ui_text(prop, "Reference Key", ""); @@ -426,7 +427,8 @@ static void rna_def_key(BlenderRNA *brna) rna_def_animdata_common(srna); - prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "from"); RNA_def_property_ui_text(prop, "User", "Datablock using these shape keys."); diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index dc59a75edbc..d00a0d61bf6 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -99,7 +99,7 @@ static StructRNA* rna_Lamp_refine(struct PointerRNA *ptr) switch(la->type) { case LA_LOCAL: - return &RNA_LocalLamp; + return &RNA_PointLamp; case LA_SUN: return &RNA_SunLamp; case LA_SPOT: @@ -477,13 +477,14 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL); } -static void rna_def_local_lamp(BlenderRNA *brna) +static void rna_def_point_lamp(BlenderRNA *brna) { StructRNA *srna; - srna= RNA_def_struct(brna, "LocalLamp", "Lamp"); + srna= RNA_def_struct(brna, "PointLamp", "Lamp"); RNA_def_struct_sdna(srna, "Lamp"); - RNA_def_struct_ui_text(srna, "Local Lamp", "Omnidirectional point lamp."); + RNA_def_struct_ui_text(srna, "Point Lamp", "Omnidirectional point lamp."); + RNA_def_struct_ui_icon(srna, ICON_LAMP_POINT); rna_def_lamp_falloff(srna); rna_def_lamp_shadow(srna, 0, 0); @@ -502,6 +503,7 @@ static void rna_def_area_lamp(BlenderRNA *brna) srna= RNA_def_struct(brna, "AreaLamp", "Lamp"); RNA_def_struct_sdna(srna, "Lamp"); RNA_def_struct_ui_text(srna, "Area Lamp", "Directional area lamp."); + RNA_def_struct_ui_icon(srna, ICON_LAMP_AREA); rna_def_lamp_shadow(srna, 0, 1); @@ -571,6 +573,7 @@ static void rna_def_spot_lamp(BlenderRNA *brna) srna= RNA_def_struct(brna, "SpotLamp", "Lamp"); RNA_def_struct_sdna(srna, "Lamp"); RNA_def_struct_ui_text(srna, "Spot Lamp", "Directional cone lamp."); + RNA_def_struct_ui_icon(srna, ICON_LAMP_SPOT); rna_def_lamp_falloff(srna); rna_def_lamp_shadow(srna, 1, 0); @@ -683,11 +686,13 @@ static void rna_def_sun_lamp(BlenderRNA *brna) srna= RNA_def_struct(brna, "SunLamp", "Lamp"); RNA_def_struct_sdna(srna, "Lamp"); RNA_def_struct_ui_text(srna, "Sun Lamp", "Constant direction parallel ray lamp."); + RNA_def_struct_ui_icon(srna, ICON_LAMP_SUN); rna_def_lamp_shadow(srna, 0, 0); /* sky */ - prop= RNA_def_property(srna, "sky", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "sky", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "LampSkySettings"); RNA_def_property_pointer_funcs(prop, "rna_Lamp_sky_settings_get", NULL, NULL); RNA_def_property_ui_text(prop, "Sky Settings", "Sky related settings for sun lamps."); @@ -702,12 +707,13 @@ static void rna_def_hemi_lamp(BlenderRNA *brna) srna= RNA_def_struct(brna, "HemiLamp", "Lamp"); RNA_def_struct_sdna(srna, "Lamp"); RNA_def_struct_ui_text(srna, "Hemi Lamp", "180 degree constant lamp."); + RNA_def_struct_ui_icon(srna, ICON_LAMP_HEMI); } void RNA_def_lamp(BlenderRNA *brna) { rna_def_lamp(brna); - rna_def_local_lamp(brna); + rna_def_point_lamp(brna); rna_def_area_lamp(brna); rna_def_spot_lamp(brna); rna_def_sun_lamp(brna); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index e23333713c4..18c0dc42e17 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -667,6 +667,7 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "ramp_col"); RNA_def_property_struct_type(prop, "ColorRamp"); RNA_def_property_ui_text(prop, "Diffuse Ramp", "Color ramp used to affect diffuse shading."); + RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL); prop= RNA_def_property(srna, "use_specular_ramp", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_RAMP_SPEC); @@ -678,6 +679,7 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "ramp_spec"); RNA_def_property_struct_type(prop, "ColorRamp"); RNA_def_property_ui_text(prop, "Specular Ramp", "Color ramp used to affect specular shading."); + RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL); prop= RNA_def_property(srna, "diffuse_ramp_blend", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "rampblend_col"); @@ -1615,37 +1617,44 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); /* nested structs */ - prop= RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "MaterialRaytraceMirror"); RNA_def_property_pointer_funcs(prop, "rna_Material_mirror_get", NULL, NULL); RNA_def_property_ui_text(prop, "Raytrace Mirror", "Raytraced reflection settings for the material."); - prop= RNA_def_property(srna, "raytrace_transparency", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "raytrace_transparency", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "MaterialRaytraceTransparency"); RNA_def_property_pointer_funcs(prop, "rna_Material_transp_get", NULL, NULL); RNA_def_property_ui_text(prop, "Raytrace Transparency", "Raytraced reflection settings for the material."); - prop= RNA_def_property(srna, "volume", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "volume", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "vol"); RNA_def_property_struct_type(prop, "MaterialVolume"); RNA_def_property_ui_text(prop, "Volume", "Volume settings for the material."); - prop= RNA_def_property(srna, "halo", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "halo", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "MaterialHalo"); RNA_def_property_pointer_funcs(prop, "rna_Material_halo_get", NULL, NULL); RNA_def_property_ui_text(prop, "Halo", "Halo settings for the material."); - prop= RNA_def_property(srna, "subsurface_scattering", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "subsurface_scattering", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "MaterialSubsurfaceScattering"); RNA_def_property_pointer_funcs(prop, "rna_Material_sss_get", NULL, NULL); RNA_def_property_ui_text(prop, "Subsurface Scattering", "Subsurface scattering settings for the material."); - prop= RNA_def_property(srna, "strand", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "strand", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "MaterialStrand"); RNA_def_property_pointer_funcs(prop, "rna_Material_strand_get", NULL, NULL); RNA_def_property_ui_text(prop, "Strand", "Strand settings for the material."); - prop= RNA_def_property(srna, "physics", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "physics", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "MaterialPhysics"); RNA_def_property_pointer_funcs(prop, "rna_Material_physics_get", NULL, NULL); RNA_def_property_ui_text(prop, "Physics", "Game physics settings."); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 32e34559f1f..ffc2d78a6ce 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -930,12 +930,14 @@ static void rna_def_modifier_softbody(BlenderRNA *brna) RNA_def_struct_sdna(srna, "SoftbodyModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_SOFT); - prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "SoftBodySettings"); RNA_def_property_pointer_funcs(prop, "rna_SoftBodyModifier_settings_get", NULL, NULL); RNA_def_property_ui_text(prop, "Soft Body Settings", ""); - prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "PointCache"); RNA_def_property_pointer_funcs(prop, "rna_SoftBodyModifier_point_cache_get", NULL, NULL); RNA_def_property_ui_text(prop, "Soft Body Point Cache", ""); @@ -1551,15 +1553,18 @@ static void rna_def_modifier_cloth(BlenderRNA *brna) RNA_def_struct_sdna(srna, "ClothModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_CLOTH); - prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "sim_parms"); RNA_def_property_ui_text(prop, "Cloth Settings", ""); - prop= RNA_def_property(srna, "collision_settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "collision_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "coll_parms"); RNA_def_property_ui_text(prop, "Cloth Collision Settings", ""); - prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_ui_text(prop, "Point Cache", ""); } @@ -1609,7 +1614,8 @@ static void rna_def_modifier_collision(BlenderRNA *brna) RNA_def_struct_sdna(srna, "CollisionModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_PHYSICS); - prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "CollisionSettings"); RNA_def_property_pointer_funcs(prop, "rna_CollisionModifier_settings_get", NULL, NULL); RNA_def_property_ui_text(prop, "Settings", ""); @@ -1780,7 +1786,8 @@ static void rna_def_modifier_fluidsim(BlenderRNA *brna) RNA_def_struct_sdna(srna, "FluidsimModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_FLUIDSIM); - prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "fss"); RNA_def_property_ui_text(prop, "Settings", "Settings for how this object is used in the fluid simulation."); } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 3d43dfdfc2c..8e805597e11 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1224,7 +1224,8 @@ static void rna_def_object(BlenderRNA *brna) /* game engine */ - prop= RNA_def_property(srna, "game", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "game", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "GameObjectSettings"); RNA_def_property_pointer_funcs(prop, "rna_Object_game_settings_get", NULL, NULL); RNA_def_property_ui_text(prop, "Game Settings", "Game engine related settings for the object."); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index bbbb13c6e97..02fa0c25335 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1871,10 +1871,10 @@ static void rna_def_particle_system(BlenderRNA *brna) /* access to particle settings is redirected through functions */ /* to allow proper id-buttons functionality */ - prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); //RNA_def_property_pointer_sdna(prop, NULL, "part"); RNA_def_property_struct_type(prop, "ParticleSettings"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL); RNA_def_property_pointer_funcs(prop, "rna_particle_settings_get", "rna_particle_settings_set", NULL); RNA_def_property_ui_text(prop, "Settings", "Particle system settings."); RNA_def_property_update(prop, 0, "rna_Particle_reset"); @@ -1904,9 +1904,10 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Hair Dynamics", "Enable hair dynamics using cloth simulation."); RNA_def_property_update(prop, 0, "rna_Particle_hair_dynamics"); - prop= RNA_def_property(srna, "cloth", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "cloth", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "clmd"); RNA_def_property_struct_type(prop, "ClothModifier"); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Cloth", "Cloth dynamics for hair"); @@ -2082,7 +2083,8 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Particle_reset"); /* pointcache */ - prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "pointcache"); RNA_def_property_struct_type(prop, "PointCache"); RNA_def_property_ui_text(prop, "Point Cache", ""); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index b568fb38dfb..b5c0716bed1 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -428,7 +428,8 @@ static void rna_def_bone_group(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); // TODO: editing the colors for this should result in changes to the color type... - prop= RNA_def_property(srna, "colors", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "colors", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "ThemeBoneColorSet"); RNA_def_property_pointer_sdna(prop, NULL, "cs"); /* NOTE: the DNA data is not really a pointer, but this code works :) */ RNA_def_property_ui_text(prop, "Colors", "Copy of the colors associated with the group's color set."); @@ -486,7 +487,8 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update"); /* Relationships to other bones */ - prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "Bone"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Bone", "Bone associated with this Pose Channel."); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 196d25ada86..37a1c9fb186 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -853,7 +853,6 @@ static void rna_def_property(BlenderRNA *brna) {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""}, {PROP_XYZ, "XYZ", 0, "XYZ", ""}, {PROP_RGB, "RGB", 0, "RGB", ""}, - {PROP_NEVER_NULL, "NEVER_NULL", 0, "Never Null", ""}, {PROP_LAYER, "LAYER", 0, "Layer", ""}, {PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 15329b126d3..e82f25a11fd 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2032,19 +2032,22 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_KEYINGSET, NULL); /* Tool Settings */ - prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "toolsettings"); RNA_def_property_struct_type(prop, "ToolSettings"); RNA_def_property_ui_text(prop, "Tool Settings", ""); /* Unit Settings */ - prop= RNA_def_property(srna, "unit_settings", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "unit_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "unit"); RNA_def_property_struct_type(prop, "UnitSettings"); RNA_def_property_ui_text(prop, "Unit Settings", "Unit editing settings"); /* Render Data */ - prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "r"); RNA_def_property_struct_type(prop, "SceneRenderData"); RNA_def_property_ui_text(prop, "Render Data", ""); @@ -2056,7 +2059,8 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Timeline Markers", "Markers used in all timelines for the current scene."); /* Game Settings */ - prop= RNA_def_property(srna, "game_data", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "game_data", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "gm"); RNA_def_property_struct_type(prop, "SceneGameData"); RNA_def_property_ui_text(prop, "Game Data", ""); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 7a243327bd1..2a72845dd42 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -135,10 +135,10 @@ static void rna_def_screen(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Screen", "Screen datablock, defining the layout of areas in a window."); RNA_def_struct_ui_icon(srna, ICON_SPLITSCREEN); - prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NEVER_NULL); - RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen."); - RNA_def_property_flag(prop, PROP_EDITABLE); + prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL); RNA_def_property_pointer_funcs(prop, NULL, "rna_Screen_scene_set", NULL); + RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen."); RNA_def_property_update(prop, 0, "rna_Screen_scene_update"); prop= RNA_def_property(srna, "areas", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 943129c7169..7bccd685c1d 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -211,11 +211,13 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x "); RNA_def_property_update(prop, 0, NULL); - prop= RNA_def_property(srna, "point_cache_low", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache_low", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "point_cache[0]"); RNA_def_property_ui_text(prop, "Point Cache", ""); - prop= RNA_def_property(srna, "point_cache_high", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "point_cache_high", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]"); RNA_def_property_ui_text(prop, "Point Cache", ""); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index bb01ab9a9c7..c2f565e4912 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -491,7 +491,8 @@ static void rna_def_background_image(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); - prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "iuser"); RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); @@ -779,7 +780,8 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); - prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "iuser"); RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); @@ -808,7 +810,8 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); /* uv */ - prop= RNA_def_property(srna, "uv_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "uv_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "SpaceUVEditor"); RNA_def_property_pointer_funcs(prop, "rna_SpaceImageEditor_uvedit_get", NULL, NULL); RNA_def_property_ui_text(prop, "UV Editor", "UV editor settings."); diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c index 22cf7e7aeae..8c9b2b58887 100644 --- a/source/blender/makesrna/intern/rna_text.c +++ b/source/blender/makesrna/intern/rna_text.c @@ -198,7 +198,8 @@ static void rna_def_text(BlenderRNA *brna) RNA_def_property_struct_type(prop, "TextLine"); RNA_def_property_ui_text(prop, "Lines", "Lines of text."); - prop= RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "curl"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "TextLine"); @@ -209,7 +210,8 @@ static void rna_def_text(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Current Character", "Index of current character in current line, and also start index of character in selection if one exists."); - prop= RNA_def_property(srna, "selection_end_line", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "selection_end_line", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "sell"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "TextLine"); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index e3cae8ab453..16bc988a54b 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -89,7 +89,7 @@ static void api_ui_item_rna_common(FunctionRNA *func) PropertyRNA *parm; parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); - RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); RNA_def_property_flag(parm, PROP_REQUIRED); } @@ -146,7 +146,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); RNA_def_boolean(func, "slider", 0, "", "Use slider widget for numeric values."); RNA_def_boolean(func, "toggle", 0, "", "Use toggle widget for boolean values."); - RNA_def_boolean(func, "icon_only", 0, "", "Only show the property's icon, with no text"); + RNA_def_boolean(func, "icon_only", 0, "", "Draw only icons in buttons, no text."); func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); api_ui_item_rna_common(func); @@ -165,7 +165,7 @@ void RNA_api_ui_layout(StructRNA *srna) api_ui_item_common(func); api_ui_item_rna_common(func); parm= RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in."); - RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_string(func, "search_property", "", 0, "", "Identifier of search collection property."); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -254,21 +254,21 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); parm= RNA_def_pointer(func, "data", "Modifier", "", "Modifier data."); - RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); RNA_def_function_return(func, parm); func= RNA_def_function(srna, "template_constraint", "uiTemplateConstraint"); parm= RNA_def_pointer(func, "data", "Constraint", "", "Constraint data."); - RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in."); RNA_def_function_return(func, parm); func= RNA_def_function(srna, "template_preview", "uiTemplatePreview"); parm= RNA_def_pointer(func, "id", "ID", "", "ID datablock."); RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "parent", "ID", "", "ID datablock."); - parm= RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot."); + RNA_def_pointer(func, "parent", "ID", "", "ID datablock."); + RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot."); func= RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping"); parm= RNA_def_pointer(func, "curvemap", "CurveMapping", "", "Curve mapping pointer."); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 1a000525fda..b38475469b0 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -197,25 +197,29 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna) RNA_def_property_range(prop, 0.5, 2.0); RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas."); - prop= RNA_def_property(srna, "paneltitle", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "paneltitle", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "paneltitle"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Panel Font", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "grouplabel", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "grouplabel", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "grouplabel"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Group Label Font", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "widgetlabel", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "widgetlabel", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "widgetlabel"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Widget Label Font", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "widget", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "widget", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "widget"); RNA_def_property_struct_type(prop, "ThemeFontStyle"); RNA_def_property_ui_text(prop, "Widget Font", ""); @@ -334,97 +338,113 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) RNA_def_struct_sdna(srna, "ThemeUI"); RNA_def_struct_ui_text(srna, "Theme User Interface", "Theme settings for user interface elements."); - prop= RNA_def_property(srna, "wcol_regular", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_regular", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_regular"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Regular Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_tool", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_tool", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_tool"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Tool Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_radio", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_radio", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_radio"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Radio Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_text", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_text", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_text"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Text Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_option", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_option", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_option"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Option Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_toggle"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Toggle Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_num"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Number Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_numslider", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_numslider", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_numslider"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Slider Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_box", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_box", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_box"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Box Backdrop Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_menu", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_menu", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Menu Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_pulldown", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_pulldown", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_pulldown"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Pulldown Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_menu_back", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_menu_back", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu_back"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Menu Backdrop Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_menu_item", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_menu_item", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_menu_item"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Menu Item Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_scroll"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "Scroll Widget Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_list_item", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_list_item", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_list_item"); RNA_def_property_struct_type(prop, "ThemeWidgetColors"); RNA_def_property_ui_text(prop, "List Item Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "wcol_state", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "wcol_state", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "wcol_state"); RNA_def_property_struct_type(prop, "ThemeWidgetStateColors"); RNA_def_property_ui_text(prop, "State Colors", ""); @@ -1380,87 +1400,104 @@ static void rna_def_userdef_themes(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Name", "Name of the theme."); RNA_def_struct_name_property(srna, prop); - prop= RNA_def_property(srna, "user_interface", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "user_interface", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tui"); RNA_def_property_struct_type(prop, "ThemeUserInterface"); RNA_def_property_ui_text(prop, "User Interface", ""); - prop= RNA_def_property(srna, "view_3d", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "view_3d", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tv3d"); RNA_def_property_struct_type(prop, "ThemeView3D"); RNA_def_property_ui_text(prop, "3D View", ""); - prop= RNA_def_property(srna, "graph_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "graph_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tipo"); RNA_def_property_struct_type(prop, "ThemeGraphEditor"); RNA_def_property_ui_text(prop, "Graph Editor", ""); - prop= RNA_def_property(srna, "file_browser", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "file_browser", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tfile"); RNA_def_property_struct_type(prop, "ThemeFileBrowser"); RNA_def_property_ui_text(prop, "File Browser", ""); - prop= RNA_def_property(srna, "nla_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "nla_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tnla"); RNA_def_property_struct_type(prop, "ThemeNLAEditor"); RNA_def_property_ui_text(prop, "NLA Editor", ""); - prop= RNA_def_property(srna, "dopesheet_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "dopesheet_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tact"); RNA_def_property_struct_type(prop, "ThemeDopeSheet"); RNA_def_property_ui_text(prop, "DopeSheet", ""); - prop= RNA_def_property(srna, "image_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "image_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tima"); RNA_def_property_struct_type(prop, "ThemeImageEditor"); RNA_def_property_ui_text(prop, "Image Editor", ""); - prop= RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tseq"); RNA_def_property_struct_type(prop, "ThemeSequenceEditor"); RNA_def_property_ui_text(prop, "Sequence Editor", ""); - prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tbuts"); RNA_def_property_struct_type(prop, "ThemeProperties"); RNA_def_property_ui_text(prop, "Properties", ""); - prop= RNA_def_property(srna, "text_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "text_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "text"); RNA_def_property_struct_type(prop, "ThemeTextEditor"); RNA_def_property_ui_text(prop, "Text Editor", ""); - prop= RNA_def_property(srna, "timeline", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "timeline", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "ttime"); RNA_def_property_struct_type(prop, "ThemeTimeline"); RNA_def_property_ui_text(prop, "Timeline", ""); - prop= RNA_def_property(srna, "node_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "node_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tnode"); RNA_def_property_struct_type(prop, "ThemeNodeEditor"); RNA_def_property_ui_text(prop, "Node Editor", ""); - prop= RNA_def_property(srna, "logic_editor", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "logic_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tlogic"); RNA_def_property_struct_type(prop, "ThemeLogicEditor"); RNA_def_property_ui_text(prop, "Logic Editor", ""); - prop= RNA_def_property(srna, "outliner", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "outliner", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "toops"); RNA_def_property_struct_type(prop, "ThemeOutliner"); RNA_def_property_ui_text(prop, "Outliner", ""); - prop= RNA_def_property(srna, "info", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "info", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tinfo"); RNA_def_property_struct_type(prop, "ThemeInfo"); RNA_def_property_ui_text(prop, "Info", ""); - prop= RNA_def_property(srna, "user_preferences", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "user_preferences", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "tuserpref"); RNA_def_property_struct_type(prop, "ThemeUserPreferences"); RNA_def_property_ui_text(prop, "User Preferences", ""); - prop= RNA_def_property(srna, "bone_color_sets", PROP_COLLECTION, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "bone_color_sets", PROP_COLLECTION, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_collection_sdna(prop, NULL, "tarm", ""); RNA_def_property_struct_type(prop, "ThemeBoneColorSet"); RNA_def_property_ui_text(prop, "Bone Color Sets", ""); @@ -2100,7 +2137,8 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_CUSTOM_RANGE); RNA_def_property_ui_text(prop, "Use Weight Color Range", "Enable color range used for weight visualization in weight painting mode."); - prop= RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "coba_weight"); RNA_def_property_struct_type(prop, "ColorRamp"); RNA_def_property_ui_text(prop, "Weight Color Range", "Color range used for weight visualization in weight painting mode."); @@ -2331,27 +2369,32 @@ void RNA_def_userdef(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Styles", ""); /* nested structs */ - prop= RNA_def_property(srna, "view", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "view", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "UserPreferencesView"); RNA_def_property_pointer_funcs(prop, "rna_UserDef_view_get", NULL, NULL); RNA_def_property_ui_text(prop, "View & Controls", "Preferences related to viewing data."); - prop= RNA_def_property(srna, "edit", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "edit", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "UserPreferencesEdit"); RNA_def_property_pointer_funcs(prop, "rna_UserDef_edit_get", NULL, NULL); RNA_def_property_ui_text(prop, "Edit Methods", "Settings for interacting with Blender data."); - prop= RNA_def_property(srna, "language", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "language", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "UserPreferencesLanguage"); RNA_def_property_pointer_funcs(prop, "rna_UserDef_language_get", NULL, NULL); RNA_def_property_ui_text(prop, "Language & Font", "User interface translation settings."); - prop= RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "UserPreferencesFilePaths"); RNA_def_property_pointer_funcs(prop, "rna_UserDef_filepaths_get", NULL, NULL); RNA_def_property_ui_text(prop, "File Paths", "Default paths for external files."); - prop= RNA_def_property(srna, "system", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "system", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "UserPreferencesSystem"); RNA_def_property_pointer_funcs(prop, "rna_UserDef_system_get", NULL, NULL); RNA_def_property_ui_text(prop, "System & OpenGL", "Graphics driver and operating system settings."); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 53532e3f383..fff51ad8ade 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -278,7 +278,8 @@ static void rna_def_operator(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Name", ""); RNA_def_struct_name_property(srna, prop); - prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "OperatorProperties"); RNA_def_property_ui_text(prop, "Properties", ""); RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL); @@ -404,7 +405,8 @@ static void rna_def_window(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Window", "Open window."); RNA_def_struct_sdna(srna, "wmWindow"); - prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "Screen"); RNA_def_property_ui_text(prop, "Screen", "Active screen showing in the window."); RNA_def_property_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index d2eebbc61aa..c6068d0a650 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -461,17 +461,20 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_update(prop, NC_WORLD, NULL); /* nested structs */ - prop= RNA_def_property(srna, "ambient_occlusion", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "ambient_occlusion", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "WorldAmbientOcclusion"); RNA_def_property_pointer_funcs(prop, "rna_World_ambient_occlusion_get", NULL, NULL); RNA_def_property_ui_text(prop, "Ambient Occlusion", "World ambient occlusion settings."); - prop= RNA_def_property(srna, "mist", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "mist", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "WorldMistSettings"); RNA_def_property_pointer_funcs(prop, "rna_World_mist_get", NULL, NULL); RNA_def_property_ui_text(prop, "Mist", "World mist settings."); - prop= RNA_def_property(srna, "stars", PROP_POINTER, PROP_NEVER_NULL); + prop= RNA_def_property(srna, "stars", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "WorldStarsSettings"); RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL); RNA_def_property_ui_text(prop, "Stars", "World stars settings."); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index c2335bea995..65c701c0041 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -628,17 +628,18 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v case PROP_POINTER: { StructRNA *ptype= RNA_property_pointer_type(ptr, prop); + int flag = RNA_property_flag(prop); if(!BPy_StructRNA_Check(value) && value != Py_None) { - PointerRNA tmp; - RNA_pointer_create(NULL, ptype, NULL, &tmp); - PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(tmp.type)); + PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptype)); + return -1; + } else if((flag & PROP_NEVER_NULL) && value == Py_None) { + PyErr_Format(PyExc_TypeError, "property can't be assigned a None value"); return -1; } else { BPy_StructRNA *param= (BPy_StructRNA*)value; int raise_error= FALSE; if(data) { - int flag = RNA_property_flag(prop); if(flag & PROP_RNAPTR) { if(value == Py_None) -- cgit v1.2.3 From 615624805129f989a735a9edf20c9f562725063b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 18:05:28 +0000 Subject: UI: fix region edges cursor to show the right direction, was always vertical now. --- source/blender/editors/screen/screen_edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 5d938ba36cc..2cc5500c3ef 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1140,7 +1140,7 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event) if(az->type==AZONE_AREA) WM_cursor_set(win, CURSOR_EDIT); else if(az->type==AZONE_REGION) { - if(az->x1==az->x2) + if(az->edge == 'l' || az->edge == 'r') WM_cursor_set(win, CURSOR_X_MOVE); else WM_cursor_set(win, CURSOR_Y_MOVE); -- cgit v1.2.3 From 4596f0ee5ea4139ccf3df787df503940a0f8fef2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 18:07:49 +0000 Subject: File Browser * Fix warning for non-existing "relative_paths" property. * Fix problem where the image browser would keep trying to load images it failed opening. --- source/blender/editors/space_file/file_ops.c | 7 ++++--- source/blender/editors/space_file/filelist.c | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 0e0ad88906e..faca6db75bf 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -531,9 +531,10 @@ int file_exec(bContext *C, wmOperator *unused) RNA_string_set(op->ptr, "directory", name); strcat(name, sfile->params->file); - if ( RNA_boolean_get(op->ptr, "relative_paths") ) { - BLI_makestringcode(G.sce, name); - } + if(RNA_struct_find_property(op->ptr, "relative_paths")) + if(RNA_boolean_get(op->ptr, "relative_paths")) + BLI_makestringcode(G.sce, name); + RNA_string_set(op->ptr, "path", name); /* some ops have multiple files to select */ diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index c0b16e639c0..582a5997ef5 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -592,10 +592,12 @@ void filelist_loadimage_timer(struct FileList* filelist) } if (limg->done) { FileImage *oimg = limg; - BLI_remlink(&filelist->loadimages, oimg); BLI_remove_thread(&filelist->threads, oimg); + /* brecht: keep failed images in the list, otherwise + it keeps trying to load them over and over? + BLI_remlink(&filelist->loadimages, oimg); + MEM_freeN(oimg);*/ limg = oimg->next; - MEM_freeN(oimg); refresh = 1; } else { limg= limg->next; -- cgit v1.2.3 From e0d36b73a1e364f70de315afb915b68d74a8e170 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 16 Sep 2009 18:22:53 +0000 Subject: #19317: Some more missing notifiers for the "2 open properties windows" scenario. Scene Buttons should be fine now. --- source/blender/makesrna/intern/rna_scene.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index e82f25a11fd..68b29919ff4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1302,7 +1302,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "planes"); RNA_def_property_enum_items(prop, color_mode_items); RNA_def_property_ui_text(prop, "Color Mode", "Choose BW for saving greyscale images, RGB for saving red, green and blue channels, AND RGBA for saving red, green, blue + alpha channels"); - + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + prop= RNA_def_property(srna, "resolution_x", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "xsch"); RNA_def_property_range(prop, 4, 10000); @@ -1319,6 +1320,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "size"); RNA_def_property_ui_range(prop, 1, 100, 10, 1); RNA_def_property_ui_text(prop, "Resolution %", "Percentage scale for render resolution"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "parts_x", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "xparts"); @@ -1574,6 +1576,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, field_order_items); RNA_def_property_ui_text(prop, "Field Order", "Order of video fields. Select which lines get rendered first, to create smooth motion for TV output"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "fields_still", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_FIELDSTILL); @@ -1643,6 +1646,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, threads_mode_items); RNA_def_property_ui_text(prop, "Threads Mode", "Determine the amount of render threads used"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "motion_blur", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR); @@ -1726,6 +1730,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "displaymode"); RNA_def_property_enum_items(prop, display_mode_items); RNA_def_property_ui_text(prop, "Display", "Select where rendered images will be displayed"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "output_path", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "pic"); -- cgit v1.2.3 From 6b5ce9366d176a753348fcf1f2753f76cd164a2f Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 16 Sep 2009 18:32:03 +0000 Subject: Fixed Resolution and Aspect Ratio Notifier for camera mode in 3D View. NC_OBJECT, won't do it alone, added ND_DRAW. --- source/blender/makesrna/intern/rna_scene.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 68b29919ff4..08efa13d8f4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1308,13 +1308,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "xsch"); RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution X", "Number of horizontal pixels in the rendered image."); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL); prop= RNA_def_property(srna, "resolution_y", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ysch"); RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image."); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL); prop= RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "size"); @@ -1338,13 +1338,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "xasp"); RNA_def_property_range(prop, 1.0f, 200.0f); RNA_def_property_ui_text(prop, "Pixel Aspect X", "Horizontal aspect ratio - for anamorphic or non-square pixel output"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL); prop= RNA_def_property(srna, "pixel_aspect_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yasp"); RNA_def_property_range(prop, 1.0f, 200.0f); RNA_def_property_ui_text(prop, "Pixel Aspect Y", "Vertical aspect ratio - for anamorphic or non-square pixel output"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, NULL); /* JPEG and AVI JPEG */ -- cgit v1.2.3 From de59f34be0a2da17a90950aef1c87a0bb6c74052 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 18:32:10 +0000 Subject: UI: action editor header now also uses template for browsing action datablocks, was last place using deprecated uiDefIDPoinButs. --- source/blender/editors/space_action/action_edit.c | 34 +++++++++++ .../blender/editors/space_action/action_header.c | 67 +++------------------- .../blender/editors/space_action/action_intern.h | 2 + source/blender/editors/space_action/action_ops.c | 1 + source/blender/makesrna/intern/rna_space.c | 46 +++++++++++---- 5 files changed, 82 insertions(+), 68 deletions(-) diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 89633d0cdfe..9e05c482ecb 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1331,4 +1331,38 @@ void ACT_OT_mirror (wmOperatorType *ot) RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", ""); } +/* ******************** New Action Operator *********************** */ + +static int act_new_exec(bContext *C, wmOperator *op) +{ + bAction *action; + + // XXX need to restore behaviour to copy old actions... + action= add_empty_action("Action"); + + /* combined with RNA property, this will assign & increase user, + so decrease here to compensate for that */ + action->id.us--; + + /* set notifier that keyframes have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); + + return OPERATOR_FINISHED; +} + +void ACT_OT_new (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New"; + ot->idname= "ACT_OT_new"; + ot->description= "Create new action."; + + /* api callbacks */ + ot->exec= act_new_exec; + ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* ************************************************************************** */ diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index 8674f481a18..57546d440b0 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -260,61 +260,6 @@ static void do_action_buttons(bContext *C, void *arg, int event) } } -static void saction_idpoin_handle(bContext *C, ID *id, int event) -{ - SpaceAction *saction= CTX_wm_space_action(C); - Object *obact= CTX_data_active_object(C); - - printf("actedit do id: \n"); - - switch (event) { - case UI_ID_BROWSE: - printf("browse \n"); - case UI_ID_DELETE: - printf("browse or delete \n"); - saction->action= (bAction*)id; - - /* we must set this action to be the one used by active object (if not pinned) */ - if (saction->pin == 0) { - AnimData *adt= BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */ - - /* set action */ - printf("\tset action \n"); - adt->action= saction->action; - adt->action->id.us++; - } - - ED_area_tag_redraw(CTX_wm_area(C)); - ED_undo_push(C, "Assign Action"); - break; - case UI_ID_RENAME: - printf("actedit rename \n"); - break; - case UI_ID_ADD_NEW: - printf("actedit addnew \n"); - if (saction->pin == 0) { - AnimData *adt= BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */ - - /* set new action */ - // XXX need to restore behaviour to copy old actions... - printf("\tset new action \n"); - adt->action= saction->action= add_empty_action("Action"); - } - break; - case UI_ID_OPEN: - printf("actedit open \n"); - /* XXX not implemented */ - break; - case UI_ID_ALONE: - printf("actedit alone \n"); - /* XXX not implemented */ - break; - case UI_ID_PIN: - printf("actedit pin \n"); - break; - } -} - void action_header_buttons(const bContext *C, ARegion *ar) { ScrArea *sa= CTX_wm_area(C); @@ -409,9 +354,15 @@ void action_header_buttons(const bContext *C, ARegion *ar) xco += 30; } else if (saction->mode == SACTCONT_ACTION) { - /* NAME ETC */ - xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)saction->action, ID_AC, &saction->pin, xco, yco, - saction_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE|UI_ID_FAKE_USER|UI_ID_ALONE|UI_ID_PIN); + uiLayout *layout; + bScreen *sc= CTX_wm_screen(C); + PointerRNA ptr; + + RNA_pointer_create(&sc->id, &RNA_SpaceDopeSheetEditor, saction, &ptr); + + layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, 20+3, 20, 1, U.uistyles.first); + uiTemplateID(layout, (bContext*)C, &ptr, "action", "ACT_OT_new", NULL, NULL); + uiBlockLayoutResolve(C, block, &xco, NULL); xco += 8; } diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index e5f0ab8994e..4326bed62d3 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -99,6 +99,8 @@ void ACT_OT_frame_jump(struct wmOperatorType *ot); void ACT_OT_snap(struct wmOperatorType *ot); void ACT_OT_mirror(struct wmOperatorType *ot); +void ACT_OT_new(struct wmOperatorType *ot); + /* defines for snap keyframes * NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h) */ diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index 42b033040b1..cd4a7b30eff 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -83,6 +83,7 @@ void action_operatortypes(void) WM_operatortype_append(ACT_OT_insert_keyframe); WM_operatortype_append(ACT_OT_copy); WM_operatortype_append(ACT_OT_paste); + WM_operatortype_append(ACT_OT_new); WM_operatortype_append(ACT_OT_previewrange_set); WM_operatortype_append(ACT_OT_view_all); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c2f565e4912..6b6e8b5b98e 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -38,8 +38,7 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" -#include "BKE_paint.h" - +#include "WM_api.h" #include "WM_types.h" EnumPropertyItem space_type_items[] = { @@ -80,11 +79,15 @@ static EnumPropertyItem dc_all_items[] = {DC_RGB, DC_RGBA, DC_ALPHA, DC_Z, DC_LC #ifdef RNA_RUNTIME +#include "DNA_anim_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "BKE_animsys.h" #include "BKE_brush.h" +#include "BKE_colortools.h" #include "BKE_context.h" +#include "BKE_paint.h" #include "ED_image.h" #include "ED_screen.h" @@ -227,13 +230,6 @@ static void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value) st->top= 0; } -static void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value) -{ - SpaceFile *sfile= (SpaceFile*)(ptr->data); - - sfile->params= value.data; -} - /* Space Properties */ static StructRNA *rna_SpaceProperties_pin_id_typef(PointerRNA *ptr) @@ -311,12 +307,36 @@ static void rna_View3D_display_background_image_set(PointerRNA *ptr, int value) } /* Space Time */ + static void rna_SpaceTime_redraw_update(bContext *C, PointerRNA *ptr) { SpaceTime *st= (SpaceTime*)ptr->data; ED_screen_animation_timer_update(C, st->redraws); } +/* Space Dopesheet */ + +static void rna_SpaceDopeSheetEditor_action_set(PointerRNA *ptr, PointerRNA value) +{ + SpaceAction *saction= (SpaceAction*)(ptr->data); + saction->action= value.data; +} + +static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr) +{ + SpaceAction *saction= (SpaceAction*)(ptr->data); + Object *obact= CTX_data_active_object(C); + + /* we must set this action to be the one used by active object (if not pinned) */ + if(obact && saction->pin == 0) { + AnimData *adt= BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */ + + /* set action */ + adt->action= saction->action; + id_us_plus(&adt->action->id); + } +} + #else static void rna_def_space(BlenderRNA *brna) @@ -1039,6 +1059,13 @@ static void rna_def_space_dopesheet(BlenderRNA *brna) srna= RNA_def_struct(brna, "SpaceDopeSheetEditor", "Space"); RNA_def_struct_sdna(srna, "SpaceAction"); RNA_def_struct_ui_text(srna, "Space DopeSheet Editor", "DopeSheet space data."); + + /* data */ + prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceDopeSheetEditor_action_set", NULL); + RNA_def_property_ui_text(prop, "Action", "Action displayed and edited in this space."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_DOPESHEET, "rna_SpaceDopeSheetEditor_action_update"); /* mode */ prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); @@ -1425,7 +1452,6 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) prop= RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "params"); - RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceFileBrowser_params_set", NULL); RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser."); } -- cgit v1.2.3 From 3a6bf17b3ef696c572207d5af3381c6327fe6a92 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 18:47:42 +0000 Subject: UI * Fix problem with curve mapping / color ramps not updating things like previews propertly. Now it uses the RNA update of the pointer from the material/texture/.. so each of those can define their own update, but still share the RNA struct. * Code for these templates is now in interface_templates.c * Fix exception for "axis" property, now it always shows normal widget with the PROP_DIRECTION subtype. * Remove context from uiBlockLayoutResolve, no longer needed. --- release/ui/buttons_data_lamp.py | 2 +- release/ui/buttons_material.py | 6 +- release/ui/buttons_scene.py | 3 +- release/ui/buttons_texture.py | 8 +- release/ui/space_userpref.py | 2 +- release/ui/space_view3d_toolbar.py | 4 +- source/blender/editors/include/UI_interface.h | 8 +- source/blender/editors/interface/interface.c | 24 +- .../blender/editors/interface/interface_handlers.c | 8 +- .../blender/editors/interface/interface_intern.h | 3 + .../blender/editors/interface/interface_layout.c | 48 +- .../blender/editors/interface/interface_regions.c | 2 +- .../editors/interface/interface_templates.c | 505 +++++++++++++++++++-- source/blender/editors/screen/area.c | 6 +- .../blender/editors/space_action/action_header.c | 2 +- source/blender/makesrna/intern/rna_ui_api.c | 8 +- 16 files changed, 546 insertions(+), 93 deletions(-) diff --git a/release/ui/buttons_data_lamp.py b/release/ui/buttons_data_lamp.py index d5aaa5ad679..0dbda46bccf 100644 --- a/release/ui/buttons_data_lamp.py +++ b/release/ui/buttons_data_lamp.py @@ -301,7 +301,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel): def draw(self, context): lamp = context.lamp - self.layout.template_curve_mapping(lamp.falloff_curve) + self.layout.template_curve_mapping(lamp, "falloff_curve") bpy.types.register(DATA_PT_context_lamp) bpy.types.register(DATA_PT_preview) diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py index dc11731d7a9..9f1c216c36b 100644 --- a/release/ui/buttons_material.py +++ b/release/ui/buttons_material.py @@ -28,7 +28,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel): # this manages materials for all engine types engine = context.scene.render_data.engine - return (context.object) and (engine in self.COMPAT_ENGINES) + return (context.material or context.object) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -282,7 +282,7 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel): if mat.use_diffuse_ramp: layout.itemS() - layout.template_color_ramp(mat.diffuse_ramp, expand=True) + layout.template_color_ramp(mat, "diffuse_ramp", expand=True) layout.itemS() row = layout.row() split = row.split(percentage=0.3) @@ -334,7 +334,7 @@ class MATERIAL_PT_specular(MaterialButtonsPanel): if mat.use_specular_ramp: layout.itemS() - layout.template_color_ramp(mat.specular_ramp, expand=True) + layout.template_color_ramp(mat, "specular_ramp", expand=True) layout.itemS() row = layout.row() split = row.split(percentage=0.3) diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index 3c321f11f6e..c25e6352aaf 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -240,7 +240,8 @@ class SCENE_PT_output(RenderButtonsPanel): split = layout.split() col = split.column() - col.itemR(rd, "exr_codec") + col.itemL(text="Codec:") + col.itemR(rd, "exr_codec", text="") subsplit = split.split() col = subsplit.column() diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index 3cea47a236e..c595e2b1cc2 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -96,7 +96,7 @@ class TEXTURE_PT_colors(TextureButtonsPanel): layout.itemR(tex, "use_color_ramp", text="Ramp") if tex.use_color_ramp: - layout.template_color_ramp(tex.color_ramp, expand=True) + layout.template_color_ramp(tex, "color_ramp", expand=True) split = layout.split() @@ -410,10 +410,10 @@ class TEXTURE_PT_image(TextureTypePanel): def draw(self, context): layout = self.layout - + tex = context.texture - layout.template_texture_image(tex) + layout.template_image(tex, "image", tex.image_user) class TEXTURE_PT_image_sampling(TextureTypePanel): __label__ = "Image Sampling" @@ -689,7 +689,7 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel): if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_VELOCITY'): col.itemR(pd, "speed_scale") if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_AGE'): - layout.template_color_ramp(pd.color_ramp, expand=True) + layout.template_color_ramp(pd, "color_ramp", expand=True) col = split.column() col.itemL() diff --git a/release/ui/space_userpref.py b/release/ui/space_userpref.py index cfdabadcee1..267a0b4a78b 100644 --- a/release/ui/space_userpref.py +++ b/release/ui/space_userpref.py @@ -264,7 +264,7 @@ class USERPREF_PT_system(bpy.types.Panel): sub2 = sub1.column() sub2.active = system.use_weight_color_range - sub2.template_color_ramp(system.weight_color_range, expand=True) + sub2.template_color_ramp(system, "weight_color_range", expand=True) sub1.itemS() sub1.itemS() diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index fe0f4ca5a21..f177c81b7b7 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -422,7 +422,7 @@ class VIEW3D_PT_tools_brush(PaintPanel): row.itemR(brush, "strength", slider=True) row.itemR(brush, "strength_pressure", toggle=True, text="") - col.itemR(brush, "blend") + col.itemR(brush, "blend", text="Blend") # Weight Paint Mode # @@ -508,7 +508,7 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel): settings = self.paint_settings(context) brush = settings.brush - layout.template_curve_mapping(brush.curve) + layout.template_curve_mapping(brush, "curve") layout.item_menu_enumO("brush.curve_preset", property="shape") class VIEW3D_PT_sculpt_options(PaintPanel): diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 77c4e4d3475..f475dd16057 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -487,6 +487,7 @@ int uiSearchBoxhHeight(void); void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg); void uiBlockSetButmFunc (uiBlock *block, uiMenuHandleFunc func, void *arg); void uiBlockSetFunc (uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2); +void uiBlockSetNFunc (uiBlock *block, uiButHandleFunc func, void *argN, void *arg2); void uiButSetRenameFunc (uiBut *but, uiButHandleRenameFunc func, void *arg1); void uiButSetFunc (uiBut *but, uiButHandleFunc func, void *arg1, void *arg2); @@ -596,7 +597,7 @@ void UI_exit(void); uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style); void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout); -void uiBlockLayoutResolve(const struct bContext *C, uiBlock *block, int *x, int *y); +void uiBlockLayoutResolve(uiBlock *block, int *x, int *y); uiBlock *uiLayoutGetBlock(uiLayout *layout); @@ -641,10 +642,11 @@ void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr); uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr); void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot); -void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand); -void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type, int compact); +void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand); +void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels); void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname); void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname); +void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *userptr, int compact); void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser); void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); void uiTemplateOperatorSearch(uiLayout *layout); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 221618b340e..2d4b2caa845 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -622,7 +622,7 @@ void uiEndBlock(const bContext *C, uiBlock *block) } /* handle pending stuff */ - if(block->layouts.first) uiBlockLayoutResolve(C, block, NULL, NULL); + if(block->layouts.first) uiBlockLayoutResolve(block, NULL, NULL); ui_block_do_align(block); if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block); @@ -1684,6 +1684,9 @@ void uiFreeBlock(const bContext *C, uiBlock *block) ui_free_but(C, but); } + if(block->func_argN) + MEM_freeN(block->func_argN); + CTX_store_free_list(&block->contexts); BLI_freelistN(&block->saferct); @@ -2232,6 +2235,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short but->func= block->func; but->func_arg1= block->func_arg1; but->func_arg2= block->func_arg2; + + but->funcN= block->funcN; + if(block->func_argN) + but->func_argN= MEM_dupallocN(block->func_argN); but->pos= -1; /* cursor invisible */ @@ -2945,6 +2952,16 @@ void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2 block->func_arg2= arg2; } +void uiBlockSetNFunc(uiBlock *block, uiButHandleFunc func, void *argN, void *arg2) +{ + if(block->func_argN) + MEM_freeN(block->func_argN); + + block->funcN= func; + block->func_argN= argN; + block->func_arg2= arg2; +} + void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1) { but->rename_func= func; @@ -2967,6 +2984,9 @@ void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2) void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) { + if(but->func_argN) + MEM_freeN(but->func_argN); + but->funcN= funcN; but->func_argN= argN; but->func_arg2= arg2; @@ -3003,6 +3023,8 @@ uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, char * { uiBut *but= ui_def_but(block, BLOCK, 0, str, x1, y1, x2, y2, NULL, 0.0, 0.0, 0.0, 0.0, tip); but->block_create_func= func; + if(but->func_argN) + MEM_freeN(but->func_argN); but->func_argN= argN; ui_check_but(but); return but; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 1041418b059..dbf5669b326 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -246,7 +246,13 @@ static void ui_apply_but_func(bContext *C, uiBut *but) if(but->func || but->funcN || block->handle_func || but->rename_func || (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) { after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc"); - after->func= but->func; + if(ELEM(but, but->func_arg1, but->func_arg2)) { + /* exception, this will crash due to removed button otherwise */ + but->func(C, but->func_arg1, but->func_arg2); + } + else + after->func= but->func; + after->func_arg1= but->func_arg1; after->func_arg2= but->func_arg2; after->func_arg3= but->func_arg3; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 2e623114fe9..7ab99a83c4b 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -263,6 +263,9 @@ struct uiBlock { void *func_arg1; void *func_arg2; + uiButHandleNFunc funcN; + void *func_argN; + uiMenuHandleFunc butm_func; void *butm_func_arg; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b6afc4daa9b..b957ff83650 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -481,6 +481,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i { uiLayout *sub; uiBut *but; + PropertyType type; PropertySubType subtype; int labelw; @@ -496,6 +497,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i w= w-labelw; } + type= RNA_property_type(prop); subtype= RNA_property_subtype(prop); if(subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) { @@ -505,8 +507,10 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i /* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */ but= uiDefIconButO(block, BUT, "BUTTONS_OT_file_browse", WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, "Browse for file or directory."); } + else if(subtype == PROP_DIRECTION) + uiDefButR(block, BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL); else - but= uiDefAutoButR(block, ptr, prop, index, (!icon_only)? "": NULL, icon, x, y, w, h); + but= uiDefAutoButR(block, ptr, prop, index, (type == PROP_ENUM && !icon_only)? NULL: "", icon, x, y, w, h); uiBlockSetCurLayout(block, layout); return but; @@ -840,9 +844,6 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper char namestr[UI_MAX_NAME_STR]; int len, w, h, slider, toggle, expand, icon_only; - if(!ptr->data || !prop) - return; - uiBlockSetCurLayout(block, layout); /* retrieve info */ @@ -913,12 +914,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int flag) { - PropertyRNA *prop; - - if(!ptr->data || !propname) - return; - - prop= RNA_struct_find_property(ptr, propname); + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); if(!prop) { ui_item_disabled(layout, propname); @@ -931,12 +927,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value) { - PropertyRNA *prop; - - if(!ptr->data || !propname) - return; - - prop= RNA_struct_find_property(ptr, propname); + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); if(!prop || RNA_property_type(prop) != PROP_ENUM) { ui_item_disabled(layout, propname); @@ -949,15 +940,10 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, void uiItemEnumR_string(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value) { - PropertyRNA *prop; + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); EnumPropertyItem *item; int ivalue, a, free; - if(!ptr->data || !propname) - return; - - prop= RNA_struct_find_property(ptr, propname); - if(!prop || RNA_property_type(prop) != PROP_ENUM) { ui_item_disabled(layout, propname); printf("uiItemEnumR: enum property not found: %s\n", propname); @@ -1123,9 +1109,6 @@ void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *p int w, h; /* validate arguments */ - if(!ptr->data || !searchptr->data) - return; - prop= RNA_struct_find_property(ptr, propname); if(!prop) { @@ -2227,18 +2210,13 @@ static void ui_item_layout(uiItem *item) } } -static void ui_layout_items(const bContext *C, uiBlock *block, uiLayout *layout) -{ - ui_item_estimate(&layout->item); - ui_item_layout(&layout->item); -} - -static void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) +static void ui_layout_end(uiBlock *block, uiLayout *layout, int *x, int *y) { if(layout->root->handlefunc) uiBlockSetButmFunc(block, layout->root->handlefunc, layout->root->argv); - ui_layout_items(C, block, layout); + ui_item_estimate(&layout->item); + ui_item_layout(&layout->item); if(x) *x= layout->x; if(y) *y= layout->y; @@ -2346,7 +2324,7 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) layout->root->argv= argv; } -void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y) +void uiBlockLayoutResolve(uiBlock *block, int *x, int *y) { uiLayoutRoot *root; @@ -2357,7 +2335,7 @@ void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y) for(root=block->layouts.first; root; root=root->next) { /* NULL in advance so we don't interfere when adding button */ - ui_layout_end(C, block, root->layout, x, y); + ui_layout_end(block, root->layout, x, y); ui_layout_free(root->layout); } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index dfcdea59f68..95305819e2b 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2192,7 +2192,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi block->direction= direction; - uiBlockLayoutResolve(C, block, NULL, NULL); + uiBlockLayoutResolve(block, NULL, NULL); if(pup->popup) { uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 2b7d6f383bf..1c7e757fbb2 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -36,6 +36,7 @@ #include "BKE_icons.h" #include "BKE_global.h" #include "BKE_library.h" +#include "BKE_main.h" #include "BKE_utildefines.h" #include "ED_screen.h" @@ -75,7 +76,7 @@ typedef struct TemplateID { } TemplateID; /* Search browse menu, assign */ -static void id_search_call_cb(struct bContext *C, void *arg_template, void *item) +static void id_search_call_cb(bContext *C, void *arg_template, void *item) { TemplateID *template= (TemplateID*)arg_template; @@ -90,7 +91,7 @@ static void id_search_call_cb(struct bContext *C, void *arg_template, void *item } /* ID Search browse menu, do the search */ -static void id_search_cb(const struct bContext *C, void *arg_template, char *str, uiSearchItems *items) +static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSearchItems *items) { TemplateID *template= (TemplateID*)arg_template; Scene *scene= CTX_data_scene(C); @@ -291,7 +292,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6; if(newop) { - but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL); + but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } else { @@ -344,9 +345,6 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname StructRNA *type; int flag; - if(!ptr->data) - return; - prop= RNA_struct_find_property(ptr, propname); if(!prop || RNA_property_type(prop) != PROP_POINTER) { @@ -1241,54 +1239,499 @@ void uiTemplatePreview(uiLayout *layout, ID *id, ID *parent, MTex *slot) /********************** ColorRamp Template **************************/ -void uiTemplateColorRamp(uiLayout *layout, ColorBand *coba, int expand) +#include "BKE_texture.h" + +typedef struct RNAUpdateCb { + PointerRNA ptr; + PropertyRNA *prop; +} RNAUpdateCb; + +static void rna_update_cb(bContext *C, void *arg_cb, void *arg_unused) +{ + RNAUpdateCb *cb= (RNAUpdateCb*)arg_cb; + + /* we call update here on the pointer property, this way the + owner of the curve mapping can still define it's own update + and notifier, even if the CurveMapping struct is shared. */ + RNA_property_update(C, &cb->ptr, cb->prop); +} + +#define B_BANDCOL 1 + +static int vergcband(const void *a1, const void *a2) +{ + const CBData *x1=a1, *x2=a2; + + if( x1->pos > x2->pos ) return 1; + else if( x1->pos < x2->pos) return -1; + return 0; +} + +static void colorband_pos_cb(bContext *C, void *cb_v, void *coba_v) +{ + ColorBand *coba= coba_v; + int a; + + if(coba->tot<2) return; + + for(a=0; atot; a++) coba->data[a].cur= a; + qsort(coba->data, coba->tot, sizeof(CBData), vergcband); + for(a=0; atot; a++) { + if(coba->data[a].cur==coba->cur) { + coba->cur= a; + break; + } + } + + rna_update_cb(C, cb_v, NULL); +} + +static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v) +{ + ColorBand *coba= coba_v; + + if(coba->tot < MAXCOLORBAND-1) coba->tot++; + coba->cur= coba->tot-1; + + colorband_pos_cb(C, cb_v, coba_v); + + ED_undo_push(C, "Add colorband"); +} + +static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v) +{ + ColorBand *coba= coba_v; + int a; + + if(coba->tot<2) return; + + for(a=coba->cur; atot; a++) { + coba->data[a]= coba->data[a+1]; + } + if(coba->cur) coba->cur--; + coba->tot--; + + ED_undo_push(C, "Delete colorband"); + + rna_update_cb(C, cb_v, NULL); +} + + +/* offset aligns from bottom, standard width 300, height 115 */ +static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb) +{ + CBData *cbd; + uiBut *bt; + + if(coba==NULL) return; + + bt= uiDefBut(block, BUT, 0, "Add", 0+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Add a new color stop to the colorband"); + uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba); + + bt= uiDefBut(block, BUT, 0, "Delete", 60+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Delete the active position"); + uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba); + + uiDefButS(block, NUM, 0, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Choose active color stop"); + + bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", + 210+xoffs, 100+yoffs, 90, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + uiBlockEndAlign(block); + + bt= uiDefBut(block, BUT_COLORBAND, 0, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + + cbd= coba->data + coba->cur; + + bt= uiDefButF(block, NUM, 0, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop"); + uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba); + bt= uiDefButF(block, COL, 0, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + bt= uiDefButF(block, NUMSLI, 0, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + +} + +static void colorband_buttons_small(uiBlock *block, ColorBand *coba, rctf *butr, RNAUpdateCb *cb) +{ + CBData *cbd; + uiBut *bt; + float unit= (butr->xmax-butr->xmin)/14.0f; + float xs= butr->xmin; + + cbd= coba->data + coba->cur; + + + bt= uiDefBut(block, BUT, 0, "Add", xs,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband"); + uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba); + bt= uiDefBut(block, BUT, 0, "Delete", xs+2.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Delete the active position"); + uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba); + + bt= uiDefButF(block, COL, 0, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + bt= uiDefButF(block, NUMSLI, 0, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + + bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", + xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + + bt= uiDefBut(block, BUT_COLORBAND, 0, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, ""); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + + uiBlockEndAlign(block); +} + +static void colorband_buttons_layout(uiBlock *block, ColorBand *coba, rctf *butr, int small, RNAUpdateCb *cb) +{ + if(small) + colorband_buttons_small(block, coba, butr, cb); + else + colorband_buttons_large(block, coba, 0, 0, cb); +} + +void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, char *propname, int expand) { + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); + PointerRNA cptr; + RNAUpdateCb *cb; uiBlock *block; rctf rect; - if(coba) { - rect.xmin= 0; rect.xmax= 200; - rect.ymin= 0; rect.ymax= 190; - - block= uiLayoutFreeBlock(layout); - colorband_buttons(block, coba, &rect, !expand); - } + if(!prop || RNA_property_type(prop) != PROP_POINTER) + return; + + cptr= RNA_property_pointer_get(ptr, prop); + if(!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp)) + return; + + cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); + cb->ptr= *ptr; + cb->prop= prop; + + rect.xmin= 0; rect.xmax= 200; + rect.ymin= 0; rect.ymax= 190; + + block= uiLayoutFreeBlock(layout); + colorband_buttons_layout(block, cptr.data, &rect, !expand, cb); + + MEM_freeN(cb); } /********************* CurveMapping Template ************************/ #include "DNA_color_types.h" +#include "BKE_colortools.h" -void uiTemplateCurveMapping(uiLayout *layout, CurveMapping *cumap, int type, int compact) +static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *unused) { - rctf rect; + CurveMapping *cumap = cumap_v; + float d; + + /* we allow 20 times zoom */ + if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) { + d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin); + cumap->curr.xmin+= d; + cumap->curr.xmax-= d; + d= 0.1154f*(cumap->curr.ymax - cumap->curr.ymin); + cumap->curr.ymin+= d; + cumap->curr.ymax-= d; + } + + ED_region_tag_redraw(CTX_wm_region(C)); +} + +static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *unused) +{ + CurveMapping *cumap = cumap_v; + float d, d1; + + /* we allow 20 times zoom, but dont view outside clip */ + if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) { + d= d1= 0.15f*(cumap->curr.xmax - cumap->curr.xmin); + + if(cumap->flag & CUMA_DO_CLIP) + if(cumap->curr.xmin-d < cumap->clipr.xmin) + d1= cumap->curr.xmin - cumap->clipr.xmin; + cumap->curr.xmin-= d1; + + d1= d; + if(cumap->flag & CUMA_DO_CLIP) + if(cumap->curr.xmax+d > cumap->clipr.xmax) + d1= -cumap->curr.xmax + cumap->clipr.xmax; + cumap->curr.xmax+= d1; + + d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin); + + if(cumap->flag & CUMA_DO_CLIP) + if(cumap->curr.ymin-d < cumap->clipr.ymin) + d1= cumap->curr.ymin - cumap->clipr.ymin; + cumap->curr.ymin-= d1; + + d1= d; + if(cumap->flag & CUMA_DO_CLIP) + if(cumap->curr.ymax+d > cumap->clipr.ymax) + d1= -cumap->curr.ymax + cumap->clipr.ymax; + cumap->curr.ymax+= d1; + } + + ED_region_tag_redraw(CTX_wm_region(C)); +} + +static void curvemap_buttons_setclip(bContext *C, void *cumap_v, void *unused) +{ + CurveMapping *cumap = cumap_v; + + curvemapping_changed(cumap, 0); +} + +static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v) +{ + CurveMapping *cumap = cumap_v; + + curvemap_remove(cumap->cm+cumap->cur, SELECT); + curvemapping_changed(cumap, 0); + + rna_update_cb(C, cb_v, NULL); +} + +/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ +static uiBlock *curvemap_clipping_func(bContext *C, struct ARegion *ar, void *cumap_v) +{ + CurveMapping *cumap = cumap_v; + uiBlock *block; + uiBut *bt; + + block= uiBeginBlock(C, ar, "curvemap_clipping_func", UI_EMBOSS); + + /* use this for a fake extra empy space around the buttons */ + uiDefBut(block, LABEL, 0, "", -4, 16, 128, 106, NULL, 0, 0, 0, 0, ""); + + bt= uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, "Use Clipping", + 0,100,120,18, &cumap->flag, 0.0, 0.0, 10, 0, ""); + uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, 0, "Min X ", 0,74,120,18, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, ""); + uiDefButF(block, NUM, 0, "Min Y ", 0,56,120,18, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, ""); + uiDefButF(block, NUM, 0, "Max X ", 0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "Max Y ", 0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, ""); + + uiBlockSetDirection(block, UI_RIGHT); + + uiEndBlock(C, block); + return block; +} + +static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) +{ + CurveMapping *cumap = cumap_v; + CurveMap *cuma= cumap->cm+cumap->cur; + + switch(event) { + case 0: + curvemap_reset(cuma, &cumap->clipr); + curvemapping_changed(cumap, 0); + break; + case 1: + cumap->curr= cumap->clipr; + break; + case 2: /* set vector */ + curvemap_sethandle(cuma, 1); + curvemapping_changed(cumap, 0); + break; + case 3: /* set auto */ + curvemap_sethandle(cuma, 0); + curvemapping_changed(cumap, 0); + break; + case 4: /* extend horiz */ + cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE; + curvemapping_changed(cumap, 0); + break; + case 5: /* extend extrapolate */ + cuma->flag |= CUMA_EXTEND_EXTRAPOLATE; + curvemapping_changed(cumap, 0); + break; + } + ED_region_tag_redraw(CTX_wm_region(C)); +} + +static uiBlock *curvemap_tools_func(bContext *C, struct ARegion *ar, void *cumap_v) +{ + uiBlock *block; + short yco= 0, menuwidth=120; + + block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS); + uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); + + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset View", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Horizontal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Extrapolated", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Curve", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); + + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block, 50); + + uiEndBlock(C, block); + return block; +} + +static void curvemap_buttons_redraw(bContext *C, void *arg1, void *arg2) +{ + ED_region_tag_redraw(CTX_wm_region(C)); +} + +static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v) +{ + CurveMapping *cumap = cumap_v; + int a; + + for(a=0; acm+a, &cumap->clipr); + + cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f; + cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f; + curvemapping_set_black_white(cumap, NULL, NULL); + + curvemapping_changed(cumap, 0); + + rna_update_cb(C, cb_v, NULL); +} + +/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */ +static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels, RNAUpdateCb *cb) +{ + CurveMapping *cumap= ptr->data; + uiLayout *row, *sub, *split; + uiBlock *block; + uiBut *bt; + float dx= UI_UNIT_X; + int icon, size; - if(cumap) { - if(compact) { - rect.xmin= 0; rect.xmax= 150; - rect.ymin= 0; rect.ymax= 140; + block= uiLayoutGetBlock(layout); + + /* curve chooser */ + row= uiLayoutRow(layout, 0); + + if(labeltype=='v') { + /* vector */ + sub= uiLayoutRow(row, 1); + uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); + + if(cumap->cm[0].curve) { + bt= uiDefButI(block, ROW, 0, "X", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); } - else { - rect.xmin= 0; rect.xmax= 200; - rect.ymin= 0; rect.ymax= 190; + if(cumap->cm[1].curve) { + bt= uiDefButI(block, ROW, 0, "Y", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); } - - curvemap_layout(layout, cumap, type, 0, 0, &rect); + if(cumap->cm[2].curve) { + bt= uiDefButI(block, ROW, 0, "Z", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + } + } + else if(labeltype=='c') { + /* color */ + sub= uiLayoutRow(row, 1); + uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); + + if(cumap->cm[3].curve) { + bt= uiDefButI(block, ROW, 0, "C", 0, 0, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + } + if(cumap->cm[0].curve) { + bt= uiDefButI(block, ROW, 0, "R", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + } + if(cumap->cm[1].curve) { + bt= uiDefButI(block, ROW, 0, "G", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + } + if(cumap->cm[2].curve) { + bt= uiDefButI(block, ROW, 0, "B", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); + uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL); + } + } + else + uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); + + /* operation buttons */ + sub= uiLayoutRow(row, 1); + + uiBlockSetEmboss(block, UI_EMBOSSN); + + bt= uiDefIconBut(block, BUT, 0, ICON_ZOOMIN, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in"); + uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL); + + bt= uiDefIconBut(block, BUT, 0, ICON_ZOOMOUT, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out"); + uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL); + + bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, 18, "Tools"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + + if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT; + bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, 18, "Clipping Options"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + + bt= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points"); + uiButSetNFunc(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap); + + uiBlockSetEmboss(block, UI_EMBOSS); + + uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); + + /* curve itself */ + size= uiLayoutGetWidth(layout); + row= uiLayoutRow(layout, 0); + uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 200), cumap, 0.0f, 1.0f, 0, 0, ""); + + /* black/white levels */ + if(levels) { + split= uiLayoutSplit(layout, 0); + uiItemR(uiLayoutColumn(split, 0), NULL, 0, ptr, "black_level", UI_ITEM_R_EXPAND); + uiItemR(uiLayoutColumn(split, 0), NULL, 0, ptr, "white_level", UI_ITEM_R_EXPAND); + + uiLayoutRow(layout, 0); + bt=uiDefBut(block, BUT, 0, "Reset", 0, 0, UI_UNIT_X*10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves"); + uiButSetNFunc(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap); } + + uiBlockSetNFunc(block, NULL, NULL, NULL); +} + +void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, int type, int levels) +{ + RNAUpdateCb *cb; + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); + PointerRNA cptr; + + if(!prop || RNA_property_type(prop) != PROP_POINTER) + return; + + cptr= RNA_property_pointer_get(ptr, prop); + if(!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping)) + return; + + cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); + cb->ptr= *ptr; + cb->prop= prop; + + curvemap_buttons_layout(layout, &cptr, type, levels, cb); + + MEM_freeN(cb); } /********************* TriColor (ThemeWireColorSet) Template ************************/ void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname) { + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); uiLayout *row; - PropertyRNA *prop; PointerRNA csPtr; - - if (!ptr->data) - return; - - prop= RNA_struct_find_property(ptr, propname); + if (!prop) { printf("uiTemplateTriColorSet: property not found: %s\n", propname); return; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 8940f560677..07d0d1a85c5 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1254,7 +1254,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex pt->draw_header(C, panel); - uiBlockLayoutResolve(C, block, &xco, &yco); + uiBlockLayoutResolve(block, &xco, &yco); panel->labelofs= xco - triangle; panel->layout= NULL; } @@ -1265,7 +1265,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex pt->draw(C, panel); - uiBlockLayoutResolve(C, block, &xco, &yco); + uiBlockLayoutResolve(block, &xco, &yco); panel->layout= NULL; yco -= 2*style->panelspace; @@ -1411,7 +1411,7 @@ void ED_region_header(const bContext *C, ARegion *ar) maxco= xco; } - uiBlockLayoutResolve(C, block, &xco, &yco); + uiBlockLayoutResolve(block, &xco, &yco); /* for view2d */ if(xco > maxco) diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index 57546d440b0..4cb02f3f233 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -362,7 +362,7 @@ void action_header_buttons(const bContext *C, ARegion *ar) layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, 20+3, 20, 1, U.uistyles.first); uiTemplateID(layout, (bContext*)C, &ptr, "action", "ACT_OT_new", NULL, NULL); - uiBlockLayoutResolve(C, block, &xco, NULL); + uiBlockLayoutResolve(block, &xco, NULL); xco += 8; } diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 16bc988a54b..60994757b59 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -271,14 +271,12 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_pointer(func, "slot", "TextureSlot", "", "Texture slot."); func= RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping"); - parm= RNA_def_pointer(func, "curvemap", "CurveMapping", "", "Curve mapping pointer."); - RNA_def_property_flag(parm, PROP_REQUIRED); + api_ui_item_rna_common(func); RNA_def_enum(func, "type", curve_type_items, 0, "Type", "Type of curves to display."); - RNA_def_boolean(func, "compact", 0, "", "Use more compact curve mapping."); + RNA_def_boolean(func, "levels", 0, "", "Show black/white levels."); func= RNA_def_function(srna, "template_color_ramp", "uiTemplateColorRamp"); - parm= RNA_def_pointer(func, "ramp", "ColorRamp", "", "Color ramp pointer."); - RNA_def_property_flag(parm, PROP_REQUIRED); + api_ui_item_rna_common(func); RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); func= RNA_def_function(srna, "template_layers", "uiTemplateLayers"); -- cgit v1.2.3 From 5129b08064817aa4bbb28011a4dc215d320ee9e4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 18:59:13 +0000 Subject: UI * Node buttons can now use the layout engine. a few simple ones are converted. We'll keep this code in C for now, python wouldn't help much here. * For node buttons not using the layout engine, manually computing the button height is not longer needed. * Node inputs are still not RNA wrapped, would be good to have these available as well for keying, but makesrna does not have access to the bNodeTypes. --- source/blender/blenkernel/BKE_node.h | 5 +- source/blender/editors/include/ED_node.h | 5 + source/blender/editors/space_node/drawnode.c | 2675 ++++++++++----------- source/blender/editors/space_node/node_draw.c | 209 +- source/blender/makesdna/DNA_node_types.h | 2 + source/blender/makesrna/intern/rna_nodetree.c | 356 ++- source/blenderplayer/bad_level_call_stubs/stubs.c | 1 + 7 files changed, 1710 insertions(+), 1543 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index cbb37918d04..ea1707c19bf 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -42,7 +42,7 @@ struct bNode; struct bNodeLink; struct bNodeSocket; struct bNodeStack; -struct uiBlock; +struct uiLayout; struct rctf; struct ListBase; struct RenderData; @@ -52,6 +52,7 @@ struct Tex; struct GPUMaterial; struct GPUNode; struct GPUNodeStack; +struct PointerRNA; /* ************** NODE TYPE DEFINITIONS ***** */ @@ -82,7 +83,7 @@ typedef struct bNodeType { void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **); /* this line is set on startup of blender */ - int (*butfunc)(struct uiBlock *, struct bNodeTree *, struct bNode *, struct rctf *); + void (*uifunc)(struct uiLayout *, struct PointerRNA *ptr); void (*initfunc)(struct bNode *); void (*freestoragefunc)(struct bNode *); diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index bf4632dc3da..305b2a64ffe 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -31,10 +31,15 @@ struct Material; struct Scene; struct Tex; +struct bContext; +struct bNode; /* drawnode.c */ void ED_init_node_butfuncs(void); +/* node_draw.c */ +void ED_node_changed_update(struct bContext *C, struct bNode *node); + /* node_edit.c */ void ED_node_shader_default(struct Material *ma); void ED_node_composit_default(struct Scene *sce); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 05adb5b75ca..494a68fc918 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -170,9 +170,13 @@ static void node_group_alone_cb(bContext *C, void *node_v, void *unused_v) /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */ -static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_group(uiLayout *layout, PointerRNA *ptr) { - if(block && node->id) { + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + if(node->id) { uiBut *bt; short width; @@ -197,112 +201,95 @@ static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf * uiBlockEndAlign(block); } - return 19; } #endif -static int node_buts_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_value(uiLayout *layout, PointerRNA *ptr) { - if(block) { - bNodeSocket *sock= node->outputs.first; /* first socket stores value */ - - uiDefButF(block, NUM, B_NODE_EXEC, "", - (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 20, - sock->ns.vec, sock->ns.min, sock->ns.max, 10, 2, ""); - - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + bNodeSocket *sock= node->outputs.first; /* first socket stores value */ + + uiDefButF(block, NUM, B_NODE_EXEC, "", + (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 20, + sock->ns.vec, sock->ns.min, sock->ns.max, 10, 2, ""); } -static int node_buts_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_rgb(uiLayout *layout, PointerRNA *ptr) { - if(block) { - bNodeSocket *sock= node->outputs.first; /* first socket stores value */ - if(sock) { - /* enforce square box drawing */ - uiBlockSetEmboss(block, UI_EMBOSSP); - - uiDefButF(block, HSVCUBE, B_NODE_EXEC, "", - (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 12, - sock->ns.vec, 0.0f, 1.0f, 3, 0, ""); - uiDefButF(block, HSVCUBE, B_NODE_EXEC, "", - (short)butr->xmin, (short)butr->ymin+15, butr->xmax-butr->xmin, butr->ymax-butr->ymin -15 -15, - sock->ns.vec, 0.0f, 1.0f, 2, 0, ""); - uiDefButF(block, COL, B_NOP, "", - (short)butr->xmin, (short)butr->ymax-12, butr->xmax-butr->xmin, 12, - sock->ns.vec, 0.0, 0.0, -1, 0, ""); - /* the -1 above prevents col button to popup a color picker */ - - uiBlockSetEmboss(block, UI_EMBOSS); - } - } - return 30 + (int)(node->width-NODE_DY); -} + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + bNodeSocket *sock= node->outputs.first; /* first socket stores value */ -static int node_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) -{ - if(block) { - uiBut *bt; - int a_but= (ntree->type==NTREE_COMPOSIT); + if(sock) { + /* enforce square box drawing */ + uiBlockSetEmboss(block, UI_EMBOSSP); - /* blend type */ - uiBlockBeginAlign(block); - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Overlay %x9|Divide %x5|Difference %x6|Darken %x7|Lighten %x8|Dodge %x10|Burn %x11|Color %x15|Value %x14|Saturation %x13|Hue %x12|Soft Light %x16|Linear Light %x17", - (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin -(a_but?20:0), 20, - &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); - /* Alpha option, composite */ - if(a_but) - uiDefIconButS(block, TOG, B_NODE_EXEC, ICON_IMAGE_RGB_ALPHA, - (short)butr->xmax-20, (short)butr->ymin, 20, 20, - &node->custom2, 0, 0, 0, 0, "Include Alpha of 2nd input in this operation"); + uiDefButF(block, HSVCUBE, B_NODE_EXEC, "", + (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, 12, + sock->ns.vec, 0.0f, 1.0f, 3, 0, ""); + uiDefButF(block, HSVCUBE, B_NODE_EXEC, "", + (short)butr->xmin, (short)butr->ymin+15, butr->xmax-butr->xmin, butr->xmax-butr->xmin -15 -15, + sock->ns.vec, 0.0f, 1.0f, 2, 0, ""); + uiDefButF(block, COL, B_NOP, "", + (short)butr->xmin, (short)butr->ymax-12, butr->xmax-butr->xmin, 12, + sock->ns.vec, 0.0, 0.0, -1, 0, ""); + /* the -1 above prevents col button to popup a color picker */ + + uiBlockSetEmboss(block, UI_EMBOSS); } - return 20; } -static int node_buts_time(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_mix_rgb(uiLayout *layout, PointerRNA *ptr) { - if(block) { - CurveMapping *cumap= node->storage; - short dx= (short)((butr->xmax-butr->xmin)/2); - butr->ymin += 26; + bNodeTree *ntree= (bNodeTree*)ptr->id.data; + uiLayout *row; - curvemap_buttons(block, node->storage, 's', B_NODE_EXEC, B_REDR, butr); - - if(cumap) { - //cumap->flag |= CUMA_DRAW_CFRA; - //if(node->custom1custom2) - // cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1); - } + row= uiLayoutRow(layout, 1); - uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_NODE_EXEC, "Sta:", - (short)butr->xmin, (short)butr->ymin-22, dx, 19, - &node->custom1, 1.0, 20000.0, 0, 0, "Start frame"); - uiDefButS(block, NUM, B_NODE_EXEC, "End:", - (short)butr->xmin+dx, (short)butr->ymin-22, dx, 19, - &node->custom2, 1.0, 20000.0, 0, 0, "End frame"); - } + uiItemR(row, "", 0, ptr, "blend_type", 0); + if(ntree->type == NTREE_COMPOSIT) + uiItemR(row, "", ICON_IMAGE_RGB_ALPHA, ptr, "alpha", 0); +} + +static void node_buts_time(uiLayout *layout, PointerRNA *ptr) +{ + uiLayout *row; +#if 0 + /* XXX no context access here .. */ + bNode *node= ptr->data; + CurveMapping *cumap= node->storage; - return node->width-NODE_DY; + if(cumap) { + cumap->flag |= CUMA_DRAW_CFRA; + if(node->custom1custom2) + cumap->sample[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1); + } +#endif + + uiTemplateCurveMapping(layout, ptr, "curve", 's', 0); + + row= uiLayoutRow(layout, 1); + uiItemR(row, "Sta", 0, ptr, "start", 0); + uiItemR(row, "End", 0, ptr, "end", 0); } -static int node_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_valtorgb(uiLayout *layout, PointerRNA *ptr) { - if(block) { - if(node->storage) { - uiBlockColorbandButtons(block, node->storage, butr, B_NODE_EXEC); - } + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + if(node->storage) { + uiBlockColorbandButtons(block, node->storage, butr, B_NODE_EXEC); } - return 40; } -static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_curvevec(uiLayout *layout, PointerRNA *ptr) { - if(block) { - curvemap_buttons(block, node->storage, 'v', B_NODE_EXEC, B_REDR, butr); - } - return (int)(node->width-NODE_DY); + uiTemplateCurveMapping(layout, ptr, "mapping", 'v', 0); } static float *_sample_col= NULL; // bad bad, 2.5 will do better? @@ -311,33 +298,31 @@ void node_curvemap_sample(float *col) _sample_col= col; } -static int node_buts_curvecol(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_curvecol(uiLayout *layout, PointerRNA *ptr) { - if(block) { - CurveMapping *cumap= node->storage; - if(_sample_col) { - cumap->flag |= CUMA_DRAW_SAMPLE; - VECCOPY(cumap->sample, _sample_col); - } - else - cumap->flag &= ~CUMA_DRAW_SAMPLE; + bNode *node= ptr->data; + CurveMapping *cumap= node->storage; - curvemap_buttons(block, node->storage, 'c', B_NODE_EXEC, B_REDR, butr); - } - return (int)(node->width-NODE_DY); + if(_sample_col) { + cumap->flag |= CUMA_DRAW_SAMPLE; + VECCOPY(cumap->sample, _sample_col); + } + else + cumap->flag &= ~CUMA_DRAW_SAMPLE; + + uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0); } -static int node_buts_normal(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_normal(uiLayout *layout, PointerRNA *ptr) { - if(block) { - bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ - - uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", - (short)butr->xmin, (short)butr->ymin, butr->xmax-butr->xmin, butr->ymax-butr->ymin, - sock->ns.vec, 0.0f, 1.0f, 0, 0, ""); - - } - return (int)(node->width-NODE_DY); + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ + + uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "", + (short)butr->xmin, (short)butr->xmin, butr->xmax-butr->xmin, butr->xmax-butr->xmin, + sock->ns.vec, 0.0f, 1.0f, 0, 0, ""); } static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v) @@ -401,8 +386,13 @@ static void node_dynamic_update_cb(bContext *C, void *ntree_v, void *node_v) // XXX BIF_preview_changed(ID_MA); } -static int node_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_texture(uiLayout *layout, PointerRNA *ptr) { + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; + short multi = ( node->id && ((Tex*)node->id)->use_nodes && @@ -410,49 +400,44 @@ static int node_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf (node->type != TEX_NODE_TEXTURE) ); - if(block) { - uiBut *bt; - char *strp; - short width = (short)(butr->xmax - butr->xmin); - - /* browse button texture */ - uiBlockBeginAlign(block); - IDnames_to_pupstring(&strp, NULL, "", &(G.main->tex), NULL, NULL); - node->menunr= 0; - bt= uiDefButS(block, MENU, B_NODE_EXEC, strp, - butr->xmin, butr->ymin+(multi?30:0), 20, 19, - &node->menunr, 0, 0, 0, 0, "Browse texture"); - uiButSetFunc(bt, node_browse_tex_cb, ntree, node); - if(strp) MEM_freeN(strp); - - if(node->id) { - bt= uiDefBut(block, TEX, B_NOP, "TE:", - butr->xmin+19, butr->ymin+(multi?30:0), butr->xmax-butr->xmin-19, 19, - node->id->name+2, 0.0, 19.0, 0, 0, "Texture name"); - uiButSetFunc(bt, node_ID_title_cb, node, NULL); - } - uiBlockEndAlign(block); - - if(multi) { - char *menustr = ntreeTexOutputMenu(((Tex*)node->id)->nodetree); - uiDefButS(block, MENU, B_MATPRV, menustr, butr->xmin, butr->ymin, width, 19, &node->custom1, 0, 0, 0, 0, "Which output to use, for multi-output textures"); - free(menustr); - return 50; - } - return 20; - } - else return multi? 50: 20; + uiBut *bt; + char *strp; + short width = (short)(butr->xmax - butr->xmin); + + /* browse button texture */ + uiBlockBeginAlign(block); + IDnames_to_pupstring(&strp, NULL, "", &(G.main->tex), NULL, NULL); + node->menunr= 0; + bt= uiDefButS(block, MENU, B_NODE_EXEC, strp, + butr->xmin, butr->ymin+(multi?30:0), 20, 19, + &node->menunr, 0, 0, 0, 0, "Browse texture"); + uiButSetFunc(bt, node_browse_tex_cb, ntree, node); + if(strp) MEM_freeN(strp); + + if(node->id) { + bt= uiDefBut(block, TEX, B_NOP, "TE:", + butr->xmin+19, butr->ymin+(multi?30:0), butr->xmax-butr->xmin-19, 19, + node->id->name+2, 0.0, 19.0, 0, 0, "Texture name"); + uiButSetFunc(bt, node_ID_title_cb, node, NULL); + } + uiBlockEndAlign(block); + + if(multi) { + char *menustr = ntreeTexOutputMenu(((Tex*)node->id)->nodetree); + uiDefButS(block, MENU, B_MATPRV, menustr, butr->xmin, butr->ymin, width, 19, &node->custom1, 0, 0, 0, 0, "Which output to use, for multi-output textures"); + free(menustr); + } } -static int node_buts_math(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_buts_math(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt; - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14|Less Than %x15|Greater Than %x16", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); - } - return 20; + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14|Less Than %x15|Greater Than %x16", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); + uiButSetFunc(bt, node_but_title_cb, node, bt); } @@ -556,192 +541,192 @@ static void node_texmap_cb(bContext *C, void *texmap_v, void *unused_v) init_mapping(texmap_v); } -static int node_shader_buts_material(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_shader_buts_material(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt; - short dx= (short)((butr->xmax-butr->xmin)/3.0f), has_us= (node->id && node->id->us>1); - short dy= (short)butr->ymin; - char *strp; - - /* WATCH IT: we use this callback in material buttons, but then only want first row */ - if(butr->ymax-butr->ymin > 21.0f) dy+= 19; - - uiBlockBeginAlign(block); - /* XXX - if(node->id==NULL) uiBlockSetCol(block, TH_REDALERT); - else if(has_us) uiBlockSetCol(block, TH_BUT_SETTING1); - else uiBlockSetCol(block, TH_BUT_SETTING2); - */ - - /* browse button */ - IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), NULL, NULL); - node->menunr= 0; - bt= uiDefButS(block, MENU, B_NOP, strp, - butr->xmin, dy, 19, 19, - &node->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW"); - uiButSetFunc(bt, node_browse_mat_cb, ntree, node); - if(strp) MEM_freeN(strp); + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; + uiBut *bt; + short dx= (short)((butr->xmax-butr->xmin)/3.0f), has_us= (node->id && node->id->us>1); + short dy= (short)butr->ymin; + char *strp; + + /* WATCH IT: we use this callback in material buttons, but then only want first row */ + if(butr->ymax-butr->ymin > 21.0f) dy+= 19; + + uiBlockBeginAlign(block); + /* XXX + if(node->id==NULL) uiBlockSetCol(block, TH_REDALERT); + else if(has_us) uiBlockSetCol(block, TH_BUT_SETTING1); + else uiBlockSetCol(block, TH_BUT_SETTING2); + */ + + /* browse button */ + IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), NULL, NULL); + node->menunr= 0; + bt= uiDefButS(block, MENU, B_NOP, strp, + butr->xmin, dy, 19, 19, + &node->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW"); + uiButSetFunc(bt, node_browse_mat_cb, ntree, node); + if(strp) MEM_freeN(strp); + + /* Add New button */ + if(node->id==NULL) { + bt= uiDefBut(block, BUT, B_NOP, "Add New", + butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19, + NULL, 0.0, 0.0, 0, 0, "Add new Material"); + uiButSetFunc(bt, node_new_mat_cb, ntree, node); + } + else { + /* name button */ + short width= (short)(butr->xmax-butr->xmin-19.0f - (has_us?19.0f:0.0f)); + bt= uiDefBut(block, TEX, B_NOP, "MA:", + butr->xmin+19, dy, width, 19, + node->id->name+2, 0.0, 19.0, 0, 0, "Material name"); + uiButSetFunc(bt, node_ID_title_cb, node, NULL); - /* Add New button */ - if(node->id==NULL) { - bt= uiDefBut(block, BUT, B_NOP, "Add New", - butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19, - NULL, 0.0, 0.0, 0, 0, "Add new Material"); - uiButSetFunc(bt, node_new_mat_cb, ntree, node); + /* user amount */ + if(has_us) { + char str1[32]; + sprintf(str1, "%d", node->id->us); + bt= uiDefBut(block, BUT, B_NOP, str1, + butr->xmax-19, dy, 19, 19, + NULL, 0, 0, 0, 0, "Displays number of users. Click to make a single-user copy."); + uiButSetFunc(bt, node_mat_alone_cb, node, NULL); } - else { - /* name button */ - short width= (short)(butr->xmax-butr->xmin-19.0f - (has_us?19.0f:0.0f)); - bt= uiDefBut(block, TEX, B_NOP, "MA:", - butr->xmin+19, dy, width, 19, - node->id->name+2, 0.0, 19.0, 0, 0, "Material name"); - uiButSetFunc(bt, node_ID_title_cb, node, NULL); - - /* user amount */ - if(has_us) { - char str1[32]; - sprintf(str1, "%d", node->id->us); - bt= uiDefBut(block, BUT, B_NOP, str1, - butr->xmax-19, dy, 19, 19, - NULL, 0, 0, 0, 0, "Displays number of users. Click to make a single-user copy."); - uiButSetFunc(bt, node_mat_alone_cb, node, NULL); - } - - /* WATCH IT: we use this callback in material buttons, but then only want first row */ - if(butr->ymax-butr->ymin > 21.0f) { - /* node options */ - uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff", - butr->xmin, butr->ymin, dx, 19, - &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse"); - uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec", - butr->xmin+dx, butr->ymin, dx, 19, - &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular"); - uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal", - butr->xmax-dx, butr->ymin, dx, 19, - &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal"); - } + + /* WATCH IT: we use this callback in material buttons, but then only want first row */ + if(butr->ymax-butr->ymin > 21.0f) { + /* node options */ + uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC, "Diff", + butr->xmin, butr->ymin, dx, 19, + &node->custom1, 0, 0, 0, 0, "Material Node outputs Diffuse"); + uiDefButBitS(block, TOG, SH_NODE_MAT_SPEC, B_NODE_EXEC, "Spec", + butr->xmin+dx, butr->ymin, dx, 19, + &node->custom1, 0, 0, 0, 0, "Material Node outputs Specular"); + uiDefButBitS(block, TOG, SH_NODE_MAT_NEG, B_NODE_EXEC, "Neg Normal", + butr->xmax-dx, butr->ymin, dx, 19, + &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal"); } - uiBlockEndAlign(block); - } - return 38; + } + uiBlockEndAlign(block); } -static int node_shader_buts_mapping(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_shader_buts_mapping(uiLayout *layout, PointerRNA *ptr) { - if(block) { - TexMapping *texmap= node->storage; - short dx= (short)((butr->xmax-butr->xmin)/7.0f); - short dy= (short)(butr->ymax-19); - - uiBlockSetFunc(block, node_texmap_cb, texmap, NULL); /* all buttons get this */ - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->loc+2, -1000.0f, 1000.0f, 10, 2, ""); - dy-= 19; - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->rot+2, -1000.0f, 1000.0f, 1000, 1, ""); - dy-= 19; - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->size+2, -1000.0f, 1000.0f, 10, 2, ""); - dy-= 25; - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->min+2, -10.0f, 10.0f, 100, 2, ""); - dy-= 19; - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->max+2, -10.0f, 10.0f, 10, 2, ""); - uiBlockEndAlign(block); - - /* labels/options */ - - dy= (short)(butr->ymax-19); - uiDefBut(block, LABEL, B_NOP, "Loc", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); - dy-= 19; - uiDefBut(block, LABEL, B_NOP, "Rot", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); - dy-= 19; - uiDefBut(block, LABEL, B_NOP, "Size", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); - dy-= 25; - uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); - dy-= 19; - uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); - - } - return 5*19 + 6; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + TexMapping *texmap= node->storage; + short dx= (short)((butr->xmax-butr->xmin)/7.0f); + short dy= (short)(butr->ymax-19); + + uiBlockSetFunc(block, node_texmap_cb, texmap, NULL); /* all buttons get this */ + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->loc+2, -1000.0f, 1000.0f, 10, 2, ""); + dy-= 19; + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->rot+2, -1000.0f, 1000.0f, 1000, 1, ""); + dy-= 19; + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->size+2, -1000.0f, 1000.0f, 10, 2, ""); + dy-= 25; + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->min+2, -10.0f, 10.0f, 100, 2, ""); + dy-= 19; + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", butr->xmin+5*dx, dy, 2*dx, 19, texmap->max+2, -10.0f, 10.0f, 10, 2, ""); + uiBlockEndAlign(block); + + /* labels/options */ + + dy= (short)(butr->ymax-19); + uiDefBut(block, LABEL, B_NOP, "Loc", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); + dy-= 19; + uiDefBut(block, LABEL, B_NOP, "Rot", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); + dy-= 19; + uiDefBut(block, LABEL, B_NOP, "Size", butr->xmin, dy, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); + dy-= 25; + uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); + dy-= 19; + uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); } -static int node_shader_buts_vect_math(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_shader_buts_vect_math(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt; - - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Average %x2|Dot Product %x3 |Cross Product %x4|Normalize %x5", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt; + + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Average %x2|Dot Product %x3 |Cross Product %x4|Normalize %x5", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); + uiButSetFunc(bt, node_but_title_cb, node, bt); } -static int node_shader_buts_geometry(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_shader_buts_geometry(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *but; - NodeGeometry *ngeo= (NodeGeometry*)node->storage; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *but; + NodeGeometry *ngeo= (NodeGeometry*)node->storage; - // XXX if(!verify_valid_uv_name(ngeo->uvname)) - // XXX uiBlockSetCol(block, TH_REDALERT); - but= uiDefBut(block, TEX, B_NODE_EXEC, "UV:", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, ngeo->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer"); - // XXX uiButSetCompleteFunc(but, autocomplete_uv, NULL); + // XXX if(!verify_valid_uv_name(ngeo->uvname)) + // XXX uiBlockSetCol(block, TH_REDALERT); + but= uiDefBut(block, TEX, B_NODE_EXEC, "UV:", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, ngeo->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer"); + // XXX uiButSetCompleteFunc(but, autocomplete_uv, NULL); - if(!verify_valid_vcol_name(ngeo->colname)); + if(!verify_valid_vcol_name(ngeo->colname)); // uiBlockSetCol(block, TH_REDALERT); - but= uiDefBut(block, TEX, B_NODE_EXEC, "Col:", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, ngeo->colname, 0, 31, 0, 0, "Set name of vertex color layer to use, default is active vertex color layer"); - uiButSetCompleteFunc(but, autocomplete_vcol, NULL); - } - - return 40; + but= uiDefBut(block, TEX, B_NODE_EXEC, "Col:", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, ngeo->colname, 0, 31, 0, 0, "Set name of vertex color layer to use, default is active vertex color layer"); + uiButSetCompleteFunc(but, autocomplete_vcol, NULL); } -static int node_shader_buts_dynamic(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_shader_buts_dynamic(uiLayout *layout, PointerRNA *ptr) { - if (block) { - uiBut *bt; - // XXX SpaceNode *snode= curarea->spacedata.first; - short dy= (short)butr->ymin; - int xoff=0; - - /* B_NODE_EXEC is handled in butspace.c do_node_buts */ - if(!node->id) { - char *strp; - IDnames_to_pupstring(&strp, NULL, "", &(G.main->text), NULL, NULL); - node->menunr= 0; - bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp, - butr->xmin, dy, 19, 19, - &node->menunr, 0, 0, 0, 0, "Browses existing choices"); - uiButSetFunc(bt, node_browse_text_cb, ntree, node); - xoff=19; - if(strp) MEM_freeN(strp); - } - else { - bt = uiDefBut(block, BUT, B_NOP, "Update", - butr->xmin+xoff, butr->ymin+20, 50, 19, - &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)"); - uiButSetFunc(bt, node_dynamic_update_cb, ntree, node); - - if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { - // UI_ThemeColor(TH_REDALERT); - // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect); - // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin); - ; - } + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; + uiBut *bt; + // XXX SpaceNode *snode= curarea->spacedata.first; + short dy= (short)butr->ymin; + int xoff=0; + + /* B_NODE_EXEC is handled in butspace.c do_node_buts */ + if(!node->id) { + char *strp; + IDnames_to_pupstring(&strp, NULL, "", &(G.main->text), NULL, NULL); + node->menunr= 0; + bt= uiDefButS(block, MENU, B_NODE_EXEC/*+node->nr*/, strp, + butr->xmin, dy, 19, 19, + &node->menunr, 0, 0, 0, 0, "Browses existing choices"); + uiButSetFunc(bt, node_browse_text_cb, ntree, node); + xoff=19; + if(strp) MEM_freeN(strp); + } + else { + bt = uiDefBut(block, BUT, B_NOP, "Update", + butr->xmin+xoff, butr->ymin+20, 50, 19, + &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)"); + uiButSetFunc(bt, node_dynamic_update_cb, ntree, node); + + if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { + // UI_ThemeColor(TH_REDALERT); + // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect); + // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin); + ; } } - return 20+19; } /* only once called */ @@ -752,49 +737,49 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_MATERIAL: case SH_NODE_MATERIAL_EXT: - ntype->butfunc= node_shader_buts_material; + ntype->uifunc= node_shader_buts_material; break; case SH_NODE_TEXTURE: - ntype->butfunc= node_buts_texture; + ntype->uifunc= node_buts_texture; break; case SH_NODE_NORMAL: - ntype->butfunc= node_buts_normal; + ntype->uifunc= node_buts_normal; break; case SH_NODE_CURVE_VEC: - ntype->butfunc= node_buts_curvevec; + ntype->uifunc= node_buts_curvevec; break; case SH_NODE_CURVE_RGB: - ntype->butfunc= node_buts_curvecol; + ntype->uifunc= node_buts_curvecol; break; case SH_NODE_MAPPING: - ntype->butfunc= node_shader_buts_mapping; + ntype->uifunc= node_shader_buts_mapping; break; case SH_NODE_VALUE: - ntype->butfunc= node_buts_value; + ntype->uifunc= node_buts_value; break; case SH_NODE_RGB: - ntype->butfunc= node_buts_rgb; + ntype->uifunc= node_buts_rgb; break; case SH_NODE_MIX_RGB: - ntype->butfunc= node_buts_mix_rgb; + ntype->uifunc= node_buts_mix_rgb; break; case SH_NODE_VALTORGB: - ntype->butfunc= node_buts_valtorgb; + ntype->uifunc= node_buts_valtorgb; break; case SH_NODE_MATH: - ntype->butfunc= node_buts_math; + ntype->uifunc= node_buts_math; break; case SH_NODE_VECT_MATH: - ntype->butfunc= node_shader_buts_vect_math; + ntype->uifunc= node_shader_buts_vect_math; break; case SH_NODE_GEOMETRY: - ntype->butfunc= node_shader_buts_geometry; + ntype->uifunc= node_shader_buts_geometry; break; case NODE_DYNAMIC: - ntype->butfunc= node_shader_buts_dynamic; + ntype->uifunc= node_shader_buts_dynamic; break; default: - ntype->butfunc= NULL; + ntype->uifunc= NULL; } } @@ -879,112 +864,102 @@ static void image_layer_cb(bContext *C, void *ima_v, void *iuser_v) // allqueue(REDRAWNODE, 0); } -static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_image(uiLayout *layout, PointerRNA *ptr) { + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; ImageUser *iuser= node->storage; + uiBut *bt; + short dy= (short)butr->ymax-19; + char *strp; - if(block) { - uiBut *bt; - short dy= (short)butr->ymax-19; - char *strp; + uiBlockBeginAlign(block); + + /* browse button */ + IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL); + node->menunr= 0; + bt= uiDefButS(block, MENU, B_NOP, strp, + butr->xmin, dy, 19, 19, + &node->menunr, 0, 0, 0, 0, "Browses existing choices"); + uiButSetFunc(bt, node_browse_image_cb, ntree, node); + if(strp) MEM_freeN(strp); + + /* Add New button */ + if(node->id==NULL) { + bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New", + butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19, + NULL, 0.0, 0.0, 0, 0, "Add new Image"); + uiButSetFunc(bt, node_active_cb, ntree, node); + } + else { + /* name button + type */ + Image *ima= (Image *)node->id; + short xmin= (short)butr->xmin, xmax= (short)butr->xmax; + short width= xmax - xmin - 45; + short icon= ICON_IMAGE_DATA; - uiBlockBeginAlign(block); + if(ima->source==IMA_SRC_MOVIE) icon= ICON_SEQUENCE; + else if(ima->source==IMA_SRC_SEQUENCE) icon= ICON_IMAGE_COL; + else if(ima->source==IMA_SRC_GENERATED) icon= ICON_BLANK1; - /* browse button */ - IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL); - node->menunr= 0; - bt= uiDefButS(block, MENU, B_NOP, strp, - butr->xmin, dy, 19, 19, - &node->menunr, 0, 0, 0, 0, "Browses existing choices"); - uiButSetFunc(bt, node_browse_image_cb, ntree, node); - if(strp) MEM_freeN(strp); + bt= uiDefBut(block, TEX, B_NOP, "IM:", + xmin+19, dy, width, 19, + node->id->name+2, 0.0, 19.0, 0, 0, "Image name"); + uiButSetFunc(bt, node_ID_title_cb, node, NULL); - /* Add New button */ - if(node->id==NULL) { - bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New", - butr->xmin+19, dy, (short)(butr->xmax-butr->xmin-19.0f), 19, - NULL, 0.0, 0.0, 0, 0, "Add new Image"); - uiButSetFunc(bt, node_active_cb, ntree, node); - } - else { - /* name button + type */ - Image *ima= (Image *)node->id; - short xmin= (short)butr->xmin, xmax= (short)butr->xmax; - short width= xmax - xmin - 45; - short icon= ICON_IMAGE_DATA; - - if(ima->source==IMA_SRC_MOVIE) icon= ICON_SEQUENCE; - else if(ima->source==IMA_SRC_SEQUENCE) icon= ICON_IMAGE_COL; - else if(ima->source==IMA_SRC_GENERATED) icon= ICON_BLANK1; - - bt= uiDefBut(block, TEX, B_NOP, "IM:", - xmin+19, dy, width, 19, - node->id->name+2, 0.0, 19.0, 0, 0, "Image name"); - uiButSetFunc(bt, node_ID_title_cb, node, NULL); - - /* buffer type option */ - strp= node_image_type_pup(); - bt= uiDefIconTextButS(block, MENU, B_NOP, icon, strp, - xmax-26, dy, 26, 19, - &ima->source, 0.0, 19.0, 0, 0, "Image type"); - uiButSetFunc(bt, node_image_type_cb, node, ima); - MEM_freeN(strp); + /* buffer type option */ + strp= node_image_type_pup(); + bt= uiDefIconTextButS(block, MENU, B_NOP, icon, strp, + xmax-26, dy, 26, 19, + &ima->source, 0.0, 19.0, 0, 0, "Image type"); + uiButSetFunc(bt, node_image_type_cb, node, ima); + MEM_freeN(strp); + + if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) ) { + width= (xmax-xmin)/2; - if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) ) { - width= (xmax-xmin)/2; - - dy-= 19; - uiDefButI(block, NUM, B_NODE_EXEC, "Frs:", - xmin, dy, width, 19, - &iuser->frames, 1.0, MAXFRAMEF, 0, 0, "Amount of images used in animation"); - uiDefButI(block, NUM, B_NODE_EXEC, "SFra:", - xmin+width, dy, width, 19, - &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Start frame of animation"); + dy-= 19; + uiDefButI(block, NUM, B_NODE_EXEC, "Frs:", + xmin, dy, width, 19, + &iuser->frames, 1.0, MAXFRAMEF, 0, 0, "Amount of images used in animation"); + uiDefButI(block, NUM, B_NODE_EXEC, "SFra:", + xmin+width, dy, width, 19, + &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Start frame of animation"); + dy-= 19; + uiDefButI(block, NUM, B_NODE_EXEC, "Offs:", + xmin, dy, width, 19, + &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); + uiDefButS(block, TOG, B_NODE_EXEC, "Cycl", + xmin+width, dy, width-20, 19, + &iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic"); + uiDefIconButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NODE_EXEC, ICON_AUTO, + xmax-20, dy, 20, 19, + &iuser->flag, 0.0, 0.0, 0, 0, "Always refresh Image on frame changes"); + } + if( ima->type==IMA_TYPE_MULTILAYER && ima->rr) { + RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); + if(rl) { + width= (xmax-xmin); dy-= 19; - uiDefButI(block, NUM, B_NODE_EXEC, "Offs:", + strp= layer_menu(ima->rr); + bt= uiDefButS(block, MENU, B_NODE_EXEC, strp, xmin, dy, width, 19, - &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); - uiDefButS(block, TOG, B_NODE_EXEC, "Cycl", - xmin+width, dy, width-20, 19, - &iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic"); - uiDefIconButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NODE_EXEC, ICON_AUTO, - xmax-20, dy, 20, 19, - &iuser->flag, 0.0, 0.0, 0, 0, "Always refresh Image on frame changes"); - } - if( ima->type==IMA_TYPE_MULTILAYER && ima->rr) { - RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); - if(rl) { - width= (xmax-xmin); - dy-= 19; - strp= layer_menu(ima->rr); - bt= uiDefButS(block, MENU, B_NODE_EXEC, strp, - xmin, dy, width, 19, - &iuser->layer, 0.0, 10000.0, 0, 0, "Layer"); - uiButSetFunc(bt, image_layer_cb, ima->rr, node->storage); - MEM_freeN(strp); - } + &iuser->layer, 0.0, 10000.0, 0, 0, "Layer"); + uiButSetFunc(bt, image_layer_cb, ima->rr, node->storage); + MEM_freeN(strp); } } + } - } if(node->id) { - Image *ima= (Image *)node->id; - int retval= 19; - /* for each draw we test for anim refresh event */ if(iuser->flag & IMA_ANIM_REFRESHED) { iuser->flag &= ~IMA_ANIM_REFRESHED; // addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC); XXX } - - if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE) ) - retval+= 38; - if( ima->type==IMA_TYPE_MULTILAYER) - retval+= 19; - return retval; } - else - return 19; } /* if we use render layers from other scene, we make a nice title */ @@ -1057,9 +1032,14 @@ static void node_browse_scene_cb(bContext *C, void *ntree_v, void *node_v) } -static int node_composit_buts_renderlayers(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_renderlayers(uiLayout *layout, PointerRNA *ptr) { - if(block && node->id) { + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; + + if(node->id) { Scene *scene= (Scene *)node->id; uiBut *bt; char *strp; @@ -1094,7 +1074,6 @@ static int node_composit_buts_renderlayers(uiBlock *block, bNodeTree *ntree, bNo &node->custom2, 0, 0, 0, 0, "Re-render this Layer"); } - return 19; } static void node_blur_relative_cb(bContext *C, void *node, void *poin2) @@ -1126,734 +1105,719 @@ static void node_blur_update_sizey_cb(bContext *C, void *node, void *poin2) nbd->sizey= (int)(nbd->percenty*nbd->image_in_height); } -static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeBlurData *nbd= node->storage; - uiBut *bt; - short dy= butr->ymin+58; - short dx= (butr->xmax-butr->xmin)/2; - char str[256]; - - uiBlockBeginAlign(block); - sprintf(str, "Filter Type%%t|Flat %%x%d|Tent %%x%d|Quad %%x%d|Cubic %%x%d|Gauss %%x%d|Fast Gauss%%x%d|CatRom %%x%d|Mitch %%x%d", R_FILTER_BOX, R_FILTER_TENT, R_FILTER_QUAD, R_FILTER_CUBIC, R_FILTER_GAUSS, R_FILTER_FAST_GAUSS, R_FILTER_CATROM, R_FILTER_MITCH); - uiDefButS(block, MENU, B_NODE_EXEC,str, - butr->xmin, dy, dx*2, 19, - &nbd->filtertype, 0, 0, 0, 0, "Set sampling filter for blur"); - dy-=19; - if (nbd->filtertype != R_FILTER_FAST_GAUSS) { - uiDefButC(block, TOG, B_NODE_EXEC, "Bokeh", - butr->xmin, dy, dx, 19, - &nbd->bokeh, 0, 0, 0, 0, "Uses circular filter, warning it's slow!"); - uiDefButC(block, TOG, B_NODE_EXEC, "Gamma", - butr->xmin+dx, dy, dx, 19, - &nbd->gamma, 0, 0, 0, 0, "Applies filter on gamma corrected values"); - } else { - uiBlockEndAlign(block); - uiBlockBeginAlign(block); - } - dy-=19; - bt= uiDefButS(block, TOG, B_NOP, "Relative", - butr->xmin, dy, dx*2, 19, - &nbd->relative, 0, 0, 0, 0, "Use relative (percent) values to define blur radius"); - uiButSetFunc(bt, node_blur_relative_cb, node, NULL); - - dy-=19; - if(nbd->relative) { - bt= uiDefButF(block, NUM, B_NODE_EXEC, "X:", - butr->xmin, dy, dx, 19, - &nbd->percentx, 0.0f, 1.0f, 0, 0, ""); - uiButSetFunc(bt, node_blur_update_sizex_cb, node, NULL); - bt= uiDefButF(block, NUM, B_NODE_EXEC, "Y:", - butr->xmin+dx, dy, dx, 19, - &nbd->percenty, 0.0f, 1.0f, 0, 0, ""); - uiButSetFunc(bt, node_blur_update_sizey_cb, node, NULL); - } - else { - uiDefButS(block, NUM, B_NODE_EXEC, "X:", - butr->xmin, dy, dx, 19, - &nbd->sizex, 0, 256, 0, 0, ""); - uiDefButS(block, NUM, B_NODE_EXEC, "Y:", - butr->xmin+dx, dy, dx, 19, - &nbd->sizey, 0, 256, 0, 0, ""); - } + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeBlurData *nbd= node->storage; + uiBut *bt; + short dy= butr->ymin+58; + short dx= (butr->xmax-butr->xmin)/2; + char str[256]; + + uiBlockBeginAlign(block); + sprintf(str, "Filter Type%%t|Flat %%x%d|Tent %%x%d|Quad %%x%d|Cubic %%x%d|Gauss %%x%d|Fast Gauss%%x%d|CatRom %%x%d|Mitch %%x%d", R_FILTER_BOX, R_FILTER_TENT, R_FILTER_QUAD, R_FILTER_CUBIC, R_FILTER_GAUSS, R_FILTER_FAST_GAUSS, R_FILTER_CATROM, R_FILTER_MITCH); + uiDefButS(block, MENU, B_NODE_EXEC,str, + butr->xmin, dy, dx*2, 19, + &nbd->filtertype, 0, 0, 0, 0, "Set sampling filter for blur"); + dy-=19; + if (nbd->filtertype != R_FILTER_FAST_GAUSS) { + uiDefButC(block, TOG, B_NODE_EXEC, "Bokeh", + butr->xmin, dy, dx, 19, + &nbd->bokeh, 0, 0, 0, 0, "Uses circular filter, warning it's slow!"); + uiDefButC(block, TOG, B_NODE_EXEC, "Gamma", + butr->xmin+dx, dy, dx, 19, + &nbd->gamma, 0, 0, 0, 0, "Applies filter on gamma corrected values"); + } else { uiBlockEndAlign(block); + uiBlockBeginAlign(block); } - return 77; + dy-=19; + bt= uiDefButS(block, TOG, B_NOP, "Relative", + butr->xmin, dy, dx*2, 19, + &nbd->relative, 0, 0, 0, 0, "Use relative (percent) values to define blur radius"); + uiButSetFunc(bt, node_blur_relative_cb, node, NULL); + + dy-=19; + if(nbd->relative) { + bt= uiDefButF(block, NUM, B_NODE_EXEC, "X:", + butr->xmin, dy, dx, 19, + &nbd->percentx, 0.0f, 1.0f, 0, 0, ""); + uiButSetFunc(bt, node_blur_update_sizex_cb, node, NULL); + bt= uiDefButF(block, NUM, B_NODE_EXEC, "Y:", + butr->xmin+dx, dy, dx, 19, + &nbd->percenty, 0.0f, 1.0f, 0, 0, ""); + uiButSetFunc(bt, node_blur_update_sizey_cb, node, NULL); + } + else { + uiDefButS(block, NUM, B_NODE_EXEC, "X:", + butr->xmin, dy, dx, 19, + &nbd->sizex, 0, 256, 0, 0, ""); + uiDefButS(block, NUM, B_NODE_EXEC, "Y:", + butr->xmin+dx, dy, dx, 19, + &nbd->sizey, 0, 256, 0, 0, ""); + } + uiBlockEndAlign(block); } -static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_dblur(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeDBlurData *ndbd = node->storage; - short dy = butr->ymin + 171; - short dx = butr->xmax - butr->xmin; - short halfdx= (short)dx/2; - - uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:", - butr->xmin, dy, dx, 19, - &ndbd->iter, 1, 32, 10, 0, "Amount of iterations"); - uiDefButC(block, TOG, B_NODE_EXEC, "Wrap", - butr->xmin, dy-= 19, dx, 19, - &ndbd->wrap, 0, 0, 0, 0, "Wrap blur"); - uiBlockEndAlign(block); + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeDBlurData *ndbd = node->storage; + short dy = butr->ymin + 171; + short dx = butr->xmax - butr->xmin; + short halfdx= (short)dx/2; - dy-= 9; + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:", + butr->xmin, dy, dx, 19, + &ndbd->iter, 1, 32, 10, 0, "Amount of iterations"); + uiDefButC(block, TOG, B_NODE_EXEC, "Wrap", + butr->xmin, dy-= 19, dx, 19, + &ndbd->wrap, 0, 0, 0, 0, "Wrap blur"); + uiBlockEndAlign(block); - uiDefBut(block, LABEL, B_NOP, "Center", butr->xmin, dy-= 19, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); + dy-= 9; - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "X:", - butr->xmin, dy-= 19, halfdx, 19, - &ndbd->center_x, 0.0f, 1.0f, 10, 0, "X center in percents"); - uiDefButF(block, NUM, B_NODE_EXEC, "Y:", - butr->xmin+halfdx, dy, halfdx, 19, - &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents"); - uiBlockEndAlign(block); + uiDefBut(block, LABEL, B_NOP, "Center", butr->xmin, dy-= 19, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); - dy-= 9; + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC, "X:", + butr->xmin, dy-= 19, halfdx, 19, + &ndbd->center_x, 0.0f, 1.0f, 10, 0, "X center in percents"); + uiDefButF(block, NUM, B_NODE_EXEC, "Y:", + butr->xmin+halfdx, dy, halfdx, 19, + &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents"); + uiBlockEndAlign(block); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Distance:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->distance, -1.0f, 1.0f, 10, 0, "Amount of which the image moves"); - uiDefButF(block, NUM, B_NODE_EXEC, "Angle:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->angle, 0.0f, 360.0f, 1000, 0, "Angle in which the image will be moved"); - uiBlockEndAlign(block); + dy-= 9; - dy-= 9; + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC, "Distance:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->distance, -1.0f, 1.0f, 10, 0, "Amount of which the image moves"); + uiDefButF(block, NUM, B_NODE_EXEC, "Angle:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->angle, 0.0f, 360.0f, 1000, 0, "Angle in which the image will be moved"); + uiBlockEndAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Spin:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image"); + dy-= 9; - dy-= 9; + uiDefButF(block, NUM, B_NODE_EXEC, "Spin:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image"); - uiDefButF(block, NUM, B_NODE_EXEC, "Zoom:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed"); + dy-= 9; - } - return 190; + uiDefButF(block, NUM, B_NODE_EXEC, "Zoom:", + butr->xmin, dy-= 19, dx, 19, + &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed"); } -static int node_composit_buts_bilateralblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_bilateralblur(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeBilateralBlurData *nbbd= node->storage; - short dy= butr->ymin+38; - short dx= (butr->xmax-butr->xmin); - - uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:", - butr->xmin, dy, dx, 19, - &nbbd->iter, 1, 128, 0, 0, "Amount of iterations"); - dy-=19; - uiDefButF(block, NUM, B_NODE_EXEC, "Color Sigma:", - butr->xmin, dy, dx, 19, - &nbbd->sigma_color,0.01, 3, 10, 0, "Sigma value used to modify color"); - dy-=19; - uiDefButF(block, NUM, B_NODE_EXEC, "Space Sigma:", - butr->xmin, dy, dx, 19, - &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space"); - - } - return 57; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeBilateralBlurData *nbbd= node->storage; + short dy= butr->ymin+38; + short dx= (butr->xmax-butr->xmin); + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:", + butr->xmin, dy, dx, 19, + &nbbd->iter, 1, 128, 0, 0, "Amount of iterations"); + dy-=19; + uiDefButF(block, NUM, B_NODE_EXEC, "Color Sigma:", + butr->xmin, dy, dx, 19, + &nbbd->sigma_color,0.01, 3, 10, 0, "Sigma value used to modify color"); + dy-=19; + uiDefButF(block, NUM, B_NODE_EXEC, "Space Sigma:", + butr->xmin, dy, dx, 19, + &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space"); } /* qdn: defocus node */ -static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) -{ - if(block) { - NodeDefocus *nqd = node->storage; - short dy = butr->ymin + 209; - short dx = butr->xmax - butr->xmin; - char* mstr1 = "Bokeh Type%t|Octagon %x8|Heptagon %x7|Hexagon %x6|Pentagon %x5|Square %x4|Triangle %x3|Disk %x0"; - - uiDefBut(block, LABEL, B_NOP, "Bokeh Type", butr->xmin, dy, dx, 19, NULL, 0, 0, 0, 0, ""); - uiDefButC(block, MENU, B_NODE_EXEC, mstr1, - butr->xmin, dy-19, dx, 19, - &nqd->bktype, 0, 0, 0, 0, "Bokeh type"); - if (nqd->bktype) { /* for some reason rotating a disk doesn't seem to work... ;) */ - uiDefButC(block, NUM, B_NODE_EXEC, "Rotate:", - butr->xmin, dy-38, dx, 19, - &nqd->rotation, 0, 90, 0, 0, "Bokeh shape rotation offset in degrees"); - } - uiDefButC(block, TOG, B_NODE_EXEC, "Gamma Correct", - butr->xmin, dy-57, dx, 19, - &nqd->gamco, 0, 0, 0, 0, "Enable gamma correction before and after main process"); - if (nqd->no_zbuf==0) { - // only needed for zbuffer input - uiDefButF(block, NUM, B_NODE_EXEC, "fStop:", - butr->xmin, dy-76, dx, 19, - &nqd->fstop, 0.5, 128, 10, 0, "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius"); - } - uiDefButF(block, NUM, B_NODE_EXEC, "Maxblur:", - butr->xmin, dy-95, dx, 19, - &nqd->maxblur, 0, 10000, 1000, 0, "blur limit, maximum CoC radius, 0=no limit"); - uiDefButF(block, NUM, B_NODE_EXEC, "BThreshold:", - butr->xmin, dy-114, dx, 19, - &nqd->bthresh, 0, 100, 100, 0, "CoC radius threshold, prevents background bleed on in-focus midground, 0=off"); - uiDefButC(block, TOG, B_NODE_EXEC, "Preview", - butr->xmin, dy-142, dx, 19, - &nqd->preview, 0, 0, 0, 0, "Enable sampling mode, useful for preview when using low samplecounts"); - if (nqd->preview) { - /* only visible when sampling mode enabled */ - uiDefButS(block, NUM, B_NODE_EXEC, "Samples:", - butr->xmin, dy-161, dx, 19, - &nqd->samples, 16, 256, 0, 0, "Number of samples (16=grainy, higher=less noise)"); - } - uiDefButS(block, TOG, B_NODE_EXEC, "No zbuffer", - butr->xmin, dy-190, dx, 19, - &nqd->no_zbuf, 0, 0, 0, 0, "Enable when using an image as input instead of actual zbuffer (auto enabled if node not image based, eg. time node)"); - if (nqd->no_zbuf) { - uiDefButF(block, NUM, B_NODE_EXEC, "Zscale:", - butr->xmin, dy-209, dx, 19, - &nqd->scale, 0, 1000, 100, 0, "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1"); - } +static void node_composit_buts_defocus(uiLayout *layout, PointerRNA *ptr) +{ + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeDefocus *nqd = node->storage; + short dy = butr->ymin + 209; + short dx = butr->xmax - butr->xmin; + char* mstr1 = "Bokeh Type%t|Octagon %x8|Heptagon %x7|Hexagon %x6|Pentagon %x5|Square %x4|Triangle %x3|Disk %x0"; + + uiDefBut(block, LABEL, B_NOP, "Bokeh Type", butr->xmin, dy, dx, 19, NULL, 0, 0, 0, 0, ""); + uiDefButC(block, MENU, B_NODE_EXEC, mstr1, + butr->xmin, dy-19, dx, 19, + &nqd->bktype, 0, 0, 0, 0, "Bokeh type"); + if (nqd->bktype) { /* for some reason rotating a disk doesn't seem to work... ;) */ + uiDefButC(block, NUM, B_NODE_EXEC, "Rotate:", + butr->xmin, dy-38, dx, 19, + &nqd->rotation, 0, 90, 0, 0, "Bokeh shape rotation offset in degrees"); + } + uiDefButC(block, TOG, B_NODE_EXEC, "Gamma Correct", + butr->xmin, dy-57, dx, 19, + &nqd->gamco, 0, 0, 0, 0, "Enable gamma correction before and after main process"); + if (nqd->no_zbuf==0) { + // only needed for zbuffer input + uiDefButF(block, NUM, B_NODE_EXEC, "fStop:", + butr->xmin, dy-76, dx, 19, + &nqd->fstop, 0.5, 128, 10, 0, "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius"); + } + uiDefButF(block, NUM, B_NODE_EXEC, "Maxblur:", + butr->xmin, dy-95, dx, 19, + &nqd->maxblur, 0, 10000, 1000, 0, "blur limit, maximum CoC radius, 0=no limit"); + uiDefButF(block, NUM, B_NODE_EXEC, "BThreshold:", + butr->xmin, dy-114, dx, 19, + &nqd->bthresh, 0, 100, 100, 0, "CoC radius threshold, prevents background bleed on in-focus midground, 0=off"); + uiDefButC(block, TOG, B_NODE_EXEC, "Preview", + butr->xmin, dy-142, dx, 19, + &nqd->preview, 0, 0, 0, 0, "Enable sampling mode, useful for preview when using low samplecounts"); + if (nqd->preview) { + /* only visible when sampling mode enabled */ + uiDefButS(block, NUM, B_NODE_EXEC, "Samples:", + butr->xmin, dy-161, dx, 19, + &nqd->samples, 16, 256, 0, 0, "Number of samples (16=grainy, higher=less noise)"); + } + uiDefButS(block, TOG, B_NODE_EXEC, "No zbuffer", + butr->xmin, dy-190, dx, 19, + &nqd->no_zbuf, 0, 0, 0, 0, "Enable when using an image as input instead of actual zbuffer (auto enabled if node not image based, eg. time node)"); + if (nqd->no_zbuf) { + uiDefButF(block, NUM, B_NODE_EXEC, "Zscale:", + butr->xmin, dy-209, dx, 19, + &nqd->scale, 0, 1000, 100, 0, "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1"); } - return 228; } /* qdn: glare node */ -static int node_composit_buts_glare(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) -{ - if(block) { - NodeGlare *ndg = node->storage; - short dy = butr->ymin + 152, dx = butr->xmax - butr->xmin; - char* mn1 = "Type%t|Ghosts%x3|Streaks%x2|Fog Glow%x1|Simple Star%x0"; - char* mn2 = "Quality/Speed%t|High/Slow%x0|Medium/Medium%x1|Low/Fast%x2"; - uiDefButC(block, MENU, B_NODE_EXEC, mn1, - butr->xmin, dy, dx, 19, - &ndg->type, 0, 0, 0, 0, "Glow/Flare/Bloom type"); - uiDefButC(block, MENU, B_NODE_EXEC, mn2, - butr->xmin, dy-19, dx, 19, - &ndg->quality, 0, 0, 0, 0, - "Quality speed trade off, if not set to high quality, effect will be applied to low-res copy of source image"); - if (ndg->type != 1) { - uiDefButC(block, NUM, B_NODE_EXEC, "Iterations:", - butr->xmin, dy-38, dx, 19, - &ndg->iter, 2, 5, 1, 0, - "higher values will generate longer/more streaks/ghosts"); - if (ndg->type != 0) - uiDefButF(block, NUM, B_NODE_EXEC, "ColMod:", - butr->xmin, dy-57, dx, 19, - &ndg->colmod, 0, 1, 10, 0, - "Amount of Color Modulation, modulates colors of streaks and ghosts for a spectral dispersion effect"); - } - uiDefButF(block, NUM, B_NODE_EXEC, "Mix:", - butr->xmin, dy-76, dx, 19, - &ndg->mix, -1, 1, 10, 0, - "Mix balance, -1 is original image only, 0 is exact 50/50 mix, 1 is processed image only"); - uiDefButF(block, NUM, B_NODE_EXEC, "Threshold:", - butr->xmin, dy-95, dx, 19, - &ndg->threshold, 0, 1000, 10, 0, - "Brightness threshold, the glarefilter will be applied only to pixels brighter than this value"); - if ((ndg->type == 2) || (ndg->type == 0)) - { - if (ndg->type == 2) { - uiDefButC(block, NUM, B_NODE_EXEC, "streaks:", - butr->xmin, dy-114, dx, 19, - &ndg->angle, 2, 16, 1000, 0, - "Total number of streaks"); - uiDefButC(block, NUM, B_NODE_EXEC, "AngOfs:", - butr->xmin, dy-133, dx, 19, - &ndg->angle_ofs, 0, 180, 1000, 0, - "Streak angle rotation offset in degrees"); - } - uiDefButF(block, NUM, B_NODE_EXEC, "Fade:", - butr->xmin, dy-152, dx, 19, - &ndg->fade, 0.75, 1, 5, 0, - "Streak fade out factor"); +static void node_composit_buts_glare(uiLayout *layout, PointerRNA *ptr) +{ + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeGlare *ndg = node->storage; + short dy = butr->ymin + 152, dx = butr->xmax - butr->xmin; + char* mn1 = "Type%t|Ghosts%x3|Streaks%x2|Fog Glow%x1|Simple Star%x0"; + char* mn2 = "Quality/Speed%t|High/Slow%x0|Medium/Medium%x1|Low/Fast%x2"; + uiDefButC(block, MENU, B_NODE_EXEC, mn1, + butr->xmin, dy, dx, 19, + &ndg->type, 0, 0, 0, 0, "Glow/Flare/Bloom type"); + uiDefButC(block, MENU, B_NODE_EXEC, mn2, + butr->xmin, dy-19, dx, 19, + &ndg->quality, 0, 0, 0, 0, + "Quality speed trade off, if not set to high quality, effect will be applied to low-res copy of source image"); + if (ndg->type != 1) { + uiDefButC(block, NUM, B_NODE_EXEC, "Iterations:", + butr->xmin, dy-38, dx, 19, + &ndg->iter, 2, 5, 1, 0, + "higher values will generate longer/more streaks/ghosts"); + if (ndg->type != 0) + uiDefButF(block, NUM, B_NODE_EXEC, "ColMod:", + butr->xmin, dy-57, dx, 19, + &ndg->colmod, 0, 1, 10, 0, + "Amount of Color Modulation, modulates colors of streaks and ghosts for a spectral dispersion effect"); + } + uiDefButF(block, NUM, B_NODE_EXEC, "Mix:", + butr->xmin, dy-76, dx, 19, + &ndg->mix, -1, 1, 10, 0, + "Mix balance, -1 is original image only, 0 is exact 50/50 mix, 1 is processed image only"); + uiDefButF(block, NUM, B_NODE_EXEC, "Threshold:", + butr->xmin, dy-95, dx, 19, + &ndg->threshold, 0, 1000, 10, 0, + "Brightness threshold, the glarefilter will be applied only to pixels brighter than this value"); + if ((ndg->type == 2) || (ndg->type == 0)) + { + if (ndg->type == 2) { + uiDefButC(block, NUM, B_NODE_EXEC, "streaks:", + butr->xmin, dy-114, dx, 19, + &ndg->angle, 2, 16, 1000, 0, + "Total number of streaks"); + uiDefButC(block, NUM, B_NODE_EXEC, "AngOfs:", + butr->xmin, dy-133, dx, 19, + &ndg->angle_ofs, 0, 180, 1000, 0, + "Streak angle rotation offset in degrees"); } - if (ndg->type == 0) - uiDefButC(block, TOG, B_NODE_EXEC, "Rot45", - butr->xmin, dy-114, dx, 19, - &ndg->angle, 0, 0, 0, 0, - "simple star filter, add 45 degree rotation offset"); - if ((ndg->type == 1) || (ndg->type > 3)) // PBGH and fog glow - uiDefButC(block, NUM, B_NODE_EXEC, "Size:", - butr->xmin, dy-114, dx, 19, - &ndg->size, 6, 9, 1000, 0, - "glow/glare size (not actual size, relative to initial size of bright area of pixels)"); - } - return 171; + uiDefButF(block, NUM, B_NODE_EXEC, "Fade:", + butr->xmin, dy-152, dx, 19, + &ndg->fade, 0.75, 1, 5, 0, + "Streak fade out factor"); + } + if (ndg->type == 0) + uiDefButC(block, TOG, B_NODE_EXEC, "Rot45", + butr->xmin, dy-114, dx, 19, + &ndg->angle, 0, 0, 0, 0, + "simple star filter, add 45 degree rotation offset"); + if ((ndg->type == 1) || (ndg->type > 3)) // PBGH and fog glow + uiDefButC(block, NUM, B_NODE_EXEC, "Size:", + butr->xmin, dy-114, dx, 19, + &ndg->size, 6, 9, 1000, 0, + "glow/glare size (not actual size, relative to initial size of bright area of pixels)"); } /* qdn: tonemap node */ -static int node_composit_buts_tonemap(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_tonemap(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeTonemap *ntm = node->storage; - short dy = butr->ymin + 76, dx = butr->xmax - butr->xmin; - char* mn = "Type%t|R/D Photoreceptor%x1|Rh Simple%x0"; - - uiBlockBeginAlign(block); - uiDefButI(block, MENU, B_NODE_EXEC, mn, - butr->xmin, dy, dx, 19, - &ntm->type, 0, 0, 0, 0, - "Tone mapping type"); - if (ntm->type == 0) { - uiDefButF(block, NUM, B_NODE_EXEC, "Key:", - butr->xmin, dy-19, dx, 19, - &ntm->key, 0, 1, 5, 0, - "The value the average luminance is mapped to"); - uiDefButF(block, NUM, B_NODE_EXEC, "Offset:", - butr->xmin, dy-38, dx, 19, - &ntm->offset, 0.001, 10, 5, 0, - "Tonemap offset, normally always 1, but can be used as an extra control to alter the brightness curve"); - uiDefButF(block, NUM, B_NODE_EXEC, "Gamma:", - butr->xmin, dy-57, dx, 19, - &ntm->gamma, 0.001, 3, 5, 0, - "Gamma factor, if not used, set to 1"); - } - else { - uiDefButF(block, NUM, B_NODE_EXEC, "Intensity:", - butr->xmin, dy-19, dx, 19, - &ntm->f, -8, 8, 10, 0, "if less than zero, darkens image, otherwise makes it brighter"); - uiDefButF(block, NUM, B_NODE_EXEC, "Contrast:", - butr->xmin, dy-38, dx, 19, - &ntm->m, 0, 1, 5, 0, "Set to 0 to use estimate from input image"); - uiDefButF(block, NUM, B_NODE_EXEC, "Adaptation:", - butr->xmin, dy-57, dx, 19, - &ntm->a, 0, 1, 5, 0, "if 0, global, if 1, based on pixel intensity"); - uiDefButF(block, NUM, B_NODE_EXEC, "ColCorrect:", - butr->xmin, dy-76, dx, 19, - &ntm->c, 0, 1, 5, 0, "color correction, if 0, same for all channels, if 1, each independent"); - } - uiBlockEndAlign(block); + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeTonemap *ntm = node->storage; + short dy = butr->ymin + 76, dx = butr->xmax - butr->xmin; + char* mn = "Type%t|R/D Photoreceptor%x1|Rh Simple%x0"; + + uiBlockBeginAlign(block); + uiDefButI(block, MENU, B_NODE_EXEC, mn, + butr->xmin, dy, dx, 19, + &ntm->type, 0, 0, 0, 0, + "Tone mapping type"); + if (ntm->type == 0) { + uiDefButF(block, NUM, B_NODE_EXEC, "Key:", + butr->xmin, dy-19, dx, 19, + &ntm->key, 0, 1, 5, 0, + "The value the average luminance is mapped to"); + uiDefButF(block, NUM, B_NODE_EXEC, "Offset:", + butr->xmin, dy-38, dx, 19, + &ntm->offset, 0.001, 10, 5, 0, + "Tonemap offset, normally always 1, but can be used as an extra control to alter the brightness curve"); + uiDefButF(block, NUM, B_NODE_EXEC, "Gamma:", + butr->xmin, dy-57, dx, 19, + &ntm->gamma, 0.001, 3, 5, 0, + "Gamma factor, if not used, set to 1"); } - return 95; + else { + uiDefButF(block, NUM, B_NODE_EXEC, "Intensity:", + butr->xmin, dy-19, dx, 19, + &ntm->f, -8, 8, 10, 0, "if less than zero, darkens image, otherwise makes it brighter"); + uiDefButF(block, NUM, B_NODE_EXEC, "Contrast:", + butr->xmin, dy-38, dx, 19, + &ntm->m, 0, 1, 5, 0, "Set to 0 to use estimate from input image"); + uiDefButF(block, NUM, B_NODE_EXEC, "Adaptation:", + butr->xmin, dy-57, dx, 19, + &ntm->a, 0, 1, 5, 0, "if 0, global, if 1, based on pixel intensity"); + uiDefButF(block, NUM, B_NODE_EXEC, "ColCorrect:", + butr->xmin, dy-76, dx, 19, + &ntm->c, 0, 1, 5, 0, "color correction, if 0, same for all channels, if 1, each independent"); + } + uiBlockEndAlign(block); } /* qdn: lens distortion node */ -static int node_composit_buts_lensdist(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeLensDist *nld = node->storage; - short dy = butr->ymin + 19, dx = butr->xmax - butr->xmin; - uiBlockBeginAlign(block); - uiDefButS(block, TOG, B_NODE_EXEC, "Projector", - butr->xmin, dy, dx, 19, - &nld->proj, 0, 0, 0, 0, - "Enable/disable projector mode, effect is applied in horizontal direction only"); - if (!nld->proj) { - uiDefButS(block, TOG, B_NODE_EXEC, "Jitter", - butr->xmin, dy-19, dx/2, 19, - &nld->jit, 0, 0, 0, 0, - "Enable/disable jittering, faster, but also noisier"); - uiDefButS(block, TOG, B_NODE_EXEC, "Fit", - butr->xmin+dx/2, dy-19, dx/2, 19, - &nld->fit, 0, 0, 0, 0, - "For positive distortion factor only, scale image such that black areas are not visible"); - } - uiBlockEndAlign(block); + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeLensDist *nld = node->storage; + short dy = butr->ymin + 19, dx = butr->xmax - butr->xmin; + uiBlockBeginAlign(block); + uiDefButS(block, TOG, B_NODE_EXEC, "Projector", + butr->xmin, dy, dx, 19, + &nld->proj, 0, 0, 0, 0, + "Enable/disable projector mode, effect is applied in horizontal direction only"); + if (!nld->proj) { + uiDefButS(block, TOG, B_NODE_EXEC, "Jitter", + butr->xmin, dy-19, dx/2, 19, + &nld->jit, 0, 0, 0, 0, + "Enable/disable jittering, faster, but also noisier"); + uiDefButS(block, TOG, B_NODE_EXEC, "Fit", + butr->xmin+dx/2, dy-19, dx/2, 19, + &nld->fit, 0, 0, 0, 0, + "For positive distortion factor only, scale image such that black areas are not visible"); } - return 38; + uiBlockEndAlign(block); } -static int node_composit_buts_vecblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) { - if(block) { - PointerRNA ptr; - short dy= butr->ymin; - short dx= (butr->xmax-butr->xmin); - - RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr); - - uiBlockBeginAlign(block); - uiDefButR(block, NUM, B_NODE_EXEC, NULL, - butr->xmin, dy+76, dx, 19, - &ptr, "samples", 0, 1, 256, 0, 0, NULL); - uiDefButR(block, NUM, B_NODE_EXEC, NULL, - butr->xmin, dy+57, dx, 19, - &ptr, "min_speed", 0, 0, 1024, 0, 0, NULL); - uiDefButR(block, NUM, B_NODE_EXEC, NULL, - butr->xmin, dy+38, dx, 19, - &ptr, "max_speed", 0, 0, 1024, 0, 0, NULL); - uiDefButR(block, NUM, B_NODE_EXEC, "Blur", - butr->xmin, dy+19, dx, 19, - &ptr, "factor", 0, 0, 2, 10, 2, NULL); - uiDefButR(block, TOG, B_NODE_EXEC, NULL, - butr->xmin, dy, dx, 19, - &ptr, "curved", 0, 0, 2, 10, 2, NULL); - uiBlockEndAlign(block); - } - return 95; + uiLayout *col; + + col= uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "samples", 0); + uiItemR(col, NULL, 0, ptr, "min_speed", 0); + uiItemR(col, NULL, 0, ptr, "max_speed", 0); + uiItemR(col, "Blur", 0, ptr, "factor", 0); + + col= uiLayoutColumn(layout, 0); + uiItemR(col, NULL, 0, ptr, "curved", 0); } -static int node_composit_buts_filter(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_filter(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt; - - /* blend type */ - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Soften %x0|Sharpen %x1|Laplace %x2|Sobel %x3|Prewitt %x4|Kirsch %x5|Shadow %x6", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt; + + /* blend type */ + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Soften %x0|Sharpen %x1|Laplace %x2|Sobel %x3|Prewitt %x4|Kirsch %x5|Shadow %x6", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 0, 0, 0, ""); + uiButSetFunc(bt, node_but_title_cb, node, bt); } -static int node_composit_buts_flip(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_flip(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt; - - /* flip x\y */ - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Flip X %x0|Flip Y %x1|Flip X & Y %x2", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt; + + /* flip x\y */ + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Flip X %x0|Flip Y %x1|Flip X & Y %x2", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 0, 0, 0, ""); + uiButSetFunc(bt, node_but_title_cb, node, bt); } -static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeTwoXYs *ntxy= node->storage; - char elementheight = 19; - short dx= (butr->xmax-butr->xmin)/2; - short dy= butr->ymax - elementheight; - short xymin= 0, xymax= 10000; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeTwoXYs *ntxy= node->storage; + char elementheight = 19; + short dx= (butr->xmax-butr->xmin)/2; + short dy= butr->ymax - elementheight; + short xymin= 0, xymax= 10000; - uiBlockBeginAlign(block); + uiBlockBeginAlign(block); - /* crop image size toggle */ - uiDefButS(block, TOG, B_NODE_EXEC, "Crop Image Size", - butr->xmin, dy, dx*2, elementheight, - &node->custom1, 0, 0, 0, 0, "Crop the size of the input image."); - - dy-=elementheight; - - /* x1 */ - uiDefButS(block, NUM, B_NODE_EXEC, "X1:", - butr->xmin, dy, dx, elementheight, - &ntxy->x1, xymin, xymax, 0, 0, ""); - /* y1 */ - uiDefButS(block, NUM, B_NODE_EXEC, "Y1:", - butr->xmin+dx, dy, dx, elementheight, - &ntxy->y1, xymin, xymax, 0, 0, ""); - - dy-=elementheight; - - /* x2 */ - uiDefButS(block, NUM, B_NODE_EXEC, "X2:", - butr->xmin, dy, dx, elementheight, - &ntxy->x2, xymin, xymax, 0, 0, ""); - /* y2 */ - uiDefButS(block, NUM, B_NODE_EXEC, "Y2:", - butr->xmin+dx, dy, dx, elementheight, - &ntxy->y2, xymin, xymax, 0, 0, ""); + /* crop image size toggle */ + uiDefButS(block, TOG, B_NODE_EXEC, "Crop Image Size", + butr->xmin, dy, dx*2, elementheight, + &node->custom1, 0, 0, 0, 0, "Crop the size of the input image."); + + dy-=elementheight; + + /* x1 */ + uiDefButS(block, NUM, B_NODE_EXEC, "X1:", + butr->xmin, dy, dx, elementheight, + &ntxy->x1, xymin, xymax, 0, 0, ""); + /* y1 */ + uiDefButS(block, NUM, B_NODE_EXEC, "Y1:", + butr->xmin+dx, dy, dx, elementheight, + &ntxy->y1, xymin, xymax, 0, 0, ""); + + dy-=elementheight; + + /* x2 */ + uiDefButS(block, NUM, B_NODE_EXEC, "X2:", + butr->xmin, dy, dx, elementheight, + &ntxy->x2, xymin, xymax, 0, 0, ""); + /* y2 */ + uiDefButS(block, NUM, B_NODE_EXEC, "Y2:", + butr->xmin+dx, dy, dx, elementheight, + &ntxy->y2, xymin, xymax, 0, 0, ""); - uiBlockEndAlign(block); - } - return 60; + uiBlockEndAlign(block); } -static int node_composit_buts_splitviewer(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBlockBeginAlign(block); - - uiDefButS(block, ROW, B_NODE_EXEC, "X", - butr->xmin, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20, - &node->custom2, 0.0, 0.0, 0, 0, ""); - uiDefButS(block, ROW, B_NODE_EXEC, "Y", - butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20, - &node->custom2, 0.0, 1.0, 0, 0, ""); - - uiDefButS(block, NUMSLI, B_NODE_EXEC, "Split %: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 100, 10, 0, ""); - } - return 40; -} - -static int node_composit_buts_map_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) -{ - if(block) { - TexMapping *texmap= node->storage; - short xstart= (short)butr->xmin; - short dy= (short)(butr->ymax-19.0f); - short dx= (short)(butr->xmax-butr->xmin)/2; - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); - dy-= 19; - uiDefButF(block, NUM, B_NODE_EXEC, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, ""); - dy-= 23; - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); - dy-= 19; - uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->max, -1000.0f, 1000.0f, 10, 2, ""); - } - return 80; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + uiBlockBeginAlign(block); + + uiDefButS(block, ROW, B_NODE_EXEC, "X", + butr->xmin, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20, + &node->custom2, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, ROW, B_NODE_EXEC, "Y", + butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20, + &node->custom2, 0.0, 1.0, 0, 0, ""); + + uiDefButS(block, NUMSLI, B_NODE_EXEC, "Split %: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 100, 10, 0, ""); } -static int node_composit_buts_alphaover(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_map_value(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeTwoFloats *ntf= node->storage; - - /* alpha type */ - uiDefButS(block, TOG, B_NODE_EXEC, "ConvertPremul", - butr->xmin, butr->ymin+19, butr->xmax-butr->xmin, 19, - &node->custom1, 0, 0, 0, 0, ""); - /* mix factor */ - uiDefButF(block, NUM, B_NODE_EXEC, "Premul: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, - &ntf->x, 0.0f, 1.0f, 100, 0, ""); - } - return 38; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + TexMapping *texmap= node->storage; + short xstart= (short)butr->xmin; + short dy= (short)(butr->ymax-19.0f); + short dx= (short)(butr->xmax-butr->xmin)/2; + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); + dy-= 19; + uiDefButF(block, NUM, B_NODE_EXEC, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, ""); + dy-= 23; + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); + dy-= 19; + uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); + uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->max, -1000.0f, 1000.0f, 10, 2, ""); } -static int node_composit_buts_hue_sat(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_alphaover(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeHueSat *nhs= node->storage; - - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Hue: ", - butr->xmin, butr->ymin+40.0f, butr->xmax-butr->xmin, 20, - &nhs->hue, 0.0f, 1.0f, 100, 0, ""); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Sat: ", - butr->xmin, butr->ymin+20.0f, butr->xmax-butr->xmin, 20, - &nhs->sat, 0.0f, 2.0f, 100, 0, ""); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Val: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &nhs->val, 0.0f, 2.0f, 100, 0, ""); - } - return 60; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeTwoFloats *ntf= node->storage; + + /* alpha type */ + uiDefButS(block, TOG, B_NODE_EXEC, "ConvertPremul", + butr->xmin, butr->ymin+19, butr->xmax-butr->xmin, 19, + &node->custom1, 0, 0, 0, 0, ""); + /* mix factor */ + uiDefButF(block, NUM, B_NODE_EXEC, "Premul: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, + &ntf->x, 0.0f, 1.0f, 100, 0, ""); } -static int node_composit_buts_dilateerode(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_hue_sat(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiDefButS(block, NUM, B_NODE_EXEC, "Distance:", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom2, -100, 100, 0, 0, "Distance to grow/shrink (number of iterations)"); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeHueSat *nhs= node->storage; + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Hue: ", + butr->xmin, butr->ymin+40.0f, butr->xmax-butr->xmin, 20, + &nhs->hue, 0.0f, 1.0f, 100, 0, ""); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Sat: ", + butr->xmin, butr->ymin+20.0f, butr->xmax-butr->xmin, 20, + &nhs->sat, 0.0f, 2.0f, 100, 0, ""); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Val: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &nhs->val, 0.0f, 2.0f, 100, 0, ""); } -static int node_composit_buts_diff_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_dilateerode(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeChroma *c= node->storage; - - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", - butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Color differences below this threshold are keyed."); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Color differences below this additional threshold are partially keyed."); - uiBlockEndAlign(block); - } - return 40; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + uiDefButS(block, NUM, B_NODE_EXEC, "Distance:", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom2, -100, 100, 0, 0, "Distance to grow/shrink (number of iterations)"); } -static int node_composit_buts_distance_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_diff_matte(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeChroma *c= node->storage; - - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", - butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Color distances below this threshold are keyed."); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Color distances below this additional threshold are partially keyed."); - uiBlockEndAlign(block); - } - return 40; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeChroma *c= node->storage; + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", + butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 1.0f, 100, 0, "Color differences below this threshold are keyed."); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Color differences below this additional threshold are partially keyed."); + uiBlockEndAlign(block); } -static int node_composit_buts_color_spill(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_distance_matte(uiLayout *layout, PointerRNA *ptr) { - if(block) { - short dx= (butr->xmax-butr->xmin)/3; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeChroma *c= node->storage; + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", + butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 1.0f, 100, 0, "Color distances below this threshold are keyed."); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Color distances below this additional threshold are partially keyed."); + uiBlockEndAlign(block); +} - NodeChroma *c=node->storage; - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Enhance: ", - butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 0.5f, 100, 2, "Adjusts how much selected channel is affected by color spill algorithm"); - uiDefButS(block, ROW, B_NODE_EXEC, "R", - butr->xmin,butr->ymin,dx,20, - &node->custom1,1,1, 0, 0, "Red Spill Suppression"); - uiDefButS(block, ROW, B_NODE_EXEC, "G", - butr->xmin+dx,butr->ymin,dx,20, - &node->custom1,1,2, 0, 0, "Green Spill Suppression"); - uiDefButS(block, ROW, B_NODE_EXEC, "B", - butr->xmin+2*dx,butr->ymin,dx,20, - &node->custom1, 1, 3, 0, 0, "Blue Spill Suppression"); - uiBlockEndAlign(block); - } - return 60; +static void node_composit_buts_color_spill(uiLayout *layout, PointerRNA *ptr) +{ + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + short dx= (butr->xmax-butr->xmin)/3; + + NodeChroma *c=node->storage; + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_NODE_EXEC, "Enhance: ", + butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 0.5f, 100, 2, "Adjusts how much selected channel is affected by color spill algorithm"); + uiDefButS(block, ROW, B_NODE_EXEC, "R", + butr->xmin,butr->ymin,dx,20, + &node->custom1,1,1, 0, 0, "Red Spill Suppression"); + uiDefButS(block, ROW, B_NODE_EXEC, "G", + butr->xmin+dx,butr->ymin,dx,20, + &node->custom1,1,2, 0, 0, "Green Spill Suppression"); + uiDefButS(block, ROW, B_NODE_EXEC, "B", + butr->xmin+2*dx,butr->ymin,dx,20, + &node->custom1, 1, 3, 0, 0, "Blue Spill Suppression"); + uiBlockEndAlign(block); } -static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_chroma_matte(uiLayout *layout, PointerRNA *ptr) { - if(block) { - short dx=(butr->xmax-butr->xmin)/2; - NodeChroma *c= node->storage; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + short dx=(butr->xmax-butr->xmin)/2; + NodeChroma *c= node->storage; - uiBlockBeginAlign(block); + uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ", - butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20, - &c->t1, 1.0f, 80.0f, 100, 0, "Tolerance for colors to be considered a keying color"); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Cutoff ", - butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 30.0f, 100, 0, "Colors below this will be considered as exact matches for keying color"); - - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Lift ", - butr->xmin, butr->ymin+20, dx, 20, - &c->fsize, 0.0f, 1.0f, 100, 0, "Alpha Lift"); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Gain ", - butr->xmin+dx, butr->ymin+20, dx, 20, - &c->fstrength, 0.0f, 1.0f, 100, 0, "Alpha Gain"); - - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured"); - uiBlockEndAlign(block); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ", + butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20, + &c->t1, 1.0f, 80.0f, 100, 0, "Tolerance for colors to be considered a keying color"); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Cutoff ", + butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 30.0f, 100, 0, "Colors below this will be considered as exact matches for keying color"); + + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Lift ", + butr->xmin, butr->ymin+20, dx, 20, + &c->fsize, 0.0f, 1.0f, 100, 0, "Alpha Lift"); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Gain ", + butr->xmin+dx, butr->ymin+20, dx, 20, + &c->fstrength, 0.0f, 1.0f, 100, 0, "Alpha Gain"); + + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured"); + uiBlockEndAlign(block); - if(c->t2 > c->t1) - c->t2=c->t1; - } - return 80; + if(c->t2 > c->t1) + c->t2=c->t1; } -static int node_composit_buts_color_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_color_matte(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeChroma *c= node->storage; - uiBlockBeginAlign(block); + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeChroma *c= node->storage; + uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "H: ", - butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 0.25f, 100, 0, "Hue tolerance for colors to be considered a keying color"); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "S: ", - butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Saturation Tolerance for the color"); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "V: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t3, 0.0f, 1.0f, 100, 0, "Value Tolerance for the color"); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "H: ", + butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 0.25f, 100, 0, "Hue tolerance for colors to be considered a keying color"); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "S: ", + butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Saturation Tolerance for the color"); + uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "V: ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t3, 0.0f, 1.0f, 100, 0, "Value Tolerance for the color"); - uiBlockEndAlign(block); - } - return 60; + uiBlockEndAlign(block); } - -static int node_composit_buts_channel_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_channel_matte(uiLayout *layout, PointerRNA *ptr) { - if(block) { - short sx= (butr->xmax-butr->xmin)/4; - short cx= (butr->xmax-butr->xmin)/3; - NodeChroma *c=node->storage; - char *c1, *c2, *c3; - - /*color space selectors*/ - uiBlockBeginAlign(block); - uiDefButS(block, ROW,B_NODE_EXEC,"RGB", - butr->xmin,butr->ymin+60,sx,20,&node->custom1,1,1, 0, 0, "RGB Color Space"); - uiDefButS(block, ROW,B_NODE_EXEC,"HSV", - butr->xmin+sx,butr->ymin+60,sx,20,&node->custom1,1,2, 0, 0, "HSV Color Space"); - uiDefButS(block, ROW,B_NODE_EXEC,"YUV", - butr->xmin+2*sx,butr->ymin+60,sx,20,&node->custom1,1,3, 0, 0, "YUV Color Space"); - uiDefButS(block, ROW,B_NODE_EXEC,"YCC", - butr->xmin+3*sx,butr->ymin+60,sx,20,&node->custom1,1,4, 0, 0, "YCbCr Color Space"); - - if (node->custom1==1) { - c1="R"; c2="G"; c3="B"; - } - else if(node->custom1==2){ - c1="H"; c2="S"; c3="V"; - } - else if(node->custom1==3){ - c1="Y"; c2="U"; c3="V"; - } - else { // if(node->custom1==4){ - c1="Y"; c2="Cb"; c3="Cr"; - } - - /*channel selector */ - uiDefButS(block, ROW, B_NODE_EXEC, c1, - butr->xmin,butr->ymin+40,cx,20,&node->custom2,1, 1, 0, 0, "Channel 1"); - uiDefButS(block, ROW, B_NODE_EXEC, c2, - butr->xmin+cx,butr->ymin+40,cx,20,&node->custom2,1, 2, 0, 0, "Channel 2"); - uiDefButS(block, ROW, B_NODE_EXEC, c3, - butr->xmin+cx+cx,butr->ymin+40,cx,20,&node->custom2, 1, 3, 0, 0, "Channel 3"); - - /*tolerance sliders */ - uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ", - butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque"); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed"); - uiBlockEndAlign(block); - - /*keep t2 (low) less than t1 (high) */ - if(c->t2 > c->t1) { - c->t2=c->t1; - } + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + short sx= (butr->xmax-butr->xmin)/4; + short cx= (butr->xmax-butr->xmin)/3; + NodeChroma *c=node->storage; + char *c1, *c2, *c3; + + /*color space selectors*/ + uiBlockBeginAlign(block); + uiDefButS(block, ROW,B_NODE_EXEC,"RGB", + butr->xmin,butr->ymin+60,sx,20,&node->custom1,1,1, 0, 0, "RGB Color Space"); + uiDefButS(block, ROW,B_NODE_EXEC,"HSV", + butr->xmin+sx,butr->ymin+60,sx,20,&node->custom1,1,2, 0, 0, "HSV Color Space"); + uiDefButS(block, ROW,B_NODE_EXEC,"YUV", + butr->xmin+2*sx,butr->ymin+60,sx,20,&node->custom1,1,3, 0, 0, "YUV Color Space"); + uiDefButS(block, ROW,B_NODE_EXEC,"YCC", + butr->xmin+3*sx,butr->ymin+60,sx,20,&node->custom1,1,4, 0, 0, "YCbCr Color Space"); + + if (node->custom1==1) { + c1="R"; c2="G"; c3="B"; + } + else if(node->custom1==2){ + c1="H"; c2="S"; c3="V"; + } + else if(node->custom1==3){ + c1="Y"; c2="U"; c3="V"; + } + else { // if(node->custom1==4){ + c1="Y"; c2="Cb"; c3="Cr"; + } + + /*channel selector */ + uiDefButS(block, ROW, B_NODE_EXEC, c1, + butr->xmin,butr->ymin+40,cx,20,&node->custom2,1, 1, 0, 0, "Channel 1"); + uiDefButS(block, ROW, B_NODE_EXEC, c2, + butr->xmin+cx,butr->ymin+40,cx,20,&node->custom2,1, 2, 0, 0, "Channel 2"); + uiDefButS(block, ROW, B_NODE_EXEC, c3, + butr->xmin+cx+cx,butr->ymin+40,cx,20,&node->custom2, 1, 3, 0, 0, "Channel 3"); + + /*tolerance sliders */ + uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ", + butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque"); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed"); + uiBlockEndAlign(block); + + /*keep t2 (low) less than t1 (high) */ + if(c->t2 > c->t1) { + c->t2=c->t1; } - return 80; } -static int node_composit_buts_luma_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_luma_matte(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeChroma *c=node->storage; - - /*tolerance sliders */ - uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ", - butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque"); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed"); - uiBlockEndAlign(block); - - /*keep t2 (low) less than t1 (high) */ - if(c->t2 > c->t1) { - c->t2=c->t1; - } + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + NodeChroma *c=node->storage; + + /*tolerance sliders */ + uiDefButF(block, NUMSLI, B_NODE_EXEC, "High ", + butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, + &c->t1, 0.0f, 1.0f, 100, 0, "Values higher than this setting are 100% opaque"); + uiDefButF(block, NUMSLI, B_NODE_EXEC, "Low ", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &c->t2, 0.0f, 1.0f, 100, 0, "Values lower than this setting are 100% keyed"); + uiBlockEndAlign(block); + + /*keep t2 (low) less than t1 (high) */ + if(c->t2 > c->t1) { + c->t2=c->t1; } - return 40; } -static int node_composit_buts_map_uv(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_map_uv(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiDefButS(block, NUM, B_NODE_EXEC, "Alpha:", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 100, 0, 0, "Conversion percentage of UV differences to Alpha"); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + uiDefButS(block, NUM, B_NODE_EXEC, "Alpha:", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 100, 0, 0, "Conversion percentage of UV differences to Alpha"); } -static int node_composit_buts_id_mask(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_id_mask(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiDefButS(block, NUM, B_NODE_EXEC, "ID:", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 10000, 0, 0, "Pass Index number to convert to Alpha"); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + uiDefButS(block, NUM, B_NODE_EXEC, "ID:", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 10000, 0, 0, "Pass Index number to convert to Alpha"); } /* allocate sufficient! */ @@ -1880,58 +1844,58 @@ static void node_set_image_cb(bContext *C, void *ntree_v, void *node_v) nodeSetActive(ntree, node); } -static int node_composit_buts_file_output(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_file_output(uiLayout *layout, PointerRNA *ptr) { - if(block) { - NodeImageFile *nif= node->storage; - uiBut *bt; - short x= (short)butr->xmin; - short y= (short)butr->ymin; - short w= (short)butr->xmax-butr->xmin; - char str[320]; - - node_imagetype_string(str); - - uiBlockBeginAlign(block); - - bt = uiDefIconBut(block, BUT, B_NODE_SETIMAGE, ICON_FILESEL, - x, y+60, 20, 20, - 0, 0, 0, 0, 0, "Open Fileselect to get Backbuf image"); - uiButSetFunc(bt, node_set_image_cb, ntree, node); - - uiDefBut(block, TEX, B_NOP, "", - 20+x, y+60, w-20, 20, - nif->name, 0.0f, 240.0f, 0, 0, ""); - - uiDefButS(block, MENU, B_NOP, str, - x, y+40, w, 20, - &nif->imtype, 0.0f, 1.0f, 0, 0, ""); - - if(nif->imtype==R_OPENEXR) { - uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_REDR, "Half", - x, y+20, w/2, 20, - &nif->subimtype, 0, 0, 0, 0, ""); - - uiDefButS(block, MENU,B_NOP, "Codec %t|None %x0|Pxr24 (lossy) %x1|ZIP (lossless) %x2|PIZ (lossless) %x3|RLE (lossless) %x4", - x+w/2, y+20, w/2, 20, - &nif->codec, 0, 0, 0, 0, ""); - } - else { - uiDefButS(block, NUM, B_NOP, "Quality: ", - x, y+20, w, 20, - &nif->quality, 10.0f, 100.0f, 10, 0, ""); - } - - /* start frame, end frame */ - uiDefButI(block, NUM, B_NODE_EXEC, "SFra: ", - x, y, w/2, 20, - &nif->sfra, 1, MAXFRAMEF, 10, 0, ""); - uiDefButI(block, NUM, B_NODE_EXEC, "EFra: ", - x+w/2, y, w/2, 20, - &nif->efra, 1, MAXFRAMEF, 10, 0, ""); - + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; + NodeImageFile *nif= node->storage; + uiBut *bt; + short x= (short)butr->xmin; + short y= (short)butr->ymin; + short w= (short)butr->xmax-butr->xmin; + char str[320]; + + node_imagetype_string(str); + + uiBlockBeginAlign(block); + + bt = uiDefIconBut(block, BUT, B_NODE_SETIMAGE, ICON_FILESEL, + x, y+60, 20, 20, + 0, 0, 0, 0, 0, "Open Fileselect to get Backbuf image"); + uiButSetFunc(bt, node_set_image_cb, ntree, node); + + uiDefBut(block, TEX, B_NOP, "", + 20+x, y+60, w-20, 20, + nif->name, 0.0f, 240.0f, 0, 0, ""); + + uiDefButS(block, MENU, B_NOP, str, + x, y+40, w, 20, + &nif->imtype, 0.0f, 1.0f, 0, 0, ""); + + if(nif->imtype==R_OPENEXR) { + uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_REDR, "Half", + x, y+20, w/2, 20, + &nif->subimtype, 0, 0, 0, 0, ""); + + uiDefButS(block, MENU,B_NOP, "Codec %t|None %x0|Pxr24 (lossy) %x1|ZIP (lossless) %x2|PIZ (lossless) %x3|RLE (lossless) %x4", + x+w/2, y+20, w/2, 20, + &nif->codec, 0, 0, 0, 0, ""); + } + else { + uiDefButS(block, NUM, B_NOP, "Quality: ", + x, y+20, w, 20, + &nif->quality, 10.0f, 100.0f, 10, 0, ""); } - return 80; + + /* start frame, end frame */ + uiDefButI(block, NUM, B_NODE_EXEC, "SFra: ", + x, y, w/2, 20, + &nif->sfra, 1, MAXFRAMEF, 10, 0, ""); + uiDefButI(block, NUM, B_NODE_EXEC, "EFra: ", + x+w/2, y, w/2, 20, + &nif->efra, 1, MAXFRAMEF, 10, 0, ""); } static void node_scale_cb(bContext *C, void *node_v, void *unused_v) @@ -1952,65 +1916,66 @@ static void node_scale_cb(bContext *C, void *node_v, void *unused_v) } } -static int node_composit_buts_scale(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_scale(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt= uiDefButS(block, MENU, B_NODE_EXEC, "Relative %x0|Absolute %x1|Scene Size % %x2|", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, "Scale new image to absolute pixel size, size relative to the incoming image, or using the 'percent' size of the scene"); - uiButSetFunc(bt, node_scale_cb, node, NULL); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt= uiDefButS(block, MENU, B_NODE_EXEC, "Relative %x0|Absolute %x1|Scene Size % %x2|", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 0, 0, 0, "Scale new image to absolute pixel size, size relative to the incoming image, or using the 'percent' size of the scene"); + uiButSetFunc(bt, node_scale_cb, node, NULL); } -static int node_composit_buts_invert(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_invert(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, CMP_CHAN_RGB, B_NODE_EXEC, "RGB", - butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiDefButBitS(block, TOG, CMP_CHAN_A, B_NODE_EXEC, "A", - butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiBlockEndAlign(block); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, CMP_CHAN_RGB, B_NODE_EXEC, "RGB", + butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 20, + &node->custom1, 0, 0, 0, 0, ""); + uiDefButBitS(block, TOG, CMP_CHAN_A, B_NODE_EXEC, "A", + butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 20, + &node->custom1, 0, 0, 0, 0, ""); + uiBlockEndAlign(block); } -static int node_composit_buts_premulkey(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_premulkey(uiLayout *layout, PointerRNA *ptr) { - if(block) { - uiBut *bt; - - /* blend type */ - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Key to Premul %x0|Premul to Key %x1", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, "Conversion between premultiplied alpha and key alpha"); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt; + + /* blend type */ + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Key to Premul %x0|Premul to Key %x1", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 0, 0, 0, "Conversion between premultiplied alpha and key alpha"); } -static int node_composit_buts_view_levels(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_composit_buts_view_levels(uiLayout *layout, PointerRNA *ptr) { - if(block) { - short sx= (butr->xmax-butr->xmin)/5; - - /*color space selectors*/ - uiBlockBeginAlign(block); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"C", - butr->xmin,butr->ymin,sx,20,&node->custom1,1,1, 0, 0, "Combined RGB"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"R", - butr->xmin+sx,butr->ymin,sx,20,&node->custom1,1,2, 0, 0, "Red Channel"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"G", - butr->xmin+2*sx,butr->ymin,sx,20,&node->custom1,1,3, 0, 0, "Green Channel"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"B", - butr->xmin+3*sx,butr->ymin,sx,20,&node->custom1,1,4, 0, 0, "Blue Channel"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"L", - butr->xmin+4*sx,butr->ymin,sx,20,&node->custom1,1,5, 0, 0, "Luminenc Channel"); - uiBlockEndAlign(block); - } - return 20; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + short sx= (butr->xmax-butr->xmin)/5; + + /*color space selectors*/ + uiBlockBeginAlign(block); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"C", + butr->xmin,butr->ymin,sx,20,&node->custom1,1,1, 0, 0, "Combined RGB"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"R", + butr->xmin+sx,butr->ymin,sx,20,&node->custom1,1,2, 0, 0, "Red Channel"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"G", + butr->xmin+2*sx,butr->ymin,sx,20,&node->custom1,1,3, 0, 0, "Green Channel"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"B", + butr->xmin+3*sx,butr->ymin,sx,20,&node->custom1,1,4, 0, 0, "Blue Channel"); + uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"L", + butr->xmin+4*sx,butr->ymin,sx,20,&node->custom1,1,5, 0, 0, "Luminenc Channel"); + uiBlockEndAlign(block); } @@ -2021,181 +1986,181 @@ static void node_composit_set_butfunc(bNodeType *ntype) /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ case CMP_NODE_IMAGE: - ntype->butfunc= node_composit_buts_image; + ntype->uifunc= node_composit_buts_image; break; case CMP_NODE_R_LAYERS: - ntype->butfunc= node_composit_buts_renderlayers; + ntype->uifunc= node_composit_buts_renderlayers; break; case CMP_NODE_NORMAL: - ntype->butfunc= node_buts_normal; + ntype->uifunc= node_buts_normal; break; case CMP_NODE_CURVE_VEC: - ntype->butfunc= node_buts_curvevec; + ntype->uifunc= node_buts_curvevec; break; case CMP_NODE_CURVE_RGB: - ntype->butfunc= node_buts_curvecol; + ntype->uifunc= node_buts_curvecol; break; case CMP_NODE_VALUE: - ntype->butfunc= node_buts_value; + ntype->uifunc= node_buts_value; break; case CMP_NODE_RGB: - ntype->butfunc= node_buts_rgb; + ntype->uifunc= node_buts_rgb; break; case CMP_NODE_FLIP: - ntype->butfunc= node_composit_buts_flip; + ntype->uifunc= node_composit_buts_flip; break; case CMP_NODE_SPLITVIEWER: - ntype->butfunc= node_composit_buts_splitviewer; + ntype->uifunc= node_composit_buts_splitviewer; break; case CMP_NODE_MIX_RGB: - ntype->butfunc= node_buts_mix_rgb; + ntype->uifunc= node_buts_mix_rgb; break; case CMP_NODE_VALTORGB: - ntype->butfunc= node_buts_valtorgb; + ntype->uifunc= node_buts_valtorgb; break; case CMP_NODE_CROP: - ntype->butfunc= node_composit_buts_crop; + ntype->uifunc= node_composit_buts_crop; break; case CMP_NODE_BLUR: - ntype->butfunc= node_composit_buts_blur; + ntype->uifunc= node_composit_buts_blur; break; case CMP_NODE_DBLUR: - ntype->butfunc= node_composit_buts_dblur; + ntype->uifunc= node_composit_buts_dblur; break; case CMP_NODE_BILATERALBLUR: - ntype->butfunc= node_composit_buts_bilateralblur; + ntype->uifunc= node_composit_buts_bilateralblur; break; /* qdn: defocus node */ case CMP_NODE_DEFOCUS: - ntype->butfunc = node_composit_buts_defocus; + ntype->uifunc = node_composit_buts_defocus; break; /* qdn: glare node */ case CMP_NODE_GLARE: - ntype->butfunc = node_composit_buts_glare; + ntype->uifunc = node_composit_buts_glare; break; /* qdn: tonemap node */ case CMP_NODE_TONEMAP: - ntype->butfunc = node_composit_buts_tonemap; + ntype->uifunc = node_composit_buts_tonemap; break; /* qdn: lens distortion node */ case CMP_NODE_LENSDIST: - ntype->butfunc = node_composit_buts_lensdist; + ntype->uifunc = node_composit_buts_lensdist; break; case CMP_NODE_VECBLUR: - ntype->butfunc= node_composit_buts_vecblur; + ntype->uifunc= node_composit_buts_vecblur; break; case CMP_NODE_FILTER: - ntype->butfunc= node_composit_buts_filter; + ntype->uifunc= node_composit_buts_filter; break; case CMP_NODE_MAP_VALUE: - ntype->butfunc= node_composit_buts_map_value; + ntype->uifunc= node_composit_buts_map_value; break; case CMP_NODE_TIME: - ntype->butfunc= node_buts_time; + ntype->uifunc= node_buts_time; break; case CMP_NODE_ALPHAOVER: - ntype->butfunc= node_composit_buts_alphaover; + ntype->uifunc= node_composit_buts_alphaover; break; case CMP_NODE_HUE_SAT: - ntype->butfunc= node_composit_buts_hue_sat; + ntype->uifunc= node_composit_buts_hue_sat; break; case CMP_NODE_TEXTURE: - ntype->butfunc= node_buts_texture; + ntype->uifunc= node_buts_texture; break; case CMP_NODE_DILATEERODE: - ntype->butfunc= node_composit_buts_dilateerode; + ntype->uifunc= node_composit_buts_dilateerode; break; case CMP_NODE_OUTPUT_FILE: - ntype->butfunc= node_composit_buts_file_output; + ntype->uifunc= node_composit_buts_file_output; break; case CMP_NODE_DIFF_MATTE: - ntype->butfunc=node_composit_buts_diff_matte; + ntype->uifunc=node_composit_buts_diff_matte; break; case CMP_NODE_DIST_MATTE: - ntype->butfunc=node_composit_buts_distance_matte; + ntype->uifunc=node_composit_buts_distance_matte; break; case CMP_NODE_COLOR_SPILL: - ntype->butfunc=node_composit_buts_color_spill; + ntype->uifunc=node_composit_buts_color_spill; break; case CMP_NODE_CHROMA_MATTE: - ntype->butfunc=node_composit_buts_chroma_matte; + ntype->uifunc=node_composit_buts_chroma_matte; break; case CMP_NODE_COLOR_MATTE: - ntype->butfunc=node_composit_buts_color_matte; + ntype->uifunc=node_composit_buts_color_matte; break; case CMP_NODE_SCALE: - ntype->butfunc= node_composit_buts_scale; + ntype->uifunc= node_composit_buts_scale; break; case CMP_NODE_CHANNEL_MATTE: - ntype->butfunc= node_composit_buts_channel_matte; + ntype->uifunc= node_composit_buts_channel_matte; break; case CMP_NODE_LUMA_MATTE: - ntype->butfunc= node_composit_buts_luma_matte; + ntype->uifunc= node_composit_buts_luma_matte; break; case CMP_NODE_MAP_UV: - ntype->butfunc= node_composit_buts_map_uv; + ntype->uifunc= node_composit_buts_map_uv; break; case CMP_NODE_ID_MASK: - ntype->butfunc= node_composit_buts_id_mask; + ntype->uifunc= node_composit_buts_id_mask; break; case CMP_NODE_MATH: - ntype->butfunc= node_buts_math; + ntype->uifunc= node_buts_math; break; case CMP_NODE_INVERT: - ntype->butfunc= node_composit_buts_invert; + ntype->uifunc= node_composit_buts_invert; break; case CMP_NODE_PREMULKEY: - ntype->butfunc= node_composit_buts_premulkey; + ntype->uifunc= node_composit_buts_premulkey; break; case CMP_NODE_VIEW_LEVELS: - ntype->butfunc=node_composit_buts_view_levels; + ntype->uifunc=node_composit_buts_view_levels; break; default: - ntype->butfunc= NULL; + ntype->uifunc= NULL; } } /* ****************** BUTTON CALLBACKS FOR TEXTURE NODES ***************** */ -static int node_texture_buts_bricks(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_texture_buts_bricks(uiLayout *layout, PointerRNA *ptr) { - if(block) { - short w = butr->xmax-butr->xmin; - short ofw = 32; - - uiBlockBeginAlign(block); - - /* Offset */ - uiDefButF( - block, NUM, B_NODE_EXEC, "Offset", - butr->xmin, butr->ymin+20, w-ofw, 20, - &node->custom3, - 0, 1, 0.25, 2, - "Offset amount" ); - uiDefButS( - block, NUM, B_NODE_EXEC, "", - butr->xmin+w-ofw, butr->ymin+20, ofw, 20, - &node->custom1, - 2, 99, 0, 0, - "Offset every N rows" ); - - /* Squash */ - uiDefButF( - block, NUM, B_NODE_EXEC, "Squash", - butr->xmin, butr->ymin+0, w-ofw, 20, - &node->custom4, - 0, 99, 0.25, 2, - "Stretch amount" ); - uiDefButS( - block, NUM, B_NODE_EXEC, "", - butr->xmin+w-ofw, butr->ymin+0, ofw, 20, - &node->custom2, - 2, 99, 0, 0, - "Stretch every N rows" ); - - uiBlockEndAlign(block); - } - return 40; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + short w = butr->xmax-butr->xmin; + short ofw = 32; + + uiBlockBeginAlign(block); + + /* Offset */ + uiDefButF( + block, NUM, B_NODE_EXEC, "Offset", + butr->xmin, butr->ymin+20, w-ofw, 20, + &node->custom3, + 0, 1, 0.25, 2, + "Offset amount" ); + uiDefButS( + block, NUM, B_NODE_EXEC, "", + butr->xmin+w-ofw, butr->ymin+20, ofw, 20, + &node->custom1, + 2, 99, 0, 0, + "Offset every N rows" ); + + /* Squash */ + uiDefButF( + block, NUM, B_NODE_EXEC, "Squash", + butr->xmin, butr->ymin+0, w-ofw, 20, + &node->custom4, + 0, 99, 0.25, 2, + "Stretch amount" ); + uiDefButS( + block, NUM, B_NODE_EXEC, "", + butr->xmin+w-ofw, butr->ymin+0, ofw, 20, + &node->custom2, + 2, 99, 0, 0, + "Stretch every N rows" ); + + uiBlockEndAlign(block); } /* Copied from buttons_shading.c -- needs unifying */ @@ -2206,208 +2171,196 @@ static char* noisebasis_menu() return nbmenu; } -static int node_texture_buts_proc(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_texture_buts_proc(uiLayout *layout, PointerRNA *ptr) { + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; Tex *tex = (Tex *)node->storage; short x,y,w,h; - if( block ) { - x = butr->xmin; - y = butr->ymin; - w = butr->xmax - x; - h = butr->ymax - y; - } - else - return 0; + x = butr->xmin; + y = butr->ymin; + w = butr->xmax - x; + h = butr->ymax - y; switch( tex->type ) { case TEX_BLEND: - if( block ) { - uiBlockBeginAlign( block ); - uiDefButS( block, MENU, B_NODE_EXEC, - "Linear %x0|Quad %x1|Ease %x2|Diag %x3|Sphere %x4|Halo %x5|Radial %x6", - x, y+20, w, 20, &tex->stype, 0, 1, 0, 0, "Blend Type" ); - uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_NODE_EXEC, "Flip XY", x, y, w, 20, - &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees"); - uiBlockEndAlign( block ); - } - return 40; - + uiBlockBeginAlign( block ); + uiDefButS( block, MENU, B_NODE_EXEC, + "Linear %x0|Quad %x1|Ease %x2|Diag %x3|Sphere %x4|Halo %x5|Radial %x6", + x, y+20, w, 20, &tex->stype, 0, 1, 0, 0, "Blend Type" ); + uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_NODE_EXEC, "Flip XY", x, y, w, 20, + &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees"); + uiBlockEndAlign( block ); + break; case TEX_MARBLE: - if( block ) { - uiBlockBeginAlign(block); + uiBlockBeginAlign(block); + + uiDefButS(block, ROW, B_NODE_EXEC, "Soft", 0*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble"); + uiDefButS(block, ROW, B_NODE_EXEC, "Sharp", 1*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble"); + uiDefButS(block, ROW, B_NODE_EXEC, "Sharper", 2*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble"); - uiDefButS(block, ROW, B_NODE_EXEC, "Soft", 0*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble"); - uiDefButS(block, ROW, B_NODE_EXEC, "Sharp", 1*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble"); - uiDefButS(block, ROW, B_NODE_EXEC, "Sharper", 2*w/3+x, 40+y, w/3, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble"); - - uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise"); - uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise"); - - uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands."); - uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands"); - uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands"); - - uiBlockEndAlign(block); - } - return 60; + uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise"); + uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 20+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise"); + + uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands."); + uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands"); + uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 0+y, w/3, 18, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands"); + + uiBlockEndAlign(block); + break; case TEX_WOOD: - if( block ) { - uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+64, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence"); - - uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_TEXPRV, "Bands", x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Uses standard noise"); - uiDefButS(block, ROW, B_TEXPRV, "Rings", w/2+x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Lets Noise return RGB value"); - - uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands."); - uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands"); - uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands"); - - uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise"); - uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise"); - uiBlockEndAlign(block); - } - return 80; + uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+64, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence"); + + uiBlockBeginAlign(block); + uiDefButS(block, ROW, B_TEXPRV, "Bands", x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Uses standard noise"); + uiDefButS(block, ROW, B_TEXPRV, "Rings", w/2+x, 40+y, w/2, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Lets Noise return RGB value"); + + uiDefButS(block, ROW, B_NODE_EXEC, "Sin", 0*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands."); + uiDefButS(block, ROW, B_NODE_EXEC, "Saw", 1*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands"); + uiDefButS(block, ROW, B_NODE_EXEC, "Tri", 2*w/3+x, 20+y, w/3, 18, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands"); + + uiDefButS(block, ROW, B_NODE_EXEC, "Soft noise", 0*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise"); + uiDefButS(block, ROW, B_NODE_EXEC, "Hard noise", 1*w/2+x, 0+y, w/2, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise"); + uiBlockEndAlign(block); + break; case TEX_CLOUDS: - if( block ) { - uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+60, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence"); - - uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_TEXPRV, "B/W", x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise"); - uiDefButS(block, ROW, B_TEXPRV, "Color", w/2+x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value"); - uiDefButS(block, ROW, B_TEXPRV, "Soft", x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise"); - uiDefButS(block, ROW, B_TEXPRV, "Hard", w/2+x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise"); - uiBlockEndAlign(block); - - uiDefButS(block, NUM, B_TEXPRV, "Depth:", x, y, w, 18, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation"); - } - return 80; + uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+60, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis used for turbulence"); + + uiBlockBeginAlign(block); + uiDefButS(block, ROW, B_TEXPRV, "B/W", x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise"); + uiDefButS(block, ROW, B_TEXPRV, "Color", w/2+x, y+38, w/2, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value"); + uiDefButS(block, ROW, B_TEXPRV, "Soft", x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise"); + uiDefButS(block, ROW, B_TEXPRV, "Hard", w/2+x, y+20, w/2, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise"); + uiBlockEndAlign(block); + + uiDefButS(block, NUM, B_TEXPRV, "Depth:", x, y, w, 18, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation"); + break; case TEX_DISTNOISE: - if( block ) { - uiBlockBeginAlign(block); - uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+18, w, 18, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort"); - uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion"); - uiBlockEndAlign(block); - } - return 36; + uiBlockBeginAlign(block); + uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y+18, w, 18, &tex->noisebasis2, 0,0,0,0, "Sets the noise basis to distort"); + uiDefButS(block, MENU, B_TEXPRV, noisebasis_menu(), x, y, w, 18, &tex->noisebasis, 0,0,0,0, "Sets the noise basis which does the distortion"); + uiBlockEndAlign(block); + break; } - return 0; } -static int node_texture_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_texture_buts_image(uiLayout *layout, PointerRNA *ptr) { + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + bNodeTree *ntree= ptr->id.data; + rctf *butr= &node->butr; char *strp; uiBut *bt; + + uiBlockBeginAlign(block); - if( block ) { - uiBlockBeginAlign(block); - - /* browse button */ - IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL); - node->menunr= 0; - bt= uiDefButS(block, MENU, B_NOP, strp, - butr->xmin, butr->ymin, 19, 19, - &node->menunr, 0, 0, 0, 0, "Browses existing choices"); - uiButSetFunc(bt, node_browse_image_cb, ntree, node); - if(strp) MEM_freeN(strp); + /* browse button */ + IMAnames_to_pupstring(&strp, NULL, "LOAD NEW %x32767", &(G.main->image), NULL, NULL); + node->menunr= 0; + bt= uiDefButS(block, MENU, B_NOP, strp, + butr->xmin, butr->ymin, 19, 19, + &node->menunr, 0, 0, 0, 0, "Browses existing choices"); + uiButSetFunc(bt, node_browse_image_cb, ntree, node); + if(strp) MEM_freeN(strp); + + /* Add New button */ + if(node->id==NULL) { + bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New", + butr->xmin+19, butr->ymin, (short)(butr->xmax-butr->xmin-19.0f), 19, + NULL, 0.0, 0.0, 0, 0, "Add new Image"); + uiButSetFunc(bt, node_active_cb, ntree, node); + } + else { + /* name button */ + short xmin= (short)butr->xmin, xmax= (short)butr->xmax; + short width= xmax - xmin - 19; - /* Add New button */ - if(node->id==NULL) { - bt= uiDefBut(block, BUT, B_NODE_LOADIMAGE, "Load New", - butr->xmin+19, butr->ymin, (short)(butr->xmax-butr->xmin-19.0f), 19, - NULL, 0.0, 0.0, 0, 0, "Add new Image"); - uiButSetFunc(bt, node_active_cb, ntree, node); - } - else { - /* name button */ - short xmin= (short)butr->xmin, xmax= (short)butr->xmax; - short width= xmax - xmin - 19; - - bt= uiDefBut(block, TEX, B_NOP, "IM:", - xmin+19, butr->ymin, width, 19, - node->id->name+2, 0.0, 19.0, 0, 0, "Image name"); - uiButSetFunc(bt, node_ID_title_cb, node, NULL); - } + bt= uiDefBut(block, TEX, B_NOP, "IM:", + xmin+19, butr->ymin, width, 19, + node->id->name+2, 0.0, 19.0, 0, 0, "Image name"); + uiButSetFunc(bt, node_ID_title_cb, node, NULL); } - return 20; } -static int node_texture_buts_output(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +static void node_texture_buts_output(uiLayout *layout, PointerRNA *ptr) { - if( block ) { - uiBut *bt; - short width; - char *name = ((TexNodeOutput*)node->storage)->name; - - uiBlockBeginAlign(block); - - width = (short)(butr->xmax - butr->xmin); - - bt = uiDefBut( - block, TEX, B_NOP, - "Name:", - butr->xmin, butr->ymin, - width, 19, - name, 0, 31, - 0, 0, - "Name this output" - ); - - uiBlockEndAlign(block); - } - return 19; + uiBlock *block= uiLayoutFreeBlock(layout); + bNode *node= ptr->data; + rctf *butr= &node->butr; + uiBut *bt; + short width; + char *name = ((TexNodeOutput*)node->storage)->name; + + uiBlockBeginAlign(block); + + width = (short)(butr->xmax - butr->xmin); + + bt = uiDefBut( + block, TEX, B_NOP, + "Name:", + butr->xmin, butr->ymin, + width, 19, + name, 0, 31, + 0, 0, + "Name this output" + ); + + uiBlockEndAlign(block); } /* only once called */ static void node_texture_set_butfunc(bNodeType *ntype) { if( ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX ) { - ntype->butfunc = node_texture_buts_proc; + ntype->uifunc = node_texture_buts_proc; } else switch(ntype->type) { case TEX_NODE_MATH: - ntype->butfunc = node_buts_math; + ntype->uifunc = node_buts_math; break; case TEX_NODE_MIX_RGB: - ntype->butfunc = node_buts_mix_rgb; + ntype->uifunc = node_buts_mix_rgb; break; case TEX_NODE_VALTORGB: - ntype->butfunc = node_buts_valtorgb; + ntype->uifunc = node_buts_valtorgb; break; case TEX_NODE_CURVE_RGB: - ntype->butfunc= node_buts_curvecol; + ntype->uifunc= node_buts_curvecol; break; case TEX_NODE_CURVE_TIME: - ntype->butfunc = node_buts_time; + ntype->uifunc = node_buts_time; break; case TEX_NODE_TEXTURE: - ntype->butfunc = node_buts_texture; + ntype->uifunc = node_buts_texture; break; case TEX_NODE_BRICKS: - ntype->butfunc = node_texture_buts_bricks; + ntype->uifunc = node_texture_buts_bricks; break; case TEX_NODE_IMAGE: - ntype->butfunc = node_texture_buts_image; + ntype->uifunc = node_texture_buts_image; break; case TEX_NODE_OUTPUT: - ntype->butfunc = node_texture_buts_output; + ntype->uifunc = node_texture_buts_output; break; default: - ntype->butfunc= NULL; + ntype->uifunc= NULL; } } diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index a872413b4e1..a87a141972b 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -81,6 +81,8 @@ #include "UI_resources.h" #include "UI_view2d.h" +#include "RNA_access.h" + #include "CMP_node.h" #include "SHD_node.h" @@ -91,6 +93,50 @@ extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); extern void ui_draw_tria_icon(float x, float y, float aspect, char dir); +void ED_node_changed_update(bContext *C, bNode *node) +{ + SpaceNode *snode= CTX_wm_space_node(C); + + if(!snode) + return; + + if(snode->treetype==NTREE_SHADER) { + WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id); + } + else if(snode->treetype==NTREE_COMPOSIT) { + NodeTagChanged(snode->edittree, node); + /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */ + + /* not the best implementation of the world... but we need it to work now :) */ + if(node->type==CMP_NODE_R_LAYERS && node->custom2) { + /* add event for this window (after render curarea can be changed) */ + //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); + + //composite_node_render(snode, node); + //snode_handle_recalc(snode); + + /* add another event, a render can go fullscreen and open new window */ + //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); + } + else { + node= node_tree_get_editgroup(snode->nodetree); + if(node) + NodeTagIDChanged(snode->nodetree, node->id); + } + WM_event_add_notifier(C, NC_SCENE|ND_NODES, CTX_data_scene(C)); + } + else if(snode->treetype==NTREE_TEXTURE) { + WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id); + } + +} + +static void do_node_internal_buttons(bContext *C, void *node_v, int event) +{ + if(event==B_NODE_EXEC) + ED_node_changed_update(C, node_v); +} + static void node_scaling_widget(int color_id, float aspect, float xmin, float ymin, float xmax, float ymax) { @@ -110,10 +156,14 @@ static void node_scaling_widget(int color_id, float aspect, float xmin, float ym } /* based on settings in node, sets drawing rect info. each redraw! */ -static void node_update(bNode *node) +static void node_update(const bContext *C, bNodeTree *ntree, bNode *node) { + uiLayout *layout; + PointerRNA ptr; bNodeSocket *nsock; float dy= node->locy; + int buty; + char str[32]; /* header */ dy-= NODE_DY; @@ -121,7 +171,7 @@ static void node_update(bNode *node) /* little bit space in top */ if(node->outputs.first) dy-= NODE_DYS/2; - + /* output sockets */ for(nsock= node->outputs.first; nsock; nsock= nsock->next) { if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { @@ -130,9 +180,9 @@ static void node_update(bNode *node) dy-= NODE_DY; } } - - node->prvr.xmin= node->butr.xmin= node->locx + NODE_DYS; - node->prvr.xmax= node->butr.xmax= node->locx + node->width- NODE_DYS; + + node->prvr.xmin= node->locx + NODE_DYS; + node->prvr.xmax= node->locx + node->width- NODE_DYS; /* preview rect? */ if(node->flag & NODE_PREVIEW) { @@ -176,16 +226,35 @@ static void node_update(bNode *node) /* XXX ugly hack, typeinfo for group is generated */ if(node->type == NODE_GROUP) - ; // XXX node->typeinfo->butfunc= node_buts_group; + ; // XXX node->typeinfo->uifunc= node_buts_group; + + /* ui block */ + sprintf(str, "node buttons %p", node); + node->block= uiBeginBlock(C, CTX_wm_region(C), str, UI_EMBOSS); + uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node); /* buttons rect? */ - if((node->flag & NODE_OPTIONS) && node->typeinfo->butfunc) { + if((node->flag & NODE_OPTIONS) && node->typeinfo->uifunc) { dy-= NODE_DYS/2; - node->butr.ymax= dy; - node->butr.ymin= dy - (float)node->typeinfo->butfunc(NULL, NULL, node, NULL); - dy= node->butr.ymin - NODE_DYS/2; + + /* set this for uifunc() that don't use layout engine yet */ + node->butr.xmin= 0; + node->butr.xmax= node->width - 2*NODE_DYS; + node->butr.ymin= 0; + node->butr.ymax= 0; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + + layout= uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, + node->locx+NODE_DYS, dy, node->butr.xmax, 20, U.uistyles.first); + + node->typeinfo->uifunc(layout, &ptr); + uiBlockEndAlign(node->block); + uiBlockLayoutResolve(node->block, NULL, &buty); + + dy= buty - NODE_DYS/2; } - + /* input sockets */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) { if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { @@ -198,7 +267,7 @@ static void node_update(bNode *node) /* little bit space in end */ if(node->inputs.first || (node->flag & (NODE_OPTIONS|NODE_PREVIEW))==0 ) dy-= NODE_DYS/2; - + node->totr.xmin= node->locx; node->totr.xmax= node->locx + node->width; node->totr.ymax= node->locy; @@ -206,11 +275,12 @@ static void node_update(bNode *node) } /* based on settings in node, sets drawing rect info. each redraw! */ -static void node_update_hidden(bNode *node) +static void node_update_hidden(const bContext *C, bNode *node) { bNodeSocket *nsock; float rad, drad, hiddenrad= HIDDEN_RAD; int totin=0, totout=0, tot; + char str[32]; /* calculate minimal radius */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) @@ -251,6 +321,11 @@ static void node_update_hidden(bNode *node) rad+= drad; } } + + /* ui block */ + sprintf(str, "node buttons %p", node); + node->block= uiBeginBlock(C, CTX_wm_region(C), str, UI_EMBOSS); + uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node); } static int node_get_colorid(bNode *node) @@ -275,7 +350,7 @@ static int node_get_colorid(bNode *node) /* based on settings in node, sets drawing rect info. each redraw! */ /* note: this assumes only 1 group at a time is drawn (linked data) */ /* in node->totr the entire boundbox for the group is stored */ -static void node_update_group(bNode *gnode) +static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode) { bNodeTree *ngroup= (bNodeTree *)gnode->id; bNode *node; @@ -288,9 +363,9 @@ static void node_update_group(bNode *gnode) node->locx+= gnode->locx; node->locy+= gnode->locy; if(node->flag & NODE_HIDDEN) - node_update_hidden(node); + node_update_hidden(C, node); else - node_update(node); + node_update(C, ntree, node); node->locx-= gnode->locx; node->locy-= gnode->locy; } @@ -575,61 +650,15 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) } -static void do_node_internal_buttons(bContext *C, void *node_v, int event) -{ - SpaceNode *snode= CTX_wm_space_node(C); - - if(event==B_NODE_EXEC) { - if(snode->treetype==NTREE_SHADER) { - WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id); - } - else if(snode->treetype==NTREE_COMPOSIT) { - bNode *node= node_v; - - NodeTagChanged(snode->edittree, node); - /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */ - - /* not the best implementation of the world... but we need it to work now :) */ - if(node->type==CMP_NODE_R_LAYERS && node->custom2) { - /* add event for this window (after render curarea can be changed) */ - //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); - - //composite_node_render(snode, node); - //snode_handle_recalc(snode); - - /* add another event, a render can go fullscreen and open new window */ - //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); - } - else { - node= node_tree_get_editgroup(snode->nodetree); - if(node) - NodeTagIDChanged(snode->nodetree, node->id); - } - WM_event_add_notifier(C, NC_SCENE|ND_NODES, CTX_data_scene(C)); - } - else if(snode->treetype==NTREE_TEXTURE) { - WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id); - } - } - -} - static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNode *node) { bNodeSocket *sock; - uiBlock *block; uiBut *bt; rctf *rct= &node->totr; float /*slen,*/ iconofs; int /*ofs,*/ color_id= node_get_colorid(node); char showname[128]; /* 128 used below */ View2D *v2d = &ar->v2d; - char str[32]; - - /* make unique block name, also used for handling blocks in editnode.c */ - sprintf(str, "node buttons %p", node); - block= uiBeginBlock(C, ar, str, UI_EMBOSS); - uiBlockSetHandleFunc(block, do_node_internal_buttons, node); uiSetRoundBox(15-4); ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT); @@ -715,7 +744,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN else BLI_strncpy(showname, node->name, 128); - uiDefBut(block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(rct->ymax-NODE_DY), + uiDefBut(node->block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(rct->ymax-NODE_DY), (int)(iconofs - rct->xmin-18.0f), NODE_DY, NULL, 0, 0, 0, 0, ""); /* body */ @@ -743,7 +772,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* hurmf... another candidate for callback, have to see how this works first */ - if(node->id && block && snode->treetype==NTREE_SHADER) + if(node->id && node->block && snode->treetype==NTREE_SHADER) nodeShaderSynchronizeID(node, 0); /* socket inputs, buttons */ @@ -751,38 +780,38 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { socket_circle_draw(sock, NODE_SOCKSIZE); - if(block && sock->link==NULL) { + if(node->block && sock->link==NULL) { float *butpoin= sock->ns.vec; if(sock->type==SOCK_VALUE) { - bt= uiDefButF(block, NUM, B_NODE_EXEC, sock->name, + bt= uiDefButF(node->block, NUM, B_NODE_EXEC, sock->name, (short)sock->locx+NODE_DYS, (short)(sock->locy)-9, (short)node->width-NODE_DY, 17, butpoin, sock->ns.min, sock->ns.max, 10, 2, ""); uiButSetFunc(bt, node_sync_cb, snode, node); } else if(sock->type==SOCK_VECTOR) { - uiDefBlockBut(block, socket_vector_menu, sock, sock->name, + uiDefBlockBut(node->block, socket_vector_menu, sock, sock->name, (short)sock->locx+NODE_DYS, (short)sock->locy-9, (short)node->width-NODE_DY, 17, ""); } - else if(block && sock->type==SOCK_RGBA) { + else if(node->block && sock->type==SOCK_RGBA) { short labelw= (short)node->width-NODE_DY-40, width; if(labelw>0) width= 40; else width= (short)node->width-NODE_DY; - bt= uiDefButF(block, COL, B_NODE_EXEC, "", + bt= uiDefButF(node->block, COL, B_NODE_EXEC, "", (short)(sock->locx+NODE_DYS), (short)sock->locy-8, width, 15, butpoin, 0, 0, 0, 0, ""); uiButSetFunc(bt, node_sync_cb, snode, node); - if(labelw>0) uiDefBut(block, LABEL, 0, sock->name, + if(labelw>0) uiDefBut(node->block, LABEL, 0, sock->name, (short)(sock->locx+NODE_DYS) + 40, (short)sock->locy-8, labelw, 15, NULL, 0, 0, 0, 0, ""); } } else { - uiDefBut(block, LABEL, 0, sock->name, (short)(sock->locx+3.0f), (short)(sock->locy-9.0f), + uiDefBut(node->block, LABEL, 0, sock->name, (short)(sock->locx+3.0f), (short)(sock->locy-9.0f), (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); } } @@ -803,7 +832,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN slen= snode->aspect*UI_GetStringWidth(sock->name+ofs); } - uiDefBut(block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), + uiDefBut(node->block, LABEL, 0, sock->name+ofs, (short)(sock->locx-15.0f-slen), (short)(sock->locy-9.0f), (short)(node->width-NODE_DY), NODE_DY, NULL, 0, 0, 0, 0, ""); } } @@ -813,33 +842,19 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN if(node->preview && node->preview->rect) node_draw_preview(node->preview, &node->prvr); - /* buttons */ - if(node->flag & NODE_OPTIONS) { - if(block) { - if(node->typeinfo->butfunc) { - node->typeinfo->butfunc(block, snode->nodetree, node, &node->butr); - } - } - } - - uiEndBlock(C, block); - uiDrawBlock(C, block); + uiEndBlock(C, node->block); + uiDrawBlock(C, node->block); + node->block= NULL; } static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, bNode *node) { - uiBlock *block; bNodeSocket *sock; rctf *rct= &node->totr; float dx, centy= 0.5f*(rct->ymax+rct->ymin); float hiddenrad= 0.5f*(rct->ymax-rct->ymin); int color_id= node_get_colorid(node); - char str[32], showname[128]; /* 128 is used below */ - - /* make unique block name, also used for handling blocks in editnode.c */ - sprintf(str, "node buttons %p", node); - block= uiBeginBlock(C, ar, str, UI_EMBOSS); - uiBlockSetHandleFunc(block, do_node_internal_buttons, node); + char showname[128]; /* 128 is used below */ /* shadow */ uiSetRoundBox(15); @@ -884,7 +899,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b else BLI_strncpy(showname, node->name, 128); - uiDefBut(block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(centy-10), + uiDefBut(node->block, LABEL, 0, showname, (short)(rct->xmin+15), (short)(centy-10), (int)(rct->xmax - rct->xmin-18.0f -12.0f), NODE_DY, NULL, 0, 0, 0, 0, ""); } @@ -910,9 +925,9 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b socket_circle_draw(sock, NODE_SOCKSIZE); } - uiEndBlock(C, block); - uiDrawBlock(C, block); - + uiEndBlock(C, node->block); + uiDrawBlock(C, node->block); + node->block= NULL; } static void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree) @@ -1081,11 +1096,11 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) /* for now, we set drawing coordinates on each redraw */ for(node= snode->nodetree->nodes.first; node; node= node->next) { if(node->flag & NODE_GROUP_EDIT) - node_update_group(node); + node_update_group(C, snode->nodetree, node); else if(node->flag & NODE_HIDDEN) - node_update_hidden(node); + node_update_hidden(C, node); else - node_update(node); + node_update(C, snode->nodetree, node); } node_draw_nodetree(C, ar, snode, snode->nodetree); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b10de02dbb4..e70221df9ab 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -40,6 +40,7 @@ struct bNodeLink; struct bNodeType; struct bNodeGroup; struct AnimData; +struct uiBlock; #define NODE_MAXSTR 32 @@ -131,6 +132,7 @@ typedef struct bNode { rctf butr; /* optional buttons area */ rctf prvr; /* optional preview area */ bNodePreview *preview; /* optional preview image */ + struct uiBlock *block; /* runtime during drawing */ struct bNodeType *typeinfo; /* lookup of callbacks and defaults */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 99f61c7a724..25fc8e966dc 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -25,6 +25,7 @@ #include #include +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" @@ -37,8 +38,81 @@ #include "BKE_node.h" #include "BKE_image.h" +static EnumPropertyItem node_blend_type_items[] = { + { 0, "MIX", 0, "Mix", ""}, + { 1, "ADD", 0, "Add", ""}, + { 3, "SUBTRACT", 0, "Subtract", ""}, + { 2, "MULTIPLY", 0, "Multiply", ""}, + { 4, "SCREEN", 0, "Screen", ""}, + { 9, "OVERLAY", 0, "Overlay", ""}, + { 5, "DIVIDE", 0, "Divide", ""}, + { 6, "DIFFERENCE", 0, "Difference", ""}, + { 7, "DARKEN", 0, "Darken", ""}, + { 8, "LIGHTEN", 0, "Lighten", ""}, + {10, "DODGE", 0, "Dodge", ""}, + {11, "BURN", 0, "Burn", ""}, + {15, "COLOR", 0, "Color", ""}, + {14, "VALUE", 0, "Value", ""}, + {13, "SATURATION", 0, "Saturation", ""}, + {12, "HUE", 0, "Hue", ""}, + {16, "SOFT_LIGHT", 0, "Soft Light", ""}, + {17, "LINEAR_LIGHT", 0, "Linear Light",""}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem node_flip_items[] = { + {0, "X", 0, "Flip X", ""}, + {1, "Y", 0, "Flip Y", ""}, + {2, "XY", 0, "Flip X & Y", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem node_math_items[] = { + { 0, "ADD", 0, "Add", ""}, + { 1, "SUBTRACT", 0, "Subtract", ""}, + { 2, "MULTIPLY", 0, "Multiply", ""}, + { 3, "DIVIDE", 0, "Divide", ""}, + { 4, "SINE", 0, "Sine", ""}, + { 5, "COSINE", 0, "Cosine", ""}, + { 6, "TANGENT", 0, "Tangent", ""}, + { 7, "ARCSINE", 0, "Arcsine", ""}, + { 8, "ARCCOSINE", 0, "Arccosine", ""}, + { 9, "ARCTANGENT", 0, "Arctangent", ""}, + {10, "POWER", 0, "Power", ""}, + {11, "LOGARITHM", 0, "Logarithm", ""}, + {12, "MINIMUM", 0, "Minimum", ""}, + {13, "MAXIMUM", 0, "Maximum", ""}, + {14, "ROUND", 0, "Round", ""}, + {15, "LESS_THAN", 0, "Less Than", ""}, + {16, "GREATER_THAN", 0, "Greater Than", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem node_vec_math_items[] = { + {0, "ADD", 0, "Add", ""}, + {1, "SUBTRACT", 0, "Subtract", ""}, + {2, "AVERAGE", 0, "Average", ""}, + {3, "DOT_PRODUCT", 0, "Dot Product", ""}, + {4, "CROSS_PRODUCT", 0, "Cross Product", ""}, + {5, "NORMALIZE", 0, "Normalize", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem node_filter_items[] = { + {0, "SOFTEN", 0, "Soften", ""}, + {1, "SHARPEN", 0, "Sharpen", ""}, + {2, "LAPLACE", 0, "Laplace", ""}, + {3, "SOBEL", 0, "Sobel", ""}, + {4, "PREWITT", 0, "Prewitt", ""}, + {5, "KIRSCH", 0, "Kirsch", ""}, + {6, "SHADOW", 0, "Shadow", ""}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME +#include "ED_node.h" + static StructRNA *rna_Node_refine(struct PointerRNA *ptr) { bNode *node = (bNode*)ptr->data; @@ -66,6 +140,53 @@ static char *rna_Node_path(PointerRNA *ptr) return BLI_sprintfN("nodes[%d]", index); } +static void rna_Node_update(bContext *C, PointerRNA *ptr) +{ + bNode *node= (bNode*)ptr->data; + + ED_node_changed_update(C, node); +} + +static void rna_Node_update_name(bContext *C, PointerRNA *ptr) +{ + bNode *node= (bNode*)ptr->data; + const char *name; + + if(node->id) { + BLI_strncpy(node->name, node->id->name+2, NODE_MAXSTR); + } + else { + switch(node->typeinfo->type) { + case SH_NODE_MIX_RGB: + case CMP_NODE_MIX_RGB: + case TEX_NODE_MIX_RGB: + if(RNA_enum_name(node_blend_type_items, node->custom1, &name)) + BLI_strncpy(node->name, name, NODE_MAXSTR); + break; + case CMP_NODE_FILTER: + if(RNA_enum_name(node_filter_items, node->custom1, &name)) + BLI_strncpy(node->name, name, NODE_MAXSTR); + break; + case CMP_NODE_FLIP: + if(RNA_enum_name(node_flip_items, node->custom1, &name)) + BLI_strncpy(node->name, name, NODE_MAXSTR); + break; + case SH_NODE_MATH: + case CMP_NODE_MATH: + case TEX_NODE_MATH: + if(RNA_enum_name(node_math_items, node->custom1, &name)) + BLI_strncpy(node->name, name, NODE_MAXSTR); + break; + case SH_NODE_VECT_MATH: + if(RNA_enum_name(node_vec_math_items, node->custom1, &name)) + BLI_strncpy(node->name, name, NODE_MAXSTR); + break; + } + } + + rna_Node_update(C, ptr); +} + #else #define MaxNodes 1000 @@ -183,53 +304,22 @@ static void def_math(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem items[] = { - { 0, "ADD", 0, "Add", ""}, - { 1, "SUBTRACT", 0, "Subtract", ""}, - { 2, "MULTIPLY", 0, "Multiply", ""}, - { 3, "DIVIDE", 0, "Divide", ""}, - { 4, "SINE", 0, "Sine", ""}, - { 5, "COSINE", 0, "Cosine", ""}, - { 6, "TANGENT", 0, "Tangent", ""}, - { 7, "ARCSINE", 0, "Arcsine", ""}, - { 8, "ARCCOSINE", 0, "Arccosine", ""}, - { 9, "ARCTANGENT", 0, "Arctangent", ""}, - {10, "POWER", 0, "Power", ""}, - {11, "LOGARITHM", 0, "Logarithm", ""}, - {12, "MINIMUM", 0, "Minimum", ""}, - {13, "MAXIMUM", 0, "Maximum", ""}, - {14, "ROUND", 0, "Round", ""}, - {15, "LESS_THAN", 0, "Less Than", ""}, - {16, "GREATER_THAN", 0, "Greater Than", ""}, - - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, items); + RNA_def_property_enum_items(prop, node_math_items); RNA_def_property_ui_text(prop, "Operation", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); } static void def_vector_math(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem items[] = { - {0, "ADD", 0, "Add", ""}, - {1, "SUBTRACT", 0, "Subtract", ""}, - {2, "AVERAGE", 0, "Average", ""}, - {3, "DOT_PRODUCT", 0, "Dot Product", ""}, - {4, "CROSS_PRODUCT", 0, "Cross Product", ""}, - {5, "NORMALIZE", 0, "Normalize", ""}, - - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, items); + RNA_def_property_enum_items(prop, node_vec_math_items); RNA_def_property_ui_text(prop, "Operation", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); } static void def_rgb_curve(StructRNA *srna) @@ -240,6 +330,7 @@ static void def_rgb_curve(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "storage"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_vector_curve(StructRNA *srna) @@ -250,6 +341,7 @@ static void def_vector_curve(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "storage"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_time(StructRNA *srna) @@ -260,59 +352,44 @@ static void def_time(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "storage"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Curve", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_ui_text(prop, "Start Frame", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "end", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); RNA_def_property_ui_text(prop, "End Frame", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_val_to_rgb(StructRNA *srna) { - /*PropertyRNA *prop;*/ + PropertyRNA *prop; - /* TODO: uncomment when ColorBand is wrapped *//* - prop = RNA_def_property(srna, "color_band", PROP_POINTER, PROP_NONE); + prop = RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "storage"); - RNA_def_property_struct_type(prop, "ColorBand"); - RNA_def_property_ui_text(prop, "Color Band", "");*/ + RNA_def_property_struct_type(prop, "ColorRamp"); + RNA_def_property_ui_text(prop, "Color Ramp", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_mix_rgb(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem blend_type_items[] = { - { 0, "MIX", 0, "Mix", ""}, - { 1, "ADD", 0, "Add", ""}, - { 3, "SUBTRACT", 0, "Subtract", ""}, - { 2, "MULTIPLY", 0, "Multiply", ""}, - { 4, "SCREEN", 0, "Screen", ""}, - { 9, "OVERLAY", 0, "Overlay", ""}, - { 5, "DIVIDE", 0, "Divide", ""}, - { 6, "DIFFERENCE", 0, "Difference", ""}, - { 7, "DARKEN", 0, "Darken", ""}, - { 8, "LIGHTEN", 0, "Lighten", ""}, - {10, "DODGE", 0, "Dodge", ""}, - {11, "BURN", 0, "Burn", ""}, - {15, "COLOR", 0, "Color", ""}, - {14, "VALUE", 0, "Value", ""}, - {13, "SATURATION", 0, "Saturation", ""}, - {12, "HUE", 0, "Hue", ""}, - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, blend_type_items); + RNA_def_property_enum_items(prop, node_blend_type_items); RNA_def_property_ui_text(prop, "Blend Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); prop = RNA_def_property(srna, "alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1); - RNA_def_property_ui_text(prop, "Diffuse", "Include alpha of second input in this operation"); + RNA_def_property_ui_text(prop, "Alpha", "Include alpha of second input in this operation"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_texture(StructRNA *srna) @@ -324,10 +401,12 @@ static void def_texture(StructRNA *srna) RNA_def_property_struct_type(prop, "Texture"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Texture", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); prop = RNA_def_property(srna, "node_output", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_ui_text(prop, "Node Output", "For node-based textures, which output node to use"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } @@ -342,18 +421,22 @@ static void def_sh_material(StructRNA *srna) RNA_def_property_struct_type(prop, "Material"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Material", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); prop = RNA_def_property(srna, "diffuse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_DIFF); RNA_def_property_ui_text(prop, "Diffuse", "Material Node outputs Diffuse"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "specular", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_SPEC); RNA_def_property_ui_text(prop, "Specular", "Material Node outputs Specular"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "invert_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_NEG); RNA_def_property_ui_text(prop, "Invert Normal", "Material Node uses inverted normal"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_sh_mapping(StructRNA *srna) @@ -364,6 +447,7 @@ static void def_sh_mapping(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "storage"); RNA_def_property_struct_type(prop, "TexMapping"); RNA_def_property_ui_text(prop, "Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_sh_geometry(StructRNA *srna) @@ -375,10 +459,12 @@ static void def_sh_geometry(StructRNA *srna) prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "uvname"); RNA_def_property_ui_text(prop, "UV Layer", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "color_layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "colname"); RNA_def_property_ui_text(prop, "Vertex Color Layer", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } @@ -391,6 +477,7 @@ static void def_cmp_alpha_over(StructRNA *srna) prop = RNA_def_property(srna, "convert_premul", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); RNA_def_property_ui_text(prop, "convert_premul", "TODO: don't know what this is"); + RNA_def_property_update(prop, 0, "rna_Node_update"); RNA_def_struct_sdna_from(srna, "NodeTwoFloats", "storage"); @@ -398,6 +485,7 @@ static void def_cmp_alpha_over(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "x"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Premul", "Mix Factor"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_blur(StructRNA *srna) @@ -422,58 +510,70 @@ static void def_cmp_blur(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "sizex"); RNA_def_property_range(prop, 0, 256); RNA_def_property_ui_text(prop, "Size X", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "sizey", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sizey"); RNA_def_property_range(prop, 1, 256); RNA_def_property_ui_text(prop, "Size Y", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "samples"); RNA_def_property_range(prop, 1, 256); RNA_def_property_ui_text(prop, "Samples", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "max_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "maxspeed"); RNA_def_property_range(prop, 1, 1024); RNA_def_property_ui_text(prop, "Max Speed", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "min_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "minspeed"); RNA_def_property_range(prop, 1, 1024); RNA_def_property_ui_text(prop, "Min Speed", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "relative", 1); RNA_def_property_ui_text(prop, "Relative", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fac"); RNA_def_property_range(prop, 0.0f, 2.0f); RNA_def_property_ui_text(prop, "Factor", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "factor_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "percentx"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Relative Size X", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "factor_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "percenty"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Relative Size Y", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "filtertype"); RNA_def_property_enum_items(prop, filter_type_items); RNA_def_property_ui_text(prop, "Filter Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "bokeh", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "bokeh", 1); RNA_def_property_ui_text(prop, "Bokeh", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "gamma", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gamma", 1); RNA_def_property_ui_text(prop, "Gamma", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: @@ -490,21 +590,11 @@ static void def_cmp_filter(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem type_items[] = { - {0, "SOFTEN", 0, "Soften", ""}, - {1, "SHARPEN", 0, "Sharpen", ""}, - {2, "LAPLACE", 0, "Laplace", ""}, - {3, "SOBEL", 0, "Sobel", ""}, - {4, "PREWITT", 0, "Prewitt", ""}, - {5, "KIRSCH", 0, "Kirsch", ""}, - {6, "SHADOW", 0, "Shadow", ""}, - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, type_items); + RNA_def_property_enum_items(prop, node_filter_items); RNA_def_property_ui_text(prop, "Filter Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); } static void def_cmp_map_value(StructRNA *srna) @@ -517,29 +607,35 @@ static void def_cmp_map_value(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "loc"); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Offset", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Size", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN); RNA_def_property_ui_text(prop, "Use Minimum", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX); RNA_def_property_ui_text(prop, "Use Maximum", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Minimum", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Maximum", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_vector_blur(StructRNA *srna) @@ -551,22 +647,27 @@ static void def_cmp_vector_blur(StructRNA *srna) prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "samples"); RNA_def_property_ui_text(prop, "Samples", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "min_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "minspeed"); RNA_def_property_ui_text(prop, "Min Speed", "Minimum speed for a pixel to be blurred; used to separate background from foreground"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "max_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "maxspeed"); - RNA_def_property_ui_text(prop, "Min Speed", "Maximum speed, or zero for none"); + RNA_def_property_ui_text(prop, "Max Speed", "Maximum speed, or zero for none"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fac"); RNA_def_property_ui_text(prop, "Blur Factor", "Scaling factor for motion vectors; actually 'shutter speed' in frames"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "curved", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "curved", 1); RNA_def_property_ui_text(prop, "Curved", "Interpolate between frames in a bezier curve, rather than linearly"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_image(StructRNA *srna) @@ -586,6 +687,7 @@ static void def_cmp_image(StructRNA *srna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); RNA_def_struct_sdna_from(srna, "ImageUser", "storage"); @@ -595,24 +697,29 @@ static void def_cmp_image(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "frames"); RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Frames", "Number of images used in animation"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sfra"); RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start Frame", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "offset", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "offset"); RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "cyclic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "cycl", 1); RNA_def_property_ui_text(prop, "Cyclic", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "auto_refresh", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANIM_ALWAYS); RNA_def_property_ui_text(prop, "Auto-Refresh", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* } */ @@ -622,6 +729,7 @@ static void def_cmp_image(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "layer"); RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Layer", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* } */ @@ -638,16 +746,19 @@ static void def_cmp_render_layers(StructRNA *srna) RNA_def_property_struct_type(prop, "Scene"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Scene", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); /* TODO: layers in menu */ prop = RNA_def_property(srna, "layer", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_ui_text(prop, "Layer", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: comments indicate this might be a hack */ prop = RNA_def_property(srna, "re_render", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1); RNA_def_property_ui_text(prop, "Re-render", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_output_file(StructRNA *srna) @@ -711,11 +822,13 @@ static void def_cmp_output_file(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "sfra"); RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start Frame", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "end", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "efra"); RNA_def_property_range(prop, 1, MAXFRAMEF); RNA_def_property_ui_text(prop, "End Frame", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_dilate_erode(StructRNA *srna) @@ -725,6 +838,7 @@ static void def_cmp_dilate_erode(StructRNA *srna) prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_scale(StructRNA *srna) @@ -742,6 +856,7 @@ static void def_cmp_scale(StructRNA *srna) 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, 0, "rna_Node_update"); } static void def_cmp_diff_matte(StructRNA *srna) @@ -756,11 +871,13 @@ static void def_cmp_diff_matte(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed."); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed."); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_color_matte(StructRNA *srna) @@ -775,16 +892,19 @@ static void def_cmp_color_matte(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "H", "Hue tolerance for colors to be considered a keying color"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "s", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "S", "Saturation Tolerance for the color"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "v", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t3"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "V", "Value Tolerance for the color"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_distance_matte(StructRNA *srna) @@ -799,11 +919,13 @@ static void def_cmp_distance_matte(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed."); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Falloff", "Color distances below this additional threshold are partially keyed."); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_color_spill(StructRNA *srna) @@ -821,6 +943,7 @@ static void def_cmp_color_spill(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, channel_items); RNA_def_property_ui_text(prop, "Channel", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); RNA_def_struct_sdna_from(srna, "NodeChroma", "storage"); @@ -828,6 +951,7 @@ static void def_cmp_color_spill(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 0.5f); RNA_def_property_ui_text(prop, "Amount", "How much the selected channel is affected by"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_chroma_matte(StructRNA *srna) @@ -840,26 +964,31 @@ static void def_cmp_chroma_matte(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 1.0f, 80.0f); RNA_def_property_ui_text(prop, "Acceptance", "Tolerance for a color to be considered a keying color"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "cutoff", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 30.0f); RNA_def_property_ui_text(prop, "Cutoff", "Tolerance below which colors will be considered as exact matches"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fsize"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Lift", "Alpha lift"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fstrength"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gain", "Alpha gain"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "shadow_adjust", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t3"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Shadow Adjust", "Adjusts the brightness of any shadows captured"); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: if(c->t2 > c->t1) @@ -883,10 +1012,12 @@ static void def_cmp_channel_matte(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, color_space_items); RNA_def_property_ui_text(prop, "Color Space", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: channel must be 1, 2 or 3 */ prop = RNA_def_property(srna, "channel", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); + RNA_def_property_update(prop, 0, "rna_Node_update"); RNA_def_property_ui_text(prop, "Channel", ""); RNA_def_struct_sdna_from(srna, "NodeChroma", "storage"); @@ -895,11 +1026,13 @@ static void def_cmp_channel_matte(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "low", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Low", "Values lower than this setting are 100% keyed"); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: if(c->t2 > c->t1) @@ -911,17 +1044,11 @@ static void def_cmp_flip(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem axis_items[] = { - {0, "X", 0, "X", ""}, - {1, "Y", 0, "Y", ""}, - {2, "XY", 0, "X & Y", ""}, - {0, NULL, 0, NULL, NULL} - }; - prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, axis_items); + RNA_def_property_enum_items(prop, node_flip_items); RNA_def_property_ui_text(prop, "Axis", ""); + RNA_def_property_update(prop, 0, "rna_Node_update_name"); } static void def_cmp_splitviewer(StructRNA *srna) @@ -938,12 +1065,14 @@ static void def_cmp_splitviewer(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "custom2"); RNA_def_property_enum_items(prop, axis_items); RNA_def_property_ui_text(prop, "Axis", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: percentage */ prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Factor", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_id_mask(StructRNA *srna) @@ -954,6 +1083,7 @@ static void def_cmp_id_mask(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Index", "Pass index number to convert to alpha"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_map_uv(StructRNA *srna) @@ -965,6 +1095,7 @@ static void def_cmp_map_uv(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Alpha", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_defocus(StructRNA *srna) @@ -988,50 +1119,60 @@ static void def_cmp_defocus(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "bktype"); RNA_def_property_enum_items(prop, bokeh_items); RNA_def_property_ui_text(prop, "Bokeh Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: angle in degrees */ prop = RNA_def_property(srna, "angle", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rotation"); RNA_def_property_range(prop, 0, 90); RNA_def_property_ui_text(prop, "Angle", "Bokeh shape rotation offset in degrees"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "gamma_correction", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gamco", 1); RNA_def_property_ui_text(prop, "Gamma Correction", "Enable gamma correction before and after main process"); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO */ prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fstop"); RNA_def_property_range(prop, 0.0f, 128.0f); RNA_def_property_ui_text(prop, "fStop", "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "max_blur", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "maxblur"); RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_ui_text(prop, "Max Blur", "blur limit, maximum CoC radius, 0=no limit"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bthresh"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Threshold", "CoC radius threshold, prevents background bleed on in-focus midground, 0=off"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "preview", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "preview", 1); RNA_def_property_ui_text(prop, "Preview", "Enable sampling mode, useful for preview when using low samplecounts"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "samples"); RNA_def_property_range(prop, 16, 256); RNA_def_property_ui_text(prop, "Samples", "Number of samples (16=grainy, higher=less noise)"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "use_zbuffer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "no_zbuf", 1); RNA_def_property_ui_text(prop, "Use Z-Buffer", "Disable when using an image as input instead of actual zbuffer (auto enabled if node not image based, eg. time node)"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "z_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "scale"); RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_text(prop, "Z-Scale", "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_luma_matte(StructRNA *srna) @@ -1044,11 +1185,13 @@ static void def_cmp_luma_matte(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "t1"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "low", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "t2"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Low", "Values lower than this setting are 100% keyed"); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: keep low less than high */ @@ -1061,10 +1204,12 @@ static void def_cmp_invert(StructRNA *srna) prop = RNA_def_property(srna, "rgb", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_CHAN_RGB); RNA_def_property_ui_text(prop, "RGB", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_CHAN_A); RNA_def_property_ui_text(prop, "Alpha", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_crop(StructRNA *srna) @@ -1074,6 +1219,7 @@ static void def_cmp_crop(StructRNA *srna) prop = RNA_def_property(srna, "crop_size", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); RNA_def_property_ui_text(prop, "Crop Image Size", "Whether to crop the size of the input image"); + RNA_def_property_update(prop, 0, "rna_Node_update"); RNA_def_struct_sdna_from(srna, "NodeTwoXYs", "storage"); @@ -1081,21 +1227,25 @@ static void def_cmp_crop(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "x1"); RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "X1", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "x2", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "x2"); RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "X2", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "y1", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "y1"); RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Y1", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "y2", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "y2"); RNA_def_property_range(prop, 0, 10000); RNA_def_property_ui_text(prop, "Y2", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_dblur(StructRNA *srna) @@ -1108,40 +1258,48 @@ static void def_cmp_dblur(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "iter"); RNA_def_property_range(prop, 1, 128); RNA_def_property_ui_text(prop, "Iterations", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "wrap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "wrap", 1); RNA_def_property_ui_text(prop, "Wrap", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "center_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "center_x"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Center X", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "center_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "center_y"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Center Y", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "distance"); RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Distance", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "angle"); RNA_def_property_range(prop, 0.0f, 360.0f); RNA_def_property_ui_text(prop, "Angle", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "spin", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spin"); RNA_def_property_range(prop, -360.0f, 360.0f); RNA_def_property_ui_text(prop, "Spin", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "zoom"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Zoom", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_bilateral_blur(StructRNA *srna) @@ -1154,16 +1312,19 @@ static void def_cmp_bilateral_blur(StructRNA *srna) RNA_def_property_int_sdna(prop, NULL, "iter"); RNA_def_property_range(prop, 1, 128); RNA_def_property_ui_text(prop, "Iterations", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "sigma_color", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sigma_color"); RNA_def_property_range(prop, 0.01f, 3.0f); RNA_def_property_ui_text(prop, "Color Sigma", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "sigma_space", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sigma_space"); RNA_def_property_range(prop, 0.01f, 30.0f); RNA_def_property_ui_text(prop, "Space Sigma", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_premul_key(StructRNA *srna) @@ -1180,6 +1341,7 @@ static void def_cmp_premul_key(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, type_items); RNA_def_property_ui_text(prop, "Mapping", "Conversion between premultiplied alpha and key alpha"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } @@ -1208,55 +1370,66 @@ static void def_cmp_glare(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, type_items); RNA_def_property_ui_text(prop, "Glare Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "quality", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "quality"); RNA_def_property_enum_items(prop, type_items); RNA_def_property_ui_text(prop, "Quality", "If not set to high quality, the effect will be applied to a low-res copy of the source image"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "iter"); RNA_def_property_range(prop, 2, 5); RNA_def_property_ui_text(prop, "Iterations", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "color_modulation", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "colmod"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Color Modulation", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "mix", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "mix"); RNA_def_property_range(prop, -1.0f, 1.0f); RNA_def_property_ui_text(prop, "Mix", "-1 is original image only, 0 is exact 50/50 mix, 1 is processed image only"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "threshold"); RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_text(prop, "Threshold", "The glare filter will only be applied to pixels brighter than this value"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "streaks", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "angle"); RNA_def_property_range(prop, 2, 16); RNA_def_property_ui_text(prop, "Streaks", "Total number of streaks"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "angle_offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "angle_ofs"); RNA_def_property_range(prop, 0.0f, 180.0f); RNA_def_property_ui_text(prop, "Angle Offset", "Streak angle offset in degrees"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "fade", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fade"); RNA_def_property_range(prop, 0.75f, 1.0f); RNA_def_property_ui_text(prop, "Fade", "Streak fade-out factor"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "rotate_45", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "angle", 1); RNA_def_property_ui_text(prop, "Rotate 45", "Simple star filter: add 45 degree rotation offset"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "size"); RNA_def_property_range(prop, 6, 9); RNA_def_property_ui_text(prop, "Size", "Glow/glare size (not actual size; relative to initial size of bright area of pixels)"); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO */ } @@ -1277,6 +1450,7 @@ static void def_cmp_tonemap(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, type_items); RNA_def_property_ui_text(prop, "Tonemap Type", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: if type==0 { */ @@ -1284,16 +1458,19 @@ static void def_cmp_tonemap(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "key"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Key", "The value the average luminance is mapped to"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "offset"); RNA_def_property_range(prop, 0.001f, 10.0f); RNA_def_property_ui_text(prop, "Offset", "Normally always 1, but can be used as an extra control to alter the brightness curve"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "gamma"); RNA_def_property_range(prop, 0.001f, 3.0f); RNA_def_property_ui_text(prop, "Gamma", "If not used, set to 1"); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: } else { */ @@ -1301,21 +1478,25 @@ static void def_cmp_tonemap(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "f"); RNA_def_property_range(prop, -8.0f, 8.0f); RNA_def_property_ui_text(prop, "Intensity", "If less than zero, darkens image; otherwise, makes it brighter"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "m"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Contrast", "Set to 0 to use estimate from input image"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "adaptation", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "a"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Adaptation", "If 0, global; if 1, based on pixel intensity"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "correction", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "c"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Color Correction", "If 0, same for all channels; if 1, each independent"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_cmp_lensdist(StructRNA *srna) @@ -1327,16 +1508,19 @@ static void def_cmp_lensdist(StructRNA *srna) prop = RNA_def_property(srna, "projector", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "proj", 1); RNA_def_property_ui_text(prop, "Projector", "Enable/disable projector mode. Effect is applied in horizontal direction only."); + RNA_def_property_update(prop, 0, "rna_Node_update"); /* TODO: if proj mode is off { */ prop = RNA_def_property(srna, "jitter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "jit", 1); RNA_def_property_ui_text(prop, "Jitter", "Enable/disable jittering; faster, but also noisier"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "fit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "fit", 1); RNA_def_property_ui_text(prop, "Fit", "For positive distortion factor only: scale image such that black areas are not visible"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } @@ -1352,6 +1536,7 @@ static void def_tex_output(StructRNA *srna) prop = RNA_def_property(srna, "output_name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Output Name", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_tex_image(StructRNA *srna) @@ -1362,6 +1547,7 @@ static void def_tex_image(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "storage"); RNA_def_property_struct_type(prop, "ImageUser"); RNA_def_property_ui_text(prop, "Settings", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); } static void def_tex_bricks(StructRNA *srna) @@ -1372,21 +1558,25 @@ static void def_tex_bricks(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "custom3"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Offset Amount", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "offset_frequency", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 2, 99); RNA_def_property_ui_text(prop, "Offset Frequency", "Offset every N rows"); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "squash", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "custom4"); RNA_def_property_range(prop, 0.0f, 99.0f); RNA_def_property_ui_text(prop, "Squash Amount", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "squash_frequency", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); RNA_def_property_range(prop, 2, 99); RNA_def_property_ui_text(prop, "Squash Frequency", "Squash every N rows"); + RNA_def_property_update(prop, 0, "rna_Node_update"); } /* -------------------------------------------------------------------------- */ diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index c1585a71ac1..4c32f86e501 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -95,6 +95,7 @@ char *ED_info_stats_string(struct Scene *scene){return NULL;} void ED_area_tag_redraw(struct ScrArea *sa){} void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op){} void ED_node_texture_default(struct Tex *tx){} +void ED_node_changed_update(struct bContext *C, struct bNode *node); int text_file_modified(struct Text *text){return 0;} void ED_node_shader_default(struct Material *ma){} void ED_screen_animation_timer_update(struct bContext *C, int redraws){} -- cgit v1.2.3 From f8abfce7ce022e4a7ac53a68477f56e4b740e91e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 19:27:08 +0000 Subject: Image Panels * The image panels in the image editor and texture buttons should be more complete now, with working new/open, refreshes, and using the layout engine. * Paint panels in image editor are now consistent with the ones in the 3d view toolbar. * Curves panel also uses layout engine, and doesn't look squashed anymore. --- release/ui/space_image.py | 109 +++ source/blender/blenkernel/intern/image.c | 17 +- source/blender/blenkernel/intern/paint.c | 27 +- source/blender/editors/include/ED_image.h | 3 - .../editors/interface/interface_templates.c | 13 - source/blender/editors/space_image/image_buttons.c | 778 ++++++--------------- source/blender/editors/space_image/image_ops.c | 21 +- source/blender/editors/uvedit/uvedit_ops.c | 2 +- source/blender/makesrna/intern/rna_color.c | 6 +- source/blender/makesrna/intern/rna_image.c | 116 ++- source/blender/makesrna/intern/rna_space.c | 11 +- source/blender/makesrna/intern/rna_texture.c | 14 +- source/blender/makesrna/intern/rna_ui_api.c | 14 +- 13 files changed, 510 insertions(+), 621 deletions(-) diff --git a/release/ui/space_image.py b/release/ui/space_image.py index 0d0fd86ef8c..02ebd864b8e 100644 --- a/release/ui/space_image.py +++ b/release/ui/space_image.py @@ -277,6 +277,24 @@ class IMAGE_HT_header(bpy.types.Header): if show_uvedit or sima.image_painting: layout.itemR(sima, "update_automatically", text="") +class IMAGE_PT_image_properties(bpy.types.Panel): + __space_type__ = 'IMAGE_EDITOR' + __region_type__ = 'UI' + __label__ = "Image" + + def poll(self, context): + sima = context.space_data + return (sima.image) + + def draw(self, context): + layout = self.layout + + sima = context.space_data + ima = sima.image + iuser = sima.image_user + + layout.template_image(sima, "image", iuser, compact=True) + class IMAGE_PT_game_properties(bpy.types.Panel): __space_type__ = 'IMAGE_EDITOR' __region_type__ = 'UI' @@ -368,6 +386,92 @@ class IMAGE_PT_view_properties(bpy.types.Panel): #col.itemR(uvedit, "draw_edges") #col.itemR(uvedit, "draw_faces") +class IMAGE_PT_paint(bpy.types.Panel): + __space_type__ = 'IMAGE_EDITOR' + __region_type__ = 'UI' + __label__ = "Paint" + + def poll(self, context): + sima = context.space_data + return sima.show_paint + + def draw(self, context): + layout = self.layout + + settings = context.tool_settings.image_paint + brush = settings.brush + + col = layout.split().column() + row = col.row() + row.template_list(settings, "brushes", settings, "active_brush_index", rows=2) + + col.template_ID(settings, "brush", new="brush.add") + + row = layout.row(align=True) + row.item_enumR(settings, "tool", 'DRAW') + row.item_enumR(settings, "tool", 'SOFTEN') + row.item_enumR(settings, "tool", 'CLONE') + row.item_enumR(settings, "tool", 'SMEAR') + + col = layout.column() + col.itemR(brush, "color", text="") + + row = col.row(align=True) + row.itemR(brush, "size", slider=True) + row.itemR(brush, "size_pressure", toggle=True, text="") + + row = col.row(align=True) + row.itemR(brush, "strength", slider=True) + row.itemR(brush, "strength_pressure", toggle=True, text="") + + col.itemR(brush, "blend", text="Blend") + +class IMAGE_PT_paint_stroke(bpy.types.Panel): + __space_type__ = 'IMAGE_EDITOR' + __region_type__ = 'UI' + __label__ = "Paint Stroke" + __default_closed__ = True + + def poll(self, context): + sima = context.space_data + return sima.show_paint + + def draw(self, context): + layout = self.layout + + settings = context.tool_settings.image_paint + brush = settings.brush + + layout.itemR(brush, "airbrush") + col = layout.column() + col.active = brush.airbrush + col.itemR(brush, "rate", slider=True) + + layout.itemR(brush, "space") + row = layout.row(align=True) + row.active = brush.space + row.itemR(brush, "spacing", text="Distance", slider=True) + row.itemR(brush, "spacing_pressure", toggle=True, text="") + +class IMAGE_PT_paint_curve(bpy.types.Panel): + __space_type__ = 'IMAGE_EDITOR' + __region_type__ = 'UI' + __label__ = "Paint Curve" + __default_closed__ = True + + def poll(self, context): + sima = context.space_data + return sima.show_paint + + def draw(self, context): + layout = self.layout + + settings = context.tool_settings.image_paint + brush = settings.brush + + layout.template_curve_mapping(brush, "curve") + layout.item_menu_enumO("brush.curve_preset", property="shape") + bpy.types.register(IMAGE_MT_view) bpy.types.register(IMAGE_MT_select) bpy.types.register(IMAGE_MT_image) @@ -377,5 +481,10 @@ bpy.types.register(IMAGE_MT_uvs_mirror) bpy.types.register(IMAGE_MT_uvs_weldalign) bpy.types.register(IMAGE_MT_uvs) bpy.types.register(IMAGE_HT_header) +bpy.types.register(IMAGE_PT_image_properties) +bpy.types.register(IMAGE_PT_paint) +bpy.types.register(IMAGE_PT_paint_stroke) +bpy.types.register(IMAGE_PT_paint_curve) bpy.types.register(IMAGE_PT_game_properties) bpy.types.register(IMAGE_PT_view_properties) + diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index cdb175ed661..e955f10f3e3 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -277,7 +277,7 @@ static Image *image_alloc(const char *name, short source, short type) ima->xrep= ima->yrep= 1; ima->aspx= ima->aspy= 1.0; - ima->gen_x= 256; ima->gen_y= 256; + ima->gen_x= 1024; ima->gen_y= 1024; ima->gen_type= 1; /* no defines yet? */ ima->source= source; @@ -1472,9 +1472,11 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) iuser->ok= 1; break; case IMA_SIGNAL_SRC_CHANGE: - if(ima->type==IMA_TYPE_MULTILAYER) - image_free_buffers(ima); - else if(ima->source==IMA_SRC_GENERATED) { + if(ima->type == IMA_TYPE_UV_TEST) + if(ima->source != IMA_SRC_GENERATED) + ima->type= IMA_TYPE_IMAGE; + + if(ima->source==IMA_SRC_GENERATED) { if(ima->gen_x==0 || ima->gen_y==0) { ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); if(ibuf) { @@ -1483,6 +1485,9 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) } } } + + image_free_buffers(ima); + ima->ok= 1; if(iuser) iuser->ok= 1; @@ -2090,8 +2095,8 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) else if(ima->source == IMA_SRC_GENERATED) { /* generated is: ibuf is allocated dynamically */ /* UV testgrid or black or solid etc */ - if(ima->gen_x==0) ima->gen_x= 256; - if(ima->gen_y==0) ima->gen_y= 256; + if(ima->gen_x==0) ima->gen_x= 1024; + if(ima->gen_y==0) ima->gen_y= 1024; ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 0, ima->gen_type, color); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); ima->ok= IMA_OK_LOADED; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 7c5b2b82b4b..f17d2fbdcac 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -46,19 +46,24 @@ const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255}; Paint *paint_get_active(Scene *sce) { - if(sce && sce->basact && sce->basact->object) { + if(sce) { ToolSettings *ts = sce->toolsettings; - - switch(sce->basact->object->mode) { - case OB_MODE_SCULPT: - return &ts->sculpt->paint; - case OB_MODE_VERTEX_PAINT: - return &ts->vpaint->paint; - case OB_MODE_WEIGHT_PAINT: - return &ts->wpaint->paint; - case OB_MODE_TEXTURE_PAINT: - return &ts->imapaint.paint; + + if(sce->basact && sce->basact->object) { + switch(sce->basact->object->mode) { + case OB_MODE_SCULPT: + return &ts->sculpt->paint; + case OB_MODE_VERTEX_PAINT: + return &ts->vpaint->paint; + case OB_MODE_WEIGHT_PAINT: + return &ts->wpaint->paint; + case OB_MODE_TEXTURE_PAINT: + return &ts->imapaint.paint; + } } + + /* default to image paint */ + return &ts->imapaint.paint; } return NULL; diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index 566105109b2..a4263f7bd77 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -53,9 +53,6 @@ int ED_space_image_show_paint(struct SpaceImage *sima); int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit); int ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit); -void ED_image_uiblock_panel(const struct bContext *C, struct uiBlock *block, struct Image **ima_pp, - struct ImageUser *iuser, short redraw, short imagechanged); - /* image_render.c, export for screen_ops.c, render operator */ void ED_space_image_output(struct bContext *C); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 1c7e757fbb2..66873917e8a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2125,17 +2125,4 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); } -/************************* Image Template **************************/ - -#include "ED_image.h" - -void uiTemplateTextureImage(uiLayout *layout, bContext *C, Tex *tex) -{ - uiBlock *block; - - if(tex) { - block= uiLayoutFreeBlock(layout); - ED_image_uiblock_panel(C, block, &tex->ima, &tex->iuser, 0, 0); - } -} diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 456e802194e..f3607ed7276 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -100,8 +100,6 @@ #define B_FACESEL_PAINT_TEST 11 #define B_SIMA_RECORD 12 #define B_SIMA_PLAY 13 -#define B_SIMARANGE 14 -#define B_SIMACURVES 15 #define B_SIMANOTHING 16 #define B_SIMABRUSHCHANGE 17 @@ -116,10 +114,8 @@ #define B_SIMACLONEDELETE 26 /* XXX */ -static int okee() {return 0;} static int simaFaceDraw_Check() {return 0;} static int simaUVSel_Check() {return 0;} -static int is_uv_tface_editing_allowed_silent() {return 0;} /* XXX */ /* proto */ @@ -135,13 +131,6 @@ static void do_image_panel_events(bContext *C, void *arg, int event) switch(event) { case B_REDR: break; - case B_SIMACURVES: - curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); - break; - case B_SIMARANGE: - curvemapping_set_black_white(sima->cumap, NULL, NULL); - curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); - break; case B_TRANS_IMAGE: image_editvertex_buts(C, NULL); break; @@ -149,12 +138,11 @@ static void do_image_panel_events(bContext *C, void *arg, int event) image_editcursor_buts(C, &ar->v2d, NULL); break; } + /* all events now */ WM_event_add_notifier(C, NC_IMAGE, sima->image); } - - static void image_info(Image *ima, ImBuf *ibuf, char *str) { int ofs= 0; @@ -168,12 +156,12 @@ static void image_info(Image *ima, ImBuf *ibuf, char *str) } if(ima->source==IMA_SRC_MOVIE) { - ofs= sprintf(str, "Movie "); + ofs= sprintf(str, "Movie"); if(ima->anim) ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim)); } else - ofs= sprintf(str, "Image "); + ofs= sprintf(str, "Image"); ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y); @@ -246,10 +234,6 @@ static void image_editvertex_buts(const bContext *C, uiBlock *block) EditFace *efa; MTFace *tf; - if(obedit==NULL || obedit->type!=OB_MESH) return; - - if( is_uv_tface_editing_allowed_silent()==0 ) return; - image_transform_but_attr(sima, &imx, &imy, &step, &digits); em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -354,8 +338,6 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block int imx= 256, imy= 256; int step, digits; - if( is_uv_tface_editing_allowed_silent()==0 ) return; - image_transform_but_attr(sima, &imx, &imy, &step, &digits); if(block) { // do the buttons @@ -388,59 +370,6 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block #if 0 static void image_panel_view_properties(const bContext *C, Panel *pa) { - SpaceImage *sima= CTX_wm_space_image(C); - ARegion *ar= CTX_wm_region(C); - Object *obedit= CTX_data_edit_object(C); - uiBlock *block; - - block= uiLayoutFreeBlock(pa->layout); - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - uiDefButBitI(block, TOG, SI_DRAW_TILE, B_REDR, "Repeat Image", 10,160,140,19, &sima->flag, 0, 0, 0, 0, "Repeat/Tile the image display"); - uiDefButBitI(block, TOG, SI_COORDFLOATS, B_REDR, "Normalized Coords", 165,160,145,19, &sima->flag, 0, 0, 0, 0, "Display coords from 0.0 to 1.0 rather then in pixels"); - - if (sima->image) { - uiDefBut(block, LABEL, B_NOP, "Image Display:", 10,140,140,19, 0, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_REDR, "AspX:", 10,120,140,19, &sima->image->aspx, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect renderingm 0 disables."); - uiDefButF(block, NUM, B_REDR, "AspY:", 10,100,140,19, &sima->image->aspy, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect rendering 0 disables."); - uiBlockEndAlign(block); - } - - if (obedit && obedit->type==OB_MESH) { - Mesh *me= obedit->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - - if(EM_texFaceCheck(em)) { - uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 80,120,19, 0, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButC(block, ROW, B_REDR, "Outline", 10,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "Dash", 68, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "Black", 126, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "White", 184,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype"); - - uiBlockEndAlign(block); - uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,60,60,19, &sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view"); - - - uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades in the 3d view and UV editor"); - uiDefButBitI(block, TOG, ME_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor"); - - uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers"); - uiDefButBitI(block, TOG, SI_DRAW_OTHER, B_REDR, "Other Objs", 230, 30, 80, 19, &sima->flag, 0, 0, 0, 0, "Also draw all 3d view selected mesh objects that use this image"); - - uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)"); - if (sima->flag & SI_DRAW_STRETCH) { - uiBlockBeginAlign(block); - uiDefButC(block, ROW, B_REDR, "Area", 120,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_AREA, 0, 0, "Area distortion between UV's and 3D coords"); - uiDefButC(block, ROW, B_REDR, "Angle", 180,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_ANGLE, 0, 0, "Angle distortion between UV's and 3D coords"); - uiBlockEndAlign(block); - } - } - - BKE_mesh_end_editmesh(me, em); - } - image_editcursor_buts(C, &ar->v2d, block); } #endif @@ -565,104 +494,33 @@ void brush_buttons(const bContext *C, uiBlock *block, short fromsima, #endif } -static int image_panel_paint_poll(const bContext *C, PanelType *pt) -{ - SpaceImage *sima= CTX_wm_space_image(C); - - return (sima->image && (sima->flag & SI_DRAWTOOL)); -} - -static void image_panel_paintcolor(const bContext *C, Panel *pa) -{ - SpaceImage *sima= CTX_wm_space_image(C); - ToolSettings *settings= CTX_data_tool_settings(C); - Brush *brush= paint_brush(&settings->imapaint.paint); - uiBlock *block; - static float hsv[3], old[3]; // used as temp mem for picker - static char hexcol[128]; - - if(!sima->image || (sima->flag & SI_DRAWTOOL)==0) - return; - - block= uiLayoutFreeBlock(pa->layout); - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - if(brush) - uiBlockPickerButtons(block, brush->rgb, hsv, old, hexcol, 'f', B_REDR); -} - -static void image_panel_paint(const bContext *C, Panel *pa) -{ - SpaceImage *sima= CTX_wm_space_image(C); - uiBlock *block; - - if(!sima->image || (sima->flag & SI_DRAWTOOL)==0) - return; - - block= uiLayoutFreeBlock(pa->layout); - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - brush_buttons(C, block, 1, B_SIMANOTHING, B_SIMABRUSHCHANGE, B_SIMABRUSHBROWSE, B_SIMABRUSHLOCAL, B_SIMABRUSHDELETE, B_KEEPDATA, B_SIMABTEXBROWSE, B_SIMABTEXDELETE); -} - -static void image_panel_curves_reset(bContext *C, void *cumap_v, void *ibuf_v) +static int image_panel_poll(const bContext *C, PanelType *pt) { SpaceImage *sima= CTX_wm_space_image(C); - CurveMapping *cumap = cumap_v; - int a; - - for(a=0; acm+a, &cumap->clipr); - - cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f; - cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f; - curvemapping_set_black_white(cumap, NULL, NULL); - - curvemapping_changed(cumap, 0); - curvemapping_do_ibuf(cumap, ibuf_v); + ImBuf *ibuf= ED_space_image_buffer(sima); - WM_event_add_notifier(C, NC_IMAGE, sima->image); + return (ibuf != NULL); } - static void image_panel_curves(const bContext *C, Panel *pa) { + bScreen *sc= CTX_wm_screen(C); SpaceImage *sima= CTX_wm_space_image(C); ImBuf *ibuf; - uiBlock *block; - uiBut *bt; + PointerRNA simaptr; + int levels; - /* and we check for spare */ ibuf= ED_space_image_buffer(sima); - block= uiLayoutFreeBlock(pa->layout); - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - if (ibuf) { - rctf rect; - + if(ibuf) { if(sima->cumap==NULL) sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); - - rect.xmin= 110; rect.xmax= 310; - rect.ymin= 10; rect.ymax= 200; - curvemap_buttons(block, sima->cumap, 'c', B_SIMACURVES, B_REDR, &rect); - - /* curvemap min/max only works for RGBA */ - if(ibuf->channels==4) { - bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset", 10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves"); - uiButSetFunc(bt, image_panel_curves_reset, sima->cumap, ibuf); - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level"); - uiDefButF(block, NUM, B_SIMARANGE, "Min G:", 10, 100, 90, 19, sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level"); - uiDefButF(block, NUM, B_SIMARANGE, "Min B:", 10, 80, 90, 19, sima->cumap->black+2, -1000.0f, 1000.0f, 10, 2, "Black level"); - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_SIMARANGE, "Max R:", 10, 50, 90, 19, sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level"); - uiDefButF(block, NUM, B_SIMARANGE, "Max G:", 10, 30, 90, 19, sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level"); - uiDefButF(block, NUM, B_SIMARANGE, "Max B:", 10, 10, 90, 19, sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level"); - } + + /* curvemap black/white levels only works for RGBA */ + levels= (ibuf->channels==4); + + RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &simaptr); + uiTemplateCurveMapping(pa->layout, &simaptr, "curves", 'c', levels); } } @@ -799,81 +657,11 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVI uiBlockSetDrawExtraFunc(block, preview_cb); } - -static void image_panel_gpencil(short cntrl) // IMAGE_HANDLER_GREASEPENCIL -{ - uiBlock *block; - SpaceImage *sima; - - sima= curarea->spacedata.first; - - block= uiBeginBlock(C, ar, "image_panel_gpencil", UI_EMBOSS); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(IMAGE_HANDLER_GREASEPENCIL); // for close and esc - if (uiNewPanel(C, ar, block, "Grease Pencil", "SpaceImage", 100, 30, 318, 204)==0) return; - - /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */ - if (sima->flag & SI_DISPGP) { - if (sima->gpd == NULL) - gpencil_data_setactive(curarea, gpencil_data_addnew()); - } - - if (sima->flag & SI_DISPGP) { - bGPdata *gpd= sima->gpd; - short newheight; - - /* this is a variable height panel, newpanel doesnt force new size on existing panels */ - /* so first we make it default height */ - uiNewPanelHeight(block, 204); - - /* draw button for showing gpencil settings and drawings */ - uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor (draw using Shift-LMB)"); - - /* extend the panel if the contents won't fit */ - newheight= draw_gpencil_panel(block, gpd, curarea); - uiNewPanelHeight(block, newheight); - } - else { - uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor"); - uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); - } -} #endif /* ********************* callbacks for standard image buttons *************** */ -/* called from fileselect or button */ -static void load_image_cb(bContext *C, char *str, void *ima_pp_v, void *iuser_v) -{ - Image **ima_pp= (Image **)ima_pp_v; - Image *ima= NULL; - - ima= BKE_add_image_file(str, 0); - if(ima) { - if(*ima_pp) { - (*ima_pp)->id.us--; - } - *ima_pp= ima; - - BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD); - WM_event_add_notifier(C, NC_IMAGE, ima); - - /* button event gets lost when it goes via filewindow */ -// if(G.buts && G.buts->lockpoin) { -// Tex *tex= G.buts->lockpoin; -// if(GS(tex->id.name)==ID_TE) { -// BIF_preview_changed(ID_TE); -// allqueue(REDRAWBUTSSHADING, 0); -// allqueue(REDRAWVIEW3D, 0); -// allqueue(REDRAWOOPS, 0); -// } -// } - } - - ED_undo_push(C, "Load image"); -} - static char *layer_menu(RenderResult *rr, short *curlay) { RenderLayer *rl; @@ -937,92 +725,6 @@ static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v) } } -static void image_src_change_cb(bContext *C, void *ima_v, void *iuser_v) -{ - BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE); -} - -/* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */ -static void image_browse_cb1(bContext *C, void *ima_pp_v, void *iuser_v) -{ - Image **ima_pp= (Image **)ima_pp_v; - ImageUser *iuser= iuser_v; - - if(ima_pp) { - Image *ima= *ima_pp; - - if(iuser->menunr== -2) { - // XXX activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser); - } - else if (iuser->menunr>0) { - Image *newima= (Image*) BLI_findlink(&CTX_data_main(C)->image, iuser->menunr-1); - - if (newima && newima!=ima) { - *ima_pp= newima; - id_us_plus(&newima->id); - if(ima) ima->id.us--; - - BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE); - - ED_undo_push(C, "Browse image"); - } - } - } -} - -static void image_browse_cb(bContext *C, void *ima_pp_v, void *iuser_v) -{ - image_browse_cb1(C, ima_pp_v, iuser_v); -} - -static void image_reload_cb(bContext *C, void *ima_v, void *iuser_v) -{ - if(ima_v) { - BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD); - } -} - -static void image_field_test(bContext *C, void *ima_v, void *iuser_v) -{ - Image *ima= ima_v; - - if(ima) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); - if(ibuf) { - short nr= 0; - if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1; - if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1; - if(nr) { - BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE); - } - } - } -} - -static void image_unlink_cb(bContext *C, void *ima_pp_v, void *unused) -{ - Image **ima_pp= (Image **)ima_pp_v; - - if(ima_pp && *ima_pp) { - Image *ima= *ima_pp; - /* (for time being, texturefaces are no users, conflict in design...) */ - if(ima->id.us>1) - ima->id.us--; - *ima_pp= NULL; - } -} - -static void image_load_fs_cb(bContext *C, void *ima_pp_v, void *iuser_v) -{ - ScrArea *sa= CTX_wm_area(C); -// Image **ima_pp= (Image **)ima_pp_v; - - if(sa->spacetype==SPACE_IMAGE) - WM_operator_name_call(C, "IMAGE_OT_open", WM_OP_INVOKE_REGION_WIN, NULL); - else - printf("not supported yet\n"); -} - /* 5 layer button callbacks... */ static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) { @@ -1077,6 +779,7 @@ static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) } } +#if 0 static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v) { if(ima_v) { @@ -1106,282 +809,270 @@ static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v) } } } +#endif -static void image_load_cb(bContext *C, void *ima_pp_v, void *iuser_v) -{ - if(ima_pp_v) { - Image *ima= *((Image **)ima_pp_v); - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); - char str[FILE_MAX]; - - /* name in ima has been changed by button! */ - BLI_strncpy(str, ima->name, FILE_MAX); - if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX); - - load_image_cb(C, str, ima_pp_v, iuser_v); - } -} - +#if 0 static void image_freecache_cb(bContext *C, void *ima_v, void *unused) { Scene *scene= CTX_data_scene(C); BKE_image_free_anim_ibufs(ima_v, scene->r.cfra); WM_event_add_notifier(C, NC_IMAGE, ima_v); } +#endif -static void image_generated_change_cb(bContext *C, void *ima_v, void *iuser_v) -{ - BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE); -} - +#if 0 static void image_user_change(bContext *C, void *iuser_v, void *unused) { Scene *scene= CTX_data_scene(C); BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0); } +#endif -static void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w) +static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w) { + uiBlock *block= uiLayoutGetBlock(layout); uiBut *but; RenderLayer *rl= NULL; int wmenu1, wmenu2; char *strp; + uiLayoutRow(layout, 1); + /* layer menu is 1/3 larger than pass */ wmenu1= (3*w)/5; wmenu2= (2*w)/5; /* menu buts */ strp= layer_menu(rr, &iuser->layer); - but= uiDefButS(block, MENU, event, strp, x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer"); + but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer"); uiButSetFunc(but, image_multi_cb, rr, iuser); MEM_freeN(strp); rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */ strp= pass_menu(rl, &iuser->pass); - but= uiDefButS(block, MENU, event, strp, x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass"); + but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass"); uiButSetFunc(but, image_multi_cb, rr, iuser); MEM_freeN(strp); } -static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged) +static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser) { + uiBlock *block= uiLayoutGetBlock(layout); + uiLayout *row; uiBut *but; + row= uiLayoutRow(layout, 1); + if(rr==NULL || iuser==NULL) return; if(rr->layers.first==NULL) { - uiDefBut(block, LABEL, 0, "No Layers in Render Result,", 10, 107, 300, 20, NULL, 1, 0, 0, 0, ""); + uiItemL(row, "No Layers in Render Result.", 0); return; } - - uiBlockBeginAlign(block); /* decrease, increase arrows */ - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer"); + but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Layer"); uiButSetFunc(but, image_multi_declay_cb, rr, iuser); - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer"); + but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer"); uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); - uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230); + uiblock_layer_pass_buttons(row, rr, iuser, 230); /* decrease, increase arrows */ - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); + but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); uiButSetFunc(but, image_multi_decpass_cb, rr, iuser); - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass"); + but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Pass"); uiButSetFunc(but, image_multi_incpass_cb, rr, iuser); uiBlockEndAlign(block); - } // XXX HACK! -static int packdummy=0; +// static int packdummy=0; + +typedef struct RNAUpdateCb { + PointerRNA ptr; + PropertyRNA *prop; + ImageUser *iuser; +} RNAUpdateCb; + +static void rna_update_cb(bContext *C, void *arg_cb, void *arg_unused) +{ + RNAUpdateCb *cb= (RNAUpdateCb*)arg_cb; + + /* ideally this would be done by RNA itself, but there we have + no image user available, so we just update this flag here */ + cb->iuser->ok= 1; -/* The general Image panel with the loadsa callbacks! */ -void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, ImageUser *iuser, - short redraw, short imagechanged) + /* we call update here on the pointer property, this way the + owner of the image pointer can still define it's own update + and notifier */ + RNA_property_update(C, &cb->ptr, cb->prop); +} + +void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *userptr, int compact) { + PropertyRNA *prop; + PointerRNA imaptr; + RNAUpdateCb *cb; + Image *ima; + ImageUser *iuser; + ImBuf *ibuf; Scene *scene= CTX_data_scene(C); - SpaceImage *sima= CTX_wm_space_image(C); - Image *ima= *ima_pp; + uiLayout *row, *split, *col; + uiBlock *block; uiBut *but; - char str[128], *strp; + char str[128]; + + if(!ptr->data) + return; - /* different stuff when we show viewer */ - if(ima && ima->source==IMA_SRC_VIEWER) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser); - - image_info(ima, ibuf, str); - uiDefBut(block, LABEL, 0, ima->id.name+2, 10, 180, 300, 20, NULL, 1, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, str, 10, 160, 300, 20, NULL, 1, 0, 0, 0, ""); - - if(ima->type==IMA_TYPE_COMPOSITE) { - iuser= ntree_get_active_iuser(scene->nodetree); - if(iuser) { - uiBlockBeginAlign(block); - uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, ""); - uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, ""); - but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, ""); - uiButSetFunc(but, image_freecache_cb, ima, NULL); - - if(iuser->frames) - sprintf(str, "(%d) Frames:", iuser->framenr); - else strcpy(str, "Frames:"); - uiBlockBeginAlign(block); - uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); - } - } - else if(ima->type==IMA_TYPE_R_RESULT) { - /* browse layer/passes */ - uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(scene->id.name)), iuser, imagechanged); - } + prop= RNA_struct_find_property(ptr, propname); + if(!prop) { + printf("uiTemplateImage: property not found: %s\n", propname); return; } - - /* the main ima source types */ + + block= uiLayoutGetBlock(layout); + + imaptr= RNA_property_pointer_get(ptr, prop); + ima= imaptr.data; + iuser= userptr->data; + + cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); + cb->ptr= *ptr; + cb->prop= prop; + cb->iuser= iuser; + + if(!compact) + uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); + + // XXX missing: reload, pack + if(ima) { -// XXX uiSetButLock(ima->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); - uiBlockBeginAlign(block); - uiBlockSetFunc(block, image_src_change_cb, ima, iuser); - uiDefButS(block, ROW, imagechanged, "Still", 0, 180, 105, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file"); - uiDefButS(block, ROW, imagechanged, "Movie", 105, 180, 105, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file"); - uiDefButS(block, ROW, imagechanged, "Sequence", 210, 180, 105, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence"); - uiDefButS(block, ROW, imagechanged, "Generated", 315, 180, 105, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image"); - uiBlockSetFunc(block, NULL, NULL, NULL); - } - else - uiDefBut(block, LABEL, 0, " ", 0, 180, 440, 20, 0, 0, 0, 0, 0, ""); /* for align in panel */ - - /* Browse */ - IMAnames_to_pupstring(&strp, NULL, NULL, &(CTX_data_main(C)->image), NULL, &iuser->menunr); - - uiBlockBeginAlign(block); - but= uiDefButS(block, MENU, imagechanged, strp, 0,155,40,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie"); - uiButSetFunc(but, image_browse_cb, ima_pp, iuser); - - MEM_freeN(strp); - - /* name + options, or only load */ - if(ima) { - int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok); - - but= uiDefBut(block, TEX, B_IDNAME, "IM:", 40, 155, 220, 20, ima->id.name+2, 0.0, 21.0, 0, 0, "Current Image Datablock name."); - uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL); - but= uiDefBut(block, BUT, imagechanged, "Reload", 260, 155, 70, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie"); - uiButSetFunc(but, image_reload_cb, ima, iuser); - - but= uiDefIconBut(block, BUT, imagechanged, ICON_X, 330, 155, 40, 20, 0, 0, 0, 0, 0, "Unlink Image block"); - uiButSetFunc(but, image_unlink_cb, ima_pp, NULL); - sprintf(str, "%d", ima->id.us); - uiDefBut(block, BUT, B_NOP, str, 370, 155, 40, 20, 0, 0, 0, 0, 0, "Only displays number of users of Image block"); - uiBlockEndAlign(block); - - uiBlockBeginAlign(block); - but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL, 0, 130, 40, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image"); - uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser); - but= uiDefBut(block, TEX, imagechanged, "", 40,130, 340+(drawpack?0:20),20, ima->name, 0.0, 239.0, 0, 0, "Image/Movie file name, change to load new"); - uiButSetFunc(but, image_load_cb, ima_pp, iuser); - uiBlockEndAlign(block); - - if(drawpack) { - if (ima->packedfile) packdummy = 1; - else packdummy = 0; - but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 380, 130, 40, 20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image"); - uiButSetFunc(but, image_pack_cb, ima, iuser); - } - - } - else { - but= uiDefBut(block, BUT, imagechanged, "Load", 33, 155, 200,20, NULL, 0, 0, 0, 0, "Load new Image of Movie"); - uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser); - } - uiBlockEndAlign(block); - - if(ima) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser); - - /* check for re-render, only buttons */ - if(imagechanged==B_IMAGECHANGED) { - if(iuser->flag & IMA_ANIM_REFRESHED) { - iuser->flag &= ~IMA_ANIM_REFRESHED; - WM_event_add_notifier(C, NC_IMAGE, ima); - } - } - - /* multilayer? */ - if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { - uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged); - } - else { - image_info(ima, ibuf, str); - uiDefBut(block, LABEL, 0, str, 10, 112, 300, 20, NULL, 1, 0, 0, 0, ""); - } - - /* exception, let's do because we only use this panel 3 times in blender... but not real good code! */ - if( (paint_facesel_test(CTX_data_active_object(C))) && sima && &sima->iuser==iuser) - return; - /* left side default per-image options, right half the additional options */ - - /* fields */ - - but= uiDefButBitS(block, OPTION, IMA_FIELDS, imagechanged, "Fields", 0, 80, 200, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); - uiButSetFunc(but, image_field_test, ima, iuser); - uiDefButBitS(block, OPTION, IMA_STD_FIELD, B_NOP, "Odd", 0, 55, 200, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); + uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL); + + if(ima->source == IMA_SRC_VIEWER) { + ibuf= BKE_image_get_ibuf(ima, iuser); + image_info(ima, ibuf, str); + + uiItemL(layout, ima->id.name+2, 0); + uiItemL(layout, str, 0); + + if(ima->type==IMA_TYPE_COMPOSITE) { + // XXX not working yet +#if 0 + iuser= ntree_get_active_iuser(scene->nodetree); + if(iuser) { + uiBlockBeginAlign(block); + uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, ""); + uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, ""); + but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, ""); + uiButSetFunc(but, image_freecache_cb, ima, NULL); + + if(iuser->frames) + sprintf(str, "(%d) Frames:", iuser->framenr); + else strcpy(str, "Frames:"); + uiBlockBeginAlign(block); + uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); + uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); + } +#endif + } + else if(ima->type==IMA_TYPE_R_RESULT) { + /* browse layer/passes */ + uiblock_layer_pass_arrow_buttons(layout, RE_GetResult(RE_GetRender(scene->id.name)), iuser); + } + } + else { + row= uiLayoutRow(layout, 0); + uiItemR(row, NULL, 0, &imaptr, "source", (compact)? 0: UI_ITEM_R_EXPAND); + + if(ima->source != IMA_SRC_GENERATED) { + row= uiLayoutRow(layout, 0); + uiItemR(row, "", 0, &imaptr, "filename", 0); + //uiItemO(row, "Reload", 0, "image.reload"); + } + + // XXX what was this for? +#if 0 + /* check for re-render, only buttons */ + if(imagechanged==B_IMAGECHANGED) { + if(iuser->flag & IMA_ANIM_REFRESHED) { + iuser->flag &= ~IMA_ANIM_REFRESHED; + WM_event_add_notifier(C, NC_IMAGE, ima); + } + } +#endif + + /* multilayer? */ + if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { + uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser); + } + else if(ima->source != IMA_SRC_GENERATED) { + ibuf= BKE_image_get_ibuf(ima, iuser); + image_info(ima, ibuf, str); + uiItemL(layout, str, 0); + } - - uiBlockSetFunc(block, image_reload_cb, ima, iuser); - uiDefButBitS(block, OPTION, IMA_ANTIALI, B_NOP, "Anti-Aliasing", 0, 5, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); - uiDefButBitS(block, OPTION, IMA_DO_PREMUL, imagechanged, "Premultiply", 0, -20, 200, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); - - - if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - sprintf(str, "(%d) Frames:", iuser->framenr); - - //uiBlockBeginAlign(block); - uiBlockSetFunc(block, image_user_change, iuser, NULL); - - if(ima->anim) { - uiBlockBeginAlign(block); - uiDefButI(block, NUM, imagechanged, str, 220, 80, 160, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - but= uiDefBut(block, BUT, redraw, "<", 380, 80, 40, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button"); - uiButSetFunc(but, set_frames_cb, ima, iuser); - uiBlockEndAlign(block); - } - else - uiDefButI(block, NUM, imagechanged, str, 220, 80, 200, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - - uiDefButI(block, NUM, imagechanged, "Start Frame:", 220, 55, 200, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); - uiDefButI(block, NUM, imagechanged, "Offset:", 220, 30, 200, 20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); - uiDefButS(block, NUM, imagechanged, "Fields:", 0, 30, 200, 20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)"); - - uiDefButBitS(block, OPTION, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 220, 5, 200, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); - - uiDefButS(block, OPTION, imagechanged, "Cyclic", 220, -20, 200, 20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); - - uiBlockSetFunc(block, NULL, iuser, NULL); - } - else if(ima->source==IMA_SRC_GENERATED) { - - uiDefBut(block, LABEL, 0, "Size:", 220, 80, 200, 20, 0, 0, 0, 0, 0, ""); - - uiBlockBeginAlign(block); - uiBlockSetFunc(block, image_generated_change_cb, ima, iuser); - uiDefButS(block, NUM, imagechanged, "X:", 220, 55,200,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x"); - uiDefButS(block, NUM, imagechanged, "Y:", 220, 35,200,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y"); - uiBlockEndAlign(block); - - uiDefButS(block, OPTION, imagechanged, "UV Test grid", 220,10,200,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); - uiBlockSetFunc(block, NULL, NULL, NULL); - } - } - uiBlockEndAlign(block); -} + if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + split= uiLayoutSplit(layout, 0); + + col= uiLayoutColumn(split, 0); + + sprintf(str, "(%d) Frames:", iuser->framenr); + row= uiLayoutRow(col, 1); + uiItemR(col, str, 0, userptr, "frames", 0); + if(ima->anim) { + block= uiLayoutGetBlock(row); + but= uiDefBut(block, BUT, 0, "<", 0, 0, UI_UNIT_X*2, UI_UNIT_Y, 0, 0, 0, 0, 0, "Set the number of frames from the movie or sequence."); + uiButSetFunc(but, set_frames_cb, ima, iuser); + } + + uiItemR(col, "Start", 0, userptr, "start_frame", 0); + uiItemR(col, NULL, 0, userptr, "offset", 0); + + col= uiLayoutColumn(split, 0); + uiItemR(col, "Fields", 0, userptr, "fields_per_frame", 0); + uiItemR(col, NULL, 0, userptr, "auto_refresh", 0); + uiItemR(col, NULL, 0, userptr, "cyclic", 0); + } + else if(ima->source==IMA_SRC_GENERATED) { + split= uiLayoutSplit(layout, 0); + + col= uiLayoutColumn(split, 1); + uiItemR(col, "X", 0, &imaptr, "generated_width", 0); + uiItemR(col, "Y", 0, &imaptr, "generated_height", 0); + + col= uiLayoutColumn(split, 0); + uiItemR(col, NULL, 0, &imaptr, "generated_type", UI_ITEM_R_EXPAND); + } + + if(ima->source != IMA_SRC_GENERATED) { + uiItemS(layout); + + split= uiLayoutSplit(layout, 0); + + col= uiLayoutColumn(split, 0); + uiItemR(col, NULL, 0, &imaptr, "fields", 0); + row= uiLayoutRow(col, 0); + uiItemR(row, "Odd", 0, &imaptr, "odd_fields", 0); + uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "fields")); + + col= uiLayoutColumn(split, 0); + uiItemR(col, NULL, 0, &imaptr, "antialias", 0); + uiItemR(col, NULL, 0, &imaptr, "premultiply", 0); + } + } + + uiBlockSetNFunc(block, NULL, NULL, NULL); + } + + MEM_freeN(cb); +} void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser) { - uiBlock *block= uiLayoutFreeBlock(layout); Scene *scene= CTX_data_scene(C); RenderResult *rr; @@ -1389,55 +1080,46 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser if(ima && iuser) { rr= BKE_image_get_renderresult(scene, ima); - if(rr) { - uiBlockBeginAlign(block); - uiblock_layer_pass_buttons(block, rr, iuser, 0, 0, 0, 160); - uiBlockEndAlign(block); - } + if(rr) + uiblock_layer_pass_buttons(layout, rr, iuser, 160); } } -static void image_panel_properties(const bContext *C, Panel *pa) +static int image_panel_uv_poll(const bContext *C, PanelType *pt) { - SpaceImage *sima= CTX_wm_space_image(C); + Object *obedit= CTX_data_edit_object(C); + return ED_uvedit_test(obedit); +} + +static void image_panel_uv(const bContext *C, Panel *pa) +{ + ARegion *ar= CTX_wm_region(C); uiBlock *block; block= uiLayoutFreeBlock(pa->layout); uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - /* note, it draws no bottom half in facemode, for vertex buttons */ - ED_image_uiblock_panel(C, block, &sima->image, &sima->iuser, B_REDR, B_REDR); image_editvertex_buts(C, block); + image_editcursor_buts(C, &ar->v2d, block); } void image_buttons_register(ARegionType *art) { PanelType *pt; - pt= MEM_callocN(sizeof(PanelType), "spacetype image panel properties"); - strcpy(pt->idname, "IMAGE_PT_properties"); - strcpy(pt->label, "Image Properties"); - pt->draw= image_panel_properties; - BLI_addtail(&art->paneltypes, pt); - - pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint"); - strcpy(pt->idname, "IMAGE_PT_paint"); - strcpy(pt->label, "Paint"); - pt->draw= image_panel_paint; - pt->poll= image_panel_paint_poll; - BLI_addtail(&art->paneltypes, pt); - - pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint color"); - strcpy(pt->idname, "IMAGE_PT_paint_color"); - strcpy(pt->label, "Paint Color"); - pt->draw= image_panel_paintcolor; - pt->poll= image_panel_paint_poll; + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel uv"); + strcpy(pt->idname, "IMAGE_PT_uv"); + strcpy(pt->label, "UV"); + pt->draw= image_panel_uv; + pt->poll= image_panel_uv_poll; BLI_addtail(&art->paneltypes, pt); pt= MEM_callocN(sizeof(PanelType), "spacetype image panel curves"); strcpy(pt->idname, "IMAGE_PT_curves"); strcpy(pt->label, "Curves"); pt->draw= image_panel_curves; + pt->poll= image_panel_poll; + pt->flag |= PNL_DEFAULT_CLOSED; BLI_addtail(&art->paneltypes, pt); pt= MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 806d0d7ce52..d54dd56d1e8 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -628,9 +628,14 @@ static int open_exec(bContext *C, wmOperator *op) if(!ima) return OPERATOR_CANCELLED; + + /* already set later */ + ima->id.us--; - BKE_image_signal(ima, &sima->iuser, IMA_SIGNAL_RELOAD); - ED_space_image_set(C, sima, scene, obedit, ima); + // XXX other users? + BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_RELOAD); + if(sima) + ED_space_image_set(C, sima, scene, obedit, ima); return OPERATOR_FINISHED; } @@ -651,13 +656,12 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) void IMAGE_OT_open(wmOperatorType *ot) { /* identifiers */ - ot->name= "Open Image"; + ot->name= "Open"; ot->idname= "IMAGE_OT_open"; /* api callbacks */ ot->exec= open_exec; ot->invoke= open_invoke; - ot->poll= ED_operator_image_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1051,8 +1055,12 @@ static int new_exec(bContext *C, wmOperator *op) color[3]= RNA_float_get(op->ptr, "alpha"); ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color); - BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); - ED_space_image_set(C, sima, scene, obedit, ima); + ima->id.us--; /* already set later */ + + if(sima) { // XXX other users? + BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); + ED_space_image_set(C, sima, scene, obedit, ima); + } return OPERATOR_FINISHED; } @@ -1066,7 +1074,6 @@ void IMAGE_OT_new(wmOperatorType *ot) /* api callbacks */ ot->exec= new_exec; ot->invoke= WM_operator_props_popup; - ot->poll= ED_operator_image_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 9051300e117..cb05109d984 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -77,7 +77,7 @@ int ED_uvedit_test(Object *obedit) EditMesh *em; int ret; - if(obedit->type != OB_MESH) + if(!obedit || obedit->type != OB_MESH) return 0; em = BKE_mesh_get_editmesh(obedit->data); diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 420add2622a..4cef6fa481f 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -216,13 +216,15 @@ static void rna_def_curvemapping(BlenderRNA *brna) RNA_def_property_struct_type(prop, "CurveMap"); RNA_def_property_ui_text(prop, "Curves", ""); - prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_COLOR); + prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_RGB); RNA_def_property_float_sdna(prop, NULL, "black"); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Black Level", "For RGB curves, the color that black is mapped to"); RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_black_level_set", NULL); - prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_COLOR); + prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_RGB); RNA_def_property_float_sdna(prop, NULL, "white"); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "White Level", "For RGB curves, the color that white is mapped to"); RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_white_level_set", NULL); } diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 4d04f4ee1f3..ad96eaa99ad 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -37,6 +37,14 @@ #include "WM_types.h" +static EnumPropertyItem image_source_items[]= { + {IMA_SRC_FILE, "FILE", 0, "File", "Single image file"}, + {IMA_SRC_SEQUENCE, "SEQUENCE", 0, "Sequence", "Multiple image files, as a sequence"}, + {IMA_SRC_MOVIE, "MOVIE", 0, "Movie", "Movie file"}, + {IMA_SRC_GENERATED, "GENERATED", 0, "Generated", "Generated image"}, + {IMA_SRC_VIEWER, "VIEWER", 0, "Viewer", "Compositing node viewer"}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "IMB_imbuf_types.h" @@ -66,6 +74,76 @@ static int rna_Image_dirty_get(PointerRNA *ptr) return 0; } +static void rna_Image_source_update(bContext *C, PointerRNA *ptr) +{ + Image *ima= ptr->id.data; + BKE_image_signal(ima, NULL, IMA_SIGNAL_SRC_CHANGE); +} + +static void rna_Image_fields_update(bContext *C, PointerRNA *ptr) +{ + Image *ima= ptr->id.data; + ImBuf *ibuf; + + ibuf= BKE_image_get_ibuf(ima, NULL); + + if(ibuf) { + short nr= 0; + + if(!(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields)) nr= 1; + if((ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields)) nr= 1; + + if(nr) + BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); + } +} + +static void rna_Image_reload_update(bContext *C, PointerRNA *ptr) +{ + Image *ima= ptr->id.data; + BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD); + printf("reload %p\n", ima); +} + +static void rna_Image_generated_update(bContext *C, PointerRNA *ptr) +{ + Image *ima= ptr->id.data; + BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); +} + +static void rna_ImageUser_update(bContext *C, PointerRNA *ptr) +{ + Scene *scene= CTX_data_scene(C); + ImageUser *iuser= ptr->data; + + BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0); +} + +static EnumPropertyItem *rna_Image_source_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Image *ima= (Image*)ptr->data; + EnumPropertyItem *item= NULL; + int totitem= 0; + + if(C==NULL) /* needed for doc generation */ + return image_source_items; + + if(ima->source == IMA_SRC_VIEWER) { + RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_VIEWER); + } + else { + RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_FILE); + RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_SEQUENCE); + RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_MOVIE); + RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_GENERATED); + } + + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; +} + #else static void rna_def_imageuser(BlenderRNA *brna) @@ -79,29 +157,35 @@ static void rna_def_imageuser(BlenderRNA *brna) prop= RNA_def_property(srna, "auto_refresh", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANIM_ALWAYS); RNA_def_property_ui_text(prop, "Auto Refresh", "Always refresh image on frame changes."); + RNA_def_property_update(prop, 0, "rna_ImageUser_update"); /* animation */ prop= RNA_def_property(srna, "cyclic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "cycl", 0); RNA_def_property_ui_text(prop, "Cyclic", "Cycle the images in the movie."); + RNA_def_property_update(prop, 0, "rna_ImageUser_update"); prop= RNA_def_property(srna, "frames", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, MAXFRAMEF); RNA_def_property_ui_text(prop, "Frames", "Sets the number of images of a movie to use."); + RNA_def_property_update(prop, 0, "rna_ImageUser_update"); prop= RNA_def_property(srna, "offset", PROP_INT, PROP_NONE); RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation."); + RNA_def_property_update(prop, 0, "rna_ImageUser_update"); prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_TIME); RNA_def_property_int_sdna(prop, NULL, "sfra"); RNA_def_property_range(prop, 1.0f, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start Frame", "Sets the global starting frame of the movie."); + RNA_def_property_update(prop, 0, "rna_ImageUser_update"); prop= RNA_def_property(srna, "fields_per_frame", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "fie_ima"); RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Fields per Frame", "The number of fields per rendered frame (2 fields is 1 image)."); + RNA_def_property_update(prop, 0, "rna_ImageUser_update"); prop= RNA_def_property(srna, "multilayer_layer", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "layer"); @@ -121,17 +205,10 @@ static void rna_def_image(BlenderRNA *brna) static const EnumPropertyItem prop_type_items[]= { {IMA_TYPE_IMAGE, "IMAGE", 0, "Image", ""}, {IMA_TYPE_MULTILAYER, "MULTILAYER", 0, "Multilayer", ""}, - {IMA_TYPE_UV_TEST, "UVTEST", 0, "UV Test", ""}, - {IMA_TYPE_R_RESULT, "RENDERRESULT", 0, "Render Result", ""}, + {IMA_TYPE_UV_TEST, "UV_TEST", 0, "UV Test", ""}, + {IMA_TYPE_R_RESULT, "RENDER_RESULT", 0, "Render Result", ""}, {IMA_TYPE_COMPOSITE, "COMPOSITING", 0, "Compositing", ""}, {0, NULL, 0, NULL, NULL}}; - static const EnumPropertyItem prop_source_items[]= { - {IMA_SRC_FILE, "FILE", 0, "File", "Single image file"}, - {IMA_SRC_SEQUENCE, "SEQUENCE", 0, "Sequence", "Multiple image files, as a sequence"}, - {IMA_SRC_MOVIE, "MOVIE", 0, "Movie", "Movie file"}, - {IMA_SRC_GENERATED, "GENERATED", 0, "Generated", "Generated image"}, - {IMA_SRC_VIEWER, "VIEWER", 0, "Viewer", "Compositing node viewer"}, - {0, NULL, 0, NULL, NULL}}; static const EnumPropertyItem prop_generated_type_items[]= { {0, "BLANK", 0, "Blank", "Generate a blank image"}, {1, "UVTESTGRID", 0, "UV Test Grid", "Generated grid to test UV mappings"}, @@ -147,19 +224,18 @@ static void rna_def_image(BlenderRNA *brna) prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */ RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update"); prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_source_items); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */ + RNA_def_property_enum_items(prop, image_source_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Image_source_itemf"); RNA_def_property_ui_text(prop, "Source", "Where the image comes from."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_source_update"); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_type_items); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */ + RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Type", "How to generate the image."); RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); @@ -171,12 +247,12 @@ static void rna_def_image(BlenderRNA *brna) prop= RNA_def_property(srna, "fields", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS); RNA_def_property_ui_text(prop, "Fields", "Use fields of the image."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_fields_update"); prop= RNA_def_property(srna, "odd_fields", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_STD_FIELD); RNA_def_property_ui_text(prop, "Odd Fields", "Standard field toggle."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update"); prop= RNA_def_property(srna, "antialias", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANTIALI); @@ -198,19 +274,19 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "gen_type"); RNA_def_property_enum_items(prop, prop_generated_type_items); RNA_def_property_ui_text(prop, "Generated Type", "Generated image type."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_generated_update"); prop= RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gen_x"); RNA_def_property_range(prop, 1, 16384); RNA_def_property_ui_text(prop, "Generated Width", "Generated image width."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_generated_update"); prop= RNA_def_property(srna, "generated_height", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "gen_y"); RNA_def_property_range(prop, 1, 16384); RNA_def_property_ui_text(prop, "Generated Height", "Generated image height."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_generated_update"); /* realtime properties */ prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 6b6e8b5b98e..30c5d4988b3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -212,6 +212,15 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, P return dc_rgb_items; } +static void rna_SpaceImageEditor_curves_update(bContext *C, PointerRNA *ptr) +{ + SpaceImage *sima= (SpaceImage*)ptr->data; + + curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); + WM_event_add_notifier(C, NC_IMAGE, sima->image); +} + + /* Space Text Editor */ static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value) @@ -809,7 +818,7 @@ static void rna_def_space_image(BlenderRNA *brna) prop= RNA_def_property(srna, "curves", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "cumap"); RNA_def_property_ui_text(prop, "Curves", "Color curve mapping to use for displaying the image."); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_curves_update"); prop= RNA_def_property(srna, "image_pin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "pin", 0); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 7a81138a3be..6fb9a9ca57b 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1073,6 +1073,11 @@ static void rna_def_texture_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Image", ""); RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "iuser"); + RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + /* filtering */ prop= RNA_def_property(srna, "filter", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "texfilter"); @@ -1116,6 +1121,11 @@ static void rna_def_texture_environment_map(BlenderRNA *brna) rna_def_environment_map_common(srna); + prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "iuser"); + RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed."); + RNA_def_property_update(prop, NC_TEXTURE, NULL); + prop= RNA_def_property(srna, "environment_map", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "env"); RNA_def_property_struct_type(prop, "EnvironmentMap"); @@ -1641,9 +1651,7 @@ static void rna_def_texture(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Contrast", ""); RNA_def_property_update(prop, NC_TEXTURE, NULL); - /* XXX: would be nicer to have this as a color selector? - but the values can go past [0,1]. */ - prop= RNA_def_property(srna, "rgb_factor", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "rgb_factor", PROP_FLOAT, PROP_RGB); RNA_def_property_float_sdna(prop, NULL, "rfac"); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0, 2); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 60994757b59..3110e631a65 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -292,11 +292,18 @@ void RNA_api_ui_layout(StructRNA *srna) parm= RNA_def_pointer(func, "image_user", "ImageUser", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + func= RNA_def_function(srna, "template_image", "uiTemplateImage"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + api_ui_item_rna_common(func); + parm= RNA_def_pointer(func, "image_user", "ImageUser", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_boolean(func, "compact", 0, "", "Use more compact layout."); + func= RNA_def_function(srna, "template_list", "uiTemplateList"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); api_ui_item_rna_common(func); parm= RNA_def_pointer(func, "active_data", "AnyType", "", "Data from which to take property for the active element."); - RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element."); RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display.", 0, INT_MAX); @@ -314,11 +321,6 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "view3d_select_faceselmenu", "uiTemplate_view3d_select_faceselmenu"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - - func= RNA_def_function(srna, "template_texture_image", "uiTemplateTextureImage"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT); - parm= RNA_def_pointer(func, "texture", "Texture", "", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); } #endif -- cgit v1.2.3 From 21e2f27532db7a9107d91fad79250cb5dd5103f5 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 16 Sep 2009 19:27:23 +0000 Subject: Tiny fix for mistake in toolbar. --- release/ui/space_view3d_toolbar.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index f177c81b7b7..4a5f2ae642c 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -67,9 +67,12 @@ class VIEW3D_PT_tools_meshedit(View3DPanel): col = layout.column(align=True) col.itemL(text="Modeling:") col.itemO("mesh.extrude") + col.itemO("mesh.extrude_repeat", text="Extrude Repeat") col.itemO("mesh.subdivide") col.itemO("mesh.spin") col.itemO("mesh.screw") + col.itemO("mesh.merge") + col.itemO("mesh.rip_move") col = layout.column(align=True) col.itemL(text="Shading:") @@ -288,7 +291,7 @@ class VIEW3D_PT_tools_posemode(View3DPanel): col.itemO("pose.reveal", text="Reveal") col = layout.column(align=True) - layout.itemL(text="Keyframes:") + col.itemL(text="Keyframes:") col.itemO("anim.insert_keyframe_menu", text="Insert") col.itemO("anim.delete_keyframe_v3d", text="Remove") -- cgit v1.2.3 From b6c6610630220de3fd39ee0c117451e436c889e0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 16 Sep 2009 19:36:17 +0000 Subject: UI * Removed some legacy code which is not needed anymore now. * Move some test_*poin_but functions to logic space code, since that's the only place using it still. * uiIconFromID now uses RNA info to lookup the icon, to avoid code duplication, and means it works for more ID types. --- source/blender/editors/include/UI_interface.h | 24 - .../editors/interface/interface_templates.c | 27 +- source/blender/editors/interface/interface_utils.c | 1077 +------------------- .../blender/editors/space_buttons/space_buttons.c | 65 -- source/blender/editors/space_graph/graph_buttons.c | 21 +- source/blender/editors/space_logic/logic_window.c | 101 ++ 6 files changed, 159 insertions(+), 1156 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index f475dd16057..848432b5f42 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -418,7 +418,6 @@ typedef void (*uiIDPoinFunc)(struct bContext *C, struct ID *id, int event); uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str, short x1, short y1, short x2, short y2, void *idpp, char *tip); -int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID *id, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events); int uiIconFromID(struct ID *id); @@ -531,29 +530,6 @@ void UI_add_region_handlers(struct ListBase *handlers); void UI_add_area_handlers(struct ListBase *handlers); void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *menu); -/* Legacy code - * Callbacks and utils to get 2.48 work */ - -void test_idbutton_cb(struct bContext *C, void *namev, void *arg2); -void test_scriptpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_actionpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_obpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_meshobpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_meshpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_matpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_scenepoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_grouppoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_texpoin_but(struct bContext *C, char *name, struct ID **idpp); -void test_imapoin_but(struct bContext *C, char *name, struct ID **idpp); -void autocomplete_bone(struct bContext *C, char *str, void *arg_v); -void autocomplete_vgroup(struct bContext *C, char *str, void *arg_v); - -struct rctf; -void curvemap_buttons(uiBlock *block, struct CurveMapping *cumap, char labeltype, short event, short redraw, struct rctf *rect); -void curvemap_layout(uiLayout *layout, struct CurveMapping *cumap, char labeltype, short event, short redraw, struct rctf *rect); -void colorband_buttons(uiBlock *block, struct ColorBand *coba, struct rctf *rect, int small); - - /* Module * * init and exit should be called before using this module. init_userdef must diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 66873917e8a..b27425f958d 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -762,6 +762,22 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short } } +static void test_obpoin_but(bContext *C, char *name, ID **idpp) +{ + ID *id; + + id= CTX_data_main(C)->object.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ + return; + } + id= id->next; + } + *idpp= NULL; +} + /* draw panel showing settings for a constraint */ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) { @@ -956,11 +972,11 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) /* subtarget */ if (is_armature_target(ct->tar)) { but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", xco+120, yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Subtarget Bone"); - uiButSetCompleteFunc(but, autocomplete_bone, (void *)ct->tar); + //uiButSetCompleteFunc(but, autocomplete_bone, (void *)ct->tar); } else if (is_geom_target(ct->tar)) { but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", xco+120, yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points"); - uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ct->tar); + //uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ct->tar); } else { strcpy(ct->subtarget, ""); @@ -1762,9 +1778,6 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname) int groups, cols, layers; int group, col, layer, row; - if (!ptr->data) - return; - prop= RNA_struct_find_property(ptr, propname); if (!prop) { printf("uiTemplateLayer: layers property not found: %s\n", propname); @@ -2036,7 +2049,7 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr /************************* Operator Search Template **************************/ -static void operator_call_cb(struct bContext *C, void *arg1, void *arg2) +static void operator_call_cb(bContext *C, void *arg1, void *arg2) { wmOperatorType *ot= arg2; @@ -2044,7 +2057,7 @@ static void operator_call_cb(struct bContext *C, void *arg1, void *arg2) WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL); } -static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items) +static void operator_search_cb(const bContext *C, void *arg, char *str, uiSearchItems *items) { wmOperatorType *ot = WM_operatortype_first(); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 539c71cc497..00dec9a06c2 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -23,31 +23,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include +#include #include #include -#include "MEM_guardedalloc.h" - -#include "DNA_action_types.h" -#include "DNA_color_types.h" -#include "DNA_listBase.h" -#include "DNA_material_types.h" -#include "DNA_lamp_types.h"" #include "DNA_object_types.h" -#include "DNA_screen_types.h" -#include "DNA_texture_types.h" -#include "DNA_windowmanager_types.h" - -#include "BLI_blenlib.h" -#include "BKE_colortools.h" #include "BKE_context.h" -#include "BKE_idprop.h" -#include "BKE_icons.h" -#include "BKE_library.h" -#include "BKE_main.h" -#include "BKE_texture.h" #include "BKE_utildefines.h" #include "RNA_access.h" @@ -55,18 +37,6 @@ #include "UI_interface.h" #include "UI_resources.h" -#include "ED_screen.h" -#include "ED_util.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "interface_intern.h" - -#define DEF_BUT_WIDTH 150 -#define DEF_ICON_BUT_WIDTH 20 -#define DEF_BUT_HEIGHT 20 - /*************************** RNA Utilities ******************************/ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2) @@ -177,1047 +147,38 @@ void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int else col= NULL; - /* temp hack to show normal button for spin/screw */ - if(strcmp(name, "Axis")==0) { - uiDefButR(uiLayoutGetBlock(col), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL); - } - else uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0); + uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0); } RNA_STRUCT_END; } /***************************** ID Utilities *******************************/ -/* note, C code version, will be replaced with version in interface_templates.c */ - -typedef struct uiIDPoinParams { - uiIDPoinFunc func; - ListBase *lb; - ID *id; - short id_code; - short browsenr; -} uiIDPoinParams; - -static void idpoin_cb(bContext *C, void *arg_params, void *arg_event) -{ - uiIDPoinParams *params= (uiIDPoinParams*)arg_params; - ListBase *lb= params->lb; - uiIDPoinFunc func= params->func; - ID *id= params->id, *idtest; - int nr, event= GET_INT_FROM_POINTER(arg_event); - - if(event == UI_ID_BROWSE && params->browsenr == 32767) - event= UI_ID_ADD_NEW; - else if(event == UI_ID_BROWSE && params->browsenr == 32766) - event= UI_ID_OPEN; - - switch(event) { - case UI_ID_RENAME: - if(id) test_idbutton(id->name+2); - else return; - break; - case UI_ID_BROWSE: { - /* ID can be NULL, if nothing was assigned yet */ - if(lb->first==NULL) return; - - if(params->browsenr== -2) { - /* XXX implement or find a replacement (ID can be NULL!) - * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, ¶ms->browsenr, do_global_buttons); */ - return; - } - if(params->browsenr < 0) - return; - - for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) { - if(nr==params->browsenr) { - if(id == idtest) - return; - - id= idtest; - - break; - } - } - break; - } - case UI_ID_DELETE: - id= NULL; - break; - case UI_ID_FAKE_USER: - if(id) { - if(id->flag & LIB_FAKEUSER) id->us++; - else id->us--; - } - else return; - break; - case UI_ID_PIN: - break; - case UI_ID_ADD_NEW: - break; - case UI_ID_OPEN: - break; - case UI_ID_ALONE: - if(!id || id->us < 1) - return; - break; - case UI_ID_LOCAL: - if(!id || id->us < 1) - return; - break; - case UI_ID_AUTO_NAME: - break; - } - - if(func) - func(C, id, event); -} - -/* ***************************** ID Search browse menu ********************** */ - -static void id_search_call_cb(struct bContext *C, void *arg_params, void *item) -{ - uiIDPoinParams *params= (uiIDPoinParams*)arg_params; - - if(item && params->func) - params->func(C, item, UI_ID_BROWSE); - -} - -static void id_search_cb(const struct bContext *C, void *arg_params, char *str, uiSearchItems *items) -{ - uiIDPoinParams *params= (uiIDPoinParams*)arg_params; - ID *id; - - for(id= params->lb->first; id; id= id->next) { - int iconid= 0; - - - /* icon */ - switch(GS(id->name)) - { - case ID_MA: /* fall through */ - case ID_TE: /* fall through */ - case ID_IM: /* fall through */ - case ID_WO: /* fall through */ - case ID_LA: /* fall through */ - iconid= BKE_icon_getid(id); - break; - default: - break; - } - - if(BLI_strcasestr(id->name+2, str)) { - if(0==uiSearchItemAdd(items, id->name+2, id, iconid)) - break; - } - } -} - -static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_params) -{ - static char search[256]; - static uiIDPoinParams params; - wmEvent event; - wmWindow *win= CTX_wm_window(C); - uiBlock *block; - uiBut *but; - - /* clear initial search string, then all items show */ - search[0]= 0; - /* params is malloced, can be freed by parent button */ - params= *((uiIDPoinParams*)arg_params); - - block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); - - /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); - - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, ""); - uiButSetSearchFunc(but, id_search_cb, ¶ms, id_search_call_cb, NULL); - - uiBoundsBlock(block, 6); - uiBlockSetDirection(block, UI_DOWN); - uiEndBlock(C, block); - - event= *(win->eventstate); /* XXX huh huh? make api call */ - event.type= EVT_BUT_OPEN; - event.val= KM_PRESS; - event.customdata= but; - event.customdatafree= FALSE; - wm_event_add(win, &event); - - return block; -} - -/* ****************** */ - -int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID *id, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events) -{ - uiBut *but; - uiIDPoinParams *params, *dup_params; - char str1[10]; - int len, add_addbutton=0; - - /* setup struct that we will pass on with the buttons */ - params= MEM_callocN(sizeof(uiIDPoinParams), "uiIDPoinParams"); - params->lb= wich_libbase(bmain, id_code); - params->id= id; - params->id_code= id_code; - params->func= func; - - /* create buttons */ - uiBlockBeginAlign(block); - - /* XXX solve? - if(id && id->us>1) - uiBlockSetCol(block, TH_BUT_SETTING1); - - if((events & UI_ID_PIN) && *pin_p) - uiBlockSetCol(block, TH_BUT_SETTING2); - */ - - /* pin button */ - if(id && (events & UI_ID_PIN)) { - but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), ICON_KEY_DEHLT, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected"); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_PIN)); - x+= DEF_ICON_BUT_WIDTH; - } - - /* browse menu */ - if(events & UI_ID_BROWSE) { - uiDefBlockButN(block, id_search_menu, MEM_dupallocN(params), "", x, y, DEF_ICON_BUT_WIDTH, DEF_BUT_HEIGHT, "Browse ID data"); - x+= DEF_ICON_BUT_WIDTH; - } - - - - /* text button with name */ - if(id) { - /* XXX solve? - if(id->us > 1) - uiBlockSetCol(block, TH_BUT_SETTING1); - */ - /* pinned data? - if((events & UI_ID_PIN) && *pin_p) - uiBlockSetCol(block, TH_BUT_SETTING2); - */ - /* redalert overrides pin color - if(id->us<=0) - uiBlockSetCol(block, TH_REDALERT); - */ - uiBlockSetButLock(block, id->lib!=0, "Can't edit external libdata"); - - /* name button */ - text_idbutton(id, str1); - - if(GS(id->name)==ID_IP) len= 110; - else if((y) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib) - else if(y) len= 140; // comes from button panel - else len= 120; - - but= uiDefBut(block, TEX, 0, str1,x, y, (short)len, DEF_BUT_HEIGHT, id->name+2, 0.0, 21.0, 0, 0, "Displays current Datablock name. Click to change."); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_RENAME)); - - x+= len; - - uiBlockClearButLock(block); - - /* lib make local button */ - if(id->lib) { - if(id->flag & LIB_INDIRECT) uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_DATALIB */,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Indirect Library Datablock. Cannot change."); - else { - but= uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_PARLIB */, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, - (events & UI_ID_LOCAL)? "Direct linked Library Datablock. Click to make local.": "Direct linked Library Datablock, cannot make local."); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE)); - } - - x+= DEF_ICON_BUT_WIDTH; - } - - /* number of users / make local button */ - if((events & UI_ID_ALONE) && id->us>1) { - int butwidth; - - uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't make pinned data single-user"); - - sprintf(str1, "%d", id->us); - butwidth= (id->us<10)? DEF_ICON_BUT_WIDTH: DEF_ICON_BUT_WIDTH+10; - - but= uiDefBut(block, BUT, 0, str1, x, y, butwidth, DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy."); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE)); - x+= butwidth; - - uiBlockClearButLock(block); - } - - /* add button */ - if(events & UI_ID_ADD_NEW) { - uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data"); - if(parid && parid->lib); - else { - dup_params= MEM_dupallocN(params); - but= uiDefIconBut(block, BUT, 0, ICON_ZOOMIN, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block"); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); - x+= DEF_ICON_BUT_WIDTH; - } - - uiBlockClearButLock(block); - } - - /* delete button */ - if(events & UI_ID_DELETE) { - uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data"); - if(parid && parid->lib); - else { - but= uiDefIconBut(block, BUT, 0, ICON_X, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Deletes link to this Datablock"); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_DELETE)); - x+= DEF_ICON_BUT_WIDTH; - } - - uiBlockClearButLock(block); - } - - /* auto name button */ - if(events & UI_ID_AUTO_NAME) { - if(parid && parid->lib); - else { - but= uiDefIconBut(block, BUT, 0, ICON_AUTO,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Generates an automatic name"); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_AUTO_NAME)); - x+= DEF_ICON_BUT_WIDTH; - } - } - - /* fake user button */ - if(events & UI_ID_FAKE_USER) { - but= uiDefButBitS(block, TOG, LIB_FAKEUSER, 0, "F", x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &id->flag, 0, 0, 0, 0, "Saves this datablock even if it has no users"); - uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_FAKE_USER)); - x+= DEF_ICON_BUT_WIDTH; - } - } - /* add new button */ - else if(add_addbutton) { - if(parid) uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata"); - dup_params= MEM_dupallocN(params); - but= uiDefButS(block, TOG, 0, "Add New", x, y, 110, DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block"); - uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_ADD_NEW)); - x+= 110; - } - - uiBlockEndAlign(block); - - MEM_freeN(params); - return x; -} - -/* currently only object-data types */ int uiIconFromID(ID *id) { - if (id==NULL) - return 0; - - switch(GS(id->name)) { - case ID_OB: - { - Object *ob= (Object *)id; - - switch(ob->type) { - case OB_EMPTY: - return ICON_EMPTY_DATA; - case OB_CURVE: - return ICON_CURVE_DATA; - case OB_SURF: - return ICON_SURFACE_DATA; - case OB_FONT: - return ICON_FONT_DATA; - } - - return uiIconFromID(ob->data); - } - case ID_ME: - return ICON_MESH_DATA; - case ID_AR: - return ICON_ARMATURE_DATA; - case ID_MB: - return ICON_META_DATA; - case ID_CA: - return ICON_CAMERA_DATA; - case ID_LT: - return ICON_LATTICE_DATA; - case ID_CU: - return ICON_CURVE_DATA; - case ID_LA: - { - Lamp *la= (Lamp *)id; - switch(la->type) { - case LA_LOCAL: - return ICON_LAMP_POINT; - case LA_SUN: - return ICON_LAMP_SUN; - case LA_SPOT: - return ICON_LAMP_SPOT; - case LA_HEMI: - return ICON_LAMP_HEMI; - case LA_AREA: - return ICON_LAMP_AREA; - } - return ICON_LAMP_DATA; - } - } - - return 0; -} - -/* ****************************** default button callbacks ******************* */ -/* ************ LEGACY WARNING, only to get things work with 2.48 code! ****** */ - -void test_idbutton_cb(struct bContext *C, void *namev, void *arg2) -{ - char *name= namev; - - test_idbutton(name+2); -} - - -void test_scriptpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - id= CTX_data_main(C)->text.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - return; - } - id= id->next; - } - *idpp= NULL; -} - -void test_actionpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - id= CTX_data_main(C)->action.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - id_us_plus(id); - *idpp= id; - return; - } - id= id->next; - } - *idpp= NULL; -} - - -void test_obpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - -// XXX if(idpp == (ID **)&(emptytex.object)) { -// error("You must add a texture first"); -// *idpp= 0; -// return; -// } - - id= CTX_data_main(C)->object.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ - return; - } - id= id->next; - } - *idpp= NULL; -} - -/* tests for an object of type OB_MESH */ -void test_meshobpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - id = CTX_data_main(C)->object.first; - while(id) { - Object *ob = (Object *)id; - if(ob->type == OB_MESH && strcmp(name, id->name + 2) == 0) { - *idpp = id; - /* checks lib data, sets correct flag for saving then */ - id_lib_extern(id); - return; - } - id = id->next; - } - *idpp = NULL; -} - -void test_meshpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - if( *idpp ) (*idpp)->us--; - - id= CTX_data_main(C)->mesh.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_us_plus(id); - return; - } - id= id->next; - } - *idpp= NULL; -} - -void test_matpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - if( *idpp ) (*idpp)->us--; - - id= CTX_data_main(C)->mat.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_us_plus(id); - return; - } - id= id->next; - } - *idpp= NULL; -} - -void test_scenepoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - if( *idpp ) (*idpp)->us--; - - id= CTX_data_main(C)->scene.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_us_plus(id); - return; - } - id= id->next; - } - *idpp= NULL; -} - -void test_grouppoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - if( *idpp ) (*idpp)->us--; - - id= CTX_data_main(C)->group.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_us_plus(id); - return; - } - id= id->next; - } - *idpp= NULL; -} - -void test_texpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - if( *idpp ) (*idpp)->us--; - - id= CTX_data_main(C)->tex.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_us_plus(id); - return; - } - id= id->next; - } - *idpp= NULL; -} - -void test_imapoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - if( *idpp ) (*idpp)->us--; - - id= CTX_data_main(C)->image.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_us_plus(id); - return; - } - id= id->next; - } - *idpp= NULL; -} - -/* autocomplete callback for buttons */ -void autocomplete_bone(struct bContext *C, char *str, void *arg_v) -{ - Object *ob= (Object *)arg_v; - - if(ob==NULL || ob->pose==NULL) return; - - /* search if str matches the beginning of name */ - if(str[0]) { - AutoComplete *autocpl= autocomplete_begin(str, 32); - bPoseChannel *pchan; - - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) - autocomplete_do_name(autocpl, pchan->name); - - autocomplete_end(autocpl, str); - } -} - -/* autocomplete callback for buttons */ -void autocomplete_vgroup(struct bContext *C, char *str, void *arg_v) -{ - Object *ob= (Object *)arg_v; - - if(ob==NULL) return; - - /* search if str matches the beginning of a name */ - if(str[0]) { - AutoComplete *autocpl= autocomplete_begin(str, 32); - bDeformGroup *dg; - - for(dg= ob->defbase.first; dg; dg= dg->next) - if(dg->name!=str) - autocomplete_do_name(autocpl, dg->name); - - autocomplete_end(autocpl, str); - } -} - - -/* ----------- custom button group ---------------------- */ - -static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *unused) -{ - CurveMapping *cumap = cumap_v; - float d; - - /* we allow 20 times zoom */ - if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) { - d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin); - cumap->curr.xmin+= d; - cumap->curr.xmax-= d; - d= 0.1154f*(cumap->curr.ymax - cumap->curr.ymin); - cumap->curr.ymin+= d; - cumap->curr.ymax-= d; - } -} - -static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *unused) -{ - CurveMapping *cumap = cumap_v; - float d, d1; - - /* we allow 20 times zoom, but dont view outside clip */ - if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) { - d= d1= 0.15f*(cumap->curr.xmax - cumap->curr.xmin); - - if(cumap->flag & CUMA_DO_CLIP) - if(cumap->curr.xmin-d < cumap->clipr.xmin) - d1= cumap->curr.xmin - cumap->clipr.xmin; - cumap->curr.xmin-= d1; - - d1= d; - if(cumap->flag & CUMA_DO_CLIP) - if(cumap->curr.xmax+d > cumap->clipr.xmax) - d1= -cumap->curr.xmax + cumap->clipr.xmax; - cumap->curr.xmax+= d1; - - d= d1= 0.15f*(cumap->curr.ymax - cumap->curr.ymin); - - if(cumap->flag & CUMA_DO_CLIP) - if(cumap->curr.ymin-d < cumap->clipr.ymin) - d1= cumap->curr.ymin - cumap->clipr.ymin; - cumap->curr.ymin-= d1; - - d1= d; - if(cumap->flag & CUMA_DO_CLIP) - if(cumap->curr.ymax+d > cumap->clipr.ymax) - d1= -cumap->curr.ymax + cumap->clipr.ymax; - cumap->curr.ymax+= d1; - } -} - -static void curvemap_buttons_setclip(bContext *C, void *cumap_v, void *unused) -{ - CurveMapping *cumap = cumap_v; - - curvemapping_changed(cumap, 0); -} - -static void curvemap_buttons_delete(bContext *C, void *cumap_v, void *unused) -{ - CurveMapping *cumap = cumap_v; - - curvemap_remove(cumap->cm+cumap->cur, SELECT); - curvemapping_changed(cumap, 0); -} - -/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ -static uiBlock *curvemap_clipping_func(struct bContext *C, struct ARegion *ar, void *cumap_v) -{ - CurveMapping *cumap = cumap_v; - uiBlock *block; - uiBut *bt; - - block= uiBeginBlock(C, ar, "curvemap_clipping_func", UI_EMBOSS); - - /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", -4, 16, 128, 106, NULL, 0, 0, 0, 0, ""); - - bt= uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, "Use Clipping", - 0,100,120,18, &cumap->flag, 0.0, 0.0, 10, 0, ""); - uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL); - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, 0, "Min X ", 0,74,120,18, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, ""); - uiDefButF(block, NUM, 0, "Min Y ", 0,56,120,18, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, ""); - uiDefButF(block, NUM, 0, "Max X ", 0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "Max Y ", 0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, ""); - - uiBlockSetDirection(block, UI_RIGHT); - - uiEndBlock(C, block); - return block; -} - - -static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event) -{ - CurveMapping *cumap = cumap_v; - CurveMap *cuma= cumap->cm+cumap->cur; - - switch(event) { - case 0: - curvemap_reset(cuma, &cumap->clipr); - curvemapping_changed(cumap, 0); - break; - case 1: - cumap->curr= cumap->clipr; - break; - case 2: /* set vector */ - curvemap_sethandle(cuma, 1); - curvemapping_changed(cumap, 0); - break; - case 3: /* set auto */ - curvemap_sethandle(cuma, 0); - curvemapping_changed(cumap, 0); - break; - case 4: /* extend horiz */ - cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE; - curvemapping_changed(cumap, 0); - break; - case 5: /* extend extrapolate */ - cuma->flag |= CUMA_EXTEND_EXTRAPOLATE; - curvemapping_changed(cumap, 0); - break; - } - ED_region_tag_redraw(CTX_wm_region(C)); -} - -static uiBlock *curvemap_tools_func(struct bContext *C, struct ARegion *ar, void *cumap_v) -{ - uiBlock *block; - short yco= 0, menuwidth=120; - - block= uiBeginBlock(C, ar, "curvemap_tools_func", UI_EMBOSS); - uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset View", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Handle", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Horizontal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Extrapolated", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Curve", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); - - uiBlockSetDirection(block, UI_RIGHT); - uiTextBoundsBlock(block, 50); - - uiEndBlock(C, block); - return block; -} - -/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */ -void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short event, short redraw, rctf *rect) -{ - uiBut *bt; - float dx, fy= rect->ymax-18.0f; - int icon; - short xco, yco; - - yco= (short)(rect->ymax-18.0f); - - /* curve choice options + tools/settings, 8 icons + spacer */ - dx= (rect->xmax-rect->xmin)/(9.0f); - - uiBlockBeginAlign(block); - if(labeltype=='v') { /* vector */ - xco= (short)rect->xmin; - if(cumap->cm[0].curve) - uiDefButI(block, ROW, redraw, "X", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - xco= (short)(rect->xmin+1.0f*dx); - if(cumap->cm[1].curve) - uiDefButI(block, ROW, redraw, "Y", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - xco= (short)(rect->xmin+2.0f*dx); - if(cumap->cm[2].curve) - uiDefButI(block, ROW, redraw, "Z", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - } - else if(labeltype=='c') { /* color */ - xco= (short)rect->xmin; - if(cumap->cm[3].curve) - uiDefButI(block, ROW, redraw, "C", xco, yco+2, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, ""); - xco= (short)(rect->xmin+1.0f*dx); - if(cumap->cm[0].curve) - uiDefButI(block, ROW, redraw, "R", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - xco= (short)(rect->xmin+2.0f*dx); - if(cumap->cm[1].curve) - uiDefButI(block, ROW, redraw, "G", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - xco= (short)(rect->xmin+3.0f*dx); - if(cumap->cm[2].curve) - uiDefButI(block, ROW, redraw, "B", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - } - /* else no channels ! */ - uiBlockEndAlign(block); - - xco= (short)(rect->xmin+4.5f*dx); - uiBlockSetEmboss(block, UI_EMBOSSN); - bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMIN, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in"); - uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL); - - xco= (short)(rect->xmin+5.25f*dx); - bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMOUT, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out"); - uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL); - - xco= (short)(rect->xmin+6.0f*dx); - bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, xco, yco, dx, 18, "Tools"); - - xco= (short)(rect->xmin+7.0f*dx); - if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT; - bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, event, icon, xco, yco, dx, 18, "Clipping Options"); - - xco= (short)(rect->xmin+8.0f*dx); - bt= uiDefIconBut(block, BUT, event, ICON_X, xco, yco, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points"); - uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL); - - uiBlockSetEmboss(block, UI_EMBOSS); - - uiDefBut(block, BUT_CURVE, event, "", - rect->xmin, rect->ymin, rect->xmax-rect->xmin, fy-rect->ymin, - cumap, 0.0f, 1.0f, 0, 0, ""); -} - -/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */ -void curvemap_layout(uiLayout *layout, CurveMapping *cumap, char labeltype, short event, short redraw, rctf *rect) -{ - uiLayout *row; - uiBlock *block; - uiBut *bt; - float dx, fy= rect->ymax-18.0f; - int icon; - - block= uiLayoutGetBlock(layout); - - /* curve choice options + tools/settings, 8 icons + spacer */ - dx= UI_UNIT_X; - - row= uiLayoutRow(layout, 0); - uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); - - if(labeltype=='v') { /* vector */ - row= uiLayoutRow(layout, 1); - - if(cumap->cm[0].curve) - uiDefButI(block, ROW, redraw, "X", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - if(cumap->cm[1].curve) - uiDefButI(block, ROW, redraw, "Y", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - if(cumap->cm[2].curve) - uiDefButI(block, ROW, redraw, "Z", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - } - else if(labeltype=='c') { /* color */ - row= uiLayoutRow(layout, 1); - - if(cumap->cm[3].curve) - uiDefButI(block, ROW, redraw, "C", 0, 0, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, ""); - if(cumap->cm[0].curve) - uiDefButI(block, ROW, redraw, "R", 0, 0, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); - if(cumap->cm[1].curve) - uiDefButI(block, ROW, redraw, "G", 0, 0, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); - if(cumap->cm[2].curve) - uiDefButI(block, ROW, redraw, "B", 0, 0, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, ""); - } - - row= uiLayoutRow(row, 1); - - uiBlockSetEmboss(block, UI_EMBOSSN); - bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMIN, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in"); - uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL); - - bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMOUT, 0, 0, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out"); - uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL); - - bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, 0, 0, dx, 18, "Tools"); - - if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT; - bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, event, icon, 0, 0, dx, 18, "Clipping Options"); - - bt= uiDefIconBut(block, BUT, event, ICON_X, 0, 0, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points"); - uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL); - - uiBlockSetEmboss(block, UI_EMBOSS); - - row= uiLayoutRow(layout, 0); - uiDefBut(block, BUT_CURVE, event, "", - rect->xmin, rect->ymin, rect->xmax-rect->xmin, fy-rect->ymin, - cumap, 0.0f, 1.0f, 0, 0, ""); -} - - -#define B_BANDCOL 1 - -static int vergcband(const void *a1, const void *a2) -{ - const CBData *x1=a1, *x2=a2; + Object *ob; + PointerRNA ptr; + short idcode; - if( x1->pos > x2->pos ) return 1; - else if( x1->pos < x2->pos) return -1; - return 0; -} - -static void colorband_pos_cb(bContext *C, void *coba_v, void *unused_v) -{ - ColorBand *coba= coba_v; - int a; - - if(coba->tot<2) return; + if(id==NULL) + return 0; - for(a=0; atot; a++) coba->data[a].cur= a; - qsort(coba->data, coba->tot, sizeof(CBData), vergcband); - for(a=0; atot; a++) { - if(coba->data[a].cur==coba->cur) { - // XXX if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ - coba->cur= a; - break; - } - } - - WM_event_add_notifier(C, NC_TEXTURE, NULL); -} + idcode= GS(id->name); -static void colorband_cb(bContext *C, void *coba_v, void *unused_v) -{ - WM_event_add_notifier(C, NC_TEXTURE, NULL); -} - -static void colorband_add_cb(bContext *C, void *coba_v, void *unused_v) -{ - ColorBand *coba= coba_v; - - if(coba->tot < MAXCOLORBAND-1) coba->tot++; - coba->cur= coba->tot-1; - - colorband_pos_cb(C, coba, NULL); - ED_undo_push(C, "Add colorband"); - WM_event_add_notifier(C, NC_TEXTURE, NULL); -} + /* exception for objects */ + if(idcode == ID_OB) { + ob= (Object*)id; -static void colorband_del_cb(bContext *C, void *coba_v, void *unused_v) -{ - ColorBand *coba= coba_v; - int a; - - if(coba->tot<2) return; - - for(a=coba->cur; atot; a++) { - coba->data[a]= coba->data[a+1]; + if(ob->type == OB_EMPTY) + return ICON_EMPTY_DATA; + else + return uiIconFromID(ob->data); } - if(coba->cur) coba->cur--; - coba->tot--; - - ED_undo_push(C, "Delete colorband"); - // XXX BIF_preview_changed(ID_TE); - WM_event_add_notifier(C, NC_TEXTURE, NULL); -} - -/* offset aligns from bottom, standard width 300, height 115 */ -static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw) -{ - CBData *cbd; - uiBut *bt; - - if(coba==NULL) return; - - bt= uiDefBut(block, BUT, redraw, "Add", 0+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Add a new color stop to the colorband"); - uiButSetFunc(bt, colorband_add_cb, coba, NULL); - bt= uiDefBut(block, BUT, redraw, "Delete", 60+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Delete the active position"); - uiDefButS(block, NUM, redraw, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Choose active color stop"); - - uiButSetFunc(bt, colorband_del_cb, coba, NULL); - - bt= uiDefButS(block, MENU, redraw, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", - 210+xoffs, 100+yoffs, 90, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops"); - uiButSetFunc(bt, colorband_cb, coba, NULL); - uiBlockEndAlign(block); - - bt= uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); - uiButSetFunc(bt, colorband_cb, coba, NULL); - - cbd= coba->data + coba->cur; - - bt= uiDefButF(block, NUM, redraw, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop"); - uiButSetFunc(bt, colorband_pos_cb, coba, NULL); - bt= uiDefButF(block, COL, redraw, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); - uiButSetFunc(bt, colorband_cb, coba, NULL); - bt= uiDefButF(block, NUMSLI, redraw, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop"); - uiButSetFunc(bt, colorband_cb, coba, NULL); - -} + /* otherwise get it through RNA, creating the pointer + will set the right type, also with subclassing */ + RNA_id_pointer_create(id, &ptr); -static void colorband_buttons_small(uiBlock *block, ColorBand *coba, rctf *butr, int event) -{ - CBData *cbd; - uiBut *bt; - float unit= (butr->xmax-butr->xmin)/14.0f; - float xs= butr->xmin; - - cbd= coba->data + coba->cur; - - - bt= uiDefBut(block, BUT, event, "Add", xs,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband"); - uiButSetFunc(bt, colorband_add_cb, coba, NULL); - bt= uiDefBut(block, BUT, event, "Delete", xs+2.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Delete the active position"); - uiButSetFunc(bt, colorband_del_cb, coba, NULL); - - uiDefButF(block, COL, event, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); - uiDefButF(block, NUMSLI, event, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop"); - - uiDefButS(block, MENU, event, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", - xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops"); - - uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, ""); - uiBlockEndAlign(block); -} - -void colorband_buttons(uiBlock *block, ColorBand *coba, rctf *butr, int small) -{ - if(small) - colorband_buttons_small(block, coba, butr, 0); - else - colorband_buttons_large(block, coba, 0, 0, 0); + return (ptr.type)? RNA_struct_ui_icon(ptr.type): 0; } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index d4ad77daca7..c8ced42c2d2 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -259,58 +259,6 @@ static void buttons_header_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); } -#if 0 -/* add handlers, stuff you only do once or on area/region changes */ -static void buttons_context_area_init(wmWindowManager *wm, ARegion *ar) -{ - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); -} - -#define CONTEXTY 30 - -static void buttons_context_area_draw(const bContext *C, ARegion *ar) -{ - SpaceButs *sbuts= CTX_wm_space_buts(C); - uiStyle *style= U.uistyles.first; - uiBlock *block; - uiLayout *layout; - View2D *v2d= &ar->v2d; - float col[3]; - int x, y, w, h; - - buttons_context_compute(C, sbuts); - - w= v2d->cur.xmax - v2d->cur.xmin; - h= v2d->cur.ymax - v2d->cur.ymin; - UI_view2d_view_ortho(C, v2d); - - /* create UI */ - block= uiBeginBlock(C, ar, "buttons_context", UI_EMBOSS); - layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_PANEL, - style->panelspace, h - (h-UI_UNIT_Y)/2, w, 20, style); - - buttons_context_draw(C, layout); - - uiBlockLayoutResolve(C, block, &x, &y); - uiEndBlock(C, block); - - /* draw */ - UI_SetTheme(SPACE_BUTS, RGN_TYPE_WINDOW); /* XXX */ - - UI_GetThemeColor3fv(TH_BACK, col); - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - UI_view2d_totRect_set(v2d, x, -y); - UI_view2d_view_ortho(C, v2d); - - uiDrawBlock(C, block); - - /* restore view matrix */ - UI_view2d_view_restore(C); -} -#endif - /* reused! */ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn) { @@ -424,19 +372,6 @@ void ED_spacetype_buttons(void) art->draw= buttons_header_area_draw; BLI_addhead(&st->regiontypes, art); -#if 0 - /* regions: context */ - art= MEM_callocN(sizeof(ARegionType), "spacetype buttons region"); - art->regionid = RGN_TYPE_CHANNELS; - art->minsizey= CONTEXTY; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; - art->init= buttons_context_area_init; - art->draw= buttons_context_area_draw;; - art->listener= buttons_area_listener; - - BLI_addhead(&st->regiontypes, art); -#endif - BKE_spacetype_register(st); } diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 9aa02b45950..09008f8d2d1 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -46,15 +46,16 @@ #include "BLI_editVert.h" #include "BLI_rand.h" -#include "BKE_animsys.h" #include "BKE_action.h" +#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_fcurve.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_object.h" -#include "BKE_global.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_utildefines.h" @@ -250,6 +251,22 @@ static int graph_panel_drivers_poll(const bContext *C, PanelType *pt) return graph_panel_context(C, NULL, NULL); } +static void test_obpoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + id= CTX_data_main(C)->object.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ + return; + } + id= id->next; + } + *idpp= NULL; +} + /* driver settings for active F-Curve (only for 'Drivers' mode) */ static void graph_panel_drivers(const bContext *C, Panel *pa) { diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 4afa56582a2..cd02f2c6304 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -965,6 +965,107 @@ static void verify_logicbutton_func(bContext *C, void *data1, void *data2) } } +static void test_scriptpoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + id= CTX_data_main(C)->text.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + return; + } + id= id->next; + } + *idpp= NULL; +} + +static void test_actionpoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + id= CTX_data_main(C)->action.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + id_us_plus(id); + *idpp= id; + return; + } + id= id->next; + } + *idpp= NULL; +} + + +static void test_obpoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + id= CTX_data_main(C)->object.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ + return; + } + id= id->next; + } + *idpp= NULL; +} + +static void test_meshpoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= CTX_data_main(C)->mesh.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= NULL; +} + +static void test_matpoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= CTX_data_main(C)->mat.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= NULL; +} + +static void test_scenepoin_but(struct bContext *C, char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= CTX_data_main(C)->scene.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= NULL; +} /** * Draws a toggle for pulse mode, a frequency field and a toggle to invert -- cgit v1.2.3 From 6e4d4a8a1266834ac5ec7e079c734563caa14628 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 16 Sep 2009 19:47:58 +0000 Subject: fix bugs with file transfer --- release/io/netrender/master.py | 11 ++++++----- release/io/netrender/slave.py | 8 ++++---- release/io/netrender/utils.py | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 13e8b399d6c..29cec4e2232 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -323,8 +323,9 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if render_file: self.server.stats("", "Sending file to render node") - f = open(render_file.path, 'rb') + f = open(render_file.filepath, 'rb') + self.send_head() shutil.copyfileobj(f, self.wfile) f.close() @@ -444,7 +445,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): render_file = job.files_map.get(job_file, None) if render_file: - main_file = job.files[0] + main_file = job.files[0][0] # filename of the first file main_path, main_name = os.path.split(main_file) @@ -462,12 +463,12 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): f.close() del buf - render_file.path = file_path # set the new path + render_file.filepath = file_path # set the new path if job.testStart(): - self.send_head(headers=headers) + self.send_head(http.client.OK) else: - self.send_head(http.client.ACCEPTED, headers=headers) + self.send_head(http.client.ACCEPTED) else: # invalid file self.send_head(http.client.NO_CONTENT) else: # job not found diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index cec5439fc63..3a4e77abc54 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -26,12 +26,12 @@ def testCancel(conn, job_id): else: return False -def testFile(conn, JOB_PREFIX, file_path, main_path = None): +def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None): job_full_path = prefixPath(JOB_PREFIX, file_path, main_path) if not os.path.exists(job_full_path): temp_path = JOB_PREFIX + "slave.temp.blend" - conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id, "job-file":file_path}) + conn.request("GET", "file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path}) response = conn.getresponse() if response.status != http.client.OK: @@ -86,14 +86,14 @@ def render_slave(engine, scene): job_path = job.files[0][0] # data in files have format (path, start, end) main_path, main_file = os.path.split(job_path) - job_full_path = testFile(conn, JOB_PREFIX, job_path) + job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) print("Fullpath", job_full_path) print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) engine.update_stats("", "Render File", main_file, "for job", job.id) for file_path, start, end in job.files[1:]: print("\t", file_path) - testFile(conn, JOB_PREFIX, file_path, main_path) + testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) frame_args = [] diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index 72a29472748..46c2011b188 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -59,8 +59,8 @@ def prefixPath(prefix_directory, file_path, prefix_path): if not os.path.exists(full_path): p, n = os.path.split(full_path) - if main_path and p.startswith(main_path): - directory = prefix_directory + p[len(main_path):] + if prefix_path and p.startswith(prefix_path): + directory = prefix_directory + p[len(prefix_path):] full_path = directory + n if not os.path.exists(directory): os.mkdir(directory) -- cgit v1.2.3 From f26ac206c9acd9f1593cde2dc822c9e344507e97 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 16 Sep 2009 19:58:01 +0000 Subject: *Changed image field order property to enum, making it consistent with the corresponding render option *Tiny edit to image panel. --- source/blender/editors/space_image/image_buttons.c | 39 ++++++++++++---------- source/blender/makesrna/intern/rna_image.c | 17 ++++++---- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index f3607ed7276..78687958c60 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -1014,13 +1014,31 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn image_info(ima, ibuf, str); uiItemL(layout, str, 0); } - + + if(ima->source != IMA_SRC_GENERATED) { + uiItemS(layout); + + split= uiLayoutSplit(layout, 0); + + col= uiLayoutColumn(split, 0); + uiItemR(col, NULL, 0, &imaptr, "fields", 0); + row= uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, &imaptr, "field_order", UI_ITEM_R_EXPAND); + uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "fields")); + + col= uiLayoutColumn(split, 0); + uiItemR(col, NULL, 0, &imaptr, "antialias", 0); + uiItemR(col, NULL, 0, &imaptr, "premultiply", 0); + } + if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + uiItemS(layout); + split= uiLayoutSplit(layout, 0); col= uiLayoutColumn(split, 0); - sprintf(str, "(%d) Frames:", iuser->framenr); + sprintf(str, "(%d) Frames", iuser->framenr); row= uiLayoutRow(col, 1); uiItemR(col, str, 0, userptr, "frames", 0); if(ima->anim) { @@ -1048,22 +1066,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn uiItemR(col, NULL, 0, &imaptr, "generated_type", UI_ITEM_R_EXPAND); } - if(ima->source != IMA_SRC_GENERATED) { - uiItemS(layout); - - split= uiLayoutSplit(layout, 0); - - col= uiLayoutColumn(split, 0); - uiItemR(col, NULL, 0, &imaptr, "fields", 0); - row= uiLayoutRow(col, 0); - uiItemR(row, "Odd", 0, &imaptr, "odd_fields", 0); - uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "fields")); - - col= uiLayoutColumn(split, 0); - uiItemR(col, NULL, 0, &imaptr, "antialias", 0); - uiItemR(col, NULL, 0, &imaptr, "premultiply", 0); - } - } + } uiBlockSetNFunc(block, NULL, NULL, NULL); } diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index ad96eaa99ad..8614e6f4ef3 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -217,6 +217,10 @@ static void rna_def_image(BlenderRNA *brna) {0, "UV", 0, "UV Coordinates", "Use UV coordinates for mapping the image"}, {IMA_REFLECT, "REFLECTION", 0, "Reflection", "Use reflection mapping for mapping the image"}, {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_field_order_items[]= { + {0, "EVEN", 0, "Even", "Even Fields first"}, + {IMA_STD_FIELD, "Odd", 0, "Odd", "Odd Fields first"}, + {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Image", "ID"); RNA_def_struct_ui_text(srna, "Image", "Image datablock referencing an external or packed image."); @@ -242,18 +246,19 @@ static void rna_def_image(BlenderRNA *brna) prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "packedfile"); RNA_def_property_ui_text(prop, "Packed File", ""); - + + prop= RNA_def_property(srna, "field_order", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_field_order_items); + RNA_def_property_ui_text(prop, "Field Order", "Order of video fields. Select which lines are displayed first."); + RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); + /* booleans */ prop= RNA_def_property(srna, "fields", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS); RNA_def_property_ui_text(prop, "Fields", "Use fields of the image."); RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_fields_update"); - prop= RNA_def_property(srna, "odd_fields", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_STD_FIELD); - RNA_def_property_ui_text(prop, "Odd Fields", "Standard field toggle."); - RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update"); - prop= RNA_def_property(srna, "antialias", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANTIALI); RNA_def_property_ui_text(prop, "Anti-alias", "Toggles image anti-aliasing, only works with solid colors"); -- cgit v1.2.3 From 90d8088e53293d1f36d9063d5898dd8bd3ddf878 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 16 Sep 2009 20:07:05 +0000 Subject: 2.5: Test Commit, converted Filter Composite Node to use layout engine. :) Will do other Nodes in the next few days. --- source/blender/editors/space_node/drawnode.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 494a68fc918..466d1aaa281 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1449,16 +1449,7 @@ static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_filter(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - uiBut *bt; - - /* blend type */ - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Soften %x0|Sharpen %x1|Laplace %x2|Sobel %x3|Prewitt %x4|Kirsch %x5|Shadow %x6", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); + uiItemR(layout, "", 0, ptr, "filter_type", 0); } static void node_composit_buts_flip(uiLayout *layout, PointerRNA *ptr) -- cgit v1.2.3 From 591a30dab030a90218f37a0c4a8c4474663c7155 Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Wed, 16 Sep 2009 22:12:23 +0000 Subject: bugfix for LineIntersectLine() - was imperfect calculation for points marking shortest distance for non-crossing lines in 3d --- source/blender/blenlib/intern/arithb.c | 2 +- source/blender/python/generic/Mathutils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 339a7250295..b7f56e6ca1c 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -4715,7 +4715,7 @@ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float VecSubf(c, v3t, v1); VecSubf(a, v2, v1); - VecSubf(b, v4t, v3); + VecSubf(b, v4t, v3t); Crossf(ab, a, b); Crossf(cb, c, b); diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c index d354aea6614..431f1987383 100644 --- a/source/blender/python/generic/Mathutils.c +++ b/source/blender/python/generic/Mathutils.c @@ -912,7 +912,7 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" ); return NULL; } - if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) { + if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) { PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); return NULL; } -- cgit v1.2.3 From 00f9bf51d6bd0f7dc3495b284c6c4872b497bc3c Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Wed, 16 Sep 2009 22:13:48 +0000 Subject: bugfix for LineIntersectLine() - was imperfect calculation for points marking shortest distance for non-crossing lines in 3d --- source/blender/blenlib/intern/arithb.c | 2 +- source/blender/python/api2_2x/Mathutils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index e7a31e37581..2f0af2cf903 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -4316,7 +4316,7 @@ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float VecSubf(c, v3t, v1); VecSubf(a, v2, v1); - VecSubf(b, v4t, v3); + VecSubf(b, v4t, v3t); Crossf(ab, a, b); Crossf(cb, c, b); diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index 3ffc8662cc9..3b4c63352a0 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -1360,7 +1360,7 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" ); return NULL; } - if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) { + if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) { PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); return NULL; } -- cgit v1.2.3 From 4a15b40c37fc36a041c2d20dbcadbcf9d258c583 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 16 Sep 2009 22:27:27 +0000 Subject: * fix compilation on osx --- intern/ghost/intern/GHOST_SystemCarbon.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp index fb1b96fcbc7..57d6f6c06cc 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.cpp +++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp @@ -788,21 +788,21 @@ OSStatus GHOST_SystemCarbon::handleTabletEvent(EventRef event) switch(tabletProximityRecord.pointerType) { case 1: /* stylus */ - ct.Active = 1; + ct.Active = GHOST_kTabletModeStylus; break; case 2: /* puck, not supported so far */ - ct.Active = 0; + ct.Active = GHOST_kTabletModeNone; break; case 3: /* eraser */ - ct.Active = 2; + ct.Active = GHOST_kTabletModeEraser; break; default: - ct.Active = 0; + ct.Active = GHOST_kTabletModeNone; break; } } else { // pointer is leaving - return to mouse - ct.Active = 0; + ct.Active = GHOST_kTabletModeNone; } } } -- cgit v1.2.3 From 1934ee422a47f7dcc5e63cfff5811873798561d8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 Sep 2009 00:14:47 +0000 Subject: rna function api was overwriting useful errors with keyword errors. fix some missing checks in the python interface. --- release/ui/buttons_data_mesh.py | 3 ++- release/ui/buttons_material.py | 5 +++-- source/blender/python/intern/bpy_rna.c | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py index 33b3960b381..8796d7a46a8 100644 --- a/release/ui/buttons_data_mesh.py +++ b/release/ui/buttons_data_mesh.py @@ -102,7 +102,8 @@ class DATA_PT_shape_keys(DataButtonsPanel): kb = ob.active_shape_key row = layout.row() - row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) + if key: # XXX - looks crappy + row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) col = row.column() diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py index 9f1c216c36b..8b58c2b8953 100644 --- a/release/ui/buttons_material.py +++ b/release/ui/buttons_material.py @@ -65,8 +65,9 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel): elif mat: split.template_ID(space, "pin_id") split.itemS() - - layout.itemR(mat, "type", expand=True) + + if mat: + layout.itemR(mat, "type", expand=True) class MATERIAL_PT_shading(MaterialButtonsPanel): __label__ = "Shading" diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 65c701c0041..50e32f34594 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1994,8 +1994,10 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw) /* Check if we gave args that dont exist in the function * printing the error is slow but it should only happen when developing. - * the if below is quick, checking if it passed less keyword args then we gave */ - if(kw && (PyDict_Size(kw) > kw_tot)) { + * the if below is quick, checking if it passed less keyword args then we gave. + * (Dont overwrite the error if we have one, otherwise can skip important messages and confuse with args) + */ + if(err == 0 && kw && (PyDict_Size(kw) > kw_tot)) { PyObject *key, *value; Py_ssize_t pos = 0; -- cgit v1.2.3 From 68f4465cdc0925ec22584e404a895982f6a74de0 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 17 Sep 2009 10:14:56 +0000 Subject: 2.5 - Animation Utility Function Added a utility function to check which transforms for an object or bone are animated, returning these as bitflags and/or optionally retrieving the relevant F-Curves too. Beware that this method may not be working correctly yet, but it shouldn't hurt anyone in the meantime :) Also, split RNA-path building function up into a version which only creates the path up to the given struct, with the other parts being added later. --- source/blender/blenkernel/BKE_action.h | 30 ++++++++- source/blender/blenkernel/intern/action.c | 100 +++++++++++++++++++++++++++- source/blender/blenkernel/intern/anim_sys.c | 2 +- source/blender/blenlib/BLI_listbase.h | 4 ++ source/blender/blenlib/intern/listbase.c | 14 ++++ source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_access.c | 21 ++++-- 7 files changed, 163 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 4724ee19aaa..f079cc08281 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -51,7 +51,7 @@ struct ID; extern "C" { #endif -/* Action API ----------------- */ +/* Action Lib Stuff ----------------- */ /* Allocate a new bAction with the given name */ struct bAction *add_empty_action(const char name[]); @@ -65,6 +65,31 @@ void free_action(struct bAction *act); // XXX is this needed? void make_local_action(struct bAction *act); + +/* Action API ----------------- */ + +/* types of transforms applied to the given item + * - these are the return falgs for action_get_item_transforms() + */ +typedef enum eAction_TransformFlags { + /* location */ + ACT_TRANS_LOC = (1<<0), + /* rotation */ + ACT_TRANS_ROT = (1<<1), + /* scaling */ + ACT_TRANS_SCALE = (1<<2), + + /* all flags */ + ACT_TRANS_ALL = (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE), +} eAction_TransformFlags; + +/* Return flags indicating which transforms the given object/posechannel has + * - if 'curves' is provided, a list of links to these curves are also returned + * whose nodes WILL NEED FREEING + */ +short action_get_item_transforms(struct bAction *act, struct Object *ob, struct bPoseChannel *pchan, ListBase *curves); + + /* Some kind of bounding box operation on the action */ void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers); @@ -73,6 +98,9 @@ short action_has_motion(const struct bAction *act); /* Action Groups API ----------------- */ +/* Get the active action-group for an Action */ +struct bActionGroup *get_active_actiongroup(struct bAction *act); + /* Make the given Action Group the active one */ void set_active_action_group(struct bAction *act, struct bActionGroup *agrp, short select); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 2bde61818bf..1ff5d9b5c01 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -212,9 +212,10 @@ bAction *copy_action (bAction *src) return dst; } +/* *************** Action Groups *************** */ /* Get the active action-group for an Action */ -static bActionGroup *get_active_actiongroup (bAction *act) +bActionGroup *get_active_actiongroup (bAction *act) { bActionGroup *agrp= NULL; @@ -404,7 +405,7 @@ bActionGroup *action_groups_find_named (bAction *act, const char name[]) return NULL; } -/* ************************ Pose channels *************** */ +/* *************** Pose channels *************** */ /* usually used within a loop, so we got a N^2 slowdown */ bPoseChannel *get_pose_channel(const bPose *pose, const char *name) @@ -818,7 +819,7 @@ void pose_remove_group (Object *ob) } } -/* ************** time ****************** */ +/* ************** F-Curve Utilities for Actions ****************** */ /* Check if the given action has any keyframes */ short action_has_motion(const bAction *act) @@ -916,6 +917,99 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ } } + +/* Return flags indicating which transforms the given object/posechannel has + * - if 'curves' is provided, a list of links to these curves are also returned + */ +short action_get_item_transforms (bAction *act, Object *ob, bPoseChannel *pchan, ListBase *curves) +{ + PointerRNA ptr; + FCurve *fcu; + char *basePath=NULL; + short flags=0; + + /* build PointerRNA from provided data to obtain the paths to use */ + if (pchan) + RNA_pointer_create((ID *)ob, &RNA_PoseChannel, pchan, &ptr); + else if (ob) + RNA_id_pointer_create((ID *)ob, &ptr); + else + return 0; + + /* get the basic path to the properties of interest */ + basePath= RNA_path_from_ID_to_struct(&ptr); + if (basePath == NULL) + return 0; + + /* search F-Curves for the given properties + * - we cannot use the groups, since they may not be grouped in that way... + */ + for (fcu= act->curves.first; fcu; fcu= fcu->next) { + char *bPtr=NULL, *pPtr=NULL; + + /* if enough flags have been found, we can stop checking unless we're also getting the curves */ + if ((flags == ACT_TRANS_ALL) && (curves == NULL)) + break; + + /* just in case... */ + if (fcu->rna_path == NULL) + continue; + + /* step 1: check for matching base path */ + bPtr= strstr(fcu->rna_path, basePath); + + if (bPtr) { + /* step 2: check for some property with transforms + * - to speed things up, only check for the ones not yet found + * unless we're getting the curves too + * - if we're getting the curves, the BLI_genericNodeN() creates a LinkData + * node wrapping the F-Curve, which then gets added to the list + * - once a match has been found, the curve cannot possibly be any other one + */ + if ((curves) || (flags & ACT_TRANS_LOC) == 0) { + pPtr= strstr(fcu->rna_path, "location"); + if ((pPtr) && (pPtr >= bPtr)) { + flags |= ACT_TRANS_LOC; + + if (curves) + BLI_addtail(curves, BLI_genericNodeN(fcu)); + continue; + } + } + + if ((curves) || (flags & ACT_TRANS_SCALE) == 0) { + pPtr= strstr(fcu->rna_path, "scale"); + if ((pPtr) && (pPtr >= bPtr)) { + flags |= ACT_TRANS_SCALE; + + if (curves) + BLI_addtail(curves, BLI_genericNodeN(fcu)); + continue; + } + } + + if ((curves) || (flags & ACT_TRANS_ROT) == 0) { + pPtr= strstr(fcu->rna_path, "rotation"); + if ((pPtr) && (pPtr >= bPtr)) { + flags |= ACT_TRANS_ROT; + + if (curves) + BLI_addtail(curves, BLI_genericNodeN(fcu)); + continue; + } + } + } + } + + /* free basePath */ + MEM_freeN(basePath); + + /* return flags found */ + return flags; +} + +/* ************** Pose Management Tools ****************** */ + /* Copy the data from the action-pose (src) into the pose */ /* both args are assumed to be valid */ /* exported to game engine */ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 643aa6bc779..522297da1d7 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1485,7 +1485,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) } /* nodes */ - // TODO... + EVAL_ANIM_IDS(main->nodetree.first, ADT_RECALC_ANIM); /* textures */ EVAL_ANIM_IDS(main->tex.first, ADT_RECALC_ANIM); diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index d0b106b59c3..21b4c83bd88 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -34,6 +34,7 @@ //#include "DNA_listbase.h" struct ListBase; +struct LinkData; #ifdef __cplusplus extern "C" { @@ -56,6 +57,9 @@ int BLI_countlist(struct ListBase *listbase); void BLI_freelinkN(struct ListBase *listbase, void *vlink); void BLI_duplicatelist(struct ListBase *list1, struct ListBase *list2); /* copy from 2 to 1 */ +/* create a generic list node containing link to provided data */ +struct LinkData *BLI_genericNodeN(void *data); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 3194593374f..b3a4722d6d9 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -359,3 +359,17 @@ void BLI_duplicatelist(ListBase *list1, ListBase *list2) /* copy from 2 to 1 */ } } +/* create a generic list node containing link to provided data */ +LinkData *BLI_genericNodeN (void *data) +{ + LinkData *ld; + + if (data == NULL) + return NULL; + + /* create new link, and make it hold the given data */ + ld= MEM_callocN(sizeof(LinkData), "BLI_genericNodeN()"); + ld->data= data; + + return ld; +} diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 40f640473db..b1f5292f9d4 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -692,6 +692,7 @@ char *RNA_path_back(const char *path); int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop); +char *RNA_path_from_ID_to_struct(PointerRNA *ptr); char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop); #if 0 diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 738d52bfbcd..55893b42a92 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2387,12 +2387,11 @@ char *RNA_path_back(const char *path) return result; } -char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) +char *RNA_path_from_ID_to_struct(PointerRNA *ptr) { - char *ptrpath=NULL, *path; - const char *propname; + char *ptrpath=NULL; - if(!ptr->id.data || !ptr->data || !prop) + if(!ptr->id.data || !ptr->data) return NULL; if(!RNA_struct_is_ID(ptr->type)) { @@ -2418,6 +2417,20 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) else return NULL; } + + return ptrpath; +} + +char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *propname; + char *ptrpath, *path; + + if(!ptr->id.data || !ptr->data || !prop) + return NULL; + + /* path from ID to the struct holding this property */ + ptrpath= RNA_path_from_ID_to_struct(ptr); propname= RNA_property_identifier(prop); -- cgit v1.2.3 From a911fd88af5ffb2a377ade4e14b918f138ecaee2 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 17 Sep 2009 11:17:49 +0000 Subject: Update MSVC project files. --- projectfiles_vc9/blender/editors/ED_editors.vcproj | 2 +- projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index 81d80436a00..948a26c49b5 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -379,7 +379,7 @@ > diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj index 8dd1982deca..a9d78d8b69a 100644 --- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj +++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj @@ -810,6 +810,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_text.c" > + + -- cgit v1.2.3 From 5e609c9c52c76c26e890b676184ed6b52c82b393 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 17 Sep 2009 12:56:16 +0000 Subject: * converted raytrace visibility test on meshlaplacian.c to new raytrace API I need test scenes and test instructions to make sure this is ok, since i have no idea how to test this feature. --- source/blender/editors/armature/meshlaplacian.c | 40 +++++++++++--------- source/blender/render/extern/include/RE_raytrace.h | 22 +++++++++++ source/blender/render/intern/include/rayobject.h | 19 ---------- source/blender/render/intern/source/rayobject.c | 44 ++++++++++++++++------ 4 files changed, 78 insertions(+), 47 deletions(-) diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 7f95fb47d61..c994f7789a0 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -30,7 +30,6 @@ #include #include -#include #include "MEM_guardedalloc.h" @@ -107,7 +106,8 @@ struct LaplacianSystem { float *mindist; /* minimum distance to a bone for all vertices */ RayObject *raytree; /* ray tracing acceleration structure */ - MFace **vface; /* a face that the vertex belongs to */ + RayFace *faces; /* faces to add to the ray tracing struture */ + MFace **vface; /* a face that the vertex belongs to */ } heat; #ifdef RIGID_DEFORM @@ -398,14 +398,25 @@ float laplacian_system_get_solution(int v) static void heat_ray_tree_create(LaplacianSystem *sys) { Mesh *me = sys->heat.mesh; - MFace *mface; int a; - assert(0); //TODO - //sys->heat.raytree = RE_rayobject_mesh_create(me, me); - + sys->heat.raytree = RE_rayobject_vbvh_create(me->totface); + sys->heat.faces = MEM_callocN(sizeof(RayFace)*me->totface, "Heat RayFaces"); sys->heat.vface = MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces"); - for(a=0, mface=me->mface; atotface; a++, mface++) { + + for(a=0; atotface; a++) { + + MFace *mface = me->mface+a; + RayFace *rayface = sys->heat.faces+a; + + RayObject *obj = RE_rayface_from_coords( + rayface, me, mface, + sys->heat.verts[mface->v1], sys->heat.verts[mface->v2], + sys->heat.verts[mface->v3], mface->v4 ? sys->heat.verts[mface->v4] : 0 + ); + RE_rayobject_add(sys->heat.raytree, obj); + + //Setup inverse pointers to use on isect.orig sys->heat.vface[mface->v1]= mface; sys->heat.vface[mface->v2]= mface; sys->heat.vface[mface->v3]= mface; @@ -420,7 +431,6 @@ static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone) float end[3]; int visible; - assert( 0 ); mface= sys->heat.vface[vertex]; if(!mface) return 1; @@ -429,23 +439,18 @@ static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone) memset(&isec, 0, sizeof(isec)); isec.mode= RE_RAY_SHADOW; isec.lay= -1; + isec.orig.ob = sys->heat.mesh; isec.orig.face = mface; isec.skip = RE_SKIP_CULLFACE; + VECCOPY(isec.start, sys->heat.verts[vertex]); PclosestVL3Dfl(end, isec.start, sys->heat.root[bone], sys->heat.tip[bone]); VECSUB(isec.vec, end, isec.start); - isec.labda = 1.0f; + isec.labda = 1.0f - 1e-5; + VECADDFAC( isec.start, isec.start, isec.vec, 1e-5); -#if 0 - TODO - /* add an extra offset to the start position to avoid self intersection */ - VECCOPY(dir, isec.vec); - Normalize(dir); - VecMulf(dir, 1e-5); - VecAddf(isec.start, isec.start, dir); -#endif visible= !RE_rayobject_raycast(sys->heat.raytree, &isec); return visible; @@ -712,6 +717,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, RE_rayobject_free(sys->heat.raytree); MEM_freeN(sys->heat.vface); + MEM_freeN(sys->heat.faces); MEM_freeN(sys->heat.mindist); MEM_freeN(sys->heat.H); diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index af3ea8e2ac0..fe490461da0 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -79,6 +79,28 @@ RayObject* RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_svbvh.c * RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ +/* + * This ray object represents a triangle or a quad face. + * All data needed to realize intersection is "localy" available. + */ +typedef struct RayFace +{ + float v1[4], v2[4], v3[4], v4[3]; + int quad; + void *ob; + void *face; + +} RayFace; + +#define RE_rayface_isQuad(a) ((a)->quad) +struct VlakRen; +struct ObjectInstanceRen; + +RayObject* RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); +RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *co1, float *co2, float *co3, float *co4); + + + typedef struct LCTSHint LCTSHint; struct LCTSHint { diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 19608fba262..dbd68fe8b8b 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -102,25 +102,6 @@ typedef struct RayVlak } RayVlak; */ -/* - * This ray object represents a triangle or a quad face. - * All data needed to realize intersection is "localy" available. - */ -typedef struct RayFace -{ - float v1[4], v2[4], v3[4], v4[3]; - int quad; - void *ob; - void *face; - -} RayFace; - -#define RE_rayface_isQuad(a) ((a)->quad) -/* Loads a VlakRen on a RayFace */ -void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr); - - - /* * This rayobject represents a generic object. With it's own callbacks for raytrace operations. * It's suitable to implement things like LOD. diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c index 4bd8a12aa01..df457a37123 100644 --- a/source/blender/render/intern/source/rayobject.c +++ b/source/blender/render/intern/source/rayobject.c @@ -165,6 +165,17 @@ static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen return 0; } +static int rayface_check_cullface(RayFace *face, Isect *is) +{ + float nor[3]; + + /* don't intersect if the ray faces along the face normal */ + if(face->quad) CalcNormFloat4(face->v1, face->v2, face->v3, face->v4, nor); + else CalcNormFloat(face->v1, face->v2, face->v3, nor); + + return (INPR(nor, is->vec) < 0); +} + /* ray - triangle or quad intersection */ /* this function shall only modify Isect if it detects an hit */ static int intersect_rayface(RayFace *face, Isect *is) @@ -188,6 +199,11 @@ static int intersect_rayface(RayFace *face, Isect *is) if(vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) return 0; } + if(is->skip & RE_SKIP_CULLFACE) + { + if(rayface_check_cullface(face, is) == 0) + return 0; + } RE_RC_COUNT(is->raycounter->faces.test); @@ -319,26 +335,32 @@ static int intersect_rayface(RayFace *face, Isect *is) return 0; } -void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr) +RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr) +{ + return RE_rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0 ); +} + +RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) { - VECCOPY(face->v1, vlr->v1->co); - VECCOPY(face->v2, vlr->v2->co); - VECCOPY(face->v3, vlr->v3->co); - if(vlr->v4) + rayface->ob = ob; + rayface->face = face; + + VECCOPY(rayface->v1, v1); + VECCOPY(rayface->v2, v2); + VECCOPY(rayface->v3, v3); + if(v4) { - VECCOPY(face->v4, vlr->v4->co); - face->quad = 1; + VECCOPY(rayface->v4, v4); + rayface->quad = 1; } else { - face->quad = 0; + rayface->quad = 0; } - face->ob = obi; - face->face = vlr; + return RE_rayobject_unalignRayFace(rayface); } - int RE_rayobject_raycast(RayObject *r, Isect *isec) { int i; -- cgit v1.2.3 From 7783c286b9ac3622972ba979f80789aee8fabaed Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Sep 2009 14:35:08 +0000 Subject: UI: fix display of shape key list to show with no items, list template should also accept None. --- release/ui/buttons_data_mesh.py | 3 +-- source/blender/makesrna/intern/rna_ui_api.c | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py index 8796d7a46a8..33b3960b381 100644 --- a/release/ui/buttons_data_mesh.py +++ b/release/ui/buttons_data_mesh.py @@ -102,8 +102,7 @@ class DATA_PT_shape_keys(DataButtonsPanel): kb = ob.active_shape_key row = layout.row() - if key: # XXX - looks crappy - row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) + row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) col = row.column() diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 3110e631a65..17846651c3b 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -301,7 +301,10 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_list", "uiTemplateList"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - api_ui_item_rna_common(func); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_pointer(func, "active_data", "AnyType", "", "Data from which to take property for the active element."); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element."); -- cgit v1.2.3 From 09652d8c05f30015518205ea6bb7ac0ee3d3745f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Sep 2009 14:37:08 +0000 Subject: Fix #19371: vertex group dropdown crash, own fault in commit yesterday. --- source/blender/editors/interface/interface_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index dbf5669b326..246058ceacc 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -246,7 +246,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) if(but->func || but->funcN || block->handle_func || but->rename_func || (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) { after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc"); - if(ELEM(but, but->func_arg1, but->func_arg2)) { + if(but->func && ELEM(but, but->func_arg1, but->func_arg2)) { /* exception, this will crash due to removed button otherwise */ but->func(C, but->func_arg1, but->func_arg2); } -- cgit v1.2.3 From fbbda4c06e6ae642e5702bb39aff92a0ea007a75 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Sep 2009 14:46:22 +0000 Subject: Warning fixes for blenkernel and editors. Note sure what to do with this one, and personally think we should avoid using macros for this kind of thing: V_GROW(edges); source/blender/editors/mesh/loopcut.c:232: warning: value computed is not used --- source/blender/blenkernel/intern/fcurve.c | 2 ++ source/blender/blenkernel/intern/implicit.c | 4 +++- source/blender/blenkernel/intern/modifier.c | 15 ++------------- source/blender/blenkernel/intern/object.c | 6 +++--- source/blender/blenkernel/intern/particle.c | 3 ++- source/blender/blenkernel/intern/particle_system.c | 1 - source/blender/blenkernel/intern/text.c | 6 ++---- source/blender/blenkernel/intern/writeffmpeg.c | 4 ++-- source/blender/editors/mesh/editmesh_tools.c | 5 ++--- source/blender/editors/mesh/loopcut.c | 4 +--- source/blender/editors/object/object_select.c | 2 ++ source/blender/editors/physics/editparticle.c | 1 - source/blender/editors/preview/previewrender.c | 1 - source/blender/editors/space_image/image_draw.c | 2 +- source/blender/editors/space_view3d/drawvolume.c | 1 - source/blender/editors/space_view3d/view3d_buttons.c | 4 ++-- source/blender/makesrna/intern/rna_pose.c | 2 ++ source/blender/render/intern/source/volumetric.c | 4 +--- 18 files changed, 27 insertions(+), 40 deletions(-) diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 54d2f85457f..f7f79e9772f 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1026,6 +1026,7 @@ static void berekeny (float f1, float f2, float f3, float f4, float *o, int b) } } +#if 0 static void berekenx (float *f, float *o, int b) { float t, c0, c1, c2, c3; @@ -1041,6 +1042,7 @@ static void berekenx (float *f, float *o, int b) o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3; } } +#endif /* -------------------------- */ diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 956a5851827..ae2acd6aef7 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -496,6 +496,7 @@ DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float fro // SPARSE SYMMETRIC big matrix with 3x3 matrix entries /////////////////////////// /* printf a big matrix on console: for debug output */ +#if 0 static void print_bfmatrix(fmatrix3x3 *m3) { unsigned int i = 0; @@ -505,6 +506,8 @@ static void print_bfmatrix(fmatrix3x3 *m3) print_fmatrix(m3[i].m); } } +#endif + /* create big matrix */ DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs) { @@ -1417,7 +1420,6 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX, int i = 0; int j = 0; int k = 0; - lfVector temp; INIT_MINMAX(gmin, gmax); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 4f2264a052f..c64c48b9ce7 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -8503,6 +8503,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->initData = smoothModifier_initData; mti->copyData = smoothModifier_copyData; mti->requiredDataMask = smoothModifier_requiredDataMask; + mti->isDisabled = smoothModifier_isDisabled; mti->deformVerts = smoothModifier_deformVerts; mti->deformVertsEM = smoothModifier_deformVertsEM; @@ -8513,6 +8514,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->initData = castModifier_initData; mti->copyData = castModifier_copyData; mti->requiredDataMask = castModifier_requiredDataMask; + mti->isDisabled = castModifier_isDisabled; mti->foreachObjectLink = castModifier_foreachObjectLink; mti->updateDepgraph = castModifier_updateDepgraph; mti->deformVerts = castModifier_deformVerts; @@ -9137,19 +9139,6 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek) return i; } -static int modifiers_usesPointCache(Object *ob) -{ - ModifierData *md = ob->modifiers.first; - - for (; md; md=md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); - if (mti->flags & eModifierTypeFlag_UsesPointCache) { - return 1; - } - } - return 0; -} - void modifier_freeTemporaryData(ModifierData *md) { if(md->type == eModifierType_Armature) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ed4e82cb3c6..35514e9697e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2562,7 +2562,7 @@ int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3 static int pc_cmp(void *a, void *b) { LinkData *ad = a, *bd = b; - if((int)ad->data > (int)bd->data) + if(GET_INT_FROM_POINTER(ad->data) > GET_INT_FROM_POINTER(bd->data)) return 1; else return 0; } @@ -2576,14 +2576,14 @@ int object_insert_ptcache(Object *ob) for(link=ob->pc_ids.first, i = 0; link; link=link->next, i++) { - int index =(int)link->data; + int index = GET_INT_FROM_POINTER(link->data); if(i < index) break; } link = MEM_callocN(sizeof(LinkData), "PCLink"); - link->data = (void *)i; + link->data = SET_INT_IN_POINTER(i); BLI_addtail(&ob->pc_ids, link); return i; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 2d3e3210afc..cce18e99157 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -81,7 +81,6 @@ #include "RE_render_ext.h" -static void key_from_object(Object *ob, ParticleKey *key); static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float *fuv, float *orco, ParticleTexture *ptex, int event); static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, @@ -3039,6 +3038,7 @@ void psys_key_to_object(Object *ob, ParticleKey *key, float imat[][4]){ VECSUB(key->vel,key->vel,key->co); QuatMul(key->rot,q,key->rot); } +#if 0 static void key_from_object(Object *ob, ParticleKey *key){ float q[4]; @@ -3051,6 +3051,7 @@ static void key_from_object(Object *ob, ParticleKey *key){ VECSUB(key->vel,key->vel,key->co); QuatMul(key->rot,q,key->rot); } +#endif static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4]) { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 72b580a4543..26d23399316 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -122,7 +122,6 @@ static int get_current_display_percentage(ParticleSystem *psys) void psys_reset(ParticleSystem *psys, int mode) { - ParticleSettings *part= psys->part; PARTICLE_P; if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) { diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 350b0acba9d..270cd873ff5 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -596,17 +596,15 @@ static TextLine *txt_new_line(char *str) return tmp; } -static TextLine *txt_new_linen(char *str, int n) +static TextLine *txt_new_linen(const char *str, int n) { TextLine *tmp; - if(!str) str= ""; - tmp= (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); tmp->line= MEM_mallocN(n+1, "textline_string"); tmp->format= NULL; - BLI_strncpy(tmp->line, str, n+1); + BLI_strncpy(tmp->line, (str)? str: "", n+1); tmp->len= strlen(tmp->line); tmp->next= tmp->prev= NULL; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 9e86dcbe491..a90924055b3 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -148,7 +148,7 @@ static int write_audio_frame(void) #else pkt.pts = c->coded_frame->pts; #endif - fprintf(stderr, "Audio Frame PTS: %lld\n", pkt.pts); + fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts); pkt.stream_index = audio_stream->index; pkt.flags |= PKT_FLAG_KEY; @@ -265,7 +265,7 @@ static void write_video_frame(RenderData *rd, AVFrame* frame) #else packet.pts = c->coded_frame->pts; #endif - fprintf(stderr, "Video Frame PTS: %lld\n", packet.pts); + fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts); } else { fprintf(stderr, "Video Frame PTS: not set\n"); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 7698faf3178..1d2b97b3f29 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -482,11 +482,10 @@ int removedoublesflag(EditMesh *em, short flag, short automerge, float limit) / static int removedoublesflag_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); - ToolSettings *ts= CTX_data_tool_settings(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - char msg[100]; + /*char msg[100]; - int cnt = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); + int cnt = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));*/ /*XXX this messes up last operator panel if(cnt) diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index dfdb713d345..f83ab04d785 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -129,7 +129,7 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select) float (*edges)[2][3] = NULL; V_DYNDECLARE(edges); float co[2][3]; - int looking=1, i, j=0, tot=0; + int looking=1, i, tot=0; if (!startedge) return; @@ -318,7 +318,6 @@ static int ringsel_cancel (bContext *C, wmOperator *op) static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - ScrArea *sa = CTX_wm_area(C); tringselOpData *lcd; EditEdge *edge; int dist = 75; @@ -347,7 +346,6 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - ScrArea *sa = CTX_wm_area(C); tringselOpData *lcd; EditEdge *edge; int dist = 75; diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 432aaf2d2cb..98603ee843a 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -30,6 +30,8 @@ #include #include +#include "MEM_guardedalloc.h" + #include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_modifier_types.h" diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 5acdcb40613..85ec215a326 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -3911,7 +3911,6 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) { Scene *scene= CTX_data_scene(C); ParticleEditSettings *pset=PE_settings(scene); - PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C)); uiPopupMenu *pup; uiLayout *layout; diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index 710ac3d6553..7a4cc1c7865 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -635,7 +635,6 @@ void BIF_view3d_previewrender_clear(ScrArea *sa) /* afterqueue call */ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa) { - bContext *C= NULL; View3D *v3d= sa->spacedata.first; RegionView3D *rv3d= NULL; // XXX Render *re; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index cf9bac1ebee..fa736a29ce8 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -541,7 +541,7 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) } else { /* assume that UI_view2d_restore(C) has been called... */ - SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); + //SpaceImage *sima= (SpaceImage *)CTX_wm_space_data(C); /* draw grease-pencil ('screen' strokes) */ //if (sima->flag & SI_DISPGP) diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 0bdc65b5461..ef3627e2b12 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -169,7 +169,6 @@ static int larger_pow2(int n) void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) { - Object *ob = base->object; RegionView3D *rv3d= ar->regiondata; float viewnormal[3]; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 7d4e3337fe3..286b0ca0898 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -476,6 +476,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, } } +#if 0 /* assumes armature active */ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev) { @@ -494,10 +495,10 @@ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev) ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c } } +#endif static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim) { - uiBut *but; bArmature *arm; bPoseChannel *pchan; Bone *bone= NULL; @@ -586,7 +587,6 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float { bArmature *arm= ob->data; EditBone *ebone; - uiBut *but; TransformProperties *tfp= v3d->properties_storage; ebone= arm->edbo->first; diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index b5c0716bed1..cb566fb473f 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -323,6 +323,7 @@ static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, in *max= MAX2(0, *max); } +#if 0 static void rna_pose_bgroup_name_index_get(PointerRNA *ptr, char *value, int index) { bPose *pose= (bPose*)ptr->data; @@ -373,6 +374,7 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r BLI_strncpy(result, "", maxlen); } +#endif #else diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index bc425c8a1a3..b2692c25b99 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -422,7 +422,6 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float * float hitco[3], *atten_co; float p; float scatter_fac; - float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE); if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return; if ((lar->lay & shi->lay)==0) return; @@ -683,7 +682,6 @@ void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct float hitco[3]; float tr[3] = {1.0,1.0,1.0}; Isect is; - float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE); float *startco, *endco; float density=0.f; @@ -749,4 +747,4 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) shi->mat = mat_backup; shi->obi = obi_backup; shi->obr = obi_backup->obr; -} \ No newline at end of file +} -- cgit v1.2.3 From 91e5ac872e281c1bbf1719cc1ae5d29a8bf129ba Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 17 Sep 2009 15:06:03 +0000 Subject: Wrapped some more Nodes: * Composite: Flip, Crop, Map UV, Lens Distortion. --- source/blender/editors/space_node/drawnode.c | 97 +++++++-------------------- source/blender/makesrna/intern/rna_nodetree.c | 5 +- 2 files changed, 25 insertions(+), 77 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 466d1aaa281..9cfae9a7ef5 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1409,27 +1409,19 @@ static void node_composit_buts_tonemap(uiLayout *layout, PointerRNA *ptr) /* qdn: lens distortion node */ static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiLayout *row, *col; + bNode *node= ptr->data; - rctf *butr= &node->butr; NodeLensDist *nld = node->storage; - short dy = butr->ymin + 19, dx = butr->xmax - butr->xmin; - uiBlockBeginAlign(block); - uiDefButS(block, TOG, B_NODE_EXEC, "Projector", - butr->xmin, dy, dx, 19, - &nld->proj, 0, 0, 0, 0, - "Enable/disable projector mode, effect is applied in horizontal direction only"); + + col= uiLayoutColumn(layout, 1); + + uiItemR(col, NULL, 0, ptr, "projector", UI_ITEM_R_TOGGLE); if (!nld->proj) { - uiDefButS(block, TOG, B_NODE_EXEC, "Jitter", - butr->xmin, dy-19, dx/2, 19, - &nld->jit, 0, 0, 0, 0, - "Enable/disable jittering, faster, but also noisier"); - uiDefButS(block, TOG, B_NODE_EXEC, "Fit", - butr->xmin+dx/2, dy-19, dx/2, 19, - &nld->fit, 0, 0, 0, 0, - "For positive distortion factor only, scale image such that black areas are not visible"); + row= uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "jitter", UI_ITEM_R_TOGGLE); + uiItemR(row, NULL, 0, ptr, "fit", UI_ITEM_R_TOGGLE); } - uiBlockEndAlign(block); } @@ -1454,59 +1446,24 @@ static void node_composit_buts_filter(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_flip(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - uiBut *bt; - - /* flip x\y */ - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Flip X %x0|Flip Y %x1|Flip X & Y %x2", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiButSetFunc(bt, node_but_title_cb, node, bt); + uiItemR(layout, "", 0, ptr, "axis", 0); } static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeTwoXYs *ntxy= node->storage; - char elementheight = 19; - short dx= (butr->xmax-butr->xmin)/2; - short dy= butr->ymax - elementheight; - short xymin= 0, xymax= 10000; - - uiBlockBeginAlign(block); - - /* crop image size toggle */ - uiDefButS(block, TOG, B_NODE_EXEC, "Crop Image Size", - butr->xmin, dy, dx*2, elementheight, - &node->custom1, 0, 0, 0, 0, "Crop the size of the input image."); - - dy-=elementheight; - - /* x1 */ - uiDefButS(block, NUM, B_NODE_EXEC, "X1:", - butr->xmin, dy, dx, elementheight, - &ntxy->x1, xymin, xymax, 0, 0, ""); - /* y1 */ - uiDefButS(block, NUM, B_NODE_EXEC, "Y1:", - butr->xmin+dx, dy, dx, elementheight, - &ntxy->y1, xymin, xymax, 0, 0, ""); - - dy-=elementheight; - - /* x2 */ - uiDefButS(block, NUM, B_NODE_EXEC, "X2:", - butr->xmin, dy, dx, elementheight, - &ntxy->x2, xymin, xymax, 0, 0, ""); - /* y2 */ - uiDefButS(block, NUM, B_NODE_EXEC, "Y2:", - butr->xmin+dx, dy, dx, elementheight, - &ntxy->y2, xymin, xymax, 0, 0, ""); - - uiBlockEndAlign(block); + uiLayout *row, *col; + + col= uiLayoutColumn(layout, 1); + + uiItemR(col, NULL, 0, ptr, "crop_size", UI_ITEM_R_TOGGLE); + + row= uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "x1", 0); + uiItemR(row, NULL, 0, ptr, "y1", 0); + + row= uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "x2", 0); + uiItemR(row, NULL, 0, ptr, "y2", 0); } static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) @@ -1791,13 +1748,7 @@ static void node_composit_buts_luma_matte(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_map_uv(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - - uiDefButS(block, NUM, B_NODE_EXEC, "Alpha:", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 100, 0, 0, "Conversion percentage of UV differences to Alpha"); + uiItemR(layout, NULL, 0, ptr, "alpha", 0); } static void node_composit_buts_id_mask(uiLayout *layout, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 25fc8e966dc..f2caf1a4d52 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1089,8 +1089,7 @@ static void def_cmp_id_mask(StructRNA *srna) static void def_cmp_map_uv(StructRNA *srna) { PropertyRNA *prop; - - /* TODO: percentage */ + prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 0, 100); @@ -1510,8 +1509,6 @@ static void def_cmp_lensdist(StructRNA *srna) RNA_def_property_ui_text(prop, "Projector", "Enable/disable projector mode. Effect is applied in horizontal direction only."); RNA_def_property_update(prop, 0, "rna_Node_update"); - /* TODO: if proj mode is off { */ - prop = RNA_def_property(srna, "jitter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "jit", 1); RNA_def_property_ui_text(prop, "Jitter", "Enable/disable jittering; faster, but also noisier"); -- cgit v1.2.3 From 064569c52eeeabaaef617c44e13df11026f37a2d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 Sep 2009 15:35:25 +0000 Subject: building scons blenderlite would fail when building the player --- SConstruct | 1 + 1 file changed, 1 insertion(+) diff --git a/SConstruct b/SConstruct index 4ce3aa25d11..e56603170bb 100644 --- a/SConstruct +++ b/SConstruct @@ -264,6 +264,7 @@ if 'blendernogame' in B.targets: if 'blenderlite' in B.targets: target_env_defs = {} target_env_defs['WITH_BF_GAMEENGINE'] = False + target_env_defs['WITH_BF_PLAYER'] = False target_env_defs['WITH_BF_OPENAL'] = False target_env_defs['WITH_BF_OPENEXR'] = False target_env_defs['WITH_BF_ICONV'] = False -- cgit v1.2.3 From 77446c59e991d25493148c7ea56199025248922c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 17 Sep 2009 16:17:32 +0000 Subject: backport Nicholas Bishop's 2.5 commit from r22581, stylus fails on ubuntu 9.10 without this. --- intern/ghost/intern/GHOST_WindowX11.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 5a1f3bf1e21..0457cbcaecb 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -42,6 +42,9 @@ #include #include +#include +#include + // For obscure full screen mode stuuf // lifted verbatim from blut. @@ -441,7 +444,20 @@ void GHOST_WindowX11::initXInputDevices() old_handler = XSetErrorHandler(ApplicationErrorHandler) ; for(int i=0; i Date: Thu, 17 Sep 2009 16:47:04 +0000 Subject: -Added Loop Cut to toolbar -Adjusted some UV Editor panels slightly -Made a few nodes clearer. The Crop node was especially confusing. --- release/ui/space_image.py | 24 ++++++++++++-------- release/ui/space_view3d_toolbar.py | 2 +- source/blender/editors/space_node/drawnode.c | 33 +++++++++++++++------------- source/blender/makesrna/intern/rna_image.c | 2 +- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/release/ui/space_image.py b/release/ui/space_image.py index 02ebd864b8e..161e29194ed 100644 --- a/release/ui/space_image.py +++ b/release/ui/space_image.py @@ -314,13 +314,7 @@ class IMAGE_PT_game_properties(bpy.types.Panel): split = layout.split() col = split.column() - col.itemR(ima, "clamp_x") - col.itemR(ima, "clamp_y") - col.itemR(ima, "mapping", expand=True) - col.itemR(ima, "tiles") - - col = split.column() - + sub = col.column(align=True) sub.itemR(ima, "animated") @@ -329,11 +323,21 @@ class IMAGE_PT_game_properties(bpy.types.Panel): subsub.itemR(ima, "animation_start", text="Start") subsub.itemR(ima, "animation_end", text="End") subsub.itemR(ima, "animation_speed", text="Speed") - - sub = col.row(align=True) + + col.itemR(ima, "tiles") + sub = col.column(align=True) sub.active = ima.tiles or ima.animated sub.itemR(ima, "tiles_x", text="X") sub.itemR(ima, "tiles_y", text="Y") + + col = split.column() + col.itemL(text="Clamp:") + col.itemR(ima, "clamp_x", text="X") + col.itemR(ima, "clamp_y", text="Y") + col.itemS() + col.itemR(ima, "mapping", expand=True) + + class IMAGE_PT_view_properties(bpy.types.Panel): __space_type__ = 'IMAGE_EDITOR' @@ -368,7 +372,9 @@ class IMAGE_PT_view_properties(bpy.types.Panel): col.itemR(uvedit, "normalized_coordinates", text="Normalized") if show_uvedit: + col = layout.column() + col.itemL(text="UVs:") row = col.row() row.itemR(uvedit, "edge_draw_type", expand=True) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 4a5f2ae642c..cbea6466a85 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -67,8 +67,8 @@ class VIEW3D_PT_tools_meshedit(View3DPanel): col = layout.column(align=True) col.itemL(text="Modeling:") col.itemO("mesh.extrude") - col.itemO("mesh.extrude_repeat", text="Extrude Repeat") col.itemO("mesh.subdivide") + col.itemO("mesh.loopcut") col.itemO("mesh.spin") col.itemO("mesh.screw") col.itemO("mesh.merge") diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 9cfae9a7ef5..fadcda67d5b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1414,14 +1414,15 @@ static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr) bNode *node= ptr->data; NodeLensDist *nld = node->storage; - col= uiLayoutColumn(layout, 1); + col= uiLayoutColumn(layout, 0); - uiItemR(col, NULL, 0, ptr, "projector", UI_ITEM_R_TOGGLE); + uiItemR(col, NULL, 0, ptr, "projector", 0); if (!nld->proj) { - row= uiLayoutRow(col, 0); - uiItemR(row, NULL, 0, ptr, "jitter", UI_ITEM_R_TOGGLE); - uiItemR(row, NULL, 0, ptr, "fit", UI_ITEM_R_TOGGLE); + col = uiLayoutColumn(col, 0); + uiItemR(col, NULL, 0, ptr, "jitter", 0); + uiItemR(col, NULL, 0, ptr, "fit", 0); } +// uiLayoutSetActive(col, RNA_boolean_get(&imaptr, "projector")); } @@ -1431,9 +1432,13 @@ static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) col= uiLayoutColumn(layout, 1); uiItemR(col, NULL, 0, ptr, "samples", 0); - uiItemR(col, NULL, 0, ptr, "min_speed", 0); - uiItemR(col, NULL, 0, ptr, "max_speed", 0); uiItemR(col, "Blur", 0, ptr, "factor", 0); + + col= uiLayoutColumn(layout, 1); + uiItemL(col, "Speed:", 0); + uiItemR(col, "Min", 0, ptr, "min_speed", 0); + uiItemR(col, "Max", 0, ptr, "max_speed", 0); + col= uiLayoutColumn(layout, 0); uiItemR(col, NULL, 0, ptr, "curved", 0); @@ -1455,15 +1460,13 @@ static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr) col= uiLayoutColumn(layout, 1); - uiItemR(col, NULL, 0, ptr, "crop_size", UI_ITEM_R_TOGGLE); - - row= uiLayoutRow(col, 0); - uiItemR(row, NULL, 0, ptr, "x1", 0); - uiItemR(row, NULL, 0, ptr, "y1", 0); + uiItemR(col, NULL, 0, ptr, "crop_size", 0); - row= uiLayoutRow(col, 0); - uiItemR(row, NULL, 0, ptr, "x2", 0); - uiItemR(row, NULL, 0, ptr, "y2", 0); + col= uiLayoutColumn(layout, 1); + uiItemR(row, "Left", 0, ptr, "x1", 0); + uiItemR(row, "Right", 0, ptr, "x2", 0); + uiItemR(row, "Up", 0, ptr, "y1", 0); + uiItemR(row, "Down", 0, ptr, "y2", 0); } static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 8614e6f4ef3..13ec9aea9bb 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -211,7 +211,7 @@ static void rna_def_image(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static const EnumPropertyItem prop_generated_type_items[]= { {0, "BLANK", 0, "Blank", "Generate a blank image"}, - {1, "UVTESTGRID", 0, "UV Test Grid", "Generated grid to test UV mappings"}, + {1, "UVGRID", 0, "UV Grid", "Generated grid to test UV mappings"}, {0, NULL, 0, NULL, NULL}}; static const EnumPropertyItem prop_mapping_items[]= { {0, "UV", 0, "UV Coordinates", "Use UV coordinates for mapping the image"}, -- cgit v1.2.3 From a08b16436ded1e43332f6c7326e2dfeb3fc5f4a7 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 17 Sep 2009 17:31:50 +0000 Subject: 2.5: Adding a crop node caused crash, wrong layout deceleration was used. --- source/blender/editors/space_node/drawnode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index fadcda67d5b..a9f53c9efd9 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1409,7 +1409,7 @@ static void node_composit_buts_tonemap(uiLayout *layout, PointerRNA *ptr) /* qdn: lens distortion node */ static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr) { - uiLayout *row, *col; + uiLayout *col; bNode *node= ptr->data; NodeLensDist *nld = node->storage; @@ -1456,17 +1456,17 @@ static void node_composit_buts_flip(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr) { - uiLayout *row, *col; + uiLayout *col; col= uiLayoutColumn(layout, 1); uiItemR(col, NULL, 0, ptr, "crop_size", 0); col= uiLayoutColumn(layout, 1); - uiItemR(row, "Left", 0, ptr, "x1", 0); - uiItemR(row, "Right", 0, ptr, "x2", 0); - uiItemR(row, "Up", 0, ptr, "y1", 0); - uiItemR(row, "Down", 0, ptr, "y2", 0); + uiItemR(col, "Left", 0, ptr, "x1", 0); + uiItemR(col, "Right", 0, ptr, "x2", 0); + uiItemR(col, "Up", 0, ptr, "y1", 0); + uiItemR(col, "Down", 0, ptr, "y2", 0); } static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) -- cgit v1.2.3 From a133907c9273ab3f41a0b91c0e4955f800bee820 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 17 Sep 2009 17:42:08 +0000 Subject: -Shuffled some user prefs around to make better use of the available space in Preferences. -Temporarily disabled the Themes tab until we figure out how to manage themes properly. --- release/ui/space_userpref.py | 123 ++++++++++++--------------- source/blender/makesrna/intern/rna_userdef.c | 107 +++++++++++++++++------ 2 files changed, 136 insertions(+), 94 deletions(-) diff --git a/release/ui/space_userpref.py b/release/ui/space_userpref.py index 267a0b4a78b..c148506214a 100644 --- a/release/ui/space_userpref.py +++ b/release/ui/space_userpref.py @@ -1,4 +1,4 @@ - + import bpy class USERPREF_HT_header(bpy.types.Header): @@ -195,7 +195,7 @@ class USERPREF_PT_edit(bpy.types.Panel): sub1 = sub.column() sub1.itemL(text="Keyframing:") sub1.itemR(edit, "use_visual_keying") - sub1.itemR(edit, "new_interpolation_type") + sub1.itemR(edit, "new_interpolation_type", text="New F-Curves") sub1.itemS() sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing") sub2 = sub1.column() @@ -203,13 +203,16 @@ class USERPREF_PT_edit(bpy.types.Panel): sub2.row().itemR(edit, "auto_keying_mode", expand=True) sub2.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available") sub2.itemR(edit, "auto_keyframe_insert_needed", text="Only Insert Needed") + sub1.itemS() sub1.itemS() sub1.itemS() + sub1.itemL(text="Undo:") sub1.itemR(edit, "global_undo") sub1.itemR(edit, "undo_steps", text="Steps") sub1.itemR(edit, "undo_memory_limit", text="Memory Limit") + sub1.itemS() sub1.itemS() sub1.itemS() @@ -218,7 +221,7 @@ class USERPREF_PT_edit(bpy.types.Panel): sub = col.split(percentage=0.85) sub1 = sub.column() - sub1.itemL(text="Duplicate:") + sub1.itemL(text="Duplicate Data:") sub1.itemR(edit, "duplicate_mesh", text="Mesh") sub1.itemR(edit, "duplicate_surface", text="Surface") sub1.itemR(edit, "duplicate_curve", text="Curve") @@ -246,63 +249,64 @@ class USERPREF_PT_system(bpy.types.Panel): userpref = context.user_preferences system = userpref.system - lan = userpref.language split = layout.split() col = split.column() - sub = col.split(percentage=0.85) + sub = col.split(percentage=0.9) sub1 = sub.column() - sub1.itemR(system, "emulate_numpad") + sub1.itemL(text="General:") + sub1.itemR(system, "dpi") + sub1.itemR(system, "frame_server_port") + sub1.itemR(system, "scrollback", text="Console Scrollback") + sub1.itemR(system, "emulate_numpad") + sub1.itemR(system, "auto_run_python_scripts") + + sub1.itemS() sub1.itemS() sub1.itemS() - #Weight Colors + sub1.itemL(text="Sound:") + sub1.row().itemR(system, "audio_device", expand=True) + sub2 = sub1.column() + sub2.active = system.audio_device != 'AUDIO_DEVICE_NULL' + sub2.itemR(system, "enable_all_codecs") + sub2.itemR(system, "game_sound") + sub2.itemR(system, "audio_channels", text="Channels") + sub2.itemR(system, "audio_mixing_buffer", text="Mixing Buffer") + sub2.itemR(system, "audio_sample_rate", text="Sample Rate") + sub2.itemR(system, "audio_sample_format", text="Sample Format") + + col = split.column() + sub = col.split(percentage=0.9) + + sub1 = sub .column() sub1.itemL(text="Weight Colors:") sub1.itemR(system, "use_weight_color_range", text="Use Custom Range") - sub2 = sub1.column() sub2.active = system.use_weight_color_range sub2.template_color_ramp(system, "weight_color_range", expand=True) + + sub1.itemS() sub1.itemS() sub1.itemS() - #sequencer - sub1.itemL(text="Sequencer:") - sub1.itemR(system, "prefetch_frames") - sub1.itemR(system, "memory_cache_limit") - - col = split.column() - sub = col.split(percentage=0.85) + sub1.itemR(system, "language") + sub1.itemL(text="Translate:") + sub1.itemR(system, "translate_tooltips", text="Tooltips") + sub1.itemR(system, "translate_buttons", text="Labels") + sub1.itemR(system, "translate_toolbox", text="Toolbox") - sub1 = sub .column() - #System - sub1.itemL(text="System:") - sub1.itemR(lan, "dpi") - sub1.itemR(system, "auto_run_python_scripts") - sub1.itemR(system, "frame_server_port") - sub1.itemR(system, "filter_file_extensions") - sub1.itemR(system, "hide_dot_files_datablocks") - sub1.itemR(lan, "scrollback", text="Console Scrollback") - sub1.itemS() sub1.itemS() - sub1.itemL(text="Sound:") - sub1.itemR(system, "audio_device") - sub2 = sub1.column() - sub2.active = system.audio_device != 'AUDIO_DEVICE_NULL' - sub2.itemR(system, "enable_all_codecs") - sub2.itemR(system, "game_sound") - sub2.itemR(system, "audio_channels") - sub2.itemR(system, "audio_mixing_buffer") - sub2.itemR(system, "audio_sample_rate") - sub2.itemR(system, "audio_sample_format") + + sub1.itemR(system, "use_textured_fonts") col = split.column() - sub = col.split(percentage=0.85) + sub = col.split(percentage=0.9) sub1 = sub.column() - #OpenGL + sub1.itemL(text="OpenGL:") sub1.itemR(system, "clip_alpha", slider=True) sub1.itemR(system, "use_mipmaps") @@ -311,7 +315,15 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemL(text="Textures:") sub1.itemR(system, "gl_texture_limit", text="Limit Size") sub1.itemR(system, "texture_time_out", text="Time Out") - sub1.itemR(system, "texture_collection_rate", text="Collection Rate") + sub1.itemR(system, "texture_collection_rate", text="Collection Rate") + + sub1.itemS() + sub1.itemS() + sub1.itemS() + + sub1.itemL(text="Sequencer:") + sub1.itemR(system, "prefetch_frames") + sub1.itemR(system, "memory_cache_limit") class USERPREF_PT_filepaths(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' @@ -328,7 +340,7 @@ class USERPREF_PT_filepaths(bpy.types.Panel): userpref = context.user_preferences paths = userpref.filepaths - split = layout.split() + split = layout.split(percentage=0.6) col = split.column() col.itemL(text="File Paths:") @@ -366,6 +378,8 @@ class USERPREF_PT_filepaths(bpy.types.Panel): sub2.itemR(paths, "use_relative_paths") sub2.itemR(paths, "compress_file") sub2.itemR(paths, "load_ui") + sub2.itemR(paths, "filter_file_extensions") + sub2.itemR(paths, "hide_dot_files_datablocks") sub2.itemS() sub2.itemS() sub2.itemL(text="Auto Save:") @@ -377,36 +391,6 @@ class USERPREF_PT_filepaths(bpy.types.Panel): sub3.enabled = paths.auto_save_temporary_files sub3.itemR(paths, "auto_save_time", text="Timer (mins)") -class USERPREF_PT_language(bpy.types.Panel): - __space_type__ = 'USER_PREFERENCES' - __label__ = "Language" - __show_header__ = False - - def poll(self, context): - userpref = context.user_preferences - return (userpref.active_section == 'LANGUAGE_COLORS') - - def draw(self, context): - layout = self.layout - - userpref = context.user_preferences - lan = userpref.language - - split = layout.split() - col = split.column() - - col.itemR(lan, "language") - col.itemL(text="Translate:") - col.itemR(lan, "translate_tooltips", text="Tooltips") - col.itemR(lan, "translate_buttons", text="Labels") - col.itemR(lan, "translate_toolbox", text="Toolbox") - col.itemS() - col.itemS() - col.itemR(lan, "use_textured_fonts") - - col = split.column() - - bpy.types.register(USERPREF_HT_header) bpy.types.register(USERPREF_MT_view) bpy.types.register(USERPREF_PT_tabs) @@ -414,5 +398,4 @@ bpy.types.register(USERPREF_PT_view) bpy.types.register(USERPREF_PT_edit) bpy.types.register(USERPREF_PT_system) bpy.types.register(USERPREF_PT_filepaths) -bpy.types.register(USERPREF_PT_language) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index b38475469b0..fcc0d7f8a61 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -109,11 +109,6 @@ static PointerRNA rna_UserDef_edit_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesEdit, ptr->data); } -static PointerRNA rna_UserDef_language_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesLanguage, ptr->data); -} - static PointerRNA rna_UserDef_filepaths_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_UserPreferencesFilePaths, ptr->data); @@ -2120,12 +2115,84 @@ static void rna_def_userdef_system(BlenderRNA *brna) {USER_DRAW_OVERLAP, "OVERLAP", 0, "Overlap", "Redraw all overlapping regions, minimal memory usage but more redraws."}, {USER_DRAW_FULL, "FULL", 0, "Full", "Do a full redraw each time, slow, only use for reference or when all else fails."}, {0, NULL, 0, NULL, NULL}}; + + /* hardcoded here, could become dynamic somehow */ + static EnumPropertyItem language_items[] = { + {0, "ENGLISH", 0, "English", ""}, + {1, "JAPANESE", 0, "Japanese", ""}, + {2, "DUTCH", 0, "Dutch", ""}, + {3, "ITALIAN", 0, "Italian", ""}, + {4, "GERMAN", 0, "German", ""}, + {5, "FINNISH", 0, "Finnish", ""}, + {6, "SWEDISH", 0, "Swedish", ""}, + {7, "FRENCH", 0, "French", ""}, + {8, "SPANISH", 0, "Spanish", ""}, + {9, "CATALAN", 0, "Catalan", ""}, + {10, "CZECH", 0, "Czech", ""}, + {11, "BRAZILIAN_PORTUGUESE", 0, "Brazilian Portuguese", ""}, + {12, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese", ""}, + {13, "RUSSIAN", 0, "Russian", ""}, + {14, "CROATIAN", 0, "Croatian", ""}, + {15, "SERBIAN", 0, "Serbian", ""}, + {16, "UKRAINIAN", 0, "Ukrainian", ""}, + {17, "POLISH", 0, "Polish", ""}, + {18, "ROMANIAN", 0, "Romanian", ""}, + {19, "ARABIC", 0, "Arabic", ""}, + {20, "BULGARIAN", 0, "Bulgarian", ""}, + {21, "GREEK", 0, "Greek", ""}, + {22, "KOREAN", 0, "Korean", ""}, + {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "UserPreferencesSystem", NULL); RNA_def_struct_sdna(srna, "UserDef"); RNA_def_struct_nested(brna, srna, "UserPreferences"); RNA_def_struct_ui_text(srna, "System & OpenGL", "Graphics driver and operating system settings."); + /* Language */ + + prop= RNA_def_property(srna, "international_fonts", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE); + RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "dpi"); + RNA_def_property_range(prop, 48, 128); + RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "scrollback"); + RNA_def_property_range(prop, 32, 32768); + RNA_def_property_ui_text(prop, "Scrollback", "Maximum number of lines to store for the console buffer."); + + /* Language Selection */ + + prop= RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, language_items); + RNA_def_property_ui_text(prop, "Language", "Language use for translation."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "translate_tooltips", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS); + RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate Tooltips."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "translate_buttons", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_BUTTONS); + RNA_def_property_ui_text(prop, "Translate Buttons", "Translate button labels."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "translate_toolbox", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_MENUS); + RNA_def_property_ui_text(prop, "Translate Toolbox", "Translate toolbox menu."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT); + RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* System & OpenGL */ prop= RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE); @@ -2174,14 +2241,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_SOUND); RNA_def_property_ui_text(prop, "Game Sound", "Enables sounds to be played in games."); - prop= RNA_def_property(srna, "filter_file_extensions", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_FILTERFILEEXTS); - RNA_def_property_ui_text(prop, "Filter File Extensions", "Display only files with extensions in the image select window."); - - prop= RNA_def_property(srna, "hide_dot_files_datablocks", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_HIDE_DOT); - RNA_def_property_ui_text(prop, "Hide Dot Files/Datablocks", "Hide files/datablocks that start with a dot(.*)"); - prop= RNA_def_property(srna, "clip_alpha", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "glalphaclip"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -2261,7 +2320,15 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) RNA_def_struct_sdna(srna, "UserDef"); RNA_def_struct_nested(brna, srna, "UserPreferences"); RNA_def_struct_ui_text(srna, "File Paths", "Default paths for external files."); - + + prop= RNA_def_property(srna, "hide_dot_files_datablocks", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_HIDE_DOT); + RNA_def_property_ui_text(prop, "Hide Dot Files/Datablocks", "Hide files/datablocks that start with a dot(.*)"); + + prop= RNA_def_property(srna, "filter_file_extensions", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_FILTERFILEEXTS); + RNA_def_property_ui_text(prop, "Filter File Extensions", "Display only files with extensions in the image select window."); + prop= RNA_def_property(srna, "use_relative_paths", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_RELPATHS); RNA_def_property_ui_text(prop, "Relative Paths", "Default relative path option for the file selector."); @@ -2340,10 +2407,9 @@ void RNA_def_userdef(BlenderRNA *brna) static EnumPropertyItem user_pref_sections[] = { {0, "VIEW_CONTROLS", 0, "View", ""}, {1, "EDIT_METHODS", 0, "Editing", ""}, - {2, "LANGUAGE_COLORS", 0, "Language", ""}, + {2, "FILE_PATHS", 0, "File", ""}, {3, "SYSTEM_OPENGL", 0, "System", ""}, - {4, "FILE_PATHS", 0, "File", ""}, - {5, "THEMES", 0, "Themes", ""}, +// {4, "THEMES", 0, "Themes", ""}, // Leave this out until we figure out a way to manage themes in the prefs. {0, NULL, 0, NULL, NULL}}; rna_def_userdef_dothemes(brna); @@ -2381,12 +2447,6 @@ void RNA_def_userdef(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_UserDef_edit_get", NULL, NULL); RNA_def_property_ui_text(prop, "Edit Methods", "Settings for interacting with Blender data."); - prop= RNA_def_property(srna, "language", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "UserPreferencesLanguage"); - RNA_def_property_pointer_funcs(prop, "rna_UserDef_language_get", NULL, NULL); - RNA_def_property_ui_text(prop, "Language & Font", "User interface translation settings."); - prop= RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "UserPreferencesFilePaths"); @@ -2401,7 +2461,6 @@ void RNA_def_userdef(BlenderRNA *brna) rna_def_userdef_view(brna); rna_def_userdef_edit(brna); - rna_def_userdef_language(brna); rna_def_userdef_filepaths(brna); rna_def_userdef_system(brna); -- cgit v1.2.3 From bf34328634266a347e2872e01a06960638a900a4 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 17 Sep 2009 17:44:54 +0000 Subject: Forgot to delete unused code. --- source/blender/makesrna/intern/rna_userdef.c | 81 ---------------------------- 1 file changed, 81 deletions(-) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fcc0d7f8a61..d9ce215f899 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1959,87 +1959,6 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Duplicate Particle", "Causes particle systems to be duplicated with the object."); } -static void rna_def_userdef_language(BlenderRNA *brna) -{ - PropertyRNA *prop; - StructRNA *srna; - - /* hardcoded here, could become dynamic somehow */ - static EnumPropertyItem language_items[] = { - {0, "ENGLISH", 0, "English", ""}, - {1, "JAPANESE", 0, "Japanese", ""}, - {2, "DUTCH", 0, "Dutch", ""}, - {3, "ITALIAN", 0, "Italian", ""}, - {4, "GERMAN", 0, "German", ""}, - {5, "FINNISH", 0, "Finnish", ""}, - {6, "SWEDISH", 0, "Swedish", ""}, - {7, "FRENCH", 0, "French", ""}, - {8, "SPANISH", 0, "Spanish", ""}, - {9, "CATALAN", 0, "Catalan", ""}, - {10, "CZECH", 0, "Czech", ""}, - {11, "BRAZILIAN_PORTUGUESE", 0, "Brazilian Portuguese", ""}, - {12, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese", ""}, - {13, "RUSSIAN", 0, "Russian", ""}, - {14, "CROATIAN", 0, "Croatian", ""}, - {15, "SERBIAN", 0, "Serbian", ""}, - {16, "UKRAINIAN", 0, "Ukrainian", ""}, - {17, "POLISH", 0, "Polish", ""}, - {18, "ROMANIAN", 0, "Romanian", ""}, - {19, "ARABIC", 0, "Arabic", ""}, - {20, "BULGARIAN", 0, "Bulgarian", ""}, - {21, "GREEK", 0, "Greek", ""}, - {22, "KOREAN", 0, "Korean", ""}, - {0, NULL, 0, NULL, NULL}}; - - srna= RNA_def_struct(brna, "UserPreferencesLanguage", NULL); - RNA_def_struct_sdna(srna, "UserDef"); - RNA_def_struct_nested(brna, srna, "UserPreferences"); - RNA_def_struct_ui_text(srna, "Language & Font", "User interface translation settings."); - - prop= RNA_def_property(srna, "international_fonts", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE); - RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "dpi"); - RNA_def_property_range(prop, 48, 128); - RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "scrollback"); - RNA_def_property_range(prop, 32, 32768); - RNA_def_property_ui_text(prop, "Scrollback", "Maximum number of lines to store for the console buffer."); - - /* Language Selection */ - - prop= RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, language_items); - RNA_def_property_ui_text(prop, "Language", "Language use for translation."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "translate_tooltips", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS); - RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate Tooltips."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "translate_buttons", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_BUTTONS); - RNA_def_property_ui_text(prop, "Translate Buttons", "Translate button labels."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "translate_toolbox", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_MENUS); - RNA_def_property_ui_text(prop, "Translate Toolbox", "Translate toolbox menu."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT); - RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts."); - RNA_def_property_update(prop, 0, "rna_userdef_update"); -} - static void rna_def_userdef_system(BlenderRNA *brna) { PropertyRNA *prop; -- cgit v1.2.3 From b572ae2a8bdd4adfc1641a43ca02061b9ae6eff9 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 17 Sep 2009 18:40:37 +0000 Subject: netrender: Disable windows' blocking crash reports in child process. (windows only) Get server port as well as ip address from master broadcast (broadcast is on a fixed port). --- release/io/netrender/master.py | 2 +- release/io/netrender/operators.py | 5 +++-- release/io/netrender/slave.py | 24 ++++++++++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 29cec4e2232..8f59ef37069 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -632,5 +632,5 @@ def runMaster(address, broadcast, path, update_stats, test_break): if broadcast: if time.time() - start_time >= 10: # need constant here print("broadcasting address") - s.sendto(bytes("%s:%i" % address, encoding='utf8'), 0, ('',address[1])) + s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('', 8000)) start_time = time.time() diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 928c2b9efaf..e6888731437 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -339,14 +339,15 @@ class netclientscan(bpy.types.Operator): s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.settimeout(30) - s.bind(('', netsettings.server_port)) + s.bind(('', 8000)) try: - buf, address = s.recvfrom(128) + buf, address = s.recvfrom(64) print("received:", buf) netsettings.server_address = address[0] + netsettings.server_port = int(str(buf, encoding='utf8')) except socket.timeout: print("no server info") diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 3a4e77abc54..1f4ef3a3616 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -9,6 +9,22 @@ CANCEL_POLL_SPEED = 2 MAX_TIMEOUT = 10 INCREMENT_TIMEOUT = 1 +if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5 + import ctypes + def SetErrorMode(): + val = ctypes.windll.kernel32.SetErrorMode(0x0002) + ctypes.windll.kernel32.SetErrorMode(val | 0x0002) + return val + + def RestoreErrorMode(val): + ctypes.windll.kernel32.SetErrorMode(val) +else: + def SetErrorMode(): + return 0 + + def RestoreErrorMode(val): + pass + def slave_Info(): sysname, nodename, release, version, machine, processor = platform.uname() slave = netrender.model.RenderSlave() @@ -100,10 +116,14 @@ def render_slave(engine, scene): for frame in job.frames: print("frame", frame.number) frame_args += ["-f", str(frame.number)] - + + + start_t = time.time() - process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + val = SetErrorMode() + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) headers = {"job-id":job.id, "slave-id":slave_id} -- cgit v1.2.3 From 69e919530e179c0ac251534003e3ab8f540e82fe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Sep 2009 21:36:02 +0000 Subject: Keymaps now have a poll() function, rather than adding/removing their handlers based on notifiers, which is simpler and more reliable. This fixes for example editmode or uv edit keymaps not working when creating a new 3dview or image space. --- source/blender/blenloader/intern/readfile.c | 1 - .../blender/editors/animation/anim_channels_edit.c | 2 +- source/blender/editors/animation/anim_markers.c | 2 +- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/armature/armature_ops.c | 8 +- source/blender/editors/curve/curve_ops.c | 8 +- source/blender/editors/gpencil/gpencil_ops.c | 2 +- source/blender/editors/include/ED_transform.h | 3 +- source/blender/editors/interface/view2d_ops.c | 4 +- source/blender/editors/mesh/mesh_ops.c | 5 +- source/blender/editors/metaball/mball_ops.c | 7 +- source/blender/editors/object/object_ops.c | 16 ++- source/blender/editors/physics/ed_pointcache.c | 2 +- source/blender/editors/physics/editparticle.c | 5 +- source/blender/editors/screen/area.c | 14 +-- source/blender/editors/screen/screen_ops.c | 6 +- source/blender/editors/space_action/action_ops.c | 6 +- source/blender/editors/space_action/space_action.c | 8 +- .../blender/editors/space_buttons/space_buttons.c | 6 +- .../blender/editors/space_console/space_console.c | 6 +- source/blender/editors/space_file/space_file.c | 22 ++-- source/blender/editors/space_graph/graph_ops.c | 8 +- source/blender/editors/space_graph/space_graph.c | 16 +-- source/blender/editors/space_image/space_image.c | 41 ++----- source/blender/editors/space_logic/space_logic.c | 10 +- source/blender/editors/space_nla/nla_ops.c | 12 +- source/blender/editors/space_nla/space_nla.c | 16 +-- source/blender/editors/space_node/node_ops.c | 2 +- source/blender/editors/space_node/space_node.c | 4 +- .../blender/editors/space_outliner/outliner_ops.c | 2 +- .../editors/space_outliner/space_outliner.c | 4 +- source/blender/editors/space_script/script_ops.c | 2 +- source/blender/editors/space_script/space_script.c | 4 +- .../editors/space_sequencer/sequencer_ops.c | 2 +- .../editors/space_sequencer/space_sequencer.c | 4 +- source/blender/editors/space_sound/space_sound.c | 4 +- source/blender/editors/space_text/space_text.c | 8 +- source/blender/editors/space_time/space_time.c | 4 +- source/blender/editors/space_time/time_ops.c | 2 +- source/blender/editors/space_view3d/space_view3d.c | 132 +++++++-------------- source/blender/editors/space_view3d/view3d_ops.c | 6 +- source/blender/editors/transform/transform_ops.c | 2 +- source/blender/editors/uvedit/uvedit_ops.c | 5 +- source/blender/makesdna/DNA_view3d_types.h | 4 +- source/blender/makesdna/DNA_windowmanager_types.h | 3 + source/blender/windowmanager/WM_api.h | 16 +-- .../blender/windowmanager/intern/wm_event_system.c | 32 +++-- source/blender/windowmanager/intern/wm_keymap.c | 39 +++--- source/blender/windowmanager/intern/wm_operators.c | 2 +- source/blender/windowmanager/intern/wm_window.c | 6 +- source/blender/windowmanager/wm_event_system.h | 2 +- 51 files changed, 253 insertions(+), 276 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bb7262c01d4..6518db2dc91 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4826,7 +4826,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->ri= NULL; rv3d->sms= NULL; rv3d->smooth_timer= NULL; - rv3d->lastmode= 0; } } diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 72d8f71bc26..4afecdb55c0 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -1572,7 +1572,7 @@ void ED_operatortypes_animchannels(void) void ED_keymap_animchannels(wmWindowManager *wm) { - ListBase *keymap = WM_keymap_listbase(wm, "Animation_Channels", 0, 0); + wmKeyMap *keymap = WM_keymap_find(wm, "Animation_Channels", 0, 0); /* selection */ /* click-select */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index d33eece52c9..06fa3b715e0 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -992,7 +992,7 @@ void ED_operatortypes_marker(void) /* called in screen_ops.c:ED_keymap_screen() */ void ED_marker_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Markers", 0, 0); WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index fedbe12c0e6..186bdc3b762 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -406,7 +406,7 @@ void ED_operatortypes_anim(void) void ED_keymap_anim(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Animation", 0, 0); /* frame management */ /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */ diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 389a0a5174a..4a61c8ddaf8 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -202,11 +202,12 @@ void ED_operatortypes_armature(void) void ED_keymap_armature(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; wmKeymapItem *kmi; /* Armature ------------------------ */ - keymap= WM_keymap_listbase(wm, "Armature", 0, 0); + keymap= WM_keymap_find(wm, "Armature", 0, 0); + keymap->poll= ED_operator_editarmature; /* only set in editmode armature, by space_view3d listener */ // WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0); @@ -280,7 +281,8 @@ void ED_keymap_armature(wmWindowManager *wm) /* Pose ------------------------ */ /* only set in posemode, by space_view3d listener */ - keymap= WM_keymap_listbase(wm, "Pose", 0, 0); + keymap= WM_keymap_find(wm, "Pose", 0, 0); + keymap->poll= ED_operator_posemode; WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0); kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 8a90dace40b..77c5ed1de2c 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -163,7 +163,10 @@ void ED_operatortypes_curve(void) void ED_keymap_curve(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Font", 0, 0); + wmKeyMap *keymap; + + keymap= WM_keymap_find(wm, "Font", 0, 0); + keymap->poll= ED_operator_editfont; /* only set in editmode font, by space_view3d listener */ RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", BKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_BOLD); @@ -212,7 +215,8 @@ void ED_keymap_curve(wmWindowManager *wm) WM_keymap_add_item(keymap, "FONT_OT_text_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last! /* only set in editmode curve, by space_view3d listener */ - keymap= WM_keymap_listbase(wm, "Curve", 0, 0); + keymap= WM_keymap_find(wm, "Curve", 0, 0); + keymap->poll= ED_operator_editsurfcurve; WM_keymap_add_item(keymap, "OBJECT_OT_curve_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CURVE_OT_vertex_add", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index d33ad16dfb1..d311b39b9a3 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -47,7 +47,7 @@ void ED_keymap_gpencil(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Grease Pencil", 0, 0); wmKeymapItem *kmi; /* Draw */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 984def760ae..96425f725e9 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -41,8 +41,9 @@ struct Object; struct uiLayout; struct EnumPropertyItem; struct wmOperatorType; +struct wmKeyMap; -void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid); +void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid); void transform_operatortypes(void); /* ******************** Macros & Prototypes *********************** */ diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 3e009884dee..33838418842 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1409,7 +1409,7 @@ void ui_view2d_operatortypes(void) void UI_view2d_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "View2D", 0, 0); /* pan/scroll */ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -1445,7 +1445,7 @@ void UI_view2d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); /* Alternative keymap for buttons listview */ - keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); + keymap= WM_keymap_find(wm, "View2D Buttons List", 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 6da42f28af4..f22adc597c7 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -349,9 +349,12 @@ void ED_operatortypes_mesh(void) /* note mesh keymap also for other space? */ void ED_keymap_mesh(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0); + wmKeyMap *keymap; wmKeymapItem *kmi; + keymap= WM_keymap_find(wm, "EditMesh", 0, 0); + keymap->poll= ED_operator_editmesh; + WM_keymap_add_item(keymap, "MESH_OT_loopcut", ACTIONMOUSE, KM_PRESS, KM_CTRL, RKEY); /* selecting */ diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c index b469bb3e400..dd8a18f385c 100644 --- a/source/blender/editors/metaball/mball_ops.c +++ b/source/blender/editors/metaball/mball_ops.c @@ -34,6 +34,8 @@ #include "DNA_listBase.h" #include "DNA_windowmanager_types.h" +#include "ED_screen.h" + #include "mball_intern.h" void ED_operatortypes_metaball(void) @@ -51,7 +53,10 @@ void ED_operatortypes_metaball(void) void ED_keymap_metaball(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Metaball", 0, 0); + wmKeyMap *keymap; + + keymap= WM_keymap_find(wm, "Metaball", 0, 0); + keymap->poll= ED_operator_editmball; WM_keymap_add_item(keymap, "OBJECT_OT_metaball_add", AKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index dce09d47b2c..fdfe6ed501c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -184,11 +184,19 @@ void ED_operatortypes_object(void) } } +static int object_mode_poll(bContext *C) +{ + Object *ob= CTX_data_active_object(C); + return (!ob || ob->mode == OB_MODE_OBJECT); +} + void ED_keymap_object(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0); + wmKeyMap *keymap; wmKeymapItem *kmi; + keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0); + /* Note: this keymap works disregarding mode */ WM_keymap_add_item(keymap, "OBJECT_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_posemode_toggle", TABKEY, KM_PRESS, KM_CTRL, 0); @@ -203,7 +211,8 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_center_set", CKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_CTRL, 0); /* Note: this keymap gets disabled in non-objectmode, */ - keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0); + keymap= WM_keymap_find(wm, "Object Mode", 0, 0); + keymap->poll= object_mode_poll; WM_keymap_add_item(keymap, "OBJECT_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); @@ -246,7 +255,8 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); /* Lattice */ - keymap= WM_keymap_listbase(wm, "Lattice", 0, 0); + keymap= WM_keymap_find(wm, "Lattice", 0, 0); + keymap->poll= ED_operator_editlattice; WM_keymap_add_item(keymap, "LATTICE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c index f2c7b64032f..ed3aaf0cfd1 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/ed_pointcache.c @@ -347,7 +347,7 @@ void ED_operatortypes_pointcache(void) //void ED_keymap_pointcache(wmWindowManager *wm) //{ -// ListBase *keymap= WM_keymap_listbase(wm, "Pointcache", 0, 0); +// wmKeyMap *keymap= WM_keymap_find(wm, "Pointcache", 0, 0); // // WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0); // WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 85ec215a326..6d1f2e5057b 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -3973,7 +3973,10 @@ void ED_operatortypes_particle(void) void ED_keymap_particle(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Particle", 0, 0); + wmKeyMap *keymap; + + keymap= WM_keymap_find(wm, "Particle", 0, 0); + keymap->poll= PE_poll; WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 07d0d1a85c5..87901d75494 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -824,24 +824,24 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla UI_add_region_handlers(handlers); } if(flag & ED_KEYMAP_VIEW2D) { - ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "View2D", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } if(flag & ED_KEYMAP_MARKERS) { - ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Markers", 0, 0); WM_event_add_keymap_handler(handlers, keymap); // XXX need boundbox check urgently!!! } if(flag & ED_KEYMAP_ANIMATION) { - ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Animation", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } if(flag & ED_KEYMAP_FRAMES) { - ListBase *keymap= WM_keymap_listbase(wm, "Frames", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Frames", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } if(flag & ED_KEYMAP_GPENCIL) { - ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Grease Pencil", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } } @@ -1353,7 +1353,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; // XXX quick hacks for files saved with 2.5 already (i.e. the builtin defaults file) // scrollbars for button regions @@ -1366,7 +1366,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); - keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); + keymap= WM_keymap_find(wm, "View2D Buttons List", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 0bb1969ce3c..605bd8682f5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3291,10 +3291,10 @@ static void keymap_modal_set(wmWindowManager *wm) /* called in spacetypes.c */ void ED_keymap_screen(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; /* Screen General ------------------------------------------------ */ - keymap= WM_keymap_listbase(wm, "Screen", 0, 0); + keymap= WM_keymap_find(wm, "Screen", 0, 0); /* standard timers */ @@ -3361,7 +3361,7 @@ void ED_keymap_screen(wmWindowManager *wm) /* Anim Playback ------------------------------------------------ */ - keymap= WM_keymap_listbase(wm, "Frames", 0, 0); + keymap= WM_keymap_find(wm, "Frames", 0, 0); /* frame offsets */ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10); diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index cd4a7b30eff..00b22232608 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -91,7 +91,7 @@ void action_operatortypes(void) /* ************************** registration - keymaps **********************************/ -static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap) +static void action_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) { wmKeymapItem *kmi; @@ -166,7 +166,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap) void action_keymap(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; /* channels */ /* Channels are not directly handled by the Action Editor module, but are inherited from the Animation module. @@ -175,7 +175,7 @@ void action_keymap(wmWindowManager *wm) */ /* keyframes */ - keymap= WM_keymap_listbase(wm, "Action_Keys", SPACE_ACTION, 0); + keymap= WM_keymap_find(wm, "Action_Keys", SPACE_ACTION, 0); action_keymap_keyframes(wm, keymap); } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index b7a3df563ea..bceee73d5f0 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -153,12 +153,12 @@ static SpaceLink *action_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void action_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Action_Keys", SPACE_ACTION, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Action_Keys", SPACE_ACTION, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -216,12 +216,12 @@ static void action_main_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void action_channel_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Animation_Channels", 0, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Animation_Channels", 0, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index c8ced42c2d2..381beaa0295 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -138,11 +138,11 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "Buttons Generic", SPACE_BUTS, 0); + keymap= WM_keymap_find(wm, "Buttons Generic", SPACE_BUTS, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -216,7 +216,7 @@ void buttons_operatortypes(void) void buttons_keymap(struct wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Buttons Generic", SPACE_BUTS, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Buttons Generic", SPACE_BUTS, 0); WM_keymap_add_item(keymap, "BUTTONS_OT_toolbox", RIGHTMOUSE, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index dfaaa269970..6526b569bbb 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -147,12 +147,12 @@ static SpaceLink *console_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void console_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -231,7 +231,7 @@ void console_operatortypes(void) void console_keymap(struct wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Console", SPACE_CONSOLE, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0); #ifdef __APPLE__ RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 27948618d03..99d649b28cc 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -255,15 +255,15 @@ static void file_listener(ScrArea *sa, wmNotifier *wmn) /* add handlers, stuff you only do once or on area/region changes */ static void file_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymaps */ - keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0); + keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_listbase(wm, "FileMain", SPACE_FILE, 0); + keymap= WM_keymap_find(wm, "FileMain", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -375,7 +375,7 @@ void file_keymap(struct wmWindowManager *wm) { wmKeymapItem *kmi; /* keys for all areas */ - ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); WM_keymap_add_item(keymap, "FILE_OT_bookmark_toggle", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_add_bookmark", BKEY, KM_PRESS, KM_CTRL, 0); @@ -386,7 +386,7 @@ void file_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "FILE_OT_delete", XKEY, KM_PRESS, 0, 0); /* keys for main area */ - keymap= WM_keymap_listbase(wm, "FileMain", SPACE_FILE, 0); + keymap= WM_keymap_find(wm, "FileMain", SPACE_FILE, 0); WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0); @@ -407,7 +407,7 @@ void file_keymap(struct wmWindowManager *wm) RNA_int_set(kmi->ptr, "increment",-100); /* keys for button area (top) */ - keymap= WM_keymap_listbase(wm, "FileButtons", SPACE_FILE, 0); + keymap= WM_keymap_find(wm, "FileButtons", SPACE_FILE, 0); WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0); RNA_int_set(kmi->ptr, "increment", 1); @@ -426,12 +426,12 @@ void file_keymap(struct wmWindowManager *wm) static void file_channel_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); /* own keymaps */ - keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0); + keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -462,15 +462,15 @@ static void file_header_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void file_ui_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_listbase(wm, "FileButtons", SPACE_FILE, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "FileButtons", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index fc4c05915c9..b7d67c85ab9 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -141,7 +141,7 @@ void graphedit_operatortypes(void) /* ************************** registration - keymaps **********************************/ -static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap) +static void graphedit_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) { wmKeymapItem *kmi; @@ -232,10 +232,10 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap) void graphedit_keymap(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; /* keymap for all regions */ - keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); WM_keymap_add_item(keymap, "GRAPH_OT_properties", NKEY, KM_PRESS, 0, 0); /* channels */ @@ -245,7 +245,7 @@ void graphedit_keymap(wmWindowManager *wm) */ /* keyframes */ - keymap= WM_keymap_listbase(wm, "GraphEdit Keys", SPACE_IPO, 0); + keymap= WM_keymap_find(wm, "GraphEdit Keys", SPACE_IPO, 0); graphedit_keymap_keyframes(wm, keymap); } diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 8887d464f30..e0b961b38f1 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -203,14 +203,14 @@ static SpaceLink *graph_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void graph_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "GraphEdit Keys", SPACE_IPO, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "GraphEdit Keys", SPACE_IPO, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -281,14 +281,14 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar) static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Animation_Channels", 0, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Animation_Channels", 0, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -352,11 +352,11 @@ static void graph_header_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index c57bc5773b0..e57a059265f 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -204,7 +204,7 @@ void image_operatortypes(void) void image_keymap(struct wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0); WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0); @@ -212,7 +212,7 @@ void image_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0); - keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm, "Image", SPACE_IMAGE, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); @@ -398,23 +398,22 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *sce /* add handlers, stuff you only do once or on area/region changes */ static void image_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; // image space manages own v2d // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* image paint polls for mode */ - keymap= WM_keymap_listbase(wm, "ImagePaint", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm, "ImagePaint", SPACE_IMAGE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - /* XXX need context here? - keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap);*/ + keymap= WM_keymap_find(wm, "UVEdit", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); /* own keymaps */ - keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_listbase(wm, "Image", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm, "Image", SPACE_IMAGE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -457,29 +456,11 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) UI_view2d_scrollers_free(scrollers);*/ } -static void image_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype) -{ - ListBase *keymap; - - keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0); - - if(stype==NS_EDITMODE_MESH) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); -} - static void image_main_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { - case NC_SCENE: - switch(wmn->data) { - case ND_MODE: - image_modal_keymaps(wmn->wm, ar, wmn->subtype); - break; - } - break; + /* nothing yet */ } } @@ -488,11 +469,11 @@ static void image_main_area_listener(ARegion *ar, wmNotifier *wmn) /* add handlers, stuff you only do once or on area/region changes */ static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c index 3c46522bba2..7043d625ab0 100644 --- a/source/blender/editors/space_logic/space_logic.c +++ b/source/blender/editors/space_logic/space_logic.c @@ -188,7 +188,7 @@ void logic_operatortypes(void) void logic_keymap(struct wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Logic Generic", SPACE_LOGIC, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0); WM_keymap_add_item(keymap, "LOGIC_OT_properties", NKEY, KM_PRESS, 0, 0); } @@ -234,12 +234,12 @@ static int logic_context(const bContext *C, const char *member, bContextDataResu /* add handlers, stuff you only do once or on area/region changes */ static void logic_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymaps */ - keymap= WM_keymap_listbase(wm, "Logic Generic", SPACE_LOGIC, 0); + keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -276,11 +276,11 @@ static void logic_main_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void logic_buttons_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "Logic Generic", SPACE_LOGIC, 0); + keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c index ad5f5174690..5ea2e99ad6a 100644 --- a/source/blender/editors/space_nla/nla_ops.c +++ b/source/blender/editors/space_nla/nla_ops.c @@ -167,7 +167,7 @@ void nla_operatortypes(void) /* ************************** registration - keymaps **********************************/ -static void nla_keymap_channels (wmWindowManager *wm, ListBase *keymap) +static void nla_keymap_channels (wmWindowManager *wm, wmKeyMap *keymap) { /* NLA-specific (different to standard channels keymap) -------------------------- */ /* selection */ @@ -210,7 +210,7 @@ static void nla_keymap_channels (wmWindowManager *wm, ListBase *keymap) RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1); } -static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap) +static void nla_keymap_main (wmWindowManager *wm, wmKeyMap *keymap) { wmKeymapItem *kmi; @@ -284,10 +284,10 @@ static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap) void nla_keymap(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; /* keymap for all regions */ - keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); WM_keymap_add_item(keymap, "NLA_OT_properties", NKEY, KM_PRESS, 0, 0); /* channels */ @@ -297,11 +297,11 @@ void nla_keymap(wmWindowManager *wm) * * However, those operations which involve clicking on channels and/or the placement of them in the view are implemented here instead */ - keymap= WM_keymap_listbase(wm, "NLA Channels", SPACE_NLA, 0); + keymap= WM_keymap_find(wm, "NLA Channels", SPACE_NLA, 0); nla_keymap_channels(wm, keymap); /* data */ - keymap= WM_keymap_listbase(wm, "NLA Data", SPACE_NLA, 0); + keymap= WM_keymap_find(wm, "NLA Data", SPACE_NLA, 0); nla_keymap_main(wm, keymap); } diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 89d4e7cddf2..06ee34a6573 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -208,15 +208,15 @@ static SpaceLink *nla_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void nla_channel_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ // TODO: cannot use generic copy, need special NLA version - keymap= WM_keymap_listbase(wm, "NLA Channels", SPACE_NLA, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "NLA Channels", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -254,14 +254,14 @@ static void nla_channel_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void nla_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "NLA Data", SPACE_NLA, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "NLA Data", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -354,11 +354,11 @@ static void nla_header_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void nla_buttons_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 4c2fbf7b9dc..f47e9aa2a6f 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -69,7 +69,7 @@ void node_operatortypes(void) void node_keymap(struct wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Node", SPACE_NODE, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0); /* mouse select in nodes used to be both keys, it's UI elements... */ RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0)->ptr, "select_type", NODE_SELECT_MOUSE); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index d3a445b18c0..12a5f33e119 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -245,12 +245,12 @@ static void node_channel_area_draw(const bContext *C, ARegion *ar) /* Initialise main area, setting handlers. */ static void node_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Node", SPACE_NODE, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 2e11eb379b4..a35b91249db 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -76,7 +76,7 @@ void outliner_operatortypes(void) void outliner_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OUTLINER, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Outliner", SPACE_OUTLINER, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 5058a167a29..e7e6c2d0128 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -72,12 +72,12 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OUTLINER, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Outliner", SPACE_OUTLINER, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c index 270cc1ffd8f..0e6ea9cf4fd 100644 --- a/source/blender/editors/space_script/script_ops.c +++ b/source/blender/editors/space_script/script_ops.c @@ -65,7 +65,7 @@ void script_operatortypes(void) void script_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Script", SPACE_SCRIPT, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Script", SPACE_SCRIPT, 0); /* TODO - this is just while we have no way to load a text datablock */ RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "path", "test.py"); diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index 99233cc5020..a0e73082701 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -133,12 +133,12 @@ static SpaceLink *script_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void script_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Script", SPACE_SCRIPT, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Script", SPACE_SCRIPT, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 74f22b86b75..ac125c10b2d 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -105,7 +105,7 @@ void sequencer_operatortypes(void) void sequencer_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Sequencer", SPACE_SEQ, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Sequencer", SPACE_SEQ, 0); wmKeymapItem *kmi; WM_keymap_add_item(keymap, "SEQUENCER_OT_properties", NKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 26ffd88ae67..c2756b05946 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -185,12 +185,12 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Sequencer", SPACE_SEQ, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Sequencer", SPACE_SEQ, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_sound/space_sound.c b/source/blender/editors/space_sound/space_sound.c index f8ef2b21ae7..6713e19b6de 100644 --- a/source/blender/editors/space_sound/space_sound.c +++ b/source/blender/editors/space_sound/space_sound.c @@ -142,12 +142,12 @@ static SpaceLink *sound_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void sound_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Sound", SPACE_SOUND, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Sound", SPACE_SOUND, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 1f919fc9cd7..e068c1a70bb 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -208,7 +208,9 @@ static void text_operatortypes(void) static void text_keymap(struct wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Text", SPACE_TEXT, 0); + wmKeyMap *keymap; + + keymap= WM_keymap_find(wm, "Text", SPACE_TEXT, 0); #ifdef __APPLE__ RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); @@ -329,12 +331,12 @@ static int text_context(const bContext *C, const char *member, bContextDataResul /* add handlers, stuff you only do once or on area/region changes */ static void text_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "Text", SPACE_TEXT, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "Text", SPACE_TEXT, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 8f7486f81d9..0f05eb0149d 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -202,12 +202,12 @@ static void time_draw_keyframes(const bContext *C, SpaceTime *stime, ARegion *ar /* add handlers, stuff you only do once or on area/region changes */ static void time_main_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_listbase(wm, "TimeLine", SPACE_TIME, 0); /* XXX weak? */ + keymap= WM_keymap_find(wm, "TimeLine", SPACE_TIME, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index a833cca095c..2b073f269bf 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -142,7 +142,7 @@ void time_operatortypes(void) void time_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "TimeLine", SPACE_TIME, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "TimeLine", SPACE_TIME, 0); WM_keymap_add_item(keymap, "TIME_OT_start_frame_set", SKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TIME_OT_end_frame_set", EKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index b5e5de928b5..15e12e73b49 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -275,101 +275,60 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) return (SpaceLink *)v3dn; } -static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype) -{ - RegionView3D *rv3d= ar->regiondata; - ListBase *keymap; - - /* copy last mode, then we can re-init the region maps */ - rv3d->lastmode= stype; - - keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0); - if(ELEM(stype, 0, NS_MODE_OBJECT)) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0); - if(stype==NS_EDITMODE_MESH) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Curve", 0, 0); - if(stype==NS_EDITMODE_CURVE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Armature", 0, 0); - if(stype==NS_EDITMODE_ARMATURE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Pose", 0, 0); - if(stype==NS_MODE_POSE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Metaball", 0, 0); - if(stype==NS_EDITMODE_MBALL) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Lattice", 0, 0); - if(stype==NS_EDITMODE_LATTICE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - /* armature sketching needs to take over mouse */ - keymap= WM_keymap_listbase(wm, "Armature_Sketch", 0, 0); - if(stype==NS_EDITMODE_ARMATURE) - WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - keymap= WM_keymap_listbase(wm, "Particle", 0, 0); - if(stype==NS_MODE_PARTICLE) - WM_event_add_keymap_handler(&ar->handlers, keymap); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); - - /* editfont keymap swallows all... */ - keymap= WM_keymap_listbase(wm, "Font", 0, 0); - if(stype==NS_EDITMODE_TEXT) - WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10); - else - WM_event_remove_keymap_handler(&ar->handlers, keymap); -} - /* add handlers, stuff you only do once or on area/region changes */ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) { - RegionView3D *rv3d= ar->regiondata; - ListBase *keymap; + wmKeyMap *keymap; /* own keymap */ - keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0); + + keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* object ops. */ - keymap= WM_keymap_listbase(wm, "Object Non-modal", 0, 0); + keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* pose is not modal, operator poll checks for this */ - keymap= WM_keymap_listbase(wm, "Pose", 0, 0); + keymap= WM_keymap_find(wm, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - /* modal ops keymaps */ - view3d_modal_keymaps(wm, ar, rv3d->lastmode); /* operator poll checks for modes */ - keymap= WM_keymap_listbase(wm, "ImagePaint", 0, 0); + keymap= WM_keymap_find(wm, "ImagePaint", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Object Mode", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "EditMesh", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Curve", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Armature", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Pose", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Metaball", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Lattice", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* armature sketching needs to take over mouse */ + keymap= WM_keymap_find(wm, "Armature_Sketch", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Particle", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* editfont keymap swallows all... */ + keymap= WM_keymap_find(wm, "Font", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -444,7 +403,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) ED_region_tag_redraw(ar); break; case ND_MODE: - view3d_modal_keymaps(wmn->wm, ar, wmn->subtype); ED_region_tag_redraw(ar); break; } @@ -516,7 +474,7 @@ static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -552,11 +510,11 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -618,16 +576,14 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar) { - ListBase *keymap; + wmKeyMap *keymap; ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } - - static void view3d_tools_area_draw(const bContext *C, ARegion *ar) { ED_region_panels(C, ar, 1, CTX_data_mode_string(C), -1); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index e179809adc9..9ffdef478b3 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -103,14 +103,16 @@ void view3d_operatortypes(void) void view3d_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); + wmKeyMap *keymap; wmKeymapItem *km; + keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_toolbar", TKEY, KM_PRESS, 0, 0); /* only for region 3D window */ - keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); /* paint poll checks mode */ WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 8d7e8f20ad5..7dfae33bc39 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -621,7 +621,7 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_select_orientation); } -void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid) +void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid) { wmKeymapItem *km; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index cb05109d984..611eee00d79 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -3072,7 +3072,10 @@ void ED_operatortypes_uvedit(void) void ED_keymap_uvedit(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0); + wmKeyMap *keymap; + + keymap= WM_keymap_find(wm, "UVEdit", 0, 0); + keymap->poll= ED_operator_uvedit; /* pick selection */ WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index e221524eac2..d42ccd62694 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -89,9 +89,7 @@ typedef struct RegionView3D { float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */ float pixsize; float ofs[3]; - short camzoom, viewbut; - - int lastmode; /* for modal keymap switching, int because it stores notifier code */ + short camzoom, viewbut, pad[2]; short rflag, viewlock; short persp; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 4274cb7ebc0..00fbc04844c 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -265,6 +265,9 @@ typedef struct wmKeyMap { short pad; void *items; /* struct EnumPropertyItem for now */ + + /* verify if the keymap is enabled in the current context */ + int (*poll)(struct bContext *); } wmKeyMap; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 6610c5d8931..b2edbc324ea 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -83,12 +83,12 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle); /* keymap */ void WM_keymap_init (struct bContext *C); -wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, +wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier); -wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, +wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier); -void WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short keymodifier); -ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid, +void WM_keymap_tweak (wmKeyMap *keymap, short type, short val, int modifier, short keymodifier); +wmKeyMap *WM_keymap_find (struct wmWindowManager *wm, const char *nameid, short spaceid, short regionid); wmKeyMap *WM_modalkeymap_add(struct wmWindowManager *wm, const char *nameid, struct EnumPropertyItem *items); @@ -104,13 +104,13 @@ void WM_key_event_operator_change(const struct bContext *C, const char *opname, /* handlers */ -struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap); +struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap); /* boundbox, optional subwindow boundbox for offset */ -struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bb, rcti *swinbb); +struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, rcti *bb, rcti *swinbb); /* priority not implemented, it adds in begin */ -struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority); +struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int priority); -void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap); +void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap); struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBase *handlers, int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 9d5bd13ea25..22c5788b0ae 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1014,16 +1014,19 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= WM_HANDLER_BREAK; if(handler->keymap) { + wmKeyMap *keymap= handler->keymap; wmKeymapItem *kmi; - for(kmi= handler->keymap->first; kmi; kmi= kmi->next) { - if(wm_eventmatch(event, kmi)) { - - event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ - - action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); - if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */ - break; + if(!keymap->poll || keymap->poll(C)) { + for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) { + if(wm_eventmatch(event, kmi)) { + + event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ + + action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); + if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */ + break; + } } } } @@ -1304,10 +1307,15 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOp return handler; } -wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap) +wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap) { wmEventHandler *handler; + if(!keymap) { + printf("WM_event_add_keymap_handler called with NULL keymap\n"); + return NULL; + } + /* only allow same keymap once */ for(handler= handlers->first; handler; handler= handler->next) if(handler->keymap==keymap) @@ -1321,7 +1329,7 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap } /* priorities not implemented yet, for time being just insert in begin of list */ -wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority) +wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int priority) { wmEventHandler *handler; @@ -1334,7 +1342,7 @@ wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBas return handler; } -wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bblocal, rcti *bbwin) +wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, rcti *bblocal, rcti *bbwin) { wmEventHandler *handler= WM_event_add_keymap_handler(handlers, keymap); @@ -1345,7 +1353,7 @@ wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *key return handler; } -void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap) +void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap) { wmEventHandler *handler; diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 5566aeba260..7d25fb8172e 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -96,17 +96,17 @@ static void keymap_properties_set(wmKeymapItem *kmi) } /* if item was added, then bail out */ -wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier) +wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier) { wmKeymapItem *kmi; - for(kmi= lb->first; kmi; kmi= kmi->next) + for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0) break; if(kmi==NULL) { kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, kmi); + BLI_addtail(&keymap->keymap, kmi); BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); @@ -116,11 +116,11 @@ wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, shor } /* always add item */ -wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier) +wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier) { wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, kmi); + BLI_addtail(&keymap->keymap, kmi); BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); @@ -134,14 +134,14 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short v space/region ids are same as DNA_space_types.h */ /* gets free'd in wm.c */ -static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) +wmKeyMap *WM_keymap_find(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) { wmKeyMap *km; for(km= wm->keymaps.first; km; km= km->next) if(km->spaceid==spaceid && km->regionid==regionid) if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME)) - break; + return km; if(km==NULL) { km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); @@ -154,19 +154,13 @@ static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short sp return km; } -ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) -{ - wmKeyMap *km= wm_keymap_add(wm, nameid, spaceid, regionid); - return &km->keymap; -} - /* ****************** modal keymaps ************ */ /* modal maps get linked to a running operator, and filter the keys before sending to modal() callback */ wmKeyMap *WM_modalkeymap_add(wmWindowManager *wm, const char *nameid, EnumPropertyItem *items) { - wmKeyMap *km= wm_keymap_add(wm, nameid, 0, 0); + wmKeyMap *km= WM_keymap_find(wm, nameid, 0, 0); km->is_modal= 1; km->items= items; @@ -242,15 +236,18 @@ static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len) return str; } -static wmKeymapItem *wm_keymap_item_find_handlers(ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props) +static wmKeymapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props) { wmEventHandler *handler; + wmKeyMap *keymap; wmKeymapItem *kmi; /* find keymap item in handlers */ for(handler=handlers->first; handler; handler=handler->next) { - if(handler->keymap) { - for(kmi=handler->keymap->first; kmi; kmi=kmi->next) { + keymap= handler->keymap; + + if(keymap && (!keymap->poll || keymap->poll((bContext*)C))) { + for(kmi=keymap->keymap.first; kmi; kmi=kmi->next) { if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) { if(compare_props) { if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) @@ -272,11 +269,11 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, /* look into multiple handler lists to find the item */ if(CTX_wm_window(C)) - found= wm_keymap_item_find_handlers(&CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props); if(CTX_wm_area(C) && found==NULL) - found= wm_keymap_item_find_handlers(&CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props); if(found==NULL) { if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) { @@ -287,12 +284,12 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, break; if(ar) - found= wm_keymap_item_find_handlers(&ar->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props); } } else { if(CTX_wm_region(C)) - found= wm_keymap_item_find_handlers(&CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 86a02e2731a..2e2d463bbd9 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2098,7 +2098,7 @@ void wm_operatortype_init(void) /* default keymap for windows and screens, only call once per WM */ void wm_window_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Window", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Window", 0, 0); /* items to make WM work */ WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index d70516ef02e..cbb5bed4c00 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -331,7 +331,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow /* called in wm_check, also inits stuff after file read */ void wm_window_add_ghostwindows(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; wmWindow *win; /* no commandline prefsize? then we set this */ @@ -367,10 +367,10 @@ void wm_window_add_ghostwindows(wmWindowManager *wm) win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state"); /* add keymap handlers (1 handler for all keys in map!) */ - keymap= WM_keymap_listbase(wm, "Window", 0, 0); + keymap= WM_keymap_find(wm, "Window", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); - keymap= WM_keymap_listbase(wm, "Screen", 0, 0); + keymap= WM_keymap_find(wm, "Screen", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); wm_window_title(wm, win); diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 9a3bba9af1d..4360e49e371 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -43,7 +43,7 @@ typedef struct wmEventHandler { int type, flag; /* type default=0, rest is custom */ /* keymap handler */ - ListBase *keymap; /* pointer to builtin/custom keymaps */ + wmKeyMap *keymap; /* pointer to builtin/custom keymaps */ rcti *bblocal, *bbwin; /* optional local and windowspace bb */ -- cgit v1.2.3 From 08e2da590f812860ae14fff4d4e22e98cbd3528c Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Thu, 17 Sep 2009 22:00:49 +0000 Subject: Particles cleanup, optimizations and some small new stuff. New stuff - Bending springs for hair dynamics. Code cleanup & optimization - Disabled reactor particles temporarily for cleanup, it's a clumsy system that will be replaced with something better. - Removed child seams, something better will come here too :) - Normal particle drawing data is now saved between redraws if the particles don't move between redraws. * For example rotating the 3d view is now realtime even with 1M particles. - Many random values for particles now come from a lookup table making things much faster. - Most accessed small point cache functions are now much faster as macros. - Lot's of general code cleanup. - Nothing big should have changed so if something doesn't work like it used to it's probably just a typo somewhere :) --- release/ui/buttons_particle.py | 1 + source/blender/blenkernel/BKE_boids.h | 4 +- source/blender/blenkernel/BKE_particle.h | 124 +- source/blender/blenkernel/intern/anim.c | 15 +- source/blender/blenkernel/intern/boids.c | 82 +- source/blender/blenkernel/intern/cloth.c | 81 +- source/blender/blenkernel/intern/depsgraph.c | 4 +- source/blender/blenkernel/intern/modifier.c | 21 +- source/blender/blenkernel/intern/particle.c | 519 ++++----- source/blender/blenkernel/intern/particle_system.c | 1210 ++++++++++---------- source/blender/blenkernel/intern/pointcache.c | 233 +++- source/blender/blenloader/intern/readfile.c | 2 + source/blender/editors/physics/editparticle.c | 25 +- source/blender/editors/space_view3d/drawobject.c | 133 +-- source/blender/makesdna/DNA_particle_types.h | 14 +- source/blender/makesrna/intern/rna_particle.c | 23 +- .../blender/render/intern/source/convertblender.c | 35 +- source/blender/render/intern/source/pointdensity.c | 5 +- 18 files changed, 1285 insertions(+), 1246 deletions(-) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index 1bbd64c9b0f..e72bd38e563 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -255,6 +255,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel): sub = col.column(align=True) sub.itemR(cloth, "pin_stiffness", text="Stiffness") sub.itemR(cloth, "mass") + sub.itemR(cloth, "bending_stiffness", text="Bending") col.itemL(text="Damping:") sub = col.column(align=True) sub.itemR(cloth, "spring_damping", text="Spring") diff --git a/source/blender/blenkernel/BKE_boids.h b/source/blender/blenkernel/BKE_boids.h index acceff863b9..fb65c9c8920 100644 --- a/source/blender/blenkernel/BKE_boids.h +++ b/source/blender/blenkernel/BKE_boids.h @@ -35,9 +35,7 @@ #include "DNA_boid_types.h" typedef struct BoidBrainData { - Scene *scene; - struct Object *ob; - struct ParticleSystem *psys; + struct ParticleSimulationData *sim; struct ParticleSettings *part; float timestep, cfra, dfra; float wanted_co[3], wanted_speed; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index c22778f5a30..5850ddaca08 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -61,6 +61,23 @@ struct BVHTreeRayHit; #define PARTICLE_P ParticleData *pa; int p #define LOOP_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) +#define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST)) +#define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP))) + +#define PSYS_FRAND_COUNT 1024 +#define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT] + +/* fast but sure way to get the modifier*/ +#define PARTICLE_PSMD ParticleSystemModifierData *psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys) + +/* common stuff that many particle functions need */ +typedef struct ParticleSimulationData { + struct Scene *scene; + struct Object *ob; + struct ParticleSystem *psys; + struct ParticleSystemModifierData *psmd; + float timestep; +} ParticleSimulationData; typedef struct ParticleEffectorCache { struct ParticleEffectorCache *next, *prev; @@ -118,11 +135,8 @@ typedef struct ParticleCacheKey{ typedef struct ParticleThreadContext { /* shared */ - struct Scene *scene; - struct Object *ob; + struct ParticleSimulationData sim; struct DerivedMesh *dm; - struct ParticleSystemModifierData *psmd; - struct ParticleSystem *psys; struct Material *ma; /* distribution */ @@ -166,8 +180,7 @@ typedef struct ParticleBillboardData int lock, num; int totnum; short align, uv_split, anim, split_offset; -} -ParticleBillboardData; +} ParticleBillboardData; /* container for moving data between deflet_particle and particle_intersect_face */ typedef struct ParticleCollision @@ -179,40 +192,40 @@ typedef struct ParticleCollision float co1[3], co2[3]; // ray start and end points float ray_len; // original length of co2-co1, needed for collision time evaluation float t; // time of previous collision, needed for substracting face velocity -} -ParticleCollision; +} ParticleCollision; + +typedef struct ParticleDrawData { + float *vdata, *vd; /* vertice data */ + float *ndata, *nd; /* normal data */ + float *cdata, *cd; /* color data */ + float *vedata, *ved; /* velocity data */ + float *ma_r, *ma_g, *ma_b; + int tot_vec_size, flag; + int totpoint, totve; +} ParticleDrawData; + +#define PARTICLE_DRAW_DATA_UPDATED 1 /* ----------- functions needed outside particlesystem ---------------- */ /* particle.c */ int count_particles(struct ParticleSystem *psys); int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur); -int psys_count_keys(struct ParticleSystem *psys); -char *psys_menu_string(struct Object *ob, int for_sb); struct ParticleSystem *psys_get_current(struct Object *ob); +/* for rna */ short psys_get_current_num(struct Object *ob); void psys_set_current_num(Object *ob, int index); struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys); -//struct ParticleSystem *psys_get(struct Object *ob, int index); -struct ParticleData *psys_get_selected_particle(struct ParticleSystem *psys, int *index); -struct ParticleKey *psys_get_selected_key(struct ParticleSystem *psys, int pa_index, int *key_index); -void psys_change_act(void *ob_v, void *act_v); -struct Object *psys_get_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys); -void psys_disable_all(struct Object *ob); -void psys_enable_all(struct Object *ob); -int psys_ob_has_hair(struct Object *ob); + +struct Object *psys_get_lattice(struct ParticleSimulationData *sim); + int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys); int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys); -void psys_free_boid_rules(struct ListBase *list); +/* free */ void psys_free_settings(struct ParticleSettings *part); -void free_child_path_cache(struct ParticleSystem *psys); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); -void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics); -void free_keyed_keys(struct ParticleSystem *psys); -void psys_free_particles(struct ParticleSystem *psys); void psys_free(struct Object * ob, struct ParticleSystem * psys); -void psys_free_children(struct ParticleSystem *psys); void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset); void psys_render_restore(struct Object *ob, struct ParticleSystem *psys); @@ -234,45 +247,38 @@ struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part); void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc); void make_local_particlesettings(struct ParticleSettings *part); -struct LinkNode *psys_using_settings(struct Scene *scene, struct ParticleSettings *part, int flush_update); void psys_reset(struct ParticleSystem *psys, int mode); -void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys); +void psys_find_parents(struct ParticleSimulationData *sim); -void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra); +void psys_cache_paths(struct ParticleSimulationData *sim, float cfra); void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra); -void psys_cache_child_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate); +void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate); int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb); -float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size); -float psys_get_timestep(struct ParticleSettings *part); +float psys_get_timestep(struct ParticleSimulationData *sim); float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime); float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time); -void psys_get_particle_on_path(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int pa_num, struct ParticleKey *state, int vel); -int psys_get_particle_state(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int p, struct ParticleKey *state, int always); +void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel); +int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); + +/* for anim.c */ void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco); -void psys_get_dupli_path_transform(struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale); +void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale); -ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys); -int psys_threads_init_distribution(ParticleThread *threads, struct Scene *scene, struct DerivedMesh *dm, int from); -int psys_threads_init_path(ParticleThread *threads, struct Scene *scene, float cfra, int editupdate); +ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); void psys_threads_free(ParticleThread *threads); -void psys_thread_distribute_particle(ParticleThread *thread, struct ParticleData *pa, struct ChildParticle *cpa, int p); -void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i); - void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]); /* particle_system.c */ struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt); -void psys_count_keyed_targets(struct Object *ob, struct ParticleSystem *psys); -void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, struct Object **target_ob, struct ParticleSystem **target_psys); +void psys_count_keyed_targets(struct ParticleSimulationData *sim); +//void psys_get_reactor_target(struct ParticleSimulationData *sim, struct Object **target_ob, struct ParticleSystem **target_psys); -void psys_init_effectors(struct Scene *scene, struct Object *obsrc, struct Group *group, struct ParticleSystem *psys); -void psys_end_effectors(struct ParticleSystem *psys); +int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc); void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys); -void psys_end_temp_pointcache(struct ParticleSystem *psys); -void psys_get_pointcache_start_end(struct Scene *scene, struct ParticleSystem *psys, int *sfra, int *efra); +void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra); void psys_check_boid_data(struct ParticleSystem *psys); @@ -280,39 +286,45 @@ void particle_system_update(struct Scene *scene, struct Object *ob, struct Parti /* ----------- functions needed only inside particlesystem ------------ */ /* particle.c */ +void psys_disable_all(struct Object *ob); +void psys_enable_all(struct Object *ob); + +void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics); +void free_keyed_keys(struct ParticleSystem *psys); +void psys_free_particles(struct ParticleSystem *psys); +void psys_free_children(struct ParticleSystem *psys); + void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity); -void psys_key_to_object(struct Object *ob, struct ParticleKey *key, float imat[][4]); -//void psys_key_to_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key); -//void psys_key_from_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key); -//void psys_face_mat(struct DerivedMesh *dm, struct ParticleData *pa, float mat[][4]); void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec); -//void psys_vec_rot_from_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec); void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); +void psys_free_pdd(struct ParticleSystem *psys); + float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup); -void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event); +void psys_get_texture(struct ParticleSimulationData *sim, struct Material *ma, struct ParticleData *pa, struct ParticleTexture *ptex, int event); void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values); -float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, int index, float *fw, float *values); void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time); +/* only in edisparticle.c*/ int psys_intersect_dm(struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint); +/* BLI_bvhtree_ray_cast callback */ void particle_intersect_face(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); /* particle_system.c */ -void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd); +void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p); int effector_find_co(struct Scene *scene, float *pco, struct SurfaceModifierData *sur, struct Object *ob, struct PartDeflect *pd, float *co, float *nor, float *vel, int *index); -void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra); +void do_effectors(struct ParticleSimulationData *sim, int pa_no, struct ParticleData *pa, struct ParticleKey *state, float *texco, float *force_field, float *vel,float framestep, float cfra); +void psys_end_effectors(struct ParticleSystem *psys); void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys); int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node); -void reset_particle(struct Scene *scene, struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob, - float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot); +void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra); /* psys_reset */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 8cb88cdb786..e943d92a0b5 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -766,12 +766,12 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p GroupObject *go; Object *ob=0, **oblist=0, obcopy, *obcopylist=0; DupliObject *dob; + ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)}; ParticleSettings *part; ParticleData *pa; ChildParticle *cpa=0; ParticleKey state; ParticleCacheKey *cache; - ParticleSystemModifierData *psmd; float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], size=0.0; float (*obmat)[4], (*oldobmat)[4]; @@ -784,7 +784,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if(level>MAX_DUPLI_RECUR) return; part=psys->part; - psmd= psys_get_modifier(par, psys); if(part==0) return; @@ -816,7 +815,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p totpart = psys->totcached; } - psys->lattice = psys_get_lattice(scene, par, psys); + psys->lattice = psys_get_lattice(&sim); /* gather list of objects or single object */ if(part->ren_as==PART_DRAW_GR) { @@ -887,11 +886,11 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* hair we handle separate and compute transform based on hair keys */ if(a < totpart) { cache = psys->pathcache[a]; - psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale); + psys_get_dupli_path_transform(&sim, pa, 0, cache, pamat, &scale); } else { cache = psys->childcache[a-totpart]; - psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale); + psys_get_dupli_path_transform(&sim, 0, cpa, cache, pamat, &scale); } VECCOPY(pamat[3], cache->co); @@ -901,7 +900,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else { /* first key */ state.time = ctime; - if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0) + if(psys_get_particle_state(&sim, a, &state, 0) == 0) continue; QuatToMat4(state.rot, pamat); @@ -921,7 +920,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); Mat4CpyMat4(dob->omat, obcopylist[b].obmat); if(G.rendering) - psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); + psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } else { @@ -940,7 +939,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated); Mat4CpyMat4(dob->omat, oldobmat); if(G.rendering) - psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); + psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 18f065b59d9..7c3f3a7876f 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -87,7 +87,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, float vec_to_part[3]; if(pd && pd->forcefield == PFIELD_BOID) { - effector_find_co(bbd->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL); + effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL); VecSubf(vec_to_part, pa->prev_state.co, loc); @@ -99,7 +99,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, priority = 1.0; priority_ob = gabr->ob; } - else for(ec=bbd->psys->effectors.first; ec; ec=ec->next) { + else for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) { if(ec->type & PSYS_EC_EFFECTOR) { Object *eob = ec->ob; PartDeflect *pd = eob->pd; @@ -111,7 +111,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) { float vec_to_part[3], temp; - effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL); + effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL); VecSubf(vec_to_part, pa->prev_state.co, loc); @@ -147,7 +147,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, if(gabr->options & BRULE_GOAL_AVOID_PREDICT) { /* estimate future location of target */ - surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL); + surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL); VecSubf(vec_to_part, pa->prev_state.co, loc); len = Normalize(vec_to_part); @@ -157,7 +157,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, VecSubf(vec_to_part, pa->prev_state.co, loc); } else { - surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL); + surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL); VecSubf(vec_to_part, pa->prev_state.co, loc); len = VecLength(vec_to_part); @@ -228,7 +228,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * hit.dist = col.ray_len = VecLength(ray_dir); /* find out closest deflector object */ - for(ec=bbd->psys->effectors.first; ec; ec=ec->next) { + for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) { if(ec->type & PSYS_EC_DEFLECT) { Object *eob = ec->ob; @@ -261,12 +261,12 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * //check boids in own system if(acbr->options & BRULE_ACOLL_WITH_BOIDS) { - neighbors = BLI_kdtree_range_search(bbd->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn); + neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn); if(neighbors > 1) for(n=1; nprev_state.co); VECCOPY(vel1, pa->prev_state.vel); - VECCOPY(co2, (bbd->psys->particles + ptn[n].index)->prev_state.co); - VECCOPY(vel2, (bbd->psys->particles + ptn[n].index)->prev_state.vel); + VECCOPY(co2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.co); + VECCOPY(vel2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.vel); VecSubf(loc, co1, co2); @@ -303,8 +303,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * if(ptn){ MEM_freeN(ptn); ptn=NULL; } /* check boids in other systems */ - for(pt=bbd->psys->targets.first; pt; pt=pt->next) { - ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt); + for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) { + ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt); if(epsys) { neighbors = BLI_kdtree_range_search(epsys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn); @@ -362,11 +362,11 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa ParticleTarget *pt; float len = 2.0f * val->personal_space * pa->size + 1.0f; float vec[3] = {0.0f, 0.0f, 0.0f}; - int neighbors = BLI_kdtree_range_search(bbd->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn); + int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn); int ret = 0; if(neighbors > 1 && ptn[1].dist!=0.0f) { - VecSubf(vec, pa->prev_state.co, bbd->psys->particles[ptn[1].index].state.co); + VecSubf(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co); VecMulf(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist); VecAddf(bbd->wanted_co, bbd->wanted_co, vec); bbd->wanted_speed = val->max_speed; @@ -376,8 +376,8 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa if(ptn){ MEM_freeN(ptn); ptn=NULL; } /* check other boid systems */ - for(pt=bbd->psys->targets.first; pt; pt=pt->next) { - ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt); + for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) { + ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt); if(epsys) { neighbors = BLI_kdtree_range_search(epsys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn); @@ -400,14 +400,14 @@ static int rule_flock(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti { KDTreeNearest ptn[11]; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; - int neighbors = BLI_kdtree_find_n_nearest(bbd->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn); + int neighbors = BLI_kdtree_find_n_nearest(bbd->sim->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn); int n; int ret = 0; if(neighbors > 1) { for(n=1; npsys->particles[ptn[n].index].prev_state.co); - VecAddf(vec, vec, bbd->psys->particles[ptn[n].index].prev_state.vel); + VecAddf(loc, loc, bbd->sim->psys->particles[ptn[n].index].prev_state.co); + VecAddf(vec, vec, bbd->sim->psys->particles[ptn[n].index].prev_state.vel); } VecMulf(loc, 1.0f/((float)neighbors - 1.0f)); @@ -429,8 +429,8 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader*) rule; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float mul, len; - int n = (flbr->queue_size <= 1) ? bbd->psys->totpart : flbr->queue_size; - int i, ret = 0, p = pa - bbd->psys->particles; + int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size; + int i, ret = 0, p = pa - bbd->sim->psys->particles; if(flbr->ob) { float vec2[3], t; @@ -475,8 +475,8 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* not blocking so try to follow leader */ if(p && flbr->options & BRULE_LEADER_IN_LINE) { - VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel); - VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co); + VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel); + VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co); } else { VECCOPY(loc, flbr->oloc); @@ -496,10 +496,10 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va float vec2[3], t, t_min = 3.0f; /* first check we're not blocking any leaders */ - for(i = 0; i< bbd->psys->totpart; i+=n){ - VECCOPY(vec, bbd->psys->particles[i].prev_state.vel); + for(i = 0; i< bbd->sim->psys->totpart; i+=n){ + VECCOPY(vec, bbd->sim->psys->particles[i].prev_state.vel); - VecSubf(loc, pa->prev_state.co, bbd->psys->particles[i].prev_state.co); + VecSubf(loc, pa->prev_state.co, bbd->sim->psys->particles[i].prev_state.co); mul = Inpf(vec, vec); @@ -539,12 +539,12 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* not blocking so try to follow leader */ if(flbr->options & BRULE_LEADER_IN_LINE) { - VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel); - VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co); + VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel); + VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co); } else { - VECCOPY(vec, bbd->psys->particles[p - p%n].prev_state.vel); - VECCOPY(loc, bbd->psys->particles[p - p%n].prev_state.co); + VECCOPY(vec, bbd->sim->psys->particles[p - p%n].prev_state.vel); + VECCOPY(loc, bbd->sim->psys->particles[p - p%n].prev_state.co); } /* fac is seconds behind leader */ @@ -584,7 +584,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* leveling */ if(asbr->level > 0.0f) { - Projf(vec, bbd->wanted_co, bbd->psys->part->acc); + Projf(vec, bbd->wanted_co, bbd->sim->psys->part->acc); VecMulf(vec, asbr->level); VecSubf(bbd->wanted_co, bbd->wanted_co, vec); } @@ -601,7 +601,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* leveling */ if(asbr->level > 0.0f) { - Projf(vec, bbd->wanted_co, bbd->psys->part->acc); + Projf(vec, bbd->wanted_co, bbd->sim->psys->part->acc); VecMulf(vec, asbr->level); VecSubf(bbd->wanted_co, bbd->wanted_co, vec); } @@ -627,9 +627,9 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti int n, ret = 0; /* calculate own group strength */ - int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn); + int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn); for(n=0; npsys->particles[ptn[n].index].boid; + bpa = bbd->sim->psys->particles[ptn[n].index].boid; health += bpa->data.health; } @@ -638,8 +638,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti if(ptn){ MEM_freeN(ptn); ptn=NULL; } /* add other friendlies and calculate enemy strength and find closest enemy */ - for(pt=bbd->psys->targets.first; pt; pt=pt->next) { - ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt); + for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) { + ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt); if(epsys) { epars = epsys->particles; @@ -760,11 +760,11 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface ); /* take surface velocity into account */ - effector_find_co(bbd->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL); + effector_find_co(bbd->sim->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL); VecAddf(x, x, v); /* get actual position on surface */ - effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL); + effector_find_co(bbd->sim->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL); return bpa->ground; } @@ -785,7 +785,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro hit.dist = col.ray_len = VecLength(ray_dir); /* find out upmost deflector object */ - for(ec=bbd->psys->effectors.first; ec; ec=ec->next) { + for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) { if(ec->type & PSYS_EC_DEFLECT) { Object *eob = ec->ob; @@ -941,7 +941,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f; /* create random seed for every particle & frame */ - BLI_srandom(bbd->psys->seed + p); + BLI_srandom(bbd->sim->psys->seed + p); rand = BLI_rand(); BLI_srandom((int)bbd->cfra + rand); @@ -1077,7 +1077,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f}; float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f}; float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep; - int p = pa - bbd->psys->particles; + int p = pa - bbd->sim->psys->particles; set_boid_values(&val, boids, pa); @@ -1208,7 +1208,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) } /* account for effectors */ - do_effectors(p, pa, &pa->state, bbd->scene, bbd->ob, bbd->psys, pa->state.co, force, tvel, bbd->dfra, bbd->cfra); + do_effectors(bbd->sim, p, pa, &pa->state, pa->state.co, force, tvel, bbd->dfra, bbd->cfra); if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { float length = Normalize(force); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 9ee6be903fa..5cfbd5c18dc 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1160,25 +1160,66 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_linklist_prepend ( &cloth->springs, spring ); } - // bending springs - search2 = cloth->springs; - for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) - { - if ( !search2 ) - break; + if(numfaces) { + // bending springs + search2 = cloth->springs; + for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) + { + if ( !search2 ) + break; + + tspring2 = search2->link; + search = edgelist[tspring2->kl]; + while ( search ) + { + tspring = search->link; + index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) ); + + // check for existing spring + // check also if startpoint is equal to endpoint + if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) ) + && ( index2!=tspring2->ij ) ) + { + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if(!spring) + { + cloth_free_errorsprings(cloth, edgehash, edgelist); + return 0; + } - tspring2 = search2->link; - search = edgelist[tspring2->kl]; - while ( search ) + spring->ij = MIN2(tspring2->ij, index2); + spring->kl = MAX2(tspring2->ij, index2); + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_BENDING; + spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; + BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL ); + bend_springs++; + + BLI_linklist_prepend ( &cloth->springs, spring ); + } + search = search->next; + } + search2 = search2->next; + } + } + else if(struct_springs > 2) { + /* bending springs for hair strands */ + /* The current algorightm only goes through the edges in order of the mesh edges list */ + /* and makes springs between the outer vert of edges sharing a vertice. This works just */ + /* fine for hair, but not for user generated string meshes. This could/should be later */ + /* extended to work with non-ordered edges so that it can be used for general "rope */ + /* dynamics" without the need for the vertices or edges to be ordered through the length*/ + /* of the strands. -jahka */ + search = cloth->springs; + search2 = search->next; + while(search && search2) { tspring = search->link; - index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) ); - - // check for existing spring - // check also if startpoint is equal to endpoint - if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) ) - && ( index2!=tspring2->ij ) ) - { + tspring2 = search2->link; + + if(tspring->ij == tspring2->kl) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); if(!spring) @@ -1187,20 +1228,20 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) return 0; } - spring->ij = MIN2(tspring2->ij, index2); - spring->kl = MAX2(tspring2->ij, index2); + spring->ij = tspring2->ij; + spring->kl = tspring->kl; VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; - BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL ); bend_springs++; BLI_linklist_prepend ( &cloth->springs, spring ); } + search = search->next; + search2 = search2->next; } - search2 = search2->next; } /* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */ diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 58f3db50d0f..4c2b2f3ec12 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -560,6 +560,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O for(; psys; psys=psys->next) { BoidRule *rule = NULL; BoidState *state = NULL; + ParticleSimulationData sim = {scene, ob, psys, NULL}; ParticleSettings *part= psys->part; dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation"); @@ -592,8 +593,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O } } - psys_end_effectors(psys); - psys_init_effectors(scene, ob, psys->part->eff_group, psys); + psys_update_effectors(&sim, 0.0, 0); for(nec= psys->effectors.first; nec; nec= nec->next) { Object *ob1= nec->ob; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index c64c48b9ce7..b9b9ea6b4f3 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6601,6 +6601,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( { DerivedMesh *dm = derivedData, *result; ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md; + ParticleSimulationData sim; ParticleSystem * psys=0; ParticleData *pa=0, *pars=0; MFace *mface, *orig_mface; @@ -6635,6 +6636,11 @@ static DerivedMesh * particleInstanceModifier_applyModifier( if(totpart==0) return derivedData; + sim.scene = md->scene; + sim.ob = pimd->ob; + sim.psys = psys; + sim.psmd = psys_get_modifier(pimd->ob, psys); + if(pimd->flag & eParticleInstanceFlag_UseSize) { int p; float *si; @@ -6662,7 +6668,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( maxvert=totvert*totpart; maxface=totface*totpart; - psys->lattice=psys_get_lattice(md->scene, ob, psys); + psys->lattice=psys_get_lattice(&sim); if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){ @@ -6712,7 +6718,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( mv->co[axis] = 0.0; } - psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1); + psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1); Normalize(state.vel); @@ -6734,7 +6740,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( } else{ state.time=-1.0; - psys_get_particle_state(md->scene, pimd->ob, psys, first_particle + i/totvert, &state,1); + psys_get_particle_state(&sim, first_particle + i/totvert, &state,1); } QuatMulVecf(state.rot,mv->co); @@ -7416,6 +7422,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, DerivedMesh *explode, *dm=to_explode; MFace *mf=0; ParticleSettings *part=psmd->psys->part; + ParticleSimulationData sim = {scene, ob, psmd->psys, psmd}; ParticleData *pa=NULL, *pars=psmd->psys->particles; ParticleKey state; EdgeHash *vertpahash; @@ -7431,7 +7438,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, totvert= dm->getNumVerts(dm); totpart= psmd->psys->totpart; - timestep= psys_get_timestep(part); + timestep= psys_get_timestep(&sim); //if(part->flag & PART_GLOB_TIME) cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0); @@ -7474,7 +7481,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, /* getting back to object space */ Mat4Invert(imat,ob->obmat); - psmd->psys->lattice = psys_get_lattice(scene, ob, psmd->psys); + psmd->psys->lattice = psys_get_lattice(&sim); /* duplicate & displace vertices */ ehi= BLI_edgehashIterator_new(vertpahash); @@ -7502,7 +7509,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, Mat4MulVecfl(ob->obmat,loc0); state.time=cfra; - psys_get_particle_state(scene, ob, psmd->psys, i, &state,1); + psys_get_particle_state(&sim, i, &state, 1); vertco=CDDM_get_vert(explode,v)->co; @@ -7591,7 +7598,7 @@ static DerivedMesh * explodeModifier_applyModifier( { DerivedMesh *dm = derivedData; ExplodeModifierData *emd= (ExplodeModifierData*) md; - ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);; + ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md); if(psmd){ ParticleSystem * psys=psmd->psys; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index cce18e99157..0dc041bfc6a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -69,7 +69,7 @@ #include "BKE_particle.h" #include "BKE_DerivedMesh.h" #include "BKE_object.h" -#include "BKE_softbody.h" +#include "BKE_cloth.h" #include "BKE_material.h" #include "BKE_key.h" #include "BKE_library.h" @@ -85,7 +85,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float *fuv, float *orco, ParticleTexture *ptex, int event); static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex); -static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, +static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t); @@ -95,11 +95,10 @@ int count_particles(ParticleSystem *psys){ PARTICLE_P; int tot=0; - LOOP_PARTICLES { + LOOP_SHOWN_PARTICLES { if(pa->alive == PARS_KILLED); else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); - else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)); else tot++; } return tot; @@ -109,55 +108,14 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ PARTICLE_P; int tot=0; - LOOP_PARTICLES { + LOOP_SHOWN_PARTICLES { if(pa->alive == PARS_KILLED); else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); - else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)); else if(p%totgr==cur) tot++; } return tot; } -int psys_count_keys(ParticleSystem *psys) -{ - PARTICLE_P; - int totkey=0; - - LOOP_PARTICLES - totkey += pa->totkey; - - return totkey; -} -/* remember to free the pointer returned from this! */ -char *psys_menu_string(Object *ob, int for_sb) -{ - ParticleSystem *psys; - DynStr *ds; - char *str, num[6]; - int i; - - ds = BLI_dynstr_new(); - - if(for_sb) - BLI_dynstr_append(ds, "|Object%x-1"); - - for(i=0,psys=ob->particlesystem.first; psys; i++,psys=psys->next){ - - BLI_dynstr_append(ds, "|"); - sprintf(num,"%i. ",i+1); - BLI_dynstr_append(ds, num); - BLI_dynstr_append(ds, psys->part->id.name+2); - sprintf(num,"%%x%i",i+1); - BLI_dynstr_append(ds, num); - } - - str = BLI_dynstr_get_cstring(ds); - - BLI_dynstr_free(ds); - - return str; -} - /* we allocate path cache memory in chunks instead of a big continguous * chunk, windows' memory allocater fails to find big blocks of memory often */ @@ -257,30 +215,13 @@ Object *psys_find_object(Scene *scene, ParticleSystem *psys) return NULL; } -/* change object's active particle system */ -void psys_change_act(void *ob_v, void *act_v) -{ - Object *ob = ob_v; - ParticleSystem *npsys, *psys; - short act = *((short*)act_v)-1; - - if(act>=0){ - npsys=BLI_findlink(&ob->particlesystem,act); - psys=psys_get_current(ob); - - if(psys) - psys->flag &= ~PSYS_CURRENT; - if(npsys) - npsys->flag |= PSYS_CURRENT; - } -} -Object *psys_get_lattice(Scene *scene, Object *ob, ParticleSystem *psys) +Object *psys_get_lattice(ParticleSimulationData *sim) { Object *lattice=0; - if(psys_in_edit_mode(scene, psys)==0){ + if(psys_in_edit_mode(sim->scene, sim->psys)==0){ - ModifierData *md = (ModifierData*)psys_get_modifier(ob,psys); + ModifierData *md = (ModifierData*)psys_get_modifier(sim->ob, sim->psys); for(; md; md=md->next){ if(md->type==eModifierType_Lattice){ @@ -309,20 +250,20 @@ void psys_enable_all(Object *ob) for(; psys; psys=psys->next) psys->flag &= ~PSYS_DISABLED; } -int psys_ob_has_hair(Object *ob) -{ - ParticleSystem *psys = ob->particlesystem.first; - - for(; psys; psys=psys->next) - if(psys->part->type == PART_HAIR) - return 1; - - return 0; -} int psys_in_edit_mode(Scene *scene, ParticleSystem *psys) { return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit)); } +static void psys_create_frand(ParticleSystem *psys) +{ + int i; + float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms"); + + BLI_srandom(psys->seed); + + for(i=0; i<1024; i++, rand++) + *rand = BLI_frand(); +} int psys_check_enabled(Object *ob, ParticleSystem *psys) { ParticleSystemModifierData *psmd; @@ -344,6 +285,14 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys) } else if(!(psmd->modifier.mode & eModifierMode_Realtime)) return 0; + + /* perhaps not the perfect place, but we have to be sure the rands are there before usage */ + if(!psys->frand) + psys_create_frand(psys); + else if(psys->recalc & PSYS_RECALC_RESET) { + MEM_freeN(psys->frand); + psys_create_frand(psys); + } return 1; } @@ -423,7 +372,7 @@ void free_keyed_keys(ParticleSystem *psys) } } } -void free_child_path_cache(ParticleSystem *psys) +static void free_child_path_cache(ParticleSystem *psys) { psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs); psys->childcache = NULL; @@ -477,6 +426,24 @@ void psys_free_particles(ParticleSystem *psys) psys->totpart= 0; } } +void psys_free_pdd(ParticleSystem *psys) +{ + if(psys->pdd->cdata) + MEM_freeN(psys->pdd->cdata); + psys->pdd->cdata = NULL; + + if(psys->pdd->vdata) + MEM_freeN(psys->pdd->vdata); + psys->pdd->vdata = NULL; + + if(psys->pdd->ndata) + MEM_freeN(psys->pdd->ndata); + psys->pdd->ndata = NULL; + + if(psys->pdd->vedata) + MEM_freeN(psys->pdd->vedata); + psys->pdd->vedata = NULL; +} /* free everything */ void psys_free(Object *ob, ParticleSystem * psys) { @@ -530,6 +497,14 @@ void psys_free(Object *ob, ParticleSystem * psys) BLI_kdtree_free(psys->tree); + if(psys->frand) + MEM_freeN(psys->frand); + + if(psys->pdd) { + psys_free_pdd(psys); + MEM_freeN(psys->pdd); + } + MEM_freeN(psys); } } @@ -721,12 +696,12 @@ void psys_render_restore(Object *ob, ParticleSystem *psys) int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) { DerivedMesh *dm= ctx->dm; - Mesh *me= (Mesh*)(ctx->ob->data); + Mesh *me= (Mesh*)(ctx->sim.ob->data); MFace *mf, *mface; MVert *mvert; ParticleRenderData *data; ParticleRenderElem *elems, *elem; - ParticleSettings *part= ctx->psys->part; + ParticleSettings *part= ctx->sim.psys->part; float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp; float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport; double vprate; @@ -735,10 +710,10 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) if(part->ren_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) return tot; - if(!ctx->psys->renderdata) + if(!ctx->sim.psys->renderdata) return tot; - data= ctx->psys->renderdata; + data= ctx->sim.psys->renderdata; if(data->timeoffset) return 0; if(!(part->simplify_flag & PART_SIMPLIFY_ENABLE)) @@ -815,7 +790,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) /* set simplification parameters per original face */ for(a=0, elem=elems; apsys, facecenter[a], facearea[a], vprate, &viewport); + area = psys_render_projected_area(ctx->sim.psys, facecenter[a], facearea[a], vprate, &viewport); arearatio= fac*area/facearea[a]; if((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) { @@ -1437,7 +1412,7 @@ void psys_interpolate_mcol(MCol *mcol, int quad, float *w, MCol *mc) } } -float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values) +static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values) { if(values==0 || index==-1) return 0.0; @@ -2074,7 +2049,7 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float VECADDFAC(state->co,state->co,mat[0],rough[0]); VECADDFAC(state->co,state->co,mat[1],rough[1]); } -static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec) +static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec) { float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}; ParticleKey eff_key; @@ -2084,10 +2059,10 @@ static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, in VECCOPY(eff_key.vel,(ca-1)->vel); QUATCOPY(eff_key.rot,(ca-1)->rot); - pa= psys->particles+i; - do_effectors(i, pa, &eff_key, scene, ob, psys, rootco, force, vel, dfra, cfra); + pa= sim->psys->particles+i; + do_effectors(sim, i, pa, &eff_key, rootco, force, vel, dfra, cfra); - VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps); + VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps); VecAddf(force, force, vec); @@ -2154,12 +2129,12 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup) } return vg; } -void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys) +void psys_find_parents(ParticleSimulationData *sim) { - ParticleSettings *part=psys->part; + ParticleSettings *part=sim->psys->part; KDTree *tree; ChildParticle *cpa; - int p, totparent,totchild=psys->totchild; + int p, totparent,totchild=sim->psys->totchild; float co[3], orco[3]; int from=PART_FROM_FACE; totparent=(int)(totchild*part->parents*0.3); @@ -2169,15 +2144,15 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys tree=BLI_kdtree_new(totparent); - for(p=0,cpa=psys->child; pnum,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); + for(p=0,cpa=sim->psys->child; ppsmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); BLI_kdtree_insert(tree, p, orco, NULL); } BLI_kdtree_balance(tree); for(; pnum,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); + psys_particle_on_emitter(sim->psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); cpa->parent=BLI_kdtree_find_nearest(tree, orco, NULL, NULL); } @@ -2215,11 +2190,11 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa VECCOPY(nor, vnor); } -int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate) +static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate) { ParticleThreadContext *ctx= threads[0].ctx; - Object *ob= ctx->ob; - ParticleSystem *psys= ctx->psys; + Object *ob= ctx->sim.ob; + ParticleSystem *psys= ctx->sim.psys; ParticleSettings *part = psys->part; ParticleEditSettings *pset = &scene->toolsettings->particle; int totparent=0, between=0; @@ -2252,10 +2227,10 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in if(totchild==0) return 0; /* init random number generator */ - if(ctx->psys->part->flag & PART_ANIM_BRANCHING) - seed= 31415926 + ctx->psys->seed + (int)cfra; + if(ctx->sim.psys->part->flag & PART_ANIM_BRANCHING) + seed= 31415926 + ctx->sim.psys->seed + (int)cfra; else - seed= 31415926 + ctx->psys->seed; + seed= 31415926 + ctx->sim.psys->seed; if(part->flag & PART_BRANCHING || ctx->editupdate || totchild < 10000) totthread= 1; @@ -2273,7 +2248,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in ctx->parent_pass= 0; ctx->cfra= cfra; - psys->lattice = psys_get_lattice(scene, ob, psys); + psys->lattice = psys_get_lattice(&ctx->sim); /* cache all relevant vertex groups if they exist */ if(part->from!=PART_FROM_PARTICLE){ @@ -2299,11 +2274,11 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in } /* note: this function must be thread safe, except for branching! */ -void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i) +static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i) { ParticleThreadContext *ctx= thread->ctx; - Object *ob= ctx->ob; - ParticleSystem *psys = ctx->psys; + Object *ob= ctx->sim.ob; + ParticleSystem *psys = ctx->sim.psys; ParticleSettings *part = psys->part; ParticleCacheKey **cache= psys->childcache; ParticleCacheKey **pcache= psys->pathcache; @@ -2372,7 +2347,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, cpa_fuv = cpa->fuv; cpa_from = PART_FROM_FACE; - psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0); + psys_particle_on_emitter(ctx->sim.psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0); if(part->path_start==0.0f) { /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ @@ -2382,7 +2357,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, pa = psys->particles + cpa->parent; - psys_mat_hair_to_global(ob, ctx->psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat); pa=0; } @@ -2404,9 +2379,9 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, cpa_num=pa->num; cpa_fuv=pa->fuv; - psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0); + psys_particle_on_emitter(ctx->sim.psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0); - psys_mat_hair_to_global(ob, ctx->psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat); } keys->steps = ctx->steps; @@ -2423,7 +2398,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, /* get different child parameters from textures & vgroups */ get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); - if(ptex.exist < cpa->rand[1]) { + if(ptex.exist < PSYS_FRAND(i + 24)) { keys->steps = -1; return; } @@ -2472,7 +2447,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, if(part->flag & PART_CHILD_EFFECT) { for(k=0,state=keys; k<=ctx->steps; k++,state++) { if(k) { - do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec); + do_path_effectors(&ctx->sim, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec); } else { VecSubf(eff_vec,(state+1)->co,state->co); @@ -2498,7 +2473,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, } /* apply different deformations to the child path */ - do_child_modifiers(ctx->scene, ob, psys, part, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)state, t); + do_child_modifiers(&ctx->sim, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)state, t); /* TODO: better branching */ //if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING) @@ -2575,7 +2550,7 @@ static void *exec_child_path_cache(void *data) { ParticleThread *thread= (ParticleThread*)data; ParticleThreadContext *ctx= thread->ctx; - ParticleSystem *psys= ctx->psys; + ParticleSystem *psys= ctx->sim.psys; ParticleCacheKey **cache= psys->childcache; ChildParticle *cpa; int i, totchild= ctx->totchild, first= 0; @@ -2592,21 +2567,21 @@ static void *exec_child_path_cache(void *data) return 0; } -void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate) +void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupdate) { - ParticleSettings *part = psys->part; + ParticleSettings *part = sim->psys->part; ParticleThread *pthreads; ParticleThreadContext *ctx; ParticleCacheKey **cache; ListBase threads; int i, totchild, totparent, totthread; - if(psys->flag & PSYS_GLOBAL_HAIR) + if(sim->psys->flag & PSYS_GLOBAL_HAIR) return; - pthreads= psys_threads_create(scene, ob, psys); + pthreads= psys_threads_create(sim); - if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) { + if(!psys_threads_init_path(pthreads, sim->scene, cfra, editupdate)) { psys_threads_free(pthreads); return; } @@ -2615,14 +2590,14 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa totchild= ctx->totchild; totparent= ctx->totparent; - if(editupdate && psys->childcache && !(part->flag & PART_BRANCHING) && totchild == psys->totchildcache) { - cache = psys->childcache; + if(editupdate && sim->psys->childcache && !(part->flag & PART_BRANCHING) && totchild == sim->psys->totchildcache) { + cache = sim->psys->childcache; } else { /* clear out old and create new empty path cache */ - free_child_path_cache(psys); - psys->childcache= psys_alloc_path_cache_buffers(&psys->childcachebufs, totchild, ctx->steps+1); - psys->totchildcache = totchild; + free_child_path_cache(sim->psys); + sim->psys->childcache= psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps+1); + sim->psys->totchildcache = totchild; } totthread= pthreads[0].tot; @@ -2660,27 +2635,29 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa /* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */ /* -Makes child strands possible and creates them too into the cache. */ /* -Cached path data is also used to determine cut position for the editmode tool. */ -void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra) +void psys_cache_paths(ParticleSimulationData *sim, float cfra) { - ParticleCacheKey *ca, **cache= psys->pathcache; - ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); + PARTICLE_PSMD; + ParticleEditSettings *pset = &sim->scene->toolsettings->particle; + ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - ParticleEditSettings *pset = &scene->toolsettings->particle; + ParticleCacheKey *ca, **cache= psys->pathcache; DerivedMesh *hair_dm = psys->hair_out_dm; - ParticleData *pa = psys->particles; ParticleKey result; Material *ma; ParticleInterpolationData pind; + + PARTICLE_P; float birthtime = 0.0, dietime = 0.0; - float t, time = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec; + float t, time = 0.0, dfra = 1.0, frs_sec = sim->scene->r.frs_sec; float col[4] = {0.5f, 0.5f, 0.5f, 1.0f}; float prev_tangent[3], hairmat[4][4]; float rotmat[3][3]; - int k,i; + int k; int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step)); int totpart = psys->totpart; float length, vec[3]; @@ -2692,7 +2669,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) return; - if(psys_in_edit_mode(scene, psys)) + if(psys_in_edit_mode(sim->scene, psys)) if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0) return; @@ -2705,8 +2682,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra psys_free_path_cache(psys, psys->edit); cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1); - psys->lattice = psys_get_lattice(scene, ob, psys); - ma= give_current_material(ob, psys->part->omat); + psys->lattice = psys_get_lattice(sim); + ma= give_current_material(sim->ob, psys->part->omat); if(ma && (psys->part->draw & PART_DRAW_MAT_COL)) VECCOPY(col, &ma->r) @@ -2719,12 +2696,9 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra } /*---first main loop: create all actual particles' paths---*/ - for(i=0; iflag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) - continue; - + LOOP_SHOWN_PARTICLES { if(!psys->totchild) { - BLI_srandom(psys->seed + i); + BLI_srandom(psys->seed + p); pa_length = 1.0f - part->randlength * BLI_frand(); if(vg_length) pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length); @@ -2736,15 +2710,15 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); pind.dm = hair_dm; - memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); + memset(cache[p], 0, sizeof(*cache[p])*(steps+1)); - cache[i]->steps = steps; + cache[p]->steps = steps; /*--get the first data points--*/ - init_particle_interpolation(ob, psys, pa, &pind); + init_particle_interpolation(sim->ob, sim->psys, pa, &pind); /* hairmat is needed for for non-hair particle too so we get proper rotations */ - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, psmd->dm, psys->part->from, pa, hairmat); VECCOPY(rotmat[0], hairmat[2]); VECCOPY(rotmat[1], hairmat[1]); VECCOPY(rotmat[2], hairmat[0]); @@ -2760,26 +2734,26 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra } if(birthtime >= dietime) { - cache[i]->steps = -1; + cache[p]->steps = -1; continue; } dietime = birthtime + pa_length * (dietime - birthtime); /*--interpolate actual path from data points--*/ - for(k=0, ca=cache[i]; k<=steps; k++, ca++){ + for(k=0, ca=cache[p]; k<=steps; k++, ca++){ time = (float)k / (float)steps; t = birthtime + time * (dietime - birthtime); result.time = -t; - do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); + do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, &result); /* dynamic hair is in object space */ /* keyed and baked are allready in global space */ if(hair_dm) - Mat4MulVecfl(ob->obmat, result.co); + Mat4MulVecfl(sim->ob->obmat, result.co); else if(!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR)) Mat4MulVecfl(hairmat, result.co); @@ -2789,23 +2763,23 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra /*--modify paths and calculate rotation & velocity--*/ - VecSubf(vec,(cache[i]+1)->co,cache[i]->co); + VecSubf(vec,(cache[p]+1)->co,cache[p]->co); length = VecLength(vec); effector= 1.0f; if(vg_effector) effector*= psys_particle_value_from_verts(psmd->dm,psys->part->from,pa,vg_effector); - for(k=0, ca=cache[i]; k<=steps; k++, ca++) { + for(k=0, ca=cache[p]; k<=steps; k++, ca++) { if(!(psys->flag & PSYS_GLOBAL_HAIR)) { /* apply effectors */ if(!(psys->part->flag & PART_CHILD_EFFECT) && k) - do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec); + do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec); /* apply guide curves to path data */ if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0) /* ca is safe to cast, since only co and vel are used */ - do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors); + do_guide(sim->scene, (ParticleKey*)ca, p, (float)k/(float)steps, &psys->effectors); /* apply lattice */ if(psys->lattice) @@ -3021,23 +2995,6 @@ void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, flo if(time) *time=key->time; } /*-------changing particle keys from space to another-------*/ -void psys_key_to_object(Object *ob, ParticleKey *key, float imat[][4]){ - float q[4], imat2[4][4]; - - if(imat==0){ - Mat4Invert(imat2,ob->obmat); - imat=imat2; - } - - VECADD(key->vel,key->vel,key->co); - - Mat4MulVecfl(imat,key->co); - Mat4MulVecfl(imat,key->vel); - Mat4ToQuat(imat,q); - - VECSUB(key->vel,key->vel,key->co); - QuatMul(key->rot,q,key->rot); -} #if 0 static void key_from_object(Object *ob, ParticleKey *key){ float q[4]; @@ -3410,41 +3367,6 @@ void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int reca } } -LinkNode *psys_using_settings(struct Scene *scene, ParticleSettings *part, int flush_update) -{ - Object *ob, *tob; - ParticleSystem *psys, *tpsys; - LinkNode *node= NULL; - int found; - - /* update all that have same particle settings */ - for(ob=G.main->object.first; ob; ob=ob->id.next) { - found= 0; - - for(psys=ob->particlesystem.first; psys; psys=psys->next) { - if(psys->part == part) { - BLI_linklist_append(&node, psys); - found++; - } - else if(psys->part->type == PART_REACTOR){ - tob= (psys->target_ob)? psys->target_ob: ob; - tpsys= BLI_findlink(&tob->particlesystem, psys->target_psys-1); - - if(tpsys && tpsys->part==part) { - BLI_linklist_append(&node, tpsys); - found++; - } - } - } - - if(flush_update && found) - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - - return node; -} - - /************************************************/ /* Textures */ /************************************************/ @@ -3541,7 +3463,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float } if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); } } -void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event) +void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *pa, ParticleTexture *ptex, int event) { MTex *mtex; int m; @@ -3556,14 +3478,14 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd short blend=mtex->blendtype; short neg=mtex->pmaptoneg; - if((mtex->texco & TEXCO_UV) && ELEM(psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { - if(!get_particle_uv(psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) { + if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) { /* failed to get uv's, let's try orco's */ - psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0); + psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0); } } else { - psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0); + psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0); } externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3); @@ -3608,38 +3530,9 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd /************************************************/ /* Particle State */ /************************************************/ -float psys_get_timestep(ParticleSettings *part) +float psys_get_timestep(ParticleSimulationData *sim) { - return 0.04f*part->timetweak; -} -/* part->size should be updated with possible ipo effection before this is called */ -float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, IpoCurve *icu_size, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, float *vg_size) -{ - ParticleTexture ptex; - float size=1.0f; - - BLI_srandom(psys->seed + (pa - psys->particles) + 100); - - if(ma && part->from!=PART_FROM_PARTICLE){ - ptex.size=size; - psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_SIZE); - size=ptex.size; - } - -#if 0 // XXX old animation system - if(icu_size){ - calc_icu(icu_size,pa->time); - size*=icu_size->curval; - } -#endif // XXX old animation system - - if(vg_size) - size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size); - - if(part->randsize!=0.0) - size*= 1.0f - part->randsize * BLI_frand(); - - return size*part->size; + return 0.04f * sim->psys->part->timetweak; } float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *birthtime, float *dietime) { @@ -3654,7 +3547,7 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra, w++; } - life = part->lifetime*(1.0f-part->randlife*cpa->rand[1]); + life = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(cpa - psys->child + 25)); } else{ ParticleData *pa = psys->particles + cpa->parent; @@ -3703,13 +3596,16 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, size*=part->childsize; if(part->childrandsize!=0.0) - size *= 1.0f - part->childrandsize*cpa->rand[2]; + size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26); return size; } static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex) { - ptex->length= 1.0f - part->randlength*cpa->rand[0]; + ParticleSystem *psys = ctx->sim.psys; + int i = cpa - psys->child; + + ptex->length= 1.0f - part->randlength * PSYS_FRAND(i + 26); ptex->clump=1.0; ptex->kink=1.0; ptex->rough1= 1.0; @@ -3718,13 +3614,13 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread ptex->exist= 1.0; ptex->effector= 1.0; - ptex->length*= part->clength_thres < cpa->rand[1] ? part->clength : 1.0f; + ptex->length*= part->clength_thres < PSYS_FRAND(i + 27) ? part->clength : 1.0f; get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,ptex, MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH); - if(ptex->exist < cpa->rand[1]) + if(ptex->exist < PSYS_FRAND(i + 24)) return; if(ctx->vg_length) @@ -3742,18 +3638,20 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread if(ctx->vg_effector) ptex->effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector); } -static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t) +static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t) { + ParticleSettings *part = sim->psys->part; + int i = cpa - sim->psys->child; int guided = 0; if(part->flag & PART_CHILD_EFFECT) /* state is safe to cast, since only co and vel are used */ - guided = do_guide(scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors)); + guided = do_guide(sim->scene, (ParticleKey*)state, cpa->parent, t, &(sim->psys->effectors)); if(guided==0){ if(part->kink) do_prekink(state, par, par_rot, t, part->kink_freq * ptex->kink, part->kink_shape, - part->kink_amp, part->kink, part->kink_axis, ob->obmat); + part->kink_amp, part->kink, part->kink_axis, sim->ob->obmat); do_clump(state, par, t, part->clumpfac, part->clumppow, ptex->clump); } @@ -3762,17 +3660,18 @@ static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, P do_rough(orco, mat, t, ptex->rough1*part->rough1, part->rough1_size, 0.0, state); if(part->rough2 != 0.0 && ptex->rough2 != 0.0) - do_rough(cpa->rand, mat, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state); + do_rough(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state); if(part->rough_end != 0.0 && ptex->roughe != 0.0) - do_rough_end(cpa->rand, mat, t, ptex->roughe*part->rough_end, part->rough_end_shape, state); + do_rough_end(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, ptex->roughe*part->rough_end, part->rough_end_shape, state); } /* get's hair (or keyed) particles state at the "path time" specified in state->time */ -void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel) +void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, int vel) { - ParticleSettings *part = psys->part; - ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); - Material *ma = give_current_material(ob, part->omat); + PARTICLE_PSMD; + ParticleSystem *psys = sim->psys; + ParticleSettings *part = sim->psys->part; + Material *ma = give_current_material(sim->ob, part->omat); ParticleData *pa; ChildParticle *cpa; ParticleTexture ptex; @@ -3780,7 +3679,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i ParticleThreadContext ctx; /* fake thread context for child modifiers */ ParticleInterpolationData pind; - float t, frs_sec = scene->r.frs_sec; + float t, frs_sec = sim->scene->r.frs_sec; float co[3], orco[3]; float hairmat[4][4]; int totparent = 0; @@ -3808,17 +3707,17 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i pind.cache = cached ? psys->pointcache : NULL; pind.epoint = NULL; pind.dm = psys->hair_out_dm; - init_particle_interpolation(ob, psys, pa, &pind); + init_particle_interpolation(sim->ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state); if(!keyed && !cached) { if((pa->flag & PARS_REKEY)==0) { - psys_mat_hair_to_global(ob, psmd->dm, part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->dm, part->from, pa, hairmat); Mat4MulVecfl(hairmat, state->co); Mat4Mul3Vecfl(hairmat, state->vel); if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) { - do_guide(scene, state, p, state->time, &psys->effectors); + do_guide(sim->scene, state, p, state->time, &psys->effectors); /* TODO: proper velocity handling */ } @@ -3851,7 +3750,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i /* get parent states */ while(w<4 && cpa->pa[w]>=0){ keys[w].time = state->time; - psys_get_particle_on_path(scene, ob, psys, cpa->pa[w], keys+w, 1); + psys_get_particle_on_path(sim, cpa->pa[w], keys+w, 1); w++; } @@ -3871,14 +3770,14 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i pa = psys->particles + cpa->parent; - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat); pa=0; } else{ /* get the parent state */ keys->time = state->time; - psys_get_particle_on_path(scene, ob, psys, cpa->parent, keys,1); + psys_get_particle_on_path(sim, cpa->parent, keys,1); /* get the original coordinates (orco) for texture usage */ pa=psys->particles+cpa->parent; @@ -3889,7 +3788,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0); - psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat); } /* correct child ipo timing */ @@ -3938,7 +3837,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i copy_particle_key(&tstate, state, 1); /* apply different deformations to the child path */ - do_child_modifiers(scene, ob, psys, part, &ptex, par, par->rot, cpa, orco, hairmat, state, t); + do_child_modifiers(sim, &ptex, par, par->rot, cpa, orco, hairmat, state, t); /* try to estimate correct velocity */ if(vel){ @@ -3947,13 +3846,13 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i if(t>=0.001f){ tstate.time=t-0.001f; - psys_get_particle_on_path(scene,ob,psys,p,&tstate,0); + psys_get_particle_on_path(sim,p,&tstate,0); VECSUB(state->vel,state->co,tstate.co); Normalize(state->vel); } else{ tstate.time=t+0.001f; - psys_get_particle_on_path(scene, ob,psys,p,&tstate,0); + psys_get_particle_on_path(sim,p,&tstate,0); VECSUB(state->vel,tstate.co,state->co); Normalize(state->vel); } @@ -3963,39 +3862,52 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i } } /* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */ -int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int always){ - ParticleSettings *part=psys->part; - ParticleData *pa=0; +int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always){ + ParticleSystem *psys = sim->psys; + ParticleSettings *part = psys->part; + ParticleData *pa = NULL; + ChildParticle *cpa = NULL; float cfra; - int totpart=psys->totpart, between=0; + int totpart = psys->totpart, between = 0; /* negative time means "use current time" */ - if(state->time>0) - cfra=state->time; - else - cfra= bsystem_time(scene, 0, (float)scene->r.cfra,0.0); + cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0); - if(psys->totchild && p>=totpart){ - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ - between=1; + if(p>=totpart){ + if(!psys->totchild) + return 0; + + if(part->from != PART_FROM_PARTICLE && part->childtype == PART_CHILD_FACES){ + if(!(psys->flag & PSYS_KEYED)) + return 0; + + cpa = psys->child + p - totpart; + + state->time = psys_get_child_time(psys, cpa, cfra, NULL, NULL); + + if(!always) + if((state->time < 0.0 && !(part->flag & PART_UNBORN)) + || (state->time > 1.0 && !(part->flag & PART_DIED))) + return 0; + + state->time= (cfra - (part->sta + (part->end - part->sta) * PSYS_FRAND(p + 23))) / (part->lifetime * PSYS_FRAND(p + 24)); + + psys_get_particle_on_path(sim, p, state,1); + return 1; + } + else { + cpa = sim->psys->child + p - totpart; + pa = sim->psys->particles + cpa->parent; } - else - pa=psys->particles+(psys->child+p-totpart)->parent; } - else - pa=psys->particles+p; + else { + pa = sim->psys->particles + p; + } - if(between){ - state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra,NULL,NULL); + if(pa) { + if(pa->alive == PARS_KILLED) return 0; - if(always==0) - if((state->time<0.0 && (part->flag & PART_UNBORN)==0) - || (state->time>1.0 && (part->flag & PART_DIED)==0)) - return 0; - } - else{ - if(pa->alive==PARS_KILLED) return 0; - if(always==0) + if(!always) if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0) || (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0)) return 0; @@ -4003,38 +3915,28 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy state->time = MIN2(state->time, pa->dietime); } - if(psys->flag & PSYS_KEYED){ - if(between){ - ChildParticle *cpa=psys->child+p-totpart; - state->time= (cfra-(part->sta+(part->end-part->sta)*cpa->rand[0]))/(part->lifetime*cpa->rand[1]); - } - else - state->time= -cfra; - - psys_get_particle_on_path(scene, ob, psys, p, state,1); + if(sim->psys->flag & PSYS_KEYED){ + state->time= -cfra; + psys_get_particle_on_path(sim, p, state,1); return 1; } else{ - if(between) - return 0; /* currently not supported */ - else if(psys->totchild && p>=psys->totpart){ - ChildParticle *cpa=psys->child+p-psys->totpart; + if(cpa){ ParticleKey *key1; float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime; - pa = psys->particles + cpa->parent; key1=&pa->state; offset_child(cpa, key1, state, part->childflat, part->childrad); CLAMP(t,0.0,1.0); if(part->kink) /* TODO: part->kink_freq*pa_kink */ - do_prekink(state,key1,key1->rot,t,part->kink_freq,part->kink_shape,part->kink_amp,part->kink,part->kink_axis,ob->obmat); + do_prekink(state,key1,key1->rot,t,part->kink_freq,part->kink_shape,part->kink_amp,part->kink,part->kink_axis,sim->ob->obmat); /* TODO: pa_clump vgroup */ do_clump(state,key1,t,part->clumpfac,part->clumppow,1.0); if(psys->lattice) - calc_latt_deform(psys->lattice, state->co,1.0f); + calc_latt_deform(sim->psys->lattice, state->co,1.0f); } else{ if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)) @@ -4045,7 +3947,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy /* let's interpolate to try to be as accurate as possible */ if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) { ParticleKey keys[4]; - float dfra, keytime, frs_sec = scene->r.frs_sec; + float dfra, keytime, frs_sec = sim->scene->r.frs_sec; if(pa->prev_state.time >= pa->state.time) { /* prev_state is wrong so let's not use it, this can happen at frame 1 or particle birth */ @@ -4080,8 +3982,8 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy } } - if(psys->lattice) - calc_latt_deform(psys->lattice, state->co,1.0f); + if(sim->psys->lattice) + calc_latt_deform(sim->psys->lattice, state->co,1.0f); } return 1; @@ -4137,8 +4039,11 @@ void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemMo } } -void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale) +void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale) { + Object *ob = sim->ob; + ParticleSystem *psys = sim->psys; + ParticleSystemModifierData *psmd = sim->psmd; float loc[3], nor[3], vec[3], side[3], len, obrotmat[4][4], qmat[4][4]; float xvec[3] = {-1.0, 0.0, 0.0}, q[4]; @@ -4146,7 +4051,7 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys len= Normalize(vec); if(pa) - psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0); + psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0); else psys_particle_on_emitter(psmd, (psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE, diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 26d23399316..9cd897e4bcd 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -164,20 +164,22 @@ void psys_reset(ParticleSystem *psys, int mode) psys->pointcache->simframe= 0; } -static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) +static void realloc_particles(ParticleSimulationData *sim, int new_totpart) { + ParticleSystem *psys = sim->psys; + ParticleSettings *part = psys->part; ParticleData *newpars = NULL; BoidParticle *newboids = NULL; PARTICLE_P; int totpart, totsaved = 0; if(new_totpart<0) { - if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) { - totpart= psys->part->grid_res; + if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT) { + totpart= part->grid_res; totpart*=totpart*totpart; } else - totpart=psys->part->totpart; + totpart=part->totpart; } else totpart=new_totpart; @@ -212,6 +214,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) if(pa->hair) MEM_freeN(pa->hair); MEM_freeN(psys->particles); + psys_free_pdd(psys); } psys->particles=newpars; @@ -605,13 +608,13 @@ static int binary_search_distribution(float *sum, int n, float value) /* note: this function must be thread safe, for from == PART_FROM_CHILD */ #define ONLY_WORKING_WITH_PA_VERTS 0 -void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p) +static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p) { ParticleThreadContext *ctx= thread->ctx; - Object *ob= ctx->ob; + Object *ob= ctx->sim.ob; DerivedMesh *dm= ctx->dm; ParticleData *tpa; - ParticleSettings *part= ctx->psys->part; + ParticleSettings *part= ctx->sim.psys->part; float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3]; float cur_d, min_d, randu, randv; int from= ctx->from; @@ -624,7 +627,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C pa->num= ctx->index[p]; pa->fuv[0] = 1.0f; pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0; - //pa->verts[0] = pa->verts[1] = pa->verts[2] = 0; #if ONLY_WORKING_WITH_PA_VERTS if(ctx->tree){ @@ -652,7 +654,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel); psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv); ctx->jitoff[i]++; - //ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel); break; case PART_DISTR_RAND: randu= rng_getFloat(thread->rng); @@ -662,12 +663,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C } pa->foffset= 0.0f; - /* - pa->verts[0] = mface->v1; - pa->verts[1] = mface->v2; - pa->verts[2] = mface->v3; - */ - /* experimental */ if(from==PART_FROM_VOLUME){ MVert *mvert=dm->getVertDataArray(dm,CD_MVERT); @@ -723,10 +718,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C } } else if(from == PART_FROM_PARTICLE) { - //pa->verts[0]=0; /* not applicable */ - //pa->verts[1]=0; - //pa->verts[2]=0; - tpa=ctx->tpars+ctx->index[p]; pa->num=ctx->index[p]; pa->fuv[0]=tpa->fuv[0]; @@ -742,42 +733,30 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C cpa->num=0; cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f; cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0; - cpa->rand[0]=cpa->rand[1]=cpa->rand[2]=0.0f; return; } mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE); - //switch(distr){ - // case PART_DISTR_JIT: - // i=index[p]; - // psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mf->v4, cpa->fuv); - // ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel); - // break; - // case PART_DISTR_RAND: - randu= rng_getFloat(thread->rng); - randv= rng_getFloat(thread->rng); - psys_uv_to_w(randu, randv, mf->v4, cpa->fuv); - // break; - //} + randu= rng_getFloat(thread->rng); + randv= rng_getFloat(thread->rng); + psys_uv_to_w(randu, randv, mf->v4, cpa->fuv); - cpa->rand[0] = rng_getFloat(thread->rng); - cpa->rand[1] = rng_getFloat(thread->rng); - cpa->rand[2] = rng_getFloat(thread->rng); cpa->num = ctx->index[p]; if(ctx->tree){ KDTreeNearest ptn[10]; - int w,maxw, do_seams; + int w,maxw;//, do_seams; float maxd,mind,dd,totw=0.0; int parent[10]; float pweight[10]; - do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams); + /*do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);*/ psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1); transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1); - maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn); + //maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn); + maxw = BLI_kdtree_find_n_nearest(ctx->tree,4,orco1,ornor1,ptn); maxd=ptn[maxw-1].dist; mind=ptn[0].dist; @@ -787,70 +766,68 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C for(w=0; wseams; - float temp[3],temp2[3],tan[3]; - float inp,cur_len,min_len=10000.0f; - int min_seam=0, near_vert=0; - /* find closest seam */ - for(i=0; itotseam; i++, seam++){ - VecSubf(temp,co1,seam->v0); - inp=Inpf(temp,seam->dir)/seam->length2; - if(inp<0.0f){ - cur_len=VecLenf(co1,seam->v0); - } - else if(inp>1.0f){ - cur_len=VecLenf(co1,seam->v1); - } - else{ - VecCopyf(temp2,seam->dir); - VecMulf(temp2,inp); - cur_len=VecLenf(temp,temp2); - } - if(cur_len1.0f) near_vert=1; - else near_vert=0; - } - } - seam=ctx->seams+min_seam; - - VecCopyf(temp,seam->v0); - - if(near_vert){ - if(near_vert==-1) - VecSubf(tan,co1,seam->v0); - else{ - VecSubf(tan,co1,seam->v1); - VecCopyf(temp,seam->v1); - } + //if(do_seams){ + // ParticleSeam *seam=ctx->seams; + // float temp[3],temp2[3],tan[3]; + // float inp,cur_len,min_len=10000.0f; + // int min_seam=0, near_vert=0; + // /* find closest seam */ + // for(i=0; itotseam; i++, seam++){ + // VecSubf(temp,co1,seam->v0); + // inp=Inpf(temp,seam->dir)/seam->length2; + // if(inp<0.0f){ + // cur_len=VecLenf(co1,seam->v0); + // } + // else if(inp>1.0f){ + // cur_len=VecLenf(co1,seam->v1); + // } + // else{ + // VecCopyf(temp2,seam->dir); + // VecMulf(temp2,inp); + // cur_len=VecLenf(temp,temp2); + // } + // if(cur_len1.0f) near_vert=1; + // else near_vert=0; + // } + // } + // seam=ctx->seams+min_seam; + // + // VecCopyf(temp,seam->v0); + // + // if(near_vert){ + // if(near_vert==-1) + // VecSubf(tan,co1,seam->v0); + // else{ + // VecSubf(tan,co1,seam->v1); + // VecCopyf(temp,seam->v1); + // } + + // Normalize(tan); + // } + // else{ + // VecCopyf(tan,seam->tan); + // VecSubf(temp2,co1,temp); + // if(Inpf(tan,temp2)<0.0f) + // VecNegf(tan); + // } + // for(w=0; wtan); - VecSubf(temp2,co1,temp); - if(Inpf(tan,temp2)<0.0f) - VecNegf(tan); - } - for(w=0; w=0){ @@ -876,7 +853,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C static void *exec_distribution(void *data) { ParticleThread *thread= (ParticleThread*)data; - ParticleSystem *psys= thread->ctx->psys; + ParticleSystem *psys= thread->ctx->sim.psys; ParticleData *pa; ChildParticle *cpa; int p, totpart; @@ -943,11 +920,11 @@ static int compare_orig_index(const void *p1, const void *p2) /* 6. and we're done! */ /* This is to denote functionality that does not yet work with mesh - only derived mesh */ -int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from) +static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from) { ParticleThreadContext *ctx= threads[0].ctx; - Object *ob= ctx->ob; - ParticleSystem *psys= ctx->psys; + Object *ob= ctx->sim.ob; + ParticleSystem *psys= ctx->sim.psys; Object *tob; ParticleData *pa=0, *tpars= 0; ParticleSettings *part; @@ -999,49 +976,49 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive totpart=get_psys_tot_child(scene, psys); cfrom=from=PART_FROM_FACE; - if(part->flag&PART_CHILD_SEAMS){ - MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE); - MVert *mvert=dm->getVertDataArray(dm,CD_MVERT); - int totedge=dm->getNumEdges(dm); + //if(part->flag&PART_CHILD_SEAMS){ + // MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE); + // MVert *mvert=dm->getVertDataArray(dm,CD_MVERT); + // int totedge=dm->getNumEdges(dm); - for(p=0, ed=medge; pflag&ME_SEAM) - totseam++; + // for(p=0, ed=medge; pflag&ME_SEAM) + // totseam++; - if(totseam){ - ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams"); - float temp[3],temp2[3]; + // if(totseam){ + // ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams"); + // float temp[3],temp2[3]; - for(p=0, ed=medge; pflag&ME_SEAM){ - VecCopyf(cur_seam->v0,(mvert+ed->v1)->co); - VecCopyf(cur_seam->v1,(mvert+ed->v2)->co); + // for(p=0, ed=medge; pflag&ME_SEAM){ + // VecCopyf(cur_seam->v0,(mvert+ed->v1)->co); + // VecCopyf(cur_seam->v1,(mvert+ed->v2)->co); - VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0); + // VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0); - cur_seam->length2=VecLength(cur_seam->dir); - cur_seam->length2*=cur_seam->length2; + // cur_seam->length2=VecLength(cur_seam->dir); + // cur_seam->length2*=cur_seam->length2; - temp[0]=(float)((mvert+ed->v1)->no[0]); - temp[1]=(float)((mvert+ed->v1)->no[1]); - temp[2]=(float)((mvert+ed->v1)->no[2]); - temp2[0]=(float)((mvert+ed->v2)->no[0]); - temp2[1]=(float)((mvert+ed->v2)->no[1]); - temp2[2]=(float)((mvert+ed->v2)->no[2]); + // temp[0]=(float)((mvert+ed->v1)->no[0]); + // temp[1]=(float)((mvert+ed->v1)->no[1]); + // temp[2]=(float)((mvert+ed->v1)->no[2]); + // temp2[0]=(float)((mvert+ed->v2)->no[0]); + // temp2[1]=(float)((mvert+ed->v2)->no[1]); + // temp2[2]=(float)((mvert+ed->v2)->no[2]); - VecAddf(cur_seam->nor,temp,temp2); - Normalize(cur_seam->nor); + // VecAddf(cur_seam->nor,temp,temp2); + // Normalize(cur_seam->nor); - Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor); + // Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor); - Normalize(cur_seam->tan); + // Normalize(cur_seam->tan); - cur_seam++; - } - } - } - - } + // cur_seam++; + // } + // } + // } + // + //} } else{ /* no need to figure out distribution */ @@ -1063,10 +1040,6 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive length=VecLength(cpa->fuv); } - cpa->rand[0]=BLI_frand(); - cpa->rand[1]=BLI_frand(); - cpa->rand[2]=BLI_frand(); - cpa->num=-1; } } @@ -1345,7 +1318,6 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive jitlevel= totpart/tot; if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */ if(jitlevel<3) jitlevel= 3; - //if(jitlevel>100) jitlevel= 100; } jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit"); @@ -1364,7 +1336,7 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive ctx->tree= tree; ctx->seams= seams; ctx->totseam= totseam; - ctx->psys= psys; + ctx->sim.psys= psys; ctx->index= index; ctx->jit= jit; ctx->jitlevel= jitlevel; @@ -1385,7 +1357,7 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive if(!children || psys->totchild < 10000) totthread= 1; - seed= 31415926 + ctx->psys->seed; + seed= 31415926 + ctx->sim.psys->seed; for(i=0; ipsmd->dm; ListBase threads; ParticleThread *pthreads; ParticleThreadContext *ctx; int i, totthread; - pthreads= psys_threads_create(scene, ob, psys); + pthreads= psys_threads_create(sim); - if(!psys_threads_init_distribution(pthreads, scene, finaldm, from)) { + if(!psys_threads_init_distribution(pthreads, sim->scene, finaldm, from)) { psys_threads_free(pthreads); return; } @@ -1420,7 +1393,7 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec else exec_distribution(&pthreads[0]); - psys_calc_dmcache(ob, finaldm, psys); + psys_calc_dmcache(sim->ob, finaldm, sim->psys); ctx= pthreads[0].ctx; if(ctx->dm != finaldm) @@ -1430,8 +1403,9 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec } /* ready for future use, to emit particles without geometry */ -static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from) +static void distribute_particles_on_shape(ParticleSimulationData *sim, int from) { + ParticleSystem *psys = sim->psys; PARTICLE_P; fprintf(stderr,"Shape emission not yet possible!\n"); @@ -1442,22 +1416,22 @@ static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int pa->num= -1; } } -static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys, int from) +static void distribute_particles(ParticleSimulationData *sim, int from) { - ParticleSystemModifierData *psmd=0; + PARTICLE_PSMD; int distr_error=0; - psmd=psys_get_modifier(ob,psys); if(psmd){ if(psmd->dm) - distribute_particles_on_dm(psmd->dm, scene, ob, psys, from); + distribute_particles_on_dm(sim, from); else distr_error=1; } else - distribute_particles_on_shape(ob,psys,from); + distribute_particles_on_shape(sim, from); if(distr_error){ + ParticleSystem *psys = sim->psys; PARTICLE_P; fprintf(stderr,"Particle distribution error!\n"); @@ -1471,26 +1445,23 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys, } /* threaded child particle distribution and path caching */ -ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys) +ParticleThread *psys_threads_create(ParticleSimulationData *sim) { ParticleThread *threads; ParticleThreadContext *ctx; int i, totthread; - if(scene->r.mode & R_FIXED_THREADS) - totthread= scene->r.threads; + if(sim->scene->r.mode & R_FIXED_THREADS) + totthread= sim->scene->r.threads; else totthread= BLI_system_thread_count(); threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread"); ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext"); - ctx->scene= scene; - ctx->ob= ob; - ctx->psys= psys; - ctx->psmd= psys_get_modifier(ob, psys); - ctx->dm= ctx->psmd->dm; - ctx->ma= give_current_material(ob, psys->part->omat); + ctx->sim = *sim; + ctx->dm= ctx->sim.psmd->dm; + ctx->ma= give_current_material(sim->ob, sim->psys->part->omat); memset(threads, 0, sizeof(ParticleThread)*totthread); @@ -1522,9 +1493,9 @@ void psys_threads_free(ParticleThread *threads) if(ctx->vg_roughe) MEM_freeN(ctx->vg_roughe); - if(ctx->psys->lattice){ - end_latt_deform(ctx->psys->lattice); - ctx->psys->lattice= NULL; + if(ctx->sim.psys->lattice){ + end_latt_deform(ctx->sim.psys->lattice); + ctx->sim.psys->lattice= NULL; } /* distribution */ @@ -1550,37 +1521,34 @@ void psys_threads_free(ParticleThread *threads) } /* set particle parameters that don't change during particle's life */ -void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd) +void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p) { - ParticleSettings *part; + ParticleSettings *part = sim->psys->part; ParticleTexture ptex; Material *ma=0; //IpoCurve *icu=0; // XXX old animation system int totpart; - float rand; - - part=psys->part; - totpart=psys->totpart; + totpart=sim->psys->totpart; ptex.life=ptex.size=ptex.exist=ptex.length=1.0; ptex.time=(float)p/(float)totpart; - BLI_srandom(psys->seed+p); + BLI_srandom(sim->psys->seed + p + 125); if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){ - ma=give_current_material(ob,part->omat); + ma=give_current_material(sim->ob,part->omat); /* TODO: needs some work to make most blendtypes generally usefull */ - psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_INIT); + psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT); } pa->lifetime= part->lifetime*ptex.life; if(part->type==PART_HAIR) pa->time= 0.0f; - else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0) - pa->time= 300000.0f; /* max frame */ + //else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0) + // pa->time= 300000.0f; /* max frame */ else{ //icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME); //if(icu){ @@ -1604,10 +1572,8 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps } #endif // XXX old animation system - /* need to get every rand even if we don't use them so that randoms don't affect each other */ - rand= BLI_frand(); if(part->randlife!=0.0) - pa->lifetime*= 1.0f - part->randlife*rand; + pa->lifetime*= 1.0f - part->randlife * BLI_frand(); } pa->dietime= pa->time+pa->lifetime; @@ -1624,13 +1590,14 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps /* usage other than straight after distribute has to handle this index by itself - jahka*/ //pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */ } -static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd) +static void initialize_all_particles(ParticleSimulationData *sim) { //IpoCurve *icu=0; // XXX old animation system + ParticleSystem *psys = sim->psys; PARTICLE_P; LOOP_PARTICLES - initialize_particle(pa,p,ob,psys,psmd); + initialize_particle(sim, pa, p); if(psys->part->type != PART_FLUID) { #if 0 // XXX old animation system @@ -1687,66 +1654,51 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS } } /* sets particle to the emitter surface with initial velocity & rotation */ -void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob, - float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot) +void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra) { + Object *ob = sim->ob; + ParticleSystem *psys = sim->psys; ParticleSettings *part; ParticleTexture ptex; ParticleKey state; //IpoCurve *icu=0; // XXX old animation system - float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4]; + float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4]; float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0}; float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0}; - float q_phase[4], length, r_phase; + float q_phase[4], r_phase; + int p = pa - psys->particles; part=psys->part; ptex.ivel=1.0; - BLI_srandom(psys->seed + (pa - psys->particles)); - /* we need to get every random even if they're not used so that they don't effect eachother */ - /* while loops are to have a spherical distribution (avoid cubic distribution) */ - length=2.0f; - while(length>1.0){ - r_vel[0]=2.0f*(BLI_frand()-0.5f); - r_vel[1]=2.0f*(BLI_frand()-0.5f); - r_vel[2]=2.0f*(BLI_frand()-0.5f); - length=VecLength(r_vel); - } - - length=2.0f; - while(length>1.0){ - r_ave[0]=2.0f*(BLI_frand()-0.5f); - r_ave[1]=2.0f*(BLI_frand()-0.5f); - r_ave[2]=2.0f*(BLI_frand()-0.5f); - length=VecLength(r_ave); - } - - r_rot[0]=2.0f*(BLI_frand()-0.5f); - r_rot[1]=2.0f*(BLI_frand()-0.5f); - r_rot[2]=2.0f*(BLI_frand()-0.5f); - r_rot[3]=2.0f*(BLI_frand()-0.5f); - + r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f); + r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f); + r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f); + + r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f); + r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f); + r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f); + + r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f); + r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f); + r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f); + r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f); NormalQuat(r_rot); - r_phase = BLI_frand(); + r_phase = PSYS_FRAND(p + 20); if(part->from==PART_FROM_PARTICLE){ - Object *tob; - ParticleSystem *tpsys=0; + ParticleSimulationData tsim = {sim->scene, psys->target_ob ? psys->target_ob : ob, NULL, NULL}; float speed; - tob=psys->target_ob; - if(tob==0) - tob=ob; - - tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1); + tsim.psys = BLI_findlink(&tsim.ob->particlesystem, sim->psys->target_psys-1); state.time = pa->time; if(pa->num == -1) memset(&state, 0, sizeof(state)); else - psys_get_particle_state(scene, tob,tpsys,pa->num,&state,1); + psys_get_particle_state(&tsim, pa->num, &state, 1); psys_get_from_key(&state, loc, nor, rot, 0); QuatMulVecf(rot, vtan); @@ -1763,23 +1715,20 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic } else{ /* get precise emitter matrix if particle is born */ - if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= psys->cfra) - where_is_object_time(scene, ob,pa->time); + if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra) + where_is_object_time(sim->scene, sim->ob, pa->time); /* get birth location from object */ if(part->tanfac!=0.0) - psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); + psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); else - psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0); - - /* save local coordinates for later */ - VECCOPY(tloc,loc); + psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0); /* get possible textural influence */ - psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL); + psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL); - if(vg_vel && pa->num != -1) - ptex.ivel*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_vel); + //if(vg_vel && pa->num != -1) + // ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel); /* particles live in global space so */ /* let's convert: */ @@ -1787,21 +1736,18 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic Mat4MulVecfl(ob->obmat,loc); /* -normal */ - VECADD(nor,tloc,nor); - Mat4MulVecfl(ob->obmat,nor); - VECSUB(nor,nor,loc); + Mat4Mul3Vecfl(ob->obmat,nor); Normalize(nor); /* -tangent */ if(part->tanfac!=0.0){ - float phase=vg_rot?2.0f*(psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f; + //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f; + float phase=0.0f; VecMulf(vtan,-(float)cos(M_PI*(part->tanphase+phase))); fac=-(float)sin(M_PI*(part->tanphase+phase)); VECADDFAC(vtan,vtan,utan,fac); - VECADD(vtan,tloc,vtan); - Mat4MulVecfl(ob->obmat,vtan); - VECSUB(vtan,vtan,loc); + Mat4Mul3Vecfl(ob->obmat,vtan); VECCOPY(utan,nor); VecMulf(utan,Inpf(vtan,nor)); @@ -1853,11 +1799,6 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic if(part->acc[2]!=0.0f) bpa->gravity[2] = part->acc[2]; - //pa->r_ve[0] = pa->r_ve[1] = 0.0f; - //pa->r_ve[2] = -1.0f; - //if(part->acc[2]!=0.0f) - // pa->r_ve[2] = part->acc[2]; - /* calculate rotation matrix */ Projf(dvec, r_vel, pa->state.ave); VecSubf(mat[0], pa->state.ave, dvec); @@ -1896,8 +1837,9 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic VECADDFAC(vel,vel,nor,part->normfac); /* *emitter tangent */ - if(psmd && part->tanfac!=0.0) - VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_tan):1.0f)); + if(sim->psmd && part->tanfac!=0.0) + VECADDFAC(vel,vel,vtan,part->tanfac); + //VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f)); /* *texture */ /* TODO */ @@ -1917,9 +1859,6 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic //} VecMulf(vel,ptex.ivel); - - //if(ELEM(part->phystype, PART_PHYS_GRADU_EX, PART_PHYS_GRADU_SIM)) - // VecAddf(vel,vel,part->acc); VECCOPY(pa->state.vel,vel); @@ -2001,22 +1940,20 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic pa->alive = PARS_UNBORN; pa->state.time = cfra; - -// pa->flag &= ~PARS_STICKY; } -static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from) +static void reset_all_particles(ParticleSimulationData *sim, float dtime, float cfra, int from) { ParticleData *pa; - int p, totpart=psys->totpart; - float *vg_vel=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL); - float *vg_tan=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN); - float *vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT); + int p, totpart=sim->psys->totpart; + //float *vg_vel=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_VEL); + //float *vg_tan=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_TAN); + //float *vg_rot=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_ROT); - for(p=from, pa=psys->particles+from; ppsys->particles+from; ppsys, *kpsys; ParticleTarget *pt = psys->targets.first; int keys_valid = 1; psys->totkeyed = 0; for(; pt; pt=pt->next) { - kpsys = psys_get_target_system(ob, pt); + kpsys = psys_get_target_system(sim->ob, pt); if(kpsys && kpsys->totpart) { psys->totkeyed += keys_valid; @@ -2064,9 +2001,10 @@ void psys_count_keyed_targets(Object *ob, ParticleSystem *psys) psys->totkeyed *= psys->flag & PSYS_KEYED_TIMING ? 1 : psys->part->keyed_loops; } -static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) +static void set_keyed_keys(ParticleSimulationData *sim) { - ParticleSystem *kpsys = psys; + ParticleSystem *psys = sim->psys; + ParticleSimulationData ksim = {sim->scene, NULL, NULL, NULL}; ParticleTarget *pt; PARTICLE_P; ParticleKey *key; @@ -2096,16 +2034,14 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) pt = psys->targets.first; for(k=0; kob) - kpsys = BLI_findlink(&pt->ob->particlesystem, pt->psys - 1); - else - kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1); + ksim.ob = pt->ob ? pt->ob : sim->ob; + ksim.psys = BLI_findlink(&ksim.ob->particlesystem, pt->psys - 1); LOOP_PARTICLES { key = pa->keys + k; key->time = -1.0; /* use current time */ - psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1); + psys_get_particle_state(&ksim, p%ksim.psys->totpart, key, 1); if(psys->flag & PSYS_KEYED_TIMING){ key->time = pa->time + pt->time; @@ -2131,111 +2067,109 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) /************************************************/ /* Reactors */ /************************************************/ -static void push_reaction(Object* ob, ParticleSystem *psys, int pa_num, int event, ParticleKey *state) -{ - Object *rob; - ParticleSystem *rpsys; - ParticleSettings *rpart; - ParticleData *pa; - ListBase *lb=&psys->effectors; - ParticleEffectorCache *ec; - ParticleReactEvent *re; - - if(lb->first) for(ec = lb->first; ec; ec= ec->next){ - if(ec->type & PSYS_EC_REACTOR){ - /* all validity checks already done in add_to_effectors */ - rob=ec->ob; - rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr); - rpart=rpsys->part; - if(rpsys->part->reactevent==event){ - pa=psys->particles+pa_num; - re= MEM_callocN(sizeof(ParticleReactEvent), "react event"); - re->event=event; - re->pa_num = pa_num; - re->ob = ob; - re->psys = psys; - re->size = pa->size; - copy_particle_key(&re->state,state,1); - - switch(event){ - case PART_EVENT_DEATH: - re->time=pa->dietime; - break; - case PART_EVENT_COLLIDE: - re->time=state->time; - break; - case PART_EVENT_NEAR: - re->time=state->time; - break; - } - - BLI_addtail(&rpsys->reactevents, re); - } - } - } -} -static void react_to_events(ParticleSystem *psys, int pa_num) -{ - ParticleSettings *part=psys->part; - ParticleData *pa=psys->particles+pa_num; - ParticleReactEvent *re=psys->reactevents.first; - int birth=0; - float dist=0.0f; - - for(re=psys->reactevents.first; re; re=re->next){ - birth=0; - if(part->from==PART_FROM_PARTICLE){ - if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){ - if(re->event==PART_EVENT_NEAR){ - ParticleData *tpa = re->psys->particles+re->pa_num; - float pa_time=tpa->time + pa->foffset*tpa->lifetime; - if(re->time >= pa_time){ - pa->time=pa_time; - pa->dietime=pa->time+pa->lifetime; - } - } - else{ - pa->time=re->time; - pa->dietime=pa->time+pa->lifetime; - } - } - } - else{ - dist=VecLenf(pa->state.co, re->state.co); - if(dist <= re->size){ - if(pa->alive==PARS_UNBORN){ - pa->time=re->time; - pa->dietime=pa->time+pa->lifetime; - birth=1; - } - if(birth || part->flag&PART_REACT_MULTIPLE){ - float vec[3]; - VECSUB(vec,pa->state.co, re->state.co); - if(birth==0) - VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape)); - VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac); - VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac); - } - if(birth) - VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape)); - } - } - } -} -void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_ob, ParticleSystem **target_psys) -{ - Object *tob; - - tob=psys->target_ob; - if(tob==0) - tob=ob; - - *target_psys=BLI_findlink(&tob->particlesystem,psys->target_psys-1); - if(*target_psys) - *target_ob=tob; - else - *target_ob=0; -} +//static void push_reaction(ParticleSimulationData *sim, int pa_num, int event, ParticleKey *state) +//{ +// Object *rob; +// ParticleSystem *rpsys; +// ParticleSettings *rpart; +// ParticleData *pa; +// ListBase *lb=&sim->psys->effectors; +// ParticleEffectorCache *ec; +// ParticleReactEvent *re; +// +// if(lb->first) for(ec = lb->first; ec; ec= ec->next){ +// if(ec->type & PSYS_EC_REACTOR){ +// /* all validity checks already done in add_to_effectors */ +// rob=ec->ob; +// rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr); +// rpart=rpsys->part; +// if(rpsys->part->reactevent==event){ +// pa=sim->psys->particles+pa_num; +// re= MEM_callocN(sizeof(ParticleReactEvent), "react event"); +// re->event=event; +// re->pa_num = pa_num; +// re->ob = sim->ob; +// re->psys = sim->psys; +// re->size = pa->size; +// copy_particle_key(&re->state,state,1); +// +// switch(event){ +// case PART_EVENT_DEATH: +// re->time=pa->dietime; +// break; +// case PART_EVENT_COLLIDE: +// re->time=state->time; +// break; +// case PART_EVENT_NEAR: +// re->time=state->time; +// break; +// } +// +// BLI_addtail(&rpsys->reactevents, re); +// } +// } +// } +//} +//static void react_to_events(ParticleSystem *psys, int pa_num) +//{ +// ParticleSettings *part=psys->part; +// ParticleData *pa=psys->particles+pa_num; +// ParticleReactEvent *re=psys->reactevents.first; +// int birth=0; +// float dist=0.0f; +// +// for(re=psys->reactevents.first; re; re=re->next){ +// birth=0; +// if(part->from==PART_FROM_PARTICLE){ +// if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){ +// if(re->event==PART_EVENT_NEAR){ +// ParticleData *tpa = re->psys->particles+re->pa_num; +// float pa_time=tpa->time + pa->foffset*tpa->lifetime; +// if(re->time >= pa_time){ +// pa->time=pa_time; +// pa->dietime=pa->time+pa->lifetime; +// } +// } +// else{ +// pa->time=re->time; +// pa->dietime=pa->time+pa->lifetime; +// } +// } +// } +// else{ +// dist=VecLenf(pa->state.co, re->state.co); +// if(dist <= re->size){ +// if(pa->alive==PARS_UNBORN){ +// pa->time=re->time; +// pa->dietime=pa->time+pa->lifetime; +// birth=1; +// } +// if(birth || part->flag&PART_REACT_MULTIPLE){ +// float vec[3]; +// VECSUB(vec,pa->state.co, re->state.co); +// if(birth==0) +// VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape)); +// VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac); +// VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac); +// } +// if(birth) +// VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape)); +// } +// } +// } +//} +//void psys_get_reactor_target(ParticleSimulationData *sim, Object **target_ob, ParticleSystem **target_psys) +//{ +// Object *tob; +// +// tob = sim->psys->target_ob ? sim->psys->target_ob : sim->ob; +// +// *target_psys = BLI_findlink(&tob->particlesystem, sim->psys->target_psys-1); +// if(*target_psys) +// *target_ob=tob; +// else +// *target_ob=0; +//} /************************************************/ /* Point Cache */ /************************************************/ @@ -2280,11 +2214,9 @@ static void update_particle_tree(ParticleSystem *psys) psys->tree = BLI_kdtree_new(psys->totpart); - LOOP_PARTICLES { - if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE) - continue; - - BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL); + LOOP_SHOWN_PARTICLES { + if(pa->alive == PARS_ALIVE) + BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL); } BLI_kdtree_balance(psys->tree); @@ -2301,7 +2233,7 @@ static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0; - strength= force_val*falloff;///(float)pow((double)distance,(double)power); + strength= force_val*falloff; VECCOPY(tex_co,pa_co); @@ -2364,19 +2296,19 @@ static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, VecAddf(field,field,mag_vec); } -static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys) +static void add_to_effectors(ParticleSimulationData *sim, ListBase *lb, Object *ob) { ParticleEffectorCache *ec; PartDeflect *pd= ob->pd; short type=0,i; - if(pd && ob != obsrc){ + if(pd && ob != sim->ob){ if(pd->forcefield == PFIELD_GUIDE) { if(ob->type==OB_CURVE) { Curve *cu= ob->data; if(cu->flag & CU_PATH) { if(cu->path==NULL || cu->path->data==NULL) - makeDispListCurveTypes(scene, ob, 0); + makeDispListCurveTypes(sim->scene, ob, 0); if(cu->path && cu->path->data) { type |= PSYS_EC_EFFECTOR; } @@ -2410,13 +2342,13 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs if(ob->particlesystem.first){ ParticleSystem *epsys=ob->particlesystem.first; ParticleSettings *epart=0; - Object *tob; + //Object *tob; for(i=0; epsys; epsys=epsys->next,i++){ if(!psys_check_enabled(ob, epsys)) continue; type=0; - if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){ + if(epsys!=sim->psys || (sim->psys->part->flag & PART_SELF_EFFECT)){ epart=epsys->part; if((epsys->part->pd && epsys->part->pd->forcefield) @@ -2425,13 +2357,13 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs type=PSYS_EC_PARTICLE; } - if(epart->type==PART_REACTOR) { - tob=epsys->target_ob; - if(tob==0) - tob=ob; - if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==psys) - type|=PSYS_EC_REACTOR; - } + //if(epart->type==PART_REACTOR) { + // tob=epsys->target_ob; + // if(tob==0) + // tob=ob; + // if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==sim->psys) + // type|=PSYS_EC_REACTOR; + //} if(type){ ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache"); @@ -2449,29 +2381,29 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs } } -static void psys_init_effectors_recurs(Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys, ListBase *listb, int level) +static void psys_init_effectors_recurs(ParticleSimulationData *sim, Object *ob, ListBase *listb, int level) { Group *group; GroupObject *go; - unsigned int layer= obsrc->lay; + unsigned int layer= sim->ob->lay; if(level>MAX_DUPLI_RECUR) return; if(ob->lay & layer) { if(ob->pd || ob->particlesystem.first) - add_to_effectors(listb, scene, ob, obsrc, psys); + add_to_effectors(sim, listb, ob); if(ob->dup_group) { group= ob->dup_group; for(go= group->gobject.first; go; go= go->next) - psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, level+1); + psys_init_effectors_recurs(sim, go->ob, listb, level+1); } } } -void psys_init_effectors(Scene *scene, Object *obsrc, Group *group, ParticleSystem *psys) +static void psys_init_effectors(ParticleSimulationData *sim, Group *group) { - ListBase *listb= &psys->effectors; + ListBase *listb= &sim->psys->effectors; Base *base; listb->first=listb->last=0; @@ -2480,11 +2412,11 @@ void psys_init_effectors(Scene *scene, Object *obsrc, Group *group, ParticleSyst GroupObject *go; for(go= group->gobject.first; go; go= go->next) - psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, 0); + psys_init_effectors_recurs(sim, go->ob, listb, 0); } else { - for(base = scene->base.first; base; base= base->next) - psys_init_effectors_recurs(scene, base->object, obsrc, psys, listb, 0); + for(base = sim->scene->base.first; base; base= base->next) + psys_init_effectors_recurs(sim, base->object, listb, 0); } } @@ -2518,13 +2450,16 @@ void psys_end_effectors(ParticleSystem *psys) BLI_freelistN(&psys->effectors); } -static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra) +/* precalcs effectors and returns 1 if there were any collision object +/* so collision checks can be avoided as quickly as possible */ +static int precalc_effectors(ParticleSimulationData *sim, float cfra) { + ParticleSystem *psys = sim->psys; ListBase *lb=&psys->effectors; ParticleEffectorCache *ec; ParticleSettings *part=psys->part; PARTICLE_P; - int totpart; + int totpart, collision = 0; float vec2[3],loc[3],radius,*co=0; for(ec= lb->first; ec; ec= ec->next) { @@ -2556,9 +2491,9 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa VECCOPY(loc, pa->fuv); } else - psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0); + psys_particle_on_emitter(sim->psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0); - Mat4MulVecfl(ob->obmat,loc); + Mat4MulVecfl(sim->ob->obmat,loc); ec->distances[p]=VecLenf(loc,vec); VECSUB(loc,loc,vec); VECCOPY(ec->locations+3*p,loc); @@ -2566,11 +2501,10 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa } } else if(ec->type==PSYS_EC_PARTICLE){ - Object *eob = ec->ob; - ParticleSystem *epsys = BLI_findlink(&eob->particlesystem,ec->psys_nbr); - ParticleSettings *epart = epsys->part; + ParticleSimulationData esim = {sim->scene, ec->ob, BLI_findlink(&ec->ob->particlesystem, ec->psys_nbr), NULL}; + ParticleSettings *epart = esim.psys->part; ParticleData *epa; - int p, totepart = epsys->totpart; + int p, totepart = esim.psys->totpart; if(psys->part->phystype==PART_PHYS_BOIDS){ ParticleKey state; @@ -2583,8 +2517,8 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa tree=BLI_kdtree_new(totepart); ec->tree=tree; - for(p=0, epa=epsys->particles; palive==PARS_ALIVE && psys_get_particle_state(scene, eob,epsys,p,&state,0)) + for(p=0, epa=esim.psys->particles; palive==PARS_ALIVE && psys_get_particle_state(&esim,p,&state,0)) BLI_kdtree_insert(tree, p, state.co, NULL); BLI_kdtree_balance(tree); @@ -2594,12 +2528,23 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa } else if(ec->type==PSYS_EC_DEFLECT) { CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) ); - if(collmd) + if(collmd) { collision_move_object(collmd, 1.0, 0.0); + collision = 1; + } } } + + return collision; } +/* updates particle effectors and returns if any collision objects were found */ +int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc) +{ + psys_end_effectors(sim->psys); + psys_init_effectors(sim, sim->psys->part->eff_group); + return (precalc ? precalc_effectors(sim, cfra) : 0); +} int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object *ob, PartDeflect *pd, float *co, float *nor, float *vel, int *index) { SurfaceModifierData *surmd = NULL; @@ -2679,10 +2624,10 @@ int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object return ret; } /* calculate forces that all effectors apply to a particle*/ -void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra) +void do_effectors(ParticleSimulationData *sim, int pa_no, ParticleData *pa, ParticleKey *state, float *rootco, float *force_field, float *vel,float framestep, float cfra) { Object *eob; - ParticleSystem *epsys; + ParticleSystem *psys = sim->psys; ParticleSettings *epart; ParticleData *epa; ParticleKey estate; @@ -2712,19 +2657,19 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, if(ec->type & PSYS_EC_EFFECTOR){ pd=eob->pd; if(psys->part->type!=PART_HAIR && psys->part->integrator) - where_is_object_time(scene, eob,cfra); + where_is_object_time(sim->scene, eob, cfra); if(pd && pd->flag&PFIELD_SURFACE) { float velocity[3]; /* using velocity corrected location allows for easier sliding over effector surface */ VecCopyf(velocity, state->vel); - VecMulf(velocity, psys_get_timestep(psys->part)); + VecMulf(velocity, psys_get_timestep(sim)); VecAddf(pco, state->co, velocity); } else VECCOPY(pco, state->co); - effector_find_co(scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index); + effector_find_co(sim->scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index); VecSubf(vec_to_part, state->co, co); @@ -2741,68 +2686,69 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat, strength, falloff, force_field); } else { - do_physical_effector(scene, eob, state->co, pd->forcefield,strength,distance, + do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance, falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part, state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size); } } if(ec->type & PSYS_EC_PARTICLE){ + ParticleSimulationData esim = {sim->scene, eob, BLI_findlink(&eob->particlesystem,ec->psys_nbr), NULL}; int totepart, i; - epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr); - epart= epsys->part; - pd=epart->pd; - totepart= epsys->totpart; + + epart = esim.psys->part; + pd = epart->pd; + totepart = esim.psys->totpart; if(totepart <= 0) continue; if(pd && pd->forcefield==PFIELD_HARMONIC){ /* every particle is mapped to only one harmonic effector particle */ - p= pa_no%epsys->totpart; + p= pa_no%esim.psys->totpart; totepart= p+1; } else{ p=0; } - epsys->lattice= psys_get_lattice(scene, ob, psys); + esim.psys->lattice= psys_get_lattice(sim); for(; pparticles + p; - estate.time=cfra; - if(psys_get_particle_state(scene, eob,epsys,p,&estate,0)){ + epa = esim.psys->particles + p; + estate.time = cfra; + if(psys_get_particle_state(&esim, p, &estate, 0)){ VECSUB(vec_to_part, state->co, estate.co); distance = VecLength(vec_to_part); for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) { if(pd==NULL || pd->forcefield==0) continue; - falloff=effector_falloff(pd,estate.vel,vec_to_part); + falloff = effector_falloff(pd, estate.vel, vec_to_part); strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield]; if(falloff<=0.0f) ; /* don't do anything */ else - do_physical_effector(scene, eob, state->co, pd->forcefield,strength,distance, + do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance, falloff,epart->size,pd->f_damp,estate.vel,vec_to_part, state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size); } } else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){ /* first step after key release */ - psys_get_particle_state(scene, eob,epsys,p,&estate,1); - VECADD(vel,vel,estate.vel); + psys_get_particle_state(&esim, p, &estate, 1); + VECADD(vel, vel, estate.vel); /* TODO: add rotation handling here too */ } } - if(epsys->lattice){ - end_latt_deform(epsys->lattice); - epsys->lattice= NULL; + if(esim.psys->lattice){ + end_latt_deform(esim.psys->lattice); + esim.psys->lattice= NULL; } } } @@ -2813,11 +2759,14 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, /* Newtonian physics */ /************************************************/ /* gathers all forces that effect particles and calculates a new state for the particle */ -static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra) +static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra, float cfra) { + ParticleSettings *part = sim->psys->part; + ParticleData *pa = sim->psys->particles + p; ParticleKey states[5], tkey; + float timestep = psys_get_timestep(sim); float force[3],tvel[3],dx[4][3],dv[4][3]; - float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=psys->cfra; + float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra; int i, steps=1; /* maintain angular velocity */ @@ -2845,7 +2794,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj tvel[0]=tvel[1]=tvel[2]=0.0; /* add effectors */ if(part->type != PART_HAIR) - do_effectors(pa_no,pa,states+i,scene, ob, psys,states->co,force,tvel,dfra,fra); + do_effectors(sim, p, pa, states+i, states->co, force, tvel, dfra, fra); /* calculate air-particle interaction */ if(part->dragfac!=0.0f){ @@ -2878,7 +2827,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj if(i==0){ VECADDFAC(states[1].co,states->co,states->vel,dtime*0.5f); VECADDFAC(states[1].vel,states->vel,force,dtime*0.5f); - fra=psys->cfra+0.5f*dfra; + fra=sim->psys->cfra+0.5f*dfra; } else{ VECADDFAC(pa->state.co,states->co,states[1].vel,dtime); @@ -2895,7 +2844,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj VECADDFAC(states[1].co,states->co,dx[0],0.5f); VECADDFAC(states[1].vel,states->vel,dv[0],0.5f); - fra=psys->cfra+0.5f*dfra; + fra=sim->psys->cfra+0.5f*dfra; break; case 1: VECADDFAC(dx[1],states->vel,dv[0],0.5f); @@ -2949,7 +2898,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj tkey.time=pa->state.time; if(part->type != PART_HAIR) { - if(do_guide(scene, &tkey, pa_no, time, &psys->effectors)) { + if(do_guide(sim->scene, &tkey, p, time, &sim->psys->effectors)) { VECCOPY(pa->state.co,tkey.co); /* guides don't produce valid velocity */ VECSUB(pa->state.vel,tkey.co,pa->prev_state.co); @@ -3213,15 +3162,18 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B /* angular momentum <-> linear momentum and swept sphere - mesh collisions */ /* 1. check for all possible deflectors for closest intersection on particle path */ /* 2. if deflection was found kill the particle or calculate new coordinates */ -static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, int p, float timestep, float dfra, float cfra){ +static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){ Object *ob = NULL, *skip_ob = NULL; - ListBase *lb=&psys->effectors; + ParticleSettings *part = sim->psys->part; + ListBase *lb=&sim->psys->effectors; ParticleEffectorCache *ec; ParticleKey reaction_state; ParticleCollision col; + ParticleData *pa = sim->psys->particles + p; BVHTreeRayHit hit; float ray_dir[3], zerovec[3]={0.0,0.0,0.0}; float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f; + float timestep = psys_get_timestep(sim); int deflections=0, max_deflections=10; VECCOPY(col.co1, pa->prev_state.co); @@ -3258,11 +3210,11 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa continue; /* particles should not collide with emitter at birth */ - if(ob==pob && pa->time < cfra && pa->time >= psys->cfra) + if(ob==sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra) continue; if(part->type!=PART_HAIR) - where_is_object_time(scene,ob,cfra); + where_is_object_time(sim->scene, sim->ob, cfra); col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) ); col.ob_t = ob; @@ -3399,9 +3351,9 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa } /* store state for reactors */ - VECCOPY(reaction_state.co, co); - VecLerpf(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt); - QuatInterpol(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt); + //VECCOPY(reaction_state.co, co); + //VecLerpf(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt); + //QuatInterpol(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt); /* set coordinates for next iteration */ VECCOPY(col.co1, co); @@ -3423,8 +3375,8 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa } deflections++; - reaction_state.time = cfra - (1.0f - dt) * dfra; - push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state); + //reaction_state.time = cfra - (1.0f - dt) * dfra; + //push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state); } else return; @@ -3434,29 +3386,30 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa /* Hair */ /************************************************/ /* check if path cache or children need updating and do it if needed */ -static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) +static void psys_update_path_cache(ParticleSimulationData *sim, float cfra) { - ParticleSettings *part=psys->part; - ParticleEditSettings *pset=&scene->toolsettings->particle; - int distr=0,alloc=0,skip=0; + ParticleSystem *psys = sim->psys; + ParticleSettings *part = psys->part; + ParticleEditSettings *pset = &sim->scene->toolsettings->particle; + int distr=0, alloc=0, skip=0; - if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET) + if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET) alloc=1; - if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))) + if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT))) distr=1; if(distr){ if(alloc) - realloc_particles(ob,psys,psys->totpart); + realloc_particles(sim, sim->psys->totpart); - if(get_psys_tot_child(scene, psys)) { + if(get_psys_tot_child(sim->scene, psys)) { /* don't generate children while computing the hair keys */ if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { - distribute_particles(scene, ob, psys, PART_FROM_CHILD); + distribute_particles(sim, PART_FROM_CHILD); if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0) - psys_find_parents(ob,psmd,psys); + psys_find_parents(sim); } } } @@ -3470,7 +3423,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif skip = 1; /* draw visualization */ else if(psys->pointcache->flag & PTCACHE_BAKING) skip = 1; /* no need to cache paths while baking dynamics */ - else if(psys_in_edit_mode(scene, psys)) { + else if(psys_in_edit_mode(sim->scene, psys)) { if((pset->flag & PE_DRAW_PART)==0) skip = 1; else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0) @@ -3479,7 +3432,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif } if(!skip) { - psys_cache_paths(scene, ob, psys, cfra); + psys_cache_paths(sim, cfra); /* for render, child particle paths are computed on the fly */ if(part->childtype) { @@ -3489,15 +3442,16 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif skip = 1; if(!skip) - psys_cache_child_paths(scene, ob, psys, cfra, 0); + psys_cache_child_paths(sim, cfra, 0); } } else if(psys->pathcache) psys_free_path_cache(psys, NULL); } -static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd) +static void do_hair_dynamics(ParticleSimulationData *sim) { + ParticleSystem *psys = sim->psys; DerivedMesh *dm = psys->hair_in_dm; MVert *mvert = NULL; MEdge *medge = NULL; @@ -3520,7 +3474,8 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par LOOP_PARTICLES totpoint += pa->totkey; - totedge = totpoint - psys->totpart; + totedge = totpoint; + totpoint += psys->totpart; if(dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) { dm->release(dm); @@ -3539,14 +3494,39 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par psys->clmd->sim_parms->vgroup_mass = 1; /* make vgroup for pin roots etc.. */ - psys->particles->hair_index = 0; + psys->particles->hair_index = 1; LOOP_PARTICLES { if(p) - pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey; + pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey + 1; - psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat); + psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat); for(k=0, key=pa->hair; ktotkey; k++,key++) { + + /* create fake root before actual root to resist bending */ + if(k==0) { + float temp[3]; + VECSUB(temp, key->co, (key+1)->co); + VECCOPY(mvert->co, key->co); + VECADD(mvert->co, mvert->co, temp); + Mat4MulVecfl(hairmat, mvert->co); + mvert++; + + medge->v1 = pa->hair_index - 1; + medge->v2 = pa->hair_index; + medge++; + + if(dvert) { + if(!dvert->totweight) { + dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight"); + dvert->totweight = 1; + } + + dvert->dw->weight = 1.0f; + dvert++; + } + } + VECCOPY(mvert->co, key->co); Mat4MulVecfl(hairmat, mvert->co); mvert++; @@ -3576,10 +3556,11 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par psys->clmd->point_cache = psys->pointcache; - psys->hair_out_dm = clothModifier_do(psys->clmd, scene, ob, dm, 0, 0); + psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0); } -static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) +static void hair_step(ParticleSimulationData *sim, float cfra) { + ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; PARTICLE_P; float disp = (float)get_current_display_percentage(psys)/100.0f; @@ -3587,7 +3568,7 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd BLI_srandom(psys->seed); LOOP_PARTICLES { - if(BLI_frand() > disp) + if(PSYS_FRAND(p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -3595,36 +3576,33 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd if(psys->recalc & PSYS_RECALC_RESET) { /* need this for changing subsurf levels */ - psys_calc_dmcache(ob, psmd->dm, psys); + psys_calc_dmcache(sim->ob, sim->psmd->dm, psys); if(psys->clmd) - cloth_free_modifier(ob, psys->clmd); + cloth_free_modifier(sim->ob, psys->clmd); } - if(psys->effectors.first) - psys_end_effectors(psys); - /* dynamics with cloth simulation */ if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) - do_hair_dynamics(scene, ob, psys, psmd); + do_hair_dynamics(sim); - psys_init_effectors(scene, ob, part->eff_group, psys); - if(psys->effectors.first) - precalc_effectors(scene, ob,psys,psmd,cfra); + psys_update_effectors(sim, cfra, 1); - psys_update_path_cache(scene, ob,psmd,psys,cfra); + psys_update_path_cache(sim, cfra); psys->flag |= PSYS_HAIR_UPDATED; } -static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){ +static void save_hair(ParticleSimulationData *sim, float cfra){ + Object *ob = sim->ob; + ParticleSystem *psys = sim->psys; HairKey *key, *root; PARTICLE_P; int totpart; - Mat4Invert(ob->imat,ob->obmat); + Mat4Invert(ob->imat, ob->obmat); - psys->lattice= psys_get_lattice(scene, ob, psys); + psys->lattice= psys_get_lattice(sim); if(psys->totpart==0) return; @@ -3647,7 +3625,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy if(pa->totkey) { VECSUB(key->co, key->co, root->co); - psys_vec_rot_to_face(psmd->dm, pa, key->co); + psys_vec_rot_to_face(sim->psmd->dm, pa, key->co); } key->time = pa->state.time; @@ -3665,17 +3643,17 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy /* System Core */ /************************************************/ /* unbaked particles are calculated dynamically */ -static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra, - float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size) +static void dynamics_step(ParticleSimulationData *sim, float cfra) { + ParticleSystem *psys = sim->psys; ParticleSettings *part=psys->part; KDTree *tree=0; IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system - Material *ma=give_current_material(ob,part->omat); + Material *ma=give_current_material(sim->ob, part->omat); BoidBrainData bbd; PARTICLE_P; float timestep; - int totpart; + int totpart, check_collisions = 0; /* current time */ float ctime, ipotime; // XXX old animation system /* frame & time changes */ @@ -3687,7 +3665,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic totpart=psys->totpart; - timestep=psys_get_timestep(part); + timestep=psys_get_timestep(sim); dtime= dfra*timestep; ctime= cfra*timestep; ipotime= cfra; // XXX old animation system @@ -3701,12 +3679,10 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic if(dfra<0.0){ float *vg_size=0; - if(part->type==PART_REACTOR) - vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); - - LOOP_PARTICLES { - if(pa->flag & PARS_UNEXIST) continue; + //if(part->type==PART_REACTOR) + // vg_size=psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE); + LOOP_EXISTING_PARTICLES { /* set correct ipo timing */ #if 0 // XXX old animation system if((part->flag&PART_ABS_TIME)==0 && part->ipo){ @@ -3715,13 +3691,15 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic execute_ipo((ID *)part, part->ipo); } #endif // XXX old animation system - pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size); + pa->size = part->size; + if(part->randsize > 0.0) + pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); - reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot); + reset_particle(sim, pa, dtime, cfra); - if(cfra>pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){ - pa->loop=(short)((cfra-pa->time)/pa->lifetime); - pa->alive=PARS_UNBORN; + if(cfra > pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){ + pa->loop = (short)((cfra-pa->time)/pa->lifetime); + pa->alive = PARS_UNBORN; } else{ pa->loop = 0; @@ -3742,21 +3720,12 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic } else{ BLI_srandom(31415926 + (int)cfra + psys->seed); - - /* update effectors */ - if(psys->effectors.first) - psys_end_effectors(psys); - psys_init_effectors(scene, ob, part->eff_group, psys); - - if(psys->effectors.first) - precalc_effectors(scene, ob,psys,psmd,cfra); + psys_update_effectors(sim, cfra, 1); if(part->phystype==PART_PHYS_BOIDS){ ParticleTarget *pt = psys->targets.first; - bbd.scene = scene; - bbd.ob = ob; - bbd.psys = psys; + bbd.sim = sim; bbd.part = part; bbd.cfra = cfra; bbd.dfra = dfra; @@ -3773,9 +3742,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic } /* main loop: calculate physics for all particles */ - LOOP_PARTICLES { - if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue; - + LOOP_SHOWN_PARTICLES { copy_particle_key(&pa->prev_state,&pa->state,1); /* set correct ipo timing */ @@ -3786,23 +3753,19 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic execute_ipo((ID *)part, part->ipo); } #endif // XXX old animation system - pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size); + //update_particle_settings(psys, part, &tpart, pa); + + pa->size = part->size; + if(part->randsize > 0.0) + pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); - /* reactions can change birth time so they need to be checked first */ - if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0) - react_to_events(psys,p); + ///* reactions can change birth time so they need to be checked first */ + //if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0) + // react_to_events(psys,p); birthtime = pa->time + pa->loop * pa->lifetime; dietime = birthtime + pa->lifetime; - /* allways reset particles to emitter before birth */ - if(pa->alive==PARS_UNBORN - || pa->alive==PARS_KILLED - || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED) - || birthtime >= psys->cfra){ - reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot); - } - pa_dfra = dfra; pa_dtime = dtime; @@ -3815,6 +3778,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic } else if(birthtime <= cfra && birthtime >= psys->cfra){ /* particle is born some time between this and last step*/ + reset_particle(sim, pa, dtime, cfra); pa->alive = PARS_ALIVE; pa_dfra = cfra - birthtime; pa_dtime = pa_dfra*timestep; @@ -3823,18 +3787,22 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic /* nothing to be done when particle is dead */ } + /* only reset unborn particles if they're shown */ + if(pa->alive==PARS_UNBORN && part->flag & PART_UNBORN) + reset_particle(sim, pa, dtime, cfra); if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){ switch(part->phystype){ case PART_PHYS_NEWTON: /* do global forces & effectors */ - apply_particle_forces(scene, p, pa, ob, psys, part, timestep,pa_dfra,cfra); + apply_particle_forces(sim, p, pa_dfra, cfra); /* deflection */ - deflect_particle(scene, ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra); + if(check_collisions) + deflect_particle(sim, p, pa_dfra, cfra); /* rotations */ - rotate_particle(part,pa,pa_dfra,timestep); + rotate_particle(part, pa, pa_dfra, timestep); break; case PART_PHYS_BOIDS: { @@ -3844,18 +3812,18 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic boid_body(&bbd, pa); /* deflection */ - deflect_particle(scene,ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra); + deflect_particle(sim, p, pa_dfra, cfra); } break; } } if(pa->alive == PARS_DYING){ - push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state); + //push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state); if(part->flag & PART_LOOP && part->type!=PART_HAIR){ pa->loop++; - reset_particle(scene, pa,psys,psmd,ob,0.0,cfra,vg_vel,vg_tan,vg_rot); + reset_particle(sim, pa, 0.0, cfra); pa->alive=PARS_ALIVE; } else{ @@ -3866,7 +3834,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic else pa->state.time=cfra; - push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state); + //push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state); } } } @@ -3878,28 +3846,21 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic } /* updates cached particles' alive & other flags etc..*/ -static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) +static void cached_step(ParticleSimulationData *sim, float cfra) { - ParticleSettings *part=psys->part; - ParticleKey state; - IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system - Material *ma=give_current_material(ob,part->omat); + ParticleSystem *psys = sim->psys; + ParticleSettings *part = psys->part; + IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system + Material *ma = give_current_material(sim->ob,part->omat); PARTICLE_P; float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra BLI_srandom(psys->seed); if(part->from!=PART_FROM_PARTICLE) - vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); + vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE); - if(psys->effectors.first) - psys_end_effectors(psys); - - //if(part->flag & (PART_BAKED_GUIDES+PART_BAKED_DEATHS)){ - psys_init_effectors(scene, ob, part->eff_group, psys); - if(psys->effectors.first) - precalc_effectors(scene, ob,psys,psmd,cfra); - //} + psys_update_effectors(sim, cfra, 1); disp= (float)get_current_display_percentage(psys)/100.0f; @@ -3911,9 +3872,13 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps execute_ipo((ID *)part, part->ipo); } #endif // XXX old animation system - pa->size= psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size); + //update_settings_with_particle(psys, part, pa); + + pa->size = part->size; + if(part->randsize > 0.0) + pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); - psys->lattice= psys_get_lattice(scene, ob, psys); + psys->lattice= psys_get_lattice(sim); if(part->flag & PART_LOOP && part->type!=PART_HAIR) pa->loop = (short)((cfra - pa->time) / pa->lifetime); @@ -3924,25 +3889,16 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps dietime = birthtime + (1 + pa->loop) * (pa->dietime - pa->time); /* update alive status and push events */ - if(pa->time >= cfra) { - pa->alive = pa->time==cfra ? PARS_ALIVE : PARS_UNBORN; - if((psys->pointcache->flag & PTCACHE_EXTERNAL) == 0) - reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL); + if(pa->time > cfra) { + pa->alive = PARS_UNBORN; + if(part->flag & PART_UNBORN && (psys->pointcache->flag & PTCACHE_EXTERNAL) == 0) + reset_particle(sim, pa, 0.0f, cfra); } else if(dietime <= cfra){ - if(dietime > psys->cfra){ - state.time = dietime; - psys_get_particle_state(scene, ob,psys,p,&state,1); - push_reaction(ob,psys,p,PART_EVENT_DEATH,&state); - } pa->alive = PARS_DEAD; } else{ pa->alive = PARS_ALIVE; - state.time = cfra; - psys_get_particle_state(scene, ob,psys,p,&state,1); - state.time = cfra; - push_reaction(ob,psys,p,PART_EVENT_NEAR,&state); } if(psys->lattice){ @@ -3950,43 +3906,41 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps psys->lattice= NULL; } - if(BLI_frand() > disp) + if(PSYS_FRAND(p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; } /* make sure that children are up to date */ - if(psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) { - realloc_particles(ob, psys, psys->totpart); - distribute_particles(scene, ob, psys, PART_FROM_CHILD); + if(psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) { + realloc_particles(sim, psys->totpart); + distribute_particles(sim, PART_FROM_CHILD); } - psys_update_path_cache(scene, ob,psmd,psys,cfra); + psys_update_path_cache(sim, cfra); if(vg_size) MEM_freeN(vg_size); } -static void psys_changed_type(Object *ob, ParticleSystem *psys) +static void psys_changed_type(ParticleSimulationData *sim) { - ParticleSettings *part; + ParticleSettings *part = sim->psys->part; PTCacheID pid; - part= psys->part; - - BKE_ptcache_id_from_particles(&pid, ob, psys); + BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys); /* system type has changed so set sensible defaults and clear non applicable flags */ if(part->from == PART_FROM_PARTICLE) { - if(part->type != PART_REACTOR) - part->from = PART_FROM_FACE; + //if(part->type != PART_REACTOR) + part->from = PART_FROM_FACE; if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT) part->distr = PART_DISTR_JIT; } if(part->phystype != PART_PHYS_KEYED) - psys->flag &= ~PSYS_KEYED; + sim->psys->flag &= ~PSYS_KEYED; if(part->type == PART_HAIR) { if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0) @@ -4001,13 +3955,13 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys) BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); } else { - free_hair(ob, psys, 1); + free_hair(sim->ob, sim->psys, 1); CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime)); CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime)); } - psys_reset(psys, PSYS_RESET_ALL); + psys_reset(sim->psys, PSYS_RESET_ALL); } void psys_check_boid_data(ParticleSystem *psys) { @@ -4033,24 +3987,24 @@ void psys_check_boid_data(ParticleSystem *psys) pa->boid = NULL; } } -static void psys_changed_physics(Object *ob, ParticleSystem *psys) +static void psys_changed_physics(ParticleSimulationData *sim) { - ParticleSettings *part = psys->part; + ParticleSettings *part = sim->psys->part; if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) { PTCacheID pid; - BKE_ptcache_id_from_particles(&pid, ob, psys); + BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys); BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); } else { - free_keyed_keys(psys); - psys->flag &= ~PSYS_KEYED; + free_keyed_keys(sim->psys); + sim->psys->flag &= ~PSYS_KEYED; } if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) { BoidState *state; - psys_check_boid_data(psys); + psys_check_boid_data(sim->psys); part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings"); boid_default_settings(part->boids); @@ -4065,8 +4019,9 @@ static void psys_changed_physics(Object *ob, ParticleSystem *psys) BLI_addtail(&part->boids->states, state); } } -static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, int cfra) +static void particles_fluid_step(ParticleSimulationData *sim, int cfra) { + ParticleSystem *psys = sim->psys; if(psys->particles){ MEM_freeN(psys->particles); psys->particles = 0; @@ -4076,7 +4031,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, /* fluid sim particle import handling, actual loading of particles from file */ #ifndef DISABLE_ELBEEM { - FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); + FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(sim->ob, eModifierType_Fluidsim); if( fluidmd && fluidmd->fss) { FluidsimSettings *fss= fluidmd->fss; @@ -4086,7 +4041,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, char *suffix2 = ".gz"; char filename[256]; char debugStrBuffer[256]; - int curFrame = scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading + int curFrame = sim->scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading int p, j, numFileParts, totpart; int readMask, activeParts = 0, fileParts = 0; gzFile gzf; @@ -4114,11 +4069,11 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, part->totpart= totpart; part->sta=part->end = 1.0f; - part->lifetime = scene->r.efra + 1; + part->lifetime = sim->scene->r.efra + 1; /* initialize particles */ - realloc_particles(ob, psys, part->totpart); - initialize_all_particles(ob, psys, 0); + realloc_particles(sim, part->totpart); + initialize_all_particles(sim); // set up reading mask readMask = fss->typeFlags; @@ -4174,10 +4129,11 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, /* Calculates the next state for all particles of the system */ /* In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)*/ -static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra) +static void system_step(ParticleSimulationData *sim, float cfra) { - ParticleSettings *part; - PointCache *cache; + ParticleSystem *psys = sim->psys; + ParticleSettings *part = psys->part; + PointCache *cache = psys->pointcache; PTCacheID pid; PARTICLE_P; int totpart, oldtotpart, totchild, oldtotchild; @@ -4185,20 +4141,17 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0; int framenr, framedelta, startframe, endframe; - part= psys->part; - cache= psys->pointcache; - - framenr= (int)scene->r.cfra; + framenr= (int)sim->scene->r.cfra; framedelta= framenr - cache->simframe; /* set suitable cache range automatically */ if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0 && !(psys->flag & PSYS_HAIR_DYNAMICS)) - psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe); + psys_get_pointcache_start_end(sim->scene, sim->psys, &cache->startframe, &cache->endframe); - BKE_ptcache_id_from_particles(&pid, ob, psys); - BKE_ptcache_id_time(&pid, scene, 0.0f, &startframe, &endframe, NULL); + BKE_ptcache_id_from_particles(&pid, sim->ob, psys); + BKE_ptcache_id_time(&pid, sim->scene, 0.0f, &startframe, &endframe, NULL); - psys_clear_temp_pointcache(psys); + psys_clear_temp_pointcache(sim->psys); /* update ipo's */ #if 0 // XXX old animation system @@ -4210,14 +4163,14 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle /* hair if it's already done is handled separate */ if(part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)) { - hair_step(scene, ob, psmd, psys, cfra); + hair_step(sim, cfra); psys->cfra = cfra; psys->recalc = 0; return; } /* fluid is also handled separate */ else if(part->type == PART_FLUID) { - particles_fluid_step(scene, ob, psys, framenr); + particles_fluid_step(sim, framenr); psys->cfra = cfra; psys->recalc = 0; return; @@ -4254,7 +4207,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle totpart = part->grid_res*part->grid_res*part->grid_res; else totpart = psys->part->totpart; - totchild = get_psys_tot_child(scene, psys); + totchild = get_psys_tot_child(sim->scene, psys); if(oldtotpart != totpart || oldtotchild != totchild) { only_children_changed = (oldtotpart == totpart); @@ -4271,45 +4224,45 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle if(init) { if(distr) { if(alloc) { - realloc_particles(ob, psys, totpart); + realloc_particles(sim, totpart); if(usecache && !only_children_changed) { BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); - BKE_ptcache_id_from_particles(&pid, ob, psys); + BKE_ptcache_id_from_particles(&pid, sim->ob, psys); } } if(!only_children_changed) - distribute_particles(scene, ob, psys, part->from); + distribute_particles(sim, part->from); if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE)) /* don't generate children while growing hair - waste of time */ psys_free_children(psys); - else if(get_psys_tot_child(scene, psys)) - distribute_particles(scene, ob, psys, PART_FROM_CHILD); + else if(get_psys_tot_child(sim->scene, psys)) + distribute_particles(sim, PART_FROM_CHILD); } if(!only_children_changed) { free_keyed_keys(psys); - initialize_all_particles(ob, psys, psmd); + initialize_all_particles(sim); if(alloc) { - reset_all_particles(scene, ob, psys, psmd, 0.0, cfra, oldtotpart); + reset_all_particles(sim, 0.0, cfra, oldtotpart); } } /* flag for possible explode modifiers after this system */ - psmd->flag |= eParticleSystemFlag_Pars; + sim->psmd->flag |= eParticleSystemFlag_Pars; } /* try to read from the cache */ if(usecache) { - int result = BKE_ptcache_read_cache(&pid, cfra, scene->r.frs_sec); + int result = BKE_ptcache_read_cache(&pid, cfra, sim->scene->r.frs_sec); if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) { - cached_step(scene, ob, psmd, psys, cfra); + cached_step(sim, cfra); psys->cfra=cfra; psys->recalc = 0; @@ -4333,7 +4286,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle pa->alive = PARS_ALIVE; } } - else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { + else if(sim->ob->id.lib || (cache->flag & PTCACHE_BAKED)) { psys_reset(psys, PSYS_RESET_CACHE_MISS); psys->cfra=cfra; psys->recalc = 0; @@ -4351,14 +4304,14 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle BKE_ptcache_write_cache(&pid, startframe); if(part->phystype==PART_PHYS_KEYED) - psys_count_keyed_targets(ob,psys); + psys_count_keyed_targets(sim); /* initialize vertex groups */ if(part->from!=PART_FROM_PARTICLE) { - vg_vel= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL); - vg_tan= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN); - vg_rot= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT); - vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); + vg_vel= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_VEL); + vg_tan= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_TAN); + vg_rot= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_ROT); + vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE); } /* set particles to be not calculated TODO: can't work with pointcache */ @@ -4366,7 +4319,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle BLI_srandom(psys->seed); LOOP_PARTICLES { - if(BLI_frand() > disp) + if(PSYS_FRAND(p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -4382,7 +4335,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle for(dframe=-totframesback; dframe<=0; dframe++) { /* ok now we're all set so let's go */ - dynamics_step(scene, ob, psys, psmd, cfra+dframe, vg_vel, vg_tan, vg_rot, vg_size); + dynamics_step(sim, cfra+dframe); psys->cfra = cfra+dframe; } } @@ -4399,8 +4352,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle /* for keyed particles the path is allways known so it can be drawn */ if(part->phystype==PART_PHYS_KEYED) { - set_keyed_keys(scene, ob, psys); - psys_update_path_cache(scene, ob, psmd, psys,(int)cfra); + set_keyed_keys(sim); + psys_update_path_cache(sim,(int)cfra); } else if(psys->pathcache) psys_free_path_cache(psys, NULL); @@ -4430,30 +4383,33 @@ static int hair_needs_recalc(ParticleSystem *psys) /* main particle update call, checks that things are ok on the large scale before actual particle calculations */ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) { - ParticleSystemModifierData *psmd; + ParticleSimulationData sim = {scene, ob, psys, NULL}; float cfra; + /* drawdata is outdated after ANY change */ + if(psys->pdd) psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; + if(!psys_check_enabled(ob, psys)) return; cfra= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f); - psmd= psys_get_modifier(ob, psys); + sim.psmd= psys_get_modifier(ob, psys); /* system was already updated from modifier stack */ - if(psmd->flag & eParticleSystemFlag_psys_updated) { - psmd->flag &= ~eParticleSystemFlag_psys_updated; + if(sim.psmd->flag & eParticleSystemFlag_psys_updated) { + sim.psmd->flag &= ~eParticleSystemFlag_psys_updated; /* make sure it really was updated to cfra */ if(psys->cfra == cfra) return; } - if(!psmd->dm) + if(!sim.psmd->dm) return; if(psys->recalc & PSYS_RECALC_TYPE) - psys_changed_type(ob, psys); + psys_changed_type(&sim); else if(psys->recalc & PSYS_RECALC_PHYS) - psys_changed_physics(ob, psys); + psys_changed_physics(&sim); /* (re-)create hair */ if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) { @@ -4467,15 +4423,15 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) for(i=0; i<=psys->part->hair_step; i++){ hcfra=100.0f*(float)i/(float)psys->part->hair_step; - system_step(scene, ob, psys, psmd, hcfra); - save_hair(scene, ob, psys, psmd, hcfra); + system_step(&sim, hcfra); + save_hair(&sim, hcfra); } psys->flag |= PSYS_HAIR_DONE; } /* the main particle system step */ - system_step(scene, ob, psys, psmd, cfra); + system_step(&sim, cfra); /* save matrix for duplicators */ Mat4Invert(psys->imat, ob->obmat); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index d685bc29568..dfc5b4cd770 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -79,6 +79,20 @@ static void ptcache_data_to(void **data, int type, int index, void *to); static void ptcache_data_from(void **data, int type, void *from); +#define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); } +#define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); } + +int ptcache_data_size[] = { + sizeof(int), // BPHYS_DATA_INDEX + 3 * sizeof(float), // BPHYS_DATA_LOCATION: + 3 * sizeof(float), // BPHYS_DATA_VELOCITY: + 4 * sizeof(float), // BPHYS_DATA_ROTATION: + 3 * sizeof(float), // BPHYS_DATA_AVELOCITY: /* also BPHYS_DATA_XCONST */ + sizeof(float), // BPHYS_DATA_SIZE: + 3 * sizeof(float), // BPHYS_DATA_TIMES: + sizeof(BoidData) // case BPHYS_DATA_BOIDS: +}; + /* Common functions */ static int ptcache_read_basic_header(PTCacheFile *pf) { @@ -110,8 +124,8 @@ static int ptcache_write_softbody(int index, void *soft_v, void **data) SoftBody *soft= soft_v; BodyPoint *bp = soft->bpoint + index; - ptcache_data_from(data, BPHYS_DATA_LOCATION, bp->pos); - ptcache_data_from(data, BPHYS_DATA_VELOCITY, bp->vec); + PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, bp->pos); + PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, bp->vec); return 1; } @@ -125,8 +139,8 @@ static void ptcache_read_softbody(int index, void *soft_v, void **data, float fr memcpy(bp->vec, data + 3, 3 * sizeof(float)); } else { - ptcache_data_to(data, BPHYS_DATA_LOCATION, 0, bp->pos); - ptcache_data_to(data, BPHYS_DATA_VELOCITY, 0, bp->vec); + PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, bp->pos); + PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec); } } static void ptcache_interpolate_softbody(int index, void *soft_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data) @@ -181,25 +195,25 @@ static int ptcache_write_particle(int index, void *psys_v, void **data) return 0; } - ptcache_data_from(data, BPHYS_DATA_INDEX, &index); - ptcache_data_from(data, BPHYS_DATA_LOCATION, pa->state.co); - ptcache_data_from(data, BPHYS_DATA_VELOCITY, pa->state.vel); - ptcache_data_from(data, BPHYS_DATA_ROTATION, pa->state.rot); - ptcache_data_from(data, BPHYS_DATA_AVELOCITY, pa->state.ave); - ptcache_data_from(data, BPHYS_DATA_SIZE, &pa->size); - ptcache_data_from(data, BPHYS_DATA_TIMES, times); + PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index); + PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co); + PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, pa->state.vel); + PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, pa->state.rot); + PTCACHE_DATA_FROM(data, BPHYS_DATA_AVELOCITY, pa->state.ave); + PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size); + PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times); if(boid) - ptcache_data_from(data, BPHYS_DATA_BOIDS, &boid->data); + PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data); return 1; } void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, float time) { - ptcache_data_to(data, BPHYS_DATA_LOCATION, index, key->co); - ptcache_data_to(data, BPHYS_DATA_VELOCITY, index, key->vel); - ptcache_data_to(data, BPHYS_DATA_ROTATION, index, key->rot); - ptcache_data_to(data, BPHYS_DATA_AVELOCITY, index, key->ave); + PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, index, key->co); + PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, index, key->vel); + PTCACHE_DATA_TO(data, BPHYS_DATA_ROTATION, index, key->rot); + PTCACHE_DATA_TO(data, BPHYS_DATA_AVELOCITY, index, key->ave); key->time = time; } static void ptcache_read_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float *old_data) @@ -220,18 +234,18 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra); if(data[BPHYS_DATA_SIZE]) - ptcache_data_to(data, BPHYS_DATA_SIZE, 0, &pa->size); + PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size); if(data[BPHYS_DATA_TIMES]) { float times[3]; - ptcache_data_to(data, BPHYS_DATA_TIMES, 0, ×); + PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, ×); pa->time = times[0]; pa->dietime = times[1]; pa->lifetime = times[2]; } if(boid) - ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &boid->data); + PTCACHE_DATA_TO(data, BPHYS_DATA_BOIDS, 0, &boid->data); /* determine velocity from previous location */ if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) { @@ -307,6 +321,132 @@ static int ptcache_totwrite_particle(void *psys_v) return totwrite; } +//static int ptcache_write_particle_stream(PTCacheFile *pf, PTCacheMem *pm, void *psys_v) +//{ +// ParticleSystem *psys= psys_v; +// ParticleData *pa = psys->particles; +// BoidParticle *boid = NULL; +// float times[3]; +// int i = 0; +// +// if(!pf && !pm) +// return 0; +// +// for(i=0; itotpart; i++, pa++) { +// +// if(data[BPHYS_DATA_INDEX]) { +// int step = psys->pointcache->step; +// /* No need to store unborn or died particles */ +// if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time) +// continue; +// } +// +// times[0] = pa->time; +// times[1] = pa->dietime; +// times[2] = pa->lifetime; +// +// PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index); +// PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co); +// PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, pa->state.vel); +// PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, pa->state.rot); +// PTCACHE_DATA_FROM(data, BPHYS_DATA_AVELOCITY, pa->state.ave); +// PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size); +// PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times); +// +// boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL; +// if(boid) +// PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data); +// +// if(pf && !ptcache_file_write_data(pf)) +// return 0; +// +// if(pm) +// BKE_ptcache_mem_incr_pointers(pm); +// } +// +// return 1; +//} +//static void ptcache_read_particle_stream(PTCacheFile *pf, PTCacheMem *pm, void *psys_v, void **data, float frs_sec, float cfra, float *old_data) +//{ +// ParticleSystem *psys= psys_v; +// ParticleData *pa = psys->particles + index; +// BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL; +// +// if(cfra > pa->state.time) +// memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey)); +// +// if(old_data){ +// /* old format cache */ +// memcpy(&pa->state, old_data, sizeof(ParticleKey)); +// return; +// } +// +// BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra); +// +// if(data[BPHYS_DATA_SIZE]) +// PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size); +// +// if(data[BPHYS_DATA_TIMES]) { +// float times[3]; +// PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, ×); +// pa->time = times[0]; +// pa->dietime = times[1]; +// pa->lifetime = times[2]; +// } +// +// if(boid) +// PTCACHE_DATA_TO(data, BPHYS_DATA_BOIDS, 0, &boid->data); +// +// /* determine velocity from previous location */ +// if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) { +// if(cfra > pa->prev_state.time) { +// VecSubf(pa->state.vel, pa->state.co, pa->prev_state.co); +// VecMulf(pa->state.vel, (cfra - pa->prev_state.time) / frs_sec); +// } +// else { +// VecSubf(pa->state.vel, pa->prev_state.co, pa->state.co); +// VecMulf(pa->state.vel, (pa->prev_state.time - cfra) / frs_sec); +// } +// } +// +// /* determine rotation from velocity */ +// if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) { +// vectoquat(pa->state.vel, OB_POSX, OB_POSZ, pa->state.rot); +// } +//} +//static void ptcache_interpolate_particle_stream(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data) +//{ +// ParticleSystem *psys= psys_v; +// ParticleData *pa = psys->particles + index; +// ParticleKey keys[4]; +// float dfra; +// +// cfra = MIN2(cfra, pa->dietime); +// cfra1 = MIN2(cfra1, pa->dietime); +// cfra2 = MIN2(cfra2, pa->dietime); +// +// if(cfra1 == cfra2) +// return; +// +// memcpy(keys+1, &pa->state, sizeof(ParticleKey)); +// if(old_data) +// memcpy(keys+2, old_data, sizeof(ParticleKey)); +// else +// BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2); +// +// dfra = cfra2 - cfra1; +// +// VecMulf(keys[1].vel, dfra / frs_sec); +// VecMulf(keys[2].vel, dfra / frs_sec); +// +// psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1); +// QuatInterpol(pa->state.rot, keys[1].rot,keys[2].rot, (cfra - cfra1) / dfra); +// +// VecMulf(pa->state.vel, frs_sec / dfra); +// +// pa->state.time = cfra; +//} +// /* Cloth functions */ static int ptcache_write_cloth(int index, void *cloth_v, void **data) { @@ -314,9 +454,9 @@ static int ptcache_write_cloth(int index, void *cloth_v, void **data) Cloth *cloth= clmd->clothObject; ClothVertex *vert = cloth->verts + index; - ptcache_data_from(data, BPHYS_DATA_LOCATION, vert->x); - ptcache_data_from(data, BPHYS_DATA_VELOCITY, vert->v); - ptcache_data_from(data, BPHYS_DATA_XCONST, vert->xconst); + PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, vert->x); + PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, vert->v); + PTCACHE_DATA_FROM(data, BPHYS_DATA_XCONST, vert->xconst); return 1; } @@ -332,9 +472,9 @@ static void ptcache_read_cloth(int index, void *cloth_v, void **data, float frs_ memcpy(vert->v, data + 6, 3 * sizeof(float)); } else { - ptcache_data_to(data, BPHYS_DATA_LOCATION, 0, vert->x); - ptcache_data_to(data, BPHYS_DATA_VELOCITY, 0, vert->v); - ptcache_data_to(data, BPHYS_DATA_XCONST, 0, vert->xconst); + PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, vert->x); + PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, vert->v); + PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst); } } static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data) @@ -987,7 +1127,7 @@ static int ptcache_file_read_data(PTCacheFile *pf) int i; for(i=0; idata_types & (1<cur[i], 1, BKE_ptcache_data_size(i))) + if(pf->data_types & (1<cur[i], 1, ptcache_data_size[i])) return 0; } @@ -998,7 +1138,7 @@ static int ptcache_file_write_data(PTCacheFile *pf) int i; for(i=0; idata_types & (1<cur[i], 1, BKE_ptcache_data_size(i))) + if(pf->data_types & (1<cur[i], 1, ptcache_data_size[i])) return 0; } @@ -1045,38 +1185,7 @@ static int ptcache_file_write_header_begin(PTCacheFile *pf) /* Data pointer handling */ int BKE_ptcache_data_size(int data_type) { - switch(data_type) { - case BPHYS_DATA_INDEX: - return sizeof(int); - case BPHYS_DATA_LOCATION: - case BPHYS_DATA_VELOCITY: - case BPHYS_DATA_AVELOCITY: /* also BPHYS_DATA_XCONST */ - case BPHYS_DATA_TIMES: - return 3 * sizeof(float); - case BPHYS_DATA_ROTATION: - return 4 * sizeof(float); - case BPHYS_DATA_SIZE: - return sizeof(float); - case BPHYS_DATA_BOIDS: - return sizeof(BoidData); - default: - return 0; - } -} -static void ptcache_data_to(void **data, int type, int index, void *to) -{ - if(data[type]) { - if(index) - memcpy(to, (char*)data[type] + index * BKE_ptcache_data_size(type), BKE_ptcache_data_size(type)); - else - memcpy(to, data[type], BKE_ptcache_data_size(type)); - } -} - -static void ptcache_data_from(void **data, int type, void *from) -{ - if(data[type]) - memcpy(data[type], from, BKE_ptcache_data_size(type)); + return ptcache_data_size[data_type]; } static void ptcache_file_init_pointers(PTCacheFile *pf) @@ -1108,7 +1217,7 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm) for(i=0; icur[i]) - pm->cur[i] = (char*)pm->cur[i] + BKE_ptcache_data_size(i); + pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i]; } } static void ptcache_alloc_data(PTCacheMem *pm) @@ -1119,7 +1228,7 @@ static void ptcache_alloc_data(PTCacheMem *pm) for(i=0; idata[i] = MEM_callocN(totpoint * BKE_ptcache_data_size(i), "PTCache Data"); + pm->data[i] = MEM_callocN(totpoint * ptcache_data_size[i], "PTCache Data"); } } static void ptcache_free_data(void *data[]) @@ -1136,7 +1245,7 @@ static void ptcache_copy_data(void *from[], void *to[]) int i; for(i=0; ipathcachebufs.first = psys->pathcachebufs.last = 0; psys->childcachebufs.first = psys->childcachebufs.last = 0; psys->reactevents.first = psys->reactevents.last = 0; + psys->frand = NULL; + psys->pdd = NULL; direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache); diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 6d1f2e5057b..cbfcf1508c7 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -1184,6 +1184,9 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) point->flag &= ~PEP_EDIT_RECALC; } + if(edit->psys) + edit->psys->flag &= ~PSYS_HAIR_UPDATED; + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } @@ -1761,6 +1764,7 @@ static void rekey_particle(PEData *data, int pa_index) { PTCacheEdit *edit= data->edit; ParticleSystem *psys= edit->psys; + ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL}; ParticleData *pa= psys->particles + pa_index; PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; @@ -1785,7 +1789,7 @@ static void rekey_particle(PEData *data, int pa_index) /* interpolate new keys from old ones */ for(k=1,key++; ktotrekey-1; k++,key++) { state.time= (float)k / (float)(data->totrekey-1); - psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0); + psys_get_particle_on_path(&sim, pa_index, &state, 0); VECCOPY(key->co, state.co); key->time= sta + k * dval; } @@ -1853,6 +1857,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float { PTCacheEdit *edit= PE_get_current(scene, ob); ParticleSystem *psys; + ParticleSimulationData sim = {scene, ob, edit ? edit->psys : NULL, NULL}; ParticleData *pa; ParticleKey state; HairKey *new_keys, *key; @@ -1872,7 +1877,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float /* interpolate new keys from old ones (roots stay the same) */ for(k=1, key++; k < pa->totkey; k++, key++) { state.time= path_time * (float)k / (float)(pa->totkey-1); - psys_get_particle_on_path(scene, ob, psys, pa_index, &state, 0); + psys_get_particle_on_path(&sim, pa_index, &state, 0); VECCOPY(key->co, state.co); } @@ -2044,6 +2049,7 @@ static void subdivide_particle(PEData *data, int pa_index) { PTCacheEdit *edit= data->edit; ParticleSystem *psys= edit->psys; + ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL}; ParticleData *pa= psys->particles + pa_index; PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; @@ -2083,7 +2089,7 @@ static void subdivide_particle(PEData *data, int pa_index) if(ekey->flag & PEK_SELECT && (ekey+1)->flag & PEK_SELECT) { nkey->time= (key->time + (key+1)->time)*0.5f; state.time= (endtime != 0.0f)? nkey->time/endtime: 0.0f; - psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0); + psys_get_particle_on_path(&sim, pa_index, &state, 0); VECCOPY(nkey->co, state.co); nekey->co= nkey->co; @@ -2875,12 +2881,13 @@ static void brush_add(PEData *data, short number) ParticleSystem *psys= edit->psys; ParticleData *add_pars= MEM_callocN(number*sizeof(ParticleData),"ParticleData add"); ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys); + ParticleSimulationData sim = {scene, ob, psys, psmd}; ParticleEditSettings *pset= PE_settings(scene); int i, k, n= 0, totpart= psys->totpart; short mco[2]; short dmx= 0, dmy= 0; float co1[3], co2[3], min_d, imat[4][4]; - float framestep, timestep= psys_get_timestep(psys->part); + float framestep, timestep= psys_get_timestep(&sim); short size= pset->brush[PE_BRUSH_ADD].size; short size2= size*size; DerivedMesh *dm=0; @@ -2975,8 +2982,8 @@ static void brush_add(PEData *data, short number) } pa->size= 1.0f; - initialize_particle(pa,i,ob,psys,psmd); - reset_particle(scene, pa,psys,psmd,ob,0.0,1.0,0,0,0); + initialize_particle(&sim, pa,i); + reset_particle(&sim, pa, 0.0, 1.0); point->flag |= PEP_EDIT_RECALC; if(pset->flag & PE_X_MIRROR) point->flag |= PEP_TAG; /* signal for duplicate */ @@ -3013,18 +3020,18 @@ static void brush_add(PEData *data, short number) hkey->time= pa->time + k * framestep; key[0].time= hkey->time/ 100.0f; - psys_get_particle_on_path(scene, ob, psys, ptn[0].index, key, 0); + psys_get_particle_on_path(&sim, ptn[0].index, key, 0); VecMulf(key[0].co, weight[0]); if(maxw>1) { key[1].time= key[0].time; - psys_get_particle_on_path(scene, ob, psys, ptn[1].index, key + 1, 0); + psys_get_particle_on_path(&sim, ptn[1].index, key + 1, 0); VecMulf(key[1].co, weight[1]); VECADD(key[0].co, key[0].co, key[1].co); if(maxw>2) { key[2].time= key[0].time; - psys_get_particle_on_path(scene, ob, psys, ptn[2].index, key + 2, 0); + psys_get_particle_on_path(&sim, ptn[2].index, key + 2, 0); VecMulf(key[2].co, weight[2]); VECADD(key[0].co, key[0].co, key[2].co); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 40eb74e8062..3212d5cee89 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2974,13 +2974,6 @@ static void view3d_particle_text_draw(View3D *v3d, ARegion *ar) if(pstrings.first) BLI_freelistN(&pstrings); } -typedef struct ParticleDrawData { - float *vdata, *vd; - float *ndata, *nd; - float *cdata, *cd; - float *vedata, *ved; - float *ma_r, *ma_g, *ma_b; -} ParticleDrawData; static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd) { float vec[3], vec2[3]; @@ -3145,7 +3138,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv ParticleData *pars, *pa; ParticleKey state, *states=0; ParticleBillboardData bb; - ParticleDrawData pdd; + ParticleSimulationData sim = {scene, ob, psys, NULL}; + ParticleDrawData *pdd = psys->pdd; Material *ma; float vel[3], imat[4][4]; float timestep, pixsize=1.0, pa_size, r_tilt, r_length; @@ -3176,9 +3170,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(part->draw_as==PART_DRAW_NOT) return; /* 2. */ + sim.psmd = psmd = psys_get_modifier(ob,psys); + if(part->phystype==PART_PHYS_KEYED){ if(psys->flag&PSYS_KEYED){ - psys_count_keyed_targets(ob,psys); + psys_count_keyed_targets(&sim); if(psys->totkeyed==0) return; } @@ -3196,8 +3192,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totchild=0; else totchild=psys->totchild*part->disp/100; - - memset(&pdd, 0, sizeof(ParticleDrawData)); ma= give_current_material(ob,part->omat); @@ -3212,18 +3206,16 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv ma_g = ma->g; ma_b = ma->b; - pdd.ma_r = &ma_r; - pdd.ma_g = &ma_g; - pdd.ma_b = &ma_b; + pdd->ma_r = &ma_r; + pdd->ma_g = &ma_g; + pdd->ma_b = &ma_b; create_cdata = 1; } else cpack(0); - psmd= psys_get_modifier(ob,psys); - - timestep= psys_get_timestep(part); + timestep= psys_get_timestep(&sim); if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) { float mat[4][4]; @@ -3317,54 +3309,65 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv /* 4. */ if(draw_as && draw_as!=PART_DRAW_PATH) { int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); - + + if(!pdd) + pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData"); + if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) { tot_vec_size *= part->trail_count; psys_make_temp_pointcache(ob, psys); } + if(pdd->tot_vec_size != tot_vec_size) + psys_free_pdd(psys); + if(draw_as!=PART_DRAW_CIRC) { switch(draw_as) { case PART_DRAW_AXIS: case PART_DRAW_CROSS: if(draw_as != PART_DRAW_CROSS || create_cdata) - pdd.cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); - pdd.vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); + if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); + if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); break; case PART_DRAW_LINE: if(create_cdata) - pdd.cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); - pdd.vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); + if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); + if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); break; case PART_DRAW_BB: if(create_cdata) - pdd.cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); - pdd.vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); - pdd.ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); + if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); + if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); + if(!pdd->ndata) pdd->ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); break; default: if(create_cdata) - pdd.cdata=MEM_callocN(tot_vec_size, "particle_cdata"); - pdd.vdata=MEM_callocN(tot_vec_size, "particle_vdata"); + if(!pdd->cdata) pdd->cdata=MEM_callocN(tot_vec_size, "particle_cdata"); + if(!pdd->vdata) pdd->vdata=MEM_callocN(tot_vec_size, "particle_vdata"); } } if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { - pdd.vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); + if(!pdd->vedata) pdd->vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); need_v = 1; } - pdd.vd= pdd.vdata; - pdd.ved= pdd.vedata; - pdd.cd= pdd.cdata; - pdd.nd= pdd.ndata; + pdd->vd= pdd->vdata; + pdd->ved= pdd->vedata; + pdd->cd= pdd->cdata; + pdd->nd= pdd->ndata; + pdd->tot_vec_size= tot_vec_size; - psys->lattice= psys_get_lattice(scene, ob, psys); + psys->lattice= psys_get_lattice(&sim); } if(draw_as){ /* 5. */ - for(a=0,pa=pars; aflag & PARTICLE_DRAW_DATA_UPDATED) + && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) { + totpoint = pdd->totpoint; /* draw data is up to date */ + } + else for(a=0,pa=pars; adraw&PART_DRAW_PARENT)==0) continue; @@ -3374,9 +3377,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_birthtime=pa->time; pa_dietime = pa->dietime; pa_size=pa->size; - if(part->phystype==PART_PHYS_BOIDS) { + if(part->phystype==PART_PHYS_BOIDS) pa_health = pa->boid->data.health; - } else pa_health = -1.0; @@ -3411,10 +3413,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } #endif // XXX old animation system - BLI_srandom(psys->seed+a); - - r_tilt = 2.0f*(BLI_frand() - 0.5f); - r_length = BLI_frand(); + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); } else{ ChildParticle *cpa= &psys->child[a-totpart]; @@ -3445,8 +3445,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_health = -1.0; - r_tilt = 2.0f * cpa->rand[2]; - r_length = cpa->rand[1]; + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); } if(draw_as!=PART_DRAW_PATH){ @@ -3468,7 +3468,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv continue; state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); - psys_get_particle_on_path(scene,ob,psys,a,&state,need_v); + psys_get_particle_on_path(&sim,a,&state,need_v); if(psys->parent) Mat4MulVecfl(psys->parent->obmat, state.co); @@ -3480,7 +3480,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv bb.time = ct; } - draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd); + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd); totpoint++; drawn = 1; @@ -3489,7 +3489,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv else { state.time=cfra; - if(psys_get_particle_state(scene,ob,psys,a,&state,0)){ + if(psys_get_particle_state(&sim,a,&state,0)){ if(psys->parent) Mat4MulVecfl(psys->parent->obmat, state.co); @@ -3500,7 +3500,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv bb.time = pa_time; } - draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd); + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd); totpoint++; drawn = 1; @@ -3510,13 +3510,13 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(drawn) { /* additional things to draw for each particle */ /* (velocity, size and number) */ - if(pdd.vedata){ - VECCOPY(pdd.ved,state.co); - pdd.ved+=3; + if(pdd->vedata){ + VECCOPY(pdd->ved,state.co); + pdd->ved+=3; VECCOPY(vel,state.vel); VecMulf(vel,timestep); - VECADD(pdd.ved,state.co,vel); - pdd.ved+=3; + VECADD(pdd->ved,state.co,vel); + pdd->ved+=3; totve++; } @@ -3628,17 +3628,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDisableClientState(GL_COLOR_ARRAY); /* setup created data arrays */ - if(pdd.vdata){ + if(pdd->vdata){ glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, pdd.vdata); + glVertexPointer(3, GL_FLOAT, 0, pdd->vdata); } else glDisableClientState(GL_VERTEX_ARRAY); /* billboards are drawn this way */ - if(pdd.ndata && ob_dt>OB_WIRE){ + if(pdd->ndata && ob_dt>OB_WIRE){ glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, pdd.ndata); + glNormalPointer(GL_FLOAT, 0, pdd->ndata); glEnable(GL_LIGHTING); } else{ @@ -3646,9 +3646,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDisable(GL_LIGHTING); } - if(pdd.cdata){ + if(pdd->cdata){ glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, pdd.cdata); + glColorPointer(3, GL_FLOAT, 0, pdd->cdata); } /* draw created data arrays */ @@ -3670,14 +3670,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDrawArrays(GL_POINTS, 0, totpoint); break; } + + pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; + pdd->totpoint = totpoint; } - if(pdd.vedata){ + if(pdd->vedata){ glDisableClientState(GL_COLOR_ARRAY); cpack(0xC0C0C0); glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, pdd.vedata); + glVertexPointer(3, GL_FLOAT, 0, pdd->vedata); glDrawArrays(GL_LINES, 0, 2*totve); } @@ -3694,14 +3697,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(states) MEM_freeN(states); - if(pdd.vdata) - MEM_freeN(pdd.vdata); - if(pdd.vedata) - MEM_freeN(pdd.vedata); - if(pdd.cdata) - MEM_freeN(pdd.cdata); - if(pdd.ndata) - MEM_freeN(pdd.ndata); psys->flag &= ~PSYS_DRAWING; @@ -3728,10 +3723,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj float *pathcol = NULL, *pcol; - if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) { + if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) PE_update_object(scene, ob, 0); - edit->psys->flag &= ~PSYS_HAIR_UPDATED; - } /* create path and child path cache if it doesn't exist already */ if(edit->pathcache==0) diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 6a0a0e1d912..089c1c76bcf 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -67,7 +67,7 @@ typedef struct ChildParticle { int pa[4]; /* nearest particles to the child, used for the interpolation */ float w[4]; /* interpolation weights for the above particles */ float fuv[4], foffset; /* face vertex weights and offset */ - float rand[3]; + float rt; } ChildParticle; typedef struct ParticleTarget { @@ -234,13 +234,17 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in struct ListBase ptcaches; struct KDTree *tree; /* used for interactions with self and other systems */ + + struct ParticleDrawData *pdd; + + float *frand; /* array of 1024 random floats for fast lookups */ }ParticleSystem; /* part->type */ /* hair is allways baked static in object/geometry space */ /* other types (normal particles) are in global space and not static baked */ #define PART_EMITTER 0 -#define PART_REACTOR 1 +//#define PART_REACTOR 1 #define PART_HAIR 2 #define PART_FLUID 3 @@ -325,7 +329,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_DRAW_EMITTER 8 /* render emitter also */ #define PART_DRAW_HEALTH 16 #define PART_ABS_PATH_TIME 32 -//#define PART_DRAW_TRAIL 64 +//#define PART_DRAW_TRAIL 64 /* deprecated */ #define PART_DRAW_BB_LOCK 128 #define PART_DRAW_PARENT 256 #define PART_DRAW_NUM 512 @@ -422,13 +426,13 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PSYS_HAIR_DONE 512 #define PSYS_KEYED 1024 #define PSYS_EDITED 2048 -//#define PSYS_PROTECT_CACHE 4096 +//#define PSYS_PROTECT_CACHE 4096 /* deprecated */ #define PSYS_DISABLED 8192 /* pars->flag */ #define PARS_UNEXIST 1 #define PARS_NO_DISP 2 -//#define PARS_STICKY 4 +//#define PARS_STICKY 4 /* deprecated */ #define PARS_REKEY 8 /* pars->alive */ diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 02fa0c25335..5821d30bc3b 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -312,9 +312,10 @@ static void rna_PartSettings_start_set(struct PointerRNA *ptr, float value) if(value > settings->end) value = settings->end; - if(settings->type==PART_REACTOR && value < 1.0) - value = 1.0; - else if (value < MINAFRAMEF) + //if(settings->type==PART_REACTOR && value < 1.0) + // value = 1.0; + //else + if (value < MINAFRAMEF) value = MINAFRAMEF; settings->sta = value; @@ -522,9 +523,9 @@ static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, i return item; } - if(part->type==PART_REACTOR) - return part_reactor_from_items; - else + //if(part->type==PART_REACTOR) + // return part_reactor_from_items; + //else return part_from_items; } @@ -767,7 +768,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) static EnumPropertyItem type_items[] = { {PART_EMITTER, "EMITTER", 0, "Emitter", ""}, - {PART_REACTOR, "REACTOR", 0, "Reactor", ""}, + //{PART_REACTOR, "REACTOR", 0, "Reactor", ""}, {PART_HAIR, "HAIR", 0, "Hair", ""}, {0, NULL, 0, NULL, NULL} }; @@ -986,10 +987,10 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Children", "Apply effectors to children."); RNA_def_property_update(prop, 0, "rna_Particle_redo"); - prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS); - RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents"); - RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); + //prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE); + //RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS); + //RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents"); + //RNA_def_property_update(prop, 0, "rna_Particle_redo_child"); /* TODO: used somewhere? */ prop= RNA_def_property(srna, "child_render", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 99825c0c2ff..0c56841b70d 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1484,6 +1484,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem ParticleKey state; ParticleCacheKey *cache=0; ParticleBillboardData bb; + ParticleSimulationData sim = {re->scene, ob, psys, NULL}; ParticleStrandData sd; StrandBuffer *strandbuf=0; StrandVert *svert=0; @@ -1517,14 +1518,16 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem return 1; /* 2. start initialising things */ - if(part->phystype==PART_PHYS_KEYED) - psys_count_keyed_targets(ob,psys); /* last possibility to bail out! */ - psmd= psys_get_modifier(ob,psys); + sim.psmd = psmd = psys_get_modifier(ob,psys); if(!(psmd->modifier.mode & eModifierMode_Render)) return 0; + if(part->phystype==PART_PHYS_KEYED) + psys_count_keyed_targets(&sim); + + if(G.rendering == 0) { /* preview render */ totchild = (int)((float)totchild * (float)part->disp / 100.0f); } @@ -1611,14 +1614,14 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem #endif // XXX old animation system cfra = bsystem_time(re->scene, 0, (float)re->scene->r.cfra, 0.0); -/* 2.4 setup reactors */ - if(part->type == PART_REACTOR){ - psys_get_reactor_target(ob, psys, &tob, &tpsys); - if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ - psmd = psys_get_modifier(tob,tpsys); - tpart = tpsys->part; - } - } +///* 2.4 setup reactors */ +// if(part->type == PART_REACTOR){ +// psys_get_reactor_target(ob, psys, &tob, &tpsys); +// if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ +// psmd = psys_get_modifier(tob,tpsys); +// tpart = tpsys->part; +// } +// } /* 2.5 setup matrices */ Mat4MulMat4(mat, ob->obmat, re->viewmat); @@ -1695,7 +1698,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } if(path_nbr == 0) - psys->lattice = psys_get_lattice(re->scene, ob, psys); + psys->lattice = psys_get_lattice(&sim); /* 3. start creating renderable things */ for(a=0,pa=pars; arand[2]; - r_length = cpa->rand[1]; + r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f); + r_length = PSYS_FRAND(a + 22); num = cpa->num; @@ -1952,7 +1955,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem continue; state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : ct; - psys_get_particle_on_path(re->scene,ob,psys,a,&state,1); + psys_get_particle_on_path(&sim,a,&state,1); if(psys->parent) Mat4MulVecfl(psys->parent->obmat, state.co); @@ -1971,7 +1974,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem else { time=0.0f; state.time=cfra; - if(psys_get_particle_state(re->scene,ob,psys,a,&state,0)==0) + if(psys_get_particle_state(&sim,a,&state,0)==0) continue; if(psys->parent) diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 5f8cf5504fa..b7832e74cd1 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -92,6 +92,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa { DerivedMesh* dm; ParticleKey state; + ParticleSimulationData sim = {re->scene, ob, psys, NULL}; ParticleData *pa=NULL; float cfra = bsystem_time(re->scene, ob, (float)re->scene->r.cfra, 0.0); int i, childexists; @@ -120,7 +121,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa Mat4Invert(ob->imat, ob->obmat); total_particles = psys->totpart+psys->totchild; - psys->lattice=psys_get_lattice(re->scene,ob,psys); + psys->lattice=psys_get_lattice(&sim); pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6); alloc_point_data(pd, total_particles, data_used); @@ -133,7 +134,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa for (i=0, pa=psys->particles; i < total_particles; i++, pa++) { state.time = cfra; - if(psys_get_particle_state(re->scene, ob, psys, i, &state, 0)) { + if(psys_get_particle_state(&sim, i, &state, 0)) { VECCOPY(partco, state.co); -- cgit v1.2.3 From b75d2c56c86ec030dbdf1031361952cccfb89878 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 18 Sep 2009 02:19:27 +0000 Subject: * Made image editor paint use predefined left/right mouse buttons rather than action/select, consistent with 3d view painting (and better for tablets!) * Fixed a small bug in project paint tool ui --- release/ui/space_view3d_toolbar.py | 2 +- source/blender/editors/space_image/space_image.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index cbea6466a85..09e85bf5131 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -599,7 +599,7 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel): # ********** default tools for texturepaint **************** class VIEW3D_PT_tools_projectpaint(View3DPanel): - __context__ = "projectpaint" + __context__ = "texturepaint" __label__ = "Project Paint" def poll(self, context): diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index e57a059265f..75e7461df95 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -232,9 +232,9 @@ void image_keymap(struct wmWindowManager *wm) RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f); - WM_keymap_add_item(keymap, "PAINT_OT_image_paint", ACTIONMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", SELECTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SELECTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); -- cgit v1.2.3 From 6a144086647fca303eed56b9d27f6d56bde37432 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 02:36:23 +0000 Subject: use functions to detect stylus and eraser from the wine project, supposed to work with non-wacom tablets too (searches for wizardpen & acecad as well as 'stylus'). 2.4x did an exact check on the name, 2.5 does a case insensitive search on the type. This does a case insensitive check on both the name and type. close the devices on exit too. --- intern/ghost/intern/GHOST_WindowX11.cpp | 121 ++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 14 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 0457cbcaecb..9241525bdeb 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -427,6 +427,100 @@ static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) { return 0 ; } +/* These C functions are copied from Wine 1.1.13's wintab.c */ +#define BOOL int +#define TRUE 1 +#define FALSE 0 + +static bool match_token(const char *haystack, const char *needle) +{ + const char *p, *q; + for (p = haystack; *p; ) + { + while (*p && isspace(*p)) + p++; + if (! *p) + break; + + for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++) + p++; + if (! *q && (isspace(*p) || !*p)) + return TRUE; + + while (*p && ! isspace(*p)) + p++; + } + return FALSE; +} + +/* Determining if an X device is a Tablet style device is an imperfect science. +** We rely on common conventions around device names as well as the type reported +** by Wacom tablets. This code will likely need to be expanded for alternate tablet types +** +** Wintab refers to any device that interacts with the tablet as a cursor, +** (stylus, eraser, tablet mouse, airbrush, etc) +** this is not to be confused with wacom x11 configuration "cursor" device. +** Wacoms x11 config "cursor" refers to its device slot (which we mirror with +** our gSysCursors) for puck like devices (tablet mice essentially). +*/ + +static BOOL is_tablet_cursor(const char *name, const char *type) +{ + int i; + static const char *tablet_cursor_whitelist[] = { + "wacom", + "wizardpen", + "acecad", + "tablet", + "cursor", + "stylus", + "eraser", + "pad", + NULL + }; + + for (i=0; tablet_cursor_whitelist[i] != NULL; i++) { + if (name && match_token(name, tablet_cursor_whitelist[i])) + return TRUE; + if (type && match_token(type, tablet_cursor_whitelist[i])) + return TRUE; + } + return FALSE; +} + +static BOOL is_stylus(const char *name, const char *type) +{ + int i; + static const char* tablet_stylus_whitelist[] = { + "stylus", + "wizardpen", + "acecad", + NULL + }; + + for (i=0; tablet_stylus_whitelist[i] != NULL; i++) { + if (name && match_token(name, tablet_stylus_whitelist[i])) + return TRUE; + if (type && match_token(type, tablet_stylus_whitelist[i])) + return TRUE; + } + + return FALSE; +} + +static BOOL is_eraser(const char *name, const char *type) +{ + if (name && match_token(name, "eraser")) + return TRUE; + if (type && match_token(type, "eraser")) + return TRUE; + return FALSE; +} +#undef BOOL +#undef TRUE +#undef FALSE +/* end code copied from wine */ + void GHOST_WindowX11::initXInputDevices() { static XErrorHandler old_handler = (XErrorHandler) 0 ; @@ -436,28 +530,21 @@ void GHOST_WindowX11::initXInputDevices() if(version->present) { int device_count; XDeviceInfo* device_info = XListInputDevices(m_display, &device_count); - m_xtablet.StylusDevice = 0; - m_xtablet.EraserDevice = 0; + m_xtablet.StylusDevice = NULL; + m_xtablet.EraserDevice = NULL; m_xtablet.CommonData.Active= 0; /* Install our error handler to override Xlib's termination behavior */ old_handler = XSetErrorHandler(ApplicationErrorHandler) ; for(int i=0; inum_classes; ++j) { if(ici->c_class==ValuatorClass) { +// printf("\t\tfound ValuatorClass\n"); XValuatorInfo* xvi = (XValuatorInfo*)ici; m_xtablet.PressureLevels = xvi->axes[2].max_value; @@ -482,11 +570,16 @@ void GHOST_WindowX11::initXInputDevices() m_xtablet.StylusID= 0; } } - if(type.find("eraser") != std::string::npos) { + else if(m_xtablet.EraserDevice==NULL && is_eraser(device_info[i].name, device_type)) { +// printf("\tfound eraser\n"); m_xtablet.EraserID= device_info[i].id; m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID); if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID= 0; } + + if(device_type) { + XFree((void*)device_type); + } } /* Restore handler */ -- cgit v1.2.3 From a393a9c6f05b66692fbbb7ae2a3f101744e550f0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 02:38:38 +0000 Subject: same as r23322 in 2.4x --- 2.4x log use functions to detect stylus and eraser from the wine project, supposed to work with non-wacom tablets too (searches for wizardpen & acecad as well as 'stylus'). 2.4x did an exact check on the name, 2.5 does a case insensitive search on the type. This does a case insensitive check on both the name and type. close the devices on exit too. --- intern/ghost/intern/GHOST_WindowX11.cpp | 128 ++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 14 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 708256f75f5..ab46c050fa3 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -414,6 +414,100 @@ static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) { return 0 ; } +/* These C functions are copied from Wine 1.1.13's wintab.c */ +#define BOOL int +#define TRUE 1 +#define FALSE 0 + +static bool match_token(const char *haystack, const char *needle) +{ + const char *p, *q; + for (p = haystack; *p; ) + { + while (*p && isspace(*p)) + p++; + if (! *p) + break; + + for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++) + p++; + if (! *q && (isspace(*p) || !*p)) + return TRUE; + + while (*p && ! isspace(*p)) + p++; + } + return FALSE; +} + +/* Determining if an X device is a Tablet style device is an imperfect science. +** We rely on common conventions around device names as well as the type reported +** by Wacom tablets. This code will likely need to be expanded for alternate tablet types +** +** Wintab refers to any device that interacts with the tablet as a cursor, +** (stylus, eraser, tablet mouse, airbrush, etc) +** this is not to be confused with wacom x11 configuration "cursor" device. +** Wacoms x11 config "cursor" refers to its device slot (which we mirror with +** our gSysCursors) for puck like devices (tablet mice essentially). +*/ + +static BOOL is_tablet_cursor(const char *name, const char *type) +{ + int i; + static const char *tablet_cursor_whitelist[] = { + "wacom", + "wizardpen", + "acecad", + "tablet", + "cursor", + "stylus", + "eraser", + "pad", + NULL + }; + + for (i=0; tablet_cursor_whitelist[i] != NULL; i++) { + if (name && match_token(name, tablet_cursor_whitelist[i])) + return TRUE; + if (type && match_token(type, tablet_cursor_whitelist[i])) + return TRUE; + } + return FALSE; +} + +static BOOL is_stylus(const char *name, const char *type) +{ + int i; + static const char* tablet_stylus_whitelist[] = { + "stylus", + "wizardpen", + "acecad", + NULL + }; + + for (i=0; tablet_stylus_whitelist[i] != NULL; i++) { + if (name && match_token(name, tablet_stylus_whitelist[i])) + return TRUE; + if (type && match_token(type, tablet_stylus_whitelist[i])) + return TRUE; + } + + return FALSE; +} + +static BOOL is_eraser(const char *name, const char *type) +{ + if (name && match_token(name, "eraser")) + return TRUE; + if (type && match_token(type, "eraser")) + return TRUE; + return FALSE; +} +#undef BOOL +#undef TRUE +#undef FALSE +/* end code copied from wine */ + void GHOST_WindowX11::initXInputDevices() { static XErrorHandler old_handler = (XErrorHandler) 0 ; @@ -423,28 +517,21 @@ void GHOST_WindowX11::initXInputDevices() if(version->present) { int device_count; XDeviceInfo* device_info = XListInputDevices(m_display, &device_count); - m_xtablet.StylusDevice = 0; - m_xtablet.EraserDevice = 0; + m_xtablet.StylusDevice = NULL; + m_xtablet.EraserDevice = NULL; m_xtablet.CommonData.Active= GHOST_kTabletModeNone; /* Install our error handler to override Xlib's termination behavior */ old_handler = XSetErrorHandler(ApplicationErrorHandler) ; for(int i=0; inum_classes; ++j) { if(ici->c_class==ValuatorClass) { +// printf("\t\tfound ValuatorClass\n"); XValuatorInfo* xvi = (XValuatorInfo*)ici; m_xtablet.PressureLevels = xvi->axes[2].max_value; @@ -469,11 +557,16 @@ void GHOST_WindowX11::initXInputDevices() m_xtablet.StylusID= 0; } } - if(type.find("eraser") != std::string::npos) { + else if(m_xtablet.EraserDevice==NULL && is_eraser(device_info[i].name, device_type)) { +// printf("\tfound eraser\n"); m_xtablet.EraserID= device_info[i].id; m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID); if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID= 0; } + + if(device_type) { + XFree((void*)device_type); + } } /* Restore handler */ @@ -1125,6 +1218,13 @@ GHOST_WindowX11:: XFreeCursor(m_display, m_custom_cursor); } + /* close tablet devices */ + if(m_xtablet.StylusDevice) + XCloseDevice(m_display, m_xtablet.StylusDevice); + + if(m_xtablet.EraserDevice) + XCloseDevice(m_display, m_xtablet.EraserDevice); + if (m_context) { if (m_context == s_firstContext) { s_firstContext = NULL; -- cgit v1.2.3 From bf6f23ff5f8af6ae28b5efa113b5b628ad2edb6b Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 18 Sep 2009 03:11:17 +0000 Subject: * Added notifiers/redraws for brush edits in 3d view and image editor (so using radial control updates tool properties) * Changed the non-projection paint code to use the brush falloff curve, rather than a predefined falloff. This makes non-projection painting in the 3d view, and image editor painting much more consistent with other brush usage. --- source/blender/blenkernel/intern/brush.c | 9 +++++---- source/blender/editors/sculpt_paint/paint_image.c | 10 ++++++++-- source/blender/editors/sculpt_paint/paint_vertex.c | 12 ++++++++++-- source/blender/editors/sculpt_paint/sculpt.c | 5 ++++- source/blender/editors/space_image/space_image.c | 5 ++++- source/blender/editors/space_view3d/space_view3d.c | 4 ++++ 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 76a26762abe..9ae0863a78a 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -446,6 +446,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o ImBuf *ibuf; float xy[2], dist, rgba[4], *dstf; int x, y, rowbytes, xoff, yoff, imbflag; + int maxsize = brush->size >> 1; char *dst, crgb[3]; imbflag= (flt)? IB_rectfloat: IB_rect; @@ -470,7 +471,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); VECCOPY(dstf, brush->rgb); - dstf[3]= brush_sample_falloff(brush, dist); + dstf[3]= brush_curve_strength(brush, dist, maxsize); } else if (texfall == 1) { brush_sample_tex(brush, xy, dstf); @@ -483,7 +484,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dstf[0] = rgba[0]*brush->rgb[0]; dstf[1] = rgba[1]*brush->rgb[1]; dstf[2] = rgba[2]*brush->rgb[2]; - dstf[3] = rgba[3]*brush_sample_falloff(brush, dist); + dstf[3] = rgba[3]*brush_curve_strength(brush, dist, maxsize); } } } @@ -506,7 +507,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0]= crgb[0]; dst[1]= crgb[1]; dst[2]= crgb[2]; - dst[3]= FTOCHAR(brush_sample_falloff(brush, dist)); + dst[3]= FTOCHAR(brush_curve_strength(brush, dist, maxsize)); } else if (texfall == 1) { brush_sample_tex(brush, xy, rgba); @@ -522,7 +523,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]); dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]); dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]); - dst[3] = FTOCHAR(rgba[3]*brush_sample_falloff(brush, dist)); + dst[3] = FTOCHAR(rgba[3]*brush_curve_strength(brush, dist, maxsize)); } } } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 870b66cdbbd..e8dd27f1bd2 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -4897,12 +4897,15 @@ static int paint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *even static int paint_radial_control_exec(bContext *C, wmOperator *op) { + Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint); float zoom; int ret; char str[256]; get_imapaint_zoom(C, &zoom, &zoom); - ret = brush_radial_control_exec(op, paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint), 2.0 / zoom); + ret = brush_radial_control_exec(op, brush, 2.0 / zoom); WM_radial_control_string(op, str, 256); + + WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush); return ret; } @@ -5216,10 +5219,13 @@ static int texture_paint_radial_control_invoke(bContext *C, wmOperator *op, wmEv static int texture_paint_radial_control_exec(bContext *C, wmOperator *op) { - int ret = brush_radial_control_exec(op, paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint), 2); + Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint); + int ret = brush_radial_control_exec(op, brush, 2); char str[256]; WM_radial_control_string(op, str, 256); + WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush); + return ret; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 2375e4e70ec..c43d903d4a6 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1136,7 +1136,11 @@ static int vpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve static int vpaint_radial_control_exec(bContext *C, wmOperator *op) { Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->vpaint->paint); - return brush_radial_control_exec(op, brush, 1); + int ret = brush_radial_control_exec(op, brush, 1); + + WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush); + + return ret; } static int wpaint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) @@ -1161,7 +1165,11 @@ static int wpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve static int wpaint_radial_control_exec(bContext *C, wmOperator *op) { Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->wpaint->paint); - return brush_radial_control_exec(op, brush, 1); + int ret = brush_radial_control_exec(op, brush, 1); + + WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush); + + return ret; } void PAINT_OT_weight_paint_radial_control(wmOperatorType *ot) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index b08e8ab5c2b..822e79bea1e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1091,8 +1091,11 @@ static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve static int sculpt_radial_control_exec(bContext *C, wmOperator *op) { Brush *brush = paint_brush(&CTX_data_tool_settings(C)->sculpt->paint); + int ret = brush_radial_control_exec(op, brush, 1); - return brush_radial_control_exec(op, brush, 1); + WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush); + + return ret; } static void SCULPT_OT_radial_control(wmOperatorType *ot) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 75e7461df95..e325a820e92 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -486,7 +486,10 @@ static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { - + case NC_BRUSH: + if(wmn->action==NA_EDITED) + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 15e12e73b49..12c2b272258 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -566,6 +566,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + case NC_BRUSH: + if(wmn->action==NA_EDITED) + ED_region_tag_redraw(ar); + break; case NC_SPACE: if(wmn->data == ND_SPACE_VIEW3D) ED_region_tag_redraw(ar); -- cgit v1.2.3 From 985031c23553fb851f3e351d3f3ac2bdafb7c157 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 18 Sep 2009 03:29:50 +0000 Subject: netrender: only one log file for each chunk --- release/io/netrender/master.py | 61 +++++++++++++++++++++++++++++++++--------- release/io/netrender/model.py | 22 +++++++++++++++ release/io/netrender/slave.py | 25 ++++++++++------- 3 files changed, 86 insertions(+), 22 deletions(-) diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 8f59ef37069..58af47d6240 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -82,6 +82,15 @@ class MRenderJob(netrender.model.RenderJob): self.credits += (time.time() - self.last_dispatched) / 60 self.last_dispatched = time.time() + def addLog(self, frames): + log_name = "_".join(("%04d" % f for f in frames)) + ".log" + log_path = self.save_path + log_name + + for number in frames: + frame = self[number] + if frame: + frame.log_path = log_path + def addFrame(self, frame_number): frame = MRenderFrame(frame_number) self.frames.append(frame) @@ -117,6 +126,7 @@ class MRenderFrame(netrender.model.RenderFrame): self.slave = None self.time = 0 self.status = QUEUED + self.log_path = None def reset(self, all): if all or self.status == ERROR: @@ -222,11 +232,11 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): frame = job[job_frame] if frame: - if frame.status in (QUEUED, DISPATCHED): + if not frame.log_path or frame.status in (QUEUED, DISPATCHED): self.send_head(http.client.PROCESSING) else: self.server.stats("", "Sending log back to client") - f = open(job.save_path + "%04d" % job_frame + ".log", 'rb') + f = open(frame.log_path, 'rb') self.send_head() @@ -420,7 +430,27 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) self.send_head(headers = {"slave-id": slave_id}) - + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "log": + slave_id = self.headers['slave-id'] + + slave = self.server.updateSlave(slave_id) + + if slave: # only if slave id is valid + length = int(self.headers['content-length']) + + log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) + + job = self.server.getJobByID(log_info.job_id) + + if job: + job.addLog(log_info.frames) + self.send_head(http.client.OK) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -526,19 +556,24 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job = self.server.getJobByID(job_id) if job: - length = int(self.headers['content-length']) job_frame = int(self.headers['job-frame']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".log", 'ab') - f.write(buf) - f.close() - - del buf - - self.server.updateSlave(self.headers['slave-id']) + frame = job[job_frame] - self.send_head() + if frame and frame.log_path: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(frame.log_path, 'ab') + f.write(buf) + f.close() + + del buf + + self.server.updateSlave(self.headers['slave-id']) + + self.send_head() + else: # frame not found + self.send_head(http.client.NO_CONTENT) else: # job not found self.send_head(http.client.NO_CONTENT) diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 7803ad034a7..924493fd34a 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -4,6 +4,28 @@ import subprocess, shutil, time, hashlib from netrender.utils import * +class LogFile: + def __init__(self, job_id = 0, frames = []): + self.job_id = job_id + self.frames = frames + + def serialize(self): + return { + "job_id": self.job_id, + "frames": self.frames + } + + @staticmethod + def materialize(data): + if not data: + return None + + logfile = LogFile() + logfile.job_id = data["job_id"] + logfile.frames = data["frames"] + + return logfile + class RenderSlave: _slave_map = {} diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 1f4ef3a3616..ecdbf69591a 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -117,8 +117,14 @@ def render_slave(engine, scene): print("frame", frame.number) frame_args += ["-f", str(frame.number)] + # announce log to master + logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) + conn.request("POST", "log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) + response = conn.getresponse() + first_frame = job.frames[0].number + # start render start_t = time.time() val = SetErrorMode() @@ -136,13 +142,14 @@ def render_slave(engine, scene): cancelled = engine.test_break() if current_t - run_t > CANCEL_POLL_SPEED: - # update logs. Eventually, it should support one log file for many frames - for frame in job.frames: - headers["job-frame"] = str(frame.number) + # update logs if needed + if stdout: + # (only need to update on one frame, they are linked + headers["job-frame"] = str(first_frame) conn.request("PUT", "log", stdout, headers=headers) response = conn.getresponse() - - stdout = bytes() + + stdout = bytes() run_t = current_t if testCancel(conn, job.id): @@ -164,10 +171,10 @@ def render_slave(engine, scene): # flush the rest of the logs if stdout: - for frame in job.frames: - headers["job-frame"] = str(frame.number) - conn.request("PUT", "log", stdout, headers=headers) - response = conn.getresponse() + # (only need to update on one frame, they are linked + headers["job-frame"] = str(first_frame) + conn.request("PUT", "log", stdout, headers=headers) + response = conn.getresponse() headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} -- cgit v1.2.3 From fd6654d4ef4be21447e45a983b15c7024de33711 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 03:41:37 +0000 Subject: remove brush_sample_falloff, #if 0, unused function is_tablet_cursor --- intern/ghost/intern/GHOST_WindowX11.cpp | 4 ++-- source/blender/blenkernel/BKE_brush.h | 1 - source/blender/blenkernel/intern/brush.c | 30 ------------------------------ 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index ab46c050fa3..060e9ca6f6c 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -450,7 +450,7 @@ static bool match_token(const char *haystack, const char *needle) ** Wacoms x11 config "cursor" refers to its device slot (which we mirror with ** our gSysCursors) for puck like devices (tablet mice essentially). */ - +#if 0 // unused static BOOL is_tablet_cursor(const char *name, const char *type) { int i; @@ -474,7 +474,7 @@ static BOOL is_tablet_cursor(const char *name, const char *type) } return FALSE; } - +#endif static BOOL is_stylus(const char *name, const char *type) { int i; diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 4d24a2433b3..01566648557 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -63,7 +63,6 @@ void brush_curve_preset(struct Brush *b, BrushCurvePreset preset); float brush_curve_strength(struct Brush *br, float p, const float len); /* sampling */ -float brush_sample_falloff(struct Brush *brush, float dist); void brush_sample_tex(struct Brush *brush, float *xy, float *rgba); void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size, struct ImBuf **imbuf); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 9ae0863a78a..6c23d4260ae 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -379,36 +379,6 @@ void brush_check_exists(Brush **brush, const char *name) } /* Brush Sampling */ - -/*static float taylor_approx_cos(float f) -{ - f = f*f; - f = 1.0f - f/2.0f + f*f/24.0f; - return f; -}*/ - -float brush_sample_falloff(Brush *brush, float dist) -{ - float a, outer, inner; - - outer = brush->size >> 1; - inner = outer*brush->innerradius; - - if (dist <= inner) { - return brush->alpha; - } - else if ((dist < outer) && (inner < outer)) { - a = sqrt((dist - inner)/(outer - inner)); - return (1 - a)*brush->alpha; - - /* formula used by sculpt, with taylor approx - a = 0.5f*(taylor_approx_cos(3.0f*(dist - inner)/(outer - inner)) + 1.0f); - return a*brush->alpha; */ - } - else - return 0.0f; -} - void brush_sample_tex(Brush *brush, float *xy, float *rgba) { MTex *mtex= brush->mtex[brush->texact]; -- cgit v1.2.3 From 292e695a35155d9e97897ac9e708c2fadd6ff2a8 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 18 Sep 2009 03:47:17 +0000 Subject: * fix for previous commit, didn't take brush strength into account --- source/blender/blenkernel/intern/brush.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 6c23d4260ae..2a0256da34c 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -441,7 +441,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); VECCOPY(dstf, brush->rgb); - dstf[3]= brush_curve_strength(brush, dist, maxsize); + dstf[3]= brush->alpha*brush_curve_strength(brush, dist, maxsize); } else if (texfall == 1) { brush_sample_tex(brush, xy, dstf); @@ -454,7 +454,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dstf[0] = rgba[0]*brush->rgb[0]; dstf[1] = rgba[1]*brush->rgb[1]; dstf[2] = rgba[2]*brush->rgb[2]; - dstf[3] = rgba[3]*brush_curve_strength(brush, dist, maxsize); + dstf[3] = rgba[3]*brush->alpha*brush_curve_strength(brush, dist, maxsize); } } } @@ -477,7 +477,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0]= crgb[0]; dst[1]= crgb[1]; dst[2]= crgb[2]; - dst[3]= FTOCHAR(brush_curve_strength(brush, dist, maxsize)); + dst[3]= FTOCHAR(brush->alpha*brush_curve_strength(brush, dist, maxsize)); } else if (texfall == 1) { brush_sample_tex(brush, xy, rgba); @@ -493,7 +493,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]); dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]); dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]); - dst[3] = FTOCHAR(rgba[3]*brush_curve_strength(brush, dist, maxsize)); + dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength(brush, dist, maxsize)); } } } -- cgit v1.2.3 From 2a21669e6522c5a2a0f24b36524f274e5d0a699b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 04:07:41 +0000 Subject: curve could return values lower then zero, making a brush add and subtract the color in different parts. (cool but not useful!) --- source/blender/blenkernel/intern/brush.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 2a0256da34c..2e88dc2158c 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -933,8 +933,10 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl /* Uses the brush curve control to find a strength value between 0 and 1 */ float brush_curve_strength(Brush *br, float p, const float len) { + float f; if(p > len) p= len; - return curvemapping_evaluateF(br->curve, 0, p/len); + f= curvemapping_evaluateF(br->curve, 0, p/len); + return (f > 0.0f) ? f:0.0f; } /* TODO: should probably be unified with BrushPainter stuff? */ -- cgit v1.2.3 From d56e23afc08f931c6c5ef59e9822f9604b9db0c8 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Fri, 18 Sep 2009 07:44:52 +0000 Subject: Changed a few mutually exclusive options in preferences to radio buttons (enums) --- release/ui/space_userpref.py | 18 +++++++++------ source/blender/makesrna/intern/rna_userdef.c | 34 ++++++++++++++++------------ 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/release/ui/space_userpref.py b/release/ui/space_userpref.py index c148506214a..9798e0ccab6 100644 --- a/release/ui/space_userpref.py +++ b/release/ui/space_userpref.py @@ -97,14 +97,18 @@ class USERPREF_PT_view(bpy.types.Panel): sub1 = sub.column() sub1.itemL(text="Mouse Buttons:") - sub1.itemR(view, "left_mouse_button_select") - sub1.itemR(view, "right_mouse_button_select") - sub1.itemR(view, "emulate_3_button_mouse") + + sub2 = sub1.column() + sub2.enabled = (view.select_mouse == 'RIGHT') + sub2.itemR(view, "emulate_3_button_mouse") + sub1.itemL(text="Select With:") + sub1.row().itemR(view, "select_mouse", expand=True) + sub1.itemL(text="Middle Mouse:") + sub1.row().itemR(view, "middle_mouse", expand=True) sub1.itemR(view, "use_middle_mouse_paste") - sub1.itemR(view, "middle_mouse_rotate") - sub1.itemR(view, "middle_mouse_pan") - sub1.itemR(view, "wheel_invert_zoom") - sub1.itemR(view, "wheel_scroll_lines") + sub1.itemL(text="Mouse Wheel:") + sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom") + sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines") sub1.itemS() sub1.itemS() sub1.itemS() diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index d9ce215f899..b9c5739e7eb 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1563,6 +1563,16 @@ static void rna_def_userdef_view(BlenderRNA *brna) {USER_ZOOM_DOLLY, "DOLLY", 0, "Dolly", "Zooms in and out based on vertical mouse movement."}, {USER_ZOOM_SCALE, "SCALE", 0, "Scale", "Zooms in and out like scaling the view, mouse movements relative to center."}, {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem select_mouse_items[] = { + {USER_LMOUSESELECT, "LEFT", 0, "Left", "Use left Mouse Button for selection."}, + {0, "RIGHT", 0, "Right", "Use Right Mouse Button for selection."}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem middle_mouse_mouse_items[] = { + {0, "PAN", 0, "Pan", "Use the middle mouse button for panning the viewport."}, + {USER_VIEWMOVE, "ROTATE", 0, "Rotate", "Use the middle mouse button for rotation the viewport."}, + {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem view_rotation_items[] = { {0, "TURNTABLE", 0, "Turntable", "Use turntable style rotation in the viewport."}, @@ -1678,15 +1688,11 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Rotate Around Selection", "Use selection as the orbiting center."); /* select with */ - prop= RNA_def_property(srna, "left_mouse_button_select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_LMOUSESELECT); - RNA_def_property_boolean_funcs(prop, NULL, "rna_userdef_lmb_select_set"); - RNA_def_property_ui_text(prop, "Left Mouse Button Select", "Use left Mouse Button for selection."); - prop= RNA_def_property(srna, "right_mouse_button_select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_LMOUSESELECT); - RNA_def_property_boolean_funcs(prop, NULL, "rna_userdef_rmb_select_set"); - RNA_def_property_ui_text(prop, "Right Mouse Button Select", "Use Right Mouse Button for selection."); + prop= RNA_def_property(srna, "select_mouse", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, select_mouse_items); + RNA_def_property_ui_text(prop, "Select Mouse", "The mouse button used for selection."); prop= RNA_def_property(srna, "emulate_3_button_mouse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_TWOBUTTONMOUSE); @@ -1715,13 +1721,11 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_userdef_update"); /* middle mouse button */ - prop= RNA_def_property(srna, "middle_mouse_rotate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_VIEWMOVE); - RNA_def_property_ui_text(prop, "Middle Mouse Rotate", "Use the middle mouse button for rotation the viewport."); - - prop= RNA_def_property(srna, "middle_mouse_pan", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_VIEWMOVE); - RNA_def_property_ui_text(prop, "Middle Mouse Pan", "Use the middle mouse button for panning the viewport."); + + prop= RNA_def_property(srna, "middle_mouse", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, middle_mouse_mouse_items); + RNA_def_property_ui_text(prop, "Middle Mouse", "Use the middle mouse button to pan or zoom the view."); prop= RNA_def_property(srna, "wheel_invert_zoom", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_WHEELZOOMDIR); -- cgit v1.2.3 From ab518939b55810a6bf0be7a23d5f66a547299cd8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 11:25:52 +0000 Subject: - jitter for painting (image and projection painting, others can be added) - remove falloff setting now the curve is used. - bugfix for airbrush & tablet, with no movement it would assume 1.0 pressure. - rna, use the use_* prefix for brush options. --- release/ui/space_image.py | 22 +++++---- release/ui/space_view3d.py | 6 +-- release/ui/space_view3d_toolbar.py | 55 ++++++++++++++------- source/blender/blenkernel/intern/brush.c | 57 +++++++++++++++------- source/blender/editors/sculpt_paint/paint_image.c | 10 ++-- source/blender/editors/space_image/image_buttons.c | 4 +- source/blender/makesdna/DNA_brush_types.h | 4 +- source/blender/makesrna/intern/rna_brush.c | 38 +++++++-------- 8 files changed, 121 insertions(+), 75 deletions(-) diff --git a/release/ui/space_image.py b/release/ui/space_image.py index 161e29194ed..50ccda34c6a 100644 --- a/release/ui/space_image.py +++ b/release/ui/space_image.py @@ -412,7 +412,7 @@ class IMAGE_PT_paint(bpy.types.Panel): row.template_list(settings, "brushes", settings, "active_brush_index", rows=2) col.template_ID(settings, "brush", new="brush.add") - + row = layout.row(align=True) row.item_enumR(settings, "tool", 'DRAW') row.item_enumR(settings, "tool", 'SOFTEN') @@ -424,12 +424,16 @@ class IMAGE_PT_paint(bpy.types.Panel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, text="") + row.itemR(brush, "use_size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, text="") - + row.itemR(brush, "use_strength_pressure", toggle=True, text="") + + row = col.row(align=True) + row.itemR(brush, "jitter", slider=True) + row.itemR(brush, "use_jitter_pressure", toggle=True, text="") + col.itemR(brush, "blend", text="Blend") class IMAGE_PT_paint_stroke(bpy.types.Panel): @@ -448,16 +452,16 @@ class IMAGE_PT_paint_stroke(bpy.types.Panel): settings = context.tool_settings.image_paint brush = settings.brush - layout.itemR(brush, "airbrush") + layout.itemR(brush, "use_airbrush") col = layout.column() - col.active = brush.airbrush + col.active = brush.use_airbrush col.itemR(brush, "rate", slider=True) - layout.itemR(brush, "space") + layout.itemR(brush, "use_space") row = layout.row(align=True) - row.active = brush.space + row.active = brush.use_space row.itemR(brush, "spacing", text="Distance", slider=True) - row.itemR(brush, "spacing_pressure", toggle=True, text="") + row.itemR(brush, "use_spacing_pressure", toggle=True, text="") class IMAGE_PT_paint_curve(bpy.types.Panel): __space_type__ = 'IMAGE_EDITOR' diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index 62b7fa0d91f..fd06853625e 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -539,16 +539,16 @@ class VIEW3D_MT_sculpt(bpy.types.Menu): layout.itemS() if brush.sculpt_tool != 'GRAB': - layout.itemR(brush, "airbrush") + layout.itemR(brush, "use_airbrush") if brush.sculpt_tool != 'LAYER': - layout.itemR(brush, "anchored") + layout.itemR(brush, "use_anchor") if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'): layout.itemR(brush, "flip_direction") if brush.sculpt_tool == 'LAYER': - layout.itemR(brush, "persistent") + layout.itemR(brush, "use_persistent") layout.itemO("sculpt.set_persistent_base") # ********** Particle menu ********** diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 09e85bf5131..6f17ad925cf 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -387,13 +387,18 @@ class VIEW3D_PT_tools_brush(PaintPanel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, text="") + row.itemR(brush, "use_size_pressure", toggle=True, text="") if brush.sculpt_tool != 'GRAB': row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", text="") - + row.itemR(brush, "use_strength_pressure", text="") + + ''' # XXX - TODO + row = col.row(align=True) + row.itemR(brush, "jitter", slider=True) + row.itemR(brush, "use_jitter_pressure", toggle=True, text="") + ''' col = layout.column() if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'): @@ -419,11 +424,15 @@ class VIEW3D_PT_tools_brush(PaintPanel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, text="") + row.itemR(brush, "use_size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, text="") + row.itemR(brush, "use_strength_pressure", toggle=True, text="") + + row = col.row(align=True) + row.itemR(brush, "jitter", slider=True) + row.itemR(brush, "use_jitter_pressure", toggle=True, text="") col.itemR(brush, "blend", text="Blend") @@ -435,11 +444,15 @@ class VIEW3D_PT_tools_brush(PaintPanel): col = layout.column() row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, text="") + row.itemR(brush, "use_size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, text="") + row.itemR(brush, "use_strength_pressure", toggle=True, text="") + + row = col.row(align=True) + row.itemR(brush, "jitter", slider=True) + row.itemR(brush, "use_jitter_pressure", toggle=True, text="") # Vertex Paint Mode # @@ -449,11 +462,17 @@ class VIEW3D_PT_tools_brush(PaintPanel): row = col.row(align=True) row.itemR(brush, "size", slider=True) - row.itemR(brush, "size_pressure", toggle=True, text="") + row.itemR(brush, "use_size_pressure", toggle=True, text="") row = col.row(align=True) row.itemR(brush, "strength", slider=True) - row.itemR(brush, "strength_pressure", toggle=True, text="") + row.itemR(brush, "use_strength_pressure", toggle=True, text="") + + ''' # XXX - TODO + row = col.row(align=True) + row.itemR(brush, "jitter", slider=True) + row.itemR(brush, "use_jitter_pressure", toggle=True, text="") + ''' class VIEW3D_PT_tools_brush_stroke(PaintPanel): __label__ = "Stroke" @@ -475,27 +494,27 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel): if context.sculpt_object: if brush.sculpt_tool != 'LAYER': - layout.itemR(brush, "anchored") - layout.itemR(brush, "rake") + layout.itemR(brush, "use_anchor") + layout.itemR(brush, "use_rake") - layout.itemR(brush, "airbrush") + layout.itemR(brush, "use_airbrush") col = layout.column() - col.active = brush.airbrush + col.active = brush.use_airbrush col.itemR(brush, "rate", slider=True) if not texture_paint: - layout.itemR(brush, "smooth_stroke") + layout.itemR(brush, "use_smooth_stroke") col = layout.column() - col.active = brush.smooth_stroke + col.active = brush.use_smooth_stroke col.itemR(brush, "smooth_stroke_radius", text="Radius", slider=True) col.itemR(brush, "smooth_stroke_factor", text="Factor", slider=True) - layout.itemR(brush, "space") + layout.itemR(brush, "use_space") row = layout.row(align=True) - row.active = brush.space + row.active = brush.use_space row.itemR(brush, "spacing", text="Distance", slider=True) if texture_paint: - row.itemR(brush, "spacing_pressure", toggle=True, text="") + row.itemR(brush, "use_spacing_pressure", toggle=True, text="") class VIEW3D_PT_tools_brush_curve(PaintPanel): __label__ = "Curve" diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 2e88dc2158c..6c3c97399e4 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -44,6 +44,7 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BLI_rand.h" #include "BKE_brush.h" #include "BKE_colortools.h" @@ -78,7 +79,7 @@ Brush *add_brush(const char *name) brush->smooth_stroke_radius= 75; brush->smooth_stroke_factor= 0.9; brush->rate= 0.1f; - brush->innerradius= 0.5f; + brush->jitter= 0.0f; brush->clone.alpha= 0.5; brush->sculpt_tool = SCULPT_TOOL_DRAW; @@ -513,7 +514,7 @@ typedef struct BrushPainterCache { int lastsize; float lastalpha; - float lastinnerradius; + float lastjitter; ImBuf *ibuf; ImBuf *texibuf; @@ -538,7 +539,7 @@ struct BrushPainter { float startsize; float startalpha; - float startinnerradius; + float startjitter; float startspacing; BrushPainterCache cache; @@ -554,7 +555,7 @@ BrushPainter *brush_painter_new(Brush *brush) painter->startsize = brush->size; painter->startalpha = brush->alpha; - painter->startinnerradius = brush->innerradius; + painter->startjitter = brush->jitter; painter->startspacing = brush->spacing; return painter; @@ -588,7 +589,7 @@ void brush_painter_free(BrushPainter *painter) brush->size = painter->startsize; brush->alpha = painter->startalpha; - brush->innerradius = painter->startinnerradius; + brush->jitter = painter->startjitter; brush->spacing = painter->startspacing; if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf); @@ -744,7 +745,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos) short flt; if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha) - || (brush->innerradius != cache->lastinnerradius)) { + || (brush->jitter != cache->lastjitter)) { if (cache->ibuf) { IMB_freeImBuf(cache->ibuf); cache->ibuf= NULL; @@ -769,7 +770,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos) cache->lastsize= brush->size; cache->lastalpha= brush->alpha; - cache->lastinnerradius= brush->innerradius; + cache->lastjitter= brush->jitter; } else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) { int dx = (int)painter->lastpaintpos[0] - (int)pos[0]; @@ -791,20 +792,34 @@ static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pres brush->alpha = MAX2(0.0, painter->startalpha*pressure); if (brush->flag & BRUSH_SIZE_PRESSURE) brush->size = MAX2(1.0, painter->startsize*pressure); - if (brush->flag & BRUSH_RAD_PRESSURE) - brush->innerradius = MAX2(0.0, painter->startinnerradius*pressure); + if (brush->flag & BRUSH_JITTER_PRESSURE) + brush->jitter = MAX2(0.0, painter->startjitter*pressure); if (brush->flag & BRUSH_SPACING_PRESSURE) brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure)); } +static void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos) +{ + if(brush->jitter){ + jitterpos[0] = pos[0] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2); + jitterpos[1] = pos[1] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2); + } + else { + VECCOPY2D(jitterpos, pos); + } +} + int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user) { Brush *brush= painter->brush; int totpaintops= 0; - if (pressure == 0.0f) - pressure = 1.0f; /* zero pressure == not using tablet */ - + if (pressure == 0.0f) { + if(painter->lastpressure) // XXX - hack, operator misses + pressure= painter->lastpressure; + else + pressure = 1.0f; /* zero pressure == not using tablet */ + } if (painter->firsttouch) { /* paint exactly once on first touch */ painter->startpaintpos[0]= pos[0]; @@ -855,7 +870,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl } #endif else { - float startdistance, spacing, step, paintpos[2], dmousepos[2]; + float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2]; float t, len, press; /* compute brush spacing adapted to brush size, spacing may depend @@ -880,11 +895,13 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl brush_apply_pressure(painter, brush, press); spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f; + brush_jitter_pos(brush, paintpos, finalpos); + if (painter->cache.enabled) - brush_painter_refresh_cache(painter, paintpos); + brush_painter_refresh_cache(painter, finalpos); totpaintops += - func(user, painter->cache.ibuf, painter->lastpaintpos, paintpos); + func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos); painter->lastpaintpos[0]= paintpos[0]; painter->lastpaintpos[1]= paintpos[1]; @@ -907,10 +924,14 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl while (painter->accumtime >= brush->rate) { brush_apply_pressure(painter, brush, pressure); + + brush_jitter_pos(brush, pos, finalpos); + if (painter->cache.enabled) - brush_painter_refresh_cache(painter, paintpos); + brush_painter_refresh_cache(painter, finalpos); + totpaintops += - func(user, painter->cache.ibuf, painter->lastmousepos, pos); + func(user, painter->cache.ibuf, painter->lastmousepos, finalpos); painter->accumtime -= brush->rate; } @@ -924,7 +945,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl brush->alpha = painter->startalpha; brush->size = painter->startsize; - brush->innerradius = painter->startinnerradius; + brush->jitter = painter->startjitter; brush->spacing = painter->startspacing; return totpaintops; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index e8dd27f1bd2..0d83cef3e95 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -4443,6 +4443,7 @@ typedef struct PaintOperation { int first; int prevmouse[2]; + float prev_pressure; /* need this since we dont get tablet events for pressure change */ int brush_size_orig; double starttime; @@ -4722,8 +4723,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) if(wmtab->Active == EVT_TABLET_ERASER) pop->s.blend= IMB_BLEND_ERASE_ALPHA; } - else - pressure= 1.0f; + else /* otherwise airbrush becomes 1.0 pressure instantly */ + pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f; if(pop->first) { pop->prevmouse[0]= mouse[0]; @@ -4732,8 +4733,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) /* special exception here for too high pressure values on first touch in windows for some tablets, then we just skip first touch .. */ - if ((pop->s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE| - BRUSH_SPACING_PRESSURE|BRUSH_RAD_PRESSURE)) && tablet && (pressure >= 0.99f)) + if ((pop->s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|BRUSH_SPACING_PRESSURE)) && tablet && (pressure >= 0.99f)) return; } @@ -4748,6 +4748,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) /* apply */ paint_apply(C, op, &itemptr); + + pop->prev_pressure= pressure; } static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event) diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 78687958c60..bdf3e9416b9 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -453,8 +453,8 @@ void brush_buttons(const bContext *C, uiBlock *block, short fromsima, uiDefIconButBitS(block, TOG|BIT, BRUSH_ALPHA_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-20,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiDefButI(block, NUMSLI, evt_nop, "Size ", 0,yco-40,180,19, &brush->size, 1, 200, 0, 0, "The size of the brush"); uiDefIconButBitS(block, TOG|BIT, BRUSH_SIZE_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-40,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); - uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush"); - uiDefIconButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); +// uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush"); +// uiDefIconButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiDefButF(block, NUMSLI, evt_nop, "Spacing ",0,yco-80,180,19, &brush->spacing, 1.0, 100.0, 0, 0, "Repeating paint on %% of brush diameter"); uiDefIconButBitS(block, TOG|BIT, BRUSH_SPACING_PRESSURE, evt_nop, ICON_STYLUS_PRESSURE, 180,yco-80,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); uiBlockEndAlign(block); diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index a3a1a342584..1bbccd20486 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -56,7 +56,7 @@ typedef struct Brush { short flag, blend; /* general purpose flag, blend mode */ int size; /* brush diameter */ - float innerradius; /* inner radius after which the falloff starts */ + float jitter; /* jitter the position of the brush */ float spacing; /* spacing of paint operations */ int smooth_stroke_radius; /* turning radius (in pixels) for smooth stroke */ float smooth_stroke_factor; /* higher values limit fast changes in the stroke direction */ @@ -76,7 +76,7 @@ typedef struct Brush { #define BRUSH_TORUS 2 #define BRUSH_ALPHA_PRESSURE 4 #define BRUSH_SIZE_PRESSURE 8 -#define BRUSH_RAD_PRESSURE 16 +#define BRUSH_JITTER_PRESSURE 16 /* was BRUSH_RAD_PRESSURE */ #define BRUSH_SPACING_PRESSURE 32 #define BRUSH_FIXED_TEX 64 #define BRUSH_RAKE 128 diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index eea29381b92..15125795e01 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * Contributor(s): Blender Foundation (2008), Juho Vepsäläinen + * Contributor(s): Blender Foundation (2008), Juho Veps�l�inen * * ***** END GPL LICENSE BLOCK ***** */ @@ -133,11 +133,11 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_range(prop, 1, 200); RNA_def_property_ui_text(prop, "Size", "Diameter of the brush."); - prop= RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "innerradius"); + prop= RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "jitter"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Falloff", "Falloff radius of the brush."); - + RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush while painting."); + prop= RNA_def_property(srna, "spacing", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spacing"); RNA_def_property_range(prop, 1.0f, 100.0f); @@ -166,51 +166,51 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Strength", "The amount of pressure on the brush."); /* flag */ - prop= RNA_def_property(srna, "airbrush", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_airbrush", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_AIRBRUSH); RNA_def_property_ui_text(prop, "Airbrush", "Keep applying paint effect while holding mouse (spray)."); - prop= RNA_def_property(srna, "wrap", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_wrap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_TORUS); RNA_def_property_ui_text(prop, "Wrap", "Enable torus wrapping while painting."); - prop= RNA_def_property(srna, "strength_pressure", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength."); - prop= RNA_def_property(srna, "size_pressure", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_size_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SIZE_PRESSURE); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size."); - prop= RNA_def_property(srna, "falloff_pressure", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RAD_PRESSURE); + prop= RNA_def_property(srna, "use_jitter_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_JITTER_PRESSURE); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); - RNA_def_property_ui_text(prop, "Falloff Pressure", "Enable tablet pressure sensitivity for falloff."); - - prop= RNA_def_property(srna, "spacing_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Jitter Pressure", "Enable tablet pressure sensitivity for jitter."); + + prop= RNA_def_property(srna, "use_spacing_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACING_PRESSURE); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Spacing Pressure", "Enable tablet pressure sensitivity for spacing."); - prop= RNA_def_property(srna, "rake", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_rake", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RAKE); RNA_def_property_ui_text(prop, "Rake", "Rotate the brush texture to match the stroke direction."); - prop= RNA_def_property(srna, "anchored", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_anchor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ANCHORED); RNA_def_property_ui_text(prop, "Anchored", "Keep the brush anchored to the initial location."); - prop= RNA_def_property(srna, "space", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_space", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE); RNA_def_property_ui_text(prop, "Space", "Limit brush application to the distance specified by spacing."); - prop= RNA_def_property(srna, "smooth_stroke", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_smooth_stroke", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SMOOTH_STROKE); RNA_def_property_ui_text(prop, "Smooth Stroke", "Brush lags behind mouse and follows a smoother path."); - prop= RNA_def_property(srna, "persistent", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_persistent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_PERSISTENT); RNA_def_property_ui_text(prop, "Persistent", "Sculpts on a persistent layer of the mesh."); -- cgit v1.2.3 From 854ea35a2498cb35e7cce26e396fab775692196e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 18 Sep 2009 12:43:36 +0000 Subject: 2.5: Handlers are now evaluated in a different order, fixing some issues like Shift+R (repeat last) not giving capital R in the text editor. There is also new modal handler list at the window level, and the API call will always add it to that one now, since modal handlers were not used in other levels. The order used to be: * window modal + keymap * area modal + keymap * region modal + keymap Now it is: * window modal * region keymap * area keymap * window keymap --- source/blender/blenloader/intern/readfile.c | 1 + source/blender/editors/animation/anim_markers.c | 2 +- source/blender/editors/animation/anim_ops.c | 2 +- .../blender/editors/armature/editarmature_sketch.c | 4 +- source/blender/editors/armature/poselib.c | 2 +- source/blender/editors/gpencil/gpencil_paint.c | 2 +- .../blender/editors/interface/interface_handlers.c | 6 +- source/blender/editors/interface/interface_panel.c | 4 +- .../blender/editors/interface/interface_regions.c | 8 +-- source/blender/editors/interface/view2d_ops.c | 6 +- source/blender/editors/mesh/loopcut.c | 4 +- source/blender/editors/physics/editparticle.c | 2 +- source/blender/editors/screen/screen_ops.c | 14 ++-- source/blender/editors/sculpt_paint/paint_image.c | 4 +- source/blender/editors/sculpt_paint/paint_vertex.c | 4 +- source/blender/editors/sculpt_paint/sculpt.c | 2 +- source/blender/editors/space_image/image_ops.c | 8 +-- source/blender/editors/space_node/node_edit.c | 4 +- source/blender/editors/space_text/text_ops.c | 6 +- source/blender/editors/space_view3d/view3d_edit.c | 6 +- source/blender/editors/transform/transform_ops.c | 2 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 2 +- source/blender/makesdna/DNA_windowmanager_types.h | 3 +- source/blender/windowmanager/WM_api.h | 2 +- .../blender/windowmanager/intern/wm_event_system.c | 77 ++++++++++++++-------- source/blender/windowmanager/intern/wm_init_exit.c | 1 + source/blender/windowmanager/intern/wm_operators.c | 10 +-- source/blender/windowmanager/intern/wm_window.c | 1 + 28 files changed, 106 insertions(+), 83 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0cbbc1051e7..c5dcf1ce520 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4371,6 +4371,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->timers.first= win->timers.last= NULL; win->queue.first= win->queue.last= NULL; win->handlers.first= win->handlers.last= NULL; + win->modalhandlers.first= win->modalhandlers.last= NULL; win->subwindows.first= win->subwindows.last= NULL; win->gesture.first= win->gesture.last= NULL; diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 06fa3b715e0..bed534ae070 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -458,7 +458,7 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt) mm->event_type= evt->type; /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); /* reset frs delta */ RNA_int_set(op->ptr, "frames", 0); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 186bdc3b762..80077a6d4b3 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -162,7 +162,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) change_frame_apply(C, op); /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 79d3d7b1366..1e416d9c31d 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -2618,7 +2618,7 @@ static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event) sk_draw_stroke(C, sketch, sketch->active_stroke, dd, snap); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -2644,7 +2644,7 @@ static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event) sk_start_draw_gesture(sketch); sk_draw_stroke(C, sketch, sketch->gesture, dd, snap); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index c332a297e57..f072f2e980e 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -1411,7 +1411,7 @@ static int poselib_preview_invoke(bContext *C, wmOperator *op, wmEvent *event) poselib_preview_apply(C, op); /* add temp handler if we're running as a modal operator */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 99b85d62026..92ae2400666 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1341,7 +1341,7 @@ static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event) } /* add a modal handler for this operator, so that we can then draw continuous strokes */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 246058ceacc..e8d813d8ff9 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3660,11 +3660,11 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s if(!(but->block->handle && but->block->handle->popup)) { if(button_modal_state(state)) { if(!button_modal_state(data->state)) - WM_event_add_ui_handler(C, &data->window->handlers, ui_handler_region_menu, NULL, data); + WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data); } else { if(button_modal_state(data->state)) - WM_event_remove_ui_handler(&data->window->handlers, ui_handler_region_menu, NULL, data); + WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data); } } @@ -4600,7 +4600,7 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata) uiPopupBlockHandle temp= *menu; ui_popup_block_free(C, menu); - WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu); + WM_event_remove_ui_handler(&CTX_wm_window(C)->modalhandlers, ui_handler_popup, ui_handler_remove_popup, menu); if(temp.menuretval == UI_RETURN_OK) { if(temp.popup_func) diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 776122380bf..cf29a1ddb58 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1400,14 +1400,14 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat MEM_freeN(data); pa->activedata= NULL; - WM_event_remove_ui_handler(&win->handlers, ui_handler_panel, ui_handler_remove_panel, pa); + WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa); } else { if(!data) { data= MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData"); pa->activedata= data; - WM_event_add_ui_handler(C, &win->handlers, ui_handler_panel, ui_handler_remove_panel, pa); + WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa); } if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG)) diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 95305819e2b..065d391e6d6 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2275,7 +2275,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut if(!but) { handle->popup= 1; - UI_add_popup_handlers(C, &window->handlers, handle); + UI_add_popup_handlers(C, &window->modalhandlers, handle); WM_event_add_mousemove(C); } @@ -2332,7 +2332,7 @@ void uiPupMenuEnd(bContext *C, uiPopupMenu *pup) menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup); menu->popup= 1; - UI_add_popup_handlers(C, &window->handlers, menu); + UI_add_popup_handlers(C, &window->modalhandlers, menu); WM_event_add_mousemove(C); MEM_freeN(pup); @@ -2493,7 +2493,7 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, i handle->optype= (opname)? WM_operatortype_find(opname, 0): NULL; handle->opcontext= opcontext; - UI_add_popup_handlers(C, &window->handlers, handle); + UI_add_popup_handlers(C, &window->modalhandlers, handle); WM_event_add_mousemove(C); } @@ -2516,7 +2516,7 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int handle->cancel_func= confirm_cancel_operator; handle->opcontext= opcontext; - UI_add_popup_handlers(C, &window->handlers, handle); + UI_add_popup_handlers(C, &window->modalhandlers, handle); WM_event_add_mousemove(C); } diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 33838418842..ae4fe4eed1b 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -210,7 +210,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) WM_cursor_modal(window, BC_NSEW_SCROLLCURSOR); /* add temp handler */ - WM_event_add_modal_handler(C, &window->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -764,7 +764,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event) WM_cursor_modal(window, BC_NSEW_SCROLLCURSOR); /* add temp handler */ - WM_event_add_modal_handler(C, &window->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1292,7 +1292,7 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event) v2d->scroll_ui |= V2D_SCROLL_V_ACTIVE; /* still ok, so can add */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } else { diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index f83ab04d785..c322a169679 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -328,7 +328,7 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) return OPERATOR_CANCELLED; /* add a modal handler for this operator - handles loop selection */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); lcd = op->customdata; lcd->vc.mval[0] = evt->mval[0]; @@ -356,7 +356,7 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) return OPERATOR_CANCELLED; /* add a modal handler for this operator - handles loop selection */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); lcd = op->customdata; lcd->vc.mval[0] = evt->mval[0]; diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index cbfcf1508c7..a5e169eba06 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -3352,7 +3352,7 @@ static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event) brush_edit_apply_event(C, op, event); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 605bd8682f5..6107d412323 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -456,7 +456,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event) } else { /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -588,7 +588,7 @@ static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event) /* add modal handler */ WM_cursor_modal(CTX_wm_window(C), BC_SWAPAREA_CURSOR); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -870,7 +870,7 @@ static int area_move_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1160,7 +1160,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event) area_move_set_limits(CTX_wm_screen(C), dir, &sd->bigger, &sd->smaller); /* add temp handler for edge move or cancel */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1296,7 +1296,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) rmd->origval= rmd->ar->type->minsizey; /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1749,7 +1749,7 @@ static int area_join_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -2944,7 +2944,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene); /* add modal handler for ESC */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 0d83cef3e95..d3cd49a2658 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -4764,7 +4764,7 @@ static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event) paint_apply_event(C, op, event); pop= op->customdata; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); if(pop->s.brush->flag & BRUSH_AIRBRUSH) pop->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f); @@ -4966,7 +4966,7 @@ static int grab_clone_invoke(bContext *C, wmOperator *op, wmEvent *event) cmv->starty= event->y; op->customdata= cmv; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index c43d903d4a6..17fd1d4fa4a 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1502,7 +1502,7 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) wpaint_stroke_done); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); op->type->modal(C, op, event); @@ -1775,7 +1775,7 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) vpaint_stroke_done); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); op->type->modal(C, op, event); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 822e79bea1e..a466c87746b 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1440,7 +1440,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even sculpt_stroke_done); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); op->type->modal(C, op, event); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index d54dd56d1e8..3491ccd9d20 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -161,7 +161,7 @@ static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event) vpd->xof= sima->xof; vpd->yof= sima->yof; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); } static void view_pan_exit(bContext *C, wmOperator *op, int cancel) @@ -280,7 +280,7 @@ static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event) vpd->y= event->y; vpd->zoom= sima->zoom; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); } static void view_zoom_exit(bContext *C, wmOperator *op, int cancel) @@ -1453,7 +1453,7 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event) sample_apply(C, op, event); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1621,7 +1621,7 @@ static int record_composite_invoke(bContext *C, wmOperator *op, wmEvent *event) rcd= op->customdata; rcd->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.0f); - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); if(!record_composite_apply(C, op)) return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 4fd6995b8fd..5fc09408229 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1216,7 +1216,7 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event) nsw->oldwidth= node->width; /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -2033,7 +2033,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) nldrag->link= nodeAddLink(snode->edittree, NULL, NULL, nldrag->node, nldrag->sock); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 3568f50dfe1..8e81336912b 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1731,7 +1731,7 @@ static int scroll_invoke(bContext *C, wmOperator *op, wmEvent *event) st->flags|= ST_SCROLL_SELECT; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1860,7 +1860,7 @@ static int scroll_bar_invoke(bContext *C, wmOperator *op, wmEvent *event) st->flags|= ST_SCROLL_SELECT; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -2115,7 +2115,7 @@ static int set_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event) scu->sell= txt_get_span(st->text->lines.first, st->text->sell); scu->selc= st->text->selc; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); set_cursor_apply(C, op, event); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index bbcee0415f8..d28789491dd 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -541,7 +541,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -625,7 +625,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) viewops_data(C, op, event); /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -823,7 +823,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) viewops_data(C, op, event); /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 7dfae33bc39..f9597b81114 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -270,7 +270,7 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event) TransInfo *t = op->customdata; /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); t->flag |= T_MODAL; // XXX meh maybe somewhere else diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index ccdc51430bc..b848bd4fb09 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -342,7 +342,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *event) minimize_stretch_iteration(C, op, 1); ms= op->customdata; - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); ms->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f); return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 00fbc04844c..67a6b3153e4 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -162,7 +162,8 @@ typedef struct wmWindow { ListBase timers; ListBase queue; /* all events (ghost level events were handled) */ - ListBase handlers; /* window+screen handlers, overriding all queues */ + ListBase handlers; /* window+screen handlers, handled last */ + ListBase modalhandlers; /* modal handlers, overriding all queues */ ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ ListBase gesture; /* gesture stuff */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index b2edbc324ea..a757deb4a8a 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -119,7 +119,7 @@ void WM_event_remove_ui_handler(ListBase *handlers, int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), void *userdata); -struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, ListBase *handlers, struct wmOperator *op); +struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op); void WM_event_remove_handlers(struct bContext *C, ListBase *handlers); void WM_event_add_mousemove(struct bContext *C); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 22c5788b0ae..2a2e0141381 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1024,7 +1024,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); - if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */ + if(action==WM_HANDLER_BREAK) /* not always_pass here, it denotes removed handler */ break; } } @@ -1042,8 +1042,12 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= wm_handler_operator_call(C, handlers, handler, event, NULL); } - if(!always_pass && action==WM_HANDLER_BREAK) - break; + if(action==WM_HANDLER_BREAK) { + if(always_pass) + action= WM_HANDLER_CONTINUE; + else + break; + } } /* fileread case */ @@ -1055,6 +1059,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) static int wm_event_inside_i(wmEvent *event, rcti *rect) { + if(wm_event_always_pass(event)) + return 1; if(BLI_in_rcti(rect, event->x, event->y)) return 1; if(event->type==MOUSEMOVE) { @@ -1156,58 +1162,70 @@ void wm_event_do_handlers(bContext *C) /* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */ wm_window_make_drawable(C, win); - action= wm_handlers_do(C, event, &win->handlers); + /* first we do modal handlers */ + action= wm_handlers_do(C, event, &win->modalhandlers); /* fileread case */ - if(CTX_wm_window(C)==NULL) { + if(CTX_wm_window(C)==NULL) return; - } /* builtin tweak, if action is break it removes tweak */ - if(!wm_event_always_pass(event)) - wm_tweakevent_test(C, event, action); + wm_tweakevent_test(C, event, action); - if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) { + if(action==WM_HANDLER_CONTINUE) { ScrArea *sa; ARegion *ar; int doit= 0; /* XXX to solve, here screen handlers? */ - if(!wm_event_always_pass(event)) { - if(event->type==MOUSEMOVE) { - /* state variables in screen, cursors */ - ED_screen_set_subwinactive(win, event); - /* for regions having custom cursors */ - wm_paintcursor_test(C, event); - } + if(event->type==MOUSEMOVE) { + /* state variables in screen, cursors */ + ED_screen_set_subwinactive(win, event); + /* for regions having custom cursors */ + wm_paintcursor_test(C, event); } for(sa= win->screen->areabase.first; sa; sa= sa->next) { - if(wm_event_always_pass(event) || wm_event_inside_i(event, &sa->totrct)) { - + if(wm_event_inside_i(event, &sa->totrct)) { CTX_wm_area_set(C, sa); - CTX_wm_region_set(C, NULL); - action= wm_handlers_do(C, event, &sa->handlers); - if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) { + if(action==WM_HANDLER_CONTINUE) { for(ar=sa->regionbase.first; ar; ar= ar->next) { - if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct)) { + if(wm_event_inside_i(event, &ar->winrct)) { CTX_wm_region_set(C, ar); action= wm_handlers_do(C, event, &ar->handlers); doit |= (BLI_in_rcti(&ar->winrct, event->x, event->y)); - if(!wm_event_always_pass(event)) { - if(action==WM_HANDLER_BREAK) - break; - } + if(action==WM_HANDLER_BREAK) + break; } } } + + CTX_wm_region_set(C, NULL); + + if(action==WM_HANDLER_CONTINUE) + action= wm_handlers_do(C, event, &sa->handlers); + + CTX_wm_area_set(C, NULL); + /* NOTE: do not escape on WM_HANDLER_BREAK, mousemove needs handled for previous area */ } } + if(action==WM_HANDLER_CONTINUE) { + /* also some non-modal handlers need active area/region */ + CTX_wm_area_set(C, area_event_inside(C, event->x, event->y)); + CTX_wm_region_set(C, region_event_inside(C, event->x, event->y)); + + action= wm_handlers_do(C, event, &win->handlers); + + /* fileread case */ + if(CTX_wm_window(C)==NULL) + return; + } + /* XXX hrmf, this gives reliable previous mouse coord for area change, feels bad? doing it on ghost queue gives errors when mousemoves go over area borders */ if(doit && win->screen->subwinactive != win->screen->mainwin) { @@ -1274,7 +1292,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) handler->op_region= CTX_wm_region(C); handler->filescreen= CTX_wm_screen(C); - BLI_addhead(&win->handlers, handler); + BLI_addhead(&win->modalhandlers, handler); WM_event_fileselect_event(C, op, full?EVT_FILESELECT_FULL_OPEN:EVT_FILESELECT_OPEN); } @@ -1285,9 +1303,10 @@ void WM_event_set_handler_flag(wmEventHandler *handler, int flag) handler->flag= flag; } -wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op) +wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op) { wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event modal handler"); + wmWindow *win= CTX_wm_window(C); /* operator was part of macro */ if(op->opm) { @@ -1302,7 +1321,7 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOp handler->op_area= CTX_wm_area(C); /* means frozen screen context for modal handlers! */ handler->op_region= CTX_wm_region(C); - BLI_addhead(handlers, handler); + BLI_addhead(&win->modalhandlers, handler); return handler; } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 9a268f8be17..5c78b32f3f8 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -186,6 +186,7 @@ void WM_exit(bContext *C) CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); + WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 2e2d463bbd9..f31d62967ae 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1366,7 +1366,7 @@ int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1430,7 +1430,7 @@ int WM_gesture_circle_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_CIRCLE); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1607,7 +1607,7 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_LASSO); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1622,7 +1622,7 @@ int WM_gesture_lines_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_LINES); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1929,7 +1929,7 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) wm_radial_control_paint, op->customdata); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); WM_radial_control_modal(C, op, event); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index cbb5bed4c00..2eee11c6820 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -146,6 +146,7 @@ void wm_window_free(bContext *C, wmWindow *win) CTX_wm_window_set(C, NULL); WM_event_remove_handlers(C, &win->handlers); + WM_event_remove_handlers(C, &win->modalhandlers); /* end running jobs, a job end also removes its timer */ for(wt= win->timers.first; wt; wt= wtnext) { -- cgit v1.2.3 From 26836bf44f39d4c83d7b4de94dd742c84cf82eda Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 18 Sep 2009 13:02:20 +0000 Subject: 2.5: Python operators now have a working poll() function, solved by wrapping all polling in WM_operator_poll and adding a special callback for python. --- release/io/export_ply.py | 1 - source/blender/editors/interface/interface.c | 2 +- .../editors/interface/interface_templates.c | 2 +- .../blender/editors/space_view3d/view3d_toolbar.c | 4 +-- source/blender/makesdna/DNA_windowmanager_types.h | 1 + source/blender/python/intern/bpy_operator.c | 2 +- source/blender/python/intern/bpy_operator_wrap.c | 42 +++++++++++----------- source/blender/windowmanager/WM_api.h | 1 + .../blender/windowmanager/intern/wm_event_system.c | 15 ++++---- source/blender/windowmanager/intern/wm_operators.c | 2 +- 10 files changed, 39 insertions(+), 33 deletions(-) diff --git a/release/io/export_ply.py b/release/io/export_ply.py index 491ffe6b9df..b8fbe56f01c 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -250,7 +250,6 @@ class EXPORT_OT_ply(bpy.types.Operator): ] def poll(self, context): - print("Poll") return context.active_object != None def execute(self, context): diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2d4b2caa845..fbc3c859f20 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -597,7 +597,7 @@ void uiEndBlock(const bContext *C, uiBlock *block) if(but->context) CTX_store_set((bContext*)C, but->context); - if(ot==NULL || (ot->poll && ot->poll((bContext *)C)==0)) { + if(ot == NULL || WM_operator_poll((bContext*)C, ot)==0) { but->flag |= UI_BUT_DISABLED; but->lock = 1; } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b27425f958d..b15ddcfae17 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2064,7 +2064,7 @@ static void operator_search_cb(const bContext *C, void *arg, char *str, uiSearch for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { char name[256]; int len= strlen(ot->name); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 46341f53c26..e1c6f70bde0 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -163,7 +163,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) if(op==NULL) return; - if(op->type->poll && op->type->poll((bContext *)C)==0) + if(WM_operator_poll((bContext*)C, op->type) == 0) return; block= uiLayoutGetBlock(pa->layout); @@ -208,7 +208,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { if(0==uiSearchItemAdd(items, ot->name, ot, 0)) break; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 67a6b3153e4..ee2b0ab848f 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -228,6 +228,7 @@ typedef struct wmOperatorType { /* only used for operators defined with python * use to store pointers to python functions */ void *pyop_data; + int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot); } wmOperatorType; diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 69a7e554452..f2e2dd77e6d 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -65,7 +65,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) return NULL; } - if(ot->poll && (ot->poll(C) == FALSE)) { + if(WM_operator_poll((bContext*)C, ot) == FALSE) { PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect"); return NULL; } diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 0a487a8dbe8..bbf657d8ce0 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -81,9 +81,9 @@ static struct BPY_flag_def pyop_ret_flags[] = { extern void BPY_update_modules( void ); //XXX temp solution -static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event) +static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event) { - PyObject *py_class = op->type->pyop_data; + PyObject *py_class = ot->pyop_data; PyObject *args; PyObject *ret= NULL, *py_class_instance, *item= NULL; int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); @@ -105,7 +105,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve /* Assign instance attributes from operator properties */ - { + if(op) { const char *arg_name; RNA_STRUCT_BEGIN(op->ptr, prop) { @@ -121,10 +121,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve } /* set operator pointer RNA as instance "__operator__" attribute */ - RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); - py_operator= pyrna_struct_CreatePyObject(&ptr_operator); - PyObject_SetAttrString(py_class_instance, "__operator__", py_operator); - Py_DECREF(py_operator); + if(op) { + RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); + py_operator= pyrna_struct_CreatePyObject(&ptr_operator); + PyObject_SetAttrString(py_class_instance, "__operator__", py_operator); + Py_DECREF(py_operator); + } RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); @@ -148,8 +150,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve else if (mode==PYOP_POLL) { item= PyObject_GetAttrString(py_class, "poll"); args = PyTuple_New(2); - //XXX Todo - wrap context in a useful way, None for now. - PyTuple_SET_ITEM(args, 1, Py_None); + PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context)); } PyTuple_SET_ITEM(args, 0, py_class_instance); @@ -160,21 +161,24 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve } if (ret == NULL) { /* covers py_class_instance failing too */ - BPy_errors_to_report(op->reports); + if(op) + BPy_errors_to_report(op->reports); } else { if (mode==PYOP_POLL) { if (PyBool_Check(ret) == 0) { PyErr_SetString(PyExc_ValueError, "Python poll function return value "); - BPy_errors_to_report(op->reports); + if(op) + BPy_errors_to_report(op->reports); } else { ret_flag= ret==Py_True ? 1:0; } } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) { - /* the returned value could not be converted into a flag */ - BPy_errors_to_report(op->reports); + /* the returned value could not be converted into a flag */ + if(op) + BPy_errors_to_report(op->reports); ret_flag = OPERATOR_CANCELLED; } @@ -225,19 +229,17 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event) { - return PYTHON_OT_generic(PYOP_INVOKE, C, op, event); + return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event); } static int PYTHON_OT_execute(bContext *C, wmOperator *op) { - return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL); + return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL); } -static int PYTHON_OT_poll(bContext *C) +static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot) { - // XXX TODO - no way to get the operator type (and therefor class) from the poll function. - //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL); - return 1; + return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL); } void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) @@ -270,7 +272,7 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) if (PyObject_HasAttrString(py_class, "execute")) ot->exec= PYTHON_OT_execute; if (PyObject_HasAttrString(py_class, "poll")) - ot->poll= PYTHON_OT_poll; + ot->pyop_poll= PYTHON_OT_poll; ot->pyop_data= userdata; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index a757deb4a8a..69c96d0d89d 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -162,6 +162,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag) wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname); +int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot); int WM_operator_call (struct bContext *C, struct wmOperator *op); int WM_operator_repeat (struct bContext *C, struct wmOperator *op); int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2a2e0141381..e570a733d89 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -259,20 +259,23 @@ void wm_event_do_notifiers(bContext *C) /* ********************* operators ******************* */ -static int wm_operator_poll(bContext *C, wmOperatorType *ot) +int WM_operator_poll(bContext *C, wmOperatorType *ot) { wmOperatorTypeMacro *otmacro; for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) { wmOperatorType *ot= WM_operatortype_find(otmacro->idname, 0); - if(0==wm_operator_poll(C, ot)) + if(0==WM_operator_poll(C, ot)) return 0; } - if(ot->poll) + /* python needs operator type, so we added exception for it */ + if(ot->pyop_poll) + return ot->pyop_poll(C, ot); + else if(ot->poll) return ot->poll(C); - + return 1; } @@ -284,7 +287,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) if(op==NULL || op->type==NULL) return retval; - if(0==wm_operator_poll(C, op->type)) + if(0==WM_operator_poll(C, op->type)) return retval; if(op->type->exec) @@ -397,7 +400,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P wmWindowManager *wm= CTX_wm_manager(C); int retval= OPERATOR_PASS_THROUGH; - if(wm_operator_poll(C, ot)) { + if(WM_operator_poll(C, ot)) { wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */ if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index f31d62967ae..a6fc575ce70 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -682,7 +682,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { char name[256]; int len= strlen(ot->name); -- cgit v1.2.3 From c67db42e3ee8d6d8a373a76fa62b2e28adf6d24e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 18 Sep 2009 13:13:28 +0000 Subject: Fix #19383: crash pressing image open in texture buttons. --- source/blender/editors/space_image/image_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 3491ccd9d20..483d2fc6043 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -643,7 +643,7 @@ static int open_exec(bContext *C, wmOperator *op) static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) { SpaceImage *sima= CTX_wm_space_image(C); - char *path= (sima->image)? sima->image->name: U.textudir; + char *path= (sima && sima->image)? sima->image->name: U.textudir; if(RNA_property_is_set(op->ptr, "path")) return open_exec(C, op); -- cgit v1.2.3 From 0f25d9bb542d4c78b3b28571e1ed435928f5c336 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 18 Sep 2009 13:17:33 +0000 Subject: Fix #19381: Switching from sculpt to object mode does not update toolbar. --- source/blender/editors/sculpt_paint/sculpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a466c87746b..89cd0555ff9 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1569,10 +1569,10 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); paint_cursor_start(C, sculpt_poll); - - WM_event_add_notifier(C, NC_SCENE|ND_MODE, CTX_data_scene(C)); } + WM_event_add_notifier(C, NC_SCENE|ND_MODE, CTX_data_scene(C)); + return OPERATOR_FINISHED; } -- cgit v1.2.3 From 474378a0e80cb89a91d206d77b933f5c5bdd2319 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 15:47:00 +0000 Subject: VecAngle3_2D, VecAngle2 and VecAngle3 returned degrees, in arithb.c degrees are most common. - These now return radians - added macro RAD2DEG(rad) - renamed VecAngle3_2D to Vec2Angle3 since Vec2* is used in arithb.c for 2D vector functions. --- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenlib/BLI_arithb.h | 4 +++- source/blender/blenlib/intern/arithb.c | 8 +++---- .../blender/editors/armature/editarmature_sketch.c | 6 ++--- source/blender/editors/armature/meshlaplacian.c | 6 ++--- source/blender/editors/mesh/editmesh_mods.c | 10 ++++---- source/blender/editors/mesh/editmesh_tools.c | 12 +++++----- source/blender/editors/space_view3d/drawobject.c | 10 ++++---- source/blender/editors/uvedit/uvedit_draw.c | 28 +++++++++++----------- 9 files changed, 44 insertions(+), 42 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index ea3fce9ffaf..2ce877bd847 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1616,7 +1616,7 @@ static void bevel_list_flip_tangents(BevList *bl) nr= bl->nr; while(nr--) { - if(VecAngle2(bevp0->tan, bevp1->tan) > 90) + if(RAD2DEG(VecAngle2(bevp0->tan, bevp1->tan)) > 90) VecNegf(bevp1->tan); bevp0= bevp1; diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index c2d707f60f0..623a9afeb73 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -401,7 +401,7 @@ float VecAngle2(float *v1, float *v2); float VecAngle3(float *v1, float *v2, float *v3); float NormalizedVecAngle2(float *v1, float *v2); -float VecAngle3_2D(float *v1, float *v2, float *v3); +float Vec2Angle3(float *v1, float *v2, float *v3); float NormalizedVecAngle2_2D(float *v1, float *v2); void NormalShortToFloat(float *out, short *in); @@ -454,6 +454,8 @@ void i_window( #define BLI_CS_REC709 1 #define BLI_CS_CIE 2 +#define RAD2DEG(_rad) ((_rad)*(180.0/M_PI)) + void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b); void hex_to_rgb(char *hexcol, float *r, float *g, float *b); void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index b7f56e6ca1c..b10051b056a 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -3548,10 +3548,10 @@ float VecAngle3(float *v1, float *v2, float *v3) Normalize(vec1); Normalize(vec2); - return NormalizedVecAngle2(vec1, vec2) * (float)(180.0/M_PI); + return NormalizedVecAngle2(vec1, vec2); } -float VecAngle3_2D(float *v1, float *v2, float *v3) +float Vec2Angle3(float *v1, float *v2, float *v3) { float vec1[2], vec2[2]; @@ -3564,7 +3564,7 @@ float VecAngle3_2D(float *v1, float *v2, float *v3) Normalize2(vec1); Normalize2(vec2); - return NormalizedVecAngle2_2D(vec1, vec2) * (float)(180.0/M_PI); + return NormalizedVecAngle2_2D(vec1, vec2); } /* Return the shortest angle in degrees between the 2 vectors */ @@ -3577,7 +3577,7 @@ float VecAngle2(float *v1, float *v2) Normalize(vec1); Normalize(vec2); - return NormalizedVecAngle2(vec1, vec2)* (float)(180.0/M_PI); + return NormalizedVecAngle2(vec1, vec2); } float NormalizedVecAngle2(float *v1, float *v2) diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 1e416d9c31d..7f2f2a3410c 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1814,7 +1814,7 @@ int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch) VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p); VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p); - angle = VecAngle2(s1, s2); + angle = RAD2DEG(VecAngle2(s1, s2)); if (angle > 60 && angle < 120) { @@ -1932,7 +1932,7 @@ int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch) VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p); VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p); - angle = VecAngle2(s1, s2); + angle = RAD2DEG(VecAngle2(s1, s2)); if (angle > 120) { @@ -2064,7 +2064,7 @@ int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch) VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p); } - angle = VecAngle2(start_v, end_v); + angle = RAD2DEG(VecAngle2(start_v, end_v)); if (angle > 120) { diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index a6c94bee5b1..81e67c4d46e 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -176,9 +176,9 @@ static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3 t2= cotan_weight(v2, v3, v1); t3= cotan_weight(v3, v1, v2); - if(VecAngle3(v2, v1, v3) > 90) obtuse= 1; - else if(VecAngle3(v1, v2, v3) > 90) obtuse= 2; - else if(VecAngle3(v1, v3, v2) > 90) obtuse= 3; + if(RAD2DEG(VecAngle3(v2, v1, v3)) > 90) obtuse= 1; + else if(RAD2DEG(VecAngle3(v1, v2, v3)) > 90) obtuse= 2; + else if(RAD2DEG(VecAngle3(v1, v3, v2)) > 90) obtuse= 3; if (obtuse > 0) { area= AreaT3Dfl(v1, v2, v3); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 7301901aff5..09ea9088a16 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -761,7 +761,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode) float angle; for(efa= em->faces.first; efa; efa= efa->next) { if (!(efa->f & SELECT) && !efa->h) { - angle= VecAngle2(base_efa->n, efa->n); + angle= RAD2DEG(VecAngle2(base_efa->n, efa->n)); if (angle/180.0<=thresh) { EM_select_face(efa, 1); selcount++; @@ -776,7 +776,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode) base_dot= Inpf(base_efa->cent, base_efa->n); for(efa= em->faces.first; efa; efa= efa->next) { if (!(efa->f & SELECT) && !efa->h) { - angle= VecAngle2(base_efa->n, efa->n); + angle= RAD2DEG(VecAngle2(base_efa->n, efa->n)); if (angle/180.0<=thresh) { dot=Inpf(efa->cent, base_efa->n); if (fabs(base_dot-dot) <= thresh) { @@ -916,7 +916,7 @@ static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mod else if (eed->f2==0) /* first access, assign the face */ eed->tmp.f= efa; else if (eed->f2==1) /* second, we assign the angle*/ - eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180; + eed->tmp.fp= RAD2DEG(VecAngle2(eed->tmp.f->n, efa->n))/180; eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/ } j++; @@ -946,7 +946,7 @@ static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mod for(eed= em->edges.first; eed; eed= eed->next) { if (!(eed->f & SELECT) && !eed->h) { VecSubf(dir, eed->v1->co, eed->v2->co); - angle= VecAngle2(base_dir, dir); + angle= RAD2DEG(VecAngle2(base_dir, dir)); if (angle>90) /* use the smallest angle between the edges */ angle= fabs(angle-180.0f); @@ -1137,7 +1137,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) float angle; for(eve= em->verts.first; eve; eve= eve->next) { if (!(eve->f & SELECT) && !eve->h) { - angle= VecAngle2(base_eve->no, eve->no); + angle= RAD2DEG(VecAngle2(base_eve->no, eve->no)); if (angle/180.0<=thresh) { eve->f |= SELECT; selcount++; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 1d2b97b3f29..46b941f70df 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3121,13 +3121,13 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert CalcNormFloat(v1->co, v3->co, v4->co, noA2); if(noA1[0] == noA2[0] && noA1[1] == noA2[1] && noA1[2] == noA2[2]) normalADiff = 0.0; - else normalADiff = VecAngle2(noA1, noA2); + else normalADiff = RAD2DEG(VecAngle2(noA1, noA2)); //if(!normalADiff) normalADiff = 179; CalcNormFloat(v2->co, v3->co, v4->co, noB1); CalcNormFloat(v4->co, v1->co, v2->co, noB2); if(noB1[0] == noB2[0] && noB1[1] == noB2[1] && noB1[2] == noB2[2]) normalBDiff = 0.0; - else normalBDiff = VecAngle2(noB1, noB2); + else normalBDiff = RAD2DEG(VecAngle2(noB1, noB2)); //if(!normalBDiff) normalBDiff = 179; measure += (normalADiff/360) + (normalBDiff/360); @@ -3142,10 +3142,10 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert diff = 0.0; diff = ( - fabs(VecAngle2(edgeVec1, edgeVec2) - 90) + - fabs(VecAngle2(edgeVec2, edgeVec3) - 90) + - fabs(VecAngle2(edgeVec3, edgeVec4) - 90) + - fabs(VecAngle2(edgeVec4, edgeVec1) - 90)) / 360; + fabs(RAD2DEG(VecAngle2(edgeVec1, edgeVec2)) - 90) + + fabs(RAD2DEG(VecAngle2(edgeVec2, edgeVec3)) - 90) + + fabs(RAD2DEG(VecAngle2(edgeVec3, edgeVec4)) - 90) + + fabs(RAD2DEG(VecAngle2(edgeVec4, edgeVec1)) - 90)) / 360; if(!diff) return 0.0; measure += diff; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3212d5cee89..b8852486dea 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1991,29 +1991,29 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) { /* Vec 1 */ - sprintf(val,"%.3f", VecAngle3(v4, v1, v2)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2))); VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f); view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); } if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) { /* Vec 2 */ - sprintf(val,"%.3f", VecAngle3(v1, v2, v3)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3))); VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f); view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) { /* Vec 3 */ if(efa->v4) - sprintf(val,"%.3f", VecAngle3(v2, v3, v4)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v4))); else - sprintf(val,"%.3f", VecAngle3(v2, v3, v1)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1))); VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f); view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } /* Vec 4 */ if(efa->v4) { if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) { - sprintf(val,"%.3f", VecAngle3(v3, v4, v1)); + sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1))); VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f); view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index a58ee9772e9..fbd12007c16 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -251,17 +251,17 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac if(efa->v4) { #if 0 /* Simple but slow, better reuse normalized vectors */ - uvang1 = VecAngle3_2D(tf_uv[3], tf_uv[0], tf_uv[1]); - ang1 = VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co); + uvang1 = RAD2DEG(Vec2Angle3(tf_uv[3], tf_uv[0], tf_uv[1])); + ang1 = RAD2DEG(VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co)); - uvang2 = VecAngle3_2D(tf_uv[0], tf_uv[1], tf_uv[2]); - ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co); + uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2])); + ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co)); - uvang3 = VecAngle3_2D(tf_uv[1], tf_uv[2], tf_uv[3]); - ang3 = VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co); + uvang3 = RAD2DEG(Vec2Angle3(tf_uv[1], tf_uv[2], tf_uv[3])); + ang3 = RAD2DEG(VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co)); - uvang4 = VecAngle3_2D(tf_uv[2], tf_uv[3], tf_uv[0]); - ang4 = VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co); + uvang4 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[3], tf_uv[0])); + ang4 = RAD2DEG(VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co)); #endif /* uv angles */ @@ -315,14 +315,14 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac } else { #if 0 /* Simple but slow, better reuse normalized vectors */ - uvang1 = VecAngle3_2D(tf_uv[2], tf_uv[0], tf_uv[1]); - ang1 = VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co); + uvang1 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[0], tf_uv[1])); + ang1 = RAD2DEG(VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co)); - uvang2 = VecAngle3_2D(tf_uv[0], tf_uv[1], tf_uv[2]); - ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co); + uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2])); + ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co)); - uvang3 = 180-(uvang1+uvang2); - ang3 = 180-(ang1+ang2); + uvang3 = M_PI-(uvang1+uvang2); + ang3 = M_PI-(ang1+ang2); #endif /* uv angles */ -- cgit v1.2.3 From 9435727712e39d728b83de9c4709679c32006405 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 18 Sep 2009 15:48:49 +0000 Subject: Handlers/keymaps, some tweaks for previous commits: * Screen keymap is now split up in two, some of the area/region manipulation operators here need to be handled before others. * Moved paint/sculpt/sketch out of the 3d view keymap, these were there as a workaround, now with keymap poll no longer needed. * Also fixes #19297, 3d cursor moves when combing in particle mode. --- source/blender/editors/armature/armature_ops.c | 9 +++++ source/blender/editors/include/ED_sculpt.h | 2 +- source/blender/editors/screen/screen_ops.c | 18 +++++---- source/blender/editors/sculpt_paint/paint_image.c | 5 +++ source/blender/editors/sculpt_paint/paint_intern.h | 7 +++- source/blender/editors/sculpt_paint/paint_ops.c | 46 ++++++++++++++++++++++ source/blender/editors/sculpt_paint/paint_vertex.c | 20 +++++----- source/blender/editors/sculpt_paint/sculpt.c | 2 +- .../blender/editors/sculpt_paint/sculpt_intern.h | 3 ++ source/blender/editors/space_api/spacetypes.c | 1 + source/blender/editors/space_image/space_image.c | 2 +- source/blender/editors/space_view3d/space_view3d.c | 28 ++++++++----- source/blender/editors/space_view3d/view3d_edit.c | 3 +- source/blender/editors/space_view3d/view3d_ops.c | 32 --------------- source/blender/makesdna/DNA_windowmanager_types.h | 2 +- .../blender/windowmanager/intern/wm_event_system.c | 2 +- source/blender/windowmanager/intern/wm_window.c | 3 ++ 17 files changed, 118 insertions(+), 67 deletions(-) diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 4a61c8ddaf8..9076b533974 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -279,6 +279,15 @@ void ED_keymap_armature(wmWindowManager *wm) WM_keymap_add_item(keymap, "SKETCH_OT_cancel_stroke", ESCKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "SKETCH_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + /* sketch poll checks mode */ + WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "snap", 1); + WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0); + kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "snap", 1); + /* Pose ------------------------ */ /* only set in posemode, by space_view3d listener */ keymap= WM_keymap_find(wm, "Pose", 0, 0); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index c6a8881a0c6..a08f0576f42 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -33,10 +33,10 @@ struct wmWindowManager; /* sculpt.c */ void ED_operatortypes_sculpt(void); -void ED_keymap_sculpt(struct wmWindowManager *wm); /* paint_ops.c */ void ED_operatortypes_paint(void); +void ED_keymap_paint(struct wmWindowManager *wm); /* paint_image.c */ void undo_imagepaint_step(int step); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6107d412323..b7e7fd18547 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3293,17 +3293,13 @@ void ED_keymap_screen(wmWindowManager *wm) { wmKeyMap *keymap; - /* Screen General ------------------------------------------------ */ - keymap= WM_keymap_find(wm, "Screen", 0, 0); - - - /* standard timers */ - WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0); + /* Screen Editing ------------------------------------------------ */ + keymap= WM_keymap_find(wm, "Screen Editing", 0, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "modifier", 2); - + /* screen tools */ WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE_AREA, 0, 0, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE_AREA, 0, 0, 0); @@ -3312,6 +3308,14 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_verify_item(keymap, "SCREEN_OT_region_scale", EVT_ACTIONZONE_REGION, 0, 0, 0); /* area move after action zones */ WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0); + + + /* Screen General ------------------------------------------------ */ + keymap= WM_keymap_find(wm, "Screen", 0, 0); + + /* standard timers */ + WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0); + RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index d3cd49a2658..b42566732ec 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5240,6 +5240,11 @@ static int texture_paint_poll(bContext *C) return 0; } +int image_texture_paint_poll(bContext *C) +{ + return (texture_paint_poll(C) || image_paint_poll(C)); +} + void PAINT_OT_texture_paint_radial_control(wmOperatorType *ot) { WM_OT_radial_control_partial(ot); diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index ba1b57a1bef..8251d1a5a1a 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -57,7 +57,10 @@ int paint_poll(bContext *C); void paint_cursor_start(struct bContext *C, int (*poll)(struct bContext *C)); /* paint_vertex.c */ -int vertex_paint_mode_poll(bContext *C); +int weight_paint_poll(struct bContext *C); +int vertex_paint_poll(struct bContext *C); +int vertex_paint_mode_poll(struct bContext *C); + void clear_vpaint(Scene *scene, int selected); void PAINT_OT_weight_paint_toggle(struct wmOperatorType *ot); @@ -69,6 +72,8 @@ void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot); void PAINT_OT_vertex_paint(struct wmOperatorType *ot); /* paint_image.c */ +int image_texture_paint_poll(struct bContext *C); + void PAINT_OT_image_paint(struct wmOperatorType *ot); void PAINT_OT_image_paint_radial_control(struct wmOperatorType *ot); void PAINT_OT_grab_clone(struct wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 19b46f5a941..514c80d929d 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -38,6 +38,7 @@ #include "RNA_enum_types.h" #include "paint_intern.h" +#include "sculpt_intern.h" #include @@ -133,3 +134,48 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_vertex_color_set); } +void ED_keymap_paint(wmWindowManager *wm) +{ + wmKeyMap *keymap; + + /* Sculpt mode */ + keymap= WM_keymap_find(wm, "Sculpt", 0, 0); + keymap->poll= sculpt_poll; + + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE); + + WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + + /* Vertex Paint mode */ + keymap= WM_keymap_find(wm, "Vertex Paint", 0, 0); + keymap->poll= vertex_paint_poll; + + RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); + + /* Weight Paint mode */ + keymap= WM_keymap_find(wm, "Weight Paint", 0, 0); + keymap->poll= weight_paint_poll; + + RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + + WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0); + + /* Image/Texture Paint mode */ + keymap= WM_keymap_find(wm, "Image Paint", 0, 0); + keymap->poll= image_texture_paint_poll; + + RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + + WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); +} + diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 17fd1d4fa4a..5afc4954c9c 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -119,7 +119,7 @@ int vertex_paint_mode_poll(bContext *C) return ob && ob->mode == OB_MODE_VERTEX_PAINT; } -static int vp_poll(bContext *C) +int vertex_paint_poll(bContext *C) { if(vertex_paint_mode_poll(C) && paint_brush(&CTX_data_tool_settings(C)->vpaint->paint)) { @@ -133,7 +133,7 @@ static int vp_poll(bContext *C) return 0; } -static int wp_poll(bContext *C) +int weight_paint_poll(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -1060,7 +1060,7 @@ static int set_wpaint(bContext *C, wmOperator *op) /* toggle */ wp= scene->toolsettings->wpaint= new_vpaint(1); paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT); - paint_cursor_start(C, wp_poll); + paint_cursor_start(C, weight_paint_poll); mesh_octree_table(ob, NULL, NULL, 's'); @@ -1129,7 +1129,7 @@ static int vpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve { int ret = WM_radial_control_modal(C, op, event); if(ret != OPERATOR_RUNNING_MODAL) - paint_cursor_start(C, vp_poll); + paint_cursor_start(C, vertex_paint_poll); return ret; } @@ -1158,7 +1158,7 @@ static int wpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve { int ret = WM_radial_control_modal(C, op, event); if(ret != OPERATOR_RUNNING_MODAL) - paint_cursor_start(C, wp_poll); + paint_cursor_start(C, weight_paint_poll); return ret; } @@ -1182,7 +1182,7 @@ void PAINT_OT_weight_paint_radial_control(wmOperatorType *ot) ot->invoke= wpaint_radial_control_invoke; ot->modal= wpaint_radial_control_modal; ot->exec= wpaint_radial_control_exec; - ot->poll= wp_poll; + ot->poll= weight_paint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; @@ -1198,7 +1198,7 @@ void PAINT_OT_vertex_paint_radial_control(wmOperatorType *ot) ot->invoke= vpaint_radial_control_invoke; ot->modal= vpaint_radial_control_modal; ot->exec= vpaint_radial_control_exec; - ot->poll= vp_poll; + ot->poll= vertex_paint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; @@ -1520,7 +1520,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot) ot->invoke= wpaint_invoke; ot->modal= paint_stroke_modal; /* ot->exec= vpaint_exec; <-- needs stroke property */ - ot->poll= wp_poll; + ot->poll= weight_paint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; @@ -1567,7 +1567,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ if(vp==NULL) vp= scene->toolsettings->vpaint= new_vpaint(0); - paint_cursor_start(C, vp_poll); + paint_cursor_start(C, vertex_paint_poll); paint_init(&vp->paint, PAINT_CURSOR_VERTEX_PAINT); } @@ -1792,7 +1792,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot) ot->invoke= vpaint_invoke; ot->modal= paint_stroke_modal; /* ot->exec= vpaint_exec; <-- needs stroke property */ - ot->poll= vp_poll; + ot->poll= vertex_paint_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 89cd0555ff9..64af39ea497 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1039,7 +1039,7 @@ static int sculpt_mode_poll(bContext *C) return ob && ob->mode & OB_MODE_SCULPT; } -static int sculpt_poll(bContext *C) +int sculpt_poll(bContext *C) { return sculpt_mode_poll(C) && paint_poll(C); } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 25f97b862e6..15ccacc294a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -33,6 +33,7 @@ #include "DNA_listBase.h" #include "DNA_vec_types.h" +struct bContext; struct Brush; struct Mesh; struct Object; @@ -53,6 +54,8 @@ struct Brush *sculptmode_brush(void); char sculpt_modifiers_active(struct Object *ob); void sculpt(Sculpt *sd); +int sculpt_poll(struct bContext *C); + /* Stroke */ struct SculptStroke *sculpt_stroke_new(const int max); void sculpt_stroke_free(struct SculptStroke *); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index edd5da44526..18bc7ec9555 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -129,6 +129,7 @@ void ED_spacetypes_keymap(wmWindowManager *wm) ED_keymap_armature(wm); ED_keymap_particle(wm); ED_keymap_metaball(wm); + ED_keymap_paint(wm); ED_marker_keymap(wm); UI_view2d_keymap(wm); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index e325a820e92..f222499ba86 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -404,7 +404,7 @@ static void image_main_area_init(wmWindowManager *wm, ARegion *ar) // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* image paint polls for mode */ - keymap= WM_keymap_find(wm, "ImagePaint", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm, "Image Paint", SPACE_IMAGE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); keymap= WM_keymap_find(wm, "UVEdit", 0, 0); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 12c2b272258..5ea633a47f7 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -279,14 +279,7 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) { wmKeyMap *keymap; - - /* own keymap */ - keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); - /* object ops. */ keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -295,11 +288,19 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - /* operator poll checks for modes */ - keymap= WM_keymap_find(wm, "ImagePaint", 0, 0); + keymap= WM_keymap_find(wm, "Object Mode", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Object Mode", 0, 0); + keymap= WM_keymap_find(wm, "Image Paint", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Vertex Paint", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Weight Paint", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "Sculpt", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); keymap= WM_keymap_find(wm, "EditMesh", 0, 0); @@ -330,6 +331,13 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) /* editfont keymap swallows all... */ keymap= WM_keymap_find(wm, "Font", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* own keymap, last so modes can override it */ + keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); } /* type callback, not region itself */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index d28789491dd..0faa1f8c16d 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1850,8 +1850,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event) // XXX notifier for scene */ ED_area_tag_redraw(CTX_wm_area(C)); - /* prevent other mouse ops to fail */ - return OPERATOR_PASS_THROUGH; + return OPERATOR_FINISHED; } void VIEW3D_OT_cursor3d(wmOperatorType *ot) diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 9ffdef478b3..3569e2a79e3 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -114,26 +114,6 @@ void view3d_keymap(wmWindowManager *wm) /* only for region 3D window */ keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); - /* paint poll checks mode */ - WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0); - - WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); - - WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); - - /* sketch poll checks mode */ - WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0); - km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_boolean_set(km->ptr, "snap", 1); - WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0); - km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0); - RNA_boolean_set(km->ptr, "snap", 1); - WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/ WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); @@ -234,18 +214,6 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0); - - /* radial control */ - RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE); - - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); transform_keymap_for_space(wm, keymap, SPACE_VIEW3D); diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index ee2b0ab848f..f1ce3491d0a 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -163,7 +163,7 @@ typedef struct wmWindow { ListBase queue; /* all events (ghost level events were handled) */ ListBase handlers; /* window+screen handlers, handled last */ - ListBase modalhandlers; /* modal handlers, overriding all queues */ + ListBase modalhandlers; /* priority handlers, handled first */ ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ ListBase gesture; /* gesture stuff */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e570a733d89..40026d27bac 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1165,7 +1165,7 @@ void wm_event_do_handlers(bContext *C) /* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */ wm_window_make_drawable(C, win); - /* first we do modal handlers */ + /* first we do priority handlers, modal + some limited keymaps */ action= wm_handlers_do(C, event, &win->modalhandlers); /* fileread case */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 2eee11c6820..9d3d0a9535e 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -373,6 +373,9 @@ void wm_window_add_ghostwindows(wmWindowManager *wm) keymap= WM_keymap_find(wm, "Screen", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); + + keymap= WM_keymap_find(wm, "Screen Editing", 0, 0); + WM_event_add_keymap_handler(&win->modalhandlers, keymap); wm_window_title(wm, win); } -- cgit v1.2.3 From 9787a2e55aecef7cad850b7e3bccf62af7220a21 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 18 Sep 2009 15:52:28 +0000 Subject: UI: fix some python errors in sculpt/paint modes when there is no brush. --- release/ui/space_image.py | 33 ++++++++++++++++++--------------- release/ui/space_view3d_toolbar.py | 8 ++++---- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/release/ui/space_image.py b/release/ui/space_image.py index 50ccda34c6a..b14bec0e40e 100644 --- a/release/ui/space_image.py +++ b/release/ui/space_image.py @@ -419,22 +419,23 @@ class IMAGE_PT_paint(bpy.types.Panel): row.item_enumR(settings, "tool", 'CLONE') row.item_enumR(settings, "tool", 'SMEAR') - col = layout.column() - col.itemR(brush, "color", text="") + if brush: + col = layout.column() + col.itemR(brush, "color", text="") - row = col.row(align=True) - row.itemR(brush, "size", slider=True) - row.itemR(brush, "use_size_pressure", toggle=True, text="") - - row = col.row(align=True) - row.itemR(brush, "strength", slider=True) - row.itemR(brush, "use_strength_pressure", toggle=True, text="") + row = col.row(align=True) + row.itemR(brush, "size", slider=True) + row.itemR(brush, "use_size_pressure", toggle=True, text="") + + row = col.row(align=True) + row.itemR(brush, "strength", slider=True) + row.itemR(brush, "use_strength_pressure", toggle=True, text="") - row = col.row(align=True) - row.itemR(brush, "jitter", slider=True) - row.itemR(brush, "use_jitter_pressure", toggle=True, text="") + row = col.row(align=True) + row.itemR(brush, "jitter", slider=True) + row.itemR(brush, "use_jitter_pressure", toggle=True, text="") - col.itemR(brush, "blend", text="Blend") + col.itemR(brush, "blend", text="Blend") class IMAGE_PT_paint_stroke(bpy.types.Panel): __space_type__ = 'IMAGE_EDITOR' @@ -444,7 +445,8 @@ class IMAGE_PT_paint_stroke(bpy.types.Panel): def poll(self, context): sima = context.space_data - return sima.show_paint + settings = context.tool_settings.image_paint + return sima.show_paint and settings.brush def draw(self, context): layout = self.layout @@ -471,7 +473,8 @@ class IMAGE_PT_paint_curve(bpy.types.Panel): def poll(self, context): sima = context.space_data - return sima.show_paint + settings = context.tool_settings.image_paint + return sima.show_paint and settings.brush def draw(self, context): layout = self.layout diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 6f17ad925cf..9492437b863 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -379,7 +379,7 @@ class VIEW3D_PT_tools_brush(PaintPanel): # Sculpt Mode # - elif context.sculpt_object and settings.brush: + elif context.sculpt_object and brush: col = layout.column() col.itemS() col.itemR(brush, "sculpt_tool", expand=True) @@ -412,7 +412,7 @@ class VIEW3D_PT_tools_brush(PaintPanel): # Texture Paint Mode # - elif context.texture_paint_object: + elif context.texture_paint_object and brush: col = layout.column(align=True) col.item_enumR(settings, "tool", 'DRAW') col.item_enumR(settings, "tool", 'SOFTEN') @@ -438,7 +438,7 @@ class VIEW3D_PT_tools_brush(PaintPanel): # Weight Paint Mode # - elif context.weight_paint_object: + elif context.weight_paint_object and brush: layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight", slider=True) col = layout.column() @@ -456,7 +456,7 @@ class VIEW3D_PT_tools_brush(PaintPanel): # Vertex Paint Mode # - elif context.vertex_paint_object: + elif context.vertex_paint_object and brush: col = layout.column() col.itemR(brush, "color", text="") -- cgit v1.2.3 From c388244be4eac3535e785516d0a8c4b5b5d22643 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2009 16:39:45 +0000 Subject: Move some static math functions out of paint_image.c into arithb.c * VecLerp3f and Vec2Lerp3f - interpolate 3 2d/3d vectors from 3 weights * AngleToLength(angle) - useful for making even width shell/walls based on the angles of the surrounding geometry from each point. (same method used in 2.4x python solidify script). also quiet some warnings. --- source/blender/blenkernel/intern/particle.c | 4 +- source/blender/blenkernel/intern/particle_system.c | 10 +-- source/blender/blenlib/BLI_arithb.h | 8 ++- source/blender/blenlib/intern/arithb.c | 34 +++++++-- source/blender/editors/sculpt_paint/paint_image.c | 80 ++++++++-------------- source/blender/makesrna/intern/rna_particle.c | 2 +- .../blender/render/intern/source/convertblender.c | 2 +- 7 files changed, 72 insertions(+), 68 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 0dc041bfc6a..e18e7f54e49 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2193,7 +2193,7 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate) { ParticleThreadContext *ctx= threads[0].ctx; - Object *ob= ctx->sim.ob; +/* Object *ob= ctx->sim.ob; */ ParticleSystem *psys= ctx->sim.psys; ParticleSettings *part = psys->part; ParticleEditSettings *pset = &scene->toolsettings->particle; @@ -3868,7 +3868,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta ParticleData *pa = NULL; ChildParticle *cpa = NULL; float cfra; - int totpart = psys->totpart, between = 0; + int totpart = psys->totpart; /* negative time means "use current time" */ cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 9cd897e4bcd..1b6d56e6459 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -614,7 +614,7 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData Object *ob= ctx->sim.ob; DerivedMesh *dm= ctx->dm; ParticleData *tpa; - ParticleSettings *part= ctx->sim.psys->part; +/* ParticleSettings *part= ctx->sim.psys->part; */ float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3]; float cur_d, min_d, randu, randv; int from= ctx->from; @@ -2451,7 +2451,7 @@ void psys_end_effectors(ParticleSystem *psys) } /* precalcs effectors and returns 1 if there were any collision object -/* so collision checks can be avoided as quickly as possible */ + * so collision checks can be avoided as quickly as possible */ static int precalc_effectors(ParticleSimulationData *sim, float cfra) { ParticleSystem *psys = sim->psys; @@ -3561,7 +3561,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) static void hair_step(ParticleSimulationData *sim, float cfra) { ParticleSystem *psys = sim->psys; - ParticleSettings *part = psys->part; +/* ParticleSettings *part = psys->part; */ PARTICLE_P; float disp = (float)get_current_display_percentage(psys)/100.0f; @@ -3649,7 +3649,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) ParticleSettings *part=psys->part; KDTree *tree=0; IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system - Material *ma=give_current_material(sim->ob, part->omat); +/* Material *ma=give_current_material(sim->ob, part->omat); */ BoidBrainData bbd; PARTICLE_P; float timestep; @@ -3851,7 +3851,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra) ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system - Material *ma = give_current_material(sim->ob,part->omat); +/* Material *ma = give_current_material(sim->ob,part->omat); */ PARTICLE_P; float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 623a9afeb73..793dab12b83 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -364,7 +364,8 @@ void printvec4f(char *str, float v[4]); void VecAddf(float *v, float *v1, float *v2); void VecSubf(float *v, float *v1, float *v2); void VecMulVecf(float *v, float *v1, float *v2); -void VecLerpf(float *target, float *a, float *b, float t); +void VecLerpf(float *target, const float *a, const float *b, const float t); +void VecLerp3f(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]); void VecMidf(float *v, float *v1, float *v2); void VecOrthoBasisf(float *v, float *v1, float *v2); @@ -375,7 +376,8 @@ void Vec2Mulf(float *v1, float f); void Vec2Addf(float *v, float *v1, float *v2); void Vec2Subf(float *v, float *v1, float *v2); void Vec2Copyf(float *v1, float *v2); -void Vec2Lerpf(float *target, float *a, float *b, float t); +void Vec2Lerpf(float *target, const float *a, const float *b, const float t); +void Vec2Lerp3f(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]); void AxisAngleToQuat(float q[4], float axis[3], float angle); void QuatToAxisAngle(float q[4], float axis[3], float *angle); @@ -527,6 +529,8 @@ int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]); float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]); +float AngleToLength(const float angle); + typedef struct DualQuat { float quat[4]; float trans[4]; diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index b10051b056a..ac79894d827 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2187,23 +2187,40 @@ void VecMulVecf(float *v, float *v1, float *v2) v[2] = v1[2] * v2[2]; } -void VecLerpf(float *target, float *a, float *b, float t) +void VecLerpf(float *target, const float *a, const float *b, const float t) { - float s = 1.0f-t; + const float s = 1.0f-t; target[0]= s*a[0] + t*b[0]; target[1]= s*a[1] + t*b[1]; target[2]= s*a[2] + t*b[2]; } -void Vec2Lerpf(float *target, float *a, float *b, float t) +void Vec2Lerpf(float *target, const float *a, const float *b, const float t) { - float s = 1.0f-t; + const float s = 1.0f-t; target[0]= s*a[0] + t*b[0]; target[1]= s*a[1] + t*b[1]; } +/* weight 3 vectors, (VecWeightf in 2.4x) + * 'w' must be unit length but is not a vector, just 3 weights */ +void VecLerp3f(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; + p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; +} + +/* weight 3 2D vectors, (Vec2Weightf in 2.4x) + * 'w' must be unit length but is not a vector, just 3 weights */ +void Vec2Lerp3f(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; +} + void VecMidf(float *v, float *v1, float *v2) { v[0]= 0.5f*(v1[0]+ v2[0]); @@ -4823,6 +4840,15 @@ static float lambda_cp_line(float p[3], float l1[3], float l2[3]) } #endif +/* useful to calculate an even width shell, by taking the angle between 2 planes. + * The return value is a scale on the offset. + * no angle between planes is 1.0, as the angle between the 2 planes approches 180d + * the distance gets very hight, 180d would be inf, but this case isnt valid */ +float AngleToLength(const float angle) +{ + return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle * (M_PI/180.0f))); +} + /* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */ void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv) { diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index b42566732ec..91ee2fa55d1 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -625,19 +625,6 @@ static void BarycentricWeightsPersp2f(float pt[2], float v1[4], float v2[4], flo w[0] = w[1] = w[2] = 1.0f/3.0f; } -static void VecWeightf(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]) -{ - p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; - p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; - p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; -} - -static void Vec2Weightf(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]) -{ - p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; - p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; -} - static float VecZDepthOrtho(float pt[2], float v1[3], float v2[3], float v3[3], float w[3]) { BarycentricWeights2f(pt, v1, v2, v3, w); @@ -746,10 +733,10 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float tf = ps->dm_mtface + face_index; if (side == 0) { - Vec2Weightf(uv, tf->uv[0], tf->uv[1], tf->uv[2], w); + Vec2Lerp3f(uv, tf->uv[0], tf->uv[1], tf->uv[2], w); } else { /* QUAD */ - Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w); + Vec2Lerp3f(uv, tf->uv[0], tf->uv[2], tf->uv[3], w); } ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */ @@ -870,8 +857,8 @@ static int project_paint_occlude_ptv_clip( } /* Test if we're in the clipped area, */ - if (side) VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w); - else VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w); + if (side) VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w); + else VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w); Mat4MulVecfl(ps->ob->obmat, wco); if(!view3d_test_clipping(ps->rv3d, wco)) { @@ -1146,19 +1133,6 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o return 1; } -/* TODO - move to arithb.c */ -/* Converts an angle to a length that can be used for maintaining an even margin around UV's */ -static float angleToLength(float angle) -{ - // already accounted for - if (angle < 0.000001f) { - return 1.0f; - } - else { - return fabsf(1.0f / cosf(angle * (M_PI/180.0f))); - } -} - /* Calculate outset UV's, this is not the same as simply scaling the UVs, * since the outset coords are a margin that keep an even distance from the original UV's, * note that the image aspect is taken into account */ @@ -1204,15 +1178,15 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl } if (is_quad) { - a1 = angleToLength(NormalizedVecAngle2_2D(dir4, dir1)); - a2 = angleToLength(NormalizedVecAngle2_2D(dir1, dir2)); - a3 = angleToLength(NormalizedVecAngle2_2D(dir2, dir3)); - a4 = angleToLength(NormalizedVecAngle2_2D(dir3, dir4)); + a1 = AngleToLength(NormalizedVecAngle2_2D(dir4, dir1)); + a2 = AngleToLength(NormalizedVecAngle2_2D(dir1, dir2)); + a3 = AngleToLength(NormalizedVecAngle2_2D(dir2, dir3)); + a4 = AngleToLength(NormalizedVecAngle2_2D(dir3, dir4)); } else { - a1 = angleToLength(NormalizedVecAngle2_2D(dir3, dir1)); - a2 = angleToLength(NormalizedVecAngle2_2D(dir1, dir2)); - a3 = angleToLength(NormalizedVecAngle2_2D(dir2, dir3)); + a1 = AngleToLength(NormalizedVecAngle2_2D(dir3, dir1)); + a2 = AngleToLength(NormalizedVecAngle2_2D(dir1, dir2)); + a3 = AngleToLength(NormalizedVecAngle2_2D(dir2, dir3)); } if (is_quad) { @@ -1329,7 +1303,7 @@ static void screen_px_from_ortho( float w[3]) { BarycentricWeights2f(uv, uv1co, uv2co, uv3co, w); - VecWeightf(pixelScreenCo, v1co, v2co, v3co, w); + VecLerp3f(pixelScreenCo, v1co, v2co, v3co, w); } /* same as screen_px_from_ortho except we need to take into account @@ -1363,7 +1337,7 @@ static void screen_px_from_persp( } /* done re-weighting */ - VecWeightf(pixelScreenCo, v1co, v2co, v3co, w); + VecLerp3f(pixelScreenCo, v1co, v2co, v3co, w); } static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3], int side, unsigned char rgba_ub[4], float rgba_f[4]) @@ -1381,7 +1355,7 @@ static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const uvCo3 = (float *)tf_other->uv[2]; } - Vec2Weightf(uv_other, uvCo1, uvCo2, uvCo3, w); + Vec2Lerp3f(uv_other, uvCo1, uvCo2, uvCo3, w); /* use */ uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y); @@ -1916,22 +1890,22 @@ static void rect_to_uvspace_ortho( uv[0] = bucket_bounds->xmax; uv[1] = bucket_bounds->ymin; BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w); //uv[0] = bucket_bounds->xmax; // set above uv[1] = bucket_bounds->ymax; BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w); uv[0] = bucket_bounds->xmin; //uv[1] = bucket_bounds->ymax; // set above BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w); //uv[0] = bucket_bounds->xmin; // set above uv[1] = bucket_bounds->ymin; BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w); } /* same as above but use BarycentricWeightsPersp2f */ @@ -1950,22 +1924,22 @@ static void rect_to_uvspace_persp( uv[0] = bucket_bounds->xmax; uv[1] = bucket_bounds->ymin; BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w); //uv[0] = bucket_bounds->xmax; // set above uv[1] = bucket_bounds->ymax; BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w); uv[0] = bucket_bounds->xmin; //uv[1] = bucket_bounds->ymax; // set above BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?1:2], uv1co, uv2co, uv3co, w); //uv[0] = bucket_bounds->xmin; // set above uv[1] = bucket_bounds->ymin; BarycentricWeightsPersp2f(uv, v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[flip?0:3], uv1co, uv2co, uv3co, w); } /* This works as we need it to but we can save a few steps and not use it */ @@ -2209,13 +2183,13 @@ static void project_bucket_clip_face( if (is_ortho) { for(i=0; i<(*tot); i++) { BarycentricWeights2f(isectVCosSS[i], v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w); } } else { for(i=0; i<(*tot); i++) { BarycentricWeightsPersp2f(isectVCosSS[i], v1coSS, v2coSS, v3coSS, w); - Vec2Weightf(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w); + Vec2Lerp3f(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w); } } } @@ -2470,7 +2444,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* a pitty we need to get the worldspace pixel location here */ if(ps->rv3d->rflag & RV3D_CLIPPING) { - VecWeightf(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w); + VecLerp3f(wco, ps->dm_mvert[ (*(&mf->v1 + i1)) ].co, ps->dm_mvert[ (*(&mf->v1 + i2)) ].co, ps->dm_mvert[ (*(&mf->v1 + i3)) ].co, w); Mat4MulVecfl(ps->ob->obmat, wco); if(view3d_test_clipping(ps->rv3d, wco)) { continue; /* Watch out that no code below this needs to run */ @@ -2686,8 +2660,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* a pitty we need to get the worldspace pixel location here */ if(ps->rv3d->rflag & RV3D_CLIPPING) { - if (side) VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w); - else VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w); + if (side) VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w); + else VecLerp3f(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w); Mat4MulVecfl(ps->ob->obmat, wco); if(view3d_test_clipping(ps->rv3d, wco)) { diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 5821d30bc3b..04b4b1142be 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -507,7 +507,7 @@ EnumPropertyItem reactor_from_items[] = { static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, int *free) { - ParticleSettings *part = ptr->id.data; + /* ParticleSettings *part = ptr->id.data; */ if(C==NULL) { EnumPropertyItem *item= NULL; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 0c56841b70d..48a7c003c9f 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1474,7 +1474,7 @@ static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset) { Object *ob= obr->ob; - Object *tob=0; +// Object *tob=0; Material *ma=0; ParticleSystemModifierData *psmd; ParticleSystem *tpsys=0; -- cgit v1.2.3 From 6114de09b5b611478758698eab054576496d6b02 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 18 Sep 2009 21:04:54 +0000 Subject: 2.5 Nodes: More Nodes are wrapped to the layout engine. +a bit code cleanup. Brecht: please check on greying out, it doesn't look correct. :) --- source/blender/editors/space_node/drawnode.c | 364 ++++++++------------------ source/blender/makesrna/intern/rna_nodetree.c | 23 +- 2 files changed, 120 insertions(+), 267 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index a9f53c9efd9..8bd8477fe13 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -22,7 +22,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb + * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Bob Holcomb, Thomas Dinges * * ***** END GPL LICENSE BLOCK ***** */ @@ -1163,268 +1163,139 @@ static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_dblur(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeDBlurData *ndbd = node->storage; - short dy = butr->ymin + 171; - short dx = butr->xmax - butr->xmin; - short halfdx= (short)dx/2; - - uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:", - butr->xmin, dy, dx, 19, - &ndbd->iter, 1, 32, 10, 0, "Amount of iterations"); - uiDefButC(block, TOG, B_NODE_EXEC, "Wrap", - butr->xmin, dy-= 19, dx, 19, - &ndbd->wrap, 0, 0, 0, 0, "Wrap blur"); - uiBlockEndAlign(block); - - dy-= 9; - - uiDefBut(block, LABEL, B_NOP, "Center", butr->xmin, dy-= 19, dx, 19, NULL, 0.0f, 0.0f, 0, 0, ""); - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "X:", - butr->xmin, dy-= 19, halfdx, 19, - &ndbd->center_x, 0.0f, 1.0f, 10, 0, "X center in percents"); - uiDefButF(block, NUM, B_NODE_EXEC, "Y:", - butr->xmin+halfdx, dy, halfdx, 19, - &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents"); - uiBlockEndAlign(block); - - dy-= 9; - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Distance:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->distance, -1.0f, 1.0f, 10, 0, "Amount of which the image moves"); - uiDefButF(block, NUM, B_NODE_EXEC, "Angle:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->angle, 0.0f, 360.0f, 1000, 0, "Angle in which the image will be moved"); - uiBlockEndAlign(block); - - dy-= 9; - - uiDefButF(block, NUM, B_NODE_EXEC, "Spin:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image"); - - dy-= 9; - - uiDefButF(block, NUM, B_NODE_EXEC, "Zoom:", - butr->xmin, dy-= 19, dx, 19, - &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed"); + uiLayout *row, *col; + + uiItemR(layout, NULL, 0, ptr, "iterations", 0); + uiItemR(layout, NULL, 0, ptr, "wrap", 0); + + col= uiLayoutColumn(layout, 1); + uiItemL(col, "Center:", 0); + + row= uiLayoutRow(col, 1); + uiItemR(row, "X:", 0, ptr, "center_x", 0); + uiItemR(row, "Y", 0, ptr, "center_y", 0); + + uiItemS(layout); + + col= uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "distance", 0); + uiItemR(col, NULL, 0, ptr, "angle", 0); + + uiItemS(layout); + + uiItemR(layout, NULL, 0, ptr, "spin", 0); + uiItemR(layout, NULL, 0, ptr, "zoom", 0); } static void node_composit_buts_bilateralblur(uiLayout *layout, PointerRNA *ptr) -{ - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeBilateralBlurData *nbbd= node->storage; - short dy= butr->ymin+38; - short dx= (butr->xmax-butr->xmin); +{ + uiLayout *col; - uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_NODE_EXEC, "Iterations:", - butr->xmin, dy, dx, 19, - &nbbd->iter, 1, 128, 0, 0, "Amount of iterations"); - dy-=19; - uiDefButF(block, NUM, B_NODE_EXEC, "Color Sigma:", - butr->xmin, dy, dx, 19, - &nbbd->sigma_color,0.01, 3, 10, 0, "Sigma value used to modify color"); - dy-=19; - uiDefButF(block, NUM, B_NODE_EXEC, "Space Sigma:", - butr->xmin, dy, dx, 19, - &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space"); + col= uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "iterations", 0); + uiItemR(col, NULL, 0, ptr, "sigma_color", 0); + uiItemR(col, NULL, 0, ptr, "sigma_space", 0); } /* qdn: defocus node */ static void node_composit_buts_defocus(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeDefocus *nqd = node->storage; - short dy = butr->ymin + 209; - short dx = butr->xmax - butr->xmin; - char* mstr1 = "Bokeh Type%t|Octagon %x8|Heptagon %x7|Hexagon %x6|Pentagon %x5|Square %x4|Triangle %x3|Disk %x0"; - - uiDefBut(block, LABEL, B_NOP, "Bokeh Type", butr->xmin, dy, dx, 19, NULL, 0, 0, 0, 0, ""); - uiDefButC(block, MENU, B_NODE_EXEC, mstr1, - butr->xmin, dy-19, dx, 19, - &nqd->bktype, 0, 0, 0, 0, "Bokeh type"); - if (nqd->bktype) { /* for some reason rotating a disk doesn't seem to work... ;) */ - uiDefButC(block, NUM, B_NODE_EXEC, "Rotate:", - butr->xmin, dy-38, dx, 19, - &nqd->rotation, 0, 90, 0, 0, "Bokeh shape rotation offset in degrees"); - } - uiDefButC(block, TOG, B_NODE_EXEC, "Gamma Correct", - butr->xmin, dy-57, dx, 19, - &nqd->gamco, 0, 0, 0, 0, "Enable gamma correction before and after main process"); - if (nqd->no_zbuf==0) { - // only needed for zbuffer input - uiDefButF(block, NUM, B_NODE_EXEC, "fStop:", - butr->xmin, dy-76, dx, 19, - &nqd->fstop, 0.5, 128, 10, 0, "Amount of focal blur, 128=infinity=perfect focus, half the value doubles the blur radius"); - } - uiDefButF(block, NUM, B_NODE_EXEC, "Maxblur:", - butr->xmin, dy-95, dx, 19, - &nqd->maxblur, 0, 10000, 1000, 0, "blur limit, maximum CoC radius, 0=no limit"); - uiDefButF(block, NUM, B_NODE_EXEC, "BThreshold:", - butr->xmin, dy-114, dx, 19, - &nqd->bthresh, 0, 100, 100, 0, "CoC radius threshold, prevents background bleed on in-focus midground, 0=off"); - uiDefButC(block, TOG, B_NODE_EXEC, "Preview", - butr->xmin, dy-142, dx, 19, - &nqd->preview, 0, 0, 0, 0, "Enable sampling mode, useful for preview when using low samplecounts"); - if (nqd->preview) { - /* only visible when sampling mode enabled */ - uiDefButS(block, NUM, B_NODE_EXEC, "Samples:", - butr->xmin, dy-161, dx, 19, - &nqd->samples, 16, 256, 0, 0, "Number of samples (16=grainy, higher=less noise)"); - } - uiDefButS(block, TOG, B_NODE_EXEC, "No zbuffer", - butr->xmin, dy-190, dx, 19, - &nqd->no_zbuf, 0, 0, 0, 0, "Enable when using an image as input instead of actual zbuffer (auto enabled if node not image based, eg. time node)"); - if (nqd->no_zbuf) { - uiDefButF(block, NUM, B_NODE_EXEC, "Zscale:", - butr->xmin, dy-209, dx, 19, - &nqd->scale, 0, 1000, 100, 0, "Scales the Z input when not using a zbuffer, controls maximum blur designated by the color white or input value 1"); - } -} + uiLayout *sub, *col; + + col= uiLayoutColumn(layout, 1); + uiItemL(col, "Bokeh Type:", 0); + uiItemR(col, "", 0, ptr, "bokeh", 0); + uiItemR(col, NULL, 0, ptr, "angle", 0); + + uiItemR(layout, NULL, 0, ptr, "gamma_correction", 0); + col = uiLayoutColumn(layout, 0); + uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_zbuffer")==0); + uiItemR(col, NULL, 0, ptr, "f_stop", 0); + + uiItemR(layout, NULL, 0, ptr, "max_blur", 0); + uiItemR(layout, NULL, 0, ptr, "threshold", 0); + + // Preview + col = uiLayoutColumn(layout, 0); + uiItemR(col, NULL, 0, ptr, "preview", 0); + sub = uiLayoutColumn(col, 0); + uiLayoutSetActive(sub, RNA_boolean_get(ptr, "preview")); + uiItemR(sub, NULL, 0, ptr, "samples", 0); + + // Z-Buffer + col = uiLayoutColumn(layout, 0); + uiItemR(col, NULL, 0, ptr, "use_zbuffer", 0); + sub = uiLayoutColumn(col, 0); + uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_zbuffer")); + uiItemR(sub, NULL, 0, ptr, "z_scale", 0); +} /* qdn: glare node */ static void node_composit_buts_glare(uiLayout *layout, PointerRNA *ptr) -{ - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeGlare *ndg = node->storage; - short dy = butr->ymin + 152, dx = butr->xmax - butr->xmin; - char* mn1 = "Type%t|Ghosts%x3|Streaks%x2|Fog Glow%x1|Simple Star%x0"; - char* mn2 = "Quality/Speed%t|High/Slow%x0|Medium/Medium%x1|Low/Fast%x2"; - uiDefButC(block, MENU, B_NODE_EXEC, mn1, - butr->xmin, dy, dx, 19, - &ndg->type, 0, 0, 0, 0, "Glow/Flare/Bloom type"); - uiDefButC(block, MENU, B_NODE_EXEC, mn2, - butr->xmin, dy-19, dx, 19, - &ndg->quality, 0, 0, 0, 0, - "Quality speed trade off, if not set to high quality, effect will be applied to low-res copy of source image"); - if (ndg->type != 1) { - uiDefButC(block, NUM, B_NODE_EXEC, "Iterations:", - butr->xmin, dy-38, dx, 19, - &ndg->iter, 2, 5, 1, 0, - "higher values will generate longer/more streaks/ghosts"); - if (ndg->type != 0) - uiDefButF(block, NUM, B_NODE_EXEC, "ColMod:", - butr->xmin, dy-57, dx, 19, - &ndg->colmod, 0, 1, 10, 0, - "Amount of Color Modulation, modulates colors of streaks and ghosts for a spectral dispersion effect"); - } - uiDefButF(block, NUM, B_NODE_EXEC, "Mix:", - butr->xmin, dy-76, dx, 19, - &ndg->mix, -1, 1, 10, 0, - "Mix balance, -1 is original image only, 0 is exact 50/50 mix, 1 is processed image only"); - uiDefButF(block, NUM, B_NODE_EXEC, "Threshold:", - butr->xmin, dy-95, dx, 19, - &ndg->threshold, 0, 1000, 10, 0, - "Brightness threshold, the glarefilter will be applied only to pixels brighter than this value"); - if ((ndg->type == 2) || (ndg->type == 0)) - { - if (ndg->type == 2) { - uiDefButC(block, NUM, B_NODE_EXEC, "streaks:", - butr->xmin, dy-114, dx, 19, - &ndg->angle, 2, 16, 1000, 0, - "Total number of streaks"); - uiDefButC(block, NUM, B_NODE_EXEC, "AngOfs:", - butr->xmin, dy-133, dx, 19, - &ndg->angle_ofs, 0, 180, 1000, 0, - "Streak angle rotation offset in degrees"); - } - uiDefButF(block, NUM, B_NODE_EXEC, "Fade:", - butr->xmin, dy-152, dx, 19, - &ndg->fade, 0.75, 1, 5, 0, - "Streak fade out factor"); - } - if (ndg->type == 0) - uiDefButC(block, TOG, B_NODE_EXEC, "Rot45", - butr->xmin, dy-114, dx, 19, - &ndg->angle, 0, 0, 0, 0, - "simple star filter, add 45 degree rotation offset"); - if ((ndg->type == 1) || (ndg->type > 3)) // PBGH and fog glow - uiDefButC(block, NUM, B_NODE_EXEC, "Size:", - butr->xmin, dy-114, dx, 19, - &ndg->size, 6, 9, 1000, 0, - "glow/glare size (not actual size, relative to initial size of bright area of pixels)"); +{ + uiItemR(layout, "", 0, ptr, "glare_type", 0); + uiItemR(layout, "", 0, ptr, "quality", 0); + + if (RNA_enum_get(ptr, "glare_type")!= 1) { + uiItemR(layout, NULL, 0, ptr, "iterations", 0); + + if (RNA_enum_get(ptr, "glare_type")!= 0) + uiItemR(layout, NULL, 0, ptr, "color_modulation", 0); + } + + uiItemR(layout, NULL, 0, ptr, "mix", 0); + uiItemR(layout, NULL, 0, ptr, "threshold", 0); + + if (RNA_enum_get(ptr, "glare_type")== 2) { + uiItemR(layout, NULL, 0, ptr, "streaks", 0); + uiItemR(layout, NULL, 0, ptr, "angle_offset", 0); + } + if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) { + uiItemR(layout, NULL, 0, ptr, "fade", 0); + + if (RNA_enum_get(ptr, "glare_type")== 0) + uiItemR(layout, NULL, 0, ptr, "rotate_45", 0); + } + if (RNA_enum_get(ptr, "glare_type")== 1) { + uiItemR(layout, NULL, 0, ptr, "size", 0); + } } /* qdn: tonemap node */ static void node_composit_buts_tonemap(uiLayout *layout, PointerRNA *ptr) -{ - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeTonemap *ntm = node->storage; - short dy = butr->ymin + 76, dx = butr->xmax - butr->xmin; - char* mn = "Type%t|R/D Photoreceptor%x1|Rh Simple%x0"; - - uiBlockBeginAlign(block); - uiDefButI(block, MENU, B_NODE_EXEC, mn, - butr->xmin, dy, dx, 19, - &ntm->type, 0, 0, 0, 0, - "Tone mapping type"); - if (ntm->type == 0) { - uiDefButF(block, NUM, B_NODE_EXEC, "Key:", - butr->xmin, dy-19, dx, 19, - &ntm->key, 0, 1, 5, 0, - "The value the average luminance is mapped to"); - uiDefButF(block, NUM, B_NODE_EXEC, "Offset:", - butr->xmin, dy-38, dx, 19, - &ntm->offset, 0.001, 10, 5, 0, - "Tonemap offset, normally always 1, but can be used as an extra control to alter the brightness curve"); - uiDefButF(block, NUM, B_NODE_EXEC, "Gamma:", - butr->xmin, dy-57, dx, 19, - &ntm->gamma, 0.001, 3, 5, 0, - "Gamma factor, if not used, set to 1"); +{ + uiLayout *col; + + col = uiLayoutColumn(layout, 1); + uiItemR(col, "", 0, ptr, "tonemap_type", 0); + if (RNA_enum_get(ptr, "tonemap_type")== 0) { + uiItemR(col, NULL, 0, ptr, "key", 0); + uiItemR(col, NULL, 0, ptr, "offset", 0); + uiItemR(col, NULL, 0, ptr, "gamma", 0); } else { - uiDefButF(block, NUM, B_NODE_EXEC, "Intensity:", - butr->xmin, dy-19, dx, 19, - &ntm->f, -8, 8, 10, 0, "if less than zero, darkens image, otherwise makes it brighter"); - uiDefButF(block, NUM, B_NODE_EXEC, "Contrast:", - butr->xmin, dy-38, dx, 19, - &ntm->m, 0, 1, 5, 0, "Set to 0 to use estimate from input image"); - uiDefButF(block, NUM, B_NODE_EXEC, "Adaptation:", - butr->xmin, dy-57, dx, 19, - &ntm->a, 0, 1, 5, 0, "if 0, global, if 1, based on pixel intensity"); - uiDefButF(block, NUM, B_NODE_EXEC, "ColCorrect:", - butr->xmin, dy-76, dx, 19, - &ntm->c, 0, 1, 5, 0, "color correction, if 0, same for all channels, if 1, each independent"); + uiItemR(col, NULL, 0, ptr, "intensity", 0); + uiItemR(col, NULL, 0, ptr, "contrast", 0); + uiItemR(col, NULL, 0, ptr, "adaptation", 0); + uiItemR(col, NULL, 0, ptr, "correction", 0); } - uiBlockEndAlign(block); } /* qdn: lens distortion node */ static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr) { uiLayout *col; - - bNode *node= ptr->data; - NodeLensDist *nld = node->storage; col= uiLayoutColumn(layout, 0); - uiItemR(col, NULL, 0, ptr, "projector", 0); - if (!nld->proj) { - col = uiLayoutColumn(col, 0); - uiItemR(col, NULL, 0, ptr, "jitter", 0); - uiItemR(col, NULL, 0, ptr, "fit", 0); - } -// uiLayoutSetActive(col, RNA_boolean_get(&imaptr, "projector")); -} + col = uiLayoutColumn(col, 0); + uiLayoutSetActive(col, RNA_boolean_get(ptr, "projector")==0); + uiItemR(col, NULL, 0, ptr, "jitter", 0); + uiItemR(col, NULL, 0, ptr, "fit", 0); + +} static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) { @@ -1438,10 +1309,8 @@ static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) uiItemL(col, "Speed:", 0); uiItemR(col, "Min", 0, ptr, "min_speed", 0); uiItemR(col, "Max", 0, ptr, "max_speed", 0); - - col= uiLayoutColumn(layout, 0); - uiItemR(col, NULL, 0, ptr, "curved", 0); + uiItemR(layout, NULL, 0, ptr, "curved", 0); } static void node_composit_buts_filter(uiLayout *layout, PointerRNA *ptr) @@ -1458,9 +1327,7 @@ static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr) { uiLayout *col; - col= uiLayoutColumn(layout, 1); - - uiItemR(col, NULL, 0, ptr, "crop_size", 0); + uiItemR(layout, NULL, 0, ptr, "crop_size", 0); col= uiLayoutColumn(layout, 1); uiItemR(col, "Left", 0, ptr, "x1", 0); @@ -1471,21 +1338,12 @@ static void node_composit_buts_crop(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - - uiBlockBeginAlign(block); + uiLayout *row, *col; - uiDefButS(block, ROW, B_NODE_EXEC, "X", - butr->xmin, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20, - &node->custom2, 0.0, 0.0, 0, 0, ""); - uiDefButS(block, ROW, B_NODE_EXEC, "Y", - butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin+19, (butr->xmax-butr->xmin)/2, 20, - &node->custom2, 0.0, 1.0, 0, 0, ""); - - uiDefButS(block, NUMSLI, B_NODE_EXEC, "Split %: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 100, 10, 0, ""); + col= uiLayoutColumn(layout, 1); + row= uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "axis", UI_ITEM_R_EXPAND); + uiItemR(col, NULL, 0, ptr, "factor", 0); } static void node_composit_buts_map_value(uiLayout *layout, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index f2caf1a4d52..73aaf0837db 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1066,11 +1066,10 @@ static void def_cmp_splitviewer(StructRNA *srna) RNA_def_property_enum_items(prop, axis_items); RNA_def_property_ui_text(prop, "Axis", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); - - /* TODO: percentage */ - prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_PERCENTAGE); - RNA_def_property_float_sdna(prop, NULL, "custom1"); - RNA_def_property_range(prop, 0.0f, 100.0f); + + prop = RNA_def_property(srna, "factor", PROP_INT, PROP_PERCENTAGE); + RNA_def_property_int_sdna(prop, NULL, "custom1"); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Factor", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); } @@ -1255,7 +1254,7 @@ static void def_cmp_dblur(StructRNA *srna) prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "iter"); - RNA_def_property_range(prop, 1, 128); + RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text(prop, "Iterations", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); @@ -1356,12 +1355,12 @@ static void def_cmp_glare(StructRNA *srna) {0, NULL, 0, NULL, NULL} }; - /*static EnumPropertyItem quality_items[] = { + static EnumPropertyItem quality_items[] = { {0, "HIGH", 0, "High", ""}, {1, "MEDIUM", 0, "Medium", ""}, {2, "LOW", 0, "Low", ""}, {0, NULL, 0, NULL, NULL} - };*/ + }; RNA_def_struct_sdna_from(srna, "NodeGlare", "storage"); @@ -1373,7 +1372,7 @@ static void def_cmp_glare(StructRNA *srna) prop = RNA_def_property(srna, "quality", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "quality"); - RNA_def_property_enum_items(prop, type_items); + RNA_def_property_enum_items(prop, quality_items); RNA_def_property_ui_text(prop, "Quality", "If not set to high quality, the effect will be applied to a low-res copy of the source image"); RNA_def_property_update(prop, 0, "rna_Node_update"); @@ -1386,7 +1385,7 @@ static void def_cmp_glare(StructRNA *srna) prop = RNA_def_property(srna, "color_modulation", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "colmod"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Color Modulation", ""); + RNA_def_property_ui_text(prop, "Color Modulation", "Amount of Color Modulation, modulates colors of streaks and ghosts for a spectral dispersion effect"); RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "mix", PROP_FLOAT, PROP_NONE); @@ -1451,8 +1450,6 @@ static void def_cmp_tonemap(StructRNA *srna) RNA_def_property_ui_text(prop, "Tonemap Type", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); - /* TODO: if type==0 { */ - prop = RNA_def_property(srna, "key", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "key"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -1471,8 +1468,6 @@ static void def_cmp_tonemap(StructRNA *srna) RNA_def_property_ui_text(prop, "Gamma", "If not used, set to 1"); RNA_def_property_update(prop, 0, "rna_Node_update"); - /* TODO: } else { */ - prop = RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "f"); RNA_def_property_range(prop, -8.0f, 8.0f); -- cgit v1.2.3 From ad07133e531b4f1eb81cdd5086d1f769e971d606 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 18 Sep 2009 22:12:29 +0000 Subject: Add path to find SYS_System.h (which is only included with gameengine). Reported by Jasper Mine. Fixed comment, it was away from the directive it explained. --- source/blender/editors/space_view3d/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile index 07102157854..9204f2482c6 100644 --- a/source/blender/editors/space_view3d/Makefile +++ b/source/blender/editors/space_view3d/Makefile @@ -53,6 +53,9 @@ CPPFLAGS += -I../../render/extern/include CPPFLAGS += -I../../blenfont CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_SMOKE)/include -# own include +ifneq ($(NAN_NO_KETSJI),true) + CPPFLAGS += -I../../../kernel/gen_system +endif +# own include CPPFLAGS += -I../include -- cgit v1.2.3 From 8ab24bb2c2f38f3d52c985d83cf691274fa0d6f0 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 19 Sep 2009 00:18:42 +0000 Subject: 2.5 - Pose Enhancement Tools This commit restores the 'Relax Pose' tool, and also introduces two others: 'Push Pose' and 'Pose Breakdowner'. Be aware that this commit is just the initial starting point, with some parts yet to be done. A short description of these tools follows: * Relax Pose (Alt-E) - makes the current pose more like the poses on either side of it * Push Pose (Ctrl-E) - exaggerates the current pose * Breakdowner (Shift-E)[not working yet] - when this works, it will allow for interactive selection of a good in-between pose to act as a breakdown. Todo's: * Connect up the 'percentage' slider in the operator settings to allow these effects to be dialed in/out, exaggerating/relaxing/moveing-between-keyframes by varying degrees until the desired effect is reached. * Allow these effects to be interactively dialed in/out. The idea is to use the mouse to interactively set the percentage slider value initially, then use the percentage slider to tweak later. * Figure out why breakdown breaks down --- source/blender/blenkernel/BKE_fcurve.h | 5 + source/blender/blenkernel/intern/fcurve.c | 79 +++ source/blender/editors/animation/keyframes_draw.c | 24 +- source/blender/editors/animation/keyframing.c | 79 --- source/blender/editors/armature/armature_intern.h | 8 + source/blender/editors/armature/armature_ops.c | 11 + source/blender/editors/armature/poseSlide.c | 722 +++++++++++++++++++++ source/blender/editors/armature/poselib.c | 7 +- source/blender/editors/armature/poseobject.c | 172 +---- source/blender/editors/include/ED_keyframes_draw.h | 4 + source/blender/editors/screen/screen_ops.c | 23 - 11 files changed, 859 insertions(+), 275 deletions(-) create mode 100644 source/blender/editors/armature/poseSlide.c diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index cda64c6b241..e25e32a2010 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -153,6 +153,11 @@ void copy_fcurves(ListBase *dst, ListBase *src); /* find matching F-Curve in the given list of F-Curves */ struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index); +/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number. + * Returns the index to insert at (data already at that index will be offset if replace is 0) + */ +int binarysearch_bezt_index(struct BezTriple array[], float frame, int arraylen, short *replace); + /* get the time extents for F-Curve */ void calc_fcurve_range(struct FCurve *fcu, float *min, float *max); diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index f7f79e9772f..0ecd1fe912b 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -200,6 +200,85 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array return NULL; } +/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */ +#define BEZT_BINARYSEARCH_THRESH 0.00001f + +/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve) + * Returns the index to insert at (data already at that index will be offset if replace is 0) + */ +int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace) +{ + int start=0, end=arraylen; + int loopbreaker= 0, maxloop= arraylen * 2; + + /* initialise replace-flag first */ + *replace= 0; + + /* sneaky optimisations (don't go through searching process if...): + * - keyframe to be added is to be added out of current bounds + * - keyframe to be added would replace one of the existing ones on bounds + */ + if ((arraylen <= 0) || (array == NULL)) { + printf("Warning: binarysearch_bezt_index() encountered invalid array \n"); + return 0; + } + else { + /* check whether to add before/after/on */ + float framenum; + + /* 'First' Keyframe (when only one keyframe, this case is used) */ + framenum= array[0].vec[1][0]; + if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) { + *replace = 1; + return 0; + } + else if (frame < framenum) + return 0; + + /* 'Last' Keyframe */ + framenum= array[(arraylen-1)].vec[1][0]; + if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) { + *replace= 1; + return (arraylen - 1); + } + else if (frame > framenum) + return arraylen; + } + + + /* most of the time, this loop is just to find where to put it + * 'loopbreaker' is just here to prevent infinite loops + */ + for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) { + /* compute and get midpoint */ + int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */ + float midfra= array[mid].vec[1][0]; + + /* check if exactly equal to midpoint */ + if (IS_EQT(frame, midfra, BEZT_BINARYSEARCH_THRESH)) { + *replace = 1; + return mid; + } + + /* repeat in upper/lower half */ + if (frame > midfra) + start= mid + 1; + else if (frame < midfra) + end= mid - 1; + } + + /* print error if loop-limit exceeded */ + if (loopbreaker == (maxloop-1)) { + printf("Error: binarysearch_bezt_index() was taking too long \n"); + + // include debug info + printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen); + } + + /* not found, so return where to place it */ + return start; +} + /* Calculate the extents of F-Curve's data */ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax) { diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index abea38e129e..8e7789190c3 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -316,7 +316,7 @@ static void set_touched_actkeyblock (ActKeyBlock *ab) /* *************************** Keyframe Drawing *************************** */ /* helper function - find actkeycolumn that occurs on cframe */ -static ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe) +ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe) { /* sanity checks */ if (ak == NULL) @@ -331,6 +331,28 @@ static ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe) return ak; /* match */ } +/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */ +ActKeyColumn *cfra_find_nearest_next_ak (ActKeyColumn *ak, float cframe, short next) +{ + ActKeyColumn *akn= NULL; + + /* sanity checks */ + if (ak == NULL) + return NULL; + + /* check if this is a match, or whether it is in some subtree */ + if (cframe < ak->cfra) + akn= cfra_find_nearest_next_ak(ak->left, cframe, next); + else if (cframe > ak->cfra) + akn= cfra_find_nearest_next_ak(ak->right, cframe, next); + + /* if no match found (or found match), just use the current one */ + if (akn == NULL) + return ak; + else + return akn; +} + /* -------- */ /* coordinates for diamond shape */ diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 7135f8802bc..e8451b0f979 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -176,85 +176,6 @@ FCurve *verify_fcurve (bAction *act, const char group[], const char rna_path[], /* -------------- BezTriple Insertion -------------------- */ -/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */ -#define BEZT_INSERT_THRESH 0.00001f - -/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu) - * Returns the index to insert at (data already at that index will be offset if replace is 0) - */ -static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace) -{ - int start=0, end=arraylen; - int loopbreaker= 0, maxloop= arraylen * 2; - - /* initialise replace-flag first */ - *replace= 0; - - /* sneaky optimisations (don't go through searching process if...): - * - keyframe to be added is to be added out of current bounds - * - keyframe to be added would replace one of the existing ones on bounds - */ - if ((arraylen <= 0) || (array == NULL)) { - printf("Warning: binarysearch_bezt_index() encountered invalid array \n"); - return 0; - } - else { - /* check whether to add before/after/on */ - float framenum; - - /* 'First' Keyframe (when only one keyframe, this case is used) */ - framenum= array[0].vec[1][0]; - if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) { - *replace = 1; - return 0; - } - else if (frame < framenum) - return 0; - - /* 'Last' Keyframe */ - framenum= array[(arraylen-1)].vec[1][0]; - if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) { - *replace= 1; - return (arraylen - 1); - } - else if (frame > framenum) - return arraylen; - } - - - /* most of the time, this loop is just to find where to put it - * 'loopbreaker' is just here to prevent infinite loops - */ - for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) { - /* compute and get midpoint */ - int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */ - float midfra= array[mid].vec[1][0]; - - /* check if exactly equal to midpoint */ - if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH)) { - *replace = 1; - return mid; - } - - /* repeat in upper/lower half */ - if (frame > midfra) - start= mid + 1; - else if (frame < midfra) - end= mid - 1; - } - - /* print error if loop-limit exceeded */ - if (loopbreaker == (maxloop-1)) { - printf("Error: binarysearch_bezt_index() was taking too long \n"); - - // include debug info - printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen); - } - - /* not found, so return where to place it */ - return start; -} - /* This function adds a given BezTriple to an F-Curve. It will allocate * memory for the array if needed, and will insert the BezTriple into a * suitable place in chronological order. diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 0c8c0e8e644..6f5a5f44d87 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -118,11 +118,19 @@ void SKETCH_OT_select(struct wmOperatorType *ot); /* ******************************************************* */ /* PoseLib */ + void POSELIB_OT_pose_add(struct wmOperatorType *ot); void POSELIB_OT_pose_remove(struct wmOperatorType *ot); void POSELIB_OT_pose_rename(struct wmOperatorType *ot); void POSELIB_OT_browse_interactive(struct wmOperatorType *ot); +/* ******************************************************* */ +/* Pose Sliding Tools */ + +void POSE_OT_push(struct wmOperatorType *ot); +void POSE_OT_relax(struct wmOperatorType *ot); +void POSE_OT_breakdown(struct wmOperatorType *ot); + /* ******************************************************* */ /* editarmature.c */ struct bArmature; diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 9076b533974..a8b8b8aecc1 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -196,6 +196,11 @@ void ED_operatortypes_armature(void) WM_operatortype_append(POSELIB_OT_pose_remove); WM_operatortype_append(POSELIB_OT_pose_rename); + /* POSE SLIDING */ + WM_operatortype_append(POSE_OT_push); + WM_operatortype_append(POSE_OT_relax); + WM_operatortype_append(POSE_OT_breakdown); + /* TESTS */ WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed } @@ -365,5 +370,11 @@ void ED_keymap_armature(wmWindowManager *wm) WM_keymap_add_item(keymap, "POSELIB_OT_pose_add", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "POSELIB_OT_pose_remove", LKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "POSELIB_OT_pose_rename", LKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + + /* Pose -> Pose Sliding ------------- */ + /* only set in posemode, by space_view3d listener */ + WM_keymap_add_item(keymap, "POSE_OT_push", EKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "POSE_OT_relax", EKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "POSE_OT_breakdown", EKEY, KM_PRESS, KM_SHIFT, 0); } diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c new file mode 100644 index 00000000000..464dbcba54b --- /dev/null +++ b/source/blender/editors/armature/poseSlide.c @@ -0,0 +1,722 @@ +/** + * $Id: poseSlide.c 23179 2009-09-13 12:34:00Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_dynstr.h" +#include "BLI_dlrbTree.h" + +#include "DNA_listBase.h" +#include "DNA_anim_types.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_scene_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_animsys.h" +#include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_object.h" + +#include "BKE_global.h" +#include "BKE_context.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "BIF_gl.h" + +#include "ED_anim_api.h" +#include "ED_armature.h" +#include "ED_keyframes_draw.h" +#include "ED_keyframing.h" +#include "ED_keyframes_edit.h" +#include "ED_screen.h" + +#include "armature_intern.h" + +/* **************************************************** */ +/* == POSE 'SLIDING' TOOLS == + * + * A) Push & Relax, Breakdowner + * These tools provide the animator with various capabilities + * for interactively controlling the spacing of poses, but also + * for 'pushing' and/or 'relaxing' extremes as they see fit. + * + * B) Pose Sculpting + * This is yet to be implemented, but the idea here is to use + * sculpting techniques to make it easier to pose rigs by allowing + * rigs to be manipulated using a familiar paint-based interface. + */ +/* **************************************************** */ +/* A) Push & Relax, Breakdowner */ + +/* Temporary data shared between these operators */ +typedef struct tPoseSlideOp { + Scene *scene; /* current scene */ + ARegion *ar; /* region that we're operating in (needed for */ + Object *ob; /* active object that Pose Info comes from */ + + ListBase pfLinks; /* links between posechannels and f-curves */ + DLRBT_Tree keys; /* binary tree for quicker searching for keyframes (when applicable) */ + + KeyingSet *ks_loc; /* builtin KeyingSet for keyframing locations */ + KeyingSet *ks_rot; /* builtin KeyingSet for keyframing rotations */ + KeyingSet *ks_scale;/* builtin KeyingSet for keyframing scale */ + + int cframe; /* current frame number */ + int prevFrame; /* frame before current frame (blend-from) */ + int nextFrame; /* frame after current frame (blend-to) */ + + int mode; /* sliding mode (ePoseSlide_Modes) */ + int flag; // unused for now, but can later get used for storing runtime settings.... + + float percentage; /* 0-1 value for determining the influence of whatever is relevant */ +} tPoseSlideOp; + +/* Pose Sliding Modes */ +typedef enum ePoseSlide_Modes { + POSESLIDE_PUSH = 0, /* exaggerate the pose... */ + POSESLIDE_RELAX, /* soften the pose... */ + POSESLIDE_BREAKDOWN, /* slide between the endpoint poses, finding a 'soft' spot */ +} ePoseSlide_Modes; + +/* Temporary data linking PoseChannels with the F-Curves they affect */ +typedef struct tPChanFCurveLink { + struct tPChanFCurveLink *next, *prev; + + ListBase fcurves; /* F-Curves for this PoseChannel */ + bPoseChannel *pchan; /* Pose Channel which data is attached to */ + char *pchan_path; /* RNA Path to this Pose Channel (needs to be freed when we're done) */ +} tPChanFCurveLink; + +/* ------------------------------------ */ + +/* operator init */ +static int pose_slide_init (bContext *C, wmOperator *op, short mode) +{ + tPoseSlideOp *pso; + bAction *act= NULL; + + /* init slide-op data */ + pso= op->customdata= MEM_callocN(sizeof(tPoseSlideOp), "tPoseSlideOp"); + + /* get info from context */ + pso->scene= CTX_data_scene(C); + pso->ob= CTX_data_active_object(C); + pso->ar= CTX_wm_region(C); /* only really needed when doing modal() */ + + pso->cframe= pso->scene->r.cfra; + pso->mode= mode; + + /* set range info from property values - these may get overridden for the invoke() */ + pso->percentage= RNA_float_get(op->ptr, "percentage"); + pso->prevFrame= RNA_int_get(op->ptr, "prev_frame"); + pso->nextFrame= RNA_int_get(op->ptr, "next_frame"); + + /* check the settings from the context */ + if (ELEM3(NULL, pso->ob, pso->ob->adt, pso->ob->adt->action)) + return 0; + else + act= pso->ob->adt->action; + + /* for each Pose-Channel which gets affected, get the F-Curves for that channel + * and set the relevant transform flags... + */ + CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) + { + ListBase curves = {NULL, NULL}; + int transFlags = action_get_item_transforms(act, pso->ob, pchan, &curves); + + pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE); + + /* check if any transforms found... */ + if (transFlags) { + /* make new linkage data */ + tPChanFCurveLink *pfl= MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink"); + PointerRNA ptr; + + pfl->fcurves= curves; + pfl->pchan= pchan; + + /* get the RNA path to this pchan - this needs to be freed! */ + RNA_pointer_create((ID *)pso->ob, &RNA_PoseChannel, pchan, &ptr); + pfl->pchan_path= RNA_path_from_ID_to_struct(&ptr); + + /* add linkage data to operator data */ + BLI_addtail(&pso->pfLinks, pfl); + + /* set pchan's transform flags */ + if (transFlags & ACT_TRANS_LOC) + pchan->flag |= POSE_LOC; + if (transFlags & ACT_TRANS_ROT) + pchan->flag |= POSE_ROT; + if (transFlags & ACT_TRANS_SCALE) + pchan->flag |= POSE_SIZE; + } + } + CTX_DATA_END; + + /* do basic initialise of RB-BST used for finding keyframes, but leave the filling of it up + * to the caller of this (usually only invoke() will do it, to make things more efficient). + */ + BLI_dlrbTree_init(&pso->keys); + + /* get builtin KeyingSets */ + pso->ks_loc= ANIM_builtin_keyingset_get_named(NULL, "Location"); + pso->ks_rot= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); + pso->ks_scale= ANIM_builtin_keyingset_get_named(NULL, "Scale"); + + /* return status is whether we've got all the data we were requested to get */ + return 1; +} + +/* exiting the operator - free data */ +static void pose_slide_exit (bContext *C, wmOperator *op) +{ + tPoseSlideOp *pso= op->customdata; + + /* if data exists, clear its data and exit */ + if (pso) { + tPChanFCurveLink *pfl, *pfln=NULL; + + /* free the temp pchan links and their data */ + for (pfl= pso->pfLinks.first; pfl; pfl= pfln) { + pfln= pfl->next; + + /* free list of F-Curve reference links */ + BLI_freelistN(&pfl->fcurves); + + /* free pchan RNA Path */ + MEM_freeN(pfl->pchan_path); + + /* free link itself */ + BLI_freelinkN(&pso->pfLinks, pfl); + } + + /* free RB-BST for keyframes (if it contained data) */ + BLI_dlrbTree_free(&pso->keys); + + /* free data itself */ + MEM_freeN(pso); + } + + /* cleanup */ + op->customdata= NULL; +} + +/* ------------------------------------ */ + +/* helper for apply() callabcks - find the next F-Curve with matching path... */ +static LinkData *find_next_fcurve_link (ListBase *fcuLinks, LinkData *prev, char *path) +{ + LinkData *first= (prev)? prev->next : (fcuLinks)? fcuLinks->first : NULL; + LinkData *ld; + + /* check each link to see if the linked F-Curve has a matching path */ + for (ld= first; ld; ld= ld->next) { + FCurve *fcu= (FCurve *)ld->data; + + /* check if paths match */ + if (strcmp(path, fcu->rna_path) == 0) + return ld; + } + + /* none found */ + return NULL; +} + +/* helper for apply() - perform sliding for some 3-element vector */ +static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, float vec[3], char *propName) +{ + LinkData *ld=NULL; + char *path=NULL; + float cframe; + + /* get the path to use... */ + path= BLI_sprintfN("%s.%s", pfl->pchan_path, propName); + + /* get the current frame number */ + cframe= (float)pso->cframe; + + /* using this path, find each matching F-Curve for the variables we're interested in */ + while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) { + FCurve *fcu= (FCurve *)ld->data; + float w1, w2, wtot, ctrl, ictrl; + float sVal, eVal; + int ch; + + /* get keyframe values for endpoint poses to blend with */ + /* previous/start */ + sVal= evaluate_fcurve(fcu, (float)pso->prevFrame); + /* next/end */ + eVal= evaluate_fcurve(fcu, (float)pso->nextFrame); + + /* get channel index */ + ch= fcu->array_index; + + /* get the influence of the control */ + ctrl= pso->percentage; + ictrl= 1.0f - pso->percentage; + + /* calculate the relative weights of the endpoints + * - these weights are derived from the relative distance of these + * poses from the current frame + * - they then get normalised, with the results of these normalised + */ + w1 = cframe - (float)pso->prevFrame; + w2 = (float)pso->nextFrame - cframe; + + wtot = w1 + w2; + w1 = w1/wtot; + w2 = w2/wtot; + + /* depending on the mode, */ + switch (pso->mode) { + case POSESLIDE_PUSH: /* make the current pose more pronounced */ + // TODO: this is not interactively modifiable! + vec[ch]= ( -((sVal * w2) + (eVal * w1)) + (vec[ch] * 6.0f) ) / 5.0f; + break; + + case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */ + /* apply the value with a hard coded 6th */ + // TODO: this is not interactively modifiable! + vec[ch]= ( ((sVal * w2) + (eVal * w1)) + (vec[ch] * 5.0f) ) / 6.0f; + break; + + case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */ + // NOTE: just linear interpolation for now, but could add small component of our key if necessary... + // TODO: this doesn't work at all + w2= 1.0f - w1; + vec[ch]= ((sVal * w1) + (eVal * w2)); + break; + } + + } + + /* free the temp path we got */ + MEM_freeN(path); +} + +/* helper for apply() - perform sliding for quaternion rotations (using quat blending) */ +static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl) +{ + // TODO: this is quite evil stuff... +#if 0 // XXX port... + /* get 2 quats */ + quat_prev[0] = eval_icu(icu_w, frame_prev); + quat_prev[1] = eval_icu(icu_x, frame_prev); + quat_prev[2] = eval_icu(icu_y, frame_prev); + quat_prev[3] = eval_icu(icu_z, frame_prev); + + quat_next[0] = eval_icu(icu_w, frame_next); + quat_next[1] = eval_icu(icu_x, frame_next); + quat_next[2] = eval_icu(icu_y, frame_next); + quat_next[3] = eval_icu(icu_z, frame_next); + +#if 0 + /* apply the setting, completely smooth */ + QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) ); +#else + /* tricky interpolation */ + QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) ); + QUATCOPY(quat_orig, pchan->quat); + QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f); + /* done */ +#endif +#endif +} + +/* helper for apply() - perform autokeyframing */ +static void pose_slide_autoKeyframe (bContext *C, tPoseSlideOp *pso, bPoseChannel *pchan, KeyingSet *ks) +{ + /* insert keyframes as necessary if autokeyframing */ + if (autokeyframe_cfra_can_key(pso->scene, &pso->ob->id)) { + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; + + /* init common-key-source for use by KeyingSets */ + // TODO: for now, we don't clear it out, since it should be safe to do so... + //memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &pso->ob->id; + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + + /* insert keyframes */ + modify_keyframes(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + } +} + +/* apply() - perform the pose sliding based on weighting various poses */ +static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso) +{ + tPChanFCurveLink *pfl; + + /* sanitise the frame ranges */ + if (pso->prevFrame == pso->nextFrame) { + /* move out one step either side */ + pso->prevFrame--; + pso->nextFrame++; + } + + /* for each link, handle each set of transforms */ + for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) { + /* valid transforms for each PoseChannel should have been noted already + * - sliding the pose should be a straightforward exercise for location+rotation, + * but rotations get more complicated since we may want to use quaternion blending + * for quaternions instead... + */ + bPoseChannel *pchan= pfl->pchan; + + if (pchan->flag & POSE_LOC) { + /* calculate these for the 'location' vector, and use location curves */ + pose_slide_apply_vec3(pso, pfl, pchan->loc, "location"); + /* insert keyframes if needed */ + pose_slide_autoKeyframe(C, pso, pchan, pso->ks_loc); + } + + if (pchan->flag & POSE_SIZE) { + /* calculate these for the 'scale' vector, and use scale curves */ + pose_slide_apply_vec3(pso, pfl, pchan->size, "scale"); + /* insert keyframes if needed */ + pose_slide_autoKeyframe(C, pso, pchan, pso->ks_scale); + } + + if (pchan->flag & POSE_ROT) { + /* everything depends on the rotation mode */ + if (pchan->rotmode > 0) { + /* eulers - so calculate these for the 'eul' vector, and use euler_rotation curves */ + pose_slide_apply_vec3(pso, pfl, pchan->eul, "euler_rotation"); + } + else if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { + // TODO: need to figure out how to do this! + } + else { + /* quaternions - use quaternion blending */ + pose_slide_apply_quat(pso, pfl); + } + + /* insert keyframes if needed */ + pose_slide_autoKeyframe(C, pso, pchan, pso->ks_rot); + } + } + + /* funky depsgraph flags - are these still needed? */ + pso->ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); + + /* do depsgraph flush */ + DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); + + /* note, notifier might evolve */ + //WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, pso->ob); +} + +/* ------------------------------------ */ + +/* common code for invoke() methods */ +static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp *pso) +{ + tPChanFCurveLink *pfl; + AnimData *adt= pso->ob->adt; + + /* for each link, add all its keyframes to the search tree */ + for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) { + LinkData *ld; + + /* do this for each F-Curve */ + for (ld= pfl->fcurves.first; ld; ld= ld->next) { + FCurve *fcu= (FCurve *)ld->data; + fcurve_to_keylist(adt, fcu, &pso->keys, NULL); + } + } + + /* consolidate these keyframes, and figure out the nearest ones */ + BLI_dlrbTree_linkedlist_sync(&pso->keys); + + /* cancel if no keyframes found... */ + if (pso->keys.root) { + ActKeyColumn *ak; + + /* firstly, check if the current frame is a keyframe... */ + ak= cfra_find_actkeycolumn(pso->keys.root, pso->cframe); + + if (ak == NULL) { + /* current frame is not a keyframe, so search */ + /* prev frame */ + ak= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 0); + pso->prevFrame= (ak)? (ak->cfra) : (pso->cframe - 1); + RNA_int_set(op->ptr, "prev_frame", pso->prevFrame); + /* next frame */ + ak= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 1); + pso->nextFrame= (ak)? (ak->cfra) : (pso->cframe + 1); + RNA_int_set(op->ptr, "next_frame", pso->prevFrame); + } + else { + /* current frame itself is a keyframe, so just take keyframes on either side */ + /* prev frame */ + pso->prevFrame= (ak->prev)? (ak->prev->cfra) : (pso->cframe - 1); + RNA_int_set(op->ptr, "prev_frame", pso->prevFrame); + /* next frame */ + pso->nextFrame= (ak->next)? (ak->next->cfra) : (pso->cframe + 1); + RNA_int_set(op->ptr, "next_frame", pso->nextFrame); + } + } + else { + BKE_report(op->reports, RPT_ERROR, "No keyframes to slide between."); + return OPERATOR_CANCELLED; + } + + + // TODO ----------------------------------- + // from here on, we should just invoke the modal operator, but for now, just do static... + + /* temp static operator code... */ + pose_slide_apply(C, op, pso); + pose_slide_exit(C, op); + return OPERATOR_FINISHED; +} + +// TODO: common modal + cancel + + +/* common code for exec() methods */ +static int pose_slide_exec_common (bContext *C, wmOperator *op, tPoseSlideOp *pso) +{ + /* settings should have been set up ok for applying, so just apply! */ + pose_slide_apply(C, op, pso); + + /* cleanup and done */ + pose_slide_exit(C, op); + + return OPERATOR_FINISHED; +} + +/* common code for defining RNA properties */ +static void pose_slide_opdef_properties (wmOperatorType *ot) +{ + RNA_def_int(ot->srna, "prev_frame", 0, MINAFRAME, MAXFRAME, "Previous Keyframe", "Frame number of keyframe immediately before the current frame.", 0, 50); + RNA_def_int(ot->srna, "next_frame", 0, MINAFRAME, MAXFRAME, "Next Keyframe", "Frame number of keyframe immediately after the current frame.", 0, 50); + RNA_def_float_percentage(ot->srna, "percentage", 0.5f, 0.0f, 1.0f, "Percentage", "Weighting factor for the sliding operation", 0.3, 0.7); +} + +/* ------------------------------------ */ + +/* invoke() - for 'push' mode */ +static int pose_slide_push_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + tPoseSlideOp *pso; + + /* initialise data */ + if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) { + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + } + else + pso= op->customdata; + + /* do common setup work */ + return pose_slide_invoke_common(C, op, pso); +} + +/* exec() - for push */ +static int pose_slide_push_exec (bContext *C, wmOperator *op) +{ + tPoseSlideOp *pso; + + /* initialise data (from RNA-props) */ + if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) { + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + } + else + pso= op->customdata; + + /* do common exec work */ + return pose_slide_exec_common(C, op, pso); +} + +void POSE_OT_push (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Push Pose"; + ot->idname= "POSE_OT_push"; + ot->description= "Exaggerate the current pose"; + + /* callbacks */ + ot->exec= pose_slide_push_exec; + ot->invoke= pose_slide_push_invoke; + //ot->modal= pose_slide_modal; + //ot->cancel= pose_slide_cancel; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING; + + /* Properties */ + pose_slide_opdef_properties(ot); +} + +/* ........................ */ + +/* invoke() - for 'relax' mode */ +static int pose_slide_relax_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + tPoseSlideOp *pso; + + /* initialise data */ + if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) { + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + } + else + pso= op->customdata; + + /* do common setup work */ + return pose_slide_invoke_common(C, op, pso); +} + +/* exec() - for relax */ +static int pose_slide_relax_exec (bContext *C, wmOperator *op) +{ + tPoseSlideOp *pso; + + /* initialise data (from RNA-props) */ + if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) { + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + } + else + pso= op->customdata; + + /* do common exec work */ + return pose_slide_exec_common(C, op, pso); +} + +void POSE_OT_relax (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Relax Pose"; + ot->idname= "POSE_OT_relax"; + ot->description= "Make the current pose more similar to its surrounding ones."; + + /* callbacks */ + ot->exec= pose_slide_relax_exec; + ot->invoke= pose_slide_relax_invoke; + //ot->modal= pose_slide_modal; + //ot->cancel= pose_slide_cancel; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING; + + /* Properties */ + pose_slide_opdef_properties(ot); +} + +/* ........................ */ + +/* invoke() - for 'breakdown' mode */ +static int pose_slide_breakdown_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + tPoseSlideOp *pso; + + /* initialise data */ + if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) { + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + } + else + pso= op->customdata; + + /* do common setup work */ + return pose_slide_invoke_common(C, op, pso); +} + +/* exec() - for breakdown */ +static int pose_slide_breakdown_exec (bContext *C, wmOperator *op) +{ + tPoseSlideOp *pso; + + /* initialise data (from RNA-props) */ + if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) { + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + } + else + pso= op->customdata; + + /* do common exec work */ + return pose_slide_exec_common(C, op, pso); +} + +void POSE_OT_breakdown (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Pose Breakdowner"; + ot->idname= "POSE_OT_breakdown"; + ot->description= "Create a suitable breakdown pose on the current frame."; + + /* callbacks */ + ot->exec= pose_slide_breakdown_exec; + ot->invoke= pose_slide_breakdown_invoke; + //ot->modal= pose_slide_modal; + //ot->cancel= pose_slide_cancel; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING; + + /* Properties */ + pose_slide_opdef_properties(ot); +} + +/* **************************************************** */ diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index f072f2e980e..ce07cfb9042 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -44,7 +44,6 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_curve_types.h" -#include "DNA_ipo_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_scene_types.h" @@ -62,8 +61,6 @@ #include "BKE_report.h" #include "BKE_utildefines.h" -#include "PIL_time.h" /* sleep */ - #include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" @@ -769,6 +766,10 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData if (poselib_ks_locrotscale == NULL) poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + + /* now insert the keyframe */ modify_keyframes(C, &dsources, NULL, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); /* clear any unkeyed tags */ diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index bab7111dbd7..e5a7a1e167d 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1084,6 +1084,9 @@ static int pose_paste_exec (bContext *C, wmOperator *op) if (posePaste_ks_locrotscale == NULL) posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(C, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); /* clear any unkeyed tags */ @@ -1983,175 +1986,6 @@ void ARMATURE_OT_bone_layers (wmOperatorType *ot) /* ********************************************** */ -#if 0 -// XXX old sys -/* for use with pose_relax only */ -static int pose_relax_icu(struct IpoCurve *icu, float framef, float *val, float *frame_prev, float *frame_next) -{ - if (!icu) { - return 0; - } - else { - BezTriple *bezt = icu->bezt; - - BezTriple *bezt_prev=NULL, *bezt_next=NULL; - float w1, w2, wtot; - int i; - - for (i=0; i < icu->totvert; i++, bezt++) { - if (bezt->vec[1][0] < framef - 0.5) { - bezt_prev = bezt; - } else { - break; - } - } - - if (bezt_prev==NULL) return 0; - - /* advance to the next, dont need to advance i */ - bezt = bezt_prev+1; - - for (; i < icu->totvert; i++, bezt++) { - if (bezt->vec[1][0] > framef + 0.5) { - bezt_next = bezt; - break; - } - } - - if (bezt_next==NULL) return 0; - - if (val) { - w1 = framef - bezt_prev->vec[1][0]; - w2 = bezt_next->vec[1][0] - framef; - wtot = w1 + w2; - w1=w1/wtot; - w2=w2/wtot; -#if 0 - val = (bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1); -#else - /* apply the value with a hard coded 6th */ - *val = (((bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1)) + (*val * 5.0f)) / 6.0f; -#endif - } - - if (frame_prev) *frame_prev = bezt_prev->vec[1][0]; - if (frame_next) *frame_next = bezt_next->vec[1][0]; - - return 1; - } -} -#endif - -void pose_relax(Scene *scene) -{ - Object *ob = OBACT; - bPose *pose; - bAction *act; - bArmature *arm; - -// IpoCurve *icu_w, *icu_x, *icu_y, *icu_z; - - bPoseChannel *pchan; -// bActionChannel *achan; -// float framef = F_CFRA; -// float frame_prev, frame_next; -// float quat_prev[4], quat_next[4], quat_interp[4], quat_orig[4]; - - int do_scale = 0; - int do_loc = 0; - int do_quat = 0; - int flag = 0; -// int do_x, do_y, do_z; - - if (!ob) return; - - pose = ob->pose; - act = ob->action; - arm = (bArmature *)ob->data; - - if (!pose || !act || !arm) return; - - for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) { - - pchan->bone->flag &= ~BONE_TRANSFORM; - - if (pchan->bone->layer & arm->layer) { - if (pchan->bone->flag & BONE_SELECTED) { - /* do we have an ipo curve? */ -#if 0 // XXX old animation system - achan= get_action_channel(act, pchan->name); - - if (achan && achan->ipo) { - /*calc_ipo(achan->ipo, ctime);*/ - - do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_X), framef, &pchan->loc[0], NULL, NULL); - do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Y), framef, &pchan->loc[1], NULL, NULL); - do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Z), framef, &pchan->loc[2], NULL, NULL); - do_loc += do_x + do_y + do_z; - - do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_X), framef, &pchan->size[0], NULL, NULL); - do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Y), framef, &pchan->size[1], NULL, NULL); - do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Z), framef, &pchan->size[2], NULL, NULL); - do_scale += do_x + do_y + do_z; - - if( ((icu_w = find_ipocurve(achan->ipo, AC_QUAT_W))) && - ((icu_x = find_ipocurve(achan->ipo, AC_QUAT_X))) && - ((icu_y = find_ipocurve(achan->ipo, AC_QUAT_Y))) && - ((icu_z = find_ipocurve(achan->ipo, AC_QUAT_Z))) ) - { - /* use the quatw keyframe as a basis for others */ - if (pose_relax_icu(icu_w, framef, NULL, &frame_prev, &frame_next)) { - /* get 2 quats */ - quat_prev[0] = eval_icu(icu_w, frame_prev); - quat_prev[1] = eval_icu(icu_x, frame_prev); - quat_prev[2] = eval_icu(icu_y, frame_prev); - quat_prev[3] = eval_icu(icu_z, frame_prev); - - quat_next[0] = eval_icu(icu_w, frame_next); - quat_next[1] = eval_icu(icu_x, frame_next); - quat_next[2] = eval_icu(icu_y, frame_next); - quat_next[3] = eval_icu(icu_z, frame_next); - -#if 0 - /* apply the setting, completely smooth */ - QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) ); -#else - /* tricky interpolation */ - QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) ); - QUATCOPY(quat_orig, pchan->quat); - QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f); - /* done */ -#endif - do_quat++; - } - } - - /* apply BONE_TRANSFORM tag so that autokeying will pick it up */ - pchan->bone->flag |= BONE_TRANSFORM; - } - -#endif // XXX old animation system - } - } - } - - ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); - - /* do auto-keying */ - if (do_loc) flag |= TFM_TRANSLATION; - if (do_scale) flag |= TFM_RESIZE; - if (do_quat) flag |= TFM_ROTATION; - autokeyframe_pose_cb_func(ob, flag, 0); - - /* clear BONE_TRANSFORM flags */ - for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) - pchan->bone->flag &= ~ BONE_TRANSFORM; - - /* do depsgraph flush */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - BIF_undo_push("Relax Pose"); -} - /* for use in insertkey, ensure rotation goes other way around */ void pose_flipquats(Scene *scene) { diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 0969398f1e2..51d7c664fba 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -119,5 +119,9 @@ void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); +/* Keyframe Finding */ +ActKeyColumn *cfra_find_actkeycolumn(ActKeyColumn *ak, float cframe); +ActKeyColumn *cfra_find_nearest_next_ak(ActKeyColumn *ak, float cframe, short next); + #endif /* ED_KEYFRAMES_DRAW_H */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b7e7fd18547..a055041d8ae 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1444,29 +1444,6 @@ static void SCREEN_OT_frame_jump(wmOperatorType *ot) /* ************** jump to keyframe operator ***************************** */ -/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */ -// TODO: make this an API func? -static ActKeyColumn *cfra_find_nearest_next_ak (ActKeyColumn *ak, float cframe, short next) -{ - ActKeyColumn *akn= NULL; - - /* sanity checks */ - if (ak == NULL) - return NULL; - - /* check if this is a match, or whether it is in some subtree */ - if (cframe < ak->cfra) - akn= cfra_find_nearest_next_ak(ak->left, cframe, next); - else if (cframe > ak->cfra) - akn= cfra_find_nearest_next_ak(ak->right, cframe, next); - - /* if no match found (or found match), just use the current one */ - if (akn == NULL) - return ak; - else - return akn; -} - /* function to be called outside UI context, or for redo */ static int keyframe_jump_exec(bContext *C, wmOperator *op) { -- cgit v1.2.3 From 1ec44f3bb2f371b4f4c389e5f0d4a0c655672c9a Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sat, 19 Sep 2009 01:05:16 +0000 Subject: compile fix --- source/blender/blenkernel/BKE_fcurve.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index e25e32a2010..94d0864024b 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -35,6 +35,8 @@ struct DriverTarget; struct BezTriple; +#include "DNA_curve_types.h" + /* ************** Keyframe Tools ***************** */ // XXX this stuff is defined in BKE_ipo.h too, so maybe skip for now? -- cgit v1.2.3 From 9710673192f5ed972343c8e9cc6438fc97eb573e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 19 Sep 2009 11:59:23 +0000 Subject: 2.5 - Animation Bugfixes: * Breakdown tool for Poses (Shift-E in PoseMode) now works. Now this works as a modal operator when invoked, with the horizontal movement of the mouse (left to right) corresponding the placement of the breakdown relative to the endpoint keyframes. * Moving bones between armature layers in Edit Mode didn't work (wrong variable name used) * Fixed several notifier-related bugs regarding editing armature settings and the 3d-view not refreshing * Duplicating bones preserves the rotation mode * Animation Data for Nodes is now show in Datablocks viewer (i.e. AnimData for NodeTrees has now been wrapped) --- source/blender/editors/animation/keyframes_draw.c | 1 + source/blender/editors/armature/editarmature.c | 3 + source/blender/editors/armature/poseSlide.c | 158 +++++++++++++++------ source/blender/editors/armature/poseobject.c | 4 +- source/blender/editors/space_view3d/space_view3d.c | 2 + source/blender/makesrna/intern/rna_nodetree.c | 2 + 6 files changed, 123 insertions(+), 47 deletions(-) diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 8e7789190c3..dcb37f4d2c4 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -332,6 +332,7 @@ ActKeyColumn *cfra_find_actkeycolumn (ActKeyColumn *ak, float cframe) } /* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */ +// FIXME: this is buggy... next() is ignored completely... ActKeyColumn *cfra_find_nearest_next_ak (ActKeyColumn *ak, float cframe, short next) { ActKeyColumn *akn= NULL; diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 7d196d23c98..394df8111d8 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -2630,6 +2630,9 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op) /* copy transform locks */ channew->protectflag = chanold->protectflag; + /* copy rotation mode */ + channew->rotmode = chanold->rotmode; + /* copy bone group */ channew->agrp_index= chanold->agrp_index; diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 464dbcba54b..bbc9ef4d09c 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -103,6 +103,7 @@ typedef struct tPoseSlideOp { Scene *scene; /* current scene */ ARegion *ar; /* region that we're operating in (needed for */ Object *ob; /* active object that Pose Info comes from */ + bArmature *arm; /* armature for pose */ ListBase pfLinks; /* links between posechannels and f-curves */ DLRBT_Tree keys; /* binary tree for quicker searching for keyframes (when applicable) */ @@ -151,6 +152,7 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode) /* get info from context */ pso->scene= CTX_data_scene(C); pso->ob= CTX_data_active_object(C); + pso->arm= (pso->ob)? pso->ob->data : NULL; pso->ar= CTX_wm_region(C); /* only really needed when doing modal() */ pso->cframe= pso->scene->r.cfra; @@ -162,7 +164,7 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode) pso->nextFrame= RNA_int_get(op->ptr, "next_frame"); /* check the settings from the context */ - if (ELEM3(NULL, pso->ob, pso->ob->adt, pso->ob->adt->action)) + if (ELEM4(NULL, pso->ob, pso->arm, pso->ob->adt, pso->ob->adt->action)) return 0; else act= pso->ob->adt->action; @@ -204,6 +206,11 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode) } CTX_DATA_END; + /* set depsgraph flags */ + /* make sure the lock is set OK, unlock can be accidentally saved? */ + pso->ob->pose->flag |= POSE_LOCKED; + pso->ob->pose->flag &= ~POSE_DO_UNLOCK; + /* do basic initialise of RB-BST used for finding keyframes, but leave the filling of it up * to the caller of this (usually only invoke() will do it, to make things more efficient). */ @@ -289,8 +296,8 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo /* using this path, find each matching F-Curve for the variables we're interested in */ while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) { FCurve *fcu= (FCurve *)ld->data; - float w1, w2, wtot, ctrl, ictrl; float sVal, eVal; + float w1, w2; int ch; /* get keyframe values for endpoint poses to blend with */ @@ -302,21 +309,26 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo /* get channel index */ ch= fcu->array_index; - /* get the influence of the control */ - ctrl= pso->percentage; - ictrl= 1.0f - pso->percentage; - - /* calculate the relative weights of the endpoints - * - these weights are derived from the relative distance of these - * poses from the current frame - * - they then get normalised, with the results of these normalised - */ - w1 = cframe - (float)pso->prevFrame; - w2 = (float)pso->nextFrame - cframe; - - wtot = w1 + w2; - w1 = w1/wtot; - w2 = w2/wtot; + /* calculate the relative weights of the endpoints */ + if (pso->mode == POSESLIDE_BREAKDOWN) { + /* get weights from the percentage control */ + w1= pso->percentage; /* this must come second */ + w2= 1.0f - w1; /* this must come first */ + } + else { + /* - these weights are derived from the relative distance of these + * poses from the current frame + * - they then get normalised so that they only sum up to 1 + */ + float wtot; + + w1 = cframe - (float)pso->prevFrame; + w2 = (float)pso->nextFrame - cframe; + + wtot = w1 + w2; + w1 = (w1/wtot); + w2 = (w2/wtot); + } /* depending on the mode, */ switch (pso->mode) { @@ -332,10 +344,8 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo break; case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */ - // NOTE: just linear interpolation for now, but could add small component of our key if necessary... - // TODO: this doesn't work at all - w2= 1.0f - w1; - vec[ch]= ((sVal * w1) + (eVal * w2)); + /* perform simple linear interpolation - coefficient for start must come from pso->percentage... */ + vec[ch]= ((sVal * w2) + (eVal * w1)); break; } @@ -449,15 +459,18 @@ static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso) } } - /* funky depsgraph flags - are these still needed? */ - pso->ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); - - /* do depsgraph flush */ - DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); + /* old optimize trick... this enforces to bypass the depgraph + * - note: code copied from transform_generics.c -> recalcData() + */ + // FIXME: shouldn't this use the builtin stuff? + if ((pso->arm->flag & ARM_DELAYDEFORM)==0) + DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); /* sets recalc flags */ + else + where_is_pose(pso->scene, pso->ob); /* note, notifier might evolve */ - //WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, pso->ob); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); } /* ------------------------------------ */ @@ -482,7 +495,7 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * /* consolidate these keyframes, and figure out the nearest ones */ BLI_dlrbTree_linkedlist_sync(&pso->keys); - /* cancel if no keyframes found... */ + /* cancel if no keyframes found... */ if (pso->keys.root) { ActKeyColumn *ak; @@ -491,14 +504,24 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * if (ak == NULL) { /* current frame is not a keyframe, so search */ + ActKeyColumn *pk= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 0); + ActKeyColumn *nk= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 1); + + /* check if we found good keyframes */ + if ((pk == nk) && (pk != NULL)) { + if (pk->cfra < pso->cframe) + nk= nk->next; + else if (nk->cfra > pso->cframe) + pk= pk->prev; + } + + /* new set the frames */ /* prev frame */ - ak= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 0); - pso->prevFrame= (ak)? (ak->cfra) : (pso->cframe - 1); + pso->prevFrame= (pk)? (pk->cfra) : (pso->cframe - 1); RNA_int_set(op->ptr, "prev_frame", pso->prevFrame); /* next frame */ - ak= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 1); - pso->nextFrame= (ak)? (ak->cfra) : (pso->cframe + 1); - RNA_int_set(op->ptr, "next_frame", pso->prevFrame); + pso->nextFrame= (nk)? (nk->cfra) : (pso->cframe + 1); + RNA_int_set(op->ptr, "next_frame", pso->nextFrame); } else { /* current frame itself is a keyframe, so just take keyframes on either side */ @@ -515,18 +538,63 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * return OPERATOR_CANCELLED; } + // FIXME: for now, just do modal for breakdowns... + if (pso->mode == POSESLIDE_BREAKDOWN) { + /* initial apply for operator... */ + pose_slide_apply(C, op, pso); + + /* add a modal handler for this operator */ + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; + } + else { + /* temp static operator code... until a way to include percentage in the formulation comes up */ + pose_slide_apply(C, op, pso); + pose_slide_exit(C, op); + return OPERATOR_FINISHED; + } +} + +/* common code for modal() */ +static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt) +{ + tPoseSlideOp *pso= op->customdata; - // TODO ----------------------------------- - // from here on, we should just invoke the modal operator, but for now, just do static... + switch (evt->type) { + case LEFTMOUSE: /* confirm */ + pose_slide_exit(C, op); + return OPERATOR_FINISHED; + + case ESCKEY: /* cancel */ + case RIGHTMOUSE: + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; + + case MOUSEMOVE: /* calculate new position */ + { + /* calculate percentage based on position of mouse (we only use x-axis for now. + * since this is more conveninent for users to do), and store new percentage value + */ + pso->percentage= (evt->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx); + RNA_float_set(op->ptr, "percentage", pso->percentage); + + /* apply... */ + pose_slide_apply(C, op, pso); + } + break; + } - /* temp static operator code... */ - pose_slide_apply(C, op, pso); - pose_slide_exit(C, op); - return OPERATOR_FINISHED; + /* still running... */ + return OPERATOR_RUNNING_MODAL; } -// TODO: common modal + cancel - +/* common code for cancel() */ +static int pose_slide_cancel (bContext *C, wmOperator *op) +{ + /* cleanup and done */ + pose_slide_exit(C, op); + return OPERATOR_CANCELLED; +} /* common code for exec() methods */ static int pose_slide_exec_common (bContext *C, wmOperator *op, tPoseSlideOp *pso) @@ -708,12 +776,12 @@ void POSE_OT_breakdown (wmOperatorType *ot) /* callbacks */ ot->exec= pose_slide_breakdown_exec; ot->invoke= pose_slide_breakdown_invoke; - //ot->modal= pose_slide_modal; - //ot->cancel= pose_slide_cancel; + ot->modal= pose_slide_modal; + ot->cancel= pose_slide_cancel; ot->poll= ED_operator_posemode; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* Properties */ pose_slide_opdef_properties(ot); diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index e5a7a1e167d..305e153f805 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1942,7 +1942,7 @@ static int armature_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *ev /* Set the visible layers for the active armature (edit and pose modes) */ static int armature_bone_layers_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= CTX_data_edit_object(C); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[16]; /* hardcoded for now - we can only have 16 armature layers, so this should be fine... */ @@ -1955,7 +1955,7 @@ static int armature_bone_layers_exec (bContext *C, wmOperator *op) { /* get pointer for pchan, and write flags this way */ RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr); - RNA_boolean_set_array(&ptr, "layers", layers); + RNA_boolean_set_array(&ptr, "layer", layers); } CTX_DATA_END; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 5ea633a47f7..a73a16f38ba 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -420,6 +420,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_TRANSFORM: + case ND_POSE: case ND_DRAW: case ND_MODIFIER: case ND_CONSTRAINT: @@ -560,6 +561,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) case ND_BONE_ACTIVE: case ND_BONE_SELECT: case ND_TRANSFORM: + case ND_POSE: case ND_DRAW: case ND_KEYS: ED_region_tag_redraw(ar); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 73aaf0837db..b310ff06b8e 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1660,6 +1660,8 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Node Tree", "Node tree consisting of linked nodes used for materials, textures and compositing."); RNA_def_struct_sdna(srna, "bNodeTree"); RNA_def_struct_ui_icon(srna, ICON_NODE); + + rna_def_animdata_common(srna); prop = RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL); -- cgit v1.2.3 From 7eb436a6b85156c56dc842ff4289e5a3e2b7b5e9 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 19 Sep 2009 12:36:22 +0000 Subject: 2.5 - More Animation Bugfixes * Updating Preview Range settings results in correct updates for Animation Editors * Compositing nodes now correctly animate when the values were set by IKEY/RMB on suitable node parameters. Beware that these nodes are not relinkable node-trees, hence the standard code not working. * Ctrl-P to parent objects to bones now works in Pose Mode too. I needed to add a special keymap entry for this, though I thought this would have been better to be automatically inherited/present from Object keymap already? * Ctrl-P -> Parent to Bone option now works correctly again. 1.5 lines of code missing here... * Breakdowns tool now shows custom cursor during 'modal' phase so that it's not that confusing what's going on. --- source/blender/blenkernel/intern/anim_sys.c | 18 +++++++++++++++++- source/blender/editors/armature/armature_ops.c | 4 +++- source/blender/editors/armature/poseSlide.c | 7 +++++++ source/blender/editors/object/object_relations.c | 2 ++ source/blender/editors/space_action/space_action.c | 1 + source/blender/editors/space_graph/space_graph.c | 1 + source/blender/editors/space_nla/space_nla.c | 1 + 7 files changed, 32 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 522297da1d7..8b761a2ee0e 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -40,6 +40,7 @@ #include "BLI_dynstr.h" #include "DNA_anim_types.h" +#include "DNA_scene_types.h" #include "BKE_animsys.h" #include "BKE_action.h" @@ -1517,7 +1518,10 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) AnimData *adt= BKE_animdata_from_id(id); Curve *cu= (Curve *)id; + /* set ctime variable for curve */ cu->ctime= ctime; + + /* now execute animation data on top of this as per normal */ BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM); } @@ -1537,7 +1541,19 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM); /* scenes */ - EVAL_ANIM_IDS(main->scene.first, ADT_RECALC_ANIM); + for (id= main->scene.first; id; id= id->next) { + AnimData *adt= BKE_animdata_from_id(id); + Scene *scene= (Scene *)id; + + /* do compositing nodes first (since these aren't included in main tree) */ + if (scene->nodetree) { + AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree); + BKE_animsys_evaluate_animdata((ID *)scene->nodetree, adt2, ctime, ADT_RECALC_ANIM); + } + + /* now execute scene animation data as per normal */ + BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM); + } } /* ***************************************** */ diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index a8b8b8aecc1..fae0b093551 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -298,6 +298,9 @@ void ED_keymap_armature(wmWindowManager *wm) keymap= WM_keymap_find(wm, "Pose", 0, 0); keymap->poll= ED_operator_posemode; + // XXX: set parent is object-based operator, but it should also be available here... + WM_keymap_add_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0); kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "unselected", 1); @@ -310,7 +313,6 @@ void ED_keymap_armature(wmWindowManager *wm) WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0); - // for now, we include hotkeys for copy/paste WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0); kmi= WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index bbc9ef4d09c..e55c5608112 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -480,6 +480,7 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * { tPChanFCurveLink *pfl; AnimData *adt= pso->ob->adt; + wmWindow *win= CTX_wm_window(C); /* for each link, add all its keyframes to the search tree */ for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) { @@ -543,6 +544,9 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * /* initial apply for operator... */ pose_slide_apply(C, op, pso); + /* set cursor to indicate modal */ + WM_cursor_modal(win, BC_EW_SCROLLCURSOR); + /* add a modal handler for this operator */ WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; @@ -559,14 +563,17 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt) { tPoseSlideOp *pso= op->customdata; + wmWindow *win= CTX_wm_window(C); switch (evt->type) { case LEFTMOUSE: /* confirm */ + WM_cursor_restore(win); pose_slide_exit(C, op); return OPERATOR_FINISHED; case ESCKEY: /* cancel */ case RIGHTMOUSE: + WM_cursor_restore(win); pose_slide_exit(C, op); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 12cb2b95e06..65061e8dfb9 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -647,6 +647,8 @@ static int parent_set_exec(bContext *C, wmOperator *op) if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) ob->partype= PARSKEL; /* note, dna define, not operator property */ + else if (partype == PAR_BONE) + ob->partype= PARBONE; /* note, dna define, not operator property */ else ob->partype= PAROBJECT; /* note, dna define, not operator property */ } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index bceee73d5f0..3b275cab814 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -323,6 +323,7 @@ static void action_main_area_listener(ARegion *ar, wmNotifier *wmn) break; case NC_SCENE: switch(wmn->data) { + case ND_RENDER_OPTIONS: case ND_OB_ACTIVE: case ND_FRAME: case ND_MARKERS: diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index e0b961b38f1..a7ea2294ed4 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -374,6 +374,7 @@ static void graph_region_listener(ARegion *ar, wmNotifier *wmn) break; case NC_SCENE: switch(wmn->data) { + case ND_RENDER_OPTIONS: case ND_OB_ACTIVE: case ND_FRAME: case ND_MARKERS: diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 06ee34a6573..41435810889 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -409,6 +409,7 @@ static void nla_main_area_listener(ARegion *ar, wmNotifier *wmn) break; case NC_SCENE: switch(wmn->data) { + case ND_RENDER_OPTIONS: case ND_OB_ACTIVE: case ND_FRAME: case ND_MARKERS: -- cgit v1.2.3 From 645ca520a313a9881ee77556fc85820e74f83887 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sat, 19 Sep 2009 13:50:24 +0000 Subject: Armature UI Added the new pose tools in the toolbar. Changed a few armature values to enums. Brecht: The Heads/Tails enum seems to also enable armature.draw_axis, and the paths_type enum affects armature.draw_names --- release/ui/buttons_data_armature.py | 20 +++++++----- release/ui/space_view3d_toolbar.py | 8 +++-- source/blender/makesrna/intern/rna_armature.c | 45 +++++++++++++++++---------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index 5924a2eb4ea..49da9c190ff 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -121,28 +121,31 @@ class DATA_PT_paths(DataButtonsPanel): layout = self.layout arm = context.armature - + + layout.itemR(arm, "paths_type", expand=True) + split = layout.split() col = split.column() - col.itemR(arm, "paths_show_around_current_frame", text="Around Frame") sub = col.column(align=True) - if (arm.paths_show_around_current_frame): + if (arm.paths_type == 'CURRENT_FRAME'): sub.itemR(arm, "path_before_current", text="Before") sub.itemR(arm, "path_after_current", text="After") - else: + elif (arm.paths_type == 'RANGE'): sub.itemR(arm, "path_start_frame", text="Start") sub.itemR(arm, "path_end_frame", text="End") - sub.itemR(arm, "path_size", text="Step") - col.itemR(arm, "paths_calculate_head_positions", text="Head") + sub.itemR(arm, "path_size", text="Step") + col.row().itemR(arm, "paths_location", expand=True) col = split.column() col.itemL(text="Show:") col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers") col.itemR(arm, "paths_highlight_keyframes", text="Keyframes") col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers") + + layout.itemO("pose.paths_calculate") class DATA_PT_ghost(DataButtonsPanel): __label__ = "Ghost" @@ -151,11 +154,12 @@ class DATA_PT_ghost(DataButtonsPanel): layout = self.layout arm = context.armature - + + layout.itemR(arm, "ghost_type", expand=True) + split = layout.split() col = split.column() - col.itemR(arm, "ghost_type", text="") sub = col.column(align=True) if arm.ghost_type == 'RANGE': diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 9492437b863..415a3e223bb 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -299,11 +299,13 @@ class VIEW3D_PT_tools_posemode(View3DPanel): col.itemL(text="Pose:") col.itemO("pose.copy", text="Copy") col.itemO("pose.paste", text="Paste") + col.itemO("poselib.pose_add", text="Add To library") col = layout.column(align=True) - col.itemL(text="Library:") - col.itemO("poselib.pose_add", text="Add") - col.itemO("poselib.pose_remove", text="Remove") + col.itemL(text="In-Between:") + col.itemO("pose.relax", text="Relax") + col.itemO("pose.push", text="Push") + col.itemO("pose.breakdown", text="Breakdowner") col = layout.column(align=True) col.itemL(text="Repeat:") diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index dcf89b7ac1e..c271b34b6d4 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -526,15 +526,24 @@ static void rna_def_armature(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem prop_drawtype_items[] = { - {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Draw bones as octahedral shape (default)."}, - {ARM_LINE, "STICK", 0, "Stick", "Draw bones as simple 2D lines with dots."}, - {ARM_B_BONE, "BBONE", 0, "B-Bone", "Draw bones as boxes, showing subdivision and B-Splines"}, - {ARM_ENVELOPE, "ENVELOPE", 0, "Envelope", "Draw bones as extruded spheres, showing defomation influence volume."}, + {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Display bones as octahedral shape (default)."}, + {ARM_LINE, "STICK", 0, "Stick", "Display bones as simple 2D lines with dots."}, + {ARM_B_BONE, "BBONE", 0, "B-Bone", "Display bones as boxes, showing subdivision and B-Splines"}, + {ARM_ENVELOPE, "ENVELOPE", 0, "Envelope", "Display bones as extruded spheres, showing defomation influence volume."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem prop_ghost_type_items[] = { - {ARM_GHOST_CUR, "CURRENT_FRAME", 0, "Around Current Frame", "Draw Ghosts of poses within a fixed number of frames around the current frame."}, - {ARM_GHOST_RANGE, "RANGE", 0, "In Range", "Draw Ghosts of poses within specified range."}, - {ARM_GHOST_KEYS, "KEYS", 0, "On Keyframes", "Draw Ghosts of poses on Keyframes."}, + {ARM_GHOST_CUR, "CURRENT_FRAME", 0, "Around Frame", "Display Ghosts of poses within a fixed number of frames around the current frame."}, + {ARM_GHOST_RANGE, "RANGE", 0, "In Range", "Display Ghosts of poses within specified range."}, + {ARM_GHOST_KEYS, "KEYS", 0, "On Keyframes", "Display Ghosts of poses on Keyframes."}, + {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_paths_type_items[]= { + {ARM_PATH_ACFRA, "CURRENT_FRAME", 0, "Around Frame", "Display Paths of poses within a fixed number of frames around the current frame."}, + {0, "RANGE", 0, "In Range", "Display Paths of poses within specified range."}, + {0, NULL, 0, NULL, NULL}}; + + static const EnumPropertyItem prop_paths_location_items[]= { + {ARM_PATH_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"}, + {0, "TIPS", 0, "Tips", "Calculate bone paths from tips"}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Armature", "ID"); @@ -564,7 +573,19 @@ static void rna_def_armature(BlenderRNA *brna) prop= RNA_def_property(srna, "ghost_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "ghosttype"); RNA_def_property_enum_items(prop, prop_ghost_type_items); - RNA_def_property_ui_text(prop, "Ghost Drawing", "Method of Onion-skinning for active Action"); + RNA_def_property_ui_text(prop, "Ghost Type", "Method of Onion-skinning for active Action"); + RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); + + prop= RNA_def_property(srna, "paths_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_paths_type_items); + RNA_def_property_ui_text(prop, "Paths Type", "Mapping type to use for this image in the game engine."); + RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); + + prop= RNA_def_property(srna, "paths_location", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_paths_location_items); + RNA_def_property_ui_text(prop, "Paths Location", "When calculating Bone Paths, use Head or Tips"); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); /* Boolean values */ @@ -672,15 +693,7 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Paths Show Keyframe Numbers", "When drawing Armature in Pose Mode, show frame numbers of Keyframes on Bone Paths"); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); - prop= RNA_def_property(srna, "paths_show_around_current_frame", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pathflag", ARM_PATH_ACFRA); - RNA_def_property_ui_text(prop, "Paths Around Current Frame", "When drawing Armature in Pose Mode, only show section of Bone Paths that falls around current frame"); - RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); - prop= RNA_def_property(srna, "paths_calculate_head_positions", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pathflag", ARM_PATH_HEADS); - RNA_def_property_ui_text(prop, "Paths Use Heads", "When calculating Bone Paths, use Head locations instead of Tips"); - RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); /* Number fields */ /* ghost/onionskining settings */ -- cgit v1.2.3 From d25ab89ac08db7598a62614b537ae4679f26a86d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 19 Sep 2009 14:16:02 +0000 Subject: RNA: for last commit, fix paths_location and paths_type enums, these had wrong DNA variable name already before this change. --- source/blender/makesrna/intern/rna_armature.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index c271b34b6d4..aa422f85d7b 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -577,13 +577,13 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); prop= RNA_def_property(srna, "paths_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "pathflag"); RNA_def_property_enum_items(prop, prop_paths_type_items); RNA_def_property_ui_text(prop, "Paths Type", "Mapping type to use for this image in the game engine."); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); prop= RNA_def_property(srna, "paths_location", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "pathflag"); RNA_def_property_enum_items(prop, prop_paths_location_items); RNA_def_property_ui_text(prop, "Paths Location", "When calculating Bone Paths, use Head or Tips"); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); -- cgit v1.2.3 From fcbfd2979644d1b0eac963d49ee9f0e8f38d9f5b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 19 Sep 2009 15:48:47 +0000 Subject: Fix combined pose + weight paint mode, was using wrong object in a few places, missing some checks. --- source/blender/editors/armature/editarmature.c | 2 +- source/blender/editors/space_view3d/drawarmature.c | 10 +++++++--- source/blender/editors/space_view3d/view3d_select.c | 2 +- source/blender/editors/transform/transform_conversions.c | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 394df8111d8..80f8c2b07aa 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4333,7 +4333,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor } /* in weightpaint we select the associated vertex group too */ - if (ob->mode & OB_MODE_WEIGHT_PAINT) { + if (OBACT && OBACT->mode & OB_MODE_WEIGHT_PAINT) { if (nearBone->flag & BONE_ACTIVE) { ED_vgroup_select_by_name(OBACT, nearBone->name); DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index fa810677fe8..497091f2660 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -2513,7 +2513,11 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int /* drawing posemode selection indices or colors only in these cases */ if(!(base->flag & OB_FROMDUPLI)) { if(G.f & G_PICKSEL) { - if(ob->mode & OB_MODE_POSE) + if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { + if(ob==modifiers_isDeformedByArmature(OBACT)) + arm->flag |= ARM_POSEMODE; + } + else if(ob->mode & OB_MODE_POSE) arm->flag |= ARM_POSEMODE; } else if(ob->mode & OB_MODE_POSE) { @@ -2530,8 +2534,8 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int if ((flag & DRAW_SCENESET)==0) { if(ob==OBACT) arm->flag |= ARM_POSEMODE; - else if(ob->mode & OB_MODE_WEIGHT_PAINT) { - if(OBACT && ob==modifiers_isDeformedByArmature(OBACT)) + else if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { + if(ob==modifiers_isDeformedByArmature(OBACT)) arm->flag |= ARM_POSEMODE; } draw_pose_paths(scene, v3d, rv3d, ob); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index b1fec793b09..a37e916064c 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1148,7 +1148,7 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter, WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object); /* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */ - if(basact->object->mode & OB_MODE_WEIGHT_PAINT) { + if(BASACT && BASACT->object->mode & OB_MODE_WEIGHT_PAINT) { /* prevent activating */ basact= NULL; } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 776f2e47d1e..e59ec3746e3 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5289,7 +5289,7 @@ void createTransData(bContext *C, TransInfo *t) { if(ob_armature->type==OB_ARMATURE) { - if(ob_armature->mode & OB_MODE_POSE) + if((ob_armature->mode & OB_MODE_POSE) && ob_armature == modifiers_isDeformedByArmature(ob)) { createTransPose(C, t, ob_armature); break; -- cgit v1.2.3 From 01ef3301a81b18fb40257161d7d0c5daa9a1f024 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 19 Sep 2009 18:45:31 +0000 Subject: Fix drawing of armature bone axes, these were not showing labels. Also unified drawing code for object & particle text, was almost the same function duplicated, and now also used for bones. --- source/blender/editors/space_view3d/drawarmature.c | 107 +++++++----- source/blender/editors/space_view3d/drawobject.c | 179 ++++++++------------- .../blender/editors/space_view3d/view3d_intern.h | 7 +- 3 files changed, 138 insertions(+), 155 deletions(-) diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 497091f2660..028d666dc71 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -639,7 +639,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag /* figure out the sizes of spheres */ if (ebone) { - /* this routine doesn't call set_matrix_editbone() that calculates it */ + /* this routine doesn't call get_matrix_editbone() that calculates it */ ebone->length = VecLenf(ebone->head, ebone->tail); length= ebone->length; @@ -749,7 +749,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, /* figure out the sizes of spheres */ if (ebone) { - /* this routine doesn't call set_matrix_editbone() that calculates it */ + /* this routine doesn't call get_matrix_editbone() that calculates it */ ebone->length = VecLenf(ebone->head, ebone->tail); length= ebone->length; @@ -1516,15 +1516,25 @@ static void draw_pose_dofs(Object *ob) } } +static void bone_matrix_translate_y(float mat[][4], float y) +{ + float trans[3]; + + VECCOPY(trans, mat[1]); + VecMulf(trans, y); + VecAddf(mat[3], mat[3], trans); +} + /* assumes object is Armature with pose */ -static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt) { + RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; bArmature *arm= ob->data; bPoseChannel *pchan; Bone *bone; GLfloat tmp; - float smat[4][4], imat[4][4]; + float smat[4][4], imat[4][4], bmat[4][4]; int index= -1; short do_dashed= 3, draw_wire= 0; short flag, constflag; @@ -1809,15 +1819,21 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba /* Draw names of bone */ if (arm->flag & ARM_DRAWNAMES) { VecMidf(vec, pchan->pose_head, pchan->pose_tail); - view3d_object_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10); + view3d_cached_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10); } /* Draw additional axes on the bone tail */ if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) { glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - glTranslatef(0.0f, pchan->bone->length, 0.0f); - drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS); + Mat4CpyMat4(bmat, pchan->pose_mat); + bone_matrix_translate_y(bmat, pchan->bone->length); + glMultMatrixf(bmat); + + /* do cached text draw immediate to include transform */ + view3d_cached_text_draw_begin(); + drawaxes(pchan->bone->length*0.25f, 0, OB_ARROWS); + view3d_cached_text_draw_end(v3d, ar, 1, bmat); + glPopMatrix(); } } @@ -1830,32 +1846,28 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba } /* in editmode, we don't store the bone matrix... */ -static void set_matrix_editbone(EditBone *eBone) +static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) { - float delta[3],offset[3]; - float mat[3][3], bmat[4][4]; + float delta[3]; + float mat[3][3]; /* Compose the parent transforms (i.e. their translations) */ - VECCOPY(offset, eBone->head); - - glTranslatef(offset[0],offset[1],offset[2]); - VecSubf(delta, eBone->tail, eBone->head); eBone->length = (float)sqrt(delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]); vec_roll_to_mat3(delta, eBone->roll, mat); Mat4CpyMat3(bmat, mat); - - glMultMatrixf(bmat); - + + VecAddf(bmat[3], bmat[3], eBone->head); } -static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) +static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) { + RegionView3D *rv3d= ar->regiondata; EditBone *eBone; bArmature *arm= ob->data; - float smat[4][4], imat[4][4]; + float smat[4][4], imat[4][4], bmat[4][4]; unsigned int index; int flag; @@ -1893,7 +1905,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) if (eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A)==0) { glPushMatrix(); - set_matrix_editbone(eBone); + get_matrix_editbone(eBone, bmat); + glMultMatrixf(bmat); /* catch exception for bone with hidden parent */ flag= eBone->flag; @@ -1941,7 +1954,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) } else { glPushMatrix(); - set_matrix_editbone(eBone); + get_matrix_editbone(eBone, bmat); + glMultMatrixf(bmat); if (arm->drawtype == ARM_LINE) draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); @@ -1994,14 +2008,20 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) if (arm->flag & ARM_DRAWNAMES) { VecMidf(vec, eBone->head, eBone->tail); glRasterPos3fv(vec); - view3d_object_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10); + view3d_cached_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10); } /* Draw additional axes */ if (arm->flag & ARM_DRAWAXES) { glPushMatrix(); - set_matrix_editbone(eBone); - glTranslatef(0.0f, eBone->length, 0.0f); + get_matrix_editbone(eBone, bmat); + bone_matrix_translate_y(bmat, eBone->length); + glMultMatrixf(bmat); + + /* do cached text draw immediate to include transform */ + view3d_cached_text_draw_begin(); drawaxes(eBone->length*0.25f, 0, OB_ARROWS); + view3d_cached_text_draw_end(v3d, ar, 1, bmat); + glPopMatrix(); } @@ -2021,8 +2041,9 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt) /* draw bone paths * - in view space */ -static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) +static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) { + RegionView3D *rv3d= ar->regiondata; AnimData *adt= BKE_animdata_from_id(&ob->id); bArmature *arm= ob->data; bPoseChannel *pchan; @@ -2155,12 +2176,12 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* only draw framenum if several consecutive highlighted points don't occur on same point */ if (a == 0) { sprintf(str, "%d", (a+sfra)); - view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0); + view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); } else if ((a > stepsize) && (a < len-stepsize)) { if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) { sprintf(str, "%d", (a+sfra)); - view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0); + view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); } } } @@ -2202,7 +2223,7 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec char str[32]; sprintf(str, "%d", (a+sfra)); - view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0); + view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); } } } @@ -2253,7 +2274,7 @@ static void ghost_poses_tag_unselected(Object *ob, short unset) /* draw ghosts that occur within a frame range * note: object should be in posemode */ -static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { Object *ob= base->object; AnimData *adt= BKE_animdata_from_id(&ob->id); @@ -2295,7 +2316,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2315,7 +2336,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d /* draw ghosts on keyframes in action within range * - object should be in posemode */ -static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { Object *ob= base->object; AnimData *adt= BKE_animdata_from_id(&ob->id); @@ -2374,7 +2395,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2394,7 +2415,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, /* draw ghosts around current frame * - object is supposed to be armature in posemode */ -static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { Object *ob= base->object; AnimData *adt= BKE_animdata_from_id(&ob->id); @@ -2444,7 +2465,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } } @@ -2459,7 +2480,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL); where_is_pose(scene, ob); - draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE); + draw_pose_channels(scene, v3d, ar, base, OB_WIRE); } } } @@ -2480,7 +2501,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base /* ********************************** Armature Drawing - Main ************************* */ /* called from drawobject.c, return 1 if nothing was drawn */ -int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag) { Object *ob= base->object; bArmature *arm= ob->data; @@ -2504,7 +2525,7 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int /* editmode? */ if(arm->edbo) { arm->flag |= ARM_EDITMODE; - draw_ebones(v3d, rv3d, ob, dt); + draw_ebones(v3d, ar, ob, dt); arm->flag &= ~ARM_EDITMODE; } else{ @@ -2522,14 +2543,14 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int } else if(ob->mode & OB_MODE_POSE) { if (arm->ghosttype == ARM_GHOST_RANGE) { - draw_ghost_poses_range(scene, v3d, rv3d, base); + draw_ghost_poses_range(scene, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_KEYS) { - draw_ghost_poses_keys(scene, v3d, rv3d, base); + draw_ghost_poses_keys(scene, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_CUR) { if (arm->ghostep) - draw_ghost_poses(scene, v3d, rv3d, base); + draw_ghost_poses(scene, v3d, ar, base); } if ((flag & DRAW_SCENESET)==0) { if(ob==OBACT) @@ -2538,11 +2559,11 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int if(ob==modifiers_isDeformedByArmature(OBACT)) arm->flag |= ARM_POSEMODE; } - draw_pose_paths(scene, v3d, rv3d, ob); + draw_pose_paths(scene, v3d, ar, ob); } } } - draw_pose_channels(scene, v3d, rv3d, base, dt); + draw_pose_channels(scene, v3d, ar, base, dt); arm->flag &= ~ARM_POSEMODE; if(ob->mode & OB_MODE_POSE) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index b8852486dea..60ae91e7a89 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -434,11 +434,11 @@ void drawaxes(float size, int flag, char drawtype) // patch for 3d cards crashing on glSelect for text drawing (IBM) if((flag & DRAW_PICKING) == 0) { if (axis==0) - view3d_object_text_draw_add(v2[0], v2[1], v2[2], "x", 0); + view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "x", 0); else if (axis==1) - view3d_object_text_draw_add(v2[0], v2[1], v2[2], "y", 0); + view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "y", 0); else - view3d_object_text_draw_add(v2[0], v2[1], v2[2], "z", 0); + view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "z", 0); } } break; @@ -496,23 +496,32 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se if(v3d->zbuf) glDepthFunc(GL_LEQUAL); } -/* *********** text drawing for object ************* */ -static ListBase strings= {NULL, NULL}; +/* *********** text drawing for object/particles/armature ************* */ -typedef struct ViewObjectString { - struct ViewObjectString *next, *prev; +static ListBase CachedText[3]; +static int CachedTextLevel= 0; + +typedef struct ViewCachedString { + struct ViewCachedString *next, *prev; float vec[3], col[4]; char str[128]; short mval[2]; short xoffs; -} ViewObjectString; +} ViewCachedString; +void view3d_cached_text_draw_begin() +{ + ListBase *strings= &CachedText[CachedTextLevel]; + strings->first= strings->last= NULL; + CachedTextLevel++; +} -void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs) +void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs) { - ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString"); + ListBase *strings= &CachedText[CachedTextLevel-1]; + ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString"); - BLI_addtail(&strings, vos); + BLI_addtail(strings, vos); BLI_strncpy(vos->str, str, 128); vos->vec[0]= x; vos->vec[1]= y; @@ -521,22 +530,23 @@ void view3d_object_text_draw_add(float x, float y, float z, char *str, short xof vos->xoffs= xoffs; } -static void view3d_object_text_draw(View3D *v3d, ARegion *ar) +void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]) { - ViewObjectString *vos; - int tot= 0; + RegionView3D *rv3d= ar->regiondata; + ListBase *strings= &CachedText[CachedTextLevel-1]; + ViewCachedString *vos; + int a, tot= 0; /* project first and test */ - for(vos= strings.first; vos; vos= vos->next) { + for(vos= strings->first; vos; vos= vos->next) { + if(mat) + Mat4MulVecfl(mat, vos->vec); view3d_project_short_clip(ar, vos->vec, vos->mval); if(vos->mval[0]!=IS_CLIPPED) tot++; } - + if(tot) { - RegionView3D *rv3d= ar->regiondata; - int a; - if(rv3d->rflag & RV3D_CLIPPING) for(a=0; a<6; a++) glDisable(GL_CLIP_PLANE0+a); @@ -544,16 +554,22 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar) wmPushMatrix(); ED_region_pixelspace(ar); - if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + if(depth_write) { + if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + } + else glDepthMask(0); - for(vos= strings.first; vos; vos= vos->next) { + for(vos= strings->first; vos; vos= vos->next) { if(vos->mval[0]!=IS_CLIPPED) { glColor3fv(vos->col); - BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 0.0, vos->str); + BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str); } } - if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + if(depth_write) { + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + } + else glDepthMask(1); wmPopMatrix(); @@ -562,10 +578,14 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar) glEnable(GL_CLIP_PLANE0+a); } - if(strings.first) - BLI_freelistN(&strings); + if(strings->first) + BLI_freelistN(strings); + + CachedTextLevel--; } +/* ******************** primitive drawing ******************* */ + static void drawcube(void) { @@ -1912,7 +1932,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else sprintf(val, conv_float, VecLenf(v1, v2)); - view3d_object_text_draw_add(x, y, z, val, 0); + view3d_cached_text_draw_add(x, y, z, val, 0); } } } @@ -1951,7 +1971,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else sprintf(val, conv_float, area); - view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); + view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); } } } @@ -1993,13 +2013,13 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E /* Vec 1 */ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2))); VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f); - view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); + view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0); } if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) { /* Vec 2 */ sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3))); VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) { /* Vec 3 */ @@ -2008,14 +2028,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E else sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1))); VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } /* Vec 4 */ if(efa->v4) { if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) { sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1))); VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f); - view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); + view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0); } } } @@ -2905,75 +2925,8 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas return retval; } -/* *********** text drawing for particles ************* */ -static ListBase pstrings= {NULL, NULL}; - -typedef struct ViewParticleString { - struct ViewParticleString *next, *prev; - float vec[3], col[4]; - char str[128]; - short mval[2]; - short xoffs; -} ViewParticleString; - - -void view3d_particle_text_draw_add(float x, float y, float z, char *str, short xoffs) -{ - ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString"); - - BLI_addtail(&pstrings, vos); - BLI_strncpy(vos->str, str, 128); - vos->vec[0]= x; - vos->vec[1]= y; - vos->vec[2]= z; - glGetFloatv(GL_CURRENT_COLOR, vos->col); - vos->xoffs= xoffs; -} - -static void view3d_particle_text_draw(View3D *v3d, ARegion *ar) -{ - ViewObjectString *vos; - int tot= 0; - - /* project first and test */ - for(vos= pstrings.first; vos; vos= vos->next) { - project_short(ar, vos->vec, vos->mval); - if(vos->mval[0]!=IS_CLIPPED) - tot++; - } - - if(tot) { - RegionView3D *rv3d= ar->regiondata; - int a; - - if(rv3d->rflag & RV3D_CLIPPING) - for(a=0; a<6; a++) - glDisable(GL_CLIP_PLANE0+a); - - wmPushMatrix(); - ED_region_pixelspace(ar); - - if(v3d->zbuf) glDepthMask(0); - - for(vos= pstrings.first; vos; vos= vos->next) { - if(vos->mval[0]!=IS_CLIPPED) { - glColor3fv(vos->col); - BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 2.0, vos->str); - } - } - - if(v3d->zbuf) glDepthMask(1); - - wmPopMatrix(); +/* *********** drawing for particles ************* */ - if(rv3d->rflag & RV3D_CLIPPING) - for(a=0; a<6; a++) - glEnable(GL_CLIP_PLANE0+a); - } - - if(pstrings.first) - BLI_freelistN(&pstrings); -} static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd) { float vec[3], vec2[3]; @@ -3540,7 +3493,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv sprintf(val, "%s %.2f", val, pa_health); /* in path drawing state.co is the end point */ - view3d_particle_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); + view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); } } } @@ -4755,8 +4708,9 @@ static void drawtexspace(Object *ob) } /* draws wire outline */ -static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) +static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) { + RegionView3D *rv3d= ar->regiondata; Object *ob= base->object; glLineWidth(2.0); @@ -4775,7 +4729,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base } else if(ob->type==OB_ARMATURE) { if(!(ob->mode & OB_MODE_POSE)) - draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0); + draw_armature(scene, v3d, ar, base, OB_WIRE, 0); } glLineWidth(1.0); @@ -4885,11 +4839,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data) glVertex3fv(v); glEnd(); if (axis==0) - view3d_object_text_draw_add(v[0], v[1], v[2], "px", 0); + view3d_cached_text_draw_add(v[0], v[1], v[2], "px", 0); else if (axis==1) - view3d_object_text_draw_add(v[0], v[1], v[2], "py", 0); + view3d_cached_text_draw_add(v[0], v[1], v[2], "py", 0); else - view3d_object_text_draw_add(v[0], v[1], v[2], "pz", 0); + view3d_cached_text_draw_add(v[0], v[1], v[2], "pz", 0); } glLineWidth (1.0f); setlinestyle(0); @@ -4932,6 +4886,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } + /* no return after this point, otherwise leaks */ + view3d_cached_text_draw_begin(); + /* draw keys? */ #if 0 // XXX old animation system if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) { @@ -5116,7 +5073,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(dt>OB_WIRE && dtobedit && (flag && DRAW_SCENESET)==0) { if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) { - drawSolidSelect(scene, v3d, rv3d, base); + drawSolidSelect(scene, v3d, ar, base); } } } @@ -5262,7 +5219,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) break; case OB_ARMATURE: if(dt>OB_WIRE) GPU_enable_material(0, NULL); // we use default material - empty_object= draw_armature(scene, v3d, rv3d, base, dt, flag); + empty_object= draw_armature(scene, v3d, ar, base, dt, flag); if(dt>OB_WIRE) GPU_disable_material(); break; default: @@ -5282,10 +5239,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) wmLoadMatrix(rv3d->viewmat); + view3d_cached_text_draw_begin(); + for(psys=ob->particlesystem.first; psys; psys=psys->next) draw_new_particle_system(scene, v3d, rv3d, base, psys, dt); - view3d_particle_text_draw(v3d, ar); + view3d_cached_text_draw_end(v3d, ar, 0, NULL); wmMultMatrix(ob->obmat); @@ -5437,7 +5396,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */ /* but, we also dont draw names for sets or duplicators */ if(flag == 0) { - view3d_object_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10); + view3d_cached_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10); } } /*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/ @@ -5460,7 +5419,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* return warning, this is cached text draw */ - view3d_object_text_draw(v3d, ar); + view3d_cached_text_draw_end(v3d, ar, 1, NULL); wmLoadMatrix(rv3d->viewmat); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 7dbea44b68b..52505fad521 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -89,10 +89,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt); void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline); void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob); void drawaxes(float size, int flag, char drawtype); -void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs); + +void view3d_cached_text_draw_begin(void); +void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs); +void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]); /* drawarmature.c */ -int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag); +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag); /* drawmesh.c */ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, struct DerivedMesh *dm, int faceselect); -- cgit v1.2.3 From 45089af1b277770ea6eb02f1d92af9f8f1d05125 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 19 Sep 2009 19:40:38 +0000 Subject: Bone constraints are now in a separate tab. It's more consistent since object constraints also have their own tab, and I didn't want to break context going from left to right. --- release/ui/buttons_data_bone.py | 1 + release/ui/buttons_object_constraint.py | 2 +- .../editors/space_buttons/buttons_context.c | 1 + .../blender/editors/space_buttons/buttons_header.c | 6 ++++-- .../blender/editors/space_buttons/space_buttons.c | 2 ++ source/blender/makesdna/DNA_space_types.h | 25 +++++++++++----------- source/blender/makesrna/intern/rna_space.c | 5 +++-- 7 files changed, 25 insertions(+), 17 deletions(-) diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index a0121821e55..b4048a94f23 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -74,6 +74,7 @@ class BONE_PT_transform(BoneButtonsPanel): class BONE_PT_transform_locks(BoneButtonsPanel): __label__ = "Transform Locks" + __default_closed__ = True def poll(self, context): return context.bone diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py index c8f7e467a18..1d2f9a5cb49 100644 --- a/release/ui/buttons_object_constraint.py +++ b/release/ui/buttons_object_constraint.py @@ -513,7 +513,7 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel): class BONE_PT_constraints(ConstraintButtonsPanel): __label__ = "Constraints" - __context__ = "bone" + __context__ = "bone_constraint" def poll(self, context): ob = context.object diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 635abd429f6..f51cb5d6f8c 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -463,6 +463,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found= buttons_context_path_texture(C, path); break; case BCONTEXT_BONE: + case BCONTEXT_BONE_CONSTRAINT: found= buttons_context_path_bone(path); if(!found) found= buttons_context_path_data(path, OB_ARMATURE); diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index a1041bc5106..83dd679c543 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -114,13 +114,15 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object"); if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint"); + uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Object Constraints"); if(sbuts->pathflag & (1<dataicon, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data"); if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier"); + uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifiers"); if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone"); + if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_BONE_CONSTRAINT, 0, 0, "Bone Constraints"); if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_MATERIAL, 0, 0, "Material"); if(sbuts->pathflag & (1<mainb); else if (sbuts->mainb == BCONTEXT_CONSTRAINT) ED_region_panels(C, ar, vertical, "constraint", sbuts->mainb); + else if(sbuts->mainb == BCONTEXT_BONE_CONSTRAINT) + ED_region_panels(C, ar, vertical, "bone_constraint", sbuts->mainb); sbuts->re_align= 0; sbuts->mainbo= sbuts->mainb; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 806d12815b5..1a368877243 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -569,18 +569,19 @@ typedef struct SpaceUserPref { /* buts->mainb new */ -#define BCONTEXT_SCENE 0 -#define BCONTEXT_WORLD 1 -#define BCONTEXT_OBJECT 2 -#define BCONTEXT_DATA 3 -#define BCONTEXT_MATERIAL 4 -#define BCONTEXT_TEXTURE 5 -#define BCONTEXT_PARTICLE 6 -#define BCONTEXT_PHYSICS 7 -#define BCONTEXT_BONE 9 -#define BCONTEXT_MODIFIER 10 -#define BCONTEXT_CONSTRAINT 12 -#define BCONTEXT_TOT 13 +#define BCONTEXT_SCENE 0 +#define BCONTEXT_WORLD 1 +#define BCONTEXT_OBJECT 2 +#define BCONTEXT_DATA 3 +#define BCONTEXT_MATERIAL 4 +#define BCONTEXT_TEXTURE 5 +#define BCONTEXT_PARTICLE 6 +#define BCONTEXT_PHYSICS 7 +#define BCONTEXT_BONE 9 +#define BCONTEXT_MODIFIER 10 +#define BCONTEXT_CONSTRAINT 12 +#define BCONTEXT_BONE_CONSTRAINT 13 +#define BCONTEXT_TOT 14 /* sbuts->flag */ #define SB_PRV_OSA 1 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 30c5d4988b3..8e783354653 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -747,10 +747,11 @@ static void rna_def_space_buttons(BlenderRNA *brna) {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"}, {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"}, {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"}, - {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraint", "Constraint"}, - {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifier", "Modifier"}, + {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"}, + {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"}, {BCONTEXT_DATA, "DATA", 0, "Data", "Data"}, {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"}, + {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone Constraints"}, {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"}, {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"}, {BCONTEXT_PARTICLE, "PARTICLE", ICON_PARTICLES, "Particle", "Particle"}, -- cgit v1.2.3 From f7d8275ddbca3d5a1eb9c1208561d874818da390 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 19 Sep 2009 19:57:30 +0000 Subject: More Nodes wrapped to Layout Engine: * Map Value, Alpha Over, Hue Saturation, Dilate/Erode * RNA fixes and additions. --- source/blender/editors/space_node/drawnode.c | 77 ++++++++-------------- source/blender/makesrna/intern/rna_nodetree.c | 35 +++++++++- .../blender/makesrna/intern/rna_nodetree_types.h | 2 +- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8bd8477fe13..3fa1e43b51b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1348,72 +1348,49 @@ static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_map_value(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - TexMapping *texmap= node->storage; - short xstart= (short)butr->xmin; - short dy= (short)(butr->ymax-19.0f); - short dx= (short)(butr->xmax-butr->xmin)/2; + uiLayout *sub, *col; - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); - dy-= 19; - uiDefButF(block, NUM, B_NODE_EXEC, "Size:", xstart, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 3, ""); - dy-= 23; - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); - dy-= 19; - uiDefButBitI(block, TOG, TEXMAP_CLIP_MAX, B_NODE_EXEC, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); - uiDefButF(block, NUM, B_NODE_EXEC, "", xstart+dx, dy, dx, 19, texmap->max, -1000.0f, 1000.0f, 10, 2, ""); + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "offset", 0); + uiItemR(col, NULL, 0, ptr, "size", 0); + + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "use_min", 0); + sub =uiLayoutColumn(col, 0); + uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min")); + uiItemR(sub, "", 0, ptr, "min", 0); + + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "use_max", 0); + sub =uiLayoutColumn(col, 0); + uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max")); + uiItemR(sub, "", 0, ptr, "max", 0); } static void node_composit_buts_alphaover(uiLayout *layout, PointerRNA *ptr) -{ - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeTwoFloats *ntf= node->storage; +{ + uiLayout *col; + col =uiLayoutColumn(layout, 1); /* alpha type */ - uiDefButS(block, TOG, B_NODE_EXEC, "ConvertPremul", - butr->xmin, butr->ymin+19, butr->xmax-butr->xmin, 19, - &node->custom1, 0, 0, 0, 0, ""); + uiItemR(col, NULL, 0, ptr, "convert_premul", 0); /* mix factor */ - uiDefButF(block, NUM, B_NODE_EXEC, "Premul: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, - &ntf->x, 0.0f, 1.0f, 100, 0, ""); + uiItemR(col, NULL, 0, ptr, "premul", 0); } static void node_composit_buts_hue_sat(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeHueSat *nhs= node->storage; + uiLayout *col; - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Hue: ", - butr->xmin, butr->ymin+40.0f, butr->xmax-butr->xmin, 20, - &nhs->hue, 0.0f, 1.0f, 100, 0, ""); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Sat: ", - butr->xmin, butr->ymin+20.0f, butr->xmax-butr->xmin, 20, - &nhs->sat, 0.0f, 2.0f, 100, 0, ""); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Val: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &nhs->val, 0.0f, 2.0f, 100, 0, ""); + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "hue", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "sat", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "val", UI_ITEM_R_SLIDER); } static void node_composit_buts_dilateerode(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - - uiDefButS(block, NUM, B_NODE_EXEC, "Distance:", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom2, -100, 100, 0, 0, "Distance to grow/shrink (number of iterations)"); + uiItemR(layout, NULL, 0, ptr, "distance", 0); } static void node_composit_buts_diff_matte(uiLayout *layout, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b310ff06b8e..b89bf0552bd 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -473,10 +473,11 @@ static void def_sh_geometry(StructRNA *srna) static void def_cmp_alpha_over(StructRNA *srna) { PropertyRNA *prop; - + + // XXX: Tooltip prop = RNA_def_property(srna, "convert_premul", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); - RNA_def_property_ui_text(prop, "convert_premul", "TODO: don't know what this is"); + RNA_def_property_ui_text(prop, "Convert Premul", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); RNA_def_struct_sdna_from(srna, "NodeTwoFloats", "storage"); @@ -488,6 +489,31 @@ static void def_cmp_alpha_over(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Node_update"); } +static void def_cmp_hue_saturation(StructRNA *srna) +{ + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeHueSat", "storage"); + + prop = RNA_def_property(srna, "hue", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "hue"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Hue", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "sat", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "sat"); + RNA_def_property_range(prop, 0.0f, 2.0f); + RNA_def_property_ui_text(prop, "Saturation", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "val", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "val"); + RNA_def_property_range(prop, 0.0f, 2.0f); + RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); +} + static void def_cmp_blur(StructRNA *srna) { PropertyRNA *prop; @@ -605,12 +631,14 @@ static void def_cmp_map_value(StructRNA *srna) prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "loc"); + RNA_def_property_array(prop, 1); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Offset", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); + RNA_def_property_array(prop, 1); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Size", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); @@ -627,12 +655,14 @@ static void def_cmp_map_value(StructRNA *srna) prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); + RNA_def_property_array(prop, 1); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Minimum", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); + RNA_def_property_array(prop, 1); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Maximum", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); @@ -837,6 +867,7 @@ static void def_cmp_dilate_erode(StructRNA *srna) prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "custom2"); + RNA_def_property_range(prop, -100, 100); RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)"); RNA_def_property_update(prop, 0, "rna_Node_update"); } diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index be4f131a6d6..420f1deae48 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -64,7 +64,7 @@ DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBL DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" ) DefNode( CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" ) DefNode( CompositorNode, CMP_NODE_SETALPHA, 0, "SETALPHA", SetAlpha, "Set Alpha", "" ) -DefNode( CompositorNode, CMP_NODE_HUE_SAT, 0, "HUE_SAT", HueSat, "Hue/Saturation", "" ) +DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue/Saturation", "" ) DefNode( CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" ) DefNode( CompositorNode, CMP_NODE_R_LAYERS, def_cmp_render_layers, "R_LAYERS", RLayers, "Render Layers", "" ) DefNode( CompositorNode, CMP_NODE_COMPOSITE, 0, "COMPOSITE", Composite, "Composite", "" ) -- cgit v1.2.3 From 8b4ad3584cbd66c7fc76dbb9593e56d145b9fc7b Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sat, 19 Sep 2009 21:40:37 +0000 Subject: A few smaller adjustments to armature and bone properties. --- release/ui/buttons_data_armature.py | 14 ++++++++++---- release/ui/buttons_data_bone.py | 8 ++++---- source/blender/makesrna/intern/rna_armature.c | 23 +++++++++++++++++------ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index 49da9c190ff..413deee362b 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -37,7 +37,9 @@ class DATA_PT_skeleton(DataButtonsPanel): ob = context.object arm = context.armature space = context.space_data - + + layout.itemR(arm, "pose_position", expand=True) + split = layout.split() col = split.column() @@ -50,7 +52,6 @@ class DATA_PT_skeleton(DataButtonsPanel): col.itemR(arm, "auto_ik") col = split.column() - col.itemR(arm, "rest_position") col.itemL(text="Deform:") col.itemR(arm, "deform_vertexgroups", text="Vertex Groups") col.itemR(arm, "deform_envelope", text="Envelopes") @@ -140,12 +141,16 @@ class DATA_PT_paths(DataButtonsPanel): col.row().itemR(arm, "paths_location", expand=True) col = split.column() - col.itemL(text="Show:") + col.itemL(text="Display:") col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers") col.itemR(arm, "paths_highlight_keyframes", text="Keyframes") col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers") - layout.itemO("pose.paths_calculate") + layout.itemS() + + row = layout.row() + row.itemO("pose.paths_calculate", text="Calculate Paths") + row.itemO("pose.paths_clear", text="Clear Paths") class DATA_PT_ghost(DataButtonsPanel): __label__ = "Ghost" @@ -171,6 +176,7 @@ class DATA_PT_ghost(DataButtonsPanel): sub.itemR(arm, "ghost_size", text="Step") col = split.column() + col.itemL(text="Display:") col.itemR(arm, "ghost_only_selected", text="Selected Only") bpy.types.register(DATA_PT_context_arm) diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index b4048a94f23..510b41de8a7 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -177,7 +177,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel): split = layout.split(percentage=0.25) split.itemR(pchan, "ik_dof_x", text="X") row = split.row() - row.itemR(pchan, "ik_stiffness_x", text="Stiffness") + row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True) row.active = pchan.ik_dof_x split = layout.split(percentage=0.25) @@ -192,7 +192,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel): split = layout.split(percentage=0.25) split.itemR(pchan, "ik_dof_y", text="Y") row = split.row() - row.itemR(pchan, "ik_stiffness_y", text="Stiffness") + row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True) row.active = pchan.ik_dof_y split = layout.split(percentage=0.25) @@ -207,7 +207,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel): split = layout.split(percentage=0.25) split.itemR(pchan, "ik_dof_z", text="Z") row = split.row() - row.itemR(pchan, "ik_stiffness_z", text="Stiffness") + row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True) row.active = pchan.ik_dof_z split = layout.split(percentage=0.25) @@ -220,7 +220,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel): row.active = pchan.ik_dof_z and pchan.ik_limit_z split = layout.split() - split.itemR(pchan, "ik_stretch", text="Stretch") + split.itemR(pchan, "ik_stretch", text="Stretch", slider=True) split.itemL() class BONE_PT_deform(BoneButtonsPanel): diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index aa422f85d7b..a1bcbe57bd5 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -540,10 +540,13 @@ static void rna_def_armature(BlenderRNA *brna) {ARM_PATH_ACFRA, "CURRENT_FRAME", 0, "Around Frame", "Display Paths of poses within a fixed number of frames around the current frame."}, {0, "RANGE", 0, "In Range", "Display Paths of poses within specified range."}, {0, NULL, 0, NULL, NULL}}; - static const EnumPropertyItem prop_paths_location_items[]= { {ARM_PATH_HEADS, "HEADS", 0, "Heads", "Calculate bone paths from heads"}, - {0, "TIPS", 0, "Tips", "Calculate bone paths from tips"}, + {0, "TAILS", 0, "Tails", "Calculate bone paths from tails"}, + {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_pose_position_items[]= { + {0, "POSE_POSITION", 0, "Pose Position", "Show armature in posed state."}, + {ARM_RESTPOS, "REST_POSITION", 0, "Rest Position", "Show Armature in binding pose state. No posing possible."}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Armature", "ID"); @@ -565,6 +568,17 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Edit Bones", ""); /* Enum values */ +// prop= RNA_def_property(srna, "rest_position", PROP_BOOLEAN, PROP_NONE); +// RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_RESTPOS); +// RNA_def_property_ui_text(prop, "Rest Position", "Show Armature in Rest Position. No posing possible."); +// RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + + prop= RNA_def_property(srna, "pose_position", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_pose_position_items); + RNA_def_property_ui_text(prop, "Pose Position", "Show armature in binding pose or final posed state."); + RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); + prop= RNA_def_property(srna, "drawtype", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_drawtype_items); RNA_def_property_ui_text(prop, "Draw Type", ""); @@ -606,10 +620,7 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); /* flag */ - prop= RNA_def_property(srna, "rest_position", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_RESTPOS); - RNA_def_property_ui_text(prop, "Rest Position", "Show Armature in Rest Position. No posing possible."); - RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + prop= RNA_def_property(srna, "draw_axes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWAXES); -- cgit v1.2.3 From b28109b442f5e87edf865c6bcbdb8f53665cdef5 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 19 Sep 2009 22:11:26 +0000 Subject: netrender: first draft for job balancer + some minor fixes --- release/io/netrender/__init__.py | 1 + release/io/netrender/balancing.py | 75 +++++++++++++++++++++++++++++++++++++++ release/io/netrender/client.py | 7 ++-- release/io/netrender/master.py | 60 +++++++++++++------------------ release/io/netrender/model.py | 12 +++++++ release/io/netrender/operators.py | 6 ++-- release/io/netrender/slave.py | 18 +++++----- release/io/netrender/utils.py | 8 ++++- 8 files changed, 135 insertions(+), 52 deletions(-) create mode 100644 release/io/netrender/balancing.py diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py index 1eb91abb938..b313d64ccbb 100644 --- a/release/io/netrender/__init__.py +++ b/release/io/netrender/__init__.py @@ -6,6 +6,7 @@ import client import slave import master import utils +import balancing import ui # store temp data in bpy module diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py new file mode 100644 index 00000000000..89e1e3f7b06 --- /dev/null +++ b/release/io/netrender/balancing.py @@ -0,0 +1,75 @@ +import time + +from netrender.utils import * +import netrender.model + +class RatingRule: + def rate(self, job): + return 0 + +class ExclusionRule: + def test(self, job): + return False + +class PriorityRule: + def test(self, job): + return False + +class Balancer: + def __init__(self): + self.rules = [] + self.priorities = [] + self.exceptions = [] + + def addRule(self, rule): + self.rules.append(rule) + + def addPriority(self, priority): + self.priorities.append(priority) + + def addException(self, exception): + self.exceptions.append(exception) + + def applyRules(self, job): + return sum((rule.rate(job) for rule in self.rules)) + + def applyPriorities(self, job): + for priority in self.priorities: + if priority.test(job): + return True # priorities are first + + return False + + def applyExceptions(self, job): + for exception in self.exceptions: + if exception.test(job): + return True # exceptions are last + + return False + + def sortKey(self, job): + return (1 if self.applyExceptions(job) else 0, # exceptions after + 0 if self.applyPriorities(job) else 1, # priorities first + self.applyRules(job)) + + def balance(self, jobs): + if jobs: + jobs.sort(key=self.sortKey) + return jobs[0] + else: + return None + +# ========================== + + +class RatingCredit(RatingRule): + def rate(self, job): + return -job.credits # more credit is better (sort at first in list) + +class NewJobPriority(PriorityRule): + def test(self, job): + return job.countFrames(status = DISPATCHED) == 0 + +class ExcludeQueuedEmptyJob(ExclusionRule): + def test(self, job): + return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0 diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index a6cfb4e020d..f445fe2f608 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -103,7 +103,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): job.priority = netsettings.priority # try to send path first - conn.request("POST", "job", repr(job.serialize())) + conn.request("POST", "/job", repr(job.serialize())) response = conn.getresponse() job_id = response.getheader("job-id") @@ -112,7 +112,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): if response.status == http.client.ACCEPTED: for filepath, start, end in job.files: f = open(filepath, "rb") - conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath}) + conn.request("PUT", "/file", f, headers={"job-id": job_id, "job-file": filepath}) f.close() response = conn.getresponse() @@ -121,7 +121,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): return job_id def requestResult(conn, job_id, frame): - conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(frame)}) + conn.request("GET", "/render", headers={"job-id": job_id, "job-frame":str(frame)}) @rnaType class NetworkRenderEngine(bpy.types.RenderEngine): @@ -174,7 +174,6 @@ class NetworkRenderEngine(bpy.types.RenderEngine): requestResult(conn, job_id, scene.current_frame) while response.status == http.client.ACCEPTED and not self.test_break(): - print("waiting") time.sleep(1) requestResult(conn, job_id, scene.current_frame) response = conn.getresponse() diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 58af47d6240..58c6c1b2d00 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -4,10 +4,7 @@ import subprocess, shutil, time, hashlib from netrender.utils import * import netrender.model - -JOB_WAITING = 0 # before all data has been entered -JOB_PAUSED = 1 # paused by user -JOB_QUEUED = 2 # ready to be dispatched +import netrender.balancing class MRenderFile: def __init__(self, filepath, start, end): @@ -38,10 +35,6 @@ class MRenderSlave(netrender.model.RenderSlave): def seen(self): self.last_seen = time.time() -# sorting key for jobs -def groupKey(job): - return (job.status, job.framesLeft() > 0, job.priority, job.credits) - class MRenderJob(netrender.model.RenderJob): def __init__(self, job_id, name, files, chunks = 1, priority = 1, credits = 100.0, blacklist = []): super().__init__() @@ -95,14 +88,6 @@ class MRenderJob(netrender.model.RenderJob): frame = MRenderFrame(frame_number) self.frames.append(frame) return frame - - def framesLeft(self): - total = 0 - for j in self.frames: - if j.status == QUEUED: - total += 1 - - return total def reset(self, all): for f in self.frames: @@ -153,7 +138,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): def do_HEAD(self): print(self.path) - if self.path == "status": + if self.path == "/status": job_id = self.headers.get('job-id', "") job_frame = int(self.headers.get('job-frame', -1)) @@ -185,12 +170,12 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): print(self.path) - if self.path == "version": + if self.path == "/version": self.send_head() self.server.stats("", "New client connection") self.wfile.write(VERSION) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "render": + elif self.path == "/render": job_id = self.headers['job-id'] job_frame = int(self.headers['job-frame']) print("render:", job_id, job_frame) @@ -221,7 +206,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # no such job id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "log": + elif self.path == "/log": job_id = self.headers['job-id'] job_frame = int(self.headers['job-frame']) print("log:", job_id, job_frame) @@ -250,7 +235,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # no such job id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "status": + elif self.path == "/status": job_id = self.headers.get('job-id', "") job_frame = int(self.headers.get('job-frame', -1)) @@ -284,7 +269,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.wfile.write(bytes(repr(message), encoding='utf8')) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "job": + elif self.path == "/job": self.server.update() slave_id = self.headers['slave-id'] @@ -315,7 +300,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "file": + elif self.path == "/file": slave_id = self.headers['slave-id'] slave = self.server.updateSlave(slave_id) @@ -348,7 +333,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "slave": + elif self.path == "/slave": message = [] for slave in self.server.slaves: @@ -368,7 +353,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): print(self.path) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - if self.path == "job": + if self.path == "/job": print("posting job info") self.server.stats("", "Receiving job") @@ -394,7 +379,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: self.send_head(http.client.ACCEPTED, headers=headers) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "cancel": + elif self.path == "/cancel": job_id = self.headers.get('job-id', "") if job_id: print("cancel:", job_id, "\n") @@ -404,7 +389,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head() # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "reset": + elif self.path == "/reset": job_id = self.headers.get('job-id', "") job_frame = int(self.headers.get('job-frame', "-1")) all = bool(self.headers.get('reset-all', "False")) @@ -421,7 +406,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: # job not found self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "slave": + elif self.path == "/slave": length = int(self.headers['content-length']) job_frame_string = self.headers['job-frame'] @@ -431,7 +416,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(headers = {"slave-id": slave_id}) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "log": + elif self.path == "/log": slave_id = self.headers['slave-id'] slave = self.server.updateSlave(slave_id) @@ -460,7 +445,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): print(self.path) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - if self.path == "file": + if self.path == "/file": print("writing blend file") self.server.stats("", "Receiving job") @@ -504,7 +489,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: # job not found self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "render": + elif self.path == "/render": print("writing result file") self.server.stats("", "Receiving render result") @@ -547,7 +532,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "log": + elif self.path == "/log": print("writing log file") self.server.stats("", "Receiving log file") @@ -587,6 +572,11 @@ class RenderMasterServer(http.server.HTTPServer): self.job_id = 0 self.path = path + "master_" + str(os.getpid()) + os.sep + self.balancer = netrender.balancing.Balancer() + self.balancer.addRule(netrender.balancing.RatingCredit()) + self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) + self.balancer.addPriority(netrender.balancing.NewJobPriority()) + if not os.path.exists(self.path): os.mkdir(self.path) @@ -616,7 +606,7 @@ class RenderMasterServer(http.server.HTTPServer): self.jobs = [] def update(self): - self.jobs.sort(key = groupKey) + self.balancer.balance(self.jobs) def removeJob(self, id): job = self.jobs_map.pop(id) @@ -644,8 +634,8 @@ class RenderMasterServer(http.server.HTTPServer): def getNewJob(self, slave_id): if self.jobs: - for job in reversed(self.jobs): - if job.status == JOB_QUEUED and job.framesLeft() > 0 and slave_id not in job.blacklist: + for job in self.jobs: + if not self.balancer.applyExceptions(job) and slave_id not in job.blacklist: return job, job.getFrames() return None, None diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 924493fd34a..9a6645e79cf 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -95,6 +95,18 @@ class RenderJob: def __len__(self): return len(self.frames) + def countFrames(self, status=QUEUED): + total = 0 + for j in self.frames: + if j.status == status: + total += 1 + + return total + + def countSlaves(self): + return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED))) + + def framesStatus(self): results = { QUEUED: 0, diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index e6888731437..bfc67c25285 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -89,7 +89,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): conn = clientConnection(context.scene) if conn: - conn.request("GET", "status") + conn.request("GET", "/status") response = conn.getresponse() print( response.status, response.reason ) @@ -205,7 +205,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): conn = clientConnection(context.scene) if conn: - conn.request("GET", "slave") + conn.request("GET", "/slave") response = conn.getresponse() print( response.status, response.reason ) @@ -258,7 +258,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): if conn: job = bpy.data.netrender_jobs[netsettings.active_job_index] - conn.request("POST", "cancel", headers={"job-id":job.id}) + conn.request("POST", "/cancel", headers={"job-id":job.id}) response = conn.getresponse() print( response.status, response.reason ) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index ecdbf69591a..406b987c990 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -33,7 +33,7 @@ def slave_Info(): return slave def testCancel(conn, job_id): - conn.request("HEAD", "status", headers={"job-id":job_id}) + conn.request("HEAD", "/status", headers={"job-id":job_id}) response = conn.getresponse() # cancelled if job isn't found anymore @@ -47,7 +47,7 @@ def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None): if not os.path.exists(job_full_path): temp_path = JOB_PREFIX + "slave.temp.blend" - conn.request("GET", "file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path}) + conn.request("GET", "/file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path}) response = conn.getresponse() if response.status != http.client.OK: @@ -76,7 +76,7 @@ def render_slave(engine, scene): conn = clientConnection(scene) if conn: - conn.request("POST", "slave", repr(slave_Info().serialize())) + conn.request("POST", "/slave", repr(slave_Info().serialize())) response = conn.getresponse() slave_id = response.getheader("slave-id") @@ -87,7 +87,7 @@ def render_slave(engine, scene): while not engine.test_break(): - conn.request("GET", "job", headers={"slave-id":slave_id}) + conn.request("GET", "/job", headers={"slave-id":slave_id}) response = conn.getresponse() if response.status == http.client.OK: @@ -119,7 +119,7 @@ def render_slave(engine, scene): # announce log to master logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) - conn.request("POST", "log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) + conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) response = conn.getresponse() first_frame = job.frames[0].number @@ -146,7 +146,7 @@ def render_slave(engine, scene): if stdout: # (only need to update on one frame, they are linked headers["job-frame"] = str(first_frame) - conn.request("PUT", "log", stdout, headers=headers) + conn.request("PUT", "/log", stdout, headers=headers) response = conn.getresponse() stdout = bytes() @@ -173,7 +173,7 @@ def render_slave(engine, scene): if stdout: # (only need to update on one frame, they are linked headers["job-frame"] = str(first_frame) - conn.request("PUT", "log", stdout, headers=headers) + conn.request("PUT", "/log", stdout, headers=headers) response = conn.getresponse() headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} @@ -184,7 +184,7 @@ def render_slave(engine, scene): headers["job-frame"] = str(frame.number) # send result back to server f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') - conn.request("PUT", "render", f, headers=headers) + conn.request("PUT", "/render", f, headers=headers) f.close() response = conn.getresponse() else: @@ -192,7 +192,7 @@ def render_slave(engine, scene): for frame in job.frames: headers["job-frame"] = str(frame.number) # send error result back to server - conn.request("PUT", "render", headers=headers) + conn.request("PUT", "/render", headers=headers) response = conn.getresponse() else: if timeout < MAX_TIMEOUT: diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index 46c2011b188..50ca08d1723 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -8,6 +8,12 @@ import netrender.model VERSION = b"0.5" +# Jobs status +JOB_WAITING = 0 # before all data has been entered +JOB_PAUSED = 1 # paused by user +JOB_QUEUED = 2 # ready to be dispatched + +# Frames status QUEUED = 0 DISPATCHED = 1 DONE = 2 @@ -36,7 +42,7 @@ def clientConnection(scene): return None def clientVerifyVersion(conn): - conn.request("GET", "version") + conn.request("GET", "/version") response = conn.getresponse() if response.status != http.client.OK: -- cgit v1.2.3 From f4b9ec0e37d636c974f4ea24c90d288015df7d24 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 20 Sep 2009 01:36:11 +0000 Subject: 2.5 - 2 Armature Related Crash Fixes * #19397: Properties panel (transform panel in 3D-View) crashed when there was no active posechannel. * Breakdown/Push/Relax Pose tools crashed when auto-keyframing was enabled. There where 2 main causes here: 1) laziness to try and avoid having to clear some data everytime, 2) a typo for one of the KeyingSet names --- source/blender/editors/armature/poseSlide.c | 5 ++--- source/blender/editors/space_view3d/view3d_buttons.c | 17 ++++------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index e55c5608112..eb290b1f83c 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -219,7 +219,7 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode) /* get builtin KeyingSets */ pso->ks_loc= ANIM_builtin_keyingset_get_named(NULL, "Location"); pso->ks_rot= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); - pso->ks_scale= ANIM_builtin_keyingset_get_named(NULL, "Scale"); + pso->ks_scale= ANIM_builtin_keyingset_get_named(NULL, "Scaling"); /* return status is whether we've got all the data we were requested to get */ return 1; @@ -393,8 +393,7 @@ static void pose_slide_autoKeyframe (bContext *C, tPoseSlideOp *pso, bPoseChanne ListBase dsources = {&cks, &cks}; /* init common-key-source for use by KeyingSets */ - // TODO: for now, we don't clear it out, since it should be safe to do so... - //memset(&cks, 0, sizeof(bCommonKeySrc)); + memset(&cks, 0, sizeof(bCommonKeySrc)); cks.id= &pso->ob->id; /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 286b0ca0898..89d07fbbfea 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -512,6 +512,10 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer)) break; } + if (!pchan) { + uiDefBut(block, LABEL, 0, "No Bone Active", 0, 240, 100, 20, 0, 0, 0, 0, 0, ""); + return; + } if (pchan->rotmode == PCHAN_ROT_AXISANGLE) { float quat[4]; @@ -1447,25 +1451,12 @@ void view3d_buttons_register(ARegionType *art) pt->draw= view3d_panel_transform_spaces; BLI_addtail(&art->paneltypes, pt); - pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); - strcpy(pt->idname, "VIEW3D_PT_gpencil"); - strcpy(pt->label, "Greas Pencil"); - pt->draw= view3d_panel_gpencil; - BLI_addtail(&art->paneltypes, pt);*/ - pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces"); strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces"); strcpy(pt->label, "Bone Sketching"); pt->draw= view3d_panel_bonesketch_spaces; pt->poll= view3d_panel_bonesketch_spaces_poll; BLI_addtail(&art->paneltypes, pt); - - /* - pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo"); - strcpy(pt->idname, "VIEW3D_PT_redo"); - strcpy(pt->label, "Last Operator"); - pt->draw= view3d_panel_operator_redo; - BLI_addtail(&art->paneltypes, pt); */ // XXX view3d_panel_preview(C, ar, 0); } -- cgit v1.2.3 From 22995e9c459ad8dc7acbde15db94b2013def78f8 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 20 Sep 2009 05:05:16 +0000 Subject: 2.5 - Pose Relax/Push improvements * Relax and Push are now interactive. Moving the mouse left<->right decreases/increases (respectively) the number of times the pose is relaxed or pushed. The sensitivity on this could be tweaked as necessary. * Cancelling these 'pose sliding' tools now correctly restores the initial pose * Autokeyframing is now only done when the operator is confirmed. -- Also, made 'View persp/ortho' <-> 'View Persp/Ortho' to be more in line with other operator names, but to also make it easier to read. --- source/blender/editors/armature/poseSlide.c | 220 +++++++++++++++------- source/blender/editors/space_view3d/view3d_edit.c | 2 +- 2 files changed, 153 insertions(+), 69 deletions(-) diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index eb290b1f83c..02c23f01f1e 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -135,7 +135,13 @@ typedef struct tPChanFCurveLink { ListBase fcurves; /* F-Curves for this PoseChannel */ bPoseChannel *pchan; /* Pose Channel which data is attached to */ + char *pchan_path; /* RNA Path to this Pose Channel (needs to be freed when we're done) */ + + float oldloc[3]; /* transform values at start of operator (to be restored before each modal step) */ + float oldrot[3]; + float oldscale[3]; + float oldquat[4]; } tPChanFCurveLink; /* ------------------------------------ */ @@ -202,6 +208,12 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode) pchan->flag |= POSE_ROT; if (transFlags & ACT_TRANS_SCALE) pchan->flag |= POSE_SIZE; + + /* store current transforms */ + VECCOPY(pfl->oldloc, pchan->loc); + VECCOPY(pfl->oldrot, pchan->eul); + VECCOPY(pfl->oldscale, pchan->size); + QUATCOPY(pfl->oldquat, pchan->quat); } } CTX_DATA_END; @@ -261,6 +273,23 @@ static void pose_slide_exit (bContext *C, wmOperator *op) /* ------------------------------------ */ +/* helper for apply() / reset() - refresh the data */ +static void pose_slide_refresh (bContext *C, tPoseSlideOp *pso) +{ + /* old optimize trick... this enforces to bypass the depgraph + * - note: code copied from transform_generics.c -> recalcData() + */ + // FIXME: shouldn't this use the builtin stuff? + if ((pso->arm->flag & ARM_DELAYDEFORM)==0) + DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); /* sets recalc flags */ + else + where_is_pose(pso->scene, pso->ob); + + /* note, notifier might evolve */ + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); +} + /* helper for apply() callabcks - find the next F-Curve with matching path... */ static LinkData *find_next_fcurve_link (ListBase *fcuLinks, LinkData *prev, char *path) { @@ -330,22 +359,45 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo w2 = (w2/wtot); } - /* depending on the mode, */ + /* depending on the mode, calculate the new value + * - in all of these, the start+end values are multiplied by w2 and w1 (respectively), + * since multiplication in another order would decrease the value the current frame is closer to + */ switch (pso->mode) { case POSESLIDE_PUSH: /* make the current pose more pronounced */ - // TODO: this is not interactively modifiable! - vec[ch]= ( -((sVal * w2) + (eVal * w1)) + (vec[ch] * 6.0f) ) / 5.0f; + { + /* perform a weighted average here, favouring the middle pose + * - numerator should be larger than denominator to 'expand' the result + * - perform this weighting a number of times given by the percentage... + */ + int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed + + while (iters-- > 0) { + vec[ch]= ( -((sVal * w2) + (eVal * w1)) + (vec[ch] * 6.0f) ) / 5.0f; + } + } break; case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */ - /* apply the value with a hard coded 6th */ - // TODO: this is not interactively modifiable! - vec[ch]= ( ((sVal * w2) + (eVal * w1)) + (vec[ch] * 5.0f) ) / 6.0f; + { + /* perform a weighted average here, favouring the middle pose + * - numerator should be smaller than denominator to 'relax' the result + * - perform this weighting a number of times given by the percentage... + */ + int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed + + while (iters-- > 0) { + vec[ch]= ( ((sVal * w2) + (eVal * w1)) + (vec[ch] * 5.0f) ) / 6.0f; + } + } break; case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */ + { /* perform simple linear interpolation - coefficient for start must come from pso->percentage... */ + // TODO: make this use some kind of spline interpolation instead? vec[ch]= ((sVal * w2) + (eVal * w1)); + } break; } @@ -384,26 +436,6 @@ static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl) #endif } -/* helper for apply() - perform autokeyframing */ -static void pose_slide_autoKeyframe (bContext *C, tPoseSlideOp *pso, bPoseChannel *pchan, KeyingSet *ks) -{ - /* insert keyframes as necessary if autokeyframing */ - if (autokeyframe_cfra_can_key(pso->scene, &pso->ob->id)) { - bCommonKeySrc cks; - ListBase dsources = {&cks, &cks}; - - /* init common-key-source for use by KeyingSets */ - memset(&cks, 0, sizeof(bCommonKeySrc)); - cks.id= &pso->ob->id; - - /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ - cks.pchan= pchan; - - /* insert keyframes */ - modify_keyframes(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)pso->cframe); - } -} - /* apply() - perform the pose sliding based on weighting various poses */ static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso) { @@ -428,15 +460,11 @@ static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso) if (pchan->flag & POSE_LOC) { /* calculate these for the 'location' vector, and use location curves */ pose_slide_apply_vec3(pso, pfl, pchan->loc, "location"); - /* insert keyframes if needed */ - pose_slide_autoKeyframe(C, pso, pchan, pso->ks_loc); } if (pchan->flag & POSE_SIZE) { /* calculate these for the 'scale' vector, and use scale curves */ pose_slide_apply_vec3(pso, pfl, pchan->size, "scale"); - /* insert keyframes if needed */ - pose_slide_autoKeyframe(C, pso, pchan, pso->ks_scale); } if (pchan->flag & POSE_ROT) { @@ -452,24 +480,58 @@ static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso) /* quaternions - use quaternion blending */ pose_slide_apply_quat(pso, pfl); } - - /* insert keyframes if needed */ - pose_slide_autoKeyframe(C, pso, pchan, pso->ks_rot); } } - /* old optimize trick... this enforces to bypass the depgraph - * - note: code copied from transform_generics.c -> recalcData() - */ - // FIXME: shouldn't this use the builtin stuff? - if ((pso->arm->flag & ARM_DELAYDEFORM)==0) - DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); /* sets recalc flags */ - else - where_is_pose(pso->scene, pso->ob); + /* depsgraph updates + redraws */ + pose_slide_refresh(C, pso); +} + +/* perform autokeyframing after changes were made + confirmed */ +static void pose_slide_autoKeyframe (bContext *C, tPoseSlideOp *pso) +{ + /* insert keyframes as necessary if autokeyframing */ + if (autokeyframe_cfra_can_key(pso->scene, &pso->ob->id)) { + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; + tPChanFCurveLink *pfl; + + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &pso->ob->id; + + /* iterate over each pose-channel affected, applying the changes */ + for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) { + bPoseChannel *pchan= pfl->pchan; + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + + /* insert keyframes */ + if (pchan->flag & POSE_LOC) + modify_keyframes(C, &dsources, NULL, pso->ks_loc, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + if (pchan->flag & POSE_ROT) + modify_keyframes(C, &dsources, NULL, pso->ks_rot, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + if (pchan->flag & POSE_SIZE) + modify_keyframes(C, &dsources, NULL, pso->ks_scale, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + } + } +} + +/* reset changes made to current pose */ +static void pose_slide_reset (bContext *C, tPoseSlideOp *pso) +{ + tPChanFCurveLink *pfl; - /* note, notifier might evolve */ - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + /* iterate over each pose-channel affected, restoring all channels to their original values */ + for (pfl= pso->pfLinks.first; pfl; pfl= pfl->next) { + bPoseChannel *pchan= pfl->pchan; + + /* just copy all the values over regardless of whether they changed or not */ + VECCOPY(pchan->loc, pfl->oldloc); + VECCOPY(pchan->eul, pfl->oldrot); + VECCOPY(pchan->size, pfl->oldscale); + QUATCOPY(pchan->quat, pfl->oldquat); + } } /* ------------------------------------ */ @@ -538,24 +600,19 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp * return OPERATOR_CANCELLED; } - // FIXME: for now, just do modal for breakdowns... - if (pso->mode == POSESLIDE_BREAKDOWN) { - /* initial apply for operator... */ - pose_slide_apply(C, op, pso); - - /* set cursor to indicate modal */ - WM_cursor_modal(win, BC_EW_SCROLLCURSOR); - - /* add a modal handler for this operator */ - WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; - } - else { - /* temp static operator code... until a way to include percentage in the formulation comes up */ - pose_slide_apply(C, op, pso); - pose_slide_exit(C, op); - return OPERATOR_FINISHED; - } + /* initial apply for operator... */ + // TODO: need to calculate percentage for initial round too... + pose_slide_apply(C, op, pso); + + /* depsgraph updates + redraws */ + pose_slide_refresh(C, pso); + + /* set cursor to indicate modal */ + WM_cursor_modal(win, BC_EW_SCROLLCURSOR); + + /* add a modal handler for this operator */ + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; } /* common code for modal() */ @@ -566,15 +623,36 @@ static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt) switch (evt->type) { case LEFTMOUSE: /* confirm */ + { + /* return to normal cursor */ WM_cursor_restore(win); + + /* insert keyframes as required... */ + pose_slide_autoKeyframe(C, pso); pose_slide_exit(C, op); + + /* done! */ return OPERATOR_FINISHED; + } case ESCKEY: /* cancel */ case RIGHTMOUSE: + { + /* return to normal cursor */ WM_cursor_restore(win); + + /* reset transforms back to original state */ + pose_slide_reset(C, pso); + + /* depsgraph updates + redraws */ + pose_slide_refresh(C, pso); + + /* clean up temp data */ pose_slide_exit(C, op); + + /* cancelled! */ return OPERATOR_CANCELLED; + } case MOUSEMOVE: /* calculate new position */ { @@ -584,6 +662,9 @@ static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt) pso->percentage= (evt->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx); RNA_float_set(op->ptr, "percentage", pso->percentage); + /* reset transforms (to avoid accumulation errors) */ + pose_slide_reset(C, pso); + /* apply... */ pose_slide_apply(C, op, pso); } @@ -608,6 +689,9 @@ static int pose_slide_exec_common (bContext *C, wmOperator *op, tPoseSlideOp *ps /* settings should have been set up ok for applying, so just apply! */ pose_slide_apply(C, op, pso); + /* insert keyframes if needed */ + pose_slide_autoKeyframe(C, pso); + /* cleanup and done */ pose_slide_exit(C, op); @@ -668,12 +752,12 @@ void POSE_OT_push (wmOperatorType *ot) /* callbacks */ ot->exec= pose_slide_push_exec; ot->invoke= pose_slide_push_invoke; - //ot->modal= pose_slide_modal; - //ot->cancel= pose_slide_cancel; + ot->modal= pose_slide_modal; + ot->cancel= pose_slide_cancel; ot->poll= ED_operator_posemode; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* Properties */ pose_slide_opdef_properties(ot); @@ -725,12 +809,12 @@ void POSE_OT_relax (wmOperatorType *ot) /* callbacks */ ot->exec= pose_slide_relax_exec; ot->invoke= pose_slide_relax_invoke; - //ot->modal= pose_slide_modal; - //ot->cancel= pose_slide_cancel; + ot->modal= pose_slide_modal; + ot->cancel= pose_slide_cancel; ot->poll= ED_operator_posemode; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* Properties */ pose_slide_opdef_properties(ot); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 0faa1f8c16d..b788dc28311 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1628,7 +1628,7 @@ static int viewpersportho_exec(bContext *C, wmOperator *op) void VIEW3D_OT_view_persportho(wmOperatorType *ot) { /* identifiers */ - ot->name= "View persp/ortho"; + ot->name= "View Persp/Ortho"; ot->description = "Switch the current view from perspective/orthographic."; ot->idname= "VIEW3D_OT_view_persportho"; -- cgit v1.2.3 From 2c871f722d3cbc80c9f076d7c23137e19633ba3a Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Sep 2009 11:13:57 +0000 Subject: 2.5 MSVC projectfiles * maintenance (added poseSlide.c) --- projectfiles_vc9/blender/editors/ED_editors.vcproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index 948a26c49b5..e81e1a2e361 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -1286,6 +1286,10 @@ RelativePath="..\..\..\source\blender\editors\armature\poseobject.c" > + + -- cgit v1.2.3 From ad25fc829e736be4bbf2e2a125347eda294fdac9 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 20 Sep 2009 11:21:44 +0000 Subject: 2.5 - More animation/rigging bugfixes * #19419: PoseLib rename/remove tools could crash when an invalid (However, now care is needed when touching that index field, since the warnings can keep piling up) * Added Browse Poses for PoseLib to the toolbar * Removing constraints from bones now properly updates. A DAG rebuild is now forced, and the constraint flags are cleared. * Attempting to improve the situation with Copy Rotation constraint and rotation orders other than xyz. Unforunately, it looks like a different method is required... --- release/ui/space_view3d_toolbar.py | 5 ++--- source/blender/blenkernel/intern/constraint.c | 14 +++++++++++--- source/blender/editors/armature/poselib.c | 2 ++ source/blender/editors/object/object_constraint.c | 15 ++++++++++++--- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 415a3e223bb..239a727d2a2 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -277,8 +277,6 @@ class VIEW3D_PT_tools_posemode(View3DPanel): def draw(self, context): layout = self.layout - - col = layout.column(align=True) col.itemL(text="Transform:") col.itemO("tfm.translate") @@ -299,7 +297,8 @@ class VIEW3D_PT_tools_posemode(View3DPanel): col.itemL(text="Pose:") col.itemO("pose.copy", text="Copy") col.itemO("pose.paste", text="Paste") - col.itemO("poselib.pose_add", text="Add To library") + col.itemO("poselib.pose_add", text="Add To Library") + col.itemO("poselib.browse_interactive", text="Browse Library") col = layout.column(align=True) col.itemL(text="In-Between:") diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e5c0b3947de..748208d6c0b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -685,9 +685,17 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain ct->flag= CONSTRAINT_TAR_TEMP; \ \ if (ct->tar) { \ - if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_BONE; \ - else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) ct->type = CONSTRAINT_OBTYPE_VERT; \ - else ct->type = CONSTRAINT_OBTYPE_OBJECT; \ + if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) { \ + bPoseChannel *pchan= get_pose_channel(ct->tar->pose, ct->subtarget); \ + ct->type = CONSTRAINT_OBTYPE_BONE; \ + ct->rotOrder= pchan->rotmode; \ + }\ + else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \ + ct->type = CONSTRAINT_OBTYPE_VERT; \ + } \ + else {\ + ct->type = CONSTRAINT_OBTYPE_OBJECT; \ + } \ } \ \ BLI_addtail(list, ct); \ diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index ce07cfb9042..386cb6512a3 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -467,6 +467,7 @@ static int poselib_remove_exec (bContext *C, wmOperator *op) marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index")); if (marker == NULL) { BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + return OPERATOR_CANCELLED; } /* remove relevant keyframes */ @@ -533,6 +534,7 @@ static int poselib_rename_exec (bContext *C, wmOperator *op) marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index")); if (marker == NULL) { BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + return OPERATOR_CANCELLED; } /* get new name */ diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 9b073ed5878..eee6659c6b2 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -823,17 +823,22 @@ void CONSTRAINT_OT_move_up (wmOperatorType *ot) static int pose_constraints_clear_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); /* free constraints for all selected bones */ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) { free_constraints(&pchan->constraints); + pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_CONST); } CTX_DATA_END; + /* force depsgraph to get recalculated since relationships removed */ + DAG_scene_sort(scene); /* sort order of objects */ + /* do updates */ - DAG_id_flush_update(&ob->id, OB_RECALC_OB); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob); + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); return OPERATOR_FINISHED; } @@ -854,14 +859,18 @@ void POSE_OT_constraints_clear(wmOperatorType *ot) static int object_constraints_clear_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); /* do freeing */ // TODO: we should free constraints for all selected objects instead (to be more consistent with bones) free_constraints(&ob->constraints); + /* force depsgraph to get recalculated since relationships removed */ + DAG_scene_sort(scene); /* sort order of objects */ + /* do updates */ DAG_id_flush_update(&ob->id, OB_RECALC_OB); - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 2f71b49484ee2c45d77784d07a21031d07f699ed Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 20 Sep 2009 12:54:30 +0000 Subject: 2.5 - Yet another round of bugfixes * Copy Rotation constraint "should" work ok for custom rotation orders now. It now converts both rotations to the form used by the owner. So far, this doesn't seem to have broken any of the test rigs in my test-suite, though new specimens for the hall of flakiness are always welcome. * Fixed many RNA wrapping bugs for Armature data. - Fixed a few wrong tooltips - Made proper refreshes for restpose/posed, etc. * Started converting special quaternion interpolation for Pose Sliding tools (push/relax/breakdown), though this doesn't seem to be working correctly yet. -->> Help to get these working right is welcome :) --- source/blender/blenkernel/intern/constraint.c | 3 +- source/blender/editors/armature/poseSlide.c | 100 +++++++++++++++++++------- source/blender/makesrna/intern/rna_armature.c | 12 ++-- 3 files changed, 84 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 748208d6c0b..e49bda0fdd2 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1588,7 +1588,8 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta VECCOPY(loc, cob->matrix[3]); Mat4ToSize(cob->matrix, size); - Mat4ToEulO(ct->matrix, eul, ct->rotOrder); + /* to allow compatible rotations, must get both rotations in the order of the owner... */ + Mat4ToEulO(ct->matrix, eul, cob->rotOrder); Mat4ToEulO(cob->matrix, obeul, cob->rotOrder); if ((data->flag & ROTLIKE_X)==0) diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 02c23f01f1e..353503967ec 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -410,30 +410,82 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo /* helper for apply() - perform sliding for quaternion rotations (using quat blending) */ static void pose_slide_apply_quat (tPoseSlideOp *pso, tPChanFCurveLink *pfl) { - // TODO: this is quite evil stuff... -#if 0 // XXX port... - /* get 2 quats */ - quat_prev[0] = eval_icu(icu_w, frame_prev); - quat_prev[1] = eval_icu(icu_x, frame_prev); - quat_prev[2] = eval_icu(icu_y, frame_prev); - quat_prev[3] = eval_icu(icu_z, frame_prev); - - quat_next[0] = eval_icu(icu_w, frame_next); - quat_next[1] = eval_icu(icu_x, frame_next); - quat_next[2] = eval_icu(icu_y, frame_next); - quat_next[3] = eval_icu(icu_z, frame_next); - -#if 0 - /* apply the setting, completely smooth */ - QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) ); -#else - /* tricky interpolation */ - QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) ); - QUATCOPY(quat_orig, pchan->quat); - QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f); - /* done */ -#endif -#endif + FCurve *fcu_w=NULL, *fcu_x=NULL, *fcu_y=NULL, *fcu_z=NULL; + bPoseChannel *pchan= pfl->pchan; + LinkData *ld=NULL; + char *path=NULL; + float cframe; + + /* get the path to use - this should be quaternion rotations only (needs care) */ + path= BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation"); + + /* get the current frame number */ + cframe= (float)pso->cframe; + + /* using this path, find each matching F-Curve for the variables we're interested in */ + while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) { + FCurve *fcu= (FCurve *)ld->data; + + /* assign this F-Curve to one of the relevant pointers... */ + switch (fcu->array_index) { + case 3: /* z */ + fcu_z= fcu; + break; + case 2: /* y */ + fcu_y= fcu; + break; + case 1: /* x */ + fcu_x= fcu; + break; + case 0: /* w */ + fcu_w= fcu; + break; + } + } + + /* only if all channels exist, proceed */ + if (fcu_w && fcu_x && fcu_y && fcu_z) { + float quat_prev[4], quat_next[4]; + + /* get 2 quats */ + quat_prev[0] = evaluate_fcurve(fcu_w, pso->prevFrame); + quat_prev[1] = evaluate_fcurve(fcu_x, pso->prevFrame); + quat_prev[2] = evaluate_fcurve(fcu_y, pso->prevFrame); + quat_prev[3] = evaluate_fcurve(fcu_z, pso->prevFrame); + + quat_next[0] = evaluate_fcurve(fcu_w, pso->nextFrame); + quat_next[1] = evaluate_fcurve(fcu_x, pso->nextFrame); + quat_next[2] = evaluate_fcurve(fcu_y, pso->nextFrame); + quat_next[3] = evaluate_fcurve(fcu_z, pso->nextFrame); + + /* perform blending */ + if (pso->mode == POSESLIDE_BREAKDOWN) { + /* just perform the interpol between quat_prev and quat_next using pso->percentage as a guide */ + QuatInterpol(pchan->quat, quat_prev, quat_next, pso->percentage); + } + else { + float quat_interp[4], quat_orig[4]; + int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed + + /* perform this blending several times until a satisfactory result is reached */ + while (iters-- > 0) { + /* calculate the interpolation between the endpoints */ + QuatInterpol(quat_interp, quat_prev, quat_next, (cframe-pso->prevFrame) / (pso->nextFrame-pso->prevFrame) ); + + /* make a copy of the original rotation */ + QUATCOPY(quat_orig, pchan->quat); + + /* tricky interpolations - mode-dependent blending between original and new */ + if (pso->mode == POSESLIDE_RELAX) // xxx this was the original code, so should work fine + QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f); + else // I'm just guessing here... + QuatInterpol(pchan->quat, quat_orig, quat_interp, 6.0f/5.0f); + } + } + } + + /* free the path now */ + MEM_freeN(path); } /* apply() - perform the pose sliding based on weighting various poses */ diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index a1bcbe57bd5..d06c8ccee03 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -52,6 +52,7 @@ static void rna_Armature_update_data(bContext *C, PointerRNA *ptr) DAG_id_flush_update(id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); + //WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); } static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr) @@ -577,7 +578,7 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, prop_pose_position_items); RNA_def_property_ui_text(prop, "Pose Position", "Show armature in binding pose or final posed state."); - RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); + RNA_def_property_update(prop, 0, "rna_Armature_update_data"); prop= RNA_def_property(srna, "drawtype", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_drawtype_items); @@ -593,7 +594,7 @@ static void rna_def_armature(BlenderRNA *brna) prop= RNA_def_property(srna, "paths_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "pathflag"); RNA_def_property_enum_items(prop, prop_paths_type_items); - RNA_def_property_ui_text(prop, "Paths Type", "Mapping type to use for this image in the game engine."); + RNA_def_property_ui_text(prop, "Paths Type", "Type of range to show for Bone Paths"); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); prop= RNA_def_property(srna, "paths_location", PROP_ENUM, PROP_NONE); @@ -609,7 +610,7 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_array(prop, 16); RNA_def_property_ui_text(prop, "Visible Layers", "Armature layer visibility."); RNA_def_property_boolean_funcs(prop, NULL, "rna_Armature_layer_set"); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Armature_redraw_data"); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); /* layer protection */ @@ -658,8 +659,8 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); prop= RNA_def_property(srna, "ghost_only_selected", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ARM_GHOST_ONLYSEL); - RNA_def_property_ui_text(prop, "Draw Ghosts on Selected Keyframes Only", ""); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_GHOST_ONLYSEL); + RNA_def_property_ui_text(prop, "Draw Ghosts on Selected Bones Only", ""); RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); /* deformflag */ @@ -705,7 +706,6 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); - /* Number fields */ /* ghost/onionskining settings */ prop= RNA_def_property(srna, "ghost_step", PROP_INT, PROP_NONE); -- cgit v1.2.3 From 7d86e92df9d92fe7c2fe7dc144b113dcc8436578 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 20 Sep 2009 13:34:54 +0000 Subject: 2.5: * Wrapped Invert, PremulKey Levels Node, Distance Key, Difference Key and Color Spill. * Added RNA for Levels Node. * Small RNA fixes. --- source/blender/editors/space_node/drawnode.c | 106 ++++----------------- source/blender/makesrna/intern/rna_nodetree.c | 26 ++++- .../blender/makesrna/intern/rna_nodetree_types.h | 4 +- 3 files changed, 46 insertions(+), 90 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 3fa1e43b51b..9b73bdbb255 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1294,7 +1294,6 @@ static void node_composit_buts_lensdist(uiLayout *layout, PointerRNA *ptr) uiLayoutSetActive(col, RNA_boolean_get(ptr, "projector")==0); uiItemR(col, NULL, 0, ptr, "jitter", 0); uiItemR(col, NULL, 0, ptr, "fit", 0); - } static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) @@ -1395,60 +1394,30 @@ static void node_composit_buts_dilateerode(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_diff_matte(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeChroma *c= node->storage; + uiLayout *col; - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", - butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Color differences below this threshold are keyed."); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Color differences below this additional threshold are partially keyed."); - uiBlockEndAlign(block); + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "tolerance", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "falloff", UI_ITEM_R_SLIDER); } static void node_composit_buts_distance_matte(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeChroma *c= node->storage; + uiLayout *col; - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Tolerance: ", - butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 1.0f, 100, 0, "Color distances below this threshold are keyed."); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "Falloff: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Color distances below this additional threshold are partially keyed."); - uiBlockEndAlign(block); + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "tolerance", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "falloff", UI_ITEM_R_SLIDER); } static void node_composit_buts_color_spill(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - short dx= (butr->xmax-butr->xmin)/3; - - NodeChroma *c=node->storage; - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NODE_EXEC, "Enhance: ", - butr->xmin, butr->ymin+20.0, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 0.5f, 100, 2, "Adjusts how much selected channel is affected by color spill algorithm"); - uiDefButS(block, ROW, B_NODE_EXEC, "R", - butr->xmin,butr->ymin,dx,20, - &node->custom1,1,1, 0, 0, "Red Spill Suppression"); - uiDefButS(block, ROW, B_NODE_EXEC, "G", - butr->xmin+dx,butr->ymin,dx,20, - &node->custom1,1,2, 0, 0, "Green Spill Suppression"); - uiDefButS(block, ROW, B_NODE_EXEC, "B", - butr->xmin+2*dx,butr->ymin,dx,20, - &node->custom1, 1, 3, 0, 0, "Blue Spill Suppression"); - uiBlockEndAlign(block); + uiLayout *row, *col; + + col =uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "factor", 0); + row= uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND); } static void node_composit_buts_chroma_matte(uiLayout *layout, PointerRNA *ptr) @@ -1709,56 +1678,23 @@ static void node_composit_buts_scale(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_invert(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, CMP_CHAN_RGB, B_NODE_EXEC, "RGB", - butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiDefButBitS(block, TOG, CMP_CHAN_A, B_NODE_EXEC, "A", - butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 20, - &node->custom1, 0, 0, 0, 0, ""); - uiBlockEndAlign(block); + uiLayout *col; + + col= uiLayoutColumn(layout, 0); + uiItemR(col, NULL, 0, ptr, "rgb", 0); + uiItemR(col, NULL, 0, ptr, "alpha", 0); } static void node_composit_buts_premulkey(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - uiBut *bt; - - /* blend type */ - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Key to Premul %x0|Premul to Key %x1", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &node->custom1, 0, 0, 0, 0, "Conversion between premultiplied alpha and key alpha"); + uiItemR(layout, "", 0, ptr, "mapping", 0); } static void node_composit_buts_view_levels(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - short sx= (butr->xmax-butr->xmin)/5; - - /*color space selectors*/ - uiBlockBeginAlign(block); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"C", - butr->xmin,butr->ymin,sx,20,&node->custom1,1,1, 0, 0, "Combined RGB"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"R", - butr->xmin+sx,butr->ymin,sx,20,&node->custom1,1,2, 0, 0, "Red Channel"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"G", - butr->xmin+2*sx,butr->ymin,sx,20,&node->custom1,1,3, 0, 0, "Green Channel"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"B", - butr->xmin+3*sx,butr->ymin,sx,20,&node->custom1,1,4, 0, 0, "Blue Channel"); - uiDefButS(block, ROW,B_NODE_EXEC+node->nr,"L", - butr->xmin+4*sx,butr->ymin,sx,20,&node->custom1,1,5, 0, 0, "Luminenc Channel"); - uiBlockEndAlign(block); + uiItemR(layout, NULL, 0, ptr, "color_space", UI_ITEM_R_EXPAND); } - /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b89bf0552bd..239fd894e4f 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -700,6 +700,26 @@ static void def_cmp_vector_blur(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Node_update"); } +static void def_cmp_levels(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem space_items[] = { + {1, "COMNINED_RGB", 0, "C", "Combined RGB"}, + {2, "RED", 0, "R", "Red Channel"}, + {3, "GREEN", 0, "G", "Green Channel"}, + {4, "BLUE", 0, "B", "Blue Channel"}, + {5, "LUMINANCE", 0, "L", "Luminance Channel"}, + {0, NULL, 0, NULL, NULL} + }; + + prop = RNA_def_property(srna, "color_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, "Color Space", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); +} + static void def_cmp_image(StructRNA *srna) { PropertyRNA *prop; @@ -964,9 +984,9 @@ static void def_cmp_color_spill(StructRNA *srna) PropertyRNA *prop; static EnumPropertyItem channel_items[] = { - {1, "R", 0, "Red", ""}, - {2, "G", 0, "Green", ""}, - {3, "B", 0, "Blue", ""}, + {1, "R", 0, "R", "Red Spill Suppression"}, + {2, "G", 0, "G", "Green Spill Suppression"}, + {3, "B", 0, "B", "Blue Spill Suppression"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 420f1deae48..69424649b3b 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -64,7 +64,7 @@ DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBL DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" ) DefNode( CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" ) DefNode( CompositorNode, CMP_NODE_SETALPHA, 0, "SETALPHA", SetAlpha, "Set Alpha", "" ) -DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue/Saturation", "" ) +DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue/Saturation", "" ) DefNode( CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" ) DefNode( CompositorNode, CMP_NODE_R_LAYERS, def_cmp_render_layers, "R_LAYERS", RLayers, "Render Layers", "" ) DefNode( CompositorNode, CMP_NODE_COMPOSITE, 0, "COMPOSITE", Composite, "Composite", "" ) @@ -104,7 +104,7 @@ DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMU DefNode( CompositorNode, CMP_NODE_GLARE, def_cmp_glare, "GLARE", Glare, "Glare", "" ) DefNode( CompositorNode, CMP_NODE_TONEMAP, def_cmp_tonemap, "TONEMAP", Tonemap, "Tonemap", "" ) DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lensdist", "" ) -DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, 0, "LEVELS", Levels, "Levels", "" ) +DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, def_cmp_levels, "LEVELS", Levels, "Levels", "" ) DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Matte", "" ) DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" ) -- cgit v1.2.3 From 1185be4355e6f0d812b7a8909ab3677aeec694ed Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 20 Sep 2009 14:00:00 +0000 Subject: Sound: * Moved AudioData back to Scene * Updated RNA stuff * Added mixdown volume --- intern/audaspace/intern/AUD_C-API.cpp | 25 ++++++++++++++++--- intern/audaspace/intern/AUD_C-API.h | 15 ++++++++++-- source/blender/blenkernel/BKE_sound.h | 2 +- source/blender/blenkernel/intern/scene.c | 2 +- source/blender/blenkernel/intern/sound.c | 8 +++--- source/blender/blenkernel/intern/writeffmpeg.c | 9 +++---- source/blender/blenloader/intern/readfile.c | 5 +++- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/makesdna/DNA_scene_types.h | 9 ++++--- source/blender/makesrna/intern/rna_scene.c | 34 ++++++++++++++++++++++---- 10 files changed, 85 insertions(+), 26 deletions(-) diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 45faebc7e97..afa1568d6dc 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -516,21 +516,40 @@ AUD_Device* AUD_openReadDevice(AUD_Specs specs) } } -int AUD_playDevice(AUD_Device* device, AUD_Sound* sound) +AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound) { assert(device); assert(sound); try { - return device->play(sound) != NULL; + return device->play(sound); } catch(AUD_Exception) { - return false; + return NULL; } } +int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle, + float volume) +{ + if(handle) + { + assert(device); + AUD_SourceCaps caps; + caps.handle = handle; + caps.value = volume; + + try + { + return device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps); + } + catch(AUD_Exception) {} + } + return false; +} + int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length) { assert(device); diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 6ec5ec87ad5..b02b465bff2 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -303,9 +303,20 @@ extern AUD_Device* AUD_openReadDevice(AUD_Specs specs); * Plays back a sound file through a read device. * \param device The read device. * \param sound The handle of the sound file. - * \return Whether the sound could be played back. + * \return A handle to the played back sound. + */ +extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound); + +/** + * Sets the volume of a played back sound of a read device. + * \param device The read device. + * \param handle The handle to the sound. + * \param volume The new volume, must be between 0.0 and 1.0. + * \return Whether the action succeeded. */ -extern int AUD_playDevice(AUD_Device* device, AUD_Sound* sound); +extern int AUD_setDeviceSoundVolume(AUD_Device* device, + AUD_Handle* handle, + float volume); /** * Reads the next samples into the supplied buffer. diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index e9f6eb21e36..cbce4663d6f 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -71,7 +71,7 @@ void sound_update_playing(struct bContext *C); void sound_scrub(struct bContext *C); #ifdef AUD_CAPI -AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end); +AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume); #endif void sound_stop_all(struct bContext *C); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6f9ed3e0978..a9d7caaf5e0 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -419,7 +419,7 @@ Scene *add_scene(char *name) pset->brush[PE_BRUSH_CUT].strength= 100; sce->jumpframe = 10; - sce->r.audio.mixrate = 44100; + sce->r.ffcodecdata.audio_mixrate = 44100; strcpy(sce->r.backbuf, "//backbuf"); strcpy(sce->r.pic, U.renderdir); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 2d5d8dad7a8..fdf6283925e 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -421,7 +421,7 @@ void sound_scrub(struct bContext *C) int cfra = CFRA; float fps = FPS; - if(scene->r.audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer) + if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer) { AUD_lock(); @@ -443,13 +443,14 @@ void sound_scrub(struct bContext *C) } } -AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end) +AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume) { AUD_Device* mixdown = AUD_openReadDevice(specs); SoundHandle *handle; float fps = FPS; AUD_Sound *limiter, *delayer; int frameskip, s, e; + AUD_Handle* h; end++; @@ -470,7 +471,8 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps); delayer = AUD_delaySound(limiter, s / fps); - AUD_playDevice(mixdown, delayer); + h = AUD_playDevice(mixdown, delayer); + AUD_setDeviceSoundVolume(mixdown, h, volume); AUD_unload(delayer); AUD_unload(limiter); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index a90924055b3..1953058fddf 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -559,7 +559,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex c->codec_id = codec_id; c->codec_type = CODEC_TYPE_AUDIO; - c->sample_rate = rd->audio.mixrate; + c->sample_rate = rd->ffcodecdata.audio_mixrate; c->bit_rate = ffmpeg_audio_bitrate*1000; c->channels = 2; codec = avcodec_find_encoder(c->codec_id); @@ -734,7 +734,7 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) if (ffmpeg_type == FFMPEG_DV) { fmt->audio_codec = CODEC_ID_PCM_S16LE; - if (ffmpeg_multiplex_audio && rd->audio.mixrate != 48000) { + if (ffmpeg_multiplex_audio && rd->ffcodecdata.audio_mixrate != 48000) { G.afbreek = 1; //XXX error("FFMPEG only supports 48khz / stereo " // "audio for DV!"); @@ -831,7 +831,6 @@ static void makeffmpegstring(RenderData* rd, char* string) { } } - void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty) { ffmpeg_autosplit_count = 0; @@ -844,8 +843,8 @@ void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty) AUD_Specs specs; specs.channels = c->channels; specs.format = AUD_FORMAT_S16; - specs.rate = rd->audio.mixrate; - audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra); + specs.rate = rd->ffcodecdata.audio_mixrate; + audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra, rd->ffcodecdata.audio_volume); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c5dcf1ce520..2d612cffc7d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9354,7 +9354,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* toolsettings */ for(scene= main->scene.first; scene; scene= scene->id.next) - scene->r.audio = scene->audio; + { + scene->r.ffcodecdata.audio_mixrate = scene->audio.mixrate; + scene->r.ffcodecdata.audio_volume = scene->audio.main; + } /* shader, composit and texture node trees have id.name empty, put something in * to have them show in RNA viewer and accessible otherwise. diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a055041d8ae..ef28ff6dbd1 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2206,7 +2206,7 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) /* sync, don't sync, or follow scene setting */ if(sad->flag & ANIMPLAY_FLAG_SYNC) sync= 1; else if(sad->flag & ANIMPLAY_FLAG_NO_SYNC) sync= 0; - else sync= (scene->r.audio.flag & AUDIO_SYNC); + else sync= (scene->audio.flag & AUDIO_SYNC); if(sync) { /* skip frames */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 73afc3d1a53..b41cd79b6d4 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -93,6 +93,8 @@ typedef struct FFMpegCodecData { int audio_codec; int video_bitrate; int audio_bitrate; + int audio_mixrate; + int audio_volume; int gop_size; int flags; @@ -106,8 +108,8 @@ typedef struct FFMpegCodecData { typedef struct AudioData { - int mixrate; - float main; /* Main mix in dB */ + int mixrate; // 2.5: now in FFMpegCodecData: audio_mixrate + float main; // 2.5: now in FFMpegCodecData: audio_volume short flag; short pad[3]; } AudioData; @@ -170,7 +172,6 @@ typedef struct RenderData { struct AviCodecData *avicodecdata; struct QuicktimeCodecData *qtcodecdata; struct FFMpegCodecData ffcodecdata; - struct AudioData audio; /* new in 2.5 */ int cfra, sfra, efra; /* frames as in 'images' */ int psfra, pefra; /* start+end frames of preview range */ @@ -697,7 +698,7 @@ typedef struct Scene { /* migrate or replace? depends on some internal things... */ /* no, is on the right place (ton) */ struct RenderData r; - struct AudioData audio; /* DEPRECATED 2.5 */ + struct AudioData audio; ListBase markers; ListBase transform_spaces; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 08efa13d8f4..d6991a3a624 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1512,6 +1512,19 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "ffcodecdata.flags", FFMPEG_MULTIPLEX_AUDIO); RNA_def_property_ui_text(prop, "Multiplex Audio", "Interleave audio with the output video"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "ffmpeg_audio_mixrate", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.audio_mixrate"); + RNA_def_property_range(prop, 8000, 192000); + RNA_def_property_ui_text(prop, "Sample", "Audio samplerate(samples/s)"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "ffmpeg_audio_volume", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "ffcodecdata.audio_volume"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Volume", "Audio volume"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + #endif prop= RNA_def_property(srna, "fps", PROP_INT, PROP_NONE); @@ -1583,11 +1596,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fields Still", "Disable the time difference between fields."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC); - RNA_def_property_ui_text(prop, "Sync Audio", "Play back and sync with audio from Sequence Editor"); - RNA_def_property_update(prop, NC_SCENE, NULL); - prop= RNA_def_property(srna, "render_shadows", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SHADOW); RNA_def_property_ui_text(prop, "Render Shadows", "Calculate shadows while rendering."); @@ -2063,6 +2071,22 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "TimelineMarker"); RNA_def_property_ui_text(prop, "Timeline Markers", "Markers used in all timelines for the current scene."); + /* Audio Settings */ + prop= RNA_def_property(srna, "mute_audio", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_MUTE); + RNA_def_property_ui_text(prop, "Mute Audio", "Play back of audio from Sequence Editor will be muted."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC); + RNA_def_property_ui_text(prop, "Sync Audio", "Play back and sync with audio from Sequence Editor."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "scrub_audio", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SCRUB); + RNA_def_property_ui_text(prop, "Scrub Audio", "Play audio from Sequence Editor while scrubbing."); + RNA_def_property_update(prop, NC_SCENE, NULL); + /* Game Settings */ prop= RNA_def_property(srna, "game_data", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); -- cgit v1.2.3 From ec8c47f0c08bf500bbf5d5fe6a833942c7710d29 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 20 Sep 2009 14:14:40 +0000 Subject: * UI for recent sound commit. --- release/ui/buttons_scene.py | 2 ++ release/ui/space_time.py | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index c25e6352aaf..6f283bb5d5b 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -323,8 +323,10 @@ class SCENE_PT_encoding(RenderButtonsPanel): col = split.column() col.itemR(rd, "ffmpeg_audio_bitrate") + col.itemR(rd, "ffmpeg_audio_mixrate") col = split.column() col.itemR(rd, "ffmpeg_multiplex_audio") + col.itemR(rd, "ffmpeg_audio_volume") class SCENE_PT_antialiasing(RenderButtonsPanel): __label__ = "Anti-Aliasing" diff --git a/release/ui/space_time.py b/release/ui/space_time.py index bb82eea3272..b51b1d8af79 100644 --- a/release/ui/space_time.py +++ b/release/ui/space_time.py @@ -9,7 +9,6 @@ class TIME_HT_header(bpy.types.Header): st = context.space_data scene = context.scene - rd = context.scene.render_data tools = context.tool_settings screen = context.screen @@ -55,7 +54,7 @@ class TIME_HT_header(bpy.types.Header): subsub = row.row() subsub.itemR(tools, "record_with_nla", toggle=True) - layout.itemR(rd, "sync_audio", text="", toggle=True, icon='ICON_SPEAKER') + layout.itemR(scene, "sync_audio", text="", toggle=True, icon='ICON_SPEAKER') layout.itemS() @@ -112,7 +111,7 @@ class TIME_MT_playback(bpy.types.Menu): layout = self.layout st = context.space_data - rd = context.scene.render_data + scene = context.scene layout.itemR(st, "play_top_left") layout.itemR(st, "play_all_3d") @@ -127,10 +126,10 @@ class TIME_MT_playback(bpy.types.Menu): layout.itemS() - layout.itemR(rd, "sync_audio", icon='ICON_SPEAKER') + layout.itemR(scene, "sync_audio", icon='ICON_SPEAKER') + layout.itemR(scene, "mute_audio") + layout.itemR(scene, "scrub_audio") - - class TIME_MT_autokey(bpy.types.Menu): __space_type__ = 'TIMELINE' __label__ = "Auto-Keyframing Mode" -- cgit v1.2.3 From 85e529433b62b27680203221083481db04e867a1 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Sep 2009 15:02:14 +0000 Subject: 2.5 filebrowser * fix selection related bugs: ** selection outside filelist would select first item ** border select would enter directory even if more than one is selected --- source/blender/editors/space_file/file_ops.c | 49 ++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index faca6db75bf..5603c0bb2e4 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -68,7 +68,7 @@ /* ---------- FILE SELECTION ------------ */ -static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short y, short clamp) +static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short y) { float fx,fy; int active_file = -1; @@ -78,15 +78,6 @@ static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short UI_view2d_region_to_view(v2d, x, y, &fx, &fy); active_file = ED_fileselect_layout_offset(sfile->layout, v2d->tot.xmin + fx, v2d->tot.ymax - fy); - - if(active_file < 0) { - if(clamp) active_file= 0; - else active_file= -1; - } - else if(active_file >= numfiles) { - if(clamp) active_file= numfiles-1; - else active_file= -1; - } return active_file; } @@ -109,6 +100,31 @@ typedef enum FileSelect { FILE_SELECT_DIR = 1, FILE_SELECT_FILE = 2 } FileSelect; +static void clamp_to_filelist(int numfiles, int *first_file, int *last_file) +{ + /* border select before the first file */ + if ( (*first_file < 0) && (*last_file >=0 ) ) { + *first_file = 0; + } + /* don't select if everything is outside filelist */ + if ( (*first_file >= numfiles) && ((*last_file < 0) || (*last_file >= numfiles)) ) { + *first_file = -1; + *last_file = -1; + } + + /* fix if last file invalid */ + if ( (*first_file > 0) && (*last_file < 0) ) + *last_file = numfiles-1; + + /* clamp */ + if ( (*first_file >= numfiles) ) { + *first_file = numfiles-1; + } + if ( (*last_file >= numfiles) ) { + *last_file = numfiles-1; + } +} + static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short val) { int first_file = -1; @@ -123,9 +139,11 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s int numfiles = filelist_numfiles(sfile->files); params->selstate = NOTACTIVE; - first_file = find_file_mouse(sfile, ar, rect->xmin, rect->ymax, 1); - last_file = find_file_mouse(sfile, ar, rect->xmax, rect->ymin, 1); + first_file = find_file_mouse(sfile, ar, rect->xmin, rect->ymax); + last_file = find_file_mouse(sfile, ar, rect->xmax, rect->ymin); + clamp_to_filelist(numfiles, &first_file, &last_file); + /* select all valid files between first and last indicated */ if ( (first_file >= 0) && (first_file < numfiles) && (last_file >= 0) && (last_file < numfiles) ) { for (act_file = first_file; act_file <= last_file; act_file++) { @@ -137,6 +155,9 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s } } + /* Don't act on multiple selected files */ + if (first_file != last_file) selecting= 0; + /* make the last file active */ if (selecting && (last_file >= 0 && last_file < numfiles)) { struct direntry* file = filelist_file(sfile->files, last_file); @@ -168,7 +189,7 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s } } - } + } return retval; } @@ -449,7 +470,7 @@ int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my) my -= ar->winrct.ymin; if(BLI_in_rcti(&ar->v2d.mask, mx, my)) { - actfile = find_file_mouse(sfile, ar, mx , my, 0); + actfile = find_file_mouse(sfile, ar, mx , my); if((actfile >= 0) && (actfile < numfiles)) params->active_file=actfile; -- cgit v1.2.3 From 4b6c61e0a704a713d13090231aa73056ff48c6d4 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Sep 2009 15:30:52 +0000 Subject: 2.5 filebrowser * changed filebrowser operator property "filename" to "path" - fixed two missing operators. * small cleanup in init of filebrowser --- source/blender/editors/curve/editfont.c | 10 +++++----- source/blender/editors/space_buttons/buttons_ops.c | 2 +- source/blender/editors/space_file/filesel.c | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 868c5902670..2be567e1921 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -381,19 +381,19 @@ static int paste_file(bContext *C, ReportList *reports, char *filename) static int paste_file_exec(bContext *C, wmOperator *op) { - char *filename; + char *path; int retval; - filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0); - retval= paste_file(C, op->reports, filename); - MEM_freeN(filename); + path= RNA_string_get_alloc(op->ptr, "path", NULL, 0); + retval= paste_file(C, op->reports, path); + MEM_freeN(path); return retval; } static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if(RNA_property_is_set(op->ptr, "filename")) + if(RNA_property_is_set(op->ptr, "path")) return paste_file_exec(C, op); WM_event_add_fileselect(C, op); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 9b335b86163..5466a06550b 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -1107,7 +1107,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= fbo; str= RNA_property_string_get_alloc(&ptr, prop, 0, 0); - RNA_string_set(op->ptr, "filename", str); + RNA_string_set(op->ptr, "path", str); MEM_freeN(str); WM_event_add_fileselect(C, op); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index a0787ef989d..e9e09d8f60b 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -117,8 +117,6 @@ short ED_fileselect_set_params(SpaceFile *sfile) BLI_strncpy(sfile->params->file, file, sizeof(sfile->params->file)); BLI_make_file_string(G.sce, sfile->params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ } - - ED_fileselect_reset_params(sfile); params = sfile->params; -- cgit v1.2.3 From d3e88cb3e0d4117ab845a7c77254a5ab05ce1657 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 20 Sep 2009 16:49:05 +0000 Subject: *fix bone weighting forgot to call RE_rayobject_done --- source/blender/editors/armature/meshlaplacian.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index c994f7789a0..436048f5427 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -422,6 +422,7 @@ static void heat_ray_tree_create(LaplacianSystem *sys) sys->heat.vface[mface->v3]= mface; if(mface->v4) sys->heat.vface[mface->v4]= mface; } + RE_rayobject_done(sys->heat.raytree); } static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone) -- cgit v1.2.3 From e4a50e3f47de157b4213062d1dea9ff5c1ab0104 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Sep 2009 17:23:57 +0000 Subject: 2.5 filebrowser * fix crash when filebrowser tried to invoke the file_exec or file_cancel in cases no operator was set. --- source/blender/editors/space_file/file_ops.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 5603c0bb2e4..16c8733cb5b 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -526,6 +526,16 @@ int file_cancel_exec(bContext *C, wmOperator *unused) return OPERATOR_FINISHED; } +int file_operator_poll(bContext *C) +{ + int poll = ED_operator_file_active(C); + SpaceFile *sfile= CTX_wm_space_file(C); + + if (!sfile->op) poll= 0; + + return poll; +} + void FILE_OT_cancel(struct wmOperatorType *ot) { /* identifiers */ @@ -534,7 +544,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot) /* api callbacks */ ot->exec= file_cancel_exec; - ot->poll= ED_operator_file_active; + ot->poll= file_operator_poll; } /* sends events now, so things get handled on windowqueue level */ @@ -612,7 +622,7 @@ void FILE_OT_execute(struct wmOperatorType *ot) /* api callbacks */ ot->exec= file_exec; - ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ + ot->poll= file_operator_poll; } -- cgit v1.2.3 From 4f6ea2b683b81fe12642f92e8f0e0d48904f2c6c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 20 Sep 2009 17:24:56 +0000 Subject: Ghost/Compiz bug: Sometimes, events for window size or move are sent even when the window hasn't changed. This triggers unneeded refreshes. As a precaution, we now ignore all such events (eventually, it should be done in Ghost X11, but I don't know that code well enough). --- source/blender/windowmanager/intern/wm_window.c | 78 ++++++++++++++++--------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 9d3d0a9535e..c853afe4507 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -627,6 +627,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) if(state!=GHOST_kWindowStateMinimized) { GHOST_RectangleHandle client_rect; int l, t, r, b, scr_w, scr_h; + int sizex, sizey, posx, posy; client_rect= GHOST_GetClientBounds(win->ghostwin); GHOST_GetRectangle(client_rect, &l, &t, &r, &b); @@ -634,37 +635,56 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) GHOST_DisposeRectangle(client_rect); wm_get_screensize(&scr_w, &scr_h); - win->sizex= r-l; - win->sizey= b-t; - win->posx= l; - win->posy= scr_h - t - win->sizey; - - /* debug prints */ - if(0) { - state = GHOST_GetWindowState(win->ghostwin); - - if(state==GHOST_kWindowStateNormal) { - if(G.f & G_DEBUG) printf("window state: normal\n"); - } - else if(state==GHOST_kWindowStateMinimized) { - if(G.f & G_DEBUG) printf("window state: minimized\n"); - } - else if(state==GHOST_kWindowStateMaximized) { - if(G.f & G_DEBUG) printf("window state: maximized\n"); + sizex= r-l; + sizey= b-t; + posx= l; + posy= scr_h - t - win->sizey; + + /* + * Ghost sometimes send size or move events when the window hasn't changed. + * One case of this is using compiz on linux. To alleviate the problem + * we ignore all such event here. + * + * It might be good to eventually do that at Ghost level, but that is for + * another time. + */ + if (win->sizex != sizex || + win->sizey != sizey || + win->posx != posx || + win->posy != posy) + { + win->sizex= sizex; + win->sizey= sizey; + win->posx= posx; + win->posy= posy; + + /* debug prints */ + if(0) { + state = GHOST_GetWindowState(win->ghostwin); + + if(state==GHOST_kWindowStateNormal) { + if(G.f & G_DEBUG) printf("window state: normal\n"); + } + else if(state==GHOST_kWindowStateMinimized) { + if(G.f & G_DEBUG) printf("window state: minimized\n"); + } + else if(state==GHOST_kWindowStateMaximized) { + if(G.f & G_DEBUG) printf("window state: maximized\n"); + } + else if(state==GHOST_kWindowStateFullScreen) { + if(G.f & G_DEBUG) printf("window state: fullscreen\n"); + } + + if(type!=GHOST_kEventWindowSize) { + if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey); + } + } - else if(state==GHOST_kWindowStateFullScreen) { - if(G.f & G_DEBUG) printf("window state: fullscreen\n"); - } - - if(type!=GHOST_kEventWindowSize) { - if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey); - } - + + wm_window_make_drawable(C, win); + wm_draw_window_clear(win); + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } - - wm_window_make_drawable(C, win); - wm_draw_window_clear(win); - WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } break; } -- cgit v1.2.3 From 189263e1d9cd1cfdb2e9a96a01761858e8deaa7c Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 20 Sep 2009 17:55:03 +0000 Subject: Sound: * Fixed mixdown volume being int instead of float * Fixed audio muting for sequencer not working * Added 3D listener settings with RNA (not working in GE yet) --- source/blender/blenkernel/intern/scene.c | 4 ++++ source/blender/blenkernel/intern/sound.c | 2 +- source/blender/blenloader/intern/readfile.c | 19 +++++++++------ source/blender/makesdna/DNA_scene_types.h | 7 ++++-- source/blender/makesrna/intern/rna_scene.c | 36 +++++++++++++++++++++++++---- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index a9d7caaf5e0..4de9ff3b6d9 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -421,6 +421,10 @@ Scene *add_scene(char *name) sce->jumpframe = 10; sce->r.ffcodecdata.audio_mixrate = 44100; + sce->audio.distance_model = 2.0; + sce->audio.doppler_factor = 1.0; + sce->audio.speed_of_sound = 343.3; + strcpy(sce->r.backbuf, "//backbuf"); strcpy(sce->r.pic, U.renderdir); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index fdf6283925e..c6c4a776faf 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -340,7 +340,7 @@ void sound_update_playing(struct bContext *C) for(handle = scene->sound_handles.first; handle; handle = handle->next) { - if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute) + if(cfra < handle->startframe || cfra >= handle->endframe || handle->mute || (scene->audio.flag & AUDIO_MUTE)) { if(handle->state == AUD_STATUS_PLAYING) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2d612cffc7d..78949d8bd8c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9352,13 +9352,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) */ //do_versions_ipos_to_animato(main); - /* toolsettings */ - for(scene= main->scene.first; scene; scene= scene->id.next) - { - scene->r.ffcodecdata.audio_mixrate = scene->audio.mixrate; - scene->r.ffcodecdata.audio_volume = scene->audio.main; - } - /* shader, composit and texture node trees have id.name empty, put something in * to have them show in RNA viewer and accessible otherwise. */ @@ -9714,6 +9707,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + + for(sce= main->scene.first; sce; sce= sce->id.next) + { + if(sce->audio.main == 0.0) + sce->audio.main = 1.0; + + sce->r.ffcodecdata.audio_mixrate = sce->audio.mixrate; + sce->r.ffcodecdata.audio_volume = sce->audio.main; + sce->audio.distance_model = 2.0; + sce->audio.doppler_factor = 1.0; + sce->audio.speed_of_sound = 343.3; + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index b41cd79b6d4..5521f0e9315 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -94,7 +94,7 @@ typedef struct FFMpegCodecData { int video_bitrate; int audio_bitrate; int audio_mixrate; - int audio_volume; + float audio_volume; int gop_size; int flags; @@ -110,8 +110,11 @@ typedef struct FFMpegCodecData { typedef struct AudioData { int mixrate; // 2.5: now in FFMpegCodecData: audio_mixrate float main; // 2.5: now in FFMpegCodecData: audio_volume + float speed_of_sound; + float doppler_factor; + int distance_model; short flag; - short pad[3]; + short pad; } AudioData; typedef struct SceneRenderLayer { diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index d6991a3a624..ff8102a3111 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1516,7 +1516,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop= RNA_def_property(srna, "ffmpeg_audio_mixrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ffcodecdata.audio_mixrate"); RNA_def_property_range(prop, 8000, 192000); - RNA_def_property_ui_text(prop, "Sample", "Audio samplerate(samples/s)"); + RNA_def_property_ui_text(prop, "Samplerate", "Audio samplerate(samples/s)"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "ffmpeg_audio_volume", PROP_FLOAT, PROP_NONE); @@ -1915,6 +1915,16 @@ void RNA_def_scene(BlenderRNA *brna) PropertyRNA *prop; FunctionRNA *func; + static EnumPropertyItem audio_distance_model_items[] = { + {0, "NONE", 0, "None", "No distance attenuation."}, + {1, "INVERSE", 0, "Inverse", "Inverse distance model."}, + {2, "INVERSE_CLAMPED", 0, "Inverse Clamped", "Inverse distance model with clamping."}, + {3, "LINEAR", 0, "Linear", "Linear distance model."}, + {4, "LINEAR_CLAMPED", 0, "Linear Clamped", "Linear distance model with clamping."}, + {5, "EXPONENT", 0, "Exponent", "Exponent distance model."}, + {6, "EXPONENT_CLAMPED", 0, "Exponent Clamped", "Exponent distance model with clamping."}, + {0, NULL, 0, NULL, NULL}}; + /* Struct definition */ srna= RNA_def_struct(brna, "Scene", "ID"); RNA_def_struct_ui_text(srna, "Scene", "Scene consisting objects and defining time and render related settings."); @@ -2074,17 +2084,35 @@ void RNA_def_scene(BlenderRNA *brna) /* Audio Settings */ prop= RNA_def_property(srna, "mute_audio", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_MUTE); - RNA_def_property_ui_text(prop, "Mute Audio", "Play back of audio from Sequence Editor will be muted."); + RNA_def_property_ui_text(prop, "Audio Muted", "Play back of audio from Sequence Editor will be muted."); RNA_def_property_update(prop, NC_SCENE, NULL); prop= RNA_def_property(srna, "sync_audio", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SYNC); - RNA_def_property_ui_text(prop, "Sync Audio", "Play back and sync with audio from Sequence Editor."); + RNA_def_property_ui_text(prop, "Audio Sync", "Play back and sync with audio from Sequence Editor."); RNA_def_property_update(prop, NC_SCENE, NULL); prop= RNA_def_property(srna, "scrub_audio", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "audio.flag", AUDIO_SCRUB); - RNA_def_property_ui_text(prop, "Scrub Audio", "Play audio from Sequence Editor while scrubbing."); + RNA_def_property_ui_text(prop, "Audio Scrubbing", "Play audio from Sequence Editor while scrubbing."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "speed_of_sound", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "audio.speed_of_sound"); + RNA_def_property_range(prop, 1.0f, FLT_MAX); + RNA_def_property_ui_text(prop, "Speed of Sound", "Speed of sound for doppler effect calculation."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "doppler_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "audio.doppler_factor"); + RNA_def_property_range(prop, FLT_MIN, FLT_MAX); + RNA_def_property_ui_text(prop, "Doppler Factor", "Pitch factor for doppler effect calculation."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "distance_model", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "audio.distance_model"); + RNA_def_property_enum_items(prop, audio_distance_model_items); + RNA_def_property_ui_text(prop, "Distance Model", "Distance model for distance attenuation calculation."); RNA_def_property_update(prop, NC_SCENE, NULL); /* Game Settings */ -- cgit v1.2.3 From 3b4410367f1011f91cd91022b17c59917bf3ee34 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Sep 2009 18:26:02 +0000 Subject: 2.5 filebrowser more bugfixes: * removed refreshing code at file_init again, causes issues when resizing * free library in the filelist after use * make sure directory exists when library file for append/link doesn't exist, so browsing can continue from valid dir. --- source/blender/editors/space_file/file_ops.c | 2 ++ source/blender/editors/space_file/filelist.c | 2 ++ source/blender/editors/space_file/space_file.c | 11 +---------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 16c8733cb5b..70d8de7d509 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -518,6 +518,7 @@ int file_cancel_exec(bContext *C, wmOperator *unused) sfile->op = NULL; if (sfile->files) { + filelist_freelib(sfile->files); filelist_free(sfile->files); MEM_freeN(sfile->files); sfile->files= NULL; @@ -606,6 +607,7 @@ int file_exec(bContext *C, wmOperator *unused) fsmenu_write_file(fsmenu_get(), name); WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC); + filelist_freelib(sfile->files); filelist_free(sfile->files); MEM_freeN(sfile->files); sfile->files= NULL; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 582a5997ef5..8257aa5482f 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -804,6 +804,8 @@ static void filelist_read_library(struct FileList* filelist) if(!filelist->libfiledata) { int num; struct direntry *file; + + BLI_make_exist(filelist->dir); filelist_read_dir(filelist); file = filelist->filelist; for(num=0; numnumfiles; num++, file++) { diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 99d649b28cc..56dbdcbc645 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -156,16 +156,6 @@ static void file_free(SpaceLink *sl) static void file_init(struct wmWindowManager *wm, ScrArea *sa) { SpaceFile *sfile= (SpaceFile*)sa->spacedata.first; - if(sfile->params) { - MEM_freeN(sfile->params); - sfile->params = 0; - ED_fileselect_set_params(sfile); - if (sfile->files) { - filelist_free(sfile->files); - MEM_freeN(sfile->files); - sfile->files= NULL; - } - } printf("file_init\n"); } @@ -213,6 +203,7 @@ static void file_refresh(const bContext *C, ScrArea *sa) if (filelist_empty(sfile->files)) { filelist_readdir(sfile->files); + BLI_strncpy(params->dir, filelist_dir(sfile->files), FILE_MAX); } if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort); -- cgit v1.2.3 From 1de250014de04fb3312725f1fecc6327fa86666d Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 20 Sep 2009 18:35:14 +0000 Subject: Sound: * 3D listener now working in GE --- source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp | 7 +++++++ source/gameengine/BlenderRoutines/CMakeLists.txt | 1 + source/gameengine/BlenderRoutines/SConscript | 1 + 3 files changed, 9 insertions(+) diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index ae46f880711..1ede16f017e 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -89,6 +89,8 @@ extern "C" { #include "DNA_scene_types.h" /***/ +#include "AUD_C-API.h" + //XXX #include "BSE_headerbuttons.h" #include "BKE_context.h" #include "../../blender/windowmanager/WM_types.h" @@ -386,6 +388,11 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw if(blscene->gm.stereoflag == STEREO_DOME) ketsjiengine->InitDome(blscene->gm.dome.res, blscene->gm.dome.mode, blscene->gm.dome.angle, blscene->gm.dome.resbuf, blscene->gm.dome.tilt, blscene->gm.dome.warptext); + // initialize 3D Audio Settings + AUD_set3DSetting(AUD_3DS_SPEED_OF_SOUND, blscene->audio.speed_of_sound); + AUD_set3DSetting(AUD_3DS_DOPPLER_FACTOR, blscene->audio.doppler_factor); + AUD_set3DSetting(AUD_3DS_DISTANCE_MODEL, blscene->audio.distance_model); + if (sceneconverter) { // convert and add scene diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index ee15fd99ed5..ce85c1185b0 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -6,6 +6,7 @@ SET(INC ../../../source/kernel/gen_system ../../../intern/string ../../../intern/guardedalloc + ../../../intern/audaspace/intern ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer ../../../source/gameengine/Converter ../../../source/blender/imbuf diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index ad6f9f23fce..1e8ff3c48e8 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -8,6 +8,7 @@ incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc' incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer' incs += ' #source/gameengine/Converter #source/blender/imbuf' incs += ' #intern/ghost/include' +incs += ' #intern/audaspace/intern' incs += ' #intern/moto/include #source/gameengine/Ketsji #source/blender/blenlib' incs += ' #source/blender/blenkernel #source/blender' incs += ' #source/blender/blenfont #source/blender/editors/include' -- cgit v1.2.3 From 85294c6d7e1fcb4bacf39c0ff8c310c5b5a9139f Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 20 Sep 2009 18:49:46 +0000 Subject: 2.5 Game Sound: * Added Sound Buttons for Game in the Scene Buttons. --- release/ui/buttons_game.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/release/ui/buttons_game.py b/release/ui/buttons_game.py index 73ba566e23f..f3461d3e370 100644 --- a/release/ui/buttons_game.py +++ b/release/ui/buttons_game.py @@ -304,12 +304,25 @@ class SCENE_PT_game_performance(SceneButtonsPanel): col.itemL(text="Render:") col.itemR(gs, "all_frames") col.itemR(gs, "display_lists") + +class SCENE_PT_game_sound(SceneButtonsPanel): + __label__ = "Sound" + + def draw(self, context): + layout = self.layout + + scene = context.scene + + layout.itemR(scene, "distance_model") + layout.itemR(scene, "speed_of_sound", text="Speed") + layout.itemR(scene, "doppler_factor") bpy.types.register(SCENE_PT_game) bpy.types.register(SCENE_PT_game_player) bpy.types.register(SCENE_PT_game_stereo) bpy.types.register(SCENE_PT_game_shading) bpy.types.register(SCENE_PT_game_performance) +bpy.types.register(SCENE_PT_game_sound) class WorldButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' -- cgit v1.2.3 From 6d4fb84c4eeeeacca953906883a6f328fd9ffcee Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 20 Sep 2009 19:10:12 +0000 Subject: 2.5 filebrowser * fix crash in autocomplete for very long paths * allow longer paths in directory button * added some TODO comments for G.lib --- source/blender/editors/space_file/file_draw.c | 2 +- source/blender/editors/space_file/filesel.c | 5 ++++- source/blender/windowmanager/intern/wm_operators.c | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 00024ffa961..46ed6987752 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -189,7 +189,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar) if (available_w > 0) { but = uiDefBut(block, TEX, B_FS_DIRNAME, "", min_x, line1_y, line1_w, btn_h, - params->dir, 0.0, (float)FILE_MAXDIR-1, 0, 0, + params->dir, 0.0, (float)FILE_MAX-1, 0, 0, "File path."); uiButSetCompleteFunc(but, autocomplete_directory, NULL); uiDefBut(block, TEX, B_FS_FILENAME, "", diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index e9e09d8f60b..dd16a426899 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -417,13 +417,16 @@ void autocomplete_directory(struct bContext *C, char *str, void *arg_v) struct direntry* file = filelist_file(sfile->files, i); const char* dir = filelist_dir(sfile->files); if (file && S_ISDIR(file->type)) { - BLI_make_file_string(G.sce, tmp, dir, file->relname); + // BLI_make_file_string(G.sce, tmp, dir, file->relname); + BLI_join_dirfile(tmp, dir, file->relname); autocomplete_do_name(autocpl,tmp); } } autocomplete_end(autocpl, str); if (BLI_exists(str)) { BLI_add_slash(str); + } else { + BLI_make_exist(str); } } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a6fc575ce70..76c15043b89 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -943,7 +943,7 @@ static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event) return WM_operator_call(C, op); } else { - /* XXX solve where to get last linked library from */ + /* XXX TODO solve where to get last linked library from */ RNA_string_set(op->ptr, "path", G.lib); WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; @@ -1064,6 +1064,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) DAG_ids_flush_update(0); BLO_blendhandle_close(bh); + + /* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */ BLI_strncpy(G.lib, dir, FILE_MAX); WM_event_add_notifier(C, NC_WINDOW, NULL); -- cgit v1.2.3 From b11acc659b823300f8c300930494931ffcfe52c0 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sun, 20 Sep 2009 20:14:34 +0000 Subject: Add audaspace search path. --- source/gameengine/BlenderRoutines/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile index 4b65da667ef..4a437aff97d 100644 --- a/source/gameengine/BlenderRoutines/Makefile +++ b/source/gameengine/BlenderRoutines/Makefile @@ -40,6 +40,7 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) +CPPFLAGS += -I$(NAN_AUDASPACE)/include # because of kernel dependency on makesdna CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I../../blender/editors/include -- cgit v1.2.3 From 76447ef615d7f9755ee46e3e07ee0c11acdaac91 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sun, 20 Sep 2009 20:21:01 +0000 Subject: Update condition checks to match user definable CC and CCC. Also make faster to notice which FIX_NAN_WARN as not been replaced. --- source/nan_warn.mk | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/nan_warn.mk b/source/nan_warn.mk index b685c13604d..0dd4e0b8147 100644 --- a/source/nan_warn.mk +++ b/source/nan_warn.mk @@ -34,19 +34,19 @@ # # Force the correct redefinition -LEVEL_1_C_WARNINGS = -FIX_NAN_WARN -LEVEL_1_CPP_WARNINGS = -FIX_NAN_WARN -LEVEL_2_C_WARNINGS = -FIX_NAN_WARN -LEVEL_2_CPP_WARNINGS = -FIX_NAN_WARN -FIX_STUBS_WARNINGS = -FIX_NAN_WARN +LEVEL_1_C_WARNINGS = -FIX_NAN_WARN1A +LEVEL_1_CPP_WARNINGS = -FIX_NAN_WARN1B +LEVEL_2_C_WARNINGS = -FIX_NAN_WARN2A +LEVEL_2_CPP_WARNINGS = -FIX_NAN_WARN2B +FIX_STUBS_WARNINGS = -FIX_NAN_WARN3 ######################################################################## # Level 1: basic C warnings. -ifeq ($(CC),gcc) +ifeq (gcc, $(findstring gcc,$(CC))) LEVEL_1_C_WARNINGS = -Wall LEVEL_1_C_WARNINGS += -Wno-char-subscripts else - ifeq ($(CC),cc) + ifeq (cc, $(findstring cc,$(CC))) ifeq ($(OS),irix) # MIPSpro Compilers # @@ -71,11 +71,11 @@ else endif # Level 1: basic CPP warnings. -ifeq ($(CCC),g++) +ifeq (g++, $(findstring g++,$(CCC))) LEVEL_1_CPP_WARNINGS = -Wall LEVEL_1_CPP_WARNINGS += -Wno-reorder else - ifeq ($(CCC),CC) + ifeq (CC, $(findstring CC,$(CCC))) ifeq ($(OS),irix) # MIPSpro Compilers # see warning descriptions above @@ -91,7 +91,7 @@ endif ######################################################################## # Level 2: paranoia level C warnings. # DO NOT REUSE LEVEL_1_ DEFINES. -ifeq ($(CC),gcc) +ifeq (gcc, $(findstring gcc,$(CC))) LEVEL_2_C_WARNINGS = -Wall LEVEL_2_C_WARNINGS += -W # deliberately enable char-subscript warnings @@ -107,7 +107,7 @@ ifeq ($(CC),gcc) LEVEL_2_C_WARNINGS += -Wnested-externs LEVEL_2_C_WARNINGS += -Wredundant-decls else - ifeq ($(CC),cc) + ifeq (cc, $(findstring cc,$(CC))) ifeq ($(OS),irix) # MIPSpro Compilers # see warning descriptions above @@ -126,7 +126,7 @@ endif # Level 2: paranoia level CPP warnings. # DO NOT REUSE LEVEL_1_ DEFINES. -ifeq ($(CCC),g++) +ifeq (g++, $(findstring g++,$(CCC))) LEVEL_2_CPP_WARNINGS = -Wall LEVEL_2_CPP_WARNINGS += -W # deliberately enable char-subscript warnings @@ -144,7 +144,7 @@ ifeq ($(CCC),g++) LEVEL_2_CPP_WARNINGS += -Wsign-promo LEVEL_2_CPP_WARNINGS += -Wsynth else - ifeq ($(CCC),CC) + ifeq (CC, $(findstring CC,$(CCC))) ifeq ($(OS),irix) # MIPSpro Compilers # see warning descriptions above @@ -159,7 +159,7 @@ endif ######################################################################## # stubs warning fix -ifeq ($(CC),gcc) +ifeq (gcc, $(findstring gcc,$(CC))) FIX_STUBS_WARNINGS = -Wno-unused else FIX_STUBS_WARNINGS = -- cgit v1.2.3 From f560eb0c466e284208f37c3cda2d6c27f7e6bf58 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 21 Sep 2009 00:48:36 +0000 Subject: New transform input function for joeedh, to be used for edge slide. Like Vertical or Horizontal ratio input, but along a line defined by two points on screen. --- source/blender/editors/transform/transform.h | 6 ++- .../blender/editors/transform/transform_generics.c | 7 +++- source/blender/editors/transform/transform_input.c | 46 ++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index e5bd405c0cd..2ff6d6d3dce 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -210,6 +210,7 @@ typedef struct MouseInput { short precision_mval[2]; /* mouse position when precision key was pressed */ int center[2]; float factor; + void *data; /* additional data, if needed by the particular function */ } MouseInput; typedef struct TransInfo { @@ -575,7 +576,8 @@ typedef enum { INPUT_HORIZONTAL_RATIO, INPUT_HORIZONTAL_ABSOLUTE, INPUT_VERTICAL_RATIO, - INPUT_VERTICAL_ABSOLUTE + INPUT_VERTICAL_ABSOLUTE, + INPUT_CUSTOM_RATIO } MouseInputMode; void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], short mval[2]); @@ -583,6 +585,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode); int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event); void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, short mval[2], float output[3]); +void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2]); + /*********************** Generics ********************************/ int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0b7029adde0..d93e92616e1 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1052,7 +1052,7 @@ void postTrans (TransInfo *t) } MEM_freeN(t->data); } - + if (t->ext) MEM_freeN(t->ext); if (t->data2d) { MEM_freeN(t->data2d); @@ -1068,6 +1068,11 @@ void postTrans (TransInfo *t) if (t->customData) MEM_freeN(t->customData); } + + if (t->mouse.data) + { + MEM_freeN(t->mouse.data); + } } void applyTransObjects(TransInfo *t) diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 6bd0a8c8d42..e1e4569623b 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -163,6 +163,47 @@ void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float ou output[0] = Inpf(t->viewinv[1], vec) * 2.0f; } +void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2]) +{ + short *data = mi->data; + + data[0] = start[0]; + data[1] = start[1]; + data[2] = end[0]; + data[3] = end[1]; +} + +void InputCustomRatio(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) +{ + float length; + float distance; + short *data = mi->data; + short dx, dy; + + dx = data[2] - data[0]; + dy = data[3] - data[1]; + + length = (float)sqrtf(dx*dx + dy*dy); + + if (mi->precision) { + /* deal with Shift key by adding motion / 10 to motion before shift press */ + short mdx, mdy; + 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 = (mdx*dx + mdy*dy) / length; + } + else { + short mdx, mdy; + mdx = mval[0] - data[2]; + mdy = mval[1] - data[3]; + + distance = (mdx*dx + mdy*dy) / length; + } + + output[0] = distance / length; +} + void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) { double dx2 = mval[0] - mi->center[0]; @@ -291,6 +332,11 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) mi->apply = InputVerticalAbsolute; t->helpline = HLP_VARROW; break; + case INPUT_CUSTOM_RATIO: + mi->apply = InputCustomRatio; + t->helpline = HLP_NONE; + mi->data = MEM_callocN(sizeof(short) * 4, "custom points"); + break; case INPUT_NONE: default: mi->apply = NULL; -- cgit v1.2.3 From 6c655aa2a762e440ba3f64ce8520c6ce41268d3e Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 21 Sep 2009 01:32:37 +0000 Subject: * Testing removing the click-region-edge-to-minimise functionality It was getting very annoying, hitting it by accident and having the region disappear. Now, you can still hide the region by resizing it down to zero, or by using the hotkeys (i.e. N, or T in the 3D View). Perhaps this minimising would be better done in a RMB menu on sub-regions (i.e. like previous Header: top/bottom/hide stuff) --- source/blender/editors/screen/screen_ops.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index ef28ff6dbd1..f4af0cd6883 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1348,9 +1348,11 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) if(event->val==0) { if(ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) { - ED_region_toggle_hidden(C, rmd->ar); - WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); - } + if(rmd->ar->flag & RGN_FLAG_HIDDEN) { + ED_region_toggle_hidden(C, rmd->ar); + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); + } + } MEM_freeN(op->customdata); op->customdata = NULL; -- cgit v1.2.3 From e7abdd7d56256b57d9e33326af253188ed9d96dc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 03:16:26 +0000 Subject: Better unix filesystem integration as documented here http://wiki.blender.org/index.php/BlenderDev/Blender2.5/Unix_FHS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for scons WITH_BF_FHS enabled an alternative layout eg. scons WITH_BF_FHS=1 BF_INSTALLDIR="/usr/local" for CMake just run "make install" after make (CMAKE_INSTALL_PREFIX is used for the base path) Currently only scripts use both the system and user path correctly, other areas of blender have their own path code inline with lots of ifdefs, needs to be carefully updated. --- CMakeLists.txt | 4 + SConstruct | 59 +++++++--- config/darwin-config.py | 1 - config/irix6-config.py | 1 - config/linux2-config.py | 2 - config/linuxcross-config.py | 1 - config/openbsd3-config.py | 1 - config/sunos5-config.py | 1 - config/win32-mingw-config.py | 1 - config/win32-vc-config.py | 1 - config/win64-vc-config.py | 1 - source/blender/blenlib/BLI_util.h | 9 +- source/blender/blenlib/intern/util.c | 169 +++++++++++++++------------ source/blender/python/intern/bpy_interface.c | 99 +++++++--------- source/creator/CMakeLists.txt | 31 +++++ source/creator/SConscript | 5 + source/creator/creator.c | 24 ++++ source/gameengine/PyDoc/SConscript | 7 +- tools/Blender.py | 5 +- tools/btools.py | 8 +- 20 files changed, 270 insertions(+), 160 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c881dec03db..504ef5d8dd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,10 @@ PROJECT(Blender) SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) +# Note! - Could create this from the blender version string +# ...but thats quite involved, make sure this matches the blender version. +SET(BLENDER_VERSION 2.5) + #----------------------------------------------------------------------------- # Set default config options OPTION(WITH_PLAYER "Build Player" OFF) diff --git a/SConstruct b/SConstruct index 83ec6c1b718..402bf18faf5 100644 --- a/SConstruct +++ b/SConstruct @@ -186,6 +186,15 @@ if not env['BF_FANCY']: SetOption('num_jobs', int(env['BF_NUMJOBS'])) print "Build with %d parallel jobs" % (GetOption('num_jobs')) +# BLENDERPATH is a unix only option to enable typical style paths this is +# spesifically a data-dir, which is used a lot but cant replace BF_INSTALLDIR +# because the blender binary is installed in $BF_INSTALLDIR/bin/blender + +if env['WITH_BF_FHS']: + BLENDERPATH = os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) +else: + BLENDERPATH = env['BF_INSTALLDIR'] + # disable elbeem (fluidsim) compilation? if env['BF_NO_ELBEEM'] == 1: env['CPPFLAGS'].append('-DDISABLE_ELBEEM') @@ -198,7 +207,7 @@ if env['WITH_BF_OPENMP'] == 1: env['CPPFLAGS'].append('/openmp') env['CXXFLAGS'].append('/openmp') else: - if env['CC'][-3:] == 'icc': # to be able to handle CC=/opt/bla/icc case + if env['CC'].endswith('icc'): # to be able to handle CC=/opt/bla/icc case env.Append(LINKFLAGS=['-openmp', '-static-intel']) env['CCFLAGS'].append('-openmp') env['CPPFLAGS'].append('-openmp') @@ -301,7 +310,7 @@ if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-min # lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir B.root_build_dir = env['BF_BUILDDIR'] -B.doc_build_dir = env['BF_DOCDIR'] +B.doc_build_dir = os.path.join(BLENDERPATH, 'doc') if not B.root_build_dir[-1]==os.sep: B.root_build_dir += os.sep if not B.doc_build_dir[-1]==os.sep: @@ -426,7 +435,10 @@ if env['OURPLATFORM']=='darwin': source=[dp+os.sep+f for f in df] blenderinstall.append(env.Install(dir=dir,source=source)) else: - blenderinstall = env.Install(dir=env['BF_INSTALLDIR'], source=B.program_list) + if env['WITH_BF_FHS']: dir= os.path.join(env['BF_INSTALLDIR'], 'bin') + else: dir= env['BF_INSTALLDIR'] + + blenderinstall = env.Install(dir=dir, source=B.program_list) #-- .blender #- dont do .blender and scripts for darwin, it is already in the bundle @@ -450,7 +462,13 @@ if env['OURPLATFORM']!='darwin': continue dotblendlist.append(os.path.join(dp, f)) - dottargetlist.append(env['BF_INSTALLDIR']+dp[3:]+os.sep+f) + if env['WITH_BF_FHS']: dir= os.path.join(*([BLENDERPATH] + dp.split(os.sep)[2:])) # skip bin/.blender + else: dir= os.path.join(*([BLENDERPATH] + dp.split(os.sep)[1:])) # skip bin + + # print dir+ os.sep + f + print dir + dottargetlist.append(dir + os.sep + f) + dotblenderinstall = [] for targetdir,srcfile in zip(dottargetlist, dotblendlist): @@ -464,8 +482,12 @@ if env['OURPLATFORM']!='darwin': for dp, dn, df in os.walk(scriptpath): if '.svn' in dn: dn.remove('.svn') - dir=env['BF_INSTALLDIR']+'/.blender/'+os.path.basename(scriptpath)+dp[len(scriptpath):] - source=[dp+os.sep+f for f in df] + + if env['WITH_BF_FHS']: dir = BLENDERPATH + else: dir = os.path.join(env['BF_INSTALLDIR'], '.blender') + dir += os.sep + os.path.basename(scriptpath) + dp[len(scriptpath):] + + source=[os.path.join(dp, f) for f in df] scriptinstall.append(env.Install(dir=dir,source=source)) #-- icons @@ -477,8 +499,8 @@ if env['OURPLATFORM']=='linux2': if '.svn' in tn: tn.remove('.svn') for f in tf: - iconlist.append(tp+os.sep+f) - icontargetlist.append(env['BF_INSTALLDIR']+tp[19:]+os.sep+f) + iconlist.append(os.path.join(tp, f)) + icontargetlist.append( os.path.join(*([BLENDERPATH] + tp.split(os.sep)[2:] + [f])) ) iconinstall = [] for targetdir,srcfile in zip(icontargetlist, iconlist): @@ -499,24 +521,25 @@ for tp, tn, tf in os.walk('release/plugins'): if '.svn' in tn: tn.remove('.svn') for f in tf: - pluglist.append(tp+os.sep+f) - plugtargetlist.append(env['BF_INSTALLDIR']+tp[7:]+os.sep+f) + pluglist.append(os.path.join(tp, f)) + plugtargetlist.append( os.path.join(*([BLENDERPATH] + tp.split(os.sep)[1:] + [f])) ) + # header files for plugins pluglist.append('source/blender/blenpluginapi/documentation.h') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'documentation.h') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'documentation.h')) pluglist.append('source/blender/blenpluginapi/externdef.h') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'externdef.h') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'externdef.h')) pluglist.append('source/blender/blenpluginapi/floatpatch.h') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'floatpatch.h') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'floatpatch.h')) pluglist.append('source/blender/blenpluginapi/iff.h') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'iff.h') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'iff.h')) pluglist.append('source/blender/blenpluginapi/plugin.h') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'plugin.h') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'plugin.h')) pluglist.append('source/blender/blenpluginapi/util.h') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'util.h') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'util.h')) pluglist.append('source/blender/blenpluginapi/plugin.DEF') -plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep + 'plugin.def') +plugtargetlist.append(os.path.join(BLENDERPATH, 'plugins', 'include', 'plugin.def')) plugininstall = [] for targetdir,srcfile in zip(plugtargetlist, pluglist): @@ -531,7 +554,7 @@ for tp, tn, tf in os.walk('release/text'): for f in tf: textlist.append(tp+os.sep+f) -textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist) +textinstall = env.Install(dir=BLENDERPATH, source=textlist) if env['OURPLATFORM']=='darwin': allinstall = [blenderinstall, plugininstall, textinstall] diff --git a/config/darwin-config.py b/config/darwin-config.py index 92f70d716fc..981f321e5bc 100644 --- a/config/darwin-config.py +++ b/config/darwin-config.py @@ -274,4 +274,3 @@ BF_DEBUG_CCFLAGS = ['-g'] BF_BUILDDIR='../build/darwin' BF_INSTALLDIR='../install/darwin' -BF_DOCDIR='../install/doc' diff --git a/config/irix6-config.py b/config/irix6-config.py index d38665f282a..085d1dd1e62 100644 --- a/config/irix6-config.py +++ b/config/irix6-config.py @@ -189,7 +189,6 @@ BF_DEBUG_FLAGS = '-g' BF_BUILDDIR = '../build/irix6' BF_INSTALLDIR='../install/irix6' -BF_DOCDIR='../install/doc' #Link against pthread LDIRS = [] diff --git a/config/linux2-config.py b/config/linux2-config.py index 757b8210e49..026d0a200a5 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -189,8 +189,6 @@ BF_DEBUG_CCFLAGS = ['-g'] BF_BUILDDIR = '../build/linux2' BF_INSTALLDIR='../install/linux2' -BF_DOCDIR='../install/doc' - #Link against pthread PLATFORM_LINKFLAGS = ['-pthread'] diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index a7ce2dc2908..a5c83dc3503 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -139,4 +139,3 @@ BF_PROFILE_LINKFLAGS = ['-pg'] BF_BUILDDIR = '../build/linuxcross' BF_INSTALLDIR='../install/linuxcross' -BF_DOCDIR='../install/doc' diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py index 95649321c07..353d30f50b3 100644 --- a/config/openbsd3-config.py +++ b/config/openbsd3-config.py @@ -151,4 +151,3 @@ BF_DEBUG_CCFLAGS = ['-g'] BF_BUILDDIR='../build/openbsd3' BF_INSTALLDIR='../install/openbsd3' -BF_DOCDIR='../install/doc' diff --git a/config/sunos5-config.py b/config/sunos5-config.py index 8af30e4f4f3..8e4c53b5bc4 100644 --- a/config/sunos5-config.py +++ b/config/sunos5-config.py @@ -165,7 +165,6 @@ BF_DEBUG_CCFLAGS = [] BF_BUILDDIR = '../build/sunos5' BF_INSTALLDIR='../install/sunos5' -BF_DOCDIR='../install/doc' PLATFORM_LINKFLAGS = [] diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index e3834c41a81..04e9f5eb4d1 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -152,4 +152,3 @@ BF_PROFILE = False BF_BUILDDIR = '..\\build\\win32-mingw' BF_INSTALLDIR='..\\install\\win32-mingw' -BF_DOCDIR = '..\\install\\doc' diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 1e993565e98..4f2af93d0e3 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -173,4 +173,3 @@ PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/INCREMENTAL:NO','/N BF_BUILDDIR = '..\\build\\win32-vc' BF_INSTALLDIR='..\\install\\win32-vc' -BF_DOCDIR='..\\install\\doc' diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index ce2fd8cd405..b48e3875dd5 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -192,7 +192,6 @@ PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/INCREMENTAL:NO','/NO BF_BUILDDIR = '..\\build\\blender25-win64-vc' BF_INSTALLDIR='..\\install\\blender25-win64-vc' -BF_DOCDIR='..\\install\\blender25-win64-vc\\doc' diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h index f9a84e071e7..1ce7a8cdb77 100644 --- a/source/blender/blenlib/BLI_util.h +++ b/source/blender/blenlib/BLI_util.h @@ -42,7 +42,14 @@ struct ListBase; struct direntry; char *BLI_gethome(void); -char *BLI_gethome_folder(char *folder_name); +char *BLI_gethome_folder(char *folder_name, int flag); + +/* BLI_gethome_folder flag */ +#define BLI_GETHOME_LOCAL 1<<1 /* relative location for portable binaries */ +#define BLI_GETHOME_SYSTEM 1<<2 /* system location, or set from the BLENDERPATH env variable (UNIX only) */ +#define BLI_GETHOME_USER 1<<3 /* home folder ~/.blender */ +#define BLI_GETHOME_ALL (BLI_GETHOME_SYSTEM|BLI_GETHOME_LOCAL|BLI_GETHOME_USER) + void BLI_setenv(const char *env, const char *val); void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file); diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index c7bb7a54457..b1539d22909 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -856,98 +856,123 @@ char *BLI_gethome(void) { #endif } -/* this function returns the path to a blender folder, if it exists, - * trying in this order: - * - * path_to_executable/release/folder_name (in svn) - * ./release/folder_name (in svn) - * $HOME/.blender/folder_name - * path_to_executable/.blender/folder_name - * - * returns NULL if none is found. */ +/* this function returns the path to a blender folder, if it exists + * utility functions for BLI_gethome_folder */ + +/* #define PATH_DEBUG */ /* for testing paths that are checked */ + +static int test_data_path(char *targetpath, char *path_base, char *path_sep, char *folder_name) +{ + char tmppath[FILE_MAXDIR]; + + if(path_sep) BLI_join_dirfile(tmppath, path_base, path_sep); + else BLI_strncpy(tmppath, path_base, sizeof(tmppath)); + + BLI_make_file_string("/", targetpath, tmppath, folder_name); + + if (BLI_exists(targetpath)) { +#ifdef PATH_DEBUG + printf("\tpath found: %s\n", targetpath); +#endif + return 1; + } + else { +#ifdef PATH_DEBUG + printf("\tpath missing: %s\n", targetpath); +#endif + targetpath[0] = '\0'; + return 0; + } +} -char *BLI_gethome_folder(char *folder_name) +static int gethome_path_local(char *targetpath, char *folder_name) { extern char bprogname[]; /* argv[0] from creator.c */ - static char homedir[FILE_MAXDIR] = ""; - static char fulldir[FILE_MAXDIR] = ""; - char tmpdir[FILE_MAXDIR]; char bprogdir[FILE_MAXDIR]; + char cwd[FILE_MAXDIR]; char *s; int i; - + +#ifdef PATH_DEBUG + printf("gethome_path_local...\n"); +#endif + + /* try release/folder_name (binary relative) */ /* use argv[0] (bprogname) to get the path to the executable */ s = BLI_last_slash(bprogname); - i = s - bprogname + 1; BLI_strncpy(bprogdir, bprogname, i); + + /* try ./.blender/folder_name */ + if(test_data_path(targetpath, bprogdir, ".blender", folder_name)) + return 1; + + if(test_data_path(targetpath, bprogdir, "release", folder_name)) + return 1; + + /* try release/folder_name (CWD relative) */ + if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name)) + return 1; + + return 0; +} - /* try path_to_executable/release/folder_name (in svn) */ - if (folder_name) { - BLI_snprintf(tmpdir, sizeof(tmpdir), "release/%s", folder_name); - BLI_make_file_string("/", fulldir, bprogdir, tmpdir); - if (BLI_exists(fulldir)) return fulldir; - else fulldir[0] = '\0'; - } +static int gethome_path_user(char *targetpath, char *folder_name) +{ + char *home_path= BLI_gethome(); - /* try ./release/folder_name (in svn) */ - if(folder_name) { - BLI_snprintf(fulldir, sizeof(fulldir), "./release/%s", folder_name); - if (BLI_exists(fulldir)) return fulldir; - else fulldir[0] = '\0'; - } +#ifdef PATH_DEBUG + printf("gethome_path_user...\n"); +#endif + + /* try $HOME/folder_name */ + return test_data_path(targetpath, home_path, ".blender", folder_name); +} - /* BLI_gethome() can return NULL if env vars are not set */ - s = BLI_gethome(); +static int gethome_path_system(char *targetpath, char *folder_name) +{ + extern char blender_path[]; /* unix prefix eg. /usr/share/blender/2.5 creator.c */ + + if(!blender_path[0]) + return 0; + +#ifdef PATH_DEBUG + printf("gethome_path_system...\n"); +#endif + + /* try $BLENDERPATH/folder_name */ + return test_data_path(targetpath, blender_path, NULL, folder_name); +} - if(!s) { /* bail if no $HOME */ - printf("$HOME is NOT set\n"); - return NULL; +char *BLI_gethome_folder(char *folder_name, int flag) +{ + static char fulldir[FILE_MAXDIR] = ""; + + /* first check if this is a redistributable bundle */ + if(flag & BLI_GETHOME_LOCAL) { + if (gethome_path_local(fulldir, folder_name)) + return fulldir; } - if(strstr(s, ".blender")) - BLI_strncpy(homedir, s, FILE_MAXDIR); - else - BLI_make_file_string("/", homedir, s, ".blender"); - - /* if $HOME/.blender/folder_name exists, return it */ - if(BLI_exists(homedir)) { - if (folder_name) { - BLI_make_file_string("/", fulldir, homedir, folder_name); - if(BLI_exists(fulldir)) - return fulldir; - } - else - return homedir; - } - else - homedir[0] = '\0'; - - /* using tmpdir to preserve homedir (if) found above: - * the ideal is to have a home dir with folder_name dir inside - * it, but if that isn't available, it's possible to - * have a 'broken' home dir somewhere and a folder_name dir in the - * svn sources */ - BLI_make_file_string("/", tmpdir, bprogdir, ".blender"); - - if(BLI_exists(tmpdir)) { - if(folder_name) { - BLI_make_file_string("/", fulldir, tmpdir, folder_name); - if(BLI_exists(fulldir)) { - BLI_strncpy(homedir, tmpdir, FILE_MAXDIR); - return fulldir; - } - else { - homedir[0] = '\0'; - fulldir[0] = '\0'; - } - } - else return homedir; + /* then check if the OS has blender data files installed in a global location */ + if(flag & BLI_GETHOME_SYSTEM) { + if (gethome_path_system(fulldir, folder_name)) + return fulldir; } - + + /* now check the users home dir for data files */ + if(flag & BLI_GETHOME_USER) { + if (gethome_path_user(fulldir, folder_name)) + return fulldir; + } + return NULL; } +#ifdef PATH_DEBUG +#undef PATH_DEBUG +#endif + void BLI_setenv(const char *env, const char*val) { /* SGI or free windows */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index a850809b4a5..fd8cfc47f55 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -232,26 +232,10 @@ static PyObject *CreateGlobalDictionary( bContext *C ) return dict; } -/* Use this so we can include our own python bundle */ -#if 0 -wchar_t* Py_GetPath(void) -{ - int i; - static wchar_t py_path[FILE_MAXDIR] = L""; - char *dirname= BLI_gethome_folder("python"); - if(dirname) { - i= mbstowcs(py_path, dirname, FILE_MAXDIR); - printf("py path %s, %d\n", dirname, i); - } - return py_path; -} -#endif - - /* must be called before Py_Initialize */ void BPY_start_python_path(void) { - char *py_path_bundle= BLI_gethome_folder("python"); + char *py_path_bundle= BLI_gethome_folder("python", BLI_GETHOME_ALL); if(py_path_bundle==NULL) return; @@ -589,7 +573,8 @@ void BPY_run_ui_scripts(bContext *C, int reload) char *dirname; char path[FILE_MAX]; char *dirs[] = {"ui", "io", NULL}; - int a, err; + int path_flags[] = {BLI_GETHOME_LOCAL|BLI_GETHOME_SYSTEM, BLI_GETHOME_USER}; /* SYSTEM / NON-SYSTEM */ + int a, err, flag_iter; PyGILState_STATE gilstate; PyObject *sys_path; @@ -599,56 +584,60 @@ void BPY_run_ui_scripts(bContext *C, int reload) sys_path= PySys_GetObject("path"); /* borrow */ PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */ - for(a=0; dirs[a]; a++) { - dirname= BLI_gethome_folder(dirs[a]); + /* Scan system scripts first, then local/user */ + for(flag_iter=0; flag_iter < sizeof(path_flags)/sizeof(int); flag_iter++) { + + for(a=0; dirs[a]; a++) { + dirname= BLI_gethome_folder(dirs[a], path_flags[flag_iter]); - if(!dirname) - continue; + if(!dirname) + continue; - dir = opendir(dirname); + dir = opendir(dirname); - if(!dir) - continue; - - /* set the first dir in the sys.path for fast importing of modules */ - PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */ + if(!dir) + continue; - while((de = readdir(dir)) != NULL) { - /* We could stat the file but easier just to let python - * import it and complain if theres a problem */ - err = 0; - - if (de->d_name[0] == '.') { - /* do nothing, probably .svn */ - } - else if ((file_extension = strstr(de->d_name, ".py"))) { - /* normal py files? */ - if(file_extension && file_extension[3] == '\0') { - de->d_name[(file_extension - de->d_name)] = '\0'; - err= bpy_import_module(de->d_name, reload); + /* set the first dir in the sys.path for fast importing of modules */ + PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */ + + while((de = readdir(dir)) != NULL) { + /* We could stat the file but easier just to let python + * import it and complain if theres a problem */ + err = 0; + + if (de->d_name[0] == '.') { + /* do nothing, probably .svn */ + } + else if ((file_extension = strstr(de->d_name, ".py"))) { + /* normal py files? */ + if(file_extension && file_extension[3] == '\0') { + de->d_name[(file_extension - de->d_name)] = '\0'; + err= bpy_import_module(de->d_name, reload); + } } - } #ifndef __linux__ - else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) { + else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) { #else - else if(de->d_type==DT_DIR) { - BLI_join_dirfile(path, dirname, de->d_name); + else if(de->d_type==DT_DIR) { + BLI_join_dirfile(path, dirname, de->d_name); #endif - /* support packages */ - BLI_join_dirfile(path, path, "__init__.py"); + /* support packages */ + BLI_join_dirfile(path, path, "__init__.py"); - if(BLI_exists(path)) { - err= bpy_import_module(de->d_name, reload); + if(BLI_exists(path)) { + err= bpy_import_module(de->d_name, reload); + } } - } - if(err==-1) { - BPy_errors_to_report(NULL); - fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name); + if(err==-1) { + BPy_errors_to_report(NULL); + fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name); + } } - } - closedir(dir); + closedir(dir); + } } PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */ diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 1256881182b..410e0808580 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -66,6 +66,13 @@ IF(NOT WITH_SDL) ADD_DEFINITIONS(-DDISABLE_SDL) ENDIF(NOT WITH_SDL) +IF(UNIX AND NOT APPLE) + SET(BLENDERPATH ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION}) + CMAKE_POLICY(SET CMP0005 NEW) + # blender_path in creator.c + ADD_DEFINITIONS(-DBLENDERPATH="${BLENDERPATH}") +ENDIF(UNIX AND NOT APPLE) + IF(CMAKE_SYSTEM_NAME MATCHES "Linux") ADD_DEFINITIONS(-DWITH_BINRELOC) INCLUDE_DIRECTORIES(${BINRELOC_INC}) @@ -96,6 +103,9 @@ IF(WITH_INSTALL) ENDIF(UNIX) IF(UNIX AND NOT APPLE) + + # Local installation, "make install" can be done after this optionally + ADD_CUSTOM_COMMAND( TARGET blender POST_BUILD MAIN_DEPENDENCY blender COMMAND rm -Rf ${TARGETDIR}/.blender @@ -152,6 +162,27 @@ IF(WITH_INSTALL) COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;" ) + + # Above we bundle a portable distrobution in ./bin + # This is an optional "make install" which installs blender on the system. + INSTALL( + PROGRAMS ${TARGETDIR}/blender + DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + ) + + IF(WITH_GAMEENGINE AND WITH_PLAYER) + INSTALL( + PROGRAMS ${TARGETDIR}/blenderplayer + DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + ) + ENDIF(WITH_GAMEENGINE AND WITH_PLAYER) + + INSTALL( + DIRECTORY ${TARGETDIR}/.blender/ + DESTINATION ${BLENDERPATH} + ) + # end "make install" + ENDIF(UNIX AND NOT APPLE) IF(APPLE) diff --git a/source/creator/SConscript b/source/creator/SConscript index 75e7494ebb5..7b3d1493ed2 100644 --- a/source/creator/SConscript +++ b/source/creator/SConscript @@ -1,5 +1,6 @@ #!/usr/bin/python Import ('env') +import os sources = 'creator.c' @@ -32,4 +33,8 @@ if env['WITH_BF_PYTHON']: else: defs.append('DISABLE_PYTHON') +if env['WITH_BF_FHS']: # /usr -> /usr/share/blender/2.5 + defs.append('BLENDERPATH=\\"' + os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) + '\\"') + + env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 ) diff --git a/source/creator/creator.c b/source/creator/creator.c index 41b27b1c915..523273de9bf 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -116,6 +116,18 @@ extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */ char bprogname[FILE_MAXDIR+FILE_MAXFILE]; /* from blenpluginapi:pluginapi.c */ char btempdir[FILE_MAXDIR+FILE_MAXFILE]; +/* unix path support. + * defined by the compiler. eg "/usr/share/blender/2.5" "/opt/blender/2.5" */ +#ifndef BLENDERPATH +#define BLENDERPATH "" +#endif + +#if !(defined(__APPLE__) && defined(WIN32)) +char blender_path[FILE_MAXDIR+FILE_MAXFILE] = BLENDERPATH; +#else +char blender_path[FILE_MAXDIR+FILE_MAXFILE] = ""; +#endif + /* Initialise callbacks for the modules that need them */ static void setCallbacks(void); @@ -221,6 +233,12 @@ static void print_help(void) printf (" \t\t passed unchanged. Access via Python's sys.argv\n"); printf ("\nEnvironment Variables:\n"); printf (" $HOME\t\t\tStore files such as .blender/ .B.blend .Bfs .Blog here.\n"); +#if !(defined(__APPLE__) && defined(WIN32)) + printf (" $BLENDERPATH\tSystem directory to use for data files and scripts.\n"); + printf (" \tFor this build of blender the default BLENDERPATH is...\n"); + printf (" \t\"%s\"\n", blender_path); + printf (" \tseting the $BLENDERPATH will override this\n"); +#endif #ifdef WIN32 printf (" $TEMP\t\tStore temporary files here.\n"); #else @@ -305,6 +323,12 @@ int main(int argc, char **argv) BLI_where_am_i(bprogname, argv[0]); + { /* override the hard coded blender path */ + char *blender_path_env = getenv("BLENDERPATH"); + if(blender_path_env) + BLI_strncpy(blender_path, blender_path_env, sizeof(blender_path)); + } + RNA_init(); RE_engines_init(); diff --git a/source/gameengine/PyDoc/SConscript b/source/gameengine/PyDoc/SConscript index ed9712ba273..dabe004ae6a 100644 --- a/source/gameengine/PyDoc/SConscript +++ b/source/gameengine/PyDoc/SConscript @@ -1,6 +1,11 @@ #!/usr/bin/python Import ('env') +import os +if env['WITH_BF_FHS']: + BLENDERPATH = os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) +else: + BLENDERPATH = env['BF_INSTALLDIR'] from optparse import OptionParser import epydoc @@ -14,7 +19,7 @@ optvalues["quiet"] = 0 optvalues["include_source_code"] = 0 optvalues["inheritance"] = "included" optvalues["show_private"] = 0 -optvalues["target"] = env["BF_DOCDIR"]+"/BGE_API/" +optvalues["target"] = os.path.join(BLENDERPATH, 'doc') optvalues["url"] = "http://www.blender.org" optvalues["top"] = "Game Engine API" optvalues["name"] = "Blender" diff --git a/tools/Blender.py b/tools/Blender.py index d7cbe1076e7..fd6272c7c32 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -405,8 +405,11 @@ def PyInstall(target=None, source=None, env=None): print 'Install command:', cmd commands.getoutput(cmd) + if env['WITH_BF_FHS']: dir = os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) # BLENDERPATH + else: dir = os.path.join(env['BF_INSTALLDIR'], '.blender') + py_src = env.subst( env['BF_PYTHON_LIBPATH'] + '/python'+env['BF_PYTHON_VERSION'] ) - py_target = env.subst( env['BF_INSTALLDIR'] + '/.blender/python/lib/python'+env['BF_PYTHON_VERSION'] ) + py_target = env.subst( dir + '/python/lib/python'+env['BF_PYTHON_VERSION'] ) # Copied from source/creator/CMakeLists.txt, keep in sync. print 'Install python from:' diff --git a/tools/btools.py b/tools/btools.py index 7cadab992b8..771c67aee1f 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -69,6 +69,8 @@ def validate_arguments(args, bc): 'WITH_BF_DOCS', 'BF_NUMJOBS', 'BF_MSVS', + 'WITH_BF_FHS', + 'BF_VERSION', ] # Have options here that scons expects to be lists @@ -91,7 +93,7 @@ def validate_arguments(args, bc): 'BF_BSC', 'BF_CONFIG', 'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG', 'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG', - 'BF_DOCDIR', 'BF_UNIT_TEST'] + 'BF_UNIT_TEST'] okdict = {} @@ -362,7 +364,6 @@ def read_opts(cfg, args): ('BF_BUILDDIR', 'Build dir', ''), ('BF_INSTALLDIR', 'Installation dir', ''), - ('BF_DOCDIR', 'Dir where BPy documentation will be created', ''), ('CC', 'C compiler to use', ''), ('CXX', 'C++ compiler to use', ''), @@ -387,6 +388,9 @@ def read_opts(cfg, args): ('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'), ('BF_NUMJOBS', 'Number of build processes to spawn', '1'), ('BF_MSVS', 'Generate MSVS project files and solution', False), + + (BoolVariable('WITH_BF_FHS', 'Use the Unix "Filesystem Hierarchy Standard" rather then a redistributable directory layout', False)), + ('BF_VERSION', 'The root path for Unix (non-apple)', '2.5'), (BoolVariable('BF_UNIT_TEST', 'Build with unit test support.', False)) -- cgit v1.2.3 From ad7fab49d4346315cdb3db4bd087714ae45ffc89 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 05:56:43 +0000 Subject: 5 button mouse support from b333rt in IRC with some edits for X11. Tested in X11 where its fairly confusing. buttons 4 and 5 are used for the wheel which is well known, but it seems 6 and 7 are used for horizontal scrolling, my mouse assigns the extra 2 buttons to events 8 & 9. So the X11 events used for buttons called 4&5 in blender are 8&9 in X11. The mouse buttons can be re-ordered like this once xorg starts (swaps 6,7 with 8,9) xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" Couldn't test Win32, Apple not supported. If someone wants to add horizontal scrolling its quite easy. --- intern/ghost/GHOST_Types.h | 2 ++ intern/ghost/intern/GHOST_SystemWin32.cpp | 34 +++++++++++++++++++++- intern/ghost/intern/GHOST_SystemX11.cpp | 7 ++++- source/blender/editors/space_outliner/outliner.c | 4 +++ source/blender/makesrna/intern/rna_wm.c | 2 ++ .../blender/windowmanager/intern/wm_event_system.c | 4 +++ source/blender/windowmanager/wm_event_types.h | 3 ++ 7 files changed, 54 insertions(+), 2 deletions(-) diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 73ed0bdd1fa..31819f341a0 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -132,6 +132,8 @@ typedef enum { GHOST_kButtonMaskLeft = 0, GHOST_kButtonMaskMiddle, GHOST_kButtonMaskRight, + GHOST_kButtonMaskButton4, + GHOST_kButtonMaskButton5, GHOST_kButtonNumMasks } GHOST_TButtonMask; diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 8513d056795..2e89be40bcb 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -39,7 +39,6 @@ #endif #include "GHOST_SystemWin32.h" -//#include //for printf() // win64 doesn't define GWL_USERDATA #ifdef WIN32 @@ -61,6 +60,23 @@ #define WHEEL_DELTA 120 /* Value for rolling one detent, (old convention! MS changed it) */ #endif // WHEEL_DELTA +/* + * Defines for mouse buttons 4 and 5 aka xbutton1 and xbutton2. + * MSDN: Declared in Winuser.h, include Windows.h + * This does not seem to work with MinGW so we define our own here. + */ +#ifndef XBUTTON1 +#define XBUTTON1 0x0001 +#endif // XBUTTON1 +#ifndef XBUTTON2 +#define XBUTTON2 0x0002 +#endif // XBUTTON2 +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 524 +#endif // WM_XBUTTONUP +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 523 +#endif // WM_XBUTTONDOWN #include "GHOST_Debug.h" #include "GHOST_DisplayManagerWin32.h" @@ -672,6 +688,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, window->registerMouseClickEvent(true); event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight); break; + case WM_XBUTTONDOWN: + window->registerMouseClickEvent(true); + if ((short) HIWORD(wParam) == XBUTTON1){ + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4); + }else if((short) HIWORD(wParam) == XBUTTON2){ + event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5); + } + break; case WM_LBUTTONUP: window->registerMouseClickEvent(false); event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft); @@ -684,6 +708,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, window->registerMouseClickEvent(false); event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight); break; + case WM_XBUTTONUP: + window->registerMouseClickEvent(false); + if ((short) HIWORD(wParam) == XBUTTON1){ + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4); + }else if((short) HIWORD(wParam) == XBUTTON2){ + event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5); + } + break; case WM_MOUSEMOVE: event = processCursorEvent(GHOST_kEventCursorMove, window); break; diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 9f6f3b4d5b0..cdbdce9c2ca 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -444,10 +444,15 @@ GHOST_SystemX11::processEvent(XEvent *xe) XButtonEvent & xbe = xe->xbutton; GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft; - switch (xbe.button) { case Button1 : gbmask = GHOST_kButtonMaskLeft; break; case Button3 : gbmask = GHOST_kButtonMaskRight; break; + /* It seems events 6 and 7 are for horizontal scrolling. + * you can re-order button mapping like this... (swaps 6,7 with 8,9) + * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7" + */ + case 8 : gbmask = GHOST_kButtonMaskButton4; break; /* Button4 is the wheel */ + case 9 : gbmask = GHOST_kButtonMaskButton5; break; /* Button5 is a wheel too */ default: case Button2 : gbmask = GHOST_kButtonMaskMiddle; break; } diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index a3b47d505fd..a1fdbab9ccc 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -5049,6 +5049,8 @@ static char *keymap_mouse_menu(void) str += sprintf(str, formatstr, "Left Mouse", LEFTMOUSE); str += sprintf(str, formatstr, "Middle Mouse", MIDDLEMOUSE); str += sprintf(str, formatstr, "Right Mouse", RIGHTMOUSE); + str += sprintf(str, formatstr, "Button4 Mouse ", BUTTON4MOUSE); + str += sprintf(str, formatstr, "Button5 Mouse ", BUTTON5MOUSE); str += sprintf(str, formatstr, "Action Mouse", ACTIONMOUSE); str += sprintf(str, formatstr, "Select Mouse", SELECTMOUSE); str += sprintf(str, formatstr, "Mouse Move", MOUSEMOVE); @@ -5071,6 +5073,8 @@ static char *keymap_tweak_menu(void) str += sprintf(str, formatstr, "Left Mouse", EVT_TWEAK_L); str += sprintf(str, formatstr, "Middle Mouse", EVT_TWEAK_M); str += sprintf(str, formatstr, "Right Mouse", EVT_TWEAK_R); + str += sprintf(str, formatstr, "Button4 Mouse ", BUTTON4MOUSE); + str += sprintf(str, formatstr, "Button5 Mouse ", BUTTON5MOUSE); str += sprintf(str, formatstr, "Action Mouse", EVT_TWEAK_A); str += sprintf(str, formatstr, "Select Mouse", EVT_TWEAK_S); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index fff51ad8ade..0dd9e3aed42 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -46,6 +46,8 @@ EnumPropertyItem event_type_items[] = { {LEFTMOUSE, "LEFTMOUSE", 0, "Left Mouse", ""}, {MIDDLEMOUSE, "MIDDLEMOUSE", 0, "Middle Mouse", ""}, {RIGHTMOUSE, "RIGHTMOUSE", 0, "Right Mouse", ""}, + {BUTTON4MOUSE, "BUTTON4MOUSE", 0, "Button4 Mouse", ""}, + {BUTTON5MOUSE, "BUTTON5MOUSE", 0, "Button5 Mouse", ""}, {ACTIONMOUSE, "ACTIONMOUSE", 0, "Action Mouse", ""}, {SELECTMOUSE, "SELECTMOUSE", 0, "Select Mouse", ""}, diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 40026d27bac..ebb7adc3cd5 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1579,6 +1579,10 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) event.type= LEFTMOUSE; else if (bd->button == GHOST_kButtonMaskRight) event.type= RIGHTMOUSE; + else if (bd->button == GHOST_kButtonMaskButton4) + event.type= BUTTON4MOUSE; + else if (bd->button == GHOST_kButtonMaskButton5) + event.type= BUTTON5MOUSE; else event.type= MIDDLEMOUSE; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index b331e036b9e..898c6358f3a 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -56,6 +56,9 @@ /* only use if you want user option switch possible */ #define ACTIONMOUSE 0x005 #define SELECTMOUSE 0x006 +/* Extra mouse buttons */ +#define BUTTON4MOUSE 0x007 +#define BUTTON5MOUSE 0x008 /* defaults from ghost */ #define WHEELUPMOUSE 0x00a #define WHEELDOWNMOUSE 0x00b -- cgit v1.2.3 From fcab32fa206838caf1c45c0cdf5facc65e2d6918 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 21 Sep 2009 06:43:20 +0000 Subject: * Added AnimData for Armature data, for animating armature/bone settings. This allows you to do funky things like animating the number of segments in a b-bone. --- source/blender/blenkernel/intern/anim_sys.c | 5 +- source/blender/blenloader/intern/readfile.c | 16 +++-- source/blender/blenloader/intern/writefile.c | 2 + .../editors/animation/anim_channels_defines.c | 71 ++++++++++++++++++++++ source/blender/editors/animation/anim_filter.c | 45 ++++++++++++++ source/blender/editors/include/ED_anim_api.h | 2 + source/blender/makesdna/DNA_action_types.h | 1 + source/blender/makesdna/DNA_armature_types.h | 6 +- source/blender/makesrna/intern/rna_armature.c | 9 ++- 9 files changed, 145 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 8b761a2ee0e..af4bcd8b0f7 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -72,7 +72,7 @@ static short id_has_animdata (ID *id) switch (GS(id->name)) { /* has AnimData */ case ID_OB: - case ID_MB: case ID_CU: + case ID_MB: case ID_CU: case ID_AR: case ID_KE: case ID_PA: case ID_MA: case ID_TE: case ID_NT: @@ -1525,6 +1525,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM); } + /* armatures */ + EVAL_ANIM_IDS(main->armature.first, ADT_RECALC_ANIM); + /* meshes */ // TODO... diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 78949d8bd8c..af7fda82fe4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2331,6 +2331,7 @@ static void lib_link_armature(FileData *fd, Main *main) while(arm) { if(arm->id.flag & LIB_NEEDLINK) { + if (arm->adt) lib_link_animdata(fd, &arm->id, arm->adt); arm->id.flag -= LIB_NEEDLINK; } arm= arm->id.next; @@ -2357,6 +2358,7 @@ static void direct_link_armature(FileData *fd, bArmature *arm) link_list(fd, &arm->bonebase); arm->edbo= NULL; arm->sketch = NULL; + arm->adt= newdataadr(fd, arm->adt); bone=arm->bonebase.first; while (bone) { @@ -9697,15 +9699,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->unit.scale_length= 1.0f; for(ob = main->object.first; ob; ob = ob->id.next) { - ModifierData *md; - - /* add backwards pointer for fluidsim modifier RNA access */ - for (md=ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Fluidsim) { - FluidsimModifierData *fluidmd= (FluidsimModifierData*) md; - fluidmd->fss->fmd = fluidmd; - } - } + FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); + if (fluidmd) fluidmd->fss->fmd = fluidmd; } for(sce= main->scene.first; sce; sce= sce->id.next) @@ -10434,6 +10429,9 @@ 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); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 98db27182ab..37d0ee58bb2 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2116,6 +2116,8 @@ static void write_armatures(WriteData *wd, ListBase *idbase) writestruct(wd, ID_AR, "bArmature", 1, arm); if (arm->id.properties) IDP_WriteProperty(arm->id.properties, wd); + if (arm->adt) write_animdata(wd, arm->adt); + /* Direct data */ bone= arm->bonebase.first; while(bone) { diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index e3418fa194f..7f0f2411bd0 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -1526,6 +1526,76 @@ static bAnimChannelType ACF_DSMBALL= acf_dsmball_setting_ptr /* pointer for setting */ }; +/* Armature Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsarm_icon(bAnimListElem *ale) +{ + return ICON_ARMATURE_DATA; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsarm_setting_flag(int setting, short *neg) +{ + /* clear extra return data first */ + *neg= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return ARM_DS_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ + *neg= 1; + return ADT_CURVES_NOT_VISIBLE; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + bArmature *arm= (bArmature *)ale->data; + + /* clear extra return data first */ + *type= 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + GET_ACF_FLAG_PTR(arm->flag); + + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ + if (arm->adt) + GET_ACF_FLAG_PTR(arm->adt->flag) + else + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* metaball expander type define */ +static bAnimChannelType ACF_DSARM= +{ + acf_generic_dataexpand_backdrop,/* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_dsarm_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsarm_setting_flag, /* flag for setting */ + acf_dsarm_setting_ptr /* pointer for setting */ +}; + + /* ShapeKey Entry ------------------------------------------- */ // XXX ... this is currently obsolete... @@ -1709,6 +1779,7 @@ void ANIM_init_channel_typeinfo_data (void) animchannelTypeInfo[type++]= &ACF_DSWOR; /* World Channel */ animchannelTypeInfo[type++]= &ACF_DSPART; /* Particle Channel */ animchannelTypeInfo[type++]= &ACF_DSMBALL; /* MetaBall Channel */ + animchannelTypeInfo[type++]= &ACF_DSARM; /* Armature Channel */ animchannelTypeInfo[type++]= NULL; /* ShapeKey */ // XXX this is no longer used for now... diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 55fb1ccace0..38b702f81e0 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -52,6 +52,7 @@ #include "DNA_ID.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" +#include "DNA_armature_types.h" #include "DNA_constraint_types.h" #include "DNA_camera_types.h" #include "DNA_curve_types.h" @@ -1101,6 +1102,14 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad expanded= FILTER_MBALL_OBJD(mb); } break; + case OB_ARMATURE: /* ------- Armature ---------- */ + { + bArmature *arm= (bArmature *)ob->data; + + type= ANIMTYPE_DSARM; + expanded= FILTER_ARM_OBJD(arm); + } + break; } /* special exception for drivers instead of action */ @@ -1297,6 +1306,19 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B } } break; + case OB_ARMATURE: /* ------- Armature ---------- */ + { + bArmature *arm= (bArmature *)ob->data; + + if ((ads->filterflag & ADS_FILTER_NOARM) == 0) { + ANIMDATA_FILTER_CASES(arm, + { /* AnimData blocks - do nothing... */ }, + obdata_ok= 1;, + obdata_ok= 1;, + obdata_ok= 1;) + } + } + break; } if (obdata_ok) items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode); @@ -1652,6 +1674,23 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);) } break; + case OB_ARMATURE: /* ------- Armature ---------- */ + { + bArmature *arm= (bArmature *)ob->data; + dataOk= 0; + ANIMDATA_FILTER_CASES(arm, + if ((ads->filterflag & ADS_FILTER_NOARM)==0) { + /* for the special AnimData blocks only case, we only need to add + * the block if it is valid... then other cases just get skipped (hence ok=0) + */ + ANIMDATA_ADD_ANIMDATA(arm); + dataOk=0; + }, + dataOk= !(ads->filterflag & ADS_FILTER_NOARM);, + dataOk= !(ads->filterflag & ADS_FILTER_NOARM);, + dataOk= !(ads->filterflag & ADS_FILTER_NOARM);) + } + break; default: /* --- other --- */ dataOk= 0; break; @@ -1734,6 +1773,12 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int dataOk= ANIMDATA_HAS_KEYS(mb); } break; + case OB_ARMATURE: /* -------- Armature ---------- */ + { + bArmature *arm= (bArmature *)ob->data; + dataOk= ANIMDATA_HAS_KEYS(arm); + } + break; default: /* --- other --- */ dataOk= 0; break; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 799829a6e87..7e7aba85363 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -137,6 +137,7 @@ typedef enum eAnim_ChannelType { ANIMTYPE_DSWOR, ANIMTYPE_DSPART, ANIMTYPE_DSMBALL, + ANIMTYPE_DSARM, ANIMTYPE_SHAPEKEY, // XXX probably can become depreceated??? @@ -206,6 +207,7 @@ typedef enum eAnimFilter_Flags { #define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND)) #define FILTER_PART_OBJD(part) ((part->flag & PART_DS_EXPAND)) #define FILTER_MBALL_OBJD(mb) ((mb->flag2 & MB_DS_EXPAND)) +#define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND)) /* 'Sub-object/Action' channels (flags stored in Action) */ #define SEL_ACTC(actc) ((actc->flag & ACT_SELECTED)) #define EXPANDED_ACTC(actc) ((actc->flag & ACT_COLLAPSED)==0) diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 318204e3dd8..42696eeb092 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -372,6 +372,7 @@ typedef enum DOPESHEET_FILTERFLAG { ADS_FILTER_NOSCE = (1<<15), ADS_FILTER_NOPART = (1<<16), ADS_FILTER_NOMBA = (1<<17), + ADS_FILTER_NOARM = (1<<18), /* NLA-specific filters */ ADS_FILTER_NLA_NOACT = (1<<20), /* if the AnimData block has no NLA data, don't include to just show Action-line */ diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index bb60fb107ff..590e7dadcdc 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -31,6 +31,8 @@ #include "DNA_listBase.h" #include "DNA_ID.h" +struct AnimData; + /* this system works on different transformation space levels; 1) Bone Space; with each Bone having own (0,0,0) origin @@ -69,6 +71,7 @@ typedef struct Bone { typedef struct bArmature { ID id; + struct AnimData *adt; ListBase bonebase; ListBase chainbase; ListBase *edbo; /* editbone listbase, we use pointer so we can check state */ @@ -102,7 +105,8 @@ typedef enum eArmature_Flag { ARM_AUTO_IK = (1<<9), ARM_NO_CUSTOM = (1<<10), /* made option negative, for backwards compat */ ARM_COL_CUSTOM = (1<<11), /* draw custom colours */ - ARM_GHOST_ONLYSEL = (1<<12) /* when ghosting, only show selected bones (this should belong to ghostflag instead) */ + ARM_GHOST_ONLYSEL = (1<<12), /* when ghosting, only show selected bones (this should belong to ghostflag instead) */ + ARM_DS_EXPAND = (1<<13) } eArmature_Flag; /* armature->drawtype */ diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index d06c8ccee03..379ec208bc1 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -62,6 +62,11 @@ static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr) WM_event_add_notifier(C, NC_GEOM|ND_DATA, id); } +static char *rna_Bone_path(PointerRNA *ptr) +{ + return BLI_sprintfN("bones[\"%s\"]", ((Bone*)ptr->data)->name); +} + static void rna_bone_layer_set(short *layer, const int *values) { int i, tot= 0; @@ -431,6 +436,7 @@ static void rna_def_bone(BlenderRNA *brna) srna= RNA_def_struct(brna, "Bone", NULL); RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature datablock."); RNA_def_struct_ui_icon(srna, ICON_BONE_DATA); + RNA_def_struct_path_func(srna, "rna_Bone_path"); /* pointers/collections */ /* parent (pointer) */ @@ -553,9 +559,10 @@ static void rna_def_armature(BlenderRNA *brna) srna= RNA_def_struct(brna, "Armature", "ID"); RNA_def_struct_ui_text(srna, "Armature", "Armature datablock containing a hierarchy of bones, usually used for rigging characters."); RNA_def_struct_ui_icon(srna, ICON_ARMATURE_DATA); - RNA_def_struct_sdna(srna, "bArmature"); + rna_def_animdata_common(srna); + /* Collections */ prop= RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL); -- cgit v1.2.3 From e2e0a864a8c46f4ed836ea7e8fa292276a2137b2 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 21 Sep 2009 07:25:48 +0000 Subject: * Added Armature data filter buttons in Dopesheet/Graph editor headers * Fixed an RNA typo to fix ranges in action constraint --- .../blender/editors/space_action/action_header.c | 1 + source/blender/editors/space_graph/graph_header.c | 1 + source/blender/makesrna/intern/rna_constraint.c | 22 ++++++++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index 4cb02f3f233..dd02302af9c 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -349,6 +349,7 @@ void action_header_buttons(const bContext *C, ARegion *ar) uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Cameras"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Curves"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display MetaBalls"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Armature/Bone"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Particles"); uiBlockEndAlign(block); xco += 30; diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index dd304cd8cf3..79d38d9c252 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -313,6 +313,7 @@ void graph_header_buttons(const bContext *C, ARegion *ar) uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Cameras"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Curves"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display MetaBalls"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Armature/Bone data"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Particles"); uiBlockEndAlign(block); xco += 30; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 04d56eb666e..1bbac8da02f 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -253,6 +253,22 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *C, PointerR return space_object_items; } +static void rna_ActionConstraint_minmax_range(PointerRNA *ptr, float *min, float *max) +{ + bConstraint *con= (bConstraint*)ptr->data; + bActionConstraint *acon = (bActionConstraint *)con->data; + + /* 0, 1, 2 = magic numbers for rotX, rotY, rotZ */ + if (ELEM3(acon->type, 0, 1, 2)) { + *min= -90.f; + *max= 90.f; + } else { + *min= -1000.f; + *max= 1000.f; + } +} + + #else static void rna_def_constrainttarget(BlenderRNA *brna) @@ -781,15 +797,17 @@ static void rna_def_constraint_action(BlenderRNA *brna) prop= RNA_def_property(srna, "maximum", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); - RNA_def_property_range(prop, 0.0, 1000.f); + RNA_def_property_range(prop, -1000.f, 1000.f); RNA_def_property_ui_text(prop, "Maximum", "Maximum value for target channel range."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range"); prop= RNA_def_property(srna, "minimum", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); - RNA_def_property_range(prop, 0.0, 1000.f); + RNA_def_property_range(prop, -1000.f, 1000.f); RNA_def_property_ui_text(prop, "Minimum", "Minimum value for target channel range."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range"); } static void rna_def_constraint_locked_track(BlenderRNA *brna) -- cgit v1.2.3 From 2379af27d10e21c5d471884ee2f78fba62f8534c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 09:17:14 +0000 Subject: tested running the cheat-sheet, found a number of segfaults pressing escape in the outliner was also crashing (somehow it tried to exit the file selector) --- source/blender/editors/space_buttons/buttons_ops.c | 24 ++++++++++++++-------- source/blender/editors/space_file/file_ops.c | 2 +- source/blender/editors/space_image/space_image.c | 2 +- .../editors/transform/transform_conversions.c | 12 +++++------ .../editors/transform/transform_orientations.c | 3 ++- source/blender/editors/uvedit/uvedit_ops.c | 20 ++++++++++++------ .../blender/windowmanager/intern/wm_event_system.c | 4 ++-- 7 files changed, 41 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 5466a06550b..4387da19341 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -738,9 +738,9 @@ void PARTICLE_OT_target_move_down(wmOperatorType *ot) static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) { ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys); - ParticleData *pa = psys->particles; - PTCacheEdit *edit = psys->edit; - PTCacheEditPoint *point = edit ? edit->points : NULL; + ParticleData *pa; + PTCacheEdit *edit; + PTCacheEditPoint *point; PTCacheEditKey *ekey = NULL; HairKey *key; int i, k; @@ -751,8 +751,11 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) if(!psys->part || psys->part->type != PART_HAIR) return; + + edit = psys->edit; + point= edit ? edit->points : NULL; - for(i=0; itotpart; i++,pa++) { + for(i=0, pa=psys->particles; itotpart; i++,pa++) { if(point) { ekey = point->keys; point++; @@ -820,9 +823,9 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) { ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys); - ParticleData *pa = psys->particles; - PTCacheEdit *edit = psys->edit; - PTCacheEditPoint *point = edit ? edit->points : NULL; + ParticleData *pa; + PTCacheEdit *edit; + PTCacheEditPoint *point; PTCacheEditKey *ekey; HairKey *key; BVHTreeFromMesh bvhtree; @@ -836,7 +839,10 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) if(!psys || !psys->part || psys->part->type != PART_HAIR) return; - + + edit= psys->edit; + point= edit ? edit->points : NULL; + if(psmd->dm->deformedOnly) dm= psmd->dm; else @@ -852,7 +858,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6); - for(i=0; itotpart; i++,pa++) { + for(i=0, pa= psys->particles; itotpart; i++,pa++) { key = pa->hair; nearest.index = -1; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 70d8de7d509..7839cf5bf4b 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -532,7 +532,7 @@ int file_operator_poll(bContext *C) int poll = ED_operator_file_active(C); SpaceFile *sfile= CTX_wm_space_file(C); - if (!sfile->op) poll= 0; + if (!sfile || !sfile->op) poll= 0; return poll; } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index f222499ba86..f041cb00ee4 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -623,7 +623,7 @@ ImBuf *ED_space_image_buffer(SpaceImage *sima) { ImBuf *ibuf; - if(sima->image) { + if(sima && sima->image) { #if 0 if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare()) return BIF_render_spare_imbuf(); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e59ec3746e3..64151918a47 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4262,7 +4262,7 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * /* it deselects Bases, so we have to call the clear function always after */ static void set_trans_object_base_flags(bContext *C, TransInfo *t) { - Scene *sce = CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); View3D *v3d = t->view; /* @@ -4279,15 +4279,15 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t) copy_baseflags(t->scene); /* handle pending update events, otherwise they got copied below */ - for (base= sce->base.first; base; base= base->next) { + for (base= scene->base.first; base; base= base->next) { if(base->object->recalc) object_handle_update(t->scene, base->object); } - for (base= sce->base.first; base; base= base->next) { + for (base= scene->base.first; base; base= base->next) { base->flag &= ~BA_WAS_SEL; - if(TESTBASELIB(v3d, base)) { + if(TESTBASELIB_BGMODE(v3d, base)) { Object *ob= base->object; Object *parsel= ob->parent; @@ -4319,7 +4319,7 @@ static void set_trans_object_base_flags(bContext *C, 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= sce->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) @@ -5319,7 +5319,7 @@ void createTransData(bContext *C, TransInfo *t) { View3D *v3d = t->view; RegionView3D *rv3d = CTX_wm_region_view3d(C); - if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) + if(rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) { t->flag |= T_CAMERA; } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 9416425704f..d82be842596 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -353,7 +353,8 @@ void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) { void BIF_selectTransformOrientationValue(bContext *C, int orientation) { View3D *v3d = CTX_wm_view3d(C); - v3d->twmode = orientation; + if(v3d) /* currently using generic poll */ + v3d->twmode = orientation; } EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 611eee00d79..5597c624e23 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -1439,7 +1439,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) else { sync= 0; selectmode= ts->uv_selectmode; - sticky= sima->sticky; + sticky= sima ? sima->sticky : 1; } /* find nearest element */ @@ -2471,13 +2471,18 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) { EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - Image *ima= sima->image; + Image *ima; EditFace *efa; MTFace *tface; int width= 0, height= 0; float w, h; short change = 0; + if(!sima) + return 0; + + ima= sima->image; + ED_space_image_size(sima, &width, &height); w = (float)width; h = (float)height; @@ -2657,6 +2662,7 @@ static int hide_exec(bContext *C, wmOperator *op) EditFace *efa; MTFace *tf; int swap= RNA_boolean_get(op->ptr, "unselected"); + int facemode= sima ? sima->flag & SI_SELACTFACE : 0; if(ts->uv_flag & UV_SYNC_SELECTION) { EM_hide_mesh(em, swap); @@ -2670,7 +2676,7 @@ static int hide_exec(bContext *C, wmOperator *op) for(efa= em->faces.first; efa; efa= efa->next) { if(efa->f & SELECT) { tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(sima->flag & SI_SELACTFACE) { + if(facemode) { /* Pretend face mode */ if(( (efa->v4==NULL && ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || @@ -2715,7 +2721,7 @@ static int hide_exec(bContext *C, wmOperator *op) if(efa->f & SELECT) { tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(sima->flag & SI_SELACTFACE) { + if(facemode) { if( (efa->v4==NULL && ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) { @@ -2799,6 +2805,8 @@ static int reveal_exec(bContext *C, wmOperator *op) EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); EditFace *efa; MTFace *tf; + int facemode= sima ? sima->flag & SI_SELACTFACE : 0; + int stickymode= sima ? (sima->sticky != SI_STICKY_DISABLE) : 1; /* call the mesh function if we are in mesh sync sel */ if(ts->uv_flag & UV_SYNC_SELECTION) { @@ -2809,7 +2817,7 @@ static int reveal_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - if(sima->flag & SI_SELACTFACE) { + if(facemode) { if(em->selectmode == SCE_SELECT_FACE) { for(efa= em->faces.first; efa; efa= efa->next) { if(!(efa->h) && !(efa->f & SELECT)) { @@ -2821,7 +2829,7 @@ static int reveal_exec(bContext *C, wmOperator *op) } else { /* enable adjacent faces to have disconnected UV selections if sticky is disabled */ - if(sima->sticky == SI_STICKY_DISABLE) { + if(!stickymode) { for(efa= em->faces.first; efa; efa= efa->next) { if(!(efa->h) && !(efa->f & SELECT)) { /* All verts must be unselected for the face to be selected in the UV view */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ebb7adc3cd5..6b07e384f66 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1231,7 +1231,7 @@ void wm_event_do_handlers(bContext *C) /* XXX hrmf, this gives reliable previous mouse coord for area change, feels bad? doing it on ghost queue gives errors when mousemoves go over area borders */ - if(doit && win->screen->subwinactive != win->screen->mainwin) { + if(doit && win->screen && win->screen->subwinactive != win->screen->mainwin) { win->eventstate->prevx= event->x; win->eventstate->prevy= event->y; } @@ -1244,7 +1244,7 @@ void wm_event_do_handlers(bContext *C) } /* only add mousemove when queue was read entirely */ - if(win->addmousemove) { + if(win->addmousemove && win->eventstate) { wmEvent event= *(win->eventstate); event.type= MOUSEMOVE; event.prevx= event.x; -- cgit v1.2.3 From 551ddd1002cec4200c6073a8442b931122d5dd47 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 10:54:15 +0000 Subject: Fix #19389: add lamp had no submenu to choose the type. --- release/ui/space_info.py | 4 +- .../blender/editors/interface/interface_regions.c | 2 +- source/blender/editors/object/object_add.c | 48 ++++++++++++++++++++-- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/release/ui/space_info.py b/release/ui/space_info.py index 6e32cf9b071..539a6722cf0 100644 --- a/release/ui/space_info.py +++ b/release/ui/space_info.py @@ -124,7 +124,7 @@ class INFO_MT_add(bpy.types.Menu): layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH') layout.item_menu_enumO("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE') layout.item_menu_enumO("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE') - layout.item_menu_enumO("object.metaball_add", "type", 'META', icon='ICON_OUTLINER_OB_META') + layout.item_menu_enumO("object.metaball_add", "type", 'META', text="Metaball", icon='ICON_OUTLINER_OB_META') layout.itemO("object.text_add", text="Text", icon='ICON_OUTLINER_OB_FONT') layout.itemS() @@ -136,7 +136,7 @@ class INFO_MT_add(bpy.types.Menu): layout.itemS() layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA') - layout.item_enumO("object.add", "type", 'LAMP', icon='ICON_OUTLINER_OB_LAMP') + layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP') class INFO_MT_game(bpy.types.Menu): __space_type__ = 'INFO' diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 065d391e6d6..0f04333c6c5 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2226,7 +2226,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi } block->minbounds= minwidth; - uiTextBoundsBlock(block, 40); + uiTextBoundsBlock(block, 50); } /* if menu slides out of other menu, override direction */ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index ee9af61f516..d576f6e8bf6 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -32,6 +32,7 @@ #include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" +#include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" @@ -165,7 +166,7 @@ static Object *object_add_type(bContext *C, int type) /* for object add operator */ static int object_add_exec(bContext *C, wmOperator *op) { - object_add_type(C, RNA_int_get(op->ptr, "type")); + object_add_type(C, RNA_enum_get(op->ptr, "type")); return OPERATOR_FINISHED; } @@ -467,7 +468,7 @@ static int object_metaball_add_invoke(bContext *C, wmOperator *op, wmEvent *even void OBJECT_OT_metaball_add(wmOperatorType *ot) { /* identifiers */ - ot->name= "Metaball"; + ot->name= "Add Metaball"; ot->description= "Add an metaball object to the scene."; ot->idname= "OBJECT_OT_metaball_add"; @@ -559,6 +560,45 @@ void OBJECT_OT_armature_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int object_lamp_add_exec(bContext *C, wmOperator *op) +{ + Object *ob; + int type= RNA_enum_get(op->ptr, "type"); + + ob= object_add_type(C, OB_LAMP); + if(ob && ob->data) + ((Lamp*)ob->data)->type= type; + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_lamp_add(wmOperatorType *ot) +{ + static EnumPropertyItem lamp_type_items[] = { + {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}}; + + /* identifiers */ + ot->name= "Add Lamp"; + ot->description = "Add a lamp object to the scene."; + ot->idname= "OBJECT_OT_lamp_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= object_lamp_add_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", ""); +} + static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event) { uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0); @@ -567,7 +607,7 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve uiItemMenuEnumO(layout, "Mesh", ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type"); uiItemMenuEnumO(layout, "Curve", ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type"); uiItemMenuEnumO(layout, "Surface", ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type"); - uiItemMenuEnumO(layout, NULL, ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type"); + uiItemMenuEnumO(layout, "Metaball", ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type"); uiItemO(layout, "Text", ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add"); uiItemS(layout); uiItemO(layout, "Armature", ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add"); @@ -575,7 +615,7 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_add", "type", OB_EMPTY); uiItemS(layout); uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_add", "type", OB_CAMERA); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LAMP, "OBJECT_OT_add", "type", OB_LAMP); + uiItemMenuEnumO(layout, "Lamp", ICON_OUTLINER_OB_LAMP, "OBJECT_OT_lamp_add", "type"); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 315b6632051..87c4560916d 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -89,6 +89,7 @@ void OBJECT_OT_surface_add(struct wmOperatorType *ot); void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); +void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_primitive_add(struct wmOperatorType *ot); /* only used as menu */ void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index fdfe6ed501c..a9b4bfe68dd 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -115,6 +115,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_text_add); WM_operatortype_append(OBJECT_OT_surface_add); WM_operatortype_append(OBJECT_OT_armature_add); + WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_primitive_add); WM_operatortype_append(OBJECT_OT_mesh_add); -- cgit v1.2.3 From 61c79adb8b1d4d955e9af6d8866970e584fcb0a1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 10:57:46 +0000 Subject: colorbands could display with no items in the colorband array, letting you set 0 and -1 colorband index. --- .../editors/interface/interface_templates.c | 34 ++++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b15ddcfae17..23ffe46eed4 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1336,7 +1336,7 @@ static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v) /* offset aligns from bottom, standard width 300, height 115 */ static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb) { - CBData *cbd; + uiBut *bt; if(coba==NULL) return; @@ -1347,7 +1347,7 @@ static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, bt= uiDefBut(block, BUT, 0, "Delete", 60+xoffs,100+yoffs,50,20, 0, 0, 0, 0, 0, "Delete the active position"); uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba); - uiDefButS(block, NUM, 0, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Choose active color stop"); + uiDefButS(block, NUM, 0, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(MAX2(0, coba->tot-1)), 0, 0, "Choose active color stop"); bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", 210+xoffs, 100+yoffs, 90, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops"); @@ -1357,36 +1357,38 @@ static void colorband_buttons_large(uiBlock *block, ColorBand *coba, int xoffs, bt= uiDefBut(block, BUT_COLORBAND, 0, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); - cbd= coba->data + coba->cur; + if(coba->tot) { + CBData *cbd= coba->data + coba->cur; - bt= uiDefButF(block, NUM, 0, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop"); - uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba); - bt= uiDefButF(block, COL, 0, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); - bt= uiDefButF(block, NUMSLI, 0, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop"); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + bt= uiDefButF(block, NUM, 0, "Pos:", 0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop"); + uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba); + bt= uiDefButF(block, COL, 0, "", 110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + bt= uiDefButF(block, NUMSLI, 0, "A ", 200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + } } static void colorband_buttons_small(uiBlock *block, ColorBand *coba, rctf *butr, RNAUpdateCb *cb) { - CBData *cbd; uiBut *bt; float unit= (butr->xmax-butr->xmin)/14.0f; float xs= butr->xmin; - cbd= coba->data + coba->cur; - bt= uiDefBut(block, BUT, 0, "Add", xs,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband"); uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba); bt= uiDefBut(block, BUT, 0, "Delete", xs+2.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Delete the active position"); uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba); - bt= uiDefButF(block, COL, 0, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); - bt= uiDefButF(block, NUMSLI, 0, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop"); - uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + if(coba->tot) { + CBData *cbd= coba->data + coba->cur; + bt= uiDefButF(block, COL, 0, "", xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + bt= uiDefButF(block, NUMSLI, 0, "A:", xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop"); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + } bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4", xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops"); -- cgit v1.2.3 From d2639e732b345ce32ec26c42d0e3ca6df4eb761a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 21 Sep 2009 12:09:00 +0000 Subject: 2.5 - Partial Bugfixes for Parenting Objects to Curves (Ctrl-P) * Path Constraint option (i.e. this creates a follow-path constraint but doesn't actually parent the object to the curve) works now. Fixed a crash here too. * Follow Path option (i.e. parent the object to the curve, and follow it), is not working correctly yet. Some matrix seems to get set wrongly. --- source/blender/blenkernel/intern/constraint.c | 5 ++++- source/blender/editors/object/object_relations.c | 14 ++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e49bda0fdd2..a3d59720645 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1188,7 +1188,10 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr if (cu->path && cu->path->data) { if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ - curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset; + if (cob->scene) + curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset; + else + curvetime= ctime - data->offset; /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, * but this will only work if it actually is animated... diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 65061e8dfb9..17590cbaad3 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -566,8 +566,9 @@ static int parent_set_exec(bContext *C, wmOperator *op) } else cu->flag |= CU_FOLLOW; - /* fall back on regular parenting now */ - partype= PAR_OBJECT; + /* fall back on regular parenting now (for follow only) */ + if(partype == PAR_FOLLOW) + partype= PAR_OBJECT; } } else if(partype==PAR_BONE) { @@ -593,7 +594,9 @@ static int parent_set_exec(bContext *C, wmOperator *op) /* apply transformation of previous parenting */ ED_object_apply_obmat(ob); - ob->parent= par; + /* set the parent (except for follow-path constraint option) */ + if(partype != PAR_PATH_CONST) + ob->parent= par; /* handle types */ if (pchan) @@ -602,7 +605,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) ob->parsubstr[0]= 0; /* constraint */ - if(partype==PAR_PATH_CONST) { + if(partype == PAR_PATH_CONST) { bConstraint *con; bFollowPathConstraint *data; float cmat[4][4], vec[3]; @@ -620,6 +623,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) ob->loc[0] = vec[0]; ob->loc[1] = vec[1]; + ob->loc[2] = vec[2]; } else if(pararm && ob->type==OB_MESH && par->type == OB_ARMATURE) { if(partype == PAR_ARMATURE_NAME) @@ -645,6 +649,8 @@ static int parent_set_exec(bContext *C, wmOperator *op) ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; + if(partype == PAR_PATH_CONST) + ; /* don't do anything here, since this is not technically "parenting" */ if( ELEM(partype, PAR_CURVE, PAR_LATTICE) || pararm ) ob->partype= PARSKEL; /* note, dna define, not operator property */ else if (partype == PAR_BONE) -- cgit v1.2.3 From e9ffd121337d0d5d50bc8771a36117dc3696b315 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 12:23:56 +0000 Subject: bugfix [#19392] Typing help() in the console window freezes Blender for now set the sys.stdin to None, this gives an error on input() or help() but better then locking up blender. Would be nice to support for the blender console to be used as a stdin but this isnt so simple. also quiet some warnings. --- source/blender/editors/space_file/file_ops.c | 1 - source/blender/editors/space_file/space_file.c | 2 +- source/blender/editors/transform/transform_input.c | 2 +- source/blender/python/intern/bpy_interface.c | 5 +++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 7839cf5bf4b..c717623696a 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -72,7 +72,6 @@ static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short { float fx,fy; int active_file = -1; - int numfiles = filelist_numfiles(sfile->files); View2D* v2d = &ar->v2d; UI_view2d_region_to_view(v2d, x, y, &fx, &fy); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 56dbdcbc645..ca2c145c52b 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -155,7 +155,7 @@ static void file_free(SpaceLink *sl) /* spacetype; init callback, area size changes, screen set, etc */ static void file_init(struct wmWindowManager *wm, ScrArea *sa) { - SpaceFile *sfile= (SpaceFile*)sa->spacedata.first; + //SpaceFile *sfile= (SpaceFile*)sa->spacedata.first; printf("file_init\n"); } diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index e1e4569623b..83d4a314057 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -34,7 +34,7 @@ #include "transform.h" - +#include "MEM_guardedalloc.h" /* ************************** INPUT FROM MOUSE *************************** */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index fd8cfc47f55..3e28bc7968f 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -292,6 +292,11 @@ void BPY_start_python( int argc, char **argv ) PyObject *d = PyEval_GetBuiltins( ); PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item); PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item); + + /* a bit nasty but this prevents help() and input() from locking blender + * Ideally we could have some way for the console to replace sys.stdin but + * python would lock blender while waiting for a return value, not easy :| */ + PySys_SetObject("stdin", Py_None); } pyrna_alloc_types(); -- cgit v1.2.3 From cdc5fd64e5a50079ba79989f45e06dc38eb445b1 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 21 Sep 2009 12:29:53 +0000 Subject: 2.5 - Keyframes can now be marked as 'extremes' in addition to 'breakdowns' * Extremes are shown as red/pink diamonds * I've changed the order of extremes and breakdowns in the code to make for nicer sizing/ordering. This might break a couple of files out there, but it shouldn't be too many. TODO: Still on my todo is to make these tags more useful (i.e. less likely to be overwritten by keyframing) --- source/blender/editors/animation/keyframes_draw.c | 7 +++++++ source/blender/editors/animation/keyframes_edit.c | 10 ++++++++++ source/blender/editors/space_action/action_header.c | 1 + source/blender/makesdna/DNA_curve_types.h | 1 + source/blender/makesrna/intern/rna_curve.c | 1 + 5 files changed, 20 insertions(+) diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index dcb37f4d2c4..e8b25f70b06 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -419,6 +419,13 @@ void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel } break; + case BEZT_KEYTYPE_EXTREME: /* redish frames for now */ + { + if (sel) glColor3f(95.0f, 0.5f, 0.5f); + else glColor3f(0.91f, 0.70f, 0.80f); + } + break; + case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */ default: { diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index ac04dc7d1a8..9666cb115b1 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -685,6 +685,13 @@ static short set_keytype_breakdown(BeztEditData *bed, BezTriple *bezt) return 0; } +static short set_keytype_extreme(BeztEditData *bed, BezTriple *bezt) +{ + if (bezt->f2 & SELECT) + BEZKEYTYPE(bezt)= BEZT_KEYTYPE_EXTREME; + return 0; +} + /* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */ BeztEditFunc ANIM_editkeyframes_keytype(short code) { @@ -692,6 +699,9 @@ BeztEditFunc ANIM_editkeyframes_keytype(short code) case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */ return set_keytype_breakdown; + case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */ + return set_keytype_extreme; + case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */ default: return set_keytype_keyframe; diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index dd02302af9c..f602345baea 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -189,6 +189,7 @@ static void act_edit_keytypesmenu(bContext *C, uiLayout *layout, void *arg_unuse uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_KEYFRAME); uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_BREAKDOWN); + uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_EXTREME); } static void act_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused) diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 109a9528de2..6cfeb646cf2 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -310,6 +310,7 @@ typedef enum 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 */ } eBezTriple_KeyframeType; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 4a5af56d64a..3b6bd2255f2 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -54,6 +54,7 @@ EnumPropertyItem beztriple_interpolation_mode_items[] = { EnumPropertyItem beztriple_keyframe_type_items[] = { {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""}, {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""}, + {BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME -- cgit v1.2.3 From 3c5630a63d01771cea247144fd0d31cece46e681 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 13:23:47 +0000 Subject: Fix #19418: file browse button for strip filename did not work, sequence RNA now also splits up directory and filename automatic. --- .../blender/editors/interface/interface_layout.c | 2 +- source/blender/makesrna/intern/rna_sequence.c | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b957ff83650..afbbfb61cba 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -533,7 +533,7 @@ void uiFileBrowseContextProperty(const bContext *C, PointerRNA *ptr, PropertyRNA prevbut= but->prev; /* find the button before the active one */ - if((but->flag & UI_BUT_LAST_ACTIVE) && prevbut && prevbut->rnapoin.id.data) { + if((but->flag & UI_BUT_LAST_ACTIVE) && prevbut && prevbut->rnapoin.data) { if(RNA_property_type(prevbut->rnaprop) == PROP_STRING) { *ptr= prevbut->rnapoin; *prop= prevbut->rnaprop; diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index 4e12aab853e..b1ac02ae17f 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -239,6 +239,35 @@ static PointerRNA rna_SequenceEdtior_meta_stack_get(CollectionPropertyIterator * return rna_pointer_inherit_refine(&iter->parent, &RNA_Sequence, ms->parseq); } +static void rna_MovieSequence_filename_set(PointerRNA *ptr, const char *value) +{ + Sequence *seq= (Sequence*)(ptr->data); + char dir[FILE_MAX], name[FILE_MAX]; + + BLI_split_dirfile_basic(value, dir, name); + BLI_strncpy(seq->strip->dir, dir, sizeof(seq->strip->dir)); + BLI_strncpy(seq->strip->stripdata->name, name, sizeof(seq->strip->stripdata->name)); +} + +static void rna_SoundSequence_filename_set(PointerRNA *ptr, const char *value) +{ + Sequence *seq= (Sequence*)(ptr->data); + char dir[FILE_MAX], name[FILE_MAX]; + + BLI_split_dirfile_basic(value, dir, name); + BLI_strncpy(seq->strip->dir, dir, sizeof(seq->strip->dir)); + BLI_strncpy(seq->strip->stripdata->name, name, sizeof(seq->strip->stripdata->name)); +} + +static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value) +{ + StripElem *elem= (StripElem*)(ptr->data); + char name[FILE_MAX]; + + BLI_split_dirfile_basic(value, NULL, name); + BLI_strncpy(elem->name, name, sizeof(elem->name)); +} + #else static void rna_def_strip_element(BlenderRNA *brna) @@ -253,6 +282,7 @@ static void rna_def_strip_element(BlenderRNA *brna) prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Filename", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SequenceElement_filename_set"); } static void rna_def_strip_crop(BlenderRNA *brna) @@ -736,6 +766,7 @@ static void rna_def_movie(BlenderRNA *brna) prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "strip->stripdata->name"); RNA_def_property_ui_text(prop, "Filename", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MovieSequence_filename_set"); prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "strip->dir"); @@ -762,6 +793,7 @@ static void rna_def_sound(BlenderRNA *brna) prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "strip->stripdata->name"); RNA_def_property_ui_text(prop, "Filename", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SoundSequence_filename_set"); prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "strip->dir"); -- cgit v1.2.3 From e2ebb5d9e413b7dad0d63710ddeacb8e4d03718b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 13:43:11 +0000 Subject: autocomplete poll function wasn't working, added autocomplete in the console header operator docstrings with newlines and tabs show up as junk in tooltips so just use a single line. --- release/io/export_ply.py | 4 +--- release/ui/space_console.py | 13 ++++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/release/io/export_ply.py b/release/io/export_ply.py index b8fbe56f01c..98ce210aa1f 100644 --- a/release/io/export_ply.py +++ b/release/io/export_ply.py @@ -232,9 +232,7 @@ def write(filename, scene, ob, \ """ class EXPORT_OT_ply(bpy.types.Operator): - ''' - Operator documentatuon text, will be used for the operator tooltip and python docs. - ''' + '''Export a single object as a stanford PLY with normals, colours and texture coordinates.''' __idname__ = "export.ply" __label__ = "Export PLY" diff --git a/release/ui/space_console.py b/release/ui/space_console.py index 136082a285a..980c11b706a 100644 --- a/release/ui/space_console.py +++ b/release/ui/space_console.py @@ -37,6 +37,9 @@ class CONSOLE_HT_header(bpy.types.Header): row = layout.row() row.enabled = sc.show_report_operator row.itemO("console.report_replay") + else: + row = layout.row(align=True) + row.itemO("console.autocomplete", text="Autocomplete") class CONSOLE_MT_console(bpy.types.Menu): __space_type__ = 'CONSOLE' @@ -107,9 +110,7 @@ def get_console(console_id): return namespace, console, stdout, stderr class CONSOLE_OT_exec(bpy.types.Operator): - ''' - Execute the current console line as a python expression. - ''' + '''Execute the current console line as a python expression.''' __idname__ = "console.execute" __label__ = "Console Execute" __register__ = False @@ -384,15 +385,13 @@ def autocomp(bcon): class CONSOLE_OT_autocomplete(bpy.types.Operator): - ''' - Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one. - ''' + '''Evaluate the namespace up until the cursor and give a list of options or complete the name if there is only one.''' __idname__ = "console.autocomplete" __label__ = "Console Autocomplete" __register__ = False def poll(self, context): - return context.space_data.type == 'PYTHON' + return context.space_data.console_type == 'PYTHON' def execute(self, context): -- cgit v1.2.3 From 6fc4e2d37fae8696eb39ee4d5456f5184f374fe3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 14:30:59 +0000 Subject: Fix #19425: crash with long filename and rendering full sample. --- source/blender/render/intern/source/pipeline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 8ef52991ca2..68b6f9e524c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -406,7 +406,7 @@ static int passtype_from_name(char *str) static void render_unique_exr_name(Render *re, char *str, int sample) { - char di[FILE_MAX], name[FILE_MAXFILE], fi[FILE_MAXFILE]; + char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE]; BLI_strncpy(di, G.sce, FILE_MAX); BLI_splitdirstring(di, fi); -- cgit v1.2.3 From b037d280d31be3aecb05d83a2e692c096b3b8315 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 21 Sep 2009 14:45:28 +0000 Subject: * Removed an unused context callback. --- source/blender/editors/space_buttons/buttons_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index f51cb5d6f8c..9333ba9209c 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -554,7 +554,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r "world", "object", "mesh", "armature", "lattice", "curve", "meta_ball", "lamp", "camera", "material", "material_slot", "texture", "texture_slot", "bone", "edit_bone", "particle_system", - "cloth", "soft_body", "fluid", "smoke", "smoke_hr", "collision", "brush", NULL}; + "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL}; CTX_data_dir_set(result, dir); return 1; -- cgit v1.2.3 From 4453dc330f94ab0865852145cfab444f05cbd463 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 21 Sep 2009 15:47:41 +0000 Subject: remove OS checks to use BLENDERPATH, apple or win32 should be easy to add now. --- source/creator/creator.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 523273de9bf..579825b805a 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -122,11 +122,7 @@ char btempdir[FILE_MAXDIR+FILE_MAXFILE]; #define BLENDERPATH "" #endif -#if !(defined(__APPLE__) && defined(WIN32)) char blender_path[FILE_MAXDIR+FILE_MAXFILE] = BLENDERPATH; -#else -char blender_path[FILE_MAXDIR+FILE_MAXFILE] = ""; -#endif /* Initialise callbacks for the modules that need them */ static void setCallbacks(void); @@ -233,12 +229,10 @@ static void print_help(void) printf (" \t\t passed unchanged. Access via Python's sys.argv\n"); printf ("\nEnvironment Variables:\n"); printf (" $HOME\t\t\tStore files such as .blender/ .B.blend .Bfs .Blog here.\n"); -#if !(defined(__APPLE__) && defined(WIN32)) printf (" $BLENDERPATH\tSystem directory to use for data files and scripts.\n"); printf (" \tFor this build of blender the default BLENDERPATH is...\n"); printf (" \t\"%s\"\n", blender_path); printf (" \tseting the $BLENDERPATH will override this\n"); -#endif #ifdef WIN32 printf (" $TEMP\t\tStore temporary files here.\n"); #else -- cgit v1.2.3 From 1e63545a3b6331b6c1d05a15c5dc48f4aa148f19 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 15:51:29 +0000 Subject: Second attempt at fixing #19335: holding down backspace in the text editor creates squares on some systems. Based on info from Martin, it appears the keymodifier is being set when it shouldn't. I think this is happening become some systems may be generating KM_PRESS events without a matching KM_RELEASE? Also ignore ascii values 1-32 now instead of 14-32, not sure why they were included now in 2.5 because they were not in 2.4, but I don't see a reason to do it. This fixes squares when pressing e.g. ctrl+b or ctrl+n. --- source/blender/windowmanager/intern/wm_event_system.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 6b07e384f66..4acfe1e524a 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1600,7 +1600,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) event.val= (type==GHOST_kEventKeyDown)?KM_PRESS:KM_RELEASE; /* exclude arrow keys, esc, etc from text input */ - if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>14)) + if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>0)) event.ascii= '\0'; /* modifiers */ @@ -1630,6 +1630,13 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) else if(event.val==KM_RELEASE && event.keymodifier==event.type) event.keymodifier= evt->keymodifier= 0; } + + /* this case happens on some systems that on holding a key pressed, + generate press events without release, we still want to keep the + modifier in win->eventstate, but for the press event of the same + key we don't want the key modifier */ + if(event.keymodifier == event.type) + event.keymodifier= 0; /* if test_break set, it catches this. XXX Keep global for now? */ if(event.type==ESCKEY) -- cgit v1.2.3 From 34a9f423f8ab1debe78ae4d883bf6c4995d9e0ee Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 21 Sep 2009 16:01:31 +0000 Subject: netrender: more load balancing rules --- release/io/netrender/balancing.py | 23 +++++++++++++++++++++-- release/io/netrender/master.py | 13 +++++++++++++ release/io/netrender/model.py | 5 ++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py index 89e1e3f7b06..62b6dcee519 100644 --- a/release/io/netrender/balancing.py +++ b/release/io/netrender/balancing.py @@ -64,12 +64,31 @@ class Balancer: class RatingCredit(RatingRule): def rate(self, job): - return -job.credits # more credit is better (sort at first in list) + return -job.credits * job.priority # more credit is better (sort at first in list) class NewJobPriority(PriorityRule): + def __init__(self, limit = 1): + self.limit = limit + + def test(self, job): + return job.countFrames(status = DISPATCHED) < self.limit + +class MinimumTimeBetweenDispatchPriority(PriorityRule): + def __init__(self, limit = 10): + self.limit = limit + def test(self, job): - return job.countFrames(status = DISPATCHED) == 0 + return (time.time() - job.last_dispatched) / 60 > self.limit class ExcludeQueuedEmptyJob(ExclusionRule): def test(self, job): return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0 + +class ExcludeSlavesLimit(ExclusionRule): + def __init__(self, count_jobs, count_slaves, limit = 0.75): + self.count_jobs = count_jobs + self.count_slaves = count_slaves + self.limit = limit + + def test(self, job): + return not ( self.count_jobs() == 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) \ No newline at end of file diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 58c6c1b2d00..1bff5f6340b 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -575,7 +575,9 @@ class RenderMasterServer(http.server.HTTPServer): self.balancer = netrender.balancing.Balancer() self.balancer.addRule(netrender.balancing.RatingCredit()) self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) + self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves)) self.balancer.addPriority(netrender.balancing.NewJobPriority()) + self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority()) if not os.path.exists(self.path): os.mkdir(self.path) @@ -607,7 +609,18 @@ class RenderMasterServer(http.server.HTTPServer): def update(self): self.balancer.balance(self.jobs) + + def countJobs(self, status = JOB_QUEUED): + total = 0 + for j in self.jobs: + if j.status == status: + total += 1 + return total + + def countSlaves(self): + return len(self.slaves) + def removeJob(self, id): job = self.jobs_map.pop(id) diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 9a6645e79cf..e8046d7ac8c 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -97,15 +97,14 @@ class RenderJob: def countFrames(self, status=QUEUED): total = 0 - for j in self.frames: - if j.status == status: + for f in self.frames: + if f.status == status: total += 1 return total def countSlaves(self): return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED))) - def framesStatus(self): results = { -- cgit v1.2.3 From 8141725342ab12953f5299d1f00300a5292a1682 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 16:08:38 +0000 Subject: Fix #19382: crash on uv edit stitch, tweaking limit property in tool area. --- source/blender/editors/uvedit/uvedit_ops.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 5597c624e23..9216cfb5cdc 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -180,7 +180,13 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist { int width, height; - ED_space_image_size(sima, &width, &height); + if(sima) { + ED_space_image_size(sima, &width, &height); + } + else { + width= 256; + height= 256; + } dist[0]= pixeldist/width; dist[1]= pixeldist/height; @@ -1097,11 +1103,11 @@ static int stitch_exec(bContext *C, wmOperator *op) if(RNA_boolean_get(op->ptr, "use_limit")) { UvVertMap *vmap; UvMapVert *vlist, *iterv; - float newuv[2], limit[2], pixels; + float newuv[2], limit[2]; int a, vtot; - pixels= RNA_float_get(op->ptr, "limit"); - uvedit_pixel_to_float(sima, limit, pixels); + limit[0]= RNA_float_get(op->ptr, "limit"); + limit[1]= limit[0]; EM_init_index_arrays(em, 0, 0, 1); vmap= EM_make_uv_vert_map(em, 1, 0, limit); @@ -1255,7 +1261,7 @@ void UV_OT_stitch(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "use_limit", 1, "Use Limit", "Stitch UVs within a specified limit distance."); - RNA_def_float(ot->srna, "limit", 20.0, 0.0f, FLT_MAX, "Limit", "Limit distance in image pixels.", -FLT_MAX, FLT_MAX); + RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit", "Limit distance in normalized coordinates.", -FLT_MAX, FLT_MAX); } /* ******************** (de)select all operator **************** */ @@ -1439,7 +1445,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) else { sync= 0; selectmode= ts->uv_selectmode; - sticky= sima ? sima->sticky : 1; + sticky= (sima)? sima->sticky: 1; } /* find nearest element */ -- cgit v1.2.3 From 04ec0ea1908f8b15f167ffebd789e678fa6803c6 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 21 Sep 2009 16:21:54 +0000 Subject: 2.5 Nodes: * Wrapped Color Key and Blur Node. * Nodes using RNA properties can be animated. You can now choose if the Nodes Window should be updated while animation playback too. (Timeline>Playback Menu) --- release/ui/space_time.py | 1 + source/blender/editors/screen/screen_ops.c | 4 ++ source/blender/editors/space_node/drawnode.c | 87 ++++++++-------------------- source/blender/makesdna/DNA_space_types.h | 1 + source/blender/makesrna/intern/rna_space.c | 5 ++ 5 files changed, 34 insertions(+), 64 deletions(-) diff --git a/release/ui/space_time.py b/release/ui/space_time.py index b51b1d8af79..696dcf18623 100644 --- a/release/ui/space_time.py +++ b/release/ui/space_time.py @@ -119,6 +119,7 @@ class TIME_MT_playback(bpy.types.Menu): layout.itemR(st, "play_buttons") layout.itemR(st, "play_image") layout.itemR(st, "play_sequencer") + layout.itemR(st, "play_nodes") layout.itemS() diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index f4af0cd6883..5cd992eabe9 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2176,6 +2176,10 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) if(redraws & (TIME_SEQ|TIME_ALL_ANIM_WIN)) return 1; break; + case SPACE_NODE: + if(redraws & (TIME_NODES)) + return 1; + break; case SPACE_IMAGE: if(redraws & TIME_ALL_IMAGE_WIN) return 1; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 9b73bdbb255..f42bf97bf1a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1107,58 +1107,28 @@ static void node_blur_update_sizey_cb(bContext *C, void *node, void *poin2) } static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeBlurData *nbd= node->storage; - uiBut *bt; - short dy= butr->ymin+58; - short dx= (butr->xmax-butr->xmin)/2; - char str[256]; + uiLayout *row, *col; - uiBlockBeginAlign(block); - sprintf(str, "Filter Type%%t|Flat %%x%d|Tent %%x%d|Quad %%x%d|Cubic %%x%d|Gauss %%x%d|Fast Gauss%%x%d|CatRom %%x%d|Mitch %%x%d", R_FILTER_BOX, R_FILTER_TENT, R_FILTER_QUAD, R_FILTER_CUBIC, R_FILTER_GAUSS, R_FILTER_FAST_GAUSS, R_FILTER_CATROM, R_FILTER_MITCH); - uiDefButS(block, MENU, B_NODE_EXEC,str, - butr->xmin, dy, dx*2, 19, - &nbd->filtertype, 0, 0, 0, 0, "Set sampling filter for blur"); - dy-=19; - if (nbd->filtertype != R_FILTER_FAST_GAUSS) { - uiDefButC(block, TOG, B_NODE_EXEC, "Bokeh", - butr->xmin, dy, dx, 19, - &nbd->bokeh, 0, 0, 0, 0, "Uses circular filter, warning it's slow!"); - uiDefButC(block, TOG, B_NODE_EXEC, "Gamma", - butr->xmin+dx, dy, dx, 19, - &nbd->gamma, 0, 0, 0, 0, "Applies filter on gamma corrected values"); - } else { - uiBlockEndAlign(block); - uiBlockBeginAlign(block); + col= uiLayoutColumn(layout, 0); + + uiItemR(col, "", 0, ptr, "filter_type", 0); + /* Only for "Fast Gaussian" */ + if (RNA_enum_get(ptr, "filter_type")!= 7) { + uiItemR(col, NULL, 0, ptr, "bokeh", 0); + uiItemR(col, NULL, 0, ptr, "gamma", 0); } - dy-=19; - bt= uiDefButS(block, TOG, B_NOP, "Relative", - butr->xmin, dy, dx*2, 19, - &nbd->relative, 0, 0, 0, 0, "Use relative (percent) values to define blur radius"); - uiButSetFunc(bt, node_blur_relative_cb, node, NULL); - - dy-=19; - if(nbd->relative) { - bt= uiDefButF(block, NUM, B_NODE_EXEC, "X:", - butr->xmin, dy, dx, 19, - &nbd->percentx, 0.0f, 1.0f, 0, 0, ""); - uiButSetFunc(bt, node_blur_update_sizex_cb, node, NULL); - bt= uiDefButF(block, NUM, B_NODE_EXEC, "Y:", - butr->xmin+dx, dy, dx, 19, - &nbd->percenty, 0.0f, 1.0f, 0, 0, ""); - uiButSetFunc(bt, node_blur_update_sizey_cb, node, NULL); + + uiItemR(col, NULL, 0, ptr, "relative", 0); + row= uiLayoutRow(col, 1); + if (RNA_boolean_get(ptr, "relative")== 1) { + uiItemR(row, "X", 0, ptr, "factor_x", 0); + uiItemR(row, "Y", 0, ptr, "factor_y", 0); } + else { - uiDefButS(block, NUM, B_NODE_EXEC, "X:", - butr->xmin, dy, dx, 19, - &nbd->sizex, 0, 256, 0, 0, ""); - uiDefButS(block, NUM, B_NODE_EXEC, "Y:", - butr->xmin+dx, dy, dx, 19, - &nbd->sizey, 0, 256, 0, 0, ""); + uiItemR(row, "X", 0, ptr, "sizex", 0); + uiItemR(row, "Y", 0, ptr, "sizey", 0); } - uiBlockEndAlign(block); } static void node_composit_buts_dblur(uiLayout *layout, PointerRNA *ptr) @@ -1455,23 +1425,12 @@ static void node_composit_buts_chroma_matte(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_color_matte(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - NodeChroma *c= node->storage; - uiBlockBeginAlign(block); - - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "H: ", - butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, - &c->t1, 0.0f, 0.25f, 100, 0, "Hue tolerance for colors to be considered a keying color"); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "S: ", - butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 1.0f, 100, 0, "Saturation Tolerance for the color"); - uiDefButF(block, NUMSLI, B_NODE_EXEC+node->nr, "V: ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t3, 0.0f, 1.0f, 100, 0, "Value Tolerance for the color"); - - uiBlockEndAlign(block); + uiLayout *col; + + col= uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "h", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "s", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "v", UI_ITEM_R_SLIDER); } static void node_composit_buts_channel_matte(uiLayout *layout, PointerRNA *ptr) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 1a368877243..2cd47e340bd 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -834,6 +834,7 @@ enum { #define TIME_SEQ 32 #define TIME_ALL_IMAGE_WIN 64 #define TIME_CONTINUE_PHYSICS 128 +#define TIME_NODES 256 /* sseq->mainb */ #define SEQ_DRAW_SEQUENCE 0 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 8e783354653..9cf413c0f78 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1239,6 +1239,11 @@ static void rna_def_space_time(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sequencer Windows", ""); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); + prop= RNA_def_property(srna, "play_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "redraws", TIME_NODES); + RNA_def_property_ui_text(prop, "Node Windows", ""); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_SpaceTime_redraw_update"); + /* Other options */ prop= RNA_def_property(srna, "continue_physics", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From 6117d9c6e27970cef86c4532dc77b18101071beb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 16:39:07 +0000 Subject: Fix #19361: BGE keyboard sensor allowed to set mouse events too, should only be keyboard events. --- source/blender/editors/include/UI_interface.h | 2 +- source/blender/editors/interface/interface.c | 3 ++- .../blender/editors/interface/interface_handlers.c | 1 + source/blender/editors/space_logic/logic_window.c | 23 +++++++++++++++++++--- .../blender/windowmanager/intern/wm_event_system.c | 4 ++-- source/blender/windowmanager/wm_event_types.h | 7 +++++-- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 848432b5f42..dc4744c9832 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -431,7 +431,7 @@ uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, char * uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, short x1, short y1, short x2, short y2, char *tip); uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip); -void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip); +uiBut *uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip); uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *keypoin, short *modkeypoin, char *tip); uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, char *tip); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index fbc3c859f20..f79f2f8c378 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3098,10 +3098,11 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int return but; } -void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip) +uiBut *uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, short x2, short y2, short *spoin, char *tip) { uiBut *but= ui_def_but(block, KEYEVT|SHO, retval, str, x1, y1, x2, y2, spoin, 0.0, 0.0, 0.0, 0.0, tip); ui_check_but(but); + return but; } /* short pointers hardcoded */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index e8d813d8ff9..01a8f983dc6 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -855,6 +855,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut ui_apply_but_CHARTAB(C, but, data); break; #endif + case KEYEVT: case HOTKEYEVT: ui_apply_but_BUT(C, but, data); break; diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index cd02f2c6304..b99f7b94170 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1067,6 +1067,19 @@ static void test_scenepoin_but(struct bContext *C, char *name, ID **idpp) *idpp= NULL; } + +static void test_keyboard_event(struct bContext *C, void *arg_ks, void *arg_unused) +{ + bKeyboardSensor *ks= (bKeyboardSensor*)arg_ks; + + if(!ISKEYBOARD(ks->key)) + ks->key= 0; + if(!ISKEYBOARD(ks->qual)) + ks->qual= 0; + if(!ISKEYBOARD(ks->qual2)) + ks->qual2= 0; +} + /** * Draws a toggle for pulse mode, a frequency field and a toggle to invert * the value of this sensor. Operates on the shared data block of sensors. @@ -1131,6 +1144,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short bJoystickSensor *joy = NULL; bActuatorSensor *as = NULL; bDelaySensor *ds = NULL; + uiBut *but; short ysize; char *str; @@ -1279,12 +1293,15 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short if ((ks->type&1)==0) { /* is All Keys option off? */ /* line 2: hotkey and allkeys toggle */ - uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code"); + but= uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code"); + uiButSetFunc(but, test_keyboard_event, ks, NULL); /* line 3: two key modifyers (qual1, qual2) */ uiDefBut(block, LABEL, 0, "Hold", xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, ""); - uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code"); - uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code"); + but= uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code"); + uiButSetFunc(but, test_keyboard_event, ks, NULL); + but= uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code"); + uiButSetFunc(but, test_keyboard_event, ks, NULL); } /* line 4: toggle property for string logging mode */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 4acfe1e524a..503eb5a1b9a 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -718,7 +718,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) /* the matching rules */ if(kmitype==KM_TEXTINPUT) - if(ISKEYBOARD(winevent->type) && winevent->ascii) return 1; + if(ISTEXTINPUT(winevent->type) && winevent->ascii) return 1; if(kmitype!=KM_ANY) if(winevent->type!=kmitype) return 0; @@ -741,7 +741,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) /* key modifiers always check when event has it */ /* otherwise regular keypresses with keymodifier still work */ if(winevent->keymodifier) - if(ISKEYBOARD(winevent->type)) + if(ISTEXTINPUT(winevent->type)) if(winevent->keymodifier!=kmi->keymodifier) return 0; return 1; diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 898c6358f3a..cc6041ce529 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -194,10 +194,13 @@ /* for event checks */ /* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */ -#define ISKEYBOARD(event) (event >=' ' && event <=255) +#define ISTEXTINPUT(event) (event >=' ' && event <=255) + + /* test wether the event is a key on the keyboard */ +#define ISKEYBOARD(event) (event >=' ' && event <=320) /* test whether event type is acceptable as hotkey, excluding modifiers */ -#define ISHOTKEY(event) (event >=' ' && event <=320 && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY)) +#define ISHOTKEY(event) (ISKEYBOARD(event) && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY)) /* **************** BLENDER GESTURE EVENTS ********************* */ -- cgit v1.2.3 From b49e4e7bcf6279e8794afcf2d69eb9834b1dcb9d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 16:51:04 +0000 Subject: Fix #19378: border render coordinates were not RNA wrapped. --- source/blender/makesrna/intern/rna_scene.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ff8102a3111..5def517f8b2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1665,6 +1665,30 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER); RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "border_min_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "border.xmin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum X", "Sets minimum X value to for the render border."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "border_min_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "border.ymin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum Y", "Sets minimum Y value for the render border"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "border_max_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "border.xmax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum X", "Sets maximum X value for the render border"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "border_max_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "border.ymax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum Y", "Sets maximum Y value for the render border"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "crop_to_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_CROP); -- cgit v1.2.3 From fe27bb6dd4d214519816e00bb8daefcc9bdb8637 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 17:00:22 +0000 Subject: Fix #19384: missing redraw when changing transform orientation. --- source/blender/editors/space_view3d/view3d_header.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a633969d557..a18e7da8f20 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1801,8 +1801,10 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event) ED_area_tag_redraw(sa); break; case B_NDOF: + ED_area_tag_redraw(sa); break; case B_MAN_MODE: + ED_area_tag_redraw(sa); break; case B_VIEW_BUTSEDIT: break; -- cgit v1.2.3 From c8a977db78d860e0134004083ee5e49d38dbc239 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 17:32:25 +0000 Subject: Fix #19426: loop select with occlude background geometry did not work after subdivide operator, needed a check for valid backbuf. --- source/blender/editors/mesh/editmesh_mods.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 09ea9088a16..3135863d571 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -2033,6 +2033,9 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring vc.mval[0]= mval[0]; vc.mval[1]= mval[1]; em= vc.em; + + /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */ + view3d_validate_backbuf(&vc); eed= findnearestedge(&vc, &dist); if(eed) { @@ -2110,6 +2113,9 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2]) vc.mval[1]= mval[1]; em= vc.em; + /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */ + view3d_validate_backbuf(&vc); + eed= findnearestedge(&vc, &dist); if(eed) { Mesh *me= vc.obedit->data; -- cgit v1.2.3 From a15ba4f35d9e6e7054164c40be03c438c1b42ca2 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 21 Sep 2009 19:26:27 +0000 Subject: * Wrong Property Range for Blur Size_Y. --- source/blender/makesrna/intern/rna_nodetree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 239fd894e4f..d80ebe2da05 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -540,7 +540,7 @@ static void def_cmp_blur(StructRNA *srna) prop = RNA_def_property(srna, "sizey", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sizey"); - RNA_def_property_range(prop, 1, 256); + RNA_def_property_range(prop, 0, 256); RNA_def_property_ui_text(prop, "Size Y", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); -- cgit v1.2.3 From aae4335b9ffebe31326c8f3b1a83a1a17970e5e1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 20:50:11 +0000 Subject: Fix part of #19309: editing node vector input in a popup did not keep it open after changing one of the buttons. --- source/blender/editors/space_node/node_draw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index a87a141972b..1d57f4e0d4c 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -567,6 +567,7 @@ static uiBlock *socket_vector_menu(bContext *C, ARegion *ar, void *socket_v) } block= uiBeginBlock(C, ar, "socket menu", UI_EMBOSS); + uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); /* use this for a fake extra empy space around the buttons */ uiDefBut(block, LABEL, 0, "", -4, -4, 188, 68, NULL, 0, 0, 0, 0, ""); -- cgit v1.2.3 From 862ddcc0c458f2d188ba8410460540ee2d04711d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 21:03:50 +0000 Subject: Fix part of #19307: modifier cage button not working as a toggle button. --- source/blender/editors/interface/interface_templates.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 23ffe46eed4..51678327cdd 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -405,10 +405,12 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v) { Object *ob = ob_v; - ModifierData *md; - + ModifierData *md= md_v; int i, cageIndex = modifiers_getCageIndex(ob, NULL ); + /* undo button operation */ + md->mode ^= eModifierMode_OnCage; + for(i = 0, md=ob->modifiers.first; md; ++i, md=md->next) { if(md == md_v) { if(i >= cageIndex) @@ -517,9 +519,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i /* XXX uiBlockSetEmboss(block, UI_EMBOSSR); */ if(ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) { - /* XXX uiBlockSetCol(block, color); */ - but = uiDefIconBut(block, BUT, 0, ICON_MESH_DATA, 0, 0, 16, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode"); + but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0, 16, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode"); + if(index < cageIndex) + uiButSetFlag(but, UI_BUT_DISABLED); uiButSetFunc(but, modifiers_setOnCage, ob, md); uiBlockEndAlign(block); /* XXX uiBlockSetCol(block, TH_AUTO); */ -- cgit v1.2.3 From d601a51e03ca0dc8d714b36ad7ae7a5005119bc3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 21:19:58 +0000 Subject: RNA: added a "factor" subtype next to "percentage", and only display % sign for percentage assuming it is between 0-100, while factor is for values 0-1. Move collision setting absorption from modifier to collision settings, was inconsistent to have it there as the only one, and made it have range 0.0-1.0 instead of 0-100. --- release/ui/buttons_object_constraint.py | 2 +- release/ui/buttons_physics_field.py | 2 +- source/blender/blenkernel/BKE_collision.h | 2 +- source/blender/blenkernel/intern/collision.c | 27 ++++++------- source/blender/blenkernel/intern/effect.c | 11 ++++-- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/interface/interface_utils.c | 2 +- source/blender/editors/mesh/editmesh_mods.c | 2 +- source/blender/editors/transform/transform_ops.c | 2 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 2 +- source/blender/makesdna/DNA_modifier_types.h | 4 +- source/blender/makesdna/DNA_object_force.h | 2 + source/blender/makesrna/RNA_define.h | 2 + source/blender/makesrna/RNA_types.h | 7 ++-- source/blender/makesrna/intern/makesrna.c | 1 + source/blender/makesrna/intern/rna_camera.c | 2 +- source/blender/makesrna/intern/rna_constraint.c | 8 ++-- source/blender/makesrna/intern/rna_define.c | 19 +++++++++- source/blender/makesrna/intern/rna_material.c | 44 +++++++++++----------- source/blender/makesrna/intern/rna_modifier.c | 6 --- source/blender/makesrna/intern/rna_nodetree.c | 4 +- source/blender/makesrna/intern/rna_object_force.c | 6 +++ source/blender/makesrna/intern/rna_rna.c | 1 + source/blender/makesrna/intern/rna_scene.c | 2 +- source/blender/makesrna/intern/rna_userdef.c | 2 +- 25 files changed, 94 insertions(+), 70 deletions(-) diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py index 1d2f9a5cb49..8671f9e25a8 100644 --- a/release/ui/buttons_object_constraint.py +++ b/release/ui/buttons_object_constraint.py @@ -130,7 +130,7 @@ class ConstraintButtonsPanel(bpy.types.Panel): col = split.column() col.itemR(con, "use_fixed_position") if con.use_fixed_position: - col.itemR(con, "offset_percentage", text="Offset") + col.itemR(con, "offset_factor", text="Offset") else: col.itemR(con, "offset") diff --git a/release/ui/buttons_physics_field.py b/release/ui/buttons_physics_field.py index 252b3bdb08a..f6b50844fc8 100644 --- a/release/ui/buttons_physics_field.py +++ b/release/ui/buttons_physics_field.py @@ -212,7 +212,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel): sub.itemR(settings, "inner_thickness", text="Inner", slider=True) layout.itemL(text="Force Fields:") - layout.itemR(md, "absorption", text="Absorption") + layout.itemR(settings, "absorption", text="Absorption") col = split.column() col.itemL(text="") diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index e4eed084a3d..e0df75f41b9 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -139,7 +139,7 @@ void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], ///////////////////////////////////////////////// // used in effect.c ///////////////////////////////////////////////// -CollisionModifierData **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj); +Object **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj); ///////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 8ef1c285370..aa4aae2422c 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1296,15 +1296,15 @@ static int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierDa // return all collision objects in scene // collision object will exclude self -CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *numcollobj) +Object **get_collisionobjects(Scene *scene, Object *self, int *numcollobj) { Base *base=NULL; - CollisionModifierData **objs = NULL; + Object **objs = NULL; Object *coll_ob = NULL; CollisionModifierData *collmd = NULL; int numobj = 0, maxobj = 100; - objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray"); + objs = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray"); // check all collision objects for ( base = scene->base.first; base; base = base->next ) { @@ -1330,16 +1330,16 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu { // realloc int oldmax = maxobj; - CollisionModifierData **tmp; + Object **tmp; maxobj *= 2; - tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray"); - memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax); + tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray"); + memcpy(tmp, objs, sizeof(Object *)*oldmax); MEM_freeN(objs); objs = tmp; } - objs[numobj] = collmd; + objs[numobj] = coll_ob; numobj++; } else @@ -1374,15 +1374,15 @@ CollisionModifierData **get_collisionobjects(Scene *scene, Object *self, int *nu { // realloc int oldmax = maxobj; - CollisionModifierData **tmp; + Object **tmp; maxobj *= 2; - tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray"); - memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax); + tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray"); + memcpy(tmp, objs, sizeof(Object *)*oldmax); MEM_freeN(objs); objs = tmp; } - objs[numobj] = collmd; + objs[numobj] = coll_ob; numobj++; } } @@ -1459,7 +1459,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl int rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; int ret = 0, ret2 = 0; - CollisionModifierData **collobjs = NULL; + Object **collobjs = NULL; int numcollobj = 0; if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) ) @@ -1498,7 +1498,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl // check all collision objects for(i = 0; i < numcollobj; i++) { - CollisionModifierData *collmd = collobjs[i]; + Object *collob= collobjs[i]; + CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision); BVHTreeOverlap *overlap = NULL; int result = 0; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index e3c4f12184e..acf906e3163 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -258,10 +258,10 @@ static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BV // get visibility of a wind ray static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir) { - CollisionModifierData **collobjs = NULL; + Object **collobjs = NULL; int numcollobj = 0, i; float norm[3], len = 0.0; - float visibility = 1.0; + float visibility = 1.0, absorption = 0.0; collobjs = get_collisionobjects(scene, ob, &numcollobj); @@ -275,7 +275,8 @@ static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir // check all collision objects for(i = 0; i < numcollobj; i++) { - CollisionModifierData *collmd = collobjs[i]; + Object *collob= collobjs[i]; + CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision); if(collmd->bvhtree) { @@ -287,8 +288,10 @@ static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir // check if the way is blocked if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0) { + absorption= (collob->pd)? collob->pd->absorption: 0.0f; + // visibility is only between 0 and 1, calculated from 1-absorption - visibility *= MAX2(0.0, MIN2(1.0, (1.0-((float)collmd->absorption)*0.01))); + visibility *= CLAMPIS(1.0f-absorption, 0.0f, 1.0f); if(visibility <= 0.0f) break; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 8dabe24de91..a18815d04a6 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1078,7 +1078,7 @@ void CURVE_OT_spline_weight_set(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_float_percentage(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f); + RNA_def_float_factor(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f); } /******************* set radius operator ******************/ diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 00dec9a06c2..1d56ed4fb6a 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -73,7 +73,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind if(RNA_property_subtype(prop) == PROP_COLOR) but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL); } - else if(RNA_property_subtype(prop) == PROP_PERCENTAGE) + else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); else but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 3135863d571..93f8bdb6669 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -3553,7 +3553,7 @@ void MESH_OT_select_random(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f); + RNA_def_float_percentage(ot->srna, "percent", 50.0f, 0.0f, 100.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f); } void EM_select_by_material(EditMesh *em, int index) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index f9597b81114..4bf0e44de7f 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -523,7 +523,7 @@ void TFM_OT_tosphere(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_areaactive; - RNA_def_float_percentage(ot->srna, "value", 0, 0, 1, "Percentage", "", 0, 1); + RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); Properties_Proportional(ot); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index b848bd4fb09..c7258e616fa 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -423,7 +423,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry."); - RNA_def_float_percentage(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original.", 0.0f, 1.0f); + RNA_def_float_factor(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original.", 0.0f, 1.0f); RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively.", 0, 100); } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 54433fd4254..bcb85b5f87e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -438,9 +438,7 @@ typedef struct CollisionModifierData { unsigned int numverts; unsigned int numfaces; - short absorption; /* used for forces, in % */ - short pad; - float time; /* cfra time of modifier */ + float time, pad; /* cfra time of modifier */ struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ } CollisionModifierData; diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 986a75f1a96..468ad35de85 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -62,6 +62,8 @@ typedef struct PartDeflect { float pdef_sbift; /* inner face thickness for softbody deflection */ float pdef_sboft; /* outer face thickness for softbody deflection */ + float absorption, pad; /* used for forces */ + /* variables for guide curve */ float clump_fac, clump_pow; float kink_freq, kink_shape, kink_amp, free_end; diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 595562503aa..37b175fbf12 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -102,6 +102,8 @@ PropertyRNA *RNA_def_float_dynamic_array(StructOrFunctionRNA *cont, const char * */ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); +PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, + const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont, const char *identifier, const char *type, const char *ui_name, const char *ui_description); diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 353c859cf27..5fff2af29ff 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -94,9 +94,10 @@ typedef enum PropertySubType { /* numbers */ PROP_UNSIGNED = 13, PROP_PERCENTAGE = 14, - PROP_ANGLE = 15|PROP_UNIT_ROTATION, - PROP_TIME = 16|PROP_UNIT_TIME, - PROP_DISTANCE = 17|PROP_UNIT_LENGTH, + PROP_FACTOR = 15, + PROP_ANGLE = 16|PROP_UNIT_ROTATION, + PROP_TIME = 17|PROP_UNIT_TIME, + PROP_DISTANCE = 18|PROP_UNIT_LENGTH, /* number arrays */ PROP_COLOR = 20, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index c734cdfec87..3e610005113 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1406,6 +1406,7 @@ static const char *rna_property_subtypename(PropertyType type) case PROP_DIRPATH: return "PROP_DIRPATH"; case PROP_UNSIGNED: return "PROP_UNSIGNED"; case PROP_PERCENTAGE: return "PROP_PERCENTAGE"; + case PROP_FACTOR: return "PROP_FACTOR"; case PROP_ANGLE: return "PROP_ANGLE"; case PROP_TIME: return "PROP_TIME"; case PROP_DISTANCE: return "PROP_DISTANCE"; diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index 9c33b0afb00..eaf647e02a2 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -62,7 +62,7 @@ void RNA_def_camera(BlenderRNA *brna) /* Number values */ - prop= RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "passepartalpha"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view."); diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 1bbac8da02f..86aa2a1d135 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -591,7 +591,7 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna) srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint"); RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target."); - prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, "bConstraint", "headtail"); RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); @@ -893,10 +893,10 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Offset", "Offset from the position corresponding to the time frame."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); - prop= RNA_def_property(srna, "offset_percentage", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "offset_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "offset"); // XXX we might be better with another var or some hackery? RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Offset Percentage", "Percentage value defining target position along length of bone."); + RNA_def_property_ui_text(prop, "Offset Factor", "Percentage value defining target position along length of bone."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); prop= RNA_def_property(srna, "forward", PROP_ENUM, PROP_NONE); @@ -1617,7 +1617,7 @@ void RNA_def_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Proxy Local", "Constraint was added in this proxy instance (i.e. did not belong to source Armature)."); /* values */ - prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "enforce"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Influence", "Amount of influence constraint will have on the final solution."); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 45517546c16..cc86da18a0b 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -890,7 +890,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier fprop->softmin= 0.0f; fprop->softmax= 1.0f; } - else if(subtype == PROP_PERCENTAGE) { + else if(subtype == PROP_FACTOR) { fprop->softmin= fprop->hardmin= 0.0f; fprop->softmax= fprop->hardmax= 1.0f; } @@ -1530,7 +1530,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const iprop->softmax= 10000; } - if(prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE) + if(prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE || prop->subtype == PROP_FACTOR) iprop->hardmin= iprop->softmin= 0; } } @@ -2261,6 +2261,21 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *id return prop; } +PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, float default_value, + float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) +{ + ContainerRNA *cont= cont_; + PropertyRNA *prop; + + prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, default_value); + if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); + RNA_def_property_ui_text(prop, ui_name, ui_description); + RNA_def_property_ui_range(prop, softmin, softmax, 1, 3); + + return prop; +} + PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description) { diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 18c0dc42e17..23aeacb97f2 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -645,12 +645,12 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_ui_text(prop, "Mirror Color", "Mirror color of the material."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Alpha", "Alpha transparency of the material."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL); - prop= RNA_def_property(srna, "specular_alpha", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "specular_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "spectra"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Specular Alpha", "Alpha transparency for specular areas."); @@ -725,7 +725,7 @@ static void rna_def_material_diffuse(StructRNA *srna) RNA_def_property_ui_text(prop, "Diffuse Shader Model", ""); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "diffuse_intensity", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "diffuse_intensity", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "ref"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Diffuse Intensity", "Amount of diffuse reflection."); @@ -742,7 +742,7 @@ static void rna_def_material_diffuse(StructRNA *srna) RNA_def_property_ui_text(prop, "Diffuse Toon Size", "Size of diffuse toon area."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "diffuse_toon_smooth", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "diffuse_toon_smooth", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "param[1]"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Diffuse Toon Smooth", "Smoothness of diffuse toon area."); @@ -786,7 +786,7 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Enabled", "Enable raytraced reflections."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "ray_mirror"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Reflectivity", "Sets the amount mirror reflection for raytrace."); @@ -798,19 +798,19 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fresnel", "Power of Fresnel for mirror reflection."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "fresnel_mir_i"); RNA_def_property_range(prop, 0.0f, 5.0f); RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "gloss_mir"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Amount", "The shininess of the reflection. Values < 1.0 give diffuse, blurry reflections."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_anisotropic", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_anisotropic", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "aniso_gloss_mir"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Anisotropy", "The shape of the reflection, from 0.0 (circular) to 1.0 (fully stretched along the tangent."); @@ -822,7 +822,7 @@ static void rna_def_material_raymirror(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Gloss Samples", "Number of cone samples averaged for blurry reflections."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "adapt_thresh_mir"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Threshold", "Threshold for adaptive sampling. If a sample contributes less than this amount (as a percentage), sampling is stopped."); @@ -869,13 +869,13 @@ static void rna_def_material_raytra(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fresnel", "Power of Fresnel for transparency (Ray or ZTransp)."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "fresnel_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "fresnel_tra_i"); RNA_def_property_range(prop, 1.0f, 5.0f); RNA_def_property_ui_text(prop, "Fresnel Factor", "Blending factor for Fresnel."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "gloss_tra"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Amount", "The clarity of the refraction. Values < 1.0 give diffuse, blurry refractions."); @@ -887,7 +887,7 @@ static void rna_def_material_raytra(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Gloss Samples", "Number of cone samples averaged for blurry refractions."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "gloss_threshold", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "adapt_thresh_tra"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Gloss Threshold", "Threshold for adaptive sampling. If a sample contributes less than this amount (as a percentage), sampling is stopped."); @@ -899,7 +899,7 @@ static void rna_def_material_raytra(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Depth", "Maximum allowed number of light inter-refractions."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "filter", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "filter", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "filter"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Filter", "Amount to blend in the material's diffuse color in raytraced transparency (simulating absorption)."); @@ -1011,7 +1011,7 @@ static void rna_def_material_volume(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Depth Cutoff", "Stop ray marching early if transmission drops below this luminance - higher values give speedups in dense volumes at the expense of accuracy."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "density", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "density", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "density"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Density", "The base density of the volume"); @@ -1093,7 +1093,7 @@ static void rna_def_material_halo(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Hardness", "Sets the hardness of the halo."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "add", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "add", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "add"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Add", "Sets the strength of the add effect."); @@ -1239,13 +1239,13 @@ static void rna_def_material_sss(BlenderRNA *brna) RNA_def_property_ui_text(prop, "IOR", "Index of refraction (higher values are denser)."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "color_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "sss_colfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Color Factor", "Blend factor for SSS colors."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "texture_factor", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "texture_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "sss_texfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Texture Factor", "Texture scatting blend factor."); @@ -1287,7 +1287,7 @@ static void rna_def_material_specularity(StructRNA *srna) RNA_def_property_ui_text(prop, "Specular Shader Model", ""); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "spec"); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Specular Intensity", ""); @@ -1316,7 +1316,7 @@ static void rna_def_material_specularity(StructRNA *srna) RNA_def_property_ui_text(prop, "Specular Toon Size", "Size of specular toon area."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "specular_toon_smooth", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "specular_toon_smooth", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "param[3]"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Specular Toon Smooth", "Ssmoothness of specular toon area."); @@ -1474,7 +1474,7 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Transparency Method", "Method to use for rendering transparency."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "ambient", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "ambient", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "amb"); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Ambient", "Amount of global ambient color the material receives."); @@ -1486,7 +1486,7 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Emit", "Amount of light to emit."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); - prop= RNA_def_property(srna, "translucency", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "translucency", PROP_FLOAT, PROP_FACTOR); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Translucency", "Amount of diffuse shading on the back side."); RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL); @@ -1511,7 +1511,7 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_range(prop, 0, 10); RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Factor to multiply shadow buffer bias with (0 is ignore.)"); - prop= RNA_def_property(srna, "shadow_casting_alpha", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "shadow_casting_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "shad_alpha"); RNA_def_property_range(prop, 0.001, 1); RNA_def_property_ui_text(prop, "Shadow Casting Alpha", "Shadow casting alpha, only in use for Irregular Shadowbuffer."); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index ffc2d78a6ce..480abff19cb 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1619,12 +1619,6 @@ static void rna_def_modifier_collision(BlenderRNA *brna) RNA_def_property_struct_type(prop, "CollisionSettings"); RNA_def_property_pointer_funcs(prop, "rna_CollisionModifier_settings_get", NULL, NULL); RNA_def_property_ui_text(prop, "Settings", ""); - - prop= RNA_def_property(srna, "absorption", PROP_INT, PROP_PERCENTAGE); - RNA_def_property_int_sdna(prop, NULL, "absorption"); - RNA_def_property_ui_range(prop, 0, 100, 1, 2); - RNA_def_property_ui_text(prop, "Absorption %", "How much of effector force gets lost during collision with this object (in percent)."); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_bevel(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d80ebe2da05..ebd032bb0b1 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1118,7 +1118,7 @@ static void def_cmp_splitviewer(StructRNA *srna) RNA_def_property_ui_text(prop, "Axis", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); - prop = RNA_def_property(srna, "factor", PROP_INT, PROP_PERCENTAGE); + prop = RNA_def_property(srna, "factor", PROP_INT, PROP_FACTOR); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Factor", ""); @@ -1140,7 +1140,7 @@ static void def_cmp_map_uv(StructRNA *srna) { PropertyRNA *prop; - prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_PERCENTAGE); + prop = RNA_def_property(srna, "alpha", PROP_INT, PROP_FACTOR); RNA_def_property_int_sdna(prop, NULL, "custom1"); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Alpha", ""); diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 3dfbfcccacf..1f0d01ce784 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -617,6 +617,12 @@ static void rna_def_collision(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Collision from Stack", "Pick collision object from modifier stack (softbody only)"); RNA_def_property_update(prop, 0, "rna_CollisionSettings_update"); */ + + prop= RNA_def_property(srna, "absorption", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 2); + RNA_def_property_ui_text(prop, "Absorption", "How much of effector force gets lost during collision with this object (in percent)."); + RNA_def_property_update(prop, 0, "rna_CollisionSettings_update"); } static void rna_def_field(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 37a1c9fb186..8dd751cd26a 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -842,6 +842,7 @@ static void rna_def_property(BlenderRNA *brna) {PROP_DIRPATH, "DIRECTORY_PATH", 0, "Directory Path", ""}, {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned Number", ""}, {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""}, + {PROP_FACTOR, "FACTOR", 0, "Factor", ""}, {PROP_ANGLE, "ANGLE", 0, "Angle", ""}, {PROP_TIME, "TIME", 0, "Time", ""}, {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""}, diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5def517f8b2..cac639a64ed 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -523,7 +523,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_enum_items(prop, mesh_select_mode_items); RNA_def_property_ui_text(prop, "Mesh Selection Mode", "Mesh selection and display mode."); - prop= RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "vgroup_weight"); RNA_def_property_ui_text(prop, "Vertex Group Weight", "Weight to assign in vertex groups."); } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index b9c5739e7eb..e9fcb299c53 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -316,7 +316,7 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Driven Selected", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop= RNA_def_property(srna, "blend", PROP_FLOAT, PROP_PERCENTAGE); + prop= RNA_def_property(srna, "blend", PROP_FLOAT, PROP_FACTOR); RNA_def_property_ui_text(prop, "Blend", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); } -- cgit v1.2.3 From 3448f675cb20ad38691a4d40ed90f44722243ae9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 21:26:04 +0000 Subject: Fix #19427, problem in blenfont not computing the width of text correct, particularly text including spaces. This gave some problems with placing the cursor and selection, and clipping text inside buttons. --- source/blender/blenfont/intern/blf_font.c | 4 ++-- source/blender/editors/interface/interface_widgets.c | 11 +++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 0a3dd259f6c..8721e49f06b 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -353,8 +353,8 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box) pen_x += delta.x >> 6; } - gbox.xmin= g->box.xmin + pen_x; - gbox.xmax= g->box.xmax + pen_x; + gbox.xmin= pen_x; + gbox.xmax= pen_x + g->advance; gbox.ymin= g->box.ymin + pen_y; gbox.ymax= g->box.ymax + pen_y; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 90b2c920613..ac8750f84e6 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -773,7 +773,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, int blend, rcti *rect) /* sets but->ofs to make sure text is correctly visible */ static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect) { - int okwidth= rect->xmax-rect->xmin; + int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10; + int okwidth= rect->xmax-rect->xmin - border; /* need to set this first */ uiStyleFontSet(fstyle); @@ -842,11 +843,8 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b but->drawstr[selend_tmp]= ch; - /* if at pos 0, leave a bit more to the left */ - t= (pos == 0)? 0: 1; - glColor3ubv((unsigned char*)wcol->item); - glRects(rect->xmin+selsta_draw+1, rect->ymin+2, rect->xmin+selwidth_draw+1, rect->ymax-2); + glRects(rect->xmin+selsta_draw, rect->ymin+2, rect->xmin+selwidth_draw, rect->ymax-2); } } else { /* text cursor */ @@ -861,9 +859,6 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b but->drawstr[pos]= ch; } - /* if at pos 0, leave a bit more to the left */ - t += (pos == 0)? 0: 1; - glColor3ub(255,0,0); glRects(rect->xmin+t, rect->ymin+2, rect->xmin+t+2, rect->ymax-2); } -- cgit v1.2.3 From 345169d1fb82ad4d68f867e5b33276e2886bd6f0 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Mon, 21 Sep 2009 21:28:48 +0000 Subject: Updated some colors in node space and file browser to better match the color theme in 2.5. --- source/blender/editors/interface/resources.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index c54e09b2b40..87026bd1a5d 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -517,10 +517,12 @@ void ui_theme_init_userdef(void) /* space file */ /* to have something initialized */ btheme->tfile= btheme->tv3d; - SETCOL(btheme->tfile.back, 90, 90, 90, 255); + SETCOLF(btheme->tfile.back, 0.3, 0.3, 0.3, 1); + SETCOLF(btheme->tfile.panel, 0.3, 0.3, 0.3, 1); + SETCOLF(btheme->tfile.list, 0.4, 0.4, 0.4, 1); SETCOL(btheme->tfile.text, 250, 250, 250, 255); SETCOL(btheme->tfile.text_hi, 15, 15, 15, 255); - SETCOL(btheme->tfile.panel, 180, 180, 180, 255); // bookmark/ui regions + SETCOL(btheme->tfile.panel, 145, 145, 145, 255); // bookmark/ui regions SETCOL(btheme->tfile.active, 130, 130, 130, 255); // selected files SETCOL(btheme->tfile.hilite, 255, 140, 25, 255); // selected files @@ -604,11 +606,11 @@ void ui_theme_init_userdef(void) /* space node, re-uses syntax color storage */ btheme->tnode= btheme->tv3d; SETCOL(btheme->tnode.edge_select, 255, 255, 255, 255); - SETCOL(btheme->tnode.syntaxl, 150, 150, 150, 255); /* TH_NODE, backdrop */ - SETCOL(btheme->tnode.syntaxn, 129, 131, 144, 255); /* in/output */ - SETCOL(btheme->tnode.syntaxb, 127,127,127, 255); /* operator */ - SETCOL(btheme->tnode.syntaxv, 142, 138, 145, 255); /* generator */ - SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255); /* group */ + SETCOL(btheme->tnode.syntaxl, 155, 155, 155, 160); /* TH_NODE, backdrop */ + SETCOL(btheme->tnode.syntaxn, 100, 100, 100, 255); /* in/output */ + SETCOL(btheme->tnode.syntaxb, 108, 105, 111, 255); /* operator */ + SETCOL(btheme->tnode.syntaxv, 104, 106, 117, 255); /* generator */ + SETCOL(btheme->tnode.syntaxc, 105, 117, 110, 255); /* group */ /* space logic */ btheme->tlogic= btheme->tv3d; -- cgit v1.2.3 From 9182dc3b8f5e2478d3784741b6a77ad6073ac0a1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 21 Sep 2009 21:37:19 +0000 Subject: Fix #19391: quiting BGE could give drawing errors. Blender now restores the default OpenGL state after exiting the game engine, and also removed settings the default state on start, since the game engine already does this. --- source/blender/editors/space_view3d/view3d_view.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 7831d604ddf..b15a7d3c837 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1416,8 +1416,6 @@ static void SaveState(bContext *C) glPushAttrib(GL_ALL_ATTRIB_BITS); - GPU_state_init(); - if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) GPU_paint_set_mipmap(1); @@ -1446,6 +1444,8 @@ static void RestoreState(bContext *C) win->queue= queue_back; + GPU_state_init(); + glPopAttrib(); } -- cgit v1.2.3 From b55919069e98ecf877d8d44189a0560982583b36 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 22 Sep 2009 01:27:48 +0000 Subject: 2.5 - Keyframe types are now preserved after inserting keyframes which would overwrite the existing keyframes --- source/blender/editors/animation/keyframing.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index e8451b0f979..e3e72a532e2 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -207,8 +207,13 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag) // TODO: perform some other operations? } else { + char oldKeyType= BEZKEYTYPE(fcu->bezt + i); + /* just brutally replace the values */ *(fcu->bezt + i) = *bezt; + + /* special exception for keyframe type - copy value back so that this info isn't lost */ + BEZKEYTYPE(fcu->bezt + i)= oldKeyType; } } } -- cgit v1.2.3 From 7ead925ce42509c0f528a1f8919f80f10cb7c799 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 22 Sep 2009 04:40:16 +0000 Subject: - removed View3D->localview since it wasnt set on entering localview (making many tools fail, add objects for eg.), check localvd instead. - Accent (`) key now sets all layers (like in 2.4x) - added Alt+C keybinding for converting object types. --- source/blender/blenlib/intern/arithb.c | 2 +- source/blender/blenloader/intern/readfile.c | 1 - source/blender/editors/mesh/meshtools.c | 2 +- source/blender/editors/object/object_add.c | 2 +- source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_relations.c | 2 +- source/blender/editors/space_view3d/space_view3d.c | 1 - source/blender/editors/space_view3d/view3d_draw.c | 4 +- .../blender/editors/space_view3d/view3d_header.c | 55 +++++++++++++--------- source/blender/editors/space_view3d/view3d_ops.c | 1 + source/blender/editors/space_view3d/view3d_view.c | 4 +- source/blender/makesdna/DNA_view3d_types.h | 2 +- source/blender/makesrna/intern/rna_space.c | 6 +-- 13 files changed, 45 insertions(+), 38 deletions(-) diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index ac79894d827..26bbbf040f3 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -4843,7 +4843,7 @@ static float lambda_cp_line(float p[3], float l1[3], float l2[3]) /* useful to calculate an even width shell, by taking the angle between 2 planes. * The return value is a scale on the offset. * no angle between planes is 1.0, as the angle between the 2 planes approches 180d - * the distance gets very hight, 180d would be inf, but this case isnt valid */ + * the distance gets very high, 180d would be inf, but this case isn't valid */ float AngleToLength(const float angle) { return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle * (M_PI/180.0f))); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index af7fda82fe4..d9db02e630f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4688,7 +4688,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) v3d->layact= v3d->localvd->layact; MEM_freeN(v3d->localvd); v3d->localvd= NULL; - v3d->localview= 0; } */ } diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 4aa99820a6e..00893f10165 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -632,7 +632,7 @@ void sort_faces(Scene *scene, View3D *v3d) if (event == 1) Mat4MulMat4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */ else if (event == 2) { /* sort from cursor */ - if( v3d && v3d->localview ) { + if( v3d && v3d->localvd ) { VECCOPY(cur, v3d->cursor); } else { VECCOPY(cur, scene->cursor); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index d576f6e8bf6..05905cd42a4 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -110,7 +110,7 @@ void ED_object_base_init_from_view(bContext *C, Base *base) VECCOPY(ob->loc, scene->cursor); } else { - if (v3d->localview) { + if (v3d->localvd) { base->lay= ob->lay= v3d->layact | v3d->lay; VECCOPY(ob->loc, v3d->cursor); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index a9b4bfe68dd..7397cead505 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -244,6 +244,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1); WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_convert", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); // XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 17590cbaad3..4a0c812f7b1 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -994,7 +994,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op) if(lay==0) return OPERATOR_CANCELLED; - if(v3d && v3d->localview) { + if(v3d && v3d->localvd) { /* now we can move out of localview. */ // XXX if (!okee("Move from localview")) return; CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index a73a16f38ba..6e415ec731d 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -259,7 +259,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) if(v3do->localvd) { v3do->localvd= NULL; v3do->properties_storage= NULL; - v3do->localview= 0; v3do->lay= v3dn->localvd->lay; v3do->lay &= 0xFFFFFF; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index f8584b14e2b..5612e60e899 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -732,7 +732,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) char *name = view3d_get_name(v3d, rv3d); char *printable = NULL; - if (v3d->localview) { + if (v3d->localvd) { printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */ strcpy(printable, name); strcat(printable, " (Local)"); @@ -745,7 +745,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) BLF_draw_default(22, ar->winy-17, 0.0f, printable); } - if (v3d->localview) { + if (v3d->localvd) { free(printable); } } diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a18e7da8f20..45828d654aa 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -177,7 +177,7 @@ static void handle_view3d_lock(bContext *C) View3D *v3d= CTX_wm_view3d(C); if (v3d != NULL && sa != NULL) { - if(v3d->localview==0 && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) { + if(v3d->localvd==NULL && v3d->scenelock && sa->spacetype==SPACE_VIEW3D) { /* copy to scene */ scene->lay= v3d->lay; @@ -195,27 +195,38 @@ static int layers_exec(bContext *C, wmOperator *op) View3D *v3d= sa->spacedata.first; int nr= RNA_int_get(op->ptr, "nr"); - if(nr<=0) + if(nr < 0) return OPERATOR_CANCELLED; - nr--; - - if(RNA_boolean_get(op->ptr, "extend")) - v3d->lay |= (1<lay = (1<lay & (1<layact= 1<lay & v3d->layact)==0) { - int bit= 0; + + + if(nr == 0) { + /* all layers */ + v3d->lay |= (1<<20)-1; + + if(!v3d->layact) + v3d->layact= 1; + } + else { + nr--; + + if(RNA_boolean_get(op->ptr, "extend")) + v3d->lay |= (1<lay = (1<lay & (1<layact= 1<lay & (1<layact= 1<lay & v3d->layact)==0) { + int bit= 0; + + while(bit<32) { + if(v3d->lay & (1<layact= 1<flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "", 0, 20); - RNA_def_boolean(ot->srna, "extend", 0, "Extend", ""); + RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers"); } #if 0 @@ -2078,7 +2089,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) } /* LAYERS */ - if(obedit==NULL && v3d->localview==0) { + if(obedit==NULL && v3d->localvd==NULL) { int ob_lay = ob ? ob->lay : 0; uiBlockBeginAlign(block); for(a=0; a<5; a++) { diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 3569e2a79e3..57176dc2592 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -157,6 +157,7 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0); /* layers, shift + alt are properties set in invoke() */ + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ACCENTGRAVEKEY, KM_PRESS, 0, 0)->ptr, "nr", 0); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ONEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", TWOKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 2); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", THREEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 3); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b15a7d3c837..b6b6f654909 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -110,7 +110,7 @@ void view3d_operator_needs_opengl(const bContext *C) float *give_cursor(Scene *scene, View3D *v3d) { - if(v3d && v3d->localview) return v3d->cursor; + if(v3d && v3d->localvd) return v3d->cursor; else return scene->cursor; } @@ -1303,7 +1303,6 @@ static void initlocalview(Scene *scene, ScrArea *sa) base->object->lay= base->lay; } } - v3d->localview= 0; } } @@ -1325,7 +1324,6 @@ static void restore_localviewdata(ScrArea *sa, int free) if(free) { MEM_freeN(v3d->localvd); v3d->localvd= NULL; - v3d->localview= 0; } for(ar= sa->regionbase.first; ar; ar= ar->next) { diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index d42ccd62694..f67a242b469 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -144,7 +144,7 @@ typedef struct View3D { * The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID, * OB_SHADED or OB_TEXTURE */ short drawtype; - short localview; + short pad2; short scenelock, around, pad3; short flag, flag2; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 9cf413c0f78..df956670eb3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -602,11 +602,9 @@ static void rna_def_space_3dview(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Viewport Shading", "Method to display/shade objects in the 3D View."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); - prop= RNA_def_property(srna, "localview", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "localview", 0); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop= RNA_def_property(srna, "local_view", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "localvd"); RNA_def_property_ui_text(prop, "Local View", "Display an isolated sub-set of objects, apart from the scene visibility."); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "lens", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "lens"); -- cgit v1.2.3 From b1d4d75aab81eecf409956f15bf9c795715dfe86 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 22 Sep 2009 08:41:03 +0000 Subject: brought back edge slide. --- source/blender/editors/include/ED_mesh.h | 8 + source/blender/editors/include/ED_transform.h | 3 +- source/blender/editors/mesh/editmesh_tools.c | 6 +- source/blender/editors/mesh/mesh_intern.h | 6 - source/blender/editors/mesh/mesh_ops.c | 1 + source/blender/editors/transform/transform.c | 669 +++++++++++++++++++++ source/blender/editors/transform/transform.h | 32 + .../blender/editors/transform/transform_generics.c | 4 + source/blender/editors/transform/transform_ops.c | 1 + 9 files changed, 721 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index a2dba89ec20..a871ab555a5 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -175,5 +175,13 @@ float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int ver struct MDeformWeight *ED_vgroup_weight_verify(struct MDeformVert *dv, int defgroup); struct MDeformWeight *ED_vgroup_weight_get(struct MDeformVert *dv, int defgroup); +/*needed by edge slide*/ +struct EditVert *editedge_getOtherVert(struct EditEdge *eed, struct EditVert *eve); +struct EditVert *editedge_getSharedVert(struct EditEdge *eed, struct EditEdge *eed2); +int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve); +int editface_containsVert(struct EditFace *efa, struct EditVert *eve); +int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed); +short sharesFace(struct EditMesh *em, struct EditEdge *e1, struct EditEdge *e2); + #endif /* ED_MESH_H */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 96425f725e9..bf3111de5dc 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -75,7 +75,8 @@ enum { TFM_BAKE_TIME, TFM_BEVEL, TFM_BWEIGHT, - TFM_ALIGN + TFM_ALIGN, + TFM_EDGE_SLIDE } TfmMode; /* TRANSFORM CONTEXTS */ diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 46b941f70df..2c20e4a147c 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3868,11 +3868,11 @@ typedef struct SlideVert { EditVert origvert; } SlideVert; +#if 0 int EdgeSlide(EditMesh *em, wmOperator *op, short immediate, float imperc) { return 0; /* XXX REFACTOR - #if 0'd for now, otherwise can't make 64bit windows builds on 64bit machine */ -#if 0 useless: goto useless // because it doesn't do anything right now @@ -4654,11 +4654,12 @@ useless: } return 1; -#endif // END OF XXX } +#endif // END OF XXX int EdgeLoopDelete(EditMesh *em, wmOperator *op) { +#if 0 //XXX won't work with new edgeslide /* temporal flag setting so we keep UVs when deleting edge loops, * this is a bit of a hack but it works how you would want in almost all cases */ @@ -4677,6 +4678,7 @@ int EdgeLoopDelete(EditMesh *em, wmOperator *op) EM_select_flush(em); // DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return 1; +#endif } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 11a974f2c49..37a6d0f384f 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -61,12 +61,6 @@ extern struct EditEdge *addedgelist(EditMesh *em, struct EditVert *v1, struct Ed extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); extern struct EditEdge *findedgelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2); -EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve); -EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2); -int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve); -int editface_containsVert(struct EditFace *efa, struct EditVert *eve); -int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed); - void em_setup_viewcontext(struct bContext *C, ViewContext *vc); void MESH_OT_separate(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index f22adc597c7..3f1bbbb9097 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -113,6 +113,7 @@ static int edge_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) uiItemEnumO(layout, "Rotate Edge CCW", 0, "MESH_OT_edge_rotate", "direction", 2); //uiItemO(layout, "Loopcut", 0, "MESH_OT_loop_cut"); // CutEdgeloop(em, 1); //uiItemO(layout, "Edge Slide", 0, "MESH_OT_edge_slide"); // EdgeSlide(em, 0,0.0); + uiItemEnumO(layout, "Edge Slide", 0, "TFM_OT_transform", "mode", TFM_EDGE_SLIDE); uiItemO(layout, "Edge Loop", 0, "MESH_OT_loop_multi_select"); uiItemBooleanO(layout, "Edge Ring", 0, "MESH_OT_loop_multi_select", "ring", 1); uiItemO(layout, NULL, 0, "MESH_OT_loop_to_region"); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index e877f1fecae..8f3fcfedd18 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -100,6 +100,7 @@ #include "ED_markers.h" #include "ED_util.h" #include "ED_view3d.h" +#include "ED_mesh.h" #include "UI_view2d.h" #include "WM_types.h" @@ -108,6 +109,8 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "BLI_ghash.h" +#include "BLI_linklist.h" #include "PIL_time.h" /* sleep */ @@ -1428,6 +1431,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int case TFM_BONE_ENVELOPE: initBoneEnvelope(t); break; + case TFM_EDGE_SLIDE: + initEdgeSlide(t); + break; case TFM_BONE_ROLL: initBoneRoll(t); break; @@ -4029,6 +4035,669 @@ int BoneEnvelope(TransInfo *t, short mval[2]) return 1; } +/* ******************** Edge Slide *************** */ + +static int createSlideVerts(TransInfo *t) +{ + Mesh *me = t->obedit->data; + EditMesh *em = me->edit_mesh; + EditFace *efa; + EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL; + EditVert *ev, *nearest = NULL; + LinkNode *edgelist = NULL, *vertlist=NULL, *look; + GHash *vertgh; + TransDataSlideVert *tempsv; + float perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4]; + float shiftlabda= 0.0f,len = 0.0f; + int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0; + int wasshift = 0; + /* UV correction vars */ + GHash **uvarray= NULL; + SlideData *sld = MEM_callocN(sizeof(*sld), "sld"); + int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); + int uvlay_idx; + TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL; + RegionView3D *v3d = t->ar->regiondata; + float projectMat[4][4]; + float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f}; + float vec[3]; + //short mval[2], mvalo[2]; + float labda = 0.0f, totvec=0.0; + + view3d_get_object_project_mat(v3d, t->obedit, projectMat); + + //mvalo[0] = -1; mvalo[1] = -1; + numsel =0; + + // Get number of selected edges and clear some flags + for(eed=em->edges.first;eed;eed=eed->next) { + eed->f1 = 0; + eed->f2 = 0; + if(eed->f & SELECT) numsel++; + } + + for(ev=em->verts.first;ev;ev=ev->next) { + ev->f1 = 0; + } + + //Make sure each edge only has 2 faces + // make sure loop doesn't cross face + for(efa=em->faces.first;efa;efa=efa->next) { + int ct = 0; + if(efa->e1->f & SELECT) { + ct++; + efa->e1->f1++; + if(efa->e1->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + if(efa->e2->f & SELECT) { + ct++; + efa->e2->f1++; + if(efa->e2->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + if(efa->e3->f & SELECT) { + ct++; + efa->e3->f1++; + if(efa->e3->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + if(efa->e4 && efa->e4->f & SELECT) { + ct++; + efa->e4->f1++; + if(efa->e4->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + // Make sure loop is not 2 edges of same face + if(ct > 1) { + //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself"); + return 0; + } + } + + // Get # of selected verts + for(ev=em->verts.first;ev;ev=ev->next) { + if(ev->f & SELECT) vertsel++; + } + + // Test for multiple segments + if(vertsel > numsel+1) { + //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop"); + return 0; + } + + // Get the edgeloop in order - mark f1 with SELECT once added + for(eed=em->edges.first;eed;eed=eed->next) { + if((eed->f & SELECT) && !(eed->f1 & SELECT)) { + // If this is the first edge added, just put it in + if(!edgelist) { + BLI_linklist_prepend(&edgelist,eed); + numadded++; + first = eed; + last = eed; + eed->f1 = SELECT; + } else { + if(editedge_getSharedVert(eed, last)) { + BLI_linklist_append(&edgelist,eed); + eed->f1 = SELECT; + numadded++; + last = eed; + } else if(editedge_getSharedVert(eed, first)) { + BLI_linklist_prepend(&edgelist,eed); + eed->f1 = SELECT; + numadded++; + first = eed; + } + } + } + if(eed->next == NULL && numadded != numsel) { + eed=em->edges.first; + timesthrough++; + } + + // It looks like there was an unexpected case - Hopefully should not happen + if(timesthrough >= numsel*2) { + BLI_linklist_free(edgelist,NULL); + //BKE_report(op->reports, RPT_ERROR, "Could not order loop"); + return 0; + } + } + + // Put the verts in order in a linklist + look = edgelist; + while(look) { + eed = look->link; + if(!vertlist) { + if(look->next) { + temp = look->next->link; + + //This is the first entry takes care of extra vert + if(eed->v1 != temp->v1 && eed->v1 != temp->v2) { + BLI_linklist_append(&vertlist,eed->v1); + eed->v1->f1 = 1; + } else { + BLI_linklist_append(&vertlist,eed->v2); + eed->v2->f1 = 1; + } + } else { + //This is the case that we only have 1 edge + BLI_linklist_append(&vertlist,eed->v1); + eed->v1->f1 = 1; + } + } + // for all the entries + if(eed->v1->f1 != 1) { + BLI_linklist_append(&vertlist,eed->v1); + eed->v1->f1 = 1; + } else if(eed->v2->f1 != 1) { + BLI_linklist_append(&vertlist,eed->v2); + eed->v2->f1 = 1; + } + look = look->next; + } + + // populate the SlideVerts + + vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + look = vertlist; + while(look) { + i=0; + j=0; + ev = look->link; + tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert"); + tempsv->up = NULL; + tempsv->down = NULL; + tempsv->origvert.co[0] = ev->co[0]; + tempsv->origvert.co[1] = ev->co[1]; + tempsv->origvert.co[2] = ev->co[2]; + tempsv->origvert.no[0] = ev->no[0]; + tempsv->origvert.no[1] = ev->no[1]; + tempsv->origvert.no[2] = ev->no[2]; + // i is total edges that vert is on + // j is total selected edges that vert is on + + for(eed=em->edges.first;eed;eed=eed->next) { + if(eed->v1 == ev || eed->v2 == ev) { + i++; + if(eed->f & SELECT) { + j++; + } + } + } + // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges + if(i == 4 && j == 2) { + for(eed=em->edges.first;eed;eed=eed->next) { + if(editedge_containsVert(eed, ev)) { + if(!(eed->f & SELECT)) { + if(!tempsv->up) { + tempsv->up = eed; + } else if (!(tempsv->down)) { + tempsv->down = eed; + } + } + } + } + } + // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected + if(i >= 3 && j == 1) { + for(eed=em->edges.first;eed;eed=eed->next) { + if(editedge_containsVert(eed, ev) && eed->f & SELECT) { + for(efa = em->faces.first;efa;efa=efa->next) { + if(editface_containsEdge(efa, eed)) { + if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e1; + } else if (!(tempsv->down)) { + tempsv->down = efa->e1; + } + } + if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e2; + } else if (!(tempsv->down)) { + tempsv->down = efa->e2; + } + } + if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e3; + } else if (!(tempsv->down)) { + tempsv->down = efa->e3; + } + } + if(efa->e4) { + if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e4; + } else if (!(tempsv->down)) { + tempsv->down = efa->e4; + } + } + } + + } + } + } + } + } + if(i > 4 && j == 2) { + BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(vertlist,NULL); + BLI_linklist_free(edgelist,NULL); + return 0; + } + BLI_ghash_insert(vertgh,ev,tempsv); + + look = look->next; + } + + // make sure the UPs nad DOWNs are 'faceloops' + // Also find the nearest slidevert to the cursor + + look = vertlist; + nearest = NULL; + vertdist = -1; + while(look) { + tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); + + if(!tempsv->up || !tempsv->down) { + //BKE_report(op->reports, RPT_ERROR, "Missing rails"); + BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(vertlist,NULL); + BLI_linklist_free(edgelist,NULL); + return 0; + } + + if(me->drawflag & ME_DRAW_EDGELEN) { + if(!(tempsv->up->f & SELECT)) { + tempsv->up->f |= SELECT; + tempsv->up->f2 |= 16; + } else { + tempsv->up->f2 |= ~16; + } + if(!(tempsv->down->f & SELECT)) { + tempsv->down->f |= SELECT; + tempsv->down->f2 |= 16; + } else { + tempsv->down->f2 |= ~16; + } + } + + if(look->next != NULL) { + TransDataSlideVert *sv; + + ev = (EditVert*)look->next->link; + sv = BLI_ghash_lookup(vertgh, ev); + + if(sv) { + float co[3], co2[3], vec[3]; + + if(!sharesFace(em, tempsv->up,sv->up)) { + EditEdge *swap; + swap = sv->up; + sv->up = sv->down; + sv->down = swap; + } + + view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat); + view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat); + + if (ev == sv->up->v1) { + VecSubf(vec, co, co2); + } else { + VecSubf(vec, co2, co); + } + + VecAddf(start, start, vec); + + view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat); + view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat); + + if (ev == sv->down->v1) { + VecSubf(vec, co2, co); + } else { + VecSubf(vec, co, co2); + } + + VecAddf(end, end, vec); + + totvec += 1.0f; + nearest = (EditVert*)look->link; + } + } + + + + look = look->next; + } + + VecAddf(start, start, end); + VecMulf(start, 0.5*(1.0/totvec)); + VECCOPY(vec, start); + start[0] = t->mval[0]; + start[1] = t->mval[1]; + VecAddf(end, start, vec); + + sld->start[0] = (short) start[0]; + sld->start[1] = (short) start[1]; + sld->end[0] = (short) end[0]; + sld->end[1] = (short) end[1]; + + if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) { + int maxnum = 0; + + uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array"); + sld->totuv = uvlay_tot; + suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */ + suv = NULL; + + for (uvlay_idx=0; uvlay_idxverts.first;ev;ev=ev->next) { + ev->tmp.l = 0; + } + look = vertlist; + while(look) { + float *uv_new; + tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); + + ev = look->link; + suv = NULL; + for(efa = em->faces.first;efa;efa=efa->next) { + if (ev->tmp.l != -1) { /* test for self, in this case its invalid */ + int k=-1; /* face corner */ + + /* Is this vert in the faces corner? */ + if (efa->v1==ev) k=0; + else if (efa->v2==ev) k=1; + else if (efa->v3==ev) k=2; + else if (efa->v4 && efa->v4==ev) k=3; + + if (k != -1) { + MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx); + EditVert *ev_up, *ev_down; + + uv_new = tf->uv[k]; + + if (ev->tmp.l) { + if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) { + ev->tmp.l = -1; /* Tag as invalid */ + BLI_linklist_free(suv->fuv_list,NULL); + suv->fuv_list = NULL; + BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL); + suv = NULL; + break; + } + } else { + ev->tmp.l = 1; + suv = suv_last; + + suv->fuv_list = NULL; + suv->uv_up = suv->uv_down = NULL; + suv->origuv[0] = uv_new[0]; + suv->origuv[1] = uv_new[1]; + + BLI_linklist_prepend(&suv->fuv_list, uv_new); + BLI_ghash_insert(uvarray[uvlay_idx],ev,suv); + + suv_last++; /* advance to next slide UV */ + maxnum++; + } + + /* Now get the uvs along the up or down edge if we can */ + if (suv) { + if (!suv->uv_up) { + ev_up = editedge_getOtherVert(tempsv->up,ev); + if (efa->v1==ev_up) suv->uv_up = tf->uv[0]; + else if (efa->v2==ev_up) suv->uv_up = tf->uv[1]; + else if (efa->v3==ev_up) suv->uv_up = tf->uv[2]; + else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3]; + } + if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */ + ev_down = editedge_getOtherVert(tempsv->down,ev); + if (efa->v1==ev_down) suv->uv_down = tf->uv[0]; + else if (efa->v2==ev_down) suv->uv_down = tf->uv[1]; + else if (efa->v3==ev_down) suv->uv_down = tf->uv[2]; + else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3]; + } + + /* Copy the pointers to the face UV's */ + BLI_linklist_prepend(&suv->fuv_list, uv_new); + } + } + } + } + look = look->next; + } + } /* end uv layer loop */ + } /* end uvlay_tot */ + + sld->uvhash = uvarray; + sld->slideuv = slideuvs; + sld->vhash = vertgh; + sld->nearest = nearest; + sld->vertlist = vertlist; + sld->edgelist = edgelist; + sld->suv_last = suv_last; + sld->uvlay_tot = uvlay_tot; + + // we should have enough info now to slide + + t->customData = sld; + + return 1; +} + +void initEdgeSlide(TransInfo *t) +{ + SlideData *sld; + + t->mode = TFM_EDGE_SLIDE; + t->transform = EdgeSlide; + + createSlideVerts(t); + sld = t->customData; + + initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO); + setCustomPoints(t, &t->mouse, sld->end, sld->start); + + 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[2] = t->snap[1] * 0.2f; + + t->flag |= T_NO_CONSTRAINT; +} + +int doEdgeSlide(TransInfo *t, float perc) +{ + Mesh *me= t->obedit->data; + EditMesh *em = me->edit_mesh; + SlideData *sld = t->customData; + EditEdge *first=NULL,*last=NULL, *temp = NULL; + EditVert *ev, *nearest = sld->nearest; + EditVert *centerVert, *upVert, *downVert; + LinkNode *edgelist = sld->edgelist, *vertlist=sld->vertlist, *look; + GHash *vertgh = sld->vhash; + TransDataSlideVert *tempsv; + float shiftlabda= 0.0f,len = 0.0f; + int i = 0, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0; + int wasshift = 0; + /* UV correction vars */ + GHash **uvarray= sld->uvhash; + int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); + int uvlay_idx; + TransDataSlideUv *slideuvs=sld->slideuv, *suv=sld->slideuv, *suv_last=NULL; + float uv_tmp[2]; + LinkNode *fuv_link; + float labda = 0.0f; + + len = 0.0f; + + tempsv = BLI_ghash_lookup(vertgh,nearest); + + centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); + upVert = editedge_getOtherVert(tempsv->up, centerVert); + downVert = editedge_getOtherVert(tempsv->down, centerVert); + + len = MIN2(perc, VecLenf(upVert->co,downVert->co)); + len = MAX2(len, 0); + + //Adjust Edgeloop + if(prop) { + look = vertlist; + while(look) { + EditVert *tempev; + ev = look->link; + tempsv = BLI_ghash_lookup(vertgh,ev); + + tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev); + VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc)); + + if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { + for (uvlay_idx=0; uvlay_idxfuv_list && suv->uv_up && suv->uv_down) { + Vec2Lerpf(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc)); + fuv_link = suv->fuv_list; + while (fuv_link) { + VECCOPY2D(((float *)fuv_link->link), uv_tmp); + fuv_link = fuv_link->next; + } + } + } + } + + look = look->next; + } + } + else { + //Non prop code + look = vertlist; + while(look) { + float newlen; + ev = look->link; + tempsv = BLI_ghash_lookup(vertgh,ev); + newlen = (len / VecLenf(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co)); + if(newlen > 1.0) {newlen = 1.0;} + if(newlen < 0.0) {newlen = 0.0;} + if(flip == 0) { + VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen)); + if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { + /* dont do anything if no UVs */ + for (uvlay_idx=0; uvlay_idxfuv_list && suv->uv_up && suv->uv_down) { + Vec2Lerpf(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen)); + fuv_link = suv->fuv_list; + while (fuv_link) { + VECCOPY2D(((float *)fuv_link->link), uv_tmp); + fuv_link = fuv_link->next; + } + } + } + } + } else{ + VecLerpf(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen)); + + if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { + /* dont do anything if no UVs */ + for (uvlay_idx=0; uvlay_idxfuv_list && suv->uv_up && suv->uv_down) { + Vec2Lerpf(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen)); + fuv_link = suv->fuv_list; + while (fuv_link) { + VECCOPY2D(((float *)fuv_link->link), uv_tmp); + fuv_link = fuv_link->next; + } + } + } + } + } + look = look->next; + } + + } + + return 1; +} + +void freeSlideVerts(TransInfo *t) +{ + TransDataSlideUv *suv; + SlideData *sld = t->customData; + int uvlay_idx; + + //BLI_ghash_free(edgesgh, freeGHash, NULL); + BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(sld->vertlist, NULL); + BLI_linklist_free(sld->edgelist, NULL); + + if (sld->uvlay_tot) { + for (uvlay_idx=0; uvlay_idxuvlay_tot; uvlay_idx++) { + BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL); + } + MEM_freeN(sld->slideuv); + MEM_freeN(sld->uvhash); + + suv = sld->suv_last-1; + while (suv >= sld->slideuv) { + if (suv->fuv_list) { + BLI_linklist_free(suv->fuv_list,NULL); + } + suv--; + } + } + + MEM_freeN(sld); +} + +int EdgeSlide(TransInfo *t, short mval[2]) +{ + TransData *td = t->data; + char str[50]; + float final; + + final = t->values[0]; + + snapGrid(t, &final); + + if (hasNumInput(&t->num)) { + char c[20]; + + applyNumInput(&t->num, &final); + + outputNumInput(&(t->num), c); + + sprintf(str, "Edge Slide Percent: %s", &c[0]); + } + else { + sprintf(str, "Edge Slide Percent: %.2f", final); + } + + CLAMP(final, -1.0f, 1.0f); + + /*do stuff here*/ + doEdgeSlide(t, final); + + recalcData(t); + + ED_area_headerprint(t->sa, str); + + return 1; +} /* ******************** EditBone roll *************** */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 2ff6d6d3dce..404257a55ff 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -32,6 +32,8 @@ #include "ED_transform.h" +#include "BLI_editVert.h" + /* ************************** Types ***************************** */ struct TransInfo; @@ -179,6 +181,31 @@ typedef struct TransDataNla { int handle; /* handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends */ } TransDataNla; +struct LinkNode; +struct EditEdge; +struct EditVert; +struct GHash; +typedef struct TransDataSlideUv { + float origuv[2]; + float *uv_up, *uv_down; + //float *fuv[4]; + struct LinkNode *fuv_list; +} TransDataSlideUv; + +typedef struct TransDataSlideVert { + struct EditEdge *up, *down; + struct EditVert origvert; +} TransDataSlideVert; + +typedef struct SlideData { + TransDataSlideUv *slideuv, *suv_last; + int totuv, uvlay_tot; + struct GHash *vhash, **uvhash; + struct EditVert *nearest; + struct LinkNode *edgelist, *vertlist; + short start[2], end[2]; +} SlideData; + typedef struct TransData { float dist; /* Distance needed to affect element (for Proportionnal Editing) */ float rdist; /* Distance to the nearest element (for Proportionnal Editing) */ @@ -467,6 +494,9 @@ int BoneEnvelope(TransInfo *t, short mval[2]); void initBoneRoll(TransInfo *t); int BoneRoll(TransInfo *t, short mval[2]); +void initEdgeSlide(TransInfo *t); +int EdgeSlide(TransInfo *t, short mval[2]); + void initTimeTranslate(TransInfo *t); int TimeTranslate(TransInfo *t, short mval[2]); @@ -667,6 +697,8 @@ int getTransformOrientation(const struct bContext *C, float normal[3], float pla int createSpaceNormal(float mat[3][3], float normal[3]); int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); +void freeSlideVerts(TransInfo *t); + #endif diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index d93e92616e1..59429d65e7b 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1073,6 +1073,10 @@ void postTrans (TransInfo *t) { MEM_freeN(t->mouse.data); } + + if (t->mode == TFM_EDGE_SLIDE) { + freeSlideVerts(t); + } } void applyTransObjects(TransInfo *t) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 4bf0e44de7f..69819da8cc2 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -578,6 +578,7 @@ void TFM_OT_transform(struct wmOperatorType *ot) {TFM_BEVEL, "BEVEL", 0, "Bevel", ""}, {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""}, {TFM_ALIGN, "ALIGN", 0, "Align", ""}, + {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""}, {0, NULL, 0, NULL, NULL} }; -- cgit v1.2.3 From cea8e6b6ed834c2607c44a65fe46c5204edad7fd Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 22 Sep 2009 08:57:00 +0000 Subject: * ensure mingw toolset is recognised properly for python debug when doing BF_DEBUG=1 --- tools/Blender.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Blender.py b/tools/Blender.py index fd6272c7c32..1b0573cfda4 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -171,7 +171,7 @@ def setup_syslibs(lenv): syslibs += Split(lenv['BF_FREETYPE_LIB']) if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']: - if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'): syslibs.append(lenv['BF_PYTHON_LIB']+'_d') else: syslibs.append(lenv['BF_PYTHON_LIB']) -- cgit v1.2.3 From 3c8d34b94e8c615c0349a01e3ea5e6381feaeefa Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 22 Sep 2009 09:04:43 +0000 Subject: fixed a crash in edge slide --- source/blender/editors/transform/transform.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 8f3fcfedd18..7e381b24186 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4508,6 +4508,9 @@ void initEdgeSlide(TransInfo *t) createSlideVerts(t); sld = t->customData; + if (!sld) + return; + initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO); setCustomPoints(t, &t->mouse, sld->end, sld->start); -- cgit v1.2.3 From 92145d5950b3c069418a097055cc8ae0e5710423 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 22 Sep 2009 09:12:39 +0000 Subject: Changes to allow python to do redraws through the timer operator, a reliable way to test the overhead of the python api (printed to the consoel on exit). - rename WM_OT_ten_timer to WM_OT_redraw_timer - added iterations argument to run more then 10 times (10 is default still) - use report api rather then always calling a popup directly. - added a new test that draws every region without swapping. - dont show the info popup when operators are called from python. - operators called from python now print reports, useful with the interactive console. eg. >>> bpy.ops.wm.redraw_timer(type='DRAW_WIN', iterations=300) Info: 300 x Draw Window: 4168.56 ms, average: 13.8952 --- source/blender/blenkernel/intern/report.c | 2 +- source/blender/makesrna/intern/rna_sequence.c | 1 + source/blender/python/intern/bpy_operator.c | 10 +++ .../blender/windowmanager/intern/wm_event_system.c | 4 +- source/blender/windowmanager/intern/wm_operators.c | 75 +++++++++++++++------- 5 files changed, 66 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 391adfb762a..e524359d2bc 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -230,7 +230,7 @@ char *BKE_reports_string(ReportList *reports, ReportType level) DynStr *ds; char *cstring; - if(!reports) + if(!reports || !reports->list.first) return NULL; ds= BLI_dynstr_new(); diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index b1ac02ae17f..51e81d6dd3a 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -520,6 +520,7 @@ static void rna_def_sequence(BlenderRNA *brna) prop= RNA_def_property(srna, "channel", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "machine"); + RNA_def_property_range(prop, 0, MAXSEQ-1); RNA_def_property_ui_text(prop, "Channel", "Y position of the sequence strip."); RNA_def_property_int_funcs(prop, NULL, "rna_SequenceEditor_channel_set",NULL); // overlap test RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, NULL); diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index f2e2dd77e6d..301204d3e2b 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -89,6 +89,16 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) if(BPy_reports_to_error(reports)) error_val = -1; + /* operator output is nice to have in the terminal/console too */ + if(reports->list.first) { + char *report_str= BKE_reports_string(reports, 0); /* all reports */ + + if(report_str) { + PySys_WriteStdout(report_str); + MEM_freeN(report_str); + } + } + BKE_reports_clear(reports); if ((reports->flag & RPT_FREE) == 0) { diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 503eb5a1b9a..03e13329bbd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -415,7 +415,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P else printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */ - if(!(retval & OPERATOR_RUNNING_MODAL)) { + /* Note, if the report is given as an argument then assume the caller will deal with displaying them + * currently python only uses this */ + if(!(retval & OPERATOR_RUNNING_MODAL) && reports==NULL) { if(op->reports->list.first) /* only show the report if the report list was not given in the function */ uiPupMenuReports(C, op->reports); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 76c15043b89..0b5c2944624 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1979,17 +1979,19 @@ void WM_OT_radial_control_partial(wmOperatorType *ot) /* uses no type defines, fully local testing function anyway... ;) */ -static int ten_timer_exec(bContext *C, wmOperator *op) +static int redraw_timer_exec(bContext *C, wmOperator *op) { ARegion *ar= CTX_wm_region(C); double stime= PIL_check_seconds_timer(); int type = RNA_int_get(op->ptr, "type"); - int a, time; - char tmpstr[128]; + int iter = RNA_int_get(op->ptr, "iterations"); + int a; + float time; + char *infostr= ""; WM_cursor_wait(1); - - for(a=0; a<10; a++) { + + for(a=0; aareabase.first; sa; sa= sa->next) { + ARegion *ar_iter; + CTX_wm_area_set(C, sa); + + for(ar_iter= sa->regionbase.first; ar_iter; ar_iter= ar_iter->next) { + CTX_wm_region_set(C, ar_iter); + ED_region_do_draw(C, ar_iter); + } + } + + CTX_wm_window_set(C, win); /* XXX context manipulation warning! */ + + CTX_wm_area_set(C, sa_back); + CTX_wm_region_set(C, ar_back); + } + else if (type==3) { + wmWindow *win= CTX_wm_window(C); + ScrArea *sa; + for(sa= CTX_wm_screen(C)->areabase.first; sa; sa= sa->next) ED_area_tag_redraw(sa); wm_draw_update(C); CTX_wm_window_set(C, win); /* XXX context manipulation warning! */ } - else if (type==3) { + else if (type==4) { Scene *scene= CTX_data_scene(C); if(a & 1) scene->r.cfra--; @@ -2024,40 +2048,43 @@ static int ten_timer_exec(bContext *C, wmOperator *op) } } - time= (int) ((PIL_check_seconds_timer()-stime)*1000); + time= ((PIL_check_seconds_timer()-stime)*1000); - if(type==0) sprintf(tmpstr, "10 x Draw Region: %d ms", time); - if(type==1) sprintf(tmpstr, "10 x Draw Region and Swap: %d ms", time); - if(type==2) sprintf(tmpstr, "10 x Draw Window and Swap: %d ms", time); - if(type==3) sprintf(tmpstr, "Anim Step: %d ms", time); - if(type==4) sprintf(tmpstr, "10 x Undo/Redo: %d ms", time); + if(type==0) infostr= "Draw Region"; + if(type==1) infostr= "Draw Region and Swap"; + if(type==2) infostr= "Draw Window"; + if(type==3) infostr= "Draw Window and Swap"; + if(type==4) infostr= "Animation Steps"; + if(type==5) infostr= "Undo/Redo"; WM_cursor_wait(0); - uiPupMenuNotice(C, tmpstr); + BKE_reportf(op->reports, RPT_INFO, "%d x %s: %.2f ms, average: %.4f", iter, infostr, time, time/iter); return OPERATOR_FINISHED; } -static void WM_OT_ten_timer(wmOperatorType *ot) +static void WM_OT_redraw_timer(wmOperatorType *ot) { static EnumPropertyItem prop_type_items[] = { {0, "DRAW", 0, "Draw Region", ""}, - {1, "DRAWSWAP", 0, "Draw Region + Swap", ""}, - {2, "DRAWWINSWAP", 0, "Draw Window + Swap", ""}, - {3, "ANIMSTEP", 0, "Anim Step", ""}, - {4, "UNDO", 0, "Undo/Redo", ""}, + {1, "DRAW_SWAP", 0, "Draw Region + Swap", ""}, + {2, "DRAW_WIN", 0, "Draw Window", ""}, + {3, "DRAW_WIN_SWAP", 0, "Draw Window + Swap", ""}, + {4, "ANIM_STEP", 0, "Anim Step", ""}, + {5, "UNDO", 0, "Undo/Redo", ""}, {0, NULL, 0, NULL, NULL}}; - ot->name= "Ten Timer"; - ot->idname= "WM_OT_ten_timer"; - ot->description="Ten Timer operator."; + ot->name= "Redraw Timer"; + ot->idname= "WM_OT_redraw_timer"; + ot->description="Simple redraw timer to test the speed of updating the interface."; ot->invoke= WM_menu_invoke; - ot->exec= ten_timer_exec; + ot->exec= redraw_timer_exec; ot->poll= WM_operator_winactive; RNA_def_enum(ot->srna, "type", prop_type_items, 0, "Type", ""); + RNA_def_int(ot->srna, "iterations", 10, 1,INT_MAX, "Iterations", "Number of times to redraw", 1,1000); } @@ -2092,7 +2119,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_jobs_timer); WM_operatortype_append(WM_OT_save_as_mainfile); WM_operatortype_append(WM_OT_save_mainfile); - WM_operatortype_append(WM_OT_ten_timer); + WM_operatortype_append(WM_OT_redraw_timer); WM_operatortype_append(WM_OT_debug_menu); WM_operatortype_append(WM_OT_search_menu); } @@ -2127,7 +2154,7 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); /* debug/testing */ - WM_keymap_verify_item(keymap, "WM_OT_ten_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); + WM_keymap_verify_item(keymap, "WM_OT_redraw_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0); -- cgit v1.2.3 From 87f5f194bcf8a4bb8a22b8402d8bb088084d6489 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 22 Sep 2009 11:45:30 +0000 Subject: 2.5 - Animation Tweaks * delta-transforms for objects should work again. These were basically extra transforms that could get added on top of the values calculated from animation values. * Added some skeleton code for fixing paths when some data needs to be renamed. --- source/blender/blenkernel/intern/anim_sys.c | 103 +++++++++++++++++++++++++--- source/blender/blenkernel/intern/object.c | 53 +++++--------- 2 files changed, 112 insertions(+), 44 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index af4bcd8b0f7..ca16c62436b 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -211,25 +211,110 @@ static void make_local_strips(ListBase *strips) { NlaStrip *strip; - for(strip=strips->first; strip; strip=strip->next) { - if(strip->act) make_local_action(strip->act); - if(strip->remap && strip->remap->target) make_local_action(strip->remap->target); - + for (strip=strips->first; strip; strip=strip->next) { + if (strip->act) make_local_action(strip->act); + //if (strip->remap && strip->remap->target) make_local_action(strip->remap->target); + make_local_strips(&strip->strips); } } +/* Use local copy instead of linked copy of various ID-blocks */ void BKE_animdata_make_local(AnimData *adt) { NlaTrack *nlt; + + /* Actions - Active and Temp */ + if (adt->action) make_local_action(adt->action); + if (adt->tmpact) make_local_action(adt->tmpact); + /* Remaps */ + if (adt->remap && adt->remap->target) make_local_action(adt->remap->target); + + /* Drivers */ + // TODO: need to remap the ID-targets too? + + /* NLA Data */ + for (nlt=adt->nla_tracks.first; nlt; nlt=nlt->next) + make_local_strips(&nlt->strips); +} - if(adt->action) make_local_action(adt->action); - if(adt->tmpact) make_local_action(adt->tmpact); - if(adt->remap && adt->remap->target) make_local_action(adt->remap->target); +/* Path Validation -------------------------------------------- */ - for(nlt=adt->nla_tracks.first; nlt; nlt=nlt->next) - make_local_strips(&nlt->strips); +#if 0 +/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */ +static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath) +{ + return oldpath; // FIXME!!! +} + +/* Check RNA-Paths for a list of F-Curves */ +static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *curves) +{ + FCurve *fcu; + + /* we need to check every curve... */ + for (fcu= curves->first; fcu; fcu= fcu->next) { + /* firstly, handle the F-Curve's own path */ + fcu->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, fcu->rna_path); + + /* driver? */ + if (fcu->driver) { + ChannelDriver *driver= fcu->driver; + DriverTarget *dtar; + + /* driver targets */ + for (dtar= driver->targets.first; dtar; dtar=dtar->next) { + dtat->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, dtar->rna_path); + } + } + } +} + +/* Fix all RNA-Paths for Actions linked to NLA Strips */ +static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *strips) +{ + NlaStrip *strip; + + /* recursively check strips, fixing only actions... */ + for (strip= strips->first; strip; strip= strip->next) { + /* fix strip's action */ + if (strip->act) + fcurves_path_rename_fix(owner_id, modPtr, newName, &strip->act->curves); + /* ignore own F-Curves, since those are local... */ + + /* check sub-strips (if metas) */ + nlastrips_path_rename_fix(owner_id, modPtr, newName, &strip->strips); + } +} + +/* Fix all RNA-Paths in the AnimData block used by the given ID block + * - the pointer of interest must not have had its new name assigned already, otherwise + * path matching for this will never work + */ +void BKE_animdata_fix_paths_rename (ID *owner_id, PointerRNA *modPtr, char *newName) +{ + AnimData *adt= BKE_animdata_from_id(owner_id); + NlaTrack *nlt; + + /* if no AnimData, no need to proceed */ + if (ELEM4(NULL, owner_id, adt, modPtr, newName)) + return; + + /* Active action and temp action */ + if (adt->action) + fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->action->curves); + if (adt->tmpact) + fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->tmpact->curves); + + /* Drivers - Drivers are really F-Curves */ + fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->drivers); + + /* NLA Data - Animation Data for Strips */ + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + + } } +#endif /* *********************************** */ /* KeyingSet API */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 35514e9697e..c98e2d5970b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1553,13 +1553,11 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs) cfra+= bluroffs+fieldoffs; /* global time */ - cfra*= scene->r.framelen; + if (scene) + cfra*= scene->r.framelen; #if 0 // XXX old animation system if (ob) { - if (no_speed_curve==0 && ob->ipo) - cfra= calc_ipo_time(ob->ipo, cfra); - /* ofset frames */ if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0) cfra-= give_timeoffset(ob); @@ -1574,29 +1572,22 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs) void object_scale_to_mat3(Object *ob, float mat[][3]) { float vec[3]; - if(ob->ipo) { - vec[0]= ob->size[0]+ob->dsize[0]; - vec[1]= ob->size[1]+ob->dsize[1]; - vec[2]= ob->size[2]+ob->dsize[2]; - SizeToMat3(vec, mat); - } - else { - SizeToMat3(ob->size, mat); - } + + vec[0]= ob->size[0]+ob->dsize[0]; + vec[1]= ob->size[1]+ob->dsize[1]; + vec[2]= ob->size[2]+ob->dsize[2]; + SizeToMat3(vec, mat); } +// TODO: this should take rotation orders into account later... void object_rot_to_mat3(Object *ob, float mat[][3]) { float vec[3]; - if(ob->ipo) { - vec[0]= ob->rot[0]+ob->drot[0]; - vec[1]= ob->rot[1]+ob->drot[1]; - vec[2]= ob->rot[2]+ob->drot[2]; - EulToMat3(vec, mat); - } - else { - EulToMat3(ob->rot, mat); - } + + vec[0]= ob->rot[0]+ob->drot[0]; + vec[1]= ob->rot[1]+ob->drot[1]; + vec[2]= ob->rot[2]+ob->drot[2]; + EulToMat3(vec, mat); } void object_to_mat3(Object *ob, float mat[][3]) /* no parent */ @@ -1611,13 +1602,8 @@ void object_to_mat3(Object *ob, float mat[][3]) /* no parent */ /* rot */ /* Quats arnt used yet */ /*if(ob->transflag & OB_QUAT) { - if(ob->ipo) { - QuatMul(q1, ob->quat, ob->dquat); - QuatToMat3(q1, rmat); - } - else { - QuatToMat3(ob->quat, rmat); - } + QuatMul(q1, ob->quat, ob->dquat); + QuatToMat3(q1, rmat); } else {*/ object_rot_to_mat3(ob, rmat); @@ -1633,12 +1619,9 @@ void object_to_mat4(Object *ob, float mat[][4]) Mat4CpyMat3(mat, tmat); - VECCOPY(mat[3], ob->loc); - if(ob->ipo) { - mat[3][0]+= ob->dloc[0]; - mat[3][1]+= ob->dloc[1]; - mat[3][2]+= ob->dloc[2]; - } + mat[3][0]= ob->loc[0] + ob->dloc[0]; + mat[3][1]= ob->loc[1] + ob->dloc[1]; + mat[3][2]= ob->loc[2] + ob->dloc[2]; } int enable_cu_speed= 1; -- cgit v1.2.3 From d86864027d449114868ec531b9ccf6dd19dbe67f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 22 Sep 2009 16:23:46 +0000 Subject: PyConsole improvements - Commands from the history wont get modified in-place when you cycle back and re-use them. - Ctrl Left/Right skip words. - Autocompletion on a variable that has no alternatives adds a '.' 'bpy' -> 'bpy.', generally more useful since autocomp again will give the members of bpy also moved text_check_* functions into BKE_text.h for the console to access. --- release/ui/space_console.py | 12 ++- source/blender/blenkernel/BKE_text.h | 8 ++ source/blender/blenkernel/intern/text.c | 57 +++++++++++++ source/blender/editors/space_console/console_ops.c | 99 +++++++++++++++++++++- .../blender/editors/space_console/space_console.c | 8 +- source/blender/editors/space_text/text_draw.c | 54 ------------ 6 files changed, 173 insertions(+), 65 deletions(-) diff --git a/release/ui/space_console.py b/release/ui/space_console.py index 980c11b706a..4641d7900cb 100644 --- a/release/ui/space_console.py +++ b/release/ui/space_console.py @@ -246,11 +246,17 @@ def autocomp(bcon): break else: autocomp_prefix_ret += char_soup.pop() - - print(autocomp_prefix_ret) + return autocomp_prefix_ret, autocomp_members elif len(autocomp_members) == 1: - return autocomp_members[0][len(autocomp_prefix):], [] + if autocomp_prefix == autocomp_members[0]: + # the variable matched the prefix exactly + # add a '.' so you can quickly continue. + # Could try add [] or other possible extensions rather then '.' too if we had the variable. + return '.', [] + else: + # finish off the of the word word + return autocomp_members[0][len(autocomp_prefix):], [] else: return '', [] diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index 07e05756ea3..185e32ecdfa 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -104,6 +104,14 @@ struct TextMarker *txt_next_marker (struct Text *text, struct TextMarker *marke struct TextMarker *txt_prev_marker_color (struct Text *text, struct TextMarker *marker); struct TextMarker *txt_next_marker_color (struct Text *text, struct TextMarker *marker); +/* utility functions, could be moved somewhere more generic but are python/text related */ +int text_check_bracket(char ch); +int text_check_delim(char ch); +int text_check_digit(char ch); +int text_check_identifier(char ch); +int text_check_whitespace(char ch); + + /* Undo opcodes */ /* Simple main cursor movement */ diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 270cd873ff5..8bf0f6b8bdf 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -2832,3 +2832,60 @@ TextMarker *txt_next_marker(Text *text, TextMarker *marker) { } return NULL; /* Only if marker==NULL */ } + + +/*******************************/ +/* Character utility functions */ +/*******************************/ + +int text_check_bracket(char ch) +{ + int a; + char opens[] = "([{"; + char close[] = ")]}"; + + for(a=0; a<(sizeof(opens)-1); a++) { + if(ch==opens[a]) + return a+1; + else if(ch==close[a]) + return -(a+1); + } + return 0; +} + +int text_check_delim(char ch) +{ + int a; + char delims[] = "():\"\' ~!%^&*-+=[]{};/<>|.#\t,"; + + for(a=0; a<(sizeof(delims)-1); a++) { + if(ch==delims[a]) + return 1; + } + return 0; +} + +int text_check_digit(char ch) +{ + if(ch < '0') return 0; + if(ch <= '9') return 1; + return 0; +} + +int text_check_identifier(char ch) +{ + if(ch < '0') return 0; + if(ch <= '9') return 1; + if(ch < 'A') return 0; + if(ch <= 'Z' || ch == '_') return 1; + if(ch < 'a') return 0; + if(ch <= 'z') return 1; + return 0; +} + +int text_check_whitespace(char ch) +{ + if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') + return 1; + return 0; +} diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 2120b97becf..ccf7dbff946 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -51,6 +51,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_report.h" +#include "BKE_text.h" /* only for character utility funcs */ #include "WM_api.h" #include "WM_types.h" @@ -119,6 +120,48 @@ static int console_line_cursor_set(ConsoleLine *cl, int cursor) return 1; } +static char cursor_char(ConsoleLine *cl) +{ + /* assume cursor is clamped */ + return cl->line[cl->cursor]; +} + +static char cursor_char_prev(ConsoleLine *cl) +{ + /* assume cursor is clamped */ + if(cl->cursor <= 0) + return '\0'; + + return cl->line[cl->cursor-1]; +} + +static char cursor_char_next(ConsoleLine *cl) +{ + /* assume cursor is clamped */ + if(cl->cursor + 1 >= cl->len) + return '\0'; + + return cl->line[cl->cursor+1]; +} + +static void console_lb_debug__internal(ListBase *lb) +{ + ConsoleLine *cl; + + printf("%d: ", BLI_countlist(lb)); + for(cl= lb->first; cl; cl= cl->next) + printf("<%s> ", cl->line); + printf("\n"); + +} + +static void console_history_debug(const bContext *C) +{ + SpaceConsole *sc= CTX_wm_space_console(C); + + console_lb_debug__internal(&sc->history); +} + static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from) { ConsoleLine *ci= MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add"); @@ -251,7 +294,7 @@ static EnumPropertyItem move_type_items[]= { {PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""}, {NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""}, {0, NULL, 0, NULL, NULL}}; - + static int move_exec(bContext *C, wmOperator *op) { ConsoleLine *ci= console_history_verify(C); @@ -272,6 +315,37 @@ static int move_exec(bContext *C, wmOperator *op) case NEXT_CHAR: done= console_line_cursor_set(ci, ci->cursor+1); break; + + /* - if the character is a delimiter then skip delimiters (including white space) + * - when jump over the word */ + case PREV_WORD: + while(text_check_delim(cursor_char_prev(ci))) + if(console_line_cursor_set(ci, ci->cursor-1)==FALSE) + break; + + while(text_check_delim(cursor_char_prev(ci))==FALSE) + if(console_line_cursor_set(ci, ci->cursor-1)==FALSE) + break; + + /* This isnt used for NEXT_WORD because when going back + * its more useful to have the cursor directly after a word then whitespace */ + while(text_check_whitespace(cursor_char_prev(ci))==TRUE) + if(console_line_cursor_set(ci, ci->cursor-1)==FALSE) + break; + + done= 1; /* assume changed */ + break; + case NEXT_WORD: + while(text_check_delim(cursor_char(ci))==TRUE) + if (console_line_cursor_set(ci, ci->cursor+1)==FALSE) + break; + + while(text_check_delim(cursor_char(ci))==FALSE) + if (console_line_cursor_set(ci, ci->cursor+1)==FALSE) + break; + + done= 1; /* assume changed */ + break; } if(done) { @@ -466,7 +540,16 @@ static int history_cycle_exec(bContext *C, wmOperator *op) ConsoleLine *ci= console_history_verify(C); /* TODO - stupid, just prevernts crashes when no command line */ short reverse= RNA_boolean_get(op->ptr, "reverse"); /* assumes down, reverse is up */ - + + /* keep a copy of the line above so when history is cycled + * this is the only function that needs to know about the double-up */ + if(ci->prev) { + ConsoleLine *ci_prev= (ConsoleLine *)ci->prev; + + if(strcmp(ci->line, ci_prev->line)==0) + console_history_free(sc, ci_prev); + } + if(reverse) { /* last item in mistory */ ci= sc->history.last; BLI_remlink(&sc->history, ci); @@ -477,9 +560,17 @@ static int history_cycle_exec(bContext *C, wmOperator *op) BLI_remlink(&sc->history, ci); BLI_addtail(&sc->history, ci); } - + + { /* add a duplicate of the new arg and remove all other instances */ + ConsoleLine *cl; + while((cl= console_history_find(sc, ci->line, ci))) + console_history_free(sc, cl); + + console_history_add(C, (ConsoleLine *)sc->history.last); + } + ED_area_tag_redraw(CTX_wm_area(C)); - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 6526b569bbb..234f3b5baf2 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -233,13 +233,13 @@ void console_keymap(struct wmWindowManager *wm) { wmKeyMap *keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0); - #ifdef __APPLE__ +#ifdef __APPLE__ RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END); - #endif +#endif - RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_BEGIN); - RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN); RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 9721fbc2b9c..5996770c206 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -425,60 +425,6 @@ static void format_draw_color(char formatchar) } } -/*********************** utilities ************************/ - -int text_check_bracket(char ch) -{ - int a; - char opens[] = "([{"; - char close[] = ")]}"; - - for(a=0; a<3; a++) { - if(ch==opens[a]) - return a+1; - else if(ch==close[a]) - return -(a+1); - } - return 0; -} - -int text_check_delim(char ch) -{ - int a; - char delims[] = "():\"\' ~!%^&*-+=[]{};/<>|.#\t,"; - - for(a=0; a<28; a++) { - if(ch==delims[a]) - return 1; - } - return 0; -} - -int text_check_digit(char ch) -{ - if(ch < '0') return 0; - if(ch <= '9') return 1; - return 0; -} - -int text_check_identifier(char ch) -{ - if(ch < '0') return 0; - if(ch <= '9') return 1; - if(ch < 'A') return 0; - if(ch <= 'Z' || ch == '_') return 1; - if(ch < 'a') return 0; - if(ch <= 'z') return 1; - return 0; -} - -int text_check_whitespace(char ch) -{ - if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') - return 1; - return 0; -} - /************************** draw text *****************************/ /***********************/ /* -- cgit v1.2.3 From b4ef0c7d8d9b4197d209193743e76099cf042ec7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 22 Sep 2009 17:50:29 +0000 Subject: minor fixes for merge of soc-2009-kazanbas, rev23422 - Use CTX_data_main(C) over G.main - no need to define object_type_items inline. - rna_mesh.c - dynamic length array was commented out, not sure why this was needed. Povray and PLY scripts rely on faces having 3/4 verts rather then checking the 4th index is 0 (ok in C, not nice in py). --- source/blender/editors/mesh/editmesh_tools.c | 1 + source/blender/makesrna/intern/rna_main_api.c | 16 +--------------- source/blender/makesrna/intern/rna_mesh.c | 4 +--- source/blender/makesrna/intern/rna_object_api.c | 5 ++++- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 2c20e4a147c..26bee09c925 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4679,6 +4679,7 @@ int EdgeLoopDelete(EditMesh *em, wmOperator *op) // DAG_id_flush_update(obedit->data, OB_RECALC_DATA); return 1; #endif + return 0; } diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 9d42c473f50..379cf75d450 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -31,6 +31,7 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "DNA_object_types.h" #include "DNA_material_types.h" @@ -135,21 +136,6 @@ void RNA_api_main(StructRNA *srna) FunctionRNA *func; PropertyRNA *parm; - /* copied from rna_def_object */ - static EnumPropertyItem object_type_items[] = { - {OB_EMPTY, "EMPTY", 0, "Empty", ""}, - {OB_MESH, "MESH", 0, "Mesh", ""}, - {OB_CURVE, "CURVE", 0, "Curve", ""}, - {OB_SURF, "SURFACE", 0, "Surface", ""}, - {OB_FONT, "TEXT", 0, "Text", ""}, - {OB_MBALL, "META", 0, "Meta", ""}, - {OB_LAMP, "LAMP", 0, "Lamp", ""}, - {OB_CAMERA, "CAMERA", 0, "Camera", ""}, - {OB_WAVE, "WAVE", 0, "Wave", ""}, - {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, - {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, - {0, NULL, 0, NULL, NULL}}; - func= RNA_def_function(srna, "add_object", "rna_Main_add_object"); RNA_def_function_ui_description(func, "Add a new object."); parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object."); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index cfc1e017f3c..ecfe59a0142 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -978,13 +978,11 @@ static void rna_def_mface(BlenderRNA *brna) // XXX allows creating invalid meshes prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "v1"); RNA_def_property_array(prop, 4); - /* RNA_def_property_flag(prop, PROP_DYNAMIC); RNA_def_property_dynamic_array_funcs(prop, "rna_MeshFace_verts_get_length"); RNA_def_property_int_funcs(prop, "rna_MeshFace_verts_get", "rna_MeshFace_verts_set", NULL); - */ + RNA_def_property_ui_text(prop, "Vertices", "Vertex indices"); prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index f809868c130..af6254a99b0 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -114,7 +114,7 @@ static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports /* nurbs_to_mesh changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { - free_libblock_us( &G.main->object, tmpobj ); + free_libblock_us( &(CTX_data_main(C)->object), tmpobj ); BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); return NULL; } @@ -125,6 +125,9 @@ static Mesh *rna_Object_create_mesh(Object *ob, bContext *C, ReportList *reports case OB_MBALL: /* metaballs don't have modifiers, so just convert to mesh */ ob = find_basis_mball( sce, ob ); + /* todo, re-generatre for render-res */ + /* metaball_polygonize(scene, ob) */ + tmpmesh = add_mesh("Mesh"); mball_to_mesh( &ob->disp, tmpmesh ); break; -- cgit v1.2.3 From a2b3650e926814b5a8b8ce08a69ab7edda6e83ea Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 22 Sep 2009 18:47:28 +0000 Subject: fixed some edge slide issues --- 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 7e381b24186..6dec51945ce 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4340,6 +4340,8 @@ static int createSlideVerts(TransInfo *t) if(sv) { float co[3], co2[3], vec[3]; + ev = (EditVert*)look->link; + if(!sharesFace(em, tempsv->up,sv->up)) { EditEdge *swap; swap = sv->up; @@ -4350,7 +4352,7 @@ static int createSlideVerts(TransInfo *t) view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat); view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat); - if (ev == sv->up->v1) { + if (ev == tempsv->up->v1) { VecSubf(vec, co, co2); } else { VecSubf(vec, co2, co); @@ -4361,7 +4363,7 @@ static int createSlideVerts(TransInfo *t) view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat); view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat); - if (ev == sv->down->v1) { + if (ev == tempsv->down->v1) { VecSubf(vec, co2, co); } else { VecSubf(vec, co, co2); -- cgit v1.2.3 From 986f8a9ea34e8c994ae1e19fa47f49e7e0c544e6 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 22 Sep 2009 19:09:04 +0000 Subject: SVN maintenance. --- intern/guardedalloc/MEM_guardedalloc.h | 2 -- release/io/export_x3d.py | 2 +- source/blender/editors/armature/poseSlide.c | 2 +- source/blender/makesdna/DNA_windowmanager_types.h | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index 1d4c753802b..9e3927314d3 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -27,8 +27,6 @@ */ /** - - * $Id$ * Copyright (C) 2001 NaN Technologies B.V. * Guarded memory (de)allocation * diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py index 3e89a5202de..3661d78a343 100644 --- a/release/io/export_x3d.py +++ b/release/io/export_x3d.py @@ -25,7 +25,7 @@ Known issues:
""" -# $Id: export_x3d.py 23222 2009-09-14 14:55:49Z kazanbas $ +# $Id$ # #------------------------------------------------------------------------ # X3D exporter for blender 2.36 or above diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 353503967ec..24bd2ebe5ad 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -1,5 +1,5 @@ /** - * $Id: poseSlide.c 23179 2009-09-13 12:34:00Z aligorith $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index f1ce3491d0a..ea9d0e86c38 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -1,5 +1,5 @@ /** - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 930542540ade1ac181c1fbff2ca8f23715d377fb Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 22 Sep 2009 20:16:56 +0000 Subject: Make edge slide a proper operator Clean up a couple of things in transform (PET settings, custom data, ...) --- source/blender/editors/mesh/mesh_ops.c | 2 +- source/blender/editors/transform/transform.c | 72 ++++++++++-------- source/blender/editors/transform/transform.h | 1 + .../editors/transform/transform_conversions.c | 2 + .../blender/editors/transform/transform_generics.c | 86 ++++++++++++---------- source/blender/editors/transform/transform_ops.c | 23 ++++++ 6 files changed, 115 insertions(+), 71 deletions(-) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 3f1bbbb9097..a79b42dcbb8 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -113,7 +113,7 @@ static int edge_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) uiItemEnumO(layout, "Rotate Edge CCW", 0, "MESH_OT_edge_rotate", "direction", 2); //uiItemO(layout, "Loopcut", 0, "MESH_OT_loop_cut"); // CutEdgeloop(em, 1); //uiItemO(layout, "Edge Slide", 0, "MESH_OT_edge_slide"); // EdgeSlide(em, 0,0.0); - uiItemEnumO(layout, "Edge Slide", 0, "TFM_OT_transform", "mode", TFM_EDGE_SLIDE); + uiItemO(layout, "Edge Slide", 0, "TFM_OT_edge_slide"); uiItemO(layout, "Edge Loop", 0, "MESH_OT_loop_multi_select"); uiItemBooleanO(layout, "Edge Ring", 0, "MESH_OT_loop_multi_select", "ring", 1); uiItemO(layout, NULL, 0, "MESH_OT_loop_to_region"); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6dec51945ce..ca9981bc590 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1321,7 +1321,12 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) if (t->flag & T_MODAL) { ts->prop_mode = t->prop_mode; - ts->proportional = proportional; + + /* only save back if it wasn't automatically disabled */ + if ((t->options & CTX_NO_PET) == 0) + { + ts->proportional = proportional; + } if(t->spacetype == SPACE_VIEW3D) { @@ -4500,19 +4505,52 @@ static int createSlideVerts(TransInfo *t) return 1; } +void freeSlideVerts(TransInfo *t) +{ + TransDataSlideUv *suv; + SlideData *sld = t->customData; + int uvlay_idx; + + //BLI_ghash_free(edgesgh, freeGHash, NULL); + BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(sld->vertlist, NULL); + BLI_linklist_free(sld->edgelist, NULL); + + if (sld->uvlay_tot) { + for (uvlay_idx=0; uvlay_idxuvlay_tot; uvlay_idx++) { + BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL); + } + MEM_freeN(sld->slideuv); + MEM_freeN(sld->uvhash); + + suv = sld->suv_last-1; + while (suv >= sld->slideuv) { + if (suv->fuv_list) { + BLI_linklist_free(suv->fuv_list,NULL); + } + suv--; + } + } + + MEM_freeN(sld); + t->customData = NULL; +} + void initEdgeSlide(TransInfo *t) { SlideData *sld; t->mode = TFM_EDGE_SLIDE; t->transform = EdgeSlide; - + createSlideVerts(t); sld = t->customData; if (!sld) return; + t->customFree = freeSlideVerts; + initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO); setCustomPoints(t, &t->mouse, sld->end, sld->start); @@ -4639,36 +4677,6 @@ int doEdgeSlide(TransInfo *t, float perc) return 1; } -void freeSlideVerts(TransInfo *t) -{ - TransDataSlideUv *suv; - SlideData *sld = t->customData; - int uvlay_idx; - - //BLI_ghash_free(edgesgh, freeGHash, NULL); - BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN); - BLI_linklist_free(sld->vertlist, NULL); - BLI_linklist_free(sld->edgelist, NULL); - - if (sld->uvlay_tot) { - for (uvlay_idx=0; uvlay_idxuvlay_tot; uvlay_idx++) { - BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL); - } - MEM_freeN(sld->slideuv); - MEM_freeN(sld->uvhash); - - suv = sld->suv_last-1; - while (suv >= sld->slideuv) { - if (suv->fuv_list) { - BLI_linklist_free(suv->fuv_list,NULL); - } - suv--; - } - } - - MEM_freeN(sld); -} - int EdgeSlide(TransInfo *t, short mval[2]) { TransData *td = t->data; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 404257a55ff..66d5ecd4d66 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -291,6 +291,7 @@ typedef struct TransInfo { struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */ void *customData; /* Per Transform custom data */ + void (*customFree)(struct TransInfo *); /* if a special free function is needed */ /*************** NEW STUFF *********************/ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 64151918a47..543bbf13fcc 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5312,6 +5312,8 @@ void createTransData(bContext *C, TransInfo *t) } else { t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */ + t->options |= CTX_NO_PET; + createTransObject(C, t); t->flag |= T_OBJECT; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 59429d65e7b..ea5653dc130 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -978,51 +978,60 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } } - /* setting PET flag */ - if (op && RNA_struct_find_property(op->ptr, "proportional") && RNA_property_is_set(op->ptr, "proportional")) + /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */ + if (op && RNA_struct_find_property(op->ptr, "proportional")) { - switch(RNA_enum_get(op->ptr, "proportional")) + if (RNA_property_is_set(op->ptr, "proportional")) { - case 2: /* XXX connected constant */ - t->flag |= T_PROP_CONNECTED; - case 1: /* XXX prop on constant */ - t->flag |= T_PROP_EDIT; - break; + switch(RNA_enum_get(op->ptr, "proportional")) + { + case 2: /* XXX connected constant */ + t->flag |= T_PROP_CONNECTED; + case 1: /* XXX prop on constant */ + t->flag |= T_PROP_EDIT; + break; + } } - } - else - { - if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) { - t->flag |= T_PROP_EDIT; + else + { + if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) { + t->flag |= T_PROP_EDIT; - if(ts->proportional == 2) - t->flag |= T_PROP_CONNECTED; // yes i know, has to become define + if(ts->proportional == 2) + t->flag |= T_PROP_CONNECTED; // yes i know, has to become define + } } - } - if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size")) - { - t->prop_size = RNA_float_get(op->ptr, "proportional_size"); - } - else - { - t->prop_size = ts->proportional_size; - } + if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size")) + { + t->prop_size = RNA_float_get(op->ptr, "proportional_size"); + } + else + { + t->prop_size = ts->proportional_size; + } - if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff")) - { - t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff"); + + /* TRANSFORM_FIX_ME rna restrictions */ + if (t->prop_size <= 0) + { + t->prop_size = 1.0f; + } + + if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff")) + { + t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff"); + } + else + { + t->prop_mode = ts->prop_mode; + } } - else + else /* add not pet option to context when not available */ { - t->prop_mode = ts->prop_mode; + t->options |= CTX_NO_PET; } - /* TRANSFORM_FIX_ME rna restrictions */ - if (t->prop_size <= 0) - { - t->prop_size = 1.0f; - } setTransformViewMatrices(t); initNumInput(&t->num); @@ -1065,8 +1074,6 @@ void postTrans (TransInfo *t) ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); } else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { - if (t->customData) - MEM_freeN(t->customData); } if (t->mouse.data) @@ -1074,8 +1081,11 @@ void postTrans (TransInfo *t) MEM_freeN(t->mouse.data); } - if (t->mode == TFM_EDGE_SLIDE) { - freeSlideVerts(t); + if (t->customFree) { + t->customFree(t); + } + else if (t->customData) { + MEM_freeN(t->customData); } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 69819da8cc2..b6f8d2c8c22 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -99,6 +99,7 @@ char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten"; char OP_TILT[] = "TFM_OT_tilt"; char OP_TRACKBALL[] = "TFM_OT_trackball"; char OP_MIRROR[] = "TFM_OT_mirror"; +char OP_EDGE_SLIDE[] = "TFM_OT_edge_slide"; TransformModeItem transform_modes[] = @@ -113,6 +114,7 @@ TransformModeItem transform_modes[] = {OP_TILT, TFM_TILT}, {OP_TRACKBALL, TFM_TRACKBALL}, {OP_MIRROR, TFM_MIRROR}, + {OP_EDGE_SLIDE, TFM_EDGE_SLIDE}, {NULL, 0} }; @@ -549,6 +551,26 @@ void TFM_OT_mirror(struct wmOperatorType *ot) Properties_Constraints(ot); } +void TFM_OT_edge_slide(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Tilt"; + ot->description= "Tilt selected control vertices of 3d curve."; + ot->idname = OP_EDGE_SLIDE; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + /* api callbacks */ + ot->invoke = transform_invoke; + ot->exec = transform_exec; + ot->modal = transform_modal; + ot->cancel = transform_cancel; + ot->poll = ED_operator_editmesh; + + RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); + + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + void TFM_OT_transform(struct wmOperatorType *ot) { static EnumPropertyItem transform_mode_types[] = { @@ -618,6 +640,7 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_tilt); WM_operatortype_append(TFM_OT_trackball); WM_operatortype_append(TFM_OT_mirror); + WM_operatortype_append(TFM_OT_edge_slide); WM_operatortype_append(TFM_OT_select_orientation); } -- cgit v1.2.3 From 7b1e5f4d8e38fa39e2b97f4602031bd990ec8524 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 23 Sep 2009 00:53:30 +0000 Subject: * Tweak to fix: [#8358] Performance regression with raytraced refraction Now shadows are only sampled once in reflections/refractions. For cases where this would be a problem (perfect specular reflection/refraction), the full OSA takes care of it. --- source/blender/render/intern/source/rayshade.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index d2599f6050c..c1d0c943ca9 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1900,7 +1900,8 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * else max_samples = 1; } else { if (do_soft) max_samples = lar->ray_totsamp; - else max_samples = (R.osa > 4)?R.osa:5; + else if (shi->depth == 0) max_samples = (R.osa > 4)?R.osa:5; + else max_samples = 1; } ray_shadow_jittered_coords(shi, max_samples, jitco, &totjitco); -- cgit v1.2.3 From d98700360838e5dbb52ac633d0a32c5558754eb7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 23 Sep 2009 01:35:45 +0000 Subject: remove rna function convert_to_triface because it uses an internal editmesh function and only the OBJ exporter called this. Converting to tri's on export isnt very important. --- release/io/export_obj.py | 6 ++++- source/blender/blenkernel/BKE_image.h | 3 +++ source/blender/editors/mesh/editmesh_tools.c | 16 ++++++------ source/blender/makesrna/intern/rna_object_api.c | 34 ------------------------- 4 files changed, 16 insertions(+), 43 deletions(-) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index d52ee8ec158..bd323b6586a 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -451,6 +451,9 @@ def write(filename, objects, scene, else: faceuv = False + # XXX - todo, find a better way to do triangulation + # ...removed convert_to_triface because it relies on editmesh + ''' # We have a valid mesh if EXPORT_TRI and me.faces: # Add a dummy object to it. @@ -468,7 +471,8 @@ def write(filename, objects, scene, newob.convert_to_triface(scene) # mesh will still be there scene.remove_object(newob) - + ''' + # Make our own list so it can be sorted to reduce context switching face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)] # faces = [ f for f in me.faces ] diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 816baa20467..47ab6f324d3 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -125,6 +125,9 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf); /* called on frame change or before render */ void BKE_image_user_calc_imanr(struct ImageUser *iuser, int cfra, int fieldnr); +/* produce image export path */ +int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size); + /* fix things in ImageUser when new image gets assigned */ void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 26bee09c925..6e5ce92c904 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -140,7 +140,7 @@ static int vergface(const void *v1, const void *v2) /* *********************************** */ -void convert_to_triface(EditMesh *em, int direction) +static void convert_to_triface(EditMesh *em, int direction) { EditFace *efa, *efan, *next; float fac; @@ -5638,7 +5638,7 @@ static void collapseuvs(EditMesh *em, EditVert *mergevert) } } -int collapseEdges(EditMesh *em) +static int collapseEdges(EditMesh *em) { EditVert *eve; EditEdge *eed; @@ -5704,7 +5704,7 @@ int collapseEdges(EditMesh *em) return mergecount; } -int merge_firstlast(EditMesh *em, int first, int uvmerge) +static int merge_firstlast(EditMesh *em, int first, int uvmerge) { EditVert *eve,*mergevert; EditSelection *ese; @@ -5738,7 +5738,7 @@ int merge_firstlast(EditMesh *em, int first, int uvmerge) return removedoublesflag(em, 1, 0, MERGELIMIT); } -void em_snap_to_center(EditMesh *em) +static void em_snap_to_center(EditMesh *em) { EditVert *eve; float cent[3] = {0.0f, 0.0f, 0.0f}; @@ -5763,7 +5763,7 @@ void em_snap_to_center(EditMesh *em) } } -void em_snap_to_cursor(EditMesh *em, bContext *C) +static void em_snap_to_cursor(EditMesh *em, bContext *C) { Scene *scene = CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); @@ -5784,7 +5784,7 @@ void em_snap_to_cursor(EditMesh *em, bContext *C) } } -int merge_target(bContext *C, EditMesh *em, int target, int uvmerge) +static int merge_target(bContext *C, EditMesh *em, int target, int uvmerge) { EditVert *eve; @@ -5927,7 +5927,7 @@ typedef struct PathEdge { #define PATH_SELECT_EDGE_LENGTH 0 #define PATH_SELECT_TOPOLOGICAL 1 -int select_vertex_path_exec(bContext *C, wmOperator *op) +static int select_vertex_path_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); @@ -7140,7 +7140,7 @@ void MESH_OT_edge_flip(wmOperatorType *ot) /********************** Smooth/Solid Operators *************************/ -void mesh_set_smooth_faces(EditMesh *em, short smooth) +static void mesh_set_smooth_faces(EditMesh *em, short smooth) { EditFace *efa; diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index af6254a99b0..098604c1eab 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -260,34 +260,6 @@ static void rna_Object_free_duplilist(Object *ob, ReportList *reports) } } -static void rna_Object_convert_to_triface(Object *ob, bContext *C, ReportList *reports, Scene *sce) -{ - Mesh *me; - int ob_editing = CTX_data_edit_object(C) == ob; - - if (ob->type != OB_MESH) { - BKE_report(reports, RPT_ERROR, "Object should be of type MESH."); - return; - } - - me= (Mesh*)ob->data; - - if (!ob_editing) - make_editMesh(sce, ob); - - /* select all */ - EM_select_all(me->edit_mesh); - - convert_to_triface(me->edit_mesh, 0); - - load_editMesh(sce, ob); - - if (!ob_editing) - free_editMesh(me->edit_mesh); - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); -} - static bDeformGroup *rna_Object_add_vertex_group(Object *ob, char *group_name) { return ED_vgroup_add_name(ob, group_name); @@ -408,12 +380,6 @@ void RNA_api_object(StructRNA *srna) parm= RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export."); RNA_def_function_return(func, parm); - func= RNA_def_function(srna, "convert_to_triface", "rna_Object_convert_to_triface"); - RNA_def_function_ui_description(func, "Convert all mesh faces to triangles."); - RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene where the object belongs."); - RNA_def_property_flag(parm, PROP_REQUIRED); - /* duplis */ func= RNA_def_function(srna, "create_dupli_list", "rna_Object_create_duplilist"); RNA_def_function_ui_description(func, "Create a list of dupli objects for this object, needs to be freed manually with free_dupli_list."); -- cgit v1.2.3 From efa757fd8d57891f6feb3fc85fdd3e2ab88e7623 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 23 Sep 2009 01:59:57 +0000 Subject: netrender. first draft of html master details. Just point a browser at the master's address and port, et voila. Gives a list of jobs and slaves and well as per frame status for each job and access to slave output logs per frame --- release/io/netrender/__init__.py | 1 + release/io/netrender/client.py | 2 +- release/io/netrender/master.py | 10 ++- release/io/netrender/master_html.py | 119 ++++++++++++++++++++++++++++++++++++ release/io/netrender/model.py | 5 +- release/io/netrender/utils.py | 7 +++ 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 release/io/netrender/master_html.py diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py index b313d64ccbb..4a1dd2238e3 100644 --- a/release/io/netrender/__init__.py +++ b/release/io/netrender/__init__.py @@ -5,6 +5,7 @@ import operators import client import slave import master +import master_html import utils import balancing import ui diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py index f445fe2f608..65b2937867f 100644 --- a/release/io/netrender/client.py +++ b/release/io/netrender/client.py @@ -1,5 +1,5 @@ import bpy -import sys, os +import sys, os, re import http, http.client, http.server, urllib import subprocess, shutil, time, hashlib diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 1bff5f6340b..0e3c7063cab 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -5,6 +5,7 @@ import subprocess, shutil, time, hashlib from netrender.utils import * import netrender.model import netrender.balancing +import netrender.master_html class MRenderFile: def __init__(self, filepath, start, end): @@ -126,9 +127,9 @@ class MRenderFrame(netrender.model.RenderFrame): # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- class RenderHandler(http.server.BaseHTTPRequestHandler): - def send_head(self, code = http.client.OK, headers = {}): + def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"): self.send_response(code) - self.send_header("Content-type", "application/octet-stream") + self.send_header("Content-type", content) for key, value in headers.items(): self.send_header(key, value) @@ -342,7 +343,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head() self.wfile.write(bytes(repr(message), encoding='utf8')) - + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + else: + # hand over the rest to the html section + netrender.master_html.get(self) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py new file mode 100644 index 00000000000..6a337c8d71d --- /dev/null +++ b/release/io/netrender/master_html.py @@ -0,0 +1,119 @@ +import re + +from netrender.utils import * + + +def get(handler): + def output(text): + handler.wfile.write(bytes(text, encoding='utf8')) + + def link(text, url): + return "
%s" % (url, text) + + def startTable(border=1): + output("" % border) + + def headerTable(*headers): + output("") + + for c in headers: + output("") + + output("") + + def rowTable(*data): + output("") + + for c in data: + output("") + + output("") + + def endTable(): + output("
" + c + "
" + str(c) + "
") + + handler.send_head(content = "text/html") + + if handler.path == "/html" or handler.path == "/": + output("NetRender") + + output("

Master

") + + output("

Slaves

") + + startTable() + headerTable("id", "name", "address", "stats") + + for slave in handler.server.slaves: + rowTable(slave.id, slave.name, slave.address[0], slave.stats) + + endTable() + + output("

Jobs

") + + startTable() + headerTable("id", "name", "length", "done", "dispatched", "error") + + for job in handler.server.jobs: + results = job.framesStatus() + rowTable(link(job.id, "/html/job" + job.id), job.name, len(job), results[DONE], results[DISPATCHED], results[ERROR]) + + endTable() + + output("") + + elif handler.path.startswith("/html/job"): + job_id = handler.path[9:] + + output("NetRender") + + job = handler.server.getJobByID(job_id) + + if job: + output("

Frames

") + + startTable() + headerTable("no", "status", "render time", "slave", "log") + + for frame in job.frames: + rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else " ") + + endTable() + else: + output("no such job") + + output("") + + elif handler.path.startswith("/html/log"): + pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)") + + output("NetRender") + + match = pattern.match(handler.path[9:]) + if match: + job_id = match.groups()[0] + frame_number = int(match.groups()[1]) + + job = handler.server.getJobByID(job_id) + + if job: + frame = job[frame_number] + + if frame: + f = open(frame.log_path, 'rb') + + output("
")
+						
+						shutil.copyfileobj(f, handler.wfile)
+						
+						output("
") + + f.close() + else: + output("no such frame") + else: + output("no such job") + else: + output("malformed url") + + output("") diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index e8046d7ac8c..9cacfb54a35 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -32,7 +32,7 @@ class RenderSlave: def __init__(self): self.id = "" self.name = "" - self.address = (0,0) + self.address = ("",0) self.stats = "" self.total_done = 0 self.total_error = 0 @@ -173,6 +173,9 @@ class RenderFrame: self.status = QUEUED self.slave = None + def statusText(self): + return STATUS_TEXT[self.status] + def serialize(self): return { "number": self.number, diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index 50ca08d1723..62288aecf94 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -19,6 +19,13 @@ DISPATCHED = 1 DONE = 2 ERROR = 3 +STATUS_TEXT = { + QUEUED: "Queued", + DISPATCHED: "Dispatched", + DONE: "Done", + ERROR: "Error" + } + def rnaType(rna_type): bpy.types.register(rna_type) return rna_type -- cgit v1.2.3 From 9e110a6d00e791b7fa7cc4ba559b68acac029c5b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 23 Sep 2009 07:28:26 +0000 Subject: A few quick bugfixes: * Vertex Groups list now has a more normal length (2 rows by default) * Copy vertex groups button now has an icon * Pose Sliding tools now allow events which it doesn't process to pass through (i.e. zooming the view now works, and also moving around using the numpad works too) --- release/ui/buttons_data_mesh.py | 6 +++--- source/blender/editors/armature/poseSlide.c | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py index 33b3960b381..a93d7b66397 100644 --- a/release/ui/buttons_data_mesh.py +++ b/release/ui/buttons_data_mesh.py @@ -60,15 +60,15 @@ class DATA_PT_vertex_groups(DataButtonsPanel): ob = context.object row = layout.row() - row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index") + row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=2) col = row.column(align=True) col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="") col.itemO("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="") - col.itemO("object.vertex_group_copy", icon='ICON_BLANK1', text="") + col.itemO("object.vertex_group_copy", icon='ICON_COPYDOWN', text="") if ob.data.users > 1: - col.itemO("object.vertex_group_copy_to_linked", icon='ICON_BLANK1', text="") + col.itemO("object.vertex_group_copy_to_linked", icon='ICON_COPYDOWN', text="") group = ob.active_vertex_group if group: diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 24bd2ebe5ad..7c63954767f 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -721,6 +721,10 @@ static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt) pose_slide_apply(C, op, pso); } break; + + default: /* unhandled event (maybe it was some view manip? */ + /* allow to pass through */ + return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; } /* still running... */ -- cgit v1.2.3 From e2a7168e9680f3dd86875777f7fd9e211ce1d6d2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 23 Sep 2009 11:26:16 +0000 Subject: fly mode back as a modal operator view3d.fly - access with the F key, Ctrl+Alt+F in editmode, View->Navigation menu - camera, perspective & 4split (perspective view only) - uses modal keymap, (same as 2.4x). - bugfix since 2.4x, when flying upside down, turning left/right was inverted. - bugfix for "Align Camera To View", was using deprecated v3d->ofs rather then rv3d->ofs, fixed for NDof fly too. checked v3d->ofs is only used in readfile.c Todo - Warping the cursor removed in 2.5, no way to place the cursor in the middle of the view. - Adding keyframes while in flymode to record the path is missing. - Not getting MMB mouse release events (used for pan). need to look into why. --- release/ui/space_view3d.py | 4 + source/blender/editors/mesh/mesh_ops.c | 2 +- source/blender/editors/space_view3d/view3d_edit.c | 2 +- .../blender/editors/space_view3d/view3d_intern.h | 3 + source/blender/editors/space_view3d/view3d_ops.c | 4 + source/blender/editors/space_view3d/view3d_view.c | 815 ++++++++++++++++++++- 6 files changed, 822 insertions(+), 8 deletions(-) diff --git a/release/ui/space_view3d.py b/release/ui/space_view3d.py index fd06853625e..23f3b8a10ac 100644 --- a/release/ui/space_view3d.py +++ b/release/ui/space_view3d.py @@ -136,6 +136,10 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu): layout.item_floatO("view3d.zoom", "delta", 1.0, text="Zoom In") layout.item_floatO("view3d.zoom", "delta", -1.0, text="Zoom Out") + + layout.itemS() + + layout.itemO("view3d.fly") class VIEW3D_MT_view_align(bpy.types.Menu): __space_type__ = 'VIEW_3D' diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index a79b42dcbb8..96f5e7452d1 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -429,7 +429,7 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0); /* use KM_RELEASE because same key is used for tweaks */ WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index b788dc28311..24ec0d124c6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2338,7 +2338,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode) if (use_sel) { QuatConj(q1); /* conj == inv for unit quat */ - VecSubf(v3d->ofs, v3d->ofs, obofs); + VecSubf(rv3d->ofs, rv3d->ofs, obofs); QuatMulVecf(q1, rv3d->ofs); VecAddf(rv3d->ofs, rv3d->ofs, obofs); } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 52505fad521..d532d2b2cc8 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -124,6 +124,7 @@ void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot); void VIEW3D_OT_localview(struct wmOperatorType *ot); void VIEW3D_OT_game_start(struct wmOperatorType *ot); +void VIEW3D_OT_fly(struct wmOperatorType *ot); int boundbox_clip(RegionView3D *rv3d, float obmat[][4], struct BoundBox *bb); @@ -135,6 +136,8 @@ void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for picking */ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); +void fly_modal_keymap(struct wmWindowManager *wm); + /* view3d_buttons.c */ void VIEW3D_OT_properties(struct wmOperatorType *ot); void view3d_buttons_register(struct ARegionType *art); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 57176dc2592..06480d3e2db 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -85,6 +85,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_drawtype); WM_operatortype_append(VIEW3D_OT_localview); WM_operatortype_append(VIEW3D_OT_game_start); + WM_operatortype_append(VIEW3D_OT_fly); WM_operatortype_append(VIEW3D_OT_layers); WM_operatortype_append(VIEW3D_OT_properties); @@ -123,6 +124,8 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center", PADPERIOD, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_ANY, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); @@ -218,5 +221,6 @@ void view3d_keymap(wmWindowManager *wm) transform_keymap_for_space(wm, keymap, SPACE_VIEW3D); + fly_modal_keymap(wm); } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b6b6f654909..f722a97963d 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -56,9 +56,11 @@ #include "BKE_object.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_utildefines.h" +#include "BKE_depsgraph.h" /* for fly mode updating */ #include "RE_pipeline.h" // make_stars @@ -384,26 +386,31 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; } -static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) +static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob) { - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d= CTX_wm_region_view3d(C); - Object *ob; float dvec[3]; - ob= v3d->camera; dvec[0]= rv3d->dist*rv3d->viewinv[2][0]; dvec[1]= rv3d->dist*rv3d->viewinv[2][1]; dvec[2]= rv3d->dist*rv3d->viewinv[2][2]; VECCOPY(ob->loc, dvec); - VecSubf(ob->loc, ob->loc, v3d->ofs); + VecSubf(ob->loc, ob->loc, rv3d->ofs); rv3d->viewquat[0]= -rv3d->viewquat[0]; QuatToEul(rv3d->viewquat, ob->rot); rv3d->viewquat[0]= -rv3d->viewquat[0]; ob->recalc= OB_RECALC_OB; +} + + +static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + + setcameratoview3d(v3d, rv3d, v3d->camera); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C)); @@ -1572,6 +1579,802 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) ot->poll= game_engine_poll; } + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +#define FLY_MODAL_CANCEL 1 +#define FLY_MODAL_CONFIRM 2 +#define FLY_MODAL_ACCELERATE 3 +#define FLY_MODAL_DECELERATE 4 +#define FLY_MODAL_PAN_ENABLE 5 +#define FLY_MODAL_PAN_DISABLE 6 +#define FLY_MODAL_DIR_FORWARD 7 +#define FLY_MODAL_DIR_BACKWARD 8 +#define FLY_MODAL_DIR_LEFT 9 +#define FLY_MODAL_DIR_RIGHT 10 +#define FLY_MODAL_DIR_UP 11 +#define FLY_MODAL_DIR_DOWN 12 +#define FLY_MODAL_AXIS_LOCK_X 13 +#define FLY_MODAL_AXIS_LOCK_Z 14 +#define FLY_MODAL_PRECISION_ENABLE 15 +#define FLY_MODAL_PRECISION_DISABLE 16 + +/* called in transform_ops.c, on each regeneration of keymaps */ +void fly_modal_keymap(wmWindowManager *wm) +{ + static EnumPropertyItem modal_items[] = { + {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, + {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""}, + + {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan Enable", ""}, + {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan Disable", ""}, + + {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Fly Forward", ""}, + {FLY_MODAL_DIR_BACKWARD,"BACKWARD", 0, "Fly Backward", ""}, + {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Fly Left", ""}, + {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Fly Right", ""}, + {FLY_MODAL_DIR_UP, "UP", 0, "Fly Up", ""}, + {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Fly Down", ""}, + + {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"}, + {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"}, + + {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision Enable", ""}, + {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision Disable", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Fly Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(wm, "View3D Fly Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CANCEL); + + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, FLY_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); + WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, FLY_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, FLY_MODAL_DECELERATE); + + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ + + /* WASD */ + WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_FORWARD); + WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_BACKWARD); + WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_LEFT); + WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_RIGHT); + WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_UP); + WM_modalkeymap_add_item(keymap, FKEY, KM_PRESS, 0, 0, FLY_MODAL_DIR_DOWN); + + WM_modalkeymap_add_item(keymap, XKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_X); + WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, FLY_MODAL_AXIS_LOCK_Z); + + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_PRECISION_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PRECISION_DISABLE); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly"); + +} + +typedef struct FlyInfo { + /* context stuff */ + RegionView3D *rv3d; + View3D *v3d; + ARegion *ar; + Scene *scene; + + wmTimer *timer; /* needed for redraws */ + + short state; + short use_precision; + short redraw; + short mval[2]; + + /* fly state state */ + float speed; /* the speed the view is moving per redraw */ + short axis; /* Axis index to move allong by default Z to move allong the view */ + short pan_view; /* when true, pan the view instead of rotating */ + + /* relative view axis locking - xlock, zlock + 0; disabled + 1; enabled but not checking because mouse hasnt moved outside the margin since locking was checked an not needed + when the mouse moves, locking is set to 2 so checks are done. + 2; mouse moved and checking needed, if no view altering is donem its changed back to 1 */ + short xlock, zlock; + float xlock_momentum, zlock_momentum; /* nicer dynamics */ + float grid; /* world scale 1.0 default */ + + /* backup values */ + float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ + float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */ + float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */ + short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ + + /* compare between last state */ + double time_lastwheel; /* used to accelerate when using the mousewheel a lot */ + double time_lastdraw; /* time between draws */ + + /* use for some lag */ + float dvec_prev[3]; /* old for some lag */ + +} FlyInfo; + +/* FlyInfo->state */ +#define FLY_RUNNING 0 +#define FLY_CANCEL 1 +#define FLY_CONFIRM 2 + +int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event) +{ + float upvec[3]; // tmp + float mat[3][3]; + + fly->rv3d= CTX_wm_region_view3d(C); + fly->v3d = CTX_wm_view3d(C); + fly->ar = CTX_wm_region(C); + fly->scene= CTX_data_scene(C); + + if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->id.lib) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); + return FALSE; + } + + if(fly->v3d->ob_centre) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object"); + return FALSE; + } + + if(fly->rv3d->persp==V3D_CAMOB && fly->v3d->camera->constraints.first) { + BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints"); + return FALSE; + } + + fly->state= FLY_RUNNING; + fly->speed= 0.0f; + fly->axis= 2; + fly->pan_view= FALSE; + fly->xlock= FALSE; + fly->zlock= TRUE; + fly->xlock_momentum=0.0f; + fly->zlock_momentum=0.0f; + fly->grid= 1.0f; + fly->use_precision= 0; + + fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f; + + fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f); + + + /* we have to rely on events to give proper mousecoords after a warp_pointer */ +//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]); + //fly->mval[0]= (fly->sa->winx)/2; + //fly->mval[1]= (fly->sa->winy)/2; + + fly->mval[0] = event->x - fly->ar->winrct.xmin; + fly->mval[1] = event->y - fly->ar->winrct.ymin; + + + fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer(); + + fly->rv3d->rflag |= RV3D_FLYMODE; /* so we draw the corner margins */ + + /* detect weather to start with Z locking */ + upvec[0]=1.0f; upvec[1]=0.0f; upvec[2]=0.0f; + Mat3CpyMat4(mat, fly->rv3d->viewinv); + Mat3MulVecfl(mat, upvec); + if (fabs(upvec[2]) < 0.1) + fly->zlock = 1; + upvec[0]=0; upvec[1]=0; upvec[2]=0; + + fly->persp_backup= fly->rv3d->persp; + fly->dist_backup= fly->rv3d->dist; + if (fly->rv3d->persp==V3D_CAMOB) { + /* store the origoinal camera loc and rot */ + VECCOPY(fly->ofs_backup, fly->v3d->camera->loc); + VECCOPY(fly->rot_backup, fly->v3d->camera->rot); + + where_is_object(fly->scene, fly->v3d->camera); + VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); + VecMulf(fly->rv3d->ofs, -1.0f); /*flip the vector*/ + + fly->rv3d->dist=0.0; + fly->rv3d->viewbut=0; + + /* used for recording */ +//XXX2.5 if(v3d->camera->ipoflag & OB_ACTION_OB) +//XXX2.5 actname= "Object"; + + } else { + /* perspective or ortho */ + if (fly->rv3d->persp==V3D_ORTHO) + fly->rv3d->persp= V3D_PERSP; /*if ortho projection, make perspective */ + QUATCOPY(fly->rot_backup, fly->rv3d->viewquat); + VECCOPY(fly->ofs_backup, fly->rv3d->ofs); + fly->rv3d->dist= 0.0; + + upvec[2]= fly->dist_backup; /*x and y are 0*/ + Mat3MulVecfl(mat, upvec); + VecSubf(fly->rv3d->ofs, fly->rv3d->ofs, upvec); + /*Done with correcting for the dist*/ + } + + return 1; +} + +static int flyEnd(bContext *C, FlyInfo *fly) +{ + RegionView3D *rv3d= fly->rv3d; + View3D *v3d = fly->v3d; + + float upvec[3]; + + if(fly->state == FLY_RUNNING) + return OPERATOR_RUNNING_MODAL; + + WM_event_remove_window_timer(CTX_wm_window(C), fly->timer); + + rv3d->dist= fly->dist_backup; + + if (fly->state == FLY_CANCEL) { + /* Revert to original view? */ + if (fly->persp_backup==V3D_CAMOB) { /* a camera view */ + rv3d->viewbut=1; + VECCOPY(v3d->camera->loc, fly->ofs_backup); + VECCOPY(v3d->camera->rot, fly->rot_backup); + DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB); + } else { + /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ + QUATCOPY(rv3d->viewquat, fly->rot_backup); + VECCOPY(rv3d->ofs, fly->ofs_backup); + rv3d->persp= fly->persp_backup; + } + } + else if (fly->persp_backup==V3D_CAMOB) { /* camera */ + float mat3[3][3]; + Mat3CpyMat4(mat3, v3d->camera->obmat); + Mat3ToCompatibleEul(mat3, v3d->camera->rot, fly->rot_backup); + + DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB); +#if 0 //XXX2.5 + if (IS_AUTOKEY_MODE(NORMAL)) { + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWTIME, 0); + } +#endif + } + else { /* not camera */ + /* Apply the fly mode view */ + /*restore the dist*/ + float mat[3][3]; + upvec[0]= upvec[1]= 0; + upvec[2]= fly->dist_backup; /*x and y are 0*/ + Mat3CpyMat4(mat, rv3d->viewinv); + Mat3MulVecfl(mat, upvec); + VecAddf(rv3d->ofs, rv3d->ofs, upvec); + /*Done with correcting for the dist */ + } + + rv3d->rflag &= ~RV3D_FLYMODE; +//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ + + + if(fly->state == FLY_CONFIRM) { + MEM_freeN(fly); + return OPERATOR_FINISHED; + } + + MEM_freeN(fly); + return OPERATOR_CANCELLED; +} + +void flyEvent(FlyInfo *fly, wmEvent *event) +{ + if (event->type == TIMER) { + fly->redraw = 1; + } + else if (event->type == MOUSEMOVE) { + fly->mval[0] = event->x - fly->ar->winrct.xmin; + fly->mval[1] = event->y - fly->ar->winrct.ymin; + } /* handle modal keymap first */ + else if (event->type == EVT_MODAL_MAP) { + switch (event->val) { + case FLY_MODAL_CANCEL: + fly->state = FLY_CANCEL; + break; + case FLY_MODAL_CONFIRM: + fly->state = FLY_CONFIRM; + break; + + case FLY_MODAL_ACCELERATE: + { + double time_currwheel; + float time_wheel; + + time_currwheel= PIL_check_seconds_timer(); + time_wheel = (float)(time_currwheel - fly->time_lastwheel); + fly->time_lastwheel = time_currwheel; + /*printf("Wheel %f\n", time_wheel);*/ + /*Mouse wheel delays range from 0.5==slow to 0.01==fast*/ + time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ + + if (fly->speed<0.0f) fly->speed= 0.0f; + else { + if (event->shift) + fly->speed+= fly->grid*time_wheel*0.1; + else + fly->speed+= fly->grid*time_wheel; + } + break; + } + case FLY_MODAL_DECELERATE: + { + double time_currwheel; + float time_wheel; + + time_currwheel= PIL_check_seconds_timer(); + time_wheel = (float)(time_currwheel - fly->time_lastwheel); + fly->time_lastwheel = time_currwheel; + time_wheel = 1+ (10 - (20*MIN2(time_wheel, 0.5))); /* 0-0.5 -> 0-5.0 */ + + if (fly->speed>0) fly->speed=0; + else { + if (event->shift) + fly->speed-= fly->grid*time_wheel*0.1; + else + fly->speed-= fly->grid*time_wheel; + } + break; + } + case FLY_MODAL_PAN_ENABLE: + fly->pan_view= TRUE; + break; + case FLY_MODAL_PAN_DISABLE: +//XXX2.5 warp_pointer(cent_orig[0], cent_orig[1]); + fly->pan_view= FALSE; + break; + + /* impliment WASD keys */ + case FLY_MODAL_DIR_FORWARD: + if (fly->speed < 0.0f) fly->speed= -fly->speed; /* flip speed rather then stopping, game like motion */ + else fly->speed += fly->grid; /* increse like mousewheel if were alredy moving in that difection*/ + fly->axis= 2; + break; + case FLY_MODAL_DIR_BACKWARD: + if (fly->speed>0) fly->speed= -fly->speed; + else fly->speed -= fly->grid; + fly->axis= 2; + break; + case FLY_MODAL_DIR_LEFT: + if (fly->speed < 0.0f) fly->speed= -fly->speed; + fly->axis= 0; + break; + case FLY_MODAL_DIR_RIGHT: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + fly->axis= 0; + break; + + case FLY_MODAL_DIR_UP: + if (fly->speed < 0.0f) fly->speed= -fly->speed; + fly->axis= 1; + break; + + case FLY_MODAL_DIR_DOWN: + if (fly->speed > 0.0f) fly->speed= -fly->speed; + fly->axis= 1; + break; + + case FLY_MODAL_AXIS_LOCK_X: + if (fly->xlock) fly->xlock=0; + else { + fly->xlock = 2; + fly->xlock_momentum = 0.0; + } + break; + case FLY_MODAL_AXIS_LOCK_Z: + if (fly->zlock) fly->zlock=0; + else { + fly->zlock = 2; + fly->zlock_momentum = 0.0; + } + break; + + case FLY_MODAL_PRECISION_ENABLE: + fly->use_precision= TRUE; + break; + case FLY_MODAL_PRECISION_DISABLE: + fly->use_precision= FALSE; + break; + + } + } +} + +//int fly_exec(bContext *C, wmOperator *op) +int flyApply(FlyInfo *fly) +{ + /* + fly mode - Shift+F + a fly loop where the user can move move the view as if they are flying + */ + RegionView3D *rv3d= fly->rv3d; + View3D *v3d = fly->v3d; + ARegion *ar = fly->ar; + Scene *scene= fly->scene; + + float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */ + dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */ + + /* Camera Uprighting variables */ + upvec[3]={0,0,0}, /* stores the view's up vector */ + + moffset[2], /* mouse offset from the views center */ + tmp_quat[4]; /* used for rotating the view */ + + int cent_orig[2], /* view center */ +//XXX- can avoid using // cent[2], /* view center modified */ + xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */ + unsigned char + apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/ + + /* for recording */ +#if 0 //XXX2.5 todo, get animation recording working again. + int playing_anim = 0; //XXX has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM); + int cfra = -1; /*so the first frame always has a key added */ + char *actname=""; +#endif + /* the dist defines a vector that is infront of the offset + to rotate the view about. + this is no good for fly mode because we + want to rotate about the viewers center. + but to correct the dist removal we must + alter offset so the view doesn't jump. */ + + xmargin= ar->winx/20.0f; + ymargin= ar->winy/20.0f; + + cent_orig[0]= ar->winrct.xmin + ar->winx/2; + cent_orig[1]= ar->winrct.ymin + ar->winy/2; + + { + + /* mouse offset from the center */ + moffset[0]= fly->mval[0]- ar->winx/2; + moffset[1]= fly->mval[1]- ar->winy/2; + + /* enforce a view margin */ + if (moffset[0]>xmargin) moffset[0]-=xmargin; + else if (moffset[0] < -xmargin) moffset[0]+=xmargin; + else moffset[0]=0; + + if (moffset[1]>ymargin) moffset[1]-=ymargin; + else if (moffset[1] < -ymargin) moffset[1]+=ymargin; + else moffset[1]=0; + + + /* scale the mouse movement by this value - scales mouse movement to the view size + * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y) + * + * the mouse moves isnt linear */ + + if(moffset[0]) { + moffset[0] /= ar->winx - (xmargin*2); + moffset[0] *= fabs(moffset[0]); + } + + if(moffset[1]) { + moffset[1] /= ar->winy - (ymargin*2); + moffset[1] *= fabs(moffset[1]); + } + + /* Should we redraw? */ + if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) { + float dvec_tmp[3]; + double time_current, time_redraw; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */ + float time_redraw_clamped; + + time_current= PIL_check_seconds_timer(); + time_redraw= (float)(time_current - fly->time_lastdraw); + time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */ + fly->time_lastdraw= time_current; + /*fprintf(stderr, "%f\n", time_redraw);*/ /* 0.002 is a small redraw 0.02 is larger */ + + /* Scale the time to use shift to scale the speed down- just like + shift slows many other areas of blender down */ + if (fly->use_precision) + fly->speed= fly->speed * (1.0f-time_redraw_clamped); + + Mat3CpyMat4(mat, rv3d->viewinv); + + if (fly->pan_view==TRUE) { + /* pan only */ + dvec_tmp[0]= -moffset[0]; + dvec_tmp[1]= -moffset[1]; + dvec_tmp[2]= 0; + + if (fly->use_precision) { + dvec_tmp[0] *= 0.1; + dvec_tmp[1] *= 0.1; + } + + Mat3MulVecfl(mat, dvec_tmp); + VecMulf(dvec_tmp, time_redraw*200.0 * fly->grid); + + } else { + float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/ + + /* rotate about the X axis- look up/down */ + if (moffset[1]) { + upvec[0]=1; + upvec[1]=0; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + VecRotToQuat( upvec, (float)moffset[1]*-time_redraw*20, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + if (fly->xlock) fly->xlock = 2; /*check for rotation*/ + if (fly->zlock) fly->zlock = 2; + fly->xlock_momentum= 0.0f; + } + + /* rotate about the Y axis- look left/right */ + if (moffset[0]) { + + /* if we're upside down invert the moffset */ + upvec[0]=0; + upvec[1]=1; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + + if(upvec[2] < 0.0f) + moffset[0]= -moffset[0]; + + /* make the lock vectors */ + if (fly->zlock) { + upvec[0]=0; + upvec[1]=0; + upvec[2]=1; + } else { + upvec[0]=0; + upvec[1]=1; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + } + + VecRotToQuat( upvec, (float)moffset[0]*time_redraw*20, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + if (fly->xlock) fly->xlock = 2;/*check for rotation*/ + if (fly->zlock) fly->zlock = 2; + } + + if (fly->zlock==2) { + upvec[0]=1; + upvec[1]=0; + upvec[2]=0; + Mat3MulVecfl(mat, upvec); + + /*make sure we have some z rolling*/ + if (fabs(upvec[2]) > 0.00001f) { + roll= upvec[2]*5; + upvec[0]=0; /*rotate the view about this axis*/ + upvec[1]=0; + upvec[2]=1; + + Mat3MulVecfl(mat, upvec); + VecRotToQuat( upvec, roll*time_redraw_clamped*fly->zlock_momentum*0.1, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + fly->zlock_momentum += 0.05f; + } else { + fly->zlock=1; /* dont check until the view rotates again */ + fly->zlock_momentum= 0.0f; + } + } + + if (fly->xlock==2 && moffset[1]==0) { /*only apply xcorrect when mouse isnt applying x rot*/ + upvec[0]=0; + upvec[1]=0; + upvec[2]=1; + Mat3MulVecfl(mat, upvec); + /*make sure we have some z rolling*/ + if (fabs(upvec[2]) > 0.00001) { + roll= upvec[2] * -5; + + upvec[0]= 1.0f; /*rotate the view about this axis*/ + upvec[1]= 0.0f; + upvec[2]= 0.0f; + + Mat3MulVecfl(mat, upvec); + + VecRotToQuat( upvec, roll*time_redraw_clamped*fly->xlock_momentum*0.1f, tmp_quat); /* Rotate about the relative up vec */ + QuatMul(rv3d->viewquat, rv3d->viewquat, tmp_quat); + + fly->xlock_momentum += 0.05f; + } else { + fly->xlock=1; /* see above */ + fly->xlock_momentum= 0.0f; + } + } + + + if (apply_rotation) { + /* Normal operation */ + /* define dvec, view direction vector */ + dvec_tmp[0]= dvec_tmp[1]= dvec_tmp[2]= 0.0f; + /* move along the current axis */ + dvec_tmp[fly->axis]= 1.0f; + + Mat3MulVecfl(mat, dvec_tmp); + + VecMulf(dvec_tmp, fly->speed * time_redraw * 0.25f); + } + } + + /* impose a directional lag */ + VecLerpf(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f)))); + + if (rv3d->persp==V3D_CAMOB) { + if (v3d->camera->protectflag & OB_LOCK_LOCX) + dvec[0] = 0.0; + if (v3d->camera->protectflag & OB_LOCK_LOCY) + dvec[1] = 0.0; + if (v3d->camera->protectflag & OB_LOCK_LOCZ) + dvec[2] = 0.0; + } + + VecAddf(rv3d->ofs, rv3d->ofs, dvec); +#if 0 //XXX2.5 + if (fly->zlock && fly->xlock) + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else if (fly->zlock) + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else if (fly->xlock) + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); + else + headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB"); +#endif + +//XXX2.5 do_screenhandlers(G.curscreen); /* advance the next frame */ + + /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ + if (rv3d->persp==V3D_CAMOB) { + rv3d->persp= V3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */ + setviewmatrixview3d(scene, v3d, rv3d); + + setcameratoview3d(v3d, rv3d, v3d->camera); + + { //XXX - some reason setcameratoview3d doesnt copy, shouldnt not be needed! + VECCOPY(v3d->camera->loc, rv3d->ofs); + VecNegf(v3d->camera->loc); + } + + rv3d->persp= V3D_CAMOB; +#if 0 //XXX2.5 + /* record the motion */ + if (IS_AUTOKEY_MODE(NORMAL) && (!playing_anim || cfra != G.scene->r.cfra)) { + cfra = G.scene->r.cfra; + + if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) { + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_X, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Y, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_ROT_Z, 0); + } + if (fly->speed) { + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_X, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Y, 0); + insertkey(&v3d->camera->id, ID_OB, actname, NULL, OB_LOC_Z, 0); + } + } +#endif + } +//XXX2.5 scrarea_do_windraw(curarea); +//XXX2.5 screen_swapbuffers(); + } else + /*were not redrawing but we need to update the time else the view will jump */ + fly->time_lastdraw= PIL_check_seconds_timer(); + /* end drawing */ + VECCOPY(fly->dvec_prev, dvec); + } + +/* moved to flyEnd() */ + + return OPERATOR_FINISHED; +} + + + +static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + RegionView3D *rv3d= CTX_wm_region_view3d(C); + FlyInfo *fly; + + if(rv3d->viewlock) + return OPERATOR_CANCELLED; + + fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation"); + + op->customdata= fly; + + if(initFlyInfo(C, fly, op, event)==FALSE) { + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; + } + + flyEvent(fly, event); + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int fly_cancel(bContext *C, wmOperator *op) +{ + FlyInfo *fly = op->customdata; + + fly->state = FLY_CANCEL; + flyEnd(C, fly); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} + +static int fly_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + int exit_code; + + FlyInfo *fly = op->customdata; + + fly->redraw= 0; + + flyEvent(fly, event); + + if(event->type==TIMER) + flyApply(fly); + + if(fly->redraw) {; + ED_region_tag_redraw(CTX_wm_region(C)); + } + + exit_code = flyEnd(C, fly); + + if(exit_code!=OPERATOR_RUNNING_MODAL) + ED_region_tag_redraw(CTX_wm_region(C)); + + return exit_code; +} + +void VIEW3D_OT_fly(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Fly Navigation"; + ot->description= "Interactively fly around the scene."; + ot->idname= "VIEW3D_OT_fly"; + + /* api callbacks */ + ot->invoke= fly_invoke; + ot->cancel= fly_cancel; + ot->modal= fly_modal; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; + +} + /* ************************************** */ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3]) -- cgit v1.2.3 From 762d3ad1457a515dd7b64635b96ae55e6640d8e5 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 23 Sep 2009 11:49:12 +0000 Subject: Some UI tweaks as listed by William (http://wiki.blender.org/index.php/BlenderDev/Blender2.5/Todo/UserInterface) * Removed panel docking. "It is too easy to do by accident when reordering panels, is very hard to control and use, and has no real benefit." * Scoll bars have minimum size now, so that the 'thumb' doesn't disappear in long lists. --- source/blender/editors/interface/interface_panel.c | 9 ++++- source/blender/editors/interface/view2d.c | 38 +++++++++++++--------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index cf29a1ddb58..fa24aa72b9f 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -963,6 +963,7 @@ static void check_panel_overlap(ARegion *ar, Panel *panel) } } +#if 0 // XXX panel docking/tabbing code that's no longer used static void test_add_new_tabs(ARegion *ar) { Panel *pa, *pasel=NULL, *palap=NULL; @@ -1016,6 +1017,7 @@ static void test_add_new_tabs(ARegion *ar) pa= pa->next; } } +#endif /************************ panel dragging ****************************/ @@ -1382,7 +1384,12 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat if(state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) { if(data && data->state != PANEL_STATE_ANIMATION) { - test_add_new_tabs(ar); // also copies locations of tabs in dragged panel + /* XXX: + * - the panel tabbing function call below (test_add_new_tabs()) has been commented out + * "It is too easy to do by accident when reordering panels, is very hard to control and use, and has no real benefit." - BillRey + * Aligorith, 2009Sep + */ + //test_add_new_tabs(ar); // also copies locations of tabs in dragged panel check_panel_overlap(ar, NULL); // clears } diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index f9fb7a9306f..be58a78ca85 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1351,7 +1351,7 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short vert= v2d->vert; hor= v2d->hor; - /* slider rects smaller than region */ + /* slider rects need to be smaller than region */ hor.xmin+=4; hor.xmax-=4; if (scroll & V2D_SCROLL_BOTTOM) @@ -1393,13 +1393,18 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short else scrollers->hor_max= (int)(hor.xmin + (fac2 * scrollsize)); + /* prevent inverted sliders */ if (scrollers->hor_min > scrollers->hor_max) scrollers->hor_min= scrollers->hor_max; + /* prevent sliders from being too small, and disappearing */ + if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE) + scrollers->hor_max+= V2D_SCROLLER_HANDLE_SIZE; /* check whether sliders can disappear */ - if(v2d->keeptot) + if(v2d->keeptot) { if(fac1 <= 0.0f && fac2 >= 1.0f) scrollers->horfull= 1; + } } /* vertical scrollers */ @@ -1420,13 +1425,18 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short else scrollers->vert_max= (int)(vert.ymin + (fac2 * scrollsize)); + /* prevent inverted sliders */ if (scrollers->vert_min > scrollers->vert_max) scrollers->vert_min= scrollers->vert_max; + /* prevent sliders from being too small, and disappearing */ + if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE) + scrollers->vert_max+= V2D_SCROLLER_HANDLE_SIZE; /* check whether sliders can disappear */ - if(v2d->keeptot) + if(v2d->keeptot) { if(fac1 <= 0.0f && fac2 >= 1.0f) scrollers->vertfull= 1; + } } /* grid markings on scrollbars */ @@ -1550,14 +1560,6 @@ static void scroll_printstr(View2DScrollers *scrollers, Scene *scene, float x, f BLF_draw_default(x, y, 0.0f, str); } -/* local defines for scrollers drawing */ - /* radius of scroller 'button' caps */ -#define V2D_SCROLLCAP_RAD 5 - /* shading factor for scroller 'bar' */ -#define V2D_SCROLLBAR_SHADE 0.1f - /* shading factor for scroller 'button' caps */ -#define V2D_SCROLLCAP_SHADE 0.2f - /* Draw scrollbars in the given 2d-region */ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs) { @@ -1571,7 +1573,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* horizontal scrollbar */ if (scroll & V2D_SCROLL_HORIZONTAL) { - + /* only draw scrollbar when it doesn't fill the entire space */ if(vs->horfull==0) { bTheme *btheme= U.themes.first; uiWidgetColors wcol= btheme->tui.wcol_scroll; @@ -1584,13 +1586,15 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v slider.ymax= hor.ymax; state= (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE)?UI_SCROLL_PRESSED:0; + + // TODO: disable this for button regions... if (!(v2d->keepzoom & V2D_LOCKZOOM_X)) state |= UI_SCROLL_ARROWS; + uiWidgetScrollDraw(&wcol, &hor, &slider, state); } /* scale indicators */ - // XXX will need to update the font drawing when the new stuff comes in if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) { View2DGrid *grid= vs->grid; float fac, dfac, fac2, val; @@ -1667,7 +1671,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* vertical scrollbar */ if (scroll & V2D_SCROLL_VERTICAL) { - + /* only draw scrollbar when it doesn't fill the entire space */ if(vs->vertfull==0) { bTheme *btheme= U.themes.first; uiWidgetColors wcol= btheme->tui.wcol_scroll; @@ -1680,14 +1684,16 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v slider.ymax= vs->vert_max; state= (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE)?UI_SCROLL_PRESSED:0; - if (!(v2d->keepzoom & V2D_LOCKZOOM_Y)) + + // TODO: disable this for button regions... + if (!(v2d->keepzoom & V2D_LOCKZOOM_Y)) state |= UI_SCROLL_ARROWS; + uiWidgetScrollDraw(&wcol, &vert, &slider, state); } /* scale indiators */ - // XXX will need to update the font drawing when the new stuff comes in if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) { View2DGrid *grid= vs->grid; float fac, dfac, val; -- cgit v1.2.3 From ebbb4ad753c1424f24cb5d1ff34169582a7c9917 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Wed, 23 Sep 2009 12:10:56 +0000 Subject: * fixes for compiling with scons/mingw when BF_DEBUG=1. Needs svn up in lib/windows, where I added necessary mingw libs. --- SConstruct | 4 ++-- config/win32-mingw-config.py | 3 ++- config/win32-vc-config.py | 1 + config/win64-vc-config.py | 1 + tools/btools.py | 3 ++- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 402bf18faf5..7e3d23970cb 100644 --- a/SConstruct +++ b/SConstruct @@ -583,9 +583,9 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc'): dllsources.append('${LCGDIR}/release/python' + ver + '.zip') dllsources.append('${LCGDIR}/release/zlib.pyd') if env['BF_DEBUG']: - dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_LIB}_d.dll') + dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll') else: - dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_LIB}.dll') + dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}.dll') if env['WITH_BF_ICONV']: if env['OURPLATFORM'] == 'win64-vc': pass # we link statically to iconv on win64 diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 04e9f5eb4d1..6b10b410715 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -6,7 +6,8 @@ BF_PYTHON_VERSION = '3.1' WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' -BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}' +BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw' +BF_PYTHON_DLL = 'python31' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a' diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 4f2af93d0e3..291aa023ec8 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -13,6 +13,7 @@ BF_PYTHON_VERSION = '3.1' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' BF_PYTHON_LIB = 'python31' +BF_PYTHON_DLL = '${BF_PYTHON_LIB}' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' WITH_BF_OPENAL = True diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index b48e3875dd5..5bb01ff16b5 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -13,6 +13,7 @@ BF_PYTHON_VERSION = '3.1' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' BF_PYTHON_LIB = 'python31' +BF_PYTHON_DLL = '${BF_PYTHON_LIB}' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' WITH_BF_OPENAL = False diff --git a/tools/btools.py b/tools/btools.py index 771c67aee1f..e3f3827ff45 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -27,7 +27,7 @@ def print_arguments(args, bc): def validate_arguments(args, bc): opts_list = [ - 'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', + 'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC', 'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH', 'BF_LIBSAMPLERATE', 'BF_LIBSAMPLERATE_INC', 'BF_LIBSAMPLERATE_LIB', 'BF_LIBSAMPLERATE_LIBPATH', @@ -158,6 +158,7 @@ def read_opts(cfg, args): ('BF_PYTHON_INC', 'include path for Python headers', ''), ('BF_PYTHON_BINARY', 'Path to the Python interpreter', ''), ('BF_PYTHON_LIB', 'Python library', ''), + ('BF_PYTHON_DLL', 'Python dll - used on Windows only', ''), ('BF_PYTHON_LIB_STATIC', 'Python static libraries', ''), ('BF_PYTHON_LIBPATH', 'Library path', ''), ('BF_PYTHON_LINKFLAGS', 'Python link flags', ''), -- cgit v1.2.3 From 6e941a728a2e491f67832504550bb269655b6022 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 23 Sep 2009 13:09:09 +0000 Subject: 2 Anim Bugfixes: * Loading old (2.4x) files with keyframes now inits them properly so that keyframes are tagged as normal keyframes not breakdowns * TrackTo consraint was flagged wrongly for adding it with a target. This meant that the target didn't get set when using the Ctrl-Shift-C hotkey. --- source/blender/blenkernel/intern/ipo.c | 6 ++++++ source/blender/editors/object/object_constraint.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 62f44d92d25..dd7904b4782 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1214,6 +1214,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha /* interpolation can only be constant... */ dst->ipo= BEZT_IPO_CONST; + /* 'hide' flag is now used for keytype - only 'keyframes' existed before */ + dst->hide= BEZT_KEYTYPE_KEYFRAME; + /* correct values, by checking if the flag of interest is set */ if ( ((int)(dst->vec[1][1])) & (abp->bit) ) dst->vec[0][1]= dst->vec[1][1]= dst->vec[2][1] = 1.0f; @@ -1264,6 +1267,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha if (icu->ipo != IPO_MIXED) dst->ipo= icu->ipo; + /* 'hide' flag is now used for keytype - only 'keyframes' existed before */ + dst->hide= BEZT_KEYTYPE_KEYFRAME; + /* correct values for euler rotation curves - they were degrees/10 */ // XXX for now, just make them into radians as RNA sets/reads directly in that form if ( ((icu->blocktype == ID_OB) && ELEM3(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) || diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index eee6659c6b2..efdef506331 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -919,7 +919,6 @@ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_o /* restricted target-type constraints -------------- */ /* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */ /* curve-based constraints - set the only_curve and only_ob flags */ - case CONSTRAINT_TYPE_TRACKTO: case CONSTRAINT_TYPE_CLAMPTO: case CONSTRAINT_TYPE_FOLLOWPATH: only_curve= 1; -- cgit v1.2.3 From 6c79d757acf4bccf3dc5b53f1916826bdb99cc8b Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Wed, 23 Sep 2009 21:26:24 +0000 Subject: Initial sketch of file access wrappers. It compiles but does nothing useful yet. The "//" comments are notes to remember what to do in each block. --- source/blender/blenlib/BLI_bfile.h | 138 ++++++++++++++++++ source/blender/blenlib/intern/BLI_bfile.c | 231 ++++++++++++++++++++++++++++++ 2 files changed, 369 insertions(+) create mode 100644 source/blender/blenlib/BLI_bfile.h create mode 100644 source/blender/blenlib/intern/BLI_bfile.c diff --git a/source/blender/blenlib/BLI_bfile.h b/source/blender/blenlib/BLI_bfile.h new file mode 100644 index 00000000000..92543558a19 --- /dev/null +++ b/source/blender/blenlib/BLI_bfile.h @@ -0,0 +1,138 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 by Stichting Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + * BFILE* based abstraction of file access. + */ + +#ifndef BLI_BFILE_H +#define BLI_BFILE_H + +/* For fopen's FILE */ +#include + +/** + Defines for the bflags param. + */ +/* Special handling: */ +/* For "symmetry" of flags */ +#define BFILE_NORMAL (0) +/* No supervision, just translate // if needed, RISKY */ +#define BFILE_RAW (1<<0) +/* Path is relative to config dirs */ +#define BFILE_CONFIG (1<<1) +/* Path is for current session temp file */ +#define BFILE_TEMP (1<<2) + +/* Config handling, special cases: */ +#define BFILE_USERONLY (1<<3) +#define BFILE_SYSONLY (1<<4) + +/* Compression to apply on close: */ +#define BFILE_GZIP (1<<5) + +/** + File descriptor for Blender abstracted file access. + */ +typedef struct { + FILE *stream; + int fd; + + /* Anything below should not be touched directly */ + int uflags; /* Special options requested by upper level, copy of bflags */ + char *fpath; /* Final/requested path name */ + char *tpath; /* Temp path name if applicable */ + int type; /* Own flags, common classification of open and fopen */ + int error; /* An op caused an error, unsafe to replace older files */ +} BFILE; + +/** + Open a BFILE* with fopen()-like syntax. + */ +BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags); + +/** + Open a BFILE* with open()-like syntax. + */ +BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags); + +/** + Get the FILE* associated with the BFILE*. + */ +FILE *BLI_bfile_file_from_bfile(BFILE *bfile); + +/** + Get the fd associated with the BFILE*. + */ +int BLI_bfile_fd_from_bfile(BFILE *bfile); + +/** + write()-like using BFILE*. + */ +ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count); + +/** + read()-like using BFILE*. + */ +ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count); + +/** + fwrite()-like using BFILE*. + */ +size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f); + +/** + fread()-like using BFILE*. + */ +size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f); + +/** + Close a BFILE, to match close() and fclose(). + */ +void BLI_bfile_close(BFILE *bfile); + +/** + Clear error status. + Call it only if the error has been really handled. + */ +void BLI_bfile_clear_error(BFILE *bfile); + +/** + Set the error status. + Call it to mark writing by a 3rd party failed (libjpeg reported error, ie). + */ +void BLI_bfile_set_error(BFILE *bfile, int error); + +/* +TODO +Maybe also provide more OS/libc things like: +fflush +fprintf and related +fscanf +fgetc/fputc and related +fseek and related + +Probably good to do: +readdir (compacted list showing all files for a "directory" (user versions on top of system's)) +*/ + +#endif /* ifndef BLI_BFILE_H */ diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c new file mode 100644 index 00000000000..06e75a9a3ca --- /dev/null +++ b/source/blender/blenlib/intern/BLI_bfile.c @@ -0,0 +1,231 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 by Stichting Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + * BFILE* based abstraction for file access. + */ + +#include + +#include + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_bfile.h" + +// This would provide config paths and their oldest viable version +// so if there is an uncompatible change, user's old versions are not loaded +//#include "bfile_tables.h" + +/* Internal bfile type flags */ +#define BTF_OPEN (0) +#define BTF_FOPEN (1<<0) +#define BTF_READ (1<<1) +#define BTF_WRITE (1<<2) +#define BTF_AT_END (1<<3) +#define BTF_DISCARD (1<<4) + + +void fill_paths(BFILE *bfile, const char *path) { + char* source_path = NULL; + int bflags = bfile->uflags; + + if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) { +// bfile->fpath is path with // replaced + } + if(bflags & BFILE_TEMP) { +// bfile->fpath is tempdir+path + } + if(bflags & BFILE_CONFIG) { +// bfile->fpath is userdir+version+path +// source_path is first hit in (if using fallback to older versions) +// userdir+curversion+path (... userdir+limitversion+path) sysdir+path +// (limitversion is based in path, using some kind of regex or "tables") + } + + if(bfile->type & BTF_WRITE && !(bflags & BFILE_RAW)) { + /* Generate temp path */ + // bfile->tpath is fpath+randstring + if(!(bfile->type & BTF_DISCARD)) { + /* Copy data to tpath */ + if(source_path) { + // copy it from older version or sys version + } + } + } else { + bfile->tpath = bfile->fpath; + } +} + +BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) { + BFILE *bfile; + + bfile = MEM_mallocN(sizeof(BFILE), "bfile-fopen"); + bfile->type = BTF_FOPEN; + bfile->uflags = bflags; + + /* From fopen() doc, we can guess some logic: + r BTF_READ + r+ BTF_READ | BTF_WRITE + w BTF_DISCARD | BTF_WRITE + w+ BTF_DISCARD | BTF_WRITE | BTF_READ + a BTF_AT_END | BTF_WRITE + a+ BTF_AT_END | BTF_WRITE | BTF_READ + */ + if(strchr(mode, 'r')) + bfile->type |= BTF_READ; + if(strchr(mode, 'w')) + bfile->type |= (BTF_DISCARD | BTF_WRITE); + if(strchr(mode, 'a')) + bfile->type |= (BTF_AT_END | BTF_WRITE); + if(strchr(mode, '+')) + bfile->type |= (BTF_READ | BTF_WRITE); + + fill_paths(bfile, path); + + bfile->stream = fopen(bfile->tpath, mode); + // detect failed fopen + bfile->fd = fileno(bfile->stream); + return bfile; +} + + +BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags) { + BFILE *bfile; + + bfile = MEM_mallocN(sizeof(BFILE), "bfile-open"); + bfile->type = BTF_OPEN; + bfile->uflags = bflags; + + /* Easy mapping for open() */ + if(flags & O_RDONLY) + bfile->type |= BTF_READ; + if(flags & O_WRONLY) + bfile->type |= BTF_WRITE; + if(flags & O_RDWR) + bfile->type |= (BTF_READ | BTF_WRITE); + if(flags & O_APPEND) + bfile->type |= BTF_AT_END; + if(flags & O_TRUNC) + bfile->type |= BTF_DISCARD; + + fill_paths(bfile, pathname); + + bfile->fd = open(bfile->tpath, flags); + // detect failed open +// bfile->stream = fdopen(bfile->fd, XXX); /* MSWindows _fdopen? */ + return bfile; +} + + +FILE *BLI_bfile_file_from_bfile(BFILE *bfile) { + return bfile->stream; +} + + +int BLI_bfile_fd_from_bfile(BFILE *bfile) { + return bfile->fd; +} + + +ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count) { + ssize_t ret; + + ret = write((f->fd), buf, count); + if (ret == -1) { + f->error = 1; + } + + return ret; +} + + +ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) { + ssize_t ret; + + ret = read((f->fd), buf, count); + if (ret == -1) { + f->error = 1; + } + + return ret; +} + + +size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f) { + size_t ret; + + ret = fwrite(ptr, size, nmemb, f->stream); + if (ret < 0) { + f->error = 1; + } + + return ret; +} + + +size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) { + size_t ret; + + ret = fread(ptr, size, nmemb, f->stream); + if ((ret < 0) && ferror(f->stream)) { + f->error = 1; + } + + return ret; +} + + +void BLI_bfile_close(BFILE *bfile) { + if((bfile->type | BTF_WRITE) && + !(bfile->uflags | BFILE_RAW)) { + /* Make sure data is on disk */ + /* Move to final name if no errors */ + } + + /* Normal close */ + + /* Cleanup */ + if(bfile->fpath) { + MEM_freeN(bfile->fpath); + } + if(bfile->tpath) { + MEM_freeN(bfile->tpath); + } +} + + +void BLI_bfile_clear_error(BFILE *bfile) { + bfile->error = 0; +} + + +void BLI_bfile_set_error(BFILE *bfile, int error) { + /* No cheating, use clear_error() for 0 */ + if (error) { + bfile->error = error; + } +} -- cgit v1.2.3 From b82b50417c9d521a670ede49c7759b784edf2e1c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 23 Sep 2009 21:46:29 +0000 Subject: netrender: load balancer fixes, cancel all jobs button and small html interface changes --- release/io/netrender/balancing.py | 6 +++--- release/io/netrender/master.py | 30 +++++++++++++++++++++++------- release/io/netrender/master_html.py | 6 ++++-- release/io/netrender/operators.py | 34 ++++++++++++++++++++++++++++++++++ release/io/netrender/ui.py | 1 + release/io/netrender/utils.py | 5 +++-- 6 files changed, 68 insertions(+), 14 deletions(-) diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py index 62b6dcee519..b1a461bf0ca 100644 --- a/release/io/netrender/balancing.py +++ b/release/io/netrender/balancing.py @@ -71,14 +71,14 @@ class NewJobPriority(PriorityRule): self.limit = limit def test(self, job): - return job.countFrames(status = DISPATCHED) < self.limit + return job.countFrames(status = DONE) < self.limit class MinimumTimeBetweenDispatchPriority(PriorityRule): def __init__(self, limit = 10): self.limit = limit def test(self, job): - return (time.time() - job.last_dispatched) / 60 > self.limit + return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit class ExcludeQueuedEmptyJob(ExclusionRule): def test(self, job): @@ -91,4 +91,4 @@ class ExcludeSlavesLimit(ExclusionRule): self.limit = limit def test(self, job): - return not ( self.count_jobs() == 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) \ No newline at end of file + return not ( self.count_jobs() == 1 or self.count_slaves() == 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 0e3c7063cab..84a6ad8cca1 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -50,6 +50,7 @@ class MRenderJob(netrender.model.RenderJob): self.last_dispatched = time.time() # special server properties + self.last_update = 0 self.save_path = "" self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} self.status = JOB_WAITING @@ -68,13 +69,23 @@ class MRenderJob(netrender.model.RenderJob): self.start() return True + def testFinished(self): + for f in self.frames: + if f.status == QUEUED or f.status == DISPATCHED: + break + else: + self.status = JOB_FINISHED + def start(self): self.status = JOB_QUEUED - + def update(self): - self.credits -= 5 # cost of one frame - self.credits += (time.time() - self.last_dispatched) / 60 - self.last_dispatched = time.time() + if self.last_update == 0: + self.credits += (time.time() - self.last_dispatched) / 60 + else: + self.credits += (time.time() - self.last_update) / 60 + + self.last_update = time.time() def addLog(self, frames): log_name = "_".join(("%04d" % f for f in frames)) + ".log" @@ -98,7 +109,8 @@ class MRenderJob(netrender.model.RenderJob): frames = [] for f in self.frames: if f.status == QUEUED: - self.update() + self.credits -= 1 # cost of one frame + self.last_dispatched = time.time() frames.append(f) if len(frames) >= self.chunks: break @@ -512,7 +524,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_time = float(self.headers['job-time']) frame = job[job_frame] - + if job_result == DONE: length = int(self.headers['content-length']) buf = self.rfile.read(length) @@ -527,6 +539,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): frame.status = job_result frame.time = job_time + + job.testFinished() self.server.updateSlave(self.headers['slave-id']) @@ -581,7 +595,7 @@ class RenderMasterServer(http.server.HTTPServer): self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves)) self.balancer.addPriority(netrender.balancing.NewJobPriority()) - self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority()) + self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority(limit = 2)) if not os.path.exists(self.path): os.mkdir(self.path) @@ -612,6 +626,8 @@ class RenderMasterServer(http.server.HTTPServer): self.jobs = [] def update(self): + for job in self.jobs: + job.update() self.balancer.balance(self.jobs) def countJobs(self, status = JOB_QUEUED): diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py index 6a337c8d71d..8e11c86a88c 100644 --- a/release/io/netrender/master_html.py +++ b/release/io/netrender/master_html.py @@ -52,11 +52,13 @@ def get(handler): output("

Jobs

") startTable() - headerTable("id", "name", "length", "done", "dispatched", "error") + headerTable("id", "name", "credits", "time since last", "length", "done", "dispatched", "error", "priority", "exception") + + handler.server.update() for job in handler.server.jobs: results = job.framesStatus() - rowTable(link(job.id, "/html/job" + job.id), job.name, len(job), results[DONE], results[DISPATCHED], results[ERROR]) + rowTable(link(job.id, "/html/job" + job.id), job.name, round(job.credits, 1), int(time.time() - job.last_dispatched), len(job), results[DONE], results[DISPATCHED], results[ERROR], handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)) endTable() diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index bfc67c25285..498edd74529 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -262,12 +262,46 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): response = conn.getresponse() print( response.status, response.reason ) + + netsettings.jobs.remove(netsettings.active_job_index) return ('FINISHED',) def invoke(self, context, event): return self.execute(context) +@rnaOperator +class RENDER_OT_netclientcancelall(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientcancelall" + __label__ = "Net Render Client Cancel All" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + conn.request("POST", "/cancel") + + response = conn.getresponse() + print( response.status, response.reason ) + + while(len(netsettings.jobs) > 0): + netsettings.jobs.remove(0) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + @rnaOperator class netclientdownload(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 2ec0b62de4a..3aad8362c43 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -165,6 +165,7 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): subcol = col.column(align=True) subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + subcol.itemO("render.netclientcancelall", icon="ICON_ZOOMOUT", text="") subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py index 62288aecf94..06393a738a0 100644 --- a/release/io/netrender/utils.py +++ b/release/io/netrender/utils.py @@ -11,7 +11,8 @@ VERSION = b"0.5" # Jobs status JOB_WAITING = 0 # before all data has been entered JOB_PAUSED = 1 # paused by user -JOB_QUEUED = 2 # ready to be dispatched +JOB_FINISHED = 2 # finished rendering +JOB_QUEUED = 3 # ready to be dispatched # Frames status QUEUED = 0 @@ -82,4 +83,4 @@ def prefixPath(prefix_directory, file_path, prefix_path): else: full_path = prefix_directory + file_path - return full_path \ No newline at end of file + return full_path -- cgit v1.2.3 From 0c68fe3a61f9927dbc5c5d402c600743c611a8a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 01:32:23 +0000 Subject: brush curve - use clamped values (0-1) for everything except sculpt which can have positive and negative values. --- source/blender/blenkernel/BKE_brush.h | 3 ++- source/blender/blenkernel/intern/brush.c | 27 ++++++++++++++++------- source/blender/editors/sculpt_paint/paint_image.c | 2 +- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 01566648557..f302618e60d 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -60,7 +60,8 @@ typedef enum { BRUSH_PRESET_MAX } BrushCurvePreset; void brush_curve_preset(struct Brush *b, BrushCurvePreset preset); -float brush_curve_strength(struct Brush *br, float p, const float len); +float brush_curve_strength_clamp(struct Brush *br, float p, const float len); +float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */ /* sampling */ void brush_sample_tex(struct Brush *brush, float *xy, float *rgba); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 6c3c97399e4..115d31b587c 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -442,7 +442,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); VECCOPY(dstf, brush->rgb); - dstf[3]= brush->alpha*brush_curve_strength(brush, dist, maxsize); + dstf[3]= brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize); } else if (texfall == 1) { brush_sample_tex(brush, xy, dstf); @@ -455,7 +455,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dstf[0] = rgba[0]*brush->rgb[0]; dstf[1] = rgba[1]*brush->rgb[1]; dstf[2] = rgba[2]*brush->rgb[2]; - dstf[3] = rgba[3]*brush->alpha*brush_curve_strength(brush, dist, maxsize); + dstf[3] = rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize); } } } @@ -494,7 +494,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]); dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]); dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]); - dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength(brush, dist, maxsize)); + dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize)); } } } @@ -952,12 +952,23 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl } /* Uses the brush curve control to find a strength value between 0 and 1 */ +float brush_curve_strength_clamp(Brush *br, float p, const float len) +{ + if(p >= len) p= 1.0f; + else p= p/len; + + p= curvemapping_evaluateF(br->curve, 0, p); + if(p < 0.0) p= 0.0f; + else if(p > 1.0f) p= 1.0f; + return p; +} +/* same as above but can return negative values if the curve enables + * used for sculpt only */ float brush_curve_strength(Brush *br, float p, const float len) { - float f; - if(p > len) p= len; - f= curvemapping_evaluateF(br->curve, 0, p/len); - return (f > 0.0f) ? f:0.0f; + if(p >= len) p= 1.0f; + else p= p/len; + return curvemapping_evaluateF(br->curve, 0, p); } /* TODO: should probably be unified with BrushPainter stuff? */ @@ -1024,7 +1035,7 @@ static struct ImBuf *brush_gen_radial_control_imbuf(Brush *br) for(i=0; irect_float[i*side + j]= brush_curve_strength(br, magn, half); + im->rect_float[i*side + j]= brush_curve_strength_clamp(br, magn, half); } } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 91ee2fa55d1..d223c423690 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -3731,7 +3731,7 @@ static void *do_projectpaint_thread(void *ph_v) /*if (dist < s->brush->size) {*/ /* correct but uses a sqrtf */ if (dist_nosqrt < brush_size_sqared && (dist=sqrtf(dist_nosqrt)) < size_half) { - falloff = brush_curve_strength(ps->brush, dist, size_half); + falloff = brush_curve_strength_clamp(ps->brush, dist, size_half); if (falloff > 0.0f) { if (ps->is_texbrush) { brush_sample_tex(ps->brush, projPixel->projCoSS, rgba); -- cgit v1.2.3 From 20998fdcfa6e7dd74adc0f38af6135fdddbefdc0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 06:48:03 +0000 Subject: Use Shift+F for fly-mode (like 2.4x) rather then Any+F --- source/blender/editors/space_view3d/view3d_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 06480d3e2db..23dd092ce38 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -124,7 +124,7 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center", PADPERIOD, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_ANY, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0); -- cgit v1.2.3 From b94ed5d7e469c6c3ea421919138da8c04a3f01e3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 07:03:18 +0000 Subject: - cmake/make/scons didnt define INTERNATIONAL when buidling blenfont - BLF_lang_init used confusing IFDEF's, unlikely this was well tested. Split this into 3 functions for Apple/Win32/Unix, Unix uses BLI_gethome_folder(), cant test others, ideally they should use BLI_gethome_folder too but needs testing. Possibly each os cant be made to use BLI_gethome_folder and the separate func's can be removed (please test). - units, hectometers were displayed wrong. --- source/blender/blenfont/CMakeLists.txt | 1 + source/blender/blenfont/Makefile | 4 +++ source/blender/blenfont/SConscript | 8 +++-- source/blender/blenfont/intern/blf_lang.c | 55 +++++++++++++++++-------------- source/blender/blenkernel/intern/unit.c | 4 +-- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index 844a6899bf5..9b7e950526d 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -32,6 +32,7 @@ SET(INC IF(WITH_INTERNATIONAL) SET(INC ${INC} ${GETTEXT_INC}) + ADD_DEFINITIONS(-DINTERNATIONAL) ENDIF(WITH_INTERNATIONAL) IF(WIN32) diff --git a/source/blender/blenfont/Makefile b/source/blender/blenfont/Makefile index 70dd2e5052b..be62c87cbf4 100644 --- a/source/blender/blenfont/Makefile +++ b/source/blender/blenfont/Makefile @@ -28,3 +28,7 @@ SOURCEDIR = source/blender/blenfont DIRS = intern include nan_subdirs.mk + +ifeq ($(INTERNATIONAL), true) + CPPFLAGS += -DINTERNATIONAL +endif diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index d070d985247..91edc46ba8b 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/SConscript @@ -9,9 +9,13 @@ incs += ' #/extern/glew/include' incs += ' ' + env['BF_FREETYPE_INC'] incs += ' ' + env['BF_GETTEXT_INC'] -defs = '' +defs = [] if sys.platform == 'win32': - defs += ' _WIN32 USE_GETTEXT_DLL' + defs.append('_WIN32') + defs.append('USE_GETTEXT_DLL') + +if env['WITH_BF_INTERNATIONAL']: + defs.append('INTERNATIONAL') env.BlenderLib ( 'bf_blenfont', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[210,210] ) diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 024172d6db4..ed684eda46f 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -60,17 +60,14 @@ char global_messagepath[1024]; char global_language[32]; char global_encoding_name[32]; - -void BLF_lang_init(void) +#if defined(__APPLE__) +void BLF_lang_init(void) /* Apple Only, todo - use BLI_gethome_folder */ { -#ifdef __APPLE__ char *bundlepath; -#endif strcpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT); /* set messagepath directory */ - #ifndef LOCALEDIR #define LOCALEDIR "/usr/share/locale" #endif @@ -81,44 +78,52 @@ void BLF_lang_init(void) BLI_make_file_string("/", global_messagepath, BLI_gethome(), ".blender/locale"); if (!BLI_exist(global_messagepath)) { /* locale not in home dir */ -#ifdef WIN32 - BLI_make_file_string("/", global_messagepath, BLI_gethome(), "/locale"); - if (!BLI_exist(global_messagepath)) { -#endif -#ifdef __APPLE__ /* message catalogs are stored inside the application bundle */ bundlepath= BLI_getbundle(); strcpy(global_messagepath, bundlepath); strcat(global_messagepath, "/Contents/Resources/locale"); if (!BLI_exist(global_messagepath)) { /* locale not in bundle (now that's odd..) */ -#endif strcpy(global_messagepath, LOCALEDIR); if (!BLI_exist(global_messagepath)) { /* locale not in LOCALEDIR */ strcpy(global_messagepath, "message"); /* old compatibility as last */ } -#ifdef WIN32 } -#endif -#ifdef __APPLE__ - } -#endif } } } - -void BLF_lang_set(const char *str) +#elif defined(_WIN32) +void BLF_lang_init(void) /* Windows Only, todo - use BLI_gethome_folder */ { -#if defined (_WIN32) || defined(__APPLE__) - char envstr[12]; + strcpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT); + + strcpy(global_messagepath, ".blender/locale"); + + if (!BLI_exist(global_messagepath)) { /* locale not in current dir */ + BLI_make_file_string("/", global_messagepath, BLI_gethome(), ".blender/locale"); - sprintf(envstr, "LANG=%s", str); - envstr[strlen(envstr)]= '\0'; -#ifdef _WIN32 - gettext_putenv(envstr); + if (!BLI_exist(global_messagepath)) { /* locale not in home dir */ + BLI_make_file_string("/", global_messagepath, BLI_gethome(), "/locale"); + } + } +} #else - putenv(envstr); +void BLF_lang_init(void) /* not win or mac */ +{ + char *messagepath= BLI_gethome_folder("locale", BLI_GETHOME_ALL); + + if(messagepath) + strncpy(global_messagepath, messagepath, sizeof(global_messagepath)); + else + global_messagepath[0]= '\0'; + +} #endif + +void BLF_lang_set(const char *str) +{ +#if defined (_WIN32) || defined(__APPLE__) + BLI_setenv("LANG", str); #else char *locreturn= setlocale(LC_ALL, str); if (locreturn == NULL) { diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index f8e3b3c5ad2..1f72c894cc8 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -75,7 +75,7 @@ static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0, sizeof(buDum /* Lengths */ static struct bUnitDef buMetricLenDef[] = { {"kilometer", "kilometers", "km", NULL, "Kilometers", 1000.0, 0.0, B_UNIT_DEF_NONE}, - {"hectometer", "hectometers", "hm", NULL, "10 Meters", 100.0, 0.0, B_UNIT_DEF_SUPPRESS}, + {"hectometer", "hectometers", "hm", NULL, "100 Meters", 100.0, 0.0, B_UNIT_DEF_SUPPRESS}, {"dekameter", "dekameters", "dkm",NULL, "10 Meters", 10.0, 0.0, B_UNIT_DEF_SUPPRESS}, {"meter", "meters", "m", NULL, "Meters", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"decimetre", "decimetres", "dm", NULL, "10 Centimeters", 0.1, 0.0, B_UNIT_DEF_SUPPRESS}, @@ -485,7 +485,7 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre if(unit==NULL) unit= unit_default(usys); - /* add the unit prefic and re-run, use brackets incase there was an expression given */ + /* add the unit prefix and re-run, use brackets incase there was an expression given */ if(snprintf(str_tmp, sizeof(str_tmp), "(%s)%s", str, unit->name) < sizeof(str_tmp)) { strncpy(str, str_tmp, len_max); return bUnit_ReplaceString(str, len_max, NULL, scale_pref, system, type); -- cgit v1.2.3 From 3e59a88450b9a26b09e671e38170b0f6f17a9182 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 24 Sep 2009 09:29:59 +0000 Subject: Fix compilation problem in Windows and update project files --- projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj | 8 ++++++++ projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj | 16 ++++++++++++++++ .../gameengine/blenderhook/KX_blenderhook.vcproj | 4 ++-- source/blender/blenlib/BLI_winstuff.h | 6 ++++++ source/blender/blenlib/intern/BLI_bfile.c | 7 ++++++- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj index a6630c81aca..6d111ea4b4f 100644 --- a/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj +++ b/projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj @@ -482,6 +482,10 @@ RelativePath="..\..\..\source\blender\blenlib\intern\arithb.c" > + + @@ -619,6 +623,10 @@ RelativePath="..\..\..\source\blender\blenlib\BLI_arithb.h" > + + diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj index a9d78d8b69a..227b4856143 100644 --- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj +++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj @@ -602,6 +602,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_action.c" > + + @@ -682,6 +686,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_image.c" > + + @@ -706,6 +714,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_material.c" > + + @@ -754,6 +766,10 @@ RelativePath="..\..\..\source\blender\makesrna\intern\rna_pose.c" > + + diff --git a/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj b/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj index ea387c4e976..4d3d74ca949 100644 --- a/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj +++ b/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj @@ -43,7 +43,7 @@ -#include +#ifndef WIN32 + #include +#else + #include +#include "BLI_winstuff.h" +#endif #include #include -- cgit v1.2.3 From 71027be7f60bf55b8961c06f33a579cdef0f5cd8 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 24 Sep 2009 10:04:43 +0000 Subject: Fix more problem with mingw this time --- source/blender/blenlib/BLI_winstuff.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index 03828bf6bf3..69dbb0acdb9 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -91,11 +91,14 @@ extern "C" { typedef unsigned int mode_t; #endif +#ifndef _SSIZE_T_ +#define _SSIZE_T_ #if defined(_WIN64) typedef __int64 ssize_t; #else typedef _W64 int ssize_t; #endif +#endif struct dirent { int d_ino; -- cgit v1.2.3 From f16d2b7eaac2f9225075d85e3d570e437407d513 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 10:35:04 +0000 Subject: fix for middle mouse up events not working with modal keymaps (used for fly mode). With mouse events event->val started as 0/1 for press/release but later the tweak function made LMB and RMB zero value into KM_RELEASE, somehow MMB didnt get used by the tweak function so was left at 0 and the modal keymap function failed when comparing MMB Mouse ups. now initialize event->val as KM_PRESS/KM_RELEASE --- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/armature/editarmature_sketch.c | 2 +- source/blender/editors/interface/interface_handlers.c | 2 +- source/blender/editors/interface/view2d_ops.c | 6 +++--- source/blender/editors/mesh/loopcut.c | 2 +- source/blender/editors/screen/screen_ops.c | 8 ++++---- source/blender/editors/sculpt_paint/paint_stroke.c | 2 +- source/blender/editors/space_image/image_ops.c | 4 ++-- source/blender/editors/space_node/node_select.c | 2 +- source/blender/editors/space_view3d/view3d_edit.c | 6 +++--- source/blender/windowmanager/intern/wm_event_system.c | 10 +++++----- source/blender/windowmanager/intern/wm_operators.c | 8 ++++---- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 80077a6d4b3..40c5b8893a1 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -193,7 +193,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init * the modal op) doesn't work for some reason */ - if (event->val==0) { + if (event->val==KM_RELEASE) { change_frame_exit(C, op); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 7f2f2a3410c..74876691dac 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -2675,7 +2675,7 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short retval = OPERATOR_CANCELLED; break; case LEFTMOUSE: - if (event->val == 0) + if (event->val == KM_RELEASE) { if (gesture == 0) { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 01a8f983dc6..b5de855cb80 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1660,7 +1660,7 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u break; } case LEFTMOUSE: - if(event->val == 0) + if(event->val == KM_RELEASE) button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); retval= WM_UI_HANDLER_BREAK; break; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index ae4fe4eed1b..0af5a5cac97 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -237,7 +237,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case MIDDLEMOUSE: - if (event->val==0) { + if (event->val==KM_RELEASE) { /* calculate overall delta mouse-movement for redo */ RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx)); RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty)); @@ -836,7 +836,7 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case MIDDLEMOUSE: - if (event->val==0) { + if (event->val==KM_RELEASE) { /* for redo, store the overall deltas - need to respect zoom-locks here... */ if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) RNA_float_set(op->ptr, "deltax", vzd->dx); @@ -1244,7 +1244,7 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event) break; case LEFTMOUSE: - if (event->val==0) { + if (event->val==KM_RELEASE) { scroller_activate_exit(C, op); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index c322a169679..1adac71f40e 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -380,7 +380,7 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) switch (event->type) { case RIGHTMOUSE: case LEFTMOUSE: /* confirm */ // XXX hardcoded - if (event->val == 0) { + if (event->val == KM_RELEASE) { /* finish */ ED_region_tag_redraw(lcd->ar); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5cd992eabe9..5f7be1fd2bc 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -604,7 +604,7 @@ static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event) sad->sa2= screen_areahascursor(CTX_wm_screen(C), event->x, event->y); break; case LEFTMOUSE: /* release LMB */ - if(event->val==0) { + if(event->val==KM_RELEASE) { if(!sad->sa2 || sad->sa1 == sad->sa2) { return area_swap_cancel(C, op); @@ -1225,7 +1225,7 @@ static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event) break; case LEFTMOUSE: - if(event->val==0) { /* mouse up */ + if(event->val==KM_RELEASE) { /* mouse up */ area_split_exit(C, op); return OPERATOR_FINISHED; } @@ -1345,7 +1345,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) break; case LEFTMOUSE: - if(event->val==0) { + if(event->val==KM_RELEASE) { if(ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) { if(rmd->ar->flag & RGN_FLAG_HIDDEN) { @@ -1828,7 +1828,7 @@ static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event) } break; case LEFTMOUSE: - if(event->val==0) { + if(event->val==KM_RELEASE) { area_join_apply(C, op); WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); area_join_exit(C, op); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index bd9ea50e0f8..b83352ae70c 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -263,7 +263,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event) } /* TODO: fix hardcoded event here */ - if(event->type == LEFTMOUSE && event->val == 0) { + if(event->type == LEFTMOUSE && event->val == KM_RELEASE) { /* Exit stroke, free data */ if(stroke->smooth_stroke_cursor) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 483d2fc6043..317a058d20e 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -224,7 +224,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) view_pan_exec(C, op); break; case MIDDLEMOUSE: - if(event->val==0) { + if(event->val==KM_RELEASE) { view_pan_exit(C, op, 0); return OPERATOR_FINISHED; } @@ -339,7 +339,7 @@ static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) ED_area_tag_redraw(CTX_wm_area(C)); break; case MIDDLEMOUSE: - if(event->val==0) { + if(event->val==KM_RELEASE) { view_zoom_exit(C, op, 0); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 94691dd0ed2..5e482758c9d 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -140,7 +140,7 @@ static int node_select_modal(bContext *C, wmOperator *op, wmEvent *event) printf("%d %d\n", event->x, event->y); break; case SELECTMOUSE: - //if (event->val==0) { + //if (event->val==KM_RELEASE) { /* calculate overall delta mouse-movement for redo */ printf("done translating\n"); //WM_cursor_restore(CTX_wm_window(C)); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 24ec0d124c6..5e3a6ae0e02 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -505,7 +505,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) default: /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) { + if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==KM_RELEASE)) { request_depth_update(CTX_wm_region_view3d(C)); MEM_freeN(vod); @@ -606,7 +606,7 @@ static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) default: /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) { + if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==KM_RELEASE)) { request_depth_update(CTX_wm_region_view3d(C)); MEM_freeN(vod); @@ -767,7 +767,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event) default: /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==0)) { + if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==KM_RELEASE)) { request_depth_update(CTX_wm_region_view3d(C)); MEM_freeN(vod); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 03e13329bbd..af1339323f3 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1004,7 +1004,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) int always_pass; if(handlers==NULL) return action; - + /* modal handlers can get removed in this loop, we keep the loop this way */ for(handler= handlers->first; handler; handler= nexthandler) { nexthandler= handler->next; @@ -1157,7 +1157,7 @@ void wm_event_do_handlers(bContext *C) while( (event= win->queue.first) ) { int action; - + CTX_wm_window_set(C, win); /* we let modal handlers get active area/region, also wm_paintcursor_test needs it */ @@ -1176,7 +1176,7 @@ void wm_event_do_handlers(bContext *C) /* builtin tweak, if action is break it removes tweak */ wm_tweakevent_test(C, event, action); - + if(action==WM_HANDLER_CONTINUE) { ScrArea *sa; ARegion *ar; @@ -1189,7 +1189,7 @@ void wm_event_do_handlers(bContext *C) /* for regions having custom cursors */ wm_paintcursor_test(C, event); } - + for(sa= win->screen->areabase.first; sa; sa= sa->next) { if(wm_event_inside_i(event, &sa->totrct)) { CTX_wm_area_set(C, sa); @@ -1575,7 +1575,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd= customdata; - event.val= (type==GHOST_kEventButtonDown); + event.val= (type==GHOST_kEventButtonDown) ? KM_PRESS:KM_RELEASE; /* Note!, this starts as 0/1 but later is converted to KM_PRESS/KM_RELEASE by tweak */ if (bd->button == GHOST_kButtonMaskLeft) event.type= LEFTMOUSE; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 0b5c2944624..486a887b354 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1485,7 +1485,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: - if(event->val==0) { /* key release */ + if(event->val==KM_RELEASE) { /* key release */ wm_gesture_end(C, op); return OPERATOR_FINISHED; } @@ -1568,7 +1568,7 @@ static void tweak_gesture_modal(bContext *C, wmEvent *event) if(gesture->event_type==event->type) { WM_gesture_end(C, gesture); window->tweak= NULL; - + /* when tweak fails we should give the other keymap entries a chance */ event->val= KM_RELEASE; } @@ -1586,7 +1586,7 @@ void wm_tweakevent_test(bContext *C, wmEvent *event, int action) if(win->tweak==NULL) { if(CTX_wm_region(C)) { - if(event->val) { // pressed + if(event->val==KM_PRESS) { // pressed if( ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) ) win->tweak= WM_gesture_new(C, event, WM_GESTURE_TWEAK); } @@ -1686,7 +1686,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: - if(event->val==0) { /* key release */ + if(event->val==KM_RELEASE) { /* key release */ gesture_lasso_apply(C, op, event->type); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 813f292fc961300343ff5c6b94591d69a69f7890 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 24 Sep 2009 10:41:28 +0000 Subject: 3rd attempt to fix ssize_t problem in MSVC and mingw --- source/blender/blenlib/BLI_winstuff.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index 69dbb0acdb9..3de4981417a 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -91,12 +91,13 @@ extern "C" { typedef unsigned int mode_t; #endif +/* mingw using _SSIZE_T_ to declare ssize_t type */ #ifndef _SSIZE_T_ #define _SSIZE_T_ -#if defined(_WIN64) -typedef __int64 ssize_t; -#else -typedef _W64 int ssize_t; +/* python uses HAVE_SSIZE_T */ +#ifndef HAVE_SSIZE_T +#define HAVE_SSIZE_T 1 +typedef long ssize_t; #endif #endif -- cgit v1.2.3 From 300df490601a4267a9c77239b5638e494672a38f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 24 Sep 2009 10:46:52 +0000 Subject: Fix #19446: merge operator needs to be undone twice, interface was still doing undo pushes in cases it was not needed. --- source/blender/editors/interface/interface.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index f79f2f8c378..1b05958b679 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2271,8 +2271,9 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short } } - if(!ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, SEARCH_MENU)) - but->flag |= UI_BUT_UNDO; + if(ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, SEARCH_MENU, BUTM)); + else if(ELEM5(but->type, SCROLL, SEPR, LINK, INLINK, FTPREVIEW)); + else but->flag |= UI_BUT_UNDO; BLI_addtail(&block->buttons, but); -- cgit v1.2.3 From 4aade8ad7e2e0f941579533fcedb51a87704af18 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 11:37:33 +0000 Subject: fix for [#19437] Console (Python): first run doesn't have the ">>>" --- source/blender/editors/space_console/space_console.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 234f3b5baf2..19fb575ed16 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -174,6 +174,9 @@ static void console_main_area_draw(const bContext *C, ARegion *ar) console_scrollback_add_str(C, "Autocomplete: Ctrl+Space", 0); console_scrollback_add_str(C, "Ctrl +/- Wheel: Zoom", 0); console_scrollback_add_str(C, "Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.ui", 0); + + /* This is normally set by python but to start with its easier just to set it like this rather then running python with no args */ + strcpy(sc->prompt, ">>> "); } /* clear and setup matrix */ -- cgit v1.2.3 From 24128d2e862773200da935310b4ba8a08733a8d3 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 24 Sep 2009 11:46:17 +0000 Subject: mingw - silencing the warnings about '#pragma' warnings being unrecognised or being ignored. This should still work fine for msvc, and other platforms though. --- source/blender/blenlib/BLI_winstuff.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index 3de4981417a..bbdbc2def8d 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -28,7 +28,10 @@ * * ***** END GPL LICENSE BLOCK ***** */ + +#ifndef FREE_WINDOWS #pragma warning(once: 4761 4305 4244 4018) +#endif #define WIN32_LEAN_AND_MEAN -- cgit v1.2.3 From be380138f123b42334e06d450ce42cad7208b2e0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 24 Sep 2009 12:15:17 +0000 Subject: Fix for panorama backwards compatibility not working correct. --- source/blender/blenloader/intern/readfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d9db02e630f..d26a2a79f05 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9366,7 +9366,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) strcpy(sce->nodetree->id.name, "NTComposit Nodetree"); /* move to cameras */ - if(sce->r.scemode & R_PANORAMA) { + if(sce->r.mode & R_PANORAMA) { for(base=sce->base.first; base; base=base->next) { ob= newlibadr(fd, lib, base->object); @@ -9376,7 +9376,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - sce->r.scemode &= ~R_PANORAMA; + sce->r.mode &= ~R_PANORAMA; } } /* and texture trees */ -- cgit v1.2.3 From b0785030580735bc09a1d5037b070849bbb10775 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 12:27:20 +0000 Subject: imagewrap was using uninitialized vars from do_material_tex found while looking into a different bug. --- source/blender/render/intern/source/texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 2d2c01e0bf1..f25a167600f 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1631,7 +1631,7 @@ void do_material_tex(ShadeInput *shi) float fact, facm, factt, facmm, stencilTin=1.0; float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0; int tex_nr, rgbnor= 0, warpdone=0; - float nu[3], nv[3], nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping + float nu[3] = {0,0,0}, nv[3] = {0,0,0}, nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping int nunvdone= 0; if (R.r.scemode & R_NO_TEX) return; -- cgit v1.2.3 From a8bb3136294268cd4762986699b773688b543679 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Sep 2009 15:36:00 +0000 Subject: add buildinfo to cmake (no win32 support) --- CMakeLists.txt | 20 ++++++++++---------- source/creator/CMakeLists.txt | 20 ++++++++++++++++---- source/creator/creator.c | 1 + 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 504ef5d8dd8..92c670f572c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ OPTION(WITH_FFTW3 "Enable FFTW3 support" OFF) OPTION(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF) OPTION(WITH_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF) OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF) -# OPTION(WITH_BUILDINFO "Include extra build details" ON) +OPTION(WITH_BUILDINFO "Include extra build details" ON) OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) @@ -517,15 +517,15 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") -# TODO - buildinfo -# IF(UNIX) -# IF(WITH_BUILDINFO) -# EXEC_PROGRAM("date \"+%Y-%m-%d\"" OUTPUT_VARIABLE BUILD_DATE) -# EXEC_PROGRAM("date \"+%H:%M:%S\"" OUTPUT_VARIABLE BUILD_TIME) -# EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV) -# SET(BUILD_TYPE ${CMAKE_BUILD_TYPE}) -# ENDIF(WITH_BUILDINFO) -# ENDIF(UNIX) +# buildinfo +IF(UNIX) + IF(WITH_BUILDINFO) + EXEC_PROGRAM("date \"+%Y-%m-%d\"" OUTPUT_VARIABLE BUILD_DATE) + EXEC_PROGRAM("date \"+%H:%M:%S\"" OUTPUT_VARIABLE BUILD_TIME) + EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV) + # BUILD_PLATFORM and BUILD_PLATFORM are taken from CMake + ENDIF(WITH_BUILDINFO) +ENDIF(UNIX) #----------------------------------------------------------------------------- # Common. diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 410e0808580..51a52ee6861 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -78,14 +78,26 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") INCLUDE_DIRECTORIES(${BINRELOC_INC}) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") -MESSAGE(STATUS "Configuring blender") +# Setup the exe sources and buildinfo +SET(EXESRC creator.c) IF(WIN32) - ADD_EXECUTABLE(blender ${EXETYPE} creator.c ../icons/winblender.rc) -ELSE(WIN32) - ADD_EXECUTABLE(blender ${EXETYPE} creator.c) + SET(EXESRC ${EXESRC} ../icons/winblender.rc) ENDIF(WIN32) +IF(WITH_BUILDINFO) + ADD_DEFINITIONS(-DBUILD_DATE="${BUILD_DATE}") + ADD_DEFINITIONS(-DBUILD_TIME="${BUILD_TIME}") + ADD_DEFINITIONS(-DBUILD_REV="${BUILD_REV}") + ADD_DEFINITIONS(-DBUILD_PLATFORM="${CMAKE_SYSTEM_NAME}") + ADD_DEFINITIONS(-DBUILD_TYPE="${CMAKE_BUILD_TYPE}") + + SET(EXESRC ${EXESRC} buildinfo.c) +ENDIF(WITH_BUILDINFO) + +MESSAGE(STATUS "Configuring blender") + +ADD_EXECUTABLE(blender ${EXETYPE} ${EXESRC}) # Post build steps for bundling/packaging. diff --git a/source/creator/creator.c b/source/creator/creator.c index 579825b805a..6f64628b467 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -101,6 +101,7 @@ #ifdef BUILD_DATE extern char * build_date; extern char * build_time; +extern char * build_rev; extern char * build_platform; extern char * build_type; #endif -- cgit v1.2.3 From 22d027dcb2f46fc7db359834b8f58c4120bf2c78 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Thu, 24 Sep 2009 16:18:17 +0000 Subject: fixed some indentation, and removed declaration of index in a couple of places because it was already defined and safe to use the old def. Kent --- intern/smoke/intern/FLUID_3D_STATIC.cpp | 38 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index 2d3ec125c2b..0215dfc417f 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -54,23 +54,21 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res) float yTotal = dx * res[1]; float zTotal = dx * res[2]; - float heighMin = 0.05; - float heighMax = 0.10; - - for (int y = 0; y < res[2]; y++) - for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++) - for (int x = 0; x < res[0]; x++) - { - float xLength = x * dx - xTotal * 0.4f; - float yLength = y * dx - yTotal * 0.5f; - float radius = sqrtf(xLength * xLength + yLength * yLength); - - if (radius < 0.075f * xTotal) - { - int index = x + y * res[0] + z * slabSize; - field[index] = 1.0f; - } - } + float heighMin = 0.05; + float heighMax = 0.10; + + for (int y = 0; y < res[2]; y++) + for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++) + for (int x = 0; x < res[0]; x++) { + float xLength = x * dx - xTotal * 0.4f; + float yLength = y * dx - yTotal * 0.5f; + float radius = sqrtf(xLength * xLength + yLength * yLength); + + if (radius < 0.075f * xTotal) { + int index = x + y * res[0] + z * slabSize; + field[index] = 1.0f; + } + } } @@ -98,7 +96,7 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res) for (int z = 0; z < res[2]; z++) { // top slab - int index = y * res[0] + z * slabSize; + index = y * res[0] + z * slabSize; index += res[0] - 1; if(field[index]<0.) field[index] = 0.; index -= 1; @@ -130,7 +128,7 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res) for (int x = 0; x < res[0]; x++) { // top slab - int index = x + z * slabSize; + index = x + z * slabSize; index += slabSize - res[0]; if(field[index]<0.) field[index] = 0.; index -= res[0]; @@ -164,7 +162,7 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res) for (int x = 0; x < res[0]; x++) { // top slab - int index = x + y * res[0]; + index = x + y * res[0]; index += totalCells - slabSize; if(field[index]<0.) field[index] = 0.; index -= slabSize; -- cgit v1.2.3 From 2a63c4ab7b55cd4eb4301b54e5ca934c71a5e3b4 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 24 Sep 2009 19:50:15 +0000 Subject: * fix snprintf error with mingw * move header guards to the right place. --- source/blender/blenlib/BLI_winstuff.h | 8 ++++---- source/gameengine/BlenderRoutines/KX_BlenderGL.cpp | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index bbdbc2def8d..757b3605203 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -29,6 +29,9 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef __WINSTUFF_H__ +#define __WINSTUFF_H__ + #ifndef FREE_WINDOWS #pragma warning(once: 4761 4305 4244 4018) #endif @@ -59,10 +62,7 @@ #undef small -#ifndef __WINSTUFF_H__ -#define __WINSTUFF_H__ - - // These definitions are also in arithb for simplicity +// These definitions are also in arithb for simplicity #ifdef __cplusplus extern "C" { diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index dba6d1113c9..bb02f3b372e 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -44,6 +44,7 @@ extern "C" { * This little block needed for linking to Blender... */ #ifdef WIN32 +#include #include "BLI_winstuff.h" #endif -- cgit v1.2.3 From ddb46e12f9489efa03e86e2e03efc19913d6c775 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 24 Sep 2009 19:52:32 +0000 Subject: netrender: draft code for cluster usage per job calculations. Eventually, this will be used for load balancing --- release/io/netrender/balancing.py | 2 +- release/io/netrender/master.py | 80 ++++++++++++++++++++++++++++++++----- release/io/netrender/master_html.py | 17 ++++++-- release/io/netrender/ui.py | 2 +- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py index b1a461bf0ca..c167594e1c5 100644 --- a/release/io/netrender/balancing.py +++ b/release/io/netrender/balancing.py @@ -91,4 +91,4 @@ class ExcludeSlavesLimit(ExclusionRule): self.limit = limit def test(self, job): - return not ( self.count_jobs() == 1 or self.count_slaves() == 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) + return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 84a6ad8cca1..8a0b0434bf3 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -29,7 +29,7 @@ class MRenderSlave(netrender.model.RenderSlave): self.last_seen = time.time() self.job = None - self.frame = None + self.job_frames = [] netrender.model.RenderSlave._slave_map[self.id] = self @@ -50,6 +50,7 @@ class MRenderJob(netrender.model.RenderJob): self.last_dispatched = time.time() # special server properties + self.usage = 0.0 self.last_update = 0 self.save_path = "" self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} @@ -300,6 +301,9 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): f.status = DISPATCHED f.slave = slave + slave.job = job + slave.job_frames = [f.number for f in frames] + self.send_head(headers={"job-id": job.id}) message = job.serialize(frames) @@ -536,7 +540,11 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): elif job_result == ERROR: # blacklist slave on this job on error job.blacklist.append(slave.id) - + + slave.job_frames.remove(job_frame) + if not slave.job_frames: + slave.job = None + frame.status = job_result frame.time = job_time @@ -590,6 +598,10 @@ class RenderMasterServer(http.server.HTTPServer): self.job_id = 0 self.path = path + "master_" + str(os.getpid()) + os.sep + self.slave_timeout = 2 + + self.first_usage = True + self.balancer = netrender.balancing.Balancer() self.balancer.addRule(netrender.balancing.RatingCredit()) self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) @@ -611,6 +623,10 @@ class RenderMasterServer(http.server.HTTPServer): return slave.id + def removeSlave(self, slave): + self.slaves.remove(slave) + self.slaves_map.pop(slave.id) + def getSlave(self, slave_id): return self.slaves_map.get(slave_id, None) @@ -621,9 +637,46 @@ class RenderMasterServer(http.server.HTTPServer): return slave + def timeoutSlaves(self): + removed = [] + + t = time.time() + + for slave in self.slaves: + if (t - slave.last_seen) / 60 > self.slave_timeout: + removed.append(slave) + + if slave.job: + for f in slave.job_frames: + slave.job[f].status = ERROR + + for slave in removed: + self.removeSlave(slave) + + def updateUsage(self): + m = 1.0 + + if not self.first_usage: + for job in self.jobs: + job.usage *= 0.5 + + m = 0.5 + else: + self.first_usage = False + + if self.slaves: + slave_usage = m / self.countSlaves() + + for slave in self.slaves: + if slave.job: + slave.job.usage += slave_usage + + def clear(self): - self.jobs_map = {} - self.jobs = [] + removed = self.jobs[:] + + for job in removed: + self.removeJob(job) def update(self): for job in self.jobs: @@ -646,6 +699,11 @@ class RenderMasterServer(http.server.HTTPServer): if job: self.jobs.remove(job) + + for slave in self.slaves: + if slave.job == job: + slave.job = None + slave.job_frames = [] def addJob(self, job): self.jobs.append(job) @@ -687,8 +745,12 @@ def runMaster(address, broadcast, path, update_stats, test_break): while not test_break(): httpd.handle_request() - if broadcast: - if time.time() - start_time >= 10: # need constant here - print("broadcasting address") - s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('', 8000)) - start_time = time.time() + if time.time() - start_time >= 10: # need constant here + httpd.timeoutSlaves() + + httpd.updateUsage() + + if broadcast: + print("broadcasting address") + s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('', 8000)) + start_time = time.time() diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py index 8e11c86a88c..bafc0f44b7f 100644 --- a/release/io/netrender/master_html.py +++ b/release/io/netrender/master_html.py @@ -42,23 +42,32 @@ def get(handler): output("

Slaves

") startTable() - headerTable("id", "name", "address", "stats") + headerTable("name", "address", "last seen", "stats", "job") for slave in handler.server.slaves: - rowTable(slave.id, slave.name, slave.address[0], slave.stats) + rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None") endTable() output("

Jobs

") startTable() - headerTable("id", "name", "credits", "time since last", "length", "done", "dispatched", "error", "priority", "exception") + headerTable("name", "credits", "usage", "time since last", "length", "done", "dispatched", "error", "priority", "exception") handler.server.update() for job in handler.server.jobs: results = job.framesStatus() - rowTable(link(job.id, "/html/job" + job.id), job.name, round(job.credits, 1), int(time.time() - job.last_dispatched), len(job), results[DONE], results[DISPATCHED], results[ERROR], handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)) + rowTable( link(job.name, "/html/job" + job.id), + round(job.credits, 1), + "%0.1f%%" % (job.usage * 100), + int(time.time() - job.last_dispatched), + len(job), + results[DONE], + results[DISPATCHED], + results[ERROR], + handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job) + ) endTable() diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 3aad8362c43..7ee0b64d150 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -165,7 +165,7 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): subcol = col.column(align=True) subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") - subcol.itemO("render.netclientcancelall", icon="ICON_ZOOMOUT", text="") + subcol.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: -- cgit v1.2.3 From ebfc93de214f308a4c76a7c64c5c4b0e45b2182d Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 24 Sep 2009 20:20:43 +0000 Subject: * explicit cast needed for mingw. --- source/gameengine/Expressions/PyObjectPlus.h | 4 ++-- source/gameengine/Ketsji/KX_PyMath.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index f9edb7877b0..d8ab007dde9 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -112,13 +112,13 @@ typedef struct PyObjectPlus_Proxy { static PyAttributeDef Attributes[]; \ virtual PyTypeObject *GetType(void) {return &Type;}; \ virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \ - virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \ + virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; #ifdef WITH_CXX_GUARDEDALLOC #define Py_Header __Py_Header \ void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \ - void operator delete( void *mem ) { MEM_freeN(mem); } \ + void operator delete( void *mem ) { MEM_freeN(mem); } #else #define Py_Header __Py_Header diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index 17102905607..1ce8bcafbb6 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -157,7 +157,7 @@ bool PyVecTo(PyObject* pyval, T& vec) return true; } - else if (PyObject_TypeCheck(pyval, &PyObjectPlus::Type)) + else if (PyObject_TypeCheck(pyval, (PyTypeObject *)&PyObjectPlus::Type)) { /* note, include this check because PySequence_Check does too much introspection * on the PyObject (like getting its __class__, on a BGE type this means searching up * the parent list each time only to discover its not a sequence. -- cgit v1.2.3 From c995c605f640d8d688e6e58e0fe247ca83f91696 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 24 Sep 2009 21:05:54 +0000 Subject: netrender: usage based balancer. more useful than credits --- release/io/netrender/balancing.py | 8 +++++++- release/io/netrender/master.py | 7 ++++--- release/io/netrender/master_html.py | 22 ++++++++++++++++++---- release/io/netrender/model.py | 3 +++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py index c167594e1c5..372ea7d95b7 100644 --- a/release/io/netrender/balancing.py +++ b/release/io/netrender/balancing.py @@ -64,7 +64,13 @@ class Balancer: class RatingCredit(RatingRule): def rate(self, job): - return -job.credits * job.priority # more credit is better (sort at first in list) + # more credit is better (sort at first in list) + return -job.credits * job.priority + +class RatingUsage(RatingRule): + def rate(self, job): + # less usage is better + return job.usage / job.priority class NewJobPriority(PriorityRule): def __init__(self, limit = 1): diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 8a0b0434bf3..1202b94840f 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -45,12 +45,12 @@ class MRenderJob(netrender.model.RenderJob): self.frames = [] self.chunks = chunks self.priority = priority + self.usage = 0.0 self.credits = credits self.blacklist = blacklist self.last_dispatched = time.time() # special server properties - self.usage = 0.0 self.last_update = 0 self.save_path = "" self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} @@ -603,9 +603,10 @@ class RenderMasterServer(http.server.HTTPServer): self.first_usage = True self.balancer = netrender.balancing.Balancer() - self.balancer.addRule(netrender.balancing.RatingCredit()) + #self.balancer.addRule(netrender.balancing.RatingCredit()) + self.balancer.addRule(netrender.balancing.RatingUsage()) self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) - self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves)) + self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9)) self.balancer.addPriority(netrender.balancing.NewJobPriority()) self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority(limit = 2)) diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py index bafc0f44b7f..7513971e6cf 100644 --- a/release/io/netrender/master_html.py +++ b/release/io/netrender/master_html.py @@ -52,22 +52,36 @@ def get(handler): output("

Jobs

") startTable() - headerTable("name", "credits", "usage", "time since last", "length", "done", "dispatched", "error", "priority", "exception") + headerTable( + "name", + "priority", + "credits", + "usage", + "wait", + "length", + "done", + "dispatched", + "error", + "first", + "exception" + ) handler.server.update() for job in handler.server.jobs: results = job.framesStatus() - rowTable( link(job.name, "/html/job" + job.id), + rowTable( + link(job.name, "/html/job" + job.id), + job.priority, round(job.credits, 1), "%0.1f%%" % (job.usage * 100), - int(time.time() - job.last_dispatched), + "%is" % int(time.time() - job.last_dispatched), len(job), results[DONE], results[DISPATCHED], results[ERROR], handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job) - ) + ) endTable() diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 9cacfb54a35..91a7c8a035f 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -81,6 +81,7 @@ class RenderJob: self.chunks = 0 self.priority = 0 self.credits = 0 + self.usage = 0.0 self.blacklist = [] self.last_dispatched = 0.0 @@ -143,6 +144,7 @@ class RenderJob: "frames": [f.serialize() for f in self.frames if not frames or f in frames], "chunks": self.chunks, "priority": self.priority, + "usage": self.usage, "credits": self.credits, "blacklist": self.blacklist, "last_dispatched": self.last_dispatched @@ -160,6 +162,7 @@ class RenderJob: job.frames = [RenderFrame.materialize(f) for f in data["frames"]] job.chunks = data["chunks"] job.priority = data["priority"] + job.usage = data["usage"] job.credits = data["credits"] job.blacklist = data["blacklist"] job.last_dispatched = data["last_dispatched"] -- cgit v1.2.3 From ee6cf88d4d1571afd2a6922b09937efd9ab6b622 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Thu, 24 Sep 2009 22:11:35 +0000 Subject: * some fixes to have scons/mingw compile the sources too, even with BF_DEBUG=1 and WITH_BF_GAMEENGINE=1 --- intern/itasc/kdl/utilities/utility.h | 3 ++- source/gameengine/Ketsji/SConscript | 2 +- source/gameengine/VideoTexture/SConscript | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/intern/itasc/kdl/utilities/utility.h b/intern/itasc/kdl/utilities/utility.h index e7dcc55d8a8..9c38eacbceb 100644 --- a/intern/itasc/kdl/utilities/utility.h +++ b/intern/itasc/kdl/utilities/utility.h @@ -254,7 +254,8 @@ inline double Norm(double arg) { return fabs( (double)arg ); } -#ifdef __WIN32__ + +#if defined(__WIN32__) && !defined(__GNUC__) inline double hypot(double y,double x) { return ::_hypot(y,x);} inline double abs(double x) { return ::fabs(x);} #endif diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 5f38020780b..b20da20d0e2 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -29,7 +29,7 @@ if env['WITH_BF_SDL']: else: defs.append('DISABLE_SDL') -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): +if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'): if env['BF_DEBUG']: defs.append('_DEBUG') # for Python diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 119bd1c9954..dac0b6d32ab 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -15,12 +15,11 @@ incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/m incs += ' #intern/guardedalloc #extern/glew/include' defs = [] -if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): +if env['OURPLATFORM'] in ('win32-vc', 'win64-vc','win32-mingw'): if env['BF_DEBUG']: defs.append('_DEBUG') incs += ' ' + env['BF_PYTHON_INC'] -#incs += ' ' + env['BF_OPENGL_INC'] if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') -- cgit v1.2.3 From 1305715d2d84f67027b870f263cef3a7f009c056 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 24 Sep 2009 22:55:57 +0000 Subject: *Added VlakPrimitive (this rayobject rimitive only stores ObjectRenderInstance and VlakRen pointers) - it difers from RayFace that localy stored the vertex coordinates. - basicaly this reduces memory usage --- source/blender/render/extern/include/RE_raytrace.h | 20 +- source/blender/render/intern/include/rayobject.h | 27 +- .../blender/render/intern/include/render_types.h | 3 + .../blender/render/intern/raytrace/rayobject.cpp | 529 +++++++++++++++++++++ source/blender/render/intern/source/rayobject.c | 493 ------------------- source/blender/render/intern/source/rayshade.c | 88 +++- .../blender/render/intern/source/renderdatabase.c | 5 + 7 files changed, 632 insertions(+), 533 deletions(-) create mode 100644 source/blender/render/intern/raytrace/rayobject.cpp delete mode 100644 source/blender/render/intern/source/rayobject.c diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index fe490461da0..f868e06d27c 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -52,6 +52,8 @@ typedef struct RayCounter RayCounter; struct DerivedMesh; struct Mesh; +struct VlakRen; +struct ObjectInstanceRen; int RE_rayobject_raycast(RayObject *r, Isect *i); void RE_rayobject_add (RayObject *r, RayObject *); @@ -93,14 +95,28 @@ typedef struct RayFace } RayFace; #define RE_rayface_isQuad(a) ((a)->quad) -struct VlakRen; -struct ObjectInstanceRen; RayObject* RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *co1, float *co2, float *co3, float *co4); +/* + * This ray object represents faces directly from a given VlakRen structure. + * Thus allowing to save memory, but making code triangle intersection dependant on render structures + */ +typedef struct VlakPrimitive +{ + struct ObjectInstanceRen *ob; + struct VlakRen *face; +} VlakPrimitive; + +RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); + + +/* + * Raytrace hints + */ typedef struct LCTSHint LCTSHint; struct LCTSHint { diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index dbd68fe8b8b..337f9ca3fdd 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -57,17 +57,18 @@ extern "C" { In order to allow a mixture of RayFace+RayObjects, all RayObjects must be 4byte aligned, allowing us to use the - 2 least significant bits (with the mask 0x02) to define the + 2 least significant bits (with the mask 0x03) to define the type of RayObject. - This leads to 4 possible types of RayObject, but at the moment - only 2 are used: + This leads to 4 possible types of RayObject: - addr&2 - type of object + addr&3 - type of object 0 Self (reserved for each structure) - 1 RayFace + 1 RayFace (tri/quad primitive) 2 RayObject (generic with API callbacks) - 3 RayObject_Vlak + 3 VlakPrimitive + (vlak primitive - to be used when we have a vlak describing the data + eg.: on render code) 0 means it's reserved and has it own meaning inside each ray acceleration structure (this way each structure can use the allign offset to determine if a node represents a @@ -83,25 +84,15 @@ extern "C" { /* used to unalign a given ray object */ #define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) #define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) -#define RE_rayobject_unalignRayVlak(o) ((RayObject*)(((intptr_t)o)|3)) +#define RE_rayobject_unalignVlakPrimitive(o) ((RayObject*)(((intptr_t)o)|3)) /* used to test the type of ray object */ #define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) #define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) #define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) -#define RE_rayobject_isRayVlak(o) ((((intptr_t)o)&3) == 3) +#define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3) -/* - * This ray object represents faces directly from a given VlakRen structure. - * Thus allowing to save memory, but making code dependant on render structures -typedef struct RayVlak -{ - struct ObjectInstanceRen *ob; - struct VlakRen *face; -} RayVlak; - */ - /* * This rayobject represents a generic object. With it's own callbacks for raytrace operations. * It's suitable to implement things like LOD. diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 67c69259213..8c106f60e1d 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -172,6 +172,7 @@ struct Render /* octree tables and variables for raytrace */ struct RayObject *raytree; struct RayFace *rayfaces; + struct VlakPrimitive *rayprimitives; float maxdist; /* needed for keeping an incorrect behaviour of SUN and HEMI lights (avoid breaking old scenes) */ /* occlusion tree */ @@ -289,6 +290,7 @@ typedef struct ObjectRen { /* used on makeraytree */ struct RayObject *raytree; struct RayFace *rayfaces; + struct VlakPrimitive *rayprimitives; struct ObjectInstanceRen *rayobi; } ObjectRen; @@ -313,6 +315,7 @@ typedef struct ObjectInstanceRen { /* used on makeraytree */ struct RayObject *raytree; + int transform_primitives; } ObjectInstanceRen; diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp new file mode 100644 index 00000000000..dc5128b2d1f --- /dev/null +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -0,0 +1,529 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#include + +#include "BKE_utildefines.h" +#include "BLI_arithb.h" +#include "DNA_material_types.h" + +#include "RE_raytrace.h" +#include "render_types.h" +#include "rayobject.h" +#include "raycounter.h" + +/* + * Determines the distance that the ray must travel to hit the bounding volume of the given node + * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe + * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] + */ +int RE_rayobject_bb_intersect_test(const Isect *isec, const float *_bb) +{ + const float *bb = _bb; + + float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; + float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; + float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; + float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; + float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; + float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; + + RE_RC_COUNT(isec->raycounter->bb.test); + + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; + if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; + if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0; + RE_RC_COUNT(isec->raycounter->bb.hit); + + return 1; +} + + +/* only for self-intersecting test with current render face (where ray left) */ +static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, float ry1, float rz1) +{ + float co1[3], co2[3], co3[3], co4[3]; + float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; + float m0, m1, m2, divdet, det, det1; + float u1, v, u2; + + VECCOPY(co1, face->v1->co); + VECCOPY(co2, face->v2->co); + if(face->v4) + { + VECCOPY(co3, face->v4->co); + VECCOPY(co4, face->v3->co); + } + else + { + VECCOPY(co3, face->v3->co); + } + + t00= co3[0]-co1[0]; + t01= co3[1]-co1[1]; + t02= co3[2]-co1[2]; + t10= co3[0]-co2[0]; + t11= co3[1]-co2[1]; + t12= co3[2]-co2[2]; + + x0= t11*r2-t12*r1; + x1= t12*r0-t10*r2; + x2= t10*r1-t11*r0; + + divdet= t00*x0+t01*x1+t02*x2; + + m0= rx1-co3[0]; + m1= ry1-co3[1]; + m2= rz1-co3[2]; + det1= m0*x0+m1*x1+m2*x2; + + if(divdet!=0.0f) { + u1= det1/divdet; + + if(u1 -(1.0f+ISECT_EPSILON)) { + return 1; + } + } + } + + if(face->v4) { + + t20= co3[0]-co4[0]; + t21= co3[1]-co4[1]; + t22= co3[2]-co4[2]; + + divdet= t20*x0+t21*x1+t22*x2; + if(divdet!=0.0f) { + u2= det1/divdet; + + if(u2= -(1.0f+ISECT_EPSILON)) { + return 2; + } + } + } + } + return 0; +} + +static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) +{ + /* for baking selected to active non-traceable materials might still + * be in the raytree */ + if(!(vlr->mat->mode & MA_TRACEBLE)) + return 0; + + /* I know... cpu cycle waste, might do smarter once */ + if(is->mode==RE_RAY_MIRROR) + return !(vlr->mat->mode & MA_ONLYCAST); + else + return (is->lay & obi->lay); +} + +static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) +{ + /* solid material types only */ + if (vlr->mat->material_type == MA_TYPE_SURFACE) + return 1; + else + return 0; +} + +static int rayface_check_cullface(RayFace *face, Isect *is) +{ + float nor[3]; + + /* don't intersect if the ray faces along the face normal */ + if(face->quad) CalcNormFloat4(face->v1, face->v2, face->v3, face->v4, nor); + else CalcNormFloat(face->v1, face->v2, face->v3, nor); + + return (INPR(nor, is->vec) < 0); +} + +/* ray - triangle or quad intersection */ +/* this function shall only modify Isect if it detects an hit */ +static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) +{ + float co1[3],co2[3],co3[3],co4[3]; + float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2; + float m0, m1, m2, divdet, det1; + float labda, u, v; + short ok=0; + + if(is->orig.ob == face->ob && is->orig.face == face->face) + return 0; + + if(is->skip & RE_SKIP_VLR_RENDER_CHECK) + { + if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) + return 0; + } + if(is->skip & RE_SKIP_VLR_NON_SOLID_MATERIAL) + { + if(vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) + return 0; + } + if(is->skip & RE_SKIP_CULLFACE) + { + if(rayface_check_cullface(face, is) == 0) + return 0; + } + + RE_RC_COUNT(is->raycounter->faces.test); + + //Load coords + VECCOPY(co1, face->v1); + VECCOPY(co2, face->v2); + if(RE_rayface_isQuad(face)) + { + VECCOPY(co3, face->v4); + VECCOPY(co4, face->v3); + } + else + { + VECCOPY(co3, face->v3); + } + + t00= co3[0]-co1[0]; + t01= co3[1]-co1[1]; + t02= co3[2]-co1[2]; + t10= co3[0]-co2[0]; + t11= co3[1]-co2[1]; + t12= co3[2]-co2[2]; + + r0= is->vec[0]; + r1= is->vec[1]; + r2= is->vec[2]; + + x0= t12*r1-t11*r2; + x1= t10*r2-t12*r0; + x2= t11*r0-t10*r1; + + divdet= t00*x0+t01*x1+t02*x2; + + m0= is->start[0]-co3[0]; + m1= is->start[1]-co3[1]; + m2= is->start[2]-co3[2]; + det1= m0*x0+m1*x1+m2*x2; + + if(divdet!=0.0f) { + + divdet= 1.0f/divdet; + u= det1*divdet; + if(u-(1.0f+ISECT_EPSILON)) { + float cros0, cros1, cros2; + + cros0= m1*t02-m2*t01; + cros1= m2*t00-m0*t02; + cros2= m0*t01-m1*t00; + v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); + + if(v -(1.0f+ISECT_EPSILON)) { + labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); + + if(labda>-ISECT_EPSILON && labdalabda) { + ok= 1; + } + } + } + } + + if(ok==0 && RE_rayface_isQuad(face)) { + + t20= co3[0]-co4[0]; + t21= co3[1]-co4[1]; + t22= co3[2]-co4[2]; + + divdet= t20*x0+t21*x1+t22*x2; + if(divdet!=0.0f) { + divdet= 1.0f/divdet; + u = det1*divdet; + + if(u-(1.0f+ISECT_EPSILON)) { + float cros0, cros1, cros2; + cros0= m1*t22-m2*t21; + cros1= m2*t20-m0*t22; + cros2= m0*t21-m1*t20; + v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); + + if(v-(1.0f+ISECT_EPSILON)) { + labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); + + if(labda>-ISECT_EPSILON && labdalabda) { + ok= 2; + } + } + } + } + } + + if(ok) { + + /* when a shadow ray leaves a face, it can be little outside the edges of it, causing + intersection to be detected in its neighbour face */ + if(is->skip & RE_SKIP_VLR_NEIGHBOUR) + { + if(labda < 0.1f && is->orig.ob == face->ob) + { + VlakRen * a = (VlakRen*)is->orig.face; + VlakRen * b = (VlakRen*)face->face; + + /* so there's a shared edge or vertex, let's intersect ray with face + itself, if that's true we can safely return 1, otherwise we assume + the intersection is invalid, 0 */ + if(a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1 + || a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2 + || a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3 + || (b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4))) + if(!intersection2((VlakRen*)a, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) + { + return 0; + } + } + } + + RE_RC_COUNT(is->raycounter->faces.hit); + + is->isect= ok; // wich half of the quad + is->labda= labda; + is->u= u; is->v= v; + + is->hit.ob = face->ob; + is->hit.face = face->face; +#ifdef RT_USE_LAST_HIT + is->last_hit = hit_obj; +#endif + return 1; + } + + return 0; +} + +RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr) +{ + return RE_rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0 ); +} + +RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) +{ + rayface->ob = ob; + rayface->face = face; + + VECCOPY(rayface->v1, v1); + VECCOPY(rayface->v2, v2); + VECCOPY(rayface->v3, v3); + if(v4) + { + VECCOPY(rayface->v4, v4); + rayface->quad = 1; + } + else + { + rayface->quad = 0; + } + + return RE_rayobject_unalignRayFace(rayface); +} + +RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr) +{ + face->ob = obi; + face->face = vlr; + return RE_rayobject_unalignVlakPrimitive(face); +} + + +int RE_rayobject_raycast(RayObject *r, Isect *isec) +{ + int i; + RE_RC_COUNT(isec->raycounter->raycast.test); + + /* Setup vars used on raycast */ + isec->labda *= Normalize(isec->vec); + isec->dist = VecLength(isec->vec); + + for(i=0; i<3; i++) + { + isec->idot_axis[i] = 1.0f / isec->vec[i]; + + isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0; + isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i]; + + isec->bv_index[2*i] = i+3*isec->bv_index[2*i]; + isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; + } + +#ifdef RT_USE_LAST_HIT + /* Last hit heuristic */ + if(isec->mode==RE_RAY_SHADOW && isec->last_hit) + { + RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test); + + if(RE_rayobject_intersect(isec->last_hit, isec)) + { + RE_RC_COUNT(isec->raycounter->raycast.hit); + RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit); + return 1; + } + } +#endif + +#ifdef RT_USE_HINT + isec->hit_hint = 0; +#endif + + if(RE_rayobject_intersect(r, isec)) + { + RE_RC_COUNT(isec->raycounter->raycast.hit); + +#ifdef RT_USE_HINT + isec->hint = isec->hit_hint; +#endif + return 1; + } + return 0; +} + +int RE_rayobject_intersect(RayObject *r, Isect *i) +{ + if(RE_rayobject_isRayFace(r)) + { + return intersect_rayface(r, (RayFace*) RE_rayobject_align(r), i); + } + else if(RE_rayobject_isVlakPrimitive(r)) + { + //TODO optimize (useless copy to RayFace to avoid duplicate code) + VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r); + RayFace nface; + RE_rayface_from_vlak(&nface, face->ob, face->face); + + if(face->ob->transform_primitives) + { + Mat4MulVecfl(face->ob->mat, nface.v1); + Mat4MulVecfl(face->ob->mat, nface.v2); + Mat4MulVecfl(face->ob->mat, nface.v3); + if(RE_rayface_isQuad(&nface)) + Mat4MulVecfl(face->ob->mat, nface.v4); + } + + return intersect_rayface(r, &nface, i); + } + else if(RE_rayobject_isRayAPI(r)) + { + r = RE_rayobject_align( r ); + return r->api->raycast( r, i ); + } + else assert(0); +} + +void RE_rayobject_add(RayObject *r, RayObject *o) +{ + r = RE_rayobject_align( r ); + return r->api->add( r, o ); +} + +void RE_rayobject_done(RayObject *r) +{ + r = RE_rayobject_align( r ); + r->api->done( r ); +} + +void RE_rayobject_free(RayObject *r) +{ + r = RE_rayobject_align( r ); + r->api->free( r ); +} + +void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) +{ + if(RE_rayobject_isRayFace(r)) + { + RayFace *face = (RayFace*) RE_rayobject_align(r); + + DO_MINMAX( face->v1, min, max ); + DO_MINMAX( face->v2, min, max ); + DO_MINMAX( face->v3, min, max ); + if(RE_rayface_isQuad(face)) DO_MINMAX( face->v4, min, max ); + } + else if(RE_rayobject_isVlakPrimitive(r)) + { + VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r); + VlakRen *vlr = face->face; + + DO_MINMAX( vlr->v1->co, min, max ); + DO_MINMAX( vlr->v2->co, min, max ); + DO_MINMAX( vlr->v3->co, min, max ); + if(vlr->v4) DO_MINMAX( vlr->v4->co, min, max ); + } + else if(RE_rayobject_isRayAPI(r)) + { + r = RE_rayobject_align( r ); + r->api->bb( r, min, max ); + } + else assert(0); +} + +float RE_rayobject_cost(RayObject *r) +{ + if(RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) + { + return 1.0; + } + else if(RE_rayobject_isRayAPI(r)) + { + r = RE_rayobject_align( r ); + return r->api->cost( r ); + } + else assert(0); +} + +void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max) +{ + if(RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) + { + return; + } + else if(RE_rayobject_isRayAPI(r)) + { + r = RE_rayobject_align( r ); + return r->api->hint_bb( r, hint, min, max ); + } + else assert(0); +} + diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/source/rayobject.c deleted file mode 100644 index df457a37123..00000000000 --- a/source/blender/render/intern/source/rayobject.c +++ /dev/null @@ -1,493 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include - -#include "BKE_utildefines.h" -#include "BLI_arithb.h" - -#include "RE_raytrace.h" -#include "render_types.h" -#include "rayobject.h" -#include "raycounter.h" - -/* - * Determines the distance that the ray must travel to hit the bounding volume of the given node - * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe - * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9] - */ -int RE_rayobject_bb_intersect_test(const Isect *isec, const float *_bb) -{ - const float *bb = _bb; - - float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0]; - float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0]; - float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1]; - float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1]; - float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2]; - float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2]; - - RE_RC_COUNT(isec->raycounter->bb.test); - - if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; - if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; - if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return 0; - RE_RC_COUNT(isec->raycounter->bb.hit); - - return 1; -} - - -/* only for self-intersecting test with current render face (where ray left) */ -static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, float ry1, float rz1) -{ - float co1[3], co2[3], co3[3], co4[3]; - float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; - float m0, m1, m2, divdet, det, det1; - float u1, v, u2; - - VECCOPY(co1, face->v1->co); - VECCOPY(co2, face->v2->co); - if(face->v4) - { - VECCOPY(co3, face->v4->co); - VECCOPY(co4, face->v3->co); - } - else - { - VECCOPY(co3, face->v3->co); - } - - t00= co3[0]-co1[0]; - t01= co3[1]-co1[1]; - t02= co3[2]-co1[2]; - t10= co3[0]-co2[0]; - t11= co3[1]-co2[1]; - t12= co3[2]-co2[2]; - - x0= t11*r2-t12*r1; - x1= t12*r0-t10*r2; - x2= t10*r1-t11*r0; - - divdet= t00*x0+t01*x1+t02*x2; - - m0= rx1-co3[0]; - m1= ry1-co3[1]; - m2= rz1-co3[2]; - det1= m0*x0+m1*x1+m2*x2; - - if(divdet!=0.0f) { - u1= det1/divdet; - - if(u1 -(1.0f+ISECT_EPSILON)) { - return 1; - } - } - } - - if(face->v4) { - - t20= co3[0]-co4[0]; - t21= co3[1]-co4[1]; - t22= co3[2]-co4[2]; - - divdet= t20*x0+t21*x1+t22*x2; - if(divdet!=0.0f) { - u2= det1/divdet; - - if(u2= -(1.0f+ISECT_EPSILON)) { - return 2; - } - } - } - } - return 0; -} - -#include "DNA_material_types.h" -static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) -{ - /* for baking selected to active non-traceable materials might still - * be in the raytree */ - if(!(vlr->mat->mode & MA_TRACEBLE)) - return 0; - - /* I know... cpu cycle waste, might do smarter once */ - if(is->mode==RE_RAY_MIRROR) - return !(vlr->mat->mode & MA_ONLYCAST); - else - return (is->lay & obi->lay); -} - -static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) -{ - /* solid material types only */ - if (vlr->mat->material_type == MA_TYPE_SURFACE) - return 1; - else - return 0; -} - -static int rayface_check_cullface(RayFace *face, Isect *is) -{ - float nor[3]; - - /* don't intersect if the ray faces along the face normal */ - if(face->quad) CalcNormFloat4(face->v1, face->v2, face->v3, face->v4, nor); - else CalcNormFloat(face->v1, face->v2, face->v3, nor); - - return (INPR(nor, is->vec) < 0); -} - -/* ray - triangle or quad intersection */ -/* this function shall only modify Isect if it detects an hit */ -static int intersect_rayface(RayFace *face, Isect *is) -{ - float co1[3],co2[3],co3[3],co4[3]; - float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2; - float m0, m1, m2, divdet, det1; - float labda, u, v; - short ok=0; - - if(is->orig.ob == face->ob && is->orig.face == face->face) - return 0; - - if(is->skip & RE_SKIP_VLR_RENDER_CHECK) - { - if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) - return 0; - } - if(is->skip & RE_SKIP_VLR_NON_SOLID_MATERIAL) - { - if(vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) - return 0; - } - if(is->skip & RE_SKIP_CULLFACE) - { - if(rayface_check_cullface(face, is) == 0) - return 0; - } - - RE_RC_COUNT(is->raycounter->faces.test); - - //Load coords - VECCOPY(co1, face->v1); - VECCOPY(co2, face->v2); - if(RE_rayface_isQuad(face)) - { - VECCOPY(co3, face->v4); - VECCOPY(co4, face->v3); - } - else - { - VECCOPY(co3, face->v3); - } - - t00= co3[0]-co1[0]; - t01= co3[1]-co1[1]; - t02= co3[2]-co1[2]; - t10= co3[0]-co2[0]; - t11= co3[1]-co2[1]; - t12= co3[2]-co2[2]; - - r0= is->vec[0]; - r1= is->vec[1]; - r2= is->vec[2]; - - x0= t12*r1-t11*r2; - x1= t10*r2-t12*r0; - x2= t11*r0-t10*r1; - - divdet= t00*x0+t01*x1+t02*x2; - - m0= is->start[0]-co3[0]; - m1= is->start[1]-co3[1]; - m2= is->start[2]-co3[2]; - det1= m0*x0+m1*x1+m2*x2; - - if(divdet!=0.0f) { - - divdet= 1.0f/divdet; - u= det1*divdet; - if(u-(1.0f+ISECT_EPSILON)) { - float cros0, cros1, cros2; - - cros0= m1*t02-m2*t01; - cros1= m2*t00-m0*t02; - cros2= m0*t01-m1*t00; - v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); - - if(v -(1.0f+ISECT_EPSILON)) { - labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); - - if(labda>-ISECT_EPSILON && labdalabda) { - ok= 1; - } - } - } - } - - if(ok==0 && RE_rayface_isQuad(face)) { - - t20= co3[0]-co4[0]; - t21= co3[1]-co4[1]; - t22= co3[2]-co4[2]; - - divdet= t20*x0+t21*x1+t22*x2; - if(divdet!=0.0f) { - divdet= 1.0f/divdet; - u = det1*divdet; - - if(u-(1.0f+ISECT_EPSILON)) { - float cros0, cros1, cros2; - cros0= m1*t22-m2*t21; - cros1= m2*t20-m0*t22; - cros2= m0*t21-m1*t20; - v= divdet*(cros0*r0 + cros1*r1 + cros2*r2); - - if(v-(1.0f+ISECT_EPSILON)) { - labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12); - - if(labda>-ISECT_EPSILON && labdalabda) { - ok= 2; - } - } - } - } - } - - if(ok) { - - /* when a shadow ray leaves a face, it can be little outside the edges of it, causing - intersection to be detected in its neighbour face */ - if(is->skip & RE_SKIP_VLR_NEIGHBOUR) - { - if(labda < 0.1f && is->orig.ob == face->ob) - { - VlakRen * a = is->orig.face; - VlakRen * b = face->face; - - /* so there's a shared edge or vertex, let's intersect ray with face - itself, if that's true we can safely return 1, otherwise we assume - the intersection is invalid, 0 */ - if(a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1 - || a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2 - || a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3 - || (b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4))) - if(!intersection2((VlakRen*)a, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2])) - { - return 0; - } - } - } - - RE_RC_COUNT(is->raycounter->faces.hit); - - is->isect= ok; // wich half of the quad - is->labda= labda; - is->u= u; is->v= v; - - is->hit.ob = face->ob; - is->hit.face = face->face; -#ifdef RT_USE_LAST_HIT - is->last_hit = (RayObject*) RE_rayobject_unalignRayFace(face); -#endif - return 1; - } - - return 0; -} - -RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr) -{ - return RE_rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0 ); -} - -RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) -{ - rayface->ob = ob; - rayface->face = face; - - VECCOPY(rayface->v1, v1); - VECCOPY(rayface->v2, v2); - VECCOPY(rayface->v3, v3); - if(v4) - { - VECCOPY(rayface->v4, v4); - rayface->quad = 1; - } - else - { - rayface->quad = 0; - } - - return RE_rayobject_unalignRayFace(rayface); -} - -int RE_rayobject_raycast(RayObject *r, Isect *isec) -{ - int i; - RE_RC_COUNT(isec->raycounter->raycast.test); - - /* Setup vars used on raycast */ - isec->labda *= Normalize(isec->vec); - isec->dist = VecLength(isec->vec); - - for(i=0; i<3; i++) - { - isec->idot_axis[i] = 1.0f / isec->vec[i]; - - isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0; - isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i]; - - isec->bv_index[2*i] = i+3*isec->bv_index[2*i]; - isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; - } - -#ifdef RT_USE_LAST_HIT - /* Last hit heuristic */ - if(isec->mode==RE_RAY_SHADOW && isec->last_hit) - { - RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test); - - if(RE_rayobject_intersect(isec->last_hit, isec)) - { - RE_RC_COUNT(isec->raycounter->raycast.hit); - RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit); - return 1; - } - } -#endif - -#ifdef RT_USE_HINT - isec->hit_hint = 0; -#endif - - if(RE_rayobject_intersect(r, isec)) - { - RE_RC_COUNT(isec->raycounter->raycast.hit); - -#ifdef RT_USE_HINT - isec->hint = isec->hit_hint; -#endif - return 1; - } - return 0; -} - -int RE_rayobject_intersect(RayObject *r, Isect *i) -{ - if(RE_rayobject_isRayFace(r)) - { - return intersect_rayface( (RayFace*) RE_rayobject_align(r), i); - } - else if(RE_rayobject_isRayAPI(r)) - { - r = RE_rayobject_align( r ); - return r->api->raycast( r, i ); - } - else assert(0); -} - -void RE_rayobject_add(RayObject *r, RayObject *o) -{ - r = RE_rayobject_align( r ); - return r->api->add( r, o ); -} - -void RE_rayobject_done(RayObject *r) -{ - r = RE_rayobject_align( r ); - r->api->done( r ); -} - -void RE_rayobject_free(RayObject *r) -{ - r = RE_rayobject_align( r ); - r->api->free( r ); -} - -void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) -{ - if(RE_rayobject_isRayFace(r)) - { - RayFace *face = (RayFace*) RE_rayobject_align(r); - - DO_MINMAX( face->v1, min, max ); - DO_MINMAX( face->v2, min, max ); - DO_MINMAX( face->v3, min, max ); - if(RE_rayface_isQuad(face)) DO_MINMAX( face->v4, min, max ); - } - else if(RE_rayobject_isRayAPI(r)) - { - r = RE_rayobject_align( r ); - r->api->bb( r, min, max ); - } - else assert(0); -} - -float RE_rayobject_cost(RayObject *r) -{ - if(RE_rayobject_isRayFace(r)) - { - return 1.0; - } - else if(RE_rayobject_isRayAPI(r)) - { - r = RE_rayobject_align( r ); - return r->api->cost( r ); - } - else assert(0); -} - -void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max) -{ - if(RE_rayobject_isRayFace(r)) - { - return; - } - else if(RE_rayobject_isRayAPI(r)) - { - r = RE_rayobject_align( r ); - return r->api->hint_bb( r, hint, min, max ); - } - else assert(0); -} - diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 8cb11d11762..18278d90e72 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -61,6 +61,8 @@ #include "rayobject.h" #include "raycounter.h" + +#define USE_VLAK_PRIMITIVES 1 #define RAY_TRA 1 #define RAY_TRAFLIP 2 @@ -133,6 +135,11 @@ void freeraytree(Render *re) MEM_freeN(re->rayfaces); re->rayfaces = NULL; } + if(re->rayprimitives) + { + MEM_freeN(re->rayprimitives); + re->rayprimitives = NULL; + } for(obi=re->instancetable.first; obi; obi=obi->next) { @@ -203,6 +210,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) { RayObject *raytree; RayFace *face; + VlakPrimitive *vlakprimitive; int v; //Count faces @@ -217,7 +225,11 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) //Create Ray cast accelaration structure raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces ); - face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); + if(USE_VLAK_PRIMITIVES) + vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives"); + else + face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); + obr->rayobi = obi; for(v=0;vtotvlak;v++) @@ -225,17 +237,26 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); if(is_raytraceable_vlr(re, vlr)) { - RE_rayface_from_vlak( face, obi, vlr ); - RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) ); - face++; + if(USE_VLAK_PRIMITIVES) + { + RE_rayobject_add( raytree, RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ) ); + vlakprimitive++; + } + else + { + RE_rayface_from_vlak( face, obi, vlr ); + RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) ); + face++; + } } } RE_rayobject_done( raytree ); } - if(obi->flag & R_TRANSFORMED) + if((obi->flag & R_TRANSFORMED) && obi->raytree == NULL) { + obi->transform_primitives = 0; obi->raytree = RE_rayobject_instance_create( obr->raytree, obi->mat, obi, obi->obr->rayobi ); } @@ -271,7 +292,8 @@ static void makeraytree_single(Render *re) ObjectInstanceRen *obi; RayObject *raytree; RayFace *face; - int faces = 0, obs = 0; + VlakPrimitive *vlakprimitive; + int faces = 0, obs = 0, special = 0; for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) @@ -282,7 +304,7 @@ static void makeraytree_single(Render *re) if(has_special_rayobject(re, obi)) { - faces++; + special++; } else { @@ -296,9 +318,16 @@ static void makeraytree_single(Render *re) } //Create raytree - raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces ); + raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces+special ); - face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); + if(USE_VLAK_PRIMITIVES) + { + vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives"); + } + else + { + face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces"); + } for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) @@ -312,28 +341,46 @@ static void makeraytree_single(Render *re) { int v; ObjectRen *obr = obi->obr; + + if(obi->flag & R_TRANSFORMED) + { + obi->transform_primitives = 1; + } for(v=0;vtotvlak;v++) { VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); if(is_raytraceable_vlr(re, vlr)) { - RE_rayface_from_vlak(face, obi, vlr); - if((obi->flag & R_TRANSFORMED)) + if(USE_VLAK_PRIMITIVES) { - Mat4MulVecfl(obi->mat, face->v1); - Mat4MulVecfl(obi->mat, face->v2); - Mat4MulVecfl(obi->mat, face->v3); - if(RE_rayface_isQuad(face)) - Mat4MulVecfl(obi->mat, face->v4); + RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ); + RE_rayobject_add( raytree, obj ); + vlakprimitive++; + } + else + { + RE_rayface_from_vlak(face, obi, vlr); + if((obi->flag & R_TRANSFORMED)) + { + Mat4MulVecfl(obi->mat, face->v1); + Mat4MulVecfl(obi->mat, face->v2); + Mat4MulVecfl(obi->mat, face->v3); + if(RE_rayface_isQuad(face)) + Mat4MulVecfl(obi->mat, face->v4); + } + + RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) ); + face++; } - - RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) ); - face++; } } } } + + re->i.infostr= "Raytree.. building"; + re->stats_draw(re->sdh, &re->i); + RE_rayobject_done( raytree ); } @@ -342,7 +389,7 @@ void makeraytree(Render *re) float min[3], max[3], sub[3]; int i; - re->i.infostr= "Make raytree"; + re->i.infostr= "Raytree.. preparing"; re->stats_draw(re->sdh, &re->i); BENCH(makeraytree_single(re), tree_build); @@ -359,6 +406,7 @@ void makeraytree(Render *re) re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] ); re->i.infostr= "Raytree finished"; + re->stats_draw(re->sdh, &re->i); } void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 5f21a0e2e1a..784e42685b7 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -879,6 +879,11 @@ void free_renderdata_tables(Render *re) MEM_freeN(obr->rayfaces); obr->rayfaces = NULL; } + if(obr->rayprimitives) + { + MEM_freeN(obr->rayprimitives); + obr->rayprimitives = NULL; + } if(obr->raytree) { RE_rayobject_free(obr->raytree); -- cgit v1.2.3 From 5eb2b4b40d6a687659aeae8810c0e36dd29d6715 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 25 Sep 2009 01:13:07 +0000 Subject: SVN maintenance. --- extern/Eigen2/eigen-update.sh | 0 intern/itasc/Armature.cpp | 2 +- intern/itasc/Cache.cpp | 2 +- intern/itasc/ConstraintSet.cpp | 2 +- intern/itasc/ControlledObject.cpp | 2 +- intern/itasc/CopyPose.cpp | 2 +- intern/itasc/Distance.cpp | 2 +- intern/itasc/FixedObject.cpp | 2 +- intern/itasc/Makefile | 2 +- intern/itasc/MovingFrame.cpp | 2 +- intern/itasc/Scene.cpp | 2 +- intern/itasc/UncontrolledObject.cpp | 2 +- intern/itasc/WDLSSolver.cpp | 2 +- intern/itasc/WSDLSSolver.cpp | 2 +- intern/itasc/WorldObject.cpp | 2 +- intern/itasc/eigen_types.cpp | 2 +- intern/itasc/kdl/Makefile | 2 +- intern/itasc/kdl/frameacc.cpp | 2 +- intern/itasc/kdl/framevel.cpp | 2 +- intern/itasc/kdl/utilities/Makefile | 2 +- intern/itasc/kdl/utilities/error.h | 2 +- intern/itasc/kdl/utilities/error_stack.cpp | 2 +- intern/itasc/kdl/utilities/rall1d.h | 2 +- intern/itasc/kdl/utilities/rall2d.h | 2 +- intern/itasc/kdl/utilities/utility.h | 2 +- intern/itasc/kdl/utilities/utility_io.cpp | 2 +- intern/itasc/kdl/utilities/utility_io.h | 2 +- 27 files changed, 26 insertions(+), 26 deletions(-) mode change 100644 => 100755 extern/Eigen2/eigen-update.sh diff --git a/extern/Eigen2/eigen-update.sh b/extern/Eigen2/eigen-update.sh old mode 100644 new mode 100755 diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp index cd059505b4a..2491b0f8c9f 100644 --- a/intern/itasc/Armature.cpp +++ b/intern/itasc/Armature.cpp @@ -1,4 +1,4 @@ -/* $Id: Armature.cpp 21152 2009-06-25 11:57:19Z ben2610 $ +/* $Id$ * Armature.cpp * * Created on: Feb 3, 2009 diff --git a/intern/itasc/Cache.cpp b/intern/itasc/Cache.cpp index 68c281910e3..1a1a3b4d009 100644 --- a/intern/itasc/Cache.cpp +++ b/intern/itasc/Cache.cpp @@ -1,4 +1,4 @@ -/* $Id: Cache.cpp 21152 2009-06-25 11:57:19Z ben2610 $ +/* $Id$ * Cache.cpp * * Created on: Feb 24, 2009 diff --git a/intern/itasc/ConstraintSet.cpp b/intern/itasc/ConstraintSet.cpp index f47af4246e4..eaffc2a52f9 100644 --- a/intern/itasc/ConstraintSet.cpp +++ b/intern/itasc/ConstraintSet.cpp @@ -1,4 +1,4 @@ -/* $Id: ConstraintSet.cpp 19905 2009-04-23 13:29:54Z ben2610 $ +/* $Id$ * ConstraintSet.cpp * * Created on: Jan 5, 2009 diff --git a/intern/itasc/ControlledObject.cpp b/intern/itasc/ControlledObject.cpp index f9e819d2950..b987e176031 100644 --- a/intern/itasc/ControlledObject.cpp +++ b/intern/itasc/ControlledObject.cpp @@ -1,4 +1,4 @@ -/* $Id: ControlledObject.cpp 19905 2009-04-23 13:29:54Z ben2610 $ +/* $Id$ * ControlledObject.cpp * * Created on: Jan 5, 2009 diff --git a/intern/itasc/CopyPose.cpp b/intern/itasc/CopyPose.cpp index df0bc38b704..3bf7edd7975 100644 --- a/intern/itasc/CopyPose.cpp +++ b/intern/itasc/CopyPose.cpp @@ -1,4 +1,4 @@ -/* $Id: CopyPose.cpp 20622 2009-06-04 12:47:59Z ben2610 $ +/* $Id$ * CopyPose.cpp * * Created on: Mar 17, 2009 diff --git a/intern/itasc/Distance.cpp b/intern/itasc/Distance.cpp index 03fa1762567..0f61e7666b2 100644 --- a/intern/itasc/Distance.cpp +++ b/intern/itasc/Distance.cpp @@ -1,4 +1,4 @@ -/* $Id: Distance.cpp 20603 2009-06-03 15:17:52Z ben2610 $ +/* $Id$ * Distance.cpp * * Created on: Jan 30, 2009 diff --git a/intern/itasc/FixedObject.cpp b/intern/itasc/FixedObject.cpp index 1360c3c152b..fad77d4825e 100644 --- a/intern/itasc/FixedObject.cpp +++ b/intern/itasc/FixedObject.cpp @@ -1,4 +1,4 @@ -/* $Id: FixedObject.cpp 19905 2009-04-23 13:29:54Z ben2610 $ +/* $Id$ * FixedObject.cpp * * Created on: Feb 10, 2009 diff --git a/intern/itasc/Makefile b/intern/itasc/Makefile index 463f7763cd2..6ac0d142b72 100644 --- a/intern/itasc/Makefile +++ b/intern/itasc/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 19907 2009-04-23 13:41:59Z ben2610 $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/intern/itasc/MovingFrame.cpp b/intern/itasc/MovingFrame.cpp index 545f9bd38e9..c0995383c4b 100644 --- a/intern/itasc/MovingFrame.cpp +++ b/intern/itasc/MovingFrame.cpp @@ -1,4 +1,4 @@ -/* $Id: MovingFrame.cpp 20853 2009-06-13 12:29:46Z ben2610 $ +/* $Id$ * MovingFrame.cpp * * Created on: Feb 10, 2009 diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp index c50769e9c1d..8aa423584f1 100644 --- a/intern/itasc/Scene.cpp +++ b/intern/itasc/Scene.cpp @@ -1,4 +1,4 @@ -/* $Id: Scene.cpp 20874 2009-06-14 13:50:34Z ben2610 $ +/* $Id$ * Scene.cpp * * Created on: Jan 5, 2009 diff --git a/intern/itasc/UncontrolledObject.cpp b/intern/itasc/UncontrolledObject.cpp index e05a8682d20..4db44aaf7dc 100644 --- a/intern/itasc/UncontrolledObject.cpp +++ b/intern/itasc/UncontrolledObject.cpp @@ -1,4 +1,4 @@ -/* $Id: UncontrolledObject.cpp 19907 2009-04-23 13:41:59Z ben2610 $ +/* $Id$ * UncontrolledObject.cpp * * Created on: Jan 5, 2009 diff --git a/intern/itasc/WDLSSolver.cpp b/intern/itasc/WDLSSolver.cpp index 91278c7ad3b..e8bfc95e5dd 100644 --- a/intern/itasc/WDLSSolver.cpp +++ b/intern/itasc/WDLSSolver.cpp @@ -1,4 +1,4 @@ -/* $Id: WDLSSolver.cpp 20749 2009-06-09 11:27:30Z ben2610 $ +/* $Id$ * WDLSSolver.hpp.cpp * * Created on: Jan 8, 2009 diff --git a/intern/itasc/WSDLSSolver.cpp b/intern/itasc/WSDLSSolver.cpp index 1f99ad08334..971fb7f482e 100644 --- a/intern/itasc/WSDLSSolver.cpp +++ b/intern/itasc/WSDLSSolver.cpp @@ -1,4 +1,4 @@ -/* $Id: WSDLSSolver.cpp 20749 2009-06-09 11:27:30Z ben2610 $ +/* $Id$ * WDLSSolver.hpp.cpp * * Created on: Jan 8, 2009 diff --git a/intern/itasc/WorldObject.cpp b/intern/itasc/WorldObject.cpp index ba3f8549f06..99cb8773e77 100644 --- a/intern/itasc/WorldObject.cpp +++ b/intern/itasc/WorldObject.cpp @@ -1,4 +1,4 @@ -/* $Id: WorldObject.cpp 19907 2009-04-23 13:41:59Z ben2610 $ +/* $Id$ * WorldObject.cpp * * Created on: Feb 10, 2009 diff --git a/intern/itasc/eigen_types.cpp b/intern/itasc/eigen_types.cpp index a1b28e01210..2aa942f38c7 100644 --- a/intern/itasc/eigen_types.cpp +++ b/intern/itasc/eigen_types.cpp @@ -1,4 +1,4 @@ -/* $Id: eigen_types.cpp 19905 2009-04-23 13:29:54Z ben2610 $ +/* $Id$ * eigen_types.cpp * * Created on: March 19, 2009 diff --git a/intern/itasc/kdl/Makefile b/intern/itasc/kdl/Makefile index e87795fd3b7..e34c991db38 100644 --- a/intern/itasc/kdl/Makefile +++ b/intern/itasc/kdl/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 19905 2009-04-23 13:29:54Z ben2610 $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/intern/itasc/kdl/frameacc.cpp b/intern/itasc/kdl/frameacc.cpp index 85c4179379a..9defce0a00e 100644 --- a/intern/itasc/kdl/frameacc.cpp +++ b/intern/itasc/kdl/frameacc.cpp @@ -9,7 +9,7 @@ * - $log$ * * \par Release - * $Id: frameacc.cpp 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ ****************************************************************************/ diff --git a/intern/itasc/kdl/framevel.cpp b/intern/itasc/kdl/framevel.cpp index c0a94d64947..f70bef2e923 100644 --- a/intern/itasc/kdl/framevel.cpp +++ b/intern/itasc/kdl/framevel.cpp @@ -9,7 +9,7 @@ * - $log$ * * \par Release - * $Id: framevel.cpp 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ ****************************************************************************/ diff --git a/intern/itasc/kdl/utilities/Makefile b/intern/itasc/kdl/utilities/Makefile index 26bd7cfb470..6dedc24181e 100644 --- a/intern/itasc/kdl/utilities/Makefile +++ b/intern/itasc/kdl/utilities/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 19905 2009-04-23 13:29:54Z ben2610 $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/intern/itasc/kdl/utilities/error.h b/intern/itasc/kdl/utilities/error.h index c6cf916c151..868daef3db3 100644 --- a/intern/itasc/kdl/utilities/error.h +++ b/intern/itasc/kdl/utilities/error.h @@ -39,7 +39,7 @@ * - $log$ * * \par Release - * $Id: error.h 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ ****************************************************************************/ #ifndef ERROR_H_84822 // to make it unique, a random number diff --git a/intern/itasc/kdl/utilities/error_stack.cpp b/intern/itasc/kdl/utilities/error_stack.cpp index aabf47ad191..d55308c7346 100644 --- a/intern/itasc/kdl/utilities/error_stack.cpp +++ b/intern/itasc/kdl/utilities/error_stack.cpp @@ -9,7 +9,7 @@ * - $log$ * * \par Release - * $Id: error_stack.cpp 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ ****************************************************************************/ diff --git a/intern/itasc/kdl/utilities/rall1d.h b/intern/itasc/kdl/utilities/rall1d.h index 617683ffce6..98bd4385d1e 100644 --- a/intern/itasc/kdl/utilities/rall1d.h +++ b/intern/itasc/kdl/utilities/rall1d.h @@ -19,7 +19,7 @@ * - $log$ * * \par Release - * $Id: rall1d.h 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ ****************************************************************************/ diff --git a/intern/itasc/kdl/utilities/rall2d.h b/intern/itasc/kdl/utilities/rall2d.h index ca4c67319f5..cbd9e70b04f 100644 --- a/intern/itasc/kdl/utilities/rall2d.h +++ b/intern/itasc/kdl/utilities/rall2d.h @@ -19,7 +19,7 @@ * - $log$ * * \par Release - * $Id: rall2d.h 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ ****************************************************************************/ diff --git a/intern/itasc/kdl/utilities/utility.h b/intern/itasc/kdl/utilities/utility.h index 9c38eacbceb..7151792536e 100644 --- a/intern/itasc/kdl/utilities/utility.h +++ b/intern/itasc/kdl/utilities/utility.h @@ -9,7 +9,7 @@ * - $log$ * * \par Release - * $Id: utility.h 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ * \file * Included by most lrl-files to provide some general diff --git a/intern/itasc/kdl/utilities/utility_io.cpp b/intern/itasc/kdl/utilities/utility_io.cpp index ae65047fdbc..994567dfdfc 100644 --- a/intern/itasc/kdl/utilities/utility_io.cpp +++ b/intern/itasc/kdl/utilities/utility_io.cpp @@ -9,7 +9,7 @@ * - $log$ * * \par Release - * $Id: utility_io.cpp 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ * \todo * make IO routines more robust against the differences between DOS/UNIX end-of-line style. diff --git a/intern/itasc/kdl/utilities/utility_io.h b/intern/itasc/kdl/utilities/utility_io.h index 7c3d4f91296..2a71ce870a3 100644 --- a/intern/itasc/kdl/utilities/utility_io.h +++ b/intern/itasc/kdl/utilities/utility_io.h @@ -9,7 +9,7 @@ * - $log$ * * \par Release - * $Id: utility_io.h 19905 2009-04-23 13:29:54Z ben2610 $ + * $Id$ * $Name: $ * * \file utility_io.h -- cgit v1.2.3 From 2060127e1fc2b71b10fa1784cf7c58bc6a2ef539 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 01:29:30 +0000 Subject: missing includes --- source/blender/ikplugin/intern/iksolver_plugin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 262185fef1b..68afbcd0db2 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -34,6 +34,7 @@ #include "BLI_arithb.h" #include "BKE_armature.h" +#include "BKE_constraint.h" #include "BKE_utildefines.h" #include "DNA_object_types.h" #include "DNA_action_types.h" @@ -43,6 +44,8 @@ #include "IK_solver.h" #include "iksolver_plugin.h" +#include /* memcpy */ + /* ********************** THE IK SOLVER ******************* */ /* allocates PoseTree, and links that to root bone/channel */ -- cgit v1.2.3 From 558626714ebd903fb48d2eb2d121ba1cf54d6c1d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 25 Sep 2009 01:30:32 +0000 Subject: Bugfixes: * #19459: Shape Keys not Animateable Shape Keys were missing the appropriate 'path' callbacks. * #19458: 3D Viewport doesn't refresh when adding new bone in editmode (using Shift-A) The 'wrong' notifier was being sent. Currently, Armature EditMode only responds to NC_OBJECT|ND_TRANSFORM, which isn't strictly that correct for all cases. * Alignment code for constraints headers (i.e. enable/disable lumped with the delete constraint button) was causing the delete button to not work anymore. Removed the offending code (it shouldn't have been there to start off with). * When object's don't have their own AnimData (i.e. if you only animate the values of some shapekeys), a space is no longer left beside the object's name for a visibility toggle in the Graph Editor. --- source/blender/editors/animation/anim_channels_defines.c | 5 ++++- source/blender/editors/armature/editarmature.c | 3 ++- source/blender/editors/interface/interface_templates.c | 3 +-- source/blender/makesrna/intern/rna_key.c | 6 ++++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 7f0f2411bd0..c6ecad03be8 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -461,6 +461,9 @@ static void acf_object_name(bAnimListElem *ale, char *name) /* check if some setting exists for this channel */ static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { + Base *base= (Base *)ale->data; + Object *ob= base->object; + switch (setting) { /* muted only in NLA */ case ACHANNEL_SETTING_MUTE: @@ -468,7 +471,7 @@ static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int /* visible only in Graph Editor */ case ACHANNEL_SETTING_VISIBLE: - return ((ac) && (ac->spacetype == SPACE_IPO)); + return ((ac) && (ac->spacetype == SPACE_IPO) && (ob->adt)); /* only select and expand supported otherwise */ case ACHANNEL_SETTING_SELECT: diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index bc210fbcb54..5c224fbd4db 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -3448,7 +3448,8 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op) else VecAddf(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z - WM_event_add_notifier(C, NC_OBJECT, obedit); + /* note, notifier might evolve */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, obedit); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 31f371c5553..af4a4c13c80 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -905,10 +905,9 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) /* Close 'button' - emboss calls here disable drawing of 'button' behind X */ uiBlockSetEmboss(block, UI_EMBOSSN); - uiBlockBeginAlign(block); uiDefIconButBitS(block, ICONTOGN, CONSTRAINT_OFF, B_CONSTRAINT_TEST, ICON_CHECKBOX_DEHLT, xco+243, yco, 19, 19, &con->flag, 0.0, 0.0, 0.0, 0.0, "enable/disable constraint"); + uiDefIconButO(block, BUT, "CONSTRAINT_OT_delete", WM_OP_INVOKE_DEFAULT, ICON_X, xco+262, yco, 19, 19, "Delete constraint"); - uiBlockEndAlign(block); uiBlockSetEmboss(block, UI_EMBOSS); } diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index e66ee683e61..e1551404438 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -257,6 +257,11 @@ static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter) return rna_pointer_inherit_refine(&iter->parent, type, rna_iterator_array_get(iter)); } +static char *rna_ShapeKey_path(PointerRNA *ptr) +{ + return BLI_sprintfN("keys[\"%s\"]", ((KeyBlock*)ptr->data)->name); +} + static void rna_Key_update_data(bContext *C, PointerRNA *ptr) { Main *bmain= CTX_data_main(C); @@ -343,6 +348,7 @@ static void rna_def_keyblock(BlenderRNA *brna) srna= RNA_def_struct(brna, "ShapeKey", NULL); RNA_def_struct_ui_text(srna, "Shape Key", "Shape key in a shape keys datablock."); RNA_def_struct_sdna(srna, "KeyBlock"); + RNA_def_struct_path_func(srna, "rna_ShapeKey_path"); RNA_def_struct_ui_icon(srna, ICON_SHAPEKEY_DATA); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); -- cgit v1.2.3 From 83c3780d8c7f4bedfcd34d7a1dbb1aea9183ac32 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 25 Sep 2009 01:43:34 +0000 Subject: Quick tweaks to commonly debated mesh-editing hotkeys: * Loopcut is now just Ctrl-R. The preview will be activated when you do this, and you can just click to confirm as in 2.4x and also like when this was activated from the toolshelf. This is less error prone than having to click at the same time as picking the loop as with the previous hotkey. * Knife is now just: hold k-key and lmb click+drag to draw a cut line and cut the mesh. This is more direct than the (rather arcane) Ctrl-X-LMB-drag, and is quite similar to what's done for Grease Pencil now. --- source/blender/editors/mesh/mesh_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 96f5e7452d1..21148e59153 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -356,7 +356,7 @@ void ED_keymap_mesh(wmWindowManager *wm) keymap= WM_keymap_find(wm, "EditMesh", 0, 0); keymap->poll= ED_operator_editmesh; - WM_keymap_add_item(keymap, "MESH_OT_loopcut", ACTIONMOUSE, KM_PRESS, KM_CTRL, RKEY); + WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0); /* selecting */ /* standard mouse selection goes via space_view3d */ @@ -438,7 +438,7 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_fgon_make", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_fgon_clear", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); - WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, XKEY); + WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, 0, KKEY); /* menus */ WM_keymap_add_item(keymap, "MESH_OT_vertex_specials", VKEY, KM_PRESS, KM_CTRL, 0); -- cgit v1.2.3 From 5fdb839865436b98d021d4708e5d5141646f6e0e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 01:49:06 +0000 Subject: needed for linking with cmake on unix --- source/creator/CMakeLists.txt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 51a52ee6861..0cc0d5d496b 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -362,6 +362,7 @@ IF(UNIX) blender_ONL bf_python bf_gen_python + bf_ikplugin bf_blenkernel bf_nodes bf_gpu @@ -376,15 +377,12 @@ IF(UNIX) bf_readblenfile blender_bop bf_kernel - bf_decimation bf_elbeem bf_IK bf_memutil bf_guardedalloc blender_CTR bf_moto - bf_windowmanager - bf_editors bf_blroutines bf_converter bf_dummy @@ -399,17 +397,11 @@ IF(UNIX) bf_oglrasterizer bf_expressions bf_scenegraph - bf_moto - bf_blroutines kx_network - bf_kernel bf_ngnetwork extern_bullet bf_loopbacknetwork - bf_common - bf_moto - bf_python - bf_gen_python + bf_ITASC extern_binreloc extern_glew extern_libopenjpeg -- cgit v1.2.3 From b4f235adc0a61a74b753db4704af0c02229eb856 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 25 Sep 2009 01:59:43 +0000 Subject: Shell script exit values should be non-negative. Exact error with dash as sh "exit: 12: Illegal number: -1". The rest are just changes to whitespace and polishing. --- extern/Eigen2/eigen-update.sh | 26 +++++++++++++------------- source/blender/blenfont/Makefile | 2 +- source/blender/blenlib/intern/BLI_bfile.c | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/extern/Eigen2/eigen-update.sh b/extern/Eigen2/eigen-update.sh index 26155ed428b..926a36ef120 100755 --- a/extern/Eigen2/eigen-update.sh +++ b/extern/Eigen2/eigen-update.sh @@ -1,28 +1,28 @@ #!/bin/sh -echo "*** EIGEN2-SVN Update utility" -echo "*** This gets a new eigen2-svn tree and adapts it to blenders build structure" +echo "*** EIGEN2-HG Update utility" +echo "*** This gets a new eigen2-hg tree and adapts it to blenders build structure" echo "*** Warning! This script will wipe all the header file" -echo "*** Please run again with --i-really-know-what-im-doing ..." if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then - echo proceeding... + echo Proceeding as requested by command line ... else - exit -1 + echo "*** Please run again with --i-really-know-what-im-doing ..." + exit 1 fi # get the latest revision from repository. hg clone http://bitbucket.org/eigen/eigen2 if [ -d eigen2 ] then - cd eigen2 - # put here the version you want to use - hg up 2.0.6 - rm -f `find Eigen/ -type f -name "CMakeLists.txt"` - cp -r Eigen .. - cd .. - rm -rf eigen2 + cd eigen2 + # put here the version you want to use + hg up 2.0.6 + rm -f `find Eigen/ -type f -name "CMakeLists.txt"` + cp -r Eigen .. + cd .. + rm -rf eigen2 else - echo "Did you install Mercurial?" + echo "Did you install Mercurial?" fi diff --git a/source/blender/blenfont/Makefile b/source/blender/blenfont/Makefile index be62c87cbf4..43eda027855 100644 --- a/source/blender/blenfont/Makefile +++ b/source/blender/blenfont/Makefile @@ -30,5 +30,5 @@ DIRS = intern include nan_subdirs.mk ifeq ($(INTERNATIONAL), true) - CPPFLAGS += -DINTERNATIONAL + CPPFLAGS += -DINTERNATIONAL endif diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c index 4789df593ef..a7ce1df5712 100644 --- a/source/blender/blenlib/intern/BLI_bfile.c +++ b/source/blender/blenlib/intern/BLI_bfile.c @@ -30,7 +30,7 @@ #include #else #include -#include "BLI_winstuff.h" + #include "BLI_winstuff.h" #endif #include -- cgit v1.2.3 From 314d460eb87ec6f383358e0dbb77e9fdf5c99f23 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 02:40:10 +0000 Subject: options WITH_LZO and WITH_LZMA for cmake and scons (default to true) pointcache.c also needed to have checks for these defines. --- CMakeLists.txt | 2 ++ extern/CMakeLists.txt | 9 ++++++-- extern/Makefile | 6 ++--- extern/SConscript | 7 ++++-- source/blender/SConscript | 2 +- source/blender/blenkernel/CMakeLists.txt | 12 ++++++++-- source/blender/blenkernel/SConscript | 12 +++++++--- source/blender/blenkernel/intern/Makefile | 18 +++++++++++---- source/blender/blenkernel/intern/pointcache.c | 32 ++++++++++++++++++++------- tools/btools.py | 4 ++++ 10 files changed, 79 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92c670f572c..d8c5a132995 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,8 @@ OPTION(WITH_WEBPLUGIN "Enable Web Plugin (Unix only)" OFF) OPTION(WITH_FFTW3 "Enable FFTW3 support" OFF) OPTION(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF) OPTION(WITH_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF) +OPTION(WITH_LZO "Enable fast LZO compression, used for pointcache" ON) +OPTION(WITH_LZMA "Enable best LZMA compression, used for pointcache" ON) OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF) OPTION(WITH_BUILDINFO "Include extra build details" ON) OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 44e47aaf88d..35271d24a2d 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -38,5 +38,10 @@ IF(WITH_OPENJPEG) ADD_SUBDIRECTORY(libopenjpeg) ENDIF(WITH_OPENJPEG) -ADD_SUBDIRECTORY(lzo) -ADD_SUBDIRECTORY(lzma) +IF(WITH_LZO) + ADD_SUBDIRECTORY(lzo) +ENDIF(WITH_LZO) + +IF(WITH_LZMA) + ADD_SUBDIRECTORY(lzma) +ENDIF(WITH_LZMA) diff --git a/extern/Makefile b/extern/Makefile index b81fbd2b91a..a30cd1d7ca3 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -33,9 +33,9 @@ DIR = $(OCGDIR)/extern DIRS = glew/src # Cloth requires it -#ifneq ($(NAN_NO_KETSJI), true) -DIRS += bullet2 -#endif +ifeq ($(NAN_USE_BULLET), true) + DIRS += bullet2 +endif ifeq ($(WITH_BINRELOC), true) DIRS += binreloc diff --git a/extern/SConscript b/extern/SConscript index 20604d87e45..af057a73927 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -22,5 +22,8 @@ if env['WITH_BF_REDCODE'] and env['BF_REDCODE_LIB'] == '': if env['OURPLATFORM'] == 'linux2': SConscript(['binreloc/SConscript']); -SConscript(['lzo/SConscript']) -SConscript(['lzma/SConscript']) +if env['WITH_BF_LZO']: + SConscript(['lzo/SConscript']) + +if env['WITH_BF_LZMA']: + SConscript(['lzma/SConscript']) diff --git a/source/blender/SConscript b/source/blender/SConscript index af2c81a3b45..3625678f610 100644 --- a/source/blender/SConscript +++ b/source/blender/SConscript @@ -18,7 +18,7 @@ SConscript(['avi/SConscript', 'nodes/SConscript', 'ikplugin/SConscript', 'windowmanager/SConscript', - 'blenfont/SConscript']) + 'blenfont/SConscript']) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 3473950ab3a..f60cade61ed 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -34,8 +34,6 @@ SET(INC ../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern ../../../intern/bsp/extern ../blenfont ../../../intern/audaspace/intern - ../../../extern/lzo/minilzo - ../../../extern/lzma ${ZLIB_INC} ) @@ -76,6 +74,16 @@ IF(NOT WITH_ELBEEM) ADD_DEFINITIONS(-DDISABLE_ELBEEM) ENDIF(NOT WITH_ELBEEM) +IF(WITH_LZO) + SET(INC ${INC} ../../../extern/lzo/minilzo) + ADD_DEFINITIONS(-DWITH_LZO) +ENDIF(WITH_LZO) + +IF(WITH_LZMA) + SET(INC ${INC} ../../../extern/lzma) + ADD_DEFINITIONS(-DWITH_LZMA) +ENDIF(WITH_LZMA) + IF(WIN32) SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 944667e2963..63631ddc40f 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -11,8 +11,6 @@ incs += ' #/extern/bullet2/src' incs += ' #/intern/opennl/extern #/intern/bsp/extern' incs += ' ../gpu #/extern/glew/include' incs += ' #/intern/smoke/extern' -incs += ' #/extern/lzo/minilzo' -incs += ' #/extern/lzma' incs += ' #/intern/audaspace/intern' incs += ' ' + env['BF_OPENGL_INC'] @@ -61,7 +59,15 @@ if env['BF_NO_ELBEEM']: if env['WITH_BF_LCMS']: defs.append('WITH_LCMS') - + +if env['WITH_BF_LZO']: + incs += ' #/extern/lzo/minilzo' + defs.append('WITH_LZO') + +if env['WITH_BF_LZMA']: + incs += ' #/extern/lzma' + defs.append('WITH_LZMA') + if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index f16b57c8469..26b9b9ef0dd 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -86,14 +86,24 @@ CPPFLAGS += -I../../gpu # path to our own external headerfiles CPPFLAGS += -I.. -# path to bullet2, for cloth -CPPFLAGS += -I$(NAN_BULLET2)/include CPPFLAGS += -I$(NAN_FREETYPE)/include CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2 +# path to bullet2, for cloth +ifeq ($(NAN_USE_BULLET), true) + CPPFLAGS += -I$(NAN_BULLET2)/include +endif + # lzo and lzma, for pointcache -CPPFLAGS += -I$(NAN_LZO)/minilzo -CPPFLAGS += -I$(NAN_LZMA) +ifeq ($(WITH_LZO),true) + CPPFLAGS += -I$(NAN_LZO)/minilzo + CPPFLAGS += -DWITH_LZO +endif + +ifeq ($(WITH_LZO),true) + CPPFLAGS += -I$(NAN_LZMA) + CPPFLAGS += -DWITH_LZMA +endif ifeq ($(WITH_FFMPEG),true) CPPFLAGS += -DWITH_FFMPEG diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index e5f89727ab8..3915a6901a0 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -62,10 +62,17 @@ /* both in intern */ #include "smoke_API.h" + +#ifdef WITH_LZO #include "minilzo.h" +#else +/* used for non-lzo cases */ +#define LZO_OUT_LEN(size) ((size) + (size) / 16 + 64 + 3) +#endif +#ifdef WITH_LZMA #include "LzmaLib.h" - +#endif /* needed for directory lookup */ /* untitled blend's need getpid for a unique name */ @@ -625,20 +632,25 @@ static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size); static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode) { int r = 0; - unsigned char compressed; - LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS); - unsigned int out_len = LZO_OUT_LEN(in_len); + unsigned char compressed = 0; + unsigned int out_len= 0; unsigned char *props = MEM_callocN(16*sizeof(char), "tmp"); size_t sizeOfIt = 5; +#ifdef WITH_LZO + out_len= LZO_OUT_LEN(in_len); if(mode == 1) { + LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS); + r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem); if (!(r == LZO_E_OK) || (out_len >= in_len)) compressed = 0; else compressed = 1; } - else if(mode == 2) { +#endif +#ifdef WITH_LZMA + if(mode == 2) { r = LzmaCompress(out, (size_t *)&out_len, in, in_len,//assume sizeof(char)==1.... props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2); @@ -648,7 +660,8 @@ static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned i else compressed = 2; } - +#endif + ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char)); if(compressed) { ptcache_file_write(pf, &out_len, 1, sizeof(unsigned int)); @@ -762,16 +775,19 @@ static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigne in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer"); ptcache_file_read(pf, in, in_len, sizeof(unsigned char)); +#ifdef WITH_LZO if(compressed == 1) r = lzo1x_decompress(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL); - else if(compressed == 2) +#endif +#ifdef WITH_LZMA + if(compressed == 2) { size_t leni = in_len, leno = out_len; ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int)); ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char)); r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt); } - +#endif MEM_freeN(in); } else { diff --git a/tools/btools.py b/tools/btools.py index e3f3827ff45..b1584ae8784 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -56,6 +56,7 @@ def validate_arguments(args, bc): 'WITH_BF_PLAYER', 'WITH_BF_NOBLENDER', 'WITH_BF_BINRELOC', + 'WITH_BF_LZO', 'WITH_BF_LZMA', 'LCGDIR', 'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC', 'BF_TWEAK_MODE', 'BF_SPLIT_SRC', @@ -379,6 +380,9 @@ def read_opts(cfg, args): (BoolVariable('BF_QUIET', 'Enable silent output if true', True)), (BoolVariable('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', False)), + (BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)), + (BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)), + (BoolVariable('WITH_BF_LCMS', 'Enable color correction with lcms', False)), ('BF_LCMS_LIB', 'LCMSlibrary', 'lcms'), -- cgit v1.2.3 From 0aa08fce7236eaf263409b813b7ea072f791479d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 04:25:40 +0000 Subject: still doesn't work but this fixes make clean --- intern/Makefile | 2 +- source/nan_definitions.mk | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/intern/Makefile b/intern/Makefile index 32375f16b7a..ed0b0cfff28 100644 --- a/intern/Makefile +++ b/intern/Makefile @@ -32,7 +32,7 @@ SOURCEDIR = intern # include nan_subdirs.mk ALLDIRS = string ghost guardedalloc moto container memutil -ALLDIRS += decimation iksolver itasc bsp SoundSystem opennl elbeem boolop smoke audaspace +ALLDIRS += decimation iksolver itasc bsp opennl elbeem boolop smoke audaspace all:: @for i in $(ALLDIRS); do \ diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index 6d4a7139d5b..1aff7e1dea7 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -81,6 +81,8 @@ ifndef CONFIG_GUESS endif export NAN_MOTO ?= $(LCGDIR)/moto + export NAN_ITASC ?= $(LCGDIR)/itasc + export BF_PROFILE ?= false export NAN_USE_BULLET ?= true export NAN_BULLET2 ?= $(LCGDIR)/bullet2 -- cgit v1.2.3 From 2d22ea1f926e54da80f517278a3e7aa02b522583 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 25 Sep 2009 04:51:04 +0000 Subject: Drivers: Copy/Paste tools for the RMB Menu Drivers can now be copied/pasted for single properties, allowing drivers set up on one property to be added to a few other properties relatively easily. Also, added description strings for the other driver-button operators. --- source/blender/blenkernel/intern/constraint.c | 2 +- source/blender/editors/animation/anim_ops.c | 2 + source/blender/editors/animation/drivers.c | 237 ++++++++++++++++++++- source/blender/editors/include/ED_keyframing.h | 18 +- source/blender/editors/interface/interface_anim.c | 19 ++ .../blender/editors/interface/interface_intern.h | 2 + .../blender/editors/interface/interface_layout.c | 2 +- source/blender/windowmanager/intern/wm_init_exit.c | 2 + 8 files changed, 271 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index b8d6b333674..4de6b53d26a 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -688,7 +688,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain if ((ct->tar->type==OB_ARMATURE) && (ct->subtarget[0])) { \ bPoseChannel *pchan= get_pose_channel(ct->tar->pose, ct->subtarget); \ ct->type = CONSTRAINT_OBTYPE_BONE; \ - ct->rotOrder= pchan->rotmode; \ + ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \ }\ else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \ ct->type = CONSTRAINT_OBTYPE_VERT; \ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 40c5b8893a1..a4038028062 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -399,6 +399,8 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_add_driver_button); WM_operatortype_append(ANIM_OT_remove_driver_button); + WM_operatortype_append(ANIM_OT_copy_driver_button); + WM_operatortype_append(ANIM_OT_paste_driver_button); WM_operatortype_append(ANIM_OT_add_keyingset_button); WM_operatortype_append(ANIM_OT_remove_keyingset_button); diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 8b9224511ba..363a5a80f00 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -80,6 +80,10 @@ /* Get (or add relevant data to be able to do so) F-Curve from the driver stack, * for the given Animation Data block. This assumes that all the destinations are valid. + * + * - add: 0 - don't add anything if not found, + * 1 - add new Driver FCurve, + * -1 - add new Driver FCurve without driver stuff (for pasting) */ FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_index, short add) { @@ -115,11 +119,14 @@ FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_ind fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path)); fcu->array_index= array_index; - /* add some new driver data */ - fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver"); - - /* add simple generator modifier for driver so that there is some visible representation */ - add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + /* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */ + if (add > 0) { + /* add some new driver data */ + fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver"); + + /* add simple generator modifier for driver so that there is some visible representation */ + add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + } /* just add F-Curve to end of driver list */ BLI_addtail(&adt->drivers, fcu); @@ -144,7 +151,7 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - printf("Insert Key: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path); + printf("Add Driver: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path); return 0; } @@ -163,7 +170,7 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla float fval; if (proptype == PROP_BOOLEAN) { - if(!array) val= RNA_property_boolean_get(&ptr, prop); + if (!array) val= RNA_property_boolean_get(&ptr, prop); else val= RNA_property_boolean_get_index(&ptr, prop, array_index); BLI_strncpy(expression, (val)? "True": "False", maxlen); @@ -180,7 +187,6 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla BLI_snprintf(expression, maxlen, "%.3f", fval); } - } } @@ -218,6 +224,127 @@ short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index, return 0; } +/* ************************************************** */ +/* Driver Management API - Copy/Paste Drivers */ + +/* Copy/Paste Buffer for Driver Data... */ +static FCurve *channeldriver_copypaste_buf = NULL; + +/* This function frees any MEM_calloc'ed copy/paste buffer data */ +// XXX find some header to put this in! +void free_anim_drivers_copybuf (void) +{ + /* free the buffer F-Curve if it exists, as if it were just another F-Curve */ + if (channeldriver_copypaste_buf) + free_fcurve(channeldriver_copypaste_buf); + channeldriver_copypaste_buf= NULL; +} + +/* Checks if there is a driver in the copy/paste buffer */ +short ANIM_driver_can_paste (void) +{ + return (channeldriver_copypaste_buf != NULL); +} + +/* ------------------- */ + +/* Main Driver Management API calls: + * Make a copy of the driver for the specified property on the given ID block + */ +short ANIM_copy_driver (ID *id, const char rna_path[], int array_index, short flag) +{ + PointerRNA id_ptr, ptr; + PropertyRNA *prop; + FCurve *fcu; + + /* validate pointer first - exit if failure */ + RNA_id_pointer_create(id, &id_ptr); + if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { + printf("Copy Driver: Could not find Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path); + return 0; + } + + /* try to get F-Curve with Driver */ + fcu= verify_driver_fcurve(id, rna_path, array_index, 0); + + /* clear copy/paste buffer first (for consistency with other copy/paste buffers) */ + free_anim_drivers_copybuf(); + + /* copy this to the copy/paste buf if it exists */ + if (fcu && fcu->driver) { + /* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily + * so that we don't end up wasting memory storing the path which won't get used ever... + */ + char *tmp_path = fcu->rna_path; + fcu->rna_path= NULL; + + /* make a copy of the F-Curve with */ + channeldriver_copypaste_buf= copy_fcurve(fcu); + + /* restore the path */ + fcu->rna_path= tmp_path; + + /* copied... */ + return 1; + } + + /* done */ + return 0; +} + +/* Main Driver Management API calls: + * Add a new driver for the specified property on the given ID block or replace an existing one + * with the driver + driver-curve data from the buffer + */ +short ANIM_paste_driver (ID *id, const char rna_path[], int array_index, short flag) +{ + PointerRNA id_ptr, ptr; + PropertyRNA *prop; + FCurve *fcu; + + /* validate pointer first - exit if failure */ + RNA_id_pointer_create(id, &id_ptr); + if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { + printf("Paste Driver: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path); + return 0; + } + + /* if the buffer is empty, cannot paste... */ + if (channeldriver_copypaste_buf == NULL) { + printf("Paste Driver: No Driver to paste. \n"); + return 0; + } + + /* create Driver F-Curve, but without data which will be copied across... */ + fcu= verify_driver_fcurve(id, rna_path, array_index, -1); + + if (fcu) { + /* copy across the curve data from the buffer curve + * NOTE: this step needs care to not miss new settings + */ + /* keyframes/samples */ + fcu->bezt= MEM_dupallocN(channeldriver_copypaste_buf->bezt); + fcu->fpt= MEM_dupallocN(channeldriver_copypaste_buf->fpt); + fcu->totvert= channeldriver_copypaste_buf->totvert; + + /* modifiers */ + copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers); + + /* flags - on a per-relevant-flag basis */ + if (channeldriver_copypaste_buf->flag & FCURVE_AUTO_HANDLES) + fcu->flag |= FCURVE_AUTO_HANDLES; + else + fcu->flag &= ~FCURVE_AUTO_HANDLES; + /* extrapolation mode */ + fcu->extend= channeldriver_copypaste_buf->extend; + + /* the 'juicy' stuff - the driver */ + fcu->driver= fcurve_copy_driver(channeldriver_copypaste_buf->driver); + } + + /* done */ + return (fcu != NULL); +} /* ************************************************** */ /* UI-Button Interface */ @@ -272,10 +399,11 @@ void ANIM_OT_add_driver_button (wmOperatorType *ot) /* identifiers */ ot->name= "Add Driver"; ot->idname= "ANIM_OT_add_driver_button"; + ot->description= "Add driver(s) for the property(s) connected represented by the highlighted button."; /* callbacks */ ot->exec= add_driver_button_exec; - //op->poll= ??? + //op->poll= ??? // TODO: need to have some animateable property to do this /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -335,10 +463,11 @@ void ANIM_OT_remove_driver_button (wmOperatorType *ot) /* identifiers */ ot->name= "Remove Driver"; ot->idname= "ANIM_OT_remove_driver_button"; + ot->description= "Remove the driver(s) for the property(s) connected represented by the highlighted button."; /* callbacks */ ot->exec= remove_driver_button_exec; - //op->poll= ??? + //op->poll= ??? // TODO: need to have some driver to be able to do this... /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -347,4 +476,92 @@ void ANIM_OT_remove_driver_button (wmOperatorType *ot) RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array."); } +/* Copy Driver Button Operator ------------------------ */ + +static int copy_driver_button_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr; + PropertyRNA *prop= NULL; + char *path; + short success= 0; + int index; + + /* try to create driver using property retrieved from UI */ + memset(&ptr, 0, sizeof(PointerRNA)); + uiAnimContextProperty(C, &ptr, &prop, &index); + + if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) { + path= RNA_path_from_ID_to_property(&ptr, prop); + + if (path) { + /* only copy the driver for the button that this was involved for */ + success= ANIM_copy_driver(ptr.id.data, path, index, 0); + + MEM_freeN(path); + } + } + + /* since we're just copying, we don't really need to do anything else...*/ + return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; +} + +void ANIM_OT_copy_driver_button (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Driver"; + ot->idname= "ANIM_OT_copy_driver_button"; + ot->description= "Copy the driver for the highlighted button."; + + /* callbacks */ + ot->exec= copy_driver_button_exec; + //op->poll= ??? // TODO: need to have some driver to be able to do this... + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* Paste Driver Button Operator ------------------------ */ + +static int paste_driver_button_exec (bContext *C, wmOperator *op) +{ + PointerRNA ptr; + PropertyRNA *prop= NULL; + char *path; + short success= 0; + int index; + + /* try to create driver using property retrieved from UI */ + memset(&ptr, 0, sizeof(PointerRNA)); + uiAnimContextProperty(C, &ptr, &prop, &index); + + if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) { + path= RNA_path_from_ID_to_property(&ptr, prop); + + if (path) { + /* only copy the driver for the button that this was involved for */ + success= ANIM_paste_driver(ptr.id.data, path, index, 0); + + MEM_freeN(path); + } + } + + /* since we're just copying, we don't really need to do anything else...*/ + return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; +} + +void ANIM_OT_paste_driver_button (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Paste Driver"; + ot->idname= "ANIM_OT_paste_driver_button"; + ot->description= "Paste the driver in the copy/paste buffer for the highlighted button."; + + /* callbacks */ + ot->exec= paste_driver_button_exec; + //op->poll= ??? // TODO: need to have some driver to be able to do this... + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* ************************************************** */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 20c2301d2ac..d30fccfe4de 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -163,6 +163,9 @@ void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot); /* ************ Drivers ********************** */ +/* Returns whether there is a driver in the copy/paste buffer to paste */ +short ANIM_driver_can_paste(void); + /* Main Driver Management API calls: * Add a new driver for the specified property on the given ID block */ @@ -171,11 +174,24 @@ short ANIM_add_driver (struct ID *id, const char rna_path[], int array_index, sh /* Main Driver Management API calls: * Remove the driver for the specified property on the given ID block (if available) */ -short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index, short flag); +short ANIM_remove_driver(struct ID *id, const char rna_path[], int array_index, short flag); + +/* Main Driver Management API calls: + * Make a copy of the driver for the specified property on the given ID block + */ +short ANIM_copy_driver(struct ID *id, const char rna_path[], int array_index, short flag); + +/* Main Driver Management API calls: + * Add a new driver for the specified property on the given ID block or replace an existing one + * with the driver + driver-curve data from the buffer + */ +short ANIM_paste_driver(struct ID *id, const char rna_path[], int array_index, short flag); /* Driver management operators for UI buttons */ void ANIM_OT_add_driver_button(struct wmOperatorType *ot); void ANIM_OT_remove_driver_button(struct wmOperatorType *ot); +void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); +void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); /* ************ Auto-Keyframing ********************** */ /* Notes: diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 8c41726b81b..8037a609a2f 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -209,6 +209,18 @@ void ui_but_anim_remove_driver(bContext *C) WM_operator_name_call(C, "ANIM_OT_remove_driver_button", WM_OP_INVOKE_DEFAULT, NULL); } +void ui_but_anim_copy_driver(bContext *C) +{ + /* this operator calls uiAnimContextProperty above */ + WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL); +} + +void ui_but_anim_paste_driver(bContext *C) +{ + /* this operator calls uiAnimContextProperty above */ + WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL); +} + void ui_but_anim_add_keyingset(bContext *C) { /* this operator calls uiAnimContextProperty above */ @@ -264,6 +276,10 @@ void ui_but_anim_menu(bContext *C, uiBut *but) } else uiItemBooleanO(layout, "Delete Driver", 0, "ANIM_OT_remove_driver_button", "all", 0); + + uiItemO(layout, "Copy Driver", 0, "ANIM_OT_copy_driver_button"); + if (ANIM_driver_can_paste()) + uiItemO(layout, "Paste Driver", 0, "ANIM_OT_paste_driver_button"); } else if(but->flag & UI_BUT_ANIMATED_KEY); else if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) { @@ -275,6 +291,9 @@ void ui_but_anim_menu(bContext *C, uiBut *but) } else uiItemBooleanO(layout, "Add Driver", 0, "ANIM_OT_add_driver_button", "all", 0); + + if (ANIM_driver_can_paste()) + uiItemO(layout, "Paste Driver", 0, "ANIM_OT_paste_driver_button"); } if(RNA_property_animateable(&but->rnapoin, but->rnaprop)) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 7ab99a83c4b..885005ba06e 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -470,6 +470,8 @@ void ui_but_anim_insert_keyframe(struct bContext *C); void ui_but_anim_delete_keyframe(struct bContext *C); void ui_but_anim_add_driver(struct bContext *C); void ui_but_anim_remove_driver(struct bContext *C); +void ui_but_anim_copy_driver(struct bContext *C); +void ui_but_anim_paste_driver(struct bContext *C); void ui_but_anim_add_keyingset(struct bContext *C); void ui_but_anim_remove_keyingset(struct bContext *C); void ui_but_anim_menu(struct bContext *C, uiBut *but); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index afbbfb61cba..e3c392a145e 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -480,7 +480,7 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h, int icon_only) { uiLayout *sub; - uiBut *but; + uiBut *but=NULL; PropertyType type; PropertySubType subtype; int labelw; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 5c78b32f3f8..1074c424663 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -166,6 +166,7 @@ extern wchar_t *copybufinfo; // XXX copy/paste buffer stuff... extern void free_anim_copybuf(); +extern void free_anim_drivers_copybuf(); extern void free_posebuf(); /* called in creator.c even... tsk, split this! */ @@ -213,6 +214,7 @@ void WM_exit(bContext *C) free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); free_anim_copybuf(); + free_anim_drivers_copybuf(); free_posebuf(); // free_vertexpaint(); // free_imagepaint(); -- cgit v1.2.3 From b8c7910be12aab527fedfad7cab9337eaa5782a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 05:25:44 +0000 Subject: - use pythons time module rather then bpy.sys.time() - comment poll functions, maybe could check for editable scene later - importing OBJs imports triangle meshes. --- release/io/import_3ds.py | 6 +++--- release/io/import_obj.py | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py index f2dc99d5b7e..d57911df83c 100644 --- a/release/io/import_3ds.py +++ b/release/io/import_3ds.py @@ -1154,10 +1154,10 @@ class IMPORT_OT_3ds(bpy.types.Operator): wm = context.manager wm.add_fileselect(self.__operator__) return ('RUNNING_MODAL',) - - def poll(self, context): # Poll isnt working yet + ''' + def poll(self, context): print("Poll") - return context.active_object != None + return context.active_object != None''' bpy.ops.add(IMPORT_OT_3ds) diff --git a/release/io/import_obj.py b/release/io/import_obj.py index 34f6575dba2..9a00dc1cc2a 100644 --- a/release/io/import_obj.py +++ b/release/io/import_obj.py @@ -41,7 +41,7 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo # -------------------------------------------------------------------------- import os - +import time import bpy import Mathutils import Geometry @@ -993,7 +993,7 @@ def load_obj(filepath, if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: POLYGROUPS = False - time_main= bpy.sys.time() + time_main= time.time() # time_main= sys.time() verts_loc= [] @@ -1032,7 +1032,7 @@ def load_obj(filepath, context_multi_line= '' print('\tparsing obj file "%s"...' % filepath) - time_sub= bpy.sys.time() + time_sub= time.time() # time_sub= sys.time() file= open(filepath, 'rU') @@ -1241,7 +1241,7 @@ def load_obj(filepath, ''' file.close() - time_new= bpy.sys.time() + time_new= time.time() # time_new= sys.time() print('%.4f sec' % (time_new-time_sub)) time_sub= time_new @@ -1250,7 +1250,7 @@ def load_obj(filepath, print('\tloading materials and images...') create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) - time_new= bpy.sys.time() + time_new= time.time() # time_new= sys.time() print('%.4f sec' % (time_new-time_sub)) time_sub= time_new @@ -1307,7 +1307,7 @@ def load_obj(filepath, # for ob in new_objects: # ob.RotX = -1.570796326794896558 - time_new= bpy.sys.time() + time_new= time.time() # time_new= sys.time() print('%.4f sec' % (time_new-time_sub)) @@ -1585,9 +1585,9 @@ class IMPORT_OT_obj(bpy.types.Operator): bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True), ] + ''' def poll(self, context): - print("Poll") - return context.active_object != None + return True ''' def execute(self, context): # print("Selected: " + context.active_object.name) -- cgit v1.2.3 From 7c9bb3c40aecbb6e8e8045637c501433eed251f0 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 25 Sep 2009 07:44:29 +0000 Subject: Fix OSX compilation problem with malloc.h in itasc --- intern/itasc/Armature.cpp | 4 +++- intern/itasc/Cache.cpp | 5 +++-- intern/itasc/CopyPose.cpp | 1 - intern/itasc/Distance.cpp | 1 - intern/itasc/MovingFrame.cpp | 1 - 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp index 2491b0f8c9f..6ae60089cd8 100644 --- a/intern/itasc/Armature.cpp +++ b/intern/itasc/Armature.cpp @@ -7,8 +7,10 @@ #include "Armature.hpp" #include -#include #include +#ifndef __STDC__ +#include +#endif namespace iTaSC { diff --git a/intern/itasc/Cache.cpp b/intern/itasc/Cache.cpp index 1a1a3b4d009..d61e5a9eab5 100644 --- a/intern/itasc/Cache.cpp +++ b/intern/itasc/Cache.cpp @@ -6,11 +6,12 @@ */ #include #include +#include +#ifndef __STDC__ #include +#endif #include "Cache.hpp" -#include - namespace iTaSC { CacheEntry::~CacheEntry() diff --git a/intern/itasc/CopyPose.cpp b/intern/itasc/CopyPose.cpp index 3bf7edd7975..7977089d280 100644 --- a/intern/itasc/CopyPose.cpp +++ b/intern/itasc/CopyPose.cpp @@ -8,7 +8,6 @@ #include "CopyPose.hpp" #include "kdl/kinfam_io.hpp" #include -#include #include namespace iTaSC diff --git a/intern/itasc/Distance.cpp b/intern/itasc/Distance.cpp index 0f61e7666b2..bf19a978888 100644 --- a/intern/itasc/Distance.cpp +++ b/intern/itasc/Distance.cpp @@ -8,7 +8,6 @@ #include "Distance.hpp" #include "kdl/kinfam_io.hpp" #include -#include #include namespace iTaSC diff --git a/intern/itasc/MovingFrame.cpp b/intern/itasc/MovingFrame.cpp index c0995383c4b..e923b1fab27 100644 --- a/intern/itasc/MovingFrame.cpp +++ b/intern/itasc/MovingFrame.cpp @@ -6,7 +6,6 @@ */ #include "MovingFrame.hpp" -#include #include namespace iTaSC{ -- cgit v1.2.3 From 5eecb2ab48547449cfd9d668b92cb257bbd8da86 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 25 Sep 2009 09:33:46 +0000 Subject: Warning fixes for ITASC. Also, use instead of , it works everywhere. --- intern/itasc/Armature.cpp | 14 +++++++----- intern/itasc/Cache.cpp | 4 +--- intern/itasc/ConstraintSet.cpp | 8 +++---- intern/itasc/CopyPose.cpp | 4 ++-- intern/itasc/WSDLSSolver.hpp | 2 ++ intern/itasc/kdl/jacobian.cpp | 4 ++-- intern/itasc/kdl/treefksolverpos_recursive.cpp | 1 - source/blender/ikplugin/intern/ikplugin_api.c | 2 -- source/blender/ikplugin/intern/itasc_plugin.cpp | 29 +++++++++---------------- 9 files changed, 30 insertions(+), 38 deletions(-) diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp index 6ae60089cd8..7776b6aa3b6 100644 --- a/intern/itasc/Armature.cpp +++ b/intern/itasc/Armature.cpp @@ -8,9 +8,7 @@ #include "Armature.hpp" #include #include -#ifndef __STDC__ -#include -#endif +#include namespace iTaSC { @@ -37,9 +35,9 @@ Armature::Armature(): m_newqKdl(), m_qdotKdl(), m_jac(NULL), + m_armlength(0.0), m_jacsolver(NULL), - m_fksolver(NULL), - m_armlength(0.0) + m_fksolver(NULL) { } @@ -119,6 +117,8 @@ Armature::JointConstraint_struct::JointConstraint_struct(SegmentMap::const_itera values[1].id = value[1].id = ID_JOINT_RZ; v_nr = 2; break; + case Joint::None: + break; } } @@ -734,6 +734,8 @@ bool Armature::setControlParameter(unsigned int constraintId, unsigned int value case ACT_ALPHA: pConstraint->values[i].alpha = value; break; + default: + break; } } } else { @@ -755,6 +757,8 @@ bool Armature::setControlParameter(unsigned int constraintId, unsigned int value case ACT_ALPHA: pConstraint->values[i].alpha = value; break; + case ACT_NONE: + break; } } } diff --git a/intern/itasc/Cache.cpp b/intern/itasc/Cache.cpp index d61e5a9eab5..ccd9cef4655 100644 --- a/intern/itasc/Cache.cpp +++ b/intern/itasc/Cache.cpp @@ -7,9 +7,7 @@ #include #include #include -#ifndef __STDC__ -#include -#endif +#include #include "Cache.hpp" namespace iTaSC { diff --git a/intern/itasc/ConstraintSet.cpp b/intern/itasc/ConstraintSet.cpp index eaffc2a52f9..a38db445ea2 100644 --- a/intern/itasc/ConstraintSet.cpp +++ b/intern/itasc/ConstraintSet.cpp @@ -12,13 +12,13 @@ namespace iTaSC { ConstraintSet::ConstraintSet(unsigned int _nc,double accuracy,unsigned int maximum_iterations): m_nc(_nc), - m_Jf(e_identity_matrix(6,6)), m_Cf(e_zero_matrix(m_nc,6)), - m_U(e_identity_matrix(6,6)),m_V(e_identity_matrix(6,6)),m_B(e_zero_matrix(6,6)), - m_Jf_inv(e_zero_matrix(6,6)), m_Wy(e_scalar_vector(m_nc,1.0)), - m_chi(e_zero_vector(6)),m_y(m_nc),m_ydot(e_zero_vector(m_nc)), + m_y(m_nc),m_ydot(e_zero_vector(m_nc)),m_chi(e_zero_vector(6)), m_S(6),m_temp(6),m_tdelta(6), + m_Jf(e_identity_matrix(6,6)), + m_U(e_identity_matrix(6,6)),m_V(e_identity_matrix(6,6)),m_B(e_zero_matrix(6,6)), + m_Jf_inv(e_zero_matrix(6,6)), m_internalPose(F_identity), m_externalPose(F_identity), m_constraintCallback(NULL), m_constraintParam(NULL), m_toggle(false),m_substep(false), diff --git a/intern/itasc/CopyPose.cpp b/intern/itasc/CopyPose.cpp index 7977089d280..69722909ed1 100644 --- a/intern/itasc/CopyPose.cpp +++ b/intern/itasc/CopyPose.cpp @@ -21,7 +21,7 @@ CopyPose::CopyPose(unsigned int control_output, unsigned int dynamic_output, dou { m_maxerror = armlength/2.0; m_outputControl = (control_output & CTL_ALL); - int _nc = nBitsOn(m_outputControl); + unsigned int _nc = nBitsOn(m_outputControl); if (!_nc) return; // reset the constraint set @@ -284,7 +284,7 @@ void CopyPose::updateJacobian() void CopyPose::updateState(ConstraintValues* _values, ControlState* _state, unsigned int mask, double timestep) { - int id = (mask == CTL_ROTATIONX) ? ID_ROTATIONX : ID_POSITIONX; + unsigned int id = (mask == CTL_ROTATIONX) ? ID_ROTATIONX : ID_POSITIONX; ControlState::ControlValue* _yval; ConstraintSingleValue* _data; int i, j, k; diff --git a/intern/itasc/WSDLSSolver.hpp b/intern/itasc/WSDLSSolver.hpp index 90f89f4e853..1341cf2af66 100644 --- a/intern/itasc/WSDLSSolver.hpp +++ b/intern/itasc/WSDLSSolver.hpp @@ -31,6 +31,8 @@ public: case DLS_QMAX: m_qmax = value; break; + default: + break; } } }; diff --git a/intern/itasc/kdl/jacobian.cpp b/intern/itasc/kdl/jacobian.cpp index 4166a341fe7..f8f46b32619 100644 --- a/intern/itasc/kdl/jacobian.cpp +++ b/intern/itasc/kdl/jacobian.cpp @@ -55,13 +55,13 @@ namespace KDL double Jacobian::operator()(int i,int j)const { - assert(i<6*nr_blocks&&jsecond; p_out = recursiveFk(q_in, it, baseit); return 0; } diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c index 714843fc5e5..f106302dbaf 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.c +++ b/source/blender/ikplugin/intern/ikplugin_api.c @@ -72,8 +72,6 @@ static IKPlugin ikplugin_tab[BIK_SOLVER_COUNT] = { static IKPlugin *get_plugin(bPose *pose) { - IKPlugin *plugin; - if (!pose || pose->iksolver < 0 || pose->iksolver >= BIK_SOLVER_COUNT) return NULL; diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index b6278e40ea5..4aebda1347c 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -354,7 +354,7 @@ static int initialize_chain(Object *ob, bPoseChannel *pchan_tip, bConstraint *co static bool is_cartesian_constraint(bConstraint *con) { - bKinematicConstraint* data=(bKinematicConstraint*)con->data; + //bKinematicConstraint* data=(bKinematicConstraint*)con->data; return true; } @@ -379,12 +379,8 @@ static bool constraint_valid(bConstraint *con) int initialize_scene(Object *ob, bPoseChannel *pchan_tip) { - bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan; - PoseTree *tree; - PoseTarget *target; bConstraint *con; - bKinematicConstraint *data; - int a, segcount= 0, size, newsize, *oldparent, parent, rootbone, treecount; + int treecount; /* find all IK constraints and validate them */ treecount = 0; @@ -456,6 +452,7 @@ static void RemoveEulerAngleFromMatrix(KDL::Rotation& R, double angle, int axis) R = R*T; } +#if 0 static void GetEulerXZY(const KDL::Rotation& R, double& X,double& Z,double& Y) { if (fabs(R(0,1)) > 1.0 - KDL::epsilon ) { @@ -481,6 +478,7 @@ static void GetEulerXYZ(const KDL::Rotation& R, double& X,double& Y,double& Z) Z = KDL::atan2(-R(0,1), R(0,0)); } } +#endif static void GetJointRotation(KDL::Rotation& boneRot, int type, double* rot) { @@ -660,9 +658,6 @@ static bool copypose_callback(const iTaSC::Timestamp& timestamp, iTaSC::Constrai bKinematicConstraint *condata = (bKinematicConstraint *)iktarget->blenderConstraint->data; iTaSC::ConstraintValues* values = _values; bItasc* ikparam = (bItasc*) iktarget->owner->pose->ikparam; - iTaSC::ConstraintSingleValue* value; - double error; - int i; // we need default parameters if (!ikparam) @@ -839,7 +834,7 @@ static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintV break; } if (dof >= 0) { - for (int i=0; i<_nvalues; i++, dof++) { + for (unsigned int i=0; i<_nvalues; i++, dof++) { _values[i].values[0].yd = ikchan->jointValue[dof]; _values[i].alpha = chan->ikrotweight; _values[i].feedback = ikparam->feedback; @@ -853,7 +848,6 @@ static int convert_channels(IK_Scene *ikscene, PoseTree *tree) { IK_Channel *ikchan; bPoseChannel *pchan; - PoseTarget* target; Bone *bone; int a, flag, njoint; @@ -1046,11 +1040,11 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) KDL::Frame initPose; KDL::Rotation boneRot; Bone *bone; - int a, t, numtarget; + int a, numtarget; + unsigned int t; float length; bool ret = true, ingame; double *rot; - double lmin[3], lmax[3]; if (tree->totchannel == 0) return NULL; @@ -1105,7 +1099,6 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) double weight[3]; // assume uniform scaling and take Y scale as general scale for the armature float scale = VecLength(ob->obmat[1]); - double X, Y, Z; // build the array of joints corresponding to the IK chain convert_channels(ikscene, tree); if (ingame) { @@ -1366,8 +1359,8 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) } // set the weight e_matrix& Wq = arm->getWq(); - assert(Wq.cols() == weights.size()); - for (unsigned int q=0; qpose->ikdata) { for(IK_Scene* scene = ((IK_Data*)ob->pose->ikdata)->first; scene != NULL; @@ -1559,7 +1550,7 @@ static void execute_scene(Scene* blscene, IK_Scene* ikscene, bItasc* ikparam, fl } if (ikscene->cache && !reiterate && simulation) { - iTaSC::CacheTS sts, cts, dts; + iTaSC::CacheTS sts, cts; sts = cts = (iTaSC::CacheTS)(timestamp*1000.0+0.5); if (ikscene->cache->getPreviousCacheItem(ikscene->armature, 0, &cts) == NULL || cts == 0) { // the cache is empty before this time, reiterate -- cgit v1.2.3 From 40c175f8f6073d57a80f1ee86efe6d57ad691633 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 10:24:42 +0000 Subject: modal kaymaps for view3d rotate/move/zoom removed redundant 'view' prefix from these operators. --- source/blender/editors/space_view3d/view3d_edit.c | 221 ++++++++++++++++----- .../blender/editors/space_view3d/view3d_intern.h | 7 +- source/blender/editors/space_view3d/view3d_ops.c | 11 +- 3 files changed, 188 insertions(+), 51 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 5e3a6ae0e02..640252287fe 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -239,9 +239,10 @@ typedef struct ViewOpsData { float ofs[3], obofs[3]; float reverse, dist0; float grid, far; + short axis_snap; /* view rotate only */ int origx, origy, oldx, oldy; - int origkey; + int origkey; /* the key that triggered the operator */ } ViewOpsData; @@ -289,7 +290,7 @@ static void viewops_data(bContext *C, wmOperator *op, wmEvent *event) QUATCOPY(vod->oldquat, rv3d->viewquat); vod->origx= vod->oldx= event->x; vod->origy= vod->oldy= event->y; - vod->origkey= event->type; + vod->origkey= event->type; /* the key that triggered the operator. */ /* lookup, we dont pass on v3d to prevent confusement */ vod->grid= v3d->grid; @@ -357,11 +358,52 @@ static float snapquats[39][6] = { {0.0, 0.0, 0.0, 1.0, 0, 0} }; +enum { + VIEW_PASS= 0, + VIEW_APPLY, + VIEW_CONFIRM +}; + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +#define VIEW_MODAL_CONFIRM 1 /* used for all view operations */ +#define VIEWROT_MODAL_AXIS_SNAP_ENABLE 2 +#define VIEWROT_MODAL_AXIS_SNAP_DISABLE 3 + + +/* called in transform_ops.c, on each regeneration of keymaps */ +void viewrotate_modal_keymap(wmWindowManager *wm) +{ + static EnumPropertyItem modal_items[] = { + {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Cancel", ""}, + + {VIEWROT_MODAL_AXIS_SNAP_ENABLE, "AXIS_SNAP_ENABLE", 0, "Enable Axis Snap", ""}, + {VIEWROT_MODAL_AXIS_SNAP_DISABLE, "AXIS_SNAP_DISABLE", 0, "Enable Axis Snap", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Rotate Modal"); -static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl) + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(wm, "View3D Rotate Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate"); + +} + +static void viewrotate_apply(ViewOpsData *vod, int x, int y) { RegionView3D *rv3d= vod->rv3d; - int use_sel= 0; /* XXX */ + int use_sel= U.uiflag & USER_ORBIT_SELECTION; rv3d->view= 0; /* need to reset everytime because of view snapping */ @@ -462,7 +504,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl) } /* check for view snap */ - if (ctrl){ + if (vod->axis_snap){ int i; float viewmat[3][3]; @@ -496,23 +538,41 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl) static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewOpsData *vod= op->customdata; + short event_code= VIEW_PASS; /* execute the events */ - switch(event->type) { - case MOUSEMOVE: - viewrotate_apply(vod, event->x, event->y, event->ctrl); - break; + if(event->type==MOUSEMOVE) { + event_code= VIEW_APPLY; + } + else if(event->type==EVT_MODAL_MAP) { + switch (event->val) { + case VIEW_MODAL_CONFIRM: + event_code= VIEW_CONFIRM; + break; + case VIEWROT_MODAL_AXIS_SNAP_ENABLE: + vod->axis_snap= TRUE; + event_code= VIEW_APPLY; + break; + case VIEWROT_MODAL_AXIS_SNAP_DISABLE: + vod->axis_snap= FALSE; + event_code= VIEW_APPLY; + break; + } + } + else if(event->type==vod->origkey && event->val==KM_RELEASE) { + event_code= VIEW_CONFIRM; + } - default: - /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==KM_RELEASE)) { - request_depth_update(CTX_wm_region_view3d(C)); + if(event_code==VIEW_APPLY) { + viewrotate_apply(vod, event->x, event->y); + } + else if (event_code==VIEW_CONFIRM) { + request_depth_update(CTX_wm_region_view3d(C)); - MEM_freeN(vod); - op->customdata= NULL; + MEM_freeN(vod); + op->customdata= NULL; - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; @@ -547,13 +607,13 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } -void VIEW3D_OT_viewrotate(wmOperatorType *ot) +void VIEW3D_OT_rotate(wmOperatorType *ot) { /* identifiers */ ot->name= "Rotate view"; ot->description = "Rotate the view."; - ot->idname= "VIEW3D_OT_viewrotate"; + ot->idname= "VIEW3D_OT_rotate"; /* api callbacks */ ot->invoke= viewrotate_invoke; @@ -566,6 +626,33 @@ void VIEW3D_OT_viewrotate(wmOperatorType *ot) /* ************************ viewmove ******************************** */ + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ + +/* called in transform_ops.c, on each regeneration of keymaps */ +void viewmove_modal_keymap(wmWindowManager *wm) +{ + static EnumPropertyItem modal_items[] = { + {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Move Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(wm, "View3D Move Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_move"); +} + + static void viewmove_apply(ViewOpsData *vod, int x, int y) { if(vod->rv3d->persp==V3D_CAMOB) { @@ -596,24 +683,35 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y) static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event) { + ViewOpsData *vod= op->customdata; + short event_code= VIEW_PASS; /* execute the events */ - switch(event->type) { - case MOUSEMOVE: - viewmove_apply(vod, event->x, event->y); - break; + if(event->type==MOUSEMOVE) { + event_code= VIEW_APPLY; + } + else if(event->type==EVT_MODAL_MAP) { + switch (event->val) { + case VIEW_MODAL_CONFIRM: + event_code= VIEW_CONFIRM; + break; + } + } + else if(event->type==vod->origkey && event->val==KM_RELEASE) { + event_code= VIEW_CONFIRM; + } - default: - /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==KM_RELEASE)) { - request_depth_update(CTX_wm_region_view3d(C)); + if(event_code==VIEW_APPLY) { + viewmove_apply(vod, event->x, event->y); + } + else if (event_code==VIEW_CONFIRM) { + request_depth_update(CTX_wm_region_view3d(C)); - MEM_freeN(vod); - op->customdata= NULL; + MEM_freeN(vod); + op->customdata= NULL; - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; @@ -631,13 +729,13 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) } -void VIEW3D_OT_viewmove(wmOperatorType *ot) +void VIEW3D_OT_move(wmOperatorType *ot) { /* identifiers */ ot->name= "Move view"; ot->description = "Move the view."; - ot->idname= "VIEW3D_OT_viewmove"; + ot->idname= "VIEW3D_OT_move"; /* api callbacks */ ot->invoke= viewmove_invoke; @@ -650,6 +748,29 @@ void VIEW3D_OT_viewmove(wmOperatorType *ot) /* ************************ viewzoom ******************************** */ +/* called in transform_ops.c, on each regeneration of keymaps */ +void viewzoom_modal_keymap(wmWindowManager *wm) +{ + static EnumPropertyItem modal_items[] = { + {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Zoom Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(wm, "View3D Zoom Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom"); +} + static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my) { RegionView3D *rv3d= ar->regiondata; @@ -758,23 +879,33 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y) static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewOpsData *vod= op->customdata; + short event_code= VIEW_PASS; /* execute the events */ - switch(event->type) { - case MOUSEMOVE: - viewzoom_apply(vod, event->x, event->y); - break; + if(event->type==MOUSEMOVE) { + event_code= VIEW_APPLY; + } + else if(event->type==EVT_MODAL_MAP) { + switch (event->val) { + case VIEW_MODAL_CONFIRM: + event_code= VIEW_CONFIRM; + break; + } + } + else if(event->type==vod->origkey && event->val==KM_RELEASE) { + event_code= VIEW_CONFIRM; + } - default: - /* origkey may be zero when invoked from a button */ - if(ELEM3(event->type, ESCKEY, LEFTMOUSE, RIGHTMOUSE) || (event->type==vod->origkey && event->val==KM_RELEASE)) { - request_depth_update(CTX_wm_region_view3d(C)); + if(event_code==VIEW_APPLY) { + viewzoom_apply(vod, event->x, event->y); + } + else if (event_code==VIEW_CONFIRM) { + request_depth_update(CTX_wm_region_view3d(C)); - MEM_freeN(vod); - op->customdata= NULL; + MEM_freeN(vod); + op->customdata= NULL; - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; } return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index d532d2b2cc8..e7ab79ab955 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -66,8 +66,8 @@ void view3d_keymap(struct wmWindowManager *wm); /* view3d_edit.c */ void VIEW3D_OT_zoom(struct wmOperatorType *ot); -void VIEW3D_OT_viewmove(struct wmOperatorType *ot); -void VIEW3D_OT_viewrotate(struct wmOperatorType *ot); +void VIEW3D_OT_move(struct wmOperatorType *ot); +void VIEW3D_OT_rotate(struct wmOperatorType *ot); void VIEW3D_OT_view_all(struct wmOperatorType *ot); void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot); void VIEW3D_OT_view_center(struct wmOperatorType *ot); @@ -137,6 +137,9 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for pick void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); void fly_modal_keymap(struct wmWindowManager *wm); +void viewrotate_modal_keymap(struct wmWindowManager *wm); +void viewmove_modal_keymap(struct wmWindowManager *wm); +void viewzoom_modal_keymap(struct wmWindowManager *wm); /* view3d_buttons.c */ void VIEW3D_OT_properties(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 23dd092ce38..f9cedbd28a1 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -62,8 +62,8 @@ void view3d_operatortypes(void) { - WM_operatortype_append(VIEW3D_OT_viewrotate); - WM_operatortype_append(VIEW3D_OT_viewmove); + WM_operatortype_append(VIEW3D_OT_rotate); + WM_operatortype_append(VIEW3D_OT_move); WM_operatortype_append(VIEW3D_OT_zoom); WM_operatortype_append(VIEW3D_OT_view_all); WM_operatortype_append(VIEW3D_OT_viewnumpad); @@ -119,8 +119,8 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center", PADPERIOD, KM_PRESS, 0, 0); @@ -222,5 +222,8 @@ void view3d_keymap(wmWindowManager *wm) transform_keymap_for_space(wm, keymap, SPACE_VIEW3D); fly_modal_keymap(wm); + viewrotate_modal_keymap(wm); + viewmove_modal_keymap(wm); + viewzoom_modal_keymap(wm); } -- cgit v1.2.3 From ff7157d6f840acbd818c83ccf6ae8e06f1784788 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 25 Sep 2009 10:52:29 +0000 Subject: Graph Editor: Drawing + Selection Tweaks * Deselect all now selects/deselects F-Curves too * Tangents of unselected F-Curves now draw 'faded' like the curves they belong to. This experimental change is quite subtle, but can be made stronger still if people want. * Cleaned up some old comments in the code too... --- source/blender/editors/space_graph/graph_draw.c | 72 +++++++++++++++-------- source/blender/editors/space_graph/graph_select.c | 9 ++- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 9ae7e8263ee..38430045bef 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -90,6 +90,26 @@ /* XXX */ extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); +/* *************************** */ +/* Utility Drawing Defines */ + +/* determine the alpha value that should be used when + * drawing components for some F-Curve (fcu) + * - selected F-Curves should be more visible than partially visible ones + */ +#define drawFCurveFade(fcu) ( ((fcu)->flag & FCURVE_SELECTED)? 1.0f : 0.5f ) + +/* set the colour for some point from some value given packed into an int + * - intV: integer value containing color info packed into an int + * - alpha: float value describing the + */ +#define cpackA(intVC, alpha) \ + { \ + float _cpackCol[3]; \ + cpack_to_rgb(intVC, &_cpackCol[0], &_cpackCol[1], &_cpackCol[2]); \ + glColor4f(_cpackCol[0], _cpackCol[1], _cpackCol[2], alpha); \ + } + /* *************************** */ /* F-Curve Modifier Drawing */ @@ -258,22 +278,20 @@ static void draw_fcurve_vertices_handles (FCurve *fcu, View2D *v2d, short sel) /* helper func - set color to draw F-Curve data with */ static void set_fcurve_vertex_color (SpaceIpo *sipo, FCurve *fcu, short sel) { -#if 0 - if (sipo->showkey) { - if (sel) UI_ThemeColor(TH_TEXT_HI); - else UI_ThemeColor(TH_TEXT); - } -#endif - if ((fcu->flag & FCURVE_PROTECTED)==0) { - /* Curve's points are being edited */ - if (sel) UI_ThemeColor(TH_VERTEX_SELECT); - else UI_ThemeColor(TH_VERTEX); - } - else { - /* Curve's points cannot be edited */ - if (sel) UI_ThemeColor(TH_TEXT_HI); - else UI_ThemeColor(TH_TEXT); - } + /* Fade the 'intensity' of the vertices based on the selection of the curves too */ + int alphaOffset= (int)((drawFCurveFade(fcu) - 1.0f) * 255); + + /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */ + if ((fcu->flag & FCURVE_PROTECTED)==0) { + /* Curve's points ARE BEING edited */ + if (sel) UI_ThemeColorShadeAlpha(TH_VERTEX_SELECT, 0, alphaOffset); + else UI_ThemeColorShadeAlpha(TH_VERTEX, 0, alphaOffset); + } + else { + /* Curve's points CANNOT BE edited */ + if (sel) UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, alphaOffset); + else UI_ThemeColorShadeAlpha(TH_TEXT, 0, alphaOffset); + } } @@ -322,7 +340,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu) if ((sipo->flag & SIPO_NOHANDLES) || (fcu->flag & FCURVE_PROTECTED) || (fcu->flag & FCURVE_INT_VALUES)) return; - /* slightly hacky, but we want to draw unselected points before selected ones*/ + /* slightly hacky, but we want to draw unselected points before selected ones */ for (sel= 0; sel < 2; sel++) { BezTriple *bezt=fcu->bezt, *prevbezt=NULL; float *fp; @@ -337,7 +355,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu) /* only draw first handle if previous segment had handles */ if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) { - cpack(col[(unsigned char)bezt->h1]); + cpackA(col[(unsigned char)bezt->h1], drawFCurveFade(fcu)); glBegin(GL_LINE_STRIP); glVertex2fv(fp); glVertex2fv(fp+3); glEnd(); @@ -347,7 +365,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu) /* only draw second handle if this segment is bezier */ if (bezt->ipo == BEZT_IPO_BEZ) { - cpack(col[(unsigned char)bezt->h2]); + cpackA(col[(unsigned char)bezt->h2], drawFCurveFade(fcu)); glBegin(GL_LINE_STRIP); glVertex2fv(fp+3); glVertex2fv(fp+6); glEnd(); @@ -359,7 +377,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu) ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) ) { fp= bezt->vec[0]; - cpack(col[(unsigned char)bezt->h1]); + cpackA(col[(unsigned char)bezt->h1], drawFCurveFade(fcu)); glBegin(GL_LINE_STRIP); glVertex2fv(fp); glVertex2fv(fp+3); @@ -371,7 +389,7 @@ static void draw_fcurve_handles (SpaceIpo *sipo, ARegion *ar, FCurve *fcu) (bezt->ipo == BEZT_IPO_BEZ) ) { fp= bezt->vec[1]; - cpack(col[(unsigned char)bezt->h2]); + cpackA(col[(unsigned char)bezt->h2], drawFCurveFade(fcu)); glBegin(GL_LINE_STRIP); glVertex2fv(fp); glVertex2fv(fp+3); @@ -410,7 +428,6 @@ static void draw_fcurve_sample_control (float x, float y, float xscale, float ys glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f); /* anti-aliased lines for more consistent appearance */ - // XXX needed here? glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); @@ -506,7 +523,6 @@ static void draw_fcurve_curve (FCurve *fcu, SpaceIpo *sipo, View2D *v2d, View2DG } /* helper func - draw a samples-based F-Curve */ -// TODO: add offset stuff... static void draw_fcurve_curve_samples (FCurve *fcu, View2D *v2d) { FPoint *prevfpt= fcu->fpt; @@ -647,7 +663,7 @@ static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid) */ /* resol not depending on horizontal resolution anymore, drivers for example... */ - // XXX need to take into account the scale + // TODO: would be nice to make this depend on the scale of the graph too... if (fcu->driver) resol= 32; else @@ -809,7 +825,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri /* set whatever color the curve has set * - unselected curves draw less opaque to help distinguish the selected ones */ - glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], ((sel) ? 1.0f : 0.5f)); + glColor4f(fcu->color[0], fcu->color[1], fcu->color[2], drawFCurveFade(fcu)); } /* anti-aliased lines for less jagged appearance */ @@ -842,6 +858,9 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri * - if the option to only show controls if the F-Curve is selected is enabled, we must obey this */ if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) { + /* enable blending to allow fading of curves */ + glEnable(GL_BLEND); + if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) { /* only draw controls if this is the active modifier */ if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) { @@ -863,6 +882,9 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri draw_fcurve_samples(sipo, ar, fcu); } } + + /* restore settings */ + glDisable(GL_BLEND); } /* undo mapping of keyframes for drawing if scaled F-Curve */ diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 728c9310a47..7eec9f31d86 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -142,9 +142,13 @@ static void deselect_graph_keys (bAnimContext *ac, short test, short sel) /* Keyframes First */ ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, sel_cb, NULL); - /* deactivate the F-Curve, and deselect if deselecting keyframes */ + /* deactivate the F-Curve, and deselect if deselecting keyframes. + * otherwise select the F-Curve too since we've selected all the keyframes + */ if (sel == SELECT_SUBTRACT) fcu->flag &= ~FCURVE_SELECTED; + else + fcu->flag |= FCURVE_SELECTED; fcu->flag &= ~FCURVE_ACTIVE; } @@ -259,8 +263,9 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho /* select the curve too * NOTE: this should really only happen if the curve got touched... */ - if (selectmode == SELECT_ADD) + if (selectmode == SELECT_ADD) { fcu->flag |= FCURVE_SELECTED; + } } /* cleanup */ -- cgit v1.2.3 From f49a18f30be875d9cae5a1872f40dc02ce0f1473 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 25 Sep 2009 12:20:31 +0000 Subject: Graph Editor: F-Modifiers can now be added to multiple selected F-Curves at once with the Ctrl-Shift-M hotkey. * All the selected F-Curves will get the same type of F-Modifier added. * The button in the properties region will still only added the F-Modifier to the active F-Curve though * For now, there must be an active F-Curve in either case, otherwise the poll() callback fails. --- source/blender/editors/space_graph/graph_edit.c | 53 +++++++++++++++---------- source/blender/editors/space_graph/graph_ops.c | 2 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index d718ef28e99..9e0d574ffa3 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1710,13 +1710,18 @@ static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *eve /* start from 1 to skip the 'Invalid' modifier type */ for (i = 1; i < FMODIFIER_NUM_TYPES; i++) { FModifierTypeInfo *fmi= get_fmodifier_typeinfo(i); + PointerRNA props_ptr; /* check if modifier is valid for this context */ if (fmi == NULL) continue; - /* add entry to add this type of modifier */ - uiItemEnumO(layout, fmi->name, 0, "GRAPH_OT_fmodifier_add", "type", i); + /* create operator menu item with relevant properties filled in */ + props_ptr= uiItemFullO(layout, fmi->name, 0, "GRAPH_OT_fmodifier_add", NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + /* the only thing that gets set from the menu is the type of F-Modifier to add */ + RNA_enum_set(&props_ptr, "type", i); + /* the following properties are just repeats of existing ones... */ + RNA_boolean_set(&props_ptr, "only_active", RNA_boolean_get(op->ptr, "only_active")); } uiItemS(layout); @@ -1728,36 +1733,41 @@ static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *eve static int graph_fmodifier_add_exec(bContext *C, wmOperator *op) { bAnimContext ac; + ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - FCurve *fcu; - FModifier *fcm; + int filter; short type; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - - // xxx call the raw methods here instead? - ale= get_active_fcurve_channel(&ac); - if (ale == NULL) - return OPERATOR_CANCELLED; - fcu= (FCurve *)ale->data; - MEM_freeN(ale); - if (fcu == NULL) - return OPERATOR_CANCELLED; - /* get type of modifier to add */ type= RNA_enum_get(op->ptr, "type"); - /* add F-Modifier of specified type to active F-Curve, and make it the active one */ - fcm= add_fmodifier(&fcu->modifiers, type); - if (fcm) - set_active_fmodifier(&fcu->modifiers, fcm); - else { - BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details."); - return OPERATOR_CANCELLED; + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + if (RNA_boolean_get(op->ptr, "only_active")) + filter |= ANIMFILTER_ACTIVE; + else + filter |= ANIMFILTER_SEL; + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* smooth keyframes */ + for (ale= anim_data.first; ale; ale= ale->next) { + FCurve *fcu= (FCurve *)ale->data; + FModifier *fcm; + + /* add F-Modifier of specified type to active F-Curve, and make it the active one */ + fcm= add_fmodifier(&fcu->modifiers, type); + if (fcm) + set_active_fmodifier(&fcu->modifiers, fcm); + else { // TODO: stop when this happens? + BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details."); + break; + } } + BLI_freelistN(&anim_data); /* validate keyframes after editing */ ANIM_editkeyframes_refresh(&ac); @@ -1786,6 +1796,7 @@ void GRAPH_OT_fmodifier_add (wmOperatorType *ot) /* id-props */ RNA_def_enum(ot->srna, "type", fmodifier_type_items, 0, "Type", ""); + RNA_def_boolean(ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve."); } /* ************************************************************************** */ diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index b7d67c85ab9..b82055064f8 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -221,7 +221,7 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); /* F-Modifiers */ - WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "only_active", 0); /* transform system */ -- cgit v1.2.3 From 38ae41f94ea2045f71c9ba2a89778ea1e6ed93df Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 13:09:18 +0000 Subject: fix for buildinfo on mac's --- source/creator/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 0cc0d5d496b..a4c2bfa0008 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -24,6 +24,9 @@ # # ***** END GPL LICENSE BLOCK ***** +# So BUILDINFO and BLENDERPATH strings are automatically quoted +CMAKE_POLICY(SET CMP0005 NEW) + SETUP_LIBDIRS() INCLUDE_DIRECTORIES(../../intern/guardedalloc @@ -68,7 +71,6 @@ ENDIF(NOT WITH_SDL) IF(UNIX AND NOT APPLE) SET(BLENDERPATH ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION}) - CMAKE_POLICY(SET CMP0005 NEW) # blender_path in creator.c ADD_DEFINITIONS(-DBLENDERPATH="${BLENDERPATH}") ENDIF(UNIX AND NOT APPLE) -- cgit v1.2.3 From 69e47fcb0edfefea4c23befdd5c44886fa18557e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 14:26:00 +0000 Subject: WITH_CXX_GUARDEDALLOC was broken since BL_ArmatureObject become a PyObject --- source/gameengine/Converter/BL_ArmatureObject.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index 3e917e08001..8e3d5734b73 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -134,13 +134,6 @@ protected: float m_obmat[4][4]; double m_lastapplyframe; - - -#ifdef WITH_CXX_GUARDEDALLOC -public: - void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ArmatureObject"); } - void operator delete( void *mem ) { MEM_freeN(mem); } -#endif }; /* Pose function specific to the game engine */ -- cgit v1.2.3 From 9f6566c0a57ae136a819a461c43092a998c69f77 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 16:27:12 +0000 Subject: removed double library entries without realizing I had the BGE disabled, these are needed. --- source/creator/CMakeLists.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a4c2bfa0008..f260002feac 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -364,7 +364,7 @@ IF(UNIX) blender_ONL bf_python bf_gen_python - bf_ikplugin + bf_ikplugin bf_blenkernel bf_nodes bf_gpu @@ -379,12 +379,15 @@ IF(UNIX) bf_readblenfile blender_bop bf_kernel + bf_decimation bf_elbeem bf_IK bf_memutil bf_guardedalloc blender_CTR bf_moto + bf_windowmanager + bf_editors bf_blroutines bf_converter bf_dummy @@ -399,11 +402,18 @@ IF(UNIX) bf_oglrasterizer bf_expressions bf_scenegraph + bf_moto + bf_blroutines kx_network + bf_kernel bf_ngnetwork extern_bullet bf_loopbacknetwork - bf_ITASC + bf_ITASC + bf_common + bf_moto + bf_python + bf_gen_python extern_binreloc extern_glew extern_libopenjpeg -- cgit v1.2.3 From aa989c1e8343cb761665129d44e03a4fc4c7cd95 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2009 16:30:15 +0000 Subject: almost all event managers stored a pointer back to the logic manager, easier if this pointer is in the base class - SCA_EventManager --- source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp | 3 +-- source/gameengine/GameLogic/SCA_ActuatorEventManager.h | 2 -- source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp | 3 +-- source/gameengine/GameLogic/SCA_AlwaysEventManager.h | 2 -- source/gameengine/GameLogic/SCA_BasicEventManager.cpp | 3 +-- source/gameengine/GameLogic/SCA_EventManager.cpp | 5 +++-- source/gameengine/GameLogic/SCA_EventManager.h | 4 +++- source/gameengine/GameLogic/SCA_JoystickManager.cpp | 3 +-- source/gameengine/GameLogic/SCA_JoystickManager.h | 2 -- source/gameengine/GameLogic/SCA_KeyboardManager.cpp | 7 +++---- source/gameengine/GameLogic/SCA_KeyboardManager.h | 2 -- source/gameengine/GameLogic/SCA_MouseManager.cpp | 7 +++---- source/gameengine/GameLogic/SCA_MouseManager.h | 1 - source/gameengine/GameLogic/SCA_PropertyEventManager.cpp | 3 +-- source/gameengine/GameLogic/SCA_PropertyEventManager.h | 2 -- source/gameengine/GameLogic/SCA_RandomEventManager.cpp | 3 +-- source/gameengine/GameLogic/SCA_RandomEventManager.h | 2 -- source/gameengine/GameLogic/SCA_TimeEventManager.cpp | 2 +- source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp | 2 +- source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h | 1 - source/gameengine/Ketsji/KX_RayEventManager.h | 3 +-- source/gameengine/Ketsji/KX_TouchEventManager.cpp | 3 +-- source/gameengine/Ketsji/KX_TouchEventManager.h | 1 - 23 files changed, 22 insertions(+), 44 deletions(-) diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp index a80b2af55c8..e4dfe4e0bff 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp @@ -36,8 +36,7 @@ SCA_ActuatorEventManager::SCA_ActuatorEventManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(ACTUATOR_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, ACTUATOR_EVENTMGR) { } diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h index f3884c87a75..8c86d0dd422 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h +++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h @@ -37,8 +37,6 @@ using namespace std; class SCA_ActuatorEventManager : public SCA_EventManager { - class SCA_LogicManager* m_logicmgr; - public: SCA_ActuatorEventManager(class SCA_LogicManager* logicmgr); virtual ~SCA_ActuatorEventManager(); diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp index dd3b55abcc9..aee01606974 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp @@ -42,8 +42,7 @@ using namespace std; SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(ALWAYS_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, ALWAYS_EVENTMGR) { } diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h index 9540e3b71f6..f7fb3b9714e 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h +++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h @@ -34,8 +34,6 @@ using namespace std; class SCA_AlwaysEventManager : public SCA_EventManager { - - class SCA_LogicManager* m_logicmgr; public: SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr); virtual void NextFrame(); diff --git a/source/gameengine/GameLogic/SCA_BasicEventManager.cpp b/source/gameengine/GameLogic/SCA_BasicEventManager.cpp index 24cae439fb7..a2a7e535b5c 100644 --- a/source/gameengine/GameLogic/SCA_BasicEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_BasicEventManager.cpp @@ -42,8 +42,7 @@ using namespace std; SCA_BasicEventManager::SCA_BasicEventManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(BASIC_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, BASIC_EVENTMGR) { } diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp index d1301541a0a..5b6f3c46022 100644 --- a/source/gameengine/GameLogic/SCA_EventManager.cpp +++ b/source/gameengine/GameLogic/SCA_EventManager.cpp @@ -35,8 +35,9 @@ #endif -SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype) - :m_mgrtype(mgrtype) +SCA_EventManager::SCA_EventManager(SCA_LogicManager* logicmgr, EVENT_MANAGER_TYPE mgrtype) + :m_logicmgr(logicmgr), + m_mgrtype(mgrtype) { } diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h index f77b115ee03..debefcc45b0 100644 --- a/source/gameengine/GameLogic/SCA_EventManager.h +++ b/source/gameengine/GameLogic/SCA_EventManager.h @@ -38,6 +38,8 @@ class SCA_EventManager { protected: + class SCA_LogicManager* m_logicmgr; /* all event manager subclasses use this (other then TimeEventManager) */ + // use a set to speed-up insertion/removal //std::set m_sensors; SG_DList m_sensors; @@ -58,7 +60,7 @@ public: BASIC_EVENTMGR }; - SCA_EventManager(EVENT_MANAGER_TYPE mgrtype); + SCA_EventManager(SCA_LogicManager* logicmgr, EVENT_MANAGER_TYPE mgrtype); virtual ~SCA_EventManager(); virtual void RemoveSensor(class SCA_ISensor* sensor); diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp index ff8f3b1c81f..480292774da 100644 --- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp @@ -37,8 +37,7 @@ SCA_JoystickManager::SCA_JoystickManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(JOY_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, JOY_EVENTMGR) { int i; for (i=0; i it(m_sensors); for (it.begin();!it.end();++it) { - (*it)->Activate(m_logicmanager); + (*it)->Activate(m_logicmgr); } } diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h index c5553a74aef..8155283a274 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardManager.h +++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h @@ -45,8 +45,6 @@ using namespace std; class SCA_KeyboardManager : public SCA_EventManager { class SCA_IInputDevice* m_inputDevice; - class SCA_LogicManager* m_logicmanager; - public: SCA_KeyboardManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* inputdev); diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp index d407647cec3..c752701e785 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.cpp +++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp @@ -48,9 +48,8 @@ SCA_MouseManager::SCA_MouseManager(SCA_LogicManager* logicmgr, SCA_IInputDevice* mousedev) - : SCA_EventManager(MOUSE_EVENTMGR), - m_mousedevice (mousedev), - m_logicmanager(logicmgr) + : SCA_EventManager(logicmgr, MOUSE_EVENTMGR), + m_mousedevice (mousedev) { m_xpos = 0; m_ypos = 0; @@ -93,7 +92,7 @@ void SCA_MouseManager::NextFrame() mousesensor->setX(mx); mousesensor->setY(my); - mousesensor->Activate(m_logicmanager); + mousesensor->Activate(m_logicmgr); } } } diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h index ef1533c636b..00bbab66aa6 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.h +++ b/source/gameengine/GameLogic/SCA_MouseManager.h @@ -47,7 +47,6 @@ class SCA_MouseManager : public SCA_EventManager { class SCA_IInputDevice* m_mousedevice; - class SCA_LogicManager* m_logicmanager; unsigned short m_xpos; // Cached location of the mouse pointer unsigned short m_ypos; diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp index 764465309df..e01ce74e0a9 100644 --- a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp @@ -35,8 +35,7 @@ SCA_PropertyEventManager::SCA_PropertyEventManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(PROPERTY_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, PROPERTY_EVENTMGR) { } diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h index a9692377df8..5a036abb8b7 100644 --- a/source/gameengine/GameLogic/SCA_PropertyEventManager.h +++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h @@ -37,8 +37,6 @@ using namespace std; class SCA_PropertyEventManager : public SCA_EventManager { - class SCA_LogicManager* m_logicmgr; - public: SCA_PropertyEventManager(class SCA_LogicManager* logicmgr); virtual ~SCA_PropertyEventManager(); diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp index 976597aa812..780f8d10857 100644 --- a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp @@ -42,8 +42,7 @@ using namespace std; #endif SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(RANDOM_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, RANDOM_EVENTMGR) { } diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h index c8b511b87b7..81896709551 100644 --- a/source/gameengine/GameLogic/SCA_RandomEventManager.h +++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h @@ -39,8 +39,6 @@ using namespace std; class SCA_RandomEventManager : public SCA_EventManager { - class SCA_LogicManager* m_logicmgr; - public: SCA_RandomEventManager(class SCA_LogicManager* logicmgr); diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp index 911ea772bef..1b49906b8de 100644 --- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp @@ -43,7 +43,7 @@ #include "FloatValue.h" SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr) -: SCA_EventManager(TIME_EVENTMGR) +: SCA_EventManager(NULL, TIME_EVENTMGR) { } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp index 738f64713b0..65f7d98253c 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp @@ -45,7 +45,7 @@ KX_NetworkEventManager::KX_NetworkEventManager(class SCA_LogicManager* logicmgr, class NG_NetworkDeviceInterface *ndi) : -SCA_EventManager(NETWORK_EVENTMGR), m_logicmgr(logicmgr), m_ndi(ndi) +SCA_EventManager(logicmgr, NETWORK_EVENTMGR), m_ndi(ndi) { //printf("KX_NetworkEventManager constructor\n"); } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h index ae88f1d4987..fd776640bcf 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h @@ -34,7 +34,6 @@ class KX_NetworkEventManager : public SCA_EventManager { - class SCA_LogicManager* m_logicmgr; class NG_NetworkDeviceInterface* m_ndi; public: diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h index 27c9be14d1f..030dae525e1 100644 --- a/source/gameengine/Ketsji/KX_RayEventManager.h +++ b/source/gameengine/Ketsji/KX_RayEventManager.h @@ -41,8 +41,7 @@ class KX_RayEventManager : public SCA_EventManager class SCA_LogicManager* m_logicmgr; public: KX_RayEventManager(class SCA_LogicManager* logicmgr) - : SCA_EventManager(RAY_EVENTMGR), - m_logicmgr(logicmgr) + : SCA_EventManager(logicmgr, RAY_EVENTMGR) {} virtual void NextFrame(); diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 712a512995e..6b454f6a338 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -40,8 +40,7 @@ KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr, PHY_IPhysicsEnvironment* physEnv) - : SCA_EventManager(TOUCH_EVENTMGR), - m_logicmgr(logicmgr), + : SCA_EventManager(logicmgr, TOUCH_EVENTMGR), m_physEnv(physEnv) { //notm_scene->addTouchCallback(STATIC_RESPONSE, KX_TouchEventManager::collisionResponse, this); diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h index 6da37d615a4..e6414a2e285 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.h +++ b/source/gameengine/Ketsji/KX_TouchEventManager.h @@ -43,7 +43,6 @@ class PHY_IPhysicsEnvironment; class KX_TouchEventManager : public SCA_EventManager { typedef std::pair NewCollision; - class SCA_LogicManager* m_logicmgr; PHY_IPhysicsEnvironment* m_physEnv; std::set m_newCollisions; -- cgit v1.2.3 From 72c4c9da7a4074f86f4ed59d87a6e50a98b9bb06 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 25 Sep 2009 18:47:43 +0000 Subject: Fixing up Makefiles, its not fully working but its closer... Kent --- intern/itasc/Makefile | 9 +++++---- intern/itasc/kdl/Makefile | 10 +++++----- intern/itasc/kdl/utilities/Makefile | 2 ++ source/Makefile | 2 ++ source/blender/ikplugin/intern/Makefile | 6 ++++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/intern/itasc/Makefile b/intern/itasc/Makefile index 6ac0d142b72..2272cf2c6ac 100644 --- a/intern/itasc/Makefile +++ b/intern/itasc/Makefile @@ -28,10 +28,13 @@ # iksolver main makefile. # +include nan_definitions.mk LIBNAME = itasc -DIR = $(OCGDIR)/intern/$(SOURCEDIR) - +SOURCEDIR = intern/$(LIBNAME) +DIR = $(OCGDIR)/$(SOURCEDIR) +DIRS = kdl +include nan_subdirs.mk include nan_compile.mk CPPFLAGS += -I. @@ -48,6 +51,4 @@ ifeq ($(OS),darwin) ranlib $(NAN_ITASC)/lib/debug/libitasc.a endif ############################## -DIRS = kdl -SOURCEDIR = intern/$(LIBNAME) include nan_subdirs.mk diff --git a/intern/itasc/kdl/Makefile b/intern/itasc/kdl/Makefile index e34c991db38..9b152c27c7c 100644 --- a/intern/itasc/kdl/Makefile +++ b/intern/itasc/kdl/Makefile @@ -28,15 +28,15 @@ # iksolver main makefile. # +include nan_definitions.mk + LIBNAME = itasc DIR = $(OCGDIR)/intern/$(LIBNAME) +DIRS = utilities +SOURCEDIR = intern/$(LIBNAME)/kdl +include nan_subdirs.mk include nan_compile.mk CPPFLAGS += -I. CPPFLAGS += -I../../../extern/Eigen2 - -############################## -DIRS = utilities -SOURCEDIR = intern/$(LIBNAME)/kdl -include nan_subdirs.mk diff --git a/intern/itasc/kdl/utilities/Makefile b/intern/itasc/kdl/utilities/Makefile index 6dedc24181e..4397a80cef5 100644 --- a/intern/itasc/kdl/utilities/Makefile +++ b/intern/itasc/kdl/utilities/Makefile @@ -28,6 +28,8 @@ # iksolver main makefile. # +include nan_definitions.mk + LIBNAME = itasc DIR = $(OCGDIR)/intern/$(LIBNAME) diff --git a/source/Makefile b/source/Makefile index dab037d1749..b0c15c2eba1 100644 --- a/source/Makefile +++ b/source/Makefile @@ -98,7 +98,9 @@ COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a +COMLIB += $(OCGDIR)/blender/ikplugin/$(DEBUG_DIR)libikplugin.a COMLIB += $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a +COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a COMLIB += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a COMLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a COMLIB += $(OCGDIR)/blender/avi/$(DEBUG_DIR)libavi.a diff --git a/source/blender/ikplugin/intern/Makefile b/source/blender/ikplugin/intern/Makefile index 9254b65b7b7..0c54e5d1264 100644 --- a/source/blender/ikplugin/intern/Makefile +++ b/source/blender/ikplugin/intern/Makefile @@ -36,8 +36,8 @@ CFLAGS += -I../../makesdna CFLAGS += -I../../blenkernel CFLAGS += -I../../blenlib CFLAGS += -I../../include -CFLAGS += -I../../../intern/itasc -CFLAGS += -I../../../extern/Eigen2 +CFLAGS += -I../../../../intern/itasc +CFLAGS += -I../../../../extern/Eigen2 CFLAGS += -I.. CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include @@ -46,4 +46,6 @@ CPPFLAGS += -I../../makesdna CPPFLAGS += -I../../blenkernel CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../include +CPPFLAGS += -I../../../../intern/itasc +CPPFLAGS += -I../../../../extern/Eigen2 CPPFLAGS += -I.. -- cgit v1.2.3 From da5ff2ca98ae275f6e9addbad52621415fd30160 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Fri, 25 Sep 2009 22:38:15 +0000 Subject: Add directives to support multi dir lib. --- intern/itasc/Makefile | 13 ++++++------- intern/itasc/kdl/Makefile | 5 +++-- intern/itasc/kdl/utilities/Makefile | 5 +++-- source/Makefile | 2 ++ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/intern/itasc/Makefile b/intern/itasc/Makefile index 2272cf2c6ac..2be46a017df 100644 --- a/intern/itasc/Makefile +++ b/intern/itasc/Makefile @@ -40,15 +40,14 @@ include nan_compile.mk CPPFLAGS += -I. CPPFLAGS += -I../../extern/Eigen2 -install: all debug +install: $(ALL_OR_DEBUG) @[ -d $(NAN_ITASC) ] || mkdir $(NAN_ITASC) - @[ -d $(NAN_ITASC)/lib ] || mkdir $(NAN_ITASC)/lib - @[ -d $(NAN_ITASC)/lib/debug ] || mkdir $(NAN_ITASC)/lib/debug - @../tools/cpifdiff.sh $(DIR)/libitasc.a $(NAN_ITASC)/lib/ - @../tools/cpifdiff.sh $(DIR)/debug/libitasc.a $(NAN_ITASC)/lib/debug/ + @[ -d $(NAN_ITASC)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_ITASC)/lib/$(DEBUG_DIR) + @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libitasc.a $(DIR)/$(DEBUG_DIR)libitasc_kdl.a $(DIR)/$(DEBUG_DIR)libitasc_kdl_util.a $(NAN_ITASC)/lib/$(DEBUG_DIR) ifeq ($(OS),darwin) - ranlib $(NAN_ITASC)/lib/libitasc.a - ranlib $(NAN_ITASC)/lib/debug/libitasc.a + ranlib $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a + ranlib $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl.a + ranlib $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl_util.a endif ############################## include nan_subdirs.mk diff --git a/intern/itasc/kdl/Makefile b/intern/itasc/kdl/Makefile index 9b152c27c7c..058f93da4e1 100644 --- a/intern/itasc/kdl/Makefile +++ b/intern/itasc/kdl/Makefile @@ -30,8 +30,9 @@ include nan_definitions.mk -LIBNAME = itasc -DIR = $(OCGDIR)/intern/$(LIBNAME) +LIBNAME = itasc_kdl +# Yep, same dir than parent (itasc instead of $(LIBNAME)) +DIR = $(OCGDIR)/intern/itasc DIRS = utilities SOURCEDIR = intern/$(LIBNAME)/kdl diff --git a/intern/itasc/kdl/utilities/Makefile b/intern/itasc/kdl/utilities/Makefile index 4397a80cef5..8ee08089e10 100644 --- a/intern/itasc/kdl/utilities/Makefile +++ b/intern/itasc/kdl/utilities/Makefile @@ -30,8 +30,9 @@ include nan_definitions.mk -LIBNAME = itasc -DIR = $(OCGDIR)/intern/$(LIBNAME) +LIBNAME = itasc_kdl_util +# Same dir than parent (itasc instead of $(LIBNAME)) +DIR = $(OCGDIR)/intern/itasc include nan_compile.mk diff --git a/source/Makefile b/source/Makefile index b0c15c2eba1..5a071a10a9c 100644 --- a/source/Makefile +++ b/source/Makefile @@ -101,6 +101,8 @@ COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a COMLIB += $(OCGDIR)/blender/ikplugin/$(DEBUG_DIR)libikplugin.a COMLIB += $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a +COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl.a +COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc_kdl_util.a COMLIB += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a COMLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a COMLIB += $(OCGDIR)/blender/avi/$(DEBUG_DIR)libavi.a -- cgit v1.2.3 From 903d8231d905f528d746410ca868fa6dd1f0714b Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 26 Sep 2009 16:22:52 +0000 Subject: netrender: fix some bugs with job cancellation, remove credits system, add more status report on server, cleanup server error management --- release/io/netrender/balancing.py | 6 - release/io/netrender/master.py | 247 ++++++++++++++++++------------------ release/io/netrender/master_html.py | 8 +- release/io/netrender/model.py | 3 - release/io/netrender/operators.py | 4 +- release/io/netrender/slave.py | 6 +- 6 files changed, 129 insertions(+), 145 deletions(-) diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py index 372ea7d95b7..637dd5ff92e 100644 --- a/release/io/netrender/balancing.py +++ b/release/io/netrender/balancing.py @@ -61,12 +61,6 @@ class Balancer: # ========================== - -class RatingCredit(RatingRule): - def rate(self, job): - # more credit is better (sort at first in list) - return -job.credits * job.priority - class RatingUsage(RatingRule): def rate(self, job): # less usage is better diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py index 1202b94840f..a3e186a9cfd 100644 --- a/release/io/netrender/master.py +++ b/release/io/netrender/master.py @@ -35,9 +35,14 @@ class MRenderSlave(netrender.model.RenderSlave): def seen(self): self.last_seen = time.time() + + def finishedFrame(self, frame_number): + self.job_frames.remove(frame_number) + if not self.job_frames: + self.job = None class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, files, chunks = 1, priority = 1, credits = 100.0, blacklist = []): + def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []): super().__init__() self.id = job_id self.name = name @@ -46,7 +51,6 @@ class MRenderJob(netrender.model.RenderJob): self.chunks = chunks self.priority = priority self.usage = 0.0 - self.credits = credits self.blacklist = blacklist self.last_dispatched = time.time() @@ -79,14 +83,6 @@ class MRenderJob(netrender.model.RenderJob): def start(self): self.status = JOB_QUEUED - - def update(self): - if self.last_update == 0: - self.credits += (time.time() - self.last_dispatched) / 60 - else: - self.credits += (time.time() - self.last_update) / 60 - - self.last_update = time.time() def addLog(self, frames): log_name = "_".join(("%04d" % f for f in frames)) + ".log" @@ -110,7 +106,6 @@ class MRenderJob(netrender.model.RenderJob): frames = [] for f in self.frames: if f.status == QUEUED: - self.credits -= 1 # cost of one frame self.last_dispatched = time.time() frames.append(f) if len(frames) >= self.chunks: @@ -150,30 +145,24 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.end_headers() def do_HEAD(self): - print(self.path) if self.path == "/status": job_id = self.headers.get('job-id', "") job_frame = int(self.headers.get('job-frame', -1)) - if job_id: - print("status:", job_id, "\n") + job = self.server.getJobID(job_id) + if job: + frame = job[job_frame] - job = self.server.getJobByID(job_id) - if job: - if job_frame != -1: - frame = job[frame] - - if not frame: - # no such frame - self.send_heat(http.client.NO_CONTENT) - return + + if frame: + self.send_head(http.client.OK) else: - # no such job id + # no such frame self.send_head(http.client.NO_CONTENT) - return - - self.send_head() + else: + # no such job id + self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -182,19 +171,17 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- def do_GET(self): - print(self.path) if self.path == "/version": self.send_head() - self.server.stats("", "New client connection") + self.server.stats("", "Version check") self.wfile.write(VERSION) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/render": job_id = self.headers['job-id'] job_frame = int(self.headers['job-frame']) - print("render:", job_id, job_frame) - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: frame = job[job_frame] @@ -203,7 +190,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if frame.status in (QUEUED, DISPATCHED): self.send_head(http.client.ACCEPTED) elif frame.status == DONE: - self.server.stats("", "Sending result back to client") + self.server.stats("", "Sending result to client") f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb') self.send_head() @@ -223,9 +210,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): elif self.path == "/log": job_id = self.headers['job-id'] job_frame = int(self.headers['job-frame']) - print("log:", job_id, job_frame) - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: frame = job[job_frame] @@ -234,7 +220,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if not frame.log_path or frame.status in (QUEUED, DISPATCHED): self.send_head(http.client.PROCESSING) else: - self.server.stats("", "Sending log back to client") + self.server.stats("", "Sending log to client") f = open(frame.log_path, 'rb') self.send_head() @@ -254,9 +240,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_frame = int(self.headers.get('job-frame', -1)) if job_id: - print("status:", job_id, "\n") - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: if job_frame != -1: frame = job[frame] @@ -279,21 +264,21 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): for job in self.server: message.append(job.serialize()) + + self.server.stats("", "Sending status") self.send_head() self.wfile.write(bytes(repr(message), encoding='utf8')) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/job": - self.server.update() + self.server.balance() slave_id = self.headers['slave-id'] - print("slave-id", slave_id) - - slave = self.server.updateSlave(slave_id) + slave = self.server.getSeenSlave(slave_id) if slave: # only if slave id is valid - job, frames = self.server.getNewJob(slave_id) + job, frames = self.server.newDispatch(slave_id) if job and frames: for f in frames: @@ -310,9 +295,12 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.wfile.write(bytes(repr(message), encoding='utf8')) - self.server.stats("", "Sending job frame to render node") + self.server.stats("", "Sending job to slave") else: # no job available, return error code + slave.job = None + slave.job_frames = [] + self.send_head(http.client.ACCEPTED) else: # invalid slave id self.send_head(http.client.NO_CONTENT) @@ -320,21 +308,19 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): elif self.path == "/file": slave_id = self.headers['slave-id'] - slave = self.server.updateSlave(slave_id) + slave = self.server.getSeenSlave(slave_id) if slave: # only if slave id is valid job_id = self.headers['job-id'] job_file = self.headers['job-file'] - print("job:", job_id, "\n") - print("file:", job_file, "\n") - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: render_file = job.files_map.get(job_file, None) if render_file: - self.server.stats("", "Sending file to render node") + self.server.stats("", "Sending file to slave") f = open(render_file.filepath, 'rb') self.send_head() @@ -350,9 +336,11 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/slave": + elif self.path == "/slaves": message = [] + self.server.stats("", "Sending slaves status") + for slave in self.server.slaves: message.append(slave.serialize()) @@ -370,12 +358,9 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- def do_POST(self): - print(self.path) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- if self.path == "/job": - print("posting job info") - self.server.stats("", "Receiving job") length = int(self.headers['content-length']) @@ -383,8 +368,6 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_id = self.server.nextJobID() - print(job_info.files) - job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) for frame in job_info.frames: @@ -395,17 +378,30 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): headers={"job-id": job_id} if job.testStart(): + self.server.stats("", "New job, missing files") self.send_head(headers=headers) else: + self.server.stats("", "New job, started") self.send_head(http.client.ACCEPTED, headers=headers) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/cancel": job_id = self.headers.get('job-id', "") - if job_id: - print("cancel:", job_id, "\n") - self.server.removeJob(job_id) - else: # cancel all jobs - self.server.clear() + + job = self.server.getJobID(job_id) + + if job: + self.server.stats("", "Cancelling job") + self.server.removeJob(job) + self.send_head() + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/clear": + # cancel all jobs + self.server.stats("", "Clearing jobs") + self.server.clear() self.send_head() # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -414,15 +410,25 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_frame = int(self.headers.get('job-frame', "-1")) all = bool(self.headers.get('reset-all', "False")) - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: if job_frame != -1: - job[job_frame].reset(all) + + frame = job[job_frame] + if frame: + self.server.stats("", "Reset job frame") + frame.reset(all) + self.send_head() + else: + # no such frame + self.send_head(http.client.NO_CONTENT) + else: + self.server.stats("", "Reset job") job.reset(all) + self.send_head() - self.send_head() else: # job not found self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -430,6 +436,8 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): length = int(self.headers['content-length']) job_frame_string = self.headers['job-frame'] + self.server.stats("", "New slave connected") + slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) @@ -439,16 +447,17 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): elif self.path == "/log": slave_id = self.headers['slave-id'] - slave = self.server.updateSlave(slave_id) + slave = self.server.getSeenSlave(slave_id) if slave: # only if slave id is valid length = int(self.headers['content-length']) log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - job = self.server.getJobByID(log_info.job_id) + job = self.server.getJobID(log_info.job_id) if job: + self.server.stats("", "Log announcement") job.addLog(log_info.frames) self.send_head(http.client.OK) else: @@ -462,18 +471,16 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- def do_PUT(self): - print(self.path) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- if self.path == "/file": - print("writing blend file") self.server.stats("", "Receiving job") length = int(self.headers['content-length']) job_id = self.headers['job-id'] job_file = self.headers['job-file'] - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: @@ -501,8 +508,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): render_file.filepath = file_path # set the new path if job.testStart(): + self.server.stats("", "File upload, starting job") self.send_head(http.client.OK) else: + self.server.stats("", "File upload, file missings") self.send_head(http.client.ACCEPTED) else: # invalid file self.send_head(http.client.NO_CONTENT) @@ -510,17 +519,16 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/render": - print("writing result file") self.server.stats("", "Receiving render result") slave_id = self.headers['slave-id'] - slave = self.server.updateSlave(slave_id) + slave = self.server.getSeenSlave(slave_id) if slave: # only if slave id is valid job_id = self.headers['job-id'] - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: job_frame = int(self.headers['job-frame']) @@ -528,43 +536,43 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_time = float(self.headers['job-time']) frame = job[job_frame] - - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() - - del buf - elif job_result == ERROR: - # blacklist slave on this job on error - job.blacklist.append(slave.id) - - slave.job_frames.remove(job_frame) - if not slave.job_frames: - slave.job = None - frame.status = job_result - frame.time = job_time - - job.testFinished() - - self.server.updateSlave(self.headers['slave-id']) - - self.send_head() + if frame: + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() + + del buf + elif job_result == ERROR: + # blacklist slave on this job on error + job.blacklist.append(slave.id) + + self.server.stats("", "Receiving result") + + slave.finishedFrame(job_frame) + + frame.status = job_result + frame.time = job_time + + job.testFinished() + + self.send_head() + else: # frame not found + self.send_head(http.client.NO_CONTENT) else: # job not found self.send_head(http.client.NO_CONTENT) else: # invalid slave id self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path == "/log": - print("writing log file") self.server.stats("", "Receiving log file") job_id = self.headers['job-id'] - job = self.server.getJobByID(job_id) + job = self.server.getJobID(job_id) if job: job_frame = int(self.headers['job-frame']) @@ -580,7 +588,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): del buf - self.server.updateSlave(self.headers['slave-id']) + self.server.getSeenSlave(self.headers['slave-id']) self.send_head() else: # frame not found @@ -600,10 +608,7 @@ class RenderMasterServer(http.server.HTTPServer): self.slave_timeout = 2 - self.first_usage = True - self.balancer = netrender.balancing.Balancer() - #self.balancer.addRule(netrender.balancing.RatingCredit()) self.balancer.addRule(netrender.balancing.RatingUsage()) self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9)) @@ -631,7 +636,7 @@ class RenderMasterServer(http.server.HTTPServer): def getSlave(self, slave_id): return self.slaves_map.get(slave_id, None) - def updateSlave(self, slave_id): + def getSeenSlave(self, slave_id): slave = self.getSlave(slave_id) if slave: slave.seen() @@ -655,18 +660,12 @@ class RenderMasterServer(http.server.HTTPServer): self.removeSlave(slave) def updateUsage(self): - m = 1.0 - - if not self.first_usage: - for job in self.jobs: - job.usage *= 0.5 - - m = 0.5 - else: - self.first_usage = False + blend = 0.5 + for job in self.jobs: + job.usage *= (1 - blend) if self.slaves: - slave_usage = m / self.countSlaves() + slave_usage = blend / self.countSlaves() for slave in self.slaves: if slave.job: @@ -679,9 +678,7 @@ class RenderMasterServer(http.server.HTTPServer): for job in removed: self.removeJob(job) - def update(self): - for job in self.jobs: - job.update() + def balance(self): self.balancer.balance(self.jobs) def countJobs(self, status = JOB_QUEUED): @@ -695,16 +692,14 @@ class RenderMasterServer(http.server.HTTPServer): def countSlaves(self): return len(self.slaves) - def removeJob(self, id): - job = self.jobs_map.pop(id) - - if job: - self.jobs.remove(job) - - for slave in self.slaves: - if slave.job == job: - slave.job = None - slave.job_frames = [] + def removeJob(self, job): + self.jobs.remove(job) + self.jobs_map.pop(job.id) + + for slave in self.slaves: + if slave.job == job: + slave.job = None + slave.job_frames = [] def addJob(self, job): self.jobs.append(job) @@ -717,14 +712,14 @@ class RenderMasterServer(http.server.HTTPServer): job.save() - def getJobByID(self, id): + def getJobID(self, id): return self.jobs_map.get(id, None) def __iter__(self): for job in self.jobs: yield job - def getNewJob(self, slave_id): + def newDispatch(self, slave_id): if self.jobs: for job in self.jobs: if not self.balancer.applyExceptions(job) and slave_id not in job.blacklist: diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py index 7513971e6cf..6a956a70e9f 100644 --- a/release/io/netrender/master_html.py +++ b/release/io/netrender/master_html.py @@ -55,7 +55,6 @@ def get(handler): headerTable( "name", "priority", - "credits", "usage", "wait", "length", @@ -66,14 +65,13 @@ def get(handler): "exception" ) - handler.server.update() + handler.server.balance() for job in handler.server.jobs: results = job.framesStatus() rowTable( link(job.name, "/html/job" + job.id), job.priority, - round(job.credits, 1), "%0.1f%%" % (job.usage * 100), "%is" % int(time.time() - job.last_dispatched), len(job), @@ -92,7 +90,7 @@ def get(handler): output("NetRender") - job = handler.server.getJobByID(job_id) + job = handler.server.getJobID(job_id) if job: output("

Frames

") @@ -119,7 +117,7 @@ def get(handler): job_id = match.groups()[0] frame_number = int(match.groups()[1]) - job = handler.server.getJobByID(job_id) + job = handler.server.getJobID(job_id) if job: frame = job[frame_number] diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py index 91a7c8a035f..be97f8d0a81 100644 --- a/release/io/netrender/model.py +++ b/release/io/netrender/model.py @@ -80,7 +80,6 @@ class RenderJob: self.frames = [] self.chunks = 0 self.priority = 0 - self.credits = 0 self.usage = 0.0 self.blacklist = [] self.last_dispatched = 0.0 @@ -145,7 +144,6 @@ class RenderJob: "chunks": self.chunks, "priority": self.priority, "usage": self.usage, - "credits": self.credits, "blacklist": self.blacklist, "last_dispatched": self.last_dispatched } @@ -163,7 +161,6 @@ class RenderJob: job.chunks = data["chunks"] job.priority = data["priority"] job.usage = data["usage"] - job.credits = data["credits"] job.blacklist = data["blacklist"] job.last_dispatched = data["last_dispatched"] diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 498edd74529..4278231ab35 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -205,7 +205,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): conn = clientConnection(context.scene) if conn: - conn.request("GET", "/slave") + conn.request("GET", "/slaves") response = conn.getresponse() print( response.status, response.reason ) @@ -289,7 +289,7 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator): conn = clientConnection(context.scene) if conn: - conn.request("POST", "/cancel") + conn.request("POST", "/clear") response = conn.getresponse() print( response.status, response.reason ) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py index 406b987c990..657e31001e0 100644 --- a/release/io/netrender/slave.py +++ b/release/io/netrender/slave.py @@ -32,8 +32,8 @@ def slave_Info(): slave.stats = sysname + " " + release + " " + machine + " " + processor return slave -def testCancel(conn, job_id): - conn.request("HEAD", "/status", headers={"job-id":job_id}) +def testCancel(conn, job_id, frame_number): + conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)}) response = conn.getresponse() # cancelled if job isn't found anymore @@ -152,7 +152,7 @@ def render_slave(engine, scene): stdout = bytes() run_t = current_t - if testCancel(conn, job.id): + if testCancel(conn, job.id, first_frame): cancelled = True if cancelled: -- cgit v1.2.3 From 128dba3329076980d9a7c1cfa326cc3b17f05152 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sat, 26 Sep 2009 16:43:20 +0000 Subject: Assorted tiny UI tweaks --- release/ui/buttons_data_camera.py | 8 +- source/blender/editors/screen/screen_ops.c | 6 +- source/blender/editors/space_node/drawnode.c | 98 +++++++++++------------ source/blender/editors/space_view3d/view3d_edit.c | 4 +- source/blender/makesrna/intern/rna_image.c | 2 +- 5 files changed, 60 insertions(+), 58 deletions(-) diff --git a/release/ui/buttons_data_camera.py b/release/ui/buttons_data_camera.py index aa107d8dbdd..0ac9a88eb35 100644 --- a/release/ui/buttons_data_camera.py +++ b/release/ui/buttons_data_camera.py @@ -38,13 +38,13 @@ class DATA_PT_camera(DataButtonsPanel): layout.itemR(cam, "type", expand=True) - row = layout.row(align=True) + row = layout.row() if cam.type == 'PERSP': - row.itemR(cam, "lens_unit", text="") if cam.lens_unit == 'MILLIMETERS': row.itemR(cam, "lens", text="Angle") elif cam.lens_unit == 'DEGREES': row.itemR(cam, "angle") + row.itemR(cam, "lens_unit", text="") elif cam.type == 'ORTHO': row.itemR(cam, "ortho_scale") @@ -86,11 +86,13 @@ class DATA_PT_camera_display(DataButtonsPanel): col.itemR(cam, "show_name", text="Name") col = split.column() + col.itemR(cam, "draw_size", text="Size") + col.itemS() col.itemR(cam, "show_passepartout", text="Passepartout") sub = col.column() sub.active = cam.show_passepartout sub.itemR(cam, "passepartout_alpha", text="Alpha", slider=True) - col.itemR(cam, "draw_size", text="Size") + bpy.types.register(DATA_PT_context_camera) bpy.types.register(DATA_PT_camera) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5f7be1fd2bc..ae3f74403f2 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1574,7 +1574,7 @@ static int screen_full_area_exec(bContext *C, wmOperator *op) static void SCREEN_OT_screen_full_area(wmOperatorType *ot) { - ot->name = "Toggle Make Area Fullscreen"; + ot->name = "Toggle Full Screen"; ot->idname = "SCREEN_OT_screen_full_area"; ot->exec= screen_full_area_exec; @@ -2097,7 +2097,7 @@ static int region_foursplit_exec(bContext *C, wmOperator *op) static void SCREEN_OT_region_foursplit(wmOperatorType *ot) { /* identifiers */ - ot->name= "Split Region in 4 Parts"; + ot->name= "Toggle Quad View"; ot->idname= "SCREEN_OT_region_foursplit"; /* api callbacks */ @@ -2347,7 +2347,7 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) static void SCREEN_OT_animation_play(wmOperatorType *ot) { /* identifiers */ - ot->name= "Animation player"; + ot->name= "Play Animation"; ot->idname= "SCREEN_OT_animation_play"; /* api callbacks */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index f42bf97bf1a..0de19b22f3f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1119,15 +1119,15 @@ static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) } uiItemR(col, NULL, 0, ptr, "relative", 0); - row= uiLayoutRow(col, 1); + col= uiLayoutColumn(layout, 1); if (RNA_boolean_get(ptr, "relative")== 1) { - uiItemR(row, "X", 0, ptr, "factor_x", 0); - uiItemR(row, "Y", 0, ptr, "factor_y", 0); + uiItemR(col, "X", 0, ptr, "factor_x", 0); + uiItemR(col, "Y", 0, ptr, "factor_y", 0); } else { - uiItemR(row, "X", 0, ptr, "sizex", 0); - uiItemR(row, "Y", 0, ptr, "sizey", 0); + uiItemR(col, "X", 0, ptr, "sizex", 0); + uiItemR(col, "Y", 0, ptr, "sizey", 0); } } @@ -1140,10 +1140,8 @@ static void node_composit_buts_dblur(uiLayout *layout, PointerRNA *ptr) col= uiLayoutColumn(layout, 1); uiItemL(col, "Center:", 0); - - row= uiLayoutRow(col, 1); - uiItemR(row, "X:", 0, ptr, "center_x", 0); - uiItemR(row, "Y", 0, ptr, "center_y", 0); + uiItemR(col, "X", 0, ptr, "center_x", 0); + uiItemR(col, "Y", 0, ptr, "center_y", 0); uiItemS(layout); @@ -1172,7 +1170,7 @@ static void node_composit_buts_defocus(uiLayout *layout, PointerRNA *ptr) { uiLayout *sub, *col; - col= uiLayoutColumn(layout, 1); + col= uiLayoutColumn(layout, 0); uiItemL(col, "Bokeh Type:", 0); uiItemR(col, "", 0, ptr, "bokeh", 0); uiItemR(col, NULL, 0, ptr, "angle", 0); @@ -1211,7 +1209,7 @@ static void node_composit_buts_glare(uiLayout *layout, PointerRNA *ptr) uiItemR(layout, NULL, 0, ptr, "iterations", 0); if (RNA_enum_get(ptr, "glare_type")!= 0) - uiItemR(layout, NULL, 0, ptr, "color_modulation", 0); + uiItemR(layout, NULL, 0, ptr, "color_modulation", UI_ITEM_R_SLIDER); } uiItemR(layout, NULL, 0, ptr, "mix", 0); @@ -1222,7 +1220,7 @@ static void node_composit_buts_glare(uiLayout *layout, PointerRNA *ptr) uiItemR(layout, NULL, 0, ptr, "angle_offset", 0); } if (RNA_enum_get(ptr, "glare_type")== 0 || RNA_enum_get(ptr, "glare_type")== 2) { - uiItemR(layout, NULL, 0, ptr, "fade", 0); + uiItemR(layout, NULL, 0, ptr, "fade", UI_ITEM_R_SLIDER); if (RNA_enum_get(ptr, "glare_type")== 0) uiItemR(layout, NULL, 0, ptr, "rotate_45", 0); @@ -1237,18 +1235,18 @@ static void node_composit_buts_tonemap(uiLayout *layout, PointerRNA *ptr) { uiLayout *col; - col = uiLayoutColumn(layout, 1); + col = uiLayoutColumn(layout, 0); uiItemR(col, "", 0, ptr, "tonemap_type", 0); if (RNA_enum_get(ptr, "tonemap_type")== 0) { - uiItemR(col, NULL, 0, ptr, "key", 0); + uiItemR(col, NULL, 0, ptr, "key", UI_ITEM_R_SLIDER); uiItemR(col, NULL, 0, ptr, "offset", 0); uiItemR(col, NULL, 0, ptr, "gamma", 0); } else { uiItemR(col, NULL, 0, ptr, "intensity", 0); - uiItemR(col, NULL, 0, ptr, "contrast", 0); - uiItemR(col, NULL, 0, ptr, "adaptation", 0); - uiItemR(col, NULL, 0, ptr, "correction", 0); + uiItemR(col, NULL, 0, ptr, "contrast", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "adaptation", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "correction", UI_ITEM_R_SLIDER); } } @@ -1270,7 +1268,7 @@ static void node_composit_buts_vecblur(uiLayout *layout, PointerRNA *ptr) { uiLayout *col; - col= uiLayoutColumn(layout, 1); + col= uiLayoutColumn(layout, 0); uiItemR(col, NULL, 0, ptr, "samples", 0); uiItemR(col, "Blur", 0, ptr, "factor", 0); @@ -1309,7 +1307,7 @@ static void node_composit_buts_splitviewer(uiLayout *layout, PointerRNA *ptr) { uiLayout *row, *col; - col= uiLayoutColumn(layout, 1); + col= uiLayoutColumn(layout, 0); row= uiLayoutRow(col, 0); uiItemR(row, NULL, 0, ptr, "axis", UI_ITEM_R_EXPAND); uiItemR(col, NULL, 0, ptr, "factor", 0); @@ -1351,7 +1349,7 @@ static void node_composit_buts_hue_sat(uiLayout *layout, PointerRNA *ptr) { uiLayout *col; - col =uiLayoutColumn(layout, 1); + col =uiLayoutColumn(layout, 0); uiItemR(col, NULL, 0, ptr, "hue", UI_ITEM_R_SLIDER); uiItemR(col, NULL, 0, ptr, "sat", UI_ITEM_R_SLIDER); uiItemR(col, NULL, 0, ptr, "val", UI_ITEM_R_SLIDER); @@ -1384,7 +1382,7 @@ static void node_composit_buts_color_spill(uiLayout *layout, PointerRNA *ptr) { uiLayout *row, *col; - col =uiLayoutColumn(layout, 1); + col =uiLayoutColumn(layout, 0); uiItemR(col, NULL, 0, ptr, "factor", 0); row= uiLayoutRow(col, 0); uiItemR(row, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND); @@ -1392,35 +1390,37 @@ static void node_composit_buts_color_spill(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_chroma_matte(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); - bNode *node= ptr->data; - rctf *butr= &node->butr; - short dx=(butr->xmax-butr->xmin)/2; - NodeChroma *c= node->storage; - - uiBlockBeginAlign(block); - - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ", - butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20, - &c->t1, 1.0f, 80.0f, 100, 0, "Tolerance for colors to be considered a keying color"); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Cutoff ", - butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, - &c->t2, 0.0f, 30.0f, 100, 0, "Colors below this will be considered as exact matches for keying color"); - - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Lift ", - butr->xmin, butr->ymin+20, dx, 20, - &c->fsize, 0.0f, 1.0f, 100, 0, "Alpha Lift"); - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Gain ", - butr->xmin+dx, butr->ymin+20, dx, 20, - &c->fstrength, 0.0f, 1.0f, 100, 0, "Alpha Gain"); - - uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured"); - uiBlockEndAlign(block); - if(c->t2 > c->t1) - c->t2=c->t1; + uiLayout *col; + + col= uiLayoutColumn(layout, 0); + uiItemR(col, NULL, 0, ptr, "acceptance", 0); + uiItemR(col, NULL, 0, ptr, "cutoff", 0); + + col= uiLayoutColumn(layout, 1); + uiItemR(col, NULL, 0, ptr, "lift", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "gain", UI_ITEM_R_SLIDER); + uiItemR(col, NULL, 0, ptr, "shadow_adjust", UI_ITEM_R_SLIDER); + +// uiBlock *block= uiLayoutFreeBlock(layout); +// bNode *node= ptr->data; +// rctf *butr= &node->butr; +// short dx=(butr->xmax-butr->xmin)/2; +// NodeChroma *c= node->storage; + +// uiBlockBeginAlign(block); +// +// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Acceptance ", butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20, &c->t1, 1.0f, 80.0f, 100, 0, "Tolerance for colors to be considered a keying color"); +// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Cutoff ", butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, &c->t2, 0.0f, 30.0f, 100, 0, "Colors below this will be considered as exact matches for keying color"); +// +// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Lift ", butr->xmin, butr->ymin+20, dx, 20, &c->fsize, 0.0f, 1.0f, 100, 0, "Alpha Lift"); +// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Gain ", butr->xmin+dx, butr->ymin+20, dx, 20, &c->fstrength, 0.0f, 1.0f, 100, 0, "Alpha Gain"); +// +// uiDefButF(block, NUMSLI, B_NODE_EXEC, "Shadow Adjust ", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &c->t3, 0.0f, 1.0f, 100, 0, "Adjusts the brightness of any shadows captured"); +// uiBlockEndAlign(block); +// +// if(c->t2 > c->t1) +// c->t2=c->t1; } static void node_composit_buts_color_matte(uiLayout *layout, PointerRNA *ptr) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 640252287fe..c07d9108993 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1056,7 +1056,7 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. void VIEW3D_OT_view_all(wmOperatorType *ot) { /* identifiers */ - ot->name= "View home"; + ot->name= "View All"; ot->description = "View all objects in scene."; ot->idname= "VIEW3D_OT_view_all"; @@ -1195,7 +1195,7 @@ void VIEW3D_OT_view_center(wmOperatorType *ot) { /* identifiers */ - ot->name= "View center"; + ot->name= "View Selected"; ot->description = "Move the view to the selection center."; ot->idname= "VIEW3D_OT_view_center"; diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index db7a8afb4a4..4c2689d4f64 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -242,7 +242,7 @@ static void rna_def_image(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static const EnumPropertyItem prop_field_order_items[]= { {0, "EVEN", 0, "Even", "Even Fields first"}, - {IMA_STD_FIELD, "Odd", 0, "Odd", "Odd Fields first"}, + {IMA_STD_FIELD, "ODD", 0, "Odd", "Odd Fields first"}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Image", "ID"); -- cgit v1.2.3 From 7af92d6eff8d690789503349991db475dde16972 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 26 Sep 2009 19:50:59 +0000 Subject: netrender: split off job settings in their own panel. Add button to open up web interface in a browser. --- release/io/netrender/operators.py | 44 +++++++++++++++++++++++++++++++++------ release/io/netrender/ui.py | 34 +++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py index 4278231ab35..42d1f6a0b86 100644 --- a/release/io/netrender/operators.py +++ b/release/io/netrender/operators.py @@ -1,6 +1,7 @@ import bpy import sys, os import http, http.client, http.server, urllib, socket +import webbrowser from netrender.utils import * import netrender.client as client @@ -369,13 +370,13 @@ class netclientscan(bpy.types.Operator): def execute(self, context): netsettings = context.scene.network_render - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - s.settimeout(30) - - s.bind(('', 8000)) - try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + s.settimeout(30) + + s.bind(('', 8000)) + buf, address = s.recvfrom(64) print("received:", buf) @@ -389,3 +390,34 @@ class netclientscan(bpy.types.Operator): def invoke(self, context, event): return self.execute(context) + +@rnaOperator +class netclientweb(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientweb" + __label__ = "Net Render Client Web" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + + + # open connection to make sure server exists + conn = clientConnection(context.scene) + + if conn: + conn.close() + + webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index 7ee0b64d150..ddaf0e6854a 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -48,9 +48,6 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col = split.column() - if scene.network_render.mode == "RENDER_CLIENT": - col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") - col.itemR(scene.network_render, "mode") col.itemR(scene.network_render, "path") col.itemR(scene.network_render, "server_address") @@ -60,12 +57,33 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col.itemR(scene.network_render, "server_broadcast") else: col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="") + +@rnaType +class SCENE_PT_network_job(RenderButtonsPanel): + __label__ = "Job Settings" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + scene = context.scene + rd = scene.render_data + + layout.active = True + + split = layout.split() + + col = split.column() - if scene.network_render.mode == "RENDER_CLIENT": - col.itemO("render.netclientsend", text="send job to server") - col.itemR(scene.network_render, "job_name") - col.itemR(scene.network_render, "priority") - col.itemR(scene.network_render, "chunks") + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") + col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job") + col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor") + col.itemR(scene.network_render, "job_name") + col.itemR(scene.network_render, "priority") + col.itemR(scene.network_render, "chunks") @rnaType class SCENE_PT_network_slaves(RenderButtonsPanel): -- cgit v1.2.3 From 69995bb1b32a081dab987926e0c9f3b94cd63209 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sat, 26 Sep 2009 20:03:01 +0000 Subject: Sound: * Threading buxfix letting MSVC Debug builds crash because of corrupted std::lists * Adopted two property ranges * Changed the mixdown volume to set the device volume instead of the volume of every sound. I also removed the private redefinition of m_logicmgr in SCA_BasicEventManager, which was already defined protected in the parent class SCA_EventManager and thus caused a bug letting GE crash here because of an uninitialized pointer. --- intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 389 ++++++++++++--------- intern/audaspace/intern/AUD_C-API.cpp | 11 + intern/audaspace/intern/AUD_C-API.h | 8 + intern/audaspace/intern/AUD_SoftwareDevice.cpp | 194 ++++++---- source/blender/blenkernel/intern/sound.c | 6 +- source/blender/makesrna/intern/rna_scene.c | 4 +- .../gameengine/GameLogic/SCA_BasicEventManager.h | 2 - 7 files changed, 362 insertions(+), 252 deletions(-) diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index b33afa2b955..aa9f425d6fb 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -127,101 +127,103 @@ void AUD_OpenALDevice::updateStreams() alcSuspendContext(m_context); - // for all sounds - AUD_HandleIterator it = m_playingSounds->begin(); - while(it != m_playingSounds->end()) { - sound = *it; - // increment the iterator to make sure it's valid, - // in case the sound gets deleted after stopping - ++it; - - // is it a streamed sound? - if(!sound->isBuffered) + // for all sounds + AUD_HandleIterator it = m_playingSounds->begin(); + while(it != m_playingSounds->end()) { - // check for buffer refilling - alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info); + sound = *it; + // increment the iterator to make sure it's valid, + // in case the sound gets deleted after stopping + ++it; - if(info) + // is it a streamed sound? + if(!sound->isBuffered) { - specs = sound->reader->getSpecs(); + // check for buffer refilling + alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info); - // for all empty buffers - while(info--) + if(info) { - // if there's still data to play back - if(!sound->data_end) - { - // read data - length = m_buffersize; - sound->reader->read(length, buffer); - - // read nothing? - if(length == 0) - { - sound->data_end = true; - break; - } - - // unqueue buffer - alSourceUnqueueBuffers(sound->source, 1, - &sound->buffers[sound->current]); - ALenum err; - if((err = alGetError()) != AL_NO_ERROR) - { - sound->data_end = true; - break; - } - - // fill with new data - alBufferData(sound->buffers[sound->current], - sound->format, - buffer, - length * AUD_SAMPLE_SIZE(specs), - specs.rate); + specs = sound->reader->getSpecs(); - if(alGetError() != AL_NO_ERROR) + // for all empty buffers + while(info--) + { + // if there's still data to play back + if(!sound->data_end) { - sound->data_end = true; - break; + // read data + length = m_buffersize; + sound->reader->read(length, buffer); + + // read nothing? + if(length == 0) + { + sound->data_end = true; + break; + } + + // unqueue buffer + alSourceUnqueueBuffers(sound->source, 1, + &sound->buffers[sound->current]); + ALenum err; + if((err = alGetError()) != AL_NO_ERROR) + { + sound->data_end = true; + break; + } + + // fill with new data + alBufferData(sound->buffers[sound->current], + sound->format, + buffer, + length * AUD_SAMPLE_SIZE(specs), + specs.rate); + + if(alGetError() != AL_NO_ERROR) + { + sound->data_end = true; + break; + } + + // and queue again + alSourceQueueBuffers(sound->source, 1, + &sound->buffers[sound->current]); + if(alGetError() != AL_NO_ERROR) + { + sound->data_end = true; + break; + } + + sound->current = (sound->current+1) % + AUD_OPENAL_CYCLE_BUFFERS; } - - // and queue again - alSourceQueueBuffers(sound->source, 1, - &sound->buffers[sound->current]); - if(alGetError() != AL_NO_ERROR) - { - sound->data_end = true; + else break; - } - - sound->current = (sound->current+1) % - AUD_OPENAL_CYCLE_BUFFERS; } - else - break; } } - } - // check if the sound has been stopped - alGetSourcei(sound->source, AL_SOURCE_STATE, &info); + // check if the sound has been stopped + alGetSourcei(sound->source, AL_SOURCE_STATE, &info); - if(info != AL_PLAYING) - { - // if it really stopped - if(sound->data_end) + if(info != AL_PLAYING) { - // pause or - if(sound->keep) - pause(sound); - // stop + // if it really stopped + if(sound->data_end) + { + // pause or + if(sound->keep) + pause(sound); + // stop + else + stop(sound); + } + // continue playing else - stop(sound); + alSourcePlay(sound->source); } - // continue playing - else - alSourcePlay(sound->source); } } @@ -516,60 +518,73 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs) AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) { - // check if it is a buffered factory - for(AUD_BFIterator i = m_bufferedFactories->begin(); - i != m_bufferedFactories->end(); i++) - { - if((*i)->factory == factory) - { - // create the handle - AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle") - sound->keep = keep; - sound->current = -1; - sound->isBuffered = true; - sound->data_end = true; + lock(); - alcSuspendContext(m_context); + AUD_OpenALHandle* sound = NULL; - // OpenAL playback code - try + try + { + // check if it is a buffered factory + for(AUD_BFIterator i = m_bufferedFactories->begin(); + i != m_bufferedFactories->end(); i++) + { + if((*i)->factory == factory) { - alGenSources(1, &sound->source); - if(alGetError() != AL_NO_ERROR) - AUD_THROW(AUD_ERROR_OPENAL); + // create the handle + sound = new AUD_OpenALHandle; AUD_NEW("handle") + sound->keep = keep; + sound->current = -1; + sound->isBuffered = true; + sound->data_end = true; + + alcSuspendContext(m_context); + // OpenAL playback code try { - alSourcei(sound->source, AL_BUFFER, (*i)->buffer); + alGenSources(1, &sound->source); if(alGetError() != AL_NO_ERROR) AUD_THROW(AUD_ERROR_OPENAL); + + try + { + alSourcei(sound->source, AL_BUFFER, (*i)->buffer); + if(alGetError() != AL_NO_ERROR) + AUD_THROW(AUD_ERROR_OPENAL); + } + catch(AUD_Exception) + { + alDeleteSources(1, &sound->source); + throw; + } } catch(AUD_Exception) { - alDeleteSources(1, &sound->source); + delete sound; AUD_DELETE("handle") + alcProcessContext(m_context); throw; } - } - catch(AUD_Exception) - { - delete sound; AUD_DELETE("handle") - alcProcessContext(m_context); - unlock(); - throw; - } - // play sound - m_playingSounds->push_back(sound); + // play sound + m_playingSounds->push_back(sound); - alSourcei(sound->source, AL_SOURCE_RELATIVE, 1); - start(); + alSourcei(sound->source, AL_SOURCE_RELATIVE, 1); + start(); - alcProcessContext(m_context); - unlock(); - - return sound; + alcProcessContext(m_context); + } } } + catch(AUD_Exception) + { + unlock(); + throw; + } + + unlock(); + + if(sound) + return sound; AUD_IReader* reader = factory->createReader(); @@ -596,7 +611,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) } // create the handle - AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle") + sound = new AUD_OpenALHandle; AUD_NEW("handle") sound->keep = keep; sound->reader = reader; sound->current = 0; @@ -683,8 +698,11 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) bool AUD_OpenALDevice::pause(AUD_Handle* handle) { - // only songs that are played can be paused + bool result = false; + lock(); + + // only songs that are played can be paused for(AUD_HandleIterator i = m_playingSounds->begin(); i != m_playingSounds->end(); i++) { @@ -693,16 +711,20 @@ bool AUD_OpenALDevice::pause(AUD_Handle* handle) m_pausedSounds->push_back(*i); alSourcePause((*i)->source); m_playingSounds->erase(i); - unlock(); - return true; + result = true; + break; } } + unlock(); - return false; + + return result; } bool AUD_OpenALDevice::resume(AUD_Handle* handle) { + bool result = false; + lock(); // only songs that are paused can be resumed @@ -714,19 +736,24 @@ bool AUD_OpenALDevice::resume(AUD_Handle* handle) m_playingSounds->push_back(*i); start(); m_pausedSounds->erase(i); - unlock(); - return true; + result = true; + break; } } + unlock(); - return false; + + return result; } bool AUD_OpenALDevice::stop(AUD_Handle* handle) { AUD_OpenALHandle* sound; + bool result = false; + lock(); + for(AUD_HandleIterator i = m_playingSounds->begin(); i != m_playingSounds->end(); i++) { @@ -741,51 +768,60 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle) } delete *i; AUD_DELETE("handle") m_playingSounds->erase(i); - unlock(); - return true; + result = true; + break; } } - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + if(!result) { - if(*i == handle) + for(AUD_HandleIterator i = m_pausedSounds->begin(); + i != m_pausedSounds->end(); i++) { - sound = *i; - alDeleteSources(1, &sound->source); - if(!sound->isBuffered) + if(*i == handle) { - delete sound->reader; AUD_DELETE("reader") - alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); + sound = *i; + alDeleteSources(1, &sound->source); + if(!sound->isBuffered) + { + delete sound->reader; AUD_DELETE("reader") + alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); + } + delete *i; AUD_DELETE("handle") + m_pausedSounds->erase(i); + result = true; + break; } - delete *i; AUD_DELETE("handle") - m_pausedSounds->erase(i); - unlock(); - return true; } } + unlock(); - return false; + + return result; } bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep) { + bool result = false; + lock(); + if(isValid(handle)) { ((AUD_OpenALHandle*)handle)->keep = keep; - unlock(); - return true; + result = true; } + unlock(); - return false; + + return result; } bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message) { - lock(); - bool result = false; + lock(); + if(handle == 0) { for(AUD_HandleIterator i = m_playingSounds->begin(); @@ -800,12 +836,16 @@ bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message) else if(isValid(handle)) if(!((AUD_OpenALHandle*)handle)->isBuffered) result = ((AUD_OpenALHandle*)handle)->reader->notify(message); + unlock(); + return result; } bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position) { + bool result = false; + lock(); if(isValid(handle)) @@ -857,20 +897,19 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position) alSourceRewind(alhandle->source); } } - unlock(); - return true; + result = true; } unlock(); - return false; + return result; } float AUD_OpenALDevice::getPosition(AUD_Handle* handle) { - lock(); - float position = 0.0; + lock(); + if(isValid(handle)) { AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle; @@ -887,27 +926,35 @@ float AUD_OpenALDevice::getPosition(AUD_Handle* handle) AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle) { + AUD_Status status = AUD_STATUS_INVALID; + lock(); + for(AUD_HandleIterator i = m_playingSounds->begin(); i != m_playingSounds->end(); i++) { if(*i == handle) { - unlock(); - return AUD_STATUS_PLAYING; + status = AUD_STATUS_PLAYING; + break; } } - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + if(status == AUD_STATUS_INVALID) { - if(*i == handle) + for(AUD_HandleIterator i = m_pausedSounds->begin(); + i != m_pausedSounds->end(); i++) { - unlock(); - return AUD_STATUS_PAUSED; + if(*i == handle) + { + status = AUD_STATUS_PAUSED; + break; + } } } + unlock(); - return AUD_STATUS_INVALID; + + return status; } void AUD_OpenALDevice::lock() @@ -935,6 +982,7 @@ bool AUD_OpenALDevice::checkCapability(int capability) bool AUD_OpenALDevice::setCapability(int capability, void *value) { + bool result = false; switch(capability) { case AUD_CAPS_VOLUME: @@ -948,8 +996,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value) { alSourcef(((AUD_OpenALHandle*)caps->handle)->source, AL_GAIN, caps->value); - unlock(); - return true; + result = true; } unlock(); } @@ -962,8 +1009,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value) { alSourcef(((AUD_OpenALHandle*)caps->handle)->source, AL_PITCH, caps->value); - unlock(); - return true; + result = true; } unlock(); } @@ -981,11 +1027,13 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value) { if((*i)->factory == factory) { - unlock(); - return true; + result = true; + break; } } unlock(); + if(result) + return result; AUD_IReader* reader = factory->createReader(); @@ -1104,11 +1152,13 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value) } break; } - return false; + return result; } bool AUD_OpenALDevice::getCapability(int capability, void *value) { + bool result = false; + switch(capability) { case AUD_CAPS_VOLUME: @@ -1122,8 +1172,7 @@ bool AUD_OpenALDevice::getCapability(int capability, void *value) { alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source, AL_GAIN, &caps->value); - unlock(); - return true; + result = true; } unlock(); } @@ -1136,14 +1185,14 @@ bool AUD_OpenALDevice::getCapability(int capability, void *value) { alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source, AL_PITCH, &caps->value); - unlock(); - return true; + result = true; } unlock(); } break; } - return false; + + return result; } /******************************************************************************/ @@ -1233,6 +1282,8 @@ float AUD_OpenALDevice::getSetting(AUD_3DSetting setting) bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data) { + bool result = false; + lock(); if(isValid(handle)) @@ -1241,12 +1292,12 @@ bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data) alSourcefv(source, AL_POSITION, (ALfloat*)data.position); alSourcefv(source, AL_VELOCITY, (ALfloat*)data.velocity); alSourcefv(source, AL_DIRECTION, (ALfloat*)&(data.orientation[3])); - unlock(); - return true; + result = true; } unlock(); - return false; + + return result; } bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle, diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index afa1568d6dc..bc9598d6c81 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -531,6 +531,17 @@ AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound) } } +int AUD_setDeviceVolume(AUD_Device* device, float volume) +{ + assert(device); + + try + { + return device->setCapability(AUD_CAPS_VOLUME, &volume); + } + catch(AUD_Exception) {} +} + int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle, float volume) { diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index b02b465bff2..66a5a5147b3 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -299,6 +299,14 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch); */ extern AUD_Device* AUD_openReadDevice(AUD_Specs specs); +/** + * Sets the main volume of a device. + * \param device The device. + * \param volume The new volume, must be between 0.0 and 1.0. + * \return Whether the action succeeded. + */ +extern int AUD_setDeviceVolume(AUD_Device* device, float volume); + /** * Plays back a sound file through a read device. * \param device The read device. diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp index 174ff8c8979..42a90a6f15e 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp +++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp @@ -94,51 +94,53 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length) { lock(); - AUD_SoftwareHandle* sound; - int len; - sample_t* buf; - int sample_size = AUD_SAMPLE_SIZE(m_specs); - std::list stopSounds; - - // for all sounds - AUD_HandleIterator it = m_playingSounds->begin(); - while(it != m_playingSounds->end()) { - sound = *it; - // increment the iterator to make sure it's valid, - // in case the sound gets deleted after stopping - ++it; + AUD_SoftwareHandle* sound; + int len; + sample_t* buf; + int sample_size = AUD_SAMPLE_SIZE(m_specs); + std::list stopSounds; + + // for all sounds + AUD_HandleIterator it = m_playingSounds->begin(); + while(it != m_playingSounds->end()) + { + sound = *it; + // increment the iterator to make sure it's valid, + // in case the sound gets deleted after stopping + ++it; - // get the buffer from the source - len = length; - sound->reader->read(len, buf); + // get the buffer from the source + len = length; + sound->reader->read(len, buf); - m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume); + m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume); - // in case the end of the sound is reached - if(len < length) - { - if(sound->keep) - pause(sound); - else - stopSounds.push_back(sound); + // in case the end of the sound is reached + if(len < length) + { + if(sound->keep) + pause(sound); + else + stopSounds.push_back(sound); + } } - } - // fill with silence - if(m_specs.format == AUD_FORMAT_U8) - memset(buffer, 0x80, length * sample_size); - else - memset(buffer, 0, length * sample_size); + // fill with silence + if(m_specs.format == AUD_FORMAT_U8) + memset(buffer, 0x80, length * sample_size); + else + memset(buffer, 0, length * sample_size); - // superpose - m_mixer->superpose(buffer, length, m_volume); + // superpose + m_mixer->superpose(buffer, length, m_volume); - while(!stopSounds.empty()) - { - sound = stopSounds.front(); - stopSounds.pop_front(); - stop(sound); + while(!stopSounds.empty()) + { + sound = stopSounds.front(); + stopSounds.pop_front(); + stop(sound); + } } unlock(); @@ -201,8 +203,11 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep) bool AUD_SoftwareDevice::pause(AUD_Handle* handle) { - // only songs that are played can be paused + bool result = false; + lock(); + + // only songs that are played can be paused for(AUD_HandleIterator i = m_playingSounds->begin(); i != m_playingSounds->end(); i++) { @@ -212,18 +217,23 @@ bool AUD_SoftwareDevice::pause(AUD_Handle* handle) m_playingSounds->erase(i); if(m_playingSounds->empty()) playing(m_playback = false); - unlock(); - return true; + result = true; + break; } } + unlock(); - return false; + + return result; } bool AUD_SoftwareDevice::resume(AUD_Handle* handle) { - // only songs that are paused can be resumed + bool result = false; + lock(); + + // only songs that are paused can be resumed for(AUD_HandleIterator i = m_pausedSounds->begin(); i != m_pausedSounds->end(); i++) { @@ -233,17 +243,22 @@ bool AUD_SoftwareDevice::resume(AUD_Handle* handle) m_pausedSounds->erase(i); if(!m_playback) playing(m_playback = true); - unlock(); - return true; + result = true; + break; } } + unlock(); - return false; + + return result; } bool AUD_SoftwareDevice::stop(AUD_Handle* handle) { + bool result = false; + lock(); + for(AUD_HandleIterator i = m_playingSounds->begin(); i != m_playingSounds->end(); i++) { @@ -254,37 +269,46 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle) m_playingSounds->erase(i); if(m_playingSounds->empty()) playing(m_playback = false); - unlock(); - return true; + result = true; + break; } } - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + if(!result) { - if(*i == handle) + for(AUD_HandleIterator i = m_pausedSounds->begin(); + i != m_pausedSounds->end(); i++) { - delete (*i)->reader; AUD_DELETE("reader") - delete *i; AUD_DELETE("handle") - m_pausedSounds->erase(i); - unlock(); - return true; + if(*i == handle) + { + delete (*i)->reader; AUD_DELETE("reader") + delete *i; AUD_DELETE("handle") + m_pausedSounds->erase(i); + result = true; + break; + } } } + unlock(); - return false; + + return result; } bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep) { + bool result = false; + lock(); + if(isValid(handle)) { ((AUD_SoftwareHandle*)handle)->keep = keep; - unlock(); - return true; + result = true; } + unlock(); - return false; + + return result; } bool AUD_SoftwareDevice::sendMessage(AUD_Handle* handle, AUD_Message &message) @@ -312,16 +336,18 @@ bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position) { lock(); + bool result = false; + if(isValid(handle)) { AUD_IReader* reader = ((AUD_SoftwareHandle*)handle)->reader; reader->seek((int)(position * reader->getSpecs().rate)); - unlock(); - return true; + result = true; } unlock(); - return false; + + return result; } float AUD_SoftwareDevice::getPosition(AUD_Handle* handle) @@ -337,32 +363,41 @@ float AUD_SoftwareDevice::getPosition(AUD_Handle* handle) } unlock(); + return position; } AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle) { + AUD_Status status = AUD_STATUS_INVALID; + lock(); + for(AUD_HandleIterator i = m_playingSounds->begin(); i != m_playingSounds->end(); i++) { if(*i == handle) { - unlock(); - return AUD_STATUS_PLAYING; + status = AUD_STATUS_PLAYING; + break; } } - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + if(status == AUD_STATUS_INVALID) { - if(*i == handle) + for(AUD_HandleIterator i = m_pausedSounds->begin(); + i != m_pausedSounds->end(); i++) { - unlock(); - return AUD_STATUS_PAUSED; + if(*i == handle) + { + status = AUD_STATUS_PAUSED; + break; + } } } + unlock(); - return AUD_STATUS_INVALID; + + return status; } void AUD_SoftwareDevice::lock() @@ -384,6 +419,8 @@ bool AUD_SoftwareDevice::checkCapability(int capability) bool AUD_SoftwareDevice::setCapability(int capability, void *value) { + bool result = false; + switch(capability) { case AUD_CAPS_VOLUME: @@ -407,18 +444,20 @@ bool AUD_SoftwareDevice::setCapability(int capability, void *value) handle->volume = 1.0; else if(handle->volume < 0.0) handle->volume = 0.0; - unlock(); - return true; + result = true; } unlock(); } break; } - return false; + + return result;; } bool AUD_SoftwareDevice::getCapability(int capability, void *value) { + bool result = false; + switch(capability) { case AUD_CAPS_VOLUME: @@ -429,16 +468,19 @@ bool AUD_SoftwareDevice::getCapability(int capability, void *value) case AUD_CAPS_SOURCE_VOLUME: { AUD_SourceCaps* caps = (AUD_SourceCaps*) value; + lock(); + if(isValid(caps->handle)) { caps->value = ((AUD_SoftwareHandle*)caps->handle)->volume; - unlock(); - return true; + result = true; } + unlock(); } break; } - return false; + + return result; } diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index c6c4a776faf..6ac9b020f21 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -450,10 +450,11 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e float fps = FPS; AUD_Sound *limiter, *delayer; int frameskip, s, e; - AUD_Handle* h; end++; + AUD_setDeviceVolume(mixdown, volume); + for(handle = scene->sound_handles.first; handle; handle = handle->next) { if(start < handle->endframe && end > handle->startframe && !handle->mute && handle->source && handle->source->handle) @@ -471,8 +472,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int e limiter = AUD_limitSound(handle->source->handle, frameskip / fps, e / fps); delayer = AUD_delaySound(limiter, s / fps); - h = AUD_playDevice(mixdown, delayer); - AUD_setDeviceSoundVolume(mixdown, h, volume); + AUD_playDevice(mixdown, delayer); AUD_unload(delayer); AUD_unload(limiter); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index cac639a64ed..f0b4fae69ee 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2123,13 +2123,13 @@ void RNA_def_scene(BlenderRNA *brna) prop= RNA_def_property(srna, "speed_of_sound", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "audio.speed_of_sound"); - RNA_def_property_range(prop, 1.0f, FLT_MAX); + RNA_def_property_range(prop, 0.01f, FLT_MAX); RNA_def_property_ui_text(prop, "Speed of Sound", "Speed of sound for doppler effect calculation."); RNA_def_property_update(prop, NC_SCENE, NULL); prop= RNA_def_property(srna, "doppler_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "audio.doppler_factor"); - RNA_def_property_range(prop, FLT_MIN, FLT_MAX); + RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_text(prop, "Doppler Factor", "Pitch factor for doppler effect calculation."); RNA_def_property_update(prop, NC_SCENE, NULL); diff --git a/source/gameengine/GameLogic/SCA_BasicEventManager.h b/source/gameengine/GameLogic/SCA_BasicEventManager.h index 1aae5f9be5c..3bd2df08c07 100644 --- a/source/gameengine/GameLogic/SCA_BasicEventManager.h +++ b/source/gameengine/GameLogic/SCA_BasicEventManager.h @@ -39,8 +39,6 @@ using namespace std; class SCA_BasicEventManager : public SCA_EventManager { - class SCA_LogicManager* m_logicmgr; - public: SCA_BasicEventManager(class SCA_LogicManager* logicmgr); ~SCA_BasicEventManager(); -- cgit v1.2.3 From fbfa8d2f812095eef100b1fdd67ce766bf884844 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 27 Sep 2009 04:22:04 +0000 Subject: 2.5 - Assorted Animation UI/Editing Tweaks Main Feature: * It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.) * Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying. * Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region. --> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen... --> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors... Other tweaks: * Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon * Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though. * Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too. * Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures. --- source/blender/blenkernel/intern/anim_sys.c | 4 +- .../editors/animation/anim_channels_defines.c | 45 ++++++- .../blender/editors/animation/anim_channels_edit.c | 143 +++++++++++++++++++-- source/blender/editors/animation/anim_filter.c | 59 ++++++--- source/blender/editors/animation/keyframes_edit.c | 9 ++ source/blender/editors/armature/editarmature.c | 4 +- source/blender/editors/include/ED_keyframes_edit.h | 1 + source/blender/editors/space_action/action_edit.c | 72 ++++++----- source/blender/editors/space_graph/graph_draw.c | 11 +- source/blender/editors/space_graph/graph_edit.c | 25 +++- source/blender/editors/space_graph/graph_intern.h | 1 + source/blender/editors/space_graph/graph_utils.c | 30 +++++ source/blender/editors/space_nla/nla_buttons.c | 83 ++++++++---- source/blender/editors/space_nla/nla_channels.c | 47 ++++++- source/blender/makesdna/DNA_anim_types.h | 5 + source/blender/makesrna/intern/rna_animation.c | 11 +- .../blender/windowmanager/intern/wm_event_system.c | 2 +- 17 files changed, 440 insertions(+), 112 deletions(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index ca16c62436b..07b7b6dc30c 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -244,6 +244,8 @@ void BKE_animdata_make_local(AnimData *adt) /* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */ static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath) { + + return oldpath; // FIXME!!! } @@ -264,7 +266,7 @@ static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *new /* driver targets */ for (dtar= driver->targets.first; dtar; dtar=dtar->next) { - dtat->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, dtar->rna_path); + dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path); } } } diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index c6ecad03be8..8f8700cc43b 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -762,7 +762,7 @@ static int acf_fillactd_setting_flag(int setting, short *neg) switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ - return ACT_SELECTED; + return ADT_UI_SELECTED; case ACHANNEL_SETTING_EXPAND: /* expanded */ *neg= 1; @@ -777,13 +777,18 @@ static int acf_fillactd_setting_flag(int setting, short *neg) static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type) { bAction *act= (bAction *)ale->data; + AnimData *adt= ale->adt; /* clear extra return data first */ *type= 0; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ - GET_ACF_FLAG_PTR(act->flag); + if (adt) { + GET_ACF_FLAG_PTR(adt->flag); + } + else + return 0; case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(act->flag); @@ -1001,6 +1006,9 @@ static int acf_dsmat_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1019,6 +1027,7 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(ma->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ma->adt) @@ -1070,6 +1079,9 @@ static int acf_dslam_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1088,6 +1100,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(la->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (la->adt) @@ -1139,6 +1152,9 @@ static int acf_dscam_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1157,6 +1173,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(ca->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ca->adt) @@ -1208,6 +1225,9 @@ static int acf_dscur_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1226,6 +1246,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(cu->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (cu->adt) @@ -1277,6 +1298,9 @@ static int acf_dsskey_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1295,6 +1319,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(key->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (key->adt) @@ -1346,6 +1371,9 @@ static int acf_dswor_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1364,6 +1392,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(wo->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (wo->adt) @@ -1415,6 +1444,9 @@ static int acf_dspart_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1433,6 +1465,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(part->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (part->adt) @@ -1485,6 +1518,9 @@ static int acf_dsmball_setting_flag(int setting, short *neg) *neg= 1; return ADT_CURVES_NOT_VISIBLE; + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; + default: /* unsupported */ return 0; } @@ -1502,6 +1538,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(mb->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (mb->adt) @@ -1553,6 +1590,9 @@ static int acf_dsarm_setting_flag(int setting, short *neg) case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ *neg= 1; return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; default: /* unsupported */ return 0; @@ -1571,6 +1611,7 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_EXPAND: /* expanded */ GET_ACF_FLAG_PTR(arm->flag); + case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (arm->adt) diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 4afecdb55c0..83f5fca5af5 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -91,6 +91,7 @@ /* -------------------------- Exposed API ----------------------------------- */ /* Set the given animation-channel as the active one for the active context */ +// TODO: extend for animdata types... void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type) { ListBase anim_data = {NULL, NULL}; @@ -130,11 +131,29 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE); } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* need to verify that this data is valid for now */ + if (ale->adt) { + ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE); + } + } + break; } } /* set active flag */ - if (channel_data != NULL) { + if (channel_data) { switch (channel_type) { case ANIMTYPE_GROUP: { @@ -154,6 +173,23 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int nlt->flag |= NLATRACK_ACTIVE; } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* need to verify that this data is valid for now */ + if (ale->adt) + ale->adt->flag |= ADT_UI_ACTIVE; + } + break; } } @@ -174,7 +210,7 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short int filter; /* filter data */ - filter= ANIMFILTER_VISIBLE; + filter= ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS; ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype); /* See if we should be selecting or deselecting */ @@ -189,12 +225,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short sel= ACHANNEL_SETFLAG_CLEAR; break; case ANIMTYPE_OBJECT: + #if 0 /* for now, do not take object selection into account, since it gets too annoying */ if (ale->flag & SELECT) sel= ACHANNEL_SETFLAG_CLEAR; - break; - case ANIMTYPE_FILLACTD: - if (ale->flag & ACT_SELECTED) - sel= ACHANNEL_SETFLAG_CLEAR; + #endif break; case ANIMTYPE_GROUP: if (ale->flag & AGRP_SELECTED) @@ -208,6 +242,22 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short if (ale->flag & NLATRACK_SELECTED) sel= ACHANNEL_SETFLAG_CLEAR; break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) + sel= ACHANNEL_SETFLAG_CLEAR; + } + break; } } } @@ -220,23 +270,26 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short Scene *scene= (Scene *)ale->data; ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED); + + if (scene->adt) { + ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED); + } } break; case ANIMTYPE_OBJECT: + #if 0 /* for now, do not take object selection into account, since it gets too annoying */ { Base *base= (Base *)ale->data; Object *ob= base->object; ACHANNEL_SET_FLAG(base, sel, SELECT); ACHANNEL_SET_FLAG(ob, sel, SELECT); - } - break; - case ANIMTYPE_FILLACTD: - { - bAction *act= (bAction *)ale->data; - ACHANNEL_SET_FLAG(act, sel, ACT_SELECTED); + if (ob->adt) { + ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED); + } } + #endif break; case ANIMTYPE_GROUP: { @@ -262,6 +315,25 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short nlt->flag &= ~NLATRACK_ACTIVE; } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* need to verify that this data is valid for now */ + if (ale->adt) { + ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED); + ale->adt->flag &= ~ADT_UI_ACTIVE; + } + } + break; } } @@ -1310,18 +1382,22 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh } /* action to take depends on what channel we've got */ + // WARNING: must keep this in sync with the equivalent function in nla_channels.c switch (ale->type) { case ANIMTYPE_SCENE: { Scene *sce= (Scene *)ale->data; + AnimData *adt= sce->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ sce->flag ^= SCE_DS_SELECTED; + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { sce->flag |= SCE_DS_SELECTED; + if (adt) adt->flag |= ADT_UI_SELECTED; } notifierFlags |= ND_ANIMCHAN_SELECT; @@ -1333,34 +1409,75 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh Scene *sce= (Scene *)ads->source; Base *base= (Base *)ale->data; Object *ob= base->object; + AnimData *adt= ob->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ base->flag ^= SELECT; ob->flag= base->flag; + + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { Base *b; - /* deleselect all */ + /* deselect all */ + // TODO: should this deselect all other types of channels too? for (b= sce->base.first; b; b= b->next) { b->flag &= ~SELECT; b->object->flag= b->flag; + if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE); } /* select object now */ base->flag |= SELECT; ob->flag |= SELECT; + if (adt) adt->flag |= ADT_UI_SELECTED; } /* xxx should be ED_base_object_activate(), but we need context pointer for that... */ //set_active_base(base); + if ((adt) && (adt->flag & ADT_UI_SELECTED)) + adt->flag |= ADT_UI_ACTIVE; notifierFlags |= ND_ANIMCHAN_SELECT; } break; + + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* sanity checking... */ + if (ale->adt) { + /* select/deselect */ + if (selectmode == SELECT_INVERT) { + /* inverse selection status of this AnimData block only */ + ale->adt->flag ^= ADT_UI_SELECTED; + } + else { + /* select AnimData block by itself */ + ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ale->adt->flag |= ADT_UI_SELECTED; + } + + /* set active? */ + if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) + ale->adt->flag |= ADT_UI_ACTIVE; + } + notifierFlags |= ND_ANIMCHAN_SELECT; + } + break; + case ANIMTYPE_GROUP: { bActionGroup *agrp= (bActionGroup *)ale->data; diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 38b702f81e0..74b93089bc0 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -413,7 +413,9 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac) }\ } - +/* quick macro to test if an anim-channel representing an AnimData block is suitably active */ +#define ANIMCHANNEL_ACTIVEOK(ale) \ + ( !(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) ) /* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */ #define ANIMCHANNEL_SELOK(test_func) \ @@ -980,10 +982,13 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads, /* include material-expand widget? */ // hmm... do we need to store the index of this material in the array anywhere? if (filter_mode & ANIMFILTER_CHANNELS) { - ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(ma) { + ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } @@ -1037,11 +1042,14 @@ static int animdata_filter_dopesheet_particles (ListBase *anim_data, bDopeSheet /* add particle settings? */ if (FILTER_PART_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) { - if ((filter_mode & ANIMFILTER_CHANNELS)){ - ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + if ((filter_mode & ANIMFILTER_CHANNELS)) { + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(psys->part) { + ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } @@ -1117,9 +1125,12 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad expanded= EXPANDED_DRVD(adt); /* include data-expand widget? */ - if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) { - ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat); - if (ale) BLI_addtail(anim_data, ale); + if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) { + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(iat) { + ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat); + if (ale) BLI_addtail(anim_data, ale); + } } /* add object-data animation channels? */ @@ -1149,10 +1160,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) { /* check if filtering by selection */ if ANIMCHANNEL_SELOK((base->flag & SELECT)) { - ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, NULL); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(ob) { + ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, (ID *)ob); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } } @@ -1233,10 +1247,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B { /* action (keyframes) */ /* include shapekey-expand widget? */ if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) { - ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob); - if (ale) { - BLI_addtail(anim_data, ale); - items++; + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(key) { + ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } } } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 9666cb115b1..65f7d845b29 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -461,6 +461,13 @@ static short snap_bezier_horizontal(BeztEditData *bed, BezTriple *bezt) return 0; } +static short snap_bezier_value(BeztEditData *bed, BezTriple *bezt) +{ + /* value to snap to is stored in the custom data -> first float value slot */ + if (bezt->f2 & SELECT) + bezt->vec[1][1]= bed->f1; + return 0; +} BeztEditFunc ANIM_editkeyframes_snap(short type) { @@ -476,6 +483,8 @@ BeztEditFunc ANIM_editkeyframes_snap(short type) return snap_bezier_nearestsec; case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */ return snap_bezier_horizontal; + case SNAP_KEYS_VALUE: /* snap to given value */ + return snap_bezier_value; default: /* just in case */ return snap_bezier_nearest; } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 5c224fbd4db..5f8c503e854 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -1736,7 +1736,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op) ED_armature_sync_selection(arm->edbo); - WM_event_add_notifier(C, NC_OBJECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, obedit); return OPERATOR_FINISHED; } @@ -3938,7 +3938,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op) ED_armature_sync_selection(arm->edbo); /* note, notifier might evolve */ - WM_event_add_notifier(C, NC_OBJECT, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index b2bf05ea5ea..57a6c5fc773 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -73,6 +73,7 @@ typedef enum eEditKeyframes_Snap { SNAP_KEYS_NEARSEC, SNAP_KEYS_NEARMARKER, SNAP_KEYS_HORIZONTAL, + SNAP_KEYS_VALUE, } eEditKeyframes_Snap; /* mirroring tools */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 9e05c482ecb..865d072d938 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -88,6 +88,44 @@ #include "action_intern.h" +/* ************************************************************************** */ +/* ACTION MANAGEMENT */ + +/* ******************** New Action Operator *********************** */ + +static int act_new_exec(bContext *C, wmOperator *op) +{ + bAction *action; + + // XXX need to restore behaviour to copy old actions... + action= add_empty_action("Action"); + + /* combined with RNA property, this will assign & increase user, + so decrease here to compensate for that */ + action->id.us--; + + /* set notifier that keyframes have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); + + return OPERATOR_FINISHED; +} + +void ACT_OT_new (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "New"; + ot->idname= "ACT_OT_new"; + ot->description= "Create new action."; + + /* api callbacks */ + ot->exec= act_new_exec; + // NOTE: this is used in the NLA too... + //ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* ************************************************************************** */ /* KEYFRAME-RANGE STUFF */ @@ -1331,38 +1369,4 @@ void ACT_OT_mirror (wmOperatorType *ot) RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", ""); } -/* ******************** New Action Operator *********************** */ - -static int act_new_exec(bContext *C, wmOperator *op) -{ - bAction *action; - - // XXX need to restore behaviour to copy old actions... - action= add_empty_action("Action"); - - /* combined with RNA property, this will assign & increase user, - so decrease here to compensate for that */ - action->id.us--; - - /* set notifier that keyframes have changed */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); - - return OPERATOR_FINISHED; -} - -void ACT_OT_new (wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "New"; - ot->idname= "ACT_OT_new"; - ot->description= "Create new action."; - - /* api callbacks */ - ot->exec= act_new_exec; - ot->poll= ED_operator_action_active; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - /* ************************************************************************** */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 38430045bef..57e2208f089 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -858,9 +858,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri * - if the option to only show controls if the F-Curve is selected is enabled, we must obey this */ if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) { - /* enable blending to allow fading of curves */ - glEnable(GL_BLEND); - if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) { /* only draw controls if this is the active modifier */ if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) { @@ -874,7 +871,10 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) { if (fcu->bezt) { /* only draw handles/vertices on keyframes */ - draw_fcurve_handles(sipo, ar, fcu); + glEnable(GL_BLEND); + draw_fcurve_handles(sipo, ar, fcu); + glDisable(GL_BLEND); + draw_fcurve_vertices(sipo, ar, fcu); } else { @@ -882,9 +882,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri draw_fcurve_samples(sipo, ar, fcu); } } - - /* restore settings */ - glDisable(GL_BLEND); } /* undo mapping of keyframes for drawing if scaled F-Curve */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 9e0d574ffa3..9814f16de16 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1296,8 +1296,7 @@ void GRAPH_OT_handle_type (wmOperatorType *ot) /* set of three euler-rotation F-Curves */ typedef struct tEulerFilter { ID *id; /* ID-block which owns the channels */ - FCurve *fcu1, *fcu2, *fcu3; /* x,y,z rotation curves */ - int i1, i2, i3; /* current index for each curve */ + FCurve (*fcurves)[3]; /* 3 Pointers to F-Curves */ } tEulerFilter; static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) @@ -1347,10 +1346,26 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) if ((euf) && (ale->id != euf->id)) { } + else { + /* just add to a new block */ + euf= MEM_callocN(sizeof(tEulerFilter), "tEulerFilter"); + BLI_addtail(&eulers, euf); + + euf->id= ale->id; + euf->fcurves[fcu->array_index]= fcu; + } } + BLI_freelistN(&anim_data); - // XXX for now - return OPERATOR_CANCELLED; + /* step 2: go through each set of curves, processing the values at each keyframe + * - it is assumed that there must be a full set of keyframes at each keyframe position + */ + for (euf= eulers.first; euf; euf= euf->next) { + + } + BLI_freelistN(&eulers); + + return OPERATOR_FINISHED; } void GRAPH_OT_euler_filter (wmOperatorType *ot) @@ -1789,7 +1804,7 @@ void GRAPH_OT_fmodifier_add (wmOperatorType *ot) /* api callbacks */ ot->invoke= graph_fmodifier_add_invoke; ot->exec= graph_fmodifier_add_exec; - ot->poll= graphop_active_fcurve_poll; + ot->poll= graphop_selected_fcurve_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 2e8d0655d2d..83a565e485f 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -155,6 +155,7 @@ short fcurve_needs_draw_fmodifier_controls(struct FCurve *fcu, struct FModifier int graphop_visible_keyframes_poll(struct bContext *C); int graphop_editable_keyframes_poll(struct bContext *C); int graphop_active_fcurve_poll(struct bContext *C); +int graphop_selected_fcurve_poll(struct bContext *C); /* ***************************************** */ /* graph_ops.c */ diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index f00e7845549..19cffb5cde1 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -285,4 +285,34 @@ int graphop_active_fcurve_poll (bContext *C) return has_fcurve; } +/* has selected F-Curve that's editable */ +int graphop_selected_fcurve_poll (bContext *C) +{ + bAnimContext ac; + bAnimListElem *ale; + ListBase anim_data = {NULL, NULL}; + ScrArea *sa= CTX_wm_area(C); + int filter, items; + short found = 0; + + /* firstly, check if in Graph Editor */ + // TODO: also check for region? + if ((sa == NULL) || (sa->spacetype != SPACE_IPO)) + return 0; + + /* try to init Anim-Context stuff ourselves and check */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return 0; + + /* get the editable + selected F-Curves, and as long as we got some, we can return */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + if (items == 0) + return 0; + + /* cleanup and return findings */ + BLI_freelistN(&anim_data); + return found; +} + /* ************************************************************** */ diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index a5ba63fd15d..b193b89d65a 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -114,34 +114,69 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA if (ANIM_animdata_get_context(C, &ac) == 0) return 0; - /* extract list of active channel(s), of which we should only take the first one (expecting it to be an NLA track) */ - filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE); + /* extract list of active channel(s), of which we should only take the first one + * - we need the channels flag to get the active AnimData block when there are no NLA Tracks + */ + filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE|ANIMFILTER_CHANNELS); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); for (ale= anim_data.first; ale; ale= ale->next) { - // TODO: need some way to select active animdata too... - if (ale->type == ANIMTYPE_NLATRACK) { - NlaTrack *nlt= (NlaTrack *)ale->data; - AnimData *adt= ale->adt; - - /* found it, now set the pointers */ - if (adt_ptr) { - /* AnimData pointer */ - RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr); - } - if (nlt_ptr) { - /* NLA-Track pointer */ - RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr); - } - if (strip_ptr) { - /* NLA-Strip pointer */ - NlaStrip *strip= BKE_nlastrip_find_active(nlt); - RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr); + switch (ale->type) { + case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */ + { + NlaTrack *nlt= (NlaTrack *)ale->data; + AnimData *adt= ale->adt; + + /* found it, now set the pointers */ + if (adt_ptr) { + /* AnimData pointer */ + RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr); + } + if (nlt_ptr) { + /* NLA-Track pointer */ + RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr); + } + if (strip_ptr) { + /* NLA-Strip pointer */ + NlaStrip *strip= BKE_nlastrip_find_active(nlt); + RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr); + } + + found= 1; } - - found= 1; - break; + break; + + case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */ + case ANIMTYPE_OBJECT: + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* for these channels, we only do AnimData */ + if (ale->id && ale->adt) { + if (adt_ptr) { + /* AnimData pointer */ + RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr); + + /* set found status to -1, since setting to 1 would break the loop + * and potentially skip an active NLA-Track in some cases... + */ + found= -1; + } + } + } + break; } + + if (found > 0) + break; } /* free temp data */ @@ -211,7 +246,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa) /* Active Action Properties ------------------------------------- */ /* action */ row= uiLayoutRow(layout, 1); - uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators + uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACT_OT_new", NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators /* extrapolation */ row= uiLayoutRow(layout, 1); diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index ccf23266427..07dc3f0ad89 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -116,18 +116,22 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho } /* action to take depends on what channel we've got */ + // WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c switch (ale->type) { case ANIMTYPE_SCENE: { Scene *sce= (Scene *)ale->data; + AnimData *adt= sce->adt; /* set selection status */ if (selectmode == SELECT_INVERT) { /* swap select */ sce->flag ^= SCE_DS_SELECTED; + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { sce->flag |= SCE_DS_SELECTED; + if (adt) adt->flag |= ADT_UI_SELECTED; } notifierFlags |= ND_ANIMCHAN_SELECT; @@ -139,6 +143,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho Scene *sce= (Scene *)ads->source; Base *base= (Base *)ale->data; Object *ob= base->object; + AnimData *adt= ob->adt; if (nlaedit_is_tweakmode_on(ac) == 0) { /* set selection status */ @@ -146,23 +151,30 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho /* swap select */ base->flag ^= SELECT; ob->flag= base->flag; + + if (adt) adt->flag ^= ADT_UI_SELECTED; } else { Base *b; - /* deleselect all */ + /* deselect all */ + // TODO: should this deselect all other types of channels too? for (b= sce->base.first; b; b= b->next) { b->flag &= ~SELECT; b->object->flag= b->flag; + if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE); } /* select object now */ base->flag |= SELECT; ob->flag |= SELECT; + if (adt) adt->flag |= ADT_UI_SELECTED; } /* xxx should be ED_base_object_activate(), but we need context pointer for that... */ //set_active_base(base); + if ((adt) && (adt->flag & ADT_UI_SELECTED)) + adt->flag |= ADT_UI_ACTIVE; /* notifiers - channel was selected */ notifierFlags |= ND_ANIMCHAN_SELECT; @@ -170,6 +182,39 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho } break; + case ANIMTYPE_FILLACTD: /* Action Expander */ + case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ + case ANIMTYPE_DSLAM: + case ANIMTYPE_DSCAM: + case ANIMTYPE_DSCUR: + case ANIMTYPE_DSSKEY: + case ANIMTYPE_DSWOR: + case ANIMTYPE_DSPART: + case ANIMTYPE_DSMBALL: + case ANIMTYPE_DSARM: + { + /* sanity checking... */ + if (ale->adt) { + /* select/deselect */ + if (selectmode == SELECT_INVERT) { + /* inverse selection status of this AnimData block only */ + ale->adt->flag ^= ADT_UI_SELECTED; + } + else { + /* select AnimData block by itself */ + ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ale->adt->flag |= ADT_UI_SELECTED; + } + + /* set active? */ + if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) + ale->adt->flag |= ADT_UI_ACTIVE; + } + + notifierFlags |= ND_ANIMCHAN_SELECT; + } + break; + case ANIMTYPE_NLATRACK: { NlaTrack *nlt= (NlaTrack *)ale->data; diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index f75ed273164..c1e9ed4be40 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -763,6 +763,11 @@ typedef enum eAnimData_Flag { /* don't execute drivers */ ADT_DRIVERS_DISABLED = (1<<11), + /* AnimData block is selected in UI */ + ADT_UI_SELECTED = (1<<14), + /* AnimData block is active in UI */ + ADT_UI_ACTIVE = (1<<15), + /* F-Curves from this AnimData block are not visible in the Graph Editor */ ADT_CURVES_NOT_VISIBLE = (1<<16), } eAnimData_Flag; diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index a8d3a6edaae..4b2c11c2e0d 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -57,6 +57,12 @@ static int rna_AnimData_action_editable(PointerRNA *ptr) return 1; } +static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value) +{ + AnimData *adt= (AnimData*)(ptr->data); + adt->action= value.data; +} + static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value) { KS_Path *ksp= (KS_Path *)ptr->data; @@ -202,8 +208,11 @@ void rna_def_animdata(BlenderRNA *brna) /* Active Action */ prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock."); + RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL); + RNA_def_property_flag(prop, PROP_EDITABLE); /* this flag as well as the dynamic test must be defined for this to be editable... */ RNA_def_property_editable_func(prop, "rna_AnimData_action_editable"); + RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock."); + /* Active Action Settings */ prop= RNA_def_property(srna, "action_extrapolation", PROP_ENUM, PROP_NONE); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index af1339323f3..846309f1265 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -239,7 +239,7 @@ void wm_event_do_notifiers(bContext *C) if(G.rendering==0) { // XXX make lock in future, or separated derivedmesh users in scene - /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, + /* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual, no layer check here, gets correct flushed */ /* sets first, we allow per definition current scene to have dependencies on sets */ if(scene->set) { -- cgit v1.2.3 From 8a6d6a33f8542e8940119a6435969ac119e68229 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 27 Sep 2009 06:14:42 +0000 Subject: Animation Editors - Moved the code for drawing the filtering toggles into a single function. --- source/blender/editors/animation/anim_draw.c | 50 ++++++++++++++++++++++ source/blender/editors/include/ED_anim_api.h | 10 ++++- .../blender/editors/space_action/action_header.c | 19 +------- source/blender/editors/space_graph/graph_header.c | 25 +---------- source/blender/editors/space_graph/graph_utils.c | 1 - source/blender/editors/space_nla/nla_header.c | 26 +---------- source/blender/makesdna/DNA_action_types.h | 2 +- 7 files changed, 62 insertions(+), 71 deletions(-) diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 6388106fdb5..507bf03e7ef 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -55,6 +55,7 @@ #include "ED_anim_api.h" #include "ED_keyframes_edit.h" +#include "ED_types.h" #include "ED_util.h" #include "WM_api.h" @@ -316,3 +317,52 @@ void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, s } /* *************************************************** */ +/* ANIMATION EDITOR UI-WIDGETS */ + +/* ui button event */ +#define B_REDR 1 + +/* standard header buttons for Animation Editors */ +short ANIM_headerUI_standard_buttons (const bContext *C, bDopeSheet *ads, uiBlock *block, short xco, short yco) +{ + ScrArea *sa= CTX_wm_area(C); + short nlaActive= ((sa) && (sa->spacetype==SPACE_NLA)); + + /* check if the DopeSheet data exists, just in case... */ + if (ads) { + /* more 'generic' filtering options */ + if (nlaActive) uiBlockBeginAlign(block); + uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Only display selected Objects"); + if (nlaActive) uiDefIconButBitI(block, TOGN, ADS_FILTER_NLA_NOACT, B_REDR, ICON_ACTION, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Include AnimData blocks with no NLA Data"); + if (nlaActive) uiBlockEndAlign(block); + xco += 5; + + /* datatype based */ + // TODO: only show the datablocks which exist + uiBlockBeginAlign(block); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Scene Animation"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display World Animation"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Material Data"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Lamp Data"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Camera Data"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Curve Data"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display MetaBall Data"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Armature Data"); + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Particle Data"); + uiBlockEndAlign(block); + xco += 30; + } + else { + // XXX this case shouldn't happen at all... for now, just pad out same amount of space + printf("ERROR: dopesheet data not available when drawing Animation Editor header \n"); + xco += 11*XIC + 30; + } + + // TODO: include auto-snapping menu here too... + + /* return the width of the buttons */ + return xco; +} + +/* *************************************************** */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 7e7aba85363..d9439956569 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -42,11 +42,14 @@ struct View2D; struct Scene; struct Object; +struct bDopeSheet; + struct bActionGroup; struct FCurve; struct FModifier; struct uiBlock; +struct uiLayout; /* ************************************************ */ /* ANIMATION CHANNEL FILTERING */ @@ -394,11 +397,14 @@ void ANIM_draw_cfra(const struct bContext *C, struct View2D *v2d, short flag); /* main call to draw preview range curtains */ void ANIM_draw_previewrange(const struct bContext *C, struct View2D *v2d); +/* ------------- Preview Range Drawing -------------- */ + +/* standard header buttons for Animation Editors */ +short ANIM_headerUI_standard_buttons(const struct bContext *C, struct bDopeSheet *ads, struct uiBlock *block, short xco, short yco); + /* ************************************************* */ /* F-MODIFIER TOOLS */ -struct uiLayout; - /* draw a given F-Modifier for some layout/UI-Block */ void ANIM_uiTemplate_fmodifier_draw(struct uiLayout *layout, struct ID *id, ListBase *modifiers, struct FModifier *fcm); diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index f602345baea..25a5123d1b5 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -336,24 +336,7 @@ void action_header_buttons(const bContext *C, ARegion *ar) /* FILTERING OPTIONS */ xco -= 10; - //uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Only display selected Objects"); - //uiBlockEndAlign(block); - xco += 5; - - uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Scene Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display World Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display ShapeKeys"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Materials"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Lamps"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Cameras"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Curves"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display MetaBalls"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Armature/Bone"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Display Particles"); - uiBlockEndAlign(block); - xco += 30; + xco= ANIM_headerUI_standard_buttons(C, &saction->ads, block, xco, yco); } else if (saction->mode == SACTCONT_ACTION) { uiLayout *layout; diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index 79d38d9c252..98d58c92da4 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -298,30 +298,7 @@ void graph_header_buttons(const bContext *C, ARegion *ar) xco+= 120; /* filtering buttons */ - if (sipo->ads) { - //uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Only display selected Objects"); - //uiBlockEndAlign(block); - xco += 5; - - uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Scene Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display World Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Materials"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Lamps"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Cameras"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Curves"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display MetaBalls"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Armature/Bone data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(sipo->ads->filterflag), 0, 0, 0, 0, "Display Particles"); - uiBlockEndAlign(block); - xco += 30; - } - else { - // XXX this case shouldn't happen at all... for now, just pad out same amount of space - xco += 10*XIC + 30; - } + xco= ANIM_headerUI_standard_buttons(C, sipo->ads, block, xco, yco); /* auto-snap selector */ if (sipo->flag & SIPO_DRAWTIME) { diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index 19cffb5cde1..25087441b6a 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -289,7 +289,6 @@ int graphop_active_fcurve_poll (bContext *C) int graphop_selected_fcurve_poll (bContext *C) { bAnimContext ac; - bAnimListElem *ale; ListBase anim_data = {NULL, NULL}; ScrArea *sa= CTX_wm_area(C); int filter, items; diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c index 0d3bf2cb6b1..4eb9fac5cb8 100644 --- a/source/blender/editors/space_nla/nla_header.c +++ b/source/blender/editors/space_nla/nla_header.c @@ -246,31 +246,7 @@ void nla_header_buttons(const bContext *C, ARegion *ar) uiBlockSetEmboss(block, UI_EMBOSS); /* filtering buttons */ - if (snla->ads) { - uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOG, ADS_FILTER_ONLYSEL, B_REDR, ICON_RESTRICT_SELECT_OFF, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Only display selected Objects"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NLA_NOACT, B_REDR, ICON_ACTION, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Include AnimData blocks with no NLA Data"); - uiBlockEndAlign(block); - xco += 5; - - uiBlockBeginAlign(block); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Scene Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display World Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Materials"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Lamps"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Cameras"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Curves"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display MetaBalls"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(snla->ads->filterflag), 0, 0, 0, 0, "Display Particles"); - uiBlockEndAlign(block); - xco += 15; - } - else { - // XXX this case shouldn't happen at all... for now, just pad out same amount of space - xco += 10*XIC + 15; - } - xco += (XIC + 8); + xco= ANIM_headerUI_standard_buttons(C, snla->ads, block, xco, yco); /* auto-snap selector */ if (snla->flag & SNLA_DRAWTIME) { diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 43ef9f28828..2ed08150f3e 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -433,7 +433,7 @@ typedef enum DOPESHEET_FILTERFLAG { ADS_FILTER_NLA_NOACT = (1<<20), /* if the AnimData block has no NLA data, don't include to just show Action-line */ /* combination filters (some only used at runtime) */ - ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART), + ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART|ADS_FILTER_NOARM), } DOPESHEET_FILTERFLAG; /* DopeSheet general flags */ -- cgit v1.2.3 From bd7dc7788401acf74f971a4830a597cab6a0bc45 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 27 Sep 2009 06:27:45 +0000 Subject: Bugfix: Shapekey NLA Tracks were shown mixed with the ones for Objects --- source/blender/editors/animation/anim_filter.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 74b93089bc0..13b050e4497 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1226,8 +1226,21 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B ANIMDATA_FILTER_CASES(key, { /* AnimData blocks - do nothing... */ }, { /* nla */ - /* add NLA tracks */ - items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); + /* include shapekey-expand widget? */ + if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) { + /* check if filtering by active status */ + if ANIMCHANNEL_ACTIVEOK(key) { + ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } + } + } + + /* add NLA tracks - only if expanded or so */ + if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) + items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); }, { /* drivers */ /* include shapekey-expand widget? */ -- cgit v1.2.3 From 43631327887d3000be0743be8ac632f25401078f Mon Sep 17 00:00:00 2001 From: Arystanbek Dyussenov Date: Sun, 27 Sep 2009 09:19:29 +0000 Subject: Added Image.get_abs_filename() and updated scripts to use it. This removes the necessity of bpy.sys.expandpath(). Added missing Object.dupli_list. --- release/io/export_fbx.py | 4 ++-- release/io/export_obj.py | 7 ++++--- release/io/export_x3d.py | 2 +- release/io/import_3ds.py | 2 +- source/blender/makesrna/intern/rna_image_api.c | 25 ++++++++++++++++++++++--- source/blender/makesrna/intern/rna_object.c | 5 +++++ 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py index 3515170528f..aa65473b8d6 100644 --- a/release/io/export_fbx.py +++ b/release/io/export_fbx.py @@ -94,6 +94,7 @@ def copy_file(source, dest): file.close() +# XXX not used anymore, images are copied one at a time def copy_images(dest_dir, textures): if not dest_dir.endswith(os.sep): dest_dir += os.sep @@ -1285,10 +1286,9 @@ def write(filename, batch_objects = None, \ base = os.path.basename(rel) if EXP_IMAGE_COPY: - src = bpy.sys.expandpath(image.filename) absp = image.get_export_path(basepath, False) if not os.path.exists(absp): - shutil.copy(src, absp) + shutil.copy(image.get_abs_filename(), absp) return (rel, base) diff --git a/release/io/export_obj.py b/release/io/export_obj.py index bd323b6586a..e2ac78798bd 100644 --- a/release/io/export_obj.py +++ b/release/io/export_obj.py @@ -48,6 +48,7 @@ will be exported as mesh data. # import math and other in functions that use them for the sake of fast Blender startup # import math import os +import time import bpy import Mathutils @@ -98,7 +99,7 @@ def write_mtl(scene, filename, copy_images): if copy_images: abspath = image.get_export_path(dest_dir, False) if not os.path.exists(abs_path): - shutil.copy(bpy.sys.expandpath(image.filename), abs_path) + shutil.copy(image.get_abs_filename(), abs_path) return rel @@ -370,7 +371,7 @@ def write(filename, objects, scene, print('OBJ Export path: "%s"' % filename) temp_mesh_name = '~tmp-mesh' - time1 = bpy.sys.time() + time1 = time.clock() # time1 = sys.time() # scn = Scene.GetCurrent() @@ -816,7 +817,7 @@ def write(filename, objects, scene, # else: # print('\tError: "%s" could not be used as a base for an image path.' % filename) - print("OBJ Export time: %.2f" % (bpy.sys.time() - time1)) + print("OBJ Export time: %.2f" % (time.clock() - time1)) # print "OBJ Export time: %.2f" % (sys.time() - time1) def do_export(filename, context, diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py index 3661d78a343..f23ccf8d2dc 100644 --- a/release/io/export_x3d.py +++ b/release/io/export_x3d.py @@ -779,7 +779,7 @@ class x3d_class: pic = tex.image # using .expandpath just in case, os.path may not expect // - basename = os.path.basename(bpy.sys.expandpath(pic.filename)) + basename = os.path.basename(pic.get_abs_filename()) pic = alltextures[i].image # pic = alltextures[i].getImage() diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py index d57911df83c..99825471764 100644 --- a/release/io/import_3ds.py +++ b/release/io/import_3ds.py @@ -939,7 +939,7 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, # if BPyMessages.Error_NoFile(filename): # return - print('\n\nImporting 3DS: "%s"' % (bpy.sys.expandpath(filename))) + print('\n\nImporting 3DS: "%s"' % (filename)) # print('\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename))) time1 = time.clock() diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 25c764b8823..2bb7905fc03 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -34,12 +34,14 @@ #include "RNA_define.h" #include "RNA_types.h" -#include "DNA_object_types.h" - #ifdef RNA_RUNTIME -#include "BKE_utildefines.h" #include "BKE_image.h" +#include "BKE_main.h" +#include "BKE_utildefines.h" + +#include "DNA_image_types.h" +#include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -61,6 +63,17 @@ static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel) return path; } +char *rna_Image_get_abs_filename(Image *image, bContext *C) +{ + char *filename= MEM_callocN(FILE_MAX, "Image.get_abs_filename()"); + + BLI_strncpy(filename, image->name, FILE_MAXDIR + FILE_MAXFILE); + BLI_convertstringcode(filename, CTX_data_main(C)->name); + BLI_convertstringframe(filename, CTX_data_scene(C)->r.cfra); + + return filename; +} + #else void RNA_api_image(StructRNA *srna) @@ -76,6 +89,12 @@ void RNA_api_image(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path."); RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "get_abs_filename", "rna_Image_get_abs_filename"); + RNA_def_function_ui_description(func, "Get absolute filename."); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm= RNA_def_string_file_path(func, "abs_filename", NULL, 0, "", "Image/movie absolute filename."); + RNA_def_function_return(func, parm); } #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 76d9e077a18..5c665c0d730 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1414,6 +1414,11 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Dupli Frames Off", "Recurring frames to exclude from the Dupliframes."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); + prop= RNA_def_property(srna, "dupli_list", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "duplilist", NULL); + RNA_def_property_struct_type(prop, "DupliObject"); + RNA_def_property_ui_text(prop, "Dupli list", "Object duplis."); + /* time offset */ prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE|PROP_UNIT_TIME); -- cgit v1.2.3 From 6e0c1cd4e5acaa91adbfd2137709a6803647cde7 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 27 Sep 2009 09:38:13 +0000 Subject: RNA + Animation: * Added missing RNA wrapping for Scene -> AnimData * Fixed bug (with temp-fix) where sequence strips with no names couldn't be animated properly. Currently, this will just use the index of the strip, although that is likely to be mutable (adding/removing strips will change it). * Removed some old unused code from action.c --- source/blender/blenkernel/intern/action.c | 132 ------------------------ source/blender/editors/space_graph/graph_edit.c | 2 + source/blender/makesrna/intern/rna_armature.c | 1 + source/blender/makesrna/intern/rna_scene.c | 3 + source/blender/makesrna/intern/rna_sequence.c | 10 +- 5 files changed, 15 insertions(+), 133 deletions(-) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 4cfd35a494d..b8dc9fd049d 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1181,138 +1181,6 @@ static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src, VecAddf(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset); } -typedef struct NlaIpoChannel { - struct NlaIpoChannel *next, *prev; - float val; - void *poin; - int type; -} NlaIpoChannel; - -static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime) -{ - bActionChannel *achan= get_action_channel(act, name); - IpoCurve *icu; - NlaIpoChannel *nic; - - if(achan==NULL) return; - - if(achan->ipo) { - calc_ipo(achan->ipo, ctime); - - for(icu= achan->ipo->curve.first; icu; icu= icu->next) { - /* skip IPO_BITS, is for layers and cannot be blended */ - if(icu->vartype != IPO_BITS) { - nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel"); - BLI_addtail(lb, nic); - nic->val= icu->curval; - nic->poin= get_ipo_poin(id, icu, &nic->type); - } - } - } - - /* constraint channels only for objects */ - if(GS(id->name)==ID_OB) { - Object *ob= (Object *)id; - bConstraint *con; - bConstraintChannel *conchan; - - for (con=ob->constraints.first; con; con=con->next) { - conchan = get_constraint_channel(&achan->constraintChannels, con->name); - - if(conchan && conchan->ipo) { - calc_ipo(conchan->ipo, ctime); - - icu= conchan->ipo->curve.first; // only one ipo now - if(icu) { - nic= MEM_callocN(sizeof(NlaIpoChannel), "NlaIpoChannel constr"); - BLI_addtail(lb, nic); - nic->val= icu->curval; - nic->poin= &con->enforce; - nic->type= IPO_FLOAT; - } - } - } - } -} - -static NlaIpoChannel *find_nla_ipochannel(ListBase *lb, void *poin) -{ - NlaIpoChannel *nic; - - if(poin) { - for(nic= lb->first; nic; nic= nic->next) { - if(nic->poin==poin) - return nic; - } - } - return NULL; -} - - -static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int mode) -{ - NlaIpoChannel *snic, *dnic, *next; - float dstweight; - - switch (mode){ - case ACTSTRIPMODE_BLEND: - dstweight = 1.0F - srcweight; - break; - case ACTSTRIPMODE_ADD: - dstweight = 1.0F; - break; - default : - dstweight = 1.0F; - } - - for(snic= src->first; snic; snic= next) { - next= snic->next; - - dnic= find_nla_ipochannel(dst, snic->poin); - if(dnic==NULL) { - /* remove from src list, and insert in dest */ - BLI_remlink(src, snic); - BLI_addtail(dst, snic); - } - else { - /* we do the blend */ - dnic->val= dstweight*dnic->val + srcweight*snic->val; - } - } -} - -static int execute_ipochannels(ListBase *lb) -{ - NlaIpoChannel *nic; - int count = 0; - - for(nic= lb->first; nic; nic= nic->next) { - if(nic->poin) { - write_ipo_poin(nic->poin, nic->type, nic->val); - count++; - } - } - return count; -} - -/* nla timing */ - -/* this now only used for repeating cycles, to enable fields and blur. */ -/* the whole time control in blender needs serious thinking... */ -static float nla_time(Scene *scene, float cfra, float unit) -{ - extern float bluroffs; // bad construct, borrowed from object.c for now - extern float fieldoffs; - - /* motion blur & fields */ - cfra+= unit*(bluroffs+fieldoffs); - - /* global time */ - cfra*= scene->r.framelen; - - return cfra; -} - /* added "sizecorr" here, to allow armatures to be scaled and still have striding. Only works for uniform scaling. In general I'd advise against scaling armatures ever though! (ton) */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 9814f16de16..8c739d68cea 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1344,6 +1344,8 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) * - first check if id-blocks are compatible */ if ((euf) && (ale->id != euf->id)) { + /* if the paths match, add this curve to the set of curves */ + // NOTE: simple string compare for now... could be a bit more fancy... } else { diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index c89ed48d44a..5dbfdd3e6f1 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -592,6 +592,7 @@ static void rna_def_armature(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_ARMATURE_DATA); RNA_def_struct_sdna(srna, "bArmature"); + /* Animation Data */ rna_def_animdata_common(srna); /* Collections */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f0b4fae69ee..1d8ebdce369 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2041,6 +2041,9 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Stamp Note", "User define note for the render stamping."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + /* Animation Data (for Scene) */ + rna_def_animdata_common(srna); + /* Nodes (Compositing) */ prop= RNA_def_property(srna, "nodetree", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Node Tree", "Compositing node tree."); diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index 51e81d6dd3a..9404fb775c3 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -228,7 +228,15 @@ static char *rna_Sequence_path(PointerRNA *ptr) /* sequencer data comes from scene... * TODO: would be nice to make SequenceEditor data a datablock of its own (for shorter paths) */ - return BLI_sprintfN("sequence_editor.sequences[\"%s\"]", seq->name+2); + if (seq->name+2) + return BLI_sprintfN("sequence_editor.sequences[\"%s\"]", seq->name+2); + else { + /* compromise for the frequent sitation when strips don't have names... */ + Scene *sce= (Scene*)ptr->id.data; + Editing *ed= seq_give_editing(sce, FALSE); + + return BLI_sprintfN("sequence_editor.sequences[%d]", BLI_findindex(&ed->seqbase, seq)); + } } static PointerRNA rna_SequenceEdtior_meta_stack_get(CollectionPropertyIterator *iter) -- cgit v1.2.3 From 2fef3dbaa3512f6561155402c46bf3ff8c955980 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 27 Sep 2009 11:00:35 +0000 Subject: 2.5 Layout Files: * Some Code and Whitespace Cleanup. --- release/io/engine_render_pov.py | 38 ++++++++------------------ release/io/netrender/ui.py | 2 ++ release/ui/buttons_data_armature.py | 3 +-- release/ui/buttons_data_bone.py | 2 +- release/ui/buttons_data_camera.py | 5 ++-- release/ui/buttons_data_curve.py | 1 - release/ui/buttons_data_lamp.py | 9 +++---- release/ui/buttons_data_lattice.py | 2 +- release/ui/buttons_data_mesh.py | 2 +- release/ui/buttons_data_metaball.py | 8 +----- release/ui/buttons_data_text.py | 2 -- release/ui/buttons_game.py | 4 --- release/ui/buttons_material.py | 40 ++++++++++++---------------- release/ui/buttons_object_constraint.py | 3 +-- release/ui/buttons_physics_cloth.py | 6 ++--- release/ui/buttons_physics_field.py | 2 -- release/ui/buttons_physics_fluid.py | 9 +++---- release/ui/buttons_physics_smoke.py | 5 +--- release/ui/buttons_physics_softbody.py | 10 +++---- release/ui/buttons_scene.py | 1 - release/ui/buttons_texture.py | 7 ++--- release/ui/buttons_world.py | 7 +++-- release/ui/space_sequencer.py | 4 +-- release/ui/space_view3d_toolbar.py | 19 +++++-------- source/blender/editors/space_node/drawnode.c | 11 ++++---- 25 files changed, 70 insertions(+), 132 deletions(-) diff --git a/release/io/engine_render_pov.py b/release/io/engine_render_pov.py index 1c5026c84c0..f0247ce532a 100644 --- a/release/io/engine_render_pov.py +++ b/release/io/engine_render_pov.py @@ -110,8 +110,7 @@ def write_pov(filename, scene=None, info_callback = None): file.write('\tdiffuse 0.8\n') file.write('\tspecular 0.2\n') - - + # This is written into the object ''' if material and material.transparency_method=='RAYTRACE': @@ -143,9 +142,7 @@ def write_pov(filename, scene=None, info_callback = None): file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotationPart().toEuler()])) file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2])) file.write('}\n') - - - + def exportLamps(lamps): # Get all lamps for ob in lamps: @@ -186,9 +183,7 @@ def write_pov(filename, scene=None, info_callback = None): else: size_y = lamp.size_y samples_y = lamp.shadow_ray_samples_y - - - + file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y)) if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED': if lamp.jitter: @@ -264,10 +259,7 @@ def write_pov(filename, scene=None, info_callback = None): writeMatrix(ob.matrix) file.write('}\n') - - - - + def exportMeshs(sel): ob_num = 0 @@ -475,8 +467,7 @@ def write_pov(filename, scene=None, info_callback = None): file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count - - + file.write('\n }\n') # normal_indices indicies @@ -589,7 +580,6 @@ def write_pov(filename, scene=None, info_callback = None): file.close() - def write_pov_ini(filename_ini, filename_pov, filename_image): scene = bpy.data.scenes[0] render = scene.render_data @@ -775,9 +765,7 @@ class PovrayRender(bpy.types.RenderEngine): # compute resolution x= int(r.resolution_x*r.resolution_percentage*0.01) y= int(r.resolution_y*r.resolution_percentage*0.01) - - - + # Wait for the file to be created while not os.path.exists(self.temp_file_out): if self.test_break(): @@ -876,12 +864,13 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel): COMPAT_ENGINES = set(['POVRAY_RENDER']) def draw_header(self, context): - layout = self.layout scene = context.scene - layout.itemR(scene, "pov_radio_enable", text="") + + self.layout.itemR(scene, "pov_radio_enable", text="") def draw(self, context): layout = self.layout + scene = context.scene rd = scene.render_data @@ -890,7 +879,6 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel): split = layout.split() col = split.column() - col.itemR(scene, "pov_radio_count", text="Rays") col.itemR(scene, "pov_radio_recursion_limit", text="Recursions") col = split.column() @@ -905,15 +893,12 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel): col.itemR(scene, "pov_radio_adc_bailout", slider=True) col.itemR(scene, "pov_radio_gray_threshold", slider=True) col.itemR(scene, "pov_radio_low_error_factor", slider=True) - - - + col = split.column() col.itemR(scene, "pov_radio_brightness") col.itemR(scene, "pov_radio_minimum_reuse", text="Min Reuse") col.itemR(scene, "pov_radio_nearest_count") - - + split = layout.split() col = split.column() @@ -923,6 +908,5 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel): col = split.column() col.itemR(scene, "pov_radio_always_sample") - bpy.types.register(SCENE_PT_povray_radiosity) diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py index ddaf0e6854a..7681d4865e9 100644 --- a/release/io/netrender/ui.py +++ b/release/io/netrender/ui.py @@ -39,6 +39,7 @@ class SCENE_PT_network_settings(RenderButtonsPanel): def draw(self, context): layout = self.layout + scene = context.scene rd = scene.render_data @@ -69,6 +70,7 @@ class SCENE_PT_network_job(RenderButtonsPanel): def draw(self, context): layout = self.layout + scene = context.scene rd = scene.render_data diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py index 413deee362b..9344294ff9e 100644 --- a/release/ui/buttons_data_armature.py +++ b/release/ui/buttons_data_armature.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.armature) + return context.armature class DATA_PT_context_arm(DataButtonsPanel): __show_header__ = False @@ -128,7 +128,6 @@ class DATA_PT_paths(DataButtonsPanel): split = layout.split() col = split.column() - sub = col.column(align=True) if (arm.paths_type == 'CURRENT_FRAME'): sub.itemR(arm, "path_before_current", text="Before") diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py index dae969a7e5f..50ece679e27 100644 --- a/release/ui/buttons_data_bone.py +++ b/release/ui/buttons_data_bone.py @@ -240,7 +240,6 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel): #row = split.row() #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True) #row.active = pchan.ik_lin_control - class BONE_PT_deform(BoneButtonsPanel): __label__ = "Deform" @@ -307,6 +306,7 @@ class BONE_PT_iksolver_itasc(BoneButtonsPanel): def draw(self, context): layout = self.layout + ob = context.object itasc = ob.pose.ik_param diff --git a/release/ui/buttons_data_camera.py b/release/ui/buttons_data_camera.py index 0ac9a88eb35..19d7dfef852 100644 --- a/release/ui/buttons_data_camera.py +++ b/release/ui/buttons_data_camera.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.camera) + return context.camera class DATA_PT_context_camera(DataButtonsPanel): __show_header__ = False @@ -92,8 +92,7 @@ class DATA_PT_camera_display(DataButtonsPanel): sub = col.column() sub.active = cam.show_passepartout sub.itemR(cam, "passepartout_alpha", text="Alpha", slider=True) - - + bpy.types.register(DATA_PT_context_camera) bpy.types.register(DATA_PT_camera) bpy.types.register(DATA_PT_camera_display) diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py index 70904239d86..c715cfb5d93 100644 --- a/release/ui/buttons_data_curve.py +++ b/release/ui/buttons_data_curve.py @@ -120,7 +120,6 @@ class DATA_PT_geometry_curve(DataButtonsPanel): col.itemL(text="Bevel Object:") col.itemR(curve, "bevel_object", text="") - class DATA_PT_pathanim(DataButtonsPanelCurve): __label__ = "Path Animation" diff --git a/release/ui/buttons_data_lamp.py b/release/ui/buttons_data_lamp.py index 0dbda46bccf..86ca5beb9b5 100644 --- a/release/ui/buttons_data_lamp.py +++ b/release/ui/buttons_data_lamp.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.lamp) + return context.lamp class DATA_PT_preview(DataButtonsPanel): __label__ = "Preview" @@ -87,8 +87,7 @@ class DATA_PT_sunsky(DataButtonsPanel): lamp = context.lamp.sky layout.itemR(lamp, "sky") - - + row = layout.row() row.active = lamp.sky or lamp.atmosphere row.itemR(lamp, "atmosphere_turbidity", text="Turbidity") @@ -198,7 +197,7 @@ class DATA_PT_shadow(DataButtonsPanel): sub.itemR(lamp, "dither") sub.itemR(lamp, "jitter") - if lamp.shadow_method == 'BUFFER_SHADOW': + elif lamp.shadow_method == 'BUFFER_SHADOW': col = layout.column() col.itemL(text="Buffer Type:") col.row().itemR(lamp, "shadow_buffer_type", expand=True) @@ -258,8 +257,6 @@ class DATA_PT_area(DataButtonsPanel): elif (lamp.shape == 'RECTANGLE'): sub.itemR(lamp, "size", text="Size X") sub.itemR(lamp, "size_y", text="Size Y") - - col = split.column() class DATA_PT_spot(DataButtonsPanel): __label__ = "Spot Shape" diff --git a/release/ui/buttons_data_lattice.py b/release/ui/buttons_data_lattice.py index 895c1a65bea..bc977860330 100644 --- a/release/ui/buttons_data_lattice.py +++ b/release/ui/buttons_data_lattice.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.lattice) + return context.lattice class DATA_PT_context_lattice(DataButtonsPanel): __show_header__ = False diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py index a93d7b66397..780ae3ac8f9 100644 --- a/release/ui/buttons_data_mesh.py +++ b/release/ui/buttons_data_mesh.py @@ -7,7 +7,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.mesh) + return context.mesh class DATA_PT_context_mesh(DataButtonsPanel): __show_header__ = False diff --git a/release/ui/buttons_data_metaball.py b/release/ui/buttons_data_metaball.py index 88c0066c67f..757546fdf8a 100644 --- a/release/ui/buttons_data_metaball.py +++ b/release/ui/buttons_data_metaball.py @@ -6,7 +6,7 @@ class DataButtonsPanel(bpy.types.Panel): __context__ = "data" def poll(self, context): - return (context.meta_ball) + return context.meta_ball class DATA_PT_context_metaball(DataButtonsPanel): __show_header__ = False @@ -74,11 +74,9 @@ class DATA_PT_metaball_element(DataButtonsPanel): col.itemR(metaelem, "hide", text="Hide") if metaelem.type == 'BALL': - col = split.column(align=True) elif metaelem.type == 'CUBE': - col = split.column(align=True) col.itemL(text="Size:") col.itemR(metaelem, "size_x", text="X") @@ -86,26 +84,22 @@ class DATA_PT_metaball_element(DataButtonsPanel): col.itemR(metaelem, "size_z", text="Z") elif metaelem.type == 'TUBE': - col = split.column(align=True) col.itemL(text="Size:") col.itemR(metaelem, "size_x", text="X") elif metaelem.type == 'PLANE': - col = split.column(align=True) col.itemL(text="Size:") col.itemR(metaelem, "size_x", text="X") col.itemR(metaelem, "size_y", text="Y") elif metaelem.type == 'ELLIPSOID': - col = split.column(align=True) col.itemL(text="Size:") col.itemR(metaelem, "size_x", text="X") col.itemR(metaelem, "size_y", text="Y") col.itemR(metaelem, "size_z", text="Z") - bpy.types.register(DATA_PT_context_metaball) bpy.types.register(DATA_PT_metaball) diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py index 2959f60a5f5..0d46d5f8a0d 100644 --- a/release/ui/buttons_data_text.py +++ b/release/ui/buttons_data_text.py @@ -125,7 +125,6 @@ class DATA_PT_font(DataButtonsPanel): col.itemL(text="Underline:") col.itemR(text, "ul_position", text="Position") col.itemR(text, "ul_height", text="Thickness") - class DATA_PT_paragraph(DataButtonsPanel): __label__ = "Paragraph" @@ -151,7 +150,6 @@ class DATA_PT_paragraph(DataButtonsPanel): col.itemR(text, "offset_x", text="X") col.itemR(text, "offset_y", text="Y") - class DATA_PT_textboxes(DataButtonsPanel): __label__ = "Text Boxes" diff --git a/release/ui/buttons_game.py b/release/ui/buttons_game.py index f3461d3e370..5f5d4f916d0 100644 --- a/release/ui/buttons_game.py +++ b/release/ui/buttons_game.py @@ -26,7 +26,6 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel): #if game.physics_type == 'DYNAMIC': if game.physics_type in ('DYNAMIC', 'RIGID_BODY'): - split = layout.split() col = split.column() @@ -88,7 +87,6 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel): col.itemR(game, "lock_z_rot_axis", text="Z") elif game.physics_type == 'SOFT_BODY': - col = layout.column() col.itemR(game, "actor") col.itemR(game, "ghost") @@ -124,14 +122,12 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel): sub.itemR(soft, "cluster_iterations", text="Iterations") elif game.physics_type == 'STATIC': - col = layout.column() col.itemR(game, "actor") col.itemR(game, "ghost") col.itemR(ob, "restrict_render", text="Invisible") elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'): - layout.itemR(ob, "restrict_render", text="Invisible") class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel): diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py index 8b58c2b8953..448cb36e130 100644 --- a/release/ui/buttons_material.py +++ b/release/ui/buttons_material.py @@ -356,8 +356,8 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - sss = context.material.subsurface_scattering mat = context.material + sss = mat.subsurface_scattering self.layout.active = (not mat.shadeless) self.layout.itemR(sss, "enabled", text="") @@ -366,7 +366,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): layout = self.layout mat = context.material - sss = context.material.subsurface_scattering + sss = mat.subsurface_scattering layout.active = sss.enabled @@ -409,7 +409,7 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): layout = self.layout mat = context.material - raym = context.material.raytrace_mirror + raym = mat.raytrace_mirror layout.active = raym.enabled @@ -457,13 +457,14 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): def draw_header(self, context): mat = context.material + self.layout.itemR(mat, "transparency", text="") def draw(self, context): layout = self.layout mat = context.material - rayt = context.material.raytrace_transparency + rayt = mat.raytrace_transparency row = layout.row() row.active = mat.transparency and (not mat.shadeless) @@ -561,11 +562,9 @@ class MATERIAL_PT_flare(MaterialButtonsPanel): return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - layout = self.layout - - mat = context.material - halo = mat.halo - layout.itemR(halo, "flare_mode", text="") + halo = context.material.halo + + self.layout.itemR(halo, "flare_mode", text="") def draw(self, context): layout = self.layout @@ -619,7 +618,6 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material vol = context.material.volume row = layout.row() @@ -658,10 +656,10 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel): elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'): col.itemR(vol, "cache_resolution") - col = col.column(align=True) - col.itemR(vol, "ms_diffusion") - col.itemR(vol, "ms_spread") - col.itemR(vol, "ms_intensity") + sub = col.column(align=True) + sub.itemR(vol, "ms_diffusion") + sub.itemR(vol, "ms_spread") + sub.itemR(vol, "ms_intensity") col = split.column() # col.itemL(text="Anisotropic Scattering:") @@ -677,11 +675,8 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel): layout = self.layout mat = context.material - rayt = context.material.raytrace_transparency - row= layout.row() - row.itemR(mat, "transparency_method", expand=True) - row.active = mat.transparency and (not mat.shadeless) + layout.itemR(mat, "transparency_method", expand=True) class MATERIAL_PT_volume_integration(VolumeButtonsPanel): __label__ = "Integration" @@ -690,8 +685,7 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel): def draw(self, context): layout = self.layout - - mat = context.material + vol = context.material.volume split = layout.split() @@ -699,9 +693,9 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel): col = split.column() col.itemL(text="Step Calculation:") col.itemR(vol, "step_calculation", text="") - col = col.column(align=True) - col.itemR(vol, "step_size") - col.itemR(vol, "shading_step_size") + sub = col.column(align=True) + sub.itemR(vol, "step_size") + sub.itemR(vol, "shading_step_size") col = split.column() col.itemL() diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py index ca5c86fddd7..e089cff264f 100644 --- a/release/ui/buttons_object_constraint.py +++ b/release/ui/buttons_object_constraint.py @@ -68,8 +68,7 @@ class ConstraintButtonsPanel(bpy.types.Panel): col = split.column() col.itemR(con, "iterations") col.itemR(con, "chain_length") - - + def CHILD_OF(self, context, layout, con): self.target_template(layout, con) diff --git a/release/ui/buttons_physics_cloth.py b/release/ui/buttons_physics_cloth.py index 5cdca3c2c74..f6493951a34 100644 --- a/release/ui/buttons_physics_cloth.py +++ b/release/ui/buttons_physics_cloth.py @@ -89,7 +89,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.cloth) + return context.cloth def draw(self, context): md = context.cloth @@ -100,7 +100,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.cloth) + return context.cloth def draw_header(self, context): cloth = context.cloth.collision_settings @@ -135,7 +135,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.cloth != None) + return context.cloth def draw_header(self, context): cloth = context.cloth.settings diff --git a/release/ui/buttons_physics_field.py b/release/ui/buttons_physics_field.py index f6b50844fc8..7d14690856a 100644 --- a/release/ui/buttons_physics_field.py +++ b/release/ui/buttons_physics_field.py @@ -103,7 +103,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel): sub.itemR(field, "maximum_distance", text="Distance") if field.falloff_type == 'CONE': - layout.itemS() split = layout.split(percentage=0.35) @@ -125,7 +124,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel): sub.itemR(field, "radial_maximum", text="Angle") elif field.falloff_type == 'TUBE': - layout.itemS() split = layout.split(percentage=0.35) diff --git a/release/ui/buttons_physics_fluid.py b/release/ui/buttons_physics_fluid.py index 6f7a97ff793..e178a831ddd 100644 --- a/release/ui/buttons_physics_fluid.py +++ b/release/ui/buttons_physics_fluid.py @@ -174,8 +174,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel): def poll(self, context): md = context.fluid - if md: - return (md.settings.type == 'DOMAIN') + return md and (md.settings.type == 'DOMAIN') def draw(self, context): layout = self.layout @@ -213,8 +212,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel): def poll(self, context): md = context.fluid - if md: - return (md.settings.type == 'DOMAIN') + return md and (md.settings.type == 'DOMAIN') def draw(self, context): layout = self.layout @@ -242,8 +240,7 @@ class PHYSICS_PT_domain_particles(PhysicButtonsPanel): def poll(self, context): md = context.fluid - if md: - return (md.settings.type == 'DOMAIN') + return md and (md.settings.type == 'DOMAIN') def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py index 6aee152e92a..1541b0bae14 100644 --- a/release/ui/buttons_physics_smoke.py +++ b/release/ui/buttons_physics_smoke.py @@ -90,10 +90,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel): def poll(self, context): md = context.smoke - if md: - return (md.smoke_type == 'TYPE_DOMAIN') - - return False + return md and (md.smoke_type == 'TYPE_DOMAIN') def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_physics_softbody.py b/release/ui/buttons_physics_softbody.py index 703977a056f..3bdbb1b8b90 100644 --- a/release/ui/buttons_physics_softbody.py +++ b/release/ui/buttons_physics_softbody.py @@ -63,7 +63,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.soft_body) + return context.soft_body def draw(self, context): md = context.soft_body @@ -74,7 +74,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.soft_body) + return context.soft_body def draw_header(self, context): softbody = context.soft_body.settings @@ -115,7 +115,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.soft_body) + return context.soft_body def draw_header(self, context): softbody = context.soft_body.settings @@ -163,7 +163,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.soft_body) + return context.soft_body def draw_header(self, context): softbody = context.soft_body.settings @@ -194,7 +194,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.soft_body) + return context.soft_body def draw(self, context): layout = self.layout diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py index 6f283bb5d5b..8bb172e8cd1 100644 --- a/release/ui/buttons_scene.py +++ b/release/ui/buttons_scene.py @@ -452,7 +452,6 @@ class SCENE_PT_unit(RenderButtonsPanel): row.itemR(unit, "scale_length", text="Scale") row.itemR(unit, "use_separate") - bpy.types.register(SCENE_PT_render) bpy.types.register(SCENE_PT_layers) bpy.types.register(SCENE_PT_dimensions) diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py index c595e2b1cc2..c95fa266aaa 100644 --- a/release/ui/buttons_texture.py +++ b/release/ui/buttons_texture.py @@ -253,7 +253,6 @@ class TEXTURE_PT_influence(TextureSlotPanel): col.itemL(text=" ") factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color") factor_but(col, tex.map_colorabsorption, "map_colorabsorption", "colorabsorption_factor", "Absorption Color") - elif la: row = layout.row() @@ -617,9 +616,8 @@ class TEXTURE_PT_distortednoise(TextureTypePanel): flow.itemR(tex, "nabla") class TEXTURE_PT_voxeldata(TextureButtonsPanel): - __idname__= "TEXTURE_PT_voxeldata" __label__ = "Voxel Data" - + def poll(self, context): tex = context.texture return (tex and tex.type == 'VOXEL_DATA') @@ -647,9 +645,8 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel): layout.itemR(vd, "intensity") class TEXTURE_PT_pointdensity(TextureButtonsPanel): - __idname__= "TEXTURE_PT_pointdensity" __label__ = "Point Density" - + def poll(self, context): tex = context.texture return (tex and tex.type == 'POINT_DENSITY') diff --git a/release/ui/buttons_world.py b/release/ui/buttons_world.py index b02673d126f..3134c0ce46b 100644 --- a/release/ui/buttons_world.py +++ b/release/ui/buttons_world.py @@ -169,10 +169,9 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel): col.itemR(ao, "energy") col = split.column() - colsub = col.split(percentage=0.3) - colsub.itemL(text="Color:") - colsub.itemR(ao, "color", text="") - + sub = col.split(percentage=0.3) + sub.itemL(text="Color:") + sub.itemR(ao, "color", text="") bpy.types.register(WORLD_PT_context_world) bpy.types.register(WORLD_PT_preview) diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py index daae4a83ec4..a804998cdaa 100644 --- a/release/ui/space_sequencer.py +++ b/release/ui/space_sequencer.py @@ -555,11 +555,9 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel): return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META') def draw_header(self, context): - layout = self.layout - strip = act_strip(context) - layout.itemR(strip, "use_proxy", text="") + self.layout.itemR(strip, "use_proxy", text="") def draw(self, context): layout = self.layout diff --git a/release/ui/space_view3d_toolbar.py b/release/ui/space_view3d_toolbar.py index 239a727d2a2..4c1b54ea8e6 100644 --- a/release/ui/space_view3d_toolbar.py +++ b/release/ui/space_view3d_toolbar.py @@ -173,9 +173,7 @@ class VIEW3D_PT_tools_textedit(View3DPanel): def draw(self, context): layout = self.layout - - - + col = layout.column(align=True) col.itemL(text="Text Edit:") col.itemO("font.text_copy", text="Copy") @@ -201,9 +199,7 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel): def draw(self, context): layout = self.layout - - - + col = layout.column(align=True) col.itemL(text="Transform:") col.itemO("tfm.translate") @@ -366,7 +362,6 @@ class VIEW3D_PT_tools_brush(PaintPanel): col.itemR(brush, "strength", slider=True) if settings.tool == 'ADD': - col = layout.column() col.itemR(settings, "add_interpolate") sub = col.column(align=True) @@ -409,8 +404,6 @@ class VIEW3D_PT_tools_brush(PaintPanel): col.itemR(brush, "persistent") col.itemO("sculpt.set_persistent_base") - - # Texture Paint Mode # elif context.texture_paint_object and brush: @@ -625,10 +618,10 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel): def poll(self, context): return context.tool_settings.image_paint.tool != 'SMEAR' - def draw_header(self, context): - layout = self.layout - ipaint = context.tool_settings.image_paint - layout.itemR(ipaint, "use_projection", text="") + def draw_header(self, context): + ipaint = context.tool_settings.image_paint + + self.layout.itemR(ipaint, "use_projection", text="") def draw(self, context): layout = self.layout diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 0de19b22f3f..b8da42079c4 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -243,12 +243,12 @@ static void node_buts_rgb(uiLayout *layout, PointerRNA *ptr) } static void node_buts_mix_rgb(uiLayout *layout, PointerRNA *ptr) -{ - bNodeTree *ntree= (bNodeTree*)ptr->id.data; +{ uiLayout *row; - row= uiLayoutRow(layout, 1); + bNodeTree *ntree= (bNodeTree*)ptr->id.data; + row= uiLayoutRow(layout, 1); uiItemR(row, "", 0, ptr, "blend_type", 0); if(ntree->type == NTREE_COMPOSIT) uiItemR(row, "", ICON_IMAGE_RGB_ALPHA, ptr, "alpha", 0); @@ -1107,7 +1107,7 @@ static void node_blur_update_sizey_cb(bContext *C, void *node, void *poin2) } static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) { - uiLayout *row, *col; + uiLayout *col; col= uiLayoutColumn(layout, 0); @@ -1124,7 +1124,6 @@ static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) uiItemR(col, "X", 0, ptr, "factor_x", 0); uiItemR(col, "Y", 0, ptr, "factor_y", 0); } - else { uiItemR(col, "X", 0, ptr, "sizex", 0); uiItemR(col, "Y", 0, ptr, "sizey", 0); @@ -1133,7 +1132,7 @@ static void node_composit_buts_blur(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_dblur(uiLayout *layout, PointerRNA *ptr) { - uiLayout *row, *col; + uiLayout *col; uiItemR(layout, NULL, 0, ptr, "iterations", 0); uiItemR(layout, NULL, 0, ptr, "wrap", 0); -- cgit v1.2.3 From 0cbc87b42816711469cb63825ee826a837cc364a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 27 Sep 2009 16:20:42 +0000 Subject: Speed optimization in itasc when with armature with many bones and few targets. Thanks to Brecht who pointed out a simple but efficient optimization in SVD decomposition. --- intern/itasc/WDLSSolver.cpp | 26 +++++++++++++++++++++----- intern/itasc/WDLSSolver.hpp | 3 ++- intern/itasc/WSDLSSolver.cpp | 26 +++++++++++++++++++++----- intern/itasc/WSDLSSolver.hpp | 3 ++- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/intern/itasc/WDLSSolver.cpp b/intern/itasc/WDLSSolver.cpp index e8bfc95e5dd..1d0efde54c9 100644 --- a/intern/itasc/WDLSSolver.cpp +++ b/intern/itasc/WDLSSolver.cpp @@ -24,12 +24,22 @@ bool WDLSSolver::init(unsigned int nq, unsigned int nc, const std::vector& m_ns = std::min(nc,nq); m_AWq = e_zero_matrix(nc,nq); m_WyAWq = e_zero_matrix(nc,nq); - m_U = e_zero_matrix(nc,nq); + m_WyAWqt = e_zero_matrix(nq,nc); m_S = e_zero_vector(std::max(nc,nq)); - m_temp = e_zero_vector(nq); - m_V = e_zero_matrix(nq,nq); - m_WqV = e_zero_matrix(nq,nq); m_Wy_ydot = e_zero_vector(nc); + if (nq > nc) { + m_transpose = true; + m_temp = e_zero_vector(nc); + m_U = e_zero_matrix(nc,nc); + m_V = e_zero_matrix(nq,nc); + m_WqV = e_zero_matrix(nq,nc); + } else { + m_transpose = false; + m_temp = e_zero_vector(nq); + m_U = e_zero_matrix(nc,nq); + m_V = e_zero_matrix(nq,nq); + m_WqV = e_zero_matrix(nq,nq); + } return true; } @@ -42,7 +52,13 @@ bool WDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& yd m_WyAWq.row(i) = Wy(i)*m_AWq.row(i); // Compute the SVD of the weighted jacobian - int ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp); + int ret; + if (m_transpose) { + m_WyAWqt = m_WyAWq.transpose(); + ret = KDL::svd_eigen_HH(m_WyAWqt,m_V,m_S,m_U,m_temp); + } else { + ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp); + } if(ret<0) return false; diff --git a/intern/itasc/WDLSSolver.hpp b/intern/itasc/WDLSSolver.hpp index 4418e73675c..b56ad1ab2b8 100644 --- a/intern/itasc/WDLSSolver.hpp +++ b/intern/itasc/WDLSSolver.hpp @@ -14,12 +14,13 @@ namespace iTaSC { class WDLSSolver: public iTaSC::Solver { private: - e_matrix m_AWq,m_WyAWq,m_U,m_V,m_WqV; + e_matrix m_AWq,m_WyAWq,m_WyAWqt,m_U,m_V,m_WqV; e_vector m_S,m_temp,m_Wy_ydot; double m_lambda; double m_epsilon; double m_qmax; int m_ns; + bool m_transpose; public: WDLSSolver(); virtual ~WDLSSolver(); diff --git a/intern/itasc/WSDLSSolver.cpp b/intern/itasc/WSDLSSolver.cpp index 971fb7f482e..9f7ebed960a 100644 --- a/intern/itasc/WSDLSSolver.cpp +++ b/intern/itasc/WSDLSSolver.cpp @@ -31,13 +31,23 @@ bool WSDLSSolver::init(unsigned int _nq, unsigned int _nc, const std::vector m_nc) { + m_transpose = true; + m_temp = e_zero_vector(m_nc); + m_U = e_zero_matrix(m_nc,m_nc); + m_V = e_zero_matrix(m_nq,m_nc); + m_WqV = e_zero_matrix(m_nq,m_nc); + } else { + m_transpose = false; + m_temp = e_zero_vector(m_nq); + m_U = e_zero_matrix(m_nc,m_nq); + m_V = e_zero_matrix(m_nq,m_nq); + m_WqV = e_zero_matrix(m_nq,m_nq); + } return true; } @@ -52,7 +62,13 @@ bool WSDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& y m_WyAWq.row(i) = Wy(i)*m_AWq.row(i); // Compute the SVD of the weighted jacobian - int ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp); + int ret; + if (m_transpose) { + m_WyAWqt = m_WyAWq.transpose(); + ret = KDL::svd_eigen_HH(m_WyAWqt,m_V,m_S,m_U,m_temp); + } else { + ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp); + } if(ret<0) return false; diff --git a/intern/itasc/WSDLSSolver.hpp b/intern/itasc/WSDLSSolver.hpp index 1341cf2af66..0b17f26ef47 100644 --- a/intern/itasc/WSDLSSolver.hpp +++ b/intern/itasc/WSDLSSolver.hpp @@ -14,11 +14,12 @@ namespace iTaSC { class WSDLSSolver: public iTaSC::Solver { private: - e_matrix m_AWq,m_WyAWq,m_U,m_V,m_WqV; + e_matrix m_AWq,m_WyAWq,m_WyAWqt,m_U,m_V,m_WqV; e_vector m_S,m_temp,m_Wy_ydot; std::vector m_ytask; e_scalar m_qmax; unsigned int m_ns, m_nc, m_nq; + bool m_transpose; public: WSDLSSolver(); virtual ~WSDLSSolver(); -- cgit v1.2.3 From 2d797f35d804fd86ef079b30f2c83a81a8e38cd5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 28 Sep 2009 03:19:52 +0000 Subject: - removed 2.4x release/scripts - moved release/io and release/ui into release/scripts/io, ui - updated scons, cmake, make When porting 2.4x scripts back, use a command like this so as not to loose the commit history... svn cp https://svn.blender.org/svnroot/bf-blender/branches/blender2.4/release/scripts/raw_import.py release/scripts/io/import_raw.py --- SConstruct | 4 +- release/Makefile | 3 - release/io/engine_render_pov.py | 912 --- release/io/export_3ds.py | 1128 ---- release/io/export_fbx.py | 3457 ----------- release/io/export_obj.py | 993 ---- release/io/export_ply.py | 279 - release/io/export_x3d.py | 1239 ---- release/io/import_3ds.py | 1166 ---- release/io/import_obj.py | 1633 ----- release/io/netrender/__init__.py | 19 - release/io/netrender/balancing.py | 94 - release/io/netrender/client.py | 203 - release/io/netrender/master.py | 752 --- release/io/netrender/master_html.py | 142 - release/io/netrender/model.py | 198 - release/io/netrender/operators.py | 423 -- release/io/netrender/slave.py | 207 - release/io/netrender/ui.py | 321 - release/io/netrender/utils.py | 86 - release/scripts/3ds_export.py | 1019 ---- release/scripts/3ds_import.py | 1007 ---- release/scripts/Axiscopy.py | 125 - release/scripts/DirectX8Exporter.py | 1196 ---- release/scripts/DirectX8Importer.py | 238 - release/scripts/IDPropBrowser.py | 523 -- release/scripts/ac3d_export.py | 828 --- release/scripts/ac3d_import.py | 783 --- release/scripts/add_mesh_empty.py | 13 - release/scripts/add_mesh_torus.py | 69 - release/scripts/animation_bake_constraints.py | 792 --- release/scripts/animation_clean.py | 192 - release/scripts/animation_trajectory.py | 575 -- release/scripts/armature_symmetry.py | 325 - release/scripts/bevel_center.py | 474 -- release/scripts/blenderLipSynchro.py | 729 --- release/scripts/bpydata/KUlang.txt | 121 - release/scripts/bpydata/config/readme.txt | 6 - release/scripts/bpydata/readme.txt | 9 - release/scripts/bpymodules/BPyAddMesh.py | 159 - release/scripts/bpymodules/BPyArmature.py | 152 - release/scripts/bpymodules/BPyBlender.py | 36 - release/scripts/bpymodules/BPyCurve.py | 79 - release/scripts/bpymodules/BPyImage.py | 318 - release/scripts/bpymodules/BPyMathutils.py | 228 - release/scripts/bpymodules/BPyMesh.py | 1326 ----- release/scripts/bpymodules/BPyMesh_redux.py | 652 -- release/scripts/bpymodules/BPyMessages.py | 61 - release/scripts/bpymodules/BPyNMesh.py | 48 - release/scripts/bpymodules/BPyObject.py | 108 - release/scripts/bpymodules/BPyRegistry.py | 267 - release/scripts/bpymodules/BPyRender.py | 633 -- release/scripts/bpymodules/BPySys.py | 74 - release/scripts/bpymodules/BPyTextPlugin.py | 814 --- release/scripts/bpymodules/BPyWindow.py | 206 - release/scripts/bpymodules/blend2renderinfo.py | 95 - release/scripts/bpymodules/defaultdoodads.py | 941 --- release/scripts/bpymodules/dxfColorMap.py | 282 - release/scripts/bpymodules/dxfLibrary.py | 880 --- release/scripts/bpymodules/dxfReader.py | 381 -- release/scripts/bpymodules/mesh_gradient.py | 229 - release/scripts/bpymodules/meshtools.py | 355 -- release/scripts/bpymodules/paths_ai2obj.py | 506 -- release/scripts/bpymodules/paths_eps2obj.py | 452 -- release/scripts/bpymodules/paths_gimp2obj.py | 363 -- release/scripts/bpymodules/paths_svg2obj.py | 1651 ------ release/scripts/bvh_import.py | 757 --- release/scripts/c3d_import.py | 1244 ---- release/scripts/camera_changer.py | 121 - release/scripts/config.py | 801 --- release/scripts/console.py | 861 --- release/scripts/discombobulator.py | 1526 ----- release/scripts/envelope_symmetry.py | 174 - release/scripts/export-iv-0.1.py | 304 - release/scripts/export_dxf.py | 3041 ---------- release/scripts/export_fbx.py | 3084 ---------- release/scripts/export_lightwave_motion.py | 157 - release/scripts/export_m3g.py | 3074 ---------- release/scripts/export_map.py | 454 -- release/scripts/export_mdd.py | 168 - release/scripts/export_obj.py | 933 --- release/scripts/faceselect_same_weights.py | 111 - release/scripts/flt_defaultp.py | 1 - release/scripts/flt_dofedit.py | 835 --- release/scripts/flt_export.py | 1697 ------ release/scripts/flt_filewalker.py | 286 - release/scripts/flt_import.py | 2534 -------- release/scripts/flt_lodedit.py | 502 -- release/scripts/flt_palettemanager.py | 505 -- release/scripts/flt_properties.py | 630 -- release/scripts/flt_toolbar.py | 809 --- release/scripts/help_bpy_api.py | 47 - release/scripts/help_browser.py | 814 --- release/scripts/hotkeys.py | 944 --- release/scripts/image_2d_cutout.py | 559 -- release/scripts/image_auto_layout.py | 455 -- release/scripts/image_billboard.py | 269 - release/scripts/image_edit.py | 158 - release/scripts/import_dxf.py | 6225 -------------------- release/scripts/import_edl.py | 961 --- release/scripts/import_lightwave_motion.py | 244 - release/scripts/import_mdd.py | 158 - release/scripts/import_obj.py | 1234 ---- release/scripts/import_web3d.py | 2594 -------- release/scripts/io/engine_render_pov.py | 912 +++ release/scripts/io/export_3ds.py | 1128 ++++ release/scripts/io/export_fbx.py | 3457 +++++++++++ release/scripts/io/export_obj.py | 993 ++++ release/scripts/io/export_ply.py | 279 + release/scripts/io/export_x3d.py | 1239 ++++ release/scripts/io/import_3ds.py | 1166 ++++ release/scripts/io/import_obj.py | 1633 +++++ release/scripts/io/netrender/__init__.py | 19 + release/scripts/io/netrender/balancing.py | 94 + release/scripts/io/netrender/client.py | 203 + release/scripts/io/netrender/master.py | 752 +++ release/scripts/io/netrender/master_html.py | 142 + release/scripts/io/netrender/model.py | 198 + release/scripts/io/netrender/operators.py | 423 ++ release/scripts/io/netrender/slave.py | 207 + release/scripts/io/netrender/ui.py | 321 + release/scripts/io/netrender/utils.py | 86 + release/scripts/lightwave_export.py | 707 --- release/scripts/lightwave_import.py | 1705 ------ release/scripts/md2_export.py | 1271 ---- release/scripts/md2_import.py | 600 -- release/scripts/mesh_boneweight_copy.py | 287 - release/scripts/mesh_cleanup.py | 456 -- release/scripts/mesh_edges2curves.py | 166 - release/scripts/mesh_mirror_tool.py | 352 -- release/scripts/mesh_poly_reduce.py | 143 - release/scripts/mesh_poly_reduce_grid.py | 351 -- release/scripts/mesh_skin.py | 639 -- release/scripts/mesh_solidify.py | 345 -- release/scripts/mesh_unfolder.py | 1582 ----- release/scripts/mesh_wire.py | 290 - release/scripts/ms3d_import.py | 487 -- release/scripts/ms3d_import_ascii.py | 479 -- release/scripts/obdatacopier.py | 215 - release/scripts/object_active_to_other.py | 58 - release/scripts/object_apply_def.py | 178 - release/scripts/object_batch_name_edit.py | 274 - release/scripts/object_cookie_cutter.py | 667 --- release/scripts/object_drop.py | 253 - release/scripts/object_find.py | 222 - release/scripts/object_random_loc_sz_rot.py | 129 - release/scripts/object_sel2dupgroup.py | 84 - release/scripts/object_timeofs_follow_act.py | 107 - release/scripts/off_export.py | 106 - release/scripts/off_import.py | 177 - release/scripts/paths_import.py | 96 - release/scripts/ply_import.py | 354 -- release/scripts/raw_export.py | 100 - release/scripts/raw_import.py | 120 - release/scripts/renameobjectbyblock.py | 178 - release/scripts/render_save_layers.py | 120 - release/scripts/rvk1_torvk2.py | 341 -- release/scripts/save_theme.py | 143 - release/scripts/scripttemplate_background_job.py | 124 - release/scripts/scripttemplate_camera_object.py | 104 - release/scripts/scripttemplate_gamelogic.py | 97 - release/scripts/scripttemplate_gamelogic_basic.py | 33 - release/scripts/scripttemplate_gamelogic_module.py | 45 - release/scripts/scripttemplate_ipo_gen.py | 92 - release/scripts/scripttemplate_mesh_edit.py | 98 - release/scripts/scripttemplate_metaball_create.py | 76 - release/scripts/scripttemplate_object_edit.py | 81 - release/scripts/scripttemplate_pyconstraint.py | 114 - release/scripts/scripttemplate_text_plugin.py | 69 - release/scripts/slp_import.py | 116 - release/scripts/sysinfo.py | 287 - release/scripts/textplugin_convert_ge.py | 863 --- release/scripts/textplugin_functiondocs.py | 64 - release/scripts/textplugin_imports.py | 91 - release/scripts/textplugin_membersuggest.py | 90 - release/scripts/textplugin_outliner.py | 142 - release/scripts/textplugin_suggest.py | 94 - release/scripts/textplugin_templates.py | 123 - release/scripts/ui/bpy_ops.py | 141 + release/scripts/ui/buttons_data_armature.py | 186 + release/scripts/ui/buttons_data_bone.py | 353 ++ release/scripts/ui/buttons_data_camera.py | 98 + release/scripts/ui/buttons_data_curve.py | 227 + release/scripts/ui/buttons_data_empty.py | 23 + release/scripts/ui/buttons_data_lamp.py | 310 + release/scripts/ui/buttons_data_lattice.py | 56 + release/scripts/ui/buttons_data_mesh.py | 203 + release/scripts/ui/buttons_data_metaball.py | 106 + release/scripts/ui/buttons_data_modifier.py | 449 ++ release/scripts/ui/buttons_data_text.py | 179 + release/scripts/ui/buttons_game.py | 416 ++ release/scripts/ui/buttons_material.py | 708 +++ release/scripts/ui/buttons_object.py | 185 + release/scripts/ui/buttons_object_constraint.py | 561 ++ release/scripts/ui/buttons_particle.py | 961 +++ release/scripts/ui/buttons_physics_cloth.py | 172 + release/scripts/ui/buttons_physics_field.py | 226 + release/scripts/ui/buttons_physics_fluid.py | 257 + release/scripts/ui/buttons_physics_smoke.py | 179 + release/scripts/ui/buttons_physics_softbody.py | 231 + release/scripts/ui/buttons_scene.py | 465 ++ release/scripts/ui/buttons_texture.py | 758 +++ release/scripts/ui/buttons_world.py | 181 + release/scripts/ui/space_buttons.py | 36 + release/scripts/ui/space_console.py | 451 ++ release/scripts/ui/space_filebrowser.py | 42 + release/scripts/ui/space_image.py | 503 ++ release/scripts/ui/space_info.py | 292 + release/scripts/ui/space_logic.py | 29 + release/scripts/ui/space_node.py | 118 + release/scripts/ui/space_outliner.py | 52 + release/scripts/ui/space_sequencer.py | 600 ++ release/scripts/ui/space_text.py | 245 + release/scripts/ui/space_time.py | 151 + release/scripts/ui/space_userpref.py | 405 ++ release/scripts/ui/space_view3d.py | 1362 +++++ release/scripts/ui/space_view3d_toolbar.py | 746 +++ release/scripts/unweld.py | 247 - release/scripts/uv_export.py | 498 -- release/scripts/uv_seams_from_islands.py | 101 - release/scripts/uvcalc_follow_active_coords.py | 254 - release/scripts/uvcalc_lightmap.py | 599 -- release/scripts/uvcalc_quad_clickproj.py | 271 - release/scripts/uvcalc_smart_project.py | 1132 ---- release/scripts/uvcopy.py | 112 - release/scripts/vertexpaint_from_material.py | 99 - release/scripts/vertexpaint_gradient.py | 46 - release/scripts/vertexpaint_selfshadow_ao.py | 186 - release/scripts/vrml97_export.py | 1300 ---- release/scripts/weightpaint_average.py | 121 - release/scripts/weightpaint_clean.py | 121 - release/scripts/weightpaint_copy.py | 101 - release/scripts/weightpaint_envelope_assign.py | 240 - release/scripts/weightpaint_gradient.py | 59 - release/scripts/weightpaint_grow_shrink.py | 131 - release/scripts/weightpaint_invert.py | 95 - release/scripts/weightpaint_normalize.py | 170 - release/scripts/widgetwizard.py | 917 --- release/scripts/wizard_bolt_factory.py | 2811 --------- release/scripts/wizard_curve2tree.py | 4048 ------------- release/scripts/wizard_landscape_ant.py | 2148 ------- release/scripts/x3d_export.py | 1051 ---- release/scripts/xsi_export.py | 1227 ---- release/ui/bpy_ops.py | 141 - release/ui/buttons_data_armature.py | 186 - release/ui/buttons_data_bone.py | 353 -- release/ui/buttons_data_camera.py | 98 - release/ui/buttons_data_curve.py | 227 - release/ui/buttons_data_empty.py | 23 - release/ui/buttons_data_lamp.py | 310 - release/ui/buttons_data_lattice.py | 56 - release/ui/buttons_data_mesh.py | 203 - release/ui/buttons_data_metaball.py | 106 - release/ui/buttons_data_modifier.py | 449 -- release/ui/buttons_data_text.py | 179 - release/ui/buttons_game.py | 416 -- release/ui/buttons_material.py | 708 --- release/ui/buttons_object.py | 185 - release/ui/buttons_object_constraint.py | 561 -- release/ui/buttons_particle.py | 961 --- release/ui/buttons_physics_cloth.py | 172 - release/ui/buttons_physics_field.py | 226 - release/ui/buttons_physics_fluid.py | 257 - release/ui/buttons_physics_smoke.py | 179 - release/ui/buttons_physics_softbody.py | 231 - release/ui/buttons_scene.py | 465 -- release/ui/buttons_texture.py | 758 --- release/ui/buttons_world.py | 181 - release/ui/space_buttons.py | 36 - release/ui/space_console.py | 451 -- release/ui/space_filebrowser.py | 42 - release/ui/space_image.py | 503 -- release/ui/space_info.py | 292 - release/ui/space_logic.py | 29 - release/ui/space_node.py | 118 - release/ui/space_outliner.py | 52 - release/ui/space_sequencer.py | 600 -- release/ui/space_text.py | 245 - release/ui/space_time.py | 151 - release/ui/space_userpref.py | 405 -- release/ui/space_view3d.py | 1362 ----- release/ui/space_view3d_toolbar.py | 746 --- source/blender/blenloader/BLO_readfile.h | 2 +- source/blender/python/intern/bpy_interface.c | 2 +- source/creator/CMakeLists.txt | 11 +- source/darwin/Makefile | 2 - 286 files changed, 25922 insertions(+), 120193 deletions(-) delete mode 100644 release/io/engine_render_pov.py delete mode 100644 release/io/export_3ds.py delete mode 100644 release/io/export_fbx.py delete mode 100644 release/io/export_obj.py delete mode 100644 release/io/export_ply.py delete mode 100644 release/io/export_x3d.py delete mode 100644 release/io/import_3ds.py delete mode 100644 release/io/import_obj.py delete mode 100644 release/io/netrender/__init__.py delete mode 100644 release/io/netrender/balancing.py delete mode 100644 release/io/netrender/client.py delete mode 100644 release/io/netrender/master.py delete mode 100644 release/io/netrender/master_html.py delete mode 100644 release/io/netrender/model.py delete mode 100644 release/io/netrender/operators.py delete mode 100644 release/io/netrender/slave.py delete mode 100644 release/io/netrender/ui.py delete mode 100644 release/io/netrender/utils.py delete mode 100644 release/scripts/3ds_export.py delete mode 100644 release/scripts/3ds_import.py delete mode 100644 release/scripts/Axiscopy.py delete mode 100644 release/scripts/DirectX8Exporter.py delete mode 100644 release/scripts/DirectX8Importer.py delete mode 100644 release/scripts/IDPropBrowser.py delete mode 100644 release/scripts/ac3d_export.py delete mode 100644 release/scripts/ac3d_import.py delete mode 100644 release/scripts/add_mesh_empty.py delete mode 100644 release/scripts/add_mesh_torus.py delete mode 100644 release/scripts/animation_bake_constraints.py delete mode 100644 release/scripts/animation_clean.py delete mode 100644 release/scripts/animation_trajectory.py delete mode 100644 release/scripts/armature_symmetry.py delete mode 100644 release/scripts/bevel_center.py delete mode 100644 release/scripts/blenderLipSynchro.py delete mode 100644 release/scripts/bpydata/KUlang.txt delete mode 100644 release/scripts/bpydata/config/readme.txt delete mode 100644 release/scripts/bpydata/readme.txt delete mode 100644 release/scripts/bpymodules/BPyAddMesh.py delete mode 100644 release/scripts/bpymodules/BPyArmature.py delete mode 100644 release/scripts/bpymodules/BPyBlender.py delete mode 100644 release/scripts/bpymodules/BPyCurve.py delete mode 100644 release/scripts/bpymodules/BPyImage.py delete mode 100644 release/scripts/bpymodules/BPyMathutils.py delete mode 100644 release/scripts/bpymodules/BPyMesh.py delete mode 100644 release/scripts/bpymodules/BPyMesh_redux.py delete mode 100644 release/scripts/bpymodules/BPyMessages.py delete mode 100644 release/scripts/bpymodules/BPyNMesh.py delete mode 100644 release/scripts/bpymodules/BPyObject.py delete mode 100644 release/scripts/bpymodules/BPyRegistry.py delete mode 100644 release/scripts/bpymodules/BPyRender.py delete mode 100644 release/scripts/bpymodules/BPySys.py delete mode 100644 release/scripts/bpymodules/BPyTextPlugin.py delete mode 100644 release/scripts/bpymodules/BPyWindow.py delete mode 100644 release/scripts/bpymodules/blend2renderinfo.py delete mode 100644 release/scripts/bpymodules/defaultdoodads.py delete mode 100644 release/scripts/bpymodules/dxfColorMap.py delete mode 100644 release/scripts/bpymodules/dxfLibrary.py delete mode 100644 release/scripts/bpymodules/dxfReader.py delete mode 100644 release/scripts/bpymodules/mesh_gradient.py delete mode 100644 release/scripts/bpymodules/meshtools.py delete mode 100644 release/scripts/bpymodules/paths_ai2obj.py delete mode 100644 release/scripts/bpymodules/paths_eps2obj.py delete mode 100644 release/scripts/bpymodules/paths_gimp2obj.py delete mode 100644 release/scripts/bpymodules/paths_svg2obj.py delete mode 100644 release/scripts/bvh_import.py delete mode 100644 release/scripts/c3d_import.py delete mode 100644 release/scripts/camera_changer.py delete mode 100644 release/scripts/config.py delete mode 100644 release/scripts/console.py delete mode 100644 release/scripts/discombobulator.py delete mode 100644 release/scripts/envelope_symmetry.py delete mode 100644 release/scripts/export-iv-0.1.py delete mode 100644 release/scripts/export_dxf.py delete mode 100644 release/scripts/export_fbx.py delete mode 100644 release/scripts/export_lightwave_motion.py delete mode 100644 release/scripts/export_m3g.py delete mode 100644 release/scripts/export_map.py delete mode 100644 release/scripts/export_mdd.py delete mode 100644 release/scripts/export_obj.py delete mode 100644 release/scripts/faceselect_same_weights.py delete mode 100644 release/scripts/flt_defaultp.py delete mode 100644 release/scripts/flt_dofedit.py delete mode 100644 release/scripts/flt_export.py delete mode 100644 release/scripts/flt_filewalker.py delete mode 100644 release/scripts/flt_import.py delete mode 100644 release/scripts/flt_lodedit.py delete mode 100644 release/scripts/flt_palettemanager.py delete mode 100644 release/scripts/flt_properties.py delete mode 100644 release/scripts/flt_toolbar.py delete mode 100644 release/scripts/help_bpy_api.py delete mode 100644 release/scripts/help_browser.py delete mode 100644 release/scripts/hotkeys.py delete mode 100644 release/scripts/image_2d_cutout.py delete mode 100644 release/scripts/image_auto_layout.py delete mode 100644 release/scripts/image_billboard.py delete mode 100644 release/scripts/image_edit.py delete mode 100644 release/scripts/import_dxf.py delete mode 100644 release/scripts/import_edl.py delete mode 100644 release/scripts/import_lightwave_motion.py delete mode 100644 release/scripts/import_mdd.py delete mode 100644 release/scripts/import_obj.py delete mode 100644 release/scripts/import_web3d.py create mode 100644 release/scripts/io/engine_render_pov.py create mode 100644 release/scripts/io/export_3ds.py create mode 100644 release/scripts/io/export_fbx.py create mode 100644 release/scripts/io/export_obj.py create mode 100644 release/scripts/io/export_ply.py create mode 100644 release/scripts/io/export_x3d.py create mode 100644 release/scripts/io/import_3ds.py create mode 100644 release/scripts/io/import_obj.py create mode 100644 release/scripts/io/netrender/__init__.py create mode 100644 release/scripts/io/netrender/balancing.py create mode 100644 release/scripts/io/netrender/client.py create mode 100644 release/scripts/io/netrender/master.py create mode 100644 release/scripts/io/netrender/master_html.py create mode 100644 release/scripts/io/netrender/model.py create mode 100644 release/scripts/io/netrender/operators.py create mode 100644 release/scripts/io/netrender/slave.py create mode 100644 release/scripts/io/netrender/ui.py create mode 100644 release/scripts/io/netrender/utils.py delete mode 100644 release/scripts/lightwave_export.py delete mode 100644 release/scripts/lightwave_import.py delete mode 100644 release/scripts/md2_export.py delete mode 100644 release/scripts/md2_import.py delete mode 100644 release/scripts/mesh_boneweight_copy.py delete mode 100644 release/scripts/mesh_cleanup.py delete mode 100644 release/scripts/mesh_edges2curves.py delete mode 100644 release/scripts/mesh_mirror_tool.py delete mode 100644 release/scripts/mesh_poly_reduce.py delete mode 100644 release/scripts/mesh_poly_reduce_grid.py delete mode 100644 release/scripts/mesh_skin.py delete mode 100644 release/scripts/mesh_solidify.py delete mode 100644 release/scripts/mesh_unfolder.py delete mode 100644 release/scripts/mesh_wire.py delete mode 100644 release/scripts/ms3d_import.py delete mode 100644 release/scripts/ms3d_import_ascii.py delete mode 100644 release/scripts/obdatacopier.py delete mode 100644 release/scripts/object_active_to_other.py delete mode 100644 release/scripts/object_apply_def.py delete mode 100644 release/scripts/object_batch_name_edit.py delete mode 100644 release/scripts/object_cookie_cutter.py delete mode 100644 release/scripts/object_drop.py delete mode 100644 release/scripts/object_find.py delete mode 100644 release/scripts/object_random_loc_sz_rot.py delete mode 100644 release/scripts/object_sel2dupgroup.py delete mode 100644 release/scripts/object_timeofs_follow_act.py delete mode 100644 release/scripts/off_export.py delete mode 100644 release/scripts/off_import.py delete mode 100644 release/scripts/paths_import.py delete mode 100644 release/scripts/ply_import.py delete mode 100644 release/scripts/raw_export.py delete mode 100644 release/scripts/raw_import.py delete mode 100644 release/scripts/renameobjectbyblock.py delete mode 100644 release/scripts/render_save_layers.py delete mode 100644 release/scripts/rvk1_torvk2.py delete mode 100644 release/scripts/save_theme.py delete mode 100644 release/scripts/scripttemplate_background_job.py delete mode 100644 release/scripts/scripttemplate_camera_object.py delete mode 100644 release/scripts/scripttemplate_gamelogic.py delete mode 100644 release/scripts/scripttemplate_gamelogic_basic.py delete mode 100644 release/scripts/scripttemplate_gamelogic_module.py delete mode 100644 release/scripts/scripttemplate_ipo_gen.py delete mode 100644 release/scripts/scripttemplate_mesh_edit.py delete mode 100644 release/scripts/scripttemplate_metaball_create.py delete mode 100644 release/scripts/scripttemplate_object_edit.py delete mode 100644 release/scripts/scripttemplate_pyconstraint.py delete mode 100644 release/scripts/scripttemplate_text_plugin.py delete mode 100644 release/scripts/slp_import.py delete mode 100644 release/scripts/sysinfo.py delete mode 100644 release/scripts/textplugin_convert_ge.py delete mode 100644 release/scripts/textplugin_functiondocs.py delete mode 100644 release/scripts/textplugin_imports.py delete mode 100644 release/scripts/textplugin_membersuggest.py delete mode 100644 release/scripts/textplugin_outliner.py delete mode 100644 release/scripts/textplugin_suggest.py delete mode 100644 release/scripts/textplugin_templates.py create mode 100644 release/scripts/ui/bpy_ops.py create mode 100644 release/scripts/ui/buttons_data_armature.py create mode 100644 release/scripts/ui/buttons_data_bone.py create mode 100644 release/scripts/ui/buttons_data_camera.py create mode 100644 release/scripts/ui/buttons_data_curve.py create mode 100644 release/scripts/ui/buttons_data_empty.py create mode 100644 release/scripts/ui/buttons_data_lamp.py create mode 100644 release/scripts/ui/buttons_data_lattice.py create mode 100644 release/scripts/ui/buttons_data_mesh.py create mode 100644 release/scripts/ui/buttons_data_metaball.py create mode 100644 release/scripts/ui/buttons_data_modifier.py create mode 100644 release/scripts/ui/buttons_data_text.py create mode 100644 release/scripts/ui/buttons_game.py create mode 100644 release/scripts/ui/buttons_material.py create mode 100644 release/scripts/ui/buttons_object.py create mode 100644 release/scripts/ui/buttons_object_constraint.py create mode 100644 release/scripts/ui/buttons_particle.py create mode 100644 release/scripts/ui/buttons_physics_cloth.py create mode 100644 release/scripts/ui/buttons_physics_field.py create mode 100644 release/scripts/ui/buttons_physics_fluid.py create mode 100644 release/scripts/ui/buttons_physics_smoke.py create mode 100644 release/scripts/ui/buttons_physics_softbody.py create mode 100644 release/scripts/ui/buttons_scene.py create mode 100644 release/scripts/ui/buttons_texture.py create mode 100644 release/scripts/ui/buttons_world.py create mode 100644 release/scripts/ui/space_buttons.py create mode 100644 release/scripts/ui/space_console.py create mode 100644 release/scripts/ui/space_filebrowser.py create mode 100644 release/scripts/ui/space_image.py create mode 100644 release/scripts/ui/space_info.py create mode 100644 release/scripts/ui/space_logic.py create mode 100644 release/scripts/ui/space_node.py create mode 100644 release/scripts/ui/space_outliner.py create mode 100644 release/scripts/ui/space_sequencer.py create mode 100644 release/scripts/ui/space_text.py create mode 100644 release/scripts/ui/space_time.py create mode 100644 release/scripts/ui/space_userpref.py create mode 100644 release/scripts/ui/space_view3d.py create mode 100644 release/scripts/ui/space_view3d_toolbar.py delete mode 100644 release/scripts/unweld.py delete mode 100644 release/scripts/uv_export.py delete mode 100644 release/scripts/uv_seams_from_islands.py delete mode 100644 release/scripts/uvcalc_follow_active_coords.py delete mode 100644 release/scripts/uvcalc_lightmap.py delete mode 100644 release/scripts/uvcalc_quad_clickproj.py delete mode 100644 release/scripts/uvcalc_smart_project.py delete mode 100644 release/scripts/uvcopy.py delete mode 100644 release/scripts/vertexpaint_from_material.py delete mode 100644 release/scripts/vertexpaint_gradient.py delete mode 100644 release/scripts/vertexpaint_selfshadow_ao.py delete mode 100644 release/scripts/vrml97_export.py delete mode 100644 release/scripts/weightpaint_average.py delete mode 100644 release/scripts/weightpaint_clean.py delete mode 100644 release/scripts/weightpaint_copy.py delete mode 100644 release/scripts/weightpaint_envelope_assign.py delete mode 100644 release/scripts/weightpaint_gradient.py delete mode 100644 release/scripts/weightpaint_grow_shrink.py delete mode 100644 release/scripts/weightpaint_invert.py delete mode 100644 release/scripts/weightpaint_normalize.py delete mode 100644 release/scripts/widgetwizard.py delete mode 100644 release/scripts/wizard_bolt_factory.py delete mode 100644 release/scripts/wizard_curve2tree.py delete mode 100644 release/scripts/wizard_landscape_ant.py delete mode 100644 release/scripts/x3d_export.py delete mode 100644 release/scripts/xsi_export.py delete mode 100644 release/ui/bpy_ops.py delete mode 100644 release/ui/buttons_data_armature.py delete mode 100644 release/ui/buttons_data_bone.py delete mode 100644 release/ui/buttons_data_camera.py delete mode 100644 release/ui/buttons_data_curve.py delete mode 100644 release/ui/buttons_data_empty.py delete mode 100644 release/ui/buttons_data_lamp.py delete mode 100644 release/ui/buttons_data_lattice.py delete mode 100644 release/ui/buttons_data_mesh.py delete mode 100644 release/ui/buttons_data_metaball.py delete mode 100644 release/ui/buttons_data_modifier.py delete mode 100644 release/ui/buttons_data_text.py delete mode 100644 release/ui/buttons_game.py delete mode 100644 release/ui/buttons_material.py delete mode 100644 release/ui/buttons_object.py delete mode 100644 release/ui/buttons_object_constraint.py delete mode 100644 release/ui/buttons_particle.py delete mode 100644 release/ui/buttons_physics_cloth.py delete mode 100644 release/ui/buttons_physics_field.py delete mode 100644 release/ui/buttons_physics_fluid.py delete mode 100644 release/ui/buttons_physics_smoke.py delete mode 100644 release/ui/buttons_physics_softbody.py delete mode 100644 release/ui/buttons_scene.py delete mode 100644 release/ui/buttons_texture.py delete mode 100644 release/ui/buttons_world.py delete mode 100644 release/ui/space_buttons.py delete mode 100644 release/ui/space_console.py delete mode 100644 release/ui/space_filebrowser.py delete mode 100644 release/ui/space_image.py delete mode 100644 release/ui/space_info.py delete mode 100644 release/ui/space_logic.py delete mode 100644 release/ui/space_node.py delete mode 100644 release/ui/space_outliner.py delete mode 100644 release/ui/space_sequencer.py delete mode 100644 release/ui/space_text.py delete mode 100644 release/ui/space_time.py delete mode 100644 release/ui/space_userpref.py delete mode 100644 release/ui/space_view3d.py delete mode 100644 release/ui/space_view3d_toolbar.py diff --git a/SConstruct b/SConstruct index 7e3d23970cb..5c4af916327 100644 --- a/SConstruct +++ b/SConstruct @@ -476,8 +476,8 @@ if env['OURPLATFORM']!='darwin': dotblenderinstall.append(env.Install(dir=td, source=srcfile)) if env['WITH_BF_PYTHON']: - #-- .blender/scripts, .blender/ui, .blender/io - scriptpaths=['release/scripts', 'release/ui', 'release/io'] + #-- .blender/scripts + scriptpaths=['release/scripts'] for scriptpath in scriptpaths: for dp, dn, df in os.walk(scriptpath): if '.svn' in dn: diff --git a/release/Makefile b/release/Makefile index 94bb902646d..9fe83ef3494 100644 --- a/release/Makefile +++ b/release/Makefile @@ -153,9 +153,6 @@ endif @echo "----> Copy python infrastructure" @[ ! -d scripts ] || cp -r scripts $(CONFDIR)/scripts - - @echo "----> Copy python UI files" - @[ ! -d ui ] || cp -r ui $(CONFDIR)/ui ifeq ($(OS),darwin) @echo "----> Copy python modules" diff --git a/release/io/engine_render_pov.py b/release/io/engine_render_pov.py deleted file mode 100644 index f0247ce532a..00000000000 --- a/release/io/engine_render_pov.py +++ /dev/null @@ -1,912 +0,0 @@ -import bpy - -from math import atan, pi, degrees -import subprocess -import os -import sys -import time - -import platform as pltfrm - -if pltfrm.architecture()[0] == '64bit': - bitness = 64 -else: - bitness = 32 - -def write_pov(filename, scene=None, info_callback = None): - file = open(filename, 'w') - - # Only for testing - if not scene: - scene = bpy.data.scenes[0] - - render = scene.render_data - world = scene.world - - # --- taken from fbx exporter - ## This was used to make V, but faster not to do all that - ##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' - ##v = range(255) - ##for c in valid: v.remove(ord(c)) - v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,46,47,58,59,60,61,62,63,64,92,94,96,124,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] - invalid = ''.join([chr(i) for i in v]) - def cleanName(name): - for ch in invalid: name = name.replace(ch, '_') - return name - del v - - # --- done with clean name. - - def uniqueName(name, nameSeq): - - if name not in nameSeq: - return name - - name_orig = name - i = 1 - while name in nameSeq: - name = '%s_%.3d' % (name_orig, i) - i+=1 - - return name - - - def writeMatrix(matrix): - file.write('\tmatrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n' %\ - (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2]) ) - - def writeObjectMaterial(material): - if material and material.transparency_method=='RAYTRACE': - file.write('\tinterior { ior %.6f }\n' % material.raytrace_transparency.ior) - - # Other interior args - # fade_distance 2 - # fade_power [Value] - # fade_color - - # dispersion - # dispersion_samples - - materialNames = {} - DEF_MAT_NAME = 'Default' - def writeMaterial(material): - # Assumes only called once on each material - - if material: - name_orig = material.name - else: - name_orig = DEF_MAT_NAME - - name = materialNames[name_orig] = uniqueName(cleanName(name_orig), materialNames) - - file.write('#declare %s = finish {\n' % name) - - if material: - file.write('\tdiffuse %.3g\n' % material.diffuse_intensity) - file.write('\tspecular %.3g\n' % material.specular_intensity) - - file.write('\tambient %.3g\n' % material.ambient) - #file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value - - # map hardness between 0.0 and 1.0 - roughness = ((1.0 - ((material.specular_hardness-1.0)/510.0))) - # scale from 0.0 to 0.1 - roughness *= 0.1 - # add a small value because 0.0 is invalid - roughness += (1/511.0) - - file.write('\troughness %.3g\n' % roughness) - - # 'phong 70.0 ' - - if material.raytrace_mirror.enabled: - raytrace_mirror= material.raytrace_mirror - if raytrace_mirror.reflect_factor: - file.write('\treflection {\n') - file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color)) - file.write('\t\tfresnel 1 falloff %.3g exponent %.3g metallic %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor, raytrace_mirror.reflect_factor)) - - else: - file.write('\tdiffuse 0.8\n') - file.write('\tspecular 0.2\n') - - - # This is written into the object - ''' - if material and material.transparency_method=='RAYTRACE': - 'interior { ior %.3g} ' % material.raytrace_transparency.ior - ''' - - #file.write('\t\t\tcrand 1.0\n') # Sand granyness - #file.write('\t\t\tmetallic %.6f\n' % material.spec) - #file.write('\t\t\tphong %.6f\n' % material.spec) - #file.write('\t\t\tphong_size %.6f\n' % material.spec) - #file.write('\t\t\tbrilliance %.6f ' % (material.specular_hardness/256.0) # Like hardness - - file.write('}\n') - - def exportCamera(): - camera = scene.camera - matrix = camera.matrix - - # compute resolution - Qsize=float(render.resolution_x)/float(render.resolution_y) - - file.write('camera {\n') - file.write('\tlocation <0, 0, 0>\n') - file.write('\tlook_at <0, 0, -1>\n') - file.write('\tright <%s, 0, 0>\n' % -Qsize) - file.write('\tup <0, 1, 0>\n') - file.write('\tangle %f \n' % (360.0*atan(16.0/camera.data.lens)/pi)) - - file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotationPart().toEuler()])) - file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2])) - file.write('}\n') - - def exportLamps(lamps): - # Get all lamps - for ob in lamps: - lamp = ob.data - - matrix = ob.matrix - - color = tuple([c * lamp.energy for c in lamp.color]) # Colour is modified by energy - - file.write('light_source {\n') - file.write('\t< 0,0,0 >\n') - file.write('\tcolor rgb<%.3g, %.3g, %.3g>\n' % color) - - if lamp.type == 'POINT': # Point Lamp - pass - elif lamp.type == 'SPOT': # Spot - file.write('\tspotlight\n') - - # Falloff is the main radius from the centre line - file.write('\tfalloff %.2f\n' % (lamp.spot_size/2.0) ) # 1 TO 179 FOR BOTH - file.write('\tradius %.6f\n' % ((lamp.spot_size/2.0) * (1-lamp.spot_blend)) ) - - # Blender does not have a tightness equivilent, 0 is most like blender default. - file.write('\ttightness 0\n') # 0:10f - - file.write('\tpoint_at <0, 0, -1>\n') - elif lamp.type == 'SUN': - file.write('\tparallel\n') - file.write('\tpoint_at <0, 0, -1>\n') # *must* be after 'parallel' - - elif lamp.type == 'AREA': - - size_x = lamp.size - samples_x = lamp.shadow_ray_samples_x - if lamp.shape == 'SQUARE': - size_y = size_x - samples_y = samples_x - else: - size_y = lamp.size_y - samples_y = lamp.shadow_ray_samples_y - - file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y)) - if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED': - if lamp.jitter: - file.write('\tjitter\n') - else: - file.write('\tadaptive 1\n') - file.write('\tjitter\n') - - if lamp.shadow_method == 'NOSHADOW': - file.write('\tshadowless\n') - - file.write('\tfade_distance %.6f\n' % lamp.distance) - file.write('\tfade_power %d\n' % 1) # Could use blenders lamp quad? - writeMatrix(matrix) - - file.write('}\n') - - def exportMeta(metas): - - # TODO - blenders 'motherball' naming is not supported. - - for ob in metas: - meta = ob.data - - file.write('blob {\n') - file.write('\t\tthreshold %.4g\n' % meta.threshold) - - try: - material= meta.materials[0] # lame! - blender cant do enything else. - except: - material= None - - for elem in meta.elements: - - if elem.type not in ('BALL', 'ELLIPSOID'): - continue # Not supported - - loc = elem.location - - stiffness= elem.stiffness - if elem.negative: - stiffness = -stiffness - - if elem.type == 'BALL': - - file.write('\tsphere { <%.6g, %.6g, %.6g>, %.4g, %.4g ' % (loc.x, loc.y, loc.z, elem.radius, stiffness)) - - # After this wecould do something simple like... - # "pigment {Blue} }" - # except we'll write the color - - elif elem.type == 'ELLIPSOID': - # location is modified by scale - file.write('\tsphere { <%.6g, %.6g, %.6g>, %.4g, %.4g ' % (loc.x/elem.size_x, loc.y/elem.size_y, loc.z/elem.size_z, elem.radius, stiffness)) - file.write( 'scale <%.6g, %.6g, %.6g> ' % (elem.size_x, elem.size_y, elem.size_z)) - - if material: - diffuse_color = material.diffuse_color - - if material.transparency and material.transparency_method=='RAYTRACE': trans = 1-material.raytrace_transparency.filter - else: trans = 0.0 - - file.write( - 'pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s} }\n' % \ - (diffuse_color[0], diffuse_color[1], diffuse_color[2], 1-material.alpha, trans, materialNames[material.name]) - ) - - else: - file.write('pigment {rgb<1 1 1>} finish {%s} }\n' % DEF_MAT_NAME) # Write the finish last. - - writeObjectMaterial(material) - - writeMatrix(ob.matrix) - - file.write('}\n') - - def exportMeshs(sel): - - ob_num = 0 - - for ob in sel: - ob_num+= 1 - - if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META'): - continue - - me = ob.data - me_materials= me.materials - - me = ob.create_mesh(True, 'RENDER') - - if not me: - continue - - if info_callback: - info_callback('Object %2.d of %2.d (%s)' % (ob_num, len(sel), ob.name)) - - #if ob.type!='MESH': - # continue - # me = ob.data - - matrix = ob.matrix - try: uv_layer = me.active_uv_texture.data - except:uv_layer = None - - try: vcol_layer = me.active_vertex_color.data - except:vcol_layer = None - - faces_verts = [f.verts for f in me.faces] - faces_normals = [tuple(f.normal) for f in me.faces] - verts_normals = [tuple(v.normal) for v in me.verts] - - # quads incur an extra face - quadCount = len([f for f in faces_verts if len(f)==4]) - - file.write('mesh2 {\n') - file.write('\tvertex_vectors {\n') - file.write('\t\t%s' % (len(me.verts))) # vert count - for v in me.verts: - file.write(',\n\t\t<%.6f, %.6f, %.6f>' % tuple(v.co)) # vert count - file.write('\n }\n') - - - # Build unique Normal list - uniqueNormals = {} - for fi, f in enumerate(me.faces): - fv = faces_verts[fi] - # [-1] is a dummy index, use a list so we can modify in place - if f.smooth: # Use vertex normals - for v in fv: - key = verts_normals[v] - uniqueNormals[key] = [-1] - else: # Use face normal - key = faces_normals[fi] - uniqueNormals[key] = [-1] - - file.write('\tnormal_vectors {\n') - file.write('\t\t%d' % len(uniqueNormals)) # vert count - idx = 0 - for no, index in uniqueNormals.items(): - file.write(',\n\t\t<%.6f, %.6f, %.6f>' % no) # vert count - index[0] = idx - idx +=1 - file.write('\n }\n') - - - # Vertex colours - vertCols = {} # Use for material colours also. - - if uv_layer: - # Generate unique UV's - uniqueUVs = {} - - for fi, uv in enumerate(uv_layer): - - if len(faces_verts[fi])==4: - uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4 - else: - uvs = uv.uv1, uv.uv2, uv.uv3 - - for uv in uvs: - uniqueUVs[tuple(uv)] = [-1] - - file.write('\tuv_vectors {\n') - #print unique_uvs - file.write('\t\t%s' % (len(uniqueUVs))) # vert count - idx = 0 - for uv, index in uniqueUVs.items(): - file.write(',\n\t\t<%.6f, %.6f>' % uv) - index[0] = idx - idx +=1 - ''' - else: - # Just add 1 dummy vector, no real UV's - file.write('\t\t1') # vert count - file.write(',\n\t\t<0.0, 0.0>') - ''' - file.write('\n }\n') - - - if me.vertex_colors: - - for fi, f in enumerate(me.faces): - material_index = f.material_index - material = me_materials[material_index] - - if material and material.vertex_color_paint: - - col = vcol_layer[fi] - - if len(faces_verts[fi])==4: - cols = col.color1, col.color2, col.color3, col.color4 - else: - cols = col.color1, col.color2, col.color3 - - for col in cols: - key = col[0], col[1], col[2], material_index # Material index! - vertCols[key] = [-1] - - else: - if material: - diffuse_color = tuple(material.diffuse_color) - key = diffuse_color[0], diffuse_color[1], diffuse_color[2], material_index - vertCols[key] = [-1] - - - else: - # No vertex colours, so write material colours as vertex colours - for i, material in enumerate(me_materials): - - if material: - diffuse_color = tuple(material.diffuse_color) - key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat - vertCols[key] = [-1] - - - # Vert Colours - file.write('\ttexture_list {\n') - file.write('\t\t%s' % (len(vertCols))) # vert count - idx=0 - for col, index in vertCols.items(): - - if me_materials: - material = me_materials[col[3]] - material_finish = materialNames[material.name] - - if material.transparency and material.transparency_method=='RAYTRACE': trans = 1-material.raytrace_transparency.filter - else: trans = 0.0 - - else: - material_finish = DEF_MAT_NAME # not working properly, - trans = 0.0 - - #print material.apl - file.write( ',\n\t\ttexture { pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s}}' % - (col[0], col[1], col[2], 1-material.alpha, trans, material_finish) ) - - index[0] = idx - idx+=1 - - file.write( '\n }\n' ) - - # Face indicies - file.write('\tface_indices {\n') - file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count - for fi, f in enumerate(me.faces): - fv = faces_verts[fi] - material_index= f.material_index - if len(fv) == 4: indicies = (0,1,2), (0,2,3) - else: indicies = ((0,1,2),) - - if vcol_layer: - col = vcol_layer[fi] - - if len(fv) == 4: - cols = col.color1, col.color2, col.color3, col.color4 - else: - cols = col.color1, col.color2, col.color3 - - - if not me_materials or me_materials[material_index] == None: # No materials - for i1, i2, i3 in indicies: - file.write(',\n\t\t<%d,%d,%d>' % (fv[i1], fv[i2], fv[i3])) # vert count - else: - material = me_materials[material_index] - for i1, i2, i3 in indicies: - if me.vertex_colors and material.vertex_color_paint: - # Colour per vertex - vertex colour - - col1 = cols[i1] - col2 = cols[i2] - col3 = cols[i3] - - ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0] - ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0] - ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0] - else: - # Colour per material - flat material colour - diffuse_color= material.diffuse_color - ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], diffuse_color[2], f.material_index][0] - - file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count - - - file.write('\n }\n') - - # normal_indices indicies - file.write('\tnormal_indices {\n') - file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count - for fi, fv in enumerate(faces_verts): - - if len(fv) == 4: indicies = (0,1,2), (0,2,3) - else: indicies = ((0,1,2),) - - for i1, i2, i3 in indicies: - if f.smooth: - file.write(',\n\t\t<%d,%d,%d>' %\ - (uniqueNormals[verts_normals[fv[i1]]][0],\ - uniqueNormals[verts_normals[fv[i2]]][0],\ - uniqueNormals[verts_normals[fv[i3]]][0])) # vert count - else: - idx = uniqueNormals[faces_normals[fi]][0] - file.write(',\n\t\t<%d,%d,%d>' % (idx, idx, idx)) # vert count - - file.write('\n }\n') - - if uv_layer: - file.write('\tuv_indices {\n') - file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count - for fi, fv in enumerate(faces_verts): - - if len(fv) == 4: indicies = (0,1,2), (0,2,3) - else: indicies = ((0,1,2),) - - uv = uv_layer[fi] - if len(faces_verts[fi])==4: - uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3), tuple(uv.uv4) - else: - uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3) - - for i1, i2, i3 in indicies: - file.write(',\n\t\t<%d,%d,%d>' %\ - (uniqueUVs[uvs[i1]][0],\ - uniqueUVs[uvs[i2]][0],\ - uniqueUVs[uvs[i2]][0])) # vert count - file.write('\n }\n') - - if me.materials: - material = me.materials[0] # dodgy - writeObjectMaterial(material) - - writeMatrix(matrix) - file.write('}\n') - - bpy.data.remove_mesh(me) - - def exportWorld(world): - if not world: - return - - mist = world.mist - - if mist.enabled: - file.write('fog {\n') - file.write('\tdistance %.6f\n' % mist.depth) - file.write('\tcolor rgbt<%.3g, %.3g, %.3g, %.3g>\n' % (tuple(world.horizon_color) + (1-mist.intensity,))) - #file.write('\tfog_offset %.6f\n' % mist.start) - #file.write('\tfog_alt 5\n') - #file.write('\tturbulence 0.2\n') - #file.write('\tturb_depth 0.3\n') - file.write('\tfog_type 1\n') - file.write('}\n') - - def exportGlobalSettings(scene): - - file.write('global_settings {\n') - - if scene.pov_radio_enable: - file.write('\tradiosity {\n') - file.write("\t\tadc_bailout %.4g\n" % scene.pov_radio_adc_bailout) - file.write("\t\talways_sample %d\n" % scene.pov_radio_always_sample) - file.write("\t\tbrightness %.4g\n" % scene.pov_radio_brightness) - file.write("\t\tcount %d\n" % scene.pov_radio_count) - file.write("\t\terror_bound %.4g\n" % scene.pov_radio_error_bound) - file.write("\t\tgray_threshold %.4g\n" % scene.pov_radio_gray_threshold) - file.write("\t\tlow_error_factor %.4g\n" % scene.pov_radio_low_error_factor) - file.write("\t\tmedia %d\n" % scene.pov_radio_media) - file.write("\t\tminimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse) - file.write("\t\tnearest_count %d\n" % scene.pov_radio_nearest_count) - file.write("\t\tnormal %d\n" % scene.pov_radio_normal) - file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit) - file.write('\t}\n') - - if world: - file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color)) - - file.write('}\n') - - - # Convert all materials to strings we can access directly per vertex. - writeMaterial(None) # default material - - for material in bpy.data.materials: - writeMaterial(material) - - exportCamera() - #exportMaterials() - sel = scene.objects - exportLamps([l for l in sel if l.type == 'LAMP']) - exportMeta([l for l in sel if l.type == 'META']) - exportMeshs(sel) - exportWorld(scene.world) - exportGlobalSettings(scene) - - file.close() - -def write_pov_ini(filename_ini, filename_pov, filename_image): - scene = bpy.data.scenes[0] - render = scene.render_data - - x= int(render.resolution_x*render.resolution_percentage*0.01) - y= int(render.resolution_y*render.resolution_percentage*0.01) - - file = open(filename_ini, 'w') - - file.write('Input_File_Name="%s"\n' % filename_pov) - file.write('Output_File_Name="%s"\n' % filename_image) - - file.write('Width=%d\n' % x) - file.write('Height=%d\n' % y) - - # Needed for border render. - ''' - file.write('Start_Column=%d\n' % part.x) - file.write('End_Column=%d\n' % (part.x+part.w)) - - file.write('Start_Row=%d\n' % (part.y)) - file.write('End_Row=%d\n' % (part.y+part.h)) - ''' - - file.write('Display=0\n') - file.write('Pause_When_Done=0\n') - file.write('Output_File_Type=T\n') # TGA, best progressive loading - file.write('Output_Alpha=1\n') - - if render.antialiasing: - aa_mapping = {'OVERSAMPLE_5':2, 'OVERSAMPLE_8':3, 'OVERSAMPLE_11':4, 'OVERSAMPLE_16':5} # method 1 assumed - file.write('Antialias=1\n') - file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples]) - else: - file.write('Antialias=0\n') - - file.close() - -# Radiosity panel, use in the scene for now. -FloatProperty= bpy.types.Scene.FloatProperty -IntProperty= bpy.types.Scene.IntProperty -BoolProperty= bpy.types.Scene.BoolProperty - -# Not a real pov option, just to know if we should write -BoolProperty( attr="pov_radio_enable", - name="Enable Radiosity", - description="Enable povrays radiosity calculation.", - default= False) -BoolProperty( attr="pov_radio_display_advanced", - name="Advanced Options", - description="Show advanced options.", - default= False) - -# Real pov options -FloatProperty( attr="pov_radio_adc_bailout", - name="ADC Bailout", - description="The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results.", - min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default= 0.01) - -BoolProperty( attr="pov_radio_always_sample", - name="Always Sample", - description="Only use the data from the pretrace step and not gather any new samples during the final radiosity pass..", - default= True) - -FloatProperty( attr="pov_radio_brightness", - name="Brightness", - description="Ammount objects are brightened before being returned upwards to the rest of the system.", - min=0.0, max=1000.0, soft_min=0.0, soft_max=10.0, default= 1.0) - -IntProperty( attr="pov_radio_count", - name="Ray Count", - description="number of rays that are sent out whenever a new radiosity value has to be calculated.", - min=1, max=1600, default= 35) - -FloatProperty( attr="pov_radio_error_bound", - name="Error Bound", - description="one of the two main speed/quality tuning values, lower values are more accurate.", - min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default= 1.8) - -FloatProperty( attr="pov_radio_gray_threshold", - name="Gray Threshold", - description="one of the two main speed/quality tuning values, lower values are more accurate.", - min=0.0, max=1.0, soft_min=0, soft_max=1, default= 0.0) - -FloatProperty( attr="pov_radio_low_error_factor", - name="Low Error Factor", - description="If you calculate just enough samples, but no more, you will get an image which has slightly blotchy lighting.", - min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default= 0.5) - -# max_sample - not available yet -BoolProperty( attr="pov_radio_media", - name="Media", - description="Radiosity estimation can be affected by media.", - default= False) - -FloatProperty( attr="pov_radio_minimum_reuse", - name="Minimum Reuse", - description="Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors).", - min=0.0, max=1.0, soft_min=0.1, soft_max=0.1, default= 0.015) - -IntProperty( attr="pov_radio_nearest_count", - name="Nearest Count", - description="Number of old ambient values blended together to create a new interpolated value.", - min=1, max=20, default= 5) - -BoolProperty( attr="pov_radio_normal", - name="Normals", - description="Radiosity estimation can be affected by normals.", - default= False) - -IntProperty( attr="pov_radio_recursion_limit", - name="Recursion Limit", - description="how many recursion levels are used to calculate the diffuse inter-reflection.", - min=1, max=20, default= 3) - - -class PovrayRender(bpy.types.RenderEngine): - __idname__ = 'POVRAY_RENDER' - __label__ = "Povray" - DELAY = 0.02 - - def _export(self, scene): - import tempfile - - self.temp_file_in = tempfile.mktemp(suffix='.pov') - self.temp_file_out = tempfile.mktemp(suffix='.tga') - self.temp_file_ini = tempfile.mktemp(suffix='.ini') - ''' - self.temp_file_in = '/test.pov' - self.temp_file_out = '/test.tga' - self.temp_file_ini = '/test.ini' - ''' - - def info_callback(txt): - self.update_stats("", "POVRAY: " + txt) - - write_pov(self.temp_file_in, scene, info_callback) - - def _render(self): - - try: os.remove(self.temp_file_out) # so as not to load the old file - except: pass - - write_pov_ini(self.temp_file_ini, self.temp_file_in, self.temp_file_out) - - print ("***-STARTING-***") - - pov_binary = "povray" - - if sys.platform=='win32': - import winreg - regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.6\\Windows') - - if bitness == 64: - pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64' - else: - pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine' - - if 1: - self.process = subprocess.Popen([pov_binary, self.temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE - else: - # This works too but means we have to wait until its done - os.system('%s %s' % (pov_binary, self.temp_file_ini)) - - print ("***-DONE-***") - - def _cleanup(self): - for f in (self.temp_file_in, self.temp_file_ini, self.temp_file_out): - try: os.remove(f) - except: pass - - self.update_stats("", "") - - def render(self, scene): - - self.update_stats("", "POVRAY: Exporting data from Blender") - self._export(scene) - self.update_stats("", "POVRAY: Parsing File") - self._render() - - r = scene.render_data - - # compute resolution - x= int(r.resolution_x*r.resolution_percentage*0.01) - y= int(r.resolution_y*r.resolution_percentage*0.01) - - # Wait for the file to be created - while not os.path.exists(self.temp_file_out): - if self.test_break(): - try: self.process.terminate() - except: pass - break - - if self.process.poll() != None: - self.update_stats("", "POVRAY: Failed") - break - - time.sleep(self.DELAY) - - if os.path.exists(self.temp_file_out): - - self.update_stats("", "POVRAY: Rendering") - - prev_size = -1 - - def update_image(): - result = self.begin_result(0, 0, x, y) - lay = result.layers[0] - # possible the image wont load early on. - try: lay.load_from_file(self.temp_file_out) - except: pass - self.end_result(result) - - # Update while povray renders - while True: - - # test if povray exists - if self.process.poll() != None: - update_image(); - break - - # user exit - if self.test_break(): - try: self.process.terminate() - except: pass - - break - - # Would be nice to redirect the output - # stdout_value, stderr_value = self.process.communicate() # locks - - - # check if the file updated - new_size = os.path.getsize(self.temp_file_out) - - if new_size != prev_size: - update_image() - prev_size = new_size - - time.sleep(self.DELAY) - - self._cleanup() - -bpy.types.register(PovrayRender) - -# Use some of the existing buttons. -import buttons_scene -buttons_scene.SCENE_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') -del buttons_scene - -# Use only a subset of the world panels -import buttons_world -buttons_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER') -del buttons_world - -# Example of wrapping every class 'as is' -import buttons_material -for member in dir(buttons_material): - subclass = getattr(buttons_material, member) - try: subclass.COMPAT_ENGINES.add('POVRAY_RENDER') - except: pass -del buttons_material - -class RenderButtonsPanel(bpy.types.Panel): - __space_type__ = 'PROPERTIES' - __region_type__ = 'WINDOW' - __context__ = "scene" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - - def poll(self, context): - rd = context.scene.render_data - return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) - -class SCENE_PT_povray_radiosity(RenderButtonsPanel): - __label__ = "Radiosity" - COMPAT_ENGINES = set(['POVRAY_RENDER']) - - def draw_header(self, context): - scene = context.scene - - self.layout.itemR(scene, "pov_radio_enable", text="") - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render_data - - layout.active = scene.pov_radio_enable - - split = layout.split() - - col = split.column() - col.itemR(scene, "pov_radio_count", text="Rays") - col.itemR(scene, "pov_radio_recursion_limit", text="Recursions") - col = split.column() - col.itemR(scene, "pov_radio_error_bound", text="Error") - - layout.itemR(scene, "pov_radio_display_advanced") - - if scene.pov_radio_display_advanced: - split = layout.split() - - col = split.column() - col.itemR(scene, "pov_radio_adc_bailout", slider=True) - col.itemR(scene, "pov_radio_gray_threshold", slider=True) - col.itemR(scene, "pov_radio_low_error_factor", slider=True) - - col = split.column() - col.itemR(scene, "pov_radio_brightness") - col.itemR(scene, "pov_radio_minimum_reuse", text="Min Reuse") - col.itemR(scene, "pov_radio_nearest_count") - - split = layout.split() - - col = split.column() - col.itemL(text="Estimation Influence:") - col.itemR(scene, "pov_radio_media") - col.itemR(scene, "pov_radio_normal") - - col = split.column() - col.itemR(scene, "pov_radio_always_sample") - -bpy.types.register(SCENE_PT_povray_radiosity) diff --git a/release/io/export_3ds.py b/release/io/export_3ds.py deleted file mode 100644 index 19c12146769..00000000000 --- a/release/io/export_3ds.py +++ /dev/null @@ -1,1128 +0,0 @@ -#!BPY -# coding: utf-8 -""" -Name: '3D Studio (.3ds)...' -Blender: 243 -Group: 'Export' -Tooltip: 'Export to 3DS file format (.3ds).' -""" - -__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] -__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") -__version__ = "0.90a" -__bpydoc__ = """\ - -3ds Exporter - -This script Exports a 3ds file. - -Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information -from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Bob Holcomb -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -###################################################### -# Importing modules -###################################################### - -import struct -import os -import time - -import bpy - -# import Blender -# from BPyMesh import getMeshFromObject -# from BPyObject import getDerivedObjects -# try: -# import struct -# except: -# struct = None - -# also used by X3D exporter -# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects() -def create_derived_objects(ob): - if ob.parent and ob.parent.dupli_type != 'NONE': - return False, None - - if ob.dupli_type != 'NONE': - ob.create_dupli_list() - return True, [(dob.object, dob.matrix) for dob in ob.dupli_list] - else: - return False, [(ob, ob.matrix)] - -# also used by X3D exporter -def free_derived_objects(ob): - ob.free_dupli_list() - -# So 3ds max can open files, limit names to 12 in length -# this is verry annoying for filenames! -name_unique = [] -name_mapping = {} -def sane_name(name): - name_fixed = name_mapping.get(name) - if name_fixed != None: - return name_fixed - - if len(name) > 12: - new_name = name[:12] - else: - new_name = name - - i = 0 - - while new_name in name_unique: - new_name = new_name[:-4] + '.%.3d' % i - i+=1 - - name_unique.append(new_name) - name_mapping[name] = new_name - return new_name - -###################################################### -# Data Structures -###################################################### - -#Some of the chunks that we will export -#----- Primary Chunk, at the beginning of each file -PRIMARY= int("0x4D4D",16) - -#------ Main Chunks -OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information -VERSION = int("0x0002",16); #This gives the version of the .3ds file -KFDATA = int("0xB000",16); #This is the header for all of the key frame info - -#------ sub defines of OBJECTINFO -MATERIAL=45055 #0xAFFF // This stored the texture info -OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... - -#>------ sub defines of MATERIAL -MATNAME = int("0xA000",16); # This holds the material name -MATAMBIENT = int("0xA010",16); # Ambient color of the object/material -MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material -MATSPECULAR = int("0xA030",16); # SPecular color of the object/material -MATSHINESS = int("0xA040",16); # ?? -MATMAP = int("0xA200",16); # This is a header for a new material -MATMAPFILE = int("0xA300",16); # This holds the file name of the texture - -RGB1= int("0x0011",16) -RGB2= int("0x0012",16) - -#>------ sub defines of OBJECT -OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object -OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object -OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object - -#>------ sub defines of CAMERA -OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values - -#>------ sub defines of OBJECT_MESH -OBJECT_VERTICES = int("0x4110",16); # The objects vertices -OBJECT_FACES = int("0x4120",16); # The objects faces -OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color -OBJECT_UV = int("0x4140",16); # The UV texture coordinates -OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix - -#>------ sub defines of KFDATA -KFDATA_KFHDR = int("0xB00A",16); -KFDATA_KFSEG = int("0xB008",16); -KFDATA_KFCURTIME = int("0xB009",16); -KFDATA_OBJECT_NODE_TAG = int("0xB002",16); - -#>------ sub defines of OBJECT_NODE_TAG -OBJECT_NODE_ID = int("0xB030",16); -OBJECT_NODE_HDR = int("0xB010",16); -OBJECT_PIVOT = int("0xB013",16); -OBJECT_INSTANCE_NAME = int("0xB011",16); -POS_TRACK_TAG = int("0xB020",16); -ROT_TRACK_TAG = int("0xB021",16); -SCL_TRACK_TAG = int("0xB022",16); - -def uv_key(uv): - return round(uv[0], 6), round(uv[1], 6) -# return round(uv.x, 6), round(uv.y, 6) - -# size defines: -SZ_SHORT = 2 -SZ_INT = 4 -SZ_FLOAT = 4 - -class _3ds_short(object): - '''Class representing a short (2-byte integer) for a 3ds file. - *** This looks like an unsigned short H is unsigned from the struct docs - Cam***''' - __slots__ = 'value' - def __init__(self, val=0): - self.value=val - - def get_size(self): - return SZ_SHORT - - def write(self,file): - file.write(struct.pack("= mat_ls_len: - mat_index = f.mat = 0 - mat = mat_ls[mat_index] - if mat: mat_name = mat.name - else: mat_name = None - # else there alredy set to none - - img = uf.image -# img = f.image - if img: img_name = img.name - else: img_name = None - - materialDict.setdefault((mat_name, img_name), (mat, img) ) - - - else: - for mat in mat_ls: - if mat: # material may be None so check its not. - materialDict.setdefault((mat.name, None), (mat, None) ) - - # Why 0 Why! - for f in data.faces: - if f.material_index >= mat_ls_len: -# if f.mat >= mat_ls_len: - f.material_index = 0 - # f.mat = 0 - - if free: - free_derived_objects(ob) - - - # Make material chunks for all materials used in the meshes: - for mat_and_image in materialDict.values(): - object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1])) - - # Give all objects a unique ID and build a dictionary from object name to object id: - """ - name_to_id = {} - for ob, data in mesh_objects: - name_to_id[ob.name]= len(name_to_id) - #for ob in empty_objects: - # name_to_id[ob.name]= len(name_to_id) - """ - - # Create object chunks for all meshes: - i = 0 - for ob, blender_mesh in mesh_objects: - # create a new object chunk - object_chunk = _3ds_chunk(OBJECT) - - # set the object name - object_chunk.add_variable("name", _3ds_string(sane_name(ob.name))) - - # make a mesh chunk out of the mesh: - object_chunk.add_subchunk(make_mesh_chunk(blender_mesh, materialDict)) - object_info.add_subchunk(object_chunk) - - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - # make a kf object node for the object: - kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) - ''' -# if not blender_mesh.users: - bpy.data.remove_mesh(blender_mesh) -# blender_mesh.verts = None - - i+=i - - # Create chunks for all empties: - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - for ob in empty_objects: - # Empties only require a kf object node: - kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) - pass - ''' - - # Add main object info chunk to primary chunk: - primary.add_subchunk(object_info) - - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - # Add main keyframe data chunk to primary chunk: - primary.add_subchunk(kfdata) - ''' - - # At this point, the chunk hierarchy is completely built. - - # Check the size: - primary.get_size() - # Open the file for writing: - file = open( filename, 'wb' ) - - # Recursively write the chunks to file: - primary.write(file) - - # Close the file: - file.close() - - # Debugging only: report the exporting time: -# Blender.Window.WaitCursor(0) - print("3ds export time: %.2f" % (time.clock() - time1)) -# print("3ds export time: %.2f" % (Blender.sys.time() - time1)) - - # Debugging only: dump the chunk hierarchy: - #primary.dump() - - -# if __name__=='__main__': -# if struct: -# Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) -# else: -# Blender.Draw.PupMenu("Error%t|This script requires a full python installation") -# # save_3ds('/test_b.3ds') - -class EXPORT_OT_3ds(bpy.types.Operator): - ''' - 3DS Exporter - ''' - __idname__ = "export.3ds" - __label__ = 'Export 3DS' - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""), - ] - - def execute(self, context): - save_3ds(self.filename, context) - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - - def poll(self, context): # Poll isnt working yet - print("Poll") - return context.active_object != None - -bpy.ops.add(EXPORT_OT_3ds) diff --git a/release/io/export_fbx.py b/release/io/export_fbx.py deleted file mode 100644 index aa65473b8d6..00000000000 --- a/release/io/export_fbx.py +++ /dev/null @@ -1,3457 +0,0 @@ -#!BPY -""" -Name: 'Autodesk FBX (.fbx)...' -Blender: 249 -Group: 'Export' -Tooltip: 'Selection to an ASCII Autodesk FBX ' -""" -__author__ = "Campbell Barton" -__url__ = ['www.blender.org', 'blenderartists.org'] -__version__ = "1.2" - -__bpydoc__ = """\ -This script is an exporter to the FBX file format. - -http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx -""" -# -------------------------------------------------------------------------- -# FBX Export v0.1 by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import os -import time -import math # math.pi -import shutil # for file copying - -# try: -# import time -# # import os # only needed for batch export, nbot used yet -# except: -# time = None # use this to check if they have python modules installed - -# for python 2.3 support -try: - set() -except: - try: - from sets import Set as set - except: - set = None # so it complains you dont have a ! - -# # os is only needed for batch 'own dir' option -# try: -# import os -# except: -# os = None - -# import Blender -import bpy -import Mathutils -# from Blender.Mathutils import Matrix, Vector, RotationMatrix - -# import BPyObject -# import BPyMesh -# import BPySys -# import BPyMessages - -## This was used to make V, but faster not to do all that -##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' -##v = range(255) -##for c in valid: v.remove(ord(c)) -v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,47,58,59,60,61,62,63,64,92,94,96,124,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] -invalid = ''.join([chr(i) for i in v]) -def cleanName(name): - for ch in invalid: name = name.replace(ch, '_') - return name -# del v, i - - -def copy_file(source, dest): - file = open(source, 'rb') - data = file.read() - file.close() - - file = open(dest, 'wb') - file.write(data) - file.close() - - -# XXX not used anymore, images are copied one at a time -def copy_images(dest_dir, textures): - if not dest_dir.endswith(os.sep): - dest_dir += os.sep - - image_paths = set() - for tex in textures: - image_paths.add(Blender.sys.expandpath(tex.filename)) - - # Now copy images - copyCount = 0 - for image_path in image_paths: - if Blender.sys.exists(image_path): - # Make a name for the target path. - dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] - if not Blender.sys.exists(dest_image_path): # Image isnt alredy there - print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) - try: - copy_file(image_path, dest_image_path) - copyCount+=1 - except: - print('\t\tWarning, file failed to copy, skipping.') - - print('\tCopied %d images' % copyCount) - -# I guess FBX uses degrees instead of radians (Arystan). -# Call this function just before writing to FBX. -def eulerRadToDeg(eul): - ret = Mathutils.Euler() - - ret.x = 180 / math.pi * eul[0] - ret.y = 180 / math.pi * eul[1] - ret.z = 180 / math.pi * eul[2] - - return ret - -mtx4_identity = Mathutils.Matrix() - -# testing -mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used -#mtx_x90n = RotationMatrix(-90, 3, 'x') -#mtx_y90 = RotationMatrix( 90, 3, 'y') -#mtx_y90n = RotationMatrix(-90, 3, 'y') -#mtx_z90 = RotationMatrix( 90, 3, 'z') -#mtx_z90n = RotationMatrix(-90, 3, 'z') - -#mtx4_x90 = RotationMatrix( 90, 4, 'x') -mtx4_x90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'x') # used -#mtx4_y90 = RotationMatrix( 90, 4, 'y') -mtx4_y90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'y') # used -mtx4_z90 = Mathutils.RotationMatrix( math.pi/2, 4, 'z') # used -mtx4_z90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'z') # used - -# def strip_path(p): -# return p.split('\\')[-1].split('/')[-1] - -# Used to add the scene name into the filename without using odd chars -sane_name_mapping_ob = {} -sane_name_mapping_mat = {} -sane_name_mapping_tex = {} -sane_name_mapping_take = {} -sane_name_mapping_group = {} - -# Make sure reserved names are not used -sane_name_mapping_ob['Scene'] = 'Scene_' -sane_name_mapping_ob['blend_root'] = 'blend_root_' - -def increment_string(t): - name = t - num = '' - while name and name[-1].isdigit(): - num = name[-1] + num - name = name[:-1] - if num: return '%s%d' % (name, int(num)+1) - else: return name + '_0' - - - -# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up. -def sane_name(data, dct): - #if not data: return None - - if type(data)==tuple: # materials are paired up with images - data, other = data - use_other = True - else: - other = None - use_other = False - - if data: name = data.name - else: name = None - orig_name = name - - if other: - orig_name_other = other.name - name = '%s #%s' % (name, orig_name_other) - else: - orig_name_other = None - - # dont cache, only ever call once for each data type now, - # so as to avoid namespace collision between types - like with objects <-> bones - #try: return dct[name] - #except: pass - - if not name: - name = 'unnamed' # blank string, ASKING FOR TROUBLE! - else: - #name = BPySys.cleanName(name) - name = cleanName(name) # use our own - - while name in iter(dct.values()): name = increment_string(name) - - if use_other: # even if other is None - orig_name_other will be a string or None - dct[orig_name, orig_name_other] = name - else: - dct[orig_name] = name - - return name - -def sane_obname(data): return sane_name(data, sane_name_mapping_ob) -def sane_matname(data): return sane_name(data, sane_name_mapping_mat) -def sane_texname(data): return sane_name(data, sane_name_mapping_tex) -def sane_takename(data): return sane_name(data, sane_name_mapping_take) -def sane_groupname(data): return sane_name(data, sane_name_mapping_group) - -# def derived_paths(fname_orig, basepath, FORCE_CWD=False): -# ''' -# fname_orig - blender path, can be relative -# basepath - fname_rel will be relative to this -# FORCE_CWD - dont use the basepath, just add a ./ to the filename. -# use when we know the file will be in the basepath. -# ''' -# fname = bpy.sys.expandpath(fname_orig) -# # fname = Blender.sys.expandpath(fname_orig) -# fname_strip = os.path.basename(fname) -# # fname_strip = strip_path(fname) -# if FORCE_CWD: -# fname_rel = '.' + os.sep + fname_strip -# else: -# fname_rel = bpy.sys.relpath(fname, basepath) -# # fname_rel = Blender.sys.relpath(fname, basepath) -# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:] -# return fname, fname_strip, fname_rel - - -def mat4x4str(mat): - return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ]) - -# XXX not used -# duplicated in OBJ exporter -def getVertsFromGroup(me, group_index): - ret = [] - - for i, v in enumerate(me.verts): - for g in v.groups: - if g.group == group_index: - ret.append((i, g.weight)) - - return ret - -# ob must be OB_MESH -def BPyMesh_meshWeight2List(ob): - ''' Takes a mesh and return its group names and a list of lists, one list per vertex. - aligning the each vert list with the group names, each list contains float value for the weight. - These 2 lists can be modified and then used with list2MeshWeight to apply the changes. - ''' - - me = ob.data - - # Clear the vert group. - groupNames= [g.name for g in ob.vertex_groups] - len_groupNames= len(groupNames) - - if not len_groupNames: - # no verts? return a vert aligned empty list - return [[] for i in range(len(me.verts))], [] - else: - vWeightList= [[0.0]*len_groupNames for i in range(len(me.verts))] - - for i, v in enumerate(me.verts): - for g in v.groups: - vWeightList[i][g.group] = g.weight - - return groupNames, vWeightList - -def meshNormalizedWeights(me): - try: # account for old bad BPyMesh - groupNames, vWeightList = BPyMesh_meshWeight2List(me) -# groupNames, vWeightList = BPyMesh.meshWeight2List(me) - except: - return [],[] - - if not groupNames: - return [],[] - - for i, vWeights in enumerate(vWeightList): - tot = 0.0 - for w in vWeights: - tot+=w - - if tot: - for j, w in enumerate(vWeights): - vWeights[j] = w/tot - - return groupNames, vWeightList - -header_comment = \ -'''; FBX 6.1.0 project file -; Created by Blender FBX Exporter -; for support mail: ideasman42@gmail.com -; ---------------------------------------------------- - -''' - -# This func can be called with just the filename -def write(filename, batch_objects = None, \ - context = None, - EXP_OBS_SELECTED = True, - EXP_MESH = True, - EXP_MESH_APPLY_MOD = True, -# EXP_MESH_HQ_NORMALS = False, - EXP_ARMATURE = True, - EXP_LAMP = True, - EXP_CAMERA = True, - EXP_EMPTY = True, - EXP_IMAGE_COPY = False, - GLOBAL_MATRIX = Mathutils.Matrix(), - ANIM_ENABLE = True, - ANIM_OPTIMIZE = True, - ANIM_OPTIMIZE_PRECISSION = 6, - ANIM_ACTION_ALL = False, - BATCH_ENABLE = False, - BATCH_GROUP = True, - BATCH_FILE_PREFIX = '', - BATCH_OWN_DIR = False - ): - - # ----------------- Batch support! - if BATCH_ENABLE: - if os == None: BATCH_OWN_DIR = False - - fbxpath = filename - - # get the path component of filename - tmp_exists = bpy.sys.exists(fbxpath) -# tmp_exists = Blender.sys.exists(fbxpath) - - if tmp_exists != 2: # a file, we want a path - fbxpath = os.path.dirname(fbxpath) -# while fbxpath and fbxpath[-1] not in ('/', '\\'): -# fbxpath = fbxpath[:-1] - if not fbxpath: -# if not filename: - # XXX - print('Error%t|Directory does not exist!') -# Draw.PupMenu('Error%t|Directory does not exist!') - return - - tmp_exists = bpy.sys.exists(fbxpath) -# tmp_exists = Blender.sys.exists(fbxpath) - - if tmp_exists != 2: - # XXX - print('Error%t|Directory does not exist!') -# Draw.PupMenu('Error%t|Directory does not exist!') - return - - if not fbxpath.endswith(os.sep): - fbxpath += os.sep - del tmp_exists - - - if BATCH_GROUP: - data_seq = bpy.data.groups - else: - data_seq = bpy.data.scenes - - # call this function within a loop with BATCH_ENABLE == False - orig_sce = context.scene -# orig_sce = bpy.data.scenes.active - - - new_fbxpath = fbxpath # own dir option modifies, we need to keep an original - for data in data_seq: # scene or group - newname = BATCH_FILE_PREFIX + cleanName(data.name) -# newname = BATCH_FILE_PREFIX + BPySys.cleanName(data.name) - - - if BATCH_OWN_DIR: - new_fbxpath = fbxpath + newname + os.sep - # path may alredy exist - # TODO - might exist but be a file. unlikely but should probably account for it. - - if bpy.sys.exists(new_fbxpath) == 0: -# if Blender.sys.exists(new_fbxpath) == 0: - os.mkdir(new_fbxpath) - - - filename = new_fbxpath + newname + '.fbx' - - print('\nBatch exporting %s as...\n\t"%s"' % (data, filename)) - - # XXX don't know what to do with this, probably do the same? (Arystan) - if BATCH_GROUP: #group - # group, so objects update properly, add a dummy scene. - sce = bpy.data.scenes.new() - sce.Layers = (1<<20) -1 - bpy.data.scenes.active = sce - for ob_base in data.objects: - sce.objects.link(ob_base) - - sce.update(1) - - # TODO - BUMMER! Armatures not in the group wont animate the mesh - - else:# scene - - - data_seq.active = data - - - # Call self with modified args - # Dont pass batch options since we alredy usedt them - write(filename, data.objects, - context, - False, - EXP_MESH, - EXP_MESH_APPLY_MOD, -# EXP_MESH_HQ_NORMALS, - EXP_ARMATURE, - EXP_LAMP, - EXP_CAMERA, - EXP_EMPTY, - EXP_IMAGE_COPY, - GLOBAL_MATRIX, - ANIM_ENABLE, - ANIM_OPTIMIZE, - ANIM_OPTIMIZE_PRECISSION, - ANIM_ACTION_ALL - ) - - if BATCH_GROUP: - # remove temp group scene - bpy.data.remove_scene(sce) -# bpy.data.scenes.unlink(sce) - - bpy.data.scenes.active = orig_sce - - return # so the script wont run after we have batch exported. - - # end batch support - - # Use this for working out paths relative to the export location - basepath = os.path.dirname(filename) or '.' - basepath += os.sep -# basepath = Blender.sys.dirname(filename) - - # ---------------------------------------------- - # storage classes - class my_bone_class: - __slots__ =(\ - 'blenName',\ - 'blenBone',\ - 'blenMeshes',\ - 'restMatrix',\ - 'parent',\ - 'blenName',\ - 'fbxName',\ - 'fbxArm',\ - '__pose_bone',\ - '__anim_poselist') - - def __init__(self, blenBone, fbxArm): - - # This is so 2 armatures dont have naming conflicts since FBX bones use object namespace - self.fbxName = sane_obname(blenBone) - - self.blenName = blenBone.name - self.blenBone = blenBone - self.blenMeshes = {} # fbxMeshObName : mesh - self.fbxArm = fbxArm - self.restMatrix = blenBone.armature_matrix -# self.restMatrix = blenBone.matrix['ARMATURESPACE'] - - # not used yet - # self.restMatrixInv = self.restMatrix.copy().invert() - # self.restMatrixLocal = None # set later, need parent matrix - - self.parent = None - - # not public - pose = fbxArm.blenObject.pose -# pose = fbxArm.blenObject.getPose() - self.__pose_bone = pose.pose_channels[self.blenName] -# self.__pose_bone = pose.bones[self.blenName] - - # store a list if matricies here, (poseMatrix, head, tail) - # {frame:posematrix, frame:posematrix, ...} - self.__anim_poselist = {} - - ''' - def calcRestMatrixLocal(self): - if self.parent: - self.restMatrixLocal = self.restMatrix * self.parent.restMatrix.copy().invert() - else: - self.restMatrixLocal = self.restMatrix.copy() - ''' - def setPoseFrame(self, f): - # cache pose info here, frame must be set beforehand - - # Didnt end up needing head or tail, if we do - here it is. - ''' - self.__anim_poselist[f] = (\ - self.__pose_bone.poseMatrix.copy(),\ - self.__pose_bone.head.copy(),\ - self.__pose_bone.tail.copy() ) - ''' - - self.__anim_poselist[f] = self.__pose_bone.pose_matrix.copy() -# self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy() - - # get pose from frame. - def getPoseMatrix(self, f):# ---------------------------------------------- - return self.__anim_poselist[f] - ''' - def getPoseHead(self, f): - #return self.__pose_bone.head.copy() - return self.__anim_poselist[f][1].copy() - def getPoseTail(self, f): - #return self.__pose_bone.tail.copy() - return self.__anim_poselist[f][2].copy() - ''' - # end - - def getAnimParRelMatrix(self, frame): - #arm_mat = self.fbxArm.matrixWorld - #arm_mat = self.fbxArm.parRelMatrix() - if not self.parent: - #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore - return mtx4_z90 * self.getPoseMatrix(frame) - else: - #return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat))) * (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert() - return (mtx4_z90 * (self.getPoseMatrix(frame))) * (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert() - - # we need thes because cameras and lights modified rotations - def getAnimParRelMatrixRot(self, frame): - return self.getAnimParRelMatrix(frame) - - def flushAnimData(self): - self.__anim_poselist.clear() - - - class my_object_generic: - # Other settings can be applied for each type - mesh, armature etc. - def __init__(self, ob, matrixWorld = None): - self.fbxName = sane_obname(ob) - self.blenObject = ob - self.fbxGroupNames = [] - self.fbxParent = None # set later on IF the parent is in the selection. - if matrixWorld: self.matrixWorld = matrixWorld * GLOBAL_MATRIX - else: self.matrixWorld = ob.matrix * GLOBAL_MATRIX -# else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX - self.__anim_poselist = {} # we should only access this - - def parRelMatrix(self): - if self.fbxParent: - return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert() - else: - return self.matrixWorld - - def setPoseFrame(self, f): - self.__anim_poselist[f] = self.blenObject.matrix.copy() -# self.__anim_poselist[f] = self.blenObject.matrixWorld.copy() - - def getAnimParRelMatrix(self, frame): - if self.fbxParent: - #return (self.__anim_poselist[frame] * self.fbxParent.__anim_poselist[frame].copy().invert() ) * GLOBAL_MATRIX - return (self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert() - else: - return self.__anim_poselist[frame] * GLOBAL_MATRIX - - def getAnimParRelMatrixRot(self, frame): - type = self.blenObject.type - if self.fbxParent: - matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart() - else: - matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart() - - # Lamps need to be rotated - if type =='LAMP': - matrix_rot = mtx_x90 * matrix_rot - elif type =='CAMERA': -# elif ob and type =='Camera': - y = Mathutils.Vector(0,1,0) * matrix_rot - matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) - - return matrix_rot - - # ---------------------------------------------- - - - - - - print('\nFBX export starting...', filename) - start_time = time.clock() -# start_time = Blender.sys.time() - try: - file = open(filename, 'w') - except: - return False - - sce = context.scene -# sce = bpy.data.scenes.active - world = sce.world - - - # ---------------------------- Write the header first - file.write(header_comment) - if time: - curtime = time.localtime()[0:6] - else: - curtime = (0,0,0,0,0,0) - # - file.write(\ -'''FBXHeaderExtension: { - FBXHeaderVersion: 1003 - FBXVersion: 6100 - CreationTimeStamp: { - Version: 1000 - Year: %.4i - Month: %.2i - Day: %.2i - Hour: %.2i - Minute: %.2i - Second: %.2i - Millisecond: 0 - } - Creator: "FBX SDK/FBX Plugins build 20070228" - OtherFlags: { - FlagPLE: 0 - } -}''' % (curtime)) - - file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime) - file.write('\nCreator: "Blender3D version 2.5"') -# file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version')) - - pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way - - # --------------- funcs for exporting - def object_tx(ob, loc, matrix, matrix_mod = None): - ''' - Matrix mod is so armature objects can modify their bone matricies - ''' - if isinstance(ob, bpy.types.Bone): -# if isinstance(ob, Blender.Types.BoneType): - - # we know we have a matrix - # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod) - matrix = mtx4_z90 * ob.armature_matrix # dont apply armature matrix anymore -# matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore - - parent = ob.parent - if parent: - #par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod) - par_matrix = mtx4_z90 * parent.armature_matrix # dont apply armature matrix anymore -# par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore - matrix = matrix * par_matrix.copy().invert() - - matrix_rot = matrix.rotationPart() - - loc = tuple(matrix.translationPart()) - scale = tuple(matrix.scalePart()) - rot = tuple(matrix_rot.toEuler()) - - else: - # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore - #if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX - if ob and not matrix: raise Exception("error: this should never happen!") - - matrix_rot = matrix - #if matrix: - # matrix = matrix_scale * matrix - - if matrix: - loc = tuple(matrix.translationPart()) - scale = tuple(matrix.scalePart()) - - matrix_rot = matrix.rotationPart() - # Lamps need to be rotated - if ob and ob.type =='Lamp': - matrix_rot = mtx_x90 * matrix_rot - rot = tuple(matrix_rot.toEuler()) - elif ob and ob.type =='Camera': - y = Mathutils.Vector(0,1,0) * matrix_rot - matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) - rot = tuple(matrix_rot.toEuler()) - else: - rot = tuple(matrix_rot.toEuler()) - else: - if not loc: - loc = 0,0,0 - scale = 1,1,1 - rot = 0,0,0 - - return loc, rot, scale, matrix, matrix_rot - - def write_object_tx(ob, loc, matrix, matrix_mod= None): - ''' - We have loc to set the location if non blender objects that have a location - - matrix_mod is only used for bones at the moment - ''' - loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod) - - file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc) - file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % tuple(eulerRadToDeg(rot))) -# file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) - file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale) - return loc, rot, scale, matrix, matrix_rot - - def write_object_props(ob=None, loc=None, matrix=None, matrix_mod=None): - # if the type is 0 its an empty otherwise its a mesh - # only difference at the moment is one has a color - file.write(''' - Properties60: { - Property: "QuaternionInterpolate", "bool", "",0 - Property: "Visibility", "Visibility", "A+",1''') - - loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix, matrix_mod) - - # Rotation order, note, for FBX files Iv loaded normal order is 1 - # setting to zero. - # eEULER_XYZ = 0 - # eEULER_XZY - # eEULER_YZX - # eEULER_YXZ - # eEULER_ZXY - # eEULER_ZYX - - file.write(''' - Property: "RotationOffset", "Vector3D", "",0,0,0 - Property: "RotationPivot", "Vector3D", "",0,0,0 - Property: "ScalingOffset", "Vector3D", "",0,0,0 - Property: "ScalingPivot", "Vector3D", "",0,0,0 - Property: "TranslationActive", "bool", "",0 - Property: "TranslationMin", "Vector3D", "",0,0,0 - Property: "TranslationMax", "Vector3D", "",0,0,0 - Property: "TranslationMinX", "bool", "",0 - Property: "TranslationMinY", "bool", "",0 - Property: "TranslationMinZ", "bool", "",0 - Property: "TranslationMaxX", "bool", "",0 - Property: "TranslationMaxY", "bool", "",0 - Property: "TranslationMaxZ", "bool", "",0 - Property: "RotationOrder", "enum", "",0 - Property: "RotationSpaceForLimitOnly", "bool", "",0 - Property: "AxisLen", "double", "",10 - Property: "PreRotation", "Vector3D", "",0,0,0 - Property: "PostRotation", "Vector3D", "",0,0,0 - Property: "RotationActive", "bool", "",0 - Property: "RotationMin", "Vector3D", "",0,0,0 - Property: "RotationMax", "Vector3D", "",0,0,0 - Property: "RotationMinX", "bool", "",0 - Property: "RotationMinY", "bool", "",0 - Property: "RotationMinZ", "bool", "",0 - Property: "RotationMaxX", "bool", "",0 - Property: "RotationMaxY", "bool", "",0 - Property: "RotationMaxZ", "bool", "",0 - Property: "RotationStiffnessX", "double", "",0 - Property: "RotationStiffnessY", "double", "",0 - Property: "RotationStiffnessZ", "double", "",0 - Property: "MinDampRangeX", "double", "",0 - Property: "MinDampRangeY", "double", "",0 - Property: "MinDampRangeZ", "double", "",0 - Property: "MaxDampRangeX", "double", "",0 - Property: "MaxDampRangeY", "double", "",0 - Property: "MaxDampRangeZ", "double", "",0 - Property: "MinDampStrengthX", "double", "",0 - Property: "MinDampStrengthY", "double", "",0 - Property: "MinDampStrengthZ", "double", "",0 - Property: "MaxDampStrengthX", "double", "",0 - Property: "MaxDampStrengthY", "double", "",0 - Property: "MaxDampStrengthZ", "double", "",0 - Property: "PreferedAngleX", "double", "",0 - Property: "PreferedAngleY", "double", "",0 - Property: "PreferedAngleZ", "double", "",0 - Property: "InheritType", "enum", "",0 - Property: "ScalingActive", "bool", "",0 - Property: "ScalingMin", "Vector3D", "",1,1,1 - Property: "ScalingMax", "Vector3D", "",1,1,1 - Property: "ScalingMinX", "bool", "",0 - Property: "ScalingMinY", "bool", "",0 - Property: "ScalingMinZ", "bool", "",0 - Property: "ScalingMaxX", "bool", "",0 - Property: "ScalingMaxY", "bool", "",0 - Property: "ScalingMaxZ", "bool", "",0 - Property: "GeometricTranslation", "Vector3D", "",0,0,0 - Property: "GeometricRotation", "Vector3D", "",0,0,0 - Property: "GeometricScaling", "Vector3D", "",1,1,1 - Property: "LookAtProperty", "object", "" - Property: "UpVectorProperty", "object", "" - Property: "Show", "bool", "",1 - Property: "NegativePercentShapeSupport", "bool", "",1 - Property: "DefaultAttributeIndex", "int", "",0''') - if ob and not isinstance(ob, bpy.types.Bone): -# if ob and type(ob) != Blender.Types.BoneType: - # Only mesh objects have color - file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') - file.write('\n\t\t\tProperty: "Size", "double", "",100') - file.write('\n\t\t\tProperty: "Look", "enum", "",1') - - return loc, rot, scale, matrix, matrix_rot - - - # -------------------------------------------- Armatures - #def write_bone(bone, name, matrix_mod): - def write_bone(my_bone): - file.write('\n\tModel: "Model::%s", "Limb" {' % my_bone.fbxName) - file.write('\n\t\tVersion: 232') - - #poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.parRelMatrix())[3] - poseMatrix = write_object_props(my_bone.blenBone)[3] # dont apply bone matricies anymore - pose_items.append( (my_bone.fbxName, poseMatrix) ) - - - # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) - file.write('\n\t\t\tProperty: "Size", "double", "",1') - - #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.tail['ARMATURESPACE'] * my_bone.fbxArm.parRelMatrix())).length) - - """ - file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ - ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) - """ - - file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' % - (my_bone.blenBone.armature_head - my_bone.blenBone.armature_tail).length) -# (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length) - - #file.write('\n\t\t\tProperty: "LimbLength", "double", "",1') - file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8') - file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 1') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Skeleton"') - file.write('\n\t}') - - def write_camera_switch(): - file.write(''' - Model: "Model::Camera Switcher", "CameraSwitcher" { - Version: 232''') - - write_object_props() - file.write(''' - Property: "Color", "Color", "A",0.8,0.8,0.8 - Property: "Camera Index", "Integer", "A+",100 - } - MultiLayer: 0 - MultiTake: 1 - Hidden: "True" - Shading: W - Culling: "CullingOff" - Version: 101 - Name: "Model::Camera Switcher" - CameraId: 0 - CameraName: 100 - CameraIndexName: - }''') - - def write_camera_dummy(name, loc, near, far, proj_type, up): - file.write('\n\tModel: "Model::%s", "Camera" {' % name ) - file.write('\n\t\tVersion: 232') - write_object_props(None, loc) - - file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') - file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') - file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",40') - file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",0') - file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",0') - file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0.63,0.63,0.63') - file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') - file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') - file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') - file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') - file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') - file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') - file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') - file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",21.3544940948486') - file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') - file.write('\n\t\t\tProperty: "AspectW", "double", "",320') - file.write('\n\t\t\tProperty: "AspectH", "double", "",200') - file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",1') - file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') - file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') - file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') - file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % near) - file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % far) - file.write('\n\t\t\tProperty: "FilmWidth", "double", "",0.816') - file.write('\n\t\t\tProperty: "FilmHeight", "double", "",0.612') - file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",1.33333333333333') - file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') - file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",4') - file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') - file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') - file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') - file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') - file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') - file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') - file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') - file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') - file.write('\n\t\t\tProperty: "Crop", "bool", "",0') - file.write('\n\t\t\tProperty: "Center", "bool", "",1') - file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') - file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') - file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') - file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') - file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') - file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') - file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",1.33333333333333') - file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') - file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') - file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') - file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') - file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",%i' % proj_type) - file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') - file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') - file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') - file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') - file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') - file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') - file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') - file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 0') - file.write('\n\t\tHidden: "True"') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Camera"') - file.write('\n\t\tGeometryVersion: 124') - file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) - file.write('\n\t\tUp: %i,%i,%i' % up) - file.write('\n\t\tLookAt: 0,0,0') - file.write('\n\t\tShowInfoOnMoving: 1') - file.write('\n\t\tShowAudio: 0') - file.write('\n\t\tAudioColor: 0,1,0') - file.write('\n\t\tCameraOrthoZoom: 1') - file.write('\n\t}') - - def write_camera_default(): - # This sucks but to match FBX converter its easier to - # write the cameras though they are not needed. - write_camera_dummy('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0)) - write_camera_dummy('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1)) - write_camera_dummy('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1)) - write_camera_dummy('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0)) - write_camera_dummy('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0)) - write_camera_dummy('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0)) - write_camera_dummy('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0)) - - def write_camera(my_cam): - ''' - Write a blender camera - ''' - render = sce.render_data - width = render.resolution_x - height = render.resolution_y -# render = sce.render -# width = render.sizeX -# height = render.sizeY - aspect = float(width)/height - - data = my_cam.blenObject.data - - file.write('\n\tModel: "Model::%s", "Camera" {' % my_cam.fbxName ) - file.write('\n\t\tVersion: 232') - loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject, None, my_cam.parRelMatrix()) - - file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') - file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle) - file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026') - file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shift_x) # not sure if this is in the correct units? -# file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units? - file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shift_y) # ditto -# file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto - file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0') - file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') - file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') - file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') - file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') - file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') - file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') - file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') - file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') - file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width) - file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height) - - '''Camera aspect ratio modes. - 0 If the ratio mode is eWINDOW_SIZE, both width and height values aren't relevant. - 1 If the ratio mode is eFIXED_RATIO, the height value is set to 1.0 and the width value is relative to the height value. - 2 If the ratio mode is eFIXED_RESOLUTION, both width and height values are in pixels. - 3 If the ratio mode is eFIXED_WIDTH, the width value is in pixels and the height value is relative to the width value. - 4 If the ratio mode is eFIXED_HEIGHT, the height value is in pixels and the width value is relative to the height value. - - Definition at line 234 of file kfbxcamera.h. ''' - - file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",2') - - file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') - file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') - file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') - file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clip_start) -# file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart) - file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clip_end) -# file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart) - file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0') - file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0') - file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect) - file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') - file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",0') - file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') - file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') - file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') - file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') - file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') - file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') - file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') - file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') - file.write('\n\t\t\tProperty: "Crop", "bool", "",0') - file.write('\n\t\t\tProperty: "Center", "bool", "",1') - file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') - file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') - file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') - file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') - file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') - file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') - file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",%.6f' % aspect) - file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') - file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') - file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') - file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') - file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",0') - file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') - file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') - file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') - file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') - file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') - file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') - file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') - file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') - - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 0') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Camera"') - file.write('\n\t\tGeometryVersion: 124') - file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) - file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,1,0) * matrix_rot) ) - file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,0,-1)*matrix_rot) ) - - #file.write('\n\t\tUp: 0,0,0' ) - #file.write('\n\t\tLookAt: 0,0,0' ) - - file.write('\n\t\tShowInfoOnMoving: 1') - file.write('\n\t\tShowAudio: 0') - file.write('\n\t\tAudioColor: 0,1,0') - file.write('\n\t\tCameraOrthoZoom: 1') - file.write('\n\t}') - - def write_light(my_light): - light = my_light.blenObject.data - file.write('\n\tModel: "Model::%s", "Light" {' % my_light.fbxName) - file.write('\n\t\tVersion: 232') - - write_object_props(my_light.blenObject, None, my_light.parRelMatrix()) - - # Why are these values here twice?????? - oh well, follow the holy sdk's output - - # Blender light types match FBX's, funny coincidence, we just need to - # be sure that all unsupported types are made into a point light - #ePOINT, - #eDIRECTIONAL - #eSPOT - light_type_items = {'POINT': 0, 'SUN': 1, 'SPOT': 2, 'HEMI': 3, 'AREA': 4} - light_type = light_type_items[light.type] -# light_type = light.type - if light_type > 2: light_type = 1 # hemi and area lights become directional - -# mode = light.mode - if light.shadow_method == 'RAY_SHADOW' or light.shadow_method == 'BUFFER_SHADOW': -# if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: - do_shadow = 1 - else: - do_shadow = 0 - - if light.only_shadow or (not light.diffuse and not light.specular): -# if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular): - do_light = 0 - else: - do_light = 1 - - scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case - - file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) - file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') - file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') - file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1') - file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 - if light.type == 'SPOT': - file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spot_size * scale)) -# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) - file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') - file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.color)) -# file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col)) - file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 -# - # duplication? see ^ (Arystan) -# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) - file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') - file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) - file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light) - file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') - file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') - file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') - file.write('\n\t\t\tProperty: "DecayType", "enum", "",0') - file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.distance) -# file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist) - file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0') - file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0') - file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0') - file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0') - file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0') - file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0') - file.write('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow) - file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1') - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 0') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Light"') - file.write('\n\t\tGeometryVersion: 124') - file.write('\n\t}') - - # matrixOnly is not used at the moment - def write_null(my_null = None, fbxName = None, matrixOnly = None): - # ob can be null - if not fbxName: fbxName = my_null.fbxName - - file.write('\n\tModel: "Model::%s", "Null" {' % fbxName) - file.write('\n\t\tVersion: 232') - - # only use this for the root matrix at the moment - if matrixOnly: - poseMatrix = write_object_props(None, None, matrixOnly)[3] - - else: # all other Null's - if my_null: poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3] - else: poseMatrix = write_object_props()[3] - - pose_items.append((fbxName, poseMatrix)) - - file.write(''' - } - MultiLayer: 0 - MultiTake: 1 - Shading: Y - Culling: "CullingOff" - TypeFlags: "Null" - }''') - - # Material Settings - if world: world_amb = tuple(world.ambient_color) -# if world: world_amb = world.getAmb() - else: world_amb = (0,0,0) # Default value - - def write_material(matname, mat): - file.write('\n\tMaterial: "Material::%s", "" {' % matname) - - # Todo, add more material Properties. - if mat: - mat_cold = tuple(mat.diffuse_color) -# mat_cold = tuple(mat.rgbCol) - mat_cols = tuple(mat.specular_color) -# mat_cols = tuple(mat.specCol) - #mat_colm = tuple(mat.mirCol) # we wont use the mirror color - mat_colamb = world_amb -# mat_colamb = tuple([c for c in world_amb]) - - mat_dif = mat.diffuse_reflection -# mat_dif = mat.ref - mat_amb = mat.ambient -# mat_amb = mat.amb - mat_hard = (float(mat.specular_hardness)-1)/5.10 -# mat_hard = (float(mat.hard)-1)/5.10 - mat_spec = mat.specular_reflection/2.0 -# mat_spec = mat.spec/2.0 - mat_alpha = mat.alpha - mat_emit = mat.emit - mat_shadeless = mat.shadeless -# mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS - if mat_shadeless: - mat_shader = 'Lambert' - else: - if mat.diffuse_shader == 'LAMBERT': -# if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT: - mat_shader = 'Lambert' - else: - mat_shader = 'Phong' - else: - mat_cols = mat_cold = 0.8, 0.8, 0.8 - mat_colamb = 0.0,0.0,0.0 - # mat_colm - mat_dif = 1.0 - mat_amb = 0.5 - mat_hard = 20.0 - mat_spec = 0.2 - mat_alpha = 1.0 - mat_emit = 0.0 - mat_shadeless = False - mat_shader = 'Phong' - - file.write('\n\t\tVersion: 102') - file.write('\n\t\tShadingModel: "%s"' % mat_shader.lower()) - file.write('\n\t\tMultiLayer: 0') - - file.write('\n\t\tProperties60: {') - file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader) - file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0') - file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender - file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit) - - file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb) - file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb) - file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) - file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif) - file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0') - file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1') - file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha)) - if not mat_shadeless: - file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols) - file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec) - file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0') - file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0') - file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1') - file.write('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0') - file.write('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb) - file.write('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold) - if not mat_shadeless: - file.write('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols) - file.write('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard) - file.write('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha) - if not mat_shadeless: - file.write('\n\t\t\tProperty: "Reflectivity", "double", "",0') - - file.write('\n\t\t}') - file.write('\n\t}') - - def copy_image(image): - - rel = image.get_export_path(basepath, True) - base = os.path.basename(rel) - - if EXP_IMAGE_COPY: - absp = image.get_export_path(basepath, False) - if not os.path.exists(absp): - shutil.copy(image.get_abs_filename(), absp) - - return (rel, base) - - # tex is an Image (Arystan) - def write_video(texname, tex): - # Same as texture really! - file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) - - file.write(''' - Type: "Clip" - Properties60: { - Property: "FrameRate", "double", "",0 - Property: "LastFrame", "int", "",0 - Property: "Width", "int", "",0 - Property: "Height", "int", "",0''') - if tex: - fname_rel, fname_strip = copy_image(tex) -# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) - else: - fname = fname_strip = fname_rel = '' - - file.write('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip) - - - file.write(''' - Property: "StartFrame", "int", "",0 - Property: "StopFrame", "int", "",0 - Property: "PlaySpeed", "double", "",1 - Property: "Offset", "KTime", "",0 - Property: "InterlaceMode", "enum", "",0 - Property: "FreeRunning", "bool", "",0 - Property: "Loop", "bool", "",0 - Property: "AccessMode", "enum", "",0 - } - UseMipMap: 0''') - - file.write('\n\t\tFilename: "%s"' % fname_strip) - if fname_strip: fname_strip = '/' + fname_strip - file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # make relative - file.write('\n\t}') - - - def write_texture(texname, tex, num): - # if tex == None then this is a dummy tex - file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname) - file.write('\n\t\tType: "TextureVideoClip"') - file.write('\n\t\tVersion: 202') - # TODO, rare case _empty_ exists as a name. - file.write('\n\t\tTextureName: "Texture::%s"' % texname) - - file.write(''' - Properties60: { - Property: "Translation", "Vector", "A+",0,0,0 - Property: "Rotation", "Vector", "A+",0,0,0 - Property: "Scaling", "Vector", "A+",1,1,1''') - file.write('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num) - - - # WrapModeU/V 0==rep, 1==clamp, TODO add support - file.write(''' - Property: "TextureTypeUse", "enum", "",0 - Property: "CurrentTextureBlendMode", "enum", "",1 - Property: "UseMaterial", "bool", "",0 - Property: "UseMipMap", "bool", "",0 - Property: "CurrentMappingType", "enum", "",0 - Property: "UVSwap", "bool", "",0''') - - file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clamp_x) -# file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX) - file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clamp_y) -# file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY) - - file.write(''' - Property: "TextureRotationPivot", "Vector3D", "",0,0,0 - Property: "TextureScalingPivot", "Vector3D", "",0,0,0 - Property: "VideoProperty", "object", "" - }''') - - file.write('\n\t\tMedia: "Video::%s"' % texname) - - if tex: - fname_rel, fname_strip = copy_image(tex) -# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) - else: - fname = fname_strip = fname_rel = '' - - file.write('\n\t\tFileName: "%s"' % fname_strip) - file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # need some make relative command - - file.write(''' - ModelUVTranslation: 0,0 - ModelUVScaling: 1,1 - Texture_Alpha_Source: "None" - Cropping: 0,0,0,0 - }''') - - def write_deformer_skin(obname): - ''' - Each mesh has its own deformer - ''' - file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname) - file.write(''' - Version: 100 - MultiLayer: 0 - Type: "Skin" - Properties60: { - } - Link_DeformAcuracy: 50 - }''') - - # in the example was 'Bip01 L Thigh_2' - def write_sub_deformer_skin(my_mesh, my_bone, weights): - - ''' - Each subdeformer is spesific to a mesh, but the bone it links to can be used by many sub-deformers - So the SubDeformer needs the mesh-object name as a prefix to make it unique - - Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer, - a but silly but dosnt really matter - ''' - file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName)) - - file.write(''' - Version: 100 - MultiLayer: 0 - Type: "Cluster" - Properties60: { - Property: "SrcModel", "object", "" - Property: "SrcModelReference", "object", "" - } - UserData: "", ""''') - - # Support for bone parents - if my_mesh.fbxBoneParent: - if my_mesh.fbxBoneParent == my_bone: - # TODO - this is a bit lazy, we could have a simple write loop - # for this case because all weights are 1.0 but for now this is ok - # Parent Bones arent used all that much anyway. - vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.verts))] - else: - # This bone is not a parent of this mesh object, no weights - vgroup_data = [] - - else: - # Normal weight painted mesh - if my_bone.blenName in weights[0]: - # Before we used normalized wright list - #vgroup_data = me.getVertsFromGroup(bone.name, 1) - group_index = weights[0].index(my_bone.blenName) - vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]] - else: - vgroup_data = [] - - file.write('\n\t\tIndexes: ') - - i = -1 - for vg in vgroup_data: - if i == -1: - file.write('%i' % vg[0]) - i=0 - else: - if i==23: - file.write('\n\t\t') - i=0 - file.write(',%i' % vg[0]) - i+=1 - - file.write('\n\t\tWeights: ') - i = -1 - for vg in vgroup_data: - if i == -1: - file.write('%.8f' % vg[1]) - i=0 - else: - if i==38: - file.write('\n\t\t') - i=0 - file.write(',%.8f' % vg[1]) - i+=1 - - if my_mesh.fbxParent: - # TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible! - m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) - else: - # Yes! this is it... - but dosnt work when the mesh is a. - m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) - - #m = mtx4_z90 * my_bone.restMatrix - matstr = mat4x4str(m) - matstr_i = mat4x4str(m.invert()) - - file.write('\n\t\tTransform: %s' % matstr_i) # THIS IS __NOT__ THE GLOBAL MATRIX AS DOCUMENTED :/ - file.write('\n\t\tTransformLink: %s' % matstr) - file.write('\n\t}') - - def write_mesh(my_mesh): - - me = my_mesh.blenData - - # if there are non NULL materials on this mesh - if my_mesh.blenMaterials: do_materials = True - else: do_materials = False - - if my_mesh.blenTextures: do_textures = True - else: do_textures = False - - do_uvs = len(me.uv_textures) > 0 -# do_uvs = me.faceUV - - - file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) - file.write('\n\t\tVersion: 232') # newline is added in write_object_props - - poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3] - pose_items.append((my_mesh.fbxName, poseMatrix)) - - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 1') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - - - # Write the Real Mesh data here - file.write('\n\t\tVertices: ') - i=-1 - - for v in me.verts: - if i==-1: - file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0 - else: - if i==7: - file.write('\n\t\t'); i=0 - file.write(',%.6f,%.6f,%.6f'% tuple(v.co)) - i+=1 - - file.write('\n\t\tPolygonVertexIndex: ') - i=-1 - for f in me.faces: - fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3] -# fi = [v.index for v in f] - - # flip the last index, odd but it looks like - # this is how fbx tells one face from another - fi[-1] = -(fi[-1]+1) - fi = tuple(fi) - if i==-1: - if len(fi) == 3: file.write('%i,%i,%i' % fi ) -# if len(f) == 3: file.write('%i,%i,%i' % fi ) - else: file.write('%i,%i,%i,%i' % fi ) - i=0 - else: - if i==13: - file.write('\n\t\t') - i=0 - if len(fi) == 3: file.write(',%i,%i,%i' % fi ) -# if len(f) == 3: file.write(',%i,%i,%i' % fi ) - else: file.write(',%i,%i,%i,%i' % fi ) - i+=1 - - file.write('\n\t\tEdges: ') - i=-1 - for ed in me.edges: - if i==-1: - file.write('%i,%i' % (ed.verts[0], ed.verts[1])) -# file.write('%i,%i' % (ed.v1.index, ed.v2.index)) - i=0 - else: - if i==13: - file.write('\n\t\t') - i=0 - file.write(',%i,%i' % (ed.verts[0], ed.verts[1])) -# file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) - i+=1 - - file.write('\n\t\tGeometryVersion: 124') - - file.write(''' - LayerElementNormal: 0 { - Version: 101 - Name: "" - MappingInformationType: "ByVertice" - ReferenceInformationType: "Direct" - Normals: ''') - - i=-1 - for v in me.verts: - if i==-1: - file.write('%.15f,%.15f,%.15f' % tuple(v.normal)); i=0 -# file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0 - else: - if i==2: - file.write('\n '); i=0 - file.write(',%.15f,%.15f,%.15f' % tuple(v.normal)) -# file.write(',%.15f,%.15f,%.15f' % tuple(v.no)) - i+=1 - file.write('\n\t\t}') - - # Write Face Smoothing - file.write(''' - LayerElementSmoothing: 0 { - Version: 102 - Name: "" - MappingInformationType: "ByPolygon" - ReferenceInformationType: "Direct" - Smoothing: ''') - - i=-1 - for f in me.faces: - if i==-1: - file.write('%i' % f.smooth); i=0 - else: - if i==54: - file.write('\n '); i=0 - file.write(',%i' % f.smooth) - i+=1 - - file.write('\n\t\t}') - - # Write Edge Smoothing - file.write(''' - LayerElementSmoothing: 0 { - Version: 101 - Name: "" - MappingInformationType: "ByEdge" - ReferenceInformationType: "Direct" - Smoothing: ''') - -# SHARP = Blender.Mesh.EdgeFlags.SHARP - i=-1 - for ed in me.edges: - if i==-1: - file.write('%i' % (ed.sharp)); i=0 -# file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 - else: - if i==54: - file.write('\n '); i=0 - file.write(',%i' % (ed.sharp)) -# file.write(',%i' % ((ed.flag&SHARP)!=0)) - i+=1 - - file.write('\n\t\t}') -# del SHARP - - # small utility function - # returns a slice of data depending on number of face verts - # data is either a MeshTextureFace or MeshColor - def face_data(data, face): - if f.verts[3] == 0: - totvert = 3 - else: - totvert = 4 - - return data[:totvert] - - - # Write VertexColor Layers - # note, no programs seem to use this info :/ - collayers = [] - if len(me.vertex_colors): -# if me.vertexColors: - collayers = me.vertex_colors -# collayers = me.getColorLayerNames() - collayer_orig = me.active_vertex_color -# collayer_orig = me.activeColorLayer - for colindex, collayer in enumerate(collayers): -# me.activeColorLayer = collayer - file.write('\n\t\tLayerElementColor: %i {' % colindex) - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % collayer.name) -# file.write('\n\t\t\tName: "%s"' % collayer) - - file.write(''' - MappingInformationType: "ByPolygonVertex" - ReferenceInformationType: "IndexToDirect" - Colors: ''') - - i = -1 - ii = 0 # Count how many Colors we write - - for f, cf in zip(me.faces, collayer.data): - colors = [cf.color1, cf.color2, cf.color3, cf.color4] - - # determine number of verts - colors = face_data(colors, f) - - for col in colors: - if i==-1: - file.write('%.4f,%.4f,%.4f,1' % tuple(col)) - i=0 - else: - if i==7: - file.write('\n\t\t\t\t') - i=0 - file.write(',%.4f,%.4f,%.4f,1' % tuple(col)) - i+=1 - ii+=1 # One more Color - -# for f in me.faces: -# for col in f.col: -# if i==-1: -# file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) -# i=0 -# else: -# if i==7: -# file.write('\n\t\t\t\t') -# i=0 -# file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) -# i+=1 -# ii+=1 # One more Color - - file.write('\n\t\t\tColorIndex: ') - i = -1 - for j in range(ii): - if i == -1: - file.write('%i' % j) - i=0 - else: - if i==55: - file.write('\n\t\t\t\t') - i=0 - file.write(',%i' % j) - i+=1 - - file.write('\n\t\t}') - - - - # Write UV and texture layers. - uvlayers = [] - if do_uvs: - uvlayers = me.uv_textures -# uvlayers = me.getUVLayerNames() - uvlayer_orig = me.active_uv_texture -# uvlayer_orig = me.activeUVLayer - for uvindex, uvlayer in enumerate(me.uv_textures): -# for uvindex, uvlayer in enumerate(uvlayers): -# me.activeUVLayer = uvlayer - file.write('\n\t\tLayerElementUV: %i {' % uvindex) - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % uvlayer.name) -# file.write('\n\t\t\tName: "%s"' % uvlayer) - - file.write(''' - MappingInformationType: "ByPolygonVertex" - ReferenceInformationType: "IndexToDirect" - UV: ''') - - i = -1 - ii = 0 # Count how many UVs we write - - for f, uf in zip(me.faces, uvlayer.data): -# for f in me.faces: - uvs = [uf.uv1, uf.uv2, uf.uv3, uf.uv4] - uvs = face_data(uvs, f) - - for uv in uvs: -# for uv in f.uv: - if i==-1: - file.write('%.6f,%.6f' % tuple(uv)) - i=0 - else: - if i==7: - file.write('\n ') - i=0 - file.write(',%.6f,%.6f' % tuple(uv)) - i+=1 - ii+=1 # One more UV - - file.write('\n\t\t\tUVIndex: ') - i = -1 - for j in range(ii): - if i == -1: - file.write('%i' % j) - i=0 - else: - if i==55: - file.write('\n\t\t\t\t') - i=0 - file.write(',%i' % j) - i+=1 - - file.write('\n\t\t}') - - if do_textures: - file.write('\n\t\tLayerElementTexture: %i {' % uvindex) - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % uvlayer.name) -# file.write('\n\t\t\tName: "%s"' % uvlayer) - - if len(my_mesh.blenTextures) == 1: - file.write('\n\t\t\tMappingInformationType: "AllSame"') - else: - file.write('\n\t\t\tMappingInformationType: "ByPolygon"') - - file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') - file.write('\n\t\t\tBlendMode: "Translucent"') - file.write('\n\t\t\tTextureAlpha: 1') - file.write('\n\t\t\tTextureId: ') - - if len(my_mesh.blenTextures) == 1: - file.write('0') - else: - texture_mapping_local = {None:-1} - - i = 0 # 1 for dummy - for tex in my_mesh.blenTextures: - if tex: # None is set above - texture_mapping_local[tex] = i - i+=1 - - i=-1 - for f in uvlayer.data: -# for f in me.faces: - img_key = f.image - - if i==-1: - i=0 - file.write( '%s' % texture_mapping_local[img_key]) - else: - if i==55: - file.write('\n ') - i=0 - - file.write(',%s' % texture_mapping_local[img_key]) - i+=1 - - else: - file.write(''' - LayerElementTexture: 0 { - Version: 101 - Name: "" - MappingInformationType: "NoMappingInformation" - ReferenceInformationType: "IndexToDirect" - BlendMode: "Translucent" - TextureAlpha: 1 - TextureId: ''') - file.write('\n\t\t}') - -# me.activeUVLayer = uvlayer_orig - - # Done with UV/textures. - - if do_materials: - file.write('\n\t\tLayerElementMaterial: 0 {') - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: ""') - - if len(my_mesh.blenMaterials) == 1: - file.write('\n\t\t\tMappingInformationType: "AllSame"') - else: - file.write('\n\t\t\tMappingInformationType: "ByPolygon"') - - file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') - file.write('\n\t\t\tMaterials: ') - - if len(my_mesh.blenMaterials) == 1: - file.write('0') - else: - # Build a material mapping for this - material_mapping_local = {} # local-mat & tex : global index. - - for j, mat_tex_pair in enumerate(my_mesh.blenMaterials): - material_mapping_local[mat_tex_pair] = j - - len_material_mapping_local = len(material_mapping_local) - - mats = my_mesh.blenMaterialList - - if me.active_uv_texture: - uv_faces = me.active_uv_texture.data - else: - uv_faces = [None] * len(me.faces) - - i=-1 - for f, uf in zip(me.faces, uv_faces): -# for f in me.faces: - try: mat = mats[f.material_index] -# try: mat = mats[f.mat] - except:mat = None - - if do_uvs: tex = uf.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ -# if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ - else: tex = None - - if i==-1: - i=0 - file.write( '%s' % (material_mapping_local[mat, tex])) # None for mat or tex is ok - else: - if i==55: - file.write('\n\t\t\t\t') - i=0 - - file.write(',%s' % (material_mapping_local[mat, tex])) - i+=1 - - file.write('\n\t\t}') - - file.write(''' - Layer: 0 { - Version: 100 - LayerElement: { - Type: "LayerElementNormal" - TypedIndex: 0 - }''') - - if do_materials: - file.write(''' - LayerElement: { - Type: "LayerElementMaterial" - TypedIndex: 0 - }''') - - # Always write this - if do_textures: - file.write(''' - LayerElement: { - Type: "LayerElementTexture" - TypedIndex: 0 - }''') - - if me.vertex_colors: -# if me.vertexColors: - file.write(''' - LayerElement: { - Type: "LayerElementColor" - TypedIndex: 0 - }''') - - if do_uvs: # same as me.faceUV - file.write(''' - LayerElement: { - Type: "LayerElementUV" - TypedIndex: 0 - }''') - - - file.write('\n\t\t}') - - if len(uvlayers) > 1: - for i in range(1, len(uvlayers)): - - file.write('\n\t\tLayer: %i {' % i) - file.write('\n\t\t\tVersion: 100') - - file.write(''' - LayerElement: { - Type: "LayerElementUV"''') - - file.write('\n\t\t\t\tTypedIndex: %i' % i) - file.write('\n\t\t\t}') - - if do_textures: - - file.write(''' - LayerElement: { - Type: "LayerElementTexture"''') - - file.write('\n\t\t\t\tTypedIndex: %i' % i) - file.write('\n\t\t\t}') - - file.write('\n\t\t}') - - if len(collayers) > 1: - # Take into account any UV layers - layer_offset = 0 - if uvlayers: layer_offset = len(uvlayers)-1 - - for i in range(layer_offset, len(collayers)+layer_offset): - file.write('\n\t\tLayer: %i {' % i) - file.write('\n\t\t\tVersion: 100') - - file.write(''' - LayerElement: { - Type: "LayerElementColor"''') - - file.write('\n\t\t\t\tTypedIndex: %i' % i) - file.write('\n\t\t\t}') - file.write('\n\t\t}') - file.write('\n\t}') - - def write_group(name): - file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name) - - file.write(''' - Properties60: { - Property: "MultiLayer", "bool", "",0 - Property: "Pickable", "bool", "",1 - Property: "Transformable", "bool", "",1 - Property: "Show", "bool", "",1 - } - MultiLayer: 0 - }''') - - - # add meshes here to clear because they are not used anywhere. - meshes_to_clear = [] - - ob_meshes = [] - ob_lights = [] - ob_cameras = [] - # in fbx we export bones as children of the mesh - # armatures not a part of a mesh, will be added to ob_arms - ob_bones = [] - ob_arms = [] - ob_null = [] # emptys - - # List of types that have blender objects (not bones) - ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null] - - groups = [] # blender groups, only add ones that have objects in the selections - materials = {} # (mat, image) keys, should be a set() - textures = {} # should be a set() - - tmp_ob_type = ob_type = None # incase no objects are exported, so as not to raise an error - - # if EXP_OBS_SELECTED is false, use sceens objects - if not batch_objects: - if EXP_OBS_SELECTED: tmp_objects = context.selected_objects -# if EXP_OBS_SELECTED: tmp_objects = sce.objects.context - else: tmp_objects = sce.objects - else: - tmp_objects = batch_objects - - if EXP_ARMATURE: - # This is needed so applying modifiers dosnt apply the armature deformation, its also needed - # ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes. - # set every armature to its rest, backup the original values so we done mess up the scene - ob_arms_orig_rest = [arm.rest_position for arm in bpy.data.armatures] -# ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures] - - for arm in bpy.data.armatures: - arm.rest_position = True -# arm.restPosition = True - - if ob_arms_orig_rest: - for ob_base in bpy.data.objects: - #if ob_base.type == 'Armature': - ob_base.make_display_list() -# ob_base.makeDisplayList() - - # This causes the makeDisplayList command to effect the mesh - sce.set_frame(sce.current_frame) -# Blender.Set('curframe', Blender.Get('curframe')) - - - for ob_base in tmp_objects: - - # ignore dupli children - if ob_base.parent and ob_base.parent.dupli_type != 'NONE': - continue - - obs = [(ob_base, ob_base.matrix)] - if ob_base.dupli_type != 'NONE': - ob_base.create_dupli_list() - obs = [(dob.object, dob.matrix) for dob in ob_base.dupli_list] - - for ob, mtx in obs: -# for ob, mtx in BPyObject.getDerivedObjects(ob_base): - tmp_ob_type = ob.type - if tmp_ob_type == 'CAMERA': -# if tmp_ob_type == 'Camera': - if EXP_CAMERA: - ob_cameras.append(my_object_generic(ob, mtx)) - elif tmp_ob_type == 'LAMP': -# elif tmp_ob_type == 'Lamp': - if EXP_LAMP: - ob_lights.append(my_object_generic(ob, mtx)) - elif tmp_ob_type == 'ARMATURE': -# elif tmp_ob_type == 'Armature': - if EXP_ARMATURE: - # TODO - armatures dont work in dupligroups! - if ob not in ob_arms: ob_arms.append(ob) - # ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)" - elif tmp_ob_type == 'EMPTY': -# elif tmp_ob_type == 'Empty': - if EXP_EMPTY: - ob_null.append(my_object_generic(ob, mtx)) - elif EXP_MESH: - origData = True - if tmp_ob_type != 'MESH': -# if tmp_ob_type != 'Mesh': -# me = bpy.data.meshes.new() - try: me = ob.create_mesh(True, 'PREVIEW') -# try: me.getFromObject(ob) - except: me = None - if me: - meshes_to_clear.append( me ) - mats = me.materials - origData = False - else: - # Mesh Type! - if EXP_MESH_APPLY_MOD: -# me = bpy.data.meshes.new() - me = ob.create_mesh(True, 'PREVIEW') -# me.getFromObject(ob) - - # so we keep the vert groups -# if EXP_ARMATURE: -# orig_mesh = ob.getData(mesh=1) -# if orig_mesh.getVertGroupNames(): -# ob.copy().link(me) -# # If new mesh has no vgroups we can try add if verts are teh same -# if not me.getVertGroupNames(): # vgroups were not kept by the modifier -# if len(me.verts) == len(orig_mesh.verts): -# groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh) -# BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) - - # print ob, me, me.getVertGroupNames() - meshes_to_clear.append( me ) - origData = False - mats = me.materials - else: - me = ob.data -# me = ob.getData(mesh=1) - mats = me.materials - -# # Support object colors -# tmp_colbits = ob.colbits -# if tmp_colbits: -# tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too. -# for i in xrange(16): -# if tmp_colbits & (1< 0: -# if me.faceUV: - uvlayer_orig = me.active_uv_texture -# uvlayer_orig = me.activeUVLayer - for uvlayer in me.uv_textures: -# for uvlayer in me.getUVLayerNames(): -# me.activeUVLayer = uvlayer - for f, uf in zip(me.faces, uvlayer.data): -# for f in me.faces: - tex = uf.image -# tex = f.image - textures[tex] = texture_mapping_local[tex] = None - - try: mat = mats[f.material_index] -# try: mat = mats[f.mat] - except: mat = None - - materials[mat, tex] = material_mapping_local[mat, tex] = None # should use sets, wait for blender 2.5 - - -# me.activeUVLayer = uvlayer_orig - else: - for mat in mats: - # 2.44 use mat.lib too for uniqueness - materials[mat, None] = material_mapping_local[mat, None] = None - else: - materials[None, None] = None - - if EXP_ARMATURE: - armob = ob.find_armature() - blenParentBoneName = None - - # parent bone - special case - if (not armob) and ob.parent and ob.parent.type == 'ARMATURE' and \ - ob.parent_type == 'BONE': -# if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE: - armob = ob.parent - blenParentBoneName = ob.parent_bone -# blenParentBoneName = ob.parentbonename - - - if armob and armob not in ob_arms: - ob_arms.append(armob) - - else: - blenParentBoneName = armob = None - - my_mesh = my_object_generic(ob, mtx) - my_mesh.blenData = me - my_mesh.origData = origData - my_mesh.blenMaterials = list(material_mapping_local.keys()) - my_mesh.blenMaterialList = mats - my_mesh.blenTextures = list(texture_mapping_local.keys()) - - # if only 1 null texture then empty the list - if len(my_mesh.blenTextures) == 1 and my_mesh.blenTextures[0] == None: - my_mesh.blenTextures = [] - - my_mesh.fbxArm = armob # replace with my_object_generic armature instance later - my_mesh.fbxBoneParent = blenParentBoneName # replace with my_bone instance later - - ob_meshes.append( my_mesh ) - - # not forgetting to free dupli_list - if ob_base.dupli_list: ob_base.free_dupli_list() - - - if EXP_ARMATURE: - # now we have the meshes, restore the rest arm position - for i, arm in enumerate(bpy.data.armatures): - arm.rest_position = ob_arms_orig_rest[i] -# arm.restPosition = ob_arms_orig_rest[i] - - if ob_arms_orig_rest: - for ob_base in bpy.data.objects: - if ob_base.type == 'ARMATURE': -# if ob_base.type == 'Armature': - ob_base.make_display_list() -# ob_base.makeDisplayList() - # This causes the makeDisplayList command to effect the mesh - sce.set_frame(sce.current_frame) -# Blender.Set('curframe', Blender.Get('curframe')) - - del tmp_ob_type, tmp_objects - - # now we have collected all armatures, add bones - for i, ob in enumerate(ob_arms): - - ob_arms[i] = my_arm = my_object_generic(ob) - - my_arm.fbxBones = [] - my_arm.blenData = ob.data - if ob.animation_data: - my_arm.blenAction = ob.animation_data.action - else: - my_arm.blenAction = None -# my_arm.blenAction = ob.action - my_arm.blenActionList = [] - - # fbxName, blenderObject, my_bones, blenderActions - #ob_arms[i] = fbxArmObName, ob, arm_my_bones, (ob.action, []) - - for bone in my_arm.blenData.bones: -# for bone in my_arm.blenData.bones.values(): - my_bone = my_bone_class(bone, my_arm) - my_arm.fbxBones.append( my_bone ) - ob_bones.append( my_bone ) - - # add the meshes to the bones and replace the meshes armature with own armature class - #for obname, ob, mtx, me, mats, arm, armname in ob_meshes: - for my_mesh in ob_meshes: - # Replace - # ...this could be sped up with dictionary mapping but its unlikely for - # it ever to be a bottleneck - (would need 100+ meshes using armatures) - if my_mesh.fbxArm: - for my_arm in ob_arms: - if my_arm.blenObject == my_mesh.fbxArm: - my_mesh.fbxArm = my_arm - break - - for my_bone in ob_bones: - - # The mesh uses this bones armature! - if my_bone.fbxArm == my_mesh.fbxArm: - my_bone.blenMeshes[my_mesh.fbxName] = me - - - # parent bone: replace bone names with our class instances - # my_mesh.fbxBoneParent is None or a blender bone name initialy, replacing if the names match. - if my_mesh.fbxBoneParent == my_bone.blenName: - my_mesh.fbxBoneParent = my_bone - - bone_deformer_count = 0 # count how many bones deform a mesh - my_bone_blenParent = None - for my_bone in ob_bones: - my_bone_blenParent = my_bone.blenBone.parent - if my_bone_blenParent: - for my_bone_parent in ob_bones: - # Note 2.45rc2 you can compare bones normally - if my_bone_blenParent.name == my_bone_parent.blenName and my_bone.fbxArm == my_bone_parent.fbxArm: - my_bone.parent = my_bone_parent - break - - # Not used at the moment - # my_bone.calcRestMatrixLocal() - bone_deformer_count += len(my_bone.blenMeshes) - - del my_bone_blenParent - - - # Build blenObject -> fbxObject mapping - # this is needed for groups as well as fbxParenting -# for ob in bpy.data.objects: ob.tag = False -# bpy.data.objects.tag = False - - # using a list of object names for tagging (Arystan) - tagged_objects = [] - - tmp_obmapping = {} - for ob_generic in ob_all_typegroups: - for ob_base in ob_generic: - tagged_objects.append(ob_base.blenObject.name) -# ob_base.blenObject.tag = True - tmp_obmapping[ob_base.blenObject] = ob_base - - # Build Groups from objects we export - for blenGroup in bpy.data.groups: - fbxGroupName = None - for ob in blenGroup.objects: - if ob.name in tagged_objects: -# if ob.tag: - if fbxGroupName == None: - fbxGroupName = sane_groupname(blenGroup) - groups.append((fbxGroupName, blenGroup)) - - tmp_obmapping[ob].fbxGroupNames.append(fbxGroupName) # also adds to the objects fbxGroupNames - - groups.sort() # not really needed - - # Assign parents using this mapping - for ob_generic in ob_all_typegroups: - for my_ob in ob_generic: - parent = my_ob.blenObject.parent - if parent and parent.name in tagged_objects: # does it exist and is it in the mapping -# if parent and parent.tag: # does it exist and is it in the mapping - my_ob.fbxParent = tmp_obmapping[parent] - - - del tmp_obmapping - # Finished finding groups we use - - - materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.keys()] - textures = [(sane_texname(tex), tex) for tex in textures.keys() if tex] - materials.sort() # sort by name - textures.sort() - - camera_count = 8 - file.write(''' - -; Object definitions -;------------------------------------------------------------------ - -Definitions: { - Version: 100 - Count: %i''' % (\ - 1+1+camera_count+\ - len(ob_meshes)+\ - len(ob_lights)+\ - len(ob_cameras)+\ - len(ob_arms)+\ - len(ob_null)+\ - len(ob_bones)+\ - bone_deformer_count+\ - len(materials)+\ - (len(textures)*2))) # add 1 for the root model 1 for global settings - - del bone_deformer_count - - file.write(''' - ObjectType: "Model" { - Count: %i - }''' % (\ - 1+camera_count+\ - len(ob_meshes)+\ - len(ob_lights)+\ - len(ob_cameras)+\ - len(ob_arms)+\ - len(ob_null)+\ - len(ob_bones))) # add 1 for the root model - - file.write(''' - ObjectType: "Geometry" { - Count: %i - }''' % len(ob_meshes)) - - if materials: - file.write(''' - ObjectType: "Material" { - Count: %i - }''' % len(materials)) - - if textures: - file.write(''' - ObjectType: "Texture" { - Count: %i - }''' % len(textures)) # add 1 for an empty tex - file.write(''' - ObjectType: "Video" { - Count: %i - }''' % len(textures)) # add 1 for an empty tex - - tmp = 0 - # Add deformer nodes - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - tmp+=1 - - # Add subdeformers - for my_bone in ob_bones: - tmp += len(my_bone.blenMeshes) - - if tmp: - file.write(''' - ObjectType: "Deformer" { - Count: %i - }''' % tmp) - del tmp - - # we could avoid writing this possibly but for now just write it - - file.write(''' - ObjectType: "Pose" { - Count: 1 - }''') - - if groups: - file.write(''' - ObjectType: "GroupSelection" { - Count: %i - }''' % len(groups)) - - file.write(''' - ObjectType: "GlobalSettings" { - Count: 1 - } -}''') - - file.write(''' - -; Object properties -;------------------------------------------------------------------ - -Objects: {''') - - # To comply with other FBX FILES - write_camera_switch() - - # Write the null object - write_null(None, 'blend_root')# , GLOBAL_MATRIX) - - for my_null in ob_null: - write_null(my_null) - - for my_arm in ob_arms: - write_null(my_arm) - - for my_cam in ob_cameras: - write_camera(my_cam) - - for my_light in ob_lights: - write_light(my_light) - - for my_mesh in ob_meshes: - write_mesh(my_mesh) - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - write_bone(my_bone) - - write_camera_default() - - for matname, (mat, tex) in materials: - write_material(matname, mat) # We only need to have a material per image pair, but no need to write any image info into the material (dumb fbx standard) - - # each texture uses a video, odd - for texname, tex in textures: - write_video(texname, tex) - i = 0 - for texname, tex in textures: - write_texture(texname, tex, i) - i+=1 - - for groupname, group in groups: - write_group(groupname) - - # NOTE - c4d and motionbuilder dont need normalized weights, but deep-exploration 5 does and (max?) do. - - # Write armature modifiers - # TODO - add another MODEL? - because of this skin definition. - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - write_deformer_skin(my_mesh.fbxName) - - # Get normalized weights for temorary use - if my_mesh.fbxBoneParent: - weights = None - else: - weights = meshNormalizedWeights(my_mesh.blenObject) -# weights = meshNormalizedWeights(my_mesh.blenData) - - #for bonename, bone, obname, bone_mesh, armob in ob_bones: - for my_bone in ob_bones: - if me in iter(my_bone.blenMeshes.values()): - write_sub_deformer_skin(my_mesh, my_bone, weights) - - # Write pose's really weired, only needed when an armature and mesh are used together - # each by themselves dont need pose data. for now only pose meshes and bones - - file.write(''' - Pose: "Pose::BIND_POSES", "BindPose" { - Type: "BindPose" - Version: 100 - Properties60: { - } - NbPoseNodes: ''') - file.write(str(len(pose_items))) - - - for fbxName, matrix in pose_items: - file.write('\n\t\tPoseNode: {') - file.write('\n\t\t\tNode: "Model::%s"' % fbxName ) - if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix)) - else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity)) - file.write('\n\t\t}') - - file.write('\n\t}') - - - # Finish Writing Objects - # Write global settings - file.write(''' - GlobalSettings: { - Version: 1000 - Properties60: { - Property: "UpAxis", "int", "",1 - Property: "UpAxisSign", "int", "",1 - Property: "FrontAxis", "int", "",2 - Property: "FrontAxisSign", "int", "",1 - Property: "CoordAxis", "int", "",0 - Property: "CoordAxisSign", "int", "",1 - Property: "UnitScaleFactor", "double", "",100 - } - } -''') - file.write('}') - - file.write(''' - -; Object relations -;------------------------------------------------------------------ - -Relations: {''') - - file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}') - - for my_null in ob_null: - file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_null.fbxName) - - for my_arm in ob_arms: - file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_arm.fbxName) - - for my_mesh in ob_meshes: - file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % my_mesh.fbxName) - - # TODO - limbs can have the same name for multiple armatures, should prefix. - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - file.write('\n\tModel: "Model::%s", "Limb" {\n\t}' % my_bone.fbxName) - - for my_cam in ob_cameras: - file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % my_cam.fbxName) - - for my_light in ob_lights: - file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % my_light.fbxName) - - file.write(''' - Model: "Model::Producer Perspective", "Camera" { - } - Model: "Model::Producer Top", "Camera" { - } - Model: "Model::Producer Bottom", "Camera" { - } - Model: "Model::Producer Front", "Camera" { - } - Model: "Model::Producer Back", "Camera" { - } - Model: "Model::Producer Right", "Camera" { - } - Model: "Model::Producer Left", "Camera" { - } - Model: "Model::Camera Switcher", "CameraSwitcher" { - }''') - - for matname, (mat, tex) in materials: - file.write('\n\tMaterial: "Material::%s", "" {\n\t}' % matname) - - if textures: - for texname, tex in textures: - file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {\n\t}' % texname) - for texname, tex in textures: - file.write('\n\tVideo: "Video::%s", "Clip" {\n\t}' % texname) - - # deformers - modifiers - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {\n\t}' % my_mesh.fbxName) - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - for fbxMeshObName in my_bone.blenMeshes: # .keys() - fbxMeshObName - # is this bone effecting a mesh? - file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {\n\t}' % (fbxMeshObName, my_bone.fbxName)) - - # This should be at the end - # file.write('\n\tPose: "Pose::BIND_POSES", "BindPose" {\n\t}') - - for groupname, group in groups: - file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {\n\t}' % groupname) - - file.write('\n}') - file.write(''' - -; Object connections -;------------------------------------------------------------------ - -Connections: {''') - - # NOTE - The FBX SDK dosnt care about the order but some importers DO! - # for instance, defining the material->mesh connection - # before the mesh->blend_root crashes cinema4d - - - # write the fake root node - file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"') - - for ob_generic in ob_all_typegroups: # all blender 'Object's we support - for my_ob in ob_generic: - if my_ob.fbxParent: - file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_ob.fbxName, my_ob.fbxParent.fbxName)) - else: - file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_ob.fbxName) - - if materials: - for my_mesh in ob_meshes: - # Connect all materials to all objects, not good form but ok for now. - for mat, tex in my_mesh.blenMaterials: - if mat: mat_name = mat.name - else: mat_name = None - - if tex: tex_name = tex.name - else: tex_name = None - - file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat_name, tex_name], my_mesh.fbxName)) - - if textures: - for my_mesh in ob_meshes: - if my_mesh.blenTextures: - # file.write('\n\tConnect: "OO", "Texture::_empty_", "Model::%s"' % my_mesh.fbxName) - for tex in my_mesh.blenTextures: - if tex: - file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (sane_name_mapping_tex[tex.name], my_mesh.fbxName)) - - for texname, tex in textures: - file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname)) - - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName)) - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - for fbxMeshObName in my_bone.blenMeshes: # .keys() - file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName)) - - # limbs -> deformers - # for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - for fbxMeshObName in my_bone.blenMeshes: # .keys() - file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName)) - - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - # Always parent to armature now - if my_bone.parent: - file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.parent.fbxName) ) - else: - # the armature object is written as an empty and all root level bones connect to it - file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.fbxArm.fbxName) ) - - # groups - if groups: - for ob_generic in ob_all_typegroups: - for ob_base in ob_generic: - for fbxGroupName in ob_base.fbxGroupNames: - file.write('\n\tConnect: "OO", "Model::%s", "GroupSelection::%s"' % (ob_base.fbxName, fbxGroupName)) - - for my_arm in ob_arms: - file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_arm.fbxName) - - file.write('\n}') - - - # Needed for scene footer as well as animation - render = sce.render_data -# render = sce.render - - # from the FBX sdk - #define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000)) - def fbx_time(t): - # 0.5 + val is the same as rounding. - return int(0.5 + ((t/fps) * 46186158000)) - - fps = float(render.fps) - start = sce.start_frame -# start = render.sFrame - end = sce.end_frame -# end = render.eFrame - if end < start: start, end = end, start - if start==end: ANIM_ENABLE = False - - # animations for these object types - ob_anim_lists = ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms - - if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]: - - frame_orig = sce.current_frame -# frame_orig = Blender.Get('curframe') - - if ANIM_OPTIMIZE: - ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION - - # default action, when no actions are avaioable - tmp_actions = [None] # None is the default action - blenActionDefault = None - action_lastcompat = None - - # instead of tagging - tagged_actions = [] - - if ANIM_ACTION_ALL: -# bpy.data.actions.tag = False - tmp_actions = list(bpy.data.actions) - - - # find which actions are compatible with the armatures - # blenActions is not yet initialized so do it now. - tmp_act_count = 0 - for my_arm in ob_arms: - - # get the default name - if not blenActionDefault: - blenActionDefault = my_arm.blenAction - - arm_bone_names = set([my_bone.blenName for my_bone in my_arm.fbxBones]) - - for action in tmp_actions: - - action_chan_names = arm_bone_names.intersection( set([g.name for g in action.groups]) ) -# action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) ) - - if action_chan_names: # at least one channel matches. - my_arm.blenActionList.append(action) - tagged_actions.append(action.name) -# action.tag = True - tmp_act_count += 1 - - # incase there is no actions applied to armatures - action_lastcompat = action - - if tmp_act_count: - # unlikely to ever happen but if no actions applied to armatures, just use the last compatible armature. - if not blenActionDefault: - blenActionDefault = action_lastcompat - - del action_lastcompat - - file.write(''' -;Takes and animation section -;---------------------------------------------------- - -Takes: {''') - - if blenActionDefault: - file.write('\n\tCurrent: "%s"' % sane_takename(blenActionDefault)) - else: - file.write('\n\tCurrent: "Default Take"') - - for blenAction in tmp_actions: - # we have tagged all actious that are used be selected armatures - if blenAction: - if blenAction.name in tagged_actions: -# if blenAction.tag: - print('\taction: "%s" exporting...' % blenAction.name) - else: - print('\taction: "%s" has no armature using it, skipping' % blenAction.name) - continue - - if blenAction == None: - # Warning, this only accounts for tmp_actions being [None] - file.write('\n\tTake: "Default Take" {') - act_start = start - act_end = end - else: - # use existing name - if blenAction == blenActionDefault: # have we alredy got the name - file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name]) - else: - file.write('\n\tTake: "%s" {' % sane_takename(blenAction)) - - act_start, act_end = blenAction.get_frame_range() -# tmp = blenAction.getFrameNumbers() -# if tmp: -# act_start = min(tmp) -# act_end = max(tmp) -# del tmp -# else: -# # Fallback on this, theres not much else we can do? :/ -# # when an action has no length -# act_start = start -# act_end = end - - # Set the action active - for my_bone in ob_arms: - if blenAction in my_bone.blenActionList: - ob.action = blenAction - # print '\t\tSetting Action!', blenAction - # sce.update(1) - - file.write('\n\t\tFileName: "Default_Take.tak"') # ??? - not sure why this is needed - file.write('\n\t\tLocalTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed - file.write('\n\t\tReferenceTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed - - file.write(''' - - ;Models animation - ;----------------------------------------------------''') - - - # set pose data for all bones - # do this here incase the action changes - ''' - for my_bone in ob_bones: - my_bone.flushAnimData() - ''' - i = act_start - while i <= act_end: - sce.set_frame(i) -# Blender.Set('curframe', i) - for ob_generic in ob_anim_lists: - for my_ob in ob_generic: - #Blender.Window.RedrawAll() - if ob_generic == ob_meshes and my_ob.fbxArm: - # We cant animate armature meshes! - pass - else: - my_ob.setPoseFrame(i) - - i+=1 - - - #for bonename, bone, obname, me, armob in ob_bones: - for ob_generic in (ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms): - - for my_ob in ob_generic: - - if ob_generic == ob_meshes and my_ob.fbxArm: - # do nothing, - pass - else: - - file.write('\n\t\tModel: "Model::%s" {' % my_ob.fbxName) # ??? - not sure why this is needed - file.write('\n\t\t\tVersion: 1.1') - file.write('\n\t\t\tChannel: "Transform" {') - - context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in range(act_start, act_end+1) ] - - # ---------------- - # ---------------- - for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale - - if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats] - elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats] - elif TX_CHAN=='R': - # Was.... - # elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats] - # - # ...but we need to use the previous euler for compatible conversion. - context_bone_anim_vecs = [] - prev_eul = None - for mtx in context_bone_anim_mats: - if prev_eul: prev_eul = mtx[1].toEuler(prev_eul) - else: prev_eul = mtx[1].toEuler() - context_bone_anim_vecs.append(eulerRadToDeg(prev_eul)) -# context_bone_anim_vecs.append(prev_eul) - - file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation - - for i in range(3): - # Loop on each axis of the bone - file.write('\n\t\t\t\t\tChannel: "%s" {'% ('XYZ'[i])) # translation - file.write('\n\t\t\t\t\t\tDefault: %.15f' % context_bone_anim_vecs[0][i] ) - file.write('\n\t\t\t\t\t\tKeyVer: 4005') - - if not ANIM_OPTIMIZE: - # Just write all frames, simple but in-eficient - file.write('\n\t\t\t\t\t\tKeyCount: %i' % (1 + act_end - act_start)) - file.write('\n\t\t\t\t\t\tKey: ') - frame = act_start - while frame <= act_end: - if frame!=act_start: - file.write(',') - - # Curve types are 'C,n' for constant, 'L' for linear - # C,n is for bezier? - linear is best for now so we can do simple keyframe removal - file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) - frame+=1 - else: - # remove unneeded keys, j is the frame, needed when some frames are removed. - context_bone_anim_keys = [ (vec[i], j) for j, vec in enumerate(context_bone_anim_vecs) ] - - # last frame to fisrt frame, missing 1 frame on either side. - # removeing in a backwards loop is faster - #for j in xrange( (act_end-act_start)-1, 0, -1 ): - # j = (act_end-act_start)-1 - j = len(context_bone_anim_keys)-2 - while j > 0 and len(context_bone_anim_keys) > 2: - # print j, len(context_bone_anim_keys) - # Is this key the same as the ones next to it? - - # co-linear horizontal... - if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\ - abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: - - del context_bone_anim_keys[j] - - else: - frame_range = float(context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j-1][1]) - frame_range_fac1 = (context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j][1]) / frame_range - frame_range_fac2 = 1.0 - frame_range_fac1 - - if abs(((context_bone_anim_keys[j-1][0]*frame_range_fac1 + context_bone_anim_keys[j+1][0]*frame_range_fac2)) - context_bone_anim_keys[j][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: - del context_bone_anim_keys[j] - else: - j-=1 - - # keep the index below the list length - if j > len(context_bone_anim_keys)-2: - j = len(context_bone_anim_keys)-2 - - if len(context_bone_anim_keys) == 2 and context_bone_anim_keys[0][0] == context_bone_anim_keys[1][0]: - # This axis has no moton, its okay to skip KeyCount and Keys in this case - pass - else: - # We only need to write these if there is at least one - file.write('\n\t\t\t\t\t\tKeyCount: %i' % len(context_bone_anim_keys)) - file.write('\n\t\t\t\t\t\tKey: ') - for val, frame in context_bone_anim_keys: - if frame != context_bone_anim_keys[0][1]: # not the first - file.write(',') - # frame is alredy one less then blenders frame - file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val )) - - if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0') - elif i==1: file.write('\n\t\t\t\t\t\tColor: 0,1,0') - elif i==2: file.write('\n\t\t\t\t\t\tColor: 0,0,1') - - file.write('\n\t\t\t\t\t}') - file.write('\n\t\t\t\t\tLayerType: %i' % (TX_LAYER+1) ) - file.write('\n\t\t\t\t}') - - # --------------- - - file.write('\n\t\t\t}') - file.write('\n\t\t}') - - # end the take - file.write('\n\t}') - - # end action loop. set original actions - # do this after every loop incase actions effect eachother. - for my_bone in ob_arms: - my_bone.blenObject.action = my_bone.blenAction - - file.write('\n}') - - sce.set_frame(frame_orig) -# Blender.Set('curframe', frame_orig) - - else: - # no animation - file.write('\n;Takes and animation section') - file.write('\n;----------------------------------------------------') - file.write('\n') - file.write('\nTakes: {') - file.write('\n\tCurrent: ""') - file.write('\n}') - - - # write meshes animation - #for obname, ob, mtx, me, mats, arm, armname in ob_meshes: - - - # Clear mesh data Only when writing with modifiers applied - for me in meshes_to_clear: - bpy.data.remove_mesh(me) -# me.verts = None - - # --------------------------- Footer - if world: - m = world.mist - has_mist = m.enabled -# has_mist = world.mode & 1 - mist_intense = m.intensity - mist_start = m.start - mist_end = m.depth - mist_height = m.height -# mist_intense, mist_start, mist_end, mist_height = world.mist - world_hor = world.horizon_color -# world_hor = world.hor - else: - has_mist = mist_intense = mist_start = mist_end = mist_height = 0 - world_hor = 0,0,0 - - file.write('\n;Version 5 settings') - file.write('\n;------------------------------------------------------------------') - file.write('\n') - file.write('\nVersion5: {') - file.write('\n\tAmbientRenderSettings: {') - file.write('\n\t\tVersion: 101') - file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world_amb)) - file.write('\n\t}') - file.write('\n\tFogOptions: {') - file.write('\n\t\tFlogEnable: %i' % has_mist) - file.write('\n\t\tFogMode: 0') - file.write('\n\t\tFogDensity: %.3f' % mist_intense) - file.write('\n\t\tFogStart: %.3f' % mist_start) - file.write('\n\t\tFogEnd: %.3f' % mist_end) - file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world_hor)) - file.write('\n\t}') - file.write('\n\tSettings: {') - file.write('\n\t\tFrameRate: "%i"' % int(fps)) - file.write('\n\t\tTimeFormat: 1') - file.write('\n\t\tSnapOnFrames: 0') - file.write('\n\t\tReferenceTimeIndex: -1') - file.write('\n\t\tTimeLineStartTime: %i' % fbx_time(start-1)) - file.write('\n\t\tTimeLineStopTime: %i' % fbx_time(end-1)) - file.write('\n\t}') - file.write('\n\tRendererSetting: {') - file.write('\n\t\tDefaultCamera: "Producer Perspective"') - file.write('\n\t\tDefaultViewingMode: 0') - file.write('\n\t}') - file.write('\n}') - file.write('\n') - - # Incase sombody imports this, clean up by clearing global dicts - sane_name_mapping_ob.clear() - sane_name_mapping_mat.clear() - sane_name_mapping_tex.clear() - - ob_arms[:] = [] - ob_bones[:] = [] - ob_cameras[:] = [] - ob_lights[:] = [] - ob_meshes[:] = [] - ob_null[:] = [] - - - # copy images if enabled -# if EXP_IMAGE_COPY: -# # copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) -# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath) - - print('export finished in %.4f sec.' % (time.clock() - start_time)) -# print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) - return True - - -# -------------------------------------------- -# UI Function - not a part of the exporter. -# this is to seperate the user interface from the rest of the exporter. -# from Blender import Draw, Window -EVENT_NONE = 0 -EVENT_EXIT = 1 -EVENT_REDRAW = 2 -EVENT_FILESEL = 3 - -GLOBALS = {} - -# export opts - -def do_redraw(e,v): GLOBALS['EVENT'] = e - -# toggle between these 2, only allow one on at once -def do_obs_sel(e,v): - GLOBALS['EVENT'] = e - GLOBALS['EXP_OBS_SCENE'].val = 0 - GLOBALS['EXP_OBS_SELECTED'].val = 1 - -def do_obs_sce(e,v): - GLOBALS['EVENT'] = e - GLOBALS['EXP_OBS_SCENE'].val = 1 - GLOBALS['EXP_OBS_SELECTED'].val = 0 - -def do_batch_type_grp(e,v): - GLOBALS['EVENT'] = e - GLOBALS['BATCH_GROUP'].val = 1 - GLOBALS['BATCH_SCENE'].val = 0 - -def do_batch_type_sce(e,v): - GLOBALS['EVENT'] = e - GLOBALS['BATCH_GROUP'].val = 0 - GLOBALS['BATCH_SCENE'].val = 1 - -def do_anim_act_all(e,v): - GLOBALS['EVENT'] = e - GLOBALS['ANIM_ACTION_ALL'][0].val = 1 - GLOBALS['ANIM_ACTION_ALL'][1].val = 0 - -def do_anim_act_cur(e,v): - if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val: - Draw.PupMenu('Warning%t|Cant use this with batch export group option') - else: - GLOBALS['EVENT'] = e - GLOBALS['ANIM_ACTION_ALL'][0].val = 0 - GLOBALS['ANIM_ACTION_ALL'][1].val = 1 - -def fbx_ui_exit(e,v): - GLOBALS['EVENT'] = e - -def do_help(e,v): - url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' - print('Trying to open web browser with documentation at this address...') - print('\t' + url) - - try: - import webbrowser - webbrowser.open(url) - except: - Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation") - print('...could not open a browser window.') - - - -# run when export is pressed -#def fbx_ui_write(e,v): -def fbx_ui_write(filename, context): - - # Dont allow overwriting files when saving normally - if not GLOBALS['BATCH_ENABLE'].val: - if not BPyMessages.Warning_SaveOver(filename): - return - - GLOBALS['EVENT'] = EVENT_EXIT - - # Keep the order the same as above for simplicity - # the [] is a dummy arg used for objects - - Blender.Window.WaitCursor(1) - - # Make the matrix - GLOBAL_MATRIX = mtx4_identity - GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val - if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n - if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n - if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n - - ret = write(\ - filename, None,\ - context, - GLOBALS['EXP_OBS_SELECTED'].val,\ - GLOBALS['EXP_MESH'].val,\ - GLOBALS['EXP_MESH_APPLY_MOD'].val,\ - GLOBALS['EXP_MESH_HQ_NORMALS'].val,\ - GLOBALS['EXP_ARMATURE'].val,\ - GLOBALS['EXP_LAMP'].val,\ - GLOBALS['EXP_CAMERA'].val,\ - GLOBALS['EXP_EMPTY'].val,\ - GLOBALS['EXP_IMAGE_COPY'].val,\ - GLOBAL_MATRIX,\ - GLOBALS['ANIM_ENABLE'].val,\ - GLOBALS['ANIM_OPTIMIZE'].val,\ - GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\ - GLOBALS['ANIM_ACTION_ALL'][0].val,\ - GLOBALS['BATCH_ENABLE'].val,\ - GLOBALS['BATCH_GROUP'].val,\ - GLOBALS['BATCH_SCENE'].val,\ - GLOBALS['BATCH_FILE_PREFIX'].val,\ - GLOBALS['BATCH_OWN_DIR'].val,\ - ) - - Blender.Window.WaitCursor(0) - GLOBALS.clear() - - if ret == False: - Draw.PupMenu('Error%t|Path cannot be written to!') - - -def fbx_ui(): - # Only to center the UI - x,y = GLOBALS['MOUSE'] - x-=180; y-=0 # offset... just to get it centered - - Draw.Label('Export Objects...', x+20,y+165, 200, 20) - - if not GLOBALS['BATCH_ENABLE'].val: - Draw.BeginAlign() - GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel) - GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce) - Draw.EndAlign() - - Draw.BeginAlign() - GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)') - GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrese about the X axis') - GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrese about the Y axis') - GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrese about the Z axis') - Draw.EndAlign() - - y -= 35 - - Draw.BeginAlign() - GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects') - GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects') - GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects') - GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects') - GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z) - Draw.EndAlign() - - if GLOBALS['EXP_MESH'].val: - # below mesh but - Draw.BeginAlign() - GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z) - GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z) - Draw.EndAlign() - - GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z) - - - Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20) - - GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw) - if GLOBALS['ANIM_ENABLE'].val: - Draw.BeginAlign() - GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw) - if GLOBALS['ANIM_OPTIMIZE'].val: - GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)') - Draw.EndAlign() - - Draw.BeginAlign() - GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur) - GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all) - Draw.EndAlign() - - - Draw.Label('Export Batch...', x+20,y-60, 300, 20) - GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw) - - if GLOBALS['BATCH_ENABLE'].val: - Draw.BeginAlign() - GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp) - GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce) - - # Own dir requires OS module - if os: - GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file') - GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') - else: - GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') - - - Draw.EndAlign() - - #y+=80 - - ''' - Draw.BeginAlign() - GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ') - Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw) - ''' - # Until batch is added - # - - - #Draw.BeginAlign() - Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help) - Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit) - Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw) - - #Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write) - #Draw.EndAlign() - - # exit when mouse out of the view? - # GLOBALS['EVENT'] = EVENT_EXIT - -#def write_ui(filename): -def write_ui(): - - # globals - GLOBALS['EVENT'] = EVENT_REDRAW - #GLOBALS['MOUSE'] = Window.GetMouseCoords() - GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] - GLOBALS['FILENAME'] = '' - ''' - # IF called from the fileselector - if filename == None: - GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx')) - else: - GLOBALS['FILENAME'].val = filename - ''' - GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity - GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0) - - GLOBALS['EXP_MESH'] = Draw.Create(1) - GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1) - GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0) - GLOBALS['EXP_ARMATURE'] = Draw.Create(1) - GLOBALS['EXP_LAMP'] = Draw.Create(1) - GLOBALS['EXP_CAMERA'] = Draw.Create(1) - GLOBALS['EXP_EMPTY'] = Draw.Create(1) - GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0) - # animation opts - GLOBALS['ANIM_ENABLE'] = Draw.Create(1) - GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1) - GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places - GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action - - # batch export options - GLOBALS['BATCH_ENABLE'] = Draw.Create(0) - GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once. - GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above - GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1]) - GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0) - # done setting globals - - # Used by the user interface - GLOBALS['_SCALE'] = Draw.Create(1.0) - GLOBALS['_XROT90'] = Draw.Create(True) - GLOBALS['_YROT90'] = Draw.Create(False) - GLOBALS['_ZROT90'] = Draw.Create(False) - - # best not do move the cursor - # Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()]) - - # hack so the toggle buttons redraw. this is not nice at all - while GLOBALS['EVENT'] != EVENT_EXIT: - - if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val: - #Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ") - GLOBALS['ANIM_ACTION_ALL'][0].val = 1 - GLOBALS['ANIM_ACTION_ALL'][1].val = 0 - - if GLOBALS['EVENT'] == EVENT_FILESEL: - if GLOBALS['BATCH_ENABLE'].val: - txt = 'Batch FBX Dir' - name = Blender.sys.expandpath('//') - else: - txt = 'Export FBX' - name = Blender.sys.makename(ext='.fbx') - - Blender.Window.FileSelector(fbx_ui_write, txt, name) - #fbx_ui_write('/test.fbx') - break - - Draw.UIBlock(fbx_ui, 0) - - - # GLOBALS.clear() - -class EXPORT_OT_fbx(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' - __idname__ = "export.fbx" - __label__ = "Export FBX" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default=""), - bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True), -# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True), - bpy.props.FloatProperty(attr="_SCALE", name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0), - bpy.props.BoolProperty(attr="_XROT90", name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True), - bpy.props.BoolProperty(attr="_YROT90", name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False), - bpy.props.BoolProperty(attr="_ZROT90", name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False), - bpy.props.BoolProperty(attr="EXP_EMPTY", name="Empties", description="Export empty objects", default=True), - bpy.props.BoolProperty(attr="EXP_CAMERA", name="Cameras", description="Export camera objects", default=True), - bpy.props.BoolProperty(attr="EXP_LAMP", name="Lamps", description="Export lamp objects", default=True), - bpy.props.BoolProperty(attr="EXP_ARMATURE", name="Armatures", description="Export armature objects", default=True), - bpy.props.BoolProperty(attr="EXP_MESH", name="Meshes", description="Export mesh objects", default=True), - bpy.props.BoolProperty(attr="EXP_MESH_APPLY_MOD", name="Modifiers", description="Apply modifiers to mesh objects", default=True), - bpy.props.BoolProperty(attr="EXP_MESH_HQ_NORMALS", name="HQ Normals", description="Generate high quality normals", default=True), - bpy.props.BoolProperty(attr="EXP_IMAGE_COPY", name="Copy Image Files", description="Copy image files to the destination path", default=False), - # armature animation - bpy.props.BoolProperty(attr="ANIM_ENABLE", name="Enable Animation", description="Export keyframe animation", default=True), - bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True), - bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0), -# bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True), - bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures, if false, use current action", default=False), - # batch - bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False), - bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False), - bpy.props.BoolProperty(attr="BATCH_OWN_DIR", name="Own Dir", description="Create a dir for each exported file", default=True), - bpy.props.StringProperty(attr="BATCH_FILE_PREFIX", name="Prefix", description="Prefix each file with this name", maxlen= 1024, default=""), - ] - - def poll(self, context): - print("Poll") - return context.active_object != None - - def execute(self, context): - if not self.filename: - raise Exception("filename not set") - - GLOBAL_MATRIX = mtx4_identity - GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self._SCALE - if self._XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n - if self._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n - if self._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n - - write(self.filename, - None, # XXX - context, - self.EXP_OBS_SELECTED, - self.EXP_MESH, - self.EXP_MESH_APPLY_MOD, -# self.EXP_MESH_HQ_NORMALS, - self.EXP_ARMATURE, - self.EXP_LAMP, - self.EXP_CAMERA, - self.EXP_EMPTY, - self.EXP_IMAGE_COPY, - GLOBAL_MATRIX, - self.ANIM_ENABLE, - self.ANIM_OPTIMIZE, - self.ANIM_OPTIMIZE_PRECISSION, - self.ANIM_ACTION_ALL, - self.BATCH_ENABLE, - self.BATCH_GROUP, - self.BATCH_FILE_PREFIX, - self.BATCH_OWN_DIR) - - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - - -bpy.ops.add(EXPORT_OT_fbx) - -# if __name__ == "__main__": -# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply") - - -# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts) -# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print -# - get rid of cleanName somehow -# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 -# + get rid of BPyObject_getObjectArmature, move it in RNA? -# - BATCH_ENABLE and BATCH_GROUP options: line 327 -# - implement all BPyMesh_* used here with RNA -# - getDerivedObjects is not fully replicated with .dupli* funcs -# - talk to Campbell, this code won't work? lines 1867-1875 -# - don't know what those colbits are, do we need them? they're said to be deprecated in DNA_object_types.h: 1886-1893 -# - no hq normals: 1900-1901 - -# TODO - -# - bpy.data.remove_scene: line 366 -# - bpy.sys.time move to bpy.sys.util? -# - new scene creation, activation: lines 327-342, 368 -# - uses bpy.sys.expandpath, *.relpath - replace at least relpath - -# SMALL or COSMETICAL -# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version') diff --git a/release/io/export_obj.py b/release/io/export_obj.py deleted file mode 100644 index e2ac78798bd..00000000000 --- a/release/io/export_obj.py +++ /dev/null @@ -1,993 +0,0 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 248 -Group: 'Export' -Tooltip: 'Save a Wavefront OBJ File' -""" - -__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone" -__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] -__version__ = "1.21" - -__bpydoc__ = """\ -This script is an exporter to OBJ file format. - -Usage: - -Select the objects you wish to export and run this script from "File->Export" menu. -Selecting the default options from the popup box will be good in most cases. -All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) -will be exported as mesh data. -""" - - -# -------------------------------------------------------------------------- -# OBJ Export v1.1 by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -# import math and other in functions that use them for the sake of fast Blender startup -# import math -import os -import time - -import bpy -import Mathutils - - -# Returns a tuple - path,extension. -# 'hello.obj' > ('hello', '.obj') -def splitExt(path): - dotidx = path.rfind('.') - if dotidx == -1: - return path, '' - else: - return path[:dotidx], path[dotidx:] - -def fixName(name): - if name == None: - return 'None' - else: - return name.replace(' ', '_') - - -# this used to be in BPySys module -# frankly, I don't understand how it works -def BPySys_cleanName(name): - - v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] - - invalid = ''.join([chr(i) for i in v]) - - for ch in invalid: - name = name.replace(ch, '_') - return name - -# A Dict of Materials -# (material.name, image.name):matname_imagename # matname_imagename has gaps removed. -MTL_DICT = {} - -def write_mtl(scene, filename, copy_images): - - world = scene.world - worldAmb = world.ambient_color - - dest_dir = os.path.dirname(filename) - - def copy_image(image): - rel = image.get_export_path(dest_dir, True) - - if copy_images: - abspath = image.get_export_path(dest_dir, False) - if not os.path.exists(abs_path): - shutil.copy(image.get_abs_filename(), abs_path) - - return rel - - - file = open(filename, "w") - # XXX -# file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) - file.write('# Material Count: %i\n' % len(MTL_DICT)) - # Write material/image combinations we have used. - for key, (mtl_mat_name, mat, img) in MTL_DICT.items(): - - # Get the Blender data for the material and the image. - # Having an image named None will make a bug, dont do it :) - - file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname - - if mat: - file.write('Ns %.6f\n' % ((mat.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's - file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_intensity for c in mat.diffuse_color]) ) # Diffuse - file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_intensity for c in mat.specular_color]) ) # Specular - if hasattr(mat, "ior"): - file.write('Ni %.6f\n' % mat.ior) # Refraction index - else: - file.write('Ni %.6f\n' % 1.0) - file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) - - # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. - if mat.shadeless: - file.write('illum 0\n') # ignore lighting - elif mat.specular_intensity == 0: - file.write('illum 1\n') # no specular. - else: - file.write('illum 2\n') # light normaly - - else: - #write a dummy material here? - file.write('Ns 0\n') - file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd 0.8 0.8 0.8\n') - file.write('Ks 0.8 0.8 0.8\n') - file.write('d 1\n') # No alpha - file.write('illum 2\n') # light normaly - - # Write images! - if img: # We have an image on the face! - # write relative image path - rel = copy_image(img) - file.write('map_Kd %s\n' % rel) # Diffuse mapping image -# file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image - - elif mat: # No face image. if we havea material search for MTex image. - for mtex in mat.textures: - if mtex and mtex.texure.type == 'IMAGE': - try: - filename = copy_image(mtex.texture.image) -# filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1] - file.write('map_Kd %s\n' % filename) # Diffuse mapping image - break - except: - # Texture has no image though its an image type, best ignore. - pass - - file.write('\n\n') - - file.close() - -# XXX not used -def copy_file(source, dest): - file = open(source, 'rb') - data = file.read() - file.close() - - file = open(dest, 'wb') - file.write(data) - file.close() - - -# XXX not used -def copy_images(dest_dir): - if dest_dir[-1] != os.sep: - dest_dir += os.sep -# if dest_dir[-1] != sys.sep: -# dest_dir += sys.sep - - # Get unique image names - uniqueImages = {} - for matname, mat, image in MTL_DICT.values(): # Only use image name - # Get Texface images - if image: - uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default. - - # Get MTex images - if mat: - for mtex in mat.textures: - if mtex and mtex.texture.type == 'IMAGE': - image_tex = mtex.texture.image - if image_tex: - try: - uniqueImages[image_tex] = image_tex - except: - pass - - # Now copy images - copyCount = 0 - -# for bImage in uniqueImages.values(): -# image_path = bpy.sys.expandpath(bImage.filename) -# if bpy.sys.exists(image_path): -# # Make a name for the target path. -# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] -# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there -# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) -# copy_file(image_path, dest_image_path) -# copyCount+=1 - -# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir) - - print('\tCopied %d images' % copyCount) -# print('\tCopied %d images' % copyCount) - -# XXX not converted -def test_nurbs_compat(ob): - if ob.type != 'Curve': - return False - - for nu in ob.data: - if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier - return True - - return False - - -# XXX not converted -def write_nurb(file, ob, ob_mat): - tot_verts = 0 - cu = ob.data - - # use negative indices - Vector = Blender.Mathutils.Vector - for nu in cu: - - if nu.type==0: DEG_ORDER_U = 1 - else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct - - if nu.type==1: - print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported") - continue - - if nu.knotsV: - print("\tWarning, surface:", ob.name, "only poly and nurbs curves supported") - continue - - if len(nu) <= DEG_ORDER_U: - print("\tWarning, orderU is lower then vert count, skipping:", ob.name) - continue - - pt_num = 0 - do_closed = (nu.flagU & 1) - do_endpoints = (do_closed==0) and (nu.flagU & 2) - - for pt in nu: - pt = Vector(pt[0], pt[1], pt[2]) * ob_mat - file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2])) - pt_num += 1 - tot_verts += pt_num - - file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too - file.write('cstype bspline\n') # not ideal, hard coded - file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still - - curve_ls = [-(i+1) for i in range(pt_num)] - - # 'curv' keyword - if do_closed: - if DEG_ORDER_U == 1: - pt_num += 1 - curve_ls.append(-1) - else: - pt_num += DEG_ORDER_U - curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U] - - file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve - - # 'parm' keyword - tot_parm = (DEG_ORDER_U + 1) + pt_num - tot_parm_div = float(tot_parm-1) - parm_ls = [(i/tot_parm_div) for i in range(tot_parm)] - - if do_endpoints: # end points, force param - for i in range(DEG_ORDER_U+1): - parm_ls[i] = 0.0 - parm_ls[-(1+i)] = 1.0 - - file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] )) - - file.write('end\n') - - return tot_verts - -def write(filename, objects, scene, - EXPORT_TRI=False, - EXPORT_EDGES=False, - EXPORT_NORMALS=False, - EXPORT_NORMALS_HQ=False, - EXPORT_UV=True, - EXPORT_MTL=True, - EXPORT_COPY_IMAGES=False, - EXPORT_APPLY_MODIFIERS=True, - EXPORT_ROTX90=True, - EXPORT_BLEN_OBS=True, - EXPORT_GROUP_BY_OB=False, - EXPORT_GROUP_BY_MAT=False, - EXPORT_KEEP_VERT_ORDER=False, - EXPORT_POLYGROUPS=False, - EXPORT_CURVE_AS_NURBS=True): - ''' - Basic write function. The context and options must be alredy set - This can be accessed externaly - eg. - write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. - ''' - - # XXX - import math - - def veckey3d(v): - return round(v.x, 6), round(v.y, 6), round(v.z, 6) - - def veckey2d(v): - return round(v.x, 6), round(v.y, 6) - - def findVertexGroupName(face, vWeightMap): - """ - Searches the vertexDict to see what groups is assigned to a given face. - We use a frequency system in order to sort out the name because a given vetex can - belong to two or more groups at the same time. To find the right name for the face - we list all the possible vertex group names with their frequency and then sort by - frequency in descend order. The top element is the one shared by the highest number - of vertices is the face's group - """ - weightDict = {} - for vert_index in face.verts: -# for vert in face: - vWeights = vWeightMap[vert_index] -# vWeights = vWeightMap[vert] - for vGroupName, weight in vWeights: - weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight - - if weightDict: - alist = [(weight,vGroupName) for vGroupName, weight in weightDict.items()] # sort least to greatest amount of weight - alist.sort() - return(alist[-1][1]) # highest value last - else: - return '(null)' - - # TODO: implement this in C? dunno how it should be called... - def getVertsFromGroup(me, group_index): - ret = [] - - for i, v in enumerate(me.verts): - for g in v.groups: - if g.group == group_index: - ret.append((i, g.weight)) - - return ret - - - print('OBJ Export path: "%s"' % filename) - temp_mesh_name = '~tmp-mesh' - - time1 = time.clock() -# time1 = sys.time() -# scn = Scene.GetCurrent() - - file = open(filename, "w") - - # Write Header - version = "2.5" - file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] )) - file.write('# www.blender3d.org\n') - - # Tell the obj file what material file to use. - if EXPORT_MTL: - mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) - file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) - - if EXPORT_ROTX90: - mat_xrot90= Mathutils.RotationMatrix(-math.pi/2, 4, 'x') - - # Initialize totals, these are updated each object - totverts = totuvco = totno = 1 - - face_vert_index = 1 - - globalNormals = {} - - # Get all meshes - for ob_main in objects: - - # ignore dupli children - if ob_main.parent and ob_main.parent.dupli_type != 'NONE': - # XXX - print(ob_main.name, 'is a dupli child - ignoring') - continue - - obs = [] - if ob_main.dupli_type != 'NONE': - # XXX - print('creating dupli_list on', ob_main.name) - ob_main.create_dupli_list() - - obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list] - - # XXX debug print - print(ob_main.name, 'has', len(obs), 'dupli children') - else: - obs = [(ob_main, ob_main.matrix)] - - for ob, ob_mat in obs: - - # XXX postponed -# # Nurbs curve support -# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): -# if EXPORT_ROTX90: -# ob_mat = ob_mat * mat_xrot90 - -# totverts += write_nurb(file, ob, ob_mat) - -# continue -# end nurbs - - if ob.type != 'MESH': - continue - - me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW') - - if EXPORT_ROTX90: - me.transform(ob_mat * mat_xrot90) - else: - me.transform(ob_mat) - -# # Will work for non meshes now! :) -# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) -# if not me: -# continue - - if EXPORT_UV: - faceuv = len(me.uv_textures) > 0 - else: - faceuv = False - - # XXX - todo, find a better way to do triangulation - # ...removed convert_to_triface because it relies on editmesh - ''' - # We have a valid mesh - if EXPORT_TRI and me.faces: - # Add a dummy object to it. - has_quads = False - for f in me.faces: - if f.verts[3] != 0: - has_quads = True - break - - if has_quads: - newob = bpy.data.add_object('MESH', 'temp_object') - newob.data = me - # if we forget to set Object.data - crash - scene.add_object(newob) - newob.convert_to_triface(scene) - # mesh will still be there - scene.remove_object(newob) - ''' - - # Make our own list so it can be sorted to reduce context switching - face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)] - # faces = [ f for f in me.faces ] - - if EXPORT_EDGES: - edges = me.edges - else: - edges = [] - - if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write - - # clean up - bpy.data.remove_mesh(me) - - continue # dont bother with this mesh. - - # XXX - # High Quality Normals - if EXPORT_NORMALS and face_index_pairs: - me.calc_normals() -# if EXPORT_NORMALS_HQ: -# BPyMesh.meshCalcNormals(me) -# else: -# # transforming normals is incorrect -# # when the matrix is scaled, -# # better to recalculate them -# me.calcNormals() - - materials = me.materials - - materialNames = [] - materialItems = [m for m in materials] - if materials: - for mat in materials: - if mat: # !=None - materialNames.append(mat.name) - else: - materialNames.append(None) - # Cant use LC because some materials are None. - # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. - - # Possible there null materials, will mess up indicies - # but at least it will export, wait until Blender gets fixed. - materialNames.extend((16-len(materialNames)) * [None]) - materialItems.extend((16-len(materialItems)) * [None]) - - # Sort by Material, then images - # so we dont over context switch in the obj file. - if EXPORT_KEEP_VERT_ORDER: - pass - elif faceuv: - # XXX update - tface = me.active_uv_texture.data - - # exception only raised if Python 2.3 or lower... - try: - face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth)) - except: - face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth), - (b[0].material_index, tface[b[1]].image, b[0].smooth))) - elif len(materials) > 1: - try: - face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth)) - except: - face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth), - (b[0].material_index, b[0].smooth))) - else: - # no materials - try: - face_index_pairs.sort(key = lambda a: a[0].smooth) - except: - face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth)) -# if EXPORT_KEEP_VERT_ORDER: -# pass -# elif faceuv: -# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) -# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) -# elif len(materials) > 1: -# try: faces.sort(key = lambda a: (a.mat, a.smooth)) -# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) -# else: -# # no materials -# try: faces.sort(key = lambda a: a.smooth) -# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) - - faces = [pair[0] for pair in face_index_pairs] - - # Set the default mat to no material and no image. - contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. - contextSmooth = None # Will either be true or false, set bad to force initialization switch. - - if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: - name1 = ob.name - name2 = ob.data.name - if name1 == name2: - obnamestring = fixName(name1) - else: - obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) - - if EXPORT_BLEN_OBS: - file.write('o %s\n' % obnamestring) # Write Object name - else: # if EXPORT_GROUP_BY_OB: - file.write('g %s\n' % obnamestring) - - - # Vert - for v in me.verts: - file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) - - # UV - if faceuv: - uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ - - uv_dict = {} # could use a set() here - uv_layer = me.active_uv_texture - for f, f_index in face_index_pairs: - - tface = uv_layer.data[f_index] - - uvs = [tface.uv1, tface.uv2, tface.uv3] - - # add another UV if it's a quad - if f.verts[3] != 0: - uvs.append(tface.uv4) - - for uv_index, uv in enumerate(uvs): - uvkey = veckey2d(uv) - try: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] - except: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) - file.write('vt %.6f %.6f\n' % tuple(uv)) - -# uv_dict = {} # could use a set() here -# for f_index, f in enumerate(faces): - -# for uv_index, uv in enumerate(f.uv): -# uvkey = veckey2d(uv) -# try: -# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] -# except: -# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) -# file.write('vt %.6f %.6f\n' % tuple(uv)) - - uv_unique_count = len(uv_dict) -# del uv, uvkey, uv_dict, f_index, uv_index - # Only need uv_unique_count and uv_face_mapping - - # NORMAL, Smooth/Non smoothed. - if EXPORT_NORMALS: - for f in faces: - if f.smooth: - for v in f: - noKey = veckey3d(v.normal) - if noKey not in globalNormals: - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - else: - # Hard, 1 normal from the face. - noKey = veckey3d(f.normal) - if noKey not in globalNormals: - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - - if not faceuv: - f_image = None - - # XXX - if EXPORT_POLYGROUPS: - # Retrieve the list of vertex groups -# vertGroupNames = me.getVertGroupNames() - - currentVGroup = '' - # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to - vgroupsMap = [[] for _i in range(len(me.verts))] -# vgroupsMap = [[] for _i in xrange(len(me.verts))] - for g in ob.vertex_groups: -# for vertexGroupName in vertGroupNames: - for vIdx, vWeight in getVertsFromGroup(me, g.index): -# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): - vgroupsMap[vIdx].append((g.name, vWeight)) - - for f_index, f in enumerate(faces): - f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts] - - if f.verts[3] == 0: - f_v.pop() - -# f_v= f.v - f_smooth= f.smooth - f_mat = min(f.material_index, len(materialNames)-1) -# f_mat = min(f.mat, len(materialNames)-1) - if faceuv: - - tface = me.active_uv_texture.data[face_index_pairs[f_index][1]] - - f_image = tface.image - f_uv= [tface.uv1, tface.uv2, tface.uv3] - if f.verts[3] != 0: - f_uv.append(tface.uv4) -# f_image = f.image -# f_uv= f.uv - - # MAKE KEY - if faceuv and f_image: # Object is always true. - key = materialNames[f_mat], f_image.name - else: - key = materialNames[f_mat], None # No image, use None instead. - - # Write the vertex group - if EXPORT_POLYGROUPS: - if len(ob.vertex_groups): - # find what vertext group the face belongs to - theVGroup = findVertexGroupName(f,vgroupsMap) - if theVGroup != currentVGroup: - currentVGroup = theVGroup - file.write('g %s\n' % theVGroup) -# # Write the vertex group -# if EXPORT_POLYGROUPS: -# if vertGroupNames: -# # find what vertext group the face belongs to -# theVGroup = findVertexGroupName(f,vgroupsMap) -# if theVGroup != currentVGroup: -# currentVGroup = theVGroup -# file.write('g %s\n' % theVGroup) - - # CHECK FOR CONTEXT SWITCH - if key == contextMat: - pass # Context alredy switched, dont do anything - else: - if key[0] == None and key[1] == None: - # Write a null material, since we know the context has changed. - if EXPORT_GROUP_BY_MAT: - # can be mat_image or (null) - file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.data.name)) ) # can be mat_image or (null) - file.write('usemtl (null)\n') # mat, image - - else: - mat_data= MTL_DICT.get(key) - if not mat_data: - # First add to global dict so we can export to mtl - # Then write mtl - - # Make a new names from the mat and image name, - # converting any spaces to underscores with fixName. - - # If none image dont bother adding it to the name - if key[1] == None: - mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image - else: - mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image - - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.data.name), mat_data[0]) ) # can be mat_image or (null) - - file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) - - contextMat = key - if f_smooth != contextSmooth: - if f_smooth: # on now off - file.write('s 1\n') - contextSmooth = f_smooth - else: # was off now on - file.write('s off\n') - contextSmooth = f_smooth - - file.write('f') - if faceuv: - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % \ - (v["index"] + totverts, - totuvco + uv_face_mapping[f_index][vi], - globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal - - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.normal) ] - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % \ - (v["index"] + totverts, - totuvco + uv_face_mapping[f_index][vi], - no) ) # vert, uv, normal - else: # No Normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d' % (\ - v["index"] + totverts,\ - totuvco + uv_face_mapping[f_index][vi])) # vert, uv - - face_vert_index += len(f_v) - - else: # No UV's - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for v in f_v: - file.write( ' %d//%d' % - (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) ) - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.normal) ] - for v in f_v: - file.write( ' %d//%d' % (v["index"] + totverts, no) ) - else: # No Normals - for v in f_v: - file.write( ' %d' % (v["index"] + totverts) ) - - file.write('\n') - - # Write edges. - if EXPORT_EDGES: - for ed in edges: - if ed.loose: - file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts)) - - # Make the indicies global rather then per mesh - totverts += len(me.verts) - if faceuv: - totuvco += uv_unique_count - - # clean up - bpy.data.remove_mesh(me) - - if ob_main.dupli_type != 'NONE': - ob_main.free_dupli_list() - - file.close() - - - # Now we have all our materials, save them - if EXPORT_MTL: - write_mtl(scene, mtlfilename, EXPORT_COPY_IMAGES) -# if EXPORT_COPY_IMAGES: -# dest_dir = os.path.basename(filename) -# # dest_dir = filename -# # # Remove chars until we are just the path. -# # while dest_dir and dest_dir[-1] not in '\\/': -# # dest_dir = dest_dir[:-1] -# if dest_dir: -# copy_images(dest_dir) -# else: -# print('\tError: "%s" could not be used as a base for an image path.' % filename) - - print("OBJ Export time: %.2f" % (time.clock() - time1)) -# print "OBJ Export time: %.2f" % (sys.time() - time1) - -def do_export(filename, context, - EXPORT_APPLY_MODIFIERS = True, # not used - EXPORT_ROTX90 = True, # wrong - EXPORT_TRI = False, # ok - EXPORT_EDGES = False, - EXPORT_NORMALS = False, # not yet - EXPORT_NORMALS_HQ = False, # not yet - EXPORT_UV = True, # ok - EXPORT_MTL = True, - EXPORT_SEL_ONLY = True, # ok - EXPORT_ALL_SCENES = False, # XXX not working atm - EXPORT_ANIMATION = False, - EXPORT_COPY_IMAGES = False, - EXPORT_BLEN_OBS = True, - EXPORT_GROUP_BY_OB = False, - EXPORT_GROUP_BY_MAT = False, - EXPORT_KEEP_VERT_ORDER = False, - EXPORT_POLYGROUPS = False, - EXPORT_CURVE_AS_NURBS = True): - # Window.EditMode(0) - # Window.WaitCursor(1) - - base_name, ext = splitExt(filename) - context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension - - orig_scene = context.scene - -# if EXPORT_ALL_SCENES: -# export_scenes = bpy.data.scenes -# else: -# export_scenes = [orig_scene] - - # XXX only exporting one scene atm since changing - # current scene is not possible. - # Brecht says that ideally in 2.5 we won't need such a function, - # allowing multiple scenes open at once. - export_scenes = [orig_scene] - - # Export all scenes. - for scn in export_scenes: - # scn.makeCurrent() # If already current, this is not slow. - # context = scn.getRenderingContext() - orig_frame = scn.current_frame - - if EXPORT_ALL_SCENES: # Add scene name into the context_name - context_name[1] = '_%s' % BPySys_cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. - - # Export an animation? - if EXPORT_ANIMATION: - scene_frames = range(scn.start_frame, context.end_frame+1) # Up to and including the end frame. - else: - scene_frames = [orig_frame] # Dont export an animation. - - # Loop through all frames in the scene and export. - for frame in scene_frames: - if EXPORT_ANIMATION: # Add frame to the filename. - context_name[2] = '_%.6d' % frame - - scn.current_frame = frame - if EXPORT_SEL_ONLY: - export_objects = context.selected_objects - else: - export_objects = scn.objects - - full_path= ''.join(context_name) - - # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. - # EXPORT THE FILE. - write(full_path, export_objects, scn, - EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, - EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, - EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, - EXPORT_ROTX90, EXPORT_BLEN_OBS, - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER, - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) - - - scn.current_frame = orig_frame - - # Restore old active scene. -# orig_scene.makeCurrent() -# Window.WaitCursor(0) - - -class EXPORT_OT_obj(bpy.types.Operator): - ''' - Currently the exporter lacks these features: - * nurbs - * multiple scene export (only active scene is written) - * particles - ''' - __idname__ = "export.obj" - __label__ = 'Export OBJ' - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the OBJ file", maxlen= 1024, default= ""), - - # context group - bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False), - bpy.props.BoolProperty(attr="use_all_scenes", name="All Scenes", description="", default= False), - bpy.props.BoolProperty(attr="use_animation", name="All Animation", description="", default= False), - - # object group - bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="", default= True), - bpy.props.BoolProperty(attr="use_rotate90", name="Rotate X90", description="", default= True), - - # extra data group - bpy.props.BoolProperty(attr="use_edges", name="Edges", description="", default= True), - bpy.props.BoolProperty(attr="use_normals", name="Normals", description="", default= False), - bpy.props.BoolProperty(attr="use_hq_normals", name="High Quality Normals", description="", default= True), - bpy.props.BoolProperty(attr="use_uvs", name="UVs", description="", default= True), - bpy.props.BoolProperty(attr="use_materials", name="Materials", description="", default= True), - bpy.props.BoolProperty(attr="copy_images", name="Copy Images", description="", default= False), - bpy.props.BoolProperty(attr="use_triangles", name="Triangulate", description="", default= False), - bpy.props.BoolProperty(attr="use_vertex_groups", name="Polygroups", description="", default= False), - bpy.props.BoolProperty(attr="use_nurbs", name="Nurbs", description="", default= False), - - # grouping group - bpy.props.BoolProperty(attr="use_blen_objects", name="Objects as OBJ Objects", description="", default= True), - bpy.props.BoolProperty(attr="group_by_object", name="Objects as OBJ Groups ", description="", default= False), - bpy.props.BoolProperty(attr="group_by_material", name="Material Groups", description="", default= False), - bpy.props.BoolProperty(attr="keep_vertex_order", name="Keep Vertex Order", description="", default= False) - ] - - def execute(self, context): - - do_export(self.filename, context, - EXPORT_TRI=self.use_triangles, - EXPORT_EDGES=self.use_edges, - EXPORT_NORMALS=self.use_normals, - EXPORT_NORMALS_HQ=self.use_hq_normals, - EXPORT_UV=self.use_uvs, - EXPORT_MTL=self.use_materials, - EXPORT_COPY_IMAGES=self.copy_images, - EXPORT_APPLY_MODIFIERS=self.use_modifiers, - EXPORT_ROTX90=self.use_rotate90, - EXPORT_BLEN_OBS=self.use_blen_objects, - EXPORT_GROUP_BY_OB=self.group_by_object, - EXPORT_GROUP_BY_MAT=self.group_by_material, - EXPORT_KEEP_VERT_ORDER=self.keep_vertex_order, - EXPORT_POLYGROUPS=self.use_vertex_groups, - EXPORT_CURVE_AS_NURBS=self.use_nurbs, - EXPORT_SEL_ONLY=self.use_selection, - EXPORT_ALL_SCENES=self.use_all_scenes) - - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - - def poll(self, context): # Poll isnt working yet - print("Poll") - return context.active_object != None - -bpy.ops.add(EXPORT_OT_obj) - -if __name__ == "__main__": - bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj") - -# CONVERSION ISSUES -# - matrix problem -# - duplis - only tested dupliverts -# - NURBS - needs API additions -# - all scenes export -# + normals calculation -# - get rid of cleanName somehow diff --git a/release/io/export_ply.py b/release/io/export_ply.py deleted file mode 100644 index 8e79c3741bb..00000000000 --- a/release/io/export_ply.py +++ /dev/null @@ -1,279 +0,0 @@ -import bpy - -__author__ = "Bruce Merry" -__version__ = "0.93" -__bpydoc__ = """\ -This script exports Stanford PLY files from Blender. It supports normals, -colours, and texture coordinates per face or per vertex. -Only one mesh can be exported at a time. -""" - -# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# Vector rounding se we can use as keys -# -# Updated on Aug 11, 2008 by Campbell Barton -# - added 'comment' prefix to comments - Needed to comply with the PLY spec. -# -# Updated on Jan 1, 2007 by Gabe Ghearing -# - fixed normals so they are correctly smooth/flat -# - fixed crash when the model doesn't have uv coords or vertex colors -# - fixed crash when the model has vertex colors but doesn't have uv coords -# - changed float32 to float and uint8 to uchar for compatibility -# Errata/Notes as of Jan 1, 2007 -# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me) -# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either) -# -# Updated on Jan 3, 2007 by Gabe Ghearing -# - fixed "sticky" vertex UV exporting -# - added pupmenu to enable/disable exporting normals, uv coords, and colors -# Errata/Notes as of Jan 3, 2007 -# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either) -# - edges should be exported since PLY files support them -# - code is getting spaghettish, it should be refactored... -# - - -def rvec3d(v): return round(v[0], 6), round(v[1], 6), round(v[2], 6) -def rvec2d(v): return round(v[0], 6), round(v[1], 6) - -def write(filename, scene, ob, \ - EXPORT_APPLY_MODIFIERS= True,\ - EXPORT_NORMALS= True,\ - EXPORT_UV= True,\ - EXPORT_COLORS= True\ - ): - - if not filename.lower().endswith('.ply'): - filename += '.ply' - - if not ob: - raise Exception("Error, Select 1 active object") - return - - file = open(filename, 'w') - - - #EXPORT_EDGES = Draw.Create(0) - """ - is_editmode = Blender.Window.EditMode() - if is_editmode: - Blender.Window.EditMode(0, '', 0) - - Window.WaitCursor(1) - """ - - #mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX - if EXPORT_APPLY_MODIFIERS: - mesh = ob.create_mesh(True, 'PREVIEW') - else: - mesh = ob.data - - if not mesh: - raise ("Error, could not get mesh data from active object") - return - - # mesh.transform(ob.matrixWorld) # XXX - - faceUV = len(mesh.uv_textures) > 0 - vertexUV = len(mesh.sticky) > 0 - vertexColors = len(mesh.vertex_colors) > 0 - - if (not faceUV) and (not vertexUV): EXPORT_UV = False - if not vertexColors: EXPORT_COLORS = False - - if not EXPORT_UV: faceUV = vertexUV = False - if not EXPORT_COLORS: vertexColors = False - - if faceUV: - active_uv_layer = None - for lay in mesh.uv_textures: - if lay.active: - active_uv_layer= lay.data - break - if not active_uv_layer: - EXPORT_UV = False - faceUV = None - - if vertexColors: - active_col_layer = None - for lay in mesh.vertex_colors: - if lay.active: - active_col_layer= lay.data - if not active_col_layer: - EXPORT_COLORS = False - vertexColors = None - - # incase - color = uvcoord = uvcoord_key = normal = normal_key = None - - mesh_verts = mesh.verts # save a lookup - ply_verts = [] # list of dictionaries - # vdict = {} # (index, normal, uv) -> new index - vdict = [{} for i in range(len(mesh_verts))] - ply_faces = [[] for f in range(len(mesh.faces))] - vert_count = 0 - for i, f in enumerate(mesh.faces): - - - smooth = f.smooth - if not smooth: - normal = tuple(f.normal) - normal_key = rvec3d(normal) - - if faceUV: - uv = active_uv_layer[i] - uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/ - if vertexColors: - col = active_col_layer[i] - col = col.color1, col.color2, col.color3, col.color4 - - f_verts= f.verts - - pf= ply_faces[i] - for j, vidx in enumerate(f_verts): - v = mesh_verts[vidx] - - if smooth: - normal= tuple(v.normal) - normal_key = rvec3d(normal) - - if faceUV: - uvcoord= uv[j][0], 1.0-uv[j][1] - uvcoord_key = rvec2d(uvcoord) - elif vertexUV: - uvcoord= v.uvco[0], 1.0-v.uvco[1] - uvcoord_key = rvec2d(uvcoord) - - if vertexColors: - color= col[j] - color= int(color[0]*255.0), int(color[1]*255.0), int(color[2]*255.0) - - - key = normal_key, uvcoord_key, color - - vdict_local = vdict[vidx] - pf_vidx = vdict_local.get(key) # Will be None initially - - if pf_vidx == None: # same as vdict_local.has_key(key) - pf_vidx = vdict_local[key] = vert_count; - ply_verts.append((vidx, normal, uvcoord, color)) - vert_count += 1 - - pf.append(pf_vidx) - - file.write('ply\n') - file.write('format ascii 1.0\n') - version = "2.5" # Blender.Get('version') - file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] )) - - file.write('element vertex %d\n' % len(ply_verts)) - - file.write('property float x\n') - file.write('property float y\n') - file.write('property float z\n') - - # XXX - """ - if EXPORT_NORMALS: - file.write('property float nx\n') - file.write('property float ny\n') - file.write('property float nz\n') - """ - if EXPORT_UV: - file.write('property float s\n') - file.write('property float t\n') - if EXPORT_COLORS: - file.write('property uchar red\n') - file.write('property uchar green\n') - file.write('property uchar blue\n') - - file.write('element face %d\n' % len(mesh.faces)) - file.write('property list uchar uint vertex_indices\n') - file.write('end_header\n') - - for i, v in enumerate(ply_verts): - file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co - """ - if EXPORT_NORMALS: - file.write('%.6f %.6f %.6f ' % v[1]) # no - """ - if EXPORT_UV: file.write('%.6f %.6f ' % v[2]) # uv - if EXPORT_COLORS: file.write('%u %u %u' % v[3]) # col - file.write('\n') - - for pf in ply_faces: - if len(pf)==3: file.write('3 %d %d %d\n' % tuple(pf)) - else: file.write('4 %d %d %d %d\n' % tuple(pf)) - - file.close() - print("writing", filename, "done") - - if EXPORT_APPLY_MODIFIERS: - bpy.data.remove_mesh(mesh) - - # XXX - """ - if is_editmode: - Blender.Window.EditMode(1, '', 0) - """ - -class EXPORT_OT_ply(bpy.types.Operator): - '''Export a single object as a stanford PLY with normals, colours and texture coordinates.''' - __idname__ = "export.ply" - __label__ = "Export PLY" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""), - bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True), - bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True), - bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True), - bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True) - ] - - def poll(self, context): - return context.active_object != None - - def execute(self, context): - # print("Selected: " + context.active_object.name) - - if not self.path: - raise Exception("filename not set") - - write(self.path, context.scene, context.active_object,\ - EXPORT_APPLY_MODIFIERS = self.use_modifiers, - EXPORT_NORMALS = self.use_normals, - EXPORT_UV = self.use_uvs, - EXPORT_COLORS = self.use_colors, - ) - - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - - -bpy.ops.add(EXPORT_OT_ply) - -if __name__ == "__main__": - bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply") - - diff --git a/release/io/export_x3d.py b/release/io/export_x3d.py deleted file mode 100644 index f23ccf8d2dc..00000000000 --- a/release/io/export_x3d.py +++ /dev/null @@ -1,1239 +0,0 @@ -#!BPY -""" Registration info for Blender menus: -Name: 'X3D Extensible 3D (.x3d)...' -Blender: 245 -Group: 'Export' -Tooltip: 'Export selection to Extensible 3D file (.x3d)' -""" - -__author__ = ("Bart", "Campbell Barton") -__email__ = ["Bart, bart:neeneenee*de"] -__url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"] -__version__ = "2006/01/17" -__bpydoc__ = """\ -This script exports to X3D format. - -Usage: - -Run this script from "File->Export" menu. A pop-up will ask whether you -want to export only selected or all relevant objects. - -Known issues:
- Doesn't handle multiple materials (don't use material indices);
- Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);
- Can't get the texture array associated with material * not the UV ones; -""" - - -# $Id$ -# -#------------------------------------------------------------------------ -# X3D exporter for blender 2.36 or above -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# - -#################################### -# Library dependancies -#################################### - -import math -import os - -import bpy -import Mathutils - -from export_3ds import create_derived_objects, free_derived_objects - -# import Blender -# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh -# from Blender.Scene import Render -# import BPyObject -# import BPyMesh - -# -DEG2RAD=0.017453292519943295 -MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x') - -#################################### -# Global Variables -#################################### - -filename = "" -# filename = Blender.Get('filename') -_safeOverwrite = True - -extension = '' - -########################################################## -# Functions for writing output file -########################################################## - -class x3d_class: - - def __init__(self, filename): - #--- public you can change these --- - self.writingcolor = 0 - self.writingtexture = 0 - self.writingcoords = 0 - self.proto = 1 - self.matonly = 0 - self.share = 0 - self.billnode = 0 - self.halonode = 0 - self.collnode = 0 - self.tilenode = 0 - self.verbose=2 # level of verbosity in console 0-none, 1-some, 2-most - self.cp=3 # decimals for material color values 0.000 - 1.000 - self.vp=3 # decimals for vertex coordinate values 0.000 - n.000 - self.tp=3 # decimals for texture coordinate values 0.000 - 1.000 - self.it=3 - - #--- class private don't touch --- - self.texNames={} # dictionary of textureNames - self.matNames={} # dictionary of materiaNames - self.meshNames={} # dictionary of meshNames - self.indentLevel=0 # keeps track of current indenting - self.filename=filename - self.file = None - if filename.lower().endswith('.x3dz'): - try: - import gzip - self.file = gzip.open(filename, "w") - except: - print("failed to import compression modules, exporting uncompressed") - self.filename = filename[:-1] # remove trailing z - - if self.file == None: - self.file = open(self.filename, "w") - - self.bNav=0 - self.nodeID=0 - self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard", - "BooleanFilter","BooleanSequencer","BooleanToggle","BooleanTrigger","Box","Circle2D", - "Collision","Color","ColorInterpolator","ColorRGBA","component","Cone","connect", - "Contour2D","ContourPolyline2D","Coordinate","CoordinateDouble","CoordinateInterpolator", - "CoordinateInterpolator2D","Cylinder","CylinderSensor","DirectionalLight","Disk2D", - "ElevationGrid","EspduTransform","EXPORT","ExternProtoDeclare","Extrusion","field", - "fieldValue","FillProperties","Fog","FontStyle","GeoCoordinate","GeoElevationGrid", - "GeoLocationLocation","GeoLOD","GeoMetadata","GeoOrigin","GeoPositionInterpolator", - "GeoTouchSensor","GeoViewpoint","Group","HAnimDisplacer","HAnimHumanoid","HAnimJoint", - "HAnimSegment","HAnimSite","head","ImageTexture","IMPORT","IndexedFaceSet", - "IndexedLineSet","IndexedTriangleFanSet","IndexedTriangleSet","IndexedTriangleStripSet", - "Inline","IntegerSequencer","IntegerTrigger","IS","KeySensor","LineProperties","LineSet", - "LoadSensor","LOD","Material","meta","MetadataDouble","MetadataFloat","MetadataInteger", - "MetadataSet","MetadataString","MovieTexture","MultiTexture","MultiTextureCoordinate", - "MultiTextureTransform","NavigationInfo","Normal","NormalInterpolator","NurbsCurve", - "NurbsCurve2D","NurbsOrientationInterpolator","NurbsPatchSurface", - "NurbsPositionInterpolator","NurbsSet","NurbsSurfaceInterpolator","NurbsSweptSurface", - "NurbsSwungSurface","NurbsTextureCoordinate","NurbsTrimmedSurface","OrientationInterpolator", - "PixelTexture","PlaneSensor","PointLight","PointSet","Polyline2D","Polypoint2D", - "PositionInterpolator","PositionInterpolator2D","ProtoBody","ProtoDeclare","ProtoInstance", - "ProtoInterface","ProximitySensor","ReceiverPdu","Rectangle2D","ROUTE","ScalarInterpolator", - "Scene","Script","Shape","SignalPdu","Sound","Sphere","SphereSensor","SpotLight","StaticGroup", - "StringSensor","Switch","Text","TextureBackground","TextureCoordinate","TextureCoordinateGenerator", - "TextureTransform","TimeSensor","TimeTrigger","TouchSensor","Transform","TransmitterPdu", - "TriangleFanSet","TriangleSet","TriangleSet2D","TriangleStripSet","Viewpoint","VisibilitySensor", - "WorldInfo","X3D","XvlShell","VertexShader","FragmentShader","MultiShaderAppearance","ShaderAppearance" ] - self.namesStandard=[ "Empty","Empty.000","Empty.001","Empty.002","Empty.003","Empty.004","Empty.005", - "Empty.006","Empty.007","Empty.008","Empty.009","Empty.010","Empty.011","Empty.012", - "Scene.001","Scene.002","Scene.003","Scene.004","Scene.005","Scene.06","Scene.013", - "Scene.006","Scene.007","Scene.008","Scene.009","Scene.010","Scene.011","Scene.012", - "World","World.000","World.001","World.002","World.003","World.004","World.005" ] - self.namesFog=[ "","LINEAR","EXPONENTIAL","" ] - -########################################################## -# Writing nodes routines -########################################################## - - def writeHeader(self): - #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '<').replace('>', '>') - bfile = self.filename.replace('<', '<').replace('>', '>') # use outfile name - self.file.write("\n") - self.file.write("\n") - self.file.write("\n") - self.file.write("\n") - self.file.write("\t\n" % os.path.basename(bfile)) - # self.file.write("\t\n" % sys.basename(bfile)) - self.file.write("\t\n" % '2.5') - # self.file.write("\t\n" % Blender.Get('version')) - self.file.write("\t\n") - self.file.write("\n") - self.file.write("\n") - - # This functionality is poorly defined, disabling for now - campbell - ''' - def writeInline(self): - inlines = Blender.Scene.Get() - allinlines = len(inlines) - if scene != inlines[0]: - return - else: - for i in xrange(allinlines): - nameinline=inlines[i].name - if (nameinline not in self.namesStandard) and (i > 0): - self.file.write("" % nameinline) - self.file.write("\n\n") - - - def writeScript(self): - textEditor = Blender.Text.Get() - alltext = len(textEditor) - for i in xrange(alltext): - nametext = textEditor[i].name - nlines = textEditor[i].getNLines() - if (self.proto == 1): - if (nametext == "proto" or nametext == "proto.js" or nametext == "proto.txt") and (nlines != None): - nalllines = len(textEditor[i].asLines()) - alllines = textEditor[i].asLines() - for j in xrange(nalllines): - self.writeIndented(alllines[j] + "\n") - elif (self.proto == 0): - if (nametext == "route" or nametext == "route.js" or nametext == "route.txt") and (nlines != None): - nalllines = len(textEditor[i].asLines()) - alllines = textEditor[i].asLines() - for j in xrange(nalllines): - self.writeIndented(alllines[j] + "\n") - self.writeIndented("\n") - ''' - - def writeViewpoint(self, ob, mat, scene): - context = scene.render_data - # context = scene.render - ratio = float(context.resolution_x)/float(context.resolution_y) - # ratio = float(context.imageSizeY())/float(context.imageSizeX()) - lens = (360* (math.atan(ratio *16 / ob.data.lens) / math.pi))*(math.pi/180) - # lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180) - lens = min(lens, math.pi) - - # get the camera location, subtract 90 degress from X to orient like X3D does - # mat = ob.matrixWorld - mat is now passed! - - loc = self.rotatePointForVRML(mat.translationPart()) - rot = mat.toEuler() - rot = (((rot[0]-90)), rot[1], rot[2]) - # rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD) - nRot = self.rotatePointForVRML( rot ) - # convert to Quaternion and to Angle Axis - Q = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2]) - Q1 = self.multiplyQuaternions(Q[0], Q[1]) - Qf = self.multiplyQuaternions(Q1, Q[2]) - angleAxis = self.quaternionToAngleAxis(Qf) - self.file.write("\n\n" % (lens)) - - def writeFog(self, world): - if world: - mtype = world.mist.falloff - # mtype = world.getMistype() - mparam = world.mist - # mparam = world.getMist() - grd = world.horizon_color - # grd = world.getHor() - grd0, grd1, grd2 = grd[0], grd[1], grd[2] - else: - return - if (mtype == 'LINEAR' or mtype == 'INVERSE_QUADRATIC'): - mtype = 1 if mtype == 'LINEAR' else 2 - # if (mtype == 1 or mtype == 2): - self.file.write("\n\n" % round(mparam[2],self.cp)) - else: - return - - def writeNavigationInfo(self, scene): - self.file.write('\n') - - def writeSpotLight(self, ob, mtx, lamp, world): - safeName = self.cleanStr(ob.name) - if world: - ambi = world.ambient_color - # ambi = world.amb - ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 - else: - ambi = 0 - ambientIntensity = 0 - - # compute cutoff and beamwidth - intensity=min(lamp.energy/1.75,1.0) - beamWidth=((lamp.spot_size*math.pi)/180.0)*.37; - # beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; - cutOffAngle=beamWidth*1.3 - - dx,dy,dz=self.computeDirection(mtx) - # note -dx seems to equal om[3][0] - # note -dz seems to equal om[3][1] - # note dy seems to equal om[3][2] - - #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed - location=(mtx*MATWORLD).translationPart() - - radius = lamp.distance*math.cos(beamWidth) - # radius = lamp.dist*math.cos(beamWidth) - self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) - - - def writeDirectionalLight(self, ob, mtx, lamp, world): - safeName = self.cleanStr(ob.name) - if world: - ambi = world.ambient_color - # ambi = world.amb - ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 - else: - ambi = 0 - ambientIntensity = 0 - - intensity=min(lamp.energy/1.75,1.0) - (dx,dy,dz)=self.computeDirection(mtx) - self.file.write("\n\n" % (round(dx,4),round(dy,4),round(dz,4))) - - def writePointLight(self, ob, mtx, lamp, world): - safeName = self.cleanStr(ob.name) - if world: - ambi = world.ambient_color - # ambi = world.amb - ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 - else: - ambi = 0 - ambientIntensity = 0 - - # location=(ob.matrixWorld*MATWORLD).translationPart() # now passed - location= (mtx*MATWORLD).translationPart() - - self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) - ''' - def writeNode(self, ob, mtx): - obname=str(ob.name) - if obname in self.namesStandard: - return - else: - dx,dy,dz = self.computeDirection(mtx) - # location=(ob.matrixWorld*MATWORLD).translationPart() - location=(mtx*MATWORLD).translationPart() - self.writeIndented("<%s\n" % obname,1) - self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3))) - self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) - self.writeIndented("/>\n",-1) - self.writeIndented("\n") - ''' - def secureName(self, name): - name = name + str(self.nodeID) - self.nodeID=self.nodeID+1 - if len(name) <= 3: - newname = "_" + str(self.nodeID) - return "%s" % (newname) - else: - for bad in ['"','#',"'",',','.','[','\\',']','{','}']: - name=name.replace(bad,'_') - if name in self.namesReserved: - newname = name[0:3] + "_" + str(self.nodeID) - return "%s" % (newname) - elif name[0].isdigit(): - newname = "_" + name + str(self.nodeID) - return "%s" % (newname) - else: - newname = name - return "%s" % (newname) - - def writeIndexedFaceSet(self, ob, mesh, mtx, world, EXPORT_TRI = False): - imageMap={} # set of used images - sided={} # 'one':cnt , 'two':cnt - vColors={} # 'multi':1 - meshName = self.cleanStr(ob.name) - - meshME = self.cleanStr(ob.data.name) # We dont care if its the mesh name or not - # meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not - if len(mesh.faces) == 0: return - mode = [] - # mode = 0 - if mesh.active_uv_texture: - # if mesh.faceUV: - for face in mesh.active_uv_texture.data: - # for face in mesh.faces: - if face.halo and 'HALO' not in mode: - mode += ['HALO'] - if face.billboard and 'BILLBOARD' not in mode: - mode += ['BILLBOARD'] - if face.object_color and 'OBJECT_COLOR' not in mode: - mode += ['OBJECT_COLOR'] - if face.collision and 'COLLISION' not in mode: - mode += ['COLLISION'] - # mode |= face.mode - - if 'HALO' in mode and self.halonode == 0: - # if mode & Mesh.FaceModes.HALO and self.halonode == 0: - self.writeIndented("\n",1) - self.halonode = 1 - elif 'BILLBOARD' in mode and self.billnode == 0: - # elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0: - self.writeIndented("\n",1) - self.billnode = 1 - elif 'OBJECT_COLOR' in mode and self.matonly == 0: - # elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0: - self.matonly = 1 - # TF_TILES is marked as deprecated in DNA_meshdata_types.h - # elif mode & Mesh.FaceModes.TILES and self.tilenode == 0: - # self.tilenode = 1 - elif 'COLLISION' not in mode and self.collnode == 0: - # elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0: - self.writeIndented("\n",1) - self.collnode = 1 - - nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors) - - if nIFSCnt > 1: - self.writeIndented("\n" % ("G_", meshName),1) - - if 'two' in sided and sided['two'] > 0: - bTwoSided=1 - else: - bTwoSided=0 - - # mtx = ob.matrixWorld * MATWORLD # mtx is now passed - mtx = mtx * MATWORLD - - loc= mtx.translationPart() - sca= mtx.scalePart() - quat = mtx.toQuat() - rot= quat.axis - - self.writeIndented('\n' % \ - (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle) ) - # self.writeIndented('\n' % \ - # (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) ) - - self.writeIndented("\n",1) - maters=mesh.materials - hasImageTexture=0 - issmooth=0 - - if len(maters) > 0 or mesh.active_uv_texture: - # if len(maters) > 0 or mesh.faceUV: - self.writeIndented("\n", 1) - # right now this script can only handle a single material per mesh. - if len(maters) >= 1: - mat=maters[0] - # matFlags = mat.getMode() - if not mat.face_texture: - # if not matFlags & Blender.Material.Modes['TEXFACE']: - self.writeMaterial(mat, self.cleanStr(mat.name,''), world) - # self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world) - if len(maters) > 1: - print("Warning: mesh named %s has multiple materials" % meshName) - print("Warning: only one material per object handled") - - #-- textures - face = None - if mesh.active_uv_texture: - # if mesh.faceUV: - for face in mesh.active_uv_texture.data: - # for face in mesh.faces: - if face.image: - # if (hasImageTexture == 0) and (face.image): - self.writeImageTexture(face.image) - # hasImageTexture=1 # keep track of face texture - break - if self.tilenode == 1 and face and face.image: - # if self.tilenode == 1: - self.writeIndented("\n" % (face.image.xrep, face.image.yrep)) - self.tilenode = 0 - self.writeIndented("\n", -1) - - #-- IndexedFaceSet or IndexedLineSet - - # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5 - ifStyle="IndexedFaceSet" - # look up mesh name, use it if available - if meshME in self.meshNames: - self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1) - self.meshNames[meshME]+=1 - else: - if int(mesh.users) > 1: - self.writeIndented("<%s DEF=\"ME_%s\" " % (ifStyle, meshME), 1) - self.meshNames[meshME]=1 - else: - self.writeIndented("<%s " % ifStyle, 1) - - if bTwoSided == 1: - self.file.write("solid=\"false\" ") - else: - self.file.write("solid=\"true\" ") - - for face in mesh.faces: - if face.smooth: - issmooth=1 - break - if issmooth==1: - creaseAngle=(mesh.autosmooth_angle)*(math.pi/180.0) - # creaseAngle=(mesh.degr)*(math.pi/180.0) - self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp))) - - #--- output textureCoordinates if UV texture used - if mesh.active_uv_texture: - # if mesh.faceUV: - if self.matonly == 1 and self.share == 1: - self.writeFaceColors(mesh) - elif hasImageTexture == 1: - self.writeTextureCoordinates(mesh) - #--- output coordinates - self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) - - self.writingcoords = 1 - self.writingtexture = 1 - self.writingcolor = 1 - self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) - - #--- output textureCoordinates if UV texture used - if mesh.active_uv_texture: - # if mesh.faceUV: - if hasImageTexture == 1: - self.writeTextureCoordinates(mesh) - elif self.matonly == 1 and self.share == 1: - self.writeFaceColors(mesh) - #--- output vertexColors - self.matonly = 0 - self.share = 0 - - self.writingcoords = 0 - self.writingtexture = 0 - self.writingcolor = 0 - #--- output closing braces - self.writeIndented("\n" % ifStyle, -1) - self.writeIndented("\n", -1) - self.writeIndented("\n", -1) - - if self.halonode == 1: - self.writeIndented("\n", -1) - self.halonode = 0 - - if self.billnode == 1: - self.writeIndented("\n", -1) - self.billnode = 0 - - if self.collnode == 1: - self.writeIndented("\n", -1) - self.collnode = 0 - - if nIFSCnt > 1: - self.writeIndented("\n", -1) - - self.file.write("\n") - - def writeCoordinates(self, ob, mesh, meshName, EXPORT_TRI = False): - # create vertex list and pre rotate -90 degrees X for VRML - - if self.writingcoords == 0: - self.file.write('coordIndex="') - for face in mesh.faces: - fv = face.verts - # fv = face.v - - if len(fv)==3: - # if len(face)==3: - self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2])) - # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) - else: - if EXPORT_TRI: - self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2])) - # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) - self.file.write("%i %i %i -1, " % (fv[0], fv[2], fv[3])) - # self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index)) - else: - self.file.write("%i %i %i %i -1, " % (fv[0], fv[1], fv[2], fv[3])) - # self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index)) - - self.file.write("\">\n") - else: - #-- vertices - # mesh.transform(ob.matrixWorld) - self.writeIndented("") - self.writeIndented("\n", -1) - - def writeTextureCoordinates(self, mesh): - texCoordList=[] - texIndexList=[] - j=0 - - for face in mesh.active_uv_texture.data: - # for face in mesh.faces: - uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3] - - for uv in uvs: - # for uv in face.uv: - texIndexList.append(j) - texCoordList.append(uv) - j=j+1 - texIndexList.append(-1) - if self.writingtexture == 0: - self.file.write("\n\t\t\ttexCoordIndex=\"") - texIndxStr="" - for i in range(len(texIndexList)): - texIndxStr = texIndxStr + "%d, " % texIndexList[i] - if texIndexList[i]==-1: - self.file.write(texIndxStr) - texIndxStr="" - self.file.write("\"\n\t\t\t") - else: - self.writeIndented("") - self.writeIndented("\n", -1) - - def writeFaceColors(self, mesh): - if self.writingcolor == 0: - self.file.write("colorPerVertex=\"false\" ") - elif mesh.active_vertex_color: - # else: - self.writeIndented(" 2: - print("Debug: face.col r=%d g=%d b=%d" % (c[0], c[1], c[2])) - # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) - aColor = self.rgbToFS(c) - self.file.write("%s, " % aColor) - - # for face in mesh.faces: - # if face.col: - # c=face.col[0] - # if self.verbose > 2: - # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) - # aColor = self.rgbToFS(c) - # self.file.write("%s, " % aColor) - self.file.write("\" />") - self.writeIndented("\n",-1) - - def writeMaterial(self, mat, matName, world): - # look up material name, use it if available - if matName in self.matNames: - self.writeIndented("\n" % matName) - self.matNames[matName]+=1 - return; - - self.matNames[matName]=1 - - ambient = mat.ambient/3 - # ambient = mat.amb/3 - diffuseR, diffuseG, diffuseB = tuple(mat.diffuse_color) - # diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] - if world: - ambi = world.ambient_color - # ambi = world.getAmb() - ambi0, ambi1, ambi2 = (ambi[0]*mat.ambient)*2, (ambi[1]*mat.ambient)*2, (ambi[2]*mat.ambient)*2 - # ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 - else: - ambi0, ambi1, ambi2 = 0, 0, 0 - emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2 - - shininess = mat.specular_hardness/512.0 - # shininess = mat.hard/512.0 - specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_reflection+0.001)) - # specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001)) - specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_reflection+0.001)) - # specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001)) - specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_reflection+0.001)) - # specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001)) - transp = 1-mat.alpha - # matFlags = mat.getMode() - if mat.shadeless: - # if matFlags & Blender.Material.Modes['SHADELESS']: - ambient = 1 - shine = 1 - specR = emitR = diffuseR - specG = emitG = diffuseG - specB = emitB = diffuseB - self.writeIndented("" % (round(transp,self.cp))) - self.writeIndented("\n",-1) - - def writeImageTexture(self, image): - name = image.name - filename = image.filename.split('/')[-1].split('\\')[-1] - if name in self.texNames: - self.writeIndented("\n" % self.cleanStr(name)) - self.texNames[name] += 1 - return - else: - self.writeIndented("" % name) - self.writeIndented("\n",-1) - self.texNames[name] = 1 - - def writeBackground(self, world, alltextures): - if world: worldname = world.name - else: return - blending = (world.blend_sky, world.paper_sky, world.real_sky) - # blending = world.getSkytype() - grd = world.horizon_color - # grd = world.getHor() - grd0, grd1, grd2 = grd[0], grd[1], grd[2] - sky = world.zenith_color - # sky = world.getZen() - sky0, sky1, sky2 = sky[0], sky[1], sky[2] - mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2] - mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2 - self.file.write("\n\n") - -########################################################## -# export routine -########################################################## - - def export(self, scene, world, alltextures,\ - EXPORT_APPLY_MODIFIERS = False,\ - EXPORT_TRI= False,\ - ): - - print("Info: starting X3D export to " + self.filename + "...") - self.writeHeader() - # self.writeScript() - self.writeNavigationInfo(scene) - self.writeBackground(world, alltextures) - self.writeFog(world) - self.proto = 0 - - - # # COPIED FROM OBJ EXPORTER - # if EXPORT_APPLY_MODIFIERS: - # temp_mesh_name = '~tmp-mesh' - - # # Get the container mesh. - used for applying modifiers and non mesh objects. - # containerMesh = meshName = tempMesh = None - # for meshName in Blender.NMesh.GetNames(): - # if meshName.startswith(temp_mesh_name): - # tempMesh = Mesh.Get(meshName) - # if not tempMesh.users: - # containerMesh = tempMesh - # if not containerMesh: - # containerMesh = Mesh.New(temp_mesh_name) - # -------------------------- - - - for ob_main in [o for o in scene.objects if o.is_visible()]: - # for ob_main in scene.objects.context: - - free, derived = create_derived_objects(ob_main) - - if derived == None: continue - - for ob, ob_mat in derived: - # for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): - objType=ob.type - objName=ob.name - self.matonly = 0 - if objType == "CAMERA": - # if objType == "Camera": - self.writeViewpoint(ob, ob_mat, scene) - elif objType in ("MESH", "CURVE", "SURF", "TEXT") : - # elif objType in ("Mesh", "Curve", "Surf", "Text") : - if EXPORT_APPLY_MODIFIERS or objType != 'MESH': - # if EXPORT_APPLY_MODIFIERS or objType != 'Mesh': - me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW') - # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene) - else: - me = ob.data - # me = ob.getData(mesh=1) - - self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI) - - # free mesh created with create_mesh() - if me != ob.data: - bpy.data.remove_mesh(me) - - elif objType == "LAMP": - # elif objType == "Lamp": - data= ob.data - datatype=data.type - if datatype == 'POINT': - # if datatype == Lamp.Types.Lamp: - self.writePointLight(ob, ob_mat, data, world) - elif datatype == 'SPOT': - # elif datatype == Lamp.Types.Spot: - self.writeSpotLight(ob, ob_mat, data, world) - elif datatype == 'SUN': - # elif datatype == Lamp.Types.Sun: - self.writeDirectionalLight(ob, ob_mat, data, world) - else: - self.writeDirectionalLight(ob, ob_mat, data, world) - # do you think x3d could document what to do with dummy objects? - #elif objType == "Empty" and objName != "Empty": - # self.writeNode(ob, ob_mat) - else: - #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType) - pass - - if free: - free_derived_objects(ob_main) - - self.file.write("\n\n") - - # if EXPORT_APPLY_MODIFIERS: - # if containerMesh: - # containerMesh.verts = None - - self.cleanup() - -########################################################## -# Utility methods -########################################################## - - def cleanup(self): - self.file.close() - self.texNames={} - self.matNames={} - self.indentLevel=0 - print("Info: finished X3D export to %s\n" % self.filename) - - def cleanStr(self, name, prefix='rsvd_'): - """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name""" - - newName=name[:] - if len(newName) == 0: - self.nNodeID+=1 - return "%s%d" % (prefix, self.nNodeID) - - if newName in self.namesReserved: - newName='%s%s' % (prefix,newName) - - if newName[0].isdigit(): - newName='%s%s' % ('_',newName) - - for bad in [' ','"','#',"'",',','.','[','\\',']','{','}']: - newName=newName.replace(bad,'_') - return newName - - def countIFSSetsNeeded(self, mesh, imageMap, sided, vColors): - """ - countIFFSetsNeeded() - should look at a blender mesh to determine - how many VRML IndexFaceSets or IndexLineSets are needed. A - new mesh created under the following conditions: - - o - split by UV Textures / one per mesh - o - split by face, one sided and two sided - o - split by smooth and flat faces - o - split when faces only have 2 vertices * needs to be an IndexLineSet - """ - - imageNameMap={} - faceMap={} - nFaceIndx=0 - - if mesh.active_uv_texture: - # if mesh.faceUV: - for face in mesh.active_uv_texture.data: - # for face in mesh.faces: - sidename=''; - if face.twoside: - # if face.mode & Mesh.FaceModes.TWOSIDE: - sidename='two' - else: - sidename='one' - - if sidename in sided: - sided[sidename]+=1 - else: - sided[sidename]=1 - - image = face.image - if image: - faceName="%s_%s" % (face.image.name, sidename); - try: - imageMap[faceName].append(face) - except: - imageMap[faceName]=[face.image.name,sidename,face] - - if self.verbose > 2: - for faceName in imageMap.keys(): - ifs=imageMap[faceName] - print("Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \ - (faceName, ifs[0], ifs[1], len(ifs)-2)) - - return len(imageMap) - - def faceToString(self,face): - - print("Debug: face.flag=0x%x (bitflags)" % face.flag) - if face.sel: - print("Debug: face.sel=true") - - print("Debug: face.mode=0x%x (bitflags)" % face.mode) - if face.mode & Mesh.FaceModes.TWOSIDE: - print("Debug: face.mode twosided") - - print("Debug: face.transp=0x%x (enum)" % face.transp) - if face.transp == Mesh.FaceTranspModes.SOLID: - print("Debug: face.transp.SOLID") - - if face.image: - print("Debug: face.image=%s" % face.image.name) - print("Debug: face.materialIndex=%d" % face.materialIndex) - - # XXX not used - # def getVertexColorByIndx(self, mesh, indx): - # c = None - # for face in mesh.faces: - # j=0 - # for vertex in face.v: - # if vertex.index == indx: - # c=face.col[j] - # break - # j=j+1 - # if c: break - # return c - - def meshToString(self,mesh): - # print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors) - print("Debug: mesh.faceUV=%d" % (len(mesh.uv_textures) > 0)) - # print("Debug: mesh.faceUV=%d" % mesh.faceUV) - print("Debug: mesh.hasVertexColours=%d" % (len(mesh.vertex_colors) > 0)) - # print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()) - print("Debug: mesh.verts=%d" % len(mesh.verts)) - print("Debug: mesh.faces=%d" % len(mesh.faces)) - print("Debug: mesh.materials=%d" % len(mesh.materials)) - - def rgbToFS(self, c): - s="%s %s %s" % (round(c[0]/255.0,self.cp), - round(c[1]/255.0,self.cp), - round(c[2]/255.0,self.cp)) - - # s="%s %s %s" % ( - # round(c.r/255.0,self.cp), - # round(c.g/255.0,self.cp), - # round(c.b/255.0,self.cp)) - return s - - def computeDirection(self, mtx): - x,y,z=(0,-1.0,0) # point down - - ax,ay,az = (mtx*MATWORLD).toEuler() - - # ax *= DEG2RAD - # ay *= DEG2RAD - # az *= DEG2RAD - - # rot X - x1=x - y1=y*math.cos(ax)-z*math.sin(ax) - z1=y*math.sin(ax)+z*math.cos(ax) - - # rot Y - x2=x1*math.cos(ay)+z1*math.sin(ay) - y2=y1 - z2=z1*math.cos(ay)-x1*math.sin(ay) - - # rot Z - x3=x2*math.cos(az)-y2*math.sin(az) - y3=x2*math.sin(az)+y2*math.cos(az) - z3=z2 - - return [x3,y3,z3] - - - # swap Y and Z to handle axis difference between Blender and VRML - #------------------------------------------------------------------------ - def rotatePointForVRML(self, v): - x = v[0] - y = v[2] - z = -v[1] - - vrmlPoint=[x, y, z] - return vrmlPoint - - # For writing well formed VRML code - #------------------------------------------------------------------------ - def writeIndented(self, s, inc=0): - if inc < 1: - self.indentLevel = self.indentLevel + inc - - spaces="" - for x in range(self.indentLevel): - spaces = spaces + "\t" - self.file.write(spaces + s) - - if inc > 0: - self.indentLevel = self.indentLevel + inc - - # Converts a Euler to three new Quaternions - # Angles of Euler are passed in as radians - #------------------------------------------------------------------------ - def eulerToQuaternions(self, x, y, z): - Qx = [math.cos(x/2), math.sin(x/2), 0, 0] - Qy = [math.cos(y/2), 0, math.sin(y/2), 0] - Qz = [math.cos(z/2), 0, 0, math.sin(z/2)] - - quaternionVec=[Qx,Qy,Qz] - return quaternionVec - - # Multiply two Quaternions together to get a new Quaternion - #------------------------------------------------------------------------ - def multiplyQuaternions(self, Q1, Q2): - result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])), - ((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])), - ((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])), - ((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))] - - return result - - # Convert a Quaternion to an Angle Axis (ax, ay, az, angle) - # angle is in radians - #------------------------------------------------------------------------ - def quaternionToAngleAxis(self, Qf): - scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2) - ax = Qf[1] - ay = Qf[2] - az = Qf[3] - - if scale > .0001: - ax/=scale - ay/=scale - az/=scale - - angle = 2 * math.acos(Qf[0]) - - result = [ax, ay, az, angle] - return result - -########################################################## -# Callbacks, needed before Main -########################################################## - -def x3d_export(filename, - context, - EXPORT_APPLY_MODIFIERS=False, - EXPORT_TRI=False, - EXPORT_GZIP=False): - - if EXPORT_GZIP: - if not filename.lower().endswith('.x3dz'): - filename = '.'.join(filename.split('.')[:-1]) + '.x3dz' - else: - if not filename.lower().endswith('.x3d'): - filename = '.'.join(filename.split('.')[:-1]) + '.x3d' - - - scene = context.scene - # scene = Blender.Scene.GetCurrent() - world = scene.world - - # XXX these are global textures while .Get() returned only scene's? - alltextures = bpy.data.textures - # alltextures = Blender.Texture.Get() - - wrlexport=x3d_class(filename) - wrlexport.export(\ - scene,\ - world,\ - alltextures,\ - \ - EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\ - EXPORT_TRI = EXPORT_TRI,\ - ) - - -def x3d_export_ui(filename): - if not filename.endswith(extension): - filename += extension - #if _safeOverwrite and sys.exists(filename): - # result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0") - #if(result != 1): - # return - - # Get user options - EXPORT_APPLY_MODIFIERS = Draw.Create(1) - EXPORT_TRI = Draw.Create(0) - EXPORT_GZIP = Draw.Create( filename.lower().endswith('.x3dz') ) - - # Get USER Options - pup_block = [\ - ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object.'),\ - ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\ - ('Compress', EXPORT_GZIP, 'GZip the resulting file, requires a full python install'),\ - ] - - if not Draw.PupBlock('Export...', pup_block): - return - - Blender.Window.EditMode(0) - Blender.Window.WaitCursor(1) - - x3d_export(filename,\ - EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val,\ - EXPORT_TRI = EXPORT_TRI.val,\ - EXPORT_GZIP = EXPORT_GZIP.val\ - ) - - Blender.Window.WaitCursor(0) - - - -######################################################### -# main routine -######################################################### - - -# if __name__ == '__main__': -# Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) - -class EXPORT_OT_x3d(bpy.types.Operator): - ''' - X3D Exporter - ''' - __idname__ = "export.x3d" - __label__ = 'Export X3D' - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen=1024, default=""), - - bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True), - bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False), - bpy.props.BoolProperty(attr="compress", name="Compress", description="GZip the resulting file, requires a full python install.", default=False), - ] - - def execute(self, context): - x3d_export(self.filename, context, self.apply_modifiers, self.triangulate, self.compress) - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - - def poll(self, context): # Poll isnt working yet - print("Poll") - return context.active_object != None - -bpy.ops.add(EXPORT_OT_x3d) - -# NOTES -# - blender version is hardcoded diff --git a/release/io/import_3ds.py b/release/io/import_3ds.py deleted file mode 100644 index 99825471764..00000000000 --- a/release/io/import_3ds.py +++ /dev/null @@ -1,1166 +0,0 @@ -#!BPY -""" -Name: '3D Studio (.3ds)...' -Blender: 244 -Group: 'Import' -Tooltip: 'Import from 3DS file format (.3ds)' -""" - -__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin'] -__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") -__version__= '0.996' -__bpydoc__= '''\ - -3ds Importer - -This script imports a 3ds file and the materials into Blender for editing. - -Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). - -0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200
- - Implemented workaround to correct association between name, geometry and materials of - imported meshes. - - Without this patch, version 0.995 of this importer would associate to each mesh object the - geometry and the materials of the previously parsed mesh object. By so, the name of the - first mesh object would be thrown away, and the name of the last mesh object would be - automatically merged with a '.001' at the end. No object would desappear, however object's - names and materials would be completely jumbled. - -0.995 by Campbell Barton
-- workaround for buggy mesh vert delete -- minor tweaks - -0.99 by Bob Holcomb
-- added support for floating point color values that previously broke on import. - -0.98 by Campbell Barton
-- import faces and verts to lists instead of a mesh, convert to a mesh later -- use new index mapping feature of mesh to re-map faces that were not added. - -0.97 by Campbell Barton
-- Strip material names of spaces -- Added import as instance to import the 3ds into its own - scene and add a group instance to the current scene -- New option to scale down imported objects so they are within a limited bounding area. - -0.96 by Campbell Barton
-- Added workaround for bug in setting UV's for Zero vert index UV faces. -- Removed unique name function, let blender make the names unique. - -0.95 by Campbell Barton
-- Removed workarounds for Blender 2.41 -- Mesh objects split by material- many 3ds objects used more then 16 per mesh. -- Removed a lot of unneeded variable creation. - -0.94 by Campbell Barton
-- Face import tested to be about overall 16x speedup over 0.93. -- Material importing speedup. -- Tested with more models. -- Support some corrupt models. - -0.93 by Campbell Barton
-- Tested with 400 3ds files from turbosquid and samples. -- Tactfully ignore faces that used the same verts twice. -- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading. -- Converted from NMesh to Mesh. -- Faster and cleaner new names. -- Use external comprehensive image loader. -- Re intergrated 0.92 and 0.9 changes -- Fixes for 2.41 compat. -- Non textured faces do not use a texture flag. - -0.92
-- Added support for diffuse, alpha, spec, bump maps in a single material - -0.9
-- Reorganized code into object/material block functions
-- Use of Matrix() to copy matrix data
-- added support for material transparency
- -0.83 2005-08-07: Campell Barton -- Aggressive image finding and case insensitivy for posisx systems. - -0.82a 2005-07-22 -- image texture loading (both for face uv and renderer) - -0.82 - image texture loading (for face uv) - -0.81a (fork- not 0.9) Campbell Barton 2005-06-08 -- Simplified import code -- Never overwrite data -- Faster list handling -- Leaves import selected - -0.81 Damien McGinnes 2005-01-09 -- handle missing images better - -0.8 Damien McGinnes 2005-01-08 -- copies sticky UV coords to face ones -- handles images better -- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script - -''' - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Bob Holcomb -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -# Importing modules - -import os -import time -import struct - -from import_obj import unpack_face_list, load_image - -import bpy -import Mathutils - -# import Blender -# from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils -# from Blender.Mathutils import Vector -# import BPyImage - -# import BPyMessages - -# try: -# from struct import calcsize, unpack -# except: -# calcsize= unpack= None - - - -# # If python version is less than 2.4, try to get set stuff from module -# try: -# set -# except: -# from sets import Set as set - -BOUNDS_3DS = [] - - -#this script imports uvcoords as sticky vertex coords -#this parameter enables copying these to face uv coords -#which shold be more useful. - -def createBlenderTexture(material, name, image): - texture = bpy.data.textures.new(name) - texture.setType('Image') - texture.image = image - material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) - - - -###################################################### -# Data Structures -###################################################### - -#Some of the chunks that we will see -#----- Primary Chunk, at the beginning of each file -PRIMARY = int('0x4D4D',16) - -#------ Main Chunks -OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information -VERSION = int('0x0002',16); #This gives the version of the .3ds file -EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info - -#------ sub defines of OBJECTINFO -MATERIAL = 45055 #0xAFFF // This stored the texture info -OBJECT = 16384 #0x4000 // This stores the faces, vertices, etc... - -#>------ sub defines of MATERIAL -#------ sub defines of MATERIAL_BLOCK -MAT_NAME = int('0xA000',16) # This holds the material name -MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material -MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material -MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material -MAT_SHINESS = int('0xA040',16) # ?? -MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material -MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material -MAT_WIRE = int('0xA085',16) # Only render's wireframe - -MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map -MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map -MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map -MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map -MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map -MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture - -MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats -MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes - -#>------ sub defines of OBJECT -OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object -OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object -OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght. -OBJECT_LAMP_OFF = int('0x4620',16); # The light off. -OBJECT_LAMP_ATTENUATE = int('0x4625',16); -OBJECT_LAMP_RAYSHADE = int('0x4627',16); -OBJECT_LAMP_SHADOWED = int('0x4630',16); -OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16); -OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16); -OBJECT_LAMP_SEE_CONE = int('0x4650',16); -OBJECT_LAMP_SPOT_RECTANGULAR = int('0x4651',16); -OBJECT_LAMP_SPOT_OVERSHOOT = int('0x4652',16); -OBJECT_LAMP_SPOT_PROJECTOR = int('0x4653',16); -OBJECT_LAMP_EXCLUDE = int('0x4654',16); -OBJECT_LAMP_RANGE = int('0x4655',16); -OBJECT_LAMP_ROLL = int('0x4656',16); -OBJECT_LAMP_SPOT_ASPECT = int('0x4657',16); -OBJECT_LAMP_RAY_BIAS = int('0x4658',16); -OBJECT_LAMP_INNER_RANGE = int('0x4659',16); -OBJECT_LAMP_OUTER_RANGE = int('0x465A',16); -OBJECT_LAMP_MULTIPLIER = int('0x465B',16); -OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16); - - - -OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object - -#>------ sub defines of CAMERA -OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values - -#>------ sub defines of OBJECT_MESH -OBJECT_VERTICES = int('0x4110',16); # The objects vertices -OBJECT_FACES = int('0x4120',16); # The objects faces -OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color -OBJECT_UV = int('0x4140',16); # The UV texture coordinates -OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix - -global scn -scn = None - -#the chunk class -class chunk: - ID = 0 - length = 0 - bytes_read = 0 - - #we don't read in the bytes_read, we compute that - binary_format=' 3): - print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) - - #is it an object info chunk? - elif (new_chunk.ID == OBJECTINFO): - #print 'elif (new_chunk.ID == OBJECTINFO):' - # print 'found an OBJECTINFO chunk' - process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) - - #keep track of how much we read in the main chunk - new_chunk.bytes_read += temp_chunk.bytes_read - - #is it an object chunk? - elif (new_chunk.ID == OBJECT): - - if CreateBlenderObject: - putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) - contextMesh_vertls = []; contextMesh_facels = [] - - ## preparando para receber o proximo objeto - contextMeshMaterials = {} # matname:[face_idxs] - contextMeshUV = None - #contextMesh.vertexUV = 1 # Make sticky coords. - # Reset matrix - contextMatrix_rot = None - #contextMatrix_tx = None - - CreateBlenderObject = True - tempName = read_string(file) - contextObName = tempName - new_chunk.bytes_read += len(tempName)+1 - - #is it a material chunk? - elif (new_chunk.ID == MATERIAL): - -# print("read material") - - #print 'elif (new_chunk.ID == MATERIAL):' - contextMaterial = bpy.data.add_material('Material') -# contextMaterial = bpy.data.materials.new('Material') - - elif (new_chunk.ID == MAT_NAME): - #print 'elif (new_chunk.ID == MAT_NAME):' - material_name = read_string(file) - -# print("material name", material_name) - - #plus one for the null character that ended the string - new_chunk.bytes_read += len(material_name)+1 - - contextMaterial.name = material_name.rstrip() # remove trailing whitespace - MATDICT[material_name]= (contextMaterial.name, contextMaterial) - - elif (new_chunk.ID == MAT_AMBIENT): - #print 'elif (new_chunk.ID == MAT_AMBIENT):' - read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_FLOAT_COLOR): - contextMaterial.mirror_color = read_float_color(temp_chunk) -# temp_data = file.read(struct.calcsize('3f')) -# temp_chunk.bytes_read += 12 -# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] - elif (temp_chunk.ID == MAT_24BIT_COLOR): - contextMaterial.mirror_color = read_byte_color(temp_chunk) -# temp_data = file.read(struct.calcsize('3B')) -# temp_chunk.bytes_read += 3 -# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read += temp_chunk.bytes_read - - elif (new_chunk.ID == MAT_DIFFUSE): - #print 'elif (new_chunk.ID == MAT_DIFFUSE):' - read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_FLOAT_COLOR): - contextMaterial.diffuse_color = read_float_color(temp_chunk) -# temp_data = file.read(struct.calcsize('3f')) -# temp_chunk.bytes_read += 12 -# contextMaterial.rgbCol = [float(col) for col in struct.unpack('<3f', temp_data)] - elif (temp_chunk.ID == MAT_24BIT_COLOR): - contextMaterial.diffuse_color = read_byte_color(temp_chunk) -# temp_data = file.read(struct.calcsize('3B')) -# temp_chunk.bytes_read += 3 -# contextMaterial.rgbCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb - else: - skip_to_end(file, temp_chunk) - -# print("read material diffuse color", contextMaterial.diffuse_color) - - new_chunk.bytes_read += temp_chunk.bytes_read - - elif (new_chunk.ID == MAT_SPECULAR): - #print 'elif (new_chunk.ID == MAT_SPECULAR):' - read_chunk(file, temp_chunk) - if (temp_chunk.ID == MAT_FLOAT_COLOR): - contextMaterial.specular_color = read_float_color(temp_chunk) -# temp_data = file.read(struct.calcsize('3f')) -# temp_chunk.bytes_read += 12 -# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] - elif (temp_chunk.ID == MAT_24BIT_COLOR): - contextMaterial.specular_color = read_byte_color(temp_chunk) -# temp_data = file.read(struct.calcsize('3B')) -# temp_chunk.bytes_read += 3 -# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read += temp_chunk.bytes_read - - elif (new_chunk.ID == MAT_TEXTURE_MAP): - read_texture(new_chunk, temp_chunk, "Diffuse", "COLOR") -# #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):' -# new_texture= bpy.data.textures.new('Diffuse') -# new_texture.setType('Image') -# img = None -# while (new_chunk.bytes_read BOUNDS_3DS[i + 3]: - BOUNDS_3DS[i + 3]= v[i] # min - - # Get the max axis x/y/z - max_axis = max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2]) - # print max_axis - if max_axis < 1 << 30: # Should never be false but just make sure. - - # Get a new scale factor if set as an option - SCALE = 1.0 - while (max_axis * SCALE) > IMPORT_CONSTRAIN_BOUNDS: - SCALE/=10 - - # SCALE Matrix - SCALE_MAT = Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) -# SCALE_MAT = Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) - - for ob in importedObjects: - ob.setMatrix(ob.matrixWorld * SCALE_MAT) - - # Done constraining to bounds. - - # Select all new objects. - print('finished importing: "%s" in %.4f sec.' % (filename, (time.clock()-time1))) -# print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1))) - file.close() -# Blender.Window.WaitCursor(0) - - -DEBUG = False -# if __name__=='__main__' and not DEBUG: -# if calcsize == None: -# Blender.Draw.PupMenu('Error%t|a full python installation not found') -# else: -# Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') - -# For testing compatibility -#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False) -#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False) -''' - -else: - import os - # DEBUG ONLY - TIME = Blender.sys.time() - import os - print 'Searching for files' - os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') - # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') - print '...Done' - file = open('/tmp/temp3ds_list', 'r') - lines = file.readlines() - file.close() - # sort by filesize for faster testing - lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] - lines_size.sort() - lines = [f[1] for f in lines_size] - - - def between(v,a,b): - if v <= max(a,b) and v >= min(a,b): - return True - return False - - for i, _3ds in enumerate(lines): - if between(i, 650,800): - #_3ds= _3ds[:-1] - print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines) - _3ds_file= _3ds.split('/')[-1].split('\\')[-1] - newScn = Blender.Scene.New(_3ds_file) - newScn.makeCurrent() - load_3ds(_3ds, False) - - print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) - -''' - -class IMPORT_OT_3ds(bpy.types.Operator): - ''' - 3DS Importer - ''' - __idname__ = "import.3ds" - __label__ = 'Import 3DS' - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen=1024, default= ""), -# bpy.props.FloatProperty(attr="size_constraint", name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0), -# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True), -# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False), - ] - - def execute(self, context): - load_3ds(self.filename, context, 0.0, False, False) - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - ''' - def poll(self, context): - print("Poll") - return context.active_object != None''' - -bpy.ops.add(IMPORT_OT_3ds) - -# NOTES: -# why add 1 extra vertex? and remove it when done? -# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time) diff --git a/release/io/import_obj.py b/release/io/import_obj.py deleted file mode 100644 index 9a00dc1cc2a..00000000000 --- a/release/io/import_obj.py +++ /dev/null @@ -1,1633 +0,0 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 249 -Group: 'Import' -Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' -""" - -__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" -__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] -__version__= "2.11" - -__bpydoc__= """\ -This script imports a Wavefront OBJ files to Blender. - -Usage: -Run this script from "File->Import" menu and then load the desired OBJ file. -Note, This loads mesh objects and materials only, nurbs and curves are not supported. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton 2007 -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import os -import time -import bpy -import Mathutils -import Geometry - -# from Blender import Mesh, Draw, Window, Texture, Material, sys -# # import BPyMesh -# import BPyImage -# import BPyMessages - -# try: import os -# except: os= False - -# Generic path functions -def stripFile(path): - '''Return directory, where the file is''' - lastSlash= max(path.rfind('\\'), path.rfind('/')) - if lastSlash != -1: - path= path[:lastSlash] - return '%s%s' % (path, os.sep) -# return '%s%s' % (path, sys.sep) - -def stripPath(path): - '''Strips the slashes from the back of a string''' - return path.split('/')[-1].split('\\')[-1] - -def stripExt(name): # name is a string - '''Strips the prefix off the name before writing''' - index= name.rfind('.') - if index != -1: - return name[ : index ] - else: - return name -# end path funcs - -def unpack_list(list_of_tuples): - l = [] - for t in list_of_tuples: - l.extend(t) - return l - -# same as above except that it adds 0 for triangle faces -def unpack_face_list(list_of_tuples): - l = [] - for t in list_of_tuples: - face = [i for i in t] - if len(face) != 3 and len(face) != 4: - raise RuntimeError("{0} vertices in face.".format(len(face))) - if len(face) == 3: - face.append(0) - l.extend(face) - return l - -def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True): - ''' - Takes a polyline of indices (fgon) - and returns a list of face indicie lists. - Designed to be used for importers that need indices for an fgon to create from existing verts. - - from_data: either a mesh, or a list/tuple of vectors. - indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given. - PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. - ''' - - if not set: # Need sets for this, otherwise do a normal fill. - PREF_FIX_LOOPS= False - - Vector= Mathutils.Vector - if not indices: - return [] - - # return [] - def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6) - def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length - - def vert_treplet(v, i): - return v, rvec(v), i, mlen(v) - - def ed_key_mlen(v1, v2): - if v1[3] > v2[3]: - return v2[1], v1[1] - else: - return v1[1], v2[1] - - - if not PREF_FIX_LOOPS: - ''' - Normal single concave loop filling - ''' - if type(from_data) in (tuple, list): - verts= [Vector(from_data[i]) for ii, i in enumerate(indices)] - else: - verts= [from_data.verts[i].co for ii, i in enumerate(indices)] - - for i in range(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))): - if verts[i][1]==verts[i-1][0]: - verts.pop(i-1) - - fill= Geometry.PolyFill([verts]) - - else: - ''' - Seperate this loop into multiple loops be finding edges that are used twice - This is used by lightwave LWO files a lot - ''' - - if type(from_data) in (tuple, list): - verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)] - else: - verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)] - - edges= [(i, i-1) for i in range(len(verts))] - if edges: - edges[0]= (0,len(verts)-1) - - if not verts: - return [] - - - edges_used= set() - edges_doubles= set() - # We need to check if any edges are used twice location based. - for ed in edges: - edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]]) - if edkey in edges_used: - edges_doubles.add(edkey) - else: - edges_used.add(edkey) - - # Store a list of unconnected loop segments split by double edges. - # will join later - loop_segments= [] - - v_prev= verts[0] - context_loop= [v_prev] - loop_segments= [context_loop] - - for v in verts: - if v!=v_prev: - # Are we crossing an edge we removed? - if ed_key_mlen(v, v_prev) in edges_doubles: - context_loop= [v] - loop_segments.append(context_loop) - else: - if context_loop and context_loop[-1][1]==v[1]: - #raise "as" - pass - else: - context_loop.append(v) - - v_prev= v - # Now join loop segments - - def join_seg(s1,s2): - if s2[-1][1]==s1[0][1]: # - s1,s2= s2,s1 - elif s1[-1][1]==s2[0][1]: - pass - else: - return False - - # If were stuill here s1 and s2 are 2 segments in the same polyline - s1.pop() # remove the last vert from s1 - s1.extend(s2) # add segment 2 to segment 1 - - if s1[0][1]==s1[-1][1]: # remove endpoints double - s1.pop() - - s2[:]= [] # Empty this segment s2 so we dont use it again. - return True - - joining_segments= True - while joining_segments: - joining_segments= False - segcount= len(loop_segments) - - for j in range(segcount-1, -1, -1): #reversed(range(segcount)): - seg_j= loop_segments[j] - if seg_j: - for k in range(j-1, -1, -1): # reversed(range(j)): - if not seg_j: - break - seg_k= loop_segments[k] - - if seg_k and join_seg(seg_j, seg_k): - joining_segments= True - - loop_list= loop_segments - - for verts in loop_list: - while verts and verts[0][1]==verts[-1][1]: - verts.pop() - - loop_list= [verts for verts in loop_list if len(verts)>2] - # DONE DEALING WITH LOOP FIXING - - - # vert mapping - vert_map= [None]*len(indices) - ii=0 - for verts in loop_list: - if len(verts)>2: - for i, vert in enumerate(verts): - vert_map[i+ii]= vert[2] - ii+=len(verts) - - fill= Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ]) - #draw_loops(loop_list) - #raise 'done loop' - # map to original indicies - fill= [[vert_map[i] for i in reversed(f)] for f in fill] - - - if not fill: - print('Warning Cannot scanfill, fallback on a triangle fan.') - fill= [ [0, i-1, i] for i in range(2, len(indices)) ] - else: - # Use real scanfill. - # See if its flipped the wrong way. - flip= None - for fi in fill: - if flip != None: - break - for i, vi in enumerate(fi): - if vi==0 and fi[i-1]==1: - flip= False - break - elif vi==1 and fi[i-1]==0: - flip= True - break - - if not flip: - for i, fi in enumerate(fill): - fill[i]= tuple([ii for ii in reversed(fi)]) - - return fill - -def line_value(line_split): - ''' - Returns 1 string represneting the value for this line - None will be returned if theres only 1 word - ''' - length= len(line_split) - if length == 1: - return None - - elif length == 2: - return line_split[1] - - elif length > 2: - return ' '.join( line_split[1:] ) - -# limited replacement for BPyImage.comprehensiveImageLoad -def load_image(imagepath, dirname): - - if os.path.exists(imagepath): - return bpy.data.add_image(imagepath) - - variants = [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))] - - for path in variants: - if os.path.exists(path): - return bpy.data.add_image(path) - else: - print(path, "doesn't exist") - - # TODO comprehensiveImageLoad also searched in bpy.config.textureDir - return None - -def obj_image_load(imagepath, DIR, IMAGE_SEARCH): - - if '_' in imagepath: - image= load_image(imagepath.replace('_', ' '), DIR) - if image: return image - - return load_image(imagepath, DIR) - -# def obj_image_load(imagepath, DIR, IMAGE_SEARCH): -# ''' -# Mainly uses comprehensiveImageLoad -# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores. -# ''' - -# if '_' in imagepath: -# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) -# if image: return image -# # Did the exporter rename the image? -# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) -# if image: return image - -# # Return an image, placeholder if it dosnt exist -# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH) -# return image - - -def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH): - ''' - Create all the used materials in this obj, - assign colors and images to the materials from all referenced material libs - ''' - DIR= stripFile(filepath) - - #==================================================================================# - # This function sets textures defined in .mtl file # - #==================================================================================# - def load_material_image(blender_material, context_material_name, imagepath, type): - - texture= bpy.data.add_texture(type) - texture.type= 'IMAGE' -# texture= bpy.data.textures.new(type) -# texture.setType('Image') - - # Absolute path - c:\.. etc would work here - image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) - has_data = image.has_data if image else False - - if image: - texture.image = image - - # Adds textures for materials (rendering) - if type == 'Kd': - if has_data and image.depth == 32: - # Image has alpha - - # XXX bitmask won't work? - blender_material.add_texture(texture, "UV", ("COLOR", "ALPHA")) - texture.mipmap = True - texture.interpolation = True - texture.use_alpha = True - blender_material.z_transparency = True - blender_material.alpha = 0.0 - -# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) -# texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') -# blender_material.mode |= Material.Modes.ZTRANSP -# blender_material.alpha = 0.0 - else: - blender_material.add_texture(texture, "UV", "COLOR") -# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) - - # adds textures to faces (Textured/Alt-Z mode) - # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func. - unique_material_images[context_material_name]= image, has_data # set the texface image - - elif type == 'Ka': - blender_material.add_texture(texture, "UV", "AMBIENT") -# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API - - elif type == 'Ks': - blender_material.add_texture(texture, "UV", "SPECULARITY") -# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) - - elif type == 'Bump': - blender_material.add_texture(texture, "UV", "NORMAL") -# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR) - elif type == 'D': - blender_material.add_texture(texture, "UV", "ALPHA") - blender_material.z_transparency = True - blender_material.alpha = 0.0 -# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA) -# blender_material.mode |= Material.Modes.ZTRANSP -# blender_material.alpha = 0.0 - # Todo, unset deffuse material alpha if it has an alpha channel - - elif type == 'refl': - blender_material.add_texture(texture, "UV", "REFLECTION") -# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF) - - - # Add an MTL with the same name as the obj if no MTLs are spesified. - temp_mtl= stripExt(stripPath(filepath))+ '.mtl' - - if os.path.exists(DIR + temp_mtl) and temp_mtl not in material_libs: -# if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: - material_libs.append( temp_mtl ) - del temp_mtl - - #Create new materials - for name in unique_materials: # .keys() - if name != None: - unique_materials[name]= bpy.data.add_material(name) -# unique_materials[name]= bpy.data.materials.new(name) - unique_material_images[name]= None, False # assign None to all material images to start with, add to later. - - unique_materials[None]= None - unique_material_images[None]= None, False - - for libname in material_libs: - mtlpath= DIR + libname - if not os.path.exists(mtlpath): -# if not sys.exists(mtlpath): - #print '\tError Missing MTL: "%s"' % mtlpath - pass - else: - #print '\t\tloading mtl: "%s"' % mtlpath - context_material= None - mtl= open(mtlpath, 'rU') - for line in mtl: #.xreadlines(): - if line.startswith('newmtl'): - context_material_name= line_value(line.split()) - if context_material_name in unique_materials: - context_material = unique_materials[ context_material_name ] - else: - context_material = None - - elif context_material: - # we need to make a material to assign properties to it. - line_split= line.split() - line_lower= line.lower().lstrip() - if line_lower.startswith('ka'): - context_material.mirror_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) -# context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) - elif line_lower.startswith('kd'): - context_material.diffuse_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) -# context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) - elif line_lower.startswith('ks'): - context_material.specular_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) -# context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) - elif line_lower.startswith('ns'): - context_material.specular_hardness = int((float(line_split[1])*0.51)) -# context_material.setHardness( int((float(line_split[1])*0.51)) ) - elif line_lower.startswith('ni'): # Refraction index - context_material.ior = max(1, min(float(line_split[1]), 3)) -# context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3 - elif line_lower.startswith('d') or line_lower.startswith('tr'): - context_material.alpha = float(line_split[1]) -# context_material.setAlpha(float(line_split[1])) - elif line_lower.startswith('map_ka'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Ka') - elif line_lower.startswith('map_ks'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Ks') - elif line_lower.startswith('map_kd'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Kd') - elif line_lower.startswith('map_bump'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Bump') - elif line_lower.startswith('map_d') or line_lower.startswith('map_tr'): # Alpha map - Dissolve - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'D') - - elif line_lower.startswith('refl'): # Reflectionmap - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'refl') - mtl.close() - - - - -def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): - ''' - Takes vert_loc and faces, and seperates into multiple sets of - (verts_loc, faces, unique_materials, dataname) - This is done so objects do not overload the 16 material limit. - ''' - - filename = stripExt(stripPath(filepath)) - - if not SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: - # use the filename for the object name since we arnt chopping up the mesh. - return [(verts_loc, faces, unique_materials, filename)] - - - def key_to_name(key): - # if the key is a tuple, join it to make a string - if type(key) == tuple: - return '%s_%s' % key - elif not key: - return filename # assume its a string. make sure this is true if the splitting code is changed - else: - return key - - # Return a key that makes the faces unique. - if SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: - def face_key(face): - return face[4] # object - - elif not SPLIT_OB_OR_GROUP and SPLIT_MATERIALS: - def face_key(face): - return face[2] # material - - else: # Both - def face_key(face): - return face[4], face[2] # object,material - - - face_split_dict= {} - - oldkey= -1 # initialize to a value that will never match the key - - for face in faces: - - key= face_key(face) - - if oldkey != key: - # Check the key has changed. - try: - verts_split, faces_split, unique_materials_split, vert_remap= face_split_dict[key] - except KeyError: - faces_split= [] - verts_split= [] - unique_materials_split= {} - vert_remap= [-1]*len(verts_loc) - - face_split_dict[key]= (verts_split, faces_split, unique_materials_split, vert_remap) - - oldkey= key - - face_vert_loc_indicies= face[0] - - # Remap verts to new vert list and add where needed - for enum, i in enumerate(face_vert_loc_indicies): - if vert_remap[i] == -1: - new_index= len(verts_split) - vert_remap[i]= new_index # set the new remapped index so we only add once and can reference next time. - face_vert_loc_indicies[enum] = new_index # remap to the local index - verts_split.append( verts_loc[i] ) # add the vert to the local verts - - else: - face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index - - matname= face[2] - if matname and matname not in unique_materials_split: - unique_materials_split[matname] = unique_materials[matname] - - faces_split.append(face) - - - # remove one of the itemas and reorder - return [(value[0], value[1], value[2], key_to_name(key)) for key, value in list(face_split_dict.items())] - - -def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): - ''' - Takes all the data gathered and generates a mesh, adding the new object to new_objects - deals with fgons, sharp edges and assigning materials - ''' - if not has_ngons: - CREATE_FGONS= False - - if unique_smooth_groups: - sharp_edges= {} - smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in list(unique_smooth_groups.keys()) ]) - context_smooth_group_old= -1 - - # Split fgons into tri's - fgon_edges= {} # Used for storing fgon keys - if CREATE_EDGES: - edges= [] - - context_object= None - - # reverse loop through face indicies - for f_idx in range(len(faces)-1, -1, -1): - - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object= faces[f_idx] - - len_face_vert_loc_indicies = len(face_vert_loc_indicies) - - if len_face_vert_loc_indicies==1: - faces.pop(f_idx)# cant add single vert faces - - elif not face_vert_tex_indicies or len_face_vert_loc_indicies == 2: # faces that have no texture coords are lines - if CREATE_EDGES: - # generators are better in python 2.4+ but can't be used in 2.3 - # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) ) - edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in range(len_face_vert_loc_indicies-1)] ) - - faces.pop(f_idx) - else: - - # Smooth Group - if unique_smooth_groups and context_smooth_group: - # Is a part of of a smooth group and is a face - if context_smooth_group_old is not context_smooth_group: - edge_dict= smooth_group_users[context_smooth_group] - context_smooth_group_old= context_smooth_group - - for i in range(len_face_vert_loc_indicies): - i1= face_vert_loc_indicies[i] - i2= face_vert_loc_indicies[i-1] - if i1>i2: i1,i2= i2,i1 - - try: - edge_dict[i1,i2]+= 1 - except KeyError: - edge_dict[i1,i2]= 1 - - # FGons into triangles - if has_ngons and len_face_vert_loc_indicies > 4: - - ngon_face_indices= BPyMesh_ngon(verts_loc, face_vert_loc_indicies) - faces.extend(\ - [(\ - [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ - [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ - context_material,\ - context_smooth_group,\ - context_object)\ - for ngon in ngon_face_indices]\ - ) - - # edges to make fgons - if CREATE_FGONS: - edge_users= {} - for ngon in ngon_face_indices: - for i in (0,1,2): - i1= face_vert_loc_indicies[ngon[i ]] - i2= face_vert_loc_indicies[ngon[i-1]] - if i1>i2: i1,i2= i2,i1 - - try: - edge_users[i1,i2]+=1 - except KeyError: - edge_users[i1,i2]= 1 - - for key, users in edge_users.items(): - if users>1: - fgon_edges[key]= None - - # remove all after 3, means we dont have to pop this one. - faces.pop(f_idx) - - - # Build sharp edges - if unique_smooth_groups: - for edge_dict in list(smooth_group_users.values()): - for key, users in list(edge_dict.items()): - if users==1: # This edge is on the boundry of a group - sharp_edges[key]= None - - - # map the material names to an index - material_mapping= dict([(name, i) for i, name in enumerate(unique_materials)]) # enumerate over unique_materials keys() - - materials= [None] * len(unique_materials) - - for name, index in list(material_mapping.items()): - materials[index]= unique_materials[name] - - me= bpy.data.add_mesh(dataname) -# me= bpy.data.meshes.new(dataname) - - # make sure the list isnt too big - for material in materials[0:16]: - me.add_material(material) -# me.materials= materials[0:16] # make sure the list isnt too big. - #me.verts.extend([(0,0,0)]) # dummy vert - - me.add_geometry(len(verts_loc), 0, len(faces)) - - # verts_loc is a list of (x, y, z) tuples - me.verts.foreach_set("co", unpack_list(verts_loc)) -# me.verts.extend(verts_loc) - - # faces is a list of (vert_indices, texco_indices, ...) tuples - # XXX faces should not contain edges - # XXX no check for valid face indices - me.faces.foreach_set("verts", unpack_face_list([f[0] for f in faces])) -# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True) - - if verts_tex and me.faces: - me.add_uv_texture() -# me.faceUV= 1 - # TEXMODE= Mesh.FaceModes['TEX'] - - context_material_old= -1 # avoid a dict lookup - mat= 0 # rare case it may be un-initialized. - me_faces= me.faces -# ALPHA= Mesh.FaceTranspModes.ALPHA - - for i, face in enumerate(faces): - if len(face[0]) < 2: - pass #raise "bad face" - elif len(face[0])==2: - if CREATE_EDGES: - edges.append(face[0]) - else: -# face_index_map= face_mapping[i] - - # since we use foreach_set to add faces, all of them are added - if 1: -# if face_index_map!=None: # None means the face wasnt added - - blender_face = me.faces[i] -# blender_face= me_faces[face_index_map] - - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object= face - - - - if context_smooth_group: - blender_face.smooth= True - - if context_material: - if context_material_old is not context_material: - mat= material_mapping[context_material] - if mat>15: - mat= 15 - context_material_old= context_material - - blender_face.material_index= mat -# blender_face.mat= mat - - - if verts_tex: - - blender_tface= me.uv_textures[0].data[i] - - if context_material: - image, has_data= unique_material_images[context_material] - if image: # Can be none if the material dosnt have an image. - blender_tface.image= image -# blender_face.image= image - if has_data: -# if has_data and image.depth == 32: - blender_tface.transp = 'ALPHA' -# blender_face.transp |= ALPHA - - # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled. - if len(face_vert_loc_indicies)==4: - if face_vert_loc_indicies[2]==0 or face_vert_loc_indicies[3]==0: - face_vert_tex_indicies= face_vert_tex_indicies[2], face_vert_tex_indicies[3], face_vert_tex_indicies[0], face_vert_tex_indicies[1] - else: # length of 3 - if face_vert_loc_indicies[2]==0: - face_vert_tex_indicies= face_vert_tex_indicies[1], face_vert_tex_indicies[2], face_vert_tex_indicies[0] - # END EEEKADOODLE FIX - - # assign material, uv's and image - blender_tface.uv1= verts_tex[face_vert_tex_indicies[0]] - blender_tface.uv2= verts_tex[face_vert_tex_indicies[1]] - blender_tface.uv3= verts_tex[face_vert_tex_indicies[2]] - - if blender_face.verts[3] != 0: - blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]] - -# for ii, uv in enumerate(blender_face.uv): -# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]] - del me_faces -# del ALPHA - - if CREATE_EDGES: - - me.add_geometry(0, len(edges), 0) - - # edges should be a list of (a, b) tuples - me.edges.foreach_set("verts", unpack_list(edges)) -# me_edges.extend( edges ) - -# del me_edges - - # Add edge faces. -# me_edges= me.edges - - def edges_match(e1, e2): - return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0]) - - # XXX slow -# if CREATE_FGONS and fgon_edges: -# for fgon_edge in fgon_edges.keys(): -# for ed in me.edges: -# if edges_match(fgon_edge, ed.verts): -# ed.fgon = True - -# if CREATE_FGONS and fgon_edges: -# FGON= Mesh.EdgeFlags.FGON -# for ed in me.findEdges( fgon_edges.keys() ): -# if ed!=None: -# me_edges[ed].flag |= FGON -# del FGON - - # XXX slow -# if unique_smooth_groups and sharp_edges: -# for sharp_edge in sharp_edges.keys(): -# for ed in me.edges: -# if edges_match(sharp_edge, ed.verts): -# ed.sharp = True - -# if unique_smooth_groups and sharp_edges: -# SHARP= Mesh.EdgeFlags.SHARP -# for ed in me.findEdges( sharp_edges.keys() ): -# if ed!=None: -# me_edges[ed].flag |= SHARP -# del SHARP - - me.update() -# me.calcNormals() - - ob= bpy.data.add_object("MESH", "Mesh") - ob.data= me - scn.add_object(ob) -# ob= scn.objects.new(me) - new_objects.append(ob) - - # Create the vertex groups. No need to have the flag passed here since we test for the - # content of the vertex_groups. If the user selects to NOT have vertex groups saved then - # the following test will never run - for group_name, group_indicies in vertex_groups.items(): - group= ob.add_vertex_group(group_name) -# me.addVertGroup(group_name) - for vertex_index in group_indicies: - ob.add_vertex_to_group(vertex_index, group, 1.0, 'REPLACE') -# me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE) - - -def create_nurbs(scn, context_nurbs, vert_loc, new_objects): - ''' - Add nurbs object to blender, only support one type at the moment - ''' - deg = context_nurbs.get('deg', (3,)) - curv_range = context_nurbs.get('curv_range', None) - curv_idx = context_nurbs.get('curv_idx', []) - parm_u = context_nurbs.get('parm_u', []) - parm_v = context_nurbs.get('parm_v', []) - name = context_nurbs.get('name', 'ObjNurb') - cstype = context_nurbs.get('cstype', None) - - if cstype == None: - print('\tWarning, cstype not found') - return - if cstype != 'bspline': - print('\tWarning, cstype is not supported (only bspline)') - return - if not curv_idx: - print('\tWarning, curv argument empty or not set') - return - if len(deg) > 1 or parm_v: - print('\tWarning, surfaces not supported') - return - - cu = bpy.data.curves.new(name, 'Curve') - cu.flag |= 1 # 3D curve - - nu = None - for pt in curv_idx: - - pt = vert_loc[pt] - pt = (pt[0], pt[1], pt[2], 1.0) - - if nu == None: - nu = cu.appendNurb(pt) - else: - nu.append(pt) - - nu.orderU = deg[0]+1 - - # get for endpoint flag from the weighting - if curv_range and len(parm_u) > deg[0]+1: - do_endpoints = True - for i in range(deg[0]+1): - - if abs(parm_u[i]-curv_range[0]) > 0.0001: - do_endpoints = False - break - - if abs(parm_u[-(i+1)]-curv_range[1]) > 0.0001: - do_endpoints = False - break - - else: - do_endpoints = False - - if do_endpoints: - nu.flagU |= 2 - - - # close - ''' - do_closed = False - if len(parm_u) > deg[0]+1: - for i in xrange(deg[0]+1): - #print curv_idx[i], curv_idx[-(i+1)] - - if curv_idx[i]==curv_idx[-(i+1)]: - do_closed = True - break - - if do_closed: - nu.flagU |= 1 - ''' - - ob = scn.objects.new(cu) - new_objects.append(ob) - - -def strip_slash(line_split): - if line_split[-1][-1]== '\\': - if len(line_split[-1])==1: - line_split.pop() # remove the \ item - else: - line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number - return True - return False - - - -def get_float_func(filepath): - ''' - find the float function for this obj file - - weather to replace commas or not - ''' - file= open(filepath, 'rU') - for line in file: #.xreadlines(): - line = line.lstrip() - if line.startswith('v'): # vn vt v - if ',' in line: - return lambda f: float(f.replace(',', '.')) - elif '.' in line: - return float - - # incase all vert values were ints - return float - -def load_obj(filepath, - context, - CLAMP_SIZE= 0.0, - CREATE_FGONS= True, - CREATE_SMOOTH_GROUPS= True, - CREATE_EDGES= True, - SPLIT_OBJECTS= True, - SPLIT_GROUPS= True, - SPLIT_MATERIALS= True, - ROTATE_X90= True, - IMAGE_SEARCH=True, - POLYGROUPS=False): - ''' - Called by the user interface or another script. - load_obj(path) - should give acceptable results. - This function passes the file and sends the data off - to be split into objects and then converted into mesh objects - ''' - print('\nimporting obj "%s"' % filepath) - - if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: - POLYGROUPS = False - - time_main= time.time() -# time_main= sys.time() - - verts_loc= [] - verts_tex= [] - faces= [] # tuples of the faces - material_libs= [] # filanems to material libs this uses - vertex_groups = {} # when POLYGROUPS is true - - # Get the string to float conversion func for this file- is 'float' for almost all files. - float_func= get_float_func(filepath) - - # Context variables - context_material= None - context_smooth_group= None - context_object= None - context_vgroup = None - - # Nurbs - context_nurbs = {} - nurbs = [] - context_parm = '' # used by nurbs too but could be used elsewhere - - has_ngons= False - # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0 - - # Until we can use sets - unique_materials= {} - unique_material_images= {} - unique_smooth_groups= {} - # unique_obects= {} - no use for this variable since the objects are stored in the face. - - # when there are faces that end with \ - # it means they are multiline- - # since we use xreadline we cant skip to the next line - # so we need to know weather - context_multi_line= '' - - print('\tparsing obj file "%s"...' % filepath) - time_sub= time.time() -# time_sub= sys.time() - - file= open(filepath, 'rU') - for line in file: #.xreadlines(): - line = line.lstrip() # rare cases there is white space at the start of the line - - if line.startswith('v '): - line_split= line.split() - # rotate X90: (x,-z,y) - verts_loc.append( (float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])) ) - - elif line.startswith('vn '): - pass - - elif line.startswith('vt '): - line_split= line.split() - verts_tex.append( (float_func(line_split[1]), float_func(line_split[2])) ) - - # Handel faces lines (as faces) and the second+ lines of fa multiline face here - # use 'f' not 'f ' because some objs (very rare have 'fo ' for faces) - elif line.startswith('f') or context_multi_line == 'f': - - if context_multi_line: - # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face - line_split= line.split() - - else: - line_split= line[2:].split() - face_vert_loc_indicies= [] - face_vert_tex_indicies= [] - - # Instance a face - faces.append((\ - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object\ - )) - - if strip_slash(line_split): - context_multi_line = 'f' - else: - context_multi_line = '' - - for v in line_split: - obj_vert= v.split('/') - - vert_loc_index= int(obj_vert[0])-1 - # Add the vertex to the current group - # *warning*, this wont work for files that have groups defined around verts - if POLYGROUPS and context_vgroup: - vertex_groups[context_vgroup].append(vert_loc_index) - - # Make relative negative vert indicies absolute - if vert_loc_index < 0: - vert_loc_index= len(verts_loc) + vert_loc_index + 1 - - face_vert_loc_indicies.append(vert_loc_index) - - if len(obj_vert)>1 and obj_vert[1]: - # formatting for faces with normals and textures us - # loc_index/tex_index/nor_index - - vert_tex_index= int(obj_vert[1])-1 - # Make relative negative vert indicies absolute - if vert_tex_index < 0: - vert_tex_index= len(verts_tex) + vert_tex_index + 1 - - face_vert_tex_indicies.append(vert_tex_index) - else: - # dummy - face_vert_tex_indicies.append(0) - - if len(face_vert_loc_indicies) > 4: - has_ngons= True - - elif CREATE_EDGES and (line.startswith('l ') or context_multi_line == 'l'): - # very similar to the face load function above with some parts removed - - if context_multi_line: - # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face - line_split= line.split() - - else: - line_split= line[2:].split() - face_vert_loc_indicies= [] - face_vert_tex_indicies= [] - - # Instance a face - faces.append((\ - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object\ - )) - - if strip_slash(line_split): - context_multi_line = 'l' - else: - context_multi_line = '' - - isline= line.startswith('l') - - for v in line_split: - vert_loc_index= int(v)-1 - - # Make relative negative vert indicies absolute - if vert_loc_index < 0: - vert_loc_index= len(verts_loc) + vert_loc_index + 1 - - face_vert_loc_indicies.append(vert_loc_index) - - elif line.startswith('s'): - if CREATE_SMOOTH_GROUPS: - context_smooth_group= line_value(line.split()) - if context_smooth_group=='off': - context_smooth_group= None - elif context_smooth_group: # is not None - unique_smooth_groups[context_smooth_group]= None - - elif line.startswith('o'): - if SPLIT_OBJECTS: - context_object= line_value(line.split()) - # unique_obects[context_object]= None - - elif line.startswith('g'): - if SPLIT_GROUPS: - context_object= line_value(line.split()) - # print 'context_object', context_object - # unique_obects[context_object]= None - elif POLYGROUPS: - context_vgroup = line_value(line.split()) - if context_vgroup and context_vgroup != '(null)': - vertex_groups.setdefault(context_vgroup, []) - else: - context_vgroup = None # dont assign a vgroup - - elif line.startswith('usemtl'): - context_material= line_value(line.split()) - unique_materials[context_material]= None - elif line.startswith('mtllib'): # usemap or usemat - material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line - - - # Nurbs support - elif line.startswith('cstype '): - context_nurbs['cstype']= line_value(line.split()) # 'rat bspline' / 'bspline' - elif line.startswith('curv ') or context_multi_line == 'curv': - line_split= line.split() - - curv_idx = context_nurbs['curv_idx'] = context_nurbs.get('curv_idx', []) # incase were multiline - - if not context_multi_line: - context_nurbs['curv_range'] = float_func(line_split[1]), float_func(line_split[2]) - line_split[0:3] = [] # remove first 3 items - - if strip_slash(line_split): - context_multi_line = 'curv' - else: - context_multi_line = '' - - - for i in line_split: - vert_loc_index = int(i)-1 - - if vert_loc_index < 0: - vert_loc_index= len(verts_loc) + vert_loc_index + 1 - - curv_idx.append(vert_loc_index) - - elif line.startswith('parm') or context_multi_line == 'parm': - line_split= line.split() - - if context_multi_line: - context_multi_line = '' - else: - context_parm = line_split[1] - line_split[0:2] = [] # remove first 2 - - if strip_slash(line_split): - context_multi_line = 'parm' - else: - context_multi_line = '' - - if context_parm.lower() == 'u': - context_nurbs.setdefault('parm_u', []).extend( [float_func(f) for f in line_split] ) - elif context_parm.lower() == 'v': # surfaces not suported yet - context_nurbs.setdefault('parm_v', []).extend( [float_func(f) for f in line_split] ) - # else: # may want to support other parm's ? - - elif line.startswith('deg '): - context_nurbs['deg']= [int(i) for i in line.split()[1:]] - elif line.startswith('end'): - # Add the nurbs curve - if context_object: - context_nurbs['name'] = context_object - nurbs.append(context_nurbs) - context_nurbs = {} - context_parm = '' - - ''' # How to use usemap? depricated? - elif line.startswith('usema'): # usemap or usemat - context_image= line_value(line.split()) - ''' - - file.close() - time_new= time.time() -# time_new= sys.time() - print('%.4f sec' % (time_new-time_sub)) - time_sub= time_new - - - print('\tloading materials and images...') - create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) - - time_new= time.time() -# time_new= sys.time() - print('%.4f sec' % (time_new-time_sub)) - time_sub= time_new - - if not ROTATE_X90: - verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] - - # deselect all -# if context.selected_objects: -# bpy.ops.OBJECT_OT_select_all_toggle() - - scene = context.scene -# scn = bpy.data.scenes.active -# scn.objects.selected = [] - new_objects= [] # put new objects here - - print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) )) - # Split the mesh by objects/materials, may - if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True - else: SPLIT_OB_OR_GROUP = False - - for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): - # Create meshes from the data, warning 'vertex_groups' wont support splitting - create_mesh(scene, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) - - # nurbs support -# for context_nurbs in nurbs: -# create_nurbs(scn, context_nurbs, verts_loc, new_objects) - - - axis_min= [ 1000000000]*3 - axis_max= [-1000000000]*3 - -# if CLAMP_SIZE: -# # Get all object bounds -# for ob in new_objects: -# for v in ob.getBoundBox(): -# for axis, value in enumerate(v): -# if axis_min[axis] > value: axis_min[axis]= value -# if axis_max[axis] < value: axis_max[axis]= value - -# # Scale objects -# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2]) -# scale= 1.0 - -# while CLAMP_SIZE < max_axis * scale: -# scale= scale/10.0 - -# for ob in new_objects: -# ob.setSize(scale, scale, scale) - - # Better rotate the vert locations - #if not ROTATE_X90: - # for ob in new_objects: - # ob.RotX = -1.570796326794896558 - - time_new= time.time() -# time_new= sys.time() - - print('%.4f sec' % (time_new-time_sub)) - print('finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main))) - - -DEBUG= True - - -def load_obj_ui(filepath, BATCH_LOAD= False): - if BPyMessages.Error_NoFile(filepath): - return - - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 - - CREATE_SMOOTH_GROUPS= Draw.Create(0) - CREATE_FGONS= Draw.Create(1) - CREATE_EDGES= Draw.Create(1) - SPLIT_OBJECTS= Draw.Create(0) - SPLIT_GROUPS= Draw.Create(0) - SPLIT_MATERIALS= Draw.Create(0) - CLAMP_SIZE= Draw.Create(10.0) - IMAGE_SEARCH= Draw.Create(1) - POLYGROUPS= Draw.Create(0) - KEEP_VERT_ORDER= Draw.Create(1) - ROTATE_X90= Draw.Create(1) - - - # Get USER Options - # Note, Works but not pretty, instead use a more complicated GUI - ''' - pup_block= [\ - 'Import...',\ - ('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\ - ('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\ - ('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\ - 'Separate objects from obj...',\ - ('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\ - ('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\ - ('Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)'),\ - 'Options...',\ - ('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ - ('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\ - ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\ - ] - - if not Draw.PupBlock('Import OBJ...', pup_block): - return - - if KEEP_VERT_ORDER.val: - SPLIT_OBJECTS.val = False - SPLIT_GROUPS.val = False - SPLIT_MATERIALS.val = False - ''' - - - - # BEGIN ALTERNATIVE UI ******************* - if True: - - EVENT_NONE = 0 - EVENT_EXIT = 1 - EVENT_REDRAW = 2 - EVENT_IMPORT = 3 - - GLOBALS = {} - GLOBALS['EVENT'] = EVENT_REDRAW - #GLOBALS['MOUSE'] = Window.GetMouseCoords() - GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] - - def obj_ui_set_event(e,v): - GLOBALS['EVENT'] = e - - def do_split(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS - if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val: - KEEP_VERT_ORDER.val = 0 - POLYGROUPS.val = 0 - else: - KEEP_VERT_ORDER.val = 1 - - def do_vertorder(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER - if KEEP_VERT_ORDER.val: - SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 - else: - if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val): - KEEP_VERT_ORDER.val = 1 - - def do_polygroups(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS - if POLYGROUPS.val: - SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 - - def do_help(e,v): - url = __url__[0] - print('Trying to open web browser with documentation at this address...') - print('\t' + url) - - try: - import webbrowser - webbrowser.open(url) - except: - print('...could not open a browser window.') - - def obj_ui(): - ui_x, ui_y = GLOBALS['MOUSE'] - - # Center based on overall pup size - ui_x -= 165 - ui_y -= 90 - - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 - - Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21) - Draw.BeginAlign() - CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges') - CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons') - CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges') - Draw.EndAlign() - - Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20) - Draw.BeginAlign() - SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split) - SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split) - SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+119, ui_y+89, 60, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split) - Draw.EndAlign() - - # Only used for user feedback - KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) - - ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.') - - Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20) - CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') - POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups) - IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)') - Draw.BeginAlign() - Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help) - Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event) - Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event) - Draw.EndAlign() - - - # hack so the toggle buttons redraw. this is not nice at all - while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT): - Draw.UIBlock(obj_ui, 0) - - if GLOBALS['EVENT'] != EVENT_IMPORT: - return - - # END ALTERNATIVE UI ********************* - - - - - - - - Window.WaitCursor(1) - - if BATCH_LOAD: # load the dir - try: - files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ] - except: - Window.WaitCursor(0) - Draw.PupMenu('Error%t|Could not open path ' + filepath) - return - - if not files: - Window.WaitCursor(0) - Draw.PupMenu('Error%t|No files at path ' + filepath) - return - - for f in files: - scn= bpy.data.scenes.new( stripExt(f) ) - scn.makeCurrent() - - load_obj(sys.join(filepath, f),\ - CLAMP_SIZE.val,\ - CREATE_FGONS.val,\ - CREATE_SMOOTH_GROUPS.val,\ - CREATE_EDGES.val,\ - SPLIT_OBJECTS.val,\ - SPLIT_GROUPS.val,\ - SPLIT_MATERIALS.val,\ - ROTATE_X90.val,\ - IMAGE_SEARCH.val,\ - POLYGROUPS.val - ) - - else: # Normal load - load_obj(filepath,\ - CLAMP_SIZE.val,\ - CREATE_FGONS.val,\ - CREATE_SMOOTH_GROUPS.val,\ - CREATE_EDGES.val,\ - SPLIT_OBJECTS.val,\ - SPLIT_GROUPS.val,\ - SPLIT_MATERIALS.val,\ - ROTATE_X90.val,\ - IMAGE_SEARCH.val,\ - POLYGROUPS.val - ) - - Window.WaitCursor(0) - - -def load_obj_ui_batch(file): - load_obj_ui(file, True) - -DEBUG= False - -# if __name__=='__main__' and not DEBUG: -# if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT: -# Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '') -# else: -# Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') - - # For testing compatibility -''' -else: - # DEBUG ONLY - TIME= sys.time() - DIR = '/fe/obj' - import os - print 'Searching for files' - def fileList(path): - for dirpath, dirnames, filenames in os.walk(path): - for filename in filenames: - yield os.path.join(dirpath, filename) - - files = [f for f in fileList(DIR) if f.lower().endswith('.obj')] - files.sort() - - for i, obj_file in enumerate(files): - if 0 < i < 20: - print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files) - newScn= bpy.data.scenes.new(os.path.basename(obj_file)) - newScn.makeCurrent() - load_obj(obj_file, False, IMAGE_SEARCH=0) - - print 'TOTAL TIME: %.6f' % (sys.time() - TIME) -''' -#load_obj('/test.obj') -#load_obj('/fe/obj/mba1.obj') - - - -class IMPORT_OT_obj(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' - __idname__ = "import.obj" - __label__ = "Import OBJ" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [ - bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), - - bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True), - bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True), - bpy.props.BoolProperty(attr="CREATE_EDGES", name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True), - bpy.props.BoolProperty(attr="SPLIT_OBJECTS", name="Object", description="Import OBJ Objects into Blender Objects", default= True), - bpy.props.BoolProperty(attr="SPLIT_GROUPS", name="Group", description="Import OBJ Groups into Blender Objects", default= True), - bpy.props.BoolProperty(attr="SPLIT_MATERIALS", name="Material", description="Import each material into a seperate mesh (Avoids > 16 per mesh error)", default= True), - # old comment: only used for user feedback - # disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj - # bpy.props.BoolProperty(attr="KEEP_VERT_ORDER", name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True), - bpy.props.BoolProperty(attr="ROTATE_X90", name="-X90", description="Rotate X 90.", default= True), - bpy.props.FloatProperty(attr="CLAMP_SIZE", name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.01, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0), - bpy.props.BoolProperty(attr="POLYGROUPS", name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True), - bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True), - ] - - ''' - def poll(self, context): - return True ''' - - def execute(self, context): - # print("Selected: " + context.active_object.name) - - if not self.filename: - raise Exception("filename not set") - - load_obj(self.filename, - context, - self.CLAMP_SIZE, - self.CREATE_FGONS, - self.CREATE_SMOOTH_GROUPS, - self.CREATE_EDGES, - self.SPLIT_OBJECTS, - self.SPLIT_GROUPS, - self.SPLIT_MATERIALS, - self.ROTATE_X90, - self.IMAGE_SEARCH, - self.POLYGROUPS) - - return ('FINISHED',) - - def invoke(self, context, event): - wm = context.manager - wm.add_fileselect(self.__operator__) - return ('RUNNING_MODAL',) - - -bpy.ops.add(IMPORT_OT_obj) - - -# NOTES (all line numbers refer to 2.4x import_obj.py, not this file) -# check later: line 489 -# can convert now: edge flags, edges: lines 508-528 -# ngon (uses python module BPyMesh): 384-414 -# nurbs: 947- -# NEXT clamp size: get bound box with RNA -# get back to l 140 (here) -# search image in bpy.config.textureDir - load_image -# replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load) -# bitmask won't work? - 132 -# uses operator bpy.ops.OBJECT_OT_select_all_toggle() to deselect all (not necessary?) -# uses bpy.sys.time() diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py deleted file mode 100644 index 4a1dd2238e3..00000000000 --- a/release/io/netrender/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# This directory is a Python package. - -import model -import operators -import client -import slave -import master -import master_html -import utils -import balancing -import ui - -# store temp data in bpy module - -import bpy - -bpy.data.netrender_jobs = [] -bpy.data.netrender_slaves = [] -bpy.data.netrender_blacklist = [] \ No newline at end of file diff --git a/release/io/netrender/balancing.py b/release/io/netrender/balancing.py deleted file mode 100644 index 637dd5ff92e..00000000000 --- a/release/io/netrender/balancing.py +++ /dev/null @@ -1,94 +0,0 @@ -import time - -from netrender.utils import * -import netrender.model - -class RatingRule: - def rate(self, job): - return 0 - -class ExclusionRule: - def test(self, job): - return False - -class PriorityRule: - def test(self, job): - return False - -class Balancer: - def __init__(self): - self.rules = [] - self.priorities = [] - self.exceptions = [] - - def addRule(self, rule): - self.rules.append(rule) - - def addPriority(self, priority): - self.priorities.append(priority) - - def addException(self, exception): - self.exceptions.append(exception) - - def applyRules(self, job): - return sum((rule.rate(job) for rule in self.rules)) - - def applyPriorities(self, job): - for priority in self.priorities: - if priority.test(job): - return True # priorities are first - - return False - - def applyExceptions(self, job): - for exception in self.exceptions: - if exception.test(job): - return True # exceptions are last - - return False - - def sortKey(self, job): - return (1 if self.applyExceptions(job) else 0, # exceptions after - 0 if self.applyPriorities(job) else 1, # priorities first - self.applyRules(job)) - - def balance(self, jobs): - if jobs: - jobs.sort(key=self.sortKey) - return jobs[0] - else: - return None - -# ========================== - -class RatingUsage(RatingRule): - def rate(self, job): - # less usage is better - return job.usage / job.priority - -class NewJobPriority(PriorityRule): - def __init__(self, limit = 1): - self.limit = limit - - def test(self, job): - return job.countFrames(status = DONE) < self.limit - -class MinimumTimeBetweenDispatchPriority(PriorityRule): - def __init__(self, limit = 10): - self.limit = limit - - def test(self, job): - return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit - -class ExcludeQueuedEmptyJob(ExclusionRule): - def test(self, job): - return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0 - -class ExcludeSlavesLimit(ExclusionRule): - def __init__(self, count_jobs, count_slaves, limit = 0.75): - self.count_jobs = count_jobs - self.count_slaves = count_slaves - self.limit = limit - - def test(self, job): - return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py deleted file mode 100644 index 65b2937867f..00000000000 --- a/release/io/netrender/client.py +++ /dev/null @@ -1,203 +0,0 @@ -import bpy -import sys, os, re -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -import netrender.slave as slave -import netrender.master as master -from netrender.utils import * - - -def clientSendJob(conn, scene, anim = False, chunks = 5): - netsettings = scene.network_render - job = netrender.model.RenderJob() - - if anim: - for f in range(scene.start_frame, scene.end_frame + 1): - job.addFrame(f) - else: - job.addFrame(scene.current_frame) - - filename = bpy.data.filename - job.addFile(filename) - - job_name = netsettings.job_name - path, name = os.path.split(filename) - if job_name == "[default]": - job_name = name - - ########################### - # LIBRARIES - ########################### - for lib in bpy.data.libraries: - lib_path = lib.filename - - if lib_path.startswith("//"): - lib_path = path + os.sep + lib_path[2:] - - job.addFile(lib_path) - - ########################### - # POINT CACHES - ########################### - - root, ext = os.path.splitext(name) - cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - - if os.path.exists(cache_path): - caches = {} - pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") - for cache_file in sorted(os.listdir(cache_path)): - match = pattern.match(cache_file) - - if match: - cache_id = match.groups()[0] - cache_frame = int(match.groups()[1]) - - cache_files = caches.get(cache_id, []) - cache_files.append((cache_frame, cache_file)) - caches[cache_id] = cache_files - - for cache in caches.values(): - cache.sort() - - if len(cache) == 1: - cache_frame, cache_file = cache[0] - job.addFile(cache_path + cache_file, cache_frame, cache_frame) - else: - for i in range(len(cache)): - current_item = cache[i] - next_item = cache[i+1] if i + 1 < len(cache) else None - previous_item = cache[i - 1] if i > 0 else None - - current_frame, current_file = current_item - - if not next_item and not previous_item: - job.addFile(cache_path + current_file, current_frame, current_frame) - elif next_item and not previous_item: - next_frame = next_item[0] - job.addFile(cache_path + current_file, current_frame, next_frame - 1) - elif not next_item and previous_item: - previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, current_frame) - else: - next_frame = next_item[0] - previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) - - ########################### - # IMAGES - ########################### - for image in bpy.data.images: - if image.source == "FILE" and not image.packed_file: - job.addFile(image.filename) - - # print(job.files) - - job.name = job_name - - for slave in scene.network_render.slaves_blacklist: - job.blacklist.append(slave.id) - - job.chunks = netsettings.chunks - job.priority = netsettings.priority - - # try to send path first - conn.request("POST", "/job", repr(job.serialize())) - response = conn.getresponse() - - job_id = response.getheader("job-id") - - # if not ACCEPTED (but not processed), send files - if response.status == http.client.ACCEPTED: - for filepath, start, end in job.files: - f = open(filepath, "rb") - conn.request("PUT", "/file", f, headers={"job-id": job_id, "job-file": filepath}) - f.close() - response = conn.getresponse() - - # server will reply with NOT_FOUD until all files are found - - return job_id - -def requestResult(conn, job_id, frame): - conn.request("GET", "/render", headers={"job-id": job_id, "job-frame":str(frame)}) - -@rnaType -class NetworkRenderEngine(bpy.types.RenderEngine): - __idname__ = 'NET_RENDER' - __label__ = "Network Render" - def render(self, scene): - if scene.network_render.mode == "RENDER_CLIENT": - self.render_client(scene) - elif scene.network_render.mode == "RENDER_SLAVE": - self.render_slave(scene) - elif scene.network_render.mode == "RENDER_MASTER": - self.render_master(scene) - else: - print("UNKNOWN OPERATION MODE") - - def render_master(self, scene): - netsettings = scene.network_render - - address = "" if netsettings.server_address == "[default]" else netsettings.server_address - - master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break) - - - def render_slave(self, scene): - slave.render_slave(self, scene) - - def render_client(self, scene): - netsettings = scene.network_render - self.update_stats("", "Network render client initiation") - - - conn = clientConnection(scene) - - if conn: - # Sending file - - self.update_stats("", "Network render exporting") - - job_id = netsettings.job_id - - # reading back result - - self.update_stats("", "Network render waiting for results") - - requestResult(conn, job_id, scene.current_frame) - response = conn.getresponse() - - if response.status == http.client.NO_CONTENT: - netsettings.job_id = clientSendJob(conn, scene) - requestResult(conn, job_id, scene.current_frame) - - while response.status == http.client.ACCEPTED and not self.test_break(): - time.sleep(1) - requestResult(conn, job_id, scene.current_frame) - response = conn.getresponse() - - if response.status != http.client.OK: - conn.close() - return - - r = scene.render_data - x= int(r.resolution_x*r.resolution_percentage*0.01) - y= int(r.resolution_y*r.resolution_percentage*0.01) - - f = open(netsettings.path + "output.exr", "wb") - buf = response.read(1024) - - while buf: - f.write(buf) - buf = response.read(1024) - - f.close() - - result = self.begin_result(0, 0, x, y) - result.load_from_file(netsettings.path + "output.exr", 0, 0) - self.end_result(result) - - conn.close() - diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py deleted file mode 100644 index a3e186a9cfd..00000000000 --- a/release/io/netrender/master.py +++ /dev/null @@ -1,752 +0,0 @@ -import sys, os -import http, http.client, http.server, urllib, socket -import subprocess, shutil, time, hashlib - -from netrender.utils import * -import netrender.model -import netrender.balancing -import netrender.master_html - -class MRenderFile: - def __init__(self, filepath, start, end): - self.filepath = filepath - self.start = start - self.end = end - self.found = False - - def test(self): - self.found = os.path.exists(self.filepath) - return self.found - - -class MRenderSlave(netrender.model.RenderSlave): - def __init__(self, name, address, stats): - super().__init__() - self.id = hashlib.md5(bytes(repr(name) + repr(address), encoding='utf8')).hexdigest() - self.name = name - self.address = address - self.stats = stats - self.last_seen = time.time() - - self.job = None - self.job_frames = [] - - netrender.model.RenderSlave._slave_map[self.id] = self - - def seen(self): - self.last_seen = time.time() - - def finishedFrame(self, frame_number): - self.job_frames.remove(frame_number) - if not self.job_frames: - self.job = None - -class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []): - super().__init__() - self.id = job_id - self.name = name - self.files = files - self.frames = [] - self.chunks = chunks - self.priority = priority - self.usage = 0.0 - self.blacklist = blacklist - self.last_dispatched = time.time() - - # special server properties - self.last_update = 0 - self.save_path = "" - self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} - self.status = JOB_WAITING - - def save(self): - if self.save_path: - f = open(self.save_path + "job.txt", "w") - f.write(repr(self.serialize())) - f.close() - - def testStart(self): - for f in self.files_map.values(): - if not f.test(): - return False - - self.start() - return True - - def testFinished(self): - for f in self.frames: - if f.status == QUEUED or f.status == DISPATCHED: - break - else: - self.status = JOB_FINISHED - - def start(self): - self.status = JOB_QUEUED - - def addLog(self, frames): - log_name = "_".join(("%04d" % f for f in frames)) + ".log" - log_path = self.save_path + log_name - - for number in frames: - frame = self[number] - if frame: - frame.log_path = log_path - - def addFrame(self, frame_number): - frame = MRenderFrame(frame_number) - self.frames.append(frame) - return frame - - def reset(self, all): - for f in self.frames: - f.reset(all) - - def getFrames(self): - frames = [] - for f in self.frames: - if f.status == QUEUED: - self.last_dispatched = time.time() - frames.append(f) - if len(frames) >= self.chunks: - break - - return frames - -class MRenderFrame(netrender.model.RenderFrame): - def __init__(self, frame): - super().__init__() - self.number = frame - self.slave = None - self.time = 0 - self.status = QUEUED - self.log_path = None - - def reset(self, all): - if all or self.status == ERROR: - self.slave = None - self.time = 0 - self.status = QUEUED - - -# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -class RenderHandler(http.server.BaseHTTPRequestHandler): - def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"): - self.send_response(code) - self.send_header("Content-type", content) - - for key, value in headers.items(): - self.send_header(key, value) - - self.end_headers() - - def do_HEAD(self): - - if self.path == "/status": - job_id = self.headers.get('job-id', "") - job_frame = int(self.headers.get('job-frame', -1)) - - job = self.server.getJobID(job_id) - if job: - frame = job[job_frame] - - - if frame: - self.send_head(http.client.OK) - else: - # no such frame - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - - def do_GET(self): - - if self.path == "/version": - self.send_head() - self.server.stats("", "Version check") - self.wfile.write(VERSION) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/render": - job_id = self.headers['job-id'] - job_frame = int(self.headers['job-frame']) - - job = self.server.getJobID(job_id) - - if job: - frame = job[job_frame] - - if frame: - if frame.status in (QUEUED, DISPATCHED): - self.send_head(http.client.ACCEPTED) - elif frame.status == DONE: - self.server.stats("", "Sending result to client") - f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb') - - self.send_head() - - shutil.copyfileobj(f, self.wfile) - - f.close() - elif frame.status == ERROR: - self.send_head(http.client.PARTIAL_CONTENT) - else: - # no such frame - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/log": - job_id = self.headers['job-id'] - job_frame = int(self.headers['job-frame']) - - job = self.server.getJobID(job_id) - - if job: - frame = job[job_frame] - - if frame: - if not frame.log_path or frame.status in (QUEUED, DISPATCHED): - self.send_head(http.client.PROCESSING) - else: - self.server.stats("", "Sending log to client") - f = open(frame.log_path, 'rb') - - self.send_head() - - shutil.copyfileobj(f, self.wfile) - - f.close() - else: - # no such frame - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/status": - job_id = self.headers.get('job-id', "") - job_frame = int(self.headers.get('job-frame', -1)) - - if job_id: - - job = self.server.getJobID(job_id) - if job: - if job_frame != -1: - frame = job[frame] - - if frame: - message = frame.serialize() - else: - # no such frame - self.send_heat(http.client.NO_CONTENT) - return - else: - message = job.serialize() - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - return - else: # status of all jobs - message = [] - - for job in self.server: - message.append(job.serialize()) - - - self.server.stats("", "Sending status") - self.send_head() - self.wfile.write(bytes(repr(message), encoding='utf8')) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/job": - self.server.balance() - - slave_id = self.headers['slave-id'] - - slave = self.server.getSeenSlave(slave_id) - - if slave: # only if slave id is valid - job, frames = self.server.newDispatch(slave_id) - - if job and frames: - for f in frames: - print("dispatch", f.number) - f.status = DISPATCHED - f.slave = slave - - slave.job = job - slave.job_frames = [f.number for f in frames] - - self.send_head(headers={"job-id": job.id}) - - message = job.serialize(frames) - - self.wfile.write(bytes(repr(message), encoding='utf8')) - - self.server.stats("", "Sending job to slave") - else: - # no job available, return error code - slave.job = None - slave.job_frames = [] - - self.send_head(http.client.ACCEPTED) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/file": - slave_id = self.headers['slave-id'] - - slave = self.server.getSeenSlave(slave_id) - - if slave: # only if slave id is valid - job_id = self.headers['job-id'] - job_file = self.headers['job-file'] - - job = self.server.getJobID(job_id) - - if job: - render_file = job.files_map.get(job_file, None) - - if render_file: - self.server.stats("", "Sending file to slave") - f = open(render_file.filepath, 'rb') - - self.send_head() - shutil.copyfileobj(f, self.wfile) - - f.close() - else: - # no such file - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/slaves": - message = [] - - self.server.stats("", "Sending slaves status") - - for slave in self.server.slaves: - message.append(slave.serialize()) - - self.send_head() - - self.wfile.write(bytes(repr(message), encoding='utf8')) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - else: - # hand over the rest to the html section - netrender.master_html.get(self) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - def do_POST(self): - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - if self.path == "/job": - - length = int(self.headers['content-length']) - - job_info = netrender.model.RenderJob.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - - job_id = self.server.nextJobID() - - job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) - - for frame in job_info.frames: - frame = job.addFrame(frame.number) - - self.server.addJob(job) - - headers={"job-id": job_id} - - if job.testStart(): - self.server.stats("", "New job, missing files") - self.send_head(headers=headers) - else: - self.server.stats("", "New job, started") - self.send_head(http.client.ACCEPTED, headers=headers) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/cancel": - job_id = self.headers.get('job-id', "") - - job = self.server.getJobID(job_id) - - if job: - self.server.stats("", "Cancelling job") - self.server.removeJob(job) - self.send_head() - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/clear": - # cancel all jobs - self.server.stats("", "Clearing jobs") - self.server.clear() - - self.send_head() - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/reset": - job_id = self.headers.get('job-id', "") - job_frame = int(self.headers.get('job-frame', "-1")) - all = bool(self.headers.get('reset-all', "False")) - - job = self.server.getJobID(job_id) - - if job: - if job_frame != -1: - - frame = job[job_frame] - if frame: - self.server.stats("", "Reset job frame") - frame.reset(all) - self.send_head() - else: - # no such frame - self.send_head(http.client.NO_CONTENT) - - else: - self.server.stats("", "Reset job") - job.reset(all) - self.send_head() - - else: # job not found - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/slave": - length = int(self.headers['content-length']) - job_frame_string = self.headers['job-frame'] - - self.server.stats("", "New slave connected") - - slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - - slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) - - self.send_head(headers = {"slave-id": slave_id}) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/log": - slave_id = self.headers['slave-id'] - - slave = self.server.getSeenSlave(slave_id) - - if slave: # only if slave id is valid - length = int(self.headers['content-length']) - - log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - - job = self.server.getJobID(log_info.job_id) - - if job: - self.server.stats("", "Log announcement") - job.addLog(log_info.frames) - self.send_head(http.client.OK) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - def do_PUT(self): - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - if self.path == "/file": - self.server.stats("", "Receiving job") - - length = int(self.headers['content-length']) - job_id = self.headers['job-id'] - job_file = self.headers['job-file'] - - job = self.server.getJobID(job_id) - - if job: - - render_file = job.files_map.get(job_file, None) - - if render_file: - main_file = job.files[0][0] # filename of the first file - - main_path, main_name = os.path.split(main_file) - - if job_file != main_file: - file_path = prefixPath(job.save_path, job_file, main_path) - else: - file_path = job.save_path + main_name - - buf = self.rfile.read(length) - - # add same temp file + renames as slave - - f = open(file_path, "wb") - f.write(buf) - f.close() - del buf - - render_file.filepath = file_path # set the new path - - if job.testStart(): - self.server.stats("", "File upload, starting job") - self.send_head(http.client.OK) - else: - self.server.stats("", "File upload, file missings") - self.send_head(http.client.ACCEPTED) - else: # invalid file - self.send_head(http.client.NO_CONTENT) - else: # job not found - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/render": - self.server.stats("", "Receiving render result") - - slave_id = self.headers['slave-id'] - - slave = self.server.getSeenSlave(slave_id) - - if slave: # only if slave id is valid - job_id = self.headers['job-id'] - - job = self.server.getJobID(job_id) - - if job: - job_frame = int(self.headers['job-frame']) - job_result = int(self.headers['job-result']) - job_time = float(self.headers['job-time']) - - frame = job[job_frame] - - if frame: - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() - - del buf - elif job_result == ERROR: - # blacklist slave on this job on error - job.blacklist.append(slave.id) - - self.server.stats("", "Receiving result") - - slave.finishedFrame(job_frame) - - frame.status = job_result - frame.time = job_time - - job.testFinished() - - self.send_head() - else: # frame not found - self.send_head(http.client.NO_CONTENT) - else: # job not found - self.send_head(http.client.NO_CONTENT) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "/log": - self.server.stats("", "Receiving log file") - - job_id = self.headers['job-id'] - - job = self.server.getJobID(job_id) - - if job: - job_frame = int(self.headers['job-frame']) - - frame = job[job_frame] - - if frame and frame.log_path: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(frame.log_path, 'ab') - f.write(buf) - f.close() - - del buf - - self.server.getSeenSlave(self.headers['slave-id']) - - self.send_head() - else: # frame not found - self.send_head(http.client.NO_CONTENT) - else: # job not found - self.send_head(http.client.NO_CONTENT) - -class RenderMasterServer(http.server.HTTPServer): - def __init__(self, address, handler_class, path): - super().__init__(address, handler_class) - self.jobs = [] - self.jobs_map = {} - self.slaves = [] - self.slaves_map = {} - self.job_id = 0 - self.path = path + "master_" + str(os.getpid()) + os.sep - - self.slave_timeout = 2 - - self.balancer = netrender.balancing.Balancer() - self.balancer.addRule(netrender.balancing.RatingUsage()) - self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) - self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9)) - self.balancer.addPriority(netrender.balancing.NewJobPriority()) - self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority(limit = 2)) - - if not os.path.exists(self.path): - os.mkdir(self.path) - - def nextJobID(self): - self.job_id += 1 - return str(self.job_id) - - def addSlave(self, name, address, stats): - slave = MRenderSlave(name, address, stats) - self.slaves.append(slave) - self.slaves_map[slave.id] = slave - - return slave.id - - def removeSlave(self, slave): - self.slaves.remove(slave) - self.slaves_map.pop(slave.id) - - def getSlave(self, slave_id): - return self.slaves_map.get(slave_id, None) - - def getSeenSlave(self, slave_id): - slave = self.getSlave(slave_id) - if slave: - slave.seen() - - return slave - - def timeoutSlaves(self): - removed = [] - - t = time.time() - - for slave in self.slaves: - if (t - slave.last_seen) / 60 > self.slave_timeout: - removed.append(slave) - - if slave.job: - for f in slave.job_frames: - slave.job[f].status = ERROR - - for slave in removed: - self.removeSlave(slave) - - def updateUsage(self): - blend = 0.5 - for job in self.jobs: - job.usage *= (1 - blend) - - if self.slaves: - slave_usage = blend / self.countSlaves() - - for slave in self.slaves: - if slave.job: - slave.job.usage += slave_usage - - - def clear(self): - removed = self.jobs[:] - - for job in removed: - self.removeJob(job) - - def balance(self): - self.balancer.balance(self.jobs) - - def countJobs(self, status = JOB_QUEUED): - total = 0 - for j in self.jobs: - if j.status == status: - total += 1 - - return total - - def countSlaves(self): - return len(self.slaves) - - def removeJob(self, job): - self.jobs.remove(job) - self.jobs_map.pop(job.id) - - for slave in self.slaves: - if slave.job == job: - slave.job = None - slave.job_frames = [] - - def addJob(self, job): - self.jobs.append(job) - self.jobs_map[job.id] = job - - # create job directory - job.save_path = self.path + "job_" + job.id + os.sep - if not os.path.exists(job.save_path): - os.mkdir(job.save_path) - - job.save() - - def getJobID(self, id): - return self.jobs_map.get(id, None) - - def __iter__(self): - for job in self.jobs: - yield job - - def newDispatch(self, slave_id): - if self.jobs: - for job in self.jobs: - if not self.balancer.applyExceptions(job) and slave_id not in job.blacklist: - return job, job.getFrames() - - return None, None - -def runMaster(address, broadcast, path, update_stats, test_break): - httpd = RenderMasterServer(address, RenderHandler, path) - httpd.timeout = 1 - httpd.stats = update_stats - - if broadcast: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - - start_time = time.time() - - while not test_break(): - httpd.handle_request() - - if time.time() - start_time >= 10: # need constant here - httpd.timeoutSlaves() - - httpd.updateUsage() - - if broadcast: - print("broadcasting address") - s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('', 8000)) - start_time = time.time() diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py deleted file mode 100644 index 6a956a70e9f..00000000000 --- a/release/io/netrender/master_html.py +++ /dev/null @@ -1,142 +0,0 @@ -import re - -from netrender.utils import * - - -def get(handler): - def output(text): - handler.wfile.write(bytes(text, encoding='utf8')) - - def link(text, url): - return "%s" % (url, text) - - def startTable(border=1): - output("" % border) - - def headerTable(*headers): - output("") - - for c in headers: - output("") - - output("") - - def rowTable(*data): - output("") - - for c in data: - output("") - - output("") - - def endTable(): - output("
" + c + "
" + str(c) + "
") - - handler.send_head(content = "text/html") - - if handler.path == "/html" or handler.path == "/": - output("NetRender") - - output("

Master

") - - output("

Slaves

") - - startTable() - headerTable("name", "address", "last seen", "stats", "job") - - for slave in handler.server.slaves: - rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None") - - endTable() - - output("

Jobs

") - - startTable() - headerTable( - "name", - "priority", - "usage", - "wait", - "length", - "done", - "dispatched", - "error", - "first", - "exception" - ) - - handler.server.balance() - - for job in handler.server.jobs: - results = job.framesStatus() - rowTable( - link(job.name, "/html/job" + job.id), - job.priority, - "%0.1f%%" % (job.usage * 100), - "%is" % int(time.time() - job.last_dispatched), - len(job), - results[DONE], - results[DISPATCHED], - results[ERROR], - handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job) - ) - - endTable() - - output("") - - elif handler.path.startswith("/html/job"): - job_id = handler.path[9:] - - output("NetRender") - - job = handler.server.getJobID(job_id) - - if job: - output("

Frames

") - - startTable() - headerTable("no", "status", "render time", "slave", "log") - - for frame in job.frames: - rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else " ") - - endTable() - else: - output("no such job") - - output("") - - elif handler.path.startswith("/html/log"): - pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)") - - output("NetRender") - - match = pattern.match(handler.path[9:]) - if match: - job_id = match.groups()[0] - frame_number = int(match.groups()[1]) - - job = handler.server.getJobID(job_id) - - if job: - frame = job[frame_number] - - if frame: - f = open(frame.log_path, 'rb') - - output("
")
-						
-						shutil.copyfileobj(f, handler.wfile)
-						
-						output("
") - - f.close() - else: - output("no such frame") - else: - output("no such job") - else: - output("malformed url") - - output("") diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py deleted file mode 100644 index be97f8d0a81..00000000000 --- a/release/io/netrender/model.py +++ /dev/null @@ -1,198 +0,0 @@ -import sys, os -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -from netrender.utils import * - -class LogFile: - def __init__(self, job_id = 0, frames = []): - self.job_id = job_id - self.frames = frames - - def serialize(self): - return { - "job_id": self.job_id, - "frames": self.frames - } - - @staticmethod - def materialize(data): - if not data: - return None - - logfile = LogFile() - logfile.job_id = data["job_id"] - logfile.frames = data["frames"] - - return logfile - -class RenderSlave: - _slave_map = {} - - def __init__(self): - self.id = "" - self.name = "" - self.address = ("",0) - self.stats = "" - self.total_done = 0 - self.total_error = 0 - self.last_seen = 0.0 - - def serialize(self): - return { - "id": self.id, - "name": self.name, - "address": self.address, - "stats": self.stats, - "total_done": self.total_done, - "total_error": self.total_error, - "last_seen": self.last_seen - } - - @staticmethod - def materialize(data): - if not data: - return None - - slave_id = data["id"] - - if slave_id in RenderSlave._slave_map: - return RenderSlave._slave_map[slave_id] - else: - slave = RenderSlave() - slave.id = slave_id - slave.name = data["name"] - slave.address = data["address"] - slave.stats = data["stats"] - slave.total_done = data["total_done"] - slave.total_error = data["total_error"] - slave.last_seen = data["last_seen"] - - RenderSlave._slave_map[slave_id] = slave - - return slave - -class RenderJob: - def __init__(self): - self.id = "" - self.name = "" - self.files = [] - self.frames = [] - self.chunks = 0 - self.priority = 0 - self.usage = 0.0 - self.blacklist = [] - self.last_dispatched = 0.0 - - def addFile(self, file_path, start=-1, end=-1): - self.files.append((file_path, start, end)) - - def addFrame(self, frame_number): - frame = RenderFrame(frame_number) - self.frames.append(frame) - return frame - - def __len__(self): - return len(self.frames) - - def countFrames(self, status=QUEUED): - total = 0 - for f in self.frames: - if f.status == status: - total += 1 - - return total - - def countSlaves(self): - return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED))) - - def framesStatus(self): - results = { - QUEUED: 0, - DISPATCHED: 0, - DONE: 0, - ERROR: 0 - } - - for frame in self.frames: - results[frame.status] += 1 - - return results - - def __contains__(self, frame_number): - for f in self.frames: - if f.number == frame_number: - return True - else: - return False - - def __getitem__(self, frame_number): - for f in self.frames: - if f.number == frame_number: - return f - else: - return None - - def serialize(self, frames = None): - min_frame = min((f.number for f in frames)) if frames else -1 - max_frame = max((f.number for f in frames)) if frames else -1 - return { - "id": self.id, - "name": self.name, - "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], - "frames": [f.serialize() for f in self.frames if not frames or f in frames], - "chunks": self.chunks, - "priority": self.priority, - "usage": self.usage, - "blacklist": self.blacklist, - "last_dispatched": self.last_dispatched - } - - @staticmethod - def materialize(data): - if not data: - return None - - job = RenderJob() - job.id = data["id"] - job.name = data["name"] - job.files = data["files"] - job.frames = [RenderFrame.materialize(f) for f in data["frames"]] - job.chunks = data["chunks"] - job.priority = data["priority"] - job.usage = data["usage"] - job.blacklist = data["blacklist"] - job.last_dispatched = data["last_dispatched"] - - return job - -class RenderFrame: - def __init__(self, number = 0): - self.number = number - self.time = 0 - self.status = QUEUED - self.slave = None - - def statusText(self): - return STATUS_TEXT[self.status] - - def serialize(self): - return { - "number": self.number, - "time": self.time, - "status": self.status, - "slave": None if not self.slave else self.slave.serialize() - } - - @staticmethod - def materialize(data): - if not data: - return None - - frame = RenderFrame() - frame.number = data["number"] - frame.time = data["time"] - frame.status = data["status"] - frame.slave = RenderSlave.materialize(data["slave"]) - - return frame diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py deleted file mode 100644 index 42d1f6a0b86..00000000000 --- a/release/io/netrender/operators.py +++ /dev/null @@ -1,423 +0,0 @@ -import bpy -import sys, os -import http, http.client, http.server, urllib, socket -import webbrowser - -from netrender.utils import * -import netrender.client as client -import netrender.model - -@rnaOperator -class RENDER_OT_netclientanim(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' - __idname__ = "render.netclientanim" - __label__ = "Net Render Client Anim" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - scene = context.scene - - conn = clientConnection(scene) - - if conn: - # Sending file - scene.network_render.job_id = client.clientSendJob(conn, scene, True) - conn.close() - - bpy.ops.screen.render('INVOKE_AREA', animation=True) - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class RENDER_OT_netclientsend(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' - __idname__ = "render.netclientsend" - __label__ = "Net Render Client Send" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - scene = context.scene - - conn = clientConnection(scene) - - if conn: - # Sending file - scene.network_render.job_id = client.clientSendJob(conn, scene, True) - conn.close() - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class RENDER_OT_netclientstatus(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientstatus" - __label__ = "Net Render Client Status" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - conn.request("GET", "/status") - - response = conn.getresponse() - print( response.status, response.reason ) - - jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8'))) - - while(len(netsettings.jobs) > 0): - netsettings.jobs.remove(0) - - bpy.data.netrender_jobs = [] - - for j in jobs: - bpy.data.netrender_jobs.append(j) - netsettings.jobs.add() - job = netsettings.jobs[-1] - - j.results = j.framesStatus() # cache frame status - - job.name = j.name - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class RENDER_OT_netclientblacklistslave(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientblacklistslave" - __label__ = "Net Render Client Blacklist Slave" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - - if netsettings.active_slave_index >= 0: - - # deal with data - slave = bpy.data.netrender_slaves.pop(netsettings.active_slave_index) - bpy.data.netrender_blacklist.append(slave) - - # deal with rna - netsettings.slaves_blacklist.add() - netsettings.slaves_blacklist[-1].name = slave.name - - netsettings.slaves.remove(netsettings.active_slave_index) - netsettings.active_slave_index = -1 - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientwhitelistslave" - __label__ = "Net Render Client Whitelist Slave" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - - if netsettings.active_blacklisted_slave_index >= 0: - - # deal with data - slave = bpy.data.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index) - bpy.data.netrender_slaves.append(slave) - - # deal with rna - netsettings.slaves.add() - netsettings.slaves[-1].name = slave.name - - netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index) - netsettings.active_blacklisted_slave_index = -1 - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - - -@rnaOperator -class RENDER_OT_netclientslaves(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientslaves" - __label__ = "Net Render Client Slaves" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - conn.request("GET", "/slaves") - - response = conn.getresponse() - print( response.status, response.reason ) - - slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8'))) - - while(len(netsettings.slaves) > 0): - netsettings.slaves.remove(0) - - bpy.data.netrender_slaves = [] - - for s in slaves: - for i in range(len(bpy.data.netrender_blacklist)): - slave = bpy.data.netrender_blacklist[i] - if slave.id == s.id: - bpy.data.netrender_blacklist[i] = s - netsettings.slaves_blacklist[i].name = s.name - break - else: - bpy.data.netrender_slaves.append(s) - - netsettings.slaves.add() - slave = netsettings.slaves[-1] - slave.name = s.name - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class RENDER_OT_netclientcancel(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientcancel" - __label__ = "Net Render Client Cancel" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - netsettings = context.scene.network_render - return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - job = bpy.data.netrender_jobs[netsettings.active_job_index] - - conn.request("POST", "/cancel", headers={"job-id":job.id}) - - response = conn.getresponse() - print( response.status, response.reason ) - - netsettings.jobs.remove(netsettings.active_job_index) - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class RENDER_OT_netclientcancelall(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientcancelall" - __label__ = "Net Render Client Cancel All" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - conn.request("POST", "/clear") - - response = conn.getresponse() - print( response.status, response.reason ) - - while(len(netsettings.jobs) > 0): - netsettings.jobs.remove(0) - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class netclientdownload(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientdownload" - __label__ = "Net Render Client Download" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - netsettings = context.scene.network_render - return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 - - def execute(self, context): - netsettings = context.scene.network_render - rd = context.scene.render_data - - conn = clientConnection(context.scene) - - if conn: - job = bpy.data.netrender_jobs[netsettings.active_job_index] - - for frame in job.frames: - client.requestResult(conn, job.id, frame.number) - response = conn.getresponse() - - if response.status != http.client.OK: - print("missing", frame.number) - continue - - print("got back", frame.number) - - f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb") - buf = response.read(1024) - - while buf: - f.write(buf) - buf = response.read(1024) - - f.close() - - conn.close() - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class netclientscan(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientscan" - __label__ = "Net Render Client Scan" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - - try: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - s.settimeout(30) - - s.bind(('', 8000)) - - buf, address = s.recvfrom(64) - - print("received:", buf) - - netsettings.server_address = address[0] - netsettings.server_port = int(str(buf, encoding='utf8')) - except socket.timeout: - print("no server info") - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -@rnaOperator -class netclientweb(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientweb" - __label__ = "Net Render Client Web" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - - - # open connection to make sure server exists - conn = clientConnection(context.scene) - - if conn: - conn.close() - - webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py deleted file mode 100644 index 657e31001e0..00000000000 --- a/release/io/netrender/slave.py +++ /dev/null @@ -1,207 +0,0 @@ -import sys, os, platform -import http, http.client, http.server, urllib -import subprocess, time - -from netrender.utils import * -import netrender.model - -CANCEL_POLL_SPEED = 2 -MAX_TIMEOUT = 10 -INCREMENT_TIMEOUT = 1 - -if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5 - import ctypes - def SetErrorMode(): - val = ctypes.windll.kernel32.SetErrorMode(0x0002) - ctypes.windll.kernel32.SetErrorMode(val | 0x0002) - return val - - def RestoreErrorMode(val): - ctypes.windll.kernel32.SetErrorMode(val) -else: - def SetErrorMode(): - return 0 - - def RestoreErrorMode(val): - pass - -def slave_Info(): - sysname, nodename, release, version, machine, processor = platform.uname() - slave = netrender.model.RenderSlave() - slave.name = nodename - slave.stats = sysname + " " + release + " " + machine + " " + processor - return slave - -def testCancel(conn, job_id, frame_number): - conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)}) - response = conn.getresponse() - - # cancelled if job isn't found anymore - if response.status == http.client.NO_CONTENT: - return True - else: - return False - -def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None): - job_full_path = prefixPath(JOB_PREFIX, file_path, main_path) - - if not os.path.exists(job_full_path): - temp_path = JOB_PREFIX + "slave.temp.blend" - conn.request("GET", "/file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path}) - response = conn.getresponse() - - if response.status != http.client.OK: - return None # file for job not returned by server, need to return an error code to server - - f = open(temp_path, "wb") - buf = response.read(1024) - - while buf: - f.write(buf) - buf = response.read(1024) - - f.close() - - os.renames(temp_path, job_full_path) - - return job_full_path - - -def render_slave(engine, scene): - netsettings = scene.network_render - timeout = 1 - - engine.update_stats("", "Network render node initiation") - - conn = clientConnection(scene) - - if conn: - conn.request("POST", "/slave", repr(slave_Info().serialize())) - response = conn.getresponse() - - slave_id = response.getheader("slave-id") - - NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep - if not os.path.exists(NODE_PREFIX): - os.mkdir(NODE_PREFIX) - - while not engine.test_break(): - - conn.request("GET", "/job", headers={"slave-id":slave_id}) - response = conn.getresponse() - - if response.status == http.client.OK: - timeout = 1 # reset timeout on new job - - job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8'))) - - JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep - if not os.path.exists(JOB_PREFIX): - os.mkdir(JOB_PREFIX) - - job_path = job.files[0][0] # data in files have format (path, start, end) - main_path, main_file = os.path.split(job_path) - - job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) - print("Fullpath", job_full_path) - print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) - engine.update_stats("", "Render File", main_file, "for job", job.id) - - for file_path, start, end in job.files[1:]: - print("\t", file_path) - testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) - - frame_args = [] - - for frame in job.frames: - print("frame", frame.number) - frame_args += ["-f", str(frame.number)] - - # announce log to master - logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) - conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) - response = conn.getresponse() - - first_frame = job.frames[0].number - - # start render - start_t = time.time() - - val = SetErrorMode() - process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - RestoreErrorMode(val) - - headers = {"job-id":job.id, "slave-id":slave_id} - - cancelled = False - stdout = bytes() - run_t = time.time() - while process.poll() == None and not cancelled: - stdout += process.stdout.read(32) - current_t = time.time() - cancelled = engine.test_break() - if current_t - run_t > CANCEL_POLL_SPEED: - - # update logs if needed - if stdout: - # (only need to update on one frame, they are linked - headers["job-frame"] = str(first_frame) - conn.request("PUT", "/log", stdout, headers=headers) - response = conn.getresponse() - - stdout = bytes() - - run_t = current_t - if testCancel(conn, job.id, first_frame): - cancelled = True - - if cancelled: - # kill process if needed - if process.poll() == None: - process.terminate() - continue # to next frame - - total_t = time.time() - start_t - - avg_t = total_t / len(job.frames) - - status = process.returncode - - print("status", status) - - # flush the rest of the logs - if stdout: - # (only need to update on one frame, they are linked - headers["job-frame"] = str(first_frame) - conn.request("PUT", "/log", stdout, headers=headers) - response = conn.getresponse() - - headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} - - if status == 0: # non zero status is error - headers["job-result"] = str(DONE) - for frame in job.frames: - headers["job-frame"] = str(frame.number) - # send result back to server - f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') - conn.request("PUT", "/render", f, headers=headers) - f.close() - response = conn.getresponse() - else: - headers["job-result"] = str(ERROR) - for frame in job.frames: - headers["job-frame"] = str(frame.number) - # send error result back to server - conn.request("PUT", "/render", headers=headers) - response = conn.getresponse() - else: - if timeout < MAX_TIMEOUT: - timeout += INCREMENT_TIMEOUT - - for i in range(timeout): - time.sleep(1) - if engine.test_break(): - conn.close() - return - - conn.close() diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py deleted file mode 100644 index 7681d4865e9..00000000000 --- a/release/io/netrender/ui.py +++ /dev/null @@ -1,321 +0,0 @@ -import bpy -import sys, os -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -import netrender.slave as slave -import netrender.master as master - -from netrender.utils import * - -VERSION = b"0.3" - -PATH_PREFIX = "/tmp/" - -QUEUED = 0 -DISPATCHED = 1 -DONE = 2 -ERROR = 3 - -class RenderButtonsPanel(bpy.types.Panel): - __space_type__ = "PROPERTIES" - __region_type__ = "WINDOW" - __context__ = "scene" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - - def poll(self, context): - rd = context.scene.render_data - return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) - -# Setting panel, use in the scene for now. -@rnaType -class SCENE_PT_network_settings(RenderButtonsPanel): - __label__ = "Network Settings" - COMPAT_ENGINES = set(['NET_RENDER']) - - def draw_header(self, context): - layout = self.layout - scene = context.scene - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render_data - - layout.active = True - - split = layout.split() - - col = split.column() - - col.itemR(scene.network_render, "mode") - col.itemR(scene.network_render, "path") - col.itemR(scene.network_render, "server_address") - col.itemR(scene.network_render, "server_port") - - if scene.network_render.mode == "RENDER_MASTER": - col.itemR(scene.network_render, "server_broadcast") - else: - col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="") - -@rnaType -class SCENE_PT_network_job(RenderButtonsPanel): - __label__ = "Job Settings" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render_data - - layout.active = True - - split = layout.split() - - col = split.column() - - col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") - col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job") - col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor") - col.itemR(scene.network_render, "job_name") - col.itemR(scene.network_render, "priority") - col.itemR(scene.network_render, "chunks") - -@rnaType -class SCENE_PT_network_slaves(RenderButtonsPanel): - __label__ = "Slaves Status" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - netsettings = scene.network_render - - row = layout.row() - row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2) - - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") - - if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0: - while(len(netsettings.slaves) > 0): - netsettings.slaves.remove(0) - - if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0: - layout.itemS() - - slave = bpy.data.netrender_slaves[netsettings.active_slave_index] - - layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Address: " + slave.address[0]) - layout.itemL(text="Seen: " + time.ctime(slave.last_seen)) - layout.itemL(text="Stats: " + slave.stats) - -@rnaType -class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): - __label__ = "Slaves Blacklist" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - netsettings = scene.network_render - - row = layout.row() - row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2) - - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") - - if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0: - while(len(netsettings.slaves_blacklist) > 0): - netsettings.slaves_blacklist.remove(0) - - if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0: - layout.itemS() - - slave = bpy.data.netrender_blacklist[netsettings.active_blacklisted_slave_index] - - layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Address: " + slave.address[0]) - layout.itemL(text="Seen: " + slave.last_seen) - layout.itemL(text="Stats: " + time.ctime(slave.stats)) - -@rnaType -class SCENE_PT_network_jobs(RenderButtonsPanel): - __label__ = "Jobs" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - netsettings = scene.network_render - - row = layout.row() - row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2) - - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") - subcol.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") - subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") - - if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: - while(len(netsettings.jobs) > 0): - netsettings.jobs.remove(0) - - if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0: - layout.itemS() - - job = bpy.data.netrender_jobs[netsettings.active_job_index] - - layout.itemL(text="Name: %s" % job.name) - layout.itemL(text="Length: %04i" % len(job)) - layout.itemL(text="Done: %04i" % job.results[DONE]) - layout.itemL(text="Error: %04i" % job.results[ERROR]) - -@rnaType -class NetRenderSettings(bpy.types.IDPropertyGroup): - pass - -@rnaType -class NetRenderSlave(bpy.types.IDPropertyGroup): - pass - -@rnaType -class NetRenderJob(bpy.types.IDPropertyGroup): - pass - -bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings") - -NetRenderSettings.StringProperty( attr="server_address", - name="Server address", - description="IP or name of the master render server", - maxlen = 128, - default = "[default]") - -NetRenderSettings.IntProperty( attr="server_port", - name="Server port", - description="port of the master render server", - default = 8000, - min=1, - max=65535) - -NetRenderSettings.BoolProperty( attr="server_broadcast", - name="Broadcast server address", - description="broadcast server address on local network", - default = True) - -if os.name == 'nt': - NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "C:/tmp/") -else: - NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "/tmp/") - -NetRenderSettings.StringProperty( attr="job_name", - name="Job name", - description="Name of the job", - maxlen = 128, - default = "[default]") - -NetRenderSettings.IntProperty( attr="chunks", - name="Chunks", - description="Number of frame to dispatch to each slave in one chunk", - default = 5, - min=1, - max=65535) - -NetRenderSettings.IntProperty( attr="priority", - name="Priority", - description="Priority of the job", - default = 1, - min=1, - max=10) - -NetRenderSettings.StringProperty( attr="job_id", - name="Network job id", - description="id of the last sent render job", - maxlen = 64, - default = "") - -NetRenderSettings.IntProperty( attr="active_slave_index", - name="Index of the active slave", - description="", - default = -1, - min= -1, - max=65535) - -NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index", - name="Index of the active slave", - description="", - default = -1, - min= -1, - max=65535) - -NetRenderSettings.IntProperty( attr="active_job_index", - name="Index of the active job", - description="", - default = -1, - min= -1, - max=65535) - -NetRenderSettings.EnumProperty(attr="mode", - items=( - ("RENDER_CLIENT", "Client", "Act as render client"), - ("RENDER_MASTER", "Master", "Act as render master"), - ("RENDER_SLAVE", "Slave", "Act as render slave"), - ), - name="network mode", - description="mode of operation of this instance", - default="RENDER_CLIENT") - -NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="") -NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="") -NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="") - -NetRenderSlave.StringProperty( attr="name", - name="Name of the slave", - description="", - maxlen = 64, - default = "") - -NetRenderJob.StringProperty( attr="name", - name="Name of the job", - description="", - maxlen = 128, - default = "") diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py deleted file mode 100644 index 06393a738a0..00000000000 --- a/release/io/netrender/utils.py +++ /dev/null @@ -1,86 +0,0 @@ -import bpy -import sys, os -import re -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -import netrender.model - -VERSION = b"0.5" - -# Jobs status -JOB_WAITING = 0 # before all data has been entered -JOB_PAUSED = 1 # paused by user -JOB_FINISHED = 2 # finished rendering -JOB_QUEUED = 3 # ready to be dispatched - -# Frames status -QUEUED = 0 -DISPATCHED = 1 -DONE = 2 -ERROR = 3 - -STATUS_TEXT = { - QUEUED: "Queued", - DISPATCHED: "Dispatched", - DONE: "Done", - ERROR: "Error" - } - -def rnaType(rna_type): - bpy.types.register(rna_type) - return rna_type - -def rnaOperator(rna_op): - bpy.ops.add(rna_op) - return rna_op - -def clientConnection(scene): - netsettings = scene.network_render - - if netsettings.server_address == "[default]": - bpy.ops.render.netclientscan() - - conn = http.client.HTTPConnection(netsettings.server_address, netsettings.server_port) - - if clientVerifyVersion(conn): - return conn - else: - conn.close() - return None - -def clientVerifyVersion(conn): - conn.request("GET", "/version") - response = conn.getresponse() - - if response.status != http.client.OK: - conn.close() - return False - - server_version = response.read() - - if server_version != VERSION: - print("Incorrect server version!") - print("expected", VERSION, "received", server_version) - return False - - return True - -def prefixPath(prefix_directory, file_path, prefix_path): - if os.path.isabs(file_path): - # if an absolute path, make sure path exists, if it doesn't, use relative local path - full_path = file_path - if not os.path.exists(full_path): - p, n = os.path.split(full_path) - - if prefix_path and p.startswith(prefix_path): - directory = prefix_directory + p[len(prefix_path):] - full_path = directory + n - if not os.path.exists(directory): - os.mkdir(directory) - else: - full_path = prefix_directory + n - else: - full_path = prefix_directory + file_path - - return full_path diff --git a/release/scripts/3ds_export.py b/release/scripts/3ds_export.py deleted file mode 100644 index 87680bce1b0..00000000000 --- a/release/scripts/3ds_export.py +++ /dev/null @@ -1,1019 +0,0 @@ -#!BPY -# coding: utf-8 -""" -Name: '3D Studio (.3ds)...' -Blender: 243 -Group: 'Export' -Tooltip: 'Export to 3DS file format (.3ds).' -""" - -__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] -__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") -__version__ = "0.90a" -__bpydoc__ = """\ - -3ds Exporter - -This script Exports a 3ds file. - -Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information -from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Bob Holcomb -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -###################################################### -# Importing modules -###################################################### - -import Blender -import bpy -from BPyMesh import getMeshFromObject -from BPyObject import getDerivedObjects -try: - import struct -except: - struct = None - -# So 3ds max can open files, limit names to 12 in length -# this is verry annoying for filenames! -name_unique = [] -name_mapping = {} -def sane_name(name): - name_fixed = name_mapping.get(name) - if name_fixed != None: - return name_fixed - - if len(name) > 12: - new_name = name[:12] - else: - new_name = name - - i = 0 - - while new_name in name_unique: - new_name = new_name[:-4] + '.%.3d' % i - i+=1 - - name_unique.append(new_name) - name_mapping[name] = new_name - return new_name - -###################################################### -# Data Structures -###################################################### - -#Some of the chunks that we will export -#----- Primary Chunk, at the beginning of each file -PRIMARY= long("0x4D4D",16) - -#------ Main Chunks -OBJECTINFO = long("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information -VERSION = long("0x0002",16); #This gives the version of the .3ds file -KFDATA = long("0xB000",16); #This is the header for all of the key frame info - -#------ sub defines of OBJECTINFO -MATERIAL=45055 #0xAFFF // This stored the texture info -OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... - -#>------ sub defines of MATERIAL -MATNAME = long("0xA000",16); # This holds the material name -MATAMBIENT = long("0xA010",16); # Ambient color of the object/material -MATDIFFUSE = long("0xA020",16); # This holds the color of the object/material -MATSPECULAR = long("0xA030",16); # SPecular color of the object/material -MATSHINESS = long("0xA040",16); # ?? -MATMAP = long("0xA200",16); # This is a header for a new material -MATMAPFILE = long("0xA300",16); # This holds the file name of the texture - -RGB1= long("0x0011",16) -RGB2= long("0x0012",16) - -#>------ sub defines of OBJECT -OBJECT_MESH = long("0x4100",16); # This lets us know that we are reading a new object -OBJECT_LIGHT = long("0x4600",16); # This lets un know we are reading a light object -OBJECT_CAMERA= long("0x4700",16); # This lets un know we are reading a camera object - -#>------ sub defines of CAMERA -OBJECT_CAM_RANGES= long("0x4720",16); # The camera range values - -#>------ sub defines of OBJECT_MESH -OBJECT_VERTICES = long("0x4110",16); # The objects vertices -OBJECT_FACES = long("0x4120",16); # The objects faces -OBJECT_MATERIAL = long("0x4130",16); # This is found if the object has a material, either texture map or color -OBJECT_UV = long("0x4140",16); # The UV texture coordinates -OBJECT_TRANS_MATRIX = long("0x4160",16); # The Object Matrix - -#>------ sub defines of KFDATA -KFDATA_KFHDR = long("0xB00A",16); -KFDATA_KFSEG = long("0xB008",16); -KFDATA_KFCURTIME = long("0xB009",16); -KFDATA_OBJECT_NODE_TAG = long("0xB002",16); - -#>------ sub defines of OBJECT_NODE_TAG -OBJECT_NODE_ID = long("0xB030",16); -OBJECT_NODE_HDR = long("0xB010",16); -OBJECT_PIVOT = long("0xB013",16); -OBJECT_INSTANCE_NAME = long("0xB011",16); -POS_TRACK_TAG = long("0xB020",16); -ROT_TRACK_TAG = long("0xB021",16); -SCL_TRACK_TAG = long("0xB022",16); - -def uv_key(uv): - return round(uv.x, 6), round(uv.y, 6) - -# size defines: -SZ_SHORT = 2 -SZ_INT = 4 -SZ_FLOAT = 4 - -class _3ds_short(object): - '''Class representing a short (2-byte integer) for a 3ds file. - *** This looks like an unsigned short H is unsigned from the struct docs - Cam***''' - __slots__ = 'value' - def __init__(self, val=0): - self.value=val - - def get_size(self): - return SZ_SHORT - - def write(self,file): - file.write(struct.pack("= mat_ls_len: - mat_index = f.mat = 0 - mat = mat_ls[mat_index] - if mat: mat_name = mat.name - else: mat_name = None - # else there alredy set to none - - img = f.image - if img: img_name = img.name - else: img_name = None - - materialDict.setdefault((mat_name, img_name), (mat, img) ) - - - else: - for mat in mat_ls: - if mat: # material may be None so check its not. - materialDict.setdefault((mat.name, None), (mat, None) ) - - # Why 0 Why! - for f in data.faces: - if f.mat >= mat_ls_len: - f.mat = 0 - - # Make material chunks for all materials used in the meshes: - for mat_and_image in materialDict.itervalues(): - object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1])) - - # Give all objects a unique ID and build a dictionary from object name to object id: - """ - name_to_id = {} - for ob, data in mesh_objects: - name_to_id[ob.name]= len(name_to_id) - #for ob in empty_objects: - # name_to_id[ob.name]= len(name_to_id) - """ - - # Create object chunks for all meshes: - i = 0 - for ob, blender_mesh in mesh_objects: - # create a new object chunk - object_chunk = _3ds_chunk(OBJECT) - - # set the object name - object_chunk.add_variable("name", _3ds_string(sane_name(ob.name))) - - # make a mesh chunk out of the mesh: - object_chunk.add_subchunk(make_mesh_chunk(blender_mesh, materialDict)) - object_info.add_subchunk(object_chunk) - - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - # make a kf object node for the object: - kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) - ''' - blender_mesh.verts = None - i+=i - - # Create chunks for all empties: - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - for ob in empty_objects: - # Empties only require a kf object node: - kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) - pass - ''' - - # Add main object info chunk to primary chunk: - primary.add_subchunk(object_info) - - ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX - # Add main keyframe data chunk to primary chunk: - primary.add_subchunk(kfdata) - ''' - - # At this point, the chunk hierarchy is completely built. - - # Check the size: - primary.get_size() - # Open the file for writing: - file = open( filename, 'wb' ) - - # Recursively write the chunks to file: - primary.write(file) - - # Close the file: - file.close() - - # Debugging only: report the exporting time: - Blender.Window.WaitCursor(0) - print "3ds export time: %.2f" % (Blender.sys.time() - time1) - - # Debugging only: dump the chunk hierarchy: - #primary.dump() - - -if __name__=='__main__': - if struct: - Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) - else: - Blender.Draw.PupMenu("Error%t|This script requires a full python installation") -# save_3ds('/test_b.3ds') diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py deleted file mode 100644 index bcde82c4869..00000000000 --- a/release/scripts/3ds_import.py +++ /dev/null @@ -1,1007 +0,0 @@ -#!BPY -""" -Name: '3D Studio (.3ds)...' -Blender: 244 -Group: 'Import' -Tooltip: 'Import from 3DS file format (.3ds)' -""" - -__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin'] -__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") -__version__= '0.996' -__bpydoc__= '''\ - -3ds Importer - -This script imports a 3ds file and the materials into Blender for editing. - -Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). - -0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200
- - Implemented workaround to correct association between name, geometry and materials of - imported meshes. - - Without this patch, version 0.995 of this importer would associate to each mesh object the - geometry and the materials of the previously parsed mesh object. By so, the name of the - first mesh object would be thrown away, and the name of the last mesh object would be - automatically merged with a '.001' at the end. No object would desappear, however object's - names and materials would be completely jumbled. - -0.995 by Campbell Barton
-- workaround for buggy mesh vert delete -- minor tweaks - -0.99 by Bob Holcomb
-- added support for floating point color values that previously broke on import. - -0.98 by Campbell Barton
-- import faces and verts to lists instead of a mesh, convert to a mesh later -- use new index mapping feature of mesh to re-map faces that were not added. - -0.97 by Campbell Barton
-- Strip material names of spaces -- Added import as instance to import the 3ds into its own - scene and add a group instance to the current scene -- New option to scale down imported objects so they are within a limited bounding area. - -0.96 by Campbell Barton
-- Added workaround for bug in setting UV's for Zero vert index UV faces. -- Removed unique name function, let blender make the names unique. - -0.95 by Campbell Barton
-- Removed workarounds for Blender 2.41 -- Mesh objects split by material- many 3ds objects used more then 16 per mesh. -- Removed a lot of unneeded variable creation. - -0.94 by Campbell Barton
-- Face import tested to be about overall 16x speedup over 0.93. -- Material importing speedup. -- Tested with more models. -- Support some corrupt models. - -0.93 by Campbell Barton
-- Tested with 400 3ds files from turbosquid and samples. -- Tactfully ignore faces that used the same verts twice. -- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading. -- Converted from NMesh to Mesh. -- Faster and cleaner new names. -- Use external comprehensive image loader. -- Re intergrated 0.92 and 0.9 changes -- Fixes for 2.41 compat. -- Non textured faces do not use a texture flag. - -0.92
-- Added support for diffuse, alpha, spec, bump maps in a single material - -0.9
-- Reorganized code into object/material block functions
-- Use of Matrix() to copy matrix data
-- added support for material transparency
- -0.83 2005-08-07: Campell Barton -- Aggressive image finding and case insensitivy for posisx systems. - -0.82a 2005-07-22 -- image texture loading (both for face uv and renderer) - -0.82 - image texture loading (for face uv) - -0.81a (fork- not 0.9) Campbell Barton 2005-06-08 -- Simplified import code -- Never overwrite data -- Faster list handling -- Leaves import selected - -0.81 Damien McGinnes 2005-01-09 -- handle missing images better - -0.8 Damien McGinnes 2005-01-08 -- copies sticky UV coords to face ones -- handles images better -- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script - -''' - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Bob Holcomb -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -# Importing modules - -import Blender -import bpy -from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils -from Blender.Mathutils import Vector -import BPyImage - -import BPyMessages - -try: - from struct import calcsize, unpack -except: - calcsize= unpack= None - - - -# If python version is less than 2.4, try to get set stuff from module -try: - set -except: - from sets import Set as set - -BOUNDS_3DS= [] - - -#this script imports uvcoords as sticky vertex coords -#this parameter enables copying these to face uv coords -#which shold be more useful. - -def createBlenderTexture(material, name, image): - texture= bpy.data.textures.new(name) - texture.setType('Image') - texture.image= image - material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) - - - -###################################################### -# Data Structures -###################################################### - -#Some of the chunks that we will see -#----- Primary Chunk, at the beginning of each file -PRIMARY= long('0x4D4D',16) - -#------ Main Chunks -OBJECTINFO = long('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information -VERSION = long('0x0002',16); #This gives the version of the .3ds file -EDITKEYFRAME= long('0xB000',16); #This is the header for all of the key frame info - -#------ sub defines of OBJECTINFO -MATERIAL=45055 #0xAFFF // This stored the texture info -OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... - -#>------ sub defines of MATERIAL -#------ sub defines of MATERIAL_BLOCK -MAT_NAME = long('0xA000',16) # This holds the material name -MAT_AMBIENT = long('0xA010',16) # Ambient color of the object/material -MAT_DIFFUSE = long('0xA020',16) # This holds the color of the object/material -MAT_SPECULAR = long('0xA030',16) # SPecular color of the object/material -MAT_SHINESS = long('0xA040',16) # ?? -MAT_TRANSPARENCY= long('0xA050',16) # Transparency value of material -MAT_SELF_ILLUM = long('0xA080',16) # Self Illumination value of material -MAT_WIRE = long('0xA085',16) # Only render's wireframe - -MAT_TEXTURE_MAP = long('0xA200',16) # This is a header for a new texture map -MAT_SPECULAR_MAP= long('0xA204',16) # This is a header for a new specular map -MAT_OPACITY_MAP = long('0xA210',16) # This is a header for a new opacity map -MAT_REFLECTION_MAP= long('0xA220',16) # This is a header for a new reflection map -MAT_BUMP_MAP = long('0xA230',16) # This is a header for a new bump map -MAT_MAP_FILENAME = long('0xA300',16) # This holds the file name of the texture - -MAT_FLOAT_COLOR = long ('0x0010', 16) #color defined as 3 floats -MAT_24BIT_COLOR = long ('0x0011', 16) #color defined as 3 bytes - -#>------ sub defines of OBJECT -OBJECT_MESH = long('0x4100',16); # This lets us know that we are reading a new object -OBJECT_LAMP = long('0x4600',16); # This lets un know we are reading a light object -OBJECT_LAMP_SPOT = long('0x4610',16); # The light is a spotloght. -OBJECT_LAMP_OFF = long('0x4620',16); # The light off. -OBJECT_LAMP_ATTENUATE = long('0x4625',16); -OBJECT_LAMP_RAYSHADE = long('0x4627',16); -OBJECT_LAMP_SHADOWED = long('0x4630',16); -OBJECT_LAMP_LOCAL_SHADOW = long('0x4640',16); -OBJECT_LAMP_LOCAL_SHADOW2 = long('0x4641',16); -OBJECT_LAMP_SEE_CONE = long('0x4650',16); -OBJECT_LAMP_SPOT_RECTANGULAR= long('0x4651',16); -OBJECT_LAMP_SPOT_OVERSHOOT= long('0x4652',16); -OBJECT_LAMP_SPOT_PROJECTOR= long('0x4653',16); -OBJECT_LAMP_EXCLUDE= long('0x4654',16); -OBJECT_LAMP_RANGE= long('0x4655',16); -OBJECT_LAMP_ROLL= long('0x4656',16); -OBJECT_LAMP_SPOT_ASPECT= long('0x4657',16); -OBJECT_LAMP_RAY_BIAS= long('0x4658',16); -OBJECT_LAMP_INNER_RANGE= long('0x4659',16); -OBJECT_LAMP_OUTER_RANGE= long('0x465A',16); -OBJECT_LAMP_MULTIPLIER = long('0x465B',16); -OBJECT_LAMP_AMBIENT_LIGHT = long('0x4680',16); - - - -OBJECT_CAMERA= long('0x4700',16); # This lets un know we are reading a camera object - -#>------ sub defines of CAMERA -OBJECT_CAM_RANGES= long('0x4720',16); # The camera range values - -#>------ sub defines of OBJECT_MESH -OBJECT_VERTICES = long('0x4110',16); # The objects vertices -OBJECT_FACES = long('0x4120',16); # The objects faces -OBJECT_MATERIAL = long('0x4130',16); # This is found if the object has a material, either texture map or color -OBJECT_UV = long('0x4140',16); # The UV texture coordinates -OBJECT_TRANS_MATRIX = long('0x4160',16); # The Object Matrix - -global scn -scn= None - -#the chunk class -class chunk: - ID=0 - length=0 - bytes_read=0 - - #we don't read in the bytes_read, we compute that - binary_format='3): - print '\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version - - #is it an object info chunk? - elif (new_chunk.ID==OBJECTINFO): - #print 'elif (new_chunk.ID==OBJECTINFO):' - # print 'found an OBJECTINFO chunk' - process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) - - #keep track of how much we read in the main chunk - new_chunk.bytes_read+=temp_chunk.bytes_read - - #is it an object chunk? - elif (new_chunk.ID==OBJECT): - - if CreateBlenderObject: - putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) - contextMesh_vertls= []; contextMesh_facels= [] - - ## preparando para receber o proximo objeto - contextMeshMaterials= {} # matname:[face_idxs] - contextMeshUV= None - #contextMesh.vertexUV= 1 # Make sticky coords. - # Reset matrix - contextMatrix_rot= None - #contextMatrix_tx= None - - CreateBlenderObject= True - tempName= read_string(file) - contextObName= tempName - new_chunk.bytes_read += len(tempName)+1 - - #is it a material chunk? - elif (new_chunk.ID==MATERIAL): - #print 'elif (new_chunk.ID==MATERIAL):' - contextMaterial= bpy.data.materials.new('Material') - - elif (new_chunk.ID==MAT_NAME): - #print 'elif (new_chunk.ID==MAT_NAME):' - material_name= read_string(file) - - #plus one for the null character that ended the string - new_chunk.bytes_read+= len(material_name)+1 - - contextMaterial.name= material_name.rstrip() # remove trailing whitespace - MATDICT[material_name]= (contextMaterial.name, contextMaterial) - - elif (new_chunk.ID==MAT_AMBIENT): - #print 'elif (new_chunk.ID==MAT_AMBIENT):' - read_chunk(file, temp_chunk) - if (temp_chunk.ID==MAT_FLOAT_COLOR): - temp_data=file.read(calcsize('3f')) - temp_chunk.bytes_read+=12 - contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)] - elif (temp_chunk.ID==MAT_24BIT_COLOR): - temp_data=file.read(calcsize('3B')) - temp_chunk.bytes_read+= 3 - contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read+= temp_chunk.bytes_read - - elif (new_chunk.ID==MAT_DIFFUSE): - #print 'elif (new_chunk.ID==MAT_DIFFUSE):' - read_chunk(file, temp_chunk) - if (temp_chunk.ID==MAT_FLOAT_COLOR): - temp_data=file.read(calcsize('3f')) - temp_chunk.bytes_read+=12 - contextMaterial.rgbCol=[float(col) for col in unpack('<3f', temp_data)] - elif (temp_chunk.ID==MAT_24BIT_COLOR): - temp_data=file.read(calcsize('3B')) - temp_chunk.bytes_read+= 3 - contextMaterial.rgbCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read+= temp_chunk.bytes_read - - elif (new_chunk.ID==MAT_SPECULAR): - #print 'elif (new_chunk.ID==MAT_SPECULAR):' - read_chunk(file, temp_chunk) - if (temp_chunk.ID==MAT_FLOAT_COLOR): - temp_data=file.read(calcsize('3f')) - temp_chunk.bytes_read+=12 - contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)] - elif (temp_chunk.ID==MAT_24BIT_COLOR): - temp_data=file.read(calcsize('3B')) - temp_chunk.bytes_read+= 3 - contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb - else: - skip_to_end(file, temp_chunk) - new_chunk.bytes_read+= temp_chunk.bytes_read - - elif (new_chunk.ID==MAT_TEXTURE_MAP): - #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):' - new_texture= bpy.data.textures.new('Diffuse') - new_texture.setType('Image') - img = None - while (new_chunk.bytes_read BOUNDS_3DS[i+3]: - BOUNDS_3DS[i+3]= v[i] # min - - # Get the max axis x/y/z - max_axis= max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2]) - # print max_axis - if max_axis < 1<<30: # Should never be false but just make sure. - - # Get a new scale factor if set as an option - SCALE=1.0 - while (max_axis*SCALE) > IMPORT_CONSTRAIN_BOUNDS: - SCALE/=10 - - # SCALE Matrix - SCALE_MAT= Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) - - for ob in importedObjects: - ob.setMatrix(ob.matrixWorld*SCALE_MAT) - - # Done constraining to bounds. - - # Select all new objects. - print 'finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)) - file.close() - Blender.Window.WaitCursor(0) - - -DEBUG= False -if __name__=='__main__' and not DEBUG: - if calcsize==None: - Blender.Draw.PupMenu('Error%t|a full python installation not found') - else: - Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') - -# For testing compatibility -#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False) -#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False) -''' - -else: - import os - # DEBUG ONLY - TIME= Blender.sys.time() - import os - print 'Searching for files' - os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') - # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') - print '...Done' - file= open('/tmp/temp3ds_list', 'r') - lines= file.readlines() - file.close() - # sort by filesize for faster testing - lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] - lines_size.sort() - lines = [f[1] for f in lines_size] - - - def between(v,a,b): - if v <= max(a,b) and v >= min(a,b): - return True - return False - - for i, _3ds in enumerate(lines): - if between(i, 650,800): - #_3ds= _3ds[:-1] - print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines) - _3ds_file= _3ds.split('/')[-1].split('\\')[-1] - newScn= Blender.Scene.New(_3ds_file) - newScn.makeCurrent() - load_3ds(_3ds, False) - - print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) - -''' diff --git a/release/scripts/Axiscopy.py b/release/scripts/Axiscopy.py deleted file mode 100644 index 6a31432edb6..00000000000 --- a/release/scripts/Axiscopy.py +++ /dev/null @@ -1,125 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: <- these words are ignored -Name: 'Axis Orientation Copy' -Blender: 242 -Group: 'Object' -Tip: 'Copy local axis orientation of active object to all selected meshes (changes mesh data)' -""" - -__author__ = "A Vanpoucke (xand)" -__url__ = ("blenderartists.org", "www.blender.org", -"French Blender support forum, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "2 17/12/05" - -__bpydoc__ = """\ -This script copies the axis orientation -- X, Y and Z rotations -- of the -active object to all selected meshes. - -It's useful to align the orientations of all meshes of a structure, a human -skeleton, for example. - -Usage: - -Select all mesh objects that need to have their orientations changed -(reminder: keep SHIFT pressed after the first, to add each new one to the -selection), then select the object whose orientation will be copied from and -finally run this script to update the angles. - -Notes:
- This script changes mesh data: the vertices are transformed.
- Before copying the orientation to each object, the script stores its -transformation matrix. Then the angles are copied and after that the object's -vertices are transformed "back" so that they still have the same positions as -before. In other words, the rotations are updated, but you won't notice that -just from looking at the objects.
- Checking their X, Y and Z rotation values with "Transform Properties" in -the 3D View's Object menu shows the angles are now the same of the active -object. Or simply look at the transform manipulator handles in local transform -orientation. -""" - - -# $Id$ -# -#---------------------------------------------- -# A Vanpoucke (xand) -#from the previous script realignaxis -#---------------------------------------------- -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2003, 2004: A Vanpoucke -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from Blender import * -from Blender import Mathutils -from Blender.Mathutils import * -import BPyMessages - -def realusers(data): - users = data.users - if data.fakeUser: users -= 1 - return users - - - -def main(): - - scn_obs= Scene.GetCurrent().objects - ob_act = scn_obs.active - scn_obs = scn_obs.context - - if not ob_act: - BPyMessages.Error_NoActive() - - obs = [(ob, ob.getData(mesh=1)) for ob in scn_obs if ob != ob_act] - - for ob, me in obs: - - if ob.type != 'Mesh': - Draw.PupMenu("Error%t|Selection must be made up of mesh objects only") - return - - if realusers(me) != 1: - Draw.PupMenu("Error%t|Meshes must be single user") - return - - if len(obs) < 1: - Draw.PupMenu("Error: you must select at least 2 objects") - return - - result = Draw.PupMenu("Copy axis orientation from: " + ob_act.name + " ?%t|OK") - if result == -1: - return - - for ob_target, me_target in obs: - if ob_act.rot != ob_target.rot: - rot_target = ob_target.matrixWorld.rotationPart().toEuler().toMatrix() - rot_source = ob_act.matrixWorld.rotationPart().toEuler().toMatrix() - rot_source_inv = rot_source.copy().invert() - tx_mat = rot_target * rot_source_inv - tx_mat.resize4x4() - me_target.transform(tx_mat) - ob_target.rot=ob_act.rot - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py deleted file mode 100644 index 8a0ecaf0eb7..00000000000 --- a/release/scripts/DirectX8Exporter.py +++ /dev/null @@ -1,1196 +0,0 @@ -#!BPY - -""" -# Name: 'DirectX (.x)...' -# Blender: 242 -# Group: 'Export' -# Tooltip: 'Export to DirectX text file format format for XNA Animation Component Library.' -""" -__author__ = "vertex color exporting feature is added by mnemoto (original:minahito (original:Arben (Ben) Omari))" -__url__ = ("blender.org", "blenderartists.org", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it","Adjuster's site http://ex.homeunix.net/") -__version__ = "3.1" - -__bpydoc__ = """\ -This script exports a Blender mesh with armature to DirectX 8's text file -format. - -Notes:
- Check author's site or the elYsiun forum for a new beta version of the -DX exporter. -""" -# DirectXExporter.py version 3.0 -# Copyright (C) 2006 Arben OMARI -- omariarben@everyday.com -# -# 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. - -# This script export meshes created with Blender in DirectX8 file format -# it exports meshes,armatures,materials,normals,texturecoords and animations - -# Grab the latest version here :www.omariben.too.it - -# [Notice] -# This script is the custom version of Mr.Arben Omari's great work. -# If you have a question about the adjusted part, visit http://sunday-lab.blogspot.com/. - -import Blender -from Blender import Types, Object, NMesh, Material,Armature,Mesh -from Blender.Mathutils import * -from Blender import Draw, BGL -from Blender.BGL import * -try: import math -except: math = None - -global mat_flip,index_list,space,bone_list,mat_dict -global anim,flip_norm,swap_zy,flip_z,speed,ticks,no_light,recalc_norm,Bl_norm -bone_list =[] -index_list = [] -mat_dict = {} -space = 0;flip_z = 1;anim=0;swap_yz=0;flip_norm=0;speed=0;ticks= 25 -Bl_norm = 1;recalc_norm = 0;no_light = 0 - -toggle_val = 0 -toggle1_val = 0 -toggle2_val = 0 -toggle3_val = 1 -toggle4_val = 0 -toggle5_val = 1 -toggle6_val = 0 -toggle7_val = 0 -anim_tick = Draw.Create(25) - -#*********************************************** -# DirectX file spec only allows letters, digits, and -# underscore in Names. -#*********************************************** -def make_legal_name(starting_name): - new_name = starting_name.replace('.','_') - new_name = new_name.replace(' ','_') - if new_name[0].isdigit(): - new_name = '_' + new_name - return new_name - -#*********************************************** -# MAIN -#*********************************************** - -def my_callback(filename): - if filename.find('.x', -2) <= 0: filename += '.x' - xexport = xExport(filename) - xexport.SelectObjs() - -def my_callback_sel(filename): - if filename.find('.x', -2) <= 0: filename += '.x' - xexport = xExport(filename) - xexport.exportSelMesh() -def event(evt, val): - if evt == Draw.ESCKEY: - Draw.Exit() - return - -def button_event(evt): - global toggle_val,toggle1_val,toggle2_val,toggle3_val,toggle4_val,toggle5_val,toggle6_val,toggle7_val - global flip_z,swap_yz,flip_norm,anim,ticks,speed,no_light,Bl_norm,recalc_norm - arg = __script__['arg'] - if evt == 1: - toggle_val = 1 - toggle_val - anim = toggle_val - Draw.Redraw(1) - if evt == 2: - toggle1_val = 1 - toggle1_val - flip_norm = toggle1_val - Draw.Redraw(1) - if evt == 3: - toggle2_val = 1 - toggle2_val - swap_yz = toggle2_val - Draw.Redraw(1) - if evt == 4: - toggle3_val = 1 - toggle3_val - flip_z = toggle3_val - Draw.Redraw(1) - if evt == 5: - toggle4_val = 1 - toggle4_val - speed = toggle4_val - Draw.Redraw(1) - if evt == 10: - toggle5_val = 1 - toggle5_val - if toggle5_val==1: - toggle6_val = 0 - toggle7_val = 0 - else : - toggle6_val = 1 - toggle7_val = 1 - no_light = toggle7_val - recalc_norm = toggle6_val - Bl_norm = toggle5_val - Draw.Redraw(1) - if evt == 11: - toggle6_val = 1 - toggle6_val - if toggle6_val==1: - toggle5_val = 0 - toggle7_val = 0 - else : - toggle5_val = 1 - toggle7_val = 1 - no_light = toggle7_val - recalc_norm = toggle6_val - Bl_norm = toggle5_val - Draw.Redraw(1) - if evt == 12: - toggle7_val = 1 - toggle7_val - if toggle7_val==1: - toggle6_val = 0 - toggle5_val = 0 - else : - toggle6_val = 1 - toggle5_val = 1 - no_light = toggle7_val - recalc_norm = toggle6_val - Bl_norm = toggle5_val - Draw.Redraw(1) - if evt == 6: - ticks = anim_tick.val - if evt == 7: - fname = Blender.sys.makename(ext = ".x") - Blender.Window.FileSelector(my_callback, "Export DirectX", fname) - if evt == 8: - fname = Blender.sys.makename(ext = ".x") - Blender.Window.FileSelector(my_callback_sel, "Export DirectX", fname) - if evt == 9: - Draw.Exit() - - -def draw(): - global animsg,flipmsg,swapmsg,anim_tick - global flip_z,swap_yz,flip_norm,anim,ticks,speed,recalc_norm,Bl_norm,no_light - glClearColor(0.55,0.6,0.6,1) - glClear(BGL.GL_COLOR_BUFFER_BIT) - #external box - glColor3f(0.2,0.3,0.3) - rect(10,402,300,382) - #-- - #glColor3f(0.3,0.4,0.4) - #rect(11,399,298,398) - #-- - glColor3f(0.5,0.75,0.65) - rect(14,398,292,30) - #-- - glColor3f(0.5,0.75,0.65) - rect(14,366,292,160) - #-- - glColor3f(0.5,0.75,0.65) - rect(14,202,292,60) - #-- - glColor3f(0.5,0.75,0.65) - rect(14,138,292,40) - #-- - glColor3f(0.5,0.75,0.65) - rect(14,94,292,70) - - glColor3f(0.8,.8,0.6) - glRasterPos2i(20, 380) - Draw.Text("DirectX Exporter ",'large') - Draw.Text("(for Blender 2.41)", 'small') - #-------Aniamtion toggle--------------------------------------------- - Draw.Toggle("Anim", 1, 20, 330, 55, 20, toggle_val,"export animations") - if toggle_val : - anim = 1 - animsg = "animation will be exported" - else: - anim = 0 - animsg = "animation will be not exported" - glRasterPos2i(100,335) - Draw.Text(animsg) - #---Flip normals toggle----------------------------------------------- - Draw.Toggle("Flip norm", 2, 20, 300, 55, 20, toggle1_val,"invert normals") - if toggle1_val : - flip_norm = 1 - flipmsg = "flipped normals" - else: - flip_norm = 0 - flipmsg = "not flipped normals" - glRasterPos2i(100,305) - Draw.Text(flipmsg) - #------Swap yz toggle---------------------------------------------------------------- - Draw.Toggle("Swap zy", 3, 20, 270, 55, 20, toggle2_val,"swap z,y axis(y up)") - if toggle2_val : - swap_yz = 1 - swapmsg = "Y-axis up" - else: - swap_yz = 0 - swapmsg = "Z-axis up" - glRasterPos2i(100,275) - Draw.Text(swapmsg) - #------Flip z toggle---------------------------------------------------------------- - Draw.Toggle("Flip z", 4, 20, 240, 55, 20, toggle3_val,"flip z axis") - if toggle3_val : - flip_z = 1 - zmsg = "left handed system" - else: - flip_z = 0 - zmsg = "right handed system" - glRasterPos2i(100,245) - Draw.Text(zmsg) - #------Speed toggle---------------------------------------------------------------- - Draw.Toggle("Speed", 5, 20, 210, 55, 20, toggle4_val,"Animation speed") - if toggle4_val : - speed = 1 - spedmsg = "set speed" - anim_tick = Draw.Number("", 6,200, 210, 85, 20, anim_tick.val,1,100000,"ticks per second") - else: - speed = 0 - spedmsg = "" - glRasterPos2i(100,215) - Draw.Text(spedmsg) - #------Blender Normals toggle---------------------------------------------------------------- - Draw.Toggle("Bl.normals", 10, 20, 105, 75, 25, toggle5_val,"export normals as in Blender") - if toggle5_val : - Bl_norm = 1 - #------Recalculute Normals toggle---------------------------------------------------------------- - Draw.Toggle("recalc.no", 11, 120, 105, 75, 25, toggle6_val,"export recalculated normals") - if toggle6_val : - recalc_norm = 1 - #------Recalculute Normals toggle---------------------------------------------------------------- - Draw.Toggle("no smooth", 12, 220, 105, 75, 25, toggle7_val,"every vertex has the face normal,no smoothing") - if toggle7_val : - no_light = 1 - #------Draw Button export---------------------------------------------------------------- - exp_butt = Draw.Button("Export All",7,20, 155, 75, 30, "export all the scene objects") - sel_butt = Draw.Button("Export Sel",8,120, 155, 75, 30, "export the selected object") - exit_butt = Draw.Button("Exit",9,220, 155, 75, 30, "exit") - glRasterPos2i(20,75) - Draw.Text("(C) 2006 Arben OMARI ") - glRasterPos2i(20,55) - Draw.Text("http://www.omariben.too.it") - glRasterPos2i(20,35) - Draw.Text("aromar@tin.it") - -def rect(x,y,width,height): - glBegin(GL_LINE_LOOP) - glVertex2i(x,y) - glVertex2i(x+width,y) - glVertex2i(x+width,y-height) - glVertex2i(x,y-height) - glEnd() - -def rectFill(x,y,width,height): - glBegin(GL_POLYGON) - glVertex2i(x,y) - glVertex2i(x+width,y) - glVertex2i(x+width,y-height) - glVertex2i(x,y-height) - glEnd() - - - -Draw.Register(draw, event, button_event) - - -#*********************************************** -#*********************************************** -# EXPORTER -#*********************************************** -#*********************************************** - -class xExport: - def __init__(self, filename): - self.file = open(filename, "w") - -#********************************************************************************************************************************************* - #*********************************************** - #Select Scene objects - #*********************************************** - def analyzeScene(self): - parent_list = [] - for obj in Blender.Scene.GetCurrent().objects: - if obj.type in ('Mesh', 'Armature', 'Empty'): - if obj.parent == None : - parent_list.append(obj) - - return parent_list - - def getChildren(self,obj): - obs = Blender.Scene.GetCurrent().objects - return [ ob for ob in obs if ob.parent == obj ] - - def getArmChildren(self,obj): - for ob in Blender.Scene.GetCurrent().objects: #Object.Get(): - if ob.parent == obj : - return ob - - def getLocMat(self, obj): - pare = obj.parent - mat = obj.matrixWorld - mat_id = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]) - if pare: - mat_p = pare.matrixWorld - mat_c = Matrix(mat_p) - mat_c.invert() - mat_f = mat * mat_c - else : - mat_id.invert() - mat_f = mat * mat_id - return mat_f - - def writeObjFrames(self,obj): - global space,chld_obj,ch_list - mesh = obj.getData() - if obj.type == "Empty" : - mat = self.getLocMat(obj) - mat_c = Matrix(mat) - self.writeArmFrames(mat_c, make_legal_name(obj.name)) - if type(mesh) == Types.ArmatureType : - Child_obj = self.getArmChildren(obj) - chld_obj = obj - ch_list.append(Child_obj) - self.writeRootBone(obj, Child_obj) - if obj.type == 'Mesh' and obj not in ch_list: - self.exportMesh(obj) - - - def writeChildObj(self,obj): - global space,ch_list - space += 1 - if obj : - for ob in obj: - if ob not in ch_list: - self.writeObjFrames(ob) - ch_list.append(ob) - ch_ob = self.getChildren(ob) - self.writeChildObj(ch_ob) - self.closeBrackets() - self.file.write(" // End of the Object %s \n" % (ob.name)) - - - def writeRootFrame(self): - global flip_z,swap_yz,speed - if speed: - self.writeAnimTicks() - if flip_z: - mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]) - else : - mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) - if swap_yz : - mat_rot = RotationMatrix(-90, 4, 'x') - mat_flip = mat_rot * mat_flip - self.writeArmFrames(mat_flip, "RootFrame") - - ################################################################## - def SelectObjs(self): - global space,chld_obj,ch_list,flip_z,swap_yz,speed - print "exporting..." - self.writeHeader() - self.writeRootFrame() - obj_list = self.analyzeScene() - space += 1 - ch_list = [] - for obj in obj_list: - self.writeObjFrames(obj) - ch_l = self.getChildren(obj) - for ch in ch_l: - - - if ch and ch.type == "Armature": - ch_list.append(ch) - self.writeObjFrames(ch) - else : - self.writeChildObj(ch_l) - if obj.type != "Armature": - self.file.write(" } // SI End of the Object %s \n" % (obj.name)) - - - - self.file.write("} // End of the Root Frame\n") - if anim : - self.file.write("AnimationSet AnimationSet0 {\n") - for obj in Blender.Scene.GetCurrent().objects: - if obj.type in ('Mesh', 'Empty'): - ip_list = obj.ipo - if ip_list != None : - self.writeAnimationObj(obj) - elif obj.type == 'Armature': - act_list = obj.getAction() - if act_list != None : - self.writeAnimation(obj) - #ip_list = obj.ipo - #if ip_list != None : - # self.writeAnimationObj(obj) - - self.file.write("} // End of Animation Set\n") - self.writeEnd() - ####################################################### - - - def writeAnimTicks(self): - global ticks - self.file.write("AnimTicksPerSecond {\n") - self.file.write("%d; \n" % (ticks)) - self.file.write("}\n") - - #*********************************************** - #Export Mesh without Armature - #*********************************************** - def exportMesh(self, obj): - tex = [] - mesh = obj.getData() - self.writeTextures(obj, tex) - self.writeMeshcoordArm(obj, arm_ob = None) - self.writeMeshMaterialList(obj, mesh, tex) - self.writeMeshNormals(obj, mesh) - self.writeMeshTextureCoords(obj, mesh) - self.writeMeshVertexColors(obj, mesh) - self.file.write(" } // End of the Mesh %s \n" % (obj.name)) - - - #*********************************************** - #Export the Selected Mesh - #*********************************************** - def exportSelMesh(self): - print "exporting ..." - self.writeHeader() - self.writeRootFrame() - tex = [] - objs = Object.GetSelected() - for obj in objs: - if obj.type == 'Mesh': - mesh = obj.data - self.writeTextures(obj, tex) - self.writeMeshcoordArm(obj, arm_ob = None) - self.writeMeshMaterialList(obj, mesh, tex) - self.writeMeshNormals(obj, mesh) - self.writeMeshTextureCoords(obj, mesh) - self.writeMeshVertexColors(obj, mesh) - self.file.write(" }\n") - self.file.write("}\n") - ind = objs.index(obj) - if ind == len(objs)-1: - self.file.write("}\n") - ip_list = obj.ipo - if ip_list != None : - self.file.write("AnimationSet AnimationSet0 {\n") - self.writeAnimationObj(obj) - self.file.write("}\n") - else : - print "The selected object is not a mesh" - print "...finished" - #*********************************************** - #Export Mesh with Armature - #*********************************************** - def exportMeshArm(self,arm,arm_ob,ch_obj): - tex = [] - mesh = ch_obj.getData() - self.writeTextures(ch_obj, tex) - self.writeMeshcoordArm(ch_obj ,arm_ob) - self.writeMeshMaterialList(ch_obj, mesh, tex) - self.writeMeshNormals(ch_obj, mesh) - self.writeMeshTextureCoords(ch_obj, mesh) - self.writeSkinWeights(arm,mesh) - #self.file.write(" } // End of the Frame %s \n" % (ch_obj.name)) - self.file.write(" } // End of the Object %s \n" % (ch_obj.name)) - - #*********************************************** - #Export Root Bone - #*********************************************** - def writeRootBone(self, chld_obj, child_obj): - global space,root_bon - arms = chld_obj.getData() - mat_arm = self.getLocMat(chld_obj) - for bon in arms.bones.values(): - if bon.hasParent(): - pass - else: - root_bon = bon - space += 1 - mat_r = self.writeAnimCombineMatrix(root_bon,1) - self.writeArmFrames(mat_r, make_legal_name(root_bon.name)) - - bon_c = root_bon.children - self.writeChildren(bon_c) - self.file.write(" } // End of the Bone %s \n" % (root_bon.name)) - self.exportMeshArm(arms, chld_obj ,child_obj) - - #*********************************************** - #Create Children structure - #*********************************************** - def writeBon(self,bon): - global space - mat_r = self.writeAnimCombineMatrix(bon,1) - self.writeArmFrames(mat_r, make_legal_name(bon.name)) - - - def writeChildren(self,bon_c): - global space,bone_list - space += 1 - if bon_c: - for bo in bon_c: - if bo.name not in bone_list: - self.writeBon(bo) - bone_list.append(bo.name) - bo_c = bo.children - self.writeChildren(bo_c) - self.closeBrackets() - - - - def closeBrackets(self): - global space - space = space-1 - tab = " " - self.file.write("%s" % (tab * space)) - self.file.write("}\n") - - - - #*********************************************** - #Offset Matrix - #*********************************************** - def writeMatrixOffset(self,bon): - global chld_obj - Blender.Set('curframe', 1) - pose = chld_obj.getPose() - pos_b = pose.bones[bon.name] - mat_b = pos_b.poseMatrix - mat_c = Matrix(mat_b) - mat_c.invert() - return mat_c - - - #*********************************************** - #Combine Matrix - #*********************************************** - def writeCombineMatrix(self,bon): - global chld_obj - - Blender.Set('curframe', 1) - pose = chld_obj.getPose() - pos_b = pose.bones[bon.name] - mat_b = pos_b.poseMatrix - if bon.hasParent(): - pare = bon.parent - pos_p = pose.bones[pare.name] - mat_p = pos_p.poseMatrix - - else: - mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) - mat_c = Matrix(mat_p) - mat_c.invert() - mat_f = mat_b * mat_c - - return mat_f - #*********************************************** - #Combine Matrix - #*********************************************** - def writeAnimCombineMatrix(self,bon,fre): - global chld_obj - Blender.Set('curframe', fre) - pose = chld_obj.getPose() - pos_b = pose.bones[bon.name] - mat_b = pos_b.poseMatrix - if bon.hasParent(): - pare = bon.parent - pos_p = pose.bones[pare.name] - mat_p = pos_p.poseMatrix - - else: - mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) - mat_c = Matrix(mat_p) - mat_c.invert() - mat_f = mat_b * mat_c - - return mat_f - - -#********************************************************************************************************************************************* - #*********************************************** - #Write SkinWeights - #*********************************************** - def writeSkinWeights(self, arm, mesh): - global index_list - v_dict = {} - Blender.Set('curframe',1) - self.file.write(" XSkinMeshHeader {\n") - max_infl = 0 - for bo in arm.bones.values() : - name = bo.name - try : - vertx_list = mesh.getVertsFromGroup(name,1) - for inde in vertx_list : - vert_infl = mesh.getVertexInfluences(inde[0]) - ln_infl = len(vert_infl) - if ln_infl > max_infl : - max_infl = ln_infl - - except: - pass - - self.file.write(" %d; \n" % (max_infl)) - self.file.write(" %d; \n" % (max_infl * 3)) - self.file.write(" %d; \n" % (len(arm.bones.values()))) - self.file.write(" }\n") - - for bo in arm.bones.values() : - bo_list = [] - weight_list = [] - name = bo.name - f_name = make_legal_name(name) - try : - vert_list = mesh.getVertsFromGroup(name,1) - le = 0 - for indx in vert_list: - ver_infl = mesh.getVertexInfluences(indx[0]) - infl = 0.0 - if len(ver_infl) != 0: - sum = 0.0 - for bone_n, weight in ver_infl: - if bone_n == name: - infl = weight - sum += weight - infl /= sum - - i = -1 - for el in index_list : - i += 1 - if el == indx[0] : - le +=1 - bo_list.append(i) - weight_list.append(infl) - - - self.file.write(" SkinWeights {\n") - self.file.write(' "%s"; \n' % (f_name)) - self.file.write(' %d; \n' % (le)) - count = 0 - for ind in bo_list : - count += 1 - if count == len(bo_list): - self.file.write(" %d; \n" % (ind)) - else : - self.file.write(" %d, \n" % (ind)) - cou = 0 - for wegh in weight_list : - cou += 1 - - if cou == len(weight_list): - self.file.write(" %f; \n" % (round(wegh,6))) - else : - self.file.write(" %f, \n" % (round(wegh,6))) - - - matx = self.writeMatrixOffset(bo) - self.writeOffsFrames(matx, name) - except : - pass - self.file.write(" } // End of XSkinMeshHeader\n") - - - #*********************************************** - # Write Matrices - #*********************************************** - def writeArmFrames(self, matx, name): - global space - tab = " " - self.file.write("%s" % (tab * space)) - self.file.write("Frame ") - self.file.write("%s {\n\n" % (name)) - self.file.write("%s" % (tab * space)) - self.file.write(" FrameTransformMatrix {\n") - self.writeFrame(matx) - - #*********************************************** - # Write Frames - #*********************************************** - def writeOffsFrames(self, matx, name): - space = 1 - self.writeFrame(matx) - - #*********************************************** - # Write Frames - #*********************************************** - def writeFrame(self, matx): - tab = " " - self.file.write("%s" % (tab * space)) - self.file.write(" %f,%f,%f,%f,\n" % - (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4))) - self.file.write("%s" % (tab * space)) - self.file.write(" %f,%f,%f,%f,\n" % - (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4))) - self.file.write("%s" % (tab * space)) - self.file.write(" %f,%f,%f,%f,\n" % - (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4))) - self.file.write("%s" % (tab * space)) - self.file.write(" %f,%f,%f,%f;;\n" % - (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4))) - self.file.write("%s" % (tab * space)) - self.file.write(" }\n") -#********************************************************************************************************************************************* - - #*********************************************** - #HEADER - #*********************************************** - def writeHeader(self): - self.file.write("xof 0303txt 0032\n\n\n") - self.file.write("template VertexDuplicationIndices { \n\ - \n\ - DWORD nIndices;\n\ - DWORD nOriginalVertices;\n\ - array DWORD indices[nIndices];\n\ -}\n\ -template XSkinMeshHeader {\n\ - <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\n\ - WORD nMaxSkinWeightsPerVertex;\n\ - WORD nMaxSkinWeightsPerFace;\n\ - WORD nBones;\n\ -}\n\ -template SkinWeights {\n\ - <6f0d123b-bad2-4167-a0d0-80224f25fabb>\n\ - STRING transformNodeName;\n\ - DWORD nWeights;\n\ - array DWORD vertexIndices[nWeights];\n\ - array float weights[nWeights];\n\ - Matrix4x4 matrixOffset;\n\ -}\n\n") - - #*********************************************** - #CLOSE FILE - #*********************************************** - def writeEnd(self): - self.file.close() - print "... finished" - - - #*********************************************** - #EXPORT TEXTURES - #*********************************************** - def writeTextures(self,name, tex): - mesh = name.data - for face in mesh.faces: - if face.image and face.image.name not in tex: - tex.append(face.image.name) - - - - #*********************************************** - #EXPORT MESH DATA with Armature - #*********************************************** - def writeMeshcoordArm(self, obj ,arm_ob): - global index_list,flip_z - #TransformMatrix - mat = self.getLocMat(obj) - self.writeArmFrames(mat, make_legal_name(obj.name)) - mesh = NMesh.GetRawFromObject(obj.name) - self.file.write("Mesh {\n") - numface=len(mesh.faces) - #VERTICES NUMBER - numvert = 0 - for face in mesh.faces: - numvert = numvert + len(face.v) - self.file.write("%d;\n" % (numvert)) - if numvert == 0: - print "Mesh named",mesh.name,"has no vertices.Problems may occur using the .x file" - #VERTICES COORDINATES - counter = 0 - for face in mesh.faces: - counter += 1 - for n in range(len(face.v)): - index_list.append(face.v[n].index) - vec_vert = Vector([(face.v[n].co[0]), face.v[n].co[1], face.v[n].co[2], 1]) - if arm_ob : - f_vec_vert = vec_vert * mat - else : - f_vec_vert = vec_vert - self.file.write("%f; %f; %f;" % (round(f_vec_vert[0],4), round(f_vec_vert[1],4), round(f_vec_vert[2],4))) - if counter == numface : - if n == len(face.v)-1 : - self.file.write(";\n") - else : - self.file.write(",\n") - else : - self.file.write(",\n") - if flip_z: - a3 = 0;b3 = 2;c3 = 1 - a4 = 0;b4 = 3;c4 = 2;d4 = 1 - else: - a3 = 0;b3 = 1;c3 = 2 - a4 = 0;b4 = 1;c4 = 2;d4 = 3 - - #FACES NUMBER - self.file.write("%s;\n" % (numface)) - coun,counter = 0, 0 - for face in mesh.faces : - coun += 1 - separator = ',' - if coun == numface: - separator = ';' - if len(face.v) == 3: - self.file.write("3; %d, %d, %d;%c\n" % (counter + a3, counter + b3, counter + c3, separator)) - counter += 3 - elif len(face.v) == 4: - self.file.write("4; %d, %d, %d, %d;%c\n" % (counter + a4, counter + b4, counter + c4, counter + d4, separator)) - counter += 4 - elif len(face.v) < 3: - print "WARNING:the mesh has faces with less then 3 vertices" - print " It my be not exported correctly." - - - #*********************************************** - #MESH MATERIAL LIST - #*********************************************** - def writeMeshMaterialList(self, obj, mesh, tex): - self.file.write(" MeshMaterialList {\n") - #HOW MANY MATERIALS ARE USED - count = 0 - for mat in mesh.getMaterials(): - count+=1 - self.file.write(" %d;\n" % (len(tex) + count)) - #HOW MANY FACES IT HAS - numfaces=len(mesh.faces) - self.file.write(" %d;\n" % (numfaces)) - ##MATERIALS INDEX FOR EVERY FACE - counter = 0 - for face in mesh.faces : - counter += 1 - mater = face.materialIndex - if counter == numfaces: - if face.image and face.image.name in tex : - self.file.write(" %d;;\n" % (tex.index(face.image.name) + count)) - else : - self.file.write(" %d;;\n" % (mater)) - else : - if face.image and face.image.name in tex : - self.file.write(" %d,\n" % (tex.index(face.image.name) + count)) - else : - self.file.write(" %d,\n" % (mater)) - - ##MATERIAL NAME - for mat in mesh.getMaterials(): - self.file.write(" Material") - self.file.write(" %s "% (make_legal_name(mat.name))) - self.file.write("{\n") - self.file.write(" %f; %f; %f;" % (mat.R, mat.G, mat.B)) - self.file.write("%s;;\n" % (mat.alpha)) - self.file.write(" %f;\n" % (mat.spec)) - self.file.write(" %f; %f; %f;;\n" % (mat.specR, mat.specG, mat.specB)) - self.file.write(" 0.0; 0.0; 0.0;;\n") - self.file.write(" } //End of Material\n") - - for mat in tex: - self.file.write(" Material Mat") - self.file.write("%s "% (len(tex))) - self.file.write("{\n") - self.file.write(" 1.0; 1.0; 1.0; 1.0;;\n") - self.file.write(" 1.0;\n") - self.file.write(" 1.0; 1.0; 1.0;;\n") - self.file.write(" 0.0; 0.0; 0.0;;\n") - self.file.write(" TextureFilename {") - self.file.write(' "%s";'% (mat)) - self.file.write(" }\n") - self.file.write(" } // End of Material\n") - self.file.write(" } //End of MeshMaterialList\n") - - #*********************************************** - #MESH NORMALS - #*********************************************** - def writeMeshNormals(self,name,mesh): - global flip_norm,flip_z,no_light,recalc_norm,Bl_norm - - self.file.write(" MeshNormals {\n") - #VERTICES NUMBER - numvert = 0 - for face in mesh.faces: - numvert = numvert + len(face.v) - self.file.write("%d;\n" % (numvert)) - numfaces=len(mesh.faces) - if flip_norm : - fl = -1 - else : - fl = 1 - #VERTICES NORMAL - if Bl_norm: - self.writeBlenderNormals(mesh,fl) - if recalc_norm: - self.writeRecalcNormals(mesh,fl) - if no_light: - self.writeNoSmothing(mesh,fl) - - - - if flip_z: - a3 = 0;b3 = 2;c3 = 1 - a4 = 0;b4 = 3;c4 = 2;d4 = 1 - else: - a3 = 0;b3 = 1;c3 = 2 - a4 = 0;b4 = 1;c4 = 2;d4 = 3 - - #FACES NUMBER - self.file.write("%s;\n" % (numfaces)) - coun,counter = 0, 0 - for face in mesh.faces : - coun += 1 - if coun == numfaces: - if len(face.v) == 3: - self.file.write("3; %d, %d, %d;;\n" % (counter + a3, counter + b3, counter + c3)) - counter += 3 - else : - self.file.write("4; %d, %d, %d, %d;;\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) - counter += 4 - else: - - if len(face.v) == 3: - self.file.write("3; %d, %d, %d;,\n" % (counter + a3, counter + b3, counter + c3)) - counter += 3 - else : - self.file.write("4; %d, %d, %d, %d;,\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) - counter += 4 - self.file.write("} //End of MeshNormals\n") - - def writeBlenderNormals(self,mesh,fl): - numfaces=len(mesh.faces) - #VERTICES NORMAL - counter = 0 - for face in mesh.faces: - counter += 1 - for n in range(len(face.v)): - self.file.write(" %f; %f; %f;" % ( - (round(face.v[n].no[0],6)*fl),(round(face.v[n].no[1],6)*fl),(round(face.v[n].no[2],6)*fl))) - if counter == numfaces : - if n == len(face.v)-1 : - self.file.write(";\n") - else : - self.file.write(",\n") - else : - self.file.write(",\n") - - def writeRecalcNormals(self,mesh,fl): - numfaces=len(mesh.faces) - normal_list = {} - idx = 0 - for vertex in mesh.verts: - v_norm = Vector([0, 0, 0]) - normal_list[idx] = v_norm - idx += 1 - for face in mesh.faces: - for verts in face.v: - if verts.index == vertex.index : - v_norm[0] += face.no[0] - v_norm[1] += face.no[1] - v_norm[2] += face.no[2] - - v_norm.normalize() - - counter = 0 - for face in mesh.faces: - counter += 1 - n = 0 - for vert in face.v: - n += 1 - norm = normal_list[vert.index] - - self.file.write(" %f; %f; %f;" % ( - (round(norm[0],6)*fl),(round(norm[1],6)*fl),(round(norm[2],6)*fl))) - if counter == numfaces : - if n == len(face.v) : - self.file.write(";\n") - else : - self.file.write(",\n") - else : - self.file.write(",\n") - - def writeNoSmothing(self,mesh,fl): - numfaces=len(mesh.faces) - counter = 0 - for face in mesh.faces: - counter += 1 - n = 0 - for n in range(len(face.v)): - n += 1 - self.file.write(" %f; %f; %f;" % ( - (round(face.no[0],6)*fl),(round(face.no[1],6)*fl),(round(face.no[2],6)*fl))) - - - if counter == numfaces : - if n == len(face.v) : - self.file.write(";\n") - else : - self.file.write(",\n") - else : - self.file.write(",\n") - #*********************************************** - #MESH TEXTURE COORDS - #*********************************************** - def writeMeshTextureCoords(self, name, mesh): - if mesh.hasFaceUV(): - self.file.write("MeshTextureCoords {\n") - #VERTICES NUMBER - numvert = 0 - for face in mesh.faces: - numvert += len(face.v) - self.file.write("%d;\n" % (numvert)) - #UV COORDS - numfaces = len(mesh.faces) - counter = -1 - co = 0 - for face in mesh.faces: - counter += 1 - co += 1 - for n in range(len(face.v)): - self.file.write("%f;%f;" % (mesh.faces[counter].uv[n][0], -mesh.faces[counter].uv[n][1])) - if co == numfaces : - if n == len(face.v) - 1 : - self.file.write(";\n") - else : - self.file.write(",\n") - else : - self.file.write(",\n") - - self.file.write("} //End of MeshTextureCoords\n") - - #*********************************************** - #MESH VORTEX COLORS - #*********************************************** - def writeMeshVertexColors(self, name, mesh): - if mesh.hasVertexColours(): - self.file.write("MeshVertexColors {\n") - #VERTICES NUMBER - numvert = reduce( lambda i,f: len(f)+i, mesh.faces, 0) - self.file.write("%d;\n" % (numvert)) - #VERTEX COLORS - - vcounter =0 - for f in mesh.faces: - col = f.col - for i,c in enumerate(col): - # Note vcol alpha has no meaning - self.file.write("%d;%f;%f;%f;%f;" % (vcounter,c.r/255.0, c.g/255.0, c.b/255.0, 1.0)) # c.a/255.0)) - vcounter+=1 - if vcounter == numvert : - self.file.write(";\n") - else : - self.file.write(",\n") - - self.file.write("} //End of MeshVertexColors\n") - -#***********************************************#***********************************************#*********************************************** - #*********************************************** - #FRAMES - #*********************************************** - def writeFrames(self, matx): - - self.file.write("%f,%f,%f,%f," % - (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4))) - self.file.write("%f,%f,%f,%f," % - (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4))) - self.file.write("%f,%f,%f,%f," % - (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4))) - self.file.write("%f,%f,%f,%f;;" % - (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4))) - - - - - - #*********************************************** - #WRITE ANIMATION KEYS - #*********************************************** - def writeAnimation(self,arm_ob): - global mat_dict, root_bon - arm = arm_ob.getData() - act_list = arm_ob.getAction() - ip = act_list.getAllChannelIpos() - for bon in arm.bones.values() : - point_list = [] - name = bon.name - name_f = make_legal_name(name) - try : - ip_bon_channel = ip[bon.name] - ip_bon_name = ip_bon_channel.getName() - - ip_bon = Blender.Ipo.Get(ip_bon_name) - poi = ip_bon.getCurves() - - for po in poi[3].getPoints(): - a = po.getPoints() - point_list.append(int(a[0])) - #point_list.pop(0) - - self.file.write(" Animation { \n") - self.file.write(" { %s }\n" %(name_f)) - self.file.write(" AnimationKey { \n") - self.file.write(" 4;\n") - self.file.write(" %d; \n" % (len(point_list))) - - for fr in point_list: - - if name == root_bon.name : - - - mat_b = self.writeAnimCombineMatrix(bon,fr) - mat_arm = self.getLocMat(arm_ob) - mat = mat_b * mat_arm - else: - mat = self.writeAnimCombineMatrix(bon,fr) - - self.file.write(" %d;" % (fr)) - self.file.write("16;") - - self.writeFrames(mat) - - if fr == point_list[len(point_list)-1]: - self.file.write(";\n") - else: - self.file.write(",\n") - self.file.write(" }\n") - self.file.write(" }\n") - self.file.write("\n") - except: - pass - - - - #*********************************************** - #WRITE ANIMATION KEYS - #*********************************************** - def writeAnimationObj(self, obj): - point_list = [] - ip = obj.ipo - poi = ip.getCurves() - for po in poi[0].getPoints(): - a = po.getPoints() - point_list.append(int(a[0])) - - self.file.write(" Animation {\n") - self.file.write(" { ") - self.file.write("%s }\n" % (make_legal_name(obj.name))) - self.file.write(" AnimationKey { \n") - self.file.write(" 4;\n") - self.file.write(" %d; \n" % (len(point_list))) - for fr in point_list: - self.file.write(" %d;" % (fr)) - self.file.write("16;") - Blender.Set('curframe',fr) - - #mat_new = self.getLocMat(obj) - mat_new = obj.matrixLocal - self.writeFrames(mat_new) - - if fr == point_list[len(point_list)-1]: - self.file.write(";\n") - else: - self.file.write(",\n") - self.file.write(" }\n") - self.file.write(" }\n") - - - -#***********************************************#***********************************************#*********************************************** - - - - - diff --git a/release/scripts/DirectX8Importer.py b/release/scripts/DirectX8Importer.py deleted file mode 100644 index 0dda654944d..00000000000 --- a/release/scripts/DirectX8Importer.py +++ /dev/null @@ -1,238 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: -Name: 'DirectX(.x)...' -Blender: 244 -Group: 'Import' - -Tip: 'Import from DirectX text file format format.' -""" -# DirectXImporter.py version 1.2 -# Copyright (C) 2005 Arben OMARI -- omariarben@everyday.com -# -# 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. - -# This script import meshes from DirectX text file format - -# Grab the latest version here :www.omariben.too.it -import bpy -import Blender -from Blender import Mesh,Object,Material,Texture,Image,Draw - - -class xImport: - def __init__(self, filename): - global my_path - self.file = open(filename, "r") - my_path = Blender.sys.dirname(filename) - - # - self.lines = [l_split for l in self.file.readlines() for l_split in (' '.join(l.split()),) if l_split] - - def Import(self): - lines = self.lines - print "importing into Blender ..." - scene = bpy.data.scenes.active - - mesh_indicies = {} # the index of each 'Mesh' is used as the key for those meshes indicies - context_indicies = None # will raise an error if used! - - - #Get the line of Texture Coords - nr_uv_ind = 0 - - #Get Materials - nr_fac_mat = 0 - i = -1 - mat_list = [] - tex_list = [] - mesh_line_indicies = [] - for j, line in enumerate(lines): - l = line.strip() - words = line.split() - if words[0] == "Material" : - #context_indicies["Material"] = j - self.loadMaterials(j, mat_list, tex_list) - elif words[0] == "MeshTextureCoords" : - context_indicies["MeshTextureCoords"] = j - #nr_uv_ind = j - elif words[0] == "MeshMaterialList" : - context_indicies["MeshMaterialList"] = j+2 - #nr_fac_mat = j + 2 - elif words[0] == "Mesh": # Avoid a second loop - context_indicies = mesh_indicies[j] = {'MeshTextureCoords':0, 'MeshMaterialList':0} - - for mesh_index, value in mesh_indicies.iteritems(): - mesh = Mesh.New() - self.loadVertices(mesh_index, mesh, value['MeshTextureCoords'], value['MeshMaterialList'], tex_list) - - mesh.materials = mat_list[:16] - if value['MeshMaterialList']: - self.loadMeshMaterials(value['MeshMaterialList'], mesh) - scene.objects.new(mesh) - - self.file.close() - print "... finished" - - #------------------------------------------------------------------------------ - # CREATE THE MESH - #------------------------------------------------------------------------------ - def loadVertices(self, nr_vr_ind, mesh, nr_uv, nr_fac_mat, tex_list): - v_ind = nr_vr_ind + 1 - lin = self.lines[v_ind] - if lin : - lin_c = self.CleanLine(lin) - nr_vert = int((lin_c.split()[0])) - else : - v_ind = nr_vr_ind + 2 - lin = self.lines[v_ind] - lin_c = self.CleanLine(lin) - nr_vert = int((lin_c.split()[0])) - - #-------------------------------------------------- - nr_fac_li = v_ind + nr_vert +1 - lin_f = self.lines[nr_fac_li] - if lin_f : - lin_fc = self.CleanLine(lin_f) - nr_face = int((lin_fc.split()[0])) - else : - nr_fac_li = v_ind + nr_vert +1 - lin_f = self.lines[nr_fac_li] - lin_fc = self.CleanLine(lin_f) - nr_face = int((lin_fc.split()[0])) - - #Get Coordinates - verts_list = [(0,0,0)] # WARNING - DUMMY VERT - solves EEKADOODLE ERROR - for l in xrange(v_ind + 1, (v_ind + nr_vert +1)): - line_v = self.lines[l] - lin_v = self.CleanLine(line_v) - words = lin_v.split() - if len(words)==3: - verts_list.append((float(words[0]),float(words[1]),float(words[2]))) - - mesh.verts.extend(verts_list) - del verts_list - - face_list = [] - #Make Faces - i = 0 - mesh_verts = mesh.verts - for f in xrange(nr_fac_li + 1, (nr_fac_li + nr_face + 1)): - i += 1 - line_f = self.lines[f] - lin_f = self.CleanLine(line_f) - - # +1 for dummy vert only! - words = lin_f.split() - if len(words) == 5: - face_list.append((1+int(words[1]), 1+int(words[2]), 1+int(words[3]), 1+int(words[4]))) - elif len(words) == 4: - face_list.append((1+int(words[1]), 1+int(words[2]), 1+int(words[3]))) - - mesh.faces.extend(face_list) - del face_list - - if nr_uv : - mesh.faceUV = True - for f in mesh.faces: - fuv = f.uv - for ii, v in enumerate(f): - # _u, _v = self.CleanLine(self.lines[nr_uv + 2 + v.index]).split() - - # Use a dummy vert - _u, _v = self.CleanLine(self.lines[nr_uv + 1 + v.index]).split() - - fuv[ii].x = float(_u) - fuv[ii].y = float(_v) - - if nr_fac_mat : - fac_line = self.lines[nr_fac_mat + i] - fixed_fac = self.CleanLine(fac_line) - w_tex = int(fixed_fac.split()[0]) - f.image = tex_list[w_tex] - - # remove dummy vert - mesh.verts.delete([0,]) - - def CleanLine(self,line): - return line.replace(\ - ";", " ").replace(\ - '"', ' ').replace(\ - "{", " ").replace(\ - "}", " ").replace(\ - ",", " ").replace(\ - "'", " ") - - #------------------------------------------------------------------ - # CREATE MATERIALS - #------------------------------------------------------------------ - def loadMaterials(self, nr_mat, mat_list, tex_list): - - def load_image(name): - try: - return Image.Load(Blender.sys.join(my_path,name)) - except: - return None - - mat = bpy.data.materials.new() - line = self.lines[nr_mat + 1] - fixed_line = self.CleanLine(line) - words = fixed_line.split() - mat.rgbCol = [float(words[0]),float(words[1]),float(words[2])] - mat.setAlpha(float(words[3])) - mat_list.append(mat) - l = self.lines[nr_mat + 5] - fix_3_line = self.CleanLine(l) - tex_n = fix_3_line.split() - - if tex_n and tex_n[0] == "TextureFilename" : - - if len(tex_n) > 1: - tex_list.append(load_image(tex_n[1])) - - if len(tex_n) <= 1 : - - l_succ = self.lines[nr_mat + 6] - fix_3_succ = self.CleanLine(l_succ) - tex_n_succ = fix_3_succ.split() - tex_list.append(load_image(tex_n_succ[0])) - else : - tex_list.append(None) # no texture for this index - - return mat_list, tex_list - #------------------------------------------------------------------ - # SET MATERIALS - #------------------------------------------------------------------ - def loadMeshMaterials(self, nr_fc_mat, mesh): - for face in mesh.faces: - nr_fc_mat += 1 - line = self.lines[nr_fc_mat] - fixed_line = self.CleanLine(line) - wrd = fixed_line.split() - mat_idx = int(wrd[0]) - face.mat = mat_idx - -#------------------------------------------------------------------ -# MAIN -#------------------------------------------------------------------ -def my_callback(filename): - if not filename.lower().endswith('.x'): print "Not an .x file" - ximport = xImport(filename) - ximport.Import() - -arg = __script__['arg'] - -if __name__ == '__main__': - Blender.Window.FileSelector(my_callback, "Import DirectX", "*.x") - -#my_callback('/fe/x/directxterrain.x') -#my_callback('/fe/x/Male_Normal_MAX.X') -#my_callback('/fe/x/male_ms3d.x') diff --git a/release/scripts/IDPropBrowser.py b/release/scripts/IDPropBrowser.py deleted file mode 100644 index 2a14760270a..00000000000 --- a/release/scripts/IDPropBrowser.py +++ /dev/null @@ -1,523 +0,0 @@ -#!BPY - -""" -Name: 'ID Property Browser' -Blender: 242 -Group: 'Help' -Tooltip: 'Browse ID properties' -""" - -__author__ = "Joe Eagar" -__version__ = "0.3.108" -__email__ = "joeedh@gmail.com" -__bpydoc__ = """\ - -Allows browsing, creating and editing of ID Properties -for various ID block types such as mesh, scene, object, -etc. -""" - -# -------------------------------------------------------------------------- -# ID Property Browser. -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -from Blender import * -from Blender.BGL import * -from Blender.Types import IDGroupType, IDArrayType -import Blender - -def IsInRectWH(mx, my, x, y, wid, hgt): - if mx >= x and mx <= x + wid: - if my >= y and my <= y + hgt: - return 1 - return 0 - -Button_Back = 1 -Button_New = 2 -Button_MatMenu = 3 -Button_TypeMenu = 4 - -ButStart = 55 - -IDP_String = 0 -IDP_Int = 1 -IDP_Float = 2 -IDP_Array = 5 -IDP_Group = 6 - -ButDelStart = 255 -#max limit for string input button -strmax = 100 - -State_Normal = 0 -State_InArray = 1 - -#IDTypeModules entries are of form [module, active_object_index, module_name] -IDTypeModules = [[Scene, 0, "Scenes"], [Object, 0, "Objects"], [Mesh, 0, "Meshes"]] -IDTypeModules += [[Material, 0, "Materials"], [Texture, 0, "Textures"]] -IDTypeModules += [[Image, 0, "Images"]] - -class IDArrayBrowser: - array = 0 - parentbrowser = 0 - buts = 0 - - def __init__(self): - self.buts = [] - - def Draw(self): - pb = self.parentbrowser - x = pb.x - y = pb.y - width = pb.width - height = pb.height - pad = pb.pad - itemhgt = pb.itemhgt - cellwid = 65 - y = y + height - itemhgt - pad - - Draw.PushButton("Back", Button_Back, x, y, 40, 20) - y -= itemhgt + pad - - self.buts = [] - Draw.BeginAlign() - for i in xrange(len(self.array)): - st = "" - if type(self.array[0]) == float: - st = "%.5f" % self.array[i] - else: st = str(self.array[i]) - - b = Draw.String("", ButStart+i, x, y, cellwid, itemhgt, st, 30) - self.buts.append(b) - x += cellwid + pad - if x + cellwid + pad > width: - x = 0 - y -= itemhgt + pad - Draw.EndAlign() - def Button(self, bval): - if bval == Button_Back: - self.parentbrowser.state = State_Normal - self.parentbrowser.array = 0 - self.buts = [] - Draw.Draw() - self.array = 0 - elif bval >= ButStart: - i = bval - ButStart - st = self.buts[i].val - n = 0 - if type(self.array[0]) == float: - try: - n = int(st) - except: - return - elif type(self.array[0]) == int: - try: - n = float(st) - except: - return - - self.array[i] = n - Draw.Draw() - - def Evt(self, evt, val): - if evt == Draw.ESCKEY: - Draw.Exit() - -class IDPropertyBrowser: - width = 0 - height = 0 - x = 0 - y = 0 - scrollx = 0 - scrolly = 0 - itemhgt = 22 - pad = 2 - - group = 0 - parents = 0 #list stack of parent groups - active_item = -1 - mousecursor = 0 - _i = 0 - buts = [] - - state = 0 - array = 0 - prop = 0 - - IDList = 0 - idindex = 0 - idblock = 0 - - type = 0 # attach buildin type() method to class - # since oddly it's not available to button - # callbacks! EEK! :( - - def __init__(self, idgroup, mat, x, y, wid, hgt): - self.group = idgroup - self.prop = idgroup - self.x = x - self.y = y - self.width = wid - self.height = hgt - self.mousecursor = [0, 0] - self.parents = [] - self.idblock = mat - self.type = type - - def DrawBox(self, glmode, x, y, width, height): - glBegin(glmode) - glVertex2f(x, y) - glVertex2f(x+width, y) - glVertex2f(x+width, y+height) - glVertex2f(x, y+height) - glEnd() - - def Draw(self): - global IDTypeModules - - #first draw outlining box :) - glColor3f(0, 0, 0) - self.DrawBox(GL_LINE_LOOP, self.x, self.y, self.width, self.height) - - itemhgt = self.itemhgt - pad = self.pad - x = self.x - y = self.y + self.height - itemhgt - pad - - if self.state == State_InArray: - self.array.Draw() - return - - plist = [] - self.buts = [] - for p in self.group.iteritems(): - plist.append(p) - - #-------do top buttons----------# - Draw.BeginAlign() - Draw.PushButton("New", Button_New, x, y, 40, 20) - x += 40 + pad - #do the menu button for all materials - st = "" - - blocks = IDTypeModules[self.IDList][0].Get() - i = 1 - mi = 0 - for m in blocks: - if m.name == self.idblock.name: - mi = i - st += m.name + " %x" + str(i) + "|" - i += 1 - - self.menubut = Draw.Menu(st, Button_MatMenu, x, y, 100, 20, mi) - - x += 100 + pad - - st = "" - i = 0 - for e in IDTypeModules: - st += e[2] + " %x" + str(i+1) + "|" - i += 1 - - cur = self.IDList + 1 - self.idmenu = Draw.Menu(st, Button_TypeMenu, x, y, 100, 20, cur) - x = self.x - y -= self.itemhgt + self.pad - Draw.EndAlign() - - - #-----------do property items---------# - i = 0 - while y > self.y - 20 - pad and i < len(plist): - k = plist[i][0] - p = plist[i][1] - if i == self.active_item: - glColor3f(0.5, 0.4, 0.3) - self.DrawBox(GL_POLYGON, x+pad, y, self.width-pad*2, itemhgt) - - glColor3f(0, 0, 0) - self.DrawBox(GL_LINE_LOOP, x+pad, y, self.width-pad*2, itemhgt) - - glRasterPos2f(x+pad*2, y+5) - Draw.Text(str(k)) #str(self.mousecursor) + " " + str(self.active_item)) #p.name) - tlen = Draw.GetStringWidth(str(k)) - - type_p = type(p) - if type_p == str: - b = Draw.String("", ButStart+i, x+pad*5+tlen, y, 200, itemhgt, p, strmax) - self.buts.append(b) - elif type_p in [int, float]: - #only do precision to 5 points on floats - st = "" - if type_p == float: - st = "%.5f" % p - else: st = str(p) - b = Draw.String("", ButStart+i, x+pad*5+tlen, y, 75, itemhgt, st, strmax) - self.buts.append(b) - else: - glRasterPos2f(x+pad*2 +tlen+10, y+5) - if type_p == Types.IDArrayType: - Draw.Text('(array, click to edit)') - elif type_p == Types.IDGroupType: - Draw.Text('(group, click to edit)') - - - self.buts.append(None) - - Draw.PushButton("Del", ButDelStart+i, x+self.width-35, y, 30, 20) - - i += 1 - y -= self.itemhgt + self.pad - - if len(self.parents) != 0: - Draw.PushButton("Back", Button_Back, x, y, 40, 20) - x = x + 40 + pad - - def SetActive(self): - m = self.mousecursor - itemhgt = self.itemhgt - pad = self.pad - - x = self.x + pad - y = self.y + self.height - itemhgt - pad - itemhgt - - plist = [] - for p in self.group.iteritems(): - plist.append(p) - - self.active_item = -1 - i = 0 - while y > self.y and i < len(plist): - p = plist[i] - if IsInRectWH(m[0], m[1], x, y, self.width-pad, itemhgt): - self.active_item = i - - i += 1 - y -= self.itemhgt + self.pad - - def EventIn(self, evt, val): - if self.state == State_InArray: - self.array.Evt(evt, val) - - if evt == Draw.ESCKEY: - Draw.Exit() - if evt == Draw.MOUSEX or evt == Draw.MOUSEY: - size = Buffer(GL_FLOAT, 4) - glGetFloatv(GL_SCISSOR_BOX, size) - if evt == Draw.MOUSEX: - self.mousecursor[0] = val - size[0] - else: - self.mousecursor[1] = val - size[1] - del size - - self.SetActive() - self._i += 1 - if self._i == 5: - Draw.Draw() - self._i = 0 - - - if evt == Draw.LEFTMOUSE and val == 1: - plist = list(self.group.iteritems()) - a = self.active_item - if a >= 0 and a < len(plist): - p = plist[a] - - basictypes = [IDGroupType, float, str, int] - if type(p[1]) == IDGroupType: - self.parents.append(self.group) - self.group = p[1] - self.active_item = -1 - Draw.Draw() - elif type(p[1]) == IDArrayType: - self.array = IDArrayBrowser() - self.array.array = p[1] - self.array.parentbrowser = self - self.state = State_InArray - Draw.Draw() - - if evt == Draw.TKEY and val == 1: - try: - self.prop['float'] = 0.0 - self.prop['int'] = 1 - self.prop['string'] = "hi!" - self.prop['float array'] = [0, 0, 1.0, 0] - self.prop['int array'] = [0, 0, 0, 0] - self.prop.data['a subgroup'] = {"int": 0, "float": 0.0, "anothergroup": {"a": 0.0, "intarr": [0, 0, 0, 0]}} - Draw.Draw() - except: - Draw.PupMenu("Can only do T once per block, the test names are already taken!") - - - def Button(self, bval): - global IDTypeModules - if self.state == State_InArray: - self.array.Button(bval) - return - - if bval == Button_MatMenu: - global IDTypeModules - - val = self.idindex = self.menubut.val - 1 - i = self.IDList - block = IDTypeModules[i][0].Get()[val] - self.idblock = block - self.prop = block.properties - self.group = self.prop - self.active_item = -1 - self.parents = [] - Draw.Draw() - - if bval == Button_TypeMenu: - i = IDTypeModules[self.idmenu.val-1] - if len(i[0].Get()) == 0: - Draw.PupMenu("Error%t|There are no " + i[2] + "!") - return - - IDTypeModules[self.IDList][1] = self.idindex - self.IDList = self.idmenu.val-1 - val = self.idindex = IDTypeModules[self.IDList][1] - i = self.IDList - block = IDTypeModules[i][0].Get()[val] - self.idblock = block - self.prop = block.properties - self.group = self.prop - self.active_item = -1 - self.parents = [] - Draw.Draw() - - if bval >= ButDelStart: - plist = [p for p in self.group] - prop = plist[bval - ButDelStart] - del self.group[prop] - Draw.Draw() - - elif bval >= ButStart: - plist = list(self.group.iteritems()) - - prop = plist[bval - ButStart] - print prop - - if self.type(prop[1]) == str: - self.group[prop[0]] = self.buts[bval - ButStart].val - elif self.type(prop[1]) == int: - i = self.buts[bval - ButStart].val - try: - i = int(i) - self.group[prop[0]] = i - except: - Draw.Draw() - return - Draw.Draw() - elif self.type(prop[1]) == float: - f = self.buts[bval - ButStart].val - try: - f = float(f) - self.group[prop[0]] = f - except: - Draw.Draw() - return - Draw.Draw() - - elif bval == Button_Back: - self.group = self.parents[len(self.parents)-1] - self.parents.pop(len(self.parents)-1) - Draw.Draw() - - elif bval == Button_New: - name = Draw.Create("untitled") - stype = Draw.Create(0) - gtype = Draw.Create(0) - ftype = Draw.Create(0) - itype = Draw.Create(0) - atype = Draw.Create(0) - - block = [] - block.append(("Name: ", name, 0, 30, "Click to type in the name of the new ID property")) - block.append("Type") - block.append(("String", stype)) - block.append(("Subgroup", gtype)) - block.append(("Float", ftype)) - block.append(("Int", itype)) - block.append(("Array", atype)) - - retval = Blender.Draw.PupBlock("New IDProperty", block) - if retval == 0: return - - name = name.val - i = 1 - stop = 0 - while stop == 0: - stop = 1 - for p in self.group: - if p == name: - d = name.rfind(".") - if d != -1: - name = name[:d] - name = name + "." + str(i).zfill(3) - i += 1 - stop = 0 - - type = "String" - if stype.val: - self.group[name] = "" - elif gtype.val: - self.group[name] = {} - elif ftype.val: - self.group[name] = 0.0 - elif itype.val: - self.group[name] = 0 #newProperty("Int", name, 0) - elif atype.val: - arrfloat = Draw.Create(1) - arrint = Draw.Create(0) - arrlen = Draw.Create(3) - block = [] - block.append("Type") - block.append(("Float", arrfloat, "Make a float array")) - block.append(("Int", arrint, "Make an integer array")) - block.append(("Len", arrlen, 2, 200)) - - if Blender.Draw.PupBlock("Array Properties", block): - if arrfloat.val: - tmpl = 0.0 - elif arrint.val: - tmpl = 0 - else: - return - - self.group[name] = [tmpl] * arrlen.val - - - def Go(self): - Draw.Register(self.Draw, self.EventIn, self.Button) - -scenes = Scene.Get() - -size = Window.GetAreaSize() -browser = IDPropertyBrowser(scenes[0].properties, scenes[0], 2, 2, size[0], size[1]) -browser.Go() - -#a = prop.newProperty("String", "hwello!", "bleh") -#b = prop.newProperty("Group", "subgroup") - -#for p in prop: - #print p.name diff --git a/release/scripts/ac3d_export.py b/release/scripts/ac3d_export.py deleted file mode 100644 index 57f27c7e3a2..00000000000 --- a/release/scripts/ac3d_export.py +++ /dev/null @@ -1,828 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: -Name: 'AC3D (.ac)...' -Blender: 243 -Group: 'Export' -Tip: 'Export selected meshes to AC3D (.ac) format' -""" - -__author__ = "Willian P. Germano" -__url__ = ("blender", "blenderartists.org", "AC3D's homepage, http://www.ac3d.org", - "PLib 3d gaming lib, http://plib.sf.net") -__version__ = "2.44 2007-05-05" - -__bpydoc__ = """\ -This script exports selected Blender meshes to AC3D's .ac file format. - -AC3D is a simple commercial 3d modeller also built with OpenGL. -The .ac file format is an easy to parse text format well supported, -for example, by the PLib 3d gaming library (AC3D 3.x). - -Supported:
- UV-textured meshes with hierarchy (grouping) information. - -Missing:
- The 'url' tag, specific to AC3D. It is easy to add by hand to the exported -file, if needed. - -Known issues:
- The ambient and emit data we can retrieve from Blender are single values, -that this script copies to R, G, B, giving shades of gray.
- Loose edges (lines) receive the first material found in the mesh, if any, or a default white material.
- In AC3D 4 "compatibility mode":
- - shininess of materials is taken from the shader specularity value in Blender, mapped from [0.0, 2.0] to [0, 128];
- - crease angle is exported, but in Blender it is limited to [1, 80], since there are other more powerful ways to control surface smoothing. In AC3D 4.0 crease's range is [0.0, 180.0]; - -Config Options:
- toggle:
- - AC3D 4 mode: unset it to export without the 'crease' tag that was -introduced with AC3D 4.0 and with the old material handling;
- - global coords: transform all vertices of all meshes to global coordinates;
- - skip data: set it if you don't want mesh names (ME:, not OB: field) -to be exported as strings for AC's "data" tags (19 chars max);
- - rgb mirror color can be exported as ambient and/or emissive if needed, -since Blender handles these differently;
- - default mat: a default (white) material is added if some mesh was -left without mats -- it's better to always add your own materials;
- - no split: don't split meshes (see above);
- - set texture dir: override the actual textures path with a given default -path (or simply export the texture names, without dir info, if the path is -empty);
- - per face 1 or 2 sided: override the "Double Sided" button that defines this behavior per whole mesh in favor of the UV Face Select mode "twosided" per face atribute;
- - only selected: only consider selected objects when looking for meshes -to export (read notes below about tokens, too);
- strings:
- - export dir: default dir to export to;
- - texture dir: override textures path with this path if 'set texture dir' -toggle is "on". - -Notes:
- This version updates:
- - modified meshes are correctly exported, no need to apply the modifiers in Blender;
- - correctly export each used material, be it assigned to the object or to its mesh data;
- - exporting lines (edges) is again supported; color comes from first material found in the mesh, if any, or a default white one.
- - there's a new option to choose between exporting meshes with transformed (global) coordinates or local ones;
- Multiple textures per mesh are supported (mesh gets split);
- Parents are exported as a group containing both the parent and its children;
- Start mesh object names (OB: field) with "!" or "#" if you don't want them to be exported;
- Start mesh object names (OB: field) with "=" or "$" to prevent them from being split (meshes with multiple textures or both textured and non textured faces are split unless this trick is used or the "no split" option is set. -""" - -# $Id$ -# -# -------------------------------------------------------------------------- -# AC3DExport version 2.44 -# Program versions: Blender 2.42+ and AC3Db files (means version 0xb) -# new: updated for new Blender version and Mesh module; supports lines (edges) again; -# option to export vertices transformed to global coordinates or not; now the modified -# (by existing mesh modifiers) mesh is exported; materials are properly exported, no -# matter if each of them is linked to the mesh or to the object. New (2.43.1): loose -# edges use color of first material found in the mesh, if any. -# -------------------------------------------------------------------------- -# Thanks: Steve Baker for discussions and inspiration; for testing, bug -# reports, suggestions, patches: David Megginson, Filippo di Natale, -# Franz Melchior, Campbell Barton, Josh Babcock, Ralf Gerlich, Stewart Andreason. -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004-2007: Willian P. Germano, wgermano _at_ ig.com.br -# -# 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, -# -------------------------------------------------------------------------- - -import Blender -from Blender import Object, Mesh, Material, Image, Mathutils, Registry -from Blender import sys as bsys - -# Globals -REPORT_DATA = { - 'main': [], - 'errors': [], - 'warns': [], - 'nosplit': [], - 'noexport': [] -} -TOKENS_DONT_EXPORT = ['!', '#'] -TOKENS_DONT_SPLIT = ['=', '$'] - -MATIDX_ERROR = 0 - -# flags: -LOOSE = Mesh.EdgeFlags['LOOSE'] -FACE_TWOSIDED = Mesh.FaceModes['TWOSIDE'] -MESH_TWOSIDED = Mesh.Modes['TWOSIDED'] - -REG_KEY = 'ac3d_export' - -# config options: -GLOBAL_COORDS = True -SKIP_DATA = False -MIRCOL_AS_AMB = False -MIRCOL_AS_EMIS = False -ADD_DEFAULT_MAT = True -SET_TEX_DIR = True -TEX_DIR = '' -AC3D_4 = True # export crease value, compatible with AC3D 4 loaders -NO_SPLIT = False -ONLY_SELECTED = True -EXPORT_DIR = '' -PER_FACE_1_OR_2_SIDED = True - -tooltips = { - 'GLOBAL_COORDS': "transform all vertices of all meshes to global coordinates", - 'SKIP_DATA': "don't export mesh names as data fields", - 'MIRCOL_AS_AMB': "export mirror color as ambient color", - 'MIRCOL_AS_EMIS': "export mirror color as emissive color", - 'ADD_DEFAULT_MAT': "always add a default white material", - 'SET_TEX_DIR': "don't export default texture paths (edit also \"tex dir\")", - 'EXPORT_DIR': "default / last folder used to export .ac files to", - 'TEX_DIR': "(see \"set tex dir\") dir to prepend to all exported texture names (leave empty for no dir)", - 'AC3D_4': "compatibility mode, adds 'crease' tag and slightly better material support", - 'NO_SPLIT': "don't split meshes with multiple textures (or both textured and non textured polygons)", - 'ONLY_SELECTED': "export only selected objects", - 'PER_FACE_1_OR_2_SIDED': "override \"Double Sided\" button in favor of per face \"twosided\" attribute (UV Face Select mode)" -} - -def update_RegistryInfo(): - d = {} - d['SKIP_DATA'] = SKIP_DATA - d['MIRCOL_AS_AMB'] = MIRCOL_AS_AMB - d['MIRCOL_AS_EMIS'] = MIRCOL_AS_EMIS - d['ADD_DEFAULT_MAT'] = ADD_DEFAULT_MAT - d['SET_TEX_DIR'] = SET_TEX_DIR - d['TEX_DIR'] = TEX_DIR - d['AC3D_4'] = AC3D_4 - d['NO_SPLIT'] = NO_SPLIT - d['EXPORT_DIR'] = EXPORT_DIR - d['ONLY_SELECTED'] = ONLY_SELECTED - d['PER_FACE_1_OR_2_SIDED'] = PER_FACE_1_OR_2_SIDED - d['tooltips'] = tooltips - d['GLOBAL_COORDS'] = GLOBAL_COORDS - Registry.SetKey(REG_KEY, d, True) - -# Looking for a saved key in Blender.Registry dict: -rd = Registry.GetKey(REG_KEY, True) - -if rd: - try: - AC3D_4 = rd['AC3D_4'] - SKIP_DATA = rd['SKIP_DATA'] - MIRCOL_AS_AMB = rd['MIRCOL_AS_AMB'] - MIRCOL_AS_EMIS = rd['MIRCOL_AS_EMIS'] - ADD_DEFAULT_MAT = rd['ADD_DEFAULT_MAT'] - SET_TEX_DIR = rd['SET_TEX_DIR'] - TEX_DIR = rd['TEX_DIR'] - EXPORT_DIR = rd['EXPORT_DIR'] - ONLY_SELECTED = rd['ONLY_SELECTED'] - NO_SPLIT = rd['NO_SPLIT'] - PER_FACE_1_OR_2_SIDED = rd['PER_FACE_1_OR_2_SIDED'] - GLOBAL_COORDS = rd['GLOBAL_COORDS'] - except KeyError: update_RegistryInfo() - -else: - update_RegistryInfo() - -VERBOSE = True -CONFIRM_OVERWRITE = True - -# check General scripts config key for default behaviors -rd = Registry.GetKey('General', True) -if rd: - try: - VERBOSE = rd['verbose'] - CONFIRM_OVERWRITE = rd['confirm_overwrite'] - except: pass - - -# The default material to be used when necessary (see ADD_DEFAULT_MAT) -DEFAULT_MAT = \ -'MATERIAL "DefaultWhite" rgb 1 1 1 amb 1 1 1 emis 0 0 0 \ -spec 0.5 0.5 0.5 shi 64 trans 0' - -# This transformation aligns Blender and AC3D coordinate systems: -BLEND_TO_AC3D_MATRIX = Mathutils.Matrix([1,0,0,0], [0,0,-1,0], [0,1,0,0], [0,0,0,1]) - -def Round_s(f): - "Round to default precision and turn value to a string" - r = round(f,6) # precision set to 10e-06 - if r == int(r): - return str(int(r)) - else: - return str(r) - -def transform_verts(verts, m): - vecs = [] - for v in verts: - x, y, z = v.co - vec = Mathutils.Vector([x, y, z, 1]) - vecs.append(vec*m) - return vecs - -def get_loose_edges(mesh): - loose = LOOSE - return [e for e in mesh.edges if e.flag & loose] - -# --- - -# meshes with more than one texture assigned -# are split and saved as these foomeshes -class FooMesh: - - class FooVert: - def __init__(self, v): - self.v = v - self.index = 0 - - class FooFace: - def __init__(self, foomesh, f): - self.f = f - foov = foomesh.FooVert - self.v = [foov(f.v[0]), foov(f.v[1])] - len_fv = len(f.v) - if len_fv > 2 and f.v[2]: - self.v.append(foov(f.v[2])) - if len_fv > 3 and f.v[3]: self.v.append(foov(f.v[3])) - - def __getattr__(self, attr): - if attr == 'v': return self.v - return getattr(self.f, attr) - - def __len__(self): - return len(self.f) - - def __init__(self, tex, faces, mesh): - self.name = mesh.name - self.mesh = mesh - self.looseEdges = [] - self.faceUV = mesh.faceUV - self.degr = mesh.degr - vidxs = [0]*len(mesh.verts) - foofaces = [] - for f in faces: - foofaces.append(self.FooFace(self, f)) - for v in f.v: - if v: vidxs[v.index] = 1 - i = 0 - fooverts = [] - for v in mesh.verts: - if vidxs[v.index]: - fooverts.append(v) - vidxs[v.index] = i - i += 1 - for f in foofaces: - for v in f.v: - if v: v.index = vidxs[v.v.index] - self.faces = foofaces - self.verts = fooverts - - -class AC3DExport: # the ac3d exporter part - - def __init__(self, scene_objects, file): - - global ARG, SKIP_DATA, ADD_DEFAULT_MAT, DEFAULT_MAT - - header = 'AC3Db' - self.file = file - self.buf = '' - self.mbuf = [] - self.mlist = [] - world_kids = 0 - parents_list = self.parents_list = [] - kids_dict = self.kids_dict = {} - objs = [] - exp_objs = self.exp_objs = [] - tree = {} - - file.write(header+'\n') - - objs = \ - [o for o in scene_objects if o.type in ['Mesh', 'Empty']] - - # create a tree from parents to children objects - - for obj in objs[:]: - parent = obj.parent - lineage = [obj] - - while parent: - parents_list.append(parent.name) - obj = parent - parent = parent.getParent() - lineage.insert(0, obj) - - d = tree - for i in xrange(len(lineage)): - lname = lineage[i].getType()[:2] + lineage[i].name - if lname not in d.keys(): - d[lname] = {} - d = d[lname] - - # traverse the tree to get an ordered list of names of objects to export - self.traverse_dict(tree) - - world_kids = len(tree.keys()) - - # get list of objects to export, start writing the .ac file - - objlist = [Object.Get(name) for name in exp_objs] - - meshlist = [o for o in objlist if o.type == 'Mesh'] - - # create a temporary mesh to hold actual (modified) mesh data - TMP_mesh = Mesh.New('tmp_for_ac_export') - - # write materials - - self.MATERIALS(meshlist, TMP_mesh) - mbuf = self.mbuf - if not mbuf or ADD_DEFAULT_MAT: - mbuf.insert(0, "%s\n" % DEFAULT_MAT) - mbuf = "".join(mbuf) - file.write(mbuf) - - file.write('OBJECT world\nkids %s\n' % world_kids) - - # write the objects - - for obj in objlist: - self.obj = obj - - objtype = obj.type - objname = obj.name - kidsnum = kids_dict[objname] - - # A parent plus its children are exported as a group. - # If the parent is a mesh, its rot and loc are exported as the - # group rot and loc and the mesh (w/o rot and loc) is added to the group. - if kidsnum: - self.OBJECT('group') - self.name(objname) - if objtype == 'Mesh': - kidsnum += 1 - if not GLOBAL_COORDS: - localmatrix = obj.getMatrix('localspace') - if not obj.getParent(): - localmatrix *= BLEND_TO_AC3D_MATRIX - self.rot(localmatrix.rotationPart()) - self.loc(localmatrix.translationPart()) - self.kids(kidsnum) - - if objtype == 'Mesh': - mesh = TMP_mesh # temporary mesh to hold actual (modified) mesh data - mesh.getFromObject(objname) - self.mesh = mesh - if mesh.faceUV: - meshes = self.split_mesh(mesh) - else: - meshes = [mesh] - if len(meshes) > 1: - if NO_SPLIT or self.dont_split(objname): - self.export_mesh(mesh, ob) - REPORT_DATA['nosplit'].append(objname) - else: - self.OBJECT('group') - self.name(objname) - self.kids(len(meshes)) - counter = 0 - for me in meshes: - self.export_mesh(me, obj, - name = '%s_%s' % (obj.name, counter), foomesh = True) - self.kids() - counter += 1 - else: - self.export_mesh(mesh, obj) - self.kids() - - - def traverse_dict(self, d): - kids_dict = self.kids_dict - exp_objs = self.exp_objs - keys = d.keys() - keys.sort() # sort for predictable output - keys.reverse() - for k in keys: - objname = k[2:] - klen = len(d[k]) - kids_dict[objname] = klen - if self.dont_export(objname): - d.pop(k) - parent = Object.Get(objname).getParent() - if parent: kids_dict[parent.name] -= 1 - REPORT_DATA['noexport'].append(objname) - continue - if klen: - self.traverse_dict(d[k]) - exp_objs.insert(0, objname) - else: - if k.find('Em', 0) == 0: # Empty w/o children - d.pop(k) - parent = Object.Get(objname).getParent() - if parent: kids_dict[parent.name] -= 1 - else: - exp_objs.insert(0, objname) - - def dont_export(self, name): # if name starts with '!' or '#' - length = len(name) - if length >= 1: - if name[0] in TOKENS_DONT_EXPORT: # '!' or '#' doubled (escaped): export - if length > 1 and name[1] == name[0]: - return 0 - return 1 - - def dont_split(self, name): # if name starts with '=' or '$' - length = len(name) - if length >= 1: - if name[0] in TOKENS_DONT_SPLIT: # '=' or '$' doubled (escaped): split - if length > 1 and name[1] == name[0]: - return 0 - return 1 - - def split_mesh(self, mesh): - tex_dict = {0:[]} - for f in mesh.faces: - if f.image: - if not f.image.name in tex_dict: tex_dict[f.image.name] = [] - tex_dict[f.image.name].append(f) - else: tex_dict[0].append(f) - keys = tex_dict.keys() - len_keys = len(keys) - if not tex_dict[0]: - len_keys -= 1 - tex_dict.pop(0) - keys.remove(0) - elif len_keys > 1: - lines = [] - anyimgkey = [k for k in keys if k != 0][0] - for f in tex_dict[0]: - if len(f.v) < 3: - lines.append(f) - if len(tex_dict[0]) == len(lines): - for l in lines: - tex_dict[anyimgkey].append(l) - len_keys -= 1 - tex_dict.pop(0) - if len_keys > 1: - foo_meshes = [] - for k in keys: - faces = tex_dict[k] - foo_meshes.append(FooMesh(k, faces, mesh)) - foo_meshes[0].edges = get_loose_edges(mesh) - return foo_meshes - return [mesh] - - def export_mesh(self, mesh, obj, name = None, foomesh = False): - file = self.file - self.OBJECT('poly') - if not name: name = obj.name - self.name(name) - if not SKIP_DATA: - meshname = obj.getData(name_only = True) - self.data(len(meshname), meshname) - if mesh.faceUV: - texline = self.texture(mesh.faces) - if texline: file.write(texline) - if AC3D_4: - self.crease(mesh.degr) - - # If exporting using local coordinates, children object coordinates should not be - # transformed to ac3d's coordinate system, since that will be accounted for in - # their topmost parents (the parents w/o parents) transformations. - if not GLOBAL_COORDS: - # We hold parents in a list, so they also don't get transformed, - # because for each parent we create an ac3d group to hold both the - # parent and its children. - if obj.name not in self.parents_list: - localmatrix = obj.getMatrix('localspace') - if not obj.getParent(): - localmatrix *= BLEND_TO_AC3D_MATRIX - self.rot(localmatrix.rotationPart()) - self.loc(localmatrix.translationPart()) - matrix = None - else: - matrix = obj.getMatrix() * BLEND_TO_AC3D_MATRIX - - self.numvert(mesh.verts, matrix) - self.numsurf(mesh, foomesh) - - def MATERIALS(self, meshlist, me): - for meobj in meshlist: - me.getFromObject(meobj) - mats = me.materials - mbuf = [] - mlist = self.mlist - for m in mats: - if not m: continue - name = m.name - if name not in mlist: - mlist.append(name) - M = Material.Get(name) - material = 'MATERIAL "%s"' % name - mirCol = "%s %s %s" % (Round_s(M.mirCol[0]), Round_s(M.mirCol[1]), - Round_s(M.mirCol[2])) - rgb = "rgb %s %s %s" % (Round_s(M.R), Round_s(M.G), Round_s(M.B)) - ambval = Round_s(M.amb) - amb = "amb %s %s %s" % (ambval, ambval, ambval) - spec = "spec %s %s %s" % (Round_s(M.specCol[0]), - Round_s(M.specCol[1]), Round_s(M.specCol[2])) - if AC3D_4: - emit = Round_s(M.emit) - emis = "emis %s %s %s" % (emit, emit, emit) - shival = int(M.spec * 64) - else: - emis = "emis 0 0 0" - shival = 72 - shi = "shi %s" % shival - trans = "trans %s" % (Round_s(1 - M.alpha)) - if MIRCOL_AS_AMB: - amb = "amb %s" % mirCol - if MIRCOL_AS_EMIS: - emis = "emis %s" % mirCol - mbuf.append("%s %s %s %s %s %s %s\n" \ - % (material, rgb, amb, emis, spec, shi, trans)) - self.mlist = mlist - self.mbuf.append("".join(mbuf)) - - def OBJECT(self, type): - self.file.write('OBJECT %s\n' % type) - - def name(self, name): - if name[0] in TOKENS_DONT_EXPORT or name[0] in TOKENS_DONT_SPLIT: - if len(name) > 1: name = name[1:] - self.file.write('name "%s"\n' % name) - - def kids(self, num = 0): - self.file.write('kids %s\n' % num) - - def data(self, num, str): - self.file.write('data %s\n%s\n' % (num, str)) - - def texture(self, faces): - tex = "" - for f in faces: - if f.image: - tex = f.image.name - break - if tex: - image = Image.Get(tex) - texfname = image.filename - if SET_TEX_DIR: - texfname = bsys.basename(texfname) - if TEX_DIR: - texfname = bsys.join(TEX_DIR, texfname) - buf = 'texture "%s"\n' % texfname - xrep = image.xrep - yrep = image.yrep - buf += 'texrep %s %s\n' % (xrep, yrep) - self.file.write(buf) - - def rot(self, matrix): - rot = '' - not_I = 0 # not identity - matstr = [] - for i in [0, 1, 2]: - r = map(Round_s, matrix[i]) - not_I += (r[0] != '0')+(r[1] != '0')+(r[2] != '0') - not_I -= (r[i] == '1') - for j in [0, 1, 2]: - matstr.append(' %s' % r[j]) - if not_I: # no need to write identity - self.file.write('rot%s\n' % "".join(matstr)) - - def loc(self, loc): - loc = map(Round_s, loc) - if loc != ['0', '0', '0']: # no need to write default - self.file.write('loc %s %s %s\n' % (loc[0], loc[1], loc[2])) - - def crease(self, crease): - self.file.write('crease %f\n' % crease) - - def numvert(self, verts, matrix): - file = self.file - nvstr = [] - nvstr.append("numvert %s\n" % len(verts)) - - if matrix: - verts = transform_verts(verts, matrix) - for v in verts: - v = map (Round_s, v) - nvstr.append("%s %s %s\n" % (v[0], v[1], v[2])) - else: - for v in verts: - v = map(Round_s, v.co) - nvstr.append("%s %s %s\n" % (v[0], v[1], v[2])) - - file.write("".join(nvstr)) - - def numsurf(self, mesh, foomesh = False): - - global MATIDX_ERROR - - # local vars are faster and so better in tight loops - lc_ADD_DEFAULT_MAT = ADD_DEFAULT_MAT - lc_MATIDX_ERROR = MATIDX_ERROR - lc_PER_FACE_1_OR_2_SIDED = PER_FACE_1_OR_2_SIDED - lc_FACE_TWOSIDED = FACE_TWOSIDED - lc_MESH_TWOSIDED = MESH_TWOSIDED - - faces = mesh.faces - hasFaceUV = mesh.faceUV - if foomesh: - looseEdges = mesh.looseEdges - else: - looseEdges = get_loose_edges(mesh) - - file = self.file - - file.write("numsurf %s\n" % (len(faces) + len(looseEdges))) - - if not foomesh: verts = list(self.mesh.verts) - - materials = self.mesh.materials - mlist = self.mlist - matidx_error_reported = False - objmats = [] - for omat in materials: - if omat: objmats.append(omat.name) - else: objmats.append(None) - for f in faces: - if not objmats: - m_idx = 0 - elif objmats[f.mat] in mlist: - m_idx = mlist.index(objmats[f.mat]) - else: - if not lc_MATIDX_ERROR: - rdat = REPORT_DATA['warns'] - rdat.append("Object %s" % self.obj.name) - rdat.append("has at least one material *index* assigned but not") - rdat.append("defined (not linked to an existing material).") - rdat.append("Result: some faces may be exported with a wrong color.") - rdat.append("You can assign materials in the Edit Buttons window (F9).") - elif not matidx_error_reported: - midxmsg = "- Same for object %s." % self.obj.name - REPORT_DATA['warns'].append(midxmsg) - lc_MATIDX_ERROR += 1 - matidx_error_reported = True - m_idx = 0 - if lc_ADD_DEFAULT_MAT: m_idx -= 1 - refs = len(f) - flaglow = 0 # polygon - if lc_PER_FACE_1_OR_2_SIDED and hasFaceUV: # per face attribute - two_side = f.mode & lc_FACE_TWOSIDED - else: # global, for the whole mesh - two_side = self.mesh.mode & lc_MESH_TWOSIDED - two_side = (two_side > 0) << 1 - flaghigh = f.smooth | two_side - surfstr = "SURF 0x%d%d\n" % (flaghigh, flaglow) - if lc_ADD_DEFAULT_MAT and objmats: m_idx += 1 - matstr = "mat %s\n" % m_idx - refstr = "refs %s\n" % refs - u, v, vi = 0, 0, 0 - fvstr = [] - if foomesh: - for vert in f.v: - fvstr.append(str(vert.index)) - if hasFaceUV: - u = f.uv[vi][0] - v = f.uv[vi][1] - vi += 1 - fvstr.append(" %s %s\n" % (u, v)) - else: - for vert in f.v: - fvstr.append(str(verts.index(vert))) - if hasFaceUV: - u = f.uv[vi][0] - v = f.uv[vi][1] - vi += 1 - fvstr.append(" %s %s\n" % (u, v)) - - fvstr = "".join(fvstr) - - file.write("%s%s%s%s" % (surfstr, matstr, refstr, fvstr)) - - # material for loose edges - edges_mat = 0 # default to first material - for omat in objmats: # but look for a material from this mesh - if omat in mlist: - edges_mat = mlist.index(omat) - if lc_ADD_DEFAULT_MAT: edges_mat += 1 - break - - for e in looseEdges: - fvstr = [] - #flaglow = 2 # 1 = closed line, 2 = line - #flaghigh = 0 - #surfstr = "SURF 0x%d%d\n" % (flaghigh, flaglow) - surfstr = "SURF 0x02\n" - - fvstr.append("%d 0 0\n" % verts.index(e.v1)) - fvstr.append("%d 0 0\n" % verts.index(e.v2)) - fvstr = "".join(fvstr) - - matstr = "mat %d\n" % edges_mat # for now, use first material - refstr = "refs 2\n" # 2 verts - - file.write("%s%s%s%s" % (surfstr, matstr, refstr, fvstr)) - - MATIDX_ERROR = lc_MATIDX_ERROR - -# End of Class AC3DExport - -from Blender.Window import FileSelector - -def report_data(): - global VERBOSE - - if not VERBOSE: return - - d = REPORT_DATA - msgs = { - '0main': '%s\nExporting meshes to AC3D format' % str(19*'-'), - '1warns': 'Warnings', - '2errors': 'Errors', - '3nosplit': 'Not split (because name starts with "=" or "$")', - '4noexport': 'Not exported (because name starts with "!" or "#")' - } - if NO_SPLIT: - l = msgs['3nosplit'] - l = "%s (because OPTION NO_SPLIT is set)" % l.split('(')[0] - msgs['3nosplit'] = l - keys = msgs.keys() - keys.sort() - for k in keys: - msgk = msgs[k] - msg = '\n'.join(d[k[1:]]) - if msg: - print '\n-%s:' % msgk - print msg - -# File Selector callback: -def fs_callback(filename): - global EXPORT_DIR, OBJS, CONFIRM_OVERWRITE, VERBOSE - - if not filename.endswith('.ac'): filename = '%s.ac' % filename - - if bsys.exists(filename) and CONFIRM_OVERWRITE: - if Blender.Draw.PupMenu('OVERWRITE?%t|File exists') != 1: - return - - Blender.Window.WaitCursor(1) - starttime = bsys.time() - - export_dir = bsys.dirname(filename) - if export_dir != EXPORT_DIR: - EXPORT_DIR = export_dir - update_RegistryInfo() - - try: - file = open(filename, 'w') - except IOError, (errno, strerror): - error = "IOError #%s: %s" % (errno, strerror) - REPORT_DATA['errors'].append("Saving failed - %s." % error) - error_msg = "Couldn't save file!%%t|%s" % error - Blender.Draw.PupMenu(error_msg) - return - - try: - test = AC3DExport(OBJS, file) - except: - file.close() - raise - else: - file.close() - endtime = bsys.time() - starttime - REPORT_DATA['main'].append("Done. Saved to: %s" % filename) - REPORT_DATA['main'].append("Data exported in %.3f seconds." % endtime) - - if VERBOSE: report_data() - Blender.Window.WaitCursor(0) - - -# -- End of definitions - -scn = Blender.Scene.GetCurrent() - -if ONLY_SELECTED: - OBJS = list(scn.objects.context) -else: - OBJS = list(scn.objects) - -if not OBJS: - Blender.Draw.PupMenu('ERROR: no objects selected') -else: - fname = bsys.makename(ext=".ac") - if EXPORT_DIR: - fname = bsys.join(EXPORT_DIR, bsys.basename(fname)) - FileSelector(fs_callback, "Export AC3D", fname) diff --git a/release/scripts/ac3d_import.py b/release/scripts/ac3d_import.py deleted file mode 100644 index 2f5512e7150..00000000000 --- a/release/scripts/ac3d_import.py +++ /dev/null @@ -1,783 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: -Name: 'AC3D (.ac)...' -Blender: 243 -Group: 'Import' -Tip: 'Import an AC3D (.ac) file.' -""" - -__author__ = "Willian P. Germano" -__url__ = ("blender", "blenderartists.org", "AC3D's homepage, http://www.ac3d.org", - "PLib 3d gaming lib, http://plib.sf.net") -__version__ = "2.48.1 2009-01-11" - -__bpydoc__ = """\ -This script imports AC3D models into Blender. - -AC3D is a simple and affordable commercial 3d modeller also built with OpenGL. -The .ac file format is an easy to parse text format well supported, -for example, by the PLib 3d gaming library. - -Supported:
- UV-textured meshes with hierarchy (grouping) information. - -Missing:
- The url tag is irrelevant for Blender. - -Known issues:
- - Some objects may be imported with wrong normals due to wrong information in the model itself. This can be noticed by strange shading, like darker than expected parts in the model. To fix this, select the mesh with wrong normals, enter edit mode and tell Blender to recalculate the normals, either to make them point outside (the usual case) or inside.
- -Config Options:
- - display transp (toggle): if "on", objects that have materials with alpha < 1.0 are shown with translucency (transparency) in the 3D View.
- - subdiv (toggle): if "on", ac3d objects meant to be subdivided receive a SUBSURF modifier in Blender.
- - emis as mircol: store the emissive rgb color from AC3D as mirror color in Blender -- this is a hack to preserve the values and be able to export them using the equivalent option in the exporter.
- - textures dir (string): if non blank, when imported texture paths are -wrong in the .ac file, Blender will also look for them at this dir. - -Notes:
- - When looking for assigned textures, Blender tries in order: the actual -paths from the .ac file, the .ac file's dir and the default textures dir path -users can configure (see config options above). -""" - -# $Id$ -# -# -------------------------------------------------------------------------- -# AC3DImport version 2.43.1 Feb 21, 2007 -# Program versions: Blender 2.43 and AC3Db files (means version 0xb) -# changed: better triangulation of ngons, more fixes to support bad .ac files, -# option to display transp mats in 3d view, support "subdiv" tag (via SUBSURF modifier) -# -------------------------------------------------------------------------- -# Thanks: Melchior Franz for extensive bug testing and reporting, making this -# version cope much better with old or bad .ac files, among other improvements; -# Stewart Andreason for reporting a serious crash; Francesco Brisa for the -# emis as mircol functionality (w/ patch). -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004-2009: Willian P. Germano, wgermano _at_ ig.com.br -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from math import radians - -import Blender -from Blender import Scene, Object, Mesh, Lamp, Registry, sys as bsys, Window, Image, Material, Modifier -from Blender.sys import dirsep -from Blender.Mathutils import Vector, Matrix, Euler -from Blender.Geometry import PolyFill - -# Default folder for AC3D textures, to override wrong paths, change to your -# liking or leave as "": -TEXTURES_DIR = "" - -DISPLAY_TRANSP = True - -SUBDIV = True - -EMIS_AS_MIRCOL = False - - -tooltips = { - 'DISPLAY_TRANSP': 'Turn transparency on in the 3d View for objects using materials with alpha < 1.0.', - 'SUBDIV': 'Apply a SUBSURF modifier to objects meant to appear subdivided.', - 'TEXTURES_DIR': 'Additional folder to look for missing textures.', - 'EMIS_AS_MIRCOL': 'Store emis color as mirror color in Blender.' -} - -def update_registry(): - global TEXTURES_DIR, DISPLAY_TRANSP, EMIS_AS_MIRCOL - rd = dict([('tooltips', tooltips), ('TEXTURES_DIR', TEXTURES_DIR), ('DISPLAY_TRANSP', DISPLAY_TRANSP), ('SUBDIV', SUBDIV), ('EMIS_AS_MIRCOL', EMIS_AS_MIRCOL)]) - Registry.SetKey('ac3d_import', rd, True) - -rd = Registry.GetKey('ac3d_import', True) - -if rd: - if 'GROUP' in rd: - update_registry() - try: - TEXTURES_DIR = rd['TEXTURES_DIR'] - DISPLAY_TRANSP = rd['DISPLAY_TRANSP'] - SUBDIV = rd['SUBDIV'] - EMIS_AS_MIRCOL = rd['EMIS_AS_MIRCOL'] - except: - update_registry() -else: update_registry() - -if TEXTURES_DIR: - oldtexdir = TEXTURES_DIR - if dirsep == '/': TEXTURES_DIR = TEXTURES_DIR.replace('\\', '/') - if TEXTURES_DIR[-1] != dirsep: TEXTURES_DIR = "%s%s" % (TEXTURES_DIR, dirsep) - if oldtexdir != TEXTURES_DIR: update_registry() - - -VERBOSE = True -rd = Registry.GetKey('General', True) -if rd: - if rd.has_key('verbose'): - VERBOSE = rd['verbose'] - - -errmsg = "" - -# Matrix to align ac3d's coordinate system with Blender's one, -# it's a -90 degrees rotation around the x axis: -AC_TO_BLEND_MATRIX = Matrix([1, 0, 0], [0, 0, 1], [0, -1, 0]) - -AC_WORLD = 0 -AC_GROUP = 1 -AC_POLY = 2 -AC_LIGHT = 3 -AC_OB_TYPES = { - 'world': AC_WORLD, - 'group': AC_GROUP, - 'poly': AC_POLY, - 'light': AC_LIGHT - } - -AC_OB_BAD_TYPES_LIST = [] # to hold references to unknown (wrong) ob types - -def inform(msg): - global VERBOSE - if VERBOSE: print msg - -def euler_in_radians(eul): - "Used while there's a bug in the BPY API" - eul.x = radians(eul.x) - eul.y = radians(eul.y) - eul.z = radians(eul.z) - return eul - -class Obj: - - def __init__(self, type): - self.type = type - self.dad = None - self.name = '' - self.data = '' - self.tex = '' - self.texrep = [1,1] - self.texoff = None - self.loc = [] - self.rot = [] - self.size = [] - self.crease = 30 - self.subdiv = 0 - self.vlist = [] - self.flist_cfg = [] - self.flist_v = [] - self.flist_uv = [] - self.elist = [] - self.matlist = [] - self.kids = 0 - - self.bl_obj = None # the actual Blender object created from this data - -class AC3DImport: - - def __init__(self, filename): - - global errmsg - - self.scene = Scene.GetCurrent() - - self.i = 0 - errmsg = '' - self.importdir = bsys.dirname(filename) - try: - file = open(filename, 'r') - except IOError, (errno, strerror): - errmsg = "IOError #%s: %s" % (errno, strerror) - Blender.Draw.PupMenu('ERROR: %s' % errmsg) - inform(errmsg) - return None - header = file.read(5) - header, version = header[:4], header[-1] - if header != 'AC3D': - file.close() - errmsg = 'AC3D header not found (invalid file)' - Blender.Draw.PupMenu('ERROR: %s' % errmsg) - inform(errmsg) - return None - elif version != 'b': - inform('AC3D file version 0x%s.' % version) - inform('This importer is for version 0xb, so it may fail.') - - self.token = {'OBJECT': self.parse_obj, - 'numvert': self.parse_vert, - 'numsurf': self.parse_surf, - 'name': self.parse_name, - 'data': self.parse_data, - 'kids': self.parse_kids, - 'loc': self.parse_loc, - 'rot': self.parse_rot, - 'MATERIAL': self.parse_mat, - 'texture': self.parse_tex, - 'texrep': self.parse_texrep, - 'texoff': self.parse_texoff, - 'subdiv': self.parse_subdiv, - 'crease': self.parse_crease} - - self.objlist = [] - self.mlist = [] - self.kidsnumlist = [] - self.dad = None - - self.lines = file.readlines() - self.lines.append('') - self.parse_file() - file.close() - - self.testAC3DImport() - - def parse_obj(self, value): - kidsnumlist = self.kidsnumlist - if kidsnumlist: - while not kidsnumlist[-1]: - kidsnumlist.pop() - if kidsnumlist: - self.dad = self.dad.dad - else: - inform('Ignoring unexpected data at end of file.') - return -1 # bad file with more objects than reported - kidsnumlist[-1] -= 1 - if value in AC_OB_TYPES: - new = Obj(AC_OB_TYPES[value]) - else: - if value not in AC_OB_BAD_TYPES_LIST: - AC_OB_BAD_TYPES_LIST.append(value) - inform('Unexpected object type keyword: "%s". Assuming it is of type: "poly".' % value) - new = Obj(AC_OB_TYPES['poly']) - new.dad = self.dad - new.name = value - self.objlist.append(new) - - def parse_kids(self, value): - kids = int(value) - if kids: - self.kidsnumlist.append(kids) - self.dad = self.objlist[-1] - self.objlist[-1].kids = kids - - def parse_name(self, value): - name = value.split('"')[1] - self.objlist[-1].name = name - - def parse_data(self, value): - data = self.lines[self.i].strip() - self.objlist[-1].data = data - - def parse_tex(self, value): - line = self.lines[self.i - 1] # parse again to properly get paths with spaces - texture = line.split('"')[1] - self.objlist[-1].tex = texture - - def parse_texrep(self, trash): - trep = self.lines[self.i - 1] - trep = trep.split() - trep = [float(trep[1]), float(trep[2])] - self.objlist[-1].texrep = trep - self.objlist[-1].texoff = [0, 0] - - def parse_texoff(self, trash): - toff = self.lines[self.i - 1] - toff = toff.split() - toff = [float(toff[1]), float(toff[2])] - self.objlist[-1].texoff = toff - - def parse_mat(self, value): - i = self.i - 1 - lines = self.lines - line = lines[i].split() - mat_name = '' - mat_col = mat_amb = mat_emit = mat_spec_col = mat_mir_col = [0,0,0] - mat_alpha = 1 - mat_spec = 1.0 - - while line[0] == 'MATERIAL': - mat_name = line[1].split('"')[1] - mat_col = map(float,[line[3],line[4],line[5]]) - v = map(float,[line[7],line[8],line[9]]) - mat_amb = (v[0]+v[1]+v[2]) / 3.0 - v = map(float,[line[11],line[12],line[13]]) - mat_emit = (v[0]+v[1]+v[2]) / 3.0 - if EMIS_AS_MIRCOL: - mat_emit = 0 - mat_mir_col = map(float,[line[11],line[12],line[13]]) - - mat_spec_col = map(float,[line[15],line[16],line[17]]) - mat_spec = float(line[19]) / 64.0 - mat_alpha = float(line[-1]) - mat_alpha = 1 - mat_alpha - self.mlist.append([mat_name, mat_col, mat_amb, mat_emit, mat_spec_col, mat_spec, mat_mir_col, mat_alpha]) - i += 1 - line = lines[i].split() - - self.i = i - - def parse_rot(self, trash): - i = self.i - 1 - ob = self.objlist[-1] - rot = self.lines[i].split(' ', 1)[1] - rot = map(float, rot.split()) - matrix = Matrix(rot[:3], rot[3:6], rot[6:]) - ob.rot = matrix - size = matrix.scalePart() # vector - ob.size = size - - def parse_loc(self, trash): - i = self.i - 1 - loc = self.lines[i].split(' ', 1)[1] - loc = map(float, loc.split()) - self.objlist[-1].loc = Vector(loc) - - def parse_crease(self, value): - # AC3D: range is [0.0, 180.0]; Blender: [1, 80] - value = float(value) - self.objlist[-1].crease = int(value) - - def parse_subdiv(self, value): - self.objlist[-1].subdiv = int(value) - - def parse_vert(self, value): - i = self.i - lines = self.lines - obj = self.objlist[-1] - vlist = obj.vlist - n = int(value) - - while n: - line = lines[i].split() - line = map(float, line) - vlist.append(line) - n -= 1 - i += 1 - - if vlist: # prepend a vertex at 1st position to deal with vindex 0 issues - vlist.insert(0, line) - - self.i = i - - def parse_surf(self, value): - i = self.i - is_smooth = 0 - double_sided = 0 - lines = self.lines - obj = self.objlist[-1] - vlist = obj.vlist - matlist = obj.matlist - numsurf = int(value) - NUMSURF = numsurf - - badface_notpoly = badface_multirefs = 0 - - while numsurf: - flags = lines[i].split()[1][2:] - if len(flags) > 1: - flaghigh = int(flags[0]) - flaglow = int(flags[1]) - else: - flaghigh = 0 - flaglow = int(flags[0]) - - is_smooth = flaghigh & 1 - twoside = flaghigh & 2 - nextline = lines[i+1].split() - if nextline[0] != 'mat': # the "mat" line may be missing (found in one buggy .ac file) - matid = 0 - if not matid in matlist: matlist.append(matid) - i += 2 - else: - matid = int(nextline[1]) - if not matid in matlist: matlist.append(matid) - nextline = lines[i+2].split() - i += 3 - refs = int(nextline[1]) - face = [] - faces = [] - edges = [] - fuv = [] - fuvs = [] - rfs = refs - - while rfs: - line = lines[i].split() - v = int(line[0]) + 1 # + 1 to avoid vindex == 0 - uv = [float(line[1]), float(line[2])] - face.append(v) - fuv.append(Vector(uv)) - rfs -= 1 - i += 1 - - if flaglow: # it's a line or closed line, not a polygon - while len(face) >= 2: - cut = face[:2] - edges.append(cut) - face = face[1:] - - if flaglow == 1 and edges: # closed line - face = [edges[-1][-1], edges[0][0]] - edges.append(face) - - else: # polygon - - # check for bad face, that references same vertex more than once - lenface = len(face) - if lenface < 3: - # less than 3 vertices, not a face - badface_notpoly += 1 - elif sum(map(face.count, face)) != lenface: - # multiple references to the same vertex - badface_multirefs += 1 - else: # ok, seems fine - if len(face) > 4: # ngon, triangulate it - polyline = [] - for vi in face: - polyline.append(Vector(vlist[vi])) - tris = PolyFill([polyline]) - for t in tris: - tri = [face[t[0]], face[t[1]], face[t[2]]] - triuvs = [fuv[t[0]], fuv[t[1]], fuv[t[2]]] - faces.append(tri) - fuvs.append(triuvs) - else: # tri or quad - faces.append(face) - fuvs.append(fuv) - - obj.flist_cfg.extend([[matid, is_smooth, twoside]] * len(faces)) - obj.flist_v.extend(faces) - obj.flist_uv.extend(fuvs) - obj.elist.extend(edges) # loose edges - - numsurf -= 1 - - if badface_notpoly or badface_multirefs: - inform('Object "%s" - ignoring bad faces:' % obj.name) - if badface_notpoly: - inform('\t%d face(s) with less than 3 vertices.' % badface_notpoly) - if badface_multirefs: - inform('\t%d face(s) with multiple references to a same vertex.' % badface_multirefs) - - self.i = i - - def parse_file(self): - i = 1 - lines = self.lines - line = lines[i].split() - - while line: - kw = '' - for k in self.token.keys(): - if line[0] == k: - kw = k - break - i += 1 - if kw: - self.i = i - result = self.token[kw](line[1]) - if result: - break # bad .ac file, stop parsing - i = self.i - line = lines[i].split() - - # for each group of meshes we try to find one that can be used as - # parent of the group in Blender. - # If not found, we can use an Empty as parent. - def found_parent(self, groupname, olist): - l = [o for o in olist if o.type == AC_POLY \ - and not o.kids and not o.rot and not o.loc] - if l: - for o in l: - if o.name == groupname: - return o - #return l[0] - return None - - def build_hierarchy(self): - blmatrix = AC_TO_BLEND_MATRIX - - olist = self.objlist[1:] - olist.reverse() - - scene = self.scene - - newlist = [] - - for o in olist: - kids = o.kids - if kids: - children = newlist[-kids:] - newlist = newlist[:-kids] - if o.type == AC_GROUP: - parent = self.found_parent(o.name, children) - if parent: - children.remove(parent) - o.bl_obj = parent.bl_obj - else: # not found, use an empty - empty = scene.objects.new('Empty', o.name) - o.bl_obj = empty - - bl_children = [c.bl_obj for c in children if c.bl_obj != None] - - o.bl_obj.makeParent(bl_children, 0, 1) - for child in children: - blob = child.bl_obj - if not blob: continue - if child.rot: - eul = euler_in_radians(child.rot.toEuler()) - blob.setEuler(eul) - if child.size: - blob.size = child.size - if not child.loc: - child.loc = Vector(0.0, 0.0, 0.0) - blob.setLocation(child.loc) - - newlist.append(o) - - for o in newlist: # newlist now only has objs w/o parents - blob = o.bl_obj - if not blob: - continue - if o.size: - o.bl_obj.size = o.size - if not o.rot: - blob.setEuler([1.5707963267948966, 0, 0]) - else: - matrix = o.rot * blmatrix - eul = euler_in_radians(matrix.toEuler()) - blob.setEuler(eul) - if o.loc: - o.loc *= blmatrix - else: - o.loc = Vector(0.0, 0.0, 0.0) - blob.setLocation(o.loc) # forces DAG update, so we do it even for 0, 0, 0 - - # XXX important: until we fix the BPy API so it doesn't increase user count - # when wrapping a Blender object, this piece of code is needed for proper - # object (+ obdata) deletion in Blender: - for o in self.objlist: - if o.bl_obj: - o.bl_obj = None - - def testAC3DImport(self): - - FACE_TWOSIDE = Mesh.FaceModes['TWOSIDE'] - FACE_TEX = Mesh.FaceModes['TEX'] - MESH_AUTOSMOOTH = Mesh.Modes['AUTOSMOOTH'] - - MAT_MODE_ZTRANSP = Material.Modes['ZTRANSP'] - MAT_MODE_TRANSPSHADOW = Material.Modes['TRANSPSHADOW'] - - scene = self.scene - - bl_images = {} # loaded texture images - missing_textures = [] # textures we couldn't find - - objlist = self.objlist[1:] # skip 'world' - - bmat = [] - has_transp_mats = False - for mat in self.mlist: - name = mat[0] - m = Material.New(name) - m.rgbCol = (mat[1][0], mat[1][1], mat[1][2]) - m.amb = mat[2] - m.emit = mat[3] - m.specCol = (mat[4][0], mat[4][1], mat[4][2]) - m.spec = mat[5] - m.mirCol = (mat[6][0], mat[6][1], mat[6][2]) - m.alpha = mat[7] - if m.alpha < 1.0: - m.mode |= MAT_MODE_ZTRANSP - has_transp_mats = True - bmat.append(m) - - if has_transp_mats: - for mat in bmat: - mat.mode |= MAT_MODE_TRANSPSHADOW - - obj_idx = 0 # index of current obj in loop - for obj in objlist: - if obj.type == AC_GROUP: - continue - elif obj.type == AC_LIGHT: - light = Lamp.New('Lamp') - object = scene.objects.new(light, obj.name) - #object.select(True) - obj.bl_obj = object - if obj.data: - light.name = obj.data - continue - - # type AC_POLY: - - # old .ac files used empty meshes as groups, convert to a real ac group - if not obj.vlist and obj.kids: - obj.type = AC_GROUP - continue - - mesh = Mesh.New() - object = scene.objects.new(mesh, obj.name) - #object.select(True) - obj.bl_obj = object - if obj.data: mesh.name = obj.data - mesh.degr = obj.crease # will auto clamp to [1, 80] - - if not obj.vlist: # no vertices? nothing more to do - continue - - mesh.verts.extend(obj.vlist) - - objmat_indices = [] - for mat in bmat: - if bmat.index(mat) in obj.matlist: - objmat_indices.append(bmat.index(mat)) - mesh.materials += [mat] - if DISPLAY_TRANSP and mat.alpha < 1.0: - object.transp = True - - for e in obj.elist: - mesh.edges.extend(e) - - if obj.flist_v: - mesh.faces.extend(obj.flist_v) - - facesnum = len(mesh.faces) - - if facesnum == 0: # shouldn't happen, of course - continue - - mesh.faceUV = True - - # checking if the .ac file had duplicate faces (Blender ignores them) - if facesnum != len(obj.flist_v): - # it has, ugh. Let's clean the uv list: - lenfl = len(obj.flist_v) - flist = obj.flist_v - uvlist = obj.flist_uv - cfglist = obj.flist_cfg - for f in flist: - f.sort() - fi = lenfl - while fi > 0: # remove data related to duplicates - fi -= 1 - if flist[fi] in flist[:fi]: - uvlist.pop(fi) - cfglist.pop(fi) - - img = None - if obj.tex != '': - if obj.tex in bl_images.keys(): - img = bl_images[obj.tex] - elif obj.tex not in missing_textures: - texfname = None - objtex = obj.tex - baseimgname = bsys.basename(objtex) - if bsys.exists(objtex) == 1: - texfname = objtex - elif bsys.exists(bsys.join(self.importdir, objtex)): - texfname = bsys.join(self.importdir, objtex) - else: - if baseimgname.find('\\') > 0: - baseimgname = bsys.basename(objtex.replace('\\','/')) - objtex = bsys.join(self.importdir, baseimgname) - if bsys.exists(objtex) == 1: - texfname = objtex - else: - objtex = bsys.join(TEXTURES_DIR, baseimgname) - if bsys.exists(objtex): - texfname = objtex - if texfname: - try: - img = Image.Load(texfname) - # Commented because it's unnecessary: - #img.xrep = int(obj.texrep[0]) - #img.yrep = int(obj.texrep[1]) - if img: - bl_images[obj.tex] = img - except: - inform("Couldn't load texture: %s" % baseimgname) - else: - missing_textures.append(obj.tex) - inform("Couldn't find texture: %s" % baseimgname) - - for i in range(facesnum): - f = obj.flist_cfg[i] - fmat = f[0] - is_smooth = f[1] - twoside = f[2] - bface = mesh.faces[i] - bface.smooth = is_smooth - if twoside: bface.mode |= FACE_TWOSIDE - if img: - bface.mode |= FACE_TEX - bface.image = img - bface.mat = objmat_indices.index(fmat) - fuv = obj.flist_uv[i] - if obj.texoff: - uoff = obj.texoff[0] - voff = obj.texoff[1] - urep = obj.texrep[0] - vrep = obj.texrep[1] - for uv in fuv: - uv[0] *= urep - uv[1] *= vrep - uv[0] += uoff - uv[1] += voff - - mesh.faces[i].uv = fuv - - # finally, delete the 1st vertex we added to prevent vindices == 0 - mesh.verts.delete(0) - - mesh.calcNormals() - - mesh.mode = MESH_AUTOSMOOTH - - # subdiv: create SUBSURF modifier in Blender - if SUBDIV and obj.subdiv > 0: - subdiv = obj.subdiv - subdiv_render = subdiv - # just to be safe: - if subdiv_render > 6: subdiv_render = 6 - if subdiv > 3: subdiv = 3 - modif = object.modifiers.append(Modifier.Types.SUBSURF) - modif[Modifier.Settings.LEVELS] = subdiv - modif[Modifier.Settings.RENDLEVELS] = subdiv_render - - obj_idx += 1 - - self.build_hierarchy() - scene.update() - -# End of class AC3DImport - -def filesel_callback(filename): - - inform("\nTrying to import AC3D model(s) from:\n%s ..." % filename) - Window.WaitCursor(1) - starttime = bsys.time() - test = AC3DImport(filename) - Window.WaitCursor(0) - endtime = bsys.time() - starttime - inform('Done! Data imported in %.3f seconds.\n' % endtime) - -Window.EditMode(0) - -Window.FileSelector(filesel_callback, "Import AC3D", "*.ac") diff --git a/release/scripts/add_mesh_empty.py b/release/scripts/add_mesh_empty.py deleted file mode 100644 index 537bd1e2c3d..00000000000 --- a/release/scripts/add_mesh_empty.py +++ /dev/null @@ -1,13 +0,0 @@ -#!BPY -""" -Name: 'Empty mesh' -Blender: 243 -Group: 'AddMesh' -""" -import BPyAddMesh -import Blender - -def main(): - BPyAddMesh.add_mesh_simple('EmptyMesh', [], [], []) - -main() \ No newline at end of file diff --git a/release/scripts/add_mesh_torus.py b/release/scripts/add_mesh_torus.py deleted file mode 100644 index 2941c56420e..00000000000 --- a/release/scripts/add_mesh_torus.py +++ /dev/null @@ -1,69 +0,0 @@ -#!BPY -""" -Name: 'Torus' -Blender: 243 -Group: 'AddMesh' -""" -import BPyAddMesh -import Blender -try: from math import cos, sin, pi -except: math = None - -def add_torus(PREF_MAJOR_RAD, PREF_MINOR_RAD, PREF_MAJOR_SEG, PREF_MINOR_SEG): - Vector = Blender.Mathutils.Vector - RotationMatrix = Blender.Mathutils.RotationMatrix - verts = [] - faces = [] - i1 = 0 - tot_verts = PREF_MAJOR_SEG * PREF_MINOR_SEG - for major_index in xrange(PREF_MAJOR_SEG): - verts_tmp = [] - mtx = RotationMatrix( 360 * float(major_index)/PREF_MAJOR_SEG, 3, 'z' ) - - for minor_index in xrange(PREF_MINOR_SEG): - angle = 2*pi*minor_index/PREF_MINOR_SEG - - verts.append( Vector(PREF_MAJOR_RAD+(cos(angle)*PREF_MINOR_RAD), 0, (sin(angle)*PREF_MINOR_RAD)) * mtx ) - if minor_index+1==PREF_MINOR_SEG: - i2 = (major_index)*PREF_MINOR_SEG - i3 = i1 + PREF_MINOR_SEG - i4 = i2 + PREF_MINOR_SEG - - else: - i2 = i1 + 1 - i3 = i1 + PREF_MINOR_SEG - i4 = i3 + 1 - - if i2>=tot_verts: i2 = i2-tot_verts - if i3>=tot_verts: i3 = i3-tot_verts - if i4>=tot_verts: i4 = i4-tot_verts - - faces.append( (i3,i4,i2,i1) ) - i1+=1 - - return verts, faces - -def main(): - Draw = Blender.Draw - PREF_MAJOR_RAD = Draw.Create(1.0) - PREF_MINOR_RAD = Draw.Create(0.25) - PREF_MAJOR_SEG = Draw.Create(48) - PREF_MINOR_SEG = Draw.Create(16) - - if not Draw.PupBlock('Add Torus', [\ - ('Major Radius:', PREF_MAJOR_RAD, 0.01, 100, 'Radius for the main ring of the torus'),\ - ('Minor Radius:', PREF_MINOR_RAD, 0.01, 100, 'Radius for the minor ring of the torus setting the thickness of the ring'),\ - ('Major Segments:', PREF_MAJOR_SEG, 3, 256, 'Number of segments for the main ring of the torus'),\ - ('Minor Segments:', PREF_MINOR_SEG, 3, 256, 'Number of segments for the minor ring of the torus'),\ - ]): - return - - verts, faces = add_torus(PREF_MAJOR_RAD.val, PREF_MINOR_RAD.val, PREF_MAJOR_SEG.val, PREF_MINOR_SEG.val) - - BPyAddMesh.add_mesh_simple('Torus', verts, [], faces) - -if cos and sin and pi: - main() -else: - Blender.Draw.PupMenu("Error%t|This script requires a full python installation") - diff --git a/release/scripts/animation_bake_constraints.py b/release/scripts/animation_bake_constraints.py deleted file mode 100644 index 16855828460..00000000000 --- a/release/scripts/animation_bake_constraints.py +++ /dev/null @@ -1,792 +0,0 @@ -#!BPY - -""" -Name: 'Bake Constraints' -Blender: 246 -Group: 'Animation' -Tooltip: 'Bake a Constrained object/rig to IPOs' -Fillename: 'Bake_Constraint.py' -""" - -__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)" -__script__ = "Animation Bake Constraints" -__version__ = "0.7" -__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"] -__email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"] -__bpydoc__ = """\ - -bake_constraints - -This script bakes the real-world LocRot of an object (the net effect of any constraints - -(Copy, Limit, Track, Follow, - that affect Location, Rotation) -(usually one constrained to match another's location and/or Tracked to another) -and creates a clone with a set of Ipo Curves named Ipo -These curves control a non-constrained object and thus make it mimic the constrained object -Actions can be then be edited without the need for the drivers/constraining objects - -Developed for use with MoCap data, where a bone is constrained to point at an empty -moving through space and time. This records the actual locrot of the armature -so that the motion can be edited, reoriented, scaled, and used as NLA Actions - -see also wiki Scripts/Manual/ Tutorial/Motion Capture
- -Usage:
- - Select the reference Object(s) you want to bake
- - Set the frame range to bake in the Anim Panel
- - Set the test code (if you want a self-test) in the RT field in the Anim Panel
- -- Set RT:1 to create a test armature
- -- Set RT: up to 100 for more debug messages and status updates
-
- - Run the script
- - The clone copy of the object is created and it has an IPO curve assigned to it.
- - The clone shadows the object by an offset locrot (see usrDelta)
- - That Object has Ipo Location and Rotation curves that make the clone mimic the movement
- of the selected object, but without using constraints.
- - If the object was an Armature, the clone's bones move identically in relation to the
- original armature, and an Action is created that drives the bone movements.
- -Version History: - 0.1: bakes Loc Rot for a constrained object - 0.2: bakes Loc and Rot for the bones within Armature object - 0.3: UI for setting options - 0.3.1 add manual to script library - 0.4: bake multiple objects - 0.5: root bone worldspace rotation - 0.6: re-integration with BPyArmature - 0.7: bakes parents and leaves clones selected - -License, Copyright, and Attribution: - by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain - feel free to add to any Blender Python Scripts Bundle. - Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton), Basil_Fawlty/Cage_drei (Andrew Cruse) - much lifted/learned from blender.org/documentation/245PytonDoc and wiki - some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter - -Pseudocode: - Initialize - If at least one object is selected - For each selected object, - create a cloned object - remove any constraints on the clone - create or reset an ipo curve named like the object - for each frame - set the clone's locrot key based on the reference object - if it's an armature, - create an action (which is an Ipo for each bone) - for each frame of the animation - for each bone in the armature - set the key - Else you're a smurf - -Test Conditions and Regressions: - 1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level - 2. armatures, with ipo curve and constraints at the object level - 3. armatures, with bones that have ipo curves and constraints - 4. objects without parents, children with unselected parents, select children first. - -Naming conventions: - arm = a specific objec type armature - bone = bones that make up the skeleton of an armature - - ob = object, an instance of an object type - ebone = edit bone, a bone in edit mode - pbone = pose bone, a posed bone in an object - tst = testing, self-test routines - usr = user-entered or designated stuff -""" -######################################## - -import Blender -from Blender import * -from Blender.Mathutils import * -import struct -import string -import bpy -import BPyMessages -import BPyArmature -# reload(BPyArmature) -from BPyArmature import getBakedPoseData - -Vector= Blender.Mathutils.Vector -Euler= Blender.Mathutils.Euler -Matrix= Blender.Mathutils.Matrix #invert() function at least -RotationMatrix = Blender.Mathutils.RotationMatrix -TranslationMatrix= Blender.Mathutils.TranslationMatrix -Quaternion = Blender.Mathutils.Quaternion -Vector = Blender.Mathutils.Vector -POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT] - -#================= -# Global Variables -#================= - -# set senstitivity for displaying debug/console messages. 0=none, 100=max -# then call debug(num,string) to conditionally display status/info in console window -MODE=Blender.Get('rt') #execution mode: 0=run normal, 1=make test armature -DEBUG=Blender.Get('rt') #how much detail on internal processing for user to see. range 0-100 -BATCH=False #called from command line? is someone there? Would you like some cake? - -#there are two coordinate systems, the real, or absolute 3D space, -# and the local relative to a parent. -COORDINATE_SYSTEMS = ['local','real'] -COORD_LOCAL = 0 -COORD_REAL = 1 - -# User Settings - Change these options manually or via GUI (future TODO) -usrCoord = COORD_REAL # what the user wants -usrParent = False # True=clone keeps original parent, False = clone's parent is the clone of the original parent (if cloned) -usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin -# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant -usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz -usrACTION = True # Offset baked Action frames to start at frame 1 - -CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on -ARMATURE = 'Armature' #en anglais -BONE_SPACES = ['ARMATURESPACE','BONESPACE'] - # 'ARMATURESPACE' - this matrix of the bone in relation to the armature - # 'BONESPACE' - the matrix of the bone in relation to itself - -#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name -#bakedArmName = "b." #used for both the armature class and object instance -usrObjectNamePrefix= "" -#ipoBoneNamePrefix = "" -# for example, if on entry an armature named Man was selected, and the object prefix was "a." -# on exit an armature and an IPO curve named a.Man exists for the object as a whole -# if that armature had bones (spine, neck, arm) and the bone prefix was "a." -# the bones and IPO curves will be (a.spine, a.neck, a.arm) - -R2D = 18/3.141592653589793 # radian to grad -BLENDER_VERSION = Blender.Get('version') - -# Gets the current scene, there can be many scenes in 1 blend file. -scn = Blender.Scene.GetCurrent() - -#================= -# Methods -#================= -######################################## -def debug(num,msg): #use log4j or just console here. - if DEBUG >= num: - if BATCH == False: - print 'debug: '[:num/10+7]+msg - #TODO: else write out to file (runs faster if it doesnt have to display details) - return - -######################################## -def error(str): - debug(0,'ERROR: '+str) - if BATCH == False: - Draw.PupMenu('ERROR%t|'+str) - return - -######################################## -def getRenderInfo(): - context=scn.getRenderingContext() - staframe = context.startFrame() - endframe = context.endFrame() - if endframe= 1: - for i in range(10): - curFrame+=frameinc - Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects - Blender.Redraw() - Blender.Set(CURFRAME, staFrame) - return - -######################################## -def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob - scrub() - staFrame,endFrame,curFrame = getRenderInfo() - act = getBakedPoseData(ref_ob, staFrame, endFrame, ACTION_BAKE = True, ACTION_BAKE_FIRST_FRAME = usrACTION) # bake the pose positions of the reference ob to the armature ob - arm_ob.action = act - scrub() - - # user comprehension feature - change action name and channel ipo names to match the names of the bone they drive - debug (80,'Renaming each action ipo to match the bone they pose') - act.name = arm_ob.name - arm_channels = act.getAllChannelIpos() - pose= arm_ob.getPose() - pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup - for pbone in pbones: - debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] )) - ipo=arm_channels[pbone.name] - ipo.name = pbone.name # since bone names are unique within an armature, the pose names can be the same since they are within an Action - - return - -######################################## -def getOrCreateCurve(ipo, curvename): - """ - Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo - Either an ipo curve named C{curvename} exists before the call then this curve is returned, - Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned - """ - try: - mycurve = ipo.getCurve(curvename) - if mycurve != None: - pass - else: - mycurve = ipo.addCurve(curvename) - except: - mycurve = ipo.addCurve(curvename) - return mycurve - -######################################## -def eraseCurve(ipo,numCurves): - debug(90,'Erasing %i curves for %' % (numCurves,ipo.GetName())) - for i in range(numCurves): - nbBezPoints= ipo.getNBezPoints(i) - for j in range(nbBezPoints): - ipo.delBezPoint(i) - return - -######################################## -def resetIPO(ipo): - debug(60,'Resetting ipo curve named %s' %ipo.name) - numCurves = ipo.getNcurves() #like LocX, LocY, etc - if numCurves > 0: - eraseCurve(ipo, numCurves) #erase data if one exists - return - -######################################## -def resetIPOs(ob): #resets all IPO curvess assocated with an object and its bones - debug(30,'Resetting any ipo curves linked to %s' %ob.getName()) - ipo = ob.getIpo() #may be None - ipoName = ipo.getName() #name of the IPO that guides/controls this object - debug(70,'Object IPO is %s' %ipoName) - try: - ipo = Ipo.Get(ipoName) - except: - ipo = Ipo.New('Object', ipoName) - resetIPO(ipo) - if ob.getType() == ARMATURE: - arm_data=ob.getData() - bones=arm_data.bones.values() - for bone in bones: - #for each bone: get the name and check for a Pose IPO - debug(10,'Processing '+ bone.name) - return - -######################################## -def parse(string,delim): - index = string.find(delim) # -1 if not found, else pointer to delim - if index+1: return string[:index] - return string - -######################################## -def newIpo(ipoName): #add a new Ipo object to the Blender scene - ipo=Blender.Ipo.New('Object',ipoName) - - ipo.addCurve('LocX') - ipo.addCurve('LocY') - ipo.addCurve('LocZ') - ipo.addCurve('RotX') - ipo.addCurve('RotY') - ipo.addCurve('RotZ') - return ipo - -######################################## -def makeUpaName(type,name): #i know this exists in Blender somewhere... - debug(90,'Making up a new %s name using %s as a basis.' % (type,name)) - name = (parse(name,'.')) - if type == 'Ipo': - ipoName = name # maybe we get lucky today - ext = 0 - extlen = 3 # 3 digit extensions, like hello.002 - success = False - while not(success): - try: - debug(100,'Trying %s' % ipoName) - ipo = Ipo.Get(ipoName) - #that one exists if we get here. add on extension and keep trying - ext +=1 - if ext>=10**extlen: extlen +=1 # go to more digits if 999 not found - ipoName = '%s.%s' % (name, str(ext).zfill(extlen)) - except: # could not find it - success = True - name=ipoName - else: - debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob)) - return None - return name - -######################################## -def createIpo(ob): #create an Ipo and curves and link them to this object - #first, we have to create a unique name - #try first with just the name of the object to keep things simple. - ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name - debug(20,'Ipo and LocRot curves called %s' % ipoName) - ipo=newIpo(ipoName) - ob.setIpo(ipo) #link them - return ipo - -######################################## -def getLocLocal(ob): - key = [ - ob.LocX, - ob.LocY, - ob.LocZ, - ob.RotX*R2D, #get the curves in this order - ob.RotY*R2D, - ob.RotZ*R2D - ] - return key - -######################################## -def getLocReal(ob): - obMatrix = ob.matrixWorld #Thank you IdeasMan42 - loc = obMatrix.translationPart() - rot = obMatrix.toEuler() - key = [ - loc.x, - loc.y, - loc.z, - rot.x/10, - rot.y/10, - rot.z/10 - ] - return key - -######################################## -def getLocRot(ob,space): - if space in xrange(len(COORDINATE_SYSTEMS)): - if space == COORD_LOCAL: - key = getLocLocal(ob) - return key - elif space == COORD_REAL: - key = getLocReal(ob) - return key - else: #hey, programmers make mistakes too. - debug(0,'Fatal Error: getLoc called with %i' % space) - return - -######################################## -def getCurves(ipo): - ipos = [ - ipo[Ipo.OB_LOCX], - ipo[Ipo.OB_LOCY], - ipo[Ipo.OB_LOCZ], - ipo[Ipo.OB_ROTX], #get the curves in this order - ipo[Ipo.OB_ROTY], - ipo[Ipo.OB_ROTZ] - ] - return ipos - -######################################## -def addPoint(time,keyLocRot,ipos): - if BLENDER_VERSION < 245: - debug(0,'WARNING: addPoint uses BezTriple') - for i in range(len(ipos)): - point = BezTriple.New() #this was new with Blender 2.45 API - point.pt = (time, keyLocRot[i]) - point.handleTypes = [1,1] - - ipos[i].append(point) - return ipos - -######################################## -def bakeFrames(ob,myipo): #bakes an object in a scene, returning the IPO containing the curves - myipoName = myipo.getName() - debug(20,'Baking frames for scene %s object %s to ipo %s' % (scn.getName(),ob.getName(),myipoName)) - ipos = getCurves(myipo) - #TODO: Gui setup idea: myOffset - # reset action to start at frame 1 or at location - myOffset=0 #=1-staframe - #loop through frames in the animation. Often, there is rollup and the mocap starts late - staframe,endframe,curframe = getRenderInfo() - for frame in range(staframe, endframe+1): - debug(80,'Baking Frame %i' % frame) - #tell Blender to advace to frame - Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects - if not BATCH: Blender.Redraw() # no secrets, let user see what we are doing - - #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen - key = getLocRot(ob,usrCoord) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame - key = [a+b for a,b in zip(key, usrDelta)] #offset to the new location - - myframe= frame+myOffset - Blender.Set(CURFRAME,myframe) - - time = Blender.Get('curtime') #for BezTriple - ipos = addPoint(time,key,ipos) #add this data at this time to the ipos - debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5])) - # eye-candy - smoothly rewind the animation, showing now how the clone match moves - if endframe-staframe <400 and not BATCH: - for frame in range (endframe,staframe,-1): #rewind - Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects - Blender.Redraw() - Blender.Set(CURFRAME,staframe) - Blender.Redraw() - - return ipos - -######################################## -def duplicateLinked(ob): - obType = ob.type - debug(10,'Duplicating %s Object named %s' % (obType,ob.getName())) - scn.objects.selected = [ob] -## rdw: simplified by just duplicating armature. kept code as reference for creating armatures -## disadvantage is that you cant have clone as stick and original as octahedron -## since they share the same Armature. User can click Make Single User button. -## if obType == ARMATURE: #build a copy from scratch -## myob= dupliArmature(ob) -## else: - Blender.Object.Duplicate() # Duplicate linked, including pose constraints. - myobs = Object.GetSelected() #duplicate is top on the list - myob = myobs[0] - if usrParent == False: - myob.clrParent(usrFreeze) - debug(20,'=myob= was created as %s' % myob.getName()) - return myob - -######################################## -def removeConstraints(ob): - for const in ob.constraints: - debug(90,'removed %s => %s' % (ob.name, const)) - ob.constraints.remove(const) - return - -######################################## -def removeConstraintsOb(ob): # from object or armature - debug(40,'Removing constraints from '+ob.getName()) - if BLENDER_VERSION > 241: #constraints module not available before 242 - removeConstraints(ob) - if ob.getType() == ARMATURE: - pose = ob.getPose() - for pbone in pose.bones.values(): - #bone = pose.bones[bonename] - removeConstraints(pbone) - #should also check if it is a deflector? - return - -######################################## -def deLinkOb(type,ob): #remove linkages - if type == 'Ipo': - success = ob.clearIpo() #true=there was one - if success: debug(80,'deLinked Ipo curve to %s' % ob.getName()) - return - -######################################## -def bakeObject(ob): #bakes the core object locrot and assigns the Ipo to a Clone - if ob != None: - # Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone - myob = duplicateLinked(ob) #clone it - myob.setName(usrObjectNamePrefix + ob.getName()) - removeConstraintsOb(myob) #my object is a free man - deLinkOb('Ipo',myob) #kids, it's not nice to share. you've been lied to - if ob.getType() != ARMATURE: # baking armatures is based on bones, not object - myipo = createIpo(myob) #create own IPO and curves for the clone object - ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames - return myob - -######################################## -def bake(ob,par): #bakes an object of any type, linking it to parent - debug(0,'Baking %s object %s' % (ob.getType(), ob)) - clone = bakeObject(ob) #creates and bakes the object motion - if par!= None: - par.makeParent([clone]) - debug(20,"assigned object to parent %s" % par) - if ob.getType() == ARMATURE: -## error('Object baked. Continue with bones?') - bakeBones(ob,clone) #go into the bones and copy from -> to in frame range - #future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...) - return clone - -######################################## -def tstCreateArm(): #create a test armature in scene - # rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you! - - debug(0,'Making Test Armature') - # New Armature - arm_data= Armature.New('myArmature') - print arm_data - arm_ob = scn.objects.new(arm_data) - arm_data.makeEditable() - - # Add 4 bones - ebones = [Armature.Editbone(), Armature.Editbone(), Armature.Editbone(), Armature.Editbone()] - - # Name the editbones - ebones[0].name = 'Bone.001' - ebones[1].name = 'Bone.002' - ebones[2].name = 'Bone.003' - ebones[3].name = 'Bone.004' - - # Assign the editbones to the armature - for eb in ebones: - arm_data.bones[eb.name]= eb - - # Set the locations of the bones - ebones[0].head= Mathutils.Vector(0,0,0) - ebones[0].tail= Mathutils.Vector(0,0,1) #tip - ebones[1].head= Mathutils.Vector(0,0,1) - ebones[1].tail= Mathutils.Vector(0,0,2) - ebones[2].head= Mathutils.Vector(0,0,2) - ebones[2].tail= Mathutils.Vector(0,0,3) - ebones[3].head= Mathutils.Vector(0,0,3) - ebones[3].tail= Mathutils.Vector(0,0,4) - - ebones[1].parent= ebones[0] - ebones[2].parent= ebones[1] - ebones[3].parent= ebones[2] - - arm_data.update() - # Done with editing the armature - - # Assign the pose animation - arm_pose = arm_ob.getPose() - - act = arm_ob.getAction() - if not act: # Add a pose action if we dont have one - act = Armature.NLA.NewAction() - act.setActive(arm_ob) - - xbones=arm_ob.data.bones.values() - pbones = arm_pose.bones.values() - - frame = 1 - for pbone in pbones: # set bones to no rotation - pbone.quat[:] = 1.000,0.000,0.000,0.0000 - pbone.insertKey(arm_ob, frame, Object.Pose.ROT) - - # Set a different rotation at frame 25 - pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000 - pbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000 - pbones[2].quat[:] = 1.000,0.1000,0.3000,0.40000 - pbones[3].quat[:] = 1.000,-0.2000,-0.3000,0.30000 - - frame = 25 - for i in xrange(4): - pbones[i].insertKey(arm_ob, frame, Object.Pose.ROT) - - pbones[0].quat[:] = 1.000,0.000,0.000,0.0000 - pbones[1].quat[:] = 1.000,0.000,0.000,0.0000 - pbones[2].quat[:] = 1.000,0.000,0.000,0.0000 - pbones[3].quat[:] = 1.000,0.000,0.000,0.0000 - - frame = 50 - for pbone in pbones: # set bones to no rotation - pbone.quat[:] = 1.000,0.000,0.000,0.0000 - pbone.insertKey(arm_ob, frame, Object.Pose.ROT) - - return arm_ob - -######################################## -def tstMoveOb(ob): # makes a simple LocRot animation of object in the scene - anim = [ - #Loc Rot/10 - # - ( 0,0,0, 0, 0, 0), #frame 1 origin - ( 1,0,0, 0, 0, 0), #frame 2 - ( 1,1,0, 0, 0, 0), - ( 1,1,1, 0, 0, 0), - ( 1,1,1,4.5, 0, 0), - ( 1,1,1,4.5,4.5, 0), - ( 1,1,1,4.5,4.5,4.5) - ] - space = COORD_LOCAL - ipo = createIpo(ob) #create an Ipo and curves for this object - ipos = getCurves(ipo) - - # span this motion over the currently set anim range - # to set points, i need time but do not know how it is computed, so will have to advance the animation - staframe,endframe,curframe = getRenderInfo() - - frame = staframe #x position of new ipo datapoint. set to staframe if you want a match - frameDelta=(endframe-staframe)/(len(anim)) #accomplish the animation in frame range - for key in anim: #effectively does a getLocRot() - #tell Blender to advace to frame - Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects - time = Blender.Get('curtime') - - ipos = addPoint(time,key,ipos) #add this data at this time to the ipos - - debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5])) - frame += frameDelta - Blender.Set(CURFRAME,curframe) # reset back to where we started - return -#================= -# Program Template -#================= -######################################## -def main(): - # return code set via rt button in Blender Buttons Scene Context Anim panel - if MODE == 1: #create test armature #1 - ob = tstCreateArm() # make test arm and select it - tstMoveOb(ob) - scn.objects.selected = [ob] - - obs= Blender.Object.GetSelected() #scn.objects.selected - obs= sortObjects(obs) - debug(0,'Baking %i objects' % len(obs)) - - if len(obs) >= 1: # user might have multiple objects selected - i= 0 - clones=[] # my clone army - for ob in obs: - par= ob.getParent() - if not usrParent: - if par in obs: - par= clones[obs.index(par)] - clones.append(bake(ob,par)) - scn.objects.selected = clones - else: - error('Please select at least one object') - return - -######################################## -def benchmark(): # This lets you benchmark (time) the script's running duration - Window.WaitCursor(1) - t = sys.time() - debug(60,'%s began at %.0f' %(__script__,sys.time())) - - # Run the function on the active scene - in_editmode = Window.EditMode() - if in_editmode: Window.EditMode(0) - - main() - - if in_editmode: Window.EditMode(1) - - # Timing the script is a good way to be aware on any speed hits when scripting - debug(0,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) ) - Window.WaitCursor(0) - return - -######################################## -# This lets you can import the script without running it -if __name__ == '__main__': - debug(0, "------------------------------------") - debug(0, "%s %s Script begins with mode=%i debug=%i batch=%s" % (__script__,__version__,MODE,DEBUG,BATCH)) - benchmark() diff --git a/release/scripts/animation_clean.py b/release/scripts/animation_clean.py deleted file mode 100644 index fc44f264ac1..00000000000 --- a/release/scripts/animation_clean.py +++ /dev/null @@ -1,192 +0,0 @@ -#!BPY - -""" -Name: 'Clean Animation Curves' -Blender: 249 -Group: 'Animation' -Tooltip: 'Remove unused keyframes for ipo curves' -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2008-2009: 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, -# -------------------------------------------------------------------------- - -import bpy -from Blender import IpoCurve, Draw, Window - -def clean_ipos(ipos): - eul = 0.001 - - def isflat(vec): - prev_y = vec[0][1] - mid_y = vec[1][1] - next_y = vec[2][1] - - # flat status for prev and next - return abs(mid_y-prev_y) < eul, abs(mid_y-next_y) < eul - - - - X=0 - Y=1 - PREV=0 - MID=1 - NEXT=2 - - LEFT = 0 - RIGHT = 1 - - TOT = 0 - TOTBEZ = 0 - # for ipo in bpy.data.ipos: - for ipo in ipos: - if ipo.lib: - continue - # print ipo - for icu in ipo: - interp = icu.interpolation - extend = icu.extend - - bezierPoints = icu.bezierPoints - bezierVecs = [bez.vec for bez in bezierPoints] - - l = len(bezierPoints) - - TOTBEZ += l - - # our aim is to simplify this ipo as much as possible! - if interp == IpoCurve.InterpTypes.BEZIER or interp == interp == IpoCurve.InterpTypes.LINEAR: - #print "Not yet supported" - - if interp == IpoCurve.InterpTypes.BEZIER: - flats = [isflat(bez) for bez in bezierVecs] - else: - # A bit of a waste but fake the locations for these so they will always be flats - # IS better then too much duplicate code. - flats = [(True, True)] * l - for v in bezierVecs: - v[PREV][Y] = v[NEXT][Y] = v[MID][Y] - - - # remove middle points - if l>2: - done_nothing = False - - while not done_nothing and len(bezierVecs) > 2: - done_nothing = True - i = l-2 - - while i > 0: - #print i - #print i, len(bezierVecs) - if flats[i]==(True,True) and flats[i-1][RIGHT] and flats[i+1][LEFT]: - - if abs(bezierVecs[i][MID][Y] - bezierVecs[i-1][MID][Y]) < eul and abs(bezierVecs[i][MID][Y] - bezierVecs[i+1][MID][Y]) < eul: - done_nothing = False - - del flats[i] - del bezierVecs[i] - icu.delBezier(i) - TOT += 1 - l-=1 - i-=1 - - # remove endpoints - if extend == IpoCurve.ExtendTypes.CONST and len(bezierVecs) > 1: - #print l, len(bezierVecs) - # start - - while l > 2 and (flats[0][RIGHT] and flats[1][LEFT] and (abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul)): - print "\tremoving 1 point from start of the curve" - del flats[0] - del bezierVecs[0] - icu.delBezier(0) - TOT += 1 - l-=1 - - - # End - while l > 2 and flats[-2][RIGHT] and flats[-1][LEFT] and (abs(bezierVecs[-2][MID][Y] - bezierVecs[-1][MID][Y]) < eul): - print "\tremoving 1 point from end of the curve", l - del flats[l-1] - del bezierVecs[l-1] - icu.delBezier(l-1) - TOT += 1 - l-=1 - - - - if l==2: - if isflat( bezierVecs[0] )[RIGHT] and isflat( bezierVecs[1] )[LEFT] and abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul: - # remove the second point - print "\tremoving 1 point from 2 point bez curve" - # remove the second point - del flats[1] - del bezierVecs[1] - icu.delBezier(1) - TOT+=1 - l-=1 - - # Change to linear for faster evaluation - ''' - if l==1: - print 'Linear' - icu.interpolation = IpoCurve.InterpTypes.LINEAR - ''' - - - - - if interp== IpoCurve.InterpTypes.CONST: - print "Not yet supported" - - print 'total', TOT, TOTBEZ - return TOT, TOTBEZ - -def main(): - ret = Draw.PupMenu('Clean Selected Objects Ipos%t|Object IPO%x1|Object Action%x2|%l|All IPOs (be careful!)%x3') - - sce = bpy.data.scenes.active - ipos = [] - - if ret == 3: - ipos.extend(list(bpy.data.ipos)) - else: - for ob in sce.objects.context: - if ret == 1: - ipo = ob.ipo - if ipo: - ipos.append(ipo) - - elif ret == 2: - action = ob.action - if action: - ipos.extend([ipo for ipo in action.getAllChannelIpos().values() if ipo]) - - - - if not ipos: - Draw.PupMenu('Error%t|No ipos found') - else: - total_removed, total = clean_ipos(ipos) - Draw.PupMenu('Done!%t|Removed ' + str(total_removed) + ' of ' + str(total) + ' points') - - Window.RedrawAll() - - -if __name__ == '__main__': - main() diff --git a/release/scripts/animation_trajectory.py b/release/scripts/animation_trajectory.py deleted file mode 100644 index 55a670b66b1..00000000000 --- a/release/scripts/animation_trajectory.py +++ /dev/null @@ -1,575 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: <- these words are ignored -Name: 'Trajectory' -Blender: 243 -Group: 'Animation' -Tip: 'See Trajectory of selected object' -""" - -__author__ = '3R - R3gis' -__version__ = '2.43' -__url__ = ["Script's site , http://blenderfrance.free.fr/python/Trajectory_en.htm","Author's site , http://cybercreator.free.fr", "French Blender support forum, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender"] -__email__=["3R, r3gis@free.fr"] - - -__bpydoc__ = """ - -Usage: - -* Launch with alt+P (or put it in .script folder) - -Allow to see in real time trajectory of selected object. - -On first run, it ask you -- If you want that actually selected object have they trajectory always shown -- If you want to use Space Handler or a Scriptlink in Redraw mode -- Future and Past : it is the frame in past and future -of the beggining and the end of the path -- Width of line that represent the trajectory - -Then the object's trajectory will be shown in all 3D areas. -When trajectory is red, you can modifiy it by moving object. -When trajectory is blue and you want to be able to modify it, inser a Key (I-Key) - -Points appears on trajectory : -- Left Clic to modify position -- Right Clic to go to the frame it represents - -Notes:
-In scriptlink mode, it create one script link so make sure that 'Enable Script Link' toogle is on -In SpaceHandler mode, you have to go in View>>SpaceHandlerScript menu to activate Trajectory - - -""" - - -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004-2006: Regis Montoya -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- -################################# -# by 3R - 26/08/05 -# for any problem : -# r3gis@free.fr -# ou sur le newsgroup: -# http://zoo-logique.org/3D.Blender/ -################################# -#Many thanks to cambo for his fixes -################################# - - - -import Blender - - -scene= Blender.Scene.GetCurrent() - - -#Writing -def write_script(name, script): - global scene - #List texts and their name - #write : type of writing : 1->New, 2->Overwrite - scripting= None - for text in Blender.Text.Get(): - if text.name==name and text.asLines()[1] != "#"+str(__version__): - scripting = text - scripting.clear() - scripting.write(script) - break - - if not scripting: - scripting= Blender.Text.New(name) - scripting.write(script) - -def link_script(name, type): - global scene - scriptlinks = scene.getScriptLinks(type) # none or list - if not scriptlinks or name not in scriptlinks: - scene.addScriptLink(name, type) - - -#Deleting of a text -def text_remove(name): - global scene - #try to delete text if already linked - try: - text= Blender.Text.Get(name) - # Texte.clear() - scene.clearScriptLinks([name]) - Blender.Text.unlink(text) - except: - print('---Initialisation of Trajectory_'+str(__version__)+'.py---') - -#Whether is already running, also check if it's the last version of the script : second line contain the version fo the script -ask_modif= 0 # Default -for text in Blender.Text.Get(): - if text.name == 'Trajectory' and text.asLines()[1] == "#"+str(__version__): - #We ask if script modify his seetings, keep it or stop script - ask_modif= Blender.Draw.PupMenu("Script already launch %t|Modify settings%x0|Keep settings%x1|Stop script%x2|") - if ask_modif==-1: # user canceled. - ask_modif= 1 - break - -selection_mode= 0 -future= 35 -past= 20 -width= 2 - -#In modify case -if ask_modif==0: - handle_mode= Blender.Draw.Create(0) - selection_mode= Blender.Draw.Create(0) - future= Blender.Draw.Create(35) - past= Blender.Draw.Create(20) - width= Blender.Draw.Create(2) - - block= [] - block.append(("Space Handlers", handle_mode, "You have to activate for each area by View>>SpaceHandler")) #You can delete this option... - block.append(("Always Draw", selection_mode, "Selected object will have their trajectory always shown")) - block.append(("Past :", past, 1, 900)) - block.append(("Futur:", future, 1, 900)) - block.append(("Width:", width, 1,5)) - - if not Blender.Draw.PupBlock("Trajectory seetings", block): - ask_modif=1 - - handle_mode= handle_mode.val - selection_mode= selection_mode.val - future= future.val - past= past.val - width= width.val - - -#put names of selected objects in objects_select if option choosen by user -if selection_mode==1: - objects_select= [ob.name for ob in scene.objects.context] -else: - objects_select= [] - - -try: - if handle_mode==1: - DrawPart="#SPACEHANDLER.VIEW3D.DRAW\n" - else: - DrawPart="#!BPY\n" -except:DrawPart="#BadlyMade" - - -#Here is the script to write in Blender and to link, options are also written now -DrawPart=DrawPart+"#"+str(__version__)+""" -#This script is a part of Trajectory.py and have to be linked to the scene in Redraw if not in HANDLER mode. -#Author : 3R - Regis Montoya -#It's better to use the Trajectory_"version_number".py -#You can modify the two following value to change the path settings -future="""+str(future)+""" -past="""+str(past)+""" -object_init_names="""+str(objects_select)+""" - - -import Blender, math -from Blender import BGL, Draw, Ipo -from Blender.BGL import * -from Blender.Draw import * -from math import * - -from Blender.Mathutils import Vector - -#take actual frame -frameC=Blender.Get('curframe') -scene = Blender.Scene.GetCurrent() -render_context=scene.getRenderingContext() -#ajust number of frames with NewMap and OldMapvalue values -k=1.00*render_context.oldMapValue()/render_context.newMapValue() -if k<1: - tr=-1*int(log(k*0.1, 10)) -else: - tr=-1*int(log(k, 10)) -#The real and integer frame to compare to ipos keys frames -frameCtr=round(frameC*k, tr) -frameCr=frameC*k -frameC=int(round(frameC*k, 0)) - - -#List objects that we have to show trajectory in $objects -# In this case, using a dict for unique objects is the fastest way. -object_dict= dict([(ob.name, ob) for ob in scene.objects.context]) -for obname in object_init_names: - if not object_dict.has_key(obname): - try: # Object may be removed. - object_dict[obname]= Blender.Object.Get(obname) - except: - pass # object was removed. - -#This fonction give the resulting matrix of all parents at a given frame -#parent_list is the list of all parents [object, matrix, locX_ipo, locY, Z, rotX, Y, Z, sizeX, Y, Z] of current object -def matrixForTraj(frame, parent_list): - DecMatC=Blender.Mathutils.Matrix([1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]) - - for parent_data in parent_list: - parent_ob= parent_data[0] - - try: X= parent_data[5][frame]*pi/18 - except: X= parent_ob.RotX - try: Y= parent_data[6][frame]*pi/18 - except: Y= parent_ob.RotY - try: Z= parent_data[7][frame]*pi/18 - except: Z= parent_ob.RotZ - try: LX= parent_data[2][frame] - except: LX= parent_ob.LocX - try: LY= parent_data[3][frame] - except: LY= parent_ob.LocY - try: LZ= parent_data[4][frame] - except: LZ= parent_ob.LocZ - try: SX= parent_data[8][frame] - except: SX= parent_ob.SizeX - try: SY= parent_data[9][frame] - except: SY= parent_ob.SizeY - try: SZ= parent_data[10][frame] - except: SZ= parent_ob.SizeZ - - NMat=Blender.Mathutils.Matrix([cos(Y)*cos(Z)*SX,SX*cos(Y)*sin(Z),-SX*sin(Y),0], - [(-cos(X)*sin(Z)+sin(Y)*sin(X)*cos(Z))*SY,(sin(X)*sin(Y)*sin(Z)+cos(X)*cos(Z))*SY,sin(X)*cos(Y)*SY,0], - [(cos(X)*sin(Y)*cos(Z)+sin(X)*sin(Z))*SZ,(cos(X)*sin(Y)*sin(Z)-sin(X)*cos(Z))*SZ,SZ*cos(X)*cos(Y),0], - [LX,LY,LZ,1]) - DecMatC=DecMatC*parent_data[1]*NMat - return DecMatC - -##### -TestLIST=[] -matview=Blender.Window.GetPerspMatrix() -########### -#Fonction to draw trajectories -########### - -def Trace_Traj(ob): - global TestLIST, matview - #we draw trajectories for all objects in list - - LocX=[] - LocY=[] - LocZ=[] - #List with trajectories' vertexs - vertexX=[] - - contextIpo= ob.ipo - if contextIpo: - ipoLocX=contextIpo[Ipo.OB_LOCX] - ipoLocY=contextIpo[Ipo.OB_LOCY] - ipoLocZ=contextIpo[Ipo.OB_LOCZ] - ipoTime=contextIpo[Ipo.OB_TIME] - else: # only do if there is no IPO (if no ipo curves : return None object and don't go in this except) - ipoLocX= ipoLocY= ipoLocZ= ipoTime= None - - if ipoTime: - return 0 - - #Get all parents of ob - parent=ob.parent - backup_ob= ob - child= ob - parent_list= [] - - #Get parents's infos : - #list of [name, initial matrix at make parent, ipo in X,Y,Z,rotX,rotY,rotZ,sizeX,Y,Z] - while parent: - Init_Mat=Blender.Mathutils.Matrix(child.getMatrix('worldspace')) #must be done like it (it isn't a matrix otherwise) - Init_Mat.invert() - Init_Mat=Init_Mat*child.getMatrix('localspace') - Init_Mat=parent.getMatrix()*Init_Mat - Init_Mat.invert() - - contextIpo= parent.ipo # None or IPO - if contextIpo: - ipo_Parent_LocX=contextIpo[Ipo.OB_LOCX] - ipo_Parent_LocY=contextIpo[Ipo.OB_LOCY] - ipo_Parent_LocZ=contextIpo[Ipo.OB_LOCZ] - ipo_Parent_RotX=contextIpo[Ipo.OB_ROTX] - ipo_Parent_RotY=contextIpo[Ipo.OB_ROTY] - ipo_Parent_RotZ=contextIpo[Ipo.OB_ROTZ] - ipo_Parent_SizeX=contextIpo[Ipo.OB_SIZEX] - ipo_Parent_SizeY=contextIpo[Ipo.OB_SIZEY] - ipo_Parent_SizeZ=contextIpo[Ipo.OB_SIZEZ] - else: - ipo_Parent_LocX=ipo_Parent_LocY=ipo_Parent_LocZ=\ - ipo_Parent_RotX=ipo_Parent_RotY=ipo_Parent_RotZ=\ - ipo_Parent_SizeX=ipo_Parent_SizeY=ipo_Parent_SizeZ= None - - parent_list.append([parent, Init_Mat, ipo_Parent_LocX, ipo_Parent_LocY, ipo_Parent_LocZ, ipo_Parent_RotX, ipo_Parent_RotY, ipo_Parent_RotZ, ipo_Parent_SizeX, ipo_Parent_SizeY, ipo_Parent_SizeZ]) - - child=parent - parent=parent.parent - - #security : if one of parents object are a path>>follow : trajectory don't work properly so it have to draw nothing - for parent in parent_list: - if parent[0].type == 'Curve': - if parent[0].data.flag & 1<<4: # Follow path, 4th bit - return 1 - - #ob >> re-assign obj and not parent - ob= backup_ob - ob= backup_ob - - - if ipoLocX: LXC= ipoLocX[frameC] - else: LXC= ob.LocX - if ipoLocY: LYC= ipoLocY[frameC] - else: LYC= ob.LocY - if ipoLocZ: LZC= ipoLocZ[frameC] - else: LZC= ob.LocZ - - vect= Vector([ob.LocX, ob.LocY, ob.LocZ, 1]) - color=[0, 1] - - #If trajectory is being modified and we are at a frame where a ipo key already exist - if round(ob.LocX, 5)!=round(LXC, 5): - for bez in ipoLocX.bezierPoints: - if round(bez.pt[0], tr)==frameCtr: - bez.pt = [frameCr, vect[0]] - ipoLocX.recalc() - if round(ob.LocY, 5)!=round(LYC, 5): - for bez in ipoLocY.bezierPoints: - if round(bez.pt[0], tr)==frameCtr: - bez.pt = [frameCr, vect[1]] - ipoLocY.recalc() - if round(ob.LocZ, 5)!=round(LZC, 5): - for bez in ipoLocZ.bezierPoints: - if round(bez.pt[0], tr)==frameCtr: - bez.pt = [frameCr, vect[2]] - ipoLocZ.recalc() - - #change trajectory color if at an ipoKey - VertexFrame=[] - bezier_Coord=0 - if ipoLocX: # FIXED like others it was just in case ipoLocX==None - for bez in ipoLocX.bezierPoints: - bezier_Coord=round(bez.pt[0], tr) - if bezier_Coord not in VertexFrame: - VertexFrame.append(bezier_Coord) - if bezier_Coord==frameCtr: - color=[1, color[1]-0.3] - if ipoLocY: # FIXED - for bez in ipoLocY.bezierPoints: - bezier_Coord=round(bez.pt[0], tr) - if bezier_Coord not in VertexFrame: - VertexFrame.append(bezier_Coord) - if round(bez.pt[0], tr)==frameCtr: - color=[1, color[1]-0.3] - if ipoLocZ: # FIXED - for bez in ipoLocZ.bezierPoints: - bezier_Coord=round(bez.pt[0], tr) - if bezier_Coord not in VertexFrame: - VertexFrame.append(bezier_Coord) - if round(bez.pt[0], tr)==frameCtr: - color=[1, color[1]-0.3] - - - #put in LocX, LocY and LocZ all points of trajectory - for frame in xrange(frameC-past, frameC+future): - DecMat=matrixForTraj(frame, parent_list) - - if ipoLocX: LX= ipoLocX[frame] - else: LX= ob.LocX - if ipoLocY: LY= ipoLocY[frame] - else: LY= ob.LocY - if ipoLocZ: LZ= ipoLocZ[frame] - else: LZ= ob.LocZ - - vect=Vector(LX, LY, LZ)*DecMat - LocX.append(vect[0]) - LocY.append(vect[1]) - LocZ.append(vect[2]) - - - #draw part : get current view - MatPreBuff= [matview[i][j] for i in xrange(4) for j in xrange(4)] - - MatBuff=BGL.Buffer(GL_FLOAT, 16, MatPreBuff) - - glLoadIdentity() - glMatrixMode(GL_PROJECTION) - glPushMatrix() - glLoadMatrixf(MatBuff) - - #draw trajectory line - glLineWidth("""+str(width)+""") - - glBegin(GL_LINE_STRIP) - for i in xrange(len(LocX)): - glColor3f((i+1)*1.00/len(LocX)*color[0], 0, (i+1)*1.00/len(LocX)*color[1]) - glVertex3f(LocX[i], LocY[i], LocZ[i]) - - glEnd() - - #draw trajectory's "vertexs" - if not Blender.Window.EditMode(): - glPointSize(5) - glBegin(GL_POINTS) - TestPOINTS=[] - TestFRAME=[] - i=0 - for frame in VertexFrame: - ix=int(frame)-frameC+past - if ix>=0 and ixpt[0]-4 and mouse_co[1]>pt[1]-4 and mouse_co[1]R and R>L can use the same code - def IS_XMIRROR_SOURCE(xval): - '''Source means is this the value we want to copy from''' - - if PREF_MODE_L2R: - if xval<0: return True - else: return False - else: # PREF_MODE_R2L - if xval<0: return False - else: return True - - if IS_XMIRROR_SOURCE( h1.x ):# head bone 1s negative, so copy it to h2 - editbone2.head= VecXFlip(h1) - else: - ''' - assume h2.x<0 - not a big deal if were wrong, - its unlikely to ever happen because the bones would both be on the same side. - ''' - - # head bone 2s negative, so copy it to h1 - editbone1.head= VecXFlip(h2) - - # Same as above for tail - if IS_XMIRROR_SOURCE(t1.x): - editbone2.tail= VecXFlip(t1) - else: - editbone1.tail= VecXFlip(t2) - - # Copy roll from 1 bone to another, use the head's location to decide which side it's on. - if IS_XMIRROR_SOURCE(editbone1.head): - editbone2.roll= -editbone1.roll - else: - editbone1.roll= -editbone2.roll - - -def armature_symetry(\ - arm_ob,\ - PREF_MAX_DIST,\ - PREF_XMID_SNAP,\ - PREF_XZERO_THRESH,\ - PREF_MODE_L2R,\ - PREF_MODE_R2L,\ - PREF_SEL_ONLY): - - ''' - Main function that does all the work, - return the number of - ''' - arm_data= arm_ob.data - arm_data.makeEditable() - - # Get the bones - bones= [] - HIDDEN_EDIT= Blender.Armature.HIDDEN_EDIT - BONE_SELECTED= Blender.Armature.BONE_SELECTED - - if PREF_SEL_ONLY: - for eb in arm_data.bones.values(): - options= eb.options - if HIDDEN_EDIT not in options and BONE_SELECTED in options: - bones.append(eb) - else: - # All non hidden bones - for eb in arm_data.bones.values(): - options= eb.options - if HIDDEN_EDIT not in options: - bones.append(eb) - - del HIDDEN_EDIT # remove temp variables - del BONE_SELECTED - - # Store the numder of bones we have modified for a message - tot_editbones= len(bones) - tot_editbones_modified= 0 - - if PREF_XMID_SNAP: - # Remove bones that are in the middle (X Zero) - # reverse loop so we can remove items in the list. - for eb_idx in xrange(len(bones)-1, -1, -1): - edit_bone= bones[eb_idx] - if abs(edit_bone.head.x) + abs(edit_bone.tail.x) <= PREF_XZERO_THRESH/2: - - # This is a center bone, clamp and remove from the bone list so we dont use again. - if edit_bone.tail.x or edit_bone.head.x: - tot_editbones_modified += 1 - - edit_bone.tail.x= edit_bone.head.x= 0 - del bones[eb_idx] - - - - - bone_comparisons= [] - - # Compare every bone with every other bone, shouldn't be too slow. - # These 2 "for" loops only compare once - for eb_idx_a in xrange(len(bones)-1, -1, -1): - edit_bone_a= bones[eb_idx_a] - for eb_idx_b in xrange(eb_idx_a-1, -1, -1): - edit_bone_b= bones[eb_idx_b] - # Error float the first value from editbone_mirror_diff() so we can sort the resulting list. - bone_comparisons.append(editbone_mirror_diff(edit_bone_a, edit_bone_b)) - - - bone_comparisons.sort() # best matches first - - # Make a dict() of bone names that have been used so we dont mirror more then once - bone_mirrored= {} - - for error, editbone1, editbone2 in bone_comparisons: - # print 'Trying to merge at error %.3f' % error - if error > PREF_MAX_DIST: - # print 'breaking, max error limit reached PREF_MAX_DIST: %.3f' % PREF_MAX_DIST - break - - if not bone_mirrored.has_key(editbone1.name) and not bone_mirrored.has_key(editbone2.name): - # Were not used, execute the mirror - editbone_mirror_merge(editbone1, editbone2, PREF_MODE_L2R, PREF_MODE_R2L) - # print 'Merging bones' - - # Add ourselves so we aren't touched again - bone_mirrored[editbone1.name] = None # dummy value, would use sets in python 2.4 - bone_mirrored[editbone2.name] = None - - # If both options are enabled, then we have changed 2 bones - tot_editbones_modified+= PREF_MODE_L2R + PREF_MODE_R2L - - arm_data.update() # get out of armature editmode - return tot_editbones, tot_editbones_modified - - -def main(): - ''' - User interface function that gets the options and calls armature_symetry() - ''' - - scn= bpy.data.scenes.active - arm_ob= scn.objects.active - - if not arm_ob or arm_ob.type!='Armature': - Blender.Draw.PupMenu('No Armature object selected.') - return - - # Cant be in editmode for armature.makeEditable() - is_editmode= Blender.Window.EditMode() - if is_editmode: Blender.Window.EditMode(0) - Draw= Blender.Draw - - # Defaults for the user input - PREF_XMID_SNAP= Draw.Create(1) - PREF_MAX_DIST= Draw.Create(0.4) - PREF_XZERO_THRESH= Draw.Create(0.02) - - PREF_MODE_L2R= Draw.Create(1) - PREF_MODE_R2L= Draw.Create(0) - PREF_SEL_ONLY= Draw.Create(1) - - pup_block = [\ - 'Left (-), Right (+)',\ - ('Left > Right', PREF_MODE_L2R, 'Copy from the Left to Right of the mesh. Enable Both for a mid loc.'),\ - ('Right > Left', PREF_MODE_R2L, 'Copy from the Right to Left of the mesh. Enable Both for a mid loc.'),\ - '',\ - ('MaxDist:', PREF_MAX_DIST, 0.0, 4.0, 'Maximum difference in mirror bones to match up pairs.'),\ - ('XZero limit:', PREF_XZERO_THRESH, 0.0, 2.0, 'Tolerance for locking bones into the middle (X/zero).'),\ - ('XMidSnap Bones', PREF_XMID_SNAP, 'Snap middle verts to X Zero (uses XZero limit)'),\ - ('Selected Only', PREF_SEL_ONLY, 'Only xmirror selected bones.'),\ - ] - - # Popup, exit if the user doesn't click OK - if not Draw.PupBlock("X Mirror mesh tool", pup_block): - return - - # Replace the variables with their button values. - PREF_XMID_SNAP= PREF_XMID_SNAP.val - PREF_MAX_DIST= PREF_MAX_DIST.val - PREF_MODE_L2R= PREF_MODE_L2R.val - PREF_MODE_R2L= PREF_MODE_R2L.val - PREF_XZERO_THRESH= PREF_XZERO_THRESH.val - PREF_SEL_ONLY= PREF_SEL_ONLY.val - - # If both are off assume mid-point and enable both - if not PREF_MODE_R2L and not PREF_MODE_L2R: - PREF_MODE_R2L= PREF_MODE_L2R= True - - - tot_editbones, tot_editbones_modified = armature_symetry(\ - arm_ob,\ - PREF_MAX_DIST,\ - PREF_XMID_SNAP,\ - PREF_XZERO_THRESH,\ - PREF_MODE_L2R,\ - PREF_MODE_R2L,\ - PREF_SEL_ONLY) - - if is_editmode: Blender.Window.EditMode(1) - - # Redraw all views before popup - Blender.Window.RedrawAll() - - # Print results - if PREF_SEL_ONLY: - msg= 'moved %i bones of %i selected' % (tot_editbones_modified, tot_editbones) - else: - msg= 'moved %i bones of %i visible' % (tot_editbones_modified, tot_editbones) - - - Blender.Draw.PupMenu(msg) - -# Check for __main__ so this function can be imported by other scripts without running the script. -if __name__=='__main__': - main() diff --git a/release/scripts/bevel_center.py b/release/scripts/bevel_center.py deleted file mode 100644 index 637ed08127f..00000000000 --- a/release/scripts/bevel_center.py +++ /dev/null @@ -1,474 +0,0 @@ -#!BPY -# -*- coding: utf-8 -*- -""" Registration info for Blender menus -Name: 'Bevel Center' -Blender: 243 -Group: 'Mesh' -Tip: 'Bevel selected faces, edges, and vertices' -""" - -__author__ = "Loic BERTHE" -__url__ = ("blender", "blenderartists.org") -__version__ = "2.0" - -__bpydoc__ = """\ -This script implements vertex and edges bevelling in Blender. - -Usage: - -Select the mesh you want to work on, enter Edit Mode and select the edges -to bevel. Then run this script from the 3d View's Mesh->Scripts menu. - -You can control the thickness of the bevel with the slider -- redefine the -end points for bigger or smaller ranges. The thickness can be changed even -after applying the bevel, as many times as needed. - -For an extra smoothing after or instead of direct bevel, set the level of -recursiveness and use the "Recursive" button. - -This "Recursive" Button, won't work in face select mode, unless you choose -"faces" in the select mode menu. - -Notes:
- You can undo and redo your steps just like with normal mesh operations in -Blender. -""" - -###################################################################### -# Bevel Center v2.0 for Blender - -# This script lets you bevel the selected vertices or edges and control the -# thickness of the bevel - -# (c) 2004-2006 Loïc Berthe (loic+blender@lilotux.net) -# released under Blender Artistic License - -###################################################################### - -import Blender -from Blender import NMesh, Window, Scene -from Blender.Draw import * -from Blender.Mathutils import * -from Blender.BGL import * -import BPyMessages -#PY23 NO SETS# -''' -try: - set() -except: - from sets import set -''' - -###################################################################### -# Functions to handle the global structures of the script NF, NE and NC -# which contain informations about faces and corners to be created - -global E_selected -E_selected = NMesh.EdgeFlags['SELECT'] - -old_dist = None - -def act_mesh_ob(): - scn = Scene.GetCurrent() - ob = scn.objects.active - if ob == None or ob.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - if ob.getData(mesh=1).multires: - BPyMessages.Error_NoMeshMultiresEdit() - return - - return ob - -def make_sel_vert(*co): - v= NMesh.Vert(*co) - v.sel = 1 - me.verts.append(v) - return v - -def make_sel_face(verts): - f = NMesh.Face(verts) - f.sel = 1 - me.addFace(f) - -def add_to_NV(old,dir,new): - try: - NV[old][dir] = new - except: - NV[old] = {dir:new} - -def get_v(old, *neighbors): - # compute the direction of the new vert - if len(neighbors) == 1: dir = (neighbors[0].co - old.co).normalize() - #dir - else: dir = (neighbors[0].co - old.co).normalize() + (neighbors[1].co-old.co).normalize() - - # look in NV if this vert already exists - key = tuple(dir) - if old in NV and key in NV[old] : return NV[old][key] - - # else, create it - new = old.co + dist.val*dir - v = make_sel_vert(new.x,new.y,new.z) - add_to_NV(old,key,v) - return v - -def make_faces(): - """ Analyse the mesh, make the faces corresponding to selected faces and - fill the structures NE and NC """ - - # make the differents flags consistent - for e in me.edges: - if e.flag & E_selected : - e.v1.sel = 1 - e.v2.sel = 1 - - NF =[] # NF : New faces - for f in me.faces: - V = f.v - nV = len(V) - enumV = range(nV) - E = [me.findEdge(V[i],V[(i+1) % nV]) for i in enumV] - Esel = [x.flag & E_selected for x in E] - - # look for selected vertices and creates a list containing the new vertices - newV = V[:] - changes = False - for (i,v) in enumerate(V): - if v.sel : - changes = True - if Esel[i-1] == 0 and Esel[i] == 1 : newV[i] = get_v(v,V[i-1]) - elif Esel[i-1] == 1 and Esel[i] == 0 : newV[i] = get_v(v,V[(i+1) % nV]) - elif Esel[i-1] == 1 and Esel[i] == 1 : newV[i] = get_v(v,V[i-1],V[(i+1) % nV]) - else : newV[i] = [get_v(v,V[i-1]),get_v(v,V[(i+1) % nV])] - - if changes: - # determine and store the face to be created - - lenV = [len(x) for x in newV] - if 2 not in lenV : - new_f = NMesh.Face(newV) - if sum(Esel) == nV : new_f.sel = 1 - NF.append(new_f) - - else : - nb2 = lenV.count(2) - - if nV == 4 : # f is a quad - if nb2 == 1 : - ind2 = lenV.index(2) - NF.append(NMesh.Face([newV[ind2-1],newV[ind2][0],newV[ind2][1],newV[ind2-3]])) - NF.append(NMesh.Face([newV[ind2-1],newV[ind2-2],newV[ind2-3]])) - - elif nb2 == 2 : - # We must know if the tuples are neighbours - ind2 = ''.join([str(x) for x in lenV+lenV[:1]]).find('22') - - if ind2 != -1 : # They are - NF.append(NMesh.Face([newV[ind2][0],newV[ind2][1],newV[ind2-3][0],newV[ind2-3][1]])) - NF.append(NMesh.Face([newV[ind2][0],newV[ind2-1],newV[ind2-2],newV[ind2-3][1]])) - - else: # They aren't - ind2 = lenV.index(2) - NF.append(NMesh.Face([newV[ind2][0],newV[ind2][1],newV[ind2-2][0],newV[ind2-2][1]])) - NF.append(NMesh.Face([newV[ind2][1],newV[ind2-3],newV[ind2-2][0]])) - NF.append(NMesh.Face([newV[ind2][0],newV[ind2-1],newV[ind2-2][1]])) - - elif nb2 == 3 : - ind2 = lenV.index(3) - NF.append(NMesh.Face([newV[ind2-1][1],newV[ind2],newV[ind2-3][0]])) - NF.append(NMesh.Face([newV[ind2-1][0],newV[ind2-1][1],newV[ind2-3][0],newV[ind2-3][1]])) - NF.append(NMesh.Face([newV[ind2-3][1],newV[ind2-2][0],newV[ind2-2][1],newV[ind2-1][0]])) - - else: - if (newV[0][1].co-newV[3][0].co).length + (newV[1][0].co-newV[2][1].co).length \ - < (newV[0][0].co-newV[1][1].co).length + (newV[2][0].co-newV[3][1].co).length : - ind2 = 0 - else : - ind2 = 1 - NF.append(NMesh.Face([newV[ind2-1][0],newV[ind2-1][1],newV[ind2][0],newV[ind2][1]])) - NF.append(NMesh.Face([newV[ind2][1],newV[ind2-3][0],newV[ind2-2][1],newV[ind2-1][0]])) - NF.append(NMesh.Face([newV[ind2-3][0],newV[ind2-3][1],newV[ind2-2][0],newV[ind2-2][1]])) - - else : # f is a tri - if nb2 == 1: - ind2 = lenV.index(2) - NF.append(NMesh.Face([newV[ind2-2],newV[ind2-1],newV[ind2][0],newV[ind2][1]])) - - elif nb2 == 2: - ind2 = lenV.index(3) - NF.append(NMesh.Face([newV[ind2-1][1],newV[ind2],newV[ind2-2][0]])) - NF.append(NMesh.Face([newV[ind2-2][0],newV[ind2-2][1],newV[ind2-1][0],newV[ind2-1][1]])) - - else: - ind2 = min( [((newV[i][1].co-newV[i-1][0].co).length, i) for i in enumV] )[1] - NF.append(NMesh.Face([newV[ind2-1][1],newV[ind2][0],newV[ind2][1],newV[ind2-2][0]])) - NF.append(NMesh.Face([newV[ind2-2][0],newV[ind2-2][1],newV[ind2-1][0],newV[ind2-1][1]])) - - # Preparing the corners - for i in enumV: - if lenV[i] == 2 : NC.setdefault(V[i],[]).append(newV[i]) - - - old_faces.append(f) - - # Preparing the Edges - for i in enumV: - if Esel[i]: - verts = [newV[i],newV[(i+1) % nV]] - if V[i].index > V[(i+1) % nV].index : verts.reverse() - NE.setdefault(E[i],[]).append(verts) - - # Create the faces - for f in NF: me.addFace(f) - -def make_edges(): - """ Make the faces corresponding to selected edges """ - - for old,new in NE.iteritems() : - if len(new) == 1 : # This edge was on a border - oldv = [old.v1, old.v2] - if old.v1.index < old.v2.index : oldv.reverse() - - make_sel_face(oldv+new[0]) - - me.findEdge(*oldv).flag |= E_selected - me.findEdge(*new[0]).flag |= E_selected - - #PY23 NO SETS# for v in oldv : NV_ext.add(v) - for v in oldv : NV_ext[v]= None - - else: - make_sel_face(new[0] + new[1][::-1]) - - me.findEdge(*new[0]).flag |= E_selected - me.findEdge(*new[1]).flag |= E_selected - -def make_corners(): - """ Make the faces corresponding to corners """ - - for v in NV.iterkeys(): - V = NV[v].values() - nV = len(V) - - if nV == 1: pass - - elif nV == 2 : - #PY23 NO SETS# if v in NV_ext: - if v in NV_ext.iterkeys(): - make_sel_face(V+[v]) - me.findEdge(*V).flag |= E_selected - - else: - #PY23 NO SETS# if nV == 3 and v not in NV_ext : make_sel_face(V) - if nV == 3 and v not in NV_ext.iterkeys() : make_sel_face(V) - - - else : - - # We need to know which are the edges around the corner. - # First, we look for the quads surrounding the corner. - eed = [] - for old, new in NE.iteritems(): - if v in (old.v1,old.v2) : - if v.index == min(old.v1.index,old.v2.index) : ind = 0 - else : ind = 1 - - if len(new) == 1: eed.append([v,new[0][ind]]) - else : eed.append([new[0][ind],new[1][ind]]) - - # We will add the edges coming from faces where only one vertice is selected. - # They are stored in NC. - if v in NC: eed = eed+NC[v] - - # Now we have to sort these vertices - hc = {} - for (a,b) in eed : - hc.setdefault(a,[]).append(b) - hc.setdefault(b,[]).append(a) - - for x0,edges in hc.iteritems(): - if len(edges) == 1 : break - - b = [x0] # b will contain the sorted list of vertices - - for i in xrange(len(hc)-1): - for x in hc[x0] : - if x not in b : break - b.append(x) - x0 = x - - b.append(b[0]) - - # Now we can create the faces - if len(b) == 5: make_sel_face(b[:4]) - - else: - New_V = Vector(0.0, 0.0,0.0) - New_d = [0.0, 0.0,0.0] - - for x in hc.iterkeys(): New_V += x.co - for dir in NV[v] : - for i in xrange(3): New_d[i] += dir[i] - - New_V *= 1./len(hc) - for i in xrange(3) : New_d[i] /= nV - - center = make_sel_vert(New_V.x,New_V.y,New_V.z) - add_to_NV(v,tuple(New_d),center) - - for k in xrange(len(b)-1): make_sel_face([center, b[k], b[k+1]]) - - if 2 < nV and v in NC : - for edge in NC[v] : me.findEdge(*edge).flag |= E_selected - -def clear_old(): - """ Erase old faces and vertices """ - - for f in old_faces: me.removeFace(f) - - for v in NV.iterkeys(): - #PY23 NO SETS# if v not in NV_ext : me.verts.remove(v) - if v not in NV_ext.iterkeys() : me.verts.remove(v) - - for e in me.edges: - if e.flag & E_selected : - e.v1.sel = 1 - e.v2.sel = 1 - - -###################################################################### -# Interface - -global dist - -dist = Create(0.2) -left = Create(0.0) -right = Create(1.0) -num = Create(2) - -# Events -EVENT_NOEVENT = 1 -EVENT_BEVEL = 2 -EVENT_UPDATE = 3 -EVENT_RECURS = 4 -EVENT_EXIT = 5 - -def draw(): - global dist, left, right, num, old_dist - global EVENT_NOEVENT, EVENT_BEVEL, EVENT_UPDATE, EVENT_RECURS, EVENT_EXIT - - glClear(GL_COLOR_BUFFER_BIT) - Button("Bevel",EVENT_BEVEL,10,100,280,25) - - BeginAlign() - left=Number('', EVENT_NOEVENT,10,70,45, 20,left.val,0,right.val,'Set the minimum of the slider') - dist=Slider("Thickness ",EVENT_UPDATE,60,70,180,20,dist.val,left.val,right.val,0, \ - "Thickness of the bevel, can be changed even after bevelling") - right = Number("",EVENT_NOEVENT,245,70,45,20,right.val,left.val,200,"Set the maximum of the slider") - - EndAlign() - glRasterPos2d(8,40) - Text('To finish, you can use recursive bevel to smooth it') - - - if old_dist != None: - num=Number('', EVENT_NOEVENT,10,10,40, 16,num.val,1,100,'Recursion level') - Button("Recursive",EVENT_RECURS,55,10,100,16) - - Button("Exit",EVENT_EXIT,210,10,80,20) - -def event(evt, val): - if ((evt == QKEY or evt == ESCKEY) and not val): Exit() - -def bevent(evt): - if evt == EVENT_EXIT : Exit() - elif evt == EVENT_BEVEL : bevel() - elif evt == EVENT_UPDATE : - try: bevel_update() - except NameError : pass - elif evt == EVENT_RECURS : recursive() - -Register(draw, event, bevent) - -###################################################################### -def bevel(): - """ The main function, which creates the bevel """ - global me,NV,NV_ext,NE,NC, old_faces,old_dist - - ob = act_mesh_ob() - if not ob: return - - Window.WaitCursor(1) # Change the Cursor - t= Blender.sys.time() - is_editmode = Window.EditMode() - if is_editmode: Window.EditMode(0) - - me = ob.data - - NV = {} - #PY23 NO SETS# NV_ext = set() - NV_ext= {} - NE = {} - NC = {} - old_faces = [] - - make_faces() - make_edges() - make_corners() - clear_old() - - old_dist = dist.val - print '\tbevel in %.6f sec' % (Blender.sys.time()-t) - me.update(1) - if is_editmode: Window.EditMode(1) - Window.WaitCursor(0) - Blender.Redraw() - -def bevel_update(): - """ Use NV to update the bevel """ - global dist, old_dist - - if old_dist == None: - # PupMenu('Error%t|Must bevel first.') - return - - is_editmode = Window.EditMode() - if is_editmode: Window.EditMode(0) - - fac = dist.val - old_dist - old_dist = dist.val - - for old_v in NV.iterkeys(): - for dir in NV[old_v].iterkeys(): - for i in xrange(3): - NV[old_v][dir].co[i] += fac*dir[i] - - me.update(1) - if is_editmode: Window.EditMode(1) - Blender.Redraw() - -def recursive(): - """ Make a recursive bevel... still experimental """ - global dist - from math import pi, sin - - if num.val > 1: - a = pi/4 - ang = [] - for k in xrange(num.val): - ang.append(a) - a = (pi+2*a)/4 - - l = [2*(1-sin(x))/sin(2*x) for x in ang] - R = dist.val/sum(l) - l = [x*R for x in l] - - dist.val = l[0] - bevel_update() - - for x in l[1:]: - dist.val = x - bevel() - diff --git a/release/scripts/blenderLipSynchro.py b/release/scripts/blenderLipSynchro.py deleted file mode 100644 index c4815811512..00000000000 --- a/release/scripts/blenderLipSynchro.py +++ /dev/null @@ -1,729 +0,0 @@ -#!BPY -# coding: utf-8 -""" -Name: 'BlenderLipSynchro' -Blender: 242 -Group: 'Animation' -Tooltip: 'Import phonemes from Papagayo or JLipSync for lip synchronization' -""" - -__author__ = "Dienben: Benoit Foucque dienben_mail@yahoo.fr" -__url__ = ["blenderLipSynchro Blog, http://blenderlipsynchro.blogspot.com/", -"Papagayo (Python), http://www.lostmarble.com/papagayo/index.shtml", -"JLipSync (Java), http://jlipsync.sourceforge.net/"] -__version__ = "2.0" -__bpydoc__ = """\ -Description: - -This script imports Voice Export made by Papagayo or JLipSync and maps the export with your shapes. - -Usage: - -Import a Papagayo or JLipSync voice export file and link it with your shapes. - -Note:
-- Naturally, you need files exported from one of the supported lip synching -programs. Check their sites to learn more and download them. - -""" - -# -------------------------------------------------------------------------- -# BlenderLipSynchro -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - - -#il y a 3 etapes -#la deuxieme on charge le dictionnaire de correspondance -#la troisieme on fait le choix des correpondance -#la quatrieme on construit les cles a partir du fichiers frame - -#there are 3 stages -#the second one load the mapping dictionnary -#the tird make the mapping -#the fourth make the key in the IPO Curve - -#voici mes differents imports -#the imports -import os -import Blender - -from Blender import Ipo -from Blender.Draw import * -from Blender.BGL import * -from Blender.sys import basename - - - -#ici commencent mes fonctions -#here begin my functions -#cette fonction trace l'interface graphique -#this functions draw the User interface -def trace(): - #voici mes variables pouvant etre modifie - #my variables - global nbr_phoneme, mon_fichier_dico - global let01, let02, let03, let04,let05, let06, let07, let08, let09, let10 - global let11, let12, let13, let14,let15, let16, let17, let18, let19, let20 - global let21, let22, let23, let24 - - global let01selectkey,let02selectkey,let03selectkey,let04selectkey,let05selectkey - global let06selectkey,let07selectkey,let08selectkey,let09selectkey,let10selectkey,let11selectkey - global let12selectkey,let13selectkey,let14selectkey,let15selectkey,let16selectkey,let17selectkey - global let18selectkey,let19selectkey,let20selectkey,let21selectkey,let22selectkey,let23selectkey - global let24selectkey - - glClearColor(0.4,0.5,0.6 ,0.0) - glClear(GL_COLOR_BUFFER_BIT) - - glColor3d(1,1,1) - glRasterPos2i(87, 375) - Text("Blendersynchro V 2.0") - glColor3d(1,1,1) - glRasterPos2i(84, 360) - Text("Programming: Dienben") - - glColor3d(0,0,0) - glRasterPos2i(13, 342) - Text("Lip Synchronization Tool") - glColor3d(0,0,0) - glRasterPos2i(13, 326) - Text("Thanks to Chris Clawson and Liubomir Kovatchev") - - glColor3d(1,1,1) - glRasterPos2i(5, 320) - Text("_______________________________________________________") - glColor3d(0,0,0) - glRasterPos2i(6, 318) - Text("_______________________________________________________") - - - if (etape==1): - #cette etape permet de choisi la correspondance entre les phonemes et les cles - #this stage offer the possibility to choose the mapping between phonems and shapes - - glColor3d(1,1,1) - glRasterPos2i(140, 300) - Text("Objet: "+Blender.Object.GetSelected()[0].getName() ) - - glColor3d(1,1,1) - glRasterPos2i(5, 215) - Text("Assign phonems to shapes:") - - #on mesure la taille de la liste de phonemes - #this is the lenght of the phonem list - nbr_phoneme=len(liste_phoneme) - - #on dessine les listes de choix - #we draw the choice list - - # - if (nbr_phoneme > 0): - let01 = String(" ", 4, 5, 185, 30, 16, liste_phoneme[0], 3) - glColor3d(0,0,0) - glRasterPos2i(40, 188) - Text("=") - let01selectkey = Menu(key_menu, 50, 50, 185, 70, 16, let01selectkey.val) - - # - if (nbr_phoneme > 1): - let02 = String(" ", 4, 150, 185, 30, 16, liste_phoneme[1], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 188) - Text("=") - let02selectkey = Menu(key_menu, 51, 195, 185, 70, 16, let02selectkey.val) - - # - if (nbr_phoneme > 2): - let03 = String(" ", 4, 5, 165, 30, 16, liste_phoneme[2], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 168) - Text("=") - let03selectkey = Menu(key_menu, 52, 50, 165, 70, 16, let03selectkey.val) - - # - if (nbr_phoneme > 3): - let04 = String(" ", 4, 150, 165, 30, 16, liste_phoneme[3], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 168) - Text("=") - let04selectkey = Menu(key_menu, 53, 195, 165, 70, 16, let04selectkey.val) - - # - if (nbr_phoneme > 4): - let05 = String(" ", 4, 5, 145, 30, 16, liste_phoneme[4], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 148) - Text("=") - let05selectkey = Menu(key_menu, 54, 50, 145, 70, 16, let05selectkey.val) - - # - if (nbr_phoneme > 5): - let06 = String(" ", 4, 150, 145, 30, 16, liste_phoneme[5], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 148) - Text("=") - let06selectkey = Menu(key_menu, 55, 195, 145, 70, 16, let06selectkey.val) - - # - if (nbr_phoneme > 6): - let07 = String(" ", 4, 5, 125, 30, 16, liste_phoneme[6], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 128) - Text("=") - let07selectkey = Menu(key_menu, 56, 50, 125, 70, 16, let07selectkey.val) - - # - if (nbr_phoneme > 7): - let08 = String(" ", 4, 150, 125, 30, 16, liste_phoneme[7], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 128) - Text("=") - let08selectkey = Menu(key_menu, 57, 195, 125, 70, 16,let08selectkey.val) - - # - if (nbr_phoneme > 8): - let09 = String(" ", 4, 5, 105, 30, 16, liste_phoneme[8], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 108) - Text("=") - let09selectkey = Menu(key_menu, 58, 50, 105, 70, 16,let09selectkey.val) - - # - if (nbr_phoneme > 9): - let10 = String(" ", 4, 150, 105, 30, 16, liste_phoneme[9], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 108) - Text("=") - let10selectkey = Menu(key_menu, 59, 195, 105, 70, 16, let10selectkey.val) - - # - if (nbr_phoneme > 10): - let11 = String(" ", 4, 5, 85, 30, 16, liste_phoneme[10], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 88) - Text("=") - let11selectkey = Menu(key_menu, 60, 50, 85, 70, 16, let11selectkey.val) - - # - if (nbr_phoneme > 11): - let12 = String(" ", 4, 150, 85, 30, 16, liste_phoneme[11], 2) - glColor3d(0,0,0) - Text("=") - let12selectkey = Menu(key_menu, 61, 195, 85, 70, 16, let12selectkey.val) - - # - if (nbr_phoneme > 12): - let13 = String(" ", 4, 5, 65, 30, 16, liste_phoneme[12], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 68) - Text("=") - let13selectkey = Menu(key_menu, 62, 50, 65, 70, 16, let13selectkey.val) - - # - if (nbr_phoneme > 13): - let14 = String(" ", 4, 150, 65, 30, 16, liste_phoneme[13], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 68) - Text("=") - let14selectkey = Menu(key_menu, 63, 195, 65, 70, 16, let14selectkey.val) - - # - if (nbr_phoneme > 14): - let15 = String(" ", 4, 5, 45, 30, 16, liste_phoneme[14], 2) - glColor3d(0,0,0) - glRasterPos2i(40, 48) - Text("=") - let15selectkey = Menu(key_menu, 64, 50, 45, 70, 16, let15selectkey.val) - - # - if (nbr_phoneme > 15): - let16 = String(" ", 4, 150, 45, 30, 16, liste_phoneme[15], 2) - glColor3d(0,0,0) - glRasterPos2i(185, 48) - Text("=") - let16selectkey = Menu(key_menu, 65, 195, 45, 70, 16, let16selectkey.val) - - # - if (nbr_phoneme > 16): - let17 = String(" ", 4, 295, 185, 30, 16, liste_phoneme[16], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 188) - Text("=") - let17selectkey = Menu(key_menu, 66, 340, 185, 70, 16, let17selectkey.val) - - # - if (nbr_phoneme > 17): - let18 = String(" ", 4, 440, 185, 70, 16, liste_phoneme[17], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 188) - Text("=") - let18selectkey = Menu(key_menu, 67, 525, 185, 70, 16, let18selectkey.val) - - # - if (nbr_phoneme > 18): - let19 = String(" ", 4, 295, 165, 30, 16, liste_phoneme[18], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 168) - Text("=") - let19selectkey = Menu(key_menu, 68, 340, 165, 70, 16, let19selectkey.val) - - # - if (nbr_phoneme > 19): - let20 = String(" ", 4, 440, 165, 70, 16, liste_phoneme[19], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 168) - Text("=") - let20selectkey = Menu(key_menu, 69, 525, 165, 70, 16, let20selectkey.val) - - # - if (nbr_phoneme > 20): - let21 = String(" ", 4, 295, 145, 30, 16, liste_phoneme[20], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 148) - Text("=") - let21selectkey = Menu(key_menu, 70, 340, 145, 70, 16, let21selectkey.val) - - # - if (nbr_phoneme > 21): - let22 = String(" ", 4, 440, 145, 70, 16, liste_phoneme[21], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 148) - Text("=") - let22selectkey = Menu(key_menu, 71, 525, 145, 70, 16, let22selectkey.val) - - # - if (nbr_phoneme > 22): - let23 = String(" ", 4, 295, 125, 30, 16, liste_phoneme[22], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 128) - Text("=") - let23selectkey = Menu(key_menu, 72, 340, 125, 70, 16,let23selectkey.val) - - # - if (nbr_phoneme > 23): - let24 = String(" ", 4, 440, 125, 70, 16, liste_phoneme[23], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 128) - Text("=") - let24selectkey = Menu(key_menu, 73, 525, 125, 70, 16, let24selectkey.val) - - # - if (nbr_phoneme > 24): - let25 = String(" ", 4, 295, 105, 30, 16, liste_phoneme[24], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 108) - Text("=") - let25selectkey = Menu(key_menu, 74, 340, 105, 70, 16, let25selectkey.val) - - # - if (nbr_phoneme > 25): - let26 = String(" ", 4, 440, 105, 70, 16, liste_phoneme[25], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 108) - Text("=") - let26selectkey = Menu(key_menu, 75, 525, 105, 70, 16,let26selectkey.val) - - # - if (nbr_phoneme > 26): - let27 = String(" ", 4, 295, 85, 30, 16, liste_phoneme[26], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 88) - Text("=") - let27selectkey = Menu(key_menu, 76, 340, 85, 70, 16, let27selectkey.val) - - # - if (nbr_phoneme > 27): - let28 = String(" ", 4, 440, 85, 70, 16, liste_phoneme[27], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 88) - Text("=") - let28selectkey = Menu(key_menu, 77, 525, 85, 70, 16,let28selectkey.val) - - # - if (nbr_phoneme > 28): - let29 = String(" ", 4, 295, 65, 30, 16, liste_phoneme[28], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 68) - Text("=") - let29selectkey = Menu(key_menu, 78, 340, 65, 70, 16, let29selectkey.val) - - # - if (nbr_phoneme > 29): - let30 = String(" ", 4, 440, 65, 70, 16, liste_phoneme[29], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 68) - Text("=") - let30selectkey = Menu(key_menu, 79, 525, 65, 70, 16, let30selectkey.val) - - # - if (nbr_phoneme > 30): - let31 = String(" ", 4, 295, 45, 30, 16, liste_phoneme[30], 2) - glColor3d(0,0,0) - glRasterPos2i(330, 48) - Text("=") - let31selectkey = Menu(key_menu, 80, 340, 45, 70, 16, let31selectkey.val) - - # - if (nbr_phoneme > 31): - let32 = String(" ", 4, 440, 45, 70, 16, liste_phoneme[31], 8) - glColor3d(0,0,0) - glRasterPos2i(515, 48) - Text("=") - let32selectkey = Menu(key_menu, 81, 525, 45, 70, 16, let32selectkey.val) - - Button("Go", 3, 155, 5, 145, 22) - - if (etape==2): - glColor3d(1,1,1) - glRasterPos2i(125, 200) - Text("Operation Completed") - - if (etape==0): - glColor3d(1,1,1) - glRasterPos2i(125, 200) - Text("Please select a Mesh'Object and Create all the IPO Curves for your Shapes") - - if (etape==3): - #this stage permits to load a custom dictionnary - load_file_text = "Load File" - if mon_fichier_dico: - Button("Import Loaded File", 2, 5, 5, 145, 22) - glColor3d(1,1,1) - glRasterPos2i(6, 50) - Text("loaded file: %s" % basename(mon_fichier_dico)) - load_file_text = "Choose Another File" - Button(load_file_text, 8, 125, 180, 145, 22) - - glRasterPos2i(6, 40) - Text("_______________________________________________________") - glColor3d(0,0,0) - glRasterPos2i(6, 38) - Text("_______________________________________________________") - - Button("Exit", 1, 305, 5, 80, 22) - - - -#cette fonction sur evenement quite en cas d'ESC -#this functions catch the ESC event and quit -def event(evt,val): - if (evt == ESCKEY and not val): Exit() - -#cette fonction gere les evenements -#the event functions -def bevent(evt): - global etape,soft_type,liste_phoneme,dico_phoneme_export - - if (evt == 1): - Exit() - - elif (evt == 2): - #c'est l'import du dictionnaire - #we create and import the dictionnary - lecture_chaine(mon_fichier_dico,dico_phoneme_export) - construction_dictionnaire_phoneme() - #we change the stage - etape=1 - - elif (evt == 3): - #c'est l'import - #we import - lecture_chaine(mon_fichier_export,dico_phoneme_export) - construction_dico_correspondance() - construction_lipsynchro() - #on change d'etape - #we change the stage - etape=2 - - elif (evt == 8): - #we choose the file - Blender.Window.FileSelector(selectionner_fichier,"Select File") - - Blender.Redraw() - -#cette fonction recupere le nom et le chemin du fichier dictionnaire -#we catch the name and the path of the dictionnary -def selectionner_fichier(filename): - global mon_fichier_dico,mon_fichier_export - mon_fichier_dico=filename - mon_fichier_export=filename - -#fonction de lecture de la liste frame phoneme -#we read the frame and phonems -def lecture_chaine(fichier,liste): - mon_fichier=open(fichier) - #je lis la premiere ligne qui contiens la version de moho - #first, we read the moho version - mon_fichier.readline() - - #je lis jusqu'a la fin - #then we read until the end of the file - while 1: - ma_ligne=mon_fichier.readline() - if ma_ligne=='': - break - decoup=ma_ligne.split() - liste[decoup[0]]=decoup[1] - print liste - - - - -#fonction qui construit la liste dictionnaire simple -#we make the dictionnary -def construction_dictionnaire_phoneme(): - global liste_phoneme - index_liste=0 - #je transforme mon dictionnaire en list de tulpes - #we transform the list in tulpes - ma_liste=dico_phoneme_export.items() - #je parcours ma liste a la recherche d'elements non existant - #we read the list to find non existing elements - print dico_phoneme - for index in range(len(ma_liste)): - if ma_liste[index][1] not in liste_phoneme: - liste_phoneme[index_liste:index_liste]=[ma_liste[index][1]] - index_liste=index_liste+1 - print liste_phoneme - - -#cette fonction recupere les courbes cible -#this functon catch the IPO curve -def recuperation_courbe(): - global key_menu,dico_key - - #on recupere le nom des shapes - #we catch the shapes - key=Blender.Object.GetSelected()[0].getData().getKey().getBlocks() - for n in range(len(key)): - #on vire la première cle (en effet basic n'est pas une cle en tant que telle) - #we threw away the basic shapes - if (n>0): - key_menu=key_menu+key[n].name + " %x" + str(n-1) + "|" - dico_key[str(n-1)]=Blender.Object.GetSelected()[0].getData().getKey().getIpo().getCurves()[n-1] - - - print "dico_key" - print dico_key - print 'end dico_key' - -#cette fonction construit un dictionnaire de correspondance entre les phonemes prononces et les cles a utiliser -#we make the dictionnary for the mapping between shapes and phonems -def construction_dico_correspondance(): - global dico_correspondance - #je parcours les phonemes - #we read the phonems - if (nbr_phoneme>0): - dico_correspondance[liste_phoneme[0]]=dico_key[str(let01selectkey.val)] - if (nbr_phoneme>1): - dico_correspondance[liste_phoneme[1]]=dico_key[str(let02selectkey.val)] - if (nbr_phoneme>2): - dico_correspondance[liste_phoneme[2]]=dico_key[str(let03selectkey.val)] - if (nbr_phoneme>3): - dico_correspondance[liste_phoneme[3]]=dico_key[str(let04selectkey.val)] - if (nbr_phoneme>4): - dico_correspondance[liste_phoneme[4]]=dico_key[str(let05selectkey.val)] - if (nbr_phoneme>5): - dico_correspondance[liste_phoneme[5]]=dico_key[str(let06selectkey.val)] - if (nbr_phoneme>6): - dico_correspondance[liste_phoneme[6]]=dico_key[str(let07selectkey.val)] - if (nbr_phoneme>7): - dico_correspondance[liste_phoneme[7]]=dico_key[str(let08selectkey.val)] - if (nbr_phoneme>8): - dico_correspondance[liste_phoneme[8]]=dico_key[str(let09selectkey.val)] - if (nbr_phoneme>9): - dico_correspondance[liste_phoneme[9]]=dico_key[str(let10selectkey.val)] - if (nbr_phoneme>10): - dico_correspondance[liste_phoneme[10]]=dico_key[str(let11selectkey.val)] - if (nbr_phoneme>11): - dico_correspondance[liste_phoneme[11]]=dico_key[str(let12selectkey.val)] - if (nbr_phoneme>12): - dico_correspondance[liste_phoneme[12]]=dico_key[str(let13selectkey.val)] - if (nbr_phoneme>13): - dico_correspondance[liste_phoneme[13]]=dico_key[str(let14selectkey.val)] - if (nbr_phoneme>14): - dico_correspondance[liste_phoneme[14]]=dico_key[str(let15selectkey.val)] - if (nbr_phoneme>15): - dico_correspondance[liste_phoneme[15]]=dico_key[str(let16selectkey.val)] - if (nbr_phoneme>16): - dico_correspondance[liste_phoneme[16]]=dico_key[str(let17selectkey.val)] - if (nbr_phoneme>17): - dico_correspondance[liste_phoneme[17]]=dico_key[str(let18selectkey.val)] - if (nbr_phoneme>18): - dico_correspondance[liste_phoneme[18]]=dico_key[str(let19selectkey.val)] - if (nbr_phoneme>19): - dico_correspondance[liste_phoneme[19]]=dico_key[str(let20selectkey.val)] - if (nbr_phoneme>20): - dico_correspondance[liste_phoneme[20]]=dico_key[str(let21selectkey.val)] - if (nbr_phoneme>21): - dico_correspondance[liste_phoneme[21]]=dico_key[str(let22selectkey.val)] - if (nbr_phoneme>22): - dico_correspondance[liste_phoneme[22]]=dico_key[str(let23selectkey.val)] - if (nbr_phoneme>23): - dico_correspondance[liste_phoneme[23]]=dico_key[str(let24selectkey.val)] - if (nbr_phoneme>24): - dico_correspondance[liste_phoneme[24]]=dico_key[str(let25selectkey.val)] - if (nbr_phoneme>25): - dico_correspondance[liste_phoneme[25]]=dico_key[str(let26selectkey.val)] - if (nbr_phoneme>26): - dico_correspondance[liste_phoneme[26]]=dico_key[str(let27selectkey.val)] - if (nbr_phoneme>27): - dico_correspondance[liste_phoneme[27]]=dico_key[str(let28selectkey.val)] - if (nbr_phoneme>28): - dico_correspondance[liste_phoneme[28]]=dico_key[str(let29selectkey.val)] - if (nbr_phoneme>29): - dico_correspondance[liste_phoneme[29]]=dico_key[str(let30selectkey.val)] - if (nbr_phoneme>30): - dico_correspondance[liste_phoneme[30]]=dico_key[str(let31selectkey.val)] - if (nbr_phoneme>31): - dico_correspondance[liste_phoneme[31]]=dico_key[str(let32selectkey.val)] - - print dico_correspondance - - -#cette fonction ajoute un points a la cle donnee a la frame donnee -#we add a point to the IPO curve Target -def ajoute_point(cle,frame,valeur): - cle.setInterpolation('Linear') - cle.append((frame,valeur)) - cle.Recalc() - -#cette fonction parcours le dictionnaire des frame à ajouter et construit les points -#we add all the point to the IPO Curve -def construction_lipsynchro(): - print "je construit" - doublet_old="" - #construction de la liste des frame - cpt=0 - liste_frame=[] - for frame in dico_phoneme_export: - liste_frame.append(int(frame)) - cpt=cpt+1 - liste_frame.sort() - print "listeframe" - print liste_frame - print "fini" - - for doublet in liste_frame: - ajoute_point(dico_correspondance[dico_phoneme_export[str(doublet)]],doublet,1) - if (doublet_old==""): - ajoute_point(dico_correspondance[dico_phoneme_export[str(doublet)]],(doublet-2),0) - if (doublet_old!=''): - if (dico_correspondance[dico_phoneme_export[str(doublet)]]!=dico_correspondance[dico_phoneme_export[doublet_old]]): - print "doublet:"+str(doublet) - print "doublet old:"+doublet_old - ajoute_point(dico_correspondance[dico_phoneme_export[doublet_old]],(int(doublet_old)+2),0) - ajoute_point(dico_correspondance[dico_phoneme_export[str(doublet)]],(doublet-2),0) - doublet_old=str(doublet) - - -#end of my functions we begin the execution -#je commence l execution----------------------------------------------------------------------------------------------- -#voici mes variables - -#declaration et instanciation -#decleration and instanciation - - -#voici mon objet de travail -objet_travail=Create(0) - -#my soft type -soft_type=1 - -#voici la liste des phoneme effectivement utilise -#the phonems'list -#liste_phoneme_papagayo=['AI','E','O','U','FV','L','WQ','MBP','etc','rest'] -#liste_phoneme_jlipsinch=['A','B','C','Closed','D','E','F','G','I','K','L','M','N','O','P','Q','R','S','SH','T','TH','U','V','W'] - -liste_phoneme=[] -#voici mon dictionnaire des frames o -dico_phoneme_export = Create(0) -dico_phoneme_export={} -dico_phoneme={} - - -#voici mes cle -key_menu="" -dico_key={} - -#voici mes ipo -dico_bloc={} -iponame = Create(0) - -#voici mon dictionnaire de correspondance -dico_correspondance={} - -try: - #on verifie est bien une mesh et qu'il a des courbes - if ((Blender.Object.GetSelected()[0].getType()=='Mesh')): - #on verifie que l'objet a bien toute ses Courbes - if (len(Blender.Object.GetSelected()[0].getData().getKey().getBlocks())-1==Blender.Object.GetSelected()[0].getData().getKey().getIpo().getNcurves()): - etape=3 - #on lance la creation du dictionnaire - recuperation_courbe() - else: - print "not the good number of IPO Curve" - etape = 0 - else: - print "error: bad object Type:" - print Blender.Object.GetSelected()[0].getType() - etape = 0 -except: - print 'error: exception' - etape = 0 - - -#voici le fichier dictionnaire -mon_fichier_dico="" - -#voici le fichier export pamela -mon_fichier_export="" - - -let01selectkey = Create(0) -let02selectkey = Create(0) -let03selectkey = Create(0) -let04selectkey = Create(0) -let05selectkey = Create(0) -let06selectkey = Create(0) -let07selectkey = Create(0) -let08selectkey = Create(0) -let09selectkey = Create(0) -let10selectkey = Create(0) -let11selectkey = Create(0) -let12selectkey = Create(0) -let13selectkey = Create(0) -let14selectkey = Create(0) -let15selectkey = Create(0) -let16selectkey = Create(0) -let17selectkey = Create(0) -let18selectkey = Create(0) -let19selectkey = Create(0) -let20selectkey = Create(0) -let21selectkey = Create(0) -let22selectkey = Create(0) -let23selectkey = Create(0) -let24selectkey = Create(0) - - -Register (trace,event,bevent) diff --git a/release/scripts/bpydata/KUlang.txt b/release/scripts/bpydata/KUlang.txt deleted file mode 100644 index 38605d69c9f..00000000000 --- a/release/scripts/bpydata/KUlang.txt +++ /dev/null @@ -1,121 +0,0 @@ -Version 3.233-2004 -****************** -Espanol -Sale del programa -Utilidades de...%t|Alinea objetos%x1|Creacion%x2|Edita mallas%x3|Edita objetos%x4 -11 -Mov -Esc -Encaja -Abarca -Separa -Alinea -Rota -Incr. -Crea nuevos objetos -Es+ -Es* -Separar entre:%t|Origenes%x1|Centros geometricos%x2|Minimos%x3|Maximos%x4|Baricentro%x5|Objetos%x6 -Crear%t|Arco (3 ptos.)%x1|Arco (interactivo)%x2|Circunferencia (3 ptos.)%x3 -12 -Puntos -Centro -Orden -Objeto -AngIni: -AngFin: -Angulo: -Radio: -Puntos: -Centro -Nombre: -Puntos -Modifica vertices%t|Subdivide%x1|Envia a un plano%x2|Aplica LocRotSize%x3 -Partes -Proyectar en el plano:%t|Coordenado global...%x1|Coordenado local...%x2 -Actuar sobre el plano%t|Yz%x1|Zx%x2|Xy%x3 -En la dirección%t|X%x1|Y%x2|Z%x3|Ortogonal al plano%x4 -Captura -Buffer%t|Copia vector diferencia%x1|Copia distancia%x2|Copia diferencia de rotacion%x3|Copia media LocRotSiz%x4|Ver buffer en consola%x5 -Transformar LocRotSize%t|Hacia el obj. activo%x1|Aleatoriamente%x2 -Poner a distancia fija%x1|Sumar (desp. absoluto)%x2|Multiplicar (desp. relativo)%x3 -******************** -English -Exit program -Utils about:%t|Align Objects%x1|Create%x2|Edit Meshes%x3|Edit Objects%x4 -11 -Mov -Sca -Fit -Embrace -Separate -Align -Rota -Incr. -Create new objects -Sc+ -Sc* -Separate between:%t|Origins%x1|Geometric centers%x2|Minimum%x3|Maximum%x4|Baricenter%x5|Objects%x6 -Create what%t|Arc (3 pts.)%x1|Arc (interactive)%x2|Circunference (3 pts.)%x3 -12 -Points -Centre -Sort -Object -AngIni: -AngEnd: -Angle: -Radius: -Points: -Centre -ObjName: -Points -Modify vertices%t|Subdivide edges%x1|Send to a plane%x2|Set LocRotSize%x3 -Parts -Project onto the plane:%t|Global coordinated...%x1|Local coordinated...%x2 -Act on plane%t|Yz%x1|Zx%x2|Xy%x3 -In direction%t|X%x1|Y%x2|Z%x3|Ortogonal to plane%x4 -Get -Buffer%t|Copy diference vector%x1|Copy distance%x2|Copy rot diference%x3|Copy LocRotSiz average%x4|Show Buffer in Console%x5 -Transform LocRotSize%t|Close to active%x1|Randomly%x2 -Set at fixed distance%x1|Add (absolute displ.)%x2|Multiply (relative displ.)%x3 -******************** -Catala -Surt del programa -Utilitats de...%t|Alinea objectes%x1|Creacio%x2|Edita malles%x3|Edita objetes%x4 -11 -Mov -Esc -Encaixa -Abarca -Separa -Alinea -Rotacio -Incr. -Crea objectes nous -Es+ -Es* -Separa entra:%t|Origens%x1|Centres geometrics%x2|Minims%x3|Maxims%x4|Baricentre%x5|Objectes%x6 -Crear%t|Arc (3 pts.)%x1|Arc (interactiu)%x2|Circumferencia (3 pts.)%x3 -12 -Punts -Centre -Ordre -Objecte -AngIni: -AngFi: -Angle: -Radi: -Punts: -Centre -Nom: -Punts -Modifica vertex%t|Subdivideix%x1|Envia a un pla%x2|Aplica LocRotSize%x3 -Parts -Projectar en el pla:%t|Coordenacio global...%x1|Coordenacio local...%x2 -Actuar sobre el pla%t|Yz%x1|Zx%x2|Xy%x3 -En la direccio%t|X%x1|Y%x2|Z%x3|Ortogonal al pla%x4 -Captura -Buffer%t|Copia vector diferencia%x1|Copia distancia%x2|Copia diferencia de rotacio%x3|Copia mitjana LocRotSiz%x4|Veure buffer en consola%x5 -Transformar LocRotSize%t|Cap al obj. actiu%x1|Aleatoriamente%x2 -Posar a distancia fixa%x1|Sumar (desp. absolut)%x2|Multiplicar (desp. relatiu)%x3 diff --git a/release/scripts/bpydata/config/readme.txt b/release/scripts/bpydata/config/readme.txt deleted file mode 100644 index 4b5cb61b063..00000000000 --- a/release/scripts/bpydata/config/readme.txt +++ /dev/null @@ -1,6 +0,0 @@ -This folder is for automatically saved scripts configuration data. - -To use this feature scripts just need to set a proper Blender.Registry key. - -To know more, check the API Reference doc (specifically the API_related and -Registry parts) and the documentation for the "Scripts Config Editor" script. diff --git a/release/scripts/bpydata/readme.txt b/release/scripts/bpydata/readme.txt deleted file mode 100644 index 3e640e27c4b..00000000000 --- a/release/scripts/bpydata/readme.txt +++ /dev/null @@ -1,9 +0,0 @@ -This directory is the default place for scripts to put their data, -like internal files needed by the script and its saved configuration. - -Scripts can find the path to this dir using Blender.Get("datadir"). -Ex: - -import Blender -print Blender.Get("datadir") - diff --git a/release/scripts/bpymodules/BPyAddMesh.py b/release/scripts/bpymodules/BPyAddMesh.py deleted file mode 100644 index 901e68866cc..00000000000 --- a/release/scripts/bpymodules/BPyAddMesh.py +++ /dev/null @@ -1,159 +0,0 @@ -import Blender -from Blender.Window import EditMode, GetCursorPos, GetViewQuat -import bpy -import BPyMessages - -def add_mesh_simple(name, verts, edges, faces): - ''' - Adds a mesh from verts, edges and faces - - name - new object/mesh name - verts - list of 3d vectors - edges - list of int pairs - faces - list of int triplets/quads - ''' - - scn = bpy.data.scenes.active - if scn.lib: return - ob_act = scn.objects.active - - is_editmode = EditMode() - - cursor = GetCursorPos() - quat = None - if is_editmode or Blender.Get('add_view_align'): # Aligning seems odd for editmode, but blender does it, oh well - try: quat = Blender.Mathutils.Quaternion(GetViewQuat()) - except: pass - - # Exist editmode for non mesh types - if ob_act and ob_act.type != 'Mesh' and is_editmode: - EditMode(0) - - # We are in mesh editmode - if EditMode(): - me = ob_act.getData(mesh=1) - - if me.multires: - BPyMessages.Error_NoMeshMultiresEdit() - return - - # Add to existing mesh - # must exit editmode to modify mesh - EditMode(0) - - me.sel = False - - vert_offset = len(me.verts) - edge_offset = len(me.edges) - face_offset = len(me.faces) - - # transform the verts - txmat = Blender.Mathutils.TranslationMatrix(Blender.Mathutils.Vector(cursor)) - if quat: - mat = quat.toMatrix() - mat.invert() - mat.resize4x4() - txmat = mat * txmat - - txmat = txmat * ob_act.matrixWorld.copy().invert() - - - me.verts.extend(verts) - # Transform the verts by the cursor and view rotation - me.transform(txmat, selected_only=True) - - if vert_offset: - me.edges.extend([[i+vert_offset for i in e] for e in edges]) - me.faces.extend([[i+vert_offset for i in f] for f in faces]) - else: - # Mesh with no data, unlikely - me.edges.extend(edges) - me.faces.extend(faces) - else: - - # Object mode add new - - me = bpy.data.meshes.new(name) - me.verts.extend(verts) - me.edges.extend(edges) - me.faces.extend(faces) - me.sel = True - - # Object creation and location - scn.objects.selected = [] - ob_act = scn.objects.new(me, name) - scn.objects.active = ob_act - - if quat: - mat = quat.toMatrix() - mat.invert() - mat.resize4x4() - ob_act.setMatrix(mat) - - ob_act.loc = cursor - - me.calcNormals() - - if is_editmode or Blender.Get('add_editmode'): - EditMode(1) - - - - - -def write_mesh_script(filepath, me): - ''' - filepath - path to py file - me - mesh to write - ''' - - name = me.name - file = open(filepath, 'w') - - file.write('#!BPY\n') - file.write('"""\n') - file.write('Name: \'%s\'\n' % name) - file.write('Blender: 245\n') - file.write('Group: \'AddMesh\'\n') - file.write('"""\n\n') - file.write('import BPyAddMesh\n') - file.write('from Blender.Mathutils import Vector\n\n') - - file.write('verts = [\\\n') - for v in me.verts: - file.write('Vector(%f,%f,%f),\\\n' % tuple(v.co)) - file.write(']\n') - - file.write('edges = []\n') # TODO, write loose edges - - file.write('faces = [\\\n') - for f in me.faces: - file.write('%s,\\\n' % str(tuple([v.index for v in f]))) - file.write(']\n') - - file.write('BPyAddMesh.add_mesh_simple("%s", verts, edges, faces)\n' % name) - -# The script below can make a file from a mesh with teh above function... -''' -#!BPY -""" -Name: 'Mesh as AddMesh Script' -Blender: 242 -Group: 'Mesh' -Tip: '' -""" -import BPyAddMesh -reload(BPyAddMesh) - -import bpy - -def main(): - # Add error checking - scn = bpy.data.scenes.active - ob = scn.objects.active - me = ob.getData(mesh=1) - - BPyAddMesh.write_mesh_script('/test.py', me) - -main() -''' diff --git a/release/scripts/bpymodules/BPyArmature.py b/release/scripts/bpymodules/BPyArmature.py deleted file mode 100644 index 63df02d080c..00000000000 --- a/release/scripts/bpymodules/BPyArmature.py +++ /dev/null @@ -1,152 +0,0 @@ -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# Version History: -# 1.0 original release bakes an armature into a matrix -# 1.1 optional params (ACTION_BAKE, ACTION_BAKE_FIRST_FRAME, direct function to key and return the Action - -import Blender -from Blender import sys -import bpy -def getBakedPoseData(ob_arm, start_frame, end_frame, ACTION_BAKE = False, ACTION_BAKE_FIRST_FRAME = True): - ''' - If you are currently getting IPO's this function can be used to - ACTION_BAKE==False: return a list of frame aligned bone dictionary's - ACTION_BAKE==True: return an action with keys aligned to bone constrained movement - if ACTION_BAKE_FIRST_FRAME is not supplied or is true: keys begin at frame 1 - - The data in these can be swaped in for the IPO loc and quat - - If you want to bake an action, this is not as hard and the ipo hack can be removed. - ''' - - # --------------------------------- Dummy Action! Only for this functon - backup_action = ob_arm.action - backup_frame = Blender.Get('curframe') - - DUMMY_ACTION_NAME = '~DONT_USE~' - # Get the dummy action if it has no users - try: - new_action = bpy.data.actions[DUMMY_ACTION_NAME] - if new_action.users: - new_action = None - except: - new_action = None - - if not new_action: - new_action = bpy.data.actions.new(DUMMY_ACTION_NAME) - new_action.fakeUser = False - # ---------------------------------- Done - - Matrix = Blender.Mathutils.Matrix - Quaternion = Blender.Mathutils.Quaternion - Vector = Blender.Mathutils.Vector - POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT] - - # Each dict a frame - bake_data = [{} for i in xrange(1+end_frame-start_frame)] - - pose= ob_arm.getPose() - armature_data= ob_arm.getData(); - pose_bones= pose.bones - - # --------------------------------- Build a list of arma data for reuse - armature_bone_data = [] - bones_index = {} - for bone_name, rest_bone in armature_data.bones.items(): - pose_bone = pose_bones[bone_name] - rest_matrix = rest_bone.matrix['ARMATURESPACE'] - rest_matrix_inv = rest_matrix.copy().invert() - armature_bone_data.append( [len(bones_index), -1, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, None ]) - bones_index[bone_name] = len(bones_index) - - # Set the parent ID's - for bone_name, pose_bone in pose_bones.items(): - parent = pose_bone.parent - if parent: - bone_index= bones_index[bone_name] - parent_index= bones_index[parent.name] - armature_bone_data[ bone_index ][1]= parent_index - # ---------------------------------- Done - - - - # --------------------------------- Main loop to collect IPO data - frame_index = 0 - NvideoFrames= end_frame-start_frame - for current_frame in xrange(start_frame, end_frame+1): - if frame_index==0: start=sys.time() - elif frame_index==15: print NvideoFrames*(sys.time()-start),"seconds estimated..." #slows as it grows *3 - elif frame_index >15: - percom= frame_index*100/NvideoFrames - print "Frame %i Overall %i percent complete\r" % (current_frame, percom), - ob_arm.action = backup_action - #pose.update() # not needed - Blender.Set('curframe', current_frame) - #Blender.Window.RedrawAll() - #frame_data = bake_data[frame_index] - ob_arm.action = new_action - ###for i,pose_bone in enumerate(pose_bones): - - for index, parent_index, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, ipo in armature_bone_data: - matrix= pose_bone.poseMatrix - parent_bone= rest_bone.parent - if parent_index != -1: - parent_pose_matrix = armature_bone_data[parent_index][6].poseMatrix - parent_bone_matrix_inv = armature_bone_data[parent_index][5] - matrix= matrix * parent_pose_matrix.copy().invert() - rest_matrix= rest_matrix * parent_bone_matrix_inv - - matrix=matrix * rest_matrix.copy().invert() - pose_bone.quat= matrix.toQuat() - pose_bone.loc= matrix.translationPart() - if ACTION_BAKE==False: - pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1 - - # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE - # - use a temp action and bake into that, always at the same frame - # so as not to make big IPO's, then collect the result from the IPOs - - # Now get the data from the IPOs - if not ipo: ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name) - - loc = Vector() - quat = Quaternion() - - for curve in ipo: - val = curve.evaluate(1) - curve_name= curve.name - if curve_name == 'LocX': loc[0] = val - elif curve_name == 'LocY': loc[1] = val - elif curve_name == 'LocZ': loc[2] = val - elif curve_name == 'QuatW': quat[3] = val - elif curve_name == 'QuatX': quat[0] = val - elif curve_name == 'QuatY': quat[1] = val - elif curve_name == 'QuatZ': quat[2] = val - - bake_data[frame_index][bone_name] = loc, quat - else: - if ACTION_BAKE_FIRST_FRAME: pose_bone.insertKey(ob_arm, frame_index+1, POSE_XFORM) - else: pose_bone.insertKey(ob_arm, current_frame , POSE_XFORM) - frame_index+=1 - print "\nBaking Complete." - ob_arm.action = backup_action - if ACTION_BAKE==False: - Blender.Set('curframe', backup_frame) - return bake_data - elif ACTION_BAKE==True: - return new_action - else: print "ERROR: Invalid ACTION_BAKE %i sent to BPyArmature" % ACTION_BAKE - - - diff --git a/release/scripts/bpymodules/BPyBlender.py b/release/scripts/bpymodules/BPyBlender.py deleted file mode 100644 index 681dff63cf8..00000000000 --- a/release/scripts/bpymodules/BPyBlender.py +++ /dev/null @@ -1,36 +0,0 @@ -# $Id$ -# -# -------------------------------------------------------------------------- -# BPyBlender.py version 0.3 Mar 20, 2005 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -# Basic set of modules Blender should have in all supported platforms. -# The second and third lines are the contents of the Python23.zip file -# included with Windows Blender binaries along with zlib.pyd. -# Other platforms are assumed to have Python installed. -basic_modules = [ -'Blender', -'chunk','colorsys','copy','copy_reg','gzip','os','random','repr','stat', -'string','StringIO','types','UserDict','webbrowser', 'zlib', 'math', -'BPyBlender', 'BPyRegistry' -] diff --git a/release/scripts/bpymodules/BPyCurve.py b/release/scripts/bpymodules/BPyCurve.py deleted file mode 100644 index 3dd5f1784f2..00000000000 --- a/release/scripts/bpymodules/BPyCurve.py +++ /dev/null @@ -1,79 +0,0 @@ -# -------------------------------------------------------------------------- -# BPyImage.py version 0.15 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from Blender import * - -def curve2vecs(ob, WORLDSPACE= True): - ''' - Takes a curve object and retuirns a list of vec lists (polylines) - one list per curve - - This is usefull as a way to get a polyline per curve - so as not to have to deal with the spline types directly - ''' - if ob.type != 'Curve': - raise 'must be a curve object' - - me_dummy = Mesh.New() - me_dummy.getFromObject(ob) - - if WORLDSPACE: - me_dummy.transform(ob.matrixWorld) - - # build an edge dict - edges = {} # should be a set - - def sort_pair(i1, i2): - if i1 > i2: return i2, i1 - else: return i1, i2 - - for ed in me_dummy.edges: - edges[sort_pair(ed.v1.index,ed.v2.index)] = None # dummy value - - # now set the curves - first_time = True - - current_vecs = [] - vec_list = [current_vecs] - - for v in me_dummy.verts: - if first_time: - first_time = False - current_vecs.append(v.co.copy()) - last_index = v.index - else: - index = v.index - if edges.has_key(sort_pair(index, last_index)): - current_vecs.append( v.co.copy() ) - else: - current_vecs = [] - vec_list.append(current_vecs) - - last_index = index - - me_dummy.verts = None - - return vec_list - - diff --git a/release/scripts/bpymodules/BPyImage.py b/release/scripts/bpymodules/BPyImage.py deleted file mode 100644 index 504e4ee29ba..00000000000 --- a/release/scripts/bpymodules/BPyImage.py +++ /dev/null @@ -1,318 +0,0 @@ -# -------------------------------------------------------------------------- -# BPyImage.py version 0.15 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -#===========================================================================# -# Comprehensive image loader, will search and find the image # -# Will return a blender image or a new image if the image is missing # -#===========================================================================# -import bpy -from Blender import sys -try: - import os -except: - os=None - -#==============================================# -# Return directory, where the file is # -#==============================================# -def stripFile(path): - lastSlash = max(path.rfind('\\'), path.rfind('/')) - if lastSlash != -1: - path = path[:lastSlash] - newpath= '%s%s' % (path, sys.sep) - else: - newpath= path - return newpath - -#==============================================# -# Strips the slashes from the back of a string # -#==============================================# -def stripPath(path): - return path.split('/')[-1].split('\\')[-1] - -#====================================================# -# Strips the prefix off the name before writing # -#====================================================# -def stripExt(name): # name is a string - index = name.rfind('.') - if index != -1: - return name[ : index ] - else: - return name - -def getExt(name): - index = name.rfind('.') - if index != -1: - return name[index+1:] - return name - -#====================================================# -# Adds a slash to the end of a path if its not there # -#====================================================# -def addSlash(path): - if not path: - return '' - - elif path.endswith('\\') or path.endswith('/'): - return path - return path + sys.sep - - -def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False, CONVERT_CALLBACK=None): - ''' - imagePath: The image filename - If a path precedes it, this will be searched as well. - - filePath: is the directory where the image may be located - any file at teh end will be ignored. - - PLACE_HOLDER: if True a new place holder image will be created. - this is usefull so later you can relink the image to its original data. - - VERBOSE: If True debug info will be printed. - - RECURSIVE: If True, directories will be recursivly searched. - Be carefull with this if you have files in your root directory because it may take a long time. - - CASE_INSENSITIVE: for non win32 systems, find the correct case for the file. - - CONVERT_CALLBACK: a function that takes an existing path and returns a new one. - Use this when loading image formats blender may not support, the CONVERT_CALLBACK - can take the path for a GIF (for example), convert it to a PNG and return the PNG's path. - For formats blender can read, simply return the path that is given. - ''' - - # VERBOSE = True - - if VERBOSE: print 'img:', imagePath, 'file:', filePath - - if os == None and CASE_INSENSITIVE: - CASE_INSENSITIVE = True - - # When we have the file load it with this. try/except niceness. - def imageLoad(path): - #if path.endswith('\\') or path.endswith('/'): - # raise 'INVALID PATH' - - if CONVERT_CALLBACK: - path = CONVERT_CALLBACK(path) - - try: - img = bpy.data.images.new(filename=path) - if VERBOSE: print '\t\tImage loaded "%s"' % path - return img - except: - if VERBOSE: - if sys.exists(path): print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path) - else: print '\t\tImage not found, making a place holder "%s"' % (path) - if PLACE_HOLDER: - img= bpy.data.images.new(stripPath(path),4,4) - img.filename= path - return img #blank image - else: - return None - - # Image formats blender can read - IMAGE_EXT = ['jpg', 'jpeg', 'png', 'tga', 'bmp', 'rgb', 'sgi', 'bw', 'iff', 'lbm', # Blender Internal - 'gif', 'psd', 'tif', 'tiff', 'pct', 'pict', 'pntg', 'qtif'] # Quacktime, worth a try. - - imageFileName = stripPath(imagePath) # image path only - imageFileName_lower = imageFileName.lower() # image path only - - if VERBOSE: print '\tSearchingExisting Images for "%s"' % imagePath - for i in bpy.data.images: - if stripPath(i.filename.lower()) == imageFileName_lower: - if VERBOSE: print '\t\tUsing existing image.' - return i - - - if VERBOSE: print '\tAttempting to load "%s"' % imagePath - if sys.exists(imagePath): - if VERBOSE: print '\t\tFile found where expected "%s".' % imagePath - return imageLoad(imagePath) - - - - imageFileName_noext = stripExt(imageFileName) # With no extension. - imageFileName_noext_lower = stripExt(imageFileName_lower) # With no extension. - imageFilePath = stripFile(imagePath) - - # Remove relative path from image path - if imageFilePath.startswith('./') or imageFilePath.startswith('.\\'): - imageFilePath = imageFilePath[2:] - - - # Attempt to load from obj path. - tmpPath = stripFile(filePath) + stripPath(imageFileName) - if sys.exists(tmpPath): - if VERBOSE: print '\t\tFile found in path (1)"%s".' % tmpPath - return imageLoad(tmpPath) - - - # os needed if we go any further. - if not os: - if VERBOSE: print '\t\tCreating a placeholder with a face path: "%s".' % imagePath - return imageLoad(imagePath) # Will jus treturn a placeholder. - - - # We have os. - # GATHER PATHS. - paths = {} # Store possible paths we may use, dict for no doubles. - tmpPath = addSlash(sys.expandpath('//')) # Blenders path - if sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - tmpPath = imageFilePath - if sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - tmpPath = stripFile(filePath) - if sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - tmpPath = addSlash(bpy.config.textureDir) - if tmpPath and sys.exists(tmpPath): - if VERBOSE: print '\t\tSearching in %s' % tmpPath - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - - # Add path if relative image patrh was given. - tmp_paths= paths.keys() - for k in tmp_paths: - tmpPath = k + imageFilePath - if sys.exists(tmpPath): - paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading - paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list. - paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext - else: - if VERBOSE: print '\tNo Path: "%s"' % tmpPath - # DONE - # - for path, files in paths.iteritems(): - if sys.exists(path + imageFileName): - if VERBOSE: print '\tFound image at path: "%s" file" "%s"' % (path, imageFileName) - return imageLoad(path + imageFileName) - - # If the files not there then well do a case insensitive seek. - filesOrigCase = files[0] - filesLower = files[1] - filesLowerNoExt = files[2] - - # We are going to try in index the file directly, if its not there just keep on - - index = None - try: - # Is it just a case mismatch? - index = filesLower.index(imageFileName_lower) - except: - try: - # Have the extensions changed? - index = filesLowerNoExt.index(imageFileName_noext_lower) - - ext = getExt( filesLower[index] ) # Get the extension of the file that matches all but ext. - - # Check that the ext is useable eg- not a 3ds file :) - if ext.lower() not in IMAGE_EXT: - index = None - - except: - index = None - - if index != None: - tmpPath = path + filesOrigCase[index] - img = imageLoad( tmpPath ) - if img != None: - if VERBOSE: print '\t\tImage Found "%s"' % tmpPath - return img - - if RECURSIVE: - # IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH. - if VERBOSE: print '\t\tImage Not Found in any of the dirs, doing a recusrive search' - for path in paths.iterkeys(): - # Were not going to use files - if path == '/' or len(path) == 3 and path[1:] == ':\\': - continue - - # print path , 'ASS' - - #------------------ - # finds the file starting at the root. - # def findImage(findRoot, imagePath): - #W--------------- - - # ROOT, DIRS, FILES - pathWalk = os.walk(path) - pathList = [True] - - matchList = [] # Store a list of (match, size), choose the biggest. - while True: - try: - pathList = pathWalk.next() - except: - break - - for file in pathList[2]: - file_lower = file.lower() - # FOUND A MATCH - if (file_lower == imageFileName_lower) or\ - (stripExt(file_lower) == imageFileName_noext_lower and getExt(file_lower) in IMAGE_EXT): - name = pathList[0] + sys.sep + file - size = os.path.getsize(name) - if VERBOSE: print '\t\t\tfound:', name - matchList.append( (name, size) ) - - if matchList: - # Sort by file size - matchList.sort(lambda A, B: cmp(B[1], A[1]) ) - - if VERBOSE: print '\t\tFound "%s"' % matchList[0][0] - - # Loop through all we have found - img = None - for match in matchList: - img = imageLoad(match[0]) # 0 - first, 0 - pathname - if img != None: - break - return img - - # No go. - if VERBOSE: print '\t\tImage Not Found after looking everywhere! "%s"' % imagePath - return imageLoad(imagePath) # Will jus treturn a placeholder. diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py deleted file mode 100644 index 4882e9aaf21..00000000000 --- a/release/scripts/bpymodules/BPyMathutils.py +++ /dev/null @@ -1,228 +0,0 @@ -# $Id$ -# -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender.Mathutils import * - -# ------ Mersenne Twister - start - -# Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. -# Any feedback is very welcome. For any question, comments, -# see http://www.math.keio.ac.jp/matumoto/emt.html or email -# matumoto@math.keio.ac.jp - -# The link above is dead, this is the new one: -# http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/emt.html -# And here the license info, from Mr. Matsumoto's site: -# Until 2001/4/6, MT had been distributed under GNU Public License, -# but after 2001/4/6, we decided to let MT be used for any purpose, including -# commercial use. 2002-versions mt19937ar.c, mt19937ar-cok.c are considered -# to be usable freely. -# -# So from the year above (1997), this code is under GPL. - -# Period parameters -N = 624 -M = 397 -MATRIX_A = 0x9908b0dfL # constant vector a -UPPER_MASK = 0x80000000L # most significant w-r bits -LOWER_MASK = 0x7fffffffL # least significant r bits - -# Tempering parameters -TEMPERING_MASK_B = 0x9d2c5680L -TEMPERING_MASK_C = 0xefc60000L - -def TEMPERING_SHIFT_U(y): - return (y >> 11) - -def TEMPERING_SHIFT_S(y): - return (y << 7) - -def TEMPERING_SHIFT_T(y): - return (y << 15) - -def TEMPERING_SHIFT_L(y): - return (y >> 18) - -mt = [] # the array for the state vector -mti = N+1 # mti==N+1 means mt[N] is not initialized - -# initializing the array with a NONZERO seed -def sgenrand(seed): - # setting initial seeds to mt[N] using - # the generator Line 25 of Table 1 in - # [KNUTH 1981, The Art of Computer Programming - # Vol. 2 (2nd Ed.), pp102] - - global mt, mti - - mt = [] - - mt.append(seed & 0xffffffffL) - for i in xrange(1, N + 1): - mt.append((69069 * mt[i-1]) & 0xffffffffL) - - mti = i -# end sgenrand - - -def genrand(): - global mt, mti - - mag01 = [0x0L, MATRIX_A] - # mag01[x] = x * MATRIX_A for x=0,1 - y = 0 - - if mti >= N: # generate N words at one time - if mti == N+1: # if sgenrand() has not been called, - sgenrand(4357) # a default initial seed is used - - for kk in xrange((N-M) + 1): - y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK) - mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1] - - for kk in xrange(kk, N): - y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK) - mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1] - - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK) - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1] - - mti = 0 - - y = mt[mti] - mti += 1 - y ^= TEMPERING_SHIFT_U(y) - y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B - y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C - y ^= TEMPERING_SHIFT_L(y) - - return ( float(y) / 0xffffffffL ) # reals - -#------ Mersenne Twister -- end - - - - -""" 2d convexhull -Based from Dinu C. Gherman's work, -modified for Blender/Mathutils by Campell Barton -""" -###################################################################### -# Public interface -###################################################################### -def convexHull(point_list_2d): - """Calculate the convex hull of a set of vectors - The vectors can be 3 or 4d but only the Xand Y are used. - returns a list of convex hull indicies to the given point list - """ - - ###################################################################### - # Helpers - ###################################################################### - - def _myDet(p, q, r): - """Calc. determinant of a special matrix with three 2D points. - - The sign, "-" or "+", determines the side, right or left, - respectivly, on which the point r lies, when measured against - a directed vector from p to q. - """ - return (q.x*r.y + p.x*q.y + r.x*p.y) - (q.x*p.y + r.x*q.y + p.x*r.y) - - def _isRightTurn((p, q, r)): - "Do the vectors pq:qr form a right turn, or not?" - #assert p[0] != q[0] and q[0] != r[0] and p[0] != r[0] - if _myDet(p[0], q[0], r[0]) < 0: - return 1 - else: - return 0 - - # Get a local list copy of the points and sort them lexically. - points = [(p, i) for i, p in enumerate(point_list_2d)] - - try: points.sort(key = lambda a: (a[0].x, a[0].y)) - except: points.sort(lambda a,b: cmp((a[0].x, a[0].y), (b[0].x, b[0].y))) - - # Build upper half of the hull. - upper = [points[0], points[1]] # cant remove these. - for i in xrange(len(points)-2): - upper.append(points[i+2]) - while len(upper) > 2 and not _isRightTurn(upper[-3:]): - del upper[-2] - - # Build lower half of the hull. - points.reverse() - lower = [points.pop(0), points.pop(1)] - for p in points: - lower.append(p) - while len(lower) > 2 and not _isRightTurn(lower[-3:]): - del lower[-2] - - # Concatenate both halfs and return. - return [p[1] for ls in (upper, lower) for p in ls] - - -def plane2mat(plane, normalize= False): - ''' - Takes a plane and converts to a matrix - points between 0 and 1 are up - 1 and 2 are right - assumes the plane has 90d corners - ''' - cent= (plane[0]+plane[1]+plane[2]+plane[3] ) /4.0 - - - up= cent - ((plane[0]+plane[1])/2.0) - right= cent - ((plane[1]+plane[2])/2.0) - z= up.cross(right) - - if normalize: - up.normalize() - right.normalize() - z.normalize() - - mat= Matrix(up, right, z) - - # translate - mat.resize4x4() - tmat= Blender.Mathutils.TranslationMatrix(cent) - return mat * tmat - - -# Used for mesh_solidify.py and mesh_wire.py - -# returns a length from an angle -# Imaging a 2d space. -# there is a hoz line at Y1 going to inf on both X ends, never moves (LINEA) -# down at Y0 is a unit length line point up at (angle) from X0,Y0 (LINEB) -# This function returns the length of LINEB at the point it would intersect LINEA -# - Use this for working out how long to make the vector - differencing it from surrounding faces, -# import math -from math import pi, sin, cos, sqrt - -def angleToLength(angle): - # Alredy accounted for - if angle < 0.000001: return 1.0 - else: return abs(1.0 / cos(pi*angle/180)); diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py deleted file mode 100644 index 292f7a4b91e..00000000000 --- a/release/scripts/bpymodules/BPyMesh.py +++ /dev/null @@ -1,1326 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -import Blender -import bpy -import BPyMesh_redux # seperated because of its size. -# reload(BPyMesh_redux) -redux= BPyMesh_redux.redux - -# python 2.3 has no reversed() iterator. this will only work on lists and tuples -try: - reversed -except: - def reversed(l): return l[::-1] - - -# If python version is less than 2.4, try to get set stuff from module -try: - set -except: - try: - from sets import Set as set - except: - set= None - - - - - -def meshWeight2List(me): - ''' Takes a mesh and return its group names and a list of lists, one list per vertex. - aligning the each vert list with the group names, each list contains float value for the weight. - These 2 lists can be modified and then used with list2MeshWeight to apply the changes. - ''' - - # Clear the vert group. - groupNames= me.getVertGroupNames() - len_groupNames= len(groupNames) - - if not len_groupNames: - # no verts? return a vert aligned empty list - return [[] for i in xrange(len(me.verts))], [] - - else: - vWeightList= [[0.0]*len_groupNames for i in xrange(len(me.verts))] - - for group_index, group in enumerate(groupNames): - for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples. - vWeightList[vert_index][group_index]= weight - - # removed this because me may be copying teh vertex groups. - #for group in groupNames: - # me.removeVertGroup(group) - - return groupNames, vWeightList - - -def list2MeshWeight(me, groupNames, vWeightList): - ''' Takes a list of groups and a list of vertex Weight lists as created by meshWeight2List - and applys it to the mesh.''' - - if len(vWeightList) != len(me.verts): - raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights' - - act_group = me.activeGroup - - # Clear the vert group. - currentGroupNames= me.getVertGroupNames() - for group in currentGroupNames: - me.removeVertGroup(group) # messes up the active group. - - # Add clean unused vert groupNames back - currentGroupNames= me.getVertGroupNames() - for group in groupNames: - me.addVertGroup(group) - - add_ = Blender.Mesh.AssignModes.ADD - - vertList= [None] - for i, v in enumerate(me.verts): - vertList[0]= i - for group_index, weight in enumerate(vWeightList[i]): - if weight: - try: - me.assignVertsToGroup(groupNames[group_index], vertList, min(1, max(0, weight)), add_) - except: - pass # vert group is not used anymore. - - try: me.activeGroup = act_group - except: pass - - me.update() - - - - -def meshWeight2Dict(me): - ''' Takes a mesh and return its group names and a list of dicts, one dict per vertex. - using the group as a key and a float value for the weight. - These 2 lists can be modified and then used with dict2MeshWeight to apply the changes. - ''' - - vWeightDict= [dict() for i in xrange(len(me.verts))] # Sync with vertlist. - - # Clear the vert group. - groupNames= me.getVertGroupNames() - - for group in groupNames: - for vert_index, weight in me.getVertsFromGroup(group, 1): # (i,w) tuples. - vWeightDict[vert_index][group]= weight - - # removed this because me may be copying teh vertex groups. - #for group in groupNames: - # me.removeVertGroup(group) - - return groupNames, vWeightDict - - -def dict2MeshWeight(me, groupNames, vWeightDict): - ''' Takes a list of groups and a list of vertex Weight dicts as created by meshWeight2Dict - and applys it to the mesh.''' - - if len(vWeightDict) != len(me.verts): - raise 'Error, Lists Differ in size, do not modify your mesh.verts before updating the weights' - - act_group = me.activeGroup - - # Clear the vert group. - currentGroupNames= me.getVertGroupNames() - for group in currentGroupNames: - if group not in groupNames: - me.removeVertGroup(group) # messes up the active group. - else: - me.removeVertsFromGroup(group) - - # Add clean unused vert groupNames back - currentGroupNames= me.getVertGroupNames() - for group in groupNames: - if group not in currentGroupNames: - me.addVertGroup(group) - - add_ = Blender.Mesh.AssignModes.ADD - - vertList= [None] - for i, v in enumerate(me.verts): - vertList[0]= i - for group, weight in vWeightDict[i].iteritems(): - try: - me.assignVertsToGroup(group, vertList, min(1, max(0, weight)), add_) - except: - pass # vert group is not used anymore. - - try: me.activeGroup = act_group - except: pass - - me.update() - -def dictWeightMerge(dict_weights): - ''' - Takes dict weight list and merges into 1 weight dict item and returns it - ''' - - if not dict_weights: - return {} - - keys= [] - for weight in dict_weights: - keys.extend([ (k, 0.0) for k in weight.iterkeys() ]) - - new_wdict = dict(keys) - - len_dict_weights= len(dict_weights) - - for weight in dict_weights: - for group, value in weight.iteritems(): - new_wdict[group] += value/len_dict_weights - - return new_wdict - - -FLIPNAMES=[\ -('Left','Right'),\ -('_L','_R'),\ -('-L','-R'),\ -('.L','.R'),\ -] - -def dictWeightFlipGroups(dict_weight, groupNames, createNewGroups): - ''' - Returns a weight with flip names - dict_weight - 1 vert weight. - groupNames - because we may need to add new group names. - dict_weight - Weather to make new groups where needed. - ''' - - def flipName(name): - for n1,n2 in FLIPNAMES: - for nA, nB in ( (n1,n2), (n1.lower(),n2.lower()), (n1.upper(),n2.upper()) ): - if createNewGroups: - newName= name.replace(nA,nB) - if newName!=name: - if newName not in groupNames: - groupNames.append(newName) - return newName - - newName= name.replace(nB,nA) - if newName!=name: - if newName not in groupNames: - groupNames.append(newName) - return newName - - else: - newName= name.replace(nA,nB) - if newName!=name and newName in groupNames: - return newName - - newName= name.replace(nB,nA) - if newName!=name and newName in groupNames: - return newName - - return name - - if not dict_weight: - return dict_weight, groupNames - - - new_wdict = {} - for group, weight in dict_weight.iteritems(): - flipname= flipName(group) - new_wdict[flipname]= weight - - return new_wdict, groupNames - - -def mesh2linkedFaces(me): - ''' - Splits the mesh into connected parts, - these parts are returned as lists of faces. - used for seperating cubes from other mesh elements in the 1 mesh - ''' - - # Build vert face connectivity - vert_faces= [[] for i in xrange(len(me.verts))] - for f in me.faces: - for v in f: - vert_faces[v.index].append(f) - - # sort faces into connectivity groups - face_groups= [[f] for f in me.faces] - face_mapping = range(len(me.faces)) # map old, new face location - - # Now clump faces iterativly - ok= True - while ok: - ok= False - - for i, f in enumerate(me.faces): - mapped_index= face_mapping[f.index] - mapped_group= face_groups[mapped_index] - - for v in f: - for nxt_f in vert_faces[v.index]: - if nxt_f != f: - nxt_mapped_index= face_mapping[nxt_f.index] - - # We are not a part of the same group - if mapped_index != nxt_mapped_index: - - ok= True - - # Assign mapping to this group so they all map to this group - for grp_f in face_groups[nxt_mapped_index]: - face_mapping[grp_f.index] = mapped_index - - # Move faces into this group - mapped_group.extend(face_groups[nxt_mapped_index]) - - # remove reference to the list - face_groups[nxt_mapped_index]= None - - - # return all face groups that are not null - # this is all the faces that are connected in their own lists. - return [fg for fg in face_groups if fg] - - -def getFaceLoopEdges(faces, seams=[]): - ''' - Takes me.faces or a list of faces and returns the edge loops - These edge loops are the edges that sit between quads, so they dont touch - 1 quad, not not connected will make 2 edge loops, both only containing 2 edges. - - return a list of edge key lists - [ [(0,1), (4, 8), (3,8)], ...] - - optionaly, seams are edge keys that will be removed - ''' - - OTHER_INDEX = 2,3,0,1 # opposite face index - - edges = {} - - for f in faces: - if len(f) == 4: - edge_keys = f.edge_keys - for i, edkey in enumerate(f.edge_keys): - edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]]) - - for edkey in seams: - edges[edkey] = [] - - # Collect edge loops here - edge_loops = [] - - for edkey, ed_adj in edges.iteritems(): - if 0 face indicies - face_edges[i] -> list referencs local faces v indicies 1,2,3 &| 4 - face_edges[i][j] -> list of faces that this edge uses. - crap this is tricky to explain :/ - ''' - face_edges= [ [-1] * len(f) for f in me.faces ] - - face_edges_dict= dict([(ed.key, []) for ed in me.edges]) - for fidx, f in enumerate(me.faces): - for i, edkey in enumerate(f.edge_keys): - edge_face_users= face_edges_dict[edkey] - edge_face_users.append(f) - face_edges[fidx][i]= edge_face_users - - return face_edges - - -def facesPlanerIslands(me): - - def roundvec(v): - return round(v[0], 4), round(v[1], 4), round(v[2], 4) - - face_props= [(cent, no, roundvec(no), cent.dot(no)) for f in me.faces for no, cent in ((f.no, f.cent),)] - - face_edge_users= face_edges(me) - islands= [] - - used_faces= [0] * len(me.faces) - while True: - new_island= False - for i, used_val in enumerate(used_faces): - if used_val==0: - island= [i] - new_island= True - used_faces[i]= 1 - break - - if not new_island: - break - - island_growing= True - while island_growing: - island_growing= False - for fidx1 in island[:]: - if used_faces[fidx1]==1: - used_faces[fidx1]= 2 - face_prop1= face_props[fidx1] - for ed in face_edge_users[fidx1]: - for f2 in ed: - fidx2= f2.index - if fidx1 != fidx2 and used_faces[fidx2]==0: - island_growing= True - face_prop2= face_props[fidx2] - # normals are the same? - if face_prop1[2]==face_prop2[2]: - if abs(face_prop1[3] - face_prop1[1].dot(face_prop2[0])) < 0.000001: - used_faces[fidx2]= 1 - island.append(fidx2) - islands.append([me.faces[i] for i in island]) - return islands - - - -def facesUvIslands(me, PREF_IMAGE_DELIMIT=True): - def roundvec(v): - return round(v[0], 4), round(v[1], 4) - - if not me.faceUV: - return [ list(me.faces), ] - - # make a list of uv dicts - face_uvs= [ [roundvec(uv) for uv in f.uv] for f in me.faces] - - # key - face uv || value - list of face idxs - uv_connect_dict= dict([ (uv, [] ) for f_uvs in face_uvs for uv in f_uvs]) - - for i, f_uvs in enumerate(face_uvs): - for uv in f_uvs: # loops through rounded uv values - uv_connect_dict[uv].append(i) - islands= [] - - used_faces= [0] * len(me.faces) - while True: - new_island= False - for i, used_val in enumerate(used_faces): - if used_val==0: - island= [i] - new_island= True - used_faces[i]= 1 - break - - if not new_island: - break - - island_growing= True - while island_growing: - island_growing= False - for fidx1 in island[:]: - if used_faces[fidx1]==1: - used_faces[fidx1]= 2 - for uv in face_uvs[fidx1]: - for fidx2 in uv_connect_dict[uv]: - if fidx1 != fidx2 and used_faces[fidx2]==0: - if not PREF_IMAGE_DELIMIT or me.faces[fidx1].image==me.faces[fidx2].image: - island_growing= True - used_faces[fidx2]= 1 - island.append(fidx2) - - islands.append([me.faces[i] for i in island]) - return islands - -#def faceUvBounds(me, faces= None): - - -def facesUvRotate(me, deg, faces= None, pivot= (0,0)): - ''' - Faces can be None an all faces will be used - pivot is just the x/y well rotated about - - positive deg value for clockwise rotation - ''' - if faces==None: faces= me.faces - pivot= Blender.Mathutils.Vector(pivot) - - rotmat= Blender.Mathutils.RotationMatrix(-deg, 2) - - for f in faces: - f.uv= [((uv-pivot)*rotmat)+pivot for uv in f.uv] - -def facesUvScale(me, sca, faces= None, pivot= (0,0)): - ''' - Faces can be None an all faces will be used - pivot is just the x/y well rotated about - sca can be wither an int/float or a vector if you want to - scale x/y seperately. - a sca or (1.0, 1.0) will do nothing. - ''' - def vecmulti(v1,v2): - '''V2 is unchanged''' - v1[:]= (v1.x*v2.x, v1.y*v2.y) - return v1 - - sca= Blender.Mathutils.Vector(sca) - if faces==None: faces= me.faces - pivot= Blender.Mathutils.Vector(pivot) - - for f in faces: - f.uv= [vecmulti(uv-pivot, sca)+pivot for uv in f.uv] - - -def facesUvTranslate(me, tra, faces= None, pivot= (0,0)): - ''' - Faces can be None an all faces will be used - pivot is just the x/y well rotated about - ''' - if faces==None: faces= me.faces - tra= Blender.Mathutils.Vector(tra) - - for f in faces: - f.uv= [uv+tra for uv in f.uv] - - - -def edgeFaceUserCount(me, faces= None): - ''' - Return an edge aligned list with the count for all the faces that use that edge. - - can spesify a subset of the faces, so only those will be counted. - ''' - if faces==None: - faces= me.faces - max_vert= len(me.verts) - else: - # find the lighest vert index - pass - - edge_users= [0] * len(me.edges) - - edges_idx_dict= dict([(ed.key, ed.index) for ed in me.edges]) - - for f in faces: - for edkey in f.edge_keys: - edge_users[edges_idx_dict[edkey]] += 1 - - return edge_users - - -#============================================================================# -# Takes a face, and a pixel x/y on the image and returns a worldspace x/y/z # -# will return none if the pixel is not inside the faces UV # -#============================================================================# -def getUvPixelLoc(face, pxLoc, img_size = None, uvArea = None): - TriangleArea= Blender.Mathutils.TriangleArea - Vector= Blender.Mathutils.Vector - - if not img_size: - w,h = face.image.size - else: - w,h= img_size - - scaled_uvs= [Vector(uv.x*w, uv.y*h) for uv in f.uv] - - if len(scaled_uvs)==3: - indicies= ((0,1,2),) - else: - indicies= ((0,1,2), (0,2,3)) - - for fidxs in indicies: - for i1,i2,i3 in fidxs: - # IS a point inside our triangle? - # UVArea could be cached? - uv_area = TriangleArea(scaled_uvs[i1], scaled_uvs[i2], scaled_uvs[i3]) - area0 = TriangleArea(pxLoc, scaled_uvs[i2], scaled_uvs[i3]) - area1 = TriangleArea(pxLoc, scaled_uvs[i1], scaled_uvs[i3]) - area2 = TriangleArea(pxLoc, scaled_uvs[i1], scaled_uvs[i2]) - if area0 + area1 + area2 > uv_area + 1: # 1 px bleed/error margin. - pass # if were a quad the other side may contain the pixel so keep looking. - else: - # We know the point is in the tri - area0 /= uv_area - area1 /= uv_area - area2 /= uv_area - - # New location - return Vector(\ - face.v[i1].co[0]*area0 + face.v[i2].co[0]*area1 + face.v[i3].co[0]*area2,\ - face.v[i1].co[1]*area0 + face.v[i2].co[1]*area1 + face.v[i3].co[1]*area2,\ - face.v[i1].co[2]*area0 + face.v[i2].co[2]*area1 + face.v[i3].co[2]*area2\ - ) - - return None - - -# Used for debugging ngon -""" -def draw_loops(loops): - - me= Blender.Mesh.New() - for l in loops: - #~ me= Blender.Mesh.New() - - - i= len(me.verts) - me.verts.extend([v[0] for v in l]) - try: - me.verts[0].sel= 1 - except: - pass - me.edges.extend([ (j-1, j) for j in xrange(i+1, len(me.verts)) ]) - # Close the edge? - me.edges.extend((i, len(me.verts)-1)) - - - #~ ob= Blender.Object.New('Mesh') - #~ ob.link(me) - #~ scn= Blender.Scene.GetCurrent() - #~ scn.link(ob) - #~ ob.Layers= scn.Layers - #~ ob.sel= 1 - - - - # Fill - #fill= Blender.Mathutils.PolyFill(loops) - #me.faces.extend(fill) - - - ob= Blender.Object.New('Mesh') - ob.link(me) - scn= Blender.Scene.GetCurrent() - scn.link(ob) - ob.Layers= scn.Layers - ob.sel= 1 - Blender.Window.RedrawAll() -""" - -def ngon(from_data, indices, PREF_FIX_LOOPS= True): - ''' - Takes a polyline of indices (fgon) - and returns a list of face indicie lists. - Designed to be used for importers that need indices for an fgon to create from existing verts. - - from_data: either a mesh, or a list/tuple of vectors. - indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given. - PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. - ''' - - if not set: # Need sets for this, otherwise do a normal fill. - PREF_FIX_LOOPS= False - - Vector= Blender.Mathutils.Vector - if not indices: - return [] - - # return [] - def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6) - def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length - - def vert_treplet(v, i): - return v, rvec(v), i, mlen(v) - - def ed_key_mlen(v1, v2): - if v1[3] > v2[3]: - return v2[1], v1[1] - else: - return v1[1], v2[1] - - - if not PREF_FIX_LOOPS: - ''' - Normal single concave loop filling - ''' - if type(from_data) in (tuple, list): - verts= [Vector(from_data[i]) for ii, i in enumerate(indices)] - else: - verts= [from_data.verts[i].co for ii, i in enumerate(indices)] - - for i in xrange(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))): - if verts[i][1]==verts[i-1][0]: - verts.pop(i-1) - - fill= Blender.Geometry.PolyFill([verts]) - - else: - ''' - Seperate this loop into multiple loops be finding edges that are used twice - This is used by lightwave LWO files a lot - ''' - - if type(from_data) in (tuple, list): - verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)] - else: - verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)] - - edges= [(i, i-1) for i in xrange(len(verts))] - if edges: - edges[0]= (0,len(verts)-1) - - if not verts: - return [] - - - edges_used= set() - edges_doubles= set() - # We need to check if any edges are used twice location based. - for ed in edges: - edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]]) - if edkey in edges_used: - edges_doubles.add(edkey) - else: - edges_used.add(edkey) - - # Store a list of unconnected loop segments split by double edges. - # will join later - loop_segments= [] - - v_prev= verts[0] - context_loop= [v_prev] - loop_segments= [context_loop] - - for v in verts: - if v!=v_prev: - # Are we crossing an edge we removed? - if ed_key_mlen(v, v_prev) in edges_doubles: - context_loop= [v] - loop_segments.append(context_loop) - else: - if context_loop and context_loop[-1][1]==v[1]: - #raise "as" - pass - else: - context_loop.append(v) - - v_prev= v - # Now join loop segments - - def join_seg(s1,s2): - if s2[-1][1]==s1[0][1]: # - s1,s2= s2,s1 - elif s1[-1][1]==s2[0][1]: - pass - else: - return False - - # If were stuill here s1 and s2 are 2 segments in the same polyline - s1.pop() # remove the last vert from s1 - s1.extend(s2) # add segment 2 to segment 1 - - if s1[0][1]==s1[-1][1]: # remove endpoints double - s1.pop() - - s2[:]= [] # Empty this segment s2 so we dont use it again. - return True - - joining_segments= True - while joining_segments: - joining_segments= False - segcount= len(loop_segments) - - for j in xrange(segcount-1, -1, -1): #reversed(xrange(segcount)): - seg_j= loop_segments[j] - if seg_j: - for k in xrange(j-1, -1, -1): # reversed(xrange(j)): - if not seg_j: - break - seg_k= loop_segments[k] - - if seg_k and join_seg(seg_j, seg_k): - joining_segments= True - - loop_list= loop_segments - - for verts in loop_list: - while verts and verts[0][1]==verts[-1][1]: - verts.pop() - - loop_list= [verts for verts in loop_list if len(verts)>2] - # DONE DEALING WITH LOOP FIXING - - - # vert mapping - vert_map= [None]*len(indices) - ii=0 - for verts in loop_list: - if len(verts)>2: - for i, vert in enumerate(verts): - vert_map[i+ii]= vert[2] - ii+=len(verts) - - fill= Blender.Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ]) - #draw_loops(loop_list) - #raise 'done loop' - # map to original indicies - fill= [[vert_map[i] for i in reversed(f)] for f in fill] - - - if not fill: - print 'Warning Cannot scanfill, fallback on a triangle fan.' - fill= [ [0, i-1, i] for i in xrange(2, len(indices)) ] - else: - # Use real scanfill. - # See if its flipped the wrong way. - flip= None - for fi in fill: - if flip != None: - break - for i, vi in enumerate(fi): - if vi==0 and fi[i-1]==1: - flip= False - break - elif vi==1 and fi[i-1]==0: - flip= True - break - - if not flip: - for i, fi in enumerate(fill): - fill[i]= tuple([ii for ii in reversed(fi)]) - - - - - return fill - - - -# EG -''' -scn= Scene.GetCurrent() -me = scn.getActiveObject().getData(mesh=1) -ind= [v.index for v in me.verts if v.sel] # Get indices - -indices = ngon(me, ind) # fill the ngon. - -# Extand the faces to show what the scanfill looked like. -print len(indices) -me.faces.extend([[me.verts[ii] for ii in i] for i in indices]) -''' - -def meshCalcNormals(me, vertNormals=None): - ''' - takes a mesh and returns very high quality normals 1 normal per vertex. - The normals should be correct, indipendant of topology - - vertNormals - a list of vectors at least as long as the number of verts in the mesh - ''' - Ang= Blender.Mathutils.AngleBetweenVecs - Vector= Blender.Mathutils.Vector - SMALL_NUM=0.000001 - # Weight the edge normals by total angle difference - # EDGE METHOD - - if not vertNormals: - vertNormals= [ Vector() for v in xrange(len(me.verts)) ] - else: - for v in vertNormals: - v.zero() - - edges={} - for f in me.faces: - f_v = f.v - for edkey in f.edge_keys: - edges.setdefault(edkey, []).append(f.no) - - # Weight the edge normals by total angle difference - for fnos in edges.itervalues(): - - len_fnos= len(fnos) - if len_fnos>1: - totAngDiff=0 - for j in xrange(len_fnos-1, -1, -1): # same as reversed(xrange(...)) - for k in xrange(j-1, -1, -1): # same as reversed(xrange(...)) - #print j,k - try: - totAngDiff+= (Ang(fnos[j], fnos[k])) # /180 isnt needed, just to keeop the vert small. - except: - pass # Zero length face - - # print totAngDiff - if totAngDiff > SMALL_NUM: - ''' - average_no= Vector() - for no in fnos: - average_no+=no - ''' - average_no= reduce(lambda a,b: a+b, fnos, Vector()) - fnos.append(average_no*totAngDiff) # average no * total angle diff - #else: - # fnos[0] - else: - fnos.append(fnos[0]) - - for ed, v in edges.iteritems(): - vertNormals[ed[0]]+= v[-1] - vertNormals[ed[1]]+= v[-1] - for i, v in enumerate(me.verts): - v.no= vertNormals[i] - - - - -def pointInsideMesh(ob, pt): - Intersect = Blender.Mathutils.Intersect # 2 less dict lookups. - Vector = Blender.Mathutils.Vector - - def ptInFaceXYBounds(f, pt): - f_v = f.v - co= f_v[0].co - xmax= xmin= co.x - ymax= ymin= co.y - - co= f_v[1].co - xmax= max(xmax, co.x) - xmin= min(xmin, co.x) - ymax= max(ymax, co.y) - ymin= min(ymin, co.y) - - co= f_v[2].co - xmax= max(xmax, co.x) - xmin= min(xmin, co.x) - ymax= max(ymax, co.y) - ymin= min(ymin, co.y) - - if len(f_v)==4: - co= f_v[3].co - xmax= max(xmax, co.x) - xmin= min(xmin, co.x) - ymax= max(ymax, co.y) - ymin= min(ymin, co.y) - - # Now we have the bounds, see if the point is in it. - if\ - pt.x < xmin or\ - pt.y < ymin or\ - pt.x > xmax or\ - pt.y > ymax: - return False # point is outside face bounds - else: - return True # point inside. - #return xmax, ymax, xmin, ymin - - def faceIntersect(f): - f_v = f.v - isect = Intersect(f_v[0].co, f_v[1].co, f_v[2].co, ray, obSpacePt, 1) # Clipped. - if not isect and len(f) == 4: - isect = Intersect(f_v[0].co, f_v[2].co, f_v[3].co, ray, obSpacePt, 1) # Clipped. - - if isect and isect.z > obSpacePt.z: # This is so the ray only counts if its above the point. - return True - else: - return False - - obSpacePt = pt*ob.matrixWorld.copy().invert() - ray = Vector(0,0,-1) - me= ob.getData(mesh=1) - - # Here we find the number on intersecting faces, return true if an odd number (inside), false (outside) if its true. - return len([None for f in me.faces if ptInFaceXYBounds(f, obSpacePt) if faceIntersect(f)]) % 2 - - -def faceAngles(f): - ''' - Returns the angle between all corners in a tri or a quad - - ''' - AngleBetweenVecs = Blender.Mathutils.AngleBetweenVecs - def Ang(a1,a2): - try: return AngleBetweenVecs(a1,a2) - except: return 180 - - if len(f) == 3: - if type(f) in (tuple, list): v1,v2,v3 = f - else: v1,v2,v3 = [v.co for v in f] - a1= Ang(v2-v1,v3-v1) - a2= Ang(v1-v2,v3-v2) - a3 = 180 - (a1+a2) # a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3) - return a1,a2,a3 - - else: - if type(f) in (tuple, list): v1,v2,v3,v4 = f - else: v1,v2,v3,v4 = [v.co for v in f] - a1= Ang(v2-v1,v4-v1) - a2= Ang(v1-v2,v3-v2) - a3= Ang(v2-v3,v4-v3) - a4= Ang(v3-v4,v1-v4) - return a1,a2,a3,a4 - -# NMesh wrapper -Vector= Blender.Mathutils.Vector -class NMesh(object): - __slots__= 'verts', 'faces', 'edges', 'faceUV', 'materials', 'realmesh' - def __init__(self, mesh): - ''' - This is an NMesh wrapper that - mesh is an Mesh as returned by Blender.Mesh.New() - This class wraps NMesh like access into Mesh - - Running NMesh.update() - with this wrapper, - Will update the realmesh. - ''' - self.verts= [] - self.faces= [] - self.edges= [] - self.faceUV= False - self.materials= [] - self.realmesh= mesh - - def addFace(self, nmf): - self.faces.append(nmf) - - def Face(self, v=[]): - return NMFace(v) - def Vert(self, x,y,z): - return NMVert(x,y,z) - - def hasFaceUV(self, flag): - if flag: - self.faceUV= True - else: - self.faceUV= False - - def addMaterial(self, mat): - self.materials.append(mat) - - def update(self, recalc_normals=False): # recalc_normals is dummy - mesh= self.realmesh - mesh.verts= None # Clears the - - # Add in any verts from faces we may have not added. - for nmf in self.faces: - for nmv in nmf.v: - if nmv.index==-1: - nmv.index= len(self.verts) - self.verts.append(nmv) - - - mesh.verts.extend([nmv.co for nmv in self.verts]) - for i, nmv in enumerate(self.verts): - nmv.index= i - mv= mesh.verts[i] - mv.sel= nmv.sel - - good_faces= [nmf for nmf in self.faces if len(nmf.v) in (3,4)] - #print len(good_faces), 'AAA' - - - #mesh.faces.extend([nmf.v for nmf in self.faces]) - mesh.faces.extend([[mesh.verts[nmv.index] for nmv in nmf.v] for nmf in good_faces]) - if len(mesh.faces): - if self.faceUV: - mesh.faceUV= 1 - - #for i, nmf in enumerate(self.faces): - for i, nmf in enumerate(good_faces): - mf= mesh.faces[i] - if self.faceUV: - if len(nmf.uv) == len(mf.v): - mf.uv= [Vector(uv[0], uv[1]) for uv in nmf.uv] - if len(nmf.col) == len(mf.v): - for c, i in enumerate(mf.col): - c.r, c.g, c.b= nmf.col[i].r, nmf.col[i].g, nmf.col[i].b - if nmf.image: - mf.image= nmf.image - - mesh.materials= self.materials[:16] - -class NMVert(object): - __slots__= 'co', 'index', 'no', 'sel', 'uvco' - def __init__(self, x,y,z): - self.co= Vector(x,y,z) - self.index= None # set on appending. - self.no= Vector(0,0,1) # dummy - self.sel= 0 - self.uvco= None -class NMFace(object): - __slots__= 'col', 'flag', 'hide', 'image', 'mat', 'materialIndex', 'mode', 'normal',\ - 'sel', 'smooth', 'transp', 'uv', 'v' - - def __init__(self, v=[]): - self.col= [] - self.flag= 0 - self.hide= 0 - self.image= None - self.mat= 0 # materialIndex needs support too. - self.mode= 0 - self.normal= Vector(0,0,1) - self.uv= [] - self.sel= 0 - self.smooth= 0 - self.transp= 0 - self.uv= [] - self.v= [] # a list of nmverts. - -class NMCol(object): - __slots__ = 'r', 'g', 'b', 'a' - def __init__(self): - self.r= 255 - self.g= 255 - self.b= 255 - self.a= 255 - - -''' -# -verts_split= [dict() for i in xrange(len(me.verts))] - -tot_verts= 0 -for f in me.faces: - f_uv= f.uv - for i, v in enumerate(f.v): - vert_index= v.index # mesh index - vert_dict= verts_split[vert_index] # get the dict for this vert - - uv= f_uv[i] - # now we have the vert and the face uv well make a unique dict. - - vert_key= v.x, v.y, v.x, uv.x, uv.y # ADD IMAGE NAME HETR IF YOU WANT TO SPLIT BY THAT TOO - value= vert_index, tot_verts # ADD WEIGHT HERE IF YOU NEED. - try: - vert_dict[vert_key] # if this is missing it will fail. - except: - # this stores a mapping between the split and orig vert indicies - vert_dict[vert_key]= value - tot_verts+= 1 - -# a flat list of split verts - can add custom weight data here too if you need -split_verts= [None]*tot_verts - -for vert_split_dict in verts_split: - for key, value in vert_split_dict.iteritems(): - local_index, split_index= value - split_verts[split_index]= key - -# split_verts - Now you have a list of verts split by their UV. -''' diff --git a/release/scripts/bpymodules/BPyMesh_redux.py b/release/scripts/bpymodules/BPyMesh_redux.py deleted file mode 100644 index 5955d696fbd..00000000000 --- a/release/scripts/bpymodules/BPyMesh_redux.py +++ /dev/null @@ -1,652 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# (C) Copyright 2006 MetaVR, Inc. -# http://www.metavr.com -# Written by Campbell Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -import bpy -Vector= Blender.Mathutils.Vector -Ang= Blender.Mathutils.AngleBetweenVecs -MidpointVecs= Blender.Mathutils.MidpointVecs -import BPyMesh - -# If python version is less than 2.4, try to get set stuff from module - -try: - set -except: - try: - from sets import Set as set - except: - set= None - -def uv_key(uv): - return round(uv.x, 5), round(uv.y, 5) - -def uv_key_mix(uv1, uv2, w1, w2): - # Weighted mix. w1+w2==1.0 - return w1*uv1[0]+w2*uv2[0], w1*uv1[1]+w2*uv2[1] - -def col_key(col): - return col.r, col.g, col.b - -def col_key_mix(col1, col2, w1, w2): - # Weighted mix. w1+w2==1.0 - return int(w1*col1[0] + w2*col2[0]), int(w1*col1[1] + w2*col2[1]), int(w1*col1[2]+col2[2]*w2) - - -def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=2.0, REMOVE_DOUBLES=False, FACE_AREA_WEIGHT=1.0, FACE_TRIANGULATE=True, DO_UV=True, DO_VCOL=True, DO_WEIGHTS=True, VGROUP_INF_REDUX= None, VGROUP_INF_WEIGHT=0.5): - """ - BOUNDRY_WEIGHT - 0 is no boundry weighting. 2.0 will make them twice as unlikely to collapse. - FACE_AREA_WEIGHT - 0 is no weight. 1 is normal, 2.0 is higher. - """ - - if REDUX<0 or REDUX>1.0: - raise 'Error, factor must be between 0 and 1.0' - elif not set: - raise 'Error, this function requires Python 2.4 or a full install of Python 2.3' - - BOUNDRY_WEIGHT= 1+BOUNDRY_WEIGHT - - """ # DEBUG! - if Blender.Get('rt') == 1000: - DEBUG=True - else: - DEBUG= False - """ - - me= ob.getData(mesh=1) - me.hide= False # unhide all data,. - if len(me.faces)<5: - return - - - - if FACE_TRIANGULATE or REMOVE_DOUBLES: - me.sel= True - - if FACE_TRIANGULATE: - me.quadToTriangle() - - if REMOVE_DOUBLES: - me.remDoubles(0.0001) - - vgroups= me.getVertGroupNames() - - if not me.getVertGroupNames(): - DO_WEIGHTS= False - - if (VGROUP_INF_REDUX!= None and VGROUP_INF_REDUX not in vgroups) or\ - VGROUP_INF_WEIGHT==0.0: - VGROUP_INF_REDUX= None - - try: - VGROUP_INF_REDUX_INDEX= vgroups.index(VGROUP_INF_REDUX) - except: - VGROUP_INF_REDUX_INDEX= -1 - - # del vgroups - len_vgroups= len(vgroups) - - - - OLD_MESH_MODE= Blender.Mesh.Mode() - Blender.Mesh.Mode(Blender.Mesh.SelectModes.VERTEX) - - if DO_UV and not me.faceUV: - DO_UV= False - - if DO_VCOL and not me.vertexColors: - DO_VCOL = False - - current_face_count= len(me.faces) - target_face_count= int(current_face_count * REDUX) - # % of the collapseable faces to collapse per pass. - #collapse_per_pass= 0.333 # between 0.1 - lots of small nibbles, slow but high q. and 0.9 - big passes and faster. - collapse_per_pass= 0.333 # between 0.1 - lots of small nibbles, slow but high q. and 0.9 - big passes and faster. - - """# DEBUG! - if DEBUG: - COUNT= [0] - def rd(): - if COUNT[0]< 330: - COUNT[0]+=1 - return - me.update() - Blender.Window.RedrawAll() - print 'Press key for next, count "%s"' % COUNT[0] - try: input() - except KeyboardInterrupt: - raise "Error" - except: - pass - - COUNT[0]+=1 - """ - - class collapseEdge(object): - __slots__ = 'length', 'key', 'faces', 'collapse_loc', 'v1', 'v2','uv1', 'uv2', 'col1', 'col2', 'collapse_weight' - def __init__(self, ed): - self.init_from_edge(ed) # So we can re-use the classes without using more memory. - - def init_from_edge(self, ed): - self.key= ed.key - self.length= ed.length - self.faces= [] - self.v1= ed.v1 - self.v2= ed.v2 - if DO_UV or DO_VCOL: - self.uv1= [] - self.uv2= [] - self.col1= [] - self.col2= [] - - # self.collapse_loc= None # new collapse location. - # Basic weighting. - #self.collapse_weight= self.length * (1+ ((ed.v1.no-ed.v2.no).length**2)) - self.collapse_weight= 1.0 - - def collapse_locations(self, w1, w2): - ''' - Generate a smart location for this edge to collapse to - w1 and w2 are vertex location bias - ''' - - v1co= self.v1.co - v2co= self.v2.co - v1no= self.v1.no - v2no= self.v2.no - - # Basic operation, works fine but not as good as predicting the best place. - #between= ((v1co*w1) + (v2co*w2)) - #self.collapse_loc= between - - # normalize the weights of each vert - se we can use them as scalers. - wscale= w1+w2 - if not wscale: # no scale? - w1=w2= 0.5 - else: - w1/=wscale - w2/=wscale - - length= self.length - between= MidpointVecs(v1co, v2co) - - # Collapse - # new_location = between # Replace tricky code below. this code predicts the best collapse location. - - # Make lines at right angles to the normals- these 2 lines will intersect and be - # the point of collapsing. - - # Enlarge so we know they intersect: self.length*2 - cv1= v1no.cross(v1no.cross(v1co-v2co)) - cv2= v2no.cross(v2no.cross(v2co-v1co)) - - # Scale to be less then the edge lengths. - cv2.length = cv1.length = 1 - - cv1 = cv1 * (length* 0.4) - cv2 = cv2 * (length* 0.4) - - smart_offset_loc= between + (cv1 + cv2) - - # Now we need to blend between smart_offset_loc and w1/w2 - # you see were blending between a vert and the edges midpoint, so we cant use a normal weighted blend. - if w1 > 0.5: # between v1 and smart_offset_loc - #self.collapse_loc= v1co*(w2+0.5) + smart_offset_loc*(w1-0.5) - w2*=2 - w1= 1-w2 - new_loc_smart= v1co*w1 + smart_offset_loc*w2 - else: # w between v2 and smart_offset_loc - w1*=2 - w2= 1-w1 - new_loc_smart= v2co*w2 + smart_offset_loc*w1 - - if new_loc_smart.x != new_loc_smart.x: # NAN LOCATION, revert to between - new_loc_smart= None - - return new_loc_smart, between, v1co*0.99999 + v2co*0.00001, v1co*0.00001 + v2co*0.99999 - - - class collapseFace(object): - __slots__ = 'verts', 'normal', 'area', 'index', 'orig_uv', 'orig_col', 'uv', 'col' # , 'collapse_edge_count' - def __init__(self, f): - self.init_from_face(f) - - def init_from_face(self, f): - self.verts= f.v - self.normal= f.no - self.area= f.area - self.index= f.index - if DO_UV: - self.orig_uv= [uv_key(uv) for uv in f.uv] - self.uv= f.uv - if DO_VCOL: - self.orig_col= [col_key(col) for col in f.col] - self.col= f.col - - collapse_edges= collapse_faces= None - - # So meshCalcNormals can avoid making a new list all the time. - reuse_vertNormals= [ Vector() for v in xrange(len(me.verts)) ] - - while target_face_count <= len(me.faces): - BPyMesh.meshCalcNormals(me, reuse_vertNormals) - - if DO_WEIGHTS: - #groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) - groupNames, vWeightList= BPyMesh.meshWeight2List(me) - - # THIS CRASHES? Not anymore. - verts= list(me.verts) - edges= list(me.edges) - faces= list(me.faces) - - # THIS WORKS - #verts= me.verts - #edges= me.edges - #faces= me.faces - - # if DEBUG: DOUBLE_CHECK= [0]*len(verts) - me.sel= False - - if not collapse_faces: # Initialize the list. - collapse_faces= [collapseFace(f) for f in faces] - collapse_edges= [collapseEdge(ed) for ed in edges] - else: - for i, ed in enumerate(edges): - collapse_edges[i].init_from_edge(ed) - - # Strip the unneeded end off the list - collapse_edges[i+1:]= [] - - for i, f in enumerate(faces): - collapse_faces[i].init_from_face(f) - - # Strip the unneeded end off the list - collapse_faces[i+1:]= [] - - - collapse_edges_dict= dict( [(ced.key, ced) for ced in collapse_edges] ) - - # Store verts edges. - vert_ed_users= [[] for i in xrange(len(verts))] - for ced in collapse_edges: - vert_ed_users[ced.key[0]].append(ced) - vert_ed_users[ced.key[1]].append(ced) - - # Store face users - vert_face_users= [[] for i in xrange(len(verts))] - - # Have decieded not to use this. area is better. - #face_perim= [0.0]* len(me.faces) - - for ii, cfa in enumerate(collapse_faces): - for i, v1 in enumerate(cfa.verts): - vert_face_users[v1.index].append( (i,cfa) ) - - # add the uv coord to the vert - v2 = cfa.verts[i-1] - i1= v1.index - i2= v2.index - - if i1>i2: ced= collapse_edges_dict[i2,i1] - else: ced= collapse_edges_dict[i1,i2] - - ced.faces.append(cfa) - if DO_UV or DO_VCOL: - # if the edge is flipped from its order in the face then we need to flip the order indicies. - if cfa.verts[i]==ced.v1: i1,i2 = i, i-1 - else: i1,i2 = i-1, i - - if DO_UV: - ced.uv1.append( cfa.orig_uv[i1] ) - ced.uv2.append( cfa.orig_uv[i2] ) - - if DO_VCOL: - ced.col1.append( cfa.orig_col[i1] ) - ced.col2.append( cfa.orig_col[i2] ) - - - # PERIMITER - #face_perim[ii]+= ced.length - - - - # How weight the verts by the area of their faces * the normal difference. - # when the edge collapses, to vert weights are taken into account - - vert_weights= [0.5] * len(verts) - - for ii, vert_faces in enumerate(vert_face_users): - for f in vert_faces: - try: - no_ang= (Ang(verts[ii].no, f[1].normal)/180) * f[1].area - except: - no_ang= 1.0 - - vert_weights[ii] += no_ang - - # Use a vertex group as a weighting. - if VGROUP_INF_REDUX!=None: - - # Get Weights from a vgroup. - """ - vert_weights_map= [1.0] * len(verts) - for i, wd in enumerate(vWeightDict): - try: vert_weights_map[i]= 1+(wd[VGROUP_INF_REDUX] * VGROUP_INF_WEIGHT) - except: pass - """ - vert_weights_map= [1+(wl[VGROUP_INF_REDUX_INDEX]*VGROUP_INF_WEIGHT) for wl in vWeightList ] - - - # BOUNDRY CHECKING AND WEIGHT EDGES. CAN REMOVE - # Now we know how many faces link to an edge. lets get all the boundry verts - if BOUNDRY_WEIGHT > 0: - verts_boundry= [1] * len(verts) - #for ed_idxs, faces_and_uvs in edge_faces_and_uvs.iteritems(): - for ced in collapse_edges: - if len(ced.faces) < 2: - for key in ced.key: # only ever 2 key indicies. - verts_boundry[key]= 2 - - for ced in collapse_edges: - b1= verts_boundry[ced.key[0]] - b2= verts_boundry[ced.key[1]] - if b1 != b2: - # Edge has 1 boundry and 1 non boundry vert. weight higher - ced.collapse_weight= BOUNDRY_WEIGHT - #elif b1==b2==2: # if both are on a seam then weigh half as bad. - # ced.collapse_weight= ((BOUNDRY_WEIGHT-1)/2) +1 - # weight the verts by their boundry status - del b1 - del b2 - - for ii, boundry in enumerate(verts_boundry): - if boundry==2: - vert_weights[ii] *= BOUNDRY_WEIGHT - - vert_collapsed= verts_boundry - del verts_boundry - else: - vert_collapsed= [1] * len(verts) - - - - - # Best method, no quick hacks here, Correction. Should be the best but needs tweaks. - def ed_set_collapse_error(ced): - # Use the vertex weights to bias the new location. - new_locs= ced.collapse_locations(vert_weights[ced.key[0]], vert_weights[ced.key[1]]) - - - # Find the connecting faces of the 2 verts. - i1, i2= ced.key - test_faces= set() - for i in (i1,i2): # faster then LC's - for f in vert_face_users[i]: - test_faces.add(f[1].index) - for f in ced.faces: - test_faces.remove(f.index) - - - v1_orig= Vector(ced.v1.co) - v2_orig= Vector(ced.v2.co) - - def test_loc(new_loc): - ''' - Takes a location and tests the error without changing anything - ''' - new_weight= ced.collapse_weight - ced.v1.co= ced.v2.co= new_loc - - new_nos= [faces[i].no for i in test_faces] - - # So we can compare the befire and after normals - ced.v1.co= v1_orig - ced.v2.co= v2_orig - - # now see how bad the normals are effected - angle_diff= 1.0 - - for ii, i in enumerate(test_faces): # local face index, global face index - cfa= collapse_faces[i] # this collapse face - try: - # can use perim, but area looks better. - if FACE_AREA_WEIGHT: - # Psudo code for wrighting - # angle_diff= The before and after angle difference between the collapsed and un-collapsed face. - # ... devide by 180 so the value will be between 0 and 1.0 - # ... add 1 so we can use it as a multiplyer and not make the area have no eefect (below) - # area_weight= The faces original area * the area weight - # ... add 1.0 so a small area face dosent make the angle_diff have no effect. - # - # Now multiply - (angle_diff * area_weight) - # ... The weight will be a minimum of 1.0 - we need to subtract this so more faces done give the collapse an uneven weighting. - - angle_diff+= ((1+(Ang(cfa.normal, new_nos[ii])/180)) * (1+(cfa.area * FACE_AREA_WEIGHT))) -1 # 4 is how much to influence area - else: - angle_diff+= (Ang(cfa.normal), new_nos[ii])/180 - - except: - pass - - - # This is very arbirary, feel free to modify - try: no_ang= (Ang(ced.v1.no, ced.v2.no)/180) + 1 - except: no_ang= 2.0 - - # do *= because we face the boundry weight to initialize the weight. 1.0 default. - new_weight *= ((no_ang * ced.length) * (1-(1/angle_diff)))# / max(len(test_faces), 1) - return new_weight - # End testloc - - - # Test the collapse locatons - collapse_loc_best= None - collapse_weight_best= 1000000000 - ii= 0 - for collapse_loc in new_locs: - if collapse_loc: # will only ever fail if smart loc is NAN - test_weight= test_loc(collapse_loc) - if test_weight < collapse_weight_best: - iii= ii - collapse_weight_best = test_weight - collapse_loc_best= collapse_loc - ii+=1 - - ced.collapse_loc= collapse_loc_best - ced.collapse_weight= collapse_weight_best - - - # are we using a weight map - if VGROUP_INF_REDUX: - v= vert_weights_map[i1]+vert_weights_map[i2] - ced.collapse_weight*= v - # End collapse Error - - # We can calculate the weights on __init__ but this is higher qualuity. - for ced in collapse_edges: - if ced.faces: # dont collapse faceless edges. - ed_set_collapse_error(ced) - - # Wont use the function again. - del ed_set_collapse_error - # END BOUNDRY. Can remove - - # sort by collapse weight - try: collapse_edges.sort(key = lambda ced: ced.collapse_weight) # edges will be used for sorting - except: collapse_edges.sort(lambda ced1, ced2: cmp(ced1.collapse_weight, ced2.collapse_weight)) # edges will be used for sorting - - - vert_collapsed= [0]*len(verts) - - collapse_edges_to_collapse= [] - - # Make a list of the first half edges we can collapse, - # these will better edges to remove. - collapse_count=0 - for ced in collapse_edges: - if ced.faces: - i1, i2= ced.key - # Use vert selections - if vert_collapsed[i1] or vert_collapsed[i2]: - pass - else: - # Now we know the verts havnyt been collapsed. - vert_collapsed[i2]= vert_collapsed[i1]= 1 # Dont collapse again. - collapse_count+=1 - collapse_edges_to_collapse.append(ced) - - # Get a subset of the entire list- the first "collapse_per_pass", that are best to collapse. - if collapse_count > 4: - collapse_count = int(collapse_count*collapse_per_pass) - else: - collapse_count = len(collapse_edges) - # We know edge_container_list_collapse can be removed. - for ced in collapse_edges_to_collapse: - """# DEBUG! - if DEBUG: - if DOUBLE_CHECK[ced.v1.index] or\ - DOUBLE_CHECK[ced.v2.index]: - raise 'Error' - else: - DOUBLE_CHECK[ced.v1.index]=1 - DOUBLE_CHECK[ced.v2.index]=1 - - tmp= (ced.v1.co+ced.v2.co)*0.5 - Blender.Window.SetCursorPos(tmp.x, tmp.y, tmp.z) - Blender.Window.RedrawAll() - """ - - # Chech if we have collapsed our quota. - collapse_count-=1 - if not collapse_count: - break - - current_face_count -= len(ced.faces) - - # Find and assign the real weights based on collapse loc. - - # Find the weights from the collapse error - if DO_WEIGHTS or DO_UV or DO_VCOL: - i1, i2= ced.key - # Dont use these weights since they may not have been used to make the collapse loc. - #w1= vert_weights[i1] - #w2= vert_weights[i2] - w1= (ced.v2.co-ced.collapse_loc).length - w2= (ced.v1.co-ced.collapse_loc).length - - # Normalize weights - wscale= w1+w2 - if not wscale: # no scale? - w1=w2= 0.5 - else: - w1/= wscale - w2/= wscale - - - # Interpolate the bone weights. - if DO_WEIGHTS: - - # add verts vgroups to eachother - wl1= vWeightList[i1] # v1 weight dict - wl2= vWeightList[i2] # v2 weight dict - for group_index in xrange(len_vgroups): - wl1[group_index]= wl2[group_index]= (wl1[group_index]*w1) + (wl2[group_index]*w2) - # Done finding weights. - - - - if DO_UV or DO_VCOL: - # Handel UV's and vert Colors! - for v, my_weight, other_weight, edge_my_uvs, edge_other_uvs, edge_my_cols, edge_other_cols in (\ - (ced.v1, w1, w2, ced.uv1, ced.uv2, ced.col1, ced.col2),\ - (ced.v2, w2, w1, ced.uv2, ced.uv1, ced.col2, ced.col1)\ - ): - uvs_mixed= [ uv_key_mix(edge_my_uvs[iii], edge_other_uvs[iii], my_weight, other_weight) for iii in xrange(len(edge_my_uvs)) ] - cols_mixed= [ col_key_mix(edge_my_cols[iii], edge_other_cols[iii], my_weight, other_weight) for iii in xrange(len(edge_my_cols)) ] - - for face_vert_index, cfa in vert_face_users[v.index]: - if len(cfa.verts)==3 and cfa not in ced.faces: # if the face is apart of this edge then dont bother finding the uvs since the face will be removed anyway. - - if DO_UV: - # UV COORDS - uvk= cfa.orig_uv[face_vert_index] - try: - tex_index= edge_my_uvs.index(uvk) - except: - tex_index= None - """ # DEBUG! - if DEBUG: - print 'not found', uvk, 'in', edge_my_uvs, 'ed index', ii, '\nwhat about', edge_other_uvs - """ - if tex_index != None: # This face uses a uv in the collapsing face. - do a merge - other_uv= edge_other_uvs[tex_index] - uv_vec= cfa.uv[face_vert_index] - uv_vec.x, uv_vec.y= uvs_mixed[tex_index] - - # TEXFACE COLORS - if DO_VCOL: - colk= cfa.orig_col[face_vert_index] - try: tex_index= edge_my_cols.index(colk) - except: pass - if tex_index != None: - other_col= edge_other_cols[tex_index] - col_ob= cfa.col[face_vert_index] - col_ob.r, col_ob.g, col_ob.b= cols_mixed[tex_index] - - # DEBUG! if DEBUG: rd() - - # Execute the collapse - ced.v1.sel= ced.v2.sel= True # Select so remove doubles removed the edges and faces that use it - ced.v1.co= ced.v2.co= ced.collapse_loc - - # DEBUG! if DEBUG: rd() - if current_face_count <= target_face_count: - break - - # Copy weights back to the mesh before we remove doubles. - if DO_WEIGHTS: - #BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) - BPyMesh.list2MeshWeight(me, groupNames, vWeightList) - - doubles= me.remDoubles(0.0001) - current_face_count= len(me.faces) - - if current_face_count <= target_face_count or not doubles: # not doubles shoule never happen. - break - - me.update() - Blender.Mesh.Mode(OLD_MESH_MODE) - - -# Example usage -def main(): - Blender.Window.EditMode(0) - scn= bpy.data.scenes.active - active_ob= scn.objects.active - t= Blender.sys.time() - redux(active_ob, 0.5) - print '%.4f' % (Blender.sys.time()-t) - -if __name__=='__main__': - main() diff --git a/release/scripts/bpymodules/BPyMessages.py b/release/scripts/bpymodules/BPyMessages.py deleted file mode 100644 index 8ee1aa6c707..00000000000 --- a/release/scripts/bpymodules/BPyMessages.py +++ /dev/null @@ -1,61 +0,0 @@ -from Blender import Draw, sys -def Error_NoMeshSelected(): - Draw.PupMenu('Error%t|No mesh objects selected') -def Error_NoActive(): - Draw.PupMenu('Error%t|No active object') -def Error_NoMeshActive(): - Draw.PupMenu('Error%t|Active object is not a mesh') -def Error_NoMeshUvSelected(): - Draw.PupMenu('Error%t|No mesh objects with texface selected') -def Error_NoMeshUvActive(): - Draw.PupMenu('Error%t|Active object is not a mesh with texface') -def Error_NoMeshMultiresEdit(): - Draw.PupMenu('Error%t|Unable to complete action with multires enabled') -def Error_NoMeshFaces(): - Draw.PupMenu('Error%t|Mesh has no faces') - -# File I/O messages -def Error_NoFile(path): - '''True if file missing, False if files there - - Use simply by doing... - if Error_NoFile(path): return - ''' - if not sys.exists(sys.expandpath(path)): - Draw.PupMenu("Error%t|Can't open file: " + path) - return True - return False - -def Error_NoDir(path): - '''True if dirs missing, False if dirs there - - Use simply by doing... - if Error_NoDir(path): return - ''' - if not sys.exists(sys.expandpath(path)): - Draw.PupMenu("Error%t|Path does not exist: " + path) - return True - return False - - -def Warning_MeshDistroyLayers(mesh): - '''Returns true if we can continue to edit the mesh, warn when using NMesh''' - if len(mesh.getUVLayerNames()) >1 and len(mesh.getColorLayerNames()) >1: - return True - - ret = Draw.PupMenu('Warning%t|This script will distroy inactive UV and Color layers, OK?') - if ret == -1: - return False - - return True - -def Warning_SaveOver(path): - '''Returns - True to save, False dont save''' - if sys.exists(sys.expandpath(path)): - ret= Draw.PupMenu('Save over%t|' + path) - if ret == -1: - return False - - return True - - diff --git a/release/scripts/bpymodules/BPyNMesh.py b/release/scripts/bpymodules/BPyNMesh.py deleted file mode 100644 index 043d8514db9..00000000000 --- a/release/scripts/bpymodules/BPyNMesh.py +++ /dev/null @@ -1,48 +0,0 @@ -# $Id$ -# -# -------------------------------------------------------------------------- -# BPyNMesh.py version 0.1 -# -------------------------------------------------------------------------- -# helper functions to be used by other scripts -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -# -------------------------------------------------------------------------- -# "Apply size and rotation" function by Jonas Petersen -# -------------------------------------------------------------------------- -# This function does (hopefully) exactly what the -# "Apply size and rotation" command does (CTRL-A in Object Mode). -def ApplySizeAndRotation(obj): - if obj.getType() != "Mesh": return - if obj.SizeX==1.0 and obj.SizeY==1.0 and obj.SizeZ==1.0 and obj.RotX == 0.0 and obj.RotY == 0.0 and obj.RotZ == 0.0: return - mesh = obj.getData() - matrix = obj.matrix - v = [0,0,0] - for vert in mesh.verts: - co = vert.co - v[0] = co[0]*matrix[0][0] + co[1]*matrix[1][0] + co[2]*matrix[2][0] - v[1] = co[0]*matrix[0][1] + co[1]*matrix[1][1] + co[2]*matrix[2][1] - v[2] = co[0]*matrix[0][2] + co[1]*matrix[1][2] + co[2]*matrix[2][2] - co[0], co[1], co[2] = v - obj.SizeX = obj.SizeY = obj.SizeZ = 1.0 - obj.RotX = obj.RotY = obj.RotZ = 0.0 - mesh.update() - diff --git a/release/scripts/bpymodules/BPyObject.py b/release/scripts/bpymodules/BPyObject.py deleted file mode 100644 index 54ff949218d..00000000000 --- a/release/scripts/bpymodules/BPyObject.py +++ /dev/null @@ -1,108 +0,0 @@ -import Blender - -def getObjectArmature(ob): - ''' - This returns the first armature the mesh uses. - remember there can be more then 1 armature but most people dont do that. - ''' - if ob.type != 'Mesh': - return None - - arm = ob.parent - if arm and arm.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.ARMATURE: - return arm - - for m in ob.modifiers: - if m.type== Blender.Modifier.Types.ARMATURE: - arm = m[Blender.Modifier.Settings.OBJECT] - if arm: - return arm - - return None - - -def getDerivedObjects(ob, PARTICLES= True): - ''' - Takes an objects and returnes a list of (ob, maxrix4x4) pairs - that are derived from this object - - This will include the object its self if it would be rendered. - all dupli's for eg are not rendered themselves. - - currently supports - * dupligroups - * dupliverts - * dupliframes - * static particles as a mesh - - it is possible this function will return an empty list. - ''' - - ob_mtx_pairs = ob.DupObjects - effects= ob.effects - - # Ignore self if were a dupli* or our parent is a duplivert. - if ob.enableDupFrames or ob.enableDupGroup or ob.enableDupVerts: - pass - else: - parent= ob.parent - if parent and parent.enableDupVerts: - pass - else: - if effects and (not effects[0].flag & Blender.Effect.Flags.EMESH): - # Particles mesh wont render - pass - else: - ob_mtx_pairs.append((ob, ob.matrixWorld)) - - - if PARTICLES: - type_vec= type(Blender.Mathutils.Vector()) - type_tp= type((0,0)) - type_ls= type([]) - - # TODO, particles per child object. - # TODO Support materials - me= Blender.Mesh.New() - for eff in effects: - par= eff.getParticlesLoc() - - if par: - type_par= type(par[0]) - - if type_par == type_vec: - # point particles - me.verts.extend(par) - - elif type_par == type_tp: - # edge pairs - start_index= len(me.verts) - me.verts.extend([v for p in par for v in p]) - me.edges.extend( [(i, i+1) for i in xrange(start_index, start_index + len(par) - 1 )] ) - - elif type_par == type_ls: - # lines of edges - start_index= len(me.verts) - me.verts.extend([v for line in par for v in line]) - - edges= [] - for line in par: - edges.extend( [(i,i+1) for i in xrange(start_index, start_index+len(line)-1) ] ) - start_index+= len(line) - - me.edges.extend(edges) - - if me.verts: - # If we have verts, then add the mesh - ob_par = Blender.Object.New('Mesh') - ob_par.link( me ) - - LOOSE= Blender.Mesh.EdgeFlags.LOOSE - for ed in me.edges: - ed.flag |= LOOSE - - # Particle's are in worldspace so an identity matrix is fine. - ob_mtx_pairs.append( (ob_par, Blender.Mathutils.Matrix()) ) - - return ob_mtx_pairs - - diff --git a/release/scripts/bpymodules/BPyRegistry.py b/release/scripts/bpymodules/BPyRegistry.py deleted file mode 100644 index 4d681e15937..00000000000 --- a/release/scripts/bpymodules/BPyRegistry.py +++ /dev/null @@ -1,267 +0,0 @@ -# -------------------------------------------------------------------------- -# Module BPyRegistry version 0.1 -# Helper functions to store / restore configuration data. -# -------------------------------------------------------------------------- -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br -# -# 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, -# -------------------------------------------------------------------------- - -# The Registry is a Python dictionary that is kept in Blender for as long as -# the program is running, where scripts can store / restore persistent data -# (data that is not lost when the script exits). This module provides -# functions to save and restore Registry entries as config data in the -# bpydata/config folder. Scripts just need to give an extra parameter to -# the Blender.Registry.Get/Set() functions to have their data automatically -# saved and restored when needed. -# -# Note: entries starting with an underscore are not saved, so script authors -# can use that fact to define data that is not meant to be stored in a -# config file. Example: data to be passed to another script and references to -# invalid data, like Blender objects and any function or method. -# -# Check the Blender.Registry documentation for more information. - -import Blender -from Blender import Registry, sys as bsys - -_EXT = '.cfg' # file extension for saved config data - -# limits: -#MAX_ITEMS_NUM = 60 # max number of keys per dict and itens per list and tuple -#MAX_STR_LEN = 300 # max string length (remember this is just for config data) - -_CFG_DIR = '' -if Blender.Get('udatadir'): - _CFG_DIR = Blender.sys.join(Blender.Get('udatadir'), 'config') -if not _CFG_DIR or not bsys.exists(_CFG_DIR): - _CFG_DIR = Blender.sys.join(Blender.Get('datadir'), 'config') -if not bsys.exists(_CFG_DIR): - _CFG_DIR = '' - -# to compare against, so we don't write to a cvs tree: -_CVS_SUBPATH = 'release/scripts/bpydata/config/' -if bsys.dirsep == '\\': - _CVS_SUBPATH = _CVS_SUBPATH.replace('/', '\\') - -_KEYS = [k for k in Registry.Keys() if k[0] != '_'] - -# _ITEMS_NUM = 0 - -def _sanitize(o): - "Check recursively that all objects are valid, set invalid ones to None" - - # global MAX_ITEMS_NUM, MAX_STR_LEN, _ITEMS_NUM - - valid_types = [int, float, bool, long, type] - valid_checked_types = [str, unicode] - # Only very simple types are considered valid for configuration data, - # functions, methods and Blender objects (use their names instead) aren't. - - t = type(o) - - if t == dict: - ''' - _ITEMS_NUM += len(o) - if _ITEMS_NUM > MAX_ITEMS_NUM: - return None - ''' - for k, v in o.iteritems(): - o[k] = _sanitize(v) - elif t in [list, tuple]: - ''' - _ITEMS_NUM += len(o) - if _ITEMS_NUM > MAX_ITEMS_NUM: - return None - ''' - return [_sanitize(i) for i in o] - elif t in valid_types: - return o - elif t in valid_checked_types: - ''' - if len(o) > MAX_STR_LEN: - o = o[:MAX_STR_LEN] - ''' - return o - else: return None - - return o - - -def _dict_to_str(name, d): - "Return a pretty-print version of the passed dictionary" - if not d: return 'None' # d can be None if there was no config to pass - - if name: l = ['%s = {' % name] - else: l = ['{'] - #keys = d.keys() - for k,v in d.iteritems(): # .keys() - if type(v) == dict: - l.append("'%s': %s" % (k, _dict_to_str(None, v))) - else: - l.append("'%s': %s," % (k, repr(v))) - if name: l.append('}') - else: l.append('},') - return "\n".join(l) - -_HELP_MSG = """ -Please create a valid scripts config dir tree either by -copying release/scripts/ tree to your dir -or by copying release/scripts/bpydata/ tree to a user -defined scripts dir that you can set in the -User Preferences -> Paths tab -> Python path input box. -""" - -def _check_dir(): - global _CFG_DIR, _CVS_SUBPATH, _HELP_MSG - - if not _CFG_DIR: - errmsg = "scripts config dir not found!\n%s" % _HELP_MSG - raise IOError, errmsg - elif _CFG_DIR.find(_CVS_SUBPATH) > 0: - errmsg = """ -Your scripts config dir:\n%s -seems to reside in your local Blender's cvs tree.\n%s""" % (_CFG_DIR, _HELP_MSG) - raise SystemError, errmsg - else: return - - -# API: - -BPY_KEY_MISSING = 0 -BPY_KEY_IN_REGISTRY = 1 -BPY_KEY_IN_FILE = 2 - -def HasConfigData (key): - """ - Check if the given key exists, either already loaded in the Registry dict or - as a file in the script data config dir. - @type key: string - @param key: a given key name. - @returns: - - 0: key does not exist; - - 1: key exists in the Registry dict only; - - 2: key exists as a file only; - - 3: key exists in the Registry dict and also as a file. - @note: for readability it's better to check against the constant bitmasks - BPY_KEY_MISSING = 0, BPY_KEY_IN_REGISTRY = 1 and BPY_KEY_IN_FILE = 2. - """ - - fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT)) - - result = BPY_KEY_MISSING - if key in Registry.Keys(): result |= BPY_KEY_IN_REGISTRY - if bsys.exists(fname): result |= BPY_KEY_IN_FILE - - return result - - -def LoadConfigData (key = None): - """ - Load config data from file(s) to the Registry dictionary. - @type key: string - @param key: a given key name. If None (default), all available keys are - loaded. - @returns: None - """ - - _check_dir() - - import os - - if not key: - files = \ - [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)] - else: - files = [] - fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT)) - if bsys.exists(fname): files.append(fname) - - for p in files: - try: - f = file(p, 'r') - lines = f.readlines() - f.close() - if lines: # Lines may be blank - mainkey = lines[0].split('=')[0].strip() - pysrc = "\n".join(lines) - exec(pysrc) - exec("Registry.SetKey('%s', %s)" % (str(mainkey), mainkey)) - except Exception, e: - raise Warning(e) # Resend exception as warning - - -def RemoveConfigData (key = None): - """ - Remove this key's config file from the <(u)datadir>/config/ folder. - @type key: string - @param key: the name of the key to be removed. If None (default) all - available config files are deleted. - """ - - _check_dir() - - if not key: - files = \ - [bsys.join(_CFG_DIR, f) for f in os.listdir(_CFG_DIR) if f.endswith(_EXT)] - else: - files = [] - fname = bsys.join(_CFG_DIR, "%s%s" % (key, _EXT)) - if bsys.exists(fname): files.append(fname) - - import os - - try: - for p in files: - os.remove(p) # remove the file(s) - except Exception, e: - raise Warning(e) # Resend exception as warning - - -def SaveConfigData (key = None): - """ - Save Registry key(s) as file(s) in the <(u)datadir>/config/ folder. - @type key: string - @param key: the name of the key to be saved. If None (default) all - available keys are saved. - """ - - global _KEYS, _CFG_DIR - - _check_dir() - - if key: keys = [key] - else: keys = _KEYS - - for mainkey in keys: - cfgdict = Registry.GetKey(mainkey).copy() - for k in cfgdict: # .keys() - if not k or k[0] == '_': - del cfgdict[k] - - if not cfgdict: continue - - try: - filename = bsys.join(_CFG_DIR, "%s%s" % (mainkey, _EXT)) - f = file(filename, 'w') - output = _dict_to_str(mainkey, _sanitize(cfgdict)) - if output!='None': - f.write(output) - f.close() - except Exception, e: - raise Warning(e) # Resend exception as warning diff --git a/release/scripts/bpymodules/BPyRender.py b/release/scripts/bpymodules/BPyRender.py deleted file mode 100644 index 951e1ae6300..00000000000 --- a/release/scripts/bpymodules/BPyRender.py +++ /dev/null @@ -1,633 +0,0 @@ -import Blender -from Blender import Scene, sys, Camera, Object, Image -from Blender.Scene import Render -Vector= Blender.Mathutils.Vector - - -def extFromFormat(format): - if format == Render.TARGA: return 'tga' - if format == Render.RAWTGA: return 'tga' - if format == Render.HDR: return 'hdr' - if format == Render.PNG: return 'png' - if format == Render.BMP: return 'bmp' - if format == Render.JPEG: return 'jpg' - if format == Render.HAMX: return 'ham' - if format == Render.TIFF: return 'tif' - if format == Render.CINEON: return 'cine' - if format == Render.DPX: return 'tif' - if format == Render.OPENEXR: return 'exr' - if format == Render.IRIS: return 'rgb' - return '' - - - -def imageFromObjectsOrtho(objects, path, width, height, smooth, alpha= True, camera_matrix= None, format=Render.PNG): - ''' - Takes any number of objects and renders them on the z axis, between x:y-0 and x:y-1 - Usefull for making images from a mesh without per pixel operations - - objects must be alredy placed - - smooth, anti alias True/False - - path renders to a PNG image - - alpha weather to render background as alpha - - returns the blender image - ''' - ext = '.' + extFromFormat(format) - print ext - # remove an extension if its alredy there - if path.lower().endswith(ext): - path= path[:-4] - - path_expand= sys.expandpath(path) + ext - - print path_expand, 'path' - - # Touch the path - try: - f= open(path_expand, 'w') - f.close() - except: - raise 'Error, could not write to path:' + path_expand - - - # RENDER THE FACES. - scn= Scene.GetCurrent() - render_scn= Scene.New() - render_scn.makeCurrent() - render_scn.Layers |= (1<<20)-1 # all layers enabled - - # Add objects into the current scene - for ob in objects: - render_scn.link(ob) - - render_context= render_scn.getRenderingContext() - render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path. - - - render_context.imageSizeX(width) - render_context.imageSizeY(height) - - if smooth: - render_context.enableOversampling(True) - render_context.setOversamplingLevel(16) - else: - render_context.enableOversampling(False) - - render_context.setRenderWinSize(100) - render_context.setImageType(format) - render_context.enableExtensions(True) - #render_context.enableSky() # No alpha needed. - if alpha: - render_context.alphaMode= 1 - render_context.enableRGBAColor() - else: - render_context.alphaMode= 0 - render_context.enableRGBColor() - - render_context.displayMode= 0 # fullscreen - - # New camera and object - render_cam_data= Camera.New('ortho') - render_cam_ob= Object.New('Camera') - render_cam_ob.link(render_cam_data) - render_scn.link(render_cam_ob) - render_scn.objects.camera = render_cam_ob - - render_cam_data.type= 'ortho' - - - - # Position the camera - if camera_matrix: - render_cam_ob.setMatrix(camera_matrix) - # We need to take into account the matrix scaling when setting the size - # so we get the image bounds defined by the matrix - # first get the x and y factors from the matrix. - # To render the correct dimensions we must use the aspy and aspy to force the matrix scale to - # override the aspect enforced by the width and weight. - cent= Vector() * camera_matrix - xvec= Vector(1,0,0) * camera_matrix - yvec= Vector(0,1,0) * camera_matrix - # zvec= Vector(0,0,1) * camera_matrix - xlen = (cent-xvec).length # half height of the image - ylen = (cent-yvec).length # half width of the image - # zlen = (cent-zvec).length # dist to place the camera? - just use the loc for now. - - - # less then 1.0 portrate, 1.0 or more is portrate - asp_cam_mat= xlen/ylen # divide by zero? - possible but scripters fault. - asp_image_res= float(width)/height - #print 'asp quad', asp_cam_mat, 'asp_image', asp_image_res - #print 'xylen', xlen, ylen, 'w/h', width, height - # Setup the aspect - - if asp_cam_mat > asp_image_res: - # camera is wider then image res. - # to make the image wider, reduce the aspy - asp_diff= asp_image_res/asp_cam_mat - min_asp= asp_diff * 200 - #print 'X', min_asp - - elif asp_cam_mat < asp_image_res: # asp_cam_mat < asp_image_res - # camera is narrower then image res - # to make the image narrower, reduce the aspx - asp_diff= asp_cam_mat/asp_image_res - min_asp= asp_diff * 200 - #print 'Y', min_asp - else: - min_asp= 200 - - # set the camera size - if xlen > ylen: - if asp_cam_mat > asp_image_res: - render_context.aspectX= 200 # get the greatest range possible - render_context.aspectY= min_asp # get the greatest range possible - else: - render_context.aspectY= 200 # get the greatest range possible - render_context.aspectX= min_asp # get the greatest range possible - #print "xlen bigger" - render_cam_data.scale= xlen * 2 - elif xlen < ylen:# ylen is bigger - if asp_cam_mat > asp_image_res: - render_context.aspectX= 200 # get the greatest range possible - render_context.aspectY= min_asp # get the greatest range possible - else: - render_context.aspectY= 200 # get the greatest range possible - render_context.aspectX= min_asp # get the greatest range possible - #print "ylen bigger" - render_cam_data.scale= ylen *2 - else: - # asppect 1:1 - #print 'NOLEN Bigger' - render_cam_data.scale= xlen * 2 - - #print xlen, ylen, 'xlen, ylen' - - else: - if width > height: - min_asp = int((float(height) / width) * 200) - render_context.aspectX= min_asp - render_context.aspectY= 200 - else: - min_asp = int((float(width) / height) * 200) - render_context.aspectX= 200 - render_context.aspectY= min_asp - - - render_cam_data.scale= 1.0 - render_cam_ob.LocZ= 1.0 - render_cam_ob.LocX= 0.5 - render_cam_ob.LocY= 0.5 - - Blender.Window.RedrawAll() - - render_context.render() - render_context.saveRenderedImage(path) - Render.CloseRenderWindow() - #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND): - # raise 'Error!!!' - - scn.makeCurrent() - Scene.Unlink(render_scn) - - # NOW APPLY THE SAVED IMAGE TO THE FACES! - #print PREF_IMAGE_PATH_EXPAND - try: - target_image= Image.Load(path_expand) - return target_image - except: - raise 'Error: Could not render or load the image at path "%s"' % path_expand - return - - - -#-----------------------------------------------------------------------------# -# UV Baking functions, make a picture from mesh(es) uvs # -#-----------------------------------------------------------------------------# - -def mesh2uv(me_s, PREF_SEL_FACES_ONLY=False): - ''' - Converts a uv mapped mesh into a 2D Mesh from UV coords. - returns a triple - - (mesh2d, face_list, col_list) - "mesh" is the new mesh and... - "face_list" is the faces that were used to make the mesh, - "material_list" is a list of materials used by each face - These are in alligned with the meshes faces, so you can easerly copy data between them - - ''' - render_me= Blender.Mesh.New() - render_me.verts.extend( [Vector(0,0,0),] ) # 0 vert uv bugm dummy vert - face_list= [] - material_list= [] - for me in me_s: - me_materials= me.materials - if PREF_SEL_FACES_ONLY: - me_faces= [f for f in me.faces if f.sel] - else: - me_faces= me.faces - - face_list.extend(me_faces) - - # Dittro - if me_materials: - material_list.extend([me_materials[f.mat] for f in me_faces]) - else: - material_list.extend([None]*len(me_faces)) - - # Now add the verts - render_me.verts.extend( [ Vector(uv.x, uv.y, 0) for f in face_list for uv in f.uv ] ) - - # Now add the faces - tmp_faces= [] - vert_offset= 1 - for f in face_list: - tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] ) - vert_offset+= len(f) - - render_me.faces.extend(tmp_faces) - render_me.faceUV=1 - return render_me, face_list, material_list - - -def uvmesh_apply_normals(render_me, face_list): - '''Worldspace normals to vertex colors''' - for i, f in enumerate(render_me.faces): - face_orig= face_list[i] - f_col= f.col - for j, v in enumerate(face_orig): - c= f_col[j] - nx, ny, nz= v.no - c.r= int((nx+1)*128)-1 - c.g= int((ny+1)*128)-1 - c.b= int((nz+1)*128)-1 - -def uvmesh_apply_image(render_me, face_list): - '''Copy the image and uvs from the original faces''' - for i, f in enumerate(render_me.faces): - f.uv= face_list[i].uv - f.image= face_list[i].image - - -def uvmesh_apply_vcol(render_me, face_list): - '''Copy the vertex colors from the original faces''' - for i, f in enumerate(render_me.faces): - face_orig= face_list[i] - f_col= f.col - for j, c_orig in enumerate(face_orig.col): - c= f_col[j] - c.r= c_orig.r - c.g= c_orig.g - c.b= c_orig.b - -def uvmesh_apply_matcol(render_me, material_list): - '''Get the vertex colors from the original materials''' - for i, f in enumerate(render_me.faces): - mat_orig= material_list[i] - f_col= f.col - if mat_orig: - for c in f_col: - c.r= int(mat_orig.R*255) - c.g= int(mat_orig.G*255) - c.b= int(mat_orig.B*255) - else: - for c in f_col: - c.r= 255 - c.g= 255 - c.b= 255 - -def uvmesh_apply_col(render_me, color): - '''Get the vertex colors from the original materials''' - r,g,b= color - for i, f in enumerate(render_me.faces): - f_col= f.col - for c in f_col: - c.r= r - c.g= g - c.b= b - - -def vcol2image(me_s,\ - PREF_IMAGE_PATH,\ - PREF_IMAGE_SIZE,\ - PREF_IMAGE_BLEED,\ - PREF_IMAGE_SMOOTH,\ - PREF_IMAGE_WIRE,\ - PREF_IMAGE_WIRE_INVERT,\ - PREF_IMAGE_WIRE_UNDERLAY,\ - PREF_USE_IMAGE,\ - PREF_USE_VCOL,\ - PREF_USE_MATCOL,\ - PREF_USE_NORMAL,\ - PREF_USE_TEXTURE,\ - PREF_SEL_FACES_ONLY): - - - def rnd_mat(): - render_mat= Blender.Material.New() - mode= render_mat.mode - - # Dont use lights ever - mode |= Blender.Material.Modes.SHADELESS - - if PREF_IMAGE_WIRE: - # Set the wire color - if PREF_IMAGE_WIRE_INVERT: - render_mat.rgbCol= (1,1,1) - else: - render_mat.rgbCol= (0,0,0) - - mode |= Blender.Material.Modes.WIRE - if PREF_USE_VCOL or PREF_USE_MATCOL or PREF_USE_NORMAL: # both vcol and material color use vertex cols to avoid the 16 max limit in materials - mode |= Blender.Material.Modes.VCOL_PAINT - if PREF_USE_IMAGE: - mode |= Blender.Material.Modes.TEXFACE - - # Copy back the mode - render_mat.mode |= mode - return render_mat - - - render_me, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY) - - # Normals exclude all others - if PREF_USE_NORMAL: - uvmesh_apply_normals(render_me, face_list) - else: - if PREF_USE_IMAGE: - uvmesh_apply_image(render_me, face_list) - uvmesh_apply_vcol(render_me, face_list) - - elif PREF_USE_VCOL: - uvmesh_apply_vcol(render_me, face_list) - - elif PREF_USE_MATCOL: - uvmesh_apply_matcol(render_me, material_list) - - elif PREF_USE_TEXTURE: - # if we have more then 16 materials across all the mesh objects were stuffed :/ - # get unique materials - tex_unique_materials= dict([(mat.name, mat) for mat in material_list]).values()[:16] # just incase we have more then 16 - tex_me= Blender.Mesh.New() - - # Backup the original shadless setting - tex_unique_materials_shadeless= [ mat.mode & Blender.Material.Modes.SHADELESS for mat in tex_unique_materials ] - - # Turn shadeless on - for mat in tex_unique_materials: - mat.mode |= Blender.Material.Modes.SHADELESS - - # Assign materials - render_me.materials= tex_unique_materials - - - - tex_material_indicies= dict([(mat.name, i) for i, mat in enumerate(tex_unique_materials)]) - - tex_me.verts.extend([Vector(0,0,0),]) # dummy - tex_me.verts.extend( [ Vector(v.co) for f in face_list for v in f ] ) - - # Now add the faces - tmp_faces= [] - vert_offset= 1 - for f in face_list: - tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] ) - vert_offset+= len(f) - - tex_me.faces.extend(tmp_faces) - - # Now we have the faces, put materials and normal, uvs into the mesh - if len(tex_me.faces) != len(face_list): - # Should never happen - raise "Error face length mismatch" - - # Copy data to the mesh that could be used as texture coords - for i, tex_face in enumerate(tex_me.faces): - orig_face= face_list[i] - - # Set the material index - try: - render_face.mat= tex_material_indicies[ material_list[i].name ] - except: - # more then 16 materials - pass - - - # set the uvs on the texmesh mesh - tex_face.uv= orig_face.uv - - orig_face_v= orig_face.v - # Set the normals - for j, v in enumerate(tex_face): - v.no= orig_face_v[j].no - - # Set the texmesh - render_me.texMesh= tex_me - # END TEXMESH - - - # Handel adding objects - render_ob= Blender.Object.New('Mesh') - render_ob.link(render_me) - - if not PREF_USE_TEXTURE: # textures use the original materials - render_me.materials= [rnd_mat()] - - - obs= [render_ob] - - - if PREF_IMAGE_WIRE_UNDERLAY: - # Make another mesh with the material colors - render_me_under, face_list, material_list= mesh2uv(me_s, PREF_SEL_FACES_ONLY) - - uvmesh_apply_matcol(render_me_under, material_list) - - # Handel adding objects - render_ob= Blender.Object.New('Mesh') - render_ob.link(render_me_under) - render_ob.LocZ= -0.01 - - # Add material and disable wire - mat= rnd_mat() - mat.rgbCol= 1,1,1 - mat.alpha= 0.5 - mat.mode &= ~Blender.Material.Modes.WIRE - mat.mode |= Blender.Material.Modes.VCOL_PAINT - - render_me_under.materials= [mat] - - obs.append(render_ob) - - elif PREF_IMAGE_BLEED and not PREF_IMAGE_WIRE: - # EVIL BLEEDING CODE!! - Just do copys of the mesh and place behind. Crufty but better then many other methods I have seen. - Cam - BLEED_PIXEL= 1.0/PREF_IMAGE_SIZE - z_offset= 0.0 - for i in xrange(PREF_IMAGE_BLEED): - for diag1, diag2 in ((-1,-1),(-1,1),(1,-1),(1,1), (1,0), (0,1), (-1,0), (0, -1)): # This line extends the object in 8 different directions, top avoid bleeding. - - render_ob= Blender.Object.New('Mesh') - render_ob.link(render_me) - - render_ob.LocX= (i+1)*diag1*BLEED_PIXEL - render_ob.LocY= (i+1)*diag2*BLEED_PIXEL - render_ob.LocZ= -z_offset - - obs.append(render_ob) - z_offset += 0.01 - - - - image= imageFromObjectsOrtho(obs, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_IMAGE_SIZE, PREF_IMAGE_SMOOTH) - - # Clear from memory as best as we can - render_me.verts= None - - if PREF_IMAGE_WIRE_UNDERLAY: - render_me_under.verts= None - - if PREF_USE_TEXTURE: - tex_me.verts= None - # Restire Shadeless setting - for i, mat in enumerate(tex_unique_materials): - # we know there all on so turn it off of its not set - if not tex_unique_materials_shadeless[i]: - mat.mode &= ~Blender.Material.Modes.SHADELESS - - return image - -def bakeToPlane(sce, ob_from, width, height, bakemodes, axis='z', margin=0, depth=32): - ''' - Bakes terrain onto a plane from one object - sce - scene to bake with - ob_from - mesh object - width/height - image size - bakemodes - list of baking modes to use, Blender.Scene.Render.BakeModes.NORMALS, Blender.Scene.Render.BakeModes.AO ... etc - axis - axis to allign the plane to. - margin - margin setting for baking. - depth - bit depth for the images to bake into, (32 or 128 for floating point images) - Example: - import Blender - from Blender import * - import BPyRender - sce = Scene.GetCurrent() - ob = Object.Get('Plane') - BPyRender.bakeToPlane(sce, ob, 512, 512, [Scene.Render.BakeModes.DISPLACEMENT, Scene.Render.BakeModes.NORMALS], 'z', 8 ) - ''' - - # Backup bake settings - rend = sce.render - BACKUP_bakeDist = rend.bakeDist - BACKUP_bakeBias = rend.bakeBias - BACKUP_bakeMode = rend.bakeMode - BACKUP_bakeClear = rend.bakeClear - BACKUP_bakeMargin = rend.bakeMargin - BACKUP_bakeToActive = rend.bakeToActive - BACKUP_bakeNormalize = rend.bakeNormalize - - # Backup object selection - BACKUP_obsel = list(sce.objects.selected) - BACKUP_obact = sce.objects.active - - # New bake settings - rend.bakeClear = True - rend.bakeMargin = margin - rend.bakeToActive = True - rend.bakeNormalize = True - - # Assume a mesh - me_from = ob_from.getData(mesh=1) - - xmin = ymin = zmin = 10000000000 - xmax = ymax = zmax =-10000000000 - - # Dont trust bounding boxes :/ - #bounds = ob_from.boundingBox - #for v in bounds: - # x,y,z = tuple(v) - mtx = ob_from.matrixWorld - for v in me_from.verts: - x,y,z = tuple(v.co*mtx) - - xmax = max(xmax, x) - ymax = max(ymax, y) - zmax = max(zmax, z) - - xmin = min(xmin, x) - ymin = min(ymin, y) - zmin = min(zmin, z) - - if axis=='x': - xmed = (xmin+xmax)/2.0 - co1 = (xmed, ymin, zmin) - co2 = (xmed, ymin, zmax) - co3 = (xmed, ymax, zmax) - co4 = (xmed, ymax, zmin) - rend.bakeDist = ((xmax-xmin)/2.0) + 0.000001 # we need a euler value for this since it - elif axis=='y': - ymed = (ymin+ymax)/2.0 - co1 = (xmin, ymed, zmin) - co2 = (xmin, ymed, zmax) - co3 = (xmax, ymed, zmax) - co4 = (xmax, ymed, zmin) - rend.bakeDist = ((ymax-ymin)/2.0) + 0.000001 - elif axis=='z': - zmed = (zmin+zmax)/2.0 - co1 = (xmin, ymin, zmed) - co2 = (xmin, ymax, zmed) - co3 = (xmax, ymax, zmed) - co4 = (xmax, ymin, zmed) - rend.bakeDist = ((zmax-zmin)/2.0) + 0.000001 - else: - raise "invalid axis" - me_plane = Blender.Mesh.New() - ob_plane = Blender.Object.New('Mesh') - ob_plane.link(me_plane) - sce.objects.link(ob_plane) - ob_plane.Layers = ob_from.Layers - - ob_from.sel = 1 # make active - sce.objects.active = ob_plane - ob_plane.sel = 1 - - me_plane.verts.extend([co4, co3, co2, co1]) - me_plane.faces.extend([(0,1,2,3)]) - me_plane.faceUV = True - me_plane_face = me_plane.faces[0] - uvs = me_plane_face.uv - uvs[0].x = 0.0; uvs[0].y = 0.0 - uvs[1].x = 0.0; uvs[1].y = 1.0 - uvs[2].x = 1.0; uvs[2].y = 1.0 - uvs[3].x = 1.0; uvs[3].y = 0.0 - - images_return = [] - - for mode in bakemodes: - img = Blender.Image.New('bake', width, height, depth) - - me_plane_face.image = img - rend.bakeMode = mode - rend.bake() - images_return.append( img ) - - # Restore bake settings - #''' - rend.bakeDist = BACKUP_bakeDist - rend.bakeBias = BACKUP_bakeBias - rend.bakeMode = BACKUP_bakeMode - rend.bakeClear = BACKUP_bakeClear - rend.bakeMargin = BACKUP_bakeMargin - rend.bakeToActive = BACKUP_bakeToActive - rend.bakeNormalize = BACKUP_bakeNormalize - - - # Restore obsel - sce.objects.selected = BACKUP_obsel - sce.objects.active = BACKUP_obact - - me_plane.verts = None - sce.objects.unlink(ob_plane) - #''' - - return images_return - diff --git a/release/scripts/bpymodules/BPySys.py b/release/scripts/bpymodules/BPySys.py deleted file mode 100644 index a2d2120ebff..00000000000 --- a/release/scripts/bpymodules/BPySys.py +++ /dev/null @@ -1,74 +0,0 @@ - -## This was used to make V, but faster not to do all that -##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_' -##v = range(255) -##for c in valid: v.remove(ord(c)) -v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] -invalid = ''.join([chr(i) for i in v]) -## del v, c, i, valid -del v, i - -def cleanName(name): - for ch in invalid: name = name.replace(ch, '_') - return name - -def caseInsensitivePath(path, RET_FOUND=False): - ''' - Get a case insensitive path on a case sensitive system - - RET_FOUND is for internal use only, to avoid too many calls to os.path.exists - # Example usage - getCaseInsensitivePath('/hOmE/mE/sOmEpAtH.tXt') - ''' - import os # todo, what happens with no os? - - if os==None: - if RET_FOUND: ret = path, True - else: ret = path - return ret - - if path=='' or os.path.exists(path): - if RET_FOUND: ret = path, True - else: ret = path - return ret - - f = os.path.basename(path) # f may be a directory or a file - d = os.path.dirname(path) - - suffix = '' - if not f: # dir ends with a slash? - if len(d) < len(path): - suffix = path[:len(path)-len(d)] - - f = os.path.basename(d) - d = os.path.dirname(d) - - if not os.path.exists(d): - d, found = caseInsensitivePath(d, True) - - if not found: - if RET_FOUND: ret = path, False - else: ret = path - return ret - - # at this point, the directory exists but not the file - - try: # we are expecting 'd' to be a directory, but it could be a file - files = os.listdir(d) - except: - if RET_FOUND: ret = path, False - else: ret = path - - f_low = f.lower() - - try: f_nocase = [fl for fl in files if fl.lower() == f_low][0] - except: f_nocase = None - - if f_nocase: - if RET_FOUND: ret = os.path.join(d, f_nocase) + suffix, True - else: ret = os.path.join(d, f_nocase) + suffix - return ret - else: - if RET_FOUND: ret = path, False - else: ret = path - return ret # cant find the right one, just return the path as is. \ No newline at end of file diff --git a/release/scripts/bpymodules/BPyTextPlugin.py b/release/scripts/bpymodules/BPyTextPlugin.py deleted file mode 100644 index cd5a085de37..00000000000 --- a/release/scripts/bpymodules/BPyTextPlugin.py +++ /dev/null @@ -1,814 +0,0 @@ -"""The BPyTextPlugin Module - -Use get_cached_descriptor(txt) to retrieve information about the script held in -the txt Text object. - -Use print_cache_for(txt) to print the information to the console. - -Use line, cursor = current_line(txt) to get the logical line and cursor position - -Use get_targets(line, cursor) to find out what precedes the cursor: - aaa.bbb.cc|c.ddd -> ['aaa', 'bbb', 'cc'] - -Use resolve_targets(txt, targets) to turn a target list into a usable object if -one is found to match. -""" - -import bpy, sys, os -import __builtin__, tokenize -from Blender.sys import time -from tokenize import generate_tokens, TokenError, \ - COMMENT, DEDENT, INDENT, NAME, NEWLINE, NL, STRING, NUMBER - -class Definition: - """Describes a definition or defined object through its name, line number - and docstring. This is the base class for definition based descriptors. - """ - - def __init__(self, name, lineno, doc=''): - self.name = name - self.lineno = lineno - self.doc = doc - -class ScriptDesc: - """Describes a script through lists of further descriptor objects (classes, - defs, vars) and dictionaries to built-in types (imports). If a script has - not been fully parsed, its incomplete flag will be set. The time of the last - parse is held by the time field and the name of the text object from which - it was parsed, the name field. - """ - - def __init__(self, name, imports, classes, defs, vars, incomplete=False): - self.name = name - self.imports = imports - self.classes = classes - self.defs = defs - self.vars = vars - self.incomplete = incomplete - self.parse_due = 0 - - def set_delay(self, delay): - self.parse_due = time() + delay - -class ClassDesc(Definition): - """Describes a class through lists of further descriptor objects (defs and - vars). The name of the class is held by the name field and the line on - which it is defined is held in lineno. - """ - - def __init__(self, name, parents, defs, vars, lineno, doc=''): - Definition.__init__(self, name, lineno, doc) - self.parents = parents - self.defs = defs - self.vars = vars - -class FunctionDesc(Definition): - """Describes a function through its name and list of parameters (name, - params) and the line on which it is defined (lineno). - """ - - def __init__(self, name, params, lineno, doc=''): - Definition.__init__(self, name, lineno, doc) - self.params = params - -class VarDesc(Definition): - """Describes a variable through its name and type (if ascertainable) and the - line on which it is defined (lineno). If no type can be determined, type - will equal None. - """ - - def __init__(self, name, type, lineno): - Definition.__init__(self, name, lineno) - self.type = type # None for unknown (supports: dict/list/str) - -# Context types -CTX_UNSET = -1 -CTX_NORMAL = 0 -CTX_SINGLE_QUOTE = 1 -CTX_DOUBLE_QUOTE = 2 -CTX_COMMENT = 3 - -# Python keywords -KEYWORDS = ['and', 'del', 'from', 'not', 'while', 'as', 'elif', 'global', - 'or', 'with', 'assert', 'else', 'if', 'pass', 'yield', - 'break', 'except', 'import', 'print', 'class', 'exec', 'in', - 'raise', 'continue', 'finally', 'is', 'return', 'def', 'for', - 'lambda', 'try' ] - -# Module file extensions -MODULE_EXTS = ['.py', '.pyc', '.pyo', '.pyw', '.pyd'] - -ModuleType = type(__builtin__) -NoneScriptDesc = ScriptDesc('', dict(), dict(), dict(), dict(), True) - -_modules = {} -_modules_updated = 0 -_parse_cache = dict() - -def _load_module_names(): - """Searches the sys.path for module files and lists them, along with - sys.builtin_module_names, in the global dict _modules. - """ - - global _modules - - for n in sys.builtin_module_names: - _modules[n] = None - for p in sys.path: - if p == '': p = os.curdir - if not os.path.isdir(p): continue - for f in os.listdir(p): - for ext in MODULE_EXTS: - if f.endswith(ext): - _modules[f[:-len(ext)]] = None - break - -_load_module_names() - -def _trim_doc(doc): - """Trims the quotes from a quoted STRING token (eg. "'''text'''" -> "text") - """ - - l = len(doc) - i = 0 - while i < l/2 and (doc[i] == "'" or doc[i] == '"'): - i += 1 - return doc[i:-i] - -def resolve_targets(txt, targets): - """Attempts to return a useful object for the locally or externally defined - entity described by targets. If the object is local (defined in txt), a - Definition instance is returned. If the object is external (imported or - built in), the object itself is returned. If no object can be found, None is - returned. - """ - - count = len(targets) - if count==0: return None - - obj = None - local = None - i = 1 - - desc = get_cached_descriptor(txt) - b = targets[0].find('(') - if b==-1: b = None # Trick to let us use [:b] and get the whole string - - if desc.classes.has_key(targets[0][:b]): - local = desc.classes[targets[0][:b]] - elif desc.defs.has_key(targets[0]): - local = desc.defs[targets[0]] - elif desc.vars.has_key(targets[0]): - obj = desc.vars[targets[0]].type - - if local: - while i < count: - b = targets[i].find('(') - if b==-1: b = None - if hasattr(local, 'classes') and local.classes.has_key(targets[i][:b]): - local = local.classes[targets[i][:b]] - elif hasattr(local, 'defs') and local.defs.has_key(targets[i]): - local = local.defs[targets[i]] - elif hasattr(local, 'vars') and local.vars.has_key(targets[i]): - obj = local.vars[targets[i]].type - local = None - i += 1 - break - else: - local = None - break - i += 1 - - if local: return local - - if not obj: - if desc.imports.has_key(targets[0]): - obj = desc.imports[targets[0]] - else: - builtins = get_builtins() - if builtins.has_key(targets[0]): - obj = builtins[targets[0]] - - while obj and i < count: - if hasattr(obj, targets[i]): - obj = getattr(obj, targets[i]) - else: - obj = None - break - i += 1 - - return obj - -def get_cached_descriptor(txt, force_parse=0): - """Returns the cached ScriptDesc for the specified Text object 'txt'. If the - script has not been parsed in the last 'period' seconds it will be reparsed - to obtain this descriptor. - - Specifying TP_AUTO for the period (default) will choose a period based on the - size of the Text object. Larger texts are parsed less often. - """ - - global _parse_cache - - parse = True - key = hash(txt) - if not force_parse and _parse_cache.has_key(key): - desc = _parse_cache[key] - if desc.parse_due > time(): - parse = desc.incomplete - - if parse: - desc = parse_text(txt) - - return desc - -def parse_text(txt): - """Parses an entire script's text and returns a ScriptDesc instance - containing information about the script. - - If the text is not a valid Python script (for example if brackets are left - open), parsing may fail to complete. However, if this occurs, no exception - is thrown. Instead the returned ScriptDesc instance will have its incomplete - flag set and information processed up to this point will still be accessible. - """ - - start_time = time() - txt.reset() - tokens = generate_tokens(txt.readline) # Throws TokenError - - curl, cursor = txt.getCursorPos() - linen = curl + 1 # Token line numbers are one-based - - imports = dict() - imp_step = 0 - - classes = dict() - cls_step = 0 - - defs = dict() - def_step = 0 - - vars = dict() - var1_step = 0 - var2_step = 0 - var3_step = 0 - var_accum = dict() - var_forflag = False - - indent = 0 - prev_type = -1 - prev_text = '' - incomplete = False - - while True: - try: - type, text, start, end, line = tokens.next() - except StopIteration: - break - except (TokenError, IndentationError): - incomplete = True - break - - # Skip all comments and line joining characters - if type == COMMENT or type == NL: - continue - - ################# - ## Indentation ## - ################# - - if type == INDENT: - indent += 1 - elif type == DEDENT: - indent -= 1 - - ######################### - ## Module importing... ## - ######################### - - imp_store = False - - # Default, look for 'from' or 'import' to start - if imp_step == 0: - if text == 'from': - imp_tmp = [] - imp_step = 1 - elif text == 'import': - imp_from = None - imp_tmp = [] - imp_step = 2 - - # Found a 'from', create imp_from in form '???.???...' - elif imp_step == 1: - if text == 'import': - imp_from = '.'.join(imp_tmp) - imp_tmp = [] - imp_step = 2 - elif type == NAME: - imp_tmp.append(text) - elif text != '.': - imp_step = 0 # Invalid syntax - - # Found 'import', imp_from is populated or None, create imp_name - elif imp_step == 2: - if text == 'as': - imp_name = '.'.join(imp_tmp) - imp_step = 3 - elif type == NAME or text == '*': - imp_tmp.append(text) - elif text != '.': - imp_name = '.'.join(imp_tmp) - imp_symb = imp_name - imp_store = True - - # Found 'as', change imp_symb to this value and go back to step 2 - elif imp_step == 3: - if type == NAME: - imp_symb = text - else: - imp_store = True - - # Both imp_name and imp_symb have now been populated so we can import - if imp_store: - - # Handle special case of 'import *' - if imp_name == '*': - parent = get_module(imp_from) - imports.update(parent.__dict__) - - else: - # Try importing the name as a module - try: - if imp_from: - module = get_module(imp_from +'.'+ imp_name) - else: - module = get_module(imp_name) - except (ImportError, ValueError, AttributeError, TypeError): - # Try importing name as an attribute of the parent - try: - module = __import__(imp_from, globals(), locals(), [imp_name]) - imports[imp_symb] = getattr(module, imp_name) - except (ImportError, ValueError, AttributeError, TypeError): - pass - else: - imports[imp_symb] = module - - # More to import from the same module? - if text == ',': - imp_tmp = [] - imp_step = 2 - else: - imp_step = 0 - - ################### - ## Class parsing ## - ################### - - # If we are inside a class then def and variable parsing should be done - # for the class. Otherwise the definitions are considered global - - # Look for 'class' - if cls_step == 0: - if text == 'class': - cls_name = None - cls_lineno = start[0] - cls_indent = indent - cls_step = 1 - - # Found 'class', look for cls_name followed by '(' parents ')' - elif cls_step == 1: - if not cls_name: - if type == NAME: - cls_name = text - cls_sline = False - cls_parents = dict() - cls_defs = dict() - cls_vars = dict() - elif type == NAME: - if classes.has_key(text): - parent = classes[text] - cls_parents[text] = parent - cls_defs.update(parent.defs) - cls_vars.update(parent.vars) - elif text == ':': - cls_step = 2 - - # Found 'class' name ... ':', now check if it's a single line statement - elif cls_step == 2: - if type == NEWLINE: - cls_sline = False - else: - cls_sline = True - cls_doc = '' - cls_step = 3 - - elif cls_step == 3: - if not cls_doc and type == STRING: - cls_doc = _trim_doc(text) - if cls_sline: - if type == NEWLINE: - classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc) - cls_step = 0 - else: - if type == DEDENT and indent <= cls_indent: - classes[cls_name] = ClassDesc(cls_name, cls_parents, cls_defs, cls_vars, cls_lineno, cls_doc) - cls_step = 0 - - ################# - ## Def parsing ## - ################# - - # Look for 'def' - if def_step == 0: - if text == 'def': - def_name = None - def_lineno = start[0] - def_step = 1 - - # Found 'def', look for def_name followed by '(' - elif def_step == 1: - if type == NAME: - def_name = text - def_params = [] - elif def_name and text == '(': - def_step = 2 - - # Found 'def' name '(', now identify the parameters upto ')' - # TODO: Handle ellipsis '...' - elif def_step == 2: - if type == NAME: - def_params.append(text) - elif text == ':': - def_step = 3 - - # Found 'def' ... ':', now check if it's a single line statement - elif def_step == 3: - if type == NEWLINE: - def_sline = False - else: - def_sline = True - def_doc = '' - def_step = 4 - - elif def_step == 4: - if type == STRING: - def_doc = _trim_doc(text) - newdef = None - if def_sline: - if type == NEWLINE: - newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc) - else: - if type == NAME: - newdef = FunctionDesc(def_name, def_params, def_lineno, def_doc) - if newdef: - if cls_step > 0: # Parsing a class - cls_defs[def_name] = newdef - else: - defs[def_name] = newdef - def_step = 0 - - ########################## - ## Variable assignation ## - ########################## - - if cls_step > 0: # Parsing a class - # Look for 'self.???' - if var1_step == 0: - if text == 'self': - var1_step = 1 - elif var1_step == 1: - if text == '.': - var_name = None - var1_step = 2 - else: - var1_step = 0 - elif var1_step == 2: - if type == NAME: - var_name = text - if cls_vars.has_key(var_name): - var_step = 0 - else: - var1_step = 3 - elif var1_step == 3: - if text == '=': - var1_step = 4 - elif text != ',': - var1_step = 0 - elif var1_step == 4: - var_type = None - if type == NUMBER: - close = end[1] - if text.find('.') != -1: var_type = float - else: var_type = int - elif type == STRING: - close = end[1] - var_type = str - elif text == '[': - close = line.find(']', end[1]) - var_type = list - elif text == '(': - close = line.find(')', end[1]) - var_type = tuple - elif text == '{': - close = line.find('}', end[1]) - var_type = dict - elif text == 'dict': - close = line.find(')', end[1]) - var_type = dict - if var_type and close+1 < len(line): - if line[close+1] != ' ' and line[close+1] != '\t': - var_type = None - cls_vars[var_name] = VarDesc(var_name, var_type, start[0]) - var1_step = 0 - - elif def_step > 0: # Parsing a def - # Look for 'global ???[,???]' - if var2_step == 0: - if text == 'global': - var2_step = 1 - elif var2_step == 1: - if type == NAME: - if not vars.has_key(text): - vars[text] = VarDesc(text, None, start[0]) - elif text != ',' and type != NL: - var2_step == 0 - - else: # In global scope - if var3_step == 0: - # Look for names - if text == 'for': - var_accum = dict() - var_forflag = True - elif text == '=' or (var_forflag and text == 'in'): - var_forflag = False - var3_step = 1 - elif type == NAME: - if prev_text != '.' and not vars.has_key(text): - var_accum[text] = VarDesc(text, None, start[0]) - elif not text in [',', '(', ')', '[', ']']: - var_accum = dict() - var_forflag = False - elif var3_step == 1: - if len(var_accum) != 1: - var_type = None - vars.update(var_accum) - else: - var_name = var_accum.keys()[0] - var_type = None - if type == NUMBER: - if text.find('.') != -1: var_type = float - else: var_type = int - elif type == STRING: var_type = str - elif text == '[': var_type = list - elif text == '(': var_type = tuple - elif text == '{': var_type = dict - vars[var_name] = VarDesc(var_name, var_type, start[0]) - var3_step = 0 - - ####################### - ## General utilities ## - ####################### - - prev_type = type - prev_text = text - - desc = ScriptDesc(txt.name, imports, classes, defs, vars, incomplete) - desc.set_delay(10 * (time()-start_time) + 0.05) - - global _parse_cache - _parse_cache[hash(txt)] = desc - return desc - -def get_modules(since=1): - """Returns the set of built-in modules and any modules that have been - imported into the system upto 'since' seconds ago. - """ - - global _modules, _modules_updated - - t = time() - if _modules_updated < t - since: - _modules.update(sys.modules) - _modules_updated = t - return _modules.keys() - -def suggest_cmp(x, y): - """Use this method when sorting a list of suggestions. - """ - - return cmp(x[0].upper(), y[0].upper()) - -def get_module(name): - """Returns the module specified by its name. The module itself is imported - by this method and, as such, any initialization code will be executed. - """ - - mod = __import__(name) - components = name.split('.') - for comp in components[1:]: - mod = getattr(mod, comp) - return mod - -def type_char(v): - """Returns the character used to signify the type of a variable. Use this - method to identify the type character for an item in a suggestion list. - - The following values are returned: - 'm' if the parameter is a module - 'f' if the parameter is callable - 'v' if the parameter is variable or otherwise indeterminable - - """ - - if isinstance(v, ModuleType): - return 'm' - elif callable(v): - return 'f' - else: - return 'v' - -def get_context(txt): - """Establishes the context of the cursor in the given Blender Text object - - Returns one of: - CTX_NORMAL - Cursor is in a normal context - CTX_SINGLE_QUOTE - Cursor is inside a single quoted string - CTX_DOUBLE_QUOTE - Cursor is inside a double quoted string - CTX_COMMENT - Cursor is inside a comment - - """ - - l, cursor = txt.getCursorPos() - lines = txt.asLines(0, l+1) - - # FIXME: This method is too slow in large files for it to be called as often - # as it is. So for lines below the 1000th line we do this... (quorn) - if l > 1000: return CTX_NORMAL - - # Detect context (in string or comment) - in_str = CTX_NORMAL - for line in lines: - if l == 0: - end = cursor - else: - end = len(line) - l -= 1 - - # Comments end at new lines - if in_str == CTX_COMMENT: - in_str = CTX_NORMAL - - for i in range(end): - if in_str == 0: - if line[i] == "'": in_str = CTX_SINGLE_QUOTE - elif line[i] == '"': in_str = CTX_DOUBLE_QUOTE - elif line[i] == '#': in_str = CTX_COMMENT - else: - if in_str == CTX_SINGLE_QUOTE: - if line[i] == "'": - in_str = CTX_NORMAL - # In again if ' escaped, out again if \ escaped, and so on - for a in range(i-1, -1, -1): - if line[a] == '\\': in_str = 1-in_str - else: break - elif in_str == CTX_DOUBLE_QUOTE: - if line[i] == '"': - in_str = CTX_NORMAL - # In again if " escaped, out again if \ escaped, and so on - for a in range(i-1, -1, -1): - if line[i-a] == '\\': in_str = 2-in_str - else: break - - return in_str - -def current_line(txt): - """Extracts the Python script line at the cursor in the Blender Text object - provided and cursor position within this line as the tuple pair (line, - cursor). - """ - - lineindex, cursor = txt.getCursorPos() - lines = txt.asLines() - line = lines[lineindex] - - # Join previous lines to this line if spanning - i = lineindex - 1 - while i > 0: - earlier = lines[i].rstrip() - if earlier.endswith('\\'): - line = earlier[:-1] + ' ' + line - cursor += len(earlier) - i -= 1 - - # Join later lines while there is an explicit joining character - i = lineindex - while i < len(lines)-1 and lines[i].rstrip().endswith('\\'): - later = lines[i+1].strip() - line = line + ' ' + later[:-1] - i += 1 - - return line, cursor - -def get_targets(line, cursor): - """Parses a period separated string of valid names preceding the cursor and - returns them as a list in the same order. - """ - - brk = 0 - targets = [] - j = cursor - i = j-1 - while i >= 0: - if line[i] == ')': brk += 1 - elif brk: - if line[i] == '(': brk -= 1 - else: - if line[i] == '.': - targets.insert(0, line[i+1:j]); j=i - elif not (line[i].isalnum() or line[i] == '_' or line[i] == '.'): - break - i -= 1 - targets.insert(0, line[i+1:j]) - return targets - -def get_defs(txt): - """Returns a dictionary which maps definition names in the source code to - a list of their parameter names. - - The line 'def doit(one, two, three): print one' for example, results in the - mapping 'doit' : [ 'one', 'two', 'three' ] - """ - - return get_cached_descriptor(txt).defs - -def get_vars(txt): - """Returns a dictionary of variable names found in the specified Text - object. This method locates all names followed directly by an equal sign: - 'a = ???' or indirectly as part of a tuple/list assignment or inside a - 'for ??? in ???:' block. - """ - - return get_cached_descriptor(txt).vars - -def get_imports(txt): - """Returns a dictionary which maps symbol names in the source code to their - respective modules. - - The line 'from Blender import Text as BText' for example, results in the - mapping 'BText' : - - Note that this method imports the modules to provide this mapping as as such - will execute any initilization code found within. - """ - - return get_cached_descriptor(txt).imports - -def get_builtins(): - """Returns a dictionary of built-in modules, functions and variables.""" - - return __builtin__.__dict__ - - -################################# -## Debugging utility functions ## -################################# - -def print_cache_for(txt, period=sys.maxint): - """Prints out the data cached for a given Text object. If no period is - given the text will not be reparsed and the cached version will be returned. - Otherwise if the period has expired the text will be reparsed. - """ - - desc = get_cached_descriptor(txt, period) - print '================================================' - print 'Name:', desc.name, '('+str(hash(txt))+')' - print '------------------------------------------------' - print 'Defs:' - for name, ddesc in desc.defs.items(): - print ' ', name, ddesc.params, ddesc.lineno - print ' ', ddesc.doc - print '------------------------------------------------' - print 'Vars:' - for name, vdesc in desc.vars.items(): - print ' ', name, vdesc.type, vdesc.lineno - print '------------------------------------------------' - print 'Imports:' - for name, item in desc.imports.items(): - print ' ', name.ljust(15), item - print '------------------------------------------------' - print 'Classes:' - for clsnme, clsdsc in desc.classes.items(): - print ' *********************************' - print ' Name:', clsnme - print ' ', clsdsc.doc - print ' ---------------------------------' - print ' Defs:' - for name, ddesc in clsdsc.defs.items(): - print ' ', name, ddesc.params, ddesc.lineno - print ' ', ddesc.doc - print ' ---------------------------------' - print ' Vars:' - for name, vdesc in clsdsc.vars.items(): - print ' ', name, vdesc.type, vdesc.lineno - print ' *********************************' - print '================================================' diff --git a/release/scripts/bpymodules/BPyWindow.py b/release/scripts/bpymodules/BPyWindow.py deleted file mode 100644 index d3fd4fa88b5..00000000000 --- a/release/scripts/bpymodules/BPyWindow.py +++ /dev/null @@ -1,206 +0,0 @@ -import Blender -from Blender import Mathutils, Window, Scene, Draw, Mesh -from Blender.Mathutils import Matrix, Vector, Intersect - -# DESCRIPTION: -# screen_x, screen_y the origin point of the pick ray -# it is either the mouse location -# localMatrix is used if you want to have the returned values in an objects localspace. -# this is usefull when dealing with an objects data such as verts. -# or if useMid is true, the midpoint of the current 3dview -# returns -# Origin - the origin point of the pick ray -# Direction - the direction vector of the pick ray -# in global coordinates -epsilon = 1e-3 # just a small value to account for floating point errors - -def mouseViewRay(screen_x, screen_y, localMatrix=None, useMid = False): - - # Constant function variables - p = mouseViewRay.p - d = mouseViewRay.d - - for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example) - win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices'] - # calculate a few geometric extents for this window - - win_mid_x = (win_max_x + win_min_x + 1.0) * 0.5 - win_mid_y = (win_max_y + win_min_y + 1.0) * 0.5 - win_size_x = (win_max_x - win_min_x + 1.0) * 0.5 - win_size_y = (win_max_y - win_min_y + 1.0) * 0.5 - - #useMid is for projecting the coordinates when we subdivide the screen into bins - if useMid: # == True - screen_x = win_mid_x - screen_y = win_mid_y - - # if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one... - if (win_max_x > screen_x > win_min_x) and ( win_max_y > screen_y > win_min_y): - # first we handle all pending events for this window (otherwise the matrices might come out wrong) - Window.QHandle(win3d['id']) - - # now we get a few matrices for our window... - # sorry - i cannot explain here what they all do - # - if you're not familiar with all those matrices take a look at an introduction to OpenGL... - pm = Window.GetPerspMatrix() # the prespective matrix - pmi = Matrix(pm); pmi.invert() # the inverted perspective matrix - - if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon): - # pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5) - hms = mouseViewRay.hms - ortho_d = mouseViewRay.ortho_d - - # ortho mode: is a bit strange - actually there's no definite location of the camera ... - # but the camera could be displaced anywhere along the viewing direction. - - ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector() - ortho_d.w = 0 - - # all rays are parallel in ortho mode - so the direction vector is simply the viewing direction - #hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0 - hms[:] = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0 - - # these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1 - p=(hms*pmi) + (1000*ortho_d) - p.resize3D() - d[:] = ortho_d[:3] - - - # Finally we shift the position infinitely far away in - # the viewing direction to make sure the camera if outside the scene - # (this is actually a hack because this function - # is used in sculpt_mesh to initialize backface culling...) - else: - # PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location - vmi = Matrix(Window.GetViewMatrix()); vmi.invert() # the inverse viewing matrix - fp = mouseViewRay.fp - - dx = pm[3][3] * (((screen_x-win_min_x)/win_size_x)-1.0) - pm[3][0] - dy = pm[3][3] * (((screen_y-win_min_y)/win_size_y)-1.0) - pm[3][1] - - fp[:] = \ - pmi[0][0]*dx+pmi[1][0]*dy,\ - pmi[0][1]*dx+pmi[1][1]*dy,\ - pmi[0][2]*dx+pmi[1][2]*dy - - # fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y) - #- figuring out how to calculate this took me quite some time. - # The calculation of dxy and fp are simplified versions of my original code - #- so it's almost impossible to explain what's going on geometrically... sorry - - p[:] = vmi[3][:3] - - # the camera's location in global 3dcoords can be read directly from the inverted viewmatrix - #d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp)) - d[:] = p.x-fp.x, p.y-fp.y, p.z-fp.z - - #print 'd', d, 'p', p, 'fp', fp - - - # the direction vector is simply the difference vector from the virtual camera's position - #to the unprojected (screenspace) point fp - - # Do we want to return a direction in object's localspace? - - if localMatrix: - localInvMatrix = Matrix(localMatrix) - localInvMatrix.invert() - localInvMatrix_notrans = localInvMatrix.rotationPart() - p = p * localInvMatrix - d = d * localInvMatrix # normalize_v3 - - # remove the translation from d - d.x -= localInvMatrix[3][0] - d.y -= localInvMatrix[3][1] - d.z -= localInvMatrix[3][2] - - - d.normalize() - ''' - # Debugging - me = Blender.Mesh.New() - me.verts.extend([p[0:3]]) - me.verts.extend([(p-d)[0:3]]) - me.edges.extend([0,1]) - ob = Blender.Scene.GetCurrent().objects.new(me) - ''' - return True, p, d # Origin, Direction - - # Mouse is not in any view, return None. - return False, None, None - -# Constant function variables -mouseViewRay.d = Vector(0,0,0) # Perspective, 3d -mouseViewRay.p = Vector(0,0,0) -mouseViewRay.fp = Vector(0,0,0) - -mouseViewRay.hms = Vector(0,0,0,0) # ortho only 4d -mouseViewRay.ortho_d = Vector(0,0,0,0) # ortho only 4d - - -LMB= Window.MButs['L'] -def mouseup(): - # Loop until click - mouse_buttons = Window.GetMouseButtons() - while not mouse_buttons & LMB: - Blender.sys.sleep(10) - mouse_buttons = Window.GetMouseButtons() - while mouse_buttons & LMB: - Blender.sys.sleep(10) - mouse_buttons = Window.GetMouseButtons() - - -if __name__=='__main__': - mouseup() - x,y= Window.GetMouseCoords() - isect, point, dir= mouseViewRay(x,y) - if isect: - scn= Blender.Scene.GetCurrent() - me = Blender.Mesh.New() - ob= Blender.Object.New('Mesh') - ob.link(me) - scn.link(ob) - ob.sel= 1 - me.verts.extend([point, dir]) - me.verts[0].sel= 1 - - print isect, point, dir - - - -def spaceRect(): - ''' - Returns the space rect - xmin,ymin,width,height - ''' - - __UI_RECT__ = Blender.BGL.Buffer(Blender.BGL.GL_FLOAT, 4) - Blender.BGL.glGetFloatv(Blender.BGL.GL_SCISSOR_BOX, __UI_RECT__) - __UI_RECT__ = __UI_RECT__.list - __UI_RECT__ = int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2])-1, int(__UI_RECT__[3]) - - return __UI_RECT__ - -def mouseRelativeLoc2d(__UI_RECT__= None): - if not __UI_RECT__: - __UI_RECT__ = spaceRect() - - mco = Window.GetMouseCoords() - if mco[0] > __UI_RECT__[0] and\ - mco[1] > __UI_RECT__[1] and\ - mco[0] < __UI_RECT__[0] + __UI_RECT__[2] and\ - mco[1] < __UI_RECT__[1] + __UI_RECT__[3]: - - return (mco[0] - __UI_RECT__[0], mco[1] - __UI_RECT__[1]) - - else: - return None - - - - - - - - - \ No newline at end of file diff --git a/release/scripts/bpymodules/blend2renderinfo.py b/release/scripts/bpymodules/blend2renderinfo.py deleted file mode 100644 index 1b9dec58d55..00000000000 --- a/release/scripts/bpymodules/blend2renderinfo.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/python - -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import struct - -# In Blender, selecting scenes in the databrowser (shift+f4) will tag for rendering. - -# This struct wont change according to ton. -# Note that the size differs on 32/64bit -''' -typedef struct BHead { - int code, len; - void *old; - int SDNAnr, nr; -} BHead; -''' - - -def read_blend_rend_chunk(path): - file = open(path, 'rb') - - if file.read(len('BLENDER')) != 'BLENDER': - return [] - - # - if file.read(1) == '-': - is64bit = True - else: # '_' - is64bit = False - - if file.read(1) == 'V': - isBigEndian = True # ppc - else: # 'V' - isBigEndian = False # x86 - - - # Now read the bhead chunk!!! - file.read(3) # skip the version - - scenes = [] - - while file.read(4) == 'REND': - - if is64bit: sizeof_bhead = sizeof_bhead_left = 24 # 64bit - else: sizeof_bhead = sizeof_bhead_left = 20 # 32bit - - sizeof_bhead_left -= 4 - - if isBigEndian: rend_length = struct.unpack('>i', file.read(4))[0] - else: rend_length = struct.unpack('2i', file.read(8)) - else: start_frame, end_frame = struct.unpack('<2i', file.read(8)) - - scene_name = file.read(24) - scene_name = scene_name[ : scene_name.index('\0') ] - - scenes.append( (start_frame, end_frame, scene_name) ) - return scenes - -def main(): - import sys - for arg in sys.argv[1:]: - if arg.lower().endswith('.blend'): - print read_blend_rend_chunk(arg) - -if __name__ == '__main__': - main() - diff --git a/release/scripts/bpymodules/defaultdoodads.py b/release/scripts/bpymodules/defaultdoodads.py deleted file mode 100644 index 987b8b8ae71..00000000000 --- a/release/scripts/bpymodules/defaultdoodads.py +++ /dev/null @@ -1,941 +0,0 @@ -# Default Doodad Set for Discombobulator -# by Evan J. Rosky, 2005 -# GPL- http://www.gnu.org/copyleft/gpl.html -# -# $Id$ -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2005: Evan J. Rosky -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -#Run discombobulator.py, not this. - -import Blender -from Blender import NMesh,Object,Material -from Blender.NMesh import Vert,Face -from Blender.Mathutils import * - -import BPyMathutils -from BPyMathutils import genrand -a = BPyMathutils.sgenrand(4859) - -#Create random numbers -def randnum(low,high): - num = genrand() - num = num*(high-low) - num = num+low - return num - -face = Face() -xmin = Vector([0,0,0]) -xmax = Vector([0,0,0]) -ymin = Vector([0,0,0]) -ymax = Vector([0,0,0]) -mxmin = Vector([0,0,0]) -mxmax = Vector([0,0,0]) -mymin = Vector([0,0,0]) -mymax = Vector([0,0,0]) -doodadCenter = Vector([0,0,0]) -orientation = 0 -center = Vector([0,0,0]) -tosel = 0 -seltopsonly = 0 -tempx = [] -doodadMesh = NMesh.GetRaw() - -global materialArray -global reassignMats -global thereAreMats -global currmat -global doodSideMat -global doodTopMat - -#face is the face to add the doodad to. -#sizeX and sizeY are values from 0.0 to 1.0 that represents a percentage the face that is covered by the doodad. -#height is how tall the doodad is. - -def settings(seltops,matArr,reasMats,therMats,sidemat,topmat): - global seltopsonly - global materialArray - global reassignMats - global thereAreMats - global currmat - global doodSideMat - global doodTopMat - materialArray = matArr - reassignMats = reasMats - thereAreMats = therMats - seltopsonly = seltops - doodSideMat = sidemat - doodTopMat = topmat - -def setCurrMat(curma): - global currmat - currmat = curma - -#Find center and orientation of doodad -def findDoodadCenter(sizeX, sizeY): - #globalizing junk - global face - global xmin - global xmax - global ymin - global ymax - global orientation - global doodadCenter - global center - global tosel - global mxmin - global mxmax - global mymin - global mymax - global tempx - global seltopsonly - - #Find the center of the face - center = Vector([0,0,0]) - for pt in face.v: - center = center + pt.co - center = divideVectorByInt(center,len(face.v)) - - #Find Temp Location Range by looking at the sizes - txmin = ((divideVectorByInt((face.v[0].co + face.v[3].co),2)) - center)*(1-sizeX) + center - txmax = ((divideVectorByInt((face.v[1].co + face.v[2].co),2)) - center)*(1-sizeX) + center - tymin = ((divideVectorByInt((face.v[0].co + face.v[1].co),2)) - center)*(1-sizeY) + center - tymax = ((divideVectorByInt((face.v[2].co + face.v[3].co),2)) - center)*(1-sizeY) + center - - #Find Center of doodad - amtx = randnum(0.0,1.0) - amty = randnum(0.0,1.0) - thepoint = (((((txmin - txmax)*amtx + txmax) - ((tymin - tymax)*amty + tymax))*.5 + ((tymin - tymax)*amty + tymax)) - center)*2 + center - doodadCenter = Vector([thepoint[0],thepoint[1],thepoint[2]]) - - #Find Main Range by looking at the sizes - mxmin = divideVectorByInt((face.v[0].co + face.v[3].co),2) - mxmax = divideVectorByInt((face.v[1].co + face.v[2].co),2) - mymin = divideVectorByInt((face.v[0].co + face.v[1].co),2) - mymax = divideVectorByInt((face.v[2].co + face.v[3].co),2) - - #Find x/y equivs for whole face - ve1 = (txmin - txmax)*amtx + txmax - ve1 = ve1 - mxmax - nax = ve1.length - ve1 = (mxmin - mxmax) - nax = nax/ve1.length - - ve1 = (tymin - tymax)*amty + tymax - ve1 = ve1 - mymax - nay = ve1.length - ve1 = (mymin - mymax) - nay = nay/ve1.length - - #Find new box thing - tempx = [] - amtx = nax-sizeX/2 - amty = nay-sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - amtx = nax-sizeX/2 - amty = nay+sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - amtx = nax+sizeX/2 - amty = nay+sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - amtx = nax+sizeX/2 - amty = nay-sizeY/2 - tempx.append((((((mxmin - mxmax)*amtx + mxmax) - ((mymin - mymax)*amty + mymax))*.5 + ((mymin - mymax)*amty + mymax)) - center)*2 + center) - - #Find New Location Range by looking at the sizes - xmin = divideVectorByInt((tempx[0] + tempx[3]),2) - xmax = divideVectorByInt((tempx[1] + tempx[2]),2) - ymin = divideVectorByInt((tempx[0] + tempx[1]),2) - ymax = divideVectorByInt((tempx[2] + tempx[3]),2) - -#Make a point -def makePoint(x,y,z=0): - global xmin - global xmax - global ymin - global ymax - global doodadCenter - global tosel - global seltopsonly - global face - - amtx = x - amty = y - thepoint = (((((xmin - xmax)*amtx + xmax) - ((ymin - ymax)*amty + ymax))*.5 + ((ymin - ymax)*amty + ymax)) - doodadCenter)*2 + doodadCenter - thepoint = thepoint + z*Vector(face.no) - tver = Vert(thepoint[0],thepoint[1],thepoint[2]) - if tosel == 1 and seltopsonly == 0 and z == 0: - tver.sel = 1 - return tver - -#extrude ground-plane(s) -def extrudedoodad(vArray,heig): - global face - global doodadMesh - global tosel - - topVArray = [] - - doodadMesh.verts.extend(vArray) - - #Create array for extruded verts - for ind in range(0,(len(vArray))): - point = vArray[ind].co + heig*Vector(face.no) - ver = Vert(point[0],point[1],point[2]) - if tosel == 1: - ver.sel = 1 - topVArray.append(ver) - doodadMesh.verts.append(topVArray[ind]) - - #make faces around sides - for ind in range(0,(len(vArray) - 1)): - face = Face() - face.v.extend([vArray[ind],vArray[ind+1],topVArray[ind+1],topVArray[ind]]) - if tosel == 1 and seltopsonly == 0: face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodSideMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vArray[len(vArray) - 1],vArray[0],topVArray[0],topVArray[len(topVArray) - 1]]) - if tosel == 1 and seltopsonly == 0: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodSideMat-1 - doodadMesh.faces.append(face) - - return topVArray - -#For switching face vertices -def fixvertindex(ind): - if ind > 3: - indx = ind - 4 - else: - indx = ind - return indx - -#runs doodads -def createDoodad(indexArray,facec,minsi,maxsi,minhei,maxhei,selec,amtmin,amtmax,facpercent): - global doodadMesh - global seltopsonly - global tosel - - doodadMesh = NMesh.GetRaw() - - theamt = round(randnum(amtmin,amtmax),0) - theamt = int(theamt) - tosel = selec - - for i in range(0,(theamt)): - if randnum(0,1) <= facpercent: - index = round(randnum(1,len(indexArray)),0) - index = indexArray[(int(index) - 1)] - - Xsi = randnum(minsi,maxsi) - Ysi = randnum(minsi,maxsi) - hei = randnum(minhei,maxhei) - - #Determine orientation - orient = int(round(randnum(0.0,3.0))) - - #face to use as range - facer = Face() - facer.v.extend([facec.v[orient],facec.v[fixvertindex(1+orient)],facec.v[fixvertindex(2+orient)],facec.v[fixvertindex(3+orient)]]) - - if index == 1: - singleBox(facer,Xsi,Ysi,hei) - if index == 2: - doubleBox(facer,Xsi,Ysi,hei) - if index == 3: - tripleBox(facer,Xsi,Ysi,hei) - if index == 4: - LShape(facer,Xsi,Ysi,hei) - if index == 5: - TShape(facer,Xsi,Ysi,hei) - if index == 6: - if randnum(0.0,1.0) > .5: - SShape(facer,Xsi,Ysi,hei) - else: - ZShape(facer,Xsi,Ysi,hei) - - return doodadMesh - -def divideVectorByInt(thevect,theint): - thevect.x = thevect.x/theint - thevect.y = thevect.y/theint - thevect.z = thevect.z/theint - return thevect - -#Single Box Doodad -def singleBox(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - vertArray = [] - - #place four points - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#Double Box Doodad -def doubleBox(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - vertArray = [] - - #place first box - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(0.45,1)) - vertArray.append(makePoint(0.45,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - vertArray = [] - - #place second box - vertArray.append(makePoint(0.55,0)) - vertArray.append(makePoint(0.55,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#Triple Box Doodad -def tripleBox(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - vertArray = [] - - #place first box - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(0.3,1)) - vertArray.append(makePoint(0.3,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - vertArray = [] - - #place second box - vertArray.append(makePoint(0.35,0)) - vertArray.append(makePoint(0.35,1)) - vertArray.append(makePoint(0.65,1)) - vertArray.append(makePoint(0.65,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - vertArray = [] - - #place third box - vertArray.append(makePoint(0.7,0)) - vertArray.append(makePoint(0.7,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,0)) - topVertArray = extrudedoodad(vertArray,height) - - face = Face() - face.v.extend(vertArray) - face.v.reverse() - doodadMesh.faces.append(face) - face = Face() - face.v.extend(topVertArray) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#The "L" Shape -def LShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcon1 = randnum(0.2,0.8) - rcon2 = randnum(0.2,0.8) - - vertArray = [] - - #place L shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcon1)) - vertArray.append(makePoint(0,1)) - vertArray.append(makePoint(rcon2,1)) - vertArray.append(makePoint(rcon2,rcon1)) - vertArray.append(makePoint(1,rcon1)) - vertArray.append(makePoint(1,0)) - vertArray.append(makePoint(rcon2,0)) - topVertArray = extrudedoodad(vertArray,height) - - #This fills in the bottom of doodad with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[4],vertArray[7]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[1],vertArray[2],vertArray[3],vertArray[4]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[4],vertArray[5],vertArray[6],vertArray[7]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #This fills in the top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[4],topVertArray[7]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[1],topVertArray[2],topVertArray[3],topVertArray[4]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[4],topVertArray[5],topVertArray[6],topVertArray[7]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#The "T" Shape -def TShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcony = randnum(0.25,0.75) - rconx1 = randnum(0.1,0.49) - rconx2 = randnum(0.51,0.9) - - vertArray = [] - - #place T shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcony)) - vertArray.append(makePoint(rconx1,rcony)) - vertArray.append(makePoint(rconx1,1)) - vertArray.append(makePoint(rconx2,1)) - vertArray.append(makePoint(rconx2,rcony)) - vertArray.append(makePoint(1,rcony)) - vertArray.append(makePoint(1,0)) - vertArray.append(makePoint(rconx2,0)) - vertArray.append(makePoint(rconx1,0)) - topVertArray = extrudedoodad(vertArray,height) - - #fills bottom with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[2],vertArray[9]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[2],vertArray[3],vertArray[4],vertArray[5]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[5],vertArray[6],vertArray[7],vertArray[8]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[8],vertArray[9],vertArray[2],vertArray[5]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #fills top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[2],topVertArray[9]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[2],topVertArray[3],topVertArray[4],topVertArray[5]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[5],topVertArray[6],topVertArray[7],topVertArray[8]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[8],topVertArray[9],topVertArray[2],topVertArray[5]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -#The "S" or "Z" Shapes -def SShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcony1 = randnum(0.1,0.49) - rcony2 = randnum(0.51,0.9) - rconx1 = randnum(0.1,0.49) - rconx2 = randnum(0.51,0.9) - - vertArray = [] - - #place S shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcony1)) - vertArray.append(makePoint(rconx1,rcony1)) - vertArray.append(makePoint(rconx1,rcony2)) - vertArray.append(makePoint(rconx1,1)) - vertArray.append(makePoint(rconx2,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,rcony2)) - vertArray.append(makePoint(rconx2,rcony2)) - vertArray.append(makePoint(rconx2,rcony1)) - vertArray.append(makePoint(rconx2,0)) - vertArray.append(makePoint(rconx1,0)) - topVertArray = extrudedoodad(vertArray,height) - - #fills bottom with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[2],vertArray[11]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[2],vertArray[9],vertArray[10],vertArray[11]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[2],vertArray[3],vertArray[8],vertArray[9]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[3],vertArray[4],vertArray[5],vertArray[8]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[5],vertArray[6],vertArray[7],vertArray[8]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #fills top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[2],topVertArray[11]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[2],topVertArray[9],topVertArray[10],topVertArray[11]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[2],topVertArray[3],topVertArray[8],topVertArray[9]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[3],topVertArray[4],topVertArray[5],topVertArray[8]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[5],topVertArray[6],topVertArray[7],topVertArray[8]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - -def ZShape(facel, Xsize, Ysize, height): - #globaling junk - global face - global tosel - global doodadMesh - - face = Face() - face = facel - - findDoodadCenter(Xsize, Ysize) - - rcony1 = randnum(0.1,0.49) - rcony2 = randnum(0.51,0.9) - rconx1 = randnum(0.1,0.49) - rconx2 = randnum(0.51,0.9) - - vertArray = [] - - #place Z shape - vertArray.append(makePoint(0,0)) - vertArray.append(makePoint(0,rcony1)) - vertArray.append(makePoint(0,rcony2)) - vertArray.append(makePoint(rconx1,rcony2)) - vertArray.append(makePoint(rconx2,rcony2)) - vertArray.append(makePoint(rconx2,1)) - vertArray.append(makePoint(1,1)) - vertArray.append(makePoint(1,rcony2)) - vertArray.append(makePoint(1,rcony1)) - vertArray.append(makePoint(rconx2,rcony1)) - vertArray.append(makePoint(rconx1,rcony1)) - vertArray.append(makePoint(rconx1,0)) - topVertArray = extrudedoodad(vertArray,height) - - #fills bottom with faceness - face = Face() - face.v.extend([vertArray[0],vertArray[1],vertArray[10],vertArray[11]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[1],vertArray[2],vertArray[3],vertArray[10]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[3],vertArray[4],vertArray[9],vertArray[10]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[4],vertArray[7],vertArray[8],vertArray[9]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([vertArray[4],vertArray[5],vertArray[6],vertArray[7]]) - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - - #fills top with faceness - face = Face() - face.v.extend([topVertArray[0],topVertArray[1],topVertArray[10],topVertArray[11]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[1],topVertArray[2],topVertArray[3],topVertArray[10]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[3],topVertArray[4],topVertArray[9],topVertArray[10]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[4],topVertArray[7],topVertArray[8],topVertArray[9]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - face = Face() - face.v.extend([topVertArray[4],topVertArray[5],topVertArray[6],topVertArray[7]]) - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or doodTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = doodTopMat-1 - doodadMesh.faces.append(face) - diff --git a/release/scripts/bpymodules/dxfColorMap.py b/release/scripts/bpymodules/dxfColorMap.py deleted file mode 100644 index 66c0bd4e9a2..00000000000 --- a/release/scripts/bpymodules/dxfColorMap.py +++ /dev/null @@ -1,282 +0,0 @@ -# dictionary mapping AutoCAD color indexes with Blender colors - -# -------------------------------------------------------------------------- -# color_map.py Final by Ed Blake (AKA Kitsu) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -color_map = { - 0:[0.0, 0.0, 0.0], - 1:[0.99609375, 0.0, 0.0], - 2:[0.99609375, 0.99609375, 0.0], - 3:[0.0, 0.99609375, 0.0], - 4:[0.0, 0.99609375, 0.99609375], - 5:[0.0, 0.0, 0.99609375], - 6:[0.99609375, 0.0, 0.99609375], - 7:[0.99609375, 0.99609375, 0.99609375], - 8:[0.25390625, 0.25390625, 0.25390625], - 9:[0.5, 0.5, 0.5], - 10:[0.99609375, 0.0, 0.0], - 11:[0.99609375, 0.6640625, 0.6640625], - 12:[0.73828125, 0.0, 0.0], - 13:[0.73828125, 0.4921875, 0.4921875], - 14:[0.50390625, 0.0, 0.0], - 15:[0.50390625, 0.3359375, 0.3359375], - 16:[0.40625, 0.0, 0.0], - 17:[0.40625, 0.26953125, 0.26953125], - 18:[0.30859375, 0.0, 0.0], - 19:[0.30859375, 0.20703125, 0.20703125], - 20:[0.99609375, 0.24609375, 0.0], - 21:[0.99609375, 0.74609375, 0.6640625], - 22:[0.73828125, 0.1796875, 0.0], - 23:[0.73828125, 0.55078125, 0.4921875], - 24:[0.50390625, 0.12109375, 0.0], - 25:[0.50390625, 0.375, 0.3359375], - 26:[0.40625, 0.09765625, 0.0], - 27:[0.40625, 0.3046875, 0.26953125], - 28:[0.30859375, 0.07421875, 0.0], - 29:[0.30859375, 0.23046875, 0.20703125], - 30:[0.99609375, 0.49609375, 0.0], - 31:[0.99609375, 0.828125, 0.6640625], - 32:[0.73828125, 0.3671875, 0.0], - 33:[0.73828125, 0.61328125, 0.4921875], - 34:[0.50390625, 0.25, 0.0], - 35:[0.50390625, 0.41796875, 0.3359375], - 36:[0.40625, 0.203125, 0.0], - 37:[0.40625, 0.3359375, 0.26953125], - 38:[0.30859375, 0.15234375, 0.0], - 39:[0.30859375, 0.2578125, 0.20703125], - 40:[0.99609375, 0.74609375, 0.0], - 41:[0.99609375, 0.9140625, 0.6640625], - 42:[0.73828125, 0.55078125, 0.0], - 43:[0.73828125, 0.67578125, 0.4921875], - 44:[0.50390625, 0.375, 0.0], - 45:[0.50390625, 0.4609375, 0.3359375], - 46:[0.40625, 0.3046875, 0.0], - 47:[0.40625, 0.37109375, 0.26953125], - 48:[0.30859375, 0.23046875, 0.0], - 49:[0.30859375, 0.28515625, 0.20703125], - 50:[0.99609375, 0.99609375, 0.0], - 51:[0.99609375, 0.99609375, 0.6640625], - 52:[0.73828125, 0.73828125, 0.0], - 53:[0.73828125, 0.73828125, 0.4921875], - 54:[0.50390625, 0.50390625, 0.0], - 55:[0.50390625, 0.50390625, 0.3359375], - 56:[0.40625, 0.40625, 0.0], - 57:[0.40625, 0.40625, 0.26953125], - 58:[0.30859375, 0.30859375, 0.0], - 59:[0.30859375, 0.30859375, 0.20703125], - 60:[0.74609375, 0.99609375, 0.0], - 61:[0.9140625, 0.99609375, 0.6640625], - 62:[0.55078125, 0.73828125, 0.0], - 63:[0.67578125, 0.73828125, 0.4921875], - 64:[0.375, 0.50390625, 0.0], - 65:[0.4609375, 0.50390625, 0.3359375], - 66:[0.3046875, 0.40625, 0.0], - 67:[0.37109375, 0.40625, 0.26953125], - 68:[0.23046875, 0.30859375, 0.0], - 69:[0.28515625, 0.30859375, 0.20703125], - 70:[0.49609375, 0.99609375, 0.0], - 71:[0.828125, 0.99609375, 0.6640625], - 72:[0.3671875, 0.73828125, 0.0], - 73:[0.61328125, 0.73828125, 0.4921875], - 74:[0.25, 0.50390625, 0.0], - 75:[0.41796875, 0.50390625, 0.3359375], - 76:[0.203125, 0.40625, 0.0], - 77:[0.3359375, 0.40625, 0.26953125], - 78:[0.15234375, 0.30859375, 0.0], - 79:[0.2578125, 0.30859375, 0.20703125], - 80:[0.24609375, 0.99609375, 0.0], - 81:[0.74609375, 0.99609375, 0.6640625], - 82:[0.1796875, 0.73828125, 0.0], - 83:[0.55078125, 0.73828125, 0.4921875], - 84:[0.12109375, 0.50390625, 0.0], - 85:[0.375, 0.50390625, 0.3359375], - 86:[0.09765625, 0.40625, 0.0], - 87:[0.3046875, 0.40625, 0.26953125], - 88:[0.07421875, 0.30859375, 0.0], - 89:[0.23046875, 0.30859375, 0.20703125], - 90:[0.0, 0.99609375, 0.0], - 91:[0.6640625, 0.99609375, 0.6640625], - 92:[0.0, 0.73828125, 0.0], - 93:[0.4921875, 0.73828125, 0.4921875], - 94:[0.0, 0.50390625, 0.0], - 95:[0.3359375, 0.50390625, 0.3359375], - 96:[0.0, 0.40625, 0.0], - 97:[0.26953125, 0.40625, 0.26953125], - 98:[0.0, 0.30859375, 0.0], - 99:[0.20703125, 0.30859375, 0.20703125], - 100:[0.0, 0.99609375, 0.24609375], - 101:[0.6640625, 0.99609375, 0.74609375], - 102:[0.0, 0.73828125, 0.1796875], - 103:[0.4921875, 0.73828125, 0.55078125], - 104:[0.0, 0.50390625, 0.12109375], - 105:[0.3359375, 0.50390625, 0.375], - 106:[0.0, 0.40625, 0.09765625], - 107:[0.26953125, 0.40625, 0.3046875], - 108:[0.0, 0.30859375, 0.07421875], - 109:[0.20703125, 0.30859375, 0.23046875], - 110:[0.0, 0.99609375, 0.49609375], - 111:[0.6640625, 0.99609375, 0.828125], - 112:[0.0, 0.73828125, 0.3671875], - 113:[0.4921875, 0.73828125, 0.61328125], - 114:[0.0, 0.50390625, 0.25], - 115:[0.3359375, 0.50390625, 0.41796875], - 116:[0.0, 0.40625, 0.203125], - 117:[0.26953125, 0.40625, 0.3359375], - 118:[0.0, 0.30859375, 0.15234375], - 119:[0.20703125, 0.30859375, 0.2578125], - 120:[0.0, 0.99609375, 0.74609375], - 121:[0.6640625, 0.99609375, 0.9140625], - 122:[0.0, 0.73828125, 0.55078125], - 123:[0.4921875, 0.73828125, 0.67578125], - 124:[0.0, 0.50390625, 0.375], - 125:[0.3359375, 0.50390625, 0.4609375], - 126:[0.0, 0.40625, 0.3046875], - 127:[0.26953125, 0.40625, 0.37109375], - 128:[0.0, 0.30859375, 0.23046875], - 129:[0.20703125, 0.30859375, 0.28515625], - 130:[0.0, 0.99609375, 0.99609375], - 131:[0.6640625, 0.99609375, 0.99609375], - 132:[0.0, 0.73828125, 0.73828125], - 133:[0.4921875, 0.73828125, 0.73828125], - 134:[0.0, 0.50390625, 0.50390625], - 135:[0.3359375, 0.50390625, 0.50390625], - 136:[0.0, 0.40625, 0.40625], - 137:[0.26953125, 0.40625, 0.40625], - 138:[0.0, 0.30859375, 0.30859375], - 139:[0.20703125, 0.30859375, 0.30859375], - 140:[0.0, 0.74609375, 0.99609375], - 141:[0.6640625, 0.9140625, 0.99609375], - 142:[0.0, 0.55078125, 0.73828125], - 143:[0.4921875, 0.67578125, 0.73828125], - 144:[0.0, 0.375, 0.50390625], - 145:[0.3359375, 0.4609375, 0.50390625], - 146:[0.0, 0.3046875, 0.40625], - 147:[0.26953125, 0.37109375, 0.40625], - 148:[0.0, 0.23046875, 0.30859375], - 149:[0.20703125, 0.28515625, 0.30859375], - 150:[0.0, 0.49609375, 0.99609375], - 151:[0.6640625, 0.828125, 0.99609375], - 152:[0.0, 0.3671875, 0.73828125], - 153:[0.4921875, 0.61328125, 0.73828125], - 154:[0.0, 0.25, 0.50390625], - 155:[0.3359375, 0.41796875, 0.50390625], - 156:[0.0, 0.203125, 0.40625], - 157:[0.26953125, 0.3359375, 0.40625], - 158:[0.0, 0.15234375, 0.30859375], - 159:[0.20703125, 0.2578125, 0.30859375], - 160:[0.0, 0.24609375, 0.99609375], - 161:[0.6640625, 0.74609375, 0.99609375], - 162:[0.0, 0.1796875, 0.73828125], - 163:[0.4921875, 0.55078125, 0.73828125], - 164:[0.0, 0.12109375, 0.50390625], - 165:[0.3359375, 0.375, 0.50390625], - 166:[0.0, 0.09765625, 0.40625], - 167:[0.26953125, 0.3046875, 0.40625], - 168:[0.0, 0.07421875, 0.30859375], - 169:[0.20703125, 0.23046875, 0.30859375], - 170:[0.0, 0.0, 0.99609375], - 171:[0.6640625, 0.6640625, 0.99609375], - 172:[0.0, 0.0, 0.73828125], - 173:[0.4921875, 0.4921875, 0.73828125], - 174:[0.0, 0.0, 0.50390625], - 175:[0.3359375, 0.3359375, 0.50390625], - 176:[0.0, 0.0, 0.40625], - 177:[0.26953125, 0.26953125, 0.40625], - 178:[0.0, 0.0, 0.30859375], - 179:[0.20703125, 0.20703125, 0.30859375], - 180:[0.24609375, 0.0, 0.99609375], - 181:[0.74609375, 0.6640625, 0.99609375], - 182:[0.1796875, 0.0, 0.73828125], - 183:[0.55078125, 0.4921875, 0.73828125], - 184:[0.12109375, 0.0, 0.50390625], - 185:[0.375, 0.3359375, 0.50390625], - 186:[0.09765625, 0.0, 0.40625], - 187:[0.3046875, 0.26953125, 0.40625], - 188:[0.07421875, 0.0, 0.30859375], - 189:[0.23046875, 0.20703125, 0.30859375], - 190:[0.49609375, 0.0, 0.99609375], - 191:[0.828125, 0.6640625, 0.99609375], - 192:[0.3671875, 0.0, 0.73828125], - 193:[0.61328125, 0.4921875, 0.73828125], - 194:[0.25, 0.0, 0.50390625], - 195:[0.41796875, 0.3359375, 0.50390625], - 196:[0.203125, 0.0, 0.40625], - 197:[0.3359375, 0.26953125, 0.40625], - 198:[0.15234375, 0.0, 0.30859375], - 199:[0.2578125, 0.20703125, 0.30859375], - 200:[0.74609375, 0.0, 0.99609375], - 201:[0.9140625, 0.6640625, 0.99609375], - 202:[0.55078125, 0.0, 0.73828125], - 203:[0.67578125, 0.4921875, 0.73828125], - 204:[0.375, 0.0, 0.50390625], - 205:[0.4609375, 0.3359375, 0.50390625], - 206:[0.3046875, 0.0, 0.40625], - 207:[0.37109375, 0.26953125, 0.40625], - 208:[0.23046875, 0.0, 0.30859375], - 209:[0.28515625, 0.20703125, 0.30859375], - 210:[0.99609375, 0.0, 0.99609375], - 211:[0.99609375, 0.6640625, 0.99609375], - 212:[0.73828125, 0.0, 0.73828125], - 213:[0.73828125, 0.4921875, 0.73828125], - 214:[0.50390625, 0.0, 0.50390625], - 215:[0.50390625, 0.3359375, 0.50390625], - 216:[0.40625, 0.0, 0.40625], - 217:[0.40625, 0.26953125, 0.40625], - 218:[0.30859375, 0.0, 0.30859375], - 219:[0.30859375, 0.20703125, 0.30859375], - 220:[0.99609375, 0.0, 0.74609375], - 221:[0.99609375, 0.6640625, 0.9140625], - 222:[0.73828125, 0.0, 0.55078125], - 223:[0.73828125, 0.4921875, 0.67578125], - 224:[0.50390625, 0.0, 0.375], - 225:[0.50390625, 0.3359375, 0.4609375], - 226:[0.40625, 0.0, 0.3046875], - 227:[0.40625, 0.26953125, 0.37109375], - 228:[0.30859375, 0.0, 0.23046875], - 229:[0.30859375, 0.20703125, 0.28515625], - 230:[0.99609375, 0.0, 0.49609375], - 231:[0.99609375, 0.6640625, 0.828125], - 232:[0.73828125, 0.0, 0.3671875], - 233:[0.73828125, 0.4921875, 0.61328125], - 234:[0.50390625, 0.0, 0.25], - 235:[0.50390625, 0.3359375, 0.41796875], - 236:[0.40625, 0.0, 0.203125], - 237:[0.40625, 0.26953125, 0.3359375], - 238:[0.30859375, 0.0, 0.15234375], - 239:[0.30859375, 0.20703125, 0.2578125], - 240:[0.99609375, 0.0, 0.24609375], - 241:[0.99609375, 0.6640625, 0.74609375], - 242:[0.73828125, 0.0, 0.1796875], - 243:[0.73828125, 0.4921875, 0.55078125], - 244:[0.50390625, 0.0, 0.12109375], - 245:[0.50390625, 0.3359375, 0.375], - 246:[0.40625, 0.0, 0.09765625], - 247:[0.40625, 0.26953125, 0.3046875], - 248:[0.30859375, 0.0, 0.07421875], - 249:[0.30859375, 0.20703125, 0.23046875], - 250:[0.19921875, 0.19921875, 0.19921875], - 251:[0.3125, 0.3125, 0.3125], - 252:[0.41015625, 0.41015625, 0.41015625], - 253:[0.5078125, 0.5078125, 0.5078125], - 254:[0.7421875, 0.7421875, 0.7421875], - 255:[0.99609375, 0.99609375, 0.99609375], -} diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py deleted file mode 100644 index ccd8ef9b625..00000000000 --- a/release/scripts/bpymodules/dxfLibrary.py +++ /dev/null @@ -1,880 +0,0 @@ -#dxfLibrary.py : provides functions for generating DXF files -# -------------------------------------------------------------------------- -__version__ = "v1.33 - 2009.06.16" -__author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)" -__license__ = "GPL" -__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" -__bpydoc__ ="""The library to export geometry data to DXF format r12 version. - -Copyright %s -Version %s -License %s -Homepage %s - -See the homepage for documentation. -Dedicated thread on BlenderArtists: http://blenderartists.org/forum/showthread.php?t=136439 - -IDEAs: -- - -TODO: -- add support for DXFr14 (needs extended file header) -- add support for SPLINEs (possible first in DXFr14 version) -- add user preset for floating point precision (3-16?) - -History -v1.33 - 2009.06.16 by migius - - modif _point(): converts all coords to floats - - modif LineType class: implement elements - - added VPORT class, incl. defaults - - fix Insert class -v1.32 - 2009.06.06 by migius - - modif Style class: changed defaults to widthFactor=1.0, obliqueAngle=0.0 - - modif Text class: alignment parameter reactivated -v1.31 - 2009.06.02 by migius - - modif _Entity class: added paperspace,elevation -v1.30 - 2009.05.28 by migius - - bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0 -v1.29 - 2008.12.28 by Yorik - - modif POLYLINE to support bulge segments -v1.28 - 2008.12.13 by Steeve/BlenderArtists - - bugfix for EXTMIN/EXTMAX to suit Cycas-CAD -v1.27 - 2008.10.07 by migius - - beautifying output code: keys whitespace prefix - - refactoring DXF-strings format: NewLine moved to the end of -v1.26 - 2008.10.05 by migius - - modif POLYLINE to support POLYFACE -v1.25 - 2008.09.28 by migius - - modif FACE class for r12 -v1.24 - 2008.09.27 by migius - - modif POLYLINE class for r12 - - changing output format from r9 to r12(AC1009) -v1.1 (20/6/2005) by www.stani.be/python/sdxf - - Python library to generate dxf drawings -______________________________________________________________ -""" % (__author__,__version__,__license__,__url__) - -# -------------------------------------------------------------------------- -# DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani) -# 2008/2009 modif by Remigiusz Fiedler (AKA migius) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - - -#import Blender -#from Blender import Mathutils, Window, Scene, sys, Draw -#import BPyMessages - -try: - import copy - #from struct import pack -except: - copy = None - -####1) Private (only for developpers) -_HEADER_POINTS=['insbase','extmin','extmax'] - -#---helper functions----------------------------------- -def _point(x,index=0): - """Convert tuple to a dxf point""" - #print 'deb: _point=', x #------------- - return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))]) - -def _points(plist): - """Convert a list of tuples to dxf points""" - out = '\n'.join([_point(plist[i],i)for i in range(len(plist))]) - return out - -#---base classes---------------------------------------- -class _Call: - """Makes a callable class.""" - def copy(self): - """Returns a copy.""" - return copy.deepcopy(self) - - def __call__(self,**attrs): - """Returns a copy with modified attributes.""" - copied=self.copy() - for attr in attrs:setattr(copied,attr,attrs[attr]) - return copied - -#------------------------------------------------------- -class _Entity(_Call): - """Base class for _common group codes for entities.""" - def __init__(self,paperspace=None,color=None,layer='0', - lineType=None,lineTypeScale=None,lineWeight=None, - extrusion=None,elevation=None,thickness=None, - parent=None): - """None values will be omitted.""" - self.paperspace = paperspace - self.color = color - self.layer = layer - self.lineType = lineType - self.lineTypeScale = lineTypeScale - self.lineWeight = lineWeight - self.extrusion = extrusion - self.elevation = elevation - self.thickness = thickness - #self.visible = visible - self.parent = parent - - def _common(self): - """Return common group codes as a string.""" - if self.parent:parent=self.parent - else:parent=self - result ='' - if parent.paperspace==1: result+=' 67\n1\n' - if parent.layer!=None: result+=' 8\n%s\n'%parent.layer - if parent.color!=None: result+=' 62\n%s\n'%parent.color - if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType - # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight - # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible - if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale - if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation - if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness - if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200) - return result - -#-------------------------- -class _Entities: - """Base class to deal with composed objects.""" - def __dxf__(self): - return [] - - def __str__(self): - return ''.join([str(x) for x in self.__dxf__()]) - -#-------------------------- -class _Collection(_Call): - """Base class to expose entities methods to main object.""" - def __init__(self,entities=[]): - self.entities=copy.copy(entities) - #link entities methods to drawing - for attr in dir(self.entities): - if attr[0]!='_': - attrObject=getattr(self.entities,attr) - if callable(attrObject): - setattr(self,attr,attrObject) - -####2) Constants -#---color values -BYBLOCK=0 -BYLAYER=256 - -#---block-type flags (bit coded values, may be combined): -ANONYMOUS =1 # This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application -NON_CONSTANT_ATTRIBUTES =2 # This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all) -XREF =4 # This block is an external reference (xref) -XREF_OVERLAY =8 # This block is an xref overlay -EXTERNAL =16 # This block is externally dependent -RESOLVED =32 # This is a resolved external reference, or dependent of an external reference (ignored on input) -REFERENCED =64 # This definition is a referenced external reference (ignored on input) - -#---mtext flags -#attachment point -TOP_LEFT = 1 -TOP_CENTER = 2 -TOP_RIGHT = 3 -MIDDLE_LEFT = 4 -MIDDLE_CENTER = 5 -MIDDLE_RIGHT = 6 -BOTTOM_LEFT = 7 -BOTTOM_CENTER = 8 -BOTTOM_RIGHT = 9 -#drawing direction -LEFT_RIGHT = 1 -TOP_BOTTOM = 3 -BY_STYLE = 5 #the flow direction is inherited from the associated text style -#line spacing style (optional): -AT_LEAST = 1 #taller characters will override -EXACT = 2 #taller characters will not override - -#---polyline flags -CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction) -CURVE_FIT =2 # Curve-fit vertices have been added -SPLINE_FIT =4 # Spline-fit vertices have been added -POLYLINE_3D =8 # This is a 3D polyline -POLYGON_MESH =16 # This is a 3D polygon mesh -CLOSED_N =32 # The polygon mesh is closed in the N direction -POLYFACE_MESH =64 # The polyline is a polyface mesh -CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline - -#---text flags -#horizontal -LEFT = 0 -CENTER = 1 -RIGHT = 2 -ALIGNED = 3 #if vertical alignment = 0 -MIDDLE = 4 #if vertical alignment = 0 -FIT = 5 #if vertical alignment = 0 -#vertical -BASELINE = 0 -BOTTOM = 1 -MIDDLE = 2 -TOP = 3 - -####3) Classes -#---entitities ----------------------------------------------- -#-------------------------- -class Arc(_Entity): - """Arc, angles in degrees.""" - def __init__(self,center=(0,0,0),radius=1, - startAngle=0.0,endAngle=90,**common): - """Angles in degrees.""" - _Entity.__init__(self,**common) - self.center=center - self.radius=radius - self.startAngle=startAngle - self.endAngle=endAngle - def __str__(self): - return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\ - (self._common(),_point(self.center), - self.radius,self.startAngle,self.endAngle) - -#----------------------------------------------- -class Circle(_Entity): - """Circle""" - def __init__(self,center=(0,0,0),radius=1,**common): - _Entity.__init__(self,**common) - self.center=center - self.radius=radius - def __str__(self): - return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\ - (self._common(),_point(self.center),self.radius) - -#----------------------------------------------- -class Face(_Entity): - """3dface""" - def __init__(self,points,**common): - _Entity.__init__(self,**common) - while len(points)<4: #fix for r12 format - points.append(points[-1]) - self.points=points - - def __str__(self): - out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points)) - #print 'deb:out=', out #------------------- - return out - -#----------------------------------------------- -class Insert(_Entity): - """Block instance.""" - def __init__(self,name,point=(0,0,0), - xscale=None,yscale=None,zscale=None, - cols=None,colspacing=None,rows=None,rowspacing=None, - rotation=None, - **common): - _Entity.__init__(self,**common) - self.name=name - self.point=point - self.xscale=xscale - self.yscale=yscale - self.zscale=zscale - self.cols=cols - self.colspacing=colspacing - self.rows=rows - self.rowspacing=rowspacing - self.rotation=rotation - - def __str__(self): - result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\ - (self.name,self._common(),_point(self.point)) - if self.xscale!=None:result+=' 41\n%s\n'%self.xscale - if self.yscale!=None:result+=' 42\n%s\n'%self.yscale - if self.zscale!=None:result+=' 43\n%s\n'%self.zscale - if self.rotation:result+=' 50\n%s\n'%self.rotation - if self.cols!=None:result+=' 70\n%s\n'%self.cols - if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing - if self.rows!=None:result+=' 71\n%s\n'%self.rows - if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing - return result - -#----------------------------------------------- -class Line(_Entity): - """Line""" - def __init__(self,points,**common): - _Entity.__init__(self,**common) - self.points=points - def __str__(self): - return ' 0\nLINE\n%s%s\n' %( - self._common(), _points(self.points)) - - -#----------------------------------------------- -class PolyLine(_Entity): - def __init__(self,points,org_point=[0,0,0],flag=0,width=None,**common): - #width = number, or width = list [width_start=None, width_end=None] - #for 2d-polyline: points = [ [x, y, z, width_start=None, width_end=None, bulge=0 or None], ...] - #for 3d-polyline: points = [ [x, y, z], ...] - #for polyface: points = [points_list, faces_list] - _Entity.__init__(self,**common) - self.points=points - self.org_point=org_point - self.flag=flag - self.polyface = False - self.polyline2d = False - self.faces = [] # dummy value - self.width= None # dummy value - if self.flag & POLYFACE_MESH: - self.polyface=True - self.points=points[0] - self.faces=points[1] - self.p_count=len(self.points) - self.f_count=len(self.faces) - elif not self.flag & POLYLINE_3D: - self.polyline2d = True - if width: - if type(width)!='list': - width=[width,width] - self.width=width - - def __str__(self): - result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag) - result+=' 66\n1\n' - result+='%s\n' %_point(self.org_point) - if self.polyface: - result+=' 71\n%s\n' %self.p_count - result+=' 72\n%s\n' %self.f_count - elif self.polyline2d: - if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) - for point in self.points: - result+=' 0\nVERTEX\n' - result+=' 8\n%s\n' %self.layer - if self.polyface: - result+='%s\n' %_point(point[0:3]) - result+=' 70\n192\n' - elif self.polyline2d: - result+='%s\n' %_point(point[0:2]) - if len(point)>4: - width1, width2 = point[3], point[4] - if width1!=None: result+=' 40\n%s\n' %width1 - if width2!=None: result+=' 41\n%s\n' %width2 - if len(point)==6: - bulge = point[5] - if bulge: result+=' 42\n%s\n' %bulge - else: - result+='%s\n' %_point(point[0:3]) - for face in self.faces: - result+=' 0\nVERTEX\n' - result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(self.org_point) - result+=' 70\n128\n' - result+=' 71\n%s\n' %face[0] - result+=' 72\n%s\n' %face[1] - result+=' 73\n%s\n' %face[2] - if len(face)==4: result+=' 74\n%s\n' %face[3] - result+=' 0\nSEQEND\n' - result+=' 8\n%s\n' %self.layer - return result - -#----------------------------------------------- -class Point(_Entity): - """Point.""" - def __init__(self,points=None,**common): - _Entity.__init__(self,**common) - self.points=points - def __str__(self): # TODO: - return ' 0\nPOINT\n%s%s\n' %(self._common(), - _points(self.points) - ) - -#----------------------------------------------- -class Solid(_Entity): - """Colored solid fill.""" - def __init__(self,points=None,**common): - _Entity.__init__(self,**common) - self.points=points - def __str__(self): - return ' 0\nSOLID\n%s%s\n' %(self._common(), - _points(self.points[:2]+[self.points[3],self.points[2]]) - ) - - -#----------------------------------------------- -class Text(_Entity): - """Single text line.""" - def __init__(self,text='',point=(0,0,0),alignment=None, - flag=None,height=1,justifyhor=None,justifyver=None, - rotation=None,obliqueAngle=None,style=None,xscale=None,**common): - _Entity.__init__(self,**common) - self.text=text - self.point=point - self.alignment=alignment - self.flag=flag - self.height=height - self.justifyhor=justifyhor - self.justifyver=justifyver - self.rotation=rotation - self.obliqueAngle=obliqueAngle - self.style=style - self.xscale=xscale - def __str__(self): - result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\ - (self._common(),_point(self.point),self.height,self.text) - if self.rotation: result+=' 50\n%s\n'%self.rotation - if self.xscale: result+=' 41\n%s\n'%self.xscale - if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle - if self.style: result+=' 7\n%s\n'%self.style - if self.flag: result+=' 71\n%s\n'%self.flag - if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor - if self.alignment: result+='%s\n'%_point(self.alignment,1) - if self.justifyver: result+=' 73\n%s\n'%self.justifyver - return result - -#----------------------------------------------- -class Mtext(Text): - """Surrogate for mtext, generates some Text instances.""" - def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options): - Text.__init__(self,text=text,point=point,**options) - if down:spacingFactor*=-1 - self.spacingFactor=spacingFactor - self.spacingWidth=spacingWidth - self.width=width - self.down=down - def __str__(self): - texts=self.text.replace('\r\n','\n').split('\n') - if not self.down:texts.reverse() - result='' - x=y=0 - if self.spacingWidth:spacingWidth=self.spacingWidth - else:spacingWidth=self.height*self.spacingFactor - for text in texts: - while text: - result+='%s\n'%Text(text[:self.width], - point=(self.point[0]+x*spacingWidth, - self.point[1]+y*spacingWidth, - self.point[2]), - alignment=self.alignment,flag=self.flag,height=self.height, - justifyhor=self.justifyhor,justifyver=self.justifyver, - rotation=self.rotation,obliqueAngle=self.obliqueAngle, - style=self.style,xscale=self.xscale,parent=self - ) - text=text[self.width:] - if self.rotation:x+=1 - else:y+=1 - return result[1:] - -#----------------------------------------------- -##class _Mtext(_Entity): -## """Mtext not functioning for minimal dxf.""" -## def __init__(self,text='',point=(0,0,0),attachment=1, -## charWidth=None,charHeight=1,direction=1,height=100,rotation=0, -## spacingStyle=None,spacingFactor=None,style=None,width=100, -## xdirection=None,**common): -## _Entity.__init__(self,**common) -## self.text=text -## self.point=point -## self.attachment=attachment -## self.charWidth=charWidth -## self.charHeight=charHeight -## self.direction=direction -## self.height=height -## self.rotation=rotation -## self.spacingStyle=spacingStyle -## self.spacingFactor=spacingFactor -## self.style=style -## self.width=width -## self.xdirection=xdirection -## def __str__(self): -## input=self.text -## text='' -## while len(input)>250: -## text+='3\n%s\n'%input[:250] -## input=input[250:] -## text+='1\n%s\n'%input -## result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\ -## (self._common(),_point(self.point),self.charHeight,self.width, -## self.attachment,self.direction,text, -## self.height, -## self.rotation) -## if self.style:result+='7\n%s\n'%self.style -## if self.xdirection:result+='%s\n'%_point(self.xdirection,1) -## if self.charWidth:result+='42\n%s\n'%self.charWidth -## if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle -## if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor -## return result - -#---tables --------------------------------------------------- -#----------------------------------------------- -class Block(_Collection): - """Use list methods to add entities, eg append.""" - def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]): - self.entities=copy.copy(entities) - _Collection.__init__(self,entities) - self.layer=layer - self.name=name - self.flag=0 - self.base=base - def __str__(self): # TODO: - e=''.join([str(x)for x in self.entities]) - return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\ - (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e) - -#----------------------------------------------- -class Layer(_Call): - """Layer""" - def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64): - self.name=name - self.color=color - self.lineType=lineType - self.flag=flag - def __str__(self): - return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\ - (self.name.upper(),self.flag,self.color,self.lineType) - -#----------------------------------------------- -class LineType(_Call): - """Custom linetype""" - def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0): - self.name=name - self.description=description - self.elements=copy.copy(elements) - self.flag=flag - def __str__(self): - result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\ - (self.name.upper(),self.flag,self.description) - if self.elements: - elements = ' 73\n%s\n' %(len(self.elements)-1) - elements += ' 40\n%s\n' %(self.elements[0]) - for e in self.elements[1:]: - elements += ' 49\n%s\n' %e - result += elements - return result - - -#----------------------------------------------- -class Style(_Call): - """Text style""" - def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0, - mirror=0,lastHeight=1,font='arial.ttf',bigFont=''): - self.name=name - self.flag=flag - self.height=height - self.widthFactor=widthFactor - self.obliqueAngle=obliqueAngle - self.mirror=mirror - self.lastHeight=lastHeight - self.font=font - self.bigFont=bigFont - def __str__(self): - return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\ - (self.name.upper(),self.flag,self.flag,self.widthFactor, - self.obliqueAngle,self.mirror,self.lastHeight, - self.font.upper(),self.bigFont.upper()) - -#----------------------------------------------- -class VPort(_Call): - def __init__(self,name,flag=0, - leftBottom=(0.0,0.0), - rightTop=(1.0,1.0), - center=(0.5,0.5), - snap_base=(0.0,0.0), - snap_spacing=(0.1,0.1), - grid_spacing=(0.1,0.1), - direction=(0.0,0.0,1.0), - target=(0.0,0.0,0.0), - height=1.0, - ratio=1.0, - lens=50, - frontClipping=0, - backClipping=0, - snap_rotation=0, - twist=0, - mode=0, - circle_zoom=100, - fast_zoom=1, - ucsicon=1, - snap_on=0, - grid_on=0, - snap_style=0, - snap_isopair=0 - ): - self.name=name - self.flag=flag - self.leftBottom=leftBottom - self.rightTop=rightTop - self.center=center - self.snap_base=snap_base - self.snap_spacing=snap_spacing - self.grid_spacing=grid_spacing - self.direction=direction - self.target=target - self.height=float(height) - self.ratio=float(ratio) - self.lens=float(lens) - self.frontClipping=float(frontClipping) - self.backClipping=float(backClipping) - self.snap_rotation=float(snap_rotation) - self.twist=float(twist) - self.mode=mode - self.circle_zoom=circle_zoom - self.fast_zoom=fast_zoom - self.ucsicon=ucsicon - self.snap_on=snap_on - self.grid_on=grid_on - self.snap_style=snap_style - self.snap_isopair=snap_isopair - def __str__(self): - output = [' 0', 'VPORT', - ' 2', self.name, - ' 70', self.flag, - _point(self.leftBottom), - _point(self.rightTop,1), - _point(self.center,2), # View center point (in DCS) - _point(self.snap_base,3), - _point(self.snap_spacing,4), - _point(self.grid_spacing,5), - _point(self.direction,6), #view direction from target (in WCS) - _point(self.target,7), - ' 40', self.height, - ' 41', self.ratio, - ' 42', self.lens, - ' 43', self.frontClipping, - ' 44', self.backClipping, - ' 50', self.snap_rotation, - ' 51', self.twist, - ' 71', self.mode, - ' 72', self.circle_zoom, - ' 73', self.fast_zoom, - ' 74', self.ucsicon, - ' 75', self.snap_on, - ' 76', self.grid_on, - ' 77', self.snap_style, - ' 78', self.snap_isopair - ] - - output_str = '' - for s in output: - output_str += '%s\n' %s - return output_str - - - -#----------------------------------------------- -class View(_Call): - def __init__(self,name,flag=0, - width=1, - height=1, - center=(0.5,0.5), - direction=(0,0,1), - target=(0,0,0), - lens=50, - frontClipping=0, - backClipping=0, - twist=0,mode=0 - ): - self.name=name - self.flag=flag - self.width=float(width) - self.height=float(height) - self.center=center - self.direction=direction - self.target=target - self.lens=float(lens) - self.frontClipping=float(frontClipping) - self.backClipping=float(backClipping) - self.twist=float(twist) - self.mode=mode - def __str__(self): - output = [' 0', 'VIEW', - ' 2', self.name, - ' 70', self.flag, - ' 40', self.height, - _point(self.center), - ' 41', self.width, - _point(self.direction,1), - _point(self.target,2), - ' 42', self.lens, - ' 43', self.frontClipping, - ' 44', self.backClipping, - ' 50', self.twist, - ' 71', self.mode - ] - output_str = '' - for s in output: - output_str += '%s\n' %s - return output_str - -#----------------------------------------------- -def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options): - width=abs(rightTop[0]-leftBottom[0]) - height=abs(rightTop[1]-leftBottom[1]) - center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5) - return View(name=name,width=width,height=height,center=center,**options) - -#---drawing -#----------------------------------------------- -class Drawing(_Collection): - """Dxf drawing. Use append or any other list methods to add objects.""" - def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0), - layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[], - views=[],vports=[],entities=None,fileName='test.dxf'): - # TODO: replace list with None,arial - if not entities: - entities=[] - _Collection.__init__(self,entities) - self.insbase=insbase - self.extmin=extmin - self.extmax=extmax - self.layers=copy.copy(layers) - self.linetypes=copy.copy(linetypes) - self.styles=copy.copy(styles) - self.views=copy.copy(views) - self.vports=copy.copy(vports) - self.blocks=copy.copy(blocks) - self.fileName=fileName - #private - #self.acadver='9\n$ACADVER\n1\nAC1006\n' - self.acadver=' 9\n$ACADVER\n 1\nAC1009\n' - """DXF AutoCAD-Release format codes - AC1021 2008, 2007 - AC1018 2006, 2005, 2004 - AC1015 2002, 2000i, 2000 - AC1014 R14,14.01 - AC1012 R13 - AC1009 R12,11 - AC1006 R10 - AC1004 R9 - AC1002 R2.6 - AC1.50 R2.05 - """ - - def _name(self,x): - """Helper function for self._point""" - return ' 9\n$%s\n' %x.upper() - - def _point(self,name,x): - """Point setting from drawing like extmin,extmax,...""" - return '%s%s' %(self._name(name),_point(x)) - - def _section(self,name,x): - """Sections like tables,blocks,entities,...""" - if x: xstr=''.join(x) - else: xstr='' - return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr) - - def _table(self,name,x): - """Tables like ltype,layer,style,...""" - if x: xstr=''.join(x) - else: xstr='' - return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr) - - def __str__(self): - """Returns drawing as dxf string.""" - header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS] - header=self._section('header',header) - - tables=[self._table('vport',[str(x) for x in self.vports]), - self._table('ltype',[str(x) for x in self.linetypes]), - self._table('layer',[str(x) for x in self.layers]), - self._table('style',[str(x) for x in self.styles]), - self._table('view',[str(x) for x in self.views]), - ] - tables=self._section('tables',tables) - - blocks=self._section('blocks',[str(x) for x in self.blocks]) - - entities=self._section('entities',[str(x) for x in self.entities]) - - all=''.join([header,tables,blocks,entities,' 0\nEOF\n']) - return all - - def saveas(self,fileName): - self.fileName=fileName - self.save() - - def save(self): - test=open(self.fileName,'w') - test.write(str(self)) - test.close() - - -#---extras -#----------------------------------------------- -class Rectangle(_Entity): - """Rectangle, creates lines.""" - def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common): - _Entity.__init__(self,**common) - self.point=point - self.width=width - self.height=height - self.solid=solid - self.line=line - def __str__(self): - result='' - points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]), - (self.point[0]+self.width,self.point[1]+self.height,self.point[2]), - (self.point[0],self.point[1]+self.height,self.point[2]),self.point] - if self.solid: - result+= Solid(points=points[:-1],parent=self.solid) - if self.line: - for i in range(4): - result+= Line(points=[points[i],points[i+1]],parent=self) - return result[1:] - -#----------------------------------------------- -class LineList(_Entity): - """Like polyline, but built of individual lines.""" - def __init__(self,points=[],org_point=[0,0,0],closed=0,**common): - _Entity.__init__(self,**common) - self.closed=closed - self.points=copy.copy(points) - def __str__(self): - if self.closed:points=self.points+[self.points[0]] - else: points=self.points - result='' - for i in range(len(points)-1): - result+= Line(points=[points[i],points[i+1]],parent=self) - return result[1:] - -#----------------------------------------------------- -def test(): - #Blocks - b=Block('test') - b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1)) - b.append(Arc(center=(1,0,0),color=2)) - - #Drawing - d=Drawing() - #tables - d.blocks.append(b) #table blocks - d.styles.append(Style()) #table styles - d.views.append(View('Normal')) #table view - d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem - - #entities - d.append(Circle(center=(1,1,0),color=3)) - d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4)) - d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2)) - d.append(Line(points=[(0,0,0),(1,1,1)])) - d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90)) - d.append(Text('Please donate!',point=(3,0,1))) - #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2))) - d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3)) - #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1)) - - #d.saveas('c:\\test.dxf') - d.saveas('test.dxf') - -#----------------------------------------------------- -if __name__=='__main__': - if not copy: - Draw.PupMenu('Error%t|This script requires a full python install') - else: test() - \ No newline at end of file diff --git a/release/scripts/bpymodules/dxfReader.py b/release/scripts/bpymodules/dxfReader.py deleted file mode 100644 index df4ebc309e4..00000000000 --- a/release/scripts/bpymodules/dxfReader.py +++ /dev/null @@ -1,381 +0,0 @@ -"""This module provides a function for reading dxf files and parsing them into a useful tree of objects and data. - - The convert function is called by the readDXF fuction to convert dxf strings into the correct data based - on their type code. readDXF expects a (full path) file name as input. -""" - -# -------------------------------------------------------------------------- -# DXF Reader v0.9 by Ed Blake (AKA Kitsu) -# 2008.05.08 modif.def convert() by Remigiusz Fiedler (AKA migius) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -#from dxfImportObjects import * - -class Object: - """Empty container class for dxf objects""" - - def __init__(self, _type='', block=False): - """_type expects a string value.""" - self.type = _type - self.name = '' - self.data = [] - - def __str__(self): - if self.name: - return self.name - else: - return self.type - - def __repr__(self): - return str(self.data) - - def get_type(self, kind=''): - """Despite the name, this method actually returns all objects of type 'kind' from self.data.""" - if type: - objects = [] - for item in self.data: - if type(item) != list and item.type == kind: - # we want this type of object - objects.append(item) - elif type(item) == list and item[0] == kind: - # we want this type of data - objects.append(item[1]) - return objects - - -class InitializationError(Exception): pass - -class StateMachine: - """(finite) State Machine from the great David Mertz's great Charming Python article.""" - - def __init__(self): - self.handlers = [] - self.startState = None - self.endStates = [] - - def add_state(self, handler, end_state=0): - """All states and handlers are functions which return - a state and a cargo.""" - self.handlers.append(handler) - if end_state: - self.endStates.append(handler) - def set_start(self, handler): - """Sets the starting handler function.""" - self.startState = handler - - - def run(self, cargo=None): - if not self.startState: - raise InitializationError,\ - "must call .set_start() before .run()" - if not self.endStates: - raise InitializationError, \ - "at least one state must be an end_state" - handler = self.startState - while 1: - (newState, cargo) = handler(cargo) - #print cargo - if newState in self.endStates: - return newState(cargo) - #break - elif newState not in self.handlers: - raise RuntimeError, "Invalid target %s" % newState - else: - handler = newState - -def get_name(data): - """Get the name of an object from its object data. - - Returns a pair of (data_item, name) where data_item is the list entry where the name was found - (the data_item can be used to remove the entry from the object data). Be sure to check - name not None before using the returned values! - """ - value = None - for item in data: - if item[0] == 2: - value = item[1] - break - return item, value - -def get_layer(data): - """Expects object data as input. - - Returns (entry, layer_name) where entry is the data item that provided the layer name. - """ - value = None - for item in data: - if item[0] == 8: - value = item[1] - break - return item, value - - -def convert(code, value): - """Convert a string to the correct Python type based on its dxf code. - code types: - ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070 - longs = 90-99, 420-429, 440-459, 1071 - floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059 - hex = 105, 310-379, 390-399 - strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009 - """ - if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071: - value = int(float(value)) - elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071: - value = long(float(value)) - elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060: - value = float(value) - elif code == 105 or 309 < code < 380 or 389 < code < 400: - value = int(value, 16) # should be left as string? - else: # it's already a string so do nothing - pass - return value - - -def findObject(infile, kind=''): - """Finds the next occurance of an object.""" - obj = False - while 1: - line = infile.readline() - if not line: # readline returns '' at eof - return False - if not obj: # We're still looking for our object code - if line.lower().strip() == '0': - obj = True # found it - else: # we are in an object definition - if kind: # if we're looking for a particular kind - if line.lower().strip() == kind: - obj = Object(line.lower().strip()) - break - else: # otherwise take anything non-numeric - if line.lower().strip() not in string.digits: - obj = Object(line.lower().strip()) - break - obj = False # whether we found one or not it's time to start over - return obj - -def handleObject(infile): - """Add data to an object until end of object is found.""" - line = infile.readline() - if line.lower().strip() == 'section': - return 'section' # this would be a problem - elif line.lower().strip() == 'endsec': - return 'endsec' # this means we are done with a section - else: # add data to the object until we find a new object - obj = Object(line.lower().strip()) - obj.name = obj.type - done = False - data = [] - while not done: - line = infile.readline() - if not data: - if line.lower().strip() == '0': - #we've found an object, time to return - return obj - else: - # first part is always an int - data.append(int(line.lower().strip())) - else: - data.append(convert(data[0], line.strip())) - obj.data.append(data) - data = [] - -def handleTable(table, infile): - """Special handler for dealing with nested table objects.""" - item, name = get_name(table.data) - if name: # We should always find a name - table.data.remove(item) - table.name = name.lower() - # This next bit is from handleObject - # handleObject should be generalized to work with any section like object - while 1: - obj = handleObject(infile) - if obj.type == 'table': - print "Warning: previous table not closed!" - return table - elif obj.type == 'endtab': - return table # this means we are done with the table - else: # add objects to the table until one of the above is found - table.data.append(obj) - - - - -def handleBlock(block, infile): - """Special handler for dealing with nested table objects.""" - item, name = get_name(block.data) - if name: # We should always find a name - block.data.remove(item) - block.name = name - # This next bit is from handleObject - # handleObject should be generalized to work with any section like object - while 1: - obj = handleObject(infile) - if obj.type == 'block': - print "Warning: previous block not closed!" - return block - elif obj.type == 'endblk': - return block # this means we are done with the table - else: # add objects to the table until one of the above is found - block.data.append(obj) - - - - -"""These are the states/functions used in the State Machine. -states: - start - find first section - start_section - add data, find first object - object - add obj-data, watch for next obj (called directly by start_section) - end_section - look for next section or eof - end - return results -""" - -def start(cargo): - """Expects the infile as cargo, initializes the cargo.""" - #print "Entering start state!" - infile = cargo - drawing = Object('drawing') - section = findObject(infile, 'section') - if section: - return start_section, (infile, drawing, section) - else: - return error, (infile, "Failed to find any sections!") - -def start_section(cargo): - """Expects [infile, drawing, section] as cargo, builds a nested section object.""" - #print "Entering start_section state!" - infile = cargo[0] - drawing = cargo[1] - section = cargo[2] - # read each line, if it is an object declaration go to object mode - # otherwise create a [index, data] pair and add it to the sections data. - done = False - data = [] - while not done: - line = infile.readline() - - if not data: # if we haven't found a dxf code yet - if line.lower().strip() == '0': - # we've found an object - while 1: # no way out unless we find an end section or a new section - obj = handleObject(infile) - if obj == 'section': # shouldn't happen - print "Warning: failed to close previous section!" - return end_section, (infile, drawing) - elif obj == 'endsec': # This section is over, look for the next - drawing.data.append(section) - return end_section, (infile, drawing) - elif obj.type == 'table': # tables are collections of data - obj = handleTable(obj, infile) # we need to find all there contents - section.data.append(obj) # before moving on - elif obj.type == 'block': # the same is true of blocks - obj = handleBlock(obj, infile) # we need to find all there contents - section.data.append(obj) # before moving on - else: # found another sub-object - section.data.append(obj) - else: - data.append(int(line.lower().strip())) - else: # we have our code, now we just need to convert the data and add it to our list. - data.append(convert(data[0], line.strip())) - section.data.append(data) - data = [] -def end_section(cargo): - """Expects (infile, drawing) as cargo, searches for next section.""" - #print "Entering end_section state!" - infile = cargo[0] - drawing = cargo[1] - section = findObject(infile, 'section') - if section: - return start_section, (infile, drawing, section) - else: - return end, (infile, drawing) - -def end(cargo): - """Expects (infile, drawing) as cargo, called when eof has been reached.""" - #print "Entering end state!" - infile = cargo[0] - drawing = cargo[1] - #infile.close() - return drawing - -def error(cargo): - """Expects a (infile, string) as cargo, called when there is an error during processing.""" - #print "Entering error state!" - infile = cargo[0] - err = cargo[1] - infile.close() - print "There has been an error:" - print err - return False - -def readDXF(filename, objectify): - """Given a file name try to read it as a dxf file. - - Output is an object with the following structure - drawing - header - header data - classes - class data - tables - table data - blocks - block data - entities - entity data - objects - object data - where foo data is a list of sub-objects. True object data - is of the form [code, data]. -""" - infile = open(filename) - - sm = StateMachine() - sm.add_state(error, True) - sm.add_state(end, True) - sm.add_state(start_section) - sm.add_state(end_section) - sm.add_state(start) - sm.set_start(start) - try: - drawing = sm.run(infile) - if drawing: - drawing.name = filename - for obj in drawing.data: - item, name = get_name(obj.data) - if name: - obj.data.remove(item) - obj.name = name.lower() - setattr(drawing, name.lower(), obj) - # Call the objectify function to cast - # raw objects into the right types of object - obj.data = objectify(obj.data) - #print obj.name - finally: - infile.close() - return drawing -if __name__ == "__main__": - filename = r".\examples\block-test.dxf" - drawing = readDXF(filename) - for item in drawing.entities.data: - print item diff --git a/release/scripts/bpymodules/mesh_gradient.py b/release/scripts/bpymodules/mesh_gradient.py deleted file mode 100644 index e582a30152b..00000000000 --- a/release/scripts/bpymodules/mesh_gradient.py +++ /dev/null @@ -1,229 +0,0 @@ -# This is not to be used directly, vertexGradientPick can be used externaly - -import Blender -import BPyMesh -import BPyWindow - -mouseViewRay= BPyWindow.mouseViewRay -from Blender import Mathutils, Window, Scene, Draw, sys -from Blender.Mathutils import Vector, Intersect, LineIntersect, AngleBetweenVecs -LMB= Window.MButs['L'] - -def mouseup(): - # Loop until click - mouse_buttons = Window.GetMouseButtons() - while not mouse_buttons & LMB: - sys.sleep(10) - mouse_buttons = Window.GetMouseButtons() - while mouse_buttons & LMB: - sys.sleep(10) - mouse_buttons = Window.GetMouseButtons() - -def mousedown_wait(): - # If the menu has just been pressed dont use its mousedown, - mouse_buttons = Window.GetMouseButtons() - while mouse_buttons & LMB: - mouse_buttons = Window.GetMouseButtons() - -eps= 0.0001 -def vertexGradientPick(ob, MODE): - #MODE 0 == VWEIGHT, 1 == VCOL - - me= ob.getData(mesh=1) - if not me.faceUV: me.faceUV= True - - Window.DrawProgressBar (0.0, '') - - mousedown_wait() - - if MODE==0: - act_group= me.activeGroup - if act_group == None: - mousedown_wait() - Draw.PupMenu('Error, mesh has no active group.') - return - - # Loop until click - Window.DrawProgressBar (0.25, 'Click to set gradient start') - mouseup() - - obmat= ob.matrixWorld - screen_x, screen_y = Window.GetMouseCoords() - mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat) - if not mouseInView or not OriginA: - return - - # get the mouse weight - - if MODE==0: - pickValA= BPyMesh.pickMeshGroupWeight(me, act_group, OriginA, DirectionA) - if MODE==1: - pickValA= BPyMesh.pickMeshGroupVCol(me, OriginA, DirectionA) - - Window.DrawProgressBar (0.75, 'Click to set gradient end') - mouseup() - - TOALPHA= Window.GetKeyQualifiers() & Window.Qual.SHIFT - - screen_x, screen_y = Window.GetMouseCoords() - mouseInView, OriginB, DirectionB = mouseViewRay(screen_x, screen_y, obmat) - if not mouseInView or not OriginB: - return - - if not TOALPHA: # Only get a second opaque value if we are not blending to alpha - if MODE==0: pickValB= BPyMesh.pickMeshGroupWeight(me, act_group, OriginB, DirectionB) - else: - pickValB= BPyMesh.pickMeshGroupVCol(me, OriginB, DirectionB) - else: - if MODE==0: pickValB= 0.0 - else: pickValB= [0.0, 0.0, 0.0] # Dummy value - - # Neither points touched a face - if pickValA == pickValB == None: - return - - # clicking on 1 non face is fine. just set the weight to 0.0 - if pickValA==None: - pickValA= 0.0 - - # swap A/B - OriginA, OriginB= OriginB, OriginA - DirectionA, DirectionB= DirectionB, DirectionA - pickValA, pickValB= pickValA, pickValB - - TOALPHA= True - - if pickValB==None: - pickValB= 0.0 - TOALPHA= True - - # set up 2 lines so we can measure their distances and calc the gradient - - # make a line 90d to the grad in screenspace. - if (OriginA-OriginB).length <= eps: # Persp view. same origin different direction - cross_grad= DirectionA.cross(DirectionB) - ORTHO= False - - else: # Ortho - Same direction, different origin - cross_grad= DirectionA.cross(OriginA-OriginB) - ORTHO= True - - cross_grad.normalize() - cross_grad= cross_grad * 100 - - lineA= (OriginA, OriginA+(DirectionA*100)) - lineB= (OriginB, OriginB+(DirectionB*100)) - - if not ORTHO: - line_angle= AngleBetweenVecs(lineA[1], lineB[1])/2 - line_mid= (lineA[1]+lineB[1])*0.5 - - VSEL= [False] * (len(me.verts)) - - # Get the selected faces and apply the selection to the verts. - for f in me.faces: - if f.sel: - for v in f.v: - VSEL[v.index]= True - groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) - - - - def grad_weight_from_co(v): - ''' - Takes a vert and retuens its gradient radio between A and B - ''' - - if not VSEL[v.index]: # Not bart of a selected face? - return None, None - - v_co= v.co - # make a line 90d to the 2 lines the user clicked. - vert_line= (v_co - cross_grad, v_co + cross_grad) - - xA= LineIntersect(vert_line[0], vert_line[1], lineA[0], lineA[1]) - xB= LineIntersect(vert_line[0], vert_line[1], lineB[0], lineB[1]) - - if not xA or not xB: # Should never happen but support it anyhow - return None, None - - wA= (xA[0]-xA[1]).length - wB= (xB[0]-xB[1]).length - - wTot= wA+wB - if not wTot: # lines are on the same point. - return None, None - - ''' - Get the length of the line between both intersections on the - 2x view lines. - if the dist between lineA+VertLine and lineB+VertLine is - greater then the lenth between lineA and lineB intersection points, it means - that the verts are not inbetween the 2 lines. - ''' - lineAB_length= (xA[1]-xB[1]).length - - # normalzie - wA= wA/wTot - wB= wB/wTot - - if ORTHO: # Con only use line length method with parelelle lines - if wTot > lineAB_length+eps: - # vert is outside the range on 1 side. see what side of the grad - if wA>wB: wA, wB= 1.0, 0.0 - else: wA, wB= 0.0, 1.0 - else: - # PERSP, lineA[0] is the same origin as lineB[0] - - # Either xA[0] or xB[0] can be used instead of a possible x_mid between the 2 - # as long as the point is inbetween lineA and lineB it dosent matter. - a= AngleBetweenVecs(lineA[0]-xA[0], line_mid) - if a>line_angle: - # vert is outside the range on 1 side. see what side of the grad - if wA>wB: wA, wB= 1.0, 0.0 - else: wA, wB= 0.0, 1.0 - - return wA, wB - - - grad_weights= [grad_weight_from_co(v) for v in me.verts] - - - if MODE==0: - for v in me.verts: - i= v.index - if VSEL[i]: - wA, wB = grad_weights[i] - if wA != None: # and wB - if TOALPHA: - # Do alpha by using the exiting weight for - try: pickValB= vWeightDict[i][act_group] - except: pickValB= 0.0 # The weights not there? assume zero - # Mix2 2 opaque weights - vWeightDict[i][act_group]= pickValB*wA + pickValA*wB - - else: # MODE==1 VCol - for f in me.faces: - if f.sel: - f_v= f.v - for i in xrange(len(f_v)): - v= f_v[i] - wA, wB = grad_weights[v.index] - - c= f.col[i] - - if TOALPHA: - pickValB= c.r, c.g, c.b - - c.r = int(pickValB[0]*wA + pickValA[0]*wB) - c.g = int(pickValB[1]*wA + pickValA[1]*wB) - c.b = int(pickValB[2]*wA + pickValA[2]*wB) - - - - - # Copy weights back to the mesh. - BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) - Window.DrawProgressBar (1.0, '') - - diff --git a/release/scripts/bpymodules/meshtools.py b/release/scripts/bpymodules/meshtools.py deleted file mode 100644 index 274a12ea6da..00000000000 --- a/release/scripts/bpymodules/meshtools.py +++ /dev/null @@ -1,355 +0,0 @@ -# $Id$ -# -# +---------------------------------------------------------+ -# | Copyright (c) 2001 Anthony D'Agostino | -# | http://www.redrival.com/scorpius | -# | scorpius@netzero.com | -# | September 28, 2002 | -# +---------------------------------------------------------+ -# | Common Functions & Global Variables For All IO Modules | -# +---------------------------------------------------------+ - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - -import Blender -import sys - -show_progress = 1 # Set to 0 for faster performance -average_vcols = 1 # Off for per-face, On for per-vertex -overwrite_mesh_name = 0 # Set to 0 to increment object-name version - -blender_version = Blender.Get('version') -blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:] - -try: - import operator -except: - msg = "Error: you need a full Python install to run this script." - meshtools.print_boxed(msg) - Blender.Draw.PupMenu("ERROR%t|"+msg) - -# ================================= -# === Append Faces To Face List === -# ================================= -def append_faces(mesh, faces, facesuv, uvcoords): - for i in xrange(len(faces)): - if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces") - numfaceverts=len(faces[i]) - if numfaceverts == 2: #This is not a face is an edge - if mesh.edges == None: #first run - mesh.addEdgeData() - #rev_face = revert(cur_face) - i1 = faces[i][0] - i2 = faces[i][1] - ee = mesh.addEdge(mesh.verts[i1],mesh.verts[i2]) - ee.flag |= Blender.NMesh.EdgeFlags.EDGEDRAW - ee.flag |= Blender.NMesh.EdgeFlags.EDGERENDER - elif numfaceverts in [3,4]: # This face is a triangle or quad - face = Blender.NMesh.Face() - for j in xrange(numfaceverts): - index = faces[i][j] - face.v.append(mesh.verts[index]) - if len(uvcoords) > 1: - uvidx = facesuv[i][j] - face.uv.append(uvcoords[uvidx]) - face.mode = 0 - face.col = [Blender.NMesh.Col()]*4 - mesh.faces.append(face) - else: # Triangulate n-sided convex polygon. - a, b, c = 0, 1, 2 # Indices of first triangle. - for j in xrange(numfaceverts-2): # Number of triangles in polygon. - face = Blender.NMesh.Face() - face.v.append(mesh.verts[faces[i][a]]) - face.v.append(mesh.verts[faces[i][b]]) - face.v.append(mesh.verts[faces[i][c]]) - b = c; c += 1 - mesh.faces.append(face) - #face.smooth = 1 - -# =================================== -# === Append Verts to Vertex List === -# =================================== -def append_verts(mesh, verts, normals): - #print "Number of normals:", len(normals) - #print "Number of verts :", len(verts) - for i in xrange(len(verts)): - if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts") - x, y, z = verts[i] - mesh.verts.append(Blender.NMesh.Vert(x, y, z)) - if normals: - mesh.verts[i].no[0] = normals[i][0] - mesh.verts[i].no[1] = normals[i][1] - mesh.verts[i].no[2] = normals[i][2] - -# =========================== -# === Create Blender Mesh === -# =========================== -def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]): - if normals: normal_flag = 0 - else: normal_flag = 1 - mesh = Blender.NMesh.GetRaw() - append_verts(mesh, verts, normals) - append_faces(mesh, faces, facesuv, uvcoords) - if not overwrite_mesh_name: - objname = versioned_name(objname) - ob= Blender.NMesh.PutRaw(mesh, objname, normal_flag) # Name the Mesh - ob.name= objname # Name the Object - Blender.Redraw() - -# ============================== -# === Increment Name Version === -# ============================== -def versioned_name(objname): - existing_names = [] - for object in Blender.Object.Get(): - existing_names.append(object.name) - existing_names.append(object.getData(name_only=1)) - if objname in existing_names: # don't over-write other names - try: - name, ext = objname.split('.') - except ValueError: - name, ext = objname, '' - try: - num = int(ext) - root = name - except ValueError: - root = objname - for i in xrange(1, 1000): - objname = "%s.%03d" % (root, i) - if objname not in existing_names: - break - return objname - -# =========================== -# === Print Text In A Box === -# =========================== -def print_boxed(text): - lines = text.splitlines() - maxlinelen = max(map(len, lines)) - if sys.platform[:3] == "win": - print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191) - for line in lines: - print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179) - print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217) - else: - print '+-' + '-'*maxlinelen + '-+' - for line in lines: print '| ' + line.ljust(maxlinelen) + ' |' - print '+-' + '-'*maxlinelen + '-+' - print '\a\r', # beep when done - -# =============================================== -# === Get euler angles from a rotation matrix === -# =============================================== -def mat2euler(mat): - angle_y = -math.asin(mat[0][2]) - c = math.cos(angle_y) - if math.fabs(c) > 0.005: - angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c) - angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c) - else: - angle_x = 0.0 - angle_z = -math.atan2(mat[1][0], mat[1][1]) - return (angle_x, angle_y, angle_z) - -# ========================== -# === Transpose A Matrix === -# ========================== -def transpose(A): - S = len(A) - T = len(A[0]) - B = [[None]*S for i in xrange(T)] - for i in xrange(T): - for j in xrange(S): - B[i][j] = A[j][i] - return B - -# ======================= -# === Apply Transform === -# ======================= -def apply_transform(vertex, matrix): - x, y, z = vertex - xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2] - xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc - ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc - zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc - vertex = [xcomponent, ycomponent, zcomponent] - return vertex - -# ========================= -# === Has Vertex Colors === -# ========================= -def has_vertex_colors(mesh): - # My replacement/workaround for hasVertexColours() - # The docs say: - # "Warning: If a mesh has both vertex colours and textured faces, - # this function will return False. This is due to the way Blender - # deals internally with the vertex colours array (if there are - # textured faces, it is copied to the textured face structure and - # the original array is freed/deleted)." - try: - return mesh.faces[0].col[0] - except: - return 0 - -# =========================== -# === Generate Edge Table === -# =========================== -def generate_edgetable(mesh): - edge_table = {} - numfaces = len(mesh.faces) - - for i in xrange(numfaces): - if not i%100 and show_progress: - Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table") - if len(mesh.faces[i].v) == 4: # Process Quadrilaterals - generate_entry_from_quad(mesh, i, edge_table) - elif len(mesh.faces[i].v) == 3: # Process Triangles - generate_entry_from_tri(mesh, i, edge_table) - else: # Skip This Face - print "Face #", i, "was skipped." - - # === Sort Edge_Table Keys & Add Edge Indices === - i = 0 - keys = edge_table.keys() - keys.sort() - for key in keys: - edge_table[key][6] = i - i += 1 - - # === Replace Tuples With Indices === - for key in keys: - for i in [2,3,4,5]: - if edge_table.has_key(edge_table[key][i]): - edge_table[key][i] = edge_table[edge_table[key][i]][6] - else: - keyrev = (edge_table[key][i][1], edge_table[key][i][0]) - edge_table[key][i] = edge_table[keyrev][6] - - return edge_table - -# ================================ -# === Generate Entry From Quad === -# ================================ -def generate_entry_from_quad(mesh, i, edge_table): - vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v - - if has_vertex_colors(mesh): - vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col - Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0) - Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0) - Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0) - Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0) - - # === verts are upper case, edges are lower case === - A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index - a, b, c, d = (A, B), (B, C), (C, D), (D, A) - - if edge_table.has_key((B, A)): - edge_table[(B, A)][1] = i - edge_table[(B, A)][4] = d - edge_table[(B, A)][5] = b - if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol - else: - if has_vertex_colors(mesh): - edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None] - else: - edge_table[(A, B)] = [i, None, d, b, None, None, None] - - if edge_table.has_key((C, B)): - edge_table[(C, B)][1] = i - edge_table[(C, B)][4] = a - edge_table[(C, B)][5] = c - if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol - else: - if has_vertex_colors(mesh): - edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None] - else: - edge_table[(B, C)] = [i, None, a, c, None, None, None] - - if edge_table.has_key((D, C)): - edge_table[(D, C)][1] = i - edge_table[(D, C)][4] = b - edge_table[(D, C)][5] = d - if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol - else: - if has_vertex_colors(mesh): - edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None] - else: - edge_table[(C, D)] = [i, None, b, d, None, None, None] - - if edge_table.has_key((A, D)): - edge_table[(A, D)][1] = i - edge_table[(A, D)][4] = c - edge_table[(A, D)][5] = a - if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol - else: - if has_vertex_colors(mesh): - edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None] - else: - edge_table[(D, A)] = [i, None, c, a, None, None, None] - -# ==================================== -# === Generate Entry From Triangle === -# ==================================== -def generate_entry_from_tri(mesh, i, edge_table): - vertex3, vertex2, vertex1 = mesh.faces[i].v - - if has_vertex_colors(mesh): - vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col - Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0) - Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0) - Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0) - - # === verts are upper case, edges are lower case === - A, B, C = vertex1.index, vertex2.index, vertex3.index - a, b, c = (A, B), (B, C), (C, A) - - if edge_table.has_key((B, A)): - edge_table[(B, A)][1] = i - edge_table[(B, A)][4] = c - edge_table[(B, A)][5] = b - if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol - else: - if has_vertex_colors(mesh): - edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None] - else: - edge_table[(A, B)] = [i, None, c, b, None, None, None] - - if edge_table.has_key((C, B)): - edge_table[(C, B)][1] = i - edge_table[(C, B)][4] = a - edge_table[(C, B)][5] = c - if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol - else: - if has_vertex_colors(mesh): - edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None] - else: - edge_table[(B, C)] = [i, None, a, c, None, None, None] - - if edge_table.has_key((A, C)): - edge_table[(A, C)][1] = i - edge_table[(A, C)][4] = b - edge_table[(A, C)][5] = a - if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol - else: - if has_vertex_colors(mesh): - edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None] - else: - edge_table[(C, A)] = [i, None, b, a, None, None, None] - diff --git a/release/scripts/bpymodules/paths_ai2obj.py b/release/scripts/bpymodules/paths_ai2obj.py deleted file mode 100644 index 6eb5023a8d4..00000000000 --- a/release/scripts/bpymodules/paths_ai2obj.py +++ /dev/null @@ -1,506 +0,0 @@ -# -*- coding: latin-1 -*- -""" -paths_ai2obj.py -# --------------------------------------------------------------- -Copyright (c) jm soler juillet/novembre 2004-april 2007, -# --------------------------------------------------------------- - released under GNU Licence - for the Blender 2.45 Python Scripts Bundle. -Ce programme est libre, vous pouvez le redistribuer et/ou -le modifier selon les termes de la Licence Publique Générale GNU -publiée par la Free Software Foundation (version 2 ou bien toute -autre version ultérieure choisie par vous). - -Ce programme est distribué car potentiellement utile, mais SANS -AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties -de commercialisation ou d'adaptation dans un but spécifique. -Reportez-vous à la Licence Publique Générale GNU pour plus de détails. - -Vous devez avoir reçu une copie de la Licence Publique Générale GNU -en même temps que ce programme ; si ce n'est pas le cas, écrivez à la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307, États-Unis. - - -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 St, Fifth Floor, Boston, MA 02110-1301 USA -# --------------------------------------------------------------- -#---------------------------------------------- -# -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_ai_en.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#---------------------------------------------- - -#Changelog -#---------------------------------------------- -# 0.1.1 : 2004/08/03, bug in boundingbox reading when Value are negative -# 0.1.2 : 2005/06/12, gmove tranformation properties -# 0.1.3 : 2005/06/25, added a __name__ test to use the script alone -# 0.1.4 : 2005/06/25, closepath improvements -# 0.1.5 : 2005/06/25, ... -# 0.1.6 : 2005/06/26, warning for compacted file - compatibility increased up to AI 10.0 plain text -# 0.1.7 : 2005/06/25, two more closepath improvements -# -# 0.1.8 : 2006/07/03, two more closepath improvements -# 0.1.9 : 2007/05/06, modif on the method that gets the last object on - the list data -# 2008/03/12, Added character encoding line so french text -# does not break python interpreters. - -""" -SHARP_IMPORT=0 -SCALE=1 -NOTHING_TODO=1 -AI_VERSION='' - -GSTACK = [] -GSCALE = [] -GTRANSLATE = [] - -import sys -#oldpath=sys.path -import Blender -BLversion=Blender.Get('version') - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if pathname.find(os.sep)!=-1: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filtreFICHIER(nom): - f=open(nom,'rU') - t=f.readlines() - f.close() - - if len(t)>1 and t[0].find('EPSF')==-1: - return t - else: - name = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1 - result = Blender.Draw.PupMenu(name) - - return 'false' - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez: - def __init__(self): - self.co=[] - self.ha=[0,0] - self.tag='' - -class ITEM: - def __init__(self): - self.type = typBEZIER3D, - self.pntsUV = [0,0] - self.resolUV = [32,0] - self.orderUV = [0,0] - self.flagUV = [0,0] - self.Origine = [0.0,0.0] - self.beziers_knot = [] - -class COURBE: - def __init__(self): - self.magic_number='3DG3' - self.type = objBEZIER - self.number_of_items = 0 - self.ext1_ext2 = [0,0] - self.matrix = """0.0 0.0 1.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 1.0 """ - self.ITEM = {} - -courbes=COURBE() - -PATTERN={} - -BOUNDINGBOX={'rec':[],'coef':1.0} -npat=0 -#===================================================================== -#======== name of the curve in teh courbes dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - - -# modifs 12/06/2005 -#===================================================================== -#====================== current transform ============================ -#===================================================================== -class transform: - def __init__(self,matrix=[1,0,01],x=0.0,y=0.0): - self.matrix=matrix[:] - self.xy=[x,y] - -def G_move(l,a): - global GSCALE, GTRANSLATE, GSTACK - #print GSCALE, GTRANSLATE, GSTACK - return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a]) -# modifs 12/06/2005 - - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic efinition ================================= -#===================================================================== -def test_egalitedespositions(f1,f2): - if f1[0]==f2[0] and f1[1]==f2[1]: - return Blender.TRUE - else: - return Blender.FALSE - - -def Open_GEOfile(dir,nom): - if BLversion>=233: - in_editmode = Blender.Window.EditMode() - if in_editmode: Blender.Window.EditMode(0) - Blender.Load(dir+nom+'OOO.obj', 1) - BO=Blender.Scene.GetCurrent().objects.active - BO.RotY=0.0 - BO.RotX=1.57 - BO.makeDisplayList() - Blender.Window.RedrawAll() - else: - print "Not yet implemented" - -def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX - r=BOUNDINGBOX['rec'] - - if SCALE==1: - SCALE=1.0 - elif SCALE==2: - SCALE=r[2]-r[0] - elif SCALE==3: - SCALE=r[3]-r[1] - - t=[] - t.append(courbes.magic_number+'\n') - t.append(str(courbes.type)+'\n') - t.append(str(courbes.number_of_items)+'\n') - t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n') - t.append(courbes.matrix+'\n') - - for k in courbes.ITEM.keys(): - if len(courbes.ITEM[k].beziers_knot)>1 : - t.append("%s\n"%courbes.ITEM[k].type) - t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1])) - - flag =courbes.ITEM[k].flagUV[0] - - for k2 in range(len(courbes.ITEM[k].beziers_knot)): - #print k2 - k1 =courbes.ITEM[k].beziers_knot[k2] - t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE)) - - t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n') - return t - -def save_GEOfile(dir,nom,t): - f=open(dir+nom+'OOO.obj','w') - f.writelines(t) - f.close() - #warning = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1" - #result = Blender.Draw.PupMenu(warning) - - -#===================================================================== -#===== AI format : DEBUT ========================= -#===================================================================== -def mouvement_vers(l,n0,CP): - if n0 in courbes.ITEM.keys(): - n0+=1 - - CP=[l[-3].replace('d',''),l[-2]] - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]] - - B=Bez() - B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] - B.ha=[0,0] - B.tag=l[-1] - - courbes.ITEM[n0].beziers_knot.append(B) - - return courbes,n0,CP - -def courbe_vers_c(l,l2, n0,CP): #c,C - - B=Bez() - B.co=[l[4],l[5],l[2],l[3],l[4],l[5]] - B.tag=l[-1] - B.ha=[0,0] - - BP=courbes.ITEM[n0].beziers_knot[-1] - - BP.co[0]=l[0] - BP.co[1]=l[1] - - courbes.ITEM[n0].beziers_knot.append(B) - - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - - -def courbe_vers_v(l,n0,CP): #v-V - - B=Bez() - B.tag=l[-1] - B.co=[l[2],l[3],l[0],l[1],l[2],l[3]] - B.ha=[0,0] - - courbes.ITEM[n0].beziers_knot.append(B) - - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - -def courbe_vers_y(l,n0,CP): #y - B=Bez() - B.tag=l[-1] - B.co=[l[2],l[3],l[2],l[3],l[2],l[3]] - B.ha=[0,0] - - BP=courbes.ITEM[n0].beziers_knot[-1] - BP.co[0]=l[0] - BP.co[1]=l[1] - - courbes.ITEM[n0].beziers_knot.append(B) - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - - -def ligne_tracee_l(l,n0,CP): - B=Bez() - B.tag=l[-1] - B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] - B.ha=[0,0] - - BP=courbes.ITEM[n0].beziers_knot[-1] - - courbes.ITEM[n0].beziers_knot.append(B) - CP=[B.co[4],B.co[5]] - return courbes,n0,CP - -def ligne_fermee(l,n0,CP): - courbes.ITEM[n0].flagUV[0]=1 - - if len(courbes.ITEM[n0].beziers_knot)>1: - BP=courbes.ITEM[n0].beziers_knot[-1] - BP0=courbes.ITEM[n0].beziers_knot[0] - - if BP.tag not in ['l','L']: - BP.co[0]=BP0.co[0] #4-5 point prec - BP.co[1]=BP0.co[1] - - del courbes.ITEM[n0].beziers_knot[0] - return courbes,n0,CP - -def passe(l,n0,CP): - return courbes,n0,CP - -Actions= { "C" : courbe_vers_c, - "c" : courbe_vers_c, - "V" : courbe_vers_v, - "v" : courbe_vers_v, - "Y" : courbe_vers_y, - "y" : courbe_vers_y, - "m" : mouvement_vers, - "l" : ligne_tracee_l, - "L" : ligne_tracee_l, - "F" : passe, - "f" : ligne_fermee, - "B" : passe, - "b" : ligne_fermee, - "S" : passe, - "s" : ligne_fermee, - "N" : ligne_fermee, - "n" : passe, - } - -TAGcourbe=Actions.keys() - -def pik_pattern(t,l): - global npat, PATTERN, BOUNDINGBOX, AI_VERSION - while t[l].find('%%EndSetup')!=0: - if t[l].find('%%Creator: Adobe Illustrator(R)')!=-1: - print t[l] - AI_VERSION=t[l].split()[-1] - print AI_VERSION - - if t[l].find('%%BoundingBox:')!=-1: - t[l]=t[l][t[l].find(':')+1:] - l0=t[l].split() - BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0]) - #print l, - if t[l].find('BeginPattern')!=-1: - nomPattern=t[l][t[l].find('(')+1:t[l].find(')')] - PATTERN[nomPattern]={} - - if t[l].find('BeginPatternLayer')!=-1: - npat+=1 - PATTERN[nomPattern][npat]=[] - while t[l].find('EndPatternLayer')==-1: - #print t[l] - PATTERN[nomPattern][npat].append(l) - l+=1 - if l+10: - if len(PATTERN.keys() )>0: - #print len(PATTERN.keys() ) - warning = "Pattern list (for info not used): %t| " - p0=1 - for P in PATTERN.keys(): - warning+="%s %%x%s|"%(P,p0) - p0+=1 - Padd = Blender.Draw.PupMenu(warning) - - t=create_GEOtext(courbes) - save_GEOfile(dir,name[0],t) - - # 0.1.8 --------------------------------- - # [O.select(0) for O in Blender.Scene.getCurrent().getChildren()] - # 0.1.8 --------------------------------- - - Open_GEOfile(dir,name[0]) - - # 0.1.8 --------------------------------- - Blender.Object.Get()[-1].setName(name[0]) - # 0.1.8 --------------------------------- - - else: - pass -#===================================================================== -#====================== AI format mouvements ========================= -#===================================================================== -#========================================================= -# une sorte de contournement qui permet d'utiliser la fonction -# et de documenter les variables Window.FileSelector -#========================================================= -def fonctionSELECT(nom): - global NOTHING_TODO,AI_VERSION - scan_FILE(nom) - if NOTHING_TODO==1: - warning = "AI %s compatible file "%AI_VERSION+" but nothing to do ? %t| Perhaps a compacted file ... " - NOTHING = Blender.Draw.PupMenu(warning) - -if __name__=="__main__": - Blender.Window.FileSelector (fonctionSELECT, 'SELECT AI FILE') -#sys.path=oldpath diff --git a/release/scripts/bpymodules/paths_eps2obj.py b/release/scripts/bpymodules/paths_eps2obj.py deleted file mode 100644 index e1643c3bf40..00000000000 --- a/release/scripts/bpymodules/paths_eps2obj.py +++ /dev/null @@ -1,452 +0,0 @@ -#---------------------------------------------- -# (c) jm soler juillet 2004-juin 2005 , released under Blender Artistic Licence -# for the Blender 2.34-2.37 Python Scripts Bundle. -# -# last update: 06/05/2007 -#---------------------------------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_eps.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#---------------------------------------------- -SHARP_IMPORT = 0 -SCALE = 1.0 -scale = 1 - -import sys -#oldpath=sys.path - -import Blender -from Blender import Draw -BLversion=Blender.Get('version') - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if pathname.find(os.sep)!=-1: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filtreFICHIER(nom): - f=open(nom,'rU') - t=f.readlines() - f.close() - if len(t)==1 and t[0].find('\r'): - t=t[0].split('\r') - if len(t)>1 and t[0].find('PS-Adobe-3.0')==-1 and t[0].find('EPSF')==-1: - return t - else: - name = "OK?%t| Not a valid file or an empty file or... %x1| not a pure PS-Adobe-2.0 file %x2 " - result = Blender.Draw.PupMenu(name) - return 'false' - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez: - def __init__(self): - self.co=[] - self.ha=[0,0] - -class ITEM: - def __init__(self): - self.type = typBEZIER3D, - self.pntsUV = [0,0] - self.resolUV = [32,0] - self.orderUV = [0,0] - self.flagUV = [0,0] - self.Origine = [0.0,0.0] - self.beziers_knot = [] - -class COURBE: - def __init__(self): - self.magic_number='3DG3' - self.type = objBEZIER - self.number_of_items = 0 - self.ext1_ext2 = [0,0] - self.matrix = """0.0 0.0 1.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 1.0 """ #- right-handed object matrix. Used to determine position, rotation and size - self.ITEM = {} - -courbes=COURBE() -PATTERN={} -BOUNDINGBOX={'rec':[],'coef':1.0} -npat=0 -#===================================================================== -#======== name of the curve in teh courbes dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - -# modifs 12/06/2005 -#===================================================================== -#====================== current transform ============================ -#===================================================================== -class transform: - def __init__(self,matrix=[1,0,01],x=0.0,y=0.0): - self.matrix=matrix[:] - self.xy=[x,y] - -GSTACK = [] -stack=transform() -GSTACK.append(stack) - -GSCALE = [1.0,1.0] -GTRANSLATE = [0.0,0.0] - -def G_move(l,a): - global GSCALE, GTRANSLATE, GSTACK - #print GSCALE, GTRANSLATE, GSTACK - return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a]) -# modifs 12/06/2005 - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic efinition ================================= -#===================================================================== -def test_egalitedespositions(f1,f2): - if f1[0]==f2[0] and f1[1]==f2[1]: - return Blender.TRUE - else: - return Blender.FALSE - - -def Open_GEOfile(dir,nom): - global SCALE,BOUNDINGBOX, scale - if BLversion>=233: - Blender.Load(dir+nom+'OOO.obj', 1) - BO=Blender.Scene.GetCurrent().objects.active - BO.RotY=3.1416 - BO.RotZ=3.1416 - BO.RotX=3.1416/2.0 - if scale==1: - BO.LocY+=BOUNDINGBOX['rec'][3] - else: - BO.LocY+=BOUNDINGBOX['rec'][3]/SCALE - - BO.makeDisplayList() - Blender.Window.RedrawAll() - else: - print "Not yet implemented" - -def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX,scale - r=BOUNDINGBOX['rec'] - - if scale==1: - SCALE=1.0 - elif scale==2: - SCALE=r[2]-r[0] - elif scale==3: - SCALE=r[3]-r[1] - - t=[] - t.append(courbes.magic_number+'\n') - t.append(str(courbes.type)+'\n') - t.append(str(courbes.number_of_items)+'\n') - t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n') - t.append(courbes.matrix+'\n') - - for k in courbes.ITEM.keys(): - t.append("%s\n"%courbes.ITEM[k].type) - t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1])) - - flag =courbes.ITEM[k].flagUV[0] - - for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)): - k1 =courbes.ITEM[k].beziers_knot[k2] - t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE)) - t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n') - return t - -def save_GEOfile(dir,nom,t): - f=open(dir+nom+'OOO.obj','w') - f.writelines(t) - f.close() - - #name = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1" - #result = Blender.Draw.PupMenu(name) - - -#===================================================================== -#===== EPS format : DEBUT ========================= -#===================================================================== -def mouvement_vers(l,n0,CP): - if n0 in courbes.ITEM.keys(): - #if test_egalitedespositions(courbes.ITEM[n0].Origine,CP): - # courbes.ITEM[n0].flagUV[0]=1 - n0+=1 - CP=[l[-3].replace('d',''),l[-2]] - else: - CP=[l[-3].replace('d',''),l[-2]] - #i= - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]] - - B=Bez() - B.co=[G_move(CP[0],0), - G_move(CP[1],1), - G_move(CP[0],0), - G_move(CP[1],1), - G_move(CP[0],0), - G_move(CP[1],1)] - - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - - return courbes,n0,CP - -def rmouvement_vers(l,n0,CP): - if n0 in courbes.ITEM.keys(): - #if test_egalitedespositions(courbes.ITEM[n0].Origine,CP): - # courbes.ITEM[n0].flagUV[0]=1 - n0+=1 - CP=["%4f"%(float(l[-3])+float(CP[0])),"%4f"%(float(l[-2])+float(CP[1]))] - else: - CP=["%4f"%(float(l[-3])+float(CP[0])),"%4f"%(float(l[-2])+float(CP[1]))] - #i= - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]] - - B=Bez() - B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - return courbes,n0,CP - -def courbe_vers_c(l, l2, n0,CP): #c,C - """ - B=Bez() - B.co=[l[0],l[1],l[2],l[3],l[4],l[5]] - B.ha=[0,0] - - courbes.ITEM[n0].beziers_knot.append(B) - """ - B=Bez() - B.co=[G_move(l[2],0), - G_move(l[3],1), - G_move(l[4],0), - G_move(l[5],1), - G_move(l[0],0), - G_move(l[1],1)] - if len(courbes.ITEM[n0].beziers_knot)==1: - CP=[l[0],l[1]] - courbes.ITEM[n0].Origine=[l[0],l[1]] - if l[-1]=='C': - B.ha=[2,2] - else: - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - if len(l2)>1 and l2[-1] in Actions.keys(): - B.co[-2]=G_move(l2[0],0) - B.co[-1]=G_move(l2[1],1) - else: - B.co[-2]=G_move(CP[0],0) - B.co[-1]=G_move(CP[1],1) - return courbes,n0,CP - -def ligne_tracee_l(l,n0,CP): - B=Bez() - B.co=[G_move(l[0],0), - G_move(l[1],1), - G_move(l[0],0), - G_move(l[1],1), - G_move(l[0],0), - G_move(l[1],1)] - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return courbes,n0,CP - -def rligne_tracee_l(l,n0,CP): - B=Bez() - B.co=["%4f"%(float(l[0])+float(CP[0])), - "%4f"%(float(l[1])+float(CP[1])), - "%4f"%(float(l[0])+float(CP[0])), - "%4f"%(float(l[1])+float(CP[1])), - "%4f"%(float(l[0])+float(CP[0])), - "%4f"%(float(l[1])+float(CP[1]))] - B.ha=[0,0] - courbes.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return courbes,n0,CP - -Actions= { "curveto" : courbe_vers_c, - "curveto" : courbe_vers_c, - "moveto" : mouvement_vers, - "rmoveto" : mouvement_vers, - "lineto" : ligne_tracee_l, - "rlineto" : rligne_tracee_l -} - -TAGcourbe=Actions.keys() - -""" -def pik_pattern(t,l): - global npat, PATTERN, BOUNDINGBOX - while t[l].find('%%EndSetup')!=0: - if t[l].find('%%BoundingBox:')!=-1: - l0=t[l].split() - BOUNDINGBOX['rec']=[float(l0[-4]),float(l0[-3]),float(l0[-2]),float(l0[-1])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[3]-r[1])/(r[2]-r[0]) - print l, - if t[l].find('BeginPatternLayer')!=-1: - npat+=1 - PATTERN[npat]=[] - while t[l].find('EndPatternLayer')==-1: - print t[l] - PATTERN[npat].append(l) - l+=1 - if l+10: - if len(PATTERN.keys() )>0: - #print len(PATTERN.keys() ) - pass - t=create_GEOtext(courbes) - save_GEOfile(dir,name[0],t) - Open_GEOfile(dir,name[0]) - - # 03 juillet 2006 ---------------------- - Blender.Object.Get()[-1].setName(name[0]) - # 03 juillet 2006 ---------------------- - - else: - pass - - -#===================================================================== -#====================== EPS format mouvements ========================= -#===================================================================== -#========================================================= -# une sorte de contournement qui permet d'utiliser la fonction -# et de documenter les variables Window.FileSelector -#========================================================= -def fonctionSELECT(nom): - scan_FILE(nom) - -if __name__=="__main__": - Blender.Window.FileSelector (fonctionSELECT, 'SELECT EPS FILE') - - diff --git a/release/scripts/bpymodules/paths_gimp2obj.py b/release/scripts/bpymodules/paths_gimp2obj.py deleted file mode 100644 index c2ce9718c71..00000000000 --- a/release/scripts/bpymodules/paths_gimp2obj.py +++ /dev/null @@ -1,363 +0,0 @@ -# -*- coding: latin-1 -*- -""" -#---------------------------------------------- -# (c) jm soler juillet 2004, -#---------------------------------------------- - released under GNU Licence - for the Blender 2.45 Python Scripts Bundle. -Ce programme est libre, vous pouvez le redistribuer et/ou -le modifier selon les termes de la Licence Publique Générale GNU -publiée par la Free Software Foundation (version 2 ou bien toute -autre version ultérieure choisie par vous). - -Ce programme est distribué car potentiellement utile, mais SANS -AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties -de commercialisation ou d'adaptation dans un but spécifique. -Reportez-vous à la Licence Publique Générale GNU pour plus de détails. - -Vous devez avoir reçu une copie de la Licence Publique Générale GNU -en même temps que ce programme ; si ce n'est pas le cas, écrivez à la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307, États-Unis. - - -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 St, Fifth Floor, Boston, MA 02110-1301 USA - -""" - -# --------------------------------------------------------------- -# last update : 07/05/2007 -#---------------------------------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_gimp.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -# Modification History: -# 2008-03-12 Added character encoding line so french text does not break -# python interpreters. -#--------------------------------------------- - -SHARP_IMPORT=0 -SCALE=1 - -import sys -#oldpath=sys.path - -import Blender -BLversion=Blender.Get('version') - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if pathname.find(os.sep)!=-1: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filtreFICHIER(nom): - f=open(nom,'r') - t=f.readlines() - f.close() - if len(t)==1 and t[0].find('\r'): - t=t[0].split('\r') - if len(t)>1 and t[1].find('#POINTS:')==0: - return t - else: - warning = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1 - result = Blender.Draw.PupMenu(warning) - return "false" - -#=============================== -# Data -#=============================== -#=============================== -# Blender Curve Data -#=============================== -objBEZIER=0 -objSURFACE=5 -typBEZIER3D=1 #3D -typBEZIER2D=9 #2D - -class Bez: - def __init__(self): - self.co=[] - self.ha=[0,0] - - def echo(self): - #print 'co = ', self.co - #print 'ha = ', self.ha - pass - -class ITEM: - def __init__(self): - self.type = typBEZIER3D, - self.pntsUV = [0,0] - self.resolUV = [32,0] - self.orderUV = [0,0] - self.flagUV = [0,0] - self.Origine = [0.0,0.0] - self.beziers_knot = [] - -class COURBE: - def __init__(self): - self.magic_number='3DG3' - self.type = objBEZIER - self.number_of_items = 0 - self.ext1_ext2 = [0,0] - self.matrix = """0.0 0.0 1.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 1.0 """ #- right-handed object matrix. Used to determine position, rotation and size - self.ITEM = {} - -courbes=COURBE() -PATTERN={} -BOUNDINGBOX={'rec':[],'coef':1.0} -npat=0 -#===================================================================== -#======== name of the curve in the courbes dictionnary =============== -#===================================================================== -n0=0 - -#===================================================================== -#====================== current Point ================================ -#===================================================================== -CP=[0.0,0.0] #currentPoint - -def MINMAX(b): - global BOUNDINGBOX - r=BOUNDINGBOX['rec'] - for m in range(0,len(b)-2,2): - #print m, m+1 , len(b)-1 - #print b[m], r, r[0] - if float(b[m])r[2]: r[2]=float(b[m]) - - if float(b[m+1])r[3]: r[3]=float(b[m+1]) - -#===================================================================== -#===== to compare last position to the original move to displacement = -#===== needed for cyclic efinition ================================= -#===================================================================== -def test_egalitedespositions(f1,f2): - if f1[0]==f2[0] and f1[1]==f2[1]: - return Blender.TRUE - else: - return Blender.FALSE - - -def Open_GEOfile(dir,nom): - if BLversion>=233: - Blender.Load(dir+nom+'OOO.obj', 1) - BO=Blender.Scene.GetCurrent().objects.active - BO.LocZ=1.0 - BO.makeDisplayList() - Blender.Window.RedrawAll() - else: - print "Not yet implemented" - -def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX - r=BOUNDINGBOX['rec'] - if SCALE==1: - SCALE=1.0 - elif SCALE==2: - SCALE=r[2]-r[0] - elif SCALE==3: - SCALE=r[3]-r[1] - - t=[] - t.append(courbes.magic_number+'\n') - t.append(str(courbes.type)+'\n') - t.append(str(courbes.number_of_items)+'\n') - t.append(str(courbes.ext1_ext2[0])+' '+str(courbes.ext1_ext2[1])+'\n') - t.append(courbes.matrix+'\n') - - for k in courbes.ITEM.keys(): - - t.append("%s\n"%courbes.ITEM[k].type) - - t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1])) - t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1])) - - flag =0#courbes.ITEM[k].flagUV[0] - - for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)): - k1 =courbes.ITEM[k].beziers_knot[k2] - t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE)) - t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE)) - t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n') - return t - -def save_GEOfile(dir,nom,t): - f=open(dir+nom+'OOO.obj','w') - f.writelines(t) - f.close() - #warning = "REMINDER : %t | Do not forget to rename your blender file NOW ! %x1" - #result = Blender.Draw.PupMenu(warning) - - -#===================================================================== -#===== GIMP format : DEBUT ========================= -#===================================================================== -CLOSED=0 - -def mouvement_vers(l,l1,l2,n0): - global BOUNDINGBOX, CP - if l[1] == '3' : - n0+=1 - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3],l[-1],] - courbes.ITEM[n0-1].beziers_knot[0].co[0]=CP[0] - courbes.ITEM[n0-1].beziers_knot[0].co[1]=CP[1] - CP=[l2[-3], l2[-1]] - - elif l[1]=='1' and (n0 not in courbes.ITEM.keys()): - courbes.ITEM[n0]=ITEM() - courbes.ITEM[n0].Origine=[l[-3],l[-1],] - CP=[l2[-3], l2[-1]] - - B=Bez() - B.co=[ CP[0],CP[1], - l1[-3], l1[-1], - l[-3], l[-1]] - - CP=[l2[-3], l2[-1]] - - if BOUNDINGBOX['rec']==[]: - BOUNDINGBOX['rec']=[float(l2[-3]), float(l2[-1]), float(l[-3]), float(l[-1])] - B.ha=[0,0] - - """ - if len( courbes.ITEM[n0].beziers_knot)>=1: - courbes.ITEM[n0].beziers_knot[-1].co[2]=l1[-3] - courbes.ITEM[n0].beziers_knot[-1].co[3]=l1[-1] - """ - - MINMAX(B.co) - courbes.ITEM[n0].beziers_knot.append(B) - return courbes,n0 - -Actions= { "1" : mouvement_vers, - "3" : mouvement_vers } - -TAGcourbe=Actions.keys() - -def scan_FILE(nom): - global CP, courbes, SCALE, MAX, MIN, CLOSED - dir,name=split(nom) - name=name.split('.') - #print name - n0=0 - result=0 - t=filtreFICHIER(nom) - if t!="false": - if not SHARP_IMPORT: - warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3" - SCALE = Blender.Draw.PupMenu(warning) - npat=0 - l=0 - while l 0: - t=create_GEOtext(courbes) - save_GEOfile(dir,name[0],t) - Open_GEOfile(dir,name[0]) - # 0.1.8 --------------------------------- - Blender.Object.Get()[-1].setName(name[0]) - # 0.1.8 --------------------------------- - - else: - pass - -#===================================================================== -#====================== GIMP Path format mouvements ========================= -#===================================================================== -#========================================================= -# une sorte de contournement qui permet d'utiliser la fonction -# et de documenter les variables Window.FileSelector -#========================================================= -def fonctionSELECT(nom): - scan_FILE(nom) - -if __name__=="__main__": - Blender.Window.FileSelector (fonctionSELECT, 'SELECT GIMP FILE') - diff --git a/release/scripts/bpymodules/paths_svg2obj.py b/release/scripts/bpymodules/paths_svg2obj.py deleted file mode 100644 index 6bab6dcbfd8..00000000000 --- a/release/scripts/bpymodules/paths_svg2obj.py +++ /dev/null @@ -1,1651 +0,0 @@ -# -*- coding: latin-1 -*- -""" -SVG 2 OBJ translater, 0.5.9o -Copyright (c) jm soler juillet/novembre 2004-april 2009, -# --------------------------------------------------------------- - released under GNU Licence - for the Blender 2.42 Python Scripts Bundle. -Ce programme est libre, vous pouvez le redistribuer et/ou -le modifier selon les termes de la Licence Publique Générale GNU -publiée par la Free Software Foundation (version 2 ou bien toute -autre version ultérieure choisie par vous). - -Ce programme est distribué car potentiellement utile, mais SANS -AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties -de commercialisation ou d'adaptation dans un but spécifique. -Reportez-vous à la Licence Publique Générale GNU pour plus de détails. - -Vous devez avoir reçu une copie de la Licence Publique Générale GNU -en même temps que ce programme ; si ce n'est pas le cas, écrivez à la -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307, États-Unis. - -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 St, Fifth Floor, Boston, MA 02110-1301 USA -# --------------------------------------------------------------- -# -#--------------------------------------------------------------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg.htm -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg_en.htm -# Communiquer les problemes et erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#--------------------------------------------------------------------------- - ---Old Concept : translate SVG file in GEO .obj file and try to load it. - was removed for the Blender 2.4x release. - .-- Curiousity : the original matrix must be : - | - | 0.0 0.0 1.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 1.0 - | - | and not: - | 1.0 0.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 1.0 - | - '-- Possible bug : sometime, the new curves object's RotY value - jumps to -90.0 degrees without any reason. - ---Options : - SHARP_IMPORT = 0 - choise between "As is", "Devide by height" and "Devide by width" - SHARP_IMPORT = 1 - no choise - - - -All commands are managed: - M : absolute move to - Z : close path - L : absolute line to - C : absolute curve to - S : absolute curve to with only one handle - H : absolute horizontal line to - V : absolute vertical line to - - l : relative line to 2004/08/03 - c : relative curve to 2004/08/03 - s : relative curve to with only one handle - h : relative horizontal line to - v : relative vertical line to - - A : curve_to_a, - V : draw_line_v, - H : draw_line_h, - Z : close_z, - Q : curve_to_q, - T : curve_to_t, - a : curve_to_a, - v : draw_line_v, - h : draw_line_h, - z : close_z, - q : curve_to_q, - - transfrom for tag - transform for tag - -The circle, rectangle closed or open polygons lines are managed too. - -Changelog: - 0.1.1 : - control file without extension - 0.2.0 : - improved reading of several data of the same type - following the same command (for gimp import) - 0.2.1 : - better choice for viewboxing ( takes the viewbox if found, - instead of x,y,width and height - 0.2.2 : - read compact path data from Illustrator 10 - 0.2.3 : - read a few new relative displacements - 0.2.4 : - better hash for command followed by a lone data - (h,v) or uncommun number (a) - 0.2.5 : - correction for gimp import - 0.2.6 : - correction for illustrator 10 SVG - 0.2.7 : - correction for inskape 0.40 cvs SVG - 0.2.8 : - correction for inskape plain SVG - 0.3 : - reading of the transform properties added : - translate - 0.3.1 : - compatibility restored with gimp - 0.3.2 : - transform properties added (june, 15-16): - scale, - rotate, - matrix, - skew - - added a test on __name__ to load the script - outside from the blender menu - 0.3.3 : - matrix transform content control - 0.3.4 : - paths data reading rewritten (19/06/05) - 0.3.5 : - test on empty curve (22/06/05) - - removed overlayed points - 0.3.6 : - rewriting of the bezier point contruction to correct - a problem in the connection between L type point and - C or S type point - 0.3.7 : - code correction for bezier knot in Curveto command when - the command close a path - 0.3.8 : - code was aded to manage quadratic bezier, - Q,q command and T,t commands, as a normal blender's bezier point - - The last modications does not work with gimp 2.0 svg export . - corrected too . - 0.3.9 : - Path's A,a command for ellipse's arc . - 0.4.0 : - To speed up the function filter_DATA was removed and text - variables are changed into numeric variables - 0.4.1 : - svg, groups and shapes hierarchy added - - now transform properties are computed using a stack with all - parented groups - - removed or replaced useless functions : - - skewY, skewX transforms - - radians in rotate transform - 0.4.2 : - Added functon to translate others shapes in path - rect, line, polyline, polygon - 0.4.3 : - various corrections - text font (id property exported by Adobe Illustrator are between coma) - function to code s tag has been rewritten - 0.4.4 : - various corrections - to oblige the script to understand a line feed just after - a tag . Rarely encountered problem, but it exits in a svg file - format exported by a outliner script for mesh . - 0.4.5 : - update for CVS only, at least blender 2.38 and upper - no BezTriple module in older version - added a createCURVES function to avoid to use - the OBJ format export/import . - Perhaps problems with cyclic curves . If a closed curve - does not appear closed in blender, enter edit mode select - all knot with Akey, do a Hkey to set handle type (without - this the knot are recalculated) , and finally use the Ckey - to close the curve . - Should work ... not guaranted . - 0.4.6 : - cyclic flag ... - 0.4.7 : - Management of the svgz files . the complete python or the - gzip.py file is needed . - Little improvement of the curve drawing using the createCURVES - function - 0.4.8 : - short modif for a fantasy font case in the OOo svg format - ('viewbox' is written 'viewBox', for instance) . - Note that (at this time, 2006/05/01, 1OOo exports in svg - but does not read its own export - 0.4.9 : - skipped version : private test - 0.5.0 : - the script worked perfectly with Blender 2.41 but in Blender - 2.42, use the original svg name file + 'OOO.obj' to - write a videoscape file made blender crash under window XP when - the script loaded it . Curiously, use a more simple - name with a sole 'O' solved this problem . - - script returned errors on open path : corrected - - in b2.42, several successive imports seem to be added to - the same original curve . So now the script automaticaly - renames the last group of imported curve with the original - name file . - 0.5.1 : - without join option in the internal curve creation function - 0.5.2 : - the createCURVES() function has been cleanded . Now it works - fine but all bezier curves are joined in the same curve object . - 0.5.3 : - removed two things : - 1/ the ajustement function to increase speed . 35 % faster : - 5690 curves and 30254 points in 11 seconds . User should do - a ctrl-a on the object . - 2/ the import method menu . No reason to choose between the - old extern curve creat and the new intern curve creation - this last one is largely faster . - 0.5.4 : - translation of the functions' name + improvment in the dict lookup . - Quite 15% faster . 9.75 seconds instead of 11 to load the file test . - A test was also added to find the fill style so now the script closes - these curves even if they are not defined as closed in the strict path - commands . - The old non used functions have been completely removed . - 0.5.5 : - Modifs for architect users . - 0.5.6 : - Exec was removed from the collect_ATTRIBUTS function . - Other uses was evaluated. - 0.5.7 : - Wash down of some handle problems. - - 0.5.8 : - 2007/3/9 - Wash down of the last exec and correction of a - problem with the curve's first beztriple handle - which was not recorded at first time . - - Added some units managements - - Correction of the rotate matrix - - Correction of the skew matrix - - change in the wash_DATA function suggested by cambo - - added __slot__ in class Bez, ITEM and CURVE suggested by cambo - - remove unused properties in class ITEM and CURVE - - 0.5.9 : - 2007/3/28 - - many improvements for faster and clearer code suggested by cambo and martin. - replacement of "%s" statement by str function. - - correction of an error in the scale transform management - - correction in the management of the stack transformation that rise an error - under python 2.5 but curiously not with python 2.4 - - 0.5.9a : - 2007/3/29 - - Again a lot of minors corrections - - Backward to 0.5.8 of the function that manages float numbers exported - by the Adobe Illustrator's SVG. After a lot of tests it seems that this oldest - version is also faster too . - - correction (bad) on handle management with V and H commands. - - 0.5.9b : - 2007/3/31 - - one or two minor corrections - - now the new object curve is added in the current layer. - - short modif in the scale menu... - - 0.5.9d : - 2007/4/5 - - when a svg file containts several curves they can be imported in - separate object. - - managment of paths' name when paths are imported as separate curves. - - a menu was added to select between separate or joined curves - - management of colors - - 0.5.9e : - 2007/4/7 - - corrected a scale problem that only appears when one uses beveldepth - - in separate curve option, name is also given to the curve data - - added the list of svg's color names (147) and modified the color's method - to work with. - - 0.5.9h : - 2007/5/2 - - script was updated with the modifs by cambo - - removed all debug statements - - correction of a zero division error in the calc_arc function. - - 0.5.9f: - 2007/15/7 - - Correction de plusieurs bugs sur l'attributions des couleurs et le nommage - des courbes - - 0.5.9i : - ??/??/?? - - Patch externe réalisé sur blender.org project. - - 0.5.9j : - 08/11/2008 - 0.5.9k : - 14/01/2009 - 0.5.9l : - 31/01/2009 - 0.5.9n : - 01/02/2009 - 0.5.9o : - 04/04/2009, remove pattern if it made with path. - - -================================================================================== -==================================================================================""" -SHARP_IMPORT=0 -SCALE=1 -scale_=1 -DEBUG = 0 -DEVELOPPEMENT=0 -TESTCOLOR=0 - -LAST_ID='' -LAST_COLOR=[0.0,0.0,0.0,0.0] -SEPARATE_CURVES=0 -USE_COLORS=0 -PATTERN=0 - -SVGCOLORNAMELIST={ 'aliceblue':[240, 248, 255] ,'antiquewhite':[250, 235, 215] -,'aqua':[ 0, 255, 255], 'aquamarine':[127, 255, 212] -,'azure':[240, 255, 255], 'beige':[245, 245, 220] -,'bisque':[255, 228, 196], 'black':[ 0, 0, 0] -,'blanchedalmond':[255, 235, 205] ,'blue':[ 0, 0, 255] -,'blueviolet':[138, 43, 226],'brown':[165, 42, 42] -,'burlywood':[222, 184, 135],'cadetblue':[ 95, 158, 160] -,'chartreuse':[127, 255, 0] ,'chocolate':[210, 105, 30] -,'coral':[255, 127, 80],'cornflowerblue':[100, 149, 237] -,'cornsilk':[255, 248, 220],'crimson':[220, 20, 60] -,'cyan':[ 0, 255, 255],'darkblue':[ 0, 0, 139] -,'darkcyan':[ 0, 139, 139],'darkgoldenrod':[184, 134, 11] -,'darkgray':[169, 169, 169],'darkgreen':[ 0, 100, 0] -,'darkgrey':[169, 169, 169],'darkkhaki':[189, 183, 107] -,'darkmagenta':[139, 0, 139],'darkolivegreen':[ 85, 107, 47] -,'darkorange':[255, 140, 0],'darkorchid':[153, 50, 204] -,'darkred':[139, 0, 0],'darksalmon':[233, 150, 122] -,'darkseagreen':[143, 188, 143],'darkslateblue':[ 72, 61, 139] -,'darkslategray':[ 47, 79, 79],'darkslategrey':[ 47, 79, 79] -,'darkturquoise':[ 0, 206, 209],'darkviolet':[148, 0, 211] -,'deeppink':[255, 20, 147],'deepskyblue':[ 0, 191, 255] -,'dimgray':[105, 105, 105],'dimgrey':[105, 105, 105] -,'dodgerblue':[ 30, 144, 255],'firebrick':[178, 34, 34] -,'floralwhite':[255, 250, 240],'forestgreen':[ 34, 139, 34] -,'fuchsia':[255, 0, 255],'gainsboro':[220, 220, 220] -,'ghostwhite':[248, 248, 255],'gold':[255, 215, 0] -,'goldenrod':[218, 165, 32],'gray':[128, 128, 128] -,'grey':[128, 128, 128],'green':[ 0, 128, 0] -,'greenyellow':[173, 255, 47],'honeydew':[240, 255, 240] -,'hotpink':[255, 105, 180],'indianred':[205, 92, 92] -,'indigo':[ 75, 0, 130],'ivory':[255, 255, 240] -,'khaki':[240, 230, 140],'lavender':[230, 230, 250] -,'lavenderblush':[255, 240, 245],'lawngreen':[124, 252, 0] -,'lemonchiffon':[255, 250, 205],'lightblue':[173, 216, 230] -,'lightcoral':[240, 128, 128],'lightcyan':[224, 255, 255] -,'lightgoldenrodyellow':[250, 250, 210],'lightgray':[211, 211, 211] -,'lightgreen':[144, 238, 144],'lightgrey':[211, 211, 211] -,'lightpink':[255, 182, 193],'lightsalmon':[255, 160, 122] -,'lightseagreen':[ 32, 178, 170],'lightskyblue':[135, 206, 250] -,'lightslategray':[119, 136, 153],'lightslategrey':[119, 136, 153] -,'lightsteelblue':[176, 196, 222],'lightyellow':[255, 255, 224] -,'lime':[ 0, 255, 0],'limegreen':[ 50, 205, 50] -,'linen':[250, 240, 230],'magenta':[255, 0, 255] -,'maroon':[128, 0, 0],'mediumaquamarine':[102, 205, 170] -,'mediumblue':[ 0, 0, 205],'mediumorchid':[186, 85, 211] -,'mediumpurple':[147, 112, 219],'mediumseagreen':[ 60, 179, 113] -,'mediumslateblue':[123, 104, 238],'mediumspringgreen':[ 0, 250, 154] -,'mediumturquoise':[ 72, 209, 204],'mediumvioletred':[199, 21, 133] -,'midnightblue':[ 25, 25, 112],'mintcream':[245, 255, 250] -,'mistyrose':[255, 228, 225],'moccasin':[255, 228, 181] -,'navajowhite':[255, 222, 173],'navy':[ 0, 0, 128] -,'oldlace':[253, 245, 230],'olive':[128, 128, 0] -,'olivedrab':[107, 142, 35],'orange':[255, 165, 0] -,'orangered':[255, 69, 0],'orchid':[218, 112, 214] -,'palegoldenrod':[238, 232, 170],'palegreen':[152, 251, 152] -,'paleturquoise':[175, 238, 238],'palevioletred':[219, 112, 147] -,'papayawhip':[255, 239, 213],'peachpuff':[255, 218, 185] -,'peru':[205, 133, 63],'pink':[255, 192, 203] -,'plum':[221, 160, 221],'powderblue':[176, 224, 230] -,'purple':[128, 0, 128],'red':[255, 0, 0] -,'rosybrown':[188, 143, 143],'royalblue':[ 65, 105, 225] -,'saddlebrown':[139, 69, 19],'salmon':[250, 128, 114] -,'sandybrown':[244, 164, 96],'seagreen':[ 46, 139, 87] -,'seashell':[255, 245, 238],'sienna':[160, 82, 45] -,'silver':[192, 192, 192],'skyblue':[135, 206, 235] -,'slateblue':[106, 90, 205],'slategray':[112, 128, 144] -,'slategrey':[112, 128, 144],'snow':[255, 250, 250] -,'springgreen':[ 0, 255, 127],'steelblue':[ 70, 130, 180] -,'tan':[210, 180, 140],'teal':[ 0, 128, 128] -,'thistle':[216, 191, 216],'tomato':[255, 99, 71] -,'turquoise':[ 64, 224, 208],'violet':[238, 130, 238] -,'wheat':[245, 222, 179],'white':[255, 255, 255] -,'whitesmoke':[245, 245, 245],'yellow':[255, 255, 0] -,'yellowgreen':[154, 205, 50]} - - -import sys -from math import cos,sin,tan, atan2, pi, ceil -PI=pi -import Blender -from Blender import Mathutils - -try: - import nt - os=nt - os.sep='\\' - -except: - import posix - os=posix - os.sep='/' - -def isdir(path): - try: - st = os.stat(path) - return 1 - except: - return 0 - -def split(pathname): - if os.sep in pathname: - k0=pathname.split(os.sep) - else: - if os.sep=='/': - k0=pathname.split('\\') - else: - k0=pathname.split('/') - directory=pathname.replace(k0[len(k0)-1],'') - Name=k0[len(k0)-1] - return directory, Name - -def join(l0,l1): - return l0+os.sep+l1 - -os.isdir=isdir -os.split=split -os.join=join - -def filterFILE(nom): - """ - Function filterFILE - - in : string nom , filename - out : string t , if correct filecontaint - - read the file's content and try to see if the format - is correct . - - Lit le contenu du fichier et en fait une pre-analyse - pour savoir s'il merite d'etre traite . - """ - # ---------- - # 0.4.7 - # ---------- - if nom.upper().endswith('.SVGZ'): - try : - import gzip - tz=gzip.GzipFile(nom) - t=tz.read() - except: - name = "ERROR: fail to import gzip module or gzip error ... " - result = Blender.Draw.PupMenu(name) - return "false" - else: - f=open(nom,'rU') - t=f.read() - f.close() - # ---------- - # 0.4.7 : end - # ---------- - # ----------------- - # pre-format ... - # ----------------- - # -------------------- - # 0.4.4 '\r','' --> '\r',' ' - # '\n','' --> '\n',' ' - #-------------------- - t=t.replace('\r',' ') - t=t.replace('\n',' ') - t=t.replace('svg:','') - #-------------------- - # may be needed in some import case when the - # file is saved from a mozilla display - #-------------------- - t=t.replace(chr(0),'') - if not '= 0.0\ - and abs(f1[5])-abs(f2[5])< EPSILON and abs(f1[5])-abs(f2[5])>= 0.0 : - return 1 - else: - return 0 - - -#-------------------- -# 0.4.5 : for blender cvs 2.38 .... -#-------------------- -def createCURVES(curves, name): - """ - internal curves creation - """ - global SCALE, B, BOUNDINGBOX,scale_, SEPARATE_CURVES - global USE_COLORS - from Blender import Curve, Object, Scene, BezTriple - HANDLE={'C':BezTriple.HandleTypes.FREE,'L':BezTriple.HandleTypes.VECT} - r=BOUNDINGBOX['rec'] - - if scale_==3: - SCALE=1.0 - elif scale_==1: - SCALE=r[2]-r[0] - elif scale_==2: - SCALE=r[3]-r[1] - - scene = Scene.GetCurrent() - scene.objects.selected = [] - - if not SEPARATE_CURVES: - c = Curve.New() - c.setResolu(24) - - MATNAME=[] - nloc=0.0 - - def new_MATERIAL(val): - # ----------------------- - # have to create a material - #------------------------ - if val.matname and val.matname in MATNAME: - mat = Blender.Material.Get(val.matname) - elif val.matname: - mat = Blender.Material.New(val.matname) - mat.rgbCol = [val.color[0]/255.0, val.color[1]/255.0, val.color[2]/255.0] - else: - mat = Blender.Material.New(val.id) - mat.rgbCol = [val.color[0]/255.0, val.color[1]/255.0, val.color[2]/255.0] - return [mat] - - for I,val in curves.ITEM.iteritems(): - if SEPARATE_CURVES: - c = Curve.New() - c.setResolu(24) - if USE_COLORS and val.mat: - c.materials=new_MATERIAL(val) - - bzn=0 - if val.beziers_knot[-1].tag in ['L','l','V','v','H','h'] and\ - test_samelocations(val.beziers_knot[-1].co,val.beziers_knot[0].co): - del val.beziers_knot[-1] - - for k2 in xrange(0,len(val.beziers_knot)): - bz= [co for co in val.beziers_knot[k2].co] - if bzn==0: - cp1 = bz[4]/SCALE, bz[5]/-SCALE,0.0, bz[0]/SCALE, bz[1]/-SCALE,0.0, bz[2]/SCALE,bz[3]/-SCALE,0.0, - beztriple1 = BezTriple.New(cp1) - bez = c.appendNurb(beztriple1) - bez[0].handleTypes=(HANDLE[val.beziers_knot[k2].ha[0]],HANDLE[val.beziers_knot[k2].ha[1]]) - bzn = 1 - else: - cp2 = bz[4]/SCALE,bz[5]/-SCALE,0.0 , bz[0]/SCALE, bz[1]/-SCALE,0.0, bz[2]/SCALE,bz[3]/-SCALE,0.0 - beztriple2 = BezTriple.New(cp2) - beztriple2.handleTypes= (HANDLE[val.beziers_knot[k2].ha[0]],HANDLE[val.beziers_knot[k2].ha[1]]) - bez.append(beztriple2) - - if val.flagUV[0]==1 or val.fill==1: - #-------------------- - # 0.4.6 : cyclic flag ... - #-------------------- - bez.flagU += 1 - - if SEPARATE_CURVES: - ob = scene.objects.new(c,val.id) - scene.objects.active = ob - ob.setLocation(0.0,0.0,nloc) - nloc+=0.0001 - c.update() - - if not SEPARATE_CURVES: - ob = scene.objects.new(c,name) - scene.objects.active = ob - c.update() - -#===================================================================== -#===== SVG format : DEBUT ========================= -#===================================================================== -#-------------------- -# 0.5.8, needed with the new -# tranform evaluation -#-------------------- -pxUNIT={'pt':1.25, - 'pc':15.0, - 'mm':3.543307, - 'cm':35.43307, - 'in':90.0, - 'em':1.0, # should be taken from font size - # but not currently managed - 'ex':1.0, # should be taken from font size - # but not currently managed - '%':1.0, - } - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def rect(prp): - """ - build rectangle paths - """ - D=[] - if 'x' not in prp: x=0.0 - else : x=float(prp['x']) - if 'y' not in prp: y=0.0 - else : y=float(prp['y']) - #-------------------- - # 0.5.8 - #-------------------- - try: - height=float(prp['height']) - except: - pxUNIT['%']=(BOUNDINGBOX['rec'][3]-BOUNDINGBOX['rec'][1])/100.0 - for key in pxUNIT:#.keys(): - if key in prp['height']: - height=float(prp['height'].replace(key,''))*pxUNIT[key] - try: - width=float(prp['width']) - except: - pxUNIT['%']=(BOUNDINGBOX['rec'][2]-BOUNDINGBOX['rec'][0])/100.0 - for key in pxUNIT:#.keys(): - if key in prp['width']: - width=float(prp['width'].replace(key,''))*pxUNIT[key] - #-------------------- - # 0.5.8, end - #-------------------- - """ - normal rect - x,y - h1 - *----------* - | | - | | - | | - *----------* v1 - h2 - """ - if 'rx' not in prp or 'rx' not in prp: - D=['M',str(x),str(y),'h',str(width),'v',str(height),'h',str(-width),'z'] - else : - rx=float(prp['rx']) - if 'ry' not in prp : - ry=float(prp['rx']) - else : ry=float(prp['ry']) - if 'rx' in prp and prp['rx']<0.0: rx*=-1 - if 'ry' in prp and prp['ry']<0.0: ry*=-1 - """ - rounded corner - - x,y M h1 - ---*----------* - / \ - / \ - v2 * * c1 - | | - | | - | | - c3 * * v2 - \ / - \ / - *----------* - h2 c2 - """ - - D=['M',str(x+rx),str(y), - 'h',str(width-2*rx), - 'c',str(rx),'0.0',str(rx),str(ry),str(rx),str(ry), - 'v',str(height-ry), - 'c','0.0',str(ry),str(-rx),str(ry),str(-rx),str(ry), - 'h',str(-width+2*rx), - 'c',str(-rx),'0.0',str(-rx),str(-ry),str(-rx),str(-ry), - 'v',str(-height+ry), - 'c','0.0','0.0','0.0',str(-ry),str(rx),str(-ry), - 'z'] - - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def circle(prp): - if 'cx' not in prp: cx=0.0 - else : cx =float(prp['cx']) - if 'cy' not in prp: cy=0.0 - else : cy =float(prp['cy']) - r = float(prp['r']) - D=['M',str(cx),str(cy+r), - 'C',str(cx-r), str(cy+r*0.552),str(cx-0.552*r),str(cy+r), str(cx),str(cy+r), - 'C',str(cx+r*0.552), str(cy+r), str(cx+r), str(cy+r*0.552), str(cx+r),str(cy), - 'C',str(cx+r), str(cy-r*0.552),str(cx+r*0.552),str(cy-r),str(cx), str(cy-r), - 'C',str(cx-r*0.552), str(cy-r), str(cx-r), str(cy-r*0.552),str(cx-r),str(cy), - 'Z'] - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def ellipse(prp): - if 'cx' not in prp: cx=0.0 - else : cx =float(prp['cx']) - if 'cy' not in prp: cy=0.0 - else : cy =float(prp['cy']) - ry = float(prp['rx']) - rx = float(prp['ry']) - D=['M',str(cx),str(cy+rx), - 'C',str(cx-ry),str(cy+rx*0.552),str(cx-0.552*ry),str(cy+rx),str(cx),str(cy+rx), - 'C',str(cx+ry*0.552),str(cy+rx),str(cx+ry),str(cy+rx*0.552),str(cx+ry),str(cy), - 'C',str(cx+ry),str(cy-rx*0.552),str(cx+ry*0.552),str(cy-rx),str(cx),str(cy-rx), - 'C',str(cx-ry*0.552),str(cy-rx),str(cx-ry),str(cy-rx*0.552),str(cx-ry),str(cy), - 'z'] - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def line(prp): - D=['M',str(prp['x1']),str(prp['y1']), - 'L',str(prp['x2']),str(prp['y2'])] - return D - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def polyline(prp): - if 'points' in prp: - points=prp['points'].split(' ') - np=0 - for p in points: - if p!='': - p=p.split(',') - if np==0: - D=['M',str(p[0]),str(p[1])] - np+=1 - else: - D.append('L'); D.append(str(p[0])); D.append(str(p[1])) - return D - else: - return [] - -#-------------------- -# 0.4.2 -# 0.5.8, to remove exec -#-------------------- -def polygon(prp): - D=polyline(prp) - if D!=[]: - D.append('Z') - return D - - -#-------------------- -# 0.5.8, to remove exec -#-------------------- -OTHERSSHAPES={ 'rect' : rect, - 'line' : line, - 'polyline': polyline, - 'polygon' : polygon, - 'circle' : circle, - 'ellipse' : ellipse} - -#-------------------- -# 0.3.9 -#-------------------- -def calc_arc (cpx,cpy, rx, ry, ang, fa , fs , x, y) : - """ - Calc arc paths - """ - rx=abs(rx) - ry=abs(ry) - px=abs((cos(ang)*(cpx-x)+sin(ang)*(cpy-y))*0.5)**2.0 - py=abs((cos(ang)*(cpy-y)-sin(ang)*(cpx-x))*0.5)**2.0 - rpx=rpy=0.0 - if abs(rx)>0.0: rpx=px/(rx**2.0) - if abs(ry)>0.0: rpy=py/(ry**2.0) - pl=rpx+rpy - if pl>1.0: - pl=pl**0.5;rx*=pl;ry*=pl - carx=sarx=cary=sary=0.0 - if abs(rx)>0.0: - carx=cos(ang)/rx;sarx=sin(ang)/rx - if abs(ry)>0.0: - cary=cos(ang)/ry;sary=sin(ang)/ry - x0=(carx)*cpx+(sarx)*cpy - y0=(-sary)*cpx+(cary)*cpy - x1=(carx)*x+(sarx)*y - y1=(-sary)*x+(cary)*y - d=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0) - if abs(d)>0.0 :sq=1.0/d-0.25 - else: sq=-0.25 - if sq<0.0 :sq=0.0 - sf=sq**0.5 - if fs==fa :sf=-sf - xc=0.5*(x0+x1)-sf*(y1-y0) - yc=0.5*(y0+y1)+sf*(x1-x0) - ang_0=atan2(y0-yc,x0-xc) - ang_1=atan2(y1-yc,x1-xc) - ang_arc=ang_1-ang_0; - if (ang_arc < 0.0 and fs==1) : - ang_arc += 2.0 * PI - elif (ang_arc>0.0 and fs==0) : - ang_arc-=2.0*PI - n_segs=int(ceil(abs(ang_arc*2.0/(PI*0.5+0.001)))) - P=[] - for i in xrange(n_segs): - ang0=ang_0+i*ang_arc/n_segs - ang1=ang_0+(i+1)*ang_arc/n_segs - ang_demi=0.25*(ang1-ang0) - t=2.66666*sin(ang_demi)*sin(ang_demi)/sin(ang_demi*2.0) - x1=xc+cos(ang0)-t*sin(ang0) - y1=yc+sin(ang0)+t*cos(ang0) - x2=xc+cos(ang1) - y2=yc+sin(ang1) - x3=x2+t*sin(ang1) - y3=y2-t*cos(ang1) - P.append([[(cos(ang)*rx)*x1+(-sin(ang)*ry)*y1, - (sin(ang)*rx)*x1+(cos(ang)*ry)*y1], - [(cos(ang)*rx)*x3+(-sin(ang)*ry)*y3, - (sin(ang)*rx)*x3+(cos(ang)*ry)*y3], - [(cos(ang)*rx)*x2+(-sin(ang)*ry)*y2, - (sin(ang)*rx)*x2+(cos(ang)*ry)*y2]]) - return P - -#-------------------- -# 0.3.9 -#-------------------- -def curve_to_a(curves, c,D,n0,CP): #A,a - global SCALE - l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]), - int(D[c[1]+4]),int(D[c[1]+5]),float(D[c[1]+6]),float(D[c[1]+7])] - if c[0]=='a': - l[5]=l[5] + CP[0] - l[6]=l[6] + CP[1] - B=Bez() - B.co=[ CP[0], CP[1], CP[0], CP[1], CP[0], CP[1] ] - B.ha=['C','C'] - B.tag=c[0] - POINTS= calc_arc (CP[0],CP[1], - l[0], l[1], l[2]*(PI / 180.0), - l[3], l[4], - l[5], l[6] ) - for p in POINTS : - B=Bez() - B.co=[ p[2][0],p[2][1], p[0][0],p[0][1], p[1][0],p[1][1]] - B.ha=['C','C'] - B.tag='C' - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=B.co[2] - BP.co[3]=B.co[3] - curves.ITEM[n0].beziers_knot.append(B) - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=BP.co[0] - BP.co[3]=BP.co[1] - CP=[l[5], l[6]] - #---------- 059m------------ - if len(D)>c[1]+7 and D[c[1]+8] not in TAGcourbe : - c[1]+=7 - curves,n0,CP=curve_to_a(curves, c, D, n0,CP) - #---------- 059m------------ - return curves,n0,CP - -def move_to(curves, c, D, n0,CP, proprietes): - global DEBUG,TAGcourbe, LAST_ID - global USE_COLORS - - l=[float(D[c[1]+1]),float(D[c[1]+2])] - - if c[0]=='m': - l=[l[0]+CP[0], - l[1] + CP[1]] - - if n0 in curves.ITEM: - n0+=1 - CP=[l[0],l[1]] - curves.ITEM[n0]=ITEM() - - if 'id' in proprietes: - curves.ITEM[n0].id=proprietes['id'] - else: - curves.ITEM[n0].id=LAST_ID - - proprietes['n'].append(n0) - if USE_COLORS: - pr= proprietes.get('fill') # None or the property - if pr != None: - if '#' in pr: - i=1 - curves.ITEM[n0].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)] - curves.ITEM[n0].mat=1 - elif pr in SVGCOLORNAMELIST: - Courbe[n].color=SVGCOLORNAMELIST[pr] - Courbe[n].mat=1 - - B=Bez() - B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] - B.ha=['L','C'] - B.tag=c[0] - curves.ITEM[n0].beziers_knot.append(B) - return curves,n0,CP - -def close_z(curves, c,D,n0,CP): #Z,z - curves.ITEM[n0].flagUV[0]=1 - if len(curves.ITEM[n0].beziers_knot)>1: - BP=curves.ITEM[n0].beziers_knot[-1] - BP0=curves.ITEM[n0].beziers_knot[0] - if BP.tag in ['c','C','s','S',]: - BP.co[2]=BP0.co[2] #4-5 point prec - BP.co[3]=BP0.co[3] - del curves.ITEM[n0].beziers_knot[0] - else: - del curves.ITEM[n0] - n0-=1 - return curves,n0,CP - -def curve_to_q(curves, c,D,n0,CP): #Q,q - l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),float(D[c[1]+4])] - if c[0]=='q': - l=[l[0]+CP[0], l[1]+CP[1], l[2]+CP[0], l[3]+CP[1]] - B=Bez() - B.co=[l[2], l[3], l[2], l[3], l[0], l[1]] #plus toucher au 2-3 - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=BP.co[0] - BP.co[3]=BP.co[1] - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[2],l[3]] - #if DEBUG==1: pass - if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe : - c[1]+=4 - curves,n0,CP=curve_to_q(curves, c, D, n0,CP) - return curves,n0,CP - -def curve_to_t(curves, c,D,n0,CP): #T,t - l=[float(D[c[1]+1]),float(D[c[1]+2])] - if c[0]=='t': - l=[l[0]+CP[0], l[1]+CP[1]] - B=Bez() - B.co=[l[0], l[1], l[0], l[1], l[0], l[1]] #plus toucher au 2-3 - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - l0=build_SYMETRIC([BP.co[0],BP.co[1],BP.co[4],BP.co[5]]) - if BP.tag in ['q','Q','t','T','m','M']: - BP.co[2]=l0[2] - BP.co[3]=l0[3] - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe : - c[1]+=4 - curves,n0,CP=curve_to_t(curves, c, D, n0,CP) - return curves,n0,CP - -#-------------------- -# 0.4.3 : rewritten -#-------------------- -def build_SYMETRIC(l): - X=l[2]-(l[0]-l[2]) - Y=l[3]-(l[1]-l[3]) - return X,Y - -def curve_to_s(curves, c,D,n0,CP): #S,s - l=[float(D[c[1]+1]), - float(D[c[1]+2]), - float(D[c[1]+3]), - float(D[c[1]+4])] - if c[0]=='s': - l=[l[0]+CP[0], l[1]+CP[1], - l[2]+CP[0], l[3]+CP[1]] - B=Bez() - B.co=[l[2],l[3],l[2],l[3],l[0],l[1]] #plus toucher au 2-3 - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - #-------------------- - # 0.4.3 - #-------------------- - BP.co[2],BP.co[3]=build_SYMETRIC([BP.co[4],BP.co[5],BP.co[0],BP.co[1]]) - curves.ITEM[n0].beziers_knot.append(B) - #-------------------- - # 0.4.3 - #-------------------- - CP=[l[2],l[3]] - if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe : - c[1]+=4 - curves,n0,CP=curve_to_c(curves, c, D, n0,CP) - return curves,n0,CP - -def curve_to_c(curves, c, D, n0,CP): #c,C - l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]), - float(D[c[1]+4]),float(D[c[1]+5]),float(D[c[1]+6])] - if c[0]=='c': - l=[l[0]+CP[0], - l[1]+CP[1], - l[2]+CP[0], - l[3]+CP[1], - l[4]+CP[0], - l[5]+CP[1]] - B=Bez() - B.co=[l[4], - l[5], - l[4], - l[5], - l[2], - l[3]] #plus toucher au 2-3 - - - B.ha=['C','C'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - BP.co[2]=l[0] - BP.co[3]=l[1] - BP.ha[1]='C' - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[4],l[5]] - if len(D)>c[1]+7 and D[c[1]+7] not in TAGcourbe : - c[1]+=6 - curves,n0,CP=curve_to_c(curves, c, D, n0,CP) - return curves,n0,CP - -def draw_line_l(curves, c, D, n0,CP): #L,l - - l=[float(D[c[1]+1]),float(D[c[1]+2])] - if c[0]=='l': - l=[l[0]+CP[0], - l[1]+CP[1]] - B=Bez() - B.co=[l[0],l[1], - l[0],l[1], - l[0],l[1]] - - B.ha=['L','L'] - B.tag=c[0] - BP=curves.ITEM[n0].beziers_knot[-1] - BP.ha[1]='L' - - curves.ITEM[n0].beziers_knot.append(B) - CP=[B.co[4],B.co[5]] - - if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe : - c[1]+=2 - curves,n0,CP=draw_line_l(curves, c, D, n0,CP) #L - - return curves,n0,CP - -def draw_line_h(curves, c,D,n0,CP): #H,h - if c[0]=='h': - l=[float(D[c[1]+1])+float(CP[0]),CP[1]] - else: - l=[float(D[c[1]+1]),CP[1]] - B=Bez() - B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] - B.ha=['L','L'] - B.tag=c[0] - #BP=curves.ITEM[n0].beziers_knot[-1] - #BP.ha[0]='L' - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return curves,n0,CP - -def draw_line_v(curves, c,D,n0,CP): #V, v - if c[0]=='v': - l=[CP[0], float(D[c[1]+1])+CP[1]] - else: - l=[CP[0], float(D[c[1]+1])] - - B=Bez() - B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] - B.ha=['L','L'] - B.tag=c[0] - #BP=curves.ITEM[n0].beziers_knot[-1] - #BP.ha[0]='L' - curves.ITEM[n0].beziers_knot.append(B) - CP=[l[0],l[1]] - return curves,n0,CP - -Actions= { "C" : curve_to_c, - "A" : curve_to_a, - "S" : curve_to_s, - "M" : move_to, - "V" : draw_line_v, - "L" : draw_line_l, - "H" : draw_line_h, - "Z" : close_z, - "Q" : curve_to_q, - "T" : curve_to_t, - - "c" : curve_to_c, - "a" : curve_to_a, - "s" : curve_to_s, - "m" : move_to, - "v" : draw_line_v, - "l" : draw_line_l, - "h" : draw_line_h, - "z" : close_z, - "q" : curve_to_q, - "T" : curve_to_t -} - -TAGcourbe=Actions.keys() -TAGtransform=['M','L','C','S','H','V','T','Q'] -tagTRANSFORM=0 - -def wash_DATA(ndata): - if ndata: - ndata = ndata.strip() - - if ndata[0]==',':ndata=ndata[1:] - if ndata[-1]==',':ndata=ndata[:-1] - - #-------------------- - # 0.4.0 : 'e' - #-------------------- - ni=0 - i = ndata.find('-',ni) - if i != -1: - while i>-1 : - i = ndata.find('-',ni) - # 059l ------ - if i>0 : - if ndata[i-1] not in [' ',',','e']: - ndata=ndata[:i]+','+ndata[i:] - ni=i+2 - else: - ni=i+1 - elif i>-1: - ni=1 - # 059l ------ - - ndata=ndata.replace(',,',',') - ndata=ndata.replace(' ',',') - ndata=ndata.split(',') - ndata=[i for i in ndata if i] #059a - - return ndata - -#-------------------- -# 0.3.4 : - read data rewrittten -#-------------------- -def list_DATA(DATA): - """ - This function translate a text in a list of - correct commandswith the right number of waited - values for each of them . For example : - d="'M0,14.0 z" becomes ['M','0.0','14.0','z'] - """ - # ---------------------------------------- - # borner les differents segments qui devront etre - # traites - # pour cela construire une liste avec chaque - # position de chaque emplacement tag de type - # commande path... - # ---------------------------------------- - tagplace=[] - for d in Actions: - b1=0 - while True: - i = DATA.find(d,b1) - if i==-1: break - tagplace.append(i) - b1=i+1 - #------------------------------------------ - # cette liste doit etre traites dans l'ordre - # d'apparition des tags - #------------------------------------------ - tagplace.sort() - - tpn=range(len(tagplace)) - - - #-------------------- - # 0.3.5 :: short data, only one tag - #-------------------- - if len(tagplace)-1>0: - DATA2=[] - for t in tpn[:-1]: - DATA2.append(DATA[tagplace[t]:tagplace[t]+1]) - ndata=DATA[tagplace[t]+1:tagplace[t+1]] - - if DATA2[-1] not in ['z','Z'] : - ndata=wash_DATA(ndata) - DATA2.extend(ndata) - - DATA2.append(DATA[tagplace[t+1]:tagplace[t+1]+1]) - - if DATA2[-1] not in ['z','Z'] and len(DATA)-1>=tagplace[t+1]+1: - ndata=DATA[tagplace[t+1]+1:] - ndata=wash_DATA(ndata) - DATA2.extend(ndata) #059a - - else: - #-------------------- - # 0.3.5 : short data,only one tag - #-------------------- - DATA2=[] - DATA2.append(DATA[tagplace[0]:tagplace[0]+1]) - ndata=DATA[tagplace[0]+1:] - ndata=wash_DATA(ndata) - DATA2.extend(ndata) - return DATA2 - -#---------------------------------------------- -# 0.3 -# 0.5.8, to remove exec -#---------------------------------------------- -def translate(t): - tx=t[0] - ty=t[1] - return [1, 0, tx], [0, 1, ty],[0,0,1] - -#---------------------------------------------- -# 0.3.2 -# 0.5.8, to remove exec -#---------------------------------------------- -def scale(s): - sx=s[0] - if len(s)>1: sy=s[1] - else: sy=sx - return [sx, 0, 0], [0, sy, 0],[0,0,1] - -#---------------------------------------------- -# 0.4.1 : transslate a in radians -# 0.5.8, to remove exec -#---------------------------------------------- -def rotate(t): - a=t[0] - return [cos(a*3.1416/180.0), -sin(a*3.1416/180.0), 0], [sin(a*3.1416/180.0), cos(a*3.1416/180.0),0],[0,0,1] - -#---------------------------------------------- -# 0.3.2 -# 0.5.8, to remove exec -#---------------------------------------------- -def skewx(t): - a=t[0] - return [1, tan(a*3.1416/180.0), 0], [0, 1, 0],[0,0,1] - -#---------------------------------------------- -# 0.4.1 -# 0.5.8, to remove exec -#---------------------------------------------- -def skewy(t): - a=t[0] - return [1, 0, 0], [tan(a*3.1416/180.0), 1 , 0],[0,0,1] - -#---------------------------------------------- -# 0.3.2 -# 0.5.8, to remove exec -#---------------------------------------------- -def matrix(t): - a,b,c,d,e,f=t - return [a,c,e],[b,d,f],[0,0,1] - -#-------------------- -# 0.5.8, to remove exec -#-------------------- -matrixTRANSFORM={ 'translate':translate, - 'scale':scale, - 'rotate':rotate, - 'skewx':skewx, - 'skewy':skewy, - 'matrix':matrix - } - -#---------------------------------------------- -# 0.4.2 : rewritten -# 0.5.8 : to remove exec uses. -#---------------------------------------------- -def control_CONTAINT(txt): - """ - the transforms' descriptions can be sole or several - and separators might be forgotten - """ - t0=0 - tlist=[] - while txt.count(')',t0)>0: - t1=txt.find(')',t0) - nt0=txt[t0:t1+1] - t2=nt0[nt0.find('(')+1:-1] - val=nt0[:nt0.find('(')] - - while t2.find(' ')!=-1: - t2=t2.replace(' ',' ') - while t2.find(', ')!=-1: #059l - t2=t2.replace(', ',',') #059l - - t2=t2.replace(' ',',') - t2=[float(t) for t in t2.split(',')] - - if val=='rotate' : - t3=t2 - if len(t3)==3: - tlist.append(['translate',[t3[1],t3[2]]]) - tlist.append(['rotate',[t3[0]/180.0*3.1416]]) - tlist.append(['translate',[-t3[1],-t3[2]]]) - else: - tlist.append(['rotate',[t3[0]]]) - else: - tlist.append([val,t2]) - t0=t1+1 - return tlist - - -def curve_FILL(Courbe,proprietes): - global USE_COLORS - for n in proprietes['n']: - pr = proprietes['style'] - if n in Courbe and 'fill:' in pr: - if not 'fill:none' in pr: - Courbe[n].fill=1 - if USE_COLORS: - i= pr.find('fill:#') - if i != -1: - i= i+6 - Courbe[n].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)] - Courbe[n].mat=1 - elif ';fill-opacity' in pr: - if pr.find('fill:url')==-1: - i= pr.find('fill:')+5 - i2= pr.find(';',i) - COLORNAME= pr[i:i2] - Courbe[n].color=SVGCOLORNAMELIST[COLORNAME] - Courbe[n].mat=1 - elif 'color:' in pr: - i= pr.find('color:')+6 - i2= pr.find(';',i) - COLORNAME= pr[i:i2] - Courbe[n].color=SVGCOLORNAMELIST[COLORNAME] - Courbe[n].mat=1 - else : - COLORNAME= 'white' - Courbe[n].color=SVGCOLORNAMELIST[COLORNAME] - Courbe[n].mat=1 - -#---------------------------------------------- -# 0.4.1 : apply transform stack -#---------------------------------------------- -def curve_TRANSFORM(Courbe,proprietes): - # 1/ unpack the STACK - # create a matrix for each transform - ST=[] - for st in proprietes['stack'] : - if st and type(st)==list: - for t in st: - code = control_CONTAINT(t) - a,b,c=matrixTRANSFORM[code[0][0]](code[0][1][:]) - T=Mathutils.Matrix(a,b,c) - ST.append(T) - elif st : - code = control_CONTAINT(st) - a,b,c=matrixTRANSFORM[code[0][0]](code[0][1][:]) - T=Mathutils.Matrix(a,b,c) - ST.append(T) - if 'transform' in proprietes: - for trans in control_CONTAINT(proprietes['transform']): - #-------------------- - # 0.5.8, to remove exec - #-------------------- - a,b,c=matrixTRANSFORM[trans[0].strip()](trans[1][:]) #059 - T=Mathutils.Matrix(a,b,c) - ST.append(T) - ST.reverse() - for n in proprietes['n']: - if n in Courbe: - for bez0 in Courbe[n].beziers_knot: - bez=bez0.co - for b in [0,2,4]: - for t in ST: - v=t * Mathutils.Vector([bez[b],bez[b+1],1.0]) #059a - bez[b]=v[0] - bez[b+1]=v[1] - -def filter(d): - for nn in d: - if nn not in '0123456789.': #059a - d=d.replace(nn,"") - return d - -def get_BOUNDBOX(BOUNDINGBOX,SVG): - if 'viewbox' not in SVG: - h=float(filter(SVG['height'])) - - w=float(filter(SVG['width'])) - BOUNDINGBOX['rec']=[0.0,0.0,w,h] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=w/h - else: - viewbox=SVG['viewbox'].split() - BOUNDINGBOX['rec']=[float(viewbox[0]),float(viewbox[1]),float(viewbox[2]),float(viewbox[3])] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=(r[2]-r[0])/(r[3]-r[1]) - return BOUNDINGBOX - -#---------------------------------------------- -# 0.4.1 : attributs ex : 'id=', 'transform=', 'd=' ... -#---------------------------------------------- -def collect_ATTRIBUTS(data): - #---------------------------------------------- - # 0.4.8 : short modif for a fantasy font case - # in the OOo svg format ('viewbox' is - # written 'viewBox', for instance) - #---------------------------------------------- - data=data.replace(' ',' ').lower() - ELEM={'TYPE':data[1:data.find(' ')]} - t1=len(data) - t2=0 - ct=data.count('="') - while ct>0: - t0=data.find('="',t2) - t2=data.find(' ',t2)+1 - id=data[t2:t0] - t2=data.find('"',t0+2) - if id!='d': - ELEM[id]=data[t0+2:t2].replace('\\','/') - else: - ELEM[id]=[] - ELEM[id].append(t0+2) - ELEM[id].append(t2) - ct=data.count('="',t2) - return ELEM - -# -------------------------------------------- -# 0.4.1 : to avoid to use sax and ths xml -# tools of the complete python -# -------------------------------------------- -def build_HIERARCHY(t): - global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global LAST_ID, PATTERN - TRANSFORM=0 - t=t.replace('\t',' ') - while t.find(' ')!=-1: t=t.replace(' ',' ') - n0=0 - t0=t1=0 - #baliste=[] - balisetype=['?','?','/','/','!','!'] - BALISES=['D', #DECL_TEXTE', - 'D', #DECL_TEXTE', - 'F', #FERMANTE', - 'E', #ELEM_VIDE', - 'd', #DOC', - 'R', #REMARQUES', - 'C', #CONTENU', - 'O' #OUVRANTE' - ] - STACK=[] - while t1-1: - t0=t.find('<',t0) - t1=t.find('>',t0) - ouvrante=0 - #-------------------- - # 0.4.4 , add 'else:' and 'break' to the 'if' statement - #-------------------- - if t0>-1 and t1>-1: - if t[t0+1] in balisetype: - b=balisetype.index(t[t0+1]) - - if t[t0+2]=='-': - b=balisetype.index(t[t0+1])+1 - - balise=BALISES[b] - - if b==2: - parent=STACK.pop(-1) - if parent!=None and TRANSFORM>0: - TRANSFORM-=1 - - elif t[t1-1] in balisetype: - balise=BALISES[balisetype.index(t[t1-1])+1] - - else: - t2=t.find(' ',t0) - if t2>t1: t2=t1 - ouvrante=1 - NOM=t[t0+1:t2] - - - if '-1: - balise=BALISES[-1] - if NOM=='pattern' and not PATTERN: - t1=t.find('',t0)+len('') - balise=BALISES[-3] - else: - balise=BALISES[-2] - - if balise=='E' or balise=='O': - - proprietes=collect_ATTRIBUTS(t[t0:t1+ouvrante]) - - if 'id' in proprietes: - LAST_ID=proprietes['id'] - - if balise=='O' and 'transform' in proprietes: - STACK.append(proprietes['transform']) - TRANSFORM+=1 - elif balise=='O' : - STACK.append(None) - - proprietes['stack']=STACK[:] - D=[] - - if proprietes['TYPE'] in ['path'] and (proprietes['d'][1]-proprietes['d'][0]>1): - D=list_DATA(t[proprietes['d'][0]+t0:proprietes['d'][1]+t0]) - - elif proprietes['TYPE'] in OTHERSSHAPES: - #-------------------- - # 0.5.8, to remove exec - #-------------------- - D=OTHERSSHAPES[proprietes['TYPE']](proprietes) - - #elif proprietes['TYPE'] in ['pattern']: - # print 'pattern' - # D='' - - CP=[0.0,0.0] - if len(D)>0: - cursor=0 - proprietes['n']=[] - for cell in D: - - if len(cell)>=1 and cell[0] in TAGcourbe: - #-------------------- - # 0.5.8, to remove exec - #-------------------- - if cell[0] in ['m','M']: - curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP,proprietes) - else: - curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP) - - cursor+=1 - if TRANSFORM>0 or 'transform' in proprietes : - curve_TRANSFORM(curves.ITEM,proprietes) - - if 'style' in proprietes : - curve_FILL(curves.ITEM,proprietes) - - - elif proprietes['TYPE'] == 'svg': - BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,proprietes) - else: - #-------------------- - # 0.4.4 - #-------------------- - break - t1+=1 - t0=t1 - -def scan_FILE(nom): - global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global SEPARATE_CURVES, USE_COLORS, PATTERN - - dir,name=split(nom) - name=name.split('.') - result=0 - #Choise=1 - t1=Blender.sys.time() - t=filterFILE(nom) - if t!='false': - Blender.Window.EditMode(0) - if not SHARP_IMPORT: - togH = Blender.Draw.Create(1) - togW = Blender.Draw.Create(0) - togAS = Blender.Draw.Create(0) - togSP = Blender.Draw.Create(0) - togCOL = Blender.Draw.Create(0) - Pattern= Blender.Draw.Create(0) - block=[\ - ("Clamp Width 1", togW, "Rescale the import with a Width of one unit"),\ - ("Clamp Height 1", togH, "Rescale the import with a Heightof one unit"),\ - ("No Rescaling", togAS, "No rescaling, the result can be very large"),\ - ("Separate Curves", togSP, "Create an object for each curve, Slower. May manage colors"),\ - ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option"),\ - ("Import Patterns", Pattern, "import pattern content if it is made with paths.")] - retval = Blender.Draw.PupBlock("Import Options", block) - if togW.val: scale_=1 - elif togH.val: scale_=2 - elif togAS.val: scale_=3 - - if togSP.val: SEPARATE_CURVES=1 - - if togCOL.val and SEPARATE_CURVES : USE_COLORS=1 - - if Pattern.val : PATTERN =1 - - t1=Blender.sys.time() - # 0.4.1 : to avoid to use sax and the xml - # tools of the complete python - build_HIERARCHY(t) - r=BOUNDINGBOX['rec'] - curves.number_of_items=len(curves.ITEM) - for k, val in curves.ITEM.iteritems(): - val.pntsUV[0] =len(val.beziers_knot) - if curves.number_of_items>0 : #and Choise==1 : - #-------------------- - # 0.4.5 and 0.4.9 - #-------------------- - createCURVES(curves, name[0]) - else: - pass - print ' elapsed time : ',Blender.sys.time()-t1 - Blender.Redraw() - -#===================================================================== -#====================== SVG format mouvements ======================== -#===================================================================== -def functionSELECT(nom): - scan_FILE(nom) - - -if __name__=='__main__': - Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg') \ No newline at end of file diff --git a/release/scripts/bvh_import.py b/release/scripts/bvh_import.py deleted file mode 100644 index 4134503c511..00000000000 --- a/release/scripts/bvh_import.py +++ /dev/null @@ -1,757 +0,0 @@ -#!BPY - -""" -Name: 'Motion Capture (.bvh)...' -Blender: 242 -Group: 'Import' -Tip: 'Import a (.bvh) motion capture file' -""" - -__author__ = "Campbell Barton" -__url__ = ("blender.org", "blenderartists.org") -__version__ = "1.90 06/08/01" - -__bpydoc__ = """\ -This script imports BVH motion capture data to Blender. -as empties or armatures. -""" - -# -------------------------------------------------------------------------- -# BVH Import v2.0 by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -import bpy -import BPyMessages -Vector= Blender.Mathutils.Vector -Euler= Blender.Mathutils.Euler -Matrix= Blender.Mathutils.Matrix -RotationMatrix = Blender.Mathutils.RotationMatrix -TranslationMatrix= Blender.Mathutils.TranslationMatrix - -DEG2RAD = 0.017453292519943295 - -class bvh_node_class(object): - __slots__=(\ - 'name',# bvh joint name - 'parent',# bvh_node_class type or None for no parent - 'children',# a list of children of this type. - 'rest_head_world',# worldspace rest location for the head of this node - 'rest_head_local',# localspace rest location for the head of this node - 'rest_tail_world',# # worldspace rest location for the tail of this node - 'rest_tail_local',# # worldspace rest location for the tail of this node - 'channels',# list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, lock triple then rot triple - 'rot_order',# a triple of indicies as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation. - 'anim_data',# a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz) - 'has_loc',# Conveinience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 channels[2]!=-1) - 'has_rot',# Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1) - 'temp')# use this for whatever you want - - def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order): - self.name= name - self.rest_head_world= rest_head_world - self.rest_head_local= rest_head_local - self.rest_tail_world= None - self.rest_tail_local= None - self.parent= parent - self.channels= channels - self.rot_order= rot_order - - # convenience functions - self.has_loc= channels[0] != -1 or channels[1] != -1 or channels[2] != -1 - self.has_rot= channels[3] != -1 or channels[4] != -1 or channels[5] != -1 - - - self.children= [] - - # list of 6 length tuples: (lx,ly,lz, rx,ry,rz) - # even if the channels arnt used they will just be zero - # - self.anim_data= [(0,0,0,0,0,0)] - - - def __repr__(self): - return 'BVH name:"%s", rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)' %\ - (self.name,\ - self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z,\ - self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z) - - - -# Change the order rotation is applied. -MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1]) -MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]) - -def eulerRotate(x,y,z, rot_order): - # Clamp all values between 0 and 360, values outside this raise an error. - mats=[RotationMatrix(x%360,3,'x'), RotationMatrix(y%360,3,'y'), RotationMatrix(z%360,3,'z')] - # print rot_order - # Standard BVH multiplication order, apply the rotation in the order Z,X,Y - return (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler() - -def read_bvh(file_path, GLOBAL_SCALE=1.0): - # File loading stuff - # Open the file for importing - file = open(file_path, 'rU') - - # Seperate into a list of lists, each line a list of words. - file_lines = file.readlines() - # Non standard carrage returns? - if len(file_lines) == 1: - file_lines = file_lines[0].split('\r') - - # Split by whitespace. - file_lines =[ll for ll in [ l.split() for l in file_lines] if ll] - - - # Create Hirachy as empties - - if file_lines[0][0].lower() == 'hierarchy': - #print 'Importing the BVH Hierarchy for:', file_path - pass - else: - raise 'ERROR: This is not a BVH file' - - bvh_nodes= {None:None} - bvh_nodes_serial = [None] - - channelIndex = -1 - - - lineIdx = 0 # An index for the file. - while lineIdx < len(file_lines) -1: - #... - if file_lines[lineIdx][0].lower() == 'root' or file_lines[lineIdx][0].lower() == 'joint': - - # Join spaces into 1 word with underscores joining it. - if len(file_lines[lineIdx]) > 2: - file_lines[lineIdx][1] = '_'.join(file_lines[lineIdx][1:]) - file_lines[lineIdx] = file_lines[lineIdx][:2] - - # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.?? - - # Make sure the names are unique- Object names will match joint names exactly and both will be unique. - name = file_lines[lineIdx][1] - - #print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1]) - - lineIdx += 2 # Incriment to the next line (Offset) - rest_head_local = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) ) - lineIdx += 1 # Incriment to the next line (Channels) - - # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation] - # newChannel references indecies to the motiondata, - # if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended - # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value. - my_channel = [-1, -1, -1, -1, -1, -1] - my_rot_order= [None, None, None] - rot_count= 0 - for channel in file_lines[lineIdx][2:]: - channel= channel.lower() - channelIndex += 1 # So the index points to the right channel - if channel == 'xposition': my_channel[0] = channelIndex - elif channel == 'yposition': my_channel[1] = channelIndex - elif channel == 'zposition': my_channel[2] = channelIndex - - elif channel == 'xrotation': - my_channel[3] = channelIndex - my_rot_order[rot_count]= 0 - rot_count+=1 - elif channel == 'yrotation': - my_channel[4] = channelIndex - my_rot_order[rot_count]= 1 - rot_count+=1 - elif channel == 'zrotation': - my_channel[5] = channelIndex - my_rot_order[rot_count]= 2 - rot_count+=1 - - channels = file_lines[lineIdx][2:] - - my_parent= bvh_nodes_serial[-1] # account for none - - - # Apply the parents offset accumletivly - if my_parent==None: - rest_head_world= Vector(rest_head_local) - else: - rest_head_world= my_parent.rest_head_world + rest_head_local - - bvh_node= bvh_nodes[name]= bvh_node_class(name, rest_head_world, rest_head_local, my_parent, my_channel, my_rot_order) - - # If we have another child then we can call ourselves a parent, else - bvh_nodes_serial.append(bvh_node) - - # Account for an end node - if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it. - lineIdx += 2 # Incriment to the next line (Offset) - rest_tail = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) ) - - bvh_nodes_serial[-1].rest_tail_world= bvh_nodes_serial[-1].rest_head_world + rest_tail - bvh_nodes_serial[-1].rest_tail_local= rest_tail - - - # Just so we can remove the Parents in a uniform way- End end never has kids - # so this is a placeholder - bvh_nodes_serial.append(None) - - if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0] == '}': # == ['}'] - bvh_nodes_serial.pop() # Remove the last item - - if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion': - #print '\nImporting motion data' - lineIdx += 3 # Set the cursor to the first frame - break - - lineIdx += 1 - - - # Remove the None value used for easy parent reference - del bvh_nodes[None] - # Dont use anymore - del bvh_nodes_serial - - bvh_nodes_list= bvh_nodes.values() - - while lineIdx < len(file_lines): - line= file_lines[lineIdx] - for bvh_node in bvh_nodes_list: - #for bvh_node in bvh_nodes_serial: - lx= ly= lz= rx= ry= rz= 0.0 - channels= bvh_node.channels - anim_data= bvh_node.anim_data - if channels[0] != -1: - lx= GLOBAL_SCALE * float( line[channels[0]] ) - - if channels[1] != -1: - ly= GLOBAL_SCALE * float( line[channels[1]] ) - - if channels[2] != -1: - lz= GLOBAL_SCALE * float( line[channels[2]] ) - - if channels[3] != -1 or channels[4] != -1 or channels[5] != -1: - rx, ry, rz = eulerRotate(float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] ), bvh_node.rot_order) - #x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d - - # Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling. - # Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation. - - while anim_data[-1][3] - rx > 180: rx+=360 - while anim_data[-1][3] - rx < -180: rx-=360 - - while anim_data[-1][4] - ry > 180: ry+=360 - while anim_data[-1][4] - ry < -180: ry-=360 - - while anim_data[-1][5] - rz > 180: rz+=360 - while anim_data[-1][5] - rz < -180: rz-=360 - - # Done importing motion data # - anim_data.append( (lx, ly, lz, rx, ry, rz) ) - lineIdx += 1 - - # Assign children - for bvh_node in bvh_nodes.itervalues(): - bvh_node_parent= bvh_node.parent - if bvh_node_parent: - bvh_node_parent.children.append(bvh_node) - - # Now set the tip of each bvh_node - for bvh_node in bvh_nodes.itervalues(): - - if not bvh_node.rest_tail_world: - if len(bvh_node.children)==0: - # could just fail here, but rare BVH files have childless nodes - bvh_node.rest_tail_world = Vector(bvh_node.rest_head_world) - bvh_node.rest_tail_local = Vector(bvh_node.rest_head_local) - elif len(bvh_node.children)==1: - bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world) - bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local) - else: - # allow this, see above - #if not bvh_node.children: - # raise 'error, bvh node has no end and no children. bad file' - - # Removed temp for now - rest_tail_world= Vector(0,0,0) - rest_tail_local= Vector(0,0,0) - for bvh_node_child in bvh_node.children: - rest_tail_world += bvh_node_child.rest_head_world - rest_tail_local += bvh_node_child.rest_head_local - - bvh_node.rest_tail_world= rest_tail_world * (1.0/len(bvh_node.children)) - bvh_node.rest_tail_local= rest_tail_local * (1.0/len(bvh_node.children)) - - # Make sure tail isnt the same location as the head. - if (bvh_node.rest_tail_local-bvh_node.rest_head_local).length <= 0.001*GLOBAL_SCALE: - - bvh_node.rest_tail_local.y= bvh_node.rest_tail_local.y + GLOBAL_SCALE/10 - bvh_node.rest_tail_world.y= bvh_node.rest_tail_world.y + GLOBAL_SCALE/10 - - - - return bvh_nodes - - - -def bvh_node_dict2objects(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False): - - if IMPORT_START_FRAME<1: - IMPORT_START_FRAME= 1 - - scn= bpy.data.scenes.active - scn.objects.selected = [] - - objects= [] - - def add_ob(name): - ob = scn.objects.new('Empty') - objects.append(ob) - return ob - - # Add objects - for name, bvh_node in bvh_nodes.iteritems(): - bvh_node.temp= add_ob(name) - - # Parent the objects - for bvh_node in bvh_nodes.itervalues(): - bvh_node.temp.makeParent([ bvh_node_child.temp for bvh_node_child in bvh_node.children ], 1, 0) # ojbs, noninverse, 1 = not fast. - - # Offset - for bvh_node in bvh_nodes.itervalues(): - # Make relative to parents offset - bvh_node.temp.loc= bvh_node.rest_head_local - - # Add tail objects - for name, bvh_node in bvh_nodes.iteritems(): - if not bvh_node.children: - ob_end= add_ob(name + '_end') - bvh_node.temp.makeParent([ob_end], 1, 0) # ojbs, noninverse, 1 = not fast. - ob_end.loc= bvh_node.rest_tail_local - - - # Animate the data, the last used bvh_node will do since they all have the same number of frames - for current_frame in xrange(len(bvh_node.anim_data)): - Blender.Set('curframe', current_frame+IMPORT_START_FRAME) - - for bvh_node in bvh_nodes.itervalues(): - lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame] - - rest_head_local= bvh_node.rest_head_local - bvh_node.temp.loc= rest_head_local.x+lx, rest_head_local.y+ly, rest_head_local.z+lz - - bvh_node.temp.rot= rx*DEG2RAD,ry*DEG2RAD,rz*DEG2RAD - - bvh_node.temp.insertIpoKey(Blender.Object.IpoKeyTypes.LOCROT) - - scn.update(1) - return objects - - - -def bvh_node_dict2armature(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False): - - if IMPORT_START_FRAME<1: - IMPORT_START_FRAME= 1 - - - # Add the new armature, - scn = bpy.data.scenes.active - scn.objects.selected = [] - - arm_data= bpy.data.armatures.new() - arm_ob = scn.objects.new(arm_data) - scn.objects.context = [arm_ob] - scn.objects.active = arm_ob - - # Put us into editmode - arm_data.makeEditable() - - # Get the average bone length for zero length bones, we may not use this. - average_bone_length= 0.0 - nonzero_count= 0 - for bvh_node in bvh_nodes.itervalues(): - l= (bvh_node.rest_head_local-bvh_node.rest_tail_local).length - if l: - average_bone_length+= l - nonzero_count+=1 - - # Very rare cases all bones couldbe zero length??? - if not average_bone_length: - average_bone_length = 0.1 - else: - # Normal operation - average_bone_length = average_bone_length/nonzero_count - - - - ZERO_AREA_BONES= [] - for name, bvh_node in bvh_nodes.iteritems(): - # New editbone - bone= bvh_node.temp= Blender.Armature.Editbone() - - bone.name= name - arm_data.bones[name]= bone - - bone.head= bvh_node.rest_head_world - bone.tail= bvh_node.rest_tail_world - - # ZERO AREA BONES. - if (bone.head-bone.tail).length < 0.001: - if bvh_node.parent: - ofs= bvh_node.parent.rest_head_local- bvh_node.parent.rest_tail_local - if ofs.length: # is our parent zero length also?? unlikely - bone.tail= bone.tail+ofs - else: - bone.tail.y= bone.tail.y+average_bone_length - else: - bone.tail.y= bone.tail.y+average_bone_length - - ZERO_AREA_BONES.append(bone.name) - - - for bvh_node in bvh_nodes.itervalues(): - if bvh_node.parent: - # bvh_node.temp is the Editbone - - # Set the bone parent - bvh_node.temp.parent= bvh_node.parent.temp - - # Set the connection state - if not bvh_node.has_loc and\ - bvh_node.parent and\ - bvh_node.parent.temp.name not in ZERO_AREA_BONES and\ - bvh_node.parent.rest_tail_local == bvh_node.rest_head_local: - bvh_node.temp.options= [Blender.Armature.CONNECTED] - - # Replace the editbone with the editbone name, - # to avoid memory errors accessing the editbone outside editmode - for bvh_node in bvh_nodes.itervalues(): - bvh_node.temp= bvh_node.temp.name - - arm_data.update() - - # Now Apply the animation to the armature - - # Get armature animation data - pose= arm_ob.getPose() - pose_bones= pose.bones - - action = Blender.Armature.NLA.NewAction("Action") - action.setActive(arm_ob) - #xformConstants= [ Blender.Object.Pose.LOC, Blender.Object.Pose.ROT ] - - # Replace the bvh_node.temp (currently an editbone) - # With a tuple (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv) - for bvh_node in bvh_nodes.itervalues(): - bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened. - pose_bone= pose_bones[bone_name] - rest_bone= arm_data.bones[bone_name] - bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart() - - bone_rest_matrix_inv= Matrix(bone_rest_matrix) - bone_rest_matrix_inv.invert() - - bone_rest_matrix_inv.resize4x4() - bone_rest_matrix.resize4x4() - bvh_node.temp= (pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv) - - - # Make a dict for fast access without rebuilding a list all the time. - xformConstants_dict={ - (True,True): [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT],\ - (False,True): [Blender.Object.Pose.ROT],\ - (True,False): [Blender.Object.Pose.LOC],\ - (False,False): [],\ - } - - - # KEYFRAME METHOD, SLOW, USE IPOS DIRECT - - # Animate the data, the last used bvh_node will do since they all have the same number of frames - for current_frame in xrange(len(bvh_node.anim_data)-1): # skip the first frame (rest frame) - # print current_frame - - #if current_frame==40: # debugging - # break - - # Dont neet to set the current frame - for bvh_node in bvh_nodes.itervalues(): - pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp - lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame+1] - - if bvh_node.has_rot: - # Set the rotation, not so simple - bone_rotation_matrix= Euler(rx,ry,rz).toMatrix() - bone_rotation_matrix.resize4x4() - pose_bone.quat= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat() - - if bvh_node.has_loc: - # Set the Location, simple too - pose_bone.loc= (\ - TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) *\ - bone_rest_matrix_inv).translationPart() # WHY * 10? - just how pose works - - # Get the transform - xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot] - - - if xformConstants: - # Insert the keyframe from the loc/quat - pose_bone.insertKey(arm_ob, current_frame+IMPORT_START_FRAME, xformConstants, True ) - - # First time, set the IPO's to linear - if current_frame==0: - for ipo in action.getAllChannelIpos().itervalues(): - if ipo: - for cur in ipo: - cur.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - if IMPORT_LOOP: - cur.extend = Blender.IpoCurve.ExtendTypes.CYCLIC - - - - - # END KEYFRAME METHOD - - - """ - # IPO KEYFRAME SETTING - # Add in the IPOs by adding keyframes, AFAIK theres no way to add IPOs to an action so I do this :/ - for bvh_node in bvh_nodes.itervalues(): - pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp - - # Get the transform - xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot] - if xformConstants: - pose_bone.loc[:]= 0,0,0 - pose_bone.quat[:]= 0,0,1,0 - # Insert the keyframe from the loc/quat - pose_bone.insertKey(arm_ob, IMPORT_START_FRAME, xformConstants) - - - action_ipos= action.getAllChannelIpos() - - - for bvh_node in bvh_nodes.itervalues(): - has_loc= bvh_node.has_loc - has_rot= bvh_node.has_rot - - if not has_rot and not has_loc: - # No animation data - continue - - ipo= action_ipos[bvh_node.temp[0].name] # posebones name as key - - if has_loc: - curve_xloc= ipo[Blender.Ipo.PO_LOCX] - curve_yloc= ipo[Blender.Ipo.PO_LOCY] - curve_zloc= ipo[Blender.Ipo.PO_LOCZ] - - curve_xloc.interpolation= \ - curve_yloc.interpolation= \ - curve_zloc.interpolation= \ - Blender.IpoCurve.InterpTypes.LINEAR - - - if has_rot: - curve_wquat= ipo[Blender.Ipo.PO_QUATW] - curve_xquat= ipo[Blender.Ipo.PO_QUATX] - curve_yquat= ipo[Blender.Ipo.PO_QUATY] - curve_zquat= ipo[Blender.Ipo.PO_QUATZ] - - curve_wquat.interpolation= \ - curve_xquat.interpolation= \ - curve_yquat.interpolation= \ - curve_zquat.interpolation= \ - Blender.IpoCurve.InterpTypes.LINEAR - - # Get the bone - pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp - - - def pose_rot(anim_data): - bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix() - bone_rotation_matrix.resize4x4() - return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz - - def pose_loc(anim_data): - return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart()) - - - last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1 - - if has_loc: - pose_locations= [pose_loc(anim_key) for anim_key in bvh_node.anim_data] - - # Add the start at the end, we know the start is just 0,0,0 anyway - curve_xloc.append((last_frame, pose_locations[-1][0])) - curve_yloc.append((last_frame, pose_locations[-1][1])) - curve_zloc.append((last_frame, pose_locations[-1][2])) - - if len(pose_locations) > 1: - ox,oy,oz= pose_locations[0] - x,y,z= pose_locations[1] - - for i in xrange(1, len(pose_locations)-1): # from second frame to second last frame - - nx,ny,nz= pose_locations[i+1] - xset= yset= zset= True # we set all these by default - if abs((ox+nx)/2 - x) < 0.00001: xset= False - if abs((oy+ny)/2 - y) < 0.00001: yset= False - if abs((oz+nz)/2 - z) < 0.00001: zset= False - - if xset: curve_xloc.append((i+IMPORT_START_FRAME, x)) - if yset: curve_yloc.append((i+IMPORT_START_FRAME, y)) - if zset: curve_zloc.append((i+IMPORT_START_FRAME, z)) - - # Set the old and use the new - ox,oy,oz= x,y,z - x,y,z= nx,ny,nz - - - if has_rot: - pose_rotations= [pose_rot(anim_key) for anim_key in bvh_node.anim_data] - - # Add the start at the end, we know the start is just 0,0,0 anyway - curve_wquat.append((last_frame, pose_rotations[-1][0])) - curve_xquat.append((last_frame, pose_rotations[-1][1])) - curve_yquat.append((last_frame, pose_rotations[-1][2])) - curve_zquat.append((last_frame, pose_rotations[-1][3])) - - - if len(pose_rotations) > 1: - ow,ox,oy,oz= pose_rotations[0] - w,x,y,z= pose_rotations[1] - - for i in xrange(1, len(pose_rotations)-1): # from second frame to second last frame - - nw, nx,ny,nz= pose_rotations[i+1] - wset= xset= yset= zset= True # we set all these by default - if abs((ow+nw)/2 - w) < 0.00001: wset= False - if abs((ox+nx)/2 - x) < 0.00001: xset= False - if abs((oy+ny)/2 - y) < 0.00001: yset= False - if abs((oz+nz)/2 - z) < 0.00001: zset= False - - if wset: curve_wquat.append((i+IMPORT_START_FRAME, w)) - if xset: curve_xquat.append((i+IMPORT_START_FRAME, x)) - if yset: curve_yquat.append((i+IMPORT_START_FRAME, y)) - if zset: curve_zquat.append((i+IMPORT_START_FRAME, z)) - - # Set the old and use the new - ow,ox,oy,oz= w,x,y,z - w,x,y,z= nw,nx,ny,nz - - # IPO KEYFRAME SETTING - """ - pose.update() - return arm_ob - - -#=============# -# TESTING # -#=============# - -#('/metavr/mocap/bvh/boxer.bvh') -#('/d/staggered_walk.bvh') -#('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF -#('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings. -#('/metavr/mocap/bvh/walk4.bvh') # 0 channels - -''' -import os -DIR = '/metavr/mocap/bvh/' -for f in ('/d/staggered_walk.bvh',): - #for f in os.listdir(DIR)[5:6]: - #for f in os.listdir(DIR): - if f.endswith('.bvh'): - s = Blender.Scene.New(f) - s.makeCurrent() - #file= DIR + f - file= f - print f - bvh_nodes= read_bvh(file, 1.0) - bvh_node_dict2armature(bvh_nodes, 1) -''' - -def load_bvh_ui(file, PREF_UI= True): - - if BPyMessages.Error_NoFile(file): - return - - Draw= Blender.Draw - - IMPORT_SCALE = Draw.Create(0.1) - IMPORT_START_FRAME = Draw.Create(1) - IMPORT_AS_ARMATURE = Draw.Create(1) - IMPORT_AS_EMPTIES = Draw.Create(0) - IMPORT_LOOP = Draw.Create(0) - - # Get USER Options - if PREF_UI: - pup_block = [\ - ('As Armature', IMPORT_AS_ARMATURE, 'Imports the BVH as an armature'),\ - ('As Empties', IMPORT_AS_EMPTIES, 'Imports the BVH as empties'),\ - ('Scale: ', IMPORT_SCALE, 0.001, 100.0, 'Scale the BVH, Use 0.01 when 1.0 is 1 metre'),\ - ('Start Frame: ', IMPORT_START_FRAME, 1, 30000, 'Frame to start BVH motion'),\ - ('Loop Animation', IMPORT_LOOP, 'Enable cyclic IPOs'),\ - ] - - if not Draw.PupBlock('BVH Import...', pup_block): - return - - print 'Attempting import BVH', file - - IMPORT_SCALE = IMPORT_SCALE.val - IMPORT_START_FRAME = IMPORT_START_FRAME.val - IMPORT_AS_ARMATURE = IMPORT_AS_ARMATURE.val - IMPORT_AS_EMPTIES = IMPORT_AS_EMPTIES.val - IMPORT_LOOP = IMPORT_LOOP.val - - if not IMPORT_AS_ARMATURE and not IMPORT_AS_EMPTIES: - Blender.Draw.PupMenu('No import option selected') - return - Blender.Window.WaitCursor(1) - # Get the BVH data and act on it. - t1= Blender.sys.time() - print '\tparsing bvh...', - bvh_nodes= read_bvh(file, IMPORT_SCALE) - print '%.4f' % (Blender.sys.time()-t1) - t1= Blender.sys.time() - print '\timporting to blender...', - if IMPORT_AS_ARMATURE: bvh_node_dict2armature(bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP) - if IMPORT_AS_EMPTIES: bvh_node_dict2objects(bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP) - - print 'Done in %.4f\n' % (Blender.sys.time()-t1) - Blender.Window.WaitCursor(0) - -def main(): - Blender.Window.FileSelector(load_bvh_ui, 'Import BVH', '*.bvh') - -if __name__ == '__main__': - #def foo(): - main() - ''' - scn = bpy.data.scenes.active - for ob in list(scn.objects): - if ob.name!='arm__': - scn.objects.unlink(ob) - load_bvh_ui('/test.bvh', False) - ''' \ No newline at end of file diff --git a/release/scripts/c3d_import.py b/release/scripts/c3d_import.py deleted file mode 100644 index 98f643cbab9..00000000000 --- a/release/scripts/c3d_import.py +++ /dev/null @@ -1,1244 +0,0 @@ -#!BPY -# -*- coding: latin-1 -*- -""" -Name: 'Motion Capture (.c3d)...' -Blender: 246 -Group: 'Import' -Tooltip: 'Import a C3D Motion Capture file' -""" -__script__ = "C3D Motion Capture file import" -__author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)" -__version__ = "0.9" -__url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"] -__email__= ["rogerwickes@yahoo.com", "c3d script"] -__bpydoc__ = """\ -c3d_import.py v0.8 - -Script loading Graphics Lab Motion Capture file, -Usage:
- - Run the script
- - Choose the file to open
- - Press Import C3D button
- -Version History: - 0.4: PERIN Released under Blender Artistic Licence - 0.5: WICKES used marker names, fixed 2.45 depricated call - 0.6: WICKES creates armature for each subject - 0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s - 0.8: WICKES resolved DEC support issue - 0.9: BARTON removed scene name change, whitespace edits. WICKES added IK layers -""" - -#---------------------------------------------- -# (c) Jean-Baptiste PERIN december 2005, released under Blender Artistic Licence -# for the Blender 2.40 Python Scripts Bundle. -#---------------------------------------------- - -###################################################### -# This script imports a C3D file into blender. -# Loader is based on MATLAB C3D loader from -# Alan Morris, Toronto, October 1998 -# Jaap Harlaar, Amsterdam, april 2002 -###################################################### - -import string -import Blender -from Blender import * -import bpy -import struct -import BPyMessages -Vector= Blender.Mathutils.Vector -Euler= Blender.Mathutils.Euler -Matrix= Blender.Mathutils.Matrix -RotationMatrix = Blender.Mathutils.RotationMatrix -TranslationMatrix= Blender.Mathutils.TranslationMatrix - -#================= -# Global Variables, Constants, Defaults, and Shorthand References -#================= -# set senstitivity for displaying debug/console messages. 0=few, 100=max, including clicks at major steps -# debug(num,string) to conditionally display status/info in console window -DEBUG=Blender.Get('rt') - -# marker sets known in the world -HUMAN_CMU= "HumanRTKm.mkr" # The Human Real-Time capture marker set used by CMU -HUMAN_CMU2="HumanRT.mkr" # found in another file, seems same as others in that series -MARKER_SETS = [ HUMAN_CMU, HUMAN_CMU2 ] # marker sets that this program supports (can make an armature for) -XYZ_LIMIT= 10000 #max value for coordinates if in integer format - -# what layers to put stuff on in scene. 1 is selected, so everything goes there -# selecting only layer 2 shows only the armature moving, 12 shows only the empties -LAYERS_ARMOB= [1,2] -LAYERS_MARKER=[1,12] -LAYERS_IK=[1,11] -IK_PREFIX="ik_" # prefix in empty name: ik_prefix+subject prefix+bone name - -CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits? - -scn = Blender.Scene.GetCurrent() - -BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket -trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ} -trackup={"x":BCS.UPX, "y":BCS.UPY, "z":BCS.UPZ} - -#=============================# -# Classes -#=============================# -class Marker: - def __init__(self, x, y, z): - self.x=0.0 - self.y=0.0 - self.z=0.0 - - def __repr__(self): #report on self, as in if just printed - return str("[x = "+str(self.x) +" y = " + str(self.y)+" z = "+ str(self.z)+"]") - -class ParameterGroup: - def __init__(self, nom, description, parameter): - self.name = nom - self.description = description - self.parameter = parameter - - def __repr__(self): - return self.name, " ", self.description, " ", self.parameter - -class Parameter: - def __init__(self, name, datatype, dim, data, description): - self.name = name - self.datatype = datatype - self.dim = dim - self.data = data - self.description = description - - def __repr__(self): - return self.name, " ", self.description, " ", self.dim - -class MyVector: - def __init__(self, fx,fy,fz): - self.x=fx - self.y=fy - self.z=fz - -class Mybone: - "information structure for bone generation and posing" - def __init__(self, name,vec,par,head,tail,const): - self.name=name # name of this bone. must be unique within armature - self.vec=vec # edit bone vector it points - self.parent=par # name of parent bone to locate head and form a chain - self.headMark=head # list of 0+ markers where the head of this non-parented bone should be placed - self.tailMark=tail # list of 0+ markers where the tip should be placed - self.const=const # list of 0+ constraint tuples to control posing - self.head=MyVector(0,0,0) #T-pose location - self.tail=MyVector(0,0,0) - def __repr__(self): - return '[Mybone "%s"]' % self.name - - -#=============================# -# functions/modules -#=============================# -def error(str): - Draw.PupMenu('ERROR%t|'+str) - return -def status(str): - Draw.PupMenu('STATUS%t|'+str+"|Continue?") - return -def debug(num,msg): #use log4j or just console here. - if DEBUG >= num: - print 'debug:', (' '*num), msg - #TODO: if level 0, make a text file in Blender file to record major stuff - return - -def names(ob): return ob.name - - -######### -# Cette fonction renvoie la liste des empties -# in : -# out : emp_list (List of Object) la liste des objets de type "Empty" -######### -def getEmpty(name): - obs = [ob for ob in scn.objects if ob.type=="Empty" and ob.name==name] - if len(obs)==0: - return None - elif len(obs)==1: - return obs[0] - else: - error("FATAL ERROR: %i empties %s in file" % (len(obs),ob[0])) -######### -# Cette fonction renvoie un empty -# in : objname : le nom de l'empty recherche -# out : myobj : l'empty cree ou retrouve -######### -def getOrCreateEmpty(objname): - myobj= getEmpty(objname) - if myobj==None: - myobj = scn.objects.new("Empty",objname) - debug(50,'Marker/Empty created %s' % myobj) - return myobj - -def getOrCreateCurve(ipo, curvename): - """ - Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo - - >>> import mylib - - >>> lIpo = GetOrCreateIPO("Une IPO") - >>> laCurve = getOrCreateCurve(lIpo, "RotX") - - Either an ipo curve named C{curvename} exists before the call then this curve is returned, - Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned - - @type ipo: Blender Ipo - @param ipo: the Ipo in which the curve must be retrieved or created. - @type curvename: string - @param curvename: name of the IPO. - @rtype: Blender Curve - @return: a Blender Curve named C{curvename} in the C{ipo} Ipo - """ - try: - mycurve = ipo.getCurve(curvename) - if mycurve != None: - pass - else: - mycurve = ipo.addCurve(curvename) - except: - mycurve = ipo.addCurve(curvename) - return mycurve - -def eraseIPO (objectname): - object = Blender.Object.Get(objectname) - lIpo = object.getIpo() - if lIpo != None: - nbCurves = lIpo.getNcurves() - for i in range(nbCurves): - nbBezPoints = lIpo.getNBezPoints(i) - for j in range(nbBezPoints): - lIpo.delBezPoint(i) - -def comp_loc(emptyNameList): - myloc=Vector(0,0,0) - for emName in emptyNameList: - myobj = Blender.Object.Get(emName) - for i in range(3): - myloc[i]= myloc[i]+(myobj.loc[i]/len(emptyNameList)) #take the average loc of all marks - return myloc - -def comp_len(head, tail): # computes the length of a bone - headvec=comp_loc(head) - tailvec=comp_loc(tail) - netvec=headvec-tailvec - return netvec.length - -def createHumanCMU(): # human bone structure, makes a node set for CMU MoCap Lab - # order of bones: "spine","chest","neck","head",...face toward you in front view - # pose constraints are tuples of (type,target,influence,other-as-needed) - # constraint stack order is important. for proper bone pointing and orinetation: - # IK, then TT +YZ in world space. then LR XZ to 0 in world space, this points the bone, twists it, but then - # limits the rotation to the sidebar enpty with the Z facing it, and Y pointing along the bone. - nodes=[] # bonename, vector, parent, head targets, tail targets, constraint list - for i in range(23): nodes.append(Mybone("name","vec","par",[],[],[])) - nodes[0]= Mybone("root", "-Y","",["RBWT", "LBWT"],["RFWT", "LFWT", "RBWT", "LBWT"],[("LOC","RBWT",1.0),("LOC","LBWT",0.5),("IK","RFWT",1.0),("IK","LFWT",0.5),("TT","RBWT",1,"+YZ"),("LR","XZ",1)]) - nodes[1]= Mybone("spine","+Z","root",[],["STRN","T10"],[("IK","STRN",1.0),("IK","T10",0.5),("TT","STRN",1,"+YZ"),("LR","XZ",1)]) - nodes[2]= Mybone("chest","+Z","spine",[],["CLAV","C7"],[("IK","CLAV",1.0),("IK","C7",0.5),("TT","CLAV",1,"+YZ"),("LR","XZ",1)]) - nodes[3]= Mybone("neck", "+Z","chest",[],["RBHD","LBHD"],[("IK","RBHD",1.0),("IK","LBHD",0.5),("TT","LBHD",1,"+YZ"),("LR","XZ",1)]) - nodes[4]= Mybone("head" ,"-Y","neck",[],["RFHD","LFHD"],[("IK","RFHD",1.0),("IK","LFHD",0.5),("TT","LFHD",1,"+YZ"),("LR","XZ",1)]) - - nodes[5]= Mybone("shoulder.R","-X","chest",[],["RSHO"],[("IK","RSHO",1.0)]) - nodes[6]= Mybone("toparm.R", "-X","shoulder.R",[],["RELB"],[("IK","RELB",1.0),("TT","RUPA",1,"+YZ"),("LR","XZ",1)]) - nodes[7]= Mybone("lowarm.R", "-X","toparm.R",[],["RWRA","RWRB"],[("IK","RWRA",1.0),("IK","RWRB",0.5),("TT","RFRM",1,"+YZ"),("LR","XZ",1)]) - nodes[8]= Mybone("hand.R", "-X","lowarm.R",[],["RFIN"],[("IK","RFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"RTHM" - - nodes[9]= Mybone("hip.R", "-X","root",[],["RFWT","RBWT"],[("IK","RFWT",1.0),("IK","RBWT",0.5)]) - nodes[10]=Mybone("topleg.R","-Z","hip.R",[],["RKNE"],[("IK","RKNE",1),("TT","RTHI",1,"+YZ"),("LR","XZ",1)]) - nodes[11]=Mybone("lowleg.R","-Z","topleg.R",[],["RANK","RHEE"],[("IK","RHEE",1.0),("TT","RSHN",1,"+YZ"),("LR","XZ",1)]) - nodes[12]=Mybone("foot.R", "-Y","lowleg.R",[],["RTOE","RMT5"],[("IK","RTOE",1.0),("IK","RMT5",0.2),("TT","RMT5",1,"+YZ")]) - nodes[13]=Mybone("toes.R", "-Y","foot.R",[],["RTOE"],[("IK","RTOE",1.0)]) - - nodes[14]=Mybone("shoulder.L","+X","chest",[],["LSHO"],[("IK","LSHO",1.0)]) - nodes[15]=Mybone("toparm.L", "+X","shoulder.L",[],["LELB"],[("IK","LELB",1.0),("TT","LUPA",1,"+YZ"),("LR","XZ",1)]) - nodes[16]=Mybone("lowarm.L", "+X","toparm.L",[],["LWRA","LWRB"],[("IK","LWRA",1.0),("IK","LWRB",0.5),("TT","LFRM",1,"+YZ"),("LR","XZ",1)]) - nodes[17]=Mybone("hand.L", "+X","lowarm.L",[],["LFIN"],[("IK","LFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"LTHM" - - nodes[18]=Mybone("hip.L", "+X","root",[],["LFWT","LBWT"],[("IK","LFWT",1.0),("IK","LBWT",0.5)]) - nodes[19]=Mybone("topleg.L","-Z","hip.L",[],["LKNE"],[("IK","LKNE",1),("TT","LTHI",1,"+YZ"),("LR","XZ",1)]) - nodes[20]=Mybone("lowleg.L","-Z","topleg.L",[],["LANK","LHEE"],[("IK","LHEE",1.0),("TT","LSHN",1,"+YZ"),("LR","XZ",1)]) - nodes[21]=Mybone("foot.L", "-Y","lowleg.L",[],["LTOE","LMT5"],[("IK","LTOE",1.0),("IK","LMT5",0.2),("TT","LMT5",1,"+YZ"),("LR","XZ",1)]) - nodes[22]=Mybone("toes.L", "-Y","foot.L",[],["LTOE"],[("IK","LTOE",1.0)]) - return nodes - -def createNodes(marker_set): # make a list of bone name, parent, edit head loc, edit tail loc, pose constraints - #ultimately, I want to read in an XML file here that specifies the node trees for various marker sets - if marker_set==HUMAN_CMU: nodes= createHumanCMU() #load up and verify the file has the CMU marker set - elif marker_set==HUMAN_CMU2: nodes= createHumanCMU() - else: nodes=[] - return nodes -def findEntry(item,list): - for i in range(len(list)): - if item==list[i]: break - debug(100,"findEtnry %s is %i in list of %i items" % (item,i,len(list))) - return i -def makeNodes(prefix, markerList, empties, marker_set): #make sure the file has the nodes selected - nodes= createNodes(marker_set) # list has generic marker names; replace them with the actual object names created - #each entry in markerlist has a corresponding entry in empties in the same order - errList=[] - for i in range(len(nodes)): - node= nodes[i] - debug(60,"Adapting node %s to prefix %s" % (node,prefix)) - - #replace generic head markers with actual empty names - for im in range(len(node.headMark)): - marker= node.headMark[im] - mark= prefix+marker - imn= findEntry(mark,markerList) - if imn < len(markerList): - debug(90,"Adapating head marker %s to %s" % (marker,empties[imn].name)) - nodes[i].headMark[im]= empties[imn].name - else: errList.append([node.name,"head location",mark,node,2]) - - #replace generic tail markers with actual empty names - for im in range(len(node.tailMark)): - marker= node.tailMark[im] - mark= prefix+marker - imn= findEntry(mark,markerList) - if imn < len(markerList): - debug(90,"Adapating marker %s to %s" % (marker,empties[imn].name)) - nodes[i].tailMark[im]= empties[imn].name - else: errList.append([node.name,"tail location",mark,node,2]) - - #replace generic constraint markers (if the constraint references a marker) with empty name - for im in range(len(node.const)): - const=node.const[im] - if const[0] in ("LOC","IK","TT"): - marker=const[1] - mark= prefix+marker - imn= findEntry(mark,markerList) - if imn < len(markerList): - debug(90,"Adapating %s constraint marker %s to %s" % (const[0],marker,empties[imn].name)) - if const[0] in ("IK","LR","LOC"): - nodes[i].const[im]=(const[0], empties[imn].name, const[2]) - else: nodes[i].const[im]=(const[0], empties[imn].name, const[2], const[3]) - else: errList.append([node.name,const[0]+" constraint",mark,node,4]) - - if errList!=[]: #we have issues. - for err in errList: - debug(0,"Bone "+err[0]+" specifies "+err[2]+" as "+err[1]+"which was not specified in file.") - #need a popup here to ignore/cleanup node tree, or add the marker(?) or abort - usrOption= 1 - if usrOption==0: #ignore this marker (remove it) - for node in nodes: #find the bone in error - if node.name==err[0]: - print "Before",node - if err[3] in range(2,3): - node[err[3]].remove(err[2]) #find the marker in error and remove it - elif err[3]==4: #find the constraint and remove it - for const in node.const: - if const[1]==err[2]: node.const.remove(const) - print "After",node - elif usrOption==1: #add these markers as static empties, and user will automate them later - #and the bones will be keyed to them, so it will all be good. - #file may have just mis-named the empty, or the location can be derived based on other markers - em= getOrCreateEmpty(err[2]) - em.layers= LAYERS_MARKER - else: abort() #abend - if DEBUG==100: status("Nodes Updated") - return nodes #nodes may be updated - -def makeBones(arm,nodes): - debug(20,"Making %i edit bones" % len(nodes)) - for node in nodes: - bone= Blender.Armature.Editbone() - bone.name= node.name - arm.bones[bone.name]= bone #add it to the armature - debug(50,"Bone added: %s" % bone) - if bone.name <> node.name: - debug(0,"ERROR: duplicate node % name specified" % node.name) - node.name= bone.name #you may not get what you asked for - if node.parent!="": #parent - debug(60,"Bone parent: %s"%node.parent) - bone.parent= arm.bones[node.parent] - bone.options = [Armature.CONNECTED] - #compute head = average of the reference empties - if node.headMark==[]: # no head explicitly stated, must be tail of parent - for parnode in nodes: - if node.parent==parnode.name: break - node.headMark= parnode.tailMark - node.head= parnode.tail - else: node.head= comp_loc(node.headMark) #node head is specified, probably only for root. - - bone.head= node.head - debug(60,"%s bone head: (%0.2f, %0.2f, %0.2f)" % (bone.name,bone.head.x, bone.head.y, bone.head.z)) - mylen=comp_len(node.headMark,node.tailMark) # length of the bone as it was recorded for that person - # for our T position, compute the bone length, add it to the head vector component to get the tail - if node.vec[0]=="-": mylen=-mylen - debug(80,"Bone vector %s length %0.2f" %(node.vec,mylen)) - node.tail= Vector(node.head) - myvec=node.vec[1].lower() - if myvec=="x": node.tail.x+=mylen - elif myvec=="y": node.tail.y+=mylen - elif myvec=="z": node.tail.z+=mylen - else: - debug(0,"%s %s %s %s" % (node.vec,myvec,node.vec[0],node.vec[1])) - error("ERROR IN BONE SPEC ") - bone.tail= node.tail - debug(60,"Bone tail: (%i,%i,%i)" %(bone.tail.x, bone.tail.y, bone.tail.z)) - #Armature created in the T postion, but with bone lengths to match the marker set and subject - #when this is constrained to the markers, the recorded action will be relative to a know Rotation - #so that all recorded actions should be interchangeable. wooot! - #Only have to adjust starting object loc when matching up actions. - return #arm #updated - -def makeConstLoc(pbone,const): - const_new= pbone.constraints.append(Constraint.Type.COPYLOC) - const_new.name = const[0]+"-"+const[1] - const_target=Blender.Object.Get(const[1]) - const_new[BCS.TARGET]= const_target - const_new.influence = const[2] - return - -def makeConstLimRot(pbone,const): - const_new= pbone.constraints.append(Constraint.Type.LIMITROT) - const_new.name = const[0]+"-"+const[1] - for axis in const[1]: - if axis.lower()=="x": const_new[BCS.LIMIT] |= BCS.LIMIT_XROT #set - if axis.lower()=="y": const_new[BCS.LIMIT] |= BCS.LIMIT_YROT #set - if axis.lower()=="z": const_new[BCS.LIMIT] |= BCS.LIMIT_ZROT #set - const_new[BCS.OWNERSPACE]= BCS.SPACE_LOCAL - const_new.influence = const[2] - # fyi, const[Constraint.Settings.LIMIT] &= ~Constraint.Settings.LIMIT_XROT #reset - return - -def makeConstIK(prefix,pbone,const): - #Blender 246 only supports one IK Solver per bone, but we might want many, - # so we need to create a reference empty named after the bone - # that floats between the markers, so the bone can point to it as a singularity - myob= getOrCreateEmpty(IK_PREFIX+prefix+pbone.name) - myob.layers= LAYERS_IK - # note that this empty gets all the IK constraints added on as location constraints - myconst= myob.constraints.append(Constraint.Type.COPYLOC) - myconst.name=const[0]+"-"+const[1] - myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1]) - myconst.influence = const[2] - - #point the bone once to the empty via IK - success=False - for myconst in pbone.constraints: - if myconst.type == Constraint.Type.IKSOLVER: success=True - if not(success): #add an IK constraint to the bone to point to the empty - #print pbone - myconst= pbone.constraints.append(Constraint.Type.IKSOLVER) - myconst.name = const[1] - myconst[BCS.TARGET]= myob - myconst.influence = const[2] - #const_new[Constraint.Settings.BONE]= ? - myconst[BCS.CHAINLEN]= 1 - myconst[BCS.USETIP]= True - myconst[BCS.STRETCH]= False - return - -def makeConstTT(pbone,const): - myconst= pbone.constraints.append(Constraint.Type.TRACKTO) - myconst.name=const[0]+"-"+const[1] - debug(70,"%s %s" % (myconst,const[3])) - myob= getEmpty(const[1]) - if myob!= None: - myconst[BCS.TARGET]= myob - myconst.influence = const[2] - #const[3] is the Track and the thrird char is the Up indicator - myconst[BCS.TRACK]= trackto[const[3][0:2].lower()] - myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction - myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL - myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL] - if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE") - else: #marker not found. could be missing from this file, or an error in node spec - error("TrackTo Constraint for %s |specifies unknown marker %s" % (pbone.name,const[1])) - return - -def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements - #this is constraint-based posing, not hard-keyed posing. - #we do constraint-based first so that user can adjust the constraints, possibly smooth/tweak motion - # add additional bones or referneces/constraints, before baking to hard keyframes - - pose= arm_ob.getPose() - debug(0,"Posing %s %s" % (arm_ob, pose)) - for node in nodes: - debug(30, "examining %s" %node) - if len(node.const)>0: #constraints for this bone are desired - pbone = pose.bones[node.name] - debug(40,"Posing bone %s" %pbone) - for const in node.const: - debug(50,"Constraining %s by %s" %(pbone,const)) - if const[0]=="LOC":makeConstLoc(pbone,const) - elif const[0]=="IK": makeConstIK(prefix,pbone,const) - elif const[0]=="LR": makeConstLimRot(pbone,const) - elif const[0]=="TT": makeConstTT(pbone,const) - else: - error("FATAL: constraint %s not supported" %const[0]) - break - debug(10, "Posing complete. Cycling pose and edit mode") - pose.update() - return - -def make_arm(subject,prefix,markerList, emptyList,marker_set): - debug(10,"**************************") - debug(00, "**** Making Armature for %s..." % subject) - debug(10, "**************************") - # copied from bvh import bvh_node_dict2armature; trying to use similar process for further integtration down the road - # Add the new armature, - - nodes= makeNodes(prefix, markerList, emptyList, marker_set) #assume everyone in file uses the same mocap suit - # each person in the file may be different height, so each needs their own new armature to match marker location - -## obs= Blender.Object.Get() -## success=False -## for ob in obs: -## if ob.name==subject: -## success=True -## if success: -## menu="Human Armature already exists for this subject." -## menu+="%t|Create another in this scene" -## menu+="%l|Start a new scene" -## menu+="%l|Use this armature" -## menusel= Draw.PupMenu(menu) - - arm= Blender.Armature.New(subject) #make an armature. - debug(10,"Created Armature %s" % arm) - # Put us into editmode - arm.makeEditable() - arm.drawType = Armature.OCTAHEDRON - makeBones(arm,nodes) - scn = Blender.Scene.GetCurrent() #add it to the current scene. could create new scenes here as yaf - arm_ob= scn.objects.new(arm) #instance it in the scene. this is the new way for 2.46 to instance objects - arm_ob.name= subject #name it something like the person it represents - arm_ob.layers= LAYERS_ARMOB - debug(20,"Instanced Armature %s" % arm_ob) - arm.update() #exit editmode. Arm must be instanced as an object before you can save changes or pose it - Blender.Redraw() # show the world - if DEBUG==100: status("T-Bones made.") - - makePoses(prefix,arm_ob,nodes) #constrain arm_ob with these markers - - scn.update(1) #make everyone behave themselves in the scene, and respect the new constraints - return arm_ob - -def setupAnim(StartFrame, EndFrame, VideoFrameRate): - debug(100, 'VideoFrameRate is %i' %VideoFrameRate) - if VideoFrameRate<1: VideoFrameRate=1 - if VideoFrameRate>120: VideoFrameRate=120 - # set up anim panel for them - context=scn.getRenderingContext() - context.sFrame=StartFrame - context.eFrame=EndFrame - context.fps=int(VideoFrameRate) - - Blender.Set("curframe",StartFrame) - Blender.Redraw() - return - -def makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers): - debug(10, "**************************") - debug(00, "*** Making Cloud Formation") - debug(10, "**************************") - empties=[] - ipos=[] - curvesX=[] - curvesY=[] - curvesZ=[] - debug(0, "%i Markers (empty cloud) will be put on layers %s" % (Nmarkers,LAYERS_MARKER)) - # Empty Cloud formation - for i in range(Nmarkers): - debug(100,"%i marker %s"%(i, markerList[i])) - emptyname = markerList[i] # rdw: to use meaningful names from Points parameter - em= getOrCreateEmpty(emptyname) #in this scene - em.layers= LAYERS_MARKER - #make a list of the actual empty - empties.append(em) - #assign it an ipo with the loc xyz curves - lipo = Ipo.New("Object",em.name) - ipos.append(lipo) - curvesX.append(getOrCreateCurve(ipos[i],'LocX')) - curvesY.append(getOrCreateCurve(ipos[i],'LocY')) - curvesZ.append(getOrCreateCurve(ipos[i],'LocZ')) - empties[i].setIpo(ipos[i]) - debug(30,"Cloud of %i empties created." % len(empties)) - NvideoFrames= EndFrame-StartFrame+1 - debug(10, "**************************") - debug(00, "**** Calculating Marker Ipo Curves over %i Frames ..." % NvideoFrames) - debug(10, "**************************") - err= index=0 #number of errors, logical frame - for frame in range(StartFrame,EndFrame+1): - if index==0: start=sys.time() - elif index==100: - tmp=(NvideoFrames-100)*(sys.time()-start)/6000 - debug(0,"%i minutes process time estimated" % tmp) - elif index >100: print index*100/(NvideoFrames-1),"% complete\r", - for i in range(Nmarkers): - if Markers[index][i].z < 0: Markers[index][i].z= -Markers[index][i].z - success=True - if CLEAN: #check for good data - # C3D marker decoding may have coordinates negative (improper sign bit decoding?) - myX= abs(Markers[index][i].x) - myY= abs(Markers[index][i].y) - myZ= Markers[index][i].z - if myX > 10000 or myY > 10000 or myZ > 10000: success=False - if myX <.01 and myY <.01 and myZ <.01: success=False # discontinuity in marker tracking (lost marker) - - if success: - curvesX[i].append((frame, Markers[index][i].x)) #2.46 knot method - curvesY[i].append((frame, Markers[index][i].y)) - curvesZ[i].append((frame, Markers[index][i].z)) - if frame==StartFrame: debug(40, "%s loc frame %i: (%0.2f, %0.2f, %0.2f)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z)) - else: - err+=1 # some files have thousands... - #debug(30,"Point ignored for marker:%s frame %i: (%i, %i, %i)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z)) - index += 1 - debug(70, "%i points ignored across all markers and frames. Recalculating..." % err) - - for i in range(Nmarkers): - curvesX[i].Recalc() - curvesY[i].Recalc() - curvesZ[i].Recalc() - Blender.Set('curframe', StartFrame) - Blender.Redraw() - if DEBUG==100: status("Clound formed") - return empties - -def getNumber(str, length): - if length==2: # unsigned short - return struct.unpack('H',str[0:2])[0], str[2:] - sum = 0 - for i in range(length): - #sum = (sum << 8) + ord(str[i]) for big endian - sum = sum + ord(str[i])*(2**(8*i)) - return sum, str[length:] -def unpackFloat(chunk,proctype): - #print proctype - myvar=chunk[0:4] - if proctype==2: #DEC-VAX - myvar=chunk[2:4]+chunk[0:2] #swap lo=hi word order pair - return struct.unpack('f',myvar[0:4])[0] - -def getFloat(chunk,proctype): - return unpackFloat(chunk, proctype), chunk[4:] -def parseFloat(chunk,ptr,proctype): - return unpackFloat(chunk[ptr:ptr+4], proctype), ptr+4 - - -def load_c3d(FullFileName): -# Input: FullFileName - file (including path) to be read -# -# Variable: -# Markers 3D-marker data [Nmarkers x NvideoFrames x Ndim(=3)] -# VideoFrameRate Frames/sec -# AnalogSignals Analog signals [Nsignals x NanalogSamples ] -# AnalogFrameRate Samples/sec -# Event Event(Nevents).time ..value ..name -# ParameterGroup ParameterGroup(Ngroups).Parameters(Nparameters).data ..etc. -# CameraInfo MarkerRelated CameraInfo [Nmarkers x NvideoFrames] -# ResidualError MarkerRelated ErrorInfo [Nmarkers x NvideoFrames] - - Markers=[]; - VideoFrameRate=120; - AnalogSignals=[]; - AnalogFrameRate=0; - Event=[]; - ParameterGroups=[]; - CameraInfo=[]; - ResidualError=[]; - - debug(10, "*********************") - debug(10, "**** Opening File ***") - debug(10, "*********************") - - #ind=findstr(FullFileName,'\'); - #if ind>0, FileName=FullFileName(ind(length(ind))+1:length(FullFileName)); else FileName=FullFileName; end - debug(0, "FileName = " + FullFileName) - fid=open(FullFileName,'rb'); # native format (PC-intel). ideasman says maybe rU - content = fid.read(); - content_memory = content - #Header section - NrecordFirstParameterblock, content = getNumber(content,1) # Reading record number of parameter section - - key, content = getNumber(content,1) - if key!=80: - error('File: does not comply to the C3D format') - fid.close() - return - #Paramter section - content = content[512*(NrecordFirstParameterblock-1)+1:] # first word ignored - #file format spec says that 3rd byte=NumberofParmaterRecords... but is ignored here. - proctype,content =getNumber(content,1) - proctype = proctype-83 - proctypes= ["unknown","(INTEL-PC)","(DEC-VAX)","(MIPS-SUN/SGI)"] - - if proctype in (1,2): debug(0, "Processor coding %s"%proctypes[proctype]) - elif proctype==3: debug(0,"Program untested with %s"%proctypes[proctype]) - else: - debug(0, "INVALID processor type %i"%proctype) - proctype=1 - debug(0,"OVERRIDE processor type %i"%proctype) - - #if proctype==2, - # fclose(fid); - # fid=fopen(FullFileName,'r','d'); % DEC VAX D floating point and VAX ordering - #end - debug(10, "***********************") - debug(00, "**** Reading Header ***") - debug(10, "***********************") - - # ############################################### - # ## ## - # ## read header ## - # ## ## - # ############################################### - - #%NrecordFirstParameterblock=fread(fid,1,'int8'); % Reading record number of parameter section - #%key1=fread(fid,1,'int8'); % key = 80; - - content = content_memory - #fseek(fid,2,'bof'); - content = content[2:] - - # - Nmarkers, content=getNumber(content, 2) - NanalogSamplesPerVideoFrame, content = getNumber(content, 2) - StartFrame, content = getNumber(content, 2) - EndFrame, content = getNumber(content, 2) - MaxInterpolationGap, content = getNumber(content, 2) - - Scale, content = getFloat(content,proctype) - - NrecordDataBlock, content = getNumber(content, 2) - NanalogFramesPerVideoFrame, content = getNumber(content, 2) - - if NanalogFramesPerVideoFrame > 0: - NanalogChannels=NanalogSamplesPerVideoFrame/NanalogFramesPerVideoFrame - else: - NanalogChannels=0 - - VideoFrameRate, content = getFloat(content,proctype) - - AnalogFrameRate=VideoFrameRate*NanalogFramesPerVideoFrame - NvideoFrames = EndFrame - StartFrame + 1 - - debug(0, "Scale= %0.2f" %Scale) - debug(0, "NanalogFramesPerVideoFrame= %i" %NanalogFramesPerVideoFrame) - debug(0, "Video Frame Rate= %i" %VideoFrameRate) - debug(0, "AnalogFrame Rate= %i"%AnalogFrameRate) - debug(0, "# markers= %i" %Nmarkers) - debug(0, "StartFrame= %i" %StartFrame) - debug(0, "EndFrame= %i" %EndFrame) - debug(0, "# Video Frames= %i" %NvideoFrames) - - if Scale>0: - debug(0, "Marker data is in integer format") - if Scale>(XYZ_LIMIT/32767): - Scale=XYZ_LIMIT/32767.0 - debug(0, "OVERRIDE: Max coordinate is %i, Scale changed to %0.2f" % (XYZ_LIMIT,Scale)) - else: debug(0, "Marker data is in floating point format") - if VideoFrameRate<1 or VideoFrameRate>120: - VideoFrameRate= 120 - debug(0, "OVERRIDE Video Frame Rate= %i" %VideoFrameRate) - if proctype not in (1,2): # Intel, DEC are known good - debug(0, "OVERRIDE|Program not tested with this encoding. Set to Intel") - proctype= 1 - - debug(10, "***********************") - debug(10, "**** Reading Events ...") - debug(10, "***********************") - - content = content_memory - content = content[298:] #bizarre .. ce devrait être 150 selon la doc rdw skips first 299 bytes? - - EventIndicator, content = getNumber(content, 2) - EventTime=[] - EventValue=[] - EventName=[] - - debug(0, "Event Indicator = %i" %EventIndicator) - if EventIndicator==12345: #rdw: somehow, this original code seems fishy, but I cannot deny it. - Nevents, content = getNumber(content, 2) - debug(0, "Nevents= %i" %Nevents) - content = content[2:] - if Nevents>0: - for i in range(Nevents): - letime, content = getFloat(content,proctype) - EventTime.append(letime) - content = content_memory - content = content[188*2:] - for i in range(Nevents): - lavalue, content = getNumber(content, 1) - EventValue.append(lavalue) - content = content_memory - content = content[198*2:] - for i in range(Nevents): - lenom = content[0:4] - content = content[4:] - EventName.append(lenom) - - debug(00, "***************************") - debug(00, "**** Reading Parameters ...") - debug(10, "***************************") - subjects=[] # a name would be nice, but human will do - prefixes=[] # added on to mocap marker names, one for each subject - marker_subjects = [] # hopefully will be specified in the file and known to this program - markerList=[] - ParameterGroups = [] - ParameterNumberIndex = [] - - content = content_memory - content = content[512*(NrecordFirstParameterblock-1):] - - dat1, content = getNumber(content, 1) - key2, content = getNumber(content, 1) - - NparameterRecords, content = getNumber(content, 1) - debug(100, "NparameterRecords=%i"%NparameterRecords) - proctype,content =getNumber(content,1) - proctype = proctype-83 # proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI) - - for i in range(NparameterRecords): - leparam = ParameterGroup(None, None, []) - ParameterGroups.append(leparam) - ParameterNumberIndex.append(0) - # - Ncharacters, content = getNumber(content, 1) - if Ncharacters>=128: - Ncharacters = -(2**8)+(Ncharacters) - GroupNumber, content = getNumber(content, 1) - if GroupNumber>=128: - GroupNumber = -(2**8)+(GroupNumber) - debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters)) - - while Ncharacters > 0: - if GroupNumber<0: - GroupNumber=abs(GroupNumber) - GroupName = content[0:Ncharacters] - content = content[Ncharacters:] - #print "Group Number = ", GroupNumber - ParameterGroups[GroupNumber].name = GroupName - #print "ParameterGroupName =", GroupName - offset, content = getNumber(content, 2) - deschars, content = getNumber(content, 1) - GroupDescription = content[0:deschars] - content = content[deschars:] - ParameterGroups[GroupNumber].description = GroupDescription - # - ParameterNumberIndex[GroupNumber]=0 - content = content[offset-3-deschars:] - else: - - ParameterNumberIndex[GroupNumber]=ParameterNumberIndex[GroupNumber]+1 - ParameterNumber=ParameterNumberIndex[GroupNumber] - #print "ParameterNumber=", ParameterNumber - ParameterGroups[GroupNumber].parameter.append(Parameter(None, None, [], [], None)) - ParameterName = content[0:Ncharacters] - content = content[Ncharacters:] - #print "ParameterName = ",ParameterName - if len(ParameterName)>0: - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].name=ParameterName - offset, content = getNumber(content, 2) - filepos = len(content_memory)-len(content) - nextrec = filepos+offset-2 - - type, content=getNumber(content, 1) - if type>=128: - type = -(2**8)+type - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].type=type - - dimnum, content=getNumber(content, 1) - if dimnum == 0: - datalength = abs(type) - else: - mult=1 - dimension=[] - for j in range (dimnum): - ladim, content = getNumber(content, 1) - dimension.append(ladim) - mult=mult*dimension[j] - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].dim.append(dimension[j]) - datalength = abs(type)*mult - - #print "ParameterNumber = ", ParameterNumber, " Group Number = ", GroupNumber - - if type==-1: - data = "" - wordlength=dimension[0] - if dimnum==2 and datalength>0: - for j in range(dimension[1]): - data=string.rstrip(content[0:wordlength]) - content = content[wordlength:] - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data) - elif dimnum==1 and datalength>0: - data=content[0:wordlength] - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data) # ??? - - myParam=string.rstrip(ParameterName) - myGroup=string.rstrip(GroupName) - msg= "-%s-%s-" % (myGroup,myParam) - if myGroup == "POINT": - if myParam== "LABELS": - # named in form of subject:marker. - # the list "empties" is a corresponding list of actual empty object names that make up the cloud - markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - debug(0, "%sLABELS = %i %s" %(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points - elif myParam== "LABELS2": #more labels - # named in form of subject:marker. - # the list "empties" is a corresponding list of actual empty object names that make up the cloud - momarkList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - markerList+=momarkList - debug(0, "%sLABELS2 = %i %s" %(msg, len(momarkList),momarkList)) #list of logical markers from 0 to n corresponding to points - else: debug(70, "%s UNUSED = %s" %(msg,ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data)) - elif myGroup in ["SUBJECT", "SUBJECTS"]: #info about the actor - if myParam in ["NAME", "NAMES"]: - subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - debug(0, "%sNames of Subjects = %s" %(msg, subjects)) # might be useful in naming armatures - for i in range(len(subjects)): - subjects[i]=subjects[i].rstrip() - if subjects[i]=="": subjects[i]="Human" - elif myParam == "LABEL_PREFIXES": - prefixes = ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - debug(0, "%sMarker Prefixes = %s" %(msg, prefixes)) # to xlate marker name to that in file - for i in range(len(prefixes)): - prefixes[i]=prefixes[i].rstrip() - elif myParam== "MARKER_SETS": - marker_subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - debug(0, "%sMarker Set = %s"%(msg, marker_subjects)) # marker set that each subject was wearing - elif myParam== "MODEL_PARAM": - action= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - debug(0, "%sModel Paramter = %s"%(msg,action)) # might be a good name for the blender scene - elif myParam== "LABELS": - # named in form of subject:marker. - # the list "empties" is a corresponding list of actual empty object names that make up the cloud - markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - debug(0, "%sLABELS = %i %s"%(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points - else: debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data)) - else: - debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data)) - elif type == 1: - debug(100,"Block type %i is largely unsupported and untested."%type) - data = [] - Nparameters=datalength/abs(type) - debug(100, "Nparameters=%i"%Nparameters) - for i in range(Nparameters): - ladata,content = getNumber(content, 1) - data.append(ladata) - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data - #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - - #print "type boolean" - elif type == 2 and datalength>0: - debug(100,"Block type %i is largely unsupported and untested."%type) - data = [] - Nparameters=datalength/abs(type) - debug(100, "Nparameters=%i"%Nparameters) - for i in range(Nparameters): - ladata,content = getNumber(content, 2) - data.append(ladata) - #ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data - if dimnum>1: - #???? print "arg je comprends pas" - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data - #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension) - else: - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data - #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - #pass - #print "type integer" - elif type == 4 and datalength>0: - debug(100,"Block type %i is largely unsupported and untested."%type) - data = [] - Nparameters=datalength/abs(type) - debug(100, "Nparameters=%i"%Nparameters) - for i in range(Nparameters): - ladata,content = getFloat(content,proctype) - data.append(ladata) - if dimnum>1: - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data - #print "arg je comprends pas" - #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension) - else: - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data - #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data - else: - debug(100,"Block type %i is largely unsupported and untested."%type) - #print "error" - pass - deschars, content= getNumber(content, 1) - if deschars>0: - description = content[0:deschars] - content = content[deschars:] - ParameterGroups[GroupNumber].parameter[ParameterNumber-1].description=description - - content = content_memory - content = content[nextrec:] - - Ncharacters,content = getNumber(content, 1) - if Ncharacters>=128: - Ncharacters = -(2**8)+(Ncharacters) - GroupNumber,content = getNumber(content, 1) - if GroupNumber>=128: - GroupNumber = -(2**8)+(GroupNumber) - debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters)) - - debug(00, "***************************") - debug(00, "**** Examining Parameters ...") - debug(10, "***************************") - - if len(subjects)==0: subjects=["Test"] #well, somebody got mocapped! - for i in range(0, len(subjects)-len(prefixes)): prefixes.append("") - for i in range(0, len(subjects)-len(marker_subjects)): marker_subjects.append(subjects[i]) - - #make a markerlist if they didn't - debug(0, "%i Markers specified, %i marker names supplied" %(Nmarkers,len(markerList))) - if len(markerList)==0: - debug(0, "File missing any POINT LABELS marker list. Making defaults") - #I guess just make cloud of empty.xxx - if len(markerList)XYZ_LIMIT or abs(myy)>XYZ_LIMIT or abs(myz)>XYZ_LIMIT: - err+=1 - if err>100: - debug(0, "Warning: 100 data points for markers seem way out there") - debug(0, "data read: (%i, %i, %i)" %(x,y,z)) - debug(0, "Consider revising Scale %0.2f" % Scale) - debug(0, "which now givs coordinates: (%i, %i, %i)" %(x*Scale,y*Scale,z*Scale)) - err=-0 - if abs(myx)>XYZ_LIMIT: myx= XYZ_LIMIT*myx/abs(myx) #preserve sign - if abs(myy)>XYZ_LIMIT: myy= XYZ_LIMIT*myy/abs(myy) #preserve sign - if abs(myz)>XYZ_LIMIT: myz= XYZ_LIMIT*myz/abs(myz) #preserve sign - Markers[i][j].x = myx - Markers[i][j].y = myy - Markers[i][j].z = myz - - a,ptr_read = parseFloat(content, ptr_read, proctype) - a = int(a) - highbyte = int(a/256) - lowbyte=a-highbyte*256 - CameraInfo[i][j] = highbyte - ResidualError[i][j] = lowbyte*abs(Scale) - #Monitor marker location to ensure data block is being parsed properly - if j==0: debug(90,"Frame %i loc of %s: (%i, %i, %i)" % (i,markerList[j],myx,myy,myz)) - if i==0: debug(50, "Initial loc of %s: (%i, %i, %i)" % (markerList[j],myx,myy,myz)) - - ptr_read+=residuals #skip over the following - #for j in range (NanalogFramesPerVideoFrame): - # for k in range(NanalogChannels): - # val, content = getNumber(content, 2) - # AnalogSignals[j+NanalogFramesPerVideoFrame*(i)][k]=val #??? i-1 - #else - # for i=1:NvideoFrames - # for j=1:Nmarkers - # Markers(i,j,1:3)=fread(fid,3,'int16')'.*Scale; - # ResidualError(i,j)=fread(fid,1,'int8'); - # CameraInfo(i,j)=fread(fid,1,'int8'); - # end - # waitbar(i/NvideoFrames) - # for j=1:NanalogFramesPerVideoFrame, - # AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=... - # fread(fid,NanalogChannels,'int16')'; - # end - # end - #end - - else: #Scale is positive, but should be <1 to scale down, like 0.05 - two16= -2**16 - if len(content) < NvideoFrames*(Nmarkers*(6+2)+residuals): - error("%i bytes is not enough data for |%i frames|%i markers|%i residual" %(len(content),NvideoFrames,Nmarkers,residuals)) - #Note: I really tried to optimize this loop, since it was taking hours to process - for i in range(NvideoFrames): - if i==0: start=sys.time() - elif i==10: - tmp=(sys.time()-start)*NvideoFrames/600 - debug(0,"%i minutes remaining..." % tmp) - else: print "%i percent complete. On Frame %i Points procesed: %i\r" % (i*100/NvideoFrames,i,i*Nmarkers), - - for j in range(Nmarkers): - #x, content = getNumber(content,2) - # this is old skool signed int, not but not a short. - x = ord(content[ptr_read+0]) + (ord(content[ptr_read+1])<<8) - if x>32768: x+=two16 - y = ord(content[ptr_read+2]) + (ord(content[ptr_read+3])<<8) - if y>32768: y+=two16 - z = ord(content[ptr_read+4]) + (ord(content[ptr_read+5])<<8) - if z>32768: z+=two16 - -## -## x = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8) -## ptr_read+=2 -## if x > 32768: -## x=-(2**16)+(x) -## #y, content = getNumber(content,2) -## y = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8) -## ptr_read+=2 -## if y > 32768: -## y=-(2**16)+(y) -## #z, content = getNumber(content,2) -## z = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8) -## ptr_read+=2 -## if z > 32768: -## z=-(2**16)+(z) -## -## print "(%i=%i, %i=%i, %i=%i)" %(x,myx,y,myy,z,myz) - - # for integers, I changed Scale above to avoid getting impossible numbers - Markers[i][j].x = x*Scale - Markers[i][j].y = y*Scale - Markers[i][j].z = z*Scale - -## ResidualError[i][j], content = getNumber(content, 1) -## CameraInfo[i][j], content = getNumber(content, 1) - #try to improve performance by: - ResidualError[i][j]= ord(content[ptr_read+6]) - CameraInfo[i][j]= ord(content[ptr_read+7]) - - content= content[ptr_read+8:] - ptr_read=0 - - if j==0: debug(100,"Frame %i loc of %s: %s" % (i,markerList[j],Markers[i][j])) - if i==0: debug(50, "Initial loc of %s: (%s)" % (markerList[j],Markers[i][j])) - - #for j in range (NanalogFramesPerVideoFrame): - # for k in range(NanalogChannels): - # val, content = getNumber(content, 2) - #AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=val - ptr_read= residuals # skip over the above - print "\ndone with file." - fid.close() - - cloud= makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers) - - setupAnim(StartFrame, EndFrame,VideoFrameRate) - - debug(10, "**************************") - debug(00, "**** Making %i Armatures" % len(subjects)) - debug(10, "**************************") - for i in range(len(subjects)): - marker_set= marker_subjects[i] - success=False - if len(marker_set)>0: - for trymark in MARKER_SETS: - if trymark[0:len(marker_set)]==marker_set: - marker_set=trymark - success=True - if success: - debug(0, "Armature for %s will be put on layers %s" % (subjects[i],LAYERS_ARMOB)) - debug(0, " based on an markers beginning with %s" % prefixes[i]) - ob= make_arm(subjects[i],prefixes[i],markerList,cloud,marker_set) - else: - debug(00, "Presently, this program can automatically create a constrained armature for marker sets %s" % MARKER_SETS) - debug(00, "%s uses an unknown marker set %s" % (subjects[i],marker_set)) - debug(10, "Have a nice day! If you figure out an armature node system for this cloud, please add it to the program.") - - debug(10, "**************************") - debug(00, "**** Conclusion") - minmax=[0,0,0,0,0,0] - for i in range(NvideoFrames): - for j in range(Nmarkers): - if minmax[0]>Markers[i][j].x: minmax[0]=Markers[i][j].x - if minmax[1]>Markers[i][j].y: minmax[1]=Markers[i][j].y - if minmax[2]>Markers[i][j].z: minmax[2]=Markers[i][j].z - if minmax[3] - - a camera called "10" will become active at frame 10.
- - a camera called "10,25,185" will become active at frames 10, 25 and 185. - -Notes:
- - This script creates another script named camera.py, which is linked to the current scene.
- - If there is already a text called "camera.py", but it's from an old version or is not recognized, -you can choose if you want to rename or overwrite it. - - Script inspired by Jean-Michel (jms) Soler's:
- http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_changerdecamera.htm -""" - - -# $Id$ -# -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004-2005: Regis Montoya -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -#Script inspired of the idea of this one : -#http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_changerdecamera.htm -# -#---------------------------------------------- -# R3gis Montoya (3R) -# -# Pout tout probleme a: -# cybercreator@free.fr -# --------------------------------------------- - -import Blender -from Blender import * -import string - -header = '# camera.py 1.3 scriptlink' - -camera_change_scriptlink = header + \ -''' -import Blender -def main(): - scn = Blender.Scene.GetCurrent() - frame = str(Blender.Get('curframe')) - - # change the camera if it has the current frame - for ob_cam in [ob for ob in scn.objects if ob.type == 'Camera']: - for number in ob_cam.name.split(','): - if number == frame: - scn.setCurrentCamera(ob_cam) - return -main() -''' - -def main(): - - # Get the text - try: cam_text = Blender.Text.Get('camera.py') - except: cam_text = None - - if cam_text: - if cam_text.asLines()[0] != header: - ret = Blender.Draw.PupMenu("WARNING: An old camera.py exists%t|Overwrite|Rename old version text") - if ret == -1: return # EXIT DO NOTHING - elif ret == 1: Text.unlink(cam_text) - elif ret == 2: cam_text.name = 'old_camera.txt' - cam_text = None - - if not cam_text: - scripting=Blender.Text.New('camera.py') - scripting.write(camera_change_scriptlink) - - scn=Scene.GetCurrent() - scriptlinks = scn.getScriptLinks('FrameChanged') - if not scriptlinks or ('camera.py' not in scriptlinks): - scn.addScriptLink('camera.py','FrameChanged') - Blender.Draw.PupMenu('FrameChange Scriptlink Added%t|Name camera objects to their activation frame numbers(s) seperated by commas|valid names are "1,10,46" or "1,10,200" or "200" (without quotation marks)') - Blender.Window.RedrawAll() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/release/scripts/config.py b/release/scripts/config.py deleted file mode 100644 index cbf8e272b91..00000000000 --- a/release/scripts/config.py +++ /dev/null @@ -1,801 +0,0 @@ -#!BPY - -""" -Name: 'Scripts Config Editor' -Blender: 236 -Group: 'System' -Tooltip: 'View and edit available scripts configuration data' -""" - -__author__ = "Willian P. Germano" -__version__ = "0.1 2005/04/14" -__email__ = ('scripts', 'Author, wgermano:ig*com*br') -__url__ = ('blender', 'blenderartists.org') - -__bpydoc__ ="""\ -This script can be used to view and edit configuration data stored -by other scripts. - -Technical: this data is saved as dictionary keys with the -Blender.Registry module functions. It is persistent while Blender is -running and, if the script's author chose to, is also saved to a file -in the scripts config data dir. - -Usage: - -- Start Screen: - -To access any available key, select it from (one of) the menu(s). - -Hotkeys:
- ESC or Q: [Q]uit
- H: [H]elp - -- Keys Config Screen: - -This screen exposes the configuration data for the chosen script key. If the -buttons don't fit completely on the screen, you can scroll up or down with -arrow keys or a mouse wheel. Leave the mouse pointer over any button to get -a tooltip about that option. - -Any change can be reverted -- unless you have already applied it. - -If the key is already stored in a config file, there will be a toggle button -(called 'file') that controls whether the changes will be written back to -the file or not. If you just want to change the configuration for the current -session, simply unset that button. Note, though, that data from files has -precedence over those keys already loaded in Blender, so if you re-run this -config editor, unsaved changes will not be seen. - -Hotkeys:
- ESC: back to Start Screen
- Q: [Q]uit
- U: [U]ndo changes
- ENTER: apply changes (can't be reverted, then)
- UP, DOWN Arrows and mouse wheel: scroll text up / down - -Notes: - -a) Available keys are determined by which scripts you use. If the key you -expect isn't available (or maybe there are none or too few keys), either the -related script doesn't need or still doesn't support this feature or the key -has not been stored yet, in which case you just need to run that script once -to make its config data available. - -b) There are two places where config data files can be saved: the -bpydata/config/ dir (1) inside the default scripts dir or (2) inside the user -defined Python scripts dir -(User Preferences window -> File Paths tab -> Python path). If available, -(2) is the default and also the recommended option, because then fresh Blender -installations won't delete your config data. To use this option, simply set a -dir for Python scripts at the User Preferences window and make sure this dir -has the subdirs bpydata/ and bpydata/config/ inside it. - -c) The key called "General" in the "Other" menu has general config options. -All scripts where that data is relevant are recommended to access it and set -behaviors accordingly. -""" - -# $Id$ -# -# -------------------------------------------------------------------------- -# config.py version 0.1 2005/04/08 -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender import Draw, BGL, Registry, Window, sys as bsys -from Blender.Window import Theme -from BPyRegistry import LoadConfigData, SaveConfigData, HasConfigData,\ - BPY_KEY_IN_FILE - -MAX_STR_LEN = 300 # max length for a string -MAX_ITEMS_NUM = 100 # max number for each type of button - -# --- -# The "General" configure options key is managed from this script. -verbose = True -confirm_overwrite = True - -tooltips = { - 'verbose': 'print script messages (info, warnings, errors) to the console', - 'confirm_overwrite': 'scripts should always confirm before overwriting files' -} - -CFG_LIST = ['verbose', 'confirm_overwrite', 'tooltips'] -KEY_NAME = 'General' - -def update_registry(): - rd = {} - for var in CFG_LIST: - exec("rd['%s']=%s" % (var, var)) - Registry.SetKey(KEY_NAME, rd, True) - -rd = Registry.GetKey('General', True) -if rd: - try: - for var in CFG_LIST[:-1]: # no need to update tooltips - exec("%s=rd['%s']" % (var, var)) - except: update_registry() - -else: - update_registry() -# --- - -# script globals: -CFGKEY = '' -LABELS = [] -GD = {} # groups dict (includes "Other" for unmapped keys) -INDEX = 0 # to pass button indices to fs callbacks -FREEKEY_IDX = 0 # index of set of keys not mapped to a script name -KEYMENUS = [] -ALL_SCRIPTS = {} -ALL_GROUPS = [] -START_SCREEN = 0 -CONFIG_SCREEN = 1 -DISK_UPDATE = True # write changed data to its config file - -ACCEPTED_TYPES = [bool, int, float, str, unicode] - -SCREEN = START_SCREEN - -SCROLL_DOWN = 0 - -# events: -BEVT_START = 50 -BEVT_EXIT = 0 + BEVT_START -BEVT_BACK = 1 + BEVT_START -BEVT_DISK = 2 + BEVT_START -BEVT_CANCEL = 3 + BEVT_START -BEVT_APPLY = 4 + BEVT_START -BEVT_HELP = 5 + BEVT_START -BEVT_DEL = 6 + BEVT_START -BEVT_KEYMENU = [] -BUT_KEYMENU = [] -BEVT_BOOL = 100 -BEVT_INT = BEVT_BOOL + MAX_ITEMS_NUM -BEVT_FLOAT = BEVT_BOOL + 2*MAX_ITEMS_NUM -BEVT_STR = BEVT_BOOL + 3*MAX_ITEMS_NUM -BEVT_BROWSEDIR = BEVT_BOOL + 4*MAX_ITEMS_NUM -BEVT_BROWSEFILE = BEVT_BOOL + 5*MAX_ITEMS_NUM -BUT_TYPES = { - bool: 0, - int: 0, - float: 0, - str: 0 -} - -# Function definitions: - -def get_keys(): - LoadConfigData() # loads all data from files in (u)scripts/bpydata/config/ - return [k for k in Registry.Keys() if k[0] != "_"] - - -def show_help(script = 'config.py'): - Blender.ShowHelp(script) - - -def fs_dir_callback(pathname): - global CFGKEY, INDEX - - pathname = bsys.dirname(pathname) - datatypes = CFGKEY.sorteddata - datatypes[str][INDEX][1] = pathname - - -def fs_file_callback(pathname): - global CFGKEY, INDEX - - datatypes = CFGKEY.sorteddata - datatypes[str][INDEX][1] = pathname - - -# parse Bpymenus file to get all script filenames -# (used to show help for a given key) -def fill_scripts_dict(): - global ALL_SCRIPTS, ALL_GROUPS - - group = '' - group_len = 0 - sep = bsys.sep - home = Blender.Get('homedir') - if not home: - errmsg = """ -Can't find Blender's home dir and so can't find the -Bpymenus file automatically stored inside it, which -is needed by this script. Please run the -Help -> System -> System Information script to get -information about how to fix this. -""" - raise SystemError, errmsg - fname = bsys.join(home, 'Bpymenus') - if not bsys.exists(fname): return False - f = file(fname, 'r') - lines = f.readlines() - f.close() - for l in lines: - if l.rfind('{') > 0: - group = l.split()[0] - ALL_GROUPS.append(group) - group_len += 1 - continue - elif l[0] != "'": continue - fields = l.split("'") - if len(fields) > 2: - menuname = fields[1].replace('...','') - fields = fields[2].split() - if len(fields) > 1: - fname = fields[1].split(sep)[-1] - i = 1 - while not fname.endswith('.py'): - i += 1 - fname = "%s %s" % (fname, fields[i]) - ALL_SCRIPTS[fname] = (menuname, group_len - 1) - return True - - -def map_to_registered_script(name): - global ALL_SCRIPTS - - if not name.endswith('.py'): - name = "%s.py" % name - if ALL_SCRIPTS.has_key(name): - return ALL_SCRIPTS[name] # == (menuname, group index) - return None - - -def reset(): - global LABELS, GD, KEYMENUS, KEYS - - # init_data is recalled when a key is deleted, so: - LABELS = [] - GD = {} - KEYMENUS = [] - KEYS = get_keys() - - -# gather all script info, fill gui menus -def init_data(): - global KEYS, GD, ALL_GROUPS, ALL_SCRIPTS, KEYMENUS, LABELS - global BUT_KEYMENU, BEVT_KEYMENU, FREEKEY_IDX - - for k in ALL_GROUPS: - GD[k] = [] - GD[None] = [] - - for k in KEYS: - res = map_to_registered_script(k) - if res: - GD[ALL_GROUPS[res[1]]].append((k, res[0])) - else: GD[None].append((k, k)) - - for k in GD.keys(): - if not GD[k]: GD.pop(k) - - if GD.has_key(None): - GD['Other'] = GD[None] - GD.pop(None) - FREEKEY_IDX = -1 - - BUT_KEYMENU = range(len(GD)) - - for k in GD.keys(): - kmenu = ['Configuration Keys: %s%%t' % k] - for j in GD[k]: - kmenu.append(j[1]) - kmenu = "|".join(kmenu) - KEYMENUS.append(kmenu) - LABELS.append(k) - - if FREEKEY_IDX < 0: - FREEKEY_IDX = LABELS.index('Other') - - length = len(KEYMENUS) - BEVT_KEYMENU = range(1, length + 1) - BUT_KEYMENU = range(length) - - -# for theme colors: -def float_colors(cols): - return map(lambda x: x / 255.0, cols) - - - -class Config: - - def __init__(self, key, has_group = True): - global DISK_UPDATE - - self.key = key - self.has_group = has_group - self.name = key - self.fromdisk = HasConfigData(key) & BPY_KEY_IN_FILE - if not self.fromdisk: DISK_UPDATE = False - else: DISK_UPDATE = True - - self.origdata = Registry.GetKey(key, True) - data = self.data = self.origdata.copy() - - if not data: - Draw.PupMenu('ERROR: couldn\'t find requested data') - self.data = None - return - - keys = data.keys() - nd = {} - for k in keys: - nd[k.lower()] = k - - if nd.has_key('tooltips'): - ndval = nd['tooltips'] - self.tips = data[ndval] - data.pop(ndval) - else: self.tips = 0 - - if nd.has_key('limits'): - ndval = nd['limits'] - self.limits = data[ndval] - data.pop(ndval) - else: self.limits = 0 - - if self.has_group: - scriptname = key - if not scriptname.endswith('.py'): - scriptname = "%s.py" % scriptname - elif nd.has_key('script'): - ndval = nd['script'] - scriptname = data[ndval] - data.pop(ndval) - if not scriptname.endswith('.py'): - scriptname = "%s.py" % scriptname - else: scriptname = None - - self.scriptname = scriptname - - self.sort() - - - def needs_update(self): # check if user changed data - data = self.data - new = self.sorteddata - - for vartype in new.keys(): - for i in new[vartype]: - if data[i[0]] != i[1]: return 1 - - return 0 # no changes - - - def update(self): # update original key - global DISK_UPDATE - - data = self.data - odata = self.origdata - new = self.sorteddata - for vartype in new.keys(): - for i in new[vartype]: - if data[i[0]] != i[1]: data[i[0]] = i[1] - if odata[i[0]] != i[1]: odata[i[0]] = i[1] - - if DISK_UPDATE: Registry.SetKey(self.key, odata, True) - - def delete(self): - global DISK_UPDATE - - delmsg = 'OK?%t|Delete key from memory' - if DISK_UPDATE: - delmsg = "%s and from disk" % delmsg - if Draw.PupMenu(delmsg) == 1: - Registry.RemoveKey(self.key, DISK_UPDATE) - return True - - return False - - - def revert(self): # revert to original key - data = self.data - new = self.sorteddata - for vartype in new.keys(): - for i in new[vartype]: - if data[i[0]] != i[1]: i[1] = data[i[0]] - - - def sort(self): # create a new dict with types as keys - global ACCEPTED_TYPES, BUT_TYPES - - data = self.data - datatypes = {} - keys = [k for k in data.keys() if k[0] != '_'] - for k in keys: - val = data[k] - tval = type(val) - if tval not in ACCEPTED_TYPES: continue - if not datatypes.has_key(tval): - datatypes[tval] = [] - datatypes[type(val)].append([k, val]) - if datatypes.has_key(unicode): - if not datatypes.has_key(str): datatypes[str] = datatypes[unicode] - else: - for i in datatypes[unicode]: datatypes[str].append(i) - datatypes.pop(unicode) - for k in datatypes.keys(): - dk = datatypes[k] - dk.sort() - dk.reverse() - BUT_TYPES[k] = range(len(dk)) - self.sorteddata = datatypes - - -# GUI: - -# gui callbacks: - -def gui(): # drawing the screen - - global SCREEN, START_SCREEN, CONFIG_SCREEN, KEYMENUS, LABELS - global BEVT_KEYMENU, BUT_KEYMENU, CFGKEY - global BUT_TYPES, SCROLL_DOWN, VARS_NUM - - WIDTH, HEIGHT = Window.GetAreaSize() - - theme = Theme.Get()[0] - tui = theme.get('ui') - ttxt = theme.get('text') - - COL_BG = float_colors(ttxt.back) - COL_TXT = ttxt.text - COL_TXTHI = ttxt.text_hi - - BGL.glClearColor(COL_BG[0],COL_BG[1],COL_BG[2],COL_BG[3]) - BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) - BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2]) - - if SCREEN == START_SCREEN: - x = 10 - y = 10 - h = 20 - w = 90 - BGL.glRasterPos2i(x, y) - Draw.Text('Select a configuration key to access it. Press Q or ESC to leave.') - km_len = len(KEYMENUS) - km_columns = (WIDTH - x) / w - if km_columns == 0: km_rows = km_len - else: - km_rows = km_len / km_columns - if (km_len % km_columns): km_rows += 1 - if km_rows == 0: km_rows = 1 - ystart = y + 2*h*km_rows - if ystart > (HEIGHT - 70): ystart = HEIGHT - 70 - y = ystart - column = 1 - for i, km in enumerate(KEYMENUS): - column += 1 - BGL.glRasterPos2i(x + 2, y + h + 5) - Draw.Text(LABELS[i]) - BUT_KEYMENU[i] = Draw.Menu(km, BEVT_KEYMENU[i], - x, y, w - 10, h, 0, 'Choose a key to access its configuration data') - if column > km_columns: - column = 1 - y -= 2*h - if y < 35: break - x = 10 - else: x += w - x = 10 - y = 50 + ystart - BGL.glColor3ub(COL_TXTHI[0], COL_TXTHI[1], COL_TXTHI[2]) - BGL.glRasterPos2i(x, y) - Draw.Text('Scripts Configuration Editor') - Draw.PushButton('help', BEVT_HELP, x, 22, 45, 16, - 'View help information about this script (hotkey: H)') - - elif SCREEN == CONFIG_SCREEN: - x = y = 10 - h = 18 - data = CFGKEY.sorteddata - tips = CFGKEY.tips - fromdisk = CFGKEY.fromdisk - limits = CFGKEY.limits - VARS_NUM = 0 - for k in data.keys(): - VARS_NUM += len(data[k]) - lines = VARS_NUM + 5 # to account for header and footer - y = lines*h - if y > HEIGHT - 20: y = HEIGHT - 20 - BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2]) - BGL.glRasterPos2i(x, y) - Draw.Text('Scripts Configuration Editor') - y -= 20 - BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2]) - txtsize = 10 - if HEIGHT < lines*h: - BGL.glRasterPos2i(10, 5) - txtsize += Draw.Text('Arrow keys or mouse wheel to scroll, ') - BGL.glRasterPos2i(txtsize, 5) - Draw.Text('Q or ESC to return.') - BGL.glRasterPos2i(x, y) - Draw.Text('Key: "%s"' % CFGKEY.name) - bh = 16 - bw = 45 - by = 16 - i = -1 - if CFGKEY.scriptname: - i = 0 - Draw.PushButton('help', BEVT_HELP, x, by, bw, bh, - 'Show documentation for the script that owns this key (hotkey: H)') - Draw.PushButton('back', BEVT_BACK, x + (1+i)*bw, by, bw, bh, - 'Back to config keys selection screen (hotkey: ESC)') - Draw.PushButton('exit', BEVT_EXIT, x + (2+i)*bw, by, bw, bh, - 'Exit from Scripts Config Editor (hotkey: Q)') - Draw.PushButton('revert', BEVT_CANCEL, x + (3+i)*bw, by, bw, bh, - 'Revert data to original values (hotkey: U)') - Draw.PushButton('apply', BEVT_APPLY, x + (4+i)*bw, by, bw, bh, - 'Apply changes, if any (hotkey: ENTER)') - delmsg = 'Delete this data key from memory' - if fromdisk: delmsg = "%s and from disk" % delmsg - Draw.PushButton('delete', BEVT_DEL, x + (5+i)*bw, by, bw, bh, - '%s (hotkey: DELETE)' % delmsg) - if fromdisk: - Draw.Toggle("file", BEVT_DISK, x + 3 + (6+i)*bw, by, bw, bh, DISK_UPDATE, - 'Update also the file where this config key is stored') - i = -1 - top = -1 - y -= 20 - yend = 30 - if data.has_key(bool) and y > 0: - lst = data[bool] - for l in lst: - top += 1 - i += 1 - if top < SCROLL_DOWN: continue - y -= h - if y < yend: break - w = 20 - tog = data[bool][i][1] - if tips and tips.has_key(l[0]): tooltip = tips[l[0]] - else: tooltip = "click to toggle" - BUT_TYPES[bool][i] = Draw.Toggle("", BEVT_BOOL + i, - x, y, w, h, tog, tooltip) - BGL.glRasterPos2i(x + w + 3, y + 5) - Draw.Text(l[0].lower().replace('_', ' ')) - i = -1 - y -= 5 - if data.has_key(int) and y > 0: - lst = data[int] - for l in lst: - w = 70 - top += 1 - i += 1 - if top < SCROLL_DOWN: continue - y -= h - if y < yend: break - val = data[int][i][1] - if limits: min, max = limits[l[0]] - else: min, max = 0, 10 - if tips and tips.has_key(l[0]): tooltip = tips[l[0]] - else: tooltip = "click / drag to change" - BUT_TYPES[int][i] = Draw.Number("", BEVT_INT + i, - x, y, w, h, val, min, max, tooltip) - BGL.glRasterPos2i(x + w + 3, y + 3) - Draw.Text(l[0].lower().replace('_', ' ')) - i = -1 - y -= 5 - if data.has_key(float) and y > 0: - lst = data[float] - for l in lst: - w = 70 - top += 1 - i += 1 - if top < SCROLL_DOWN: continue - y -= h - if y < yend: break - val = data[float][i][1] - if limits: min, max = limits[l[0]] - else: min, max = 0.0, 1.0 - if tips and tips.has_key(l[0]): tooltip = tips[l[0]] - else: tooltip = "click and drag to change" - BUT_TYPES[float][i] = Draw.Number("", BEVT_FLOAT + i, - x, y, w, h, val, min, max, tooltip) - BGL.glRasterPos2i(x + w + 3, y + 3) - Draw.Text(l[0].lower().replace('_', ' ')) - i = -1 - y -= 5 - if data.has_key(str) and y > 0: - lst = data[str] - for l in lst: - top += 1 - i += 1 - if top < SCROLL_DOWN: continue - y -= h - if y < yend: break - name = l[0].lower() - is_dir = is_file = False - if name.find('_dir', -4) > 0: is_dir = True - elif name.find('_file', -5) > 0: is_file = True - w = WIDTH - 20 - wbrowse = 50 - if is_dir and w > wbrowse: w -= wbrowse - if tips and tips.has_key(l[0]): tooltip = tips[l[0]] - else: tooltip = "click to write a new string" - name = name.replace('_',' ') + ': ' - if len(l[1]) > MAX_STR_LEN: - l[1] = l[1][:MAX_STR_LEN] - BUT_TYPES[str][i] = Draw.String(name, BEVT_STR + i, - x, y, w, h, l[1], MAX_STR_LEN, tooltip) - if is_dir: - Draw.PushButton('browse', BEVT_BROWSEDIR + i, x+w+1, y, wbrowse, h, - 'click to open a file selector (pick any file in the desired dir)') - elif is_file: - Draw.PushButton('browse', BEVT_BROWSEFILE + i, x + w + 1, y, 50, h, - 'click to open a file selector') - - -def fit_scroll(): - global SCROLL_DOWN, VARS_NUM - max = VARS_NUM - 1 # so last item is always visible - if SCROLL_DOWN > max: - SCROLL_DOWN = max - elif SCROLL_DOWN < 0: - SCROLL_DOWN = 0 - - -def event(evt, val): # input events - - global SCREEN, START_SCREEN, CONFIG_SCREEN - global SCROLL_DOWN, CFGKEY - - if not val: return - - if evt == Draw.ESCKEY: - if SCREEN == START_SCREEN: Draw.Exit() - else: - if CFGKEY.needs_update(): - if Draw.PupMenu('UPDATE?%t|Data was changed') == 1: - CFGKEY.update() - SCREEN = START_SCREEN - SCROLL_DOWN = 0 - Draw.Redraw() - return - elif evt == Draw.QKEY: - if SCREEN == CONFIG_SCREEN and CFGKEY.needs_update(): - if Draw.PupMenu('UPDATE?%t|Data was changed') == 1: - CFGKEY.update() - Draw.Exit() - return - elif evt == Draw.HKEY: - if SCREEN == START_SCREEN: show_help() - elif CFGKEY.scriptname: show_help(CFGKEY.scriptname) - return - - elif SCREEN == CONFIG_SCREEN: - if evt in [Draw.DOWNARROWKEY, Draw.WHEELDOWNMOUSE]: - SCROLL_DOWN += 1 - fit_scroll() - elif evt in [Draw.UPARROWKEY, Draw.WHEELUPMOUSE]: - SCROLL_DOWN -= 1 - fit_scroll() - elif evt == Draw.UKEY: - if CFGKEY.needs_update(): - CFGKEY.revert() - elif evt == Draw.RETKEY or evt == Draw.PADENTER: - if CFGKEY.needs_update(): - CFGKEY.update() - elif evt == Draw.DELKEY: - if CFGKEY.delete(): - reset() - init_data() - SCREEN = START_SCREEN - SCROLL_DOWN = 0 - else: return - Draw.Redraw() - - -def button_event(evt): # gui button events - - global SCREEN, START_SCREEN, CONFIG_SCREEN, CFGKEY, DISK_UPDATE - global BEVT_KEYMENU, BUT_KEYMENU, BUT_TYPES, SCROLL_DOWN, GD, INDEX - global BEVT_EXIT, BEVT_BACK, BEVT_APPLY, BEVT_CANCEL, BEVT_HELP, FREEKEY_IDX - - if SCREEN == START_SCREEN: - for e in BEVT_KEYMENU: - if evt == e: - index = e - 1 - k = BUT_KEYMENU[index].val - 1 - CFGKEY = Config(GD[LABELS[index]][k][0], index != FREEKEY_IDX) - if CFGKEY.data: - SCREEN = CONFIG_SCREEN - Draw.Redraw() - return - if evt == BEVT_EXIT: - Draw.Exit() - elif evt == BEVT_HELP: - show_help() - return - - elif SCREEN == CONFIG_SCREEN: - datatypes = CFGKEY.sorteddata - if evt >= BEVT_BROWSEFILE: - INDEX = evt - BEVT_BROWSEFILE - Window.FileSelector(fs_file_callback, 'Choose file') - elif evt >= BEVT_BROWSEDIR: - INDEX = evt - BEVT_BROWSEDIR - Window.FileSelector(fs_dir_callback, 'Choose any file') - elif evt >= BEVT_STR: - var = BUT_TYPES[str][evt - BEVT_STR].val - datatypes[str][evt - BEVT_STR][1] = var - elif evt >= BEVT_FLOAT: - var = BUT_TYPES[float][evt - BEVT_FLOAT].val - datatypes[float][evt - BEVT_FLOAT][1] = var - elif evt >= BEVT_INT: - var = BUT_TYPES[int][evt - BEVT_INT].val - datatypes[int][evt - BEVT_INT][1] = var - elif evt >= BEVT_BOOL: - var = datatypes[bool][evt - BEVT_BOOL][1] - if var == True: var = False - else: var = True - datatypes[bool][evt - BEVT_BOOL][1] = var - - elif evt == BEVT_BACK: - if SCREEN == CONFIG_SCREEN: - SCREEN = START_SCREEN - SCROLL_DOWN = 0 - Draw.Redraw() - elif evt == BEVT_EXIT: - if CFGKEY.needs_update(): - if Draw.PupMenu('UPDATE?%t|Data was changed') == 1: - CFGKEY.update() - Draw.Exit() - return - elif evt == BEVT_APPLY: - if CFGKEY.needs_update(): - CFGKEY.update() - elif evt == BEVT_CANCEL: - if CFGKEY.needs_update(): - CFGKEY.revert() - elif evt == BEVT_DEL: - if CFGKEY.delete(): - reset() - init_data() - SCREEN = START_SCREEN - SCROLL_DOWN = 0 - elif evt == BEVT_DISK: - if DISK_UPDATE: DISK_UPDATE = False - else: DISK_UPDATE = True - elif evt == BEVT_HELP: - show_help(CFGKEY.scriptname) - return - else: - return - Draw.Redraw() - -# End of definitions - - -KEYS = get_keys() - -if not KEYS: - Draw.PupMenu("NO DATA: please read this help screen") - Blender.ShowHelp('config.py') -else: - fill_scripts_dict() - init_data() - Draw.Register(gui, event, button_event) diff --git a/release/scripts/console.py b/release/scripts/console.py deleted file mode 100644 index c6ae22a86f5..00000000000 --- a/release/scripts/console.py +++ /dev/null @@ -1,861 +0,0 @@ -#!BPY - -""" -Name: 'Interactive Python Console' -Blender: 245 -Group: 'System' -Tooltip: 'Interactive Python Console' -""" - -__author__ = "Campbell Barton aka ideasman42" -__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"] -__bpydoc__ = """\ -This is an interactive console, similar to Python's own command line interpreter. Since it is embedded in Blender, it has access to all Blender Python modules. - -Those completely new to Python are recommended to check the link button above -that points to its official homepage, with news, downloads and documentation. - -Usage:
- Type your code and hit "Enter" to get it executed.
- - Right mouse click: Console Menu (Save output, etc);
- - Mousewheel: Scroll text - - Arrow keys: command history and cursor;
- - Shift + Backspace: Backspace whole word;
- - Shift + Arrow keys: jump words;
- - Ctrl + (+/- or mousewheel): Zoom text size;
- - Ctrl + Enter: auto compleate based on variable names and modules loaded -- multiple choices popup a menu;
- - Shift + Enter: multiline functions -- delays executing code until only Enter is pressed. -""" - -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -import bpy -from Blender import * -import sys as python_sys -import StringIO - -# Constants -__DELIMETERS__ = '. ,=+-*/%<>&~][{}():\t' -__VARIABLE_DELIMETERS__ = ' ,=+-*/%<>&~{}():\t' - -__LINE_HISTORY__ = 500 - -global __FONT_SIZE__ - -__FONT_SIZES__ = ( ('tiny', 10), ('small', 12), ('normalfix', 14), ('large', 16) ) -__FONT_SIZE__ = 2 # index for the list above, normal default. - -global __CONSOLE_LINE_OFFSET__ -__CONSOLE_LINE_OFFSET__ = 0 - -cmdBuffer = [] # dosnt need to be global - -''' -# Generic Blender functions -def getActScriptWinRect(): - area = Window.GetAreaSize() - area = (area[0]-1, area[1]-1) - for scrInfo in Window.GetScreenInfo(Window.Types['SCRIPT'], 'win', ''): - if scrInfo['vertices'][2]-scrInfo['vertices'][0] == area[0]: - if scrInfo['vertices'][3]-scrInfo['vertices'][1] == area[1]: - return scrInfo['vertices'] - return None -''' - - -# menuText, # per group -def PupMenuLess(menu, groupSize=35): - more = [' more...'] - less = [' less...'] - - menuList= menu.split('|') - - # No Less Needed, just call. - if len(menuList) < groupSize: - return Draw.PupMenu(menu) - - title = menuList[0].split('%t')[0] - - # Split the list into groups - menuGroups = [[]] - for li in menuList[1:]: - if len(menuGroups[-1]) < groupSize: - menuGroups[-1].append(li) - else: - menuGroups.append([li]) - - # Stores teh current menu group we are looking at - groupIdx = 0 - while 1: - # Give us a title with the menu number - numTitle = [ ' '.join([title, str(groupIdx + 1), 'of', str(len(menuGroups)), '%t'])] - if groupIdx == 0: - menuString = '|'.join(numTitle + menuGroups[groupIdx] + more) - elif groupIdx == len(menuGroups)-1: - menuString = '|'.join(numTitle + less + menuGroups[groupIdx]) - else: # In the middle somewhere so Show a more and less - menuString = '|'.join(numTitle + less + menuGroups[groupIdx] + more) - result = Draw.PupMenu(menuString) - # User Exit - if result == -1: - return -1 - - if groupIdx == 0: # First menu - if result-1 < groupSize: - return result - else: # must be more - groupIdx +=1 - elif groupIdx == len(menuGroups): # Last Menu - if result == 1: # Must be less - groupIdx -= 1 - else: # Must be a choice - return result + (groupIdx*groupSize) - - else: - if result == 1: # Must be less - groupIdx -= 1 - elif result-2 == groupSize: - groupIdx +=1 - else: - return result - 1 + (groupIdx*groupSize) - - - -# Use newstyle classes, Im not bothering with inheretence -# but slots are faster. -class cmdLine(object): - __slots__ = [\ - 'cmd', # is the command string, or any other message - 'type',# type: 0:user input 1:program feedback 2:error message. 3:option feedback - 'exe' # 0- not yet executed 1:executed - ] - def __init__(self, cmd, type, exe): - self.cmd = cmd - self.type = type - self.exe = exe - -# Include external file with internal namespace -def include(filename): - file = open(filename, 'r') - filedata = file.read() - file.close() - return compile(filedata, filename, 'exec') - -# Writes command line data to a blender text file. -def writeCmdData(type): - newText = Text.New('command_output.py', 1) - if type == 3: newText.write('\n'.join( [ myCmd.cmd for myCmd in cmdBuffer ] )) - else: newText.write('\n'.join( [ myCmd.cmd for myCmd in cmdBuffer if myCmd.type is type] )) - Draw.PupMenu('%s written' % newText.name) - -def insertCmdData(): - texts = list(bpy.data.texts) - textNames = [tex.name for tex in texts] - if textNames: - choice = Draw.PupMenu('|'.join(textNames)) - if choice != -1: - text = texts[choice-1] - - # Add the text! - for l in text.asLines(): - cmdBuffer.append(cmdLine('%s ' % l, 0, 0)) - Draw.Redraw() - - -COLLECTED_VAR_NAMES = {} # a list of keys, each key has a list of absolute paths - -# Pain and simple recursice dir(), accepts a string -unused_types = str, dict, list, float, int, str, type, tuple, type(dir), type(None) -def rdir(dirString, depth=0): - #print ' ' * depth, dirString - # MAX DEPTH SET HERE - if depth > 5: - # print 'maxdepoth reached.' - return - - global COLLECTED_VAR_NAMES - dirStringSplit = dirString.split('.') - - exec('value=' + dirString) - - if type(value) in unused_types: - # print 'bad type' - return - dirList = dir(value) - - for dirItem in dirList: - if dirItem.startswith('_'): - continue - - dirData = None - try: - # Rare cases this can mess up, material.shader was a problem. - exec('dirData = %s.%s' % (dirString, dirItem)) - #print dirData - except: - # Dont bother with this data. - continue - #print 'HEY', dirData, dirItem - #if type(dirItem) != str: - # print dirItem, type(dirItem) - - if dirItem not in COLLECTED_VAR_NAMES: # .keys() - COLLECTED_VAR_NAMES[dirItem] = [] - - # Add the string - # splitD = dirString.split('"')[-2] - - # Example of dirString - # __CONSOLE_VAR_DICT__["Main"].scenes.active.render - - # Works but can be faster - # splitD = dirString.replace('__CONSOLE_VAR_DICT__["', '').replace('"]', '') - - splitD = dirString[22:].replace('"]', '') - - if splitD not in COLLECTED_VAR_NAMES[dirItem]: - # print dirItem, dirString, splitD, - COLLECTED_VAR_NAMES[dirItem].append(splitD) - - - # Stops recursice stuff, overlooping - #print type(dirItem) - #if type(dirData) == types.ClassType or \ - # type(dirData) == types.ModuleType: - type_dirData = type(dirData) - if type_dirData not in unused_types: - # print type(dirData), dirItem - # Dont loop up dirs for strings ints etc. - if dirItem not in dirStringSplit: - rdir( '%s.%s' % (dirString, dirItem), depth+1) - ''' - elif depth == 0: # Add local variables - # print type(dirData), dirItem - # Dont loop up dirs for strings ints etc. - if dirItem not in dirStringSplit: - rdir( '%s.%s' % (dirString, dirItem), depth+1) - ''' - -def recursive_dir(): - global COLLECTED_VAR_NAMES - - for name in __CONSOLE_VAR_DICT__: # .keys() - if not name.startswith('_'): # Dont pick names like __name__ - rdir('__CONSOLE_VAR_DICT__["%s"]' % name) - #print COLLECTED_VAR_NAMES - COLLECTED_VAR_NAMES[name] = [''] - return COLLECTED_VAR_NAMES - -# Runs the code line(s) the user has entered and handle errors -# As well as feeding back the output into the blender window. -def runUserCode(__USER_CODE_STRING__): - global __CONSOLE_VAR_DICT__ # We manipulate the variables here. loading and saving from localspace to this global var. - - # Open A File like object to write all output to, that would useually be printed. - python_sys.stdout.flush() # Get rid of whatever came before - __FILE_LIKE_STRING__ = StringIO.StringIO() # make a new file like string, this saves up from making a file. - __STD_OUTPUT__ = python_sys.stdout # we need to store the normal output. - python_sys.stdout=__FILE_LIKE_STRING__ # Now anything printed will be written to the file like string. - - # Try and run the user entered line(s) - try: - # Load all variabls from global dict to local space. - __TMP_VAR_NAME__ = __TMP_VAR__ = '' # so as not to raise an error when del'ing - - for __TMP_VAR_NAME__, __TMP_VAR__ in __CONSOLE_VAR_DICT__.items(): - exec('%s%s' % (__TMP_VAR_NAME__,'=__TMP_VAR__')) - del __TMP_VAR_NAME__ - del __TMP_VAR__ - - # Now all the vars are loaded, execute the code. # Newline thanks to phillip, - exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'single')) #exec(compile(__USER_CODE_STRING__, 'blender_cmd.py', 'exec')) - - # Flush global dict, allow the user to remove items. - __CONSOLE_VAR_DICT__ = {} - - __TMP_VAR_NAME__ = '' # so as not to raise an error when del'ing - # Write local veriables to global __CONSOLE_VAR_DICT__ - for __TMP_VAR_NAME__ in dir(): - if __TMP_VAR_NAME__ != '__FILE_LIKE_STRING__' and\ - __TMP_VAR_NAME__ != '__STD_OUTPUT__' and\ - __TMP_VAR_NAME__ != '__TMP_VAR_NAME__' and\ - __TMP_VAR_NAME__ != '__USER_CODE_STRING__': - - # Execute the local > global coversion. - exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__)) - del __TMP_VAR_NAME__ - - except: # Prints the REAL exception. - error = '%s: %s' % (python_sys.exc_type, python_sys.exc_value) - for errorLine in error.split('\n'): - cmdBuffer.append(cmdLine(errorLine, 2, None)) # new line to type into - - python_sys.stdout = __STD_OUTPUT__ # Go back to output to the normal blender console - - # Copy all new output to cmdBuffer - - __FILE_LIKE_STRING__.seek(0) # the readline function requires that we go back to the start of the file. - - for line in __FILE_LIKE_STRING__.readlines(): - cmdBuffer.append(cmdLine(line, 1, None)) - - cmdBuffer.append(cmdLine(' ', 0, 0)) # new line to type into - python_sys.stdout=__STD_OUTPUT__ - __FILE_LIKE_STRING__.close() - - - - - -#------------------------------------------------------------------------------# -# event handling code # -#------------------------------------------------------------------------------# -def handle_event(evt, val): - - # Insert Char into the cammand line - def insCh(ch): # Instert a char - global cursor - # Later account for a cursor variable - cmdBuffer[-1].cmd = ('%s%s%s' % ( cmdBuffer[-1].cmd[:cursor], ch, cmdBuffer[-1].cmd[cursor:])) - - #------------------------------------------------------------------------------# - # Define Complex Key Actions # - #------------------------------------------------------------------------------# - def actionEnterKey(): - global histIndex, cursor - - def getIndent(string): - # Gather white space to add in the previous line - # Ignore the last char since its padding. - whiteSpace = '' - #for i in range(len(cmdBuffer[-1].cmd)): - for i in xrange(len(string)-1): - if cmdBuffer[-1].cmd[i] == ' ' or cmdBuffer[-1].cmd[i] == '\t': - whiteSpace += string[i] - else: - break - return whiteSpace - - # Autocomplete - if Window.GetKeyQualifiers() & Window.Qual.CTRL: - actionAutoCompleate() - return - - # Are we in the middle of a multiline part or not? - # try be smart about it - if cmdBuffer[-1].cmd.split('#')[0].rstrip().endswith(':'): - # : indicates an indent is needed - cmdBuffer.append(cmdLine('\t%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0)) - print ': indicates an indent is needed' - - elif cmdBuffer[-1].cmd[0] in [' ', '\t'] and len(cmdBuffer[-1].cmd) > 1 and cmdBuffer[-1].cmd.split(): - # white space at the start means he havnt finished the multiline. - cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0)) - print 'white space at the start means he havnt finished the multiline.' - - elif Window.GetKeyQualifiers() & Window.Qual.SHIFT: - # Crtl forces multiline - cmdBuffer.append(cmdLine('%s ' % getIndent(cmdBuffer[-1].cmd), 0, 0)) - print 'Crtl forces multiline' - - else: # Execute multiline code block - - # Multiline code will still run with 1 line, - multiLineCode = ['if 1:'] # End of the multiline first. - - # Seek the start of the file multiline - i = 1 - while cmdBuffer[-i].exe == 0: - i+=1 - - while i > 1: - i-=1 - - if cmdBuffer[-i].cmd == ' ':# Tag as an output type so its not used in the key history - cmdBuffer[-i].type = 1 - else: # Tab added at the start for added if 1: statement - multiLineCode.append('\t%s' % cmdBuffer[-i].cmd ) - - # Mark as executed - cmdBuffer[-i].exe = 1 - - multiLineCode.append('\tpass') # reverse will make this the start. - - # Dubug, print the code that is executed. - #for m in multiLineCode: print m - - runUserCode('\n'.join(multiLineCode)) - - # Clear the output based on __LINE_HISTORY__ - if len(cmdBuffer) > __LINE_HISTORY__: - cmdBuffer[:__LINE_HISTORY__] = [] - - histIndex = cursor = -1 # Reset cursor and history - - def actionUpKey(): - global histIndex - if abs(histIndex)+1 >= len(cmdBuffer): - histIndex = -1 - - # When wrapping allow 1 plank lines - if cmdBuffer[-1].cmd != ' ': - cmdBuffer[-1].cmd = ' ' - return - - histIndex_orig = histIndex - histIndex -= 1 - - while (cmdBuffer[histIndex].type != 0 and abs(histIndex) < len(cmdBuffer)) or \ - ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd): - histIndex -= 1 - - if cmdBuffer[histIndex].type == 0: # we found one - cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd - - def actionDownKey(): - global histIndex - if histIndex >= -2: - histIndex = -len(cmdBuffer) - - # When wrapping allow 1 plank lines - if cmdBuffer[-1].cmd != ' ': - cmdBuffer[-1].cmd = ' ' - return - - histIndex_orig = histIndex - histIndex += 1 - while (cmdBuffer[histIndex].type != 0 and histIndex != -2) or \ - ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd): - - histIndex += 1 - - if cmdBuffer[histIndex].type == 0: # we found one - cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd - - def actionRightMouse(): - global __FONT_SIZE__ - choice = Draw.PupMenu('Console Menu%t|Write Input Data (white)|Write Output Data (blue)|Write Error Data (red)|Write All Text|%l|Insert Blender text|%l|Font Size|%l|Clear Output|Quit') - - if choice == 1: - writeCmdData(0) # type 0 user - elif choice == 2: - writeCmdData(1) # type 1 user output - elif choice == 3: - writeCmdData(2) # type 2 errors - elif choice == 4: - writeCmdData(3) # All - elif choice == 6: - insertCmdData() # Insert text from Blender and run it. - elif choice == 8: - # Fontsize. - font_choice = Draw.PupMenu('Font Size%t|Large|Normal|Small|Tiny') - if font_choice != -1: - if font_choice == 1: - __FONT_SIZE__ = 3 - elif font_choice == 2: - __FONT_SIZE__ = 2 - elif font_choice == 3: - __FONT_SIZE__ = 1 - elif font_choice == 4: - __FONT_SIZE__ = 0 - Draw.Redraw() - elif choice == 10: # Clear all output - cmdBuffer[:] = [cmd for cmd in cmdBuffer if cmd.type == 0] # keep user input - Draw.Redraw() - elif choice == 11: # Exit - Draw.Exit() - - - # Auto compleating, quite complex- use recutsice dir for the moment. - def actionAutoCompleate(): # Ctrl + Tab - if not cmdBuffer[-1].cmd[:cursor].split(): - return - - - RECURSIVE_DIR = recursive_dir() - - # get last name of user input - editVar = cmdBuffer[-1].cmd[:cursor] - # Split off spaces operators etc from the staryt of the command so we can use the startswith function. - for splitChar in __VARIABLE_DELIMETERS__: - editVar = editVar[:-1].split(splitChar)[-1] + editVar[-1] - - - # Now we should have the var by its self - if editVar: - possibilities = [] - - for __TMP_VAR_NAME__ in RECURSIVE_DIR: #.keys(): - #print '\t', __TMP_VAR_NAME__ - if __TMP_VAR_NAME__ == editVar: - # print 'ADITVAR IS A VAR' - pass - ''' - elif __TMP_VAR_NAME__.startswith( editVar ): - print __TMP_VAR_NAME__, 'aaa' - possibilities.append( __TMP_VAR_NAME__ ) - ''' - possibilities.append( __TMP_VAR_NAME__ ) - - if len(possibilities) == 1: - cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], possibilities[0], cmdBuffer[-1].cmd[cursor:])) - - elif possibilities: # If its not just [] - # -1 with insert is the second last. - - # Text choice - #cmdBuffer.insert(-1, cmdLine('options: %s' % ' '.join(possibilities), 3, None)) - - menuList = [] # A lits of tuples- ABSOLUTE, RELATIVE - - for __TMP_VAR_NAME__ in possibilities: - for usage in RECURSIVE_DIR[__TMP_VAR_NAME__]: - # Account for non absolute (variables for eg.) - if usage: # not '' - absName = '%s.%s' % (usage, __TMP_VAR_NAME__) - - if __TMP_VAR_NAME__.startswith(editVar): - menuList.append( # Used for names and can be entered when pressing shift. - (absName, # Absolute name - __TMP_VAR_NAME__) # Relative name, non shift - ) - - #else: - # if absName.find(editVar) != -1: - # menuList.append((__TMP_VAR_NAME__, __TMP_VAR_NAME__)) # Used for names and can be entered when pressing shift. - - # No items to display? no menu - if not menuList: - return - - menuList.sort() - - choice = PupMenuLess( # Menu for the user to choose the autocompleate - 'Choices (Shift for local name, Ctrl for Docs)%t|' + # Title Text - '|'.join(['%s, %s' % m for m in menuList])) # Use Absolute names m[0] - - if choice != -1: - if Window.GetKeyQualifiers() & Window.Qual.CTRL: # Help - cmdBuffer[-1].cmd = ('help(%s%s) ' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0])) - elif Window.GetKeyQualifiers() & Window.Qual.SHIFT: # Put in the long name - cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:])) - else: # Only paste in the Short name - cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0], cmdBuffer[-1].cmd[cursor:])) - - - else: - # print 'NO EDITVAR' - return - - # ------------------end------------------ # - - # Quit from menu only - #if (evt == Draw.ESCKEY and not val): - # Draw.Exit() - if evt == Draw.MOUSEX or evt == Draw.MOUSEY: # AVOID TOO MANY REDRAWS. - return - - - global cursor - global histIndex - global __FONT_SIZE__ - global __CONSOLE_LINE_OFFSET__ - - ascii = Blender.event - - resetScroll = True - - #------------------------------------------------------------------------------# - # key codes and key handling # - #------------------------------------------------------------------------------# - - # UP DOWN ARROW KEYS, TO TRAVERSE HISTORY - if (evt == Draw.UPARROWKEY and val): actionUpKey() - elif (evt == Draw.DOWNARROWKEY and val): actionDownKey() - - elif (evt == Draw.RIGHTARROWKEY and val): - if Window.GetKeyQualifiers() & Window.Qual.SHIFT: - wordJump = False - newCursor = cursor+1 - while newCursor<0: - - if cmdBuffer[-1].cmd[newCursor] not in __DELIMETERS__: - newCursor+=1 - else: - wordJump = True - break - if wordJump: # Did we find a new cursor pos? - cursor = newCursor - else: - cursor = -1 # end of line - else: - cursor +=1 - if cursor > -1: - cursor = -1 - - elif (evt == Draw.LEFTARROWKEY and val): - if Window.GetKeyQualifiers() & Window.Qual.SHIFT: - wordJump = False - newCursor = cursor-1 - while abs(newCursor) < len(cmdBuffer[-1].cmd): - - if cmdBuffer[-1].cmd[newCursor] not in __DELIMETERS__ or\ - newCursor == cursor: - newCursor-=1 - else: - wordJump = True - break - if wordJump: # Did we find a new cursor pos? - cursor = newCursor - else: - cursor = -len(cmdBuffer[-1].cmd) # Start of line - - else: - if len(cmdBuffer[-1].cmd) > abs(cursor): - cursor -=1 - - elif (evt == Draw.HOMEKEY and val): - cursor = -len(cmdBuffer[-1].cmd) - - elif (evt == Draw.ENDKEY and val): - cursor = -1 - - elif (evt == Draw.TABKEY and val): - insCh('\t') - - elif (evt == Draw.BACKSPACEKEY and val): - if Window.GetKeyQualifiers() & Window.Qual.SHIFT: - i = -1 - for d in __DELIMETERS__: - i = max(i, cmdBuffer[-1].cmd[:cursor-1].rfind(d)) - if i == -1: - i=0 - cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:i] , cmdBuffer[-1].cmd[cursor:])) - - else: - # Normal backspace. - cmdBuffer[-1].cmd = ('%s%s' % (cmdBuffer[-1].cmd[:cursor-1] , cmdBuffer[-1].cmd[cursor:])) - - elif (evt == Draw.DELKEY and val) and cursor < -1: - cmdBuffer[-1].cmd = cmdBuffer[-1].cmd[:cursor] + cmdBuffer[-1].cmd[cursor+1:] - cursor +=1 - - elif ((evt == Draw.RETKEY or evt == Draw.PADENTER) and val): - actionEnterKey() - - elif (evt == Draw.RIGHTMOUSE and not val): actionRightMouse(); return - - elif (evt == Draw.PADPLUSKEY or evt == Draw.EQUALKEY or evt == Draw.WHEELUPMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL: - __FONT_SIZE__ += 1 - __FONT_SIZE__ = min(len(__FONT_SIZES__)-1, __FONT_SIZE__) - elif (evt == Draw.PADMINUS or evt == Draw.MINUSKEY or evt == Draw.WHEELDOWNMOUSE) and val and Window.GetKeyQualifiers() & Window.Qual.CTRL: - __FONT_SIZE__ -=1 - __FONT_SIZE__ = max(0, __FONT_SIZE__) - - - elif evt == Draw.WHEELUPMOUSE and val: - __CONSOLE_LINE_OFFSET__ += 1 - __CONSOLE_LINE_OFFSET__ = min(len(cmdBuffer)-2, __CONSOLE_LINE_OFFSET__) - resetScroll = False - - elif evt == Draw.WHEELDOWNMOUSE and val: - __CONSOLE_LINE_OFFSET__ -= 1 - __CONSOLE_LINE_OFFSET__ = max(0, __CONSOLE_LINE_OFFSET__) - resetScroll = False - - - elif ascii: - insCh(chr(ascii)) - else: - return # dont redraw. - - # If the user types in anything then scroll to bottom. - if resetScroll: - __CONSOLE_LINE_OFFSET__ = 0 - Draw.Redraw() - - -def draw_gui(): - # Get the bounds from ObleGL directly - __CONSOLE_RECT__ = BGL.Buffer(BGL.GL_FLOAT, 4) - BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, __CONSOLE_RECT__) - __CONSOLE_RECT__= __CONSOLE_RECT__.list - - # Clear the screen - BGL.glClearColor(0.0, 0.0, 0.0, 1.0) - BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) # use it to clear the color buffer - - - # Fixed margin. use a margin since 0 margin can be hard to seewhen close to a crt's edge. - margin = 4 - - # Convenience - FNT_NAME, FNT_HEIGHT = __FONT_SIZES__[__FONT_SIZE__] - - # Draw cursor location colour - if __CONSOLE_LINE_OFFSET__ == 0: - cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], FNT_NAME) - BGL.glColor3f(0.8, 0.2, 0.2) - if cmd2curWidth == 0: - BGL.glRecti(margin,2,margin+2, FNT_HEIGHT+2) - else: - BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, FNT_HEIGHT+2) - - BGL.glColor3f(1,1,1) - # Draw the set of cammands to the buffer - consoleLineIdx = __CONSOLE_LINE_OFFSET__ + 1 - wrapLineIndex = 0 - while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * FNT_HEIGHT: - if cmdBuffer[-consoleLineIdx].type == 0: - BGL.glColor3f(1, 1, 1) - elif cmdBuffer[-consoleLineIdx].type == 1: - BGL.glColor3f(.3, .3, 1) - elif cmdBuffer[-consoleLineIdx].type == 2: - BGL.glColor3f(1.0, 0, 0) - elif cmdBuffer[-consoleLineIdx].type == 3: - BGL.glColor3f(0, 0.8, 0) - else: - BGL.glColor3f(1, 1, 0) - - if consoleLineIdx == 1: # user input - BGL.glRasterPos2i(margin, (FNT_HEIGHT * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) - else: # WRAP - lwid = Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) - if margin + lwid > __CONSOLE_RECT__[2]: - wrapLineList = [] - wtext = cmdBuffer[-consoleLineIdx].cmd - wlimit = len(wtext) - chunksz = int(( __CONSOLE_RECT__[2] - margin ) / (lwid / len(wtext))) - lstart = 0 - fsize = FNT_NAME - while lstart < wlimit: - lend = min(lstart+chunksz,wlimit) - ttext = wtext[lstart:lend] - while lend < wlimit and Draw.GetStringWidth(ttext, fsize) + margin < __CONSOLE_RECT__[2]: - lend += 1 - ttext = wtext[lstart:lend] - while lend > lstart+1 and Draw.GetStringWidth(ttext, fsize) + margin > __CONSOLE_RECT__[2]: - lend -= 1 - ttext = wtext[lstart:lend] - wrapLineList.append(ttext) - lstart = lend - # Now we have a list of lines, draw them (OpenGLs reverse ordering requires this odd change) - wrapLineList.reverse() - for wline in wrapLineList: - BGL.glRasterPos2i(margin, (FNT_HEIGHT*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8) - Draw.Text(wline, FNT_NAME) - wrapLineIndex += 1 - wrapLineIndex-=1 # otherwise we get a silly extra line. - - else: # no wrapping. - - BGL.glRasterPos2i(margin, (FNT_HEIGHT * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) - consoleLineIdx += 1 - -# This recieves the event index, call a function from here depending on the event. -def handle_button_event(evt): - pass - - -# Run the console -__CONSOLE_VAR_DICT__ = {} # Initialize var dict - - -# Print Startup lines, add __bpydoc__ to the console startup. -for l in __bpydoc__.split('
'): - cmdBuffer.append( cmdLine(l, 1, None) ) - - -histIndex = cursor = -1 # How far back from the first letter are we? - in current CMD line, history if for moving up and down lines. - -# Autoexec, startup code. -scriptDir = Get('scriptsdir') -console_autoexec = None -if scriptDir: - if not scriptDir.endswith(Blender.sys.sep): - scriptDir += Blender.sys.sep - - console_autoexec = '%s%s' % (scriptDir, 'console_autoexec.py') - - if not sys.exists(console_autoexec): - # touch the file - try: - open(console_autoexec, 'w').close() - cmdBuffer.append(cmdLine('...console_autoexec.py not found, making new in scripts dir', 1, None)) - except: - cmdBuffer.append(cmdLine('...console_autoexec.py could not write, this is ok', 1, None)) - scriptDir = None # make sure we only use this for console_autoexec.py - - if not sys.exists(console_autoexec): - console_autoexec = None - - else: - cmdBuffer.append(cmdLine('...Using existing console_autoexec.py in scripts dir', 1, None)) - - - -#-Autoexec---------------------------------------------------------------------# -# Just use the function to jump into local naming mode. -# This is so we can loop through all of the autoexec functions / vars and add them to the __CONSOLE_VAR_DICT__ -def include_console(includeFile): - global __CONSOLE_VAR_DICT__ # write autoexec vars to this. - - # Execute an external py file as if local - exec(include(includeFile)) - -def standard_imports(): - # Write local to global __CONSOLE_VAR_DICT__ for reuse, - - exec('%s%s' % ('__CONSOLE_VAR_DICT__["bpy"]=', 'bpy')) - exec('%s%s' % ('__CONSOLE_VAR_DICT__["Blender"]=', 'Blender')) - - for ls in (dir(), dir(Blender)): - for __TMP_VAR_NAME__ in ls: - # Execute the local > global coversion. - exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__)) - - # Add dummy imports to input so output scripts to a text file work as expected - cmdBuffer.append(cmdLine('import bpy', 0, 1)) - cmdBuffer.append(cmdLine('import Blender', 0, 1)) # pretend we have been executed, as we kindof have. - cmdBuffer.append(cmdLine('from Blender import *', 0, 1)) - -if scriptDir and console_autoexec: - include_console(console_autoexec) # pass the blender module - -standard_imports() # import Blender and bpy - -#-end autoexec-----------------------------------------------------------------# - - -# Append new line to write to -cmdBuffer.append(cmdLine(' ', 0, 0)) - -#------------------------------------------------------------------------------# -# register the event handling code, GUI # -#------------------------------------------------------------------------------# -def main(): - Draw.Register(draw_gui, handle_event, handle_button_event) - -if __name__ == '__main__': - main() diff --git a/release/scripts/discombobulator.py b/release/scripts/discombobulator.py deleted file mode 100644 index 6dbb4e5382b..00000000000 --- a/release/scripts/discombobulator.py +++ /dev/null @@ -1,1526 +0,0 @@ -#!BPY - -""" -Name: 'Discombobulator' -Blender: 237 -Group: 'Mesh' -Tip: 'Adds random geometry to a mesh' -""" - -__author__ = "Evan J. Rosky (syrux)" -__url__ = ("Script's homepage, http://evan.nerdsofparadise.com/programs/discombobulator/index.html") -__version__ = "237" -__bpydoc__ = """\ -Discombobulator adds random geometry to a mesh. - -As an example, this script can easily give a "high-tech" -look to walls and spaceships. - -Definitions:
- - Protrusions: extrusions of each original face on the mesh. -You may have from 1 to 4 protrusions on each face.
- - Taper: The tips of each protrusion will be a percentage -smaller than the base.
- - Doodads: small extruded blocks/shapes that are randomly placed -about the top of a protrusion or face. - - -Usage:
- Input your settings, make sure the mesh you would like to modify -is selected (active) and then click on "Discombobulate".
- See the scripts tutorial page (on the homepage) for more info. - - -New Features:
- - Will use existing materials if there are any.
- - Clicking "Assign materials by part" will allow assigning -of different material indices to Protrusion or Doodad Sides -and Tops in the gui element below it.
- - Setting a material index to 0 will use whatever material -is assigned to the face that is discombobulated. - - You can now scroll using the arrow keys. - - -Notes:
- - Modifications can be restricted to selected faces -by setting "Only selected faces" for protrusions and/or -doodads.
- - It's possible to restrict mesh generation to add only -protrusions or only doodads instead of both.
- - You may also choose to have Discombobulator select the -tops of created protrusions by clicking the corresponding -number of protrusion buttons under "Select Tops". You may -also do the same for doodads by choosing "Select Doodads" and -"Only Select Tops". You may choose to select the whole doodads -by leaving "Only Select Tops" off.
- - By selecting "Deselect Selected" you can have -discombobulator deselect everything but the selections it -makes.
- - The "Face %" option will set the percentage of faces that -will be modified either for the doodads or the protrusions.
- - "Copy Before Modifying" will create a new object with the -modifications where leaving it off will overwrite the original -mesh.
- -You can find more information at the Link above. -""" - - -# $Id$ -# -# Updated 2006-09-26 -# Changes since last version: -# > Works with Blender CVS and hopefully with Blender 2.40. -# > Swaps min/max values when min>max rather than complaining. -# > Will keep previously assigned materials. -# > Now allows user to assign custom material indices to -# Protrusion and Doodad Sides and Tops. -# > The initial Gui Layout will change depending on the aspect -# ratio of the window it is in. -# > Using the arrow keys will scroll the gui. -# -# -------------------------------------------------------------------------- -# Discombobulator v2.1b -# by Evan J. Rosky, 2005 -# This plugin is protected by the GPL: Gnu Public Licence -# GPL - http://www.gnu.org/copyleft/gpl.html -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2005: Evan J. Rosky -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -#Hit Alt-P to run - -import Blender -from Blender import NMesh,Object,Material,Window,Types,Scene -from Blender.NMesh import Vert,Face -from Blender.Mathutils import * - -import defaultdoodads -import BPyMathutils -from BPyMathutils import genrand -a = BPyMathutils.sgenrand(int(round(Rand(1000,99999),0))) - -#Create random numbers -def randnum(low,high): - num = genrand() - num = num*(high-low) - num = num+low - return num - -#Object Vars -newmesh = NMesh.GetRaw() -materialArray = [0] - -#Material Vars -reassignMats = 0 -protSideMat = 1 -protTopMat = 2 -doodSideMat = 3 -doodTopMat = 4 -thereAreMats = 0 -currmat = 0 - -#Global Vars -makenewobj = 1 -errortext = "Remember to select an object." -editmode = 0 - -#Protrusion Vars -makeprots = 1 -faceschangedpercent = 1.0 -minimumheight = 0.2 -maximumheight = 0.4 -subface1 = 1 -subface2 = 1 -subface3 = 1 -subface4 = 1 -subfaceArray = [1,2,3,4] -minsubfaces = 1 -minimumtaperpercent = 0.15 -maximumtaperpercent = 0.35 -useselectedfaces = 0 -selectface1 = 1 -selectface2 = 1 -selectface3 = 1 -selectface4 = 1 -deselface = 1 - -#Doodad Vars -makedoodads = 1 -doodadfacepercent = 1.0 -selectdoodad = 0 -onlyonprotrusions = 0 -doodonselectedfaces = 0 -selectdoodadtoponly = 0 -doodad1 = 1 -doodad2 = 1 -doodad3 = 1 -doodad4 = 1 -doodad5 = 1 -doodad6 = 1 -doodadminperface = 2 -doodadmaxperface = 6 -doodadminsize = 0.15 -doodadmaxsize = 0.45 -doodadminheight = 0.0 -doodadmaxheight = 0.1 -doodadArray = [1,2,3,4,5,6] - -def makeSubfaceArray(): - global subfaceArray - global subface1 - global subface2 - global subface3 - global subface4 - - subfaceArray = [] - if subface1 > 0: - subfaceArray.append(1) - if subface2 > 0: - subfaceArray.append(2) - if subface3 > 0: - subfaceArray.append(3) - if subface4 > 0: - subfaceArray.append(4) - -def makeDoodadArray(): - global doodadArray - global doodad1 - global doodad2 - global doodad3 - global doodad4 - global doodad5 - global doodad6 - - doodadArray = [] - if doodad1 > 0: - doodadArray.append(1) - if doodad2 > 0: - doodadArray.append(2) - if doodad3 > 0: - doodadArray.append(3) - if doodad4 > 0: - doodadArray.append(4) - if doodad5 > 0: - doodadArray.append(5) - if doodad6 > 0: - doodadArray.append(6) - -def extrude(mid,nor,protrusion,v1,v2,v3,v4,tosel=1,flipnor=0): - taper = 1 - randnum(minimumtaperpercent,maximumtaperpercent) - newmesh_verts = newmesh.verts - newmesh_faces = newmesh.faces - - vert = newmesh_verts[v1] - point = (vert.co - mid)*taper + mid + protrusion*Vector(nor) - ver = Vert(point[0],point[1],point[2]) - ver.sel = tosel - newmesh_verts.append(ver) - vert = newmesh_verts[v2] - point = (vert.co - mid)*taper + mid + protrusion*Vector(nor) - ver = Vert(point[0],point[1],point[2]) - ver.sel = tosel - newmesh_verts.append(ver) - vert = newmesh_verts[v3] - point = (vert.co - mid)*taper + mid + protrusion*Vector(nor) - ver = Vert(point[0],point[1],point[2]) - ver.sel = tosel - newmesh_verts.append(ver) - vert = newmesh_verts[v4] - point = (vert.co - mid)*taper + mid + protrusion*Vector(nor) - ver = Vert(point[0],point[1],point[2]) - ver.sel = tosel - newmesh_verts.append(ver) - - faceindex = len(newmesh_verts) - 4 - - #side face 1 - face = Face([newmesh_verts[v1], newmesh_verts[v2], newmesh_verts[faceindex+1], newmesh_verts[faceindex]]) - if flipnor != 0: - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh_faces.append(face) - - #side face 2 - face = Face([newmesh_verts[v2], newmesh_verts[v3], newmesh_verts[faceindex+2], newmesh_verts[faceindex+1]]) - if flipnor != 0: - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh_faces.append(face) - - #side face 3 - face = Face([newmesh_verts[v3], newmesh_verts[v4], newmesh_verts[faceindex+3], newmesh_verts[faceindex+2]]) - if flipnor != 0: - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh_faces.append(face) - - #side face 4 - face = Face([newmesh_verts[v4], newmesh_verts[v1], newmesh_verts[faceindex], newmesh_verts[faceindex+3]]) - if flipnor != 0: - face.v.reverse() - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh_faces.append(face) - - #top face - face = Face(newmesh_verts[-4:]) - if flipnor != 0: - face.v.reverse() - if tosel == 1: - face.sel = 1 - if thereAreMats == 1: - if reassignMats == 0 or protTopMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protTopMat-1 - newmesh_faces.append(face) - return face - -#Sets the global protrusion values -def setProtrusionValues(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15): - - #Protrusions - global makeprots - global minimumtaperpercent - global maximumtaperpercent - global faceschangedpercent - global minimumheight - global maximumheight - global subface1 - global subface2 - global subface3 - global subface4 - global useselectedfaces - global selectface1 - global selectface2 - global selectface3 - global selectface4 - global deselface - global subfaceArray - - #Protrusions - makeprots = p0 - faceschangedpercent = p1 - minimumheight = p2 - maximumheight = p3 - subface1 = p4 - subface2 = p5 - subface3 = p6 - subface4 = p7 - minimumtaperpercent = p8 - maximumtaperpercent = p9 - useselectedfaces = p10 - selectface1 = p11 - selectface2 = p12 - selectface3 = p13 - selectface4 = p14 - deselface = p15 - makeSubfaceArray() - if len(subfaceArray) == 0: - makeprots = 0 - - if minimumheight > maximumheight: - a = maximumheight - maximimheight = minimumheight - minimumheight = a - elif minimumtaperpercent > maximumtaperpercent: - a = maximumtaperpercent - maximimtaperpercent = minimumtaperpercent - minimumtaperpercent = a - -#Sets the global Doodad values -def setDoodadValues(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17): - - #Doodads - global makedoodads - global doodadfacepercent - global selectdoodad - global onlyonprotrusions - global doodad1 - global doodad2 - global doodad3 - global doodad4 - global doodad5 - global doodad6 - global doodadminperface - global doodadmaxperface - global doodadminsize - global doodadmaxsize - global doodadminheight - global doodadmaxheight - global doodadArray - global doodonselectedfaces - global selectdoodadtoponly - - #Doodads - makedoodads = d0 - doodadfacepercent = d1 - selectdoodad = d2 - onlyonprotrusions = d3 - doodad1 = d4 - doodad2 = d5 - doodad3 = d6 - doodad4 = d7 - doodad5 = d8 - doodad6 = d9 - doodadminperface = d10 - doodadmaxperface = d11 - doodadminsize = d12 - doodadmaxsize = d13 - doodadminheight = d14 - doodadmaxheight = d15 - doodonselectedfaces = d16 - selectdoodadtoponly = d17 - makeDoodadArray() - if len(doodadArray) == 0: - makedoodads = 0 - - elif doodadminperface > doodadmaxperface: - a = doodadmaxperface - doodadmaxperface = doodadminperface - doodadminperface = a - elif doodadminsize > doodadmaxsize: - a = doodadmaxsize - doodadmaxsize = doodadminsize - doodadminsize = a - elif doodadminheight > doodadmaxheight: - a = doodadmaxheight - doodadmaxheight = doodadminheight - doodadminheight = a - -#Sets other global values -def setOtherValues(g0,m0,m1,m2,m3,m4): - - #Global - global reassignMats - global makenewobj - global protSideMat - global protTopMat - global doodSideMat - global doodTopMat - - #Get Misc Variables - makenewobj = g0 - reassignMats = m0 - protSideMat = m1 - protTopMat = m2 - doodSideMat = m3 - doodTopMat = m4 - -def discombobulate(): - - #Global - global origmesh - global newmesh - global makenewobj - global origobj - global newobj - global messagetext - global errortext - global editmode - - #Protrusions - global makeprots - global minimumtaperpercent - global maximumtaperpercent - global faceschangedpercent - global minimumheight - global maximumheight - global subface1 - global subface2 - global subface3 - global subface4 - global useselectedfaces - global selectface1 - global selectface2 - global selectface3 - global selectface4 - global deselface - global subfaceArray - - #Doodads - global makedoodads - global doodadfacepercent - global selectdoodad - global onlyonprotrusions - global doodad1 - global doodad2 - global doodad3 - global doodad4 - global doodad5 - global doodad6 - global doodadminperface - global doodadmaxperface - global doodadminsize - global doodadmaxsize - global doodadminheight - global doodadmaxheight - global doodadArray - global doodonselectedfaces - global selectdoodadtoponly - - #Global - global materialArray - global reassignMats - global protSideMat - global protTopMat - global doodSideMat - global doodTopMat - global thereAreMats - global currmat - - origobj = Scene.GetCurrent().objects.active - if not origobj: - glRasterPos2d(10,50) - errortext = "YOU MUST SELECT AN OBJECT!" - messagetext = ErrorText(errortext) - Blender.Redraw() - return - - #Leave Editmode - editmode = Window.EditMode() - if editmode: Window.EditMode(0) - - #Get Major Variables - - origmesh = origobj.getData() - - if origobj.type != 'Mesh': - glRasterPos2d(10,50) - errortext = "OBJECT MUST BE MESH!" - messagetext = ErrorText(errortext) - Blender.Redraw() - return - - newmesh = NMesh.GetRaw() - materialArray = origmesh.getMaterials() - if len(materialArray) < 1: - thereAreMats = 0 - else: - thereAreMats = 1 - - #add material indices if necessary (only up to 4) - if thereAreMats == 1 and reassignMats == 1: - if len(materialArray) < 4: - if protSideMat > 4: protSideMat = 4 - if protTopMat > 4: protTopMat = 4 - if doodSideMat > 4: doodSideMat = 4 - if doodTopMat > 4: doodTopMat = 4 - else: - if protSideMat > len(materialArray): protSideMat = len(materialArray) - if protTopMat > len(materialArray): protTopMat = len(materialArray) - if doodSideMat > len(materialArray): doodSideMat = len(materialArray) - if doodTopMat > len(materialArray): doodTopMat = len(materialArray) - - #This only does something if there are less than 4 verts - for matind in [protSideMat,protTopMat,doodSideMat,doodTopMat]: - if matind > len(materialArray) and matind <= 4: - for i in xrange(len(materialArray),matind+1): - materialArray.append(Material.New("AddedMat " + str(i))) - - #Sets the materials - newmesh.setMaterials(materialArray) - - #Set the doodad settings - defaultdoodads.settings(selectdoodadtoponly,materialArray,reassignMats,thereAreMats,doodSideMat,doodTopMat) - #defaultdoodads.settings(selectdoodadtoponly,materialArray,reassignMats,thereAreMats,currmat) - - newmesh.verts.extend(origmesh.verts) - - #Start modifying faces - for currface in origmesh.faces: - - currmat = currface.materialIndex - defaultdoodads.setCurrMat(currmat) - - #Check if it is a triangle - if len(currface.v)<4: - face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index]]) - if thereAreMats == 1: - face.materialIndex = currmat - newmesh.faces.append(face) - continue - - #Check whether or not to make protrusions - if makeprots == 0: - face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]]) - if thereAreMats == 1: - face.materialIndex = currmat - newmesh.faces.append(face) - if makedoodads == 1 and onlyonprotrusions == 0: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - continue - - #Check if only changing selected faces - if useselectedfaces == 1: - #check if currface is selected - if currface.sel: - a = 1 - else: - face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]]) - if thereAreMats == 1: - face.materialIndex = currmat - newmesh.faces.append(face) - if makedoodads == 1 and onlyonprotrusions == 0: - if doodonselectedfaces != 1: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - continue - #Check if face should be modified by random chance - if randnum(0,1)>faceschangedpercent: - face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]]) - if thereAreMats == 1: - face.materialIndex = currmat - newmesh.faces.append(face) - if makedoodads == 1 and onlyonprotrusions == 0: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - continue - - center = Vector([0,0,0]) - for pt in currface.v: - center = center + pt.co - center = center / len(currface.v) - - #Determine amount of subfaces - subfaces = round(randnum(1,len(subfaceArray)),0) - subfaces = subfaceArray[(int(subfaces) - 1)] - - ######################## START DEALING WITH PROTRUSIONS ##################### - - if subfaces == 1: - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,currface.v[0].index,currface.v[1].index,currface.v[2].index,currface.v[3].index,selectface1) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - - elif subfaces == 2: - orientation = int(round(randnum(0,1))) - p1 = currface.v[orientation] - p2 = currface.v[orientation + 1] - p3 = ((p2.co - p1.co)/2) + p1.co - ve1 = Vert(p3[0],p3[1],p3[2]) - ve1.sel = 0 - p1 = currface.v[2 + orientation] - if orientation < 0.5: - p2 = currface.v[3] - else: - p2 = currface.v[0] - p3 = ((p2.co - p1.co)/2) + p1.co - ve2 = Vert(p3[0],p3[1],p3[2]) - ve2.sel = 0 - if orientation < 0.5: - verti = currface.v[3] - p3 = verti.index - v1 = p3 - verti = currface.v[0] - p0 = verti.index - v2 = p0 - else: - verti = currface.v[0] - p0 = verti.index - v1 = p0 - verti = currface.v[1] - p1 = verti.index - v2 = p1 - newmesh.verts.append(ve1) - newmesh.verts.append(ve2) - index = len(newmesh.verts) - 2 - v4 = index + 1 - v3 = index - center = Vector([0, 0, 0]) - for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,v1,v2,v3,v4,selectface2) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - if orientation < 0.5: - verti = currface.v[1] - p1 = verti.index - v1 = p1 - verti = currface.v[2] - p2 = verti.index - v2 = p2 - else: - verti = currface.v[2] - p2 = verti.index - v1 = p2 - verti = currface.v[3] - p3 = verti.index - v2 = p3 - center = Vector([0]*3) - for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,v1,v2,v4,v3,selectface2) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - if orientation < 0.5: - face = Face([newmesh.verts[p0],newmesh.verts[p1],newmesh.verts[v3]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[p2],newmesh.verts[p3],newmesh.verts[v4]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - else: - face = Face([newmesh.verts[p1],newmesh.verts[p2],newmesh.verts[v3]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[p3],newmesh.verts[p0],newmesh.verts[v4]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - - elif subfaces == 3: - layer2inds = [] - layer2verts = [] - orientation = int(round(randnum(0,1))) - rotation = int(round(randnum(0,1))) - p1 = currface.v[orientation] - p2 = currface.v[orientation + 1] - p3 = ((p2.co - p1.co)/2) + p1.co - ve1 = Vert(p3[0],p3[1],p3[2]) - ve1.sel = 0 - p1 = currface.v[2 + orientation] - if orientation < 0.5: - p2 = currface.v[3] - else: - p2 = currface.v[0] - p3 = ((p2.co - p1.co)/2) + p1.co - ve2 = Vert(p3[0],p3[1],p3[2]) - ve2.sel = 0 - fp = [] - - #make first protrusion - if rotation < 0.5: - if orientation < 0.5: - verti = currface.v[3] - fp.append(verti.index) - v1 = verti.index - verti = currface.v[0] - fp.append(verti.index) - v2 = verti.index - layer2verts.extend([newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index]]) - else: - verti = currface.v[0] - fp.append(verti.index) - v1 = verti.index - verti = currface.v[1] - fp.append(verti.index) - v2 = verti.index - layer2verts.extend([newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]]) - newmesh.verts.append(ve1) - newmesh.verts.append(ve2) - index = len(newmesh.verts) - 2 - v4 = index + 1 - v3 = index - center = Vector([0]*3) - for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - layer2inds.extend([v3,v4]) - tempface = extrude(center,currface.no,prot,v1,v2,v3,v4,selectface3) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - #Still first protrusion - else: - if orientation < 0.5: - verti = currface.v[1] - fp.append(verti.index) - v1 = verti.index - verti = currface.v[2] - fp.append(verti.index) - v2 = verti.index - layer2verts.extend([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[3].index]]) - else: - verti = currface.v[2] - fp.append(verti.index) - v1 = verti.index - verti = currface.v[3] - fp.append(verti.index) - v2 = verti.index - layer2verts.extend([newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[0].index]]) - newmesh.verts.append(ve2) - newmesh.verts.append(ve1) - index = len(newmesh.verts) - 2 - v4 = index - v3 = index + 1 - center = Vector([0]*3) - for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - layer2inds.extend([index, index +1]) - tempface = extrude(center,currface.no,prot,v1,v2,v4,v3,selectface3) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - - #split next rect(pre-arranged, no orientation crud)--make flag in extruder for only one existing vert in mesh - p1 = newmesh.verts[layer2inds[0]] - p2 = newmesh.verts[layer2inds[1]] - p3 = ((p2.co - p1.co)/2) + p1.co - ve3 = Vert(p3[0],p3[1],p3[2]) - ve3.sel = 0 - p1 = layer2verts[0] - p2 = layer2verts[1] - p3 = ((p2.co - p1.co)/2) + p1.co - ve4 = Vert(p3[0],p3[1],p3[2]) - ve4.sel = 0 - newmesh.verts.append(ve3) - newmesh.verts.append(ve4) - tempindex = len(newmesh.verts) - 2 - v5 = tempindex - v6 = tempindex + 1 - verti = layer2verts[0] - t0 = verti.index - center = Vector([0]*3) - for pt in [newmesh.verts[v5],newmesh.verts[v6],newmesh.verts[t0],newmesh.verts[v3]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - if rotation < 0.5: flino = 1 - else: flino = 0 - tempface = extrude(center,currface.no,prot,v3,v5,v6,t0,selectface3,flino) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - if rotation < 0.5: - fpt = t0 - face = Face([newmesh.verts[fp[1]],newmesh.verts[fpt],newmesh.verts[v3]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - else: - fpt = t0 - face = Face([newmesh.verts[fp[0]],newmesh.verts[v3],newmesh.verts[fpt]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - verti = layer2verts[1] - tempindex = verti.index - center = Vector([0]*3) - for pt in [newmesh.verts[v5],newmesh.verts[v6],newmesh.verts[tempindex],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,v6,v5,v4,tempindex,selectface3,flino) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - if rotation < 0.5: - face = Face([newmesh.verts[tempindex],newmesh.verts[fp[0]],newmesh.verts[v4]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[fpt],newmesh.verts[tempindex],newmesh.verts[v6]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - else: - face = Face([newmesh.verts[tempindex],newmesh.verts[v4],newmesh.verts[fp[1]]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[tempindex],newmesh.verts[fpt],newmesh.verts[v6]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - - else: - #get all points - verti = currface.v[0] - p0 = verti.index - - verti = currface.v[1] - p1 = verti.index - - pt = ((newmesh.verts[p1].co - newmesh.verts[p0].co)/2) + newmesh.verts[p0].co - v1 = Vert(pt[0],pt[1],pt[2]) - v1.sel = 0 - - verti = currface.v[2] - p2 = verti.index - - pt = ((newmesh.verts[p2].co - newmesh.verts[p1].co)/2) + newmesh.verts[p1].co - v2 = Vert(pt[0],pt[1],pt[2]) - v2.sel = 0 - - verti = currface.v[3] - p3 = verti.index - - pt = ((newmesh.verts[p3].co - newmesh.verts[p2].co)/2) + newmesh.verts[p2].co - v3 = Vert(pt[0],pt[1],pt[2]) - v3.sel = 0 - - pt = ((newmesh.verts[p0].co - newmesh.verts[p3].co)/2) + newmesh.verts[p3].co - v4 = Vert(pt[0],pt[1],pt[2]) - v4.sel = 0 - - pt = ((v3.co - v1.co)/2) + v1.co - m = Vert(pt[0],pt[1],pt[2]) - m.sel = 0 - - #extrusion 1 - newmesh.verts.extend([v1,m,v4]) - index = len(newmesh.verts) - 3 - v1 = index - m = index + 1 - v4 = index + 2 - center = Vector([0]*3) - for pt in [newmesh.verts[p0],newmesh.verts[v1],newmesh.verts[m],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,p0,v1,m,v4,selectface4) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - - #extrusion 2 - newmesh.verts.extend([v2]) - index = len(newmesh.verts) - 1 - v2 = index - center = Vector([0]*3) - for pt in [newmesh.verts[m],newmesh.verts[v1],newmesh.verts[p1],newmesh.verts[v2]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,m,v1,p1,v2,selectface4) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - - #extrusion 3 - newmesh.verts.extend([v3]) - index = len(newmesh.verts) - 1 - v3 = index - center = Vector([0]*3) - for pt in [newmesh.verts[m],newmesh.verts[v2],newmesh.verts[p2],newmesh.verts[v3]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,m,v2,p2,v3,selectface4) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - - #extrusion 4 - center = Vector([0]*3) - for pt in [newmesh.verts[m],newmesh.verts[v3],newmesh.verts[p3],newmesh.verts[v4]]: - center += pt.co - center = center/4 - prot = randnum(minimumheight,maximumheight) - tempface = extrude(center,currface.no,prot,v4,m,v3,p3,selectface4) - if makedoodads == 1: - if doodonselectedfaces == 1: - if currface.sel: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - else: - tempmesh = NMesh.GetRaw() - tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent) - newmesh.verts.extend(tempmesh.verts) - newmesh.faces.extend(tempmesh.faces) - - face = Face([newmesh.verts[p0],newmesh.verts[p1],newmesh.verts[v1]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[p1],newmesh.verts[p2],newmesh.verts[v2]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[p2],newmesh.verts[p3],newmesh.verts[v3]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - face = Face([newmesh.verts[p3],newmesh.verts[p0],newmesh.verts[v4]]) - if thereAreMats == 1: - if reassignMats == 0 or protSideMat == 0: - face.materialIndex = currmat - else: - face.materialIndex = protSideMat-1 - newmesh.faces.append(face) - - #NMesh.PutRaw(newmesh) - if deselface == 1: - for unvert in origmesh.verts: - newmesh.verts[unvert.index].sel = 0 - if makenewobj == 1: - newobj = origobj.__copy__() - newobj.link(newmesh) - scene = Blender.Scene.GetCurrent() - scene.objects.link(newobj) - origobj.sel = 0 - else: - origobj.link(newmesh) - - #Return to Editmode if previously in it - if editmode: Window.EditMode(1) - -####################### gui ###################### -from Blender.BGL import * -from Blender.Draw import * - -def ErrorText(errortext): - Window.WaitCursor(0) - Text(errortext) - PupMenu("ERROR: %s" % errortext.lower()) - -#Global Buttons -makenewobject = Create(makenewobj) -messagetext = Create(errortext) - -#Protrusion Buttons -doprots = Create(makeprots) -facechange = Create(faceschangedpercent*100) -minheight = Create(minimumheight) -maxheight = Create(maximumheight) -sub1 = Create(subface1) -sub2 = Create(subface2) -sub3 = Create(subface3) -sub4 = Create(subface4) -mintaper = Create(minimumtaperpercent*100) -maxtaper = Create(maximumtaperpercent*100) -useselected = Create(useselectedfaces) -selface1 = Create(selectface1) -selface2 = Create(selectface2) -selface3 = Create(selectface3) -selface4 = Create(selectface4) -deselectvertices = Create(deselface) -#selectbyverts = Create(vertselected) - -#Doodad Buttons -dodoodads = Create(makedoodads) -doodadfacechange = Create(doodadfacepercent*100) -seldoodad = Create(selectdoodad) -onprot = Create(onlyonprotrusions) -dood1 = Create(doodad1) -dood2 = Create(doodad2) -dood3 = Create(doodad3) -dood4 = Create(doodad4) -dood5 = Create(doodad5) -dood6 = Create(doodad6) -doodadminamount = Create(doodadminperface) -doodadmaxamount = Create(doodadmaxperface) -doodsizemin = Create(doodadminsize*100) -doodsizemax = Create(doodadmaxsize*100) -doodheightmin = Create(doodadminheight) -doodheightmax = Create(doodadmaxheight) -doodonselface = Create(doodonselectedfaces) -seldoodtop = Create(selectdoodadtoponly) - -#Material Buttons -assignNewMats = Create(reassignMats) -replProtSideIndex = Create(protSideMat) -replProtTopIndex = Create(protTopMat) -replDoodSideIndex = Create(doodSideMat) -replDoodTopIndex = Create(doodTopMat) - -# Events -EVENT_NONE = 1 -EVENT_DISCOMBOBULATE = 2 -EVENT_EXIT = 3 - -# Additions for moving gui -hadd = 0 -wadd = 0 -thadd = 410 -phadd = 245 -pwadd = 0 -dhadd = 55 -dwadd = 0 -ghadd = 10 -gwadd = 0 -mhadd = 55 -mwadd = 312 - -def colorbox(x,y,xright,bottom): - glColor3f(0.75, 0.75, 0.75) - glRecti(x + 1, y + 1, xright - 1, bottom - 1) - -firstDraw = 1 - -def draw(): - - #Protrusions - global doprots - global facechange - global minheight - global maxheight - global sub1 - global sub2 - global sub3 - global sub4 - global mintaper - global maxtaper - global useselected - global selface1 - global selface2 - global selface3 - global selface4 - global deselectvertices - #global selectbyverts - - #Doodads - global dodoodads - global doodadfacechange - global seldoodad - global onprot - global dood1 - global dood2 - global dood3 - global dood4 - global dood5 - global dood6 - global doodadminamount - global doodadmaxamount - global doodsizemin - global doodsizemax - global doodheightmin - global doodheightmax - global doodonselface - global seldoodtop - - #Materials - global assignNewMats - global replProtSideIndex - global replProtTopIndex - global replDoodSideIndex - global replDoodTopIndex - - #Global Settings - global makenewobject - global messagetext - global errortext - global EVENT_NONE,EVENT_DRAW,EVENT_EXIT,EVENT_UP,EVENT_DOWN,EVENT_LEFT,EVENT_RIGHT - - # Additions for moving gui - global hadd - global wadd - global thadd - global phadd - global pwadd - global dhadd - global dwadd - global ghadd - global gwadd - global mhadd - global mwadd - - #This is for creating the initial layout - global firstDraw - if(firstDraw == 1): - if(((Window.GetAreaSize()[1])*1.7) < Window.GetAreaSize()[0]): - thadd = 180 - phadd = 10 - dhadd = 10 - mhadd = 55 - ghadd = 10 - pwadd = 0 - dwadd = 305 - mwadd = 610 - gwadd = 610 - else: - thadd = 505 - phadd = 346 - dhadd = 160 - mhadd = 56 - ghadd = 10 - pwadd = 0 - dwadd = 0 - mwadd = 0 - gwadd = 0 - firstDraw = 0 - - - #Title :420high - glClearColor(0.6, 0.6, 0.6, 1.0) - glClear(GL_COLOR_BUFFER_BIT) - glColor3f(0.0,0.0,0.0) - glRasterPos2d(8+wadd, thadd+hadd) - Text("Discombobulator v2.1b") - - #Protrusion - colorbox(8+pwadd+wadd,150+phadd+hadd,312+pwadd+wadd,phadd-5+hadd) - glColor3f(0.0,0.0,0.0) - glRasterPos2d(12+pwadd+wadd, 140+phadd+hadd) - Text("Protrusions:") - doprots = Toggle("Make Protrusions",EVENT_NONE,12+pwadd+wadd,117+phadd+hadd,145,18,doprots.val,"Make Protrusions?") - facechange = Number("Face %: ",EVENT_NONE,162+pwadd+wadd,117+phadd+hadd,145,18,facechange.val,0,100,"Percentage of faces that will grow protrusions") - useselected = Toggle("Only selected faces",EVENT_NONE,12+pwadd+wadd,97+phadd+hadd,145,18,useselected.val,"If on, only selected faces will be modified") - deselectvertices = Toggle("Deselect Selected",EVENT_NONE,162+pwadd+wadd,97+phadd+hadd,145,18,deselectvertices.val,"Deselects any selected vertex except for ones selected by \"Select Tops\"") - - #Protrusion properties - glColor3f(0.0,0.0,0.0) - glRasterPos2d(12+pwadd+wadd, 80+phadd+hadd) - Text("Protrusion Properties:") - BeginAlign() - minheight = Number("Min Height: ",EVENT_NONE,12+pwadd+wadd,57+phadd+hadd,145,18,minheight.val,-100.0,100.0,"Minimum height of any protrusion") - maxheight = Number("Max Height: ",EVENT_NONE,162+pwadd+wadd,57+phadd+hadd,145,18,maxheight.val,-100.0,100.0,"Maximum height of any protrusion") - EndAlign() - BeginAlign() - mintaper = Number("Min Taper %: ",EVENT_NONE,12+pwadd+wadd,37+phadd+hadd,145,18,mintaper.val,0,100,"Minimum taper percentage of protrusion") - maxtaper = Number("Max Taper %: ",EVENT_NONE,162+pwadd+wadd,37+phadd+hadd,145,18,maxtaper.val,0,100,"Maximum taper percentage of protrusion") - EndAlign() - glRasterPos2d(19+pwadd+wadd, 22+phadd+hadd) - Text("Number of protrusions:") - BeginAlign() - sub1 = Toggle("1",EVENT_NONE,12+pwadd+wadd,phadd+hadd,34,18,sub1.val,"One Protrusion") - sub2 = Toggle("2",EVENT_NONE,48+pwadd+wadd,phadd+hadd,34,18,sub2.val,"Two Protrusions") - sub3 = Toggle("3",EVENT_NONE,84+pwadd+wadd,phadd+hadd,34,18,sub3.val,"Three Protrusions") - sub4 = Toggle("4",EVENT_NONE,120+pwadd+wadd,phadd+hadd,34,18,sub4.val,"Four Protrusions") - EndAlign() - glRasterPos2d(195+pwadd+wadd, 22+phadd+hadd) - Text("Select tops of:") - BeginAlign() - selface1 = Toggle("1",EVENT_NONE,165+pwadd+wadd,phadd+hadd,34,18,selface1.val,"Select the tip of the protrusion when it is created") - selface2 = Toggle("2",EVENT_NONE,201+pwadd+wadd,phadd+hadd,34,18,selface2.val,"Select the tips of each protrusion when they are created") - selface3 = Toggle("3",EVENT_NONE,237+pwadd+wadd,phadd+hadd,34,18,selface3.val,"Select the tips of each protrusion when they are created") - selface4 = Toggle("4",EVENT_NONE,273+pwadd+wadd,phadd+hadd,34,18,selface4.val,"Select the tips of each protrusion when they are created") - EndAlign() - #Doodads - colorbox(8+dwadd+wadd,175+dhadd+hadd,312+dwadd+wadd,dhadd-5+hadd) - glColor3f(0.0,0.0,0.0) - glRasterPos2d(12+dwadd+wadd, 165+dhadd+hadd) - Text("Doodads:") - BeginAlign() - dood1 = Toggle("1 Box",EVENT_NONE,12+dwadd+wadd,142+dhadd+hadd,45,18,dood1.val,"Creates a rectangular box") - dood2 = Toggle("2 Box",EVENT_NONE,61+dwadd+wadd,142+dhadd+hadd,45,18,dood2.val,"Creates 2 side-by-side rectangular boxes") - dood3 = Toggle("3 Box",EVENT_NONE,110+dwadd+wadd,142+dhadd+hadd,45,18,dood3.val,"Creates 3 side-by-side rectangular boxes") - EndAlign() - BeginAlign() - dood4 = Toggle("\"L\"",EVENT_NONE,164+dwadd+wadd,142+dhadd+hadd,45,18,dood4.val,"Creates a Tetris-style \"L\" shape") - dood5 = Toggle("\"T\"",EVENT_NONE,213+dwadd+wadd,142+dhadd+hadd,45,18,dood5.val,"Creates a Tetris-style \"T\" shape") - dood6 = Toggle("\"S\"",EVENT_NONE,262+dwadd+wadd,142+dhadd+hadd,45,18,dood6.val,"Creates a sort-of \"S\" or \"Z\" shape") - EndAlign() - dodoodads = Toggle("Make Doodads",EVENT_NONE,12+dwadd+wadd,120+dhadd+hadd,145,18,dodoodads.val,"Make Doodads?") - doodadfacechange = Number("Face %: ",EVENT_NONE,162+dwadd+wadd,120+dhadd+hadd,145,18,doodadfacechange.val,0,100,"Percentage of faces that will gain doodads") - seldoodad = Toggle("Select Doodads",EVENT_NONE,12+dwadd+wadd,100+dhadd+hadd,145,18,seldoodad.val,"Selects doodads when they are created") - seldoodtop = Toggle("Only Select Tops",EVENT_NONE,162+dwadd+wadd,100+dhadd+hadd,145,18,seldoodtop.val,"Only Selects tops of doodads when\"Select Doodads\" is on") - doodonselface = Toggle("Only selected faces",EVENT_NONE,12+dwadd+wadd,80+dhadd+hadd,145,18,doodonselface.val,"Only create doodads on selected faces") - onprot = Toggle("Only on Protrusions",EVENT_NONE,162+dwadd+wadd,80+dhadd+hadd,145,18,onprot.val,"Only place doodads on protrusions") - - #Doodad Properties - glColor3f(0.0,0.0,0.0) - glRasterPos2d(12+dwadd+wadd, 63+dhadd+hadd) - Text("Doodad Properties:") - BeginAlign() - doodadminamount = Number("Min Amount: ",EVENT_NONE,12+dwadd+wadd,40+dhadd+hadd,145,18,doodadminamount.val,0,100,"Minimum number of doodads per face") - doodadmaxamount = Number("Max Amount: ",EVENT_NONE,162+dwadd+wadd,40+dhadd+hadd,145,18,doodadmaxamount.val,0,100,"Maximum number of doodads per face") - EndAlign() - BeginAlign() - doodheightmin = Number("Min Height: ",EVENT_NONE,12+dwadd+wadd,20+dhadd+hadd,145,18,doodheightmin.val,0.0,100.0,"Minimum height of any doodad") - doodheightmax = Number("Max Height: ",EVENT_NONE,162+dwadd+wadd,20+dhadd+hadd,145,18,doodheightmax.val,0.0,100.0,"Maximum height of any doodad") - EndAlign() - BeginAlign() - doodsizemin = Number("Min Size %: ",EVENT_NONE,12+dwadd+wadd,dhadd+hadd,145,18,doodsizemin.val,0.0,100.0,"Minimum size of any doodad in percentage of face") - doodsizemax = Number("Max Size %: ",EVENT_NONE,162+dwadd+wadd,dhadd+hadd,145,18,doodsizemax.val,0.0,100.0,"Maximum size of any doodad in percentage of face") - EndAlign() - - #Materials - colorbox(8+mwadd+wadd,93+mhadd+hadd,312+mwadd+wadd,mhadd-5+hadd) - glColor3f(0.0,0.0,0.0) - glRasterPos2d(12+mwadd+wadd, 83+mhadd+hadd) - Text("Materials:") - glRasterPos2d(12+mwadd+wadd, 43+mhadd+hadd) - Text("Assigned Material Indices:") - assignNewMats = Toggle("Assign materials by part",EVENT_NONE,32+mwadd+wadd,60+mhadd+hadd,256,18,assignNewMats.val,"Otherwise, previous materials will be preserved") - replProtSideIndex = Number("Protrusion Sides:",EVENT_NONE,12+mwadd+wadd,20+mhadd+hadd,145,18,replProtSideIndex.val,0,16,"Material index assigned to sides of protrusions") - replProtTopIndex = Number("Protrusion Tops:",EVENT_NONE,162+mwadd+wadd,20+mhadd+hadd,145,18,replProtTopIndex.val,0,16,"Material index assigned to tops of protrusions") - replDoodSideIndex = Number("Doodad Sides:",EVENT_NONE,12+mwadd+wadd,mhadd+hadd,145,18,replDoodSideIndex.val,0,16,"Material index assigned to sides of doodads") - replDoodTopIndex = Number("Doodad Tops:",EVENT_NONE,162+mwadd+wadd,mhadd+hadd,145,18,replDoodTopIndex.val,0,16,"Material index assigned to tops and bottoms of doodads") - - #Global Parts - colorbox(8+gwadd+wadd,35+ghadd+hadd,312+gwadd+wadd,ghadd-5+hadd) - glColor3f(1.0,0.0,0.0) - glRasterPos2d(12+gwadd+wadd,25+ghadd+hadd) - messagetext = Text(errortext) - glColor3f(0.0,0.0,0.0) - makenewobject = Toggle("Copy Before Modifying",EVENT_NONE,162+gwadd+wadd,ghadd+hadd,145,18,makenewobject.val,"If selected, the original object will be copied before it is changed") - Button("Discombobulate",EVENT_DISCOMBOBULATE,12+gwadd+wadd,ghadd+hadd,100,18) - Button("Exit",EVENT_EXIT,120+gwadd+wadd,ghadd+hadd,30,18) - -def event(evt, val): - global wadd - global hadd - - if (evt == RIGHTARROWKEY and val): - wadd = wadd + 20 - Redraw(1) - if (evt == LEFTARROWKEY and val): - wadd = wadd - 20 - Redraw(1) - if (evt == UPARROWKEY and val): - hadd = hadd + 20 - Redraw(1) - if (evt == DOWNARROWKEY and val): - hadd = hadd - 20 - Redraw(1) - if (evt == QKEY and not val): - Exit() - -def bevent(evt): - - #Protrusions - global doprots - global facechange - global minheight - global maxheight - global sub1 - global sub2 - global sub3 - global sub4 - global mintaper - global maxtaper - global useselected - global selface1 - global selface2 - global selface3 - global selface4 - global deselectvertices - #global selectbyverts - - #Doodads - global dodoodads - global doodadfacechange - global seldoodad - global onprot - global dood1 - global dood2 - global dood3 - global dood4 - global dood5 - global dood6 - global doodadminamount - global doodadmaxamount - global doodsizemin - global doodsizemax - global doodheightmin - global doodheightmax - global doodonselface - global seldoodtop - - #Materials - global assignNewMats - global replProtSideIndex - global replProtTopIndex - global replDoodSideIndex - global replDoodTopIndex - - #Global Settings - global makenewobject - global messagetext - global errortext - global EVENT_NONE,EVENT_DRAW,EVENT_EXIT - - ######### Manages GUI events - if evt==EVENT_EXIT: - Exit() - elif evt==EVENT_DISCOMBOBULATE: - Window.WaitCursor(1) - setProtrusionValues(doprots.val,facechange.val/100,minheight.val,maxheight.val,sub1.val,sub2.val,sub3.val,sub4.val,mintaper.val/100,maxtaper.val/100,useselected.val,selface1.val,selface2.val,selface3.val,selface4.val,deselectvertices.val) - setDoodadValues(dodoodads.val,doodadfacechange.val/100,seldoodad.val,onprot.val,dood1.val,dood2.val,dood3.val,dood4.val,dood5.val,dood6.val,doodadminamount.val,doodadmaxamount.val,doodsizemin.val/100,doodsizemax.val/100,doodheightmin.val,doodheightmax.val,doodonselface.val,seldoodtop.val) - setOtherValues(makenewobject.val,assignNewMats.val,replProtSideIndex.val,replProtTopIndex.val,replDoodSideIndex.val,replDoodTopIndex.val) - discombobulate() - Window.WaitCursor(0) - Blender.Redraw() - -Register(draw, event, bevent) diff --git a/release/scripts/envelope_symmetry.py b/release/scripts/envelope_symmetry.py deleted file mode 100644 index a72e8c060b4..00000000000 --- a/release/scripts/envelope_symmetry.py +++ /dev/null @@ -1,174 +0,0 @@ -#!BPY - -""" -Name: 'Envelope Symmetry' -Blender: 234 -Group: 'Animation' -Tooltip: 'Make envelope symmetrical' -""" - -__author__ = "Jonas Petersen" -__url__ = ("blender", "blenderartists.org", "Script's homepage, http://www.mindfloaters.de/blender/", "thread at blender.org, http://www.blender.org/modules.php?op=modload&name=phpBB2&file=viewtopic&t=4858 ") -__version__ = "0.9 2004-11-10" -__doc__ = """\ -This script creates perfectly symmetrical envelope sets. It is part of the -envelop assignment tools. - -"Envelopes" are Mesh objects with names following this naming convention: - -: - -Please check the script's homepage and the thread at blender.org (last link button above) for more info. - -For this version users need to edit the script code to change default options. -""" - -# -------------------------------------------------------------------------- -# "Envelope Symmetry" by Jonas Petersen -# Version 0.9 - 10th November 2004 - first public release -# -------------------------------------------------------------------------- -# -# A script for creating perfectly symmetrical envelope sets. It is -# part of the envelope assignment tool. -# -# It is available in Object Mode via the menu item: -# -# Object -> Scripts -> Envelope Symmetry -# -# With default settings it will: -# -# - Look for bones -# -# Find the latest version at: http://www.mindfloaters.de/blender/ -# -# -------------------------------------------------------------------------- -# $Id$ -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004: Jonas Petersen, jonas at mindfloaters dot de -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - -# -------------------------------------------------------------------------- -# CONFIGURATION -# -------------------------------------------------------------------------- - -# Note: Theses values will later be editable via a gui interface -# within Blender. - -# The suffix for the reference and opposite envelope. -# The configuration of of the opposite envelope will be overwritten by -# the configuration of the reference envelope (shape, position, bone, weight). -# The default is REF_SUFFIX = '.L' and OPP_SUFFIX = '.R'. -REF_SUFFIX = '.R' -OPP_SUFFIX = '.L' - -# MIRROR_AXIS defines the axis in which bones are mirrored/aligned. -# Values: -# 0 for X (default) -# 1 for Y -# 2 for Z -MIRROR_AXIS = 0 - -# SEPARATOR is the character used to delimit the bone name and the weight -# in the envelope name. -SEPARATOR = ":" - -# -------------------------------------------------------------------------- -# END OF CONFIGURATION -# -------------------------------------------------------------------------- - -import Blender, math, sys -from Blender import Mathutils -from BPyNMesh import * - -def flipFace(v): - if len(v) == 3: v[0], v[1], v[2] = v[2], v[1], v[0] - elif len(v) == 4: v[0], v[1], v[2], v[3] = v[3], v[2], v[1], v[0] - -# return object with given object name (with variable parts) and mesh name -def getObjectByName(obj_name, mesh_name): - for obj in Blender.Scene.GetCurrent().objects: - if obj.type == "Mesh": -# if obj.getName()[0:len(obj_name)] == obj_name and obj.getData().name == mesh_name: - # use only mesh_name so bone name and weight (in the envelope name) - # can be changed by the user and mirrored by the script. - if obj.getData(name_only=1) == mesh_name: - return obj - return False - -SUFFIX_LEN = len(REF_SUFFIX); - -Blender.Window.EditMode(0) - -count = 0 -for obj in Blender.Scene.GetCurrent().objects: - if obj.type != 'Mesh': - continue - - count += 1 - name = obj.name - pos = name.find(SEPARATOR) - if (pos > -1): - ApplySizeAndRotation(obj) - - base_name = name[0:pos-SUFFIX_LEN] - suffix = name[pos-SUFFIX_LEN:pos] - weight = name[pos:len(name)] # the SEPARATOR following a float value - - if suffix == REF_SUFFIX: - mesh = obj.getData() - mirror_name = base_name + OPP_SUFFIX + weight - mirror_mesh_name = mesh.name + ".mirror" - - mirror_obj = getObjectByName(base_name + OPP_SUFFIX, mirror_mesh_name) - - if mirror_obj: - - # update vertices - - mirror_mesh = mirror_obj.getData() - for i in xrange(len(mesh.verts)): - org = mesh.verts[i] - mir = mirror_mesh.verts[i] - mir.co[0], mir.co[1], mir.co[2] = org.co[0], org.co[1], org.co[2] - mir.co[MIRROR_AXIS] *= -1 - - mirror_mesh.update() - else: - - # create mirror object - - mirror_mesh = obj.data - for face in mirror_mesh.faces: - flipFace(face.v) - for vert in mirror_mesh.verts: - vert.co[MIRROR_AXIS] *= -1 - - mirror_obj = Blender.NMesh.PutRaw(mirror_mesh, mirror_mesh_name) - - # update name, drawType and location - - mirror_obj.setName(mirror_name) - mirror_obj.drawType = obj.drawType - - loc = [obj.LocX, obj.LocY, obj.LocZ] - loc[MIRROR_AXIS] *= -1 - mirror_obj.setLocation(loc) - -Blender.Window.EditMode(0) diff --git a/release/scripts/export-iv-0.1.py b/release/scripts/export-iv-0.1.py deleted file mode 100644 index 647dd9c5518..00000000000 --- a/release/scripts/export-iv-0.1.py +++ /dev/null @@ -1,304 +0,0 @@ -#!BPY - -""" -Name: 'OpenInventor (.iv)...' -Blender: 236 -Group: 'Export' -Tip: 'Export to OpenInventor file format. (.iv)' -""" -__author__ = ("Radek Barton") -__url__ = ["http://blackhex.no-ip.org/"] -__email__ = ["scripts"] -__version__ = "0.1" - - -__bpydoc__ = """\ -This script exports to the Open Inventor format. - -Usage: - -Run this script from "File->Export" menu. - -Note: -""" -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Radek Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# - -import Blender -math_pi= 3.1415926535897931 - -def WriteHeader(file): - file.write("#Inventor V2.1 ascii\n\n") - file.write("Separator\n") - file.write("{\n") - file.write(" ShapeHints\n") - file.write(" {\n") - file.write(" vertexOrdering COUNTERCLOCKWISE\n") - file.write(" }\n") - -def WriteFooter(file): - file.write("}\n") - -def WriteMesh(file, ob): - file.write(" Separator\n") - file.write(" {\n") - file.write(" # %s\n" % ob.name) - WriteMatrix(file, ob) - mesh = ob.getData() - WriteMaterials(file, mesh) - WriteTexture(file, mesh) - WriteNormals(file, mesh) - WriteVertices(file, mesh) - WriteFaces(file, mesh) - file.write(" }\n") - -def WriteMatrix(file, ob): - matrix = ob.getMatrix() - file.write(" MatrixTransform\n") - file.write(" {\n") - file.write(" matrix\n") - for line in matrix: - file.write(" %.6f %.6f %.6f %.6f\n" % (line[0], line[1], line[2], line[3])) - file.write(" }\n") - -def WriteColors(file, mesh): - file.write(" vertexProperty VertexProperty\n") - file.write(" {\n") - file.write(" orderedRGBA\n") - file.write(" [\n") - for face in mesh.faces: - for I in xrange(len(face)): - file.write(" 0x%02x%02x%02x%02x,\n" % (face.col[I].r, - face.col[I].g, face.col[I].b, face.col[I].a)) - file.write(" ]\n") - file.write(" materialBinding PER_VERTEX\n") - file.write(" }\n") - -def WriteMaterials(file, mesh): - if mesh.materials: - file.write(" Material\n") - file.write(" {\n") - file.write(" ambientColor\n") - file.write(" [\n") - for mat in mesh.materials: - file.write(" %.6f %.6f %.6f,\n" % (mat.mirCol[0], mat.mirCol[1], - mat.mirCol[2])) - file.write(" ]\n") - file.write(" diffuseColor\n") - file.write(" [\n") - for mat in mesh.materials: - file.write(" %.6f %.6f %.6f,\n" % (mat.rgbCol[0], mat.rgbCol[1], - mat.rgbCol[2])) - file.write(" ]\n") - file.write(" specularColor\n") - file.write(" [\n") - for mat in mesh.materials: - file.write(" %.6f %.6f %.6f,\n" % (mat.specCol[0] * mat.spec / 2.0, - mat.specCol[1] * mat.spec / 2.0, mat.specCol[2] * mat.spec / 2.0)) - file.write(" ]\n") - file.write(" emissiveColor\n") - file.write(" [\n") - for mat in mesh.materials: - file.write(" %.6f %.6f %.6f,\n" % (mat.rgbCol[0] * mat.emit, - mat.rgbCol[1] * mat.emit, mat.rgbCol[0] * mat.emit)) - file.write(" ]\n") - file.write(" shininess\n") - file.write(" [\n") - for mat in mesh.materials: - file.write(" %.6f,\n" % (mat.hard / 255.0)) - file.write(" ]\n") - file.write(" transparency\n") - file.write(" [\n") - for mat in mesh.materials: - file.write(" %.6f,\n" % (1.0 - mat.alpha)) - file.write(" ]\n") - file.write(" }\n") - file.write(" MaterialBinding\n") - file.write(" {\n") - file.write(" value PER_FACE_INDEXED\n") - file.write(" }\n") - -def WriteTexture(file, mesh): - texture = mesh.faces[0].image # BAD Ju Ju - if texture: - file.write(" Texture2\n") - file.write(" {\n") - file.write(' filename "%s"\n' % texture.getName()) - file.write(" }\n") - file.write(" TextureCoordinate2\n") - file.write(" {\n") - file.write(" point\n") - file.write(" [\n") - if mesh.hasVertexUV(): - for vert in mesh.verts: - file.write(" %s %s,\n" % (vert.uvco[0], vert.uvco[1])) - file.write(" ]\n") - file.write(" }\n") - file.write(" TextureCoordinateBinding\n") - file.write(" {\n") - file.write(" value PER_VERTEX_INDEXED\n") - file.write(" }\n") - elif mesh.hasFaceUV(): - for face in mesh.faces: - for uv in face.uv: - file.write(" %.6f %.6f,\n" % (uv[0], uv[1])) - file.write(" ]\n") - file.write(" }\n") - file.write(" TextureCoordinateBinding\n") - file.write(" {\n") - file.write(" value PER_VERTEX\n") - file.write(" }\n") - -def WriteVertices(file, mesh): - file.write(" Coordinate3\n") - file.write(" {\n") - file.write(" point\n") - file.write(" [\n") - for vert in mesh.verts: - file.write(" %.6f %.6f %.6f,\n" % (vert[0], vert[1], vert[2])) - file.write(" ]\n") - file.write(" }\n") - -def WriteNormals(file, mesh): - file.write(" Normal\n") - file.write(" {\n") - file.write(" vector\n") - file.write(" [\n") - - # make copy of vertex normals - normals = [] - for face in mesh.faces: - if len(face.v) in [3, 4]: - if face.smooth: - for v in face.v: - normals.append(v.no) - else: - for v in face.v: - normals.append(face.no) - - # write normals - for no in normals: - file.write(" %.6f %.6f %.6f,\n" % (no[0], no[1], no[2])) - file.write(" ]\n") - file.write(" }\n") - - # write way how normals are binded - file.write(" NormalBinding\n") - file.write(" {\n") - file.write(" value PER_VERTEX\n") - file.write(" }\n") - -def WriteFaces(file, mesh): - file.write(" IndexedFaceSet\n") - file.write(" {\n") - - # write vertex paint - if mesh.hasVertexColours(): - WriteColors(file, mesh) - - # write material indexes - file.write(" materialIndex\n") - file.write(" [\n") - for face in mesh.faces: - file.write(" %i,\n" % face.mat); - file.write(" ]\n") - - # write faces with coordinate indexes - file.write(" coordIndex\n") - file.write(" [\n") - for face in mesh.faces: - face_v= face.v - if len(face_v) == 3: - file.write(" %i, %i, %i, -1,\n" % (face_v[0].index, - face_v[1].index, face_v[2].index)) - elif len(face_v) == 4: - file.write(" %i, %i, %i, %i, -1,\n" % (face_v[0].index, - face_v[1].index, face_v[2].index, face_v[3].index)) - file.write(" ]\n") - file.write(" }\n") - - -def WriteCamera(file, ob): - camera = ob.getData(); - # perspective camera - if camera.type == 0: - file.write(" PerspectiveCamera\n") - file.write(" {\n") - file.write(" nearDistance %s\n" % (camera.clipStart)) - file.write(" farDistance %s\n" % (camera.clipEnd)) - file.write(" }\n") - # ortho camera - else: - print camera.type - -def WriteLamp(file, ob): - lamp = ob.getData(); - # spot lamp - if lamp.type == 2: - file.write(" SpotLight\n") - file.write(" {\n") - file.write(" intensity %s\n" % (lamp.energy / 10.0)) - file.write(" color %s %s %s\n" % (lamp.col[0], lamp.col[1], lamp.col[2])) - #file.write(" location %s\n" % ()) - #file.write(" direction %s\n" % ()) - file.write(" dropOffRate %s\n" % (lamp.spotBlend)) - file.write(" cutOffAngle %s\n" % (lamp.spotSize * math_pi / 180.0)) - file.write(" }\n") - -# script main function -def ExportToIv(file_name): - scene = Blender.Scene.GetCurrent() - file = open(file_name, "w") - - # make lists of individual ob types - meshes = [] - lamps = [] - cameras = [] - for ob in scene.objects: - obtype= ob.type - if obtype == "Mesh": - meshes.append(ob); - #elif obtype == "Lamp": - # lamps.append(ob); - #elif obtype == "Camera": - # cameras.append(ob); - #else: - # print "Exporting %s objects isn't supported!" % ob.type - - # write header, footer and groups of ob types - WriteHeader(file); - #for camera in cameras: - # WriteCamera(file, camera); - #for lamp in lamps: - # WriteLamp(file, lamp) - for mesh in meshes: - WriteMesh(file, mesh) - WriteFooter(file) - - file.close() - -def FileSelectorCB(file_name): - if not file_name.lower().endswith('.iv'): - file_name += '.iv' - ExportToIv(file_name) - -if __name__ == '__main__': - Blender.Window.FileSelector(FileSelectorCB, "Export IV", Blender.sys.makename(ext='.iv')) diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py deleted file mode 100644 index 17f2132fbe8..00000000000 --- a/release/scripts/export_dxf.py +++ /dev/null @@ -1,3041 +0,0 @@ -#!BPY - -""" - Name: 'Autodesk DXF (.dxf/dwg)' - Blender: 249 - Group: 'Export' - Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).' -""" - -__version__ = "1.35 - 2009.06.18" -__author__ = "Remigiusz Fiedler (AKA migius)" -__license__ = "GPL" -__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" -__bpydoc__ ="""The script exports Blender geometry to DXF format r12 version. - -Version %s -Copyright %s -License %s - -extern dependances: dxfLibrary.py, dxfColorMap.py (optionaly: DConvertCon.exe) - -CONTRIBUTORS: -Remigiusz Fiedler (AKA migius) -Alexandros Sigalas (AKA alxarch) -Stani Michiels (AKA stani) - -See the homepage for documentation. -url: %s - -IDEAs: -- HPGL output, usefull for correct scaled printing of 2d drawings - -TODO: -- export dupligroups and dupliverts as blocks (as option) -- optimize POLYFACE routine: remove double-vertices -- fix support for X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert() -- support hierarchies: groups, instances, parented structures -- support n/f-gons as POLYFACEs with invisible edges -- mapping materials to DXF-styles -- ProgressBar -- export rotation of Camera to VIEW/VPORT -- export parented Cameras to VIEW/VPORT -- wip: write drawing extends for automatic view positioning in CAD -- wip: fix text-objects in persp-projection -- wip: translate current 3D-View to *ACTIVE-VPORT -- wip: fix support Include-Duplis, cause not conform with INSERT-method - -History -v1.35 - 2009.06.18 by migius -- export multiple-instances of Curve-Objects as BLOCK/INSERTs -- added export Cameras (ortho and persp) to VPORTs, incl. clipping -- added export Cameras (ortho and persp) to VIEWs, incl. clipping -- export multiple-instances of Mesh-Objects as BLOCK/INSERTs -- on start prints dxfLibrary version -v1.34 - 2009.06.08 by migius -- export Lamps and Cameras as POINTs -- export passepartout for perspective projection -- added option for export objects only from visible layers -- optimized POLYFACE output: remove loose vertices in back-faces-mode -- cleaning code -- fix nasty bug in getExtrusion() -- support text-objects, also in ortho/persp-projection -- support XYmirrored 2d-curves to 2dPOLYLINEs -- support thickness and elevation for curve-objects -- fix extrusion 210-code (3d orientation vector) -- fix POLYFACE export, synchronized also dxfLibrary.py -- changed to the new 2.49 method Vector.cross() -- output style manager (first try) -v1.33 - 2009.05.25 by migius -- bugfix flipping normals in mirrored mesh-objects -- added UI-Button for future Shadow Generator -- support curve objects in projection-2d mode -- UI stuff: camera selector/manager -v1.32 - 2009.05.22 by migius -- debug mode for curve-objects: output redirect to Blender -- wip support 210-code(extrusion) calculation -- default settings for 2D and 3D export -v1.31 - 2009.05.18 by migius -- globals translated to GUI_A/B dictionary -- optimizing back-faces removal for "hidden-lines" mode -- presets for global location and scale (architecture) -- UI layout: scrollbars, pan with MMB/WHEEL, dynamic width -- new GUI with Draw.Register() from DXF-importer.py -v1.30 - 2008.12.14 by migius -- started work on GUI with Draw.Register() -v1.29 - 2009.04.11 by stani -- added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter -v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch) -- added option to apply modifiers on exported meshes -- added option to also export duplicates (from dupliverts etc) -v1.28 - 2008.10.22 by migius -- workaround for PVert-bug on ubuntu (reported by Yorik) -- add support for FGons - ignore invisible_tagged edges -- add support for camera: ortho and perspective -v1.27 - 2008.10.07 by migius -- exclude Stani's DXF-Library to extern module -v1.26 - 2008.10.05 by migius -- add "hidden mode" substitut: back-faces removal -- add support for mesh ->POLYFACE -- optimized code for "Flat" procedure -v1.25 - 2008.09.28 by migius -- modif FACE class for r12 -- add mesh-polygon -> Bezier-curve converter (Yorik's code) -- add support for curves ->POLYLINEs -- add "3d-View to Flat" - geometry projection to XY-plane -v1.24 - 2008.09.27 by migius -- add start UI with preferences -- modif POLYLINE class for r12 -- changing output format from r9 to r12(AC1009) -v1.23 - 2008.09.26 by migius -- add finish message-box -v1.22 - 2008.09.26 by migius -- add support for curves ->LINEs -- add support for mesh-edges ->LINEs -v1.21 - 2008.06.04 by migius -- initial adaptation for Blender -v1.1 (20/6/2005) by Stani Michiels www.stani.be/python/sdxf -- Python library to generate dxf drawings -______________________________________________________________ -""" % (__author__,__version__,__license__,__url__) - -# -------------------------------------------------------------------------- -# Script copyright (C) 2008 Remigiusz Fiedler (AKA migius) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - - -import Blender -from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple -from Blender import Registry, Object, Mesh, Curve -import os -import subprocess - -try: - import dxfLibrary as DXF - #reload(DXF) - #reload(dxfLibrary) - #from dxfLibrary import * -except: - DXF=None - print "DXF-Exporter: error! found no dxfLibrary.py module in Blender script folder" - Draw.PupMenu("Error%t|found no dxfLibrary.py module in script folder") - - -import math -from math import atan, atan2, log10, sin, cos - -#pi = math.pi -#pi = 3.14159265359 -r2d = 180.0 / math.pi -d2r = math.pi / 180.0 -#note: d2r * angle == math.radians(angle) -#note: r2d * angle == math.degrees(angle) - - -#DEBUG = True #activates debug mode - - -#----globals------------------------------------------ -ONLYSELECTED = 1 # 0/1 = False/True -ONLYVISIBLE = 1 # ignore objects on invisible layers -POLYLINES = 1 # prefer POLYLINEs not LINEs -POLYFACES = 1 # prefer POLYFACEs not 3DFACEs -PROJECTION = 0 # output geometry will be projected to XYplane with Z=0.0 -HIDDEN_LINES = 0 #filter out hidden geometry -SHADOWS = 0 # sun/shadows simulation -CAMERA = 1 # selected camera index -PERSPECTIVE = 0 # projection (camera) type: perspective, opposite to orthographic -CAMERAVIEW = 0 # use camera for projection, opposite is 3d-view -INSTANCES = 1 # Export instances of Mesh/Curve as BLOCK/INSERTs on/off -APPLY_MODIFIERS = 1 -INCLUDE_DUPLIS = 0 -OUTPUT_DWG = 0 #optional save to DWG with extern converter - -G_SCALE = 1.0 #(0.0001-1000) global scaling factor for output dxf data -G_ORIGIN = [0.0,0.0,0.0] #global translation-vector (x,y,z) in Blender units -ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units - -BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults -BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults -PREFIX = 'BF_' #used as prefix for DXF names -LAYERNAME_DEF = '' #default layer name -LAYERCOLOR_DEF = 7 #default layer color index -LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType -ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index -ENTITYCOLOR_DEF = BYLAYER #default entity color index -ENTITYLTYPE_DEF = BYLAYER #default entity lineType - -E_M = 0 -LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction" -M_OBJ = 0 - -FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE) -NAMELENGTH_MAX = 80 #max_obnamelength in DXF, (limited to 256? ) -INIFILE_DEFAULT_NAME = 'exportDXF' -INIFILE_EXTENSION = '.ini' -INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data' -INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data' - -BLOCKREGISTRY = {} # registry and map for BLOCKs -SCENE = None -WORLDX = Mathutils.Vector((1,0,0)) -WORLDY = Mathutils.Vector((0,1,0)) -WORLDZ = Mathutils.Vector((0,0,1)) - -AUTO = BezTriple.HandleTypes.AUTO -FREE = BezTriple.HandleTypes.FREE -VECT = BezTriple.HandleTypes.VECT -ALIGN = BezTriple.HandleTypes.ALIGN - - -#-------- DWG support ------------------------------------------ -extCONV_OK = True -extCONV = 'DConvertCon.exe' -extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) -if not os.path.isfile(extCONV_PATH): - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ -Copy first %s into Blender script directory.|\ -More details in online Help.' %extCONV -else: - if not os.sys.platform.startswith('win'): - # check if Wine installed: - if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): - extCONV_PATH = 'wine %s'%extCONV_PATH - else: - extCONV_OK = False - extCONV_TEXT = 'DWG-Exporter: Abort, nothing done!|\ -The external DWG-converter (%s) needs Wine installed on your system.|\ -More details in online Help.' %extCONV -#print 'extCONV_PATH = ', extCONV_PATH - - -#---------------------------------------------- -def updateMenuCAMERA(): - global CAMERAS - global MenuCAMERA - global MenuLIGHT - - scn = Scene.GetCurrent() - objs = scn.getChildren() - currcam = scn.getCurrentCamera() - if currcam: currcam = currcam.getName() - maincams = [] - MenuCAMERA = "Select Camera%t" - for cam in objs: - if cam.getType() == 'Camera': - if cam.getName()[0:4] != "Temp": - maincams.append(cam.getName()) - maincams.sort() - maincams.reverse() - CAMERAS = maincams - for i, cam in enumerate(CAMERAS): - if cam==currcam: - MenuCAMERA += "|* " + cam - else: MenuCAMERA += "| " + cam - MenuCAMERA += "|current 3d-View" - MenuLIGHT = "Select Sun%t| *todo" - - -#---------------------------------------------- -def updateCAMERA(): - global CAMERA, GUI_A - #CAMERA = 1 - scn = Scene.GetCurrent() - currcam = scn.getCurrentCamera() - if currcam: currcam = currcam.getName() - if currcam in CAMERAS: - CAMERA = CAMERAS.index(currcam)+1 - GUI_A['camera_selected'].val = CAMERA - -#---------------------------------------------- -def gotoCAMERA(): - cam = Object.Get(CAMERAS[CAMERA-1]) - #print 'deb: CAMERA, cam',CAMERA, cam - if cam.getType() != 'Camera': - sure = Draw.PupMenu("Info: %t| It is not a Camera Object.") - else: - scn = Scene.getCurrent() - scn.setCurrentCamera(cam) - Window.CameraView(0) - Window.Redraw() - updateMenuCAMERA() - - -#------- Duplicates support ---------------------------------------------- -def dupTest(object): - """ - Checks objects for duplicates enabled (any type) - object: Blender Object. - Returns: Boolean - True if object has any kind of duplicates enabled. - """ - if (object.enableDupFrames or \ - object.enableDupGroup or \ - object.enableDupVerts): - return True - else: - return False - -def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): - """ - Return a list of real objects and duplicates and optionally their matrices - oblist: List of Blender Objects - MATRICES: Boolean - Check to also get the objects matrices, default=False - HACK: Boolean - See note, default=False - Returns: List of objects or - List of tuples of the form:(ob,matrix) if MATRICES is set to True - NOTE: There is an ugly hack here that excludes all objects whose name - starts with "dpl_" to exclude objects that are parented to a duplicating - object, User must name objects properly if hack is used. - """ - - result = [] - for ob in oblist: - if INCLUDE_DUPLIS and dupTest(ob): - dup_obs=ob.DupObjects - if len(dup_obs): - for dup_ob, dup_mx in dup_obs: - if MATRICES: - result.append((dup_ob,dup_mx)) - else: - result.append(dup_ob) - else: - if HACK: - if ob.getName()[0:4] != "dpl_": - if MATRICES: - mx = ob.mat - result.append((ob,mx)) - else: - result.append(ob) - else: - if MATRICES: - mx = ob.mat - result.append((ob,mx)) - else: - result.append(ob) - return result - -#----------------------------------------------------- -def hidden_status(faces, mx, mx_n): - # sort out back-faces = with normals pointed away from camera - #print 'HIDDEN_LINES: caution! not full implemented yet' - front_faces = [] - front_edges = [] - for f in faces: - #print 'deb: face=', f #--------- - #print 'deb: dir(face)=', dir(f) #--------- - # get its normal-vector in localCS - vec_normal = f.no.copy() - #print 'deb: vec_normal=', vec_normal #------------------ - # must be transfered to camera/view-CS - vec_normal *= mx_n - #vec_normal *= mb.rotationPart() - #print 'deb:2vec_normal=', vec_normal #------------------ - #vec_normal *= mw0.rotationPart() - #print 'deb:3vec_normal=', vec_normal, '\n' #------------------ - - - frontFace = False - if not PERSPECTIVE: #for ortho mode ---------- - # normal must point the Z direction-hemisphere - if vec_normal[2] > 0.00001: - frontFace = True - else: - v = f.verts[0] - vert = Mathutils.Vector(v.co) * mx - if Mathutils.DotVecs(vert, vec_normal) < 0.00001: - frontFace = True - - if frontFace: - front_faces.append(f.index) - for key in f.edge_keys: - #this test can be done faster with set() - if key not in front_edges: - front_edges.append(key) - - #print 'deb: amount of visible faces=', len(front_faces) #--------- - #print 'deb: visible faces=', front_faces #--------- - #print 'deb: amount of visible edges=', len(front_edges) #--------- - #print 'deb: visible edges=', front_edges #--------- - return front_faces, front_edges - - -#---- migration to 2.49------------------------------------------------- -if 'cross' in dir(Mathutils.Vector()): - #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!') - def M_CrossVecs(v1,v2): - return v1.cross(v2) #for up2.49 - def M_DotVecs(v1,v2): - return v1.dot(v2) #for up2.49 -else: - def M_CrossVecs(v1,v2): - return Mathutils.CrossVecs(v1,v2) #for pre2.49 - def M_DotVecs(v1,v2): - return Mathutils.DotVecs(v1,v2) #for pre2.49 - - -#----------------------------------------------------- -def getExtrusion(matrix): - """calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors - - """ - AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector - Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]] - if AZaxis[2]==1.0: - Extrusion = None - AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector - else: - threshold = 1.0 / 64.0 - if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold: - # AXaxis is the intersection WorldPlane and ExtrusionPlane - AXaxis = M_CrossVecs(WORLDY,AZaxis) - else: - AXaxis = M_CrossVecs(WORLDZ,AZaxis) - #print 'deb:\n' #------------- - #print 'deb:getExtrusion() Extrusion=', Extrusion #--------- - return Extrusion, AXaxis.normalize() - - -#----------------------------------------------------- -def getZRotation(AXaxis, rot_matrix_invert): - """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis - - """ - # this works: Xaxis is the obj.matrix-Xaxis vector - # but not correct for all orientations - #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector - ##Xaxis.normalize() # = ArbitraryXvector - #ZRotation = - Mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians - - # this works for all orientations, maybe a bit faster - # transform AXaxis into OCS:Object-Coord-System - #rot_matrix = normalizeMat(matrix.rotationPart()) - #rot_matrix_invert = rot_matrix.invert() - vec = AXaxis * rot_matrix_invert - ##vec = AXaxis * matrix.copy().invert() - ##vec.normalize() # not needed for atan2() - #print '\ndeb:getExtrusion() vec=', vec #--------- - ZRotation = - atan2(vec[1],vec[0]) #output in radians - - #print 'deb:ZRotation() ZRotation=', ZRotation*r2d #--------- - return ZRotation - - -#------------------------------------------ -def normalizeMat(matrix): - mat12 = matrix.copy() - mat12 = [Mathutils.Vector(v).normalize() for v in mat12] - if len(mat12)>3: - matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2],mat12[3]) - else: - matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2]) - return matr12 - - -#----------------------------------------------------- -def projected_co(verts, matrix): - """ converts coordinates of points from OCS to WCS->ScreenCS - needs matrix: a projection matrix - needs verts: a list of vectors[x,y,z] - returns a list of [x,y,z] - """ - #print 'deb:projected_co() verts=', verts #--------- - temp_verts = [Mathutils.Vector(v)*matrix for v in verts] - #print 'deb:projected_co() temp_verts=', temp_verts #--------- - - if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val - else: locZ = 0.0 - - if PROJECTION: - if PERSPECTIVE: - clipStart = 10.0 - for v in temp_verts: - coef = - clipStart / v[2] - v[0] *= coef - v[1] *= coef - v[2] = locZ - for v in temp_verts: - v[2] = locZ - temp_verts = [v[:3] for v in temp_verts] - #print 'deb:projected_co() out_verts=', temp_verts #--------- - return temp_verts - - -#----------------------------------------------------- -def isLeftHand(matrix): - #Is the matrix a left-hand-system, or not? - ma = matrix.rotationPart() - crossXY = M_CrossVecs(ma[0], ma[1]) - check = M_DotVecs(ma[2], crossXY) - if check < 0.00001: return 1 - return 0 - - -#----------------------------------------------------- -def exportMesh(ob, mx, mx_n, me=None, **common): - """converts Mesh-Object to desired projection and representation(DXF-Entity type) - """ - global BLOCKREGISTRY - entities = [] - block = None - #print 'deb:exportMesh() given common=', common #--------- - if me==None: - me = ob.getData(mesh=1) - else: - me.getFromObject(ob) - # idea: me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state - # the .transform-method is fast, but bad, cause invasive: - # it manipulates original geometry and by retransformation lefts back rounding-errors - # we dont want to manipulate original data! - #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug? - if me.verts: - #print 'deb:exportMesh() started' #--------- - - #print 'deb:exportMesh() ob.name=', ob.name #--------- - #print 'deb:exportMesh() me.name=', me.name #--------- - #print 'deb:exportMesh() me.users=', me.users #--------- - # check if there are more instances of this mesh (if used by other objects), then write to BLOCK/INSERT - if GUI_A['instances_on'].val and me.users>1 and not PROJECTION: - if me.name in BLOCKREGISTRY.keys(): - insert_name = BLOCKREGISTRY[me.name] - # write INSERT to entities - entities = exportInsert(ob, mx,insert_name, **common) - else: - # generate geom_output in ObjectCS - allpoints = [v.co for v in me.verts] - identity_matrix = Mathutils.Matrix().identity() - allpoints = projected_co(allpoints, identity_matrix) - #allpoints = toGlobalOrigin(allpoints) - faces=[] - edges=[] - for e in me.edges: edges.append(e.key) - faces = [[v.index for v in f.verts] for f in me.faces] - entities = writeMeshEntities(allpoints, edges, faces, **common) - if entities: # if not empty block - # write BLOCK definition and INSERT entity - # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name) - BLOCKREGISTRY[me.name]=validDXFr12name(('ME_'+ me.name)) - insert_name = BLOCKREGISTRY[me.name] - block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities) - # write INSERT as entity - entities = exportInsert(ob, mx, insert_name, **common) - - else: # no other instances, so go the standard way - allpoints = [v.co for v in me.verts] - allpoints = projected_co(allpoints, mx) - allpoints = toGlobalOrigin(allpoints) - faces=[] - edges=[] - if me.faces and PROJECTION and HIDDEN_LINES: - #if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #--------- - faces, edges = hidden_status(me.faces, mx, mx_n) - faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces] - else: - #if DEBUG: print 'deb:exportMesh STANDARD mode' #--------- - for e in me.edges: edges.append(e.key) - #faces = [f.index for f in me.faces] - faces = [[v.index for v in f.verts] for f in me.faces] - #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces] - #print 'deb: allpoints=\n', allpoints #--------- - #print 'deb: edges=\n', edges #--------- - #print 'deb: faces=\n', faces #--------- - if isLeftHand(mx): # then change vertex-order in every face - for f in faces: - f.reverse() - #f = [f[-1]] + f[:-1] #TODO: might be needed - #print 'deb: faces=\n', faces #--------- - entities = writeMeshEntities(allpoints, edges, faces, **common) - - return entities, block - - -#------------------------------------------------- -def writeMeshEntities(allpoints, edges, faces, **common): - """help routine for exportMesh() - """ - entities = [] - - c = mesh_as_list[GUI_A['mesh_as'].val] - if 'POINTs'==c: # export Mesh as multiple POINTs - for p in allpoints: - dxfPOINT = DXF.Point(points=[p],**common) - entities.append(dxfPOINT) - elif 'LINEs'==c or (not faces): - if edges and allpoints: - if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene - for e in edges: - points = [allpoints[e[0]], allpoints[e[1]]] - dxfLINE = DXF.Line(points, **common) - entities.append(dxfLINE) - elif faces: - if c in ('POLYFACE','POLYLINE'): - if allpoints: - #TODO: purge allpoints: left only vertices used by faces - if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene - if not (PROJECTION and HIDDEN_LINES): - faces = [[v+1 for v in f] for f in faces] - else: - # for back-Faces-mode remove face-free verts - map=verts_state= [0]*len(allpoints) - for f in faces: - for v in f: - verts_state[v]=1 - if 0 in verts_state: # if dirty state - i,newverts=0,[] - for used_i,used in enumerate(verts_state): - if used: - newverts.append(allpoints[used_i]) - map[used_i]=i - i+=1 - allpoints = newverts - faces = [[map[v]+1 for v in f] for f in faces] - dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common) - #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #------------- - entities.append(dxfPOLYFACE) - elif '3DFACEs'==c: - if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene - for f in faces: - #print 'deb: face=', f #--------- - points = [allpoints[key] for key in f] - #points = [p.co[:3] for p in points] - #print 'deb: pointsXX=\n', points #--------- - dxfFACE = DXF.Face(points, **common) - entities.append(dxfFACE) - - return entities - - -#----------------------------------------------------- -def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True): - #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #--------- - ob = Object.New("Mesh",name) - me = Mesh.New(name) - #print 'deb: vertList=\n', vertList #--------- - #print 'deb: edgeList=\n', edgeList #--------- - #print 'deb: faceList=\n', faceList #--------- - me.verts.extend(vertList) - if edgeList: me.edges.extend(edgeList) - if faceList: me.faces.extend(faceList) - if flatten: - for v in me.verts: v.co.z = 0.0 - ob.link(me) - if link: - sce = Scene.getCurrent() - sce.objects.link(ob) - #me.triangleToQuad() - if AT_CUR: - cur_loc = Window.GetCursorPos() - ob.setLocation(cur_loc) - Blender.Redraw() - #return ob - -#----------------------------------------------------- -def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True): - #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #--------- - ob = Object.New("Curve",name) - cu = Curve.New(name) - #print 'deb: vertList=\n', vertList #--------- - curve = cu.appendNurb(BezTriple.New(vertList[0])) - for p in vertList[1:]: - curve.append(BezTriple.New(p)) - for point in curve: - #point.handleTypes = [VECT, VECT] - point.handleTypes = [FREE, FREE] - point.radius = 1.0 - curve.flagU = closed # 0 sets the curve not cyclic=open - cu.setResolu(6) - cu.update() #important for handles calculation - if flatten: - for v in cu.verts: v.co.z = 0.0 - ob.link(cu) - if link: - sce = Scene.getCurrent() - sce.objects.link(ob) - #me.triangleToQuad() - if AT_CUR: - cur_loc = Window.GetCursorPos() - ob.setLocation(cur_loc) - elif org_point: - cur_loc=org_point - ob.setLocation(cur_loc) - Blender.Redraw() - #return ob - - -#----------------------------------------------------- -def toGlobalOrigin(points): - """relocates points to the new location - needs a list of points [x,y,z] - """ - if GUI_A['g_origin_on'].val: - for p in points: - p[0] += G_ORIGIN[0] - p[1] += G_ORIGIN[1] - p[2] += G_ORIGIN[2] - return points - - -#----------------------------------------------------- -def exportEmpty(ob, mx, mw, **common): - """converts Empty-Object to desired projection and representation(DXF-Entity type) - """ - p = Mathutils.Vector(ob.loc) - [p] = projected_co([p], mx) - [p] = toGlobalOrigin([p]) - - entities = [] - c = empty_as_list[GUI_A['empty_as'].val] - if c=="POINT": # export Empty as POINT - dxfPOINT = DXF.Point(points=[p],**common) - entities.append(dxfPOINT) - return entities - -#----------------------------------------------------- -def exportCamera(ob, mx, mw, **common): - """converts Camera-Object to desired projection and representation(DXF-Entity type) - """ - location = Mathutils.Vector(ob.loc) - [location] = projected_co([location], mx) - [location] = toGlobalOrigin([location]) - view_name=validDXFr12name(('CAM_'+ ob.name)) - - camera = Camera.Get(ob.getData(name_only=True)) - #print 'deb: camera=', dir(camera) #------------------ - if camera.type=='persp': - mode = 1+2+4+16 - # mode flags: 1=persp, 2=frontclip, 4=backclip,16=FrontZ - elif camera.type=='ortho': - mode = 0+2+4+16 - - leftBottom=(0.0,0.0) # default - rightTop=(1.0,1.0) # default - center=(0.0,0.0) # default - - direction = Mathutils.Vector(0.0,0.0,1.0) * mx.rotationPart() # in W-C-S - direction.normalize() - target=Mathutils.Vector(ob.loc) - direction # in W-C-S - #ratio=1.0 - width=height= camera.scale # for ortho-camera - lens = camera.lens # for persp-camera - frontClipping = -(camera.clipStart - 1.0) - backClipping = -(camera.clipEnd - 1.0) - - entities, vport, view = [], None, None - c = camera_as_list[GUI_A['camera_as'].val] - if c=="POINT": # export as POINT - dxfPOINT = DXF.Point(points=[location],**common) - entities.append(dxfPOINT) - elif c=="VIEW": # export as VIEW - view = DXF.View(name=view_name, - center=center, width=width, height=height, - frontClipping=frontClipping,backClipping=backClipping, - direction=direction,target=target,lens=lens,mode=mode - ) - elif c=="VPORT": # export as VPORT - vport = DXF.VPort(name=view_name, - center=center, ratio=1.0, height=height, - frontClipping=frontClipping,backClipping=backClipping, - direction=direction,target=target,lens=lens,mode=mode - ) - return entities, vport, view - -#----------------------------------------------------- -def exportLamp(ob, mx, mw, **common): - """converts Lamp-Object to desired projection and representation(DXF-Entity type) - """ - p = Mathutils.Vector(ob.loc) - [p] = projected_co([p], mx) - [p] = toGlobalOrigin([p]) - - entities = [] - c = lamp_as_list[GUI_A['lamp_as'].val] - if c=="POINT": # export as POINT - dxfPOINT = DXF.Point(points=[p],**common) - entities.append(dxfPOINT) - return entities - -#----------------------------------------------------- -def exportInsert(ob, mx, insert_name, **common): - """converts Object to DXF-INSERT in given orientation - """ - WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem - sizeX = ob.SizeX - sizeY = ob.SizeY - sizeZ = ob.SizeZ - rotX = ob.RotX - rotY = ob.RotY - rotZ = ob.RotZ - #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- - - Thickness,Extrusion,ZRotation,Elevation = None,None,None,None - - AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector - if not PROJECTION: - #Extrusion, ZRotation, Elevation = getExtrusion(mx) - Extrusion, AXaxis = getExtrusion(mx) - - entities = [] - - if 1: - if not PROJECTION: - ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ - AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) - ZRotation *= r2d - point = ECS_origin - else: #TODO: fails correct location - point1 = Mathutils.Vector(ob.loc) - [point] = projected_co([point1], mx) - if PERSPECTIVE: - clipStart = 10.0 - coef = -clipStart / (point1*mx)[2] - #print 'deb: coef=', coef #-------------- - #TODO: ? sizeX *= coef - #sizeY *= coef - #sizeZ *= coef - - #print 'deb: point=', point #-------------- - [point] = toGlobalOrigin([point]) - - #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene - common['extrusion']= Extrusion - #common['elevation']= Elevation - #print 'deb: common=', common #------------------ - if 0: #DEBUG - #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]] - linepoints = [[0,0,0], point] - dxfLINE = DXF.Line(linepoints,**common) - entities.append(dxfLINE) - - xscale=sizeX - yscale=sizeY - zscale=sizeZ - cols=None - colspacing=None - rows=None - rowspacing=None - - dxfINSERT = DXF.Insert(insert_name,point=point,rotation=ZRotation,\ - xscale=xscale,yscale=yscale,zscale=zscale,\ - cols=cols,colspacing=colspacing,rows=rows,rowspacing=rowspacing,\ - **common) - entities.append(dxfINSERT) - - return entities - - -#----------------------------------------------------- -def exportText(ob, mx, mw, **common): - """converts Text-Object to desired projection and representation(DXF-Entity type) - """ - text3d = ob.getData() - textstr = text3d.getText() - WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem - sizeX = ob.SizeX - sizeY = ob.SizeY - sizeZ = ob.SizeZ - rotX = ob.RotX - rotY = ob.RotY - rotZ = ob.RotZ - #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- - - Thickness,Extrusion,ZRotation,Elevation = None,None,None,None - - AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector - if not PROJECTION: - #Extrusion, ZRotation, Elevation = getExtrusion(mx) - Extrusion, AXaxis = getExtrusion(mx) - - # no thickness/width for TEXTs converted into ScreenCS - if text3d.getExtrudeDepth(): - Thickness = text3d.getExtrudeDepth() * sizeZ - - #Horizontal text justification type, code 72, (optional, default = 0) - # integer codes (not bit-coded) - #0=left, 1=center, 2=right - #3=aligned, 4=middle, 5=fit - Alignment = None - alignment = text3d.getAlignment().value - if alignment in (1,2): Alignment = alignment - - textHeight = text3d.getSize() / 1.7 - textFlag = 0 - if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored - if sizeZ < 0.0: textFlag |= 4 # vertical mirrored - - entities = [] - c = text_as_list[GUI_A['text_as'].val] - - if c=="TEXT": # export text as TEXT - if not PROJECTION: - ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ - AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) - ZRotation *= r2d - point = ECS_origin - else: #TODO: fails correct location - point1 = Mathutils.Vector(ob.loc) - [point] = projected_co([point1], mx) - if PERSPECTIVE: - clipStart = 10.0 - coef = -clipStart / (point1*mx)[2] - textHeight *= coef - #print 'deb: coef=', coef #-------------- - - #print 'deb: point=', point #-------------- - [point] = toGlobalOrigin([point]) - point2 = point - - #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene - common['extrusion']= Extrusion - #common['elevation']= Elevation - common['thickness']= Thickness - #print 'deb: common=', common #------------------ - if 0: #DEBUG - #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]] - linepoints = [[0,0,0], point] - dxfLINE = DXF.Line(linepoints,**common) - entities.append(dxfLINE) - - dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\ - flag=textFlag,height=textHeight,justifyhor=Alignment,**common) - entities.append(dxfTEXT) - if Thickness: - common['thickness']= -Thickness - dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\ - flag=textFlag,height=textHeight,justifyhor=Alignment,**common) - entities.append(dxfTEXT) - return entities - - -#------------------------------------------- -def euler2matrix(rx, ry, rz): - """creates full 3D rotation matrix (optimized) - needs rx, ry, rz angles in radians - """ - #print 'rx, ry, rz: ', rx, ry, rz - A, B = sin(rx), cos(rx) - C, D = sin(ry), cos(ry) - E, F = sin(rz), cos(rz) - AC, BC = A*C, B*C - return Mathutils.Matrix([D*F, D*E, -C], - [AC*F-B*E, AC*E+B*F, A*D], - [BC*F+A*E, BC*E-A*F, B*D]) - - -#----------------------------------------------------- -def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ): - """given - """ - if 1: - rot_matrix = normalizeMat(mx.rotationPart()) - #TODO: workaround for blender negative-matrix.invert() - # partially done: works only for rotX,rotY==0.0 - if sizeX<0.0: rot_matrix[0] *= -1 - if sizeY<0.0: rot_matrix[1] *= -1 - #if sizeZ<0.0: rot_matrix[2] *= -1 - rot_matrix_invert = rot_matrix.invert() - else: #TODO: to check, why below rot_matrix_invert is not equal above one - rot_euler_matrix = euler2matrix(rotX,rotY,rotZ) - rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ) - - # OCS_origin is Global_Origin in ObjectCoordSystem - OCS_origin = Mathutils.Vector(WCS_loc) * rot_matrix_invert - #print 'deb: OCS_origin=', OCS_origin #--------- - - ZRotation = rotZ - if Extrusion!=None: - ZRotation = getZRotation(AXaxis,rot_matrix_invert) - #Zrotmatrix = Mathutils.RotationMatrix(-ZRotation, 3, "Z") - rs, rc = sin(ZRotation), cos(ZRotation) - Zrotmatrix = Mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0]) - #print 'deb: Zrotmatrix=\n', Zrotmatrix #-------------- - - # ECS_origin is Global_Origin in EntityCoordSystem - ECS_origin = OCS_origin * Zrotmatrix - #print 'deb: ECS_origin=', ECS_origin #--------- - #TODO: it doesnt work yet for negative scaled curve-objects! - return ZRotation,Zrotmatrix,OCS_origin,ECS_origin - - -#----------------------------------------------------- -def exportCurve(ob, mx, mw, **common): - """converts Curve-Object to desired projection and representation(DXF-Entity type) - """ - entities = [] - block = None - curve = ob.getData() - #print 'deb: curve=', dir(curve) #--------- - # TODO: should be: if curve.users>1 and not (PERSPECTIVE or (PROJECTION and HIDDEN_MODE): - if GUI_A['instances_on'].val and curve.users>1 and not PROJECTION: - if curve.name in BLOCKREGISTRY.keys(): - insert_name = BLOCKREGISTRY[curve.name] - # write INSERT to entities - entities = exportInsert(ob, mx,insert_name, **common) - else: - # generate geom_output in ObjectCS - imx = Mathutils.Matrix().identity() - WCS_loc = [0,0,0] # WCS_loc is object location in WorldCoordSystem - #print 'deb: WCS_loc=', WCS_loc #--------- - sizeX = sizeY = sizeZ = 1.0 - rotX = rotY = rotZ = 0.0 - Thickness,Extrusion,ZRotation,Elevation = None,None,None,None - ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None - AXaxis = imx[0].copy().resize3D() # = ArbitraryXvector - OCS_origin = [0,0,0] - if not PROJECTION: - #Extrusion, ZRotation, Elevation = getExtrusion(mx) - Extrusion, AXaxis = getExtrusion(imx) - - # no thickness/width for POLYLINEs converted into Screen-C-S - #print 'deb: curve.ext1=', curve.ext1 #--------- - if curve.ext1: Thickness = curve.ext1 * sizeZ - if curve.ext2 and sizeX==sizeY: - Width = curve.ext2 * sizeX - if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE - ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(imx,Extrusion,\ - AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) - - entities = writeCurveEntities(curve, imx, - Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix, - WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ, - **common) - - if entities: # if not empty block - # write BLOCK definition and INSERT entity - # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name) - BLOCKREGISTRY[curve.name]=validDXFr12name(('CU_'+ curve.name)) - insert_name = BLOCKREGISTRY[curve.name] - block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities) - # write INSERT as entity - entities = exportInsert(ob, mx, insert_name, **common) - - else: # no other instances, so go the standard way - WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem - #print 'deb: WCS_loc=', WCS_loc #--------- - sizeX = ob.SizeX - sizeY = ob.SizeY - sizeZ = ob.SizeZ - rotX = ob.RotX - rotY = ob.RotY - rotZ = ob.RotZ - #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- - - Thickness,Extrusion,ZRotation,Elevation = None,None,None,None - ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None - AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector - OCS_origin = [0,0,0] - if not PROJECTION: - #Extrusion, ZRotation, Elevation = getExtrusion(mx) - Extrusion, AXaxis = getExtrusion(mx) - - # no thickness/width for POLYLINEs converted into Screen-C-S - #print 'deb: curve.ext1=', curve.ext1 #--------- - if curve.ext1: Thickness = curve.ext1 * sizeZ - if curve.ext2 and sizeX==sizeY: - Width = curve.ext2 * sizeX - if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE - ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ - AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) - entities = writeCurveEntities(curve, mx, - Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix, - WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ, - **common) - - return entities, block - - -#------------------------------------------------- -def writeCurveEntities(curve, mx, - Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix, - WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ, - **common): - """help routine for exportCurve() - """ - entities = [] - - if 1: - for cur in curve: - #print 'deb: START cur=', cur #-------------- - points = [] - if cur.isNurb(): - for point in cur: - #print 'deb:isNurb point=', point #--------- - vec = point[0:3] - #print 'deb: vec=', vec #--------- - pkt = Mathutils.Vector(vec) - #print 'deb: pkt=', pkt #--------- - points.append(pkt) - else: - for point in cur: - #print 'deb:isBezier point=', point.getTriple() #--------- - vec = point.getTriple()[1] - #print 'deb: vec=', vec #--------- - pkt = Mathutils.Vector(vec) - #print 'deb: pkt=', pkt #--------- - points.append(pkt) - - #print 'deb: points', points #-------------- - if len(points)>1: - c = curve_as_list[GUI_A['curve_as'].val] - - if c=="POLYLINE": # export Curve as POLYLINE - if not PROJECTION: - # recalculate points(2d=X,Y) into Entity-Coords-System - for p in points: # list of vectors - p[0] *= sizeX - p[1] *= sizeY - p2 = p * Zrotmatrix - p2[0] += ECS_origin[0] - p2[1] += ECS_origin[1] - p[0],p[1] = p2[0],p2[1] - else: - points = projected_co(points, mx) - #print 'deb: points', points #-------------- - - if cur.isCyclic(): closed = 1 - else: closed = 0 - points = toGlobalOrigin(points) - - if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene - - common['extrusion']= Extrusion - ##common['rotation']= ZRotation - ##common['elevation']= Elevation - common['thickness']= Thickness - #print 'deb: common=', common #------------------ - - if 0: #DEBUG - p=AXaxis[:3] - entities.append(DXF.Line([[0,0,0], p],**common)) - p=ECS_origin[:3] - entities.append(DXF.Line([[0,0,0], p],**common)) - common['color']= 5 - p=OCS_origin[:3] - entities.append(DXF.Line([[0,0,0], p],**common)) - #OCS_origin=[0,0,0] #only debug---------------- - dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common) - entities.append(dxfPLINE) - - dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common) - entities.append(dxfPLINE) - if Thickness: - common['thickness']= -Thickness - dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common) - entities.append(dxfPLINE) - - elif c=="LINEs": # export Curve as multiple LINEs - points = projected_co(points, mx) - if cur.isCyclic(): points.append(points[0]) - #print 'deb: points', points #-------------- - points = toGlobalOrigin(points) - - if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene - common['extrusion']= Extrusion - common['elevation']= Elevation - common['thickness']= Thickness - #print 'deb: common=', common #------------------ - for i in range(len(points)-1): - linepoints = [points[i], points[i+1]] - dxfLINE = DXF.Line(linepoints,**common) - entities.append(dxfLINE) - if Thickness: - common['thickness']= -Thickness - for i in range(len(points)-1): - linepoints = [points[i], points[i+1]] - dxfLINE = DXF.Line(linepoints,**common) - entities.append(dxfLINE) - - elif c=="POINTs": # export Curve as multiple POINTs - points = projected_co(points, mx) - for p in points: - dxfPOINT = DXF.Point(points=[p],**common) - entities.append(dxfPOINT) - return entities - - -#----------------------------------------------------- -def getClipBox(camera): - """calculates Field-of-View-Clipping-Box of given Camera - returns clip_box: a list of vertices - returns matr: translation matrix - """ - sce = Scene.GetCurrent() - context = sce.getRenderingContext() - #print 'deb: context=\n', context #------------------ - sizeX = context.sizeX - sizeY = context.sizeY - ratioXY = sizeX/float(sizeY) - #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------ - - clip1_Z = - camera.clipStart - clip2_Z = - camera.clipEnd - #print 'deb: clip Start=', camera.clipStart #------------------ - #print 'deb: clip End=', camera.clipEnd #------------------ - - if camera.type=='ortho': - scale = camera.scale - #print 'deb: camscale=', scale #------------------ - clip1shiftX = clip2shiftX = camera.shiftX * scale - clip1shiftY = clip2shiftY = camera.shiftY * scale - clip1_X = scale * 0.5 - clip1_Y = scale * 0.5 - if ratioXY > 1.0: clip1_Y /= ratioXY - else: clip1_X *= ratioXY - clip2_X = clip1_X - clip2_Y = clip1_Y - - near = clip1_Z - far = clip2_Z - right, left = clip1_X, -clip1_X - top, bottom = clip1_Y, -clip1_Y - - scaleX = 2.0/float(right - left) - x3 = -float(right + left)/float(right - left) - scaleY = 2.0/float(top - bottom) - y3 = -float(top + bottom)/float(top - bottom) - scaleZ = 1.0/float(far - near) - z3 = -float(near)/float(far - near) - - matrix = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3], - [0.0, scaleY, 0.0, y3], - [0.0, 0.0, scaleZ, z3], - [0.0, 0.0, 0.0, 1.0]) - - elif camera.type=='persp': - #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe - #lens = camera.lens - angle = camera.angle - #print 'deb: cam angle=', angle #------------------ - shiftX = camera.shiftX - shiftY = camera.shiftY - fov_coef = atan(angle * d2r) - fov_coef *= 1.3 #incl. passpartou - clip1_k = clip1_Z * fov_coef - clip2_k = clip2_Z * fov_coef - clip1shiftX = - camera.shiftX * clip1_k - clip2shiftX = - camera.shiftX * clip2_k - clip1shiftY = - camera.shiftY * clip1_k - clip2shiftY = - camera.shiftY * clip2_k - clip1_X = clip1_Y = clip1_k * 0.5 - clip2_X = clip2_Y = clip2_k * 0.5 - if ratioXY > 1.0: - clip1_Y /= ratioXY - clip2_Y /= ratioXY - else: - clip1_X *= ratioXY - clip2_X *= ratioXY - - near = clip1_Z - far = clip2_Z - right, left = clip1_X, -clip1_X - top, bottom = clip1_Y, -clip1_Y - #return Matrix( [scaleX, 0.0, x2, 0.0], - #[0.0, scaleY, y2, 0.0], - #[0.0, 0.0, scaleZ, wZ], - #[0.0, 0.0, -1.0, 0.0]) - matrix = Mathutils.Matrix( [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0], - [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0], - [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)], - [0.0, 0.0, -1.0, 0.0]) - - - clip_box = [ - -clip1_X + clip1shiftX, clip1_X + clip1shiftX, - -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY, - -clip2_X + clip2shiftX, clip2_X + clip2shiftX, - -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY, - clip1_Z, clip2_Z] - #print 'deb: clip_box=\n', clip_box #------------------ - #drawClipBox(clip_box) - return clip_box, matrix - - -#----------------------------------------------------- -def drawClipBox(clip_box): - """debug tool: draws Clipping-Box of a Camera View - """ - min_X1, max_X1, min_Y1, max_Y1,\ - min_X2, max_X2, min_Y2, max_Y2,\ - min_Z, max_Z = clip_box - verts = [] - verts.append([min_X1, min_Y1, min_Z]) - verts.append([max_X1, min_Y1, min_Z]) - verts.append([max_X1, max_Y1, min_Z]) - verts.append([min_X1, max_Y1, min_Z]) - verts.append([min_X2, min_Y2, max_Z]) - verts.append([max_X2, min_Y2, max_Z]) - verts.append([max_X2, max_Y2, max_Z]) - verts.append([min_X2, max_Y2, max_Z]) - faces = [[0,1,2,3],[4,5,6,7]] - newmesh = Mesh.New() - newmesh.verts.extend(verts) - newmesh.faces.extend(faces) - - plan = Object.New('Mesh','clip_box') - plan.link(newmesh) - sce = Scene.GetCurrent() - sce.objects.link(plan) - plan.setMatrix(sce.objects.camera.matrix) - - -#------------------------------------------------- -def getCommons(ob): - """set up common attributes for output style: - color=None - extrusion=None - layer='0', - lineType=None - lineTypeScale=None - lineWeight=None - thickness=None - parent=None - """ - - layers = ob.layers #gives a list e.g.[1,5,19] - if layers: ob_layer_nr = layers[0] - #print 'ob_layer_nr=', ob_layer_nr #-------------- - - materials = ob.getMaterials() - if materials: - ob_material = materials[0] - ob_mat_color = ob_material.rgbCol - else: ob_mat_color, ob_material = None, None - #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #-------------- - - data = ob.getData() - data_materials = ob.getMaterials() - if data_materials: - data_material = data_materials[0] - data_mat_color = data_material.rgbCol - else: data_mat_color, data_material = None, None - #print 'data_mat_color, data_material=', data_mat_color, data_material #-------------- - - entitylayer = ENTITYLAYER_DEF - c = entitylayer_from_list[GUI_A['entitylayer_from'].val] - #["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"] - if c=="default_LAYER": - entitylayer = LAYERNAME_DEF - elif c=="obj.layer" and ob_layer_nr: - entitylayer = 'LAYER'+ str(ob_layer_nr) - elif c=="obj.material" and ob_material: - entitylayer = ob_material.name - elif c=="obj.name": - entitylayer = ob.name - elif c=="obj.data.material" and ob_material: - entitylayer = data_material.name - elif c=="obj.data.name": - entitylayer = data.name - entitylayer = validDXFr12name(PREFIX+entitylayer) - if entitylayer=="": entitylayer = "BF_0" - - entitycolor = ENTITYCOLOR_DEF - c = entitycolor_from_list[GUI_A['entitycolor_from'].val] - if c=="default_COLOR": - entitycolor = LAYERCOLOR_DEF - elif c=="BYLAYER": - entitycolor = BYLAYER - elif c=="BYBLOCK": - entitycolor = BYBLOCK - elif c=="obj.layer" and ob_layer_nr: - entitycolor = ob_layer_nr - elif c=="obj.color" and ob.color: - entitycolor = col2DXF(ob.color) - elif c=="obj.material" and ob_mat_color: - entitycolor = col2DXF(ob_mat_color) - elif c=="obj.data.material" and data_mat_color: - entitycolor = col2DXF(data_mat_color) - #if entitycolor!=None: layercolor = entitycolor - - entityltype = ENTITYLTYPE_DEF - c = entityltype_from_list[GUI_A['entityltype_from'].val] - if c=="default_LTYPE": - entityltype = LAYERLTYPE_DEF - elif c=="BYLAYER": - entityltype = BYLAYER - elif c=="BYBLOCK": - entityltype = BYBLOCK - elif c: - entityltype = c - - return entitylayer,entitycolor,entityltype - - -#----------------------------------------------------- -def do_export(export_list, filepath): - global PERSPECTIVE, CAMERAVIEW, BLOCKREGISTRY - Window.WaitCursor(1) - t = Blender.sys.time() - - # init Drawing --------------------- - d=DXF.Drawing() - # add Tables ----------------- - # initialized automatic: d.blocks.append(b) #section BLOCKS - # initialized automatic: d.styles.append(DXF.Style()) #table STYLE - - #table LTYPE --------------- - #d.linetypes.append(DXF.LineType(name='CONTINUOUS',description='--------',elements=[0.0])) - d.linetypes.append(DXF.LineType(name='DOT',description='. . . . . . .',elements=[0.25, 0.0, -0.25])) - d.linetypes.append(DXF.LineType(name='DASHED',description='__ __ __ __ __',elements=[0.8, 0.5, -0.3])) - d.linetypes.append(DXF.LineType(name='DASHDOT',description='__ . __ . __ .',elements=[1.0, 0.5, -0.25, 0.0, -0.25])) - d.linetypes.append(DXF.LineType(name='DIVIDE',description='____ . . ____ . . ',elements=[1.25, 0.5, -0.25, 0.0, -0.25, 0.0, -0.25])) - d.linetypes.append(DXF.LineType(name='BORDER',description='__ __ . __ __ . ',elements=[1.75, 0.5, -0.25, 0.5, -0.25, 0.0, -0.25])) - d.linetypes.append(DXF.LineType(name='HIDDEN',description='__ __ __ __ __',elements=[0.4, 0.25, -0.25])) - d.linetypes.append(DXF.LineType(name='CENTER',description='____ _ ____ _ __',elements=[2.0, 1.25, -0.25, 0.25, -0.25])) - - #d.vports.append(DXF.VPort('*ACTIVE')) - d.vports.append(DXF.VPort('*ACTIVE',center=(-5.0,1.0),height=10.0)) - #d.vports.append(DXF.VPort('*ACTIVE',leftBottom=(-100.0,-60.0),rightTop=(100.0,60.0))) - #d.views.append(DXF.View('Normal')) #table view - d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem - - # add Entities -------------------- - BLOCKREGISTRY = {} # registry and map for BLOCKs - PERSPECTIVE = 0 - something_ready = 0 - selected_len = len(export_list) - sce = Scene.GetCurrent() - - mw = Mathutils.Matrix( [1.0, 0.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, 1.0]) - if PROJECTION: - if CAMERA ',\n' - # replace: '{' -> '\n{\n' - # replace: '}' -> '\n}\n' - output_str = ',\n'.join(output_str.split(',')) - output_str = '\n}'.join(output_str.split('}')) - output_str = '{\n'.join(output_str.split('{')) - try: - f = file(iniFile, 'w') - f.write(INIFILE_HEADER + '\n# this is a comment line\n') - f.write(output_str) - f.close() - #Draw.PupMenu('DXF-Exporter: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile) - except: - Draw.PupMenu('DXF-Exporter: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile) - - else: - Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid name/extension for INI-file selected!') - print "DXF-Exporter: Alert!: no valid INI-file selected." - if not iniFile: - if dxfFileName.val.lower().endswith('.dxf'): - iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION - - -def loadConfig(): #remi--todo----------------------------------------------- - """Load settings/config/materials from INI-file. - - TODO: Read material-assignements from config-file. - """ - #20070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename) - global iniFileName, GUI_A, GUI_B - - iniFile = iniFileName.val - update_RegistryKey('iniFileName', iniFile) - #print 'deb:loadConfig iniFile: ', iniFile #---------------------- - if iniFile.lower().endswith(INIFILE_EXTENSION) and Blender.sys.exists(iniFile): - f = file(iniFile, 'r') - header_str = f.readline() - if header_str.startswith(INIFILE_HEADER): - data_str = f.read() - f.close() - #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #----------------- - data = eval(data_str) - for k, v in data[0].iteritems(): - try: GUI_A[k].val = v - except: GUI_A[k] = Draw.Create(v) - for k, v in data[1].iteritems(): - try: GUI_B[k].val = v - except: GUI_B[k] = Draw.Create(v) - else: - f.close() - Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile) - else: - Draw.PupMenu('DXF-Exporter: INI-file: Alert!%t|no valid INI-file selected!') - print "DXF-Exporter: Alert!: no valid INI-file selected." - if not iniFileName: - if dxfFileName.val.lower().endswith('.dxf'): - iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION - - - -def updateConfig(keywords, drawTypes): #----------------------------------------------- - """updates GUI_settings with given dictionaries - - """ - global GUI_A, GUI_B - #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #--------- - for k, v in keywords.iteritems(): - GUI_A[k].val = v - for k, v in drawTypes.iteritems(): - GUI_B[k].val = v - -def resetDefaultConfig(): #----------------------------------------------- - """Resets settings/config/materials to defaults. - - """ - #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #--------- - updateConfig(keywords_org, drawTypes_org) - - -def presetConfig_polyline(activate): #----------------------------------------------- - """Sets settings/config for polygon representation: POLYLINE(FACE) or LINEs/3DFACEs. - - """ - global GUI_A - if activate: - GUI_A['to_polyline_on'].val = 1 - GUI_A['mesh_as'].val = 1 - GUI_A['curve_as'].val = 1 - else: - GUI_A['to_polyline_on'].val = 0 - GUI_A['mesh_as'].val = 0 - GUI_A['curve_as'].val = 0 - -def resetDefaultConfig_2D(): #----------------------------------------------- - """Sets settings/config/materials to defaults 2D. - - """ - keywords2d = { - 'projection_on' : 1, - 'fill_on' : 1, - 'text_as' : 0, - 'group_as' : 0, - } - - drawTypes2d = { - 'bmesh' : 1, - 'bcurve': 1, - 'surface':0, - 'bmeta' : 0, - 'text' : 1, - 'empty' : 1, - 'group' : 1, - 'parent' : 1, - #'proxy' : 0, - #'camera': 0, - #'lamp' : 0, - - } - presetConfig_polyline(1) - updateConfig(keywords2d, drawTypes2d) - -def resetDefaultConfig_3D(): #----------------------------------------------- - """Sets settings/config/materials to defaults 3D. - - """ - keywords3d = { - 'projection_on' : 0, - 'fill_on' : 0, - 'text_as' : 0, - 'group_as' : 0, - } - - drawTypes3d = { - 'bmesh' : 1, - 'bcurve': 1, - 'surface':0, - 'bmeta' : 0, - 'text' : 0, - 'empty' : 1, - 'group' : 1, - 'parent' : 1, - #'proxy' : 0, - #'camera': 1, - #'lamp' : 1, - } - presetConfig_polyline(1) - updateConfig(keywords3d, drawTypes3d) - - -def inputGlobalScale(): - """Pop-up UI-Block for global scale factor - """ - global GUI_A - #print 'deb:inputGlobalScale ##########' #------------ - x_scale = Draw.Create(GUI_A['g_scale'].val) - block = [] - #block.append("global translation vector:") - block.append(("", x_scale, 0.0, 10000000.0)) - - retval = Draw.PupBlock("set global scale factor:", block) - - GUI_A['g_scale'].val = float(x_scale.val) - - -def inputOriginVector(): - """Pop-up UI-Block for global translation vector - """ - global GUI_A - #print 'deb:inputOriginVector ##########' #------------ - x_origin = Draw.Create(GUI_A['g_originX'].val) - y_origin = Draw.Create(GUI_A['g_originY'].val) - z_origin = Draw.Create(GUI_A['g_originZ'].val) - block = [] - #block.append("global translation vector:") - block.append(("X: ", x_origin, -100000000.0, 100000000.0)) - block.append(("Y: ", y_origin, -100000000.0, 100000000.0)) - block.append(("Z: ", z_origin, -100000000.0, 100000000.0)) - - retval = Draw.PupBlock("set global translation vector:", block) - - GUI_A['g_originX'].val = x_origin.val - GUI_A['g_originY'].val = y_origin.val - GUI_A['g_originZ'].val = z_origin.val - - -def update_globals(): #----------------------------------------------------------------- - """ update globals if GUI_A changed - """ - global ONLYSELECTED,ONLYVISIBLE, DEBUG,\ - PROJECTION, HIDDEN_LINES, CAMERA, \ - G_SCALE, G_ORIGIN,\ - PREFIX, LAYERNAME_DEF, LAYERCOLOR_DEF, LAYERLTYPE_DEF,\ - APPLY_MODIFIERS, INCLUDE_DUPLIS,\ - OUTPUT_DWG - #global POLYLINES - - ONLYSELECTED = GUI_A['only_selected_on'].val - ONLYVISIBLE = GUI_A['only_visible_on'].val - """ - POLYLINES = GUI_A['to_polyline_on'].val - if GUI_A['curve_as'].val==1: POLYLINES=1 - else: POLYLINES=0 - """ - - if GUI_A['optimization'].val==0: DEBUG = 1 - else: DEBUG = 0 - PROJECTION = GUI_A['projection_on'].val - HIDDEN_LINES = GUI_A['hidden_lines_on'].val - CAMERA = GUI_A['camera_selected'].val - G_SCALE = GUI_A['g_scale'].val - if GUI_A['g_origin_on'].val: - G_ORIGIN[0] = GUI_A['g_originX'].val - G_ORIGIN[1] = GUI_A['g_originY'].val - G_ORIGIN[2] = GUI_A['g_originZ'].val - if GUI_A['g_scale_on'].val: - G_ORIGIN[0] *= G_SCALE - G_ORIGIN[1] *= G_SCALE - G_ORIGIN[2] *= G_SCALE - - PREFIX = GUI_A['prefix_def'].val - LAYERNAME_DEF = GUI_A['layername_def'].val - LAYERCOLOR_DEF = GUI_A['layercolor_def'].val - LAYERLTYPE_DEF = layerltype_def_list[GUI_A['layerltype_def'].val] - - APPLY_MODIFIERS = GUI_A['apply_modifiers_on'].val - INCLUDE_DUPLIS = GUI_A['include_duplis_on'].val - OUTPUT_DWG = GUI_A['outputDWG_on'].val - #print 'deb: GUI HIDDEN_LINES=', HIDDEN_LINES #--------- - #print 'deb: GUI GUI_A: ', GUI_A['hidden_lines_on'].val #--------------- - #print 'deb: GUI GUI_B: ', GUI_B #--------------- - - -def draw_UI(): #----------------------------------------------------------------- - """ Draw startUI and setup Settings. - """ - global GUI_A, GUI_B #__version__ - global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as - global model_space_on - global SCROLL - - global mPAN_X, menu_orgX, mPAN_Xmax - global mPAN_Y, menu_orgY, mPAN_Ymax - global menu__Area, headerArea, screenArea, scrollArea - - size=Buffer(GL_FLOAT, 4) - glGetFloatv(GL_SCISSOR_BOX, size) #window X,Y,sizeX,sizeY - size= size.list - #print '-------------size:', size #-------------------------- - for s in [0,1,2,3]: size[s]=int(size[s]) - window_Area = [0,0,size[2],size[3]-2] - scrollXArea = [0,0,window_Area[2],15] - scrollYArea = [0,0,15,window_Area[3]] - - menu_orgX = -mPAN_X - #menu_orgX = 0 #scrollW - #if menu_pan: menu_orgX -= mPAN_X - if menu_orgX < -mPAN_Xmax: menu_orgX, mPAN_X = -mPAN_Xmax,mPAN_Xmax - if menu_orgX > 0: menu_orgX, mPAN_X = 0,0 - - menu_orgY = -mPAN_Y - #if menu_pan: menu_orgY -= mPAN_Y - if menu_orgY < -mPAN_Ymax: menu_orgY, mPAN_Y = -mPAN_Ymax,mPAN_Ymax - if menu_orgY > 0: menu_orgY, mPAN_Y = 0,0 - - - menu_margin = 10 - butt_margin = 10 - common_column = int((window_Area[2] - (3 * butt_margin) - (2 * menu_margin)-30) / 4.0) - common_column = 70 - # This is for easy layout changes - but_0c = common_column #button 1.column width - but_1c = common_column #button 1.column width - but_2c = common_column #button 2.column - but_3c = common_column #button 3.column - menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width - - simple_menu_h = 260 - extend_menu_h = 345 - menu_h = simple_menu_h # y is menu upper.y - if config_UI.val: - menu_h += extend_menu_h - - mPAN_Xmax = menu_w-window_Area[2]+50 - mPAN_Ymax = menu_h-window_Area[3]+30 - - y = menu_h - x = 0 #menu left.x - x +=menu_orgX+20 - y +=menu_orgY+20 - - - but0c = x + menu_margin #buttons 0.column position.x - but1c = but0c + but_0c + butt_margin - but2c = but1c + but_1c + butt_margin - but3c = but2c + but_2c + butt_margin - but4c = but3c + but_3c - - # Here starts menu ----------------------------------------------------- - #glClear(GL_COLOR_BUFFER_BIT) - #glRasterPos2d(8, 125) - - - ui_box(x, y, x+menu_w+menu_margin*2, y-menu_h) - y -= 20 - Draw.Label("DXF(r12)-Exporter v" + __version__, but0c, y, menu_w, 20) - - if config_UI.val: - b0, b0_ = but0c, but_0c-20 + butt_margin - b1, b1_ = but1c-20, but_1c+20 - y_top = y - - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_B['bmesh'] = Draw.Toggle('Mesh', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmesh'].val, "Export Mesh-Objects on/off") - if GUI_B['bmesh'].val: - GUI_A['mesh_as'] = Draw.Menu(mesh_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['mesh_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['bcurve'] = Draw.Toggle('Curve', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bcurve'].val, "Export Curve-Objects on/off") - if GUI_B['bcurve'].val: - GUI_A['curve_as'] = Draw.Menu(curve_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['curve_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['surface'] = Draw.Toggle('..Surface', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['surface'].val, "(*todo) Export Surface-Objects on/off") - if GUI_B['surface'].val: - GUI_A['surface_as'] = Draw.Menu(surface_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['surface_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['bmeta'] = Draw.Toggle('..Meta', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['bmeta'].val, "(*todo) Export Meta-Objects on/off") - if GUI_B['bmeta'].val: - GUI_A['meta_as'] = Draw.Menu(meta_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['meta_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['text'] = Draw.Toggle('Text', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['text'].val, "Export Text-Objects on/off") - if GUI_B['text'].val: - GUI_A['text_as'] = Draw.Menu(text_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['text_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['empty'] = Draw.Toggle('Empty', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['empty'].val, "Export Empty-Objects on/off") - if GUI_B['empty'].val: - GUI_A['empty_as'] = Draw.Menu(empty_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['empty_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y_down = y - # ----------------------------------------------- - - y = y_top - b0, b0_ = but2c, but_2c-20 + butt_margin - b1, b1_ = but3c-20, but_3c+20 - - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_B['group'] = Draw.Toggle('..Group', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['group'].val, "(*todo) Export Group-Relationships on/off") - if GUI_B['group'].val: - GUI_A['group_as'] = Draw.Menu(group_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['group_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['parent'] = Draw.Toggle('..Parent', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['parent'].val, "(*todo) Export Parent-Relationships on/off") - if GUI_B['parent'].val: - GUI_A['parent_as'] = Draw.Menu(parent_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['parent_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['proxy'] = Draw.Toggle('..Proxy', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['proxy'].val, "(*todo) Export Proxy-Objects on/off") - if GUI_B['proxy'].val: - GUI_A['proxy_as'] = Draw.Menu(proxy_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['proxy_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['camera'] = Draw.Toggle('Camera', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['camera'].val, "(*wip) Export Camera-Objects on/off") - if GUI_B['camera'].val: - GUI_A['camera_as'] = Draw.Menu(camera_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['camera_as'].val, "Select target DXF-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['lamp'] = Draw.Toggle('Lamp', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['lamp'].val, "(*wip) Export Lamp-Objects on/off") - if GUI_B['lamp'].val: - GUI_A['lamp_as'] = Draw.Menu(lamp_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['lamp_as'].val, "Select target DXF-object") - Draw.EndAlign() - - - if y < y_down: y_down = y - # -----end supported objects-------------------------------------- - - y_top = y_down - y = y_top - y -= 10 - y -= 20 - but_ = menu_w / 6 - b0 = but0c + (menu_w - but_*6)/2 - Draw.BeginAlign() - #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['dummy_on'].val, "placeholder only on/off") - GUI_A['paper_space_on'] = Draw.Toggle('Paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "Export to Paper-Space, otherwise to Model-Space on/off") - GUI_A['layFrozen_on'] = Draw.Toggle ('..frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "(*todo) Support LAYER.frozen status on/off") - GUI_A['materialFilter_on'] = Draw.Toggle('..material', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['materialFilter_on'].val, "(*todo) Material filtering on/off") - GUI_A['colorFilter_on'] = Draw.Toggle('..color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*todo) Color filtering on/off") - GUI_A['groupFilter_on'] = Draw.Toggle('..group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*todo) Group filtering on/off") - GUI_A['objectFilter_on'] = Draw.Toggle('..object', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['objectFilter_on'].val, "(*todo) Object filtering on/off") - Draw.EndAlign() - - # -----end filters-------------------------------------- - - b0, b0_ = but0c, but_0c + butt_margin - b1, b1_ = but1c, but_1c - - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_A['g_origin_on'] = Draw.Toggle('Location', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "Global relocate all objects on/off") - if GUI_A['g_origin_on'].val: - tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "Edit relocation-vector (x,y,z in DXF units)") - origin_str = '(%.4f, %.4f, %.4f)' % ( - GUI_A['g_originX'].val, - GUI_A['g_originY'].val, - GUI_A['g_originZ'].val - ) - tmp = Draw.Label(origin_str, b1+20, y, 300, 20) - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['g_scale_on'] = Draw.Toggle('Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "Global scale all objects on/off") - if GUI_A['g_scale_on'].val: - g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "Factor for scaling the DXFdata") - if g_scale_as.val == 12: - pass - else: - if g_scale_as.val == 6: #scale inches to meters - GUI_A['g_scale'].val = 0.0254000 - elif g_scale_as.val == 7: #scale feets to meters - GUI_A['g_scale'].val = 0.3048000 - elif g_scale_as.val == 8: #scale yards to meters - GUI_A['g_scale'].val = 0.9144000 - else: - GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val) - scale_float = GUI_A['g_scale'].val - if scale_float < 0.000001 or scale_float > 1000000: - scale_str = ' = %s' % GUI_A['g_scale'].val - else: - scale_str = ' = %.6f' % GUI_A['g_scale'].val - Draw.Label(scale_str, b1+45, y, 200, 20) - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['Z_force_on'] = Draw.Toggle('Elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, "Overwrite Z-coordinates (flatten geometry) on/off") - if GUI_A['Z_force_on'].val: - GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "Set value for default Z-coordinate (in DXF units)") - Draw.EndAlign() - - """ - y -= 30 - Draw.BeginAlign() - GUI_A['material_on'] = Draw.Toggle('.material', EVENT_REDRAW, b0, y, b0_-20, 20, GUI_A['material_on'].val, "Support for material assignment on/off") - if GUI_A['material_on'].val: - GUI_A['material_to'] = Draw.Menu(material_to_menu, EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_to'].val, "Material assigned to?") - Draw.EndAlign() - """ - - #b0, b0_ = but0c, but_0c + butt_margin - b0, b0_ = but0c, 50 - b1, b1_ = b0+b0_, but_0c-b0_+ but_1c + butt_margin - b2, b2_ = but2c, but_2c - b3, b3_ = but3c, but_3c - - y -= 30 - Draw.Label('Output:', b0, y, b0_, 20) - Draw.Label('LAYER:', b1, y, b1_, 20) - Draw.Label('COLOR:', b2, y, b2_, 20) - Draw.Label('LINETYPE:', b3, y, b3_, 20) - #Draw.Label('LINESIZE:', b4, y, b4_, 20) - - y -= 20 - Draw.BeginAlign() - GUI_A['prefix_def'] = Draw.String('', EVENT_NONE, b0, y, b0_, 20, GUI_A['prefix_def'].val, 10, "Type Prefix for LAYERs") - GUI_A['layername_def'] = Draw.String('', EVENT_NONE, b1, y, b1_, 20, GUI_A['layername_def'].val, 10, "Type default LAYER name") - GUI_A['layercolor_def'] = Draw.Number('', EVENT_NONE, b2, y, b2_, 20, GUI_A['layercolor_def'].val, 1, 255, "Set default COLOR. (0=BYBLOCK,256=BYLAYER)") - GUI_A['layerltype_def'] = Draw.Menu(layerltype_def_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['layerltype_def'].val, "Set default LINETYPE") - Draw.EndAlign() - - y -= 25 - Draw.Label('Style:', b0, y, b0_, 20) - Draw.BeginAlign() - GUI_A['entitylayer_from'] = Draw.Menu(entitylayer_from_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['entitylayer_from'].val, "entity LAYER assigned to?") - GUI_A['entitycolor_from'] = Draw.Menu(entitycolor_from_menu, EVENT_NONE, b2, y, b2_, 20, GUI_A['entitycolor_from'].val, "entity COLOR assigned to?") - GUI_A['entityltype_from'] = Draw.Menu(entityltype_from_menu, EVENT_NONE, b3, y, b3_, 20, GUI_A['entityltype_from'].val, "Set entity LINETYPE") - Draw.EndAlign() - - y -= 10 - - y_down = y - # -----end material,translate,scale------------------------------------------ - - - #-------------------------------------- - y_top = y_down - y = y_top - - y -= 30 - Draw.BeginAlign() - Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file with file selector') - iniFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_1c-60, 20, iniFileName.val, FILENAME_MAX, "Write here the name of the INI-file") - but = but4c-60 - Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "Toggle Preset-INI-files") - Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from selected ini-file: %s' % iniFileName.val) - Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to selected ini-file: %s' % iniFileName.val) - Draw.EndAlign() - - bm = butt_margin/2 - - y -= 10 - y -= 20 - Draw.BeginAlign() - Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file with file selector') - dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_0c-menu_margin, 20, dxfFileName.val, FILENAME_MAX, "Type path/name of output DXF-file") - Draw.EndAlign() - - y -= 30 - config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' ) - Draw.BeginAlign() - but, but_ = but1c, but_1c+bm - but_ /= 3 - Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "Reset configuration to defaults") - Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'Set to standard configuration for 2D export') - Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'Set to standard configuration for 3D import') - Draw.EndAlign() - - - y -= 30 - b0, b0_ = but0c, but_0c + butt_margin +but_1c - GUI_A['only_selected_on'] = Draw.Toggle('Export Selection', EVENT_NONE, b0, y, b0_, 20, GUI_A['only_selected_on'].val, "Export only selected geometry on/off") - b0, b0_ = but2c, but_2c + butt_margin + but_3c - Draw.BeginAlign() - GUI_A['projection_on'] = Draw.Toggle('2d Projection', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['projection_on'].val, "Export a 2d Projection according 3d-View or Camera-View on/off") - if GUI_A['projection_on'].val: - GUI_A['camera_selected'] = Draw.Menu(MenuCAMERA, EVENT_CAMERA, b0, y-20, b0_-20, 20, GUI_A['camera_selected'].val, 'Choose the camera to be rendered') - Draw.PushButton('>', EVENT_setCAMERA, b0+b0_-20, y-20, 20, 20, 'switch to selected Camera - make it active') - GUI_A['hidden_lines_on'] = Draw.Toggle('Remove backFaces', EVENT_NONE, b0, y-40, b0_, 20, GUI_A['hidden_lines_on'].val, "Filter out backFaces on/off") - #GUI_A['shadows_on'] = Draw.Toggle('..Shadows', EVENT_REDRAW, b0, y-60, but_2c, 20, GUI_A['shadows_on'].val, "(*todo) Shadow tracing on/off") - #GUI_A['light_on'] = Draw.Menu(MenuLIGHT, EVENT_LIGHT, but3c, y-60, but_3c, 20, GUI_A['light_on'].val, '(*todo) Choose the light source(sun) to be rendered') - Draw.EndAlign() - - y -= 20 - b0, b0_ = but0c, but_0c + butt_margin +but_1c - GUI_A['only_visible_on'] = Draw.Toggle('Visible only', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['only_visible_on'].val, "Export only from visible layers on/off") - #b0, b0_ = but2c, but_2c + butt_margin + but_3c - - y -= 20 - b0, b0_ = but0c, but_0c + butt_margin +but_1c - GUI_A['to_polyline_on'] = Draw.Toggle('POLYLINE-Mode', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['to_polyline_on'].val, "Export to POLYLINE/POLYFACEs, otherwise to LINEs/3DFACEs on/off") - #b0, b0_ = but2c, but_2c + butt_margin + but_3c - - y -= 20 - b0, b0_ = but0c, but_0c + butt_margin +but_1c - GUI_A['instances_on'] = Draw.Toggle('Instances as BLOCKs', EVENT_NONE, b0, y, b0_, 20, GUI_A['instances_on'].val, "Export instances (multi-users) of Mesh/Curve as BLOCK/INSERTs on/off") - #b0, b0_ = but2c, but_2c + butt_margin + but_3c - - y -= 20 - b0, b0_ = but0c, but_0c + butt_margin +but_1c - GUI_A['apply_modifiers_on'] = Draw.Toggle('Apply Modifiers', EVENT_NONE, b0, y, b0_, 20, GUI_A['apply_modifiers_on'].val, "Apply modifier stack to mesh objects before export on/off") - #b0, b0_ = but2c, but_2c + butt_margin + but_3c - - y -= 20 - b0, b0_ = but0c, but_0c + butt_margin +but_1c - GUI_A['include_duplis_on'] = Draw.Toggle('Include Duplis', EVENT_NONE, b0, y, b0_, 20, GUI_A['include_duplis_on'].val, "Export Duplicates (dupliverts, dupliframes, dupligroups) on/off") - #b0, b0_ = but2c, but_2c + butt_margin + but_3c - - - - y -= 30 - Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' ) - Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'goes to online-Manual on wiki.blender.org') - GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/Draw-in, 1=Verbose, 2=ProgressBar, 3=SilentMode") - GUI_A['outputDWG_on'] = Draw.Toggle('DWG*', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['outputDWG_on'].val, "converts DXF to DWG (needs external converter) on/off") - - Draw.BeginAlign() - Draw.PushButton('START EXPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the export process. For Cancel go to console and hit Ctrl-C') - Draw.EndAlign() - - y -= 20 - #Draw.BeginAlign() - #Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20) - #Draw.Label(LAB, but0c, y, menu_w, 20) - Draw.Label(LAB, 30, y, menu_w, 20) - #Draw.Label(' ', but0c+menu_w, y, menu_margin, 20) - #Draw.EndAlign() - - ui_scrollbarX(menu_orgX, menu_w+50, scrollXArea, c_fg, c_bg) - ui_scrollbarY(menu_orgY, menu_h+30, scrollYArea, c_fg, c_bg) - - - - -#-- END GUI Stuf----------------------------------------------------- - -c0=[0.2,0.2,0.2,0.0] -c1=[0.7,0.7,0.9,0.0] -c2=[0.71,0.71,0.71,0.0] -c3=[0.4,0.4,0.4,0.0] -c4=[0.95,0.95,0.9,0.0] -c5=[0.64,0.64,0.64,0] -c6=[0.75,0.75,0.75,0] -c7=[0.6,0.6,0.6,0] -c8=[1.0,0.0,0.0,0] -c9=[0.7,0.0,0.0,0] -c10=[0.64,0.81,0.81,0] -c11=[0.57,0.71,0.71,0] -c_nor= c5[:3] -c_act= c10[:3] -c_sel= c11[:3] -c_tx = c0[:3] -c_fg = c2[:3] -c_bg = c5[:3] - -def ui_rect(coords,color): - [X1,Y1,X2,Y2],[r,g,b] = coords,color - glColor3f(r,g,b) - glRecti(X1,Y1,X2,Y2) -def ui_rectA(coords,color): - [X1,Y1,X2,Y2],[r,g,b,a] = coords,color - glColor4f(r,g,b,a) - glRecti(X1,Y1,X2,Y2) #integer coords - #glRectf(X1,Y1,X2,Y2) #floating coords -def ui_line(coords,color): - [X1,Y1,X2,Y2],[r,g,b] = coords,color - glColor3f(r,g,b) - glBegin(GL_LINES) - glVertex2i(X1,Y1) - glVertex2i(X2,Y2) - glEnd() -def ui_panel(posX,posY,L,H,color): - [r,g,b] = color - ui_rect([posX+4,posY-4,posX+L+4,posY-H-4],[.55,.55,.55]) #1st shadow - ui_rect([posX+3,posY-3,posX+L+3,posY-H-3],[.45,.45,.45]) - ui_rect([posX+3,posY-3,posX+L+2,posY-H-2],[.30,.30,.30]) #2nd shadow - ui_rect([posX,posY-H,posX+L,posY],[r,g,b]) #Main - ui_rect([posX+3,posY-19,posX+L-3,posY-2],[.75*r,.75*g,.75*b]) #Titlebar - ui_line([posX+3,posY-19,posX+3,posY-2],[.25,.25,.25]) - ui_line([posX+4,posY-19,posX+4,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4]) - ui_line([posX+4,posY-2,posX+L-3,posY-2],[(r+.75)/4,(g+.75)/4,(b+.75)/4]) -def ui_box(x,y,xright,bottom): - color = [0.75, 0.75, 0.75] - coords = x+1,y+1,xright-1,bottom-1 - ui_rect(coords,color) - -def ui_scrollbarX(Focus,PanelH,Area, color_fg, color_bg): - # Area = ScrollBarArea - # point1=down/left, point2=top/right - P1X,P1Y,P2X,P2Y = Area - AreaH = P2X-P1X - if PanelH > AreaH: - Slider = int(AreaH * (AreaH / float(PanelH))) - if Slider<3: Slider = 3 #minimal slider heigh - posX = -int(AreaH * (Focus / float(PanelH))) - ui_rect([P1X,P1Y,P2X,P2Y], color_bg) - ui_rect([P1X+posX,P1Y+3,P1X+posX+Slider,P2Y-3], color_fg) - -def ui_scrollbarY(Focus,PanelH,Area, color_fg, color_bg): - # Area = ScrollBarArea - # point1=down/left, point2=top/right - P1X,P1Y,P2X,P2Y = Area - AreaH = P2Y-P1Y - if PanelH > AreaH: - Slider = int(AreaH * (AreaH / float(PanelH))) - if Slider<3: Slider = 3 #minimal slider heigh - posY = -int(AreaH * (Focus / float(PanelH))) - ui_rect([P1X,P1Y,P2X-1,P2Y], color_bg) - #ui_rect([P1X+3,P2Y-posY,P2X-4,P2Y-posY-Slider], color_fg) - ui_rect([P1X+3,P1Y+posY,P2X-4,P1Y+posY+Slider], color_fg) - - -#------------------------------------------------------------ -def dxf_callback(input_filename): - global dxfFileName - dxfFileName.val=input_filename -# dirname == Blender.sys.dirname(Blender.Get('filename')) -# update_RegistryKey('DirName', dirname) -# update_RegistryKey('dxfFileName', input_filename) - -def ini_callback(input_filename): - global iniFileName - iniFileName.val=input_filename - -#------------------------------------------------------------ -def getSpaceRect(): - __UI_RECT__ = Buffer(GL_FLOAT, 4) - glGetFloatv(GL_SCISSOR_BOX, __UI_RECT__) - __UI_RECT__ = __UI_RECT__.list - return (int(__UI_RECT__[0]), int(__UI_RECT__[1]), int(__UI_RECT__[2]), int(__UI_RECT__[3])) - -def getRelMousePos(mco, winRect): - # mco = Blender.Window.GetMouseCoords() - if pointInRect(mco, winRect): - return (mco[0] - winRect[0], mco[1] - winRect[1]) - return None - - -def pointInRect(pt, rect): - if rect[0] < pt[0] < rect[0]+rect[2] and\ - rect[1] < pt[1] < rect[1]+rect[3]: - return True - else: - return False - - - -#--- variables UI menu --------------------------- -mco = [0,0] # mouse coordinaten -mbX, mbY = 0,0 # mouse buffer coordinaten -scrollW = 20 # width of scrollbar -rowH = 20 # height of menu raw -menu__H = 2 * rowH +5 # height of menu bar -headerH = 1 * rowH # height of column header bar -scroll_left = True # position of scrollbar -menu_bottom = False # position of menu -edit_mode = False # indicator/activator -iconlib_mode = False # indicator/activator -icon_maps = [] #[['blenderbuttons.png',12,25,20,21], -#['referenceicons.png',12,25,20,21]] -help_text = False # indicator/activator -menu_pan = False # indicator/activator -compact_DESIGN = True # toggle UI -showLINK = True # toggle Links -filterList=[-1,-1,-1,-1,-1] -dubbleclik_delay = 0.25 - -PAN_X,PAN_Y = 0,0 # pan coordinates in characters -mPAN_X,mPAN_Y = 0,0 # manu pan coordinates in characters -menu_orgX = 0 -menu_orgY = 0 -mPAN_Xmax = 800 -mPAN_Ymax = 800 - - -#------------------------------------------------------------ -def event(evt, val): - global mbX, mbY, UP, UP0, scroll_pan, FOCUS_fix - global menu_bottom, scroll_left, mco - global PAN_X, PAN_Y, PAN_X0, PAN_Y0 - global mPAN_X, mPAN_Y, mPAN_X0, mPAN_Y0, menu_pan - - #if Blender.event: - # print 'Blender.event:%s, evt:%s' %(Blender.event, evt) #------------ - - if evt in (Draw.QKEY, Draw.ESCKEY) and not val: - print 'DXF-Exporter *** end ***' #--------------------- - Draw.Exit() - - elif val: - if evt==Draw.MIDDLEMOUSE: - mco2 = Window.GetMouseCoords() - relativeMouseCo = getRelMousePos(mco2, getSpaceRect()) - if relativeMouseCo != None: - #rect = [menu__X1,menu__Y1,menu__X2,menu__Y2] - if 1: #pointInRect(relativeMouseCo, menu__Area): - menu_pan = True - mPAN_X0 = mPAN_X - mPAN_Y0 = mPAN_Y - mco = mco2 - elif evt == Draw.MOUSEY or evt == Draw.MOUSEX: - if menu_pan: - mco2 = Window.GetMouseCoords() - mbX = mco2[0]-mco[0] - mbY = mco2[1]-mco[1] - mPAN_X = mPAN_X0 - mbX - mPAN_Y = mPAN_Y0 - mbY - #print mbX, mbY #-------------------- - Draw.Redraw() - elif evt == Draw.WHEELDOWNMOUSE: - mPAN_Y -= 80 - Draw.Redraw() - elif evt == Draw.WHEELUPMOUSE: - mPAN_Y += 80 - Draw.Redraw() - else: # = if val==False: - if evt==Draw.LEFTMOUSE: - scroll_pan = False - elif evt==Draw.MIDDLEMOUSE: - menu_pan = False - -def bevent(evt): - global config_UI, user_preset - global CAMERA, GUI_A - - ######### Manages GUI events - if (evt==EVENT_EXIT): - Draw.Exit() - print 'DXF-Exporter *** end ***' #--------------------- - elif (evt==EVENT_CHOOSE_INI): - Window.FileSelector(ini_callback, "INI-file Selection", '*.ini') - elif (evt==EVENT_REDRAW): - Draw.Redraw() - elif (evt==EVENT_RESET): - resetDefaultConfig() - Draw.Redraw() - elif (evt==EVENT_PRESET2D): - resetDefaultConfig_2D() - Draw.Redraw() - elif (evt==EVENT_PRESET3D): - resetDefaultConfig_3D() - Draw.Redraw() - elif evt in (EVENT_CAMERA,EVENT_LIGHT): - CAMERA = GUI_A['camera_selected'].val - if CAMERA==len(CAMERAS)+1: - doAllCameras = True - else: - pass #print 'deb: CAMERAS=',CAMERAS #---------------- - Draw.Redraw() - elif (evt==EVENT_setCAMERA): - if CAMERA 5: user_preset = 0; index = '' - iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION - Draw.Redraw() - elif (evt==EVENT_HELP): - try: - import webbrowser - webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf') - except: - Draw.PupMenu('DXF-Exporter: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\ -http://wiki.blender.org/index.php?title=Scripts/Manual/Export/autodesk_dxf') - Draw.Redraw() - elif (evt==EVENT_LOAD_INI): - loadConfig() - Draw.Redraw() - elif (evt==EVENT_SAVE_INI): - saveConfig() - Draw.Redraw() - elif (evt==EVENT_DXF_DIR): - dxfFile = dxfFileName.val - dxfPathName = '' - if '/' in dxfFile: - dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/' - elif '\\' in dxfFile: - dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\' - dxfFileName.val = dxfPathName + '*.dxf' -# dirname == Blender.sys.dirname(Blender.Get('filename')) -# update_RegistryKey('DirName', dirname) -# update_RegistryKey('dxfFileName', dxfFileName.val) - GUI_A['only_selected_on'].val = 1 - Draw.Redraw() - elif (evt==EVENT_CHOOSE_DXF): - filename = '' # '*.dxf' - if dxfFileName.val: filename = dxfFileName.val - Window.FileSelector(dxf_callback, "DXF-file Selection", filename) - elif (evt==EVENT_START): - dxfFile = dxfFileName.val - #print 'deb: dxfFile file: ', dxfFile #---------------------- - if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode - update_RegistryKey('dxfFileName', dxfFileName.val) - update_globals() - if dxfFile.lower().endswith('*.dxf'): - if Draw.PupMenu('DXF-Exporter: OK?|will write multiple DXF-files, one for each Scene, in:|%s' % dxfFile) == 1: - global UI_MODE - UI_MODE = False - #TODO: multi_export(dxfFile[:-5]) # cut last 5 characters '*.dxf' - Draw.Redraw() - UI_MODE = True - else: - Draw.Redraw() - elif dxfFile.lower()[-4:] in ('.dxf','.dwg'): # and Blender.sys.exists(dxfFile): - print 'preparing for export ---' #Standard Mode: activated - filepath = dxfFile - sce = Scene.GetCurrent() - if ONLYSELECTED: sel_group = sce.objects.selected - else: sel_group = sce.objects - - if ONLYVISIBLE: - sel_group_temp = [] - layerlist = sce.getLayers() - for ob in sel_group: - for lay in ob.layers: - if lay in layerlist: - sel_group_temp.append(ob) - break - sel_group = sel_group_temp - - export_list = getObjectsAndDuplis(sel_group,MATRICES=True) - - if export_list: do_export(export_list, filepath) - else: - print "Abort: selection was empty, no object to export!" - Draw.PupMenu('DXF Exporter: nothing exported!|empty selection!') - else: - Draw.PupMenu('DXF-Exporter: Alert!%t|no valid DXF-file selected!') - print "DXF-Exporter: error, no valid DXF-file selected! try again" - Draw.Redraw() - - - - -def multi_export(DIR): #TODO: - """Imports all DXF-files from directory DIR. - - """ - global SCENE - batchTIME = Blender.sys.time() - #if #DIR == "": DIR = os.path.curdir - if DIR == "": DIR = Blender.sys.dirname(Blender.Get('filename')) - print 'Multifiles Import from %s' %DIR - files = \ - [Blender.sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith('.dxf')] - if not files: - print '...None DXF-files found. Abort!' - return - - i = 0 - for dxfFile in files: - i += 1 - print '\nDXF-file', i, 'of', len(files) #,'\nImporting', dxfFile - if ONLYSELECTED: - _dxf_file = dxfFile.split('/')[-1].split('\\')[-1] - _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' - _dxf_file = _dxf_file[:NAMELENGTH_MAX] #? [-NAMELENGTH_MAX:]) - SCENE = Blender.Scene.New(_dxf_file) - SCENE.makeCurrent() - #or so? Blender.Scene.makeCurrent(_dxf_file) - #sce = bpy.data.scenes.new(_dxf_file) - #bpy.data.scenes.active = sce - else: - SCENE = Blender.Scene.GetCurrent() - SCENE.objects.selected = [] # deselect all - main(dxfFile) - #Blender.Redraw() - - print 'TOTAL TIME: %.6f' % (Blender.sys.time() - batchTIME) - print '\a\r', # beep when done - - -#----------------------------------------------------- -if __name__=='__main__': - - if DXF: - print '\n\n\n' - print 'DXF-Exporter v%s *** start ***' %(__version__) #--------------------- - print 'with Library %s' %(DXF.__version__) #--------------------- - if not DXF.copy: - print "DXF-Exporter: dxfLibrary.py script requires a full Python install" - Draw.PupMenu('Error%t|The dxfLibrary.py script requires a full Python install') - else: - #Window.FileSelector(dxf_export_ui, 'EXPORT DXF', Blender.sys.makename(ext='.dxf')) - # recall last used DXF-file and INI-file names - dxffilename = check_RegistryKey('dxfFileName') - #print 'deb:start dxffilename:', dxffilename #---------------- - if dxffilename: dxfFileName.val = dxffilename - else: - dirname = Blender.sys.dirname(Blender.Get('filename')) - #print 'deb:start dirname:', dirname #---------------- - dxfFileName.val = Blender.sys.join(dirname, '') - inifilename = check_RegistryKey('iniFileName') - if inifilename: iniFileName.val = inifilename - - updateMenuCAMERA() - updateCAMERA() - - Draw.Register(draw_UI, event, bevent) - - \ No newline at end of file diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py deleted file mode 100644 index 50357cbfa75..00000000000 --- a/release/scripts/export_fbx.py +++ /dev/null @@ -1,3084 +0,0 @@ -#!BPY -""" -Name: 'Autodesk FBX (.fbx)...' -Blender: 249 -Group: 'Export' -Tooltip: 'Selection to an ASCII Autodesk FBX ' -""" -__author__ = "Campbell Barton" -__url__ = ['www.blender.org', 'blenderartists.org'] -__version__ = "1.2" - -__bpydoc__ = """\ -This script is an exporter to the FBX file format. - -http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx -""" -# -------------------------------------------------------------------------- -# FBX Export v0.1 by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -try: - import time - # import os # only needed for batch export, nbot used yet -except: - time = None # use this to check if they have python modules installed - -# for python 2.3 support -try: - set() -except: - try: - from sets import Set as set - except: - set = None # so it complains you dont have a ! - -# os is only needed for batch 'own dir' option -try: - import os -except: - os = None - -import Blender -import bpy -from Blender.Mathutils import Matrix, Vector, RotationMatrix - -import BPyObject -import BPyMesh -import BPySys -import BPyMessages - -## This was used to make V, but faster not to do all that -##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' -##v = range(255) -##for c in valid: v.remove(ord(c)) -v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,47,58,59,60,61,62,63,64,92,94,96,124,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] -invalid = ''.join([chr(i) for i in v]) -def cleanName(name): - for ch in invalid: name = name.replace(ch, '_') - return name -del v, i - - -def copy_file(source, dest): - file = open(source, 'rb') - data = file.read() - file.close() - - file = open(dest, 'wb') - file.write(data) - file.close() - - -def copy_images(dest_dir, textures): - if not dest_dir.endswith(Blender.sys.sep): - dest_dir += Blender.sys.sep - - image_paths = set() - for tex in textures: - image_paths.add(Blender.sys.expandpath(tex.filename)) - - # Now copy images - copyCount = 0 - for image_path in image_paths: - if Blender.sys.exists(image_path): - # Make a name for the target path. - dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] - if not Blender.sys.exists(dest_image_path): # Image isnt alredy there - print '\tCopying "%s" > "%s"' % (image_path, dest_image_path) - try: - copy_file(image_path, dest_image_path) - copyCount+=1 - except: - print '\t\tWarning, file failed to copy, skipping.' - - print '\tCopied %d images' % copyCount - -mtx4_identity = Matrix() - -# testing -mtx_x90 = RotationMatrix( 90, 3, 'x') # used -#mtx_x90n = RotationMatrix(-90, 3, 'x') -#mtx_y90 = RotationMatrix( 90, 3, 'y') -#mtx_y90n = RotationMatrix(-90, 3, 'y') -#mtx_z90 = RotationMatrix( 90, 3, 'z') -#mtx_z90n = RotationMatrix(-90, 3, 'z') - -#mtx4_x90 = RotationMatrix( 90, 4, 'x') -mtx4_x90n = RotationMatrix(-90, 4, 'x') # used -#mtx4_y90 = RotationMatrix( 90, 4, 'y') -mtx4_y90n = RotationMatrix(-90, 4, 'y') # used -mtx4_z90 = RotationMatrix( 90, 4, 'z') # used -mtx4_z90n = RotationMatrix(-90, 4, 'z') # used - -def strip_path(p): - return p.split('\\')[-1].split('/')[-1] - -# Used to add the scene name into the filename without using odd chars -sane_name_mapping_ob = {} -sane_name_mapping_mat = {} -sane_name_mapping_tex = {} -sane_name_mapping_take = {} -sane_name_mapping_group = {} - -# Make sure reserved names are not used -sane_name_mapping_ob['Scene'] = 'Scene_' -sane_name_mapping_ob['blend_root'] = 'blend_root_' - -def increment_string(t): - name = t - num = '' - while name and name[-1].isdigit(): - num = name[-1] + num - name = name[:-1] - if num: return '%s%d' % (name, int(num)+1) - else: return name + '_0' - - - -# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up. -def sane_name(data, dct): - #if not data: return None - - if type(data)==tuple: # materials are paired up with images - data, other = data - use_other = True - else: - other = None - use_other = False - - if data: name = data.name - else: name = None - orig_name = name - - if other: - orig_name_other = other.name - name = '%s #%s' % (name, orig_name_other) - else: - orig_name_other = None - - # dont cache, only ever call once for each data type now, - # so as to avoid namespace collision between types - like with objects <-> bones - #try: return dct[name] - #except: pass - - if not name: - name = 'unnamed' # blank string, ASKING FOR TROUBLE! - else: - #name = BPySys.cleanName(name) - name = cleanName(name) # use our own - - while name in dct.itervalues(): name = increment_string(name) - - if use_other: # even if other is None - orig_name_other will be a string or None - dct[orig_name, orig_name_other] = name - else: - dct[orig_name] = name - - return name - -def sane_obname(data): return sane_name(data, sane_name_mapping_ob) -def sane_matname(data): return sane_name(data, sane_name_mapping_mat) -def sane_texname(data): return sane_name(data, sane_name_mapping_tex) -def sane_takename(data): return sane_name(data, sane_name_mapping_take) -def sane_groupname(data): return sane_name(data, sane_name_mapping_group) - -def derived_paths(fname_orig, basepath, FORCE_CWD=False): - ''' - fname_orig - blender path, can be relative - basepath - fname_rel will be relative to this - FORCE_CWD - dont use the basepath, just add a ./ to the filename. - use when we know the file will be in the basepath. - ''' - fname = Blender.sys.expandpath(fname_orig) - fname_strip = strip_path(fname) - if FORCE_CWD: fname_rel = '.' + Blender.sys.sep + fname_strip - else: fname_rel = Blender.sys.relpath(fname, basepath) - if fname_rel.startswith('//'): fname_rel = '.' + Blender.sys.sep + fname_rel[2:] - return fname, fname_strip, fname_rel - - -def mat4x4str(mat): - return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ]) - -def meshNormalizedWeights(me): - try: # account for old bad BPyMesh - groupNames, vWeightList = BPyMesh.meshWeight2List(me) - except: - return [],[] - - if not groupNames: - return [],[] - - for i, vWeights in enumerate(vWeightList): - tot = 0.0 - for w in vWeights: - tot+=w - - if tot: - for j, w in enumerate(vWeights): - vWeights[j] = w/tot - - return groupNames, vWeightList - -header_comment = \ -'''; FBX 6.1.0 project file -; Created by Blender FBX Exporter -; for support mail: ideasman42@gmail.com -; ---------------------------------------------------- - -''' - -# This func can be called with just the filename -def write(filename, batch_objects = None, \ - EXP_OBS_SELECTED = True, - EXP_MESH = True, - EXP_MESH_APPLY_MOD = True, - EXP_MESH_HQ_NORMALS = False, - EXP_ARMATURE = True, - EXP_LAMP = True, - EXP_CAMERA = True, - EXP_EMPTY = True, - EXP_IMAGE_COPY = False, - GLOBAL_MATRIX = Matrix(), - ANIM_ENABLE = True, - ANIM_OPTIMIZE = True, - ANIM_OPTIMIZE_PRECISSION = 6, - ANIM_ACTION_ALL = False, - BATCH_ENABLE = False, - BATCH_GROUP = True, - BATCH_SCENE = False, - BATCH_FILE_PREFIX = '', - BATCH_OWN_DIR = False - ): - - # ----------------- Batch support! - if BATCH_ENABLE: - if os == None: BATCH_OWN_DIR = False - - fbxpath = filename - - # get the path component of filename - tmp_exists = Blender.sys.exists(fbxpath) - - if tmp_exists != 2: # a file, we want a path - while fbxpath and fbxpath[-1] not in ('/', '\\'): - fbxpath = fbxpath[:-1] - if not filename: - Draw.PupMenu('Error%t|Directory does not exist!') - return - - tmp_exists = Blender.sys.exists(fbxpath) - - if tmp_exists != 2: - Draw.PupMenu('Error%t|Directory does not exist!') - return - - if not fbxpath.endswith(Blender.sys.sep): - fbxpath += Blender.sys.sep - del tmp_exists - - - if BATCH_GROUP: - data_seq = bpy.data.groups - else: - data_seq = bpy.data.scenes - - # call this function within a loop with BATCH_ENABLE == False - orig_sce = bpy.data.scenes.active - - - new_fbxpath = fbxpath # own dir option modifies, we need to keep an original - for data in data_seq: # scene or group - newname = BATCH_FILE_PREFIX + BPySys.cleanName(data.name) - - - if BATCH_OWN_DIR: - new_fbxpath = fbxpath + newname + Blender.sys.sep - # path may alredy exist - # TODO - might exist but be a file. unlikely but should probably account for it. - - if Blender.sys.exists(new_fbxpath) == 0: - os.mkdir(new_fbxpath) - - - filename = new_fbxpath + newname + '.fbx' - - print '\nBatch exporting %s as...\n\t"%s"' % (data, filename) - - if BATCH_GROUP: #group - # group, so objects update properly, add a dummy scene. - sce = bpy.data.scenes.new() - sce.Layers = (1<<20) -1 - bpy.data.scenes.active = sce - for ob_base in data.objects: - sce.objects.link(ob_base) - - sce.update(1) - - # TODO - BUMMER! Armatures not in the group wont animate the mesh - - else:# scene - - - data_seq.active = data - - - # Call self with modified args - # Dont pass batch options since we alredy usedt them - write(filename, data.objects, - False, - EXP_MESH, - EXP_MESH_APPLY_MOD, - EXP_MESH_HQ_NORMALS, - EXP_ARMATURE, - EXP_LAMP, - EXP_CAMERA, - EXP_EMPTY, - EXP_IMAGE_COPY, - GLOBAL_MATRIX, - ANIM_ENABLE, - ANIM_OPTIMIZE, - ANIM_OPTIMIZE_PRECISSION, - ANIM_ACTION_ALL - ) - - if BATCH_GROUP: - # remove temp group scene - bpy.data.scenes.unlink(sce) - - bpy.data.scenes.active = orig_sce - - return # so the script wont run after we have batch exported. - - # end batch support - - # Use this for working out paths relative to the export location - basepath = Blender.sys.dirname(filename) - - # ---------------------------------------------- - # storage classes - class my_bone_class: - __slots__ =(\ - 'blenName',\ - 'blenBone',\ - 'blenMeshes',\ - 'restMatrix',\ - 'parent',\ - 'blenName',\ - 'fbxName',\ - 'fbxArm',\ - '__pose_bone',\ - '__anim_poselist') - - def __init__(self, blenBone, fbxArm): - - # This is so 2 armatures dont have naming conflicts since FBX bones use object namespace - self.fbxName = sane_obname(blenBone) - - self.blenName = blenBone.name - self.blenBone = blenBone - self.blenMeshes = {} # fbxMeshObName : mesh - self.fbxArm = fbxArm - self.restMatrix = blenBone.matrix['ARMATURESPACE'] - - # not used yet - # self.restMatrixInv = self.restMatrix.copy().invert() - # self.restMatrixLocal = None # set later, need parent matrix - - self.parent = None - - # not public - pose = fbxArm.blenObject.getPose() - self.__pose_bone = pose.bones[self.blenName] - - # store a list if matricies here, (poseMatrix, head, tail) - # {frame:posematrix, frame:posematrix, ...} - self.__anim_poselist = {} - - ''' - def calcRestMatrixLocal(self): - if self.parent: - self.restMatrixLocal = self.restMatrix * self.parent.restMatrix.copy().invert() - else: - self.restMatrixLocal = self.restMatrix.copy() - ''' - def setPoseFrame(self, f): - # cache pose info here, frame must be set beforehand - - # Didnt end up needing head or tail, if we do - here it is. - ''' - self.__anim_poselist[f] = (\ - self.__pose_bone.poseMatrix.copy(),\ - self.__pose_bone.head.copy(),\ - self.__pose_bone.tail.copy() ) - ''' - - self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy() - - # get pose from frame. - def getPoseMatrix(self, f):# ---------------------------------------------- - return self.__anim_poselist[f] - ''' - def getPoseHead(self, f): - #return self.__pose_bone.head.copy() - return self.__anim_poselist[f][1].copy() - def getPoseTail(self, f): - #return self.__pose_bone.tail.copy() - return self.__anim_poselist[f][2].copy() - ''' - # end - - def getAnimParRelMatrix(self, frame): - #arm_mat = self.fbxArm.matrixWorld - #arm_mat = self.fbxArm.parRelMatrix() - if not self.parent: - #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore - return mtx4_z90 * self.getPoseMatrix(frame) - else: - #return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat))) * (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert() - return (mtx4_z90 * (self.getPoseMatrix(frame))) * (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert() - - # we need thes because cameras and lights modified rotations - def getAnimParRelMatrixRot(self, frame): - return self.getAnimParRelMatrix(frame) - - def flushAnimData(self): - self.__anim_poselist.clear() - - - class my_object_generic: - # Other settings can be applied for each type - mesh, armature etc. - def __init__(self, ob, matrixWorld = None): - self.fbxName = sane_obname(ob) - self.blenObject = ob - self.fbxGroupNames = [] - self.fbxParent = None # set later on IF the parent is in the selection. - if matrixWorld: self.matrixWorld = matrixWorld * GLOBAL_MATRIX - else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX - self.__anim_poselist = {} # we should only access this - - def parRelMatrix(self): - if self.fbxParent: - return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert() - else: - return self.matrixWorld - - def setPoseFrame(self, f): - self.__anim_poselist[f] = self.blenObject.matrixWorld.copy() - - def getAnimParRelMatrix(self, frame): - if self.fbxParent: - #return (self.__anim_poselist[frame] * self.fbxParent.__anim_poselist[frame].copy().invert() ) * GLOBAL_MATRIX - return (self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert() - else: - return self.__anim_poselist[frame] * GLOBAL_MATRIX - - def getAnimParRelMatrixRot(self, frame): - type = self.blenObject.type - if self.fbxParent: - matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart() - else: - matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart() - - # Lamps need to be rotated - if type =='Lamp': - matrix_rot = mtx_x90 * matrix_rot - elif ob and type =='Camera': - y = Vector(0,1,0) * matrix_rot - matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y) - - return matrix_rot - - # ---------------------------------------------- - - - - - - print '\nFBX export starting...', filename - start_time = Blender.sys.time() - try: - file = open(filename, 'w') - except: - return False - - sce = bpy.data.scenes.active - world = sce.world - - - # ---------------------------- Write the header first - file.write(header_comment) - if time: - curtime = time.localtime()[0:6] - else: - curtime = (0,0,0,0,0,0) - # - file.write(\ -'''FBXHeaderExtension: { - FBXHeaderVersion: 1003 - FBXVersion: 6100 - CreationTimeStamp: { - Version: 1000 - Year: %.4i - Month: %.2i - Day: %.2i - Hour: %.2i - Minute: %.2i - Second: %.2i - Millisecond: 0 - } - Creator: "FBX SDK/FBX Plugins build 20070228" - OtherFlags: { - FlagPLE: 0 - } -}''' % (curtime)) - - file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime) - file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version')) - - pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way - - # --------------- funcs for exporting - def object_tx(ob, loc, matrix, matrix_mod = None): - ''' - Matrix mod is so armature objects can modify their bone matricies - ''' - if isinstance(ob, Blender.Types.BoneType): - - # we know we have a matrix - # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod) - matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore - - parent = ob.parent - if parent: - #par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod) - par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore - matrix = matrix * par_matrix.copy().invert() - - matrix_rot = matrix.rotationPart() - - loc = tuple(matrix.translationPart()) - scale = tuple(matrix.scalePart()) - rot = tuple(matrix_rot.toEuler()) - - else: - # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore - #if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX - if ob and not matrix: raise "error: this should never happen!" - - matrix_rot = matrix - #if matrix: - # matrix = matrix_scale * matrix - - if matrix: - loc = tuple(matrix.translationPart()) - scale = tuple(matrix.scalePart()) - - matrix_rot = matrix.rotationPart() - # Lamps need to be rotated - if ob and ob.type =='Lamp': - matrix_rot = mtx_x90 * matrix_rot - rot = tuple(matrix_rot.toEuler()) - elif ob and ob.type =='Camera': - y = Vector(0,1,0) * matrix_rot - matrix_rot = matrix_rot * RotationMatrix(90, 3, 'r', y) - rot = tuple(matrix_rot.toEuler()) - else: - rot = tuple(matrix_rot.toEuler()) - else: - if not loc: - loc = 0,0,0 - scale = 1,1,1 - rot = 0,0,0 - - return loc, rot, scale, matrix, matrix_rot - - def write_object_tx(ob, loc, matrix, matrix_mod= None): - ''' - We have loc to set the location if non blender objects that have a location - - matrix_mod is only used for bones at the moment - ''' - loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod) - - file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc) - file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) - file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale) - return loc, rot, scale, matrix, matrix_rot - - def write_object_props(ob=None, loc=None, matrix=None, matrix_mod=None): - # if the type is 0 its an empty otherwise its a mesh - # only difference at the moment is one has a color - file.write(''' - Properties60: { - Property: "QuaternionInterpolate", "bool", "",0 - Property: "Visibility", "Visibility", "A+",1''') - - loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix, matrix_mod) - - # Rotation order, note, for FBX files Iv loaded normal order is 1 - # setting to zero. - # eEULER_XYZ = 0 - # eEULER_XZY - # eEULER_YZX - # eEULER_YXZ - # eEULER_ZXY - # eEULER_ZYX - - file.write(''' - Property: "RotationOffset", "Vector3D", "",0,0,0 - Property: "RotationPivot", "Vector3D", "",0,0,0 - Property: "ScalingOffset", "Vector3D", "",0,0,0 - Property: "ScalingPivot", "Vector3D", "",0,0,0 - Property: "TranslationActive", "bool", "",0 - Property: "TranslationMin", "Vector3D", "",0,0,0 - Property: "TranslationMax", "Vector3D", "",0,0,0 - Property: "TranslationMinX", "bool", "",0 - Property: "TranslationMinY", "bool", "",0 - Property: "TranslationMinZ", "bool", "",0 - Property: "TranslationMaxX", "bool", "",0 - Property: "TranslationMaxY", "bool", "",0 - Property: "TranslationMaxZ", "bool", "",0 - Property: "RotationOrder", "enum", "",0 - Property: "RotationSpaceForLimitOnly", "bool", "",0 - Property: "AxisLen", "double", "",10 - Property: "PreRotation", "Vector3D", "",0,0,0 - Property: "PostRotation", "Vector3D", "",0,0,0 - Property: "RotationActive", "bool", "",0 - Property: "RotationMin", "Vector3D", "",0,0,0 - Property: "RotationMax", "Vector3D", "",0,0,0 - Property: "RotationMinX", "bool", "",0 - Property: "RotationMinY", "bool", "",0 - Property: "RotationMinZ", "bool", "",0 - Property: "RotationMaxX", "bool", "",0 - Property: "RotationMaxY", "bool", "",0 - Property: "RotationMaxZ", "bool", "",0 - Property: "RotationStiffnessX", "double", "",0 - Property: "RotationStiffnessY", "double", "",0 - Property: "RotationStiffnessZ", "double", "",0 - Property: "MinDampRangeX", "double", "",0 - Property: "MinDampRangeY", "double", "",0 - Property: "MinDampRangeZ", "double", "",0 - Property: "MaxDampRangeX", "double", "",0 - Property: "MaxDampRangeY", "double", "",0 - Property: "MaxDampRangeZ", "double", "",0 - Property: "MinDampStrengthX", "double", "",0 - Property: "MinDampStrengthY", "double", "",0 - Property: "MinDampStrengthZ", "double", "",0 - Property: "MaxDampStrengthX", "double", "",0 - Property: "MaxDampStrengthY", "double", "",0 - Property: "MaxDampStrengthZ", "double", "",0 - Property: "PreferedAngleX", "double", "",0 - Property: "PreferedAngleY", "double", "",0 - Property: "PreferedAngleZ", "double", "",0 - Property: "InheritType", "enum", "",0 - Property: "ScalingActive", "bool", "",0 - Property: "ScalingMin", "Vector3D", "",1,1,1 - Property: "ScalingMax", "Vector3D", "",1,1,1 - Property: "ScalingMinX", "bool", "",0 - Property: "ScalingMinY", "bool", "",0 - Property: "ScalingMinZ", "bool", "",0 - Property: "ScalingMaxX", "bool", "",0 - Property: "ScalingMaxY", "bool", "",0 - Property: "ScalingMaxZ", "bool", "",0 - Property: "GeometricTranslation", "Vector3D", "",0,0,0 - Property: "GeometricRotation", "Vector3D", "",0,0,0 - Property: "GeometricScaling", "Vector3D", "",1,1,1 - Property: "LookAtProperty", "object", "" - Property: "UpVectorProperty", "object", "" - Property: "Show", "bool", "",1 - Property: "NegativePercentShapeSupport", "bool", "",1 - Property: "DefaultAttributeIndex", "int", "",0''') - if ob and type(ob) != Blender.Types.BoneType: - # Only mesh objects have color - file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') - file.write('\n\t\t\tProperty: "Size", "double", "",100') - file.write('\n\t\t\tProperty: "Look", "enum", "",1') - - return loc, rot, scale, matrix, matrix_rot - - - # -------------------------------------------- Armatures - #def write_bone(bone, name, matrix_mod): - def write_bone(my_bone): - file.write('\n\tModel: "Model::%s", "Limb" {' % my_bone.fbxName) - file.write('\n\t\tVersion: 232') - - #poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.parRelMatrix())[3] - poseMatrix = write_object_props(my_bone.blenBone)[3] # dont apply bone matricies anymore - pose_items.append( (my_bone.fbxName, poseMatrix) ) - - - # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) - file.write('\n\t\t\tProperty: "Size", "double", "",1') - - #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.tail['ARMATURESPACE'] * my_bone.fbxArm.parRelMatrix())).length) - - """ - file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ - ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) - """ - - file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ - (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length) - - #file.write('\n\t\t\tProperty: "LimbLength", "double", "",1') - file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8') - file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 1') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Skeleton"') - file.write('\n\t}') - - def write_camera_switch(): - file.write(''' - Model: "Model::Camera Switcher", "CameraSwitcher" { - Version: 232''') - - write_object_props() - file.write(''' - Property: "Color", "Color", "A",0.8,0.8,0.8 - Property: "Camera Index", "Integer", "A+",100 - } - MultiLayer: 0 - MultiTake: 1 - Hidden: "True" - Shading: W - Culling: "CullingOff" - Version: 101 - Name: "Model::Camera Switcher" - CameraId: 0 - CameraName: 100 - CameraIndexName: - }''') - - def write_camera_dummy(name, loc, near, far, proj_type, up): - file.write('\n\tModel: "Model::%s", "Camera" {' % name ) - file.write('\n\t\tVersion: 232') - write_object_props(None, loc) - - file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') - file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') - file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",40') - file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",0') - file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",0') - file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0.63,0.63,0.63') - file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') - file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') - file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') - file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') - file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') - file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') - file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') - file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",21.3544940948486') - file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') - file.write('\n\t\t\tProperty: "AspectW", "double", "",320') - file.write('\n\t\t\tProperty: "AspectH", "double", "",200') - file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",1') - file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') - file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') - file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') - file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % near) - file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % far) - file.write('\n\t\t\tProperty: "FilmWidth", "double", "",0.816') - file.write('\n\t\t\tProperty: "FilmHeight", "double", "",0.612') - file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",1.33333333333333') - file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') - file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",4') - file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') - file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') - file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') - file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') - file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') - file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') - file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') - file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') - file.write('\n\t\t\tProperty: "Crop", "bool", "",0') - file.write('\n\t\t\tProperty: "Center", "bool", "",1') - file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') - file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') - file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') - file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') - file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') - file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') - file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",1.33333333333333') - file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') - file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') - file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') - file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') - file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",%i' % proj_type) - file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') - file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') - file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') - file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') - file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') - file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') - file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') - file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 0') - file.write('\n\t\tHidden: "True"') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Camera"') - file.write('\n\t\tGeometryVersion: 124') - file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) - file.write('\n\t\tUp: %i,%i,%i' % up) - file.write('\n\t\tLookAt: 0,0,0') - file.write('\n\t\tShowInfoOnMoving: 1') - file.write('\n\t\tShowAudio: 0') - file.write('\n\t\tAudioColor: 0,1,0') - file.write('\n\t\tCameraOrthoZoom: 1') - file.write('\n\t}') - - def write_camera_default(): - # This sucks but to match FBX converter its easier to - # write the cameras though they are not needed. - write_camera_dummy('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0)) - write_camera_dummy('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1)) - write_camera_dummy('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1)) - write_camera_dummy('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0)) - write_camera_dummy('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0)) - write_camera_dummy('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0)) - write_camera_dummy('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0)) - - def write_camera(my_cam): - ''' - Write a blender camera - ''' - render = sce.render - width = render.sizeX - height = render.sizeY - aspect = float(width)/height - - data = my_cam.blenObject.data - - file.write('\n\tModel: "Model::%s", "Camera" {' % my_cam.fbxName ) - file.write('\n\t\tVersion: 232') - loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject, None, my_cam.parRelMatrix()) - - file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') - file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle) - file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') - file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026') - file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units? - file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto - file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0') - file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') - file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') - file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') - file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') - file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') - file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') - file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') - file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') - file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width) - file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height) - - '''Camera aspect ratio modes. - 0 If the ratio mode is eWINDOW_SIZE, both width and height values aren't relevant. - 1 If the ratio mode is eFIXED_RATIO, the height value is set to 1.0 and the width value is relative to the height value. - 2 If the ratio mode is eFIXED_RESOLUTION, both width and height values are in pixels. - 3 If the ratio mode is eFIXED_WIDTH, the width value is in pixels and the height value is relative to the width value. - 4 If the ratio mode is eFIXED_HEIGHT, the height value is in pixels and the width value is relative to the height value. - - Definition at line 234 of file kfbxcamera.h. ''' - - file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",2') - - file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') - file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') - file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') - file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') - file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart) - file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart) - file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0') - file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0') - file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect) - file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') - file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",0') - file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') - file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') - file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') - file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') - file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') - file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') - file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') - file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') - file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') - file.write('\n\t\t\tProperty: "Crop", "bool", "",0') - file.write('\n\t\t\tProperty: "Center", "bool", "",1') - file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') - file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') - file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') - file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') - file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') - file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') - file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",%.6f' % aspect) - file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') - file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') - file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') - file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') - file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",0') - file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') - file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') - file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') - file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') - file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') - file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') - file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') - file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') - file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') - - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 0') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Camera"') - file.write('\n\t\tGeometryVersion: 124') - file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) - file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Vector(0,1,0) * matrix_rot) ) - file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Vector(0,0,-1)*matrix_rot) ) - - #file.write('\n\t\tUp: 0,0,0' ) - #file.write('\n\t\tLookAt: 0,0,0' ) - - file.write('\n\t\tShowInfoOnMoving: 1') - file.write('\n\t\tShowAudio: 0') - file.write('\n\t\tAudioColor: 0,1,0') - file.write('\n\t\tCameraOrthoZoom: 1') - file.write('\n\t}') - - def write_light(my_light): - light = my_light.blenObject.data - file.write('\n\tModel: "Model::%s", "Light" {' % my_light.fbxName) - file.write('\n\t\tVersion: 232') - - write_object_props(my_light.blenObject, None, my_light.parRelMatrix()) - - # Why are these values here twice?????? - oh well, follow the holy sdk's output - - # Blender light types match FBX's, funny coincidence, we just need to - # be sure that all unsupported types are made into a point light - #ePOINT, - #eDIRECTIONAL - #eSPOT - light_type = light.type - if light_type > 2: light_type = 1 # hemi and area lights become directional - - mode = light.mode - if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: - do_shadow = 1 - else: - do_shadow = 0 - - if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular): - do_light = 0 - else: - do_light = 1 - - scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case - - file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) - file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') - file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') - file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1') - file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 - file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) - file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') - file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col)) - file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 - file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) - file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') - file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) - file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light) - file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') - file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') - file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') - file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') - file.write('\n\t\t\tProperty: "DecayType", "enum", "",0') - file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist) - file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0') - file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0') - file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0') - file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0') - file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0') - file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0') - file.write('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow) - file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1') - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 0') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - file.write('\n\t\tTypeFlags: "Light"') - file.write('\n\t\tGeometryVersion: 124') - file.write('\n\t}') - - # matrixOnly is not used at the moment - def write_null(my_null = None, fbxName = None, matrixOnly = None): - # ob can be null - if not fbxName: fbxName = my_null.fbxName - - file.write('\n\tModel: "Model::%s", "Null" {' % fbxName) - file.write('\n\t\tVersion: 232') - - # only use this for the root matrix at the moment - if matrixOnly: - poseMatrix = write_object_props(None, None, matrixOnly)[3] - - else: # all other Null's - if my_null: poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3] - else: poseMatrix = write_object_props()[3] - - pose_items.append((fbxName, poseMatrix)) - - file.write(''' - } - MultiLayer: 0 - MultiTake: 1 - Shading: Y - Culling: "CullingOff" - TypeFlags: "Null" - }''') - - # Material Settings - if world: world_amb = world.getAmb() - else: world_amb = (0,0,0) # Default value - - def write_material(matname, mat): - file.write('\n\tMaterial: "Material::%s", "" {' % matname) - - # Todo, add more material Properties. - if mat: - mat_cold = tuple(mat.rgbCol) - mat_cols = tuple(mat.specCol) - #mat_colm = tuple(mat.mirCol) # we wont use the mirror color - mat_colamb = tuple([c for c in world_amb]) - - mat_dif = mat.ref - mat_amb = mat.amb - mat_hard = (float(mat.hard)-1)/5.10 - mat_spec = mat.spec/2.0 - mat_alpha = mat.alpha - mat_emit = mat.emit - mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS - if mat_shadeless: - mat_shader = 'Lambert' - else: - if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT: - mat_shader = 'Lambert' - else: - mat_shader = 'Phong' - else: - mat_cols = mat_cold = 0.8, 0.8, 0.8 - mat_colamb = 0.0,0.0,0.0 - # mat_colm - mat_dif = 1.0 - mat_amb = 0.5 - mat_hard = 20.0 - mat_spec = 0.2 - mat_alpha = 1.0 - mat_emit = 0.0 - mat_shadeless = False - mat_shader = 'Phong' - - file.write('\n\t\tVersion: 102') - file.write('\n\t\tShadingModel: "%s"' % mat_shader.lower()) - file.write('\n\t\tMultiLayer: 0') - - file.write('\n\t\tProperties60: {') - file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader) - file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0') - file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender - file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit) - - file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb) - file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb) - file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) - file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif) - file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0') - file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1') - file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha)) - if not mat_shadeless: - file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols) - file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec) - file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0') - file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0') - file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1') - file.write('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0') - file.write('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb) - file.write('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold) - if not mat_shadeless: - file.write('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols) - file.write('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard) - file.write('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha) - if not mat_shadeless: - file.write('\n\t\t\tProperty: "Reflectivity", "double", "",0') - - file.write('\n\t\t}') - file.write('\n\t}') - - def write_video(texname, tex): - # Same as texture really! - file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) - - file.write(''' - Type: "Clip" - Properties60: { - Property: "FrameRate", "double", "",0 - Property: "LastFrame", "int", "",0 - Property: "Width", "int", "",0 - Property: "Height", "int", "",0''') - if tex: - fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) - else: - fname = fname_strip = fname_rel = '' - - file.write('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip) - - - file.write(''' - Property: "StartFrame", "int", "",0 - Property: "StopFrame", "int", "",0 - Property: "PlaySpeed", "double", "",1 - Property: "Offset", "KTime", "",0 - Property: "InterlaceMode", "enum", "",0 - Property: "FreeRunning", "bool", "",0 - Property: "Loop", "bool", "",0 - Property: "AccessMode", "enum", "",0 - } - UseMipMap: 0''') - - file.write('\n\t\tFilename: "%s"' % fname_strip) - if fname_strip: fname_strip = '/' + fname_strip - file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # make relative - file.write('\n\t}') - - - def write_texture(texname, tex, num): - # if tex == None then this is a dummy tex - file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname) - file.write('\n\t\tType: "TextureVideoClip"') - file.write('\n\t\tVersion: 202') - # TODO, rare case _empty_ exists as a name. - file.write('\n\t\tTextureName: "Texture::%s"' % texname) - - file.write(''' - Properties60: { - Property: "Translation", "Vector", "A+",0,0,0 - Property: "Rotation", "Vector", "A+",0,0,0 - Property: "Scaling", "Vector", "A+",1,1,1''') - file.write('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num) - - - # WrapModeU/V 0==rep, 1==clamp, TODO add support - file.write(''' - Property: "TextureTypeUse", "enum", "",0 - Property: "CurrentTextureBlendMode", "enum", "",1 - Property: "UseMaterial", "bool", "",0 - Property: "UseMipMap", "bool", "",0 - Property: "CurrentMappingType", "enum", "",0 - Property: "UVSwap", "bool", "",0''') - - file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX) - file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY) - - file.write(''' - Property: "TextureRotationPivot", "Vector3D", "",0,0,0 - Property: "TextureScalingPivot", "Vector3D", "",0,0,0 - Property: "VideoProperty", "object", "" - }''') - - file.write('\n\t\tMedia: "Video::%s"' % texname) - - if tex: - fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) - else: - fname = fname_strip = fname_rel = '' - - file.write('\n\t\tFileName: "%s"' % fname_strip) - file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # need some make relative command - - file.write(''' - ModelUVTranslation: 0,0 - ModelUVScaling: 1,1 - Texture_Alpha_Source: "None" - Cropping: 0,0,0,0 - }''') - - def write_deformer_skin(obname): - ''' - Each mesh has its own deformer - ''' - file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname) - file.write(''' - Version: 100 - MultiLayer: 0 - Type: "Skin" - Properties60: { - } - Link_DeformAcuracy: 50 - }''') - - # in the example was 'Bip01 L Thigh_2' - def write_sub_deformer_skin(my_mesh, my_bone, weights): - - ''' - Each subdeformer is spesific to a mesh, but the bone it links to can be used by many sub-deformers - So the SubDeformer needs the mesh-object name as a prefix to make it unique - - Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer, - a but silly but dosnt really matter - ''' - file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName)) - - file.write(''' - Version: 100 - MultiLayer: 0 - Type: "Cluster" - Properties60: { - Property: "SrcModel", "object", "" - Property: "SrcModelReference", "object", "" - } - UserData: "", ""''') - - # Support for bone parents - if my_mesh.fbxBoneParent: - if my_mesh.fbxBoneParent == my_bone: - # TODO - this is a bit lazy, we could have a simple write loop - # for this case because all weights are 1.0 but for now this is ok - # Parent Bones arent used all that much anyway. - vgroup_data = [(j, 1.0) for j in xrange(len(my_mesh.blenData.verts))] - else: - # This bone is not a parent of this mesh object, no weights - vgroup_data = [] - - else: - # Normal weight painted mesh - if my_bone.blenName in weights[0]: - # Before we used normalized wright list - #vgroup_data = me.getVertsFromGroup(bone.name, 1) - group_index = weights[0].index(my_bone.blenName) - vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]] - else: - vgroup_data = [] - - file.write('\n\t\tIndexes: ') - - i = -1 - for vg in vgroup_data: - if i == -1: - file.write('%i' % vg[0]) - i=0 - else: - if i==23: - file.write('\n\t\t') - i=0 - file.write(',%i' % vg[0]) - i+=1 - - file.write('\n\t\tWeights: ') - i = -1 - for vg in vgroup_data: - if i == -1: - file.write('%.8f' % vg[1]) - i=0 - else: - if i==38: - file.write('\n\t\t') - i=0 - file.write(',%.8f' % vg[1]) - i+=1 - - if my_mesh.fbxParent: - # TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible! - m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) - else: - # Yes! this is it... - but dosnt work when the mesh is a. - m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) - - #m = mtx4_z90 * my_bone.restMatrix - matstr = mat4x4str(m) - matstr_i = mat4x4str(m.invert()) - - file.write('\n\t\tTransform: %s' % matstr_i) # THIS IS __NOT__ THE GLOBAL MATRIX AS DOCUMENTED :/ - file.write('\n\t\tTransformLink: %s' % matstr) - file.write('\n\t}') - - def write_mesh(my_mesh): - - me = my_mesh.blenData - - # if there are non NULL materials on this mesh - if my_mesh.blenMaterials: do_materials = True - else: do_materials = False - - if my_mesh.blenTextures: do_textures = True - else: do_textures = False - - do_uvs = me.faceUV - - - file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) - file.write('\n\t\tVersion: 232') # newline is added in write_object_props - - poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3] - pose_items.append((my_mesh.fbxName, poseMatrix)) - - file.write('\n\t\t}') - file.write('\n\t\tMultiLayer: 0') - file.write('\n\t\tMultiTake: 1') - file.write('\n\t\tShading: Y') - file.write('\n\t\tCulling: "CullingOff"') - - - # Write the Real Mesh data here - file.write('\n\t\tVertices: ') - i=-1 - - for v in me.verts: - if i==-1: - file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0 - else: - if i==7: - file.write('\n\t\t'); i=0 - file.write(',%.6f,%.6f,%.6f'% tuple(v.co)) - i+=1 - - file.write('\n\t\tPolygonVertexIndex: ') - i=-1 - for f in me.faces: - fi = [v.index for v in f] - # flip the last index, odd but it looks like - # this is how fbx tells one face from another - fi[-1] = -(fi[-1]+1) - fi = tuple(fi) - if i==-1: - if len(f) == 3: file.write('%i,%i,%i' % fi ) - else: file.write('%i,%i,%i,%i' % fi ) - i=0 - else: - if i==13: - file.write('\n\t\t') - i=0 - if len(f) == 3: file.write(',%i,%i,%i' % fi ) - else: file.write(',%i,%i,%i,%i' % fi ) - i+=1 - - file.write('\n\t\tEdges: ') - i=-1 - for ed in me.edges: - if i==-1: - file.write('%i,%i' % (ed.v1.index, ed.v2.index)) - i=0 - else: - if i==13: - file.write('\n\t\t') - i=0 - file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) - i+=1 - - file.write('\n\t\tGeometryVersion: 124') - - file.write(''' - LayerElementNormal: 0 { - Version: 101 - Name: "" - MappingInformationType: "ByVertice" - ReferenceInformationType: "Direct" - Normals: ''') - - i=-1 - for v in me.verts: - if i==-1: - file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0 - else: - if i==2: - file.write('\n '); i=0 - file.write(',%.15f,%.15f,%.15f' % tuple(v.no)) - i+=1 - file.write('\n\t\t}') - - # Write Face Smoothing - file.write(''' - LayerElementSmoothing: 0 { - Version: 102 - Name: "" - MappingInformationType: "ByPolygon" - ReferenceInformationType: "Direct" - Smoothing: ''') - - i=-1 - for f in me.faces: - if i==-1: - file.write('%i' % f.smooth); i=0 - else: - if i==54: - file.write('\n '); i=0 - file.write(',%i' % f.smooth) - i+=1 - - file.write('\n\t\t}') - - # Write Edge Smoothing - file.write(''' - LayerElementSmoothing: 1 { - Version: 101 - Name: "" - MappingInformationType: "ByEdge" - ReferenceInformationType: "Direct" - Smoothing: ''') - - SHARP = Blender.Mesh.EdgeFlags.SHARP - i=-1 - for ed in me.edges: - if i==-1: - file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 - else: - if i==54: - file.write('\n '); i=0 - file.write(',%i' % ((ed.flag&SHARP)!=0)) - i+=1 - - file.write('\n\t\t}') - del SHARP - - - # Write VertexColor Layers - # note, no programs seem to use this info :/ - collayers = [] - if me.vertexColors: - collayers = me.getColorLayerNames() - collayer_orig = me.activeColorLayer - for colindex, collayer in enumerate(collayers): - me.activeColorLayer = collayer - file.write('\n\t\tLayerElementColor: %i {' % colindex) - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % collayer) - - file.write(''' - MappingInformationType: "ByPolygonVertex" - ReferenceInformationType: "IndexToDirect" - Colors: ''') - - i = -1 - ii = 0 # Count how many Colors we write - - for f in me.faces: - for col in f.col: - if i==-1: - file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) - i=0 - else: - if i==7: - file.write('\n\t\t\t\t') - i=0 - file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) - i+=1 - ii+=1 # One more Color - - file.write('\n\t\t\tColorIndex: ') - i = -1 - for j in xrange(ii): - if i == -1: - file.write('%i' % j) - i=0 - else: - if i==55: - file.write('\n\t\t\t\t') - i=0 - file.write(',%i' % j) - i+=1 - - file.write('\n\t\t}') - - - - # Write UV and texture layers. - uvlayers = [] - if do_uvs: - uvlayers = me.getUVLayerNames() - uvlayer_orig = me.activeUVLayer - for uvindex, uvlayer in enumerate(uvlayers): - me.activeUVLayer = uvlayer - file.write('\n\t\tLayerElementUV: %i {' % uvindex) - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % uvlayer) - - file.write(''' - MappingInformationType: "ByPolygonVertex" - ReferenceInformationType: "IndexToDirect" - UV: ''') - - i = -1 - ii = 0 # Count how many UVs we write - - for f in me.faces: - for uv in f.uv: - if i==-1: - file.write('%.6f,%.6f' % tuple(uv)) - i=0 - else: - if i==7: - file.write('\n ') - i=0 - file.write(',%.6f,%.6f' % tuple(uv)) - i+=1 - ii+=1 # One more UV - - file.write('\n\t\t\tUVIndex: ') - i = -1 - for j in xrange(ii): - if i == -1: - file.write('%i' % j) - i=0 - else: - if i==55: - file.write('\n\t\t\t\t') - i=0 - file.write(',%i' % j) - i+=1 - - file.write('\n\t\t}') - - if do_textures: - file.write('\n\t\tLayerElementTexture: %i {' % uvindex) - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: "%s"' % uvlayer) - - if len(my_mesh.blenTextures) == 1: - file.write('\n\t\t\tMappingInformationType: "AllSame"') - else: - file.write('\n\t\t\tMappingInformationType: "ByPolygon"') - - file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') - file.write('\n\t\t\tBlendMode: "Translucent"') - file.write('\n\t\t\tTextureAlpha: 1') - file.write('\n\t\t\tTextureId: ') - - if len(my_mesh.blenTextures) == 1: - file.write('0') - else: - texture_mapping_local = {None:-1} - - i = 0 # 1 for dummy - for tex in my_mesh.blenTextures: - if tex: # None is set above - texture_mapping_local[tex] = i - i+=1 - - i=-1 - for f in me.faces: - img_key = f.image - - if i==-1: - i=0 - file.write( '%s' % texture_mapping_local[img_key]) - else: - if i==55: - file.write('\n ') - i=0 - - file.write(',%s' % texture_mapping_local[img_key]) - i+=1 - - else: - file.write(''' - LayerElementTexture: 0 { - Version: 101 - Name: "" - MappingInformationType: "NoMappingInformation" - ReferenceInformationType: "IndexToDirect" - BlendMode: "Translucent" - TextureAlpha: 1 - TextureId: ''') - file.write('\n\t\t}') - - me.activeUVLayer = uvlayer_orig - - # Done with UV/textures. - - if do_materials: - file.write('\n\t\tLayerElementMaterial: 0 {') - file.write('\n\t\t\tVersion: 101') - file.write('\n\t\t\tName: ""') - - if len(my_mesh.blenMaterials) == 1: - file.write('\n\t\t\tMappingInformationType: "AllSame"') - else: - file.write('\n\t\t\tMappingInformationType: "ByPolygon"') - - file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') - file.write('\n\t\t\tMaterials: ') - - if len(my_mesh.blenMaterials) == 1: - file.write('0') - else: - # Build a material mapping for this - material_mapping_local = {} # local-mat & tex : global index. - - for j, mat_tex_pair in enumerate(my_mesh.blenMaterials): - material_mapping_local[mat_tex_pair] = j - - len_material_mapping_local = len(material_mapping_local) - - mats = my_mesh.blenMaterialList - - i=-1 - for f in me.faces: - try: mat = mats[f.mat] - except:mat = None - - if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ - else: tex = None - - if i==-1: - i=0 - file.write( '%s' % (material_mapping_local[mat, tex])) # None for mat or tex is ok - else: - if i==55: - file.write('\n\t\t\t\t') - i=0 - - file.write(',%s' % (material_mapping_local[mat, tex])) - i+=1 - - file.write('\n\t\t}') - - file.write(''' - Layer: 0 { - Version: 100 - LayerElement: { - Type: "LayerElementNormal" - TypedIndex: 0 - }''') - - if do_materials: - file.write(''' - LayerElement: { - Type: "LayerElementMaterial" - TypedIndex: 0 - }''') - - # Always write this - if do_textures: - file.write(''' - LayerElement: { - Type: "LayerElementTexture" - TypedIndex: 0 - }''') - - if me.vertexColors: - file.write(''' - LayerElement: { - Type: "LayerElementColor" - TypedIndex: 0 - }''') - - if do_uvs: # same as me.faceUV - file.write(''' - LayerElement: { - Type: "LayerElementUV" - TypedIndex: 0 - }''') - - - file.write('\n\t\t}') - - if len(uvlayers) > 1: - for i in xrange(1, len(uvlayers)): - - file.write('\n\t\tLayer: %i {' % i) - file.write('\n\t\t\tVersion: 100') - - file.write(''' - LayerElement: { - Type: "LayerElementUV"''') - - file.write('\n\t\t\t\tTypedIndex: %i' % i) - file.write('\n\t\t\t}') - - if do_textures: - - file.write(''' - LayerElement: { - Type: "LayerElementTexture"''') - - file.write('\n\t\t\t\tTypedIndex: %i' % i) - file.write('\n\t\t\t}') - - file.write('\n\t\t}') - - if len(collayers) > 1: - # Take into account any UV layers - layer_offset = 0 - if uvlayers: layer_offset = len(uvlayers)-1 - - for i in xrange(layer_offset, len(collayers)+layer_offset): - file.write('\n\t\tLayer: %i {' % i) - file.write('\n\t\t\tVersion: 100') - - file.write(''' - LayerElement: { - Type: "LayerElementColor"''') - - file.write('\n\t\t\t\tTypedIndex: %i' % i) - file.write('\n\t\t\t}') - file.write('\n\t\t}') - file.write('\n\t}') - - def write_group(name): - file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name) - - file.write(''' - Properties60: { - Property: "MultiLayer", "bool", "",0 - Property: "Pickable", "bool", "",1 - Property: "Transformable", "bool", "",1 - Property: "Show", "bool", "",1 - } - MultiLayer: 0 - }''') - - - # add meshes here to clear because they are not used anywhere. - meshes_to_clear = [] - - ob_meshes = [] - ob_lights = [] - ob_cameras = [] - # in fbx we export bones as children of the mesh - # armatures not a part of a mesh, will be added to ob_arms - ob_bones = [] - ob_arms = [] - ob_null = [] # emptys - - # List of types that have blender objects (not bones) - ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null] - - groups = [] # blender groups, only add ones that have objects in the selections - materials = {} # (mat, image) keys, should be a set() - textures = {} # should be a set() - - tmp_ob_type = ob_type = None # incase no objects are exported, so as not to raise an error - - # if EXP_OBS_SELECTED is false, use sceens objects - if not batch_objects: - if EXP_OBS_SELECTED: tmp_objects = sce.objects.context - else: tmp_objects = sce.objects - else: - tmp_objects = batch_objects - - if EXP_ARMATURE: - # This is needed so applying modifiers dosnt apply the armature deformation, its also needed - # ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes. - # set every armature to its rest, backup the original values so we done mess up the scene - ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures] - - for arm in bpy.data.armatures: - arm.restPosition = True - - if ob_arms_orig_rest: - for ob_base in bpy.data.objects: - #if ob_base.type == 'Armature': - ob_base.makeDisplayList() - - # This causes the makeDisplayList command to effect the mesh - Blender.Set('curframe', Blender.Get('curframe')) - - - for ob_base in tmp_objects: - for ob, mtx in BPyObject.getDerivedObjects(ob_base): - #for ob in [ob_base,]: - tmp_ob_type = ob.type - if tmp_ob_type == 'Camera': - if EXP_CAMERA: - ob_cameras.append(my_object_generic(ob, mtx)) - elif tmp_ob_type == 'Lamp': - if EXP_LAMP: - ob_lights.append(my_object_generic(ob, mtx)) - elif tmp_ob_type == 'Armature': - if EXP_ARMATURE: - # TODO - armatures dont work in dupligroups! - if ob not in ob_arms: ob_arms.append(ob) - # ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)" - elif tmp_ob_type == 'Empty': - if EXP_EMPTY: - ob_null.append(my_object_generic(ob, mtx)) - elif EXP_MESH: - origData = True - if tmp_ob_type != 'Mesh': - me = bpy.data.meshes.new() - try: me.getFromObject(ob) - except: me = None - if me: - meshes_to_clear.append( me ) - mats = me.materials - origData = False - else: - # Mesh Type! - if EXP_MESH_APPLY_MOD: - me = bpy.data.meshes.new() - me.getFromObject(ob) - - # so we keep the vert groups - if EXP_ARMATURE: - orig_mesh = ob.getData(mesh=1) - if orig_mesh.getVertGroupNames(): - ob.copy().link(me) - # If new mesh has no vgroups we can try add if verts are teh same - if not me.getVertGroupNames(): # vgroups were not kept by the modifier - if len(me.verts) == len(orig_mesh.verts): - groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh) - BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) - - # print ob, me, me.getVertGroupNames() - meshes_to_clear.append( me ) - origData = False - mats = me.materials - else: - me = ob.getData(mesh=1) - mats = me.materials - - # Support object colors - tmp_colbits = ob.colbits - if tmp_colbits: - tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too. - for i in xrange(16): - if tmp_colbits & (1< fbxObject mapping - # this is needed for groups as well as fbxParenting - bpy.data.objects.tag = False - tmp_obmapping = {} - for ob_generic in ob_all_typegroups: - for ob_base in ob_generic: - ob_base.blenObject.tag = True - tmp_obmapping[ob_base.blenObject] = ob_base - - # Build Groups from objects we export - for blenGroup in bpy.data.groups: - fbxGroupName = None - for ob in blenGroup.objects: - if ob.tag: - if fbxGroupName == None: - fbxGroupName = sane_groupname(blenGroup) - groups.append((fbxGroupName, blenGroup)) - - tmp_obmapping[ob].fbxGroupNames.append(fbxGroupName) # also adds to the objects fbxGroupNames - - groups.sort() # not really needed - - # Assign parents using this mapping - for ob_generic in ob_all_typegroups: - for my_ob in ob_generic: - parent = my_ob.blenObject.parent - if parent and parent.tag: # does it exist and is it in the mapping - my_ob.fbxParent = tmp_obmapping[parent] - - - del tmp_obmapping - # Finished finding groups we use - - - materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.iterkeys()] - textures = [(sane_texname(tex), tex) for tex in textures.iterkeys() if tex] - materials.sort() # sort by name - textures.sort() - - camera_count = 8 - file.write(''' - -; Object definitions -;------------------------------------------------------------------ - -Definitions: { - Version: 100 - Count: %i''' % (\ - 1+1+camera_count+\ - len(ob_meshes)+\ - len(ob_lights)+\ - len(ob_cameras)+\ - len(ob_arms)+\ - len(ob_null)+\ - len(ob_bones)+\ - bone_deformer_count+\ - len(materials)+\ - (len(textures)*2))) # add 1 for the root model 1 for global settings - - del bone_deformer_count - - file.write(''' - ObjectType: "Model" { - Count: %i - }''' % (\ - 1+camera_count+\ - len(ob_meshes)+\ - len(ob_lights)+\ - len(ob_cameras)+\ - len(ob_arms)+\ - len(ob_null)+\ - len(ob_bones))) # add 1 for the root model - - file.write(''' - ObjectType: "Geometry" { - Count: %i - }''' % len(ob_meshes)) - - if materials: - file.write(''' - ObjectType: "Material" { - Count: %i - }''' % len(materials)) - - if textures: - file.write(''' - ObjectType: "Texture" { - Count: %i - }''' % len(textures)) # add 1 for an empty tex - file.write(''' - ObjectType: "Video" { - Count: %i - }''' % len(textures)) # add 1 for an empty tex - - tmp = 0 - # Add deformer nodes - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - tmp+=1 - - # Add subdeformers - for my_bone in ob_bones: - tmp += len(my_bone.blenMeshes) - - if tmp: - file.write(''' - ObjectType: "Deformer" { - Count: %i - }''' % tmp) - del tmp - - # we could avoid writing this possibly but for now just write it - - file.write(''' - ObjectType: "Pose" { - Count: 1 - }''') - - if groups: - file.write(''' - ObjectType: "GroupSelection" { - Count: %i - }''' % len(groups)) - - file.write(''' - ObjectType: "GlobalSettings" { - Count: 1 - } -}''') - - file.write(''' - -; Object properties -;------------------------------------------------------------------ - -Objects: {''') - - # To comply with other FBX FILES - write_camera_switch() - - # Write the null object - write_null(None, 'blend_root')# , GLOBAL_MATRIX) - - for my_null in ob_null: - write_null(my_null) - - for my_arm in ob_arms: - write_null(my_arm) - - for my_cam in ob_cameras: - write_camera(my_cam) - - for my_light in ob_lights: - write_light(my_light) - - for my_mesh in ob_meshes: - write_mesh(my_mesh) - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - write_bone(my_bone) - - write_camera_default() - - for matname, (mat, tex) in materials: - write_material(matname, mat) # We only need to have a material per image pair, but no need to write any image info into the material (dumb fbx standard) - - # each texture uses a video, odd - for texname, tex in textures: - write_video(texname, tex) - i = 0 - for texname, tex in textures: - write_texture(texname, tex, i) - i+=1 - - for groupname, group in groups: - write_group(groupname) - - # NOTE - c4d and motionbuilder dont need normalized weights, but deep-exploration 5 does and (max?) do. - - # Write armature modifiers - # TODO - add another MODEL? - because of this skin definition. - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - write_deformer_skin(my_mesh.fbxName) - - # Get normalized weights for temorary use - if my_mesh.fbxBoneParent: - weights = None - else: - weights = meshNormalizedWeights(my_mesh.blenData) - - #for bonename, bone, obname, bone_mesh, armob in ob_bones: - for my_bone in ob_bones: - if me in my_bone.blenMeshes.itervalues(): - write_sub_deformer_skin(my_mesh, my_bone, weights) - - # Write pose's really weired, only needed when an armature and mesh are used together - # each by themselves dont need pose data. for now only pose meshes and bones - - file.write(''' - Pose: "Pose::BIND_POSES", "BindPose" { - Type: "BindPose" - Version: 100 - Properties60: { - } - NbPoseNodes: ''') - file.write(str(len(pose_items))) - - - for fbxName, matrix in pose_items: - file.write('\n\t\tPoseNode: {') - file.write('\n\t\t\tNode: "Model::%s"' % fbxName ) - if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix)) - else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity)) - file.write('\n\t\t}') - - file.write('\n\t}') - - - # Finish Writing Objects - # Write global settings - file.write(''' - GlobalSettings: { - Version: 1000 - Properties60: { - Property: "UpAxis", "int", "",1 - Property: "UpAxisSign", "int", "",1 - Property: "FrontAxis", "int", "",2 - Property: "FrontAxisSign", "int", "",1 - Property: "CoordAxis", "int", "",0 - Property: "CoordAxisSign", "int", "",1 - Property: "UnitScaleFactor", "double", "",100 - } - } -''') - file.write('}') - - file.write(''' - -; Object relations -;------------------------------------------------------------------ - -Relations: {''') - - file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}') - - for my_null in ob_null: - file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_null.fbxName) - - for my_arm in ob_arms: - file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_arm.fbxName) - - for my_mesh in ob_meshes: - file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % my_mesh.fbxName) - - # TODO - limbs can have the same name for multiple armatures, should prefix. - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - file.write('\n\tModel: "Model::%s", "Limb" {\n\t}' % my_bone.fbxName) - - for my_cam in ob_cameras: - file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % my_cam.fbxName) - - for my_light in ob_lights: - file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % my_light.fbxName) - - file.write(''' - Model: "Model::Producer Perspective", "Camera" { - } - Model: "Model::Producer Top", "Camera" { - } - Model: "Model::Producer Bottom", "Camera" { - } - Model: "Model::Producer Front", "Camera" { - } - Model: "Model::Producer Back", "Camera" { - } - Model: "Model::Producer Right", "Camera" { - } - Model: "Model::Producer Left", "Camera" { - } - Model: "Model::Camera Switcher", "CameraSwitcher" { - }''') - - for matname, (mat, tex) in materials: - file.write('\n\tMaterial: "Material::%s", "" {\n\t}' % matname) - - if textures: - for texname, tex in textures: - file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {\n\t}' % texname) - for texname, tex in textures: - file.write('\n\tVideo: "Video::%s", "Clip" {\n\t}' % texname) - - # deformers - modifiers - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {\n\t}' % my_mesh.fbxName) - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - for fbxMeshObName in my_bone.blenMeshes: # .keys() - fbxMeshObName - # is this bone effecting a mesh? - file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {\n\t}' % (fbxMeshObName, my_bone.fbxName)) - - # This should be at the end - # file.write('\n\tPose: "Pose::BIND_POSES", "BindPose" {\n\t}') - - for groupname, group in groups: - file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {\n\t}' % groupname) - - file.write('\n}') - file.write(''' - -; Object connections -;------------------------------------------------------------------ - -Connections: {''') - - # NOTE - The FBX SDK dosnt care about the order but some importers DO! - # for instance, defining the material->mesh connection - # before the mesh->blend_root crashes cinema4d - - - # write the fake root node - file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"') - - for ob_generic in ob_all_typegroups: # all blender 'Object's we support - for my_ob in ob_generic: - if my_ob.fbxParent: - file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_ob.fbxName, my_ob.fbxParent.fbxName)) - else: - file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_ob.fbxName) - - if materials: - for my_mesh in ob_meshes: - # Connect all materials to all objects, not good form but ok for now. - for mat, tex in my_mesh.blenMaterials: - if mat: mat_name = mat.name - else: mat_name = None - - if tex: tex_name = tex.name - else: tex_name = None - - file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat_name, tex_name], my_mesh.fbxName)) - - if textures: - for my_mesh in ob_meshes: - if my_mesh.blenTextures: - # file.write('\n\tConnect: "OO", "Texture::_empty_", "Model::%s"' % my_mesh.fbxName) - for tex in my_mesh.blenTextures: - if tex: - file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (sane_name_mapping_tex[tex.name], my_mesh.fbxName)) - - for texname, tex in textures: - file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname)) - - for my_mesh in ob_meshes: - if my_mesh.fbxArm: - file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName)) - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - for fbxMeshObName in my_bone.blenMeshes: # .keys() - file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName)) - - # limbs -> deformers - # for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - for fbxMeshObName in my_bone.blenMeshes: # .keys() - file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName)) - - - #for bonename, bone, obname, me, armob in ob_bones: - for my_bone in ob_bones: - # Always parent to armature now - if my_bone.parent: - file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.parent.fbxName) ) - else: - # the armature object is written as an empty and all root level bones connect to it - file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.fbxArm.fbxName) ) - - # groups - if groups: - for ob_generic in ob_all_typegroups: - for ob_base in ob_generic: - for fbxGroupName in ob_base.fbxGroupNames: - file.write('\n\tConnect: "OO", "Model::%s", "GroupSelection::%s"' % (ob_base.fbxName, fbxGroupName)) - - for my_arm in ob_arms: - file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_arm.fbxName) - - file.write('\n}') - - - # Needed for scene footer as well as animation - render = sce.render - - # from the FBX sdk - #define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000)) - def fbx_time(t): - # 0.5 + val is the same as rounding. - return int(0.5 + ((t/fps) * 46186158000)) - - fps = float(render.fps) - start = render.sFrame - end = render.eFrame - if end < start: start, end = end, start - if start==end: ANIM_ENABLE = False - - # animations for these object types - ob_anim_lists = ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms - - if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]: - - frame_orig = Blender.Get('curframe') - - if ANIM_OPTIMIZE: - ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION - - # default action, when no actions are avaioable - tmp_actions = [None] # None is the default action - blenActionDefault = None - action_lastcompat = None - - if ANIM_ACTION_ALL: - bpy.data.actions.tag = False - tmp_actions = list(bpy.data.actions) - - - # find which actions are compatible with the armatures - # blenActions is not yet initialized so do it now. - tmp_act_count = 0 - for my_arm in ob_arms: - - # get the default name - if not blenActionDefault: - blenActionDefault = my_arm.blenAction - - arm_bone_names = set([my_bone.blenName for my_bone in my_arm.fbxBones]) - - for action in tmp_actions: - - action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) ) - - if action_chan_names: # at least one channel matches. - my_arm.blenActionList.append(action) - action.tag = True - tmp_act_count += 1 - - # incase there is no actions applied to armatures - action_lastcompat = action - - if tmp_act_count: - # unlikely to ever happen but if no actions applied to armatures, just use the last compatible armature. - if not blenActionDefault: - blenActionDefault = action_lastcompat - - del action_lastcompat - - file.write(''' -;Takes and animation section -;---------------------------------------------------- - -Takes: {''') - - if blenActionDefault: - file.write('\n\tCurrent: "%s"' % sane_takename(blenActionDefault)) - else: - file.write('\n\tCurrent: "Default Take"') - - for blenAction in tmp_actions: - # we have tagged all actious that are used be selected armatures - if blenAction: - if blenAction.tag: - print '\taction: "%s" exporting...' % blenAction.name - else: - print '\taction: "%s" has no armature using it, skipping' % blenAction.name - continue - - if blenAction == None: - # Warning, this only accounts for tmp_actions being [None] - file.write('\n\tTake: "Default Take" {') - act_start = start - act_end = end - else: - # use existing name - if blenAction == blenActionDefault: # have we alredy got the name - file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name]) - else: - file.write('\n\tTake: "%s" {' % sane_takename(blenAction)) - - tmp = blenAction.getFrameNumbers() - if tmp: - act_start = min(tmp) - act_end = max(tmp) - del tmp - else: - # Fallback on this, theres not much else we can do? :/ - # when an action has no length - act_start = start - act_end = end - - # Set the action active - for my_bone in ob_arms: - if blenAction in my_bone.blenActionList: - ob.action = blenAction - # print '\t\tSetting Action!', blenAction - # sce.update(1) - - file.write('\n\t\tFileName: "Default_Take.tak"') # ??? - not sure why this is needed - file.write('\n\t\tLocalTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed - file.write('\n\t\tReferenceTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed - - file.write(''' - - ;Models animation - ;----------------------------------------------------''') - - - # set pose data for all bones - # do this here incase the action changes - ''' - for my_bone in ob_bones: - my_bone.flushAnimData() - ''' - i = act_start - while i <= act_end: - Blender.Set('curframe', i) - for ob_generic in ob_anim_lists: - for my_ob in ob_generic: - #Blender.Window.RedrawAll() - if ob_generic == ob_meshes and my_ob.fbxArm: - # We cant animate armature meshes! - pass - else: - my_ob.setPoseFrame(i) - - i+=1 - - - #for bonename, bone, obname, me, armob in ob_bones: - for ob_generic in (ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms): - - for my_ob in ob_generic: - - if ob_generic == ob_meshes and my_ob.fbxArm: - # do nothing, - pass - else: - - file.write('\n\t\tModel: "Model::%s" {' % my_ob.fbxName) # ??? - not sure why this is needed - file.write('\n\t\t\tVersion: 1.1') - file.write('\n\t\t\tChannel: "Transform" {') - - context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in xrange(act_start, act_end+1) ] - - # ---------------- - # ---------------- - for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale - - if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats] - elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats] - elif TX_CHAN=='R': - # Was.... - # elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats] - # - # ...but we need to use the previous euler for compatible conversion. - context_bone_anim_vecs = [] - prev_eul = None - for mtx in context_bone_anim_mats: - if prev_eul: prev_eul = mtx[1].toEuler(prev_eul) - else: prev_eul = mtx[1].toEuler() - context_bone_anim_vecs.append(prev_eul) - - file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation - - for i in xrange(3): - # Loop on each axis of the bone - file.write('\n\t\t\t\t\tChannel: "%s" {'% ('XYZ'[i])) # translation - file.write('\n\t\t\t\t\t\tDefault: %.15f' % context_bone_anim_vecs[0][i] ) - file.write('\n\t\t\t\t\t\tKeyVer: 4005') - - if not ANIM_OPTIMIZE: - # Just write all frames, simple but in-eficient - file.write('\n\t\t\t\t\t\tKeyCount: %i' % (1 + act_end - act_start)) - file.write('\n\t\t\t\t\t\tKey: ') - frame = act_start - while frame <= act_end: - if frame!=act_start: - file.write(',') - - # Curve types are 'C,n' for constant, 'L' for linear - # C,n is for bezier? - linear is best for now so we can do simple keyframe removal - file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) - frame+=1 - else: - # remove unneeded keys, j is the frame, needed when some frames are removed. - context_bone_anim_keys = [ (vec[i], j) for j, vec in enumerate(context_bone_anim_vecs) ] - - # last frame to fisrt frame, missing 1 frame on either side. - # removeing in a backwards loop is faster - #for j in xrange( (act_end-act_start)-1, 0, -1 ): - # j = (act_end-act_start)-1 - j = len(context_bone_anim_keys)-2 - while j > 0 and len(context_bone_anim_keys) > 2: - # print j, len(context_bone_anim_keys) - # Is this key the same as the ones next to it? - - # co-linear horizontal... - if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\ - abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: - - del context_bone_anim_keys[j] - - else: - frame_range = float(context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j-1][1]) - frame_range_fac1 = (context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j][1]) / frame_range - frame_range_fac2 = 1.0 - frame_range_fac1 - - if abs(((context_bone_anim_keys[j-1][0]*frame_range_fac1 + context_bone_anim_keys[j+1][0]*frame_range_fac2)) - context_bone_anim_keys[j][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: - del context_bone_anim_keys[j] - else: - j-=1 - - # keep the index below the list length - if j > len(context_bone_anim_keys)-2: - j = len(context_bone_anim_keys)-2 - - if len(context_bone_anim_keys) == 2 and context_bone_anim_keys[0][0] == context_bone_anim_keys[1][0]: - # This axis has no moton, its okay to skip KeyCount and Keys in this case - pass - else: - # We only need to write these if there is at least one - file.write('\n\t\t\t\t\t\tKeyCount: %i' % len(context_bone_anim_keys)) - file.write('\n\t\t\t\t\t\tKey: ') - for val, frame in context_bone_anim_keys: - if frame != context_bone_anim_keys[0][1]: # not the first - file.write(',') - # frame is alredy one less then blenders frame - file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val )) - - if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0') - elif i==1: file.write('\n\t\t\t\t\t\tColor: 0,1,0') - elif i==2: file.write('\n\t\t\t\t\t\tColor: 0,0,1') - - file.write('\n\t\t\t\t\t}') - file.write('\n\t\t\t\t\tLayerType: %i' % (TX_LAYER+1) ) - file.write('\n\t\t\t\t}') - - # --------------- - - file.write('\n\t\t\t}') - file.write('\n\t\t}') - - # end the take - file.write('\n\t}') - - # end action loop. set original actions - # do this after every loop incase actions effect eachother. - for my_bone in ob_arms: - my_bone.blenObject.action = my_bone.blenAction - - file.write('\n}') - - Blender.Set('curframe', frame_orig) - - else: - # no animation - file.write('\n;Takes and animation section') - file.write('\n;----------------------------------------------------') - file.write('\n') - file.write('\nTakes: {') - file.write('\n\tCurrent: ""') - file.write('\n}') - - - # write meshes animation - #for obname, ob, mtx, me, mats, arm, armname in ob_meshes: - - - # Clear mesh data Only when writing with modifiers applied - for me in meshes_to_clear: - me.verts = None - - - - # --------------------------- Footer - if world: - has_mist = world.mode & 1 - mist_intense, mist_start, mist_end, mist_height = world.mist - world_hor = world.hor - else: - has_mist = mist_intense = mist_start = mist_end = mist_height = 0 - world_hor = 0,0,0 - - file.write('\n;Version 5 settings') - file.write('\n;------------------------------------------------------------------') - file.write('\n') - file.write('\nVersion5: {') - file.write('\n\tAmbientRenderSettings: {') - file.write('\n\t\tVersion: 101') - file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world_amb)) - file.write('\n\t}') - file.write('\n\tFogOptions: {') - file.write('\n\t\tFlogEnable: %i' % has_mist) - file.write('\n\t\tFogMode: 0') - file.write('\n\t\tFogDensity: %.3f' % mist_intense) - file.write('\n\t\tFogStart: %.3f' % mist_start) - file.write('\n\t\tFogEnd: %.3f' % mist_end) - file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world_hor)) - file.write('\n\t}') - file.write('\n\tSettings: {') - file.write('\n\t\tFrameRate: "%i"' % int(fps)) - file.write('\n\t\tTimeFormat: 1') - file.write('\n\t\tSnapOnFrames: 0') - file.write('\n\t\tReferenceTimeIndex: -1') - file.write('\n\t\tTimeLineStartTime: %i' % fbx_time(start-1)) - file.write('\n\t\tTimeLineStopTime: %i' % fbx_time(end-1)) - file.write('\n\t}') - file.write('\n\tRendererSetting: {') - file.write('\n\t\tDefaultCamera: "Producer Perspective"') - file.write('\n\t\tDefaultViewingMode: 0') - file.write('\n\t}') - file.write('\n}') - file.write('\n') - - # Incase sombody imports this, clean up by clearing global dicts - sane_name_mapping_ob.clear() - sane_name_mapping_mat.clear() - sane_name_mapping_tex.clear() - - ob_arms[:] = [] - ob_bones[:] = [] - ob_cameras[:] = [] - ob_lights[:] = [] - ob_meshes[:] = [] - ob_null[:] = [] - - - # copy images if enabled - if EXP_IMAGE_COPY: - copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) - - print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) - return True - - -# -------------------------------------------- -# UI Function - not a part of the exporter. -# this is to seperate the user interface from the rest of the exporter. -from Blender import Draw, Window -EVENT_NONE = 0 -EVENT_EXIT = 1 -EVENT_REDRAW = 2 -EVENT_FILESEL = 3 - -GLOBALS = {} - -# export opts - -def do_redraw(e,v): GLOBALS['EVENT'] = e - -# toggle between these 2, only allow one on at once -def do_obs_sel(e,v): - GLOBALS['EVENT'] = e - GLOBALS['EXP_OBS_SCENE'].val = 0 - GLOBALS['EXP_OBS_SELECTED'].val = 1 - -def do_obs_sce(e,v): - GLOBALS['EVENT'] = e - GLOBALS['EXP_OBS_SCENE'].val = 1 - GLOBALS['EXP_OBS_SELECTED'].val = 0 - -def do_obs_sce(e,v): - GLOBALS['EVENT'] = e - GLOBALS['EXP_OBS_SCENE'].val = 1 - GLOBALS['EXP_OBS_SELECTED'].val = 0 - -def do_batch_type_grp(e,v): - GLOBALS['EVENT'] = e - GLOBALS['BATCH_GROUP'].val = 1 - GLOBALS['BATCH_SCENE'].val = 0 - -def do_batch_type_sce(e,v): - GLOBALS['EVENT'] = e - GLOBALS['BATCH_GROUP'].val = 0 - GLOBALS['BATCH_SCENE'].val = 1 - -def do_anim_act_all(e,v): - GLOBALS['EVENT'] = e - GLOBALS['ANIM_ACTION_ALL'][0].val = 1 - GLOBALS['ANIM_ACTION_ALL'][1].val = 0 - -def do_anim_act_cur(e,v): - if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val: - Draw.PupMenu('Warning%t|Cant use this with batch export group option') - else: - GLOBALS['EVENT'] = e - GLOBALS['ANIM_ACTION_ALL'][0].val = 0 - GLOBALS['ANIM_ACTION_ALL'][1].val = 1 - -def fbx_ui_exit(e,v): - GLOBALS['EVENT'] = e - -def do_help(e,v): - url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' - print 'Trying to open web browser with documentation at this address...' - print '\t' + url - - try: - import webbrowser - webbrowser.open(url) - except: - Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation") - print '...could not open a browser window.' - - - -# run when export is pressed -#def fbx_ui_write(e,v): -def fbx_ui_write(filename): - - # Dont allow overwriting files when saving normally - if not GLOBALS['BATCH_ENABLE'].val: - if not BPyMessages.Warning_SaveOver(filename): - return - - GLOBALS['EVENT'] = EVENT_EXIT - - # Keep the order the same as above for simplicity - # the [] is a dummy arg used for objects - - Blender.Window.WaitCursor(1) - - # Make the matrix - GLOBAL_MATRIX = mtx4_identity - GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val - if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n - if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n - if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n - - ret = write(\ - filename, None,\ - GLOBALS['EXP_OBS_SELECTED'].val,\ - GLOBALS['EXP_MESH'].val,\ - GLOBALS['EXP_MESH_APPLY_MOD'].val,\ - GLOBALS['EXP_MESH_HQ_NORMALS'].val,\ - GLOBALS['EXP_ARMATURE'].val,\ - GLOBALS['EXP_LAMP'].val,\ - GLOBALS['EXP_CAMERA'].val,\ - GLOBALS['EXP_EMPTY'].val,\ - GLOBALS['EXP_IMAGE_COPY'].val,\ - GLOBAL_MATRIX,\ - GLOBALS['ANIM_ENABLE'].val,\ - GLOBALS['ANIM_OPTIMIZE'].val,\ - GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\ - GLOBALS['ANIM_ACTION_ALL'][0].val,\ - GLOBALS['BATCH_ENABLE'].val,\ - GLOBALS['BATCH_GROUP'].val,\ - GLOBALS['BATCH_SCENE'].val,\ - GLOBALS['BATCH_FILE_PREFIX'].val,\ - GLOBALS['BATCH_OWN_DIR'].val,\ - ) - - Blender.Window.WaitCursor(0) - GLOBALS.clear() - - if ret == False: - Draw.PupMenu('Error%t|Path cannot be written to!') - - -def fbx_ui(): - # Only to center the UI - x,y = GLOBALS['MOUSE'] - x-=180; y-=0 # offset... just to get it centered - - Draw.Label('Export Objects...', x+20,y+165, 200, 20) - - if not GLOBALS['BATCH_ENABLE'].val: - Draw.BeginAlign() - GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel) - GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce) - Draw.EndAlign() - - Draw.BeginAlign() - GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)') - GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrese about the X axis') - GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrese about the Y axis') - GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrese about the Z axis') - Draw.EndAlign() - - y -= 35 - - Draw.BeginAlign() - GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects') - GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects') - GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects') - GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects') - GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z) - Draw.EndAlign() - - if GLOBALS['EXP_MESH'].val: - # below mesh but - Draw.BeginAlign() - GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z) - GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z) - Draw.EndAlign() - - GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z) - - - Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20) - - GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw) - if GLOBALS['ANIM_ENABLE'].val: - Draw.BeginAlign() - GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw) - if GLOBALS['ANIM_OPTIMIZE'].val: - GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)') - Draw.EndAlign() - - Draw.BeginAlign() - GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur) - GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all) - Draw.EndAlign() - - - Draw.Label('Export Batch...', x+20,y-60, 300, 20) - GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw) - - if GLOBALS['BATCH_ENABLE'].val: - Draw.BeginAlign() - GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp) - GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce) - - # Own dir requires OS module - if os: - GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file') - GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') - else: - GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') - - - Draw.EndAlign() - - #y+=80 - - ''' - Draw.BeginAlign() - GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ') - Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw) - ''' - # Until batch is added - # - - - #Draw.BeginAlign() - Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help) - Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit) - Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw) - - #Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write) - #Draw.EndAlign() - - # exit when mouse out of the view? - # GLOBALS['EVENT'] = EVENT_EXIT - -#def write_ui(filename): -def write_ui(): - - # globals - GLOBALS['EVENT'] = EVENT_REDRAW - #GLOBALS['MOUSE'] = Window.GetMouseCoords() - GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] - GLOBALS['FILENAME'] = '' - ''' - # IF called from the fileselector - if filename == None: - GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx')) - else: - GLOBALS['FILENAME'].val = filename - ''' - GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity - GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0) - - GLOBALS['EXP_MESH'] = Draw.Create(1) - GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1) - GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0) - GLOBALS['EXP_ARMATURE'] = Draw.Create(1) - GLOBALS['EXP_LAMP'] = Draw.Create(1) - GLOBALS['EXP_CAMERA'] = Draw.Create(1) - GLOBALS['EXP_EMPTY'] = Draw.Create(1) - GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0) - # animation opts - GLOBALS['ANIM_ENABLE'] = Draw.Create(1) - GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1) - GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places - GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action - - # batch export options - GLOBALS['BATCH_ENABLE'] = Draw.Create(0) - GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once. - GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above - GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1]) - GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0) - # done setting globals - - # Used by the user interface - GLOBALS['_SCALE'] = Draw.Create(1.0) - GLOBALS['_XROT90'] = Draw.Create(True) - GLOBALS['_YROT90'] = Draw.Create(False) - GLOBALS['_ZROT90'] = Draw.Create(False) - - # best not do move the cursor - # Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()]) - - # hack so the toggle buttons redraw. this is not nice at all - while GLOBALS['EVENT'] != EVENT_EXIT: - - if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val: - #Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ") - GLOBALS['ANIM_ACTION_ALL'][0].val = 1 - GLOBALS['ANIM_ACTION_ALL'][1].val = 0 - - if GLOBALS['EVENT'] == EVENT_FILESEL: - if GLOBALS['BATCH_ENABLE'].val: - txt = 'Batch FBX Dir' - name = Blender.sys.expandpath('//') - else: - txt = 'Export FBX' - name = Blender.sys.makename(ext='.fbx') - - Blender.Window.FileSelector(fbx_ui_write, txt, name) - #fbx_ui_write('/test.fbx') - break - - Draw.UIBlock(fbx_ui, 0) - - - # GLOBALS.clear() -#test = [write_ui] -if __name__ == '__main__': - # Cant call the file selector first because of a bug in the interface that crashes it. - # Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx')) - #write('/scratch/test.fbx') - #write_ui('/scratch/test.fbx') - - if not set: - Draw.PupMenu('Error%t|A full install of python2.3 or python 2.4+ is needed to run this script.') - else: - write_ui() diff --git a/release/scripts/export_lightwave_motion.py b/release/scripts/export_lightwave_motion.py deleted file mode 100644 index 562e44f3a2b..00000000000 --- a/release/scripts/export_lightwave_motion.py +++ /dev/null @@ -1,157 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: <- these words are ignored -Name: 'Lightwave Motion (.mot)...' -Blender: 241 -Group: 'Export' -Tip: 'Export Loc Rot Size chanels to a Lightwave .mot file' -""" - -__author__ = "Daniel Salazar (ZanQdo)" -__url__ = ("blender", "blenderartists.org", -"e-mail: zanqdo@gmail.com") -__version__ = "16/04/08" - -__bpydoc__ = """\ -This script exports the selected object's motion channels to Lightwave -motion files (.mot). - -Usage: -Run the script with one or more objects selected (any kind), frames exported -are between Start and End frames in Render buttons. - -""" - -# $Id$ -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2003, 2004: A Vanpoucke -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- -import Blender as B -import math as M -#------------------------------------ -#Declarados: -TotalCanales = 9 -#------------------------------------ - -def FuncionPrincipal (Dir): - B.Window.WaitCursor(1) - ObjSelect = B.Object.GetSelected() - - if not ObjSelect: - B.Draw.PupMenu('Select 1 or more objects, aborting.') - return - - if not Dir.lower().endswith('.mot'): - Dir += '.mot' - - - SC = B.Scene.GetCurrent() - SCR = SC.getRenderingContext() - - for ob in ObjSelect: - origName= NombreObjeto= ob.name - print '----\nExporting Object "%s" motion file...' % origName - - FrameA = B.Get('curframe') - FrameP = B.Get('staframe') - FrameF = B.Get('endframe') - - FrameRate = float(SCR.framesPerSec()) - - #--------------------------------------------- - - # Replace danger characters by '_' - for ch in ' /\\~!@#$%^&*()+=[];\':",./<>?\t\r\n': - NombreObjeto = NombreObjeto.replace(ch, '_') - - # Check for file path extension - if len(ObjSelect) > 1: - DirN= '%s_%s.mot' % (Dir[:-4], NombreObjeto) - else: - DirN= Dir - - # Open the file - File = open(DirN,'w') - File.write ('LWMO\n3\n\n') # 3 is the version number. - - # number of channels - File.write ('NumChannels %i\n' % TotalCanales) - - # ---------------------------- - # Main Cycle - - def CicloPrimario(NumCanal): - B.Set('curframe', FrameP) - - File.write ('Channel %i\n{ Envelope\n %i\n' % (NumCanal, (FrameF - FrameP + 1))) - - FrameA = FrameP - while FrameA < (FrameF + 1): - - B.Set('curframe', FrameA) - - mat= ob.mat # Worldspace matrix - - if NumCanal == 0: - Val = mat.translationPart().x - elif NumCanal == 1: - Val = mat.translationPart().z - elif NumCanal == 2: - Val = mat.translationPart().y - elif NumCanal == 3: - Val = M.radians (-mat.toEuler().z) - elif NumCanal == 4: - Val = M.radians (-mat.toEuler().x) - elif NumCanal == 5: - Val = M.radians (-mat.toEuler().y) - elif NumCanal == 6: - Val = mat.scalePart().x - elif NumCanal == 7: - Val = mat.scalePart().z - elif NumCanal == 8: - Val = mat.scalePart().y - File.write (' Key %f %f 3 0 0 0 0 0 0\n' % (Val, (FrameA/FrameRate))) - - FrameA += 1 - # Ending Stuff - File.write (' Behaviors 1 1\n}\n') - - NumObjetoActual = len(ObjSelect) - Iteraciones = 0 - ProgBarVal = 0.0 - while Iteraciones < TotalCanales: - CicloPrimario(Iteraciones) - - # Start Progress Bar - B.Window.DrawProgressBar(ProgBarVal, origName) - ProgBarVal = (float(Iteraciones) / TotalCanales) * 0.98 - Iteraciones += 1 - - B.Window.DrawProgressBar(1.0, '') # Done - print '\nDone, %s motion file location is:\n%s\n' % (origName, DirN) - B.Window.WaitCursor(0) - -# Check if there are selected objects -def main(): - B.Window.FileSelector(FuncionPrincipal, "Write .mot File", B.sys.makename(ext='.mot')) - -if __name__=='__main__': - main() diff --git a/release/scripts/export_m3g.py b/release/scripts/export_m3g.py deleted file mode 100644 index c74e7acbcd3..00000000000 --- a/release/scripts/export_m3g.py +++ /dev/null @@ -1,3074 +0,0 @@ -#!BPY -# coding: utf-8 -""" Registration info for Blender menus: -Name: 'M3G (.m3g, .java)...' -Blender: 244 -Group: 'Export' -Tooltip: 'Export to M3G' -""" -#------------------------------------------------------------------------ -# M3G exporter for blender 2.37 or above -# -# Source: http://www.nelson-games.de/bl2m3g/source -# -# $Id$ -# -# Author: Gerhard Völkl -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2005: gerhard völkl gkvoelkl@yahoo.de -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# ***** END GPL LICENCE BLOCK ***** -# -# To use script: -# 1.) load this file in the text window. -# (press SHIFT+F11, Open New via Datablock button) -# 2.) make sure your mouse is over the text edit window and -# run this script. (press ALT+P) -# Or: -# copy to the scripts directory and it will appear in the -# export list. (Needs 2.32 or higher) -# -# Based on informations from: -# wrl2export.py from Rick Kimball and others -# --------------------------------------------------------------------------# -# History 0.2 -# * maximal Precision in VertexArray (with algorithms from Kalle Raita) -# * IPO Animation with mesh: Rotation, Translation and Size -# History 0.3 -# * to find a 3d object in your java programm you can assign a userID -# your blender object has name 'cube#01' your 3d object will have ID 01 -# the number after '#' is taken -# * more than one material per mesh can be used -# * uv texture support (implemented by Aki Koskinen and Juha Laitinen) -# The image which is bound to the faces will be exportet within m3g-file -# Limitations by M3G-API: -# The width and height of the image must be non-negative powers of two, -# but they need not to be equal. Maximum value is 256. -# *.java export: Only PNG images can be used. -# History 0.4 -# * check limitation of texture images (credit to MASTER_ZION for Brasil) -# * Better light: The light modeles of Blender and M3G are naturally -# different. So the export script trys to translate as much as possible -# -# M3G Light type Blender Light type -# -------------------------------------------------------------- -# AMIENT Light Not available as light type in Blender -# DIRECTIONAL Light SUN -# OMNIdirectional light LAMP -# SPOT light SPOT -# not translated HEMI -# not translated AREA -# -# Attributs of M3G Lights: -# -# Attenuation (OMNI,SPOT): -# Intensity of light changes with distance -# The attenuation factor is 1 / (c + l d + q d2) -# where d is the distance between the light and the vertex being lighted -# and c, l, q are the constant, linear, and quadratic coefficients. -# In Blender exists much complex posibilies. To simplify exporter uses -# only button Dist: distance at which the light intensity is half -# the Energy -# Color (ALL) -# Color of light -# Intensity (ALL) -# The RGB color of this Light is multiplied component-wise with the -# intensity. In Blender : energy -# SpotAngle (SPOT) -# the spot cone angle for this Light -# In Blender: spotSize -# SpotExponent (SPOT) -# The spot exponent controls the distribution of the intensity of -# this Light within the spot cone, such that larger values yield -# a more concentrated cone. In Blender: SpotBl -# -# * Some GUI for options -# First prototype of GUI was created using RipSting's Blender-Python -# GUI designer. Download at Http://oregonstate.edu/~dennisa/Blender/BPG/ -# -# * Ambiente light -# Information is taken by world ambiente attribute -# -# * Parenting Part 1 -# In Blender the Empty object is used to group objects. All objects -# which have the same empty as parent are the member of the same group. -# -# empty <-- Parent of -- element 1 -# <-- Parent of -- element 2 -# -# is translated in M3G -# -# group-Node -- Member --> element 1 -# -- Member --> element 2 -# -# In Blender every object can be the parent of every other object -# In M3G that is not possible. Only a group object can be parent. -# (Or the world object which is derived from group). -# That will come later as Parenting Part 2 -# -# * Backface Culling -# you can use backface culling, if option "use backface culloing" is on. -# Culling will be set in PolygonMode object of every mesh. The correct -# winding is controlled. -# History 0.5 -#* Bone Animation - Armature (Part 1) -# -# Armature is the skeleton for skinned meshes. It stores the bones in -# rest position (more information http://www.blender.org/cms/How_Armatures_work.634.0.html) -# You can work in Blender with bones and meshes in different ways. In -# this first attempt only the use of vertex groups is assisted. -# -# Blender-Objekts translated into M3G-Objects -# -# MESH SkinnedMesh -# | | -# v v -# ARMATURE Group -# | | -# v v -# BONE_1 Group -# Group_second -# | | -# V v -# BONE_2 Group -# Group_secound -# -# Every bone is translated into two groups at the moment, because -# the second bone is needed to do the animation in an easy way. -# -# The animations in Blender for meshes are stored in action objects. -# -# Blender Objects translated into M3G-Objects -# -# ARMATURE -# | activ -# v -# ACTION ANIMATIONCONTROLLER -# | 1..n ^ -# v ANIMATIONTRACK --> Group_second -# IPOs | -# v -# KEYSEQUENZE -# -# One action is translated into one animationcontroller. One IPO is -# translated in one KEYSEQUENZE and one ANIMATIONTRACK. -# -# At the moment only the active action of the armature object is translated. -# -#* Print Info, if type of light is used that is not supported -# -# History 0.5 -# -#* New Option exportAllAction (default value: false) -# If that option is true, all actions will be exported - not only the active -# action. -# At the moment you can only assign one action to one armature. -# To know which action is used with which armature the action -# needs a special name : -# #AE# - -# Example: Name of action : walk#A10E250#02 -# Name of armature : man#10 -# End Frame: 250 -# -# History 0.6 -# Include the same image only one time into the m3g-file -# -# All the following changes of this version was made by Claus Hoefele -# -#* Until now all vertices of the faces was been written. -# Now the vertices will be used again if possible: -# normal and texture coordinates of to vertices have to be the same -# -#* Smooth/solid shading can now be defined for every single material: -# in Editing panel (F9)>Link and Materials -# -#* This script uses now correctly the TexFace and Shadless Buttons in -# Shading panel (F5)>Material buttons>Material box. -# TexFace switches on/off the Export of texture coordinates. -# Shadeless does the some with the normal coordinates -# -#* The GUI was redesigned in a PupBlock -# -#* Options: -# -#** Texturing Enabled: Switches on/off export of textures and texture -# coordinates. Attention: the TextFace button switches only -# for one mesh -#** Texturing External: the textures will be included it mg3-file or -# exported in seperate file -#** Lighting Enabled: turns on/off export of lights and normal completly -# Attention: Shadeless only for one mesh -#** Persp. Correction: turns on/off perspective correction in PolygonMode. -#** Smooth Shading: turns on/off smooth shading in PolygonMode. -# -#* Textures in external references are used again (with ImageFactory) -# -#* Blender function: Double Sided button in Editing Context -# (F9)>Mesh panel) -# turn on/off PolygonMode.CULL_BACK anzuschalten. -# -#* Script ingnores meshes that have no faces -# -# History 0.7 -# -# * Exporter can work with texture coordinates greater 1 and smaller 0 -# -# * Adler32 did not work always correct. New implementation made. -# -# * Modul shutil is not needed any longer. Exporter has its own copy_file. -# (realized and inspired by ideasman_42 and Martin Neumann) -# -# History 0.8 -# -# * Blender works with SpotAngles 1..180 but M3G works only with 0..90 -# M3G use the 'half angle' (cut off angle) (Thanks to Martin Storsjö) -# -# * Error fixed: Texture coordinates was not calculated correct. -# (Thanks to Milan Piskla, Vlad, Max Gilead, Regis Cosnier ...) -# -# * New options in GUI: -# M3G Version 2.0 : Will export M3G files Vers. 2.0 in future -# Game Physics: Adds Game Physics infos for NOPE API -# -# --------------------------------------------------------------------------# -# TODO: Export only selected mesh -# TODO: Optimize Bones <--> Vertex Group mapping -# TODO: Compressed File -# TODO: MTex - Support -# TODO: By Rotating use SQUAD instead of Beziere. It's smoother -import Blender -from Blender import Types,Lamp,Material,Texture,Window,Registry,Draw -from Blender.BGL import * -from Blender.Object import * -from Blender.Camera import * -from Blender.Mesh import * -from array import array -import sys, struct, zlib -from inspect import * -from types import * -from Blender.Mathutils import * -from os.path import * -#import rpdb2 - -# ---- Helper Functions -------------------------------------------------------# -def copy_file(source, dest): - file = open(source, 'rb') - data = file.read() - file.close() - - file = open(dest, 'wb') - file.write(data) - file.close() - -def tracer(frame, event, arg): - '''Global trace function''' - if event=='call': - tmp = getargvalues(frame) - print event, frame.f_code.co_name, frame.f_lineno, \ - formatargvalues(tmp[0],tmp[1],tmp[2],tmp[3]) - elif event=='line': - print event, frame.f_code.co_name, frame.f_lineno - #print event, frame.f_code.co_name, frame.f_lineno, \ - # getsourcelines(frame.f_code)[frame.f_lineno] - elif event=='return': - print event, frame.f_code.co_name, frame.f_lineno, "->", arg - return tracer - -def doSearchDeep(inList,outList): - '''Does deepsearch for all elements in inList''' - for element in inList: - if element != None : outList = element.searchDeep(outList) - return outList - - -def getId(aObject): - ''' returns 0 if Object is None: M3G value for null''' - if aObject == None: return 0 - return aObject.id - -def toJavaBoolean(aValue): - ''' returns java equivalent to boolean''' - if aValue: - return 'true' - else : - return 'false' - -def sign(a): - if a<0 : return -1 - elif a>0 : return 1 - else : return 0 - -def isOrderClockWise(v,normal): - ''' returns true, if order of vertices is clockwise. Important for - culling ''' - # (v2-v0)x(v2-v1)=surface_normal - # - if type(v[0]) is Types.MVertType: - mNormal = TriangleNormal(Vector(v[0].co),Vector(v[1].co),Vector(v[2].co)) - else: - mNormal = TriangleNormal(Vector(v[0]),Vectot(v[1]),Vector(v[2])) - #print "normal ",mNormal.normalize() - #print "BNormal ",normal.normalize() - - # Do not use any longer. Blender does it correct - - result = (sign(normal.x)==sign(mNormal.x) and - sign(normal.y)==sign(mNormal.y) and - sign(normal.z)==sign(mNormal.z)) - #print "Result ",result - - return True - - -# ---- M3G Types --------------------------------------------------------------# -class M3GVertexList: - def __init__(self, wrapList): - self.mlist = wrapList - - def __getitem__(self, key): - item = self.mlist[key] - if type(item) is Types.MVertType: - result =(item.co[0],item.co[1],item.co[2]) - else: - result = item - return result - -class M3GBoneReference: - def __init__(self,first,count): - self.firstVertex=first #UInt32 - self.vertexCount=count #UInt32 - - -class M3GBone: - def __init__(self): - self.verts=[] #List of influenced verts - self.transformNode=None #ObjectIndex - self.references = [] #References to Verts that are needed - self.weight=0 #Int32 - - - def setVerts(self,aVerts): - self.verts = aVerts - self.createReferences() - - def createReferences(self): - #print "createReference::len(verts) ",len(self.verts) - if len(self.verts)==0: return #No Verts available - self.verts.sort() - ref = [] - list = [] - last = self.verts[0]-1 - count = 0 - for vert in self.verts: - #print "vert ",vert - if vert==last+1: - list.append(vert) - else: - ref.append(M3GBoneReference(list[0],len(list))) - #print list[0],len(list) - list=[vert] - last=vert - #print "list ",list - if len(list)>0: - ref.append(M3GBoneReference(list[0],len(list))) - self.references = ref - - -class M3GVector3D: - def __init__(self,ax=0.0,ay=0.0,az=0.0): - self.x = ax #Float32 - self.y = ay #Float32 - self.z = az #Float32 - - def writeJava(self): - return str(self.x)+"f, "+str(self.y)+"f, "+str(self.z)+"f" - - def getData(self): - return struct.pack("<3f",self.x,self.y,self.z) - - def getDataLength(self): - return struct.calcsize("<3f") - -class M3GMatrix: - """ A 4x4 generalized matrix. The 16 elements of the - matrix are output in the same order as they are - retrieved using the API Transform.get method. In - other words, in this order: - 0 1 2 3 - 4 5 6 7 - 8 9 10 11 - 12 13 14 15 """ - def __init__(self): - self.elements=16 * [0.0] #Float32 - - def identity(self): - self.elements[ 0] = 1.0 - self.elements[ 5] = 1.0 - self.elements[10] = 1.0 - self.elements[15] = 1.0 - - def getData(self): - return struct.pack('<16f',self.elements[0],self.elements[1], - self.elements[2],self.elements[3], - self.elements[4],self.elements[5], - self.elements[6],self.elements[7], - self.elements[8],self.elements[9], - self.elements[10],self.elements[11], - self.elements[12],self.elements[13], - self.elements[14],self.elements[15]) - - def getDataLength(self): - return struct.calcsize('<16f') - - -class M3GColorRGB: - """ A color, with no alpha information. Each compo- - nent is scaled so that 0x00 is 0.0, and 0xFF is 1.0. - """ - def __init__(self,ared=0,agreen=0,ablue=0): - self.red = ared #Byte - self.green = agreen #Byte - self.blue = ablue #Byte - - def writeJava(self): - return "0x"+("%02X%02X%02X%02X" % (0.0, self.red, self.green, self.blue)) - - def getData(self): - return struct.pack('3B',self.red,self.green,self.blue) - - def getDataLength(self): - return struct.calcsize('3B') - - -class M3GColorRGBA: - """ A color, with alpha information. Each component - is scaled so that 0x00 is 0.0, and 0xFF is 1.0. The - alpha value is scaled so that 0x00 is completely - transparent, and 0xFF is completely opaque. - """ - def __init__(self,ared=0,agreen=0,ablue=0,aalpha=0): - self.red = ared #Byte - self.green = agreen #Byte - self.blue = ablue #Byte - self.alpha = aalpha #Byte - - def writeJava(self): - return "0x"+("%02X%02X%02X%02X" % (self.alpha, self.red, self.green, self.blue)) - - def getData(self): - return struct.pack('4B',self.red,self.green,self.blue,self.alpha) - - def getDataLength(self): - return struct.calcsize('4B') - - -#ObjectIndex -#The index of a previously encountered object in -#the file. Although this is serialized as a single -#unsigned integer, it is included in the compound -#type list because of the additional semantic infor- -#mation embodied in its type. A value of 0 is -#reserved to indicate a null reference; actual object indices start from 1. Object indices must refer -#only to null or to an object which has already been -#created during the input deserialization of a file - -#they must be less than or equal to the index of the -#object in which they appear. Other values are dis- -#allowed and must be treated as errors. -#UInt32 -#index; - -# ---- M3G Proxy --------------------------------------------------------------- # -class M3GProxy: - def __init__(self): - self.name = "" - self.id=0 - self.ObjectType=0 - self.binaryFormat='' - - def __repr__(self): - return "<"+str(self.__class__)[9:] + ":" + str(self.name) + ":" + str(self.id) + ">" - - -class M3GHeaderObject(M3GProxy): - def __init__(self): - M3GProxy.__init__(self) - self.M3GHeaderObject_binaryFormat = ' 0: - value += struct.calcsize('<'+str(len(self.animationTracks))+'I') - return value - - def writeJava(self,aWriter,aCreate): - if aCreate : pass #Abstract! Could not be created - if len(self.animationTracks) > 0 : - aWriter.write(2) - for iTrack in self.animationTracks: - aWriter.write(2,"BL%i.addAnimationTrack(BL%i);" % (self.id,iTrack.id)) - - -class M3GTransformable(M3GObject3D): - def __init__(self): - M3GObject3D.__init__(self) - self.hasComponentTransform=False #Boolean - #IF hasComponentTransform==TRUE, THEN - self.translation=M3GVector3D(0,0,0) #Vector3D - self.scale=M3GVector3D(1,1,1) #Vector3D - self.orientationAngle=0 #Float32 - self.orientationAxis=M3GVector3D(0,0,0) #Vector3D undefined - #END - self.hasGeneralTransform=False #Boolean - #IF hasGeneralTransform==TRUE, THEN - self.transform = M3GMatrix() #Matrix identity - self.transform.identity() - #END - #If either hasComponentTransform or hasGeneralTransform is false, the omitted fields will be - #initialized to their default values (equivalent to an identity transform in both cases). - - def writeJava(self,aWriter,aCreate): - if aCreate: pass #Abstract Base Class! Cant't be created - M3GObject3D.writeJava(self,aWriter,False) - if self.hasGeneralTransform : - aWriter.write(2,"float[] BL%i_matrix = {" % (self.id)) - aWriter.writeList(self.transform.elements,4,"f") - aWriter.write(2,"};") - aWriter.write(2) - aWriter.write(2,"Transform BL%i_transform = new Transform();" % (self.id)) - aWriter.write(2,"BL%i_transform.set(BL%i_matrix);" % (self.id,self.id)) - aWriter.write(2,"BL%i.setTransform(BL%i_transform);" % (self.id,self.id)) - aWriter.write(2) - if self.hasComponentTransform: - aWriter.write(2,("BL%i.setTranslation("+self.translation.writeJava()+");") - %(self.id)) - - def getData(self): - data = M3GObject3D.getData(self) - data += struct.pack(" 1: - aWriter.write(2,"IndexBuffer[] BL%i_indexArray = {" % (self.id)) - aWriter.write(4,",".join(["BL%i" %(i.id) for i in self.indexBuffer ])) - aWriter.write(2," };") - aWriter.write(2) - aWriter.write(2,"Appearance[] BL%i_appearanceArray = {" % (self.id)) - aWriter.write(4,",".join(["BL%i" %(i.id) for i in self.appearance ])) - aWriter.write(2," };") - aWriter.write(2) - aWriter.write(2,"%s BL%i = new %s(BL%i,BL%i_indexArray,BL%i_appearanceArray%s);" % \ - (aClassName,self.id,aClassName,self.vertexBuffer.id, self.id,self.id,aExtension)) - else: - #print "indexBuffer", len(self.indexBuffer) - #print "appearance", len(self.appearance) - aWriter.write(2,"%s BL%i = new %s(BL%i,BL%i,BL%i%s);" % \ - (aClassName, - self.id, - aClassName, - self.vertexBuffer.id, - self.indexBuffer[0].id, - self.appearance[0].id, - aExtension)) - M3GNode.writeJava(self,aWriter,False) - aWriter.write(2) - - -class M3GSkinnedMesh(M3GMesh): - def __init__(self,aVertexBuffer=None, aIndexBuffer=[], aAppearance=[]): - M3GMesh.__init__(self,aVertexBuffer, aIndexBuffer, aAppearance) - self.ObjectType=16 - self.skeleton=None #ObjectIndex - self.bones={} - #print"M3GSkinnedMesh.__init__::self.vertexBuffer:",self.vertexBuffer - ##ObjectIndex skeleton; - ##UInt32 transformReferenceCount; - ##FOR each bone reference... - ## ObjectIndex transformNode; - ## UInt32 firstVertex; - ## UInt32 vertexCount; - ## Int32 weight; - ##END - - def searchDeep(self,alist): - alist = doSearchDeep([self.skeleton],alist) - return M3GMesh.searchDeep(self,alist) - - def addSecondBone(self): - secondBones = {} - for bone in self.bones.values(): - bone2 = M3GBone() - bone2.verts=bone.verts - bone.verts=[] - mGroup = M3GGroup() - mGroup.name=bone.transformNode.name+"_second" - bone2.transformNode=mGroup - bone2.references = bone.references - bone.references = [] - bone2.weight = bone.weight - bone.weight=0 - mGroup.children = bone.transformNode.children - bone.transformNode.children = [mGroup] - mGroup.animationTracks=bone.transformNode.animationTracks - bone.transformNode.animationTracks = [] - secondBones[bone.transformNode.name+"_second"]=bone2 - for bone in secondBones.values(): - self.bones[bone.transformNode.name] = bone - - def getBlenderIndexes(self): - #print "M3GSkinnedMesh.vertexBuffer:",self.vertexBuffer - return self.vertexBuffer.positions.blenderIndexes - - def writeJava(self,aWriter,aCreate): - self.writeBaseJava(aWriter,aCreate,"SkinnedMesh", - (",BL%i" % (self.skeleton.id))) - aWriter.write(2,"//Transforms") - for bone in self.bones.values(): - #print "bone: ", bone - #print "bone.references: ", bone.references - for ref in bone.references: - aWriter.write(2,"BL%i.addTransform(BL%i,%i,%i,%i);" % - (self.id, - bone.transformNode.id,bone.weight, - ref.firstVertex, ref.vertexCount)) - aWriter.write(2) - - def getDataLength(self): - value = M3GMesh.getDataLength(self) - value += struct.calcsize(' element[i] : minimum[i] = element[i] - if maximum[i] < element[i] : maximum[i] = element[i] - #print i, maximum[i],element[i] - lrange=[0,0,0] - maxRange=0.0 - maxDimension=-1 - for i in range(3): #set bias - lrange[i] = maximum[i]-minimum[i] - self.bias[i] = minimum[i]*0.5+maximum[i]*0.5 - #print "Bias",i,self.bias[i],"min-max",minimum[i],maximum[i],"lrang",lrange[i] - if lrange[i] > maxRange: - maxRange = lrange[i] - maxDimension=i - self.scale = maxRange/65533.0 - #print "MaxRange ",maxRange - #print "scale",self.scale - - - def internalAutoScaling(self): - print "internalAutoScaling" - #Already done? - print self.components.typecode - if not self.autoscaling or self.components.typecode!="f":return - #Find bais and scale - minimum=[] - maximum=[] - for i in range(self.componentCount): - minimum.append(self.components[i]) - maximum.append(self.components[i]) - for i in range(0,len(self.components),self.componentCount): - for j in range(self.componentCount): - if minimum[j] > self.components[i+j] : minimum[j] = self.components[i+j] - if maximum[j] < self.components[i+j] : maximum[j] = self.components[i+j] - #print "i+j=",i+j,"min=",minimum[j],"max=",maximum[j],"elem=",self.components[i+j] - #print "min=", minimum - #print "max=", maximum - lrange=[0] * self.componentCount - maxRange=0.0 - maxDimension=-1 - for i in range(self.componentCount): #set bias - lrange[i] = maximum[i]-minimum[i] - self.bias[i] = minimum[i]*0.5+maximum[i]*0.5 - #print "Bias",i,self.bias[i],"min-max",minimum[i],maximum[i],"lrang",lrange[i] - if lrange[i] > maxRange: - maxRange = lrange[i] - maxDimension=i - maxValue=(2**(8*self.componentSize)*1.0)-2.0 - #print "MaxValue=",maxValue - self.scale = maxRange/maxValue - #print "MaxRange ",maxRange - #print "scale",self.scale - #Copy Components - oldArray=self.components - self.components=self.createComponentArray() - for i in range(0,len(oldArray),self.componentCount): - for j in range(self.componentCount): - element=int((oldArray[i+j]-self.bias[j])/self.scale) - #print "element",element - self.components.append(element) - # Reverse t coordinate because M3G uses a different 2D coordinate system than Blender. - if self.uvmapping: - for i in range(0,len(self.components),2): - self.components[i+1]= int(self.components[i+1]*(-1)) #Error in Version 0.7 - for i in range(len(self.components)): - if abs(self.components[i])>maxValue:raise Exception( i+". element too great/small!") - - def writeJava(self,aWriter,aCreate): - self.internalAutoScaling() - if aCreate: - aWriter.write(2,"// VertexArray " + self.name) - if self.componentSize == 1: - aWriter.write(2,"byte[] BL%i_array = {" % (self.id)) - else: - aWriter.write(2,"short[] BL%i_array = {" % (self.id)) - aWriter.writeList(self.components) - aWriter.write(2,"};") - aWriter.write(2) - aWriter.write(2,"VertexArray BL%i = new VertexArray(BL%i_array.length/%i,%i,%i);" % - (self.id,self.id, - self.componentCount,self.componentCount,self.componentSize)) - aWriter.write(2,"BL%i.set(0,BL%i_array.length/%i,BL%i_array);" % - (self.id,self.id,self.componentCount,self.id)) - M3GObject3D.writeJava(self,aWriter,False) - aWriter.write(2) - - - def getData(self): - self.internalAutoScaling() - self.vertexCount = len(self.components)/self.componentCount - data = M3GObject3D.getData(self) - data += struct.pack('<3BH',self.componentSize, - self.componentCount, - self.encoding, - self.vertexCount) - componentType = "" - if self.componentSize == 1: - componentType = "b" - else: - componentType = "h" - for element in self.components: - data += struct.pack('<'+componentType,element) - return data - - def getDataLength(self): - self.internalAutoScaling() - value = M3GObject3D.getDataLength(self) - value += struct.calcsize('<3BH') - componentType = "" - if self.componentSize == 1: - componentType = "b" - else: - componentType = "h" - value += struct.calcsize('<'+str(len(self.components))+componentType) - return value - - def append(self,element,index=None): - #print "type(element):",type(element) - if type(element) is Types.vectorType : - for i in range(3): - value = int((element[i]-self.bias[i])/self.scale) - #print "append:",i,element[i],(element[i]-self.bias[i]),value - self.components.append(value) - elif type(element) is Types.MVertType: - for i in range(3): - value = int((element.co[i]-self.bias[i])/self.scale) - #print "append:",i,element[i],(element[i]-self.bias[i]),value - self.components.append(value) - if index!=None: - key=str(len(self.blenderIndexes)) - #print"key,index:",key,index - self.blenderIndexes[key]=index - #print"blenderIndexes",self.blenderIndexes - else: - print "VertexArray.append: element=",element - self.components.append(element) - -class M3GVertexBuffer(M3GObject3D): - def __init__(self): - M3GObject3D.__init__(self) - self.ObjectType=21 - self.defaultColor=M3GColorRGBA(255,255,255) #ColorRGBA 0xFFFFFFFF (opaque white). - self.positions = None #ObjectIndex - self.positionBias = [0.0,0.0,0.0] #Float32[3] - self.positionScale = 1.0 #Float32 - self.normals = None #ObjectIndex - self.colors = None #ObjectIndex - self.texCoordArrays = [] - self.texcoordArrayCount = 0 #UInt32 -## #FOR each texture coordinate array... -## self.texCoords = [] #ObjectIndex -## self.texCoordBias=[] #Float32[3] -## self.texCoordScale=[] #;Float32 -## #END -## #If a texture coordinate array has only two components, the corresponding texCoordBias[2] element -## #must be 0.0. -## #Null texture coordinate arrays are never serialized, regardless of their position. A single texture -## #coordinate array will therefore always be serialized as belonging to texturing unit 0, regardless of -## #its original unit it was assigned to. -## #There are as many references in the texture coordinates array as there are active texture units for -## #this geometry. The texture coordinate references are loaded sequentially from texture unit 0. If the -## #implementation supports more texture units than are specified, these are left in their default, inactive -## #state, with a null texture coordinate reference and an undefined bias and scale. -## #If more texture coordinate references are specified than are supported by the implementation, then -## #this must be treated as an error, as it would be in the API. The application can then decide on an -## #appropriate course of action to handle this case. - - def searchDeep(self,alist): - if self.positions!=None: alist = self.positions.searchDeep(alist) - if self.normals != None: alist = self.normals.searchDeep(alist) - if self.colors!= None: alist = self.colors.searchDeep(alist) - alist = doSearchDeep(self.texCoordArrays, alist) - return M3GObject3D.searchDeep(self,alist) - - def setPositions(self,aVertexArray): - self.positions = aVertexArray - self.positionBias = aVertexArray.bias - self.positionScale = aVertexArray.scale - - def writeJava(self,aWriter,aCreate): - if aCreate: - aWriter.write(2,"//VertexBuffer"+self.name ) - aWriter.write(2,"VertexBuffer BL%i = new VertexBuffer();" % (self.id)) - aWriter.write(2,"float BL%i_Bias[] = { %ff, %ff, %ff};" % - (self.id,self.positionBias[0], - self.positionBias[1],self.positionBias[2])) - aWriter.write(2,"BL%i.setPositions(BL%i,%ff,BL%i_Bias);" % - (self.id, self.positions.id, - self.positionScale,self.id)) - aWriter.write(2,"BL%i.setNormals(BL%i);" % (self.id,self.normals.id)) - #if self.colors != None: aWriter.write(2,"BL%i.setTexCoords(0,BL%i,1.0f,null);" % - # (self.id,self.colors.id)) - lIndex = 0 - for iTexCoord in self.texCoordArrays: - aWriter.write(2,"float BL%i_%i_TexBias[] = { %ff, %ff, %ff};" % - (self.id,lIndex, iTexCoord.bias[0], - iTexCoord.bias[1],iTexCoord.bias[2])) - #int index, javax.microedition.m3g.VertexArray194 texCoords, float scale, float[] bias - aWriter.write(2,"BL%i.setTexCoords(%i,BL%i,%ff,BL%i_%i_TexBias);" % - (self.id, lIndex, iTexCoord.id, iTexCoord.scale,self.id,lIndex)) - lIndex += 1 - - M3GObject3D.writeJava(self,aWriter,False) - - - def getData(self): - self.texcoordArrayCount = len(self.texCoordArrays) - data = M3GObject3D.getData(self) - data += self.defaultColor.getData() - data += struct.pack(' 0 : - value += struct.calcsize('<' + str(len(self.indices)) + 'I') - value += struct.calcsize(' 0: - value+= struct.calcsize('<'+str(len(self.stripLengths))+'I') - return value - - -class M3GAppearance(M3GObject3D): - def __init__(self): - M3GObject3D.__init__(self) - self.ObjectType=3 - self.layer=0 #Byte - self.compositingMode=None #ObjectIndex - self.fog=None #ObjectIndex - self.polygonMode=None #ObjectIndex - self.material=None #ObjectIndex - self.textures=[] #;ObjectIndex[] - - def searchDeep(self,alist): - alist = doSearchDeep([self.compositingMode,self.fog, - self.polygonMode,self.material] - + self.textures,alist) - return M3GObject3D.searchDeep(self,alist) - - def getData(self): - data = M3GObject3D.getData(self) - data += struct.pack(" 0 : - value += struct.calcsize("<"+str(len(self.textures))+'I') - return value - - - def writeJava(self,aWriter,aCreate): - if aCreate: - aWriter.write(2,"//Appearance") - aWriter.write(2,"Appearance BL%i = new Appearance();" % (self.id)) - if self.compositingMode!= None: - aWriter.write(2,"BL%i.setPolygonMode(BL%i);" % - (self.id,self.compositingMode.id)) - if self.fog!=None: - aWriter.write(2,"BL%i.setFog(BL%i);" % - (self.id,self.fog.id)) - if self.polygonMode!=None: - aWriter.write(2,"BL%i.setPolygonMode(BL%i);" % - (self.id,self.polygonMode.id)) - if self.material!=None: - aWriter.write(2,"BL%i.setMaterial(BL%i);" % - (self.id,self.material.id)) - i=0 - for itexture in self.textures: - aWriter.write(2,"BL%i.setTexture(%i,BL%i);" % - (self.id,i,itexture.id)) - i =+ 1 - M3GObject3D.writeJava(self,aWriter,False) - aWriter.write(2) - -class M3GTexture2D(M3GTransformable): - #M3G imposes the following restrictions when assigning textures to a model: - #The dimensions must be powers of two (4, 8, 16, 32, 64, 128...). - - WRAP_REPEAT = 241 - WRAP_CLAMP = 240 - FILTER_BASE_LEVEL=208 - FILTER_LINEAR=209 - FILTER_NEAREST=210 - FUNC_ADD=224 - FUNC_BLEND=225 - FUNC_DECAL=226 - FUNC_MODULATE=227 - FUNC_REPLACE=228 - - def __init__(self,aImage): - M3GTransformable.__init__(self) - self.ObjectType=17 - self.Image = aImage #ObjectIndex - self.blendColor=M3GColorRGB(0,0,0) - self.blending=M3GTexture2D.FUNC_MODULATE #Byte - self.wrappingS=M3GTexture2D.WRAP_REPEAT #Byte - self.wrappingT=M3GTexture2D.WRAP_REPEAT #Byte - self.levelFilter=M3GTexture2D.FILTER_BASE_LEVEL #Byte - self.imageFilter=M3GTexture2D.FILTER_NEAREST #Byte - - def searchDeep(self,alist): - alist = doSearchDeep([self.Image],alist) - return M3GTransformable.searchDeep(self,alist) - - def getData(self): - data = M3GTransformable.getData(self) - data += struct.pack('#AE# - lError = "Armature name " + name + " is not ok. Perhaps you should set option 'ExportAllAction' to false." - #print "name ", name - lLetter = name.find("#") - if lLetter == -1 :raise Exception(lError) - if name[lLetter+1]!='A': raise Exception(lError) - lName = name[lLetter+2:] - #print "lName ", lName - lLetter = lName.find("E") - #print "lLetter ", lLetter - if lLetter == -1 :raise Exception(lError) - #print "lName[:]", lName[:0] - lArmatureID = int(lName[:lLetter]) - lName = lName[lLetter+1:] - lLetter = lName.find("#") - if lLetter == -1:raise Exception(lError) - lEndFrame = int(lName[:lLetter]) - lActionID = int(lName[lLetter+1:]) - return (lArmatureID,lEndFrame,lActionID) - - - def translateWorld(self,scene): - "creates world object" - world = M3GWorld() - - #Background - world.background = M3GBackground() - blWorld= scene.world - #AllWorlds = Blender.World.Get() # Set Color - #if len(AllWorlds)>=1: # world object available - if blWorld != None: - world.background.backgroundColor=self.translateRGBA(blWorld.getHor(),0) # horizon color of the first world - if mOptions.createAmbientLight & mOptions.lightingEnabled: - lLight = M3GLight() - lLight.mode = lLight.modes['AMBIENT'] - lLight.color = self.translateRGB(blWorld.getAmb()) - self.nodes.append(lLight) - - #TODO: Set background picture from world - - return world - - def translateEmpty(self,obj): - print "translate empty ..." - mGroup = M3GGroup() - self.translateToNode(obj,mGroup) - - def translateCamera(self,obj): - print "translate camera ..." - camera = obj.getData() - if camera.getType()!=0: - print "Only perscpectiv cameras will work korrekt" - return #Type=0 'perspectiv' Camera will be translated - mCamera = M3GCamera() - mCamera.projectionType=mCamera.PERSPECTIVE - mCamera.fovy=60.0 # TODO: Calculate fovy from Blender.lens - mCamera.AspectRatio=4.0/3.0 # TODO: different in every device - mCamera.near=camera.getClipStart() - mCamera.far=camera.getClipEnd() - self.translateToNode(obj,mCamera) - self.world.activeCamera = mCamera # Last one is always the active one - - - def translateMaterials(self, aMaterial, aMesh, aMatIndex, createNormals, createUvs): - print "translate materials ..." - - mAppearance = M3GAppearance() - - if createNormals: - mMaterial = M3GMaterial() - mMaterial.name = aMaterial.name - mMaterial.diffuseColor = self.translateRGBA(aMaterial.rgbCol,1.0) #ColorRGBA - #material.specularColor= self.translateRGB(mat.specCol) #ColorRGB - mAppearance.material = mMaterial - - if createUvs: - # Search file name in mesh face. - lImage = None - for iface in aMesh.faces: - if iface.mat==aMatIndex: - if iface.image != None: - lImage = iface.image - break - if lImage==None: - raise Exception("Mesh " + aMesh.name + ": No image found for uv-texture! Perhaps no uv-coordinates ?") - - # M3G requires textures to have power-of-two dimensions. - [width, height] = lImage.getSize() - powerWidth = 1 - while (powerWidth < width): - powerWidth *= 2 - powerHeight = 1 - while (powerHeight < height): - powerHeight *= 2 - if powerWidth != width or powerHeight != height: - raise Exception("Image " + lImage.filename + ": width and height must be power-of-two!") - - # ImageFactory reuses existing images. - mImage = ImageFactory.getImage(lImage, mOptions.textureExternal) - mTexture = M3GTexture2D(mImage) - mAppearance.textures.append(mTexture) - - mPolygonMode=M3GPolygonMode() - mPolygonMode.perspectiveCorrectionEnabled = mOptions.perspectiveCorrection - if not aMesh.mode & Modes.TWOSIDED: - mPolygonMode.culling=M3GPolygonMode.CULL_BACK - else: - mPolygonMode.culling=M3GPolygonMode.CULL_NONE - if mOptions.smoothShading: - mPolygonMode.shading=M3GPolygonMode.SHADE_SMOOTH - else: - mPolygonMode.shading=M3GPolygonMode.SHADE_FLAT - - mAppearance.polygonMode = mPolygonMode - - return mAppearance - - - def translateMesh(self,obj): - print "translate mesh ..." + str(obj) - - # Mesh data. - mesh = obj.getData(False, True) # get Mesh not NMesh object - if len(mesh.faces) <= 0: # no need to process empty meshes - print "Empty mesh " + str(obj) + " not processed." - return - - vertexBuffer = M3GVertexBuffer() - positions = M3GVertexArray(3, 2) # 3 coordinates - 2 bytes - if mOptions.autoscaling: positions.useMaxPrecision(mesh.verts) - indexBuffers = [] - appearances = [] - print str(len(mesh.materials)) + " material(s) found." - - # Texture coordinates. - createUvs = False - if mOptions.textureEnabled & mesh.faceUV: - for material in mesh.materials: - if material.getMode() & Material.Modes.TEXFACE: createUvs = True; - - if createUvs: - if mOptions.autoscaling: - uvCoordinates = M3GVertexArray(2,2,True,True) #2 coordinates - 2 bytes - autoscaling - else: - uvCoordinates = M3GVertexArray(2, 2) #2 coordinates - 2 bytes - uvCoordinates.bias[0] = 0.5 - uvCoordinates.bias[1] = 0.5 - uvCoordinates.bias[2] = 0.5 - uvCoordinates.scale = 1.0/65535.0 - else: - uvCoordinates = None - - # Normals. - createNormals = False - if mOptions.lightingEnabled: - for material in mesh.materials: - if not (material.getMode() & Material.Modes.SHADELESS): createNormals = True; - - if createNormals: - normals = M3GVertexArray(3, 1) # 3 coordinates - 1 byte - else: - normals = None - - # Create a submesh for each material. - for materialIndex, material in enumerate(mesh.materials): - faces = [face for face in mesh.faces if face.mat == materialIndex] - if len(faces) >= 0: - indexBuffers.append(self.translateFaces(faces, positions, normals, uvCoordinates, createNormals, createUvs)) - appearances.append(self.translateMaterials(material, mesh, materialIndex, createNormals, createUvs)) - - # If the above didn't result in any IndexBuffer (e.g. there's no material), write a single IndexBuffer - # with all faces and a default Appearance. - if len(indexBuffers) == 0: - indexBuffers.append(self.translateFaces(mesh.faces, positions, normals, uvCoordinates, createNormals, createUvs)) - appearances.append(M3GAppearance()) - - vertexBuffer.setPositions(positions) - if createNormals: vertexBuffer.normals = normals - if createUvs: vertexBuffer.texCoordArrays.append(uvCoordinates) - - parent = obj.getParent() - if parent!=None and parent.getType()=='Armature': #Armatures ? - mMesh = M3GSkinnedMesh(vertexBuffer,indexBuffers,appearances) - #print"vertexBuffer.positions:",vertexBuffer.positions - print"mMesh.vertexBuffer:",mMesh.vertexBuffer - self.translateArmature(parent,obj,mMesh) - else: - mMesh = M3GMesh(vertexBuffer,indexBuffers,appearances) - - self.translateToNode(obj,mMesh) - - #Do Animation - self.translateObjectIpo(obj,mMesh) - - def translateFaces(self, faces, positions, normals, uvCoordinates, createNormals, createUvs): - """Translates a list of faces into vertex data and triangle strips.""" - - # Create vertices and triangle strips. - indices = [0, 0, 0, 0] - triangleStrips = M3GTriangleStripArray() - - for face in faces: - for vertexIndex, vertex in enumerate(face.verts): - # Find candidates for sharing (vertices with same Blender ID). - vertexCandidateIds = [int(k) for k, v in positions.blenderIndexes.items() if v == vertex.index] - - # Check normal. - if createNormals and not face.smooth: - # For solid faces, a vertex can only be shared if the the face normal is - # the same as the normal of the shared vertex. - for candidateId in vertexCandidateIds[:]: - for j in range(3): - if face.no[j]*127 != normals.components[candidateId*3 + j]: - vertexCandidateIds.remove(candidateId) - break - - # Check texture coordinates. - if createUvs: - # If texture coordinates are required, a vertex can only be shared if the - # texture coordinates match. - for candidateId in vertexCandidateIds[:]: - s = int((face.uv[vertexIndex][0]-0.5)*65535) - t = int((0.5-face.uv[vertexIndex][1])*65535) - if (s != uvCoordinates.components[candidateId*2 + 0]) or (t != uvCoordinates.components[candidateId*2 + 1]): - vertexCandidateIds.remove(candidateId) - - if len(vertexCandidateIds) > 0: - # Share the vertex. - indices[vertexIndex] = vertexCandidateIds[0] - else: - # Create new vertex. - positions.append(vertex, vertex.index) - indices[vertexIndex] = len(positions.components)/3 - 1 - - # Normal. - if createNormals: - for j in range(3): - if face.smooth: - normals.append(int(vertex.no[j]*127)) # vertex normal - else: - normals.append(int(face.no[j]*127)) # face normal - - # Texture coordinates. - if createUvs: - lUvCoordinatesFound = True - print "face.uv[vertexIndex][0]:",face.uv[vertexIndex][0] - print "face.uv[vertexIndex][1]:",face.uv[vertexIndex][1] - if mOptions.autoscaling: - uvCoordinates.append(face.uv[vertexIndex][0]) - uvCoordinates.append(face.uv[vertexIndex][1]) - else: - uvCoordinates.append(int((face.uv[vertexIndex][0]-0.5)*65535)) - # Reverse t coordinate because M3G uses a different 2D coordinate system than Blender. - uvCoordinates.append(int((0.5-face.uv[vertexIndex][1])*65535)) - - # IndexBuffer. - triangleStrips.stripLengths.append(len(face.verts)) - if len(face.verts) > 3 : - triangleStrips.indices += [indices[1], indices[2], indices[0], indices[3]] # quad - else : - triangleStrips.indices += [indices[0], indices[1], indices[2]] # tri - - return triangleStrips - - - def translateObjectIpo(self,obj,aM3GObject): - if obj.getIpo() == None : return #No Ipo available - print "translate Ipo ..." - - lIpo = obj.getIpo() - self.translateIpo(lIpo,aM3GObject) - - - def translateIpo(self,aIpo,aM3GObject,aM3GAnimContr=None,aEndFrame=0): - #Print info about curves - #for iCurve in lIpo.getCurves(): - # print "Extrapolation",iCurve.getExtrapolation() #Constant, Extrapolation, Cyclic or Cyclic_extrapolation - # print "Interpolation",iCurve.getInterpolation() #Constant, Bezier, or Linear - # print "Name",iCurve.getName() - # for iPoint in iCurve.getPoints(): - # print "Knode points",iPoint.getPoints() - types = ['Loc','Rot','Size','Quat'] - - for type in types: - if aIpo.getCurve(type+'X'): - self.translateIpoCurve(aIpo,aM3GObject,type,aM3GAnimContr,aEndFrame) - - - def translateIpoCurve(self,aIpo,aM3GObject,aCurveType,aM3GAnimContr,aEndFrame=0): - - lContext = self.scene.getRenderingContext() - if aEndFrame==0: - lEndFrame = lContext.endFrame() - else: - lEndFrame = aEndFrame - - lTimePerFrame = 1.0 / lContext.framesPerSec() * 1000 - - lCurveX = aIpo.getCurve(aCurveType+'X') - lCurveY = aIpo.getCurve(aCurveType+'Y') - lCurveZ = aIpo.getCurve(aCurveType+'Z') - if aCurveType=='Quat': lCurveW = aIpo.getCurve(aCurveType+'W') - - lInterpolation = None - if aCurveType == 'Rot' or aCurveType == 'Quat': - lTrackType = M3GAnimationTrack.ORIENTATION - lNumComponents=4 - lCurveFactor= 10 #45 Degrees = 4,5 - if aCurveType == 'Quat': - lTrackType = M3GAnimationTrack.ORIENTATION - lNumComponents=4 - lCurveFactor= 1 - lInterpolation = M3GKeyframeSequence.SLERP - #lInterpolation = M3GKeyframeSequence.SQUAD - elif aCurveType == 'Size': - lTrackType = M3GAnimationTrack.SCALE - lNumComponents=3 - lCurveFactor=1 - else: - lTrackType = M3GAnimationTrack.TRANSLATION - lNumComponents=3 - lCurveFactor=1 - - mSequence = M3GKeyframeSequence(len(lCurveX.getPoints()), - lNumComponents, - lCurveX.getInterpolation(), - lInterpolation) - - #print 'ComponentCount',mSequence.componentCount - - mSequence.duration = lEndFrame * lTimePerFrame - mSequence.setRepeatMode(lCurveX.getExtrapolation()) - - lIndex = 0 - for iPoint in lCurveX.getPoints(): - lPoint = iPoint.getPoints() - - lPointList = [(lPoint[1]*lCurveFactor), - (lCurveY.evaluate(lPoint[0])*lCurveFactor), - (lCurveZ.evaluate(lPoint[0])*lCurveFactor)] - - #print "aCurveType ", aCurveType - - if aCurveType == 'Loc': - #print "PointList ", lPointList - #lorgTransVector = aM3GObject.blenderTransformMatrix.translationPart() - #ltrans = TranslationMatrix(Vector(lPointList)) - #ltrans2 = self.calculateChildMatrix(ltrans,aM3GObject.blenderTransformMatrix) - #lVector = ltrans2.translationPart() + lorgTransVector - #lPointList = [lVector.x, lVector.y,lVector.z] - #print "PointList ", lPointList - pass - - if aCurveType == 'Quat': - lPointList.append(lCurveW.evaluate(lPoint[0])*lCurveFactor) - #lQuat = Quaternion([lPointList[3],lPointList[0],lPointList[1],lPointList[2]]) - #print "Quat ", lQuat - #print "Quat.angel ", lQuat.angle - #print "Quat.axis ", lQuat.axis - #print "PointList ", lPointList - - #print "PointList",lPointList - - if aCurveType =='Rot': - lQuat = Euler(lPointList).toQuat() - #lPointList = [lQuat.w,lQuat.x,lQuat.y,lQuat.z] - lPointList = [lQuat.x,lQuat.y,lQuat.z,lQuat.w] - #print " Quat=", lPointList - - mSequence.setKeyframe(lIndex, - lPoint[0]*lTimePerFrame, - lPointList) - lIndex += 1 - mSequence.validRangeFirst = 0 - mSequence.validRangeLast = lIndex - 1 - - mTrack = M3GAnimationTrack(mSequence,lTrackType) - aM3GObject.animationTracks.append(mTrack) - if aM3GAnimContr==None: aM3GAnimContr = M3GAnimationController() - mTrack.animationController = aM3GAnimContr - - - def translateLamp(self,obj): - print "translate lamp ..." - lamp = obj.getData() - - #Type - lampType=lamp.getType() - if not lampType in [Lamp.Types.Lamp,Lamp.Types.Spot,Lamp.Types.Sun]: - print "INFO: Type of light is not supported. See documentation" - return #create not light; type not supported - mLight = M3GLight() - if lampType == Lamp.Types.Lamp: - mLight.mode = mLight.modes['OMNI'] - elif lampType == Lamp.Types.Spot: - mLight.mode = mLight.modes['SPOT'] - elif lampType == Lamp.Types.Sun: - mLight.mode = mLight.modes['DIRECTIONAL'] - #Attenuation (OMNI,SPOT): - if lampType in [Lamp.Types.Lamp,Lamp.Types.Spot]: - mLight.attenuationConstant = 0.0 - mLight.attenuationLinear = 2.0/lamp.dist - mLight.attenuationQuadratic = 0.0 - #Color - mLight.color = self.translateRGB(lamp.col) - #Energy - mLight.intensity = lamp.energy - #SpotAngle, SpotExponent (SPOT) - if lampType == Lamp.Types.Spot: - mLight.spotAngle = lamp.spotSize/2 - mLight.spotExponent = lamp.spotBlend - self.translateToNode(obj,mLight) - - - def translateCore(self,obj,node): - #Name - node.name = obj.name - node.userID = self.translateUserID(obj.name) - #Location - #node.translation=self.translateLoc(obj.LocX,obj.LocY,obj.LocZ - #node.hasComponentTransform=True - #Transform - #node.transform = self.translateMatrix(obj.getMatrix('localspace')) - if type(obj) is Types.BoneType: - #print "BoneMatrix ",obj.matrix['BONESPACE'] - node.transform = self.translateMatrix(obj.matrix['ARMATURESPACE']) - #'ARMATURESPACE' - this matrix of the bone in relation to the armature - #'BONESPACE' - the matrix of the bone in relation to itself - else: - node.transform = self.translateMatrix(obj.matrixWorld) - node.hasGeneralTransform=True - - - def translateToNode(self,obj,node): - self.translateCore(obj,node) - #Nodes - self.nodes.append(node) - #Link to Blender Object - node.blenderObj = obj - node.blenderMatrixWorld = obj.matrixWorld - lparent = None - if obj.getParent()!=None: - if obj.getParent().getType()!='Armature': - lparent = obj.getParent() - else: - if obj.getParent().getParent()!=None and obj.getParent().getParent().getType()!='Armature': - lparent = obj.getParent().getParent() - node.parentBlenderObj = lparent - - - def translateUserID(self, name): - id = 0 - start = name.find('#') - - # Use digits that follow the # sign for id. - if start != -1: - start += 1 - end = start - for char in name[start:]: - if char.isdigit(): - end += 1 - else: - break - - if end > start: - id = int(name[start:end]) - - return id - - def translateLoc(self,aLocX,aLocY,aLocZ): - return M3GVector3D(aLocX,aLocY,aLocZ) - - def translateRGB(self,color): - return M3GColorRGB(int(color[0]*255), - int(color[1]*255), - int(color[2]*255)) - - def translateRGBA(self,color,alpha): - return M3GColorRGBA(int(color[0]*255), - int(color[1]*255), - int(color[2]*255), - int(alpha*255)) - - def translateMatrix(self,aPyMatrix): - """ -  0   1   2   3  - 4   5   6   7  - 8   9  10  11 - 12  13  14  15 """ - #print "Matrix:", aPyMatrix - lMatrix = M3GMatrix() - lMatrix.elements[0] = aPyMatrix[0][0] - lMatrix.elements[1] = aPyMatrix[1][0] - lMatrix.elements[2] = aPyMatrix[2][0] - lMatrix.elements[3] = aPyMatrix[3][0] - lMatrix.elements[4] = aPyMatrix[0][1] - lMatrix.elements[5] = aPyMatrix[1][1] - lMatrix.elements[6] = aPyMatrix[2][1] - lMatrix.elements[7] = aPyMatrix[3][1] - lMatrix.elements[8] = aPyMatrix[0][2] - lMatrix.elements[9] = aPyMatrix[1][2] - lMatrix.elements[10] = aPyMatrix[2][2] - lMatrix.elements[11] = aPyMatrix[3][2] - lMatrix.elements[12] = aPyMatrix[0][3] - lMatrix.elements[13] = aPyMatrix[1][3] - lMatrix.elements[14] = aPyMatrix[2][3] - lMatrix.elements[15] = aPyMatrix[3][3] - return lMatrix - - -# ---- Exporter ---------------------------------------------------------------- # - -class M3GExporter: - "Exports Blender-Scene to M3D" - def __init__(self, aWriter): - self.writer = aWriter - - - def start(self): - print "Info: starting export ..." - #rpdb2.start_embedded_debugger("t",True) - Translator = M3GTranslator() - world = Translator.start() - - #sys.settrace(tracer) - exportList = self.createDeepSearchList(world) - externalReferences = [element for element in exportList if element.__class__ is M3GExternalReference] - exportList = [element for element in exportList if element.__class__ is not M3GExternalReference] - #sys.settrace(None) - - # 1 is reservated for HeaderObject. - i=1 - - # Next are the external references. - for element in externalReferences: - i += 1 - element.id = i - print "object ",element.id, element - - # And the standard scene objects. - for element in exportList: - i += 1 - element.id = i - print "object ",element.id, element - - self.writer.writeFile(world, exportList, externalReferences) - - print("Ready!") - - - def createDeepSearchList(self,aWorld): - "creates the right order for saving m3g : leafs first" - return aWorld.searchDeep([]) - - - -# ---- Writer ---------------------------------------------------------------- # -class JavaWriter: - "writes a java class which creates m3g-Scene in a j2me programm" - def __init__(self,aFilename): - self.filename = aFilename - self.classname = Blender.sys.basename(aFilename) - self.classname = self.classname[:-5] #without extention ".java" - self.outFile = file(aFilename,"w") - - def write(self, tab, zeile=""): - "writes to file" - #print "\t" * tab + zeile - print >>self.outFile, "\t" * tab + zeile - - def writeFile(self,aWorld,aExportList,externalReferences): - self.world = aWorld - self.writeHeader() - for element in aExportList: - element.writeJava(self,True) - self.writeFooter() - self.outFile.close() - - def writeHeader(self): - "writes class header" - self.write(0,"import javax.microedition.lcdui.Image;") - self.write(0,"import javax.microedition.m3g.*;") - self.write(0,"public final class "+self.classname+" {") - self.write(1,"public static World getRoot(Canvas3D aCanvas) {") - - def writeFooter(self): - self.write(1) - self.write(1,"return BL"+str(self.world.id)+";") - self.write(0,"}}") - - def writeList(self,alist,numberOfElementsPerLine=12,aType=""): - '''Writes numberOfElementsPerLine''' - line="" - lastLine="" - counter=0 - for element in alist: - if counter!=0: - line = line + "," + str(element) + aType - else: - line = str(element) + aType - counter = counter + 1 - if counter == numberOfElementsPerLine: - if len(lastLine)>0: - self.write(3,lastLine+",") - lastLine=line - line="" - counter = 0 - if len(lastLine)>0: - if len(line)>0: - self.write(3,lastLine+",") - else: - self.write(3,lastLine) - if len(line) > 0: self.write(3,line) - - def writeClass(self,aName,aM3GObject): - self.write(2) - self.write(2,"//"+aName+":"+aM3GObject.name) - - -class M3GSectionObject: - def __init__(self,aObject): - """Object Structure - Each object in the file represents one object in the - scene graph tree, and is stored in a chunk. The - structure of an object chunk is as follows: - Byte ObjectType - UInt32 Length - Byte[] Data""" - #ObjectType - #This field describes what type of object has been serialized. - #The values 0 and 0xFF are special: 0 represents the header object, - #and 0xFF represents an external reference. - #Example: Byte ObjectType = 14 - self.ObjectType = aObject.ObjectType - self.data = aObject.getData() - self.length = aObject.getDataLength() - - def getData(self): - data = struct.pack(' 2,1,0 - for v in f.v[2::-1]: - file.write(format_vec % tuple(v.co) ) - - try: mode= f.mode - except: mode= 0 - - if mode & Mesh.FaceModes.INVISIBLE: - file.write(PREF_INVIS_TEX.val) - else: - try: image= f.image - except: image= None - - if image: file.write(sys.splitext(sys.basename(image.filename))[0]) - else: file.write(PREF_NULL_TEX.val) - - # Texture stuff ignored for now - file.write(PREF_DEF_TEX_OPTS.val) - file.write('}\n') - - -def round_vec(v): - if PREF_GRID_SNAP.val: - return round(v.x), round(v.y), round(v.z) - else: - return tuple(v) - -def write_face2brush(file, face): - ''' - takes a face and writes it as a brush - each face is a cube/brush - ''' - - if PREF_GRID_SNAP.val: format_vec= '( %d %d %d ) ' - else: format_vec= '( %.8f %.8f %.8f ) ' - - - image_text= PREF_NULL_TEX.val - - try: mode= face.mode - except: mode= 0 - - if mode & Mesh.FaceModes.INVISIBLE: - image_text= PREF_INVIS_TEX.val - else: - try: image= face.image - except: image= None - if image: image_text = sys.splitext(sys.basename(image.filename))[0] - - # original verts as tuples for writing - orig_vco= [tuple(v.co) for v in face] - - # new verts that give the face a thickness - dist= PREF_SCALE.val * PREF_FACE_THICK.val - new_vco= [round_vec(v.co - (v.no * dist)) for v in face] - #new_vco= [round_vec(v.co - (face.no * dist)) for v in face] - - file.write('// brush from face\n{\n') - # front - for co in orig_vco[2::-1]: - file.write(format_vec % co ) - file.write(image_text) - # Texture stuff ignored for now - file.write(PREF_DEF_TEX_OPTS.val) - - - for co in new_vco[:3]: - file.write(format_vec % co ) - if mode & Mesh.FaceModes.TWOSIDE: - file.write(image_text) - else: - file.write(PREF_INVIS_TEX.val) - - # Texture stuff ignored for now - file.write(PREF_DEF_TEX_OPTS.val) - - # sides. - if len(orig_vco)==3: # Tri, it seemms tri brushes are supported. - index_pairs= ((0,1), (1,2), (2,0)) - else: - index_pairs= ((0,1), (1,2), (2,3), (3,0)) - - for i1, i2 in index_pairs: - for co in orig_vco[i1], orig_vco[i2], new_vco[i2]: - file.write( format_vec % co ) - file.write(PREF_INVIS_TEX.val) - file.write(PREF_DEF_TEX_OPTS.val) - - file.write('}\n') - -def is_cube_facegroup(faces): - ''' - Returens a bool, true if the faces make up a cube - ''' - # cube must have 6 faces - if len(faces) != 6: - print '1' - return False - - # Check for quads and that there are 6 unique verts - verts= {} - for f in faces: - if len(f)!= 4: - return False - - for v in f: - verts[v.index]= 0 - - if len(verts) != 8: - return False - - # Now check that each vert has 3 face users - for f in faces: - for v in f: - verts[v.index] += 1 - - for v in verts.itervalues(): - if v != 3: # vert has 3 users? - return False - - # Could we check for 12 unique edges??, probably not needed. - return True - -def is_tricyl_facegroup(faces): - ''' - is the face group a tri cylinder - Returens a bool, true if the faces make an extruded tri solid - ''' - - # cube must have 5 faces - if len(faces) != 5: - print '1' - return False - - # Check for quads and that there are 6 unique verts - verts= {} - tottri= 0 - for f in faces: - if len(f)== 3: - tottri+=1 - - for v in f: - verts[v.index]= 0 - - if len(verts) != 6 or tottri != 2: - return False - - # Now check that each vert has 3 face users - for f in faces: - for v in f: - verts[v.index] += 1 - - for v in verts.itervalues(): - if v != 3: # vert has 3 users? - return False - - # Could we check for 12 unique edges??, probably not needed. - return True - -def write_node_map(file, ob): - ''' - Writes the properties of an object (empty in this case) - as a MAP node as long as it has the property name - classname - returns True/False based on weather a node was written - ''' - props= [(p.name, p.data) for p in ob.game_properties] - - IS_MAP_NODE= False - for name, value in props: - if name=='classname': - IS_MAP_NODE= True - break - - if not IS_MAP_NODE: - return False - - # Write a node - file.write('{\n') - for name_value in props: - file.write('"%s" "%s"\n' % name_value) - if PREF_GRID_SNAP.val: - file.write('"origin" "%d %d %d"\n' % tuple([round(axis*PREF_SCALE.val) for axis in ob.getLocation('worldspace')]) ) - else: - file.write('"origin" "%.6f %.6f %.6f"\n' % tuple([axis*PREF_SCALE.val for axis in ob.getLocation('worldspace')]) ) - file.write('}\n') - return True - - -def export_map(filepath): - - pup_block = [\ - ('Scale:', PREF_SCALE, 1, 1000, 'Scale the blender scene by this value.'),\ - ('Face Width:', PREF_FACE_THICK, 0.01, 10, 'Thickness of faces exported as brushes.'),\ - ('Grid Snap', PREF_GRID_SNAP, 'snaps floating point values to whole numbers.'),\ - 'Null Texture',\ - ('', PREF_NULL_TEX, 1, 128, 'Export textureless faces with this texture'),\ - 'Unseen Texture',\ - ('', PREF_INVIS_TEX, 1, 128, 'Export invisible faces with this texture'),\ - ] - - if not Draw.PupBlock('map export', pup_block): - return - - Window.WaitCursor(1) - time= sys.time() - print 'Map Exporter 0.0' - file= open(filepath, 'w') - - - obs_mesh= [] - obs_lamp= [] - obs_surf= [] - obs_empty= [] - - SCALE_MAT= Mathutils.Matrix() - SCALE_MAT[0][0]= SCALE_MAT[1][1]= SCALE_MAT[2][2]= PREF_SCALE.val - - dummy_mesh= Mesh.New() - - TOTBRUSH= TOTLAMP= TOTNODE= 0 - - for ob in Object.GetSelected(): - type= ob.type - if type == 'Mesh': obs_mesh.append(ob) - elif type == 'Surf': obs_surf.append(ob) - elif type == 'Lamp': obs_lamp.append(ob) - elif type == 'Empty': obs_empty.append(ob) - - if obs_mesh or obs_surf: - # brushes and surf's must be under worldspan - file.write('\n// entity 0\n') - file.write('{\n') - file.write('"classname" "worldspawn"\n') - - - print '\twriting cubes from meshes' - for ob in obs_mesh: - dummy_mesh.getFromObject(ob.name) - - #print len(mesh_split2connected(dummy_mesh)) - - # Is the object 1 cube? - object-is-a-brush - dummy_mesh.transform(ob.matrixWorld*SCALE_MAT) # 1 to tx the normals also - - if PREF_GRID_SNAP.val: - for v in dummy_mesh.verts: - co= v.co - co.x= round(co.x) - co.y= round(co.y) - co.z= round(co.z) - - # High quality normals - BPyMesh.meshCalcNormals(dummy_mesh) - - # Split mesh into connected regions - for face_group in BPyMesh.mesh2linkedFaces(dummy_mesh): - if is_cube_facegroup(face_group): - write_cube2brush(file, face_group) - TOTBRUSH+=1 - elif is_tricyl_facegroup(face_group): - write_cube2brush(file, face_group) - TOTBRUSH+=1 - else: - for f in face_group: - write_face2brush(file, f) - TOTBRUSH+=1 - - #print 'warning, not exporting "%s" it is not a cube' % ob.name - - - dummy_mesh.verts= None - - - valid_dims= 3,5,7,9,11,13,15 - for ob in obs_surf: - ''' - Surf, patches - ''' - surf_name= ob.getData(name_only=1) - data= Curve.Get(surf_name) - mat = ob.matrixWorld*SCALE_MAT - - # This is what a valid patch looks like - - """ -// brush 0 -{ -patchDef2 -{ -NULL -( 3 3 0 0 0 ) -( -( ( -64 -64 0 0 0 ) ( -64 0 0 0 -2 ) ( -64 64 0 0 -4 ) ) -( ( 0 -64 0 2 0 ) ( 0 0 0 2 -2 ) ( 0 64 0 2 -4 ) ) -( ( 64 -64 0 4 0 ) ( 64 0 0 4 -2 ) ( 80 88 0 4 -4 ) ) -) -} -} - """ - for i, nurb in enumerate(data): - u= nurb.pointsU - v= nurb.pointsV - if u in valid_dims and v in valid_dims: - - file.write('// brush %d surf_name\n' % i) - file.write('{\n') - file.write('patchDef2\n') - file.write('{\n') - file.write('NULL\n') - file.write('( %d %d 0 0 0 )\n' % (u, v) ) - file.write('(\n') - - u_iter = 0 - for p in nurb: - - if u_iter == 0: - file.write('(') - - u_iter += 1 - - # add nmapping 0 0 ? - if PREF_GRID_SNAP.val: - file.write(' ( %d %d %d 0 0 )' % round_vec(Mathutils.Vector(p[0:3]) * mat)) - else: - file.write(' ( %.6f %.6f %.6f 0 0 )' % tuple(Mathutils.Vector(p[0:3]) * mat)) - - # Move to next line - if u_iter == u: - file.write(' )\n') - u_iter = 0 - - file.write(')\n') - file.write('}\n') - file.write('}\n') - - - # Debugging - # for p in nurb: print 'patch', p - - else: - print "NOT EXPORTING PATCH", surf_name, u,v, 'Unsupported' - - - if obs_mesh or obs_surf: - file.write('}\n') # end worldspan - - - print '\twriting lamps' - for ob in obs_lamp: - print '\t\t%s' % ob.name - lamp= ob.data - file.write('{\n') - file.write('"classname" "light"\n') - file.write('"light" "%.6f"\n' % (lamp.dist* PREF_SCALE.val)) - if PREF_GRID_SNAP.val: - file.write('"origin" "%d %d %d"\n' % tuple([round(axis*PREF_SCALE.val) for axis in ob.getLocation('worldspace')]) ) - else: - file.write('"origin" "%.6f %.6f %.6f"\n' % tuple([axis*PREF_SCALE.val for axis in ob.getLocation('worldspace')]) ) - file.write('"_color" "%.6f %.6f %.6f"\n' % tuple(lamp.col)) - file.write('"style" "0"\n') - file.write('}\n') - TOTLAMP+=1 - - - print '\twriting empty objects as nodes' - for ob in obs_empty: - if write_node_map(file, ob): - print '\t\t%s' % ob.name - TOTNODE+=1 - else: - print '\t\tignoring %s' % ob.name - - Window.WaitCursor(0) - - print 'Exported Map in %.4fsec' % (sys.time()-time) - print 'Brushes: %d Nodes: %d Lamps %d\n' % (TOTBRUSH, TOTNODE, TOTLAMP) - - -def main(): - Window.FileSelector(export_map, 'EXPORT MAP', '*.map') - -if __name__ == '__main__': main() -# export_map('/foo.map') diff --git a/release/scripts/export_mdd.py b/release/scripts/export_mdd.py deleted file mode 100644 index 4f99c9175fd..00000000000 --- a/release/scripts/export_mdd.py +++ /dev/null @@ -1,168 +0,0 @@ -#!BPY - -""" - Name: 'Vertex Keyframe Animation (.mdd)...' - Blender: 242 - Group: 'Export' - Tooltip: 'Animated mesh to MDD vertex keyframe file.' -""" - -__author__ = "Bill L.Nieuwendorp" -__bpydoc__ = """\ -This script Exports Lightwaves MotionDesigner format. - -The .mdd format has become quite a popular Pipeline format
-for moving animations from package to package. - -Be sure not to use modifiers that change the number or order of verts in the mesh -""" -#Please send any fixes,updates,bugs to Slow67_at_Gmail.com or cbarton_at_metavr.com -#Bill Niewuendorp -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - -import bpy -import Blender -from Blender import * -import BPyMessages -try: - from struct import pack -except: - pack = None - - -def zero_file(filepath): - ''' - If a file fails, this replaces it with 1 char, better not remove it? - ''' - file = open(filepath, 'w') - file.write('\n') # aparently macosx needs some data in a blank file? - file.close() - - -def check_vertcount(mesh,vertcount): - ''' - check and make sure the vertcount is consistent throghout the frame range - ''' - if len(mesh.verts) != vertcount: - Blender.Draw.PupMenu('Error%t|Number of verts has changed during animation|cannot export') - f.close() - zero_file(filepath) - return - - -def mdd_export(filepath, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS): - - Window.EditMode(0) - Blender.Window.WaitCursor(1) - mesh_orig = Mesh.New() - mesh_orig.getFromObject(ob.name) - - #Flip y and z - ''' - mat = Mathutils.Matrix() - mat[2][2] = -1 - rotmat = Mathutils.RotationMatrix(90, 4, 'x') - mat_flip = mat*rotmat - ''' - # Above results in this matrix - mat_flip= Mathutils.Matrix(\ - [1.0, 0.0, 0.0, 0.0],\ - [0.0, 0.0, 1.0, 0.0],\ - [0.0, 1.0, 0.0, 0.0],\ - [0.0, 0.0, 0.0, 1.0],\ - ) - - me_tmp = Mesh.New() # container mesh - - numverts = len(mesh_orig.verts) - numframes = PREF_ENDFRAME-PREF_STARTFRAME+1 - PREF_FPS= float(PREF_FPS) - f = open(filepath, 'wb') #no Errors yet:Safe to create file - - # Write the header - f.write(pack(">2i", numframes, numverts)) - - # Write the frame times (should we use the time IPO??) - f.write( pack(">%df" % (numframes), *[frame/PREF_FPS for frame in xrange(numframes)]) ) # seconds - - #rest frame needed to keep frames in sync - Blender.Set('curframe', PREF_STARTFRAME) - me_tmp.getFromObject(ob.name) - check_vertcount(me_tmp,numverts) - me_tmp.transform(ob.matrixWorld * mat_flip) - f.write(pack(">%df" % (numverts*3), *[axis for v in me_tmp.verts for axis in v.co])) - me_tmp.verts= None - - for frame in xrange(PREF_STARTFRAME,PREF_ENDFRAME+1):#in order to start at desired frame - Blender.Set('curframe', frame) - - me_tmp.getFromObject(ob.name) - - check_vertcount(me_tmp,numverts) - - me_tmp.transform(ob.matrixWorld * mat_flip) - - # Write the vertex data - f.write(pack(">%df" % (numverts*3), *[axis for v in me_tmp.verts for axis in v.co])) - - me_tmp.verts= None - f.close() - - print'MDD Exported: %s frames:%d\n'% (filepath, numframes-1) - Blender.Window.WaitCursor(0) - - -def mdd_export_ui(filepath): - # Dont overwrite - if not BPyMessages.Warning_SaveOver(filepath): - return - - scn= bpy.data.scenes.active - ob_act= scn.objects.active - if not ob_act or ob_act.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - - ctx = scn.getRenderingContext() - orig_frame = Blender.Get('curframe') - PREF_STARTFRAME= Blender.Draw.Create(int(ctx.startFrame())) - PREF_ENDFRAME= Blender.Draw.Create(int(ctx.endFrame())) - PREF_FPS= Blender.Draw.Create(ctx.fps) - - block = [\ - ("Start Frame: ", PREF_STARTFRAME, 1, 30000, "Start Bake from what frame?: Default 1"),\ - ("End Frame: ", PREF_ENDFRAME, 1, 30000, "End Bake on what Frame?"),\ - ("FPS: ", PREF_FPS, 1, 100, "Frames per second")\ - ] - - if not Blender.Draw.PupBlock("Export MDD", block): - return - - PREF_STARTFRAME, PREF_ENDFRAME=\ - min(PREF_STARTFRAME.val, PREF_ENDFRAME.val),\ - max(PREF_STARTFRAME.val, PREF_ENDFRAME.val) - - print (filepath, ob_act, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS.val) - mdd_export(filepath, ob_act, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS.val) - Blender.Set('curframe', orig_frame) - -if __name__=='__main__': - if not pack: - Draw.PupMenu('Error%t|This script requires a full python install') - - Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd')) \ No newline at end of file diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py deleted file mode 100644 index 7dffb5d2048..00000000000 --- a/release/scripts/export_obj.py +++ /dev/null @@ -1,933 +0,0 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 249 -Group: 'Export' -Tooltip: 'Save a Wavefront OBJ File' -""" - -__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone" -__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] -__version__ = "1.22" - -__bpydoc__ = """\ -This script is an exporter to OBJ file format. - -Usage: - -Select the objects you wish to export and run this script from "File->Export" menu. -Selecting the default options from the popup box will be good in most cases. -All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) -will be exported as mesh data. -""" - - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton 2007-2009 -# - V1.22- bspline import/export added (funded by PolyDimensions GmbH) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -import Blender -from Blender import Mesh, Scene, Window, sys, Image, Draw -import BPyMesh -import BPyObject -import BPySys -import BPyMessages - -# Returns a tuple - path,extension. -# 'hello.obj' > ('hello', '.obj') -def splitExt(path): - dotidx = path.rfind('.') - if dotidx == -1: - return path, '' - else: - return path[:dotidx], path[dotidx:] - -def fixName(name): - if name == None: - return 'None' - else: - return name.replace(' ', '_') - -# A Dict of Materials -# (material.name, image.name):matname_imagename # matname_imagename has gaps removed. -MTL_DICT = {} - -def write_mtl(filename): - - world = Blender.World.GetCurrent() - if world: - worldAmb = world.getAmb() - else: - worldAmb = (0,0,0) # Default value - - file = open(filename, "w") - file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) - file.write('# Material Count: %i\n' % len(MTL_DICT)) - # Write material/image combinations we have used. - for key, (mtl_mat_name, mat, img) in MTL_DICT.iteritems(): - - # Get the Blender data for the material and the image. - # Having an image named None will make a bug, dont do it :) - - file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname - - if mat: - file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's - file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse - file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular - file.write('Ni %.6f\n' % mat.IOR) # Refraction index - file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) - - # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. - if mat.getMode() & Blender.Material.Modes['SHADELESS']: - file.write('illum 0\n') # ignore lighting - elif mat.getSpec() == 0: - file.write('illum 1\n') # no specular. - else: - file.write('illum 2\n') # light normaly - - else: - #write a dummy material here? - file.write('Ns 0\n') - file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, - file.write('Kd 0.8 0.8 0.8\n') - file.write('Ks 0.8 0.8 0.8\n') - file.write('d 1\n') # No alpha - file.write('illum 2\n') # light normaly - - # Write images! - if img: # We have an image on the face! - file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image - - elif mat: # No face image. if we havea material search for MTex image. - for mtex in mat.getTextures(): - if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: - try: - filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1] - file.write('map_Kd %s\n' % filename) # Diffuse mapping image - break - except: - # Texture has no image though its an image type, best ignore. - pass - - file.write('\n\n') - - file.close() - -def copy_file(source, dest): - file = open(source, 'rb') - data = file.read() - file.close() - - file = open(dest, 'wb') - file.write(data) - file.close() - - -def copy_images(dest_dir): - if dest_dir[-1] != sys.sep: - dest_dir += sys.sep - - # Get unique image names - uniqueImages = {} - for matname, mat, image in MTL_DICT.itervalues(): # Only use image name - # Get Texface images - if image: - uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default. - - # Get MTex images - if mat: - for mtex in mat.getTextures(): - if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE: - image_tex = mtex.tex.image - if image_tex: - try: - uniqueImages[image_tex] = image_tex - except: - pass - - # Now copy images - copyCount = 0 - - for bImage in uniqueImages.itervalues(): - image_path = sys.expandpath(bImage.filename) - if sys.exists(image_path): - # Make a name for the target path. - dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] - if not sys.exists(dest_image_path): # Image isnt alredy there - print '\tCopying "%s" > "%s"' % (image_path, dest_image_path) - copy_file(image_path, dest_image_path) - copyCount+=1 - print '\tCopied %d images' % copyCount - - -def test_nurbs_compat(ob): - if ob.type != 'Curve': - return False - - for nu in ob.data: - if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier - return True - - return False - -def write_nurb(file, ob, ob_mat): - tot_verts = 0 - cu = ob.data - - # use negative indices - Vector = Blender.Mathutils.Vector - for nu in cu: - - if nu.type==0: DEG_ORDER_U = 1 - else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct - - if nu.type==1: - print "\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported" - continue - - if nu.knotsV: - print "\tWarning, surface:", ob.name, "only poly and nurbs curves supported" - continue - - if len(nu) <= DEG_ORDER_U: - print "\tWarning, orderU is lower then vert count, skipping:", ob.name - continue - - pt_num = 0 - do_closed = (nu.flagU & 1) - do_endpoints = (do_closed==0) and (nu.flagU & 2) - - for pt in nu: - pt = Vector(pt[0], pt[1], pt[2]) * ob_mat - file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2])) - pt_num += 1 - tot_verts += pt_num - - file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too - file.write('cstype bspline\n') # not ideal, hard coded - file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still - - curve_ls = [-(i+1) for i in xrange(pt_num)] - - # 'curv' keyword - if do_closed: - if DEG_ORDER_U == 1: - pt_num += 1 - curve_ls.append(-1) - else: - pt_num += DEG_ORDER_U - curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U] - - file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve - - # 'parm' keyword - tot_parm = (DEG_ORDER_U + 1) + pt_num - tot_parm_div = float(tot_parm-1) - parm_ls = [(i/tot_parm_div) for i in xrange(tot_parm)] - - if do_endpoints: # end points, force param - for i in xrange(DEG_ORDER_U+1): - parm_ls[i] = 0.0 - parm_ls[-(1+i)] = 1.0 - - file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] )) - - file.write('end\n') - - return tot_verts - -def write(filename, objects,\ -EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ -EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ -EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ -EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False,\ -EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): - ''' - Basic write function. The context and options must be alredy set - This can be accessed externaly - eg. - write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. - ''' - - def veckey3d(v): - return round(v.x, 6), round(v.y, 6), round(v.z, 6) - - def veckey2d(v): - return round(v.x, 6), round(v.y, 6) - - def findVertexGroupName(face, vWeightMap): - """ - Searches the vertexDict to see what groups is assigned to a given face. - We use a frequency system in order to sort out the name because a given vetex can - belong to two or more groups at the same time. To find the right name for the face - we list all the possible vertex group names with their frequency and then sort by - frequency in descend order. The top element is the one shared by the highest number - of vertices is the face's group - """ - weightDict = {} - for vert in face: - vWeights = vWeightMap[vert.index] - for vGroupName, weight in vWeights: - weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight - - if weightDict: - alist = [(weight,vGroupName) for vGroupName, weight in weightDict.iteritems()] # sort least to greatest amount of weight - alist.sort() - return(alist[-1][1]) # highest value last - else: - return '(null)' - - - print 'OBJ Export path: "%s"' % filename - temp_mesh_name = '~tmp-mesh' - - time1 = sys.time() - scn = Scene.GetCurrent() - - file = open(filename, "w") - - # Write Header - file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) - file.write('# www.blender3d.org\n') - - # Tell the obj file what material file to use. - if EXPORT_MTL: - mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) - file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) - - # Get the container mesh. - used for applying modifiers and non mesh objects. - containerMesh = meshName = tempMesh = None - for meshName in Blender.NMesh.GetNames(): - if meshName.startswith(temp_mesh_name): - tempMesh = Mesh.Get(meshName) - if not tempMesh.users: - containerMesh = tempMesh - if not containerMesh: - containerMesh = Mesh.New(temp_mesh_name) - - if EXPORT_ROTX90: - mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x') - - del meshName - del tempMesh - - # Initialize totals, these are updated each object - totverts = totuvco = totno = 1 - - face_vert_index = 1 - - globalNormals = {} - - # Get all meshes - for ob_main in objects: - for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): - - # Nurbs curve support - if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): - if EXPORT_ROTX90: - ob_mat = ob_mat * mat_xrot90 - - totverts += write_nurb(file, ob, ob_mat) - - continue - # end nurbs - - # Will work for non meshes now! :) - # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) - me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) - if not me: - continue - - if EXPORT_UV: - faceuv= me.faceUV - else: - faceuv = False - - # We have a valid mesh - if EXPORT_TRI and me.faces: - # Add a dummy object to it. - has_quads = False - for f in me.faces: - if len(f) == 4: - has_quads = True - break - - if has_quads: - oldmode = Mesh.Mode() - Mesh.Mode(Mesh.SelectModes['FACE']) - - me.sel = True - tempob = scn.objects.new(me) - me.quadToTriangle(0) # more=0 shortest length - oldmode = Mesh.Mode(oldmode) - scn.objects.unlink(tempob) - - Mesh.Mode(oldmode) - - # Make our own list so it can be sorted to reduce context switching - faces = [ f for f in me.faces ] - - if EXPORT_EDGES: - edges = me.edges - else: - edges = [] - - if not (len(faces)+len(edges)+len(me.verts)): # Make sure there is somthing to write - continue # dont bother with this mesh. - - if EXPORT_ROTX90: - me.transform(ob_mat*mat_xrot90) - else: - me.transform(ob_mat) - - # High Quality Normals - if EXPORT_NORMALS and faces: - if EXPORT_NORMALS_HQ: - BPyMesh.meshCalcNormals(me) - else: - # transforming normals is incorrect - # when the matrix is scaled, - # better to recalculate them - me.calcNormals() - - # # Crash Blender - #materials = me.getMaterials(1) # 1 == will return None in the list. - materials = me.materials - - materialNames = [] - materialItems = materials[:] - if materials: - for mat in materials: - if mat: # !=None - materialNames.append(mat.name) - else: - materialNames.append(None) - # Cant use LC because some materials are None. - # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. - - # Possible there null materials, will mess up indicies - # but at least it will export, wait until Blender gets fixed. - materialNames.extend((16-len(materialNames)) * [None]) - materialItems.extend((16-len(materialItems)) * [None]) - - # Sort by Material, then images - # so we dont over context switch in the obj file. - if EXPORT_KEEP_VERT_ORDER: - pass - elif faceuv: - try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) - except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) - elif len(materials) > 1: - try: faces.sort(key = lambda a: (a.mat, a.smooth)) - except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) - else: - # no materials - try: faces.sort(key = lambda a: a.smooth) - except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) - - # Set the default mat to no material and no image. - contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. - contextSmooth = None # Will either be true or false, set bad to force initialization switch. - - if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: - name1 = ob.name - name2 = ob.getData(1) - if name1 == name2: - obnamestring = fixName(name1) - else: - obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) - - if EXPORT_BLEN_OBS: - file.write('o %s\n' % obnamestring) # Write Object name - else: # if EXPORT_GROUP_BY_OB: - file.write('g %s\n' % obnamestring) - - - # Vert - for v in me.verts: - file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) - - # UV - if faceuv: - uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ - - uv_dict = {} # could use a set() here - for f_index, f in enumerate(faces): - - for uv_index, uv in enumerate(f.uv): - uvkey = veckey2d(uv) - try: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] - except: - uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) - file.write('vt %.6f %.6f\n' % tuple(uv)) - - uv_unique_count = len(uv_dict) - del uv, uvkey, uv_dict, f_index, uv_index - # Only need uv_unique_count and uv_face_mapping - - # NORMAL, Smooth/Non smoothed. - if EXPORT_NORMALS: - for f in faces: - if f.smooth: - for v in f: - noKey = veckey3d(v.no) - if not globalNormals.has_key( noKey ): - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - else: - # Hard, 1 normal from the face. - noKey = veckey3d(f.no) - if not globalNormals.has_key( noKey ): - globalNormals[noKey] = totno - totno +=1 - file.write('vn %.6f %.6f %.6f\n' % noKey) - - if not faceuv: - f_image = None - - if EXPORT_POLYGROUPS: - # Retrieve the list of vertex groups - vertGroupNames = me.getVertGroupNames() - - currentVGroup = '' - # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to - vgroupsMap = [[] for _i in xrange(len(me.verts))] - for vertexGroupName in vertGroupNames: - for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): - vgroupsMap[vIdx].append((vertexGroupName, vWeight)) - - for f_index, f in enumerate(faces): - f_v= f.v - f_smooth= f.smooth - f_mat = min(f.mat, len(materialNames)-1) - if faceuv: - f_image = f.image - f_uv= f.uv - - # MAKE KEY - if faceuv and f_image: # Object is always true. - key = materialNames[f_mat], f_image.name - else: - key = materialNames[f_mat], None # No image, use None instead. - - # Write the vertex group - if EXPORT_POLYGROUPS: - if vertGroupNames: - # find what vertext group the face belongs to - theVGroup = findVertexGroupName(f,vgroupsMap) - if theVGroup != currentVGroup: - currentVGroup = theVGroup - file.write('g %s\n' % theVGroup) - - # CHECK FOR CONTEXT SWITCH - if key == contextMat: - pass # Context alredy switched, dont do anything - else: - if key[0] == None and key[1] == None: - # Write a null material, since we know the context has changed. - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.getData(1))) ) # can be mat_image or (null) - file.write('usemtl (null)\n') # mat, image - - else: - mat_data= MTL_DICT.get(key) - if not mat_data: - # First add to global dict so we can export to mtl - # Then write mtl - - # Make a new names from the mat and image name, - # converting any spaces to underscores with fixName. - - # If none image dont bother adding it to the name - if key[1] == None: - mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image - else: - mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image - - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), mat_data[0]) ) # can be mat_image or (null) - - file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) - - contextMat = key - if f_smooth != contextSmooth: - if f_smooth: # on now off - file.write('s 1\n') - contextSmooth = f_smooth - else: # was off now on - file.write('s off\n') - contextSmooth = f_smooth - - file.write('f') - if faceuv: - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi],\ - globalNormals[ veckey3d(v.no) ])) # vert, uv, normal - - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.no) ] - for vi, v in enumerate(f_v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi],\ - no)) # vert, uv, normal - - else: # No Normals - for vi, v in enumerate(f_v): - file.write( ' %d/%d' % (\ - v.index+totverts,\ - totuvco + uv_face_mapping[f_index][vi])) # vert, uv - - face_vert_index += len(f_v) - - else: # No UV's - if EXPORT_NORMALS: - if f_smooth: # Smoothed, use vertex normals - for v in f_v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - globalNormals[ veckey3d(v.no) ])) - else: # No smoothing, face normals - no = globalNormals[ veckey3d(f.no) ] - for v in f_v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - no)) - else: # No Normals - for v in f_v: - file.write( ' %d' % (\ - v.index+totverts)) - - file.write('\n') - - # Write edges. - if EXPORT_EDGES: - LOOSE= Mesh.EdgeFlags.LOOSE - for ed in edges: - if ed.flag & LOOSE: - file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) - - # Make the indicies global rather then per mesh - totverts += len(me.verts) - if faceuv: - totuvco += uv_unique_count - me.verts= None - file.close() - - - # Now we have all our materials, save them - if EXPORT_MTL: - write_mtl(mtlfilename) - if EXPORT_COPY_IMAGES: - dest_dir = filename - # Remove chars until we are just the path. - while dest_dir and dest_dir[-1] not in '\\/': - dest_dir = dest_dir[:-1] - if dest_dir: - copy_images(dest_dir) - else: - print '\tError: "%s" could not be used as a base for an image path.' % filename - - print "OBJ Export time: %.2f" % (sys.time() - time1) - - - -def write_ui(filename): - - if not filename.lower().endswith('.obj'): - filename += '.obj' - - if not BPyMessages.Warning_SaveOver(filename): - return - - global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ - EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ - EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ - EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS - - EXPORT_APPLY_MODIFIERS = Draw.Create(0) - EXPORT_ROTX90 = Draw.Create(1) - EXPORT_TRI = Draw.Create(0) - EXPORT_EDGES = Draw.Create(1) - EXPORT_NORMALS = Draw.Create(0) - EXPORT_NORMALS_HQ = Draw.Create(0) - EXPORT_UV = Draw.Create(1) - EXPORT_MTL = Draw.Create(1) - EXPORT_SEL_ONLY = Draw.Create(1) - EXPORT_ALL_SCENES = Draw.Create(0) - EXPORT_ANIMATION = Draw.Create(0) - EXPORT_COPY_IMAGES = Draw.Create(0) - EXPORT_BLEN_OBS = Draw.Create(0) - EXPORT_GROUP_BY_OB = Draw.Create(0) - EXPORT_GROUP_BY_MAT = Draw.Create(0) - EXPORT_KEEP_VERT_ORDER = Draw.Create(1) - EXPORT_POLYGROUPS = Draw.Create(0) - EXPORT_CURVE_AS_NURBS = Draw.Create(1) - - - # Old UI - ''' - # removed too many options are bad! - - # Get USER Options - pup_block = [\ - ('Context...'),\ - ('Selection Only', EXPORT_SEL_ONLY, 'Only export objects in visible selection. Else export whole scene.'),\ - ('All Scenes', EXPORT_ALL_SCENES, 'Each scene as a separate OBJ file.'),\ - ('Animation', EXPORT_ANIMATION, 'Each frame as a numbered OBJ file.'),\ - ('Object Prefs...'),\ - ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object. May break vert order for morph targets.'),\ - ('Rotate X90', EXPORT_ROTX90 , 'Rotate on export so Blenders UP is translated into OBJs UP'),\ - ('Keep Vert Order', EXPORT_KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ - ('Extra Data...'),\ - ('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\ - ('Normals', EXPORT_NORMALS, 'Export vertex normal data (Ignored on import).'),\ - ('High Quality Normals', EXPORT_NORMALS_HQ, 'Calculate high quality normals for rendering.'),\ - ('UVs', EXPORT_UV, 'Export texface UV coords.'),\ - ('Materials', EXPORT_MTL, 'Write a separate MTL file with the OBJ.'),\ - ('Copy Images', EXPORT_COPY_IMAGES, 'Copy image files to the export directory, never overwrite.'),\ - ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\ - ('Grouping...'),\ - ('Objects', EXPORT_BLEN_OBS, 'Export blender objects as "OBJ objects".'),\ - ('Object Groups', EXPORT_GROUP_BY_OB, 'Export blender objects as "OBJ Groups".'),\ - ('Material Groups', EXPORT_GROUP_BY_MAT, 'Group by materials.'),\ - ] - - if not Draw.PupBlock('Export...', pup_block): - return - ''' - - # BEGIN ALTERNATIVE UI ******************* - if True: - - EVENT_NONE = 0 - EVENT_EXIT = 1 - EVENT_REDRAW = 2 - EVENT_EXPORT = 3 - - GLOBALS = {} - GLOBALS['EVENT'] = EVENT_REDRAW - #GLOBALS['MOUSE'] = Window.GetMouseCoords() - GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] - - def obj_ui_set_event(e,v): - GLOBALS['EVENT'] = e - - def do_split(e,v): - global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER, EXPORT_POLYGROUPS - if EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val: - EXPORT_KEEP_VERT_ORDER.val = 0 - else: - EXPORT_KEEP_VERT_ORDER.val = 1 - - def do_vertorder(e,v): - global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER - if EXPORT_KEEP_VERT_ORDER.val: - EXPORT_BLEN_OBS.val = EXPORT_GROUP_BY_OB.val = EXPORT_GROUP_BY_MAT.val = EXPORT_APPLY_MODIFIERS.val = 0 - else: - if not (EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val): - EXPORT_KEEP_VERT_ORDER.val = 1 - - - def do_help(e,v): - url = __url__[0] - print 'Trying to open web browser with documentation at this address...' - print '\t' + url - - try: - import webbrowser - webbrowser.open(url) - except: - print '...could not open a browser window.' - - def obj_ui(): - ui_x, ui_y = GLOBALS['MOUSE'] - - # Center based on overall pup size - ui_x -= 165 - ui_y -= 140 - - global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\ - EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\ - EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ - EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS - - Draw.Label('Context...', ui_x+9, ui_y+239, 220, 20) - Draw.BeginAlign() - EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+219, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.') - EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+219, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.') - EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+219, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.') - Draw.EndAlign() - - - Draw.Label('Output Options...', ui_x+9, ui_y+189, 220, 20) - Draw.BeginAlign() - EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+170, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split) - EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+170, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP') - EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+170, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.') - Draw.EndAlign() - - - Draw.Label('Export...', ui_x+9, ui_y+139, 220, 20) - Draw.BeginAlign() - EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+120, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.') - EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+120, 70, 20, EXPORT_TRI.val, 'Triangulate quads.') - Draw.EndAlign() - Draw.BeginAlign() - EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+120, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.') - EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+120, 31, 20, EXPORT_UV.val, 'Export texface UV coords.') - Draw.EndAlign() - Draw.BeginAlign() - EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+120, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).') - EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+120, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.') - Draw.EndAlign() - EXPORT_POLYGROUPS = Draw.Toggle('Polygroups', EVENT_REDRAW, ui_x+9, ui_y+95, 120, 20, EXPORT_POLYGROUPS.val, 'Export vertex groups as OBJ groups (one group per face approximation).') - - EXPORT_CURVE_AS_NURBS = Draw.Toggle('Nurbs', EVENT_NONE, ui_x+139, ui_y+95, 100, 20, EXPORT_CURVE_AS_NURBS.val, 'Export 3D nurbs curves and polylines as OBJ curves, (bezier not supported).') - - - Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20) - Draw.BeginAlign() - EXPORT_BLEN_OBS = Draw.Toggle('Objects', EVENT_REDRAW, ui_x+9, ui_y+39, 60, 20, EXPORT_BLEN_OBS.val, 'Export blender objects as "OBJ objects".', do_split) - EXPORT_GROUP_BY_OB = Draw.Toggle('Groups', EVENT_REDRAW, ui_x+69, ui_y+39, 60, 20, EXPORT_GROUP_BY_OB.val, 'Export blender objects as "OBJ Groups".', do_split) - EXPORT_GROUP_BY_MAT = Draw.Toggle('Material Groups', EVENT_REDRAW, ui_x+129, ui_y+39, 100, 20, EXPORT_GROUP_BY_MAT.val, 'Group by materials.', do_split) - Draw.EndAlign() - - EXPORT_KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+239, ui_y+39, 100, 20, EXPORT_KEEP_VERT_ORDER.val, 'Keep vert and face order, disables some other options. Use for morph targets.', do_vertorder) - - Draw.BeginAlign() - Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 20, 'Load the wiki page for this script', do_help) - Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 20, '', obj_ui_set_event) - Draw.PushButton('Export', EVENT_EXPORT, ui_x+229, ui_y+9, 110, 20, 'Export with these settings', obj_ui_set_event) - Draw.EndAlign() - - - # hack so the toggle buttons redraw. this is not nice at all - while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_EXPORT): - Draw.UIBlock(obj_ui, 0) - - if GLOBALS['EVENT'] != EVENT_EXPORT: - return - - # END ALTERNATIVE UI ********************* - - - if EXPORT_KEEP_VERT_ORDER.val: - EXPORT_BLEN_OBS.val = False - EXPORT_GROUP_BY_OB.val = False - EXPORT_GROUP_BY_MAT.val = False - EXPORT_APPLY_MODIFIERS.val = False - - Window.EditMode(0) - Window.WaitCursor(1) - - EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val - EXPORT_ROTX90 = EXPORT_ROTX90.val - EXPORT_TRI = EXPORT_TRI.val - EXPORT_EDGES = EXPORT_EDGES.val - EXPORT_NORMALS = EXPORT_NORMALS.val - EXPORT_NORMALS_HQ = EXPORT_NORMALS_HQ.val - EXPORT_UV = EXPORT_UV.val - EXPORT_MTL = EXPORT_MTL.val - EXPORT_SEL_ONLY = EXPORT_SEL_ONLY.val - EXPORT_ALL_SCENES = EXPORT_ALL_SCENES.val - EXPORT_ANIMATION = EXPORT_ANIMATION.val - EXPORT_COPY_IMAGES = EXPORT_COPY_IMAGES.val - EXPORT_BLEN_OBS = EXPORT_BLEN_OBS.val - EXPORT_GROUP_BY_OB = EXPORT_GROUP_BY_OB.val - EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val - EXPORT_KEEP_VERT_ORDER = EXPORT_KEEP_VERT_ORDER.val - EXPORT_POLYGROUPS = EXPORT_POLYGROUPS.val - EXPORT_CURVE_AS_NURBS = EXPORT_CURVE_AS_NURBS.val - - - base_name, ext = splitExt(filename) - context_name = [base_name, '', '', ext] # basename, scene_name, framenumber, extension - - # Use the options to export the data using write() - # def write(filename, objects, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, EXPORT_APPLY_MODIFIERS=True): - orig_scene = Scene.GetCurrent() - if EXPORT_ALL_SCENES: - export_scenes = Scene.Get() - else: - export_scenes = [orig_scene] - - # Export all scenes. - for scn in export_scenes: - scn.makeCurrent() # If alredy current, this is not slow. - context = scn.getRenderingContext() - orig_frame = Blender.Get('curframe') - - if EXPORT_ALL_SCENES: # Add scene name into the context_name - context_name[1] = '_%s' % BPySys.cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. - - # Export an animation? - if EXPORT_ANIMATION: - scene_frames = xrange(context.startFrame(), context.endFrame()+1) # up to and including the end frame. - else: - scene_frames = [orig_frame] # Dont export an animation. - - # Loop through all frames in the scene and export. - for frame in scene_frames: - if EXPORT_ANIMATION: # Add frame to the filename. - context_name[2] = '_%.6d' % frame - - Blender.Set('curframe', frame) - if EXPORT_SEL_ONLY: - export_objects = scn.objects.context - else: - export_objects = scn.objects - - full_path= ''.join(context_name) - - # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. - # EXPORT THE FILE. - write(full_path, export_objects,\ - EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ - EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ - EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ - EXPORT_ROTX90, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) - - Blender.Set('curframe', orig_frame) - - # Restore old active scene. - orig_scene.makeCurrent() - Window.WaitCursor(0) - - -if __name__ == '__main__': - Window.FileSelector(write_ui, 'Export Wavefront OBJ', sys.makename(ext='.obj')) diff --git a/release/scripts/faceselect_same_weights.py b/release/scripts/faceselect_same_weights.py deleted file mode 100644 index 967aedec363..00000000000 --- a/release/scripts/faceselect_same_weights.py +++ /dev/null @@ -1,111 +0,0 @@ -#!BPY -""" -Name: 'Same Weights...' -Blender: 245 -Group: 'FaceSelect' -Tooltip: 'Select same faces with teh same weight for the active group.' -""" - -__author__ = ["Campbell Barton aka ideasman42"] -__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"] -__version__ = "0.1" -__bpydoc__ = """\ - -Select Same Weights - -Select same weights as the active face on the active group. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from Blender import Scene, Draw, Mesh -import BPyMesh - -def selSameWeights(me, PREF_TOLERENCE): - - # Check for missing data - if not me.faceUV: return - - act_group= me.activeGroup - if not act_group: return - - act_face = me.faces[me.activeFace] - if act_face == None: return - - - - groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) - - def get_face_weight(f): - ''' - Return the faces median weight and weight range. - ''' - wmin = 1.0 - wmax = 0.0 - w = 0.0 - for v in f: - try: - new_weight = vWeightDict[v.index][act_group] - if wmin > new_weight: wmin = new_weight - if wmax < new_weight: wmax = new_weight - w += new_weight - except: - pass - return w, wmax-wmin # weight, range - - weight_from, weight_range_from = get_face_weight(act_face) - for f in me.faces: - if (not f.sel) and f != act_face: - weight, weight_range = get_face_weight(f) - - # Compare the 2 faces weight difference and difference in their contrast. - if\ - abs(weight - weight_from) <= PREF_TOLERENCE and\ - abs(weight_range - weight_range_from) <= PREF_TOLERENCE: - f.sel = True - - -def main(): - scn= Scene.GetCurrent() - ob= scn.objects.active - - if not ob or ob.type != 'Mesh': - Draw.PupMenu('Error, no active mesh object, aborting.') - return - - me= ob.getData(mesh=1) - - PREF_TOLERENCE= Draw.Create(0.1) - - pup_block= [\ - ('Tolerence:', PREF_TOLERENCE, 0.01, 1.0, 'Tolerence for selecting faces of the same weight.'),\ - ] - - if not Draw.PupBlock('Select Same Weight...', pup_block): - return - - PREF_TOLERENCE= PREF_TOLERENCE.val - - selSameWeights(me, PREF_TOLERENCE) - -if __name__=='__main__': - main() \ No newline at end of file diff --git a/release/scripts/flt_defaultp.py b/release/scripts/flt_defaultp.py deleted file mode 100644 index 5c44fe29a6f..00000000000 --- a/release/scripts/flt_defaultp.py +++ /dev/null @@ -1 +0,0 @@ -pal = [-1,255,16711935,-16776961,-19529729,-19726337,-19922945,-20119553,-20316161,-20578305,-20840449,-21102593,-21364737,-21692417,-22020097,-22413313,-22806529,-23199745,-23658497,-24117249,-24641537,-25165825,-25755649,-26411009,-27066369,-27787265,-28573697,-29425665,-30343169,-31326209,-32374785,-33488897,-354549761,-371458049,-388366337,-405274625,-422182913,-439156737,-456130561,-473104385,-506855425,-540672001,-574488577,-608305153,-642121729,-676003841,-709885953,-760610817,-811335681,-862060545,-912850945,-980418561,-1048051713,-1115684865,-1183383553,-1267924993,-1352466433,-1453850625,-1555300353,-1656815617,-1775173633,-1893597185,-2028863489,2130771967,-1010376193,-1043996161,-1077681665,-1111367169,-1145052673,-1178738177,-1229200897,-1279663617,-1330126337,-1380654593,-1431182849,-1498488321,-1565793793,-1633164801,-1700535809,-1784684033,-1868832257,-1969823233,-2070814209,2123096575,2005262847,1887429119,1752752639,1601298943,1449779711,1281417727,1096278527,911073791,709026303,490201599,254534143,2023935,-1380857601,-1397700353,-1431320321,-1464940289,-1498560257,-1532180225,-1565865729,-1599551233,-1650013953,-1700476673,-1750939393,-1801402113,-1851864833,-1919170305,-1986475777,-2053781249,-2121086721,2089797887,2005649663,1904724223,1803798783,1686030591,1568262399,1450494207,1315883263,1164495103,1013041407,844810495,659736831,457885951,239192319,3655935,-1767919617,-1784762369,-1801605121,-1818447873,-1852067841,-1885687809,-1919307777,-1952927745,-1986547713,-2020167681,-2070564865,-2120962049,2123542527,2073079807,2022617087,1955377151,1888137215,1820897279,1736880127,1652797439,1568714751,1467854847,1366994943,1249357823,1131655167,997175295,862695423,711372799,560050175,391950335,207007743,5287935,2139657983,2122880767,2106103551,2089326335,2072549119,2055771903,2022217471,1988663039,1955108607,1921554175,1887934207,1854314239,1803917055,1753519871,1703122687,1652725503,1602328319,1535153919,1467979519,1400805119,1316853503,1232901887,1148950271,1048221439,947427071,846632703,729061119,611489535,477140735,326014719,174888703,6919935,1837268479,1820491263,1803714047,1786936831,1770159615,1753382399,1736605183,1719827967,1686273535,1652719103,1619164671,1585610239,1552055807,1518501375,1468169727,1417838079,1367506431,1317174783,1266843135,1199734271,1132625407,1065516543,998407679,914521599,830635519,729972223,629308927,528645631,411205119,293764607,159546879,8551935,-2086957569,-2103734785,-2120512001,-2137289217,2140900863,2107346431,2073791999,2040237311,2006682623,1973127935,1939573247,1906018559,1855686655,1805354751,1755022847,1704690943,1654359039,1587249919,1520140799,1453031679,1369145343,1285258751,1201372159,1100708351,1000044543,882603519,765162495,630943999,496725503,345729791,177956863,10183935,-1699437825,-1716215297,-1732992769,-1766547457,-1800102145,-1833656833,-1867211521,-1900766209,-1934320897,-1967875585,-2018207489,-2068539649,-2118871809,2125763327,2058653951,1991544575,1924435199,1857325823,1773438975,1689552127,1588888063,1488223999,1387559679,1270118143,1152676607,1018457855,884238847,733242623,565468927,397695231,213144319,11815935,-1311918593,-1345473281,-1379027969,-1412582657,-1446137345,-1479692289,-1513247233,-1546802177,-1597134337,-1647466497,-1697798657,-1748130817,-1798463233,-1865572865,-1932682497,-1999792129,-2083678977,2127401215,2043514111,1942849791,1842185215,1724743423,1607301631,1473082367,1338863103,1187866367,1020092415,852318207,667766783,466437887,248331519,13447935,-924398849,-957953793,-991508737,-1025063681,-1058618625,-1092173569,-1142505729,-1192837889,-1243170305,-1293502721,-1343835137,-1410944769,-1478054401,-1545164289,-1629051393,-1712938497,-1796825857,-1897490433,-1998155009,-2098819841,2078705407,1961263103,1827043583,1676046591,1525049599,1357275135,1172723199,971394047,753287423,518403327,283518975,15079935,-570434049,-603988993,-637543937,-671098881,-704653825,-754986241,-805318657,-855651073,-905983489,-973093377,-1040203265,-1107313153,-1174423041,-1258310401,-1342197761,-1442862593,-1543527425,-1644192257,-1761634561,-1879076865,-2013296641,2147450879,1996453631,1828678911,1660904191,1476351999,1275022335,1056915199,822030591,570368511,301928959,16711935,-503325185,-536880129,-570435073,-603990017,-637544961,-671100161,-721432577,-771764993,-822097409,-872430081,-922762753,-989872641,-1056982529,-1124092673,-1191202817,-1275090433,-1358978049,-1459642881,-1560307969,-1660973057,-1778415617,-1895858177,-2030078209,2113891583,1962894079,1795119103,1610566655,1426013951,1224683775,1006576127,771691007,520028415,-452993537,-469771265,-503326209,-536881153,-570436097,-603991297,-637546497,-671101697,-721434113,-771766785,-822099457,-872432129,-922764801,-989874945,-1056985089,-1124095489,-1191205889,-1275093505,-1358981377,-1459646465,-1560311809,-1677754369,-1795197185,-1912640257,-2046860545,2097108991,1946110975,1778335487,1593782527,1392452095,1174344191,939458815,-419439105,-436216833,-452994561,-469772289,-503327233,-536882433,-570437633,-603992833,-637548033,-671103489,-721436161,-771768833,-822101505,-872434433,-922767361,-989877761,-1056988161,-1124098561,-1207986433,-1291874305,-1375762433,-1476427777,-1577093377,-1694536449,-1811979521,-1946200065,-2080420865,2063548159,1912549631,1744773631,1560220159,1358889215,-385884673,-402662401,-419440129,-436217857,-452995585,-469773569,-503328769,-536883969,-570439169,-603994625,-637550081,-671105537,-721438209,-771771137,-822104065,-872437249,-922770433,-989880833,-1056991489,-1124102145,-1191213057,-1275101185,-1358989569,-1459655425,-1560321281,-1677764609,-1795208193,-1912652033,-2046873345,2097095167,1946096127,1778319615,-335553025,-352330753,-369108481,-385886209,-402663937,-419441921,-436219905,-452997889,-486553089,-520108545,-553664001,-587219457,-620774913,-654330625,-687886337,-738219521,-788552705,-838885889,-889219329,-939552769,-1006663681,-1073774593,-1140885761,-1224774401,-1308663041,-1392551937,-1493218305,-1593884929,-1711329025,-1828773377,-1962995201,-2097217281,-285221377,-301999105,-318776833,-335554561,-352332289,-369110273,-385888257,-402666241,-419444225,-436222465,-453000705,-469778945,-503334401,-536890113,-570445825,-604001793,-637557761,-671113729,-721447169,-771780609,-822114305,-872448001,-922781953,-989893377,-1057004801,-1124116481,-1191228417,-1275117825,-1359007489,-1459674625,-1560342017,-1677786881,-234889729,-234890241,-251667969,-268445697,-285223425,-302001409,-318779393,-335557377,-352335361,-369113601,-385891841,-402670081,-419448321,-436226817,-453005313,-469784065,-503340033,-536896001,-570452225,-604008449,-637564929,-671121409,-704678145,-755012353,-805346561,-855681025,-906015745,-973127937,-1040240385,-1107353089,-1174466049,-1258356481,-234889729,-234890241,-234890753,-234891265,-234891777,-234892545,-234893313,-234894081,-234894849,-251673089,-268451329,-285229569,-302007809,-318786305,-335564801,-352343553,-369122305,-385901057,-402680065,-419459073,-436238337,-453017601,-486574337,-520131329,-553688321,-587245569,-620803073,-654360833,-687918849,-738254337,-788590081,-838926081,-234889729,-234890241,-234890753,-234891265,-234891777,-234892545,-234893313,-234894081,-234894849,-234895873,-234896897,-234897921,-234898945,-234900225,-234901505,-234903041,-234904577,-234906113,-234907905,-234909697,-234911745,-251691009,-268470529,-285250305,-302030081,-318810113,-335590401,-352370945,-369151745,-385932801,-402714113,-419495681,-8705,-9217,-9729,-10241,-10753,-11521,-12289,-13057,-13825,-14849,-15873,-16897,-17921,-19201,-20481,-22017,-23553,-25089,-26881,-28673,-30721,-32769,-35073,-37633,-40193,-43009,-46081,-49409,-52993,-56833,-60929,-65281,-926209,-926721,-927233,-927745,-928257,-929025,-929793,-930561,-931329,-932353,-933377,-934401,-935425,-936705,-937985,-939521,-941057,-1008129,-1075457,-1142785,-1210369,-1277953,-1345793,-1413889,-1481985,-1550337,-1618945,-1687809,-1756929,-1826305,-1895937,-2031361,-926209,-926721,-927233,-927745,-928257,-929025,-929793,-996097,-1062401,-1128961,-1195521,-1262081,-1328641,-1395457,-1462273,-1529345,-1596417,-1663489,-1730817,-1798145,-1865729,-1998849,-2132225,-2265857,-2399489,-2533377,-2667521,-2867457,-3067649,-3268097,-3468801,-3669761,-926209,-992257,-1058305,-1124353,-1190401,-1256705,-1323009,-1389313,-1455617,-1522177,-1588737,-1655297,-1721857,-1788673,-1855489,-1988097,-2120705,-2253313,-2386177,-2519041,-2652161,-2785281,-2984193,-3183361,-3382529,-3581953,-3847169,-4112641,-4378369,-4644353,-4976129,-5308161,-1188353,-1254401,-1320449,-1386497,-1452545,-1518849,-1585153,-1651457,-1717761,-1784321,-1850881,-1982977,-2115073,-2247425,-2379777,-2512385,-2644993,-2777601,-2976001,-3174401,-3373057,-3571713,-3836161,-4100865,-4365569,-4630529,-4961281,-5292289,-5689089,-6086145,-6483457,-6946561,-1384961,-1451009,-1517057,-1583105,-1649153,-1715457,-1781761,-1848065,-1979905,-2112001,-2244097,-2376193,-2508289,-2640641,-2838529,-3036673,-3234817,-3432961,-3631361,-3895297,-4159489,-4423681,-4688129,-5018369,-5348609,-5744641,-6140929,-6537473,-6999809,-7462401,-7990785,-8584961,-1581569,-1647617,-1713665,-1779713,-1845761,-1977601,-2109441,-2241281,-2373121,-2505217,-2637313,-2769409,-2967041,-3164929,-3362817,-3560961,-3759105,-4022785,-4286721,-4550657,-4880385,-5210113,-5540097,-5935873,-6331649,-6793217,-7255041,-7782657,-8310529,-8904193,-9563649,-10223361,-1712641,-1778689,-1844737,-1976321,-2107905,-2239745,-2371585,-2503425,-2635265,-2767361,-2964993,-3162625,-3360257,-3558145,-3821569,-4085249,-4348929,-4612609,-4942081,-5271553,-5666817,-6062081,-6457601,-6918913,-7380225,-7907329,-8434689,-9027841,-9686785,-10345985,-11070977,-11861761,-1843713,-1975297,-2106881,-2238465,-2370049,-2501889,-2633729,-2765569,-2962945,-3160577,-3358209,-3555841,-3753473,-4016897,-4280321,-4544001,-4873217,-5202433,-5531905,-5926913,-6322177,-6782977,-7244033,-7770881,-8297729,-8890369,-9548801,-10207489,-10931969,-11722241,-12578305,-13500161,-1974785,-2106369,-2237953,-2369537,-2501121,-2632961,-2830337,-3027713,-3225089,-3422721,-3620353,-3883521,-4146689,-4410113,-4673537,-5002753,-5331969,-5726721,-6121729,-6582273,-7043073,-7503873,-8030465,-8622849,-9215233,-9873409,-10597377,-11387137,-12242689,-13164033,-14085633,-15138561,-2236929,-2368513,-2500097,-2631681,-2763265,-2960641,-3158017,-3355393,-3552769,-3815937,-4079105,-4342273,-4605441,-4934401,-5263361,-5658113,-6052865,-6447617,-6908161,-7368705,-7895041,-8421377,-9013505,-9671425,-10329345,-11053057,-11842561,-12697857,-13618945,-14605825,-15658497,-16776961] \ No newline at end of file diff --git a/release/scripts/flt_dofedit.py b/release/scripts/flt_dofedit.py deleted file mode 100644 index 36e8e4d2501..00000000000 --- a/release/scripts/flt_dofedit.py +++ /dev/null @@ -1,835 +0,0 @@ -#!BPY - -""" -Name: 'FLT DOF Editor' -Blender: 240 -Group: 'Misc' -Tooltip: 'Degree of Freedom editor for FLT nodes' -""" - -__author__ = "Geoffrey Bantle" -__version__ = "1.0 11/21/07" -__email__ = ('scripts', 'Author, ') -__url__ = ('blender', 'blenderartists.org') - -__bpydoc__ ="""\ -This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. - -Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/FLTools -""" - -# -------------------------------------------------------------------------- -# flt_palettemanager.py version 0.1 2005/04/08 -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender.Draw as Draw -from Blender.BGL import * -import Blender -import flt_properties -reload(flt_properties) -from flt_properties import * - -#event codes -evcode = { - "DOF_MAKE" : 100, - "DOF_UPDATE" : 138, - "DOF_DELETE" : 101, - "DOF_TRANSX" : 102, - "DOF_TRANSY" : 103, - "DOF_TRANSZ" : 104, - "DOF_ROTX" : 105, - "DOF_ROTY" : 106, - "DOF_ROTZ" : 107, - "DOF_SCALEX" : 108, - "DOF_SCALEY" : 109, - "DOF_SCALEZ" : 110, - "DOF_MIN_TRANSX" : 111, - "DOF_MIN_TRANSY" : 112, - "DOF_MIN_TRANSZ" : 113, - "DOF_MIN_ROTX" : 114, - "DOF_MIN_ROTY" : 115, - "DOF_MIN_ROTZ" : 116, - "DOF_MIN_SCALEX" : 117, - "DOF_MIN_SCALEY" : 118, - "DOF_MIN_SCALEZ" : 119, - "DOF_MAX_TRANSX" : 120, - "DOF_MAX_TRANSY" : 121, - "DOF_MAX_TRANSZ" : 122, - "DOF_MAX_ROTX" : 123, - "DOF_MAX_ROTY" : 124, - "DOF_MAX_ROTZ" : 125, - "DOF_MAX_SCALEX" : 126, - "DOF_MAX_SCALEY" : 127, - "DOF_MAX_SCALEZ" : 128, - "DOF_STEP_TRANSX" : 129, - "DOF_STEP_TRANSY" : 130, - "DOF_STEP_TRANSZ" : 131, - "DOF_STEP_ROTX" : 132, - "DOF_STEP_ROTY" : 133, - "DOF_STEP_ROTZ" : 134, - "DOF_STEP_SCALEX" : 135, - "DOF_STEP_SCALEY" : 136, - "DOF_STEP_SCALEZ" : 137 -} - -#system -DOF_MAKE = None -DOF_UPDATE = None -DOF_DELETE = None - -#toggle buttons -DOF_TRANSX = None -DOF_TRANSY = None -DOF_TRANSZ = None -DOF_ROTX = None -DOF_ROTY = None -DOF_ROTZ = None -DOF_SCALEX = None -DOF_SCALEY = None -DOF_SCALEZ = None - -#Minimums -DOF_MIN_TRANSX = None -DOF_MIN_TRANSY = None -DOF_MIN_TRANSZ = None -DOF_MIN_ROTX = None -DOF_MIN_ROTY = None -DOF_MIN_ROTZ = None -DOF_MIN_SCALEX = None -DOF_MIN_SCALEY = None -DOF_MIN_SCALEZ = None - -#maximums -DOF_MAX_TRANSX = None -DOF_MAX_TRANSY = None -DOF_MAX_TRANSZ = None -DOF_MAX_ROTX = None -DOF_MAX_ROTY = None -DOF_MAX_ROTZ = None -DOF_MAX_SCALEX = None -DOF_MAX_SCALEY = None -DOF_MAX_SCALEZ = None - -#step -DOF_STEP_TRANSX = None -DOF_STEP_TRANSY = None -DOF_STEP_TRANSZ = None -DOF_STEP_ROTX = None -DOF_STEP_ROTY = None -DOF_STEP_ROTZ = None -DOF_STEP_SCALEX = None -DOF_STEP_SCALEY = None -DOF_STEP_SCALEZ = None - -#labels -DOF_ROTSTRING = None -DOF_TRANSTRING = None -DOF_SCALESTRING = None -DOF_EDITLABEL = None - -#make ID props easier/morereadable -zmin = '14d!ZMIN' -zmax = '15d!ZMAX' -zcur = '16d!ZCUR' -zstep = '17d!ZSTEP' -ymin = '18d!YMIN' -ymax = '19d!YMAX' -ycur = '20d!YCUR' -ystep = '21d!YSTEP' -xmin = '22d!XMIN' -xmax = '23d!XMAX' -xcur = '24d!XCUR' -xstep = '25d!XSTEP' -pitchmin = '26d!PITCH-MIN' -pitchmax = '27d!PITCH-MAX' -pitchcur = '28d!PITCH-CUR' -pitchstep = '29d!PITCH-STEP' -rollmin = '30d!ROLL-MIN' -rollmax = '31d!ROLL-MAX' -rollcur = '32d!ROLL-CUR' -rollstep = '33d!ROLL-STEP' -yawmin = '34d!YAW-MIN' -yawmax = '35d!YAW-MAX' -yawcur = '36d!YAW-CUR' -yawstep = '37d!YAW-STEP' -zscalemin = '38d!ZSIZE-MIN' -zscalemax = '39d!ZSIZE-MAX' -zscalecur = '40d!ZSIZE-CUR' -zscalestep = '41d!ZSIZE-STEP' -yscalemin = '42d!YSIZE-MIN' -yscalemax = '43d!YSIZE-MAX' -yscalecur = '44d!YSIZE-CUR' -yscalestep = '45d!YSIZE-STEP' -xscalemin = '46d!XSIZE-MIN' -xscalemax = '47d!XSIZE-MAX' -xscalecur = '48d!XSIZE-CUR' -xscalestep = '49d!XSIZE-STEP' - - - -def update_state(): - state = dict() - state["activeScene"] = Blender.Scene.GetCurrent() - state["activeObject"] = state["activeScene"].objects.active - if state["activeObject"] and not state["activeObject"].sel: - state["activeObject"] = None - state["activeMesh"] = None - if state["activeObject"] and state["activeObject"].type == 'Mesh': - state["activeMesh"] = state["activeObject"].getData(mesh=True) - - - state["activeFace"] = None - if state["activeMesh"]: - if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None: - state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace] - - - #update editmode - state["editmode"] = Blender.Window.EditMode() - - return state - -def idprops_append(object, typecode, props): - object.properties["FLT"] = dict() - object.properties["FLT"]['type'] = typecode - for prop in props: - object.properties["FLT"][prop] = props[prop] - object.properties["FLT"]['3t8!id'] = object.name - -def idprops_kill(): - state = update_state() - if state["activeObject"] and state["activeObject"].properties.has_key('FLT'): - state["activeObject"].properties.pop('FLT') - -def idprops_copy(source): - state = update_state() - if source.properties.has_key('FLT'): - for object in state["activeScene"].objects: - if object.sel and object != source and (state["activeScene"].Layers & object.Layers): - idprops_kill(object) - object.properties['FLT'] = dict() - for key in source.properties['FLT']: - object.properties['FLT'][key] = source.properties['FLT'][key] - -def select_by_typecode(typecode): - state = update_state() - - for object in state["activeScene"].objects: - if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers: - object.select(1) - -def DOF_get_frame(): - state = update_state() - - if not state["activeObject"] and not id_props_type(state["activeObject"], 14): - return - - #Warning! assumes 1 BU == 10 meters. - #do origin - state["activeObject"].properties['FLT']['5d!ORIGX'] = state["activeObject"].getLocation('worldspace')[0]*10.0 - state["activeObject"].properties['FLT']['6d!ORIGY'] = state["activeObject"].getLocation('worldspace')[1]*10.0 - state["activeObject"].properties['FLT']['7d!ORIGZ'] = state["activeObject"].getLocation('worldspace')[2]*10.0 - #do X axis - x = Blender.Mathutils.Vector(1.0,0.0,0.0) - x = x * state["activeObject"].getMatrix('worldspace') - x = x * 10.0 - state["activeObject"].properties['FLT']['8d!XAXIS-X'] = x[0] - state["activeObject"].properties['FLT']['9d!XAXIS-Y'] = x[1] - state["activeObject"].properties['FLT']['10d!XAXIS-Z'] = x[2] - #do X/Y plane - x = Blender.Mathutils.Vector(0.0,1.0,0.0) - x.normalize() - x = x * state["activeObject"].getMatrix('worldspace') - x = x * 10.0 - state["activeObject"].properties['FLT']['11d!XYPLANE-X'] = x[0] - state["activeObject"].properties['FLT']['12d!XYPLANE-Y'] = x[1] - state["activeObject"].properties['FLT']['13d!XZPLANE-Z'] = x[2] - -def idprops_type(object, typecode): - if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode: - return True - return False - -#ui type code -def get_prop(typecode, prop): - - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], typecode): - props = state["activeObject"].properties['FLT'] - else: - props = flt_properties.FLTDOF - - return props[prop] - -def set_prop(typecode, prop, value): - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"],typecode): - state["activeObject"].properties['FLT'][prop] = value - -lockxtrans = (1 << 31) -lockytrans = (1 << 30) -lockztrans = (1 << 29) -lockxrot = (1 << 28) -lockyrot = (1 << 27) -lockzrot = (1 << 26) -lockxscale = (1 << 25) -lockyscale = (1 << 24) -lockzscale = (1 << 23) - -def get_lockmask(mask): - state = update_state() - if state["activeObject"]: - flag = get_prop(14,'50I!FLAG') - if flag & mask: - return True - return False - -def set_lockmask(mask): - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], 14): - oldvalue = state["activeObject"].properties['FLT']['50I!FLAG'] - oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0] - oldvalue |= mask - state["activeObject"].properties['FLT']['50I!FLAG'] = struct.unpack('>i', struct.pack(">I", oldvalue))[0] - -def clear_lockmask(mask): - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], 14): - oldvalue = state["activeObject"].properties['FLT']['50I!FLAG'] - oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0] - oldvalue &= ~mask - state["activeObject"].properties['FLT']['50I!FLAG'] = struct.unpack('>i',struct.pack('>I',oldvalue))[0] - - -def create_dof(): - state = update_state() - actobj = state["activeObject"] - if actobj and not idprops_type(actobj, 14): - idprops_kill() - idprops_append(actobj,14, flt_properties.FLTDOF) - DOF_get_frame() - - -def event(evt,val): - if evt == Draw.ESCKEY: - Draw.Exit() - -def but_event(evt): - global DOF_MAKE - global DOF_UPDATE - global DOF_DELETE - - global DOF_TRANSX - global DOF_TRANSY - global DOF_TRANSZ - global DOF_ROTX - global DOF_ROTY - global DOF_ROTZ - global DOF_SCALEX - global DOF_SCALEY - global DOF_SCALEZ - - global DOF_MIN_TRANSX - global DOF_MIN_TRANSY - global DOF_MIN_TRANSZ - global DOF_MIN_ROTX - global DOF_MIN_ROTY - global DOF_MIN_ROTZ - global DOF_MIN_SCALEX - global DOF_MIN_SCALEY - global DOF_MIN_SCALEZ - - global DOF_MAX_TRANSX - global DOF_MAX_TRANSY - global DOF_MAX_TRANSZ - global DOF_MAX_ROTX - global DOF_MAX_ROTY - global DOF_MAX_ROTZ - global DOF_MAX_SCALEX - global DOF_MAX_SCALEY - global DOF_MAX_SCALEZ - - global DOF_STEP_TRANSX - global DOF_STEP_TRANSY - global DOF_STEP_TRANSZ - global DOF_STEP_ROTX - global DOF_STEP_ROTY - global DOF_STEP_ROTZ - global DOF_STEP_SCALEX - global DOF_STEP_SCALEY - global DOF_STEP_SCALEZ - - #labels - global DOF_ROTSTRING - global DOF_TRANSTRING - global DOF_SCALESTRING - - - #masks - global lockxtrans - global lockytrans - global lockztrans - global lockxrot - global lockyrot - global lockzrot - global lockxscale - global lockyscale - global lockzscale - - global zmin - global zmax - global zcur - global zstep - global ymin - global ymax - global ycur - global ystep - global xmin - global xmax - global xcur - global xstep - global pitchmin - global pitchmax - global pitchcur - global pitchstep - global rollmin - global rollmax - global rollcur - global rollstep - global yawmin - global yawmax - global yawcur - global yawstep - global zscalemin - global zscalemax - global zscalecur - global zscalestep - global yscalemin - global yscalemax - global yscalecur - global yscalestep - global xscalemin - global xscalemax - global xscalecur - global xscalestep - - - - #do "system" events - if evt == evcode["DOF_MAKE"]: - create_dof() - - if evt == evcode["DOF_UPDATE"]: - DOF_get_frame() - - if evt == evcode["DOF_DELETE"]: - idprops_kill() - #do translation lock events - if evt == evcode["DOF_TRANSX"]: - if DOF_TRANSX.val == True: - set_lockmask(lockxtrans) - else: - clear_lockmask(lockxtrans) - - if evt == evcode["DOF_TRANSY"]: - if DOF_TRANSY.val == True: - set_lockmask(lockytrans) - else: - clear_lockmask(lockytrans) - - if evt == evcode["DOF_TRANSZ"]: - if DOF_TRANSZ.val == True: - set_lockmask(lockztrans) - else: - clear_lockmask(lockztrans) - - - #do rotation lock events - if evt == evcode["DOF_ROTX"]: - if DOF_ROTX.val == True: - set_lockmask(lockxrot) - else: - clear_lockmask(lockxrot) - - if evt == evcode["DOF_ROTY"]: - if DOF_ROTY.val == True: - set_lockmask(lockyrot) - else: - clear_lockmask(lockyrot) - - if evt == evcode["DOF_ROTZ"]: - if DOF_ROTZ.val == True: - set_lockmask(lockzrot) - else: - clear_lockmask(lockzrot) - - #do scale lock events - if evt == evcode["DOF_SCALEX"]: - if DOF_SCALEX.val == True: - set_lockmask(lockxscale) - else: - clear_lockmask(lockxscale) - - if evt == evcode["DOF_SCALEY"]: - if DOF_SCALEY.val == True: - set_lockmask(lockyscale) - else: - clear_lockmask(lockyscale) - - if evt == evcode["DOF_SCALEZ"]: - if DOF_SCALEZ.val == True: - set_lockmask(lockzscale) - else: - clear_lockmask(lockzscale) - - - #do translation buttons - if evt == evcode["DOF_MIN_TRANSX"]: - set_prop(14, xmin, DOF_MIN_TRANSX.val) - if evt == evcode["DOF_MAX_TRANSX"]: - set_prop(14,xmax, DOF_MAX_TRANSX.val) - if evt == evcode["DOF_STEP_TRANSX"]: - set_prop(14,xstep, DOF_STEP_TRANSX.val) - - if evt == evcode["DOF_MIN_TRANSY"]: - set_prop(14, ymin, DOF_MIN_TRANSY.val) - if evt == evcode["DOF_MAX_TRANSY"]: - set_prop(14,ymax, DOF_MAX_TRANSY.val) - if evt == evcode["DOF_STEP_TRANSY"]: - set_prop(14,ystep, DOF_STEP_TRANSY.val) - - if evt == evcode["DOF_MIN_TRANSZ"]: - set_prop(14, zmin, DOF_MIN_TRANSZ.val) - if evt == evcode["DOF_MAX_TRANSZ"]: - set_prop(14, zmax, DOF_MAX_TRANSZ.val) - if evt == evcode["DOF_STEP_TRANSZ"]: - set_prop(14, zstep, DOF_STEP_TRANSZ.val) - - #do rotation buttons - if evt == evcode["DOF_MIN_ROTX"]: - set_prop(14, pitchmin, DOF_MIN_ROTX.val) - if evt == evcode["DOF_MAX_ROTX"]: - set_prop(14, pitchmax, DOF_MAX_ROTX.val) - if evt == evcode["DOF_STEP_ROTX"]: - set_prop(14, pitchstep, DOF_STEP_ROTX.val) - - if evt == evcode["DOF_MIN_ROTY"]: - set_prop(14, rollmin, DOF_MIN_ROTY.val) - if evt == evcode["DOF_MAX_ROTY"]: - set_prop(14, rollmax, DOF_MAX_ROTY.val) - if evt == evcode["DOF_STEP_ROTY"]: - set_prop(14, rollstep, DOF_STEP_ROTY.val) - - if evt == evcode["DOF_MIN_ROTZ"]: - set_prop(14, yawmin, DOF_MIN_ROTZ.val) - if evt == evcode["DOF_MAX_ROTZ"]: - set_prop(14, yawmax, DOF_MAX_ROTZ.val) - if evt == evcode["DOF_STEP_ROTZ"]: - set_prop(14, yawstep, DOF_STEP_ROTZ.val) - - #do scale buttons - if evt == evcode["DOF_MIN_SCALEX"]: - set_prop(14, xscalemin, DOF_MIN_SCALEX.val) - if evt == evcode["DOF_MAX_SCALEX"]: - set_prop(14, xscalemax, DOF_MAX_SCALEX.val) - if evt == evcode["DOF_STEP_SCALEX"]: - set_prop(14, xscalestep, DOF_STEP_SCALEX.val) - - if evt == evcode["DOF_MIN_SCALEY"]: - set_prop(14, yscalemin, DOF_MIN_SCALEY.val) - if evt == evcode["DOF_MAX_SCALEY"]: - set_prop(14, yscalemax, DOF_MAX_SCALEY.val) - if evt == evcode["DOF_STEP_SCALEY"]: - set_prop(14, yscalestep, DOF_STEP_SCALEY.val) - - if evt == evcode["DOF_MIN_SCALEZ"]: - set_prop(14, zscalemin, DOF_MIN_SCALEZ.val) - if evt == evcode["DOF_MAX_SCALEZ"]: - set_prop(14, zscalemax, DOF_MAX_SCALEZ.val) - if evt == evcode["DOF_STEP_SCALEZ"]: - set_prop(14, zscalestep, DOF_STEP_SCALEZ.val) - - - Draw.Redraw(1) - Blender.Window.RedrawAll() - -def draw_propsheet(x,y): - #UI buttons - global DOF_MAKE - global DOF_UPDATE - global DOF_DELETE - - global DOF_TRANSX - global DOF_TRANSY - global DOF_TRANSZ - global DOF_ROTX - global DOF_ROTY - global DOF_ROTZ - global DOF_SCALEX - global DOF_SCALEY - global DOF_SCALEZ - - global DOF_MIN_TRANSX - global DOF_MIN_TRANSY - global DOF_MIN_TRANSZ - global DOF_MIN_ROTX - global DOF_MIN_ROTY - global DOF_MIN_ROTZ - global DOF_MIN_SCALEX - global DOF_MIN_SCALEY - global DOF_MIN_SCALEZ - - global DOF_MAX_TRANSX - global DOF_MAX_TRANSY - global DOF_MAX_TRANSZ - global DOF_MAX_ROTX - global DOF_MAX_ROTY - global DOF_MAX_ROTZ - global DOF_MAX_SCALEX - global DOF_MAX_SCALEY - global DOF_MAX_SCALEZ - - global DOF_STEP_TRANSX - global DOF_STEP_TRANSY - global DOF_STEP_TRANSZ - global DOF_STEP_ROTX - global DOF_STEP_ROTY - global DOF_STEP_ROTZ - global DOF_STEP_SCALEX - global DOF_STEP_SCALEY - global DOF_STEP_SCALEZ - - #labels - global DOF_ROTSTRING - global DOF_TRANSTRING - global DOF_SCALESTRING - global DOF_EDITLABEL - - #masks - global lockxtrans - global lockytrans - global lockztrans - global lockxrot - global lockyrot - global lockzrot - global lockxscale - global lockyscale - global lockzscale - - global zmin - global zmax - global zcur - global zstep - global ymin - global ymax - global ycur - global ystep - global xmin - global xmax - global xcur - global xstep - global pitchmin - global pitchmax - global pitchcur - global pitchstep - global rollmin - global rollmax - global rollcur - global rollstep - global yawmin - global yawmax - global yawcur - global yawstep - global zscalemin - global zscalemax - global zscalecur - global zscalestep - global yscalemin - global yscalemax - global yscalecur - global yscalestep - global xscalemin - global xscalemax - global xscalecur - global xscalestep - - - global evcode - - state = update_state() - - row_height = 20 - toggle_width = 50 - input_width = 100 - pad = 10 - origx = x - origy = (row_height * 15) + (pad * 15) - - - #editor label - x = origx - y = origy - #y = y - (row_height + pad) - DOF_EDITLABEL = Blender.Draw.Label("FLT Degree of Freedom Editor", x, y, 200, row_height) - - - #draw Translation limits - x = origx - y = y- (row_height + pad) - DOF_TRANSTRING = Blender.Draw.Label("Translation Limits", x, y, input_width, row_height) - - - #X limits - x = origx - y = y- (row_height + pad) - DOF_TRANSX = Blender.Draw.Toggle("LimX", evcode["DOF_TRANSX"], x, y, toggle_width, row_height, get_lockmask(lockxtrans), "") - x = x + (toggle_width + pad) - DOF_MIN_TRANSX = Blender.Draw.Number("MinX", evcode["DOF_MIN_TRANSX"], x, y, input_width, row_height,get_prop(14,xmin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_TRANSX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_TRANSX"], x, y, input_width, row_height,get_prop(14,xmax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_TRANSX = Blender.Draw.Number("StepX", evcode["DOF_STEP_TRANSX"], x, y, input_width, row_height,get_prop(14,xstep), -1000000.0, 1000000.0, "") - - #Y limits - x = origx - y = y- (row_height + pad) - DOF_TRANSY = Blender.Draw.Toggle("LimY", evcode["DOF_TRANSY"], x, y, toggle_width, row_height, get_lockmask(lockytrans), "") - x = x + (toggle_width + pad) - DOF_MIN_TRANSY = Blender.Draw.Number("MinY", evcode["DOF_MIN_TRANSY"], x, y, input_width, row_height, get_prop(14,ymin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_TRANSY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_TRANSY"], x, y, input_width, row_height, get_prop(14,ymax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_TRANSY = Blender.Draw.Number("StepY", evcode["DOF_STEP_TRANSY"], x, y, input_width, row_height, get_prop(14,ystep), -1000000.0, 1000000.0, "") - - #Z limits - x = origx - y = y- (row_height + pad) - DOF_TRANSZ = Blender.Draw.Toggle("LimZ", evcode["DOF_TRANSZ"], x, y, toggle_width, row_height, get_lockmask(lockztrans), "") - x = x + (toggle_width + pad) - DOF_MIN_TRANSZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_TRANSZ"], x, y, input_width, row_height, get_prop(14,zmin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_TRANSZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_TRANSZ"], x, y, input_width, row_height, get_prop(14,zmax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_TRANSZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_TRANSZ"], x, y, input_width, row_height, get_prop(14,zstep), -1000000.0, 1000000.0, "") - - #draw Rotation limits - x = origx - y = y- (row_height + pad) - DOF_ROTSTRING = Blender.Draw.Label("Rotation Limits", x, y, input_width, row_height) - - #draw Rotation limits - #X limits - x = origx - y = y- (row_height + pad) - DOF_ROTX = Blender.Draw.Toggle("LimX", evcode["DOF_ROTX"], x, y, toggle_width, row_height, get_lockmask(lockxrot), "") - x = x + (toggle_width + pad) - DOF_MIN_ROTX = Blender.Draw.Number("MinX", evcode["DOF_MIN_ROTX"], x, y, input_width, row_height, get_prop(14,pitchmin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_ROTX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_ROTX"], x, y, input_width, row_height, get_prop(14,pitchmax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_ROTX = Blender.Draw.Number("StepX", evcode["DOF_STEP_ROTX"], x, y, input_width, row_height, get_prop(14,pitchstep), -1000000.0, 1000000.0, "") - - #Y limits - x = origx - y = y- (row_height + pad) - DOF_ROTY = Blender.Draw.Toggle("LimY", evcode["DOF_ROTY"], x, y, toggle_width, row_height, get_lockmask(lockyrot), "") - x = x + (toggle_width + pad) - DOF_MIN_ROTY = Blender.Draw.Number("MinY", evcode["DOF_MIN_ROTY"], x, y, input_width, row_height, get_prop(14,rollmin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_ROTY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_ROTY"], x, y, input_width, row_height, get_prop(14,rollmax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_ROTY = Blender.Draw.Number("StepY", evcode["DOF_STEP_ROTY"], x, y, input_width, row_height, get_prop(14,rollstep), -1000000.0, 1000000.0, "") - - #Z limits - x = origx - y = y- (row_height + pad) - DOF_ROTZ = Blender.Draw.Toggle("LimZ", evcode["DOF_ROTZ"], x, y, toggle_width, row_height, get_lockmask(lockzrot), "") - x = x + (toggle_width + pad) - DOF_MIN_ROTZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_ROTZ"], x, y, input_width, row_height, get_prop(14, yawmin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_ROTZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_ROTZ"], x, y, input_width, row_height, get_prop(14, yawmax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_ROTZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_ROTZ"], x, y, input_width, row_height, get_prop(14, yawstep), -1000000.0, 1000000.0, "") - - - #draw Scale limits - x = origx - y = y- (row_height + pad) - DOF_SCALESTRING = Blender.Draw.Label("Scale Limits", x, y, input_width, row_height) - - #draw Scale limits - #X limits - x = origx - y = y- (row_height + pad) - DOF_SCALEX = Blender.Draw.Toggle("LimX", evcode["DOF_SCALEX"], x, y, toggle_width, row_height, get_lockmask(lockxscale), "") - x = x + (toggle_width + pad) - DOF_MIN_SCALEX = Blender.Draw.Number("MinX", evcode["DOF_MIN_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalemin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_SCALEX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalemax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_SCALEX = Blender.Draw.Number("StepX", evcode["DOF_STEP_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalestep), -1000000.0, 1000000.0, "") - - #Y limits - x = origx - y = y- (row_height + pad) - DOF_SCALEY = Blender.Draw.Toggle("LimY", evcode["DOF_SCALEY"], x, y, toggle_width, row_height, get_lockmask(lockyscale), "") - x = x + (toggle_width + pad) - DOF_MIN_SCALEY = Blender.Draw.Number("MinY", evcode["DOF_MIN_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalemin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_SCALEY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalemax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_SCALEY = Blender.Draw.Number("StepY", evcode["DOF_STEP_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalestep), -1000000.0, 1000000.0, "") - - #Z limits - x = origx - y = y- (row_height + pad) - DOF_SCALEZ = Blender.Draw.Toggle("LimZ", evcode["DOF_SCALEZ"], x, y, toggle_width, row_height, get_lockmask(lockzscale), "") - x = x + (toggle_width + pad) - DOF_MIN_SCALEZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalemin), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_MAX_SCALEZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalemax), -1000000.0, 1000000.0, "") - x = x + (input_width + pad) - DOF_STEP_SCALEZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalestep), -1000000.0, 1000000.0, "") - - #System - x = origx - y = y - (row_height + (pad)*3) - DOF_MAKE = Blender.Draw.PushButton("Make DOF", evcode["DOF_MAKE"], x, y, input_width, row_height, "Make a Dof Node out of Active Object") - x = x + (input_width + pad) - DOF_UPDATE = Blender.Draw.PushButton("Grab Loc/Rot", evcode["DOF_UPDATE"], x, y, input_width, row_height, "Update the Dof Node position/orientation") - x = x + (input_width + pad) - DOF_DELETE = Blender.Draw.PushButton("Delete DOF", evcode["DOF_DELETE"], x, y, input_width, row_height, "Delete the Dof Node properties") - - - - -def gui(): - #draw the propsheet/toolbox. - psheety = 800 - #psheetx = psheety + 10 - draw_propsheet(20,psheety) - -Draw.Register(gui,event,but_event) - \ No newline at end of file diff --git a/release/scripts/flt_export.py b/release/scripts/flt_export.py deleted file mode 100644 index c099c8e62d1..00000000000 --- a/release/scripts/flt_export.py +++ /dev/null @@ -1,1697 +0,0 @@ -#!BPY -""" Registration info for Blender menus: -Name: 'OpenFlight (.flt)...' -Blender: 245 -Group: 'Export' -Tip: 'Export to OpenFlight v16.0 (.flt)' -""" - -__author__ = "Greg MacDonald, Geoffrey Bantle" -__version__ = "2.0 11/21/07" -__url__ = ("blender", "blenderartists.org", "Author's homepage, http://sourceforge.net/projects/blight/") -__bpydoc__ = """\ -This script exports v16.0 OpenFlight files. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. - -Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/Export/openflight_flt -""" - -# flt_export.py is an OpenFlight exporter for blender. -# -# Copyright (C) 2005 Greg MacDonald, 2007 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. - -import Blender -from Blender import Modifier -import os.path -import flt_properties -import flt_defaultp as defaultp -from flt_filewalker import FltOut -from flt_filewalker import FileFinder -from flt_properties import * -import shutil -import trace -import sys - -FF = FileFinder() -records = process_recordDefs() - -class ExporterOptions: - - def read_state(self): - reg = Blender.Registry.GetKey('flt_export',1) - if reg: - for key in self.state: - if reg.has_key(key): - self.state[key] = reg[key] - - def write_state(self): - d = dict() - for key in self.state: - d[key] = self.state[key] - Blender.Registry.SetKey('flt_export', d, 1) - def __init__(self): - self.verbose = 1 - self.tolerance = 0.001 - self.writevcol = True - - self.state = {'export_shading' : 0, - 'shading_default' : 45, - 'basepath' : os.path.dirname(Blender.Get('filename')), - 'scale': 1.0, - 'doxrefs' : 1, - 'attrib' : 0, - 'copytex' : 0, - 'transform' : 0, - 'xapp' : 1} - - #default externals path - if(os.path.exists(os.path.join(self.state['basepath'],'externals'))): - self.state['externalspath'] = os.path.join(self.state['basepath'],'externals') - else: - self.state['externalspath'] = self.state['basepath'] - - if(os.path.exists(os.path.join(self.state['basepath'],'textures'))): - self.state['texturespath'] = os.path.join(self.state['basepath'],'textures') - else: - self.state['texturespath'] = self.state['basepath'] - - self.state['xappath'] = '' - self.read_state() #read from registry - - -options = ExporterOptions() -tex_files = dict() #a list of (possibly) modified texture path names - -tex_layers = ['Layer0', 'Layer1', 'Layer2', 'Layer3', 'Layer4', 'Layer5', 'Layer6', 'Layer7'] -mask = 2147483648 -mtexmasks = [] -for i in xrange(7): - mtexmasks.append(mask) - mask = mask / 2 - -FLOAT_TOLERANCE = options.tolerance - -#need to move all this stuff to flt_properties.py. -identity_matrix = [[1.0, 0.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, 1.0]] -alltypes = [2,4,14,11,73,63,111] -childtypes = { - 2 : [111,2,73,4,14,63], - 4 : [111], - 73 : [111,2,73,4,14,63], - 63 : [], - 14 : [111,2,73,4,14,63], - 111 : [] -} -recordlen = { - 2: 44, - 4: 28, - 73: 80, - 63: 216, - 14: 384, - 111: 156 -} - -def is_identity(m): - for i in xrange(4): - for j in xrange(4): - if abs(m[i][j] - identity_matrix[i][j]) > FLOAT_TOLERANCE: - return False - return True - -class MaterialDesc: - def __init__(self): - self.name = 'Blender' - - # Colors, List of 3 floats. - self.diffuse = [1.0, 1.0, 1.0] - self.specular = [1.0, 1.0, 1.0] - - # Scalars - self.ambient = 0.1 # [0.0, 1.0] - self.emissive = 0.0 # [0.0, 1.0] - self.shininess = 32.0 # Range is [0.0, 128.0] - self.alpha = 1.0 # Range is [0.0, 1.0] - -class VertexDesc: - def __init__(self, co=None, no=None, uv=None, fltindex=None,cindex=None): - if co: self.x, self.y, self.z = tuple(co) - else: self.x = self.y = self.z = 0.0 - if no: self.nx, self.ny, self.nz = tuple(no) - else: self.nx = self.ny = self.nz = 0.0 - if uv: self.u, self.v = tuple(uv) - else: self.u = self.v = 0.0 - if cindex: self.cindex = cindex - else: self.cindex = 127 - self.fltindex = fltindex - self.accum = 0 - -class shadowVert: - def __init__(self,bvert,object,world,normal): - global options - - self.co = Blender.Mathutils.Vector(bvert.co[0],bvert.co[1],bvert.co[2]) - #if world: - # vec = self.co - # vec = Blender.Mathutils.Vector(vec[0] * options.scale, vec[1] * options.scale, vec[2] * options.scale) #scale - # self.co = Blender.Mathutils.TranslationMatrix(vec) * (self.co * object.getMatrix('worldspace')) - - if normal: - #if world: - # self.no = Blender.Mathutils.Vector(normal * object.getMatrix('worldspace')).normalize() - #else: - self.no = Blender.Mathutils.Vector(normal[0],normal[1],normal[2]) - - else: - #if world: - #self.no = Blender.Mathutils.Vector(bvert.no * object.getMatrix('worldspace')).normalize() - #else: - self.no = Blender.Mathutils.Vector(bvert.no[0],bvert.no[1],bvert.no[2]) - - #do scaling factor - #if options.scale != 1.0: - #self.co[0] = self.co[0] * options.scale - #self.co[1] = self.co[1] * options.scale - #self.co[2] = self.co[2] * options.scale - - self.index = bvert.index - -class GlobalResourceRepository: - def new_face_name(self): - self.face_name += 1 - return 'f%i' % (self.face_name-1) - - def vertex_count(self): - return len(self.vertex_lst) - - def request_vertex_desc(self, i): - return self.vertex_lst[i] - - def request_vertex_index(self, object, mesh, face, vfindex, uvok,cindex): - - flatShadeNorm = None - vno = None - - - if type(face) is list: - vertex = face[vfindex] - elif str(type(face)) == "": - vertex = face - vno = Blender.Mathutils.Vector(0.0,0.0,1.0) - elif str(type(face)) == "": - if vfindex == 1: - vertex = face.v1 - elif vfindex == 2: - vertex = face.v2 - elif str(type(face)) == "": - if not face.smooth: - flatShadeNorm = face.no - vertex = face.v[vfindex] - else: - return None - - if not self.namehash.has_key(object.name): - self.namehash[object.name] = dict() - indexhash = self.namehash[object.name] - - #export in global space? THIS HAS BEEN MADE REDUNDANT... REMOVE ME - if not options.state['transform']: - vertex = shadowVert(vertex,object,True,flatShadeNorm) - else: - vertex = shadowVert(vertex,object,False,flatShadeNorm) - - if vno: - vertex.no = vno - - - #Check to see if this vertex has been visited before. If not, add - if not indexhash.has_key(vertex.index): - if uvok: - newvdesc = VertexDesc(vertex.co, vertex.no, face.uv[vfindex], self.nextvindex,cindex=cindex) - else: - newvdesc = VertexDesc(co=vertex.co, no=vertex.no,fltindex=self.nextvindex,cindex=cindex) - - indexhash[vertex.index] = [newvdesc] - self.vertex_lst.append(newvdesc) - self.nextvindex = self.nextvindex + 1 - return newvdesc.fltindex - - else: - desclist = indexhash[vertex.index] - if uvok: - faceu = face.uv[vfindex][0] - facev = face.uv[vfindex][1] - else: - faceu = 0.0 - facev = 0.0 - for vdesc in desclist: - if\ - abs(vdesc.x - vertex.co[0]) > FLOAT_TOLERANCE or\ - abs(vdesc.y - vertex.co[1]) > FLOAT_TOLERANCE or\ - abs(vdesc.z - vertex.co[2]) > FLOAT_TOLERANCE or\ - abs(vdesc.nx - vertex.no[0]) > FLOAT_TOLERANCE or\ - abs(vdesc.ny - vertex.no[1]) > FLOAT_TOLERANCE or\ - abs(vdesc.nz - vertex.no[2]) > FLOAT_TOLERANCE or\ - vdesc.cindex != cindex or\ - abs(vdesc.u - faceu) > FLOAT_TOLERANCE or\ - abs(vdesc.v - facev) > FLOAT_TOLERANCE: - pass - else: - return vdesc.fltindex - - #if we get this far, we didnt find a match. Add a new one and return - if uvok: - newvdesc = VertexDesc(vertex.co, vertex.no, face.uv[vfindex], self.nextvindex,cindex=cindex) - else: - newvdesc = VertexDesc(co=vertex.co, no=vertex.no,fltindex=self.nextvindex,cindex=cindex) - indexhash[vertex.index].append(newvdesc) - self.vertex_lst.append(newvdesc) - self.nextvindex = self.nextvindex + 1 - return newvdesc.fltindex - - - def request_texture_index(self, image): - match = None - for i in xrange(len(self.texture_lst)): - if self.texture_lst[i] != image: - continue - match = i - break - if match != None: - return match - else: - self.texture_lst.append(image) - return len(self.texture_lst) - 1 - - def request_texture_filename(self, index): - return Blender.sys.expandpath(self.texture_lst[index].getFilename()) - - def texture_count(self): - return len(self.texture_lst) - - def request_material_index(self, desc): - match = None - for i in xrange(len(self.material_lst)): - if self.material_lst[i].diffuse != desc.diffuse: - continue - if self.material_lst[i].specular != desc.specular: - continue - if self.material_lst[i].ambient != desc.ambient: - continue - if self.material_lst[i].emissive != desc.emissive: - continue - if self.material_lst[i].shininess != desc.shininess: - continue - if self.material_lst[i].alpha != desc.alpha: - continue - match = i - break - - if match != None: - return i - else: - self.material_lst.append(desc) - return len(self.material_lst) - 1 - - def request_material_desc(self, index): - return self.material_lst[index] - - def material_count(self): - return len(self.material_lst) - - # Returns not actual index but one that includes intensity information. - # color_index = 127*intensity + 128*actual_index - def request_color_index(self, col): - r,g,b = tuple(col) - m = max(r, g, b) - if m > 0.0: - intensity = m / 1.0 - r = int(round(r/m * 255.0)) - g = int(round(g/m * 255.0)) - b = int(round(b/m * 255.0)) - brightest = [r, g, b] - else: - brightest = [255, 255, 255] - intensity = 0.0 - - match = None - for i in xrange(len(self.color_lst)): - if self.color_lst[i] != brightest: - continue - - match = i - break - - if match != None: - index = match - else: - length = len(self.color_lst) - if length <= 1024: - self.color_lst.append(brightest) - index = length - else: - if options.verbose >= 1: - print 'Warning: Exceeded max color limit.' - index = 0 - - color_index = int(round(127.0*intensity)) + 128*index - return color_index - - # Returns color from actual index. - def request_max_color(self, index): - return self.color_lst[index] - - def color_count(self): - return len(self.color_lst) - - def __init__(self): - #Vertex handling - self.vertex_lst = [] - self.nextvindex = 0 - self.namehash = dict() - - self.texture_lst = [] - self.material_lst = [] - self.color_lst = [[255, 255, 255]] - self.face_name = 0 - -class Node: - # Gathers info from blender needed for export. - # The =[0] is a trick to emulate c-like static function variables - # that are persistant between calls. - def blender_export(self, level=[0]): - if self.object: - if options.verbose >= 2: - print '\t' * level[0], self.name, self.object.type - level[0] += 1 - - self.children.reverse() - for child in self.children: - child.blender_export() - - level[0] -= 1 - - # Exports this node's info to file. - def write(self): - pass - - def write_matrix(self): - if self.matrix and not is_identity(self.matrix): - self.header.fw.write_short(49) # Matrix opcode - self.header.fw.write_ushort(68) # Length of record - for i in xrange(4): - for j in xrange(4): - self.header.fw.write_float(self.matrix[i][j]) - - def write_push(self): - self.header.fw.write_short(10) - self.header.fw.write_ushort(4) - - def write_pop(self): - self.header.fw.write_short(11) - self.header.fw.write_ushort(4) - - def write_push_extension(self): - self.header.fw.write_short(21) - self.header.fw.write_ushort(24) - self.header.fw.pad(18) - self.header.fw.write_ushort(0) - - def write_pop_extension(self): - self.header.fw.write_short(22) - self.header.fw.write_ushort(24) - self.header.fw.pad(18) - self.header.fw.write_ushort(0) - - def write_longid(self, name): - length = len(name) - if length >= 8: - self.header.fw.write_short(33) # Long ID opcode - self.header.fw.write_ushort(length+5) # Length of record - self.header.fw.write_string(name, length+1) # name + zero terminator - - def write_comment(self,comment): - length = len(comment) - if length >= 65535: - comment = comment[:65530] - length = len(comment) - - pad = (length % 4) - 1 - if pad < 0: - pad = None - reclength = length + 5 - else: - reclength = length + 5 + pad - - self.header.fw.write_short(31) # Comment Opcode - self.header.fw.write_ushort(reclength) # Length of record is 4 + comment length + null terminator + pad - self.header.fw.write_string(comment,length+1) # comment + zero terminator - if pad: - self.header.fw.pad(pad) # pad to multiple of 4 bytes - - # Initialization sets up basic tree structure. - def __init__(self, parent, header, object,props): - global options - - self.header = header - self.object = object - if object: - self.name = self.object.name - if not options.state['transform']: - oloc = Blender.Mathutils.Vector(object.getLocation('worldspace')) - vec = Blender.Mathutils.Vector(oloc[0] * options.state['scale'], oloc[1] * options.state['scale'], oloc[2] * options.state['scale']) #scale - self.matrix = self.object.getMatrix('worldspace') * Blender.Mathutils.TranslationMatrix(vec - oloc) - else: - self.matrix = self.object.getMatrix('localspace') #do matrix mult here. - self.props = props - self.child_objects = self.header.parenthash[object.name] - else: - self.name = 'no name' - self.matrix = None - self.props = None - self.child_objects = self.header.child_objects - - self.children = [] - self.parent = parent - if parent: - parent.children.append(self) - - # Spawn children. - for child in self.child_objects: - if(not child.restrictDisplay): - childprops = None - ftype = None - if not child.properties.has_key('FLT'): - if child.type == 'Empty': - if child.DupGroup: - childprops = FLTXRef.copy() - ftype = 63 - else: - childprops = FLTGroup.copy() - ftype = 2 - elif child.type == 'Mesh': - if self.header.childhash[child.name] or not child.parent: - childprops = FLTGroup.copy() - ftype = 2 - else: - childprops = FLTObject.copy() - ftype = 4 - - else: - childprops = dict() - for prop in child.properties['FLT']: - childprops[prop] = child.properties['FLT'][prop] - ftype = child.properties['FLT']['type'] - - if ftype in self.childtypes and ftype in alltypes: - Newnode = FLTNode(self,header,child,childprops,ftype) - if child.type == 'Mesh': - self.header.mnodes.append(Newnode) -class FaceDesc: - def __init__(self): - self.vertex_index_lst = [] - self.mface = None - self.texture_index = 65535 - self.material_index = 65535 - self.color_index = 127 - self.renderstyle = 0 - self.twoside = 0 - self.name = None #uses next FLT name if not set... fix resolution of conflicts! - self.billboard = 0 - - #Multi-Tex info. Dosn't include first UV Layer! - self.uvlayer = list() #list of list of tuples for UV coordinates. - self.images = list() #list of texture indices for seperate UV layers - self.mtex = list() - self.subface = None #can either be 'Push' or 'Pop' - -def edge_get_othervert(vert, edge): - if edge.v1 == vert: - return edge.v2 - elif edge.v2 == vert: - return edge.v1 - return None - -class FLTNode(Node): - def walkLoop(self, targetvert, startvert, startedge, edgelist, visited, vedges, closeloop): - loop = [targetvert] - - curvert = startvert - curedge = startedge - visited[curedge] = True - found = False - - while not found: - loop.append(curvert) - disk = vedges[curvert.index] - if not closeloop: - if len(disk) == 1: - visited[curedge] = True - break - else: - if len(disk) < 2: #what? - visited[curedge] = True - return None - - if disk[0] == curedge: - curedge = disk[1] - else: - curedge = disk[0] - if curedge.v1.index == curvert.index: - curvert = curedge.v2 - else: - curvert = curedge.v1 - - visited[curedge] = True - - if(curvert == targetvert): - found = True - - return loop - - def buildVertFaces(self,vertuse): - for vert in self.exportmesh.verts: - if vertuse[vert.index][0] == False and vertuse[vert.index][1] == 0: - face_desc = FaceDesc() - face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, vert, 0,0,0)) - face_desc.renderstyle = 3 - face_desc.color_index = 227 - self.face_lst.append(face_desc) - - def buildEdgeFaces(self,vertuse): - for edge in self.exportmesh.edges: - v1 = vertuse[edge.v1.index] - v2 = vertuse[edge.v2.index] - if v1[0] == False and v2[0] == False: - if v1[1] == 1 and v2[1] == 1: - face_desc = FaceDesc() - face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, edge, 1, 0,0)) - face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, edge, 2, 0,0)) - face_desc.renderstyle = 3 - face_desc.color_index = 227 - self.face_lst.append(face_desc) - - - def vertwalk(self, startvert, loop, disk, visited): - visited[startvert] = True - for edge in disk[startvert]: - othervert = edge_get_othervert(startvert, edge) - if not visited[othervert]: - loop.append(othervert) - self.vertwalk(othervert,loop,disk,visited) - - def buildOpenFacesNew(self, vertuse): - wireverts = list() - wiredges = list() - visited = dict() - disk = dict() - loops = list() - - for edge in self.exportmesh.edges: - v1 = vertuse[edge.v1.index] - v2 = vertuse[edge.v2.index] - if v1[0] == False and v2[0] == False: - if v1[1] < 3 and v2[1] < 3: - wireverts.append(edge.v1) - wireverts.append(edge.v2) - wiredges.append(edge) - - #build disk data - for vert in wireverts: - visited[vert] = False - disk[vert] = list() - for edge in wiredges: - disk[edge.v1].append(edge) - disk[edge.v2].append(edge) - - #first pass: do open faces - for vert in wireverts: - if not visited[vert] and vertuse[vert.index][1] == 1: - loop = list() - done = 0 - startvert = vert - while not done: - done = 1 - visited[startvert] = True - loop.append(startvert) - for edge in disk[startvert]: - othervert = edge_get_othervert(startvert, edge) - if not visited[othervert]: - done = 0 - startvert = othervert - break - if len(loop) > 2: loops.append( ('Open', loop) ) - for vert in wireverts: - if not visited[vert]: - loop = list() - done = 0 - startvert = vert - while not done: - done = 1 - visited[startvert] = True - loop.append(startvert) - for edge in disk[startvert]: - othervert = edge_get_othervert(startvert,edge) - if not visited[othervert]: - done = 0 - startvert = othervert - break - if len(loop) > 2: loops.append( ('closed', loop) ) - - #now go through the loops and append. - for l in loops: - (ftype, loop) = l - face_desc = FaceDesc() - for i,vert in enumerate(loop): - face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,loop,i,0,0)) - if ftype == 'closed': - face_desc.renderstyle = 2 - else: - face_desc.renderstyle = 3 - face_desc.color_index = 227 - self.face_lst.append(face_desc) - - - - def sortFLTFaces(self,a,b): - aindex = a.getProperty("FLT_ORIGINDEX") - bindex = b.getProperty("FLT_ORIGINDEX") - - if aindex > bindex: - return 1 - elif aindex < bindex: - return -1 - return 0 - - def buildNormFaces(self): - - global options - meshlayers = self.exportmesh.getUVLayerNames() - oldlayer = self.exportmesh.activeUVLayer - uvok = 0 - subfaceok = 0 - subfacelevel = 0 - - #special case - if self.exportmesh.faceUV and len(meshlayers) == 1: - uvok = 1 - elif self.exportmesh.faceUV and tex_layers[0] in meshlayers: - self.exportmesh.activeUVLayer = tex_layers[0] - uvok = 1 - - #Sort faces according to the subfaces/FLT indices - if "FLT_ORIGINDEX" in self.exportmesh.faces.properties and "FLT_SFLEVEL" in self.exportmesh.faces.properties: - exportfaces = list() - for face in self.exportmesh.faces: - exportfaces.append(face) - exportfaces.sort(self.sortFLTFaces) - subfaceok = 1 - else: - exportfaces = self.exportmesh.faces - - # Faces described as lists of indices into the GRR's vertex_lst. - for face in exportfaces: - descs = list() - #first we export the face as normal - index_lst = [] - face_v = face.verts - for i, v in enumerate(face_v): - index_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,face,i,uvok,0)) - face_desc = FaceDesc() - face_desc.vertex_index_lst = index_lst - face_desc.mface = face - descs.append(face_desc) - - #deal with subfaces - if subfaceok: - fsflevel = face.getProperty("FLT_SFLEVEL") - for face_desc in descs: - if fsflevel > subfacelevel: - face_desc.subface = 'Push' - subfacelevel = fsflevel - elif fsflevel < subfacelevel: - face_desc.subface = 'Pop' - subfacelevel = fsflevel - - - if uvok and (face.mode & Blender.Mesh.FaceModes.TWOSIDE): - face_desc.renderstyle = 1 - for face_desc in descs: - if "FLT_COL" in self.exportmesh.faces.properties: - color_index = face.getProperty("FLT_COL") -# if(color_index < 127): -# color_index = 127 #sanity check for face color indices - if(color_index == 0): - color_index = 127 - face_desc.color_index = color_index - else: - face_desc.color_index = 127 - if "FLT_ID" in self.exportmesh.faces.properties: - face_desc.name = face.getProperty("FLT_ID") #need better solution than this. - - if uvok and face.mode & Blender.Mesh.FaceModes["BILLBOARD"]: - face_desc.billboard = 1 - - self.face_lst.append(face_desc) - if uvok: - self.exportmesh.activeUVLayer = oldlayer - - def buildTexData(self): - - meshlayers = self.exportmesh.getUVLayerNames() - oldlayer = self.exportmesh.activeUVLayer - uvok = 0 - - if self.exportmesh.faceUV and len(meshlayers) == 1: - uvok = 1 - if self.exportmesh.faceUV and tex_layers[0] in meshlayers: - self.exportmesh.activeUVLayer = tex_layers[0] - uvok = 1 - - if uvok: - #do base layer. UVs have been stored on vertices directly already. - for i, face in enumerate(self.face_lst): - if face.mface: - mface = face.mface - image = mface.image - if image != None and mface.mode & Blender.Mesh.FaceModes["TEX"]: - index = self.header.GRR.request_texture_index(image) - else: - index = -1 - face.texture_index = index - - for i, face in enumerate(self.face_lst): - if face.mface: - mface_v = face.mface.v - for v in mface_v: - face.uvlayer.append([]) - - for layername in tex_layers[1:]: - if layername in meshlayers: - self.exportmesh.activeUVLayer=layername - for i, face in enumerate(self.face_lst): - if face.mface: - - face.mtex.append(layername) - mface = face.mface - mface_v = mface.v - image = mface.image - - if image != None and mface.mode & Blender.Mesh.FaceModes["TEX"]: - index = self.header.GRR.request_texture_index(image) - face.images.append(index) - else: - face.images.append(-1) - - for j, v in enumerate(mface_v): - face.uvlayer[j].append(tuple(mface.uv[j])) - if uvok: - self.exportmesh.activeUVLayer = oldlayer - def blender_export(self): - global options - Node.blender_export(self) - if self.opcode == 111: - self.exportmesh = Blender.Mesh.New() - self.exportmesh.getFromObject(self.object.name) - - for vert in self.exportmesh.verts: - if not options.state['transform']: - vec = vert.co - vec = Blender.Mathutils.Vector(vec[0] * options.state['scale'], vec[1] * options.state['scale'], vec[2] * options.state['scale']) #scale - vert.co = Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace')) - - if options.state['scale'] != 1.0: - vert.co = vert.co * options.state['scale'] - - if("FLT_VCOL") in self.mesh.verts.properties: - for v in self.exportmesh.verts: - self.vert_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,v,0,0,v.getProperty("FLT_VCOL"))) - else: - for v in self.mesh.verts: - self.vert_lst.append(self.header.GRR.request_vertex_index(self.object,self.mesh,v,0,0,127)) - - - - elif self.mesh: - orig_mesh = self.object.getData(mesh=True) - self.exportmesh = Blender.Mesh.New() - default = None - - - if options.state['export_shading']: - mods = self.object.modifiers - hasedsplit = False - for mod in mods: - if mod.type == Blender.Modifier.Types.EDGESPLIT: - hasedsplit = True - break - if not hasedsplit: - default = mods.append(Modifier.Types.EDGESPLIT) - default[Modifier.Settings.EDGESPLIT_ANGLE] = options.state['shading_default'] - default[Modifier.Settings.EDGESPLIT_FROM_ANGLE] = True - default[Modifier.Settings.EDGESPLIT_FROM_SHARP] = False - self.object.makeDisplayList() - - self.exportmesh.getFromObject(self.object.name) - - #recalculate vertex positions - for vert in self.exportmesh.verts: - if not options.state['transform']: - vec = vert.co - vec = Blender.Mathutils.Vector(vec[0] * options.state['scale'], vec[1] * options.state['scale'], vec[2] * options.state['scale']) #scale - vert.co = Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace')) - - if options.state['scale'] != 1.0: - vert.co = vert.co * options.state['scale'] - - flipped = self.object.getMatrix('worldspace').determinant() - - if not options.state['transform']: - self.exportmesh.calcNormals() - - - if default: - #remove modifier from list - mods.remove(default) - self.object.makeDisplayList() - - #build some adjacency data - vertuse = list() - wiredges = list() - openends = list() - for v in self.exportmesh.verts: - vertuse.append([False,0]) - - #build face incidence data - for face in self.exportmesh.faces: - for i, v in enumerate(face.verts): - vertuse[v.index][0] = True - - for edge in self.exportmesh.edges: #count valance - vertuse[edge.v1.index][1] = vertuse[edge.v1.index][1] + 1 - vertuse[edge.v2.index][1] = vertuse[edge.v2.index][1] + 1 - - #create all face types - self.buildVertFaces(vertuse) - self.buildEdgeFaces(vertuse) - self.buildOpenFacesNew(vertuse) - self.buildNormFaces() - self.buildTexData() - - if not options.state['transform']: - if flipped < 0: - for vdesc in self.header.GRR.vertex_lst: - vdesc.accum = 0 - for face in self.face_lst: - face.vertex_index_lst.reverse() - for vert in face.vertex_index_lst: - self.header.GRR.vertex_lst[vert].accum = 1 - - for vdesc in self.header.GRR.vertex_lst: - if vdesc.accum: - vdesc.nx = vdesc.nx * -1 - vdesc.ny = vdesc.ny * -1 - vdesc.nz = vdesc.nz * -1 - - - def write_faces(self): - sublevel = 0 - for face_desc in self.face_lst: - if face_desc.name: - face_name = face_desc.name - else: - face_name = self.header.GRR.new_face_name() - - #grab the alpha value. - alpha = 0 - if face_desc.texture_index > -1: - try: - typestring = os.path.splitext(self.header.GRR.texture_lst[face_desc.texture_index].getFilename())[1] - if typestring == '.inta' or typestring == '.rgba': - alpha = 1 - except: - pass - - if not alpha: - for index in face_desc.images: - try: - typestring = os.path.splitext(self.header.GRR.texture_lst[index].getFilename())[1] - if typestring == '.inta' or typestring == '.rgba': - alpha = 1 - except: - pass - - if face_desc.billboard: - alpha = 2 - - if face_desc.subface: - if face_desc.subface == 'Push': - self.header.fw.write_short(19) - self.header.fw.write_ushort(4) - sublevel += 1 - else: - self.header.fw.write_short(20) - self.header.fw.write_ushort(4) - sublevel -= 1 - self.header.fw.write_short(5) # Face opcode - self.header.fw.write_ushort(80) # Length of record - self.header.fw.write_string(face_name, 8) # ASCII ID - self.header.fw.write_int(-1) # IR color code - self.header.fw.write_short(0) # Relative priority - self.header.fw.write_char(face_desc.renderstyle) # Draw type - self.header.fw.write_char(0) # Draw textured white. - self.header.fw.write_ushort(0) # Color name index - self.header.fw.write_ushort(0) # Alt color name index - self.header.fw.write_char(0) # Reserved - self.header.fw.write_char(alpha) # Template - self.header.fw.write_short(-1) # Detail tex pat index - if face_desc.texture_index == -1: - self.header.fw.write_ushort(65535) - else: - self.header.fw.write_ushort(face_desc.texture_index) # Tex pattern index - if face_desc.material_index == -1: - self.header.fw.write_ushort(65535) - else: - self.header.fw.write_ushort(face_desc.material_index) # material index - self.header.fw.write_short(0) # SMC code - self.header.fw.write_short(0) # Feature code - self.header.fw.write_int(0) # IR material code - self.header.fw.write_ushort(0) # transparency 0 = opaque - self.header.fw.write_uchar(0) # LOD generation control - self.header.fw.write_uchar(0) # line style index - self.header.fw.write_int(0) # Flags - self.header.fw.write_uchar(2) # Light mode - #self.header.fw.write_uchar(3) # Light mode - - self.header.fw.pad(7) # Reserved - self.header.fw.write_uint(0) # Packed color - self.header.fw.write_uint(0) # Packed alt color - self.header.fw.write_short(-1) # Tex map index - self.header.fw.write_short(0) # Reserved - self.header.fw.write_uint(face_desc.color_index) # Color index - self.header.fw.write_uint(127) # Alt color index - self.header.fw.write_short(0) # Reserved - self.header.fw.write_short(-1) # Shader index - - self.write_longid(face_name) - - - #Write Multitexture field if appropriate - mtex = len(face_desc.mtex) - if mtex: - uvmask = 0 - for layername in face_desc.mtex: - mask = mtexmasks[tex_layers.index(layername)-1] - uvmask |= mask - self.header.fw.write_ushort(52) # MultiTexture Opcode - self.header.fw.write_ushort(8 + (mtex * 8)) # Length - self.header.fw.write_uint(uvmask) # UV mask - for i in xrange(mtex): - if face_desc.images[i] == -1: - self.header.fw.write_ushort(65535) - else: - self.header.fw.write_ushort(face_desc.images[i]) # Tex pattern index - self.header.fw.write_ushort(0) # Tex effect - self.header.fw.write_ushort(0) # Tex Mapping index - self.header.fw.write_ushort(0) # Tex data. User defined - - self.write_push() - - # Vertex list record - self.header.fw.write_short(72) # Vertex list opcode - num_verts = len(face_desc.vertex_index_lst) - self.header.fw.write_ushort(4*num_verts+4) # Length of record - - for vert_index in face_desc.vertex_index_lst: - # Offset into vertex palette - self.header.fw.write_int(vert_index*64+8) - - #UV list record - if mtex: - #length = 8 + (numverts * multitex * 8) - self.header.fw.write_ushort(53) # UV List Ocode - self.header.fw.write_ushort(8 + (num_verts*mtex*8)) # Record Length - self.header.fw.write_uint(uvmask) # UV mask - for i, vert_index in enumerate(face_desc.vertex_index_lst): - for uv in face_desc.uvlayer[i]: - self.header.fw.write_float(uv[0]) #U coordinate - self.header.fw.write_float(uv[1]) #V coordinate - self.write_pop() - #clean up faces at the end of meshes.... - if sublevel: - self.header.fw.write_short(20) - self.header.fw.write_ushort(4) - - def write_lps(self): - # Vertex list record - self.write_push() - self.header.fw.write_short(72) # Vertex list opcode - num_verts = len(self.vert_lst) - self.header.fw.write_ushort(4*num_verts+4) # Length of record - - for vert_index in self.vert_lst: - # Offset into vertex palette - self.header.fw.write_int(vert_index*64+8) - self.write_pop() - def write(self): - self.header.fw.write_short(self.opcode) - self.header.fw.write_ushort(recordlen[self.opcode]) - exportdict = FLT_Records[self.opcode].copy() - if self.object: - self.props['3t8!id'] = self.object.name[:7] - for key in exportdict.keys(): - if self.props.has_key(key): - exportdict[key] = self.props[key] - - if self.opcode == 63 and options.state['externalspath']: - try: - exportdict['3t200!filename'] = os.path.join(options.state['externalspath'],self.object.DupGroup.name+'.flt').replace("\\", "/") - self.header.xrefnames.append(self.object.DupGroup.name) - except: - pass - - for key in records[self.opcode]: - (ftype,length,propname) = records[self.opcode][key] - write_prop(self.header.fw,ftype,exportdict[propname],length) - - if self.props.has_key('comment'): - self.write_comment(self.props['comment']) - - if self.object and self.object.properties.has_key('FLT') and self.object.properties['FLT'].has_key('EXT'): - datalen = len(self.object.properties['FLT']['EXT']['data']) - self.write_push_extension() - self.header.fw.write_short(100) - self.header.fw.write_ushort(24 + datalen) - for key in records[100]: - (ftype,length,propname) = records[100][key] - write_prop(self.header.fw,ftype,self.object.properties['FLT']['EXT'][propname],length) - #write extension data - for i in xrange(datalen): - self.header.fw.write_uchar(struct.unpack('>B', struct.pack('>B', self.object.properties['FLT']['EXT']['data'][i]))[0]) - self.write_pop_extension() - - - self.write_longid(self.name) #fix this! - - if options.state['transform'] or self.opcode == 63: - #writing transform matrix.... - self.write_matrix() - - if self.opcode == 111: - self.write_lps() - elif self.face_lst != [] or self.children: - self.write_push() - if self.face_lst != []: - #self.write_push() - self.write_faces() - #self.write_pop() - - if self.children: - #self.write_push() - for child in self.children: - child.write() - #self.write_pop() - self.write_pop() - - def __init__(self, parent, header, object,props,ftype): - self.opcode = ftype #both these next two lines need to be in the node class.... - self.childtypes = childtypes[self.opcode] - Node.__init__(self, parent, header, object,props) - self.face_lst = [] - self.vert_lst = [] #for light points. - self.mesh = None - self.uvlayer = 0 - self.flipx = False - self.flipy = False - self.flipz = False - - - if self.object.type == 'Mesh': - self.mesh = self.object.getData(mesh=True) - if(self.mesh.faceUV): - self.uvLayer = len(self.mesh.getUVLayerNames()) - -class Database(Node): - def write_header(self): - if options.verbose >= 2: - print 'Writing header.' - self.fw.write_short(1) # Header opcode - self.fw.write_ushort(324) # Length of record - self.fw.write_string('db', 8) # ASCII ID - self.fw.write_int(1600) # Revision Number - self.fw.pad(44) - self.fw.write_short(1) # Unit multiplier. - self.fw.write_char(0) # Units, 0 = meters - self.fw.write_char(0) # texwhite on new faces 0 = false - self.fw.write_uint(0x80000000) # misc flags set to saving vertex normals - self.fw.pad(24) - self.fw.write_int(0) # projection type, 0 = flat earth - self.fw.pad(30) - self.fw.write_short(1) # double precision - self.fw.write_int(100) # database origin type - self.fw.pad(88) - try: - self.fw.write_double(self.header.scene.properties['FLT']['origin lat']) #database origin lattitude - except: - self.fw.write_double(0) - try: - self.fw.write_double(self.header.scene.properties['FLT']['origin lon']) #database origin longitude - except: - self.fw.write_double(0) - self.fw.pad(32) - self.fw.write_int(0) # ellipsoid model, 0 = WSG 1984 - - self.fw.pad(52) - - def write_vert_pal(self): - if options.verbose >= 2: - print 'Writing vertex palette.' - # Write record for vertex palette - self.fw.write_short(67) # Vertex palette opcode. - self.fw.write_short(8) # Length of record - self.fw.write_int(self.GRR.vertex_count() * 64 + 8) # Length of everything. - # Write records for individual vertices. - for i in xrange(self.GRR.vertex_count()): - desc = self.GRR.request_vertex_desc(i) - self.fw.write_short(70) # Vertex with color normal and uv opcode. - self.fw.write_ushort(64) # Length of record - self.fw.write_ushort(0) # Color name index - self.fw.write_short(1 << 14) # Frozen Normal - self.fw.write_double(desc.x) - self.fw.write_double(desc.y) - self.fw.write_double(desc.z) - self.fw.write_float(desc.nx) - self.fw.write_float(desc.ny) - self.fw.write_float(desc.nz) - self.fw.write_float(desc.u) - self.fw.write_float(desc.v) - self.fw.pad(4) - self.fw.write_uint(desc.cindex) - self.fw.pad(4) - - def write_tex_pal(self): - if options.verbose >= 2: - print 'Writing texture palette.' - # Write record for texture palette - for i, img in enumerate(self.GRR.texture_lst): - filename = tex_files[img.name] - self.fw.write_short(64) # Texture palette opcode. - self.fw.write_short(216) # Length of record - self.fw.write_string(filename, 200) # Filename - self.fw.write_int(i) # Texture index - self.fw.write_int(0) # X - self.fw.write_int(0) # Y - - def write_mat_pal(self): - if options.verbose >= 2: - print 'Writing material palette.' - for i in xrange(self.GRR.material_count()): - desc = self.GRR.request_material_desc(i) - self.fw.write_short(113) # Material palette opcode. - self.fw.write_short(84) # Length of record - self.fw.write_int(i) # Material index - self.fw.write_string(desc.name, 12) # Material name - self.fw.write_uint(0x80000000) # Flags - self.fw.write_float(desc.ambient[0]) # Ambient color. - self.fw.write_float(desc.ambient[1]) # Ambient color. - self.fw.write_float(desc.ambient[2]) # Ambient color. - self.fw.write_float(desc.diffuse[0]) # Diffuse color. - self.fw.write_float(desc.diffuse[1]) # Diffuse color. - self.fw.write_float(desc.diffuse[2]) # Diffuse color. - self.fw.write_float(desc.specular[0]) # Specular color. - self.fw.write_float(desc.specular[1]) # Specular color. - self.fw.write_float(desc.specular[2]) # Specular color. - self.fw.write_float(desc.emissive[0]) # Emissive color. - self.fw.write_float(desc.emissive[1]) # Emissive color. - self.fw.write_float(desc.emissive[2]) # Emissive color. - self.fw.write_float(desc.shininess) - self.fw.write_float(desc.alpha) - self.fw.write_int(0) # Reserved - - def write_col_pal(self): - if options.verbose >= 2: - print 'Writing color palette.' - self.fw.write_short(32) # Color palette opcode. - self.fw.write_short(4228) # Length of record - self.fw.pad(128) - try: - cpalette = self.scene.properties['FLT']['Color Palette'] - except: - cpalette = defaultp.pal - count = len(cpalette) - for i in xrange(count): - color = struct.unpack('>BBBB',struct.pack('>i',cpalette[i])) - self.fw.write_uchar(color[3]) # alpha - self.fw.write_uchar(color[2]) # b - self.fw.write_uchar(color[1]) # g - self.fw.write_uchar(color[0]) # r - self.fw.pad(max(4096-count*4, 0)) - - def write(self): - self.write_header() - self.write_vert_pal() - self.write_tex_pal() - self.write_mat_pal() - self.write_col_pal() - - self.write_push() - - for child in self.children: - child.write() - self.write_pop() - - def export_textures(self,texturepath): - for i in xrange(self.GRR.texture_count()): - texture = self.GRR.texture_lst[i] - - if options.state['copytex']: - filename = os.path.normpath(os.path.join(options.state['texturespath'], os.path.basename(self.GRR.request_texture_filename(i)))) - else: - filename = os.path.normpath(self.GRR.request_texture_filename(i)) - - tex_files[texture.name] = filename - - def blender_export(self): - Node.blender_export(self) - self.export_textures(self) - return self.xrefnames - def __init__(self, scene, fw): - self.fw = fw - self.opcode = 1 - self.childtypes = [73,14,2,63] - self.scene = scene - self.childhash = dict() - self.parenthash = dict() - self.child_objects = list() - self.mnodes = list() - self.xrefnames = list() - for i in self.scene.objects: - self.parenthash[i.name] = list() - self.childhash[i.name] = False - for i in self.scene.objects: - if i.parent: - self.childhash[i.parent.name] = True - self.parenthash[i.parent.name].append(i) - else: - self.child_objects.append(i) - - self.GRR = GlobalResourceRepository() - Node.__init__(self, None, self, None,None) - -def write_attribute_files(): - for imgname in tex_files: - blentex = Blender.Image.Get(imgname) - exportdict = FLT_Records['Image'].copy() - - if blentex.properties.has_key('FLT'): - for key in exportdict.keys(): - if blentex.properties.has_key(key): - exportdict[key] = blentex.properties['FLT'][key] - - # ClampX/Y override - if blentex.clampX: - exportdict['11i!WrapU'] = 1 - if blentex.clampY: - exportdict['12i!WrapV'] = 1 - - exportdict['16i!Enviorment'] = 0 - - # File type - typecode = 0 - try: - typestring = os.path.splitext(blentex.getFilename())[1] - - if typestring == '.rgba': - typecode = 5 - elif typestring == '.rgb': - typecode = 4 - elif typestring == '.inta': - typecode = 3 - elif typestring == '.int': - typecode = 2 - except: - pass - - exportdict['7i!File Format'] = typecode - - fw = FltOut(tex_files[imgname] + '.attr') - size = blentex.getSize() - fw.write_int(size[0]) - fw.write_int(size[1]) - for key in records['Image']: - (ftype,length,propname) = records['Image'][key] - write_prop(fw,ftype,exportdict[propname],length) - fw.close_file() - -#globals used by the scene export function -exportlevel = None -xrefsdone = None - -def dbexport_internal(scene): - global exportlevel - global xrefsdone - global options - - if exportlevel == 0 or not options.state['externalspath']: - fname = os.path.join(options.state['basepath'],scene.name + '.flt') - else: - fname = os.path.join(options.state['externalspath'],scene.name + '.flt') - - fw = FltOut(fname) - db = Database(scene,fw) - - if options.verbose >= 1: - print 'Pass 1: Exporting ', scene.name,'.flt from Blender.\n' - - xreflist = db.blender_export() - if options.verbose >= 1: - print 'Pass 2: Writing %s\n' % fname - db.write() - fw.close_file() - - if options.state['doxrefs']: - for xname in xreflist: - try: - xrefscene = Blender.Scene.Get(xname) - except: - xrefscene = None - if xrefscene and xname not in xrefsdone: - xrefsdone.append(xname) - exportlevel+=1 - dbexport_internal(xrefscene) - exportlevel-=1 - return fname -#main database export function -def dbexport(): - global exportlevel - global xrefsdone - exportlevel = 0 - xrefsdone = list() - - Blender.Window.WaitCursor(True) - time1 = Blender.sys.time() # Start timing - - if options.verbose >= 1: - print '\nOpenFlight Exporter' - print 'Version:', __version__ - print 'Author: Greg MacDonald, Geoffrey Bantle' - print __url__[2] - print - - fname = dbexport_internal(Blender.Scene.GetCurrent()) - if options.verbose >=1: - print 'Done in %.4f sec.\n' % (Blender.sys.time() - time1) - Blender.Window.WaitCursor(False) - - #optional: Copy textures - if options.state['copytex']: - for imgname in tex_files: - #Check to see if texture exists in target directory - if not os.path.exists(tex_files[imgname]): - #Get original Blender file name - origpath = Blender.sys.expandpath(Blender.Image.Get(imgname).getFilename()) - #copy original to new - if os.path.exists(origpath): - shutil.copyfile(origpath,tex_files[imgname]) - - #optional: Write attribute files - if options.state['attrib']: - write_attribute_files() - - if options.state['xapp']: - cmd= options.state['xappath'] + " " + fname - status = os.system(cmd) - - -#Begin UI code -FLTExport = None -FLTClose = None -FLTLabel = None - -FLTBaseLabel = None -FLTTextureLabel = None -FLTXRefLabel = None - -FLTBaseString = None -FLTTextureString = None -FLTXRefString = None - -FLTBasePath = None -FLTTexturePath = None -FLTXRefPath = None - -FLTShadeExport = None -FLTShadeDefault = None - -FLTCopyTex = None -FLTDoXRef = None -FLTGlobal = None - -FLTScale = None - -FLTXAPP = None -FLTXAPPath = None -FLTXAPPString = None -FLTXAPPLabel = None -FLTXAPPChooser = None - -FLTAttrib = None - - -FLTWarn = None - -def setshadingangle(ID,val): - global options - options.state['shading_default'] = val -def setBpath(fname): - global options - options.state['basepath'] = os.path.dirname(fname) - #update xref and textures path too.... - if(os.path.exists(os.path.join(options.state['basepath'],'externals'))): - options.state['externalspath'] = os.path.join(options.state['basepath'],'externals') - if(os.path.exists(os.path.join(options.state['basepath'],'textures'))): - options.state['texturespath'] = os.path.join(options.state['basepath'],'textures') -def setexportscale(ID,val): - global options - options.state['scale'] = val - -def setTpath(fname): - global options - options.state['texturespath'] = os.path.dirname(fname) -def setXpath(fname): - global options - options.state['externalspath'] = os.path.dirname(fname) -def setXApath(fname): - global options - options.state['xappath'] = fname -def event(evt, val): - x = 1 -def but_event(evt): - global options - - global FLTExport - global FLTClose - global FLTLabel - - global FLTBaseLabel - global FLTTextureLabel - global FLTXRefLabel - - global FLTBaseString - global FLTTextureString - global FLTXRefString - - global FLTBasePath - global FLTTexturePath - global FLTXRefPath - - global FLTShadeExport - global FLTShadeDefault - - global FLTCopyTex - global FLTDoXRef - global FLTGlobal - - global FLTScale - - - global FLTXAPP - global FLTXAPPath - global FLTXAPPString - global FLTXAPPLabel - global FLTXAPPChooser - - global FLTAttrib - - global FLTWarn - - #choose base path for export - if evt == 4: - Blender.Window.FileSelector(setBpath, "DB Root", options.state['basepath']) - - #choose XREF path - if evt == 6: - Blender.Window.FileSelector(setXpath,"DB Externals",options.state['externalspath']) - - #choose texture path - if evt == 8: - Blender.Window.FileSelector(setTpath,"DB Textures",options.state['texturespath']) - - #export shading toggle - if evt == 9: - options.state['export_shading'] = FLTShadeExport.val - #export Textures - if evt == 11: - options.state['copytex']= FLTCopyTex.val - #export XRefs - if evt == 13: - options.state['doxrefs'] = FLTDoXRef.val - #export Transforms - if evt == 12: - options.state['transform'] = FLTGlobal.val - - if evt == 14: - options.state['xapp'] = FLTXAPP.val - if evt == 16: - Blender.Window.FileSelector(setXApath,"External Application",options.state['xappath']) - if evt == 20: - options.state['attrib'] = FLTAttrib.val - - #Export DB - if evt == 1: - try: - dbexport() - except Exception, inst: - import traceback - FLTWarn = Draw.PupBlock("Export Error", ["See console for output!"]) - traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) - - #exit - if evt == 2: - Draw.Exit() - - options.write_state() - -from Blender.BGL import * -from Blender import Draw -def gui(): - - global options - - global FLTExport - global FLTClose - global FLTLabel - - global FLTBaseLabel - global FLTTextureLabel - global FLTXRefLabel - - global FLTBaseString - global FLTTextureString - global FLTXRefString - - global FLTBasePath - global FLTTexturePath - global FLTXRefPath - - global FLTShadeExport - global FLTShadeDefault - - global FLTCopyTex - global FLTDoXRef - global FLTGlobal - - global FLTScale - - global FLTXAPP - global FLTXAPPath - global FLTXAPPString - global FLTXAPPLabel - global FLTXAPPChooser - - global FLTAttrib - - glClearColor(0.880,0.890,0.730,1.0 ) - glClear(GL_COLOR_BUFFER_BIT) - - areas = Blender.Window.GetScreenInfo() - curarea = Blender.Window.GetAreaID() - curRect = None - - for area in areas: - if area['id'] == curarea: - curRect = area['vertices'] - break - - width = curRect[2] - curRect[0] - height = curRect[3] - curRect[1] - #draw from top to bottom.... - cx = 50 - #Draw Title Bar... - #glRasterPos2d(cx, curRect[3]-100) - #FLTLabel = Draw.Text("FLT Exporter V2.0",'large') - cy = height - 80 - - FLTBaseLabel = Draw.Label("Base Path:",cx,cy,100,20) - FLTBaseString = Draw.String("",3,cx+100,cy,300,20,options.state['basepath'],255,"Folder to export to") - FLTBaseChooser = Draw.PushButton("...",4,cx+400,cy,20,20,"Choose Folder") - - cy = cy-40 - - #externals path - FLTXRefLabel = Draw.Label("XRefs:",cx,cy,100,20) - FLTXRefString = Draw.String("",5,cx+100,cy,300,20,options.state['externalspath'],255,"Folder for external references") - FLTXRefChooser = Draw.PushButton("...",6,cx+400,cy,20,20,"Choose Folder") - cy = cy-40 - #Textures path - FLTTextureLabel = Draw.Label("Textures:",cx,cy,100,20) - FLTTextureString = Draw.String("",7,cx+100,cy,300,20,options.state['texturespath'],255,"Folder for texture files") - FLTTextureChooser = Draw.PushButton("...",8,cx+400,cy,20,20,"Choose Folder") - cy=cy-40 - #External application path - FLTXAPPLabel = Draw.Label("XApp:",cx,cy,100,20) - FLTXAPPString = Draw.String("",15,cx+100,cy,300,20,options.state['xappath'],255,"External application to launch when done") - FLTXAPPChooser = Draw.PushButton("...",16,cx+400, cy,20,20,"Choose Folder") - - cy = cy-60 - #Shading Options - FLTShadeExport = Draw.Toggle("Default Shading",9,cx,cy,100,20,options.state['export_shading'],"Turn on export of custom shading") - FLTShadDefault = Draw.Number("",10,cx + 120,cy,100,20,options.state['shading_default'],0.0,180.0,"Default shading angle for objects with no custom shading assigned",setshadingangle) - - cy = cy-40 - FLTScale = Draw.Number("Export Scale",14,cx,cy,220,20,options.state['scale'],0.0,100.0,"Export scaling factor",setexportscale) - - cy = cy-40 - #misc Options - FLTCopyTex = Draw.Toggle("Copy Textures",11,cx,cy,220,20,options.state['copytex'],"Copy textures to folder indicated above") - cy = cy-40 - FLTGlobal = Draw.Toggle("Export Transforms",12,cx,cy,220,20,options.state['transform'],"If unchecked, Global coordinates are used (recommended)") - cy = cy-40 - FLTDoXRef = Draw.Toggle("Export XRefs", 13,cx,cy,220,20,options.state['doxrefs'],"Export External references (only those below current scene!)") - cy = cy-40 - FLTXAPP = Draw.Toggle("Launch External App", 14, cx,cy,220,20,options.state['xapp'],"Launch External Application on export") - cy = cy-40 - FLTAttrib = Draw.Toggle("Write Attribute Files", 20, cx, cy, 220,20,options.state['attrib'], "Write Texture Attribute files") - #FLTXAPPATH = Draw.String("",15,cx,cy,300,20,options.xappath,255,"External application path") - - - #Draw export/close buttons - FLTExport = Draw.PushButton("Export",1,cx,20,100,20,"Export to FLT") - FLTClose = Draw.PushButton("Close", 2, cx+120,20,100,20,"Close window") - - -Draw.Register(gui,event,but_event) \ No newline at end of file diff --git a/release/scripts/flt_filewalker.py b/release/scripts/flt_filewalker.py deleted file mode 100644 index 4a9b86c45d2..00000000000 --- a/release/scripts/flt_filewalker.py +++ /dev/null @@ -1,286 +0,0 @@ -#!BPY - -# flt_filewalker.py is an utility module for OpenFlight IO scripts for blender. -# Copyright (C) 2005 Greg MacDonald -# -# 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. - -__bpydoc__ ="""\ -File read/write module used by OpenFlight I/O and tool scripts. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. -""" - -import Blender -from struct import * -import re - -class FltIn: - def __init__(self, filename): - self.file = open(filename, 'rb') - self.position = 0 - self.next_position = 100000 - self.opcode = 0 - self.length = 0 - self.level = 0 - self.repeat = False # Repeat the last record. - - def begin_record(self): - if self.repeat == True: - self.repeat = False - else: - self.position += self.length - try: - self.file.seek(self.position) - input = self.file.read(4) - except: - print 'Parse Error!' - return False - - if not input: - self.close_file() - return False - - self.opcode = unpack('>h', input[:2])[0] - self.length = unpack('>H', input[-2:])[0] - - self.next_position = self.position + self.length - - return True - - def repeat_record(self): - self.repeat = True - - def get_opcode(self): - return self.opcode - - def get_level(self): - return self.level - - def up_level(self): - self.level += 1 - - def down_level(self): - self.level -= 1 - - def read_string(self, length): - s = '' - if self.file.tell() + length <= self.next_position: - start = self.file.tell() - for i in xrange(length): - char = self.file.read(1) - if char == '\x00': - break - s = s + char - - self.file.seek(start+length) -# else: -# print 'Warning: string truncated' - - return s - - def read_int(self): - if self.file.tell() + 4 <= self.next_position: - return unpack('>i', self.file.read(4))[0] - else: - #print 'Warning: int truncated' - return 0 - - def read_uint(self): - if self.file.tell() + 4 <= self.next_position: - return unpack('>I', self.file.read(4))[0] - else: - #print 'Warning: uint truncated' - return 0 - - def read_double(self): - if self.file.tell() + 8 <= self.next_position: - return unpack('>d', self.file.read(8))[0] - else: - #print 'Warning: double truncated' - return 0.0 - - def read_float(self): - if self.file.tell() + 4 <= self.next_position: - return unpack('>f', self.file.read(4))[0] - else: - #print 'Warning: float truncated' - return 0.0 - - def read_ushort(self): - if self.file.tell() + 2 <= self.next_position: - return unpack('>H', self.file.read(2))[0] - else: - #print 'Warning: ushort truncated' - return 0 - - def read_short(self): - if self.file.tell() + 2 <= self.next_position: - return unpack('>h', self.file.read(2))[0] - else: - #print 'Warning: short trunated' - return 0 - - def read_uchar(self): - if self.file.tell() + 1 <= self.next_position: - return unpack('>B', self.file.read(1))[0] - else: - #print 'Warning: uchar truncated' - return 0 - - def read_char(self): - if self.file.tell() + 1 <= self.next_position: - return unpack('>b', self.file.read(1))[0] - else: - #print 'Warning: char truncated' - return 0 - - def read_ahead(self, i): - if self.file.tell() + i <= self.next_position: - self.file.seek(i, 1) -# else: -# print 'Warning: attempt to seek past record' - - def get_length(self): - return self.length - - def close_file(self): - self.file.close() - -class FltOut: - # Length includes terminating null - def write_string(self, string, length): - if len(string) > length - 1: - str_len = length - 1 - else: - str_len = len(string) - - pad_len = length - str_len - - self.file.write(string[:str_len]) - - self.pad(pad_len) - - def write_int(self, a): - self.file.write( pack('>i', a) ) - - def write_uint(self, a): - self.file.write( pack('>I', a) ) - - def write_double(self, a): - self.file.write( pack('>d', a) ) - - def write_float(self, a): - self.file.write( pack('>f', a) ) - - def write_ushort(self, a): - self.file.write( pack('>H', a) ) - - def write_short(self, a): - self.file.write( pack('>h', a) ) - - def write_uchar(self, a): - self.file.write( pack('>B', a) ) - - def write_char(self, a): - self.file.write( pack('>b', a) ) - - def pad(self, reps): - for i in xrange(reps): - self.file.write('\x00') - - def close_file(self): - self.file.close() - - def __init__(self, filename): - self.file = open(filename, 'wb') - self.filename = filename - - -class FileFinder: - def add_file_to_search_path(self, filename): - dir = Blender.sys.dirname(filename) - if dir != None and dir != '': - self.search_dirs.append(dir) - - def strip_path(self, full_path): - # One of my flt files had a windows path with unix seperation. Basename - # returned the whole path + filename, which isn't expected. So my - # attempt to fix it is to replace all / or \ with the platform specific - # dir seperator. - # - # note: \\\\ is actually just one \ indirected twice, once for python - # then again for re.sub - if Blender.sys.sep == '\\': - full_path = re.sub('/', '\\\\', full_path) - elif Blender.sys.sep == '/': - full_path = re.sub('\\\\', '/', full_path) - - filename = Blender.sys.basename(full_path) - return filename - - def find(self, full_path): - if full_path == '': - return None - - # Seperate out the path. - dirname = Blender.sys.dirname(full_path) - - # Try it first. - if Blender.sys.exists(full_path): - if not dirname in self.search_dirs: - self.search_dirs.append(dirname) - return full_path - - # Maybe it's relative. - for path in self.search_dirs: - rel_full_path = Blender.sys.join(path, full_path) - if Blender.sys.exists(rel_full_path): - return rel_full_path - - # Search previous directories that have worked. - filename = self.strip_path(full_path) - for path in self.search_dirs: - t = Blender.sys.join(path, filename) - if Blender.sys.exists(t): - return t - - # Ask user where it is. - self.user_input = Blender.Draw.PupStrInput(filename + "? ", '', 100) - #self.user_input = None - if self.user_input != None: - t = Blender.sys.join(self.user_input, filename) - if Blender.sys.exists(t): - user_dirname = Blender.sys.dirname(t) - if not user_dirname in self.search_dirs: - self.search_dirs.append(user_dirname) - return t - - # Couldn't find it. - return None - - def __init__(self): - self.user_input = '' - self.current_file = '' - self.search_dirs = [] - - dir = Blender.Get('texturesdir') - if dir != None and dir != '': - self.search_dirs.append(dir) - - dir = Blender.sys.dirname(Blender.Get('filename')) - if dir != None and dir != '': - print dir - self.search_dirs.append(dir) - \ No newline at end of file diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py deleted file mode 100644 index f8d31f7bb57..00000000000 --- a/release/scripts/flt_import.py +++ /dev/null @@ -1,2534 +0,0 @@ -#!BPY -""" Registration info for Blender menus: -Name: 'OpenFlight (.flt)...' -Blender: 245 -Group: 'Import' -Tip: 'Import OpenFlight (.flt)' -""" - - - -__author__ = "Greg MacDonald, Campbell Barton, Geoffrey Bantle" -__version__ = "2.0 11/21/07" -__url__ = ("blender", "blenderartists.org", "Author's homepage, http://sourceforge.net/projects/blight/") -__bpydoc__ = """\ -This script imports OpenFlight files into Blender. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. - -Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/Import/openflight_fltss - -Note: This file is a grab-bag of old and new code. It needs some cleanup still. -""" - -# flt_import.py is an OpenFlight importer for blender. -# Copyright (C) 2005 Greg MacDonald, 2007 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. - -import Blender -import os -import BPyMesh -import BPyImage -import flt_filewalker -import flt_properties -import sys -reload(flt_properties) -from flt_properties import * - -#Globals. Should Clean these up and minimize their usage. - -typecodes = ['c','C','s','S','i','I','f','d','t'] -records = dict() - -FLTBaseLabel = None -FLTBaseString = None -FLTBaseChooser = None -FLTExport = None -FLTClose = None -FLTDoXRef = None -FLTScale = None -FLTShadeImport = None -FLTAttrib = None -FLTWarn = None - -Vector= Blender.Mathutils.Vector -FLOAT_TOLERANCE = 0.01 - -FF = flt_filewalker.FileFinder() -current_layer = 0x01 - -global_prefs = dict() -global_prefs['verbose']= 4 -global_prefs['get_texture'] = True -global_prefs['get_diffuse'] = True -global_prefs['get_specular'] = False -global_prefs['get_emissive'] = False -global_prefs['get_alpha'] = True -global_prefs['get_ambient'] = False -global_prefs['get_shininess'] = True -global_prefs['color_from_face'] = True -global_prefs['fltfile']= '' -global_prefs['smoothshading'] = 1 -global_prefs['doxrefs'] = 1 -global_prefs['scale'] = 1.0 -global_prefs['attrib'] = 0 -msg_once = False - -reg = Blender.Registry.GetKey('flt_import',1) -if reg: - for key in global_prefs: - if reg.has_key(key): - global_prefs[key] = reg[key] - - - -throw_back_opcodes = [2, 73, 4, 11, 96, 14, 91, 98, 63,111] # Opcodes that indicate its time to return control to parent. -do_not_report_opcodes = [76, 78, 79, 80, 81, 82, 94, 83, 33, 112, 101, 102, 97, 31, 103, 104, 117, 118, 120, 121, 124, 125] - -#Process FLT record definitions -for record in FLT_Records: - props = dict() - for prop in FLT_Records[record]: - position = '' - slice = 0 - (format,name) = prop.split('!') - for i in format: - if i not in typecodes: - position = position + i - slice = slice + 1 - else: - break - type = format[slice:] - length = type[1:] - if len(length) == 0: - length = 1 - else: - type = type[0] - length = int(length) - - props[int(position)] = (type,length,prop) - records[record] = props - -def col_to_gray(c): - return 0.3*c[0] + 0.59*c[1] + 0.11*c[2] -class MaterialDesc: - # Was going to use int(f*1000.0) instead of round(f,3), but for some reason - # round produces better results, as in less dups. - def make_key(self): - key = list() - if global_prefs['get_texture']: - if self.tex0: - key.append(self.tex0.getName()) - else: - key.append(None) - - if global_prefs['get_alpha']: - key.append(round(self.alpha, 3)) - else: - key.append(None) - - if global_prefs['get_shininess']: - key.append(round(self.shininess, 3)) - else: - key.append(None) - - if global_prefs['get_emissive']: - key.append(round(self.emissive, 3)) - else: - key.append(None) - - if global_prefs['get_ambient']: - key.append(round(self.ambient, 3)) - else: - key.append(None) - - if global_prefs['get_specular']: - for n in self.specular: - key.append(round(n, 3)) - else: - key.extend([None, None, None]) - - if global_prefs['get_diffuse']: - for n in self.diffuse: - key.append(round(n, 3)) - else: - key.extend([None, None, None]) - -# key.extend(self.face_props.values()) - - return tuple(key) - - def __init__(self): - self.name = 'Material' - # Colors, List of 3 floats. - self.diffuse = [1.0, 1.0, 1.0] - self.specular = [1.0, 1.0, 1.0] - - # Scalars - self.ambient = 0.0 # [0.0, 1.0] - self.emissive = 0.0 # [0.0, 1.0] - self.shininess = 0.5 # Range is [0.0, 2.0] - self.alpha = 1.0 # Range is [0.0, 1.0] - - self.tex0 = None - - # OpenFlight Face attributes - self.face_props = dict.fromkeys(['comment', 'ir color', 'priority', - 'draw type', 'texture white', 'template billboard', - 'smc', 'fid', 'ir material', 'lod generation control', - 'flags', 'light mode']) - -class VertexDesc: - def make_key(self): - return round(self.x, 6), round(self.y, 6), round(self.z, 6) - - def __init__(self): - - # Assign later, save memory, all verts have a loc - self.x = 0.0 - self.y = 0.0 - self.z = 0.0 - - - self.nx = 0.0 - self.ny = 0.0 - self.nz = 0.0 - - self.uv= Vector(0,0) - self.cindex = 127 #default/lowest - self.cnorm = False - -class LightPointAppDesc: - def make_key(self): - d = dict(self.props) - del d['id'] - del d['type'] - - if d['directionality'] != 0: # not omni - d['nx'] = 0.0 - d['ny'] = 0.0 - d['nz'] = 0.0 - - return tuple(d.values()) - - def __init__(self): - self.props = dict() - self.props.update({'type': 'LPA'}) - self.props.update({'id': 'ap'}) - # Attribs not found in inline lightpoint. - self.props.update({'visibility range': 0.0}) - self.props.update({'fade range ratio': 0.0}) - self.props.update({'fade in duration': 0.0}) - self.props.update({'fade out duration': 0.0}) - self.props.update({'LOD range ratio': 0.0}) - self.props.update({'LOD scale': 0.0}) - -class GlobalResourceRepository: - def request_lightpoint_app(self, desc, scene): - match = self.light_point_app.get(desc.make_key()) - - if match: - return match.getName() - else: - # Create empty and fill with properties. - name = desc.props['type'] + ': ' + desc.props['id'] - object = Blender.Object.New('Empty', name) - scene.objects.link(object) - object.Layers= current_layer - object.sel= 1 - - # Attach properties - for name, value in desc.props.iteritems(): - object.addProperty(name, value) - - self.light_point_app.update({desc.make_key(): object}) - - return object.getName() - - # Dont use request_vert - faster to make it from the vector direct. - """ - def request_vert(self, desc): - match = self.vert_dict.get(desc.make_key()) - - if match: - return match - else: - vert = Blender.Mathutils.Vector(desc.x, desc.y, desc.z) - ''' IGNORE_NORMALS - vert.no[0] = desc.nx - vert.no[1] = desc.ny - vert.no[2] = desc.nz - ''' - self.vert_dict.update({desc.make_key(): vert}) - return vert - """ - def request_mat(self, mat_desc): - match = self.mat_dict.get(mat_desc.make_key()) - if match: return match - - mat = Blender.Material.New(mat_desc.name) - - if mat_desc.tex0 != None: - mat.setTexture(0, mat_desc.tex0, Blender.Texture.TexCo.UV) - - mat.setAlpha(mat_desc.alpha) - mat.setSpec(mat_desc.shininess) - mat.setHardness(255) - mat.setEmit(mat_desc.emissive) - mat.setAmb(mat_desc.ambient) - mat.setSpecCol(mat_desc.specular) - mat.setRGBCol(mat_desc.diffuse) - - # Create a text object to store openflight face attribs until - # user properties can be set on materials. -# t = Blender.Text.New('FACE: ' + mat.getName()) -# -# for name, value in mat_desc.face_props.items(): -# t.write(name + '\n' + str(value) + '\n\n') - - self.mat_dict.update({mat_desc.make_key(): mat}) - - return mat - - def request_image(self, filename_with_path): - if not global_prefs['get_texture']: return None - return BPyImage.comprehensiveImageLoad(filename_with_path, global_prefs['fltfile']) # Use join in case of spaces - - def request_texture(self, image): - if not global_prefs['get_texture']: - return None - - tex = self.tex_dict.get(image.filename) - if tex: return tex - - tex = Blender.Texture.New(Blender.sys.basename(image.filename)) - tex.setImage(image) - tex.setType('Image') - self.tex_dict.update({image.filename: tex}) - return tex - - def __init__(self): - - #list of scenes xrefs belong to. - self.xrefs = dict() - # material - self.mat_dict = dict() - mat_lst = Blender.Material.Get() - for mat in mat_lst: - mat_desc = MaterialDesc() - mapto_lst = mat.getTextures() - if mapto_lst[0]: - mat_desc.tex0 = mapto_lst[0].tex - else: - mat_desc.tex0 = None - mat_desc.alpha = mat.getAlpha() - mat_desc.shininess = mat.getSpec() - mat_desc.emissive = mat.getEmit() - mat_desc.ambient = mat.getAmb() - mat_desc.specular = mat.getSpecCol() - mat_desc.diffuse = mat.getRGBCol() - - self.mat_dict.update({mat_desc.make_key(): mat}) - - # texture - self.tex_dict = dict() - tex_lst = Blender.Texture.Get() - - for tex in tex_lst: - img = tex.getImage() - # Only interested in textures with images. - if img: - self.tex_dict.update({img.filename: tex}) - - # vertex - # self.vert_dict = dict() - - # light point - self.light_point_app = dict() - -class Handler: - def in_throw_back_lst(self, opcode): - return opcode in self.throw_back_lst - - def handle(self, opcode): - return self.handler[opcode]() - - def handles(self, opcode): - return opcode in self.handler.iterkeys() - - def throws_back_all_unhandled(self): - return self.throw_back_unhandled - - def set_throw_back_lst(self, a): - self.throw_back_lst = a - - def set_throw_back_all_unhandled(self): - self.throw_back_unhandled = True - - def set_only_throw_back_specified(self): - self.throw_back_unhandled = False - - def set_handler(self, d): - self.handler = d - - def __init__(self): - # Dictionary of opcodes to handler methods. - self.handler = dict() - # Send all opcodes not handled to the parent node. - self.throw_back_unhandled = False - # If throw_back_unhandled is False then only throw back - # if the opcodes in throw_back are encountered. - self.throw_back_lst = list() - -class Node: - def blender_import(self): - if self.opcode in opcode_name and global_prefs['verbose'] >= 2: - for i in xrange(self.get_level()): - print ' ', - print opcode_name[self.opcode], - print '-', self.props['id'], - print '-', self.props['comment'], - - print - - for child in self.children: - child.blender_import() - -# Import comment. -# if self.props['comment'] != '': -# name = 'COMMENT: ' + self.props['id'] -# t = Blender.Text.New(name) -# t.write(self.props['comment']) -# self.props['comment'] = name - - # Always ignore extensions and anything in between them. - def parse_push_extension(self): - self.saved_handler = self.active_handler - self.active_handler = self.extension_handler - return True - - def parse_pop_extension(self): - self.active_handler = self.saved_handler - return True - - def parse_push(self): - self.header.fw.up_level() - # Ignore unknown children. - self.ignore_unhandled = True - # Don't do child records that might overwrite parent info. ex: longid - self.active_handler = self.child_handler - return True - - def parse_pop(self): - self.header.fw.down_level() - - if self.header.fw.get_level() == self.level: - return False - - return True - - def parse(self): - while self.header.fw.begin_record(): - opcode = self.header.fw.get_opcode() - - # Print out info on opcode and tree level. - if global_prefs['verbose'] >= 3: - p = '' - for i in xrange(self.header.fw.get_level()): - p = p + ' ' - if opcode in opcode_name: - p = p + opcode_name[opcode] - else: - if global_prefs['verbose'] >= 1: - print 'undocumented opcode', opcode - continue - - if self.global_handler.handles(opcode): - if global_prefs['verbose'] >= 3: - print p + ' handled globally' - if self.global_handler.handle(opcode) == False: - break - - elif self.active_handler.handles(opcode): - if global_prefs['verbose'] >= 4: - print p + ' handled' - if self.active_handler.handle(opcode) == False: - break - - else: - if self.active_handler.throws_back_all_unhandled(): - if global_prefs['verbose'] >= 3: - print p + ' handled elsewhere' - self.header.fw.repeat_record() - break - - elif self.active_handler.in_throw_back_lst(opcode): - if global_prefs['verbose'] >= 3: - print p + ' handled elsewhere' - self.header.fw.repeat_record() - break - - else: - if global_prefs['verbose'] >= 3: - print p + ' ignored' - elif global_prefs['verbose'] >= 1 and not opcode in do_not_report_opcodes and opcode in opcode_name: - print 'not handled' - - def get_level(self): - return self.level - - def parse_long_id(self): - self.props['id'] = self.header.fw.read_string(self.header.fw.get_length()-4) - return True - - def parse_comment(self): - self.props['comment'] = self.header.fw.read_string(self.header.fw.get_length()-4) - return True - - def parse_extension(self): - extension = dict() - props = records[100] - propkeys = props.keys() - propkeys.sort() - for position in propkeys: - (type,length,name) = props[position] - extension[name] = read_prop(self.header.fw,type,length) - #read extension data. - dstring = list() - for i in xrange(self.header.fw.get_length()-24): - dstring.append(self.header.fw.read_char()) - extension['data'] = dstring - self.extension = extension - def parse_record(self): - self.props['type'] = self.opcode - props = records[self.opcode] - propkeys = props.keys() - propkeys.sort() - for position in propkeys: - (type,length,name) = props[position] - self.props[name] = read_prop(self.header.fw,type,length) - try: #remove me! - self.props['id'] = self.props['3t8!id'] - except: - pass - def __init__(self, parent, header): - self.root_handler = Handler() - self.child_handler = Handler() - self.extension_handler = Handler() - self.global_handler = Handler() - - self.global_handler.set_handler({21: self.parse_push_extension}) - self.active_handler = self.root_handler - - # used by parse_*_extension - self.extension_handler.set_handler({22: self.parse_pop_extension}) - self.saved_handler = None - - self.header = header - self.children = list() - - self.parent = parent - - if parent: - parent.children.append(self) - - self.level = self.header.fw.get_level() - self.opcode = self.header.fw.get_opcode() - - self.props = {'id': 'unnamed', 'comment': '', 'type': 'untyped'} - -class VertexPalette(Node): - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - self.root_handler.set_handler({68: self.parse_vertex_c, - 69: self.parse_vertex_cn, - 70: self.parse_vertex_cnuv, - 71: self.parse_vertex_cuv}) - self.root_handler.set_throw_back_all_unhandled() - - self.vert_desc_lst = list() - self.blender_verts = list() - self.offset = 8 - # Used to create a map from byte offset to vertex index. - self.index = dict() - - - def blender_import(self): - self.blender_verts.extend([Vector(vert_desc.x, vert_desc.y, vert_desc.z) for vert_desc in self.vert_desc_lst ]) - - def parse_vertex_common(self): - # Add this vertex to an offset to index dictionary. - #self.index_lst.append( (self.offset, self.next_index) ) - self.index[self.offset]= len(self.index) - - # Get ready for next record. - self.offset += self.header.fw.get_length() - - v = VertexDesc() - - self.header.fw.read_ahead(2) - v.flags = self.header.fw.read_short() - - v.x = self.header.fw.read_double() - v.y = self.header.fw.read_double() - v.z = self.header.fw.read_double() - - return v - - def parse_vertex_post_common(self, v): - #if not v.flags & 0x2000: # 0x2000 = no color - #if v.flags & 0x1000: # 0x1000 = packed color - # v.a = self.header.fw.read_uchar() - # v.b = self.header.fw.read_uchar() - # v.g = self.header.fw.read_uchar() - # v.r = self.header.fw.read_uchar() - #else: - self.header.fw.read_ahead(4) #skip packed color - v.cindex = self.header.fw.read_uint() - self.vert_desc_lst.append(v) - return True - - def parse_vertex_c(self): - v = self.parse_vertex_common() - - self.parse_vertex_post_common(v) - - return True - - def parse_vertex_cn(self): - v = self.parse_vertex_common() - v.cnorm = True - v.nx = self.header.fw.read_float() - v.ny = self.header.fw.read_float() - v.nz = self.header.fw.read_float() - - self.parse_vertex_post_common(v) - - return True - - def parse_vertex_cuv(self): - v = self.parse_vertex_common() - - v.uv[:] = self.header.fw.read_float(), self.header.fw.read_float() - - self.parse_vertex_post_common(v) - - return True - - def parse_vertex_cnuv(self): - v = self.parse_vertex_common() - v.cnorm = True - v.nx = self.header.fw.read_float() - v.ny = self.header.fw.read_float() - v.nz = self.header.fw.read_float() - - v.uv[:] = self.header.fw.read_float(), self.header.fw.read_float() - - self.parse_vertex_post_common(v) - - return True - - def parse(self): # Run once per import - Node.parse(self) - - -class InterNode(Node): - def __init__(self): - self.object = None - self.mesh = None - self.swapmesh = None - self.hasMesh = False - self.faceLs= [] - self.matrix = None - self.vis = True - self.hasmtex = False - self.uvlayers = dict() - self.blayernames = dict() - self.subfacelevel = 0 - self.extension = None - - mask = 2147483648 - for i in xrange(7): - self.uvlayers[mask] = False - mask = mask / 2 - - ####################################################### - ## Begin Remove Doubles Replacement ## - ####################################################### - def __xvertsort(self,__a,__b): - (__vert, __x1) = __a - (__vert2,__x2) = __b - - if __x1 > __x2: - return 1 - elif __x1 < __x2: - return -1 - return 0 - def __calcFaceNorm(self,__face): - if len(__face) == 3: - return Blender.Mathutils.TriangleNormal(__face[0].co, __face[1].co, __face[2].co) - elif len(__face) == 4: - return Blender.Mathutils.QuadNormal(__face[0].co, __face[1].co, __face[2].co, __face[3].co) - - def __replaceFaceVert(self,__weldface, __oldvert, __newvert): - __index = None - for __i, __v in enumerate(__weldface): - if __v == __oldvert: - __index = __i - break - __weldface[__index] = __newvert - - def __matchEdge(self,__weldmesh, __edge1, __edge2): - if __edge1[0] in __weldmesh['Vertex Disk'][__edge2[1]] and __edge1[1] in __weldmesh['Vertex Disk'][__edge2[0]]: - return True - return False - #have to compare original faces! - def __faceWinding(self, __weldmesh, __face1, __face2): - - __f1edges = list() - __f2edges = list() - - __f1edges.append((__face1.verts[0], __face1.verts[1])) - __f1edges.append((__face1.verts[1], __face1.verts[2])) - if len(__face1.verts) == 3: - __f1edges.append((__face1.verts[2], __face1.verts[0])) - else: - __f1edges.append((__face1.verts[2], __face1.verts[3])) - __f1edges.append((__face1.verts[3], __face1.verts[0])) - - __f2edges.append((__face2.verts[0], __face2.verts[1])) - __f2edges.append((__face2.verts[1], __face2.verts[2])) - if len(__face2.verts) == 3: - __f2edges.append((__face2.verts[2], __face2.verts[0])) - else: - __f2edges.append((__face2.verts[2], __face2.verts[3])) - __f2edges.append((__face2.verts[3], __face2.verts[0])) - - - #find a matching edge - for __edge1 in __f1edges: - for __edge2 in __f2edges: - if self.__matchEdge(__weldmesh, __edge1, __edge2): #no more tests nessecary - return True - - return False - - def __floatcompare(self, __f1, __f2): - epsilon = 0.1 - if ((__f1 + epsilon) > __f2) and ((__f1 - epsilon) < __f2): - return True - return False - def __testFace(self,__weldmesh,__v1face, __v2face, __v1bface, __v2bface): - limit = 0.01 - __matchvert = None - #frst test (for real this time!). Are the faces the same face? - if __v1face == __v2face: - return False - - #first test: Do the faces possibly geometrically share more than two vertices? we should be comparing original faces for this? - Yes..... - __match = 0 - for __vert in __v1bface.verts: - for __vert2 in __v2bface.verts: - #if (abs(__vert.co[0] - __vert2.co[0]) <= limit) and (abs(__vert.co[1] - __vert2.co[1]) <= limit) and (abs(__vert.co[2] - __vert2.co[2]) <= limit): #this needs to be fixed! - if __vert2 in __weldmesh['Vertex Disk'][__vert] or __vert == __vert2: - __match += 1 - __matchvert = __vert2 - #avoid faces sharing more than two verts - if __match > 2: - return False - - #consistent winding for face normals - if __match == 2: - if not self.__faceWinding(__weldmesh, __v1bface, __v2bface): - return False - - #second test: Compatible normals.Anything beyond almost exact opposite is 'ok' - __v1facenorm = self.__calcFaceNorm(__v1face) - __v2facenorm = self.__calcFaceNorm(__v2face) - - #dont even mess with zero length faces - if __v1facenorm.length < limit: - return False - if __v2facenorm.length < limit: - return False - - __v1facenorm.normalize() - __v2facenorm.normalize() - - if __match == 1: - #special case, look for comparison of normals angle - __angle = Blender.Mathutils.AngleBetweenVecs(__v1facenorm, __v2facenorm) - if __angle > 70.0: - return False - - - - __v2facenorm = __v2facenorm.negate() - - if self.__floatcompare(__v1facenorm[0], __v2facenorm[0]) and self.__floatcompare(__v1facenorm[1], __v2facenorm[1]) and self.__floatcompare(__v1facenorm[2], __v2facenorm[2]): - return False - - #next test: dont weld a subface to a non-subface! - if __v1bface.getProperty("FLT_SFLEVEL") != __v2bface.getProperty("FLT_SFLEVEL"): - return False - - #final test: edge test - We dont want to create a non-manifold edge through our weld operation - - return True - - def __copyFaceData(self, __source, __target): - #copy vcolor layers. - __actColLayer = self.mesh.activeColorLayer - for __colorlayer in self.mesh.getColorLayerNames(): - self.mesh.activeColorLayer = __colorlayer - for __i, __col in enumerate(__source.col): - __target.col[__i].r = __col.r - __target.col[__i].g = __col.g - __target.col[__i].b = __col.b - - self.mesh.activeColorLayer = __actColLayer - #copy uv layers. - __actUVLayer = self.mesh.activeUVLayer - for __uvlayer in self.mesh.getUVLayerNames(): - self.mesh.activeUVLayer = __uvlayer - __target.image = __source.image - __target.mode = __source.mode - __target.smooth = __source.smooth - __target.transp = __source.transp - for __i, __uv in enumerate(__source.uv): - __target.uv[__i][0] = __uv[0] - __target.uv[__i][1] = __uv[1] - - self.mesh.activeUVLayer = __actUVLayer - #copy property layers - for __property in self.mesh.faces.properties: - __target.setProperty(__property, __source.getProperty(__property)) - - def findDoubles(self): - limit = 0.01 - sortblock = list() - double = dict() - for vert in self.mesh.verts: - double[vert] = None - sortblock.append((vert, vert.co[0] + vert.co[1] + vert.co[2])) - sortblock.sort(self.__xvertsort) - - a = 0 - while a < len(self.mesh.verts): - (vert,xsort) = sortblock[a] - b = a+1 - if not double[vert]: - while b < len(self.mesh.verts): - (vert2, xsort2) = sortblock[b] - if not double[vert2]: - #first test, simple distance - if (xsort2 - xsort) > limit: - break - #second test, more expensive - if (abs(vert.co[0] - vert2.co[0]) <= limit) and (abs(vert.co[1] - vert2.co[1]) <= limit) and (abs(vert.co[2] - vert2.co[2]) <= limit): - double[vert2] = vert - b+=1 - a+=1 - - return double - - def buildWeldMesh(self): - - weldmesh = dict() - weldmesh['Vertex Disk'] = dict() #this is geometric adjacency - weldmesh['Vertex Faces'] = dict() #topological adjacency - - #find the doubles for this mesh - double = self.findDoubles() - - for vert in self.mesh.verts: - weldmesh['Vertex Faces'][vert] = list() - - #create weld faces - weldfaces = list() - originalfaces = list() - for face in self.mesh.faces: - weldface = list() - for vert in face.verts: - weldface.append(vert) - weldfaces.append(weldface) - originalfaces.append(face) - for i, weldface in enumerate(weldfaces): - for vert in weldface: - weldmesh['Vertex Faces'][vert].append(i) - weldmesh['Weld Faces'] = weldfaces - weldmesh['Original Faces'] = originalfaces - - #Now we need to build the vertex disk data. first we do just the 'target' vertices - for vert in self.mesh.verts: - if not double[vert]: #its a target - weldmesh['Vertex Disk'][vert] = list() - for vert in self.mesh.verts: - if double[vert]: #its a double - weldmesh['Vertex Disk'][double[vert]].append(vert) - - #Now we need to create the disk information for the remaining vertices - targets = weldmesh['Vertex Disk'].keys() - for target in targets: - for doublevert in weldmesh['Vertex Disk'][target]: - weldmesh['Vertex Disk'][doublevert] = [target] - for othervert in weldmesh['Vertex Disk'][target]: - if othervert != doublevert: - weldmesh['Vertex Disk'][doublevert].append(othervert) - - return weldmesh - - def weldFuseFaces(self,weldmesh): - - #retain original loose vertices - looseverts = dict() - for vert in self.mesh.verts: - looseverts[vert] = 0 - for edge in self.mesh.edges: - looseverts[edge.v1] += 1 - looseverts[edge.v2] += 1 - - - - #slight modification here: we need to walk around the mesh as many times as it takes to have no more matches - done = 0 - while not done: - done = 1 - for windex, weldface in enumerate(weldmesh['Weld Faces']): - for vertex in weldface: - #we walk around the faces of the doubles of this vertex and if possible, we weld them. - for doublevert in weldmesh['Vertex Disk'][vertex]: - removeFaces = list() #list of faces to remove from doubleverts face list - for doublefaceindex in weldmesh['Vertex Faces'][doublevert]: - doubleface = weldmesh['Weld Faces'][doublefaceindex] - oface1 = self.mesh.faces[windex] - oface2 = self.mesh.faces[doublefaceindex] - ok = self.__testFace(weldmesh, weldface, doubleface, oface1, oface2) - if ok: - done = 0 - removeFaces.append(doublefaceindex) - self.__replaceFaceVert(doubleface, doublevert, vertex) - for doublefaceindex in removeFaces: - weldmesh['Vertex Faces'][doublevert].remove(doublefaceindex) - #old faces first - oldindices = list() - for face in self.mesh.faces: - oldindices.append(face.index) - #make our new faces. - newfaces = list() - for weldface in weldmesh['Weld Faces']: - newfaces.append(weldface) - newindices = self.mesh.faces.extend(newfaces, indexList=True, ignoreDups=True) - #copy custom data over - for i, newindex in enumerate(newindices): - try: - self.__copyFaceData(self.mesh.faces[oldindices[i]], self.mesh.faces[newindex]) - except: - print "warning, could not copy face data!" - #delete the old faces - self.mesh.faces.delete(1, oldindices) - - #Clean up stray vertices - vertuse = dict() - for vert in self.mesh.verts: - vertuse[vert] = 0 - for face in self.mesh.faces: - for vert in face.verts: - vertuse[vert] += 1 - delverts = list() - for vert in self.mesh.verts: - if not vertuse[vert] and vert.index != 0 and looseverts[vert]: - delverts.append(vert) - - self.mesh.verts.delete(delverts) - - - ####################################################### - ## End Remove Doubles Replacement ## - ####################################################### - - def blender_import_my_faces(self): - - # Add the verts onto the mesh - blender_verts= self.header.vert_pal.blender_verts - vert_desc_lst= self.header.vert_pal.vert_desc_lst - - vert_list= [ i for flt_face in self.faceLs for i in flt_face.indices] #splitting faces apart. Is this a good thing? - face_edges= [] - face_verts= [] - self.mesh.verts.extend([blender_verts[i] for i in vert_list]) - - new_faces= [] - new_faces_props= [] - ngon= BPyMesh.ngon - vert_index= 1 - - #add vertex color layer for baked face colors. - self.mesh.addColorLayer("FLT_Fcol") - self.mesh.activeColorLayer = "FLT_Fcol" - - FLT_OrigIndex = 0 - for flt_face in self.faceLs: - if flt_face.tex_index != -1: - try: - image= self.header.tex_pal[flt_face.tex_index][1] - except KeyError: - image= None - else: - image= None - face_len= len(flt_face.indices) - - #create dummy uvert dicts - if len(flt_face.uverts) == 0: - for i in xrange(face_len): - flt_face.uverts.append(dict()) - #May need to patch up MTex info - if self.hasmtex: - #For every layer in mesh, there should be corresponding layer in the face - for mask in self.uvlayers.keys(): - if self.uvlayers[mask]: - if not flt_face.uvlayers.has_key(mask): #Does the face have this layer? - #Create Layer info for this face - flt_face.uvlayers[mask] = dict() - flt_face.uvlayers[mask]['texture index'] = -1 - flt_face.uvlayers[mask]['texture enviorment'] = 3 - flt_face.uvlayers[mask]['texture mapping'] = 0 - flt_face.uvlayers[mask]['texture data'] = 0 - - #now go through and create dummy uvs for this layer - for uvert in flt_face.uverts: - uv = Vector(0.0,0.0) - uvert[mask] = uv - - # Get the indicies in reference to the mesh. - uvs= [vert_desc_lst[j].uv for j in flt_face.indices] - if face_len == 1: - pass - elif face_len == 2: - face_edges.append((vert_index, vert_index+1)) - elif flt_face.props['draw type'] == 2 or flt_face.props['draw type'] == 3: - i = 0 - while i < (face_len-1): - face_edges.append((vert_index + i, vert_index + i + 1)) - i = i + 1 - if flt_face.props['draw type'] == 2: - face_edges.append((vert_index + i,vert_index)) - elif face_len == 3 or face_len == 4: # tri or quad - #if face_len == 1: - # pass - #if face_len == 2: - # face_edges.append((vert_index, vert_index+1)) - new_faces.append( [i+vert_index for i in xrange(face_len)] ) - new_faces_props.append((None, image, uvs, flt_face.uverts, flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,0, flt_face.subfacelevel)) - - else: # fgon - mesh_face_indicies = [i+vert_index for i in xrange(face_len)] - tri_ngons= ngon(self.mesh, mesh_face_indicies) - if len(tri_ngons) != 1: - new_faces.extend([ [mesh_face_indicies[t] for t in tri] for tri in tri_ngons]) - new_faces_props.extend( [ (None, image, (uvs[tri[0]], uvs[tri[1]], uvs[tri[2]]), [flt_face.uverts[tri[0]], flt_face.uverts[tri[1]], flt_face.uverts[tri[2]]], flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,1, flt_face.subfacelevel) for tri in tri_ngons ]) - - vert_index+= face_len - FLT_OrigIndex+=1 - - self.mesh.faces.extend(new_faces) - self.mesh.edges.extend(face_edges) - - #add in the FLT_ORIGINDEX layer - if len(self.mesh.faces): - try: self.mesh.faceUV= True - except: pass - - if self.mesh.faceUV == True: - self.mesh.renameUVLayer(self.mesh.activeUVLayer, 'Layer0') - - #create name layer for faces - self.mesh.faces.addPropertyLayer("FLT_ID",Blender.Mesh.PropertyTypes["STRING"]) - #create layer for face color indices - self.mesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"]) - #create index layer for faces. This is needed by both FGONs and subfaces - self.mesh.faces.addPropertyLayer("FLT_ORIGINDEX",Blender.Mesh.PropertyTypes["INT"]) - #create temporary FGON flag layer. Delete after remove doubles - self.mesh.faces.addPropertyLayer("FLT_FGON",Blender.Mesh.PropertyTypes["INT"]) - self.mesh.faces.addPropertyLayer("FLT_SFLEVEL", Blender.Mesh.PropertyTypes["INT"]) - - for i, f in enumerate(self.mesh.faces): - props = new_faces_props[i] - if props[6]['template billboard'] > 0: - f.transp |= Blender.Mesh.FaceTranspModes["ALPHA"] - if props[6]['template billboard'] == 2: - f.mode |= Blender.Mesh.FaceModes["BILLBOARD"] - f.mode |= Blender.Mesh.FaceModes["LIGHT"] - if props[6]['draw type'] == 1: - f.mode |= Blender.Mesh.FaceModes["TWOSIDE"] - - #f.mat = props[0] - f.image = props[1] - f.uv = props[2] - #set vertex colors - color = self.header.get_color(props[5]) - if not color: - color = [255,255,255,255] - for mcol in f.col: - mcol.a = color[3] - mcol.r = color[0] - mcol.g = color[1] - mcol.b = color[2] - - f.setProperty("FLT_SFLEVEL", props[9]) - f.setProperty("FLT_ORIGINDEX",i) - f.setProperty("FLT_ID",props[6]['id']) - #if props[5] > 13199: - # print "Warning, invalid color index read in! Using default!" - # f.setProperty("FLT_COL",127) - #else: - if(1): #uh oh.... - value = struct.unpack('>i',struct.pack('>I',props[5]))[0] - f.setProperty("FLT_COL",value) - - #if props[8]: - # f.setProperty("FLT_FGON",1) - #else: - # f.setProperty("FLT_FGON",0) - - - #Create multitex layers, if present. - actuvlayer = self.mesh.activeUVLayer - if(self.hasmtex): - #For every multi-tex layer, we have to add a new UV layer to the mesh - for i,mask in enumerate(reversed(sorted(self.uvlayers))): - if self.uvlayers[mask]: - self.blayernames[mask] = "Layer" + str(i+1) - self.mesh.addUVLayer(self.blayernames[mask]) - - #Cycle through availible multi-tex layers and add face UVS - for mask in self.uvlayers: - if self.uvlayers[mask]: - self.mesh.activeUVLayer = self.blayernames[mask] - for j, f in enumerate(self.mesh.faces): - if props[6]['draw type'] == 1: - f.mode |= Blender.Mesh.FaceModes["TWOSIDE"] - f.transp |= Blender.Mesh.FaceTranspModes["ALPHA"] - f.mode |= Blender.Mesh.FaceModes["LIGHT"] - props = new_faces_props[j] - uvlayers = props[4] - if uvlayers.has_key(mask): #redundant - uverts = props[3] - for k, uv in enumerate(f.uv): - uv[0] = uverts[k][mask][0] - uv[1] = uverts[k][mask][1] - - uvlayer = uvlayers[mask] - tex_index = uvlayer['texture index'] - if tex_index != -1: - try: - f.image = self.header.tex_pal[tex_index][1] - except KeyError: - f.image = None - - if global_prefs['smoothshading'] == True and len(self.mesh.faces): - #We need to store per-face vertex normals in the faces as UV layers and delete them later. - self.mesh.addUVLayer("FLTNorm1") - self.mesh.addUVLayer("FLTNorm2") - self.mesh.activeUVLayer = "FLTNorm1" - for f in self.mesh.faces: - f.smooth = 1 - #grab the X and Y components of normal and store them in UV - for i, uv in enumerate(f.uv): - vert = f.v[i].index - vert_desc = vert_desc_lst[vert_list[vert-1]] - if vert_desc.cnorm: - uv[0] = vert_desc.nx - uv[1] = vert_desc.ny - else: - uv[0] = 0.0 - uv[1] = 0.0 - - #Now go through and populate the second UV Layer with the z component - self.mesh.activeUVLayer = "FLTNorm2" - for f in self.mesh.faces: - for i, uv in enumerate(f.uv): - vert = f.v[i].index - vert_desc = vert_desc_lst[vert_list[vert-1]] - if vert_desc.cnorm: - uv[0] = vert_desc.nz - uv[1] = 0.0 - else: - uv[0] = 0.0 - uv[1] = 0.0 - - - - #Finally, go through, remove dummy vertex, remove doubles and add edgesplit modifier. - Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX']) - self.mesh.sel= 1 - self.header.scene.update(1) #slow! - - #self.mesh.remDoubles(0.0001) - weldmesh = self.buildWeldMesh() - welded = self.weldFuseFaces(weldmesh) - self.mesh.verts.delete(0) # remove the dummy vert - - edgeHash = dict() - - for edge in self.mesh.edges: - edgeHash[edge.key] = edge.index - - - if global_prefs['smoothshading'] == True and len(self.mesh.faces): - - #rip out the custom vertex normals from the mesh and place them in a face aligned list. Easier to compare this way. - facenorms = [] - self.mesh.activeUVLayer = "FLTNorm1" - for face in self.mesh.faces: - facenorm = [] - for uv in face.uv: - facenorm.append(Vector(uv[0],uv[1],0.0)) - facenorms.append(facenorm) - self.mesh.activeUVLayer = "FLTNorm2" - for i, face in enumerate(self.mesh.faces): - facenorm = facenorms[i] - for j, uv in enumerate(face.uv): - facenorm[j][2] = uv[0] - self.mesh.removeUVLayer("FLTNorm1") - self.mesh.removeUVLayer("FLTNorm2") - - #find hard edges - #store edge data for lookup by faces - #edgeHash = dict() - #for edge in self.mesh.edges: - # edgeHash[edge.key] = edge.index - - edgeNormHash = dict() - #make sure to align the edgenormals to key value! - for i, face in enumerate(self.mesh.faces): - - facenorm = facenorms[i] - faceEdges = [] - faceEdges.append((face.v[0].index,face.v[1].index,facenorm[0],facenorm[1],face.edge_keys[0])) - faceEdges.append((face.v[1].index,face.v[2].index,facenorm[1],facenorm[2],face.edge_keys[1])) - if len(face.v) == 3: - faceEdges.append((face.v[2].index,face.v[0].index,facenorm[2],facenorm[0],face.edge_keys[2])) - elif len(face.v) == 4: - faceEdges.append((face.v[2].index,face.v[3].index,facenorm[2],facenorm[3],face.edge_keys[2])) - faceEdges.append((face.v[3].index,face.v[0].index,facenorm[3],facenorm[0],face.edge_keys[3])) - - #check to see if edgeNormal has been placed in the edgeNormHash yet - #this is a redundant test, and should be optimized to not be called as often as it is. - for j, faceEdge in enumerate(faceEdges): - #the value we are looking for is (faceEdge[2],faceEdge[3]) - hashvalue = (faceEdge[2],faceEdge[3]) - if (faceEdge[0],faceEdge[1]) != faceEdge[4]: - hashvalue = (hashvalue[1],hashvalue[0]) - assert (faceEdge[1],faceEdge[0]) == faceEdge[4] - if edgeNormHash.has_key(faceEdge[4]): - #compare value in the hash, if different, mark as sharp - edgeNorm = edgeNormHash[faceEdge[4]] - if\ - abs(hashvalue[0][0] - edgeNorm[0][0]) > FLOAT_TOLERANCE or\ - abs(hashvalue[0][1] - edgeNorm[0][1]) > FLOAT_TOLERANCE or\ - abs(hashvalue[0][2] - edgeNorm[0][2]) > FLOAT_TOLERANCE or\ - abs(hashvalue[1][0] - edgeNorm[1][0]) > FLOAT_TOLERANCE or\ - abs(hashvalue[1][1] - edgeNorm[1][1]) > FLOAT_TOLERANCE or\ - abs(hashvalue[1][2] - edgeNorm[1][2]) > FLOAT_TOLERANCE: - edge = self.mesh.edges[edgeHash[faceEdge[4]]] - edge.flag |= Blender.Mesh.EdgeFlags.SHARP - - else: - edgeNormHash[faceEdge[4]] = hashvalue - - #add in edgesplit modifier - mod = self.object.modifiers.append(Blender.Modifier.Types.EDGESPLIT) - mod[Blender.Modifier.Settings.EDGESPLIT_FROM_SHARP] = True - mod[Blender.Modifier.Settings.EDGESPLIT_FROM_ANGLE] = False - - if(actuvlayer): - self.mesh.activeUVLayer = actuvlayer - - def blender_import(self): - if self.vis and self.parent.object: - self.vis = self.parent.vis - name = self.props['id'] - - - if self.hasMesh: - self.mesh = Blender.Mesh.New() - self.mesh.name = 'FLT_FaceList' - self.mesh.fakeUser = True - self.mesh.verts.extend( Vector()) #DUMMYVERT - self.object = self.header.scene.objects.new(self.mesh) - else: - self.object = self.header.scene.objects.new('Empty') - - self.object.name = name - self.header.group.objects.link(self.object) - - #id props import - self.object.properties['FLT'] = dict() - for key in self.props: - try: - self.object.properties['FLT'][key] = self.props[key] - except: #horrible... - pass - - - if self.extension: - self.object.properties['FLT']['EXT'] = dict() - for key in self.extension: - self.object.properties['FLT']['EXT'][key] = self.extension[key] - - if self.parent and self.parent.object and (self.header.scene == self.parent.header.scene): - self.parent.object.makeParent([self.object],1) - - if self.matrix: - self.object.setMatrix(self.matrix) - - if self.vis == False: - self.object.restrictDisplay = True - self.object.restrictRender = True - - else: #check for LOD children and set the proper flags - lodlist = list() - for child in self.children: - if child.props.has_key('type') and child.props['type'] == 73: - if child.props['6d!switch out'] != 0.0: - child.vis = False - #lodlist.append(child) - - #def LODmin(a,b): - # if a.props['5d!switch in'] < b.props['5d!switch in']: - # return a - # return b - - #min= None - #if len(lodlist) > 1: - # for lod in lodlist: - # lod.vis = False - # min = lodlist[0] - # for i in xrange(len(lodlist)): - # min= LODmin(min,lodlist[i]) - # min.vis = True - - - Node.blender_import(self) # Attach faces to self.faceLs - - if self.hasMesh: - # Add all my faces into the mesh at once - self.blender_import_my_faces() - - def parse_face(self): - child = Face(self, self.subfacelevel) - child.parse() - return True - - def parse_group(self): - child = Group(self) - child.parse() - return True - - def move_to_next_layer(self): - global current_layer - current_layer = current_layer << 1 - if current_layer > 0x80000: - current_layer = 1 - - def parse_lod(self): - child = LOD(self) - child.parse() - return True - - def parse_unhandled(self): - child = Unhandled(self) - child.parse() - return True - - def parse_object(self): - child = Object(self) - child.parse() - return True - - def parse_xref(self): - child = XRef(self) - child.parse() - return True - - def parse_dof(self): - child = DOF(self) - child.parse() - return True - - def parse_indexed_light_point(self): - child = IndexedLightPoint(self) - child.parse() - return True - - def parse_inline_light_point(self): - child = InlineLightPoint(self) - child.parse() - return True - - def parse_matrix(self): - m = list() - for i in xrange(4): - m.append([]) - for j in xrange(4): - f = self.header.fw.read_float() - m[i].append(f) - self.matrix = Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3]) - - def parse_subpush(self): - self.parse_push() - self.subfacelevel+= 1 - return True - def parse_subpop(self): - self.parse_pop() - self.subfacelevel -= 1 - return True - - - -class Face(Node): - def __init__(self, parent,subfacelevel): - Node.__init__(self, parent, parent.header) - self.root_handler.set_handler({31: self.parse_comment, - 10: self.parse_push, - 52: self.parse_multitex}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({72: self.parse_vertex_list, - 10: self.parse_push, - 11: self.parse_pop, - 53: self.parse_uvlist}) - - if parent: - parent.hasMesh = True - - self.subfacelevel = subfacelevel - self.indices = list() # face verts here - self.uvlayers = dict() # MultiTexture layers keyed to layer bitmask. - self.uverts = list() # Vertex aligned list of dictionaries keyed to layer bitmask. - self.uvmask = 0 # Bitfield read from MTex record - - self.comment = '' - self.props = dict() - self.props['id'] = self.header.fw.read_string(8) - # Load face. - self.props['ir color'] = self.header.fw.read_int() - self.props['priority'] = self.header.fw.read_short() - self.props['draw type'] = self.header.fw.read_char() - self.props['texture white'] = self.header.fw.read_char() - self.header.fw.read_ahead(4) # color name indices - self.header.fw.read_ahead(1) # reserved - self.props['template billboard'] = self.header.fw.read_uchar() - self.detail_tex_index = self.header.fw.read_short() - self.tex_index = self.header.fw.read_short() - self.mat_index = self.header.fw.read_short() - self.props['smc'] = self.header.fw.read_short() - self.props['fid'] = self.header.fw.read_short() - self.props['ir material'] = self.header.fw.read_int() - self.alpha = 1.0 - float(self.header.fw.read_ushort()) / 65535.0 - self.props['lod generation control'] = self.header.fw.read_uchar() - self.header.fw.read_ahead(1) # line style index - self.props['flags'] = self.header.fw.read_int() - self.props['light mode'] = self.header.fw.read_uchar() - self.header.fw.read_ahead(7) - a = self.header.fw.read_uchar() - b = self.header.fw.read_uchar() - g = self.header.fw.read_uchar() - r = self.header.fw.read_uchar() - self.packed_color = [r, g, b, a] - a = self.header.fw.read_uchar() - b = self.header.fw.read_uchar() - g = self.header.fw.read_uchar() - r = self.header.fw.read_uchar() - self.alt_packed_color = [r, g, b, a] - self.tex_map_index = self.header.fw.read_short() - self.header.fw.read_ahead(2) - self.color_index = self.header.fw.read_uint() - self.alt_color_index = self.header.fw.read_uint() - #self.header.fw.read_ahead(2) - #self.shader_index = self.header.fw.read_short() - - def parse_comment(self): - self.comment = self.header.fw.read_string(self.header.fw.get_length()-4) - return True - - def blender_import(self): - vert_count = len(self.indices) - if vert_count < 1: - if global_prefs['verbose'] >= 2: - print 'Warning: Ignoring face with no vertices.' - return - - # Assign material and image - - self.parent.faceLs.append(self) - #need to store comment in mesh prop layer! - - # Store comment info in parent. - #if self.comment != '': - # if self.parent.props['comment'] != '': - # self.parent.props['comment'] += '\n\nFrom Face:\n' + self.comment - # else: - # self.parent.props['comment'] = self.comment - - if self.uvlayers: - #Make sure that the mesh knows about the layers that this face uses - self.parent.hasmtex = True - for mask in self.uvlayers.keys(): - self.parent.uvlayers[mask] = True - - def parse_vertex_list(self): - length = self.header.fw.get_length() - fw = self.header.fw - vert_pal = self.header.vert_pal - - count = (length-4)/4 - - # If this ever fails the chunk below does error checking - self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)] - ''' - for i in xrange(count): - byte_offset = fw.read_int() - if byte_offset in vert_pal.index: - index = vert_pal.index[byte_offset] - self.indices.append(index) - elif global_prefs['verbose'] >= 1: - print 'Warning: Unable to map byte offset %s' + \ - ' to vertex index.' % byte_offset - ''' - return True - - def parse_multitex(self): - #Parse MultiTex Record. - length = self.header.fw.get_length() - fw = self.header.fw - #num layers == (length - 8) / 4 - uvmask = fw.read_uint() - mask = 2147483648 - for i in xrange(7): - if mask & uvmask: - uvlayer = dict() - self.uvlayers[mask] = uvlayer - mask = mask / 2 - - #read in record for each individual layer. - for key in reversed(sorted(self.uvlayers)): - uvlayer = self.uvlayers[key] - uvlayer['texture index'] = fw.read_ushort() - uvlayer['texture enviorment'] = fw.read_ushort() - uvlayer['texture mapping'] = fw.read_ushort() - uvlayer['texture data'] = fw.read_ushort() - - self.uvmask = uvmask - - def parse_uvlist(self): - #for each uvlayer, add uv vertices - length = self.header.fw.get_length() - fw = self.header.fw - uvmask = fw.read_uint() - if uvmask != self.uvmask: #This should never happen! - fw.read_ahead(self.length - 4) #potentially unnessecary? - else: - #need to store in uvverts dictionary for each vertex. - totverts = len(self.indices) - for i in xrange(totverts): - uvert = dict() - for key in reversed(sorted(self.uvlayers)): - uv = Vector(0.0,0.0) - uv[0] = fw.read_float() - uv[1] = fw.read_float() - uvert[key] = uv - self.uverts.append(uvert) - -class Object(InterNode): - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - - self.root_handler.set_handler({33: self.parse_long_id, - 21: self.parse_push_extension, - 31: self.parse_comment, - 10: self.parse_push, - 49: self.parse_matrix}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({5: self.parse_face, - 19: self.parse_subpush, - 20: self.parse_subpop, - 111: self.parse_inline_light_point, - 10: self.parse_push, - 11: self.parse_pop}) - self.extension_handler.set_handler({22: self.parse_pop_extension, - 100: self.parse_extension}) - - self.extension = dict() - self.props = dict() - self.props['comment'] = '' - self.parse_record() - -class Group(InterNode): - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - - self.root_handler.set_handler({33: self.parse_long_id, - 31: self.parse_comment, - 10: self.parse_push, - 49: self.parse_matrix, - 21: self.parse_push_extension}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({5: self.parse_face, - 19: self.parse_subpush, - 20: self.parse_subpop, - 111: self.parse_inline_light_point, - 2: self.parse_group, - 73: self.parse_lod, - 4: self.parse_object, - 10: self.parse_push, - 11: self.parse_pop, - 96: self.parse_unhandled, - 14: self.parse_dof, - 91: self.parse_unhandled, - 98: self.parse_unhandled, - 63: self.parse_xref}) - - self.extension_handler.set_handler({22: self.parse_pop_extension, - 100: self.parse_extension}) - - self.props = dict.fromkeys(['type', 'id', 'comment', 'priority', 'flags', 'special1', - 'special2', 'significance', 'layer code', 'loop count', - 'loop duration', 'last frame duration']) - - self.props['comment'] = '' - self.parse_record() - - #self.props['type'] = str(self.opcode) + ':' + opcode_name[self.opcode] - #props = records[self.opcode] - #propkeys = props.keys() - #propkeys.sort() - #for position in propkeys: - # (type,length,name) = props[position] - # self.props[name] = read_prop(self.header.fw,type,length) - #self.props['id'] = self.props['3t8!id'] - -class DOF(InterNode): - def blender_import(self): - InterNode.blender_import(self) - - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - - self.root_handler.set_handler({33: self.parse_long_id, - 31: self.parse_comment, - 10: self.parse_push, - 49: self.parse_matrix, - 21: self.parse_push_extension}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({#130: self.parse_indexed_light_point, - 111: self.parse_inline_light_point, - 2: self.parse_group, - 73: self.parse_lod, - 4: self.parse_object, - 10: self.parse_push, - 11: self.parse_pop, - 96: self.parse_unhandled, - 14: self.parse_dof, - 91: self.parse_unhandled, - 98: self.parse_unhandled, - 63: self.parse_xref}) - self.extension_handler.set_handler({22: self.parse_pop_extension, - 100: self.parse_extension}) - self.props = dict() - self.props['comment'] = '' - self.parse_record() - - -class XRef(InterNode): - def parse(self): - if self.xref: - self.xref.parse() - Node.parse(self) - - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - - self.root_handler.set_handler({49: self.parse_matrix}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.props = dict() - self.props['comment'] = '' - self.parse_record() - - xref_filename = self.props['3t200!filename'] #I dont even think there is a reason to keep this around... - - if not os.path.isabs(xref_filename): - absname = os.path.join(os.path.dirname(self.header.filename), xref_filename) - else: - absname = xref_filename - - self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(xref_filename))[0] #this is really wrong as well.... - - if global_prefs['doxrefs'] and os.path.exists(absname) and not self.header.grr.xrefs.has_key(xref_filename): - self.xref = Database(absname, self.header.grr, self) - self.header.grr.xrefs[xref_filename] = self.xref - else: - self.xref = None - - - def blender_import(self): - #name = self.props['type'] + ': ' + self.props['id'] - name = self.props['id'] - self.object = self.header.scene.objects.new('Empty') - self.object.name = name - self.object.enableDupGroup = True - self.header.group.objects.link(self.object) - - #for broken links its ok to leave this empty! they purely for visual purposes anyway..... - try: - self.object.DupGroup = self.header.grr.xrefs[self.props['3t200!filename']].group - except: - pass - - - - - if self.parent and self.parent.object: - self.parent.object.makeParent([self.object],1) - - if self.matrix: - self.object.setMatrix(self.matrix) - - - #id props import - self.object.properties['FLT'] = dict() - for key in self.props: - try: - self.object.properties['FLT'][key] = self.props[key] - except: #horrible... - pass - - self.object.Layer = current_layer - self.object.sel = 1 - - Node.blender_import(self) - - -class LOD(InterNode): - def blender_import(self): - #self.move_to_next_layer() - InterNode.blender_import(self) - #self.object.properties['FLT'] = self.props.copy() - - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - - self.root_handler.set_handler({33: self.parse_long_id, - 31: self.parse_comment, - 10: self.parse_push, - 49: self.parse_matrix, - 21: self.parse_push_extension}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({2: self.parse_group, - 111: self.parse_inline_light_point, - 73: self.parse_lod, - 4: self.parse_object, - 10: self.parse_push, - 11: self.parse_pop, - 96: self.parse_unhandled, # switch - 14: self.parse_dof, # DOF - 91: self.parse_unhandled, # sound - 98: self.parse_unhandled, # clip - 63: self.parse_xref}) - self.extension_handler.set_handler({22: self.parse_pop_extension, - 100: self.parse_extension}) - - - self.props = dict() - self.props['comment'] = '' - self.parse_record() - -class InlineLightPoint(InterNode): - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - self.root_handler.set_handler({33: self.parse_long_id, - 31: self.parse_comment, - 10: self.parse_push, - 21: self.parse_push_extension, - 49: self.parse_matrix}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({72: self.parse_vertex_list, - 10: self.parse_push, - 11: self.parse_pop}) - self.extension_handler.set_handler({22: self.parse_pop_extension, - 100: self.parse_extension}) - - self.indices = list() - self.props = dict() - self.props['comment'] = '' - self.parse_record() - - - def blender_import(self): - - - name = self.props['id'] - self.mesh= Blender.Mesh.New() - self.mesh.name = 'FLT_LP' - self.object = self.header.scene.objects.new(self.mesh) - self.object.name = name - #self.mesh.verts.extend(Vector() ) # DUMMYVERT - self.object.Layer = current_layer - self.object.sel= 1 - - self.object.properties['FLT'] = dict() - for key in self.props: - try: - self.object.properties['FLT'][key] = self.props[key] - except: #horrible... - pass - - if self.extension: - self.object.properties['FLT']['EXT'] = dict() - for key in self.extension: - self.object.properties['FLT']['EXT'][key] = self.extension[key] - - if self.parent and self.parent.object and self.header.scene == self.parent.header.scene: - self.parent.object.makeParent([self.object]) - - if self.matrix: - self.object.setMatrix(self.matrix) - - self.mesh.verts.extend([self.header.vert_pal.blender_verts[i] for i in self.indices]) - - #add color index information. - self.mesh.verts.addPropertyLayer("FLT_VCOL",Blender.Mesh.PropertyTypes["INT"]) - for i, vindex in enumerate(self.indices): - vdesc = self.header.vert_pal.vert_desc_lst[vindex] - v = self.mesh.verts[i] - v.setProperty("FLT_VCOL",vdesc.cindex) - #for i, v in enumerate(self.mesh.verts): - # vdesc = self.header.vert_pal.vert_desc_lst[i] - # v.setProperty("FLT_VCOL",vdesc.cindex) - self.mesh.update() - - def parse_vertex_list(self): - length = self.header.fw.get_length() - fw = self.header.fw - vert_pal = self.header.vert_pal - - count = (length-4)/4 - - # If this ever fails the chunk below does error checking - self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)] - - ''' - for i in xrange(count): - byte_offset = fw.read_int() - if byte_offset in vert_pal.index: - index = vert_pal.index[byte_offset] - self.indices.append(index) - elif global_prefs['verbose'] >= 1: - print 'Warning: Unable to map byte offset %s' + \ - ' to vertex index.' % byte_offset - ''' - - return True - - - -class IndexedLightPoint(InterNode): - # return dictionary: lp_app name => index list - def group_points(self, props): - - name_to_indices = {} - - for i in self.indices: - vert_desc = self.header.vert_pal.vert_desc_lst[i] - app_desc = LightPointAppDesc() - app_desc.props.update(props) - # add vertex normal and color - app_desc.props.update({'nx': vert_desc.nx}) - app_desc.props.update({'ny': vert_desc.ny}) - app_desc.props.update({'nz': vert_desc.nz}) - - app_desc.props.update({'r': vert_desc.r}) - app_desc.props.update({'g': vert_desc.g}) - app_desc.props.update({'b': vert_desc.b}) - app_desc.props.update({'a': vert_desc.a}) - - app_name = self.header.grr.request_lightpoint_app(app_desc, self.header.scene) - - if name_to_indices.get(app_name): - name_to_indices[app_name].append(i) - else: - name_to_indices.update({app_name: [i]}) - - return name_to_indices - - def blender_import(self): - name = self.props['type'] + ': ' + self.props['id'] - - name_to_indices = self.group_points(self.header.lightpoint_appearance_pal[self.index]) - - for app_name, indices in name_to_indices.iteritems(): - self.object = Blender.Object.New('Mesh', name) - self.mesh= Blender.Mesh.New() - self.mesh.verts.extend( Vector() ) # DUMMYVERT - self.object.link(self.mesh) - - if self.parent: - self.parent.object.makeParent([self.object]) - - for i in indices: - vert = self.header.vert_pal.blender_verts[i] - self.mesh.verts.append(vert) - - self.header.scene.objects.link(self.object) - - self.object.Layer = current_layer - - if self.matrix: - self.object.setMatrix(self.matrix) - - # Import comment. - if self.props['comment'] != '': - name = 'COMMENT: ' + self.props['id'] - t = Blender.Text.New(name) - t.write(self.props['comment']) - self.props['comment'] = name - - # Attach properties. - self.props.update({'appearance': app_name}) - for name, value in self.props.iteritems(): - self.object.addProperty(name, value) - - self.mesh.update() - - def parse_vertex_list(self): - length = self.header.fw.get_length() - fw = self.header.fw - vert_pal = self.header.vert_pal - - count = (length-4)/4 - - # If this ever fails the chunk below does error checking - self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)] - - ''' - for i in xrange(count): - byte_offset = fw.read_int() - if byte_offset in vert_pal.index: - index = vert_pal.index[byte_offset] - self.indices.append(index) - elif global_prefs['verbose'] >= 1: - print 'Warning: Unable to map byte offset %s' + \ - ' to vertex index.' % byte_offset - ''' - return True - - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - self.root_handler.set_handler({33: self.parse_long_id, - 31: self.parse_comment, - 10: self.parse_push, - 49: self.parse_matrix}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({72: self.parse_vertex_list, - 10: self.parse_push, - 11: self.parse_pop}) - - self.indices = list() - - self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance']) - self.props['comment'] = '' - self.props['type'] = 'Light Point' - self.props['id'] = self.header.fw.read_string(8) - self.index = self.header.fw.read_int() - self.header.fw.read_ahead(4) # animation index - self.props['draw order'] = self.header.fw.read_int() - -class Unhandled(InterNode): - def __init__(self, parent): - Node.__init__(self, parent, parent.header) - InterNode.__init__(self) - - self.root_handler.set_handler({33: self.parse_long_id, - 31: self.parse_comment, - 10: self.parse_push, - 49: self.parse_matrix}) - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({2: self.parse_group, - 73: self.parse_lod, - 4: self.parse_object, - 10: self.parse_push, - 11: self.parse_pop, - 96: self.parse_unhandled, # switch - 14: self.parse_dof, # DOF - 91: self.parse_unhandled, # sound - 98: self.parse_unhandled, # clip - 63: self.parse_xref}) - - self.props['id'] = self.header.fw.read_string(8) - -class Database(InterNode): - def blender_import(self): - for key in self.tex_pal.keys(): - path_filename= FF.find(self.tex_pal[key][0]) - if path_filename != None: - img = self.grr.request_image(path_filename) - if img: - self.tex_pal[key][1] = img - elif global_prefs['verbose'] >= 1: - print 'Warning: Unable to find', self.tex_pal[key][0] - - self.scene.properties['FLT'] = dict() - for key in self.props: - try: - self.scene.properties['FLT'][key] = self.props[key] - except: #horrible... - pass - - self.scene.properties['FLT']['Main'] = 0 - self.scene.properties['FLT']['Filename'] = self.bname - - for child in self.children: - if child.props.has_key('type') and child.props['type'] == 73: - if child.props['6d!switch out'] != 0.0: - child.vis = False - - #import color palette - carray = list() - for color in self.col_pal: - carray.append(struct.unpack('>i',struct.pack('>BBBB',color[0],color[1],color[2],color[3]))[0]) - self.scene.properties['FLT']['Color Palette'] = carray - Node.blender_import(self) - - def parse_appearance_palette(self): - props = dict() - self.fw.read_ahead(4) # reserved - props.update({'id': self.fw.read_string(256)}) - index = self.fw.read_int() - props.update({'smc': self.fw.read_short()}) - props.update({'fid': self.fw.read_short()}) - props.update({'back color: a': self.fw.read_uchar()}) - props.update({'back color: b': self.fw.read_uchar()}) - props.update({'back color: g': self.fw.read_uchar()}) - props.update({'back color: r': self.fw.read_uchar()}) - props.update({'display mode': self.fw.read_int()}) - props.update({'intensity': self.fw.read_float()}) - props.update({'back intensity': self.fw.read_float()}) - props.update({'minimum defocus': self.fw.read_float()}) - props.update({'maximum defocus': self.fw.read_float()}) - props.update({'fading mode': self.fw.read_int()}) - props.update({'fog punch mode': self.fw.read_int()}) - props.update({'directional mode': self.fw.read_int()}) - props.update({'range mode': self.fw.read_int()}) - props.update({'min pixel size': self.fw.read_float()}) - props.update({'max pixel size': self.fw.read_float()}) - props.update({'actual size': self.fw.read_float()}) - props.update({'trans falloff pixel size': self.fw.read_float()}) - props.update({'trans falloff exponent': self.fw.read_float()}) - props.update({'trans falloff scalar': self.fw.read_float()}) - props.update({'trans falloff clamp': self.fw.read_float()}) - props.update({'fog scalar': self.fw.read_float()}) - props.update({'fog intensity': self.fw.read_float()}) - props.update({'size threshold': self.fw.read_float()}) - props.update({'directionality': self.fw.read_int()}) - props.update({'horizontal lobe angle': self.fw.read_float()}) - props.update({'vertical lobe angle': self.fw.read_float()}) - props.update({'lobe roll angle': self.fw.read_float()}) - props.update({'dir falloff exponent': self.fw.read_float()}) - props.update({'dir ambient intensity': self.fw.read_float()}) - props.update({'significance': self.fw.read_float()}) - props.update({'flags': self.fw.read_int()}) - props.update({'visibility range': self.fw.read_float()}) - props.update({'fade range ratio': self.fw.read_float()}) - props.update({'fade in duration': self.fw.read_float()}) - props.update({'fade out duration': self.fw.read_float()}) - props.update({'LOD range ratio': self.fw.read_float()}) - props.update({'LOD scale': self.fw.read_float()}) - - self.lightpoint_appearance_pal.update({index: props}) - - def parse_header(self): - self.props['type'] = 'Header' - self.props['comment'] = '' - self.props['id'] = self.fw.read_string(8) - self.props['version'] = self.fw.read_int() - self.fw.read_ahead(46) - self.props['units'] = self.fw.read_char() - self.props['set white'] = bool(self.fw.read_char()) - self.props['flags'] = self.fw.read_int() - self.fw.read_ahead(24) - self.props['projection type'] = self.fw.read_int() - self.fw.read_ahead(36) - self.props['sw x'] = self.fw.read_double() - self.props['sw y'] = self.fw.read_double() - self.props['dx'] = self.fw.read_double() - self.props['dy'] = self.fw.read_double() - self.fw.read_ahead(24) - self.props['sw lat'] = self.fw.read_double() - self.props['sw lon'] = self.fw.read_double() - self.props['ne lat'] = self.fw.read_double() - self.props['ne lon'] = self.fw.read_double() - self.props['origin lat'] = self.fw.read_double() - self.props['origin lon'] = self.fw.read_double() - self.props['lambert lat1'] = self.fw.read_double() - self.props['lambert lat2'] = self.fw.read_double() - self.fw.read_ahead(16) - self.props['ellipsoid model'] = self.fw.read_int() - self.fw.read_ahead(4) - self.props['utm zone'] = self.fw.read_short() - self.fw.read_ahead(6) - self.props['dz'] = self.fw.read_double() - self.props['radius'] = self.fw.read_double() - self.fw.read_ahead(8) - self.props['major axis'] = self.fw.read_double() - self.props['minor axis'] = self.fw.read_double() - - if global_prefs['verbose'] >= 1: - print 'OpenFlight Version:', float(self.props['version']) / 100.0 - print - - return True - - def parse_mat_palette(self): - mat_desc = MaterialDesc() - index = self.fw.read_int() - - name = self.fw.read_string(12) - if len(mat_desc.name) > 0: - mat_desc.name = name - - flag = self.fw.read_int() - # skip material if not used - if not flag & 0x80000000: - return True - - ambient_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()] - mat_desc.diffuse = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()] - mat_desc.specular = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()] - emissive_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()] - - mat_desc.shininess = self.fw.read_float() / 64.0 # [0.0, 128.0] => [0.0, 2.0] - mat_desc.alpha = self.fw.read_float() - - # Convert ambient and emissive colors into intensitities. - mat_desc.ambient = col_to_gray(ambient_col) - mat_desc.emissive = col_to_gray(emissive_col) - - self.mat_desc_pal_lst.append( (index, mat_desc) ) - - return True - - def get_color(self, color_index): - color = None - index = color_index / 128 - intensity = float(color_index - 128.0 * index) / 127.0 - - if index >= 0 and index <= 1023: - brightest = self.col_pal[index] - r = int(brightest[0] * intensity) - g = int(brightest[1] * intensity) - b = int(brightest[2] * intensity) - a = int(brightest[3]) - - color = [r, g, b, a] - - return color - - def parse_color_palette(self): - self.header.fw.read_ahead(128) - for i in xrange(1024): - a = self.header.fw.read_uchar() - b = self.header.fw.read_uchar() - g = self.header.fw.read_uchar() - r = self.header.fw.read_uchar() - self.col_pal.append((r, g, b, a)) - return True - - def parse_vertex_palette(self): - self.vert_pal = VertexPalette(self) - self.vert_pal.parse() - return True - - def parse_texture_palette(self): - name = self.fw.read_string(200) - index = self.fw.read_int() - self.tex_pal[index]= [name, None] - return True - - def read_attribute_files(self): - for tex in self.tex_pal.keys(): - [name,image] = self.tex_pal[tex] - basename = os.path.basename(name) - if(image): - basename = basename + ".attr" - dirname = os.path.dirname(Blender.sys.expandpath(image.getFilename())) #can't rely on original info stored in pallette since it might be relative link - newpath = os.path.join(dirname, basename) - if os.path.exists(newpath) and not image.properties.has_key('FLT'): - fw = flt_filewalker.FltIn(newpath) - fw.read_ahead(8) #We dont care what the attribute file says about x/y dimensions - image.properties['FLT']={} - - #need to steal code from parse records.... - props = records['Image'] - propkeys = props.keys() - propkeys.sort() - for position in propkeys: - (type,length,name) = props[position] - image.properties['FLT'][name] = read_prop(fw,type,length) - fw.close_file() - - #copy clamp settings - wrap = image.properties['FLT']['10i!Wrap'] - wrapu = image.properties['FLT']['11i!WrapU'] - wrapv = image.properties['FLT']['12i!WrapV'] - - if wrapu == 3 or wrapv == 3: - wrapuv = (wrap,wrap) - else: - wrapuv = (wrapu, wrapv) - image.clampX = wrapuv[0] - image.clampY = wrapuv[1] - - elif not os.path.exists(newpath): - print "Cannot read attribute file:" + newpath - - def __init__(self, filename, grr, parent=None): - if global_prefs['verbose'] >= 1: - print 'Parsing:', filename - print - - #check to see if filename is a relative path - #filename = os.path.abspath(filename) - - self.fw = flt_filewalker.FltIn(filename) - self.filename = filename - self.bname = os.path.splitext(os.path.basename(filename))[0] - self.grr = grr - - Node.__init__(self, parent, self) - InterNode.__init__(self) - - self.root_handler.set_handler({1: self.parse_header, - 67: self.parse_vertex_palette, - 33: self.parse_long_id, - 31: self.parse_comment, - 64: self.parse_texture_palette, - 32: self.parse_color_palette, - 113: self.parse_mat_palette, - 128: self.parse_appearance_palette, - 10: self.parse_push}) - if parent: - self.root_handler.set_throw_back_lst(throw_back_opcodes) - - self.child_handler.set_handler({#130: self.parse_indexed_light_point, - 111: self.parse_inline_light_point, - 2: self.parse_group, - 73: self.parse_lod, - 4: self.parse_object, - 10: self.parse_push, - 11: self.parse_pop, - 96: self.parse_unhandled, - 14: self.parse_dof, - 91: self.parse_unhandled, - 98: self.parse_unhandled, - 63: self.parse_xref}) - - self.scene = Blender.Scene.New(self.bname) - self.group = Blender.Group.New(self.bname) - - self.vert_pal = None - self.lightpoint_appearance_pal = dict() - self.tex_pal = dict() - #self.tex_pal_lst = list() - #self.bl_tex_pal = dict() - self.col_pal = list() - self.mat_desc_pal_lst = list() - self.mat_desc_pal = dict() - self.props = dict.fromkeys(['id', 'type', 'comment', 'version', 'units', 'set white', - 'flags', 'projection type', 'sw x', 'sw y', 'dx', 'dy', 'dz', 'sw lat', - 'sw lon', 'ne lat', 'ne lon', 'origin lat', 'origin lon', 'lambert lat1', - 'lambert lat2', 'ellipsoid model', 'utm zone', 'radius', 'major axis', 'minor axis']) - - -def clearparent(root,childhash): - for child in childhash[root]: - clearparent(child,childhash) - root.clrParent(2,0) - -def fixscale(root,childhash): - for child in childhash[root]: - fixscale(child,childhash) - location = Blender.Mathutils.Vector(root.getLocation('worldspace')) - if location[0] != 0.0 or location[1] != 0.0 or location[2] != 0.0: - #direction = Blender.Mathutils.Vector(0-location[0],0-location[1],0-location[2]) #reverse vector - smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4) - root.setLocation(location * smat) - #if its a mesh, we need to scale all of its vertices too - if root.type == 'Mesh': - smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4) - rmesh = root.getData(mesh=True) - for v in rmesh.verts: - v.co = v.co * smat - -def reparent(root,childhash,sce): - for child in childhash[root]: - reparent(child,childhash,sce) - - root.makeParent(childhash[root]) - sce.update(1) - -def update_scene(root,sdone): - for object in root.objects: - if object.DupGroup: - try: - child = Blender.Scene.Get(object.DupGroup.name) - except: - child = None - if child and child not in sdone: - update_scene(child,sdone) - root.makeCurrent() - #create a list of children for each object - childhash = dict() - for object in root.objects: - childhash[object] = list() - - for object in root.objects: - if object.parent: - childhash[object.parent].append(object) - - for object in root.objects: - if not object.parent: - #recursivley go through and clear all the children of their transformation, starting at deepest level first. - clearparent(object,childhash) - #now fix the location of everything - fixscale(object,childhash) - #now fix the parenting - reparent(object,childhash,root) - - for object in root.objects: - object.makeDisplayList() - root.update(1) - sdone.append(root) - - -def select_file(filename, grr): - if not Blender.sys.exists(filename): - msg = 'Error: File ' + filename + ' does not exist.' - Blender.Draw.PupMenu(msg) - return - - if not filename.lower().endswith('.flt'): - msg = 'Error: Not a flight file.' - Blender.Draw.PupMenu(msg) - print msg - print - return - - global_prefs['fltfile']= filename - global_prefs['verbose']= 1 - global_prefs['get_texture'] = True - global_prefs['get_diffuse'] = True - global_prefs['get_specular'] = False - global_prefs['get_emissive'] = False - global_prefs['get_alpha'] = True - global_prefs['get_ambient'] = False - global_prefs['get_shininess'] = True - global_prefs['color_from_face'] = True - global_prefs['log to blender'] = True - - - - Blender.Window.WaitCursor(True) - Blender.Window.EditMode(0) - - - FF.add_file_to_search_path(filename) - - if global_prefs['verbose'] >= 1: - print 'Pass 1: Loading.' - print - - load_time = Blender.sys.time() - db = Database(filename,grr) - db.parse() - load_time = Blender.sys.time() - load_time - - if global_prefs['verbose'] >= 1: - print - print 'Pass 2: Importing to Blender.' - print - - import_time = Blender.sys.time() - db.blender_import() - - if global_prefs['attrib']: - print "reading attribute files" - db.read_attribute_files() - - Blender.Window.ViewLayer(range(1,21)) - - update_scene(db.scene,[]) - import_time = Blender.sys.time() - import_time - if global_prefs['verbose'] >= 1: - print 'Done.' - print - print 'Time to parse file: %.3f seconds' % load_time - print 'Time to import to blender: %.3f seconds' % import_time - print 'Total time: %.3f seconds' % (load_time + import_time) - - Blender.Window.WaitCursor(False) - -def setimportscale(ID,val): - global global_prefs - global_prefs['scale'] = val -def setBpath(fname): - global_prefs['fltfile'] = fname - d = dict() - for key in global_prefs: - d[key] = global_prefs[key] - Blender.Registry.SetKey('flt_import', d, 1) - -def event(evt,val): - pass - -from Blender.BGL import * -from Blender import Draw - -def but_event(evt): - - global FLTBaseLabel - global FLTBaseString - global FLTBaseChooser - - global FLTExport - global FLTClose - - global FLTDoXRef - global FLTShadeImport - global FLTAttrib - - global FLTWarn - - #Import DB - if evt == 1: - if global_prefs['verbose'] >= 1: - print - print 'OpenFlight Importer' - print 'Version:', __version__ - print 'Author: Greg MacDonald, Campbell Barton, Geoffrey Bantle' - print __url__[2] - print - - GRR = GlobalResourceRepository() - - try: - select_file(global_prefs['fltfile'], GRR) - except: - import traceback - FLTWarn = Draw.PupBlock("Ixport Error", ["See console for output!"]) - traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) - - #choose base path for export - if evt == 4: - Blender.Window.FileSelector(setBpath, "DB Root", global_prefs['fltfile']) - #Import custom shading? - if evt == 9: - global_prefs['smoothshading'] = FLTShadeImport.val - #Import Image attribute files - if evt == 10: - global_prefs['attrib'] = FLTAttrib.val - #export XRefs - if evt == 13: - global_prefs['doxrefs'] = FLTDoXRef.val - - if evt == 2: - Draw.Exit() - - d = dict() - for key in global_prefs: - d[key] = global_prefs[key] - Blender.Registry.SetKey('flt_import', d, 1) - -def gui(): - - global FLTBaseLabel - global FLTBaseString - global FLTBaseChooser - - global FLTExport - global FLTClose - - global FLTDoXRef - global FLTShadeImport - - global FLTAttrib - - - glClearColor(0.772,0.832,0.847,1.0) - glClear(GL_COLOR_BUFFER_BIT) - - areas = Blender.Window.GetScreenInfo() - curarea = Blender.Window.GetAreaID() - curRect = None - - for area in areas: - if area['id'] == curarea: - curRect = area['vertices'] - break - - width = curRect[2] - curRect[0] - height = curRect[3] - curRect[1] - cx = 50 - cy = height - 80 - - FLTBaseLabel = Draw.Label("Base file:",cx,cy,100,20) - FLTBaseString = Draw.String("",3,cx+100,cy,300,20,global_prefs['fltfile'],255,"Root DB file") - FLTBaseChooser = Draw.PushButton("...",4,cx+400,cy,20,20,"Choose Folder") - - cy = cy-40 - FLTScale = Draw.Number("Import Scale",14,cx,cy,220,20,global_prefs['scale'],0.0,100.0,"Export scaleing factor",setimportscale) - - cy = cy-40 - FLTDoXRef = Draw.Toggle("Import XRefs", 13,cx,cy,220,20,global_prefs['doxrefs'],"Import External references") - - cy = cy-40 - FLTShadeImport = Draw.Toggle("Import Custom Shading",9,cx,cy,220,20,global_prefs['smoothshading'],"Import custom shading via edgesplit modifiers") - - cy = cy-40 - FLTAttrib = Draw.Toggle("Import Attribute Files", 10,cx,cy,220,20,global_prefs['attrib'],"Import Image Attribute files") - - cy = cy - 40 - FLTExport = Draw.PushButton("Import",1,cx,20,100,20,"Import FLT Database") - FLTClose = Draw.PushButton("Close",2,cx+120,20,100,20,"Close Window") - - - -Draw.Register(gui,event,but_event) \ No newline at end of file diff --git a/release/scripts/flt_lodedit.py b/release/scripts/flt_lodedit.py deleted file mode 100644 index 58319b9e525..00000000000 --- a/release/scripts/flt_lodedit.py +++ /dev/null @@ -1,502 +0,0 @@ -#!BPY - -""" -Name: 'FLT LOD Editor' -Blender: 240 -Group: 'Misc' -Tooltip: 'Level of Detail Edtior for FLT nodes' -""" - -__author__ = "Geoffrey Bantle" -__version__ = "1.0 11/21/07" -__email__ = ('scripts', 'Author, ') -__url__ = ('blender', 'blenderartists.org') - -__bpydoc__ ="""\ -This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. - -Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/FLTools -""" - -# -------------------------------------------------------------------------- -# flt_palettemanager.py version 0.1 2005/04/08 -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender.Draw as Draw -from Blender.BGL import * -import Blender -import flt_properties -reload(flt_properties) -from flt_properties import * - -#event codes -evcode = { - "LOD_MAKE" : 100, - "LOD_DELETE" : 101, - "LOD_CALC_CENTER" : 102, - "LOD_GRAB_CENTER" : 103, - "LOD_X" : 104, - "LOD_Y" : 105, - "LOD_Z" : 106, - "LOD_FREEZE" : 107, - "LOD_SIG" : 108, - "LOD_IN" : 109, - "LOD_OUT" : 110, - "LOD_TRANS" : 111, - "LOD_PREVIOUS" : 112 -} - - -#system -LOD_MAKE = None #PushButton -LOD_DELETE = None #PushButton -LOD_CALC_CENTER = None #PushButton -LOD_GRAB_CENTER = None #Pushbutton -LOD_FREEZE = None #Toggle -LOD_PREVIOUS = None #Toggle - -LOD_X = None #Input -LOD_Y = None #Input -LOD_Z = None #Input - -LOD_SIG = None #Input -LOD_IN = None #Input -LOD_OUT = None #Input -LOD_TRANS = None #Input - -#labels -LOD_EDITLABEL = None -LOD_SWITCHLABEL = None -LOD_CENTERLABEL = None - -LOD_XLABEL = None -LOD_YLABEL = None -LOD_ZLABEL = None -LOD_SIGLABEL = None -LOD_INLABEL = None -LOD_OUTLABEL = None -LOD_TRANSLABEL = None - - -#ID Props -switch_in = '5d!switch in' -switch_out = '6d!switch out' -xco = '10d!X co' -yco = '11d!Y co' -zco = '12d!Z co' -trans = '13d!Transition' -sig_size = '14d!Sig Size' - -#Flags -lodflag = '9I!flags' -previous_mask = (1 << 31) -freeze_mask = (1 << 29) - -def update_state(): - state = dict() - state["activeScene"] = Blender.Scene.GetCurrent() - state["activeObject"] = state["activeScene"].objects.active - if state["activeObject"] and not state["activeObject"].sel: - state["activeObject"] = None - state["activeMesh"] = None - if state["activeObject"] and state["activeObject"].type == 'Mesh': - state["activeMesh"] = state["activeObject"].getData(mesh=True) - - state["activeFace"] = None - if state["activeMesh"]: - if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None: - state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace] - - - #update editmode - state["editmode"] = Blender.Window.EditMode() - - return state - -def idprops_append(object, typecode, props): - object.properties["FLT"] = dict() - object.properties["FLT"]['type'] = typecode - for prop in props: - object.properties["FLT"][prop] = props[prop] - object.properties["FLT"]['3t8!id'] = object.name - -def idprops_kill(): - state = update_state() - if state["activeObject"] and state["activeObject"].properties.has_key('FLT'): - state["activeObject"].properties.pop('FLT') - -def idprops_copy(source): - state = update_state() - if source.properties.has_key('FLT'): - for object in state["activeScene"].objects: - if object.sel and object != source and (state["activeScene"].Layers & object.Layers): - idprops_kill(object) - object.properties['FLT'] = dict() - for key in source.properties['FLT']: - object.properties['FLT'][key] = source.properties['FLT'][key] - -def select_by_typecode(typecode): - state = update_state() - - for object in state["activeScene"].objects: - if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers: - object.select(1) - -def idprops_type(object, typecode): - if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode: - return True - return False - -#ui type code -def get_prop(typecode, prop): - - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], typecode): - props = state["activeObject"].properties['FLT'] - else: - props = flt_properties.FLTLOD - - return props[prop] - -def set_prop(typecode, prop, value): - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"],typecode): - state["activeObject"].properties['FLT'][prop] = value - - - -def get_lockmask(mask): - global lodflag - state = update_state() - if state["activeObject"]: - flag = get_prop(73,lodflag) - if flag & mask: - return True - return False - -def set_lockmask(mask): - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], 73): - oldvalue = state["activeObject"].properties['FLT'][lodflag] - oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0] - oldvalue |= mask - state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i', struct.pack(">I", oldvalue))[0] - -def clear_lockmask(mask): - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], 73): - oldvalue = state["activeObject"].properties['FLT'][lodflag] - oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0] - oldvalue &= ~mask - state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i',struct.pack('>I',oldvalue))[0] - -def findchildren(object): - state = update_state() - children = list() - for candidate in state["activeScene"].objects: - if candidate.parent == object: - children.append(candidate) - retlist = list(children) - for child in children: - retlist = retlist + findchildren(child) - return retlist - -def get_object_center(object): - bbox = object.getBoundBox(1) - average = Blender.Mathutils.Vector(0.0, 0.0, 0.0) - - for point in bbox: - average[0] += point[0] - average[1] += point[1] - average[2] += point[2] - - average[0] = average[0] / 8.0 - average[1] = average[1] / 8.0 - average[2] = average[2] / 8.0 - - return average - - -def calc_center(): - - global xco - global yco - global zco - - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], 73): - average = Blender.Mathutils.Vector(0.0, 0.0, 0.0) - children = findchildren(state["activeObject"]) #get children objects - if children: - for child in children: - center = get_object_center(child) - average[0] += center[0] - average[1] += center[1] - average[2] += center[2] - - average[0] = average[0] / len(children) - average[1] = average[1] / len(children) - average[2] = average[2] / len(children) - - set_prop(73, xco, average[0]) - set_prop(73, yco, average[1]) - set_prop(73, zco, average[2]) - - -def grab_center(): - - global xco - global yco - global zco - - state = update_state() - if state["activeObject"] and idprops_type(state["activeObject"], 73): - center = Blender.Window.GetCursorPos() - - set_prop(73, xco, center[0]) - set_prop(73, yco, center[1]) - set_prop(73, zco, center[2]) - - -def create_lod(): - state = update_state() - actobj = state["activeObject"] - if actobj and not idprops_type(actobj, 73): - idprops_kill() - idprops_append(actobj,73, flt_properties.FLTLOD) - calc_center() - - - -def event(evt,val): - if evt == Draw.ESCKEY: - Draw.Exit() - -def but_event(evt): - - global LOD_MAKE - global LOD_DELETE - global LOD_CALC_CENTER - global LOD_GRAB_CENTER - global LOD_FREEZE - global LOD_PREVIOUS - global LOD_X - global LOD_Y - global LOD_Z - global LOD_SIG - global LOD_IN - global LOD_OUT - global LOD_TRANS - - global switch_in - global switch_out - global xco - global yco - global zco - global trans - global sig_size - - global lodflag - global previous_mask - global freeze_mask - - global evcode - - #do "system" events - if evt == evcode["LOD_MAKE"]: - create_lod() - - if evt == evcode["LOD_CALC_CENTER"]: - calc_center() - - if evt == evcode["LOD_DELETE"]: - idprops_kill() - - if evt == evcode["LOD_GRAB_CENTER"]: - grab_center() - - #do mask events - if evt == evcode["LOD_FREEZE"]: - if LOD_FREEZE.val == True: - set_lockmask(freeze_mask) - else: - clear_lockmask(freeze_mask) - - if evt == evcode["LOD_PREVIOUS"]: - if LOD_PREVIOUS.val == True: - set_lockmask(previous_mask) - else: - clear_lockmask(previous_mask) - - #do input events - if evt == evcode["LOD_X"]: - set_prop(73, xco, LOD_X.val) - if evt == evcode["LOD_Y"]: - set_prop(73, yco, LOD_Y.val) - if evt == evcode["LOD_Z"]: - set_prop(73, zco, LOD_Z.val) - if evt == evcode["LOD_SIG"]: - set_prop(73, sig_size, LOD_SIG.val) - if evt == evcode["LOD_IN"]: - set_prop(73, switch_in, LOD_IN.val) - if evt == evcode["LOD_OUT"]: - set_prop(73, switch_out, LOD_OUT.val) - if evt == evcode["LOD_TRANS"]: - set_prop(73, trans, LOD_TRANS.val) - - - Draw.Redraw(1) - Blender.Window.RedrawAll() - -def draw_propsheet(x,y): - - global LOD_MAKE - global LOD_DELETE - global LOD_CALC_CENTER - global LOD_GRAB_CENTER - global LOD_FREEZE - global LOD_PREVIOUS - global LOD_X - global LOD_Y - global LOD_Z - global LOD_SIG - global LOD_IN - global LOD_OUT - global LOD_TRANS - - #labels - global LOD_EDITLABEL - global LOD_SWITCHLABEL - global LOD_CENTERLABEL - global LOD_XLABEL - global LOD_YLABEL - global LOD_ZLABEL - global LOD_SIGLABEL - global LOD_INLABEL - global LOD_OUTLABEL - global LOD_TRANSLABEL - - - global switch_in - global switch_out - global xco - global yco - global zco - global trans - global sig_size - - global lodflag - global previous_mask - global freeze_mask - - global evcode - - - global evcode - - state = update_state() - - label_width = 100 - row_height = 20 - toggle_width = 50 - input_width = 100 - pad = 10 - origx = x - origy = (row_height * 16) + (pad * 16) - - - #editor label - x = origx - y = origy - LOD_EDITLABEL = Blender.Draw.Label("FLT Level of Detail Editor", x, y, 250, row_height) - - - #Center inputs - x = origx - y = y- (row_height + pad) - LOD_CENTERLABEL = Blender.Draw.Label("LOD center", x, y, label_width, row_height) - y = y- (row_height + pad) - LOD_XLABEL = Blender.Draw.Label("X Coordinate", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_X = Blender.Draw.Number("", evcode["LOD_X"], x, y, input_width, row_height,get_prop(73,xco), -1000000.0, 1000000.0, "") - x = origx - y = y- (row_height + pad) - LOD_YLABEL = Blender.Draw.Label("Y Coordinate", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_Y = Blender.Draw.Number("", evcode["LOD_Y"], x, y, input_width, row_height,get_prop(73,yco), -1000000.0, 1000000.0, "") - x = origx - y = y- (row_height + pad) - LOD_ZLABEL = Blender.Draw.Label("Z Coordinate", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_Z = Blender.Draw.Number("", evcode["LOD_Z"], x, y, input_width, row_height,get_prop(73,zco), -1000000.0, 1000000.0, "") - - - #Switch inputs - x = origx - y = y- (row_height + pad) - LOD_SWITCHLABEL = Blender.Draw.Label("Switch Settings", x, y, input_width, row_height) - y = y- (row_height + pad) - LOD_SIGLABEL = Blender.Draw.Label("Significant Size", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_SIG = Blender.Draw.Number("", evcode["LOD_SIG"], x, y, input_width, row_height, get_prop(73,sig_size), -1000000.0, 1000000.0, "") - x = origx - y = y- (row_height + pad) - LOD_INLABEL = Blender.Draw.Label("Switch In", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_IN = Blender.Draw.Number("", evcode["LOD_IN"], x, y, input_width, row_height, get_prop(73,switch_in), -1000000.0, 1000000.0, "") - x = origx - y = y- (row_height + pad) - LOD_OUTLABEL = Blender.Draw.Label("Switch Out", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_OUT = Blender.Draw.Number("", evcode["LOD_OUT"], x, y, input_width, row_height, get_prop(73,switch_out), -1000000.0, 1000000.0, "") - x = origx - y = y- (row_height + pad) - LOD_TRANSLABEL = Blender.Draw.Label("Transition", x, y, label_width, row_height) - x = origx + (label_width + pad) - LOD_TRANS = Blender.Draw.Number("", evcode["LOD_TRANS"], x, y, input_width, row_height, get_prop(73,trans), -1000000.0, 1000000.0, "") - - - x = origx - y = y - (row_height + pad) - LOD_MAKE = Blender.Draw.PushButton("Make LOD", evcode["LOD_MAKE"], x, y, input_width + label_width + pad, row_height, "Make a LOD Node out of Active Object") - y = y - (row_height + pad) - LOD_DELETE = Blender.Draw.PushButton("Delete LOD", evcode["LOD_DELETE"], x, y, input_width + label_width + pad, row_height, "Delete the LOD Node properties") - y = y - (row_height + pad) - LOD_CALC_CENTER = Blender.Draw.PushButton("Calculate Center", evcode["LOD_CALC_CENTER"], x, y, input_width + label_width + pad, row_height, "Calculate the center of this LOD") - y = y - (row_height + pad) - LOD_GRAB_CENTER = Blender.Draw.PushButton("Grab Center", evcode["LOD_GRAB_CENTER"], x, y, input_width + label_width + pad, row_height, "Grab center from 3d cursor") - y = y - (row_height + pad) - LOD_FREEZE = Blender.Draw.Toggle("Freeze Center", evcode["LOD_FREEZE"], x, y, input_width + label_width + pad, row_height, get_lockmask(freeze_mask), "") - y = y - (row_height + pad) - LOD_PREVIOUS = Blender.Draw.Toggle("Previous Range", evcode["LOD_PREVIOUS"], x, y, input_width + label_width + pad, row_height, get_lockmask(previous_mask), "") - -def gui(): - #draw the propsheet/toolbox. - psheety = 800 - #psheetx = psheety + 10 - draw_propsheet(20,psheety) - -Draw.Register(gui,event,but_event) - \ No newline at end of file diff --git a/release/scripts/flt_palettemanager.py b/release/scripts/flt_palettemanager.py deleted file mode 100644 index c2f1380a6fa..00000000000 --- a/release/scripts/flt_palettemanager.py +++ /dev/null @@ -1,505 +0,0 @@ -#!BPY - -""" -Name: 'FLT Palette Manager' -Blender: 240 -Group: 'Misc' -Tooltip: 'Manage FLT colors' -""" - -__author__ = "Geoffrey Bantle" -__version__ = "1.0 11/21/2007" -__email__ = ('scripts', 'Author, ') -__url__ = ('blender', 'blenderartists.org') - -__bpydoc__ ="""\ - -This script manages colors in OpenFlight databases. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. - -Todo: --Figure out whats causing the PC speaker to beep when initializing... - -Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/FLTools -""" - -# -------------------------------------------------------------------------- -# flt_palettemanager.py version 1.0 2005/04/08 -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender.Draw as Draw -from Blender.BGL import * -import Blender -import flt_properties -import flt_defaultp as defaultp -from flt_properties import * - -def RGBtoHSV( r, g, b): - minc = min( r, g, b ) - maxc = max( r, g, b ) - v = maxc - - delta = maxc - minc - - if( max != 0 ): - s = delta / maxc - else: - s = 0 - h = -1 - return (h,s,v) - - if( r == maxc ): - h = ( g - b ) / delta - elif( g == maxc ): - h = 2 + ( b - r ) / delta - else: - h = 4 + ( r - g ) / delta - - h *= 60 - if( h < 0 ): - h += 360 - - return(h,s,v) - -def HSVtoRGB(h,s,v): - - if( s == 0 ): - return (v,v,v) - - - h /= 60 - i = math.floor( h) - f = h - i - p = v * ( 1 - s ) - q = v * ( 1 - s * f ) - t = v * ( 1 - s * ( 1 - f ) ) - - if i == 0: - r = v - g = t - b = p - elif i == 1: - r = q - g = v - b = p - - elif i== 2: - r = p - g = v - b = t - elif i==3: - r = p - g = q - b = v - elif i==4: - r = t - g = p - b = v - - else: - r = v - g = p - b = q - - return(r,g,b) - - -palette_size = 12 -palette_x = 0 -palette_y = 0 - -colors = list() -curint = 1.0 -curswatch = 0 -#make a default palette, not very useful. -cinc = 1.0 / 1024.0 -cstep = 0.0 -picker = None -ptt = "" - - -ts1=None -ts2=None -ts3=None -ts4=None -ts5=None - -for i in xrange(1024): - colors.append([cstep,cstep,cstep]) - cstep = cstep + cinc -def update_state(): - state = dict() - state["activeScene"] = Blender.Scene.getCurrent() - state["activeObject"] = state["activeScene"].getActiveObject() - state["activeMesh"] = None - if state["activeObject"] and state["activeObject"].type == 'Mesh': - state["activeMesh"] = state["activeObject"].getData(mesh=True) - - state["activeFace"] = None - if state["activeMesh"]: - if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None: - state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace] - - return state - -def pack_face_index(index, intensity): - return ((127*intensity)+(128*index)) -def unpack_face_index(face_index): - index = face_index / 128 - intensity = float(face_index - 128.0 * index) / 127.0 - return(index,intensity) - -def event(evt,val): - global palette_size - global palette_x - global palette_y - global colors - global curint - global curswatch - - areas = Blender.Window.GetScreenInfo() - curarea = Blender.Window.GetAreaID() - curRect = None - editmode = 0 - - for area in areas: - if area['id'] == curarea: - curRect = area['vertices'] - break - - if evt == Draw.LEFTMOUSE: - mval = Blender.Window.GetMouseCoords() - rastx = mval[0] - curRect[0] - rasty = mval[1] - curRect[1] - - swatchx = (rastx -palette_x) / palette_size #+state["palette_x"] - swatchy = (rasty -palette_y) / palette_size #+state["palette_y"] - if rastx > palette_x and rastx < (palette_x + palette_size * 32) and rasty > palette_y and rasty < (palette_y+ palette_size* 32): - if swatchx < 32 and swatchy < 32: - curswatch = (swatchx * 32) + swatchy - Draw.Redraw(1) - - elif swatchy < 34 and swatchx < 32: - curint = 1.0 - (float(rastx-palette_x)/(palette_size*32.0)) - Draw.Redraw(1) - - #copy current color and intensity to selected faces. - elif evt == Draw.VKEY: - - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - state = update_state() - - #retrieve color from palette - color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch])) - actmesh = state["activeMesh"] - if actmesh: - if(Blender.Window.GetKeyQualifiers() != Blender.Window.Qual["CTRL"]): - selfaces = list() - for face in actmesh.faces: - if face.sel: - selfaces.append(face) - - if not "FLT_COL" in actmesh.faces.properties: - actmesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"]) - for face in actmesh.faces: - face.setProperty("FLT_COL",127) #default - try: - actmesh.activeColorLayer = "FLT_Fcol" - except: - actmesh.addColorLayer("FLT_Fcol") - actmesh.activeColorLayer = "FLT_Fcol" - - - for face in selfaces: - #First append packed index + color and store in face property - face.setProperty("FLT_COL",int(pack_face_index(curswatch,curint))) - #Save baked color to face vertex colors - for col in face.col: - col.r = int(color[0] * curint) - col.g = int(color[1] * curint) - col.b = int(color[2] * curint) - col.a = int(color[3] * curint) - else: - if Blender.Mesh.Mode() == Blender.Mesh.SelectModes['VERTEX']: - if not 'FLT_VCOL' in actmesh.verts.properties: - actmesh.verts.addPropertyLayer("FLT_VCOL",Blender.Mesh.PropertyTypes["INT"]) - for vert in actmesh.verts: - vert.setProperty("FLT_VCOL",127) - else: - for vert in actmesh.verts: - if vert.sel: - vert.setProperty("FLT_VCOL",int(pack_face_index(curswatch,curint))) - - if editmode: - Blender.Window.EditMode(1) - - Blender.Window.RedrawAll() - - #grab color and intensity from active face - elif evt == Draw.CKEY: - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - state = update_state() - - actmesh = state["activeMesh"] - activeFace = state["activeFace"] - - - if activeFace: - if not "FLT_COL" in actmesh.faces.properties: - actmesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"]) - for face in actmesh.faces: - face.setProperty("FLT_COL",127) #default - try: - actmesh.activeColorLayer = "FLT_Fcol" - except: - actmesh.addColorLayer("FLT_Fcol") - actmesh.activeColorLayer = "FLT_Fcol" - tcol = activeFace.getProperty("FLT_COL") - (index,intensity) = unpack_face_index(tcol) - curswatch = index - curint = intensity - - if editmode: - Blender.Window.EditMode(1) - - Blender.Window.RedrawAll() - - elif evt == Draw.GKEY: - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode =1 - state = update_state() - - actmesh = state["activeMesh"] - activeFace = state["activeFace"] - - if activeFace and "FLT_COL" in actmesh.faces.properties: - (index,intensity) = unpack_face_index(activeFace.getProperty("FLT_COL")) - for face in actmesh.faces: - (index2, intensity2) = unpack_face_index(face.getProperty("FLT_COL")) - if index == index2: - face.sel = 1 - - - elif evt == Draw.ESCKEY: - Draw.Exit() - - if editmode: - Blender.Window.EditMode(1) - -def update_all(): - global colors - state = update_state() - #update the baked FLT colors for all meshes. - for object in state["activeScene"].objects: - if object.type == "Mesh": - mesh = object.getData(mesh=True) - if 'FLT_COL' in mesh.faces.properties and "FLT_Fcol" in mesh.getColorLayerNames(): - mesh.activeColorLayer = "FLT_Fcol" - for face in mesh.faces: - (index,intensity) = unpack_face_index(face.getProperty('FLT_COL')) - color = struct.unpack('>BBBB',struct.pack('>i',colors[index])) - #update the vertex colors for this face - for col in face.col: - col.r = int(color[0] * intensity) - col.g = int(color[1] * intensity) - col.b = int(color[2] * intensity) - col.a = 255 - - -def but_event(evt): - global palette_size - global palette_x - global palette_y - global colors - global curint - global curswatch - global picker - state = update_state() - - if evt == 1: - if picker.val: - rval = (int(picker.val[0]*255),int(picker.val[1]*255),int(picker.val[2]*255),255) - rval = struct.pack('>BBBB',rval[0],rval[1],rval[2],rval[3]) - rval = struct.unpack('>i',rval) - colors[curswatch] = rval[0] - #go cd through all meshes and update their FLT colors - update_all() - - Draw.Redraw(1) -def init_pal(): - global palette_size - global palette_x - global palette_y - global colors - global curint - global curswatch - - state = update_state() - - if not state["activeScene"].properties.has_key('FLT'): - state["activeScene"].properties['FLT'] = dict() - - try: - colors = state["activeScene"].properties['FLT']['Color Palette'] - except: - state["activeScene"].properties['FLT']['Color Palette'] = defaultp.pal - colors = state["activeScene"].properties['FLT']['Color Palette'] - -def draw_palette(): - global palette_size - global palette_x - global palette_y - global colors - global curint - global curswatch - global picker - global ts1 - global ts2 - global ts3 - global ts4 - global ts5 - - state = update_state() - init_pal() - - ssize = palette_size - xpos = palette_x - cid = 0 - - highlight = [(palette_x,palette_y),(palette_x+palette_size,palette_y),(palette_x+palette_size,palette_y+palette_size),(palette_x,palette_y+palette_size)] - for x in xrange(32): - ypos = palette_y - for y in xrange(32): - color = struct.unpack('>BBBB',struct.pack('>i',colors[cid])) - glColor3f(color[0]/255.0,color[1]/255.0,color[2]/255.0) - glBegin(GL_POLYGON) - glVertex2i(xpos,ypos) - glVertex2i(xpos+ssize,ypos) - glVertex2i(xpos+ssize,ypos+ssize) - glVertex2i(xpos,ypos+ssize) - glEnd() - - if curswatch == cid: - highlight[0] = (xpos,ypos) - highlight[1] = (xpos+ssize,ypos) - highlight[2] = (xpos+ssize,ypos+ssize) - highlight[3] = (xpos,ypos+ssize) - - glColor3f(0.0,0.0,0.0) - glBegin(GL_LINE_LOOP) - glVertex2i(xpos,ypos) - glVertex2i(xpos+ssize,ypos) - glVertex2i(xpos+ssize,ypos+ssize) - glVertex2i(xpos,ypos+ssize) - glVertex2i(xpos,ypos) - glEnd() - - - cid = cid + 1 - ypos = ypos + ssize - - xpos = xpos + ssize - - #draw intensity gradient - color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch])) - color = [color[0]/255.0,color[1]/255.0,color[2]/255.0] - colsteps = [color[0]/255.0,color[1]/255.0,color[2]/255.0] - stripwidth = (palette_size * 32.0) / 256 - strippad = palette_size / 2.0 - - xpos = palette_x - grady = (palette_y + (palette_size * 32.0)) + strippad - for x in xrange(256): - color[0] = color[0] - colsteps[0] - color[1] = color[1] - colsteps[1] - color[2] = color[2] - colsteps[2] - - glColor3f(color[0], color[1] ,color[2]) - glBegin(GL_POLYGON) - glVertex2f(xpos,grady) - glVertex2f(xpos+stripwidth,grady) - glVertex2f(xpos+stripwidth,grady+palette_size) - glVertex2f(xpos,grady+palette_size) - glEnd() - xpos = xpos + stripwidth - - #draw intensity slider bar - #xposition == 512 - ((curint) * 512) - xpos = ((palette_size*32) * (1.0 - curint)) + palette_x - glColor3f(1.0,1.0,1.0) - glBegin(GL_LINE_LOOP) - glVertex2i(int(xpos-6),int(grady-1)) - glVertex2i(int(xpos+6),int(grady-1)) - glVertex2i(int(xpos+6),int(grady+palette_size+1)) - glVertex2i(int(xpos-6),int(grady+palette_size+1)) - #glVertex2i(xpos-6,grady+7) - glEnd() - - #draw color picker - color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch])) - pickcol = (color[0]/255.0,color[1]/255.0,color[2]/255.0) - picker = Blender.Draw.ColorPicker(1,highlight[0][0]+1,highlight[0][1]+1,ssize-2,ssize-2,pickcol,ptt) - - #draw highlight swatch - glColor3f(1.0,1.0,1.0) - glBegin(GL_LINE_LOOP) - glVertex2i(highlight[0][0],highlight[0][1]) - glVertex2i(highlight[1][0],highlight[1][1]) - glVertex2i(highlight[2][0],highlight[2][1]) - glVertex2i(highlight[3][0],highlight[3][1]) - glVertex2i(highlight[0][0],highlight[0][1]) - glEnd() - - #draw text string explanations - xpos = palette_size*32+20 - ypos = palette_size*32+10 - glRasterPos2d(xpos,ypos) - ts1 = Blender.Draw.Text("FLT Palette Manager V 1.0") - ypos = ypos - 20 - glRasterPos2d(xpos,ypos) - ts3 = Blender.Draw.Text("CKEY - Copy Active Face Color*") - ypos = ypos - 20 - glRasterPos2d(xpos,ypos) - ts2 = Blender.Draw.Text("VKEY - Paste Color to Selected Faces") - ypos = ypos - 20 - glRasterPos2d(xpos,ypos) - ts4 = Blender.Draw.Text("GKEY - Select Faces With Same Color") - ypos = ypos - 15 - glRasterPos2d(xpos,ypos) - ts5 = Blender.Draw.Text("(*Requires mesh with UV coordinates)", 'small') - -def gui(): - glClearColor(0.5,0.5,0.5,1.0) - glClear(GL_COLOR_BUFFER_BIT) - draw_palette() - - -init_pal() -Draw.Register(gui,event,but_event) - \ No newline at end of file diff --git a/release/scripts/flt_properties.py b/release/scripts/flt_properties.py deleted file mode 100644 index b9d93b5f52d..00000000000 --- a/release/scripts/flt_properties.py +++ /dev/null @@ -1,630 +0,0 @@ -# flt_properties.py. For setting default OpenFLight ID property types -# Copyright (C) 2007 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. - -__bpydoc__ ="""\ -Utility functions and data defintions used by OpenFlight I/O and tool scripts. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. -""" - - -import struct - -bitsLSB = [2147483648] -for i in xrange(31): - bitsLSB.append(bitsLSB[-1]/2) -bitsRSB = bitsLSB[:] -bitsRSB.reverse() - -def pack_color(col): - return struct.pack('>B',col[3]) + struct.pack('>B',col[2]) + struct.pack('>B',col[1]) + struct.pack('>B',col[0]) - -def unpack_color(col): - string = struct.pack('>I', col) - r = struct.unpack('>B',string[3:4]) - g = struct.unpack('>B',string[2:3]) - b = struct.unpack('>B',string[1:2]) - a = struct.unpack('>B',string[0:1]) - return [r,g,b,a] - -def reverse_bits(len,num): - bitbucket = list() - rval = 0 - - for i in xrange(len): - if num & bitsRSB[i]: - bitbucket.append(1) - else: - bitbucket.append(0) - - bitbucket.reverse() - - for i, bit in enumerate(bitbucket): - if bit: - rval |= bitsLSB[i] - - return rval - - -opcode_name = { 0: 'db', - 1: 'head', - 2: 'grp', - 4: 'obj', - 5: 'face', - 10: 'push', - 11: 'pop', - 14: 'dof', - 19: 'push sub', - 20: 'pop sub', - 21: 'push ext', - 22: 'pop ext', - 23: 'cont', - 31: 'comment', - 32: 'color pal', - 33: 'long id', - 49: 'matrix', - 50: 'vector', - 52: 'multi-tex', - 53: 'uv lst', - 55: 'bsp', - 60: 'rep', - 61: 'inst ref', - 62: 'inst def', - 63: 'ext ref', - 64: 'tex pal', - 67: 'vert pal', - 68: 'vert w col', - 69: 'vert w col & norm', - 70: 'vert w col, norm & uv', - 71: 'vert w col & uv', - 72: 'vert lst', - 73: 'lod', - 74: 'bndin box', - 76: 'rot edge', - 78: 'trans', - 79: 'scl', - 80: 'rot pnt', - 81: 'rot and/or scale pnt', - 82: 'put', - 83: 'eyepoint & trackplane pal', - 84: 'mesh', - 85: 'local vert pool', - 86: 'mesh prim', - 87: 'road seg', - 88: 'road zone', - 89: 'morph vert lst', - 90: 'link pal', - 91: 'snd', - 92: 'rd path', - 93: 'snd pal', - 94: 'gen matrix', - 95: 'txt', - 96: 'sw', - 97: 'line styl pal', - 98: 'clip reg', - 100: 'ext', - 101: 'light src', - 102: 'light src pal', - 103: 'reserved', - 104: 'reserved', - 105: 'bndin sph', - 106: 'bndin cyl', - 107: 'bndin hull', - 108: 'bndin vol cntr', - 109: 'bndin vol orient', - 110: 'rsrvd', - 111: 'light pnt', - 112: 'tex map pal', - 113: 'mat pal', - 114: 'name tab', - 115: 'cat', - 116: 'cat dat', - 117: 'rsrvd', - 118: 'rsrvd', - 119: 'bounding hist', - 120: 'rsrvd', - 121: 'rsrvd', - 122: 'push attrib', - 123: 'pop attrib', - 124: 'rsrvd', - 125: 'rsrvd', - 126: 'curv', - 127: 'road const', - 128: 'light pnt appear pal', - 129: 'light pnt anim pal', - 130: 'indexed lp', - 131: 'lp sys', - 132: 'indx str', - 133: 'shdr pal'} - - -typecodes = ['c','C','s','S','i','I','f','d','t'] - -FLT_GRP = 2 -FLT_OBJ = 4 -FLT_LOD = 73 -FLT_XRF = 63 -FLT_DOF = 14 -FLT_ILP = 111 -FLT_DB = 1 -FLT_FCE = 5 - -#not actual opcodes -FLT_NUL = 0 -FLT_EXP = -1 - -#valid childtypes for each FLT node type -FLT_CHILDTYPES = { - FLT_GRP : [111,2,73,4,14,63], - FLT_OBJ : [111], - FLT_LOD : [111,2,73,4,14,63], - FLT_XRF : [], - FLT_DOF : [111,2,73,4,14,63], - FLT_ILP : [] -} - -#List of nodes that can have faces as children -FLT_FACETYPES = [ - FLT_GRP, - FLT_OBJ, - FLT_LOD, - FLT_DOF -] - -def write_prop(fw,type,value,length): - if type == 'c': - fw.write_char(value) - elif type == 'C': - fw.write_uchar(value) - elif type == 's': - fw.write_short(value) - elif type == 'S': - fw.write_ushort(value) - elif type == 'i': - fw.write_int(value) - elif type == 'I': - #NOTE!: - #there is no unsigned int type in python, but we can only store signed ints in ID props - newvalue = struct.unpack('>I', struct.pack('>i', value))[0] - fw.write_uint(newvalue) - elif type == 'd': - fw.write_double(value) - elif type == 'f': - fw.write_float(value) - elif type == 't': - fw.write_string(value,length) - -def read_prop(fw,type,length): - rval = None - if type == 'c': - rval = fw.read_char() - elif type == 'C': - rval = fw.read_uchar() - elif type == 's': - rval = fw.read_short() - elif type == 'S': - rval = fw.read_ushort() - elif type == 'i': - rval = fw.read_int() - elif type == 'I': - rval = fw.read_uint() - elif type == 'd': - rval = fw.read_double() - elif type == 'f': - rval = fw.read_float() - elif type == 't': - rval = fw.read_string(length) - return rval - - -FLTExt = { - '3t8!id' : 'Ext', - '4t8!sid' : '', - '5c!reserved': 0, - '6c!revision' : 0, - '7S!recordcode' : 0 -} -FLTGroup = { - '3t8!id' : 'G', - '4s!priority' : 0, - '5s!reserved1' : 0, - '6i!flags' : 0, - '7s!special1' : 0, - '8s!special2' : 0, - '9s!significance' : 0, - '10c!layer code' : 0, - '11c!reserved2' : 0, - '12i!reserved3' : 0, - '13i!loop count' : 0, - '14f!loop duration' : 0, - '15f!last frame duration' : 0 -} -FLTGroupDisplay = [5,11,12] - -FLTObject = { - '3t8!id' : 'O', - '4I!flags' : 0, - '5s!priority' : 0, - '6S!transp' : 0, - '7s!SFX1' : 0, - '8s!SFX2' : 0, - '9s!significance' : 0, - '10s!reserved' : 0 -} -FLTObjectDisplay = [10] - -FLTLOD = { - '3t8!id' : 'L', - '4i!reserved' : 0, - '5d!switch in' : 0.0, - '6d!switch out' : 0.0, - '7s!sfx ID1' : 0, - '8s!sfx ID2' : 0, - '9I!flags' : 0, - '10d!X co' : 0.0, - '11d!Y co' : 0.0, - '12d!Z co' : 0.0, - '13d!Transition' : 0.0, - '14d!Sig Size' : 0.0 -} -FLTLODDisplay = [4] - -FLTInlineLP = { - '3t8!id' : 'Lp', - '4s!smc' : 0, - '5s!fid' : 0, - '6C!back color: a' : 255, - '7C!back color: b' : 255, - '8C!back color: g' : 255, - '9C!back color: r' : 255, - '10i!display mode' : 0, - '11f!intensity' : 1.0, - '12f!back intensity' : 0.0, - '13f!minimum defocus' : 0.0, - '14f!maximum defocus' : 1.0, - '15i!fading mode' : 0, - '16i!fog punch mode' : 0, - '17i!directional mode' : 1, - '18i!range mode' : 0, - '19f!min pixel size' : 1.0, - '20f!max pixel size' : 1024, - '21f!actual size' : 0.25, - '22f!trans falloff pixel size' : 0.25, - '23f!trans falloff exponent' : 1.0, - '24f!trans falloff scalar' : 1.0, - '25f!trans falloff clamp' : 1.0, - '26f!fog scalar' : 0.25, - '27f!fog intensity' : 1.0, - '28f!size threshold' : 0.1, - '29i!directionality' : 0, - '30f!horizontal lobe angle' : 180.0, - '31f!vertical lobe angle' : 180.0, - '32f!lobe roll angle' : 0.0, - '33f!dir falloff exponent' : 1.0, - '34f!dir ambient intensity' : 0.1, - '35f!anim period' : 2, - '36f!anim phase' : 0, - '37f!anim enabled' : 1.0, - '38f!significance' : 0.0, - '39i!draw order' : 0, - '40I!flags' : 277004288, - '41f!roti' : 0, - '42f!rotj' : 0, - '43f!rotk' : 1.0 -} - -FLTInlineLPDisplay = [35,36,37,41,42,43] - -FLTXRef = { - '3t200!filename' : '', #we dont actually use this value on export - '4i!reserved' : 0, - '5I!flag' : -478150656, - '6s!bbox' : 0, - '7s!reserved' : 0 -} - -FLTXRefDisplay = [4,7,3] - -FLTDOF = { - '3t8!id' : 'D', - '4i!reserved' : 0, - '5d!ORIGX' : 0.0, - '6d!ORIGY' : 0.0, - '7d!ORIGZ' : 0.0, - '8d!XAXIS-X' : 10.0, - '9d!XAXIS-Y' : 0.0, - '10d!XAXIS-Z' : 0.0, - '11d!XYPLANE-X' : 0.0, - '12d!XYPLANE-Y' : 10.0, - '13d!XZPLANE-Z' : 0.0, - '14d!ZMIN' : 0.0, - '15d!ZMAX' : 0.0, - '16d!ZCUR' : 0.0, - '17d!ZSTEP' : 0.0, - '18d!YMIN' : 0.0, - '19d!YMAX' : 0.0, - '20d!YCUR' : 0.0, - '21d!YSTEP' : 0.0, - '22d!XMIN' : 0.0, - '23d!XMAX' : 0.0, - '24d!XCUR' : 0.0, - '25d!XSTEP' : 0.0, - '26d!PITCH-MIN' : 0.0, - '27d!PITCH-MAX' : 0.0, - '28d!PITCH-CUR' : 0.0, - '29d!PITCH-STEP' : 0.0, - '30d!ROLL-MIN' : 0.0, - '31d!ROLL-MAX' : 0.0, - '32d!ROLL-CUR' : 0.0, - '33d!ROLL-STEP' : 0.0, - '34d!YAW-MIN' : 0.0, - '35d!YAW-MAX' : 0.0, - '36d!YAW-CUR' : 0.0, - '37d!YAW-STEP' : 0.0, - '38d!ZSIZE-MIN' : 0.0, - '39d!ZSIZE-MAX' : 0.0, - '40d!ZSIZE-CUR' : 1.0, - '41d!ZSIZE-STEP' : 0.0, - '42d!YSIZE-MIN' : 0.0, - '43d!YSIZE-MAX' : 0.0, - '44d!YSIZE-CUR' : 1.0, - '45d!YSIZE-STEP' : 0.0, - '46d!XSIZE-MIN' : 0.0, - '47d!XSIZE-MAX' : 0.0, - '48d!XSIZE-CUR' : 1.0, - '49d!XSIZE-STEP' : 0.0, - '50I!FLAG' : 1897582, - '51i!reserved2' : 0 -} - -FLTDOFDisplay = [4] - -FLTImage = { - '3i!RealU Direction' : 0, - '4i!RealV Direction' : 0, - '5i!UpX' : 0, - '6i!UpY' : 0, - '7i!File Format' : 0, - '8i!Min Filter' : 6, - '9i!Mag Filter' : 1, - '10i!Wrap' : 0, - '11i!WrapU' : 0, - '12i!WrapV' : 0, - '13i!Modified' : 0, - '14i!PivotX' : 0, - '15i!PivotY' : 0, - '16i!Enviorment' : 0, - '17i!WhiteAlpha' : 0, - '18i!reserved1' : 0, - '19i!reserved2' : 0, - '20i!reserved3' : 0, - '21i!reserved4' : 0, - '22i!reserved5' : 0, - '23i!reserved6' : 0, - '24i!reserved7' : 0, - '25i!reserved8' : 0, - '26i!reserved9' : 0, - '27d!RealU Direction' : 0, - '28d!RealV Direction' : 0, - '29i!Origin' : 0, - '30i!Kernel no.' : 0, - '31i!Internal Format' : 0, - '32i!External Format' : 0, - '33i!MipMap Filter?' : 0, - '34f!MMF1' : 0.0, - '35f!MMF2' : 0.0, - '36f!MMF3' : 0.0, - '37f!MMF4' : 0.0, - '38f!MMF5' : 0.0, - '39f!MMF6' : 0.0, - '40f!MMF7' : 0.0, - '41f!MMF8' : 0.0, - '42i!Tex CPs?' : 0, - '43f!LOD0 CP' : 0.0, - '44f!Scale0 CP' : 0.0, - '45f!LOD1 CP' : 0.0, - '46f!Scale1 CP' : 0.0, - '47f!LOD2 CP' : 0.0, - '48f!Scale2 CP' : 0.0, - '49f!LOD3 CP' : 0.0, - '50f!Scale3 CP' : 0.0, - '51f!LOD4 CP' : 0.0, - '52f!Scale4 CP' : 0.0, - '53f!LOD5 CP' : 0.0, - '54f!Scale5 CP' : 0.0, - '55f!LOD6 CP' : 0.0, - '56f!Scale6 CP' : 0.0, - '57f!LOD7 CP' : 0.0, - '58f!Scale7 CP' : 0.0, - '59f!Control Clamp' : 0.0, - '60i!Mag Alpha Filter' : 0, - '61i!Mag Color Filter' : 0, - '62f!reserved10' : 0, - '63f!reserved11' : 0, - '64f!reserved12' : 0, - '65f!reserved13' : 0, - '66f!reserved14' : 0, - '67f!reserved15' : 0, - '68f!reserved16' : 0, - '69f!reserved17' : 0, - '70f!reserved18' : 0, - '71d!Lambert Central' : 0.0, - '72d!Lambert Upper' : 0.0, - '73d!Lambert Lower' : 0.0, - '74d!reserved19' : 0, - '75f!reserved20' : 0, - '76f!reserved21' : 0, - '77f!reserved22' : 0, - '78f!reserved23' : 0, - '79f!reserved24' : 0, - '80i!Tex Detail?' : 0, - '81i!Tex J' : 0, - '82i!Tex K' : 0, - '83i!Tex M' : 0, - '84i!Tex N' : 0, - '85i!Tex Scramble' : 0, - '86i!Tex Tile?' : 0, - '87f!Tex Tile LLU' : 0.0, - '88f!Tex Tile LLV' : 0.0, - '89f!Tex Tile URU' : 0.0, - '90f!Tex Tile URV' : 0.0, - '91i!Projection' : 0, - '92i!Earth Model' : 0, - '93i!reserved25' : 0, - '94i!UTM Zone' : 0, - '95i!Image Origin' : 0, - '96i!GPU' : 0, - '97i!reserved26' : 0, - '98i!reserved27' : 0, - '99i!GPU Hemi' : 0, - '100i!reserved41' : 0, - '101i!reserved42' : 0, - '102i!reserved43' : 0, - '103i!Cubemap' : 0, - '104t588!reserved44' : '', - '105t512!Comments' : '', - '106i!reserved28' : 0, - '107i!reserved29' : 0, - '108i!reserved30' : 0, - '109i!reserved31' : 0, - '110i!reserved32' : 0, - '111i!reserved33' : 0, - '112i!reserved34' : 0, - '113i!reserved35' : 0, - '114i!reserved36' : 0, - '115i!reserved37' : 0, - '116i!reserved38' : 0, - '117i!reserved39' : 0, - '118i!reserved40' : 0, - '119i!reserved45' : 0, - '120i!Format Version' : 0, - '121i!GPU num' : 0, -} - -FLTImageDisplay = [18,19,29,21,22,23,24,25,26,62,63,64,65,66,67,68,69,70,74,75,76,77,78,79,93,97,98,102,114] - -FLTHeader = { - '3t8!id' : 'db', - '4i!version' : 1620, - '5i!editversion' : 0, - '6t32!date' : 0, - '7s!NGID' : 0, - '8s!NLID' : 0, - '9s!NOID' : 0, - '10s!NFID' : 0, - '11s!UMULT' : 1, - '12c!units' : 0, - '13c!set white' : 0, - '14I!flags' : 0x80000000, - '15i!reserved1' : 0, - '16i!reserved2' : 0, - '17i!reserved3' : 0, - '18i!reserved4' : 0, - '19i!reserved5' : 0, - '20i!reserved6' : 0, - '21i!projection type' : 0, - '22i!reserved7' : 0, - '23i!reserved8' : 0, - '24i!reserved9' : 0, - '25i!reserved10' : 0, - '26i!reserved11' : 0, - '27i!reserved12' : 0, - '28i!reserved13' : 0, - '29s!NDID' : 0, - '30s!vstore' : 1, - '31i!origin' : 0, - '32d!sw x' : 0, - '33d!sw y' : 0, - '34d!dx' : 0, - '35d!dy' : 0, - '36s!NSID' : 0, - '37s!NPID' : 0, - '38i!reserved14' : 0, - '39i!reserved15' : 0, - '40s!NCID' : 0, - '41s!NTID' : 0, - '42s!NBID' : 0, - '43s!NWID' : 0, - '44i!reserved14' : 0, - '45d!sw lat' : 0, - '46d!sw lon' : 0, - '47d!ne lat' : 0, - '48d!ne lon' : 0, - '49d!origin lat' : 0, - '50d!origin lon' : 0, - '51d!lambert lat1' : 0, - '52d!lambert lat2' : 0, - '53s!NLSID' : 0, - '54s!NLPID' : 0, - '55s!NRID' : 0, - '56s!NCATID' : 0, - '57s!reserved15' : 0, - '58s!reserved16' : 0, - '59s!reserved17' : 0, - '60s!reserved18' : 0, - '61i!ellipsoid model' : 1, - '62s!NAID' : 0, - '63s!NCVID' : 0, - '64s!utm zone' : 0, - '65t6!reserved19' : 0, - '66d!dz' : 0, - '67d!radius' : 0, - '68S!NMID' : 0, - '69S!NLPSID' : 0, - '70i!reserved20' : 0, - '71d!major axis' : 0, - '72d!minor axis' : 0, -} - -FLT_Records = { - 2 : FLTGroup, - 4 : FLTObject, - 73 : FLTLOD, - 63 : FLTXRef, - 14 : FLTDOF, - 1 : FLTHeader, - 111 : FLTInlineLP, - 100 : FLTExt, - 'Image' : FLTImage -} - -def process_recordDefs(): - records = dict() - for record in FLT_Records: - props = dict() - for prop in FLT_Records[record]: - position = '' - slice = 0 - (format,name) = prop.split('!') - for i in format: - if i not in typecodes: - position = position + i - slice = slice + 1 - else: - break - type = format[slice:] - length = type[1:] - if len(length) == 0: - length = 1 - else: - type = type[0] - length = int(length) - - props[int(position)] = (type,length,prop) - records[record] = props - return records - - diff --git a/release/scripts/flt_toolbar.py b/release/scripts/flt_toolbar.py deleted file mode 100644 index a707b87f846..00000000000 --- a/release/scripts/flt_toolbar.py +++ /dev/null @@ -1,809 +0,0 @@ -#!BPY - -""" -Name: 'FLT Toolbar' -Blender: 240 -Group: 'Misc' -Tooltip: 'Tools for working with FLT databases' -""" - -__author__ = "Geoffrey Bantle" -__version__ = "1.0 11/21/07" -__email__ = ('scripts', 'Author, ') -__url__ = ('blender', 'blenderartists.org') - -__bpydoc__ ="""\ -This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a -registered trademark of MultiGen-Paradigm, Inc. - -Feature overview and more availible at: -http://wiki.blender.org/index.php/Scripts/Manual/FLTools -""" - -# -------------------------------------------------------------------------- -# flt_palettemanager.py version 0.1 2005/04/08 -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2007: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender.Draw as Draw -from Blender.BGL import * -import Blender -import flt_properties -reload(flt_properties) -from flt_properties import * - -xrefprefix = "" -xrefstack = list() -vofsstack = list() -vquatstack = list() -prop_w = 256 -prop_h = 256 - - -#event codes -evcode = { - "XREF_MAKE" : 100, - "XREF_EDIT" : 101, - "XREF_FILE" : 102, - "XREF_PICK" : 103, - "XREF_SELECT" : 104, - "XREF_POP" : 105, - "XREF_PREFIX" : 106, - "FACE_NAME" : 200, - "FACE_MAKESUB" : 201, - "FACE_KILLSUB" : 202, - "FACE_SELSUB" : 203, - "SCENE_UPDATE" : 303, - "IDPROP_COPY" : 501, - "IDPROP_KILL" : 502, - "CLIGHT_MAKE" : 700, - "DFROMACT" : 701, - "FIXCOL" : 702 -} - -XREF_PREFIX = None -XREF_MAKE = None -XREF_EDIT = None -XREF_SELECT = None -XREF_POP = None -FACE_MAKESUB = None -FACE_SELSUB = None -FACE_KILLSUB = None -IDPROP_KILL = None -IDPROP_COPY = None -SCENE_UPDATE = None -CLIGHT_MAKE = None -DFROMACT = None -FIXCOL = None - - -def RGBtoHSV( r, g, b): - cmin = min( r, g, b ) - cmax = max( r, g, b ) - v = cmax - - if(cmax!=0.0): - s = (cmax-cmin)/cmax - else: - s = 0.0 - h = 0.0 - - if(s == 0.0): - h = -1.0 - else: - cdelta = cmax-cmin - rc = (cmax-r)/cdelta - gc = (cmax-g)/cdelta - bc = (cmax-b)/cdelta - if(r==cmax): - h = bc-gc - else: - if(g==cmax): - h = 2.0+rc-bc - else: - h = 4.0+gc-rc - h = h*60.0 - if(h<0.0): - h += 360.0 - - - h = h/360.0 - if(h < 0.0): - h = 0.0 - return (h,s,v) - - -def update_state(): - state = dict() - state["activeScene"] = Blender.Scene.GetCurrent() - state["activeObject"] = state["activeScene"].objects.active - if state["activeObject"] and not state["activeObject"].sel: - state["activeObject"] = None - state["activeMesh"] = None - if state["activeObject"] and state["activeObject"].type == 'Mesh': - state["activeMesh"] = state["activeObject"].getData(mesh=True) - - state["activeFace"] = None - if state["activeMesh"]: - if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None: - state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace] - - #update editmode - state["editmode"] = Blender.Window.EditMode() - - return state -def pack_face_index(index, intensity): - return ((127*intensity)+(128*index)) -def unpack_face_index(face_index): - index = face_index / 128 - intensity = float(face_index - 128.0 * index) / 127.0 - return(index,intensity) - -def idprops_append(object, typecode, props): - object.properties["FLT"] = dict() - object.properties["FLT"]['type'] = typecode - for prop in props: - object.properties["FLT"][prop] = props[prop] - object.properties["FLT"]['3t8!id'] = object.name - -def idprops_kill(object): - state = update_state() - if object and object.properties.has_key('FLT'): - object.properties.pop('FLT') - -def idprops_copy(source): - state = update_state() - if source.properties.has_key('FLT'): - for object in state["activeScene"].objects: - if object.sel and object != source and (state["activeScene"].Layers & object.Layers): - idprops_kill(object) - object.properties['FLT'] = dict() - for key in source.properties['FLT']: - object.properties['FLT'][key] = source.properties['FLT'][key] - -def unpack_color(color): - return struct.unpack('>BBBB',struct.pack('>I',color)) - - -def findColorKey(colordict, hsv): - hdelta = 0.001 - for key in colordict: - if not (((hsv[0] < (key[0] + hdelta)) and (hsv[0] > (key[0] - hdelta))) and ((hsv[1] < (key[1] + hdelta)) and (hsv[1] > (key[1] - hdelta)))): - return key - return None - -def hsvsort(a, b): - (index1, mag1) = a - (index2, mag2) = b - if mag1 > mag2: - return 1 - elif mag1 < mag2: - return -1 - return 0 - -def fix_colors(): - - editmode = 0 - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - state = update_state() - - scene = state["activeScene"] - colors = None - if state["activeScene"].properties.has_key('FLT'): - try: - colors = state["activeScene"].properties['FLT']['Color Palette'] - except: - pass - if not colors: - return - - #first build a HSV version of our palette - hsvpalette = list() - for swatch in colors: - color = unpack_color(swatch) - hsv = RGBtoHSV(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0) - hsvpalette.append(hsv) - - #collect all of our meshes - meshes = list() - for object in scene.objects.context: - if object.sel and object.type == 'Mesh': - mesh = object.getData(mesh=True) - if "FLT_COL" in mesh.faces.properties: - meshes.append(mesh) - - - #Now go through our meshes, and build a dictionary of face lists keyed according to (hue,saturation) of the baked color - colordict = dict() - for mesh in meshes: - for face in mesh.faces: - hsv = RGBtoHSV(face.col[0].r/255.0, face.col[0].g/255.0, face.col[0].b/255.0) #retrieve baked color - if colordict.has_key((hsv[0],hsv[1])): - colordict[(hsv[0],hsv[1])].append(face) - else: - colordict[(hsv[0],hsv[1])] = [face] - - - #for each color key in the color dict, build a list of distances from it to the values in hsvpalette and then quicksort them for closest match - for key in colordict: - maglist = list() - for i, hsv in enumerate(hsvpalette): - norm = Blender.Mathutils.Vector(hsv[0], hsv[1]) - Blender.Mathutils.Vector(key[0],key[1]) - maglist.append((i,norm.length)) - maglist.sort(hsvsort) - print maglist[0] - for face in colordict[key]: - (index, intensity) = unpack_face_index(face.getProperty("FLT_COL")) - newfindex = pack_face_index(maglist[0][0],intensity) - face.setProperty("FLT_COL", int(newfindex)) - - for mesh in meshes: - update_mesh_colors(colors,mesh) - - if editmode: - Blender.Window.EditMode(1) - - -def update_mesh_colors(colors, mesh): - if 'FLT_COL' in mesh.faces.properties: - mesh.activeColorLayer = "FLT_Fcol" - for face in mesh.faces: - (index,intensity) = unpack_face_index(face.getProperty('FLT_COL')) - color = struct.unpack('>BBBB',struct.pack('>I',colors[index])) - - if index == 0 and intensity == 0: - color = (255,255,255) - intensity = 1.0 - #update the vertex colors for this face - for col in face.col: - col.r = int(color[0] * intensity) - col.g = int(color[1] * intensity) - col.b = int(color[2] * intensity) - col.a = 255 - - -def update_all(): - - editmode = 0 - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - state = update_state() - colors = None - if state["activeScene"].properties.has_key('FLT'): - try: - colors = state["activeScene"].properties['FLT']['Color Palette'] - except: - pass - if colors: - #update the baked FLT colors for all meshes. - for object in state["activeScene"].objects: - if object.type == "Mesh": - mesh = object.getData(mesh=True) - update_mesh_colors(colors,mesh) - if editmode: - Blender.Window.EditMode(1) - -#Change this to find the deep parent -def xref_create(): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - state = update_state() - - def findchildren(object): - children = list() - for candidate in state["activeScene"].objects: - if candidate.parent == object: - children.append(candidate) - retlist = list(children) - for child in children: - retlist = retlist + findchildren(child) - return retlist - - actObject = state["activeObject"] - if actObject and xrefprefix: - scenenames = list() - for scene in Blender.Scene.Get(): - scenenames.append(scene.name) - - if xrefprefix in scenenames: - #build a unique name for the xref... - suffix = 1 - found = False - while not found: - candidate = xrefprefix + str(suffix) - if not candidate in scenenames: - xrefname = candidate - found = True - suffix+=1 - else: - xrefname = xrefprefix - #create our XRef node - xnode = state["activeScene"].objects.new('Empty') - xnode.name = 'X:' + xrefname - xnode.properties['FLT'] = dict() - for prop in FLTXRef: - xnode.properties['FLT'][prop] = FLTXRef[prop] - xnode.properties['FLT']['3t200!filename'] = xrefname + '.flt' - xnode.properties['FLT']['type'] = 63 - xnode.enableDupGroup = True - xnode.DupGroup = Blender.Group.New(xrefname) #this is dangerous... be careful! - - #copy rot and loc of actObject - xnode.setLocation(actObject.getLocation()) - xnode.setEuler(actObject.getEuler()) - - #build the new scene - xrefscene = Blender.Scene.New(xrefname) - xrefscene.properties['FLT'] = dict() - xrefscene.properties['FLT']['Filename'] = xrefname - xrefscene.properties['FLT']['Main'] = 0 - - #find the children of actObject so that we can add them to the group - linkobjects = findchildren(actObject) - linkobjects.append(actObject) - for object in linkobjects: - xrefscene.objects.link(object) - state["activeScene"].objects.unlink(object) - xnode.DupGroup.objects.link(object) - #clear rotation of actObject and location - actObject.setLocation(0.0,0.0,0.0) - actObject.setEuler(0.0,0.0,0.0) - - xrefscene.update(1) - state["activeScene"].update(1) - -def xref_select(): - state = update_state() - candidates = list() - scenelist = [scene.name for scene in Blender.Scene.Get()] - for object in state["activeScene"].objects: - if object.type == 'Empty' and object.enableDupGroup == True and object.DupGroup: - candidates.append(object) - - for object in candidates: - if object.DupGroup.name in scenelist: - object.sel = 1 - -def xref_edit(): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - state = update_state() - - actObject = state["activeObject"] - - if actObject and actObject.type == 'Empty' and actObject.DupGroup: -# if actObject.properties.has_key('FLT') and actObject.properties['FLT']['type'] == 63: - for FLTscene in Blender.Scene.Get(): - if FLTscene.properties.has_key('FLT') and FLTscene.name == actObject.DupGroup.name: - actObject.sel = 0 - xrefstack.append(state["activeScene"]) - vofsstack.append(Blender.Window.GetViewOffset()) - vquatstack.append(Blender.Window.GetViewQuat()) - FLTscene.makeCurrent() - Blender.Window.SetViewOffset(0.0,0.0,0.0) - -def xref_finish(): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - state = update_state() - if xrefstack: - scene = xrefstack.pop() - Blender.Window.SetViewQuat(vquatstack.pop()) - Blender.Window.SetViewOffset(vofsstack.pop()) - scene.makeCurrent() - - -def sortSub(a,b): - aindex = a.getProperty("FLT_ORIGINDEX") - bindex = b.getProperty("FLT_ORIGINDEX") - - if aindex > bindex: - return 1 - elif aindex < bindex: - return -1 - return 0 - -def subface_make(): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - editmode = 0 - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - - state = update_state() - - actmesh = state["activeMesh"] - activeFace = state["activeFace"] - if actmesh: - if not "FLT_ORIGINDEX" in actmesh.faces.properties: - actmesh.faces.addPropertyLayer("FLT_ORIGINDEX",Blender.Mesh.PropertyTypes["INT"]) - for i, face in enumerate(actmesh.faces): - face.setProperty("FLT_ORIGINDEX",i) - if not "FLT_SFLEVEL" in actmesh.faces.properties: - actmesh.faces.addPropertyLayer("FLT_SFLEVEL",Blender.Mesh.PropertyTypes["INT"]) - - #attach the subfaces to the active face. Note, this doesnt really work 100 percent properly yet, just enough for one level! - if activeFace: - #steps: - #remove actface and selected faces from the facelist - #quicksort facelist - #append actface and subfaces to end of facelist. - #generate new indices - facelist = list() - sublist = list() - for face in actmesh.faces: - facelist.append(face) - for face in facelist: - if face == activeFace: - face.setProperty("FLT_SFLEVEL",0) - sublist.insert(0,face) - elif face.sel: - face.setProperty("FLT_SFLEVEL",1) - sublist.append(face) - for face in sublist: - facelist.remove(face) - facelist.sort(sortSub) - for face in sublist: - facelist.append(face) - for i, face in enumerate(facelist): - face.setProperty("FLT_ORIGINDEX",i) - else: - pass - - if editmode: - Blender.Window.EditMode(1) - -def subface_kill(): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - editmode = 0 - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - state = update_state() - - actmesh = state["activeMesh"] - if actmesh: - if "FLT_ORIGINDEX" in actmesh.faces.properties and "FLT_SFLEVEL" in actmesh.faces.properties: - for i,face in enumerate(actmesh.faces): - face.setProperty("FLT_ORIGINDEX",i) - face.setProperty("FLT_SFLEVEL",0) - if editmode: - Blender.Window.EditMode(1) - -def subface_select(): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - editmode = 0 - if Blender.Window.EditMode(): - Blender.Window.EditMode(0) - editmode = 1 - state = update_state() - - actmesh = state["activeMesh"] - activeFace = state["activeFace"] - if actmesh and activeFace: - if "FLT_ORIGINDEX" in actmesh.faces.properties and "FLT_SFLEVEL" in actmesh.faces.properties: - facelist = list() - actIndex = None - sublevel = None - for face in actmesh.faces: - facelist.append(face) - facelist.sort(sortSub) - for i, face in enumerate(facelist): - if face == activeFace: - actIndex = i - sublevel = face.getProperty("FLT_SFLEVEL")+1 - break - leftover = facelist[actIndex+1:] - for face in leftover: - if face.getProperty("FLT_SFLEVEL") == sublevel: - face.sel = 1 - else: - break - if editmode: - Blender.Window.EditMode(1) - -def select_by_typecode(typecode): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - - state = update_state() - - for object in state["activeScene"].objects: - if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers: - object.select(1) -def clight_make(): - state = update_state() - actmesh = state["activeMesh"] - actobj = state["activeObject"] - - if actobj and actmesh: - actobj.properties['FLT'] = dict() - actobj.properties['FLT']['type'] = 111 - for prop in FLTInlineLP: - actobj.properties['FLT'][prop] = FLTInlineLP[prop] - - actmesh.verts.addPropertyLayer("FLT_VCOL", Blender.Mesh.PropertyTypes["INT"]) - for v in actmesh.verts: - v.setProperty("FLT_VCOL", 83815) - -def dfromact(): - state = update_state() - actobj = state["activeObject"] - actscene = state["activeScene"] - dof = None - - for object in actscene.objects.context: - if object.sel and (object != actobj): - if not dof: - dof = object - else: - break - - if not dof: - return - - if 'FLT' not in dof.properties: - dof.properties['FLT'] = dict() - - #Warning! assumes 1 BU == 10 meters. - #do origin - dof.properties['FLT']['5d!ORIGX'] = actobj.getLocation('worldspace')[0]*10.0 - dof.properties['FLT']['6d!ORIGY'] = actobj.getLocation('worldspace')[1]*10.0 - dof.properties['FLT']['7d!ORIGZ'] = actobj.getLocation('worldspace')[2]*10.0 - #do X axis - x = Blender.Mathutils.Vector(1.0,0.0,0.0) - x = x * actobj.getMatrix('worldspace') - x = x * 10.0 - dof.properties['FLT']['8d!XAXIS-X'] = x[0] - dof.properties['FLT']['9d!XAXIS-Y'] = x[1] - dof.properties['FLT']['10d!XAXIS-Z'] = x[2] - #do X/Y plane - x = Blender.Mathutils.Vector(1.0,1.0,0.0) - x.normalize() - x = x * actobj.getMatrix('worldspace') - x = x * 10.0 - dof.properties['FLT']['11d!XYPLANE-X'] = x[0] - dof.properties['FLT']['12d!XYPLANE-Y'] = x[1] - dof.properties['FLT']['13d!XZPLANE-Z'] = x[2] - - - - - -def event(evt,val): - if evt == Draw.ESCKEY: - Draw.Exit() - -def but_event(evt): - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - global evcode - - state = update_state() - - #do Xref buttons - if evt == evcode["XREF_PREFIX"]: - xrefprefix = XREF_PREFIX.val - if evt == evcode["XREF_EDIT"]: - xref_edit() - if evt == evcode["XREF_SELECT"]: - xref_select() - if evt == evcode["XREF_MAKE"]: - xref_create() - #do scene buttons - if evt == evcode["SCENE_UPDATE"]: - update_all() - #do face buttons - if evt == evcode["FACE_MAKESUB"]: - subface_make() - if evt== evcode["FACE_KILLSUB"]: - subface_kill() - if evt== evcode["FACE_SELSUB"]: - subface_select() - #common buttons - if evt == evcode["IDPROP_KILL"]: - if state["activeObject"]: - idprops_kill(state["activeObject"]) - if evt == evcode["IDPROP_COPY"]: - if state["activeObject"]: - idprops_copy(state["activeObject"]) - if evt == evcode["XREF_POP"]: - xref_finish() - if evt == evcode["CLIGHT_MAKE"]: - clight_make() - if evt == evcode["DFROMACT"]: - dfromact() - if evt == evcode["FIXCOL"]: - fix_colors() - Draw.Redraw(1) - Blender.Window.RedrawAll() - - -def box(x,y,w,h,c,mode): - glColor3f(c[0],c[1],c[2]) - if mode == "outline": - glBegin(GL_LINE_LOOP) - else: - glBegin(GL_POLYGON) - glVertex2i(x,y) - glVertex2i(x+w,y) - glVertex2i(x+w,y+h) - glVertex2i(x,y+h) - glEnd() - -def draw_postcommon(x,y,finaly): - global sheetlabel - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - global evcode - - state = update_state() - - width = prop_w - height = prop_h - - #draw the header - glColor3f(0.15,0.15,0.15) - glBegin(GL_POLYGON) - glVertex2i(x-1,y) - glVertex2i(x+width+1,y) - glVertex2i(x+width+1,y-25) - glVertex2i(x-1,y-25) - glEnd() - glColor3f(1,1,1) - glRasterPos2i(x,y-20) - sheetlabel = Blender.Draw.Text("FLT Tools Panel") - #draw the box outline - glColor3f(0,0,0) - glBegin(GL_LINE_LOOP) - glVertex2i(x-1,y) - glVertex2i(x+1+width,y) - glVertex2i(x+1+width,finaly-1) - glVertex2i(x-1,finaly-1) - glEnd() - return finaly - - -def draw_propsheet(x,y): - global XREF_PREFIX - global XREF_MAKE - global XREF_EDIT - global XREF_SELECT - global XREF_POP - global FACE_MAKESUB - global FACE_SELSUB - global FACE_KILLSUB - global IDPROP_KILL - global IDPROP_COPY - global SCENE_UPDATE - global DFROMACT - global FIXCOL - - global CLIGHT_MAKE - global xrefprefix - global xrefstack - global vofsstack - global vquatstack - global prop_w - global prop_h - global evcode - - state = update_state() - - width = prop_w - height = prop_h - origx = x - origy = y - - #draw Xref tools - y = y-20 - XREF_PREFIX = Blender.Draw.String("XRef Name:",evcode["XREF_PREFIX"],x,y,width,20,xrefprefix,18,"Xref prefix name, Actual name is generated from this") - y = y-20 - XREF_MAKE = Blender.Draw.PushButton("Make XRef",evcode["XREF_MAKE"],x,y,width,20,"Make External Reference") - y = y-20 - XREF_EDIT = Blender.Draw.PushButton("Edit XRef",evcode["XREF_EDIT"],x,y,width,20,"Edit External Reference") - y = y-20 - XREF_SELECT = Blender.Draw.PushButton("Select XRefs",evcode["XREF_SELECT"],x,y,width,20,"Select External References") - y = y - 20 - XREF_POP = Blender.Draw.PushButton("Return to previous scene",evcode["XREF_POP"],x,y,width,20,"Go up one level in xref hierarchy") - - #Draw facetools - y = y-20 - FACE_MAKESUB = Blender.Draw.PushButton("Make Subfaces",evcode["FACE_MAKESUB"],x,y,width,20,"Make subfaces") - y = y-20 - FACE_SELSUB = Blender.Draw.PushButton("Select Subfaces",evcode["FACE_SELSUB"],x,y,width,20,"Select subfaces") - y = y-20 - FACE_KILLSUB = Blender.Draw.PushButton("Kill Subfaces",evcode["FACE_KILLSUB"],x,y,width,20,"Kill subfaces") - - #Draw ID Property tools - y = y - 20 - IDPROP_KILL = Blender.Draw.PushButton("Delete ID props",evcode["IDPROP_KILL"],x,y,width,20,"Delete ID props") - y = y - 20 - IDPROP_COPY = Blender.Draw.PushButton("Copy to selected",evcode["IDPROP_COPY"],x,y,width,20, "Copy from active to all selected") - - y= y - 20 - CLIGHT_MAKE = Blender.Draw.PushButton("Make Light Point", evcode["CLIGHT_MAKE"],x,y,width,20,"Create inline light points from current mesh") - #General tools - y = y-20 - SCENE_UPDATE = Blender.Draw.PushButton("Update All",evcode["SCENE_UPDATE"],x,y,width,20,"Update all vertex colors") - - y=y-20 - DFROMACT = Blender.Draw.PushButton("Dof from Active", evcode["DFROMACT"],x,y,width,20,"Get Dof origin from active object") - y=y-20 - FIXCOL = Blender.Draw.PushButton("Fix Colors", evcode["FIXCOL"],x,y,width,20,"Fix baked FLT colors of selected meshes") - draw_postcommon(origx, origy,y) - -def gui(): - #draw the propsheet/toolbox. - psheety = 300 - #psheetx = psheety + 10 - draw_propsheet(0,psheety) -Draw.Register(gui,event,but_event) - \ No newline at end of file diff --git a/release/scripts/help_bpy_api.py b/release/scripts/help_bpy_api.py deleted file mode 100644 index e8d77ed8452..00000000000 --- a/release/scripts/help_bpy_api.py +++ /dev/null @@ -1,47 +0,0 @@ -#!BPY -""" -Name: 'Blender/Python Scripting API' -Blender: 248 -Group: 'Help' -Tooltip: 'The Blender Python API reference manual' -""" - -__author__ = "Matt Ebb" -__url__ = ("blender", "blenderartist") -__version__ = "1.0.1" -__bpydoc__ = """\ -This script opens the user's default web browser at http://www.blender.org's -"Blender Python API Reference" page. -""" - -# -------------------------------------------------------------------------- -# Blender/Python Scripting Reference Help Menu Item -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -try: import webbrowser -except: webbrowser = None - -if webbrowser: - version = str(int(Blender.Get('version'))) - webbrowser.open('http://www.blender.org/documentation/'+ version +'PythonDoc/') -else: - Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/help_browser.py b/release/scripts/help_browser.py deleted file mode 100644 index c207a12068f..00000000000 --- a/release/scripts/help_browser.py +++ /dev/null @@ -1,814 +0,0 @@ -#!BPY - -""" -Name: 'Scripts Help Browser' -Blender: 234 -Group: 'Help' -Tooltip: 'Show help information about a chosen installed script.' -""" - -__author__ = "Willian P. Germano" -__version__ = "0.3 01/21/09" -__email__ = ('scripts', 'Author, wgermano:ig*com*br') -__url__ = ('blender', 'blenderartists.org') - -__bpydoc__ ="""\ -This script shows help information for scripts registered in the menus. - -Usage: - -- Start Screen: - -To read any script's "user manual" select a script from one of the -available category menus. If the script has help information in the format -expected by this Help Browser, it will be displayed in the Script Help -Screen. Otherwise you'll be offered the possibility of loading the chosen -script's source file in Blender's Text Editor. The programmer(s) may have -written useful comments there for users. - -Hotkeys:
- ESC or Q: [Q]uit - -- Script Help Screen: - -This screen shows the user manual page for the chosen script. If the text -doesn't fit completely on the screen, you can scroll it up or down with -arrow keys or a mouse wheel. There may be link and email buttons that if -clicked should open your default web browser and email client programs for -further information or support. - -Hotkeys:
- ESC: back to Start Screen
- Q: [Q]uit
- S: view script's [S]ource code in Text Editor
- UP, DOWN Arrows and mouse wheel: scroll text up / down -""" - -# $Id$ -# -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- -# Thanks: Brendon Murphy (suggestion) and Kevin Morgan (implementation) -# for the "run" button; Jean-Michel Soler for pointing a parsing error -# with multilines using triple single quotes. - -import Blender -from Blender import sys as bsys, Draw, Window, Registry - -WEBBROWSER = True -try: - import webbrowser -except: - WEBBROWSER = False - -DEFAULT_EMAILS = { - 'scripts': ['Bf-scripts-dev', 'bf-scripts-dev@blender.org'] -} - -DEFAULT_LINKS = { - 'blender': ["blender.org\'s Python forum", "http://www.blender.org/modules.php?op=modload&name=phpBB2&file=viewforum&f=9"] -} - -PADDING = 15 -COLUMNS = 1 -TEXT_WRAP = 100 -WIN_W = WIN_H = 200 -SCROLL_DOWN = 0 - -def screen_was_resized(): - global WIN_W, WIN_H - - w, h = Window.GetAreaSize() - if WIN_W != w or WIN_H != h: - WIN_W = w - WIN_H = h - return True - return False - -def fit_on_screen(): - global TEXT_WRAP, PADDING, WIN_W, WIN_H, COLUMNS - - COLUMNS = 1 - WIN_W, WIN_H = Window.GetAreaSize() - TEXT_WRAP = int((WIN_W - PADDING) / 6) - if TEXT_WRAP < 40: - TEXT_WRAP = 40 - elif TEXT_WRAP > 100: - if TEXT_WRAP > 110: - COLUMNS = 2 - TEXT_WRAP /= 2 - else: TEXT_WRAP = 100 - -def cut_point(text, length): - "Returns position of the last space found before 'length' chars" - l = length - c = text[l] - while c != ' ': - l -= 1 - if l == 0: return length # no space found - c = text[l] - return l - -def text_wrap(text, length = None): - global TEXT_WRAP - - wrapped = [] - lines = text.split('
') - llen = len(lines) - if llen > 1: - if lines[-1] == '': llen -= 1 - for i in range(llen - 1): - lines[i] = lines[i].rstrip() + '
' - lines[llen-1] = lines[llen-1].rstrip() - - if not length: length = TEXT_WRAP - - for l in lines: - while len(l) > length: - cpt = cut_point(l, length) - line, l = l[:cpt], l[cpt + 1:] - wrapped.append(line) - wrapped.append(l) - return wrapped - -def load_script_text(script): - global PATHS, SCRIPT_INFO - - if script.userdir: - path = PATHS['uscripts'] - else: - path = PATHS['scripts'] - - fname = bsys.join(path, script.fname) - - source = Blender.Text.Load(fname) - if source: - Draw.PupMenu("File loaded%%t|Please check the file \"%s\" in the Text Editor window" % source.name) - - -# for theme colors: -def float_colors(cols): - return map(lambda x: x / 255.0, cols) - -# globals - -SCRIPT_INFO = None - -PATHS = { - 'home': Blender.Get('homedir'), - 'scripts': Blender.Get('scriptsdir'), - 'uscripts': Blender.Get('uscriptsdir') -} - -if not PATHS['home']: - errmsg = """ -Can't find Blender's home dir and so can't find the -Bpymenus file automatically stored inside it, which -is needed by this script. Please run the -Help -> System -> System Information script to get -information about how to fix this. -""" - raise SystemError, errmsg - -BPYMENUS_FILE = bsys.join(PATHS['home'], 'Bpymenus') - -f = file(BPYMENUS_FILE, 'r') -lines = f.readlines() -f.close() - -AllGroups = [] - -class Script: - - def __init__(self, data): - self.name = data[0] - self.version = data[1] - self.fname = data[2] - self.userdir = data[3] - self.tip = data[4] - -# End of class Script - - -class Group: - - def __init__(self, name): - self.name = name - self.scripts = [] - - def add_script(self, script): - self.scripts.append(script) - - def get_name(self): - return self.name - - def get_scripts(self): - return self.scripts - -# End of class Group - - -class BPy_Info: - - def __init__(self, script, dict): - - self.script = script - - self.d = dict - - self.header = [] - self.len_header = 0 - self.content = [] - self.len_content = 0 - self.spaces = 0 - self.fix_urls() - self.make_header() - self.wrap_lines() - - def make_header(self): - - sc = self.script - d = self.d - - header = self.header - - title = "Script: %s" % sc.name - version = "Version: %s for Blender %1.2f or newer" % (d['__version__'], - sc.version / 100.0) - - if len(d['__author__']) == 1: - asuffix = ':' - else: asuffix = 's:' - - authors = "%s%s %s" % ("Author", asuffix, ", ".join(d['__author__'])) - - header.append(title) - header.append(version) - header.append(authors) - self.len_header = len(header) - - - def fix_urls(self): - - emails = self.d['__email__'] - fixed = [] - for a in emails: - if a in DEFAULT_EMAILS.keys(): - fixed.append(DEFAULT_EMAILS[a]) - else: - a = a.replace('*','.').replace(':','@') - ltmp = a.split(',') - if len(ltmp) != 2: - ltmp = [ltmp[0], ltmp[0]] - fixed.append(ltmp) - - self.d['__email__'] = fixed - - links = self.d['__url__'] - fixed = [] - for a in links: - if a in DEFAULT_LINKS.keys(): - fixed.append(DEFAULT_LINKS[a]) - else: - ltmp = a.split(',') - if len(ltmp) != 2: - ltmp = [ltmp[0], ltmp[0]] - fixed.append([ltmp[0].strip(), ltmp[1].strip()]) - - self.d['__url__'] = fixed - - - def wrap_lines(self, reset = 0): - - lines = self.d['__bpydoc__'].split('\n') - self.content = [] - newlines = [] - newline = [] - - if reset: - self.len_content = 0 - self.spaces = 0 - - for l in lines: - if l == '' and newline: - newlines.append(newline) - newline = [] - newlines.append('') - else: newline.append(l) - if newline: newlines.append(newline) - - for lst in newlines: - wrapped = text_wrap(" ".join(lst)) - for l in wrapped: - self.content.append(l) - if l: self.len_content += 1 - else: self.spaces += 1 - - if not self.content[-1]: - self.len_content -= 1 - - -# End of class BPy_Info - -def parse_pyobj_close(closetag, lines, i): - i += 1 - l = lines[i] - while l.find(closetag) < 0: - i += 1 - l = "%s%s" % (l, lines[i]) - return [l, i] - -def parse_pyobj(var, lines, i): - "Bad code, was in a hurry for release" - - l = lines[i].replace(var, '').replace('=','',1).strip() - - i0 = i - 1 - - if l[0] == '"': - if l[1:3] == '""': # """ - if l.find('"""', 3) < 0: # multiline - l2, i = parse_pyobj_close('"""', lines, i) - if l[-1] == '\\': l = l[:-1] - l = "%s%s" % (l, l2) - elif l[-1] == '"' and l[-2] != '\\': # single line: "..." - pass - else: - l = "ERROR" - - elif l[0] == "'": - if l[1:3] == "''": # ''' - if l.find("'''", 3) < 0: # multiline - l2, i = parse_pyobj_close("'''", lines, i) - if l[-1] == '\\': l = l[:-1] - l = "%s%s" % (l, l2) - elif l[-1] == '\\': - l2, i = parse_pyobj_close("'", lines, i) - l = "%s%s" % (l, l2) - elif l[-1] == "'" and l[-2] != '\\': # single line: '...' - pass - else: - l = "ERROR" - - elif l[0] == '(': - if l[-1] != ')': - l2, i = parse_pyobj_close(')', lines, i) - l = "%s%s" % (l, l2) - - elif l[0] == '[': - if l[-1] != ']': - l2, i = parse_pyobj_close(']', lines, i) - l = "%s%s" % (l, l2) - - return [l, i - i0] - -# helper functions: - -def parse_help_info(script): - - global PATHS, SCRIPT_INFO - - if script.userdir: - path = PATHS['uscripts'] - else: - path = PATHS['scripts'] - - fname = bsys.join(path, script.fname) - - if not bsys.exists(fname): - Draw.PupMenu('IO Error: couldn\'t find script %s' % fname) - return None - - f = file(fname, 'r') - lines = f.readlines() - f.close() - - # fix line endings: - if lines[0].find('\r'): - unixlines = [] - for l in lines: - unixlines.append(l.replace('\r','')) - lines = unixlines - - llen = len(lines) - has_doc = 0 - - doc_data = { - '__author__': '', - '__version__': '', - '__url__': '', - '__email__': '', - '__bpydoc__': '', - '__doc__': '' - } - - i = 0 - while i < llen: - l = lines[i] - incr = 1 - for k in doc_data.keys(): - if l.find(k, 0, 20) == 0: - value, incr = parse_pyobj(k, lines, i) - exec("doc_data['%s'] = %s" % (k, value)) - has_doc = 1 - break - i += incr - - # fix these to seqs, simplifies coding elsewhere - for w in ['__author__', '__url__', '__email__']: - val = doc_data[w] - if val and type(val) == str: - doc_data[w] = [doc_data[w]] - - if not doc_data['__bpydoc__']: - if doc_data['__doc__']: - doc_data['__bpydoc__'] = doc_data['__doc__'] - - if has_doc: # any data, maybe should confirm at least doc/bpydoc - info = BPy_Info(script, doc_data) - SCRIPT_INFO = info - return True - - else: - return False - - -def parse_script_line(l): - - tip = 'No tooltip' - try: - pieces = l.split("'") - name = pieces[1].replace('...','') - data = pieces[2].strip().split() - version = data[0] - userdir = data[-1] - fname = data[1] - i = 1 - while not fname.endswith('.py'): - i += 1 - fname = '%s %s' % (fname, data[i]) - if len(pieces) > 3: tip = pieces[3] - except: - return None - - return [name, int(version), fname, int(userdir), tip] - - -def parse_bpymenus(lines): - - global AllGroups - - llen = len(lines) - - for i in range(llen): - l = lines[i].strip() - if not l: continue - if l[-1] == '{': - group = Group(l[:-2]) - AllGroups.append(group) - i += 1 - l = lines[i].strip() - while l != '}': - if l[0] != '|': - data = parse_script_line(l) - if data: - script = Script(data) - group.add_script(script) - i += 1 - l = lines[i].strip() - -# AllGroups.reverse() - - -def create_group_menus(): - - global AllGroups - menus = [] - - for group in AllGroups: - - name = group.get_name() - menu = [] - scripts = group.get_scripts() - for s in scripts: menu.append(s.name) - menu = "|".join(menu) - menu = "%s%%t|%s" % (name, menu) - menus.append([name, menu]) - - return menus - - -# Collecting data: -fit_on_screen() -parse_bpymenus(lines) -GROUP_MENUS = create_group_menus() - - -# GUI: - -from Blender import BGL -from Blender.Window import Theme - -# globals: - -START_SCREEN = 0 -SCRIPT_SCREEN = 1 - -SCREEN = START_SCREEN - -# gui buttons: -len_gmenus = len(GROUP_MENUS) - -BUT_GMENU = range(len_gmenus) -for i in range(len_gmenus): - BUT_GMENU[i] = Draw.Create(0) - -# events: -BEVT_LINK = None # range(len(SCRIPT_INFO.links)) -BEVT_EMAIL = None # range(len(SCRIPT_INFO.emails)) -BEVT_GMENU = range(100, len_gmenus + 100) -BEVT_VIEWSOURCE = 1 -BEVT_EXIT = 2 -BEVT_BACK = 3 -BEVT_EXEC = 4 # Executes Script - -# gui callbacks: - -def gui(): # drawing the screen - - global SCREEN, START_SCREEN, SCRIPT_SCREEN - global SCRIPT_INFO, AllGroups, GROUP_MENUS - global BEVT_EMAIL, BEVT_LINK - global BEVT_VIEWSOURCE, BEVT_EXIT, BEVT_BACK, BEVT_GMENU, BUT_GMENU, BEVT_EXEC - global PADDING, WIN_W, WIN_H, SCROLL_DOWN, COLUMNS, FMODE - - theme = Theme.Get()[0] - tui = theme.get('ui') - ttxt = theme.get('text') - - COL_BG = float_colors(ttxt.back) - COL_TXT = ttxt.text - COL_TXTHI = ttxt.text_hi - - BGL.glClearColor(COL_BG[0],COL_BG[1],COL_BG[2],COL_BG[3]) - BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) - BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2]) - - resize = screen_was_resized() - if resize: fit_on_screen() - - if SCREEN == START_SCREEN: - x = PADDING - bw = 85 - bh = 25 - hincr = 50 - - butcolumns = (WIN_W - 2*x)/ bw - if butcolumns < 2: butcolumns = 2 - elif butcolumns > 7: butcolumns = 7 - - len_gm = len(GROUP_MENUS) - butlines = len_gm / butcolumns - if len_gm % butcolumns: butlines += 1 - - h = hincr * butlines + 20 - y = h + bh - - BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2]) - BGL.glRasterPos2i(x, y) - Draw.Text('Scripts Help Browser') - - y -= bh - - BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2]) - - i = 0 - j = 0 - for group_menu in GROUP_MENUS: - BGL.glRasterPos2i(x, y) - Draw.Text(group_menu[0]+':') - BUT_GMENU[j] = Draw.Menu(group_menu[1], BEVT_GMENU[j], - x, y-bh-5, bw, bh, 0, - 'Choose a script to read its help information') - if i == butcolumns - 1: - x = PADDING - i = 0 - y -= hincr - else: - i += 1 - x += bw + 3 - j += 1 - - x = PADDING - y = 10 - BGL.glRasterPos2i(x, y) - Draw.Text('Select script for its help. Press Q or ESC to leave.') - - elif SCREEN == SCRIPT_SCREEN: - if SCRIPT_INFO: - - if resize: - SCRIPT_INFO.wrap_lines(1) - SCROLL_DOWN = 0 - - h = 18 * SCRIPT_INFO.len_content + 12 * SCRIPT_INFO.spaces - x = PADDING - y = WIN_H - bw = 38 - bh = 16 - - BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2]) - for line in SCRIPT_INFO.header: - y -= 18 - BGL.glRasterPos2i(x, y) - size = Draw.Text(line) - - for line in text_wrap('Tooltip: %s' % SCRIPT_INFO.script.tip): - y -= 18 - BGL.glRasterPos2i(x, y) - size = Draw.Text(line) - - i = 0 - y -= 28 - for data in SCRIPT_INFO.d['__url__']: - Draw.PushButton('link %d' % (i + 1), BEVT_LINK[i], - x + i*bw, y, bw, bh, data[0]) - i += 1 - y -= bh + 1 - - i = 0 - for data in SCRIPT_INFO.d['__email__']: - Draw.PushButton('email', BEVT_EMAIL[i], x + i*bw, y, bw, bh, data[0]) - i += 1 - y -= 18 - - y0 = y - BGL.glColor3ub(COL_TXT[0],COL_TXT[1], COL_TXT[2]) - for line in SCRIPT_INFO.content[SCROLL_DOWN:]: - if line: - line = line.replace('
', '') - BGL.glRasterPos2i(x, y) - Draw.Text(line) - y -= 18 - else: y -= 12 - if y < PADDING + 20: # reached end, either stop or go to 2nd column - if COLUMNS == 1: break - elif x == PADDING: # make sure we're still in column 1 - x = 6*TEXT_WRAP + PADDING / 2 - y = y0 - - x = PADDING - Draw.PushButton('source', BEVT_VIEWSOURCE, x, 17, 45, bh, - 'View this script\'s source code in the Text Editor (hotkey: S)') - Draw.PushButton('exit', BEVT_EXIT, x + 45, 17, 45, bh, - 'Exit from Scripts Help Browser (hotkey: Q)') - if not FMODE: - Draw.PushButton('back', BEVT_BACK, x + 2*45, 17, 45, bh, - 'Back to scripts selection screen (hotkey: ESC)') - Draw.PushButton('run script', BEVT_EXEC, x + 3*45, 17, 60, bh, 'Run this script') - - BGL.glColor3ub(COL_TXTHI[0],COL_TXTHI[1], COL_TXTHI[2]) - BGL.glRasterPos2i(x, 5) - Draw.Text('use the arrow keys or the mouse wheel to scroll text', 'small') - -def fit_scroll(): - global SCROLL_DOWN - if not SCRIPT_INFO: - SCROLL_DOWN = 0 - return - max = SCRIPT_INFO.len_content + SCRIPT_INFO.spaces - 1 - if SCROLL_DOWN > max: SCROLL_DOWN = max - if SCROLL_DOWN < 0: SCROLL_DOWN = 0 - - -def event(evt, val): # input events - - global SCREEN, START_SCREEN, SCRIPT_SCREEN - global SCROLL_DOWN, FMODE - - if not val: return - - if evt == Draw.ESCKEY: - if SCREEN == START_SCREEN or FMODE: Draw.Exit() - else: - SCREEN = START_SCREEN - SCROLL_DOWN = 0 - Draw.Redraw() - return - elif evt == Draw.QKEY: - Draw.Exit() - return - elif evt in [Draw.DOWNARROWKEY, Draw.WHEELDOWNMOUSE] and SCREEN == SCRIPT_SCREEN: - SCROLL_DOWN += 1 - fit_scroll() - Draw.Redraw() - return - elif evt in [Draw.UPARROWKEY, Draw.WHEELUPMOUSE] and SCREEN == SCRIPT_SCREEN: - SCROLL_DOWN -= 1 - fit_scroll() - Draw.Redraw() - return - elif evt == Draw.SKEY: - if SCREEN == SCRIPT_SCREEN and SCRIPT_INFO: - load_script_text(SCRIPT_INFO.script) - return - -def button_event(evt): # gui button events - - global SCREEN, START_SCREEN, SCRIPT_SCREEN - global BEVT_LINK, BEVT_EMAIL, BEVT_GMENU, BUT_GMENU, SCRIPT_INFO - global SCROLL_DOWN, FMODE - - if evt >= 100: # group menus - for i in range(len(BUT_GMENU)): - if evt == BEVT_GMENU[i]: - group = AllGroups[i] - index = BUT_GMENU[i].val - 1 - if index < 0: return # user didn't pick a menu entry - script = group.get_scripts()[BUT_GMENU[i].val - 1] - if parse_help_info(script): - SCREEN = SCRIPT_SCREEN - BEVT_LINK = range(20, len(SCRIPT_INFO.d['__url__']) + 20) - BEVT_EMAIL = range(50, len(SCRIPT_INFO.d['__email__']) + 50) - Draw.Redraw() - else: - res = Draw.PupMenu("No help available%t|View Source|Cancel") - if res == 1: - load_script_text(script) - elif evt >= 20: - if not WEBBROWSER: - Draw.PupMenu('Missing standard Python module%t|You need module "webbrowser" to access the web') - return - - if evt >= 50: # script screen email buttons - email = SCRIPT_INFO.d['__email__'][evt - 50][1] - webbrowser.open("mailto:%s" % email) - else: # >= 20: script screen link buttons - link = SCRIPT_INFO.d['__url__'][evt - 20][1] - webbrowser.open(link) - elif evt == BEVT_VIEWSOURCE: - if SCREEN == SCRIPT_SCREEN: load_script_text(SCRIPT_INFO.script) - elif evt == BEVT_EXIT: - Draw.Exit() - return - elif evt == BEVT_BACK: - if SCREEN == SCRIPT_SCREEN and not FMODE: - SCREEN = START_SCREEN - SCRIPT_INFO = None - SCROLL_DOWN = 0 - Draw.Redraw() - elif evt == BEVT_EXEC: # Execute script - exec_line = '' - if SCRIPT_INFO.script.userdir: - exec_line = bsys.join(Blender.Get('uscriptsdir'), SCRIPT_INFO.script.fname) - else: - exec_line = bsys.join(Blender.Get('scriptsdir'), SCRIPT_INFO.script.fname) - - Blender.Run(exec_line) - -keepon = True -FMODE = False # called by Blender.ShowHelp(name) API function ? - -KEYNAME = '__help_browser' -rd = Registry.GetKey(KEYNAME) -if rd: - rdscript = rd['script'] - keepon = False - Registry.RemoveKey(KEYNAME) - for group in AllGroups: - for script in group.get_scripts(): - if rdscript == script.fname: - parseit = parse_help_info(script) - if parseit == True: - keepon = True - SCREEN = SCRIPT_SCREEN - BEVT_LINK = range(20, len(SCRIPT_INFO.d['__url__']) + 20) - BEVT_EMAIL = range(50, len(SCRIPT_INFO.d['__email__']) + 50) - FMODE = True - elif parseit == False: - Draw.PupMenu("ERROR: script doesn't have proper help data") - break - -if not keepon: - Draw.PupMenu("ERROR: couldn't find script") -else: - Draw.Register(gui, event, button_event) diff --git a/release/scripts/hotkeys.py b/release/scripts/hotkeys.py deleted file mode 100644 index 187cba964bc..00000000000 --- a/release/scripts/hotkeys.py +++ /dev/null @@ -1,944 +0,0 @@ -#!BPY -# coding: utf-8 -""" Registration info for Blender menus: -Name: 'HotKey and MouseAction Reference' -Blender: 242 -Group: 'Help' -Tip: 'All the hotkeys/short keys' -""" - -__author__ = "Jean-Michel Soler (jms)" -__url__ = ("blender", "blenderartist", -"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm", -"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "21/01/2007" - -__bpydoc__ = """\ -This script is a reference about all hotkeys and mouse actions in Blender. - -Usage: - -Open the script from the Help menu and select group of keys to browse. - -Notes:
- Additional entries in the database (c) 2004 by Bart. - Additional entries in the database for blender 2.37 --> 2.43 (c) 2003-2007/01 by jms. - -""" - -#------------------------ -# Hotkeys script -# (c) jm soler (2003-->01/2007) -# ----------------------- -# Page officielle : -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm -# Communiquer les problemes et les erreurs sur: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#--------------------------------------------- -# ce script est proposé sous licence GPL pour etre associe -# a la distribution de Blender 2.33 et suivant -# -------------------------------------------------------------------------- -# this script is released under GPL licence -# for the Blender 2.33 scripts package -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) 2003, 2004: Jean-Michel Soler -# Additionnal entries in the original data base (c) 2004 by Bart (bart@neeneenee.de) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender.Draw import * -from Blender.BGL import * - -# INTERNATIONAL={0:'English','1':'French'} -# LANGUAGE=0 - -hotkeys={ -'Search ':[['', '']], -'Specials 1 ':[ -[',', 'Set Bounding Box rotation scaling pivot'], -['Ctrl-,', 'Set Median Point rotation scaling pivot'], -['.', 'Set 3D cursor as rotation scaling pivot'], -['.', 'Outliner : to get the current active data in center of view'], -['Ctrl-.', 'Set Individual Object Centers as rotation scaling pivot'], -['~', 'Display all layers (German keys: ö,french keyboard: ù)'], -['Shift-~', 'Display all/previous layers (German keys: Shift-ö, french keyboard: shift-ù)'], -['ENTER', 'Outliner : to open a subtree, works on entire item line. '], -['HOME', 'Outliner : to show the entire Object hierarchy. '], -['SHIFT+BACKSPACE',' Text edit mode: Clear text '], -['SPACE', 'Popup menu'], -['SPACE', '3D View: camera selected'], -['Ctrl-SPACE', 'Manipulator (transform widget) Menu'], -['TAB', 'Enter/exit Edit Mode'], -['TAB', 'Edit Mode and Numerical Edit (see N key) : move to next input value'], -['TAB', 'Sequencer: Edit meta strip'], -['TAB', 'IPO: Edit selected'], -['TAB', 'Text Editor : indent'], -['TAB', 'NODE window : Edit group'], #243 -['Shift-TAB', 'Text Editor : unindent'], -['Shift-TAB', 'Edit Mode: Toggle snaping'], -['Ctrl-TAB', 'ARMATURE : Enter/exit Pose Mode'], -['Ctrl-TAB','MESH : all views, enter exit weight paint mode.'], -['Shift-TAB', 'Edit Mode : Enter Object Mode'], -['Ctrl-Open menu /', ''], -['Ctrl-Load Image', 'Opens a thumbnail browser instead of file browser for images'], -['.', '...'] -], - -'Mouse ':[ -['Actions:', ''], -['LMB', '3D View: Set 3D Cursor'], -['LMB', '3D View: camera selected'], -['LMB drag', 'Border select circle: add to selection'], -['LMB hold down', 'Popup menu'], -['LMB hold down drag', 'Gesture'], -['Ctrl-LMB', 'IPO: Add key'], -['Ctrl-LMB', '3D View: OBJECT or EDIT mode, select with the Lasso tool'], -['Ctrl-LMB', '3D View: ARMATURE EDIT mode, add a new bone to the selected end '], -['Shift-LMB','MANIPULATOR (transform widget): select the axe to remove in the current'], -['Shift-LMB','MANIPULATOR transformation ( if there is a problem with small step adjustment'], -['Shift-LMB','MANIPULATOR first select the axe or axes with LBM alone)'], -['Shift-LMB', 'Outliner : Hold Shift while clicking on a triangle arrow to open/close the subtree below'], -['MMB', 'Rotate'], -['Ctrl-MMB', 'Zoom view'], -['Ctrl-LMB', 'Outliner : Hold CTRL while clicking on a name allows you to edit a name.'], -['Ctrl-LMB', 'Outliner : This works for all visualized data, including bones or vertex groups,'], -['Ctrl-LMB', 'Outliner : but not for \'nameless\' items that draw the links to Hooks, Deform '], -['Ctrl-LMB', 'Outliner : Groups or Constraints.'], -['Shift-MMB', 'Move view'], -['RMB', 'Select'], -['RMB drag', 'Border select circle: subtract from selection'], -['RMB hold down', 'Popup menu'], -['Alt-RMB', 'Object Mode :Select but in a displayed list of objects located under the mouse cursor'], -['Alt-RMB', 'Edit Mode: Select EDGES LOOP '], -['Alt-Ctrl-RMB', 'Edit Mode: Select FACES LOOP'], -['Alt-Ctrl-RMB', 'UV Image Editor: Select face'], -['Shift-RMB', 'Add/subtract to/from selection'], -['Wheel', 'Zoom view'], -['Transformations:', ''], -['Drag+Ctrl', 'Step adjustment'], -['Drag+Ctrl-Shift', 'Small step adjustment (Transform Widget : first select the axe or axes with LBM alone)'], -['Drag+Shift', 'Fine adjustment (Transform Widget : first select the axe or axes with LBM alone)'], -['LMB', 'Confirm transformation'], -['MMB', 'Toggle optional transform feature'], -['RMB', 'Abort transformation'], -['LMB', 'Grease Pencil: when "Draw Mode On", draw new stroke'], -['RMB', 'Grease Pencil: when "Draw Mode On", eraser tool for stroke segments'], -['Shift-LMB', 'Grease Pencil: draw new stroke'], -['Alt-RMB', 'Grease Pencil: eraser tool for stroke segments'], -['.', '...'] -], - -'F-Keys ':[ -['F1', 'Open File'], -['Shift-F1', 'Library Data Select'], -['F2', 'Save File'], -['Shift-F2', 'Export DXF'], -['Ctrl-F2', 'Save/export in vrml 1.0 format' ], -['F3', 'Save image'], -['Ctrl-F3', 'Save image : dump 3d view'], -['Ctrl-Shift-F3', 'Save image : dump screen'], -['F4', 'Logic Window (may change)'], -['Shift-F4', 'Object manager Data Select '], -['F5', 'Material Window'], -['Shift-F5', '3D Window'], -['F6', 'Texture Window'], -['Shift-F6', 'IPO Window'], -['F7', 'Object Window'], -['Shift-F7', 'Buttons Window'], -['F8', 'World Window'], -['Shift-F8', 'Video Sequencer Window'], -['F9', 'Edit Mode Window'], -['Shift-F9', 'OOP Window'], -['Alt-Shift-F9', 'OutLiner Window'], -['F10', 'Render Window'], -['Shift-F10', 'UV Image Editor'], -['F11', 'Recall the last rendered image'], -['Shift-F11', 'Text Editor'], -['ctrl-F11', 'replay the last rendered animation'], -['F12', 'Render current Scene'], -['Ctrl-F12', 'Render animation'], -['Ctrl-Shift-F12', 'NLA Editor'], -['Shift-F12', 'Action Editor'], -['Shift-F12', 'Action Editor'], -['.', '...'] -], - -'Numbers ':[ -['1..2..0-=', 'Show layer 1..2..12'], -['1..2..0-=', 'Edit Mode with Size, Grab, rotate tools : enter value'], -['Alt-1..2..0', 'Show layer 11..12..20'], -['Shift-1..2..0', 'Toggle layer 1..2..12'], -['Ctrl-1..4', 'Object/Edit Mode : change subsurf level to the selected value'], -['Shift-ALT-...', 'Toggle layer 11..12..20'], -['Crtl-Shift-ALT-3', 'Edit Mode & Face Mode : Triangle faces'], -['Crtl-Shift-ALT-4', 'Edit Mode & Face Mode : Quad faces'], -['Crtl-Shift-ALT-5', 'Edit Mode & Face Mode : Non quad or triangle faces'], -['.', '...'] -], - -'Numpad ':[ -['Numpad DEL', 'Zoom on object'], -['Numpad /', 'Local view on object (hide others)'], -['Numpad *', 'Rotate view to objects local axes'], -['Numpad +', 'Zoom in (works everywhere)'], -['Numpad -', 'OutLiner window, Collapse one level of the hierarchy'], -['Alt-Numpad +', 'Proportional vertex Edit Mode: Increase range of influence'], -['Ctrl-Numpad +', 'Edit Mode: Select More vertices'], -['Numpad -', 'Zoom out (works everywhere)'], -['Numpad +', 'OutLiner window, Expand one level of the hierarchy'], -['Alt-Numpad -', 'Proportional vertex Edit Mode: Decrease range of influence'], -['Ctrl-Numpad +', 'Edit Mode: Select Less vertices'], -['Numpad 0', 'Set Camera view'], -['Ctrl-Numpad 0', 'Set active object as camera'], -['Alt-Numbad 0', 'Restore old camera'], -['Ctrl-Alt-Numpad 0', 'Align active camera to view'], -['Numpad 1', 'Front view'], -['Ctrl-Numpad 1', 'Back view'], -['Numpad 3', 'Right view'], -['Ctrl-Numpad 3', 'Left view'], -['Numpad 7', 'Top view'], -['Ctrl-Numpad 7', 'Bottom view '], -['Numpad 5', 'Toggle orthogonal/perspective view'], -['Numpad 9', 'Redraw view'], -['Numpad 4', 'Rotate view left'], -['ctrl-Shift-Numpad 4', 'Previous Screen'], -['Numpad 6', 'Rotate view right'], -['ctrl-Shift-Numpad 6', 'Next Screen'], -['Numpad 8', 'Rotate view up'], -['Numpad 2', 'Rotate view down'], -['.', '...'] -], - -'Arrows ':[ -['Home/Pos1', 'View all',''], -['Home', 'OutLiner Windows, Show hierarchy'], -['PgUp', 'Edit Mode and Proportionnal Editing Tools, increase influence'], -['PgUp', 'Strip Editor, Move Down'], -['PgUp', 'TimeLine: Jump to next marker'], -['PgUp', 'IPO: Select next keyframe'], -['Ctrl-PgUp', 'IPO: Select and jump to next keyframe'], -['Ctrl-PgUn', 'TimeLine: Jump to next key'], -['PgDn', 'Edit Mode and Proportionnal Editing Tools, decrease influence'], -['PgDn', 'Strip Editor, Move Up'], -['PgDn', 'TimeLine: Jump to prev marker'], -['PgDn', 'IPO: Select previous keyframe'], -['Ctrl-PgDn', 'IPO: Select and jump to previous keyframe'], -['Ctrl-PgDn', 'TimeLine: Jump to prev key'], -['Left', 'One frame backwards'], -['Right', 'One frame forwards'], -['Down', '10 frames backwards'], -['Up', '10 frames forwards'], -['Alt-Down', 'Blender in Window mode'], -['Alt-Up', 'Blender in Fullscreen mode'], -['Ctrl-Left', 'Previous screen'], -['Ctrl-Right', 'Next screen'], -['Ctrl-Down', 'Maximize window toggle'], -['Ctrl-Up', 'Maximize window toggle'], -['Shift-Arrow', 'Toggle first frame/ last frame'], -['.', '...'] -], - -'Letters ':[ -{ -"A":[ -['A', 'Select all/Deselect all'], -['A', 'Outliner : Select all/Deselect all'], -['A', 'Ipo Editor : Object mode, Select all/Deselect all displayed Curves'], #243 -['A', 'Ipo Editor : Edit mode, Select all/Deselect all vertices'], #243 -['A', 'Render window (F12) : Display alpha plane'], -['Alt-A', 'Play animation in current window'], -['Ctrl-A', 'Apply objects size/rotation to object data'], -['Ctrl-A', 'Text Editor: Select all'], -['Ctrl-ALT-A', '3D-View: Armature Edit mode, align selected bones to active bone'], -['Shift-A', 'Sequencer: Add menu'], -['Shift-A', '3D-View: Add menu'], -['Shift-A', 'Sculpt Mode: Keep the brush center anchored to the initial location'], -['Shift-ALT-A', 'Play animation in all windows'], -['Shift-CTRL-A', 'Apply lattice / Make dupliverts real'], -['Shift-CTRL-A', 'Apply Deform '], -['.', '...'] -], - -"B":[ -['B', 'Border select'], -['BB', 'Circle select'], -['Alt-B', 'Object Mode: Select visible view section in 3D space'], -['Shift-B', 'Set render border (in active camera view)'], -['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake (on an image in the uv editor window) the selected Meshes'], #243 -['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Full render of selected Meshes'], #243 -['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Ambient Occlusion of selected Meshes'], #243 -['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Normals of the selected Meshes'], #243 -['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Texture Only of selected Meshes'], #243 -['.', '...'] -], - -"C":[ -['C', 'Center view on cursor'], -['C', 'UV Image Editor: Active Face Select toggle'], -['C', 'Sequencer: Change content of the strip '], #243 -['C', 'IPO: Snap current frame to selected key'], -['C', 'TimeLine: Center View'], -['C', 'File Selector : Copy file'], -['C', 'NODE window : Show cyclic referencies'], #243 -['Alt-C', 'Object Mode: Convert menu'], -['Alt-C', 'Text Editor: Copy '], -['Ctrl-Alt-C', 'Object Mode : Add Constraint'], -['Ctrl-Shift-C', 'Text Editor: Copy selection to clipboard'], -['Ctrl-C', 'Copy menu (Copy properties of active to selected objects)'], -['Ctrl-C', 'UV Image Editor: Stick UVs to mesh vertex'], -['Ctrl-C','ARMATURE : posemode, Copy pose attributes'], -['Ctrl-Alt-C',' ARMATURE : posemode, add constraint to new empty object.'], -['Shift-C', 'Center and zoom view on selected objects'], -['Shift-C', 'UV Image Editor: Stick local UVs to mesh vertex'], -['.', '...'] -], - -"D":[ -['D', 'Set 3d draw mode'], -['Alt-D', 'Object Mode: Create new instance of object'], -['Ctrl-D', 'Display alpha of image texture as wire'], -['Ctrl-D', 'Text Editor : uncomment'], -['Shift-D', 'Create full copy of object'], -['Shift-D', 'NODE window : duplicate'], #243 -['CTRL-SHIFT-D', 'NLA editor : Duplicate markers'], -['CTRL-SHIFT-D', 'Action editor : Duplicate markers'], -['CTRL-SHIFT-D', 'IPO editor : Duplicate markers'], -['.', '...'] -], - -"E":[ -['E', 'Edit Mode: Extrude'], -['E', 'UV Image Editor: LSCM Unwrap'], -['E', 'TimeLine: Set current frame as End '], -['E', 'NODE window : Execute composite'], #243 -['ER', 'Edit Mode: Extrude Rotate'], -['ES', 'Edit Mode: Extrude Scale'], -['ESX', 'Edit Mode: Extrude Scale X axis'], -['ESY', 'Edit Mode: Extrude Scale Y axis'], -['ESZ', 'Edit Mode: Extrude Scale Z axis'], -['EX', 'Edit Mode: Extrude along X axis'], -['EY', 'Edit Mode: Extrude along Y axis'], -['EZ', 'Edit Mode: Extrude along Z axis'], -['Alt-E', 'Edit Mode: exit Edit Mode'], -['Ctrl-E', 'Edit Mode: Edge Specials menu'], -['Ctrl-E', 'Edit Mode: Edge Specials menu, Mark seams'], -['Ctrl-E', 'Edit Mode: Edge Specials menu, Clear seams'], -['Ctrl-E', 'Edit Mode: Edge Specials menu, Rotate Edge CW'], -['Ctrl-E', 'Edit Mode: Edge Specials menu, Rotate Edge CCW'], -['Ctrl-E', 'Edit Mode: Edge Specials menu, Loop Cut'], -['Ctrl-E', 'Edit Mode: Edge Specials menu, Edge Slide'], -['Shift-E', 'Edit Mode: SubSurf Edge Sharpness'], -['.', '...'] -], - -"F":[ -['F', 'Edit mode: Make edge/face'], -['F', 'Sequencer: Set Filter Y'], -['F', 'Object Mode: UV/Face Select mode'], -['Alt-F', 'Edit Mode: Beautify fill'], -['Alt-F,','Text editor : find again '], -['Alt-Ctrl-F,','Text editor : find '], -['Ctrl-F', 'Object Mode: Sort faces in Z direction'], -['Ctrl-F', 'Edit Mode: Flip triangle edges'], -['Shift-F', 'Edit Mode: Fill with triangles'], -['Shift-F', 'Object Mode: fly mode (see header for fly mode keys)'], -['.', '...'] -], - -"G":[ -['G', 'Grab (move)'], -['G', 'Timeline : Grab (move) Marker'], -['Alt-G', 'Clear location (this does only make sense in Object mode)'], -['Alt-G', 'NODE window : ungroup'], #243 -['Shift-ALT-G', 'Object mode: Remove selected objects from group'], -['Ctrl-G', 'NODE window : group'], #243 -['Ctrl-G', 'Add selected objects to group'], -['Ctrl-G', 'IPO editor, Grab/move marker'], -['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Grab Mode'], -['Shift-G', 'Object mode: Selected Group menu'], -['Shift-G', 'Object mode: Selected Group menu 1, Children'], -['Shift-G', 'Object mode: Selected Group menu 2, Immediate Children'], -['Shift-G', 'Object mode: Selected Group menu 3, Parent'], -['Shift-G', 'Object mode: Selected Group menu 4, Sibling'], -['Shift-G', 'Object mode: Selected Group menu 5, Object of same type'], -['Shift-G', 'Object mode: Selected Group menu 6, Object in same shared layers'], -['Shift-G', 'Object mode: Selected Group menu 7, Objects in same group'], -['.', '...'] -], - -"H":[ -['H', 'Hide selected vertices/faces'], -['H', 'Curves: Set handle type'], -['H', 'Action editor: Handle type aligned'], -['H', 'Action editor: Handle type free'], -['H', 'NODE window : hide/unhide'], #243 -['Alt-H', 'Edit Mode : Show Hidden vertices/faces'], -['Shift-H', 'Curves: Automatic handle calculation'], -['Shift-H', 'Action editor: Handle type auto'], -['Shift-H', 'Edit Mode : Hide deselected vertices/faces'], -['Ctrl-H', 'Edit Mode : Add a hook on selected points or show the hook menu .'], -['.', '...'] -], - -"I":[ -['I', 'Insert Keyframe menu'], -['Alt-I','Delete Keyframe menu'], -['Ctrl-I','Select Inverse'], -['Shift-I','ARMATURE : add IK constraint'], -['Ctrl-Alt-I','ARMATURE : posemode, remove IK constraints.'], -['.', '...'] -], - -"J":[ -['J', 'IPO: Join menu'], -['J', 'Mesh: Join all adjacent triangles to quads'], -['J', 'Render Window: Swap render buffer'], -['Alt-J,','Text editor : Jump '], -['Ctrl-J', 'Join selected objects'], -['Ctrl-J', 'Nurbs: Add segment'], -['Ctrl-J', 'IPO: Join keyframes menu'], -['.', '...'] -], - -"K":[ -['K', '3d Window: Show keyframe positions'], -['K', 'Edit Mode: Loop/Cut menu'], -['K', 'IPO: Show keyframe positions'], -['K', 'Nurbs: Print knots'], -['K', 'VIDEO editor : cut at current frame'], #243 -['Ctrl-K', 'Make skeleton from armature'], -['Shift-K', 'Show and select all keyframes for object'], -['Shift-K', 'Edit Mode: Knife Mode select'], -['Shift-K', 'UV Face Select: Clear vertex colours'], -['Shift-K', 'Vertex Paint: All vertex colours are erased; they are changed to the current drawing colour.'], -['.', '...'] -], - -"L":[ -['L', 'Make local menu'], -['L', 'Edit Mode: Select linked vertices (near mouse pointer)'], -['L', 'NODE window: Select linked from '], #243 -['L', 'OOPS window: Select linked objects'], -['L', 'UV Face Select: Select linked faces'], -['Ctrl-L', 'Make links menu (for instance : to scene...)'], -['Shift-L', 'Select links menu'], -['Shift-L', 'NODE window: Select linked to '], #243 -['Ctrl-L', 'POSELIB: browse poses'], -['Shift-L', 'POSELIB: add/replace pose'], -['Ctrl-Shift-L', 'POSELIB: rename pose'], -['Alt-L', 'POSELIB: remove pose'], -['.', '...'] -], - -"M":[ -['M', 'Object mode : Move object to different layer'], -['M', 'Sequencer: Make meta strip (group) from selected strips'], -['M', 'Edit Mode: Mirros Axis menu'], -['M', 'File Selector: rename file'], -['M', 'Video Sequence Editor : Make Meta strip...'], -['M', 'NLA editor: Add marker'], -['M', 'Action editor: Add marker'], -['M', 'IPO editor: Add marker'], -['M', 'TimeLine: Add marker'], -['Alt-M', 'Edit Mode: Merge vertices menu'], -['Alt-M', 'Video Sequence Editor : Separate Meta strip...'], -['Ctrl-M', 'Object Mode: Mirros Axis menu'], -['Shift-M', 'TimeLine: Name marker'], -['Shift-M', 'IPO editor : Name marker'], -['Shift-M', 'NLA editor : Name marker'], -['Shift-M', 'Actions editor : Name marker'], -['.', '...'] -], - -"N":[ -['N', 'Transform Properties panel'] , -['N', 'OOPS window: Rename object'], -['N', 'VIDEO SEQUENCE editor : display strip properties '], #243 -['Alt-N', 'Text Editor : New text '], -['Ctrl-N', 'Armature: Recalculate bone roll angles'] , -['Ctrl-N', 'Edit Mode: Recalculate normals to outside'] , -['Ctrl-Shift-N', 'Edit Mode: Recalculate normals to inside'], -['.', '...'] -], - -"O":[ -['O', 'Edit Mode/UV Image Editor: Toggle proportional vertex editing'], -['O', 'IPO editor: Clean ipo curves (beware to the thresold needed value)'], #243 -['Alt-O', 'Clear object origin'], -['Alt-O', 'Edit mode, 3dview with prop-edit-mode, enables/disables connected'], -['Alt-O', 'Text Editor : Open file '], -['Ctrl-O', 'Open a panel with the ten most recent projets files'], #243 -['Shift-O', 'Proportional vertex Edit Mode: Toggle smooth/steep falloff'], -['Shift-O', 'Object Mode: Add a subsurf modifier to the selected mesh'], -['Shift-O', 'IPO editor: Smooth ipo curves'], #243 -['.', '...'] -], - -"P":[ -['P', 'Object Mode: Start realtime engine'], -['P', 'Edit mode: Seperate vertices to new object'], -['Shift-P', 'Edit mode: Push-Pull'], -['Shift-P', 'Object mode: Add a preview window in the D window'], -['P', 'UV Image Editor: Pin selected vertices. Pinned vertices will stay in place on the UV editor when executing an LSCM unwrap.'], -['Alt-P', 'Clear parent relationship'], -['Alt-P', 'UV Image Editor: Unpin UVs'], -['Alt-P', 'Text Editor : Run current script '], -['Ctrl-P', 'Make active object parent of selected object'], -['Ctrl-Shift-P', 'Make active object parent of selected object without inverse'], -['Ctrl-P', 'Edit mode: Make active vertex parent of selected object'], -['Ctrl-P', 'ARMATURE : editmode, make bone parent.'], -['Ctrl-Alt-P', 'ARMATURE: edimode, separate bones to new object'], -['.', '...'] -], - -"Q":[['Ctrl-Q', 'Quit'], - ['.', '...'] - ], - -"R":[ -['R', 'FileSelector : remove file'], -['R', 'Rotate'], -['R', 'IPO: Record mouse movement as IPO curve'], -['R', 'UV Face Select: Rotate menu uv coords or vertex colour'], -['R', 'NODE window : read saved render result'], #243 -['R', 'SEQUENCER window : re-assign entries to another strip '], #243 -['RX', 'Rotate around X axis'], -['RXX', "Rotate around object's local X axis"], -['RY', 'Rotate around Y axis'], -['RYY', "Rotate around object's local Y axis"], -['RZ', 'Rotate around Z axis'], -['RZZ', "Rotate around object's local Z axis"], -['Alt-R', 'Clear object rotation'], -['Alt-R', 'Text editor : reopen text.'], -['Ctrl-R', 'Edit Mode: Knife, cut selected edges, accept left mouse/ cancel right mouse'], -['Ctrl-Alt-R', 'MANIPULATOR (transform widget): set in Rotate Mode'], -['Shift-R', 'Edit Mode: select Face Loop'], -['Shift-R', 'Nurbs: Select row'], -['.', '...'] -], - -"S":[ -['S', 'Scale'] , -['S', 'TimeLine: Set Start'], -['SX', 'Flip around X axis'] , -['SY', 'Flip around Y axis'] , -['SZ', 'Flip around Z axis'] , -['SXX', 'Flip around X axis and show axis'] , -['SYY', 'Flip around Y axis and show axis'] , -['SZZ', 'Flip around Z axis and show axis'] , -['Alt-S', 'Edit mode: Shrink/fatten (Scale along vertex normals)'] , -['Alt-S', 'Text Editor : Save the current text to file '], -['Alt-S',' ARMATURE : posemode editmode: Scale envalope.'], -['Ctrl-Shift-S', 'Edit mode: To Sphere'] , -['Ctrl-Alt-Shift-S', 'Edit mode: Shear'] , -['Alt-S', 'Clear object size'] , -['Ctrl-S', 'Edit mode: Shear'] , -['Alt-Shift-S,','Text editor : Select the line '], -['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Size Mode'], -['Shift-S', 'Cursor/Grid snap menu'], -['Shift-S', 'Sculpt Mode: Smooth Stroke.'], -['Shift-S+1', 'VIDEO SEQUENCE editor : jump to the current frame '], -['.', '...'] -], - -"T":[ -['T', 'Adjust texture space'], -['T', 'Edit mode: Flip 3d curve'], -['T', 'IPO: Menu Change IPO type, 1 Constant'], -['T', 'IPO: Menu Change IPO type, 2 Linear'], -['T', 'IPO: Menu Change IPO type, 3 Bezier'], -['T', 'TimeLine: Show second'], -['T', 'VIDEO SEQUENCE editor : toggle between show second andd show frame'], #243 -['Alt-T', 'Clear tracking of object'], -['Ctrl-T', 'Make selected object track active object'], -['Ctrl-T', 'Edit Mode: Convert to triangles'], -['Ctrl-Alt-T', 'Benchmark'], -['.', '...'] -], - -"U":[ -['U', 'Make single user menu (for import completly linked object to another scene for instance) '] , -['U', '3D View: Make Single user Menu'] , -['U', 'UV Face Select: Automatic UV calculation menu'] , -['U', 'Vertex-/Weightpaint mode: Undo'] , -['Ctrl-U', 'Save current state as user default'], -['Shift-U', 'Edit Mode: Redo Menu'], -['Alt-U', 'Edit Mode & Object Mode: Undo Menu'], -['.', '...'] -], - -"V":[ -['V', 'Curves/Nurbs: Vector handle'], -['V', 'Edit Mode : Rip selected vertices'], -['V', 'Vertexpaint mode'], -['V', 'UV Image Editor: Stitch UVs'], -['Ctrl-V',' UV Image Editor: maximize stretch.'], -['V', 'Action editor: Vector'], -['Alt-V', "Scale object to match image texture's aspect ratio"], -['Alt-V', 'Text Editor : Paste '], -['Alt-Shift-V', 'Text Editor : View menu'], -['Alt-Shift-V', 'Text Editor : View menu 1, Top of the file '], -['Alt-Shift-V', 'Text Editor : View menu 2, Bottom of the file '], -['Alt-Shift-V', 'Text Editor : View menu 3, PageUp'], -['Alt-Shift-V', 'Text Editor : View menu 4, PageDown'], -['Ctrl-Shift-V', 'Text Editor: Paste from clipboard'], -['Shift-V', 'Edit mode: Align view to selected vertices'], -['Shift-V', 'UV Image Editor: Limited Stitch UVs popup'], -['.', '...'] -], - -"W":[ -['W', 'Edit Mode: Specials menu'], -['W', 'Edit Mode: Specials menu, ARMATURE 1 Subdivide'], -['W', 'Edit Mode: Specials menu, ARMATURE 2 Subdivide Multi'], -['W', 'Edit Mode: Specials menu, ARMATURE 3 Switch Direction'], -['W', 'Edit Mode: Specials menu, ARMATURE 4 Flip Left-Right Name'], -['W', 'Edit Mode: Specials menu, ARMATURE 5 AutoName Left-Right'], -['W', 'Edit Mode: Specials menu, ARMATURE 6 AutoName Front-Back'], -['W', 'Edit Mode: Specials menu, ARMATURE 7 AutoName Top-Bottom'], -['W', 'Edit Mode: Specials menu, CURVE 1 Subdivide'], -['W', 'Edit Mode: Specials menu, CURVE 2 Swich Direction'], -['W', 'Edit Mode: Specials menu, CURVE 3 Set Goal Weight'], -['W', 'Edit Mode: Specials menu, CURVE 4 Set Radius'], -['W', 'Edit Mode: Specials menu, CURVE 5 Smooth'], -['W', 'Edit Mode: Specials menu, CURVE 6 Smooth Radius'], -['W', 'Edit Mode: Specials menu, MESH 1 Subdivide'], -['W', 'Edit Mode: Specials menu, MESH 2 Subdivide Multi'], -['W', 'Edit Mode: Specials menu, MESH 3 Subdivide Multi Fractal'], -['W', 'Edit Mode: Specials menu, MESH 4 Subdivide Smooth'], -['W', 'Edit Mode: Specials menu, MESH 5 Merge'], -['W', 'Edit Mode: Specials menu, MESH 6 Remove Double'], -['W', 'Edit Mode: Specials menu, MESH 7 Hide'], -['W', 'Edit Mode: Specials menu, MESH 8 Reveal'], -['W', 'Edit Mode: Specials menu, MESH 9 Select Swap'], -['W', 'Edit Mode: Specials menu, MESH 10 Flip Normal'], -['W', 'Edit Mode: Specials menu, MESH 11 Smooth'], -['W', 'Edit Mode: Specials menu, MESH 12 Bevel'], -['W', 'Edit Mode: Specials menu, MESH 13 Set Smooth'], -['W', 'Edit Mode : Specials menu, MESH 14 Set Solid'], -['W', 'Object Mode : on MESH objects, Boolean Tools menu'], -['W', 'Object Mode : on MESH objects, Boolean Tools 1 Intersect'], -['W', 'Object Mode : on MESH objects, Boolean Tools 2 union'], -['W', 'Object Mode : on MESH objects, Boolean Tools 3 difference'], -['W', 'Object Mode : on MESH objects, Boolean Tools 4 Add an intersect Modifier'], -['W', 'Object Mode : on MESH objects, Boolean Tools 5 Add an union Modifier'], -['W', 'Object Mode : on MESH objects, Boolean Tools 6 Add a difference Modifier'], -['W', 'Object mode : on TEXT object, Split characters, a new TEXT object by character in the selected string '], -['W', 'UV Image Editor: Weld/Align'], -['WX', 'UV Image Editor: Weld/Align X axis'], -['WY', 'UV Image Editor: Weld/Align Y axis'], -['Ctrl-W', 'Save current file'] , -['Shift-W', 'Warp/bend selected vertices around cursor'], -['.', '...'] - ], - -"X":[ -['X', 'Delete menu'] , -['X', 'TimeLine : Remove marker'], -['X', 'NLA : Remove marker'], -['X', 'IPO : Remove marker'], -['X', 'NODE window : delete'], #243 -['Alt-X', 'Text Editor : Cut '], -['Alt-X', 'Grease Pencil: Delete menu'], -['Ctrl-X', 'Restore default state (Erase all)'], -['.', '...'] - ], - -"Y":[ -['Y', 'Edit Mode & Mesh : Split selected vertices/faces from the rest'], -['Ctrl-Y', 'Object Mode : Redo'], -['.', '...'] -], - -"Z":[ -['Z', 'Render Window: 200% zoom from mouse position'], -['Z', 'Switch 3d draw type : solide/ wireframe (see also D)'], -['Alt-Z', 'Switch 3d draw type : solid / textured (see also D)'], -['Alt-Z,','Text editor : undo '], -['Ctrl-Z', 'Object Mode : Undo'], -['Ctrl-Z,','Text editor : undo '], -['Ctrl-Shift-Z,','Text editor : Redo '], -['Shift-Z', 'Switch 3d draw type : shaded / wireframe (see also D)'], -['.', '...'] -]}]} - -up=128 -down=129 -UP=0 -SEARCH=131 -OLDSEARCHLINE='' -SEARCHLINE=Create('') -LINE=130 -FINDED=[] -LEN=0 - -for k in hotkeys.keys(): - hotkeys[k].append(Create(0)) - -for k in hotkeys['Letters '][0]: - hotkeys['Letters '][0][k].append(Create(0)) - -hotL=hotkeys['Letters '][0].keys() -hotL.sort() - -hot=hotkeys.keys() -hot.sort() - -def searchfor(SEARCHLINE): - global hotkeys, hot - FINDLIST=[] - for k in hot: - if k not in ['Letters ', 'Search '] : - for l in hotkeys[k][:-1]: - #print 'k, l : ', k, l, l[1] - if l[1].upper().find(SEARCHLINE.upper())!=-1: - FINDLIST.append(l) - - elif k == 'Letters ': - for l in hotL : - for l0 in hotkeys['Letters '][0][l][:-1]: - #print 'k, l : ',l, k, l0 - if l0[1].upper().find(SEARCHLINE.upper())!=-1: - FINDLIST.append(l0) - #print 'FINDLIST',FINDLIST - FINDLIST.append(['Find list','Entry']) - return FINDLIST - - -glCr=glRasterPos2d -glCl3=glColor3f -glCl4=glColor4f -glRct=glRectf - -cf=[0.95,0.95,0.9,0.0] -c1=[0.95,0.95,0.9,0.0] -c=cf -r=[0,0,0,0] - -def trace_rectangle4(r,c): - glCl4(c[0],c[1],c[2],c[3]) - glRct(r[0],r[1],r[2],r[3]) - -def trace_rectangle3(r,c,c1): - glCl3(c[0],c[1],c[2]) - glRct(r[0],r[1],r[2],r[3]) - glCl3(c1[0],c1[1],c1[2]) - -def draw(): - global r,c,c1,hotkeys, hot, hotL, up, down, UP, SEARCH, SEARCHLINE,LINE - global OLDSEARCHLINE, FINDED, SCROLL, LEN - size=Buffer(GL_FLOAT, 4) - glGetFloatv(GL_SCISSOR_BOX, size) - size= size.list - - for s in [0,1,2,3]: size[s]=int(size[s]) - - c=[0.75,0.75,0.75,0] - c1=[0.6,0.6,0.6,0] - - r=[0,size[3],size[2],0] - trace_rectangle4(r,c) - - c=[0.64,0.64,0.64,0] - c1=[0.95,0.95,0.9,0.0] - - r=[0,size[3],size[2],size[3]-40] - trace_rectangle4(r,c) - - c1=[0.7,0.7,0.9,0.0] - c=[0.2,0.2,0.4,0.0] - c2=[0.71,0.71,0.71,0.0] - - glColor3f(1, 1, 1) - glRasterPos2f(42, size[3]-25) - - Text("HotKey and MouseAction Reference") - - l=0 - listed=0 - Llisted=0 - size[3]=size[3]-18 - - BeginAlign() - for i, k in enumerate(hot): - hotkeys[k][-1]=Toggle(k, i+10, 78*i, size[3]-(47), 78, 24, hotkeys[k][-1].val ) - l+=len(k) - if hotkeys[k][-1].val==1.0: - listed= i - EndAlign() - l=0 - size[3]=size[3]-4 - - if hot[listed]!='Letters ' and hot[listed]!='Search ' : - size[3]=size[3]-8 - SCROLL=size[3]/21 - END=-1 - if SCROLL < len(hotkeys[hot[listed]][:-1]): - BeginAlign() - Button('/\\',up,4,size[3]+8,20,14,'Scroll up') - Button('\\/',down,4,size[3]-8,20,14,'Scroll down') - EndAlign() - if (SCROLL+UP)0: - LEN=len(FINDED) - size[3]=size[3]-8 - SCROLL=size[3]/21 - END=-1 - - if SCROLL < len(FINDED): - BeginAlign() - Button('/\\',up,4,size[3]+8,20,14,'Scroll up') - Button('\\/',down,4,size[3]-8,20,14,'Scroll down') - EndAlign() - if (SCROLL+UP)4: - UP-=5 - elif (evt== UPARROWKEY): - if (UP+SCROLL)0: - UP-=1 - Redraw() - -def bevent(evt): - global hotkeysmhot, hotL, up,down,UP, FINDED - global SEARCH, SEARCHLINE,LINE, OLDSEARCHLINE - - if (evt== 1): - Exit() - - elif 9 < evt < 20: - for i, k in enumerate(hot): - if i+10!=evt: - hotkeys[k][-1].val=0 - UP=0 - Blender.Window.Redraw() - - elif 19 < evt < 46: - for i, k in enumerate(hotL): - if i+20!=evt: - hotkeys['Letters '][0][k][-1].val=0 - UP=0 - Blender.Window.Redraw() - - elif (evt==up): - UP+=1 - Blender.Window.Redraw() - - elif (evt==down): - if UP>0: UP-=1 - Blender.Window.Redraw() - - elif (evt==LINE): - if SEARCHLINE.val!='' and SEARCHLINE.val!=OLDSEARCHLINE: - OLDSEARCHLINE=SEARCHLINE.val - FINDED=searchfor(OLDSEARCHLINE) - Blender.Window.Redraw() - -if __name__ == '__main__': - Register(draw, event, bevent) diff --git a/release/scripts/image_2d_cutout.py b/release/scripts/image_2d_cutout.py deleted file mode 100644 index 16d0805256b..00000000000 --- a/release/scripts/image_2d_cutout.py +++ /dev/null @@ -1,559 +0,0 @@ -#!BPY - -""" -Name: '2D Cutout Image Importer' -Blender: 249 -Group: 'Image' -Tooltip: 'Batch UV Map images to Planes' -""" - -__author__ = "Kevin Morgan (forTe)" -__url__ = ("Home page, http://gamulabs.freepgs.com") -__version__ = "1.2.1" -__bpydoc__ = """\ -This Script will take an image and -UV map it to a plane sharing the same width to height ratio as the image. -Import options allow for the image to be a still or sequence type image -

-Imports can be single images or whole directories of images depending on the chosen -option. -""" - -#################################################### -#Copyright (C) 2008: Kevin Morgan -#################################################### -#-------------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 3 of the License, or -#(at your option) any later version. -# -#This program is distributed in the hopes 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, see . -#################################################### -#################################################### -#V1.0 -#Basic Functionality -#Published June 28, 2007 -#################################################### -#V1.1 -#Added Support for enabling viewport transparency -#Added more options to the UI for materials -#Added Proportionality code (Pixels per unit) -#Added GPL License Block -#Published June 29, 2007 -#################################################### -#V1.2 -#Added Support for Copying Existing Materials -#Import Images as Sequences -#Refreshed GUI - now with more clutter :( -#Miscellaneous and Housekeeping -#Published June 16, 2008 -#################################################### -#V1.2.1 -#Added Extend Texture Mode option at request of a user -#Published September 24, 2008 -#################################################### - -import Blender -from Blender import BGL, Draw, Image, Mesh, Material, Texture, Window -from Blender.Mathutils import * -import bpy - -# Global Constants -DIR = 0 -SINGLE = 1 -CUROFFS = 0 - -# GUI CONSTANTS -NO_EVT = 0 -SINGLE_IMG = 1 -DIRECTORY_IMG = 2 -CLR_PATH = 3 -CHG_EXT = 4 -EXIT = 5 -DO_SCRIPT = 6 - -VERSIONSTRING = '1.2.1' - -# Note the two parameter dicts could be combined, I just, liked them seperate... -# GUI Buttons Dict -GUIPARAMS = { - 'Path': Draw.Create(''), - 'ImageExt': Draw.Create(''), - 'Seq': Draw.Create(0), - 'PackImage': Draw.Create(0), - 'PPU': Draw.Create(50), - 'VPTransp': Draw.Create(1), - 'XOff': Draw.Create(0.0), - 'YOff': Draw.Create(0.0), - 'ZOff': Draw.Create(0.0), - 'CopyMat': Draw.Create(0), - 'MatId': Draw.Create(0), - 'MatCol': Draw.Create(1.0, 0.0, 0.0), - 'Ref': Draw.Create(0.8), - 'Spec': Draw.Create(0.5), - 'Hard': Draw.Create(50), - 'Alpha': Draw.Create(1.0), - 'ZTransp': Draw.Create(1), - 'Shadeless': Draw.Create(0), - 'TexChan': Draw.Create(1), - 'MPTCol': Draw.Create(1), - 'MPTAlpha': Draw.Create(1), - 'UseAlpha': Draw.Create(1), - 'CalcAlpha': Draw.Create(0), - 'ExtendMode': Draw.Create(0), - 'AutoRefresh': Draw.Create(0), - 'Cyclic': Draw.Create(0), - 'Frames': Draw.Create(100), - 'Offs': Draw.Create(0), - 'StartFr': Draw.Create(1), - 'RedrawImp': Draw.Create(0) -} - -# Script Execution Paramaters -PARAMS = { - 'ImagePaths': [], # Path to images to import - 'ImportType': SINGLE, # Import a Directory or a Single Image? - 'ImageProp': Image.Sources.STILL, # What sources for the image, still or sequence - 'PackImage': 0, # Pack the Image(s)? - 'PPU': 20, # Pixels Per Blender Unit - 'MakeTransp': 1, # Make face transparent in viewport - - 'NewMat': 1, # If true make a new material, otherwise duplicate an existing one, replacing appropriate attributes - 'MaterialId': 0, # ID to take from the Materials list upon copy - 'Materials': None, # Materials in Scene - 'MatProps': {'Col': [1.0, 0.0, 0.0], 'Shadeless': 1, 'Ref': 0.5, 'Spec': 0.5, 'Hard': 200, 'Alpha': 1.0, 'ZTransp': 1}, - - 'TexProps': {'UseAlpha': 1, 'CalcAlpha': 0, 'ExtendMode': 0}, # Texture Properties - 'TexChannel': 0, # Texture Channel - 'TexMapTo': {'Col': 1, 'Alpha': 1}, # Map to Col and/or Alpha - 'SeqProps': {'AutoRefresh': 0, 'Cyclic': 0, 'Frames': 100, 'Offs': 0, 'StartFr': 1}, - 'ObOffset': Vector(1, 0, 0) # Offset by this vector upon creation for multifile import -} - -# Get the Active Scene, of course -scn = bpy.data.scenes.active - -########################################## -# MAIN SCRIPT FUNCTIONS -########################################## - -def imgImport(imgPath): - global CUROFFS, PARAMS - ###################################### - # Load the image - ###################################### - try: - img = Image.Load(imgPath) - imgDimensions = img.getSize() # do this to ensure the data is available - except: - Blender.Draw.PupMenu('Error%t|Unsupported image format for "'+ imgPath.split('\\')[-1].split('/')[-1] +'"') - return - - if PARAMS['PackImage']: - img.pack() - name = Blender.sys.makename(imgPath, strip = 1) - - ###################################### - # Construct the mesh - ###################################### - - me = Mesh.New(name) - - # Calculate Dimensions from Image Size - dim = [float(i)/PARAMS['PPU'] for i in imgDimensions] - v = [[dim[0], dim[1], 0], [-dim[0], dim[1], 0], [-dim[0], -dim[1], 0], [dim[0], -dim[1], 0]] - me.verts.extend(v) - me.faces.extend([0, 1, 2, 3]) - - me.faces[0].image = img - me.faces[0].uv = [Vector(1.0, 1.0), Vector(0.0, 1.0), Vector(0.0, 0.0), Vector(1.0, 0.0)] - - if PARAMS['MakeTransp']: - me.faces[0].transp = Mesh.FaceTranspModes.ALPHA - - ###################################### - # Modify the Material - ###################################### - - mat = None - if not PARAMS['NewMat']: - mat = PARAMS['Materials'][PARAMS['MaterialId']].__copy__() - mat.setName(name) - else: - mat = Material.New(name) - properties = PARAMS['MatProps'] - mat.setRGBCol(properties['Col']) - mat.setRef(properties['Ref']) - mat.setSpec(properties['Spec']) - mat.setHardness(properties['Hard']) - mat.setAlpha(properties['Alpha']) - - if properties['Shadeless']: - mat.mode |= Material.Modes.SHADELESS - if properties['ZTransp']: - mat.mode |= Material.Modes.ZTRANSP - - properties = PARAMS['TexProps'] - - tex = Texture.New(name) - tex.setType('Image') - tex.setImage(img) - if properties['UseAlpha']: - tex.useAlpha = Texture.ImageFlags.USEALPHA - - if properties['CalcAlpha']: - tex.calcAlpha = Texture.ImageFlags.CALCALPHA - - if properties['ExtendMode']: - tex.setExtend('Extend') - - if PARAMS['ImageProp'] == Image.Sources.SEQUENCE: - properties = PARAMS['SeqProps'] - - img.source = PARAMS['ImageProp'] # Needs to be done here, otherwise an error with earlier getSize() - - tex.animStart = properties['StartFr'] - tex.animOffset = properties['Offs'] - tex.animFrames = properties['Frames'] - tex.autoRefresh = properties['AutoRefresh'] - tex.cyclic = properties['Cyclic'] - - texMapSetters = Texture.TexCo.UV - - # PARAMS['TexMapTo']['Col'] (and alpha) will either be 0 or 1 because its from a toggle, otherwise this line doesn't work - texChanSetters = Texture.MapTo.COL * PARAMS['TexMapTo']['Col'] | Texture.MapTo.ALPHA * PARAMS['TexMapTo']['Alpha'] - - mat.setTexture(PARAMS['TexChannel'], tex, texMapSetters, texChanSetters) - me.materials += [mat] - - ###################################### - # Object Construction - ###################################### - - ob = scn.objects.new(me, name) - p = Vector(ob.getLocation()) # Should be the origin, but just to be safe, get it - ob.setLocation((CUROFFS * PARAMS['ObOffset']) + p) - - return - -def translateParams(): - # Translates (or assigns for the most part) GUI values to those that can be read by the - # Import Function - - global GUIPARAMS, PARAMS - - if GUIPARAMS['Seq'].val and PARAMS['ImportType'] != DIR: - PARAMS['ImageProp'] = Image.Sources.SEQUENCE - - PARAMS['PackImage'] = GUIPARAMS['PackImage'].val - PARAMS['PPU'] = GUIPARAMS['PPU'].val - PARAMS['MakeTransp'] = GUIPARAMS['VPTransp'].val - PARAMS['ObOffset'] = Vector(GUIPARAMS['XOff'].val, GUIPARAMS['YOff'].val, GUIPARAMS['ZOff'].val) - - PARAMS['NewMat'] = not GUIPARAMS['CopyMat'].val - PARAMS['MaterialId'] = GUIPARAMS['MatId'].val - PARAMS['MatProps']['Col'] = list(GUIPARAMS['MatCol'].val) - PARAMS['MatProps']['Ref'] = GUIPARAMS['Ref'].val - PARAMS['MatProps']['Spec'] = GUIPARAMS['Spec'].val - PARAMS['MatProps']['Hard'] = GUIPARAMS['Hard'].val - PARAMS['MatProps']['Alpha'] = GUIPARAMS['Alpha'].val - PARAMS['MatProps']['ZTransp'] = GUIPARAMS['ZTransp'].val - PARAMS['MatProps']['Shadeless'] = GUIPARAMS['Shadeless'].val - - PARAMS['TexChannel'] = GUIPARAMS['TexChan'].val - 1 #Channels are 0-9, but GUI shows 1-10 - PARAMS['TexProps']['UseAlpha'] = GUIPARAMS['UseAlpha'].val - PARAMS['TexProps']['CalcAlpha'] = GUIPARAMS['CalcAlpha'].val - PARAMS['TexProps']['ExtendMode'] = GUIPARAMS['ExtendMode'].val - PARAMS['TexMapTo']['Col'] = GUIPARAMS['MPTCol'].val - PARAMS['TexMapTo']['Alpha'] = GUIPARAMS['MPTAlpha'].val - - PARAMS['SeqProps']['AutoRefresh'] = GUIPARAMS['AutoRefresh'].val - PARAMS['SeqProps']['Cyclic'] = GUIPARAMS['Cyclic'].val - PARAMS['SeqProps']['Frames'] = GUIPARAMS['Frames'].val - PARAMS['SeqProps']['Offs'] = GUIPARAMS['Offs'].val - PARAMS['SeqProps']['StartFr'] = GUIPARAMS['StartFr'].val - return - -def doScript(): - # Main script Function - # Consists of choosing between 2 loops, one with a redraw, one without, see comments for why - - global CUROFFS - - translateParams() - - total = len(PARAMS['ImagePaths']) - broken = 0 - - if GUIPARAMS['RedrawImp'].val: # Reduces the need to compare on every go through the loop - for i, path in enumerate(PARAMS['ImagePaths']): - CUROFFS = i # Could be passed to the import Function, but I chose a global instead - Window.DrawProgressBar(float(i)/total, "Importing %i of %i Images..." %(i+1, total)) - imgImport(path) - Blender.Redraw() - if Blender.Get('version') >= 246: - if Window.TestBreak(): - broken = 1 - break - else: - for i, path in enumerate(PARAMS['ImagePaths']): - CUROFFS = i - Window.DrawProgressBar(float(i)/total, "Importing %i of %i Images..." %(i+1, total)) - imgImport(path) - if Blender.Get('version') >= 246: - if Window.TestBreak(): - broken = 1 - break - - if broken: - Window.DrawProgressBar(1.0, "Script Execution Aborted") - else: - Window.DrawProgressBar(1.0, "Finished Importing") - - Blender.Redraw() # Force a refresh, since the user may have chosen to not refresh as they go along - - return - -########################################## -# PATH SETTERS AND CHANGERS -########################################## - -def setSinglePath(filename): - global GUIPARAMS, PARAMS - GUIPARAMS['Path'].val = filename - PARAMS['ImagePaths'] = [filename] - return - -def setDirPath(filename): - global GUIPARAMS, PARAMS - - try: - import os - except: - Draw.PupMenu('Full install of python required to be able to set Directory Paths') - Draw.Exit() - return - - path = os.path.dirname(filename) # Blender.sys.dirname fails on '/' - GUIPARAMS['Path'].val = path - - ext_lower = GUIPARAMS['ImageExt'].val.lower() - for f in os.listdir(path): - if f.lower().endswith(ext_lower): - PARAMS['ImagePaths'].append(os.path.join(path, f)) - - return - -def changeExtension(): - global GUIPARAMS, PARAMS - - if PARAMS['ImportType'] == SINGLE: - return - - try: - import os - except: - Draw.PupMenu('Full install of python required to be able to set Directory Paths') - Draw.Exit() - return - - PARAMS['ImagePaths'] = [] - - ext_lower = GUIPARAMS['ImageExt'].val.lower() - for f in os.listdir(GUIPARAMS['Path'].val): - if f.lower().endswith(ext_lower): - PARAMS['ImagePaths'].append(os.path.join(GUIPARAMS['Path'].val, f)) - - return - -########################################## -# INTERFACE FUNCTIONS -########################################## -def compileMaterialList(): - # Pretty straight forward, just grabs the materials in the blend file and constructs - # an appropriate string for use as a menu - - mats = [mat for mat in bpy.data.materials] - PARAMS['Materials'] = mats - title = 'Materials%t|' - menStrs = [mat.name + '%x' + str(i) + '|' for i, mat in enumerate(mats)] - return title + ''.join(menStrs) - -def event(evt, val): - # Disabled, since Esc is often used from the file browser - #if evt == Draw.ESCKEY: - # Draw.Exit() - - return - -def bevent(evt): - global GUIPARAMS, PARAMS - - if evt == NO_EVT: - Draw.Redraw() - - elif evt == SINGLE_IMG: - Window.FileSelector(setSinglePath, 'Image', Blender.sys.expandpath('//')) - Draw.Redraw() - PARAMS['ImportType'] = SINGLE - - elif evt == DIRECTORY_IMG: - Window.FileSelector(setDirPath, 'Directory', Blender.sys.expandpath('//')) - Draw.Redraw() - PARAMS['ImportType'] = DIR - - elif evt == CLR_PATH: - GUIPARAMS['Path'].val = '' - PARAMS['ImagePaths'] = [] - GUIPARAMS['ImageExt'].val = '' - Draw.Redraw() - - elif evt == CHG_EXT: - changeExtension() - Draw.Redraw() - - elif evt == EXIT: - Draw.Exit() - - elif evt == DO_SCRIPT: - doScript() - - else: - print "ERROR: UNEXPECTED BUTTON EVENT" - - return - -# GUI Colors ###### -ScreenColor = [0.7, 0.7, 0.7] -BackgroundColor = [0.8, 0.8, 0.8] -TitleBG = [0.6, 0.6, 0.6] -TitleCol = [1.0, 1.0, 1.0] -ErrCol = [1.0, 0.0, 0.0] -TextCol = [0.4, 0.4, 0.5] -################### - -def GUI(): - global GUIPARAMS, PARAMS - - BGL.glClearColor(*(ScreenColor + [1.0])) - BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) - - minx = 5 - maxx = 500 - miny = 5 - maxy = 450 - - lineheight = 24 - buPad = 5 # Generic Button Padding, most buttons should have 24-19 (or 5) px space around them - - lP = 5 # Left Padding - rP = 5 # Right Padding - - # Draw Background Box - BGL.glColor3f(*BackgroundColor) - BGL.glRecti(minx, miny, maxx, maxy) - - # Draw Title - BGL.glColor3f(*TitleBG) - BGL.glRecti(minx, maxy - (lineheight), maxx, maxy) - BGL.glColor3f(*TitleCol) - - title = "2D Cutout Image Importer v" + VERSIONSTRING - BGL.glRasterPos2i(minx + lP, maxy - 15) - Draw.Text(title, 'large') - - Draw.PushButton('Exit', EXIT, maxx-50-rP, maxy - lineheight + 2, 50, 19, "Exit Script") - - # Path Buttons - if GUIPARAMS['Path'].val == '': - Draw.PushButton('Single Image', SINGLE_IMG, minx + lP, maxy - (2*lineheight), 150, 19, "Select a Single Image to Import") - Draw.PushButton('Directory', DIRECTORY_IMG, minx + lP + 150, maxy - (2*lineheight), 150, 19, "Select a Directory of Images to Import") - - else: - Draw.PushButton('Clear', CLR_PATH, minx+lP, maxy - (2*lineheight), 50, 19, "Clear Path and Change Import Options") - - GUIPARAMS['Path'] = Draw.String('Path: ', NO_EVT, minx + lP, maxy - (3*lineheight), (maxx-minx-lP-rP), 19, GUIPARAMS['Path'].val, 399, 'Path to Import From') - if PARAMS['ImportType'] == DIR: - GUIPARAMS['ImageExt'] = Draw.String('Image Ext: ', CHG_EXT, minx + lP, maxy - (4*lineheight), 110, 19, GUIPARAMS['ImageExt'].val, 6, 'Image extension for batch directory importing (case insensitive)') - GUIPARAMS['PackImage'] = Draw.Toggle('Pack', NO_EVT, maxx - rP - 50, maxy - (4*lineheight), 50, 19, GUIPARAMS['PackImage'].val, 'Pack Image(s) into .Blend File') - - # Geometry and Viewport Options - BGL.glColor3f(*TextCol) - BGL.glRecti(minx+lP, maxy - (5*lineheight), maxx-rP, maxy - (5*lineheight) + 1) - BGL.glRasterPos2i(minx + lP, maxy-(5*lineheight) + 3) - Draw.Text('Geometry and Display Options', 'small') - - GUIPARAMS['PPU'] = Draw.Slider('Pixels Per Unit: ', NO_EVT, minx + lP, maxy - (6*lineheight), (maxx-minx)/2 - lP, 19, GUIPARAMS['PPU'].val, 1, 5000, 0, 'Set the Number of Pixels Per Blender Unit to preserve Image Size Relations') - GUIPARAMS['VPTransp'] = Draw.Toggle('Viewport Transparency', NO_EVT, minx + lP, maxy - (8*lineheight), (maxx-minx)/2 - lP, 2*lineheight - buPad, GUIPARAMS['VPTransp'].val, 'Display Alpha Transparency in the Viewport') - - GUIPARAMS['XOff'] = Draw.Slider('Offs X: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (6*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['XOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the X-Direction if Importing Multiple Images') - GUIPARAMS['YOff'] = Draw.Slider('Offs Y: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (7*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['YOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the Y-Direction if Importing Multiple Images') - GUIPARAMS['ZOff'] = Draw.Slider('Offs Z: ', NO_EVT, minx + lP + (maxx-minx)/2, maxy - (8*lineheight), (maxx-minx)/2 - lP - rP, 19, GUIPARAMS['ZOff'].val, 0, 5.0, 0, 'Amount to Offset Each Imported in the Z-Direction if Importing Multiple Images') - - # Material and Texture Options - BGL.glColor3f(*TextCol) - BGL.glRecti(minx+lP, maxy - (9*lineheight), maxx-rP, maxy - (9*lineheight) + 1) - BGL.glRasterPos2i(minx + lP, maxy-(9*lineheight) + 3) - Draw.Text('Material and Texture Options', 'small') - - half = (maxx-minx-lP-rP)/2 - GUIPARAMS['CopyMat'] = Draw.Toggle('Copy Existing Material', NO_EVT, minx + lP, maxy-(10*lineheight), half, 19, GUIPARAMS['CopyMat'].val, 'Copy an Existing Material') - if GUIPARAMS['CopyMat'].val: - menStr = compileMaterialList() - GUIPARAMS['MatId'] = Draw.Menu(menStr, NO_EVT, minx + lP, maxy - (11*lineheight), half, 19, GUIPARAMS['MatId'].val, 'Material to Copy Settings From') - else: - GUIPARAMS['MatCol'] = Draw.ColorPicker(NO_EVT, minx+lP, maxy - (13*lineheight), 40, (3*lineheight) - buPad, GUIPARAMS['MatCol'].val, 'Color of Newly Created Material') - GUIPARAMS['Ref'] = Draw.Slider('Ref: ', NO_EVT, minx +lP+45, maxy - (11*lineheight), half-45, 19, GUIPARAMS['Ref'].val, 0.0, 1.0, 0, 'Set the Ref Value for Created Materials') - GUIPARAMS['Spec'] = Draw.Slider('Spec: ', NO_EVT, minx +lP+45, maxy - (12*lineheight), half-45, 19, GUIPARAMS['Spec'].val, 0.0, 2.0, 0, 'Set the Spec Value for Created Materials') - GUIPARAMS['Hard'] = Draw.Slider('Hard: ', NO_EVT, minx +lP+45, maxy - (13*lineheight), half-45, 19, GUIPARAMS['Hard'].val, 1, 500, 0, 'Set the Hardness Value for Created Materials') - GUIPARAMS['Alpha'] = Draw.Slider('A: ', NO_EVT, minx +lP, maxy - (14*lineheight), half, 19, GUIPARAMS['Alpha'].val, 0.0, 1.0, 0, 'Set the Alpha Value for Created Materials') - - GUIPARAMS['ZTransp'] = Draw.Toggle('ZTransparency', NO_EVT, minx + lP, maxy - (15*lineheight), half, 19, GUIPARAMS['ZTransp'].val, 'Enable ZTransparency') - GUIPARAMS['Shadeless'] = Draw.Toggle('Shadeless', NO_EVT, minx + lP, maxy - (16*lineheight), half, 19, GUIPARAMS['Shadeless'].val, 'Enable Shadeless') - - GUIPARAMS['TexChan'] = Draw.Number('Texture Channel: ', NO_EVT, minx + lP+ half + buPad, maxy - (10*lineheight), half-rP, 19, GUIPARAMS['TexChan'].val, 1, 10, 'Texture Channel for Image Texture') - - GUIPARAMS['MPTCol'] = Draw.Toggle('Color', NO_EVT, minx + lP + half + buPad, maxy - (11*lineheight), half/2, 19, GUIPARAMS['MPTCol'].val, 'Map To Color Channel') - GUIPARAMS['MPTAlpha'] = Draw.Toggle('Alpha', NO_EVT, minx + lP + int((1.5)*half) + buPad, maxy - (11*lineheight), half/2 - rP, 19, GUIPARAMS['MPTAlpha'].val, 'Map To Alpha Channel') - - third = int((maxx-minx-lP-rP)/6) - GUIPARAMS['UseAlpha'] = Draw.Toggle('Use Alpha', NO_EVT, minx + lP + half + buPad, maxy - (12*lineheight), third, 19, GUIPARAMS['UseAlpha'].val, "Use the Images' Alpha Values") - GUIPARAMS['CalcAlpha'] = Draw.Toggle('Calc Alpha', NO_EVT, minx + lP + half + third + buPad, maxy - (12*lineheight), third, 19, GUIPARAMS['CalcAlpha'].val, "Calculate Images' Alpha Values") - GUIPARAMS['ExtendMode'] = Draw.Toggle('Extend', NO_EVT, minx+lP+half+third+third+buPad, maxy - (12*lineheight), third-3, 19, GUIPARAMS['ExtendMode'].val, "Use Extend texture mode. If deselected, Repeat is used") - GUIPARAMS['Seq'] = Draw.Toggle('Sequence', NO_EVT, minx + lP + half + buPad, maxy - (13*lineheight), half-rP, 19, GUIPARAMS['Seq'].val, 'Set the Image(s) to use a Sequence instead of a Still') - - if GUIPARAMS['Seq'].val and not PARAMS['ImportType'] == DIR: - GUIPARAMS['AutoRefresh'] = Draw.Toggle('Auto Refresh', NO_EVT, minx + lP + half + buPad, maxy - (14*lineheight), half/2, 19, GUIPARAMS['AutoRefresh'].val, 'Use Auto Refresh') - GUIPARAMS['Cyclic'] = Draw.Toggle('Cyclic', NO_EVT, minx + lP + half + buPad + half/2, maxy - (14*lineheight), half/2 - rP, 19, GUIPARAMS['Cyclic'].val, 'Repeat Frames Cyclically`') - - GUIPARAMS['Frames'] = Draw.Number('Frames: ', NO_EVT, minx +lP + half + buPad, maxy - (15*lineheight), half - rP, 19, GUIPARAMS['Frames'].val, 1, 30000, 'Sets the Number of Images of a Movie to Use') - GUIPARAMS['Offs'] = Draw.Number('Offs: ', NO_EVT, minx +lP + half + buPad, maxy - (16*lineheight), half/2, 19, GUIPARAMS['Offs'].val, -30000, 30000, 'Offsets the Number of the Frame to use in the Animation') - GUIPARAMS['StartFr'] = Draw.Number('StartFr: ', NO_EVT, minx +lP + half + buPad + half/2, maxy - (16*lineheight), half/2 - rP, 19, GUIPARAMS['StartFr'].val, 1, 30000, 'Sets the Global Starting Frame of the Movie') - elif GUIPARAMS['Seq'].val and PARAMS['ImportType'] == DIR: - BGL.glColor3f(*ErrCol) - BGL.glRasterPos2i(minx + lP + half + buPad + 7, maxy-(14 * lineheight) + 5) - Draw.Text('Sequence only available for Single Image Import', 'small') - - # Import Options - BGL.glColor3f(*TextCol) - BGL.glRecti(minx+lP, maxy - (17*lineheight), maxx-rP, maxy - (17*lineheight) + 1) - BGL.glRasterPos2i(minx + lP, maxy-(17*lineheight) + 3) - Draw.Text('Import', 'small') - - if GUIPARAMS['Path'].val and GUIPARAMS['ImageExt'].val or GUIPARAMS['Path'].val and PARAMS['ImportType'] == SINGLE: - Draw.PushButton('Import', DO_SCRIPT, minx + lP, maxy - (18*lineheight), 75, 19, "Import Image(s)") - else: - BGL.glColor3f(*ErrCol) - BGL.glRasterPos2i(minx+lP, maxy - (18*lineheight) + 5) - Draw.Text('A path and image type must be specified to import images') - - GUIPARAMS['RedrawImp'] = Draw.Toggle('Redraw During Import', NO_EVT, maxx - rP - 150, maxy - (18*lineheight), 150, 19, GUIPARAMS['RedrawImp'].val, 'Redraw the View as Images Import') - -Draw.Register(GUI, event, bevent) \ No newline at end of file diff --git a/release/scripts/image_auto_layout.py b/release/scripts/image_auto_layout.py deleted file mode 100644 index d19ba1da662..00000000000 --- a/release/scripts/image_auto_layout.py +++ /dev/null @@ -1,455 +0,0 @@ -#!BPY - -""" -Name: 'Consolidate into one image' -Blender: 243 -Group: 'Image' -Tooltip: 'Pack all texture images into 1 image and remap faces.' -""" - -__author__ = "Campbell Barton" -__url__ = ("blender", "blenderartists.org") -__version__ = "1.1a 2009/04/01" - -__bpydoc__ = """\ -This script makes a new image from the used areas of all the images mapped to the selected mesh objects. -Image are packed into 1 new image that is assigned to the original faces. -This is usefull for game models where 1 image is faster then many, and saves the labour of manual texture layout in an image editor. - -""" -# -------------------------------------------------------------------------- -# Auto Texture Layout v1.0 by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -# Function to find all the images we use -import Blender as B -from Blender.Mathutils import Vector, RotationMatrix -from Blender.Scene import Render -import BPyMathutils -BIGNUM= 1<<30 -TEXMODE= B.Mesh.FaceModes.TEX - -def pointBounds(points): - ''' - Takes a list of points and returns the - area, center, bounds - ''' - ymax= xmax= -BIGNUM - ymin= xmin= BIGNUM - - for p in points: - x= p.x - y= p.y - - if x>xmax: xmax=x - if y>ymax: ymax=y - - if x 0.1: - mat_pos= RotationMatrix( rot_angle, 2) - mat_neg= RotationMatrix( -rot_angle, 2) - - new_points_pos= [v*mat_pos for v in current_points] - area_pos, cent_pos, bounds_pos= pointBounds(new_points_pos) - - # 45d rotations only need to be tested in 1 direction. - if rot_angle == 45: - area_neg= area_pos - else: - new_points_neg= [v*mat_neg for v in current_points] - area_neg, cent_neg, bounds_neg= pointBounds(new_points_neg) - - - # Works! - #print 'Testing angle', rot_angle, current_area, area_pos, area_neg - - best_area= min(area_pos, area_neg, current_area) - if area_pos == best_area: - current_area= area_pos - cent= cent_pos - bounds= bounds_pos - current_points= new_points_pos - total_rot_angle+= rot_angle - elif rot_angle != 45 and area_neg == best_area: - current_area= area_neg - cent= cent_neg - bounds= bounds_neg - current_points= new_points_neg - total_rot_angle-= rot_angle - - rot_angle *= 0.5 - - # Return the optimal rotation. - return total_rot_angle - - -class faceGroup(object): - ''' - A Group of faces that all use the same image, each group has its UVs packed into a square. - ''' - __slots__= 'xmax', 'ymax', 'xmin', 'ymin',\ - 'image', 'faces', 'box_pack', 'size', 'ang', 'rot_mat', 'cent'\ - - def __init__(self, mesh_list, image, size, PREF_IMAGE_MARGIN): - self.image= image - self.size= size - self.faces= [f for me in mesh_list for f in me.faces if f.mode & TEXMODE and f.image == image] - - # Find the best rotation. - all_points= [uv for f in self.faces for uv in f.uv] - bountry_indicies= BPyMathutils.convexHull(all_points) - bountry_points= [all_points[i] for i in bountry_indicies] - - # Pre Rotation bounds - self.cent= pointBounds(bountry_points)[1] - - # Get the optimal rotation angle - self.ang= bestBoundsRotation(bountry_points) - self.rot_mat= RotationMatrix(self.ang, 2), RotationMatrix(-self.ang, 2) - - # Post rotation bounds - bounds= pointBounds([\ - ((uv-self.cent) * self.rot_mat[0]) + self.cent\ - for uv in bountry_points])[2] - - # Break the bounds into useable values. - xmin, ymin, xmax, ymax= bounds - - # Store the bounds, include the margin. - # The bounds rect will need to be rotated to the rotation angle. - self.xmax= xmax + (PREF_IMAGE_MARGIN/size[0]) - self.xmin= xmin - (PREF_IMAGE_MARGIN/size[0]) - self.ymax= ymax + (PREF_IMAGE_MARGIN/size[1]) - self.ymin= ymin - (PREF_IMAGE_MARGIN/size[1]) - - self.box_pack=[\ - 0.0, 0.0,\ - size[0]*(self.xmax - self.xmin),\ - size[1]*(self.ymax - self.ymin),\ - image.name] - - ''' - # default. - self.scale= 1.0 - - def set_worldspace_scale(self): - scale_uv= 0.0 - scale_3d= 0.0 - for f in self.faces: - for i in xrange(len(f.v)): - scale_uv+= (f.uv[i]-f.uv[i-1]).length * 0.1 - scale_3d+= (f.v[i].co-f.v[i-1].co).length * 0.1 - self.scale= scale_3d/scale_uv - ''' - - - - def move2packed(self, width, height): - ''' - Moves the UV coords to their packed location - using self.box_pack as the offset, scaler. - box_pack must be set to its packed location. - width and weight are the w/h of the overall packed area's bounds. - ''' - # packedLs is a list of [(anyUniqueID, left, bottom, width, height)...] - # Width and height in float pixel space. - - # X Is flipped :/ - #offset_x= (1-(self.box_pack[1]/d)) - (((self.xmax-self.xmin) * self.image.size[0])/d) - offset_x= self.box_pack[0]/width - offset_y= self.box_pack[1]/height - - for f in self.faces: - for uv in f.uv: - uv_rot= ((uv-self.cent) * self.rot_mat[0]) + self.cent - uv.x= offset_x+ (((uv_rot.x-self.xmin) * self.size[0])/width) - uv.y= offset_y+ (((uv_rot.y-self.ymin) * self.size[1])/height) - -def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_KEEP_ASPECT, PREF_IMAGE_MARGIN): #, PREF_SIZE_FROM_UV=True): - ''' - Main packing function - - All meshes from mesh_list must have faceUV else this function will fail. - ''' - face_groups= {} - - for me in mesh_list: - for f in me.faces: - if f.mode & TEXMODE: - image= f.image - if image: - try: - face_groups[image.name] # will fail if teh groups not added. - except: - try: - size= image.size - except: - B.Draw.PupMenu('Aborting: Image cold not be loaded|' + image.name) - return - - face_groups[image.name]= faceGroup(mesh_list, image, size, PREF_IMAGE_MARGIN) - - if not face_groups: - B.Draw.PupMenu('No Images found in mesh(es). Aborting!') - return - - if len(face_groups)<2: - B.Draw.PupMenu('Only 1 image found|Select a mesh(es) using 2 or more images.') - return - - ''' - if PREF_SIZE_FROM_UV: - for fg in face_groups.itervalues(): - fg.set_worldspace_scale() - ''' - - # RENDER THE FACES. - render_scn= B.Scene.New() - render_scn.makeCurrent() - render_context= render_scn.getRenderingContext() - render_context.setRenderPath('') # so we can ignore any existing path and save to the abs path. - - PREF_IMAGE_PATH_EXPAND= B.sys.expandpath(PREF_IMAGE_PATH) + '.png' - - # TEST THE FILE WRITING. - try: - # Can we write to this file??? - f= open(PREF_IMAGE_PATH_EXPAND, 'w') - f.close() - except: - B.Draw.PupMenu('Error%t|Could not write to path|' + PREF_IMAGE_PATH_EXPAND) - return - - render_context.imageSizeX(PREF_IMAGE_SIZE) - render_context.imageSizeY(PREF_IMAGE_SIZE) - render_context.enableOversampling(True) - render_context.setOversamplingLevel(16) - render_context.setRenderWinSize(100) - render_context.setImageType(Render.PNG) - render_context.enableExtensions(True) - render_context.enablePremultiply() # No alpha needed. - render_context.enableRGBAColor() - render_context.threads = 2 - - #Render.EnableDispView() # Broken?? - - # New Mesh and Object - render_mat= B.Material.New() - render_mat.mode |= \ - B.Material.Modes.SHADELESS | \ - B.Material.Modes.TEXFACE | \ - B.Material.Modes.TEXFACE_ALPHA | \ - B.Material.Modes.ZTRANSP - - render_mat.setAlpha(0.0) - - render_me= B.Mesh.New() - render_me.verts.extend([Vector(0,0,0)]) # Stupid, dummy vert, preverts errors. when assigning UV's/ - render_ob= B.Object.New('Mesh') - render_ob.link(render_me) - render_scn.link(render_ob) - render_me.materials= [render_mat] - - - # New camera and object - render_cam_data= B.Camera.New('ortho') - render_cam_ob= B.Object.New('Camera') - render_cam_ob.link(render_cam_data) - render_scn.link(render_cam_ob) - render_scn.objects.camera = render_cam_ob - - render_cam_data.type= 'ortho' - render_cam_data.scale= 1.0 - - - # Position the camera - render_cam_ob.LocZ= 1.0 - render_cam_ob.LocX= 0.5 - render_cam_ob.LocY= 0.5 - - # List to send to to boxpack function. - boxes2Pack= [ fg.box_pack for fg in face_groups.itervalues()] - packWidth, packHeight = B.Geometry.BoxPack2D(boxes2Pack) - - if PREF_KEEP_ASPECT: - packWidth= packHeight= max(packWidth, packHeight) - - - # packedLs is a list of [(anyUniqueID, left, bottom, width, height)...] - # Re assign the face groups boxes to the face_group. - for box in boxes2Pack: - face_groups[ box[4] ].box_pack= box # box[4] is the ID (image name) - - - # Add geometry to the mesh - for fg in face_groups.itervalues(): - # Add verts clockwise from the bottom left. - _x= fg.box_pack[0] / packWidth - _y= fg.box_pack[1] / packHeight - _w= fg.box_pack[2] / packWidth - _h= fg.box_pack[3] / packHeight - - render_me.verts.extend([\ - Vector(_x, _y, 0),\ - Vector(_x, _y +_h, 0),\ - Vector(_x + _w, _y +_h, 0),\ - Vector(_x + _w, _y, 0),\ - ]) - - render_me.faces.extend([\ - render_me.verts[-1],\ - render_me.verts[-2],\ - render_me.verts[-3],\ - render_me.verts[-4],\ - ]) - - target_face= render_me.faces[-1] - target_face.image= fg.image - target_face.mode |= TEXMODE - - # Set the UV's, we need to flip them HOZ? - target_face.uv[0].x= target_face.uv[1].x= fg.xmax - target_face.uv[2].x= target_face.uv[3].x= fg.xmin - - target_face.uv[0].y= target_face.uv[3].y= fg.ymin - target_face.uv[1].y= target_face.uv[2].y= fg.ymax - - for uv in target_face.uv: - uv_rot= ((uv-fg.cent) * fg.rot_mat[1]) + fg.cent - uv.x= uv_rot.x - uv.y= uv_rot.y - - render_context.render() - Render.CloseRenderWindow() - render_context.saveRenderedImage(PREF_IMAGE_PATH_EXPAND) - - #if not B.sys.exists(PREF_IMAGE_PATH_EXPAND): - # raise 'Error!!!' - - - # NOW APPLY THE SAVED IMAGE TO THE FACES! - #print PREF_IMAGE_PATH_EXPAND - try: - target_image= B.Image.Load(PREF_IMAGE_PATH_EXPAND) - except: - B.Draw.PupMenu('Error: Could not render or load the image at path|' + PREF_IMAGE_PATH_EXPAND) - return - - # Set to the 1 image. - for me in mesh_list: - for f in me.faces: - if f.mode & TEXMODE and f.image: - f.image= target_image - - for fg in face_groups.itervalues(): - fg.move2packed(packWidth, packHeight) - - scn.makeCurrent() - render_me.verts= None # free a tiny amount of memory. - B.Scene.Unlink(render_scn) - target_image.makeCurrent() - - -def main(): - scn= B.Scene.GetCurrent() - scn_objects = scn.objects - ob= scn_objects.active - - if not ob or ob.type != 'Mesh': - B.Draw.PupMenu('Error, no active mesh object, aborting.') - return - - # Create the variables. - # Filename without path or extension. - newpath= B.Get('filename').split('/')[-1].split('\\')[-1].replace('.blend', '') - - PREF_IMAGE_PATH = B.Draw.Create('//%s_grp' % newpath) - PREF_IMAGE_SIZE = B.Draw.Create(1024) - PREF_IMAGE_MARGIN = B.Draw.Create(6) - PREF_KEEP_ASPECT = B.Draw.Create(0) - PREF_ALL_SEL_OBS = B.Draw.Create(0) - - pup_block = [\ - 'Image Path: (no ext)',\ - ('', PREF_IMAGE_PATH, 3, 100, 'Path to new Image. "//" for curent blend dir.'),\ - 'Image Options', - ('Pixel Size:', PREF_IMAGE_SIZE, 64, 4096, 'Image Width and Height.'),\ - ('Pixel Margin:', PREF_IMAGE_MARGIN, 0, 64, 'Use a margin to stop mipmapping artifacts.'),\ - ('Keep Aspect', PREF_KEEP_ASPECT, 'If disabled, will stretch the images to the bounds of the texture'),\ - 'Texture Source',\ - ('All Sel Objects', PREF_ALL_SEL_OBS, 'Combine all selected objects into 1 texture, otherwise active object only.'),\ - ] - - if not B.Draw.PupBlock('Consolidate images...', pup_block): - return - - PREF_IMAGE_PATH= PREF_IMAGE_PATH.val - PREF_IMAGE_SIZE= PREF_IMAGE_SIZE.val - PREF_IMAGE_MARGIN= float(PREF_IMAGE_MARGIN.val) # important this is a float otherwise division wont work properly - PREF_KEEP_ASPECT= PREF_KEEP_ASPECT.val - PREF_ALL_SEL_OBS= PREF_ALL_SEL_OBS.val - - if PREF_ALL_SEL_OBS: - mesh_list= [ob.getData(mesh=1) for ob in scn_objects.context if ob.type=='Mesh'] - # Make sure we have no doubles- dict by name, then get the values back. - - for me in mesh_list: me.tag = False - - mesh_list_new = [] - for me in mesh_list: - if me.faceUV and me.tag==False: - me.tag = True - mesh_list_new.append(me) - - # replace list with possible doubles - mesh_list = mesh_list_new - - else: - mesh_list= [ob.getData(mesh=1)] - if not mesh_list[0].faceUV: - B.Draw.PupMenu('Error, active mesh has no images, Aborting!') - return - - consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_KEEP_ASPECT, PREF_IMAGE_MARGIN) - B.Window.RedrawAll() - -if __name__=='__main__': - main() diff --git a/release/scripts/image_billboard.py b/release/scripts/image_billboard.py deleted file mode 100644 index 54f0f7c5c55..00000000000 --- a/release/scripts/image_billboard.py +++ /dev/null @@ -1,269 +0,0 @@ -#!BPY -""" -Name: 'Billboard Render on Active' -Blender: 242 -Group: 'Image' -Tooltip: 'Selected objects and lamps to rendered faces on the act mesh' -""" -__author__= "Campbell Barton" -__url__= ["blender", "blenderartist"] -__version__= "1.0" - -__bpydoc__= """\ -Render Billboard Script -This can texture a simple billboard mesh from any number of selected objects. - -Renders objects in the selection to quad faces on the active mesh. - -Usage -* Light your model or enable the shadless flag so it is visible -* Make a low poly mesh out of quads with 90d corners. (this will be you billboard mesh) -* Select the model and any lamps that light it -* Select the billboard mesh so that it is active -* Run this script, Adjust settings such as image size or oversampling. -* Select a place to save the PNG image. -* Once the script has finished running return to the 3d view by pressing Shift+F5 -* To see the newly applied textures change the drawtype to 'Textured Solid' -""" -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton 2006 -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender import Mesh, Material, Draw -import BPyMathutils -import bpy -import BPyRender -from Blender.Scene import Render - -# reload(BPyRender) -# reload(BPyMathutils) - -import os -Vector= Blender.Mathutils.Vector - -def alpha_mat(image): - # returns a material useable for - mtl= bpy.data.materials.new() - mtl.mode |= (Material.Modes.SHADELESS | Material.Modes.ZTRANSP | Material.Modes.FULLOSA | Material.Modes.TEXFACE | Material.Modes.TEXFACE_ALPHA ) - return mtl - -# PupBlock Settings -GLOBALS= {} -PREF_RES= Draw.Create(512) -PREF_TILE_RES= Draw.Create(256) -PREF_AA = Draw.Create(1) -PREF_ALPHA= Draw.Create(1) -PREF_Z_OFFSET = Draw.Create(10.0) -PREF_IMG_PACK= Draw.Create(1) - - -def save_billboard(PREF_IMAGE_PATH): - Blender.Window.WaitCursor(1) - # remove png, add it later - PREF_IMAGE_PATH= PREF_IMAGE_PATH.replace('.png', '') - - ob_sel= GLOBALS['ob_sel'] - me_ob = GLOBALS['me_ob'] - me_data = GLOBALS['me_data'] - - time= Blender.sys.time() - - me_mat= me_ob.matrixWorld - - # Render images for all faces - face_data= [] # Store faces, images etc - boxes2Pack= [] - me_data.faceUV= True - - for i, f in enumerate(me_data.faces): - no= f.no - - # Offset the plane by the zoffset on the faces normal - plane= [v.co * me_mat for v in f] - - # Horizontal stacking, make sure 0,1 and 2,3 are the longest - if\ - (plane[0]-plane[1]).length + (plane[2]-plane[3]).length < \ - (plane[1]-plane[2]).length + (plane[3]-plane[0]).length: - plane.append(plane.pop(0)) - rot90= True - else: - rot90= False - - no= Blender.Mathutils.QuadNormal(*plane) - plane= [v + no*PREF_Z_OFFSET.val for v in plane] - - cent= (plane[0]+plane[1]+plane[2]+plane[3] ) /4.0 - camera_matrix= BPyMathutils.plane2mat(plane) - tmp_path= '%s_%d' % (PREF_IMAGE_PATH, i) - img= BPyRender.imageFromObjectsOrtho(ob_sel, tmp_path, PREF_TILE_RES.val, PREF_TILE_RES.val, PREF_AA.val, PREF_ALPHA.val, camera_matrix) - img.reload() - #img.pack() # se we can keep overwriting the path - #img.filename= "" - - if rot90: - f.uv=Vector(1,1), Vector(0,1), Vector(0,0), Vector(1,0) - else: - f.uv= Vector(0,1), Vector(0,0), Vector(1,0), Vector(1,1) - - if not PREF_IMG_PACK.val: - f.mode |= Mesh.FaceModes.TEX - f.image = img - - if PREF_ALPHA.val: - f.transp |= Mesh.FaceTranspModes.ALPHA - else: - w= ((plane[0]-plane[1]).length + (plane[2]-plane[3]).length)/2 - h= ((plane[1]-plane[2]).length + (plane[3]-plane[0]).length)/2 - - face_data.append( (f, img) ) - boxes2Pack.append( [0.0,0.0,h, w, i] ) - - if PREF_IMG_PACK.val: - # pack the quads into a square - packWidth, packHeight = Blender.Geometry.BoxPack2D(boxes2Pack) - - render_obs= [] - - render_mat= alpha_mat(img) - - # Add geometry to the mesh - for box in boxes2Pack: - i= box[4] - - orig_f, img= face_data[i] - - # New Mesh and Object - - render_me= bpy.data.meshes.new() - - render_ob= Blender.Object.New('Mesh') - render_me.materials= [render_mat] - render_ob.link(render_me) - - render_obs.append(render_ob) - - # Add verts clockwise from the bottom left. - _x= box[0] / packWidth - _y= box[1] / packHeight - _w= box[2] / packWidth - _h= box[3] / packHeight - - - render_me.verts.extend([\ - Vector(_x, _y, 0),\ - Vector(_x, _y +_h, 0),\ - Vector(_x + _w, _y +_h, 0),\ - Vector(_x + _w, _y, 0),\ - ]) - - render_me.faces.extend(list(render_me.verts)) - render_me.faceUV= True - - render_me.faces[0].uv = [Vector(0,0), Vector(0,1), Vector(1,1), Vector(1,0)] - render_me.faces[0].image = img - - # Set the UV's, we need to flip them HOZ? - for uv in orig_f.uv: - uv.x = _x + (uv.x * _w) - uv.y = _y + (uv.y * _h) - - target_image= BPyRender.imageFromObjectsOrtho(render_obs, PREF_IMAGE_PATH, PREF_RES.val, PREF_RES.val, PREF_AA.val, PREF_ALPHA.val, None) - target_image.reload() # incase your overwriting an existing image. - - # Set to the 1 image. - for f in me_data.faces: - f.image= target_image - if PREF_ALPHA.val: - f.transp |= Mesh.FaceTranspModes.ALPHA - - # Free the images data and remove - for data in face_data: - img= data[1] - os.remove(img.filename) - img.reload() - - # Finish pack - - me_data.update() - me_ob.makeDisplayList() - Blender.Window.WaitCursor(0) - print '%.2f secs taken' % (Blender.sys.time()-time) - - -def main(): - scn= bpy.data.scenes.active - ob_sel= list(scn.objects.context) - - PREF_KEEP_ASPECT= False - - # Error Checking - if len(ob_sel) < 2: - Draw.PupMenu("Error%t|Select 2 mesh objects") - return - - me_ob= scn.objects.active - - if not me_ob: - Draw.PupMenu("Error%t|No active mesh selected.") - - try: - ob_sel.remove(me_ob) - except: - pass - - if me_ob.type != 'Mesh': - Draw.PupMenu("Error%t|Active Object must be a mesh to write billboard images too") - return - - me_data= me_ob.getData(mesh=1) - - for f in me_data.faces: - if len(f) != 4: - Draw.PupMenu("Error%t|Active mesh must have only quads") - return - - - # Get user input - block = [\ - 'Image Pixel Size',\ - ("Packed Size: ", PREF_RES, 128, 2048, "Pixel width and height to render the billboard to"),\ - ("Tile Size: ", PREF_TILE_RES, 64, 1024, "Pixel width and height for each tile to render to"),\ - 'Render Settings',\ - ("Pack Final", PREF_IMG_PACK , "Pack the image for each face into images into a single image"),\ - ("Oversampling", PREF_AA , "Higher quality woth extra sampling"),\ - ("Alpha Clipping", PREF_ALPHA , "Render empty areas as transparent"),\ - ("Cam ZOffset: ", PREF_Z_OFFSET, 0.1, 100, "Distance to place the camera away from the quad when rendering")\ - ] - - if not Draw.PupBlock("Billboard Render", block): - return - - # Set globals - GLOBALS['ob_sel'] = ob_sel - GLOBALS['me_ob'] = me_ob - GLOBALS['me_data'] = me_data - - Blender.Window.FileSelector(save_billboard, 'SAVE BILLBOARD', Blender.sys.makename(ext='.png')) - # save_billboard('/tmp/test.png') - -if __name__=='__main__': - main() diff --git a/release/scripts/image_edit.py b/release/scripts/image_edit.py deleted file mode 100644 index cae40b74097..00000000000 --- a/release/scripts/image_edit.py +++ /dev/null @@ -1,158 +0,0 @@ -#!BPY -""" -Name: 'Edit Externally' -Blender: 242a -Group: 'Image' -Tooltip: 'Open in an application for editing. (hold Shift to configure)' -""" - -__author__ = "Campbell Barton" -__url__ = ["blender", "blenderartists.org"] -__version__ = "1.0" -__bpydoc__ = """\ -This script opens the current image in an external application for editing. - -Usage: -Choose an image for editing in the UV/Image view. - -To configure the application to open the image with, hold Shift as you -click on this menu item. - -For first time users try running the default application for your -operating system. If the application does not open you can type in -the full path. You can choose that the last entered application will -be saved as a default. - -* Note, default commants for opening an image are "start" for win32 -and "open" for macos. This will use the system default associated -application. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton 2006 -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender import Image, sys, Draw, Registry - -try: - import subprocess - import sys as py_sys - platform = py_sys.platform -except: - Draw.PupMenu('Error: Recent version of Python not installed.') - subprocess=None - -def os_run(appstring, filename): - ''' - Run the app, take into account different python versions etc - looks like python 2.6 wants a list for - ''' - - # evil trick, temp replace spaces so we can allow spaces in filenames - # also allows multiple instances of %f - appstring = appstring.replace(' ', '\t') - appstring = appstring.replace('%f', filename) - appstring = appstring.split('\t') - - print ' '.join(appstring) - - try: # only python 2.6 wants a list? - p = subprocess.Popen(appstring) - except: - p = subprocess.Popen(' '.join(appstring)) - - -def edit_extern(image=None): - - if not image: - image = Image.GetCurrent() - - if not image: # Image is None - Draw.PupMenu('ERROR: Please select active Image.') - return - if image.packed: - Draw.PupMenu('ERROR: Image is packed, unpack before editing.') - return - - imageFileName = sys.expandpath( image.filename ) - - if not sys.exists(imageFileName): - Draw.PupMenu('ERROR: Image path does not exist.') - return - - pupblock = [imageFileName.split('/')[-1].split('\\')[-1]] - - new_text= False - try: - appstring = Registry.GetKey('ExternalImageEditor', True) - appstring = appstring['path'] - - # for ZanQdo if he removed the path from the textbox totaly. ;) - Cam - if not appstring or appstring.find('%f')==-1: - new_text= True - except: - new_text= True - - if new_text: - pupblock.append('first time, set path.') - if platform == 'win32': - # Example of path to popular image editor... ;-) - # appstring = '"C:\\Program Files\\Adobe\\Photoshop CS\\photoshop.exe" "%f"' - # Have to add "cmd /c" to make sure we're using Windows shell. - appstring = 'cmd /c start "" /B "%f"' - elif platform == 'darwin': - appstring = 'open "%f"' - else: - appstring = 'gimp %f' - - appstring_but = Draw.Create(appstring) - save_default_but = Draw.Create(0) - - pupblock.append(('editor: ', appstring_but, 0, 99, 'Path to application, %f will be replaced with the image path.')) - pupblock.append(('Set Default', save_default_but, 'Store this path in the blender registry.')) - - # Only configure if Shift is held, - if Blender.Window.GetKeyQualifiers() & Blender.Window.Qual.SHIFT: - if not Draw.PupBlock('External Image Editor...', pupblock): - return - - appstring = appstring_but.val - save_default= save_default_but.val - - if save_default: - Registry.SetKey('ExternalImageEditor', {'path':appstring}, True) - - if appstring.find('%f') == -1: - Draw.PupMenu('ERROR: No filename specified! ("%f")') - return - - # ------------------------------- - - os_run(appstring, imageFileName) - - - -def main(): - edit_extern() - - -if __name__ == '__main__' and subprocess: - main() diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py deleted file mode 100644 index b3bee11c464..00000000000 --- a/release/scripts/import_dxf.py +++ /dev/null @@ -1,6225 +0,0 @@ -#!BPY - -""" -Name: 'Autodesk DXF (.dxf .dwg)' -Blender: 249 -Group: 'Import' -Tooltip: 'Import for DWG/DXF geometry data.' -""" -__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)' -__version__ = '1.12 - 2009.06.16 by migius' -__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319", - "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"] -__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"] -__bpydoc__ = """\ -This script imports objects from DWG/DXF (2d/3d) into Blender. - -This script imports 2d and 3d geometery from DXF files. -It supports DWG format too, with help of an external converter. -Supported DXF format versions: from (r2.5) r12 up to r2008. -Enhanced features are: -- configurable object filtering and geometry manipulation, -- configurable material pre-processing, -- DXF-code analyze and reporting. - -Supported DXF r12 objects: -LINE, -POINT, -SOLID, -TRACE, -TEXT, -INSERT (=block), -MINSERT (=array of blocks), -CIRCLE, -ARC, -3DFACE, -2d-POLYLINE (=in plane, incl. arc, variable-width, curve, spline), -3d-POLYLINE (=non-plane), -3d-POLYMESH, -3d-POLYFACE, -VIEW, VPORT -XREF (External Reference). - -Supported DXF>r12 objects: -ELLIPSE, -LWPOLYLINE (LightWeight Polyline), -SPLINE, -(todo v1.13) MLINE, -(todo v1.13) MTEXT - -Unsupported objects: -DXF r12: DIMENSION. -DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK - -Supported geometry: 2d and 3d DXF-objects. -Curves imported as Blender curves or meshes optionally. - -Supported layout modes: -"model space" is default, -"paper space" as option (= "layout views") - -Supported scene definition objects produced with AVE_RENDER: -scene: selection of lights assigned to the camera, -lights: DIRECT, OVERHEAD, SH_SPOT, -(wip v1.13 import of AVE_RENDER material definitions) - -Hierarchy: -Entire DXF BLOCK hierarchy is preserved after import into Blender -(BLOCKs as groups on layer19, INSERTs as dupliGroups on target layer). - -Supported properties: -visibility status, -frozen status, -thickness, -width, -color, -layer, -(todo v1.13: XDATA, grouped status) -It is recommended to use DXF-object properties for assign Blender materials. - -Notes: -- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script -- Blocks are created on layer 19 then referenced at each insert point. -- support for DXF-files up to 160MB on systems with 1GB RAM -- DXF-files with over 1500 objects decrease import performance. -The problem is not the inefficiency of python-scripting but Blenders performance -in creating new objects in scene database - probably a database management problem. - -""" - -""" -History: - v1.0 - 2007/2008/2009 by migius - planned tasks: - -- (to see more, search for "--todo--" in script code) - -- command-line-mode/batch-mode - -- in-place-editing for dupliGroups - -- support for MLINE (is exported to r12 as BLOCK*Unnamed with LINEs) - -- support for MTEXT (is exported to r12 as TEXT???) - -- blender_object.properties['dxf_layer_name'] - -- better support for long dxf-layer-names - -- add configuration file.ini handles multiple material setups - -- added f_layerFilter - -- to-check: obj/mat/group/_mapping-idea from ideasman42 - -- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs - -- "normalize Z" option to correct non-planar figures - -- LINEs need "width" in 3d-space incl vGroups - -- support width_force for LINEs/ELLIPSEs = "solidify" - -- add better support for color_index BYLAYER=256, BYBLOCK=0 - -- bug: "oneMesh" produces irregularly errors - -- bug: Registry recall from hd_cache ?? only win32 bug?? - -- support DXF-definitions of autoshade: scene, lights and cameras - -- support ortho mode for VIEWs and VPORTs as cameras - - v1.12 - 2009.06.16 by migius - d7 fix for ignored BLOCKs (e.g. *X) which are members of other BLOCKs - v1.12 - 2009.05.27 by migius - d6 bugfix negative scaled INSERTs - isLeftHand(Matrix) check - v1.12 - 2009.05.26 by migius - d5 changed to the new 2.49 method Vector.cross() - d5 bugfix WORLDY(1,1,0) to (0,1,0) - v1.12 - 2009.04.11 by migius - d4 added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter - v1.12 - 2009.03.14 by migius - d3 removed all set()functions (problem with osx/python<2.4 reported by Blinkozo) - d3 code-cleaning - v1.12 - 2009.01.14 by migius - d2 temp patch for noname BLOCKS (*X,*U,*D) - v1.12 - 2008.11.16 by migius - d1 remove try_finally: cause not supported in python <2.5 - d1 add Bezier curves bevel radius support (default 1.0) - v1.12 - 2008.08.03 by migius - c2 warningfix: relocating of globals: layersmap, oblist - c2 modif UI: buttons newScene+targetLayer moved to start panel - v1.12 - 2008.07.04 by migius - c1 added control Curve's OrderU parameter - c1 modif UI: preset buttons X-2D-3D moved to start panel - b6 added handling exception of not registered LAYERs (Hammer-HL-editor DXF output) - b5 rebuild UI: global preset 2D for Curve-Import - b5 added UI-options: PL-MESH N+N plmesh_flip and normals_out - b5 added support for SPLINEs, added control OrderU parameter - b5 rewrote draw module for NURBS_curve and Bezier_curve - v1.12 - 2008.06.22 by migius - b4 change versioning system 1.0.12 -> 1.12 - b4 print at start version-info to console - b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name) - v1.0.12: 2008.05.24 by migius - b2 added support for LWPOLYLINEs - b2 added support for ProE in readerDXF.py - v1.0.12: 2008.02.08 by migius - b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren() - a9 bugfix by non-existing tables views, vports, layers (Kai reported) - v1.0.12: 2008.01.17 by migius - a8 lately used INI-dir/filename persistently stored in Registry - a8 lately used DXF-dir/filename persistently stored in Registry - a7 fix missing layersmap{} for dxf-files without "section:layer" - a6 added support for XREF external referenced BLOCKs - a6 check for bug in AutoCAD2002:DXFr12export: ELLIPSE->POLYLINE_ARC fault angles - a6 support VIEWs and VPORTs as cameras: ortho and perspective mode - a6 save resources through ignoring unused BLOCKs (not-inserted or on frozen/blocked layers) - a6 added try_finally: f.close() for all IO-files - a6 added handling for TypeError raise - a5 bugfix f_getOCS for (0,0,z!=1.0) (ellipse in Kai's dxf) - a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs - a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH - a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs - a4 added to UI: BLOCK-(n): filter noname/hatch BLOCKs *X... - a2 g_scale_as is no more GUI_A-variable - a2 bugfix "material": negative sign color_index - a2 added support for BLOCKs defined with origin !=(0,0,0) - a1 added 'global.reLocation-vector' option - - v1.0.11: 2007.11.24 by migius - c8 added 'curve_resolution_U' option - c8 added context_sensitivity for some UI-buttons - c8 bugfix ELLIPSE rotation, added closed_variant and caps - c7 rebuild UI: new layout, grouping and meta-buttons - c6 rewritten support for ELLIPSE mesh & curve representation - c6 restore selector-buttons for DXF-drawTypes: LINE & Co - c6 change header of INI/INF-files: # at begin - c6 apply scale(1,1,1) after glob.Scale for all mesh objects, not for curve objects. - c5 fixing 'material_on' option - c4 added "analyze DXF-file" UI-option: print LAYER/BLOCK-dependences into a textfile - c3 human-formating of data in INI-Files - c2 added "caps" for closed Bezier-curves - c2 added "set elevation" UI-option - c1 rewrite POLYLINE2d-arc-segments Bezier-interpreter - b9 many bugs fixed - b9 rewrite POLYLINE2d-arc-segments trimming (clean-trim) - b8 added "import from frozen layers" UI-option - b8 added "import from paper space" UI-option - b8 support Bezier curves for LINEs incl.thickness(0.0-10.0) - b8 added meshSmooth_on for circle/arc/polyline - b8 added vertexGroups for circle/arc - b7 added width_force for ARCs/CIRCLEs = "thin_box" option - b3 cleanup code, rename f_drawArc/Bulg->f_calcArc/Bulg - b2 fixing material assignment by LAYER+COLOR - b1 fixing Bezier curves representation of POLYLINEs-arc-segments - b0 added global_scale_presets: "yard/feet/inch to meter" - - v1.0.10: 2007.10.18 by migius - a6 bugfix CircleDrawCaps for OSX - a5 added two "curve_res" UI-buttons for Bezier curves representation - a5 improved Bezier curves representation of circles/arcs: correct handlers - a4 try to fix malformed endpoints of Blender curves of ARC/POLYLINE-arc segments. - a3 bugfix: open-POLYLINEs with end_point.loc==start_point.loc - a2 bugfix: f_transform for OCS=(0,0,-1) oriented objects - a1 added "fill_on=caps" option to draw top and bottom sides of CIRCLEs and ELLIPSEs - a1 rewrite f_CIRCLE.Draw: from Mesh.Primitive to Mesh - a1 bugfix "newScene"-mode: all Cylinders/Arcs were drawn at <0,0,0>location - - v1.0.beta09: 2007.09.02 by migius - g5 redesign UI: grouping of buttons - g3 update multi-import-mode: <*.*> button - g- added multi-import-mode: (path/*) for importing many dxf-files at once - g- added import into newScene - g- redesign UI: user presets, into newScene-import - f- cleanup code - f- bugfix: thickness for Bezier/Bsplines into Blender-curves - f- BlenderWiki documentation, on-line Manual - f- added import POLYLINE-Bsplines into Blender-NURBSCurves - f- added import POLYLINE-arc-segments into Blender-BezierCurves - f- added import POLYLINE-Bezier-curves into Blender-Curves - d5 rewrite: Optimization Levels, added 'directDrawing' - d4 added: f_set_thick(controlled by ini-parameters) - d4 bugfix: face-normals in objects with minus thickness - d4 added: placeholder'Empty'-size in f_Insert.draw - d3 rewrite f_Text.Draw: added support for all Text's parameters - d2 redesign: progressbar - e- tuning by ideasman42: better use of the Py API. - c- tuning by ideasman42 - b- rewrite f_Text.Draw rotation/transform - b- bugfix: POLYLINE-segment-intersection more reliable now - b- bugfix: circle:_thic, 'Empties':no material_assignment - b- added material assignment (from layer and/or color) - a- added empty, cylinder and UVsphere for POINTs - a- added support for 2d-POLYLINE: splines, fitted curves, fitted surfaces - a- redesign f_Drawer for block_definitions - a- rewrite import into Blender-Curve-Object - - v1.0.beta08 - 2007.07.27 by migius: "full 3d"-release - l- bugfix: solid_vgroups, clean:scene.objects.new() - l- redesign UI to standard Draw.Register+FileSelector, advanced_config_option - k- bugfix UI:fileSelect() for MacOSX os.listdir() - k- added reset/save/load for config-data - k- redesign keywords/drawTypes/Draw.Create_Buttons - j- new UI using UIBlock() with own FileSelector, cause problem Window.FileSelector() - i- rewritten Class:Settings for better config-parameter management - h- bugfix: face-normals in objects with minus thickness - h- added Vertex-Groups in POLYLINE and SOLID meshes, for easy material assignment - h- beautify code, whitespace->tabs - h- added settings.thic_force switch for forcing thickness - h- added "one Mesh" option for all entities from the same Layer, sorted in
- Vertex-Groups(color_name) (fewer objects = better import performance) - g- rewrote: insert-point-handle-object is a small tetrahedron - e- bugfix: closed-polymesh3d - - rewrote: UI, type_map.keys, f_drawer, all class_f_draw(added "settings" as attribut) - - added 2d/3d-support for Polyline_Width incl. angle intersection - beta07: 2007.06.19 by migius - - added 3d-support for LWPolylines - - added 2d/3d-support for Points - beta06: 2007.06.15 by migius - - cleanup code - - added 2d/3d-support for MINSERT=BlockArray in f_drawer, added f_rotXY_Vec - beta05: 2007.06.14 by migius - - added 2d/3d-support for 3d-PolyLine, PolyMesh and PolyFace - - added Global-Scale for size control of imported scenes - beta04: 2007.06.12 by migius - - rewrote the f_drawBulge for correct import the arc-segments of Polylines - beta03: 2007.06.10 by migius - - rewrote interface - beta02: 2007.06.09 by migius - - added 3d-support for Arcs and Circles - - added support for Object_Thickness(=height) - beta01: 2007.06.08 by migius - - added 3d-support for Blocks/Inserts within nested-structures - - rewrote f_transform for correct 3d-location/3d-rotation - - added 3d-support Lines, 3dFaces - - added 2d+3d-support for Solids and Traces - - v0.9 - 2007.01 by kitsu: (for 2.43) - - first draft of true POLYLINE import - - - - v0.8 - 2006.12 by kitsu: - - first draft of object space coordinates OCS import - - - - v0.5b - 2006.10 by kitsu: (for 2.42a) - - dxfReader.py - - color_map.py - -""" - -# -------------------------------------------------------------------------- -# DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender import Mathutils, BezTriple, Draw, Registry, sys,\ -Text3d, Window, Mesh, Material, Group, Curve -#from Blender.Mathutils import Vector, Matrix -#import bpy #not used yet -#import BPyMessages - -from dxfReader import readDXF -#from dxfReader import get_name, get_layer -from dxfReader import Object as dxfObject -from dxfColorMap import color_map -from math import log10, sqrt, radians, degrees, atan, cos, sin - -# osx-patch by Blinkozo -#todo: avoid additional modules, prefer Blender-build-in test routines -#import platform -#if platform.python_version() < '2.4': -# from sets import Set as set -#from sys import version_info -#ver = '%s.%s' % version_info[0:2] -# end osx-patch - -import subprocess -import os -if os.name != 'mac': - try: - import psyco - psyco.log(Blender.Get('tempdir')+"/blender.log-psyco") - #psyco.log() - psyco.full(memory=100) - psyco.profile(0.05, memory=100) - psyco.profile(0.2) - #print 'psyco imported' - except ImportError: - print 'psyco not imported' - -print '\n\n\n' -print 'DXF/DWG-Importer v%s *** start ***' %(__version__) #--------------------- - -SCENE = None -WORLDX = Mathutils.Vector((1,0,0)) -WORLDY = Mathutils.Vector((0,1,0)) -WORLDZ = Mathutils.Vector((0,0,1)) - -G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data -G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units -G_ORIGIN_Y = 0.0 -G_ORIGIN_Z = 0.0 -MIN_DIST = 0.001 #cut-off value for sort out short-distance polyline-"duoble_vertex" -ARC_RESOLUTION = 64 #(4-500) arc/circle resolution - number of segments -ARC_RADIUS = 1.0 #(0.01-100) arc/circle radius for number of segments algorithm -CURV_RESOLUTION = 12 #(1-128) Bezier curves U-resolution -CURVARC_RESOLUTION = 4 #(3-32) resolution of circle represented as Bezier curve -THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments -MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness -MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width -TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0) -ELEVATION = 0.0 #standard elevation = coordinate Z value - -BYBLOCK = 0 -BYLAYER = 256 -TARGET_LAYER = 3 #target blender_layer -GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group -LAYER_DEF_NAME = 'AAAA' #default layer name -LAYER_DEF_COLOR = 4 #default layer color -E_M = 0 -LAB = ". wip .. todo" #"*) parts under construction" -M_OBJ = 0 - -FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE) -MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001) -INIFILE_DEFAULT_NAME = 'importDXF' -INIFILE_EXTENSION = '.ini' -INIFILE_HEADER = '#ImportDXF.py ver.1.0 config data' -INFFILE_HEADER = '#ImportDXF.py ver.1.0 analyze of DXF-data' - -AUTO = BezTriple.HandleTypes.AUTO -FREE = BezTriple.HandleTypes.FREE -VECT = BezTriple.HandleTypes.VECT -ALIGN = BezTriple.HandleTypes.ALIGN - -UI_MODE = True #activates UI-popup-print, if not multiple files imported - -#---- migration to 2.49------------------------------------------------- -if 'cross' in dir(Mathutils.Vector()): - #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!') - def M_CrossVecs(v1,v2): - return v1.cross(v2) #for up2.49 - def M_DotVecs(v1,v2): - return v1.dot(v2) #for up2.49 -else: - def M_CrossVecs(v1,v2): - return Mathutils.CrossVecs(v1,v2) #for pre2.49 - def M_DotVecs(v1,v2): - return Mathutils.DotVecs(v1,v2) #for pre2.49 - - -#-------- DWG support ------------------------------------------ -extCONV_OK = True -extCONV = 'DConvertCon.exe' -extCONV_PATH = os.path.join(Blender.Get('scriptsdir'),extCONV) -if not os.path.isfile(extCONV_PATH): - extCONV_OK = False - extCONV_TEXT = 'DWG-Importer cant find external DWG-converter (%s) in Blender script directory.|\ -More details in online Help.' %extCONV -else: - if not os.sys.platform.startswith('win'): - # check if Wine installed: - if subprocess.Popen(('which', 'winepath'), stdout=subprocess.PIPE).stdout.read().strip(): - extCONV_PATH = 'wine %s'%extCONV_PATH - else: - extCONV_OK = False - extCONV_TEXT = 'The external DWG-converter (%s) needs Wine installed on your system.|\ -More details in online Help.' %extCONV -#print 'extCONV_PATH = ', extCONV_PATH - - - -class View: #----------------------------------------------------------------- - """Class for objects representing dxf VIEWs. - """ - def __init__(self, obj, active=None): - """Expects an object of type VIEW as input. - """ - if not obj.type == 'view': - raise TypeError, "Wrong type %s for VIEW object!" %obj.type - - self.type = obj.type - self.name = obj.get_type(2)[0] -# self.data = obj.data[:] - - - self.centerX = getit(obj, 10, 0.0) #view center pointX (in DCS) - self.centerY = getit(obj, 20, 0.0) #view center pointY (in DCS) - self.height = obj.get_type(40)[0] #view height (in DCS) - self.width = obj.get_type(41)[0] #view width (in DCS) - - self.dir = [0,0,0] - self.dir[0] = getit(obj, 11, 0.0) #view directionX from target (in WCS) - self.dir[1] = getit(obj, 21, 0.0) # - self.dir[2] = getit(obj, 31, 0.0) # - - self.target = [0,0,0] - self.target[0] = getit(obj, 12, 0.0) #target pointX(in WCS) - self.target[1] = getit(obj, 22, 0.0) # - self.target[2] = getit(obj, 32, 0.0) # - - self.length = obj.get_type(42)[0] #Lens length - self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point) - self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point) - self.twist = obj.get_type(50)[0] #view twist angle in degrees - - self.flags = getit(obj, 70, 0) - self.paperspace = self.flags & 1 # - - self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable) - - def __repr__(self): - return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length) - - - def draw(self, settings): - """for VIEW: generate Blender_camera. - """ - obname = 'vw_%s' %self.name # create camera object name - #obname = 'ca_%s' %self.name # create camera object name - obname = obname[:MAX_NAMELENGTH] - - if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0: - cam= Camera.New('ortho', obname) - ob= SCENE.objects.new(cam) - cam.type = 'ortho' - cam.scale = 1.0 # for ortho cameras - else: - cam= Camera.New('persp', obname) - ob= SCENE.objects.new(cam) - cam.type = 'persp' - cam.angle = 60.0 # for persp cameras - if self.length: - #cam.angle = 2 * atan(17.5/self.length) * 180/pi - cam.lens = self.length #for persp cameras - # hack to update Camera>Lens setting (inaccurate as a focal length) - #curLens = cam.lens; cam.lens = curLens - # AutoCAD gets clip distance from target: - dist = Mathutils.Vector(self.dir).length - cam.clipEnd = dist - self.clip_back - cam.clipStart = dist - self.clip_front - - cam.drawLimits = 1 - cam.drawSize = 10 - - v = Mathutils.Vector(self.dir) -# print 'deb:view cam:', cam #------------ -# print 'deb:view self.target:', self.target #------------ -# print 'deb:view self.dir:', self.dir #------------ -# print 'deb:view self.twist:', self.twist #------------ -# print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------ - transform(v.normalize(), -self.twist, ob) - ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir) - return ob - - -class Vport: #----------------------------------------------------------------- - """Class for objects representing dxf VPORTs. - """ - def __init__(self, obj, active=None): - """Expects an object of type VPORT as input. - """ - if not obj.type == 'vport': - raise TypeError, "Wrong type %s for VPORT object!" %obj.type - - self.type = obj.type - self.name = obj.get_type(2)[0] -# self.data = obj.data[:] - #print 'deb:vport name, data:', self.name #------- - #print 'deb:vport data:', self.data #------- - - self.height = obj.get_type(40)[0] #vport height (in DCS) - self.centerX = getit(obj, 12, 0.0) #vport center pointX (in DCS) - self.centerY = getit(obj, 22, 0.0) #vport center pointY (in DCS) - self.width = self.height * obj.get_type(41)[0] #vport aspect ratio - width (in DCS) - - self.dir = [0,0,0] - self.dir[0] = getit(obj, 16, 0.0) #vport directionX from target (in WCS) - self.dir[1] = getit(obj, 26, 0.0) # - self.dir[2] = getit(obj, 36, 0.0) # - - self.target = [0,0,0] - self.target[0] = getit(obj, 17, 0.0) #target pointX(in WCS) - self.target[1] = getit(obj, 27, 0.0) # - self.target[2] = getit(obj, 37, 0.0) # - - self.length = obj.get_type(42)[0] #Lens length - self.clip_front = getit(obj, 43) #Front clipping plane (offset from target point) - self.clip_back = getit(obj, 44) #Back clipping plane (offset from target point) - self.twist = obj.get_type(51)[0] #view twist angle - - self.flags = getit(obj, 70, 0) - self.paperspace = self.flags & 1 # - - self.mode = obj.get_type(71)[0] #view mode (VIEWMODE system variable) - - def __repr__(self): - return "%s: name - %s, focus length - %s" %(self.__class__.__name__, self.name, self.length) - - def draw(self, settings): - """for VPORT: generate Blender_camera. - """ - obname = 'vp_%s' %self.name # create camera object name - #obname = 'ca_%s' %self.name # create camera object name - obname = obname[:MAX_NAMELENGTH] - - if self.target == [0,0,0] and Mathutils.Vector(self.dir).length == 1.0: - cam= Camera.New('ortho', obname) - ob= SCENE.objects.new(cam) - cam.type = 'ortho' - cam.scale = 1.0 # for ortho cameras - else: - cam= Camera.New('persp', obname) - ob= SCENE.objects.new(cam) - cam.type = 'persp' - cam.angle = 60.0 # for persp cameras - if self.length: - #cam.angle = 2 * atan(17.5/self.length) * 180/pi - cam.lens = self.length #for persp cameras - # hack to update Camera>Lens setting (inaccurate as a focal length) - #curLens = cam.lens; cam.lens = curLens - # AutoCAD gets clip distance from target: - dist = Mathutils.Vector(self.dir).length - cam.clipEnd = dist - self.clip_back - cam.clipStart = dist - self.clip_front - - cam.drawLimits = 1 - cam.drawSize = 10 - - v = Mathutils.Vector(self.dir) -# print 'deb:view cam:', cam #------------ -# print 'deb:view self.target:', self.target #------------ -# print 'deb:view self.dir:', self.dir #------------ -# print 'deb:view self.twist:', self.twist #------------ -# print 'deb:view self.clip_front=%s, self.clip_back=%s, dist=%s' %(self.clip_front, self.clip_back, dist) #------------ - transform(v.normalize(), -self.twist, ob) - ob.loc = Mathutils.Vector(self.target) + Mathutils.Vector(self.dir) - return ob - - - -class Layer: #----------------------------------------------------------------- - """Class for objects representing dxf LAYERs. - """ - def __init__(self, obj, name=None, color=None, frozen=None): - """Expects an dxfobject of type layer as input. - if no dxfobject - creates surogate layer with default parameters - """ - - if obj==None: - self.type = 'layer' - if name: self.name = name - else: self.name = LAYER_DEF_NAME - - if color: self.color = color - else: self.color = LAYER_DEF_COLOR - - if frozen!=None: self.frozen = frozen - else: self.frozen = 0 - else: - if obj.type=='layer': - self.type = obj.type - #self.data = obj.data[:] - if name: self.name = name - #self.bfname = name #--todo---see layernamesmap in f_getLayersmap --- - else: self.name = obj.get_type(2)[0] #layer name of object - - if color: self.color = color - else: self.color = obj.get_type(62)[0] #color of object - - if frozen!=None: self.frozen = frozen - else: - self.flags = obj.get_type(70)[0] - self.frozen = self.flags & 1 - - def __repr__(self): - return "%s: name - %s, color - %s" %(self.__class__.__name__, self.name, self.color) - - - -def getit(obj, typ, default=None): #------------------------------------------ - """Universal procedure for geting data from list/objects. - """ - it = default - if type(obj) == list: #if obj is a list, then searching in a list - for item in obj: - #print 'deb:getit item, type(item)', item, type(item) - try: - if item[0] == typ: - it = item[1] - break #as soon as the first found - except: - # --todo-- I found one case where item was a text instance - # that failed with no __getitem__ - pass - else: #else searching in Object with get_type-Methode - item = obj.get_type(typ) - if item: - it = item[0] - #print 'deb:getit:typ, it', typ, it #---------- - return it - - - -def get_extrusion(data): #------------------------------------------------- - """Find the axis of extrusion. - - Used to get from object_data the objects Object_Coordinate_System (ocs). - """ - #print 'deb:get_extrusion: data: \n', data #--------------- - vec = [0,0,1] - vec[0] = getit(data, 210, 0) # 210 = x - vec[1] = getit(data, 220, 0) # 220 = y - vec[2] = getit(data, 230, 1) # 230 = z - #print 'deb:get_extrusion: vec: ', vec #--------------- - return vec - - -#------------------------------------------ -def getSceneChild(name): - dudu = [i for i in SCENE.objects if i.name==name] -# dudu = [i for i in SCENE.getChildren() if i.name==name] - #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #----------------- - if dudu!=[]: return dudu[0] - return None - - -class Solid: #----------------------------------------------------------------- - """Class for objects representing dxf SOLID or TRACE. - """ - def __init__(self, obj): - """Expects an entity object of type solid or trace as input. - """ - if obj.type == 'trace': - obj.type = 'solid' - if not obj.type == 'solid': - raise TypeError, "Wrong type \'%s\' for solid/trace object!" %obj.type - - self.type = obj.type -# self.data = obj.data[:] - - self.space = getit(obj, 67, 0) - self.thic = getit(obj, 39, 0) - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.extrusion = get_extrusion(obj) - self.points = self.get_points(obj) - - - - def get_points(self, data): - """Gets start and end points for a solid type object. - - Solids have 3 or 4 points and fixed codes for each value. - """ - - # start x, y, z and end x, y, z = 0 - a = [0, 0, 0] - b = [0, 0, 0] - c = [0, 0, 0] - d = [0, 0, 0] - a[0] = getit(data, 10, None) # 10 = x - a[1] = getit(data, 20, None) # 20 = y - a[2] = getit(data, 30, 0) # 30 = z - b[0] = getit(data, 11, None) - b[1] = getit(data, 21, None) - b[2] = getit(data, 31, 0) - c[0] = getit(data, 12, None) - c[1] = getit(data, 22, None) - c[2] = getit(data, 32, 0) - out = [a,b,c] - - d[0] = getit(data, 13, None) - if d[0] != None: - d[1] = getit(data, 23, None) - d[2] = getit(data, 33, 0) - out.append(d) - #print 'deb:solid.vertices:---------\n', out #----------------------- - return out - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - def draw(self, settings): - """for SOLID: generate Blender_geometry. - """ - points = self.points - if not points: return - edges, faces = [], [] - l = len(self.points) - - obname = 'so_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - - vg_left, vg_right, vg_top, vg_bottom, vg_start, vg_end = [], [], [], [], [], [] - thic = set_thick(self.thic, settings) - if thic != 0: - thic_points = [[v[0], v[1], v[2] + thic] for v in points[:]] - if thic < 0.0: - thic_points.extend(points) - points = thic_points - else: - points.extend(thic_points) - - if l == 4: - faces = [[0,1,3,2], [4,6,7,5], [0,4,5,1], - [1,5,7,3], [3,7,6,2], [2,6,4,0]] - vg_left = [2,6,4,0] - vg_right = [1,5,7,3] - vg_top = [4,6,7,5] - vg_bottom = [0,1,3,2] - vg_start = [0,4,5,1] - vg_end = [3,7,6,2] - elif l == 3: - faces = [[0,1,2], [3,5,4], [0,3,4,1], [1,4,5,2], [2,5,3,0]] - vg_top = [3,4,5] - vg_bottom = [0,1,2] - vg_left = [2,5,3,0] - vg_right = [1,4,5,2] - vg_start = [0,3,4,1] - elif l == 2: faces = [[0,1,3,2]] - else: - if l == 4: faces = [[0,1,3,2]] - elif l == 3: faces = [[0,1,2]] - elif l == 2: edges = [[0,1]] - - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(points) # add vertices to mesh - if faces: me.faces.extend(faces) # add faces to the mesh - if edges: me.edges.extend(edges) # add faces to the mesh - - if settings.var['vGroup_on'] and not M_OBJ: - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE - if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace) - if vg_right:me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace) - if vg_top: me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace) - if vg_bottom:me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace) - if vg_start:me.addVertGroup('side.start') ; me.assignVertsToGroup('side.start', vg_start, 1.0, replace) - if vg_end: me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', vg_end, 1.0, replace) - - transform(self.extrusion, 0, ob) - - return ob - -class Line: #----------------------------------------------------------------- - """Class for objects representing dxf LINEs. - """ - def __init__(self, obj): - """Expects an entity object of type line as input. - """ - if not obj.type == 'line': - raise TypeError, "Wrong type \'%s\' for line object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - self.space = getit(obj, 67, 0) - self.thic = getit(obj, 39, 0) - #print 'deb:self.thic: ', self.thic #--------------------- - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.extrusion = get_extrusion(obj) - self.points = self.get_points(obj) - - - def get_points(self, data): - """Gets start and end points for a line type object. - - Lines have a fixed number of points (two) and fixed codes for each value. - """ - # start x,y,z and end x,y,z = 0 - a = [0, 0, 0] - b = [0, 0, 0] - a[0] = getit(data, 10, None) # 10 = x - a[1] = getit(data, 20, None) # 20 = y - a[2] = getit(data, 30, 0) # 30 = z - b[0] = getit(data, 11, None) - b[1] = getit(data, 21, None) - b[2] = getit(data, 31, 0) - out = [a,b] - return out - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - def draw(self, settings): - """for LINE: generate Blender_geometry. - """ - # Generate the geometery - #settings.var['curves_on']=False - - points = self.points - thic = set_thick(self.thic, settings) - width = 0.0 - if settings.var['lines_as'] == 4: # as thin_box - thic = settings.var['thick_min'] - width = settings.var['width_min'] - elif settings.var['lines_as'] == 3: # as thin cylinder - cyl_rad = 0.5 * settings.var['width_min'] - - elif settings.var['lines_as'] == 5: # LINE curve representation------------------------- - obname = 'li_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - - c = Curve.New(obname) # create new curve data - curve = c.appendNurb(BezTriple.New(points[0])) - curve.append(BezTriple.New(points[1])) - for point in curve: - point.handleTypes = [VECT, VECT] - point.radius = 1.0 - curve.flagU = 0 # 0 sets the curve not cyclic=open - c.setResolu(settings.var['curve_res']) - c.update() #important for handles calculation - - ob = SCENE.objects.new(c) # create a new curve_object - - #if False: # --todo-- better support for 210-group - if thic != 0.0: #hack: Blender2.45 curve-extrusion - t = thic * 0.5 - if abs(t) > 5.0: t = 5.0 * cmp(t,0) # Blender2.45 accepts only (0.0 - 5.0) - e = self.extrusion - c.setExt1(abs(t)) # curve-extrusion - ob.LocX += t * e[0] - ob.LocY += t * e[1] - ob.LocZ += t * e[2] - #c.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0) - #ob.LocZ = t + self.loc[2] - #ob.SizeZ *= abs(t) - return ob - - else: # LINE mesh representation ------------------------------ - global activObjectLayer - global activObjectName - #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #--------------------- - - if M_OBJ: obname, me, ob = makeNewObject() - else: - if activObjectLayer == self.layer and settings.var['one_mesh_on']: - obname = activObjectName - #print 'deb:line.draw obname from activObjectName: ', obname #--------------------- - ob = getSceneChild(obname) # open an existing mesh_object - #ob = SCENE.getChildren(obname) # open an existing mesh_object - #me = Mesh.Get(ob.name) # open objects mesh data - me = ob.getData(name_only=False, mesh=True) - else: - obname = 'li_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - activObjectName = ob.name - activObjectLayer = self.layer - #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #--------------------- - - faces, edges = [], [] - n = len(me.verts) - - #if settings.var['width_force']: #--todo----------- - - if thic != 0: - t, e = thic, self.extrusion - #print 'deb:thic, extr: ', t, e #--------------------- - points.extend([[v[0]+t*e[0], v[1]+t*e[1], v[2]+t*e[2]] for v in points[:]]) - faces = [[0+n, 1+n, 3+n, 2+n]] - else: - edges = [[0+n, 1+n]] - - me.verts.extend(points) # adds vertices to global mesh - if faces: me.faces.extend(faces) # add faces to the mesh - if edges: me.edges.extend(edges) # add faces to the mesh - - if settings.var['vGroup_on'] and not M_OBJ: - # entities with the same color build one vertexGroup for easier material assignment ---- - ob.link(me) # link mesh to that object - vG_name = 'color_%s' %self.color_index - if edges: faces = edges - replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD - try: - me.assignVertsToGroup(vG_name, faces[0], 1.0, replace) - #print 'deb: existed vGroup:', vG_name #--------------------- - except: - me.addVertGroup(vG_name) - me.assignVertsToGroup(vG_name, faces[0], 1.0, replace) - #print 'deb: create new vGroup:', vG_name #--------------------- - - - #print 'deb:draw:line.ob OUT activObjectName: ', activObjectName #--------------------- - return ob - - - -class Point: #----------------------------------------------------------------- - """Class for objects representing dxf POINTs. - """ - def __init__(self, obj): - """Expects an entity object of type point as input. - """ - if not obj.type == 'point': - raise TypeError, "Wrong type %s for point object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - self.space = getit(obj, 67, 0) - self.thic = getit(obj, 39, 0) - #print 'deb:self.thic: ', self.thic #--------------------- - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.extrusion = get_extrusion(obj) - self.points = self.get_points(obj) - - - def get_points(self, data): - """Gets coordinates for a point type object. - - Points have fixed codes for each value. - """ - a = [0, 0, 0] - a[0] = getit(data, 10, None) # 10 = x - a[1] = getit(data, 20, None) # 20 = y - a[2] = getit(data, 30, 0) # 30 = z - out = [a] - return out - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - def draw(self, settings): - """for POINT: generate Blender_geometry. - """ - points = self.points - obname = 'po_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - points_as = settings.var['points_as'] - thic = settings.var['thick_min'] - if thic < settings.var['dist_min']: thic = settings.var['dist_min'] - - if points_as in [1,3,4,5]: - if points_as in [1,5]: # as 'empty' - c = 'Empty' - elif points_as == 3: # as 'thin sphere' - res = settings.var['thin_res'] - c = Mesh.Primitives.UVsphere(res,res,thic) - elif points_as == 4: # as 'thin box' - c = Mesh.Primitives.Cube(thic) - ob = SCENE.objects.new(c, obname) # create a new object - transform(self.extrusion, 0, ob) - ob.loc = tuple(points[0]) - - elif points_as == 2: # as 'vertex' - global activObjectLayer - global activObjectName - #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #--------------------- - if M_OBJ: obname, me, ob = makeNewObject() - else: - if activObjectLayer == self.layer and settings.var['one_mesh_on']: - obname = activObjectName - #print 'deb:draw:point.ob obname from activObjectName: ', obname #--------------------- - ob = getSceneChild(obname) # open an existing mesh_object - #ob = SCENE.getChildren(obname) # open an existing mesh_object - me = ob.getData(name_only=False, mesh=True) - #me = Mesh.Get(ob.name) # open objects mesh data - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - activObjectName = ob.name - activObjectLayer = self.layer - #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #--------------------- - me.verts.extend(points) # add vertices to mesh - - return ob - - - -class Polyline: #----------------------------------------------------------------- - """Class for objects representing dxf POLYLINEs. - """ - def __init__(self, obj): - """Expects an entity object of type polyline as input. - """ - #print 'deb:polyline.init.START:----------------' #------------------------ - if not obj.type == 'polyline': - raise TypeError, "Wrong type %s for polyline object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - self.space = getit(obj, 67, 0) - self.elevation = getit(obj, 30, 0) - #print 'deb:elevation: ', self.elevation #--------------- - self.thic = getit(obj, 39, 0) - self.color_index = getit(obj, 62, BYLAYER) - - self.flags = getit(obj, 70, 0) - self.closed = self.flags & 1 # closed in the M direction - self.curved = self.flags & 2 # Bezier-curve-fit vertices have been added - self.spline = self.flags & 4 # NURBS-curve-fit vertices have been added - self.poly3d = self.flags & 8 # 3D-polyline - self.plmesh = self.flags & 16 # 3D-polygon mesh - self.closeN = self.flags & 32 # closed in the N direction - self.plface = self.flags & 64 # 3D-polyface mesh - self.contin = self.flags & 128 # the linetype pattern is generated continuously - - self.pltype='poly2d' # default is a 2D-polyline - if self.poly3d: self.pltype='poly3d' - elif self.plface: self.pltype='plface' - elif self.plmesh: self.pltype='plmesh' - - self.swidth = getit(obj, 40, 0) # default start width - self.ewidth = getit(obj, 41, 0) # default end width - #self.bulge = getit(obj, 42, None) # bulge of the segment - self.vectorsM = getit(obj, 71, None) # PolyMesh: expansion in M-direction / PolyFace: number of the vertices - self.vectorsN = getit(obj, 72, None) # PolyMesh: expansion in M-direction / PolyFace: number of faces - #self.resolM = getit(obj, 73, None) # resolution of surface in M direction - #self.resolN = getit(obj, 74, None) # resolution of surface in N direction - self.curvNoFitted = False - self.curvQuadrati = False - self.curvCubicBsp = False - self.curvBezier = False - curvetype = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier - if curvetype == 0: self.curvNoFitted = True - elif curvetype == 5: self.curvQuadrati = True - elif curvetype == 6: self.curvCubicBsp = True - elif curvetype == 8: self.curvBezier = True - - self.layer = getit(obj, 8, None) - self.extrusion = get_extrusion(obj) - - self.points = [] #list with vertices coordinats - self.faces = [] #list with vertices assigment to faces - #print 'deb:polyline.init.ENDinit:----------------' #------------ - - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - - def doubles_out(self, settings, d_points): - """routine to sort out of double.vertices----------------------------- - """ - minimal_dist = settings.var['dist_min'] * 0.1 - dv_count = 0 - temp_points = [] - for i in xrange(len(d_points)-1): - point = d_points[i] - point2 = d_points[i+1] - #print 'deb:double.vertex p1,p2', point, point2 #------------------------ - delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc) - if delta.length > minimal_dist: - temp_points.append(point) - else: - dv_count+=1 - #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------ - temp_points.append(d_points[-1]) #------ incl. last vertex ------------- - #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex ------------- - d_points = temp_points #-----vertex.list without "double.vertices" - #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------ - return d_points - - - def tribles_out(self, settings, d_points): - """routine to sort out of three_in_place.vertices----------------------------- - """ - minimal_dist = settings.var['dist_min'] * 0.1 - dv_count = 0 - temp_points = [] - for i in xrange(len(d_points)-2): - point1 = d_points[i] - point2 = d_points[i+1] - point3 = d_points[i+2] - #print 'deb:double.vertex p1,p2', point, point2 #------------------------ - delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc) - delta23 = Mathutils.Vector(point3.loc) - Mathutils.Vector(point2.loc) - if delta12.length < minimal_dist and delta23.length < minimal_dist: - dv_count+=1 - else: - temp_points.append(point1) - #print 'deb:drawPoly2d double.vertex sort out! count=', dv_count #------------------------ - point1 = d_points[-2] - point2 = d_points[-1] - delta12 = Mathutils.Vector(point2.loc) - Mathutils.Vector(point1.loc) - if delta12.length > minimal_dist: - temp_points.append(d_points[-2]) #------ incl. 2last vertex ------------- - temp_points.append(d_points[-1]) #------ incl. 1last vertex ------------- - #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex ------------- - d_points = temp_points #-----vertex.list without "double.vertices" - #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------ - return d_points - - - def draw(self, settings): #-------------%%%% DRAW POLYLINE %%%--------------- - """for POLYLINE: generate Blender_geometry. - """ - #print 'deb:drawPOLYLINE.START:----------------' #------------------------ - #print 'deb:POLYLINEdraw self.pltype:', self.pltype #------------------------ - #print 'deb:POLYLINEdraw self.points:\n', self.points #------------------------ - ob = [] - #---- 3dPolyFace - mesh with free topology - if self.pltype=='plface' and settings.drawTypes['plmesh']: - ob = self.drawPlFace(settings) - #---- 3dPolyMesh - mesh with ortogonal topology - elif self.pltype=='plmesh' and settings.drawTypes['plmesh']: - ob = self.drawPlMesh(settings) - - #---- 2dPolyline - plane polyline with arc/wide/thic segments - elif self.pltype=='poly2d' and settings.drawTypes['polyline']: - if settings.var['plines_as'] in [5,6]: # and self.spline: - ob = self.drawPolyCurve(settings) - else: - ob = self.drawPoly2d(settings) - - #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic) - elif self.pltype=='poly3d' and settings.drawTypes['pline3']: - if settings.var['plines3_as'] in [5,6]: # and self.spline: - ob = self.drawPolyCurve(settings) - else: - ob = self.drawPoly2d(settings) - - #---- Spline - curved polyline (thin segments = without arc/wide/thic) - elif self.pltype=='spline' and settings.drawTypes['spline']: - if settings.var['splines_as'] in [5,6]: - ob = self.drawPolyCurve(settings) - else: - ob = self.drawPoly2d(settings) - return ob - - - def drawPlFace(self, settings): #---- 3dPolyFace - mesh with free topology - """Generate the geometery of polyface. - """ - #print 'deb:drawPlFace.START:----------------' #------------------------ - points = [] - faces = [] - #print 'deb:len of pointsList ====== ', len(self.points) #------------------------ - for point in self.points: - if point.face: - faces.append(point.face) - else: - points.append(point.loc) - - if settings.var['plmesh_flip']: # ---------------------- - for face in faces: - face.reverse() - face = [face[-1]] + face[:-1] - - #print 'deb:drawPlFace: len of points_list:\n', len(points) #----------------------- - #print 'deb:drawPlFace: len of faces_list:\n', len(faces) #----------------------- - #print 'deb:drawPlFace: points_list:\n', points #----------------------- - #print 'deb:drawPlFace: faces_list:\n', faces #----------------------- - obname = 'pf_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(points) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - if settings.var['normals_out']: # ---------------------- - #me.flipNormals() - me.recalcNormals(0) - #me.update() - #print 'deb:drawPlFace: len of me.faces:\n', len(me.faces) #----------------------- - - if settings.var['meshSmooth_on']: # ---------------------- - for i in xrange(len(me.faces)): - me.faces[i].smooth = True - #me.Mode(AUTOSMOOTH) - transform(self.extrusion, 0, ob) - #print 'deb:drawPlFace.END:----------------' #------------------------ - return ob - - - - def drawPlMesh(self, settings): #---- 3dPolyMesh - mesh with orthogonal topology - """Generate the geometery of polymesh. - """ - #print 'deb:polymesh.draw.START:----------------' #------------------------ - #points = [] - #print 'deb:len of pointsList ====== ', len(self.points) #------------------------ - faces = [] - m = self.vectorsM - n = self.vectorsN - for j in xrange(m - 1): - for i in xrange(n - 1): - nn = j * n - faces.append([nn+i, nn+i+1, nn+n+i+1, nn+n+i]) - - if self.closed: #mesh closed in N-direction - nn = (m-1)*n - for i in xrange(n - 1): - faces.append([nn+i, nn+i+1, i+1, i]) - - if self.closeN: #mesh closed in M-direction - for j in xrange(m-1): - nn = j * n - faces.append([nn+n-1, nn, nn+n, nn+n-1+n]) - - if self.closed and self.closeN: #mesh closed in M/N-direction - faces.append([ (n*m)-1, (m-1)*n, 0, n-1]) - - #print 'deb:len of points_list:\n', len(points) #----------------------- - #print 'deb:faces_list:\n', faces #----------------------- - obname = 'pm_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend([point.loc for point in self.points]) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - if settings.var['normals_out']: # ---------------------- - #me.flipNormals() - me.recalcNormals(0) - #me.update() - if settings.var['meshSmooth_on']: # ---------------------- - for i in xrange(len(faces)): - me.faces[i].smooth = True - #me.Mode(AUTOSMOOTH) - - transform(self.extrusion, 0, ob) - #print 'deb:polymesh.draw.END:----------------' #------------------------ - return ob - - - def drawPolyCurve(self, settings): #---- Polyline - draw as Blender-curve - """Generate the geometery of polyline as Blender-curve. - """ - #print 'deb:polyline2dCurve.draw.START:----------------' #--- - if len(self.points) < 2: - #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #--------- - return - - if self.spline: pline_typ = 'ps' # Polyline-NURBSpline - elif self.curved: pline_typ = 'pc' # Polyline-BezierCurve - else: pline_typ = 'pl' # Polyline classic - obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name - obname = obname[:MAX_NAMELENGTH] - d_points = [] - - if settings.var['Z_force_on']: - self.elevation = settings.var['Z_elev'] - for point in self.points: - point.loc[2] = self.elevation - d_points.append(point) - else: #for DXFr10-format: update all points[].loc[2] == None -> 0.0 - for point in self.points: - if point.loc[2] == None: - point.loc[2] = self.elevation - d_points.append(point) - - #d_points = self.tribles_out(settings, d_points) - #d_points = self.doubles_out(settings, d_points) - #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------ - - thic = set_thick(self.thic, settings) - if thic != 0.0: #hack: Blender<2.45 curve-extrusion - LocZ = d_points[0].loc[2] - temp_points = [] - for point in d_points: - point.loc[2] = 0.0 - temp_points.append(point) - d_points = temp_points - - #print 'deb:polyline2dCurve.draw d_points=', d_points #--------------- - pline = Curve.New(obname) # create new curve data - #pline.setResolu(24) #--todo----- - - if self.spline: # NURBSplines-----OK----- - #print 'deb:polyline2dCurve.draw self.spline!' #--------------- - nurbs_points = [] - for d in d_points: - pkt = d.loc - pkt.append(d.weight) - nurbs_points.append(pkt) - firstpoint = nurbs_points[0] - curve = pline.appendNurb(firstpoint) - curve.setType(4) # set curve_type NURBS - print 'deb: dir(curve):', dir(curve[-1]) #---------------- - for point in nurbs_points[1:]: - curve.append(point) - #TODO: what is the trick for bevel radius? curve[-1].radius = 1.0 - if self.closed: - curve.flagU = 1+0 # Set curve cyclic=close and uni - else: - curve.flagU = 0+2 # Set curve not cyclic=open - try: curve.orderU = 5 # works only with >2.46svn080625 - except AttributeError: pass - #print 'deb: dir(curve):', dir(curve) #---------------- - - elif self.curved: #--SPLINE as Bezier-curves---wip------ - #print 'deb:polyline2dCurve.draw self.curved!' #--------------- - begtangent, endtangent = None, None - if d_points[0].tangent: - begtangent = d_points[0] - d_points = d_points[1:] - if d_points[-1].tangent: - endtangent = d_points[-1] - d_points = d_points[:-1] - curve = pline.appendNurb(BezTriple.New(d_points[0])) - for p in d_points[1:]: - curve.append(BezTriple.New(p)) - for point in curve: - point.handleTypes = [AUTO, AUTO] - point.radius = 1.0 - #curve.setType(1) #Bezier curve - if self.closed: - curve.flagU = 5 #1 # Set curve cyclic=close - else: - curve.flagU = 4 #0 # Set curve not cyclic=open - if begtangent: - #print 'deb:polyline2dCurve.draw curve[0].vec:', curve[0].vec #----- - #print 'deb:polyline2dCurve.draw begtangent:', begtangent #----- - p0h1,p0,p0h2 = curve[0].vec - p0h1 = [p0h1[i]+begtangent[i] for i in range(3)] - curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2)) - curve[0].handleTypes = [FREE, ALIGN] #remi--todo----- - curve[0].radius = 1.0 - if endtangent: - #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #----- - #print 'deb:polyline2dCurve.draw endtangent:', endtangent #----- - p0h1,p0,p0h2 = curve[-1].vec - p0h2 = [p0h2[i]+endtangent[i] for i in range(3)] - #print 'deb:drawPlineCurve: p0h2:', p0h2 #---------- - curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2)) - #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #----- - curve[-1].handleTypes = [ALIGN, FREE] #remi--todo----- - curve[-1].radius = 1.0 - - - - else: #-- only straight line- and arc-segments----OK------ - #print 'deb:polyline2dCurve.draw curve:', curve #----- - points = [] - arc_res = settings.var['curve_arc'] - prevHandleType = VECT - #d_points.append(d_points[0]) #------ first vertex added at the end of list -------- - #curve.setType(0) #polygon_type of Blender_curve - for i in xrange(len(d_points)): - point1 = d_points[i] - #point2 = d_points[i+1] - #----- optimised Bezier-Handles calculation -------------------------------- - #print 'deb:drawPlineCurve: i:', i #--------- - if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed): - if i == len(d_points)-1: point2 = d_points[0] - else: point2 = d_points[i+1] - - - # calculate additional points for bulge - VectorTriples = calcBulge(point1, point2, arc_res, triples=True) - - if prevHandleType == FREE: - #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #--------- - VectorTriples[0][:3] = prevHandleVect - #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #--------- - - if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0])) - else: curve.append(BezTriple.New(VectorTriples[0])) - curve[-1].handleTypes = [prevHandleType, FREE] - curve[-1].radius = 1.0 - - for p in VectorTriples[1:-1]: - curve.append(BezTriple.New(p)) - curve[-1].handleTypes = [FREE, FREE] - curve[-1].radius = 1.0 - - prevHandleVect = VectorTriples[-1][:3] - prevHandleType = FREE - #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #--------- - else: - #print 'deb:drawPlineCurve: else' #---------- - if prevHandleType == FREE: - VectorTriples = prevHandleVect + list(point1) + list(point1) - #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #--------- - curve.append(BezTriple.New(VectorTriples)) - curve[-1].handleTypes = [FREE, VECT] - prevHandleType = VECT - curve[-1].radius = 1.0 - else: - if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc)) - else: curve.append(BezTriple.New(point1.loc)) - curve[-1].handleTypes = [VECT, VECT] - curve[-1].radius = 1.0 - #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #---------- - - if self.closed: - curve.flagU = 1 # Set curve cyclic=close - if prevHandleType == FREE: - #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #---------- - #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #---------- - prevHandleType2 = curve[0].handleTypes[1] - p0h1,p0,p0h2 = curve[0].vec - #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #---------- - p0h1 = prevHandleVect - #p0h1 = [0,0,0] - #print 'deb:drawPlineCurve:closed p0h1:', p0h1 #---------- - #curve[0].vec = [p0h1,p0,p0h2] - curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2)) - - curve[0].handleTypes = [FREE,prevHandleType2] - curve[0].radius = 1.0 - #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #---------- - #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #---------- - else: - curve[0].handleTypes[0] = VECT - curve[0].radius = 1.0 - else: - curve.flagU = 0 # Set curve not cyclic=open - - if settings.var['fill_on']: - pline.setFlag(6) # 2+4 set top and button caps - else: - pline.setFlag(pline.getFlag() & ~6) # dont set top and button caps - - pline.setResolu(settings.var['curve_res']) - pline.update() - ob = SCENE.objects.new(pline) # create a new curve_object - - if thic != 0.0: #hack: Blender<2.45 curve-extrusion - thic = thic * 0.5 - pline.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0) - ob.LocZ = thic + LocZ - - transform(self.extrusion, 0, ob) - if thic != 0.0: - ob.SizeZ *= abs(thic) - - #print 'deb:polyline2dCurve.draw.END:----------------' #----- - return ob - - - def drawPoly2d(self, settings): #---- 2dPolyline - plane lines/arcs with wide/thic - """Generate the geometery of regular polyline. - """ - #print 'deb:polyline2d.draw.START:----------------' #------------------------ - points = [] - d_points = [] - swidths = [] - ewidths = [] - swidth_default = self.swidth #default start width of POLYLINEs segments - ewidth_default = self.ewidth #default end width of POLYLINEs segments - #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------ - thic = set_thick(self.thic, settings) - if self.spline: pline_typ = 'ps' - elif self.curved: pline_typ = 'pc' - else: pline_typ = 'pl' - obname = '%s_%s' %(pline_typ, self.layer) # create object_name from layer name - obname = obname[:MAX_NAMELENGTH] - - if len(self.points) < 2: - #print 'deb:drawPoly2d exit, cause POLYLINE has less than 2 vertices' #--------- - return - - if settings.var['Z_force_on']: - self.elevation = settings.var['Z_elev'] - for point in self.points: - point.loc[2] = self.elevation - d_points.append(point) - else: #for DXFr10-format: update all non-existing LocZ points[].loc[2] == None -> 0.0 elevation - for point in self.points: - if point.loc[2] == None: - point.loc[2] = self.elevation - d_points.append(point) - #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------ - #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------ - - - #if closed polyline, add duplic of the first vertex at the end of pointslist - if self.closed: #new_b8 - if d_points[-1].loc != d_points[0].loc: # if not equal, then set the first at the end of pointslist - d_points.append(d_points[0]) - else: - if d_points[-1].loc == d_points[0].loc: # if equal, then set to closed, and modify the last point - d_points[-1] = d_points[0] - self.closed = True - #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------ - #print 'deb:drawPoly2d d_pointsList ======:\n ', d_points #------------------------ - - d_points = self.doubles_out(settings, d_points) - #print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------ - - #print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------ - if len(d_points) < 2: #if too few vertex, then return - #print 'deb:drawPoly2d corrupted Vertices' #--------- - return - - # analyze of straight- and bulge-segments - # generation of additional points for bulge segments - arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad']) - wide_segment_exist = False - bulg_points = [] # for each point set None (or center for arc-subPoints) - for i in xrange(len(d_points)-1): - point1 = d_points[i] - point2 = d_points[i+1] - #print 'deb:drawPoly2d_bulg tocalc.point1:', point1 #------------------------ - #print 'deb:drawPoly2d_bulg tocalc.point2:', point2 #------------------------ - - swidth = point1.swidth - ewidth = point1.ewidth - #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------ - if swidth == None: swidth = swidth_default - if ewidth == None: ewidth = ewidth_default - if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True - #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------ - - if settings.var['width_force']: # force minimal width for thin segments - width_min = settings.var['width_min'] - if swidth < width_min: swidth = width_min - if ewidth < width_min: ewidth = width_min - if not settings.var['width_on']: # then force minimal width for all segments - swidth = width_min - ewidth = width_min - - #if point1.bulge and (i < (len(d_points)-1) or self.closed): - if point1.bulge and i < (len(d_points)-1): #10_b8 - verts, center = calcBulge(point1, point2, arc_res) #calculate additional points for bulge - points.extend(verts) - delta_width = (ewidth - swidth) / len(verts) - width_list = [swidth + (delta_width * ii) for ii in xrange(len(verts)+1)] - swidths.extend(width_list[:-1]) - ewidths.extend(width_list[1:]) - bulg_list = [center for ii in xrange(len(verts))] - #the last point in bulge has index False for better indexing of bulg_end! - bulg_list[-1] = None - bulg_points.extend(bulg_list) - - else: - points.append(point1.loc) - swidths.append(swidth) - ewidths.append(ewidth) - bulg_points.append(None) - points.append(d_points[-1].loc) - - - #--calculate width_vectors: left-side- and right-side-points ---------------- - # 1.level:IF width --------------------------------------- - if (settings.var['width_on'] and wide_segment_exist) or settings.var['width_force']: - #new_b8 points.append(d_points[0].loc) #temporarly add first vertex at the end (for better loop) - dist_min05 = 0.5 * settings.var['dist_min'] #minimal width for zero_witdh - - pointsLs = [] # list of left-start-points - pointsLe = [] # list of left-end-points - pointsRs = [] # list of right-start-points - pointsRe = [] # list of right-end-points - pointsW = [] # list of all border-points - #rotMatr90 = Mathutils.Matrix(rotate 90 degree around Z-axis) = normalvectorXY - rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1]) - bulg_in = False - last_bulg_point = False - for i in xrange(len(points)-1): - point1 = points[i] - point2 = points[i+1] - point1vec = Mathutils.Vector(point1) - point2vec = Mathutils.Vector(point2) - swidth05 = swidths[i] * 0.5 - ewidth05 = ewidths[i] * 0.5 - if swidth05 == 0: swidth05 = dist_min05 - if ewidth05 == 0: ewidth05 = dist_min05 - normal_vector = rotMatr90 * (point2vec-point1vec).normalize() - if last_bulg_point: - last_bulg_point = False - bulg_in = True - elif bulg_points[i] != None: - centerVec = Mathutils.Vector(bulg_points[i]) - if bulg_points[i+1] == None: last_bulg_point = True - bulg_in = True - else: bulg_in = False - - if bulg_in: - #makes clean intersections for arc-segments - radius1vec = point1vec - centerVec - radius2vec = point2vec - centerVec - angle = Mathutils.AngleBetweenVecs(normal_vector, radius1vec) - if angle < 90.0: - normal_vector1 = radius1vec.normalize() - normal_vector2 = radius2vec.normalize() - else: - normal_vector1 = - radius1vec.normalize() - normal_vector2 = - radius2vec.normalize() - - swidth05vec = swidth05 * normal_vector1 - ewidth05vec = ewidth05 * normal_vector2 - pointsLs.append(point1vec + swidth05vec) #vertex left start - pointsRs.append(point1vec - swidth05vec) #vertex right start - pointsLe.append(point2vec + ewidth05vec) #vertex left end - pointsRe.append(point2vec - ewidth05vec) #vertex right end - - else: - swidth05vec = swidth05 * normal_vector - ewidth05vec = ewidth05 * normal_vector - pointsLs.append(point1vec + swidth05vec) #vertex left start - pointsRs.append(point1vec - swidth05vec) #vertex right start - pointsLe.append(point2vec + ewidth05vec) #vertex left end - pointsRe.append(point2vec - ewidth05vec) #vertex right end - - # additional last point is also calculated - #pointsLs.append(pointsLs[0]) - #pointsRs.append(pointsRs[0]) - #pointsLe.append(pointsLe[0]) - #pointsRe.append(pointsRe[0]) - - pointsLc, pointsRc = [], [] # lists Left/Right corners = intersection points - - # 2.level:IF width and corner-trim - if settings.var['pl_trim_on']: #optional clean corner-intersections - # loop preset - # set STARTpoints of the first point points[0] - if not self.closed: - pointsLc.append(pointsLs[0]) - pointsRc.append(pointsRs[0]) - else: - pointsLs.append(pointsLs[0]) - pointsRs.append(pointsRs[0]) - pointsLe.append(pointsLe[0]) - pointsRe.append(pointsRe[0]) - points.append(points[0]) - vecL3, vecL4 = pointsLs[0], pointsLe[0] - vecR3, vecR4 = pointsRs[0], pointsRe[0] - lenL = len(pointsLs)-1 - #print 'deb:drawPoly2d pointsLs():\n', pointsLs #---------------- - #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #---------------- - bulg_in = False - last_bulg_point = False - - # LOOP: makes (ENDpoints[i],STARTpoints[i+1]) - for i in xrange(lenL): - if bulg_points[i] != None: - if bulg_points[i+1] == None: #makes clean intersections for arc-segments - last_bulg_point = True - if not bulg_in: - bulg_in = True - #pointsLc.extend((points[i], pointsLs[i])) - #pointsRc.extend((points[i], pointsRs[i])) - vecL1, vecL2 = vecL3, vecL4 - vecR1, vecR2 = vecR3, vecR4 - vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1] - vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1] - #compute left- and right-cornerpoints - #cornerpointL = Geometry.LineIntersect2D(vec1, vec2, vec3, vec4) - cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4) - cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4) - #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #------------- - #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #------------- - - # IF not cornerpoint THEN check if identic start-endpoints (=collinear segments) - if cornerpointL == None or cornerpointR == None: - if vecL2 == vecL3 and vecR2 == vecR3: - #print 'deb:drawPoly2d pointVec: ####### identic ##########' #---------------- - pointsLc.append(pointsLe[i]) - pointsRc.append(pointsRe[i]) - else: - pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1])) - pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1])) - else: - cornerpointL = cornerpointL[0] # because Mathutils.LineIntersect() -> (pkt1,pkt2) - cornerpointR = cornerpointR[0] - #print 'deb:drawPoly2d cornerpointL: ', cornerpointL #------------- - #print 'deb:drawPoly2d cornerpointR: ', cornerpointR #------------- - pointVec0 = Mathutils.Vector(points[i]) - pointVec = Mathutils.Vector(points[i+1]) - pointVec2 = Mathutils.Vector(points[i+2]) - #print 'deb:drawPoly2d pointVec0: ', pointVec0 #------------- - #print 'deb:drawPoly2d pointVec: ', pointVec #------------- - #print 'deb:drawPoly2d pointVec2: ', pointVec2 #------------- - # if diststance(cornerL-center-cornerR) < limiter * (seg1_endWidth + seg2_startWidth) - max_cornerDist = (vecL2 - vecR2).length + (vecL3 - vecR3).length - is_cornerDist = (cornerpointL - pointVec).length + (cornerpointR - pointVec).length - #corner_angle = Mathutils.AngleBetweenVecs((pointVec0 - pointVec),(pointVec - pointVec2)) - #print 'deb:drawPoly2d corner_angle: ', corner_angle #------------- - #print 'deb:drawPoly2d max_cornerDist, is_cornerDist: ', max_cornerDist, is_cornerDist #------------- - #if abs(corner_angle) < 90.0: - # intersection --------- limited by TRIM_LIMIT (1.0 - 5.0) - if is_cornerDist < max_cornerDist * settings.var['pl_trim_max']: - # clean corner intersection - pointsLc.append(cornerpointL) - pointsRc.append(cornerpointR) - else: - pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1])) - pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1])) - if not self.closed: - pointsLc.append(pointsLe[-1]) - pointsRc.append(pointsRe[-1]) - - # 2.level:IF width but no-trim - else: - # loop preset - # set STARTpoints of the first point points[0] - if not self.closed: - pointsLc.append(pointsLs[0]) - pointsRc.append(pointsRs[0]) - else: - pointsLs.append(pointsLs[0]) - pointsRs.append(pointsRs[0]) - pointsLe.append(pointsLe[0]) - pointsRe.append(pointsRe[0]) - points.append(points[0]) - vecL3, vecL4 = pointsLs[0], pointsLe[0] - vecR3, vecR4 = pointsRs[0], pointsRe[0] - lenL = len(pointsLs)-1 - #print 'deb:drawPoly2d pointsLs():\n', pointsLs #---------------- - #print 'deb:drawPoly2d lenL, len.pointsLs():', lenL,',', len(pointsLs) #---------------- - bulg_in = False - last_bulg_point = False - - # LOOP: makes (ENDpoints[i],STARTpoints[i+1]) - for i in xrange(lenL): - vecL1, vecL2 = vecL3, vecL4 - vecR1, vecR2 = vecR3, vecR4 - vecL3, vecL4 = pointsLs[i+1], pointsLe[i+1] - vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1] - if bulg_points[i] != None: - #compute left- and right-cornerpoints - cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4) - cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4) - pointsLc.append(cornerpointL[0]) - pointsRc.append(cornerpointR[0]) - else: # IF non-bulg - pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1])) - pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1])) - if not self.closed: - pointsLc.append(pointsLe[-1]) - pointsRc.append(pointsRe[-1]) - - len1 = len(pointsLc) - #print 'deb:drawPoly2d len1:', len1 #----------------------- - #print 'deb:drawPoly2d len1 len(pointsLc),len(pointsRc):', len(pointsLc),len(pointsRc) #----------------------- - pointsW = pointsLc + pointsRc # all_points_List = left_side + right_side - #print 'deb:drawPoly2d pointsW():\n', pointsW #---------------- - - # 2.level:IF width and thickness --------------------- - if thic != 0: - thic_pointsW = [] - thic_pointsW.extend([[point[0], point[1], point[2]+thic] for point in pointsW]) - if thic < 0.0: - thic_pointsW.extend(pointsW) - pointsW = thic_pointsW - else: - pointsW.extend(thic_pointsW) - faces = [] - f_start, f_end = [], [] - f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)] - f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)] - f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)] - f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)] - - if self.closed: - f_bottom.append([len1-1, 0, len1, len1+len1-1]) #bottom face - f_top.append( [len1+len1+len1-1, len1+len1+len1+len1-1, len1+len1+len1, len1+len1+0]) #top face - f_left.append( [0, len1-1, len1+len1+len1-1, len1+len1]) #left face - f_right.append( [len1, len1+len1+len1, len1+len1+len1+len1-1, len1+len1-1]) #right face - else: - f_start = [[0, len1, len1+len1+len1, len1+len1]] - f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]] - - faces = f_left + f_right + f_bottom + f_top + f_start + f_end - #faces = f_bottom + f_top - #faces = f_left + f_right + f_start + f_end - #print 'deb:faces_list:\n', faces #----------------------- - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(pointsW) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - # The mesh must first be linked to an object so the method knows which object to update. - # This is because vertex groups in Blender are stored in the object -- not in the mesh, - # which may be linked to more than one object. - if settings.var['vGroup_on'] and not M_OBJ: - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD - vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] - for v in f_left: vg_left.extend(v) - for v in f_right: vg_right.extend(v) - for v in f_top: vg_top.extend(v) - for v in f_bottom: vg_bottom.extend(v) - me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace) - me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace) - me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace) - me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace) - if not self.closed: - me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace) - me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace) - - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - #if self.spline or self.curved: - smooth_len = len(f_left) + len(f_right) - for i in xrange(smooth_len): - me.faces[i].smooth = True - #me.Modes(AUTOSMOOTH) - - # 2.level:IF width, but no-thickness --------------------- - else: - faces = [] - faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)] - if self.closed: - faces.append([len1, 0, len1-1, len1+len1-1]) - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(pointsW) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - - # 1.level:IF no-width, but thickness --------------------- - elif thic != 0: - len1 = len(points) - thic_points = [] - thic_points.extend([[point[0], point[1], point[2]+thic] for point in points]) - if thic < 0.0: - thic_points.extend(points) - points = thic_points - else: - points.extend(thic_points) - faces = [] - faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] - if self.closed: - faces.append([len1-1, 0, len1, 2*len1-1]) - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(points) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - #if self.spline or self.curved: - for i in xrange(len(faces)): - me.faces[i].smooth = True - #me.Modes(AUTOSMOOTH) - - # 1.level:IF no-width and no-thickness --------------------- - else: - edges = [[num, num+1] for num in xrange(len(points)-1)] - if self.closed: - edges.append([len(points)-1, 0]) - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(points) # add vertices to mesh - me.edges.extend(edges) # add edges to the mesh - - transform(self.extrusion, 0, ob) - #print 'deb:polyline.draw.END:----------------' #----------------------- - return ob - - - - -class Vertex(object): #----------------------------------------------------------------- - """Generic vertex object used by POLYLINEs, (and maybe others). - also used by class_LWPOLYLINEs but without obj-parameter - """ - - def __init__(self, obj=None): - """Initializes vertex data. - - The optional obj arg is an entity object of type vertex. - """ - #print 'deb:Vertex.init.START:----------------' #----------------------- - self.loc = [0,0,0] - self.face = [] - self.swidth = None #0 - self.ewidth = None #0 - self.bulge = 0 - self.tangent = False - self.weight = 1.0 - if obj is not None: - if not obj.type == 'vertex': - raise TypeError, "Wrong type %s for vertex object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - self.get_props(obj) - else: - pass - #print 'deb:Vertex.init.END:----------------' #------------------------ - - - def get_props(self, data): - """Gets coords for a VERTEX type object. - - Each vert can have a number of properties. - Verts should be coded as - 10:xvalue - 20:yvalue - 40:startwidth or 0 - 41:endwidth or 0 - 42:bulge or 0 - """ - self.x = getit(data, 10, None) - self.y = getit(data, 20, None) - self.z = getit(data, 30, None) - - self.flags = getit(data, 70, 0) # flags - self.curved = self.flags&1 # Bezier-curve-fit:additional-vertex - self.curved_t = self.flags&2 # Bezier-curve-fit:tangent exists - self.spline = self.flags&8 # NURBSpline-fit:additional-vertex - self.spline_c = self.flags&16 # NURBSpline-fit:control-vertex - self.poly3d = self.flags&32 # polyline3d:control-vertex - self.plmesh = self.flags&64 # polymesh3d:control-vertex - self.plface = self.flags&128 # polyface - - # if PolyFace.Vertex with Face_definition - if self.curved_t: - self.curve_tangent = getit(data, 50, None) # curve_tangent - if not self.curve_tangent==None: - self.tangent = True - #elif self.spline_c: # NURBSpline:control-vertex - # self.weight = getit(data, 41, 1.0) # weight od control point - - elif self.plface and not self.plmesh: - v1 = getit(data, 71, 0) # polyface:Face.vertex 1. - v2 = getit(data, 72, 0) # polyface:Face.vertex 2. - v3 = getit(data, 73, 0) # polyface:Face.vertex 3. - v4 = getit(data, 74, None) # polyface:Face.vertex 4. - self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1] - if v4 != None: - if abs(v4) != abs(v1): - self.face.append(abs(v4)-1) - else: #--parameter for polyline2d - self.swidth = getit(data, 40, None) # start width - self.ewidth = getit(data, 41, None) # end width - self.bulge = getit(data, 42, 0) # bulge of segment - - - def __len__(self): - return 3 - - - def __getitem__(self, key): - return self.loc[key] - - - def __setitem__(self, key, value): - if key in [0,1,2]: - self.loc[key] - - - def __iter__(self): - return self.loc.__iter__() - - - def __str__(self): - return str(self.loc) - - - def __repr__(self): - return "Vertex %s, swidth=%s, ewidth=%s, bulge=%s, face=%s" %(self.loc, self.swidth, self.ewidth, self.bulge, self.face) - - - def getx(self): - return self.loc[0] - def setx(self, value): - self.loc[0] = value - x = property(getx, setx) - - - def gety(self): - return self.loc[1] - def sety(self, value): - self.loc[1] = value - y = property(gety, sety) - - - def getz(self): - return self.loc[2] - def setz(self, value): - self.loc[2] = value - z = property(getz, setz) - - - -class Spline(Polyline): #----------------------------------------------------------------- - """Class for objects representing dxf SPLINEs. - """ - """Expects an entity object of type spline as input. -100 - Subclass marker (AcDbSpline) -210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector -70 - Spline flag (bit coded): - 1 = Closed spline - 2 = Periodic spline - 4 = Rational spline - 8 = Planar - 16 = Linear (planar bit is also set) -71 - Degree of the spline curve -72 - Number of knots -73 - Number of control points -74 - Number of fit points (if any) -42 - Knot tolerance (default = 0.0000001) -43 - Control-point tolerance (default = 0.0000001) -44 - Fit tolerance (default = 0.0000000001) -12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS). -13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS) -40 - Knot value (one entry per knot) -41 - Weight (if not 1); with multiple group pairs, are present if all are not 1 -10,20, 30 - Control points (in WCS) one entry per control point. -DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point) -11,21, 31 - Fit points (in WCS) one entry per fit point. - X,Y,Z values of fit points (in WCS) (one entry per fit point) - """ - def __init__(self, obj): - #print 'deb:Spline.START:----------------' #------------------------ - if not obj.type == 'spline': - raise TypeError, "Wrong type %s for spline object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.num_points = obj.get_type(73)[0] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - - self.color_index = getit(obj, 62, BYLAYER) - - #self.elevation = getit(obj, 30, 0) - self.thic = 0 # getit(obj, 39, 0) - - width = 0 - self.swidth = width # default start width - self.ewidth = width # default end width - - self.flags = getit(obj, 70, 0) - self.closed = self.flags & 1 # closed spline - self.period = self.flags & 2 # Periodic spline - self.ration = self.flags & 4 # Rational spline - self.planar = self.flags & 8 # Planar - self.linear = self.flags & 16 # Linear (and Planar) - - self.curvNoFitted = False - self.curvQuadrati = False - self.curvCubicBsp = False - self.curvBezier = False - self.degree = getit(obj, 71, 0) # Degree of the spline curve - if self.degree == 0: self.curvNoFitted = True - elif self.degree == 1: self.curvQuadrati = True - elif self.degree == 2: self.curvCubicBsp = True - #elif self.degree == 3: self.curvBezier = True - #elif self.degree == 3: self.spline = True - - self.knotpk_len = getit(obj, 72, 0) # Number of knots - self.ctrlpk_len = getit(obj, 73, 0) # Number of control points - self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any) - - #TODO: import SPLINE as Bezier curve directly, possible? - #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------ - #self.fit_pk_len = 0 # temp for debug - if self.fit_pk_len and settings.var['splines_as']==5: - self.spline = False - self.curved = True - else: - self.spline = True - self.curved = False - - self.knotpk_tol = getit(obj, 42, 0.0000001) # Knot tolerance (default = 0.0000001) - self.ctrlpk_tol = getit(obj, 43, 0.0000001) # Control-point tolerance (default = 0.0000001) - self.fit_pk_tol = getit(obj, 44, 0.0000000001) # Fit tolerance (default = 0.0000000001) - - self.layer = getit(obj, 8, None) - self.extrusion = get_extrusion(obj) - - self.pltype = 'spline' # spline is a 2D- or 3D-polyline - - self.points = self.get_points(obj.data) - #self.knots_val = self.get_knots_val(obj.data) # 40 - Knot value (one entry per knot) - #self.knots_wgh = self.get_knots_wgh(obj.data) # 41 - Weight (default 1) - - #print 'deb:Spline obj.data:\n', obj.data #------------------------ - #print 'deb:Spline self.points:\n', self.points #------------------------ - #print 'deb:Spline.ENDinit:----------------' #------------------------ - - - def get_points(self, data): - """Gets points for a spline type object. - - Splines have fixed number of verts, and - each vert can have a number of properties. - Verts should be coded as - 10:xvalue - 20:yvalue - for each vert - """ - point = None - points = [] - pointend = None - #point = Vertex() - if self.spline: # NURBSpline definition - for item in data: - #print 'deb:Spline.get_points spilne_item:', item #------------------------ - if item[0] == 10: # control point - if point: points.append(point) - point = Vertex() - point.curved = True - point.x = item[1] - elif item[0] == 20: # 20 = y - point.y = item[1] - elif item[0] == 30: # 30 = z - point.z = item[1] - elif item[0] == 41: # 41 = weight - point.weight = item[1] - #print 'deb:Spline.get_points control point:', point #------------------------ - - elif self.curved: # Bezier definition - for item in data: - #print 'deb:Spline.get_points curved_item:', item #------------------------ - if item[0] == 11: # fit point - if point: points.append(point) - point = Vertex() - point.tangent = False - point.x = item[1] - elif item[0] == 21: # 20 = y - point.y = item[1] - elif item[0] == 31: # 30 = z - point.z = item[1] - #print 'deb:Spline.get_points fit point:', point #------------------------ - - elif item[0] == 12: # start tangent - if point: points.append(point) - point = Vertex() - point.tangent = True - point.x = item[1] - elif item[0] == 22: # = y - point.y = item[1] - elif item[0] == 32: # = z - point.z = item[1] - #print 'deb:Spline.get_points fit begtangent:', point #------------------------ - - elif item[0] == 13: # end tangent - if point: points.append(point) - pointend = Vertex() - pointend.tangent = True - pointend.x = item[1] - elif item[0] == 23: # 20 = y - pointend.y = item[1] - elif item[0] == 33: # 30 = z - pointend.z = item[1] - #print 'deb:Spline.get_points fit endtangent:', pointend #------------------------ - points.append(point) - if self.curved and pointend: - points.append(pointend) - #print 'deb:Spline points:\n', points #------------------------ - return points - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - -class LWpolyline(Polyline): #------------------------------------------------------------- - """Class for objects representing dxf LWPOLYLINEs. - """ - def __init__(self, obj): - """Expects an entity object of type lwpolyline as input. - """ - #print 'deb:LWpolyline.START:----------------' #------------------------ - if not obj.type == 'lwpolyline': - raise TypeError, "Wrong type %s for polyline object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.num_points = obj.get_type(90)[0] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.elevation = getit(obj, 38, 0) - self.thic = getit(obj, 39, 0) - self.color_index = getit(obj, 62, BYLAYER) - width = getit(obj, 43, 0) - self.swidth = width # default start width - self.ewidth = width # default end width - #print 'deb:LWpolyline width=', width #------------------------ - #print 'deb:LWpolyline elevation=', self.elevation #------------------------ - - self.flags = getit(obj, 70, 0) - self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen - - self.layer = getit(obj, 8, None) - self.extrusion = get_extrusion(obj) - - self.points = self.get_points(obj.data) - - self.pltype = 'poly2d' # LW-polyline is a 2D-polyline - self.spline = False - self.curved = False - - #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------ - #print 'deb:LWpolyline.ENDinit:----------------' #------------------------ - - - def get_points(self, data): - """Gets points for a polyline type object. - - LW-Polylines have no fixed number of verts, and - each vert can have a number of properties. - Verts should be coded as - 10:xvalue - 20:yvalue - 40:startwidth or 0 - 41:endwidth or 0 - 42:bulge or 0 - for each vert - """ - num = self.num_points - point = None - points = [] - for item in data: - if item[0] == 10: # 10 = x - if point: - points.append(point) - point = Vertex() - point.x = item[1] - point.z = self.elevation - elif item[0] == 20: # 20 = y - point.y = item[1] - elif item[0] == 40: # 40 = start width - point.swidth = item[1] - elif item[0] == 41: # 41 = end width - point.ewidth = item[1] - elif item[0] == 42: # 42 = bulge - point.bulge = item[1] - points.append(point) - return points - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - -class Text: #----------------------------------------------------------------- - """Class for objects representing dxf TEXT. - """ - def __init__(self, obj): - """Expects an entity object of type text as input. - """ - if not obj.type == 'text': - raise TypeError, "Wrong type %s for text object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.height = 1.7 * obj.get_type(40)[0] #text.height - self.value = obj.get_type(1)[0] #The text string value - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.color_index = getit(obj, 62, BYLAYER) - self.thic = getit(obj, 39, 0) - - self.rotation = getit(obj, 50, 0) # radians - self.width_factor = getit(obj, 41, 1) # Scaling factor along local x axis - self.oblique = getit(obj, 51, 0) # oblique angle: skew in degrees -90 <= oblique <= 90 - - #self.style = getit(obj, 7, 'STANDARD') # --todo---- Text style name (optional, default = STANDARD) - - #Text generation flags (optional, default = 0): - #2 = backward (mirrored in X), - #4 = upside down (mirrored in Y) - self.flags = getit(obj, 71, 0) - self.mirrorX, self.mirrorY = 1.0, 1.0 - if self.flags&2: self.mirrorX = - 1.0 - if self.flags&4: self.mirrorY = - 1.0 - - # vertical.alignment: 0=baseline, 1=bottom, 2=middle, 3=top - self.valignment = getit(obj, 73, 0) - #Horizontal text justification type (optional, default = 0) integer codes (not bit-coded) - #0=left, 1=center, 2=right - #3=aligned, 4=middle, 5=fit - self.halignment = getit(obj, 72, 0) - - self.layer = getit(obj, 8, None) - self.loc1, self.loc2 = self.get_loc(obj) - if self.loc2[0] != None and self.halignment != 5: - self.loc = self.loc2 - else: - self.loc = self.loc1 - self.extrusion = get_extrusion(obj) - - - def get_loc(self, data): - """Gets adjusted location for text type objects. - - If group 72 and/or 73 values are nonzero then the first alignment point values - are ignored and AutoCAD calculates new values based on the second alignment - point and the length and height of the text string itself (after applying the - text style). If the 72 and 73 values are zero or missing, then the second - alignment point is meaningless. - I don't know how to calc text size... - """ - # bottom left x, y, z and justification x, y, z = 0 - #x, y, z, jx, jy, jz = 0, 0, 0, 0, 0, 0 - x = getit(data, 10, None) #First alignment point (in OCS). - y = getit(data, 20, None) - z = getit(data, 30, 0.0) - jx = getit(data, 11, None) #Second alignment point (in OCS). - jy = getit(data, 21, None) - jz = getit(data, 31, 0.0) - return [x, y, z],[jx, jy, jz] - - - def __repr__(self): - return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value) - - - def draw(self, settings): - """for TEXTs: generate Blender_geometry. - """ - obname = 'tx_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - txt = Text3d.New(obname) - ob = SCENE.objects.new(txt) # create a new text_object - - txt.setText(self.value) - txt.setSize(1.0) #Blender<2.45 accepts only (0.0 - 5.0) - #txt.setSize(self.height) - #txt.setWidth(self.bold) - #setLineSeparation(sep) - txt.setShear(self.oblique/90) - - thic = set_thick(self.thic, settings) - if thic != 0.0: - thic = self.thic * 0.5 - self.loc[2] += thic - txt.setExtrudeDepth(1.0) #Blender<2.45 accepts only (0.1 - 10.0) - if self.halignment == 0: - align = Text3d.LEFT - elif self.halignment == 1: - align = Text3d.MIDDLE - elif self.halignment == 2: - align = Text3d.RIGHT - else: - align = Text3d.LEFT - txt.setAlignment(align) - - if self.valignment == 1: - txt.setYoffset(0.0) - elif self.valignment == 2: - txt.setYoffset(- self.height * 0.5) - elif self.valignment == 3: - txt.setYoffset(- self.height) - - # move the object center to the text location - ob.loc = tuple(self.loc) - transform(self.extrusion, self.rotation, ob) - - # flip it and scale it to the text width - ob.SizeX *= self.height * self.width_factor * self.mirrorX - ob.SizeY *= self.height * self.mirrorY - if thic != 0.0: ob.SizeZ *= abs(thic) - return ob - - - -def set_thick(thickness, settings): - """Set thickness relative to settings variables. - - Set thickness relative to settings variables: - 'thick_on','thick_force','thick_min'. - Accepted also minus values of thickness - python trick: sign(x)=cmp(x,0) - """ - if settings.var['thick_force']: - if settings.var['thick_on']: - if abs(thickness) < settings.var['thick_min']: - thic = settings.var['thick_min'] * cmp(thickness,0) - else: thic = thickness - else: thic = settings.var['thick_min'] - else: - if settings.var['thick_on']: thic = thickness - else: thic = 0.0 - return thic - - - - -class Mtext: #----------------------------------------------------------------- - """Class for objects representing dxf MTEXT. - """ - - def __init__(self, obj): - """Expects an entity object of type mtext as input. - """ - if not obj.type == 'mtext': - raise TypeError, "Wrong type %s for mtext object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.height = obj.get_type(40)[0] - self.width = obj.get_type(41)[0] - self.alignment = obj.get_type(71)[0] # alignment 1=TL, 2=TC, 3=TR, 4=ML, 5=MC, 6=MR, 7=BL, 8=BC, 9=BR - self.value = self.get_text(obj) # The text string value - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.color_index = getit(obj, 62, BYLAYER) - self.rotation = getit(obj, 50, 0) # radians - - self.width_factor = getit(obj, 42, 1) # Scaling factor along local x axis - self.line_space = getit(obj, 44, 1) # percentage of default - - self.layer = getit(obj, 8, None) - self.loc = self.get_loc(obj) - self.extrusion = get_extrusion(obj) - - - def get_text(self, data): - """Reconstructs mtext data from dxf codes. - """ - primary = '' - secondary = [] - for item in data: - if item[0] == 1: # There should be only one primary... - primary = item[1] - elif item[0] == 3: # There may be any number of extra strings (in order) - secondary.append(item[1]) - if not primary: - #raise ValueError, "Empty Mtext Object!" - string = "Empty Mtext Object!" - if not secondary: - string = primary.replace(r'\P', '\n') - else: - string = ''.join(secondary)+primary - string = string.replace(r'\P', '\n') - return string - - - def get_loc(self, data): - """Gets location for a mtext type objects. - - Mtext objects have only one point indicating - """ - loc = [0, 0, 0] - loc[0] = getit(data, 10, None) - loc[1] = getit(data, 20, None) - loc[2] = getit(data, 30, 0.0) - return loc - - - def __repr__(self): - return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value) - - - def draw(self, settings): - """for MTEXTs: generate Blender_geometry. - """ - # Now Create an object - obname = 'tm_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - txt = Text3d.New(obname) - ob = SCENE.objects.new(txt) # create a new text_object - - txt.setSize(1) - # Blender doesn't give access to its text object width currently - # only to the text3d's curve width... - #txt.setWidth(text.width/10) - txt.setLineSeparation(self.line_space) - txt.setExtrudeDepth(0.5) - txt.setText(self.value) - - # scale it to the text size - ob.SizeX = self.height * self.width_factor - ob.SizeY = self.height - ob.SizeZ = self.height - - # move the object center to the text location - ob.loc = tuple(self.loc) - transform(self.extrusion, self.rotation, ob) - - return ob - - -class Circle: #----------------------------------------------------------------- - """Class for objects representing dxf CIRCLEs. - """ - - def __init__(self, obj): - """Expects an entity object of type circle as input. - """ - if not obj.type == 'circle': - raise TypeError, "Wrong type %s for circle object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.radius = obj.get_type(40)[0] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.thic = getit(obj, 39, 0) - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.loc = self.get_loc(obj) - self.extrusion = get_extrusion(obj) - - - - def get_loc(self, data): - """Gets the center location for circle type objects. - - Circles have a single coord location. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 10, None) - loc[1] = getit(data, 20, None) - loc[2] = getit(data, 30, 0.0) - return loc - - - - def __repr__(self): - return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius) - - - def draw(self, settings): - """for CIRCLE: generate Blender_geometry. - """ - obname = 'ci_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - radius = self.radius - - thic = set_thick(self.thic, settings) - width = 0.0 - if settings.var['lines_as'] == 4: # as thin_box - thic = settings.var['thick_min'] - width = settings.var['width_min'] - if settings.var['lines_as'] == 3: # as thin cylinder - cyl_rad = 0.5 * settings.var['width_min'] - - if settings.var['lines_as'] == 5: # draw CIRCLE as curve ------------- - arc_res = settings.var['curve_arc'] - #arc_res = 3 - start, end = 0.0, 360.0 - VectorTriples = calcArc(None, radius, start, end, arc_res, True) - c = Curve.New(obname) # create new curve data - curve = c.appendNurb(BezTriple.New(VectorTriples[0])) - for p in VectorTriples[1:-1]: - curve.append(BezTriple.New(p)) - for point in curve: - point.handleTypes = [FREE, FREE] - point.radius = 1.0 - curve.flagU = 1 # 1 sets the curve cyclic=closed - if settings.var['fill_on']: - c.setFlag(6) # 2+4 set top and button caps - else: - c.setFlag(c.getFlag() & ~6) # dont set top and button caps - - c.setResolu(settings.var['curve_res']) - c.update() - - #--todo-----to check--------------------------- - ob = SCENE.objects.new(c) # create a new curve_object - ob.loc = tuple(self.loc) - if thic != 0.0: #hack: Blender<2.45 curve-extrusion - thic = thic * 0.5 - c.setExt1(1.0) # curve-extrusion accepts only (0.0 - 2.0) - ob.LocZ = thic + self.loc[2] - transform(self.extrusion, 0, ob) - if thic != 0.0: - ob.SizeZ *= abs(thic) - return ob - - else: # draw CIRCLE as mesh ----------------------------------------------- - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - # set a number of segments in entire circle - arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad']) - start, end = 0.0 , 360.0 - verts = calcArc(None, radius, start, end, arc_res, False) - verts = verts[:-1] #list without last point/edge (cause by circle it is equal to the first point) - #print 'deb:circleDraw: verts:', verts #--------------- - - if thic != 0: - len1 = len(verts) - thic_verts = [] - thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts]) - if thic < 0.0: - thic_verts.extend(verts) - verts = thic_verts - else: - verts.extend(thic_verts) - faces = [] - f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] - #f_band = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1)] - f_band.append([len1 - 1, 0, len1, len1 + len1 -1]) - faces = f_band - smooth_len = len(f_band) - if settings.var['fill_on']: - if thic < 0.0: - verts.append([0,0,thic]) #center of top side - verts.append([0,0,0]) #center of bottom side - else: - verts.append([0,0,0]) #center of bottom side - verts.append([0,0,thic]) #center of top side - center1 = len(verts)-2 - center2 = len(verts)-1 - f_bottom = [[num+1, num, center1] for num in xrange(len1 - 1)] - f_bottom.append([0, len1 - 1, center1]) - f_top = [[num+len1, num+1+len1, center2] for num in xrange(len1 - 1)] - f_top.append([len1-1+len1, 0+len1, center2]) - #print 'deb:circleDraw:verts:', verts #--------------- - faces = f_band + f_bottom + f_top - #print 'deb:circleDraw:faces:', faces #--------------- - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - for i in xrange(smooth_len): - me.faces[i].smooth = True - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - if settings.var['vGroup_on'] and not M_OBJ: - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD - vg_band, vg_top, vg_bottom = [], [], [] - for v in f_band: vg_band.extend(v) - me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', vg_band, 1.0, replace) - - if settings.var['fill_on']: - for v in f_top: vg_top.extend(v) - for v in f_bottom: vg_bottom.extend(v) - me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace) - me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace) - - else: # if thic == 0 - if settings.var['fill_on']: - len1 = len(verts) - verts.append([0,0,0]) #center of circle - center1 = len1 - faces = [] - faces.extend([[num, num+1, center1] for num in xrange(len1)]) - faces.append([len1-1, 0, center1]) - #print 'deb:circleDraw:verts:', verts #--------------- - #print 'deb:circleDraw:faces:', faces #--------------- - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - else: - me.verts.extend(verts) # add vertices to mesh - edges = [[num, num+1] for num in xrange(len(verts))] - edges[-1][1] = 0 # it points the "new" last edge to the first vertex - me.edges.extend(edges) # add edges to the mesh - - ob.loc = tuple(self.loc) - transform(self.extrusion, 0, ob) - return ob - - -class Arc: #----------------------------------------------------------------- - """Class for objects representing dxf ARCs. - """ - - def __init__(self, obj): - """Expects an entity object of type arc as input. - """ - if not obj.type == 'arc': - raise TypeError, "Wrong type %s for arc object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.radius = obj.get_type(40)[0] - self.start_angle = obj.get_type(50)[0] - self.end_angle = obj.get_type(51)[0] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.thic = getit(obj, 39, 0) - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.loc = self.get_loc(obj) - self.extrusion = get_extrusion(obj) - #print 'deb:Arc__init__: center, radius, start, end:\n', self.loc, self.radius, self.start_angle, self.end_angle #--------- - - - - def get_loc(self, data): - """Gets the center location for arc type objects. - - Arcs have a single coord location. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 10, None) - loc[1] = getit(data, 20, None) - loc[2] = getit(data, 30, 0.0) - return loc - - - - def __repr__(self): - return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius) - - - def draw(self, settings): - """for ARC: generate Blender_geometry. - """ - obname = 'ar_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - - center = self.loc - radius = self.radius - start = self.start_angle - end = self.end_angle - #print 'deb:calcArcPoints:\n center, radius, start, end:\n', center, radius, start, end #--------- - thic = set_thick(self.thic, settings) - width = 0.0 - if settings.var['lines_as'] == 4: # as thin_box - thic = settings.var['thick_min'] - width = settings.var['width_min'] - if settings.var['lines_as'] == 3: # as thin cylinder - cyl_rad = 0.5 * settings.var['width_min'] - - if settings.var['lines_as'] == 5: # draw ARC as curve ------------- - arc_res = settings.var['curve_arc'] - triples = True - VectorTriples = calcArc(None, radius, start, end, arc_res, triples) - arc = Curve.New(obname) # create new curve data - curve = arc.appendNurb(BezTriple.New(VectorTriples[0])) - for p in VectorTriples[1:]: - curve.append(BezTriple.New(p)) - for point in curve: - point.handleTypes = [FREE, FREE] - point.radius = 1.0 - curve.flagU = 0 # 0 sets the curve not cyclic=open - arc.setResolu(settings.var['curve_res']) - - arc.update() #important for handles calculation - - ob = SCENE.objects.new(arc) # create a new curve_object - ob.loc = tuple(self.loc) - if thic != 0.0: #hack: Blender<2.45 curve-extrusion - thic = thic * 0.5 - arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0) - ob.LocZ = thic + self.loc[2] - transform(self.extrusion, 0, ob) - if thic != 0.0: - ob.SizeZ *= abs(thic) - return ob - - else: # draw ARC as mesh -------------------- - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - # set a number of segments in entire circle - arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad']) - - verts = calcArc(None, radius, start, end, arc_res, False) - #verts = [list(point) for point in verts] - len1 = len(verts) - #print 'deb:len1:', len1 #----------------------- - if width != 0: - radius_out = radius + (0.5 * width) - radius_in = radius - (0.5 * width) - if radius_in <= 0.0: - radius_in = settings.var['dist_min'] - #radius_in = 0.0 - verts_in = [] - verts_out = [] - for point in verts: - pointVec = Mathutils.Vector(point) - pointVec = pointVec.normalize() - verts_in.append(list(radius_in * pointVec)) #vertex inside - verts_out.append(list(radius_out * pointVec)) #vertex outside - verts = verts_in + verts_out - - #print 'deb:verts:', verts #--------------------- - if thic != 0: - thic_verts = [] - thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts]) - if thic < 0.0: - thic_verts.extend(verts) - verts = thic_verts - else: - verts.extend(thic_verts) - f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)] - f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)] - f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)] - f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)] - f_start = [[0, len1, len1+len1+len1, len1+len1]] - f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]] - faces = f_left + f_right + f_bottom + f_top + f_start + f_end - - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - smooth_len = len(f_left) + len(f_right) - for i in xrange(smooth_len): - me.faces[i].smooth = True - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - if settings.var['vGroup_on'] and not M_OBJ: - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD - vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] - for v in f_left: vg_left.extend(v) - for v in f_right: vg_right.extend(v) - for v in f_top: vg_top.extend(v) - for v in f_bottom: vg_bottom.extend(v) - me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace) - me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace) - me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace) - me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace) - me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace) - me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace) - - - else: # if thick=0 - draw only flat ring - faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)] - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - elif thic != 0: - thic_verts = [] - thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts]) - if thic < 0.0: - thic_verts.extend(verts) - verts = thic_verts - else: - verts.extend(thic_verts) - faces = [] - #print 'deb:len1:', len1 #----------------------- - #print 'deb:verts:', verts #--------------------- - faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] - - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - for i in xrange(len(faces)): - me.faces[i].smooth = True - - else: - edges = [[num, num+1] for num in xrange(len(verts)-1)] - me.verts.extend(verts) # add vertices to mesh - me.edges.extend(edges) # add edges to the mesh - - #me.update() - #ob = SCENE.objects.new(me) # create a new arc_object - #ob.link(me) - ob.loc = tuple(center) - #ob.loc = Mathutils.Vector(ob.loc) - transform(self.extrusion, 0, ob) - #ob.size = (1,1,1) - return ob - - -class BlockRecord: #----------------------------------------------------------------- - """Class for objects representing dxf block_records. - """ - - def __init__(self, obj): - """Expects an entity object of type block_record as input. - """ - if not obj.type == 'block_record': - raise TypeError, "Wrong type %s for block_record object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.name = getit(obj, 2, None) - - # optional data (with defaults) - self.insertion_units = getit(obj, 70, None) - self.insert_units = getit(obj, 1070, None) - """code 1070 Einfuegeeinheiten: - 0 = Keine Einheiten; 1 = Zoll; 2 = Fuss; 3 = Meilen; 4 = Millimeter; - 5 = Zentimeter; 6 = Meter; 7 = Kilometer; 8 = Mikrozoll; - 9 = Mils; 10 = Yard; 11 = Angstrom; 12 = Nanometer; - 13 = Mikrons; 14 = Dezimeter; 15 = Dekameter; - 16 = Hektometer; 17 = Gigameter; 18 = Astronomische Einheiten; - 19 = Lichtjahre; 20 = Parsecs - """ - - - def __repr__(self): - return "%s: name - %s, insert units - %s" %(self.__class__.__name__, self.name, self.insertion_units) - - - - -class Block: #----------------------------------------------------------------- - """Class for objects representing dxf BLOCKs. - """ - - def __init__(self, obj): - """Expects an entity object of type block as input. - """ - if not obj.type == 'block': - raise TypeError, "Wrong type %s for block object!" %obj.type - - self.type = obj.type - self.name = obj.name - self.data = obj.data[:] - - # required data - self.flags = getit(obj, 70, 0) - self.anonim = self.flags & 1 #anonymous block generated by hatching, associative dimensioning, other - self.atrib = self.flags & 2 # has attribute definitions - self.xref = self.flags & 4 # is an external reference (xref) - self.xref_lay = self.flags & 8 # is an xref overlay - self.dep_ext = self.flags & 16 # is externally dependent - self.dep_res = self.flags & 32 # resolved external reference - self.xref_ext = self.flags & 64 # is a referenced external reference xref - #--todo--- if self.flag > 4: self.xref = True - - # optional data (with defaults) - self.path = getit(obj, 1, '') # Xref path name - self.discription = getit(obj, 4, '') - - self.entities = dxfObject('block_contents') #creates empty entities_container for this block - self.entities.data = objectify([ent for ent in obj.data if type(ent) != list]) - - self.layer = getit(obj, 8, None) - self.loc = self.get_loc(obj) - - #print 'deb:Block %s data:\n%s' %(self.name, self.data) #------------ - #print 'deb:Block %s self.entities.data:\n%s' %(self.name, self.entities.data) #------------ - - - - def get_loc(self, data): - """Gets the insert point of the block. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 10, 0.0) # 10 = x - loc[1] = getit(data, 20, 0.0) # 20 = y - loc[2] = getit(data, 30, 0.0) # 30 = z - return loc - - - def __repr__(self): - return "%s: name - %s, description - %s, xref-path - %s" %(self.__class__.__name__, self.name, self.discription, self.path) - - - - -class Insert: #----------------------------------------------------------------- - """Class for objects representing dxf INSERTs. - """ - - def __init__(self, obj): - """Expects an entity object of type insert as input. - """ - if not obj.type == 'insert': - raise TypeError, "Wrong type %s for insert object!" %obj.type - self.type = obj.type - self.data = obj.data[:] - #print 'deb:Insert_init_ self.data:\n', self.data #----------- - - # required data - self.name = obj.get_type(2)[0] - - # optional data (with defaults) - self.rotation = getit(obj, 50, 0) - self.space = getit(obj, 67, 0) - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.loc = self.get_loc(obj) - self.scale = self.get_scale(obj) - self.rows, self.columns = self.get_array(obj) - self.extrusion = get_extrusion(obj) - - #self.flags = getit(obj.data, 66, 0) # - #self.attrib = self.flags & 1 - - - def get_loc(self, data): - """Gets the origin location of the insert. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 10, 0.0) - loc[1] = getit(data, 20, 0.0) - loc[2] = getit(data, 30, 0.0) - return loc - - - def get_scale(self, data): - """Gets the x/y/z scale factors of the insert. - """ - scale = [1, 1, 1] - scale[0] = getit(data, 41, 1.0) - scale[1] = getit(data, 42, 1.0) - scale[2] = getit(data, 43, 1.0) - return scale - - - def get_array(self, data): - """Returns the pair (row number, row spacing), (column number, column spacing). - """ - columns = getit(data, 70, 1) - rows = getit(data, 71, 1) - cspace = getit(data, 44, 0.0) - rspace = getit(data, 45, 0.0) - return (rows, rspace), (columns, cspace) - - - def get_target(self, data): - """Gets the origin location of the insert. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 1011, 0.0) - loc[1] = getit(data, 1021, 0.0) - loc[2] = getit(data, 1031, 0.0) - return loc - - - def get_color(self, data): - """Gets the origin location of the insert. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 1010, 0.0) - loc[1] = getit(data, 1020, 0.0) - loc[2] = getit(data, 1030, 0.0) - return loc - - - def get_ave_render(self, data): - """Gets the origin location of the insert. - """ - loc = [0, 0, 0] - loc[0] = getit(data, 1010, 0.0) - loc[1] = getit(data, 1020, 0.0) - loc[2] = getit(data, 1030, 0.0) - return loc - - - def __repr__(self): - return "%s: layer - %s, name - %s" %(self.__class__.__name__, self.layer, self.name) - - - def draw(self, settings, deltaloc): - """for INSERT(block): draw empty-marker for duplicated Blender_Group. - - Blocks are made of three objects: - the block_record in the tables section - the block in the blocks section - the insert object (one or more) in the entities section - block_record gives the insert units, - block provides the objects drawn in the block, - insert object gives the location/scale/rotation of the block instances. - """ - - name = self.name.lower() - if name == 'ave_render': - if settings.var['lights_on']: #if lights support activated - a_data = get_ave_data(self.data) - # AVE_RENDER objects: - # 7:'Pref', 0:'Full Opt', 0:'Quick Opt', 1:'Scanl Opt', 2:'Raytr Opt', 0:'RFile Opt' - # 0:'Fog Opt', 0:'BG Opt', 0:'SCENE1','','','','','','','','','', - # '','','','','','','','','','','','', - - if a_data.key == 'SCENE': # define set of lights as blender group - scene_lights = 1 - return - elif name == 'ave_global': - if settings.var['lights_on']: #if lights support activated - return - elif name == 'sh_spot': - if settings.var['lights_on']: #if lights support activated - obname = settings.blocknamesmap[self.name] - obname = 'sp_%s' %obname # create object name from block name - #obname = obname[:MAX_NAMELENGTH] - # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon' - li = Lamp.New('Spot', obname) - ob = SCENE.objects.new(li) - intensity = 2.0 #--todo-- ----------- - li.setEnergy(intensity) - target = self.get_target(self.data) - color = self.get_color(self.data) - li.R = color[0] - li.G = color[1] - li.B = color[2] - - ob.loc = tuple(self.loc) - transform(self.extrusion, 0, ob) - return ob - - elif name == 'overhead': - if settings.var['lights_on']: #if lights support activated - obname = settings.blocknamesmap[self.name] - obname = 'la_%s' %obname # create object name from block name - #obname = obname[:MAX_NAMELENGTH] - # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon' - li = Lamp.New('Lamp', obname) - ob = SCENE.objects.new(li) - intensity = 2.0 #--todo-- ----------- - li.setEnergy(intensity) - target = self.get_target(self.data) - color = self.get_color(self.data) - li.R = color[0] - li.G = color[1] - li.B = color[2] - - ob.loc = tuple(self.loc) - transform(self.extrusion, 0, ob) - return ob - - elif name == 'direct': - if settings.var['lights_on']: #if lights support activated - obname = settings.blocknamesmap[self.name] - obname = 'su_%s' %obname # create object name from block name - #obname = obname[:MAX_NAMELENGTH] - # blender: 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', or 'Photon' - li = Lamp.New('Sun', obname) - ob = SCENE.objects.new(li) - intensity = 2.0 #--todo-- ----------- - li.setEnergy(intensity) - color = self.get_color(self.data) - li.R = color[0] - li.G = color[1] - li.B = color[2] - - ob.loc = tuple(self.loc) - transform(self.extrusion, 0, ob) - return ob - - elif settings.drawTypes['insert']: #if insert_drawType activated - #print 'deb:draw. settings.blocknamesmap:', settings.blocknamesmap #-------------------- - obname = settings.blocknamesmap[self.name] - obname = 'in_%s' %obname # create object name from block name - #obname = obname[:MAX_NAMELENGTH] - - # if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty - ob = SCENE.objects.new('Empty', obname) # create a new empty_object - empty_size = 1.0 * settings.var['g_scale'] - if empty_size < 0.01: empty_size = 0.01 #Blender limits (0.01-10.0) - elif empty_size > 10.0: empty_size = 10.0 - ob.drawSize = empty_size - - # get our block_def-group - block = settings.blocks(self.name) - ob.DupGroup = block - ob.enableDupGroup = True - - if block.name.startswith('xr_'): - ob.name = 'xb_' + ob.name[3:] - - #print 'deb:draw.block.deltaloc:', deltaloc #-------------------- - ob.loc = tuple(self.loc) - if deltaloc: - deltaloc = rotXY_Vec(self.rotation, deltaloc) - #print 'deb:draw.block.loc:', deltaloc #-------------------- - ob.loc = [ob.loc[0]+deltaloc[0], ob.loc[1]+deltaloc[1], ob.loc[2]+deltaloc[2]] - transform(self.extrusion, self.rotation, ob) - ob.size = tuple(self.scale) - return ob - - - - -class Ellipse: #----------------------------------------------------------------- - """Class for objects representing dxf ELLIPSEs. - """ - - def __init__(self, obj): - """Expects an entity object of type ellipse as input. - """ - if not obj.type == 'ellipse': - raise TypeError, "Wrong type %s for ellipse object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # required data - self.ratio = obj.get_type(40)[0] # Ratio of minor axis to major axis - self.start_angle = obj.get_type(41)[0] # in radians - self.end_angle = obj.get_type(42)[0] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.thic = getit(obj, 39, 0.0) - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.loc = self.get_loc(obj) - self.major = self.get_major(obj) - self.extrusion = get_extrusion(obj) - - - def get_loc(self, data): - """Gets the center location for arc type objects. - - Arcs have a single coord location. - """ - loc = [0.0, 0.0, 0.0] - loc[0] = getit(data, 10, 0.0) - loc[1] = getit(data, 20, 0.0) - loc[2] = getit(data, 30, 0.0) - return loc - - - def get_major(self, data): - """Gets the major axis for ellipse type objects. - - The ellipse major axis defines the rotation of the ellipse and its radius. - """ - loc = [0.0, 0.0, 0.0] - loc[0] = getit(data, 11, 0.0) - loc[1] = getit(data, 21, 0.0) - loc[2] = getit(data, 31, 0.0) - return loc - - - def __repr__(self): - return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius) - - - def draw(self, settings): - """for ELLIPSE: generate Blender_geometry. - """ - obname = 'el_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - - center = self.loc - start = degrees(self.start_angle) - end = degrees(self.end_angle) - if abs(end - 360.0) < 0.00001: end = 360.0 - ellipse_closed = False - if end - start == 360.0: ellipse_closed = True - - # rotation = Angle between major and WORLDX - # doesnt work, couse produces always positive value: rotation = Mathutils.AngleBetweenVecs(major, WORLDX) - if self.major[0] == 0: - rotation = 90.0 - if self.major[1] < 0: rotation += 180 - else: - rotation = degrees(atan(self.major[1] / self.major[0])) - if self.major[0] < 0: - rotation += 180.0 - - major = Mathutils.Vector(self.major) - #radius = sqrt(self.major[0]**2 + self.major[1]**2 + self.major[2]**2) - radius = major.length - #print 'deb:calcEllipse:\n center, radius, start, end:\n', center, radius, start, end #--------- - - thic = set_thick(self.thic, settings) - width = 0.0 - if settings.var['lines_as'] == 4: # as thin_box - thic = settings.var['thick_min'] - width = settings.var['width_min'] - elif settings.var['lines_as'] == 3: # as thin cylinder - cyl_rad = 0.5 * settings.var['width_min'] - - elif settings.var['lines_as'] == 5: # draw ELLIPSE as curve ------------- - arc_res = settings.var['curve_arc'] - triples = True - VectorTriples = calcArc(None, radius, start, end, arc_res, triples) - arc = Curve.New(obname) # create new curve data - curve = arc.appendNurb(BezTriple.New(VectorTriples[0])) - if ellipse_closed: - for p in VectorTriples[1:-1]: - curve.append(BezTriple.New(p)) - for point in curve: - point.handleTypes = [FREE, FREE] - point.radius = 1.0 - curve.flagU = 1 # 0 sets the curve not cyclic=open - if settings.var['fill_on']: - arc.setFlag(6) # 2+4 set top and button caps - else: - arc.setFlag(arc.getFlag() & ~6) # dont set top and button caps - else: - for p in VectorTriples[1:]: - curve.append(BezTriple.New(p)) - for point in curve: - point.handleTypes = [FREE, FREE] - point.radius = 1.0 - curve.flagU = 0 # 0 sets the curve not cyclic=open - - arc.setResolu(settings.var['curve_res']) - arc.update() #important for handles calculation - - ob = SCENE.objects.new(arc) # create a new curve_object - ob.loc = tuple(self.loc) - if thic != 0.0: #hack: Blender<2.45 curve-extrusion - thic = thic * 0.5 - arc.setExt1(1.0) # curve-extrusion: Blender2.45 accepts only (0.0 - 5.0) - ob.LocZ = thic + self.loc[2] - transform(self.extrusion, rotation, ob) - ob.SizeY *= self.ratio - if thic != 0.0: - ob.SizeZ *= abs(thic) - return ob - - - else: # draw ELLIPSE as mesh -------------------------------------- - if M_OBJ: obname, me, ob = makeNewObject() - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - # set a number of segments in entire circle - arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad']) - - verts = calcArc(None, radius, start, end, arc_res, False) - #verts = [list(point) for point in verts] - len1 = len(verts) - #print 'deb:len1:', len1 #----------------------- - if width != 0: - radius_out = radius + (0.5 * width) - radius_in = radius - (0.5 * width) - if radius_in <= 0.0: - radius_in = settings.var['dist_min'] - #radius_in = 0.0 - verts_in = [] - verts_out = [] - for point in verts: - pointVec = Mathutils.Vector(point) - pointVec = pointVec.normalize() - verts_in.append(list(radius_in * pointVec)) #vertex inside - verts_out.append(list(radius_out * pointVec)) #vertex outside - verts = verts_in + verts_out - - #print 'deb:verts:', verts #--------------------- - if thic != 0: - thic_verts = [] - thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts]) - if thic < 0.0: - thic_verts.extend(verts) - verts = thic_verts - else: - verts.extend(thic_verts) - f_bottom = [[num, num+1, len1+num+1, len1+num] for num in xrange(len1-1)] - f_top = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1+len1, len1+len1+len1-1)] - f_left = [[num, len1+len1+num, len1+len1+num+1, num+1] for num in xrange(len1-1)] - f_right = [[num, num+1, len1+len1+num+1, len1+len1+num] for num in xrange(len1, len1+len1-1)] - f_start = [[0, len1, len1+len1+len1, len1+len1]] - f_end = [[len1+len1-1, 0+len1-1, len1+len1+len1-1, len1+len1+len1+len1-1]] - faces = f_left + f_right + f_bottom + f_top + f_start + f_end - - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - smooth_len = len(f_left) + len(f_right) - for i in xrange(smooth_len): - me.faces[i].smooth = True - if settings.var['vGroup_on'] and not M_OBJ: - # each MeshSide becomes vertexGroup for easier material assignment --------------------- - replace = Mesh.AssignModes.REPLACE #or .AssignModes.ADD - vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] - for v in f_left: vg_left.extend(v) - for v in f_right: vg_right.extend(v) - for v in f_top: vg_top.extend(v) - for v in f_bottom: vg_bottom.extend(v) - me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace) - me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace) - me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace) - me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace) - me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace) - me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace) - - - else: # if thick=0 - draw only flat ring - faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)] - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - - elif thic != 0: - thic_verts = [] - thic_verts.extend([[point[0], point[1], point[2]+thic] for point in verts]) - if thic < 0.0: - thic_verts.extend(verts) - verts = thic_verts - else: - verts.extend(thic_verts) - faces = [] - #print 'deb:len1:', len1 #----------------------- - #print 'deb:verts:', verts #--------------------- - faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] - - me.verts.extend(verts) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- - for i in xrange(len(faces)): - me.faces[i].smooth = True - - else: - edges = [[num, num+1] for num in xrange(len(verts)-1)] - me.verts.extend(verts) # add vertices to mesh - me.edges.extend(edges) # add edges to the mesh - - #print 'deb:calcEllipse transform rotation: ', rotation #--------- - ob.loc = tuple(center) - #old ob.SizeY = self.ratio - transform(self.extrusion, rotation, ob) - #old transform(self.extrusion, 0, ob) - ob.SizeY *= self.ratio - - return ob - - - -class Face: #----------------------------------------------------------------- - """Class for objects representing dxf 3DFACEs. - """ - - def __init__(self, obj): - """Expects an entity object of type 3dfaceplot as input. - """ - if not obj.type == '3dface': - raise TypeError, "Wrong type %s for 3dface object!" %obj.type - self.type = obj.type -# self.data = obj.data[:] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - self.color_index = getit(obj, 62, BYLAYER) - - self.layer = getit(obj, 8, None) - self.points = self.get_points(obj) - - - def get_points(self, data): - """Gets 3-4 points for a 3d face type object. - - Faces have three or optionally four verts. - """ - a = [0, 0, 0] - b = [0, 0, 0] - c = [0, 0, 0] - d = [0, 0, 0] - a[0] = getit(data, 10, None) # 10 = x - a[1] = getit(data, 20, None) # 20 = y - a[2] = getit(data, 30, 0.0) # 30 = z - b[0] = getit(data, 11, None) - b[1] = getit(data, 21, None) - b[2] = getit(data, 31, 0.0) - c[0] = getit(data, 12, None) - c[1] = getit(data, 22, None) - c[2] = getit(data, 32, 0.0) - out = [a,b,c] - - d[0] = getit(data, 13, None) - if d[0] != None: - d[1] = getit(data, 23, None) - d[2] = getit(data, 33, 0.0) - out.append(d) - - #if len(out) < 4: print '3dface with only 3 vertices:\n',a,b,c,d #----------------- - return out - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - def draw(self, settings): - """for 3DFACE: generate Blender_geometry. - """ - # Generate the geometery - points = self.points - - global activObjectLayer - global activObjectName - #print 'deb:draw:face.ob IN activObjectName: ', activObjectName #--------------------- - - if M_OBJ: obname, me, ob = makeNewObject() - else: - if activObjectLayer == self.layer and settings.var['one_mesh_on']: - obname = activObjectName - #print 'deb:face.draw obname from activObjectName: ', obname #--------------------- - ob = getSceneChild(obname) # open an existing mesh_object - #ob = SCENE.getChildren(obname) # open an existing mesh_object - me = ob.getData(name_only=False, mesh=True) - else: - obname = 'fa_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - activObjectName = ob.name - activObjectLayer = self.layer - #print ('deb:except. new face.ob+mesh:"%s" created!' %ob.name) #--------------------- - - #me = Mesh.Get(ob.name) # open objects mesh data - faces, edges = [], [] - n = len(me.verts) - if len(self.points) == 4: - faces = [[0+n,1+n,2+n,3+n]] - elif len(self.points) == 3: - faces = [[0+n,1+n,2+n]] - elif len(self.points) == 2: - edges = [[0+n,1+n]] - - me.verts.extend(points) # add vertices to mesh - if faces: me.faces.extend(faces) # add faces to the mesh - if edges: me.edges.extend(edges) # add faces to the mesh - if settings.var['vGroup_on'] and not M_OBJ: - # entities with the same color build one vertexGroup for easier material assignment --------------------- - ob.link(me) # link mesh to that object - vG_name = 'color_%s' %self.color_index - if edges: faces = edges - replace = Mesh.AssignModes.ADD #or .AssignModes.REPLACE or ADD - try: - me.assignVertsToGroup(vG_name, faces[0], 1.0, replace) - #print 'deb: existed vGroup:', vG_name #--------------------- - except: - me.addVertGroup(vG_name) - me.assignVertsToGroup(vG_name, faces[0], 1.0, replace) - #print 'deb: create new vGroup:', vG_name #-------------------- - - #print 'deb:draw:face.ob OUT activObjectName: ', activObjectName #--------------------- - return ob - - -#--------------------------------------------------------------------------------------- -# type to object maping (sorted-dictionary for f_obiectify ONLY!, format={'key':Class} ) -type_map = { - 'vport':Vport, - 'view':View, - 'layer':Layer, - 'block_record':BlockRecord, - 'block':Block, - 'insert':Insert, - 'point':Point, - '3dface':Face, - 'line':Line, -# 'mline':MLine, - 'polyline':Polyline, - 'lwpolyline':LWpolyline, - 'spline':Spline, -# 'region':Region, - 'trace':Solid, - 'solid':Solid, - 'text':Text, - 'mtext':Mtext, - 'circle':Circle, - 'ellipse':Ellipse, - 'arc':Arc -} - - - -def objectify(data): #----------------------------------------------------------------- - """Expects a section type object's data as input. - - Maps object data to the correct object type. - """ - #print 'deb:objectify start %%%%%%%%%%%' #--------------- - objects = [] # colector for finished objects - known_types = type_map.keys() # so we don't have to call foo.keys() every iteration - curves_on = GUI_A['curves_on'].val - index = 0 - while index < len(data): - item = data[index] - #print 'deb:objectify item: \n', item #------------ - if type(item) != list and item.type == 'table': - item.data = objectify(item.data) # tables have sub-objects - objects.append(item) - elif type(item) != list and item.type == 'polyline': #remi --todo----------- - #print 'deb:gosub Polyline\n' #------------- - pline = Polyline(item) - while 1: - index += 1 - item = data[index] - if item.type == 'vertex': - #print 'deb:objectify gosub Vertex--------' #------------- - v = Vertex(item) - if pline.spline: # if NURBSpline-curve - # then for Blender-mesh filter only additional_vertices - # OR - # then for Blender-curve filter only spline_control_vertices - if (v.spline and not curves_on) or (curves_on and v.spline_c): #correct for real NURBS-import - #if (v.spline and not curves_on) or (curves_on and not v.spline_c): #fake for Bezier-emulation of NURBS-import - pline.points.append(v) - elif pline.curved: # if Bezier-curve - # then for Blender-mesh filter only curve_additional_vertices - # OR - # then for Blender-curve filter curve_control_vertices - if not curves_on or (curves_on and not v.curved): - pline.points.append(v) - else: - pline.points.append(v) - elif item.type == 'seqend': - #print 'deb:objectify it is seqEND ---------\n' #------------- - break - else: - print "Error: non-vertex found before seqend!" - index -= 1 #so go back one step - break - objects.append(pline) - elif type(item) != list and item.type in ['block', 'insert']: - if not settings.var['block_nn'] and item.name.startswith('*X'): - #print 'deb:objectify item.type:"%s", item.name:"%s"' %(item.type, item.name) #------------ - pass - elif settings.var['blockFilter_on'] and not settings.accepted_block(item.name): - pass - else: - try: - objects.append(type_map[item.type](item)) - except TypeError: - pass - elif type(item) != list and item.type in known_types: - # proccess the object and append the resulting object - try: - objects.append(type_map[item.type](item)) - except TypeError: - pass - else: - #we will just let the data pass un-harrased - #objects.append(item) - pass - index += 1 - #print 'deb:objectify objects:\n', objects #------------ - #print 'deb:objectify END %%%%%%%%' #------------ - return objects - - - -class MatColors: #----------------------------------------------------------------- - """A smart container for dxf-color based materials. - - This class is a wrapper around a dictionary mapping dxf-color indicies to materials. - When called with a color_index - it returns a material corresponding to that index. - Behind the scenes it checks if that index is in its keys, and if not it creates - a new material. It then adds the new index:material pair to its dict and returns - the material. - """ - - def __init__(self): - """Expects a map - a dictionary mapping layer names to layers. - """ - #self.layersmap = layersmap # a dictionary of layername:layerobject - self.colMaterials = {} # a dictionary of color_index:blender_material - #print 'deb:init_MatColors argument.map: ', map #------------------ - - - def __call__(self, color=None): - """Return the material associated with color. - - If a layer name is provided, the color of that layer is used. - """ - if color == None: color = 256 # color 256=BYLAYER - if type(color) == str: # looking for color of LAYER named "color" - #--todo---bug with ARC from ARC-T0.DXF layer="T-3DARC-1"----- - #print 'deb:color is string:--------: ', color - #try: - #color = layersmap[color].color - #print 'deb:color=self.map[color].color:', color #------------------ - #except KeyError: - #layer = Layer(name=color, color=256, frozen=False) - #layersmap[color] = layer - #color = 0 - if color in layersmap.keys(): - color = layersmap[color].color - if color == 256: # color 256 = BYLAYER - #--todo-- should looking for color of LAYER - #if layersmap: color = layersmap[color].color - color = 3 - if color == 0: # color 0 = BYBLOCK - #--todo-- should looking for color of paret-BLOCK - #if layersmap: color = layersmap[color].color - color = 3 - color = abs(color) # cause the value could be nagative = means the layer is turned off - - if color not in self.colMaterials.keys(): - self.add(color) - return self.colMaterials[color] - - - def add(self, color): - """Create a new material 'ColorNr-N' using the provided color index-N. - """ - #global color_map #--todo-- has not to be global? - mat = Material.New('ColorNr-%s' %color) - mat.setRGBCol(color_map[color]) - #mat.mode |= Material.Modes.SHADELESS #--todo-- - #mat.mode |= Material.Modes.WIRE -# try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug -# except: pass - self.colMaterials[color] = mat - - - -class MatLayers: #----------------------------------------------------------------- - """A smart container for dxf-layer based materials. - - This class is a wrapper around a dictionary mapping dxf-layer names to materials. - When called with a layer name it returns a material corrisponding to that. - Behind the scenes it checks if that layername is in its keys, and if not it creates - a new material. It then adds the new layername:material pair to its dict and returns - the material. - """ - - def __init__(self): - """Expects a map - a dictionary mapping layer names to layers. - """ - #self.layersmap = layersmap # a dictionary of layername:layer - self.layMaterials = {} # a dictionary of layer_name:blender_material - #print 'deb:init_MatLayers argument.map: ', map #------------------ - - - def __call__(self, layername=None, color=None): - """Return the material associated with dxf-layer. - - If a dxf-layername is not provided, create a new material - """ - #global layernamesmap - layername_short = layername - if layername in layernamesmap.keys(): - layername_short = layernamesmap[layername] - colorlayername = layername_short - if color: colorlayername = str(color) + colorlayername - if colorlayername not in self.layMaterials.keys(): - self.add(layername, color, colorlayername) - return self.layMaterials[colorlayername] - - - def add(self, layername, color, colorlayername): - """Create a new material 'layername'. - """ - try: mat = Material.Get('L-%s' %colorlayername) - except: mat = Material.New('L-%s' %colorlayername) - #print 'deb:MatLayers material: ', mat #---------- - #global settings - #print 'deb:MatLayers material_from: ', settings.var['material_from'] #---------- - if settings.var['material_from'] == 3 and color: - if color == 0 or color == 256: mat_color = 3 - else: mat_color = color - elif layersmap and layername: - mat_color = layersmap[layername].color - else: mat_color = 3 - #print 'deb:MatLayers color: ', color #----------- - #print 'deb:MatLayers mat_color: ', mat_color #----------- - mat.setRGBCol(color_map[abs(mat_color)]) - #mat.mode |= Material.Modes.SHADELESS - #mat.mode |= Material.Modes.WIRE -# try: mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc-bug -# except: pass - self.layMaterials[colorlayername] = mat - - - - -class Blocks: #----------------------------------------------------------------- - """A smart container for blocks. - - This class is a wrapper around a dictionary mapping block names to Blender data blocks. - When called with a name string it returns a block corresponding to that name. - Behind the scenes it checks if that name is in its keys, and if not it creates - a new data block. It then adds the new name:block_data pair to its dict and returns - the block. - """ - - def __init__(self, blocksmap, settings): - """Expects a dictionary mapping block_name:block_data. - """ - self.blocksmap = blocksmap #a dictionary mapping block_name:block_data - self.settings = settings - self.blocks = {} #container for blender groups representing blocks - - - def __call__(self, name=None): - """Return the data block associated with that block_name. - - If that name is not in its keys, it creates a new data block. - If no name is provided return entire self.blocks container. - """ - if name == None: - return self.blocks - if name not in self.blocks.keys(): - self.addBlock(name) - return self.blocks[name] - - - def addBlock(self, name): - """Create a new 'block group' for the block name. - """ - block = self.blocksmap[name] - prefix = 'bl' - if block.xref: prefix = 'xr' - blender_group = Group.New('%s_%s' %(prefix,name)) # Blender groupObject contains definition of BLOCK - block_def = [blender_group, block.loc] - self.settings.write("\nDrawing block:\'%s\' ..." % name) - - if block.xref: - obname = 'xr_%s' %name # create object name from xref block name - #obname = obname[:MAX_NAMELENGTH] - # if material BYBLOCK def needed: use as placeholder a mesh-vertex instead of empty - ob = SCENE.objects.new('Empty', obname) # create a new empty_object - empty_size = 1.0 * settings.var['g_scale'] - if empty_size < 0.01: empty_size = 0.01 #Blender limits (0.01-10.0) - elif empty_size > 10.0: empty_size = 10.0 - ob.drawSize = empty_size - ob.loc = tuple(block.loc) - ob.properties['xref_path'] = block.path - ob.layers = [19] - insertFlag=True; blockFlag=True - global oblist - oblist.append((ob, insertFlag, blockFlag)) - else: - if M_OBJ: - car_end() - car_start() - drawEntities(block.entities, self.settings, block_def) - if M_OBJ: car_end() - self.settings.write("Drawing block:\'%s\' done!" %name) - self.blocks[name] = blender_group - - - - - -class Settings: #----------------------------------------------------------------- - """A container for all the import settings and objects used by the draw functions. - - This is like a collection of globally accessable persistant properties and functions. - """ - # Optimization constants - MIN = 0 - MID = 1 - PRO = 2 - MAX = 3 - - def __init__(self, keywords, drawTypes): - """initialize all the important settings used by the draw functions. - """ - self.obj_number = 1 #global object_number for progress_bar - - self.var = dict(keywords) #a dictionary of (key_variable:Value) control parameter - self.drawTypes = dict(drawTypes) #a dictionary of (entity_type:True/False) = import on/off for this entity_type - - self.var['colorFilter_on'] = False #deb:remi------------ - self.acceptedColors = [0,2,3,4,5,6,7,8,9, - 10 ] - - self.var['layerFilter_on'] = False #deb:remi------------ - self.acceptedLayers = ['3', - '0' - ] - - self.var['groupFilter_on'] = False #deb:remi------------ - self.acceptedLayers = ['3', - '0' - ] - - #self.var['blockFilter_on'] = 0 #deb:remi------------ - self.acceptedBlocks = ['WALL_1871', - 'BOX02' - ] - self.unwantedBlocks = ['BOX05', - 'BOX04' - ] - - - def update(self, keywords, drawTypes): - """update all the important settings used by the draw functions. - mostly used after loading parameters from INI-file - """ - - for k, v in keywords.iteritems(): - self.var[k] = v - #print 'deb:settings_update var %s= %s' %(k, self.var[k]) #-------------- - for t, v in drawTypes.iteritems(): - self.drawTypes[t] = v - #print 'deb:settings_update drawType %s= %s' %(t, self.drawTypes[t]) #-------------- - - self.drawTypes['arc'] = self.drawTypes['line'] - self.drawTypes['circle'] = self.drawTypes['line'] - self.drawTypes['ellipse'] = self.drawTypes['line'] - self.drawTypes['trace'] = self.drawTypes['solid'] - self.drawTypes['insert'] = self.drawTypes['block'] - #self.drawTypes['vport'] = self.drawTypes['view'] - - #print 'deb:self.drawTypes', self.drawTypes #--------------- - - - def validate(self, drawing): - """Given the drawing, build dictionaries of Layers, Colors and Blocks. - """ - - global oblist - #adjust the distance parameter to globalScale - if self.var['g_scale'] != 1.0: - self.var['dist_min'] = self.var['dist_min'] / self.var['g_scale'] - self.var['thick_min'] = self.var['thick_min'] / self.var['g_scale'] - self.var['width_min'] = self.var['width_min'] / self.var['g_scale'] - self.var['arc_rad'] = self.var['arc_rad'] / self.var['g_scale'] - - self.g_origin = Mathutils.Vector(self.var['g_originX'], self.var['g_originY'], self.var['g_originZ']) - - # First sort out all the section_items - sections = dict([(item.name, item) for item in drawing.data]) - - # The section:header may be omited - if 'header' in sections.keys(): - self.write("found section:header") - else: - self.write("File contains no section:header!") - - if self.var['optimization'] == 0: self.var['one_mesh_on'] = 0 - # The section:tables may be partialy or completely missing. - self.layersTable = False - self.colMaterials = MatColors() #A container for dxf-color based materials - self.layMaterials = MatLayers() #A container for dxf-layer based materials - #self.collayMaterials = MatColLayers({}) #A container for dxf-color+layer based materials - global layersmap, layernamesmap - layersmap, layernamesmap = {}, {} - if 'tables' in sections.keys(): - self.write("found section:tables") - views, vports, layers = False, False, False - for table in drawing.tables.data: - if table.name == 'layer': - self.write("found table:layers") - layers = table - elif table.name == 'view': - print "found table:view" - views = table - elif table.name == 'vport': - print "found table:vport" - vports = table - if layers: #---------------------------------- - # Read the layers table and get the layer colors - layersmap, layernamesmap = getLayersmap(layers) - #self.colMaterials = MatColors() - #self.layMaterials = MatLayers() - else: - self.write("File contains no table:layers!") - - - if views: #---------------------------------- - if self.var['views_on']: - for item in views.data: - if type(item) != list and item.type == 'view': - #print 'deb:settings_valid views dir(item)=', dir(item) #------------- - #print 'deb:settings_valid views item=', item #------------- - ob = item.draw(self) - #viewsmap[item.name] = [item.length] - #--todo-- add to obj_list for global.Scaling - insertFlag, blockFlag = False, False - oblist.append((ob, insertFlag, blockFlag)) - - else: - self.write("File contains no table:views!") - - - if vports: #---------------------------------- - if self.var['views_on']: - for item in vports.data: - if type(item) != list and item.type == 'vport': - #print 'deb:settings_valid views dir(item)=', dir(item) #------------- - #print 'deb:settings_valid views item=', item #------------- - ob = item.draw(self) - #viewsmap[item.name] = [item.length] - #--todo-- add to obj_list for global.Scaling - insertFlag, blockFlag = False, False - oblist.append((ob, insertFlag, blockFlag)) - else: - self.write("File contains no table:vports!") - - - else: - self.write("File contains no section:tables!") - self.write("File contains no table:layers!") - - - # The section:blocks may be omited - if 'blocks' in sections.keys(): - self.write("found section:blocks") - # Read the block definitions and build our block object - if self.drawTypes['insert']: #if support for entity type 'Insert' is activated - #Build a dictionary of blockname:block_data pairs - blocksmap, obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on']) - self.obj_number += obj_number - self.blocknamesmap = getBlocknamesmap(blocksmap) - self.blocks = Blocks(blocksmap, self) # initiates container for blocks_data - self.usedBlocks = blocksmap.keys() - #print 'deb:settings_valid self.usedBlocks', self.usedBlocks #---------- - else: - self.write("ignored, because support for BLOCKs is turn off!") - #print 'deb:settings_valid self.obj_number', self.obj_number #---------- - else: - self.write("File contains no section:blocks!") - self.drawTypes['insert'] = False - - # The section:entities - if 'entities' in sections.keys(): - self.write("found section:entities") - self.obj_number += len(drawing.entities.data) - self.obj_number = 1.0 / self.obj_number - - - def accepted_block(self, name): - if name not in self.usedBlocks: return False - if name in self.unwantedBlocks: return False - elif name in self.acceptedBlocks: return True - #elif (name.find('*X')+1): return False - #elif name.startswith('3'): return True - #elif name.endswith('H'): return False - return True - - - def write(self, text, newline=True): - """Wraps the built-in print command in a optimization check. - """ - if self.var['optimization'] <= self.MID: - if newline: print text - else: print text, - - - def redraw(self): - """Update Blender if optimization level is low enough. - """ - if self.var['optimization'] <= self.MIN: - Blender.Redraw() - - - def progress(self, done, text): - """Wrapper for Blender.Window.DrawProgressBar. - """ - if self.var['optimization'] <= self.PRO: - progressbar = done * self.obj_number - Window.DrawProgressBar(progressbar, text) - #print 'deb:drawer done, progressbar: ', done, progressbar #----------------------- - - def layer_isOff(self, layername): # no more used ------- - """Given a layer name, and return its visible status. - """ - # if layer is off then color_index is negative - if layersmap and layersmap[layername].color < 0: return True - #print 'deb:layer_isOff: layer is ON' #--------------- - return False - - - def layer_isFrozen(self, layername): # no more used ------- - """Given a layer name, and return its frozen status. - """ - if layersmap and layersmap[layername].frozen: return True - #print 'deb:layer_isFrozen: layer is not FROZEN' #--------------- - return False - - - -def analyzeDXF(dxfFile): #--------------------------------------- - """list statistics about LAYER and BLOCK dependences into textfile.INF - - """ - Window.WaitCursor(True) # Let the user know we are thinking - print 'reading DXF file: %s.' % dxfFile - time1 = sys.time() #time marker1 - drawing = readDXF(dxfFile, objectify) - print 'finish reading in %.4f sec.' % (sys.time()-time1) - - # First sort out all the section_items - sections = dict([(item.name, item) for item in drawing.data]) - - # The section:header may be omited - if 'header' in sections.keys(): print "found section:header" - else: print "File contains no section:header!" - - # The section:tables may be partialy or completely missing. - layersTable = False - global layersmap - layersmap = {} - viewsmap = {} - vportsmap = {} - layersmap_str = '#File contains no table:layers!' - viewsmap_str = '#File contains no table:views!' - vportsmap_str = '#File contains no table:vports!' - if 'tables' in sections.keys(): - print "found section:tables" - views, vports, layers = False, False, False - for table in drawing.tables.data: - if table.name == 'layer': - print "found table:layers" - layers = table - elif table.name == 'view': - print "found table:view" - views = table - elif table.name == 'vport': - print "found table:vport" - vports = table - if layers: #---------------------------------- - for item in layers.data: - if type(item) != list and item.type == 'layer': - #print dir(item) - layersmap[item.name] = [item.color, item.frozen] - #print 'deb:analyzeDXF: layersmap=' , layersmap #------------- - layersmap_str = '#list of LAYERs: name, color, frozen_status ---------------------------\n' - key_list = layersmap.keys() - key_list.sort() - for key in key_list: - #for layer_name, layer_data in layersmap.iteritems(): - layer_name, layer_data = key, layersmap[key] - layer_str = '\'%s\': col=%s' %(layer_name,layer_data[0])#------------- - if layer_data[1]: layer_str += ', frozen' - layersmap_str += layer_str + '\n' - #print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #------------- - else: - print "File contains no table:layers!" - - if views: #---------------------------------- - for item in views.data: - if type(item) != list and item.type == 'view': - #print dir(item) - viewsmap[item.name] = [item.length] - #print 'deb:analyzeDXF: viewsmap=' , viewsmap #------------- - viewsmap_str = '#list of VIEWs: name, focus_length ------------------------------------\n' - key_list = viewsmap.keys() - key_list.sort() - for key in key_list: - #for view_name, view_data in viewsmap.iteritems(): - view_name, view_data = key, viewsmap[key] - view_str = '\'%s\': length=%s' %(view_name,view_data[0])#------------- - #if view_data[1]: view_str += ', something' - viewsmap_str += view_str + '\n' - #print 'deb:analyzeDXF: layersmap_str=\n' , layersmap_str #------------- - else: - print "File contains no table:views!" - - if vports: #---------------------------------- - for item in vports.data: - if type(item) != list and item.type == 'vport': - #print dir(item) - vportsmap[item.name] = [item.length] - #print 'deb:analyzeDXF: vportsmap=' , vportsmap #------------- - vportsmap_str = '#list of VPORTs: name, focus_length -----------------------------------\n' - key_list = vportsmap.keys() - key_list.sort() - for key in key_list: - #for vport_name, vport_data in vportsmap.iteritems(): - vport_name, vport_data = key, vportsmap[key] - vport_str = '\'%s\': length=%s' %(vport_name,vport_data[0])#------------- - #if vport_data[1]: vport_str += ', something' - vportsmap_str += vport_str + '\n' - #print 'deb:analyzeDXF: vportsmap_str=\n' , vportsmap_str #------------- - else: - print "File contains no table:vports!" - - else: - print "File contains no section:tables!" - print "File contains no tables:layers,views,vports!" - - # The section:blocks may be omited - if 'blocks' in sections.keys(): - print "found section:blocks" - blocksmap = {} - for item in drawing.blocks.data: - #print 'deb:getBlocksmap item=' ,item #-------- - #print 'deb:getBlocksmap item.entities=' ,item.entities #-------- - #print 'deb:getBlocksmap item.entities.data=' ,item.entities.data #-------- - if type(item) != list and item.type == 'block': - xref = False - if item.xref: xref = True - childList = [] - used = False - for item2 in item.entities.data: - if type(item2) != list and item2.type == 'insert': - #print 'deb:getBlocksmap dir(item2)=', dir(item2) #---------- - item2str = [item2.name, item2.layer, item2.color_index, item2.scale, item2.space] - childList.append(item2str) - try: blocksmap[item.name] = [used, childList, xref] - except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item) - #print 'deb:analyzeDXF: blocksmap=' , blocksmap #------------- - - for item2 in drawing.entities.data: - if type(item2) != list and item2.type == 'insert': - if item2.name in blocksmap.keys(): - if not layersmap or (layersmap and not layersmap[item2.layer][1]): #if insert_layer is not frozen - blocksmap[item2.name][0] = True # marked as world used BLOCK - - key_list = blocksmap.keys() - key_list.reverse() - for key in key_list: - if blocksmap[key][0]: #if used - for child in blocksmap[key][1]: - if not layersmap or (layersmap and not layersmap[child[1]][1]): #if insert_layer is not frozen - blocksmap[child[0]][0] = True # marked as used BLOCK - - blocksmap_str = '#list of BLOCKs: name:(unused)(xref) -[child_name, layer, color, scale, space]-------\n' - key_list = blocksmap.keys() - key_list.sort() - for key in key_list: - #for block_name, block_data in blocksmap.iteritems(): - block_name, block_data = key, blocksmap[key] - block_str = '\'%s\': ' %(block_name) #------------- - used = '(unused)' - if block_data[0]: used = '' -# else: used = '(unused)' - xref = '' - if block_data[2]: xref = '(xref)' - blocksmap_str += block_str + used + xref +'\n' - if block_data: - for block_item in block_data[1]: - block_data_str = ' - %s\n' %block_item - blocksmap_str += block_data_str - #print 'deb:analyzeDXF: blocksmap_str=\n' , blocksmap_str #------------- - else: - blocksmap_str = '#File contains no section:blocks!' - print "File contains no section:blocks!" - - Window.WaitCursor(False) - output_str = '%s\n%s\n%s\n%s' %(viewsmap_str, vportsmap_str, layersmap_str, blocksmap_str) - infFile = dxfFile[:-4] + '_DXF.INF' # replace last char:'.dxf' with '_DXF.inf' - try: - f = file(infFile, 'w') - f.write(INFFILE_HEADER + '\n# this is a comment line\n\n') - f.write(output_str) - f.close() - Draw.PupMenu('DXF importer: report saved in INF-file:%t|' + '\'%s\'' %infFile) - except: - Draw.PupMenu('DXF importer: ERROR by writing report in INF-file:%t|' + '\'%s\'' %infFile) - #finally: f.close() - - - - -def main(dxfFile): #---------------#############################----------- - #print 'deb:filename:', filename #-------------- - global SCENE - global oblist - editmode = Window.EditMode() # are we in edit mode? If so ... - if editmode: - Window.EditMode(0) # leave edit mode before - - #SCENE = bpy.data.scenes.active - #SCENE.objects.selected = [] # deselect all - - global cur_COUNTER #counter for progress_bar - cur_COUNTER = 0 - - #try: - if 1: - #print "Getting settings..." - global GUI_A, GUI_B, g_scale_as - if not GUI_A['g_scale_on'].val: - GUI_A['g_scale'].val = 1.0 - - keywords = {} - drawTypes = {} - for k, v in GUI_A.iteritems(): - keywords[k] = v.val - for k, v in GUI_B.iteritems(): - drawTypes[k] = v.val - #print 'deb:startUInew keywords: ', keywords #-------------- - #print 'deb:startUInew drawTypes: ', drawTypes #-------------- - - # The settings object controls how dxf entities are drawn - settings.update(keywords, drawTypes) - #print 'deb:settings.var:\n', settings.var #----------------------- - - if not settings: - #Draw.PupMenu('DXF importer: EXIT!%t') - #print '\nDXF Import: terminated by user!' - print '\nDXF Import: terminated, cause settings failure!' - Window.WaitCursor(False) - if editmode: Window.EditMode(1) # and put things back how we fond them - return None - - #no more used dxfFile = dxfFileName.val - #print 'deb: dxfFile file: ', dxfFile #---------------------- - if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile): - Window.WaitCursor(True) # Let the user know we are thinking - print 'reading file: %s.' % dxfFile - time1 = sys.time() #time marker1 - drawing = readDXF(dxfFile, objectify) - print 'reading finished in %.4f sec.' % (sys.time()-time1) - Window.WaitCursor(False) - elif dxfFile.lower().endswith('.dwg') and sys.exists(dxfFile): - if not extCONV_OK: - Draw.PupMenu(extCONV_TEXT) - Window.WaitCursor(False) - if editmode: Window.EditMode(1) # and put things back how we fond them - return None - else: - Window.WaitCursor(True) # Let the user know we are thinking - #todo: issue: in DConvertCon.exe the output filename is fixed to dwg_name.dxf - - if 0: # works only for Windows - dwgTemp = 'temp_01.dwg' - dxfTemp = 'temp_01.dxf' - os.system('copy %s %s' %(dxfFile,dwgTemp)) - else: - dwgTemp = dxfFile - dxfTemp = dxfFile[:-3]+'dxf' - #print 'temp. converting: %s\n to: %s' %(dxfFile, dxfTemp) - #os.system('%s %s -acad11 -dxf' %(extCONV_PATH, dxfFile)) - os.system('%s %s -dxf' %(extCONV_PATH, dwgTemp)) - #os.system('%s %s -dxf' %(extCONV_PATH, dxfFile_temp)) - if sys.exists(dxfTemp): - print 'reading file: %s.' % dxfTemp - time1 = sys.time() #time marker1 - drawing = readDXF(dxfTemp, objectify) - #os.remove(dwgTemp) - os.remove(dxfTemp) # clean up - print 'reading finished in %.4f sec.' % (sys.time()-time1) - Window.WaitCursor(False) - else: - if UI_MODE: Draw.PupMenu('DWG importer: nothing imported!%t|No valid DXF-representation found!') - print 'DWG importer: nothing imported. No valid DXF-representation found.' - Window.WaitCursor(False) - if editmode: Window.EditMode(1) # and put things back how we fond them - return None - else: - if UI_MODE: Draw.PupMenu('DXF importer: Alert!%t| no valid DXF-file selected!') - print "DXF importer: Alert! - no valid DXF-file selected." - Window.WaitCursor(False) - if editmode: Window.EditMode(1) # and put things back how we fond them - return None - - # Draw all the know entity types in the current scene - oblist = [] # a list of all created AND linked objects for final f_globalScale - time2 = sys.time() #time marker2 - - Window.WaitCursor(True) # Let the user know we are thinking - settings.write("\n\nDrawing entities...") - - settings.validate(drawing) - - global activObjectLayer, activObjectName - activObjectLayer, activObjectName = None, None - - if M_OBJ: car_init() - - drawEntities(drawing.entities, settings) - - #print 'deb:drawEntities after: oblist:', oblist #----------------------- - if M_OBJ: car_end() - if oblist: # and settings.var['g_scale'] != 1: - globalScale(oblist, settings.var['g_scale']) - - # Set visibility for all layers on all View3d - #Window.ViewLayers([i+1 for i in range(18)]) # for 2.45 - SCENE.setLayers([i+1 for i in range(18)]) - SCENE.update(1) - SCENE.objects.selected = [i[0] for i in oblist] #select only the imported objects - #SCENE.objects.selected = SCENE.objects #select all objects in current scene - Blender.Redraw() - - time_text = sys.time() - time2 - Window.WaitCursor(False) - if settings.var['paper_space_on']: space = 'from paper space' - else: space = 'from model space' - ob_len = len(oblist) - message = ' %s objects imported %s in %.4f sec. -----DONE-----' % (ob_len, space, time_text) - settings.progress(1.0/settings.obj_number, 'DXF import done!') - print message - #settings.write(message) - if UI_MODE: Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % time_text) - - #finally: - # restore state even if things didn't work - #print 'deb:drawEntities finally!' #----------------------- - Window.WaitCursor(False) - if editmode: Window.EditMode(1) # and put things back how we fond them - - - -def getOCS(az): #----------------------------------------------------------------- - """An implimentation of the Arbitrary Axis Algorithm. - """ - #decide if we need to transform our coords - #if az[0] == 0 and az[1] == 0: - if abs(az[0]) < 0.00001 and abs(az[1]) < 0.00001: - if az[2] > 0.0: - return False - elif az[2] < 0.0: - ax = Mathutils.Vector(-1.0, 0, 0) - ay = Mathutils.Vector(0, 1.0, 0) - az = Mathutils.Vector(0, 0, -1.0) - return ax, ay, az - - az = Mathutils.Vector(az) - - cap = 0.015625 # square polar cap value (1/64.0) - if abs(az.x) < cap and abs(az.y) < cap: - ax = M_CrossVecs(WORLDY,az) - else: - ax = M_CrossVecs(WORLDZ,az) - ax = ax.normalize() - ay = M_CrossVecs(az, ax) - ay = ay.normalize() - return ax, ay, az - - - -def transform(normal, rotation, obj): #-------------------------------------------- - """Use the calculated ocs to determine the objects location/orientation in space. - - Quote from dxf docs: - The elevation value stored with an entity and output in DXF files is a sum - of the Z-coordinate difference between the UCS XY plane and the OCS XY - plane, and the elevation value that the user specified at the time the entity - was drawn. - """ - ma = Mathutils.Matrix([1,0,0],[0,1,0],[0,0,1]) - o = Mathutils.Vector(obj.loc) - ocs = getOCS(normal) - if ocs: - ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2]) - o = ma.invert() * o - ma = Mathutils.Matrix(ocs[0], ocs[1], ocs[2]) - - if rotation != 0: - g = radians(-rotation) - rmat = Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1]) - ma = rmat * ma - - obj.setMatrix(ma) - obj.loc = o - #print 'deb:new obj.matrix:\n', obj.getMatrix() #-------------------- - - - -def rotXY_Vec(rotation, vec): #---------------------------------------------------- - """Rotate vector vec in XY-plane. vec must be in radians - """ - if rotation != 0: - o = Mathutils.Vector(vec) - g = radians(-rotation) - vec = o * Mathutils.Matrix([cos(g), -sin(g), 0], [sin(g), cos(g), 0], [0, 0, 1]) - return vec - - - -def getLayersmap(dxflayers): #------------------------------------------------------ - """Build two dictionaries: 1.layername:layer object, and 2.layername:layername_short - gets set of layers from TABLES SECTION LAYERS - """ - layersmap = {} - layernamesmap = {} - for item in dxflayers.data: - if type(item) != list and item.type == 'layer': - layersmap[item.name] = item - layername_short = item.name[:MAX_NAMELENGTH-1] - i = 0 #sufix for layernames cause Blender-objectnames-limits - while layername_short in layernamesmap.keys(): - i += 1 - suffix = str(i) #--todo--set zero-leading number format - layername_short = layername_short[:-2] + suffix - layernamesmap[item.name] = layername_short - - #print 'deb:getLayersmap layersmap:\n', layersmap #------------ - #print 'deb:getLayersmap layernamesmap:\n', layernamesmap #------------ - return layersmap, layernamesmap - - - -def getBlocksmap(drawing, layersmap, layFrozen_on=False): #-------------------------------------------------------- - """Build a dictionary of blockname:block_data pairs - """ - usedblocks = {} - for item in drawing.blocks.data: - #print 'deb:getBlocksmap item=%s\n i.entities=%s\n i.data=%s' %(item,item.entities,item.entities.data) - if type(item) != list and item.type == 'block': - childList = [] - used = False - for item2 in item.entities.data: - if type(item2) != list and item2.type == 'insert': - #print 'deb:getBlocksmap dir(item2)=', dir(item2) #---------- - item2str = [item2.name, item2.layer] - childList.append(item2str) - try: usedblocks[item.name] = [used, childList] - except KeyError: print 'Cannot find "%s" Block!' %(item.name) - #print 'deb:getBlocksmap: usedblocks=' , usedblocks #------------- - #print 'deb:getBlocksmap: layersmap=' , layersmap #------------- - - for item in drawing.entities.data: - if type(item) != list and item.type == 'insert': - if not layersmap or (not layersmap[item.layer].frozen or layFrozen_on): #if insert_layer is not frozen - try: usedblocks[item.name][0] = True - except KeyError: print 'Cannot find "%s" Block!' %(item.name) - - key_list = usedblocks.keys() - key_list.reverse() - for key in key_list: - if usedblocks[key][0]: #if parent used, then set used also all child blocks - for child in usedblocks[key][1]: - if not layersmap or (layersmap and not layersmap[child[1]].frozen): #if insert_layer is not frozen - try: usedblocks[child[0]][0] = True # marked as used BLOCK - except KeyError: print 'Cannot find "%s" Block!' %(child[0]) - - usedblocks = [i for i in usedblocks.keys() if usedblocks[i][0]] - #print 'deb:getBlocksmap: usedblocks=' , usedblocks #------------- - obj_number = 0 - blocksmap = {} - for item in drawing.blocks.data: - if type(item) != list and item.type == 'block' and item.name in usedblocks: - #if item.name.startswith('*X'): #--todo-- - obj_number += len(item.entities.data) - try: blocksmap[item.name] = item - except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item) - - - #print 'deb:getBlocksmap: blocksmap:\n', blocksmap #------------ - return blocksmap, obj_number - - -def getBlocknamesmap(blocksmap): #-------------------------------------------------------- - """Build a dictionary of blockname:blockname_short pairs - """ - #print 'deb:getBlocknamesmap blocksmap:\n', blocksmap #------------ - blocknamesmap = {} - for n in blocksmap.keys(): - blockname_short = n[:MAX_NAMELENGTH-1] - i = 0 #sufix for blockname cause Blender-objectnamelength-limit - while blockname_short in blocknamesmap.keys(): - i += 1 - suffix = str(i) - blockname_short = blockname_short[:-2] + suffix - blocknamesmap[n] = blockname_short - #print 'deb:getBlocknamesmap blocknamesmap:\n', blocknamesmap #------------ - return blocknamesmap - - -def drawEntities(entities, settings, block_def=None): #---------------------------------------- - """Draw every kind of thing in the entity list. - - If provided 'block_def': the entities are to be added to the Blender 'group'. - """ - for _type in type_map.keys(): - #print 'deb:drawEntities_type:', _type #------------------ - # for each known type get a list of that type and call the associated draw function - entities_type = entities.get_type(_type) - if entities_type: drawer(_type, entities_type, settings, block_def) - - -def drawer(_type, entities, settings, block_def): #------------------------------------------ - """Call with a list of entities and a settings object to generate Blender geometry. - - If 'block_def': the entities are to be added to the Blender 'group'. - """ - global layersmap, layersmapshort - #print 'deb:drawer _type, entities:\n ', _type, entities #----------------------- - - if entities: - # Break out early if settings says we aren't drawing the current dxf-type - global cur_COUNTER #counter for progress_bar - group = None - #print 'deb:drawer.check:_type: ', _type #-------------------- - if _type == '3dface':_type = 'face' # hack, while python_variable_name can not beginn with a nummber - if not settings.drawTypes[_type] or _type == 'block_record': - message = 'Skipping dxf\'%ss\' entities' %_type - settings.write(message, True) - cur_COUNTER += len(entities) - settings.progress(cur_COUNTER, message) - return - #print 'deb:drawer.todo:_type:', _type #----------------------- - #print 'deb:drawer entities:\n ', entities #----------------------- - - len_temp = len(entities) - # filtering only model-space enitities (no paper-space enitities) - if settings.var['paper_space_on']: - entities = [entity for entity in entities if entity.space != 0] - else: - entities = [entity for entity in entities if entity.space == 0] - - # filtering only objects with color from acceptedColorsList - if settings.var['colorFilter_on']: - entities = [entity for entity in entities if entity.color in settings.acceptedColors] - - # filtering only objects on layers from acceptedLayersList - if settings.var['layerFilter_on']: - #entities = [entity for entity in entities if entity.layer[0] in ['M','3','0'] and not entity.layer.endswith('H')] - entities = [entity for entity in entities if entity.layer in settings.acceptedLayers] - - # patch for incomplete layer table in HL2-DXF-files - if layersmap: - for entity in entities: - oblayer = entity.layer - if oblayer not in layersmap.keys(): - layer_obj = Layer(None, name=oblayer) - layersmap[oblayer] = layer_obj - layername_short = oblayer[:MAX_NAMELENGTH-1] - i = 0 #sufix for layernames cause Blender-objectnames-limits - while layername_short in layernamesmap.keys(): - i += 1 - suffix = str(i) #--todo--set zero-leading number format - layername_short = layername_short[:-2] + suffix - layernamesmap[oblayer] = layername_short - - # filtering only objects on not-frozen layers - if layersmap and not settings.var['layFrozen_on']: - entities = [entity for entity in entities if not layersmap[entity.layer].frozen] - - global activObjectLayer, activObjectName - activObjectLayer = '' - activObjectName = '' - - message = "Drawing dxf \'%ss\'..." %_type - cur_COUNTER += len_temp - len(entities) - settings.write(message, False) - settings.progress(cur_COUNTER, message) - if len(entities) > 0.1 / settings.obj_number: - show_progress = int(0.03 / settings.obj_number) - else: show_progress = 0 - cur_temp = 0 - - #print 'deb:drawer cur_COUNTER: ', cur_COUNTER #----------------------- - - for entity in entities: #----loop------------------------------------- - settings.write('\b.', False) - cur_COUNTER += 1 - if show_progress: - cur_temp += 1 - if cur_temp == show_progress: - settings.progress(cur_COUNTER, message) - cur_temp = 0 - #print 'deb:drawer show_progress=',show_progress #---------------- - - # get the layer group (just to make things a little cleaner) - if settings.var['group_bylayer_on'] and not block_def: - group = getGroup('l:%s' % layernamesmap[entity.layer]) - - if _type == 'insert': #---- INSERT and MINSERT=array -------------------- - if not settings.var['block_nn']: #----turn off support for noname BLOCKs - prefix = entity.name[:2] - if prefix in ('*X', '*U', '*D'): - #print 'deb:drawer entity.name:', entity.name #------------ - continue - if settings.var['blockFilter_on'] and not settings.accepted_block(entity.name): - continue - - #print 'deb:insert entity.loc:', entity.loc #---------------- - insertFlag = True - columns = entity.columns[0] - coldist = entity.columns[1] - rows = entity.rows[0] - rowdist = entity.rows[1] - deltaloc = [0,0,0] - #print 'deb:insert columns, rows:', columns, rows #----------- - for col in xrange(columns): - deltaloc[0] = col * coldist - for row in xrange(rows): - deltaloc[1] = row * rowdist - #print 'deb:insert col=%s, row=%s,deltaloc=%s' %(col, row, deltaloc) #------ - ob = entity.draw(settings, deltaloc) #-----draw BLOCK---------- - if block_def: - blockFlag = True - bl_loc = block_def[1] - ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]] - else: blockFlag = False - setObjectProperties(ob, group, entity, settings, block_def) - if ob: - if settings.var['optimization'] <= settings.MIN: - #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin - if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale']) - settings.redraw() - else: oblist.append((ob, insertFlag, blockFlag)) - - else: #---draw entities except BLOCKs/INSERTs--------------------- - insertFlag = False - alt_obname = activObjectName - ob = entity.draw(settings) - if ob: - if M_OBJ and ob.type=='Mesh': #'Curve', 'Text' - if block_def: - blockFlag = True - bl_loc = block_def[1] - ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]] - car_nr() - - elif ob.name != alt_obname: - if block_def: - blockFlag = True - bl_loc = block_def[1] - ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]] - else: blockFlag = False - setObjectProperties(ob, group, entity, settings, block_def) - if settings.var['optimization'] <= settings.MIN: - #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin - if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale']) - settings.redraw() - else: oblist.append((ob, insertFlag, blockFlag)) - - #print 'deb:Finished drawing:', entities[0].type #------------------------ - message = "\nDrawing dxf\'%ss\' done!" % _type - settings.write(message, True) - - - -def globalScale(oblist, SCALE): #--------------------------------------------------------- - """Global_scale for list of all imported objects. - - oblist is a list of pairs (ob, insertFlag), where insertFlag=True/False - """ - #print 'deb:globalScale.oblist: ---------%\n', oblist #--------------------- - for l in oblist: - ob, insertFlag, blockFlag = l[0], l[1], l[2] - globalScaleOne(ob, insertFlag, blockFlag, SCALE) - - -def globalScaleOne(ob, insertFlag, blockFlag, SCALE): #--------------------------------------------------------- - """Global_scale imported object. - """ - #print 'deb:globalScaleOne ob: ', ob #--------------------- - if settings.var['g_origin_on'] and not blockFlag: - ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin - - SCALE_MAT= Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) - if insertFlag: # by BLOCKs/INSERTs only insert-point coords must be scaled------------ - ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT - else: # entire scaling for all other imported objects ------------ - if ob.type == 'Mesh': - me = ob.getData(name_only=False, mesh=True) - #me = Mesh.Get(ob.name) - # set centers of all objects in (0,0,0) - #me.transform(ob.matrixWorld*SCALE_MAT) - #ob.loc = Mathutils.Vector([0,0,0]) - # preseve centers of all objects - me.transform(SCALE_MAT) - ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT - else: #--todo-- also for curves: neutral scale factor after import - ob.setMatrix(ob.matrixWorld*SCALE_MAT) - - -def setObjectProperties(ob, group, entity, settings, block_def): #----------------------- - """Link object to scene. - """ - - if not ob: #remi--todo----------------------- - message = "\nObject \'%s\' not found!" %entity - settings.write(message) - return - - if group: - setGroup(group, ob) # if object belongs to group - - if block_def: # if object belongs to BLOCK_def - Move it to layer nr19 - setGroup(block_def[0], ob) - #print 'deb:setObjectProperties \'%s\' set to block_def_group!' %ob.name #--------- - ob.layers = [19] - else: - #ob.layers = [i+1 for i in xrange(20)] #remi--todo------------ - ob.layers = [settings.var['target_layer']] - - # Set material for any objects except empties - if ob.type != 'Empty' and settings.var['material_on']: - setMaterial_from(entity, ob, settings, block_def) - - # Set the visibility - #if settings.layer_isOff(entity.layer): - if layersmap and layersmap[entity.layer].color < 0: # color is negative if layer is off - #ob.layers = [20] #remi--todo------------- - ob.restrictDisplay = True - ob.restrictRender = True - - #print 'deb:\n---------linking Object %s!' %ob.name #---------- - - - -def getGroup(name): #----------------------------------------------------------------- - """Returns a Blender group-object. - """ - try: - group = Group.Get(name) - except: # What is the exception? - group = Group.New(name) - return group - - -def setGroup(group, ob): #------------------------------------------------------------ - """Assigns object to Blender group. - """ - try: - group.objects.link(ob) - except: - group.objects.append(ob) #remi?--------------- - - - -def setMaterial_from(entity, ob, settings, block_def): #------------------------------------------------ - """ Set Blender-material for the object controled by item. - - Set Blender-material for the object - - controlled by settings.var['material_from'] - """ - if settings.var['material_from'] == 1: # 1= material from color - if entity.color_index == BYLAYER or entity.color_index == 256: - mat = settings.colMaterials(entity.layer) - elif entity.color_index == BYBLOCK or entity.color_index == 0: - #--todo-- looking for block.color_index - #mat = settings.colMaterials(block.color_index) - #if block_def: mat = settings.colMaterials(block_def[2]) - mat = settings.colMaterials(3) - else: - mat = settings.colMaterials(entity.color_index) - - elif settings.var['material_from'] == 2: # 2= material from layer_name - mat = settings.layMaterials(layername=entity.layer) - - elif settings.var['material_from'] == 3: # 3= material from layer+color - mat = settings.layMaterials(layername=entity.layer, color=entity.color_index) - -# elif settings.var['material_from'] == 4: # 4= material from block_name - -# elif settings.var['material_from'] == 5: # 5= material from XDATA - -# elif settings.var['material_from'] == 6: # 6= material from INI-file - - else: # set neutral material - try: - mat = Material.Get('dxf-neutral') - except: - mat = Material.New('dxf-neutral') - mat.setRGBCol(color_map[3]) - try:mat.setMode('Shadeless', 'Wire') #work-around for 2.45rc1-bug - except: - mat.mode |= Material.Modes.SHADELESS # - mat.mode |= Material.Modes.WIRE - try: - #print 'deb:material mat:', mat #----------- - ob.setMaterials([mat]) #assigns Blender-material to object - except ValueError: - settings.write("material error - \'%s\'!" %mat) - ob.colbits = 0x01 # Set OB materials. - - - -def calcBulge(p1, p2, arc_res, triples=False): #------------------------------------------------- - """given startpoint, endpoint and bulge of arc, returns points/segments of its representation. - - Needs to take into account bulge sign. - negative = clockwise - positive = counter-clockwise - - to find center given two points, and arc angle - calculate radius - Cord = sqrt(start^2 + end^2) - S = (bulge*Cord)/2 - radius = ((Cord/2)^2+S^2)/2*S - angle of arc = 4*atan( bulge ) - angle from p1 to center is (180-angle)/2 - get vector pointing from p1 to p2 (p2 - p1) - normalize it and multiply by radius - rotate around p1 by angle to center, point to center. - start angle = angle between (center - p1) and worldX - end angle = angle between (center - p2) and worldX - - calculate the center, radius, start angle, and end angle - returns points/segments of its mesh representation - incl.startpoint, without endpoint - """ - - bulge = p1.bulge - p1 = Mathutils.Vector(p1.loc) - p2 = Mathutils.Vector(p2.loc) - cord = p2 - p1 # vector from p1 to p2 - clength = cord.length - s = (bulge * clength)/2.0 # sagitta (height) - radius = abs(((clength/2.0)**2.0 + s**2.0)/(2.0*s)) # magic formula - angle = (degrees(4.0*atan(bulge))) # theta (included angle) - radial = cord.normalize() * radius # a radius length vector aligned with cord - delta = (180.0 - abs(angle))/2.0 # the angle from cord to center - if bulge < 0: delta = -delta - rmat = Mathutils.RotationMatrix(-delta, 3, 'Z') - center = p1 + (rmat * radial) # rotate radial by delta degrees, then add to p1 to find center - #length = radians(abs(angle)) * radius - #print 'deb:calcBulge:\n angle, delta: ', angle, delta #---------------- - #print 'deb:center, radius: ', center, radius #---------------------- - startpoint = p1 - center - endpoint = p2 - center - #print 'deb:calcBulg: startpoint:', startpoint #--------- - #print 'deb:calcBulg: endpoint:', endpoint #--------- - - if not triples: #IF mesh-representation ----------- - if arc_res > 1024: arc_res = 1024 - elif arc_res < 4: arc_res = 4 - pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION - if pieces < 3: pieces = 3 - else: #IF curve-representation ------------------------------- - if arc_res > 32: arc_res = 32 - elif arc_res < 3: arc_res = 3 - pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION - if pieces < 2: pieces = 2 - - step = angle/pieces # set step so pieces * step = degrees in arc - stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z") - - if not triples: #IF mesh-representation ----------- - points = [startpoint] - point = startpoint - for i in xrange(int(pieces)-1): #fast (but not so acurate as: vector * RotMatrix(-step*i,3,"Z") - point = stepmatrix * point - points.append(point) - points = [ point+center for point in points] - # vector to point convertion: - points = [list(point) for point in points] - return points, list(center) - - else: #IF curve-representation ------------------------------- - # correct Bezier curves representation for free segmented circles/arcs - step2 = radians(step * 0.5) - bulg = radius * (1 - cos(step2)) - deltaY = 4.0 * bulg / (3.0 * sin(step2) ) - #print 'deb:calcArcCurve: bulg, deltaY:\n', bulg, deltaY #--------- - #print 'deb:calcArcCurve: step:\n', step #--------- - - #org handler0 = Mathutils.Vector(0.0, -deltaY, 0.0) - #handler = startmatrix * handler0 - #endhandler = endmatrix * handler0 - rotMatr90 = Mathutils.Matrix([0, -1, 0], [1, 0, 0], [0, 0, 1]) - handler = rotMatr90 * startpoint - handler = - deltaY * handler.normalize() - endhandler = rotMatr90 * endpoint - endhandler = - deltaY * endhandler.normalize() - - points = [startpoint] - handlers1 = [startpoint + handler] - handlers2 = [startpoint - handler] - point = Mathutils.Vector(startpoint) - for i in xrange(int(pieces)-1): - point = stepmatrix * point - handler = stepmatrix * handler - handler1 = point + handler - handler2 = point - handler - points.append(point) - handlers1.append(handler1) - handlers2.append(handler2) - points.append(endpoint) - handlers1.append(endpoint + endhandler) - handlers2.append(endpoint - endhandler) - - points = [point + center for point in points] - handlers1 = [point + center for point in handlers1] - handlers2 = [point + center for point in handlers2] - - VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)] - #print 'deb:calcBulgCurve: handlers1:\n', handlers1 #--------- - #print 'deb:calcBulgCurve: points:\n', points #--------- - #print 'deb:calcBulgCurve: handlers2:\n', handlers2 #--------- - #print 'deb:calcBulgCurve: VectorTriples:\n', VectorTriples #--------- - return VectorTriples - - - - -def calcArc(center, radius, start, end, arc_res, triples): #----------------------------------------- - """calculate Points (or BezierTriples) for ARC/CIRCLEs representation. - - Given parameters of the ARC/CIRCLE, - returns points/segments (or BezierTriples) and centerPoint - """ - # center is currently set by object - # if start > end: start = start - 360 - if end > 360: end = end % 360.0 - - startmatrix = Mathutils.RotationMatrix(-start, 3, "Z") - startpoint = startmatrix * Mathutils.Vector(radius, 0, 0) - endmatrix = Mathutils.RotationMatrix(-end, 3, "Z") - endpoint = endmatrix * Mathutils.Vector(radius, 0, 0) - - if end < start: end +=360.0 - angle = end - start - #length = radians(angle) * radius - - if not triples: #IF mesh-representation ----------- - if arc_res > 1024: arc_res = 1024 - elif arc_res < 4: arc_res = 4 - pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION - if pieces < 3: pieces = 3 - step = angle/pieces # set step so pieces * step = degrees in arc - stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z") - - points = [startpoint] - point = startpoint - for i in xrange(int(pieces)-1): - point = stepmatrix * point - points.append(point) - points.append(endpoint) - - if center: - centerVec = Mathutils.Vector(center) - #points = [point + centerVec for point in points()] - points = [point + centerVec for point in points] - # vector to point convertion: - points = [list(point) for point in points] - return points - - else: #IF curve-representation --------------- - if arc_res > 32: arc_res = 32 - elif arc_res < 3: arc_res = 3 - pieces = int(abs(angle)/(360.0/arc_res)) # set a fixed step of ARC_RESOLUTION - if pieces < 2: pieces = 2 - step = angle/pieces # set step so pieces * step = degrees in arc - stepmatrix = Mathutils.RotationMatrix(-step, 3, "Z") - - # correct Bezier curves representation for free segmented circles/arcs - step2 = radians(step * 0.5) - bulg = radius * (1 - cos(step2)) - deltaY = 4.0 * bulg / (3.0 * sin(step2) ) - #print 'deb:calcArcCurve: bulg, deltaY:\n', bulg, deltaY #--------- - #print 'deb:calcArcCurve: step:\n', step #--------- - handler0 = Mathutils.Vector(0.0, -deltaY, 0.0) - - points = [startpoint] - handler = startmatrix * handler0 - endhandler = endmatrix * handler0 - handlers1 = [startpoint + handler] - handlers2 = [startpoint - handler] - point = Mathutils.Vector(startpoint) - for i in xrange(int(pieces)-1): - point = stepmatrix * point - handler = stepmatrix * handler - handler1 = point + handler - handler2 = point - handler - points.append(point) - handlers1.append(handler1) - handlers2.append(handler2) - points.append(endpoint) - handlers1.append(endpoint + endhandler) - handlers2.append(endpoint - endhandler) - VectorTriples = [list(h1)+list(p)+list(h2) for h1,p,h2 in zip(handlers1, points, handlers2)] - #print 'deb:calcArcCurve: handlers1:\n', handlers1 #--------- - #print 'deb:calcArcCurve: points:\n', points #--------- - #print 'deb:calcArcCurve: handlers2:\n', handlers2 #--------- - #print 'deb:calcArcCurve: VectorTriples:\n', VectorTriples #--------- - return VectorTriples - - -def drawCurveCircle(circle): #--- no more used -------------------------------------------- - """Given a dxf circle object return a blender circle object using curves. - """ - c = Curve.New('circle') # create new curve data - center = circle.loc - radius = circle.radius - - p1 = (0, -radius, 0) - p2 = (radius, 0, 0) - p3 = (0, radius, 0) - p4 = (-radius, 0, 0) - - p1 = BezTriple.New(p1) - p2 = BezTriple.New(p2) - p3 = BezTriple.New(p3) - p4 = BezTriple.New(p4) - - curve = c.appendNurb(p1) - curve.append(p2) - curve.append(p3) - curve.append(p4) - for point in curve: - point.handleTypes = [AUTO, AUTO] - point.radius = 1.0 - curve.flagU = 1 # Set curve cyclic - c.update() - - ob = Object.New('Curve', 'circle') # make curve object - return ob - - -def drawCurveArc(self): #---- only for ELLIPSE ------------------------------------------------------------- - """Given a dxf ELLIPSE object return a blender_curve. - """ - center = self.loc - radius = self.radius - start = self.start_angle - end = self.end_angle - - if start > end: - start = start - 360.0 - startmatrix = Mathutils.RotationMatrix(start, 3, "Z") - startpoint = startmatrix * Mathutils.Vector((radius, 0, 0)) - endmatrix = Mathutils.RotationMatrix(end, 3, "Z") - endpoint = endmatrix * Mathutils.Vector((radius, 0, 0)) - # Note: handles must be tangent to arc and of correct length... - - a = Curve.New('arc') # create new curve data - - p1 = (0, -radius, 0) - p2 = (radius, 0, 0) - p3 = (0, radius, 0) - p4 = (-radius, 0, 0) - - p1 = BezTriple.New(p1) - p2 = BezTriple.New(p2) - p3 = BezTriple.New(p3) - p4 = BezTriple.New(p4) - - curve = a.appendNurb(p1) - curve.append(p2) - curve.append(p3) - curve.append(p4) - for point in curve: - point.handleTypes = [AUTO, AUTO] - point.radius = 1.0 - curve.flagU = 1 # Set curve cyclic - a.update() - - ob = Object.New('Curve', 'arc') # make curve object - return ob - - - - -# GUI STUFF -----#################################################----------------- -from Blender.BGL import glColor3f, glRecti, glClear, glRasterPos2d - -EVENT_NONE = 1 -EVENT_START = 2 -EVENT_REDRAW = 3 -EVENT_LOAD_INI = 4 -EVENT_SAVE_INI = 5 -EVENT_RESET = 6 -EVENT_CHOOSE_INI = 7 -EVENT_CHOOSE_DXF = 8 -EVENT_HELP = 9 -EVENT_PRESETCURV = 10 -EVENT_PRESETS = 11 -EVENT_DXF_DIR = 12 -# = 13 -EVENT_LIST = 14 -EVENT_ORIGIN = 15 -EVENT_SCALE = 16 -EVENT_PRESET2D = 20 -EVENT_PRESET3D = 21 -EVENT_EXIT = 100 -GUI_EVENT = EVENT_NONE - -GUI_A = {} # GUI-buttons dictionary for parameter -GUI_B = {} # GUI-buttons dictionary for drawingTypes - -# settings default, initialize ------------------------ - -points_as_menu = "convert to: %t|empty %x1|mesh.vertex %x2|thin sphere %x3|thin box %x4|..curve.vertex %x5" -lines_as_menu = "convert to: %t|..edge %x1|mesh %x2|..thin cylinder %x3|thin box %x4|Bezier-curve %x5|..NURBS-curve %x6" -mlines_as_menu = "convert to: %t|..edge %x1|..mesh %x2|..thin cylinder %x3|..thin box %x|..curve %x5" -plines_as_menu = "convert to: %t|..edge %x1|mesh %x2|..thin cylinder %x3|..thin box %x4|Bezier-curve %x5|NURBS-curve %x6" -splines_as_menu = "convert to: %t|mesh %x2|..thin cylinder %x3|..thin box %x4|Bezier-curve %x5|NURBS-curve %x6" -plines3_as_menu = "convert to: %t|..edge %x1|mesh %x2|..thin cylinder %x3|..thin box %x4|Bezier-curve %x5|NURBS-curve %x6" -plmesh_as_menu = "convert to: %t|..edge %x1|mesh %x2|..NURBS-surface %x6" -solids_as_menu = "convert to: %t|..edge %x1|mesh %x2" -blocks_as_menu = "convert to: %t|dupliGroup %x1|..real.Group %x2|..exploded %x3" -texts_as_menu = "convert to: %t|text %x1|..mesh %x2|..curve %x5" -material_from_menu= "material from: %t|..LINESTYLE %x7|COLOR %x1|LAYER %x2|..LAYER+COLOR %x3|..BLOCK %x4|..XDATA %x5|..INI-File %x6" -g_scale_list = ''.join(( - 'scale factor: %t', - '|user def. %x12', - '|yard to m %x8', - '|feet to m %x7', - '|inch to m %x6', - '| x 1000 %x3', - '| x 100 %x2', - '| x 10 %x1', - '| x 1 %x0', - '| x 0.1 %x-1', - '| x 0.01 %x-2', - '| x 0.001 %x-3', - '| x 0.0001 %x-4', - '| x 0.00001 %x-5')) - -#print 'deb: g_scale_list', g_scale_list #----------- - -dxfFileName = Draw.Create("") -iniFileName = Draw.Create(INIFILE_DEFAULT_NAME + INIFILE_EXTENSION) -user_preset = 0 -config_UI = Draw.Create(0) #switch_on/off extended config_UI -g_scale_as = Draw.Create(int(log10(G_SCALE))) - - -keywords_org = { - 'curves_on' : 0, - 'optimization': 2, - 'one_mesh_on': 1, - 'vGroup_on' : 1, - 'dummy_on' : 0, - 'views_on' : 0, - 'cams_on' : 0, - 'lights_on' : 0, - 'xref_on' : 1, - 'block_nn': 0, - 'blockFilter_on': 0, - 'layerFilter_on': 0, - 'colorFilter_on': 0, - 'groupFilter_on': 0, - 'newScene_on' : 1, - 'target_layer' : TARGET_LAYER, - 'group_bylayer_on' : GROUP_BYLAYER, - 'g_originX' : G_ORIGIN_X, - 'g_originY' : G_ORIGIN_Y, - 'g_originZ' : G_ORIGIN_Z, - 'g_origin_on': 0, - 'g_scale' : float(G_SCALE), -# 'g_scale_as': int(log10(G_SCALE)), # 0, - 'g_scale_on': 0, - 'thick_on' : 1, - 'thick_min' : float(MIN_THICK), - 'thick_force': 0, - 'width_on' : 1, - 'width_min' : float(MIN_WIDTH), - 'width_force': 0, - 'dist_on' : 1, - 'dist_min' : float(MIN_DIST), - 'dist_force': 0, - 'material_on': 1, - 'material_from': 2, - 'fill_on' : 1, - 'meshSmooth_on': 1, - 'curve_res' : CURV_RESOLUTION, - 'curve_arc' : CURVARC_RESOLUTION, - 'arc_res' : ARC_RESOLUTION, - 'arc_rad' : ARC_RADIUS, - 'thin_res' : THIN_RESOLUTION, - 'pl_trim_max' : TRIM_LIMIT, - 'pl_trim_on': 1, - 'plmesh_flip': 0, - 'normals_out': 0, - 'paper_space_on': 0, - 'layFrozen_on': 0, - 'Z_force_on': 0, - 'Z_elev': float(ELEVATION), - 'points_as' : 2, - 'lines_as' : 2, - 'mlines_as' : 2, - 'plines_as' : 2, - 'splines_as' : 5, - 'plines3_as': 2, - 'plmesh_as' : 2, - 'solids_as' : 2, - 'blocks_as' : 1, - 'texts_as' : 1 - } - -drawTypes_org = { - 'point' : 1, - 'line' : 1, - 'arc' : 1, - 'circle': 1, - 'ellipse': 1, - 'mline' : 0, - 'polyline': 1, - 'spline': 1, - 'plmesh': 1, - 'pline3': 1, - 'lwpolyline': 1, - 'text' : 1, - 'mtext' : 0, - 'block' : 1, - 'insert': 1, - 'solid' : 1, - 'trace' : 1, - 'face' : 1, -# 'view' : 0, - } - -# creating of GUI-buttons -# GUI_A - GUI-buttons dictionary for parameter -# GUI_B - GUI-buttons dictionary for drawingTypes -for k, v in keywords_org.iteritems(): - GUI_A[k] = Draw.Create(v) -for k, v in drawTypes_org.iteritems(): - GUI_B[k] = Draw.Create(v) -#print 'deb:init GUI_A: ', GUI_A #--------------- -#print 'deb:init GUI_B: ', GUI_B #--------------- - -model_space_on = Draw.Create(1) - -# initialize settings-object controls how dxf entities are drawn -settings = Settings(keywords_org, drawTypes_org) - - -def update_RegistryKey(key, item): # - """updates key in Blender.Registry - """ - cache = True # data is also saved to a file - rdict = Registry.GetKey('DXF_Importer', cache) - if not rdict: rdict = {} - if item: - rdict[key] = item - Registry.SetKey('DXF_Importer', rdict, cache) - #print 'deb:update_RegistryKey rdict', rdict #--------------- - - -def check_RegistryKey(key): - """ check if the key is already there (saved on a previous execution of this script) - """ - cache = True # data is also saved to a file - rdict = Registry.GetKey('DXF_Importer', cache) - #print 'deb:check_RegistryKey rdict:', rdict #---------------- - if rdict: # if found, get the values saved there - try: - item = rdict[key] - return item - except: - #update_RegistryKey() # if data isn't valid rewrite it - pass - -def saveConfig(): #--todo----------------------------------------------- - """Save settings/config/materials from GUI to INI-file. - - Write all config data to INI-file. - """ - global iniFileName - - iniFile = iniFileName.val - #print 'deb:saveConfig inifFile: ', inifFile #---------------------- - if iniFile.lower().endswith(INIFILE_EXTENSION): - - #--todo-- sort key.list for output - #key_list = GUI_A.keys().val - #key_list.sort() - #for key in key_list: - # l_name, l_data = key, GUI_A[key].val - # list_A - - output_str = '[%s,%s]' %(GUI_A, GUI_B) - if output_str =='None': - Draw.PupMenu('DXF importer: INI-file: Alert!%t|no config-data present to save!') - else: - #if BPyMessages.Warning_SaveOver(iniFile): #<- remi find it too abstarct - if sys.exists(iniFile): - f = file(iniFile, 'r') - header_str = f.readline() - f.close() - if header_str.startswith(INIFILE_HEADER[0:13]): - if Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1: - save_ok = True - else: save_ok = False - elif Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile + - '|Alert: this file has no valid ImportDXF-header| ! it may belong to another aplication !') == 1: - save_ok = True - else: save_ok = False - else: save_ok = True - - if save_ok: - # replace: ',' -> ',\n' - # replace: '{' -> '\n{\n' - # replace: '}' -> '\n}\n' - output_str = ',\n'.join(output_str.split(',')) - output_str = '\n}'.join(output_str.split('}')) - output_str = '{\n'.join(output_str.split('{')) - try: - f = file(iniFile, 'w') - f.write(INIFILE_HEADER + '\n# this is a comment line\n') - f.write(output_str) - f.close() - #Draw.PupMenu('DXF importer: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile) - except: - Draw.PupMenu('DXF importer: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile) - - else: - Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid name/extension for INI-file selected!') - print "DXF importer: Alert!: no valid INI-file selected." - if not iniFile: - if dxfFileName.val.lower().endswith('.dxf'): - iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION - - -def loadConfig(): #remi--todo----------------------------------------------- - """Load settings/config/materials from INI-file. - - Read material-assignements from config-file. - """ - #070724 buggy Window.FileSelector(loadConfigFile, 'Load config data from INI-file', inifilename) - global iniFileName, GUI_A, GUI_B - - iniFile = iniFileName.val - update_RegistryKey('iniFileName', iniFile) - #print 'deb:loadConfig iniFile: ', iniFile #---------------------- - if iniFile.lower().endswith(INIFILE_EXTENSION) and sys.exists(iniFile): - f = file(iniFile, 'r') - header_str = f.readline() - if header_str.startswith(INIFILE_HEADER): - data_str = f.read() - f.close() - #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #----------------- - data = eval(data_str) - for k, v in data[0].iteritems(): - try: GUI_A[k].val = v - except: GUI_A[k] = Draw.Create(v) - for k, v in data[1].iteritems(): - try: GUI_B[k].val = v - except: GUI_B[k] = Draw.Create(v) - else: - f.close() - Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile) - else: - Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid INI-file selected!') - print "DXF importer: Alert!: no valid INI-file selected." - if not iniFileName: - if dxfFileName.val.lower().endswith('.dxf'): - iniFileName.val = dxfFileName.val[0:-4] + INIFILE_EXTENSION - - - -def updateConfig(keywords, drawTypes): #----------------------------------------------- - """updates GUI_settings with given dictionaries - - """ - global GUI_A, GUI_B - #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #--------- - for k, v in keywords.iteritems(): - GUI_A[k].val = v - for k, v in drawTypes.iteritems(): - GUI_B[k].val = v - -def resetDefaultConfig(): #----------------------------------------------- - """Resets settings/config/materials to defaults. - - """ - #print 'deb:lresetDefaultConfig keywords_org: \n', keywords_org #--------- - updateConfig(keywords_org, drawTypes_org) - - -def presetConfig_curv(activate): #----------------------------------------------- - """Sets settings/config/materials for curve representation. - - """ - global GUI_A - if activate: - GUI_A['curves_on'].val = 1 - GUI_A['points_as'].val = 5 - GUI_A['lines_as'].val = 5 - GUI_A['mlines_as'].val = 5 - GUI_A['plines_as'].val = 5 - GUI_A['splines_as'].val = 5 - GUI_A['plines3_as'].val = 5 - else: - GUI_A['curves_on'].val = 0 - GUI_A['points_as'].val = 2 - GUI_A['lines_as'].val = 2 - GUI_A['mlines_as'].val = 2 - GUI_A['plines_as'].val = 2 - GUI_A['splines_as'].val = 6 - GUI_A['plines3_as'].val = 2 - - -def resetDefaultConfig_2D(): #----------------------------------------------- - """Sets settings/config/materials to defaults 2D. - - """ - presetConfig_curv(1) - keywords2d = { - 'views_on' : 0, - 'cams_on' : 0, - 'lights_on' : 0, - 'vGroup_on' : 1, - 'thick_on' : 0, - 'thick_force': 0, - 'width_on' : 1, - 'width_force': 0, - 'dist_on' : 1, - 'dist_force': 0, - 'fill_on' : 0, - 'pl_trim_on': 1, - 'Z_force_on': 0, - 'meshSmooth_on': 0, - 'solids_as' : 2, - 'blocks_as' : 1, - 'texts_as' : 1 - } - - drawTypes2d = { - 'point' : 1, - 'line' : 1, - 'arc' : 1, - 'circle': 1, - 'ellipse': 1, - 'mline' : 0, - 'polyline': 1, - 'spline': 1, - 'plmesh': 0, - 'pline3': 1, - 'lwpolyline': 1, - 'text' : 1, - 'mtext' : 0, - 'block' : 1, - 'insert': 1, - 'solid' : 1, - 'trace' : 1, - 'face' : 0, -# 'view' : 0, - } - - updateConfig(keywords2d, drawTypes2d) - -def resetDefaultConfig_3D(): #----------------------------------------------- - """Sets settings/config/materials to defaults 3D. - - """ - presetConfig_curv(0) - keywords3d = { -# 'views_on' : 1, -# 'cams_on' : 1, -# 'lights_on' : 1, - 'vGroup_on' : 1, - 'thick_on' : 1, - 'thick_force': 0, - 'width_on' : 1, - 'width_force': 0, - 'dist_on' : 1, - 'dist_force': 0, - 'fill_on' : 1, - 'pl_trim_on': 1, - 'Z_force_on': 0, - 'meshSmooth_on': 1, - 'solids_as' : 2, - 'blocks_as' : 1, - 'texts_as' : 1 - } - - drawTypes3d = { - 'point' : 1, - 'line' : 1, - 'arc' : 1, - 'circle': 1, - 'ellipse': 1, - 'mline' : 0, - 'polyline': 1, - 'spline': 1, - 'plmesh': 1, - 'pline3': 1, - 'lwpolyline': 1, - 'text' : 0, - 'mtext' : 0, - 'block' : 1, - 'insert': 1, - 'solid' : 1, - 'trace' : 1, - 'face' : 1, -# 'view' : 0, - } - - updateConfig(keywords3d, drawTypes3d) - - -def inputGlobalScale(): - """Pop-up UI-Block for global scale factor - """ - global GUI_A - #print 'deb:inputGlobalScale ##########' #------------ - x_scale = Draw.Create(GUI_A['g_scale'].val) - block = [] - #block.append("global translation vector:") - block.append(("", x_scale, 0.0, 10000000.0)) - - retval = Draw.PupBlock("set global scale factor:", block) - - GUI_A['g_scale'].val = float(x_scale.val) - - -def inputOriginVector(): - """Pop-up UI-Block for global translation vector - """ - global GUI_A - #print 'deb:inputOriginVector ##########' #------------ - x_origin = Draw.Create(GUI_A['g_originX'].val) - y_origin = Draw.Create(GUI_A['g_originY'].val) - z_origin = Draw.Create(GUI_A['g_originZ'].val) - block = [] - #block.append("global translation vector:") - block.append(("X: ", x_origin, -100000000.0, 100000000.0)) - block.append(("Y: ", y_origin, -100000000.0, 100000000.0)) - block.append(("Z: ", z_origin, -100000000.0, 100000000.0)) - - retval = Draw.PupBlock("set global translation vector:", block) - - GUI_A['g_originX'].val = x_origin.val - GUI_A['g_originY'].val = y_origin.val - GUI_A['g_originZ'].val = z_origin.val - - -def draw_UI(): #----------------------------------------------------------------- - """ Draw startUI and setup Settings. - """ - global GUI_A, GUI_B #__version__ - global user_preset, iniFileName, dxfFileName, config_UI, g_scale_as - global model_space_on - - # This is for easy layout changes - but_0c = 70 #button 1.column width - but_1c = 70 #button 1.column width - but_2c = 70 #button 2.column - but_3c = 70 #button 3.column - menu_margin = 10 - butt_margin = 10 - menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width - - simple_menu_h = 100 - extend_menu_h = 350 - y = simple_menu_h # y is menu upper.y - if config_UI.val: y += extend_menu_h - x = 20 #menu left.x - but0c = x + menu_margin #buttons 0.column position.x - but1c = but0c + but_0c + butt_margin - but2c = but1c + but_1c + butt_margin - but3c = but2c + but_2c + butt_margin - but4c = but3c + but_3c - - # Here starts menu ----------------------------------------------------- - #glClear(GL_COLOR_BUFFER_BIT) - #glRasterPos2d(8, 125) - - y += 30 - colorbox(x, y+20, x+menu_w+menu_margin*2, menu_margin) - Draw.Label("DXF/DWG-Importer v" + __version__, but0c, y, menu_w, 20) - - if config_UI.val: - b0, b0_ = but0c, but_0c + butt_margin - b1, b1_ = but1c, but_1c - y_top = y - - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_B['point'] = Draw.Toggle('POINT', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['point'].val, "support dxf-POINT on/off") - if GUI_B['point'].val: - GUI_A['points_as'] = Draw.Menu(points_as_menu, EVENT_NONE, b1, y, b1_, 20, GUI_A['points_as'].val, "select target Blender-object") -# Draw.Label('-->', but2c, y, but_2c, 20) - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['line'] = Draw.Toggle('LINE...etc', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['line'].val, "support dxf-LINE,ARC,CIRCLE,ELLIPSE on/off") - if GUI_B['line'].val: - GUI_A['lines_as'] = Draw.Menu(lines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['lines_as'].val, "select target Blender-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['mline'] = Draw.Toggle('..MLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['mline'].val, "(*todo)support dxf-MLINE on/off") - if GUI_B['mline'].val: - GUI_A['mlines_as'] = Draw.Menu(mlines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['mlines_as'].val, "select target Blender-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['spline'] = Draw.Toggle('SPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['spline'].val, "support dxf-SPLINE on/off") - if GUI_B['spline'].val: - GUI_A['splines_as'] = Draw.Menu(splines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['splines_as'].val, "select target Blender-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['polyline'] = Draw.Toggle('2D/LWPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['polyline'].val, "support dxf-2D-POLYLINE on/off") - if GUI_B['polyline'].val: - GUI_A['plines_as'] = Draw.Menu(plines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines_as'].val, "select target Blender-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['pline3'] = Draw.Toggle('3D-PLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['pline3'].val, "support dxf-3D-POLYLINE on/off") - if GUI_B['pline3'].val: - GUI_A['plines3_as'] = Draw.Menu(plines3_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines3_as'].val, "select target Blender-object") - Draw.EndAlign() - - y_down = y - # ----------------------------------------------- - - y = y_top - b0, b0_ = but2c, but_2c + butt_margin - b1, b1_ = but3c, but_3c - - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_B['plmesh'] = Draw.Toggle('PL-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_-40, 20, GUI_B['plmesh'].val, "support dxf-POLYMESH/POLYFACE on/off") -# GUI_A['plmesh_as'] = Draw.Menu(plmesh_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plmesh_as'].val, "select target Blender-object") - GUI_A['plmesh_flip'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-40, y, 20, 20, GUI_A['plmesh_flip'].val, "flip DXF normals on/off") - GUI_A['normals_out'] = Draw.Toggle('N', EVENT_NONE, b1+b1_-20, y, 20, 20, GUI_A['normals_out'].val, "force Blender normals to outside on/off") - Draw.EndAlign() - - y -= 20 - GUI_B['solid'] = Draw.Toggle('SOLID', EVENT_NONE, b0, y, b0_, 20, GUI_B['solid'].val, "support dxf-SOLID and TRACE on/off") - GUI_B['face'] = Draw.Toggle('3DFACE', EVENT_NONE, b1, y, b1_, 20, GUI_B['face'].val, "support dxf-3DFACE on/off") -# GUI_A['solids_as'] = Draw.Menu(solids_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['solids_as'].val, "select target Blender-object") - #print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------ - - - y -= 20 - GUI_B['text'] = Draw.Toggle('TEXT', EVENT_NONE, b0, y, b0_, 20, GUI_B['text'].val, "support dxf-TEXT on/off") - GUI_B['mtext'] = Draw.Toggle('..MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*todo)support dxf-MTEXT on/off") -# GUI_A['texts_as'] = Draw.Menu(texts_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['texts_as'].val, "select target Blender-object") - - y -= 20 - Draw.BeginAlign() - GUI_B['block'] = Draw.Toggle('BLOCK', EVENT_REDRAW, b0, y, b0_-30, 20, GUI_B['block'].val, "support dxf-BLOCK and ARRAY on/off") - GUI_B['insert'].val = GUI_B['block'].val - if GUI_B['block'].val: - GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "support hatch/noname BLOCKs *X... on/off") - GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1-15, y, 35, 20, GUI_A['xref_on'].val, "support for XREF-BLOCKs (place holders) on/off") - GUI_A['blocks_as'] = Draw.Menu(blocks_as_menu, EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['blocks_as'].val, "select target representation for imported BLOCKs") - Draw.EndAlign() - - - y -= 20 - y -= 20 - - Draw.BeginAlign() - GUI_A['views_on'] = Draw.Toggle('views', EVENT_NONE, b0, y, b0_-25, 20, GUI_A['views_on'].val, "imports VIEWs and VIEWPORTs as cameras on/off") - GUI_A['cams_on'] = Draw.Toggle('..cams', EVENT_NONE, b1-25, y, b1_-25, 20, GUI_A['cams_on'].val, "(*todo) support ASHADE cameras on/off") - GUI_A['lights_on'] = Draw.Toggle('..lights', EVENT_NONE, b1+25, y, b1_-25, 20, GUI_A['lights_on'].val, "(*todo) support AVE_RENDER lights on/off") - Draw.EndAlign() - - - if y < y_down: y_down = y - # -----end supported objects-------------------------------------- - - y_top = y_down - y = y_top - y -= 10 - y -= 20 - but_ = menu_w / 6 - b0 = but0c + (menu_w - but_*6)/2 - Draw.BeginAlign() - GUI_A['paper_space_on'] = Draw.Toggle('paper', EVENT_NONE, b0+but_*0, y, but_, 20, GUI_A['paper_space_on'].val, "import only from Paper-Space on/off") - GUI_A['layFrozen_on'] = Draw.Toggle ('frozen', EVENT_NONE, b0+but_*1, y, but_, 20, GUI_A['layFrozen_on'].val, "import also from frozen LAYERs on/off") - GUI_A['layerFilter_on'] = Draw.Toggle('..layer', EVENT_NONE, b0+but_*2, y, but_, 20, GUI_A['layerFilter_on'].val, "(*todo) LAYER filtering on/off") - GUI_A['colorFilter_on'] = Draw.Toggle('..color', EVENT_NONE, b0+but_*3, y, but_, 20, GUI_A['colorFilter_on'].val, "(*todo) COLOR filtering on/off") - GUI_A['groupFilter_on'] = Draw.Toggle('..group', EVENT_NONE, b0+but_*4, y, but_, 20, GUI_A['groupFilter_on'].val, "(*todo) GROUP filtering on/off") - GUI_A['blockFilter_on'] = Draw.Toggle('..block', EVENT_NONE, b0+but_*5, y, but_, 20, GUI_A['blockFilter_on'].val, "(*todo) BLOCK filtering on/off") - #GUI_A['dummy_on'] = Draw.Toggle('-', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['dummy_on'].val, "dummy on/off") - Draw.EndAlign() - - # -----end filters-------------------------------------- - - b0, b0_ = but0c, but_0c + butt_margin - b1, b1_ = but1c, but_1c - - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_A['g_origin_on'] = Draw.Toggle('glob.reLoc', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_origin_on'].val, "global relocate all DXF objects on/off") - if GUI_A['g_origin_on'].val: - tmp = Draw.PushButton('=', EVENT_ORIGIN, b1, y, 20, 20, "edit relocation-vector (x,y,z in DXF units)") - origin_str = '(%.4f, %.4f, %.4f)' % ( - GUI_A['g_originX'].val, - GUI_A['g_originY'].val, - GUI_A['g_originZ'].val - ) - tmp = Draw.Label(origin_str, b1+20, y, 300, 20) - #GUI_A['g_origin'] = Draw.String('', EVENT_ORIGIN, b1, y, b1_, 20, GUI_A['g_origin'].val, "global translation-vector (x,y,z) in DXF units") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['g_scale_on'] = Draw.Toggle('glob.Scale', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['g_scale_on'].val, "global scale all DXF objects on/off") - if GUI_A['g_scale_on'].val: - g_scale_as = Draw.Menu(g_scale_list, EVENT_SCALE, b1, y, 45, 20, g_scale_as.val, "factor for scaling the DXFdata") - if g_scale_as.val == 12: - pass - else: - if g_scale_as.val == 6: #scale inches to meters - GUI_A['g_scale'].val = 0.0254000 - elif g_scale_as.val == 7: #scale feets to meters - GUI_A['g_scale'].val = 0.3048000 - elif g_scale_as.val == 8: #scale yards to meters - GUI_A['g_scale'].val = 0.9144000 - else: - GUI_A['g_scale'].val = 10.0 ** int(g_scale_as.val) - scale_float = GUI_A['g_scale'].val - if scale_float < 0.000001 or scale_float > 1000000: - scale_str = ' = %s' % GUI_A['g_scale'].val - else: - scale_str = ' = %.6f' % GUI_A['g_scale'].val - Draw.Label(scale_str, b1+45, y, 200, 20) - Draw.EndAlign() - - y_down = y - # -----end material,translate,scale------------------------------------------ - - b0, b0_ = but0c, but_0c + butt_margin - b1, b1_ = but1c, but_1c - - y_top = y_down - y = y_top - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_A['meshSmooth_on'] = Draw.Toggle('smooth', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['meshSmooth_on'].val, "mesh smooth for circles/arc-segments on/off") - GUI_A['pl_trim_on'] = Draw.Toggle('trim', EVENT_NONE, b1-20, y, 32, 20, GUI_A['pl_trim_on'].val, "clean intersection of POLYLINE-wide-segments on/off") - GUI_A['pl_trim_max'] = Draw.Number('', EVENT_NONE, b1+12, y, b1_-12, 20, GUI_A['pl_trim_max'].val, 0, 5, "threshold intersection of POLYLINE-wide-segments: 0.0-5.0") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() -# GUI_A['thin_res'] = Draw.Number('thin:', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['thin_res'].val, 4, 64, "thin cylinder resolution - number of segments (4-64)") - GUI_A['arc_rad'] = Draw.Number('bR:', EVENT_NONE, b0, y, b0_, 20, GUI_A['arc_rad'].val, 0.01, 100, "basis radius for arc/circle resolution (0.01-100)") - GUI_A['arc_res'] = Draw.Number('', EVENT_NONE, b1, y, b1_/2, 20, GUI_A['arc_res'].val, 3, 500, "arc/circle resolution - number of segments (3-500)") - GUI_A['fill_on'] = Draw.Toggle('caps', EVENT_NONE, b1+b1_/2, y, b1_/2, 20, GUI_A['fill_on'].val, "draws top and bottom caps of CYLINDERs/closed curves on/off") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['curve_arc'] = Draw.Number('', EVENT_NONE, b0, y, b0_/2, 20, GUI_A['curve_arc'].val, 3, 32, "Bezier circle: amount of segments: 3-32") - GUI_A['curve_res'] = Draw.Number('', EVENT_NONE, b0+b0_/2, y, b0_/2, 20, GUI_A['curve_res'].val, 1, 128, "Set the Curve's U-resolution value: 1-128") - GUI_A['curves_on'] = Draw.Toggle('to Curves', EVENT_PRESETCURV, b1, y, b1_, 20, GUI_A['curves_on'].val, "set Curve as target object type on/off") - Draw.EndAlign() - - y -= 20 - GUI_A['group_bylayer_on'] = Draw.Toggle('Layer', EVENT_NONE, b0, y, 30, 20, GUI_A['group_bylayer_on'].val, "DXF-entities group by layer on/off") - GUI_A['vGroup_on'] = Draw.Toggle('vGroups', EVENT_NONE, b0+30, y, b1_-10, 20, GUI_A['vGroup_on'].val, "sort faces into VertexGroups on/off") - GUI_A['one_mesh_on'] = Draw.Toggle('oneMesh', EVENT_NONE, b1+10, y, b1_-10, 20, GUI_A['one_mesh_on'].val, "draw DXF-entities into one mesh-object. Recommended for big DXF-files. on/off") - - y -= 30 - Draw.BeginAlign() - GUI_A['material_on'] = Draw.Toggle('material', EVENT_REDRAW, b0, y, b0_-20, 20, GUI_A['material_on'].val, "support for material assignment on/off") - if GUI_A['material_on'].val: - GUI_A['material_from'] = Draw.Menu(material_from_menu, EVENT_NONE, b1-20, y, b1_+20, 20, GUI_A['material_from'].val, "material assignment from?") - Draw.EndAlign() - - y_down = y - # ----------------------------------------------- - - b0, b0_ = but2c, but_2c + butt_margin - b1, b1_ = but3c, but_3c - - y = y_top - y -= 10 - y -= 20 - Draw.BeginAlign() - GUI_A['Z_force_on'] = Draw.Toggle('.elevation', EVENT_REDRAW, b0, y, b0_, 20, GUI_A['Z_force_on'].val, ".set objects Z-coordinates to elevation on/off") - if GUI_A['Z_force_on'].val: - GUI_A['Z_elev'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['Z_elev'].val, -1000, 1000, "set default elevation(Z-coordinate)") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['dist_on'] = Draw.Toggle('dist.:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['dist_on'].val, "support distance on/off") - GUI_A['dist_force'] = Draw.Toggle('F', EVENT_NONE, b0+b0_-20, y, 20, 20, GUI_A['dist_force'].val, "force minimal distance on/off") - GUI_A['dist_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['dist_min'].val, 0, 10, "minimal length/distance (double.vertex removing)") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['thick_on'] = Draw.Toggle('thick:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['thick_on'].val, "support thickness on/off") - GUI_A['thick_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['thick_force'].val, "force for thickness at least limiter value on/off") - if GUI_A['thick_force'].val: - GUI_A['thick_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['thick_min'].val, 0, 10, "minimal value for thickness") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_A['width_on'] = Draw.Toggle('width:', EVENT_NONE, b0, y, b0_-20, 20, GUI_A['width_on'].val, "support width on/off") - GUI_A['width_force'] = Draw.Toggle('F', EVENT_REDRAW, b0+b0_-20, y, 20, 20, GUI_A['width_force'].val, "force for width at least limiter value on/off") - if GUI_A['width_force'].val: - GUI_A['width_min'] = Draw.Number('', EVENT_NONE, b1, y, b1_, 20, GUI_A['width_min'].val, 0, 10, "minimal value for width") - Draw.EndAlign() - - y -= 30 - but, but_ = but2c, 25 - Draw.BeginAlign() - Draw.EndAlign() - - if y < y_down: y_down = y - # -----end options -------------------------------------- - - - #-------------------------------------- - y_top = y_down - y = y_top - #GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved") - y -= 30 - Draw.BeginAlign() - Draw.PushButton('INI file >', EVENT_CHOOSE_INI, but0c, y, but_0c, 20, 'Select INI-file from project directory') - iniFileName = Draw.String(' :', EVENT_NONE, but1c, y, menu_w-but_1c-60, 20, iniFileName.val, FILENAME_MAX, "write here the name of the INI-file") - but = but4c-60 - Draw.PushButton('#', EVENT_PRESETS, but, y, 20, 20, "toggle Preset-INI-files") - Draw.PushButton('L', EVENT_LOAD_INI, but+20, y, 20, 20, 'Loads configuration from ini-file: %s' % iniFileName.val) - Draw.PushButton('S', EVENT_SAVE_INI, but+40, y, 20, 20, 'Saves configuration to ini-file: %s' % iniFileName.val) - Draw.EndAlign() - - - b0, b0_ = but2c, but_2c + butt_margin - b1, b1_ = but3c, but_3c - - y = simple_menu_h - bm = butt_margin/2 - - #y -= 10 - Draw.BeginAlign() - Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF/DWG-file for import') - dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF/DWG-file or type *.dxf/*.dwg for multiple files") - Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'set filter for import all files from this directory') - Draw.EndAlign() - - y -= 30 - config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but0c, y, but_0c+bm, 20, config_UI.val, 'Advanced configuration on/off' ) - Draw.BeginAlign() - but, but_ = but1c, but_1c+bm - but_ /= 3 - Draw.PushButton('X', EVENT_RESET, but, y, 15, 20, "reset configuration to defaults") - Draw.PushButton('2D', EVENT_PRESET2D, but+but_, y, but_, 20, 'set configuration for 2D import') - Draw.PushButton('3D', EVENT_PRESET3D, but+(but_*2), y, but_, 20, 'set configuration for 3D import') - Draw.EndAlign() - - Draw.BeginAlign() - GUI_A['newScene_on'] = Draw.Toggle('newScene', EVENT_NONE, but2c, y, but_2c, 20, GUI_A['newScene_on'].val, "create new Scene for each imported dxf file on/off") - GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, but3c, y, but_3c, 20, GUI_A['target_layer'].val, 1, 18, "target Blender-layer (<19> reserved for block_definitions)") - Draw.EndAlign() - - y -= 40 - Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c+bm, 20, '' ) - Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c+bm, 20, 'calls DXF-Importer Manual Page on Wiki.Blender.org') - Draw.BeginAlign() - GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but2c, y+20, 40, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/directDrawing, 1=Verbose, 2=ProgressBar, 3=SilentMode") - Draw.EndAlign() - Draw.BeginAlign() - Draw.PushButton('TEST', EVENT_LIST, but2c, y, 40, 20, 'DXF-Analyze-Tool: reads data from selected dxf file and writes report in project_directory/dxf_blendname.INF') - Draw.PushButton('START IMPORT', EVENT_START, but2c+40, y, but_2c-40+but_3c+butt_margin, 40, 'Start the import process. For Cancel go to console and hit Ctrl-C') - Draw.EndAlign() - - - - - y -= 20 - Draw.BeginAlign() - Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20) - Draw.Label(LAB, but0c, y, menu_w, 20) - Draw.Label(' ', but0c+menu_w, y, menu_margin, 20) - Draw.EndAlign() - -#-- END GUI Stuf----------------------------------------------------- - -def colorbox(x,y,xright,bottom): - glColor3f(0.75, 0.75, 0.75) - glRecti(x + 1, y + 1, xright - 1, bottom - 1) - -def dxf_callback(input_filename): - global dxfFileName - if input_filename.lower()[-3:] in ('dwg','dxf'): - dxfFileName.val=input_filename -# dirname == sys.dirname(Blender.Get('filename')) -# update_RegistryKey('DirName', dirname) -# update_RegistryKey('dxfFileName', input_filename) - -def ini_callback(input_filename): - global iniFileName - iniFileName.val=input_filename - -def event(evt, val): - if evt in (Draw.QKEY, Draw.ESCKEY) and not val: - Draw.Exit() - -def bevent(evt): -# global EVENT_NONE,EVENT_LOAD_DXF,EVENT_LOAD_INI,EVENT_SAVE_INI,EVENT_EXIT - global config_UI, user_preset - global GUI_A, UI_MODE - - ######### Manages GUI events - if (evt==EVENT_EXIT): - Draw.Exit() - print 'DXF/DWG-Importer *** exit ***' #--------------------- - elif (evt==EVENT_CHOOSE_INI): - Window.FileSelector(ini_callback, "INI-file Selection", '*.ini') - elif (evt==EVENT_REDRAW): - Draw.Redraw() - elif (evt==EVENT_RESET): - resetDefaultConfig() - Draw.Redraw() - elif (evt==EVENT_PRESET2D): - resetDefaultConfig_2D() - Draw.Redraw() - elif (evt==EVENT_SCALE): - if g_scale_as.val == 12: - inputGlobalScale() - if GUI_A['g_scale'].val < 0.00000001: - GUI_A['g_scale'].val = 0.00000001 - Draw.Redraw() - elif (evt==EVENT_ORIGIN): - inputOriginVector() - Draw.Redraw() - elif (evt==EVENT_PRESET3D): - resetDefaultConfig_3D() - Draw.Redraw() - elif (evt==EVENT_PRESETCURV): - presetConfig_curv(GUI_A['curves_on'].val) - Draw.Redraw() - elif (evt==EVENT_PRESETS): - user_preset += 1 - index = str(user_preset) - if user_preset > 5: user_preset = 0; index = '' - iniFileName.val = INIFILE_DEFAULT_NAME + index + INIFILE_EXTENSION - Draw.Redraw() - elif (evt==EVENT_LIST): - dxfFile = dxfFileName.val - update_RegistryKey('dxfFileName', dxfFileName.val) - if dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile): - analyzeDXF(dxfFile) - else: - Draw.PupMenu('DXF importer: Alert!%t|no valid DXF-file selected!') - print "DXF importer: error, no valid DXF-file selected! try again" - Draw.Redraw() - elif (evt==EVENT_HELP): - try: - import webbrowser - webbrowser.open('http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D') - except: - Draw.PupMenu('DXF importer: HELP Alert!%t|no connection to manual-page on Blender-Wiki! try:|\ -http://wiki.blender.org/index.php?title=Scripts/Manual/Import/DXF-3D') - Draw.Redraw() - elif (evt==EVENT_LOAD_INI): - loadConfig() - Draw.Redraw() - elif (evt==EVENT_SAVE_INI): - saveConfig() - Draw.Redraw() - elif (evt==EVENT_DXF_DIR): - dxfFile = dxfFileName.val - dxfFileExt = '*'+dxfFile.lower()[-4:] #can be .dxf or .dwg - dxfPathName = '' - if '/' in dxfFile: - dxfPathName = '/'.join(dxfFile.split('/')[:-1]) + '/' - elif '\\' in dxfFile: - dxfPathName = '\\'.join(dxfFile.split('\\')[:-1]) + '\\' - dxfFileName.val = dxfPathName + dxfFileExt -# dirname == sys.dirname(Blender.Get('filename')) -# update_RegistryKey('DirName', dirname) -# update_RegistryKey('dxfFileName', dxfFileName.val) - GUI_A['newScene_on'].val = 1 - Draw.Redraw() - elif (evt==EVENT_CHOOSE_DXF): - filename = '' # '*.dxf' - if dxfFileName.val: filename = dxfFileName.val - Window.FileSelector(dxf_callback, "DXF/DWG-file Selection", filename) - elif (evt==EVENT_START): - dxfFile = dxfFileName.val - #print 'deb: dxfFile file: ', dxfFile #---------------------- - if E_M: dxfFileName.val, dxfFile = e_mode(dxfFile) #evaluation mode - update_RegistryKey('dxfFileName', dxfFileName.val) - if dxfFile.lower().endswith('*.dxf'): - if Draw.PupMenu('DXF importer will import all DXF-files from:|%s|OK?' % dxfFile) != -1: - UI_MODE = False - multi_import(dxfFile) - UI_MODE = True - Draw.Redraw() - - elif dxfFile.lower().endswith('*.dwg'): - if not extCONV_OK: Draw.PupMenu(extCONV_TEXT) - elif Draw.PupMenu('DWG importer will import all DWG-files from:|%s|OK?' % dxfFile) != -1: - #elif Draw.PupMenu('DWG importer will import all DWG-files from:|%s|Caution! overwrites existing DXF-files!| OK?' % dxfFile) != -1: - UI_MODE = False - multi_import(dxfFile) - UI_MODE = True - Draw.Redraw() - - elif sys.exists(dxfFile) and dxfFile.lower()[-4:] in ('.dxf','.dwg'): - if dxfFile.lower().endswith('.dwg') and (not extCONV_OK): - Draw.PupMenu(extCONV_TEXT) - else: - #print '\nStandard Mode: active' - if GUI_A['newScene_on'].val: - _dxf_file = dxfFile.split('/')[-1].split('\\')[-1] - _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' - _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:]) - global SCENE - SCENE = Blender.Scene.New(_dxf_file) - SCENE.makeCurrent() - Blender.Redraw() - #or so? Blender.Scene.makeCurrent(_dxf_file) - #sce = bpy.data.scenes.new(_dxf_file) - #bpy.data.scenes.active = sce - else: - SCENE = Blender.Scene.GetCurrent() - SCENE.objects.selected = [] # deselect all - main(dxfFile) - #SCENE.objects.selected = SCENE.objects - #Window.RedrawAll() - #Blender.Redraw() - #Draw.Redraw() - else: - Draw.PupMenu('DXF importer: nothing imported!%t|no valid DXF-file selected!') - print "DXF importer: nothing imported, no valid DXF-file selected! try again" - Draw.Redraw() - - - - -def multi_import(DIR): - """Imports all DXF-files from directory DIR. - - """ - global SCENE - batchTIME = sys.time() - #if #DIR == "": DIR = os.path.curdir - if DIR == "": - DIR = sys.dirname(Blender.Get('filename')) - EXT = '.dxf' - else: - EXT = DIR[-4:] # get last 4 characters '.dxf' - DIR = DIR[:-5] # cut last 5 characters '*.dxf' - print 'importing multiple %s files from %s' %(EXT,DIR) - files = \ - [sys.join(DIR, f) for f in os.listdir(DIR) if f.lower().endswith(EXT)] - if not files: - print '...None %s-files found. Abort!' %EXT - return - - i = 0 - for dxfFile in files: - i += 1 - print '\n%s-file' %EXT, i, 'of', len(files) #,'\nImporting', dxfFile - if GUI_A['newScene_on'].val: - _dxf_file = dxfFile.split('/')[-1].split('\\')[-1] - _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' - _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:]) - SCENE = Blender.Scene.New(_dxf_file) - SCENE.makeCurrent() - #or so? Blender.Scene.makeCurrent(_dxf_file) - #sce = bpy.data.scenes.new(_dxf_file) - #bpy.data.scenes.active = sce - else: - SCENE = Blender.Scene.GetCurrent() - SCENE.objects.selected = [] # deselect all - main(dxfFile) - #Blender.Redraw() - - print 'TOTAL TIME: %.6f' % (sys.time() - batchTIME) - print '\a\r', # beep when done - Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % (sys.time() - batchTIME)) - - -if __name__ == "__main__": - #Draw.PupMenu('DXF importer: Abort%t|This script version works for Blender up 2.49 only!') - UI_MODE = True - # recall last used DXF-file and INI-file names - dxffilename = check_RegistryKey('dxfFileName') - #print 'deb:start dxffilename:', dxffilename #---------------- - if dxffilename: dxfFileName.val = dxffilename - else: - dirname = sys.dirname(Blender.Get('filename')) - #print 'deb:start dirname:', dirname #---------------- - dxfFileName.val = sys.join(dirname, '') - inifilename = check_RegistryKey('iniFileName') - if inifilename: iniFileName.val = inifilename - - Draw.Register(draw_UI, event, bevent) - - -""" -if 1: - # DEBUG ONLY - UI_MODE = False - TIME= sys.time() - #DIR = '/dxf_r12_testfiles/' - DIR = '/metavr/' - import os - print 'Searching for files' - os.system('find %s -iname "*.dxf" > /tmp/tempdxf_list' % DIR) - # os.system('find /storage/ -iname "*.dxf" > /tmp/tempdxf_list') - print '...Done' - file= open('/tmp/tempdxf_list', 'r') - lines= file.readlines() - file.close() - # sort by filesize for faster testing - lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] - lines_size.sort() - lines = [f[1] for f in lines_size] - - for i, _dxf in enumerate(lines): - if i >= 70: - #if 1: - print 'Importing', _dxf, '\nNUMBER', i, 'of', len(lines) - if True: - _dxf_file= _dxf.split('/')[-1].split('\\')[-1] - _dxf_file = _dxf_file[:-4] # cut last char:'.dxf' - _dxf_file = _dxf_file[:MAX_NAMELENGTH] #? [-MAX_NAMELENGTH:]) - sce = bpy.data.scenes.new(_dxf_file) - bpy.data.scenes.active = sce - dxfFileName.val = _dxf - main(_dxf) - - print 'TOTAL TIME: %.6f' % (sys.time() - TIME) -""" \ No newline at end of file diff --git a/release/scripts/import_edl.py b/release/scripts/import_edl.py deleted file mode 100644 index 8c5d041b34c..00000000000 --- a/release/scripts/import_edl.py +++ /dev/null @@ -1,961 +0,0 @@ -#!BPY - -""" -Name: 'Video Sequence (.edl)...' -Blender: 248 -Group: 'Import' -Tooltip: 'Load a CMX formatted EDL into the sequencer' -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2009: Campbell Barton, ideasman42@gmail.com -# -# 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, -# -------------------------------------------------------------------------- - -class TimeCode(object): - ''' - Simple timecode class - also supports conversion from other time strings used by EDL - ''' - def __init__(self, data, fps): - self.fps= fps - if type(data)==str: - self.fromString(data) - frame = self.asFrame() - self.fromFrame(frame) - else: - self.fromFrame(data) - - def fromString(self, text): - # hh:mm:ss:ff - # No dropframe support yet - - if text.lower().endswith('mps'): # 5.2mps - return self.fromFrame( int( float(text[:-3]) * self.fps ) ) - elif text.lower().endswith('s'): # 5.2s - return self.fromFrame( int( float(text[:-1]) * self.fps ) ) - elif text.isdigit(): # 1234 - return self.fromFrame( int(text) ) - elif ':' in text: # hh:mm:ss:ff - text= text.replace(';', ':').replace(',', ':').replace('.', ':') - text= text.split(':') - - self.hours= int(text[0]) - self.minutes= int(text[1]) - self.seconds= int(text[2]) - self.frame= int(text[3]) - return self - else: - print 'ERROR: could not convert this into timecode "%s"' % test - return self - - - def fromFrame(self, frame): - - if frame < 0: - frame = -frame; - neg=True - else: - neg=False - - fpm = 60 * self.fps - fph = 60 * fpm - - if frame < fph: - self.hours= 0 - else: - self.hours= int(frame/fph) - frame = frame % fph - - if frame < fpm: - self.minutes= 0 - else: - self.minutes= int(frame/fpm) - frame = frame % fpm - - if frame < self.fps: - self.seconds= 0 - else: - self.seconds= int(frame/self.fps) - frame = frame % self.fps - - self.frame= frame - - if neg: - self.frame = -self.frame - self.seconds = -self.seconds - self.minutes = -self.minutes - self.hours = -self.hours - - return self - - def asFrame(self): - abs_frame= self.frame - abs_frame += self.seconds * self.fps - abs_frame += self.minutes * 60 * self.fps - abs_frame += self.hours * 60 * 60 * self.fps - - return abs_frame - - def asString(self): - self.fromFrame(int(self)) - return '%.2d:%.2d:%.2d:%.2d' % (self.hours, self.minutes, self.seconds, self.frame) - - def __repr__(self): - return self.asString() - - # Numeric stuff, may as well have this - def __neg__(self): return TimeCode(-int(self), self.fps) - def __int__(self): return self.asFrame() - def __sub__(self, other): return TimeCode(int(self)-int(other), self.fps) - def __add__(self, other): return TimeCode(int(self)+int(other), self.fps) - def __mul__(self, other): return TimeCode(int(self)*int(other), self.fps) - def __div__(self, other): return TimeCode(int(self)/int(other), self.fps) - def __abs__(self): return TimeCode(abs(int(self)), self.fps) - def __iadd__(self, other): return self.fromFrame(int(self)+int(other)) - def __imul__(self, other): return self.fromFrame(int(self)*int(other)) - def __idiv__(self, other): return self.fromFrame(int(self)/int(other)) -# end timecode - - -'''Comments -Comments can appear at the beginning of the EDL file (header) or between the edit lines in the EDL. The first block of comments in the file is defined to be the header comments and they are associated with the EDL as a whole. Subsequent comments in the EDL file are associated with the first edit line that appears after them. -Edit Entries - [num] [duration] [srcIn] [srcOut] [recIn] [recOut] - - * : Filename or tag value. Filename can be for an MPEG file, Image file, or Image file template. Image file templates use the same pattern matching as for command line glob, and can be used to specify images to encode into MPEG. i.e. /usr/data/images/image*.jpg - * : 'V' | 'A' | 'VA' | 'B' | 'v' | 'a' | 'va' | 'b' which equals Video, Audio, Video_Audio edits (note B or b can be used in place of VA or va). - * : 'C' | 'D' | 'E' | 'FI' | 'FO' | 'W' | 'c' | 'd' | 'e' | 'fi' | 'fo' | 'w'. which equals Cut, Dissolve, Effect, FadeIn, FadeOut, Wipe. - * [num]: if TransitionType = Wipe, then a wipe number must be given. At the moment only wipe 'W0' and 'W1' are supported. - * [duration]: if the TransitionType is not equal to Cut, then an effect duration must be given. Duration is in frames. - * [srcIn]: Src in. If no srcIn is given, then it defaults to the first frame of the video or the first frame in the image pattern. If srcIn isn't specified, then srcOut, recIn, recOut can't be specified. - * [srcOut]: Src out. If no srcOut is given, then it defaults to the last frame of the video - or last image in the image pattern. if srcOut isn't given, then recIn and recOut can't be specified. - * [recIn]: Rec in. If no recIn is given, then it is calculated based on its position in the EDL and the length of its input. - [recOut]: Rec out. If no recOut is given, then it is calculated based on its position in the EDL and the length of its input. first frame of the video. - -For srcIn, srcOut, recIn, recOut, the values can be specified as either timecode, frame number, seconds, or mps seconds. i.e. -[tcode | fnum | sec | mps], where: - - * tcode : SMPTE timecode in hh:mm:ss:ff - * fnum : frame number (the first decodable frame in the video is taken to be frame 0). - * sec : seconds with 's' suffix (e.g. 5.2s) - * mps : seconds with 'mps' suffix (e.g. 5.2mps). This corresponds to the 'seconds' value displayed by Windows MediaPlayer. - -More notes, -Key - -''' - -enum= 0 -TRANSITION_UNKNOWN= enum -TRANSITION_CUT= enum; enum+=1 -TRANSITION_DISSOLVE= enum; enum+=1 -TRANSITION_EFFECT= enum; enum+=1 -TRANSITION_FADEIN= enum; enum+=1 -TRANSITION_FADEOUT= enum; enum+=1 -TRANSITION_WIPE= enum; enum+=1 -TRANSITION_KEY= enum; enum+=1 - -TRANSITION_DICT={ \ - 'c':TRANSITION_CUT, - 'd':TRANSITION_DISSOLVE, - 'e':TRANSITION_EFFECT, - 'fi':TRANSITION_FADEIN, - 'fo':TRANSITION_FADEOUT, - 'w':TRANSITION_WIPE, - 'k':TRANSITION_KEY, - } - -enum= 0 -EDIT_UNKNOWN= 1<= 1.0: - mov.endStill = int(mov.length * (scale - 1.0)) - else: - speed.speedEffectGlobalSpeed = 1.0/scale - meta.endOffset = mov.length - int(mov.length*scale) - - speed.update() - meta.update() - return meta - -def apply_dissolve_ipo(mov, blendin): - len_disp = float(mov.endDisp - mov.startDisp) - - if len_disp <= 0.0: - print 'Error, strip is zero length' - return - - mov.ipo= ipo= bpy.data.ipos.new("fade", "Sequence") - icu= ipo.addCurve('Fac') - - icu.interpolation= Blender.IpoCurve.InterpTypes.LINEAR - icu.append((0, 0)) - icu.append(((int(blendin)/len_disp) * 100, 1)) - - if mov.type not in (SEQ_HD_SOUND, SEQ_RAM_SOUND): - mov.blendMode = Blender.Scene.Sequence.BlendModes.ALPHAOVER - - -def replace_ext(path, ext): - return path[:path.rfind('.')+1] + ext - -def load_edl(filename, reel_files, reel_offsets): - ''' - reel_files - key:reel <--> reel:filename - ''' - - # For test file - # frame_offset = -769 - - - sce= bpy.data.scenes.active - fps= sce.render.fps - - elist= EditList() - if not elist.parse(filename, fps): - return 'Unable to parse "%s"' % filename - # elist.clean() - - - seq= sce.sequence - - track= 0 - - edits = elist.edits[:] - # edits.sort(key = lambda edit: int(edit.recIn)) - - prev_edit = None - for edit in edits: - print edit - frame_offset = reel_offsets[edit.reel] - - - src_start= int(edit.srcIn) + frame_offset - src_end= int(edit.srcOut) + frame_offset - src_length= src_end-src_start - - rec_start= int(edit.recIn) + 1 - rec_end= int(edit.recOut) + 1 - rec_length= rec_end-rec_start - - # print src_length, rec_length, src_start - - if edit.m2 != None: scale = fps/float(edit.m2.fps) - else: scale = 1.0 - - unedited_start= rec_start - src_start - offset_start = src_start - int(src_start*scale) # works for scaling up AND down - - if edit.transition_type == TRANSITION_CUT and (not elist.testOverlap(edit)): - track = 1 - - strip= None - final_strips = [] - if edit.reel.lower()=='bw': - strip= seq.new((0,0,0), rec_start, track+1) - strip.length= rec_length # for color its simple - final_strips.append(strip) - else: - - path_full = reel_files[edit.reel] - path_fileonly= path_full.split('/')[-1].split('\\')[-1] # os.path.basename(full) - path_dironly= path_full[:-len(path_fileonly)] # os.path.dirname(full) - - if edit.edit_type & EDIT_VIDEO: #and edit.transition_type == TRANSITION_CUT: - - try: - strip= seq.new((path_fileonly, path_dironly, path_full, 'movie'), unedited_start + offset_start, track+1) - except: - return 'Invalid input for movie' - - # Apply scaled rec in bounds - if scale != 1.0: - meta = scale_meta_speed(seq, strip, scale) - final_strip = meta - else: - final_strip = strip - - - final_strip.update() - final_strip.startOffset= rec_start - final_strip.startDisp - final_strip.endOffset= rec_end- final_strip.endDisp - final_strip.update() - final_strip.endOffset += (final_strip.endDisp - rec_end) - final_strip.update() - - - if edit.transition_duration: - if not prev_edit: - print "Error no previous strip" - else: - new_end = rec_start + int(edit.transition_duration) - for other in prev_edit.custom_data: - if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND: - other.endOffset += (other.endDisp - new_end) - other.update() - - # Apply disolve - if edit.transition_type == TRANSITION_DISSOLVE: - apply_dissolve_ipo(final_strip, edit.transition_duration) - - if edit.transition_type == TRANSITION_WIPE: - other_track = track + 2 - for other in prev_edit.custom_data: - if other.type != SEQ_HD_SOUND and other.type != SEQ_RAM_SOUND: - - strip_wipe= seq.new((SEQ_WIPE, other, final_strip), 1, other_track) - - if edit.wipe_type == WIPE_0: - strip_wipe.wipeEffectAngle = 90 - else: - strip_wipe.wipeEffectAngle = -90 - - other_track += 1 - - - - # strip.endOffset= strip.length - int(edit.srcOut) - #end_offset= (unedited_start+strip.length) - end - # print start, end, end_offset - #strip.endOffset = end_offset - - # break - # print strip - - final_strips.append(final_strip) - - - if edit.edit_type & (EDIT_AUDIO | EDIT_AUDIO_STEREO | EDIT_VIDEO_AUDIO): - - if scale == 1.0: # TODO - scaled audio - - try: - strip= seq.new((path_fileonly, path_dironly, path_full, 'audio_hd'), unedited_start + offset_start, track+6) - except: - - # See if there is a wave file there - path_full_wav = replace_ext(path_full, 'wav') - path_fileonly_wav = replace_ext(path_fileonly, 'wav') - - #try: - strip= seq.new((path_fileonly_wav, path_dironly, path_full_wav, 'audio_hd'), unedited_start + offset_start, track+6) - #except: - # return 'Invalid input for audio' - - final_strip = strip - - # Copied from above - final_strip.update() - final_strip.startOffset= rec_start - final_strip.startDisp - final_strip.endOffset= rec_end- final_strip.endDisp - final_strip.update() - final_strip.endOffset += (final_strip.endDisp - rec_end) - final_strip.update() - - if edit.transition_type == TRANSITION_DISSOLVE: - apply_dissolve_ipo(final_strip, edit.transition_duration) - - final_strips.append(final_strip) - - # strip= seq.new((0.6, 0.6, 0.6), start, track+1) - - if final_strips: - for strip in final_strips: - # strip.length= length - final_strip.name = edit.asName() - edit.custom_data[:]= final_strips - # track = not track - prev_edit = edit - track += 1 - - #break - - - def recursive_update(s): - s.update(1) - for s_kid in s: - recursive_update(s_kid) - - - for s in seq: - recursive_update(s) - - return '' - - - -#load_edl('/fe/edl/EP30CMXtrk1.edl') # /tmp/test.edl -#load_edl('/fe/edl/EP30CMXtrk2.edl') # /tmp/test.edl -#load_edl('/fe/edl/EP30CMXtrk3.edl') # /tmp/test.edl -#load_edl('/root/vid/rush/blender_edl.edl', ['/root/vid/rush/rushes3.avi',]) # /tmp/test.edl - - - - -# ---------------------- Blender UI part -from Blender import Draw, Window -import BPyWindow - -if 0: - DEFAULT_FILE_EDL = '/root/vid/rush/blender_edl.edl' - DEFAULT_FILE_MEDIA = '/root/vid/rush/rushes3_wav.avi' - DEFAULT_FRAME_OFFSET = -769 -else: - DEFAULT_FILE_EDL = '' - DEFAULT_FILE_MEDIA = '' - DEFAULT_FRAME_OFFSET = 0 - -B_EVENT_IMPORT = 1 -B_EVENT_RELOAD = 2 -B_EVENT_FILESEL_EDL = 3 -B_EVENT_NOP = 4 - -B_EVENT_FILESEL = 100 # or greater - -class ReelItemUI(object): - __slots__ = 'filename_but', 'offset_but', 'ui_text' - def __init__(self): - self.filename_but = Draw.Create(DEFAULT_FILE_MEDIA) - self.offset_but = Draw.Create(DEFAULT_FRAME_OFFSET) - self.ui_text = '' - - - -REEL_UI = {} # reel:ui_string - - -#REEL_FILENAMES = {} # reel:filename -#REEL_OFFSETS = {} # reel:filename - -PREF = {} - -PREF['filename'] = Draw.Create(DEFAULT_FILE_EDL) -PREF['reel_act'] = '' - -def edl_reload(): - Window.WaitCursor(1) - filename = PREF['filename'].val - sce= bpy.data.scenes.active - fps= sce.render.fps - - elist= EditList() - - if filename: - if not elist.parse(filename, fps): - Draw.PupMenu('Error%t|Could not open the file "' + filename + '"') - reels = elist.getReels() - else: - reels = {} - - REEL_UI.clear() - for reel_key, edits in reels.iteritems(): - - if reel_key == 'bw': - continue - - flag = 0 - for edit in edits: - flag |= edit.edit_type - - reel_item = REEL_UI[reel_key] = ReelItemUI() - - reel_item.ui_text = '%s (%s): ' % (reel_key, editFlagsToText(flag)) - - Window.WaitCursor(0) - -def edl_set_path(filename): - PREF['filename'].val = filename - edl_reload() - Draw.Redraw() - -def edl_set_path_reel(filename): - REEL_UI[PREF['reel_act']].filename_but.val = filename - Draw.Redraw() - -def edl_reel_keys(): - reel_keys = REEL_UI.keys() - - if 'bw' in reel_keys: - reel_keys.remove('bw') - - reel_keys.sort() - return reel_keys - -def edl_draw(): - - MARGIN = 4 - rect = BPyWindow.spaceRect() - but_width = int((rect[2]-MARGIN*2)/4.0) # 72 - # Clamp - if but_width>100: but_width = 100 - but_height = 17 - - x=MARGIN - y=rect[3]-but_height-MARGIN - xtmp = x - - - - # ---------- ---------- ---------- ---------- - Blender.Draw.BeginAlign() - PREF['filename'] = Draw.String('edl path: ', B_EVENT_RELOAD, xtmp, y, (but_width*3)-20, but_height, PREF['filename'].val, 256, 'EDL Path'); xtmp += (but_width*3)-20; - Draw.PushButton('..', B_EVENT_FILESEL_EDL, xtmp, y, 20, but_height, 'Select an EDL file'); xtmp += 20; - Blender.Draw.EndAlign() - - Draw.PushButton('Reload', B_EVENT_RELOAD, xtmp + MARGIN, y, but_width - MARGIN, but_height, 'Read the ID Property settings from the active curve object'); xtmp += but_width; - y-=but_height + MARGIN - xtmp = x - # ---------- ---------- ---------- ---------- - - reel_keys = edl_reel_keys() - - - - if reel_keys: text = 'Reel file list...' - elif PREF['filename'].val == '': text = 'No EDL loaded.' - else: text = 'No reels found!' - - Draw.Label(text, xtmp + MARGIN, y, but_width*4, but_height); xtmp += but_width*4; - - y-=but_height + MARGIN - xtmp = x - - # ---------- ---------- ---------- ---------- - - - for i, reel_key in enumerate(reel_keys): - reel_item = REEL_UI[reel_key] - - Blender.Draw.BeginAlign() - REEL_UI[reel_key].filename_but = Draw.String(reel_item.ui_text, B_EVENT_NOP, xtmp, y, (but_width*3)-20, but_height, REEL_UI[reel_key].filename_but.val, 256, 'Select the reel path'); xtmp += (but_width*3)-20; - Draw.PushButton('..', B_EVENT_FILESEL + i, xtmp, y, 20, but_height, 'Media path to use for this reel'); xtmp += 20; - Blender.Draw.EndAlign() - - reel_item.offset_but= Draw.Number('ofs:', B_EVENT_NOP, xtmp + MARGIN, y, but_width - MARGIN, but_height, reel_item.offset_but.val, -100000, 100000, 'Start offset in frames when applying timecode'); xtmp += but_width - MARGIN; - - y-=but_height + MARGIN - xtmp = x - - # ---------- ---------- ---------- ---------- - - Draw.PushButton('Import CMX-EDL Sequencer Strips', B_EVENT_IMPORT, xtmp + MARGIN, MARGIN, but_width*4 - MARGIN, but_height, 'Load the EDL file into the sequencer'); xtmp += but_width*4; - y-=but_height + MARGIN - xtmp = x - - -def edl_event(evt, val): - pass - -def edl_bevent(evt): - - if evt == B_EVENT_NOP: - pass - elif evt == B_EVENT_IMPORT: - ''' - Load the file into blender with UI settings - ''' - filename = PREF['filename'].val - - reel_files = {} - reel_offsets = {} - - for reel_key, reel_item in REEL_UI.iteritems(): - reel_files[reel_key] = reel_item.filename_but.val - reel_offsets[reel_key] = reel_item.offset_but.val - - error = load_edl(filename, reel_files, reel_offsets) - if error != '': - Draw.PupMenu('Error%t|' + error) - else: - Window.RedrawAll() - - elif evt == B_EVENT_RELOAD: - edl_reload() - Draw.Redraw() - - elif evt == B_EVENT_FILESEL_EDL: - filename = PREF['filename'].val - if not filename: filename = Blender.sys.join(Blender.sys.expandpath('//'), '*.edl') - - Window.FileSelector(edl_set_path, 'Select EDL', filename) - - elif evt >= B_EVENT_FILESEL: - reel_keys = edl_reel_keys() - reel_key = reel_keys[evt - B_EVENT_FILESEL] - - filename = REEL_UI[reel_key].filename_but.val - if not filename: filename = Blender.sys.expandpath('//') - - PREF['reel_act'] = reel_key # so file set path knows which one to set - Window.FileSelector(edl_set_path_reel, 'Reel Media', filename) - - - -if __name__ == '__main__': - Draw.Register(edl_draw, edl_event, edl_bevent) - edl_reload() - diff --git a/release/scripts/import_lightwave_motion.py b/release/scripts/import_lightwave_motion.py deleted file mode 100644 index 20c87dfd5c6..00000000000 --- a/release/scripts/import_lightwave_motion.py +++ /dev/null @@ -1,244 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: <- these words are ignored -Name: 'Lightwave Motion (.mot)...' -Blender: 245 -Group: 'Import' -Tip: 'Import Loc Rot Size chanels from a Lightwave .mot file' -""" - -__author__ = "Daniel Salazar (ZanQdo)" -__url__ = ("blender", "blenderartists.org", -"e-mail: zanqdo@gmail.com") -__version__ = "16/04/08" - -__bpydoc__ = """\ -This script loads Lightwave motion files (.mot) -into the selected objects - -Usage: -Run the script with one or more objects selected (any kind) -Be sure to set the framerate correctly - -""" - -# $Id$ -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2003, 2004: A Vanpoucke -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import math as M -import Blender as B -import bpy - - -def FuncionPrincipal (Dir): - B.Window.WaitCursor(1) - ObjSelect = B.Object.GetSelected() - - if not ObjSelect: - B.Draw.PupMenu('Select one or more objects, aborting.') - return - - - SC = B.Scene.GetCurrent() - SCR = SC.getRenderingContext() - FrameRate = float(SCR.framesPerSec()) - - - # Creating new IPO - - IPO = B.Ipo.New('Object', 'LW_Motion') - - - # Creating Curves in the IPO - - LocX = IPO.addCurve("LocX") - LocX.setInterpolation("Bezier") - - LocY = IPO.addCurve("LocY") - LocX.setInterpolation("Bezier") - - LocZ = IPO.addCurve("LocZ") - LocX.setInterpolation("Bezier") - - RotX = IPO.addCurve("RotX") - LocX.setInterpolation("Bezier") - - RotY = IPO.addCurve("RotY") - LocX.setInterpolation("Bezier") - - RotZ = IPO.addCurve("RotZ") - LocX.setInterpolation("Bezier") - - ScaleX = IPO.addCurve("ScaleX") - LocX.setInterpolation("Bezier") - - ScaleY = IPO.addCurve("ScaleY") - LocX.setInterpolation("Bezier") - - ScaleZ = IPO.addCurve("ScaleZ") - LocX.setInterpolation("Bezier") - - - # Opening the mot file - - File = open (Dir, 'rU') - - - # Init flags - - CurChannel = -1 - ScaleFlag = 0 - - # Main file reading cycle - - for Line in File: - - ''' - # Number of channels in the file - - if "NumChannels" in Line: - Line = Line.split (' ') - NumChannels = int(Line[1]) - ''' - - # Current Channel Flag - - if "Channel 0" in Line: - CurChannel = 0 - - elif "Channel 1" in Line: - CurChannel = 1 - - elif "Channel 2" in Line: - CurChannel = 2 - - elif "Channel 3" in Line: - CurChannel = 3 - - elif "Channel 4" in Line: - CurChannel = 4 - - elif "Channel 5" in Line: - CurChannel = 5 - - elif "Channel 6" in Line: - CurChannel = 6 - - elif "Channel 7" in Line: - CurChannel = 7 - - elif "Channel 8" in Line: - CurChannel = 8 - - - # Getting the data and writing to IPOs - - if CurChannel == 0: - if "Key" in Line: - Line = Line.split (' ') - ValCh_0 = float (Line [3]) - TimeCh_0 = float (Line [4]) * FrameRate - LocX.addBezier ((TimeCh_0, ValCh_0)) - - if CurChannel == 1: - if "Key" in Line: - Line = Line.split (' ') - ValCh_1 = float (Line [3]) - TimeCh_1 = float (Line [4]) * FrameRate - LocZ.addBezier ((TimeCh_1, ValCh_1)) - - if CurChannel == 2: - if "Key" in Line: - Line = Line.split (' ') - ValCh_2 = float (Line [3]) - TimeCh_2 = float (Line [4]) * FrameRate - LocY.addBezier ((TimeCh_2, ValCh_2)) - - if CurChannel == 3: - if "Key" in Line: - Line = Line.split (' ') - ValCh_3 = M.degrees ( - float (Line [3]) ) / 10 - TimeCh_3 = float (Line [4]) * FrameRate - RotZ.addBezier ((TimeCh_3, ValCh_3)) - - if CurChannel == 4: - if "Key" in Line: - Line = Line.split (' ') - ValCh_4 = M.degrees ( - float (Line [3]) ) / 10 - TimeCh_4 = float (Line [4]) * FrameRate - RotX.addBezier ((TimeCh_4, ValCh_4)) - - if CurChannel == 5: - if "Key" in Line: - Line = Line.split (' ') - ValCh_5 = M.degrees ( - float (Line [3]) ) / 10 - TimeCh_5 = float (Line [4]) * FrameRate - RotY.addBezier ((TimeCh_5, ValCh_5)) - - if CurChannel == 6: - if "Key" in Line: - Line = Line.split (' ') - ValCh_6 = float (Line [3]) - TimeCh_6 = float (Line [4]) * FrameRate - ScaleX.addBezier ((TimeCh_6, ValCh_6)) - elif ScaleFlag < 3: - ScaleFlag += 1 - ScaleX.addBezier ((0, 1)) - - if CurChannel == 7: - if "Key" in Line: - Line = Line.split (' ') - ValCh_7 = float (Line [3]) - TimeCh_7 = float (Line [4]) * FrameRate - ScaleZ.addBezier ((TimeCh_7, ValCh_7)) - elif ScaleFlag < 3: - ScaleFlag += 1 - ScaleZ.addBezier ((0, 1)) - - if CurChannel == 8: - if "Key" in Line: - Line = Line.split (' ') - ValCh_8 = float (Line [3]) - TimeCh_8 = float (Line [4]) * FrameRate - ScaleY.addBezier ((TimeCh_8, ValCh_8)) - elif ScaleFlag < 3: - ScaleFlag += 1 - ScaleY.addBezier ((0, 1)) - - - # Link the IPO to all selected objects - - for ob in ObjSelect: - ob.setIpo(IPO) - - File.close() - - print '\nDone, the following motion file has been loaded:\n\n%s' % Dir - B.Window.WaitCursor(0) - -def main(): - B.Window.FileSelector(FuncionPrincipal, "Load IPO from .mot File", B.sys.makename(ext='.mot')) - -if __name__=='__main__': - main() - diff --git a/release/scripts/import_mdd.py b/release/scripts/import_mdd.py deleted file mode 100644 index 1ee196ab67f..00000000000 --- a/release/scripts/import_mdd.py +++ /dev/null @@ -1,158 +0,0 @@ -#!BPY - -""" - Name: 'Load MDD to Mesh RVKs' - Blender: 242 - Group: 'Import' - Tooltip: 'baked vertex animation to active mesh object.' -""" -__author__ = "Bill L.Nieuwendorp" -__bpydoc__ = """\ -This script Imports Lightwaves MotionDesigner format. - -The .mdd format has become quite a popular Pipeline format
-for moving animations from package to package. -""" -# mdd importer -# -# Warning if the vertex order or vertex count differs from the -# origonal model the mdd was Baked out from their will be Strange -# behavior -# -# -#vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0 -#A modifier to read mdd files would be Ideal but thats for another day :) -# -#Please send any fixes,updates,bugs to Slow67_at_Gmail.com -#Bill Niewuendorp - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - - - - -try: - from struct import unpack -except: - unpack = None - -import Blender -from Blender import Mesh, Object, Scene -import BPyMessages - -def mdd_import(filepath, ob, PREF_IPONAME, PREF_START_FRAME, PREF_JUMP): - - print '\n\nimporting mdd "%s"' % filepath - - Blender.Window.DrawProgressBar (0.0, "Importing mdd ...") - Blender.Window.EditMode(0) - Blender.Window.WaitCursor(1) - - file = open(filepath, 'rb') - frames, points = unpack(">2i", file.read(8)) - time = unpack((">%df" % frames), file.read(frames * 4)) - - print '\tpoints:%d frames:%d' % (points,frames) - - scn = Scene.GetCurrent() - ctx = scn.getRenderingContext() - Blender.Set("curframe", PREF_START_FRAME) - me = ob.getData(mesh=1) - - def UpdateMesh(me,fr): - for v in me.verts: - # 12 is the size of 3 floats - x,y,z= unpack('>3f', file.read(12)) - v.co[:] = x,z,y - me.update() - - Blender.Window.DrawProgressBar (0.4, "4 Importing mdd ...") - - - curfr = ctx.currentFrame() - print'\twriting mdd data...' - for i in xrange(frames): - Blender.Set("curframe", i+PREF_START_FRAME) - if len(me.verts) > 1 and (curfr >= PREF_START_FRAME) and (curfr <= PREF_START_FRAME+frames): - UpdateMesh(me, i) - ob.insertShapeKey() - - Blender.Window.DrawProgressBar (0.5, "5 Importing mdd ...") - - key= me.key - - # Add the key of its not there - if not key: - me.insertKey(1, 'relative') - key= me.key - - key.ipo = Blender.Ipo.New('Key', PREF_IPONAME) - ipo = key.ipo - # block = key.getBlocks() # not used. - all_keys = ipo.curveConsts - - for i in xrange(PREF_JUMP+1, len(all_keys), PREF_JUMP): - curve = ipo.getCurve(i) - if curve == None: - curve = ipo.addCurve(all_keys[i]) - - curve.append((PREF_START_FRAME+i-1,1)) - curve.append((PREF_START_FRAME+i- PREF_JUMP -1,0)) - curve.append((PREF_START_FRAME+i+ PREF_JUMP-1,0)) - curve.setInterpolation('Linear') - curve.recalc() - - print 'done' - Blender.Window.WaitCursor(0) - Blender.Window.DrawProgressBar (1.0, '') - - -def mdd_import_ui(filepath): - - if BPyMessages.Error_NoFile(filepath): - return - - scn= Scene.GetCurrent() - ob_act= scn.objects.active - - if ob_act == None or ob_act.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - PREF_IPONAME = Blender.Draw.Create(filepath.split('/')[-1].split('\\')[-1].split('.')[0]) - PREF_START_FRAME = Blender.Draw.Create(1) - PREF_JUMP = Blender.Draw.Create(1) - - block = [\ - ("Ipo Name: ", PREF_IPONAME, 0, 30, "Ipo name for the new shape key"),\ - ("Start Frame: ", PREF_START_FRAME, 1, 3000, "Start frame for the animation"),\ - ("Key Skip: ", PREF_JUMP, 1, 100, "KeyReduction, Skip every Nth Frame")\ - ] - - if not Blender.Draw.PupBlock("Import MDD", block): - return - orig_frame = Blender.Get('curframe') - mdd_import(filepath, ob_act, PREF_IPONAME.val, PREF_START_FRAME.val, PREF_JUMP.val) - Blender.Set('curframe', orig_frame) - -if __name__ == '__main__': - if not unpack: - Draw.PupMenu('Error%t|This script requires a full python install') - - Blender.Window.FileSelector(mdd_import_ui, 'IMPORT MDD', '*.mdd') diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py deleted file mode 100644 index 81230bfcf03..00000000000 --- a/release/scripts/import_obj.py +++ /dev/null @@ -1,1234 +0,0 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 249 -Group: 'Import' -Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' -""" - -__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" -__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] -__version__= "2.13" - -__bpydoc__= """\ -This script imports a Wavefront OBJ files to Blender. - -Usage: -Run this script from "File->Import" menu and then load the desired OBJ file. -Note, This loads mesh objects and materials only, nurbs and curves are not supported. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton 2007-2009 -# - V2.12- bspline import/export added (funded by PolyDimensions GmbH) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from Blender import Mesh, Draw, Window, Texture, Material, sys -import bpy -import BPyMesh -import BPyImage -import BPyMessages - -try: import os -except: os= False - -# Generic path functions -def stripFile(path): - '''Return directory, where the file is''' - lastSlash= max(path.rfind('\\'), path.rfind('/')) - if lastSlash != -1: - path= path[:lastSlash] - return '%s%s' % (path, sys.sep) - -def stripPath(path): - '''Strips the slashes from the back of a string''' - return path.split('/')[-1].split('\\')[-1] - -def stripExt(name): # name is a string - '''Strips the prefix off the name before writing''' - index= name.rfind('.') - if index != -1: - return name[ : index ] - else: - return name -# end path funcs - - - -def line_value(line_split): - ''' - Returns 1 string represneting the value for this line - None will be returned if theres only 1 word - ''' - length= len(line_split) - if length == 1: - return None - - elif length == 2: - return line_split[1] - - elif length > 2: - return ' '.join( line_split[1:] ) - -def obj_image_load(imagepath, DIR, IMAGE_SEARCH): - ''' - Mainly uses comprehensiveImageLoad - but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores. - ''' - - if '_' in imagepath: - image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) - if image: return image - # Did the exporter rename the image? - image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) - if image: return image - - # Return an image, placeholder if it dosnt exist - image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH) - return image - - -def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH): - ''' - Create all the used materials in this obj, - assign colors and images to the materials from all referenced material libs - ''' - DIR= stripFile(filepath) - - #==================================================================================# - # This function sets textures defined in .mtl file # - #==================================================================================# - def load_material_image(blender_material, context_material_name, imagepath, type): - - texture= bpy.data.textures.new(type) - texture.setType('Image') - - # Absolute path - c:\.. etc would work here - image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) - has_data = image.has_data - texture.image = image - - if not has_data: - try: - # first time using this image. We need to load it first - image.glLoad() - except: - # probably the image is crashed - pass - else: - has_data = image.has_data - - # Adds textures for materials (rendering) - if type == 'Kd': - if has_data and image.depth == 32: - # Image has alpha - blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) - texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') - blender_material.mode |= Material.Modes.ZTRANSP - blender_material.alpha = 0.0 - else: - blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) - - # adds textures to faces (Textured/Alt-Z mode) - # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func. - unique_material_images[context_material_name]= image, has_data # set the texface image - - elif type == 'Ka': - blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API - - elif type == 'Ks': - blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) - - elif type == 'Bump': - blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR) - elif type == 'D': - blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA) - blender_material.mode |= Material.Modes.ZTRANSP - blender_material.alpha = 0.0 - # Todo, unset deffuse material alpha if it has an alpha channel - - elif type == 'refl': - blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF) - - - # Add an MTL with the same name as the obj if no MTLs are spesified. - temp_mtl= stripExt(stripPath(filepath))+ '.mtl' - - if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: - material_libs.append( temp_mtl ) - del temp_mtl - - #Create new materials - for name in unique_materials: # .keys() - if name != None: - unique_materials[name]= bpy.data.materials.new(name) - unique_material_images[name]= None, False # assign None to all material images to start with, add to later. - - unique_materials[None]= None - unique_material_images[None]= None, False - - for libname in material_libs: - mtlpath= DIR + libname - if not sys.exists(mtlpath): - #print '\tError Missing MTL: "%s"' % mtlpath - pass - else: - #print '\t\tloading mtl: "%s"' % mtlpath - context_material= None - mtl= open(mtlpath, 'rU') - for line in mtl: #.xreadlines(): - if line.startswith('newmtl'): - context_material_name= line_value(line.split()) - if unique_materials.has_key(context_material_name): - context_material = unique_materials[ context_material_name ] - else: - context_material = None - - elif context_material: - # we need to make a material to assign properties to it. - line_split= line.split() - line_lower= line.lower().lstrip() - if line_lower.startswith('ka'): - context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) - elif line_lower.startswith('kd'): - context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) - elif line_lower.startswith('ks'): - context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) - elif line_lower.startswith('ns'): - context_material.setHardness( int((float(line_split[1])*0.51)) ) - elif line_lower.startswith('ni'): # Refraction index - context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3 - elif line_lower.startswith('d') or line_lower.startswith('tr'): - context_material.setAlpha(float(line_split[1])) - context_material.mode |= Material.Modes.ZTRANSP - elif line_lower.startswith('map_ka'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Ka') - elif line_lower.startswith('map_ks'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Ks') - elif line_lower.startswith('map_kd'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Kd') - elif line_lower.startswith('map_bump'): - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'Bump') - elif line_lower.startswith('map_d') or line_lower.startswith('map_tr'): # Alpha map - Dissolve - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'D') - - elif line_lower.startswith('refl'): # Reflectionmap - img_filepath= line_value(line.split()) - if img_filepath: - load_material_image(context_material, context_material_name, img_filepath, 'refl') - mtl.close() - - - - -def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): - ''' - Takes vert_loc and faces, and seperates into multiple sets of - (verts_loc, faces, unique_materials, dataname) - This is done so objects do not overload the 16 material limit. - ''' - - filename = stripExt(stripPath(filepath)) - - if not SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: - # use the filename for the object name since we arnt chopping up the mesh. - return [(verts_loc, faces, unique_materials, filename)] - - - def key_to_name(key): - # if the key is a tuple, join it to make a string - if type(key) == tuple: - return '%s_%s' % key - elif not key: - return filename # assume its a string. make sure this is true if the splitting code is changed - else: - return key - - # Return a key that makes the faces unique. - if SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: - def face_key(face): - return face[4] # object - - elif not SPLIT_OB_OR_GROUP and SPLIT_MATERIALS: - def face_key(face): - return face[2] # material - - else: # Both - def face_key(face): - return face[4], face[2] # object,material - - - face_split_dict= {} - - oldkey= -1 # initialize to a value that will never match the key - - for face in faces: - - key= face_key(face) - - if oldkey != key: - # Check the key has changed. - try: - verts_split, faces_split, unique_materials_split, vert_remap= face_split_dict[key] - except KeyError: - faces_split= [] - verts_split= [] - unique_materials_split= {} - vert_remap= [-1]*len(verts_loc) - - face_split_dict[key]= (verts_split, faces_split, unique_materials_split, vert_remap) - - oldkey= key - - face_vert_loc_indicies= face[0] - - # Remap verts to new vert list and add where needed - for enum, i in enumerate(face_vert_loc_indicies): - if vert_remap[i] == -1: - new_index= len(verts_split) - vert_remap[i]= new_index # set the new remapped index so we only add once and can reference next time. - face_vert_loc_indicies[enum] = new_index # remap to the local index - verts_split.append( verts_loc[i] ) # add the vert to the local verts - - else: - face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index - - matname= face[2] - if matname and not unique_materials_split.has_key(matname): - unique_materials_split[matname] = unique_materials[matname] - - faces_split.append(face) - - - # remove one of the itemas and reorder - return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.iteritems()] - - -def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): - ''' - Takes all the data gathered and generates a mesh, adding the new object to new_objects - deals with fgons, sharp edges and assigning materials - ''' - if not has_ngons: - CREATE_FGONS= False - - if unique_smooth_groups: - sharp_edges= {} - smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.iterkeys() ]) - context_smooth_group_old= -1 - - # Split fgons into tri's - fgon_edges= {} # Used for storing fgon keys - if CREATE_EDGES: - edges= [] - - context_object= None - - # reverse loop through face indicies - for f_idx in xrange(len(faces)-1, -1, -1): - - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object= faces[f_idx] - - len_face_vert_loc_indicies = len(face_vert_loc_indicies) - - if len_face_vert_loc_indicies==1: - faces.pop(f_idx)# cant add single vert faces - - elif not face_vert_tex_indicies or len_face_vert_loc_indicies == 2: # faces that have no texture coords are lines - if CREATE_EDGES: - # generators are better in python 2.4+ but can't be used in 2.3 - # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) ) - edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] ) - - faces.pop(f_idx) - else: - - # Smooth Group - if unique_smooth_groups and context_smooth_group: - # Is a part of of a smooth group and is a face - if context_smooth_group_old is not context_smooth_group: - edge_dict= smooth_group_users[context_smooth_group] - context_smooth_group_old= context_smooth_group - - for i in xrange(len_face_vert_loc_indicies): - i1= face_vert_loc_indicies[i] - i2= face_vert_loc_indicies[i-1] - if i1>i2: i1,i2= i2,i1 - - try: - edge_dict[i1,i2]+= 1 - except KeyError: - edge_dict[i1,i2]= 1 - - # FGons into triangles - if has_ngons and len_face_vert_loc_indicies > 4: - - ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies) - faces.extend(\ - [(\ - [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ - [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ - context_material,\ - context_smooth_group,\ - context_object)\ - for ngon in ngon_face_indices]\ - ) - - # edges to make fgons - if CREATE_FGONS: - edge_users= {} - for ngon in ngon_face_indices: - for i in (0,1,2): - i1= face_vert_loc_indicies[ngon[i ]] - i2= face_vert_loc_indicies[ngon[i-1]] - if i1>i2: i1,i2= i2,i1 - - try: - edge_users[i1,i2]+=1 - except KeyError: - edge_users[i1,i2]= 1 - - for key, users in edge_users.iteritems(): - if users>1: - fgon_edges[key]= None - - # remove all after 3, means we dont have to pop this one. - faces.pop(f_idx) - - - # Build sharp edges - if unique_smooth_groups: - for edge_dict in smooth_group_users.itervalues(): - for key, users in edge_dict.iteritems(): - if users==1: # This edge is on the boundry of a group - sharp_edges[key]= None - - - # map the material names to an index - material_mapping= dict([(name, i) for i, name in enumerate(unique_materials)]) # enumerate over unique_materials keys() - - materials= [None] * len(unique_materials) - - for name, index in material_mapping.iteritems(): - materials[index]= unique_materials[name] - - me= bpy.data.meshes.new(dataname) - - me.materials= materials[0:16] # make sure the list isnt too big. - #me.verts.extend([(0,0,0)]) # dummy vert - me.verts.extend(verts_loc) - - face_mapping= me.faces.extend([f[0] for f in faces], indexList=True) - - if verts_tex and me.faces: - me.faceUV= 1 - # TEXMODE= Mesh.FaceModes['TEX'] - - context_material_old= -1 # avoid a dict lookup - mat= 0 # rare case it may be un-initialized. - me_faces= me.faces - ALPHA= Mesh.FaceTranspModes.ALPHA - - for i, face in enumerate(faces): - if len(face[0]) < 2: - pass #raise "bad face" - elif len(face[0])==2: - if CREATE_EDGES: - edges.append(face[0]) - else: - face_index_map= face_mapping[i] - if face_index_map!=None: # None means the face wasnt added - blender_face= me_faces[face_index_map] - - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object= face - - - - if context_smooth_group: - blender_face.smooth= True - - if context_material: - if context_material_old is not context_material: - mat= material_mapping[context_material] - if mat>15: - mat= 15 - context_material_old= context_material - - blender_face.mat= mat - - - if verts_tex: - if context_material: - image, has_data= unique_material_images[context_material] - if image: # Can be none if the material dosnt have an image. - blender_face.image= image - if has_data and image.depth == 32: - blender_face.transp |= ALPHA - - # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled. - if len(face_vert_loc_indicies)==4: - if face_vert_loc_indicies[2]==0 or face_vert_loc_indicies[3]==0: - face_vert_tex_indicies= face_vert_tex_indicies[2], face_vert_tex_indicies[3], face_vert_tex_indicies[0], face_vert_tex_indicies[1] - else: # length of 3 - if face_vert_loc_indicies[2]==0: - face_vert_tex_indicies= face_vert_tex_indicies[1], face_vert_tex_indicies[2], face_vert_tex_indicies[0] - # END EEEKADOODLE FIX - - # assign material, uv's and image - for ii, uv in enumerate(blender_face.uv): - uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]] - del me_faces - del ALPHA - - # Add edge faces. - me_edges= me.edges - if CREATE_FGONS and fgon_edges: - FGON= Mesh.EdgeFlags.FGON - for ed in me.findEdges( fgon_edges.keys() ): - if ed!=None: - me_edges[ed].flag |= FGON - del FGON - - if unique_smooth_groups and sharp_edges: - SHARP= Mesh.EdgeFlags.SHARP - for ed in me.findEdges( sharp_edges.keys() ): - if ed!=None: - me_edges[ed].flag |= SHARP - del SHARP - - if CREATE_EDGES: - me_edges.extend( edges ) - - del me_edges - - me.calcNormals() - - ob= scn.objects.new(me) - new_objects.append(ob) - - # Create the vertex groups. No need to have the flag passed here since we test for the - # content of the vertex_groups. If the user selects to NOT have vertex groups saved then - # the following test will never run - for group_name, group_indicies in vertex_groups.iteritems(): - me.addVertGroup(group_name) - me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE) - - -def create_nurbs(scn, context_nurbs, vert_loc, new_objects): - ''' - Add nurbs object to blender, only support one type at the moment - ''' - deg = context_nurbs.get('deg', (3,)) - curv_range = context_nurbs.get('curv_range', None) - curv_idx = context_nurbs.get('curv_idx', []) - parm_u = context_nurbs.get('parm_u', []) - parm_v = context_nurbs.get('parm_v', []) - name = context_nurbs.get('name', 'ObjNurb') - cstype = context_nurbs.get('cstype', None) - - if cstype == None: - print '\tWarning, cstype not found' - return - if cstype != 'bspline': - print '\tWarning, cstype is not supported (only bspline)' - return - if not curv_idx: - print '\tWarning, curv argument empty or not set' - return - if len(deg) > 1 or parm_v: - print '\tWarning, surfaces not supported' - return - - cu = bpy.data.curves.new(name, 'Curve') - cu.flag |= 1 # 3D curve - - nu = None - for pt in curv_idx: - - pt = vert_loc[pt] - pt = (pt[0], pt[1], pt[2], 1.0) - - if nu == None: - nu = cu.appendNurb(pt) - else: - nu.append(pt) - - nu.orderU = deg[0]+1 - - # get for endpoint flag from the weighting - if curv_range and len(parm_u) > deg[0]+1: - do_endpoints = True - for i in xrange(deg[0]+1): - - if abs(parm_u[i]-curv_range[0]) > 0.0001: - do_endpoints = False - break - - if abs(parm_u[-(i+1)]-curv_range[1]) > 0.0001: - do_endpoints = False - break - - else: - do_endpoints = False - - if do_endpoints: - nu.flagU |= 2 - - - # close - ''' - do_closed = False - if len(parm_u) > deg[0]+1: - for i in xrange(deg[0]+1): - #print curv_idx[i], curv_idx[-(i+1)] - - if curv_idx[i]==curv_idx[-(i+1)]: - do_closed = True - break - - if do_closed: - nu.flagU |= 1 - ''' - - ob = scn.objects.new(cu) - new_objects.append(ob) - - -def strip_slash(line_split): - if line_split[-1][-1]== '\\': - if len(line_split[-1])==1: - line_split.pop() # remove the \ item - else: - line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number - return True - return False - - - -def get_float_func(filepath): - ''' - find the float function for this obj file - - weather to replace commas or not - ''' - file= open(filepath, 'rU') - for line in file: #.xreadlines(): - line = line.lstrip() - if line.startswith('v'): # vn vt v - if ',' in line: - return lambda f: float(f.replace(',', '.')) - elif '.' in line: - return float - - # incase all vert values were ints - return float - -def load_obj(filepath, - CLAMP_SIZE= 0.0, - CREATE_FGONS= True, - CREATE_SMOOTH_GROUPS= True, - CREATE_EDGES= True, - SPLIT_OBJECTS= True, - SPLIT_GROUPS= True, - SPLIT_MATERIALS= True, - ROTATE_X90= True, - IMAGE_SEARCH=True, - POLYGROUPS=False): - ''' - Called by the user interface or another script. - load_obj(path) - should give acceptable results. - This function passes the file and sends the data off - to be split into objects and then converted into mesh objects - ''' - print '\nimporting obj "%s"' % filepath - - if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: - POLYGROUPS = False - - time_main= sys.time() - - verts_loc= [] - verts_tex= [] - faces= [] # tuples of the faces - material_libs= [] # filanems to material libs this uses - vertex_groups = {} # when POLYGROUPS is true - - # Get the string to float conversion func for this file- is 'float' for almost all files. - float_func= get_float_func(filepath) - - # Context variables - context_material= None - context_smooth_group= None - context_object= None - context_vgroup = None - - # Nurbs - context_nurbs = {} - nurbs = [] - context_parm = '' # used by nurbs too but could be used elsewhere - - has_ngons= False - # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0 - - # Until we can use sets - unique_materials= {} - unique_material_images= {} - unique_smooth_groups= {} - # unique_obects= {} - no use for this variable since the objects are stored in the face. - - # when there are faces that end with \ - # it means they are multiline- - # since we use xreadline we cant skip to the next line - # so we need to know weather - context_multi_line= '' - - print '\tparsing obj file "%s"...' % filepath, - time_sub= sys.time() - - file= open(filepath, 'rU') - for line in file: #.xreadlines(): - line = line.lstrip() # rare cases there is white space at the start of the line - - if line.startswith('v '): - line_split= line.split() - # rotate X90: (x,-z,y) - verts_loc.append( (float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])) ) - - elif line.startswith('vn '): - pass - - elif line.startswith('vt '): - line_split= line.split() - verts_tex.append( (float_func(line_split[1]), float_func(line_split[2])) ) - - # Handel faces lines (as faces) and the second+ lines of fa multiline face here - # use 'f' not 'f ' because some objs (very rare have 'fo ' for faces) - elif line.startswith('f') or context_multi_line == 'f': - - if context_multi_line: - # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face - line_split= line.split() - - else: - line_split= line[2:].split() - face_vert_loc_indicies= [] - face_vert_tex_indicies= [] - - # Instance a face - faces.append((\ - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object\ - )) - - if strip_slash(line_split): - context_multi_line = 'f' - else: - context_multi_line = '' - - for v in line_split: - obj_vert= v.split('/') - - vert_loc_index= int(obj_vert[0])-1 - # Add the vertex to the current group - # *warning*, this wont work for files that have groups defined around verts - if POLYGROUPS and context_vgroup: - vertex_groups[context_vgroup].append(vert_loc_index) - - # Make relative negative vert indicies absolute - if vert_loc_index < 0: - vert_loc_index= len(verts_loc) + vert_loc_index + 1 - - face_vert_loc_indicies.append(vert_loc_index) - - if len(obj_vert)>1 and obj_vert[1]: - # formatting for faces with normals and textures us - # loc_index/tex_index/nor_index - - vert_tex_index= int(obj_vert[1])-1 - # Make relative negative vert indicies absolute - if vert_tex_index < 0: - vert_tex_index= len(verts_tex) + vert_tex_index + 1 - - face_vert_tex_indicies.append(vert_tex_index) - else: - # dummy - face_vert_tex_indicies.append(0) - - if len(face_vert_loc_indicies) > 4: - has_ngons= True - - elif CREATE_EDGES and (line.startswith('l ') or context_multi_line == 'l'): - # very similar to the face load function above with some parts removed - - if context_multi_line: - # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face - line_split= line.split() - - else: - line_split= line[2:].split() - face_vert_loc_indicies= [] - face_vert_tex_indicies= [] - - # Instance a face - faces.append((\ - face_vert_loc_indicies,\ - face_vert_tex_indicies,\ - context_material,\ - context_smooth_group,\ - context_object\ - )) - - if strip_slash(line_split): - context_multi_line = 'l' - else: - context_multi_line = '' - - isline= line.startswith('l') - - for v in line_split: - vert_loc_index= int(v)-1 - - # Make relative negative vert indicies absolute - if vert_loc_index < 0: - vert_loc_index= len(verts_loc) + vert_loc_index + 1 - - face_vert_loc_indicies.append(vert_loc_index) - - elif line.startswith('s'): - if CREATE_SMOOTH_GROUPS: - context_smooth_group= line_value(line.split()) - if context_smooth_group=='off': - context_smooth_group= None - elif context_smooth_group: # is not None - unique_smooth_groups[context_smooth_group]= None - - elif line.startswith('o'): - if SPLIT_OBJECTS: - context_object= line_value(line.split()) - # unique_obects[context_object]= None - - elif line.startswith('g'): - if SPLIT_GROUPS: - context_object= line_value(line.split()) - # print 'context_object', context_object - # unique_obects[context_object]= None - elif POLYGROUPS: - context_vgroup = line_value(line.split()) - if context_vgroup and context_vgroup != '(null)': - vertex_groups.setdefault(context_vgroup, []) - else: - context_vgroup = None # dont assign a vgroup - - elif line.startswith('usemtl'): - context_material= line_value(line.split()) - unique_materials[context_material]= None - elif line.startswith('mtllib'): # usemap or usemat - material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line - - - # Nurbs support - elif line.startswith('cstype '): - context_nurbs['cstype']= line_value(line.split()) # 'rat bspline' / 'bspline' - elif line.startswith('curv ') or context_multi_line == 'curv': - line_split= line.split() - - curv_idx = context_nurbs['curv_idx'] = context_nurbs.get('curv_idx', []) # incase were multiline - - if not context_multi_line: - context_nurbs['curv_range'] = float_func(line_split[1]), float_func(line_split[2]) - line_split[0:3] = [] # remove first 3 items - - if strip_slash(line_split): - context_multi_line = 'curv' - else: - context_multi_line = '' - - - for i in line_split: - vert_loc_index = int(i)-1 - - if vert_loc_index < 0: - vert_loc_index= len(verts_loc) + vert_loc_index + 1 - - curv_idx.append(vert_loc_index) - - elif line.startswith('parm') or context_multi_line == 'parm': - line_split= line.split() - - if context_multi_line: - context_multi_line = '' - else: - context_parm = line_split[1] - line_split[0:2] = [] # remove first 2 - - if strip_slash(line_split): - context_multi_line = 'parm' - else: - context_multi_line = '' - - if context_parm.lower() == 'u': - context_nurbs.setdefault('parm_u', []).extend( [float_func(f) for f in line_split] ) - elif context_parm.lower() == 'v': # surfaces not suported yet - context_nurbs.setdefault('parm_v', []).extend( [float_func(f) for f in line_split] ) - # else: # may want to support other parm's ? - - elif line.startswith('deg '): - context_nurbs['deg']= [int(i) for i in line.split()[1:]] - elif line.startswith('end'): - # Add the nurbs curve - if context_object: - context_nurbs['name'] = context_object - nurbs.append(context_nurbs) - context_nurbs = {} - context_parm = '' - - ''' # How to use usemap? depricated? - elif line.startswith('usema'): # usemap or usemat - context_image= line_value(line.split()) - ''' - - file.close() - time_new= sys.time() - print '%.4f sec' % (time_new-time_sub) - time_sub= time_new - - - print '\tloading materials and images...', - create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) - - time_new= sys.time() - print '%.4f sec' % (time_new-time_sub) - time_sub= time_new - - if not ROTATE_X90: - verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] - - # deselect all - scn = bpy.data.scenes.active - scn.objects.selected = [] - new_objects= [] # put new objects here - - print '\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), - # Split the mesh by objects/materials, may - if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True - else: SPLIT_OB_OR_GROUP = False - - for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): - # Create meshes from the data, warning 'vertex_groups' wont support splitting - create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) - - # nurbs support - for context_nurbs in nurbs: - create_nurbs(scn, context_nurbs, verts_loc, new_objects) - - - axis_min= [ 1000000000]*3 - axis_max= [-1000000000]*3 - - if CLAMP_SIZE: - # Get all object bounds - for ob in new_objects: - for v in ob.getBoundBox(): - for axis, value in enumerate(v): - if axis_min[axis] > value: axis_min[axis]= value - if axis_max[axis] < value: axis_max[axis]= value - - # Scale objects - max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2]) - scale= 1.0 - - while CLAMP_SIZE < max_axis * scale: - scale= scale/10.0 - - for ob in new_objects: - ob.setSize(scale, scale, scale) - - # Better rotate the vert locations - #if not ROTATE_X90: - # for ob in new_objects: - # ob.RotX = -1.570796326794896558 - - time_new= sys.time() - - print '%.4f sec' % (time_new-time_sub) - print 'finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)) - - -DEBUG= True - - -def load_obj_ui(filepath, BATCH_LOAD= False): - if BPyMessages.Error_NoFile(filepath): - return - - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 - - CREATE_SMOOTH_GROUPS= Draw.Create(0) - CREATE_FGONS= Draw.Create(1) - CREATE_EDGES= Draw.Create(1) - SPLIT_OBJECTS= Draw.Create(0) - SPLIT_GROUPS= Draw.Create(0) - SPLIT_MATERIALS= Draw.Create(0) - CLAMP_SIZE= Draw.Create(10.0) - IMAGE_SEARCH= Draw.Create(1) - POLYGROUPS= Draw.Create(0) - KEEP_VERT_ORDER= Draw.Create(1) - ROTATE_X90= Draw.Create(1) - - - # Get USER Options - # Note, Works but not pretty, instead use a more complicated GUI - ''' - pup_block= [\ - 'Import...',\ - ('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\ - ('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\ - ('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\ - 'Separate objects from obj...',\ - ('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\ - ('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\ - ('Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)'),\ - 'Options...',\ - ('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ - ('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\ - ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\ - ] - - if not Draw.PupBlock('Import OBJ...', pup_block): - return - - if KEEP_VERT_ORDER.val: - SPLIT_OBJECTS.val = False - SPLIT_GROUPS.val = False - SPLIT_MATERIALS.val = False - ''' - - - - # BEGIN ALTERNATIVE UI ******************* - if True: - - EVENT_NONE = 0 - EVENT_EXIT = 1 - EVENT_REDRAW = 2 - EVENT_IMPORT = 3 - - GLOBALS = {} - GLOBALS['EVENT'] = EVENT_REDRAW - #GLOBALS['MOUSE'] = Window.GetMouseCoords() - GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] - - def obj_ui_set_event(e,v): - GLOBALS['EVENT'] = e - - def do_split(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS - if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val: - KEEP_VERT_ORDER.val = 0 - POLYGROUPS.val = 0 - else: - KEEP_VERT_ORDER.val = 1 - - def do_vertorder(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER - if KEEP_VERT_ORDER.val: - SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 - else: - if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val): - KEEP_VERT_ORDER.val = 1 - - def do_polygroups(e,v): - global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS - if POLYGROUPS.val: - SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 - - def do_help(e,v): - url = __url__[0] - print 'Trying to open web browser with documentation at this address...' - print '\t' + url - - try: - import webbrowser - webbrowser.open(url) - except: - print '...could not open a browser window.' - - def obj_ui(): - ui_x, ui_y = GLOBALS['MOUSE'] - - # Center based on overall pup size - ui_x -= 165 - ui_y -= 90 - - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 - - Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21) - Draw.BeginAlign() - CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges') - CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons') - CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges') - Draw.EndAlign() - - Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20) - Draw.BeginAlign() - SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split) - SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split) - SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+119, ui_y+89, 60, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split) - Draw.EndAlign() - - # Only used for user feedback - KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) - - ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.') - - Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20) - CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') - POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups) - IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)') - Draw.BeginAlign() - Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help) - Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event) - Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event) - Draw.EndAlign() - - - # hack so the toggle buttons redraw. this is not nice at all - while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT): - Draw.UIBlock(obj_ui, 0) - - if GLOBALS['EVENT'] != EVENT_IMPORT: - return - - # END ALTERNATIVE UI ********************* - - - - - - - - Window.WaitCursor(1) - - if BATCH_LOAD: # load the dir - try: - files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ] - except: - Window.WaitCursor(0) - Draw.PupMenu('Error%t|Could not open path ' + filepath) - return - - if not files: - Window.WaitCursor(0) - Draw.PupMenu('Error%t|No files at path ' + filepath) - return - - for f in files: - scn= bpy.data.scenes.new( stripExt(f) ) - scn.makeCurrent() - - load_obj(sys.join(filepath, f),\ - CLAMP_SIZE.val,\ - CREATE_FGONS.val,\ - CREATE_SMOOTH_GROUPS.val,\ - CREATE_EDGES.val,\ - SPLIT_OBJECTS.val,\ - SPLIT_GROUPS.val,\ - SPLIT_MATERIALS.val,\ - ROTATE_X90.val,\ - IMAGE_SEARCH.val,\ - POLYGROUPS.val - ) - - else: # Normal load - load_obj(filepath,\ - CLAMP_SIZE.val,\ - CREATE_FGONS.val,\ - CREATE_SMOOTH_GROUPS.val,\ - CREATE_EDGES.val,\ - SPLIT_OBJECTS.val,\ - SPLIT_GROUPS.val,\ - SPLIT_MATERIALS.val,\ - ROTATE_X90.val,\ - IMAGE_SEARCH.val,\ - POLYGROUPS.val - ) - - Window.WaitCursor(0) - - -def load_obj_ui_batch(file): - load_obj_ui(file, True) - -DEBUG= False - -if __name__=='__main__' and not DEBUG: - if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT: - Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '') - else: - Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') - - # For testing compatibility -''' -else: - # DEBUG ONLY - TIME= sys.time() - DIR = '/fe/obj' - import os - print 'Searching for files' - def fileList(path): - for dirpath, dirnames, filenames in os.walk(path): - for filename in filenames: - yield os.path.join(dirpath, filename) - - files = [f for f in fileList(DIR) if f.lower().endswith('.obj')] - files.sort() - - for i, obj_file in enumerate(files): - if 0 < i < 20: - print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files) - newScn= bpy.data.scenes.new(os.path.basename(obj_file)) - newScn.makeCurrent() - load_obj(obj_file, False, IMAGE_SEARCH=0) - - print 'TOTAL TIME: %.6f' % (sys.time() - TIME) -''' -#load_obj('/test.obj') -#load_obj('/fe/obj/mba1.obj') diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py deleted file mode 100644 index a5547506dc7..00000000000 --- a/release/scripts/import_web3d.py +++ /dev/null @@ -1,2594 +0,0 @@ -#!BPY -""" -Name: 'X3D & VRML97 (.x3d / wrl)...' -Blender: 248 -Group: 'Import' -Tooltip: 'Load an X3D or VRML97 file' -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# (C) Copyright 2008 Paravizion -# Written by Campbell Barton aka Ideasman42 -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -__author__ = "Campbell Barton" -__url__ = ['www.blender.org', 'blenderartists.org', 'http://wiki.blender.org/index.php/Scripts/Manual/Import/X3D_VRML97'] -__version__ = "0.1" - -__bpydoc__ = """\ -This script is an importer for the X3D and VRML97 file formats. -""" - -DEBUG = False - -# This should work without a blender at all -try: - from Blender.sys import exists -except: - from os.path import exists - -def baseName(path): - return path.split('/')[-1].split('\\')[-1] - -def dirName(path): - return path[:-len(baseName(path))] - -def imageConvertCompat(path): - - try: import os - except: return path - if os.sep=='\\': return path # assime win32 has quicktime, dont convert - - if path.lower().endswith('.gif'): - path_to = path[:-3] + 'png' - - ''' - if exists(path_to): - return path_to - ''' - # print '\n'+path+'\n'+path_to+'\n' - os.system('convert "%s" "%s"' % (path, path_to)) # for now just hope we have image magick - - if exists(path_to): - return path_to - - return path - -# notes -# transform are relative -# order dosnt matter for loc/size/rot -# right handed rotation -# angles are in radians -# rotation first defines axis then ammount in radians - - - -# =============================== VRML Spesific - - -def vrmlFormat(data): - ''' - Keep this as a valid vrml file, but format in a way we can predict. - ''' - # Strip all commends - # not in strings - warning multiline strings are ignored. - def strip_comment(l): - #l = ' '.join(l.split()) - l = l.strip() - - if l.startswith('#'): - return '' - - i = l.find('#') - - if i==-1: - return l - - # Most cases accounted for! if we have a comment at the end of the line do this... - #j = l.find('url "') - j = l.find('"') - - if j == -1: # simple no strings - return l[:i].strip() - - q = False - for i,c in enumerate(l): - if c == '"': - q = not q # invert - - elif c == '#': - if q==False: - return l[:i-1] - - return l - - data = '\n'.join([strip_comment(l) for l in data.split('\n') ]) # remove all whitespace - - EXTRACT_STRINGS = True # only needed when strings or filesnames containe ,[]{} chars :/ - - if EXTRACT_STRINGS: - - # We need this so we can detect URL's - data = '\n'.join([' '.join(l.split()) for l in data.split('\n')]) # remove all whitespace - - string_ls = [] - - #search = 'url "' - search = '"' - - ok = True - last_i = 0 - while ok: - ok = False - i = data.find(search, last_i) - if i != -1: - - start = i + len(search) # first char after end of search - end = data.find('"', start) - if end != -1: - item = data[start:end] - string_ls.append( item ) - data = data[:start] + data[end:] - ok = True # keep looking - - last_i = (end - len(item)) + 1 - # print last_i, item, '|' + data[last_i] + '|' - - # done with messy extracting strings part - - - # Bad, dont take strings into account - ''' - data = data.replace('#', '\n#') - data = '\n'.join([ll for l in data.split('\n') for ll in (l.strip(),) if not ll.startswith('#')]) # remove all whitespace - ''' - data = data.replace('{', '\n{\n') - data = data.replace('}', '\n}\n') - data = data.replace('[', '\n[\n') - data = data.replace(']', '\n]\n') - data = data.replace(',', ' , ') # make sure comma's seperate - - if EXTRACT_STRINGS: - # add strings back in - - search = '"' # fill in these empty strings - - ok = True - last_i = 0 - while ok: - ok = False - i = data.find(search + '"', last_i) - # print i - if i != -1: - start = i + len(search) # first char after end of search - item = string_ls.pop(0) - # print item - data = data[:start] + item + data[start:] - - last_i = start + len(item) + 1 - - ok = True - - - # More annoying obscure cases where USE or DEF are placed on a newline - # data = data.replace('\nDEF ', ' DEF ') - # data = data.replace('\nUSE ', ' USE ') - - data = '\n'.join([' '.join(l.split()) for l in data.split('\n')]) # remove all whitespace - - # Better to parse the file accounting for multiline arrays - ''' - data = data.replace(',\n', ' , ') # remove line endings with commas - data = data.replace(']', '\n]\n') # very very annoying - but some comma's are at the end of the list, must run this again. - ''' - - return [l for l in data.split('\n') if l] - -NODE_NORMAL = 1 # {} -NODE_ARRAY = 2 # [] -NODE_REFERENCE = 3 # USE foobar -# NODE_PROTO = 4 # - -lines = [] - -def getNodePreText(i, words): - # print lines[i] - use_node = False - while len(words) < 5: - - if i>=len(lines): - break - ''' - elif lines[i].startswith('PROTO'): - return NODE_PROTO, i+1 - ''' - elif lines[i]=='{': - # words.append(lines[i]) # no need - # print "OK" - return NODE_NORMAL, i+1 - elif lines[i].count('"') % 2 != 0: # odd number of quotes? - part of a string. - # print 'ISSTRING' - break - else: - new_words = lines[i].split() - if 'USE' in new_words: - use_node = True - - words.extend(new_words) - i += 1 - - # Check for USE node - no { - # USE #id - should always be on the same line. - if use_node: - # print 'LINE', i, words[:words.index('USE')+2] - words[:] = words[:words.index('USE')+2] - if lines[i] == '{' and lines[i+1] == '}': - # USE sometimes has {} after it anyway - i+=2 - return NODE_REFERENCE, i - - # print "error value!!!", words - return 0, -1 - -def is_nodeline(i, words): - - if not lines[i][0].isalpha(): - return 0, 0 - - #if lines[i].startswith('field'): - # return 0, 0 - - # Is this a prototype?? - if lines[i].startswith('PROTO'): - words[:] = lines[i].split() - return NODE_NORMAL, i+1 # TODO - assumes the next line is a '[\n', skip that - if lines[i].startswith('EXTERNPROTO'): - words[:] = lines[i].split() - return NODE_ARRAY, i+1 # TODO - assumes the next line is a '[\n', skip that - - ''' - proto_type, new_i = is_protoline(i, words, proto_field_defs) - if new_i != -1: - return proto_type, new_i - ''' - - # Simple "var [" type - if lines[i+1] == '[': - if lines[i].count('"') % 2 == 0: - words[:] = lines[i].split() - return NODE_ARRAY, i+2 - - node_type, new_i = getNodePreText(i, words) - - if not node_type: - if DEBUG: print "not node_type", lines[i] - return 0, 0 - - # Ok, we have a { after some values - # Check the values are not fields - for i, val in enumerate(words): - if i != 0 and words[i-1] in ('DEF', 'USE'): - # ignore anything after DEF, it is a ID and can contain any chars. - pass - elif val[0].isalpha() and val not in ('TRUE', 'FALSE'): - pass - else: - # There is a number in one of the values, therefor we are not a node. - return 0, 0 - - #if node_type==NODE_REFERENCE: - # print words, "REF_!!!!!!!" - return node_type, new_i - -def is_numline(i): - ''' - Does this line start with a number? - ''' - - # Works but too slow. - ''' - l = lines[i] - for w in l.split(): - if w==',': - pass - else: - try: - float(w) - return True - - except: - return False - - return False - ''' - - l = lines[i] - - line_start = 0 - - if l.startswith(', '): - line_start += 2 - - line_end = len(l)-1 - line_end_new = l.find(' ', line_start) # comma's always have a space before them - - if line_end_new != -1: - line_end = line_end_new - - try: - float(l[line_start:line_end]) # works for a float or int - return True - except: - return False - - -class vrmlNode(object): - __slots__ = 'id', 'fields', 'proto_node', 'proto_field_defs', 'proto_fields', 'node_type', 'parent', 'children', 'parent', 'array_data', 'reference', 'lineno', 'filename', 'blendObject', 'DEF_NAMESPACE', 'ROUTE_IPO_NAMESPACE', 'PROTO_NAMESPACE', 'x3dNode' - def __init__(self, parent, node_type, lineno): - self.id = None - self.node_type = node_type - self.parent = parent - self.blendObject = None - self.x3dNode = None # for x3d import only - if parent: - parent.children.append(self) - - self.lineno = lineno - - # This is only set from the root nodes. - # Having a filename also denotes a root node - self.filename = None - self.proto_node = None # proto field definition eg: "field SFColor seatColor .6 .6 .1" - - # Store in the root node because each inline file needs its own root node and its own namespace - self.DEF_NAMESPACE = None - self.ROUTE_IPO_NAMESPACE = None - ''' - self.FIELD_NAMESPACE = None - ''' - - - self.PROTO_NAMESPACE = None - - self.reference = None - - if node_type==NODE_REFERENCE: - # For references, only the parent and ID are needed - # the reference its self is assigned on parsing - return - - self.fields = [] # fields have no order, in some cases rool level values are not unique so dont use a dict - - self.proto_field_defs = [] # proto field definition eg: "field SFColor seatColor .6 .6 .1" - self.proto_fields = [] # proto field usage "diffuseColor IS seatColor" - self.children = [] - self.array_data = [] # use for arrays of data - should only be for NODE_ARRAY types - - - # Only available from the root node - ''' - def getFieldDict(self): - if self.FIELD_NAMESPACE != None: - return self.FIELD_NAMESPACE - else: - return self.parent.getFieldDict() - ''' - def getProtoDict(self): - if self.PROTO_NAMESPACE != None: - return self.PROTO_NAMESPACE - else: - return self.parent.getProtoDict() - - def getDefDict(self): - if self.DEF_NAMESPACE != None: - return self.DEF_NAMESPACE - else: - return self.parent.getDefDict() - - def getRouteIpoDict(self): - if self.ROUTE_IPO_NAMESPACE != None: - return self.ROUTE_IPO_NAMESPACE - else: - return self.parent.getRouteIpoDict() - - def setRoot(self, filename): - self.filename = filename - # self.FIELD_NAMESPACE = {} - self.DEF_NAMESPACE = {} - self.ROUTE_IPO_NAMESPACE = {} - self.PROTO_NAMESPACE = {} - - def isRoot(self): - if self.filename == None: - return False - else: - return True - - def getFilename(self): - if self.filename: - return self.filename - elif self.parent: - return self.parent.getFilename() - else: - return None - - def getRealNode(self): - if self.reference: - return self.reference - else: - return self - - def getSpec(self): - self_real = self.getRealNode() - try: - return self_real.id[-1] # its possible this node has no spec - except: - return None - - def findSpecRecursive(self, spec): - self_real = self.getRealNode() - if spec == self_real.getSpec(): - return self - - for child in self_real.children: - if child.findSpecRecursive(spec): - return child - - return None - - def getPrefix(self): - if self.id: - return self.id[0] - return None - - def getSpecialTypeName(self, typename): - self_real = self.getRealNode() - try: return self_real.id[ list(self_real.id).index(typename)+1 ] - except: return None - - - def getDefName(self): - return self.getSpecialTypeName('DEF') - - def getProtoName(self): - return self.getSpecialTypeName('PROTO') - - def getExternprotoName(self): - return self.getSpecialTypeName('EXTERNPROTO') - - def getChildrenBySpec(self, node_spec): # spec could be Transform, Shape, Appearance - self_real = self.getRealNode() - # using getSpec functions allows us to use the spec of USE children that dont have their spec in their ID - if type(node_spec) == str: - return [child for child in self_real.children if child.getSpec()==node_spec] - else: - # Check inside a list of optional types - return [child for child in self_real.children if child.getSpec() in node_spec] - - def getChildBySpec(self, node_spec): # spec could be Transform, Shape, Appearance - # Use in cases where there is only ever 1 child of this type - ls = self.getChildrenBySpec(node_spec) - if ls: return ls[0] - else: return None - - def getChildrenByName(self, node_name): # type could be geometry, children, appearance - self_real = self.getRealNode() - return [child for child in self_real.children if child.id if child.id[0]==node_name] - - def getChildByName(self, node_name): - self_real = self.getRealNode() - for child in self_real.children: - if child.id and child.id[0]==node_name: # and child.id[-1]==node_spec: - return child - - def getSerialized(self, results, ancestry): - ''' Return this node and all its children in a flat list ''' - ancestry = ancestry[:] # always use a copy - - # self_real = self.getRealNode() - - results.append((self, tuple(ancestry))) - ancestry.append(self) - for child in self.getRealNode().children: - if child not in ancestry: - # We dont want to load proto's, they are only references - # We could enforce this elsewhere - - # Only add this in a very special case - # where the parent of this object is not the real parent - # - In this case we have added the proto as a child to a node instancing it. - # This is a bit arbitary, but its how Proto's are done with this importer. - if child.getProtoName() == None and child.getExternprotoName() == None: - child.getSerialized(results, ancestry) - else: - - if DEBUG: print 'getSerialized() is proto:', child.getProtoName(), child.getExternprotoName(), self.getSpec() - - self_spec = self.getSpec() - - if child.getProtoName() == self_spec or child.getExternprotoName() == self_spec: - if DEBUG: "FoundProto!" - child.getSerialized(results, ancestry) - - - - return results - - def searchNodeTypeID(self, node_spec, results): - self_real = self.getRealNode() - # print self.lineno, self.id - if self_real.id and self_real.id[-1]==node_spec: # use last element, could also be only element - results.append(self_real) - for child in self_real.children: - child.searchNodeTypeID(node_spec, results) - return results - - def getFieldName(self, field, ancestry, AS_CHILD=False): - self_real = self.getRealNode() # incase we're an instance - - for f in self_real.fields: - # print f - if f and f[0] == field: - # print '\tfound field', f - - if len(f)>=3 and f[1] == 'IS': # eg: 'diffuseColor IS legColor' - field_id = f[2] - - # print "\n\n\n\n\n\nFOND IS!!!" - f_proto_lookup = None - f_proto_child_lookup = None - i = len(ancestry) - while i: - i -= 1 - node = ancestry[i] - node = node.getRealNode() - - # proto settings are stored in "self.proto_node" - if node.proto_node: - # Get the default value from the proto, this can be overwridden by the proto instace - # 'field SFColor legColor .8 .4 .7' - if AS_CHILD: - for child in node.proto_node.children: - #if child.id and len(child.id) >= 3 and child.id[2]==field_id: - if child.id and ('point' in child.id or 'points' in child.id): - f_proto_child_lookup = child - - else: - for f_def in node.proto_node.proto_field_defs: - if len(f_def) >= 4: - if f_def[0]=='field' and f_def[2]==field_id: - f_proto_lookup = f_def[3:] - - # Node instance, Will be 1 up from the proto-node in the ancestry list. but NOT its parent. - # This is the setting as defined by the instance, including this setting is optional, - # and will override the default PROTO value - # eg: 'legColor 1 0 0' - if AS_CHILD: - for child in node.children: - if child.id and child.id[0]==field_id: - f_proto_child_lookup = child - else: - for f_def in node.fields: - if len(f_def) >= 2: - if f_def[0]==field_id: - if DEBUG: print "getFieldName(), found proto", f_def - f_proto_lookup = f_def[1:] - - - if AS_CHILD: - if f_proto_child_lookup: - if DEBUG: - print "getFieldName() - AS_CHILD=True, child found" - print f_proto_child_lookup - return f_proto_child_lookup - else: - return f_proto_lookup - else: - if AS_CHILD: - return None - else: - # Not using a proto - return f[1:] - - # print '\tfield not found', field - - - # See if this is a proto name - if AS_CHILD: - child_array = None - for child in self_real.children: - if child.id and len(child.id) == 1 and child.id[0] == field: - return child - - return None - - def getFieldAsInt(self, field, default, ancestry): - self_real = self.getRealNode() # incase we're an instance - - f = self_real.getFieldName(field, ancestry) - if f==None: return default - if ',' in f: f = f[:f.index(',')] # strip after the comma - - if len(f) != 1: - print '\t"%s" wrong length for int conversion for field "%s"' % (f, field) - return default - - try: - return int(f[0]) - except: - print '\tvalue "%s" could not be used as an int for field "%s"' % (f[0], field) - return default - - def getFieldAsFloat(self, field, default, ancestry): - self_real = self.getRealNode() # incase we're an instance - - f = self_real.getFieldName(field, ancestry) - if f==None: return default - if ',' in f: f = f[:f.index(',')] # strip after the comma - - if len(f) != 1: - print '\t"%s" wrong length for float conversion for field "%s"' % (f, field) - return default - - try: - return float(f[0]) - except: - print '\tvalue "%s" could not be used as a float for field "%s"' % (f[0], field) - return default - - def getFieldAsFloatTuple(self, field, default, ancestry): - self_real = self.getRealNode() # incase we're an instance - - f = self_real.getFieldName(field, ancestry) - if f==None: return default - # if ',' in f: f = f[:f.index(',')] # strip after the comma - - if len(f) < 1: - print '"%s" wrong length for float tuple conversion for field "%s"' % (f, field) - return default - - ret = [] - for v in f: - if v != ',': - try: ret.append(float(v)) - except: break # quit of first non float, perhaps its a new field name on the same line? - if so we are going to ignore it :/ TODO - # print ret - - if ret: - return ret - if not ret: - print '\tvalue "%s" could not be used as a float tuple for field "%s"' % (f, field) - return default - - def getFieldAsBool(self, field, default, ancestry): - self_real = self.getRealNode() # incase we're an instance - - f = self_real.getFieldName(field, ancestry) - if f==None: return default - if ',' in f: f = f[:f.index(',')] # strip after the comma - - if len(f) != 1: - print '\t"%s" wrong length for bool conversion for field "%s"' % (f, field) - return default - - if f[0].upper()=='"TRUE"' or f[0].upper()=='TRUE': - return True - elif f[0].upper()=='"FALSE"' or f[0].upper()=='FALSE': - return False - else: - print '\t"%s" could not be used as a bool for field "%s"' % (f[1], field) - return default - - def getFieldAsString(self, field, default, ancestry): - self_real = self.getRealNode() # incase we're an instance - - f = self_real.getFieldName(field, ancestry) - if f==None: return default - if len(f) < 1: - print '\t"%s" wrong length for string conversion for field "%s"' % (f, field) - return default - - if len(f) > 1: - # String may contain spaces - st = ' '.join(f) - else: - st = f[0] - - # X3D HACK - if self.x3dNode: - return st - - if st[0]=='"' and st[-1]=='"': - return st[1:-1] - else: - print '\tvalue "%s" could not be used as a string for field "%s"' % (f[0], field) - return default - - def getFieldAsArray(self, field, group, ancestry): - ''' - For this parser arrays are children - ''' - self_real = self.getRealNode() # incase we're an instance - - child_array = self_real.getFieldName(field, ancestry, True) - - #if type(child_array)==list: # happens occasionaly - # array_data = child_array - - if child_array==None: - - # For x3d, should work ok with vrml too - # for x3d arrays are fields, vrml they are nodes, annoying but not tooo bad. - data_split = self.getFieldName(field, ancestry) - if not data_split: - return [] - array_data = ' '.join(data_split) - if array_data == None: - return [] - - array_data = array_data.replace(',', ' ') - data_split = array_data.split() - try: - array_data = [int(val) for val in data_split] - except: - try: - array_data = [float(val) for val in data_split] - except: - print '\tWarning, could not parse array data from field' - array_data = [] - else: - # print child_array - # Normal vrml - array_data = child_array.array_data - - - # print 'array_data', array_data - - if group==-1 or len(array_data)==0: - return array_data - - # We want a flat list - flat = True - for item in array_data: - if type(item) == list: - flat = False - break - - # make a flat array - if flat: - flat_array = array_data # we are alredy flat. - else: - flat_array = [] - - def extend_flat(ls): - for item in ls: - if type(item)==list: extend_flat(item) - else: flat_array.append(item) - - extend_flat(array_data) - - - # We requested a flat array - if group == 0: - return flat_array - - new_array = [] - sub_array = [] - - for item in flat_array: - sub_array.append(item) - if len(sub_array)==group: - new_array.append(sub_array) - sub_array = [] - - if sub_array: - print '\twarning, array was not aligned to requested grouping', group, 'remaining value', sub_array - - return new_array - - def getFieldAsStringArray(self, field, ancestry): - ''' - Get a list of strings - ''' - self_real = self.getRealNode() # incase we're an instance - - child_array = None - for child in self_real.children: - if child.id and len(child.id) == 1 and child.id[0] == field: - child_array = child - break - if not child_array: - return [] - - # each string gets its own list, remove ""'s - try: - new_array = [f[0][1:-1] for f in child_array.fields] - except: - print '\twarning, string array could not be made' - new_array = [] - - return new_array - - - def getLevel(self): - # Ignore self_real - level = 0 - p = self.parent - while p: - level +=1 - p = p.parent - if not p: break - - return level - - def __repr__(self): - level = self.getLevel() - ind = ' ' * level - if self.node_type==NODE_REFERENCE: - brackets = '' - elif self.node_type==NODE_NORMAL: - brackets = '{}' - else: - brackets = '[]' - - if brackets: - text = ind + brackets[0] + '\n' - else: - text = '' - - text += ind + 'ID: ' + str(self.id) + ' ' + str(level) + (' lineno %d\n' % self.lineno) - - if self.node_type==NODE_REFERENCE: - text += ind + "(reference node)\n" - return text - - if self.proto_node: - text += ind + 'PROTO NODE...\n' - text += str(self.proto_node) - text += ind + 'PROTO NODE_DONE\n' - - text += ind + 'FIELDS:' + str(len(self.fields)) + '\n' - - for i,item in enumerate(self.fields): - text += ind + 'FIELD:\n' - text += ind + str(item) +'\n' - - text += ind + 'PROTO_FIELD_DEFS:' + str(len(self.proto_field_defs)) + '\n' - - for i,item in enumerate(self.proto_field_defs): - text += ind + 'PROTO_FIELD:\n' - text += ind + str(item) +'\n' - - text += ind + 'ARRAY: ' + str(len(self.array_data)) + ' ' + str(self.array_data) + '\n' - #text += ind + 'ARRAY: ' + str(len(self.array_data)) + '[...] \n' - - text += ind + 'CHILDREN: ' + str(len(self.children)) + '\n' - for i, child in enumerate(self.children): - text += ind + ('CHILD%d:\n' % i) - text += str(child) - - text += '\n' + ind + brackets[1] - - return text - - def parse(self, i, IS_PROTO_DATA=False): - new_i = self.__parse(i, IS_PROTO_DATA) - - # print self.id, self.getFilename() - - # Check if this node was an inline or externproto - - url_ls = [] - - if self.node_type == NODE_NORMAL and self.getSpec() == 'Inline': - ancestry = [] # Warning! - PROTO's using this wont work at all. - url = self.getFieldAsString('url', None, ancestry) - if url: - url_ls = [(url, None)] - del ancestry - - elif self.getExternprotoName(): - # externproto - url_ls = [] - for f in self.fields: - - if type(f)==str: - f = [f] - - for ff in f: - for f_split in ff.split('"'): - # print f_split - # "someextern.vrml#SomeID" - if '#' in f_split: - - f_split, f_split_id = f_split.split('#') # there should only be 1 # anyway - - url_ls.append( (f_split, f_split_id) ) - else: - url_ls.append( (f_split, None) ) - - - # Was either an Inline or an EXTERNPROTO - if url_ls: - - # print url_ls - - for url, extern_key in url_ls: - print url - urls = [] - urls.append( url ) - urls.append( BPySys.caseInsensitivePath(urls[-1]) ) - - urls.append( dirName(self.getFilename()) + url ) - urls.append( BPySys.caseInsensitivePath(urls[-1]) ) - - urls.append( dirName(self.getFilename()) + baseName(url) ) - urls.append( BPySys.caseInsensitivePath(urls[-1]) ) - - try: - url = [url for url in urls if exists(url)][0] - url_found = True - except: - url_found = False - - if not url_found: - print '\tWarning: Inline URL could not be found:', url - else: - if url==self.getFilename(): - print '\tWarning: cant Inline yourself recursively:', url - else: - - try: - data = gzipOpen(url) - except: - print '\tWarning: cant open the file:', url - data = None - - if data: - # Tricky - inline another VRML - print '\tLoading Inline:"%s"...' % url - - # Watch it! - backup lines - lines_old = lines[:] - - - lines[:] = vrmlFormat( data ) - - lines.insert(0, '{') - lines.insert(0, 'root_node____') - lines.append('}') - ''' - ff = open('/tmp/test.txt', 'w') - ff.writelines([l+'\n' for l in lines]) - ''' - - child = vrmlNode(self, NODE_NORMAL, -1) - child.setRoot(url) # initialized dicts - child.parse(0) - - # if self.getExternprotoName(): - if self.getExternprotoName(): - if not extern_key: # if none is spesified - use the name - extern_key = self.getSpec() - - if extern_key: - - self.children.remove(child) - child.parent = None - - extern_child = child.findSpecRecursive(extern_key) - - if extern_child: - self.children.append(extern_child) - extern_child.parent = self - - if DEBUG: print "\tEXTERNPROTO ID found!:", extern_key - else: - print "\tEXTERNPROTO ID not found!:", extern_key - - # Watch it! - restore lines - lines[:] = lines_old - - return new_i - - def __parse(self, i, IS_PROTO_DATA=False): - ''' - print 'parsing at', i, - print i, self.id, self.lineno - ''' - l = lines[i] - - if l=='[': - # An anonymous list - self.id = None - i+=1 - else: - words = [] - - node_type, new_i = is_nodeline(i, words) - if not node_type: # fail for parsing new node. - print "Failed to parse new node" - raise ValueError - - if self.node_type==NODE_REFERENCE: - # Only assign the reference and quit - key = words[words.index('USE')+1] - self.id = (words[0],) - - self.reference = self.getDefDict()[key] - return new_i - - self.id = tuple(words) - - # fill in DEF/USE - key = self.getDefName() - if key != None: - self.getDefDict()[ key ] = self - - key = self.getProtoName() - if not key: key = self.getExternprotoName() - - proto_dict = self.getProtoDict() - if key != None: - proto_dict[ key ] = self - - # Parse the proto nodes fields - self.proto_node = vrmlNode(self, NODE_ARRAY, new_i) - new_i = self.proto_node.parse(new_i) - - self.children.remove(self.proto_node) - - # print self.proto_node - - new_i += 1 # skip past the { - - - else: # If we're a proto instance, add the proto node as our child. - spec = self.getSpec() - try: - self.children.append( proto_dict[spec] ) - #pass - except: - pass - - del spec - - del proto_dict, key - - i = new_i - - # print self.id - ok = True - while ok: - if i>=len(lines): - return len(lines)-1 - - l = lines[i] - # print '\tDEBUG:', i, self.node_type, l - if l=='': - i+=1 - continue - - if l=='}': - if self.node_type != NODE_NORMAL: # also ends proto nodes, we may want a type for these too. - print 'wrong node ending, expected an } ' + str(i) + ' ' + str(self.node_type) - if DEBUG: - raise ValueError - ### print "returning", i - return i+1 - if l==']': - if self.node_type != NODE_ARRAY: - print 'wrong node ending, expected a ] ' + str(i) + ' ' + str(self.node_type) - if DEBUG: - raise ValueError - ### print "returning", i - return i+1 - - node_type, new_i = is_nodeline(i, []) - if node_type: # check text\n{ - child = vrmlNode(self, node_type, i) - i = child.parse(i) - - elif l=='[': # some files have these anonymous lists - child = vrmlNode(self, NODE_ARRAY, i) - i = child.parse(i) - - elif is_numline(i): - l_split = l.split(',') - - values = None - # See if each item is a float? - - for num_type in (int, float): - try: - values = [num_type(v) for v in l_split ] - break - except: - pass - - - try: - values = [[num_type(v) for v in segment.split()] for segment in l_split ] - break - except: - pass - - if values == None: # dont parse - values = l_split - - # This should not extend over multiple lines however it is possible - # print self.array_data - if values: - self.array_data.extend( values ) - i+=1 - else: - words = l.split() - if len(words) > 2 and words[1] == 'USE': - vrmlNode(self, NODE_REFERENCE, i) - else: - - # print "FIELD", i, l - # - #words = l.split() - ### print '\t\ttag', i - # this is a tag/ - # print words, i, l - value = l - # print i - # javastrips can exist as values. - quote_count = l.count('"') - if quote_count % 2: # odd number? - # print 'MULTILINE' - while 1: - i+=1 - l = lines[i] - quote_count = l.count('"') - if quote_count % 2: # odd number? - value += '\n'+ l[:l.rfind('"')] - break # assume - else: - value += '\n'+ l - - value_all = value.split() - - def iskey(k): - if k[0] != '"' and k[0].isalpha() and k.upper() not in ('TRUE', 'FALSE'): - return True - return False - - def split_fields(value): - ''' - key 0.0 otherkey 1,2,3 opt1 opt1 0.0 - -> [key 0.0], [otherkey 1,2,3], [opt1 opt1 0.0] - ''' - field_list = [] - field_context = [] - - for j in xrange(len(value)): - if iskey(value[j]): - if field_context: - # this IS a key but the previous value was not a key, ot it was a defined field. - if (not iskey(field_context[-1])) or ((len(field_context)==3 and field_context[1]=='IS')): - field_list.append(field_context) - - field_context = [value[j]] - else: - # The last item was not a value, multiple keys are needed in some cases. - field_context.append(value[j]) - else: - # Is empty, just add this on - field_context.append(value[j]) - else: - # Add a value to the list - field_context.append(value[j]) - - if field_context: - field_list.append(field_context) - - return field_list - - - for value in split_fields(value_all): - # Split - - if value[0]=='field': - # field SFFloat creaseAngle 4 - self.proto_field_defs.append(value) - else: - self.fields.append(value) - i+=1 - -def gzipOpen(path): - try: import gzip - except: gzip = None - - data = None - if gzip: - try: data = gzip.open(path, 'r').read() - except: pass - else: - print '\tNote, gzip module could not be imported, compressed files will fail to load' - - if data==None: - try: data = open(path, 'rU').read() - except: pass - - return data - -def vrml_parse(path): - ''' - Sets up the root node and returns it so load_web3d() can deal with the blender side of things. - Return root (vrmlNode, '') or (None, 'Error String') - ''' - data = gzipOpen(path) - - if data==None: - return None, 'Failed to open file: ' + path - - # Stripped above - lines[:] = vrmlFormat( data ) - - lines.insert(0, '{') - lines.insert(0, 'dymmy_node') - lines.append('}') - # Use for testing our parsed output, so we can check on line numbers. - - ''' - ff = open('/tmp/test.txt', 'w') - ff.writelines([l+'\n' for l in lines]) - ff.close() - ''' - - # Now evaluate it - node_type, new_i = is_nodeline(0, []) - if not node_type: - return None, 'Error: VRML file has no starting Node' - - # Trick to make sure we get all root nodes. - lines.insert(0, '{') - lines.insert(0, 'root_node____') # important the name starts with an ascii char - lines.append('}') - - root = vrmlNode(None, NODE_NORMAL, -1) - root.setRoot(path) # we need to set the root so we have a namespace and know the path incase of inlineing - - # Parse recursively - root.parse(0) - - # This prints a load of text - if DEBUG: - print root - - return root, '' - - -# ====================== END VRML - - - -# ====================== X3d Support - -# Sane as vrml but replace the parser -class x3dNode(vrmlNode): - def __init__(self, parent, node_type, x3dNode): - vrmlNode.__init__(self, parent, node_type, -1) - self.x3dNode = x3dNode - - def parse(self, IS_PROTO_DATA=False): - # print self.x3dNode.tagName - - define = self.x3dNode.getAttributeNode('DEF') - if define: - self.getDefDict()[define.value] = self - else: - use = self.x3dNode.getAttributeNode('USE') - if use: - try: - self.reference = self.getDefDict()[use.value] - self.node_type = NODE_REFERENCE - except: - print '\tWarning: reference', use.value, 'not found' - self.parent.children.remove(self) - - return - - for x3dChildNode in self.x3dNode.childNodes: - if x3dChildNode.nodeType in (x3dChildNode.TEXT_NODE, x3dChildNode.COMMENT_NODE, x3dChildNode.CDATA_SECTION_NODE): - continue - - node_type = NODE_NORMAL - # print x3dChildNode, dir(x3dChildNode) - if x3dChildNode.getAttributeNode('USE'): - node_type = NODE_REFERENCE - - child = x3dNode(self, node_type, x3dChildNode) - child.parse() - - # TODO - x3d Inline - - def getSpec(self): - return self.x3dNode.tagName # should match vrml spec - - def getDefName(self): - data = self.x3dNode.getAttributeNode('DEF') - if data: data.value - return None - - # Other funcs operate from vrml, but this means we can wrap XML fields, still use nice utility funcs - # getFieldAsArray getFieldAsBool etc - def getFieldName(self, field, ancestry, AS_CHILD=False): - # ancestry and AS_CHILD are ignored, only used for VRML now - - self_real = self.getRealNode() # incase we're an instance - field_xml = self.x3dNode.getAttributeNode(field) - if field_xml: - value = field_xml.value - - # We may want to edit. for x3d spesific stuff - # Sucks a bit to return the field name in the list but vrml excepts this :/ - return value.split() - else: - return None - -def x3d_parse(path): - ''' - Sets up the root node and returns it so load_web3d() can deal with the blender side of things. - Return root (x3dNode, '') or (None, 'Error String') - ''' - - try: - import xml.dom.minidom - except: - return None, 'Error, import XML parsing module (xml.dom.minidom) failed, install python' - - ''' - try: doc = xml.dom.minidom.parse(path) - except: return None, 'Could not parse this X3D file, XML error' - ''' - - # Could add a try/except here, but a console error is more useful. - data = gzipOpen(path) - - if data==None: - return None, 'Failed to open file: ' + path - - doc = xml.dom.minidom.parseString(data) - - - try: - x3dnode = doc.getElementsByTagName('X3D')[0] - except: - return None, 'Not a valid x3d document, cannot import' - - root = x3dNode(None, NODE_NORMAL, x3dnode) - root.setRoot(path) # so images and Inline's we load have a relative path - root.parse() - - return root, '' - - - -## f = open('/_Cylinder.wrl', 'r') -# f = open('/fe/wrl/Vrml/EGS/TOUCHSN.WRL', 'r') -# vrml_parse('/fe/wrl/Vrml/EGS/TOUCHSN.WRL') -#vrml_parse('/fe/wrl/Vrml/EGS/SCRIPT.WRL') -''' - -import os -files = os.popen('find /fe/wrl -iname "*.wrl"').readlines() -files.sort() -tot = len(files) -for i, f in enumerate(files): - #if i < 801: - # continue - - f = f.strip() - print f, i, tot - vrml_parse(f) -''' - -# NO BLENDER CODE ABOVE THIS LINE. -# ----------------------------------------------------------------------------------- -import bpy -import BPyImage -import BPySys -reload(BPySys) -reload(BPyImage) -import Blender -from Blender import Texture, Material, Mathutils, Mesh, Types, Window -from Blender.Mathutils import TranslationMatrix -from Blender.Mathutils import RotationMatrix -from Blender.Mathutils import Vector -from Blender.Mathutils import Matrix - -RAD_TO_DEG = 57.29578 - -GLOBALS = {'CIRCLE_DETAIL':16} - -def translateRotation(rot): - ''' axis, angle ''' - return RotationMatrix(rot[3]*RAD_TO_DEG, 4, 'r', Vector(rot[:3])) - -def translateScale(sca): - mat = Matrix() # 4x4 default - mat[0][0] = sca[0] - mat[1][1] = sca[1] - mat[2][2] = sca[2] - return mat - -def translateTransform(node, ancestry): - cent = node.getFieldAsFloatTuple('center', None, ancestry) # (0.0, 0.0, 0.0) - rot = node.getFieldAsFloatTuple('rotation', None, ancestry) # (0.0, 0.0, 1.0, 0.0) - sca = node.getFieldAsFloatTuple('scale', None, ancestry) # (1.0, 1.0, 1.0) - scaori = node.getFieldAsFloatTuple('scaleOrientation', None, ancestry) # (0.0, 0.0, 1.0, 0.0) - tx = node.getFieldAsFloatTuple('translation', None, ancestry) # (0.0, 0.0, 0.0) - - if cent: - cent_mat = TranslationMatrix(Vector(cent)).resize4x4() - cent_imat = cent_mat.copy().invert() - else: - cent_mat = cent_imat = None - - if rot: rot_mat = translateRotation(rot) - else: rot_mat = None - - if sca: sca_mat = translateScale(sca) - else: sca_mat = None - - if scaori: - scaori_mat = translateRotation(scaori) - scaori_imat = scaori_mat.copy().invert() - else: - scaori_mat = scaori_imat = None - - if tx: tx_mat = TranslationMatrix(Vector(tx)).resize4x4() - else: tx_mat = None - - new_mat = Matrix() - - mats = [tx_mat, cent_mat, rot_mat, scaori_mat, sca_mat, scaori_imat, cent_imat] - for mtx in mats: - if mtx: - new_mat = mtx * new_mat - - return new_mat - -def translateTexTransform(node, ancestry): - cent = node.getFieldAsFloatTuple('center', None, ancestry) # (0.0, 0.0) - rot = node.getFieldAsFloat('rotation', None, ancestry) # 0.0 - sca = node.getFieldAsFloatTuple('scale', None, ancestry) # (1.0, 1.0) - tx = node.getFieldAsFloatTuple('translation', None, ancestry) # (0.0, 0.0) - - - if cent: - # cent is at a corner by default - cent_mat = TranslationMatrix(Vector(cent).resize3D()).resize4x4() - cent_imat = cent_mat.copy().invert() - else: - cent_mat = cent_imat = None - - if rot: rot_mat = RotationMatrix(rot*RAD_TO_DEG, 4, 'z') # translateRotation(rot) - else: rot_mat = None - - if sca: sca_mat = translateScale((sca[0], sca[1], 0.0)) - else: sca_mat = None - - if tx: tx_mat = TranslationMatrix(Vector(tx).resize3D()).resize4x4() - else: tx_mat = None - - new_mat = Matrix() - - # as specified in VRML97 docs - mats = [cent_imat, sca_mat, rot_mat, cent_mat, tx_mat] - - for mtx in mats: - if mtx: - new_mat = mtx * new_mat - - return new_mat - - - -def getFinalMatrix(node, mtx, ancestry): - - transform_nodes = [node_tx for node_tx in ancestry if node_tx.getSpec() == 'Transform'] - if node.getSpec()=='Transform': - transform_nodes.append(node) - transform_nodes.reverse() - - if mtx==None: - mtx = Matrix() - - for node_tx in transform_nodes: - mat = translateTransform(node_tx, ancestry) - mtx = mtx * mat - - return mtx - -def importMesh_IndexedFaceSet(geom, bpyima, ancestry): - # print geom.lineno, geom.id, vrmlNode.DEF_NAMESPACE.keys() - - ccw = geom.getFieldAsBool('ccw', True, ancestry) - ifs_colorPerVertex = geom.getFieldAsBool('colorPerVertex', True, ancestry) # per vertex or per face - ifs_normalPerVertex = geom.getFieldAsBool('normalPerVertex', True, ancestry) - - # This is odd how point is inside Coordinate - - # VRML not x3d - #coord = geom.getChildByName('coord') # 'Coordinate' - - coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml - - if coord: ifs_points = coord.getFieldAsArray('point', 3, ancestry) - else: coord = [] - - if not coord: - print '\tWarnint: IndexedFaceSet has no points' - return None, ccw - - ifs_faces = geom.getFieldAsArray('coordIndex', 0, ancestry) - - coords_tex = None - if ifs_faces: # In rare cases this causes problems - no faces but UVs??? - - # WORKS - VRML ONLY - # coords_tex = geom.getChildByName('texCoord') - coords_tex = geom.getChildBySpec('TextureCoordinate') - - if coords_tex: - ifs_texpoints = coords_tex.getFieldAsArray('point', 2, ancestry) - ifs_texfaces = geom.getFieldAsArray('texCoordIndex', 0, ancestry) - - if not ifs_texpoints: - # IF we have no coords, then dont bother - coords_tex = None - - - # WORKS - VRML ONLY - # vcolor = geom.getChildByName('color') - vcolor = geom.getChildBySpec('Color') - vcolor_spot = None # spot color when we dont have an array of colors - if vcolor: - # float to char - ifs_vcol = [(0,0,0)] # EEKADOODLE - vertex start at 1 - ifs_vcol.extend([[int(c*256) for c in col] for col in vcolor.getFieldAsArray('color', 3, ancestry)]) - ifs_color_index = geom.getFieldAsArray('colorIndex', 0, ancestry) - - if not ifs_vcol: - vcolor_spot = [int(c*256) for c in vcolor.getFieldAsFloatTuple('color', [], ancestry)] - - # Convert faces into somthing blender can use - edges = [] - - # All lists are aligned! - faces = [] - faces_uv = [] # if ifs_texfaces is empty then the faces_uv will match faces exactly. - faces_orig_index = [] # for ngons, we need to know our original index - - if coords_tex and ifs_texfaces: - do_uvmap = True - else: - do_uvmap = False - - # current_face = [0] # pointer anyone - - def add_face(face, fuvs, orig_index): - l = len(face) - if l==3 or l==4: - faces.append(face) - # faces_orig_index.append(current_face[0]) - if do_uvmap: - faces_uv.append(fuvs) - - faces_orig_index.append(orig_index) - elif l==2: edges.append(face) - elif l>4: - for i in xrange(2, len(face)): - faces.append([face[0], face[i-1], face[i]]) - if do_uvmap: - faces_uv.append([fuvs[0], fuvs[i-1], fuvs[i]]) - faces_orig_index.append(orig_index) - else: - # faces with 1 verts? pfft! - # still will affect index ordering - pass - - face = [] - fuvs = [] - orig_index = 0 - for i, fi in enumerate(ifs_faces): - # ifs_texfaces and ifs_faces should be aligned - if fi != -1: - # face.append(int(fi)) # in rare cases this is a float - # EEKADOODLE!!! - # Annoyance where faces that have a zero index vert get rotated. This will then mess up UVs and VColors - face.append(int(fi)+1) # in rare cases this is a float, +1 because of stupid EEKADOODLE :/ - - if do_uvmap: - if i >= len(ifs_texfaces): - print '\tWarning: UV Texface index out of range' - fuvs.append(ifs_texfaces[0]) - else: - fuvs.append(ifs_texfaces[i]) - else: - add_face(face, fuvs, orig_index) - face = [] - if do_uvmap: - fuvs = [] - orig_index += 1 - - add_face(face, fuvs, orig_index) - del add_face # dont need this func anymore - - bpymesh = bpy.data.meshes.new() - - bpymesh.verts.extend([(0,0,0)]) # EEKADOODLE - bpymesh.verts.extend(ifs_points) - - # print len(ifs_points), faces, edges, ngons - - try: - bpymesh.faces.extend(faces, smooth=True, ignoreDups=True) - except KeyError: - print "one or more vert indicies out of range. corrupt file?" - #for f in faces: - # bpymesh.faces.extend(faces, smooth=True) - - bpymesh.calcNormals() - - if len(bpymesh.faces) != len(faces): - print '\tWarning: adding faces did not work! file is invalid, not adding UVs or vcolors' - return bpymesh, ccw - - # Apply UVs if we have them - if not do_uvmap: - faces_uv = faces # fallback, we didnt need a uvmap in the first place, fallback to the face/vert mapping. - if coords_tex: - #print ifs_texpoints - # print geom - bpymesh.faceUV = True - for i,f in enumerate(bpymesh.faces): - f.image = bpyima - fuv = faces_uv[i] # uv indicies - for j,uv in enumerate(f.uv): - # print fuv, j, len(ifs_texpoints) - try: - uv[:] = ifs_texpoints[fuv[j]] - except: - print '\tWarning: UV Index out of range' - uv[:] = ifs_texpoints[0] - - elif bpyima and len(bpymesh.faces): - # Oh Bugger! - we cant really use blenders ORCO for for texture space since texspace dosnt rotate. - # we have to create VRML's coords as UVs instead. - - # VRML docs - ''' - If the texCoord field is NULL, a default texture coordinate mapping is calculated using the local - coordinate system bounding box of the shape. The longest dimension of the bounding box defines the S coordinates, - and the next longest defines the T coordinates. If two or all three dimensions of the bounding box are equal, - ties shall be broken by choosing the X, Y, or Z dimension in that order of preference. - The value of the S coordinate ranges from 0 to 1, from one end of the bounding box to the other. - The T coordinate ranges between 0 and the ratio of the second greatest dimension of the bounding box to the greatest dimension. - ''' - - # Note, S,T == U,V - # U gets longest, V gets second longest - xmin, ymin, zmin = ifs_points[0] - xmax, ymax, zmax = ifs_points[0] - for co in ifs_points: - x,y,z = co - if x < xmin: xmin = x - if y < ymin: ymin = y - if z < zmin: zmin = z - - if x > xmax: xmax = x - if y > ymax: ymax = y - if z > zmax: zmax = z - - xlen = xmax - xmin - ylen = ymax - ymin - zlen = zmax - zmin - - depth_min = xmin, ymin, zmin - depth_list = [xlen, ylen, zlen] - depth_sort = depth_list[:] - depth_sort.sort() - - depth_idx = [depth_list.index(val) for val in depth_sort] - - axis_u = depth_idx[-1] - axis_v = depth_idx[-2] # second longest - - # Hack, swap these !!! TODO - Why swap??? - it seems to work correctly but should not. - # axis_u,axis_v = axis_v,axis_u - - min_u = depth_min[axis_u] - min_v = depth_min[axis_v] - depth_u = depth_list[axis_u] - depth_v = depth_list[axis_v] - - depth_list[axis_u] - - if axis_u == axis_v: - # This should be safe because when 2 axies have the same length, the lower index will be used. - axis_v += 1 - - bpymesh.faceUV = True - - # HACK !!! - seems to be compatible with Cosmo though. - depth_v = depth_u = max(depth_v, depth_u) - - for f in bpymesh.faces: - f.image = bpyima - fuv = f.uv - - for i,v in enumerate(f): - co = v.co - fuv[i][:] = (co[axis_u]-min_u) / depth_u, (co[axis_v]-min_v) / depth_v - - # Add vcote - if vcolor: - # print ifs_vcol - bpymesh.vertexColors = True - - for f in bpymesh.faces: - fcol = f.col - if ifs_colorPerVertex: - fv = f.verts - for i,c in enumerate(fcol): - color_index = fv[i].index # color index is vert index - if ifs_color_index: - try: - color_index = ifs_color_index[color_index] - except: - print '\tWarning: per vertex color index out of range' - continue - - if color_index < len(ifs_vcol): - c.r, c.g, c.b = ifs_vcol[color_index] - else: - #print '\tWarning: per face color index out of range' - pass - else: - if vcolor_spot: # use 1 color, when ifs_vcol is [] - for c in fcol: - c.r, c.g, c.b = vcolor_spot - else: - color_index = faces_orig_index[f.index] # color index is face index - #print color_index, ifs_color_index - if ifs_color_index: - if color_index <= len(ifs_color_index): - print '\tWarning: per face color index out of range' - color_index = 0 - else: - color_index = ifs_color_index[color_index] - - - col = ifs_vcol[color_index] - for i,c in enumerate(fcol): - try: - c.r, c.g, c.b = col - except: - pass # incase its not between 0 and 255 - - bpymesh.verts.delete([0,]) # EEKADOODLE - - return bpymesh, ccw - -def importMesh_IndexedLineSet(geom, ancestry): - # VRML not x3d - #coord = geom.getChildByName('coord') # 'Coordinate' - coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml - if coord: points = coord.getFieldAsArray('point', 3, ancestry) - else: points = [] - - if not points: - print '\tWarning: IndexedLineSet had no points' - return None - - ils_lines = geom.getFieldAsArray('coordIndex', 0, ancestry) - - lines = [] - line = [] - - for il in ils_lines: - if il==-1: - lines.append(line) - line = [] - else: - line.append(int(il)) - lines.append(line) - - # vcolor = geom.getChildByName('color') # blender dosnt have per vertex color - - bpycurve = bpy.data.curves.new('IndexedCurve', 'Curve') - bpycurve.setFlag(1) - - w=t=1 - - curve_index = 0 - - for line in lines: - if not line: - continue - co = points[line[0]] - bpycurve.appendNurb([co[0], co[1], co[2], w, t]) - bpycurve[curve_index].type= 0 # Poly Line - - for il in line[1:]: - co = points[il] - bpycurve.appendPoint(curve_index, [co[0], co[1], co[2], w]) - - - curve_index += 1 - - return bpycurve - - -def importMesh_PointSet(geom, ancestry): - # VRML not x3d - #coord = geom.getChildByName('coord') # 'Coordinate' - coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml - if coord: points = coord.getFieldAsArray('point', 3, ancestry) - else: points = [] - - # vcolor = geom.getChildByName('color') # blender dosnt have per vertex color - - bpymesh = bpy.data.meshes.new() - bpymesh.verts.extend(points) - bpymesh.calcNormals() # will just be dummy normals - return bpymesh - -GLOBALS['CIRCLE_DETAIL'] = 12 - -MATRIX_Z_TO_Y = RotationMatrix(90, 4, 'x') - -def importMesh_Sphere(geom, ancestry): - # bpymesh = bpy.data.meshes.new() - diameter = geom.getFieldAsFloat('radius', 0.5, ancestry) * 2 # * 2 for the diameter - bpymesh = Mesh.Primitives.UVsphere(GLOBALS['CIRCLE_DETAIL'], GLOBALS['CIRCLE_DETAIL'], diameter) - bpymesh.transform(MATRIX_Z_TO_Y) - return bpymesh - -def importMesh_Cylinder(geom, ancestry): - # bpymesh = bpy.data.meshes.new() - diameter = geom.getFieldAsFloat('radius', 1.0, ancestry) * 2 # * 2 for the diameter - height = geom.getFieldAsFloat('height', 2, ancestry) - bpymesh = Mesh.Primitives.Cylinder(GLOBALS['CIRCLE_DETAIL'], diameter, height) - bpymesh.transform(MATRIX_Z_TO_Y) - - # Warning - Rely in the order Blender adds verts - # not nice design but wont change soon. - - bottom = geom.getFieldAsBool('bottom', True, ancestry) - side = geom.getFieldAsBool('side', True, ancestry) - top = geom.getFieldAsBool('top', True, ancestry) - - if not top: # last vert is top center of tri fan. - bpymesh.verts.delete([(GLOBALS['CIRCLE_DETAIL']+GLOBALS['CIRCLE_DETAIL'])+1]) - - if not bottom: # second last vert is bottom of triangle fan - bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']+GLOBALS['CIRCLE_DETAIL']]) - - if not side: - # remove all quads - bpymesh.faces.delete(1, [f for f in bpymesh.faces if len(f)==4]) - - return bpymesh - -def importMesh_Cone(geom, ancestry): - # bpymesh = bpy.data.meshes.new() - diameter = geom.getFieldAsFloat('bottomRadius', 1.0, ancestry) * 2 # * 2 for the diameter - height = geom.getFieldAsFloat('height', 2, ancestry) - bpymesh = Mesh.Primitives.Cone(GLOBALS['CIRCLE_DETAIL'], diameter, height) - bpymesh.transform(MATRIX_Z_TO_Y) - - # Warning - Rely in the order Blender adds verts - # not nice design but wont change soon. - - bottom = geom.getFieldAsBool('bottom', True, ancestry) - side = geom.getFieldAsBool('side', True, ancestry) - - if not bottom: # last vert is on the bottom - bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']+1]) - if not side: # second last vert is on the pointy bit of the cone - bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']]) - - return bpymesh - -def importMesh_Box(geom, ancestry): - # bpymesh = bpy.data.meshes.new() - - size = geom.getFieldAsFloatTuple('size', (2.0, 2.0, 2.0), ancestry) - bpymesh = Mesh.Primitives.Cube(1.0) - - # Scale the box to the size set - scale_mat = Matrix([size[0],0,0], [0, size[1], 0], [0, 0, size[2]]) - bpymesh.transform(scale_mat.resize4x4()) - - return bpymesh - -def importShape(node, ancestry): - vrmlname = node.getDefName() - if not vrmlname: vrmlname = 'Shape' - - # works 100% in vrml, but not x3d - #appr = node.getChildByName('appearance') # , 'Appearance' - #geom = node.getChildByName('geometry') # , 'IndexedFaceSet' - - # Works in vrml and x3d - appr = node.getChildBySpec('Appearance') - geom = node.getChildBySpec(['IndexedFaceSet', 'IndexedLineSet', 'PointSet', 'Sphere', 'Box', 'Cylinder', 'Cone']) - - # For now only import IndexedFaceSet's - if geom: - bpymat = None - bpyima = None - texmtx = None - - depth = 0 # so we can set alpha face flag later - - if appr: - - #mat = appr.getChildByName('material') # 'Material' - #ima = appr.getChildByName('texture') # , 'ImageTexture' - #if ima and ima.getSpec() != 'ImageTexture': - # print '\tWarning: texture type "%s" is not supported' % ima.getSpec() - # ima = None - # textx = appr.getChildByName('textureTransform') - - mat = appr.getChildBySpec('Material') - ima = appr.getChildBySpec('ImageTexture') - - textx = appr.getChildBySpec('TextureTransform') - - if textx: - texmtx = translateTexTransform(textx, ancestry) - - - - # print mat, ima - if mat or ima: - - if not mat: - mat = ima # This is a bit dumb, but just means we use default values for all - - # all values between 0.0 and 1.0, defaults from VRML docs - bpymat = bpy.data.materials.new() - bpymat.amb = mat.getFieldAsFloat('ambientIntensity', 0.2, ancestry) - bpymat.rgbCol = mat.getFieldAsFloatTuple('diffuseColor', [0.8, 0.8, 0.8], ancestry) - - # NOTE - blender dosnt support emmisive color - # Store in mirror color and approximate with emit. - emit = mat.getFieldAsFloatTuple('emissiveColor', [0.0, 0.0, 0.0], ancestry) - bpymat.mirCol = emit - bpymat.emit = (emit[0]+emit[1]+emit[2])/3.0 - - bpymat.hard = int(1+(510*mat.getFieldAsFloat('shininess', 0.2, ancestry))) # 0-1 -> 1-511 - bpymat.specCol = mat.getFieldAsFloatTuple('specularColor', [0.0, 0.0, 0.0], ancestry) - bpymat.alpha = 1.0 - mat.getFieldAsFloat('transparency', 0.0, ancestry) - if bpymat.alpha < 0.999: - bpymat.mode |= Material.Modes.ZTRANSP - - - if ima: - - ima_url = ima.getFieldAsString('url', None, ancestry) - - if ima_url==None: - try: ima_url = ima.getFieldAsStringArray('url', ancestry)[0] # in some cases we get a list of images. - except: ima_url = None - - if ima_url==None: - print "\twarning, image with no URL, this is odd" - else: - bpyima= BPyImage.comprehensiveImageLoad(ima_url, dirName(node.getFilename()), PLACE_HOLDER= False, RECURSIVE= False, CONVERT_CALLBACK= imageConvertCompat) - if bpyima: - texture= bpy.data.textures.new() - texture.setType('Image') - texture.image = bpyima - - # Adds textures for materials (rendering) - try: depth = bpyima.depth - except: depth = -1 - - if depth == 32: - # Image has alpha - bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) - texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') - bpymat.mode |= Material.Modes.ZTRANSP - bpymat.alpha = 0.0 - else: - bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) - - ima_repS = ima.getFieldAsBool('repeatS', True, ancestry) - ima_repT = ima.getFieldAsBool('repeatT', True, ancestry) - - # To make this work properly we'd need to scale the UV's too, better to ignore th - # texture.repeat = max(1, ima_repS * 512), max(1, ima_repT * 512) - - if not ima_repS: bpyima.clampX = True - if not ima_repT: bpyima.clampY = True - - bpydata = None - geom_spec = geom.getSpec() - ccw = True - if geom_spec == 'IndexedFaceSet': - bpydata, ccw = importMesh_IndexedFaceSet(geom, bpyima, ancestry) - elif geom_spec == 'IndexedLineSet': - bpydata = importMesh_IndexedLineSet(geom, ancestry) - elif geom_spec == 'PointSet': - bpydata = importMesh_PointSet(geom, ancestry) - elif geom_spec == 'Sphere': - bpydata = importMesh_Sphere(geom, ancestry) - elif geom_spec == 'Box': - bpydata = importMesh_Box(geom, ancestry) - elif geom_spec == 'Cylinder': - bpydata = importMesh_Cylinder(geom, ancestry) - elif geom_spec == 'Cone': - bpydata = importMesh_Cone(geom, ancestry) - else: - print '\tWarning: unsupported type "%s"' % geom_spec - return - - if bpydata: - vrmlname = vrmlname + geom_spec - - bpydata.name = vrmlname - - bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpydata) - - if type(bpydata) == Types.MeshType: - is_solid = geom.getFieldAsBool('solid', True, ancestry) - creaseAngle = geom.getFieldAsFloat('creaseAngle', None, ancestry) - - if creaseAngle != None: - bpydata.maxSmoothAngle = 1+int(min(79, creaseAngle * RAD_TO_DEG)) - bpydata.mode |= Mesh.Modes.AUTOSMOOTH - - # Only ever 1 material per shape - if bpymat: bpydata.materials = [bpymat] - - if bpydata.faceUV: - - if depth==32: # set the faces alpha flag? - transp = Mesh.FaceTranspModes.ALPHA - for f in bpydata.faces: - f.transp = transp - - if texmtx: - # Apply texture transform? - uv_copy = Vector() - for f in bpydata.faces: - for uv in f.uv: - uv_copy.x = uv.x - uv_copy.y = uv.y - - uv.x, uv.y = (uv_copy * texmtx)[0:2] - # Done transforming the texture - - - # Must be here and not in IndexedFaceSet because it needs an object for the flip func. Messy :/ - if not ccw: bpydata.flipNormals() - - - # else could be a curve for example - - - - # Can transform data or object, better the object so we can instance the data - #bpymesh.transform(getFinalMatrix(node)) - bpyob.setMatrix( getFinalMatrix(node, None, ancestry) ) - - -def importLamp_PointLight(node, ancestry): - vrmlname = node.getDefName() - if not vrmlname: vrmlname = 'PointLight' - - # ambientIntensity = node.getFieldAsFloat('ambientIntensity', 0.0, ancestry) # TODO - # attenuation = node.getFieldAsFloatTuple('attenuation', (1.0, 0.0, 0.0), ancestry) # TODO - color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0), ancestry) - intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher. - location = node.getFieldAsFloatTuple('location', (0.0, 0.0, 0.0), ancestry) - # is_on = node.getFieldAsBool('on', True, ancestry) # TODO - radius = node.getFieldAsFloat('radius', 100.0, ancestry) - - bpylamp = bpy.data.lamps.new() - bpylamp.setType('Lamp') - bpylamp.energy = intensity - bpylamp.dist = radius - bpylamp.col = color - - mtx = TranslationMatrix(Vector(location)) - - return bpylamp, mtx - -def importLamp_DirectionalLight(node, ancestry): - vrmlname = node.getDefName() - if not vrmlname: vrmlname = 'DirectLight' - - # ambientIntensity = node.getFieldAsFloat('ambientIntensity', 0.0) # TODO - color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0), ancestry) - direction = node.getFieldAsFloatTuple('direction', (0.0, 0.0, -1.0), ancestry) - intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher. - # is_on = node.getFieldAsBool('on', True, ancestry) # TODO - - bpylamp = bpy.data.lamps.new(vrmlname) - bpylamp.setType('Sun') - bpylamp.energy = intensity - bpylamp.col = color - - # lamps have their direction as -z, yup - mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4() - - return bpylamp, mtx - -# looks like default values for beamWidth and cutOffAngle were swapped in VRML docs. - -def importLamp_SpotLight(node, ancestry): - vrmlname = node.getDefName() - if not vrmlname: vrmlname = 'SpotLight' - - # ambientIntensity = geom.getFieldAsFloat('ambientIntensity', 0.0, ancestry) # TODO - # attenuation = geom.getFieldAsFloatTuple('attenuation', (1.0, 0.0, 0.0), ancestry) # TODO - beamWidth = node.getFieldAsFloat('beamWidth', 1.570796, ancestry) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher. - color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0), ancestry) - cutOffAngle = node.getFieldAsFloat('cutOffAngle', 0.785398, ancestry) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher. - direction = node.getFieldAsFloatTuple('direction', (0.0, 0.0, -1.0), ancestry) - intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher. - location = node.getFieldAsFloatTuple('location', (0.0, 0.0, 0.0), ancestry) - # is_on = node.getFieldAsBool('on', True, ancestry) # TODO - radius = node.getFieldAsFloat('radius', 100.0, ancestry) - - bpylamp = bpy.data.lamps.new(vrmlname) - bpylamp.setType('Spot') - bpylamp.energy = intensity - bpylamp.dist = radius - bpylamp.col = color - bpylamp.spotSize = cutOffAngle - if beamWidth > cutOffAngle: - bpylamp.spotBlend = 0.0 - else: - if cutOffAngle==0.0: #@#$%^&*(!!! - this should never happen - bpylamp.spotBlend = 0.5 - else: - bpylamp.spotBlend = beamWidth / cutOffAngle - - # Convert - - # lamps have their direction as -z, y==up - mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4() * TranslationMatrix(Vector(location)) - - return bpylamp, mtx - - -def importLamp(node, spec, ancestry): - if spec=='PointLight': - bpylamp,mtx = importLamp_PointLight(node, ancestry) - elif spec=='DirectionalLight': - bpylamp,mtx = importLamp_DirectionalLight(node, ancestry) - elif spec=='SpotLight': - bpylamp,mtx = importLamp_SpotLight(node, ancestry) - else: - print "Error, not a lamp" - raise ValueError - - bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpylamp) - bpyob.setMatrix( getFinalMatrix(node, mtx, ancestry) ) - - -def importViewpoint(node, ancestry): - name = node.getDefName() - if not name: name = 'Viewpoint' - - fieldOfView = node.getFieldAsFloat('fieldOfView', 0.785398, ancestry) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher. - # jump = node.getFieldAsBool('jump', True, ancestry) - orientation = node.getFieldAsFloatTuple('orientation', (0.0, 0.0, 1.0, 0.0), ancestry) - position = node.getFieldAsFloatTuple('position', (0.0, 0.0, 0.0), ancestry) - description = node.getFieldAsString('description', '', ancestry) - - bpycam = bpy.data.cameras.new(name) - - bpycam.angle = fieldOfView - - mtx = translateRotation(orientation) * TranslationMatrix(Vector(position)) - - - bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpycam) - bpyob.setMatrix( getFinalMatrix(node, mtx, ancestry) ) - - -def importTransform(node, ancestry): - name = node.getDefName() - if not name: name = 'Transform' - - bpyob = node.blendObject = bpy.data.scenes.active.objects.new('Empty', name) # , name) - bpyob.setMatrix( getFinalMatrix(node, None, ancestry) ) - - # so they are not too annoying - bpyob.emptyShape= Blender.Object.EmptyShapes.AXES - bpyob.drawSize= 0.2 - - -#def importTimeSensor(node): - - -def translatePositionInterpolator(node, ipo, ancestry): - key = node.getFieldAsArray('key', 0, ancestry) - keyValue = node.getFieldAsArray('keyValue', 3, ancestry) - - try: - loc_x = ipo.addCurve('LocX') - loc_y = ipo.addCurve('LocY') - loc_z = ipo.addCurve('LocZ') - except ValueError: - return - - loc_x.interpolation = loc_y.interpolation = loc_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - - for i, time in enumerate(key): - try: x,y,z = keyValue[i] - except: continue - - loc_x.append((time,x)) - loc_y.append((time,y)) - loc_z.append((time,z)) - -def translateOrientationInterpolator(node, ipo, ancestry): - key = node.getFieldAsArray('key', 0, ancestry) - keyValue = node.getFieldAsArray('keyValue', 4, ancestry) - - try: - rot_x = ipo.addCurve('RotX') - rot_y = ipo.addCurve('RotY') - rot_z = ipo.addCurve('RotZ') - except ValueError: - return - - rot_x.interpolation = rot_y.interpolation = rot_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - - for i, time in enumerate(key): - try: x,y,z,w = keyValue[i] - except: continue - - mtx = translateRotation((x,y,z,w)) - eul = mtx.toEuler() - rot_x.append((time,eul.x/10.0)) - rot_y.append((time,eul.y/10.0)) - rot_z.append((time,eul.z/10.0)) - -# Untested! -def translateScalarInterpolator(node, ipo, ancestry): - key = node.getFieldAsArray('key', 0, ancestry) - keyValue = node.getFieldAsArray('keyValue', 4, ancestry) - - try: - sca_x = ipo.addCurve('ScaleX') - sca_y = ipo.addCurve('ScaleY') - sca_z = ipo.addCurve('ScaleZ') - except ValueError: - return - - sca_x.interpolation = sca_y.interpolation = sca_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - - for i, time in enumerate(key): - try: x,y,z = keyValue[i] - except: continue - sca_x.append((time,x/10.0)) - sca_y.append((time,y/10.0)) - sca_z.append((time,z/10.0)) - -def translateTimeSensor(node, ipo, ancestry): - ''' - Apply a time sensor to an IPO, VRML has many combinations of loop/start/stop/cycle times - to give different results, for now just do the basics - ''' - - time_cu = ipo.addCurve('Time') - time_cu.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - - cycleInterval = node.getFieldAsFloat('cycleInterval', None, ancestry) - - startTime = node.getFieldAsFloat('startTime', 0.0, ancestry) - stopTime = node.getFieldAsFloat('stopTime', 250.0, ancestry) - - if cycleInterval != None: - stopTime = startTime+cycleInterval - - loop = node.getFieldAsBool('loop', False, ancestry) - - time_cu.append((1+startTime, 0.0)) - time_cu.append((1+stopTime, 1.0/10.0))# anoying, the UI uses /10 - - - if loop: - time_cu.extend = Blender.IpoCurve.ExtendTypes.CYCLIC # or - EXTRAP, CYCLIC_EXTRAP, CONST, - - -def importRoute(node, ancestry): - ''' - Animation route only at the moment - ''' - - if not hasattr(node, 'fields'): - return - - routeIpoDict = node.getRouteIpoDict() - - def getIpo(id): - try: ipo = routeIpoDict[id] - except: ipo = routeIpoDict[id] = bpy.data.ipos.new('web3d_ipo', 'Object') - return ipo - - # for getting definitions - defDict = node.getDefDict() - ''' - Handles routing nodes to eachother - -ROUTE vpPI.value_changed TO champFly001.set_position -ROUTE vpOI.value_changed TO champFly001.set_orientation -ROUTE vpTs.fraction_changed TO vpPI.set_fraction -ROUTE vpTs.fraction_changed TO vpOI.set_fraction -ROUTE champFly001.bindTime TO vpTs.set_startTime - ''' - - #from_id, from_type = node.id[1].split('.') - #to_id, to_type = node.id[3].split('.') - - #value_changed - set_position_node = None - set_orientation_node = None - time_node = None - - for field in node.fields: - if field and field[0]=='ROUTE': - try: - from_id, from_type = field[1].split('.') - to_id, to_type = field[3].split('.') - except: - print "Warning, invalid ROUTE", field - continue - - if from_type == 'value_changed': - if to_type == 'set_position': - ipo = getIpo(to_id) - set_data_from_node = defDict[from_id] - translatePositionInterpolator(set_data_from_node, ipo, ancestry) - - if to_type in ('set_orientation', 'rotation'): - ipo = getIpo(to_id) - set_data_from_node = defDict[from_id] - translateOrientationInterpolator(set_data_from_node, ipo, ancestry) - - if to_type == 'set_scale': - ipo = getIpo(to_id) - set_data_from_node = defDict[from_id] - translateScalarInterpolator(set_data_from_node, ipo, ancestry) - - elif from_type =='bindTime': - ipo = getIpo(from_id) - time_node = defDict[to_id] - translateTimeSensor(time_node, ipo, ancestry) - - - - -def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC = None): - - # Used when adding blender primitives - GLOBALS['CIRCLE_DETAIL'] = PREF_CIRCLE_DIV - - #root_node = vrml_parse('/_Cylinder.wrl') - if path.lower().endswith('.x3d'): - root_node, msg = x3d_parse(path) - else: - root_node, msg = vrml_parse(path) - - if not root_node: - if Blender.mode == 'background': - print msg - else: - Blender.Draw.PupMenu(msg) - return - - - # fill with tuples - (node, [parents-parent, parent]) - all_nodes = root_node.getSerialized([], []) - - for node, ancestry in all_nodes: - #if 'castle.wrl' not in node.getFilename(): - # continue - - spec = node.getSpec() - ''' - prefix = node.getPrefix() - if prefix=='PROTO': - pass - else - ''' - if HELPER_FUNC and HELPER_FUNC(node, ancestry): - # Note, include this function so the VRML/X3D importer can be extended - # by an external script. - gets first pick - pass - if spec=='Shape': - importShape(node, ancestry) - elif spec in ('PointLight', 'DirectionalLight', 'SpotLight'): - importLamp(node, spec, ancestry) - elif spec=='Viewpoint': - importViewpoint(node, ancestry) - elif spec=='Transform': - # Only use transform nodes when we are not importing a flat object hierarchy - if PREF_FLAT==False: - importTransform(node, ancestry) - ''' - # These are delt with later within importRoute - elif spec=='PositionInterpolator': - ipo = bpy.data.ipos.new('web3d_ipo', 'Object') - translatePositionInterpolator(node, ipo) - ''' - - - - # After we import all nodes, route events - anim paths - for node, ancestry in all_nodes: - importRoute(node, ancestry) - - for node, ancestry in all_nodes: - if node.isRoot(): - # we know that all nodes referenced from will be in - # routeIpoDict so no need to run node.getDefDict() for every node. - routeIpoDict = node.getRouteIpoDict() - defDict = node.getDefDict() - - for key, ipo in routeIpoDict.iteritems(): - - # Assign anim curves - node = defDict[key] - if node.blendObject==None: # Add an object if we need one for animation - node.blendObject = bpy.data.scenes.active.objects.new('Empty', 'AnimOb') # , name) - - node.blendObject.setIpo(ipo) - - - - # Add in hierarchy - if PREF_FLAT==False: - child_dict = {} - for node, ancestry in all_nodes: - if node.blendObject: - blendObject = None - - # Get the last parent - i = len(ancestry) - while i: - i-=1 - blendObject = ancestry[i].blendObject - if blendObject: - break - - if blendObject: - # Parent Slow, - 1 liner but works - # blendObject.makeParent([node.blendObject], 0, 1) - - # Parent FAST - try: child_dict[blendObject].append(node.blendObject) - except: child_dict[blendObject] = [node.blendObject] - - # Parent FAST - for parent, children in child_dict.iteritems(): - parent.makeParent(children, 0, 1) - - # update deps - bpy.data.scenes.active.update(1) - del child_dict - - -def load_ui(path): - Draw = Blender.Draw - PREF_HIERARCHY= Draw.Create(0) - PREF_CIRCLE_DIV= Draw.Create(16) - - # Get USER Options - pup_block= [\ - 'Import...',\ - ('Hierarchy', PREF_HIERARCHY, 'Import transform nodes as empties to create a parent/child hierarchy'),\ - ('Circle Div:', PREF_CIRCLE_DIV, 3, 128, 'Number of divisions to use for circular primitives') - ] - - if not Draw.PupBlock('Import X3D/VRML...', pup_block): - return - - Window.WaitCursor(1) - - load_web3d(path,\ - (not PREF_HIERARCHY.val),\ - PREF_CIRCLE_DIV.val,\ - ) - - Window.WaitCursor(0) - - -if __name__ == '__main__': - Window.FileSelector(load_ui, 'Import X3D/VRML97') - - -# Testing stuff - -# load_web3d('/test.x3d') -# load_web3d('/_Cylinder.x3d') - -# Testing below -# load_web3d('m:\\root\\Desktop\\_Cylinder.wrl') -# load_web3d('/_Cylinder.wrl') -# load_web3d('/fe/wrl/Vrml/EGS/BCKGD.WRL') - -# load_web3d('/fe/wrl/Vrml/EGS/GRNDPLNE.WRL') -# load_web3d('/fe/wrl/Vrml/EGS/INDEXFST.WRL') -# load_web3d('/fe/wrl/panel1c.wrl') -# load_web3d('/test.wrl') -# load_web3d('/fe/wrl/dulcimer.wrl') -# load_web3d('/fe/wrl/rccad/Ju-52.wrl') # Face index out of range -# load_web3d('/fe/wrl/16lat.wrl') # spotlight -# load_web3d('/fe/wrl/Vrml/EGS/FOG.WRL') # spotlight -# load_web3d('/fe/wrl/Vrml/EGS/LOD.WRL') # vcolor per face - -# load_web3d('/fe/wrl/new/daybreak_final.wrl') # no faces in mesh, face duplicate error -# load_web3d('/fe/wrl/new/earth.wrl') -# load_web3d('/fe/wrl/new/hendrix.ei.dtu.dk/vrml/talairach/fourd/TalaDruryRight.wrl') # define/use fields -# load_web3d('/fe/wrl/new/imac.wrl') # extrusion and define/use fields, face index is a float somehow -# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/mcastle.wrl') -# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/tower.wrl') -# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/temple.wrl') -# load_web3d('/fe/wrl/brain.wrl') # field define test 'a IS b' -# load_web3d('/fe/wrl/new/coaster.wrl') # fields that are confusing to read. - -# X3D - -# load_web3d('/fe/x3d/www.web3d.org/x3d/content/examples/Basic/StudentProjects/PlayRoom.x3d') # invalid UVs - - - -def test(): - import os - - files = os.popen('find /fe/wrl -iname "*.wrl"').readlines() - # files = os.popen('find /fe/x3d -iname "*.x3d"').readlines() - # files = os.popen('find /fe/x3d/X3dExamplesSavage -iname "*.x3d"').readlines() - - files.sort() - tot = len(files) - for i, f in enumerate(files): - if i < 124 or i > 1000000: - continue - - #if i != 1068: - # continue - - #if i != 12686: - # continue - - f = f.strip() - print f, i, tot - sce = bpy.data.scenes.new(str(i) + '_' + f.split('/')[-1]) - bpy.data.scenes.active = sce - # Window. - load_web3d(f, PREF_FLAT=True) - -# test() diff --git a/release/scripts/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py new file mode 100644 index 00000000000..f0247ce532a --- /dev/null +++ b/release/scripts/io/engine_render_pov.py @@ -0,0 +1,912 @@ +import bpy + +from math import atan, pi, degrees +import subprocess +import os +import sys +import time + +import platform as pltfrm + +if pltfrm.architecture()[0] == '64bit': + bitness = 64 +else: + bitness = 32 + +def write_pov(filename, scene=None, info_callback = None): + file = open(filename, 'w') + + # Only for testing + if not scene: + scene = bpy.data.scenes[0] + + render = scene.render_data + world = scene.world + + # --- taken from fbx exporter + ## This was used to make V, but faster not to do all that + ##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' + ##v = range(255) + ##for c in valid: v.remove(ord(c)) + v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,46,47,58,59,60,61,62,63,64,92,94,96,124,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] + invalid = ''.join([chr(i) for i in v]) + def cleanName(name): + for ch in invalid: name = name.replace(ch, '_') + return name + del v + + # --- done with clean name. + + def uniqueName(name, nameSeq): + + if name not in nameSeq: + return name + + name_orig = name + i = 1 + while name in nameSeq: + name = '%s_%.3d' % (name_orig, i) + i+=1 + + return name + + + def writeMatrix(matrix): + file.write('\tmatrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n' %\ + (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2]) ) + + def writeObjectMaterial(material): + if material and material.transparency_method=='RAYTRACE': + file.write('\tinterior { ior %.6f }\n' % material.raytrace_transparency.ior) + + # Other interior args + # fade_distance 2 + # fade_power [Value] + # fade_color + + # dispersion + # dispersion_samples + + materialNames = {} + DEF_MAT_NAME = 'Default' + def writeMaterial(material): + # Assumes only called once on each material + + if material: + name_orig = material.name + else: + name_orig = DEF_MAT_NAME + + name = materialNames[name_orig] = uniqueName(cleanName(name_orig), materialNames) + + file.write('#declare %s = finish {\n' % name) + + if material: + file.write('\tdiffuse %.3g\n' % material.diffuse_intensity) + file.write('\tspecular %.3g\n' % material.specular_intensity) + + file.write('\tambient %.3g\n' % material.ambient) + #file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value + + # map hardness between 0.0 and 1.0 + roughness = ((1.0 - ((material.specular_hardness-1.0)/510.0))) + # scale from 0.0 to 0.1 + roughness *= 0.1 + # add a small value because 0.0 is invalid + roughness += (1/511.0) + + file.write('\troughness %.3g\n' % roughness) + + # 'phong 70.0 ' + + if material.raytrace_mirror.enabled: + raytrace_mirror= material.raytrace_mirror + if raytrace_mirror.reflect_factor: + file.write('\treflection {\n') + file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color)) + file.write('\t\tfresnel 1 falloff %.3g exponent %.3g metallic %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor, raytrace_mirror.reflect_factor)) + + else: + file.write('\tdiffuse 0.8\n') + file.write('\tspecular 0.2\n') + + + # This is written into the object + ''' + if material and material.transparency_method=='RAYTRACE': + 'interior { ior %.3g} ' % material.raytrace_transparency.ior + ''' + + #file.write('\t\t\tcrand 1.0\n') # Sand granyness + #file.write('\t\t\tmetallic %.6f\n' % material.spec) + #file.write('\t\t\tphong %.6f\n' % material.spec) + #file.write('\t\t\tphong_size %.6f\n' % material.spec) + #file.write('\t\t\tbrilliance %.6f ' % (material.specular_hardness/256.0) # Like hardness + + file.write('}\n') + + def exportCamera(): + camera = scene.camera + matrix = camera.matrix + + # compute resolution + Qsize=float(render.resolution_x)/float(render.resolution_y) + + file.write('camera {\n') + file.write('\tlocation <0, 0, 0>\n') + file.write('\tlook_at <0, 0, -1>\n') + file.write('\tright <%s, 0, 0>\n' % -Qsize) + file.write('\tup <0, 1, 0>\n') + file.write('\tangle %f \n' % (360.0*atan(16.0/camera.data.lens)/pi)) + + file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotationPart().toEuler()])) + file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2])) + file.write('}\n') + + def exportLamps(lamps): + # Get all lamps + for ob in lamps: + lamp = ob.data + + matrix = ob.matrix + + color = tuple([c * lamp.energy for c in lamp.color]) # Colour is modified by energy + + file.write('light_source {\n') + file.write('\t< 0,0,0 >\n') + file.write('\tcolor rgb<%.3g, %.3g, %.3g>\n' % color) + + if lamp.type == 'POINT': # Point Lamp + pass + elif lamp.type == 'SPOT': # Spot + file.write('\tspotlight\n') + + # Falloff is the main radius from the centre line + file.write('\tfalloff %.2f\n' % (lamp.spot_size/2.0) ) # 1 TO 179 FOR BOTH + file.write('\tradius %.6f\n' % ((lamp.spot_size/2.0) * (1-lamp.spot_blend)) ) + + # Blender does not have a tightness equivilent, 0 is most like blender default. + file.write('\ttightness 0\n') # 0:10f + + file.write('\tpoint_at <0, 0, -1>\n') + elif lamp.type == 'SUN': + file.write('\tparallel\n') + file.write('\tpoint_at <0, 0, -1>\n') # *must* be after 'parallel' + + elif lamp.type == 'AREA': + + size_x = lamp.size + samples_x = lamp.shadow_ray_samples_x + if lamp.shape == 'SQUARE': + size_y = size_x + samples_y = samples_x + else: + size_y = lamp.size_y + samples_y = lamp.shadow_ray_samples_y + + file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y)) + if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED': + if lamp.jitter: + file.write('\tjitter\n') + else: + file.write('\tadaptive 1\n') + file.write('\tjitter\n') + + if lamp.shadow_method == 'NOSHADOW': + file.write('\tshadowless\n') + + file.write('\tfade_distance %.6f\n' % lamp.distance) + file.write('\tfade_power %d\n' % 1) # Could use blenders lamp quad? + writeMatrix(matrix) + + file.write('}\n') + + def exportMeta(metas): + + # TODO - blenders 'motherball' naming is not supported. + + for ob in metas: + meta = ob.data + + file.write('blob {\n') + file.write('\t\tthreshold %.4g\n' % meta.threshold) + + try: + material= meta.materials[0] # lame! - blender cant do enything else. + except: + material= None + + for elem in meta.elements: + + if elem.type not in ('BALL', 'ELLIPSOID'): + continue # Not supported + + loc = elem.location + + stiffness= elem.stiffness + if elem.negative: + stiffness = -stiffness + + if elem.type == 'BALL': + + file.write('\tsphere { <%.6g, %.6g, %.6g>, %.4g, %.4g ' % (loc.x, loc.y, loc.z, elem.radius, stiffness)) + + # After this wecould do something simple like... + # "pigment {Blue} }" + # except we'll write the color + + elif elem.type == 'ELLIPSOID': + # location is modified by scale + file.write('\tsphere { <%.6g, %.6g, %.6g>, %.4g, %.4g ' % (loc.x/elem.size_x, loc.y/elem.size_y, loc.z/elem.size_z, elem.radius, stiffness)) + file.write( 'scale <%.6g, %.6g, %.6g> ' % (elem.size_x, elem.size_y, elem.size_z)) + + if material: + diffuse_color = material.diffuse_color + + if material.transparency and material.transparency_method=='RAYTRACE': trans = 1-material.raytrace_transparency.filter + else: trans = 0.0 + + file.write( + 'pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s} }\n' % \ + (diffuse_color[0], diffuse_color[1], diffuse_color[2], 1-material.alpha, trans, materialNames[material.name]) + ) + + else: + file.write('pigment {rgb<1 1 1>} finish {%s} }\n' % DEF_MAT_NAME) # Write the finish last. + + writeObjectMaterial(material) + + writeMatrix(ob.matrix) + + file.write('}\n') + + def exportMeshs(sel): + + ob_num = 0 + + for ob in sel: + ob_num+= 1 + + if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META'): + continue + + me = ob.data + me_materials= me.materials + + me = ob.create_mesh(True, 'RENDER') + + if not me: + continue + + if info_callback: + info_callback('Object %2.d of %2.d (%s)' % (ob_num, len(sel), ob.name)) + + #if ob.type!='MESH': + # continue + # me = ob.data + + matrix = ob.matrix + try: uv_layer = me.active_uv_texture.data + except:uv_layer = None + + try: vcol_layer = me.active_vertex_color.data + except:vcol_layer = None + + faces_verts = [f.verts for f in me.faces] + faces_normals = [tuple(f.normal) for f in me.faces] + verts_normals = [tuple(v.normal) for v in me.verts] + + # quads incur an extra face + quadCount = len([f for f in faces_verts if len(f)==4]) + + file.write('mesh2 {\n') + file.write('\tvertex_vectors {\n') + file.write('\t\t%s' % (len(me.verts))) # vert count + for v in me.verts: + file.write(',\n\t\t<%.6f, %.6f, %.6f>' % tuple(v.co)) # vert count + file.write('\n }\n') + + + # Build unique Normal list + uniqueNormals = {} + for fi, f in enumerate(me.faces): + fv = faces_verts[fi] + # [-1] is a dummy index, use a list so we can modify in place + if f.smooth: # Use vertex normals + for v in fv: + key = verts_normals[v] + uniqueNormals[key] = [-1] + else: # Use face normal + key = faces_normals[fi] + uniqueNormals[key] = [-1] + + file.write('\tnormal_vectors {\n') + file.write('\t\t%d' % len(uniqueNormals)) # vert count + idx = 0 + for no, index in uniqueNormals.items(): + file.write(',\n\t\t<%.6f, %.6f, %.6f>' % no) # vert count + index[0] = idx + idx +=1 + file.write('\n }\n') + + + # Vertex colours + vertCols = {} # Use for material colours also. + + if uv_layer: + # Generate unique UV's + uniqueUVs = {} + + for fi, uv in enumerate(uv_layer): + + if len(faces_verts[fi])==4: + uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4 + else: + uvs = uv.uv1, uv.uv2, uv.uv3 + + for uv in uvs: + uniqueUVs[tuple(uv)] = [-1] + + file.write('\tuv_vectors {\n') + #print unique_uvs + file.write('\t\t%s' % (len(uniqueUVs))) # vert count + idx = 0 + for uv, index in uniqueUVs.items(): + file.write(',\n\t\t<%.6f, %.6f>' % uv) + index[0] = idx + idx +=1 + ''' + else: + # Just add 1 dummy vector, no real UV's + file.write('\t\t1') # vert count + file.write(',\n\t\t<0.0, 0.0>') + ''' + file.write('\n }\n') + + + if me.vertex_colors: + + for fi, f in enumerate(me.faces): + material_index = f.material_index + material = me_materials[material_index] + + if material and material.vertex_color_paint: + + col = vcol_layer[fi] + + if len(faces_verts[fi])==4: + cols = col.color1, col.color2, col.color3, col.color4 + else: + cols = col.color1, col.color2, col.color3 + + for col in cols: + key = col[0], col[1], col[2], material_index # Material index! + vertCols[key] = [-1] + + else: + if material: + diffuse_color = tuple(material.diffuse_color) + key = diffuse_color[0], diffuse_color[1], diffuse_color[2], material_index + vertCols[key] = [-1] + + + else: + # No vertex colours, so write material colours as vertex colours + for i, material in enumerate(me_materials): + + if material: + diffuse_color = tuple(material.diffuse_color) + key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat + vertCols[key] = [-1] + + + # Vert Colours + file.write('\ttexture_list {\n') + file.write('\t\t%s' % (len(vertCols))) # vert count + idx=0 + for col, index in vertCols.items(): + + if me_materials: + material = me_materials[col[3]] + material_finish = materialNames[material.name] + + if material.transparency and material.transparency_method=='RAYTRACE': trans = 1-material.raytrace_transparency.filter + else: trans = 0.0 + + else: + material_finish = DEF_MAT_NAME # not working properly, + trans = 0.0 + + #print material.apl + file.write( ',\n\t\ttexture { pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s}}' % + (col[0], col[1], col[2], 1-material.alpha, trans, material_finish) ) + + index[0] = idx + idx+=1 + + file.write( '\n }\n' ) + + # Face indicies + file.write('\tface_indices {\n') + file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count + for fi, f in enumerate(me.faces): + fv = faces_verts[fi] + material_index= f.material_index + if len(fv) == 4: indicies = (0,1,2), (0,2,3) + else: indicies = ((0,1,2),) + + if vcol_layer: + col = vcol_layer[fi] + + if len(fv) == 4: + cols = col.color1, col.color2, col.color3, col.color4 + else: + cols = col.color1, col.color2, col.color3 + + + if not me_materials or me_materials[material_index] == None: # No materials + for i1, i2, i3 in indicies: + file.write(',\n\t\t<%d,%d,%d>' % (fv[i1], fv[i2], fv[i3])) # vert count + else: + material = me_materials[material_index] + for i1, i2, i3 in indicies: + if me.vertex_colors and material.vertex_color_paint: + # Colour per vertex - vertex colour + + col1 = cols[i1] + col2 = cols[i2] + col3 = cols[i3] + + ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0] + ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0] + ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0] + else: + # Colour per material - flat material colour + diffuse_color= material.diffuse_color + ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], diffuse_color[2], f.material_index][0] + + file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count + + + file.write('\n }\n') + + # normal_indices indicies + file.write('\tnormal_indices {\n') + file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count + for fi, fv in enumerate(faces_verts): + + if len(fv) == 4: indicies = (0,1,2), (0,2,3) + else: indicies = ((0,1,2),) + + for i1, i2, i3 in indicies: + if f.smooth: + file.write(',\n\t\t<%d,%d,%d>' %\ + (uniqueNormals[verts_normals[fv[i1]]][0],\ + uniqueNormals[verts_normals[fv[i2]]][0],\ + uniqueNormals[verts_normals[fv[i3]]][0])) # vert count + else: + idx = uniqueNormals[faces_normals[fi]][0] + file.write(',\n\t\t<%d,%d,%d>' % (idx, idx, idx)) # vert count + + file.write('\n }\n') + + if uv_layer: + file.write('\tuv_indices {\n') + file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count + for fi, fv in enumerate(faces_verts): + + if len(fv) == 4: indicies = (0,1,2), (0,2,3) + else: indicies = ((0,1,2),) + + uv = uv_layer[fi] + if len(faces_verts[fi])==4: + uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3), tuple(uv.uv4) + else: + uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3) + + for i1, i2, i3 in indicies: + file.write(',\n\t\t<%d,%d,%d>' %\ + (uniqueUVs[uvs[i1]][0],\ + uniqueUVs[uvs[i2]][0],\ + uniqueUVs[uvs[i2]][0])) # vert count + file.write('\n }\n') + + if me.materials: + material = me.materials[0] # dodgy + writeObjectMaterial(material) + + writeMatrix(matrix) + file.write('}\n') + + bpy.data.remove_mesh(me) + + def exportWorld(world): + if not world: + return + + mist = world.mist + + if mist.enabled: + file.write('fog {\n') + file.write('\tdistance %.6f\n' % mist.depth) + file.write('\tcolor rgbt<%.3g, %.3g, %.3g, %.3g>\n' % (tuple(world.horizon_color) + (1-mist.intensity,))) + #file.write('\tfog_offset %.6f\n' % mist.start) + #file.write('\tfog_alt 5\n') + #file.write('\tturbulence 0.2\n') + #file.write('\tturb_depth 0.3\n') + file.write('\tfog_type 1\n') + file.write('}\n') + + def exportGlobalSettings(scene): + + file.write('global_settings {\n') + + if scene.pov_radio_enable: + file.write('\tradiosity {\n') + file.write("\t\tadc_bailout %.4g\n" % scene.pov_radio_adc_bailout) + file.write("\t\talways_sample %d\n" % scene.pov_radio_always_sample) + file.write("\t\tbrightness %.4g\n" % scene.pov_radio_brightness) + file.write("\t\tcount %d\n" % scene.pov_radio_count) + file.write("\t\terror_bound %.4g\n" % scene.pov_radio_error_bound) + file.write("\t\tgray_threshold %.4g\n" % scene.pov_radio_gray_threshold) + file.write("\t\tlow_error_factor %.4g\n" % scene.pov_radio_low_error_factor) + file.write("\t\tmedia %d\n" % scene.pov_radio_media) + file.write("\t\tminimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse) + file.write("\t\tnearest_count %d\n" % scene.pov_radio_nearest_count) + file.write("\t\tnormal %d\n" % scene.pov_radio_normal) + file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit) + file.write('\t}\n') + + if world: + file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color)) + + file.write('}\n') + + + # Convert all materials to strings we can access directly per vertex. + writeMaterial(None) # default material + + for material in bpy.data.materials: + writeMaterial(material) + + exportCamera() + #exportMaterials() + sel = scene.objects + exportLamps([l for l in sel if l.type == 'LAMP']) + exportMeta([l for l in sel if l.type == 'META']) + exportMeshs(sel) + exportWorld(scene.world) + exportGlobalSettings(scene) + + file.close() + +def write_pov_ini(filename_ini, filename_pov, filename_image): + scene = bpy.data.scenes[0] + render = scene.render_data + + x= int(render.resolution_x*render.resolution_percentage*0.01) + y= int(render.resolution_y*render.resolution_percentage*0.01) + + file = open(filename_ini, 'w') + + file.write('Input_File_Name="%s"\n' % filename_pov) + file.write('Output_File_Name="%s"\n' % filename_image) + + file.write('Width=%d\n' % x) + file.write('Height=%d\n' % y) + + # Needed for border render. + ''' + file.write('Start_Column=%d\n' % part.x) + file.write('End_Column=%d\n' % (part.x+part.w)) + + file.write('Start_Row=%d\n' % (part.y)) + file.write('End_Row=%d\n' % (part.y+part.h)) + ''' + + file.write('Display=0\n') + file.write('Pause_When_Done=0\n') + file.write('Output_File_Type=T\n') # TGA, best progressive loading + file.write('Output_Alpha=1\n') + + if render.antialiasing: + aa_mapping = {'OVERSAMPLE_5':2, 'OVERSAMPLE_8':3, 'OVERSAMPLE_11':4, 'OVERSAMPLE_16':5} # method 1 assumed + file.write('Antialias=1\n') + file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples]) + else: + file.write('Antialias=0\n') + + file.close() + +# Radiosity panel, use in the scene for now. +FloatProperty= bpy.types.Scene.FloatProperty +IntProperty= bpy.types.Scene.IntProperty +BoolProperty= bpy.types.Scene.BoolProperty + +# Not a real pov option, just to know if we should write +BoolProperty( attr="pov_radio_enable", + name="Enable Radiosity", + description="Enable povrays radiosity calculation.", + default= False) +BoolProperty( attr="pov_radio_display_advanced", + name="Advanced Options", + description="Show advanced options.", + default= False) + +# Real pov options +FloatProperty( attr="pov_radio_adc_bailout", + name="ADC Bailout", + description="The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results.", + min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default= 0.01) + +BoolProperty( attr="pov_radio_always_sample", + name="Always Sample", + description="Only use the data from the pretrace step and not gather any new samples during the final radiosity pass..", + default= True) + +FloatProperty( attr="pov_radio_brightness", + name="Brightness", + description="Ammount objects are brightened before being returned upwards to the rest of the system.", + min=0.0, max=1000.0, soft_min=0.0, soft_max=10.0, default= 1.0) + +IntProperty( attr="pov_radio_count", + name="Ray Count", + description="number of rays that are sent out whenever a new radiosity value has to be calculated.", + min=1, max=1600, default= 35) + +FloatProperty( attr="pov_radio_error_bound", + name="Error Bound", + description="one of the two main speed/quality tuning values, lower values are more accurate.", + min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default= 1.8) + +FloatProperty( attr="pov_radio_gray_threshold", + name="Gray Threshold", + description="one of the two main speed/quality tuning values, lower values are more accurate.", + min=0.0, max=1.0, soft_min=0, soft_max=1, default= 0.0) + +FloatProperty( attr="pov_radio_low_error_factor", + name="Low Error Factor", + description="If you calculate just enough samples, but no more, you will get an image which has slightly blotchy lighting.", + min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default= 0.5) + +# max_sample - not available yet +BoolProperty( attr="pov_radio_media", + name="Media", + description="Radiosity estimation can be affected by media.", + default= False) + +FloatProperty( attr="pov_radio_minimum_reuse", + name="Minimum Reuse", + description="Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors).", + min=0.0, max=1.0, soft_min=0.1, soft_max=0.1, default= 0.015) + +IntProperty( attr="pov_radio_nearest_count", + name="Nearest Count", + description="Number of old ambient values blended together to create a new interpolated value.", + min=1, max=20, default= 5) + +BoolProperty( attr="pov_radio_normal", + name="Normals", + description="Radiosity estimation can be affected by normals.", + default= False) + +IntProperty( attr="pov_radio_recursion_limit", + name="Recursion Limit", + description="how many recursion levels are used to calculate the diffuse inter-reflection.", + min=1, max=20, default= 3) + + +class PovrayRender(bpy.types.RenderEngine): + __idname__ = 'POVRAY_RENDER' + __label__ = "Povray" + DELAY = 0.02 + + def _export(self, scene): + import tempfile + + self.temp_file_in = tempfile.mktemp(suffix='.pov') + self.temp_file_out = tempfile.mktemp(suffix='.tga') + self.temp_file_ini = tempfile.mktemp(suffix='.ini') + ''' + self.temp_file_in = '/test.pov' + self.temp_file_out = '/test.tga' + self.temp_file_ini = '/test.ini' + ''' + + def info_callback(txt): + self.update_stats("", "POVRAY: " + txt) + + write_pov(self.temp_file_in, scene, info_callback) + + def _render(self): + + try: os.remove(self.temp_file_out) # so as not to load the old file + except: pass + + write_pov_ini(self.temp_file_ini, self.temp_file_in, self.temp_file_out) + + print ("***-STARTING-***") + + pov_binary = "povray" + + if sys.platform=='win32': + import winreg + regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.6\\Windows') + + if bitness == 64: + pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64' + else: + pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine' + + if 1: + self.process = subprocess.Popen([pov_binary, self.temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE + else: + # This works too but means we have to wait until its done + os.system('%s %s' % (pov_binary, self.temp_file_ini)) + + print ("***-DONE-***") + + def _cleanup(self): + for f in (self.temp_file_in, self.temp_file_ini, self.temp_file_out): + try: os.remove(f) + except: pass + + self.update_stats("", "") + + def render(self, scene): + + self.update_stats("", "POVRAY: Exporting data from Blender") + self._export(scene) + self.update_stats("", "POVRAY: Parsing File") + self._render() + + r = scene.render_data + + # compute resolution + x= int(r.resolution_x*r.resolution_percentage*0.01) + y= int(r.resolution_y*r.resolution_percentage*0.01) + + # Wait for the file to be created + while not os.path.exists(self.temp_file_out): + if self.test_break(): + try: self.process.terminate() + except: pass + break + + if self.process.poll() != None: + self.update_stats("", "POVRAY: Failed") + break + + time.sleep(self.DELAY) + + if os.path.exists(self.temp_file_out): + + self.update_stats("", "POVRAY: Rendering") + + prev_size = -1 + + def update_image(): + result = self.begin_result(0, 0, x, y) + lay = result.layers[0] + # possible the image wont load early on. + try: lay.load_from_file(self.temp_file_out) + except: pass + self.end_result(result) + + # Update while povray renders + while True: + + # test if povray exists + if self.process.poll() != None: + update_image(); + break + + # user exit + if self.test_break(): + try: self.process.terminate() + except: pass + + break + + # Would be nice to redirect the output + # stdout_value, stderr_value = self.process.communicate() # locks + + + # check if the file updated + new_size = os.path.getsize(self.temp_file_out) + + if new_size != prev_size: + update_image() + prev_size = new_size + + time.sleep(self.DELAY) + + self._cleanup() + +bpy.types.register(PovrayRender) + +# Use some of the existing buttons. +import buttons_scene +buttons_scene.SCENE_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_scene.SCENE_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_scene.SCENE_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_scene.SCENE_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') +del buttons_scene + +# Use only a subset of the world panels +import buttons_world +buttons_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER') +del buttons_world + +# Example of wrapping every class 'as is' +import buttons_material +for member in dir(buttons_material): + subclass = getattr(buttons_material, member) + try: subclass.COMPAT_ENGINES.add('POVRAY_RENDER') + except: pass +del buttons_material + +class RenderButtonsPanel(bpy.types.Panel): + __space_type__ = 'PROPERTIES' + __region_type__ = 'WINDOW' + __context__ = "scene" + # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here + + def poll(self, context): + rd = context.scene.render_data + return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) + +class SCENE_PT_povray_radiosity(RenderButtonsPanel): + __label__ = "Radiosity" + COMPAT_ENGINES = set(['POVRAY_RENDER']) + + def draw_header(self, context): + scene = context.scene + + self.layout.itemR(scene, "pov_radio_enable", text="") + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render_data + + layout.active = scene.pov_radio_enable + + split = layout.split() + + col = split.column() + col.itemR(scene, "pov_radio_count", text="Rays") + col.itemR(scene, "pov_radio_recursion_limit", text="Recursions") + col = split.column() + col.itemR(scene, "pov_radio_error_bound", text="Error") + + layout.itemR(scene, "pov_radio_display_advanced") + + if scene.pov_radio_display_advanced: + split = layout.split() + + col = split.column() + col.itemR(scene, "pov_radio_adc_bailout", slider=True) + col.itemR(scene, "pov_radio_gray_threshold", slider=True) + col.itemR(scene, "pov_radio_low_error_factor", slider=True) + + col = split.column() + col.itemR(scene, "pov_radio_brightness") + col.itemR(scene, "pov_radio_minimum_reuse", text="Min Reuse") + col.itemR(scene, "pov_radio_nearest_count") + + split = layout.split() + + col = split.column() + col.itemL(text="Estimation Influence:") + col.itemR(scene, "pov_radio_media") + col.itemR(scene, "pov_radio_normal") + + col = split.column() + col.itemR(scene, "pov_radio_always_sample") + +bpy.types.register(SCENE_PT_povray_radiosity) diff --git a/release/scripts/io/export_3ds.py b/release/scripts/io/export_3ds.py new file mode 100644 index 00000000000..19c12146769 --- /dev/null +++ b/release/scripts/io/export_3ds.py @@ -0,0 +1,1128 @@ +#!BPY +# coding: utf-8 +""" +Name: '3D Studio (.3ds)...' +Blender: 243 +Group: 'Export' +Tooltip: 'Export to 3DS file format (.3ds).' +""" + +__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] +__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") +__version__ = "0.90a" +__bpydoc__ = """\ + +3ds Exporter + +This script Exports a 3ds file. + +Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information +from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode. +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Bob Holcomb +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + + +###################################################### +# Importing modules +###################################################### + +import struct +import os +import time + +import bpy + +# import Blender +# from BPyMesh import getMeshFromObject +# from BPyObject import getDerivedObjects +# try: +# import struct +# except: +# struct = None + +# also used by X3D exporter +# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects() +def create_derived_objects(ob): + if ob.parent and ob.parent.dupli_type != 'NONE': + return False, None + + if ob.dupli_type != 'NONE': + ob.create_dupli_list() + return True, [(dob.object, dob.matrix) for dob in ob.dupli_list] + else: + return False, [(ob, ob.matrix)] + +# also used by X3D exporter +def free_derived_objects(ob): + ob.free_dupli_list() + +# So 3ds max can open files, limit names to 12 in length +# this is verry annoying for filenames! +name_unique = [] +name_mapping = {} +def sane_name(name): + name_fixed = name_mapping.get(name) + if name_fixed != None: + return name_fixed + + if len(name) > 12: + new_name = name[:12] + else: + new_name = name + + i = 0 + + while new_name in name_unique: + new_name = new_name[:-4] + '.%.3d' % i + i+=1 + + name_unique.append(new_name) + name_mapping[name] = new_name + return new_name + +###################################################### +# Data Structures +###################################################### + +#Some of the chunks that we will export +#----- Primary Chunk, at the beginning of each file +PRIMARY= int("0x4D4D",16) + +#------ Main Chunks +OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information +VERSION = int("0x0002",16); #This gives the version of the .3ds file +KFDATA = int("0xB000",16); #This is the header for all of the key frame info + +#------ sub defines of OBJECTINFO +MATERIAL=45055 #0xAFFF // This stored the texture info +OBJECT=16384 #0x4000 // This stores the faces, vertices, etc... + +#>------ sub defines of MATERIAL +MATNAME = int("0xA000",16); # This holds the material name +MATAMBIENT = int("0xA010",16); # Ambient color of the object/material +MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material +MATSPECULAR = int("0xA030",16); # SPecular color of the object/material +MATSHINESS = int("0xA040",16); # ?? +MATMAP = int("0xA200",16); # This is a header for a new material +MATMAPFILE = int("0xA300",16); # This holds the file name of the texture + +RGB1= int("0x0011",16) +RGB2= int("0x0012",16) + +#>------ sub defines of OBJECT +OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object +OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object +OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object + +#>------ sub defines of CAMERA +OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values + +#>------ sub defines of OBJECT_MESH +OBJECT_VERTICES = int("0x4110",16); # The objects vertices +OBJECT_FACES = int("0x4120",16); # The objects faces +OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color +OBJECT_UV = int("0x4140",16); # The UV texture coordinates +OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix + +#>------ sub defines of KFDATA +KFDATA_KFHDR = int("0xB00A",16); +KFDATA_KFSEG = int("0xB008",16); +KFDATA_KFCURTIME = int("0xB009",16); +KFDATA_OBJECT_NODE_TAG = int("0xB002",16); + +#>------ sub defines of OBJECT_NODE_TAG +OBJECT_NODE_ID = int("0xB030",16); +OBJECT_NODE_HDR = int("0xB010",16); +OBJECT_PIVOT = int("0xB013",16); +OBJECT_INSTANCE_NAME = int("0xB011",16); +POS_TRACK_TAG = int("0xB020",16); +ROT_TRACK_TAG = int("0xB021",16); +SCL_TRACK_TAG = int("0xB022",16); + +def uv_key(uv): + return round(uv[0], 6), round(uv[1], 6) +# return round(uv.x, 6), round(uv.y, 6) + +# size defines: +SZ_SHORT = 2 +SZ_INT = 4 +SZ_FLOAT = 4 + +class _3ds_short(object): + '''Class representing a short (2-byte integer) for a 3ds file. + *** This looks like an unsigned short H is unsigned from the struct docs - Cam***''' + __slots__ = 'value' + def __init__(self, val=0): + self.value=val + + def get_size(self): + return SZ_SHORT + + def write(self,file): + file.write(struct.pack("= mat_ls_len: + mat_index = f.mat = 0 + mat = mat_ls[mat_index] + if mat: mat_name = mat.name + else: mat_name = None + # else there alredy set to none + + img = uf.image +# img = f.image + if img: img_name = img.name + else: img_name = None + + materialDict.setdefault((mat_name, img_name), (mat, img) ) + + + else: + for mat in mat_ls: + if mat: # material may be None so check its not. + materialDict.setdefault((mat.name, None), (mat, None) ) + + # Why 0 Why! + for f in data.faces: + if f.material_index >= mat_ls_len: +# if f.mat >= mat_ls_len: + f.material_index = 0 + # f.mat = 0 + + if free: + free_derived_objects(ob) + + + # Make material chunks for all materials used in the meshes: + for mat_and_image in materialDict.values(): + object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1])) + + # Give all objects a unique ID and build a dictionary from object name to object id: + """ + name_to_id = {} + for ob, data in mesh_objects: + name_to_id[ob.name]= len(name_to_id) + #for ob in empty_objects: + # name_to_id[ob.name]= len(name_to_id) + """ + + # Create object chunks for all meshes: + i = 0 + for ob, blender_mesh in mesh_objects: + # create a new object chunk + object_chunk = _3ds_chunk(OBJECT) + + # set the object name + object_chunk.add_variable("name", _3ds_string(sane_name(ob.name))) + + # make a mesh chunk out of the mesh: + object_chunk.add_subchunk(make_mesh_chunk(blender_mesh, materialDict)) + object_info.add_subchunk(object_chunk) + + ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX + # make a kf object node for the object: + kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) + ''' +# if not blender_mesh.users: + bpy.data.remove_mesh(blender_mesh) +# blender_mesh.verts = None + + i+=i + + # Create chunks for all empties: + ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX + for ob in empty_objects: + # Empties only require a kf object node: + kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id)) + pass + ''' + + # Add main object info chunk to primary chunk: + primary.add_subchunk(object_info) + + ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX + # Add main keyframe data chunk to primary chunk: + primary.add_subchunk(kfdata) + ''' + + # At this point, the chunk hierarchy is completely built. + + # Check the size: + primary.get_size() + # Open the file for writing: + file = open( filename, 'wb' ) + + # Recursively write the chunks to file: + primary.write(file) + + # Close the file: + file.close() + + # Debugging only: report the exporting time: +# Blender.Window.WaitCursor(0) + print("3ds export time: %.2f" % (time.clock() - time1)) +# print("3ds export time: %.2f" % (Blender.sys.time() - time1)) + + # Debugging only: dump the chunk hierarchy: + #primary.dump() + + +# if __name__=='__main__': +# if struct: +# Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) +# else: +# Blender.Draw.PupMenu("Error%t|This script requires a full python installation") +# # save_3ds('/test_b.3ds') + +class EXPORT_OT_3ds(bpy.types.Operator): + ''' + 3DS Exporter + ''' + __idname__ = "export.3ds" + __label__ = 'Export 3DS' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""), + ] + + def execute(self, context): + save_3ds(self.filename, context) + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + def poll(self, context): # Poll isnt working yet + print("Poll") + return context.active_object != None + +bpy.ops.add(EXPORT_OT_3ds) diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py new file mode 100644 index 00000000000..aa65473b8d6 --- /dev/null +++ b/release/scripts/io/export_fbx.py @@ -0,0 +1,3457 @@ +#!BPY +""" +Name: 'Autodesk FBX (.fbx)...' +Blender: 249 +Group: 'Export' +Tooltip: 'Selection to an ASCII Autodesk FBX ' +""" +__author__ = "Campbell Barton" +__url__ = ['www.blender.org', 'blenderartists.org'] +__version__ = "1.2" + +__bpydoc__ = """\ +This script is an exporter to the FBX file format. + +http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx +""" +# -------------------------------------------------------------------------- +# FBX Export v0.1 by Campbell Barton (AKA Ideasman) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +import os +import time +import math # math.pi +import shutil # for file copying + +# try: +# import time +# # import os # only needed for batch export, nbot used yet +# except: +# time = None # use this to check if they have python modules installed + +# for python 2.3 support +try: + set() +except: + try: + from sets import Set as set + except: + set = None # so it complains you dont have a ! + +# # os is only needed for batch 'own dir' option +# try: +# import os +# except: +# os = None + +# import Blender +import bpy +import Mathutils +# from Blender.Mathutils import Matrix, Vector, RotationMatrix + +# import BPyObject +# import BPyMesh +# import BPySys +# import BPyMessages + +## This was used to make V, but faster not to do all that +##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' +##v = range(255) +##for c in valid: v.remove(ord(c)) +v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,47,58,59,60,61,62,63,64,92,94,96,124,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] +invalid = ''.join([chr(i) for i in v]) +def cleanName(name): + for ch in invalid: name = name.replace(ch, '_') + return name +# del v, i + + +def copy_file(source, dest): + file = open(source, 'rb') + data = file.read() + file.close() + + file = open(dest, 'wb') + file.write(data) + file.close() + + +# XXX not used anymore, images are copied one at a time +def copy_images(dest_dir, textures): + if not dest_dir.endswith(os.sep): + dest_dir += os.sep + + image_paths = set() + for tex in textures: + image_paths.add(Blender.sys.expandpath(tex.filename)) + + # Now copy images + copyCount = 0 + for image_path in image_paths: + if Blender.sys.exists(image_path): + # Make a name for the target path. + dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] + if not Blender.sys.exists(dest_image_path): # Image isnt alredy there + print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) + try: + copy_file(image_path, dest_image_path) + copyCount+=1 + except: + print('\t\tWarning, file failed to copy, skipping.') + + print('\tCopied %d images' % copyCount) + +# I guess FBX uses degrees instead of radians (Arystan). +# Call this function just before writing to FBX. +def eulerRadToDeg(eul): + ret = Mathutils.Euler() + + ret.x = 180 / math.pi * eul[0] + ret.y = 180 / math.pi * eul[1] + ret.z = 180 / math.pi * eul[2] + + return ret + +mtx4_identity = Mathutils.Matrix() + +# testing +mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used +#mtx_x90n = RotationMatrix(-90, 3, 'x') +#mtx_y90 = RotationMatrix( 90, 3, 'y') +#mtx_y90n = RotationMatrix(-90, 3, 'y') +#mtx_z90 = RotationMatrix( 90, 3, 'z') +#mtx_z90n = RotationMatrix(-90, 3, 'z') + +#mtx4_x90 = RotationMatrix( 90, 4, 'x') +mtx4_x90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'x') # used +#mtx4_y90 = RotationMatrix( 90, 4, 'y') +mtx4_y90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'y') # used +mtx4_z90 = Mathutils.RotationMatrix( math.pi/2, 4, 'z') # used +mtx4_z90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'z') # used + +# def strip_path(p): +# return p.split('\\')[-1].split('/')[-1] + +# Used to add the scene name into the filename without using odd chars +sane_name_mapping_ob = {} +sane_name_mapping_mat = {} +sane_name_mapping_tex = {} +sane_name_mapping_take = {} +sane_name_mapping_group = {} + +# Make sure reserved names are not used +sane_name_mapping_ob['Scene'] = 'Scene_' +sane_name_mapping_ob['blend_root'] = 'blend_root_' + +def increment_string(t): + name = t + num = '' + while name and name[-1].isdigit(): + num = name[-1] + num + name = name[:-1] + if num: return '%s%d' % (name, int(num)+1) + else: return name + '_0' + + + +# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up. +def sane_name(data, dct): + #if not data: return None + + if type(data)==tuple: # materials are paired up with images + data, other = data + use_other = True + else: + other = None + use_other = False + + if data: name = data.name + else: name = None + orig_name = name + + if other: + orig_name_other = other.name + name = '%s #%s' % (name, orig_name_other) + else: + orig_name_other = None + + # dont cache, only ever call once for each data type now, + # so as to avoid namespace collision between types - like with objects <-> bones + #try: return dct[name] + #except: pass + + if not name: + name = 'unnamed' # blank string, ASKING FOR TROUBLE! + else: + #name = BPySys.cleanName(name) + name = cleanName(name) # use our own + + while name in iter(dct.values()): name = increment_string(name) + + if use_other: # even if other is None - orig_name_other will be a string or None + dct[orig_name, orig_name_other] = name + else: + dct[orig_name] = name + + return name + +def sane_obname(data): return sane_name(data, sane_name_mapping_ob) +def sane_matname(data): return sane_name(data, sane_name_mapping_mat) +def sane_texname(data): return sane_name(data, sane_name_mapping_tex) +def sane_takename(data): return sane_name(data, sane_name_mapping_take) +def sane_groupname(data): return sane_name(data, sane_name_mapping_group) + +# def derived_paths(fname_orig, basepath, FORCE_CWD=False): +# ''' +# fname_orig - blender path, can be relative +# basepath - fname_rel will be relative to this +# FORCE_CWD - dont use the basepath, just add a ./ to the filename. +# use when we know the file will be in the basepath. +# ''' +# fname = bpy.sys.expandpath(fname_orig) +# # fname = Blender.sys.expandpath(fname_orig) +# fname_strip = os.path.basename(fname) +# # fname_strip = strip_path(fname) +# if FORCE_CWD: +# fname_rel = '.' + os.sep + fname_strip +# else: +# fname_rel = bpy.sys.relpath(fname, basepath) +# # fname_rel = Blender.sys.relpath(fname, basepath) +# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:] +# return fname, fname_strip, fname_rel + + +def mat4x4str(mat): + return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ]) + +# XXX not used +# duplicated in OBJ exporter +def getVertsFromGroup(me, group_index): + ret = [] + + for i, v in enumerate(me.verts): + for g in v.groups: + if g.group == group_index: + ret.append((i, g.weight)) + + return ret + +# ob must be OB_MESH +def BPyMesh_meshWeight2List(ob): + ''' Takes a mesh and return its group names and a list of lists, one list per vertex. + aligning the each vert list with the group names, each list contains float value for the weight. + These 2 lists can be modified and then used with list2MeshWeight to apply the changes. + ''' + + me = ob.data + + # Clear the vert group. + groupNames= [g.name for g in ob.vertex_groups] + len_groupNames= len(groupNames) + + if not len_groupNames: + # no verts? return a vert aligned empty list + return [[] for i in range(len(me.verts))], [] + else: + vWeightList= [[0.0]*len_groupNames for i in range(len(me.verts))] + + for i, v in enumerate(me.verts): + for g in v.groups: + vWeightList[i][g.group] = g.weight + + return groupNames, vWeightList + +def meshNormalizedWeights(me): + try: # account for old bad BPyMesh + groupNames, vWeightList = BPyMesh_meshWeight2List(me) +# groupNames, vWeightList = BPyMesh.meshWeight2List(me) + except: + return [],[] + + if not groupNames: + return [],[] + + for i, vWeights in enumerate(vWeightList): + tot = 0.0 + for w in vWeights: + tot+=w + + if tot: + for j, w in enumerate(vWeights): + vWeights[j] = w/tot + + return groupNames, vWeightList + +header_comment = \ +'''; FBX 6.1.0 project file +; Created by Blender FBX Exporter +; for support mail: ideasman42@gmail.com +; ---------------------------------------------------- + +''' + +# This func can be called with just the filename +def write(filename, batch_objects = None, \ + context = None, + EXP_OBS_SELECTED = True, + EXP_MESH = True, + EXP_MESH_APPLY_MOD = True, +# EXP_MESH_HQ_NORMALS = False, + EXP_ARMATURE = True, + EXP_LAMP = True, + EXP_CAMERA = True, + EXP_EMPTY = True, + EXP_IMAGE_COPY = False, + GLOBAL_MATRIX = Mathutils.Matrix(), + ANIM_ENABLE = True, + ANIM_OPTIMIZE = True, + ANIM_OPTIMIZE_PRECISSION = 6, + ANIM_ACTION_ALL = False, + BATCH_ENABLE = False, + BATCH_GROUP = True, + BATCH_FILE_PREFIX = '', + BATCH_OWN_DIR = False + ): + + # ----------------- Batch support! + if BATCH_ENABLE: + if os == None: BATCH_OWN_DIR = False + + fbxpath = filename + + # get the path component of filename + tmp_exists = bpy.sys.exists(fbxpath) +# tmp_exists = Blender.sys.exists(fbxpath) + + if tmp_exists != 2: # a file, we want a path + fbxpath = os.path.dirname(fbxpath) +# while fbxpath and fbxpath[-1] not in ('/', '\\'): +# fbxpath = fbxpath[:-1] + if not fbxpath: +# if not filename: + # XXX + print('Error%t|Directory does not exist!') +# Draw.PupMenu('Error%t|Directory does not exist!') + return + + tmp_exists = bpy.sys.exists(fbxpath) +# tmp_exists = Blender.sys.exists(fbxpath) + + if tmp_exists != 2: + # XXX + print('Error%t|Directory does not exist!') +# Draw.PupMenu('Error%t|Directory does not exist!') + return + + if not fbxpath.endswith(os.sep): + fbxpath += os.sep + del tmp_exists + + + if BATCH_GROUP: + data_seq = bpy.data.groups + else: + data_seq = bpy.data.scenes + + # call this function within a loop with BATCH_ENABLE == False + orig_sce = context.scene +# orig_sce = bpy.data.scenes.active + + + new_fbxpath = fbxpath # own dir option modifies, we need to keep an original + for data in data_seq: # scene or group + newname = BATCH_FILE_PREFIX + cleanName(data.name) +# newname = BATCH_FILE_PREFIX + BPySys.cleanName(data.name) + + + if BATCH_OWN_DIR: + new_fbxpath = fbxpath + newname + os.sep + # path may alredy exist + # TODO - might exist but be a file. unlikely but should probably account for it. + + if bpy.sys.exists(new_fbxpath) == 0: +# if Blender.sys.exists(new_fbxpath) == 0: + os.mkdir(new_fbxpath) + + + filename = new_fbxpath + newname + '.fbx' + + print('\nBatch exporting %s as...\n\t"%s"' % (data, filename)) + + # XXX don't know what to do with this, probably do the same? (Arystan) + if BATCH_GROUP: #group + # group, so objects update properly, add a dummy scene. + sce = bpy.data.scenes.new() + sce.Layers = (1<<20) -1 + bpy.data.scenes.active = sce + for ob_base in data.objects: + sce.objects.link(ob_base) + + sce.update(1) + + # TODO - BUMMER! Armatures not in the group wont animate the mesh + + else:# scene + + + data_seq.active = data + + + # Call self with modified args + # Dont pass batch options since we alredy usedt them + write(filename, data.objects, + context, + False, + EXP_MESH, + EXP_MESH_APPLY_MOD, +# EXP_MESH_HQ_NORMALS, + EXP_ARMATURE, + EXP_LAMP, + EXP_CAMERA, + EXP_EMPTY, + EXP_IMAGE_COPY, + GLOBAL_MATRIX, + ANIM_ENABLE, + ANIM_OPTIMIZE, + ANIM_OPTIMIZE_PRECISSION, + ANIM_ACTION_ALL + ) + + if BATCH_GROUP: + # remove temp group scene + bpy.data.remove_scene(sce) +# bpy.data.scenes.unlink(sce) + + bpy.data.scenes.active = orig_sce + + return # so the script wont run after we have batch exported. + + # end batch support + + # Use this for working out paths relative to the export location + basepath = os.path.dirname(filename) or '.' + basepath += os.sep +# basepath = Blender.sys.dirname(filename) + + # ---------------------------------------------- + # storage classes + class my_bone_class: + __slots__ =(\ + 'blenName',\ + 'blenBone',\ + 'blenMeshes',\ + 'restMatrix',\ + 'parent',\ + 'blenName',\ + 'fbxName',\ + 'fbxArm',\ + '__pose_bone',\ + '__anim_poselist') + + def __init__(self, blenBone, fbxArm): + + # This is so 2 armatures dont have naming conflicts since FBX bones use object namespace + self.fbxName = sane_obname(blenBone) + + self.blenName = blenBone.name + self.blenBone = blenBone + self.blenMeshes = {} # fbxMeshObName : mesh + self.fbxArm = fbxArm + self.restMatrix = blenBone.armature_matrix +# self.restMatrix = blenBone.matrix['ARMATURESPACE'] + + # not used yet + # self.restMatrixInv = self.restMatrix.copy().invert() + # self.restMatrixLocal = None # set later, need parent matrix + + self.parent = None + + # not public + pose = fbxArm.blenObject.pose +# pose = fbxArm.blenObject.getPose() + self.__pose_bone = pose.pose_channels[self.blenName] +# self.__pose_bone = pose.bones[self.blenName] + + # store a list if matricies here, (poseMatrix, head, tail) + # {frame:posematrix, frame:posematrix, ...} + self.__anim_poselist = {} + + ''' + def calcRestMatrixLocal(self): + if self.parent: + self.restMatrixLocal = self.restMatrix * self.parent.restMatrix.copy().invert() + else: + self.restMatrixLocal = self.restMatrix.copy() + ''' + def setPoseFrame(self, f): + # cache pose info here, frame must be set beforehand + + # Didnt end up needing head or tail, if we do - here it is. + ''' + self.__anim_poselist[f] = (\ + self.__pose_bone.poseMatrix.copy(),\ + self.__pose_bone.head.copy(),\ + self.__pose_bone.tail.copy() ) + ''' + + self.__anim_poselist[f] = self.__pose_bone.pose_matrix.copy() +# self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy() + + # get pose from frame. + def getPoseMatrix(self, f):# ---------------------------------------------- + return self.__anim_poselist[f] + ''' + def getPoseHead(self, f): + #return self.__pose_bone.head.copy() + return self.__anim_poselist[f][1].copy() + def getPoseTail(self, f): + #return self.__pose_bone.tail.copy() + return self.__anim_poselist[f][2].copy() + ''' + # end + + def getAnimParRelMatrix(self, frame): + #arm_mat = self.fbxArm.matrixWorld + #arm_mat = self.fbxArm.parRelMatrix() + if not self.parent: + #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore + return mtx4_z90 * self.getPoseMatrix(frame) + else: + #return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat))) * (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert() + return (mtx4_z90 * (self.getPoseMatrix(frame))) * (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert() + + # we need thes because cameras and lights modified rotations + def getAnimParRelMatrixRot(self, frame): + return self.getAnimParRelMatrix(frame) + + def flushAnimData(self): + self.__anim_poselist.clear() + + + class my_object_generic: + # Other settings can be applied for each type - mesh, armature etc. + def __init__(self, ob, matrixWorld = None): + self.fbxName = sane_obname(ob) + self.blenObject = ob + self.fbxGroupNames = [] + self.fbxParent = None # set later on IF the parent is in the selection. + if matrixWorld: self.matrixWorld = matrixWorld * GLOBAL_MATRIX + else: self.matrixWorld = ob.matrix * GLOBAL_MATRIX +# else: self.matrixWorld = ob.matrixWorld * GLOBAL_MATRIX + self.__anim_poselist = {} # we should only access this + + def parRelMatrix(self): + if self.fbxParent: + return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert() + else: + return self.matrixWorld + + def setPoseFrame(self, f): + self.__anim_poselist[f] = self.blenObject.matrix.copy() +# self.__anim_poselist[f] = self.blenObject.matrixWorld.copy() + + def getAnimParRelMatrix(self, frame): + if self.fbxParent: + #return (self.__anim_poselist[frame] * self.fbxParent.__anim_poselist[frame].copy().invert() ) * GLOBAL_MATRIX + return (self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert() + else: + return self.__anim_poselist[frame] * GLOBAL_MATRIX + + def getAnimParRelMatrixRot(self, frame): + type = self.blenObject.type + if self.fbxParent: + matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart() + else: + matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart() + + # Lamps need to be rotated + if type =='LAMP': + matrix_rot = mtx_x90 * matrix_rot + elif type =='CAMERA': +# elif ob and type =='Camera': + y = Mathutils.Vector(0,1,0) * matrix_rot + matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) + + return matrix_rot + + # ---------------------------------------------- + + + + + + print('\nFBX export starting...', filename) + start_time = time.clock() +# start_time = Blender.sys.time() + try: + file = open(filename, 'w') + except: + return False + + sce = context.scene +# sce = bpy.data.scenes.active + world = sce.world + + + # ---------------------------- Write the header first + file.write(header_comment) + if time: + curtime = time.localtime()[0:6] + else: + curtime = (0,0,0,0,0,0) + # + file.write(\ +'''FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 6100 + CreationTimeStamp: { + Version: 1000 + Year: %.4i + Month: %.2i + Day: %.2i + Hour: %.2i + Minute: %.2i + Second: %.2i + Millisecond: 0 + } + Creator: "FBX SDK/FBX Plugins build 20070228" + OtherFlags: { + FlagPLE: 0 + } +}''' % (curtime)) + + file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime) + file.write('\nCreator: "Blender3D version 2.5"') +# file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version')) + + pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way + + # --------------- funcs for exporting + def object_tx(ob, loc, matrix, matrix_mod = None): + ''' + Matrix mod is so armature objects can modify their bone matricies + ''' + if isinstance(ob, bpy.types.Bone): +# if isinstance(ob, Blender.Types.BoneType): + + # we know we have a matrix + # matrix = mtx4_z90 * (ob.matrix['ARMATURESPACE'] * matrix_mod) + matrix = mtx4_z90 * ob.armature_matrix # dont apply armature matrix anymore +# matrix = mtx4_z90 * ob.matrix['ARMATURESPACE'] # dont apply armature matrix anymore + + parent = ob.parent + if parent: + #par_matrix = mtx4_z90 * (parent.matrix['ARMATURESPACE'] * matrix_mod) + par_matrix = mtx4_z90 * parent.armature_matrix # dont apply armature matrix anymore +# par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore + matrix = matrix * par_matrix.copy().invert() + + matrix_rot = matrix.rotationPart() + + loc = tuple(matrix.translationPart()) + scale = tuple(matrix.scalePart()) + rot = tuple(matrix_rot.toEuler()) + + else: + # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore + #if ob and not matrix: matrix = ob.matrixWorld * GLOBAL_MATRIX + if ob and not matrix: raise Exception("error: this should never happen!") + + matrix_rot = matrix + #if matrix: + # matrix = matrix_scale * matrix + + if matrix: + loc = tuple(matrix.translationPart()) + scale = tuple(matrix.scalePart()) + + matrix_rot = matrix.rotationPart() + # Lamps need to be rotated + if ob and ob.type =='Lamp': + matrix_rot = mtx_x90 * matrix_rot + rot = tuple(matrix_rot.toEuler()) + elif ob and ob.type =='Camera': + y = Mathutils.Vector(0,1,0) * matrix_rot + matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y) + rot = tuple(matrix_rot.toEuler()) + else: + rot = tuple(matrix_rot.toEuler()) + else: + if not loc: + loc = 0,0,0 + scale = 1,1,1 + rot = 0,0,0 + + return loc, rot, scale, matrix, matrix_rot + + def write_object_tx(ob, loc, matrix, matrix_mod= None): + ''' + We have loc to set the location if non blender objects that have a location + + matrix_mod is only used for bones at the moment + ''' + loc, rot, scale, matrix, matrix_rot = object_tx(ob, loc, matrix, matrix_mod) + + file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc) + file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % tuple(eulerRadToDeg(rot))) +# file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % rot) + file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale) + return loc, rot, scale, matrix, matrix_rot + + def write_object_props(ob=None, loc=None, matrix=None, matrix_mod=None): + # if the type is 0 its an empty otherwise its a mesh + # only difference at the moment is one has a color + file.write(''' + Properties60: { + Property: "QuaternionInterpolate", "bool", "",0 + Property: "Visibility", "Visibility", "A+",1''') + + loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix, matrix_mod) + + # Rotation order, note, for FBX files Iv loaded normal order is 1 + # setting to zero. + # eEULER_XYZ = 0 + # eEULER_XZY + # eEULER_YZX + # eEULER_YXZ + # eEULER_ZXY + # eEULER_ZYX + + file.write(''' + Property: "RotationOffset", "Vector3D", "",0,0,0 + Property: "RotationPivot", "Vector3D", "",0,0,0 + Property: "ScalingOffset", "Vector3D", "",0,0,0 + Property: "ScalingPivot", "Vector3D", "",0,0,0 + Property: "TranslationActive", "bool", "",0 + Property: "TranslationMin", "Vector3D", "",0,0,0 + Property: "TranslationMax", "Vector3D", "",0,0,0 + Property: "TranslationMinX", "bool", "",0 + Property: "TranslationMinY", "bool", "",0 + Property: "TranslationMinZ", "bool", "",0 + Property: "TranslationMaxX", "bool", "",0 + Property: "TranslationMaxY", "bool", "",0 + Property: "TranslationMaxZ", "bool", "",0 + Property: "RotationOrder", "enum", "",0 + Property: "RotationSpaceForLimitOnly", "bool", "",0 + Property: "AxisLen", "double", "",10 + Property: "PreRotation", "Vector3D", "",0,0,0 + Property: "PostRotation", "Vector3D", "",0,0,0 + Property: "RotationActive", "bool", "",0 + Property: "RotationMin", "Vector3D", "",0,0,0 + Property: "RotationMax", "Vector3D", "",0,0,0 + Property: "RotationMinX", "bool", "",0 + Property: "RotationMinY", "bool", "",0 + Property: "RotationMinZ", "bool", "",0 + Property: "RotationMaxX", "bool", "",0 + Property: "RotationMaxY", "bool", "",0 + Property: "RotationMaxZ", "bool", "",0 + Property: "RotationStiffnessX", "double", "",0 + Property: "RotationStiffnessY", "double", "",0 + Property: "RotationStiffnessZ", "double", "",0 + Property: "MinDampRangeX", "double", "",0 + Property: "MinDampRangeY", "double", "",0 + Property: "MinDampRangeZ", "double", "",0 + Property: "MaxDampRangeX", "double", "",0 + Property: "MaxDampRangeY", "double", "",0 + Property: "MaxDampRangeZ", "double", "",0 + Property: "MinDampStrengthX", "double", "",0 + Property: "MinDampStrengthY", "double", "",0 + Property: "MinDampStrengthZ", "double", "",0 + Property: "MaxDampStrengthX", "double", "",0 + Property: "MaxDampStrengthY", "double", "",0 + Property: "MaxDampStrengthZ", "double", "",0 + Property: "PreferedAngleX", "double", "",0 + Property: "PreferedAngleY", "double", "",0 + Property: "PreferedAngleZ", "double", "",0 + Property: "InheritType", "enum", "",0 + Property: "ScalingActive", "bool", "",0 + Property: "ScalingMin", "Vector3D", "",1,1,1 + Property: "ScalingMax", "Vector3D", "",1,1,1 + Property: "ScalingMinX", "bool", "",0 + Property: "ScalingMinY", "bool", "",0 + Property: "ScalingMinZ", "bool", "",0 + Property: "ScalingMaxX", "bool", "",0 + Property: "ScalingMaxY", "bool", "",0 + Property: "ScalingMaxZ", "bool", "",0 + Property: "GeometricTranslation", "Vector3D", "",0,0,0 + Property: "GeometricRotation", "Vector3D", "",0,0,0 + Property: "GeometricScaling", "Vector3D", "",1,1,1 + Property: "LookAtProperty", "object", "" + Property: "UpVectorProperty", "object", "" + Property: "Show", "bool", "",1 + Property: "NegativePercentShapeSupport", "bool", "",1 + Property: "DefaultAttributeIndex", "int", "",0''') + if ob and not isinstance(ob, bpy.types.Bone): +# if ob and type(ob) != Blender.Types.BoneType: + # Only mesh objects have color + file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') + file.write('\n\t\t\tProperty: "Size", "double", "",100') + file.write('\n\t\t\tProperty: "Look", "enum", "",1') + + return loc, rot, scale, matrix, matrix_rot + + + # -------------------------------------------- Armatures + #def write_bone(bone, name, matrix_mod): + def write_bone(my_bone): + file.write('\n\tModel: "Model::%s", "Limb" {' % my_bone.fbxName) + file.write('\n\t\tVersion: 232') + + #poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.parRelMatrix())[3] + poseMatrix = write_object_props(my_bone.blenBone)[3] # dont apply bone matricies anymore + pose_items.append( (my_bone.fbxName, poseMatrix) ) + + + # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) + file.write('\n\t\t\tProperty: "Size", "double", "",1') + + #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.tail['ARMATURESPACE'] * my_bone.fbxArm.parRelMatrix())).length) + + """ + file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' %\ + ((my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length) + """ + + file.write('\n\t\t\tProperty: "LimbLength", "double", "",%.6f' % + (my_bone.blenBone.armature_head - my_bone.blenBone.armature_tail).length) +# (my_bone.blenBone.head['ARMATURESPACE'] - my_bone.blenBone.tail['ARMATURESPACE']).length) + + #file.write('\n\t\t\tProperty: "LimbLength", "double", "",1') + file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8') + file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 1') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Skeleton"') + file.write('\n\t}') + + def write_camera_switch(): + file.write(''' + Model: "Model::Camera Switcher", "CameraSwitcher" { + Version: 232''') + + write_object_props() + file.write(''' + Property: "Color", "Color", "A",0.8,0.8,0.8 + Property: "Camera Index", "Integer", "A+",100 + } + MultiLayer: 0 + MultiTake: 1 + Hidden: "True" + Shading: W + Culling: "CullingOff" + Version: 101 + Name: "Model::Camera Switcher" + CameraId: 0 + CameraName: 100 + CameraIndexName: + }''') + + def write_camera_dummy(name, loc, near, far, proj_type, up): + file.write('\n\tModel: "Model::%s", "Camera" {' % name ) + file.write('\n\t\tVersion: 232') + write_object_props(None, loc) + + file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8') + file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') + file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",40') + file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",0') + file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",0') + file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0.63,0.63,0.63') + file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') + file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') + file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') + file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') + file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') + file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') + file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') + file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",21.3544940948486') + file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') + file.write('\n\t\t\tProperty: "AspectW", "double", "",320') + file.write('\n\t\t\tProperty: "AspectH", "double", "",200') + file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",1') + file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') + file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') + file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') + file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % near) + file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % far) + file.write('\n\t\t\tProperty: "FilmWidth", "double", "",0.816') + file.write('\n\t\t\tProperty: "FilmHeight", "double", "",0.612') + file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",1.33333333333333') + file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') + file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",4') + file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') + file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') + file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') + file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') + file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') + file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') + file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') + file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') + file.write('\n\t\t\tProperty: "Crop", "bool", "",0') + file.write('\n\t\t\tProperty: "Center", "bool", "",1') + file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') + file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') + file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') + file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') + file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') + file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') + file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",1.33333333333333') + file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') + file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') + file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') + file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') + file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",%i' % proj_type) + file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') + file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') + file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') + file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') + file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') + file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') + file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') + file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 0') + file.write('\n\t\tHidden: "True"') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Camera"') + file.write('\n\t\tGeometryVersion: 124') + file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) + file.write('\n\t\tUp: %i,%i,%i' % up) + file.write('\n\t\tLookAt: 0,0,0') + file.write('\n\t\tShowInfoOnMoving: 1') + file.write('\n\t\tShowAudio: 0') + file.write('\n\t\tAudioColor: 0,1,0') + file.write('\n\t\tCameraOrthoZoom: 1') + file.write('\n\t}') + + def write_camera_default(): + # This sucks but to match FBX converter its easier to + # write the cameras though they are not needed. + write_camera_dummy('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0)) + write_camera_dummy('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1)) + write_camera_dummy('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1)) + write_camera_dummy('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0)) + write_camera_dummy('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0)) + write_camera_dummy('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0)) + write_camera_dummy('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0)) + + def write_camera(my_cam): + ''' + Write a blender camera + ''' + render = sce.render_data + width = render.resolution_x + height = render.resolution_y +# render = sce.render +# width = render.sizeX +# height = render.sizeY + aspect = float(width)/height + + data = my_cam.blenObject.data + + file.write('\n\tModel: "Model::%s", "Camera" {' % my_cam.fbxName ) + file.write('\n\t\tVersion: 232') + loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject, None, my_cam.parRelMatrix()) + + file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0') + file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle) + file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1') + file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026') + file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shift_x) # not sure if this is in the correct units? +# file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units? + file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shift_y) # ditto +# file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto + file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0') + file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0') + file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1') + file.write('\n\t\t\tProperty: "Motion Blur Intensity", "Real", "A+",1') + file.write('\n\t\t\tProperty: "UseMotionBlur", "bool", "",0') + file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1') + file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2') + file.write('\n\t\t\tProperty: "GateFit", "enum", "",0') + file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0') + file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width) + file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height) + + '''Camera aspect ratio modes. + 0 If the ratio mode is eWINDOW_SIZE, both width and height values aren't relevant. + 1 If the ratio mode is eFIXED_RATIO, the height value is set to 1.0 and the width value is relative to the height value. + 2 If the ratio mode is eFIXED_RESOLUTION, both width and height values are in pixels. + 3 If the ratio mode is eFIXED_WIDTH, the width value is in pixels and the height value is relative to the width value. + 4 If the ratio mode is eFIXED_HEIGHT, the height value is in pixels and the width value is relative to the height value. + + Definition at line 234 of file kfbxcamera.h. ''' + + file.write('\n\t\t\tProperty: "PixelAspectRatio", "double", "",2') + + file.write('\n\t\t\tProperty: "UseFrameColor", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameColor", "ColorRGB", "",0.3,0.3,0.3') + file.write('\n\t\t\tProperty: "ShowName", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowGrid", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowOpticalCenter", "bool", "",0') + file.write('\n\t\t\tProperty: "ShowAzimut", "bool", "",1') + file.write('\n\t\t\tProperty: "ShowTimeCode", "bool", "",0') + file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clip_start) +# file.write('\n\t\t\tProperty: "NearPlane", "double", "",%.6f' % data.clipStart) + file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clip_end) +# file.write('\n\t\t\tProperty: "FarPlane", "double", "",%.6f' % data.clipStart) + file.write('\n\t\t\tProperty: "FilmWidth", "double", "",1.0') + file.write('\n\t\t\tProperty: "FilmHeight", "double", "",1.0') + file.write('\n\t\t\tProperty: "FilmAspectRatio", "double", "",%.6f' % aspect) + file.write('\n\t\t\tProperty: "FilmSqueezeRatio", "double", "",1') + file.write('\n\t\t\tProperty: "FilmFormatIndex", "enum", "",0') + file.write('\n\t\t\tProperty: "ViewFrustum", "bool", "",1') + file.write('\n\t\t\tProperty: "ViewFrustumNearFarPlane", "bool", "",0') + file.write('\n\t\t\tProperty: "ViewFrustumBackPlaneMode", "enum", "",2') + file.write('\n\t\t\tProperty: "BackPlaneDistance", "double", "",100') + file.write('\n\t\t\tProperty: "BackPlaneDistanceMode", "enum", "",0') + file.write('\n\t\t\tProperty: "ViewCameraToLookAt", "bool", "",1') + file.write('\n\t\t\tProperty: "LockMode", "bool", "",0') + file.write('\n\t\t\tProperty: "LockInterestNavigation", "bool", "",0') + file.write('\n\t\t\tProperty: "FitImage", "bool", "",0') + file.write('\n\t\t\tProperty: "Crop", "bool", "",0') + file.write('\n\t\t\tProperty: "Center", "bool", "",1') + file.write('\n\t\t\tProperty: "KeepRatio", "bool", "",1') + file.write('\n\t\t\tProperty: "BackgroundMode", "enum", "",0') + file.write('\n\t\t\tProperty: "BackgroundAlphaTreshold", "double", "",0.5') + file.write('\n\t\t\tProperty: "ForegroundTransparent", "bool", "",1') + file.write('\n\t\t\tProperty: "DisplaySafeArea", "bool", "",0') + file.write('\n\t\t\tProperty: "SafeAreaDisplayStyle", "enum", "",1') + file.write('\n\t\t\tProperty: "SafeAreaAspectRatio", "double", "",%.6f' % aspect) + file.write('\n\t\t\tProperty: "Use2DMagnifierZoom", "bool", "",0') + file.write('\n\t\t\tProperty: "2D Magnifier Zoom", "Real", "A+",100') + file.write('\n\t\t\tProperty: "2D Magnifier X", "Real", "A+",50') + file.write('\n\t\t\tProperty: "2D Magnifier Y", "Real", "A+",50') + file.write('\n\t\t\tProperty: "CameraProjectionType", "enum", "",0') + file.write('\n\t\t\tProperty: "UseRealTimeDOFAndAA", "bool", "",0') + file.write('\n\t\t\tProperty: "UseDepthOfField", "bool", "",0') + file.write('\n\t\t\tProperty: "FocusSource", "enum", "",0') + file.write('\n\t\t\tProperty: "FocusAngle", "double", "",3.5') + file.write('\n\t\t\tProperty: "FocusDistance", "double", "",200') + file.write('\n\t\t\tProperty: "UseAntialiasing", "bool", "",0') + file.write('\n\t\t\tProperty: "AntialiasingIntensity", "double", "",0.77777') + file.write('\n\t\t\tProperty: "UseAccumulationBuffer", "bool", "",0') + file.write('\n\t\t\tProperty: "FrameSamplingCount", "int", "",7') + + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 0') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Camera"') + file.write('\n\t\tGeometryVersion: 124') + file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc) + file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,1,0) * matrix_rot) ) + file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Mathutils.Vector(0,0,-1)*matrix_rot) ) + + #file.write('\n\t\tUp: 0,0,0' ) + #file.write('\n\t\tLookAt: 0,0,0' ) + + file.write('\n\t\tShowInfoOnMoving: 1') + file.write('\n\t\tShowAudio: 0') + file.write('\n\t\tAudioColor: 0,1,0') + file.write('\n\t\tCameraOrthoZoom: 1') + file.write('\n\t}') + + def write_light(my_light): + light = my_light.blenObject.data + file.write('\n\tModel: "Model::%s", "Light" {' % my_light.fbxName) + file.write('\n\t\tVersion: 232') + + write_object_props(my_light.blenObject, None, my_light.parRelMatrix()) + + # Why are these values here twice?????? - oh well, follow the holy sdk's output + + # Blender light types match FBX's, funny coincidence, we just need to + # be sure that all unsupported types are made into a point light + #ePOINT, + #eDIRECTIONAL + #eSPOT + light_type_items = {'POINT': 0, 'SUN': 1, 'SPOT': 2, 'HEMI': 3, 'AREA': 4} + light_type = light_type_items[light.type] +# light_type = light.type + if light_type > 2: light_type = 1 # hemi and area lights become directional + +# mode = light.mode + if light.shadow_method == 'RAY_SHADOW' or light.shadow_method == 'BUFFER_SHADOW': +# if mode & Blender.Lamp.Modes.RayShadow or mode & Blender.Lamp.Modes.Shadows: + do_shadow = 1 + else: + do_shadow = 0 + + if light.only_shadow or (not light.diffuse and not light.specular): +# if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular): + do_light = 0 + else: + do_light = 1 + + scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case + + file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) + file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') + file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') + file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1') + file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 + if light.type == 'SPOT': + file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spot_size * scale)) +# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) + file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') + file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.color)) +# file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col)) + file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy*100, 200))) # clamp below 200 +# + # duplication? see ^ (Arystan) +# file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % (light.spotSize * scale)) + file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50') + file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type) + file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light) + file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1') + file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0') + file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1') + file.write('\n\t\t\tProperty: "GoboProperty", "object", ""') + file.write('\n\t\t\tProperty: "DecayType", "enum", "",0') + file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.distance) +# file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist) + file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0') + file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0') + file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0') + file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0') + file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0') + file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0') + file.write('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow) + file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1') + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 0') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + file.write('\n\t\tTypeFlags: "Light"') + file.write('\n\t\tGeometryVersion: 124') + file.write('\n\t}') + + # matrixOnly is not used at the moment + def write_null(my_null = None, fbxName = None, matrixOnly = None): + # ob can be null + if not fbxName: fbxName = my_null.fbxName + + file.write('\n\tModel: "Model::%s", "Null" {' % fbxName) + file.write('\n\t\tVersion: 232') + + # only use this for the root matrix at the moment + if matrixOnly: + poseMatrix = write_object_props(None, None, matrixOnly)[3] + + else: # all other Null's + if my_null: poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3] + else: poseMatrix = write_object_props()[3] + + pose_items.append((fbxName, poseMatrix)) + + file.write(''' + } + MultiLayer: 0 + MultiTake: 1 + Shading: Y + Culling: "CullingOff" + TypeFlags: "Null" + }''') + + # Material Settings + if world: world_amb = tuple(world.ambient_color) +# if world: world_amb = world.getAmb() + else: world_amb = (0,0,0) # Default value + + def write_material(matname, mat): + file.write('\n\tMaterial: "Material::%s", "" {' % matname) + + # Todo, add more material Properties. + if mat: + mat_cold = tuple(mat.diffuse_color) +# mat_cold = tuple(mat.rgbCol) + mat_cols = tuple(mat.specular_color) +# mat_cols = tuple(mat.specCol) + #mat_colm = tuple(mat.mirCol) # we wont use the mirror color + mat_colamb = world_amb +# mat_colamb = tuple([c for c in world_amb]) + + mat_dif = mat.diffuse_reflection +# mat_dif = mat.ref + mat_amb = mat.ambient +# mat_amb = mat.amb + mat_hard = (float(mat.specular_hardness)-1)/5.10 +# mat_hard = (float(mat.hard)-1)/5.10 + mat_spec = mat.specular_reflection/2.0 +# mat_spec = mat.spec/2.0 + mat_alpha = mat.alpha + mat_emit = mat.emit + mat_shadeless = mat.shadeless +# mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS + if mat_shadeless: + mat_shader = 'Lambert' + else: + if mat.diffuse_shader == 'LAMBERT': +# if mat.diffuseShader == Blender.Material.Shaders.DIFFUSE_LAMBERT: + mat_shader = 'Lambert' + else: + mat_shader = 'Phong' + else: + mat_cols = mat_cold = 0.8, 0.8, 0.8 + mat_colamb = 0.0,0.0,0.0 + # mat_colm + mat_dif = 1.0 + mat_amb = 0.5 + mat_hard = 20.0 + mat_spec = 0.2 + mat_alpha = 1.0 + mat_emit = 0.0 + mat_shadeless = False + mat_shader = 'Phong' + + file.write('\n\t\tVersion: 102') + file.write('\n\t\tShadingModel: "%s"' % mat_shader.lower()) + file.write('\n\t\tMultiLayer: 0') + + file.write('\n\t\tProperties60: {') + file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader) + file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0') + file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender + file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit) + + file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb) + file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb) + file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) + file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif) + file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0') + file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1') + file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha)) + if not mat_shadeless: + file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols) + file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec) + file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0') + file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0') + file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1') + file.write('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0') + file.write('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb) + file.write('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold) + if not mat_shadeless: + file.write('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols) + file.write('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard) + file.write('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha) + if not mat_shadeless: + file.write('\n\t\t\tProperty: "Reflectivity", "double", "",0') + + file.write('\n\t\t}') + file.write('\n\t}') + + def copy_image(image): + + rel = image.get_export_path(basepath, True) + base = os.path.basename(rel) + + if EXP_IMAGE_COPY: + absp = image.get_export_path(basepath, False) + if not os.path.exists(absp): + shutil.copy(image.get_abs_filename(), absp) + + return (rel, base) + + # tex is an Image (Arystan) + def write_video(texname, tex): + # Same as texture really! + file.write('\n\tVideo: "Video::%s", "Clip" {' % texname) + + file.write(''' + Type: "Clip" + Properties60: { + Property: "FrameRate", "double", "",0 + Property: "LastFrame", "int", "",0 + Property: "Width", "int", "",0 + Property: "Height", "int", "",0''') + if tex: + fname_rel, fname_strip = copy_image(tex) +# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) + else: + fname = fname_strip = fname_rel = '' + + file.write('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip) + + + file.write(''' + Property: "StartFrame", "int", "",0 + Property: "StopFrame", "int", "",0 + Property: "PlaySpeed", "double", "",1 + Property: "Offset", "KTime", "",0 + Property: "InterlaceMode", "enum", "",0 + Property: "FreeRunning", "bool", "",0 + Property: "Loop", "bool", "",0 + Property: "AccessMode", "enum", "",0 + } + UseMipMap: 0''') + + file.write('\n\t\tFilename: "%s"' % fname_strip) + if fname_strip: fname_strip = '/' + fname_strip + file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # make relative + file.write('\n\t}') + + + def write_texture(texname, tex, num): + # if tex == None then this is a dummy tex + file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname) + file.write('\n\t\tType: "TextureVideoClip"') + file.write('\n\t\tVersion: 202') + # TODO, rare case _empty_ exists as a name. + file.write('\n\t\tTextureName: "Texture::%s"' % texname) + + file.write(''' + Properties60: { + Property: "Translation", "Vector", "A+",0,0,0 + Property: "Rotation", "Vector", "A+",0,0,0 + Property: "Scaling", "Vector", "A+",1,1,1''') + file.write('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num) + + + # WrapModeU/V 0==rep, 1==clamp, TODO add support + file.write(''' + Property: "TextureTypeUse", "enum", "",0 + Property: "CurrentTextureBlendMode", "enum", "",1 + Property: "UseMaterial", "bool", "",0 + Property: "UseMipMap", "bool", "",0 + Property: "CurrentMappingType", "enum", "",0 + Property: "UVSwap", "bool", "",0''') + + file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clamp_x) +# file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX) + file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clamp_y) +# file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY) + + file.write(''' + Property: "TextureRotationPivot", "Vector3D", "",0,0,0 + Property: "TextureScalingPivot", "Vector3D", "",0,0,0 + Property: "VideoProperty", "object", "" + }''') + + file.write('\n\t\tMedia: "Video::%s"' % texname) + + if tex: + fname_rel, fname_strip = copy_image(tex) +# fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) + else: + fname = fname_strip = fname_rel = '' + + file.write('\n\t\tFileName: "%s"' % fname_strip) + file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # need some make relative command + + file.write(''' + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + }''') + + def write_deformer_skin(obname): + ''' + Each mesh has its own deformer + ''' + file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname) + file.write(''' + Version: 100 + MultiLayer: 0 + Type: "Skin" + Properties60: { + } + Link_DeformAcuracy: 50 + }''') + + # in the example was 'Bip01 L Thigh_2' + def write_sub_deformer_skin(my_mesh, my_bone, weights): + + ''' + Each subdeformer is spesific to a mesh, but the bone it links to can be used by many sub-deformers + So the SubDeformer needs the mesh-object name as a prefix to make it unique + + Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer, + a but silly but dosnt really matter + ''' + file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName)) + + file.write(''' + Version: 100 + MultiLayer: 0 + Type: "Cluster" + Properties60: { + Property: "SrcModel", "object", "" + Property: "SrcModelReference", "object", "" + } + UserData: "", ""''') + + # Support for bone parents + if my_mesh.fbxBoneParent: + if my_mesh.fbxBoneParent == my_bone: + # TODO - this is a bit lazy, we could have a simple write loop + # for this case because all weights are 1.0 but for now this is ok + # Parent Bones arent used all that much anyway. + vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.verts))] + else: + # This bone is not a parent of this mesh object, no weights + vgroup_data = [] + + else: + # Normal weight painted mesh + if my_bone.blenName in weights[0]: + # Before we used normalized wright list + #vgroup_data = me.getVertsFromGroup(bone.name, 1) + group_index = weights[0].index(my_bone.blenName) + vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]] + else: + vgroup_data = [] + + file.write('\n\t\tIndexes: ') + + i = -1 + for vg in vgroup_data: + if i == -1: + file.write('%i' % vg[0]) + i=0 + else: + if i==23: + file.write('\n\t\t') + i=0 + file.write(',%i' % vg[0]) + i+=1 + + file.write('\n\t\tWeights: ') + i = -1 + for vg in vgroup_data: + if i == -1: + file.write('%.8f' % vg[1]) + i=0 + else: + if i==38: + file.write('\n\t\t') + i=0 + file.write(',%.8f' % vg[1]) + i+=1 + + if my_mesh.fbxParent: + # TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible! + m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) + else: + # Yes! this is it... - but dosnt work when the mesh is a. + m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() ) + + #m = mtx4_z90 * my_bone.restMatrix + matstr = mat4x4str(m) + matstr_i = mat4x4str(m.invert()) + + file.write('\n\t\tTransform: %s' % matstr_i) # THIS IS __NOT__ THE GLOBAL MATRIX AS DOCUMENTED :/ + file.write('\n\t\tTransformLink: %s' % matstr) + file.write('\n\t}') + + def write_mesh(my_mesh): + + me = my_mesh.blenData + + # if there are non NULL materials on this mesh + if my_mesh.blenMaterials: do_materials = True + else: do_materials = False + + if my_mesh.blenTextures: do_textures = True + else: do_textures = False + + do_uvs = len(me.uv_textures) > 0 +# do_uvs = me.faceUV + + + file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName) + file.write('\n\t\tVersion: 232') # newline is added in write_object_props + + poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3] + pose_items.append((my_mesh.fbxName, poseMatrix)) + + file.write('\n\t\t}') + file.write('\n\t\tMultiLayer: 0') + file.write('\n\t\tMultiTake: 1') + file.write('\n\t\tShading: Y') + file.write('\n\t\tCulling: "CullingOff"') + + + # Write the Real Mesh data here + file.write('\n\t\tVertices: ') + i=-1 + + for v in me.verts: + if i==-1: + file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0 + else: + if i==7: + file.write('\n\t\t'); i=0 + file.write(',%.6f,%.6f,%.6f'% tuple(v.co)) + i+=1 + + file.write('\n\t\tPolygonVertexIndex: ') + i=-1 + for f in me.faces: + fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3] +# fi = [v.index for v in f] + + # flip the last index, odd but it looks like + # this is how fbx tells one face from another + fi[-1] = -(fi[-1]+1) + fi = tuple(fi) + if i==-1: + if len(fi) == 3: file.write('%i,%i,%i' % fi ) +# if len(f) == 3: file.write('%i,%i,%i' % fi ) + else: file.write('%i,%i,%i,%i' % fi ) + i=0 + else: + if i==13: + file.write('\n\t\t') + i=0 + if len(fi) == 3: file.write(',%i,%i,%i' % fi ) +# if len(f) == 3: file.write(',%i,%i,%i' % fi ) + else: file.write(',%i,%i,%i,%i' % fi ) + i+=1 + + file.write('\n\t\tEdges: ') + i=-1 + for ed in me.edges: + if i==-1: + file.write('%i,%i' % (ed.verts[0], ed.verts[1])) +# file.write('%i,%i' % (ed.v1.index, ed.v2.index)) + i=0 + else: + if i==13: + file.write('\n\t\t') + i=0 + file.write(',%i,%i' % (ed.verts[0], ed.verts[1])) +# file.write(',%i,%i' % (ed.v1.index, ed.v2.index)) + i+=1 + + file.write('\n\t\tGeometryVersion: 124') + + file.write(''' + LayerElementNormal: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByVertice" + ReferenceInformationType: "Direct" + Normals: ''') + + i=-1 + for v in me.verts: + if i==-1: + file.write('%.15f,%.15f,%.15f' % tuple(v.normal)); i=0 +# file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0 + else: + if i==2: + file.write('\n '); i=0 + file.write(',%.15f,%.15f,%.15f' % tuple(v.normal)) +# file.write(',%.15f,%.15f,%.15f' % tuple(v.no)) + i+=1 + file.write('\n\t\t}') + + # Write Face Smoothing + file.write(''' + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygon" + ReferenceInformationType: "Direct" + Smoothing: ''') + + i=-1 + for f in me.faces: + if i==-1: + file.write('%i' % f.smooth); i=0 + else: + if i==54: + file.write('\n '); i=0 + file.write(',%i' % f.smooth) + i+=1 + + file.write('\n\t\t}') + + # Write Edge Smoothing + file.write(''' + LayerElementSmoothing: 0 { + Version: 101 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: ''') + +# SHARP = Blender.Mesh.EdgeFlags.SHARP + i=-1 + for ed in me.edges: + if i==-1: + file.write('%i' % (ed.sharp)); i=0 +# file.write('%i' % ((ed.flag&SHARP)!=0)); i=0 + else: + if i==54: + file.write('\n '); i=0 + file.write(',%i' % (ed.sharp)) +# file.write(',%i' % ((ed.flag&SHARP)!=0)) + i+=1 + + file.write('\n\t\t}') +# del SHARP + + # small utility function + # returns a slice of data depending on number of face verts + # data is either a MeshTextureFace or MeshColor + def face_data(data, face): + if f.verts[3] == 0: + totvert = 3 + else: + totvert = 4 + + return data[:totvert] + + + # Write VertexColor Layers + # note, no programs seem to use this info :/ + collayers = [] + if len(me.vertex_colors): +# if me.vertexColors: + collayers = me.vertex_colors +# collayers = me.getColorLayerNames() + collayer_orig = me.active_vertex_color +# collayer_orig = me.activeColorLayer + for colindex, collayer in enumerate(collayers): +# me.activeColorLayer = collayer + file.write('\n\t\tLayerElementColor: %i {' % colindex) + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: "%s"' % collayer.name) +# file.write('\n\t\t\tName: "%s"' % collayer) + + file.write(''' + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + Colors: ''') + + i = -1 + ii = 0 # Count how many Colors we write + + for f, cf in zip(me.faces, collayer.data): + colors = [cf.color1, cf.color2, cf.color3, cf.color4] + + # determine number of verts + colors = face_data(colors, f) + + for col in colors: + if i==-1: + file.write('%.4f,%.4f,%.4f,1' % tuple(col)) + i=0 + else: + if i==7: + file.write('\n\t\t\t\t') + i=0 + file.write(',%.4f,%.4f,%.4f,1' % tuple(col)) + i+=1 + ii+=1 # One more Color + +# for f in me.faces: +# for col in f.col: +# if i==-1: +# file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) +# i=0 +# else: +# if i==7: +# file.write('\n\t\t\t\t') +# i=0 +# file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0)) +# i+=1 +# ii+=1 # One more Color + + file.write('\n\t\t\tColorIndex: ') + i = -1 + for j in range(ii): + if i == -1: + file.write('%i' % j) + i=0 + else: + if i==55: + file.write('\n\t\t\t\t') + i=0 + file.write(',%i' % j) + i+=1 + + file.write('\n\t\t}') + + + + # Write UV and texture layers. + uvlayers = [] + if do_uvs: + uvlayers = me.uv_textures +# uvlayers = me.getUVLayerNames() + uvlayer_orig = me.active_uv_texture +# uvlayer_orig = me.activeUVLayer + for uvindex, uvlayer in enumerate(me.uv_textures): +# for uvindex, uvlayer in enumerate(uvlayers): +# me.activeUVLayer = uvlayer + file.write('\n\t\tLayerElementUV: %i {' % uvindex) + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: "%s"' % uvlayer.name) +# file.write('\n\t\t\tName: "%s"' % uvlayer) + + file.write(''' + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: ''') + + i = -1 + ii = 0 # Count how many UVs we write + + for f, uf in zip(me.faces, uvlayer.data): +# for f in me.faces: + uvs = [uf.uv1, uf.uv2, uf.uv3, uf.uv4] + uvs = face_data(uvs, f) + + for uv in uvs: +# for uv in f.uv: + if i==-1: + file.write('%.6f,%.6f' % tuple(uv)) + i=0 + else: + if i==7: + file.write('\n ') + i=0 + file.write(',%.6f,%.6f' % tuple(uv)) + i+=1 + ii+=1 # One more UV + + file.write('\n\t\t\tUVIndex: ') + i = -1 + for j in range(ii): + if i == -1: + file.write('%i' % j) + i=0 + else: + if i==55: + file.write('\n\t\t\t\t') + i=0 + file.write(',%i' % j) + i+=1 + + file.write('\n\t\t}') + + if do_textures: + file.write('\n\t\tLayerElementTexture: %i {' % uvindex) + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: "%s"' % uvlayer.name) +# file.write('\n\t\t\tName: "%s"' % uvlayer) + + if len(my_mesh.blenTextures) == 1: + file.write('\n\t\t\tMappingInformationType: "AllSame"') + else: + file.write('\n\t\t\tMappingInformationType: "ByPolygon"') + + file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') + file.write('\n\t\t\tBlendMode: "Translucent"') + file.write('\n\t\t\tTextureAlpha: 1') + file.write('\n\t\t\tTextureId: ') + + if len(my_mesh.blenTextures) == 1: + file.write('0') + else: + texture_mapping_local = {None:-1} + + i = 0 # 1 for dummy + for tex in my_mesh.blenTextures: + if tex: # None is set above + texture_mapping_local[tex] = i + i+=1 + + i=-1 + for f in uvlayer.data: +# for f in me.faces: + img_key = f.image + + if i==-1: + i=0 + file.write( '%s' % texture_mapping_local[img_key]) + else: + if i==55: + file.write('\n ') + i=0 + + file.write(',%s' % texture_mapping_local[img_key]) + i+=1 + + else: + file.write(''' + LayerElementTexture: 0 { + Version: 101 + Name: "" + MappingInformationType: "NoMappingInformation" + ReferenceInformationType: "IndexToDirect" + BlendMode: "Translucent" + TextureAlpha: 1 + TextureId: ''') + file.write('\n\t\t}') + +# me.activeUVLayer = uvlayer_orig + + # Done with UV/textures. + + if do_materials: + file.write('\n\t\tLayerElementMaterial: 0 {') + file.write('\n\t\t\tVersion: 101') + file.write('\n\t\t\tName: ""') + + if len(my_mesh.blenMaterials) == 1: + file.write('\n\t\t\tMappingInformationType: "AllSame"') + else: + file.write('\n\t\t\tMappingInformationType: "ByPolygon"') + + file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"') + file.write('\n\t\t\tMaterials: ') + + if len(my_mesh.blenMaterials) == 1: + file.write('0') + else: + # Build a material mapping for this + material_mapping_local = {} # local-mat & tex : global index. + + for j, mat_tex_pair in enumerate(my_mesh.blenMaterials): + material_mapping_local[mat_tex_pair] = j + + len_material_mapping_local = len(material_mapping_local) + + mats = my_mesh.blenMaterialList + + if me.active_uv_texture: + uv_faces = me.active_uv_texture.data + else: + uv_faces = [None] * len(me.faces) + + i=-1 + for f, uf in zip(me.faces, uv_faces): +# for f in me.faces: + try: mat = mats[f.material_index] +# try: mat = mats[f.mat] + except:mat = None + + if do_uvs: tex = uf.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ +# if do_uvs: tex = f.image # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/ + else: tex = None + + if i==-1: + i=0 + file.write( '%s' % (material_mapping_local[mat, tex])) # None for mat or tex is ok + else: + if i==55: + file.write('\n\t\t\t\t') + i=0 + + file.write(',%s' % (material_mapping_local[mat, tex])) + i+=1 + + file.write('\n\t\t}') + + file.write(''' + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + }''') + + if do_materials: + file.write(''' + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + }''') + + # Always write this + if do_textures: + file.write(''' + LayerElement: { + Type: "LayerElementTexture" + TypedIndex: 0 + }''') + + if me.vertex_colors: +# if me.vertexColors: + file.write(''' + LayerElement: { + Type: "LayerElementColor" + TypedIndex: 0 + }''') + + if do_uvs: # same as me.faceUV + file.write(''' + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + }''') + + + file.write('\n\t\t}') + + if len(uvlayers) > 1: + for i in range(1, len(uvlayers)): + + file.write('\n\t\tLayer: %i {' % i) + file.write('\n\t\t\tVersion: 100') + + file.write(''' + LayerElement: { + Type: "LayerElementUV"''') + + file.write('\n\t\t\t\tTypedIndex: %i' % i) + file.write('\n\t\t\t}') + + if do_textures: + + file.write(''' + LayerElement: { + Type: "LayerElementTexture"''') + + file.write('\n\t\t\t\tTypedIndex: %i' % i) + file.write('\n\t\t\t}') + + file.write('\n\t\t}') + + if len(collayers) > 1: + # Take into account any UV layers + layer_offset = 0 + if uvlayers: layer_offset = len(uvlayers)-1 + + for i in range(layer_offset, len(collayers)+layer_offset): + file.write('\n\t\tLayer: %i {' % i) + file.write('\n\t\t\tVersion: 100') + + file.write(''' + LayerElement: { + Type: "LayerElementColor"''') + + file.write('\n\t\t\t\tTypedIndex: %i' % i) + file.write('\n\t\t\t}') + file.write('\n\t\t}') + file.write('\n\t}') + + def write_group(name): + file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name) + + file.write(''' + Properties60: { + Property: "MultiLayer", "bool", "",0 + Property: "Pickable", "bool", "",1 + Property: "Transformable", "bool", "",1 + Property: "Show", "bool", "",1 + } + MultiLayer: 0 + }''') + + + # add meshes here to clear because they are not used anywhere. + meshes_to_clear = [] + + ob_meshes = [] + ob_lights = [] + ob_cameras = [] + # in fbx we export bones as children of the mesh + # armatures not a part of a mesh, will be added to ob_arms + ob_bones = [] + ob_arms = [] + ob_null = [] # emptys + + # List of types that have blender objects (not bones) + ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null] + + groups = [] # blender groups, only add ones that have objects in the selections + materials = {} # (mat, image) keys, should be a set() + textures = {} # should be a set() + + tmp_ob_type = ob_type = None # incase no objects are exported, so as not to raise an error + + # if EXP_OBS_SELECTED is false, use sceens objects + if not batch_objects: + if EXP_OBS_SELECTED: tmp_objects = context.selected_objects +# if EXP_OBS_SELECTED: tmp_objects = sce.objects.context + else: tmp_objects = sce.objects + else: + tmp_objects = batch_objects + + if EXP_ARMATURE: + # This is needed so applying modifiers dosnt apply the armature deformation, its also needed + # ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes. + # set every armature to its rest, backup the original values so we done mess up the scene + ob_arms_orig_rest = [arm.rest_position for arm in bpy.data.armatures] +# ob_arms_orig_rest = [arm.restPosition for arm in bpy.data.armatures] + + for arm in bpy.data.armatures: + arm.rest_position = True +# arm.restPosition = True + + if ob_arms_orig_rest: + for ob_base in bpy.data.objects: + #if ob_base.type == 'Armature': + ob_base.make_display_list() +# ob_base.makeDisplayList() + + # This causes the makeDisplayList command to effect the mesh + sce.set_frame(sce.current_frame) +# Blender.Set('curframe', Blender.Get('curframe')) + + + for ob_base in tmp_objects: + + # ignore dupli children + if ob_base.parent and ob_base.parent.dupli_type != 'NONE': + continue + + obs = [(ob_base, ob_base.matrix)] + if ob_base.dupli_type != 'NONE': + ob_base.create_dupli_list() + obs = [(dob.object, dob.matrix) for dob in ob_base.dupli_list] + + for ob, mtx in obs: +# for ob, mtx in BPyObject.getDerivedObjects(ob_base): + tmp_ob_type = ob.type + if tmp_ob_type == 'CAMERA': +# if tmp_ob_type == 'Camera': + if EXP_CAMERA: + ob_cameras.append(my_object_generic(ob, mtx)) + elif tmp_ob_type == 'LAMP': +# elif tmp_ob_type == 'Lamp': + if EXP_LAMP: + ob_lights.append(my_object_generic(ob, mtx)) + elif tmp_ob_type == 'ARMATURE': +# elif tmp_ob_type == 'Armature': + if EXP_ARMATURE: + # TODO - armatures dont work in dupligroups! + if ob not in ob_arms: ob_arms.append(ob) + # ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)" + elif tmp_ob_type == 'EMPTY': +# elif tmp_ob_type == 'Empty': + if EXP_EMPTY: + ob_null.append(my_object_generic(ob, mtx)) + elif EXP_MESH: + origData = True + if tmp_ob_type != 'MESH': +# if tmp_ob_type != 'Mesh': +# me = bpy.data.meshes.new() + try: me = ob.create_mesh(True, 'PREVIEW') +# try: me.getFromObject(ob) + except: me = None + if me: + meshes_to_clear.append( me ) + mats = me.materials + origData = False + else: + # Mesh Type! + if EXP_MESH_APPLY_MOD: +# me = bpy.data.meshes.new() + me = ob.create_mesh(True, 'PREVIEW') +# me.getFromObject(ob) + + # so we keep the vert groups +# if EXP_ARMATURE: +# orig_mesh = ob.getData(mesh=1) +# if orig_mesh.getVertGroupNames(): +# ob.copy().link(me) +# # If new mesh has no vgroups we can try add if verts are teh same +# if not me.getVertGroupNames(): # vgroups were not kept by the modifier +# if len(me.verts) == len(orig_mesh.verts): +# groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh) +# BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) + + # print ob, me, me.getVertGroupNames() + meshes_to_clear.append( me ) + origData = False + mats = me.materials + else: + me = ob.data +# me = ob.getData(mesh=1) + mats = me.materials + +# # Support object colors +# tmp_colbits = ob.colbits +# if tmp_colbits: +# tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too. +# for i in xrange(16): +# if tmp_colbits & (1< 0: +# if me.faceUV: + uvlayer_orig = me.active_uv_texture +# uvlayer_orig = me.activeUVLayer + for uvlayer in me.uv_textures: +# for uvlayer in me.getUVLayerNames(): +# me.activeUVLayer = uvlayer + for f, uf in zip(me.faces, uvlayer.data): +# for f in me.faces: + tex = uf.image +# tex = f.image + textures[tex] = texture_mapping_local[tex] = None + + try: mat = mats[f.material_index] +# try: mat = mats[f.mat] + except: mat = None + + materials[mat, tex] = material_mapping_local[mat, tex] = None # should use sets, wait for blender 2.5 + + +# me.activeUVLayer = uvlayer_orig + else: + for mat in mats: + # 2.44 use mat.lib too for uniqueness + materials[mat, None] = material_mapping_local[mat, None] = None + else: + materials[None, None] = None + + if EXP_ARMATURE: + armob = ob.find_armature() + blenParentBoneName = None + + # parent bone - special case + if (not armob) and ob.parent and ob.parent.type == 'ARMATURE' and \ + ob.parent_type == 'BONE': +# if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE: + armob = ob.parent + blenParentBoneName = ob.parent_bone +# blenParentBoneName = ob.parentbonename + + + if armob and armob not in ob_arms: + ob_arms.append(armob) + + else: + blenParentBoneName = armob = None + + my_mesh = my_object_generic(ob, mtx) + my_mesh.blenData = me + my_mesh.origData = origData + my_mesh.blenMaterials = list(material_mapping_local.keys()) + my_mesh.blenMaterialList = mats + my_mesh.blenTextures = list(texture_mapping_local.keys()) + + # if only 1 null texture then empty the list + if len(my_mesh.blenTextures) == 1 and my_mesh.blenTextures[0] == None: + my_mesh.blenTextures = [] + + my_mesh.fbxArm = armob # replace with my_object_generic armature instance later + my_mesh.fbxBoneParent = blenParentBoneName # replace with my_bone instance later + + ob_meshes.append( my_mesh ) + + # not forgetting to free dupli_list + if ob_base.dupli_list: ob_base.free_dupli_list() + + + if EXP_ARMATURE: + # now we have the meshes, restore the rest arm position + for i, arm in enumerate(bpy.data.armatures): + arm.rest_position = ob_arms_orig_rest[i] +# arm.restPosition = ob_arms_orig_rest[i] + + if ob_arms_orig_rest: + for ob_base in bpy.data.objects: + if ob_base.type == 'ARMATURE': +# if ob_base.type == 'Armature': + ob_base.make_display_list() +# ob_base.makeDisplayList() + # This causes the makeDisplayList command to effect the mesh + sce.set_frame(sce.current_frame) +# Blender.Set('curframe', Blender.Get('curframe')) + + del tmp_ob_type, tmp_objects + + # now we have collected all armatures, add bones + for i, ob in enumerate(ob_arms): + + ob_arms[i] = my_arm = my_object_generic(ob) + + my_arm.fbxBones = [] + my_arm.blenData = ob.data + if ob.animation_data: + my_arm.blenAction = ob.animation_data.action + else: + my_arm.blenAction = None +# my_arm.blenAction = ob.action + my_arm.blenActionList = [] + + # fbxName, blenderObject, my_bones, blenderActions + #ob_arms[i] = fbxArmObName, ob, arm_my_bones, (ob.action, []) + + for bone in my_arm.blenData.bones: +# for bone in my_arm.blenData.bones.values(): + my_bone = my_bone_class(bone, my_arm) + my_arm.fbxBones.append( my_bone ) + ob_bones.append( my_bone ) + + # add the meshes to the bones and replace the meshes armature with own armature class + #for obname, ob, mtx, me, mats, arm, armname in ob_meshes: + for my_mesh in ob_meshes: + # Replace + # ...this could be sped up with dictionary mapping but its unlikely for + # it ever to be a bottleneck - (would need 100+ meshes using armatures) + if my_mesh.fbxArm: + for my_arm in ob_arms: + if my_arm.blenObject == my_mesh.fbxArm: + my_mesh.fbxArm = my_arm + break + + for my_bone in ob_bones: + + # The mesh uses this bones armature! + if my_bone.fbxArm == my_mesh.fbxArm: + my_bone.blenMeshes[my_mesh.fbxName] = me + + + # parent bone: replace bone names with our class instances + # my_mesh.fbxBoneParent is None or a blender bone name initialy, replacing if the names match. + if my_mesh.fbxBoneParent == my_bone.blenName: + my_mesh.fbxBoneParent = my_bone + + bone_deformer_count = 0 # count how many bones deform a mesh + my_bone_blenParent = None + for my_bone in ob_bones: + my_bone_blenParent = my_bone.blenBone.parent + if my_bone_blenParent: + for my_bone_parent in ob_bones: + # Note 2.45rc2 you can compare bones normally + if my_bone_blenParent.name == my_bone_parent.blenName and my_bone.fbxArm == my_bone_parent.fbxArm: + my_bone.parent = my_bone_parent + break + + # Not used at the moment + # my_bone.calcRestMatrixLocal() + bone_deformer_count += len(my_bone.blenMeshes) + + del my_bone_blenParent + + + # Build blenObject -> fbxObject mapping + # this is needed for groups as well as fbxParenting +# for ob in bpy.data.objects: ob.tag = False +# bpy.data.objects.tag = False + + # using a list of object names for tagging (Arystan) + tagged_objects = [] + + tmp_obmapping = {} + for ob_generic in ob_all_typegroups: + for ob_base in ob_generic: + tagged_objects.append(ob_base.blenObject.name) +# ob_base.blenObject.tag = True + tmp_obmapping[ob_base.blenObject] = ob_base + + # Build Groups from objects we export + for blenGroup in bpy.data.groups: + fbxGroupName = None + for ob in blenGroup.objects: + if ob.name in tagged_objects: +# if ob.tag: + if fbxGroupName == None: + fbxGroupName = sane_groupname(blenGroup) + groups.append((fbxGroupName, blenGroup)) + + tmp_obmapping[ob].fbxGroupNames.append(fbxGroupName) # also adds to the objects fbxGroupNames + + groups.sort() # not really needed + + # Assign parents using this mapping + for ob_generic in ob_all_typegroups: + for my_ob in ob_generic: + parent = my_ob.blenObject.parent + if parent and parent.name in tagged_objects: # does it exist and is it in the mapping +# if parent and parent.tag: # does it exist and is it in the mapping + my_ob.fbxParent = tmp_obmapping[parent] + + + del tmp_obmapping + # Finished finding groups we use + + + materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.keys()] + textures = [(sane_texname(tex), tex) for tex in textures.keys() if tex] + materials.sort() # sort by name + textures.sort() + + camera_count = 8 + file.write(''' + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: %i''' % (\ + 1+1+camera_count+\ + len(ob_meshes)+\ + len(ob_lights)+\ + len(ob_cameras)+\ + len(ob_arms)+\ + len(ob_null)+\ + len(ob_bones)+\ + bone_deformer_count+\ + len(materials)+\ + (len(textures)*2))) # add 1 for the root model 1 for global settings + + del bone_deformer_count + + file.write(''' + ObjectType: "Model" { + Count: %i + }''' % (\ + 1+camera_count+\ + len(ob_meshes)+\ + len(ob_lights)+\ + len(ob_cameras)+\ + len(ob_arms)+\ + len(ob_null)+\ + len(ob_bones))) # add 1 for the root model + + file.write(''' + ObjectType: "Geometry" { + Count: %i + }''' % len(ob_meshes)) + + if materials: + file.write(''' + ObjectType: "Material" { + Count: %i + }''' % len(materials)) + + if textures: + file.write(''' + ObjectType: "Texture" { + Count: %i + }''' % len(textures)) # add 1 for an empty tex + file.write(''' + ObjectType: "Video" { + Count: %i + }''' % len(textures)) # add 1 for an empty tex + + tmp = 0 + # Add deformer nodes + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + tmp+=1 + + # Add subdeformers + for my_bone in ob_bones: + tmp += len(my_bone.blenMeshes) + + if tmp: + file.write(''' + ObjectType: "Deformer" { + Count: %i + }''' % tmp) + del tmp + + # we could avoid writing this possibly but for now just write it + + file.write(''' + ObjectType: "Pose" { + Count: 1 + }''') + + if groups: + file.write(''' + ObjectType: "GroupSelection" { + Count: %i + }''' % len(groups)) + + file.write(''' + ObjectType: "GlobalSettings" { + Count: 1 + } +}''') + + file.write(''' + +; Object properties +;------------------------------------------------------------------ + +Objects: {''') + + # To comply with other FBX FILES + write_camera_switch() + + # Write the null object + write_null(None, 'blend_root')# , GLOBAL_MATRIX) + + for my_null in ob_null: + write_null(my_null) + + for my_arm in ob_arms: + write_null(my_arm) + + for my_cam in ob_cameras: + write_camera(my_cam) + + for my_light in ob_lights: + write_light(my_light) + + for my_mesh in ob_meshes: + write_mesh(my_mesh) + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + write_bone(my_bone) + + write_camera_default() + + for matname, (mat, tex) in materials: + write_material(matname, mat) # We only need to have a material per image pair, but no need to write any image info into the material (dumb fbx standard) + + # each texture uses a video, odd + for texname, tex in textures: + write_video(texname, tex) + i = 0 + for texname, tex in textures: + write_texture(texname, tex, i) + i+=1 + + for groupname, group in groups: + write_group(groupname) + + # NOTE - c4d and motionbuilder dont need normalized weights, but deep-exploration 5 does and (max?) do. + + # Write armature modifiers + # TODO - add another MODEL? - because of this skin definition. + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + write_deformer_skin(my_mesh.fbxName) + + # Get normalized weights for temorary use + if my_mesh.fbxBoneParent: + weights = None + else: + weights = meshNormalizedWeights(my_mesh.blenObject) +# weights = meshNormalizedWeights(my_mesh.blenData) + + #for bonename, bone, obname, bone_mesh, armob in ob_bones: + for my_bone in ob_bones: + if me in iter(my_bone.blenMeshes.values()): + write_sub_deformer_skin(my_mesh, my_bone, weights) + + # Write pose's really weired, only needed when an armature and mesh are used together + # each by themselves dont need pose data. for now only pose meshes and bones + + file.write(''' + Pose: "Pose::BIND_POSES", "BindPose" { + Type: "BindPose" + Version: 100 + Properties60: { + } + NbPoseNodes: ''') + file.write(str(len(pose_items))) + + + for fbxName, matrix in pose_items: + file.write('\n\t\tPoseNode: {') + file.write('\n\t\t\tNode: "Model::%s"' % fbxName ) + if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix)) + else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity)) + file.write('\n\t\t}') + + file.write('\n\t}') + + + # Finish Writing Objects + # Write global settings + file.write(''' + GlobalSettings: { + Version: 1000 + Properties60: { + Property: "UpAxis", "int", "",1 + Property: "UpAxisSign", "int", "",1 + Property: "FrontAxis", "int", "",2 + Property: "FrontAxisSign", "int", "",1 + Property: "CoordAxis", "int", "",0 + Property: "CoordAxisSign", "int", "",1 + Property: "UnitScaleFactor", "double", "",100 + } + } +''') + file.write('}') + + file.write(''' + +; Object relations +;------------------------------------------------------------------ + +Relations: {''') + + file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}') + + for my_null in ob_null: + file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_null.fbxName) + + for my_arm in ob_arms: + file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_arm.fbxName) + + for my_mesh in ob_meshes: + file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % my_mesh.fbxName) + + # TODO - limbs can have the same name for multiple armatures, should prefix. + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + file.write('\n\tModel: "Model::%s", "Limb" {\n\t}' % my_bone.fbxName) + + for my_cam in ob_cameras: + file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % my_cam.fbxName) + + for my_light in ob_lights: + file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % my_light.fbxName) + + file.write(''' + Model: "Model::Producer Perspective", "Camera" { + } + Model: "Model::Producer Top", "Camera" { + } + Model: "Model::Producer Bottom", "Camera" { + } + Model: "Model::Producer Front", "Camera" { + } + Model: "Model::Producer Back", "Camera" { + } + Model: "Model::Producer Right", "Camera" { + } + Model: "Model::Producer Left", "Camera" { + } + Model: "Model::Camera Switcher", "CameraSwitcher" { + }''') + + for matname, (mat, tex) in materials: + file.write('\n\tMaterial: "Material::%s", "" {\n\t}' % matname) + + if textures: + for texname, tex in textures: + file.write('\n\tTexture: "Texture::%s", "TextureVideoClip" {\n\t}' % texname) + for texname, tex in textures: + file.write('\n\tVideo: "Video::%s", "Clip" {\n\t}' % texname) + + # deformers - modifiers + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {\n\t}' % my_mesh.fbxName) + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + for fbxMeshObName in my_bone.blenMeshes: # .keys() - fbxMeshObName + # is this bone effecting a mesh? + file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {\n\t}' % (fbxMeshObName, my_bone.fbxName)) + + # This should be at the end + # file.write('\n\tPose: "Pose::BIND_POSES", "BindPose" {\n\t}') + + for groupname, group in groups: + file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {\n\t}' % groupname) + + file.write('\n}') + file.write(''' + +; Object connections +;------------------------------------------------------------------ + +Connections: {''') + + # NOTE - The FBX SDK dosnt care about the order but some importers DO! + # for instance, defining the material->mesh connection + # before the mesh->blend_root crashes cinema4d + + + # write the fake root node + file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"') + + for ob_generic in ob_all_typegroups: # all blender 'Object's we support + for my_ob in ob_generic: + if my_ob.fbxParent: + file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_ob.fbxName, my_ob.fbxParent.fbxName)) + else: + file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_ob.fbxName) + + if materials: + for my_mesh in ob_meshes: + # Connect all materials to all objects, not good form but ok for now. + for mat, tex in my_mesh.blenMaterials: + if mat: mat_name = mat.name + else: mat_name = None + + if tex: tex_name = tex.name + else: tex_name = None + + file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat_name, tex_name], my_mesh.fbxName)) + + if textures: + for my_mesh in ob_meshes: + if my_mesh.blenTextures: + # file.write('\n\tConnect: "OO", "Texture::_empty_", "Model::%s"' % my_mesh.fbxName) + for tex in my_mesh.blenTextures: + if tex: + file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (sane_name_mapping_tex[tex.name], my_mesh.fbxName)) + + for texname, tex in textures: + file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname)) + + for my_mesh in ob_meshes: + if my_mesh.fbxArm: + file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName)) + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + for fbxMeshObName in my_bone.blenMeshes: # .keys() + file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName)) + + # limbs -> deformers + # for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + for fbxMeshObName in my_bone.blenMeshes: # .keys() + file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName)) + + + #for bonename, bone, obname, me, armob in ob_bones: + for my_bone in ob_bones: + # Always parent to armature now + if my_bone.parent: + file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.parent.fbxName) ) + else: + # the armature object is written as an empty and all root level bones connect to it + file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.fbxArm.fbxName) ) + + # groups + if groups: + for ob_generic in ob_all_typegroups: + for ob_base in ob_generic: + for fbxGroupName in ob_base.fbxGroupNames: + file.write('\n\tConnect: "OO", "Model::%s", "GroupSelection::%s"' % (ob_base.fbxName, fbxGroupName)) + + for my_arm in ob_arms: + file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_arm.fbxName) + + file.write('\n}') + + + # Needed for scene footer as well as animation + render = sce.render_data +# render = sce.render + + # from the FBX sdk + #define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000)) + def fbx_time(t): + # 0.5 + val is the same as rounding. + return int(0.5 + ((t/fps) * 46186158000)) + + fps = float(render.fps) + start = sce.start_frame +# start = render.sFrame + end = sce.end_frame +# end = render.eFrame + if end < start: start, end = end, start + if start==end: ANIM_ENABLE = False + + # animations for these object types + ob_anim_lists = ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms + + if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]: + + frame_orig = sce.current_frame +# frame_orig = Blender.Get('curframe') + + if ANIM_OPTIMIZE: + ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION + + # default action, when no actions are avaioable + tmp_actions = [None] # None is the default action + blenActionDefault = None + action_lastcompat = None + + # instead of tagging + tagged_actions = [] + + if ANIM_ACTION_ALL: +# bpy.data.actions.tag = False + tmp_actions = list(bpy.data.actions) + + + # find which actions are compatible with the armatures + # blenActions is not yet initialized so do it now. + tmp_act_count = 0 + for my_arm in ob_arms: + + # get the default name + if not blenActionDefault: + blenActionDefault = my_arm.blenAction + + arm_bone_names = set([my_bone.blenName for my_bone in my_arm.fbxBones]) + + for action in tmp_actions: + + action_chan_names = arm_bone_names.intersection( set([g.name for g in action.groups]) ) +# action_chan_names = arm_bone_names.intersection( set(action.getChannelNames()) ) + + if action_chan_names: # at least one channel matches. + my_arm.blenActionList.append(action) + tagged_actions.append(action.name) +# action.tag = True + tmp_act_count += 1 + + # incase there is no actions applied to armatures + action_lastcompat = action + + if tmp_act_count: + # unlikely to ever happen but if no actions applied to armatures, just use the last compatible armature. + if not blenActionDefault: + blenActionDefault = action_lastcompat + + del action_lastcompat + + file.write(''' +;Takes and animation section +;---------------------------------------------------- + +Takes: {''') + + if blenActionDefault: + file.write('\n\tCurrent: "%s"' % sane_takename(blenActionDefault)) + else: + file.write('\n\tCurrent: "Default Take"') + + for blenAction in tmp_actions: + # we have tagged all actious that are used be selected armatures + if blenAction: + if blenAction.name in tagged_actions: +# if blenAction.tag: + print('\taction: "%s" exporting...' % blenAction.name) + else: + print('\taction: "%s" has no armature using it, skipping' % blenAction.name) + continue + + if blenAction == None: + # Warning, this only accounts for tmp_actions being [None] + file.write('\n\tTake: "Default Take" {') + act_start = start + act_end = end + else: + # use existing name + if blenAction == blenActionDefault: # have we alredy got the name + file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name]) + else: + file.write('\n\tTake: "%s" {' % sane_takename(blenAction)) + + act_start, act_end = blenAction.get_frame_range() +# tmp = blenAction.getFrameNumbers() +# if tmp: +# act_start = min(tmp) +# act_end = max(tmp) +# del tmp +# else: +# # Fallback on this, theres not much else we can do? :/ +# # when an action has no length +# act_start = start +# act_end = end + + # Set the action active + for my_bone in ob_arms: + if blenAction in my_bone.blenActionList: + ob.action = blenAction + # print '\t\tSetting Action!', blenAction + # sce.update(1) + + file.write('\n\t\tFileName: "Default_Take.tak"') # ??? - not sure why this is needed + file.write('\n\t\tLocalTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed + file.write('\n\t\tReferenceTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed + + file.write(''' + + ;Models animation + ;----------------------------------------------------''') + + + # set pose data for all bones + # do this here incase the action changes + ''' + for my_bone in ob_bones: + my_bone.flushAnimData() + ''' + i = act_start + while i <= act_end: + sce.set_frame(i) +# Blender.Set('curframe', i) + for ob_generic in ob_anim_lists: + for my_ob in ob_generic: + #Blender.Window.RedrawAll() + if ob_generic == ob_meshes and my_ob.fbxArm: + # We cant animate armature meshes! + pass + else: + my_ob.setPoseFrame(i) + + i+=1 + + + #for bonename, bone, obname, me, armob in ob_bones: + for ob_generic in (ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms): + + for my_ob in ob_generic: + + if ob_generic == ob_meshes and my_ob.fbxArm: + # do nothing, + pass + else: + + file.write('\n\t\tModel: "Model::%s" {' % my_ob.fbxName) # ??? - not sure why this is needed + file.write('\n\t\t\tVersion: 1.1') + file.write('\n\t\t\tChannel: "Transform" {') + + context_bone_anim_mats = [ (my_ob.getAnimParRelMatrix(frame), my_ob.getAnimParRelMatrixRot(frame)) for frame in range(act_start, act_end+1) ] + + # ---------------- + # ---------------- + for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale + + if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats] + elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats] + elif TX_CHAN=='R': + # Was.... + # elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats] + # + # ...but we need to use the previous euler for compatible conversion. + context_bone_anim_vecs = [] + prev_eul = None + for mtx in context_bone_anim_mats: + if prev_eul: prev_eul = mtx[1].toEuler(prev_eul) + else: prev_eul = mtx[1].toEuler() + context_bone_anim_vecs.append(eulerRadToDeg(prev_eul)) +# context_bone_anim_vecs.append(prev_eul) + + file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation + + for i in range(3): + # Loop on each axis of the bone + file.write('\n\t\t\t\t\tChannel: "%s" {'% ('XYZ'[i])) # translation + file.write('\n\t\t\t\t\t\tDefault: %.15f' % context_bone_anim_vecs[0][i] ) + file.write('\n\t\t\t\t\t\tKeyVer: 4005') + + if not ANIM_OPTIMIZE: + # Just write all frames, simple but in-eficient + file.write('\n\t\t\t\t\t\tKeyCount: %i' % (1 + act_end - act_start)) + file.write('\n\t\t\t\t\t\tKey: ') + frame = act_start + while frame <= act_end: + if frame!=act_start: + file.write(',') + + # Curve types are 'C,n' for constant, 'L' for linear + # C,n is for bezier? - linear is best for now so we can do simple keyframe removal + file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] )) + frame+=1 + else: + # remove unneeded keys, j is the frame, needed when some frames are removed. + context_bone_anim_keys = [ (vec[i], j) for j, vec in enumerate(context_bone_anim_vecs) ] + + # last frame to fisrt frame, missing 1 frame on either side. + # removeing in a backwards loop is faster + #for j in xrange( (act_end-act_start)-1, 0, -1 ): + # j = (act_end-act_start)-1 + j = len(context_bone_anim_keys)-2 + while j > 0 and len(context_bone_anim_keys) > 2: + # print j, len(context_bone_anim_keys) + # Is this key the same as the ones next to it? + + # co-linear horizontal... + if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\ + abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + + del context_bone_anim_keys[j] + + else: + frame_range = float(context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j-1][1]) + frame_range_fac1 = (context_bone_anim_keys[j+1][1] - context_bone_anim_keys[j][1]) / frame_range + frame_range_fac2 = 1.0 - frame_range_fac1 + + if abs(((context_bone_anim_keys[j-1][0]*frame_range_fac1 + context_bone_anim_keys[j+1][0]*frame_range_fac2)) - context_bone_anim_keys[j][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT: + del context_bone_anim_keys[j] + else: + j-=1 + + # keep the index below the list length + if j > len(context_bone_anim_keys)-2: + j = len(context_bone_anim_keys)-2 + + if len(context_bone_anim_keys) == 2 and context_bone_anim_keys[0][0] == context_bone_anim_keys[1][0]: + # This axis has no moton, its okay to skip KeyCount and Keys in this case + pass + else: + # We only need to write these if there is at least one + file.write('\n\t\t\t\t\t\tKeyCount: %i' % len(context_bone_anim_keys)) + file.write('\n\t\t\t\t\t\tKey: ') + for val, frame in context_bone_anim_keys: + if frame != context_bone_anim_keys[0][1]: # not the first + file.write(',') + # frame is alredy one less then blenders frame + file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val )) + + if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0') + elif i==1: file.write('\n\t\t\t\t\t\tColor: 0,1,0') + elif i==2: file.write('\n\t\t\t\t\t\tColor: 0,0,1') + + file.write('\n\t\t\t\t\t}') + file.write('\n\t\t\t\t\tLayerType: %i' % (TX_LAYER+1) ) + file.write('\n\t\t\t\t}') + + # --------------- + + file.write('\n\t\t\t}') + file.write('\n\t\t}') + + # end the take + file.write('\n\t}') + + # end action loop. set original actions + # do this after every loop incase actions effect eachother. + for my_bone in ob_arms: + my_bone.blenObject.action = my_bone.blenAction + + file.write('\n}') + + sce.set_frame(frame_orig) +# Blender.Set('curframe', frame_orig) + + else: + # no animation + file.write('\n;Takes and animation section') + file.write('\n;----------------------------------------------------') + file.write('\n') + file.write('\nTakes: {') + file.write('\n\tCurrent: ""') + file.write('\n}') + + + # write meshes animation + #for obname, ob, mtx, me, mats, arm, armname in ob_meshes: + + + # Clear mesh data Only when writing with modifiers applied + for me in meshes_to_clear: + bpy.data.remove_mesh(me) +# me.verts = None + + # --------------------------- Footer + if world: + m = world.mist + has_mist = m.enabled +# has_mist = world.mode & 1 + mist_intense = m.intensity + mist_start = m.start + mist_end = m.depth + mist_height = m.height +# mist_intense, mist_start, mist_end, mist_height = world.mist + world_hor = world.horizon_color +# world_hor = world.hor + else: + has_mist = mist_intense = mist_start = mist_end = mist_height = 0 + world_hor = 0,0,0 + + file.write('\n;Version 5 settings') + file.write('\n;------------------------------------------------------------------') + file.write('\n') + file.write('\nVersion5: {') + file.write('\n\tAmbientRenderSettings: {') + file.write('\n\t\tVersion: 101') + file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world_amb)) + file.write('\n\t}') + file.write('\n\tFogOptions: {') + file.write('\n\t\tFlogEnable: %i' % has_mist) + file.write('\n\t\tFogMode: 0') + file.write('\n\t\tFogDensity: %.3f' % mist_intense) + file.write('\n\t\tFogStart: %.3f' % mist_start) + file.write('\n\t\tFogEnd: %.3f' % mist_end) + file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world_hor)) + file.write('\n\t}') + file.write('\n\tSettings: {') + file.write('\n\t\tFrameRate: "%i"' % int(fps)) + file.write('\n\t\tTimeFormat: 1') + file.write('\n\t\tSnapOnFrames: 0') + file.write('\n\t\tReferenceTimeIndex: -1') + file.write('\n\t\tTimeLineStartTime: %i' % fbx_time(start-1)) + file.write('\n\t\tTimeLineStopTime: %i' % fbx_time(end-1)) + file.write('\n\t}') + file.write('\n\tRendererSetting: {') + file.write('\n\t\tDefaultCamera: "Producer Perspective"') + file.write('\n\t\tDefaultViewingMode: 0') + file.write('\n\t}') + file.write('\n}') + file.write('\n') + + # Incase sombody imports this, clean up by clearing global dicts + sane_name_mapping_ob.clear() + sane_name_mapping_mat.clear() + sane_name_mapping_tex.clear() + + ob_arms[:] = [] + ob_bones[:] = [] + ob_cameras[:] = [] + ob_lights[:] = [] + ob_meshes[:] = [] + ob_null[:] = [] + + + # copy images if enabled +# if EXP_IMAGE_COPY: +# # copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) +# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath) + + print('export finished in %.4f sec.' % (time.clock() - start_time)) +# print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) + return True + + +# -------------------------------------------- +# UI Function - not a part of the exporter. +# this is to seperate the user interface from the rest of the exporter. +# from Blender import Draw, Window +EVENT_NONE = 0 +EVENT_EXIT = 1 +EVENT_REDRAW = 2 +EVENT_FILESEL = 3 + +GLOBALS = {} + +# export opts + +def do_redraw(e,v): GLOBALS['EVENT'] = e + +# toggle between these 2, only allow one on at once +def do_obs_sel(e,v): + GLOBALS['EVENT'] = e + GLOBALS['EXP_OBS_SCENE'].val = 0 + GLOBALS['EXP_OBS_SELECTED'].val = 1 + +def do_obs_sce(e,v): + GLOBALS['EVENT'] = e + GLOBALS['EXP_OBS_SCENE'].val = 1 + GLOBALS['EXP_OBS_SELECTED'].val = 0 + +def do_batch_type_grp(e,v): + GLOBALS['EVENT'] = e + GLOBALS['BATCH_GROUP'].val = 1 + GLOBALS['BATCH_SCENE'].val = 0 + +def do_batch_type_sce(e,v): + GLOBALS['EVENT'] = e + GLOBALS['BATCH_GROUP'].val = 0 + GLOBALS['BATCH_SCENE'].val = 1 + +def do_anim_act_all(e,v): + GLOBALS['EVENT'] = e + GLOBALS['ANIM_ACTION_ALL'][0].val = 1 + GLOBALS['ANIM_ACTION_ALL'][1].val = 0 + +def do_anim_act_cur(e,v): + if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val: + Draw.PupMenu('Warning%t|Cant use this with batch export group option') + else: + GLOBALS['EVENT'] = e + GLOBALS['ANIM_ACTION_ALL'][0].val = 0 + GLOBALS['ANIM_ACTION_ALL'][1].val = 1 + +def fbx_ui_exit(e,v): + GLOBALS['EVENT'] = e + +def do_help(e,v): + url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx' + print('Trying to open web browser with documentation at this address...') + print('\t' + url) + + try: + import webbrowser + webbrowser.open(url) + except: + Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation") + print('...could not open a browser window.') + + + +# run when export is pressed +#def fbx_ui_write(e,v): +def fbx_ui_write(filename, context): + + # Dont allow overwriting files when saving normally + if not GLOBALS['BATCH_ENABLE'].val: + if not BPyMessages.Warning_SaveOver(filename): + return + + GLOBALS['EVENT'] = EVENT_EXIT + + # Keep the order the same as above for simplicity + # the [] is a dummy arg used for objects + + Blender.Window.WaitCursor(1) + + # Make the matrix + GLOBAL_MATRIX = mtx4_identity + GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val + if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n + if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n + if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n + + ret = write(\ + filename, None,\ + context, + GLOBALS['EXP_OBS_SELECTED'].val,\ + GLOBALS['EXP_MESH'].val,\ + GLOBALS['EXP_MESH_APPLY_MOD'].val,\ + GLOBALS['EXP_MESH_HQ_NORMALS'].val,\ + GLOBALS['EXP_ARMATURE'].val,\ + GLOBALS['EXP_LAMP'].val,\ + GLOBALS['EXP_CAMERA'].val,\ + GLOBALS['EXP_EMPTY'].val,\ + GLOBALS['EXP_IMAGE_COPY'].val,\ + GLOBAL_MATRIX,\ + GLOBALS['ANIM_ENABLE'].val,\ + GLOBALS['ANIM_OPTIMIZE'].val,\ + GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\ + GLOBALS['ANIM_ACTION_ALL'][0].val,\ + GLOBALS['BATCH_ENABLE'].val,\ + GLOBALS['BATCH_GROUP'].val,\ + GLOBALS['BATCH_SCENE'].val,\ + GLOBALS['BATCH_FILE_PREFIX'].val,\ + GLOBALS['BATCH_OWN_DIR'].val,\ + ) + + Blender.Window.WaitCursor(0) + GLOBALS.clear() + + if ret == False: + Draw.PupMenu('Error%t|Path cannot be written to!') + + +def fbx_ui(): + # Only to center the UI + x,y = GLOBALS['MOUSE'] + x-=180; y-=0 # offset... just to get it centered + + Draw.Label('Export Objects...', x+20,y+165, 200, 20) + + if not GLOBALS['BATCH_ENABLE'].val: + Draw.BeginAlign() + GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel) + GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce) + Draw.EndAlign() + + Draw.BeginAlign() + GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)') + GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrese about the X axis') + GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrese about the Y axis') + GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrese about the Z axis') + Draw.EndAlign() + + y -= 35 + + Draw.BeginAlign() + GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects') + GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects') + GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects') + GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects') + GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z) + Draw.EndAlign() + + if GLOBALS['EXP_MESH'].val: + # below mesh but + Draw.BeginAlign() + GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z) + GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z) + Draw.EndAlign() + + GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z) + + + Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20) + + GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw) + if GLOBALS['ANIM_ENABLE'].val: + Draw.BeginAlign() + GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw) + if GLOBALS['ANIM_OPTIMIZE'].val: + GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)') + Draw.EndAlign() + + Draw.BeginAlign() + GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur) + GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all) + Draw.EndAlign() + + + Draw.Label('Export Batch...', x+20,y-60, 300, 20) + GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw) + + if GLOBALS['BATCH_ENABLE'].val: + Draw.BeginAlign() + GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp) + GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce) + + # Own dir requires OS module + if os: + GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file') + GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') + else: + GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ') + + + Draw.EndAlign() + + #y+=80 + + ''' + Draw.BeginAlign() + GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ') + Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw) + ''' + # Until batch is added + # + + + #Draw.BeginAlign() + Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help) + Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit) + Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw) + + #Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write) + #Draw.EndAlign() + + # exit when mouse out of the view? + # GLOBALS['EVENT'] = EVENT_EXIT + +#def write_ui(filename): +def write_ui(): + + # globals + GLOBALS['EVENT'] = EVENT_REDRAW + #GLOBALS['MOUSE'] = Window.GetMouseCoords() + GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] + GLOBALS['FILENAME'] = '' + ''' + # IF called from the fileselector + if filename == None: + GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx')) + else: + GLOBALS['FILENAME'].val = filename + ''' + GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity + GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0) + + GLOBALS['EXP_MESH'] = Draw.Create(1) + GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1) + GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0) + GLOBALS['EXP_ARMATURE'] = Draw.Create(1) + GLOBALS['EXP_LAMP'] = Draw.Create(1) + GLOBALS['EXP_CAMERA'] = Draw.Create(1) + GLOBALS['EXP_EMPTY'] = Draw.Create(1) + GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0) + # animation opts + GLOBALS['ANIM_ENABLE'] = Draw.Create(1) + GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1) + GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places + GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action + + # batch export options + GLOBALS['BATCH_ENABLE'] = Draw.Create(0) + GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once. + GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above + GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1]) + GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0) + # done setting globals + + # Used by the user interface + GLOBALS['_SCALE'] = Draw.Create(1.0) + GLOBALS['_XROT90'] = Draw.Create(True) + GLOBALS['_YROT90'] = Draw.Create(False) + GLOBALS['_ZROT90'] = Draw.Create(False) + + # best not do move the cursor + # Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()]) + + # hack so the toggle buttons redraw. this is not nice at all + while GLOBALS['EVENT'] != EVENT_EXIT: + + if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val: + #Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ") + GLOBALS['ANIM_ACTION_ALL'][0].val = 1 + GLOBALS['ANIM_ACTION_ALL'][1].val = 0 + + if GLOBALS['EVENT'] == EVENT_FILESEL: + if GLOBALS['BATCH_ENABLE'].val: + txt = 'Batch FBX Dir' + name = Blender.sys.expandpath('//') + else: + txt = 'Export FBX' + name = Blender.sys.makename(ext='.fbx') + + Blender.Window.FileSelector(fbx_ui_write, txt, name) + #fbx_ui_write('/test.fbx') + break + + Draw.UIBlock(fbx_ui, 0) + + + # GLOBALS.clear() + +class EXPORT_OT_fbx(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "export.fbx" + __label__ = "Export FBX" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default=""), + bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True), +# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True), + bpy.props.FloatProperty(attr="_SCALE", name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0), + bpy.props.BoolProperty(attr="_XROT90", name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True), + bpy.props.BoolProperty(attr="_YROT90", name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False), + bpy.props.BoolProperty(attr="_ZROT90", name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False), + bpy.props.BoolProperty(attr="EXP_EMPTY", name="Empties", description="Export empty objects", default=True), + bpy.props.BoolProperty(attr="EXP_CAMERA", name="Cameras", description="Export camera objects", default=True), + bpy.props.BoolProperty(attr="EXP_LAMP", name="Lamps", description="Export lamp objects", default=True), + bpy.props.BoolProperty(attr="EXP_ARMATURE", name="Armatures", description="Export armature objects", default=True), + bpy.props.BoolProperty(attr="EXP_MESH", name="Meshes", description="Export mesh objects", default=True), + bpy.props.BoolProperty(attr="EXP_MESH_APPLY_MOD", name="Modifiers", description="Apply modifiers to mesh objects", default=True), + bpy.props.BoolProperty(attr="EXP_MESH_HQ_NORMALS", name="HQ Normals", description="Generate high quality normals", default=True), + bpy.props.BoolProperty(attr="EXP_IMAGE_COPY", name="Copy Image Files", description="Copy image files to the destination path", default=False), + # armature animation + bpy.props.BoolProperty(attr="ANIM_ENABLE", name="Enable Animation", description="Export keyframe animation", default=True), + bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True), + bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0), +# bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True), + bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures, if false, use current action", default=False), + # batch + bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False), + bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False), + bpy.props.BoolProperty(attr="BATCH_OWN_DIR", name="Own Dir", description="Create a dir for each exported file", default=True), + bpy.props.StringProperty(attr="BATCH_FILE_PREFIX", name="Prefix", description="Prefix each file with this name", maxlen= 1024, default=""), + ] + + def poll(self, context): + print("Poll") + return context.active_object != None + + def execute(self, context): + if not self.filename: + raise Exception("filename not set") + + GLOBAL_MATRIX = mtx4_identity + GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self._SCALE + if self._XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n + if self._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n + if self._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n + + write(self.filename, + None, # XXX + context, + self.EXP_OBS_SELECTED, + self.EXP_MESH, + self.EXP_MESH_APPLY_MOD, +# self.EXP_MESH_HQ_NORMALS, + self.EXP_ARMATURE, + self.EXP_LAMP, + self.EXP_CAMERA, + self.EXP_EMPTY, + self.EXP_IMAGE_COPY, + GLOBAL_MATRIX, + self.ANIM_ENABLE, + self.ANIM_OPTIMIZE, + self.ANIM_OPTIMIZE_PRECISSION, + self.ANIM_ACTION_ALL, + self.BATCH_ENABLE, + self.BATCH_GROUP, + self.BATCH_FILE_PREFIX, + self.BATCH_OWN_DIR) + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + +bpy.ops.add(EXPORT_OT_fbx) + +# if __name__ == "__main__": +# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply") + + +# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts) +# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print +# - get rid of cleanName somehow +# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565 +# + get rid of BPyObject_getObjectArmature, move it in RNA? +# - BATCH_ENABLE and BATCH_GROUP options: line 327 +# - implement all BPyMesh_* used here with RNA +# - getDerivedObjects is not fully replicated with .dupli* funcs +# - talk to Campbell, this code won't work? lines 1867-1875 +# - don't know what those colbits are, do we need them? they're said to be deprecated in DNA_object_types.h: 1886-1893 +# - no hq normals: 1900-1901 + +# TODO + +# - bpy.data.remove_scene: line 366 +# - bpy.sys.time move to bpy.sys.util? +# - new scene creation, activation: lines 327-342, 368 +# - uses bpy.sys.expandpath, *.relpath - replace at least relpath + +# SMALL or COSMETICAL +# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version') diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py new file mode 100644 index 00000000000..e2ac78798bd --- /dev/null +++ b/release/scripts/io/export_obj.py @@ -0,0 +1,993 @@ +#!BPY + +""" +Name: 'Wavefront (.obj)...' +Blender: 248 +Group: 'Export' +Tooltip: 'Save a Wavefront OBJ File' +""" + +__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone" +__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org'] +__version__ = "1.21" + +__bpydoc__ = """\ +This script is an exporter to OBJ file format. + +Usage: + +Select the objects you wish to export and run this script from "File->Export" menu. +Selecting the default options from the popup box will be good in most cases. +All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) +will be exported as mesh data. +""" + + +# -------------------------------------------------------------------------- +# OBJ Export v1.1 by Campbell Barton (AKA Ideasman) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +# import math and other in functions that use them for the sake of fast Blender startup +# import math +import os +import time + +import bpy +import Mathutils + + +# Returns a tuple - path,extension. +# 'hello.obj' > ('hello', '.obj') +def splitExt(path): + dotidx = path.rfind('.') + if dotidx == -1: + return path, '' + else: + return path[:dotidx], path[dotidx:] + +def fixName(name): + if name == None: + return 'None' + else: + return name.replace(' ', '_') + + +# this used to be in BPySys module +# frankly, I don't understand how it works +def BPySys_cleanName(name): + + v = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,58,59,60,61,62,63,64,91,92,93,94,96,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,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,247,248,249,250,251,252,253,254] + + invalid = ''.join([chr(i) for i in v]) + + for ch in invalid: + name = name.replace(ch, '_') + return name + +# A Dict of Materials +# (material.name, image.name):matname_imagename # matname_imagename has gaps removed. +MTL_DICT = {} + +def write_mtl(scene, filename, copy_images): + + world = scene.world + worldAmb = world.ambient_color + + dest_dir = os.path.dirname(filename) + + def copy_image(image): + rel = image.get_export_path(dest_dir, True) + + if copy_images: + abspath = image.get_export_path(dest_dir, False) + if not os.path.exists(abs_path): + shutil.copy(image.get_abs_filename(), abs_path) + + return rel + + + file = open(filename, "w") + # XXX +# file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) + file.write('# Material Count: %i\n' % len(MTL_DICT)) + # Write material/image combinations we have used. + for key, (mtl_mat_name, mat, img) in MTL_DICT.items(): + + # Get the Blender data for the material and the image. + # Having an image named None will make a bug, dont do it :) + + file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname + + if mat: + file.write('Ns %.6f\n' % ((mat.specular_hardness-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's + file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.ambient for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.diffuse_intensity for c in mat.diffuse_color]) ) # Diffuse + file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.specular_intensity for c in mat.specular_color]) ) # Specular + if hasattr(mat, "ior"): + file.write('Ni %.6f\n' % mat.ior) # Refraction index + else: + file.write('Ni %.6f\n' % 1.0) + file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve) + + # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. + if mat.shadeless: + file.write('illum 0\n') # ignore lighting + elif mat.specular_intensity == 0: + file.write('illum 1\n') # no specular. + else: + file.write('illum 2\n') # light normaly + + else: + #write a dummy material here? + file.write('Ns 0\n') + file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour, + file.write('Kd 0.8 0.8 0.8\n') + file.write('Ks 0.8 0.8 0.8\n') + file.write('d 1\n') # No alpha + file.write('illum 2\n') # light normaly + + # Write images! + if img: # We have an image on the face! + # write relative image path + rel = copy_image(img) + file.write('map_Kd %s\n' % rel) # Diffuse mapping image +# file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image + + elif mat: # No face image. if we havea material search for MTex image. + for mtex in mat.textures: + if mtex and mtex.texure.type == 'IMAGE': + try: + filename = copy_image(mtex.texture.image) +# filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1] + file.write('map_Kd %s\n' % filename) # Diffuse mapping image + break + except: + # Texture has no image though its an image type, best ignore. + pass + + file.write('\n\n') + + file.close() + +# XXX not used +def copy_file(source, dest): + file = open(source, 'rb') + data = file.read() + file.close() + + file = open(dest, 'wb') + file.write(data) + file.close() + + +# XXX not used +def copy_images(dest_dir): + if dest_dir[-1] != os.sep: + dest_dir += os.sep +# if dest_dir[-1] != sys.sep: +# dest_dir += sys.sep + + # Get unique image names + uniqueImages = {} + for matname, mat, image in MTL_DICT.values(): # Only use image name + # Get Texface images + if image: + uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default. + + # Get MTex images + if mat: + for mtex in mat.textures: + if mtex and mtex.texture.type == 'IMAGE': + image_tex = mtex.texture.image + if image_tex: + try: + uniqueImages[image_tex] = image_tex + except: + pass + + # Now copy images + copyCount = 0 + +# for bImage in uniqueImages.values(): +# image_path = bpy.sys.expandpath(bImage.filename) +# if bpy.sys.exists(image_path): +# # Make a name for the target path. +# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1] +# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there +# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path)) +# copy_file(image_path, dest_image_path) +# copyCount+=1 + +# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir) + + print('\tCopied %d images' % copyCount) +# print('\tCopied %d images' % copyCount) + +# XXX not converted +def test_nurbs_compat(ob): + if ob.type != 'Curve': + return False + + for nu in ob.data: + if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier + return True + + return False + + +# XXX not converted +def write_nurb(file, ob, ob_mat): + tot_verts = 0 + cu = ob.data + + # use negative indices + Vector = Blender.Mathutils.Vector + for nu in cu: + + if nu.type==0: DEG_ORDER_U = 1 + else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct + + if nu.type==1: + print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported") + continue + + if nu.knotsV: + print("\tWarning, surface:", ob.name, "only poly and nurbs curves supported") + continue + + if len(nu) <= DEG_ORDER_U: + print("\tWarning, orderU is lower then vert count, skipping:", ob.name) + continue + + pt_num = 0 + do_closed = (nu.flagU & 1) + do_endpoints = (do_closed==0) and (nu.flagU & 2) + + for pt in nu: + pt = Vector(pt[0], pt[1], pt[2]) * ob_mat + file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2])) + pt_num += 1 + tot_verts += pt_num + + file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too + file.write('cstype bspline\n') # not ideal, hard coded + file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still + + curve_ls = [-(i+1) for i in range(pt_num)] + + # 'curv' keyword + if do_closed: + if DEG_ORDER_U == 1: + pt_num += 1 + curve_ls.append(-1) + else: + pt_num += DEG_ORDER_U + curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U] + + file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve + + # 'parm' keyword + tot_parm = (DEG_ORDER_U + 1) + pt_num + tot_parm_div = float(tot_parm-1) + parm_ls = [(i/tot_parm_div) for i in range(tot_parm)] + + if do_endpoints: # end points, force param + for i in range(DEG_ORDER_U+1): + parm_ls[i] = 0.0 + parm_ls[-(1+i)] = 1.0 + + file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] )) + + file.write('end\n') + + return tot_verts + +def write(filename, objects, scene, + EXPORT_TRI=False, + EXPORT_EDGES=False, + EXPORT_NORMALS=False, + EXPORT_NORMALS_HQ=False, + EXPORT_UV=True, + EXPORT_MTL=True, + EXPORT_COPY_IMAGES=False, + EXPORT_APPLY_MODIFIERS=True, + EXPORT_ROTX90=True, + EXPORT_BLEN_OBS=True, + EXPORT_GROUP_BY_OB=False, + EXPORT_GROUP_BY_MAT=False, + EXPORT_KEEP_VERT_ORDER=False, + EXPORT_POLYGROUPS=False, + EXPORT_CURVE_AS_NURBS=True): + ''' + Basic write function. The context and options must be alredy set + This can be accessed externaly + eg. + write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options. + ''' + + # XXX + import math + + def veckey3d(v): + return round(v.x, 6), round(v.y, 6), round(v.z, 6) + + def veckey2d(v): + return round(v.x, 6), round(v.y, 6) + + def findVertexGroupName(face, vWeightMap): + """ + Searches the vertexDict to see what groups is assigned to a given face. + We use a frequency system in order to sort out the name because a given vetex can + belong to two or more groups at the same time. To find the right name for the face + we list all the possible vertex group names with their frequency and then sort by + frequency in descend order. The top element is the one shared by the highest number + of vertices is the face's group + """ + weightDict = {} + for vert_index in face.verts: +# for vert in face: + vWeights = vWeightMap[vert_index] +# vWeights = vWeightMap[vert] + for vGroupName, weight in vWeights: + weightDict[vGroupName] = weightDict.get(vGroupName, 0) + weight + + if weightDict: + alist = [(weight,vGroupName) for vGroupName, weight in weightDict.items()] # sort least to greatest amount of weight + alist.sort() + return(alist[-1][1]) # highest value last + else: + return '(null)' + + # TODO: implement this in C? dunno how it should be called... + def getVertsFromGroup(me, group_index): + ret = [] + + for i, v in enumerate(me.verts): + for g in v.groups: + if g.group == group_index: + ret.append((i, g.weight)) + + return ret + + + print('OBJ Export path: "%s"' % filename) + temp_mesh_name = '~tmp-mesh' + + time1 = time.clock() +# time1 = sys.time() +# scn = Scene.GetCurrent() + + file = open(filename, "w") + + # Write Header + version = "2.5" + file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] )) + file.write('# www.blender3d.org\n') + + # Tell the obj file what material file to use. + if EXPORT_MTL: + mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) + file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) + + if EXPORT_ROTX90: + mat_xrot90= Mathutils.RotationMatrix(-math.pi/2, 4, 'x') + + # Initialize totals, these are updated each object + totverts = totuvco = totno = 1 + + face_vert_index = 1 + + globalNormals = {} + + # Get all meshes + for ob_main in objects: + + # ignore dupli children + if ob_main.parent and ob_main.parent.dupli_type != 'NONE': + # XXX + print(ob_main.name, 'is a dupli child - ignoring') + continue + + obs = [] + if ob_main.dupli_type != 'NONE': + # XXX + print('creating dupli_list on', ob_main.name) + ob_main.create_dupli_list() + + obs = [(dob.object, dob.matrix) for dob in ob_main.dupli_list] + + # XXX debug print + print(ob_main.name, 'has', len(obs), 'dupli children') + else: + obs = [(ob_main, ob_main.matrix)] + + for ob, ob_mat in obs: + + # XXX postponed +# # Nurbs curve support +# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): +# if EXPORT_ROTX90: +# ob_mat = ob_mat * mat_xrot90 + +# totverts += write_nurb(file, ob, ob_mat) + +# continue +# end nurbs + + if ob.type != 'MESH': + continue + + me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW') + + if EXPORT_ROTX90: + me.transform(ob_mat * mat_xrot90) + else: + me.transform(ob_mat) + +# # Will work for non meshes now! :) +# me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) +# if not me: +# continue + + if EXPORT_UV: + faceuv = len(me.uv_textures) > 0 + else: + faceuv = False + + # XXX - todo, find a better way to do triangulation + # ...removed convert_to_triface because it relies on editmesh + ''' + # We have a valid mesh + if EXPORT_TRI and me.faces: + # Add a dummy object to it. + has_quads = False + for f in me.faces: + if f.verts[3] != 0: + has_quads = True + break + + if has_quads: + newob = bpy.data.add_object('MESH', 'temp_object') + newob.data = me + # if we forget to set Object.data - crash + scene.add_object(newob) + newob.convert_to_triface(scene) + # mesh will still be there + scene.remove_object(newob) + ''' + + # Make our own list so it can be sorted to reduce context switching + face_index_pairs = [ (face, index) for index, face in enumerate(me.faces)] + # faces = [ f for f in me.faces ] + + if EXPORT_EDGES: + edges = me.edges + else: + edges = [] + + if not (len(face_index_pairs)+len(edges)+len(me.verts)): # Make sure there is somthing to write + + # clean up + bpy.data.remove_mesh(me) + + continue # dont bother with this mesh. + + # XXX + # High Quality Normals + if EXPORT_NORMALS and face_index_pairs: + me.calc_normals() +# if EXPORT_NORMALS_HQ: +# BPyMesh.meshCalcNormals(me) +# else: +# # transforming normals is incorrect +# # when the matrix is scaled, +# # better to recalculate them +# me.calcNormals() + + materials = me.materials + + materialNames = [] + materialItems = [m for m in materials] + if materials: + for mat in materials: + if mat: # !=None + materialNames.append(mat.name) + else: + materialNames.append(None) + # Cant use LC because some materials are None. + # materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. + + # Possible there null materials, will mess up indicies + # but at least it will export, wait until Blender gets fixed. + materialNames.extend((16-len(materialNames)) * [None]) + materialItems.extend((16-len(materialItems)) * [None]) + + # Sort by Material, then images + # so we dont over context switch in the obj file. + if EXPORT_KEEP_VERT_ORDER: + pass + elif faceuv: + # XXX update + tface = me.active_uv_texture.data + + # exception only raised if Python 2.3 or lower... + try: + face_index_pairs.sort(key = lambda a: (a[0].material_index, tface[a[1]].image, a[0].smooth)) + except: + face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, tface[a[1]].image, a[0].smooth), + (b[0].material_index, tface[b[1]].image, b[0].smooth))) + elif len(materials) > 1: + try: + face_index_pairs.sort(key = lambda a: (a[0].material_index, a[0].smooth)) + except: + face_index_pairs.sort(lambda a,b: cmp((a[0].material_index, a[0].smooth), + (b[0].material_index, b[0].smooth))) + else: + # no materials + try: + face_index_pairs.sort(key = lambda a: a[0].smooth) + except: + face_index_pairs.sort(lambda a,b: cmp(a[0].smooth, b[0].smooth)) +# if EXPORT_KEEP_VERT_ORDER: +# pass +# elif faceuv: +# try: faces.sort(key = lambda a: (a.mat, a.image, a.smooth)) +# except: faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) +# elif len(materials) > 1: +# try: faces.sort(key = lambda a: (a.mat, a.smooth)) +# except: faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) +# else: +# # no materials +# try: faces.sort(key = lambda a: a.smooth) +# except: faces.sort(lambda a,b: cmp(a.smooth, b.smooth)) + + faces = [pair[0] for pair in face_index_pairs] + + # Set the default mat to no material and no image. + contextMat = (0, 0) # Can never be this, so we will label a new material teh first chance we get. + contextSmooth = None # Will either be true or false, set bad to force initialization switch. + + if EXPORT_BLEN_OBS or EXPORT_GROUP_BY_OB: + name1 = ob.name + name2 = ob.data.name + if name1 == name2: + obnamestring = fixName(name1) + else: + obnamestring = '%s_%s' % (fixName(name1), fixName(name2)) + + if EXPORT_BLEN_OBS: + file.write('o %s\n' % obnamestring) # Write Object name + else: # if EXPORT_GROUP_BY_OB: + file.write('g %s\n' % obnamestring) + + + # Vert + for v in me.verts: + file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) + + # UV + if faceuv: + uv_face_mapping = [[0,0,0,0] for f in faces] # a bit of a waste for tri's :/ + + uv_dict = {} # could use a set() here + uv_layer = me.active_uv_texture + for f, f_index in face_index_pairs: + + tface = uv_layer.data[f_index] + + uvs = [tface.uv1, tface.uv2, tface.uv3] + + # add another UV if it's a quad + if f.verts[3] != 0: + uvs.append(tface.uv4) + + for uv_index, uv in enumerate(uvs): + uvkey = veckey2d(uv) + try: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] + except: + uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) + file.write('vt %.6f %.6f\n' % tuple(uv)) + +# uv_dict = {} # could use a set() here +# for f_index, f in enumerate(faces): + +# for uv_index, uv in enumerate(f.uv): +# uvkey = veckey2d(uv) +# try: +# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] +# except: +# uv_face_mapping[f_index][uv_index] = uv_dict[uvkey] = len(uv_dict) +# file.write('vt %.6f %.6f\n' % tuple(uv)) + + uv_unique_count = len(uv_dict) +# del uv, uvkey, uv_dict, f_index, uv_index + # Only need uv_unique_count and uv_face_mapping + + # NORMAL, Smooth/Non smoothed. + if EXPORT_NORMALS: + for f in faces: + if f.smooth: + for v in f: + noKey = veckey3d(v.normal) + if noKey not in globalNormals: + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + else: + # Hard, 1 normal from the face. + noKey = veckey3d(f.normal) + if noKey not in globalNormals: + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) + + if not faceuv: + f_image = None + + # XXX + if EXPORT_POLYGROUPS: + # Retrieve the list of vertex groups +# vertGroupNames = me.getVertGroupNames() + + currentVGroup = '' + # Create a dictionary keyed by face id and listing, for each vertex, the vertex groups it belongs to + vgroupsMap = [[] for _i in range(len(me.verts))] +# vgroupsMap = [[] for _i in xrange(len(me.verts))] + for g in ob.vertex_groups: +# for vertexGroupName in vertGroupNames: + for vIdx, vWeight in getVertsFromGroup(me, g.index): +# for vIdx, vWeight in me.getVertsFromGroup(vertexGroupName, 1): + vgroupsMap[vIdx].append((g.name, vWeight)) + + for f_index, f in enumerate(faces): + f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts] + + if f.verts[3] == 0: + f_v.pop() + +# f_v= f.v + f_smooth= f.smooth + f_mat = min(f.material_index, len(materialNames)-1) +# f_mat = min(f.mat, len(materialNames)-1) + if faceuv: + + tface = me.active_uv_texture.data[face_index_pairs[f_index][1]] + + f_image = tface.image + f_uv= [tface.uv1, tface.uv2, tface.uv3] + if f.verts[3] != 0: + f_uv.append(tface.uv4) +# f_image = f.image +# f_uv= f.uv + + # MAKE KEY + if faceuv and f_image: # Object is always true. + key = materialNames[f_mat], f_image.name + else: + key = materialNames[f_mat], None # No image, use None instead. + + # Write the vertex group + if EXPORT_POLYGROUPS: + if len(ob.vertex_groups): + # find what vertext group the face belongs to + theVGroup = findVertexGroupName(f,vgroupsMap) + if theVGroup != currentVGroup: + currentVGroup = theVGroup + file.write('g %s\n' % theVGroup) +# # Write the vertex group +# if EXPORT_POLYGROUPS: +# if vertGroupNames: +# # find what vertext group the face belongs to +# theVGroup = findVertexGroupName(f,vgroupsMap) +# if theVGroup != currentVGroup: +# currentVGroup = theVGroup +# file.write('g %s\n' % theVGroup) + + # CHECK FOR CONTEXT SWITCH + if key == contextMat: + pass # Context alredy switched, dont do anything + else: + if key[0] == None and key[1] == None: + # Write a null material, since we know the context has changed. + if EXPORT_GROUP_BY_MAT: + # can be mat_image or (null) + file.write('g %s_%s\n' % (fixName(ob.name), fixName(ob.data.name)) ) # can be mat_image or (null) + file.write('usemtl (null)\n') # mat, image + + else: + mat_data= MTL_DICT.get(key) + if not mat_data: + # First add to global dict so we can export to mtl + # Then write mtl + + # Make a new names from the mat and image name, + # converting any spaces to underscores with fixName. + + # If none image dont bother adding it to the name + if key[1] == None: + mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image + else: + mat_data = MTL_DICT[key] = ('%s_%s' % (fixName(key[0]), fixName(key[1]))), materialItems[f_mat], f_image + + if EXPORT_GROUP_BY_MAT: + file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.data.name), mat_data[0]) ) # can be mat_image or (null) + + file.write('usemtl %s\n' % mat_data[0]) # can be mat_image or (null) + + contextMat = key + if f_smooth != contextSmooth: + if f_smooth: # on now off + file.write('s 1\n') + contextSmooth = f_smooth + else: # was off now on + file.write('s off\n') + contextSmooth = f_smooth + + file.write('f') + if faceuv: + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % \ + (v["index"] + totverts, + totuvco + uv_face_mapping[f_index][vi], + globalNormals[ veckey3d(v["vertex"].normal) ]) ) # vert, uv, normal + + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.normal) ] + for vi, v in enumerate(f_v): + file.write( ' %d/%d/%d' % \ + (v["index"] + totverts, + totuvco + uv_face_mapping[f_index][vi], + no) ) # vert, uv, normal + else: # No Normals + for vi, v in enumerate(f_v): + file.write( ' %d/%d' % (\ + v["index"] + totverts,\ + totuvco + uv_face_mapping[f_index][vi])) # vert, uv + + face_vert_index += len(f_v) + + else: # No UV's + if EXPORT_NORMALS: + if f_smooth: # Smoothed, use vertex normals + for v in f_v: + file.write( ' %d//%d' % + (v["index"] + totverts, globalNormals[ veckey3d(v["vertex"].normal) ]) ) + else: # No smoothing, face normals + no = globalNormals[ veckey3d(f.normal) ] + for v in f_v: + file.write( ' %d//%d' % (v["index"] + totverts, no) ) + else: # No Normals + for v in f_v: + file.write( ' %d' % (v["index"] + totverts) ) + + file.write('\n') + + # Write edges. + if EXPORT_EDGES: + for ed in edges: + if ed.loose: + file.write('f %d %d\n' % (ed.verts[0] + totverts, ed.verts[1] + totverts)) + + # Make the indicies global rather then per mesh + totverts += len(me.verts) + if faceuv: + totuvco += uv_unique_count + + # clean up + bpy.data.remove_mesh(me) + + if ob_main.dupli_type != 'NONE': + ob_main.free_dupli_list() + + file.close() + + + # Now we have all our materials, save them + if EXPORT_MTL: + write_mtl(scene, mtlfilename, EXPORT_COPY_IMAGES) +# if EXPORT_COPY_IMAGES: +# dest_dir = os.path.basename(filename) +# # dest_dir = filename +# # # Remove chars until we are just the path. +# # while dest_dir and dest_dir[-1] not in '\\/': +# # dest_dir = dest_dir[:-1] +# if dest_dir: +# copy_images(dest_dir) +# else: +# print('\tError: "%s" could not be used as a base for an image path.' % filename) + + print("OBJ Export time: %.2f" % (time.clock() - time1)) +# print "OBJ Export time: %.2f" % (sys.time() - time1) + +def do_export(filename, context, + EXPORT_APPLY_MODIFIERS = True, # not used + EXPORT_ROTX90 = True, # wrong + EXPORT_TRI = False, # ok + EXPORT_EDGES = False, + EXPORT_NORMALS = False, # not yet + EXPORT_NORMALS_HQ = False, # not yet + EXPORT_UV = True, # ok + EXPORT_MTL = True, + EXPORT_SEL_ONLY = True, # ok + EXPORT_ALL_SCENES = False, # XXX not working atm + EXPORT_ANIMATION = False, + EXPORT_COPY_IMAGES = False, + EXPORT_BLEN_OBS = True, + EXPORT_GROUP_BY_OB = False, + EXPORT_GROUP_BY_MAT = False, + EXPORT_KEEP_VERT_ORDER = False, + EXPORT_POLYGROUPS = False, + EXPORT_CURVE_AS_NURBS = True): + # Window.EditMode(0) + # Window.WaitCursor(1) + + base_name, ext = splitExt(filename) + context_name = [base_name, '', '', ext] # Base name, scene name, frame number, extension + + orig_scene = context.scene + +# if EXPORT_ALL_SCENES: +# export_scenes = bpy.data.scenes +# else: +# export_scenes = [orig_scene] + + # XXX only exporting one scene atm since changing + # current scene is not possible. + # Brecht says that ideally in 2.5 we won't need such a function, + # allowing multiple scenes open at once. + export_scenes = [orig_scene] + + # Export all scenes. + for scn in export_scenes: + # scn.makeCurrent() # If already current, this is not slow. + # context = scn.getRenderingContext() + orig_frame = scn.current_frame + + if EXPORT_ALL_SCENES: # Add scene name into the context_name + context_name[1] = '_%s' % BPySys_cleanName(scn.name) # WARNING, its possible that this could cause a collision. we could fix if were feeling parranoied. + + # Export an animation? + if EXPORT_ANIMATION: + scene_frames = range(scn.start_frame, context.end_frame+1) # Up to and including the end frame. + else: + scene_frames = [orig_frame] # Dont export an animation. + + # Loop through all frames in the scene and export. + for frame in scene_frames: + if EXPORT_ANIMATION: # Add frame to the filename. + context_name[2] = '_%.6d' % frame + + scn.current_frame = frame + if EXPORT_SEL_ONLY: + export_objects = context.selected_objects + else: + export_objects = scn.objects + + full_path= ''.join(context_name) + + # erm... bit of a problem here, this can overwrite files when exporting frames. not too bad. + # EXPORT THE FILE. + write(full_path, export_objects, scn, + EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS, + EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL, + EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS, + EXPORT_ROTX90, EXPORT_BLEN_OBS, + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER, + EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) + + + scn.current_frame = orig_frame + + # Restore old active scene. +# orig_scene.makeCurrent() +# Window.WaitCursor(0) + + +class EXPORT_OT_obj(bpy.types.Operator): + ''' + Currently the exporter lacks these features: + * nurbs + * multiple scene export (only active scene is written) + * particles + ''' + __idname__ = "export.obj" + __label__ = 'Export OBJ' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the OBJ file", maxlen= 1024, default= ""), + + # context group + bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False), + bpy.props.BoolProperty(attr="use_all_scenes", name="All Scenes", description="", default= False), + bpy.props.BoolProperty(attr="use_animation", name="All Animation", description="", default= False), + + # object group + bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="", default= True), + bpy.props.BoolProperty(attr="use_rotate90", name="Rotate X90", description="", default= True), + + # extra data group + bpy.props.BoolProperty(attr="use_edges", name="Edges", description="", default= True), + bpy.props.BoolProperty(attr="use_normals", name="Normals", description="", default= False), + bpy.props.BoolProperty(attr="use_hq_normals", name="High Quality Normals", description="", default= True), + bpy.props.BoolProperty(attr="use_uvs", name="UVs", description="", default= True), + bpy.props.BoolProperty(attr="use_materials", name="Materials", description="", default= True), + bpy.props.BoolProperty(attr="copy_images", name="Copy Images", description="", default= False), + bpy.props.BoolProperty(attr="use_triangles", name="Triangulate", description="", default= False), + bpy.props.BoolProperty(attr="use_vertex_groups", name="Polygroups", description="", default= False), + bpy.props.BoolProperty(attr="use_nurbs", name="Nurbs", description="", default= False), + + # grouping group + bpy.props.BoolProperty(attr="use_blen_objects", name="Objects as OBJ Objects", description="", default= True), + bpy.props.BoolProperty(attr="group_by_object", name="Objects as OBJ Groups ", description="", default= False), + bpy.props.BoolProperty(attr="group_by_material", name="Material Groups", description="", default= False), + bpy.props.BoolProperty(attr="keep_vertex_order", name="Keep Vertex Order", description="", default= False) + ] + + def execute(self, context): + + do_export(self.filename, context, + EXPORT_TRI=self.use_triangles, + EXPORT_EDGES=self.use_edges, + EXPORT_NORMALS=self.use_normals, + EXPORT_NORMALS_HQ=self.use_hq_normals, + EXPORT_UV=self.use_uvs, + EXPORT_MTL=self.use_materials, + EXPORT_COPY_IMAGES=self.copy_images, + EXPORT_APPLY_MODIFIERS=self.use_modifiers, + EXPORT_ROTX90=self.use_rotate90, + EXPORT_BLEN_OBS=self.use_blen_objects, + EXPORT_GROUP_BY_OB=self.group_by_object, + EXPORT_GROUP_BY_MAT=self.group_by_material, + EXPORT_KEEP_VERT_ORDER=self.keep_vertex_order, + EXPORT_POLYGROUPS=self.use_vertex_groups, + EXPORT_CURVE_AS_NURBS=self.use_nurbs, + EXPORT_SEL_ONLY=self.use_selection, + EXPORT_ALL_SCENES=self.use_all_scenes) + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + def poll(self, context): # Poll isnt working yet + print("Poll") + return context.active_object != None + +bpy.ops.add(EXPORT_OT_obj) + +if __name__ == "__main__": + bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj") + +# CONVERSION ISSUES +# - matrix problem +# - duplis - only tested dupliverts +# - NURBS - needs API additions +# - all scenes export +# + normals calculation +# - get rid of cleanName somehow diff --git a/release/scripts/io/export_ply.py b/release/scripts/io/export_ply.py new file mode 100644 index 00000000000..8e79c3741bb --- /dev/null +++ b/release/scripts/io/export_ply.py @@ -0,0 +1,279 @@ +import bpy + +__author__ = "Bruce Merry" +__version__ = "0.93" +__bpydoc__ = """\ +This script exports Stanford PLY files from Blender. It supports normals, +colours, and texture coordinates per face or per vertex. +Only one mesh can be exported at a time. +""" + +# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Vector rounding se we can use as keys +# +# Updated on Aug 11, 2008 by Campbell Barton +# - added 'comment' prefix to comments - Needed to comply with the PLY spec. +# +# Updated on Jan 1, 2007 by Gabe Ghearing +# - fixed normals so they are correctly smooth/flat +# - fixed crash when the model doesn't have uv coords or vertex colors +# - fixed crash when the model has vertex colors but doesn't have uv coords +# - changed float32 to float and uint8 to uchar for compatibility +# Errata/Notes as of Jan 1, 2007 +# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me) +# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either) +# +# Updated on Jan 3, 2007 by Gabe Ghearing +# - fixed "sticky" vertex UV exporting +# - added pupmenu to enable/disable exporting normals, uv coords, and colors +# Errata/Notes as of Jan 3, 2007 +# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either) +# - edges should be exported since PLY files support them +# - code is getting spaghettish, it should be refactored... +# + + +def rvec3d(v): return round(v[0], 6), round(v[1], 6), round(v[2], 6) +def rvec2d(v): return round(v[0], 6), round(v[1], 6) + +def write(filename, scene, ob, \ + EXPORT_APPLY_MODIFIERS= True,\ + EXPORT_NORMALS= True,\ + EXPORT_UV= True,\ + EXPORT_COLORS= True\ + ): + + if not filename.lower().endswith('.ply'): + filename += '.ply' + + if not ob: + raise Exception("Error, Select 1 active object") + return + + file = open(filename, 'w') + + + #EXPORT_EDGES = Draw.Create(0) + """ + is_editmode = Blender.Window.EditMode() + if is_editmode: + Blender.Window.EditMode(0, '', 0) + + Window.WaitCursor(1) + """ + + #mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX + if EXPORT_APPLY_MODIFIERS: + mesh = ob.create_mesh(True, 'PREVIEW') + else: + mesh = ob.data + + if not mesh: + raise ("Error, could not get mesh data from active object") + return + + # mesh.transform(ob.matrixWorld) # XXX + + faceUV = len(mesh.uv_textures) > 0 + vertexUV = len(mesh.sticky) > 0 + vertexColors = len(mesh.vertex_colors) > 0 + + if (not faceUV) and (not vertexUV): EXPORT_UV = False + if not vertexColors: EXPORT_COLORS = False + + if not EXPORT_UV: faceUV = vertexUV = False + if not EXPORT_COLORS: vertexColors = False + + if faceUV: + active_uv_layer = None + for lay in mesh.uv_textures: + if lay.active: + active_uv_layer= lay.data + break + if not active_uv_layer: + EXPORT_UV = False + faceUV = None + + if vertexColors: + active_col_layer = None + for lay in mesh.vertex_colors: + if lay.active: + active_col_layer= lay.data + if not active_col_layer: + EXPORT_COLORS = False + vertexColors = None + + # incase + color = uvcoord = uvcoord_key = normal = normal_key = None + + mesh_verts = mesh.verts # save a lookup + ply_verts = [] # list of dictionaries + # vdict = {} # (index, normal, uv) -> new index + vdict = [{} for i in range(len(mesh_verts))] + ply_faces = [[] for f in range(len(mesh.faces))] + vert_count = 0 + for i, f in enumerate(mesh.faces): + + + smooth = f.smooth + if not smooth: + normal = tuple(f.normal) + normal_key = rvec3d(normal) + + if faceUV: + uv = active_uv_layer[i] + uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/ + if vertexColors: + col = active_col_layer[i] + col = col.color1, col.color2, col.color3, col.color4 + + f_verts= f.verts + + pf= ply_faces[i] + for j, vidx in enumerate(f_verts): + v = mesh_verts[vidx] + + if smooth: + normal= tuple(v.normal) + normal_key = rvec3d(normal) + + if faceUV: + uvcoord= uv[j][0], 1.0-uv[j][1] + uvcoord_key = rvec2d(uvcoord) + elif vertexUV: + uvcoord= v.uvco[0], 1.0-v.uvco[1] + uvcoord_key = rvec2d(uvcoord) + + if vertexColors: + color= col[j] + color= int(color[0]*255.0), int(color[1]*255.0), int(color[2]*255.0) + + + key = normal_key, uvcoord_key, color + + vdict_local = vdict[vidx] + pf_vidx = vdict_local.get(key) # Will be None initially + + if pf_vidx == None: # same as vdict_local.has_key(key) + pf_vidx = vdict_local[key] = vert_count; + ply_verts.append((vidx, normal, uvcoord, color)) + vert_count += 1 + + pf.append(pf_vidx) + + file.write('ply\n') + file.write('format ascii 1.0\n') + version = "2.5" # Blender.Get('version') + file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] )) + + file.write('element vertex %d\n' % len(ply_verts)) + + file.write('property float x\n') + file.write('property float y\n') + file.write('property float z\n') + + # XXX + """ + if EXPORT_NORMALS: + file.write('property float nx\n') + file.write('property float ny\n') + file.write('property float nz\n') + """ + if EXPORT_UV: + file.write('property float s\n') + file.write('property float t\n') + if EXPORT_COLORS: + file.write('property uchar red\n') + file.write('property uchar green\n') + file.write('property uchar blue\n') + + file.write('element face %d\n' % len(mesh.faces)) + file.write('property list uchar uint vertex_indices\n') + file.write('end_header\n') + + for i, v in enumerate(ply_verts): + file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co + """ + if EXPORT_NORMALS: + file.write('%.6f %.6f %.6f ' % v[1]) # no + """ + if EXPORT_UV: file.write('%.6f %.6f ' % v[2]) # uv + if EXPORT_COLORS: file.write('%u %u %u' % v[3]) # col + file.write('\n') + + for pf in ply_faces: + if len(pf)==3: file.write('3 %d %d %d\n' % tuple(pf)) + else: file.write('4 %d %d %d %d\n' % tuple(pf)) + + file.close() + print("writing", filename, "done") + + if EXPORT_APPLY_MODIFIERS: + bpy.data.remove_mesh(mesh) + + # XXX + """ + if is_editmode: + Blender.Window.EditMode(1, '', 0) + """ + +class EXPORT_OT_ply(bpy.types.Operator): + '''Export a single object as a stanford PLY with normals, colours and texture coordinates.''' + __idname__ = "export.ply" + __label__ = "Export PLY" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""), + bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True), + bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True), + bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True), + bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True) + ] + + def poll(self, context): + return context.active_object != None + + def execute(self, context): + # print("Selected: " + context.active_object.name) + + if not self.path: + raise Exception("filename not set") + + write(self.path, context.scene, context.active_object,\ + EXPORT_APPLY_MODIFIERS = self.use_modifiers, + EXPORT_NORMALS = self.use_normals, + EXPORT_UV = self.use_uvs, + EXPORT_COLORS = self.use_colors, + ) + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + +bpy.ops.add(EXPORT_OT_ply) + +if __name__ == "__main__": + bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply") + + diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py new file mode 100644 index 00000000000..f23ccf8d2dc --- /dev/null +++ b/release/scripts/io/export_x3d.py @@ -0,0 +1,1239 @@ +#!BPY +""" Registration info for Blender menus: +Name: 'X3D Extensible 3D (.x3d)...' +Blender: 245 +Group: 'Export' +Tooltip: 'Export selection to Extensible 3D file (.x3d)' +""" + +__author__ = ("Bart", "Campbell Barton") +__email__ = ["Bart, bart:neeneenee*de"] +__url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"] +__version__ = "2006/01/17" +__bpydoc__ = """\ +This script exports to X3D format. + +Usage: + +Run this script from "File->Export" menu. A pop-up will ask whether you +want to export only selected or all relevant objects. + +Known issues:
+ Doesn't handle multiple materials (don't use material indices);
+ Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);
+ Can't get the texture array associated with material * not the UV ones; +""" + + +# $Id$ +# +#------------------------------------------------------------------------ +# X3D exporter for blender 2.36 or above +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# + +#################################### +# Library dependancies +#################################### + +import math +import os + +import bpy +import Mathutils + +from export_3ds import create_derived_objects, free_derived_objects + +# import Blender +# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh +# from Blender.Scene import Render +# import BPyObject +# import BPyMesh + +# +DEG2RAD=0.017453292519943295 +MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x') + +#################################### +# Global Variables +#################################### + +filename = "" +# filename = Blender.Get('filename') +_safeOverwrite = True + +extension = '' + +########################################################## +# Functions for writing output file +########################################################## + +class x3d_class: + + def __init__(self, filename): + #--- public you can change these --- + self.writingcolor = 0 + self.writingtexture = 0 + self.writingcoords = 0 + self.proto = 1 + self.matonly = 0 + self.share = 0 + self.billnode = 0 + self.halonode = 0 + self.collnode = 0 + self.tilenode = 0 + self.verbose=2 # level of verbosity in console 0-none, 1-some, 2-most + self.cp=3 # decimals for material color values 0.000 - 1.000 + self.vp=3 # decimals for vertex coordinate values 0.000 - n.000 + self.tp=3 # decimals for texture coordinate values 0.000 - 1.000 + self.it=3 + + #--- class private don't touch --- + self.texNames={} # dictionary of textureNames + self.matNames={} # dictionary of materiaNames + self.meshNames={} # dictionary of meshNames + self.indentLevel=0 # keeps track of current indenting + self.filename=filename + self.file = None + if filename.lower().endswith('.x3dz'): + try: + import gzip + self.file = gzip.open(filename, "w") + except: + print("failed to import compression modules, exporting uncompressed") + self.filename = filename[:-1] # remove trailing z + + if self.file == None: + self.file = open(self.filename, "w") + + self.bNav=0 + self.nodeID=0 + self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard", + "BooleanFilter","BooleanSequencer","BooleanToggle","BooleanTrigger","Box","Circle2D", + "Collision","Color","ColorInterpolator","ColorRGBA","component","Cone","connect", + "Contour2D","ContourPolyline2D","Coordinate","CoordinateDouble","CoordinateInterpolator", + "CoordinateInterpolator2D","Cylinder","CylinderSensor","DirectionalLight","Disk2D", + "ElevationGrid","EspduTransform","EXPORT","ExternProtoDeclare","Extrusion","field", + "fieldValue","FillProperties","Fog","FontStyle","GeoCoordinate","GeoElevationGrid", + "GeoLocationLocation","GeoLOD","GeoMetadata","GeoOrigin","GeoPositionInterpolator", + "GeoTouchSensor","GeoViewpoint","Group","HAnimDisplacer","HAnimHumanoid","HAnimJoint", + "HAnimSegment","HAnimSite","head","ImageTexture","IMPORT","IndexedFaceSet", + "IndexedLineSet","IndexedTriangleFanSet","IndexedTriangleSet","IndexedTriangleStripSet", + "Inline","IntegerSequencer","IntegerTrigger","IS","KeySensor","LineProperties","LineSet", + "LoadSensor","LOD","Material","meta","MetadataDouble","MetadataFloat","MetadataInteger", + "MetadataSet","MetadataString","MovieTexture","MultiTexture","MultiTextureCoordinate", + "MultiTextureTransform","NavigationInfo","Normal","NormalInterpolator","NurbsCurve", + "NurbsCurve2D","NurbsOrientationInterpolator","NurbsPatchSurface", + "NurbsPositionInterpolator","NurbsSet","NurbsSurfaceInterpolator","NurbsSweptSurface", + "NurbsSwungSurface","NurbsTextureCoordinate","NurbsTrimmedSurface","OrientationInterpolator", + "PixelTexture","PlaneSensor","PointLight","PointSet","Polyline2D","Polypoint2D", + "PositionInterpolator","PositionInterpolator2D","ProtoBody","ProtoDeclare","ProtoInstance", + "ProtoInterface","ProximitySensor","ReceiverPdu","Rectangle2D","ROUTE","ScalarInterpolator", + "Scene","Script","Shape","SignalPdu","Sound","Sphere","SphereSensor","SpotLight","StaticGroup", + "StringSensor","Switch","Text","TextureBackground","TextureCoordinate","TextureCoordinateGenerator", + "TextureTransform","TimeSensor","TimeTrigger","TouchSensor","Transform","TransmitterPdu", + "TriangleFanSet","TriangleSet","TriangleSet2D","TriangleStripSet","Viewpoint","VisibilitySensor", + "WorldInfo","X3D","XvlShell","VertexShader","FragmentShader","MultiShaderAppearance","ShaderAppearance" ] + self.namesStandard=[ "Empty","Empty.000","Empty.001","Empty.002","Empty.003","Empty.004","Empty.005", + "Empty.006","Empty.007","Empty.008","Empty.009","Empty.010","Empty.011","Empty.012", + "Scene.001","Scene.002","Scene.003","Scene.004","Scene.005","Scene.06","Scene.013", + "Scene.006","Scene.007","Scene.008","Scene.009","Scene.010","Scene.011","Scene.012", + "World","World.000","World.001","World.002","World.003","World.004","World.005" ] + self.namesFog=[ "","LINEAR","EXPONENTIAL","" ] + +########################################################## +# Writing nodes routines +########################################################## + + def writeHeader(self): + #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '<').replace('>', '>') + bfile = self.filename.replace('<', '<').replace('>', '>') # use outfile name + self.file.write("\n") + self.file.write("\n") + self.file.write("\n") + self.file.write("\n") + self.file.write("\t\n" % os.path.basename(bfile)) + # self.file.write("\t\n" % sys.basename(bfile)) + self.file.write("\t\n" % '2.5') + # self.file.write("\t\n" % Blender.Get('version')) + self.file.write("\t\n") + self.file.write("\n") + self.file.write("\n") + + # This functionality is poorly defined, disabling for now - campbell + ''' + def writeInline(self): + inlines = Blender.Scene.Get() + allinlines = len(inlines) + if scene != inlines[0]: + return + else: + for i in xrange(allinlines): + nameinline=inlines[i].name + if (nameinline not in self.namesStandard) and (i > 0): + self.file.write("" % nameinline) + self.file.write("\n\n") + + + def writeScript(self): + textEditor = Blender.Text.Get() + alltext = len(textEditor) + for i in xrange(alltext): + nametext = textEditor[i].name + nlines = textEditor[i].getNLines() + if (self.proto == 1): + if (nametext == "proto" or nametext == "proto.js" or nametext == "proto.txt") and (nlines != None): + nalllines = len(textEditor[i].asLines()) + alllines = textEditor[i].asLines() + for j in xrange(nalllines): + self.writeIndented(alllines[j] + "\n") + elif (self.proto == 0): + if (nametext == "route" or nametext == "route.js" or nametext == "route.txt") and (nlines != None): + nalllines = len(textEditor[i].asLines()) + alllines = textEditor[i].asLines() + for j in xrange(nalllines): + self.writeIndented(alllines[j] + "\n") + self.writeIndented("\n") + ''' + + def writeViewpoint(self, ob, mat, scene): + context = scene.render_data + # context = scene.render + ratio = float(context.resolution_x)/float(context.resolution_y) + # ratio = float(context.imageSizeY())/float(context.imageSizeX()) + lens = (360* (math.atan(ratio *16 / ob.data.lens) / math.pi))*(math.pi/180) + # lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180) + lens = min(lens, math.pi) + + # get the camera location, subtract 90 degress from X to orient like X3D does + # mat = ob.matrixWorld - mat is now passed! + + loc = self.rotatePointForVRML(mat.translationPart()) + rot = mat.toEuler() + rot = (((rot[0]-90)), rot[1], rot[2]) + # rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD) + nRot = self.rotatePointForVRML( rot ) + # convert to Quaternion and to Angle Axis + Q = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2]) + Q1 = self.multiplyQuaternions(Q[0], Q[1]) + Qf = self.multiplyQuaternions(Q1, Q[2]) + angleAxis = self.quaternionToAngleAxis(Qf) + self.file.write("\n\n" % (lens)) + + def writeFog(self, world): + if world: + mtype = world.mist.falloff + # mtype = world.getMistype() + mparam = world.mist + # mparam = world.getMist() + grd = world.horizon_color + # grd = world.getHor() + grd0, grd1, grd2 = grd[0], grd[1], grd[2] + else: + return + if (mtype == 'LINEAR' or mtype == 'INVERSE_QUADRATIC'): + mtype = 1 if mtype == 'LINEAR' else 2 + # if (mtype == 1 or mtype == 2): + self.file.write("\n\n" % round(mparam[2],self.cp)) + else: + return + + def writeNavigationInfo(self, scene): + self.file.write('\n') + + def writeSpotLight(self, ob, mtx, lamp, world): + safeName = self.cleanStr(ob.name) + if world: + ambi = world.ambient_color + # ambi = world.amb + ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 + else: + ambi = 0 + ambientIntensity = 0 + + # compute cutoff and beamwidth + intensity=min(lamp.energy/1.75,1.0) + beamWidth=((lamp.spot_size*math.pi)/180.0)*.37; + # beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; + cutOffAngle=beamWidth*1.3 + + dx,dy,dz=self.computeDirection(mtx) + # note -dx seems to equal om[3][0] + # note -dz seems to equal om[3][1] + # note dy seems to equal om[3][2] + + #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed + location=(mtx*MATWORLD).translationPart() + + radius = lamp.distance*math.cos(beamWidth) + # radius = lamp.dist*math.cos(beamWidth) + self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) + + + def writeDirectionalLight(self, ob, mtx, lamp, world): + safeName = self.cleanStr(ob.name) + if world: + ambi = world.ambient_color + # ambi = world.amb + ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 + else: + ambi = 0 + ambientIntensity = 0 + + intensity=min(lamp.energy/1.75,1.0) + (dx,dy,dz)=self.computeDirection(mtx) + self.file.write("\n\n" % (round(dx,4),round(dy,4),round(dz,4))) + + def writePointLight(self, ob, mtx, lamp, world): + safeName = self.cleanStr(ob.name) + if world: + ambi = world.ambient_color + # ambi = world.amb + ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5 + else: + ambi = 0 + ambientIntensity = 0 + + # location=(ob.matrixWorld*MATWORLD).translationPart() # now passed + location= (mtx*MATWORLD).translationPart() + + self.file.write("\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) + ''' + def writeNode(self, ob, mtx): + obname=str(ob.name) + if obname in self.namesStandard: + return + else: + dx,dy,dz = self.computeDirection(mtx) + # location=(ob.matrixWorld*MATWORLD).translationPart() + location=(mtx*MATWORLD).translationPart() + self.writeIndented("<%s\n" % obname,1) + self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3))) + self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3))) + self.writeIndented("/>\n",-1) + self.writeIndented("\n") + ''' + def secureName(self, name): + name = name + str(self.nodeID) + self.nodeID=self.nodeID+1 + if len(name) <= 3: + newname = "_" + str(self.nodeID) + return "%s" % (newname) + else: + for bad in ['"','#',"'",',','.','[','\\',']','{','}']: + name=name.replace(bad,'_') + if name in self.namesReserved: + newname = name[0:3] + "_" + str(self.nodeID) + return "%s" % (newname) + elif name[0].isdigit(): + newname = "_" + name + str(self.nodeID) + return "%s" % (newname) + else: + newname = name + return "%s" % (newname) + + def writeIndexedFaceSet(self, ob, mesh, mtx, world, EXPORT_TRI = False): + imageMap={} # set of used images + sided={} # 'one':cnt , 'two':cnt + vColors={} # 'multi':1 + meshName = self.cleanStr(ob.name) + + meshME = self.cleanStr(ob.data.name) # We dont care if its the mesh name or not + # meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not + if len(mesh.faces) == 0: return + mode = [] + # mode = 0 + if mesh.active_uv_texture: + # if mesh.faceUV: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + if face.halo and 'HALO' not in mode: + mode += ['HALO'] + if face.billboard and 'BILLBOARD' not in mode: + mode += ['BILLBOARD'] + if face.object_color and 'OBJECT_COLOR' not in mode: + mode += ['OBJECT_COLOR'] + if face.collision and 'COLLISION' not in mode: + mode += ['COLLISION'] + # mode |= face.mode + + if 'HALO' in mode and self.halonode == 0: + # if mode & Mesh.FaceModes.HALO and self.halonode == 0: + self.writeIndented("\n",1) + self.halonode = 1 + elif 'BILLBOARD' in mode and self.billnode == 0: + # elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0: + self.writeIndented("\n",1) + self.billnode = 1 + elif 'OBJECT_COLOR' in mode and self.matonly == 0: + # elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0: + self.matonly = 1 + # TF_TILES is marked as deprecated in DNA_meshdata_types.h + # elif mode & Mesh.FaceModes.TILES and self.tilenode == 0: + # self.tilenode = 1 + elif 'COLLISION' not in mode and self.collnode == 0: + # elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0: + self.writeIndented("\n",1) + self.collnode = 1 + + nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors) + + if nIFSCnt > 1: + self.writeIndented("\n" % ("G_", meshName),1) + + if 'two' in sided and sided['two'] > 0: + bTwoSided=1 + else: + bTwoSided=0 + + # mtx = ob.matrixWorld * MATWORLD # mtx is now passed + mtx = mtx * MATWORLD + + loc= mtx.translationPart() + sca= mtx.scalePart() + quat = mtx.toQuat() + rot= quat.axis + + self.writeIndented('\n' % \ + (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle) ) + # self.writeIndented('\n' % \ + # (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) ) + + self.writeIndented("\n",1) + maters=mesh.materials + hasImageTexture=0 + issmooth=0 + + if len(maters) > 0 or mesh.active_uv_texture: + # if len(maters) > 0 or mesh.faceUV: + self.writeIndented("\n", 1) + # right now this script can only handle a single material per mesh. + if len(maters) >= 1: + mat=maters[0] + # matFlags = mat.getMode() + if not mat.face_texture: + # if not matFlags & Blender.Material.Modes['TEXFACE']: + self.writeMaterial(mat, self.cleanStr(mat.name,''), world) + # self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world) + if len(maters) > 1: + print("Warning: mesh named %s has multiple materials" % meshName) + print("Warning: only one material per object handled") + + #-- textures + face = None + if mesh.active_uv_texture: + # if mesh.faceUV: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + if face.image: + # if (hasImageTexture == 0) and (face.image): + self.writeImageTexture(face.image) + # hasImageTexture=1 # keep track of face texture + break + if self.tilenode == 1 and face and face.image: + # if self.tilenode == 1: + self.writeIndented("\n" % (face.image.xrep, face.image.yrep)) + self.tilenode = 0 + self.writeIndented("\n", -1) + + #-- IndexedFaceSet or IndexedLineSet + + # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5 + ifStyle="IndexedFaceSet" + # look up mesh name, use it if available + if meshME in self.meshNames: + self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1) + self.meshNames[meshME]+=1 + else: + if int(mesh.users) > 1: + self.writeIndented("<%s DEF=\"ME_%s\" " % (ifStyle, meshME), 1) + self.meshNames[meshME]=1 + else: + self.writeIndented("<%s " % ifStyle, 1) + + if bTwoSided == 1: + self.file.write("solid=\"false\" ") + else: + self.file.write("solid=\"true\" ") + + for face in mesh.faces: + if face.smooth: + issmooth=1 + break + if issmooth==1: + creaseAngle=(mesh.autosmooth_angle)*(math.pi/180.0) + # creaseAngle=(mesh.degr)*(math.pi/180.0) + self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp))) + + #--- output textureCoordinates if UV texture used + if mesh.active_uv_texture: + # if mesh.faceUV: + if self.matonly == 1 and self.share == 1: + self.writeFaceColors(mesh) + elif hasImageTexture == 1: + self.writeTextureCoordinates(mesh) + #--- output coordinates + self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) + + self.writingcoords = 1 + self.writingtexture = 1 + self.writingcolor = 1 + self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI) + + #--- output textureCoordinates if UV texture used + if mesh.active_uv_texture: + # if mesh.faceUV: + if hasImageTexture == 1: + self.writeTextureCoordinates(mesh) + elif self.matonly == 1 and self.share == 1: + self.writeFaceColors(mesh) + #--- output vertexColors + self.matonly = 0 + self.share = 0 + + self.writingcoords = 0 + self.writingtexture = 0 + self.writingcolor = 0 + #--- output closing braces + self.writeIndented("\n" % ifStyle, -1) + self.writeIndented("\n", -1) + self.writeIndented("\n", -1) + + if self.halonode == 1: + self.writeIndented("\n", -1) + self.halonode = 0 + + if self.billnode == 1: + self.writeIndented("\n", -1) + self.billnode = 0 + + if self.collnode == 1: + self.writeIndented("\n", -1) + self.collnode = 0 + + if nIFSCnt > 1: + self.writeIndented("\n", -1) + + self.file.write("\n") + + def writeCoordinates(self, ob, mesh, meshName, EXPORT_TRI = False): + # create vertex list and pre rotate -90 degrees X for VRML + + if self.writingcoords == 0: + self.file.write('coordIndex="') + for face in mesh.faces: + fv = face.verts + # fv = face.v + + if len(fv)==3: + # if len(face)==3: + self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2])) + # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) + else: + if EXPORT_TRI: + self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2])) + # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index)) + self.file.write("%i %i %i -1, " % (fv[0], fv[2], fv[3])) + # self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index)) + else: + self.file.write("%i %i %i %i -1, " % (fv[0], fv[1], fv[2], fv[3])) + # self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index)) + + self.file.write("\">\n") + else: + #-- vertices + # mesh.transform(ob.matrixWorld) + self.writeIndented("") + self.writeIndented("\n", -1) + + def writeTextureCoordinates(self, mesh): + texCoordList=[] + texIndexList=[] + j=0 + + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3] + + for uv in uvs: + # for uv in face.uv: + texIndexList.append(j) + texCoordList.append(uv) + j=j+1 + texIndexList.append(-1) + if self.writingtexture == 0: + self.file.write("\n\t\t\ttexCoordIndex=\"") + texIndxStr="" + for i in range(len(texIndexList)): + texIndxStr = texIndxStr + "%d, " % texIndexList[i] + if texIndexList[i]==-1: + self.file.write(texIndxStr) + texIndxStr="" + self.file.write("\"\n\t\t\t") + else: + self.writeIndented("") + self.writeIndented("\n", -1) + + def writeFaceColors(self, mesh): + if self.writingcolor == 0: + self.file.write("colorPerVertex=\"false\" ") + elif mesh.active_vertex_color: + # else: + self.writeIndented(" 2: + print("Debug: face.col r=%d g=%d b=%d" % (c[0], c[1], c[2])) + # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) + aColor = self.rgbToFS(c) + self.file.write("%s, " % aColor) + + # for face in mesh.faces: + # if face.col: + # c=face.col[0] + # if self.verbose > 2: + # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)) + # aColor = self.rgbToFS(c) + # self.file.write("%s, " % aColor) + self.file.write("\" />") + self.writeIndented("\n",-1) + + def writeMaterial(self, mat, matName, world): + # look up material name, use it if available + if matName in self.matNames: + self.writeIndented("\n" % matName) + self.matNames[matName]+=1 + return; + + self.matNames[matName]=1 + + ambient = mat.ambient/3 + # ambient = mat.amb/3 + diffuseR, diffuseG, diffuseB = tuple(mat.diffuse_color) + # diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] + if world: + ambi = world.ambient_color + # ambi = world.getAmb() + ambi0, ambi1, ambi2 = (ambi[0]*mat.ambient)*2, (ambi[1]*mat.ambient)*2, (ambi[2]*mat.ambient)*2 + # ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 + else: + ambi0, ambi1, ambi2 = 0, 0, 0 + emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2 + + shininess = mat.specular_hardness/512.0 + # shininess = mat.hard/512.0 + specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_reflection+0.001)) + # specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001)) + specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_reflection+0.001)) + # specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001)) + specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_reflection+0.001)) + # specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001)) + transp = 1-mat.alpha + # matFlags = mat.getMode() + if mat.shadeless: + # if matFlags & Blender.Material.Modes['SHADELESS']: + ambient = 1 + shine = 1 + specR = emitR = diffuseR + specG = emitG = diffuseG + specB = emitB = diffuseB + self.writeIndented("" % (round(transp,self.cp))) + self.writeIndented("\n",-1) + + def writeImageTexture(self, image): + name = image.name + filename = image.filename.split('/')[-1].split('\\')[-1] + if name in self.texNames: + self.writeIndented("\n" % self.cleanStr(name)) + self.texNames[name] += 1 + return + else: + self.writeIndented("" % name) + self.writeIndented("\n",-1) + self.texNames[name] = 1 + + def writeBackground(self, world, alltextures): + if world: worldname = world.name + else: return + blending = (world.blend_sky, world.paper_sky, world.real_sky) + # blending = world.getSkytype() + grd = world.horizon_color + # grd = world.getHor() + grd0, grd1, grd2 = grd[0], grd[1], grd[2] + sky = world.zenith_color + # sky = world.getZen() + sky0, sky1, sky2 = sky[0], sky[1], sky[2] + mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2] + mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2 + self.file.write("\n\n") + +########################################################## +# export routine +########################################################## + + def export(self, scene, world, alltextures,\ + EXPORT_APPLY_MODIFIERS = False,\ + EXPORT_TRI= False,\ + ): + + print("Info: starting X3D export to " + self.filename + "...") + self.writeHeader() + # self.writeScript() + self.writeNavigationInfo(scene) + self.writeBackground(world, alltextures) + self.writeFog(world) + self.proto = 0 + + + # # COPIED FROM OBJ EXPORTER + # if EXPORT_APPLY_MODIFIERS: + # temp_mesh_name = '~tmp-mesh' + + # # Get the container mesh. - used for applying modifiers and non mesh objects. + # containerMesh = meshName = tempMesh = None + # for meshName in Blender.NMesh.GetNames(): + # if meshName.startswith(temp_mesh_name): + # tempMesh = Mesh.Get(meshName) + # if not tempMesh.users: + # containerMesh = tempMesh + # if not containerMesh: + # containerMesh = Mesh.New(temp_mesh_name) + # -------------------------- + + + for ob_main in [o for o in scene.objects if o.is_visible()]: + # for ob_main in scene.objects.context: + + free, derived = create_derived_objects(ob_main) + + if derived == None: continue + + for ob, ob_mat in derived: + # for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): + objType=ob.type + objName=ob.name + self.matonly = 0 + if objType == "CAMERA": + # if objType == "Camera": + self.writeViewpoint(ob, ob_mat, scene) + elif objType in ("MESH", "CURVE", "SURF", "TEXT") : + # elif objType in ("Mesh", "Curve", "Surf", "Text") : + if EXPORT_APPLY_MODIFIERS or objType != 'MESH': + # if EXPORT_APPLY_MODIFIERS or objType != 'Mesh': + me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW') + # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene) + else: + me = ob.data + # me = ob.getData(mesh=1) + + self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI) + + # free mesh created with create_mesh() + if me != ob.data: + bpy.data.remove_mesh(me) + + elif objType == "LAMP": + # elif objType == "Lamp": + data= ob.data + datatype=data.type + if datatype == 'POINT': + # if datatype == Lamp.Types.Lamp: + self.writePointLight(ob, ob_mat, data, world) + elif datatype == 'SPOT': + # elif datatype == Lamp.Types.Spot: + self.writeSpotLight(ob, ob_mat, data, world) + elif datatype == 'SUN': + # elif datatype == Lamp.Types.Sun: + self.writeDirectionalLight(ob, ob_mat, data, world) + else: + self.writeDirectionalLight(ob, ob_mat, data, world) + # do you think x3d could document what to do with dummy objects? + #elif objType == "Empty" and objName != "Empty": + # self.writeNode(ob, ob_mat) + else: + #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType) + pass + + if free: + free_derived_objects(ob_main) + + self.file.write("\n\n") + + # if EXPORT_APPLY_MODIFIERS: + # if containerMesh: + # containerMesh.verts = None + + self.cleanup() + +########################################################## +# Utility methods +########################################################## + + def cleanup(self): + self.file.close() + self.texNames={} + self.matNames={} + self.indentLevel=0 + print("Info: finished X3D export to %s\n" % self.filename) + + def cleanStr(self, name, prefix='rsvd_'): + """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name""" + + newName=name[:] + if len(newName) == 0: + self.nNodeID+=1 + return "%s%d" % (prefix, self.nNodeID) + + if newName in self.namesReserved: + newName='%s%s' % (prefix,newName) + + if newName[0].isdigit(): + newName='%s%s' % ('_',newName) + + for bad in [' ','"','#',"'",',','.','[','\\',']','{','}']: + newName=newName.replace(bad,'_') + return newName + + def countIFSSetsNeeded(self, mesh, imageMap, sided, vColors): + """ + countIFFSetsNeeded() - should look at a blender mesh to determine + how many VRML IndexFaceSets or IndexLineSets are needed. A + new mesh created under the following conditions: + + o - split by UV Textures / one per mesh + o - split by face, one sided and two sided + o - split by smooth and flat faces + o - split when faces only have 2 vertices * needs to be an IndexLineSet + """ + + imageNameMap={} + faceMap={} + nFaceIndx=0 + + if mesh.active_uv_texture: + # if mesh.faceUV: + for face in mesh.active_uv_texture.data: + # for face in mesh.faces: + sidename=''; + if face.twoside: + # if face.mode & Mesh.FaceModes.TWOSIDE: + sidename='two' + else: + sidename='one' + + if sidename in sided: + sided[sidename]+=1 + else: + sided[sidename]=1 + + image = face.image + if image: + faceName="%s_%s" % (face.image.name, sidename); + try: + imageMap[faceName].append(face) + except: + imageMap[faceName]=[face.image.name,sidename,face] + + if self.verbose > 2: + for faceName in imageMap.keys(): + ifs=imageMap[faceName] + print("Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \ + (faceName, ifs[0], ifs[1], len(ifs)-2)) + + return len(imageMap) + + def faceToString(self,face): + + print("Debug: face.flag=0x%x (bitflags)" % face.flag) + if face.sel: + print("Debug: face.sel=true") + + print("Debug: face.mode=0x%x (bitflags)" % face.mode) + if face.mode & Mesh.FaceModes.TWOSIDE: + print("Debug: face.mode twosided") + + print("Debug: face.transp=0x%x (enum)" % face.transp) + if face.transp == Mesh.FaceTranspModes.SOLID: + print("Debug: face.transp.SOLID") + + if face.image: + print("Debug: face.image=%s" % face.image.name) + print("Debug: face.materialIndex=%d" % face.materialIndex) + + # XXX not used + # def getVertexColorByIndx(self, mesh, indx): + # c = None + # for face in mesh.faces: + # j=0 + # for vertex in face.v: + # if vertex.index == indx: + # c=face.col[j] + # break + # j=j+1 + # if c: break + # return c + + def meshToString(self,mesh): + # print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors) + print("Debug: mesh.faceUV=%d" % (len(mesh.uv_textures) > 0)) + # print("Debug: mesh.faceUV=%d" % mesh.faceUV) + print("Debug: mesh.hasVertexColours=%d" % (len(mesh.vertex_colors) > 0)) + # print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()) + print("Debug: mesh.verts=%d" % len(mesh.verts)) + print("Debug: mesh.faces=%d" % len(mesh.faces)) + print("Debug: mesh.materials=%d" % len(mesh.materials)) + + def rgbToFS(self, c): + s="%s %s %s" % (round(c[0]/255.0,self.cp), + round(c[1]/255.0,self.cp), + round(c[2]/255.0,self.cp)) + + # s="%s %s %s" % ( + # round(c.r/255.0,self.cp), + # round(c.g/255.0,self.cp), + # round(c.b/255.0,self.cp)) + return s + + def computeDirection(self, mtx): + x,y,z=(0,-1.0,0) # point down + + ax,ay,az = (mtx*MATWORLD).toEuler() + + # ax *= DEG2RAD + # ay *= DEG2RAD + # az *= DEG2RAD + + # rot X + x1=x + y1=y*math.cos(ax)-z*math.sin(ax) + z1=y*math.sin(ax)+z*math.cos(ax) + + # rot Y + x2=x1*math.cos(ay)+z1*math.sin(ay) + y2=y1 + z2=z1*math.cos(ay)-x1*math.sin(ay) + + # rot Z + x3=x2*math.cos(az)-y2*math.sin(az) + y3=x2*math.sin(az)+y2*math.cos(az) + z3=z2 + + return [x3,y3,z3] + + + # swap Y and Z to handle axis difference between Blender and VRML + #------------------------------------------------------------------------ + def rotatePointForVRML(self, v): + x = v[0] + y = v[2] + z = -v[1] + + vrmlPoint=[x, y, z] + return vrmlPoint + + # For writing well formed VRML code + #------------------------------------------------------------------------ + def writeIndented(self, s, inc=0): + if inc < 1: + self.indentLevel = self.indentLevel + inc + + spaces="" + for x in range(self.indentLevel): + spaces = spaces + "\t" + self.file.write(spaces + s) + + if inc > 0: + self.indentLevel = self.indentLevel + inc + + # Converts a Euler to three new Quaternions + # Angles of Euler are passed in as radians + #------------------------------------------------------------------------ + def eulerToQuaternions(self, x, y, z): + Qx = [math.cos(x/2), math.sin(x/2), 0, 0] + Qy = [math.cos(y/2), 0, math.sin(y/2), 0] + Qz = [math.cos(z/2), 0, 0, math.sin(z/2)] + + quaternionVec=[Qx,Qy,Qz] + return quaternionVec + + # Multiply two Quaternions together to get a new Quaternion + #------------------------------------------------------------------------ + def multiplyQuaternions(self, Q1, Q2): + result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])), + ((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])), + ((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])), + ((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))] + + return result + + # Convert a Quaternion to an Angle Axis (ax, ay, az, angle) + # angle is in radians + #------------------------------------------------------------------------ + def quaternionToAngleAxis(self, Qf): + scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2) + ax = Qf[1] + ay = Qf[2] + az = Qf[3] + + if scale > .0001: + ax/=scale + ay/=scale + az/=scale + + angle = 2 * math.acos(Qf[0]) + + result = [ax, ay, az, angle] + return result + +########################################################## +# Callbacks, needed before Main +########################################################## + +def x3d_export(filename, + context, + EXPORT_APPLY_MODIFIERS=False, + EXPORT_TRI=False, + EXPORT_GZIP=False): + + if EXPORT_GZIP: + if not filename.lower().endswith('.x3dz'): + filename = '.'.join(filename.split('.')[:-1]) + '.x3dz' + else: + if not filename.lower().endswith('.x3d'): + filename = '.'.join(filename.split('.')[:-1]) + '.x3d' + + + scene = context.scene + # scene = Blender.Scene.GetCurrent() + world = scene.world + + # XXX these are global textures while .Get() returned only scene's? + alltextures = bpy.data.textures + # alltextures = Blender.Texture.Get() + + wrlexport=x3d_class(filename) + wrlexport.export(\ + scene,\ + world,\ + alltextures,\ + \ + EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\ + EXPORT_TRI = EXPORT_TRI,\ + ) + + +def x3d_export_ui(filename): + if not filename.endswith(extension): + filename += extension + #if _safeOverwrite and sys.exists(filename): + # result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0") + #if(result != 1): + # return + + # Get user options + EXPORT_APPLY_MODIFIERS = Draw.Create(1) + EXPORT_TRI = Draw.Create(0) + EXPORT_GZIP = Draw.Create( filename.lower().endswith('.x3dz') ) + + # Get USER Options + pup_block = [\ + ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object.'),\ + ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\ + ('Compress', EXPORT_GZIP, 'GZip the resulting file, requires a full python install'),\ + ] + + if not Draw.PupBlock('Export...', pup_block): + return + + Blender.Window.EditMode(0) + Blender.Window.WaitCursor(1) + + x3d_export(filename,\ + EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val,\ + EXPORT_TRI = EXPORT_TRI.val,\ + EXPORT_GZIP = EXPORT_GZIP.val\ + ) + + Blender.Window.WaitCursor(0) + + + +######################################################### +# main routine +######################################################### + + +# if __name__ == '__main__': +# Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) + +class EXPORT_OT_x3d(bpy.types.Operator): + ''' + X3D Exporter + ''' + __idname__ = "export.x3d" + __label__ = 'Export X3D' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen=1024, default=""), + + bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True), + bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False), + bpy.props.BoolProperty(attr="compress", name="Compress", description="GZip the resulting file, requires a full python install.", default=False), + ] + + def execute(self, context): + x3d_export(self.filename, context, self.apply_modifiers, self.triangulate, self.compress) + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + def poll(self, context): # Poll isnt working yet + print("Poll") + return context.active_object != None + +bpy.ops.add(EXPORT_OT_x3d) + +# NOTES +# - blender version is hardcoded diff --git a/release/scripts/io/import_3ds.py b/release/scripts/io/import_3ds.py new file mode 100644 index 00000000000..99825471764 --- /dev/null +++ b/release/scripts/io/import_3ds.py @@ -0,0 +1,1166 @@ +#!BPY +""" +Name: '3D Studio (.3ds)...' +Blender: 244 +Group: 'Import' +Tooltip: 'Import from 3DS file format (.3ds)' +""" + +__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin'] +__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") +__version__= '0.996' +__bpydoc__= '''\ + +3ds Importer + +This script imports a 3ds file and the materials into Blender for editing. + +Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). + +0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200
+ - Implemented workaround to correct association between name, geometry and materials of + imported meshes. + + Without this patch, version 0.995 of this importer would associate to each mesh object the + geometry and the materials of the previously parsed mesh object. By so, the name of the + first mesh object would be thrown away, and the name of the last mesh object would be + automatically merged with a '.001' at the end. No object would desappear, however object's + names and materials would be completely jumbled. + +0.995 by Campbell Barton
+- workaround for buggy mesh vert delete +- minor tweaks + +0.99 by Bob Holcomb
+- added support for floating point color values that previously broke on import. + +0.98 by Campbell Barton
+- import faces and verts to lists instead of a mesh, convert to a mesh later +- use new index mapping feature of mesh to re-map faces that were not added. + +0.97 by Campbell Barton
+- Strip material names of spaces +- Added import as instance to import the 3ds into its own + scene and add a group instance to the current scene +- New option to scale down imported objects so they are within a limited bounding area. + +0.96 by Campbell Barton
+- Added workaround for bug in setting UV's for Zero vert index UV faces. +- Removed unique name function, let blender make the names unique. + +0.95 by Campbell Barton
+- Removed workarounds for Blender 2.41 +- Mesh objects split by material- many 3ds objects used more then 16 per mesh. +- Removed a lot of unneeded variable creation. + +0.94 by Campbell Barton
+- Face import tested to be about overall 16x speedup over 0.93. +- Material importing speedup. +- Tested with more models. +- Support some corrupt models. + +0.93 by Campbell Barton
+- Tested with 400 3ds files from turbosquid and samples. +- Tactfully ignore faces that used the same verts twice. +- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading. +- Converted from NMesh to Mesh. +- Faster and cleaner new names. +- Use external comprehensive image loader. +- Re intergrated 0.92 and 0.9 changes +- Fixes for 2.41 compat. +- Non textured faces do not use a texture flag. + +0.92
+- Added support for diffuse, alpha, spec, bump maps in a single material + +0.9
+- Reorganized code into object/material block functions
+- Use of Matrix() to copy matrix data
+- added support for material transparency
+ +0.83 2005-08-07: Campell Barton +- Aggressive image finding and case insensitivy for posisx systems. + +0.82a 2005-07-22 +- image texture loading (both for face uv and renderer) + +0.82 - image texture loading (for face uv) + +0.81a (fork- not 0.9) Campbell Barton 2005-06-08 +- Simplified import code +- Never overwrite data +- Faster list handling +- Leaves import selected + +0.81 Damien McGinnes 2005-01-09 +- handle missing images better + +0.8 Damien McGinnes 2005-01-08 +- copies sticky UV coords to face ones +- handles images better +- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script + +''' + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Bob Holcomb +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +# Importing modules + +import os +import time +import struct + +from import_obj import unpack_face_list, load_image + +import bpy +import Mathutils + +# import Blender +# from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils +# from Blender.Mathutils import Vector +# import BPyImage + +# import BPyMessages + +# try: +# from struct import calcsize, unpack +# except: +# calcsize= unpack= None + + + +# # If python version is less than 2.4, try to get set stuff from module +# try: +# set +# except: +# from sets import Set as set + +BOUNDS_3DS = [] + + +#this script imports uvcoords as sticky vertex coords +#this parameter enables copying these to face uv coords +#which shold be more useful. + +def createBlenderTexture(material, name, image): + texture = bpy.data.textures.new(name) + texture.setType('Image') + texture.image = image + material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) + + + +###################################################### +# Data Structures +###################################################### + +#Some of the chunks that we will see +#----- Primary Chunk, at the beginning of each file +PRIMARY = int('0x4D4D',16) + +#------ Main Chunks +OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information +VERSION = int('0x0002',16); #This gives the version of the .3ds file +EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info + +#------ sub defines of OBJECTINFO +MATERIAL = 45055 #0xAFFF // This stored the texture info +OBJECT = 16384 #0x4000 // This stores the faces, vertices, etc... + +#>------ sub defines of MATERIAL +#------ sub defines of MATERIAL_BLOCK +MAT_NAME = int('0xA000',16) # This holds the material name +MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material +MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material +MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material +MAT_SHINESS = int('0xA040',16) # ?? +MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material +MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material +MAT_WIRE = int('0xA085',16) # Only render's wireframe + +MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map +MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map +MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map +MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map +MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map +MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture + +MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats +MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes + +#>------ sub defines of OBJECT +OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object +OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object +OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght. +OBJECT_LAMP_OFF = int('0x4620',16); # The light off. +OBJECT_LAMP_ATTENUATE = int('0x4625',16); +OBJECT_LAMP_RAYSHADE = int('0x4627',16); +OBJECT_LAMP_SHADOWED = int('0x4630',16); +OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16); +OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16); +OBJECT_LAMP_SEE_CONE = int('0x4650',16); +OBJECT_LAMP_SPOT_RECTANGULAR = int('0x4651',16); +OBJECT_LAMP_SPOT_OVERSHOOT = int('0x4652',16); +OBJECT_LAMP_SPOT_PROJECTOR = int('0x4653',16); +OBJECT_LAMP_EXCLUDE = int('0x4654',16); +OBJECT_LAMP_RANGE = int('0x4655',16); +OBJECT_LAMP_ROLL = int('0x4656',16); +OBJECT_LAMP_SPOT_ASPECT = int('0x4657',16); +OBJECT_LAMP_RAY_BIAS = int('0x4658',16); +OBJECT_LAMP_INNER_RANGE = int('0x4659',16); +OBJECT_LAMP_OUTER_RANGE = int('0x465A',16); +OBJECT_LAMP_MULTIPLIER = int('0x465B',16); +OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16); + + + +OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object + +#>------ sub defines of CAMERA +OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values + +#>------ sub defines of OBJECT_MESH +OBJECT_VERTICES = int('0x4110',16); # The objects vertices +OBJECT_FACES = int('0x4120',16); # The objects faces +OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color +OBJECT_UV = int('0x4140',16); # The UV texture coordinates +OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix + +global scn +scn = None + +#the chunk class +class chunk: + ID = 0 + length = 0 + bytes_read = 0 + + #we don't read in the bytes_read, we compute that + binary_format=' 3): + print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version) + + #is it an object info chunk? + elif (new_chunk.ID == OBJECTINFO): + #print 'elif (new_chunk.ID == OBJECTINFO):' + # print 'found an OBJECTINFO chunk' + process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH) + + #keep track of how much we read in the main chunk + new_chunk.bytes_read += temp_chunk.bytes_read + + #is it an object chunk? + elif (new_chunk.ID == OBJECT): + + if CreateBlenderObject: + putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) + contextMesh_vertls = []; contextMesh_facels = [] + + ## preparando para receber o proximo objeto + contextMeshMaterials = {} # matname:[face_idxs] + contextMeshUV = None + #contextMesh.vertexUV = 1 # Make sticky coords. + # Reset matrix + contextMatrix_rot = None + #contextMatrix_tx = None + + CreateBlenderObject = True + tempName = read_string(file) + contextObName = tempName + new_chunk.bytes_read += len(tempName)+1 + + #is it a material chunk? + elif (new_chunk.ID == MATERIAL): + +# print("read material") + + #print 'elif (new_chunk.ID == MATERIAL):' + contextMaterial = bpy.data.add_material('Material') +# contextMaterial = bpy.data.materials.new('Material') + + elif (new_chunk.ID == MAT_NAME): + #print 'elif (new_chunk.ID == MAT_NAME):' + material_name = read_string(file) + +# print("material name", material_name) + + #plus one for the null character that ended the string + new_chunk.bytes_read += len(material_name)+1 + + contextMaterial.name = material_name.rstrip() # remove trailing whitespace + MATDICT[material_name]= (contextMaterial.name, contextMaterial) + + elif (new_chunk.ID == MAT_AMBIENT): + #print 'elif (new_chunk.ID == MAT_AMBIENT):' + read_chunk(file, temp_chunk) + if (temp_chunk.ID == MAT_FLOAT_COLOR): + contextMaterial.mirror_color = read_float_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3f')) +# temp_chunk.bytes_read += 12 +# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] + elif (temp_chunk.ID == MAT_24BIT_COLOR): + contextMaterial.mirror_color = read_byte_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3B')) +# temp_chunk.bytes_read += 3 +# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb + else: + skip_to_end(file, temp_chunk) + new_chunk.bytes_read += temp_chunk.bytes_read + + elif (new_chunk.ID == MAT_DIFFUSE): + #print 'elif (new_chunk.ID == MAT_DIFFUSE):' + read_chunk(file, temp_chunk) + if (temp_chunk.ID == MAT_FLOAT_COLOR): + contextMaterial.diffuse_color = read_float_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3f')) +# temp_chunk.bytes_read += 12 +# contextMaterial.rgbCol = [float(col) for col in struct.unpack('<3f', temp_data)] + elif (temp_chunk.ID == MAT_24BIT_COLOR): + contextMaterial.diffuse_color = read_byte_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3B')) +# temp_chunk.bytes_read += 3 +# contextMaterial.rgbCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb + else: + skip_to_end(file, temp_chunk) + +# print("read material diffuse color", contextMaterial.diffuse_color) + + new_chunk.bytes_read += temp_chunk.bytes_read + + elif (new_chunk.ID == MAT_SPECULAR): + #print 'elif (new_chunk.ID == MAT_SPECULAR):' + read_chunk(file, temp_chunk) + if (temp_chunk.ID == MAT_FLOAT_COLOR): + contextMaterial.specular_color = read_float_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3f')) +# temp_chunk.bytes_read += 12 +# contextMaterial.mirCol = [float(col) for col in struct.unpack('<3f', temp_data)] + elif (temp_chunk.ID == MAT_24BIT_COLOR): + contextMaterial.specular_color = read_byte_color(temp_chunk) +# temp_data = file.read(struct.calcsize('3B')) +# temp_chunk.bytes_read += 3 +# contextMaterial.mirCol = [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb + else: + skip_to_end(file, temp_chunk) + new_chunk.bytes_read += temp_chunk.bytes_read + + elif (new_chunk.ID == MAT_TEXTURE_MAP): + read_texture(new_chunk, temp_chunk, "Diffuse", "COLOR") +# #print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):' +# new_texture= bpy.data.textures.new('Diffuse') +# new_texture.setType('Image') +# img = None +# while (new_chunk.bytes_read BOUNDS_3DS[i + 3]: + BOUNDS_3DS[i + 3]= v[i] # min + + # Get the max axis x/y/z + max_axis = max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2]) + # print max_axis + if max_axis < 1 << 30: # Should never be false but just make sure. + + # Get a new scale factor if set as an option + SCALE = 1.0 + while (max_axis * SCALE) > IMPORT_CONSTRAIN_BOUNDS: + SCALE/=10 + + # SCALE Matrix + SCALE_MAT = Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) +# SCALE_MAT = Blender.Mathutils.Matrix([SCALE,0,0,0],[0,SCALE,0,0],[0,0,SCALE,0],[0,0,0,1]) + + for ob in importedObjects: + ob.setMatrix(ob.matrixWorld * SCALE_MAT) + + # Done constraining to bounds. + + # Select all new objects. + print('finished importing: "%s" in %.4f sec.' % (filename, (time.clock()-time1))) +# print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1))) + file.close() +# Blender.Window.WaitCursor(0) + + +DEBUG = False +# if __name__=='__main__' and not DEBUG: +# if calcsize == None: +# Blender.Draw.PupMenu('Error%t|a full python installation not found') +# else: +# Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') + +# For testing compatibility +#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False) +#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False) +''' + +else: + import os + # DEBUG ONLY + TIME = Blender.sys.time() + import os + print 'Searching for files' + os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') + # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') + print '...Done' + file = open('/tmp/temp3ds_list', 'r') + lines = file.readlines() + file.close() + # sort by filesize for faster testing + lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] + lines_size.sort() + lines = [f[1] for f in lines_size] + + + def between(v,a,b): + if v <= max(a,b) and v >= min(a,b): + return True + return False + + for i, _3ds in enumerate(lines): + if between(i, 650,800): + #_3ds= _3ds[:-1] + print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines) + _3ds_file= _3ds.split('/')[-1].split('\\')[-1] + newScn = Blender.Scene.New(_3ds_file) + newScn.makeCurrent() + load_3ds(_3ds, False) + + print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) + +''' + +class IMPORT_OT_3ds(bpy.types.Operator): + ''' + 3DS Importer + ''' + __idname__ = "import.3ds" + __label__ = 'Import 3DS' + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen=1024, default= ""), +# bpy.props.FloatProperty(attr="size_constraint", name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0), +# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True), +# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False), + ] + + def execute(self, context): + load_3ds(self.filename, context, 0.0, False, False) + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + ''' + def poll(self, context): + print("Poll") + return context.active_object != None''' + +bpy.ops.add(IMPORT_OT_3ds) + +# NOTES: +# why add 1 extra vertex? and remove it when done? +# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time) diff --git a/release/scripts/io/import_obj.py b/release/scripts/io/import_obj.py new file mode 100644 index 00000000000..9a00dc1cc2a --- /dev/null +++ b/release/scripts/io/import_obj.py @@ -0,0 +1,1633 @@ +#!BPY + +""" +Name: 'Wavefront (.obj)...' +Blender: 249 +Group: 'Import' +Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' +""" + +__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" +__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] +__version__= "2.11" + +__bpydoc__= """\ +This script imports a Wavefront OBJ files to Blender. + +Usage: +Run this script from "File->Import" menu and then load the desired OBJ file. +Note, This loads mesh objects and materials only, nurbs and curves are not supported. +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Campbell J Barton 2007 +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +import os +import time +import bpy +import Mathutils +import Geometry + +# from Blender import Mesh, Draw, Window, Texture, Material, sys +# # import BPyMesh +# import BPyImage +# import BPyMessages + +# try: import os +# except: os= False + +# Generic path functions +def stripFile(path): + '''Return directory, where the file is''' + lastSlash= max(path.rfind('\\'), path.rfind('/')) + if lastSlash != -1: + path= path[:lastSlash] + return '%s%s' % (path, os.sep) +# return '%s%s' % (path, sys.sep) + +def stripPath(path): + '''Strips the slashes from the back of a string''' + return path.split('/')[-1].split('\\')[-1] + +def stripExt(name): # name is a string + '''Strips the prefix off the name before writing''' + index= name.rfind('.') + if index != -1: + return name[ : index ] + else: + return name +# end path funcs + +def unpack_list(list_of_tuples): + l = [] + for t in list_of_tuples: + l.extend(t) + return l + +# same as above except that it adds 0 for triangle faces +def unpack_face_list(list_of_tuples): + l = [] + for t in list_of_tuples: + face = [i for i in t] + if len(face) != 3 and len(face) != 4: + raise RuntimeError("{0} vertices in face.".format(len(face))) + if len(face) == 3: + face.append(0) + l.extend(face) + return l + +def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True): + ''' + Takes a polyline of indices (fgon) + and returns a list of face indicie lists. + Designed to be used for importers that need indices for an fgon to create from existing verts. + + from_data: either a mesh, or a list/tuple of vectors. + indices: a list of indicies to use this list is the ordered closed polyline to fill, and can be a subset of the data given. + PREF_FIX_LOOPS: If this is enabled polylines that use loops to make multiple polylines are delt with correctly. + ''' + + if not set: # Need sets for this, otherwise do a normal fill. + PREF_FIX_LOOPS= False + + Vector= Mathutils.Vector + if not indices: + return [] + + # return [] + def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6) + def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length + + def vert_treplet(v, i): + return v, rvec(v), i, mlen(v) + + def ed_key_mlen(v1, v2): + if v1[3] > v2[3]: + return v2[1], v1[1] + else: + return v1[1], v2[1] + + + if not PREF_FIX_LOOPS: + ''' + Normal single concave loop filling + ''' + if type(from_data) in (tuple, list): + verts= [Vector(from_data[i]) for ii, i in enumerate(indices)] + else: + verts= [from_data.verts[i].co for ii, i in enumerate(indices)] + + for i in range(len(verts)-1, 0, -1): # same as reversed(xrange(1, len(verts))): + if verts[i][1]==verts[i-1][0]: + verts.pop(i-1) + + fill= Geometry.PolyFill([verts]) + + else: + ''' + Seperate this loop into multiple loops be finding edges that are used twice + This is used by lightwave LWO files a lot + ''' + + if type(from_data) in (tuple, list): + verts= [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)] + else: + verts= [vert_treplet(from_data.verts[i].co, ii) for ii, i in enumerate(indices)] + + edges= [(i, i-1) for i in range(len(verts))] + if edges: + edges[0]= (0,len(verts)-1) + + if not verts: + return [] + + + edges_used= set() + edges_doubles= set() + # We need to check if any edges are used twice location based. + for ed in edges: + edkey= ed_key_mlen(verts[ed[0]], verts[ed[1]]) + if edkey in edges_used: + edges_doubles.add(edkey) + else: + edges_used.add(edkey) + + # Store a list of unconnected loop segments split by double edges. + # will join later + loop_segments= [] + + v_prev= verts[0] + context_loop= [v_prev] + loop_segments= [context_loop] + + for v in verts: + if v!=v_prev: + # Are we crossing an edge we removed? + if ed_key_mlen(v, v_prev) in edges_doubles: + context_loop= [v] + loop_segments.append(context_loop) + else: + if context_loop and context_loop[-1][1]==v[1]: + #raise "as" + pass + else: + context_loop.append(v) + + v_prev= v + # Now join loop segments + + def join_seg(s1,s2): + if s2[-1][1]==s1[0][1]: # + s1,s2= s2,s1 + elif s1[-1][1]==s2[0][1]: + pass + else: + return False + + # If were stuill here s1 and s2 are 2 segments in the same polyline + s1.pop() # remove the last vert from s1 + s1.extend(s2) # add segment 2 to segment 1 + + if s1[0][1]==s1[-1][1]: # remove endpoints double + s1.pop() + + s2[:]= [] # Empty this segment s2 so we dont use it again. + return True + + joining_segments= True + while joining_segments: + joining_segments= False + segcount= len(loop_segments) + + for j in range(segcount-1, -1, -1): #reversed(range(segcount)): + seg_j= loop_segments[j] + if seg_j: + for k in range(j-1, -1, -1): # reversed(range(j)): + if not seg_j: + break + seg_k= loop_segments[k] + + if seg_k and join_seg(seg_j, seg_k): + joining_segments= True + + loop_list= loop_segments + + for verts in loop_list: + while verts and verts[0][1]==verts[-1][1]: + verts.pop() + + loop_list= [verts for verts in loop_list if len(verts)>2] + # DONE DEALING WITH LOOP FIXING + + + # vert mapping + vert_map= [None]*len(indices) + ii=0 + for verts in loop_list: + if len(verts)>2: + for i, vert in enumerate(verts): + vert_map[i+ii]= vert[2] + ii+=len(verts) + + fill= Geometry.PolyFill([ [v[0] for v in loop] for loop in loop_list ]) + #draw_loops(loop_list) + #raise 'done loop' + # map to original indicies + fill= [[vert_map[i] for i in reversed(f)] for f in fill] + + + if not fill: + print('Warning Cannot scanfill, fallback on a triangle fan.') + fill= [ [0, i-1, i] for i in range(2, len(indices)) ] + else: + # Use real scanfill. + # See if its flipped the wrong way. + flip= None + for fi in fill: + if flip != None: + break + for i, vi in enumerate(fi): + if vi==0 and fi[i-1]==1: + flip= False + break + elif vi==1 and fi[i-1]==0: + flip= True + break + + if not flip: + for i, fi in enumerate(fill): + fill[i]= tuple([ii for ii in reversed(fi)]) + + return fill + +def line_value(line_split): + ''' + Returns 1 string represneting the value for this line + None will be returned if theres only 1 word + ''' + length= len(line_split) + if length == 1: + return None + + elif length == 2: + return line_split[1] + + elif length > 2: + return ' '.join( line_split[1:] ) + +# limited replacement for BPyImage.comprehensiveImageLoad +def load_image(imagepath, dirname): + + if os.path.exists(imagepath): + return bpy.data.add_image(imagepath) + + variants = [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))] + + for path in variants: + if os.path.exists(path): + return bpy.data.add_image(path) + else: + print(path, "doesn't exist") + + # TODO comprehensiveImageLoad also searched in bpy.config.textureDir + return None + +def obj_image_load(imagepath, DIR, IMAGE_SEARCH): + + if '_' in imagepath: + image= load_image(imagepath.replace('_', ' '), DIR) + if image: return image + + return load_image(imagepath, DIR) + +# def obj_image_load(imagepath, DIR, IMAGE_SEARCH): +# ''' +# Mainly uses comprehensiveImageLoad +# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores. +# ''' + +# if '_' in imagepath: +# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) +# if image: return image +# # Did the exporter rename the image? +# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH) +# if image: return image + +# # Return an image, placeholder if it dosnt exist +# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH) +# return image + + +def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH): + ''' + Create all the used materials in this obj, + assign colors and images to the materials from all referenced material libs + ''' + DIR= stripFile(filepath) + + #==================================================================================# + # This function sets textures defined in .mtl file # + #==================================================================================# + def load_material_image(blender_material, context_material_name, imagepath, type): + + texture= bpy.data.add_texture(type) + texture.type= 'IMAGE' +# texture= bpy.data.textures.new(type) +# texture.setType('Image') + + # Absolute path - c:\.. etc would work here + image= obj_image_load(imagepath, DIR, IMAGE_SEARCH) + has_data = image.has_data if image else False + + if image: + texture.image = image + + # Adds textures for materials (rendering) + if type == 'Kd': + if has_data and image.depth == 32: + # Image has alpha + + # XXX bitmask won't work? + blender_material.add_texture(texture, "UV", ("COLOR", "ALPHA")) + texture.mipmap = True + texture.interpolation = True + texture.use_alpha = True + blender_material.z_transparency = True + blender_material.alpha = 0.0 + +# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA) +# texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha') +# blender_material.mode |= Material.Modes.ZTRANSP +# blender_material.alpha = 0.0 + else: + blender_material.add_texture(texture, "UV", "COLOR") +# blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL) + + # adds textures to faces (Textured/Alt-Z mode) + # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func. + unique_material_images[context_material_name]= image, has_data # set the texface image + + elif type == 'Ka': + blender_material.add_texture(texture, "UV", "AMBIENT") +# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API + + elif type == 'Ks': + blender_material.add_texture(texture, "UV", "SPECULARITY") +# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC) + + elif type == 'Bump': + blender_material.add_texture(texture, "UV", "NORMAL") +# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR) + elif type == 'D': + blender_material.add_texture(texture, "UV", "ALPHA") + blender_material.z_transparency = True + blender_material.alpha = 0.0 +# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA) +# blender_material.mode |= Material.Modes.ZTRANSP +# blender_material.alpha = 0.0 + # Todo, unset deffuse material alpha if it has an alpha channel + + elif type == 'refl': + blender_material.add_texture(texture, "UV", "REFLECTION") +# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF) + + + # Add an MTL with the same name as the obj if no MTLs are spesified. + temp_mtl= stripExt(stripPath(filepath))+ '.mtl' + + if os.path.exists(DIR + temp_mtl) and temp_mtl not in material_libs: +# if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs: + material_libs.append( temp_mtl ) + del temp_mtl + + #Create new materials + for name in unique_materials: # .keys() + if name != None: + unique_materials[name]= bpy.data.add_material(name) +# unique_materials[name]= bpy.data.materials.new(name) + unique_material_images[name]= None, False # assign None to all material images to start with, add to later. + + unique_materials[None]= None + unique_material_images[None]= None, False + + for libname in material_libs: + mtlpath= DIR + libname + if not os.path.exists(mtlpath): +# if not sys.exists(mtlpath): + #print '\tError Missing MTL: "%s"' % mtlpath + pass + else: + #print '\t\tloading mtl: "%s"' % mtlpath + context_material= None + mtl= open(mtlpath, 'rU') + for line in mtl: #.xreadlines(): + if line.startswith('newmtl'): + context_material_name= line_value(line.split()) + if context_material_name in unique_materials: + context_material = unique_materials[ context_material_name ] + else: + context_material = None + + elif context_material: + # we need to make a material to assign properties to it. + line_split= line.split() + line_lower= line.lower().lstrip() + if line_lower.startswith('ka'): + context_material.mirror_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) +# context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + elif line_lower.startswith('kd'): + context_material.diffuse_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) +# context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + elif line_lower.startswith('ks'): + context_material.specular_color = (float(line_split[1]), float(line_split[2]), float(line_split[3])) +# context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3]))) + elif line_lower.startswith('ns'): + context_material.specular_hardness = int((float(line_split[1])*0.51)) +# context_material.setHardness( int((float(line_split[1])*0.51)) ) + elif line_lower.startswith('ni'): # Refraction index + context_material.ior = max(1, min(float(line_split[1]), 3)) +# context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3 + elif line_lower.startswith('d') or line_lower.startswith('tr'): + context_material.alpha = float(line_split[1]) +# context_material.setAlpha(float(line_split[1])) + elif line_lower.startswith('map_ka'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Ka') + elif line_lower.startswith('map_ks'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Ks') + elif line_lower.startswith('map_kd'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Kd') + elif line_lower.startswith('map_bump'): + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'Bump') + elif line_lower.startswith('map_d') or line_lower.startswith('map_tr'): # Alpha map - Dissolve + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'D') + + elif line_lower.startswith('refl'): # Reflectionmap + img_filepath= line_value(line.split()) + if img_filepath: + load_material_image(context_material, context_material_name, img_filepath, 'refl') + mtl.close() + + + + +def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): + ''' + Takes vert_loc and faces, and seperates into multiple sets of + (verts_loc, faces, unique_materials, dataname) + This is done so objects do not overload the 16 material limit. + ''' + + filename = stripExt(stripPath(filepath)) + + if not SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: + # use the filename for the object name since we arnt chopping up the mesh. + return [(verts_loc, faces, unique_materials, filename)] + + + def key_to_name(key): + # if the key is a tuple, join it to make a string + if type(key) == tuple: + return '%s_%s' % key + elif not key: + return filename # assume its a string. make sure this is true if the splitting code is changed + else: + return key + + # Return a key that makes the faces unique. + if SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS: + def face_key(face): + return face[4] # object + + elif not SPLIT_OB_OR_GROUP and SPLIT_MATERIALS: + def face_key(face): + return face[2] # material + + else: # Both + def face_key(face): + return face[4], face[2] # object,material + + + face_split_dict= {} + + oldkey= -1 # initialize to a value that will never match the key + + for face in faces: + + key= face_key(face) + + if oldkey != key: + # Check the key has changed. + try: + verts_split, faces_split, unique_materials_split, vert_remap= face_split_dict[key] + except KeyError: + faces_split= [] + verts_split= [] + unique_materials_split= {} + vert_remap= [-1]*len(verts_loc) + + face_split_dict[key]= (verts_split, faces_split, unique_materials_split, vert_remap) + + oldkey= key + + face_vert_loc_indicies= face[0] + + # Remap verts to new vert list and add where needed + for enum, i in enumerate(face_vert_loc_indicies): + if vert_remap[i] == -1: + new_index= len(verts_split) + vert_remap[i]= new_index # set the new remapped index so we only add once and can reference next time. + face_vert_loc_indicies[enum] = new_index # remap to the local index + verts_split.append( verts_loc[i] ) # add the vert to the local verts + + else: + face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index + + matname= face[2] + if matname and matname not in unique_materials_split: + unique_materials_split[matname] = unique_materials[matname] + + faces_split.append(face) + + + # remove one of the itemas and reorder + return [(value[0], value[1], value[2], key_to_name(key)) for key, value in list(face_split_dict.items())] + + +def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname): + ''' + Takes all the data gathered and generates a mesh, adding the new object to new_objects + deals with fgons, sharp edges and assigning materials + ''' + if not has_ngons: + CREATE_FGONS= False + + if unique_smooth_groups: + sharp_edges= {} + smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in list(unique_smooth_groups.keys()) ]) + context_smooth_group_old= -1 + + # Split fgons into tri's + fgon_edges= {} # Used for storing fgon keys + if CREATE_EDGES: + edges= [] + + context_object= None + + # reverse loop through face indicies + for f_idx in range(len(faces)-1, -1, -1): + + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object= faces[f_idx] + + len_face_vert_loc_indicies = len(face_vert_loc_indicies) + + if len_face_vert_loc_indicies==1: + faces.pop(f_idx)# cant add single vert faces + + elif not face_vert_tex_indicies or len_face_vert_loc_indicies == 2: # faces that have no texture coords are lines + if CREATE_EDGES: + # generators are better in python 2.4+ but can't be used in 2.3 + # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) ) + edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in range(len_face_vert_loc_indicies-1)] ) + + faces.pop(f_idx) + else: + + # Smooth Group + if unique_smooth_groups and context_smooth_group: + # Is a part of of a smooth group and is a face + if context_smooth_group_old is not context_smooth_group: + edge_dict= smooth_group_users[context_smooth_group] + context_smooth_group_old= context_smooth_group + + for i in range(len_face_vert_loc_indicies): + i1= face_vert_loc_indicies[i] + i2= face_vert_loc_indicies[i-1] + if i1>i2: i1,i2= i2,i1 + + try: + edge_dict[i1,i2]+= 1 + except KeyError: + edge_dict[i1,i2]= 1 + + # FGons into triangles + if has_ngons and len_face_vert_loc_indicies > 4: + + ngon_face_indices= BPyMesh_ngon(verts_loc, face_vert_loc_indicies) + faces.extend(\ + [(\ + [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\ + [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\ + context_material,\ + context_smooth_group,\ + context_object)\ + for ngon in ngon_face_indices]\ + ) + + # edges to make fgons + if CREATE_FGONS: + edge_users= {} + for ngon in ngon_face_indices: + for i in (0,1,2): + i1= face_vert_loc_indicies[ngon[i ]] + i2= face_vert_loc_indicies[ngon[i-1]] + if i1>i2: i1,i2= i2,i1 + + try: + edge_users[i1,i2]+=1 + except KeyError: + edge_users[i1,i2]= 1 + + for key, users in edge_users.items(): + if users>1: + fgon_edges[key]= None + + # remove all after 3, means we dont have to pop this one. + faces.pop(f_idx) + + + # Build sharp edges + if unique_smooth_groups: + for edge_dict in list(smooth_group_users.values()): + for key, users in list(edge_dict.items()): + if users==1: # This edge is on the boundry of a group + sharp_edges[key]= None + + + # map the material names to an index + material_mapping= dict([(name, i) for i, name in enumerate(unique_materials)]) # enumerate over unique_materials keys() + + materials= [None] * len(unique_materials) + + for name, index in list(material_mapping.items()): + materials[index]= unique_materials[name] + + me= bpy.data.add_mesh(dataname) +# me= bpy.data.meshes.new(dataname) + + # make sure the list isnt too big + for material in materials[0:16]: + me.add_material(material) +# me.materials= materials[0:16] # make sure the list isnt too big. + #me.verts.extend([(0,0,0)]) # dummy vert + + me.add_geometry(len(verts_loc), 0, len(faces)) + + # verts_loc is a list of (x, y, z) tuples + me.verts.foreach_set("co", unpack_list(verts_loc)) +# me.verts.extend(verts_loc) + + # faces is a list of (vert_indices, texco_indices, ...) tuples + # XXX faces should not contain edges + # XXX no check for valid face indices + me.faces.foreach_set("verts", unpack_face_list([f[0] for f in faces])) +# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True) + + if verts_tex and me.faces: + me.add_uv_texture() +# me.faceUV= 1 + # TEXMODE= Mesh.FaceModes['TEX'] + + context_material_old= -1 # avoid a dict lookup + mat= 0 # rare case it may be un-initialized. + me_faces= me.faces +# ALPHA= Mesh.FaceTranspModes.ALPHA + + for i, face in enumerate(faces): + if len(face[0]) < 2: + pass #raise "bad face" + elif len(face[0])==2: + if CREATE_EDGES: + edges.append(face[0]) + else: +# face_index_map= face_mapping[i] + + # since we use foreach_set to add faces, all of them are added + if 1: +# if face_index_map!=None: # None means the face wasnt added + + blender_face = me.faces[i] +# blender_face= me_faces[face_index_map] + + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object= face + + + + if context_smooth_group: + blender_face.smooth= True + + if context_material: + if context_material_old is not context_material: + mat= material_mapping[context_material] + if mat>15: + mat= 15 + context_material_old= context_material + + blender_face.material_index= mat +# blender_face.mat= mat + + + if verts_tex: + + blender_tface= me.uv_textures[0].data[i] + + if context_material: + image, has_data= unique_material_images[context_material] + if image: # Can be none if the material dosnt have an image. + blender_tface.image= image +# blender_face.image= image + if has_data: +# if has_data and image.depth == 32: + blender_tface.transp = 'ALPHA' +# blender_face.transp |= ALPHA + + # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled. + if len(face_vert_loc_indicies)==4: + if face_vert_loc_indicies[2]==0 or face_vert_loc_indicies[3]==0: + face_vert_tex_indicies= face_vert_tex_indicies[2], face_vert_tex_indicies[3], face_vert_tex_indicies[0], face_vert_tex_indicies[1] + else: # length of 3 + if face_vert_loc_indicies[2]==0: + face_vert_tex_indicies= face_vert_tex_indicies[1], face_vert_tex_indicies[2], face_vert_tex_indicies[0] + # END EEEKADOODLE FIX + + # assign material, uv's and image + blender_tface.uv1= verts_tex[face_vert_tex_indicies[0]] + blender_tface.uv2= verts_tex[face_vert_tex_indicies[1]] + blender_tface.uv3= verts_tex[face_vert_tex_indicies[2]] + + if blender_face.verts[3] != 0: + blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]] + +# for ii, uv in enumerate(blender_face.uv): +# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]] + del me_faces +# del ALPHA + + if CREATE_EDGES: + + me.add_geometry(0, len(edges), 0) + + # edges should be a list of (a, b) tuples + me.edges.foreach_set("verts", unpack_list(edges)) +# me_edges.extend( edges ) + +# del me_edges + + # Add edge faces. +# me_edges= me.edges + + def edges_match(e1, e2): + return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0]) + + # XXX slow +# if CREATE_FGONS and fgon_edges: +# for fgon_edge in fgon_edges.keys(): +# for ed in me.edges: +# if edges_match(fgon_edge, ed.verts): +# ed.fgon = True + +# if CREATE_FGONS and fgon_edges: +# FGON= Mesh.EdgeFlags.FGON +# for ed in me.findEdges( fgon_edges.keys() ): +# if ed!=None: +# me_edges[ed].flag |= FGON +# del FGON + + # XXX slow +# if unique_smooth_groups and sharp_edges: +# for sharp_edge in sharp_edges.keys(): +# for ed in me.edges: +# if edges_match(sharp_edge, ed.verts): +# ed.sharp = True + +# if unique_smooth_groups and sharp_edges: +# SHARP= Mesh.EdgeFlags.SHARP +# for ed in me.findEdges( sharp_edges.keys() ): +# if ed!=None: +# me_edges[ed].flag |= SHARP +# del SHARP + + me.update() +# me.calcNormals() + + ob= bpy.data.add_object("MESH", "Mesh") + ob.data= me + scn.add_object(ob) +# ob= scn.objects.new(me) + new_objects.append(ob) + + # Create the vertex groups. No need to have the flag passed here since we test for the + # content of the vertex_groups. If the user selects to NOT have vertex groups saved then + # the following test will never run + for group_name, group_indicies in vertex_groups.items(): + group= ob.add_vertex_group(group_name) +# me.addVertGroup(group_name) + for vertex_index in group_indicies: + ob.add_vertex_to_group(vertex_index, group, 1.0, 'REPLACE') +# me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE) + + +def create_nurbs(scn, context_nurbs, vert_loc, new_objects): + ''' + Add nurbs object to blender, only support one type at the moment + ''' + deg = context_nurbs.get('deg', (3,)) + curv_range = context_nurbs.get('curv_range', None) + curv_idx = context_nurbs.get('curv_idx', []) + parm_u = context_nurbs.get('parm_u', []) + parm_v = context_nurbs.get('parm_v', []) + name = context_nurbs.get('name', 'ObjNurb') + cstype = context_nurbs.get('cstype', None) + + if cstype == None: + print('\tWarning, cstype not found') + return + if cstype != 'bspline': + print('\tWarning, cstype is not supported (only bspline)') + return + if not curv_idx: + print('\tWarning, curv argument empty or not set') + return + if len(deg) > 1 or parm_v: + print('\tWarning, surfaces not supported') + return + + cu = bpy.data.curves.new(name, 'Curve') + cu.flag |= 1 # 3D curve + + nu = None + for pt in curv_idx: + + pt = vert_loc[pt] + pt = (pt[0], pt[1], pt[2], 1.0) + + if nu == None: + nu = cu.appendNurb(pt) + else: + nu.append(pt) + + nu.orderU = deg[0]+1 + + # get for endpoint flag from the weighting + if curv_range and len(parm_u) > deg[0]+1: + do_endpoints = True + for i in range(deg[0]+1): + + if abs(parm_u[i]-curv_range[0]) > 0.0001: + do_endpoints = False + break + + if abs(parm_u[-(i+1)]-curv_range[1]) > 0.0001: + do_endpoints = False + break + + else: + do_endpoints = False + + if do_endpoints: + nu.flagU |= 2 + + + # close + ''' + do_closed = False + if len(parm_u) > deg[0]+1: + for i in xrange(deg[0]+1): + #print curv_idx[i], curv_idx[-(i+1)] + + if curv_idx[i]==curv_idx[-(i+1)]: + do_closed = True + break + + if do_closed: + nu.flagU |= 1 + ''' + + ob = scn.objects.new(cu) + new_objects.append(ob) + + +def strip_slash(line_split): + if line_split[-1][-1]== '\\': + if len(line_split[-1])==1: + line_split.pop() # remove the \ item + else: + line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number + return True + return False + + + +def get_float_func(filepath): + ''' + find the float function for this obj file + - weather to replace commas or not + ''' + file= open(filepath, 'rU') + for line in file: #.xreadlines(): + line = line.lstrip() + if line.startswith('v'): # vn vt v + if ',' in line: + return lambda f: float(f.replace(',', '.')) + elif '.' in line: + return float + + # incase all vert values were ints + return float + +def load_obj(filepath, + context, + CLAMP_SIZE= 0.0, + CREATE_FGONS= True, + CREATE_SMOOTH_GROUPS= True, + CREATE_EDGES= True, + SPLIT_OBJECTS= True, + SPLIT_GROUPS= True, + SPLIT_MATERIALS= True, + ROTATE_X90= True, + IMAGE_SEARCH=True, + POLYGROUPS=False): + ''' + Called by the user interface or another script. + load_obj(path) - should give acceptable results. + This function passes the file and sends the data off + to be split into objects and then converted into mesh objects + ''' + print('\nimporting obj "%s"' % filepath) + + if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS: + POLYGROUPS = False + + time_main= time.time() +# time_main= sys.time() + + verts_loc= [] + verts_tex= [] + faces= [] # tuples of the faces + material_libs= [] # filanems to material libs this uses + vertex_groups = {} # when POLYGROUPS is true + + # Get the string to float conversion func for this file- is 'float' for almost all files. + float_func= get_float_func(filepath) + + # Context variables + context_material= None + context_smooth_group= None + context_object= None + context_vgroup = None + + # Nurbs + context_nurbs = {} + nurbs = [] + context_parm = '' # used by nurbs too but could be used elsewhere + + has_ngons= False + # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0 + + # Until we can use sets + unique_materials= {} + unique_material_images= {} + unique_smooth_groups= {} + # unique_obects= {} - no use for this variable since the objects are stored in the face. + + # when there are faces that end with \ + # it means they are multiline- + # since we use xreadline we cant skip to the next line + # so we need to know weather + context_multi_line= '' + + print('\tparsing obj file "%s"...' % filepath) + time_sub= time.time() +# time_sub= sys.time() + + file= open(filepath, 'rU') + for line in file: #.xreadlines(): + line = line.lstrip() # rare cases there is white space at the start of the line + + if line.startswith('v '): + line_split= line.split() + # rotate X90: (x,-z,y) + verts_loc.append( (float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])) ) + + elif line.startswith('vn '): + pass + + elif line.startswith('vt '): + line_split= line.split() + verts_tex.append( (float_func(line_split[1]), float_func(line_split[2])) ) + + # Handel faces lines (as faces) and the second+ lines of fa multiline face here + # use 'f' not 'f ' because some objs (very rare have 'fo ' for faces) + elif line.startswith('f') or context_multi_line == 'f': + + if context_multi_line: + # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face + line_split= line.split() + + else: + line_split= line[2:].split() + face_vert_loc_indicies= [] + face_vert_tex_indicies= [] + + # Instance a face + faces.append((\ + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object\ + )) + + if strip_slash(line_split): + context_multi_line = 'f' + else: + context_multi_line = '' + + for v in line_split: + obj_vert= v.split('/') + + vert_loc_index= int(obj_vert[0])-1 + # Add the vertex to the current group + # *warning*, this wont work for files that have groups defined around verts + if POLYGROUPS and context_vgroup: + vertex_groups[context_vgroup].append(vert_loc_index) + + # Make relative negative vert indicies absolute + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + face_vert_loc_indicies.append(vert_loc_index) + + if len(obj_vert)>1 and obj_vert[1]: + # formatting for faces with normals and textures us + # loc_index/tex_index/nor_index + + vert_tex_index= int(obj_vert[1])-1 + # Make relative negative vert indicies absolute + if vert_tex_index < 0: + vert_tex_index= len(verts_tex) + vert_tex_index + 1 + + face_vert_tex_indicies.append(vert_tex_index) + else: + # dummy + face_vert_tex_indicies.append(0) + + if len(face_vert_loc_indicies) > 4: + has_ngons= True + + elif CREATE_EDGES and (line.startswith('l ') or context_multi_line == 'l'): + # very similar to the face load function above with some parts removed + + if context_multi_line: + # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face + line_split= line.split() + + else: + line_split= line[2:].split() + face_vert_loc_indicies= [] + face_vert_tex_indicies= [] + + # Instance a face + faces.append((\ + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object\ + )) + + if strip_slash(line_split): + context_multi_line = 'l' + else: + context_multi_line = '' + + isline= line.startswith('l') + + for v in line_split: + vert_loc_index= int(v)-1 + + # Make relative negative vert indicies absolute + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + face_vert_loc_indicies.append(vert_loc_index) + + elif line.startswith('s'): + if CREATE_SMOOTH_GROUPS: + context_smooth_group= line_value(line.split()) + if context_smooth_group=='off': + context_smooth_group= None + elif context_smooth_group: # is not None + unique_smooth_groups[context_smooth_group]= None + + elif line.startswith('o'): + if SPLIT_OBJECTS: + context_object= line_value(line.split()) + # unique_obects[context_object]= None + + elif line.startswith('g'): + if SPLIT_GROUPS: + context_object= line_value(line.split()) + # print 'context_object', context_object + # unique_obects[context_object]= None + elif POLYGROUPS: + context_vgroup = line_value(line.split()) + if context_vgroup and context_vgroup != '(null)': + vertex_groups.setdefault(context_vgroup, []) + else: + context_vgroup = None # dont assign a vgroup + + elif line.startswith('usemtl'): + context_material= line_value(line.split()) + unique_materials[context_material]= None + elif line.startswith('mtllib'): # usemap or usemat + material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line + + + # Nurbs support + elif line.startswith('cstype '): + context_nurbs['cstype']= line_value(line.split()) # 'rat bspline' / 'bspline' + elif line.startswith('curv ') or context_multi_line == 'curv': + line_split= line.split() + + curv_idx = context_nurbs['curv_idx'] = context_nurbs.get('curv_idx', []) # incase were multiline + + if not context_multi_line: + context_nurbs['curv_range'] = float_func(line_split[1]), float_func(line_split[2]) + line_split[0:3] = [] # remove first 3 items + + if strip_slash(line_split): + context_multi_line = 'curv' + else: + context_multi_line = '' + + + for i in line_split: + vert_loc_index = int(i)-1 + + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + curv_idx.append(vert_loc_index) + + elif line.startswith('parm') or context_multi_line == 'parm': + line_split= line.split() + + if context_multi_line: + context_multi_line = '' + else: + context_parm = line_split[1] + line_split[0:2] = [] # remove first 2 + + if strip_slash(line_split): + context_multi_line = 'parm' + else: + context_multi_line = '' + + if context_parm.lower() == 'u': + context_nurbs.setdefault('parm_u', []).extend( [float_func(f) for f in line_split] ) + elif context_parm.lower() == 'v': # surfaces not suported yet + context_nurbs.setdefault('parm_v', []).extend( [float_func(f) for f in line_split] ) + # else: # may want to support other parm's ? + + elif line.startswith('deg '): + context_nurbs['deg']= [int(i) for i in line.split()[1:]] + elif line.startswith('end'): + # Add the nurbs curve + if context_object: + context_nurbs['name'] = context_object + nurbs.append(context_nurbs) + context_nurbs = {} + context_parm = '' + + ''' # How to use usemap? depricated? + elif line.startswith('usema'): # usemap or usemat + context_image= line_value(line.split()) + ''' + + file.close() + time_new= time.time() +# time_new= sys.time() + print('%.4f sec' % (time_new-time_sub)) + time_sub= time_new + + + print('\tloading materials and images...') + create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH) + + time_new= time.time() +# time_new= sys.time() + print('%.4f sec' % (time_new-time_sub)) + time_sub= time_new + + if not ROTATE_X90: + verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] + + # deselect all +# if context.selected_objects: +# bpy.ops.OBJECT_OT_select_all_toggle() + + scene = context.scene +# scn = bpy.data.scenes.active +# scn.objects.selected = [] + new_objects= [] # put new objects here + + print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) )) + # Split the mesh by objects/materials, may + if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True + else: SPLIT_OB_OR_GROUP = False + + for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS): + # Create meshes from the data, warning 'vertex_groups' wont support splitting + create_mesh(scene, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) + + # nurbs support +# for context_nurbs in nurbs: +# create_nurbs(scn, context_nurbs, verts_loc, new_objects) + + + axis_min= [ 1000000000]*3 + axis_max= [-1000000000]*3 + +# if CLAMP_SIZE: +# # Get all object bounds +# for ob in new_objects: +# for v in ob.getBoundBox(): +# for axis, value in enumerate(v): +# if axis_min[axis] > value: axis_min[axis]= value +# if axis_max[axis] < value: axis_max[axis]= value + +# # Scale objects +# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2]) +# scale= 1.0 + +# while CLAMP_SIZE < max_axis * scale: +# scale= scale/10.0 + +# for ob in new_objects: +# ob.setSize(scale, scale, scale) + + # Better rotate the vert locations + #if not ROTATE_X90: + # for ob in new_objects: + # ob.RotX = -1.570796326794896558 + + time_new= time.time() +# time_new= sys.time() + + print('%.4f sec' % (time_new-time_sub)) + print('finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main))) + + +DEBUG= True + + +def load_obj_ui(filepath, BATCH_LOAD= False): + if BPyMessages.Error_NoFile(filepath): + return + + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 + + CREATE_SMOOTH_GROUPS= Draw.Create(0) + CREATE_FGONS= Draw.Create(1) + CREATE_EDGES= Draw.Create(1) + SPLIT_OBJECTS= Draw.Create(0) + SPLIT_GROUPS= Draw.Create(0) + SPLIT_MATERIALS= Draw.Create(0) + CLAMP_SIZE= Draw.Create(10.0) + IMAGE_SEARCH= Draw.Create(1) + POLYGROUPS= Draw.Create(0) + KEEP_VERT_ORDER= Draw.Create(1) + ROTATE_X90= Draw.Create(1) + + + # Get USER Options + # Note, Works but not pretty, instead use a more complicated GUI + ''' + pup_block= [\ + 'Import...',\ + ('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\ + ('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\ + ('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\ + 'Separate objects from obj...',\ + ('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\ + ('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\ + ('Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)'),\ + 'Options...',\ + ('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\ + ('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\ + ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\ + ] + + if not Draw.PupBlock('Import OBJ...', pup_block): + return + + if KEEP_VERT_ORDER.val: + SPLIT_OBJECTS.val = False + SPLIT_GROUPS.val = False + SPLIT_MATERIALS.val = False + ''' + + + + # BEGIN ALTERNATIVE UI ******************* + if True: + + EVENT_NONE = 0 + EVENT_EXIT = 1 + EVENT_REDRAW = 2 + EVENT_IMPORT = 3 + + GLOBALS = {} + GLOBALS['EVENT'] = EVENT_REDRAW + #GLOBALS['MOUSE'] = Window.GetMouseCoords() + GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()] + + def obj_ui_set_event(e,v): + GLOBALS['EVENT'] = e + + def do_split(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS + if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val: + KEEP_VERT_ORDER.val = 0 + POLYGROUPS.val = 0 + else: + KEEP_VERT_ORDER.val = 1 + + def do_vertorder(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER + if KEEP_VERT_ORDER.val: + SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 + else: + if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val): + KEEP_VERT_ORDER.val = 1 + + def do_polygroups(e,v): + global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER, POLYGROUPS + if POLYGROUPS.val: + SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0 + + def do_help(e,v): + url = __url__[0] + print('Trying to open web browser with documentation at this address...') + print('\t' + url) + + try: + import webbrowser + webbrowser.open(url) + except: + print('...could not open a browser window.') + + def obj_ui(): + ui_x, ui_y = GLOBALS['MOUSE'] + + # Center based on overall pup size + ui_x -= 165 + ui_y -= 90 + + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 + + Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21) + Draw.BeginAlign() + CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges') + CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons') + CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges') + Draw.EndAlign() + + Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20) + Draw.BeginAlign() + SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split) + SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split) + SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+119, ui_y+89, 60, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split) + Draw.EndAlign() + + # Only used for user feedback + KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) + + ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.') + + Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20) + CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') + POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups) + IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)') + Draw.BeginAlign() + Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help) + Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event) + Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event) + Draw.EndAlign() + + + # hack so the toggle buttons redraw. this is not nice at all + while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT): + Draw.UIBlock(obj_ui, 0) + + if GLOBALS['EVENT'] != EVENT_IMPORT: + return + + # END ALTERNATIVE UI ********************* + + + + + + + + Window.WaitCursor(1) + + if BATCH_LOAD: # load the dir + try: + files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ] + except: + Window.WaitCursor(0) + Draw.PupMenu('Error%t|Could not open path ' + filepath) + return + + if not files: + Window.WaitCursor(0) + Draw.PupMenu('Error%t|No files at path ' + filepath) + return + + for f in files: + scn= bpy.data.scenes.new( stripExt(f) ) + scn.makeCurrent() + + load_obj(sys.join(filepath, f),\ + CLAMP_SIZE.val,\ + CREATE_FGONS.val,\ + CREATE_SMOOTH_GROUPS.val,\ + CREATE_EDGES.val,\ + SPLIT_OBJECTS.val,\ + SPLIT_GROUPS.val,\ + SPLIT_MATERIALS.val,\ + ROTATE_X90.val,\ + IMAGE_SEARCH.val,\ + POLYGROUPS.val + ) + + else: # Normal load + load_obj(filepath,\ + CLAMP_SIZE.val,\ + CREATE_FGONS.val,\ + CREATE_SMOOTH_GROUPS.val,\ + CREATE_EDGES.val,\ + SPLIT_OBJECTS.val,\ + SPLIT_GROUPS.val,\ + SPLIT_MATERIALS.val,\ + ROTATE_X90.val,\ + IMAGE_SEARCH.val,\ + POLYGROUPS.val + ) + + Window.WaitCursor(0) + + +def load_obj_ui_batch(file): + load_obj_ui(file, True) + +DEBUG= False + +# if __name__=='__main__' and not DEBUG: +# if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT: +# Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '') +# else: +# Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') + + # For testing compatibility +''' +else: + # DEBUG ONLY + TIME= sys.time() + DIR = '/fe/obj' + import os + print 'Searching for files' + def fileList(path): + for dirpath, dirnames, filenames in os.walk(path): + for filename in filenames: + yield os.path.join(dirpath, filename) + + files = [f for f in fileList(DIR) if f.lower().endswith('.obj')] + files.sort() + + for i, obj_file in enumerate(files): + if 0 < i < 20: + print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files) + newScn= bpy.data.scenes.new(os.path.basename(obj_file)) + newScn.makeCurrent() + load_obj(obj_file, False, IMAGE_SEARCH=0) + + print 'TOTAL TIME: %.6f' % (sys.time() - TIME) +''' +#load_obj('/test.obj') +#load_obj('/fe/obj/mba1.obj') + + + +class IMPORT_OT_obj(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "import.obj" + __label__ = "Import OBJ" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [ + bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""), + + bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True), + bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True), + bpy.props.BoolProperty(attr="CREATE_EDGES", name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True), + bpy.props.BoolProperty(attr="SPLIT_OBJECTS", name="Object", description="Import OBJ Objects into Blender Objects", default= True), + bpy.props.BoolProperty(attr="SPLIT_GROUPS", name="Group", description="Import OBJ Groups into Blender Objects", default= True), + bpy.props.BoolProperty(attr="SPLIT_MATERIALS", name="Material", description="Import each material into a seperate mesh (Avoids > 16 per mesh error)", default= True), + # old comment: only used for user feedback + # disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj + # bpy.props.BoolProperty(attr="KEEP_VERT_ORDER", name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True), + bpy.props.BoolProperty(attr="ROTATE_X90", name="-X90", description="Rotate X 90.", default= True), + bpy.props.FloatProperty(attr="CLAMP_SIZE", name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.01, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0), + bpy.props.BoolProperty(attr="POLYGROUPS", name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True), + bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True), + ] + + ''' + def poll(self, context): + return True ''' + + def execute(self, context): + # print("Selected: " + context.active_object.name) + + if not self.filename: + raise Exception("filename not set") + + load_obj(self.filename, + context, + self.CLAMP_SIZE, + self.CREATE_FGONS, + self.CREATE_SMOOTH_GROUPS, + self.CREATE_EDGES, + self.SPLIT_OBJECTS, + self.SPLIT_GROUPS, + self.SPLIT_MATERIALS, + self.ROTATE_X90, + self.IMAGE_SEARCH, + self.POLYGROUPS) + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + + +bpy.ops.add(IMPORT_OT_obj) + + +# NOTES (all line numbers refer to 2.4x import_obj.py, not this file) +# check later: line 489 +# can convert now: edge flags, edges: lines 508-528 +# ngon (uses python module BPyMesh): 384-414 +# nurbs: 947- +# NEXT clamp size: get bound box with RNA +# get back to l 140 (here) +# search image in bpy.config.textureDir - load_image +# replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load) +# bitmask won't work? - 132 +# uses operator bpy.ops.OBJECT_OT_select_all_toggle() to deselect all (not necessary?) +# uses bpy.sys.time() diff --git a/release/scripts/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py new file mode 100644 index 00000000000..4a1dd2238e3 --- /dev/null +++ b/release/scripts/io/netrender/__init__.py @@ -0,0 +1,19 @@ +# This directory is a Python package. + +import model +import operators +import client +import slave +import master +import master_html +import utils +import balancing +import ui + +# store temp data in bpy module + +import bpy + +bpy.data.netrender_jobs = [] +bpy.data.netrender_slaves = [] +bpy.data.netrender_blacklist = [] \ No newline at end of file diff --git a/release/scripts/io/netrender/balancing.py b/release/scripts/io/netrender/balancing.py new file mode 100644 index 00000000000..637dd5ff92e --- /dev/null +++ b/release/scripts/io/netrender/balancing.py @@ -0,0 +1,94 @@ +import time + +from netrender.utils import * +import netrender.model + +class RatingRule: + def rate(self, job): + return 0 + +class ExclusionRule: + def test(self, job): + return False + +class PriorityRule: + def test(self, job): + return False + +class Balancer: + def __init__(self): + self.rules = [] + self.priorities = [] + self.exceptions = [] + + def addRule(self, rule): + self.rules.append(rule) + + def addPriority(self, priority): + self.priorities.append(priority) + + def addException(self, exception): + self.exceptions.append(exception) + + def applyRules(self, job): + return sum((rule.rate(job) for rule in self.rules)) + + def applyPriorities(self, job): + for priority in self.priorities: + if priority.test(job): + return True # priorities are first + + return False + + def applyExceptions(self, job): + for exception in self.exceptions: + if exception.test(job): + return True # exceptions are last + + return False + + def sortKey(self, job): + return (1 if self.applyExceptions(job) else 0, # exceptions after + 0 if self.applyPriorities(job) else 1, # priorities first + self.applyRules(job)) + + def balance(self, jobs): + if jobs: + jobs.sort(key=self.sortKey) + return jobs[0] + else: + return None + +# ========================== + +class RatingUsage(RatingRule): + def rate(self, job): + # less usage is better + return job.usage / job.priority + +class NewJobPriority(PriorityRule): + def __init__(self, limit = 1): + self.limit = limit + + def test(self, job): + return job.countFrames(status = DONE) < self.limit + +class MinimumTimeBetweenDispatchPriority(PriorityRule): + def __init__(self, limit = 10): + self.limit = limit + + def test(self, job): + return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit + +class ExcludeQueuedEmptyJob(ExclusionRule): + def test(self, job): + return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0 + +class ExcludeSlavesLimit(ExclusionRule): + def __init__(self, count_jobs, count_slaves, limit = 0.75): + self.count_jobs = count_jobs + self.count_slaves = count_slaves + self.limit = limit + + def test(self, job): + return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py new file mode 100644 index 00000000000..65b2937867f --- /dev/null +++ b/release/scripts/io/netrender/client.py @@ -0,0 +1,203 @@ +import bpy +import sys, os, re +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +import netrender.slave as slave +import netrender.master as master +from netrender.utils import * + + +def clientSendJob(conn, scene, anim = False, chunks = 5): + netsettings = scene.network_render + job = netrender.model.RenderJob() + + if anim: + for f in range(scene.start_frame, scene.end_frame + 1): + job.addFrame(f) + else: + job.addFrame(scene.current_frame) + + filename = bpy.data.filename + job.addFile(filename) + + job_name = netsettings.job_name + path, name = os.path.split(filename) + if job_name == "[default]": + job_name = name + + ########################### + # LIBRARIES + ########################### + for lib in bpy.data.libraries: + lib_path = lib.filename + + if lib_path.startswith("//"): + lib_path = path + os.sep + lib_path[2:] + + job.addFile(lib_path) + + ########################### + # POINT CACHES + ########################### + + root, ext = os.path.splitext(name) + cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that + + if os.path.exists(cache_path): + caches = {} + pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") + for cache_file in sorted(os.listdir(cache_path)): + match = pattern.match(cache_file) + + if match: + cache_id = match.groups()[0] + cache_frame = int(match.groups()[1]) + + cache_files = caches.get(cache_id, []) + cache_files.append((cache_frame, cache_file)) + caches[cache_id] = cache_files + + for cache in caches.values(): + cache.sort() + + if len(cache) == 1: + cache_frame, cache_file = cache[0] + job.addFile(cache_path + cache_file, cache_frame, cache_frame) + else: + for i in range(len(cache)): + current_item = cache[i] + next_item = cache[i+1] if i + 1 < len(cache) else None + previous_item = cache[i - 1] if i > 0 else None + + current_frame, current_file = current_item + + if not next_item and not previous_item: + job.addFile(cache_path + current_file, current_frame, current_frame) + elif next_item and not previous_item: + next_frame = next_item[0] + job.addFile(cache_path + current_file, current_frame, next_frame - 1) + elif not next_item and previous_item: + previous_frame = previous_item[0] + job.addFile(cache_path + current_file, previous_frame + 1, current_frame) + else: + next_frame = next_item[0] + previous_frame = previous_item[0] + job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) + + ########################### + # IMAGES + ########################### + for image in bpy.data.images: + if image.source == "FILE" and not image.packed_file: + job.addFile(image.filename) + + # print(job.files) + + job.name = job_name + + for slave in scene.network_render.slaves_blacklist: + job.blacklist.append(slave.id) + + job.chunks = netsettings.chunks + job.priority = netsettings.priority + + # try to send path first + conn.request("POST", "/job", repr(job.serialize())) + response = conn.getresponse() + + job_id = response.getheader("job-id") + + # if not ACCEPTED (but not processed), send files + if response.status == http.client.ACCEPTED: + for filepath, start, end in job.files: + f = open(filepath, "rb") + conn.request("PUT", "/file", f, headers={"job-id": job_id, "job-file": filepath}) + f.close() + response = conn.getresponse() + + # server will reply with NOT_FOUD until all files are found + + return job_id + +def requestResult(conn, job_id, frame): + conn.request("GET", "/render", headers={"job-id": job_id, "job-frame":str(frame)}) + +@rnaType +class NetworkRenderEngine(bpy.types.RenderEngine): + __idname__ = 'NET_RENDER' + __label__ = "Network Render" + def render(self, scene): + if scene.network_render.mode == "RENDER_CLIENT": + self.render_client(scene) + elif scene.network_render.mode == "RENDER_SLAVE": + self.render_slave(scene) + elif scene.network_render.mode == "RENDER_MASTER": + self.render_master(scene) + else: + print("UNKNOWN OPERATION MODE") + + def render_master(self, scene): + netsettings = scene.network_render + + address = "" if netsettings.server_address == "[default]" else netsettings.server_address + + master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break) + + + def render_slave(self, scene): + slave.render_slave(self, scene) + + def render_client(self, scene): + netsettings = scene.network_render + self.update_stats("", "Network render client initiation") + + + conn = clientConnection(scene) + + if conn: + # Sending file + + self.update_stats("", "Network render exporting") + + job_id = netsettings.job_id + + # reading back result + + self.update_stats("", "Network render waiting for results") + + requestResult(conn, job_id, scene.current_frame) + response = conn.getresponse() + + if response.status == http.client.NO_CONTENT: + netsettings.job_id = clientSendJob(conn, scene) + requestResult(conn, job_id, scene.current_frame) + + while response.status == http.client.ACCEPTED and not self.test_break(): + time.sleep(1) + requestResult(conn, job_id, scene.current_frame) + response = conn.getresponse() + + if response.status != http.client.OK: + conn.close() + return + + r = scene.render_data + x= int(r.resolution_x*r.resolution_percentage*0.01) + y= int(r.resolution_y*r.resolution_percentage*0.01) + + f = open(netsettings.path + "output.exr", "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + result = self.begin_result(0, 0, x, y) + result.load_from_file(netsettings.path + "output.exr", 0, 0) + self.end_result(result) + + conn.close() + diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py new file mode 100644 index 00000000000..a3e186a9cfd --- /dev/null +++ b/release/scripts/io/netrender/master.py @@ -0,0 +1,752 @@ +import sys, os +import http, http.client, http.server, urllib, socket +import subprocess, shutil, time, hashlib + +from netrender.utils import * +import netrender.model +import netrender.balancing +import netrender.master_html + +class MRenderFile: + def __init__(self, filepath, start, end): + self.filepath = filepath + self.start = start + self.end = end + self.found = False + + def test(self): + self.found = os.path.exists(self.filepath) + return self.found + + +class MRenderSlave(netrender.model.RenderSlave): + def __init__(self, name, address, stats): + super().__init__() + self.id = hashlib.md5(bytes(repr(name) + repr(address), encoding='utf8')).hexdigest() + self.name = name + self.address = address + self.stats = stats + self.last_seen = time.time() + + self.job = None + self.job_frames = [] + + netrender.model.RenderSlave._slave_map[self.id] = self + + def seen(self): + self.last_seen = time.time() + + def finishedFrame(self, frame_number): + self.job_frames.remove(frame_number) + if not self.job_frames: + self.job = None + +class MRenderJob(netrender.model.RenderJob): + def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []): + super().__init__() + self.id = job_id + self.name = name + self.files = files + self.frames = [] + self.chunks = chunks + self.priority = priority + self.usage = 0.0 + self.blacklist = blacklist + self.last_dispatched = time.time() + + # special server properties + self.last_update = 0 + self.save_path = "" + self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} + self.status = JOB_WAITING + + def save(self): + if self.save_path: + f = open(self.save_path + "job.txt", "w") + f.write(repr(self.serialize())) + f.close() + + def testStart(self): + for f in self.files_map.values(): + if not f.test(): + return False + + self.start() + return True + + def testFinished(self): + for f in self.frames: + if f.status == QUEUED or f.status == DISPATCHED: + break + else: + self.status = JOB_FINISHED + + def start(self): + self.status = JOB_QUEUED + + def addLog(self, frames): + log_name = "_".join(("%04d" % f for f in frames)) + ".log" + log_path = self.save_path + log_name + + for number in frames: + frame = self[number] + if frame: + frame.log_path = log_path + + def addFrame(self, frame_number): + frame = MRenderFrame(frame_number) + self.frames.append(frame) + return frame + + def reset(self, all): + for f in self.frames: + f.reset(all) + + def getFrames(self): + frames = [] + for f in self.frames: + if f.status == QUEUED: + self.last_dispatched = time.time() + frames.append(f) + if len(frames) >= self.chunks: + break + + return frames + +class MRenderFrame(netrender.model.RenderFrame): + def __init__(self, frame): + super().__init__() + self.number = frame + self.slave = None + self.time = 0 + self.status = QUEUED + self.log_path = None + + def reset(self, all): + if all or self.status == ERROR: + self.slave = None + self.time = 0 + self.status = QUEUED + + +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +class RenderHandler(http.server.BaseHTTPRequestHandler): + def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"): + self.send_response(code) + self.send_header("Content-type", content) + + for key, value in headers.items(): + self.send_header(key, value) + + self.end_headers() + + def do_HEAD(self): + + if self.path == "/status": + job_id = self.headers.get('job-id', "") + job_frame = int(self.headers.get('job-frame', -1)) + + job = self.server.getJobID(job_id) + if job: + frame = job[job_frame] + + + if frame: + self.send_head(http.client.OK) + else: + # no such frame + self.send_head(http.client.NO_CONTENT) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + def do_GET(self): + + if self.path == "/version": + self.send_head() + self.server.stats("", "Version check") + self.wfile.write(VERSION) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/render": + job_id = self.headers['job-id'] + job_frame = int(self.headers['job-frame']) + + job = self.server.getJobID(job_id) + + if job: + frame = job[job_frame] + + if frame: + if frame.status in (QUEUED, DISPATCHED): + self.send_head(http.client.ACCEPTED) + elif frame.status == DONE: + self.server.stats("", "Sending result to client") + f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb') + + self.send_head() + + shutil.copyfileobj(f, self.wfile) + + f.close() + elif frame.status == ERROR: + self.send_head(http.client.PARTIAL_CONTENT) + else: + # no such frame + self.send_head(http.client.NO_CONTENT) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/log": + job_id = self.headers['job-id'] + job_frame = int(self.headers['job-frame']) + + job = self.server.getJobID(job_id) + + if job: + frame = job[job_frame] + + if frame: + if not frame.log_path or frame.status in (QUEUED, DISPATCHED): + self.send_head(http.client.PROCESSING) + else: + self.server.stats("", "Sending log to client") + f = open(frame.log_path, 'rb') + + self.send_head() + + shutil.copyfileobj(f, self.wfile) + + f.close() + else: + # no such frame + self.send_head(http.client.NO_CONTENT) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/status": + job_id = self.headers.get('job-id', "") + job_frame = int(self.headers.get('job-frame', -1)) + + if job_id: + + job = self.server.getJobID(job_id) + if job: + if job_frame != -1: + frame = job[frame] + + if frame: + message = frame.serialize() + else: + # no such frame + self.send_heat(http.client.NO_CONTENT) + return + else: + message = job.serialize() + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + return + else: # status of all jobs + message = [] + + for job in self.server: + message.append(job.serialize()) + + + self.server.stats("", "Sending status") + self.send_head() + self.wfile.write(bytes(repr(message), encoding='utf8')) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/job": + self.server.balance() + + slave_id = self.headers['slave-id'] + + slave = self.server.getSeenSlave(slave_id) + + if slave: # only if slave id is valid + job, frames = self.server.newDispatch(slave_id) + + if job and frames: + for f in frames: + print("dispatch", f.number) + f.status = DISPATCHED + f.slave = slave + + slave.job = job + slave.job_frames = [f.number for f in frames] + + self.send_head(headers={"job-id": job.id}) + + message = job.serialize(frames) + + self.wfile.write(bytes(repr(message), encoding='utf8')) + + self.server.stats("", "Sending job to slave") + else: + # no job available, return error code + slave.job = None + slave.job_frames = [] + + self.send_head(http.client.ACCEPTED) + else: # invalid slave id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/file": + slave_id = self.headers['slave-id'] + + slave = self.server.getSeenSlave(slave_id) + + if slave: # only if slave id is valid + job_id = self.headers['job-id'] + job_file = self.headers['job-file'] + + job = self.server.getJobID(job_id) + + if job: + render_file = job.files_map.get(job_file, None) + + if render_file: + self.server.stats("", "Sending file to slave") + f = open(render_file.filepath, 'rb') + + self.send_head() + shutil.copyfileobj(f, self.wfile) + + f.close() + else: + # no such file + self.send_head(http.client.NO_CONTENT) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/slaves": + message = [] + + self.server.stats("", "Sending slaves status") + + for slave in self.server.slaves: + message.append(slave.serialize()) + + self.send_head() + + self.wfile.write(bytes(repr(message), encoding='utf8')) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + else: + # hand over the rest to the html section + netrender.master_html.get(self) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + def do_POST(self): + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + if self.path == "/job": + + length = int(self.headers['content-length']) + + job_info = netrender.model.RenderJob.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) + + job_id = self.server.nextJobID() + + job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) + + for frame in job_info.frames: + frame = job.addFrame(frame.number) + + self.server.addJob(job) + + headers={"job-id": job_id} + + if job.testStart(): + self.server.stats("", "New job, missing files") + self.send_head(headers=headers) + else: + self.server.stats("", "New job, started") + self.send_head(http.client.ACCEPTED, headers=headers) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/cancel": + job_id = self.headers.get('job-id', "") + + job = self.server.getJobID(job_id) + + if job: + self.server.stats("", "Cancelling job") + self.server.removeJob(job) + self.send_head() + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/clear": + # cancel all jobs + self.server.stats("", "Clearing jobs") + self.server.clear() + + self.send_head() + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/reset": + job_id = self.headers.get('job-id', "") + job_frame = int(self.headers.get('job-frame', "-1")) + all = bool(self.headers.get('reset-all', "False")) + + job = self.server.getJobID(job_id) + + if job: + if job_frame != -1: + + frame = job[job_frame] + if frame: + self.server.stats("", "Reset job frame") + frame.reset(all) + self.send_head() + else: + # no such frame + self.send_head(http.client.NO_CONTENT) + + else: + self.server.stats("", "Reset job") + job.reset(all) + self.send_head() + + else: # job not found + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/slave": + length = int(self.headers['content-length']) + job_frame_string = self.headers['job-frame'] + + self.server.stats("", "New slave connected") + + slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) + + slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) + + self.send_head(headers = {"slave-id": slave_id}) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/log": + slave_id = self.headers['slave-id'] + + slave = self.server.getSeenSlave(slave_id) + + if slave: # only if slave id is valid + length = int(self.headers['content-length']) + + log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) + + job = self.server.getJobID(log_info.job_id) + + if job: + self.server.stats("", "Log announcement") + job.addLog(log_info.frames) + self.send_head(http.client.OK) + else: + # no such job id + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + def do_PUT(self): + + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + if self.path == "/file": + self.server.stats("", "Receiving job") + + length = int(self.headers['content-length']) + job_id = self.headers['job-id'] + job_file = self.headers['job-file'] + + job = self.server.getJobID(job_id) + + if job: + + render_file = job.files_map.get(job_file, None) + + if render_file: + main_file = job.files[0][0] # filename of the first file + + main_path, main_name = os.path.split(main_file) + + if job_file != main_file: + file_path = prefixPath(job.save_path, job_file, main_path) + else: + file_path = job.save_path + main_name + + buf = self.rfile.read(length) + + # add same temp file + renames as slave + + f = open(file_path, "wb") + f.write(buf) + f.close() + del buf + + render_file.filepath = file_path # set the new path + + if job.testStart(): + self.server.stats("", "File upload, starting job") + self.send_head(http.client.OK) + else: + self.server.stats("", "File upload, file missings") + self.send_head(http.client.ACCEPTED) + else: # invalid file + self.send_head(http.client.NO_CONTENT) + else: # job not found + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/render": + self.server.stats("", "Receiving render result") + + slave_id = self.headers['slave-id'] + + slave = self.server.getSeenSlave(slave_id) + + if slave: # only if slave id is valid + job_id = self.headers['job-id'] + + job = self.server.getJobID(job_id) + + if job: + job_frame = int(self.headers['job-frame']) + job_result = int(self.headers['job-result']) + job_time = float(self.headers['job-time']) + + frame = job[job_frame] + + if frame: + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() + + del buf + elif job_result == ERROR: + # blacklist slave on this job on error + job.blacklist.append(slave.id) + + self.server.stats("", "Receiving result") + + slave.finishedFrame(job_frame) + + frame.status = job_result + frame.time = job_time + + job.testFinished() + + self.send_head() + else: # frame not found + self.send_head(http.client.NO_CONTENT) + else: # job not found + self.send_head(http.client.NO_CONTENT) + else: # invalid slave id + self.send_head(http.client.NO_CONTENT) + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/log": + self.server.stats("", "Receiving log file") + + job_id = self.headers['job-id'] + + job = self.server.getJobID(job_id) + + if job: + job_frame = int(self.headers['job-frame']) + + frame = job[job_frame] + + if frame and frame.log_path: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(frame.log_path, 'ab') + f.write(buf) + f.close() + + del buf + + self.server.getSeenSlave(self.headers['slave-id']) + + self.send_head() + else: # frame not found + self.send_head(http.client.NO_CONTENT) + else: # job not found + self.send_head(http.client.NO_CONTENT) + +class RenderMasterServer(http.server.HTTPServer): + def __init__(self, address, handler_class, path): + super().__init__(address, handler_class) + self.jobs = [] + self.jobs_map = {} + self.slaves = [] + self.slaves_map = {} + self.job_id = 0 + self.path = path + "master_" + str(os.getpid()) + os.sep + + self.slave_timeout = 2 + + self.balancer = netrender.balancing.Balancer() + self.balancer.addRule(netrender.balancing.RatingUsage()) + self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob()) + self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9)) + self.balancer.addPriority(netrender.balancing.NewJobPriority()) + self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority(limit = 2)) + + if not os.path.exists(self.path): + os.mkdir(self.path) + + def nextJobID(self): + self.job_id += 1 + return str(self.job_id) + + def addSlave(self, name, address, stats): + slave = MRenderSlave(name, address, stats) + self.slaves.append(slave) + self.slaves_map[slave.id] = slave + + return slave.id + + def removeSlave(self, slave): + self.slaves.remove(slave) + self.slaves_map.pop(slave.id) + + def getSlave(self, slave_id): + return self.slaves_map.get(slave_id, None) + + def getSeenSlave(self, slave_id): + slave = self.getSlave(slave_id) + if slave: + slave.seen() + + return slave + + def timeoutSlaves(self): + removed = [] + + t = time.time() + + for slave in self.slaves: + if (t - slave.last_seen) / 60 > self.slave_timeout: + removed.append(slave) + + if slave.job: + for f in slave.job_frames: + slave.job[f].status = ERROR + + for slave in removed: + self.removeSlave(slave) + + def updateUsage(self): + blend = 0.5 + for job in self.jobs: + job.usage *= (1 - blend) + + if self.slaves: + slave_usage = blend / self.countSlaves() + + for slave in self.slaves: + if slave.job: + slave.job.usage += slave_usage + + + def clear(self): + removed = self.jobs[:] + + for job in removed: + self.removeJob(job) + + def balance(self): + self.balancer.balance(self.jobs) + + def countJobs(self, status = JOB_QUEUED): + total = 0 + for j in self.jobs: + if j.status == status: + total += 1 + + return total + + def countSlaves(self): + return len(self.slaves) + + def removeJob(self, job): + self.jobs.remove(job) + self.jobs_map.pop(job.id) + + for slave in self.slaves: + if slave.job == job: + slave.job = None + slave.job_frames = [] + + def addJob(self, job): + self.jobs.append(job) + self.jobs_map[job.id] = job + + # create job directory + job.save_path = self.path + "job_" + job.id + os.sep + if not os.path.exists(job.save_path): + os.mkdir(job.save_path) + + job.save() + + def getJobID(self, id): + return self.jobs_map.get(id, None) + + def __iter__(self): + for job in self.jobs: + yield job + + def newDispatch(self, slave_id): + if self.jobs: + for job in self.jobs: + if not self.balancer.applyExceptions(job) and slave_id not in job.blacklist: + return job, job.getFrames() + + return None, None + +def runMaster(address, broadcast, path, update_stats, test_break): + httpd = RenderMasterServer(address, RenderHandler, path) + httpd.timeout = 1 + httpd.stats = update_stats + + if broadcast: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + + start_time = time.time() + + while not test_break(): + httpd.handle_request() + + if time.time() - start_time >= 10: # need constant here + httpd.timeoutSlaves() + + httpd.updateUsage() + + if broadcast: + print("broadcasting address") + s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('', 8000)) + start_time = time.time() diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py new file mode 100644 index 00000000000..6a956a70e9f --- /dev/null +++ b/release/scripts/io/netrender/master_html.py @@ -0,0 +1,142 @@ +import re + +from netrender.utils import * + + +def get(handler): + def output(text): + handler.wfile.write(bytes(text, encoding='utf8')) + + def link(text, url): + return "%s" % (url, text) + + def startTable(border=1): + output("" % border) + + def headerTable(*headers): + output("") + + for c in headers: + output("") + + output("") + + def rowTable(*data): + output("") + + for c in data: + output("") + + output("") + + def endTable(): + output("
" + c + "
" + str(c) + "
") + + handler.send_head(content = "text/html") + + if handler.path == "/html" or handler.path == "/": + output("NetRender") + + output("

Master

") + + output("

Slaves

") + + startTable() + headerTable("name", "address", "last seen", "stats", "job") + + for slave in handler.server.slaves: + rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None") + + endTable() + + output("

Jobs

") + + startTable() + headerTable( + "name", + "priority", + "usage", + "wait", + "length", + "done", + "dispatched", + "error", + "first", + "exception" + ) + + handler.server.balance() + + for job in handler.server.jobs: + results = job.framesStatus() + rowTable( + link(job.name, "/html/job" + job.id), + job.priority, + "%0.1f%%" % (job.usage * 100), + "%is" % int(time.time() - job.last_dispatched), + len(job), + results[DONE], + results[DISPATCHED], + results[ERROR], + handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job) + ) + + endTable() + + output("") + + elif handler.path.startswith("/html/job"): + job_id = handler.path[9:] + + output("NetRender") + + job = handler.server.getJobID(job_id) + + if job: + output("

Frames

") + + startTable() + headerTable("no", "status", "render time", "slave", "log") + + for frame in job.frames: + rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else " ") + + endTable() + else: + output("no such job") + + output("") + + elif handler.path.startswith("/html/log"): + pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)") + + output("NetRender") + + match = pattern.match(handler.path[9:]) + if match: + job_id = match.groups()[0] + frame_number = int(match.groups()[1]) + + job = handler.server.getJobID(job_id) + + if job: + frame = job[frame_number] + + if frame: + f = open(frame.log_path, 'rb') + + output("
")
+						
+						shutil.copyfileobj(f, handler.wfile)
+						
+						output("
") + + f.close() + else: + output("no such frame") + else: + output("no such job") + else: + output("malformed url") + + output("") diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py new file mode 100644 index 00000000000..be97f8d0a81 --- /dev/null +++ b/release/scripts/io/netrender/model.py @@ -0,0 +1,198 @@ +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +from netrender.utils import * + +class LogFile: + def __init__(self, job_id = 0, frames = []): + self.job_id = job_id + self.frames = frames + + def serialize(self): + return { + "job_id": self.job_id, + "frames": self.frames + } + + @staticmethod + def materialize(data): + if not data: + return None + + logfile = LogFile() + logfile.job_id = data["job_id"] + logfile.frames = data["frames"] + + return logfile + +class RenderSlave: + _slave_map = {} + + def __init__(self): + self.id = "" + self.name = "" + self.address = ("",0) + self.stats = "" + self.total_done = 0 + self.total_error = 0 + self.last_seen = 0.0 + + def serialize(self): + return { + "id": self.id, + "name": self.name, + "address": self.address, + "stats": self.stats, + "total_done": self.total_done, + "total_error": self.total_error, + "last_seen": self.last_seen + } + + @staticmethod + def materialize(data): + if not data: + return None + + slave_id = data["id"] + + if slave_id in RenderSlave._slave_map: + return RenderSlave._slave_map[slave_id] + else: + slave = RenderSlave() + slave.id = slave_id + slave.name = data["name"] + slave.address = data["address"] + slave.stats = data["stats"] + slave.total_done = data["total_done"] + slave.total_error = data["total_error"] + slave.last_seen = data["last_seen"] + + RenderSlave._slave_map[slave_id] = slave + + return slave + +class RenderJob: + def __init__(self): + self.id = "" + self.name = "" + self.files = [] + self.frames = [] + self.chunks = 0 + self.priority = 0 + self.usage = 0.0 + self.blacklist = [] + self.last_dispatched = 0.0 + + def addFile(self, file_path, start=-1, end=-1): + self.files.append((file_path, start, end)) + + def addFrame(self, frame_number): + frame = RenderFrame(frame_number) + self.frames.append(frame) + return frame + + def __len__(self): + return len(self.frames) + + def countFrames(self, status=QUEUED): + total = 0 + for f in self.frames: + if f.status == status: + total += 1 + + return total + + def countSlaves(self): + return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED))) + + def framesStatus(self): + results = { + QUEUED: 0, + DISPATCHED: 0, + DONE: 0, + ERROR: 0 + } + + for frame in self.frames: + results[frame.status] += 1 + + return results + + def __contains__(self, frame_number): + for f in self.frames: + if f.number == frame_number: + return True + else: + return False + + def __getitem__(self, frame_number): + for f in self.frames: + if f.number == frame_number: + return f + else: + return None + + def serialize(self, frames = None): + min_frame = min((f.number for f in frames)) if frames else -1 + max_frame = max((f.number for f in frames)) if frames else -1 + return { + "id": self.id, + "name": self.name, + "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], + "frames": [f.serialize() for f in self.frames if not frames or f in frames], + "chunks": self.chunks, + "priority": self.priority, + "usage": self.usage, + "blacklist": self.blacklist, + "last_dispatched": self.last_dispatched + } + + @staticmethod + def materialize(data): + if not data: + return None + + job = RenderJob() + job.id = data["id"] + job.name = data["name"] + job.files = data["files"] + job.frames = [RenderFrame.materialize(f) for f in data["frames"]] + job.chunks = data["chunks"] + job.priority = data["priority"] + job.usage = data["usage"] + job.blacklist = data["blacklist"] + job.last_dispatched = data["last_dispatched"] + + return job + +class RenderFrame: + def __init__(self, number = 0): + self.number = number + self.time = 0 + self.status = QUEUED + self.slave = None + + def statusText(self): + return STATUS_TEXT[self.status] + + def serialize(self): + return { + "number": self.number, + "time": self.time, + "status": self.status, + "slave": None if not self.slave else self.slave.serialize() + } + + @staticmethod + def materialize(data): + if not data: + return None + + frame = RenderFrame() + frame.number = data["number"] + frame.time = data["time"] + frame.status = data["status"] + frame.slave = RenderSlave.materialize(data["slave"]) + + return frame diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py new file mode 100644 index 00000000000..42d1f6a0b86 --- /dev/null +++ b/release/scripts/io/netrender/operators.py @@ -0,0 +1,423 @@ +import bpy +import sys, os +import http, http.client, http.server, urllib, socket +import webbrowser + +from netrender.utils import * +import netrender.client as client +import netrender.model + +@rnaOperator +class RENDER_OT_netclientanim(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "render.netclientanim" + __label__ = "Net Render Client Anim" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + scene = context.scene + + conn = clientConnection(scene) + + if conn: + # Sending file + scene.network_render.job_id = client.clientSendJob(conn, scene, True) + conn.close() + + bpy.ops.screen.render('INVOKE_AREA', animation=True) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class RENDER_OT_netclientsend(bpy.types.Operator): + ''' + Operator documentation text, will be used for the operator tooltip and python docs. + ''' + __idname__ = "render.netclientsend" + __label__ = "Net Render Client Send" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + scene = context.scene + + conn = clientConnection(scene) + + if conn: + # Sending file + scene.network_render.job_id = client.clientSendJob(conn, scene, True) + conn.close() + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class RENDER_OT_netclientstatus(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientstatus" + __label__ = "Net Render Client Status" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + conn.request("GET", "/status") + + response = conn.getresponse() + print( response.status, response.reason ) + + jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8'))) + + while(len(netsettings.jobs) > 0): + netsettings.jobs.remove(0) + + bpy.data.netrender_jobs = [] + + for j in jobs: + bpy.data.netrender_jobs.append(j) + netsettings.jobs.add() + job = netsettings.jobs[-1] + + j.results = j.framesStatus() # cache frame status + + job.name = j.name + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class RENDER_OT_netclientblacklistslave(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientblacklistslave" + __label__ = "Net Render Client Blacklist Slave" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + + if netsettings.active_slave_index >= 0: + + # deal with data + slave = bpy.data.netrender_slaves.pop(netsettings.active_slave_index) + bpy.data.netrender_blacklist.append(slave) + + # deal with rna + netsettings.slaves_blacklist.add() + netsettings.slaves_blacklist[-1].name = slave.name + + netsettings.slaves.remove(netsettings.active_slave_index) + netsettings.active_slave_index = -1 + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientwhitelistslave" + __label__ = "Net Render Client Whitelist Slave" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + + if netsettings.active_blacklisted_slave_index >= 0: + + # deal with data + slave = bpy.data.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index) + bpy.data.netrender_slaves.append(slave) + + # deal with rna + netsettings.slaves.add() + netsettings.slaves[-1].name = slave.name + + netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index) + netsettings.active_blacklisted_slave_index = -1 + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + + +@rnaOperator +class RENDER_OT_netclientslaves(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientslaves" + __label__ = "Net Render Client Slaves" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + conn.request("GET", "/slaves") + + response = conn.getresponse() + print( response.status, response.reason ) + + slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8'))) + + while(len(netsettings.slaves) > 0): + netsettings.slaves.remove(0) + + bpy.data.netrender_slaves = [] + + for s in slaves: + for i in range(len(bpy.data.netrender_blacklist)): + slave = bpy.data.netrender_blacklist[i] + if slave.id == s.id: + bpy.data.netrender_blacklist[i] = s + netsettings.slaves_blacklist[i].name = s.name + break + else: + bpy.data.netrender_slaves.append(s) + + netsettings.slaves.add() + slave = netsettings.slaves[-1] + slave.name = s.name + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class RENDER_OT_netclientcancel(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientcancel" + __label__ = "Net Render Client Cancel" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + netsettings = context.scene.network_render + return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 + + def execute(self, context): + netsettings = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + job = bpy.data.netrender_jobs[netsettings.active_job_index] + + conn.request("POST", "/cancel", headers={"job-id":job.id}) + + response = conn.getresponse() + print( response.status, response.reason ) + + netsettings.jobs.remove(netsettings.active_job_index) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class RENDER_OT_netclientcancelall(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientcancelall" + __label__ = "Net Render Client Cancel All" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + conn = clientConnection(context.scene) + + if conn: + conn.request("POST", "/clear") + + response = conn.getresponse() + print( response.status, response.reason ) + + while(len(netsettings.jobs) > 0): + netsettings.jobs.remove(0) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class netclientdownload(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientdownload" + __label__ = "Net Render Client Download" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + netsettings = context.scene.network_render + return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 + + def execute(self, context): + netsettings = context.scene.network_render + rd = context.scene.render_data + + conn = clientConnection(context.scene) + + if conn: + job = bpy.data.netrender_jobs[netsettings.active_job_index] + + for frame in job.frames: + client.requestResult(conn, job.id, frame.number) + response = conn.getresponse() + + if response.status != http.client.OK: + print("missing", frame.number) + continue + + print("got back", frame.number) + + f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + conn.close() + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class netclientscan(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientscan" + __label__ = "Net Render Client Scan" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + s.settimeout(30) + + s.bind(('', 8000)) + + buf, address = s.recvfrom(64) + + print("received:", buf) + + netsettings.server_address = address[0] + netsettings.server_port = int(str(buf, encoding='utf8')) + except socket.timeout: + print("no server info") + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) + +@rnaOperator +class netclientweb(bpy.types.Operator): + '''Operator documentation text, will be used for the operator tooltip and python docs.''' + __idname__ = "render.netclientweb" + __label__ = "Net Render Client Web" + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + + __props__ = [] + + def poll(self, context): + return True + + def execute(self, context): + netsettings = context.scene.network_render + + + # open connection to make sure server exists + conn = clientConnection(context.scene) + + if conn: + conn.close() + + webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) + + return ('FINISHED',) + + def invoke(self, context, event): + return self.execute(context) diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py new file mode 100644 index 00000000000..657e31001e0 --- /dev/null +++ b/release/scripts/io/netrender/slave.py @@ -0,0 +1,207 @@ +import sys, os, platform +import http, http.client, http.server, urllib +import subprocess, time + +from netrender.utils import * +import netrender.model + +CANCEL_POLL_SPEED = 2 +MAX_TIMEOUT = 10 +INCREMENT_TIMEOUT = 1 + +if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5 + import ctypes + def SetErrorMode(): + val = ctypes.windll.kernel32.SetErrorMode(0x0002) + ctypes.windll.kernel32.SetErrorMode(val | 0x0002) + return val + + def RestoreErrorMode(val): + ctypes.windll.kernel32.SetErrorMode(val) +else: + def SetErrorMode(): + return 0 + + def RestoreErrorMode(val): + pass + +def slave_Info(): + sysname, nodename, release, version, machine, processor = platform.uname() + slave = netrender.model.RenderSlave() + slave.name = nodename + slave.stats = sysname + " " + release + " " + machine + " " + processor + return slave + +def testCancel(conn, job_id, frame_number): + conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)}) + response = conn.getresponse() + + # cancelled if job isn't found anymore + if response.status == http.client.NO_CONTENT: + return True + else: + return False + +def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None): + job_full_path = prefixPath(JOB_PREFIX, file_path, main_path) + + if not os.path.exists(job_full_path): + temp_path = JOB_PREFIX + "slave.temp.blend" + conn.request("GET", "/file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path}) + response = conn.getresponse() + + if response.status != http.client.OK: + return None # file for job not returned by server, need to return an error code to server + + f = open(temp_path, "wb") + buf = response.read(1024) + + while buf: + f.write(buf) + buf = response.read(1024) + + f.close() + + os.renames(temp_path, job_full_path) + + return job_full_path + + +def render_slave(engine, scene): + netsettings = scene.network_render + timeout = 1 + + engine.update_stats("", "Network render node initiation") + + conn = clientConnection(scene) + + if conn: + conn.request("POST", "/slave", repr(slave_Info().serialize())) + response = conn.getresponse() + + slave_id = response.getheader("slave-id") + + NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep + if not os.path.exists(NODE_PREFIX): + os.mkdir(NODE_PREFIX) + + while not engine.test_break(): + + conn.request("GET", "/job", headers={"slave-id":slave_id}) + response = conn.getresponse() + + if response.status == http.client.OK: + timeout = 1 # reset timeout on new job + + job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8'))) + + JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep + if not os.path.exists(JOB_PREFIX): + os.mkdir(JOB_PREFIX) + + job_path = job.files[0][0] # data in files have format (path, start, end) + main_path, main_file = os.path.split(job_path) + + job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) + print("Fullpath", job_full_path) + print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) + engine.update_stats("", "Render File", main_file, "for job", job.id) + + for file_path, start, end in job.files[1:]: + print("\t", file_path) + testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) + + frame_args = [] + + for frame in job.frames: + print("frame", frame.number) + frame_args += ["-f", str(frame.number)] + + # announce log to master + logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) + conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) + response = conn.getresponse() + + first_frame = job.frames[0].number + + # start render + start_t = time.time() + + val = SetErrorMode() + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) + + headers = {"job-id":job.id, "slave-id":slave_id} + + cancelled = False + stdout = bytes() + run_t = time.time() + while process.poll() == None and not cancelled: + stdout += process.stdout.read(32) + current_t = time.time() + cancelled = engine.test_break() + if current_t - run_t > CANCEL_POLL_SPEED: + + # update logs if needed + if stdout: + # (only need to update on one frame, they are linked + headers["job-frame"] = str(first_frame) + conn.request("PUT", "/log", stdout, headers=headers) + response = conn.getresponse() + + stdout = bytes() + + run_t = current_t + if testCancel(conn, job.id, first_frame): + cancelled = True + + if cancelled: + # kill process if needed + if process.poll() == None: + process.terminate() + continue # to next frame + + total_t = time.time() - start_t + + avg_t = total_t / len(job.frames) + + status = process.returncode + + print("status", status) + + # flush the rest of the logs + if stdout: + # (only need to update on one frame, they are linked + headers["job-frame"] = str(first_frame) + conn.request("PUT", "/log", stdout, headers=headers) + response = conn.getresponse() + + headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} + + if status == 0: # non zero status is error + headers["job-result"] = str(DONE) + for frame in job.frames: + headers["job-frame"] = str(frame.number) + # send result back to server + f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') + conn.request("PUT", "/render", f, headers=headers) + f.close() + response = conn.getresponse() + else: + headers["job-result"] = str(ERROR) + for frame in job.frames: + headers["job-frame"] = str(frame.number) + # send error result back to server + conn.request("PUT", "/render", headers=headers) + response = conn.getresponse() + else: + if timeout < MAX_TIMEOUT: + timeout += INCREMENT_TIMEOUT + + for i in range(timeout): + time.sleep(1) + if engine.test_break(): + conn.close() + return + + conn.close() diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py new file mode 100644 index 00000000000..7681d4865e9 --- /dev/null +++ b/release/scripts/io/netrender/ui.py @@ -0,0 +1,321 @@ +import bpy +import sys, os +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +import netrender.slave as slave +import netrender.master as master + +from netrender.utils import * + +VERSION = b"0.3" + +PATH_PREFIX = "/tmp/" + +QUEUED = 0 +DISPATCHED = 1 +DONE = 2 +ERROR = 3 + +class RenderButtonsPanel(bpy.types.Panel): + __space_type__ = "PROPERTIES" + __region_type__ = "WINDOW" + __context__ = "scene" + # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here + + def poll(self, context): + rd = context.scene.render_data + return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) + +# Setting panel, use in the scene for now. +@rnaType +class SCENE_PT_network_settings(RenderButtonsPanel): + __label__ = "Network Settings" + COMPAT_ENGINES = set(['NET_RENDER']) + + def draw_header(self, context): + layout = self.layout + scene = context.scene + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render_data + + layout.active = True + + split = layout.split() + + col = split.column() + + col.itemR(scene.network_render, "mode") + col.itemR(scene.network_render, "path") + col.itemR(scene.network_render, "server_address") + col.itemR(scene.network_render, "server_port") + + if scene.network_render.mode == "RENDER_MASTER": + col.itemR(scene.network_render, "server_broadcast") + else: + col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="") + +@rnaType +class SCENE_PT_network_job(RenderButtonsPanel): + __label__ = "Job Settings" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render_data + + layout.active = True + + split = layout.split() + + col = split.column() + + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") + col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job") + col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor") + col.itemR(scene.network_render, "job_name") + col.itemR(scene.network_render, "priority") + col.itemR(scene.network_render, "chunks") + +@rnaType +class SCENE_PT_network_slaves(RenderButtonsPanel): + __label__ = "Slaves Status" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + netsettings = scene.network_render + + row = layout.row() + row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2) + + col = row.column() + + subcol = col.column(align=True) + subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") + subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") + + if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0: + while(len(netsettings.slaves) > 0): + netsettings.slaves.remove(0) + + if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0: + layout.itemS() + + slave = bpy.data.netrender_slaves[netsettings.active_slave_index] + + layout.itemL(text="Name: " + slave.name) + layout.itemL(text="Address: " + slave.address[0]) + layout.itemL(text="Seen: " + time.ctime(slave.last_seen)) + layout.itemL(text="Stats: " + slave.stats) + +@rnaType +class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): + __label__ = "Slaves Blacklist" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + netsettings = scene.network_render + + row = layout.row() + row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2) + + col = row.column() + + subcol = col.column(align=True) + subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") + + if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0: + while(len(netsettings.slaves_blacklist) > 0): + netsettings.slaves_blacklist.remove(0) + + if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0: + layout.itemS() + + slave = bpy.data.netrender_blacklist[netsettings.active_blacklisted_slave_index] + + layout.itemL(text="Name: " + slave.name) + layout.itemL(text="Address: " + slave.address[0]) + layout.itemL(text="Seen: " + slave.last_seen) + layout.itemL(text="Stats: " + time.ctime(slave.stats)) + +@rnaType +class SCENE_PT_network_jobs(RenderButtonsPanel): + __label__ = "Jobs" + COMPAT_ENGINES = set(['NET_RENDER']) + + def poll(self, context): + scene = context.scene + return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" + + def draw(self, context): + layout = self.layout + + scene = context.scene + netsettings = scene.network_render + + row = layout.row() + row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2) + + col = row.column() + + subcol = col.column(align=True) + subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") + subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + subcol.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") + subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") + + if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: + while(len(netsettings.jobs) > 0): + netsettings.jobs.remove(0) + + if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0: + layout.itemS() + + job = bpy.data.netrender_jobs[netsettings.active_job_index] + + layout.itemL(text="Name: %s" % job.name) + layout.itemL(text="Length: %04i" % len(job)) + layout.itemL(text="Done: %04i" % job.results[DONE]) + layout.itemL(text="Error: %04i" % job.results[ERROR]) + +@rnaType +class NetRenderSettings(bpy.types.IDPropertyGroup): + pass + +@rnaType +class NetRenderSlave(bpy.types.IDPropertyGroup): + pass + +@rnaType +class NetRenderJob(bpy.types.IDPropertyGroup): + pass + +bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings") + +NetRenderSettings.StringProperty( attr="server_address", + name="Server address", + description="IP or name of the master render server", + maxlen = 128, + default = "[default]") + +NetRenderSettings.IntProperty( attr="server_port", + name="Server port", + description="port of the master render server", + default = 8000, + min=1, + max=65535) + +NetRenderSettings.BoolProperty( attr="server_broadcast", + name="Broadcast server address", + description="broadcast server address on local network", + default = True) + +if os.name == 'nt': + NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = "C:/tmp/") +else: + NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = "/tmp/") + +NetRenderSettings.StringProperty( attr="job_name", + name="Job name", + description="Name of the job", + maxlen = 128, + default = "[default]") + +NetRenderSettings.IntProperty( attr="chunks", + name="Chunks", + description="Number of frame to dispatch to each slave in one chunk", + default = 5, + min=1, + max=65535) + +NetRenderSettings.IntProperty( attr="priority", + name="Priority", + description="Priority of the job", + default = 1, + min=1, + max=10) + +NetRenderSettings.StringProperty( attr="job_id", + name="Network job id", + description="id of the last sent render job", + maxlen = 64, + default = "") + +NetRenderSettings.IntProperty( attr="active_slave_index", + name="Index of the active slave", + description="", + default = -1, + min= -1, + max=65535) + +NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index", + name="Index of the active slave", + description="", + default = -1, + min= -1, + max=65535) + +NetRenderSettings.IntProperty( attr="active_job_index", + name="Index of the active job", + description="", + default = -1, + min= -1, + max=65535) + +NetRenderSettings.EnumProperty(attr="mode", + items=( + ("RENDER_CLIENT", "Client", "Act as render client"), + ("RENDER_MASTER", "Master", "Act as render master"), + ("RENDER_SLAVE", "Slave", "Act as render slave"), + ), + name="network mode", + description="mode of operation of this instance", + default="RENDER_CLIENT") + +NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="") +NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="") +NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="") + +NetRenderSlave.StringProperty( attr="name", + name="Name of the slave", + description="", + maxlen = 64, + default = "") + +NetRenderJob.StringProperty( attr="name", + name="Name of the job", + description="", + maxlen = 128, + default = "") diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py new file mode 100644 index 00000000000..06393a738a0 --- /dev/null +++ b/release/scripts/io/netrender/utils.py @@ -0,0 +1,86 @@ +import bpy +import sys, os +import re +import http, http.client, http.server, urllib +import subprocess, shutil, time, hashlib + +import netrender.model + +VERSION = b"0.5" + +# Jobs status +JOB_WAITING = 0 # before all data has been entered +JOB_PAUSED = 1 # paused by user +JOB_FINISHED = 2 # finished rendering +JOB_QUEUED = 3 # ready to be dispatched + +# Frames status +QUEUED = 0 +DISPATCHED = 1 +DONE = 2 +ERROR = 3 + +STATUS_TEXT = { + QUEUED: "Queued", + DISPATCHED: "Dispatched", + DONE: "Done", + ERROR: "Error" + } + +def rnaType(rna_type): + bpy.types.register(rna_type) + return rna_type + +def rnaOperator(rna_op): + bpy.ops.add(rna_op) + return rna_op + +def clientConnection(scene): + netsettings = scene.network_render + + if netsettings.server_address == "[default]": + bpy.ops.render.netclientscan() + + conn = http.client.HTTPConnection(netsettings.server_address, netsettings.server_port) + + if clientVerifyVersion(conn): + return conn + else: + conn.close() + return None + +def clientVerifyVersion(conn): + conn.request("GET", "/version") + response = conn.getresponse() + + if response.status != http.client.OK: + conn.close() + return False + + server_version = response.read() + + if server_version != VERSION: + print("Incorrect server version!") + print("expected", VERSION, "received", server_version) + return False + + return True + +def prefixPath(prefix_directory, file_path, prefix_path): + if os.path.isabs(file_path): + # if an absolute path, make sure path exists, if it doesn't, use relative local path + full_path = file_path + if not os.path.exists(full_path): + p, n = os.path.split(full_path) + + if prefix_path and p.startswith(prefix_path): + directory = prefix_directory + p[len(prefix_path):] + full_path = directory + n + if not os.path.exists(directory): + os.mkdir(directory) + else: + full_path = prefix_directory + n + else: + full_path = prefix_directory + file_path + + return full_path diff --git a/release/scripts/lightwave_export.py b/release/scripts/lightwave_export.py deleted file mode 100644 index bbfb9649c69..00000000000 --- a/release/scripts/lightwave_export.py +++ /dev/null @@ -1,707 +0,0 @@ -#!BPY - -""" -Name: 'LightWave (.lwo)...' -Blender: 243 -Group: 'Export' -Tooltip: 'Export selected meshes to LightWave File Format (.lwo)' -""" - -__author__ = "Anthony D'Agostino (Scorpius)" -__url__ = ("blender", "blenderartists.org", -"Author's homepage, http://www.redrival.com/scorpius") -__version__ = "Part of IOSuite 0.5" - -__bpydoc__ = """\ -This script exports meshes to LightWave file format. - -LightWave is a full-featured commercial modeling and rendering -application. The lwo file format is composed of 'chunks,' is well -defined, and easy to read and write. It is similar in structure to the -trueSpace cob format. - -Usage:
- Select meshes to be exported and run this script from "File->Export" menu. - -Supported:
- UV Coordinates, Meshes, Materials, Material Indices, Specular -Highlights, and Vertex Colors. For added functionality, each object is -placed on its own layer. Someone added the CLIP chunk and imagename support. - -Missing:
- Not too much, I hope! :). - -Known issues:
- Empty objects crash has been fixed. - -Notes:
- For compatibility reasons, it also reads lwo files in the old LW -v5.5 format. -""" - -# $Id$ -# -# +---------------------------------------------------------+ -# | Copyright (c) 2002 Anthony D'Agostino | -# | http://www.redrival.com/scorpius | -# | scorpius@netzero.com | -# | April 21, 2002 | -# | Read and write LightWave Object File Format (*.lwo) | -# +---------------------------------------------------------+ - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - -import Blender -import BPyMesh -try: import struct -except: struct = None -try: import cStringIO -except: cStringIO = None -try: import operator -except: operator = None - -VCOL_NAME = "\251 Per-Face Vertex Colors" -DEFAULT_NAME = "\251 Blender Default" -# ============================== -# === Write LightWave Format === -# ============================== -def write(filename): - start = Blender.sys.time() - file = open(filename, "wb") - - scn = Blender.Scene.GetCurrent() - objects = list(scn.objects.context) - - if not objects: - Blender.Draw.PupMenu('Error%t|No Objects selected') - return - - try: objects.sort( key = lambda a: a.name ) - except: objects.sort(lambda a,b: cmp(a.name, b.name)) - - text = generate_text() - desc = generate_desc() - icon = "" #generate_icon() - - meshes = [] - mesh_object_name_lookup = {} # for name lookups only - - for obj in objects: - mesh = BPyMesh.getMeshFromObject(obj, None, True, False, scn) - if mesh: - mesh.transform(obj.matrixWorld) - meshes.append(mesh) - mesh_object_name_lookup[mesh] = obj.name - del obj - - material_names = get_used_material_names(meshes) - tags = generate_tags(material_names) - surfs = generate_surfs(material_names) - chunks = [text, desc, icon, tags] - - meshdata = cStringIO.StringIO() - - layer_index = 0 - - for mesh in meshes: - layr = generate_layr(mesh_object_name_lookup[mesh], layer_index) - pnts = generate_pnts(mesh) - bbox = generate_bbox(mesh) - pols = generate_pols(mesh) - ptag = generate_ptag(mesh, material_names) - clip = generate_clip(mesh, material_names) - - if mesh.faceUV: - vmad_uv = generate_vmad_uv(mesh) # per face - - if mesh.vertexColors: - #if meshtools.average_vcols: - # vmap_vc = generate_vmap_vc(mesh) # per vert - #else: - vmad_vc = generate_vmad_vc(mesh) # per face - - write_chunk(meshdata, "LAYR", layr); chunks.append(layr) - write_chunk(meshdata, "PNTS", pnts); chunks.append(pnts) - write_chunk(meshdata, "BBOX", bbox); chunks.append(bbox) - write_chunk(meshdata, "POLS", pols); chunks.append(pols) - write_chunk(meshdata, "PTAG", ptag); chunks.append(ptag) - - if mesh.vertexColors: - #if meshtools.average_vcols: - # write_chunk(meshdata, "VMAP", vmap_vc) - # chunks.append(vmap_vc) - #else: - write_chunk(meshdata, "VMAD", vmad_vc) - chunks.append(vmad_vc) - - if mesh.faceUV: - write_chunk(meshdata, "VMAD", vmad_uv) - chunks.append(vmad_uv) - write_chunk(meshdata, "CLIP", clip) - chunks.append(clip) - - layer_index += 1 - mesh.verts = None # save some ram - - del mesh_object_name_lookup - - for surf in surfs: - chunks.append(surf) - - write_header(file, chunks) - write_chunk(file, "ICON", icon) - write_chunk(file, "TEXT", text) - write_chunk(file, "DESC", desc) - write_chunk(file, "TAGS", tags) - file.write(meshdata.getvalue()); meshdata.close() - for surf in surfs: - write_chunk(file, "SURF", surf) - write_chunk(file, "DATE", "August 19, 2005") - - Blender.Window.DrawProgressBar(1.0, "") # clear progressbar - file.close() - print '\a\r', - print "Successfully exported %s in %.3f seconds" % (filename.split('\\')[-1].split('/')[-1], Blender.sys.time() - start) - - -# ======================================= -# === Generate Null-Terminated String === -# ======================================= -def generate_nstring(string): - if len(string)%2 == 0: # even - string += "\0\0" - else: # odd - string += "\0" - return string - -# =============================== -# === Get Used Material Names === -# =============================== -def get_used_material_names(meshes): - matnames = {} - for mesh in meshes: - if (not mesh.materials) and mesh.vertexColors: - # vcols only - matnames[VCOL_NAME] = None - - elif mesh.materials and (not mesh.vertexColors): - # materials only - for material in mesh.materials: - if material: - matnames[material.name] = None - elif (not mesh.materials) and (not mesh.vertexColors): - # neither - matnames[DEFAULT_NAME] = None - else: - # both - for material in mesh.materials: - if material: - matnames[material.name] = None - return matnames.keys() - -# ========================================= -# === Generate Tag Strings (TAGS Chunk) === -# ========================================= -def generate_tags(material_names): - if material_names: - material_names = map(generate_nstring, material_names) - tags_data = reduce(operator.add, material_names) - else: - tags_data = generate_nstring(''); - return tags_data - -# ======================== -# === Generate Surface === -# ======================== -def generate_surface(name): - #if name.find("\251 Per-") == 0: - # return generate_vcol_surf(mesh) - if name == DEFAULT_NAME: - return generate_default_surf() - else: - return generate_surf(name) - -# ====================== -# === Generate Surfs === -# ====================== -def generate_surfs(material_names): - return map(generate_surface, material_names) - -# =================================== -# === Generate Layer (LAYR Chunk) === -# =================================== -def generate_layr(name, idx): - data = cStringIO.StringIO() - data.write(struct.pack(">h", idx)) # layer number - data.write(struct.pack(">h", 0)) # flags - data.write(struct.pack(">fff", 0, 0, 0)) # pivot - data.write(generate_nstring(name)) # name - return data.getvalue() - -# =================================== -# === Generate Verts (PNTS Chunk) === -# =================================== -def generate_pnts(mesh): - data = cStringIO.StringIO() - for i, v in enumerate(mesh.verts): - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts") - x, y, z = v.co - data.write(struct.pack(">fff", x, z, y)) - return data.getvalue() - -# ========================================== -# === Generate Bounding Box (BBOX Chunk) === -# ========================================== -def generate_bbox(mesh): - data = cStringIO.StringIO() - # need to transform verts here - if mesh.verts: - nv = [v.co for v in mesh.verts] - xx = [ co[0] for co in nv ] - yy = [ co[1] for co in nv ] - zz = [ co[2] for co in nv ] - else: - xx = yy = zz = [0.0,] - - data.write(struct.pack(">6f", min(xx), min(zz), min(yy), max(xx), max(zz), max(yy))) - return data.getvalue() - -# ======================================== -# === Average All Vertex Colors (Fast) === -# ======================================== -''' -def average_vertexcolors(mesh): - vertexcolors = {} - vcolor_add = lambda u, v: [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]] - vcolor_div = lambda u, s: [u[0]/s, u[1]/s, u[2]/s, u[3]/s] - for i, f in enumerate(mesh.faces): # get all vcolors that share this vertex - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors") - col = f.col - for j in xrange(len(f)): - index = f[j].index - color = col[j] - r,g,b = color.r, color.g, color.b - vertexcolors.setdefault(index, []).append([r,g,b,255]) - i = 0 - for index, value in vertexcolors.iteritems(): # average them - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors") - vcolor = [0,0,0,0] # rgba - for v in value: - vcolor = vcolor_add(vcolor, v) - shared = len(value) - value[:] = vcolor_div(vcolor, shared) - i+=1 - return vertexcolors -''' - -# ==================================================== -# === Generate Per-Vert Vertex Colors (VMAP Chunk) === -# ==================================================== -# Blender now has all vcols per face -""" -def generate_vmap_vc(mesh): - data = cStringIO.StringIO() - data.write("RGB ") # type - data.write(struct.pack(">H", 3)) # dimension - data.write(generate_nstring("Blender's Vertex Colors")) # name - vertexcolors = average_vertexcolors(mesh) - for i in xrange(len(vertexcolors)): - try: r, g, b, a = vertexcolors[i] # has a face user - except: r, g, b, a = 255,255,255,255 - data.write(struct.pack(">H", i)) # vertex index - data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0)) - return data.getvalue() -""" - -# ==================================================== -# === Generate Per-Face Vertex Colors (VMAD Chunk) === -# ==================================================== -def generate_vmad_vc(mesh): - data = cStringIO.StringIO() - data.write("RGB ") # type - data.write(struct.pack(">H", 3)) # dimension - data.write(generate_nstring("Blender's Vertex Colors")) # name - for i, f in enumerate(mesh.faces): - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Vertex Colors") - col = f.col - f_v = f.v - for j in xrange(len(f)-1, -1, -1): # Reverse order - r,g,b, dummy = tuple(col[j]) - data.write(struct.pack(">H", f_v[j].index)) # vertex index - data.write(struct.pack(">H", i)) # face index - data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0)) - return data.getvalue() - -# ================================================ -# === Generate Per-Face UV Coords (VMAD Chunk) === -# ================================================ -def generate_vmad_uv(mesh): - layers = mesh.getUVLayerNames() - org_uv = mesh.activeUVLayer - for l in layers: - mesh.activeUVLayer = l - data = cStringIO.StringIO() - data.write("TXUV") # type - data.write(struct.pack(">H", 2)) # dimension - data.write(generate_nstring(l)) # name - for i, f in enumerate(mesh.faces): - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coordinates") - - uv = f.uv - f_v = f.v - for j in xrange(len(f)-1, -1, -1): # Reverse order - U,V = uv[j] - v = f_v[j].index - data.write(struct.pack(">H", v)) # vertex index - data.write(struct.pack(">H", i)) # face index - data.write(struct.pack(">ff", U, V)) - - mesh.activeUVLayer = org_uv - return data.getvalue() - -# ====================================== -# === Generate Variable-Length Index === -# ====================================== -def generate_vx(index): - if index < 0xFF00: - value = struct.pack(">H", index) # 2-byte index - else: - value = struct.pack(">L", index | 0xFF000000) # 4-byte index - return value - -# =================================== -# === Generate Faces (POLS Chunk) === -# =================================== -def generate_pols(mesh): - data = cStringIO.StringIO() - data.write("FACE") # polygon type - for i,f in enumerate(mesh.faces): - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces") - data.write(struct.pack(">H", len(f))) # numfaceverts - numfaceverts = len(f) - f_v = f.v - for j in xrange(numfaceverts-1, -1, -1): # Reverse order - data.write(generate_vx(f_v[j].index)) - return data.getvalue() - -# ================================================= -# === Generate Polygon Tag Mapping (PTAG Chunk) === -# ================================================= -def generate_ptag(mesh, material_names): - - def surf_indicies(mat): - try: - if mat: - return material_names.index(mat.name) - except: - pass - - return 0 - - - data = cStringIO.StringIO() - data.write("SURF") # polygon tag type - mesh_materials = mesh.materials - mesh_surfindicies = [surf_indicies(mat) for mat in mesh_materials] - - try: VCOL_NAME_SURF_INDEX = material_names.index(VCOL_NAME) - except: VCOL_NAME_SURF_INDEX = 0 - - try: DEFAULT_NAME_SURF_INDEX = material_names.index(DEFAULT_NAME) - except: DEFAULT_NAME_SURF_INDEX = 0 - len_mat = len(mesh_materials) - for i, f in enumerate(mesh.faces): # numfaces - f_mat = f.mat - if f_mat >= len_mat: f_mat = 0 # Rare annoying eror - - - if not i%100: - Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Surface Indices") - - data.write(generate_vx(i)) - if (not mesh_materials) and mesh.vertexColors: # vcols only - surfidx = VCOL_NAME_SURF_INDEX - elif mesh_materials and not mesh.vertexColors: # materials only - surfidx = mesh_surfindicies[f_mat] - elif (not mesh_materials) and (not mesh.vertexColors): # neither - surfidx = DEFAULT_NAME_SURF_INDEX - else: # both - surfidx = mesh_surfindicies[f_mat] - - data.write(struct.pack(">H", surfidx)) # surface index - return data.getvalue() - -# =================================================== -# === Generate VC Surface Definition (SURF Chunk) === -# =================================================== -def generate_vcol_surf(mesh): - data = cStringIO.StringIO() - if mesh.vertexColors: - surface_name = generate_nstring(VCOL_NAME) - data.write(surface_name) - data.write("\0\0") - - data.write("COLR") - data.write(struct.pack(">H", 14)) - data.write(struct.pack(">fffH", 1, 1, 1, 0)) - - data.write("DIFF") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", 0.0, 0)) - - data.write("LUMI") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", 1.0, 0)) - - data.write("VCOL") - data.write(struct.pack(">H", 34)) - data.write(struct.pack(">fH4s", 1.0, 0, "RGB ")) # intensity, envelope, type - data.write(generate_nstring("Blender's Vertex Colors")) # name - - data.write("CMNT") # material comment - comment = "Vertex Colors: Exported from Blender\256 243" - comment = generate_nstring(comment) - data.write(struct.pack(">H", len(comment))) - data.write(comment) - return data.getvalue() - -# ================================================ -# === Generate Surface Definition (SURF Chunk) === -# ================================================ -def generate_surf(material_name): - data = cStringIO.StringIO() - data.write(generate_nstring(material_name)) - data.write("\0\0") - - try: - material = Blender.Material.Get(material_name) - R,G,B = material.R, material.G, material.B - ref = material.ref - emit = material.emit - spec = material.spec - hard = material.hard - - except: - material = None - - R=G=B = 1.0 - ref = 1.0 - emit = 0.0 - spec = 0.2 - hard = 0.0 - - - data.write("COLR") - data.write(struct.pack(">H", 14)) - data.write(struct.pack(">fffH", R, G, B, 0)) - - data.write("DIFF") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", ref, 0)) - - data.write("LUMI") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", emit, 0)) - - data.write("SPEC") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", spec, 0)) - - data.write("GLOS") - data.write(struct.pack(">H", 6)) - gloss = hard / (255/2.0) - gloss = round(gloss, 1) - data.write(struct.pack(">fH", gloss, 0)) - - data.write("CMNT") # material comment - comment = material_name + ": Exported from Blender\256 243" - comment = generate_nstring(comment) - data.write(struct.pack(">H", len(comment))) - data.write(comment) - - # Check if the material contains any image maps - if material: - mtextures = material.getTextures() # Get a list of textures linked to the material - for mtex in mtextures: - if (mtex) and (mtex.tex.type == Blender.Texture.Types.IMAGE): # Check if the texture is of type "IMAGE" - data.write("BLOK") # Surface BLOK header - data.write(struct.pack(">H", 104)) # Hardcoded and ugly! Will only handle 1 image per material - - # IMAP subchunk (image map sub header) - data.write("IMAP") - data_tmp = cStringIO.StringIO() - data_tmp.write(struct.pack(">H", 0)) # Hardcoded - not sure what it represents - data_tmp.write("CHAN") - data_tmp.write(struct.pack(">H", 4)) - data_tmp.write("COLR") - data_tmp.write("OPAC") # Hardcoded texture layer opacity - data_tmp.write(struct.pack(">H", 8)) - data_tmp.write(struct.pack(">H", 0)) - data_tmp.write(struct.pack(">f", 1.0)) - data_tmp.write(struct.pack(">H", 0)) - data_tmp.write("ENAB") - data_tmp.write(struct.pack(">HH", 2, 1)) # 1 = texture layer enabled - data_tmp.write("NEGA") - data_tmp.write(struct.pack(">HH", 2, 0)) # Disable negative image (1 = invert RGB values) - data_tmp.write("AXIS") - data_tmp.write(struct.pack(">HH", 2, 1)) - data.write(struct.pack(">H", len(data_tmp.getvalue()))) - data.write(data_tmp.getvalue()) - - # IMAG subchunk - data.write("IMAG") - data.write(struct.pack(">HH", 2, 1)) - data.write("PROJ") - data.write(struct.pack(">HH", 2, 5)) # UV projection - - data.write("VMAP") - uvname = generate_nstring("Blender's UV Coordinates") - data.write(struct.pack(">H", len(uvname))) - data.write(uvname) - - return data.getvalue() - -# ============================================= -# === Generate Default Surface (SURF Chunk) === -# ============================================= -def generate_default_surf(): - data = cStringIO.StringIO() - material_name = DEFAULT_NAME - data.write(generate_nstring(material_name)) - data.write("\0\0") - - data.write("COLR") - data.write(struct.pack(">H", 14)) - data.write(struct.pack(">fffH", 1, 1, 1, 0)) - - data.write("DIFF") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", 0.8, 0)) - - data.write("LUMI") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", 0, 0)) - - data.write("SPEC") - data.write(struct.pack(">H", 6)) - data.write(struct.pack(">fH", 0.5, 0)) - - data.write("GLOS") - data.write(struct.pack(">H", 6)) - gloss = 50 / (255/2.0) - gloss = round(gloss, 1) - data.write(struct.pack(">fH", gloss, 0)) - - data.write("CMNT") # material comment - comment = material_name + ": Exported from Blender\256 243" - - # vals = map(chr, xrange(164,255,1)) - # keys = xrange(164,255,1) - # keys = map(lambda x: `x`, keys) - # comment = map(None, keys, vals) - # comment = reduce(operator.add, comment) - # comment = reduce(operator.add, comment) - - comment = generate_nstring(comment) - data.write(struct.pack(">H", len(comment))) - data.write(comment) - return data.getvalue() - -# ============================================ -# === Generate Object Comment (TEXT Chunk) === -# ============================================ -def generate_text(): - comment = "Lightwave Export Script for Blender by Anthony D'Agostino" - return generate_nstring(comment) - -# ============================================== -# === Generate Description Line (DESC Chunk) === -# ============================================== -def generate_desc(): - comment = "Copyright 2002 Scorpius Entertainment" - return generate_nstring(comment) - -# ================================================== -# === Generate Thumbnail Icon Image (ICON Chunk) === -# ================================================== -def generate_icon(): - data = cStringIO.StringIO() - file = open("f:/obj/radiosity/lwo2_icon.tga", "rb") # 60x60 uncompressed TGA - file.read(18) - icon_data = file.read(3600) # ? - file.close() - data.write(struct.pack(">HH", 0, 60)) - data.write(icon_data) - #print len(icon_data) - return data.getvalue() - -# =============================================== -# === Generate CLIP chunk with STIL subchunks === -# =============================================== -def generate_clip(mesh, material_names): - data = cStringIO.StringIO() - clipid = 1 - for i, material in enumerate(mesh.materials): # Run through list of materials used by mesh - if material: - mtextures = material.getTextures() # Get a list of textures linked to the material - for mtex in mtextures: - if (mtex) and (mtex.tex.type == Blender.Texture.Types.IMAGE): # Check if the texture is of type "IMAGE" - pathname = mtex.tex.image.filename # If full path is needed use filename in place of name - pathname = pathname[0:2] + pathname.replace("\\", "/")[3:] # Convert to Modo standard path - imagename = generate_nstring(pathname) - data.write(struct.pack(">L", clipid)) # CLIP sequence/id - data.write("STIL") # STIL image - data.write(struct.pack(">H", len(imagename))) # Size of image name - data.write(imagename) - clipid += 1 - return data.getvalue() - -# =================== -# === Write Chunk === -# =================== -def write_chunk(file, name, data): - file.write(name) - file.write(struct.pack(">L", len(data))) - file.write(data) - -# ============================= -# === Write LWO File Header === -# ============================= -def write_header(file, chunks): - chunk_sizes = map(len, chunks) - chunk_sizes = reduce(operator.add, chunk_sizes) - form_size = chunk_sizes + len(chunks)*8 + len("FORM") - file.write("FORM") - file.write(struct.pack(">L", form_size)) - file.write("LWO2") - -def fs_callback(filename): - if not filename.lower().endswith('.lwo'): filename += '.lwo' - write(filename) - -if struct and cStringIO and operator: - Blender.Window.FileSelector(fs_callback, "Export LWO", Blender.sys.makename(ext='.lwo')) -else: - Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/lightwave_import.py b/release/scripts/lightwave_import.py deleted file mode 100644 index 6d02467cef8..00000000000 --- a/release/scripts/lightwave_import.py +++ /dev/null @@ -1,1705 +0,0 @@ -#!BPY -""" -Name: 'LightWave (.lwo)...' -Blender: 239 -Group: 'Import' -Tooltip: 'Import LightWave Object File Format' -""" - -__author__ = ["Alessandro Pirovano, Anthony D'Agostino (Scorpius)", "Campbell Barton (ideasman42)", "ZanQdo"] -__url__ = ("www.blender.org", "blenderartist.org", -"Anthony's homepage, http://www.redrival.com/scorpius", "Alessandro's homepage, http://uaraus.altervista.org") - -importername = "lwo_import 0.4.0" - -# +---------------------------------------------------------+ -# | Save your work before and after use. | -# | Please report any useful comment to: | -# | uaraus-dem@yahoo.it | -# | Thanks | -# +---------------------------------------------------------+ -# +---------------------------------------------------------+ -# | Copyright (c) 2002 Anthony D'Agostino | -# | http://www.redrival.com/scorpius | -# | scorpius@netzero.com | -# | April 21, 2002 | -# | Import Export Suite v0.5 | -# +---------------------------------------------------------+ -# | Read and write LightWave Object File Format (*.lwo) | -# +---------------------------------------------------------+ -# +---------------------------------------------------------+ -# | Alessandro Pirovano tweaked starting on March 2005 | -# | http://uaraus.altervista.org | -# +---------------------------------------------------------+ -# +---------------------------------------------------------- -# | GPL license block -# | -# | This program is free software; you can redistribute it and/or modify -# | it under the terms of the GNU General Public License as published by -# | the Free Software Foundation; either version 2 of the License, or -# | (at your option) any later version. -# | -# | This program is distributed in the hope that it will be useful, -# | but WITHOUT ANY WARRANTY; without even the implied warranty of -# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# | GNU General Public License for more details. -# | -# | You should have received a copy of the GNU General Public License -# | along with this program; if not, write to the Free Software -# | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# +---------------------------------------------------------- -# +---------------------------------------------------------+ -# | Release log: | -# | 0.4.0 : Updated for blender 2.44 | -# | ZanQdo - made the mesh import the right way up | -# | Ideasman42 - Updated functions for the bew API | -# | as well as removing the text object class | -# | 0.2.2 : This code works with Blender 2.42 RC3 | -# | Added a new PolyFill function for BPYMesh's | -# | ngon() to use, checked compatibility | -# | lightwaves ngons are imported as fgons | -# | Checked compatibility against 1711 lwo files | -# | 0.2.1 : This code works with Blender 2.40 RC1 | -# | modified material mode assignment to deal with | -# | Python API modification | -# | Changed script license to GNU GPL | -# | 0.2.0: This code works with Blender 2.40a2 or up | -# | Major rewrite to deal with large meshes | -# | - 2 pass file parsing | -# | - lower memory foot###if DEBUG: print | -# | (as long as python gc allows) | -# | 2.40a2 - Removed subsurf settings patches=poly | -# | 2.40a2 - Edge generation instead of 2vert faces | -# | 0.1.16: fixed (try 2) texture offset calculations | -# | added hint on axis mapping | -# | added hint on texture blending mode | -# | added hint on texture transparency setting | -# | search images in original directory first | -# | fixed texture order application | -# | 0.1.15: added release log | -# | fixed texture offset calculations (non-UV) | -# | fixed reverting vertex order in face generation | -# | associate texture on game-engine settings | -# | vector math definitely based on mathutils | -# | search images in "Images" and "../Images" dir | -# | revised logging facility | -# | fixed subsurf texture and material mappings | -# | 0.1.14: patched missing mod_vector (not definitive) | -# | 0.1.13: first public release | -# +---------------------------------------------------------+ - -#blender related import -import Blender -import bpy - -# use for comprehensiveImageLoad -import BPyImage - -# Use this ngon function -import BPyMesh - -import BPyMessages - -#python specific modules import -try: - import struct, chunk, cStringIO -except: - struct= chunk= cStringIO= None - -# python 2.3 has no reversed() iterator. this will only work on lists and tuples -try: - reversed -except: - def reversed(l): return l[::-1] - -### # Debuggin disabled in release. -### # do a search replace to enabe debug prints -### DEBUG = False - -# =========================================================== -# === Utility Preamble ====================================== -# =========================================================== - -textname = None -#uncomment the following line to enable logging facility to the named text object -#textname = "lwo_log" - -TXMTX = Blender.Mathutils.Matrix(\ -[1, 0, 0, 0],\ -[0, 0, 1, 0],\ -[0, 1, 0, 0],\ -[0, 0, 0, 1]) - -# =========================================================== -# === Make sure it is a string ... deal with strange chars == -# =========================================================== -def safestring(st): - myst = "" - for ll in xrange(len(st)): - if st[ll] < " ": - myst += "#" - else: - myst += st[ll] - return myst - -# =========================================================== -# === Main read functions =================================== -# =========================================================== - -# ============================= -# === Read LightWave Format === -# ============================= -def read(filename): - if BPyMessages.Error_NoFile(filename): - return - - print "This is: %s" % importername - print "Importing file:", filename - bpy.data.scenes.active.objects.selected = [] - - start = Blender.sys.time() - file = open(filename, "rb") - - editmode = Blender.Window.EditMode() # are we in edit mode? If so ... - if editmode: Blender.Window.EditMode(0) # leave edit mode before getting the mesh # === LWO header === - - try: - form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12)) - except: - Blender.Draw.PupMenu('Error%t|This is not a lightwave file') - return - - if (form_type == "LWOB"): - read_lwob(file, filename) - elif (form_type == "LWO2"): - read_lwo2(file, filename) - else: - print "Can't read a file with the form_type: %s" % form_type - return - - Blender.Window.DrawProgressBar(1.0, "") # clear progressbar - file.close() - end = Blender.sys.time() - seconds = " in %.2f %s" % (end-start, "seconds") - if form_type == "LWO2": fmt = " (v6.0 Format)" - if form_type == "LWOB": fmt = " (v5.5 Format)" - print "Successfully imported " + filename.split('\\')[-1].split('/')[-1] + fmt + seconds - - if editmode: Blender.Window.EditMode(1) # optional, just being nice - Blender.Redraw() - -# enddef read - - -# ================================= -# === Read LightWave 5.5 format === -# ================================= -def read_lwob(file, filename): - #This function is directly derived from the LWO2 import routine - #dropping all the material analysis parts - - ###if DEBUG: print "LightWave 5.5 format" - - dir_part = Blender.sys.dirname(filename) - fname_part = Blender.sys.basename(filename) - #ask_weird = 1 - - #first initialization of data structures - defaultname = Blender.sys.splitext(fname_part)[0] - tag_list = [] #tag list: global for the whole file? - surf_list = [] #surf list: global for the whole file? - clip_list = [] #clip list: global for the whole file? - object_index = 0 - object_list = None - objspec_list = None - - #add default material for orphaned faces, if any - surf_list.append({'NAME': "_Orphans", 'g_MAT': bpy.data.materials.new("_Orphans")}) - - #pass 2: effectively generate objects - ###if DEBUG: print "Pass 1: dry import" - file.seek(0) - objspec_list = ["imported", {}, [], [], {}, {}, 0, {}, {}] - # === LWO header === - form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12)) - if (form_type != "LWOB"): - ###if DEBUG: print "??? Inconsistent file type: %s" % form_type - return - while 1: - try: - lwochunk = chunk.Chunk(file) - except EOFError: - break - ###if DEBUG: print ' ', - if lwochunk.chunkname == "LAYR": - ###if DEBUG: print "---- LAYR", - objname = read_layr(lwochunk) - ###if DEBUG: print objname - if objspec_list != None: #create the object - create_objects(clip_list, objspec_list, surf_list) - update_material(clip_list, objspec_list, surf_list) #give it all the object - objspec_list = [objname, {}, [], [], {}, {}, 0, {}, {}] - object_index += 1 - elif lwochunk.chunkname == "PNTS": # Verts - ###if DEBUG: print "---- PNTS", - verts = read_verts(lwochunk) - objspec_list[2] = verts - elif lwochunk.chunkname == "POLS": # Faces v5.5 - ###if DEBUG: print "-------- POLS(5.5)" - faces = read_faces_5(lwochunk) - flag = 0 - #flag is 0 for regular polygon, 1 for patches (= subsurf), 2 for anything else to be ignored - if flag<2: - if objspec_list[3] != []: - #create immediately the object - create_objects(clip_list, objspec_list, surf_list) - update_material(clip_list, objspec_list, surf_list) #give it all the object - #update with new data - objspec_list = [objspec_list[0], #update name - {}, #init - objspec_list[2], #same vertexes - faces, #give it the new faces - {}, #no need to copy - filled at runtime - {}, #polygon tagging will follow - flag, #patch flag - objspec_list[7], #same uvcoords - {}] #no vmad mapping - object_index += 1 - #end if already has a face list - objspec_list[3] = faces - objname = objspec_list[0] - if objname == None: - objname = defaultname - #end if processing a valid poly type - else: # Misc Chunks - ###if DEBUG: print "---- %s: skipping (definitely!)" % lwochunk.chunkname - lwochunk.skip() - #uncomment here to log data structure as it is built - # ###if DEBUG: print object_list - #last object read - create_objects(clip_list, objspec_list, surf_list) - update_material(clip_list, objspec_list, surf_list) #give it all the object - objspec_list = None - surf_list = None - clip_list = None - - - ###if DEBUG: print "\nFound %d objects:" % object_index - -# enddef read_lwob - - -# ============================= -# === Read LightWave Format === -# ============================= -def read_lwo2(file, filename, typ="LWO2"): - - ###if DEBUG: print "LightWave 6 (and above) format" - - dir_part = Blender.sys.dirname(filename) - fname_part = Blender.sys.basename(filename) - ask_weird = 1 - - #first initialization of data structures - defaultname = Blender.sys.splitext(fname_part)[0] - tag_list = [] #tag list: global for the whole file? - surf_list = [] #surf list: global for the whole file? - clip_list = [] #clip list: global for the whole file? - object_index = 0 - object_list = None - objspec_list = None - # init value is: object_list = [[None, {}, [], [], {}, {}, 0, {}, {}]] - #0 - objname #original name - #1 - obj_dict = {TAG} #objects created - #2 - verts = [] #object vertexes - #3 - faces = [] #object faces (associations poly -> vertexes) - #4 - obj_dim_dict = {TAG} #tuples size and pos in local object coords - used for NON-UV mappings - #5 - polytag_dict = {TAG} #tag to polygons mapping - #6 - patch_flag #0 = surf; 1 = patch (subdivision surface) - it was the image list - #7 - uvcoords_dict = {name} #uvmap coordinates (mixed mode per vertex/per face) - #8 - facesuv_dict = {name} #vmad only coordinates associations poly & vertex -> uv tuples - - #pass 1: look in advance for materials - ###if DEBUG: print "Starting Pass 1: hold on tight" - while 1: - try: - lwochunk = chunk.Chunk(file) - except EOFError: - break - ###if DEBUG: print ' ', - if lwochunk.chunkname == "TAGS": # Tags - ###if DEBUG: print "---- TAGS" - tag_list.extend(read_tags(lwochunk)) - elif lwochunk.chunkname == "SURF": # surfaces - ###if DEBUG: print "---- SURF" - surf_list.append(read_surfs(lwochunk, surf_list, tag_list)) - elif lwochunk.chunkname == "CLIP": # texture images - ###if DEBUG: print "---- CLIP" - clip_list.append(read_clip(lwochunk, dir_part)) - ###if DEBUG: print "read total %s clips up to now" % len(clip_list) - else: # Misc Chunks - if ask_weird: - ckname = safestring(lwochunk.chunkname) - if "#" in ckname: - choice = Blender.Draw.PupMenu("WARNING: file could be corrupted.%t|Import anyway|Give up") - if choice != 1: - ###if DEBUG: print "---- %s: Maybe file corrupted. Terminated by user" % lwochunk.chunkname - return - ask_weird = 0 - ###if DEBUG: print "---- %s: skipping (maybe later)" % lwochunk.chunkname - lwochunk.skip() - - #add default material for orphaned faces, if any - surf_list.append({'NAME': "_Orphans", 'g_MAT': bpy.data.materials.new("_Orphans")}) - - #pass 2: effectively generate objects - ###if DEBUG: print "Pass 2: now for the hard part" - file.seek(0) - # === LWO header === - form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12)) - if (form_type != "LWO2"): - ###if DEBUG: print "??? Inconsistent file type: %s" % form_type - return - while 1: - try: - lwochunk = chunk.Chunk(file) - except EOFError: - break - ###if DEBUG: print ' ', - if lwochunk.chunkname == "LAYR": - ###if DEBUG: print "---- LAYR" - objname = read_layr(lwochunk) - ###if DEBUG: print objname - if objspec_list != None: #create the object - create_objects(clip_list, objspec_list, surf_list) - update_material(clip_list, objspec_list, surf_list) #give it all the object - objspec_list = [objname, {}, [], [], {}, {}, 0, {}, {}] - object_index += 1 - elif lwochunk.chunkname == "PNTS": # Verts - ###if DEBUG: print "---- PNTS" - verts = read_verts(lwochunk) - objspec_list[2] = verts - elif lwochunk.chunkname == "VMAP": # MAPS (UV) - ###if DEBUG: print "---- VMAP" - #objspec_list[7] = read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk) - read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk) - elif lwochunk.chunkname == "VMAD": # MAPS (UV) per-face - ###if DEBUG: print "---- VMAD" - #objspec_list[7], objspec_list[8] = read_vmad(objspec_list[7], objspec_list[8], len(objspec_list[3]), len(objspec_list[2]), lwochunk) - read_vmad(objspec_list[7], objspec_list[8], len(objspec_list[3]), len(objspec_list[2]), lwochunk) - elif lwochunk.chunkname == "POLS": # Faces v6.0 - ###if DEBUG: print "-------- POLS(6)" - faces, flag = read_faces_6(lwochunk) - #flag is 0 for regular polygon, 1 for patches (= subsurf), 2 for anything else to be ignored - if flag<2: - if objspec_list[3] != []: - #create immediately the object - create_objects(clip_list, objspec_list, surf_list) - update_material(clip_list, objspec_list, surf_list) #give it all the object - #update with new data - objspec_list = [objspec_list[0], #update name - {}, #init - objspec_list[2], #same vertexes - faces, #give it the new faces - {}, #no need to copy - filled at runtime - {}, #polygon tagging will follow - flag, #patch flag - objspec_list[7], #same uvcoords - {}] #no vmad mapping - object_index += 1 - #end if already has a face list - objspec_list[3] = faces - objname = objspec_list[0] - if objname == None: - objname = defaultname - #end if processing a valid poly type - elif lwochunk.chunkname == "PTAG": # PTags - ###if DEBUG: print "---- PTAG" - polytag_dict = read_ptags(lwochunk, tag_list) - for kk, polytag_dict_val in polytag_dict.iteritems(): objspec_list[5][kk] = polytag_dict_val - else: # Misc Chunks - ###if DEBUG: print "---- %s: skipping (definitely!)" % lwochunk.chunkname - lwochunk.skip() - #uncomment here to log data structure as it is built - - #last object read - create_objects(clip_list, objspec_list, surf_list) - update_material(clip_list, objspec_list, surf_list) #give it all the object - objspec_list = None - surf_list = None - clip_list = None - - ###if DEBUG: print "\nFound %d objects:" % object_index -# enddef read_lwo2 - - - - - - -# =========================================================== -# === File reading routines ================================= -# =========================================================== -# ================== -# === Read Verts === -# ================== -def read_verts(lwochunk): - #data = cStringIO.StringIO(lwochunk.read()) - numverts = lwochunk.chunksize/12 - return [struct.unpack(">fff", lwochunk.read(12)) for i in xrange(numverts)] -# enddef read_verts - - -# ================= -# === Read Name === -# ================= -# modified to deal with odd lenght strings -def read_name(file): - name = "" - while 1: - char = file.read(1) - if char == "\0": break - else: name += char - len_name = len(name) + 1 #count the trailing zero - if len_name%2==1: - char = file.read(1) #remove zero padding to even lenght - len_name += 1 - return name, len_name - - -# ================== -# === Read Layer === -# ================== -def read_layr(lwochunk): - data = cStringIO.StringIO(lwochunk.read()) - idx, flags = struct.unpack(">hh", data.read(4)) - pivot = struct.unpack(">fff", data.read(12)) - layer_name, discard = read_name(data) - if not layer_name: layer_name = "NoName" - return layer_name -# enddef read_layr - - -# ====================== -# === Read Faces 5.5 === -# ====================== -def read_faces_5(lwochunk): - data = cStringIO.StringIO(lwochunk.read()) - faces = [] - i = 0 - while i < lwochunk.chunksize: - #if not i%1000 and my_meshtools.show_progress: - # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces") - - numfaceverts, = struct.unpack(">H", data.read(2)) - facev = [struct.unpack(">H", data.read(2))[0] for j in xrange(numfaceverts)] - facev.reverse() - faces.append(facev) - surfaceindex, = struct.unpack(">H", data.read(2)) - if surfaceindex < 0: - ###if DEBUG: print "***Error. Referencing uncorrect surface index" - return - i += (4+numfaceverts*2) - return faces - - -# ================================== -# === Read Variable-Length Index === -# ================================== -def read_vx(data): - byte1, = struct.unpack(">B", data.read(1)) - if byte1 != 0xFF: # 2-byte index - byte2, = struct.unpack(">B", data.read(1)) - index = byte1*256 + byte2 - index_size = 2 - else: # 4-byte index - byte2, byte3, byte4 = struct.unpack(">3B", data.read(3)) - index = byte2*65536 + byte3*256 + byte4 - index_size = 4 - return index, index_size - - -# ====================== -# === Read uvmapping === -# ====================== -def read_vmap(uvcoords_dict, maxvertnum, lwochunk): - - if maxvertnum == 0: - ###if DEBUG: print "Found VMAP but no vertexes to map!" - return uvcoords_dict - data = cStringIO.StringIO(lwochunk.read()) - map_type = data.read(4) - if map_type != "TXUV": - ###if DEBUG: print "Reading VMAP: No Texture UV map Were Found. Map Type: %s" % map_type - return uvcoords_dict - dimension, = struct.unpack(">H", data.read(2)) - name, i = read_name(data) #i initialized with string lenght + zeros - ###if DEBUG: print "TXUV %d %s" % (dimension, name) - #note if there is already a VMAD it will be lost - #it is assumed that VMAD will follow the corresponding VMAP - Vector = Blender.Mathutils.Vector - try: #if uvcoords_dict.has_key(name): - my_uv_dict = uvcoords_dict[name] #update existing - except: #else: - my_uv_dict = {} #start a brand new: this could be made more smart - while (i < lwochunk.chunksize - 6): #4+2 header bytes already read - vertnum, vnum_size = read_vx(data) - uv = struct.unpack(">ff", data.read(8)) - if vertnum >= maxvertnum: - ###if DEBUG: print "Hem: more uvmap than vertexes? ignoring uv data for vertex %d" % vertnum - pass - else: - my_uv_dict[vertnum] = Vector(uv) - i += 8 + vnum_size - #end loop on uv pairs - uvcoords_dict[name] = my_uv_dict - #this is a per-vertex mapping AND the uv tuple is vertex-ordered, so faces_uv is the same as faces - #return uvcoords_dict - return - -# ======================== -# === Read uvmapping 2 === -# ======================== -def read_vmad(uvcoords_dict, facesuv_dict, maxfacenum, maxvertnum, lwochunk): - if maxvertnum == 0 or maxfacenum == 0: - ###if DEBUG: print "Found VMAD but no vertexes to map!" - return uvcoords_dict, facesuv_dict - data = cStringIO.StringIO(lwochunk.read()) - map_type = data.read(4) - if map_type != "TXUV": - ###if DEBUG: print "Reading VMAD: No Texture UV map Were Found. Map Type: %s" % map_type - return uvcoords_dict, facesuv_dict - dimension, = struct.unpack(">H", data.read(2)) - name, i = read_name(data) #i initialized with string lenght + zeros - ###if DEBUG: print "TXUV %d %s" % (dimension, name) - try: #if uvcoords_dict.has_key(name): - my_uv_dict = uvcoords_dict[name] #update existing - except: #else: - my_uv_dict = {} #start a brand new: this could be made more smart - my_facesuv_list = [] - newindex = maxvertnum + 10 #why +10? Why not? - #end variable initialization - Vector = Blender.Mathutils.Vector - while (i < lwochunk.chunksize - 6): #4+2 header bytes already read - vertnum, vnum_size = read_vx(data) - i += vnum_size - polynum, vnum_size = read_vx(data) - i += vnum_size - uv = struct.unpack(">ff", data.read(8)) - if polynum >= maxfacenum or vertnum >= maxvertnum: - ###if DEBUG: print "Hem: more uvmap than vertexes? ignorig uv data for vertex %d" % vertnum - pass - else: - my_uv_dict[newindex] = Vector(uv) - my_facesuv_list.append([polynum, vertnum, newindex]) - newindex += 1 - i += 8 - #end loop on uv pairs - uvcoords_dict[name] = my_uv_dict - facesuv_dict[name] = my_facesuv_list - ###if DEBUG: print "updated %d vertexes data" % (newindex-maxvertnum-10) - return - - -# ================= -# === Read tags === -# ================= -def read_tags(lwochunk): - data = cStringIO.StringIO(lwochunk.read()) - tag_list = [] - current_tag = "" - i = 0 - while i < lwochunk.chunksize: - char = data.read(1) - if char == "\0": - tag_list.append(current_tag) - if (len(current_tag) % 2 == 0): char = data.read(1) - current_tag = "" - else: - current_tag += char - i += 1 - ###if DEBUG: print "read %d tags, list follows: %s" % (len(tag_list), tag_list) - return tag_list - - -# ================== -# === Read Ptags === -# ================== -def read_ptags(lwochunk, tag_list): - data = cStringIO.StringIO(lwochunk.read()) - polygon_type = data.read(4) - if polygon_type != "SURF": - ###if DEBUG: print "No Surf Were Found. Polygon Type: %s" % polygon_type - return {} - ptag_dict = {} - i = 0 - while(i < lwochunk.chunksize-4): #4 bytes polygon type already read - #if not i%1000 and my_meshtools.show_progress: - # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading PTAGS") - poln, poln_size = read_vx(data) - i += poln_size - tag_index, = struct.unpack(">H", data.read(2)) - if tag_index > (len(tag_list)): - ###if DEBUG: print "Reading PTAG: Surf belonging to undefined TAG: %d. Skipping" % tag_index - return {} - i += 2 - tag_key = tag_list[tag_index] - try: - ptag_dict[tag_list[tag_index]].append(poln) - except: #if not(ptag_dict.has_key(tag_key)): - ptag_dict[tag_list[tag_index]] = [poln] - - ###if DEBUG: for i, ptag_dict_val in ptag_dict.iteritems(): print "read %d polygons belonging to TAG %s" % (len(ptag_dict_val ), i) - return ptag_dict - - - -# ================== -# === Read Clips === -# ================== -def read_clip(lwochunk, dir_part): -# img, IMG, g_IMG refers to blender image objects -# ima, IMAG, g_IMAG refers to clip dictionary 'ID' entries: refer to blok and surf - clip_dict = {} - data = cStringIO.StringIO(lwochunk.read()) - data_str = data.read(4) - if len(data_str) < 4: # can be zero also??? :/ - # Should not happen but lw can import so we should too - return - - image_index, = struct.unpack(">L", data_str) - clip_dict['ID'] = image_index - i = 4 - while(i < lwochunk.chunksize): - subchunkname, = struct.unpack("4s", data.read(4)) - subchunklen, = struct.unpack(">H", data.read(2)) - if subchunkname == "STIL": - ###if DEBUG: print "-------- STIL" - clip_name, k = read_name(data) - #now split text independently from platform - #depend on the system where image was saved. NOT the one where the script is run - no_sep = "\\" - if Blender.sys.sep == no_sep: no_sep ="/" - if (no_sep in clip_name): - clip_name = clip_name.replace(no_sep, Blender.sys.sep) - short_name = Blender.sys.basename(clip_name) - if clip_name == "" or short_name == "": - ###if DEBUG: print "Reading CLIP: Empty clip name not allowed. Skipping" - discard = data.read(subchunklen-k) - clip_dict['NAME'] = clip_name - clip_dict['BASENAME'] = short_name - elif subchunkname == "XREF": #cross reference another image - ###if DEBUG: print "-------- XREF" - image_index, = struct.unpack(">L", data.read(4)) - clip_name, k = read_name(data) - clip_dict['NAME'] = clip_name - clip_dict['XREF'] = image_index - elif subchunkname == "NEGA": #negate texture effect - ###if DEBUG: print "-------- NEGA" - n, = struct.unpack(">H", data.read(2)) - clip_dict['NEGA'] = n - else: # Misc Chunks - ###if DEBUG: print "-------- CLIP:%s: skipping" % subchunkname - discard = data.read(subchunklen) - i = i + 6 + subchunklen - #end loop on surf chunks - ###if DEBUG: print "read image:%s" % clip_dict - if 'XREF' in clip_dict: # has_key - ###if DEBUG: print "Cross-reference: no image pre-allocated." - return clip_dict - #look for images - #img = load_image("",clip_dict['NAME']) - NAME= BASENAME= None - - try: - NAME= clip_dict['NAME'] - BASENAME= clip_dict['BASENAME'] - except: - clip_dict['g_IMG'] = None - return - # ###if DEBUG: print 'test', NAME, BASENAME - img = BPyImage.comprehensiveImageLoad(NAME, dir_part, PLACE_HOLDER= False, RECURSIVE=False) - if not img: - ###if DEBUG: print "***No image %s found: trying LWO file subdir" % NAME - img = BPyImage.comprehensiveImageLoad(BASENAME, dir_part, PLACE_HOLDER= False, RECURSIVE=False) - - ###if DEBUG: if not img: print "***No image %s found: giving up" % BASENAME - #lucky we are: we have an image - ###if DEBUG: print "Image pre-allocated." - clip_dict['g_IMG'] = img - - return clip_dict - - -# =========================== -# === Read Surfaces Block === -# =========================== -def read_surfblok(subchunkdata): - lenght = len(subchunkdata) - my_dict = {} - my_uvname = "" - data = cStringIO.StringIO(subchunkdata) - ############################################################## - # blok header sub-chunk - ############################################################## - subchunkname, = struct.unpack("4s", data.read(4)) - subchunklen, = struct.unpack(">h", data.read(2)) - accumulate_i = subchunklen + 6 - if subchunkname != 'IMAP': - ###if DEBUG: print "---------- SURF: BLOK: %s: block aborting" % subchunkname - return {}, "" - ###if DEBUG: print "---------- IMAP" - ordinal, i = read_name(data) - my_dict['ORD'] = ordinal - #my_dict['g_ORD'] = -1 - my_dict['ENAB'] = True - while(i < subchunklen): # ---------left 6------------------------- loop on header parameters - sub2chunkname, = struct.unpack("4s", data.read(4)) - sub2chunklen, = struct.unpack(">h", data.read(2)) - i = i + 6 + sub2chunklen - if sub2chunkname == "CHAN": - ###if DEBUG: print "------------ CHAN" - sub2chunkname, = struct.unpack("4s", data.read(4)) - my_dict['CHAN'] = sub2chunkname - sub2chunklen -= 4 - elif sub2chunkname == "ENAB": #only present if is to be disabled - ###if DEBUG: print "------------ ENAB" - ena, = struct.unpack(">h", data.read(2)) - my_dict['ENAB'] = ena - sub2chunklen -= 2 - elif sub2chunkname == "NEGA": #only present if is to be enabled - ###if DEBUG: print "------------ NEGA" - ena, = struct.unpack(">h", data.read(2)) - if ena == 1: - my_dict['NEGA'] = ena - sub2chunklen -= 2 - elif sub2chunkname == "OPAC": #only present if is to be disabled - ###if DEBUG: print "------------ OPAC" - opa, = struct.unpack(">h", data.read(2)) - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['OPAC'] = opa - my_dict['OPACVAL'] = s - sub2chunklen -= 6 - elif sub2chunkname == "AXIS": - ###if DEBUG: print "------------ AXIS" - ena, = struct.unpack(">h", data.read(2)) - my_dict['DISPLAXIS'] = ena - sub2chunklen -= 2 - else: # Misc Chunks - ###if DEBUG: print "------------ SURF: BLOK: IMAP: %s: skipping" % sub2chunkname - discard = data.read(sub2chunklen) - #end loop on blok header subchunks - ############################################################## - # blok attributes sub-chunk - ############################################################## - subchunkname, = struct.unpack("4s", data.read(4)) - subchunklen, = struct.unpack(">h", data.read(2)) - accumulate_i += subchunklen + 6 - if subchunkname != 'TMAP': - ###if DEBUG: print "---------- SURF: BLOK: %s: block aborting" % subchunkname - return {}, "" - ###if DEBUG: print "---------- TMAP" - i = 0 - while(i < subchunklen): # -----------left 6----------------------- loop on header parameters - sub2chunkname, = struct.unpack("4s", data.read(4)) - sub2chunklen, = struct.unpack(">h", data.read(2)) - i = i + 6 + sub2chunklen - if sub2chunkname == "CNTR": - ###if DEBUG: print "------------ CNTR" - x, y, z = struct.unpack(">fff", data.read(12)) - envelope, env_size = read_vx(data) - my_dict['CNTR'] = [x, y, z] - sub2chunklen -= (12+env_size) - elif sub2chunkname == "SIZE": - ###if DEBUG: print "------------ SIZE" - x, y, z = struct.unpack(">fff", data.read(12)) - envelope, env_size = read_vx(data) - my_dict['SIZE'] = [x, y, z] - sub2chunklen -= (12+env_size) - elif sub2chunkname == "ROTA": - ###if DEBUG: print "------------ ROTA" - x, y, z = struct.unpack(">fff", data.read(12)) - envelope, env_size = read_vx(data) - my_dict['ROTA'] = [x, y, z] - sub2chunklen -= (12+env_size) - elif sub2chunkname == "CSYS": - ###if DEBUG: print "------------ CSYS" - ena, = struct.unpack(">h", data.read(2)) - my_dict['CSYS'] = ena - sub2chunklen -= 2 - else: # Misc Chunks - ###if DEBUG: print "------------ SURF: BLOK: TMAP: %s: skipping" % sub2chunkname - pass - if sub2chunklen > 0: - discard = data.read(sub2chunklen) - #end loop on blok attributes subchunks - ############################################################## - # ok, now other attributes without sub_chunks - ############################################################## - while(accumulate_i < lenght): # ---------------------------------- loop on header parameters: lenght has already stripped the 6 bypes header - subchunkname, = struct.unpack("4s", data.read(4)) - subchunklen, = struct.unpack(">H", data.read(2)) - accumulate_i = accumulate_i + 6 + subchunklen - if subchunkname == "PROJ": - ###if DEBUG: print "---------- PROJ" - p, = struct.unpack(">h", data.read(2)) - my_dict['PROJ'] = p - subchunklen -= 2 - elif subchunkname == "AXIS": - ###if DEBUG: print "---------- AXIS" - a, = struct.unpack(">h", data.read(2)) - my_dict['MAJAXIS'] = a - subchunklen -= 2 - elif subchunkname == "IMAG": - ###if DEBUG: print "---------- IMAG" - i, i_size = read_vx(data) - my_dict['IMAG'] = i - subchunklen -= i_size - elif subchunkname == "WRAP": - ###if DEBUG: print "---------- WRAP" - ww, wh = struct.unpack(">hh", data.read(4)) - #reduce width and height to just 1 parameter for both - my_dict['WRAP'] = max([ww,wh]) - #my_dict['WRAPWIDTH'] = ww - #my_dict['WRAPHEIGHT'] = wh - subchunklen -= 4 - elif subchunkname == "WRPW": - ###if DEBUG: print "---------- WRPW" - w, = struct.unpack(">f", data.read(4)) - my_dict['WRPW'] = w - envelope, env_size = read_vx(data) - subchunklen -= (env_size+4) - elif subchunkname == "WRPH": - ###if DEBUG: print "---------- WRPH" - w, = struct.unpack(">f", data.read(4)) - my_dict['WRPH'] = w - envelope, env_size = read_vx(data) - subchunklen -= (env_size+4) - elif subchunkname == "VMAP": - ###if DEBUG: print "---------- VMAP" - vmp, i = read_name(data) - my_dict['VMAP'] = vmp - my_uvname = vmp - subchunklen -= i - else: # Misc Chunks - ###if DEBUG: print "---------- SURF: BLOK: %s: skipping" % subchunkname - pass - if subchunklen > 0: - discard = data.read(subchunklen) - #end loop on blok subchunks - return my_dict, my_uvname - - -# ===================== -# === Read Surfaces === -# ===================== -def read_surfs(lwochunk, surf_list, tag_list): - my_dict = {} - data = cStringIO.StringIO(lwochunk.read()) - surf_name, i = read_name(data) - parent_name, j = read_name(data) - i += j - if (surf_name == "") or not(surf_name in tag_list): - ###if DEBUG: print "Reading SURF: Actually empty surf name not allowed. Skipping" - return {} - if (parent_name != ""): - parent_index = [x['NAME'] for x in surf_list].count(parent_name) - if parent_index >0: - my_dict = surf_list[parent_index-1] - my_dict['NAME'] = surf_name - ###if DEBUG: print "Surface data for TAG %s" % surf_name - while(i < lwochunk.chunksize): - subchunkname, = struct.unpack("4s", data.read(4)) - subchunklen, = struct.unpack(">H", data.read(2)) - i = i + 6 + subchunklen #6 bytes subchunk header - if subchunkname == "COLR": #color: mapped on color - ###if DEBUG: print "-------- COLR" - r, g, b = struct.unpack(">fff", data.read(12)) - envelope, env_size = read_vx(data) - my_dict['COLR'] = [r, g, b] - subchunklen -= (12+env_size) - elif subchunkname == "DIFF": #diffusion: mapped on reflection (diffuse shader) - ###if DEBUG: print "-------- DIFF" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['DIFF'] = s - subchunklen -= (4+env_size) - elif subchunkname == "SPEC": #specularity: mapped to specularity (spec shader) - ###if DEBUG: print "-------- SPEC" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['SPEC'] = s - subchunklen -= (4+env_size) - elif subchunkname == "REFL": #reflection: mapped on raymirror - ###if DEBUG: print "-------- REFL" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['REFL'] = s - subchunklen -= (4+env_size) - elif subchunkname == "TRNL": #translucency: mapped on same param - ###if DEBUG: print "-------- TRNL" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['TRNL'] = s - subchunklen -= (4+env_size) - elif subchunkname == "GLOS": #glossiness: mapped on specularity hardness (spec shader) - ###if DEBUG: print "-------- GLOS" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['GLOS'] = s - subchunklen -= (4+env_size) - elif subchunkname == "TRAN": #transparency: inverted and mapped on alpha channel - ###if DEBUG: print "-------- TRAN" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['TRAN'] = s - subchunklen -= (4+env_size) - elif subchunkname == "LUMI": #luminosity: mapped on emit channel - ###if DEBUG: print "-------- LUMI" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['LUMI'] = s - subchunklen -= (4+env_size) - elif subchunkname == "GVAL": #glow: mapped on add channel - ###if DEBUG: print "-------- GVAL" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['GVAL'] = s - subchunklen -= (4+env_size) - elif subchunkname == "SMAN": #smoothing angle - ###if DEBUG: print "-------- SMAN" - s, = struct.unpack(">f", data.read(4)) - my_dict['SMAN'] = s - subchunklen -= 4 - elif subchunkname == "SIDE": #double sided? - ###if DEBUG: print "-------- SIDE" #if 1 side do not define key - s, = struct.unpack(">H", data.read(2)) - if s == 3: - my_dict['SIDE'] = s - subchunklen -= 2 - elif subchunkname == "RIND": #Refraction: mapped on IOR - ###if DEBUG: print "-------- RIND" - s, = struct.unpack(">f", data.read(4)) - envelope, env_size = read_vx(data) - my_dict['RIND'] = s - subchunklen -= (4+env_size) - elif subchunkname == "BLOK": #blocks - ###if DEBUG: print "-------- BLOK" - rr, uvname = read_surfblok(data.read(subchunklen)) - #paranoia setting: preventing adding an empty dict - if rr: # != {} - try: - my_dict['BLOK'].append(rr) - except: - my_dict['BLOK'] = [rr] - - if uvname: # != "": - my_dict['UVNAME'] = uvname #theoretically there could be a number of them: only one used per surf - # all are dictionaries - so testing keys - if not('g_IMAG' in my_dict) and ('CHAN' in rr) and ('OPAC' in rr) and ('IMAG' in rr): - if (rr['CHAN'] == 'COLR') and (rr['OPAC'] == 0): - my_dict['g_IMAG'] = rr['IMAG'] #do not set anything, just save image object for later assignment - subchunklen = 0 #force ending - else: # Misc Chunks - pass - ###if DEBUG: print "-------- SURF:%s: skipping" % subchunkname - if subchunklen > 0: - discard = data.read(subchunklen) - #end loop on surf chunks - try:#if my_dict.has_key('BLOK'): - my_dict['BLOK'].reverse() #texture applied in reverse order with respect to reading from lwo - except: - pass - - #uncomment this if material pre-allocated by read_surf - my_dict['g_MAT'] = bpy.data.materials.new(my_dict['NAME']) - ###if DEBUG: print "-> Material pre-allocated." - return my_dict - -# ========================= -# === Recalculate Faces === -# ========================= - -def get_uvface(complete_list, facenum): - # extract from the complete list only vertexes of the desired polygon - ''' - my_facelist = [] - for elem in complete_list: - if elem[0] == facenum: - my_facelist.append(elem) - return my_facelist - ''' - return [elem for elem in complete_list if elem[0] == facenum] - -def get_newindex(polygon_list, vertnum): - # extract from the polygon list the new index associated to a vertex - if not polygon_list: # == [] - return -1 - for elem in polygon_list: - if elem[1] == vertnum: - return elem[2] - # ###if DEBUG: print "WARNING: expected vertex %s for polygon %s. Polygon_list dump follows" % (vertnum, polygon_list[0][0]) - # ###if DEBUG: print polygon_list - return -1 - -def get_surf(surf_list, cur_tag): - for elem in surf_list: # elem can be None - if elem and elem['NAME'] == cur_tag: - return elem - return {} - - - -# ==================================== -# === Modified Create Blender Mesh === -# ==================================== -def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not_used_faces): - #take the needed faces and update the not-used face list - complete_vertlist = objspec_list[2] - complete_facelist = objspec_list[3] - uvcoords_dict = objspec_list[7] - facesuv_dict = objspec_list[8] - vertex_map = {} #implementation as dict - cur_ptag_faces = [] - cur_ptag_faces_indexes = [] - maxface = len(complete_facelist) - for ff in current_facelist: - if ff >= maxface: - ###if DEBUG: print "Non existent face addressed: Giving up with this object" - return None, not_used_faces #return the created object - cur_face = complete_facelist[ff] - cur_ptag_faces_indexes.append(ff) - if not_used_faces: # != [] - not_used_faces[ff] = -1 - for vv in cur_face: vertex_map[vv] = 1 - #end loop on faces - store_edge = 0 - - scn= bpy.data.scenes.active - msh = bpy.data.meshes.new() - obj = scn.objects.new(msh) - - mat = None - try: - msh.materials = [surf['g_MAT']] - except: - pass - - msh.mode |= Blender.Mesh.Modes.AUTOSMOOTH #smooth it anyway - if 'SMAN' in surf: # has_key - #not allowed mixed mode mesh (all the mesh is smoothed and all with the same angle) - #only one smoothing angle will be active! => take the max one - msh.degr = min(80, int(surf['SMAN']/3.1415926535897932384626433832795*180.0)) #lwo in radians - blender in degrees - - try: - img= lookup_imag(clip_list, surf['g_IMAG'])['g_IMG'] - except: - img= None - - #uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME'])) and (img != None)) - uv_flag = (('UVNAME' in surf) and (surf['UVNAME'] in uvcoords_dict)) - - ###if DEBUG: print "\n#===================================================================#" - ###if DEBUG: print "Processing Object: %s" % objname - ###if DEBUG: print "#===================================================================#" - - if uv_flag: - msh.verts.extend([(0.0,0.0,0.0),]) - j = 1 - else: - j = 0 - - def tmp_get_vert(k, i): - vertex_map[k] = i+j # j is the dummy vert - # ###if DEBUG: print complete_vertlist[i] - return complete_vertlist[k] - - - - msh.verts.extend([tmp_get_vert(k, i) for i, k in enumerate(vertex_map.iterkeys())]) - msh.transform(TXMTX) # faster then applying while reading. - #end sweep over vertexes - - #append faces - FACE_TEX= Blender.Mesh.FaceModes.TEX - FACE_ALPHA= Blender.Mesh.FaceTranspModes.ALPHA - EDGE_DRAW_FLAG= Blender.Mesh.EdgeFlags.EDGEDRAW | Blender.Mesh.EdgeFlags.EDGERENDER - - - edges = [] - face_data = [] # [(indicies, material, uvs, image), ] - face_uvs = [] - edges_fgon = [] - - if uv_flag: - uvcoords_dict_context = uvcoords_dict[surf['UVNAME']] - try: current_uvdict = facesuv_dict[surf['UVNAME']] - except: current_uvdict = None - - default_uv = Blender.Mathutils.Vector(0,0) - def tmp_get_face_uvs(cur_face, i): - uvs = [] - if current_uvdict: - uvface = get_uvface(current_uvdict,i) - for vi in cur_face: - ni = get_newindex(uvface, vi) - if ni == -1: ni = vi - - try: - uvs.append(uvcoords_dict_context[ ni ]) - except: - ###if DEBUG: print '\tWarning, Corrupt UVs' - uvs.append(default_uv) - else: - for vi in cur_face: - try: - uvs.append(uvcoords_dict_context[ vi ]) - except: - ###if DEBUG: print '\tWarning, Corrupt UVs' - uvs.append(default_uv) - - return uvs - cur_face - for i in cur_ptag_faces_indexes: - cur_face = complete_facelist[i] - numfaceverts = len(cur_face) - - if numfaceverts == 2: edges.append((vertex_map[cur_face[0]], vertex_map[cur_face[1]])) - elif numfaceverts == 3 or numfaceverts == 4: - rev_face = [__i for __i in reversed(cur_face)] - face_data.append( [vertex_map[j] for j in rev_face] ) - if uv_flag: face_uvs.append(tmp_get_face_uvs(rev_face, i)) - elif numfaceverts > 4: - meta_faces= BPyMesh.ngon(complete_vertlist, cur_face, PREF_FIX_LOOPS= True) - edge_face_count = {} - for mf in meta_faces: - # These will always be tri's since they are scanfill faces - mf = cur_face[mf[2]], cur_face[mf[1]], cur_face[mf[0]] - face_data.append( [vertex_map[j] for j in mf] ) - - if uv_flag: face_uvs.append(tmp_get_face_uvs(mf, i)) - - #if USE_FGON: - if len(meta_faces) > 1: - mf = face_data[-1] # reuse mf - for j in xrange(3): - v1= mf[j] - v2= mf[j-1] - if v1!=v2: - if v1>v2: - v2,v1= v1,v2 - try: - edge_face_count[v1,v2]+= 1 - except: - edge_face_count[v1,v2]= 0 - - - - if edge_face_count: - edges_fgon.extend( [vert_key for vert_key, count in edge_face_count.iteritems() if count] ) - - if edges: - msh.edges.extend(edges) - - face_mapping_removed = msh.faces.extend(face_data, indexList=True) - if 'TRAN' in surf or (mat and mat.alpha<1.0): # incase mat is null - transp_flag = True - else: - transp_flag = False - - if uv_flag: - msh.faceUV = True - msh_faces= msh.faces - for i, uvs in enumerate(face_uvs): - i_mapped = face_mapping_removed[i] - if i_mapped != None: - f = msh_faces[i_mapped] - f.uv = uvs - if img: - f.image = img - - if transp_flag: f.transp |= FACE_ALPHA - - if edges_fgon: - msh_edges = msh.edges - FGON= Blender.Mesh.EdgeFlags.FGON - edges_fgon = msh.findEdges( edges_fgon ) - if type(edges_fgon) != list: edges_fgon = [edges_fgon] - for ed in edges_fgon: - if ed!=None: - msh_edges[ed].flag |= FGON - - if not(uv_flag): #clear eventual UV data - msh.faceUV = False - - if uv_flag: - msh.verts.delete([0,]) - - return obj, not_used_faces #return the created object - - -# ============================================ -# === Set Subsurf attributes on given mesh === -# ============================================ -def set_subsurf(obj): - mods = obj.modifiers # get the object's modifiers - mod = mods.append(Blender.Modifier.Type.SUBSURF) # add a new subsurf modifier - mod[Blender.Modifier.Settings.LEVELS] = 2 # set subsurf subdivision levels to 2 - mod[Blender.Modifier.Settings.RENDLEVELS] = 2 # set subsurf rendertime subdivision levels to 2 - obj.makeDisplayList() - - -# ================================= -# === object size and dimension === -# ================================= -def obj_size_pos(obj): - bbox = obj.getBoundBox() - bbox_min = map(lambda *row: min(row), *bbox) #transpose & get min - bbox_max = map(lambda *row: max(row), *bbox) #transpose & get max - obj_size = (bbox_max[0]-bbox_min[0], bbox_max[1]-bbox_min[1], bbox_max[2]-bbox_min[2]) - obj_pos = ( (bbox_max[0]+bbox_min[0]) / 2, (bbox_max[1]+bbox_min[1]) / 2, (bbox_max[2]+bbox_min[2]) / 2) - return (obj_size, obj_pos) - - -# ========================= -# === Create the object === -# ========================= -def create_objects(clip_list, objspec_list, surf_list): - nf = len(objspec_list[3]) - not_used_faces = range(nf) - ptag_dict = objspec_list[5] - obj_dict = {} #links tag names to object, used for material assignments - obj_dim_dict = {} - obj_list = [] #have it handy for parent association - middlechar = "+" - endchar = "" - if (objspec_list[6] == 1): - middlechar = endchar = "#" - for cur_tag, ptag_dict_val in ptag_dict.iteritems(): - if ptag_dict_val != []: - cur_surf = get_surf(surf_list, cur_tag) - cur_obj, not_used_faces= my_create_mesh(clip_list, cur_surf, objspec_list, ptag_dict_val, objspec_list[0][:9]+middlechar+cur_tag[:9], not_used_faces) - # Works now with new modifiers - if objspec_list[6] == 1: - set_subsurf(cur_obj) - if cur_obj: # != None - obj_dict[cur_tag] = cur_obj - obj_dim_dict[cur_tag] = obj_size_pos(cur_obj) - obj_list.append(cur_obj) - #end loop on current group - #and what if some faces not used in any named PTAG? get rid of unused faces - orphans = [] - for tt in not_used_faces: - if tt > -1: orphans.append(tt) - #end sweep on unused face list - not_used_faces = None - if orphans: # != [] - cur_surf = get_surf(surf_list, "_Orphans") - cur_obj, not_used_faces = my_create_mesh(clip_list, cur_surf, objspec_list, orphans, objspec_list[0][:9]+middlechar+"Orphans", []) - if cur_obj: # != None - if objspec_list[6] == 1: - set_subsurf(cur_obj) - obj_dict["_Orphans"] = cur_obj - obj_dim_dict["_Orphans"] = obj_size_pos(cur_obj) - obj_list.append(cur_obj) - objspec_list[1]= obj_dict - objspec_list[4]= obj_dim_dict - - return - - - -# =========================================== -# === Lookup for image index in clip_list === -# =========================================== -def lookup_imag(clip_list, ima_id): - for ii in clip_list: - if ii and ii['ID'] == ima_id: - if 'XREF' in ii: # has_key - #cross reference - recursively look for images - return lookup_imag(clip_list, ii['XREF']) - else: - return ii - return None - - -# =================================================== -# === Create and assign image mapping to material === -# =================================================== -def create_blok(surf, mat, clip_list, obj_size, obj_pos): - - def output_size_ofs(size, pos, blok): - #just automate repetitive task - # 0 == X, 1 == Y, 2 == Z - size_default = [1.0] * 3 - size2 = [1.0] * 3 - ofs_default = [0.0] * 3 - offset = [1.0] * 3 - axis_default = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z] - axis = [1.0] * 3 - c_map_txt = [" X--", " -Y-", " --Z"] - c_map = [0,1,2] # standard, good for Z axis projection - if blok['MAJAXIS'] == 0: - c_map = [1,2,0] # X axis projection - if blok['MAJAXIS'] == 2: - c_map = [0,2,1] # Y axis projection - - ###if DEBUG: print "!!!axis mapping:" - #this is the smart way - ###if DEBUG: for mp in c_map: print c_map_txt[mp] - - if blok['SIZE'][0] != 0.0: #paranoia controls - size_default[0] = (size[0]/blok['SIZE'][0]) - ofs_default[0] = ((blok['CNTR'][0]-pos[0])/blok['SIZE'][0]) - if blok['SIZE'][1] != 0.0: - size_default[2] = (size[2]/blok['SIZE'][1]) - ofs_default[2] = ((blok['CNTR'][1]-pos[2])/blok['SIZE'][1]) - if blok['SIZE'][2] != 0.0: - size_default[1] = (size[1]/blok['SIZE'][2]) - ofs_default[1] = ((blok['CNTR'][2]-pos[1])/blok['SIZE'][2]) - - for mp in xrange(3): - axis[mp] = axis_default[c_map[mp]] - size2[mp] = size_default[c_map[mp]] - offset[mp] = ofs_default[c_map[mp]] - if offset[mp]>10.0: offset[mp]-10.0 - if offset[mp]<-10.0: offset[mp]+10.0 -# size = [size_default[mp] for mp in c_map] - - ###if DEBUG: print "!!!texture size and offsets:" - ###if DEBUG: print " sizeX = %.5f; sizeY = %.5f; sizeZ = %.5f" % (size[0],size[1],size[2]) - ###if DEBUG: print " ofsX = %.5f; ofsY = %.5f; ofsZ = %.5f" % (offset[0],offset[1],offset[2]) - return axis, size2, offset - - ti = 0 - alphaflag = 0 #switched to 1 if some tex in this block is using alpha - lastimag = 0 #experimental .... - for blok in surf['BLOK']: - ###if DEBUG: print "#...................................................................#" - ###if DEBUG: print "# Processing texture block no.%s for surf %s" % (ti,surf['NAME']) - ###if DEBUG: print "#...................................................................#" - # tobj.pdict (blok) - if ti > 9: break #only 8 channels 0..7 allowed for texture mapping - #if not blok['ENAB']: - # ###if DEBUG: print "***Image is not ENABled! Quitting this block" - # break - if not('IMAG' in blok): # has_key - ###if DEBUG: print "***No IMAGE for this block? Quitting" - break #extract out the image index within the clip_list - if blok['IMAG'] == 0: blok['IMAG'] = lastimag #experimental .... - ###if DEBUG: print "looking for image number %d" % blok['IMAG'] - ima = lookup_imag(clip_list, blok['IMAG']) - if ima == None: - ###if DEBUG: print "***Block index image not within CLIP list? Quitting Block" - break #safety check (paranoia setting) - img = ima['g_IMG'] - lastimag = blok['IMAG'] #experimental .... - if img == None: - ###if DEBUG: print "***Failed to pre-allocate image %s found: giving up" % ima['BASENAME'] - break - tname = str(ima['ID']) - if blok['ENAB']: - tname += "+" - else: - tname += "x" #let's signal when should not be enabled - if 'CHAN' in blok: # has_key - tname += blok['CHAN'] - newtex = bpy.data.textures.new(tname) - newtex.setType('Image') # make it anu image texture - newtex.image = img - #how does it extends beyond borders - if 'WRAP' in blok: # has_key - if (blok['WRAP'] == 3) or (blok['WRAP'] == 2): - newtex.setExtend('Extend') - elif (blok['WRAP'] == 1): - newtex.setExtend('Repeat') - elif (blok['WRAP'] == 0): - newtex.setExtend('Clip') - ###if DEBUG: print "generated texture %s" % tname - - #MapTo is determined by CHAN parameter - #assign some defaults - colfac = 1.0 - dvar = 1.0 - norfac = 0.5 - nega = False - mapflag = Blender.Texture.MapTo.COL #default to color - maptype = Blender.Texture.Mappings.FLAT - if 'CHAN' in blok: # has_key - if blok['CHAN'] == 'COLR' and 'OPACVAL' in blok: # has_key - colfac = blok['OPACVAL'] - # Blender needs this to be clamped - colfac = max(0.0, min(1.0, colfac)) - ###if DEBUG: print "!!!Set Texture -> MapTo -> Col = %.3f" % colfac - if blok['CHAN'] == 'BUMP': - mapflag = Blender.Texture.MapTo.NOR - if 'OPACVAL' in blok: norfac = blok['OPACVAL'] # has_key - ###if DEBUG: print "!!!Set Texture -> MapTo -> Nor = %.3f" % norfac - if blok['CHAN'] == 'LUMI': - mapflag = Blender.Texture.MapTo.EMIT - if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key - ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar - if blok['CHAN'] == 'DIFF': - mapflag = Blender.Texture.MapTo.REF - if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key - ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar - if blok['CHAN'] == 'SPEC': - mapflag = Blender.Texture.MapTo.SPEC - if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key - ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar - if blok['CHAN'] == 'TRAN': - mapflag = Blender.Texture.MapTo.ALPHA - if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key - ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar - alphaflag = 1 - nega = True - if 'NEGA' in blok: # has_key - ###if DEBUG: print "!!!Watch-out: effect of this texture channel must be INVERTED!" - nega = not nega - - blendmode_list = ['Mix', - 'Subtractive', - 'Difference', - 'Multiply', - 'Divide', - 'Mix with calculated alpha layer and stencil flag', - 'Texture Displacement', - 'Additive'] - set_blendmode = 7 #default additive - if 'OPAC' in blok: # has_key - set_blendmode = blok['OPAC'] - if set_blendmode == 5: #transparency - newtex.imageFlags |= Blender.Texture.ImageFlags.CALCALPHA - if nega: newtex.flags |= Blender.Texture.Flags.NEGALPHA - ###if DEBUG: print "!!!Set Texture -> MapTo -> Blending Mode = %s" % blendmode_list[set_blendmode] - - #the TexCo flag is determined by PROJ parameter - axis = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z] - size = [1.0] * 3 - ofs = [0.0] * 3 - if 'PROJ' in blok: # has_key - if blok['PROJ'] == 0: #0 - Planar - ###if DEBUG: print "!!!Flat projection" - coordflag = Blender.Texture.TexCo.ORCO - maptype = Blender.Texture.Mappings.FLAT - elif blok['PROJ'] == 1: #1 - Cylindrical - ###if DEBUG: print "!!!Cylindrical projection" - coordflag = Blender.Texture.TexCo.ORCO - maptype = Blender.Texture.Mappings.TUBE - elif blok['PROJ'] == 2: #2 - Spherical - ###if DEBUG: print "!!!Spherical projection" - coordflag = Blender.Texture.TexCo.ORCO - maptype = Blender.Texture.Mappings.SPHERE - elif blok['PROJ'] == 3: #3 - Cubic - ###if DEBUG: print "!!!Cubic projection" - coordflag = Blender.Texture.TexCo.ORCO - maptype = Blender.Texture.Mappings.CUBE - elif blok['PROJ'] == 4: #4 - Front Projection - ###if DEBUG: print "!!!Front projection" - coordflag = Blender.Texture.TexCo.ORCO - maptype = Blender.Texture.Mappings.FLAT # ??? could it be a FLAT with some other TexCo type? - elif blok['PROJ'] == 5: #5 - UV - ###if DEBUG: print "UVMapped" - coordflag = Blender.Texture.TexCo.UV - maptype = Blender.Texture.Mappings.FLAT #in case of UV default to FLAT mapping => effectively not used - if blok['PROJ'] != 5: #This holds for any projection map except UV - axis, size, ofs = output_size_ofs(obj_size, obj_pos, blok) - - # Clamp ofs and size else blender will raise an error - for ii in xrange(3): - ofs[ii]= min(10.0, max(-10, ofs[ii])) - size[ii]= min(100, max(-100, size[ii])) - - mat.setTexture(ti, newtex, coordflag, mapflag) - current_mtex = mat.getTextures()[ti] - current_mtex.mapping = maptype - current_mtex.colfac = colfac - current_mtex.dvar = dvar - current_mtex.norfac = norfac - current_mtex.neg = nega - current_mtex.xproj = axis[0] - current_mtex.yproj = axis[1] - current_mtex.zproj = axis[2] - current_mtex.size = tuple(size) - current_mtex.ofs = tuple(ofs) - if (set_blendmode == 5): #transparency - current_mtex.stencil = not (nega) - - ti += 1 - #end loop over bloks - return alphaflag - - -# ======================================== -# === Create and assign a new material === -# ======================================== -#def update_material(surf_list, ptag_dict, obj, clip_list, uv_dict, dir_part): -def update_material(clip_list, objspec, surf_list): - if (surf_list == []) or (objspec[5] == {}) or (objspec[1] == {}): - ###if DEBUG: print "something getting wrong in update_material: dump follows ..." - ###if DEBUG: print surf_list - ###if DEBUG: print objspec[5] - ###if DEBUG: print objspec[1] - return - obj_dict = objspec[1] - all_faces = objspec[3] - obj_dim_dict = objspec[4] - ptag_dict = objspec[5] - uvcoords_dict = objspec[7] - facesuv_dict = objspec[8] - for surf in surf_list: - if surf and surf['NAME'] in ptag_dict: # in ptag_dict.keys() - ###if DEBUG: print "#-------------------------------------------------------------------#" - ###if DEBUG: print "Processing surface (material): %s" % surf['NAME'] - ###if DEBUG: print "#-------------------------------------------------------------------#" - #material set up - facelist = ptag_dict[surf['NAME']] - #bounding box and position - cur_obj = obj_dict[surf['NAME']] - obj_size = obj_dim_dict[surf['NAME']][0] - obj_pos = obj_dim_dict[surf['NAME']][1] - ###if DEBUG: print surf - #uncomment this if material pre-allocated by read_surf - mat = surf['g_MAT'] - if mat == None: - ###if DEBUG: print "Sorry, no pre-allocated material to update. Giving up for %s." % surf['NAME'] - break - #mat = Blender.Material.New(surf['NAME']) - #surf['g_MAT'] = mat - if 'COLR' in surf: # has_key - mat.rgbCol = surf['COLR'] - if 'LUMI' in surf: - mat.setEmit(surf['LUMI']) - if 'GVAL' in surf: # has_key - mat.setAdd(surf['GVAL']) - if 'SPEC' in surf: # has_key - mat.setSpec(surf['SPEC']) #it should be * 2 but seems to be a bit higher lwo [0.0, 1.0] - blender [0.0, 2.0] - if 'DIFF' in surf: # has_key - mat.setRef(surf['DIFF']) #lwo [0.0, 1.0] - blender [0.0, 1.0] - if 'GLOS' in surf: # has_key #lwo [0.0, 1.0] - blender [0, 255] - glo = int(371.67 * surf['GLOS'] - 42.334) #linear mapping - seems to work better than exp mapping - if glo <32: glo = 32 #clamped to 32-255 - if glo >255: glo = 255 - mat.setHardness(glo) - if 'TRNL' in surf: # has_key - mat.setTranslucency(surf['TRNL']) #NOT SURE ABOUT THIS lwo [0.0, 1.0] - blender [0.0, 1.0] - - mm = mat.mode - mm |= Blender.Material.Modes.TRANSPSHADOW - if 'REFL' in surf: # has_key - mat.setRayMirr(surf['REFL']) #lwo [0.0, 1.0] - blender [0.0, 1.0] - mm |= Blender.Material.Modes.RAYMIRROR - if 'TRAN' in surf: # has_key - mat.setAlpha(1.0-surf['TRAN']) #lwo [0.0, 1.0] - blender [1.0, 0.0] - mm |= Blender.Material.Modes.RAYTRANSP - if 'RIND' in surf: # has_key - s = surf['RIND'] - if s < 1.0: s = 1.0 - if s > 3.0: s = 3.0 - mat.setIOR(s) #clipped to blender [1.0, 3.0] - mm |= Blender.Material.Modes.RAYTRANSP - if 'BLOK' in surf and surf['BLOK'] != []: - #update the material according to texture. - alphaflag = create_blok(surf, mat, clip_list, obj_size, obj_pos) - if alphaflag: - mm |= Blender.Material.Modes.RAYTRANSP - mat.mode = mm - #finished setting up the material - #end if exist SURF - #end loop on materials (SURFs) - return - - -# ====================== -# === Read Faces 6.0 === -# ====================== -def read_faces_6(lwochunk): - data = cStringIO.StringIO(lwochunk.read()) - faces = [] - polygon_type = data.read(4) - subsurf = 0 - if polygon_type != "FACE" and polygon_type != "PTCH": - ###if DEBUG: print "No FACE/PATCH Were Found. Polygon Type: %s" % polygon_type - return "", 2 - if polygon_type == 'PTCH': subsurf = 1 - i = 0 - while(i < lwochunk.chunksize-4): - #if not i%1000 and my_meshtools.show_progress: - # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces") - facev = [] - numfaceverts, = struct.unpack(">H", data.read(2)) - i += 2 - - for j in xrange(numfaceverts): - index, index_size = read_vx(data) - i += index_size - facev.append(index) - faces.append(facev) - ###if DEBUG: print "read %s faces; type of block %d (0=FACE; 1=PATCH)" % (len(faces), subsurf) - return faces, subsurf - -def main(): - if not struct: - Blender.Draw.PupMenu('This importer requires a full python install') - return - - Blender.Window.FileSelector(read, "Import LWO", '*.lwo') - -if __name__=='__main__': - main() - - -# Cams debugging lwo loader -""" -TIME= Blender.sys.time() -import os -print 'Searching for files' -os.system('find /fe/lwo/Objects/ -follow -iname "*.lwo" > /tmp/templwo_list') -# os.system('find /storage/ -iname "*.lwo" > /tmp/templwo_list') -print '...Done' -file= open('/tmp/templwo_list', 'r') -lines= file.readlines() - -# sort by filesize for faster testing -lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines] -lines_size.sort() -lines = [f[1] for f in lines_size] - -file.close() - -def between(v,a,b): - if v <= max(a,b) and v >= min(a,b): - return True - - return False -size= 0.0 -for i, _lwo in enumerate(lines): - #if i==425: # SCANFILL - #if 1: - #if i==520: # SCANFILL CRASH - #if i==47: # SCANFILL CRASH - #if between(i, 525, 550): - #if i > 1635: - #if i != 1519: # 730 - if i>141: - #if 1: - # _lwo= _lwo[:-1] - print 'Importing', _lwo, '\nNUMBER', i, 'of', len(lines) - _lwo_file= _lwo.split('/')[-1].split('\\')[-1] - newScn= bpy.data.scenes.new(_lwo_file) - bpy.data.scenes.active = newScn - size += ((os.path.getsize(_lwo)/1024.0))/ 1024.0 - read(_lwo) - # Remove objects to save memory? - ''' - for ob in newScn.objects: - if ob.type=='Mesh': - me= ob.getData(mesh=1) - me.verts= None - newScn.unlink(ob) - ''' - print 'mb size so far', size - -print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) -""" \ No newline at end of file diff --git a/release/scripts/md2_export.py b/release/scripts/md2_export.py deleted file mode 100644 index f0fe6b9af40..00000000000 --- a/release/scripts/md2_export.py +++ /dev/null @@ -1,1271 +0,0 @@ -#!BPY - -""" -Name: 'MD2 (.md2)' -Blender: 243 -Group: 'Export' -Tooltip: 'Export to Quake file format (.md2).' -""" - -__author__ = 'Bob Holcomb' -__version__ = '0.18.1 patch 1' -__url__ = ["Bob's site, http://bane.servebeer.com", - "Support forum, http://bane.servebeer.com", "blender", "blenderartists.org"] -__email__ = ["Bob Holcomb, bob_holcomb:hotmail*com", "scripts"] -__bpydoc__ = """\ -This script Exports a Quake 2 file (MD2). - - Additional help from: Shadwolf, Skandal, Rojo, Cambo
- Thanks Guys! -""" - -# This is a PATCHED VERSION, fixing the bug due to which animations would -# (almost) never work. It is now also possible to output a MD2 model without -# texture. -# On: 23 january 2008 -# By: Boris van Schooten (schooten@cs.utwente.nl) - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C): Bob Holcomb -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -import Blender -from Blender import * -from Blender.Draw import * -from Blender.BGL import * -from Blender.Window import * - -import struct, string -from types import * - - - -###################################################### -# GUI Loader -###################################################### - -# Export globals -g_filename=Create("tris.md2") -g_frame_filename=Create("default") - -g_filename_search=Create("") -g_frame_search=Create("default") - -g_texture_path=Create("") - -user_frame_list=[] - -#Globals -g_scale=Create(1.0) - -# Events -EVENT_NOEVENT=1 -EVENT_SAVE_MD2=2 -EVENT_CHOOSE_FILENAME=3 -EVENT_CHOOSE_FRAME=4 -EVENT_EXIT=100 - -###################################################### -# Callbacks for Window functions -###################################################### -def filename_callback(input_filename): - global g_filename - g_filename.val=input_filename - -def frame_callback(input_frame): - global g_frame_filename - g_frame_filename.val=input_frame - -def draw_gui(): - global g_scale - global g_filename - global g_frame_filename - global EVENT_NOEVENT,EVENT_SAVE_MD2,EVENT_CHOOSE_FILENAME,EVENT_CHOOSE_FRAME,EVENT_EXIT - global g_texture_path - - ########## Titles - glClear(GL_COLOR_BUFFER_BIT) - glRasterPos2d(10, 120) - Text("MD2 Export") - - ######### Parameters GUI Buttons - ######### MD2 Filename text entry - g_filename = String("MD2 file to save: ", EVENT_NOEVENT, 10, 75, 210, 18, - g_filename.val, 255, "MD2 file to save") - ########## MD2 File Search Button - Button("Browse",EVENT_CHOOSE_FILENAME,220,75,80,18) - - ########## MD2 Frame List Text entry - g_frame_filename = String("Frame List file to load: ", EVENT_NOEVENT, 10, 55, 210, 18, - g_frame_filename.val, 255, "Frame List to load-overrides MD2 defaults") - ########## Frame List Search Button - Button("Browse",EVENT_CHOOSE_FRAME,220,55,80,18) - - ########## Texture path to append - g_texture_path=String("Texture Path: ", EVENT_NOEVENT, 10,35,210,18, - g_texture_path.val,255, "Texture path to prepend") - - - ########## Scale slider-default is 1/8 which is a good scale for md2->blender - g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 95, 210, 18, - 1.0, 0.001, 10.0, 1, "Scale factor for object Model"); - - ######### Draw and Exit Buttons - Button("Export",EVENT_SAVE_MD2 , 10, 10, 80, 18) - Button("Exit",EVENT_EXIT , 170, 10, 80, 18) - -def event(evt, val): - if (evt == QKEY and not val): - Exit() - -def bevent(evt): - global g_filename - global g_frame_filename - global EVENT_NOEVENT,EVENT_SAVE_MD2,EVENT_EXIT - - ######### Manages GUI events - if (evt==EVENT_EXIT): - Blender.Draw.Exit() - elif (evt==EVENT_CHOOSE_FILENAME): - FileSelector(filename_callback, "MD2 File Selection") - elif (evt==EVENT_CHOOSE_FRAME): - FileSelector(frame_callback, "Frame Selection") - elif (evt==EVENT_SAVE_MD2): - save_md2(g_filename.val) - Blender.Draw.Exit() - return - -Register(draw_gui, event, bevent) - -###################################################### -# MD2 Model Constants -###################################################### -MD2_MAX_TRIANGLES=4096 -MD2_MAX_VERTICES=2048 -MD2_MAX_TEXCOORDS=2048 -MD2_MAX_FRAMES=512 -MD2_MAX_SKINS=32 -MD2_MAX_FRAMESIZE=(MD2_MAX_VERTICES * 4 + 128) - -MD2_FRAME_NAME_LIST=(("stand",1,40), - ("run",41,46), - ("attack",47,54), - ("pain1",55,58), - ("pain2",59,62), - ("pain3",63,66), - ("jump",67,72), - ("flip",73,84), - ("salute", 85,95), - ("taunt",96,112), - ("wave",113,123), - ("point",124,135), - ("crstnd",136,154), - ("crwalk",155,160), - ("crattack",161,169), - ("crpain",170,173), - ("crdeath",174,178), - ("death1",179,184), - ("death2",185,190), - ("death3",191,198)) - #198 frames - -MD2_NORMALS=((-0.525731, 0.000000, 0.850651), - (-0.442863, 0.238856, 0.864188), - (-0.295242, 0.000000, 0.955423), - (-0.309017, 0.500000, 0.809017), - (-0.162460, 0.262866, 0.951056), - (0.000000, 0.000000, 1.000000), - (0.000000, 0.850651, 0.525731), - (-0.147621, 0.716567, 0.681718), - (0.147621, 0.716567, 0.681718), - (0.000000, 0.525731, 0.850651), - (0.309017, 0.500000, 0.809017), - (0.525731, 0.000000, 0.850651), - (0.295242, 0.000000, 0.955423), - (0.442863, 0.238856, 0.864188), - (0.162460, 0.262866, 0.951056), - (-0.681718, 0.147621, 0.716567), - (-0.809017, 0.309017, 0.500000), - (-0.587785, 0.425325, 0.688191), - (-0.850651, 0.525731, 0.000000), - (-0.864188, 0.442863, 0.238856), - (-0.716567, 0.681718, 0.147621), - (-0.688191, 0.587785, 0.425325), - (-0.500000, 0.809017, 0.309017), - (-0.238856, 0.864188, 0.442863), - (-0.425325, 0.688191, 0.587785), - (-0.716567, 0.681718, -0.147621), - (-0.500000, 0.809017, -0.309017), - (-0.525731, 0.850651, 0.000000), - (0.000000, 0.850651, -0.525731), - (-0.238856, 0.864188, -0.442863), - (0.000000, 0.955423, -0.295242), - (-0.262866, 0.951056, -0.162460), - (0.000000, 1.000000, 0.000000), - (0.000000, 0.955423, 0.295242), - (-0.262866, 0.951056, 0.162460), - (0.238856, 0.864188, 0.442863), - (0.262866, 0.951056, 0.162460), - (0.500000, 0.809017, 0.309017), - (0.238856, 0.864188, -0.442863), - (0.262866, 0.951056, -0.162460), - (0.500000, 0.809017, -0.309017), - (0.850651, 0.525731, 0.000000), - (0.716567, 0.681718, 0.147621), - (0.716567, 0.681718, -0.147621), - (0.525731, 0.850651, 0.000000), - (0.425325, 0.688191, 0.587785), - (0.864188, 0.442863, 0.238856), - (0.688191, 0.587785, 0.425325), - (0.809017, 0.309017, 0.500000), - (0.681718, 0.147621, 0.716567), - (0.587785, 0.425325, 0.688191), - (0.955423, 0.295242, 0.000000), - (1.000000, 0.000000, 0.000000), - (0.951056, 0.162460, 0.262866), - (0.850651, -0.525731, 0.000000), - (0.955423, -0.295242, 0.000000), - (0.864188, -0.442863, 0.238856), - (0.951056, -0.162460, 0.262866), - (0.809017, -0.309017, 0.500000), - (0.681718, -0.147621, 0.716567), - (0.850651, 0.000000, 0.525731), - (0.864188, 0.442863, -0.238856), - (0.809017, 0.309017, -0.500000), - (0.951056, 0.162460, -0.262866), - (0.525731, 0.000000, -0.850651), - (0.681718, 0.147621, -0.716567), - (0.681718, -0.147621, -0.716567), - (0.850651, 0.000000, -0.525731), - (0.809017, -0.309017, -0.500000), - (0.864188, -0.442863, -0.238856), - (0.951056, -0.162460, -0.262866), - (0.147621, 0.716567, -0.681718), - (0.309017, 0.500000, -0.809017), - (0.425325, 0.688191, -0.587785), - (0.442863, 0.238856, -0.864188), - (0.587785, 0.425325, -0.688191), - (0.688191, 0.587785, -0.425325), - (-0.147621, 0.716567, -0.681718), - (-0.309017, 0.500000, -0.809017), - (0.000000, 0.525731, -0.850651), - (-0.525731, 0.000000, -0.850651), - (-0.442863, 0.238856, -0.864188), - (-0.295242, 0.000000, -0.955423), - (-0.162460, 0.262866, -0.951056), - (0.000000, 0.000000, -1.000000), - (0.295242, 0.000000, -0.955423), - (0.162460, 0.262866, -0.951056), - (-0.442863, -0.238856, -0.864188), - (-0.309017, -0.500000, -0.809017), - (-0.162460, -0.262866, -0.951056), - (0.000000, -0.850651, -0.525731), - (-0.147621, -0.716567, -0.681718), - (0.147621, -0.716567, -0.681718), - (0.000000, -0.525731, -0.850651), - (0.309017, -0.500000, -0.809017), - (0.442863, -0.238856, -0.864188), - (0.162460, -0.262866, -0.951056), - (0.238856, -0.864188, -0.442863), - (0.500000, -0.809017, -0.309017), - (0.425325, -0.688191, -0.587785), - (0.716567, -0.681718, -0.147621), - (0.688191, -0.587785, -0.425325), - (0.587785, -0.425325, -0.688191), - (0.000000, -0.955423, -0.295242), - (0.000000, -1.000000, 0.000000), - (0.262866, -0.951056, -0.162460), - (0.000000, -0.850651, 0.525731), - (0.000000, -0.955423, 0.295242), - (0.238856, -0.864188, 0.442863), - (0.262866, -0.951056, 0.162460), - (0.500000, -0.809017, 0.309017), - (0.716567, -0.681718, 0.147621), - (0.525731, -0.850651, 0.000000), - (-0.238856, -0.864188, -0.442863), - (-0.500000, -0.809017, -0.309017), - (-0.262866, -0.951056, -0.162460), - (-0.850651, -0.525731, 0.000000), - (-0.716567, -0.681718, -0.147621), - (-0.716567, -0.681718, 0.147621), - (-0.525731, -0.850651, 0.000000), - (-0.500000, -0.809017, 0.309017), - (-0.238856, -0.864188, 0.442863), - (-0.262866, -0.951056, 0.162460), - (-0.864188, -0.442863, 0.238856), - (-0.809017, -0.309017, 0.500000), - (-0.688191, -0.587785, 0.425325), - (-0.681718, -0.147621, 0.716567), - (-0.442863, -0.238856, 0.864188), - (-0.587785, -0.425325, 0.688191), - (-0.309017, -0.500000, 0.809017), - (-0.147621, -0.716567, 0.681718), - (-0.425325, -0.688191, 0.587785), - (-0.162460, -0.262866, 0.951056), - (0.442863, -0.238856, 0.864188), - (0.162460, -0.262866, 0.951056), - (0.309017, -0.500000, 0.809017), - (0.147621, -0.716567, 0.681718), - (0.000000, -0.525731, 0.850651), - (0.425325, -0.688191, 0.587785), - (0.587785, -0.425325, 0.688191), - (0.688191, -0.587785, 0.425325), - (-0.955423, 0.295242, 0.000000), - (-0.951056, 0.162460, 0.262866), - (-1.000000, 0.000000, 0.000000), - (-0.850651, 0.000000, 0.525731), - (-0.955423, -0.295242, 0.000000), - (-0.951056, -0.162460, 0.262866), - (-0.864188, 0.442863, -0.238856), - (-0.951056, 0.162460, -0.262866), - (-0.809017, 0.309017, -0.500000), - (-0.864188, -0.442863, -0.238856), - (-0.951056, -0.162460, -0.262866), - (-0.809017, -0.309017, -0.500000), - (-0.681718, 0.147621, -0.716567), - (-0.681718, -0.147621, -0.716567), - (-0.850651, 0.000000, -0.525731), - (-0.688191, 0.587785, -0.425325), - (-0.587785, 0.425325, -0.688191), - (-0.425325, 0.688191, -0.587785), - (-0.425325, -0.688191, -0.587785), - (-0.587785, -0.425325, -0.688191), - (-0.688191, -0.587785, -0.425325)) - - -###################################################### -# MD2 data structures -###################################################### -class md2_point: - vertices=[] - lightnormalindex=0 - binary_format="<3BB" - def __init__(self): - self.vertices=[0]*3 - self.lightnormalindex=0 - def save(self, file): - temp_data=[0]*4 - temp_data[0]=self.vertices[0] - temp_data[1]=self.vertices[1] - temp_data[2]=self.vertices[2] - temp_data[3]=self.lightnormalindex - data=struct.pack(self.binary_format, temp_data[0], temp_data[1], temp_data[2], temp_data[3]) - file.write(data) - def dump(self): - print "MD2 Point Structure" - print "vertex X: ", self.vertices[0] - print "vertex Y: ", self.vertices[1] - print "vertex Z: ", self.vertices[2] - print "lightnormalindex: ",self.lightnormalindex - print "" - -class md2_face: - vertex_index=[] - texture_index=[] - binary_format="<3h3h" - def __init__(self): - self.vertex_index = [ 0, 0, 0 ] - self.texture_index = [ 0, 0, 0] - def save(self, file): - temp_data=[0]*6 - #swap vertices around so they draw right - temp_data[0]=self.vertex_index[0] - temp_data[1]=self.vertex_index[2] - temp_data[2]=self.vertex_index[1] - #swap texture vertices around so they draw right - temp_data[3]=self.texture_index[0] - temp_data[4]=self.texture_index[2] - temp_data[5]=self.texture_index[1] - data=struct.pack(self.binary_format,temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5]) - file.write(data) - def dump (self): - print "MD2 Face Structure" - print "vertex 1 index: ", self.vertex_index[0] - print "vertex 2 index: ", self.vertex_index[1] - print "vertex 3 index: ", self.vertex_index[2] - print "texture 1 index: ", self.texture_index[0] - print "texture 2 index: ", self.texture_index[1] - print "texture 3 index: ", self.texture_index[2] - print "" - -class md2_tex_coord: - u=0 - v=0 - binary_format="<2h" - def __init__(self): - self.u=0 - self.v=0 - def save(self, file): - temp_data=[0]*2 - temp_data[0]=self.u - temp_data[1]=self.v - data=struct.pack(self.binary_format, temp_data[0], temp_data[1]) - file.write(data) - def dump (self): - print "MD2 Texture Coordinate Structure" - print "texture coordinate u: ",self.u - print "texture coordinate v: ",self.v - print "" - -class md2_GL_command: - s=0.0 - t=0.0 - vert_index=0 - binary_format="<2fi" - - def __init__(self): - self.s=0.0 - self.t=0.0 - vert_index=0 - def save(self,file): - temp_data=[0]*3 - temp_data[0]=float(self.s) - temp_data[1]=float(self.t) - temp_data[2]=self.vert_index - data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2]) - file.write(data) - def dump (self): - print "MD2 OpenGL Command" - print "s: ", self.s - print "t: ", self.t - print "Vertex Index: ", self.vert_index - print "" - -class md2_GL_cmd_list: - num=0 - cmd_list=[] - binary_format="MD2_MAX_TRIANGLES: - print "Number of triangles exceeds MD2 standard: ", face_count,">",MD2_MAX_TRIANGLES - result=Blender.Draw.PupMenu("Number of triangles exceeds MD2 standard: Continue?%t|YES|NO") - if(result==2): - return False - if vert_count>MD2_MAX_VERTICES: - print "Number of verticies exceeds MD2 standard",vert_count,">",MD2_MAX_VERTICES - result=Blender.Draw.PupMenu("Number of verticies exceeds MD2 standard: Continue?%t|YES|NO") - if(result==2): - return False - if frame_count>MD2_MAX_FRAMES: - print "Number of frames exceeds MD2 standard of",frame_count,">",MD2_MAX_FRAMES - result=Blender.Draw.PupMenu("Number of frames exceeds MD2 standard: Continue?%t|YES|NO") - if(result==2): - return False - #model is OK - return True - -###################################################### -# Fill MD2 data structure -###################################################### -def fill_md2(md2, object): - #global defines - global user_frame_list - global g_texture_path - - Blender.Window.DrawProgressBar(0.25,"Filling MD2 Data") - - #get a Mesh, not NMesh - mesh=object.getData(False, True) - #don't forget to copy the data! -- Boris van Schooten - mesh=mesh.__copy__(); - #load up some intermediate data structures - tex_list={} - tex_count=0 - #create the vertex list from the first frame - Blender.Set("curframe", 1) - - has_uvs = mesh.faceUV - - #header information - md2.ident=844121161 - md2.version=8 - md2.num_vertices=len(mesh.verts) - md2.num_faces=len(mesh.faces) - - #get the skin information - #use the first faces' image for the texture information - if has_uvs: - mesh_image=mesh.faces[0].image - try: size=mesh_image.getSize() - except: size= 256,256 - - md2.skin_width=size[0] - md2.skin_height=size[1] - md2.num_skins=1 - #add a skin node to the md2 data structure - md2.skins.append(md2_skin()) - md2.skins[0].name=g_texture_path.val+Blender.sys.basename(mesh_image.getFilename()) - if len(md2.skins[0].name)>64: - print "Texture Path and name is more than 64 characters" - result=Blender.Draw.PupMenu("Texture path and name is more than 64 characters-Quitting") - return False - - #put texture information in the md2 structure - #build UV coord dictionary (prevents double entries-saves space) - if not has_uvs: - t=(0,0) - - for face in mesh.faces: - for i in xrange(0,3): - if has_uvs: - t=(face.uv[i]) - - tex_key=(t[0],t[1]) - if not tex_list.has_key(tex_key): - tex_list[tex_key]=tex_count - tex_count+=1 - md2.num_tex_coords=tex_count #each vert has its own UV coord - - for this_tex in xrange (0, md2.num_tex_coords): - md2.tex_coords.append(md2_tex_coord()) - for coord, index in tex_list.iteritems(): - #md2.tex_coords.append(md2_tex_coord()) - md2.tex_coords[index].u=int(coord[0]*md2.skin_width) - md2.tex_coords[index].v=int((1-coord[1])*md2.skin_height) - - #put faces in the md2 structure - #for each face in the model - - if not has_uvs: - uv_coords=[(0,0)]*3 - - for this_face in xrange(0, md2.num_faces): - md2.faces.append(md2_face()) - mf = mesh.faces[this_face] - mf_v = mf.v - if has_uvs: - uv_coords = mf.uv - - for i in xrange(0,3): - #blender uses indexed vertexes so this works very well - md2.faces[this_face].vertex_index[i] = mf_v[i].index - #lookup texture index in dictionary - if has_uvs: - uv_coord = uv_coords[i] - # otherwise we set it before - - tex_key=(uv_coord[0],uv_coord[1]) - tex_index=tex_list[tex_key] - md2.faces[this_face].texture_index[i]=tex_index - - Blender.Window.DrawProgressBar(0.5, "Computing GL Commands") - - #compute GL commands - md2.num_GL_commands=build_GL_commands(md2, mesh) - - #get the frame data - #calculate 1 frame size + (1 vert size*num_verts) - md2.frame_size=40+(md2.num_vertices*4) #in bytes - - #get the frame list - user_frame_list=get_frame_list() - if user_frame_list=="default": - md2.num_frames=198 - else: - temp=user_frame_list[len(user_frame_list)-1] #last item - md2.num_frames=temp[2] #last frame number - - - progress=0.5 - progressIncrement=0.25/md2.num_frames - - #fill in each frame with frame info and all the vertex data for that frame - for frame_counter in xrange(0,md2.num_frames): - - progress+=progressIncrement - Blender.Window.DrawProgressBar(progress, "Calculating Frame: %d of %d" % (frame_counter, md2.num_frames)) - - #add a frame - md2.frames.append(md2_frame()) - #update the mesh objects vertex positions for the animation - Blender.Set("curframe", frame_counter) #set blender to the correct frame - - - - - mesh.getFromObject(object) #update the mesh to make verts current - mesh.transform(object.matrixWorld) - -#each frame has a scale and transform value that gets the vertex value between 0-255 -#since the scale and transform are the same for the all the verts in the frame, we only need -#to figure this out once per frame - - #we need to start with the bounding box - #bounding_box=object.getBoundBox() #uses the object, not the mesh data - #initialize with the first vertex for both min and max. X and Y are swapped for MD2 format - - #initialize - frame_min_x=100000.0 - frame_max_x=-100000.0 - frame_min_y=100000.0 - frame_max_y=-100000.0 - frame_min_z=100000.0 - frame_max_z=-100000.0 - - for face in mesh.faces: - for vert in face: - co = vert.co - if frame_min_x>co[1]: frame_min_x=co[1] - if frame_max_xco[0]: frame_min_y=co[0] - if frame_max_yco[2]: frame_min_z=co[2] - if frame_max_z maxdot): - maxdot = dot; - maxdotindex = j; - - # See patch [#19206], gives good info on this line below. - md2.frames[frame_counter].vertices[vert_counter].lightnormalindex=maxdotindex - - del maxdot, maxdotindex - del new_x, new_y, new_z - del frame_max_x, frame_max_y, frame_max_z, frame_min_x, frame_min_y, frame_min_z - del frame_scale_x, frame_scale_y, frame_scale_z, frame_trans_x, frame_trans_y, frame_trans_z - - - #output all the frame names-user_frame_list is loaded during the validation - for frame_set in user_frame_list: - for counter in xrange(frame_set[1]-1, frame_set[2]): - md2.frames[counter].name=frame_set[0]+"_"+str(counter-frame_set[1]+2) - - #compute these after everthing is loaded into a md2 structure - header_size=17*4 #17 integers, and each integer is 4 bytes - skin_size=64*md2.num_skins #64 char per skin * number of skins - tex_coord_size=4*md2.num_tex_coords #2 short * number of texture coords - face_size=12*md2.num_faces #3 shorts for vertex index, 3 shorts for tex index - frames_size=(((12+12+16)+(4*md2.num_vertices)) * md2.num_frames) #frame info+verts per frame*num frames - GL_command_size=md2.num_GL_commands*4 #each is an int or float, so 4 bytes per - - #fill in the info about offsets - md2.offset_skins=0+header_size - md2.offset_tex_coords=md2.offset_skins+skin_size - md2.offset_faces=md2.offset_tex_coords+tex_coord_size - md2.offset_frames=md2.offset_faces+face_size - md2.offset_GL_commands=md2.offset_frames+frames_size - md2.offset_end=md2.offset_GL_commands+GL_command_size - -###################################################### -# Get Frame List -###################################################### -def get_frame_list(): - global g_frame_filename - frame_list=[] - - if g_frame_filename.val=="default": - return MD2_FRAME_NAME_LIST - - else: - #check for file - if (Blender.sys.exists(g_frame_filename.val)==1): - #open file and read it in - file=open(g_frame_filename.val,"r") - lines=file.readlines() - file.close() - - #check header (first line) - if lines[0].strip() != "# MD2 Frame Name List": - print "its not a valid file" - result=Blender.Draw.PupMenu("This is not a valid frame definition file-using default%t|OK") - return MD2_FRAME_NAME_LIST - else: - #read in the data - num_frames=0 - for counter in xrange(1, len(lines)): - current_line=lines[counter].strip() - if current_line[0]=="#": - #found a comment - pass - else: - data=current_line.split() - frame_list.append([data[0],num_frames+1, num_frames+int(data[1])]) - num_frames+=int(data[1]) - return frame_list - else: - print "Cannot find file" - result=Blender.Draw.PupMenu("Cannot find frame definion file-using default%t|OK") - return MD2_FRAME_NAME_LIST - -###################################################### -# Globals for GL command list calculations -###################################################### -used_tris=[] -edge_dict={} -strip_verts=[] -strip_st=[] -strip_tris=[] -strip_first_run=True -odd=False - -###################################################### -# Find Strip length function -###################################################### -def find_strip_length(mesh, start_tri, edge_key): - #print "Finding strip length" - - global used_tris - global edge_dict - global strip_tris - global strip_st - global strip_verts - global strip_first_run - global odd - - used_tris[start_tri]=2 - - strip_tris.append(start_tri) #add this tri to the potential list of tri-strip - - #print "I am face: ", start_tri - #print "Using edge Key: ", edge_key - - faces=edge_dict[edge_key] #get list of face indexes that share this edge - if (len(faces)==0): - #print "Cant find edge with key: ", edge_key - pass - - #print "Faces sharing this edge: ", faces - for face_index in faces: - face=mesh.faces[face_index] - if face_index==start_tri: #don't want to check myself - #print "I found myself, continuing" - pass - else: - if used_tris[face_index]!=0: #found a used tri-move along - #print "Found a used tri: ", face_index - pass - else: - #find non-shared vert - for vert_counter in xrange(0,3): - if (face.verts[vert_counter].index!=edge_key[0] and face.verts[vert_counter].index!=edge_key[1]): - next_vert=vert_counter - - if(odd==False): - #print "Found a suitable even connecting tri: ", face_index - used_tris[face_index]=2 #mark as dirty for this rum - odd=True - - #find the new edge - if(face.verts[next_vert].index < face.verts[(next_vert+2)%3].index): - temp_key=(face.verts[next_vert].index,face.verts[(next_vert+2)%3].index) - else: - temp_key=(face.verts[(next_vert+2)%3].index, face.verts[next_vert].index) - - #print "temp key: ", temp_key - temp_faces=edge_dict[temp_key] - - if(len(temp_faces)==0): - print "Can't find any other faces with key: ", temp_key - else: - #search the new edge - #print "found other faces, searching them" - find_strip_length(mesh, face_index, temp_key) #recursive greedy-takes first tri it finds as best - break; - else: - #print "Found a suitable odd connecting tri: ", face_index - used_tris[face_index]=2 #mark as dirty for this rum - odd=False - - #find the new edge - if(face.verts[next_vert].index < face.verts[(next_vert+1)%3].index): - temp_key=(face.verts[next_vert].index,face.verts[(next_vert+1)%3].index) - else: - temp_key=(face.verts[(next_vert+1)%3].index, face.verts[next_vert].index) - #print "temp key: ", temp_key - temp_faces=edge_dict[temp_key] - if(len(temp_faces)==0): - print "Can't find any other faces with key: ", temp_key - else: - #search the new edge - #print "found other faces, searching them" - find_strip_length(mesh, face_index, temp_key) #recursive greedy-takes first tri it finds as best - break; - - return len(strip_tris) - - -###################################################### -# Tri-Stripify function -###################################################### -def stripify_tri_list(mesh, edge_key): - global edge_dict - global strip_tris - global strip_st - global strip_verts - - shared_edge=[] - key=[] - - #print "*****Stripify the triangle list*******" - #print "strip tris: ", strip_tris - #print "strip_tri length: ", len(strip_tris) - - for tri_counter in xrange(0, len(strip_tris)): - face=mesh.faces[strip_tris[tri_counter]] - if (tri_counter==0): #first one only - #find non-edge vert - for vert_counter in xrange(0,3): - if (face.verts[vert_counter].index!=edge_key[0] and face.verts[vert_counter].index!=edge_key[1]): - start_vert=vert_counter - strip_verts.append(face.verts[start_vert].index) - strip_st.append(face.uv[start_vert]) - - strip_verts.append(face.verts[(start_vert+2)%3].index) - strip_st.append(face.uv[(start_vert+2)%3]) - - strip_verts.append(face.verts[(start_vert+1)%3].index) - strip_st.append(face.uv[(start_vert+1)%3]) - else: - for vert_counter in xrange(0,3): - if(face.verts[vert_counter].index!=strip_verts[-1] and face.verts[vert_counter].index!=strip_verts[-2]): - strip_verts.append(face.verts[vert_counter].index) - strip_st.append(face.uv[vert_counter]) - break - - - -###################################################### -# Build GL command List -###################################################### -def build_GL_commands(md2, mesh): - # we can't output gl command structure without uv - if not mesh.faceUV: - print "No UV: not building GL Commands" - return 0 - - print "Building GL Commands" - - global used_tris - global edge_dict - global strip_verts - global strip_tris - global strip_st - - #globals initialization - used_tris=[0]*len(mesh.faces) - #print "Used: ", used_tris - num_commands=0 - - #edge dictionary generation - edge_dict=dict([(ed.key,[]) for ed in mesh.edges]) - for face in (mesh.faces): - for key in face.edge_keys: - edge_dict[key].append(face.index) - - #print "edge Dict: ", edge_dict - - for tri_counter in xrange(0,len(mesh.faces)): - if used_tris[tri_counter]!=0: - #print "Found a used triangle: ", tri_counter - pass - else: - #print "Found an unused triangle: ", tri_counter - - #intialization - strip_tris=[0]*0 - strip_verts=[0]*0 - strip_st=[0]*0 - strip_first_run=True - odd=True - - #find the strip length - strip_length=find_strip_length(mesh, tri_counter, mesh.faces[tri_counter].edge_keys[0]) - - #mark tris as used - for used_counter in xrange(0,strip_length): - used_tris[strip_tris[used_counter]]=1 - - stripify_tri_list(mesh, mesh.faces[tri_counter].edge_keys[0]) - - #create command list - cmd_list=md2_GL_cmd_list() - #number of commands in this list - print "strip length: ", strip_length - cmd_list.num=(len(strip_tris)+2) #positive for strips, fans would be negative, but not supported yet - num_commands+=1 - - #add s,t,vert for this command list - for command_counter in xrange(0, len(strip_tris)+2): - cmd=md2_GL_command() - cmd.s=strip_st[command_counter][0] - cmd.t=1.0-strip_st[command_counter][1] #flip upside down - cmd.vert_index=strip_verts[command_counter] - num_commands+=3 - cmd_list.cmd_list.append(cmd) - print "Cmd List length: ", len(cmd_list.cmd_list) - print "Cmd list num: ", cmd_list.num - print "Cmd List: ", cmd_list.dump() - md2.GL_commands.append(cmd_list) - - #add the null command at the end - temp_cmdlist=md2_GL_cmd_list() - temp_cmdlist.num=0 - md2.GL_commands.append(temp_cmdlist) - num_commands+=1 - - #cleanup and return - used=strip_vert=strip_st=strip_tris=0 - return num_commands - - - - -###################################################### -# Save MD2 Format -###################################################### -def save_md2(filename): - print "" - print "***********************************" - print "MD2 Export" - print "***********************************" - print "" - - Blender.Window.DrawProgressBar(0.0,"Begining MD2 Export") - - md2=md2_obj() #blank md2 object to save - - #get the object - mesh_objs = Blender.Object.GetSelected() - - #check there is a blender object selected - if len(mesh_objs)==0: - print "Fatal Error: Must select a mesh to output as MD2" - print "Found nothing" - result=Blender.Draw.PupMenu("Must select an object to export%t|OK") - return - - mesh_obj=mesh_objs[0] #this gets the first object (should be only one) - - #check if it's a mesh object - if mesh_obj.getType()!="Mesh": - print "Fatal Error: Must select a mesh to output as MD2" - print "Found: ", mesh_obj.getType() - result=Blender.Draw.PupMenu("Selected Object must be a mesh to output as MD2%t|OK") - return - - ok=validation(mesh_obj) - if ok==False: - return - - fill_md2(md2, mesh_obj) - md2.dump() - - Blender.Window.DrawProgressBar(1.0, "Writing to Disk") - - #actually write it to disk - file=open(filename,"wb") - md2.save(file) - file.close() - - #cleanup - md2=0 - - print "Closed the file" - diff --git a/release/scripts/md2_import.py b/release/scripts/md2_import.py deleted file mode 100644 index f52746259a6..00000000000 --- a/release/scripts/md2_import.py +++ /dev/null @@ -1,600 +0,0 @@ -#!BPY - -""" -Name: 'MD2 (.md2)' -Blender: 239 -Group: 'Import' -Tooltip: 'Import from Quake file format (.md2).' -""" - -__author__ = 'Bob Holcomb' -__version__ = '0.16' -__url__ = ["Bob's site, http://bane.servebeer.com", - "Support forum, http://scourage.servebeer.com/phpbb/", "blender", "blenderartists.org"] -__email__ = ["Bob Holcomb, bob_holcomb:hotmail*com", "scripts"] -__bpydoc__ = """\ -This script imports a Quake 2 file (MD2), textures, -and animations into blender for editing. Loader is based on MD2 loader from www.gametutorials.com-Thanks DigiBen! and the md3 blender loader by PhaethonH
- - Additional help from: Shadwolf, Skandal, Rojo and Campbell Barton
- Thanks Guys! -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Bob Holcomb -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -import Blender -from Blender import Mesh, Object, sys -from Blender.BGL import * -from Blender.Draw import * -from Blender.Window import * -from Blender.Mathutils import Vector -import struct -from types import * - - -###################################################### -# Main Body -###################################################### - -#returns the string from a null terminated string -def asciiz (s): - n = 0 - while (ord(s[n]) != 0): - n = n + 1 - return s[0:n] - - -###################################################### -# MD2 Model Constants -###################################################### -MD2_MAX_TRIANGLES=4096 -MD2_MAX_VERTICES=2048 -MD2_MAX_TEXCOORDS=2048 -MD2_MAX_FRAMES=512 -MD2_MAX_SKINS=32 -MD2_MAX_FRAMESIZE=(MD2_MAX_VERTICES * 4 + 128) - -###################################################### -# MD2 data structures -###################################################### -class md2_alias_triangle(object): - __slots__ = 'vertices', 'lightnormalindex' - binary_format="<3BB" #little-endian (<), 3 Unsigned char - - def __init__(self): - self.vertices=[0]*3 - self.lightnormalindex=0 - - def load(self, file): - temp_data = file.read(struct.calcsize(self.binary_format)) - data = struct.unpack(self.binary_format, temp_data) - self.vertices[0]=data[0] - self.vertices[1]=data[1] - self.vertices[2]=data[2] - self.lightnormalindex=data[3] - return self - - def dump(self): - print "MD2 Alias_Triangle Structure" - print "vertex: ", self.vertices[0] - print "vertex: ", self.vertices[1] - print "vertex: ", self.vertices[2] - print "lightnormalindex: ",self.lightnormalindex - print "" - -class md2_face(object): - - binary_format="<3h3h" #little-endian (<), 3 short, 3 short - - __slots__ = 'vertex_index', 'texture_index' - - def __init__(self): - self.vertex_index = [ 0, 0, 0 ] - self.texture_index = [ 0, 0, 0] - - def load (self, file): - temp_data=file.read(struct.calcsize(self.binary_format)) - data=struct.unpack(self.binary_format, temp_data) - self.vertex_index[0]=data[0] - self.vertex_index[1]=data[1] - self.vertex_index[2]=data[2] - self.texture_index[0]=data[3] - self.texture_index[1]=data[4] - self.texture_index[2]=data[5] - return self - - def dump (self): - print "MD2 Face Structure" - print "vertex index: ", self.vertex_index[0] - print "vertex index: ", self.vertex_index[1] - print "vertex index: ", self.vertex_index[2] - print "texture index: ", self.texture_index[0] - print "texture index: ", self.texture_index[1] - print "texture index: ", self.texture_index[2] - print "" - -class md2_tex_coord(object): - __slots__ = 'u', 'v' - binary_format="<2h" #little-endian (<), 2 unsigned short - - def __init__(self): - self.u=0 - self.v=0 - - def load (self, file): - temp_data=file.read(struct.calcsize(self.binary_format)) - data=struct.unpack(self.binary_format, temp_data) - self.u=data[0] - self.v=data[1] - return self - - def dump (self): - print "MD2 Texture Coordinate Structure" - print "texture coordinate u: ",self.u - print "texture coordinate v: ",self.v - print "" - - -class md2_skin(object): - __slots__ = 'name' - binary_format="<64s" #little-endian (<), char[64] - - def __init__(self): - self.name="" - - def load (self, file): - temp_data=file.read(struct.calcsize(self.binary_format)) - data=struct.unpack(self.binary_format, temp_data) - self.name=asciiz(data[0]) - return self - - def dump (self): - print "MD2 Skin" - print "skin name: ",self.name - print "" - -class md2_alias_frame(object): - __slots__ = 'scale', 'translate', 'name', 'vertices' - binary_format="<3f3f16s" #little-endian (<), 3 float, 3 float char[16] - #did not add the "3bb" to the end of the binary format - #because the alias_vertices will be read in through - #thier own loader - - def __init__(self): - self.scale=[0.0]*3 - self.translate=[0.0]*3 - self.name="" - self.vertices=[] - - - def load (self, file): - temp_data=file.read(struct.calcsize(self.binary_format)) - data=struct.unpack(self.binary_format, temp_data) - self.scale[0]=data[0] - self.scale[1]=data[1] - self.scale[2]=data[2] - self.translate[0]=data[3] - self.translate[1]=data[4] - self.translate[2]=data[5] - self.name=asciiz(data[6]) - return self - - def dump (self): - print "MD2 Alias Frame" - print "scale x: ",self.scale[0] - print "scale y: ",self.scale[1] - print "scale z: ",self.scale[2] - print "translate x: ",self.translate[0] - print "translate y: ",self.translate[1] - print "translate z: ",self.translate[2] - print "name: ",self.name - print "" - -class md2_obj(object): - __slots__ =\ - 'tex_coords', 'faces', 'frames',\ - 'skins', 'ident', 'version',\ - 'skin_width', 'skin_height',\ - 'frame_size', 'num_skins', 'num_vertices',\ - 'num_tex_coords', 'num_faces', 'num_GL_commands',\ - 'num_frames', 'offset_skins', 'offset_tex_coords',\ - 'offset_faces', 'offset_frames', 'offset_GL_commands' - - ''' - #Header Structure - ident=0 #int 0 This is used to identify the file - version=0 #int 1 The version number of the file (Must be 8) - skin_width=0 #int 2 The skin width in pixels - skin_height=0 #int 3 The skin height in pixels - frame_size=0 #int 4 The size in bytes the frames are - num_skins=0 #int 5 The number of skins associated with the model - num_vertices=0 #int 6 The number of vertices (constant for each frame) - num_tex_coords=0 #int 7 The number of texture coordinates - num_faces=0 #int 8 The number of faces (polygons) - num_GL_commands=0 #int 9 The number of gl commands - num_frames=0 #int 10 The number of animation frames - offset_skins=0 #int 11 The offset in the file for the skin data - offset_tex_coords=0 #int 12 The offset in the file for the texture data - offset_faces=0 #int 13 The offset in the file for the face data - offset_frames=0 #int 14 The offset in the file for the frames data - offset_GL_commands=0#int 15 The offset in the file for the gl commands data - offset_end=0 #int 16 The end of the file offset - ''' - binary_format="<17i" #little-endian (<), 17 integers (17i) - - #md2 data objects - - def __init__ (self): - self.tex_coords=[] - self.faces=[] - self.frames=[] - self.skins=[] - - - def load (self, file): - temp_data = file.read(struct.calcsize(self.binary_format)) - data = struct.unpack(self.binary_format, temp_data) - - self.ident=data[0] - self.version=data[1] - - if (self.ident!=844121161 or self.version!=8): - print "Not a valid MD2 file" - Exit() - - self.skin_width=data[2] - self.skin_height=data[3] - self.frame_size=data[4] - - #make the # of skin objects for model - self.num_skins=data[5] - for i in xrange(0,self.num_skins): - self.skins.append(md2_skin()) - - self.num_vertices=data[6] - - #make the # of texture coordinates for model - self.num_tex_coords=data[7] - for i in xrange(0,self.num_tex_coords): - self.tex_coords.append(md2_tex_coord()) - - #make the # of triangle faces for model - self.num_faces=data[8] - for i in xrange(0,self.num_faces): - self.faces.append(md2_face()) - - self.num_GL_commands=data[9] - - #make the # of frames for the model - self.num_frames=data[10] - for i in xrange(0,self.num_frames): - self.frames.append(md2_alias_frame()) - #make the # of vertices for each frame - for j in xrange(0,self.num_vertices): - self.frames[i].vertices.append(md2_alias_triangle()) - - self.offset_skins=data[11] - self.offset_tex_coords=data[12] - self.offset_faces=data[13] - self.offset_frames=data[14] - self.offset_GL_commands=data[15] - - #load the skin info - file.seek(self.offset_skins,0) - for i in xrange(0, self.num_skins): - self.skins[i].load(file) - #self.skins[i].dump() - - #load the texture coordinates - file.seek(self.offset_tex_coords,0) - for i in xrange(0, self.num_tex_coords): - self.tex_coords[i].load(file) - #self.tex_coords[i].dump() - - #load the face info - file.seek(self.offset_faces,0) - for i in xrange(0, self.num_faces): - self.faces[i].load(file) - #self.faces[i].dump() - - #load the frames - file.seek(self.offset_frames,0) - for i in xrange(0, self.num_frames): - self.frames[i].load(file) - #self.frames[i].dump() - for j in xrange(0,self.num_vertices): - self.frames[i].vertices[j].load(file) - #self.frames[i].vertices[j].dump() - return self - - def dump (self): - print "Header Information" - print "ident: ", self.ident - print "version: ", self.version - print "skin width: ", self.skin_width - print "skin height: ", self.skin_height - print "frame size: ", self.frame_size - print "number of skins: ", self.num_skins - print "number of texture coordinates: ", self.num_tex_coords - print "number of faces: ", self.num_faces - print "number of frames: ", self.num_frames - print "number of vertices: ", self.num_vertices - print "offset skins: ", self.offset_skins - print "offset texture coordinates: ", self.offset_tex_coords - print "offset faces: ", self.offset_faces - print "offset frames: ",self.offset_frames - print "" - -###################################################### -# Import functions -###################################################### -def load_textures(md2, texture_filename): - #did the user specify a texture they wanted to use? - if texture_filename: - if (Blender.sys.exists(texture_filename)): - try: return Blender.Image.Load(texture_filename) - except: return -1 # could not load? - - #does the model have textures specified with it? - if int(md2.num_skins) > 0: - for i in xrange(0,md2.num_skins): - #md2.skins[i].dump() - if (Blender.sys.exists(md2.skins[i].name)): - try: return Blender.Image.Load(md2.skins[i].name) - except: return -1 - - -def animate_md2(md2, mesh): - ######### Animate the verts through keyframe animation - - # Fast access to the meshes vertex coords - verts = [v.co for v in mesh.verts] - scale = g_scale.val - - for i in xrange(1, md2.num_frames): - frame = md2.frames[i] - #update the vertices - for j in xrange(md2.num_vertices): - x=(frame.scale[0] * frame.vertices[j].vertices[0] + frame.translate[0]) * scale - y=(frame.scale[1] * frame.vertices[j].vertices[1] + frame.translate[1]) * scale - z=(frame.scale[2] * frame.vertices[j].vertices[2] + frame.translate[2]) * scale - - #put the vertex in the right spot - verts[j][:] = y,-x,z - - mesh.insertKey(i,"absolute") - # mesh.insertKey(i) - - #not really necissary, but I like playing with the frame counter - Blender.Set("curframe", i) - - - # Make the keys animate in the 3d view. - key = mesh.key - key.relative = False - - # Add an IPO to teh Key - ipo = Blender.Ipo.New('Key', 'md2') - key.ipo = ipo - # Add a curve to the IPO - curve = ipo.addCurve('Basis') - - # Add 2 points to cycle through the frames. - curve.append((1, 0)) - curve.append((md2.num_frames, (md2.num_frames-1)/10.0)) - curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - - - -def load_md2(md2_filename, texture_filename): - #read the file in - file=open(md2_filename,"rb") - WaitCursor(1) - DrawProgressBar(0.0, 'Loading MD2') - md2=md2_obj() - md2.load(file) - #md2.dump() - file.close() - - ######### Creates a new mesh - mesh = Mesh.New() - - uv_coord=[] - #uv_list=[] - verts_extend = [] - #load the textures to use later - #-1 if there is no texture to load - mesh_image=load_textures(md2, texture_filename) - if mesh_image == -1 and texture_filename: - print 'MD2 Import, Warning, texture "%s" could not load' - - ######### Make the verts - DrawProgressBar(0.25,"Loading Vertex Data") - frame = md2.frames[0] - scale = g_scale.val - - def tmp_get_vertex(i): - #use the first frame for the mesh vertices - x=(frame.scale[0]*frame.vertices[i].vertices[0]+frame.translate[0])*scale - y=(frame.scale[1]*frame.vertices[i].vertices[1]+frame.translate[1])*scale - z=(frame.scale[2]*frame.vertices[i].vertices[2]+frame.translate[2])*scale - return y,-x,z - - mesh.verts.extend( [tmp_get_vertex(i) for i in xrange(0,md2.num_vertices)] ) - del tmp_get_vertex - - ######## Make the UV list - DrawProgressBar(0.50,"Loading UV Data") - - w = float(md2.skin_width) - h = float(md2.skin_height) - if w <= 0.0: w = 1.0 - if h <= 0.0: h = 1.0 - #for some reason quake2 texture maps are upside down, flip that - uv_list = [Vector(co.u/w, 1-(co.v/h)) for co in md2.tex_coords] - del w, h - - ######### Make the faces - DrawProgressBar(0.75,"Loading Face Data") - faces = [] - face_uvs = [] - for md2_face in md2.faces: - f = md2_face.vertex_index[0], md2_face.vertex_index[2], md2_face.vertex_index[1] - uv = uv_list[md2_face.texture_index[0]], uv_list[md2_face.texture_index[2]], uv_list[md2_face.texture_index[1]] - - if f[2] == 0: - # EEKADOODLE :/ - f= f[1], f[2], f[0] - uv= uv[1], uv[2], uv[0] - - #ditto in reverse order with the texture verts - faces.append(f) - face_uvs.append(uv) - - - face_mapping = mesh.faces.extend(faces, indexList=True) - print len(faces) - print len(mesh.faces) - mesh.faceUV= True #turn on face UV coordinates for this mesh - mesh_faces = mesh.faces - for i, uv in enumerate(face_uvs): - if face_mapping[i] != None: - f = mesh_faces[face_mapping[i]] - f.uv = uv - if (mesh_image!=-1): - f.image=mesh_image - - scn= Blender.Scene.GetCurrent() - mesh_obj= scn.objects.new(mesh) - animate_md2(md2, mesh) - DrawProgressBar(0.98,"Loading Animation Data") - - #locate the Object containing the mesh at the cursor location - cursor_pos=Blender.Window.GetCursorPos() - mesh_obj.setLocation(float(cursor_pos[0]),float(cursor_pos[1]),float(cursor_pos[2])) - DrawProgressBar (1.0, "") - WaitCursor(0) - -#*********************************************** -# MAIN -#*********************************************** - -# Import globals -g_md2_filename=Create("*.md2") -#g_md2_filename=Create("/d/warvet/tris.md2") -g_texture_filename=Create('') -# g_texture_filename=Create("/d/warvet/warvet.jpg") - -g_filename_search=Create("*.md2") -g_texture_search=Create('') -# g_texture_search=Create("/d/warvet/warvet.jpg") - -#Globals -g_scale=Create(1.0) - -# Events -EVENT_NOEVENT=1 -EVENT_LOAD_MD2=2 -EVENT_CHOOSE_FILENAME=3 -EVENT_CHOOSE_TEXTURE=4 -EVENT_SAVE_MD2=5 -EVENT_EXIT=100 - -###################################################### -# Callbacks for Window functions -###################################################### -def filename_callback(input_filename): - global g_md2_filename - g_md2_filename.val=input_filename - -def texture_callback(input_texture): - global g_texture_filename - g_texture_filename.val=input_texture - -###################################################### -# GUI Loader -###################################################### - - -def draw_gui(): - global g_scale - global g_md2_filename - global g_texture_filename - global EVENT_NOEVENT,EVENT_LOAD_MD2,EVENT_CHOOSE_FILENAME,EVENT_CHOOSE_TEXTURE,EVENT_EXIT - - ########## Titles - glClear(GL_COLOR_BUFFER_BIT) - glRasterPos2d(8, 125) - Text("MD2 loader") - - ######### Parameters GUI Buttons - BeginAlign() - g_md2_filename = String("MD2 file to load: ", EVENT_NOEVENT, 10, 55, 210, 18, - g_md2_filename.val, 255, "MD2 file to load") - ########## MD2 File Search Button - Button("Browse",EVENT_CHOOSE_FILENAME,220,55,80,18) - EndAlign() - - BeginAlign() - g_texture_filename = String("Texture file to load: ", EVENT_NOEVENT, 10, 35, 210, 18, - g_texture_filename.val, 255, "Texture file to load-overrides MD2 file") - ########## Texture Search Button - Button("Browse",EVENT_CHOOSE_TEXTURE,220,35,80,18) - EndAlign() - - ########## Scale slider-default is 1/8 which is a good scale for md2->blender - g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 75, 210, 18, - 1.0, 0.001, 10.0, 1, "Scale factor for obj Model"); - - ######### Draw and Exit Buttons - Button("Load",EVENT_LOAD_MD2 , 10, 10, 80, 18) - Button("Exit",EVENT_EXIT , 170, 10, 80, 18) - -def event(evt, val): - if (evt == QKEY and not val): - Blender.Draw.Exit() - -def bevent(evt): - global g_md2_filename - global g_texture_filename - global EVENT_NOEVENT,EVENT_LOAD_MD2,EVENT_SAVE_MD2,EVENT_EXIT - - ######### Manages GUI events - if (evt==EVENT_EXIT): - Blender.Draw.Exit() - elif (evt==EVENT_CHOOSE_FILENAME): - FileSelector(filename_callback, "MD2 File Selection") - elif (evt==EVENT_CHOOSE_TEXTURE): - FileSelector(texture_callback, "Texture Selection") - elif (evt==EVENT_LOAD_MD2): - if not Blender.sys.exists(g_md2_filename.val): - PupMenu('Model file does not exist') - return - else: - load_md2(g_md2_filename.val, g_texture_filename.val) - Blender.Redraw() - Blender.Draw.Exit() - return - -if __name__ == '__main__': - Register(draw_gui, event, bevent) diff --git a/release/scripts/mesh_boneweight_copy.py b/release/scripts/mesh_boneweight_copy.py deleted file mode 100644 index d2a477fbc0b..00000000000 --- a/release/scripts/mesh_boneweight_copy.py +++ /dev/null @@ -1,287 +0,0 @@ -#!BPY -""" -Name: 'Bone Weight Copy' -Blender: 245 -Group: 'Object' -Tooltip: 'Copy Bone Weights from 1 mesh, to all other selected meshes.' -""" - -__author__ = "Campbell Barton aka ideasman42" -__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"] -__version__ = "0.1" -__bpydoc__ = """\ - -Bone Weight Copy - -This script is used to copy bone weights from 1 mesh with weights (the source mesh) to many (the target meshes). -Weights are copied from 1 mesh to another based on how close they are together. - -For normal operation, select 1 source mesh with vertex weights and any number of unweighted meshes that overlap the source mesh. -Then run this script using default options and check the new weigh. - - -A differnt way to use this script is to update the weights an an alredy weighted mesh. -this is done using the "Copy to Selected" option enabled and works a bit differently, -With the target mesh, select the verts you want to update. -since all meshes have weights we cant just use the weighted mesh as the source, -so the Active Object is used for the source mesh. -Run the script and the selected verts on all non active meshes will be updated. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from Blender import Armature, Object, Mathutils, Window, Mesh -Vector= Mathutils.Vector -SMALL_NUM= 0.000001 -def copy_bone_influences(_from, _to, PREF_SEL_ONLY, PREF_NO_XCROSS): - ob_from, me_from, world_verts_from, from_groups= _from - ob_to, me_to, world_verts_to, dummy= _to - del dummy - - def getSnapIdx(seek_vec, vecs): - ''' - Returns the closest vec to snap_points - ''' - - # First seek the closest Z axis vert idx/v - seek_vec_x,seek_vec_y,seek_vec_z= seek_vec - - from_vec_idx= 0 - - len_vecs= len(vecs) - - upidx= len_vecs-1 - loidx= 0 - - while from_vec_idx < len_vecs and vecs[from_vec_idx][1].z < seek_vec_z: - from_vec_idx+=1 - - # Clamp if we overstepped. - if from_vec_idx >= len_vecs: - from_vec_idx-=1 - - close_dist= (vecs[from_vec_idx][1]-seek_vec).length - close_idx= vecs[from_vec_idx][0] - - upidx= from_vec_idx+1 - loidx= from_vec_idx-1 - - # Set uselo/useup. This means we can keep seeking up/down. - if upidx >= len_vecs: useup= False - else: useup= True - - if loidx < 0: uselo= False - else: uselo= True - - # Seek up/down to find the closest v to seek vec. - while uselo or useup: - if useup: - if upidx >= len_vecs: - useup= False - else: - i,v= vecs[upidx] - if (not PREF_NO_XCROSS) or ((v.x >= -SMALL_NUM and seek_vec_x >= -SMALL_NUM) or (v.x <= SMALL_NUM and seek_vec_x <= SMALL_NUM)): # enfoce xcrossing - if v.z-seek_vec_z > close_dist: - # the verticle distance is greater then the best distance sofar. we can stop looking up. - useup= False - elif abs(seek_vec_y-v.y) < close_dist and abs(seek_vec_x-v.x) < close_dist: - # This is in the limit measure it. - l= (seek_vec-v).length - if l= -SMALL_NUM and seek_vec_x >= -SMALL_NUM) or (v.x <= SMALL_NUM and seek_vec_x <= SMALL_NUM)): # enfoce xcrossing - if seek_vec_z-v.z > close_dist: - # the verticle distance is greater then the best distance sofar. we can stop looking up. - uselo= False - elif abs(seek_vec_y-v.y) < close_dist and abs(seek_vec_x-v.x) < close_dist: - # This is in the limit measure it. - l= (seek_vec-v).length - if l "%s" ' % (ob_from.name, ob_to.name)) - - from_idx= getSnapIdx(co, world_verts_from) - from_infs= me_from.getVertexInfluences(from_idx) - - for group, weight in from_infs: - - # Add where needed. - if PREF_SEL_ONLY and group not in to_groups: - me_to.addVertGroup(group) - to_groups.append(group) - - me_to.assignVertsToGroup(group, [i], weight, add_) - - me_to.update() - -# ZSORT return (i/co) tuples, used for fast seeking of the snapvert. -def worldspace_verts_idx(me, ob): - mat= ob.matrixWorld - verts_zsort= [ (i, v.co*mat) for i, v in enumerate(me.verts) ] - - # Sorts along the Z Axis so we can optimize the getsnap. - try: verts_zsort.sort(key = lambda a: a[1].z) - except: verts_zsort.sort(lambda a,b: cmp(a[1].z, b[1].z,)) - - return verts_zsort - - -def worldspace_verts(me, ob): - mat= ob.matrixWorld - return [ v.co*mat for v in me.verts ] - -def subdivMesh(me, subdivs): - oldmode = Mesh.Mode() - Mesh.Mode(Mesh.SelectModes['FACE']) - me.sel= 1 - for i in xrange(subdivs): - me.subdivide(0) - Mesh.Mode(oldmode) - - -def main(): - print '\nStarting BoneWeight Copy...' - scn= Blender.Scene.GetCurrent() - contextSel= Object.GetSelected() - if not contextSel: - Blender.Draw.PupMenu('Error%t|2 or more mesh objects need to be selected.|aborting.') - return - - PREF_QUALITY= Blender.Draw.Create(0) - PREF_NO_XCROSS= Blender.Draw.Create(0) - PREF_SEL_ONLY= Blender.Draw.Create(0) - - pup_block = [\ - ('Quality:', PREF_QUALITY, 0, 4, 'Generate interpolated verts for a higher quality result.'),\ - ('No X Crossing', PREF_NO_XCROSS, 'Do not snap across the zero X axis'),\ - '',\ - '"Update Selected" copies',\ - 'active object weights to',\ - 'selected verts on the other',\ - 'selected mesh objects.',\ - ('Update Selected', PREF_SEL_ONLY, 'Only copy new weights to selected verts on the target mesh. (use active object as source)'),\ - ] - - - if not Blender.Draw.PupBlock("Copy Weights for %i Meshs" % len(contextSel), pup_block): - return - - PREF_SEL_ONLY= PREF_SEL_ONLY.val - PREF_NO_XCROSS= PREF_NO_XCROSS.val - quality= PREF_QUALITY.val - - act_ob= scn.objects.active - if PREF_SEL_ONLY and act_ob==None: - Blender.Draw.PupMenu('Error%t|When dealing with 2 or more meshes with vgroups|There must be an active object|to be used as a source|aborting.') - return - - sel=[] - from_data= None - - for ob in contextSel: - if ob.type=='Mesh': - me= ob.getData(mesh=1) - groups= me.getVertGroupNames() - - # If this is the only mesh with a group OR if its one of many, but its active. - if groups and ((ob==act_ob and PREF_SEL_ONLY) or (not PREF_SEL_ONLY)): - if from_data: - Blender.Draw.PupMenu('More then 1 mesh has vertex weights, only select 1 mesh with weights. aborting.') - return - else: - # This uses worldspace_verts_idx which gets (idx,co) pairs, then zsorts. - if quality: - for _ob in contextSel: - _ob.sel=0 - ob.sel=1 - Object.Duplicate(mesh=1) - ob= scn.objects.active - me= ob.getData(mesh=1) - # groups will be the same - print '\tGenerating higher %ix quality weights.' % quality - subdivMesh(me, quality) - scn.unlink(ob) - from_data= (ob, me, worldspace_verts_idx(me, ob), groups) - - else: - data= (ob, me, worldspace_verts(me, ob), groups) - sel.append(data) - - if not from_data: - Blender.Draw.PupMenu('Error%t|No mesh with vertex groups found.') - return - - if not sel: - Blender.Draw.PupMenu('Error%t|Select 2 or more mesh objects, aborting.') - if quality: from_data[1].verts= None - return - - t= Blender.sys.time() - Window.WaitCursor(1) - - # Now do the copy. - print '\tCopying from "%s" to %i other mesh(es).' % (from_data[0].name, len(sel)) - for data in sel: - copy_bone_influences(from_data, data, PREF_SEL_ONLY, PREF_NO_XCROSS) - - # We cant unlink the mesh, but at least remove its data. - if quality: - from_data[1].verts= None - - print 'Copy Complete in %.6f sec' % (Blender.sys.time()-t) - Window.DrawProgressBar(1.0, '') - Window.WaitCursor(0) - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/release/scripts/mesh_cleanup.py b/release/scripts/mesh_cleanup.py deleted file mode 100644 index 27adca335cb..00000000000 --- a/release/scripts/mesh_cleanup.py +++ /dev/null @@ -1,456 +0,0 @@ -#!BPY -""" -Name: 'Clean Meshes' -Blender: 245 -Group: 'Mesh' -Tooltip: 'Clean unused data from all selected mesh objects.' -""" - -__author__ = "Campbell Barton aka ideasman42" -__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"] -__version__ = "0.1" -__bpydoc__ = """\ -Clean Meshes - -Cleans unused data from selected meshes -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -from Blender import * -import bpy -from Blender.Mathutils import TriangleArea - -import Blender -import BPyMesh -dict2MeshWeight= BPyMesh.dict2MeshWeight -meshWeight2Dict= BPyMesh.meshWeight2Dict - -def rem_free_verts(me): - vert_users= [0] * len(me.verts) - for f in me.faces: - for v in f: - vert_users[v.index]+=1 - - for e in me.edges: - for v in e: # loop on edge verts - vert_users[v.index]+=1 - - verts_free= [i for i, users in enumerate(vert_users) if not users] - - if verts_free: - pass - me.verts.delete(verts_free) - return len(verts_free) - -def rem_free_edges(me, limit=None): - ''' Only remove based on limit if a limit is set, else remove all ''' - - edgeDict= {} # will use a set when python 2.4 is standard. - - for f in me.faces: - for edkey in f.edge_keys: - edgeDict[edkey] = None - - edges_free= [] - for e in me.edges: - if not edgeDict.has_key(e.key): - edges_free.append(e) - - if limit != None: - edges_free= [e for e in edges_free if e.length <= limit] - - me.edges.delete(edges_free) - return len(edges_free) - -def rem_area_faces(me, limit=0.001): - ''' Faces that have an area below the limit ''' - rem_faces= [f for f in me.faces if f.area <= limit] - if rem_faces: - me.faces.delete( 0, rem_faces ) - return len(rem_faces) - -def rem_perimeter_faces(me, limit=0.001): - ''' Faces whos combine edge length is below the limit ''' - def faceEdLen(f): - v= f.v - if len(v) == 3: - return\ - (v[0].co-v[1].co).length +\ - (v[1].co-v[2].co).length +\ - (v[2].co-v[0].co).length - else: # 4 - return\ - (v[0].co-v[1].co).length +\ - (v[1].co-v[2].co).length +\ - (v[2].co-v[3].co).length +\ - (v[3].co-v[0].co).length - rem_faces= [f for f in me.faces if faceEdLen(f) <= limit] - if rem_faces: - me.faces.delete( 0, rem_faces ) - return len(rem_faces) - -def rem_unused_materials(me): - materials= me.materials - len_materials= len(materials) - if len_materials < 2: - return 0 - - rem_materials= 0 - - material_users= dict( [(i,0) for i in xrange(len_materials)] ) - - for f in me.faces: - f_mat = f.mat - # Make sure the face index isnt too big. this happens sometimes. - if f_mat >= len_materials: - f_mat = f.mat = 0 - material_users[f_mat] += 1 - - # mat_idx_subtract= 0 - # reindex_mapping= dict( [(i,0) for i in xrange(len_materials)] ) - - reindex_mapping_ls = range(len_materials) - for i in range(len_materials-1, -1, -1): - if material_users[i] == 0: - del reindex_mapping_ls[i] - del materials[i] - rem_materials+=1 - - reindex_mapping= {} - - for i, mat in enumerate(reindex_mapping_ls): - reindex_mapping[mat] = i - - for f in me.faces: - f.mat= reindex_mapping[f.mat] - - me.materials= materials - return rem_materials - - -def rem_free_groups(me, groupNames, vWeightDict): - ''' cound how many vert users a group has and remove unused groups ''' - rem_groups = 0 - groupUserDict= dict([(group,0) for group in groupNames]) - - for vertexWeight in vWeightDict: - for group, weight in vertexWeight.iteritems(): - groupUserDict[group] += 1 - - i=len(groupNames) - while i: - i-=1 - group= groupNames[i] - if groupUserDict[group] == 0: - del groupNames[i] - print '\tremoving, vgroup', group - rem_groups+=1 - return rem_groups - -def rem_zero_weights(me, limit, groupNames, vWeightDict): - ''' remove verts from a group when their weight is zero.''' - rem_vweight_count= 0 - for vertexWeight in vWeightDict: - items= vertexWeight.items() - for group, weight in items: - if weight < limit: - del vertexWeight[group] - rem_vweight_count+= 1 - - return rem_vweight_count - - -def normalize_vweight(me, groupNames, vWeightDict): - for vertexWeight in vWeightDict: - unit= 0.0 - for group, weight in vertexWeight.iteritems(): - unit+= weight - - if unit != 1.0 and unit != 0.0: - for group, weight in vertexWeight.iteritems(): - vertexWeight[group]= weight/unit - -def isnan(f): - fstring = str(f).lower() - if 'nan' in fstring: - return True - if 'inf' in fstring: - return True - - return False - -def fix_nan_verts__internal(me): - rem_nan = 0 - for v in me.verts: - co = v.co - for i in (0,1,2): - if isnan(co[i]): - co[i] = 0.0 - rem_nan += 1 - return rem_nan - -def fix_nan_verts(me): - rem_nan = 0 - key = me.key - if key: - # Find the object, and get a mesh thats thinked to the oblink. - # this is a bit crap but needed to set the active key. - me_oblink = None - for ob in bpy.data.objects: - me_oblink = ob.getData(mesh=1) - if me_oblink == me: - me = me_oblink - break - if not me_oblink: - ob = None - - if key and ob: - blocks = key.blocks - # print blocks - orig_pin = ob.pinShape - orig_shape = ob.activeShape - orig_relative = key.relative - ob.pinShape = True - for i, block in enumerate(blocks): - ob.activeShape = i+1 - ob.makeDisplayList() - rem_nan += fix_nan_verts__internal(me) - me.update(block.name) # get the new verts - ob.pinShape = orig_pin - ob.activeShape = orig_shape - key.relative = orig_relative - - else: # No keys, simple operation - rem_nan = fix_nan_verts__internal(me) - - return rem_nan - -def fix_nan_uvs(me): - rem_nan = 0 - if me.faceUV: - orig_uvlayer = me.activeUVLayer - for uvlayer in me.getUVLayerNames(): - me.activeUVLayer = uvlayer - for f in me.faces: - for uv in f.uv: - for i in (0,1): - if isnan(uv[i]): - uv[i] = 0.0 - rem_nan += 1 - me.activeUVLayer = orig_uvlayer - return rem_nan - - -def has_vcol(me): - for f in me.faces: - for col in f.col: - if not (255 == col.r == col.g == col.b): - return True - return False - -def rem_white_vcol_layers(me): - vcols_removed = 0 - if me.vertexColors: - for col in me.getColorLayerNames(): - me.activeColorLayer = col - if not has_vcol(me): - me.removeColorLayer(col) - vcols_removed += 1 - - return vcols_removed - - -def main(): - sce= bpy.data.scenes.active - obsel= list(sce.objects.context) - actob= sce.objects.active - - is_editmode= Window.EditMode() - - # Edit mode object is not active, add it to the list. - if is_editmode and (not actob.sel): - obsel.append(actob) - - - #====================================# - # Popup menu to select the functions # - #====================================# - - CLEAN_ALL_DATA= Draw.Create(0) - CLEAN_VERTS_FREE= Draw.Create(1) - CLEAN_EDGE_NOFACE= Draw.Create(0) - CLEAN_EDGE_SMALL= Draw.Create(0) - CLEAN_FACE_PERIMETER= Draw.Create(0) - CLEAN_FACE_SMALL= Draw.Create(0) - - CLEAN_MATERIALS= Draw.Create(0) - CLEAN_WHITE_VCOL_LAYERS= Draw.Create(0) - CLEAN_GROUP= Draw.Create(0) - CLEAN_VWEIGHT= Draw.Create(0) - CLEAN_WEIGHT_NORMALIZE= Draw.Create(0) - limit= Draw.Create(0.01) - - CLEAN_NAN_VERTS= Draw.Create(0) - CLEAN_NAN_UVS= Draw.Create(0) - - # Get USER Options - - pup_block= [\ - ('Verts: free', CLEAN_VERTS_FREE, 'Remove verts that are not used by an edge or a face.'),\ - ('Edges: free', CLEAN_EDGE_NOFACE, 'Remove edges that are not in a face.'),\ - ('Edges: short', CLEAN_EDGE_SMALL, 'Remove edges that are below the length limit.'),\ - ('Faces: small perimeter', CLEAN_FACE_PERIMETER, 'Remove faces below the perimeter limit.'),\ - ('Faces: small area', CLEAN_FACE_SMALL, 'Remove faces below the area limit (may remove faces stopping T-face artifacts).'),\ - ('limit: ', limit, 0.001, 1.0, 'Limit for the area and length tests above (a higher limit will remove more data).'),\ - ('Material Clean', CLEAN_MATERIALS, 'Remove unused materials.'),\ - ('Color Layers', CLEAN_WHITE_VCOL_LAYERS, 'Remove vertex color layers that are totaly white'),\ - ('VGroup Clean', CLEAN_GROUP, 'Remove vertex groups that have no verts using them.'),\ - ('Weight Clean', CLEAN_VWEIGHT, 'Remove zero weighted verts from groups (limit is zero threshold).'),\ - ('WeightNormalize', CLEAN_WEIGHT_NORMALIZE, 'Make the sum total of vertex weights accross vgroups 1.0 for each vertex.'),\ - 'Clean NAN values',\ - ('NAN Verts', CLEAN_NAN_VERTS, 'Make NAN or INF verts (0,0,0)'),\ - ('NAN UVs', CLEAN_NAN_UVS, 'Make NAN or INF UVs (0,0)'),\ - '',\ - ('All Mesh Data', CLEAN_ALL_DATA, 'Warning! Operate on ALL mesh objects in your Blend file. Use with care'),\ - ] - - if not Draw.PupBlock('Clean Selected Meshes...', pup_block): - return - - CLEAN_VERTS_FREE= CLEAN_VERTS_FREE.val - CLEAN_EDGE_NOFACE= CLEAN_EDGE_NOFACE.val - CLEAN_EDGE_SMALL= CLEAN_EDGE_SMALL.val - CLEAN_FACE_PERIMETER= CLEAN_FACE_PERIMETER.val - CLEAN_FACE_SMALL= CLEAN_FACE_SMALL.val - CLEAN_MATERIALS= CLEAN_MATERIALS.val - CLEAN_WHITE_VCOL_LAYERS= CLEAN_WHITE_VCOL_LAYERS.val - CLEAN_GROUP= CLEAN_GROUP.val - CLEAN_VWEIGHT= CLEAN_VWEIGHT.val - CLEAN_WEIGHT_NORMALIZE= CLEAN_WEIGHT_NORMALIZE.val - limit= limit.val - CLEAN_ALL_DATA= CLEAN_ALL_DATA.val - CLEAN_NAN_VERTS= CLEAN_NAN_VERTS.val - CLEAN_NAN_UVS= CLEAN_NAN_UVS.val - - if is_editmode: Window.EditMode(0) - - if CLEAN_ALL_DATA: - if CLEAN_GROUP or CLEAN_VWEIGHT or CLEAN_WEIGHT_NORMALIZE: - # For groups we need the objects linked to the mesh - meshes= [ob.getData(mesh=1) for ob in bpy.data.objects if ob.type == 'Mesh' if not ob.lib] - else: - meshes= bpy.data.meshes - else: - meshes= [ob.getData(mesh=1) for ob in obsel if ob.type == 'Mesh'] - - tot_meshes = len(meshes) # so we can decrement libdata - rem_face_count= rem_edge_count= rem_vert_count= rem_material_count= rem_vcol_layer_count= rem_group_count= rem_vweight_count= fix_nan_vcount= fix_nan_uvcount= 0 - if not meshes: - if is_editmode: Window.EditMode(1) - Draw.PupMenu('No meshes to clean') - - Blender.Window.WaitCursor(1) - bpy.data.meshes.tag = False - for me in meshes: - - # Dont touch the same data twice - if me.tag: - tot_meshes -= 1 - continue - me.tag = True - - if me.lib: - tot_meshes -= 1 - continue - - if me.multires: - multires_level_orig = me.multiresDrawLevel - me.multiresDrawLevel = 1 - print 'Warning, cannot perform destructive operations on multires mesh:', me.name - else: - if CLEAN_FACE_SMALL: - rem_face_count += rem_area_faces(me, limit) - - if CLEAN_FACE_PERIMETER: - rem_face_count += rem_perimeter_faces(me, limit) - - if CLEAN_EDGE_SMALL: # for all use 2- remove all edges. - rem_edge_count += rem_free_edges(me, limit) - - if CLEAN_EDGE_NOFACE: - rem_edge_count += rem_free_edges(me) - - if CLEAN_VERTS_FREE: - rem_vert_count += rem_free_verts(me) - - if CLEAN_MATERIALS: - rem_material_count += rem_unused_materials(me) - - if CLEAN_WHITE_VCOL_LAYERS: - rem_vcol_layer_count += rem_white_vcol_layers(me) - - if CLEAN_VWEIGHT or CLEAN_GROUP or CLEAN_WEIGHT_NORMALIZE: - groupNames, vWeightDict= meshWeight2Dict(me) - - if CLEAN_VWEIGHT: - rem_vweight_count += rem_zero_weights(me, limit, groupNames, vWeightDict) - - if CLEAN_GROUP: - rem_group_count += rem_free_groups(me, groupNames, vWeightDict) - pass - - if CLEAN_WEIGHT_NORMALIZE: - normalize_vweight(me, groupNames, vWeightDict) - - # Copy back to mesh vertex groups. - dict2MeshWeight(me, groupNames, vWeightDict) - - if CLEAN_NAN_VERTS: - fix_nan_vcount = fix_nan_verts(me) - - if CLEAN_NAN_UVS: - fix_nan_uvcount = fix_nan_uvs(me) - - # restore multires. - if me.multires: - me.multiresDrawLevel = multires_level_orig - - Blender.Window.WaitCursor(0) - if is_editmode: Window.EditMode(0) - stat_string= 'Removed from ' + str(tot_meshes) + ' Mesh(es)%t|' - - if CLEAN_VERTS_FREE: stat_string+= 'Verts: %i|' % rem_vert_count - if CLEAN_EDGE_SMALL or CLEAN_EDGE_NOFACE: stat_string+= 'Edges: %i|' % rem_edge_count - if CLEAN_FACE_SMALL or CLEAN_FACE_PERIMETER: stat_string+= 'Faces: %i|' % rem_face_count - if CLEAN_MATERIALS: stat_string+= 'Materials: %i|' % rem_material_count - if CLEAN_WHITE_VCOL_LAYERS: stat_string+= 'Color Layers: %i|' % rem_vcol_layer_count - if CLEAN_VWEIGHT: stat_string+= 'VWeights: %i|' % rem_vweight_count - if CLEAN_GROUP: stat_string+= 'VGroups: %i|' % rem_group_count - if CLEAN_NAN_VERTS: stat_string+= 'Vert Nan Fix: %i|' % fix_nan_vcount - if CLEAN_NAN_UVS: stat_string+= 'UV Nan Fix: %i|' % fix_nan_uvcount - Draw.PupMenu(stat_string) - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/release/scripts/mesh_edges2curves.py b/release/scripts/mesh_edges2curves.py deleted file mode 100644 index 670165dda51..00000000000 --- a/release/scripts/mesh_edges2curves.py +++ /dev/null @@ -1,166 +0,0 @@ -#!BPY -""" Registration info for Blender menus: -Name: 'Edges to Curve' -Blender: 241 -Group: 'Mesh' -Tip: 'Edges not used by a face are converted into polyline(s)' -""" -__author__ = ("Campbell Barton") -__url__ = ("blender", "blenderartists.org") -__version__ = "1.0 2006/02/08" - -__bpydoc__ = """\ -Edges to Curves - -This script converts open and closed edge loops into curve polylines - -Supported:
- Polylines where each vert has no more then 2 edges attached to it. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from Blender import * - -def polysFromMesh(me): - # a polyline is 2 - #polylines are a list - polyLines = [] - - # Get edges not used by a face - edgeDict= dict([ (ed.key, ed) for ed in me.edges ]) - for f in me.faces: - for key in f.edge_keys: - try: - del edgeDict[key] - except: - pass - - edges= edgeDict.values() - - - while edges: - currentEdge= edges.pop() - startVert= currentEdge.v2 - endVert= currentEdge.v1 - polyLine= [startVert, endVert] - ok= 1 - while ok: - ok= 0 - #for i, ed in enumerate(edges): - i=len(edges) - while i: - i-=1 - ed= edges[i] - if ed.v1 == endVert: - polyLine.append(ed.v2) - endVert= polyLine[-1] - ok=1 - del edges[i] - #break - elif ed.v2 == endVert: - polyLine.append(ed.v1) - endVert= polyLine[-1] - ok=1 - del edges[i] - #break - elif ed.v1 == startVert: - polyLine.insert(0, ed.v2) - startVert= polyLine[0] - ok=1 - del edges[i] - #break - elif ed.v2 == startVert: - polyLine.insert(0, ed.v1) - startVert= polyLine[0] - ok=1 - del edges[i] - #break - polyLines.append((polyLine, polyLine[0]==polyLine[-1])) - # print len(edges), len(polyLines) - return polyLines - - -def mesh2polys(): - scn= Scene.GetCurrent() - scn.objects.selected = [] - - meshOb= scn.objects.active - if meshOb==None or meshOb.type != 'Mesh': - Draw.PupMenu( 'ERROR: No Active Mesh Selected, Aborting' ) - return - Window.WaitCursor(1) - Window.EditMode(0) - me = meshOb.getData(mesh=1) - polygons= polysFromMesh(me) - w = 1.0 - cu= Curve.New() - cu.name = me.name - cu.setFlag(1) - - ob = scn.objects.active = scn.objects.new(cu) - ob.setMatrix(meshOb.matrixWorld) - - i=0 - for poly, closed in polygons: - if closed: - vIdx= 1 - else: - vIdx= 0 - - v= poly[vIdx] - cu.appendNurb((v.co.x, v.co.y, v.co.z, w)) - vIdx += 1 - cu[i].type= 0 # Poly Line - - # Close the polyline if its closed. - if closed: - cu[i].setFlagU(1) - - # Add all the points in the polyline. - while vIdx 0] - - else: - # Use a small margin verts must be outside before we mirror them. - neg_vts = [v for v in me.verts if v.sel if v.co.x < -PREF_XZERO_THRESH] - pos_vts = [v for v in me.verts if v.sel if v.co.x > PREF_XZERO_THRESH] - - - - #*Mirror Location*********************************************************# - if PREF_MIRROR_LOCATION: - mirror_pairs= [] - # allign the negative with the positive. - flipvec= Mathutils.Vector() - len_neg_vts= float(len(neg_vts)) - for i1, nv in enumerate(neg_vts): - if nv.sel: # we may alredy be mirrored, if so well be deselected - nv_co= nv.co - for i2, pv in enumerate(pos_vts): - if pv.sel: - # Enforce edge users. - if not PREF_EDGE_USERS or edge_users[i1]==edge_users[i2]: - flipvec[:]= pv.co - flipvec.x= -flipvec.x - l= (nv_co-flipvec).length - - if l==0.0: # Both are alredy mirrored so we dont need to think about them. - # De-Select so we dont use again/ - pv.sel= nv.sel= 0 - - # Record a match. - elif l<=PREF_MAX_DIST: - - # We can adjust the length by the normal, now we know the length is under the limit. - # DISABLED, WASNT VERY USEFULL - ''' - if PREF_NOR_WEIGHT>0: - # Get the normal and flipm reuse flipvec - flipvec[:]= pv.no - flipvec.x= -flipvec.x - try: - ang= Mathutils.AngleBetweenVecs(nv.no, flipvec)/180.0 - except: # on rare occasions angle between vecs will fail.- zero length vec. - ang= 0 - - l=l*(1+(ang*PREF_NOR_WEIGHT)) - ''' - # Record the pairs for sorting to see who will get joined - mirror_pairs.append((l, nv, pv)) - - # Update every 20 loops - if i1 % 10 == 0: - Window.DrawProgressBar(0.8 * (i1/len_neg_vts), 'Mirror verts %i of %i' % (i1, len_neg_vts)) - - Window.DrawProgressBar(0.9, 'Mirror verts: Updating locations') - - # Now we have a list of the pairs we might use, lets find the best and do them first. - # de-selecting as we go. so we can makke sure not to mess it up. - try: mirror_pairs.sort(key = lambda a: a[0]) - except: mirror_pairs.sort(lambda a,b: cmp(a[0], b[0])) - - for dist, v1,v2 in mirror_pairs: # dist, neg, pos - if v1.sel and v2.sel: - if PREF_MODE==0: # Middle - flipvec[:]= v2.co # positive - flipvec.x= -flipvec.x # negatve - v2.co= v1.co= (flipvec+v1.co)*0.5 # midway - v2.co.x= -v2.co.x - elif PREF_MODE==2: # Left - v2.co= v1.co - v2.co.x= -v2.co.x - elif PREF_MODE==1: # Right - v1.co= v2.co - v1.co.x= -v1.co.x - v1.sel= v2.sel= 0 - - - #*Mirror Weights**********************************************************# - if PREF_MIRROR_WEIGHTS: - - groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) - mirror_pairs_l2r= [] # Stor a list of matches for these verts. - mirror_pairs_r2l= [] # Stor a list of matches for these verts. - - # allign the negative with the positive. - flipvec= Mathutils.Vector() - len_neg_vts= float(len(neg_vts)) - - # Here we make a tuple to look through, if were middle well need to look through both. - if PREF_MODE==0: # Middle - find_set= ((neg_vts, pos_vts, mirror_pairs_l2r), (pos_vts, neg_vts, mirror_pairs_r2l)) - elif PREF_MODE==1: # Left - find_set= ((neg_vts, pos_vts, mirror_pairs_l2r), ) - elif PREF_MODE==2: # Right - find_set= ((pos_vts, neg_vts, mirror_pairs_r2l), ) - - - # Do a locational lookup again :/ - This isnt that good form but if we havnt mirrored weights well need to do it anyway. - # The Difference with this is that we dont need to have 1:1 match for each vert- just get each vert to find another mirrored vert - # and use its weight. - # Use "find_set" so we can do a flipped search L>R and R>L without duplicate code. - for vtls_A, vtls_B, pair_ls in find_set: - for i1, vA in enumerate(vtls_A): - best_len=1<<30 # BIGNUM - best_idx=-1 - - # Find the BEST match - vA_co= vA.co - for i2, vB in enumerate(vtls_B): - # Enforce edge users. - if not PREF_EDGE_USERS or edge_users[i1]==edge_users[i2]: - flipvec[:]= vB.co - flipvec.x= -flipvec.x - l= (vA_co-flipvec).length - - if l Right', PREF_MODE_L2R, 'Copy from the Left to Right of the mesh. Enable Both for a mid loc/weight.'),\ - ('Right > Left', PREF_MODE_R2L, 'Copy from the Right to Left of the mesh. Enable Both for a mid loc/weight.'),\ - '',\ - ('MaxDist:', PREF_MAX_DIST, 0.0, 1.0, 'Generate interpolated verts so closer vert weights can be copied.'),\ - ('XZero limit:', PREF_XZERO_THRESH, 0.0, 1.0, 'Mirror verts above this distance from the middle, else lock to X/zero.'),\ - ('Sel Verts Only', PREF_SEL_ONLY, 'Only mirror selected verts. Else try and mirror all'),\ - ('Edge Users', PREF_EDGE_USERS, 'Only match up verts that have the same number of edge users.'),\ - 'Location Prefs',\ - ('Mirror Location', PREF_MIRROR_LOCATION, 'Mirror vertex locations.'),\ - ('XMidSnap Verts', PREF_XMID_SNAP, 'Snap middle verts to X Zero (uses XZero limit)'),\ - 'Weight Prefs',\ - ('Mirror Weights', PREF_MIRROR_WEIGHTS, 'Mirror vertex locations.'),\ - ('Flip Groups', PREF_FLIP_NAMES, 'Mirror flip names.'),\ - ('New Flip Groups', PREF_CREATE_FLIP_NAMES, 'Make new groups for flipped names.'),\ - ] - - if not Draw.PupBlock("X Mirror mesh tool", pup_block): - return - - # WORK OUT THE MODE 0 - # PREF_MODE, 0:middle, 1: Left. 2:Right. - PREF_MODE_R2L= PREF_MODE_R2L.val - PREF_MODE_L2R= PREF_MODE_L2R.val - - if PREF_MODE_R2L and PREF_MODE_L2R: - PREF_MODE= 0 # Middle - elif not PREF_MODE_R2L and PREF_MODE_L2R: - PREF_MODE= 1 # Left to Right - elif PREF_MODE_R2L and not PREF_MODE_L2R: - PREF_MODE= 2 # Right to Left - else: # Neither Selected. Do middle anyway - PREF_MODE= 0 - - - PREF_EDITMESH_ONLY= PREF_EDITMESH_ONLY.val - PREF_MIRROR_LOCATION= PREF_MIRROR_LOCATION.val - PREF_XMID_SNAP= PREF_XMID_SNAP.val - PREF_MAX_DIST= PREF_MAX_DIST.val - PREF_XZERO_THRESH= PREF_XZERO_THRESH.val - PREF_SEL_ONLY= PREF_SEL_ONLY.val - PREF_EDGE_USERS= PREF_EDGE_USERS.val - # weights - PREF_MIRROR_WEIGHTS= PREF_MIRROR_WEIGHTS.val - PREF_FLIP_NAMES= PREF_FLIP_NAMES.val - PREF_CREATE_FLIP_NAMES= PREF_CREATE_FLIP_NAMES.val - - t= sys.time() - - is_editmode = Window.EditMode() # Exit Editmode. - if is_editmode: Window.EditMode(0) - Mesh.Mode(Mesh.SelectModes['VERTEX']) - Window.WaitCursor(1) - - if act_ob: - mesh_mirror(act_ob.getData(mesh=1), PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES) - if (not PREF_EDITMESH_ONLY) and sel: - for ob in sel: - mesh_mirror(ob.getData(mesh=1), PREF_MIRROR_LOCATION, PREF_XMID_SNAP, PREF_MAX_DIST, PREF_XZERO_THRESH, PREF_MODE, PREF_SEL_ONLY, PREF_EDGE_USERS, PREF_MIRROR_WEIGHTS, PREF_FLIP_NAMES, PREF_CREATE_FLIP_NAMES) - - if is_editmode: Window.EditMode(1) - Window.WaitCursor(0) - Window.DrawProgressBar(1.0, '') - Window.RedrawAll() - - print 'Mirror done in %.6f sec.' % (sys.time()-t) - -if __name__ == '__main__': - main() diff --git a/release/scripts/mesh_poly_reduce.py b/release/scripts/mesh_poly_reduce.py deleted file mode 100644 index 6dfd7a90efc..00000000000 --- a/release/scripts/mesh_poly_reduce.py +++ /dev/null @@ -1,143 +0,0 @@ -#!BPY -""" -Name: 'Poly Reducer' -Blender: 243 -Group: 'Mesh' -Tooltip: 'Removed polygons from a mesh while maintaining the shape, textures and weights.' -""" - -__author__ = "Campbell Barton" -__url__ = ("blender", "blenderartists.org") -__version__ = "1.0 2006/02/07" - -__bpydoc__ = """\ -This script simplifies the mesh by removing faces, keeping the overall shape of the mesh. -""" - -from Blender import Draw, Window, Scene, Mesh, Mathutils, sys, Object -import BPyMesh -# reload(BPyMesh) -import BPyMessages - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -def main(): - scn = Scene.GetCurrent() - act_ob= scn.objects.active - if not act_ob or act_ob.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - act_me= act_ob.getData(mesh=1) - - if act_me.multires: - BPyMessages.Error_NoMeshMultiresEdit() - return - - act_group= act_me.activeGroup - if not act_group: act_group= '' - - - # Defaults - PREF_REDUX= Draw.Create(0.5) - PREF_BOUNDRY_WEIGHT= Draw.Create(5.0) - PREF_REM_DOUBLES= Draw.Create(1) - PREF_FACE_AREA_WEIGHT= Draw.Create(1.0) - PREF_FACE_TRIANGULATE= Draw.Create(1) - - VGROUP_INF_ENABLE= Draw.Create(0) - VGROUP_INF_REDUX= Draw.Create(act_group) - VGROUP_INF_WEIGHT= Draw.Create(10.0) - - PREF_DO_UV= Draw.Create(1) - PREF_DO_VCOL= Draw.Create(1) - PREF_DO_WEIGHTS= Draw.Create(1) - PREF_OTHER_SEL_OBS= Draw.Create(0) - - pup_block = [\ - ('Poly Reduce:', PREF_REDUX, 0.05, 0.95, 'Scale the meshes poly count by this value.'),\ - ('Boundry Weight:', PREF_BOUNDRY_WEIGHT, 0.0, 20.0, 'Weight boundry verts by this scale, 0.0 for no boundry weighting.'),\ - ('Area Weight:', PREF_FACE_AREA_WEIGHT, 0.0, 20.0, 'Collapse edges effecting lower area faces first.'),\ - ('Triangulate', PREF_FACE_TRIANGULATE, 'Convert quads to tris before reduction, for more choices of edges to collapse.'),\ - '',\ - ('VGroup Weighting', VGROUP_INF_ENABLE, 'Use a vertex group to influence the reduction, higher weights for higher quality '),\ - ('vgroup name: ', VGROUP_INF_REDUX, 0, 32, 'The name of the vertex group to use for the weight map'),\ - ('vgroup mult: ', VGROUP_INF_WEIGHT, 0.0, 100.0, 'How much to make the weight effect the reduction'),\ - ('Other Selected Obs', PREF_OTHER_SEL_OBS, 'reduce other selected objects.'),\ - '',\ - '',\ - '',\ - ('UV Coords', PREF_DO_UV, 'Interpolate UV Coords.'),\ - ('Vert Colors', PREF_DO_VCOL, 'Interpolate Vertex Colors'),\ - ('Vert Weights', PREF_DO_WEIGHTS, 'Interpolate Vertex Weights'),\ - ('Remove Doubles', PREF_REM_DOUBLES, 'Remove doubles before reducing to avoid boundry tearing.'),\ - ] - - if not Draw.PupBlock("Poly Reducer", pup_block): - return - - PREF_REDUX= PREF_REDUX.val - PREF_BOUNDRY_WEIGHT= PREF_BOUNDRY_WEIGHT.val - PREF_REM_DOUBLES= PREF_REM_DOUBLES.val - PREF_FACE_AREA_WEIGHT= PREF_FACE_AREA_WEIGHT.val - PREF_FACE_TRIANGULATE= PREF_FACE_TRIANGULATE.val - - VGROUP_INF_ENABLE= VGROUP_INF_ENABLE.val - VGROUP_INF_WEIGHT= VGROUP_INF_WEIGHT.val - - if VGROUP_INF_ENABLE and VGROUP_INF_WEIGHT: - VGROUP_INF_REDUX= VGROUP_INF_REDUX.val - else: - VGROUP_INF_WEIGHT= 0.0 - VGROUP_INF_REDUX= None - - - PREF_DO_UV= PREF_DO_UV.val - PREF_DO_VCOL= PREF_DO_VCOL.val - PREF_DO_WEIGHTS= PREF_DO_WEIGHTS.val - PREF_OTHER_SEL_OBS= PREF_OTHER_SEL_OBS.val - - - t= sys.time() - - is_editmode = Window.EditMode() # Exit Editmode. - if is_editmode: Window.EditMode(0) - Window.WaitCursor(1) - print 'reducing:', act_ob.name, act_ob.getData(1) - BPyMesh.redux(act_ob, PREF_REDUX, PREF_BOUNDRY_WEIGHT, PREF_REM_DOUBLES, PREF_FACE_AREA_WEIGHT, PREF_FACE_TRIANGULATE, PREF_DO_UV, PREF_DO_VCOL, PREF_DO_WEIGHTS, VGROUP_INF_REDUX, VGROUP_INF_WEIGHT) - - if PREF_OTHER_SEL_OBS: - for ob in scn.objects.context: - if ob.type == 'Mesh' and ob != act_ob: - print 'reducing:', ob.name, ob.getData(1) - BPyMesh.redux(ob, PREF_REDUX, PREF_BOUNDRY_WEIGHT, PREF_REM_DOUBLES, PREF_FACE_AREA_WEIGHT, PREF_FACE_TRIANGULATE, PREF_DO_UV, PREF_DO_VCOL, PREF_DO_WEIGHTS, VGROUP_INF_REDUX, VGROUP_INF_WEIGHT) - Window.RedrawAll() - - if is_editmode: Window.EditMode(1) - Window.WaitCursor(0) - Window.RedrawAll() - - print 'Reduction done in %.6f sec.' % (sys.time()-t) - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/release/scripts/mesh_poly_reduce_grid.py b/release/scripts/mesh_poly_reduce_grid.py deleted file mode 100644 index 2903909027a..00000000000 --- a/release/scripts/mesh_poly_reduce_grid.py +++ /dev/null @@ -1,351 +0,0 @@ -#!BPY -""" -Name: 'Poly Reduce Selection (Unsubsurf)' -Blender: 245 -Group: 'Mesh' -Tooltip: 'predictable mesh simplifaction maintaining face loops' -""" - -from Blender import Scene, Mesh, Window, sys -import BPyMessages -import bpy - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell J Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -def my_mesh_util(me): - me_verts = me.verts - - vert_faces = [ [] for v in me_verts] - vert_faces_corner = [ [] for v in me_verts] - - - # Ignore topology where there are not 2 faces connected to an edge. - edge_count = {} - for f in me.faces: - for edkey in f.edge_keys: - try: - edge_count[edkey] += 1 - except: - edge_count[edkey] = 1 - - for edkey, count in edge_count.iteritems(): - - # Ignore verts that connect to edges with more than 2 faces. - if count != 2: - vert_faces[edkey[0]] = None - vert_faces[edkey[1]] = None - # Done - - - - def faces_set_verts(face_ls): - unique_verts = set() - for f in face_ls: - for v in f: - unique_verts.add(v.index) - return unique_verts - - for f in me.faces: - for corner, v in enumerate(f): - i = v.index - if vert_faces[i] != None: - vert_faces[i].append(f) - vert_faces_corner[i].append( corner ) - - grid_data_ls = [] - - for vi, face_ls in enumerate(vert_faces): - if face_ls != None: - if len(face_ls) == 4: - if face_ls[0].sel and face_ls[1].sel and face_ls[2].sel and face_ls[3].sel: - # Support triangles also - unique_vert_count = len(faces_set_verts(face_ls)) - quads = 0 - for f in face_ls: - if len(f) ==4: - quads += 1 - if unique_vert_count==5+quads: # yay we have a grid - grid_data_ls.append( (vi, face_ls) ) - - elif len(face_ls) == 3: - if face_ls[0].sel and face_ls[1].sel and face_ls[2].sel: - unique_vert_count = len(faces_set_verts(face_ls)) - if unique_vert_count==4: # yay we have 3 triangles to make into a bigger triangle - grid_data_ls.append( (vi, face_ls) ) - - - - # Now sort out which grid faces to use - - - # This list will be used for items we can convert, vertex is key, faces are values - grid_data_dict = {} - - if not grid_data_ls: - print "doing nothing" - return - - # quick lookup for the opposing corner of a qiad - quad_diag_mapping = 2,3,0,1 - - verts_used = [0] * len(me_verts) # 0 == untouched, 1==should touch, 2==touched - verts_used[grid_data_ls[0][0]] = 1 # start touching 1! - - # From the corner vert, get the 2 edges that are not the corner or its opposing vert, this edge will make a new face - quad_edge_mapping = (1,3), (2,0), (1,3), (0,2) # hi-low, low-hi order is intended - tri_edge_mapping = (1,2), (0,2), (0,1) - - done_somthing = True - while done_somthing: - done_somthing = False - grid_data_ls_index = -1 - - for vi, face_ls in grid_data_ls: - grid_data_ls_index += 1 - if len(face_ls) == 3: - grid_data_dict[vi] = face_ls - grid_data_ls.pop( grid_data_ls_index ) - break - elif len(face_ls) == 4: - # print vi - if verts_used[vi] == 1: - verts_used[vi] = 2 # dont look at this again. - done_somthing = True - - grid_data_dict[vi] = face_ls - - # Tag all faces verts as used - - for i, f in enumerate(face_ls): - # i == face index on vert, needed to recall which corner were on. - v_corner = vert_faces_corner[vi][i] - fv =f.v - - if len(f) == 4: - v_other = quad_diag_mapping[v_corner] - # get the 2 other corners - corner1, corner2 = quad_edge_mapping[v_corner] - if verts_used[fv[v_other].index] == 0: - verts_used[fv[v_other].index] = 1 # TAG for touching! - else: - corner1, corner2 = tri_edge_mapping[v_corner] - - verts_used[fv[corner1].index] = 2 # Dont use these, they are - verts_used[fv[corner2].index] = 2 - - - # remove this since we have used it. - grid_data_ls.pop( grid_data_ls_index ) - - break - - if done_somthing == False: - # See if there are any that have not even been tagged, (probably on a different island), then tag them. - - for vi, face_ls in grid_data_ls: - if verts_used[vi] == 0: - verts_used[vi] = 1 - done_somthing = True - break - - - # Now we have all the areas we will fill, calculate corner triangles we need to fill in. - new_faces = [] - quad_del_vt_map = (1,2,3), (0,2,3), (0,1,3), (0,1,2) - for vi, face_ls in grid_data_dict.iteritems(): - for i, f in enumerate(face_ls): - if len(f) == 4: - # i == face index on vert, needed to recall which corner were on. - v_corner = vert_faces_corner[vi][i] - v_other = quad_diag_mapping[v_corner] - fv =f.v - - #print verts_used[fv[v_other].index] - #if verts_used[fv[v_other].index] != 2: # DOSNT WORK ALWAYS - - if 1: # THIS IS LAzY - some of these faces will be removed after adding. - # Ok we are removing half of this face, add the other half - - # This is probably slower - # new_faces.append( [fv[ii].index for ii in (0,1,2,3) if ii != v_corner ] ) - - # do this instead - new_faces.append( (fv[quad_del_vt_map[v_corner][0]], fv[quad_del_vt_map[v_corner][1]], fv[quad_del_vt_map[v_corner][2]]) ) - - del grid_data_ls - - - # me.sel = 0 - def faceCombine4(vi, face_ls): - edges = [] - - for i, f in enumerate(face_ls): - fv = f.v - v_corner = vert_faces_corner[vi][i] - if len(f)==4: ed = quad_edge_mapping[v_corner] - else: ed = tri_edge_mapping[v_corner] - - edges.append( [fv[ed[0]].index, fv[ed[1]].index] ) - - # get the face from the edges - face = edges.pop() - while len(face) != 4: - # print len(edges), edges, face - for ed_idx, ed in enumerate(edges): - if face[-1] == ed[0] and (ed[1] != face[0]): - face.append(ed[1]) - elif face[-1] == ed[1] and (ed[0] != face[0]): - face.append(ed[0]) - else: - continue - - edges.pop(ed_idx) # we used the edge alredy - break - - return face - - for vi, face_ls in grid_data_dict.iteritems(): - if len(face_ls) == 4: - new_faces.append( faceCombine4(vi, face_ls) ) - #pass - if len(face_ls) == 3: # 3 triangles - face = list(faces_set_verts(face_ls)) - face.remove(vi) - new_faces.append( face ) - - - # Now remove verts surounded by 3 triangles - - - - # print new_edges - # me.faces.extend(new_faces, ignoreDups=True) - - ''' - faces_remove = [] - for vi, face_ls in grid_data_dict.iteritems(): - faces_remove.extend(face_ls) - ''' - - orig_facelen = len(me.faces) - - orig_faces = list(me.faces) - me.faces.extend(new_faces, ignoreDups=True) - new_faces = list(me.faces)[len(orig_faces):] - - - - - - if me.faceUV: - uvnames = me.getUVLayerNames() - act_uvlay = me.activeUVLayer - - vert_faces_uvs = [] - vert_faces_images = [] - - - act_uvlay = me.activeUVLayer - - for uvlay in uvnames: - me.activeUVLayer = uvlay - vert_faces_uvs[:] = [None] * len(me.verts) - vert_faces_images[:] = vert_faces_uvs[:] - - for i,f in enumerate(orig_faces): - img = f.image - fv = f.v - uv = f.uv - mat = f.mat - for i,v in enumerate(fv): - vi = v.index - vert_faces_uvs[vi] = uv[i] # no nice averaging - vert_faces_images[vi] = img - - - # Now copy UVs across - for f in new_faces: - fi = [v.index for v in f.v] - f.image = vert_faces_images[fi[0]] - uv = f.uv - for i,vi in enumerate(fi): - uv[i][:] = vert_faces_uvs[vi] - - if len(me.materials) > 1: - vert_faces_mats = [None] * len(me.verts) - for i,f in enumerate(orig_faces): - mat = f.mat - for i,v in enumerate(f.v): - vi = v.index - vert_faces_mats[vi] = mat - - # Now copy UVs across - for f in new_faces: - print vert_faces_mats[f.v[0].index] - f.mat = vert_faces_mats[f.v[0].index] - - - me.verts.delete(grid_data_dict.keys()) - - # me.faces.delete(1, faces_remove) - - if me.faceUV: - me.activeUVLayer = act_uvlay - - me.calcNormals() - -def main(): - - # Gets the current scene, there can be many scenes in 1 blend file. - sce = bpy.data.scenes.active - - # Get the active object, there can only ever be 1 - # and the active object is always the editmode object. - ob_act = sce.objects.active - - if not ob_act or ob_act.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - is_editmode = Window.EditMode() - if is_editmode: Window.EditMode(0) - - Window.WaitCursor(1) - me = ob_act.getData(mesh=1) # old NMesh api is default - t = sys.time() - - # Run the mesh editing function - my_mesh_util(me) - - # Restore editmode if it was enabled - if is_editmode: Window.EditMode(1) - - # Timing the script is a good way to be aware on any speed hits when scripting - print 'My Script finished in %.2f seconds' % (sys.time()-t) - Window.WaitCursor(0) - - -# This lets you can import the script without running it -if __name__ == '__main__': - main() - diff --git a/release/scripts/mesh_skin.py b/release/scripts/mesh_skin.py deleted file mode 100644 index 4a330a516fb..00000000000 --- a/release/scripts/mesh_skin.py +++ /dev/null @@ -1,639 +0,0 @@ -#!BPY - -""" -Name: 'Skin Faces/Edge-Loops' -Blender: 243 -Group: 'MeshFaceKey' -Tooltip: 'Select 2 vert loops, then run this script.' -""" - -__author__ = "Campbell Barton AKA Ideasman" -__url__ = ["blenderartists.org", "www.blender.org"] -__version__ = "1.1 2006/12/26" - -__bpydoc__ = """\ -With this script vertex loops can be skinned: faces are created to connect the -selected loops of vertices. - -Usage: - -In mesh Edit mode select the vertices of the loops (closed paths / curves of -vertices: circles, for example) that should be skinned, then run this script. -A pop-up will provide further options, if the results of a method are not adequate try one of the others. -""" - - -# $Id$ -# -# -------------------------------------------------------------------------- -# Skin Selected edges 1.0 By Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -# Made by Ideasman/Campbell 2005/06/15 - cbarton@metavr.com - -import Blender -import bpy -from Blender import Window -from Blender.Mathutils import MidpointVecs, Vector -from Blender.Mathutils import AngleBetweenVecs as _AngleBetweenVecs_ -import BPyMessages - -from Blender.Draw import PupMenu - -BIG_NUM = 1<<30 - -global CULL_METHOD -CULL_METHOD = 0 - -def AngleBetweenVecs(a1,a2): - try: - return _AngleBetweenVecs_(a1,a2) - except: - return 180.0 - -class edge(object): - __slots__ = 'v1', 'v2', 'co1', 'co2', 'length', 'removed', 'match', 'cent', 'angle', 'next', 'prev', 'normal', 'fake' - def __init__(self, v1,v2): - self.v1 = v1 - self.v2 = v2 - co1, co2= v1.co, v2.co - self.co1= co1 - self.co2= co2 - - # uv1 uv2 vcol1 vcol2 # Add later - self.length = (co1 - co2).length - self.removed = 0 # Have we been culled from the eloop - self.match = None # The other edge were making a face with - - self.cent= MidpointVecs(co1, co2) - self.angle= 0.0 - self.fake= False - -class edgeLoop(object): - __slots__ = 'centre', 'edges', 'normal', 'closed', 'backup_edges' - def __init__(self, loop, me, closed): # Vert loop - # Use next and prev, nextDist, prevDist - - # Get Loops centre. - fac= len(loop) - verts = me.verts - self.centre= reduce(lambda a,b: a+verts[b].co/fac, loop, Vector()) - - # Convert Vert loop to Edges. - self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in xrange(len(loop))] - - if not closed: - self.edges[0].fake = True # fake edge option - - self.closed = closed - - - # Assign linked list - for eIdx in xrange(len(self.edges)-1): - self.edges[eIdx].next = self.edges[eIdx+1] - self.edges[eIdx].prev = self.edges[eIdx-1] - # Now last - self.edges[-1].next = self.edges[0] - self.edges[-1].prev = self.edges[-2] - - - - # GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP. - self.normal = Vector() - for e in self.edges: - n = (self.centre-e.co1).cross(self.centre-e.co2) - # Do we realy need tot normalize? - n.normalize() - self.normal += n - - # Generate the angle - va= e.cent - e.prev.cent - vb= e.next.cent - e.cent - - e.angle= AngleBetweenVecs(va, vb) - - # Blur the angles - #for e in self.edges: - # e.angle= (e.angle+e.next.angle)/2 - - # Blur the angles - #for e in self.edges: - # e.angle= (e.angle+e.prev.angle)/2 - - self.normal.normalize() - - # Generate a normal for each edge. - for e in self.edges: - - n1 = e.co1 - n2 = e.co2 - n3 = e.prev.co1 - - a = n1-n2 - b = n1-n3 - normal1 = a.cross(b) - normal1.normalize() - - n1 = e.co2 - n3 = e.next.co2 - n2 = e.co1 - - a = n1-n2 - b = n1-n3 - - normal2 = a.cross(b) - normal2.normalize() - - # Reuse normal1 var - normal1 += normal1 + normal2 - normal1.normalize() - - e.normal = normal1 - #print e.normal - - - - def backup(self): - # Keep a backup of the edges - self.backup_edges = self.edges[:] - - def restore(self): - self.edges = self.backup_edges[:] - for e in self.edges: - e.removed = 0 - - def reverse(self): - self.edges.reverse() - self.normal.negate() - - for e in self.edges: - e.normal.negate() - e.v1, e.v2 = e.v2, e.v1 - e.co1, e.co2 = e.co2, e.co1 - e.next, e.prev = e.prev, e.next - - - def removeSmallest(self, cullNum, otherLoopLen): - ''' - Removes N Smallest edges and backs up the loop, - this is so we can loop between 2 loops as if they are the same length, - backing up and restoring incase the loop needs to be skinned with another loop of a different length. - ''' - global CULL_METHOD - if CULL_METHOD == 1: # Shortest edge - eloopCopy = self.edges[:] - - # Length sort, smallest first - try: eloopCopy.sort(key = lambda e1: e1.length) - except: eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length )) - - # Dont use atm - #eloopCopy.sort(lambda e1, e2: cmp(e1.angle*e1.length, e2.angle*e2.length)) # Length sort, smallest first - #eloopCopy.sort(lambda e1, e2: cmp(e1.angle, e2.angle)) # Length sort, smallest first - - remNum = 0 - for i, e in enumerate(eloopCopy): - if not e.fake: - e.removed = 1 - self.edges.remove( e ) # Remove from own list, still in linked list. - remNum += 1 - - if not remNum < cullNum: - break - - else: # CULL METHOD is even - - culled = 0 - - step = int(otherLoopLen / float(cullNum)) * 2 - - currentEdge = self.edges[0] - while culled < cullNum: - - # Get the shortest face in the next STEP - step_count= 0 - bestAng= 360.0 - smallestEdge= None - while step_count<=step or smallestEdge==None: - step_count+=1 - if not currentEdge.removed: # 0 or -1 will not be accepted - if currentEdge.angle 2: - return None - - vert_used[i] = True - - # do an edgeloop seek - if len(sbl) == 2: - contextVertLoop= [sbl[0], i, sbl[1]] # start the vert loop - vert_used[contextVertLoop[ 0]] = True - vert_used[contextVertLoop[-1]] = True - else: - contextVertLoop= [i, sbl[0]] - vert_used[contextVertLoop[ 1]] = True - - # Always seek up - ok = True - while ok: - ok = False - closed = False - sbl = vert_siblings[contextVertLoop[-1]] - if len(sbl) == 2: - next = sbl[not sbl.index( contextVertLoop[-2] )] - if vert_used[next]: - closed = True - # break - else: - contextVertLoop.append( next ) # get the vert that isnt the second last - vert_used[next] = True - ok = True - - # Seek down as long as the starting vert was not at the edge. - if not closed and len(vert_siblings[i]) == 2: - - ok = True - while ok: - ok = False - sbl = vert_siblings[contextVertLoop[0]] - if len(sbl) == 2: - next = sbl[not sbl.index( contextVertLoop[1] )] - if vert_used[next]: - closed = True - else: - contextVertLoop.insert(0, next) # get the vert that isnt the second last - vert_used[next] = True - ok = True - - mainVertLoops.append((contextVertLoop, closed)) - - - verts = me.verts - # convert from indicies to verts - # mainVertLoops = [([verts[i] for i in contextVertLoop], closed) for contextVertLoop, closed in mainVertLoops] - # print len(mainVertLoops) - return mainVertLoops - - - -def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE): - - new_faces= [] # - - # Make sure e1 loops is bigger then e2 - if len(eloop1.edges) != len(eloop2.edges): - if len(eloop1.edges) < len(eloop2.edges): - eloop1, eloop2 = eloop2, eloop1 - - eloop1.backup() # were about to cull faces - CULL_FACES = len(eloop1.edges) - len(eloop2.edges) - eloop1.removeSmallest(CULL_FACES, len(eloop1.edges)) - else: - CULL_FACES = 0 - # First make sure poly vert loops are in sync with eachother. - - # The vector allong which we are skinning. - skinVector = eloop1.centre - eloop2.centre - - loopDist = skinVector.length - - # IS THE LOOP FLIPPED, IF SO FLIP BACK. we keep it flipped, its ok, - if eloop1.closed or eloop2.closed: - angleBetweenLoopNormals = AngleBetweenVecs(eloop1.normal, eloop2.normal) - if angleBetweenLoopNormals > 90: - eloop2.reverse() - - - DIR= eloop1.centre - eloop2.centre - - # if eloop2.closed: - bestEloopDist = BIG_NUM - bestOffset = 0 - # Loop rotation offset to test.1 - eLoopIdxs = range(len(eloop1.edges)) - for offset in xrange(len(eloop1.edges)): - totEloopDist = 0 # Measure this total distance for thsi loop. - - offsetIndexLs = eLoopIdxs[offset:] + eLoopIdxs[:offset] # Make offset index list - - - # e1Idx is always from 0uu to N, e2Idx is offset. - for e1Idx, e2Idx in enumerate(offsetIndexLs): - e1= eloop1.edges[e1Idx] - e2= eloop2.edges[e2Idx] - - - # Include fan connections in the measurement. - OK= True - while OK or e1.removed: - OK= False - - # Measure the vloop distance =============== - diff= ((e1.cent - e2.cent).length) #/ nangle1 - - ed_dir= e1.cent-e2.cent - a_diff= AngleBetweenVecs(DIR, ed_dir)/18 # 0 t0 18 - - totEloopDist += (diff * (1+a_diff)) / (1+loopDist) - - # Premeture break if where no better off - if totEloopDist > bestEloopDist: - break - - e1=e1.next - - if totEloopDist < bestEloopDist: - bestOffset = offset - bestEloopDist = totEloopDist - - # Modify V2 LS for Best offset - eloop2.edges = eloop2.edges[bestOffset:] + eloop2.edges[:bestOffset] - - else: - # Both are open loops, easier to calculate. - - - # Make sure the fake edges are at the start. - for i, edloop in enumerate((eloop1, eloop2)): - # print "LOOPO" - if edloop.edges[0].fake: - # alredy at the start - #print "A" - pass - elif edloop.edges[-1].fake: - # put the end at the start - edloop.edges.insert(0, edloop.edges.pop()) - #print "B" - - else: - for j, ed in enumerate(edloop.edges): - if ed.fake: - #print "C" - edloop.edges = edloop.edges = edloop.edges[j:] + edloop.edges[:j] - break - # print "DONE" - ed1, ed2 = eloop1.edges[0], eloop2.edges[0] - - if not ed1.fake or not ed2.fake: - raise "Error" - - # Find the join that isnt flipped (juts like detecting a bow-tie face) - a1 = (ed1.co1 - ed2.co1).length + (ed1.co2 - ed2.co2).length - a2 = (ed1.co1 - ed2.co2).length + (ed1.co2 - ed2.co1).length - - if a1 > a2: - eloop2.reverse() - # make the first edge the start edge still - eloop2.edges.insert(0, eloop2.edges.pop()) - - - - - for loopIdx in xrange(len(eloop2.edges)): - e1 = eloop1.edges[loopIdx] - e2 = eloop2.edges[loopIdx] - - # Remember the pairs for fan filling culled edges. - e1.match = e2; e2.match = e1 - - if not (e1.fake or e2.fake): - new_faces.append([e1.v1, e1.v2, e2.v2, e2.v1]) - - # FAN FILL MISSING FACES. - if CULL_FACES: - # Culled edges will be in eloop1. - FAN_FILLED_FACES = 0 - - contextEdge = eloop1.edges[0] # The larger of teh 2 - while FAN_FILLED_FACES < CULL_FACES: - while contextEdge.next.removed == 0: - contextEdge = contextEdge.next - - vertFanPivot = contextEdge.match.v2 - - while contextEdge.next.removed == 1: - #if not contextEdge.next.fake: - new_faces.append([contextEdge.next.v1, contextEdge.next.v2, vertFanPivot]) - - # Should we use another var?, this will work for now. - contextEdge.next.removed = 1 - - contextEdge = contextEdge.next - FAN_FILLED_FACES += 1 - - # may need to fan fill backwards 1 for non closed loops. - - eloop1.restore() # Add culled back into the list. - - return new_faces - -def main(): - global CULL_METHOD - - is_editmode = Window.EditMode() - if is_editmode: Window.EditMode(0) - ob = bpy.data.scenes.active.objects.active - if ob == None or ob.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - me = ob.getData(mesh=1) - - if me.multires: - BPyMessages.Error_NoMeshMultiresEdit() - return - - time1 = Blender.sys.time() - selEdges = getSelectedEdges(me, ob) - vertLoops = getVertLoops(selEdges, me) # list of lists of edges. - if vertLoops == None: - PupMenu('Error%t|Selection includes verts that are a part of more then 1 loop') - if is_editmode: Window.EditMode(1) - return - # print len(vertLoops) - - - if len(vertLoops) > 2: - choice = PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment') - if choice == -1: - if is_editmode: Window.EditMode(1) - return - elif len(vertLoops) < 2: - PupMenu('Error%t|No Vertloops found!') - if is_editmode: Window.EditMode(1) - return - else: - choice = 2 - - - # The line below checks if any of the vert loops are differenyt in length. - if False in [len(v[0]) == len(vertLoops[0][0]) for v in vertLoops]: - CULL_METHOD = PupMenu('Small to large edge loop distrobution method%t|remove edges evenly|remove smallest edges') - if CULL_METHOD == -1: - if is_editmode: Window.EditMode(1) - return - - if CULL_METHOD ==1: # RESET CULL_METHOD - CULL_METHOD = 0 # shortest - else: - CULL_METHOD = 1 # even - - - time1 = Blender.sys.time() - # Convert to special edge data. - edgeLoops = [] - for vloop, closed in vertLoops: - edgeLoops.append(edgeLoop(vloop, me, closed)) - - - # VERT LOOP ORDERING CODE - # "Build a worm" list - grow from Both ends - edgeOrderedList = [edgeLoops.pop()] - - # Find the closest. - bestSoFar = BIG_NUM - bestIdxSoFar = None - for edLoopIdx, edLoop in enumerate(edgeLoops): - l =(edgeOrderedList[-1].centre - edLoop.centre).length - if l < bestSoFar: - bestIdxSoFar = edLoopIdx - bestSoFar = l - - edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) ) - - # Now we have the 2 closest, append to either end- - # Find the closest. - while edgeLoops: - bestSoFar = BIG_NUM - bestIdxSoFar = None - first_or_last = 0 # Zero is first - for edLoopIdx, edLoop in enumerate(edgeLoops): - l1 =(edgeOrderedList[-1].centre - edLoop.centre).length - - if l1 < bestSoFar: - bestIdxSoFar = edLoopIdx - bestSoFar = l1 - first_or_last = 1 # last - - l2 =(edgeOrderedList[0].centre - edLoop.centre).length - if l2 < bestSoFar: - bestIdxSoFar = edLoopIdx - bestSoFar = l2 - first_or_last = 0 # last - - if first_or_last: # add closest Last - edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) ) - else: # Add closest First - edgeOrderedList.insert(0, edgeLoops.pop(bestIdxSoFar) ) # First - - faces = [] - - for i in xrange(len(edgeOrderedList)-1): - faces.extend( skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0) ) - if choice == 1 and len(edgeOrderedList) > 2: # Loop - faces.extend( skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) ) - - # REMOVE SELECTED FACES. - MESH_MODE= Blender.Mesh.Mode() - if MESH_MODE & Blender.Mesh.SelectModes.EDGE or MESH_MODE & Blender.Mesh.SelectModes.VERTEX: pass - elif MESH_MODE & Blender.Mesh.SelectModes.FACE: - try: me.faces.delete(1, [ f for f in me.faces if f.sel ]) - except: pass - - me.faces.extend(faces, smooth = True) - - print '\nSkin done in %.4f sec.' % (Blender.sys.time()-time1) - - - if is_editmode: Window.EditMode(1) - -if __name__ == '__main__': - main() diff --git a/release/scripts/mesh_solidify.py b/release/scripts/mesh_solidify.py deleted file mode 100644 index 9e11ed68c63..00000000000 --- a/release/scripts/mesh_solidify.py +++ /dev/null @@ -1,345 +0,0 @@ -#!BPY -""" -Name: 'Solidify Selection' -Blender: 243 -Group: 'Mesh' -Tooltip: 'Makes the mesh solid by creating a second skin.' -""" - -__author__ = "Campbell Barton" -__url__ = ("www.blender.org", "blenderartists.org") -__version__ = "1.1" - -__bpydoc__ = """\ -This script makes a skin from the selected faces. -Optionaly you can skin between the original and new faces to make a watertight solid object -""" - -# -------------------------------------------------------------------------- -# Solidify Selection 1.0 by Campbell Barton (AKA Ideasman42) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -from Blender import * -import bpy -import BPyMesh -# reload(BPyMesh) -import BPyMessages -# reload(BPyMessages) - -from BPyMathutils import angleToLength - -# python 2.3 has no reversed() iterator. this will only work on lists and tuples -try: - reversed -except: - def reversed(l): return l[::-1] - -def copy_facedata_multilayer(me, from_faces, to_faces): - ''' - Tkes 2 lists of faces and copies multilayer data from 1 to another - make sure they are aligned, cant copy from a quad to a tri, used for solidify selection. - ''' - - def copy_default_face(data): - face_from, face_to = data - face_to.mat = face_from.mat - face_to.smooth = face_from.smooth - face_to.sel = True - face_from.sel = False - - def copy_tex_face(data): - face_from, face_to = data - face_to.uv = [c for c in reversed(face_from.uv)] - face_to.mode = face_from.mode - face_to.flag = face_from.flag - face_to.image = face_from.image - - def copy_col_face(data): - face_from, face_to = data - face_to.col = [c for c in reversed(face_from.col)] - - # make a list of face_from, face_to pairs - #face_pairs = zip(faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))]) - face_pairs = zip(from_faces, to_faces) - - # Copy properties from 1 set of faces to another. - map(copy_default_face, face_pairs) - - for uvlayer in me.getUVLayerNames(): - me.activeUVLayer = uvlayer - map(copy_tex_face, face_pairs) - - for collayer in me.getColorLayerNames(): - me.activeColorLayer = collayer - map(copy_col_face, face_pairs) - - # Now add quads between if we wants - - -Ang= Mathutils.AngleBetweenVecs -SMALL_NUM=0.00001 - -def solidify(me, PREF_THICK, PREF_SKIN_SIDES=True, PREF_REM_ORIG=False, PREF_COLLAPSE_SIDES=False): - - # Main code function - me_faces = me.faces - faces_sel= [f for f in me_faces if f.sel] - - BPyMesh.meshCalcNormals(me) - normals= [v.no for v in me.verts] - vertFaces= [[] for i in xrange(len(me.verts))] - for f in me_faces: - no=f.no - for v in f: - vertFaces[v.index].append(no) - - # Scale the normals by the face angles from the vertex Normals. - for i in xrange(len(me.verts)): - length=0.0 - if vertFaces[i]: - for fno in vertFaces[i]: - try: - a= Ang(fno, normals[i]) - except: - a= 0 - if a>=90: - length+=1 - elif a < SMALL_NUM: - length+= 1 - else: - length+= angleToLength(a) - - length= length/len(vertFaces[i]) - #print 'LENGTH %.6f' % length - # normals[i]= (normals[i] * length) * PREF_THICK - normals[i] *= length * PREF_THICK - - - - len_verts = len( me.verts ) - len_faces = len( me_faces ) - - vert_mapping= [-1] * len(me.verts) - verts= [] - for f in faces_sel: - for v in f: - i= v.index - if vert_mapping[i]==-1: - vert_mapping[i]= len_verts + len(verts) - verts.append(v.co + normals[i]) - - #verts= [v.co + normals[v.index] for v in me.verts] - - me.verts.extend( verts ) - #faces= [tuple([ me.verts[v.index+len_verts] for v in reversed(f.v)]) for f in me_faces ] - faces= [ tuple([vert_mapping[v.index] for v in reversed(f.v)]) for f in faces_sel ] - me_faces.extend( faces ) - - - - - # Old method before multi UVs - """ - has_uv = me.faceUV - has_vcol = me.vertexColors - for i, orig_f in enumerate(faces_sel): - new_f= me_faces[len_faces + i] - new_f.mat = orig_f.mat - new_f.smooth = orig_f.smooth - orig_f.sel=False - new_f.sel= True - new_f = me_faces[i+len_faces] - if has_uv: - new_f.uv = [c for c in reversed(orig_f.uv)] - new_f.mode = orig_f.mode - new_f.flag = orig_f.flag - if orig_f.image: - new_f.image = orig_f.image - if has_vcol: - new_f.col = [c for c in reversed(orig_f.col)] - """ - copy_facedata_multilayer(me, faces_sel, [me_faces[len_faces + i] for i in xrange(len(faces_sel))]) - - if PREF_SKIN_SIDES or PREF_COLLAPSE_SIDES: - skin_side_faces= [] - skin_side_faces_orig= [] - # Get edges of faces that only have 1 user - so we can make walls - edges = {} - - # So we can reference indicies that wrap back to the start. - ROT_TRI_INDEX = 0,1,2,0 - ROT_QUAD_INDEX = 0,1,2,3,0 - - for f in faces_sel: - f_v= f.v - for i, edgekey in enumerate(f.edge_keys): - if edges.has_key(edgekey): - edges[edgekey]= None - else: - if len(f_v) == 3: - edges[edgekey] = f, f_v, i, ROT_TRI_INDEX[i+1] - else: - edges[edgekey] = f, f_v, i, ROT_QUAD_INDEX[i+1] - del ROT_QUAD_INDEX, ROT_TRI_INDEX - - # So we can remove doubles with edges only. - if PREF_COLLAPSE_SIDES: - me.sel = False - - # Edges are done. extrude the single user edges. - for edge_face_data in edges.itervalues(): - if edge_face_data: # != None - f, f_v, i1, i2 = edge_face_data - v1i,v2i= f_v[i1].index, f_v[i2].index - - if PREF_COLLAPSE_SIDES: - # Collapse - cv1 = me.verts[v1i] - cv2 = me.verts[vert_mapping[v1i]] - - cv3 = me.verts[v2i] - cv4 = me.verts[vert_mapping[v2i]] - - cv1.co = cv2.co = (cv1.co+cv2.co)/2 - cv3.co = cv4.co = (cv3.co+cv4.co)/2 - - cv1.sel=cv2.sel=cv3.sel=cv4.sel=True - - - - else: - # Now make a new Face - # skin_side_faces.append( (v1i, v2i, vert_mapping[v2i], vert_mapping[v1i]) ) - skin_side_faces.append( (v2i, v1i, vert_mapping[v1i], vert_mapping[v2i]) ) - skin_side_faces_orig.append((f, len(me_faces) + len(skin_side_faces_orig), i1, i2)) - - if PREF_COLLAPSE_SIDES: - me.remDoubles(0.0001) - else: - me_faces.extend(skin_side_faces) - # Now assign properties. - """ - # Before MultiUVs - for i, origfData in enumerate(skin_side_faces_orig): - orig_f, new_f_idx, i1, i2 = origfData - new_f= me_faces[new_f_idx] - - new_f.mat= orig_f.mat - new_f.smooth= orig_f.smooth - if has_uv: - new_f.mode= orig_f.mode - new_f.flag= orig_f.flag - if orig_f.image: - new_f.image= orig_f.image - - uv1= orig_f.uv[i1] - uv2= orig_f.uv[i2] - new_f.uv= (uv1, uv2, uv2, uv1) - - if has_vcol: - col1= orig_f.col[i1] - col2= orig_f.col[i2] - new_f.col= (col1, col2, col2, col1) - """ - - for i, origfData in enumerate(skin_side_faces_orig): - orig_f, new_f_idx, i2, i1 = origfData - new_f= me_faces[new_f_idx] - - new_f.mat= orig_f.mat - new_f.smooth= orig_f.smooth - - for uvlayer in me.getUVLayerNames(): - me.activeUVLayer = uvlayer - for i, origfData in enumerate(skin_side_faces_orig): - orig_f, new_f_idx, i2, i1 = origfData - new_f= me_faces[new_f_idx] - - new_f.mode= orig_f.mode - new_f.flag= orig_f.flag - new_f.image= orig_f.image - - uv1= orig_f.uv[i1] - uv2= orig_f.uv[i2] - new_f.uv= (uv1, uv2, uv2, uv1) - - for collayer in me.getColorLayerNames(): - me.activeColorLayer = collayer - for i, origfData in enumerate(skin_side_faces_orig): - orig_f, new_f_idx, i2, i1 = origfData - new_f= me_faces[new_f_idx] - - col1= orig_f.col[i1] - col2= orig_f.col[i2] - new_f.col= (col1, col2, col2, col1) - - - if PREF_REM_ORIG: - me_faces.delete(0, faces_sel) - - - - -def main(): - scn = bpy.data.scenes.active - ob = scn.objects.active - - if not ob or ob.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - me = ob.getData(mesh=1) - if me.multires: - BPyMessages.Error_NoMeshMultiresEdit() - return - - # Create the variables. - PREF_THICK = Draw.Create(-0.1) - PREF_SKIN_SIDES= Draw.Create(1) - PREF_COLLAPSE_SIDES= Draw.Create(0) - PREF_REM_ORIG= Draw.Create(0) - - pup_block = [\ - ('Thick:', PREF_THICK, -10, 10, 'Skin thickness in mesh space.'),\ - ('Skin Sides', PREF_SKIN_SIDES, 'Skin between the original and new faces.'),\ - ('Collapse Sides', PREF_COLLAPSE_SIDES, 'Skin between the original and new faces.'),\ - ('Remove Original', PREF_REM_ORIG, 'Remove the selected faces after skinning.'),\ - ] - - if not Draw.PupBlock('Solid Skin Selection', pup_block): - return - - is_editmode = Window.EditMode() - if is_editmode: Window.EditMode(0) - - Window.WaitCursor(1) - - me = ob.getData(mesh=1) - solidify(me, PREF_THICK.val, PREF_SKIN_SIDES.val, PREF_REM_ORIG.val, PREF_COLLAPSE_SIDES.val) - - - Window.WaitCursor(0) - if is_editmode: Window.EditMode(1) - - Window.RedrawAll() - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/release/scripts/mesh_unfolder.py b/release/scripts/mesh_unfolder.py deleted file mode 100644 index f5c19a92bd0..00000000000 --- a/release/scripts/mesh_unfolder.py +++ /dev/null @@ -1,1582 +0,0 @@ -#!BPY -""" -Name: 'Unfold' -Blender: 245 -Group: 'Mesh' -Tip: 'Unfold meshes to create nets' -Version: v2.5 -Author: Matthew Chadwick -""" -import Blender -from Blender import * -from Blender.Mathutils import * -try: - import sys - import traceback - import math - import re - from math import * - import sys - import random - import xml.sax, xml.sax.handler, xml.sax.saxutils - - # annoying but need so classes dont raise errors - xml_sax_handler_ContentHandler = xml.sax.handler.ContentHandler - -except: - Draw.PupMenu('Error%t|A full python installation is required to run this script.') - xml = None - xml_sax_handler_ContentHandler = type(0) - -__author__ = 'Matthew Chadwick' -__version__ = '2.5 06102007' -__url__ = ["http://celeriac.net/unfolder/", "blender", "blenderartist"] -__email__ = ["post at cele[remove this text]riac.net", "scripts"] -__bpydoc__ = """\ - -Mesh Unfolder - -Unfolds the selected mesh onto a plane to form a net - -Not all meshes can be unfolded - -Meshes must be free of holes, -isolated edges (not part of a face), twisted quads and other rubbish. -Nice clean triangulated meshes unfold best - -This program is free software; you can distribute it and/or modify it under the terms -of the GNU General Public License as published by the Free Software Foundation; version 2 -or later, currently at http://www.gnu.org/copyleft/gpl.html - -The idea came while I was riding a bike. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - -# Face lookup -class FacesAndEdges: - def __init__(self, mesh): - self.nfaces = 0 - # straight from the documentation - self.edgeFaces = dict([(edge.key, []) for edge in mesh.edges]) - for face in mesh.faces: - face.sel = False - for key in face.edge_keys: - self.edgeFaces[key].append(face) - def findTakenAdjacentFace(self, bface, edge): - return self.findAdjacentFace(bface, edge) - # find the first untaken (non-selected) adjacent face in the list of adjacent faces for the given edge (allows for manifold meshes too) - def findAdjacentFace(self, bface, edge): - faces = self.edgeFaces[edge.key()] - for i in xrange(len(faces)): - if faces[i] == bface: - j = (i+1) % len(faces) - while(faces[j]!=bface): - if faces[j].sel == False: - return faces[j] - j = (j+1) % len(faces) - return None - def returnFace(self, face): - face.sel = False - self.nfaces-=1 - def facesTaken(self): - return self.nfaces - def takeAdjacentFace(self, bface, edge): - if (edge==None): - return None - face = self.findAdjacentFace(bface, edge) - if(face!=None): - face.sel = True - self.nfaces+=1 - return face - def takeFace(self, bface): - if(bface!=None): - bface.sel= True - self.nfaces+=1 - - -# A fold between two faces with a common edge -class Fold: - ids = -1 - def __init__(self, parent, refPoly, poly, edge, angle=None): - Fold.ids+=1 - self.id = Fold.ids - self.refPoly = refPoly - self.poly = poly - self.srcFace = None - self.desFace = None - self.edge = edge - self.foldedEdge = edge - self.rm = None - self.parent = parent - self.tree = None - if(refPoly!=None): - self.refPolyNormal = refPoly.normal() - self.polyNormal = poly.normal() - if(angle==None): - self.angle = self.calculateAngle() - self.foldingPoly = poly.rotated(edge, self.angle) - else: - self.angle = angle - self.foldingPoly = poly - self.unfoldedEdge = self.edge - self.unfoldedNormal = None - self.animAngle = self.angle - self.cr = None - self.nancestors = None - def reset(self): - self.foldingPoly = self.poly.rotated(self.edge, self.dihedralAngle()) - def getID(self): - return self.id - def getParent(self): - return self.parent - def ancestors(self): - if(self.nancestors==None): - self.nancestors = self.computeAncestors() - return self.nancestors - def computeAncestors(self): - if(self.parent==None): - return 0 - else: - return self.parent.ancestors()+1 - def dihedralAngle(self): - return self.angle - def unfoldTo(self, f): - self.animAngle = self.angle*f - self.foldingPoly = self.poly.rotated(self.edge, self.animAngle) - def calculateAngle(self): - sangle = Mathutils.AngleBetweenVecs(self.refPolyNormal, self.polyNormal) - if(sangle!=sangle): - sangle=0.0 - ncp = self.refPolyNormal.cross(self.polyNormal) - dp = ncp.dot(self.edge.vector) - if(dp>0.0): - return +sangle - else: - return -sangle - def alignWithParent(self): - pass - def unfoldedNormal(self): - return self.unfoldedNormal - def getEdge(self): - return self.edge - def getFace(self): - return self.poly - def testFace(self): - return Poly.fromVectors([self.edge.v1, self.edge.v2, Vector([0,0,0])]) - def unfoldedFace(self): - return self.foldingPoly - def unfold(self): - if(self.parent!=None): - self.parent.foldFace(self) - def foldFace(self, child): - child.foldingPoly.rotate(self.edge, self.animAngle) - if(self.parent!=None): - self.parent.foldFace(child) - -class Cut(Fold): - pass - -# Trees build folds by traversing the mesh according to a local measure -class Tree: - def __init__(self, net, parent,fold,otherConstructor=None): - self.net = net - self.fold = fold - self.face = fold.srcFace - self.poly = Poly.fromBlenderFace(self.face) - self.generations = net.generations - self.growing = True - self.tooLong = False - self.parent = parent - self.grown = False - if not(otherConstructor): - self.edges = net.edgeIteratorClass(self) - def goodness(self): - return self.edges.goodness() - def compare(self, other): - if(self.goodness() > other.goodness()): - return +1 - else: - return -1 - def isGrowing(self): - return self.growing - def beGrowing(self): - self.growing = True - def grow(self): - self.tooLong = self.fold.ancestors()>self.generations - if(self.edges.hasNext() and self.growing): - edge = self.edges.next() - tface = self.net.facesAndEdges.takeAdjacentFace(self.face, edge) - if(tface!=None): - self.branch(tface, edge) - if(self.parent==None): - self.grow() - else: - self.grown = True - def isGrown(self): - return self.grown - def canGrow(self): - return (self.parent!=None and self.parent.grown) - def getNet(self): - return self.net - def getFold(self): - return self.fold - def getFace(self): - return self.face - def branch(self, tface, edge): - fold = Fold(self.fold, self.poly, Poly.fromBlenderFace(tface), edge) - fold.srcFace = tface - self.net.myFacesVisited+=1 - tree = Tree(self.net, self, fold) - fold.tree = tree - fold.unfold() - overlaps = self.net.checkOverlaps(fold) - nc = len(overlaps) - self.net.overlaps+=nc - if(nc>0 and self.net.avoidsOverlaps): - self.handleOverlap(fold, overlaps) - else: - self.addFace(fold) - def handleOverlap(self, fold, overlaps): - self.net.facesAndEdges.returnFace(fold.srcFace) - self.net.myFacesVisited-=1 - for cfold in overlaps: - ttree = cfold.tree - ttree.growing = True - ttree.grow() - def addFace(self, fold): - ff = fold.unfoldedFace() - fold.desFace = self.net.addFace(ff, fold.srcFace) - self.net.folds.append(fold) - self.net.addBranch(fold.tree) - fold.tree.growing = not(self.tooLong) - if(self.net.diffuse==False): - fold.tree.grow() - -# A Net is the result of the traversal of the mesh by Trees -class Net: - def __init__(self, src, des): - self.src = src - self.des = des - self.firstFace = None - self.firstPoly = None - self.refFold = None - self.edgeIteratorClass = RandomEdgeIterator - if(src!=None): - self.srcFaces = src.faces - self.facesAndEdges = FacesAndEdges(self.src) - self.myFacesVisited = 0 - self.facesAdded = 0 - self.folds = [] - self.cuts = [] - self.branches = [] - self.overlaps = 0 - self.avoidsOverlaps = True - self.frame = 1 - self.ff = 180.0 - self.firstFaceIndex = None - self.trees = 0 - self.foldIPO = None - self.perFoldIPO = None - self.IPOCurves = {} - self.generations = 128 - self.diffuse = True - self.noise = 0.0 - self.grownBranches = 0 - self.assignsUV = True - self.animates = False - self.showProgress = False - self.feedback = None - def setSelectedFaces(self, faces): - self.srcFaces = faces - self.facesAndEdges = FacesAndEdges(self.srcFaces) - def setShowProgress(self, show): - self.showProgress = show - # this method really needs work - def unfold(self): - selectedFaces = [face for face in self.src.faces if (self.src.faceUV and face.sel)] - if(self.avoidsOverlaps): - print "unfolding with overlap detection" - if(self.firstFaceIndex==None): - self.firstFaceIndex = random.randint(0, len(self.src.faces)-1) - else: - print "Using user-selected seed face ", self.firstFaceIndex - self.firstFace = self.src.faces[self.firstFaceIndex] - z = min([v.co.z for v in self.src.verts])-0.1 - ff = Poly.fromBlenderFace(self.firstFace) - if(len(ff.v)<3): - raise Exception("This mesh contains an isolated edge - it must consist only of faces") - testFace = Poly.fromVectors( [ Vector([0.0,0.0,0.0]), Vector([0.0,1.0,0.0]), Vector([1.0,1.0,0.0]) ] ) - # hmmm. I honestly can't remember why this needs to be done, but it does. - u=0 - v=1 - w=2 - if ff.v[u].x==ff.v[u+1].x and ff.v[u].y==ff.v[u+1].y: - u=1 - v=2 - w=0 - # here we make a couple of folds, not part of the net, which serve to get the net into the xy plane - xyFace = Poly.fromList( [ [ff.v[u].x,ff.v[u].y, z] , [ff.v[v].x,ff.v[v].y, z] , [ff.v[w].x+0.1,ff.v[w].y+0.1, z] ] ) - refFace = Poly.fromVectors([ ff.v[u], ff.v[v], xyFace.v[1], xyFace.v[0] ] ) - xyFold = Fold(None, xyFace, refFace, Edge(xyFace.v[0], xyFace.v[1] )) - self.refFold = Fold(xyFold, refFace, ff, Edge(refFace.v[0], refFace.v[1] )) - self.refFold.srcFace = self.firstFace - # prepare to grow the trees - trunk = Tree(self, None, self.refFold) - trunk.generations = self.generations - self.firstPoly = ff - self.facesAndEdges.takeFace(self.firstFace) - self.myFacesVisited+=1 - self.refFold.unfold() - self.refFold.tree = trunk - self.refFold.desFace = self.addFace(self.refFold.unfoldedFace(), self.refFold.srcFace) - self.folds.append(self.refFold) - trunk.grow() - i = 0 - # keep the trees growing while they can - while(self.myFacesVisited 0): - if self.edgeIteratorClass==RandomEdgeIterator: - i = random.randint(0,len(self.branches)-1) - tree = self.branches[i] - if(tree.isGrown()): - self.branches.pop(i) - else: - tree.beGrowing() - if(tree.canGrow()): - tree.grow() - i = 0 - else: - i = (i + 1) % len(self.branches) - if self.src.faceUV: - for face in self.src.faces: - face.sel = False - for face in selectedFaces: - face.sel = True - self.src.update() - Window.RedrawAll() - def assignUVs(self): - for fold in self.folds: - self.assignUV(fold.srcFace, fold.unfoldedFace()) - print " assigned uv to ", len(self.folds), len(self.src.faces) - self.src.update() - def checkOverlaps(self, fold): - #return self.getOverlapsBetween(fold, self.folds) - return self.getOverlapsBetweenGL(fold, self.folds) - def getOverlapsBetween(self, fold, folds): - if(fold.parent==None): - return [] - mf = fold.unfoldedFace() - c = [] - for afold in folds: - mdf = afold.unfoldedFace() - if(afold!=fold): - # currently need to get agreement from both polys because - # a touch by a vertex of one the other's edge is acceptable & - # they disagree on that - intersects = mf.intersects2D(mdf) and mdf.intersects2D(mf) - inside = ( mdf.containsAnyOf(mf) or mf.containsAnyOf(mdf) ) - if( intersects or inside or mdf.overlays(mf)): - c.append(afold) - return c - def getOverlapsBetweenGL(self, fold, folds): - b = fold.unfoldedFace().bounds() - polys = len(folds)*4+16 # the buffer is nhits, mindepth, maxdepth, name - buffer = BGL.Buffer(BGL.GL_INT, polys) - BGL.glSelectBuffer(polys, buffer) - BGL.glRenderMode(BGL.GL_SELECT) - BGL.glInitNames() - BGL.glPushName(0) - BGL.glPushMatrix() - BGL.glMatrixMode(BGL.GL_PROJECTION) - BGL.glLoadIdentity() - BGL.glOrtho(b[0].x, b[1].x, b[1].y, b[0].y, 0.0, 10.0) - #clip = BGL.Buffer(BGL.GL_FLOAT, 4) - #clip.list = [0,0,0,0] - #BGL.glClipPlane(BGL.GL_CLIP_PLANE1, clip) - # could use clipping planes here too - BGL.glMatrixMode(BGL.GL_MODELVIEW) - BGL.glLoadIdentity() - bx = (b[1].x - b[0].x) - by = (b[1].y - b[0].y) - cx = bx / 2.0 - cy = by / 2.0 - for f in xrange(len(folds)): - afold = folds[f] - if(fold!=afold): - BGL.glLoadName(f) - BGL.glBegin(BGL.GL_LINE_LOOP) - for v in afold.unfoldedFace().v: - BGL.glVertex2f(v.x, v.y) - BGL.glEnd() - BGL.glPopMatrix() - BGL.glFlush() - hits = BGL.glRenderMode(BGL.GL_RENDER) - buffer = [buffer[i] for i in xrange(3, 4*hits, 4)] - o = [folds[buffer[i]] for i in xrange(len(buffer))] - return self.getOverlapsBetween(fold, o) - def colourFace(self, face, cr): - for c in face.col: - c.r = int(cr[0]) - c.g = int(cr[1]) - c.b = int(cr[2]) - c.a = int(cr[3]) - self.src.update() - def setAvoidsOverlaps(self, avoids): - self.avoidsOverlaps = avoids - def addBranch(self, branch): - self.branches.append(branch) - if self.edgeIteratorClass!=RandomEdgeIterator: - self.branches.sort(lambda b1, b2: b1.compare(b2)) - def srcSize(self): - return len(self.src.faces) - def nBranches(self): - return len(self.branches) - def facesCreated(self): - return len(self.des.faces) - def facesVisited(self): - return self.myFacesVisited - def getOverlaps(self): - return self.overlaps - def sortOutIPOSource(self): - print "Sorting out IPO" - if self.foldIPO!=None: - return - o = None - try: - o = Blender.Object.Get("FoldRate") - except: - o = Blender.Object.New("Empty", "FoldRate") - Blender.Scene.GetCurrent().objects.link(o) - if(o.getIpo()==None): - ipo = Blender.Ipo.New("Object", "FoldRateIPO") - z = ipo.addCurve("RotZ") - print " added RotZ IPO curve" - z.addBezier((1,0)) - # again, why is this 10x out ? - z.addBezier((180, self.ff/10.0)) - z.addBezier((361, 0.0)) - o.setIpo(ipo) - z.recalc() - z.setInterpolation("Bezier") - z.setExtrapolation("Cyclic") - self.setIPOSource(o) - print " added IPO source" - def setIPOSource(self, object): - try: - self.foldIPO = object - for i in xrange(self.foldIPO.getIpo().getNcurves()): - self.IPOCurves[self.foldIPO.getIpo().getCurves()[i].getName()] = i - print " added ", self.foldIPO.getIpo().getCurves()[i].getName() - except: - print "Problem setting IPO object" - print sys.exc_info()[1] - traceback.print_exc(file=sys.stdout) - def setFoldFactor(self, ff): - self.ff = ff - def sayTree(self): - for fold in self.folds: - if(fold.getParent()!=None): - print fold.getID(), fold.dihedralAngle(), fold.getParent().getID() - def report(self): - p = int(float(self.myFacesVisited)/float(len(self.src.faces)) * 100) - print str(p) + "% unfolded" - print "faces created:", self.facesCreated() - print "faces visited:", self.facesVisited() - print "originalfaces:", len(self.src.faces) - n=0 - if(self.avoidsOverlaps): - print "net avoided at least ", self.getOverlaps(), " overlaps ", - n = len(self.src.faces) - self.facesCreated() - if(n>0): - print "but was unable to avoid ", n, " overlaps. Incomplete net." - else: - print "- A complete net." - else: - print "net has at least ", self.getOverlaps(), " collision(s)" - return n - # fold all my folds to a fraction of their total fold angle - def unfoldToCurrentFrame(self): - self.unfoldTo(Blender.Scene.GetCurrent().getRenderingContext().currentFrame()) - def unfoldTo(self, frame): - frames = Blender.Scene.GetCurrent().getRenderingContext().endFrame() - if(self.foldIPO!=None and self.foldIPO.getIpo()!=None): - f = self.foldIPO.getIpo().EvaluateCurveOn(self.IPOCurves["RotZ"],frame) - # err, this number seems to be 10x less than it ought to be - fff = 1.0 - (f*10.0 / self.ff) - else: - fff = 1.0-((frame)/(frames*1.0)) - for fold in self.folds: - fold.unfoldTo(fff) - for fold in self.folds: - fold.unfold() - tface = fold.unfoldedFace() - bface = fold.desFace - i = 0 - for v in bface.verts: - v.co.x = tface.v[i].x - v.co.y = tface.v[i].y - v.co.z = tface.v[i].z - i+=1 - Window.Redraw(Window.Types.VIEW3D) - return None - def addFace(self, poly, originalFace=None): - originalLength = len(self.des.verts) - self.des.verts.extend([Vector(vv.x, vv.y, vv.z) for vv in poly.v]) - self.des.faces.extend([ range(originalLength, originalLength + poly.size()) ]) - newFace = self.des.faces[len(self.des.faces)-1] - newFace.uv = [vv for vv in poly.v] - if(originalFace!=None and self.src.vertexColors): - newFace.col = [c for c in originalFace.col] - if(self.feedback!=None): - pu = str(int(self.fractionUnfolded() * 100))+"% unfolded" - howMuchDone = str(self.myFacesVisited)+" of "+str(len(self.src.faces))+" "+pu - self.feedback.say(howMuchDone) - #Window.DrawProgressBar (p, pu) - if(self.showProgress): - Window.Redraw(Window.Types.VIEW3D) - return newFace - def fractionUnfolded(self): - return float(self.myFacesVisited)/float(len(self.src.faces)) - def assignUV(self, face, uv): - face.uv = [Vector(v.x, v.y) for v in uv.v] - def unfoldAll(feedback=None): - objects = Blender.Object.Get() - for object in objects: - if(object.getType()=='Mesh' and not(object.getName().endswith("_net")) and len(object.getData(False, True).faces)>1): - net = Net.createNet(object, feedback) - net.searchForUnfolding() - svg = SVGExporter(net, object.getName()+".svg") - svg.export() - unfoldAll = staticmethod(unfoldAll) - def searchForUnfolding(self, limit=-1): - overlaps = 1 - attempts = 0 - while(overlaps > 0 or attempts=0 and (mesh.faces[mesh.activeFace].sel): - net.firstFaceIndex = mesh.activeFace - net.object = ob - net.feedback = feedback - return net - createNet = staticmethod(createNet) - def importNet(filename): - netName = filename.rstrip(".svg").replace("\\","/") - netName = netName[netName.rfind("/")+1:] - try: - netObject = Blender.Object.Get(netName) - except: - netObject = Blender.Object.New("Mesh", netName) - netObject.getData(mesh=1).name = netName - try: - Blender.Scene.GetCurrent().objects.link(netObject) - except: - pass - net = Net(None, netObject.getData(mesh=1)) - handler = NetHandler(net) - xml.sax.parse(filename, handler) - Window.Redraw(Window.Types.VIEW3D) - return net - importNet = staticmethod(importNet) - def getSourceMesh(self): - return self.src - -# determines the order in which to visit faces according to a local measure -class EdgeIterator: - def __init__(self, branch, otherConstructor=None): - self.branch = branch - self.bface = branch.getFace() - self.edge = branch.getFold().getEdge() - self.net = branch.getNet() - self.n = len(self.bface) - self.edges = [] - self.i = 0 - self.gooodness = 0 - self.createEdges() - self.computeGoodness() - if(otherConstructor==None): - self.sequenceEdges() - def createEdges(self): - edge = None - e = Edge.edgesOfBlenderFace(self.net.getSourceMesh(), self.bface) - for edge in e: - if not(edge.isBlenderSeam() and edge!=self.edge): - self.edges.append(edge) - def sequenceEdges(self): - pass - def next(self): - edge = self.edges[self.i] - self.i+=1 - return edge - def size(self): - return len(self.edges) - def reset(self): - self.i = 0 - def hasNext(self): - return (self.ilen(bface)-1): - return None - if(i==len(bface)-1): - j = 0 - else: - j = i+1 - edge = Edge( bface.v[i].co.copy(), bface.v[j].co.copy() ) - edge.bEdge = mesh.findEdge(bface.v[i], bface.v[j]) - edge.idx = i - return edge - fromBlenderFace=staticmethod(fromBlenderFace) - def edgesOfBlenderFace(mesh, bmFace): - edges = [mesh.edges[mesh.findEdges(edge[0], edge[1])] for edge in bmFace.edge_keys] - v = bmFace.verts - e = [] - vi = v[0] - i=0 - for j in xrange(1, len(bmFace)+1): - vj = v[j%len(bmFace)] - for ee in edges: - if((ee.v1.index==vi.index and ee.v2.index==vj.index) or (ee.v2.index==vi.index and ee.v1.index==vj.index)): - e.append(Edge(vi.co, vj.co, ee, i)) - i+=1 - vi = vj - return e - edgesOfBlenderFace=staticmethod(edgesOfBlenderFace) - def isBlenderSeam(self): - return (self.bmEdge.flag & Mesh.EdgeFlags.SEAM) - def isInFGon(self): - return (self.bmEdge.flag & Mesh.EdgeFlags.FGON) - def mapTo(self, poly): - if(self.idx==len(poly.v)-1): - j = 0 - else: - j = self.idx+1 - return Edge(poly.v[self.idx], poly.v[j]) - def isDegenerate(self): - return self.vector.length==0 - def vertices(s): - return [ [s.v1.x, s.v1.y, s.v1.z], [s.v2.x, s.v2.y,s.v2.z] ] - def key(self): - return self.bmEdge.key - def goodness(self): - return self.gooodness - def setGoodness(self, g): - self.gooodness = g - def compare(self, other): - if(self.goodness() > other.goodness()): - return +1 - else: - return -1 - # Does the given segment intersect this, for overlap detection. - # endpoints are allowed to touch the line segment - def intersects2D(self, s): - if(self.matches(s)): - return False - else: - i = Geometry.LineIntersect2D(self.v1, self.v2, s.v1, s.v2) - if(i!=None): - i.resize4D() - i.z = self.v1.z # hack to put the point on the same plane as this edge for comparison - return(i!=None and not(self.endsWith(i))) - def matches(self, s): - return ( (self.v1==s.v1 and self.v2==s.v2) or (self.v2==s.v1 and self.v1==s.v2) ) - # Is the given point on the end of this segment ? 10-5 seems to an acceptable limit for closeness in Blender - def endsWith(self, aPoint, e=0.0001): - return ( (self.v1-aPoint).length < e or (self.v2-aPoint).length < e ) - - -class Poly: - ids = -1 - def __init__(self): - Poly.ids+=1 - self.v = [] - self.id = Poly.ids - self.boundz = None - self.edges = None - def getID(self): - return self.id - def normal(self): - a =self.v[0] - b=self.v[1] - c=self.v[2] - p = b-a - p.resize3D() - q = a-c - q.resize3D() - return p.cross(q) - def makeEdges(self): - self.edges = [] - for i in xrange(self.nPoints()): - self.edges.append(Edge( self.v[i % self.nPoints()], self.v[ (i+1) % self.nPoints()] )) - def edgeAt(self, i): - if(self.edges==None): - self.makeEdges() - return self.edges[i] - def intersects2D(self, poly): - for i in xrange(self.nPoints()): - edge = self.edgeAt(i) - for j in xrange(poly.nPoints()): - if edge.intersects2D(poly.edgeAt(j)): - return True - return False - def isBad(self): - badness = 0 - for vv in self.v: - if(vv.x!=vv.x or vv.y!=vv.y or vv.z!=vv.z): # Nan check - badness+=1 - return (badness>0) - def midpoint(self): - x=y=z = 0.0 - n = 0 - for vv in self.v: - x+=vv.x - y+=vv.y - z+=vv.z - n+=1 - return [ x/n, y/n, z/n ] - def centerAtOrigin(self): - mp = self.midpoint() - mp = -mp - toOrigin = TranslationMatrix(mp) - self.v = [(vv * toOrigin) for vv in self.v] - def move(self, tv): - mv = TranslationMatrix(tv) - self.v = [(vv * mv) for vv in self.v] - def scale(self, s): - mp = Vector(self.midpoint()) - fromOrigin = TranslationMatrix(mp) - mp = -mp - toOrigin = TranslationMatrix(mp) - sm = ScaleMatrix(s, 4) - # Todo, the 3 lines below in 1 LC - self.v = [(vv * toOrigin) for vv in self.v] - self.v = [(sm * vv) for vv in self.v] - self.v = [(vv * fromOrigin) for vv in self.v] - def nPoints(self): - return len(self.v) - def size(self): - return len(self.v) - def rotated(self, axis, angle): - p = self.clone() - p.rotate(axis, angle) - return p - def rotate(self, axis, angle): - rotation = RotationMatrix(angle, 4, "r", axis.vector) - toOrigin = TranslationMatrix(axis.v1n) - fromOrigin = TranslationMatrix(axis.v1) - # Todo, the 3 lines below in 1 LC - self.v = [(vv * toOrigin) for vv in self.v] - self.v = [(rotation * vv) for vv in self.v] - self.v = [(vv * fromOrigin) for vv in self.v] - def moveAlong(self, vector, distance): - t = TranslationMatrix(vector) - s = ScaleMatrix(distance, 4) - ts = t*s - self.v = [(vv * ts) for vv in self.v] - def bounds(self): - if(self.boundz == None): - vv = [vv for vv in self.v] - vv.sort(key=lambda v: v.x) - minx = vv[0].x - maxx = vv[len(vv)-1].x - vv.sort(key=lambda v: v.y) - miny = vv[0].y - maxy = vv[len(vv)-1].y - self.boundz = [Vector(minx, miny, 0), Vector(maxx, maxy, 0)] - return self.boundz - def fromBlenderFace(bface): - p = Poly() - for vv in bface.v: - vec = Vector([vv.co[0], vv.co[1], vv.co[2] , 1.0]) - p.v.append(vec) - return p - fromBlenderFace = staticmethod(fromBlenderFace) - def fromList(list): - p = Poly() - for vv in list: - vec = Vector( [vvv for vvv in vv] ) - vec.resize4D() - p.v.append(vec) - return p - fromList = staticmethod(fromList) - def fromVectors(vectors): - p = Poly() - p.v.extend([v.copy().resize4D() for v in vectors]) - return p - fromVectors = staticmethod(fromVectors) - def clone(self): - p = Poly() - p.v.extend(self.v) - return p - def hasVertex(self, ttv): - v = Mathutils.Vector(ttv) - v.normalize() - for tv in self.v: - vv = Mathutils.Vector(tv) - vv.normalize() - t = 0.00001 - if abs(vv.x-v.x)0): j=i-1 - cv = self.v[i] - nv = self.v[j] - if ((((cv.y<=tp.y) and (tp.y") - self.e.endElement("style") - self.e.endElement("defs") - #self.addClipPath() - self.addMeta() - def addMeta(self): - self.e.startElement("metadata", xml.sax.xmlreader.AttributesImpl({})) - self.e.startElement("nets:net", xml.sax.xmlreader.AttributesImpl({})) - for i in xrange(1, len(self.net.folds)): - fold = self.net.folds[i] - # AttributesNSImpl - documentation is rubbish. using this hack. - atts = {} - atts["nets:id"] = "fold"+str(fold.getID()) - if(fold.parent!=None): - atts["nets:parent"] = "fold"+str(fold.parent.getID()) - else: - atts["nets:parent"] = "null" - atts["nets:da"] = str(fold.dihedralAngle()) - if(fold.parent!=None): - atts["nets:ofPoly"] = "poly"+str(fold.parent.foldingPoly.getID()) - else: - atts["nets:ofPoly"] = "" - atts["nets:toPoly"] = "poly"+str(fold.foldingPoly.getID()) - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("nets:fold", a) - self.e.endElement("nets:fold") - self.e.endElement("nets:net") - self.e.endElement("metadata") - def end(self): - self.e.endElement("svg") - self.e.endDocument() - print "grown." - def export(self): - self.net.unfoldTo(1) - bb = self.object.getBoundBox() - print bb - self.vxmin = bb[0][0] - self.vymin = bb[0][1] - self.vxmax = bb[7][0] - self.vymax = bb[7][1] - self.start() - atts = {} - atts["id"] = self.object.getName() - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("g", a) - #self.addUVImage() - self.addPolys() - self.addFoldLines() - #self.addCutLines() - self.e.endElement("g") - self.end() - def addClipPath(self): - atts = {} - atts["id"] = "netClip" - atts["clipPathUnits"] = "userSpaceOnUse" - atts["x"] = str(self.vxmin) - atts["y"] = str(self.vymin) - atts["width"] = "100%" - atts["height"] = "100%" - self.e.startElement("clipPath", atts) - self.addPolys() - self.e.endElement("clipPath") - def addUVImage(self): - image = Blender.Image.GetCurrent() #hmm - how to determine the desired image ? - if image==None: - return - ifn = image.getFilename() - ifn = self.filename.replace(".svg", ".jpg") - image.setFilename(ifn) - ifn = ifn[ifn.rfind("/")+1:] - image.save() - atts = {} - atts["clip-path"] = "url(#netClip)" - atts["xlink:href"] = ifn - self.e.startElement("image", atts) - self.e.endElement("image") - def addPolys(self): - atts = {} - atts["id"] = "polys" - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("g", a) - for i in xrange(len(self.net.folds)): - self.addPoly(self.net.folds[i]) - self.e.endElement("g") - def addFoldLines(self): - atts = {} - atts["id"] = "foldLines" - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("g", a) - for i in xrange( 1, len(self.net.folds)): - self.addFoldLine(self.net.folds[i]) - self.e.endElement("g") - def addFoldLine(self, fold): - edge = fold.edge.mapTo(fold.parent.foldingPoly) - if fold.dihedralAngle()>0: - foldType="valley" - else: - foldType="mountain" - atts={} - atts["x1"] = str(edge.v1.x) - atts["y1"] = str(edge.v1.y) - atts["x2"] = str(edge.v2.x) - atts["y2"] = str(edge.v2.y) - atts["id"] = "fold"+str(fold.getID()) - atts["class"] = foldType - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("line", a) - self.e.endElement("line") - def addCutLines(self): - atts = {} - atts["id"] = "cutLines" - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("g", a) - for i in xrange( 1, len(self.net.cuts)): - self.addCutLine(self.net.cuts[i]) - self.e.endElement("g") - def addCutLine(self, cut): - edge = cut.edge.mapTo(cut.parent.foldingPoly) - if cut.dihedralAngle()>0: - foldType="valley" - else: - foldType="mountain" - atts={} - atts["x1"] = str(edge.v1.x) - atts["y1"] = str(edge.v1.y) - atts["x2"] = str(edge.v2.x) - atts["y2"] = str(edge.v2.y) - atts["id"] = "cut"+str(cut.getID()) - atts["class"] = foldType - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("line", a) - self.e.endElement("line") - def addPoly(self, fold): - face = fold.foldingPoly - atts = {} - if fold.desFace.col: - col = fold.desFace.col[0] - rgb = "rgb("+str(col.r)+","+str(col.g)+","+str(col.b)+")" - atts["fill"] = rgb - atts["class"] = "poly" - atts["id"] = "poly"+str(face.getID()) - points = "" - first = True - for vv in face.v: - if(not(first)): - points+=',' - first = False - points+=str(vv[0]) - points+=' ' - points+=str(vv[1]) - atts["points"] = points - a = xml.sax.xmlreader.AttributesImpl(atts) - self.e.startElement("polygon", a) - self.e.endElement("polygon") - def fileSelected(filename): - try: - net = Registry.GetKey('unfolder')['net'] - exporter = SVGExporter(net, filename) - exporter.export() - except: - print "Problem exporting SVG" - traceback.print_exc(file=sys.stdout) - fileSelected = staticmethod(fileSelected) - -# for importing nets saved by the above exporter -class NetHandler(xml.sax.handler.ContentHandler): - def __init__(self, net): - self.net = net - self.first = (41==41) - self.currentElement = None - self.chars = None - self.currentAction = None - self.foldsPending = {} - self.polys = {} - self.actions = {} - self.actions["nets:fold"] = self.foldInfo - self.actions["line"] = self.cutOrFold - self.actions["polygon"] = self.createPoly - def setDocumentLocator(self, locator): - pass - def startDocument(self): - pass - def endDocument(self): - for fold in self.foldsPending.values(): - face = self.net.addFace(fold.unfoldedFace()) - fold.desFace = face - self.net.folds.append(fold) - self.net.addFace(self.first) - self.foldsPending = None - self.polys = None - def startPrefixMapping(self, prefix, uri): - pass - def endPrefixMapping(self, prefix): - pass - def startElement(self, name, attributes): - self.currentAction = None - try: - self.currentAction = self.actions[name] - except: - pass - if(self.currentAction!=None): - self.currentAction(attributes) - def endElement(self, name): - pass - def startElementNS(self, name, qname, attrs): - self.currentAction = self.actions[name] - if(self.currentAction!=None): - self.currentAction(attributes) - def endElementNS(self, name, qname): - pass - def characters(self, content): - pass - def ignorableWhitespace(self): - pass - def processingInstruction(self, target, data): - pass - def skippedEntity(self, name): - pass - def foldInfo(self, atts): - self.foldsPending[atts["nets:id"]] = atts - def createPoly(self, atts): - xy = re.split('[, ]' , atts["points"]) - vectors = [] - for i in xrange(0, len(xy)-1, 2): - v = Vector([float(xy[i]), float(xy[i+1]), 0.0]) - vectors.append(v) - poly = Poly.fromVectors(vectors) - if(self.first==True): - self.first = poly - self.polys[atts["id"]] = poly - def cutOrFold(self, atts): - fid = atts["id"] - try: - fi = self.foldsPending[fid] - except: - pass - p1 = Vector([float(atts["x1"]), float(atts["y1"]), 0.0]) - p2 = Vector([float(atts["x2"]), float(atts["y2"]), 0.0]) - edge = Edge(p1, p2) - parent = None - ofPoly = None - toPoly = None - try: - parent = self.foldsPending[fi["nets:parent"]] - except: - pass - try: - ofPoly = self.polys[fi["nets:ofPoly"]] - except: - pass - try: - toPoly = self.polys[fi["nets:toPoly"]] - except: - pass - fold = Fold(parent, ofPoly , toPoly, edge, float(fi["nets:da"])) - self.foldsPending[fid] = fold - def fileSelected(filename): - try: - net = Net.importNet(filename) - try: - Registry.GetKey('unfolder')['net'] = net - except: - Registry.SetKey('unfolder', {}) - Registry.GetKey('unfolder')['net'] = net - Registry.GetKey('unfolder')['lastpath'] = filename - except: - print "Problem importing SVG" - traceback.print_exc(file=sys.stdout) - fileSelected = staticmethod(fileSelected) - - -class GUI: - def __init__(self): - self.overlaps = Draw.Create(0) - self.ani = Draw.Create(0) - self.selectedFaces =0 - self.search = Draw.Create(0) - self.diffuse = True - self.ancestors = Draw.Create(0) - self.noise = Draw.Create(0.0) - self.shape = Draw.Create(0) - self.nOverlaps = 1==2 - self.iterators = [RandomEdgeIterator,Brightest,Curvature,EdgeIterator,OddEven,Largest] - self.iterator = RandomEdgeIterator - self.overlapsText = "*" - self.message = " " - def makePopupGUI(self): - useRandom = Draw.Create(0) - pub = [] - pub.append(("Search", self.search, "Search for non-overlapping net (maybe forever)")) - pub.append(("Random", useRandom, "Random style net")) - ok = True - while ok: - ok = Blender.Draw.PupBlock("Unfold", pub) - if ok: - if useRandom.val: - self.iterator = RandomEdgeIterator - else: - self.iterator = Curvature - self.unfold() - def makeStandardGUI(self): - Draw.Register(self.draw, self.keyOrMouseEvent, self.buttonEvent) - def installScriptLink(self): - print "Adding script link for animation" - s = Blender.Scene.GetCurrent().getScriptLinks("FrameChanged") - if(s!=None and s.count("frameChanged.py")>0): - return - try: - script = Blender.Text.Get("frameChanged.py") - except: - script = Blender.Text.New("frameChanged.py") - script.write("import Blender\n") - script.write("import mesh_unfolder as Unfolder\n") - script.write("u = Blender.Registry.GetKey('unfolder')\n") - script.write("if u!=None:\n") - script.write("\tn = u['net']\n") - script.write("\tif(n!=None and n.animates):\n") - script.write("\t\tn.unfoldToCurrentFrame()\n") - Blender.Scene.GetCurrent().addScriptLink("frameChanged.py", "FrameChanged") - def unfold(self): - anc = self.ancestors.val - n = 0.0 - s = True - self.nOverlaps = 0 - searchLimit = 10 - search = 1 - Draw.Redraw(1) - net = None - name = None - try: - self.say("Unfolding...") - Draw.Redraw(1) - while(s):# and search < searchLimit): - if(net!=None): - name = net.des.name - net = Net.fromSelected(self, name) - net.setAvoidsOverlaps(not(self.overlaps.val)) - print - print "Unfolding selected object" - net.edgeIteratorClass = self.iterator - print "Using ", net.edgeIteratorClass - net.animates = self.ani.val - self.diffuse = (self.ancestors.val==0) - net.diffuse = self.diffuse - net.generations = self.ancestors.val - net.noise = self.noise.val - print "even:", net.diffuse, " depth:", net.generations - net.unfold() - n = net.report() - t = "." - if(n<1.0): - t = "Overlaps>="+str(n) - else: - t = "A complete net." - self.nOverlaps = (n>=1) - if(self.nOverlaps): - self.say(self.message+" - unfolding failed - try again ") - elif(not(self.overlaps.val)): - self.say("Success. Complete net - no overlaps ") - else: - self.say("Unfolding complete") - self.ancestors.val = anc - s = (self.search.val and n>=1.0) - dict = Registry.GetKey('unfolder') - if(not(dict)): - dict = {} - dict['net'] = net - Registry.SetKey('unfolder', dict) - if(s): - net = net.clone() - search += 1 - except(IndexError): - self.say("Please select an object to unfold") - except: - self.say("Problem unfolding selected object - see console for details") - print "Problem unfolding selected object:" - print sys.exc_info()[1] - traceback.print_exc(file=sys.stdout) - if(self.ani): - if Registry.GetKey('unfolder')==None: - print "no net!" - return - Registry.GetKey('unfolder')['net'].sortOutIPOSource() - self.installScriptLink() - Draw.Redraw(1) - def keyOrMouseEvent(self, evt, val): - if (evt == Draw.ESCKEY and not val): - Draw.Exit() - def buttonEvent(self, evt): - if (evt == 1): - self.unfold() - if (evt == 5): - try: - Registry.GetKey('unfolder')['net'].setAvoidsOverlaps(self.overlaps.val) - except: - pass - if (evt == 2): - print "Trying to set IPO curve" - try: - s = Blender.Object.GetSelected() - if(s!=None): - Registry.GetKey('unfolder')['net'].setIPOSource( s[0] ) - print "Set IPO curve" - else: - print "Please select an object to use the IPO of" - except: - print "Problem setting IPO source" - Draw.Redraw(1) - if (evt == 6): - Draw.Exit() - if (evt == 7): - try: - if (Registry.GetKey('unfolder')['net']!=None): - Registry.GetKey('unfolder')['net'].animates = self.ani.val - if(self.ani): - Registry.GetKey('unfolder')['net'].sortOutIPOSource() - self.installScriptLink() - except: - print sys.exc_info()[1] - traceback.print_exc(file=sys.stdout) - Draw.Redraw(1) - if (evt == 19): - pass - if (evt == 87): - try: - if (Registry.GetKey('unfolder')['net']!=None): - Registry.GetKey('unfolder')['net'].assignUVs() - self.say("Assigned UVs") - except: - print sys.exc_info()[1] - traceback.print_exc(file=sys.stdout) - Draw.Redraw(1) - if(evt==91): - if( testOverlap() == True): - self.nOverlaps = 1 - else: - self.nOverlaps = 0 - Draw.Redraw(1) - if(evt==233): - f1 = Poly.fromBlenderFace(Blender.Object.GetSelected()[0].getData().faces[0]) - f2 = Poly.fromBlenderFace(Blender.Object.GetSelected()[1].getData().faces[0]) - print - print Blender.Object.GetSelected()[0].getName() - print Blender.Object.GetSelected()[1].getName() - print f1.intersects2D(f2) - print f2.intersects2D(f1) - if(evt==714): - Net.unfoldAll(self) - Draw.Redraw(1) - if(evt==713): - self.iterator = self.iterators[self.shape.val] - Draw.Redraw(1) - if(evt==92): - if( testContains() == True): - self.nOverlaps = 1 - else: - self.nOverlaps = 0 - Draw.Redraw(1) - if(evt==104): - try: - filename = "net.svg" - s = Blender.Object.GetSelected() - if(s!=None and len(s)>0): - filename = s[0].getName()+".svg" - else: - if (Registry.GetKey('unfolder')['net']!=None): - filename = Registry.GetKey('unfolder')['net'].des.name - if(filename==None): - filename="net.svg" - else: - filename=filename+".svg" - Window.FileSelector(SVGExporter.fileSelected, "Select filename", filename) - except: - print "Problem exporting SVG" - traceback.print_exc(file=sys.stdout) - if(evt==107): - try: - Window.FileSelector(NetHandler.fileSelected, "Select file") - except: - print "Problem importing SVG" - traceback.print_exc(file=sys.stdout) - def say(self, m): - self.message = m - Draw.Redraw(1) - Window.Redraw(Window.Types.SCRIPT) - def draw(self): - cw = 64 - ch = 16 - l = FlowLayout(32, cw, ch, 350, 64) - l.y = 70 - self.search = Draw.Toggle("search", 19, l.nx(), l.ny(), l.cw, l.ch, self.search.val, "Search for non-overlapping mesh (potentially indefinitely)") - self.overlaps = Draw.Toggle("overlaps", 5, l.nx(), l.ny(), l.cw, l.ch, self.overlaps.val, "Allow overlaps / avoid overlaps - if off, will not place overlapping faces") - self.ani = Draw.Toggle("ani", 7, l.nx(), l.ny(), l.cw, l.ch, self.ani.val, "Animate net") - Draw.Button("uv", 87, l.nx(), l.ny(), l.cw, l.ch, "Assign net as UV to source mesh (overwriting existing UV)") - Draw.Button("Unfold", 1, l.nx(), l.ny(), l.cw, l.ch, "Unfold selected mesh to net") - Draw.Button("save", 104, l.nx(), l.ny(), l.cw, l.ch, "Save net as SVG") - Draw.Button("load", 107, l.nx(), l.ny(), l.cw, l.ch, "Load net from SVG") - #Draw.Button("test", 233, l.nx(), l.ny(), l.cw, l.ch, "test") - # unfolding enthusiasts - try uncommenting this - self.ancestors = Draw.Number("depth", 654, l.nx(), l.ny(), cw, ch, self.ancestors.val, 0, 9999, "depth of branching 0=diffuse") - #self.noise = Draw.Number("noise", 631, l.nx(), l.ny(), cw, ch, self.noise.val, 0.0, 1.0, "noisyness of branching") - #Draw.Button("UnfoldAll", 714, l.nx(), l.ny(), l.cw, l.ch, "Unfold all meshes and save their nets") - options = "order %t|random %x0|brightest %x1|curvature %x2|winding %x3| 1010 %x4|largest %x5" - self.shape = Draw.Menu(options, 713, l.nx(), l.ny(), cw, ch, self.shape.val, "shape of net") - Draw.Button("exit", 6, l.nx(), l.ny(), l.cw, l.ch, "exit") - BGL.glClearColor(0.3, 0.3, 0.3, 1) - BGL.glColor3f(0.3,0.3,0.3) - l.newLine() - BGL.glRasterPos2i(32, 100) - Draw.Text(self.message) - -class FlowLayout: - def __init__(self, margin, cw, ch, w, h): - self.x = margin-cw-4 - self.y = margin - self.cw = cw - self.ch = ch - self.width = w - self.height = h - self.margin = margin - def nx(self): - self.x+=(self.cw+4) - if(self.x>self.width): - self.x = self.margin - self.y-=self.ch+4 - return self.x - def ny(self): - return self.y - def newLine(self): - self.y-=self.ch+self.margin - self.x = self.margin - -# if xml is None, then dont bother running the script -if xml: - try: - sys.setrecursionlimit(10000) - gui = GUI() - gui.makeStandardGUI() - #gui.makePopupGUI() - except: - traceback.print_exc(file=sys.stdout) diff --git a/release/scripts/mesh_wire.py b/release/scripts/mesh_wire.py deleted file mode 100644 index bd38c47a9b9..00000000000 --- a/release/scripts/mesh_wire.py +++ /dev/null @@ -1,290 +0,0 @@ -#!BPY -""" -Name: 'Solid Wireframe' -Blender: 243 -Group: 'Mesh' -Tooltip: 'Make a solid wireframe copy of this mesh' -""" - -# -------------------------------------------------------------------------- -# Solid Wireframe1.0 by Campbell Barton (AKA Ideasman42) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- -import Blender -from Blender import Scene, Mesh, Window, sys -from Blender.Mathutils import AngleBetweenVecs, TriangleNormal -from BPyMesh import faceAngles # get angles for face cornders -#import BPyMesh -#reload(BPyMesh) -#faceAngles = BPyMesh.faceAngles - -# works out the distanbce to inset the corners based on angles -from BPyMathutils import angleToLength -#import BPyMathutils -#reload(BPyMathutils) -#angleToLength = BPyMathutils.angleToLength - -import mesh_solidify - -import BPyMessages -reload(BPyMessages) -import bpy - - -def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_SHARP, PREF_XSHARP): - if not PREF_SHARP and PREF_XSHARP: - PREF_XSHARP = False - - # This function runs out of editmode with a mesh - # error cases are alredy checked for - - inset_half = PREF_THICKNESS / 2 - del PREF_THICKNESS - - ob = ob_orig.copy() - me = me_orig.copy() - ob.link(me) - sce.objects.selected = [] - sce.objects.link(ob) - ob.sel = True - sce.objects.active = ob - - # Modify the object, should be a set - FGON= Mesh.EdgeFlags.FGON - edges_fgon = dict([(ed.key,None) for ed in me.edges if ed.flag & FGON]) - # edges_fgon.fromkeys([ed.key for ed in me.edges if ed.flag & FGON]) - - del FGON - - - - # each face needs its own verts - # orig_vert_count =len(me.verts) - new_vert_count = len(me.faces) * 4 - for f in me.faces: - if len(f) == 3: - new_vert_count -= 1 - - if PREF_SHARP == 0: - new_faces_edge= {} - - def add_edge(i1,i2, ni1, ni2): - - if i1>i2: - i1,i2 = i2,i1 - flip = True - else: - flip = False - new_faces_edge.setdefault((i1,i2), []).append((ni1, ni2, flip)) - - - new_verts = [] - new_faces = [] - vert_index = len(me.verts) - - for f in me.faces: - f_v_co = [v.co for v in f] - angles = faceAngles(f_v_co) - f_v_idx = [v.index for v in f] - - def new_vert(fi): - co = f_v_co[fi] - a = angles[fi] - if a > 180: - vert_inset = 1 * inset_half - else: - vert_inset = inset_half * angleToLength( abs((180-a) / 2) ) - - # Calculate the inset direction - co1 = f_v_co[fi-1] - co2 = fi+1 # Wrap this index back to the start - if co2 == len(f_v_co): co2 = 0 - co2 = f_v_co[co2] - - co1 = co1 - co - co2 = co2 - co - co1.normalize() - co2.normalize() - d = co1+co2 - # Done with inset direction - - d.length = vert_inset - return co+d - - new_verts.extend([new_vert(i) for i in xrange(len(f_v_co))]) - - if len(f_v_idx) == 4: - faces = [\ - (f_v_idx[1], f_v_idx[0], vert_index, vert_index+1),\ - (f_v_idx[2], f_v_idx[1], vert_index+1, vert_index+2),\ - (f_v_idx[3], f_v_idx[2], vert_index+2, vert_index+3),\ - (f_v_idx[0], f_v_idx[3], vert_index+3, vert_index),\ - ] - else: - faces = [\ - (f_v_idx[1], f_v_idx[0], vert_index, vert_index+1),\ - (f_v_idx[2], f_v_idx[1], vert_index+1, vert_index+2),\ - (f_v_idx[0], f_v_idx[2], vert_index+2, vert_index),\ - ] - - - if PREF_SHARP == 1: - if not edges_fgon: - new_faces.extend(faces) - else: - for nf in faces: - i1,i2 = nf[0], nf[1] - if i1>i2: i1,i2 = i2,i1 - - if edges_fgon and (i1,i2) not in edges_fgon: - new_faces.append(nf) - - - - elif PREF_SHARP == 0: - for nf in faces: - add_edge(*nf) - - vert_index += len(f_v_co) - - me.verts.extend(new_verts) - - if PREF_SHARP == 0: - def add_tri_flipped(i1,i2,i3): - try: - if AngleBetweenVecs(me.verts[i1].no, TriangleNormal(me.verts[i1].co, me.verts[i2].co, me.verts[i3].co)) < 90: - return i3,i2,i1 - else: - return i1,i2,i3 - except: - return i1,i2,i3 - - # This stores new verts that use this vert - # used for re-averaging this verts location - # based on surrounding verts. looks better but not needed. - vert_users = [set() for i in xrange(vert_index)] - - for (i1,i2), nf in new_faces_edge.iteritems(): - - if len(nf) == 2: - # Add the main face - if edges_fgon and (i1,i2) not in edges_fgon: - new_faces.append((nf[0][0], nf[0][1], nf[1][0], nf[1][1])) - - - if nf[0][2]: key1 = nf[0][1],nf[0][0] - else: key1 = nf[0][0],nf[0][1] - if nf[1][2]: key2 = nf[1][1],nf[1][0] - else: key2 = nf[1][0],nf[1][1] - - # CRAP, cont work out which way to flip so make it oppisite the verts normal. - - ###new_faces.append((i2, key1[0], key2[0])) # NO FLIPPING, WORKS THOUGH - ###new_faces.append((i1, key1[1], key2[1])) - new_faces.append(add_tri_flipped(i2, key1[0], key2[0])) - new_faces.append(add_tri_flipped(i1, key1[1], key2[1])) - - # Average vert loction so its not tooo pointy - # not realy needed but looks better - vert_users[i2].update((key1[0], key2[0])) - vert_users[i1].update((key1[1], key2[1])) - - if len(nf) == 1: - if nf[0][2]: new_faces.append((nf[0][0], nf[0][1], i2, i1)) # flipped - else: new_faces.append((i1,i2, nf[0][0], nf[0][1])) - - - # average points now. - for i, vusers in enumerate(vert_users): - if vusers: - co = me.verts[i].co - co.zero() - - for ii in vusers: - co += me.verts[ii].co - co /= len(vusers) - - me.faces.delete(1, range(len(me.faces))) - - me.faces.extend(new_faces) - - # External function, solidify - me.sel = True - if PREF_SOLID: - mesh_solidify.solidify(me, -inset_half*2, True, False, PREF_XSHARP) - - -def main(): - - # Gets the current scene, there can be many scenes in 1 blend file. - sce = bpy.data.scenes.active - - # Get the active object, there can only ever be 1 - # and the active object is always the editmode object. - ob_act = sce.objects.active - - if not ob_act or ob_act.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - # Saves the editmode state and go's out of - # editmode if its enabled, we cant make - # changes to the mesh data while in editmode. - is_editmode = Window.EditMode() - Window.EditMode(0) - - me = ob_act.getData(mesh=1) # old NMesh api is default - if len(me.faces)==0: - BPyMessages.Error_NoMeshFaces() - if is_editmode: Window.EditMode(1) - return - - # Create the variables. - PREF_THICK = Blender.Draw.Create(0.005) - PREF_SOLID = Blender.Draw.Create(1) - PREF_SHARP = Blender.Draw.Create(1) - PREF_XSHARP = Blender.Draw.Create(0) - - pup_block = [\ - ('Thick:', PREF_THICK, 0.0001, 2.0, 'Skin thickness in mesh space.'),\ - ('Solid Wire', PREF_SOLID, 'If Disabled, will use 6 sided wire segments'),\ - ('Sharp Wire', PREF_SHARP, 'Use the original mesh topology for more accurate sharp wire.'),\ - ('Extra Sharp', PREF_XSHARP, 'Use less geometry to create a sharper looking wire'),\ - ] - - if not Blender.Draw.PupBlock('Solid Wireframe', pup_block): - if is_editmode: Window.EditMode(1) - return - - Window.WaitCursor(1) - t = sys.time() - - # Run the mesh editing function - solid_wire(ob_act, me, sce, PREF_THICK.val, PREF_SOLID.val, PREF_SHARP.val, PREF_XSHARP.val) - - # Timing the script is a good way to be aware on any speed hits when scripting - print 'Solid Wireframe finished in %.2f seconds' % (sys.time()-t) - Window.WaitCursor(0) - if is_editmode: Window.EditMode(1) - - -# This lets you can import the script without running it -if __name__ == '__main__': - main() diff --git a/release/scripts/ms3d_import.py b/release/scripts/ms3d_import.py deleted file mode 100644 index c1438cbfc97..00000000000 --- a/release/scripts/ms3d_import.py +++ /dev/null @@ -1,487 +0,0 @@ -#!BPY -""" -Name: 'MilkShape3D (.ms3d)...' -Blender: 245 -Group: 'Import' -Tooltip: 'Import from MilkShape3D file format (.ms3d)' -""" -# -# Author: Markus Ilmola -# Email: markus.ilmola@pp.inet.fi -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# - -# import needed stuff -import os.path -import math -from math import * -import struct -import Blender -from Blender import Mathutils -from Blender.Mathutils import * - - -# trims a string by removing ending 0 and everything after it -def uku(s): - try: - return s[:s.index('\0')] - except: - return s - - -# Converts ms3d euler angles to a rotation matrix -def RM(a): - sy = sin(a[2]) - cy = cos(a[2]) - sp = sin(a[1]) - cp = cos(a[1]) - sr = sin(a[0]) - cr = cos(a[0]) - return Matrix([cp*cy, cp*sy, -sp], [sr*sp*cy+cr*-sy, sr*sp*sy+cr*cy, sr*cp],[cr*sp*cy+-sr*-sy, cr*sp*sy+-sr*cy, cr*cp]) - - -# Converts ms3d euler angles to a quaternion -def RQ(a): - angle = a[2] * 0.5; - sy = sin(angle); - cy = cos(angle); - angle = a[1] * 0.5; - sp = sin(angle); - cp = cos(angle); - angle = a[0] * 0.5; - sr = sin(angle); - cr = cos(angle); - return Quaternion(cr*cp*cy+sr*sp*sy, sr*cp*cy-cr*sp*sy, cr*sp*cy+sr*cp*sy, cr*cp*sy-sr*sp*cy) - - -# takes a texture filename and tries to load it -def loadImage(path, filename): - image = None - try: - image = Blender.Image.Load(os.path.abspath(filename)) - except IOError: - print "Warning: Failed to load image: " + filename + ". Trying short path instead...\n" - try: - image = Blender.Image.Load(os.path.dirname(path) + "/" + os.path.basename(filename)) - except IOError: - print "Warning: Failed to load image: " + os.path.basename(filename) + "!\n" - return image - - -# imports a ms3d file to the current scene -def import_ms3d(path): - # get scene - scn = Blender.Scene.GetCurrent() - if scn == None: - return "No scene to import to!" - - # open the file - try: - file = open(path, 'rb') - except IOError: - return "Failed to open the file!" - - # get the file size - file.seek(0, os.SEEK_END); - fileSize = file.tell(); - file.seek(0, os.SEEK_SET); - - # read id to check if the file is a MilkShape3D file - id = file.read(10) - if id!="MS3D000000": - return "The file is not a MS3D file!" - - # read version - version = struct.unpack("i", file.read(4))[0] - if version!=4: - return "The file has invalid version!" - - # Create the mesh - scn.objects.selected = [] - mesh = Blender.Mesh.New("MilkShape3D Mesh") - meshOb = scn.objects.new(mesh) - - # read the number of vertices - numVertices = struct.unpack("H", file.read(2))[0] - - # read vertices - coords = [] - boneIds = [] - for i in xrange(numVertices): - # skip flags - file.read(1) - - # read coords - coords.append(struct.unpack("fff", file.read(3*4))) - - # read bone ids - boneIds.append(struct.unpack("b", file.read(1))[0]) - - # skip refcount - file.read(1) - - # add the vertices to the mesh - mesh.verts.extend(coords) - - # read number of triangles - numTriangles = struct.unpack("H", file.read(2))[0] - - # read triangles - faces = [] - uvs = [] - for i in xrange(numTriangles): - # skip flags - file.read(2) - - # read indices (faces) - faces.append(struct.unpack("HHH", file.read(3*2))) - - # read normals - normals = struct.unpack("fffffffff", file.read(3*3*4)) - - # read texture coordinates - s = struct.unpack("fff", file.read(3*4)) - t = struct.unpack("fff", file.read(3*4)) - - # store texture coordinates - uvs.append([[s[0], 1-t[0]], [s[1], 1-t[1]], [s[2], 1-t[2]]]) - - if faces[-1][2] == 0: # Cant have zero at the third index - faces[-1] = faces[-1][1], faces[-1][2], faces[-1][0] - uvs[-1] = uvs[-1][1], uvs[-1][2], uvs[-1][0] - - # skip smooth group - file.read(1) - - # skip group - file.read(1) - - # add the faces to the mesh - mesh.faces.extend(faces) - - # set texture coordinates - for i in xrange(numTriangles): - mesh.faces[i].uv = [Vector(uvs[i][0]), Vector(uvs[i][1]), Vector(uvs[i][2])] - - # read number of groups - numGroups = struct.unpack("H", file.read(2))[0] - - # read groups - for i in xrange(numGroups): - # skip flags - file.read(1) - - # skip name - file.read(32) - - # read the number of triangles in the group - numGroupTriangles = struct.unpack("H", file.read(2))[0] - - # read the group triangles - if numGroupTriangles > 0: - triangleIndices = struct.unpack(str(numGroupTriangles) + "H", file.read(2*numGroupTriangles)); - - # read material - material = struct.unpack("b", file.read(1))[0] - if material>=0: - for j in xrange(numGroupTriangles): - mesh.faces[triangleIndices[j]].mat = material - - # read the number of materials - numMaterials = struct.unpack("H", file.read(2))[0] - - # read materials - for i in xrange(numMaterials): - # read name - name = uku(file.read(32)) - - # create the material - mat = Blender.Material.New(name) - mesh.materials += [mat] - - # read ambient color - ambient = struct.unpack("ffff", file.read(4*4))[0:3] - mat.setAmb((ambient[0]+ambient[1]+ambient[2])/3) - - # read diffuse color - diffuse = struct.unpack("ffff", file.read(4*4))[0:3] - mat.setRGBCol(diffuse) - - # read specular color - specular = struct.unpack("ffff", file.read(4*4))[0:3] - mat.setSpecCol(specular) - - # read emissive color - emissive = struct.unpack("ffff", file.read(4*4))[0:3] - mat.setEmit((emissive[0]+emissive[1]+emissive[2])/3) - - # read shininess - shininess = struct.unpack("f", file.read(4))[0] - - # read transparency - transparency = struct.unpack("f", file.read(4))[0] - mat.setAlpha(transparency) - if transparency < 1: - mat.mode |= Blender.Material.Modes.ZTRANSP - - # read mode - mode = struct.unpack("B", file.read(1))[0] - - # read texturemap - texturemap = uku(file.read(128)) - if len(texturemap)>0: - colorTexture = Blender.Texture.New(name + "_texture") - colorTexture.setType('Image') - colorTexture.setImage(loadImage(path, texturemap)) - mat.setTexture(0, colorTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.COL) - - # read alphamap - alphamap = uku(file.read(128)) - if len(alphamap)>0: - alphaTexture = Blender.Texture.New(name + "_alpha") - alphaTexture.setType('Image') - alphaTexture.setImage(loadImage(path, alphamap)) - mat.setTexture(1, alphaTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.ALPHA) - - # read animation - fps = struct.unpack("f", file.read(4))[0] - time = struct.unpack("f", file.read(4))[0] - frames = struct.unpack("i", file.read(4))[0] - - # read the number of joints - numJoints = struct.unpack("H", file.read(2))[0] - - # create the armature - armature = 0 - armOb = 0 - if numJoints > 0: - armOb = Blender.Object.New('Armature', "MilkShape3D Skeleton") - armature = Blender.Armature.New("MilkShape3D Skeleton") - armature.drawType = Blender.Armature.STICK - armOb.link(armature) - scn.objects.link(armOb) - armOb.makeParentDeform([meshOb]) - armature.makeEditable() - - # read joints - joints = [] - rotKeys = {} - posKeys = {} - for i in xrange(numJoints): - # skip flags - file.read(1) - - # read name - name = uku(file.read(32)) - joints.append(name) - - # create the bone - bone = Blender.Armature.Editbone() - armature.bones[name] = bone - - # read parent - parent = uku(file.read(32)) - if len(parent)>0: - bone.parent = armature.bones[parent] - - # read orientation - rot = struct.unpack("fff", file.read(3*4)) - - # read position - pos = struct.unpack("fff", file.read(3*4)) - - # set head - if bone.hasParent(): - bone.head = Vector(pos) * bone.parent.matrix + bone.parent.head - tempM = RM(rot) * bone.parent.matrix - tempM.transpose; - bone.matrix = tempM - else: - bone.head = Vector(pos) - bone.matrix = RM(rot) - - # set tail - bvec = bone.tail - bone.head - bvec.normalize() - bone.tail = bone.head + 0.01 * bvec - - # Create vertex group for this bone - mesh.addVertGroup(name) - vgroup = [] - for index, v in enumerate(boneIds): - if v==i: - vgroup.append(index) - mesh.assignVertsToGroup(name, vgroup, 1.0, 1) - - # read the number of rotation keys - numKeyFramesRot = struct.unpack("H", file.read(2))[0] - - # read the number of postions keys - numKeyFramesPos = struct.unpack("H", file.read(2))[0] - - # read rotation keys - rotKeys[name] = [] - for j in xrange(numKeyFramesRot): - # read time - time = fps * struct.unpack("f", file.read(4))[0] - # read data - rotKeys[name].append([time, struct.unpack("fff", file.read(3*4))]) - - # read position keys - posKeys[name] = [] - for j in xrange(numKeyFramesPos): - # read time - time = fps * struct.unpack("f", file.read(4))[0] - # read data - posKeys[name].append([time, struct.unpack("fff", file.read(3*4))]) - - # create action and pose - action = 0 - pose = 0 - if armature!=0: - armature.update() - pose = armOb.getPose() - action = armOb.getAction() - if not action: - action = Blender.Armature.NLA.NewAction() - action.setActive(armOb) - - # create animation key frames - for name, pbone in pose.bones.items(): - # create position keys - for key in posKeys[name]: - pbone.loc = Vector(key[1]) - pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.LOC, True) - - # create rotation keys - for key in rotKeys[name]: - pbone.quat = RQ(key[1]) - pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.ROT, True) - - # The old format ends here. If there is more data then the file is newer version - - # check to see if there are any comments - if file.tell()0: - print "Group comment: " + file.read(size) - - # Material comments - numComments = struct.unpack("i", file.read(4))[0] - for i in range(numComments): - file.read(4) # index - size = struct.unpack("i", file.read(4))[0] # comment size - if size>0: - print "Material comment: " + file.read(size) - - # Joint comments - numComments = struct.unpack("i", file.read(4))[0] - for i in range(numComments): - file.read(4) # index - size = struct.unpack("i", file.read(4))[0] # comment size - if size>0: - print "Joint comment: " + file.read(size) - - # Model comments - numComments = struct.unpack("i", file.read(4))[0] - for i in range(numComments): - file.read(4) # index - size = struct.unpack("i", file.read(4))[0] # comment size - if size>0: - print "Model comment: " + file.read(size) - - # Unknown version give a warning - else: - print "Warning: Unknown version!" - - - # check to see if there is any extra vertex data - if file.tell()=0 or ids[1]>=0 or ids[2]>=0: - mesh.assignVertsToGroup(joints[boneIds[i]], [i], 0.01*weights[0], 1) - if ids[0]>=0: - mesh.assignVertsToGroup(joints[ids[0]], [i], 0.01*weights[1], 1) - if ids[1]>=0: - mesh.assignVertsToGroup(joints[ids[1]], [i], 0.01*weights[2], 1) - if ids[2]>=0: - mesh.assignVertsToGroup(joints[ids[2]], [i], 0.01*(100-(weights[0]+weights[1]+weights[2])), 1) - - elif subVersion==1: - # read extra data for each vertex - for i in xrange(numVertices): - # bone ids - ids = struct.unpack("bbb", file.read(3)) - # weights - weights = struct.unpack("BBB", file.read(3)) - # add extra vertices with weights to deform groups - if ids[0]>=0 or ids[1]>=0 or ids[2]>=0: - mesh.assignVertsToGroup(joints[boneIds[i]], [i], 0.01*weights[0], 1) - if ids[0]>=0: - mesh.assignVertsToGroup(joints[ids[0]], [i], 0.01*weights[1], 1) - if ids[1]>=0: - mesh.assignVertsToGroup(joints[ids[1]], [i], 0.01*weights[2], 1) - if ids[2]>=0: - mesh.assignVertsToGroup(joints[ids[2]], [i], 0.01*(100-(weights[0]+weights[1]+weights[2])), 1) - - # non supported subversion give a warning - else: - print "Warning: Unknown subversion!" - - # rest of the extra data in the file is not imported/used - - # refresh the view - Blender.Redraw() - - # close the file - file.close() - - # succes return empty error string - return "" - - -# load the model -def fileCallback(filename): - error = import_ms3d(filename) - if error!="": - Blender.Draw.PupMenu("An error occured during import: " + error + "|Not all data might have been imported succesfully.", 2) - -Blender.Window.FileSelector(fileCallback, 'Import') diff --git a/release/scripts/ms3d_import_ascii.py b/release/scripts/ms3d_import_ascii.py deleted file mode 100644 index d8c22a1ec99..00000000000 --- a/release/scripts/ms3d_import_ascii.py +++ /dev/null @@ -1,479 +0,0 @@ -#!BPY -""" -Name: 'MilkShape3D ASCII (.txt)...' -Blender: 245 -Group: 'Import' -Tooltip: 'Import from a MilkShape3D ASCII file format (.txt)' -""" -# -# Author: Markus Ilmola -# Email: markus.ilmola@pp.inet.fi -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# - -# import needed stuff -import os.path -import re -import math -from math import * -import Blender -from Blender import Mathutils -from Blender.Mathutils import * - - - -# Converts ms3d euler angles to a rotation matrix -def RM(a): - sy = sin(a[2]) - cy = cos(a[2]) - sp = sin(a[1]) - cp = cos(a[1]) - sr = sin(a[0]) - cr = cos(a[0]) - return Matrix([cp*cy, cp*sy, -sp], [sr*sp*cy+cr*-sy, sr*sp*sy+cr*cy, sr*cp],[cr*sp*cy+-sr*-sy, cr*sp*sy+-sr*cy, cr*cp]) - - -# Converts ms3d euler angles to a quaternion -def RQ(a): - angle = a[2] * 0.5; - sy = sin(angle); - cy = cos(angle); - angle = a[1] * 0.5; - sp = sin(angle); - cp = cos(angle); - angle = a[0] * 0.5; - sr = sin(angle); - cr = cos(angle); - return Quaternion(cr*cp*cy+sr*sp*sy, sr*cp*cy-cr*sp*sy, cr*sp*cy+sr*cp*sy, cr*cp*sy-sr*sp*cy) - - -# takes a texture filename and tries to load it -def loadImage(path, filename): - image = None - try: - image = Blender.Image.Load(os.path.abspath(filename)) - except IOError: - print "Warning: Failed to load image: " + filename + ". Trying short path instead...\n" - try: - image = Blender.Image.Load(os.path.dirname(path) + "/" + os.path.basename(filename)) - except IOError: - print "Warning: Failed to load image: " + os.path.basename(filename) + "!\n" - return image - - - -# returns the next non-empty, non-comment line from the file -def getNextLine(file): - ready = False - while ready==False: - line = file.readline() - if len(line)==0: - print "Warning: End of file reached." - return line - ready = True - line = line.strip() - if len(line)==0 or line.isspace(): - ready = False - if len(line)>=2 and line[0]=='/' and line[1]=='/': - ready = False - return line - - - -# imports a MilkShape3D ascii file to the current scene -def import_ms3d_ascii(path): - # limits - MAX_NUMMESHES = 1000 - MAX_NUMVERTS = 100000 - MAX_NUMNORMALS = 100000 - MAX_NUMTRIS = 100000 - MAX_NUMMATS = 16 - MAX_NUMBONES = 100 - MAX_NUMPOSKEYS = 1000 - MAX_NUMROTKEYS = 1000 - - # get scene - scn = Blender.Scene.GetCurrent() - if scn==None: - return "No scene to import to!" - - # open the file - try: - file = open(path, 'r') - except IOError: - return "Failed to open the file!" - - # Read frame info - try: - lines = getNextLine(file).split() - if len(lines) != 2 or lines[0] != "Frames:": - raise ValueError - lines = getNextLine(file).split() - if len(lines) != 2 or lines[0] != "Frame:": - raise ValueError - except ValueError: - return "Frame information is invalid!" - - # Create the mesh - meshOb = Blender.Object.New('Mesh', "MilkShape3D Object") - mesh = Blender.Mesh.New("MilkShape3D Mesh") - meshOb.link(mesh) - scn.objects.link(meshOb) - - # read the number of meshes - try: - lines = getNextLine(file).split() - if len(lines)!=2 or lines[0]!="Meshes:": - raise ValueError - numMeshes = int(lines[1]) - if numMeshes < 0 or numMeshes > MAX_NUMMESHES: - raise ValueError - except ValueError: - return "Number of meshes is invalid!" - - # read meshes - vertBase = 0 - faceBase = 0 - boneIds = [] - for i in range(numMeshes): - # read name, flags and material - try: - lines = re.findall(r'\".*\"|[^ ]+', getNextLine(file)) - if len(lines)!=3: - raise ValueError - material = int(lines[2]) - except ValueError: - return "Name, flags or material in mesh " + str(i+1) + " are invalid!" - - # read the number of vertices - try: - numVerts = int(getNextLine(file)) - if numVerts < 0 or numVerts > MAX_NUMVERTS: - raise ValueError - except ValueError: - return "Number of vertices in mesh " + str(i+1) + " is invalid!" - - # read vertices - coords = [] - uvs = [] - for j in xrange(numVerts): - try: - lines = getNextLine(file).split() - if len(lines)!=7: - raise ValueError - coords.append([float(lines[1]), float(lines[2]), float(lines[3])]) - uvs.append([float(lines[4]), 1-float(lines[5])]) - boneIds.append(int(lines[6])) - except ValueError: - return "Vertex " + str(j+1) + " in mesh " + str(i+1) + " is invalid!" - mesh.verts.extend(coords) - - # read number of normals - try: - numNormals = int(getNextLine(file)) - if numNormals < 0 or numNormals > MAX_NUMNORMALS: - raise ValueError - except ValueError: - return "Number of normals in mesh " + str(i+1) + " is invalid!" - - # read normals - normals = [] - for j in xrange(numNormals): - try: - lines = getNextLine(file).split() - if len(lines)!=3: - raise ValueError - normals.append([float(lines[0]), float(lines[1]), float(lines[2])]) - except ValueError: - return "Normal " + str(j+1) + " in mesh " + str(i+1) + " is invalid!" - - # read the number of triangles - try: - numTris = int(getNextLine(file)) - if numTris < 0 or numTris > MAX_NUMTRIS: - raise ValueError - except ValueError: - return "Number of triangles in mesh " + str(i+1) + " is invalid!" - - # read triangles - faces = [] - for j in xrange(numTris): - # read the triangle - try: - lines = getNextLine(file).split() - if len(lines)!=8: - raise ValueError - v1 = int(lines[1]) - v2 = int(lines[2]) - v3 = int(lines[3]) - faces.append([v1+vertBase, v2+vertBase, v3+vertBase]) - except ValueError: - return "Triangle " + str(j+1) + " in mesh " + str(i+1) + " is invalid!" - mesh.faces.extend(faces) - - # set texture coordinates and material - for j in xrange(faceBase, len(mesh.faces)): - face = mesh.faces[j] - face.uv = [Vector(uvs[face.verts[0].index-vertBase]), Vector(uvs[face.verts[1].index-vertBase]), Vector(uvs[face.verts[2].index-vertBase])] - if material>=0: - face.mat = material - - # increase vertex and face base - vertBase = len(mesh.verts) - faceBase = len(mesh.faces) - - # read the number of materials - try: - lines = getNextLine(file).split() - if len(lines)!=2 or lines[0]!="Materials:": - raise ValueError - numMats = int(lines[1]) - if numMats < 0 or numMats > MAX_NUMMATS: - raise ValueError - except ValueError: - return "Number of materials is invalid!" - - # read the materials - for i in range(numMats): - # read name - name = getNextLine(file)[1:-1] - - # create the material - mat = Blender.Material.New(name) - mesh.materials += [mat] - - # read ambient color - try: - lines = getNextLine(file).split() - if len(lines)!=4: - raise ValueError - amb = (float(lines[0])+float(lines[1])+float(lines[2]))/3 - mat.setAmb(amb) - except ValueError: - return "Ambient color in material " + str(i+1) + " is invalid!" - - # read diffuse color - try: - lines = getNextLine(file).split() - if len(lines)!=4: - raise ValueError - mat.setRGBCol([float(lines[0]), float(lines[1]), float(lines[2])]) - except ValueError: - return "Diffuse color in material " + str(i+1) + " is invalid!" - - # read specular color - try: - lines = getNextLine(file).split() - if len(lines)!=4: - raise ValueError - mat.setSpecCol([float(lines[0]), float(lines[1]), float(lines[2])]) - except ValueError: - return "Specular color in material " + str(i+1) + " is invalid!" - - # read emissive color - try: - lines = getNextLine(file).split() - if len(lines)!=4: - raise ValueError - emit = (float(lines[0])+float(lines[1])+float(lines[2]))/3 - mat.setEmit(emit) - except ValueError: - return "Emissive color in material " + str(i+1) + " is invalid!" - - # read shininess - try: - shi = float(getNextLine(file)) - #mat.setHardness(int(shi)) - except ValueError: - return "Shininess in material " + str(i+1) + " is invalid!" - - # read transparency - try: - alpha = float(getNextLine(file)) - mat.setAlpha(alpha) - if alpha < 1: - mat.mode |= Blender.Material.Modes.ZTRANSP - except ValueError: - return "Transparency in material " + str(i+1) + " is invalid!" - - # read texturemap - texturemap = getNextLine(file)[1:-1] - if len(texturemap)>0: - colorTexture = Blender.Texture.New(name + "_texture") - colorTexture.setType('Image') - colorTexture.setImage(loadImage(path, texturemap)) - mat.setTexture(0, colorTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.COL) - - # read alphamap - alphamap = getNextLine(file)[1:-1] - if len(alphamap)>0: - alphaTexture = Blender.Texture.New(name + "_alpha") - alphaTexture.setType('Image') - alphaTexture.setImage(loadImage(path, alphamap)) - mat.setTexture(1, alphaTexture, Blender.Texture.TexCo.UV, Blender.Texture.MapTo.ALPHA) - - # read the number of bones - try: - lines = getNextLine(file).split() - if len(lines)!=2 or lines[0]!="Bones:": - raise ValueError - numBones = int(lines[1]) - if numBones < 0 or numBones > MAX_NUMBONES: - raise ValueError - except: - return "Number of bones is invalid!" - - # create the armature - armature = None - armOb = None - if numBones > 0: - armOb = Blender.Object.New('Armature', "MilkShape3D Skeleton") - armature = Blender.Armature.New("MilkShape3D Skeleton") - armature.drawType = Blender.Armature.STICK - armOb.link(armature) - scn.objects.link(armOb) - armOb.makeParentDeform([meshOb]) - armature.makeEditable() - - # read bones - posKeys = {} - rotKeys = {} - for i in range(numBones): - # read name - name = getNextLine(file)[1:-1] - - # create the bone - bone = Blender.Armature.Editbone() - armature.bones[name] = bone - - # read parent - parent = getNextLine(file)[1:-1] - if len(parent)>0: - bone.parent = armature.bones[parent] - - # read position and rotation - try: - lines = getNextLine(file).split() - if len(lines) != 7: - raise ValueError - pos = [float(lines[1]), float(lines[2]), float(lines[3])] - rot = [float(lines[4]), float(lines[5]), float(lines[6])] - except ValueError: - return "Invalid position or orientation in a bone!" - - # set position and orientation - if bone.hasParent(): - bone.head = Vector(pos) * bone.parent.matrix + bone.parent.head - bone.tail = bone.head + Vector([1,0,0]) - tempM = RM(rot) * bone.parent.matrix - tempM.transpose; - bone.matrix = tempM - else: - bone.head = Vector(pos) - bone.tail = bone.head + Vector([1,0,0]) - bone.matrix = RM(rot) - - # Create vertex group for this bone - mesh.addVertGroup(name) - vgroup = [] - for index, v in enumerate(boneIds): - if v==i: - vgroup.append(index) - mesh.assignVertsToGroup(name, vgroup, 1.0, 1) - - # read the number of position key frames - try: - numPosKeys = int(getNextLine(file)) - if numPosKeys < 0 or numPosKeys > MAX_NUMPOSKEYS: - raise ValueError - except ValueError: - return "Invalid number of position key frames!" - - # read position key frames - posKeys[name] = [] - for j in range(numPosKeys): - # read time and position - try: - lines = getNextLine(file).split() - if len(lines) != 4: - raise ValueError - time = float(lines[0]) - pos = [float(lines[1]), float(lines[2]), float(lines[3])] - posKeys[name].append([time, pos]) - except ValueError: - return "Invalid position key frame!" - - # read the number of rotation key frames - try: - numRotKeys = int(getNextLine(file)) - if numRotKeys < 0 or numRotKeys > MAX_NUMROTKEYS: - raise ValueError - except ValueError: - return "Invalid number of rotation key frames!" - - # read rotation key frames - rotKeys[name] = [] - for j in range(numRotKeys): - # read time and rotation - try: - lines = getNextLine(file).split() - if len(lines) != 4: - raise ValueError - time = float(lines[0]) - rot = [float(lines[1]), float(lines[2]), float(lines[3])] - rotKeys[name].append([time, rot]) - except ValueError: - return "Invalid rotation key frame!" - - # create action and pose - action = None - pose = None - if armature != None: - armature.update() - pose = armOb.getPose() - action = armOb.getAction() - if not action: - action = Blender.Armature.NLA.NewAction() - action.setActive(armOb) - - # create animation key frames - for name, pbone in pose.bones.items(): - # create position keys - for key in posKeys[name]: - pbone.loc = Vector(key[1]) - pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.LOC, True) - - # create rotation keys - for key in rotKeys[name]: - pbone.quat = RQ(key[1]) - pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.ROT, True) - - # set the imported object to be the selected one - scn.objects.selected = [] - meshOb.sel= 1 - Blender.Redraw() - - # The import was a succes! - return "" - - -# load the model -def fileCallback(filename): - error = import_ms3d_ascii(filename) - if error!="": - Blender.Draw.PupMenu("An error occured during import: " + error + "|Not all data might have been imported succesfully.", 2) - -Blender.Window.FileSelector(fileCallback, 'Import') diff --git a/release/scripts/obdatacopier.py b/release/scripts/obdatacopier.py deleted file mode 100644 index 2f5617951de..00000000000 --- a/release/scripts/obdatacopier.py +++ /dev/null @@ -1,215 +0,0 @@ -#!BPY - -""" Registration info for Blender menus: <- these words are ignored -Name: 'Data Copier' -Blender: 232 -Group: 'Object' -Tip: 'Copy data from active object to other selected ones.' -""" - -__author__ = "Jean-Michel Soler (jms), Campbell Barton (Ideasman42)" -__url__ = ("blender", "blenderartists.org", -"Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm", -"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "0.1.2" - -__bpydoc__ = """\ -Use "Data Copier" to copy attributes from the active object to other selected ones of -its same type. - -This script is still in an early version but is already useful for copying -attributes for some types of objects like lamps and cameras. - -Usage: - -Select the objects that will be updated, select the object whose data will -be copied (they must all be of the same type, of course), then run this script. -Toggle the buttons representing the attributes to be copied and press "Copy". -""" - -# ---------------------------------------------------------- -# Object DATA copier 0.1.2 -# (c) 2004 jean-michel soler -# ----------------------------------------------------------- -#---------------------------------------------- -# Page officielle/official page du blender python Object DATA copier: -# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm -# Communiquer les problemes et erreurs sur: -# To Communicate problems and errors on: -# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender -#--------------------------------------------- -# Blender Artistic License -# http://download.blender.org/documentation/html/x21254.html -#--------------------------------------------- - -import Blender -from Blender import * -from Blender.Draw import * -from Blender.BGL import * - - -scn= Blender.Scene.GetCurrent() - -type_func_method= type(dir) -type_func= type(lambda:i) -type_dict= type({}) -# type_list= type([]) - -IGNORE_VARS = 'users', 'fakeUser', 'edges', 'faces', 'verts', 'elements' - -def renew(): - scn= Blender.Scene.GetCurrent() - act_ob= scn.objects.active - if act_ob==None: - return {} - - act_ob_type= act_ob.getType() - act_ob_data= act_ob.getData(mesh=1) - - if act_ob_data==None: # Surf? - return {} - - PARAM={} - evt=4 - doc='doc' - - for prop_name in dir(act_ob_data): - if not prop_name.startswith('__') and prop_name not in IGNORE_VARS: - # Get the type - try: exec 'prop_type= type(act_ob_data.%s)' % prop_name - except: prop_type= None - - if prop_type != None and prop_type not in (type_func_method, type_func, type_dict): - - # Now we know that the attribute can be listed in the UI Create a button and tooltip. - - # Tooltip - try: - if prop_name=='mode': - try: - exec "doc=str(%s.Modes)+' ; value : %s'"%( act_ob_type, str(act_ob_data.mode) ) - except: - exec """doc= '%s'+' value = '+ str(act_ob.getData(mesh=1).%s)"""%(prop_name, prop_name) - elif prop_name=='type': - try: - exec "doc=str(%s.Types)+' ; value : %s'"%( act_ob_type, str(act_ob_data.type) ) - except: - exec """doc= '%s'+' value = '+ str(act_ob.getData(mesh=1).%s)"""%(prop_name, prop_name) - else: - exec """doc= '%s'+' value = '+ str(act_ob_data.%s)"""%(prop_name, prop_name) - if doc.find('built-in')!=-1: - exec """doc= 'This is a function ! Doc = '+ str(act_ob_data.%s.__doc__)"""% prop_name - except: - doc='Doc...' - - # Button - PARAM[prop_name]= [Create(0), evt, doc] - evt+=1 - - return PARAM - -def copy(): - global PARAM - - scn= Blender.Scene.GetCurrent() - act_ob= scn.getActiveObject() - if act_ob==None: - Blender.Draw.PupMenu('Error|No Active Object.') - return - - act_ob_type= act_ob.getType() - - if act_ob_type in ('Empty', 'Surf'): - Blender.Draw.PupMenu('Error|Copying Empty or Surf object data isnt supported.') - return - - act_ob_data= act_ob.getData(mesh=1) - - print '\n\nStarting copy for object "%s"' % act_ob.name - some_errors= False - for ob in scn.objects.context: - if ob != act_ob and ob.getType() == act_ob_type: - ob_data= None - for prop_name, value in PARAM.iteritems(): - if value[0].val==1: - - # Init the object data if we havnt alredy - if ob_data==None: - ob_data= ob.getData(mesh=1) - - try: - exec "ob_data.%s = act_ob_data.%s"%(prop_name, prop_name) - except: - some_errors= True - print 'Cant copy property "%s" for type "%s"' % (prop_name, act_ob_type) - if some_errors: - Blender.Draw.PupMenu('Some attributes could not be copied, see console for details.') - -PARAM= renew() - -def EVENT(evt,val): - pass - -def BUTTON(evt): - global PARAM - if (evt==1): - Exit() - - if (evt==2): - copy() - Blender.Redraw() - - if (evt==3): - PARAM= renew() - Blender.Redraw() - -def DRAW(): - global PARAM - - scn= Blender.Scene.GetCurrent() - act_ob= scn.objects.active - - glColor3f(0.7, 0.7, 0.7) - glClear(GL_COLOR_BUFFER_BIT) - glColor3f(0.1, 0.1, 0.15) - - size=Buffer(GL_FLOAT, 4) - glGetFloatv(GL_SCISSOR_BOX, size) - size= size.list - for s in [0,1,2,3]: size[s]=int(size[s]) - ligne=20 - - Button("Exit",1,20,4,80,ligne) - Button("Copy",2,102,4,80,ligne) - Button("Renew",3,184,4,80,ligne) - - glRasterPos2f(20, ligne*2-8) - if act_ob: - Text(act_ob.getType()+" DATA copier") - else: - Text("Please select an object") - - - max=size[3] / 22 -2 - pos = 0 - decal = 20 - key=PARAM.keys() - key.sort() - for p in key: - if pos==max: - decal+=102 - pos=1 - else: - pos+=1 - - PARAM[p][0]=Toggle(p, - PARAM[p][1], - decal, - pos*22+22, - 100, - 20, - PARAM[p][0].val, - str(PARAM[p][2])) - - -Register(DRAW,EVENT,BUTTON) diff --git a/release/scripts/object_active_to_other.py b/release/scripts/object_active_to_other.py deleted file mode 100644 index 68aa6a3a039..00000000000 --- a/release/scripts/object_active_to_other.py +++ /dev/null @@ -1,58 +0,0 @@ -#!BPY -""" -Name: 'Copy Active to Selected' -Blender: 249 -Group: 'Object' -Tooltip: 'For every selected object, copy the active to their loc/size/rot' -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - - -from Blender import Window, sys, Draw -import bpy - -def my_object_util(sce): - ob_act = sce.objects.active - - if not ob_act: - Draw.PupMenu('Error%t|No active object selected') - return - - mats = [(ob, ob.matrixWorld) for ob in sce.objects.context if ob != ob_act] - - for ob, m in mats: - ob_copy = ob_act.copy() - sce.objects.link(ob_copy) - ob_copy.setMatrix(m) - ob_copy.Layers = ob.Layers & (1<<20)-1 - - -def main(): - sce = bpy.data.scenes.active - - Window.WaitCursor(1) - my_object_util(sce) - Window.WaitCursor(0) - -if __name__ == '__main__': - main() diff --git a/release/scripts/object_apply_def.py b/release/scripts/object_apply_def.py deleted file mode 100644 index 006e97463d8..00000000000 --- a/release/scripts/object_apply_def.py +++ /dev/null @@ -1,178 +0,0 @@ -#!BPY - -""" -Name: 'Apply Deformation' -Blender: 242 -Group: 'Object' -Tooltip: 'Make copys of all the selected objects with modifiers, softbodies and fluid baked into a mesh' -""" - -__author__ = "Martin Poirier (theeth), Jean-Michel Soler (jms), Campbell Barton (ideasman)" -# This script is the result of merging the functionalities of two other: -# Martin Poirier's Apply_Def.py and -# Jean-Michel Soler's Fix From Everything - -__url__ = ("http://www.blender.org", "http://blenderartists.org", "http://jmsoler.free.fr") -__version__ = "1.6 07/07/2006" - -__bpydoc__ = """\ -This script creates "raw" copies of deformed meshes. - -Usage: - -Select any number of Objects and run this script. A fixed copy of each selected object -will be created, with the word "_def" appended to its name. If an object with -the same name already exists, it appends a number at the end as Blender itself does. - -Objects in Blender can be deformed by armatures, lattices, curve objects and subdivision, -but this will only change its appearance on screen and rendered -images -- the actual mesh data is still simpler, with vertices in an original -"rest" position and less vertices than the subdivided version. - -Use this script if you want a "real" version of the deformed mesh, so you can -directly manipulate or export its data. - -This script will work with object types: Mesh, Metaballs, Text3d, Curves and Nurbs Surface. -""" - - -# $Id$ -# -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2003: Martin Poirier, theeth@yahoo.com -# -# Thanks to Jonathan Hudson for help with the vertex groups part -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** - - -import Blender -import bpy -import BPyMesh - -def copy_vgroups(source_ob, target_ob): - - source_me = source_ob.getData(mesh=1) - - vgroups= source_me.getVertGroupNames() - if vgroups: - ADD= Blender.Mesh.AssignModes.ADD - target_me = target_ob.getData(mesh=1) - for vgroupname in vgroups: - target_me.addVertGroup(vgroupname) - if len(target_me.verts) == len(source_me.verts): - try: # in rare cases this can raise an 'no deform groups assigned to mesh' error - vlist = source_me.getVertsFromGroup(vgroupname, True) - except: - vlist = [] - - try: - for vpair in vlist: - target_me.assignVertsToGroup(vgroupname, [vpair[0]], vpair[1], ADD) - except: - pass - - -def apply_deform(): - scn= bpy.data.scenes.active - #Blender.Window.EditMode(0) - - NAME_LENGTH = 19 - SUFFIX = "_def" - SUFFIX_LENGTH = len(SUFFIX) - # Get all object and mesh names - - - ob_list = list(scn.objects.context) - ob_act = scn.objects.active - - # Assume no soft body - has_sb= False - - # reverse loop so we can remove objects (metaballs in this case) - for ob_idx in xrange(len(ob_list)-1, -1, -1): - ob= ob_list[ob_idx] - - ob.sel = 0 # deselect while where checking the metaballs - - # Test for a softbody - if not has_sb and ob.isSB(): - has_sb= True - - # Remove all numbered metaballs because their disp list is only on the main metaball (un numbered) - if ob.type == 'MBall': - name= ob.name - # is this metaball numbered? - dot_idx= name.rfind('.') + 1 - if name[dot_idx:].isdigit(): - # Not the motherball, ignore it. - del ob_list[ob_idx] - - - if not ob_list: - Blender.Draw.PupMenu('No objects selected, nothing to do.') - return - - - if has_sb: - curframe=Blender.Get('curframe') - for f in xrange(curframe): - Blender.Set('curframe',f+1) - Blender.Window.RedrawAll() - - used_names = [ob.name for ob in Blender.Object.Get()] - used_names.extend(Blender.NMesh.GetNames()) - - - deformedList = [] - for ob in ob_list: - - # Get the mesh data - new_me= BPyMesh.getMeshFromObject(ob, vgroups=False) - - if not new_me: - continue # Object has no display list - - - name = ob.name - new_name = "%s_def" % name[:NAME_LENGTH-SUFFIX_LENGTH] - num = 0 - - while new_name in used_names: - new_name = "%s_def.%.3i" % (name[:NAME_LENGTH-(SUFFIX_LENGTH+SUFFIX_LENGTH)], num) - num += 1 - used_names.append(new_name) - - new_me.name= new_name - - new_ob= scn.objects.new(new_me) - new_ob.setMatrix(ob.matrixWorld) - - # Make the active duplicate also active - if ob == ob_act: - scn.objects.active = new_ob - - # Original object was a mesh? see if we can copy any vert groups. - if ob.type =='Mesh': - copy_vgroups(ob, new_ob) - - Blender.Window.RedrawAll() - -if __name__=='__main__': - apply_deform() diff --git a/release/scripts/object_batch_name_edit.py b/release/scripts/object_batch_name_edit.py deleted file mode 100644 index 4db3a6210db..00000000000 --- a/release/scripts/object_batch_name_edit.py +++ /dev/null @@ -1,274 +0,0 @@ -#!BPY -""" -Name: 'Batch Object Name Edit' -Blender: 240 -Group: 'Object' -Tooltip: 'Apply the chosen rule to rename all selected objects at once.' -""" -__author__ = "Campbell Barton" -__url__ = ("blender", "blenderartists.org") -__version__ = "1.0" - -__bpydoc__ = """\ -"Batch Object Name Edit" allows you to change multiple names of Blender -objects at once. It provides options to define if you want to: replace text -in the current names, truncate their beginnings or endings or prepend / append -strings to them. - -Usage: -Select the objects to be renamed and run this script from the Object->Scripts -menu of the 3d View. -""" -# $Id$ -# -# -------------------------------------------------------------------------- -# Batch Name Edit by Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- -from Blender import * -import bpy - -global renameCount -renameCount = 0 -obsel = [ob for ob in bpy.data.scenes.active.objects.context if not ob.lib] - -def setDataNameWrapper(ob, newname): - if ob.getData(name_only=1) == newname: - return False - - data= ob.getData(mesh=1) - - if data and not data.lib: - data.name= newname - return True - return False - -def main(): - global renameCount - # Rename the datablocks that are used by the object. - def renameLinkedDataFromObject(): - - # Result 1, we want to rename data - for ob in obsel: - if ob.name == ob.getData(name_only=1): - return # Alredy the same name, dont bother. - - data = ob.getData(mesh=1) # use mesh so we dont have to update the nmesh. - if data and not data.lib: - data.name = ob.name - - - def new(): - global renameCount - NEW_NAME_STRING = Draw.Create('') - RENAME_LINKED = Draw.Create(0) - pup_block = [\ - ('New Name: ', NEW_NAME_STRING, 19, 19, 'New Name'),\ - ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\ - ] - - if not Draw.PupBlock('Replace in name...', pup_block): - return 0 - - NEW_NAME_STRING= NEW_NAME_STRING.val - - Window.WaitCursor(1) - for ob in obsel: - if ob.name != NEW_NAME_STRING: - ob.name = NEW_NAME_STRING - renameCount+=1 - - return RENAME_LINKED.val - - def replace(): - global renameCount - REPLACE_STRING = Draw.Create('') - WITH_STRING = Draw.Create('') - RENAME_LINKED = Draw.Create(0) - - pup_block = [\ - ('Replace: ', REPLACE_STRING, 19, 19, 'Text to find'),\ - ('With:', WITH_STRING, 19, 19, 'Text to replace with'),\ - ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\ - ] - - if not Draw.PupBlock('Replace in name...', pup_block) or\ - ((not REPLACE_STRING.val) and (not WITH_STRING)): - return 0 - - REPLACE_STRING = REPLACE_STRING.val - WITH_STRING = WITH_STRING.val - - Window.WaitCursor(1) - for ob in obsel: - newname = ob.name.replace(REPLACE_STRING, WITH_STRING) - if ob.name != newname: - ob.name = newname - renameCount+=1 - return RENAME_LINKED.val - - - def prefix(): - global renameCount - PREFIX_STRING = Draw.Create('') - RENAME_LINKED = Draw.Create(0) - - pup_block = [\ - ('Prefix: ', PREFIX_STRING, 19, 19, 'Name prefix'),\ - ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\ - ] - - if not Draw.PupBlock('Prefix...', pup_block) or\ - not PREFIX_STRING.val: - return 0 - - PREFIX_STRING = PREFIX_STRING.val - - Window.WaitCursor(1) - for ob in obsel: - ob.name = PREFIX_STRING + ob.name - renameCount+=1 # we knows these are different. - return RENAME_LINKED.val - - def suffix(): - global renameCount - SUFFIX_STRING = Draw.Create('') - RENAME_LINKED = Draw.Create(0) - - pup_block = [\ - ('Suffix: ', SUFFIX_STRING, 19, 19, 'Name suffix'),\ - ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\ - ] - - if not Draw.PupBlock('Suffix...', pup_block) or\ - not SUFFIX_STRING.val: - return 0 - - SUFFIX_STRING = SUFFIX_STRING.val - - Window.WaitCursor(1) - for ob in obsel: - ob.name = ob.name + SUFFIX_STRING - renameCount+=1 # we knows these are different. - return RENAME_LINKED.val - - def truncate_start(): - global renameCount - TRUNCATE_START = Draw.Create(0) - RENAME_LINKED = Draw.Create(0) - - pup_block = [\ - ('Truncate Start: ', TRUNCATE_START, 0, 19, 'Truncate chars from the start of the name'),\ - ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\ - ] - - if not Draw.PupBlock('Truncate Start...', pup_block) or\ - not TRUNCATE_START.val: - return 0 - - Window.WaitCursor(1) - TRUNCATE_START = TRUNCATE_START.val - for ob in obsel: - newname = ob.name[TRUNCATE_START: ] - ob.name = newname - renameCount+=1 - - return RENAME_LINKED.val - - def truncate_end(): - global renameCount - TRUNCATE_END = Draw.Create(0) - RENAME_LINKED = Draw.Create(0) - - pup_block = [\ - ('Truncate End: ', TRUNCATE_END, 0, 19, 'Truncate chars from the end of the name'),\ - ('Rename ObData', RENAME_LINKED, 'Renames objects data to match the obname'),\ - ] - - if not Draw.PupBlock('Truncate End...', pup_block) or\ - not TRUNCATE_END.val: - return 0 - - Window.WaitCursor(1) - TRUNCATE_END = TRUNCATE_END.val - for ob in obsel: - newname = ob.name[: -TRUNCATE_END] - ob.name = newname - renameCount+=1 - - return RENAME_LINKED.val - - def renameObjectFromLinkedData(): - global renameCount - Window.WaitCursor(1) - - for ob in obsel: - newname = ob.getData(name_only=1) - if newname != None and ob.name != newname: - ob.name = newname - renameCount+=1 - return 0 - - def renameObjectFromDupGroup(): - global renameCount - Window.WaitCursor(1) - - for ob in obsel: - group= ob.DupGroup - if group != None: - newname= group.name - if newname != ob.name: - ob.name = newname - renameCount+=1 - return 0 - - def renameLinkedDataFromObject(): - global renameCount - Window.WaitCursor(1) - - for ob in obsel: - if setDataNameWrapper(ob, ob.name): - renameCount+=1 - return 0 - - name = "Selected Object Names%t|New Name|Replace Text|Add Prefix|Add Suffix|Truncate Start|Truncate End|Rename Objects to Data Names|Rename Objects to DupGroup Names|Rename Data to Object Names" - result = Draw.PupMenu(name) - renLinked = 0 # Rename linked data to the object name? - if result == -1: - return - elif result == 1: renLinked= new() - elif result == 2: renLinked= replace() - elif result == 3: renLinked= prefix() - elif result == 4: renLinked= suffix() - elif result == 5: renLinked= truncate_start() - elif result == 6: renLinked= truncate_end() - elif result == 7: renameObjectFromLinkedData() - elif result == 8: renameObjectFromDupGroup() - elif result == 9: renameLinkedDataFromObject() - - if renLinked: - renameLinkedDataFromObject() - - Window.WaitCursor(0) - - Draw.PupMenu('renamed: %d objects.' % renameCount) - -if __name__=='__main__': - main() diff --git a/release/scripts/object_cookie_cutter.py b/release/scripts/object_cookie_cutter.py deleted file mode 100644 index 4950c18c0f4..00000000000 --- a/release/scripts/object_cookie_cutter.py +++ /dev/null @@ -1,667 +0,0 @@ -#!BPY -""" -Name: 'Cookie Cut from View' -Blender: 234 -Group: 'Object' -Tooltip: 'Cut from the view axis, (Sel 3d Curves and Meshes (only edges) into other meshes with faces)' -""" -__author__= "Campbell Barton" -__url__= ["blender", "blenderartist"] -__version__= "1.0" - -__bpydoc__= """\ -This script takes the selected mesh objects, divides them into 2 groups -Cutters and The objects to be cut. - -Cutters are meshes with no faces, just edge loops. and any meshes with faces will be cut. - -Usage: - -Select 2 or more meshes, one with no faces (a closed polyline) and one with faces to cut. - -Align the view on the axis you want to cut. -For shapes that have overlapping faces (from the view), hide any backfacing faces so they will be ignored during the cut. -Run the script. - -You can choose to make the cut verts lie on the face that they were cut from or on the edge that cut them. -This script supports UV coordinates and images. -""" - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Script copyright (C) Campbell Barton -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -import Blender -from math import sqrt -import BPyMesh -Vector= Blender.Mathutils.Vector -LineIntersect2D= Blender.Geometry.LineIntersect2D -PointInTriangle2D= Blender.Geometry.PointInTriangle2D - -# Auto class -def auto_class(slots): - exec('class container_class(object): __slots__=%s' % slots) - return container_class - - -bignum= 1<<30 -def bounds_xy(iter_item): - ''' - Works with types - MMesh.verts - MFace - MEdge - ''' - xmin= ymin= bignum - xmax= ymax= -bignum - for v in iter_item: - x= v.co.x - y= v.co.y - if xxmax: xmax= x - if y>ymax: ymax= y - - return xmin, ymin, xmax, ymax - -def bounds_intersect(a,b): - ''' - each tuple is - xmin, ymin, xmax, ymax - ''' - if\ - a[0]>b[2] or\ - a[1]>b[3] or\ - a[2]i2: - i1,i2= i2,i1 - return i1, i2 - -def sorted_indicies(i1, i2): - if i1>i2: - i1,i2= i2,i1 - return i1, i2 - -def fake_length2d(pt1, pt2): - ''' - Only used for comparison so don't sqrt - ''' - #return math.sqrt(abs(pow(x1-x2, 2)+ pow(y1-y2, 2))) - return pow(pt1[0]-pt2[0], 2) + pow(pt1[1]- pt2[1], 2) - -def length2d(pt1, pt2): - ''' - Only used for comparison so don't sqrt - ''' - #return math.sqrt(abs(pow(x1-x2, 2)+ pow(y1-y2, 2))) - return sqrt(pow(pt1[0]-pt2[0], 2) + pow(pt1[1]- pt2[1], 2)) - - - -def tri_area_2d(v1, v2, v3): - e1 = length2d(v1, v2) - e2 = length2d(v2, v3) - e3 = length2d(v3, v1) - p = e1+e2+e3 - return 0.25 * sqrt(abs(p*(p-2*e1)*(p-2*e2)*(p-2*e3))) - -def tri_pt_find_z_2d(pt, tri): - """ Takes a face and 3d vector and assigns the vectors Z to its on the face""" - - l1= tri_area_2d(tri[1], tri[2], pt) - l2= tri_area_2d(tri[0], tri[2], pt) - l3= tri_area_2d(tri[0], tri[1], pt) - - tot= l1+l2+l3 - # Normalize - l1=l1/tot - l2=l2/tot - l3=l3/tot - - z1= tri[0].z*l1 - z2= tri[1].z*l2 - z3= tri[2].z*l3 - - return z1+z2+z3 - - -def tri_pt_find_uv_2d(pt, tri, uvs): - """ Takes a face and 3d vector and assigns the vectors Z to its on the face""" - - l1= tri_area_2d(tri[1], tri[2], pt) - l2= tri_area_2d(tri[0], tri[2], pt) - l3= tri_area_2d(tri[0], tri[1], pt) - - tot= l1+l2+l3 - if not tot: # No area, just return the first uv - return Vector(uvs[0]) - - # Normalize - l1=l1/tot - l2=l2/tot - l3=l3/tot - - uv1= uvs[0]*l1 - uv2= uvs[1]*l2 - uv3= uvs[2]*l3 - - return uv1+uv2+uv3 - - - - -def mesh_edge_dict(me): - ed_dict= {} - for f in me.faces: - if not f.hide: - for edkey in f.edge_keys: - ed_dict.setdefault(edkey, []).append(f) - - return ed_dict - - - -def terrain_cut_2d(t, c, PREF_Z_LOC): - ''' - t is the terrain - c is the cutter - - PREF_Z_LOC: 0 - from terrain face - 1 - from cutter edge - - returns nothing - ''' - - # do we have a 2d intersection - if not bounds_intersect(t.bounds, c.bounds): - return - - # Local vars - me_t= t.mesh - me_c= c.mesh - - has_uv= me_t.faceUV - - Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX']) - ''' - first assign a face terrain face for each cutter verticie - ''' - cut_verts_temp= list(me_c.verts) - cut_vert_terrain_faces= [None] * len(me_c.verts) - vert_z_level= [-10.0] * len(me_c.verts) - - for v in me_c.verts: - v_index= v.index - v_co= v.co - for fidx, f in enumerate(me_t.faces): - if not f.hide: - if point_in_bounds(v_co, t.face_bounds[fidx]): - f_v= [vv.co for vv in f] - if point_in_poly2d(v_co, f_v): - - - if PREF_Z_LOC==0: - ''' - Get the z location from the face. - ''' - - if len(f_v)==3: - vert_z_level[v_index]= tri_pt_find_z_2d(v_co, (f_v[0], f_v[1], f_v[2]) ) - else: - # Quad, which side are we on? - a1= tri_area_2d(f_v[0], f_v[1], v_co) - a2= tri_area_2d(f_v[1], f_v[2], v_co) - - a3= tri_area_2d(f_v[0], f_v[1], f_v[2]) - - if a1+a2
- - @@ -1548,6 +1544,26 @@ > + + + + + + + + + + diff --git a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj index b52cf929fc3..66449b01f81 100644 --- a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj +++ b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj @@ -43,7 +43,7 @@ Date: Wed, 30 Sep 2009 21:31:08 +0000 Subject: building without bullet didnt work --- source/blender/blenkernel/intern/collision.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index aa4aae2422c..20fc1708454 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -45,9 +45,9 @@ #include "BKE_modifier.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" - +#ifdef USE_BULLET #include "Bullet-C-Api.h" - +#endif #include "BLI_kdopbvh.h" #include "BKE_collision.h" -- cgit v1.2.3 From bff893a42047cfc92671f878109c1ff17ce5f8a2 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 30 Sep 2009 22:10:14 +0000 Subject: Unified effector functionality for particles, cloth and softbody * Unified scene wide gravity (currently in scene buttons) instead of each simulation having it's own gravity. * Weight parameters for all effectors and an effector group setting. * Every effector can use noise. * Most effectors have "shapes" point, plane, surface, every point. - "Point" is most like the old effectors and uses the effector location as the effector point. - "Plane" uses the closest point on effectors local xy-plane as the effector point. - "Surface" uses the closest point on an effector object's surface as the effector point. - "Every Point" uses every point in a mesh effector object as an effector point. - The falloff is calculated from this point, so for example with "surface" shape and "use only negative z axis" it's possible to apply force only "inside" the effector object. * Spherical effector is now renamed as "force" as it's no longer just spherical. * New effector parameter "flow", which makes the effector act as surrounding air velocity, so the resulting force is proportional to the velocity difference of the point and "air velocity". For example a wind field with flow=1.0 results in proper non-accelerating wind. * New effector fields "turbulence", which creates nice random flow paths, and "drag", which slows the points down. * Much improved vortex field. * Effectors can now effect particle rotation as well as location. * Use full, or only positive/negative z-axis to apply force (note. the z-axis is the surface normal in the case of effector shape "surface") * New "force field" submenu in add menu, which adds an empty with the chosen effector (curve object for corve guides). * Other dynamics should be quite easy to add to the effector system too if wanted. * "Unified" doesn't mean that force fields give the exact same results for particles, softbody & cloth, since their final effect depends on many external factors, like for example the surface area of the effected faces. Code changes * Subversion bump for correct handling of global gravity. * Separate ui py file for common dynamics stuff. * Particle settings updating is flushed with it's id through DAG_id_flush_update(..). Known issues * Curve guides don't yet have all ui buttons in place, but they should work none the less. * Hair dynamics don't yet respect force fields. Other changes * Particle emission defaults now to frames 1-200 with life of 50 frames to fill the whole default timeline. * Many particles drawing related crashes fixed. * Sometimes particles didn't update on first frame properly. * Hair with object/group visualization didn't work properly. * Memory leaks with PointCacheID lists (Genscher, remember to free pidlists after use :). --- release/scripts/ui/buttons_particle.py | 149 ++-- release/scripts/ui/buttons_physics_cloth.py | 38 +- release/scripts/ui/buttons_physics_common.py | 153 ++++ release/scripts/ui/buttons_physics_field.py | 83 +- release/scripts/ui/buttons_physics_softbody.py | 17 +- release/scripts/ui/buttons_scene.py | 18 + source/blender/blenkernel/BKE_collision.h | 9 + source/blender/blenkernel/BKE_effect.h | 109 ++- source/blender/blenkernel/BKE_particle.h | 65 +- source/blender/blenkernel/intern/boids.c | 187 ++--- source/blender/blenkernel/intern/cloth.c | 7 + source/blender/blenkernel/intern/collision.c | 91 +++ source/blender/blenkernel/intern/depsgraph.c | 54 +- source/blender/blenkernel/intern/effect.c | 855 +++++++++++++++------ source/blender/blenkernel/intern/implicit.c | 22 +- source/blender/blenkernel/intern/modifier.c | 7 +- source/blender/blenkernel/intern/object.c | 15 +- source/blender/blenkernel/intern/particle.c | 307 ++++---- source/blender/blenkernel/intern/particle_system.c | 686 +++-------------- source/blender/blenkernel/intern/pointcache.c | 4 + source/blender/blenkernel/intern/scene.c | 4 + source/blender/blenkernel/intern/smoke.c | 3 +- source/blender/blenkernel/intern/softbody.c | 67 +- source/blender/blenloader/intern/readfile.c | 90 ++- source/blender/blenloader/intern/writefile.c | 7 +- source/blender/editors/object/object_add.c | 88 +++ source/blender/editors/object/object_edit.c | 1 + source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_modifier.c | 6 +- source/blender/editors/object/object_ops.c | 1 + source/blender/editors/physics/particle_boids.c | 12 +- source/blender/editors/space_view3d/drawobject.c | 8 +- .../editors/transform/transform_conversions.c | 1 + source/blender/makesdna/DNA_cloth_types.h | 2 + source/blender/makesdna/DNA_object_force.h | 127 ++- source/blender/makesdna/DNA_particle_types.h | 26 +- source/blender/makesdna/DNA_scene_types.h | 11 + source/blender/makesrna/intern/rna_boid.c | 27 +- source/blender/makesrna/intern/rna_cloth.c | 5 + source/blender/makesrna/intern/rna_object.c | 4 +- source/blender/makesrna/intern/rna_object_force.c | 424 ++++++++-- source/blender/makesrna/intern/rna_particle.c | 221 ++---- source/blender/makesrna/intern/rna_scene.c | 23 +- 43 files changed, 2319 insertions(+), 1716 deletions(-) create mode 100644 release/scripts/ui/buttons_physics_common.py diff --git a/release/scripts/ui/buttons_particle.py b/release/scripts/ui/buttons_particle.py index 5274ddbcfbe..1a800fc4dfd 100644 --- a/release/scripts/ui/buttons_particle.py +++ b/release/scripts/ui/buttons_particle.py @@ -1,6 +1,11 @@ import bpy +from buttons_physics_common import point_cache_ui +from buttons_physics_common import effector_weights_ui +from buttons_physics_common import basic_force_field_settings_ui +from buttons_physics_common import basic_force_field_falloff_ui + def particle_panel_enabled(psys): return psys.point_cache.baked==False and psys.edited==False @@ -10,72 +15,6 @@ def particle_panel_poll(context): if psys.settings==None: return False return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR') -def point_cache_ui(self, cache, enabled, particles, smoke): - layout = self.layout - layout.set_context_pointer("PointCache", cache) - - row = layout.row() - row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 ) - col = row.column(align=True) - col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") - col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") - - row = layout.row() - row.itemL(text="File Name:") - if particles: - row.itemR(cache, "external") - - if cache.external: - split = layout.split(percentage=0.80) - split.itemR(cache, "name", text="") - split.itemR(cache, "index", text="") - - layout.itemL(text="File Path:") - layout.itemR(cache, "filepath", text="") - - layout.itemL(text=cache.info) - else: - layout.itemR(cache, "name", text="") - - if not particles: - row = layout.row() - row.enabled = enabled - row.itemR(cache, "start_frame") - row.itemR(cache, "end_frame") - - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake", text="Free Bake") - else: - row.item_booleanO("ptcache.bake", "bake", True, text="Bake") - - sub = row.row() - sub.enabled = (cache.frames_skipped or cache.outdated) and enabled - sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") - - row = layout.row() - row.enabled = enabled - row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") - if not smoke: - row.itemR(cache, "step"); - - if not smoke: - row = layout.row() - sub = row.row() - sub.enabled = enabled - sub.itemR(cache, "quick_cache") - row.itemR(cache, "disk_cache") - - layout.itemL(text=cache.info) - - layout.itemS() - - row = layout.row() - row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") - class ParticleButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' @@ -244,24 +183,23 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel): split = layout.split() - col = split.column() - col.itemL(text="Quality:") - col.itemR(cloth, "quality", text="Steps",slider=True) - col.itemL(text="Gravity:") - col.itemR(cloth, "gravity", text="") - col = split.column() col.itemL(text="Material:") sub = col.column(align=True) sub.itemR(cloth, "pin_stiffness", text="Stiffness") sub.itemR(cloth, "mass") sub.itemR(cloth, "bending_stiffness", text="Bending") + sub.itemR(cloth, "internal_friction", slider="True") + + col = split.column() + col.itemL(text="Damping:") sub = col.column(align=True) sub.itemR(cloth, "spring_damping", text="Spring") sub.itemR(cloth, "air_damping", text="Air") - layout.itemR(cloth, "internal_friction", slider="True") + col.itemL(text="Quality:") + col.itemR(cloth, "quality", text="Steps",slider=True) class PARTICLE_PT_cache(ParticleButtonsPanel): __label__ = "Cache" @@ -385,9 +323,11 @@ class PARTICLE_PT_physics(ParticleButtonsPanel): sub.itemR(part, "brownian_factor") sub.itemR(part, "drag_factor", slider=True) sub.itemR(part, "damp_factor", slider=True) - sub.itemR(part, "integrator") sub = split.column() - sub.itemR(part, "acceleration") + sub.itemR(part, "size_deflect") + sub.itemR(part, "die_on_collision") + sub.itemR(part, "integrator") + sub.itemR(part, "time_tweak") elif part.physics_type == 'KEYED': split = layout.split() @@ -445,14 +385,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel): col = row.column() col.itemL(text="Misc:") - col.itemR(part, "gravity") col.itemR(boids, "banking", slider=True) col.itemR(boids, "height", slider=True) - if part.physics_type=='NEWTON': - sub.itemR(part, "size_deflect") - sub.itemR(part, "die_on_collision") - elif part.physics_type=='KEYED' or part.physics_type=='BOIDS': + if part.physics_type=='KEYED' or part.physics_type=='BOIDS': if part.physics_type=='BOIDS': layout.itemL(text="Relations:") @@ -502,11 +438,10 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel): return psys.settings.physics_type=='BOIDS' def draw(self, context): - psys = context.particle_system - boids = psys.settings.boids + boids = context.particle_system.settings.boids layout = self.layout - layout.enabled = particle_panel_enabled(psys) + layout.enabled = particle_panel_enabled(context.particle_system) # Currently boids can only use the first state so these are commented out for now. #row = layout.row() @@ -858,30 +793,41 @@ class PARTICLE_PT_children(ParticleButtonsPanel): sub = split.column() sub.itemR(part, "kink_shape", slider=True) -class PARTICLE_PT_effectors(ParticleButtonsPanel): - __label__ = "Effectors" +class PARTICLE_PT_field_weights(ParticleButtonsPanel): + __label__ = "Field Weights" + __default_closed__ = True + + def draw(self, context): + part = context.particle_system.settings + effector_weights_ui(self, part.effector_weights) + + if part.type == 'HAIR': + self.layout.itemR(part.effector_weights, "do_growing_hair") + +class PARTICLE_PT_force_fields(ParticleButtonsPanel): + __label__ = "Force Field Settings" __default_closed__ = True def draw(self, context): layout = self.layout - - psys = context.particle_system - part = psys.settings + part = context.particle_system.settings - layout.itemR(part, "effector_group") + layout.itemR(part, "self_effect") - layout.itemR(part, "eweight_all", slider=True) + split = layout.split(percentage=0.2) + split.itemL(text="Type 1:") + split.itemR(part.force_field_1, "type",text="") + basic_force_field_settings_ui(self, part.force_field_1) + basic_force_field_falloff_ui(self, part.force_field_1) - layout.itemS() - layout.itemR(part, "eweight_spherical", slider=True) - layout.itemR(part, "eweight_vortex", slider=True) - layout.itemR(part, "eweight_magnetic", slider=True) - layout.itemR(part, "eweight_wind", slider=True) - layout.itemR(part, "eweight_curveguide", slider=True) - layout.itemR(part, "eweight_texture", slider=True) - layout.itemR(part, "eweight_harmonic", slider=True) - layout.itemR(part, "eweight_charge", slider=True) - layout.itemR(part, "eweight_lennardjones", slider=True) + if part.force_field_1.type != 'NONE': + layout.itemL(text="") + + split = layout.split(percentage=0.2) + split.itemL(text="Type 2:") + split.itemR(part.force_field_2, "type",text="") + basic_force_field_settings_ui(self, part.force_field_2) + basic_force_field_falloff_ui(self, part.force_field_2) class PARTICLE_PT_vertexgroups(ParticleButtonsPanel): __label__ = "Vertexgroups" @@ -958,5 +904,6 @@ bpy.types.register(PARTICLE_PT_boidbrain) bpy.types.register(PARTICLE_PT_render) bpy.types.register(PARTICLE_PT_draw) bpy.types.register(PARTICLE_PT_children) -bpy.types.register(PARTICLE_PT_effectors) +bpy.types.register(PARTICLE_PT_field_weights) +bpy.types.register(PARTICLE_PT_force_fields) bpy.types.register(PARTICLE_PT_vertexgroups) diff --git a/release/scripts/ui/buttons_physics_cloth.py b/release/scripts/ui/buttons_physics_cloth.py index f6493951a34..e25497b3713 100644 --- a/release/scripts/ui/buttons_physics_cloth.py +++ b/release/scripts/ui/buttons_physics_cloth.py @@ -1,7 +1,8 @@ import bpy -from buttons_particle import point_cache_ui +from buttons_physics_common import point_cache_ui +from buttons_physics_common import effector_weights_ui def cloth_panel_enabled(md): return md.point_cache.baked==False @@ -49,10 +50,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel): split = layout.split() col = split.column() - col.itemL(text="Quality:") - col.itemR(cloth, "quality", text="Steps",slider=True) - col.itemL(text="Gravity:") - col.itemR(cloth, "gravity", text="") + col.itemL(text="Material:") + sub = col.column(align=True) + sub.itemR(cloth, "mass") + sub.itemR(cloth, "structural_stiffness", text="Structural") + sub.itemR(cloth, "bending_stiffness", text="Bending") col.itemR(cloth, "pin_cloth", text="Pin") sub = col.column(align=True) @@ -61,18 +63,18 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel): sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="") col = split.column() - col.itemL(text="Presets...") - col.itemL(text="TODO!") - col.itemL(text="Material:") - sub = col.column(align=True) - sub.itemR(cloth, "mass") - sub.itemR(cloth, "structural_stiffness", text="Structural") - sub.itemR(cloth, "bending_stiffness", text="Bending") + col.itemL(text="Damping:") sub = col.column(align=True) sub.itemR(cloth, "spring_damping", text="Spring") sub.itemR(cloth, "air_damping", text="Air") + col.itemL(text="Presets...") + col.itemL(text="TODO!") + + col.itemL(text="Quality:") + col.itemR(cloth, "quality", text="Steps",slider=True) + # Disabled for now """ if cloth.mass_vertex_group: @@ -165,8 +167,20 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel): sub = col.column(align=True) sub.itemR(cloth, "bending_stiffness_max", text="Max") sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="") + +class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel): + __label__ = "Cloth Field Weights" + __default_closed__ = True + + def poll(self, context): + return (context.cloth) + + def draw(self, context): + cloth = context.cloth.settings + effector_weights_ui(self, cloth.effector_weights) bpy.types.register(PHYSICS_PT_cloth) bpy.types.register(PHYSICS_PT_cloth_cache) bpy.types.register(PHYSICS_PT_cloth_collision) bpy.types.register(PHYSICS_PT_cloth_stiffness) +bpy.types.register(PHYSICS_PT_cloth_field_weights) diff --git a/release/scripts/ui/buttons_physics_common.py b/release/scripts/ui/buttons_physics_common.py new file mode 100644 index 00000000000..b65d092fcfa --- /dev/null +++ b/release/scripts/ui/buttons_physics_common.py @@ -0,0 +1,153 @@ +import bpy + +def point_cache_ui(self, cache, enabled, particles, smoke): + layout = self.layout + layout.set_context_pointer("PointCache", cache) + + row = layout.row() + row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 ) + col = row.column(align=True) + col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="") + col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="") + + row = layout.row() + row.itemL(text="File Name:") + if particles: + row.itemR(cache, "external") + + if cache.external: + split = layout.split(percentage=0.80) + split.itemR(cache, "name", text="") + split.itemR(cache, "index", text="") + + layout.itemL(text="File Path:") + layout.itemR(cache, "filepath", text="") + + layout.itemL(text=cache.info) + else: + layout.itemR(cache, "name", text="") + + if not particles: + row = layout.row() + row.enabled = enabled + row.itemR(cache, "start_frame") + row.itemR(cache, "end_frame") + + row = layout.row() + + if cache.baked == True: + row.itemO("ptcache.free_bake", text="Free Bake") + else: + row.item_booleanO("ptcache.bake", "bake", True, text="Bake") + + sub = row.row() + sub.enabled = (cache.frames_skipped or cache.outdated) and enabled + sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame") + + row = layout.row() + row.enabled = enabled + row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake") + if not smoke: + row.itemR(cache, "step"); + + if not smoke: + row = layout.row() + sub = row.row() + sub.enabled = enabled + sub.itemR(cache, "quick_cache") + row.itemR(cache, "disk_cache") + + layout.itemL(text=cache.info) + + layout.itemS() + + row = layout.row() + row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") + row.itemO("ptcache.free_bake_all", text="Free All Bakes") + layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame") + +def effector_weights_ui(self, weights): + layout = self.layout + + layout.itemR(weights, "group") + + split = layout.split() + split.itemR(weights, "gravity", slider=True) + split.itemR(weights, "all", slider=True) + + layout.itemS() + + flow = layout.column_flow() + flow.itemR(weights, "spherical", slider=True) + flow.itemR(weights, "vortex", slider=True) + flow.itemR(weights, "magnetic", slider=True) + flow.itemR(weights, "wind", slider=True) + flow.itemR(weights, "curveguide", slider=True) + flow.itemR(weights, "texture", slider=True) + flow.itemR(weights, "harmonic", slider=True) + flow.itemR(weights, "charge", slider=True) + flow.itemR(weights, "lennardjones", slider=True) + flow.itemR(weights, "turbulence", slider=True) + flow.itemR(weights, "drag", slider=True) + flow.itemR(weights, "boid", slider=True) + +def basic_force_field_settings_ui(self, field): + layout = self.layout + split = layout.split() + + if not field or field.type == 'NONE': + return + + col = split.column() + + if field.type == 'DRAG': + col.itemR(field, "linear_drag", text="Linear") + else: + col.itemR(field, "strength") + + if field.type == 'TURBULENCE': + col.itemR(field, "size") + col.itemR(field, "flow") + elif field.type == 'HARMONIC': + col.itemR(field, "harmonic_damping", text="Damping") + elif field.type == 'VORTEX' and field.shape == 'PLANE': + col.itemR(field, "inflow") + elif field.type == 'DRAG': + col.itemR(field, "quadratic_drag", text="Quadratic") + else: + col.itemR(field, "flow") + + col = split.column() + col.itemR(field, "noise") + col.itemR(field, "seed") + if field.type == 'TURBULENCE': + col.itemR(field, "global_coordinates", text="Global") + + row = layout.row() + row.itemL(text="Effect point:") + row.itemR(field, "do_location") + row.itemR(field, "do_rotation") + + +def basic_force_field_falloff_ui(self, field): + layout = self.layout + split = layout.split(percentage=0.35) + + if not field or field.type == 'NONE': + return + + col = split.column() + col.itemR(field, "z_direction", text="") + col.itemR(field, "use_min_distance", text="Use Minimum") + col.itemR(field, "use_max_distance", text="Use Maximum") + + col = split.column() + col.itemR(field, "falloff_power", text="Power") + + sub = col.column() + sub.active = field.use_min_distance + sub.itemR(field, "minimum_distance", text="Distance") + + sub = col.column() + sub.active = field.use_max_distance + sub.itemR(field, "maximum_distance", text="Distance") \ No newline at end of file diff --git a/release/scripts/ui/buttons_physics_field.py b/release/scripts/ui/buttons_physics_field.py index 7d14690856a..24740acc68f 100644 --- a/release/scripts/ui/buttons_physics_field.py +++ b/release/scripts/ui/buttons_physics_field.py @@ -1,6 +1,9 @@ import bpy +from buttons_physics_common import basic_force_field_settings_ui +from buttons_physics_common import basic_force_field_falloff_ui + class PhysicButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -12,7 +15,6 @@ class PhysicButtonsPanel(bpy.types.Panel): class PHYSICS_PT_field(PhysicButtonsPanel): __label__ = "Force Fields" - __default_closed__ = True def draw(self, context): layout = self.layout @@ -23,50 +25,21 @@ class PHYSICS_PT_field(PhysicButtonsPanel): #layout.active = field.enabled split = layout.split(percentage=0.2) - split.itemL(text="Type:") split.itemR(field, "type",text="") + + if field.type not in ('NONE', 'GUIDE', 'TEXTURE'): + split = layout.split(percentage=0.2) + #split = layout.row() + split.itemL(text="Shape:") + split.itemR(field, "shape", text="") split = layout.split() - if field.type == 'GUIDE': + if field.type == 'NONE': + return # nothing to draw + elif field.type == 'GUIDE': layout.itemR(field, "guide_path_add") - - elif field.type == 'WIND': - split.itemR(field, "strength") - - col = split.column() - col.itemR(field, "noise") - col.itemR(field, "seed") - - elif field.type == 'VORTEX': - split.itemR(field, "strength") - split.itemL() - - elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'): - split.itemR(field, "strength") - - col = split.column() - col.itemR(field, "planar") - col.itemR(field, "surface") - - elif field.type == 'BOID': - split.itemR(field, "strength") - split.itemR(field, "surface") - - elif field.type == 'MAGNET': - split.itemR(field, "strength") - split.itemR(field, "planar") - - elif field.type == 'HARMONIC': - col = split.column() - col.itemR(field, "strength") - col.itemR(field, "harmonic_damping", text="Damping") - - col = split.column() - col.itemR(field, "planar") - col.itemR(field, "surface") - elif field.type == 'TEXTURE': col = split.column() col.itemR(field, "strength") @@ -78,29 +51,15 @@ class PHYSICS_PT_field(PhysicButtonsPanel): col.itemR(field, "use_coordinates") col.itemR(field, "root_coordinates") col.itemR(field, "force_2d") + else : + basic_force_field_settings_ui(self, field) - if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', 'WIND', 'VORTEX', 'TEXTURE', 'MAGNET', 'BOID'): + if field.type not in ('NONE', 'GUIDE'): layout.itemL(text="Falloff:") layout.itemR(field, "falloff_type", expand=True) - split = layout.split(percentage=0.35) - - col = split.column() - col.itemR(field, "positive_z", text="Positive Z") - col.itemR(field, "use_min_distance", text="Use Minimum") - col.itemR(field, "use_max_distance", text="Use Maximum") - - col = split.column() - col.itemR(field, "falloff_power", text="Power") - - sub = col.column() - sub.active = field.use_min_distance - sub.itemR(field, "minimum_distance", text="Distance") - - sub = col.column() - sub.active = field.use_max_distance - sub.itemR(field, "maximum_distance", text="Distance") + basic_force_field_falloff_ui(self, field) if field.falloff_type == 'CONE': layout.itemS() @@ -157,7 +116,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel): class PHYSICS_PT_collision(PhysicButtonsPanel): __label__ = "Collision" - __default_closed__ = True + #__default_closed__ = True def poll(self, context): ob = context.object @@ -182,16 +141,18 @@ class PHYSICS_PT_collision(PhysicButtonsPanel): #row.itemR(md, "render", text="") #row.itemR(md, "realtime", text="") - settings = md.settings + coll = md.settings else: # add modifier split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add") split.itemL() - settings = None + coll = None - if settings: + if coll: + settings = context.object.collision + layout.active = settings.enabled split = layout.split() diff --git a/release/scripts/ui/buttons_physics_softbody.py b/release/scripts/ui/buttons_physics_softbody.py index 3bdbb1b8b90..cd66df00044 100644 --- a/release/scripts/ui/buttons_physics_softbody.py +++ b/release/scripts/ui/buttons_physics_softbody.py @@ -1,7 +1,8 @@ import bpy -from buttons_particle import point_cache_ui +from buttons_physics_common import point_cache_ui +from buttons_physics_common import effector_weights_ui def softbody_panel_enabled(md): return md.point_cache.baked==False @@ -55,7 +56,6 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel): col = split.column() col.itemL(text="Simulation:") - col.itemR(softbody, "gravity") col.itemR(softbody, "speed") class PHYSICS_PT_softbody_cache(PhysicButtonsPanel): @@ -222,6 +222,18 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel): layout.itemL(text="Diagnostics:") layout.itemR(softbody, "diagnose") + +class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel): + __label__ = "Soft Body Field Weights" + __default_closed__ = True + + def poll(self, context): + return (context.soft_body) + + def draw(self, context): + md = context.soft_body + softbody = md.settings + effector_weights_ui(self, softbody.effector_weights) bpy.types.register(PHYSICS_PT_softbody) bpy.types.register(PHYSICS_PT_softbody_cache) @@ -229,3 +241,4 @@ bpy.types.register(PHYSICS_PT_softbody_goal) bpy.types.register(PHYSICS_PT_softbody_edge) bpy.types.register(PHYSICS_PT_softbody_collision) bpy.types.register(PHYSICS_PT_softbody_solver) +bpy.types.register(PHYSICS_PT_softbody_field_weights) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 88947aac86c..2fbd176e36a 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -451,6 +451,23 @@ class SCENE_PT_unit(RenderButtonsPanel): row.itemR(unit, "scale_length", text="Scale") row.itemR(unit, "use_separate") +class SCENE_PT_physics(RenderButtonsPanel): + __label__ = "Gravity" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw_header(self, context): + self.layout.itemR(context.scene, "use_gravity", text="") + + def draw(self, context): + layout = self.layout + + scene = context.scene + + layout.active = scene.use_gravity + + layout.itemR(scene, "gravity", text="") + + bpy.types.register(SCENE_PT_render) bpy.types.register(SCENE_PT_layers) bpy.types.register(SCENE_PT_dimensions) @@ -462,3 +479,4 @@ bpy.types.register(SCENE_PT_performance) bpy.types.register(SCENE_PT_post_processing) bpy.types.register(SCENE_PT_stamp) bpy.types.register(SCENE_PT_unit) +bpy.types.register(SCENE_PT_physics) diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index e0df75f41b9..5ca8ad892ac 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -141,6 +141,15 @@ void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], ///////////////////////////////////////////////// Object **get_collisionobjects(struct Scene *scene, Object *self, int *numcollobj); +typedef struct ColliderCache { + struct ColliderCache *next, *prev; + struct Object *ob; + struct CollisionModifierData *collmd; +} ColliderCache; + +struct ListBase *get_collider_cache(struct Scene *scene, Object *self); +void free_collider_cache(struct ListBase **colliders); + ///////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index e21e83bf5cf..83ec7c13946 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -32,6 +32,7 @@ #define BKE_EFFECT_H #include "DNA_object_types.h" +#include "DNA_modifier_types.h" struct Object; struct Scene; @@ -40,20 +41,72 @@ struct ListBase; struct Particle; struct Group; struct RNG; +struct ParticleSimulationData; +struct ParticleData; +struct ParticleKey; -struct PartDeflect *object_add_collision_fields(void); +struct EffectorWeights *BKE_add_effector_weights(struct Group *group); +struct PartDeflect *object_add_collision_fields(int type); -typedef struct pEffectorCache { - struct pEffectorCache *next, *prev; - Object *ob; - - /* precalculated variables */ - float oldloc[3], oldspeed[3]; - float scale, time_scale; - float guide_dist; +/* Input to effector code */ +typedef struct EffectedPoint { + float *loc; + float *vel; + float *ave; /* angular velocity for particles with dynamic rotation */ + float *rot; /* rotation quaternion for particles with dynamic rotation */ + float vel_to_frame; + float vel_to_sec; + + /* only for particles */ + float size, charge; + + unsigned int flag; + int index; + + struct ParticleSystem *psys; /* particle system the point belongs to */ +} EffectedPoint; + +typedef struct GuideEffectorData { + float vec_to_point[3]; + float strength; +} GuideEffectorData; + +typedef struct EffectorData { + /* Effector point */ + float loc[3]; + float nor[3]; + float vel[3]; + + float vec_to_point[3]; + float distance, falloff; + + /* only for effector particles */ + float size, charge; + + /* only for vortex effector with surface falloff */ + float nor2[3], vec_to_point2[3]; + + int *index; /* point index */ +} EffectorData; + +/* used for calculating the effector force */ +typedef struct EffectorCache { + struct EffectorCache *next, *prev; + + struct Scene *scene; + struct Object *ob; + struct ParticleSystem *psys; + struct SurfaceModifierData *surmd; - Object obcopy; /* for restoring transformation data */ -} pEffectorCache; + struct PartDeflect *pd; + + /* precalculated for guides */ + struct GuideEffectorData *guide_data; + float guide_loc[4], guide_dir[3], guide_radius; + + float frame; + int flag; +} EffectorCache; void free_effect(struct Effect *eff); void free_effects(struct ListBase *lb); @@ -61,23 +114,33 @@ struct Effect *copy_effect(struct Effect *eff); void copy_effects(struct ListBase *lbn, struct ListBase *lb); void deselectall_eff(struct Object *ob); -/* particle deflector */ -#define PE_WIND_AS_SPEED 0x00000001 - struct PartEff *give_parteff(struct Object *ob); -struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *obsrc, struct Group *group); -void pdEndEffectors(struct ListBase *lb); -void pdDoEffectors(struct Scene *scene, struct ListBase *lb, float *opco, float *force, - float *speed, float cur_time, float loc_time, unsigned int flags); + + +void free_partdeflect(struct PartDeflect *pd); +struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights); +void pdEndEffectors(struct ListBase **effectors); +void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse); + +void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point); +void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point); +void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point); + +/* needed for boids */ +float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights); +int closest_point_on_surface(struct SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel); +int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity); /* required for particle_system.c */ -void do_physical_effector(struct Scene *scene, struct Object *ob, float *opco, short type, float force_val, float distance, - float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, - float *velocity, float *field, int planar, struct RNG *rng, float noise_factor, - float charge, float pa_size); -float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float *vec_to_part); +//void do_physical_effector(struct EffectorData *eff, struct EffectorPoint *point, float *total_force); +//float effector_falloff(struct EffectorData *eff, struct EffectorPoint *point, struct EffectorWeights *weights); +/* EffectedPoint->flag */ +#define PE_WIND_AS_SPEED 1 +#define PE_DYNAMIC_ROTATION 2 +/* EffectorData->flag */ +#define PE_VELOCITY_TO_IMPULSE 1 #endif diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 5850ddaca08..e0259ff10dd 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -76,39 +76,18 @@ typedef struct ParticleSimulationData { struct Object *ob; struct ParticleSystem *psys; struct ParticleSystemModifierData *psmd; - float timestep; + struct ListBase *colliders; } ParticleSimulationData; -typedef struct ParticleEffectorCache { - struct ParticleEffectorCache *next, *prev; - struct Object *ob; - - /* precalculated variables for guides */ - float firstloc[4], firstdir[3]; - float *distances; - float *locations; - /* precalculated variables for deflection */ - float ob_minmax[6]; - float *face_minmax; - float *vert_cos; - /* precalculated variables for boids */ - struct KDTree *tree; - - short type, psys_nbr; - - struct Object obcopy; /* for restoring transformation data */ - struct RNG *rng; /* random noise generator for e.g. wind */ -} ParticleEffectorCache; - -typedef struct ParticleReactEvent { - struct ParticleReactEvent *next, *prev; - int event, pa_num; - Object *ob; - struct ParticleSystem *psys; - struct ParticleKey state; - - float time, size; -}ParticleReactEvent; +//typedef struct ParticleReactEvent { +// struct ParticleReactEvent *next, *prev; +// int event, pa_num; +// Object *ob; +// struct ParticleSystem *psys; +// struct ParticleKey state; +// +// float time, size; +//}ParticleReactEvent; typedef struct ParticleTexture{ float ivel; /* used in reset */ @@ -185,8 +164,8 @@ typedef struct ParticleBillboardData /* container for moving data between deflet_particle and particle_intersect_face */ typedef struct ParticleCollision { - struct Object *ob, *ob_t; // collided and current objects - struct CollisionModifierData *md; // collision modifier for ob_t; + struct Object *ob, *hit_ob; // collided and current objects + struct CollisionModifierData *md, *hit_md; // collision modifiers for current and hit object; float nor[3]; // normal at collision point float vel[3]; // velocity of collision point float co1[3], co2[3]; // ray start and end points @@ -244,7 +223,6 @@ void object_add_particle_system(struct Scene *scene, struct Object *ob); void object_remove_particle_system(struct Scene *scene, struct Object *ob); struct ParticleSettings *psys_new_settings(char *name, struct Main *main); struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part); -void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc); void make_local_particlesettings(struct ParticleSettings *part); void psys_reset(struct ParticleSystem *psys, int mode); @@ -254,7 +232,8 @@ void psys_find_parents(struct ParticleSimulationData *sim); void psys_cache_paths(struct ParticleSimulationData *sim, float cfra); void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra); void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate); -int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb); +int do_guides(struct ListBase *effectors, ParticleKey *state, int pa_num, float time); +void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors); float psys_get_timestep(struct ParticleSimulationData *sim); float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime); float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time); @@ -273,9 +252,7 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] /* particle_system.c */ struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt); void psys_count_keyed_targets(struct ParticleSimulationData *sim); -//void psys_get_reactor_target(struct ParticleSimulationData *sim, struct Object **target_ob, struct ParticleSystem **target_psys); - -int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc); +void psys_update_particle_tree(struct ParticleSystem *psys, float cfra); void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys); void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra); @@ -316,29 +293,17 @@ void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_ /* particle_system.c */ void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p); - -int effector_find_co(struct Scene *scene, float *pco, struct SurfaceModifierData *sur, struct Object *ob, struct PartDeflect *pd, float *co, float *nor, float *vel, int *index); -void do_effectors(struct ParticleSimulationData *sim, int pa_no, struct ParticleData *pa, struct ParticleKey *state, float *texco, float *force_field, float *vel,float framestep, float cfra); -void psys_end_effectors(struct ParticleSystem *psys); - void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys); int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node); void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra); - /* psys_reset */ #define PSYS_RESET_ALL 1 #define PSYS_RESET_DEPSGRAPH 2 #define PSYS_RESET_CHILDREN 3 #define PSYS_RESET_CACHE_MISS 4 -/* ParticleEffectorCache->type */ -#define PSYS_EC_EFFECTOR 1 -#define PSYS_EC_DEFLECT 2 -#define PSYS_EC_PARTICLE 4 -#define PSYS_EC_REACTOR 8 - /* index_dmcache */ #define DMCACHE_NOTFOUND -1 #define DMCACHE_ISCHILD -2 diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 7c3f3a7876f..76824d3a34a 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -47,6 +47,7 @@ #include "BLI_blenlib.h" #include "BLI_kdtree.h" #include "BLI_kdopbvh.h" +#include "BKE_collision.h" #include "BKE_effect.h" #include "BKE_boids.h" #include "BKE_particle.h" @@ -72,112 +73,91 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, { BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule; BoidSettings *boids = bbd->part->boids; - ParticleEffectorCache *ec; Object *priority_ob = NULL; BoidParticle *bpa = pa->boid; + EffectedPoint epoint; + ListBase *effectors = bbd->sim->psys->effectors; + EffectorCache *cur, *eff = NULL; + EffectorData efd, cur_efd; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0); float priority = 0.0f, len = 0.0f; int ret = 0; - /* first find out goal/predator with highest priority */ - /* if rule->ob specified use it */ - if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) { - PartDeflect *pd = gabr->ob->pd; - float vec_to_part[3]; - - if(pd && pd->forcefield == PFIELD_BOID) { - effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL); - - VecSubf(vec_to_part, pa->prev_state.co, loc); + pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint); - priority = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part); - } - else - priority = 1.0; - - priority = 1.0; - priority_ob = gabr->ob; - } - else for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) { - if(ec->type & PSYS_EC_EFFECTOR) { - Object *eob = ec->ob; - PartDeflect *pd = eob->pd; - - /* skip current object */ - if(rule->type == eBoidRuleType_Goal && eob == bpa->ground) - continue; - - if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) { - float vec_to_part[3], temp; - - effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL); - - VecSubf(vec_to_part, pa->prev_state.co, loc); - - temp = mul * pd->f_strength * effector_falloff(pd, vec, vec_to_part); - - if(temp == 0.0f) - ; /* do nothing */ - else if(temp > priority) { - priority = temp; - priority_ob = eob; - len = VecLength(vec_to_part); - } - /* choose closest object with same priority */ - else if(temp == priority) { - float len2 = VecLength(vec_to_part); - - if(len2 < len) { - priority_ob = eob; - len = len2; - } + /* first find out goal/predator with highest priority */ + if(effectors) for(cur = effectors->first; cur; cur=cur->next) { + Object *eob = cur->ob; + PartDeflect *pd = cur->pd; + + if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) { + if(gabr->ob == eob) { + /* TODO: objects without any effector and effectors with multiple points */ + if(get_effector_data(cur, &efd, &epoint, 0)) { + if(cur->pd && cur->pd->forcefield == PFIELD_BOID) + priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights); + else + priority = 1.0; + + eff = cur; } + break; + } + } + else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground) + ; /* skip current object */ + else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(eff, &efd, &epoint, 0)) { + float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights); + + if(temp == 0.0f) + ; /* do nothing */ + else if(temp > priority) { + priority = temp; + eff = cur; + efd = cur_efd; + len = efd.distance; + } + /* choose closest object with same priority */ + else if(temp == priority && efd.distance < len) { + eff = cur; + efd = cur_efd; + len = efd.distance; } } } /* then use that effector */ if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */ - Object *eob = priority_ob; + Object *eob = eff->ob; PartDeflect *pd = eob->pd; - float vec_to_part[3]; - float surface = 0.0f; - float nor[3]; + float surface = pd->shape == PFIELD_SHAPE_SURFACE ? 1.0f : 0.0f; if(gabr->options & BRULE_GOAL_AVOID_PREDICT) { /* estimate future location of target */ - surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL); - - VecSubf(vec_to_part, pa->prev_state.co, loc); - len = Normalize(vec_to_part); + get_effector_data(eff, &efd, &epoint, 1); - VecMulf(vec, len / (val->max_speed * bbd->timestep)); - VecAddf(loc, loc, vec); - VecSubf(vec_to_part, pa->prev_state.co, loc); - } - else { - surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL); - - VecSubf(vec_to_part, pa->prev_state.co, loc); - len = VecLength(vec_to_part); + VecMulf(efd.vel, efd.distance / (val->max_speed * bbd->timestep)); + VecAddf(efd.loc, efd.loc, efd.vel); + VecSubf(efd.vec_to_point, pa->prev_state.co, efd.loc); + efd.distance = VecLength(efd.vec_to_point); } if(rule->type == eBoidRuleType_Goal && boids->options & BOID_ALLOW_CLIMB && surface!=0.0f) { if(!bbd->goal_ob || bbd->goal_priority < priority) { bbd->goal_ob = eob; - VECCOPY(bbd->goal_co, loc); - VECCOPY(bbd->goal_nor, nor); + VECCOPY(bbd->goal_co, efd.loc); + VECCOPY(bbd->goal_nor, efd.nor); } } else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing && priority > 2.0f * gabr->fear_factor) { /* detach from surface and try to fly away from danger */ - VECCOPY(vec_to_part, bpa->gravity); - VecMulf(vec_to_part, -1.0f); + VECCOPY(efd.vec_to_point, bpa->gravity); + VecMulf(efd.vec_to_point, -1.0f); } - VECCOPY(bbd->wanted_co, vec_to_part); + VECCOPY(bbd->wanted_co, efd.vec_to_point); VecMulf(bbd->wanted_co, mul); bbd->wanted_speed = val->max_speed * priority; @@ -188,8 +168,8 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, surface *= pa->size * boids->height; - if(len2 > 0.0f && len - surface < len2) { - len2 = (len - surface)/len2; + if(len2 > 0.0f && efd.distance - surface < len2) { + len2 = (efd.distance - surface)/len2; bbd->wanted_speed *= pow(len2, boids->landing_smoothness); } } @@ -204,9 +184,9 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * { BoidRuleAvoidCollision *acbr = (BoidRuleAvoidCollision*) rule; KDTreeNearest *ptn = NULL; - ParticleEffectorCache *ec; ParticleTarget *pt; BoidParticle *bpa = pa->boid; + ColliderCache *coll; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float co1[3], vel1[3], co2[3], vel2[3]; float len, t, inp, t_min = 2.0f; @@ -214,7 +194,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * int ret = 0; //check deflector objects first - if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS) { + if(acbr->options & BRULE_ACOLL_WITH_DEFLECTORS && bbd->sim->colliders) { ParticleCollision col; BVHTreeRayHit hit; float radius = val->personal_space * pa->size, ray_dir[3]; @@ -228,20 +208,16 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * hit.dist = col.ray_len = VecLength(ray_dir); /* find out closest deflector object */ - for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) { - if(ec->type & PSYS_EC_DEFLECT) { - Object *eob = ec->ob; - - /* don't check with current ground object */ - if(eob == bpa->ground) - continue; + for(coll = bbd->sim->colliders->first; coll; coll=coll->next) { + /* don't check with current ground object */ + if(coll->ob == bpa->ground) + continue; - col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) ); - col.ob_t = eob; + col.ob = coll->ob; + col.md = coll->collmd; - if(col.md && col.md->bvhtree) - BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col); - } + if(col.md && col.md->bvhtree) + BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col); } /* then avoid that object */ if(hit.index>=0) { @@ -756,25 +732,28 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro if(bpa->data.mode == eBoidMode_Climbing) { SurfaceModifierData *surmd = NULL; float x[3], v[3]; - + surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface ); /* take surface velocity into account */ - effector_find_co(bbd->sim->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL); + closest_point_on_surface(surmd, pa->state.co, x, NULL, v); VecAddf(x, x, v); /* get actual position on surface */ - effector_find_co(bbd->sim->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL); + closest_point_on_surface(surmd, x, ground_co, ground_nor, NULL); return bpa->ground; } else { float zvec[3] = {0.0f, 0.0f, 2000.0f}; ParticleCollision col; + ColliderCache *coll; BVHTreeRayHit hit; - ParticleEffectorCache *ec; float radius = 0.0f, t, ray_dir[3]; + if(!bbd->sim->colliders) + return NULL; + VECCOPY(col.co1, pa->state.co); VECCOPY(col.co2, pa->state.co); VecAddf(col.co1, col.co1, zvec); @@ -785,16 +764,12 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro hit.dist = col.ray_len = VecLength(ray_dir); /* find out upmost deflector object */ - for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) { - if(ec->type & PSYS_EC_DEFLECT) { - Object *eob = ec->ob; + for(coll = bbd->sim->colliders->first; coll; coll = coll->next){ + col.ob = coll->ob; + col.md = coll->collmd; - col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) ); - col.ob_t = eob; - - if(col.md && col.md->bvhtree) - BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col); - } + if(col.md && col.md->bvhtree) + BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col); } /* then use that object */ if(hit.index>=0) { @@ -802,7 +777,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro VecLerpf(ground_co, col.co1, col.co2, t); VECCOPY(ground_nor, col.nor); Normalize(ground_nor); - return col.ob; + return col.hit_ob; } else { /* default to z=0 */ @@ -1068,6 +1043,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) BoidSettings *boids = bbd->part->boids; BoidParticle *bpa = pa->boid; BoidValues val; + EffectedPoint epoint; float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3]; float dvec[3], bvec[3]; float new_dir[3], new_speed; @@ -1208,7 +1184,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) } /* account for effectors */ - do_effectors(bbd->sim, p, pa, &pa->state, pa->state.co, force, tvel, bbd->dfra, bbd->cfra); + pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint); + pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL); if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { float length = Normalize(force); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 5cfbd5c18dc..74f88a77e63 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -153,6 +153,9 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->defgoal = 0.0f; clmd->sim_parms->goalspring = 1.0f; clmd->sim_parms->goalfrict = 0.0f; + + if(!clmd->sim_parms->effector_weights) + clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL); } static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) @@ -402,6 +405,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul VECCOPY(verts->xconst, mvert[i].co); Mat4MulVecfl(ob->obmat, verts->xconst); } + + effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights); tstart(); @@ -411,6 +416,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul tend(); + pdEndEffectors(&effectors); + // printf ( "%f\n", ( float ) tval() ); return ret; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 20fc1708454..8c664bc1a57 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1392,6 +1392,97 @@ Object **get_collisionobjects(Scene *scene, Object *self, int *numcollobj) return objs; } +ListBase *get_collider_cache(Scene *scene, Object *self) +{ + Base *base=NULL; + ListBase *objs = NULL; + Object *coll_ob = NULL; + CollisionModifierData *collmd = NULL; + ColliderCache *col; + + // check all collision objects + for ( base = scene->base.first; base; base = base->next ) + { + /*Only proceed for mesh object in same layer */ + if(base->object->type!=OB_MESH) + continue; + + if(self && (base->lay & self->lay)==0) + continue; + + + coll_ob = base->object; + + if(coll_ob == self) + continue; + + if(coll_ob->pd && coll_ob->pd->deflect) + { + collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); + } + else + collmd = NULL; + + if ( collmd ) + { + if(objs == NULL) + objs = MEM_callocN(sizeof(ListBase), "ColliderCache array"); + + col = MEM_callocN(sizeof(ColliderCache), "ColliderCache"); + col->ob = coll_ob; + col->collmd = collmd; + /* make sure collider is properly set up */ + collision_move_object(collmd, 1.0, 0.0); + BLI_addtail(objs, col); + } + else if ( coll_ob->dup_group ) + { + GroupObject *go; + Group *group = coll_ob->dup_group; + + for ( go= group->gobject.first; go; go= go->next ) + { + coll_ob = go->ob; + collmd = NULL; + + if(coll_ob == self) + continue; + + if(coll_ob->pd && coll_ob->pd->deflect) + { + collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); + } + else + collmd = NULL; + + if ( !collmd ) + continue; + + if( !collmd->bvhtree) + continue; + + if(objs == NULL) + objs = MEM_callocN(sizeof(ListBase), "ColliderCache array"); + + col = MEM_callocN(sizeof(ColliderCache), "ColliderCache"); + col->ob = coll_ob; + col->collmd = collmd; + /* make sure collider is properly set up */ + collision_move_object(collmd, 1.0, 0.0); + BLI_addtail(objs, col); + } + } + } + return objs; +} +void free_collider_cache(ListBase **colliders) +{ + if(*colliders) { + BLI_freelistN(*colliders); + MEM_freeN(*colliders); + *colliders = NULL; + } +} static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap) { int i; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 608cfe03b72..a8cec6070a0 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -521,8 +521,8 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O /* softbody collision */ if((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE)) - if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob)) - dag_add_collision_field_relation(dag, scene, ob, node); + if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob) || ob->particlesystem.first) + dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */ if (ob->type==OB_MBALL) { Object *mom= find_basis_mball(scene, ob); @@ -554,14 +554,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O psys= ob->particlesystem.first; if(psys) { - ParticleEffectorCache *nec; GroupObject *go; for(; psys; psys=psys->next) { BoidRule *rule = NULL; BoidState *state = NULL; - ParticleSimulationData sim = {scene, ob, psys, NULL}; ParticleSettings *part= psys->part; + ListBase *effectors = NULL; + EffectorCache *eff; dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation"); @@ -593,33 +593,17 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O } } - psys_update_effectors(&sim, 0.0, 0); + effectors = pdInitEffectors(scene, ob, psys, part->effector_weights); - for(nec= psys->effectors.first; nec; nec= nec->next) { - Object *ob1= nec->ob; - - if(nec->type & PSYS_EC_EFFECTOR) { - node2 = dag_get_node(dag, ob1); - if(ob1->pd->forcefield==PFIELD_GUIDE) - dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Field"); - else - dag_add_relation(dag, node2, node, DAG_RL_OB_DATA, "Particle Field"); - } - else if(nec->type & PSYS_EC_DEFLECT) { - node2 = dag_get_node(dag, ob1); - dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Collision"); - } - else if(nec->type & PSYS_EC_PARTICLE) { - node2 = dag_get_node(dag, ob1); - dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Field"); - } - - if(nec->type & PSYS_EC_REACTOR) { - node2 = dag_get_node(dag, ob1); - dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Reactor"); + if(effectors) for(eff = effectors->first; eff; eff=eff->next) { + if(eff->psys) { + node2 = dag_get_node(dag, eff->ob); + dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Particle Field"); } } + pdEndEffectors(&effectors); + if(part->boids) { for(state = part->boids->states.first; state; state=state->next) { for(rule = state->rules.first; rule; rule=rule->next) { @@ -2217,7 +2201,7 @@ void DAG_id_flush_update(ID *id, short flag) /* set flags & pointcache for object */ if(GS(id->name) == ID_OB) { ob= (Object*)id; - ob->recalc |= flag; + ob->recalc |= (flag & OB_RECALC); BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH); if(flag & OB_RECALC_DATA) { @@ -2255,6 +2239,20 @@ void DAG_id_flush_update(ID *id, short flag) } } + /* set flags based on particle settings */ + if(idtype == ID_PA) { + ParticleSystem *psys; + for(obt=bmain->object.first; obt; obt= obt->id.next) { + for(psys=obt->particlesystem.first; psys; psys=psys->next) { + if(&psys->part->id == id) { + BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); + obt->recalc |= (flag & OB_RECALC); + psys->recalc |= (flag & PSYS_RECALC); + } + } + } + } + /* update editors */ dag_editors_update(bmain, id); } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index acf906e3163..7cc65de827a 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -48,12 +48,15 @@ #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_particle_types.h" #include "DNA_texture_types.h" #include "DNA_scene_types.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_jitter.h" +#include "BLI_listbase.h" +#include "BLI_noise.h" #include "BLI_rand.h" #include "PIL_time.h" @@ -68,6 +71,7 @@ #include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_group.h" @@ -79,11 +83,13 @@ #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_particle.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_utildefines.h" #include "RE_render_ext.h" +#include "RE_shader_ext.h" /* fluid sim particle import */ #ifndef DISABLE_ELBEEM @@ -95,17 +101,46 @@ //XXX #include "BIF_screen.h" -PartDeflect *object_add_collision_fields(void) +EffectorWeights *BKE_add_effector_weights(Group *group) +{ + EffectorWeights *weights = MEM_callocN(sizeof(EffectorWeights), "EffectorWeights"); + int i; + + for(i=0; iweight[i] = 1.0f; + + weights->global_gravity = 1.0f; + + weights->group = group; + + return weights; +} +PartDeflect *object_add_collision_fields(int type) { PartDeflect *pd; pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect"); + pd->forcefield = type; pd->pdef_sbdamp = 0.1f; pd->pdef_sbift = 0.2f; pd->pdef_sboft = 0.02f; pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer()))+1) % 128; pd->f_strength = 1.0f; + pd->f_damp = 1.0f; + pd->f_size = 1.0f; + + /* set sensible defaults based on type */ + switch(type) { + case PFIELD_VORTEX: + pd->shape = PFIELD_SHAPE_PLANE; + break; + case PFIELD_WIND: + pd->shape = PFIELD_SHAPE_PLANE; + pd->f_flow = 1.0f; /* realistic wind behavior */ + break; + } + pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; return pd; } @@ -156,93 +191,216 @@ void free_effects(ListBase *lb) } /* -------------------------- Effectors ------------------ */ +void free_partdeflect(PartDeflect *pd) +{ + if(!pd) + return; + + if(pd->tex) + pd->tex->id.us--; -static void add_to_effectorcache(ListBase *lb, Scene *scene, Object *ob, Object *obsrc) + if(pd->rng) + rng_free(pd->rng); + + MEM_freeN(pd); +} + +static void precalculate_effector(EffectorCache *eff) { - pEffectorCache *ec; - PartDeflect *pd= ob->pd; - - if(pd->forcefield == PFIELD_GUIDE) { - if(ob->type==OB_CURVE && obsrc->type==OB_MESH) { /* guides only do mesh particles */ - Curve *cu= ob->data; - if(cu->flag & CU_PATH) { - if(cu->path==NULL || cu->path->data==NULL) - makeDispListCurveTypes(scene, ob, 0); - if(cu->path && cu->path->data) { - ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); - ec->ob= ob; - BLI_addtail(lb, ec); - } + unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra); + if(!eff->pd->rng) + eff->pd->rng = rng_new(eff->pd->seed + cfra); + else + rng_srandom(eff->pd->rng, eff->pd->seed + cfra); + + if(eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) { + Curve *cu= eff->ob->data; + if(cu->flag & CU_PATH) { + if(cu->path==NULL || cu->path->data==NULL) + makeDispListCurveTypes(eff->scene, eff->ob, 0); + + if(cu->path && cu->path->data) { + where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius); + Mat4MulVecfl(eff->ob->obmat, eff->guide_loc); + Mat4Mul3Vecfl(eff->ob->obmat, eff->guide_dir); } } } - else if(pd->forcefield) { - - if(pd->forcefield == PFIELD_WIND) - { - pd->rng = rng_new(pd->seed); - } - - ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); - ec->ob= ob; - BLI_addtail(lb, ec); + else if(eff->pd->shape == PFIELD_SHAPE_SURFACE) { + eff->surmd = (SurfaceModifierData *)modifiers_findByType ( eff->ob, eModifierType_Surface ); + } + else if(eff->psys) + psys_update_particle_tree(eff->psys, eff->scene->r.cfra); +} +static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd) +{ + EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache"); + eff->scene = scene; + eff->ob = ob; + eff->psys = psys; + eff->pd = pd; + eff->frame = -1; + + precalculate_effector(eff); + + return eff; +} +static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src) +{ + EffectorCache *eff = NULL; + + if( ob == ob_src || weights->weight[ob->pd->forcefield] == 0.0f ) + return; + + if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal ) + return; + + if(*effectors == NULL) + *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); + + eff = new_effector_cache(scene, ob, NULL, ob->pd); + + BLI_addtail(*effectors, eff); +} +static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src) +{ + ParticleSettings *part= psys->part; + + if( !psys_check_enabled(ob, psys) ) + return; + + if( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) + return; + + if( part->pd && part->pd->forcefield && weights->weight[part->pd->forcefield] != 0.0f) { + if(*effectors == NULL) + *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); + + BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd)); + } + + if (part->pd2 && part->pd2->forcefield && weights->weight[part->pd2->forcefield] != 0.0f) { + if(*effectors == NULL) + *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); + + BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd2)); } } /* returns ListBase handle with objects taking part in the effecting */ -ListBase *pdInitEffectors(Scene *scene, Object *obsrc, Group *group) +ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src, EffectorWeights *weights) { - static ListBase listb={NULL, NULL}; - pEffectorCache *ec; Base *base; - unsigned int layer= obsrc->lay; + unsigned int layer= ob_src->lay; + ListBase *effectors = NULL; - if(group) { + if(weights->group) { GroupObject *go; - for(go= group->gobject.first; go; go= go->next) { - if( (go->ob->lay & layer) && go->ob->pd && go->ob!=obsrc) { - add_to_effectorcache(&listb, scene, go->ob, obsrc); + for(go= weights->group->gobject.first; go; go= go->next) { + if( (go->ob->lay & layer) ) { + if( go->ob->pd && go->ob->pd->forcefield ) + add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src); + + if( go->ob->particlesystem.first ) { + ParticleSystem *psys= go->ob->particlesystem.first; + + for( ; psys; psys=psys->next ) + add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src); + } } } } else { for(base = scene->base.first; base; base= base->next) { - if( (base->lay & layer) && base->object->pd && base->object!=obsrc) { - add_to_effectorcache(&listb, scene, base->object, obsrc); + if( (base->lay & layer) ) { + if( base->object->pd && base->object->pd->forcefield ) + add_object_to_effectors(&effectors, scene, weights, base->object, ob_src); + + if( base->object->particlesystem.first ) { + ParticleSystem *psys= base->object->particlesystem.first; + + for( ; psys; psys=psys->next ) + add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src); + } } } } - - /* make a full copy */ - for(ec= listb.first; ec; ec= ec->next) { - ec->obcopy= *(ec->ob); - } - - if(listb.first) - return &listb; - - return NULL; + return effectors; } -void pdEndEffectors(ListBase *lb) +void pdEndEffectors(ListBase **effectors) { - if(lb) { - pEffectorCache *ec; - /* restore full copy */ - for(ec= lb->first; ec; ec= ec->next) - { - if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND)) - rng_free(ec->ob->pd->rng); - - *(ec->ob)= ec->obcopy; + if(*effectors) { + EffectorCache *eff = (*effectors)->first; + + for(; eff; eff=eff->next) { + if(eff->guide_data) + MEM_freeN(eff->guide_data); } - BLI_freelistN(lb); + BLI_freelistN(*effectors); + MEM_freeN(*effectors); + *effectors = NULL; } } +void pd_point_from_particle(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, EffectedPoint *point) +{ + point->loc = state->co; + point->vel = state->vel; + point->index = pa - sim->psys->particles; + point->size = pa->size; + /* TODO: point->charge */ + point->charge = 1.0f; + + point->vel_to_sec = 1.0f; + point->vel_to_frame = psys_get_timestep(sim); + + point->flag = 0; + + if(sim->psys->part->flag & PART_ROT_DYN) { + point->ave = state->ave; + point->rot = state->rot; + } + else + point->ave = point->rot = NULL; + + point->psys = sim->psys; +} + +void pd_point_from_loc(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point) +{ + point->loc = loc; + point->vel = vel; + point->index = index; + point->size = 0.0f; + + point->vel_to_sec = (float)scene->r.frs_sec; + point->vel_to_frame = 1.0f; + + point->flag = 0; + + point->ave = point->rot = NULL; + point->psys = NULL; +} +void pd_point_from_soft(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point) +{ + point->loc = loc; + point->vel = vel; + point->index = index; + point->size = 0.0f; + + point->vel_to_sec = (float)scene->r.frs_sec; + point->vel_to_frame = 1.0f; + + point->flag = PE_WIND_AS_SPEED; + + point->ave = point->rot = NULL; + + point->psys = NULL; +} /************************************************/ /* Effectors */ /************************************************/ @@ -256,27 +414,33 @@ static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BV } // get visibility of a wind ray -static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir) +static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, EffectorData *efd, EffectedPoint *point) { - Object **collobjs = NULL; - int numcollobj = 0, i; + ListBase *colls = colliders; + ColliderCache *col; float norm[3], len = 0.0; float visibility = 1.0, absorption = 0.0; - collobjs = get_collisionobjects(scene, ob, &numcollobj); - - if(!collobjs) - return 0; + if(!(eff->pd->flag & PFIELD_VISIBILITY)) + return visibility; + + if(!colls) + colls = get_collider_cache(eff->scene, NULL); + + if(!colls) + return visibility; - VECCOPY(norm, dir); + VECCOPY(norm, efd->vec_to_point); VecNegf(norm); len = Normalize(norm); // check all collision objects - for(i = 0; i < numcollobj; i++) + for(col = colls->first; col; col = col->next) { - Object *collob= collobjs[i]; - CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision); + CollisionModifierData *collmd = col->collmd; + + if(col->ob == eff->ob) + continue; if(collmd->bvhtree) { @@ -286,9 +450,9 @@ static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir hit.dist = len + FLT_EPSILON; // check if the way is blocked - if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0) + if(BLI_bvhtree_ray_cast(collmd->bvhtree, point->loc, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0) { - absorption= (collob->pd)? collob->pd->absorption: 0.0f; + absorption= col->ob->pd->absorption; // visibility is only between 0 and 1, calculated from 1-absorption visibility *= CLAMPIS(1.0f-absorption, 0.0f, 1.0f); @@ -298,8 +462,9 @@ static float eff_calc_visibility(Scene *scene, Object *ob, float *co, float *dir } } } - - MEM_freeN(collobjs); + + if(!colliders) + free_collider_cache(&colls); return visibility; } @@ -347,43 +512,39 @@ static float falloff_func_rad(PartDeflect *pd, float fac) return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r); } -float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part) +float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, EffectorWeights *weights) { - float eff_dir[3], temp[3]; - float falloff=1.0, fac, r_fac; - - if(pd->forcefield==PFIELD_LENNARDJ) - return falloff; /* Lennard-Jones field has it's own falloff built in */ + float temp[3]; + float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f; + float fac, r_fac; - VecCopyf(eff_dir,eff_velocity); - Normalize(eff_dir); + fac = Inpf(efd->nor, efd->vec_to_point); - if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f) + if(eff->pd->zdir == PFIELD_Z_POS && fac < 0.0f) falloff=0.0f; - else switch(pd->falloff){ + else if(eff->pd->zdir == PFIELD_Z_NEG && fac > 0.0f) + falloff=0.0f; + else switch(eff->pd->falloff){ case PFIELD_FALL_SPHERE: - fac=VecLength(vec_to_part); - falloff= falloff_func_dist(pd, fac); + falloff*= falloff_func_dist(eff->pd, efd->distance); break; case PFIELD_FALL_TUBE: - fac=Inpf(vec_to_part,eff_dir); - falloff= falloff_func_dist(pd, ABS(fac)); + falloff*= falloff_func_dist(eff->pd, ABS(fac)); if(falloff == 0.0f) break; - VECADDFAC(temp,vec_to_part,eff_dir,-fac); - r_fac=VecLength(temp); - falloff*= falloff_func_rad(pd, r_fac); + VECADDFAC(temp, efd->vec_to_point, efd->nor, -fac); + r_fac= VecLength(temp); + falloff*= falloff_func_rad(eff->pd, r_fac); break; case PFIELD_FALL_CONE: - fac=Inpf(vec_to_part,eff_dir); - falloff= falloff_func_dist(pd, ABS(fac)); + falloff*= falloff_func_dist(eff->pd, ABS(fac)); if(falloff == 0.0f) break; - r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI; - falloff*= falloff_func_rad(pd, r_fac); + r_fac=saacos(fac/VecLength(efd->vec_to_point))*180.0f/(float)M_PI; + falloff*= falloff_func_rad(eff->pd, r_fac); break; } @@ -391,127 +552,391 @@ float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part) return falloff; } -void do_physical_effector(Scene *scene, Object *ob, float *opco, short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise_factor, float charge, float pa_size) +int closest_point_on_surface(SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel) { - float mag_vec[3]={0,0,0}; - float temp[3], temp2[3]; - float eff_vel[3]; - float noise = 0, visibility; - - // calculate visibility - visibility = eff_calc_visibility(scene, ob, opco, vec_to_part); - if(visibility <= 0.0) - return; - falloff *= visibility; + BVHTreeNearest nearest; - VecCopyf(eff_vel,eff_velocity); - Normalize(eff_vel); + nearest.index = -1; + nearest.dist = FLT_MAX; - switch(type){ - case PFIELD_WIND: - VECCOPY(mag_vec,eff_vel); - - // add wind noise here, only if we have wind - if((noise_factor > 0.0f) && (force_val > FLT_EPSILON)) - noise = wind_func(rng, noise_factor); + BLI_bvhtree_find_nearest(surmd->bvhtree->tree, co, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree); + + if(nearest.index != -1) { + VECCOPY(surface_co, nearest.co); + + if(surface_nor) { + VECCOPY(surface_nor, nearest.no); + } + + if(surface_vel) { + MFace *mface = CDDM_get_face(surmd->dm, nearest.index); - VecMulf(mag_vec,(force_val+noise)*falloff); - VecAddf(field,field,mag_vec); - break; + VECCOPY(surface_vel, surmd->v[mface->v1].co); + VecAddf(surface_vel, surface_vel, surmd->v[mface->v2].co); + VecAddf(surface_vel, surface_vel, surmd->v[mface->v3].co); + if(mface->v4) + VecAddf(surface_vel, surface_vel, surmd->v[mface->v4].co); - case PFIELD_FORCE: - if(planar) - Projf(mag_vec,vec_to_part,eff_vel); - else - VecCopyf(mag_vec,vec_to_part); + VecMulf(surface_vel, mface->v4 ? 0.25f : 0.333f); + } + return 1; + } - Normalize(mag_vec); + return 0; +} +int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int real_velocity) +{ + float cfra = eff->scene->r.cfra; + int ret = 0; - VecMulf(mag_vec,force_val*falloff); - VecAddf(field,field,mag_vec); - break; + if(eff->pd->shape==PFIELD_SHAPE_SURFACE && eff->surmd) { + /* closest point in the object surface is an effector */ + float vec[3]; - case PFIELD_VORTEX: - Crossf(mag_vec,eff_vel,vec_to_part); + /* using velocity corrected location allows for easier sliding over effector surface */ + VecCopyf(vec, point->vel); + VecMulf(vec, point->vel_to_frame); + VecAddf(vec, vec, point->loc); - Normalize(mag_vec); + ret = closest_point_on_surface(eff->surmd, vec, efd->loc, efd->nor, real_velocity ? efd->vel : NULL); - VecMulf(mag_vec,force_val*distance*falloff); - VecAddf(field,field,mag_vec); + efd->size = 0.0f; + } + else if(eff->pd->shape==PFIELD_SHAPE_POINTS) { - break; - case PFIELD_MAGNET: - if(planar) - VecCopyf(temp,eff_vel); - else - /* magnetic field of a moving charge */ - Crossf(temp,eff_vel,vec_to_part); + if(eff->ob->derivedFinal) { + DerivedMesh *dm = eff->ob->derivedFinal; - Normalize(temp); + dm->getVertCo(dm, *efd->index, efd->loc); + dm->getVertNo(dm, *efd->index, efd->nor); - Crossf(temp2,velocity,temp); - VecAddf(mag_vec,mag_vec,temp2); + Mat4MulVecfl(eff->ob->obmat, efd->loc); + Mat4Mul3Vecfl(eff->ob->obmat, efd->nor); - VecMulf(mag_vec,force_val*falloff); - VecAddf(field,field,mag_vec); - break; - case PFIELD_HARMONIC: - if(planar) - Projf(mag_vec,vec_to_part,eff_vel); - else - VecCopyf(mag_vec,vec_to_part); + Normalize(efd->nor); - VecMulf(mag_vec,force_val*falloff); - VecSubf(field,field,mag_vec); + efd->size = 0.0f; - VecCopyf(mag_vec,velocity); - VecMulf(mag_vec,damp*2.0f*(float)sqrt(force_val)); - VecSubf(field,field,mag_vec); - break; - case PFIELD_CHARGE: - if(planar) - Projf(mag_vec,vec_to_part,eff_vel); - else - VecCopyf(mag_vec,vec_to_part); + /**/ + ret = 1; + } + } + else if(eff->psys) { + ParticleSimulationData sim = {eff->scene, eff->ob, eff->psys, NULL, NULL}; + ParticleData *pa = eff->psys->particles + *efd->index; + ParticleKey state; + + /* exclude the particle itself for self effecting particles */ + if(eff->psys == point->psys && *efd->index == point->index) + ; + else { + /* TODO: time from actual previous calculated frame (step might not be 1) */ + state.time = cfra - 1.0; + ret = psys_get_particle_state(&sim, *efd->index, &state, 0); + + /* TODO */ + //if(eff->pd->forcefiled == PFIELD_HARMONIC && ret==0) { + // if(pa->dietime < eff->psys->cfra) + // eff->flag |= PE_VELOCITY_TO_IMPULSE; + //} + + VECCOPY(efd->loc, state.co); + VECCOPY(efd->nor, state.vel); + if(real_velocity) { + VECCOPY(efd->vel, state.vel); + } - Normalize(mag_vec); + efd->size = pa->size; + } + } + else { + /* use center of object for distance calculus */ + Object *ob = eff->ob; + Object obcopy = *ob; + + where_is_object_time(eff->scene, ob, cfra); + + /* use z-axis as normal*/ + VECCOPY(efd->nor, ob->obmat[2]); + Normalize(efd->nor); + + /* for vortex the shape chooses between old / new force */ + if(eff->pd->shape == PFIELD_SHAPE_PLANE) { + /* efd->loc is closes point on effector xy-plane */ + float temp[3]; + VecSubf(temp, point->loc, ob->obmat[3]); + Projf(efd->loc, temp, efd->nor); + VecSubf(efd->loc, point->loc, efd->loc); + } + else { + VECCOPY(efd->loc, ob->obmat[3]); + } - VecMulf(mag_vec,charge*force_val*falloff); - VecAddf(field,field,mag_vec); - break; - case PFIELD_LENNARDJ: - { - float fac; + if(real_velocity) { + VECCOPY(efd->vel, ob->obmat[3]); + + where_is_object_time(eff->scene, ob, cfra - 1.0); + + VecSubf(efd->vel, efd->vel, ob->obmat[3]); + } + + *eff->ob = obcopy; + + efd->size = 0.0f; + + ret = 1; + } + + if(ret) { + VecSubf(efd->vec_to_point, point->loc, efd->loc); + efd->distance = VecLength(efd->vec_to_point); + + /* for some effectors we need the object center every time */ + VecSubf(efd->vec_to_point2, point->loc, eff->ob->obmat[3]); + VECCOPY(efd->nor2, eff->ob->obmat[2]); + Normalize(efd->nor2); + } + + return ret; +} +static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p) +{ + if(eff->pd->shape == PFIELD_SHAPE_POINTS) { + efd->index = p; + + *p = 0; + *tot = eff->ob->derivedFinal ? eff->ob->derivedFinal->numVertData : 1; + + if(*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) { + *p = point->index % *tot; + *tot = *p+1; + } + } + else if(eff->psys) { + efd->index = p; + + *p = 0; + *tot = eff->psys->totpart; + + if(eff->pd->forcefield == PFIELD_CHARGE) { + /* Only the charge of the effected particle is used for + interaction, not fall-offs. If the fall-offs aren't the + same this will be unphysical, but for animation this + could be the wanted behavior. If you want physical + correctness the fall-off should be spherical 2.0 anyways. + */ + efd->charge = eff->pd->f_strength; + } + else if(eff->pd->forcefield == PFIELD_HARMONIC) { + /* every particle is mapped to only one harmonic effector particle */ + *p= point->index % eff->psys->totpart; + *tot= *p + 1; + } + } + else { + *p = 0; + *tot = 1; + } +} +static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force) +{ + TexResult result[4]; + float tex_co[3], strength, force[3]; + float nabla = eff->pd->tex_nabla; + int hasrgb; + short mode = eff->pd->tex_mode; + + if(!eff->pd->tex) + return; + + result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0; + + strength= eff->pd->f_strength * efd->falloff; + + VECCOPY(tex_co,point->loc); + + if(eff->pd->flag & PFIELD_TEX_2D) { + float fac=-Inpf(tex_co, efd->nor); + VECADDFAC(tex_co, tex_co, efd->nor, fac); + } + + if(eff->pd->flag & PFIELD_TEX_OBJECT) { + Mat4Mul3Vecfl(eff->ob->obmat, tex_co); + } + + hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL,NULL, 1, result); + + if(hasrgb && mode==PFIELD_TEX_RGB) { + force[0] = (0.5f - result->tr) * strength; + force[1] = (0.5f - result->tg) * strength; + force[2] = (0.5f - result->tb) * strength; + } + else { + strength/=nabla; + + tex_co[0] += nabla; + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+1); + + tex_co[0] -= nabla; + tex_co[1] += nabla; + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+2); - if(planar) { - Projf(mag_vec,vec_to_part,eff_vel); - distance = VecLength(mag_vec); + tex_co[1] -= nabla; + tex_co[2] += nabla; + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+3); + + if(mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we dont have rgb fall back to grad */ + force[0] = (result[0].tin - result[1].tin) * strength; + force[1] = (result[0].tin - result[2].tin) * strength; + force[2] = (result[0].tin - result[3].tin) * strength; + } + else { /*PFIELD_TEX_CURL*/ + float dbdy, dgdz, drdz, dbdx, dgdx, drdy; + + dbdy = result[2].tb - result[0].tb; + dgdz = result[3].tg - result[0].tg; + drdz = result[3].tr - result[0].tr; + dbdx = result[1].tb - result[0].tb; + dgdx = result[1].tg - result[0].tg; + drdy = result[2].tr - result[0].tr; + + force[0] = (dbdy - dgdz) * strength; + force[1] = (drdz - dbdx) * strength; + force[2] = (dgdx - drdy) * strength; + } + } + + if(eff->pd->flag & PFIELD_TEX_2D){ + float fac = -Inpf(force, efd->nor); + VECADDFAC(force, force, efd->nor, fac); + } + + VecAddf(total_force, total_force, force); +} +void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force) +{ + PartDeflect *pd = eff->pd; + RNG *rng = pd->rng; + float force[3]={0,0,0}; + float temp[3]; + float fac; + float strength = pd->f_strength; + float damp = pd->f_damp; + float noise_factor = pd->f_noise; + + if(noise_factor > 0.0f) { + strength += wind_func(rng, noise_factor); + + if(ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)) + damp += wind_func(rng, noise_factor); + } + + VECCOPY(force, efd->vec_to_point); + + switch(pd->forcefield){ + case PFIELD_WIND: + Normalize(force); + strength *= (Inpf(force, efd->nor) >= 0.0f ? 1.0f : -1.0f); + VecMulf(force, strength * efd->falloff); + break; + case PFIELD_FORCE: + Normalize(force); + VecMulf(force, strength * efd->falloff); + break; + case PFIELD_VORTEX: + /* old vortex force */ + if(pd->shape == PFIELD_SHAPE_POINT) { + Crossf(force, efd->nor, efd->vec_to_point); + Normalize(force); + VecMulf(force, strength * efd->distance * efd->falloff); } + else { + /* new vortex force */ + Crossf(temp, efd->nor2, efd->vec_to_point2); + VecMulf(temp, strength * efd->falloff); + + Crossf(force, efd->nor2, temp); + VecMulf(force, strength * efd->falloff); + + VECADDFAC(temp, temp, point->vel, -point->vel_to_sec); + VecAddf(force, force, temp); + } + break; + case PFIELD_MAGNET: + if(eff->pd->shape == PFIELD_SHAPE_POINT) + /* magnetic field of a moving charge */ + Crossf(temp, efd->nor, efd->vec_to_point); else - VecCopyf(mag_vec,vec_to_part); - - /* at this distance the field is 60 times weaker than maximum */ - if(distance > 2.22 * (size+pa_size)) - break; + VecCopyf(temp, efd->nor); - fac = pow((size+pa_size)/distance,6.0); + Normalize(temp); + VecMulf(temp, strength * efd->falloff); + Crossf(force, point->vel, temp); + VecMulf(force, point->vel_to_sec); + break; + case PFIELD_HARMONIC: + VecMulf(force, -strength * efd->falloff); + VecCopyf(temp, point->vel); + VecMulf(temp, -damp * 2.0f * (float)sqrt(fabs(strength)) * point->vel_to_sec); + VecAddf(force, force, temp); + break; + case PFIELD_CHARGE: + VecMulf(force, point->charge * strength * efd->falloff); + break; + case PFIELD_LENNARDJ: + fac = pow((efd->size + point->size) / efd->distance, 6.0); - fac = - fac * (1.0 - fac) / distance; + fac = - fac * (1.0 - fac) / efd->distance; /* limit the repulsive term drastically to avoid huge forces */ fac = ((fac>2.0) ? 2.0 : fac); - /* 0.003715 is the fac value at 2.22 times (size+pa_size), - substracted to avoid discontinuity at the border - */ - VecMulf(mag_vec, force_val * (fac-0.0037315)); - VecAddf(field,field,mag_vec); + VecMulf(force, strength * fac); break; - } case PFIELD_BOID: /* Boid field is handled completely in boids code. */ + return; + case PFIELD_TURBULENCE: + if(pd->flag & PFIELD_GLOBAL_CO) { + VECCOPY(temp, point->loc); + } + else { + VECADD(temp, efd->vec_to_point2, efd->nor2); + } + force[0] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[0], temp[1], temp[2], 2,0,2); + force[1] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[1], temp[2], temp[0], 2,0,2); + force[2] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[2], temp[0], temp[1], 2,0,2); + VecMulf(force, strength * efd->falloff); + break; + case PFIELD_DRAG: + VECCOPY(force, point->vel); + fac = Normalize(force) * point->vel_to_sec; + + strength = MIN2(strength, 2.0f); + damp = MIN2(damp, 2.0f); + + VecMulf(force, -efd->falloff * fac * (strength * fac + damp)); break; } + + if(pd->flag & PFIELD_DO_LOCATION) { + VECADDFAC(total_force, total_force, force, 1.0f/point->vel_to_sec); + + if(ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) { + VECADDFAC(total_force, total_force, point->vel, -pd->f_flow * efd->falloff); + } + } + + if(pd->flag & PFIELD_DO_ROTATION && point->ave && point->rot) { + float xvec[3] = {1.0f, 0.0f, 0.0f}; + float dave[3]; + QuatMulVecf(point->rot, xvec); + Crossf(dave, xvec, force); + if(pd->f_flow != 0.0f) { + VECADDFAC(dave, dave, point->ave, -pd->f_flow * efd->falloff); + } + VecAddf(point->ave, point->ave, dave); + } } /* -------- pdDoEffectors() -------- @@ -528,7 +953,7 @@ void do_physical_effector(Scene *scene, Object *ob, float *opco, short type, flo guide = old speed of particle */ -void pdDoEffectors(Scene *scene, ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags) +void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse) { /* Modifies the force on a particle according to its @@ -543,43 +968,45 @@ void pdDoEffectors(Scene *scene, ListBase *lb, float *opco, float *force, float (particles are guided along a curve bezier or old nurbs) (is independent of other effectors) */ - Object *ob; - pEffectorCache *ec; - PartDeflect *pd; - - float distance, vec_to_part[3]; - float falloff; + EffectorCache *eff; + EffectorData efd; + int p=0, tot = 1; /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */ /* Check for min distance here? (yes would be cool to add that, ton) */ - for(ec = lb->first; ec; ec= ec->next) { + if(effectors) for(eff = effectors->first; eff; eff=eff->next) { /* object effectors were fully checked to be OK to evaluate! */ - ob= ec->ob; - pd= ob->pd; - - /* Get IPO force strength and fall off values here */ - where_is_object_time(scene, ob, cur_time); - - /* use center of object for distance calculus */ - VecSubf(vec_to_part, opco, ob->obmat[3]); - distance = VecLength(vec_to_part); - falloff=effector_falloff(pd,ob->obmat[2],vec_to_part); - - if(falloff<=0.0f) - ; /* don't do anything */ - else { - float field[3]={0,0,0}, tmp[3]; - VECCOPY(field, force); - do_physical_effector(scene, ob, opco, pd->forcefield,pd->f_strength,distance, - falloff, pd->f_dist, pd->f_damp, ob->obmat[2], vec_to_part, - speed,force, pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise, 0.0f, 0.0f); - - // for softbody backward compatibility - if(flags & PE_WIND_AS_SPEED){ - VECSUB(tmp, force, field); - VECSUB(speed, speed, tmp); + get_effector_tot(eff, &efd, point, &tot, &p); + + for(; p 0.0f) + efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point); + + if(efd.falloff <= 0.0f) + ; /* don't do anything */ + else if(eff->pd->forcefield == PFIELD_TEXTURE) + do_texture_effector(eff, &efd, point, force); + else { + float temp1[3]={0,0,0}, temp2[3]; + VECCOPY(temp1, force); + + do_physical_effector(eff, &efd, point, force); + + // for softbody backward compatibility + if(point->flag & PE_WIND_AS_SPEED && impulse){ + VECSUB(temp2, force, temp1); + VECSUB(impulse, impulse, temp2); + } + } + } + else if(eff->flag & PE_VELOCITY_TO_IMPULSE && impulse) { + /* special case for harmonic effector */ + VECADD(impulse, impulse, efd.vel); } } } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index ae2acd6aef7..de215ae4af9 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -33,6 +33,7 @@ #include "DNA_cloth_types.h" #include "DNA_scene_types.h" +#include "DNA_object_force.h" #include "BKE_effect.h" #include "BKE_global.h" @@ -1482,15 +1483,19 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, Cloth *cloth = clmd->clothObject; int i = 0; float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */ - float gravity[3]; + float gravity[3] = {0.0f, 0.0f, 0.0f}; float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; MFace *mfaces = cloth->mfaces; unsigned int numverts = cloth->numverts; LinkNode *search = cloth->springs; lfVector *winvec; + EffectedPoint epoint; - VECCOPY(gravity, clmd->sim_parms->gravity); - mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */ + /* global acceleration (gravitation) */ + if(clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + VECCOPY(gravity, clmd->scene->physics_settings.gravity); + mul_fvector_S(gravity, gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity); /* scale gravity force */ + } /* set dFdX jacobi matrix to zero */ init_bfmatrix(dFdX, ZERO); @@ -1525,10 +1530,9 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, // precalculate wind forces for(i = 0; i < cloth->numverts; i++) - { - float speed[3] = {0.0f, 0.0f,0.0f}; - - pdDoEffectors(clmd->scene, effectors, lX[i], winvec[i], speed, frame, 0.0f, 0); + { + pd_point_from_loc(clmd->scene, (float*)lX[i], (float*)lV[i], i, &epoint); + pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL); } for(i = 0; i < cloth->numfaces; i++) @@ -1656,9 +1660,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase while(step < tf) { // calculate forces - effectors= pdInitEffectors(clmd->scene, ob, NULL); cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M); - if(effectors) pdEndEffectors(effectors); // calculate new velocity simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI); @@ -1741,9 +1743,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase cp_lfvector(id->V, id->Vnew, numverts); // calculate - effectors= pdInitEffectors(clmd->scene, ob, NULL); cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M); - if(effectors) pdEndEffectors(effectors); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b9b9ea6b4f3..3b47c2f1830 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5971,6 +5971,8 @@ static void clothModifier_copyData(ModifierData *md, ModifierData *target) tclmd->point_cache = NULL; tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms); + if(clmd->sim_parms->effector_weights) + tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights); tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms); tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches); tclmd->clothObject = NULL; @@ -5992,8 +5994,11 @@ static void clothModifier_freeData(ModifierData *md) cloth_free_modifier_extern (clmd); - if(clmd->sim_parms) + if(clmd->sim_parms) { + if(clmd->sim_parms->effector_weights) + MEM_freeN(clmd->sim_parms->effector_weights); MEM_freeN(clmd->sim_parms); + } if(clmd->coll_parms) MEM_freeN(clmd->coll_parms); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4c729845745..579466ea626 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -91,6 +91,7 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_displist.h" +#include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_group.h" #include "BKE_icons.h" @@ -298,11 +299,8 @@ void free_object(Object *ob) free_constraints(&ob->constraints); - if(ob->pd){ - if(ob->pd->tex) - ob->pd->tex->id.us--; - MEM_freeN(ob->pd); - } + free_partdeflect(ob->pd); + if(ob->soft) sbFree(ob->soft); if(ob->bsoft) bsbFree(ob->bsoft); if(ob->gpulamp.first) GPU_lamp_free(ob); @@ -1069,6 +1067,9 @@ SoftBody *copy_softbody(SoftBody *sb) sbn->pointcache= BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches); + if(sb->effector_weights) + sbn->effector_weights = MEM_dupallocN(sb->effector_weights); + return sbn; } @@ -1129,11 +1130,9 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) psysn->pathcache= NULL; psysn->childcache= NULL; psysn->edit= NULL; - psysn->effectors.first= psysn->effectors.last= 0; psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL; psysn->childcachebufs.first = psysn->childcachebufs.last = NULL; - psysn->reactevents.first = psysn->reactevents.last = NULL; psysn->renderdata = NULL; psysn->pointcache= BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches); @@ -1278,6 +1277,8 @@ Object *copy_object(Object *ob) obn->pd= MEM_dupallocN(ob->pd); if(obn->pd->tex) id_us_plus(&(obn->pd->tex->id)); + if(obn->pd->rng) + obn->pd->rng = MEM_dupallocN(ob->pd->rng); } obn->soft= copy_softbody(ob->soft); obn->bsoft = copy_bulletsoftbody(ob->bsoft); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e18e7f54e49..e63b77a134e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -53,7 +53,7 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" #include "BLI_kdtree.h" -#include "BLI_linklist.h" +#include "BLI_listbase.h" #include "BLI_rand.h" #include "BLI_threads.h" @@ -61,6 +61,7 @@ #include "BKE_boids.h" #include "BKE_cloth.h" +#include "BKE_effect.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_lattice.h" @@ -96,8 +97,7 @@ int count_particles(ParticleSystem *psys){ int tot=0; LOOP_SHOWN_PARTICLES { - if(pa->alive == PARS_KILLED); - else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); + if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); else tot++; } @@ -109,8 +109,7 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ int tot=0; LOOP_SHOWN_PARTICLES { - if(pa->alive == PARS_KILLED); - else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); + if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); else if(p%totgr==cur) tot++; } @@ -302,15 +301,11 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys) /************************************************/ void psys_free_settings(ParticleSettings *part) { - if(part->pd) { - MEM_freeN(part->pd); - part->pd = NULL; - } - - if(part->pd2) { - MEM_freeN(part->pd2); - part->pd2 = NULL; - } + free_partdeflect(part->pd); + free_partdeflect(part->pd2); + + if(part->effector_weights) + MEM_freeN(part->effector_weights); boid_free_settings(part->boids); } @@ -428,21 +423,23 @@ void psys_free_particles(ParticleSystem *psys) } void psys_free_pdd(ParticleSystem *psys) { - if(psys->pdd->cdata) - MEM_freeN(psys->pdd->cdata); - psys->pdd->cdata = NULL; + if(psys->pdd) { + if(psys->pdd->cdata) + MEM_freeN(psys->pdd->cdata); + psys->pdd->cdata = NULL; - if(psys->pdd->vdata) - MEM_freeN(psys->pdd->vdata); - psys->pdd->vdata = NULL; + if(psys->pdd->vdata) + MEM_freeN(psys->pdd->vdata); + psys->pdd->vdata = NULL; - if(psys->pdd->ndata) - MEM_freeN(psys->pdd->ndata); - psys->pdd->ndata = NULL; + if(psys->pdd->ndata) + MEM_freeN(psys->pdd->ndata); + psys->pdd->ndata = NULL; - if(psys->pdd->vedata) - MEM_freeN(psys->pdd->vedata); - psys->pdd->vedata = NULL; + if(psys->pdd->vedata) + MEM_freeN(psys->pdd->vedata); + psys->pdd->vedata = NULL; + } } /* free everything */ void psys_free(Object *ob, ParticleSystem * psys) @@ -465,9 +462,6 @@ void psys_free(Object *ob, ParticleSystem * psys) psys->child = 0; psys->totchild = 0; } - - if(psys->effectors.first) - psys_end_effectors(psys); // check if we are last non-visible particle system for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){ @@ -493,10 +487,11 @@ void psys_free(Object *ob, ParticleSystem * psys) psys->pointcache = NULL; BLI_freelistN(&psys->targets); - BLI_freelistN(&psys->reactevents); BLI_kdtree_free(psys->tree); + pdEndEffectors(&psys->effectors); + if(psys->frand) MEM_freeN(psys->frand); @@ -1896,124 +1891,135 @@ static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clu VecLerpf(state->co,state->co,par->co,clump); } } +void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) +{ + EffectedPoint point; + ParticleKey state; + EffectorData efd; + EffectorCache *eff; + ParticleSystem *psys = sim->psys; + EffectorWeights *weights = sim->psys->part->effector_weights; + GuideEffectorData *data; + PARTICLE_P; + + if(!effectors) + return; + + LOOP_PARTICLES { + psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,state.co,0,0,0,0,0); + pd_point_from_particle(sim, pa, &state, &point); + + for(eff = effectors->first; eff; eff=eff->next) { + if(eff->pd->forcefield != PFIELD_GUIDE) + continue; -int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase *lb) + if(!eff->guide_data) + eff->guide_data = MEM_callocN(sizeof(GuideEffectorData)*psys->totpart, "GuideEffectorData"); + + data = eff->guide_data + p; + + VECSUB(efd.vec_to_point, state.co, eff->guide_loc); + VECCOPY(efd.nor, eff->guide_dir); + efd.distance = VecLength(efd.vec_to_point); + + VECCOPY(data->vec_to_point, efd.vec_to_point); + data->strength = effector_falloff(eff, &efd, &point, weights); + } + } +} +int do_guides(ListBase *effectors, ParticleKey *state, int index, float time) { + EffectorCache *eff; PartDeflect *pd; - ParticleEffectorCache *ec; - Object *eob; Curve *cu; ParticleKey key, par; + GuideEffectorData *data; - float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0; - float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f}; - float veffect[3]={0.0,0.0,0.0}, guidetime; + float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f}; + float guidevec[4], guidedir[3], rot2[4], temp[3]; + float guidetime, radius, angle, totstrength = 0.0f; + float vec_to_point[3]; - effect[0]=effect[1]=effect[2]=0.0; + if(effectors) for(eff = effectors->first; eff; eff=eff->next) { + pd = eff->pd; - if(lb->first){ - for(ec = lb->first; ec; ec= ec->next){ - eob= ec->ob; - if(ec->type & PSYS_EC_EFFECTOR){ - pd=eob->pd; - if(pd->forcefield==PFIELD_GUIDE){ - cu = (Curve*)eob->data; - - distance=ec->distances[pa_num]; - mindist=pd->f_strength; + if(pd->forcefield != PFIELD_GUIDE) + continue; - VECCOPY(pa_loc, ec->locations+3*pa_num); - VECCOPY(pa_zero,pa_loc); - VECADD(pa_zero,pa_zero,ec->firstloc); + data = eff->guide_data + index; - guidetime=time/(1.0-pd->free_end); + if(data->strength <= 0.0f) + continue; - /* WARNING: bails out with continue here */ - if(((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) || guidetime>1.0f) continue; + guidetime = time / (1.0 - pd->free_end); - if(guidetime>1.0f) continue; + if(guidetime>1.0f) + continue; - /* calculate contribution factor for this guide */ - f_force=1.0f; - if(distance<=mindist); - else if(pd->flag & PFIELD_USEMAX) { - if(mindist>=pd->maxdist) f_force= 0.0f; - else if(pd->f_power!=0.0f){ - f_force= 1.0f - (distance-mindist)/(pd->maxdist - mindist); - f_force = (float)pow(f_force, pd->f_power); - } - } - else if(pd->f_power!=0.0f){ - f_force= 1.0f/(1.0f + distance-mindist); - f_force = (float)pow(f_force, pd->f_power); - } + cu = (Curve*)eff->ob->data; - if(pd->flag & PFIELD_GUIDE_PATH_ADD) - where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius); - else - where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius); + if(pd->flag & PFIELD_GUIDE_PATH_ADD) { + if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius)==0) + return 0; + } + else { + if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius)==0) + return 0; + } - Mat4MulVecfl(ec->ob->obmat,guidevec); - Mat4Mul3Vecfl(ec->ob->obmat,guidedir); + Mat4MulVecfl(eff->ob->obmat, guidevec); + Mat4Mul3Vecfl(eff->ob->obmat, guidedir); - Normalize(guidedir); + Normalize(guidedir); - if(guidetime!=0.0){ - /* curve direction */ - Crossf(temp, ec->firstdir, guidedir); - angle=Inpf(ec->firstdir,guidedir)/(VecLength(ec->firstdir)); - angle=saacos(angle); - VecRotToQuat(temp,angle,rot2); - QuatMulVecf(rot2,pa_loc); + VECCOPY(vec_to_point, data->vec_to_point); - /* curve tilt */ - VecRotToQuat(guidedir,guidevec[3]-ec->firstloc[3],rot2); - QuatMulVecf(rot2,pa_loc); + if(guidetime != 0.0){ + /* curve direction */ + Crossf(temp, eff->guide_dir, guidedir); + angle = Inpf(eff->guide_dir, guidedir)/(VecLength(eff->guide_dir)); + angle = saacos(angle); + VecRotToQuat(temp, angle, rot2); + QuatMulVecf(rot2, vec_to_point); - //vectoquat(guidedir, pd->kink_axis, (pd->kink_axis+1)%3, q); - //QuatMul(par.rot,rot2,q); - } - //else{ - // par.rot[0]=1.0f; - // par.rot[1]=par.rot[2]=par.rot[3]=0.0f; - //} - - /* curve taper */ - if(cu->taperobj) - VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100)); - - else{ /* curve size*/ - if(cu->flag & CU_PATH_RADIUS) { - VecMulf(pa_loc, radius); - } - } - par.co[0]=par.co[1]=par.co[2]=0.0f; - VECCOPY(key.co,pa_loc); - do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0); - do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f); - VECCOPY(pa_loc,key.co); - - VECADD(pa_loc,pa_loc,guidevec); - VECSUB(pa_loc,pa_loc,pa_zero); - VECADDFAC(effect,effect,pa_loc,f_force); - VECADDFAC(veffect,veffect,guidedir,f_force); - totforce+=f_force; - } - } + /* curve tilt */ + VecRotToQuat(guidedir, guidevec[3] - eff->guide_loc[3], rot2); + QuatMulVecf(rot2, vec_to_point); } - if(totforce!=0.0){ - if(totforce>1.0) - VecMulf(effect,1.0f/totforce); - CLAMP(totforce,0.0,1.0); - VECADD(effect,effect,pa_zero); - VecLerpf(state->co,state->co,effect,totforce); + /* curve taper */ + if(cu->taperobj) + VecMulf(vec_to_point, calc_taper(eff->scene, cu->taperobj, (int)(data->strength*guidetime*100.0), 100)); - Normalize(veffect); - VecMulf(veffect,VecLength(state->vel)); - VECCOPY(state->vel,veffect); - return 1; + else{ /* curve size*/ + if(cu->flag & CU_PATH_RADIUS) { + VecMulf(vec_to_point, radius); + } } + par.co[0] = par.co[1] = par.co[2] = 0.0f; + VECCOPY(key.co, vec_to_point); + do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0); + do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f); + VECCOPY(vec_to_point, key.co); + + VECADD(vec_to_point, vec_to_point, guidevec); + //VECSUB(pa_loc,pa_loc,pa_zero); + VECADDFAC(effect, effect, vec_to_point, data->strength); + VECADDFAC(veffect, veffect, guidedir, data->strength); + totstrength += data->strength; + } + + if(totstrength != 0.0){ + if(totstrength > 1.0) + VecMulf(effect, 1.0f / totstrength); + CLAMP(totstrength, 0.0, 1.0); + //VECADD(effect,effect,pa_zero); + VecLerpf(state->co, state->co, effect, totstrength); + + Normalize(veffect); + VecMulf(veffect, VecLength(state->vel)); + VECCOPY(state->vel, veffect); + return 1; } return 0; } @@ -2053,14 +2059,18 @@ static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheK { float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}; ParticleKey eff_key; - ParticleData *pa; + EffectedPoint epoint; + + /* Don't apply effectors for dynamic hair, otherwise the effectors don't get applied twice. */ + if(sim->psys->flag & PSYS_HAIR_DYNAMICS) + return; VECCOPY(eff_key.co,(ca-1)->co); VECCOPY(eff_key.vel,(ca-1)->vel); QUATCOPY(eff_key.rot,(ca-1)->rot); - pa= sim->psys->particles+i; - do_effectors(sim, i, pa, &eff_key, rootco, force, vel, dfra, cfra); + pd_point_from_particle(sim, sim->psys->particles+i, &eff_key, &epoint); + pdDoEffectors(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL); VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps); @@ -2777,9 +2787,9 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec); /* apply guide curves to path data */ - if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0) + if(sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT)==0) /* ca is safe to cast, since only co and vel are used */ - do_guide(sim->scene, (ParticleKey*)ca, p, (float)k/(float)steps, &psys->effectors); + do_guides(sim->psys->effectors, (ParticleKey*)ca, p, (float)k/(float)steps); /* apply lattice */ if(psys->lattice) @@ -3187,8 +3197,6 @@ void object_remove_particle_system(Scene *scene, Object *ob) } static void default_particle_settings(ParticleSettings *part) { - int i; - part->type= PART_EMITTER; part->distr= PART_DISTR_JIT; part->draw_as = PART_DRAW_REND; @@ -3199,7 +3207,7 @@ static void default_particle_settings(ParticleSettings *part) part->flag=PART_REACT_MULTIPLE|PART_HAIR_GEOMETRY|PART_EDISTR|PART_TRAND; part->sta= 1.0; - part->end= 100.0; + part->end= 200.0; part->lifetime= 50.0; part->jitfac= 1.0; part->totpart= 1000; @@ -3249,10 +3257,6 @@ static void default_particle_settings(ParticleSettings *part) part->keyed_loops = 1; - for(i=0; i<10; i++) - part->effector_weight[i]=1.0f; - - #if 0 // XXX old animation system part->ipo = NULL; #endif // XXX old animation system @@ -3261,6 +3265,9 @@ static void default_particle_settings(ParticleSettings *part) part->simplify_rate= 1.0f; part->simplify_transition= 0.1f; part->simplify_viewport= 0.8; + + if(!part->effector_weights) + part->effector_weights = BKE_add_effector_weights(NULL); } @@ -3348,24 +3355,6 @@ void make_local_particlesettings(ParticleSettings *part) } } } -void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc) -{ - Base *base = scene->base.first; - ParticleSystem *psys; - int flush; - - for(base = scene->base.first; base; base = base->next) { - flush = 0; - for(psys = base->object->particlesystem.first; psys; psys=psys->next) { - if(psys->part == part) { - psys->recalc |= recalc; - flush++; - } - } - if(flush) - DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); - } -} /************************************************/ /* Textures */ @@ -3646,7 +3635,7 @@ static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *pte if(part->flag & PART_CHILD_EFFECT) /* state is safe to cast, since only co and vel are used */ - guided = do_guide(sim->scene, (ParticleKey*)state, cpa->parent, t, &(sim->psys->effectors)); + guided = do_guides(sim->psys->effectors, (ParticleKey*)state, cpa->parent, t); if(guided==0){ if(part->kink) @@ -3716,8 +3705,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * Mat4MulVecfl(hairmat, state->co); Mat4Mul3Vecfl(hairmat, state->vel); - if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) { - do_guide(sim->scene, state, p, state->time, &psys->effectors); + if(sim->psys->effectors && (part->flag & PART_CHILD_GUIDE)==0) { + do_guides(sim->psys->effectors, state, p, state->time); /* TODO: proper velocity handling */ } @@ -3905,8 +3894,6 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } if(pa) { - if(pa->alive == PARS_KILLED) return 0; - if(!always) if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0) || (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0)) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1b6d56e6459..77cef689d09 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -58,7 +58,7 @@ #include "BLI_blenlib.h" #include "BLI_kdtree.h" #include "BLI_kdopbvh.h" -#include "BLI_linklist.h" +#include "BLI_listbase.h" #include "BLI_threads.h" #include "BKE_anim.h" @@ -132,9 +132,6 @@ void psys_reset(ParticleSystem *psys, int mode) psys->totkeyed= 0; psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED); - if(psys->reactevents.first) - BLI_freelistN(&psys->reactevents); - if(psys->edit && psys->free_edit) { psys->free_edit(psys->edit); psys->edit = NULL; @@ -1796,8 +1793,9 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, /* and gravity in r_ve */ bpa->gravity[0] = bpa->gravity[1] = 0.0f; bpa->gravity[2] = -1.0f; - if(part->acc[2]!=0.0f) - bpa->gravity[2] = part->acc[2]; + if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) + && sim->scene->physics_settings.gravity[2]!=0.0f) + bpa->gravity[2] = sim->scene->physics_settings.gravity[2]; /* calculate rotation matrix */ Projf(dvec, r_vel, pa->state.ave); @@ -1936,8 +1934,12 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, pa->dietime = pa->time + pa->lifetime; - if(pa->time >= cfra) + if(pa->time > cfra) pa->alive = PARS_UNBORN; + else if(pa->dietime <= cfra) + pa->alive = PARS_DEAD; + else + pa->alive = PARS_ALIVE; pa->state.time = cfra; } @@ -2203,12 +2205,12 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra /************************************************/ /* Effectors */ /************************************************/ -static void update_particle_tree(ParticleSystem *psys) +void psys_update_particle_tree(ParticleSystem *psys, float cfra) { if(psys) { PARTICLE_P; - if(!psys->tree || psys->tree_frame != psys->cfra) { + if(!psys->tree || psys->tree_frame != cfra) { BLI_kdtree_free(psys->tree); @@ -2216,7 +2218,10 @@ static void update_particle_tree(ParticleSystem *psys) LOOP_SHOWN_PARTICLES { if(pa->alive == PARS_ALIVE) - BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL); + if(pa->state.time == cfra) + BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL); + else + BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL); } BLI_kdtree_balance(psys->tree); @@ -2224,535 +2229,12 @@ static void update_particle_tree(ParticleSystem *psys) } } } -static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field) -{ - TexResult result[4]; - float tex_co[3], strength, mag_vec[3]; - int hasrgb; - if(tex==NULL) return; - - result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0; - - strength= force_val*falloff; - - VECCOPY(tex_co,pa_co); - - if(is_2d){ - float fac=-Inpf(tex_co,obmat[2]); - VECADDFAC(tex_co,tex_co,obmat[2],fac); - } - - if(object){ - VecSubf(tex_co,tex_co,obmat[3]); - Mat4Mul3Vecfl(obmat,tex_co); - } - - hasrgb = multitex_ext(tex, tex_co, NULL,NULL, 1, result); - - if(hasrgb && mode==PFIELD_TEX_RGB){ - mag_vec[0]= (0.5f-result->tr)*strength; - mag_vec[1]= (0.5f-result->tg)*strength; - mag_vec[2]= (0.5f-result->tb)*strength; - } - else{ - strength/=nabla; - - tex_co[0]+= nabla; - multitex_ext(tex, tex_co, NULL,NULL, 1, result+1); - - tex_co[0]-= nabla; - tex_co[1]+= nabla; - multitex_ext(tex, tex_co, NULL,NULL, 1, result+2); - - tex_co[1]-= nabla; - tex_co[2]+= nabla; - multitex_ext(tex, tex_co, NULL,NULL, 1, result+3); - - if(mode==PFIELD_TEX_GRAD || !hasrgb){ /* if we dont have rgb fall back to grad */ - mag_vec[0]= (result[0].tin-result[1].tin)*strength; - mag_vec[1]= (result[0].tin-result[2].tin)*strength; - mag_vec[2]= (result[0].tin-result[3].tin)*strength; - } - else{ /*PFIELD_TEX_CURL*/ - float dbdy,dgdz,drdz,dbdx,dgdx,drdy; - - dbdy= result[2].tb-result[0].tb; - dgdz= result[3].tg-result[0].tg; - drdz= result[3].tr-result[0].tr; - dbdx= result[1].tb-result[0].tb; - dgdx= result[1].tg-result[0].tg; - drdy= result[2].tr-result[0].tr; - - mag_vec[0]=(dbdy-dgdz)*strength; - mag_vec[1]=(drdz-dbdx)*strength; - mag_vec[2]=(dgdx-drdy)*strength; - } - } - - if(is_2d){ - float fac=-Inpf(mag_vec,obmat[2]); - VECADDFAC(mag_vec,mag_vec,obmat[2],fac); - } - - VecAddf(field,field,mag_vec); -} -static void add_to_effectors(ParticleSimulationData *sim, ListBase *lb, Object *ob) -{ - ParticleEffectorCache *ec; - PartDeflect *pd= ob->pd; - short type=0,i; - - if(pd && ob != sim->ob){ - if(pd->forcefield == PFIELD_GUIDE) { - if(ob->type==OB_CURVE) { - Curve *cu= ob->data; - if(cu->flag & CU_PATH) { - if(cu->path==NULL || cu->path->data==NULL) - makeDispListCurveTypes(sim->scene, ob, 0); - if(cu->path && cu->path->data) { - type |= PSYS_EC_EFFECTOR; - } - } - } - } - else if(pd->forcefield) - { - type |= PSYS_EC_EFFECTOR; - } - } - - if(pd && pd->deflect) - type |= PSYS_EC_DEFLECT; - - if(type){ - ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache"); - ec->ob= ob; - ec->type=type; - ec->distances=0; - ec->locations=0; - ec->rng = rng_new(1); - rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed - - BLI_addtail(lb, ec); - } - - type=0; - - /* add particles as different effectors */ - if(ob->particlesystem.first){ - ParticleSystem *epsys=ob->particlesystem.first; - ParticleSettings *epart=0; - //Object *tob; - - for(i=0; epsys; epsys=epsys->next,i++){ - if(!psys_check_enabled(ob, epsys)) - continue; - type=0; - if(epsys!=sim->psys || (sim->psys->part->flag & PART_SELF_EFFECT)){ - epart=epsys->part; - - if((epsys->part->pd && epsys->part->pd->forcefield) - || (epsys->part->pd2 && epsys->part->pd2->forcefield)) - { - type=PSYS_EC_PARTICLE; - } - - //if(epart->type==PART_REACTOR) { - // tob=epsys->target_ob; - // if(tob==0) - // tob=ob; - // if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==sim->psys) - // type|=PSYS_EC_REACTOR; - //} - - if(type){ - ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache"); - ec->ob= ob; - ec->type=type; - ec->psys_nbr=i; - ec->rng = rng_new(1); - rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); - - BLI_addtail(lb, ec); - } - } - } - - } -} - -static void psys_init_effectors_recurs(ParticleSimulationData *sim, Object *ob, ListBase *listb, int level) -{ - Group *group; - GroupObject *go; - unsigned int layer= sim->ob->lay; - - if(level>MAX_DUPLI_RECUR) return; - - if(ob->lay & layer) { - if(ob->pd || ob->particlesystem.first) - add_to_effectors(sim, listb, ob); - - if(ob->dup_group) { - group= ob->dup_group; - for(go= group->gobject.first; go; go= go->next) - psys_init_effectors_recurs(sim, go->ob, listb, level+1); - } - } -} - -static void psys_init_effectors(ParticleSimulationData *sim, Group *group) -{ - ListBase *listb= &sim->psys->effectors; - Base *base; - - listb->first=listb->last=0; - - if(group) { - GroupObject *go; - - for(go= group->gobject.first; go; go= go->next) - psys_init_effectors_recurs(sim, go->ob, listb, 0); - } - else { - for(base = sim->scene->base.first; base; base= base->next) - psys_init_effectors_recurs(sim, base->object, listb, 0); - } -} - -void psys_end_effectors(ParticleSystem *psys) -{ - /* NOTE: - ec->ob is not valid in here anymore! - dg - */ - ParticleEffectorCache *ec = psys->effectors.first; - - for(; ec; ec= ec->next){ - if(ec->distances) - MEM_freeN(ec->distances); - - if(ec->locations) - MEM_freeN(ec->locations); - - if(ec->face_minmax) - MEM_freeN(ec->face_minmax); - - if(ec->vert_cos) - MEM_freeN(ec->vert_cos); - - if(ec->tree) - BLI_kdtree_free(ec->tree); - - if(ec->rng) - rng_free(ec->rng); - } - - BLI_freelistN(&psys->effectors); -} - -/* precalcs effectors and returns 1 if there were any collision object - * so collision checks can be avoided as quickly as possible */ -static int precalc_effectors(ParticleSimulationData *sim, float cfra) -{ - ParticleSystem *psys = sim->psys; - ListBase *lb=&psys->effectors; - ParticleEffectorCache *ec; - ParticleSettings *part=psys->part; - PARTICLE_P; - int totpart, collision = 0; - float vec2[3],loc[3],radius,*co=0; - - for(ec= lb->first; ec; ec= ec->next) { - PartDeflect *pd= ec->ob->pd; - co = NULL; - - if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE - && part->phystype!=PART_PHYS_BOIDS) { - float vec[4]; - - where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius); - - Mat4MulVecfl(ec->ob->obmat,vec); - Mat4Mul3Vecfl(ec->ob->obmat,vec2); - - QUATCOPY(ec->firstloc,vec); - VECCOPY(ec->firstdir,vec2); - - /* TODO - use 'radius' to adjust the effector */ - - totpart=psys->totpart; - - if(totpart){ - ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances"); - ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations"); - - LOOP_PARTICLES { - if(part->from == PART_FROM_PARTICLE) { - VECCOPY(loc, pa->fuv); - } - else - psys_particle_on_emitter(sim->psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0); - - Mat4MulVecfl(sim->ob->obmat,loc); - ec->distances[p]=VecLenf(loc,vec); - VECSUB(loc,loc,vec); - VECCOPY(ec->locations+3*p,loc); - } - } - } - else if(ec->type==PSYS_EC_PARTICLE){ - ParticleSimulationData esim = {sim->scene, ec->ob, BLI_findlink(&ec->ob->particlesystem, ec->psys_nbr), NULL}; - ParticleSettings *epart = esim.psys->part; - ParticleData *epa; - int p, totepart = esim.psys->totpart; - - if(psys->part->phystype==PART_PHYS_BOIDS){ - ParticleKey state; - PartDeflect *pd; - - pd= epart->pd; - if(pd->forcefield==PFIELD_FORCE && totepart){ - KDTree *tree; - - tree=BLI_kdtree_new(totepart); - ec->tree=tree; - - for(p=0, epa=esim.psys->particles; palive==PARS_ALIVE && psys_get_particle_state(&esim,p,&state,0)) - BLI_kdtree_insert(tree, p, state.co, NULL); - - BLI_kdtree_balance(tree); - } - } - - } - else if(ec->type==PSYS_EC_DEFLECT) { - CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) ); - if(collmd) { - collision_move_object(collmd, 1.0, 0.0); - collision = 1; - } - } - } - - return collision; -} -/* updates particle effectors and returns if any collision objects were found */ -int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc) -{ - psys_end_effectors(sim->psys); - psys_init_effectors(sim, sim->psys->part->eff_group); - return (precalc ? precalc_effectors(sim, cfra) : 0); -} -int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object *ob, PartDeflect *pd, float *co, float *nor, float *vel, int *index) +static void psys_update_effectors(ParticleSimulationData *sim) { - SurfaceModifierData *surmd = NULL; - int ret = 0; - - if(sur) - surmd = sur; - else if(pd && pd->flag&PFIELD_SURFACE) - { - surmd = (SurfaceModifierData *)modifiers_findByType ( ob, eModifierType_Surface ); - } - - if(surmd) { - /* closest point in the object surface is an effector */ - BVHTreeNearest nearest; - - nearest.index = -1; - nearest.dist = FLT_MAX; - - BLI_bvhtree_find_nearest(surmd->bvhtree->tree, pco, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree); - - if(nearest.index != -1) { - VECCOPY(co, nearest.co); - - if(nor) { - VECCOPY(nor, nearest.no); - } - - if(vel) { - MFace *mface = CDDM_get_face(surmd->dm, nearest.index); - - VECCOPY(vel, surmd->v[mface->v1].co); - VecAddf(vel, vel, surmd->v[mface->v2].co); - VecAddf(vel, vel, surmd->v[mface->v3].co); - if(mface->v4) - VecAddf(vel, vel, surmd->v[mface->v4].co); - - VecMulf(vel, mface->v4 ? 0.25f : 0.333f); - } - - if(index) - *index = nearest.index; - - ret = 1; - } - else { - co[0] = co[1] = co[2] = 0.0f; - - if(nor) - nor[0] = nor[1] = nor[2] = 0.0f; - - if(vel) - vel[0] = vel[1] = vel[2] = 0.0f; - } - } - else { - /* use center of object for distance calculus */ - VECCOPY(co, ob->obmat[3]); - - if(nor) { - VECCOPY(nor, ob->obmat[2]); - } - - if(vel) { - Object obcopy = *ob; - - VECCOPY(vel, ob->obmat[3]); - - where_is_object_time(scene, ob, scene->r.cfra - 1.0); - - VecSubf(vel, vel, ob->obmat[3]); - - *ob = obcopy; - } - } - - return ret; -} -/* calculate forces that all effectors apply to a particle*/ -void do_effectors(ParticleSimulationData *sim, int pa_no, ParticleData *pa, ParticleKey *state, float *rootco, float *force_field, float *vel,float framestep, float cfra) -{ - Object *eob; - ParticleSystem *psys = sim->psys; - ParticleSettings *epart; - ParticleData *epa; - ParticleKey estate; - PartDeflect *pd; - ListBase *lb=&psys->effectors; - ParticleEffectorCache *ec; - float distance, vec_to_part[3], pco[3], co[3]; - float falloff, charge = 0.0f, strength; - int p, face_index=-1; - - /* check all effector objects for interaction */ - if(lb->first){ - if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){ - /* Only the charge of the effected particle is used for - interaction, not fall-offs. If the fall-offs aren't the - same this will be unphysical, but for animation this - could be the wanted behavior. If you want physical - correctness the fall-off should be spherical 2.0 anyways. - */ - charge = psys->part->pd->f_strength; - } - if(psys->part->pd2 && psys->part->pd2->forcefield==PFIELD_CHARGE){ - charge += psys->part->pd2->f_strength; - } - for(ec = lb->first; ec; ec= ec->next){ - eob= ec->ob; - if(ec->type & PSYS_EC_EFFECTOR){ - pd=eob->pd; - if(psys->part->type!=PART_HAIR && psys->part->integrator) - where_is_object_time(sim->scene, eob, cfra); - - if(pd && pd->flag&PFIELD_SURFACE) { - float velocity[3]; - /* using velocity corrected location allows for easier sliding over effector surface */ - VecCopyf(velocity, state->vel); - VecMulf(velocity, psys_get_timestep(sim)); - VecAddf(pco, state->co, velocity); - } - else - VECCOPY(pco, state->co); - - effector_find_co(sim->scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index); - - VecSubf(vec_to_part, state->co, co); - - distance = VecLength(vec_to_part); - - falloff=effector_falloff(pd,eob->obmat[2],vec_to_part); - - strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield]; - - if(falloff<=0.0f) - ; /* don't do anything */ - else if(pd->forcefield==PFIELD_TEXTURE) { - do_texture_effector(pd->tex, pd->tex_mode, pd->flag&PFIELD_TEX_2D, pd->tex_nabla, - pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat, - strength, falloff, force_field); - } else { - do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance, - falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part, - state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size); - } - } - if(ec->type & PSYS_EC_PARTICLE){ - ParticleSimulationData esim = {sim->scene, eob, BLI_findlink(&eob->particlesystem,ec->psys_nbr), NULL}; - int totepart, i; - - epart = esim.psys->part; - pd = epart->pd; - totepart = esim.psys->totpart; - - if(totepart <= 0) - continue; - - if(pd && pd->forcefield==PFIELD_HARMONIC){ - /* every particle is mapped to only one harmonic effector particle */ - p= pa_no%esim.psys->totpart; - totepart= p+1; - } - else{ - p=0; - } - - esim.psys->lattice= psys_get_lattice(sim); - - for(; pparticles + p; - estate.time = cfra; - if(psys_get_particle_state(&esim, p, &estate, 0)){ - VECSUB(vec_to_part, state->co, estate.co); - distance = VecLength(vec_to_part); - - for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) { - if(pd==NULL || pd->forcefield==0) continue; - - falloff = effector_falloff(pd, estate.vel, vec_to_part); - - strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield]; - - if(falloff<=0.0f) - ; /* don't do anything */ - else - do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance, - falloff,epart->size,pd->f_damp,estate.vel,vec_to_part, - state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size); - } - } - else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){ - /* first step after key release */ - psys_get_particle_state(&esim, p, &estate, 1); - VECADD(vel, vel, estate.vel); - /* TODO: add rotation handling here too */ - } - } - - if(esim.psys->lattice){ - end_latt_deform(esim.psys->lattice); - esim.psys->lattice= NULL; - } - } - } - } + pdEndEffectors(&sim->psys->effectors); + sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights); + precalc_guides(sim, sim->psys->effectors); } /************************************************/ @@ -2763,9 +2245,10 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra { ParticleSettings *part = sim->psys->part; ParticleData *pa = sim->psys->particles + p; + EffectedPoint epoint; ParticleKey states[5], tkey; float timestep = psys_get_timestep(sim); - float force[3],tvel[3],dx[4][3],dv[4][3]; + float force[3],impulse[3],dx[4][3],dv[4][3]; float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra; int i, steps=1; @@ -2791,10 +2274,11 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra for(i=0; itype != PART_HAIR) - do_effectors(sim, p, pa, states+i, states->co, force, tvel, dfra, fra); + pd_point_from_particle(sim, pa, states+i, &epoint); + if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR) + pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse); /* calculate air-particle interaction */ if(part->dragfac!=0.0f){ @@ -2813,10 +2297,17 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra VecMulf(force,1.0f/pa_mass); /* add global acceleration (gravitation) */ - VECADD(force,force,part->acc); + if(sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY + /* normal gravity is too strong for hair so it's disabled by default */ + && (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) { + float gravity[3]; + VECCOPY(gravity, sim->scene->physics_settings.gravity); + VecMulf(gravity, part->effector_weights->global_gravity); + VECADD(force,force,gravity); + } /* calculate next state */ - VECADD(states[i].vel,states[i].vel,tvel); + VECADD(states[i].vel,states[i].vel,impulse); switch(part->integrator){ case PART_INT_EULER: @@ -2889,6 +2380,8 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra if(part->dampfac!=0.0) VecMulf(pa->state.vel,1.0f-part->dampfac); + VECCOPY(pa->state.ave, states->ave); + /* finally we do guides */ time=(cfra-pa->time)/pa->lifetime; CLAMP(time,0.0,1.0); @@ -2898,7 +2391,7 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra tkey.time=pa->state.time; if(part->type != PART_HAIR) { - if(do_guide(sim->scene, &tkey, p, time, &sim->psys->effectors)) { + if(do_guides(sim->psys->effectors, &tkey, p, time)) { VECCOPY(pa->state.co,tkey.co); /* guides don't produce valid velocity */ VECSUB(pa->state.vel,tkey.co,pa->prev_state.co); @@ -3129,7 +2622,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B VECCOPY(col->vel,vel); - col->ob = col->ob_t; + col->hit_ob = col->ob; + col->hit_md = col->md; } } } @@ -3146,7 +2640,8 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B VECCOPY(col->vel,vel); - col->ob = col->ob_t; + col->hit_ob = col->ob; + col->hit_md = col->md; } } } @@ -3163,13 +2658,11 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B /* 1. check for all possible deflectors for closest intersection on particle path */ /* 2. if deflection was found kill the particle or calculate new coordinates */ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){ - Object *ob = NULL, *skip_ob = NULL; + Object *ground_ob = NULL; ParticleSettings *part = sim->psys->part; - ListBase *lb=&sim->psys->effectors; - ParticleEffectorCache *ec; - ParticleKey reaction_state; - ParticleCollision col; ParticleData *pa = sim->psys->particles + p; + ParticleCollision col; + ColliderCache *coll; BVHTreeRayHit hit; float ray_dir[3], zerovec[3]={0.0,0.0,0.0}; float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f; @@ -3185,11 +2678,11 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo BoidParticle *bpa = pa->boid; radius = pa->size; boid_z = pa->state.co[2]; - skip_ob = bpa->ground; + ground_ob = bpa->ground; } /* 10 iterations to catch multiple deflections */ - if(lb->first) while(deflections < max_deflections){ + if(sim->colliders) while(deflections < max_deflections){ /* 1. */ VECSUB(ray_dir, col.co2, col.co1); @@ -3201,32 +2694,25 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo if(hit.dist == 0.0f) hit.dist = col.ray_len = 0.000001f; - for(ec=lb->first; ec; ec=ec->next){ - if(ec->type & PSYS_EC_DEFLECT){ - ob= ec->ob; - - /* for boids: don't check with current ground object */ - if(ob==skip_ob) - continue; - - /* particles should not collide with emitter at birth */ - if(ob==sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra) - continue; + for(coll = sim->colliders->first; coll; coll=coll->next){ + /* for boids: don't check with current ground object */ + if(coll->ob == ground_ob) + continue; - if(part->type!=PART_HAIR) - where_is_object_time(sim->scene, sim->ob, cfra); + /* particles should not collide with emitter at birth */ + if(coll->ob == sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra) + continue; - col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) ); - col.ob_t = ob; + col.ob = coll->ob; + col.md = coll->collmd; - if(col.md && col.md->bvhtree) - BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col); - } + if(col.md && col.md->bvhtree) + BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col); } /* 2. */ if(hit.index>=0) { - PartDeflect *pd = col.ob->pd; + PartDeflect *pd = col.hit_ob->pd; int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0; float co[3]; /* point of collision */ float vec[3]; /* movement through collision */ @@ -3253,9 +2739,6 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo /* particle is dead so we don't need to calculate further */ deflections=max_deflections; - - /* store for reactors */ - copy_particle_key(&reaction_state, &pa->state, 0); } else { float nor_vec[3], tan_vec[3], tan_vel[3], vel[3]; @@ -3416,7 +2899,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra) if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) skip = 1; /* only hair, keyed and baked stuff can have paths */ - else if(part->ren_as != PART_DRAW_PATH) + else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR))) skip = 1; /* particle visualization must be set as path */ else if(!psys->renderdata) { if(part->draw_as != PART_DRAW_REND) @@ -3555,8 +3038,11 @@ static void do_hair_dynamics(ParticleSimulationData *sim) psys->hair_out_dm->release(psys->hair_out_dm); psys->clmd->point_cache = psys->pointcache; + psys->clmd->sim_parms->effector_weights = psys->part->effector_weights; psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0); + + psys->clmd->sim_parms->effector_weights = NULL; } static void hair_step(ParticleSimulationData *sim, float cfra) { @@ -3586,7 +3072,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra) if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) do_hair_dynamics(sim); - psys_update_effectors(sim, cfra, 1); + psys_update_effectors(sim); psys_update_path_cache(sim, cfra); @@ -3653,7 +3139,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) BoidBrainData bbd; PARTICLE_P; float timestep; - int totpart, check_collisions = 0; + int totpart; /* current time */ float ctime, ipotime; // XXX old animation system /* frame & time changes */ @@ -3665,7 +3151,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) totpart=psys->totpart; - timestep=psys_get_timestep(sim); + timestep = psys_get_timestep(sim); dtime= dfra*timestep; ctime= cfra*timestep; ipotime= cfra; // XXX old animation system @@ -3703,15 +3189,6 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) } else{ pa->loop = 0; - if(cfra <= pa->time) - pa->alive = PARS_UNBORN; - /* without dynamics the state is allways known so no need to kill */ - else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)){ - if(cfra < pa->dietime) - pa->alive = PARS_ALIVE; - } - else - pa->alive = PARS_KILLED; } } @@ -3721,7 +3198,10 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) else{ BLI_srandom(31415926 + (int)cfra + psys->seed); - psys_update_effectors(sim, cfra, 1); + psys_update_effectors(sim); + + if(part->type != PART_HAIR) + sim->colliders = get_collider_cache(sim->scene, NULL); if(part->phystype==PART_PHYS_BOIDS){ ParticleTarget *pt = psys->targets.first; @@ -3731,13 +3211,13 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) bbd.dfra = dfra; bbd.timestep = timestep; - update_particle_tree(psys); + psys_update_particle_tree(psys, cfra); boids_precalc_rules(part, cfra); for(; pt; pt=pt->next) { if(pt->ob) - update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1)); + psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra); } } @@ -3798,7 +3278,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) apply_particle_forces(sim, p, pa_dfra, cfra); /* deflection */ - if(check_collisions) + if(sim->colliders) deflect_particle(sim, p, pa_dfra, cfra); /* rotations */ @@ -3812,7 +3292,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) boid_body(&bbd, pa); /* deflection */ - deflect_particle(sim, p, pa_dfra, cfra); + if(sim->colliders) + deflect_particle(sim, p, pa_dfra, cfra); } break; } @@ -3837,9 +3318,9 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) //push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state); } } + + free_collider_cache(&sim->colliders); } - if(psys->reactevents.first) - BLI_freelistN(&psys->reactevents); if(tree) BLI_kdtree_free(tree); @@ -3860,7 +3341,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra) if(part->from!=PART_FROM_PARTICLE) vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE); - psys_update_effectors(sim, cfra, 1); + psys_update_effectors(sim); disp= (float)get_current_display_percentage(psys)/100.0f; @@ -4195,6 +3676,13 @@ static void system_step(ParticleSimulationData *sim, float cfra) else if(framenr > endframe) { framenr= endframe; } + + if(framenr == startframe) { + BKE_ptcache_id_reset(sim->scene, &pid, PTCACHE_RESET_OUTDATED); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->flag &= ~PTCACHE_REDO_NEEDED; + } } /* verify if we need to reallocate */ @@ -4226,7 +3714,7 @@ static void system_step(ParticleSimulationData *sim, float cfra) if(alloc) { realloc_particles(sim, totpart); - if(usecache && !only_children_changed) { + if(oldtotpart && usecache && !only_children_changed) { BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); BKE_ptcache_id_from_particles(&pid, sim->ob, psys); } @@ -4286,7 +3774,7 @@ static void system_step(ParticleSimulationData *sim, float cfra) pa->alive = PARS_ALIVE; } } - else if(sim->ob->id.lib || (cache->flag & PTCACHE_BAKED)) { + else if(cfra != startframe && (sim->ob->id.lib || (cache->flag & PTCACHE_BAKED))) { psys_reset(psys, PSYS_RESET_CACHE_MISS); psys->cfra=cfra; psys->recalc = 0; @@ -4383,7 +3871,7 @@ static int hair_needs_recalc(ParticleSystem *psys) /* main particle update call, checks that things are ok on the large scale before actual particle calculations */ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) { - ParticleSimulationData sim = {scene, ob, psys, NULL}; + ParticleSimulationData sim = {scene, ob, psys, NULL, NULL}; float cfra; /* drawdata is outdated after ANY change */ diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 3915a6901a0..bffe4566f74 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -292,6 +292,9 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f else BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2); + if(cfra > pa->time) + cfra1 = MAX2(cfra1, pa->time); + dfra = cfra2 - cfra1; VecMulf(keys[1].vel, dfra / frs_sec); @@ -2266,6 +2269,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) } } } + BLI_freelistN(&pidlist2); } if(bake || cache->flag & PTCACHE_REDO_NEEDED) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b3f00f884bc..4f72ca96f5f 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -400,6 +400,10 @@ Scene *add_scene(char *name) sce->toolsettings->proportional_size = 1.0f; + sce->physics_settings.gravity[0] = 0.0f; + sce->physics_settings.gravity[1] = 0.0f; + sce->physics_settings.gravity[2] = -9.81f; + sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY; sce->unit.scale_length = 1.0f; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 62463b3d555..4f7a8cda81b 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -832,8 +832,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) size_t i = 0; size_t index = 0; int badcell = 0; - if(pa->alive == PARS_KILLED) continue; - else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue; + if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue; else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue; else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue; // VECCOPY(pos, pa->state.co); diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 450a64d72eb..089f2a5ebfb 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1550,11 +1550,14 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, float f,windfactor = 0.25f; /*see if we have wind*/ if(do_effector) { + EffectedPoint epoint; float speed[3]={0.0f,0.0f,0.0f}; float pos[3]; VecMidf(pos, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos); VecMidf(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec); - pdDoEffectors(scene, do_effector, pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); + pd_point_from_soft(scene, pos, vel, -1, &epoint); + pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + VecMulf(speed,windfactor); VecAddf(vel,vel,speed); } @@ -1589,14 +1592,13 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow) { SoftBody *sb = ob->soft; - ListBase *do_effector= NULL; + ListBase *do_effector = NULL; - do_effector= pdInitEffectors(scene, ob,NULL); + do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights); if (sb){ _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector); } - if(do_effector) - pdEndEffectors(do_effector); + pdEndEffectors(&do_effector); } static void *exec_scan_for_ext_spring_forces(void *data) @@ -1614,7 +1616,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, int i, totthread,left,dec; int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ - do_effector= pdInitEffectors(scene, ob,NULL); + do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights); /* figure the number of threads while preventing pretty pointless threading overhead */ if(scene->r.mode & R_FIXED_THREADS) @@ -1661,9 +1663,8 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow, exec_scan_for_ext_spring_forces(&sb_threads[0]); /* clean up */ MEM_freeN(sb_threads); - - if(do_effector) - pdEndEffectors(do_effector); + + pdEndEffectors(&do_effector); } @@ -2226,19 +2227,22 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo /* done goal stuff */ /* gravitation */ - if (sb){ - float gravity = sb->grav * sb_grav_force_scale(ob); - bp->force[2]-= gravity*bp->mass; /* individual mass of node here */ + if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){ + float gravity[3]; + VECCOPY(gravity, scene->physics_settings.gravity); + VecMulf(gravity, sb_grav_force_scale(ob)*bp->mass*sb->effector_weights->global_gravity); /* individual mass of node here */ + VecAddf(bp->force, bp->force, gravity); } /* particle field & vortex */ if(do_effector) { + EffectedPoint epoint; float kd; float force[3]= {0.0f, 0.0f, 0.0f}; float speed[3]= {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ - - pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); + pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); + pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); /* apply forcefield*/ VecMulf(force,fieldfactor* eval_sb_fric_force_scale); @@ -2341,6 +2345,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t left = totpoint; dec = totpoint/totthread +1; for(i=0; isoft; /* is supposed to be there */ BodyPoint *bproot; - ListBase *do_effector; + ListBase *do_effector = NULL; float iks, gravity; float fieldfactor = -1.0f, windfactor = 0.25; int do_deflector,do_selfcollision,do_springcollision,do_aero; @@ -2401,7 +2406,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl sb_sfesf_threads_run(scene, ob, timenow,sb->totspring,NULL); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(scene, ob,NULL); + do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights); if (do_deflector) { float defforce[3]; @@ -2414,7 +2419,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow); /* finish matrix and solve */ - if(do_effector) pdEndEffectors(do_effector); + pdEndEffectors(&do_effector); } @@ -2443,8 +2448,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa BodyPoint *bp; BodyPoint *bproot; BodySpring *bs; - ListBase *do_effector; - float iks, ks, kd, gravity; + ListBase *do_effector = NULL; + float iks, ks, kd, gravity[3] = {0.0f,0.0f,0.0f}; float fieldfactor = -1.0f, windfactor = 0.25f; float tune = sb->ballstiff; int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero; @@ -2460,7 +2465,10 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa */ - gravity = sb->grav * sb_grav_force_scale(ob); + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){ + VECCOPY(gravity, scene->physics_settings.gravity); + VecMulf(gravity, sb_grav_force_scale(ob)*sb->effector_weights->global_gravity); + } /* check conditions for various options */ do_deflector= query_external_colliders(scene, ob); @@ -2473,7 +2481,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(scene, ob,NULL); + do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights); if (do_deflector) { float defforce[3]; @@ -2631,16 +2639,17 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa /* gravitation */ - bp->force[2]-= gravity*bp->mass; /* individual mass of node here */ + VECADDFAC(bp->force, bp->force, gravity, bp->mass); /* individual mass of node here */ /* particle field & vortex */ if(do_effector) { + EffectedPoint epoint; float force[3]= {0.0f, 0.0f, 0.0f}; float speed[3]= {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ - - pdDoEffectors(scene, do_effector, bp->pos, force, speed, (float)scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); + pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); + pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); /* apply forcefield*/ VecMulf(force,fieldfactor* eval_sb_fric_force_scale); @@ -2819,7 +2828,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa } /* cleanup */ #endif - if(do_effector) pdEndEffectors(do_effector); + pdEndEffectors(&do_effector); } } @@ -3635,6 +3644,9 @@ SoftBody *sbNew(Scene *scene) sb->pointcache = BKE_ptcache_add(&sb->ptcaches); + if(!sb->effector_weights) + sb->effector_weights = BKE_add_effector_weights(NULL); + return sb; } @@ -3644,6 +3656,8 @@ void sbFree(SoftBody *sb) free_softbody_intern(sb); BKE_ptcache_free_list(&sb->ptcaches); sb->pointcache = NULL; + if(sb->effector_weights) + MEM_freeN(sb->effector_weights); MEM_freeN(sb); } @@ -3684,6 +3698,9 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo BodyPoint *bp; int a; + if(!sb || !sb->bpoint) + return; + for(a=0,bp=sb->bpoint; aorigS, bp->origE); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 94478b0d235..d1da29bef70 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3044,6 +3044,10 @@ static void lib_link_particlesettings(FileData *fd, Main *main) part->dup_group = newlibadr(fd, part->id.lib, part->dup_group); part->eff_group = newlibadr(fd, part->id.lib, part->eff_group); part->bb_ob = newlibadr(fd, part->id.lib, part->bb_ob); + + if(part->effector_weights) + part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group); + if(part->boids) { BoidState *state = part->boids->states.first; BoidRule *rule; @@ -3079,6 +3083,11 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) part->pd= newdataadr(fd, part->pd); part->pd2= newdataadr(fd, part->pd2); + if(part->effector_weights) + part->effector_weights = newdataadr(fd, part->effector_weights); + else + part->effector_weights = BKE_add_effector_weights(part->eff_group); + part->boids= newdataadr(fd, part->boids); if(part->boids) { @@ -3155,18 +3164,17 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) } - psys->child=newdataadr(fd,psys->child); - psys->effectors.first=psys->effectors.last=0; + psys->child = newdataadr(fd,psys->child); + psys->effectors = NULL; link_list(fd, &psys->targets); psys->edit = NULL; psys->free_edit = NULL; - psys->pathcache = 0; - psys->childcache = 0; - psys->pathcachebufs.first = psys->pathcachebufs.last = 0; - psys->childcachebufs.first = psys->childcachebufs.last = 0; - psys->reactevents.first = psys->reactevents.last = 0; + psys->pathcache = NULL; + psys->childcache = NULL; + psys->pathcachebufs.first = psys->pathcachebufs.last = NULL; + psys->childcachebufs.first = psys->childcachebufs.last = NULL; psys->frand = NULL; psys->pdd = NULL; @@ -3642,12 +3650,24 @@ static void lib_link_object(FileData *fd, Main *main) smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group); } } + + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + + if(clmd) + { + clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group); + } + } /* texture field */ if(ob->pd) if(ob->pd->tex) ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex); + if(ob->soft) + ob->soft->effector_weights->group = newlibadr(fd, ob->id.lib, ob->soft->effector_weights->group); + lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem); lib_link_modifiers(fd, ob); } @@ -3727,6 +3747,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) if(clmd->sim_parms->presets > 10) clmd->sim_parms->presets = 0; } + + if(clmd->sim_parms->effector_weights) + clmd->sim_parms->effector_weights = newdataadr(fd, clmd->sim_parms->effector_weights); + else + clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL); } else if (md->type==eModifierType_Fluidsim) { @@ -3948,6 +3973,8 @@ static void direct_link_object(FileData *fd, Object *ob) } ob->pd= newdataadr(fd, ob->pd); + if(ob->pd) + ob->pd->rng=NULL; ob->soft= newdataadr(fd, ob->soft); if(ob->soft) { SoftBody *sb= ob->soft; @@ -3965,6 +3992,11 @@ static void direct_link_object(FileData *fd, Object *ob) } } + if(sb->effector_weights) + sb->effector_weights = newdataadr(fd, sb->effector_weights); + else + sb->effector_weights = BKE_add_effector_weights(NULL); + direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache); } ob->bsoft= newdataadr(fd, ob->bsoft); @@ -9702,6 +9734,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Object *ob; Material *ma; Tex *tex; + ParticleSettings *part; + int do_gravity = 0; for(sce = main->scene.first; sce; sce = sce->id.next) if(sce->unit.scale_length == 0.0f) @@ -9741,6 +9775,48 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->audio.doppler_factor = 1.0; sce->audio.speed_of_sound = 343.3; } + + /* Add default gravity to scenes */ + for(sce= main->scene.first; sce; sce= sce->id.next) { + if((sce->physics_settings.flag & PHYS_GLOBAL_GRAVITY) == 0 + && VecLength(sce->physics_settings.gravity) == 0.0f) { + + sce->physics_settings.gravity[0] = sce->physics_settings.gravity[1] = 0.0f; + sce->physics_settings.gravity[2] = -9.81f; + sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY; + do_gravity = 1; + } + } + + /* Assign proper global gravity weights for dynamics (only z-coordinate is taken into account) */ + if(do_gravity) for(part= main->particle.first; part; part= part->id.next) + part->effector_weights->global_gravity = part->acc[2]/-9.81f; + + for(ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + + if(do_gravity) { + for(md= ob->modifiers.first; md; md= md->next) { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + clmd->sim_parms->effector_weights->global_gravity = clmd->sim_parms->gravity[2]/-9.81; + } + + if(ob->soft) + ob->soft->effector_weights->global_gravity = ob->soft->grav/9.81; + } + + /* Normal wind shape is plane */ + if(ob->pd) { + if(ob->pd->forcefield == PFIELD_WIND) + ob->pd->shape = PFIELD_SHAPE_PLANE; + + if(ob->pd->flag & PFIELD_PLANAR) + ob->pd->shape = PFIELD_SHAPE_PLANE; + else if(ob->pd->flag & PFIELD_SURFACE) + ob->pd->shape = PFIELD_SHAPE_SURFACE; + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index fda35d28d0e..52870420833 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -620,6 +620,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase) if (part->adt) write_animdata(wd, part->adt); writestruct(wd, DATA, "PartDeflect", 1, part->pd); writestruct(wd, DATA, "PartDeflect", 1, part->pd2); + writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights); if(part->boids && part->phystype == PART_PHYS_BOIDS) { BoidState *state = part->boids->states.first; @@ -1140,6 +1141,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms); writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms); + writestruct(wd, DATA, "EffectorWeights", 1, clmd->sim_parms->effector_weights); write_pointcaches(wd, &clmd->ptcaches); } else if(md->type==eModifierType_Smoke) { @@ -1227,7 +1229,10 @@ static void write_objects(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "PartDeflect", 1, ob->pd); writestruct(wd, DATA, "SoftBody", 1, ob->soft); - if(ob->soft) write_pointcaches(wd, &ob->soft->ptcaches); + if(ob->soft) { + write_pointcaches(wd, &ob->soft->ptcaches); + writestruct(wd, DATA, "EffectorWeights", 1, ob->soft->effector_weights); + } writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft); write_particlesystems(wd, &ob->particlesystem); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 05905cd42a4..7188368a95f 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -38,6 +38,7 @@ #include "DNA_meta_types.h" #include "DNA_object_fluidsim.h" #include "DNA_object_types.h" +#include "DNA_object_force.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_userdef_types.h" @@ -56,6 +57,7 @@ #include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_displist.h" +#include "BKE_effect.h" #include "BKE_global.h" #include "BKE_group.h" #include "BKE_lattice.h" @@ -190,6 +192,90 @@ void OBJECT_OT_add(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", object_type_items, 0, "Type", ""); } +/********************* Add Effector Operator ********************/ +/* copy from rna_object_force.c*/ +static EnumPropertyItem field_type_items[] = { + {0, "NONE", 0, "None", ""}, + {PFIELD_FORCE, "FORCE", 0, "Force", ""}, + {PFIELD_WIND, "WIND", 0, "Wind", ""}, + {PFIELD_VORTEX, "VORTEX", 0, "Vortex", ""}, + {PFIELD_MAGNET, "MAGNET", 0, "Magnetic", ""}, + {PFIELD_HARMONIC, "HARMONIC", 0, "Harmonic", ""}, + {PFIELD_CHARGE, "CHARGE", 0, "Charge", ""}, + {PFIELD_LENNARDJ, "LENNARDJ", 0, "Lennard-Jones", ""}, + {PFIELD_TEXTURE, "TEXTURE", 0, "Texture", ""}, + {PFIELD_GUIDE, "GUIDE", 0, "Curve Guide", ""}, + {PFIELD_BOID, "BOID", 0, "Boid", ""}, + {PFIELD_TURBULENCE, "TURBULENCE", 0, "Turbulence", ""}, + {PFIELD_DRAG, "DRAG", 0, "Drag", ""}, + {0, NULL, 0, NULL, NULL}}; + +void add_effector_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menus, only non-editmode stuff */ +{ + /* keep here to get things compile, remove later */ +} + +/* for effector add primitive operators */ +static Object *effector_add_type(bContext *C, int type) +{ + Scene *scene= CTX_data_scene(C); + Object *ob; + + /* for as long scene has editmode... */ + if (CTX_data_edit_object(C)) + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ + + /* deselects all, sets scene->basact */ + if(type==PFIELD_GUIDE) { + ob = add_object(scene, OB_CURVE); + ((Curve*)ob->data)->flag |= CU_PATH|CU_3D; + ED_object_enter_editmode(C, 0); + BLI_addtail(curve_get_editcurve(ob), add_nurbs_primitive(C, CU_NURBS|CU_PRIM_PATH, 1)); + ED_object_exit_editmode(C, EM_FREEDATA); + } + else + ob= add_object(scene, OB_EMPTY); + + ob->pd= object_add_collision_fields(type); + + /* editor level activate, notifiers */ + ED_base_object_activate(C, BASACT); + + /* more editor stuff */ + ED_object_base_init_from_view(C, BASACT); + + DAG_scene_sort(scene); + + return ob; +} + +/* for object add operator */ +static int effector_add_exec(bContext *C, wmOperator *op) +{ + effector_add_type(C, RNA_int_get(op->ptr, "type")); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_effector_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Effector"; + ot->description = "Add an empty object with a physics effector to the scene."; + ot->idname= "OBJECT_OT_effector_add"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= effector_add_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", field_type_items, 0, "Type", ""); +} + /* ***************** add primitives *************** */ /* ****** work both in and outside editmode ****** */ @@ -616,6 +702,8 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve uiItemS(layout); uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_add", "type", OB_CAMERA); uiItemMenuEnumO(layout, "Lamp", ICON_OUTLINER_OB_LAMP, "OBJECT_OT_lamp_add", "type"); + uiItemS(layout); + uiItemMenuEnumO(layout, "Force Field", ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_effector_add", "type"); uiPupMenuEnd(C, pup); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index ee0b043a9a1..54df3ae92da 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -346,6 +346,7 @@ void ED_object_exit_editmode(bContext *C, int flag) if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } + BLI_freelistN(&pidlist); BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index c5499ef8f5d..474715c593b 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -91,6 +91,7 @@ void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_primitive_add(struct wmOperatorType *ot); /* only used as menu */ +void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); void OBJECT_OT_duplicate(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index cc8cc420bf7..7f0f1876417 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -110,7 +110,7 @@ int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int ty } else if(type == eModifierType_Collision) { if(!ob->pd) - ob->pd= object_add_collision_fields(); + ob->pd= object_add_collision_fields(0); ob->pd->deflect= 1; DAG_scene_sort(scene); @@ -159,8 +159,8 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod DAG_scene_sort(scene); } else if(md->type == eModifierType_Surface) { - if(ob->pd) - ob->pd->flag &= ~PFIELD_SURFACE; + if(ob->pd && ob->pd->shape == PFIELD_SHAPE_SURFACE) + ob->pd->shape = PFIELD_SHAPE_PLANE; DAG_scene_sort(scene); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 3f975d1e807..9bfd6a4201c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -117,6 +117,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_armature_add); WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_add); + WM_operatortype_append(OBJECT_OT_effector_add); WM_operatortype_append(OBJECT_OT_primitive_add); WM_operatortype_append(OBJECT_OT_mesh_add); WM_operatortype_append(OBJECT_OT_metaball_add); diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c index 47d073e2dbb..0b63f1a98ff 100644 --- a/source/blender/editors/physics/particle_boids.c +++ b/source/blender/editors/physics/particle_boids.c @@ -78,7 +78,7 @@ static int rule_add_exec(bContext *C, wmOperator *op) BLI_addtail(&state->rules, rule); - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); + DAG_id_flush_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; @@ -129,7 +129,7 @@ static int rule_del_exec(bContext *C, wmOperator *op) rule->flag |= BOIDRULE_CURRENT; DAG_scene_sort(scene); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -168,7 +168,7 @@ static int rule_move_up_exec(bContext *C, wmOperator *op) BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->prev->prev, rule); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } @@ -207,7 +207,7 @@ static int rule_move_down_exec(bContext *C, wmOperator *op) BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->next, rule); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } @@ -303,7 +303,7 @@ static int state_del_exec(bContext *C, wmOperator *op) state->flag |= BOIDSTATE_CURRENT; DAG_scene_sort(scene); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -378,7 +378,7 @@ static int state_move_down_exec(bContext *C, wmOperator *op) if(state->flag & BOIDSTATE_CURRENT && state->next) { BLI_remlink(&boids->states, state); BLI_insertlink(&boids->states, state->next, state); - psys_flush_particle_settings(scene, psys->part, PSYS_RECALC_RESET); + DAG_id_flush_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 60ae91e7a89..db3b7130ab3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3159,9 +3159,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv ma_g = ma->g; ma_b = ma->b; - pdd->ma_r = &ma_r; - pdd->ma_g = &ma_g; - pdd->ma_b = &ma_b; + if(pdd) { + pdd->ma_r = &ma_r; + pdd->ma_g = &ma_g; + pdd->ma_b = &ma_b; + } create_cdata = 1; } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 8d709d1b38a..f6d30a7bec9 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4848,6 +4848,7 @@ void special_aftertrans_update(TransInfo *t) if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } + BLI_freelistN(&pidlist); /* pointcache refresh */ if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED)) diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 5cfecf7cc01..9423e871c77 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -79,6 +79,8 @@ typedef struct ClothSimSettings short vgroup_struct; /* vertex group for scaling structural stiffness */ short presets; /* used for presets on GUI */ short pad; + + struct EffectorWeights *effector_weights; } ClothSimSettings; diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 468ad35de85..e7e785e605b 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -35,47 +35,91 @@ extern "C" { #endif #include "DNA_listBase.h" + +/* 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 */ + NUM_PFIELD_TYPES +} PFieldType; typedef struct PartDeflect { - short deflect; /* Deflection flag - does mesh deflect particles*/ - short forcefield; /* Force field type, do the vertices attract / repel particles ? */ - short flag; /* general settings flag */ - short falloff; /* fall-off type*/ + short deflect; /* Deflection flag - does mesh deflect particles */ + short forcefield; /* Force field type, do the vertices attract / repel particles? */ + short flag; /* general settings flag */ + short falloff; /* fall-off type */ + short shape; /* point, plane or surface */ + short tex_mode; /* texture effector */ + short kink, kink_axis; /* for curve guide */ + short zdir, rt; + /* Main effector values */ + float f_strength; /* The strength of the force (+ or - ) */ + float f_damp; /* Damping ratio of the harmonic effector. */ + float f_flow; /* How much force is converted into "air flow", i.e. */ + /* force used as the velocity of surrounding medium. */ + + float f_size; + + /* fall-off */ + float f_power; /* The power law - real gravitation is 2 (square) */ + float maxdist; /* if indicated, use this maximum */ + float mindist; /* if indicated, use this minimum */ + float f_power_r; /* radial fall-off power */ + float maxrad; /* radial versions of above */ + float minrad; + + /* particle collisions */ float pdef_damp; /* Damping factor for particle deflection */ float pdef_rdamp; /* Random element of damping for deflection */ float pdef_perm; /* Chance of particle passing through mesh */ float pdef_frict; /* Friction factor for particle deflection */ float pdef_rfrict; /* Random element of friction for deflection */ - float f_strength; /* The strength of the force (+ or - ) */ - float f_power; /* The power law - real gravitation is 2 (square) */ - float f_dist; - float f_damp; /* The dampening factor, currently only for harmonic force */ - float maxdist; /* if indicated, use this maximum */ - float mindist; /* if indicated, use this minimum */ - float maxrad; /* radial versions of above */ - float minrad; - float f_power_r; /* radial fall-off power*/ + float absorption, pad; /* used for forces */ + /* softbody collisions */ float pdef_sbdamp; /* Damping factor for softbody deflection */ float pdef_sbift; /* inner face thickness for softbody deflection */ float pdef_sboft; /* outer face thickness for softbody deflection */ - float absorption, pad; /* used for forces */ - - /* variables for guide curve */ + /* guide curve, same as for particle child effects */ float clump_fac, clump_pow; float kink_freq, kink_shape, kink_amp, free_end; - float tex_nabla; - short tex_mode, kink, kink_axis, rt2; - struct Tex *tex; /* Texture of the texture effector */ - struct RNG *rng; /* random noise generator for e.g. wind */ - float f_noise; /* noise of force (currently used for wind) */ - int seed; /* wind noise random seed */ + /* texture effector */ + float tex_nabla; /* Used for calculating partial derivatives */ + struct Tex *tex; /* Texture of the texture effector */ + + /* effector noise */ + struct RNG *rng; /* random noise generator for e.g. wind */ + float f_noise; /* noise of force */ + int seed; /* noise random seed */ } PartDeflect; +typedef struct EffectorWeights { + struct Group *group; /* only use effectors from this group of objects */ + + float weight[13]; /* effector type specific weights */ + float global_gravity; + short flag, rt[3]; +} EffectorWeights; + +/* EffectorWeights->flag */ +#define EFF_WEIGHT_DO_HAIR 1 + /* Point cache file data types: * - used as (1<forcefield: Effector Fields types */ -#define PFIELD_FORCE 1 -#define PFIELD_VORTEX 2 -#define PFIELD_MAGNET 3 -#define PFIELD_WIND 4 -#define PFIELD_GUIDE 5 -#define PFIELD_TEXTURE 6 -#define PFIELD_HARMONIC 7 -#define PFIELD_CHARGE 8 -#define PFIELD_LENNARDJ 9 -#define PFIELD_BOID 10 +} SoftBody; /* pd->flag: various settings */ #define PFIELD_USEMAX 1 #define PDEFLE_DEFORM 2 -#define PFIELD_GUIDE_PATH_ADD 4 -#define PFIELD_PLANAR 8 +#define PFIELD_GUIDE_PATH_ADD 4 /* TODO: do_versions for below */ +#define PFIELD_PLANAR 8 /* used for do_versions */ #define PDEFLE_KILL_PART 16 -#define PFIELD_POSZ 32 +#define PFIELD_POSZ 32 /* used for do_versions */ #define PFIELD_TEX_OBJECT 64 +#define PFIELD_GLOBAL_CO 64 /* used for turbulence */ #define PFIELD_TEX_2D 128 #define PFIELD_USEMIN 256 #define PFIELD_USEMAXR 512 #define PFIELD_USEMINR 1024 #define PFIELD_TEX_ROOTCO 2048 -#define PFIELD_SURFACE 4096 +#define PFIELD_SURFACE (1<<12) /* used for do_versions */ +#define PFIELD_VISIBILITY (1<<13) +#define PFIELD_DO_LOCATION (1<<14) +#define PFIELD_DO_ROTATION (1<<15) /* pd->falloff */ #define PFIELD_FALL_SPHERE 0 #define PFIELD_FALL_TUBE 1 #define PFIELD_FALL_CONE 2 -//reserved for near future -//#define PFIELD_FALL_INSIDE 3 + +/* pd->shape */ +#define PFIELD_SHAPE_POINT 0 +#define PFIELD_SHAPE_PLANE 1 +#define PFIELD_SHAPE_SURFACE 2 +#define PFIELD_SHAPE_POINTS 3 /* pd->tex_mode */ #define PFIELD_TEX_RGB 0 #define PFIELD_TEX_GRAD 1 #define PFIELD_TEX_CURL 2 +/* pd->zdir */ +#define PFIELD_Z_BOTH 0 +#define PFIELD_Z_POS 1 +#define PFIELD_Z_NEG 2 + /* pointcache->flag */ #define PTCACHE_BAKED 1 #define PTCACHE_OUTDATED 2 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 089c1c76bcf..4c620ae527e 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -114,6 +114,8 @@ typedef struct ParticleSettings { struct BoidSettings *boids; + struct EffectorWeights *effector_weights; + int flag; short type, from, distr; /* physics modes */ @@ -176,10 +178,8 @@ typedef struct ParticleSettings { /* keyed particles */ int keyed_loops; - float effector_weight[10]; - struct Group *dup_group; - struct Group *eff_group; + struct Group *eff_group; // deprecated struct Object *dup_ob; struct Object *bb_ob; struct Ipo *ipo; // xxx depreceated... old animation system @@ -209,8 +209,6 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in struct Object *lattice; struct Object *parent; /* particles from global space -> parent space */ - struct ListBase effectors, reactevents; /* runtime */ - struct ListBase targets; /* used for keyed and boid physics */ char name[32]; /* particle system name */ @@ -233,6 +231,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in struct PointCache *pointcache; struct ListBase ptcaches; + struct ListBase *effectors; + struct KDTree *tree; /* used for interactions with self and other systems */ struct ParticleDrawData *pdd; @@ -270,7 +270,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_ROT_DYN (1<<14) /* dynamic rotation */ #define PART_SIZEMASS (1<<16) -//#define PART_KEYED_TIMING (1<<15) +//#define PART_HAIR_GRAVITY (1<<15) //#define PART_ABS_TIME (1<<17) //#define PART_GLOB_TIME (1<<18) @@ -407,11 +407,13 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_CHILD_FACES 2 /* psys->recalc */ -#define PSYS_RECALC_REDO 1 /* only do pathcache etc */ -#define PSYS_RECALC_RESET 2 /* reset everything including pointcache */ -#define PSYS_RECALC_TYPE 4 /* handle system type change */ -#define PSYS_RECALC_CHILD 16 /* only child settings changed */ -#define PSYS_RECALC_PHYS 32 /* physics type changed */ +/* starts from 8 so that the first bits can be ob->recalc */ +#define PSYS_RECALC_REDO 8 /* only do pathcache etc */ +#define PSYS_RECALC_RESET 16 /* reset everything including pointcache */ +#define PSYS_RECALC_TYPE 32 /* handle system type change */ +#define PSYS_RECALC_CHILD 64 /* only child settings changed */ +#define PSYS_RECALC_PHYS 128 /* physics type changed */ +#define PSYS_RECALC 248 /* psys->flag */ #define PSYS_CURRENT 1 @@ -436,7 +438,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PARS_REKEY 8 /* pars->alive */ -#define PARS_KILLED 0 +//#define PARS_KILLED 0 /* deprecated */ #define PARS_DEAD 1 #define PARS_UNBORN 2 #define PARS_ALIVE 3 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5521f0e9315..c5691b47157 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -667,6 +667,11 @@ typedef struct UnitSettings { short flag; /* imperial, metric etc */ } UnitSettings; +typedef struct PhysicsSettings { + float gravity[3]; + int flag; +} PhysicsSettings; + typedef struct Scene { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ @@ -731,6 +736,9 @@ typedef struct Scene { /* Grease Pencil */ struct bGPdata *gpd; + + /* Physics simulation settings */ + struct PhysicsSettings physics_settings; } Scene; @@ -1127,6 +1135,9 @@ typedef enum SculptFlags { #define SK_RETARGET_ROLL_VIEW 1 #define SK_RETARGET_ROLL_JOINT 2 +/* physics_settings->flag */ +#define PHYS_GLOBAL_GRAVITY 1 + /* UnitSettings */ /* UnitSettings->system */ diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c index 8002aa89313..36a648c8a82 100644 --- a/source/blender/makesrna/intern/rna_boid.c +++ b/source/blender/makesrna/intern/rna_boid.c @@ -74,44 +74,33 @@ EnumPropertyItem boidruleset_type_items[] ={ static void rna_Boids_reset(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); - ParticleSettings *part; - if(ptr->type==&RNA_ParticleSystem) { ParticleSystem *psys = (ParticleSystem*)ptr->data; - Object *ob = psys_find_object(scene, psys); psys->recalc = PSYS_RECALC_RESET; - if(ob) - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - else { - part = ptr->id.data; - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); } + else + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } static void rna_Boids_reset_deps(bContext *C, PointerRNA *ptr) { Scene *scene = CTX_data_scene(C); - ParticleSettings *part; if(ptr->type==&RNA_ParticleSystem) { ParticleSystem *psys = (ParticleSystem*)ptr->data; - Object *ob = psys_find_object(scene, psys); psys->recalc = PSYS_RECALC_RESET; - if(ob) - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - else { - part = ptr->id.data; - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); - DAG_scene_sort(scene); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); } + else + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET); + + DAG_scene_sort(scene); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 22cc2e2c9c3..d64e2c7119b 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -306,6 +306,11 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bending Stiffness Vertex Group", "Vertex group for fine control over bending stiffness."); RNA_def_property_update(prop, 0, "rna_cloth_update"); + prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "EffectorWeights"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Effector Weights", ""); + /* unused */ /* unused still diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index a2b4d6d7335..afc82016502 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -741,7 +741,7 @@ static PointerRNA rna_Object_field_get(PointerRNA *ptr) /* weak */ if(!ob->pd) - ob->pd= object_add_collision_fields(); + ob->pd= object_add_collision_fields(0); return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, ob->pd); } @@ -752,7 +752,7 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr) /* weak */ if(!ob->pd) - ob->pd= object_add_collision_fields(); + ob->pd= object_add_collision_fields(0); return rna_pointer_inherit_refine(ptr, &RNA_CollisionSettings, ob->pd); } diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 1f0d01ce784..652a80a24eb 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -31,11 +31,40 @@ #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_particle_types.h" #include "DNA_scene_types.h" #include "WM_api.h" #include "WM_types.h" +EnumPropertyItem effector_shape_items[] = { + {PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""}, + {PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""}, + {PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Surface", ""}, + {PFIELD_SHAPE_POINTS, "POINTS", 0, "Every Point", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem empty_shape_items[] = { + {PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""}, + {PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem vortex_shape_items[] = { + {PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""}, + {PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""}, + {PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Surface falloff (New)", ""}, + {PFIELD_SHAPE_POINTS, "POINTS", 0, "Every Point (New)", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem empty_vortex_shape_items[] = { + {PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""}, + {PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -358,65 +387,115 @@ static void rna_SoftBodySettings_goal_vgroup_set(PointerRNA *ptr, const char *va rna_object_vgroup_name_index_set(ptr, value, &sb->vertgroup); } +static int particle_field_check(PointerRNA *ptr) +{ + ID *id= ptr->id.data; + + return (GS(id->name) == ID_PA); +} static void rna_FieldSettings_update(bContext *C, PointerRNA *ptr) { - Object *ob= (Object*)ptr->id.data; + if(particle_field_check(ptr)) { + ParticleSettings *part = (ParticleSettings*)ptr->id.data; + + if(part->pd->forcefield != PFIELD_TEXTURE && part->pd->tex) { + part->pd->tex->id.us--; + part->pd->tex= 0; + } + + if(part->pd2->forcefield != PFIELD_TEXTURE && part->pd2->tex) { + part->pd2->tex->id.us--; + part->pd2->tex= 0; + } + + DAG_id_flush_update(&part->id, OB_RECALC|PSYS_RECALC_RESET); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); - if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex) { - ob->pd->tex->id.us--; - ob->pd->tex= 0; } + else { + Object *ob = (Object*)ptr->id.data; - DAG_id_flush_update(&ob->id, OB_RECALC_OB); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex) { + ob->pd->tex->id.us--; + ob->pd->tex= 0; + } + + DAG_id_flush_update(&ob->id, OB_RECALC_OB); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + } } -static void rna_FieldSettings_surface_update(bContext *C, PointerRNA *ptr) +static void rna_FieldSettings_shape_update(bContext *C, PointerRNA *ptr) { Scene *scene= CTX_data_scene(C); - Object *ob= (Object*)ptr->id.data; - PartDeflect *pd= ob->pd; - ModifierData *md= modifiers_findByType(ob, eModifierType_Surface); - /* add/remove modifier as needed */ - if(!md) { - if(pd && (pd->flag & PFIELD_SURFACE)) - if(ELEM6(pd->forcefield,PFIELD_HARMONIC,PFIELD_FORCE,PFIELD_HARMONIC,PFIELD_CHARGE,PFIELD_LENNARDJ,PFIELD_BOID)) + if(!particle_field_check(ptr)) { + Object *ob= (Object*)ptr->id.data; + PartDeflect *pd= ob->pd; + ModifierData *md= modifiers_findByType(ob, eModifierType_Surface); + + /* add/remove modifier as needed */ + if(!md) { + if(pd && (pd->shape == PFIELD_SHAPE_SURFACE) && ELEM(pd->forcefield,PFIELD_GUIDE,PFIELD_TEXTURE)==0) if(ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) ED_object_modifier_add(NULL, scene, ob, eModifierType_Surface); - } - else { - if(!pd || !(pd->flag & PFIELD_SURFACE)) - ED_object_modifier_remove(NULL, scene, ob, md); - } + } + else { + if(!pd || pd->shape != PFIELD_SHAPE_SURFACE) + ED_object_modifier_remove(NULL, scene, ob, md); + } - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + } } static void rna_FieldSettings_dependency_update(bContext *C, PointerRNA *ptr) { Scene *scene= CTX_data_scene(C); - Object *ob= (Object*)ptr->id.data; - /* do this before scene sort, that one checks for CU_PATH */ - /* XXX if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) { - Curve *cu= ob->data; - cu->flag |= (CU_PATH|CU_3D); - do_curvebuts(B_CU3D); // all curves too - }*/ + if(particle_field_check(ptr)) { + DAG_id_flush_update((ID*)ptr->id.data, OB_RECALC|PSYS_RECALC_RESET); + } + else { + Object *ob= (Object*)ptr->id.data; - rna_FieldSettings_surface_update(C, ptr); + /* do this before scene sort, that one checks for CU_PATH */ + /* XXX if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) { + Curve *cu= ob->data; + cu->flag |= (CU_PATH|CU_3D); + do_curvebuts(B_CU3D); // all curves too + }*/ - DAG_scene_sort(scene); + rna_FieldSettings_shape_update(C, ptr); - if(ob->type == OB_CURVE && ob->pd->forcefield == PFIELD_GUIDE) - DAG_id_flush_update(&ob->id, OB_RECALC); - else - DAG_id_flush_update(&ob->id, OB_RECALC_OB); + DAG_scene_sort(scene); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + if(ob->type == OB_CURVE && ob->pd->forcefield == PFIELD_GUIDE) + DAG_id_flush_update(&ob->id, OB_RECALC); + else + DAG_id_flush_update(&ob->id, OB_RECALC_OB); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + } +} + +static void rna_EffectorWeight_update(bContext *C, PointerRNA *ptr) +{ + DAG_id_flush_update((ID*)ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); } +static void rna_EffectorWeight_dependency_update(bContext *C, PointerRNA *ptr) +{ + Scene *scene= CTX_data_scene(C); + + DAG_scene_sort(scene); + + DAG_id_flush_update((ID*)ptr->id.data, OB_RECALC_DATA|PSYS_RECALC_RESET); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); +} static void rna_CollisionSettings_dependency_update(bContext *C, PointerRNA *ptr) { Scene *scene= CTX_data_scene(C); @@ -448,6 +527,47 @@ static void rna_softbody_update(bContext *C, PointerRNA *ptr) WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); } + +static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Object *ob= NULL; + + if(C==NULL) { + EnumPropertyItem *item= NULL; + int totitem= 0; + + /* needed for doc generation */ + RNA_enum_items_add(&item, &totitem, effector_shape_items); + RNA_enum_items_add(&item, &totitem, empty_shape_items); + RNA_enum_items_add(&item, &totitem, vortex_shape_items); + RNA_enum_items_add(&item, &totitem, empty_shape_items); + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; + } + + if(particle_field_check(ptr)) + return empty_shape_items; + + ob= (Object*)ptr->id.data; + + if(ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) { + if(ob->pd->forcefield == PFIELD_VORTEX) + return vortex_shape_items; + + return effector_shape_items; + } + else { + if(ob->pd->forcefield == PFIELD_VORTEX) + return empty_vortex_shape_items; + + return empty_shape_items; + } +} + + #else static void rna_def_pointcache(BlenderRNA *brna) @@ -625,6 +745,129 @@ static void rna_def_collision(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_CollisionSettings_update"); } +static void rna_def_effector_weight(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "EffectorWeights", NULL); + RNA_def_struct_ui_text(srna, "Effector Weights", "Effector weights for physics simulation."); + RNA_def_struct_ui_icon(srna, ICON_PHYSICS); + + /* Flags */ + prop= RNA_def_property(srna, "do_growing_hair", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", EFF_WEIGHT_DO_HAIR); + RNA_def_property_ui_text(prop, "Use For Growing Hair", "Use force fields when growing hair."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + /* General */ + prop= RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "group"); + RNA_def_property_struct_type(prop, "Group"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this Group."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_dependency_update"); + + prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "global_gravity"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Gravity", "Global gravity weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + /* Effector weights */ + prop= RNA_def_property(srna, "all", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[0]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "All", "All effector's weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "spherical", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[1]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "vortex", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[2]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Vortex", "Vortex effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "magnetic", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[3]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Magnetic", "Magnetic effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "wind", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[4]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Wind", "Wind effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "curveguide", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[5]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Curve Guide", "Curve guide effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "texture", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[6]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Texture", "Texture effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "harmonic", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[7]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Harmonic", "Harmonic effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "charge", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[8]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Charge", "Charge effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "lennardjones", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[9]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Lennard-Jones", "Lennard-Jones effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "boid", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[10]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Boid", "Boid effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[11]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Turbulence", "Turbulence effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop= RNA_def_property(srna, "drag", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[12]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Drag", "Drag effector weight."); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); +} + static void rna_def_field(BlenderRNA *brna) { StructRNA *srna; @@ -632,18 +875,20 @@ static void rna_def_field(BlenderRNA *brna) static EnumPropertyItem field_type_items[] = { {0, "NONE", 0, "None", ""}, - {PFIELD_FORCE, "SPHERICAL", 0, "Spherical", ""}, + {PFIELD_FORCE, "FORCE", 0, "Force", ""}, + {PFIELD_WIND, "WIND", 0, "Wind", ""}, {PFIELD_VORTEX, "VORTEX", 0, "Vortex", ""}, {PFIELD_MAGNET, "MAGNET", 0, "Magnetic", ""}, - {PFIELD_WIND, "WIND", 0, "Wind", ""}, - {PFIELD_GUIDE, "GUIDE", 0, "Curve Guide", ""}, - {PFIELD_TEXTURE, "TEXTURE", 0, "Texture", ""}, {PFIELD_HARMONIC, "HARMONIC", 0, "Harmonic", ""}, {PFIELD_CHARGE, "CHARGE", 0, "Charge", ""}, {PFIELD_LENNARDJ, "LENNARDJ", 0, "Lennard-Jones", ""}, + {PFIELD_TEXTURE, "TEXTURE", 0, "Texture", ""}, + {PFIELD_GUIDE, "GUIDE", 0, "Curve Guide", ""}, {PFIELD_BOID, "BOID", 0, "Boid", ""}, + {PFIELD_TURBULENCE, "TURBULENCE", 0, "Turbulence", ""}, + {PFIELD_DRAG, "DRAG", 0, "Drag", ""}, {0, NULL, 0, NULL, NULL}}; - + static EnumPropertyItem falloff_items[] = { {PFIELD_FALL_SPHERE, "SPHERE", 0, "Sphere", ""}, {PFIELD_FALL_TUBE, "TUBE", 0, "Tube", ""}, @@ -656,6 +901,12 @@ static void rna_def_field(BlenderRNA *brna) {PFIELD_TEX_CURL, "CURL", 0, "Curl", ""}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem zdirection_items[] = { + {PFIELD_Z_BOTH, "BOTH", 0, "Both Z", ""}, + {PFIELD_Z_POS, "POSITIVE", 0, "+Z", ""}, + {PFIELD_Z_NEG, "NEGATIVE", 0, "-Z", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "FieldSettings", NULL); RNA_def_struct_sdna(srna, "PartDeflect"); RNA_def_struct_ui_text(srna, "Field Settings", "Field settings for an object in physics simulation."); @@ -668,6 +919,12 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_enum_items(prop, field_type_items); RNA_def_property_ui_text(prop, "Type", "Type of field."); RNA_def_property_update(prop, 0, "rna_FieldSettings_dependency_update"); + + prop= RNA_def_property(srna, "shape", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, effector_shape_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Effector_shape_itemf"); + RNA_def_property_ui_text(prop, "Shape", "Which direction is used to calculate the effector force."); + RNA_def_property_update(prop, 0, "rna_FieldSettings_shape_update"); prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "falloff"); @@ -680,6 +937,12 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_enum_items(prop, texture_items); RNA_def_property_ui_text(prop, "Texture Mode", "How the texture effect is calculated (RGB & Curl need a RGB texture else Gradient will be used instead)"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "z_direction", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "zdir"); + RNA_def_property_enum_items(prop, zdirection_items); + RNA_def_property_ui_text(prop, "Z Direction", "Effect in full or only positive/negative Z direction."); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /* Float */ @@ -688,18 +951,51 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Strength", "Strength of force field"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); - - prop= RNA_def_property(srna, "falloff_power", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "f_power"); - RNA_def_property_range(prop, 0.0f, 10.0f); - RNA_def_property_ui_text(prop, "Falloff Power", "Falloff power (real gravitational falloff = 2)"); + + /* different ui range to above */ + prop= RNA_def_property(srna, "linear_drag", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_strength"); + RNA_def_property_range(prop, -2.0f, 2.0f); + RNA_def_property_ui_text(prop, "Linear Drag", "Drag component proportional to velocity."); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); - + prop= RNA_def_property(srna, "harmonic_damping", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "f_damp"); RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text(prop, "Harmonic Damping", "Damping of the harmonic force"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + /* different ui range to above */ + prop= RNA_def_property(srna, "quadratic_drag", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_damp"); + RNA_def_property_range(prop, -2.0f, 2.0f); + RNA_def_property_ui_text(prop, "Quadratic Drag", "Drag component proportional to the square of velocity."); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "flow", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_flow"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_text(prop, "Flow", "Convert effector force into air flow velocity"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + /* different ui range to above */ + prop= RNA_def_property(srna, "inflow", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_flow"); + RNA_def_property_range(prop, -10.0f, 10.0f); + RNA_def_property_ui_text(prop, "Inflow", "Inwards component of the vortex force"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_size"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_text(prop, "Size", "Size of the noise"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "falloff_power", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_power"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_text(prop, "Falloff Power", "Falloff power (real gravitational falloff = 2)"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); prop= RNA_def_property(srna, "minimum_distance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "mindist"); @@ -776,26 +1072,16 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_ADD); RNA_def_property_ui_text(prop, "Additive", "Based on distance/falloff it adds a portion of the entire path"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); - - prop= RNA_def_property(srna, "planar", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_PLANAR); - RNA_def_property_ui_text(prop, "Planar", "Create planar field"); - RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); - - prop= RNA_def_property(srna, "surface", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_SURFACE); - RNA_def_property_ui_text(prop, "Surface", "Use closest point on surface"); - RNA_def_property_update(prop, 0, "rna_FieldSettings_surface_update"); - - prop= RNA_def_property(srna, "positive_z", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_POSZ); - RNA_def_property_ui_text(prop, "Positive", "Effect only in direction of positive Z axis"); - RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); - + prop= RNA_def_property(srna, "use_coordinates", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_OBJECT); RNA_def_property_ui_text(prop, "Use Coordinates", "Use object/global coordinates for texture"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "global_coordinates", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GLOBAL_CO); + RNA_def_property_ui_text(prop, "Use Global Coordinates", "Use effector/global coordinates for turbulence"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); prop= RNA_def_property(srna, "force_2d", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_2D); @@ -806,6 +1092,16 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_ROOTCO); RNA_def_property_ui_text(prop, "Root Texture Coordinates", "Texture coordinates from root particle locations"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "do_location", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_LOCATION); + RNA_def_property_ui_text(prop, "Location", "Effect particles' location"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "do_rotation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_ROTATION); + RNA_def_property_ui_text(prop, "Rotation", "Effect particles' dynamic rotation"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /* Pointer */ @@ -1115,12 +1411,18 @@ static void rna_def_softbody(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get", "rna_SoftBodySettings_self_collision_set"); RNA_def_property_ui_text(prop, "Self Collision", "Enable naive vertex ball self collision."); RNA_def_property_update(prop, 0, "rna_softbody_update"); + + prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "EffectorWeights"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Effector Weights", ""); } void RNA_def_object_force(BlenderRNA *brna) { rna_def_pointcache(brna); rna_def_collision(brna); + rna_def_effector_weight(brna); rna_def_field(brna); rna_def_game_softbody(brna); rna_def_softbody(brna); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 04b4b1142be..453b5f9f91a 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -99,6 +99,7 @@ EnumPropertyItem part_hair_ren_as_items[] = { #include "BKE_context.h" #include "BKE_cloth.h" #include "BKE_depsgraph.h" +#include "BKE_effect.h" #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -106,48 +107,43 @@ EnumPropertyItem part_hair_ren_as_items[] = { #include "BLI_arithb.h" /* property update functions */ -static void rna_Particle_redo(bContext *C, PointerRNA *ptr) +static void particle_recalc(bContext *C, PointerRNA *ptr, short flag) { - Scene *scene = CTX_data_scene(C); - ParticleSettings *part; if(ptr->type==&RNA_ParticleSystem) { ParticleSystem *psys = (ParticleSystem*)ptr->data; - Object *ob = psys_find_object(scene, psys); - psys->recalc = PSYS_RECALC_REDO; + psys->recalc = flag; - if(ob) - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - else { - part = ptr->id.data; - psys_flush_particle_settings(scene, part, PSYS_RECALC_REDO); + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA); } + else + DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA|flag); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); } +static void rna_Particle_redo(bContext *C, PointerRNA *ptr) +{ + particle_recalc(C, ptr, PSYS_RECALC_REDO); +} static void rna_Particle_reset(bContext *C, PointerRNA *ptr) { - Scene *scene = CTX_data_scene(C); - ParticleSettings *part; + particle_recalc(C, ptr, PSYS_RECALC_RESET); +} - if(ptr->type==&RNA_ParticleSystem) { - ParticleSystem *psys = (ParticleSystem*)ptr->data; - Object *ob = psys_find_object(scene, psys); - - psys->recalc = PSYS_RECALC_RESET; +static void rna_Particle_change_type(bContext *C, PointerRNA *ptr) +{ + particle_recalc(C, ptr, PSYS_RECALC_RESET|PSYS_RECALC_TYPE); +} - if(ob) { - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } - else { - part = ptr->id.data; - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET); - } +static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr) +{ + particle_recalc(C, ptr, PSYS_RECALC_RESET|PSYS_RECALC_PHYS); +} - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); +static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr) +{ + particle_recalc(C, ptr, PSYS_RECALC_CHILD); } static void rna_Particle_target_reset(bContext *C, PointerRNA *ptr) @@ -199,59 +195,6 @@ static void rna_Particle_target_redo(bContext *C, PointerRNA *ptr) } } -static void rna_Particle_change_type(bContext *C, PointerRNA *ptr) -{ - Scene *scene = CTX_data_scene(C); - ParticleSettings *part; - - if(ptr->type==&RNA_ParticleSystem) { - ParticleSystem *psys = (ParticleSystem*)ptr->data; - Object *ob = psys_find_object(scene, psys); - - psys->recalc = PSYS_RECALC_RESET|PSYS_RECALC_TYPE; - - if(ob) { - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - } - else { - part = ptr->id.data; - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE); - } - - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); -} - -static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr) -{ - Scene *scene = CTX_data_scene(C); - ParticleSettings *part = ptr->id.data; - psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_PHYS); - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); -} - -static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr) -{ - Scene *scene = CTX_data_scene(C); - ParticleSettings *part; - - if(ptr->type==&RNA_ParticleSystem) { - ParticleSystem *psys = (ParticleSystem*)ptr->data; - Object *ob = psys_find_object(scene, psys); - - psys->recalc = PSYS_RECALC_CHILD; - - if(ob) - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - } - else { - part = ptr->id.data; - - psys_flush_particle_settings(scene, part, PSYS_RECALC_CHILD); - } - - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, NULL); -} static void rna_Particle_hair_dynamics(bContext *C, PointerRNA *ptr) { /* Scene *scene = CTX_data_scene(C); */ @@ -577,6 +520,28 @@ static EnumPropertyItem *rna_Particle_ren_as_itemf(bContext *C, PointerRNA *ptr, return part_ren_as_items; } +static PointerRNA rna_Particle_field1_get(PointerRNA *ptr) +{ + ParticleSettings *part= (ParticleSettings*)ptr->id.data; + + /* weak */ + if(!part->pd) + part->pd= object_add_collision_fields(0); + + return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd); +} + +static PointerRNA rna_Particle_field2_get(PointerRNA *ptr) +{ + ParticleSettings *part= (ParticleSettings*)ptr->id.data; + + /* weak */ + if(!part->pd2) + part->pd2= object_add_collision_fields(0); + + return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd2); +} + #else @@ -650,7 +615,7 @@ static void rna_def_particle(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem alive_items[] = { - {PARS_KILLED, "KILLED", 0, "Killed", ""}, + //{PARS_KILLED, "KILLED", 0, "Killed", ""}, {PARS_DEAD, "DEAD", 0, "Dead", ""}, {PARS_UNBORN, "UNBORN", 0, "Unborn", ""}, {PARS_ALIVE, "ALIVE", 0, "Alive", ""}, @@ -1714,89 +1679,25 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Billboard Object", "Billboards face this object (default is active camera)"); RNA_def_property_update(prop, 0, "rna_Particle_redo"); - /* effectors */ - prop= RNA_def_property(srna, "effector_group", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "eff_group"); - RNA_def_property_struct_type(prop, "Group"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this Group."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_all", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[0]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "All", "All effector's weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_spherical", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[1]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_vortex", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[2]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Vortex", "Vortex effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_magnetic", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[3]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Magnetic", "Magnetic effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_wind", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[4]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Wind", "Wind effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_curveguide", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[5]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Curve Guide", "Curve guide effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_texture", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[6]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Texture", "Texture effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_harmonic", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[7]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Harmonic", "Harmonic effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_charge", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[8]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Charge", "Charge effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "eweight_lennardjones", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "effector_weight[9]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Lennard-Jones", "Lennard-Jones effector weight."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); + prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "EffectorWeights"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Effector Weights", ""); /* animation here? */ rna_def_animdata_common(srna); -// struct PartDeflect *pd; -// struct PartDeflect *pd2; + prop= RNA_def_property(srna, "force_field_1", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "pd"); + RNA_def_property_struct_type(prop, "FieldSettings"); + RNA_def_property_pointer_funcs(prop, "rna_Particle_field1_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Force Field 1", ""); + + prop= RNA_def_property(srna, "force_field_2", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "pd2"); + RNA_def_property_struct_type(prop, "FieldSettings"); + RNA_def_property_pointer_funcs(prop, "rna_Particle_field2_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Force Field 2", ""); } static void rna_def_particle_target(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 95678678569..d6cd81aced2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -62,6 +62,7 @@ EnumPropertyItem prop_mode_items[] ={ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_node.h" +#include "BKE_pointcache.h" #include "BLI_threads.h" @@ -415,6 +416,14 @@ static void rna_Scene_use_nodes_set(PointerRNA *ptr, int value) ED_node_composit_default(scene); } +static void rna_Physics_update(bContext *C, PointerRNA *ptr) +{ + Scene *scene= (Scene*)ptr->id.data; + Base *base; + + for(base = scene->base.first; base; base=base->next) + BKE_ptcache_object_reset(scene, base->object, PTCACHE_RESET_DEPSGRAPH); +} #else static void rna_def_tool_settings(BlenderRNA *brna) @@ -596,7 +605,6 @@ static void rna_def_unit_settings(BlenderRNA *brna) RNA_def_property_update(prop, NC_WINDOW, NULL); } - void rna_def_render_layer_common(StructRNA *srna, int scene) { PropertyRNA *prop; @@ -2131,6 +2139,19 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "unit"); RNA_def_property_struct_type(prop, "UnitSettings"); RNA_def_property_ui_text(prop, "Unit Settings", "Unit editing settings"); + + /* Physics Settings */ + prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION); + RNA_def_property_float_sdna(prop, NULL, "physics_settings.gravity"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_text(prop, "Gravity", "Constant acceleration in a given direction"); + RNA_def_property_update(prop, 0, "rna_Physics_update"); + + prop= RNA_def_property(srna, "use_gravity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "physics_settings.flag", PHYS_GLOBAL_GRAVITY); + RNA_def_property_ui_text(prop, "Global Gravity", "Use global gravity for all dynamics."); + RNA_def_property_update(prop, 0, "rna_Physics_update"); /* Render Data */ prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NONE); -- cgit v1.2.3 From bf3374426abe1382718120830572cd5775c4bf82 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 30 Sep 2009 23:31:10 +0000 Subject: Use curve twist for the CurveDeform modifier and bones (anything that uses curve_deform_verts() and curve_deform_vector()). So means minimum twist and twist smoothing are now used. the Z up quaternion from the path is rotated to match the up axis given. There was no logical rule for the up vector, some cases flipped the normals when used with the CurveDeform modifier. Use the default X-Up behavior and match other settings with this. (comments explain this in detail). - Interpolating quaternions didn't work in some cases, disabled for now. - 'no_rot_axis' is different from in 2.4x since it now removes rotation from the tilt whereas before it edited the axis before calculating the tilt. --- source/blender/blenkernel/intern/anim.c | 16 +++- source/blender/blenkernel/intern/lattice.c | 144 +++++++++++++++++++++-------- 2 files changed, 118 insertions(+), 42 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index e943d92a0b5..bd779935d55 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -280,17 +280,27 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, if (quat) { float totfac, q1[4], q2[4]; + /* checks for totfac are needed when 'fac' is 1.0 key_curve_position_weights can assign zero + * to more then one index in data which can give divide by zero error */ +/* totfac= data[0]+data[1]; - QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac); + if(totfac>0.000001) QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac); + else QUATCOPY(q1, p1->quat); + NormalQuat(q1); totfac= data[2]+data[3]; - QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac); + if(totfac>0.000001) QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac); + else QUATCOPY(q1, p3->quat); NormalQuat(q2); totfac = data[0]+data[1]+data[2]+data[3]; - QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac); + if(totfac>0.000001) QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac); + else QUATCOPY(quat, q2); NormalQuat(quat); + */ + // XXX - find some way to make quat interpolation work correctly, above code fails in rare but nasty cases. + QUATCOPY(quat, p1->quat); } if(radius) diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 730a12bea09..a957be4704c 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -524,30 +524,13 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp) { Curve *cu= par->data; - float fac, loc[4], dir[3], cent[3], radius; - short upflag, index; - - if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) { - upflag= OB_POSZ; - cent[0]= 0.0; - cent[1]= co[1]; - cent[2]= co[2]; - index= 0; - } - else if(axis==MOD_CURVE_POSY || axis==MOD_CURVE_NEGY) { - upflag= OB_POSZ; - cent[0]= co[0]; - cent[1]= 0.0; - cent[2]= co[2]; - index= 1; - } - else { - upflag= OB_POSY; - cent[0]= co[0]; - cent[1]= co[1]; - cent[2]= 0.0; - index= 2; - } + float fac, loc[4], dir[3], new_quat[4], radius; + short /*upflag, */ index; + + index= axis-1; + if(index>2) + index -= 3; /* negative */ + /* to be sure, mostly after file load */ if(cu->path==NULL) { makeDispListCurveTypes(scene, par, 0); @@ -555,7 +538,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C } /* options */ - if(ELEM3(axis, OB_NEGX, OB_NEGY, OB_NEGZ)) { + if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */ if(cu->flag & CU_STRETCH) fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]); else @@ -579,9 +562,10 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C } #endif // XXX old animation system - if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */ - float q[4], mat[3][3], quat[4]; - + if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ + float quat[4], cent[3]; + +#if 0 // XXX - 2.4x Z-Up, Now use bevel tilt. if(cd->no_rot_axis) /* set by caller */ dir[cd->no_rot_axis-1]= 0.0f; @@ -597,22 +581,104 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C q[2]= -fac*dir[1]; q[3]= -fac*dir[2]; QuatMul(quat, q, quat); - } - QuatToMat3(quat, mat); - - if(cu->flag & CU_PATH_RADIUS) { - float tmat[3][3], rmat[3][3]; - Mat3Scale(tmat, radius); - Mat3MulMat3(rmat, mat, tmat); - Mat3CpyMat3(mat, rmat); } +#endif - /* local rotation */ - Mat3MulVecfl(mat, cent); + + static float q_x90d[4] = {0.70710676908493, 0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180)); + static float q_y90d[4] = {0.70710676908493, 0.0, 0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180)); + static float q_z90d[4] = {0.70710676908493, 0.0, 0.0, 0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180)); + + static float q_nx90d[4] = {0.70710676908493, -0.70710676908493, 0.0, 0.0}; // float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180)); + static float q_ny90d[4] = {0.70710676908493, 0.0, -0.70710676908493, 0.0}; // float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180)); + static float q_nz90d[4] = {0.70710676908493, 0.0, 0.0, -0.70710676908493}; // float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180)); + + + if(cd->no_rot_axis) { /* set by caller */ + + /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then + * changing the axis before calculating the tilt but serves much the same purpose */ + float dir_flat[3]={0,0,0}, q[4]; + VECCOPY(dir_flat, dir); + dir_flat[cd->no_rot_axis-1]= 0.0f; + + Normalize(dir); + Normalize(dir_flat); + + RotationBetweenVectorsToQuat(q, dir, dir_flat); /* Could this be done faster? */ + + QuatMul(new_quat, q, new_quat); + } + + + /* Logic for 'cent' orientation * + * + * The way 'co' is copied to 'cent' may seem to have no meaning, but it does. + * + * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark. + * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise + * Notice X,Y,Z Up all have light colors and each ordered CCW. + * + * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell + * */ + + switch(axis) { + case MOD_CURVE_POSX: + QuatMul(quat, new_quat, q_y90d); + + cent[0]= 0.0; + cent[1]= co[2]; + cent[2]= co[1]; + break; + case MOD_CURVE_NEGX: + QuatMul(quat, new_quat, q_ny90d); + + cent[0]= 0.0; + cent[1]= -co[1]; + cent[2]= co[2]; + + break; + case MOD_CURVE_POSY: + QuatMul(quat, new_quat, q_x90d); + + cent[0]= co[2]; + cent[1]= 0.0; + cent[2]= -co[0]; + break; + case MOD_CURVE_NEGY: + QuatMul(quat, new_quat, q_nx90d); + + cent[0]= -co[0]; + cent[1]= 0.0; + cent[2]= -co[2]; + break; + case MOD_CURVE_POSZ: + QuatMul(quat, new_quat, q_z90d); + + cent[0]= co[1]; + cent[1]= -co[0]; + cent[2]= 0.0; + break; + case MOD_CURVE_NEGZ: + QuatMul(quat, new_quat, q_nz90d); + + cent[0]= co[0]; + cent[1]= -co[1]; + cent[2]= 0.0; + break; + } + + /* scale if enabled */ + if(cu->flag & CU_PATH_RADIUS) + VecMulf(cent, radius); + /* local rotation */ + NormalQuat(quat); + QuatMulVecf(quat, cent); + /* translation */ VECADD(co, cent, loc); - + if(quatp) QUATCOPY(quatp, quat); -- cgit v1.2.3 From 0901eafa8fe093db1938aa773b8c963ec9a649c7 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Thu, 1 Oct 2009 04:14:43 +0000 Subject: * Added proper update/conversions for changing between degrees and "mm" in camera --- source/blender/makesrna/intern/rna_camera.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index eaf647e02a2..6254041c7ef 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -22,7 +22,9 @@ * ***** END GPL LICENSE BLOCK ***** */ +#define _USE_MATH_DEFINES #include +#include #include "RNA_define.h" #include "RNA_types.h" @@ -35,6 +37,19 @@ #ifdef RNA_RUNTIME +static void rna_Camera_angle_update(bContext *C, PointerRNA *ptr) +{ + Camera *cam= (Camera*)ptr->id.data; + cam->lens = 16.0f / tan(M_PI*cam->angle/360.0f); +} + +static void rna_Camera_lens_update(bContext *C, PointerRNA *ptr) +{ + Camera *cam= (Camera*)ptr->id.data; + cam->angle= 360.0f * atan(16.0f/cam->lens) / M_PI; +} + + #else void RNA_def_camera(BlenderRNA *brna) @@ -72,7 +87,7 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "angle"); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Angle", "Perspective Camera lend field of view in degrees."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_angle_update"); prop= RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "clipsta"); @@ -90,7 +105,7 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "lens"); RNA_def_property_range(prop, 1.0f, 250.0f); RNA_def_property_ui_text(prop, "Lens", "Perspective Camera lens value in mm."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_lens_update"); prop= RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ortho_scale"); -- cgit v1.2.3 From 3f3c2d0204c98ee1a095d716633bdb84c1f03bd8 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Thu, 1 Oct 2009 08:58:09 +0000 Subject: Cocoa port, events WIP: - Fix keyboard keymap - NSAutoReleasePool now drained at every cycle - Tablet events combined with mouse events now handled --- intern/ghost/intern/GHOST_SystemCocoa.h | 2 +- intern/ghost/intern/GHOST_SystemCocoa.mm | 434 ++++++++++++++++--------------- 2 files changed, 223 insertions(+), 213 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index a996c101a98..cd2cf12daa1 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -252,7 +252,7 @@ protected: //static void s_timerCallback(TMTaskPtr tmTask); /** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */ - void* autoReleasePool; + void* m_autoReleasePool; /** Event handler reference. */ //EventHandlerRef m_handler; diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 7ad523d5a9f..252ac9e6318 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -49,27 +49,17 @@ #include "GHOST_NDOFManager.h" #include "AssertMacros.h" -#define GHOST_KEY_SWITCH(mac, ghost) { case (mac): ghostKey = (ghost); break; } - -/* blender class and types events */ -enum { - kEventClassBlender = 'blnd' -}; - -enum { - kEventBlenderNdofAxis = 1, - kEventBlenderNdofButtons = 2 -}; - #pragma mark KeyMap, mouse converters +//TODO: remove (kept as reminder to implement window events) +/* const EventTypeSpec kEvents[] = { { kEventClassAppleEvent, kEventAppleEvent }, -/* - { kEventClassApplication, kEventAppActivated }, - { kEventClassApplication, kEventAppDeactivated }, -*/ + +// { kEventClassApplication, kEventAppActivated }, +// { kEventClassApplication, kEventAppDeactivated }, + { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat }, { kEventClassKeyboard, kEventRawKeyUp }, @@ -81,10 +71,10 @@ const EventTypeSpec kEvents[] = { kEventClassMouse, kEventMouseDragged }, { kEventClassMouse, kEventMouseWheelMoved }, - { kEventClassWindow, kEventWindowClickZoomRgn } , /* for new zoom behaviour */ - { kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */ - { kEventClassWindow, kEventWindowExpand } , /* for new zoom behaviour */ - { kEventClassWindow, kEventWindowExpandAll }, /* for new zoom behaviour */ + { kEventClassWindow, kEventWindowClickZoomRgn } , // for new zoom behaviour + { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour + { kEventClassWindow, kEventWindowExpand } , // for new zoom behaviour + { kEventClassWindow, kEventWindowExpandAll }, // for new zoom behaviour { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowActivated }, @@ -97,7 +87,7 @@ const EventTypeSpec kEvents[] = -}; +};*/ static GHOST_TButtonMask convertButton(EventMouseButton button) { @@ -117,103 +107,155 @@ static GHOST_TButtonMask convertButton(EventMouseButton button) } } -static GHOST_TKey convertKey(int rawCode, unsigned char asciiCharacter) +/** + * Converts Mac rawkey codes (same for Cocoa & Carbon) + * into GHOST key codes + * @param rawCode The raw physical key code + * @param recvChar the character ignoring modifiers (except for shift) + * @return Ghost key code + */ +static GHOST_TKey convertKey(int rawCode, unichar recvChar) { - /* This bit of magic converts the rawCode into a virtual - * Mac key based on the current keyboard mapping, but - * without regard to the modifiers (so we don't get 'a' - * and 'A' for example. - */ - /* Map numpad based on rawcodes first, otherwise they - * look like non-numpad events. - * Added too: mapping the number keys, for french keyboards etc (ton) - */ - // printf("GHOST: vk: %d %c raw: %d\n", asciiCharacter, asciiCharacter, rawCode); - //FIXME : check rawcodes - switch (rawCode) { - case 18: return GHOST_kKey1; - case 19: return GHOST_kKey2; - case 20: return GHOST_kKey3; - case 21: return GHOST_kKey4; - case 23: return GHOST_kKey5; - case 22: return GHOST_kKey6; - case 26: return GHOST_kKey7; - case 28: return GHOST_kKey8; - case 25: return GHOST_kKey9; - case 29: return GHOST_kKey0; - - case 82: return GHOST_kKeyNumpad0; - case 83: return GHOST_kKeyNumpad1; - case 84: return GHOST_kKeyNumpad2; - case 85: return GHOST_kKeyNumpad3; - case 86: return GHOST_kKeyNumpad4; - case 87: return GHOST_kKeyNumpad5; - case 88: return GHOST_kKeyNumpad6; - case 89: return GHOST_kKeyNumpad7; - case 91: return GHOST_kKeyNumpad8; - case 92: return GHOST_kKeyNumpad9; - case 65: return GHOST_kKeyNumpadPeriod; - case 76: return GHOST_kKeyNumpadEnter; - case 69: return GHOST_kKeyNumpadPlus; - case 78: return GHOST_kKeyNumpadMinus; - case 67: return GHOST_kKeyNumpadAsterisk; - case 75: return GHOST_kKeyNumpadSlash; - } - if ((asciiCharacter >= 'a') && (asciiCharacter <= 'z')) { - return (GHOST_TKey) (asciiCharacter - 'a' + GHOST_kKeyA); - } else if ((asciiCharacter >= '0') && (asciiCharacter <= '9')) { - return (GHOST_TKey) (asciiCharacter - '0' + GHOST_kKey0); - } else if (asciiCharacter==16) { - switch (rawCode) { - case 122: return GHOST_kKeyF1; - case 120: return GHOST_kKeyF2; - case 99: return GHOST_kKeyF3; - case 118: return GHOST_kKeyF4; - case 96: return GHOST_kKeyF5; - case 97: return GHOST_kKeyF6; - case 98: return GHOST_kKeyF7; - case 100: return GHOST_kKeyF8; - case 101: return GHOST_kKeyF9; - case 109: return GHOST_kKeyF10; - case 103: return GHOST_kKeyF11; - case 111: return GHOST_kKeyF12; // FIXME : Never get, is used for ejecting the CD! - } - } else { - switch (asciiCharacter) { - case kUpArrowCharCode: return GHOST_kKeyUpArrow; - case kDownArrowCharCode: return GHOST_kKeyDownArrow; - case kLeftArrowCharCode: return GHOST_kKeyLeftArrow; - case kRightArrowCharCode: return GHOST_kKeyRightArrow; - - case kReturnCharCode: return GHOST_kKeyEnter; - case kBackspaceCharCode: return GHOST_kKeyBackSpace; - case kDeleteCharCode: return GHOST_kKeyDelete; - case kEscapeCharCode: return GHOST_kKeyEsc; - case kTabCharCode: return GHOST_kKeyTab; - case kSpaceCharCode: return GHOST_kKeySpace; - - case kHomeCharCode: return GHOST_kKeyHome; - case kEndCharCode: return GHOST_kKeyEnd; - case kPageUpCharCode: return GHOST_kKeyUpPage; - case kPageDownCharCode: return GHOST_kKeyDownPage; - - case '-': return GHOST_kKeyMinus; - case '=': return GHOST_kKeyEqual; - case ',': return GHOST_kKeyComma; - case '.': return GHOST_kKeyPeriod; - case '/': return GHOST_kKeySlash; - case ';': return GHOST_kKeySemicolon; - case '\'': return GHOST_kKeyQuote; - case '\\': return GHOST_kKeyBackslash; - case '[': return GHOST_kKeyLeftBracket; - case ']': return GHOST_kKeyRightBracket; - case '`': return GHOST_kKeyAccentGrave; - } + //printf("\nrecvchar %c 0x%x",recvChar,recvChar); + switch (rawCode) { + /*Physical keycodes not used due to map changes in int'l keyboards + case kVK_ANSI_A: return GHOST_kKeyA; + case kVK_ANSI_B: return GHOST_kKeyB; + case kVK_ANSI_C: return GHOST_kKeyC; + case kVK_ANSI_D: return GHOST_kKeyD; + case kVK_ANSI_E: return GHOST_kKeyE; + case kVK_ANSI_F: return GHOST_kKeyF; + case kVK_ANSI_G: return GHOST_kKeyG; + case kVK_ANSI_H: return GHOST_kKeyH; + case kVK_ANSI_I: return GHOST_kKeyI; + case kVK_ANSI_J: return GHOST_kKeyJ; + case kVK_ANSI_K: return GHOST_kKeyK; + case kVK_ANSI_L: return GHOST_kKeyL; + case kVK_ANSI_M: return GHOST_kKeyM; + case kVK_ANSI_N: return GHOST_kKeyN; + case kVK_ANSI_O: return GHOST_kKeyO; + case kVK_ANSI_P: return GHOST_kKeyP; + case kVK_ANSI_Q: return GHOST_kKeyQ; + case kVK_ANSI_R: return GHOST_kKeyR; + case kVK_ANSI_S: return GHOST_kKeyS; + case kVK_ANSI_T: return GHOST_kKeyT; + case kVK_ANSI_U: return GHOST_kKeyU; + case kVK_ANSI_V: return GHOST_kKeyV; + case kVK_ANSI_W: return GHOST_kKeyW; + case kVK_ANSI_X: return GHOST_kKeyX; + case kVK_ANSI_Y: return GHOST_kKeyY; + case kVK_ANSI_Z: return GHOST_kKeyZ;*/ + + /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/ + case kVK_ISO_Section: return GHOST_kKeyUnknown; + case kVK_ANSI_1: return GHOST_kKey1; + case kVK_ANSI_2: return GHOST_kKey2; + case kVK_ANSI_3: return GHOST_kKey3; + case kVK_ANSI_4: return GHOST_kKey4; + case kVK_ANSI_5: return GHOST_kKey5; + case kVK_ANSI_6: return GHOST_kKey6; + case kVK_ANSI_7: return GHOST_kKey7; + case kVK_ANSI_8: return GHOST_kKey8; + case kVK_ANSI_9: return GHOST_kKey9; + case kVK_ANSI_0: return GHOST_kKey0; + + case kVK_ANSI_Keypad0: return GHOST_kKeyNumpad0; + case kVK_ANSI_Keypad1: return GHOST_kKeyNumpad1; + case kVK_ANSI_Keypad2: return GHOST_kKeyNumpad2; + case kVK_ANSI_Keypad3: return GHOST_kKeyNumpad3; + case kVK_ANSI_Keypad4: return GHOST_kKeyNumpad4; + case kVK_ANSI_Keypad5: return GHOST_kKeyNumpad5; + case kVK_ANSI_Keypad6: return GHOST_kKeyNumpad6; + case kVK_ANSI_Keypad7: return GHOST_kKeyNumpad7; + case kVK_ANSI_Keypad8: return GHOST_kKeyNumpad8; + case kVK_ANSI_Keypad9: return GHOST_kKeyNumpad9; + case kVK_ANSI_KeypadDecimal: return GHOST_kKeyNumpadPeriod; + case kVK_ANSI_KeypadEnter: return GHOST_kKeyNumpadEnter; + case kVK_ANSI_KeypadPlus: return GHOST_kKeyNumpadPlus; + case kVK_ANSI_KeypadMinus: return GHOST_kKeyNumpadMinus; + case kVK_ANSI_KeypadMultiply: return GHOST_kKeyNumpadAsterisk; + case kVK_ANSI_KeypadDivide: return GHOST_kKeyNumpadSlash; + case kVK_ANSI_KeypadClear: return GHOST_kKeyUnknown; + + case kVK_F1: return GHOST_kKeyF1; + case kVK_F2: return GHOST_kKeyF2; + case kVK_F3: return GHOST_kKeyF3; + case kVK_F4: return GHOST_kKeyF4; + case kVK_F5: return GHOST_kKeyF5; + case kVK_F6: return GHOST_kKeyF6; + case kVK_F7: return GHOST_kKeyF7; + case kVK_F8: return GHOST_kKeyF8; + case kVK_F9: return GHOST_kKeyF9; + case kVK_F10: return GHOST_kKeyF10; + case kVK_F11: return GHOST_kKeyF11; + case kVK_F12: return GHOST_kKeyF12; + case kVK_F13: return GHOST_kKeyF13; + case kVK_F14: return GHOST_kKeyF14; + case kVK_F15: return GHOST_kKeyF15; + case kVK_F16: return GHOST_kKeyF16; + case kVK_F17: return GHOST_kKeyF17; + case kVK_F18: return GHOST_kKeyF18; + case kVK_F19: return GHOST_kKeyF19; + case kVK_F20: return GHOST_kKeyF20; + + case kVK_UpArrow: return GHOST_kKeyUpArrow; + case kVK_DownArrow: return GHOST_kKeyDownArrow; + case kVK_LeftArrow: return GHOST_kKeyLeftArrow; + case kVK_RightArrow: return GHOST_kKeyRightArrow; + + case kVK_Return: return GHOST_kKeyEnter; + case kVK_Delete: return GHOST_kKeyBackSpace; + case kVK_ForwardDelete: return GHOST_kKeyDelete; + case kVK_Escape: return GHOST_kKeyEsc; + case kVK_Tab: return GHOST_kKeyTab; + case kVK_Space: return GHOST_kKeySpace; + + case kVK_Home: return GHOST_kKeyHome; + case kVK_End: return GHOST_kKeyEnd; + case kVK_PageUp: return GHOST_kKeyUpPage; + case kVK_PageDown: return GHOST_kKeyDownPage; + + /*case kVK_ANSI_Minus: return GHOST_kKeyMinus; + case kVK_ANSI_Equal: return GHOST_kKeyEqual; + case kVK_ANSI_Comma: return GHOST_kKeyComma; + case kVK_ANSI_Period: return GHOST_kKeyPeriod; + case kVK_ANSI_Slash: return GHOST_kKeySlash; + case kVK_ANSI_Semicolon: return GHOST_kKeySemicolon; + case kVK_ANSI_Quote: return GHOST_kKeyQuote; + case kVK_ANSI_Backslash: return GHOST_kKeyBackslash; + case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket; + case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket; + case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/ + + case kVK_VolumeUp: + case kVK_VolumeDown: + case kVK_Mute: + return GHOST_kKeyUnknown; + + default: + /*Then detect on character value for "remappable" keys in int'l keyboards*/ + if ((recvChar >= 'A') && (recvChar <= 'Z')) { + return (GHOST_TKey) (recvChar - 'A' + GHOST_kKeyA); + } else if ((recvChar >= 'a') && (recvChar <= 'z')) { + return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA); + } else + switch (recvChar) { + case '-': return GHOST_kKeyMinus; + case '=': return GHOST_kKeyEqual; + case ',': return GHOST_kKeyComma; + case '.': return GHOST_kKeyPeriod; + case '/': return GHOST_kKeySlash; + case ';': return GHOST_kKeySemicolon; + case '\'': return GHOST_kKeyQuote; + case '\\': return GHOST_kKeyBackslash; + case '[': return GHOST_kKeyLeftBracket; + case ']': return GHOST_kKeyRightBracket; + case '`': return GHOST_kKeyAccentGrave; + default: + return GHOST_kKeyUnknown; + } } - - // printf("GHOST: unknown key: %d %d\n", vk, rawCode); - return GHOST_kKeyUnknown; } @@ -349,6 +391,7 @@ static unsigned char convertRomanToLatin(unsigned char ascii) static bool g_hasFirstFile = false; static char g_firstFileBuf[512]; +//TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { if (g_hasFirstFile) { strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1); @@ -375,6 +418,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { { //Note that Cmd+Q is already handled by keyhandler //FIXME: Cocoa_SendQuit(); + //sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) ); return NSTerminateCancel; } @end @@ -427,13 +471,12 @@ GHOST_TSuccess GHOST_SystemCocoa::init() SetFrontProcess(&psn); }*/ - autoReleasePool = [[NSAutoreleasePool alloc] init]; + m_autoReleasePool = [[NSAutoreleasePool alloc] init]; if (NSApp == nil) { [NSApplication sharedApplication]; if ([NSApp mainMenu] == nil) { //FIXME: CreateApplicationMenus(); - printf("Creating main menu"); } [NSApp finishLaunching]; } @@ -467,8 +510,8 @@ GHOST_TSuccess GHOST_SystemCocoa::init() GHOST_TSuccess GHOST_SystemCocoa::exit() { - NSAutoreleasePool* pool = (NSAutoreleasePool *)autoReleasePool; - [pool release]; + NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool; + [pool drain]; return GHOST_System::exit(); } @@ -476,7 +519,7 @@ GHOST_TSuccess GHOST_SystemCocoa::exit() GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const { - //FIXME : replace by Cocoa equivalent + //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime]) int mib[2]; struct timeval boottime; size_t len; @@ -587,17 +630,11 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3 GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const { float xf=(float)x, yf=(float)y; - //TODO:cocoatize this + CGAssociateMouseAndMouseCursorPosition(false); - CGSetLocalEventsSuppressionInterval(0); CGWarpMouseCursorPosition(CGPointMake(xf, yf)); CGAssociateMouseAndMouseCursorPosition(true); -//this doesn't work properly, see game engine mouse-look scripts -// CGWarpMouseCursorPosition(CGPointMake(xf, yf)); - // this call below sends event, but empties other events (like shift) - // CGPostMouseEvent(CGPointMake(xf, yf), TRUE, 1, FALSE, 0); - return GHOST_kSuccess; } @@ -635,15 +672,22 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const */ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) { - bool anyProcessed = false; + NSAutoreleasePool* pool = (NSAutoreleasePool*)m_autoReleasePool; + //bool anyProcessed = false; NSEvent *event; + //Reinit the AutoReleasePool + //This is not done the typical Cocoa way (init at beginning of loop, and drain at the end) + //to allow pool to work with other function calls outside this loop (but in same thread) + [pool drain]; + m_autoReleasePool = [[NSAutoreleasePool alloc] init]; + // SetMouseCoalescingEnabled(false, NULL); //TODO : implement timer ?? - do { - //GHOST_TimerManager* timerMgr = getTimerManager(); - /* + /*do { + GHOST_TimerManager* timerMgr = getTimerManager(); + if (waitForEvent) { GHOST_TUns64 next = timerMgr->nextFireTime(); double timeOut; @@ -681,7 +725,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) if (event==nil) break; - anyProcessed = true; + //anyProcessed = true; switch ([event type]) { case NSKeyDown: @@ -689,7 +733,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) case NSFlagsChanged: handleKeyEvent(event); - /* Support system-wide keyboard shortcuts, like Exposé, ...) */ + /* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */ /* if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) { [NSApp sendEvent:event]; }*/ @@ -738,15 +782,15 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) //Resend event to NSApp to ensure Mac wide events are handled [NSApp sendEvent:event]; } while (event!= nil); - } while (waitForEvent && !anyProcessed); + //} while (waitForEvent && !anyProcessed); Needed only for timer implementation + - return anyProcessed; + return true; //anyProcessed; } //TODO: To be called from NSWindow delegate int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) { - int err = eventNotHandledErr; /*WindowRef windowRef; GHOST_WindowCocoa *window; @@ -795,7 +839,7 @@ int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) //::RemoveEventFromQueue(::GetMainEventQueue(), event); //} */ - return err; + return GHOST_kSuccess; } int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) @@ -803,13 +847,27 @@ int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData(); + NSUInteger tabletEvent; ct.Pressure = 0; ct.Xtilt = 0; ct.Ytilt = 0; + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + tabletEvent = NSTabletPoint; + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + tabletEvent = NSTabletProximity; + break; + + default: + tabletEvent = [event type]; + break; + } - switch ([event type]) { + switch (tabletEvent) { case NSTabletPoint: ct.Pressure = [event tangentialPressure]; ct.Xtilt = [event tilt].x; @@ -841,9 +899,10 @@ int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) default: GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received"); + return GHOST_kFailure; break; } - return noErr; + return GHOST_kSuccess; } @@ -851,16 +910,16 @@ int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); - + switch ([event type]) { - //TODO: check for tablet subtype events case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: if (m_windowManager->getActiveWindow()) { pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber]))); } + handleTabletEvent(eventPtr); break; case NSLeftMouseUp: @@ -869,12 +928,14 @@ int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) if (m_windowManager->getActiveWindow()) { pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber]))); } + handleTabletEvent(eventPtr); break; - case NSMouseMoved: case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: + handleTabletEvent(eventPtr); + case NSMouseMoved: { NSPoint mousePos = [event locationInWindow]; pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y)); @@ -889,46 +950,44 @@ int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } break; + + default: + return GHOST_kFailure; + break; } - return noErr; + return GHOST_kSuccess; } int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; - OSStatus err = eventNotHandledErr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); NSUInteger modifiers; - unsigned short rawCode; - GHOST_TKey key; + GHOST_TKey keyCode; unsigned char ascii; /* Can happen, very rarely - seems to only be when command-H makes * the window go away and we still get an HKey up. */ if (!window) { - //::GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &rawCode); - //key = convertKey(rawCode); - return err; + return GHOST_kFailure; } - err = noErr; switch ([event type]) { case NSKeyDown: case NSKeyUp: - rawCode = [event keyCode]; - ascii = [[event characters] characterAtIndex:0]; - - key = convertKey(rawCode,ascii); - ascii= convertRomanToLatin(ascii); + keyCode = convertKey([event keyCode], + [[event charactersIgnoringModifiers] characterAtIndex:0]); + ascii= convertRomanToLatin((char)[[event characters] characterAtIndex:0]); if ([event type] == NSKeyDown) { - pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, key, ascii) ); - } else { - pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyUp, window, key, ascii) ); - } + pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) ); + //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii); + } else { + pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyUp, window, keyCode, ascii) ); + } break; case NSFlagsChanged: @@ -950,11 +1009,11 @@ int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) break; default: - err = eventNotHandledErr; + return GHOST_kFailure; break; } - return err; + return GHOST_kSuccess; } @@ -1157,6 +1216,8 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const [pasteBoard setString:textToCopy forType:@"public.utf8-plain-text"]; + printf("\nCopy"); + } #pragma mark Carbon stuff to remove @@ -1228,55 +1289,4 @@ OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *re return noErr; } - -OSStatus GHOST_SystemCarbon::sEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) -{ - GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) userData; - OSStatus err = eventNotHandledErr; - GHOST_IWindow* window; - GHOST_TEventNDOFData data; - UInt32 kind; - - switch (::GetEventClass(event)) - { - case kEventClassAppleEvent: - EventRecord eventrec; - if (ConvertEventRefToEventRecord(event, &eventrec)) { - err = AEProcessAppleEvent(&eventrec); - } - break; - case kEventClassMouse: - err = sys->handleMouseEvent(event); - break; - case kEventClassWindow: - err = sys->handleWindowEvent(event); - break; - case kEventClassKeyboard: - err = sys->handleKeyEvent(event); - break; - case kEventClassBlender : - window = sys->m_windowManager->getActiveWindow(); - sys->m_ndofManager->GHOST_NDOFGetDatas(data); - kind = ::GetEventKind(event); - - switch (kind) - { - case 1: - sys->m_eventManager->pushEvent(new GHOST_EventNDOF(sys->getMilliSeconds(), GHOST_kEventNDOFMotion, window, data)); - // printf("motion\n"); - break; - case 2: - sys->m_eventManager->pushEvent(new GHOST_EventNDOF(sys->getMilliSeconds(), GHOST_kEventNDOFButton, window, data)); - // printf("button\n"); - break; - } - err = noErr; - break; - default : - ; - break; - } - - return err; -} #endif \ No newline at end of file -- cgit v1.2.3 From 492c545e05cc12f9a57976d17725fbf6dfb1b711 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 1 Oct 2009 11:21:40 +0000 Subject: only link against python when its enabled remove duplicate linking flags (looks like a copy/paste error) --- CMake/macros.cmake | 30 ++++++++++++------------------ source/creator/CMakeLists.txt | 3 ++- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/CMake/macros.cmake b/CMake/macros.cmake index 6a337505c00..e8f378c0925 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -85,30 +85,24 @@ ENDMACRO(SETUP_LIBDIRS) MACRO(SETUP_LIBLINKS target) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ") - #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIBRARY} ${LLIBS}) - TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS}) + TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS}) # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions - IF(WIN32) - TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d) - TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB}) - ELSE(WIN32) - TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB}) - ENDIF(WIN32) + IF(WITH_PYTHON) + TARGET_LINK_LIBRARIES(${target} ${PYTHON_LINKFLAGS}) + + IF(WIN32) + TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d) + TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB}) + ELSE(WIN32) + TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB}) + ENDIF(WIN32) + ENDIF(WITH_PYTHON) - TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${LLIBS}) + TARGET_LINK_LIBRARIES(${target} ${OPENGL_glu_LIBRARY} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB}) TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIBRARY} ${LIBSAMPLERATE_LIB}) - # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions - - IF(WIN32) - TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d) - TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB}) - ELSE(WIN32) - TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB}) - ENDIF(WIN32) - IF(WITH_INTERNATIONAL) TARGET_LINK_LIBRARIES(${target} ${GETTEXT_LIB}) ENDIF(WITH_INTERNATIONAL) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 7a7101bb13c..bef41983bab 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -257,7 +257,8 @@ IF(WITH_INSTALL) COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\scripts\\*.*\" \"${TARGETDIR}\\.blender\\scripts\" COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\" COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python26.zip\" \"${TARGETDIR}\\\" + # TODO, copy python bundle + # COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python31.zip\" \"${TARGETDIR}\\\" ) FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR) -- cgit v1.2.3 From 988e9132b849e4156a20fb15a8a1fc794e5389b8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 1 Oct 2009 12:33:35 +0000 Subject: Fix #19513: scroll wheel did not work when over disabled buttons. --- source/blender/editors/interface/interface_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b5de855cb80..c60c94a9c4d 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3271,7 +3271,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) retval= WM_UI_HANDLER_CONTINUE; if(but->flag & UI_BUT_DISABLED) - return WM_UI_HANDLER_BREAK; + return WM_UI_HANDLER_CONTINUE; if(data->state == BUTTON_STATE_HIGHLIGHT) { /* handle copy-paste */ -- cgit v1.2.3 From 1c3faa97ff63e22929f5bac63f9b757b37103336 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 1 Oct 2009 14:41:45 +0000 Subject: Fixed a part of [#19494]. Transform Lock Options didn't updated 3D View's Transform manipulator. * Minor Code tweak in material RNA. --- source/blender/makesrna/intern/rna_material.c | 2 +- source/blender/makesrna/intern/rna_object.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 593fc2e5935..9b9fbb350a1 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1055,7 +1055,7 @@ static void rna_def_material_volume(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "reflection_col"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Reflection Color", "Colour of light scattered out of the volume (does not affect transmission)"); - RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); prop= RNA_def_property(srna, "reflection", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "reflection"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index afc82016502..3a3842adbf1 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1289,11 +1289,14 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_LOCX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Location", "Lock editing of location in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_XYZ); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + // XXX this is sub-optimal - it really should be included above, but due to technical reasons we can't do this! prop= RNA_def_property(srna, "lock_rotation_w", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTW); @@ -1307,6 +1310,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_SCALEX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Scale", "Lock editing of scale in the interface."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); /* matrix */ prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); -- cgit v1.2.3 From 37a729cb1d3aa4957a40f30267bb784c2376cf89 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 1 Oct 2009 16:30:05 +0000 Subject: Fix crashes with .blend files saved in particle mode, derivedmesh can't be assumed to be made yet then. --- source/blender/editors/physics/particle_edit.c | 27 ++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 3478d63f67e..ac47ddebc1f 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -110,14 +110,11 @@ int PE_poll(bContext *C) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); - PTCacheEdit *edit; - if(!scene || !ob) + if(!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) return 0; - edit= PE_get_current(scene, ob); - - return (edit && (ob->mode & OB_MODE_PARTICLE_EDIT)); + return (PE_get_current(scene, ob) != NULL); } int PE_hair_poll(bContext *C) @@ -126,12 +123,12 @@ int PE_hair_poll(bContext *C) Object *ob= CTX_data_active_object(C); PTCacheEdit *edit; - if(!scene || !ob) + if(!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) return 0; edit= PE_get_current(scene, ob); - return (edit && edit->psys && (ob->mode & OB_MODE_PARTICLE_EDIT)); + return (edit && edit->psys); } int PE_poll_3dview(bContext *C) @@ -675,6 +672,9 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd= psys_get_modifier(ob, psys); totpart= psys->totpart; + if(!psmd->dm) + return; + tree= BLI_kdtree_new(totpart); /* insert particles into kd tree */ @@ -803,6 +803,9 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit= psys->edit; psmd= psys_get_modifier(ob, psys); + if(!edit->mirror_cache || !psmd->dm) + return; + /* we delay settings the PARS_EDIT_RECALC for mirrored particles * to avoid doing mirror twice */ LOOP_POINTS { @@ -841,6 +844,9 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; psmd = psys_get_modifier(ob,psys); + if(!psmd->dm) + return; + LOOP_EDITED_POINTS { psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles + p, hairmat); @@ -994,6 +1000,9 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys) float *vec, *nor; int i, totface, totvert; + if(!dm) + return; + if(edit->emitter_cosnos) MEM_freeN(edit->emitter_cosnos); @@ -1079,7 +1088,7 @@ static void update_world_cos(Object *ob, PTCacheEdit *edit) POINT_P; KEY_K; float hairmat[4][4]; - if(psys==0 || psys->edit==0) + if(psys==0 || psys->edit==0 || psmd->dm==NULL) return; LOOP_POINTS { @@ -2444,6 +2453,8 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) return; psmd= psys_get_modifier(ob, psys); + if(!psmd->dm) + return; mirrorfaces= mesh_get_x_mirror_faces(ob, NULL); -- cgit v1.2.3 From 15d81b21f6db8656b4784729b307a0a147c8e362 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 1 Oct 2009 16:32:33 +0000 Subject: Fixing scons compile on windows. Since bli_threads.h now includes pthreads directly, we need to had instructions in SConscripts everywhere for proper include path. Frankly, I feel like this should be done in a global manner and not in a per lib fashion, but that is for another day. This commit also fixes more missing properties --- source/blender/blenpluginapi/SConscript | 7 +++++++ source/blender/editors/armature/SConscript | 7 +++++++ source/blender/editors/mesh/SConscript | 7 +++++++ source/blender/editors/physics/SConscript | 7 +++++++ source/blender/editors/render/SConscript | 7 +++++++ source/blender/editors/screen/SConscript | 7 +++++++ source/blender/editors/sculpt_paint/SConscript | 7 +++++++ source/blender/editors/space_file/SConscript | 7 +++++++ source/blender/editors/space_node/SConscript | 9 ++++++++- source/blender/makesrna/SConscript | 8 ++++++++ source/blender/makesrna/intern/SConscript | 10 +++++++++- source/blender/nodes/SConscript | 7 +++++++ source/blender/render/SConscript | 8 ++++++++ source/blender/windowmanager/SConscript | 7 +++++++ 14 files changed, 103 insertions(+), 2 deletions(-) diff --git a/source/blender/blenpluginapi/SConscript b/source/blender/blenpluginapi/SConscript index af69b4519b4..b310bcb95ec 100644 --- a/source/blender/blenpluginapi/SConscript +++ b/source/blender/blenpluginapi/SConscript @@ -11,4 +11,11 @@ if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ' + env['BF_QUICKTIME_INC'] +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( libname = 'bf_blenpluginapi', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [170] ) diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript index f96d25b0fe0..a7fa9d7071f 100644 --- a/source/blender/editors/armature/SConscript +++ b/source/blender/editors/armature/SConscript @@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include #/intern/guardedalloc' incs += ' ../../gpu ../../makesrna #/intern/opennl/extern' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_armature', sources, Split(incs), [], libtype=['core'], priority=[44] ) diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index df1f297698d..00391b3474a 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' #/intern/guardedalloc ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript index 5718ae0c217..60b992d2e07 100644 --- a/source/blender/editors/physics/SConscript +++ b/source/blender/editors/physics/SConscript @@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' #/intern/guardedalloc ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_physics', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index cca2ab9b2ab..bddc5ed10e0 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -9,4 +9,11 @@ incs += ' #/intern/guardedalloc ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' incs += ' ../../blenloader' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_render', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript index a4f73cfea7e..847a1cddfb4 100644 --- a/source/blender/editors/screen/SConscript +++ b/source/blender/editors/screen/SConscript @@ -15,4 +15,11 @@ if not env['WITH_BF_PYTHON']: if env['WITH_BF_OPENEXR']: defs += ' WITH_OPENEXR' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_screen', sources, Split(incs), Split(defs), libtype=['core'], priority=[105] ) diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript index 01e1d80c24c..3d2ea89f506 100644 --- a/source/blender/editors/sculpt_paint/SConscript +++ b/source/blender/editors/sculpt_paint/SConscript @@ -8,4 +8,11 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include #/intern/guardedalloc' incs += ' ../../gpu ../../makesrna' +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), [], libtype=['core'], priority=[40] ) diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript index e6fba38fb8f..b22a265dcbc 100644 --- a/source/blender/editors/space_file/SConscript +++ b/source/blender/editors/space_file/SConscript @@ -15,4 +15,11 @@ if env['WITH_BF_OPENJPEG']: if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_space_file', sources, Split(incs), defs, libtype=['core'], priority=[115] ) diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript index 5453aa7dd44..fd0dfe83852 100644 --- a/source/blender/editors/space_node/SConscript +++ b/source/blender/editors/space_node/SConscript @@ -14,5 +14,12 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if env['CC'] == 'gcc': #cf.append('-Werror') pass - + +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_editors_space_node', sources, Split(incs), defs, libtype=['core'], priority=[55], compileflags=cf ) diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 8fc9df0fbf6..72dc6be683c 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -40,4 +40,12 @@ if env['WITH_BF_GAMEENGINE']: if env['BF_UNIT_TEST']: defs.append('UNIT_TEST') + +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core','player'], priority = [165,20] ) diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 0f8bc752f09..c63b63ce5f7 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -74,6 +74,14 @@ if env['WITH_BF_JACK']: if env['BF_UNIT_TEST']: defs.append('UNIT_TEST') + +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + makesrna_tool.Append(CPPDEFINES=defs) makesrna_tool.Append (CPPPATH = Split(incs)) @@ -126,7 +134,7 @@ rna.Depends (generated_files, makesrna) # this seems bad, how to retrieve it from scons? build_dir = root_build_dir + os.sep +'source' + os.sep + 'blender' + os.sep + 'makesrna' + os.sep + 'intern' + os.sep - + if env['OURPLATFORM'] != 'linuxcross': if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'): rna.Command (generated_files, '', "\"" + root_build_dir+os.sep+"makesrna.exe\" \"" + build_dir ) diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 771ce42e1dc..01319dc1eb4 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -38,6 +38,13 @@ if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ' + env['BF_QUICKTIME_INC'] +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [190,105] ) env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] ) env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [175,101] ) diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index db151775b96..f6193c29eba 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -23,4 +23,12 @@ if env['WITH_BF_OPENEXR']: if env['OURPLATFORM']=='linux2': cflags='-pthread' + +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( libname = 'bf_render', sources = sources, includes = Split(incs), defines=defs, libtype='core', priority=145, compileflags=cflags ) diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index 91635904524..08a291871f1 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -19,4 +19,11 @@ defs = [] if not env['WITH_BF_PYTHON']: defs.append('DISABLE_PYTHON') +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_windowmanager', sources, Split(incs), defs, libtype=['core'], priority=[5] ) -- cgit v1.2.3 From 1525ed42c9b4d81deb686f3bdd5a5bdae70b5af2 Mon Sep 17 00:00:00 2001 From: Roland Hess Date: Thu, 1 Oct 2009 16:37:08 +0000 Subject: Brought back mousewheel multicut to Ctrl-R loopcut tool that was recently added. Tweak still doesn't work for the loopcut op, but it didn't before, so at least we're advancing. --- source/blender/editors/mesh/loopcut.c | 38 ++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index d1ef4ebc233..e58025ac6ce 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -50,6 +50,7 @@ #include "BKE_blender.h" #include "BKE_context.h" +#include "BKE_depsgraph.h" #include "BKE_scene.h" #include "BKE_utildefines.h" #include "BKE_mesh.h" @@ -249,22 +250,22 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select) lcd->totedge = tot; } -static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *ar) +static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *ar, int cuts) { if (lcd->eed) - edgering_sel(lcd, 1, 0); + edgering_sel(lcd, cuts, 0); } static void ringsel_finish(bContext *C, wmOperator *op) { tringselOpData *lcd= op->customdata; + int cuts= RNA_int_get(op->ptr,"number_cuts"); if (lcd->eed) { - edgering_sel(lcd, 0, 1); + edgering_sel(lcd, cuts, 1); if (lcd->do_cut) { EditMesh *em = BKE_mesh_get_editmesh(lcd->ob->data); - esubdivideflag(lcd->ob, em, SELECT, 0.0f, - 0.0f, 0, 1, SUBDIV_SELECT_LOOPCUT); + esubdivideflag(lcd->ob, em, SELECT, 0.0f, 0.0f, 0, cuts, SUBDIV_SELECT_LOOPCUT); DAG_id_flush_update(lcd->ob->data, OB_RECALC_DATA); } @@ -340,7 +341,7 @@ static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt) edge = findnearestedge(&lcd->vc, &dist); if (edge != lcd->eed) { lcd->eed = edge; - ringsel_find_edge(lcd, C, lcd->ar); + ringsel_find_edge(lcd, C, lcd->ar, 1); } return OPERATOR_RUNNING_MODAL; @@ -368,7 +369,7 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) edge = findnearestedge(&lcd->vc, &dist); if (edge != lcd->eed) { lcd->eed = edge; - ringsel_find_edge(lcd, C, lcd->ar); + ringsel_find_edge(lcd, C, lcd->ar, 1); } return OPERATOR_RUNNING_MODAL; @@ -376,10 +377,12 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) { + int cuts= RNA_int_get(op->ptr,"number_cuts"); tringselOpData *lcd= op->customdata; view3d_operator_needs_opengl(C); + switch (event->type) { case RIGHTMOUSE: case LEFTMOUSE: /* confirm */ // XXX hardcoded @@ -393,6 +396,20 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_FINISHED; } + ED_region_tag_redraw(lcd->ar); + break; + case WHEELUPMOUSE: /* change number of cuts */ + cuts++; + RNA_int_set(op->ptr,"number_cuts",cuts); + ringsel_find_edge(lcd, C, lcd->ar, cuts); + + ED_region_tag_redraw(lcd->ar); + break; + case WHEELDOWNMOUSE: /* change number of cuts */ + cuts=MAX2(cuts-1,1); + RNA_int_set(op->ptr,"number_cuts",cuts); + ringsel_find_edge(lcd, C, lcd->ar,cuts); + ED_region_tag_redraw(lcd->ar); break; case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ @@ -405,12 +422,12 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) if (edge != lcd->eed) { lcd->eed = edge; - ringsel_find_edge(lcd, C, lcd->ar); + ringsel_find_edge(lcd, C, lcd->ar, cuts); } ED_region_tag_redraw(lcd->ar); break; - } + } } /* keep going until the user confirms */ @@ -451,4 +468,7 @@ void MESH_OT_loopcut (wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + /* properties */ + RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX); } -- cgit v1.2.3 From 022a343223be895c4dfab63af28ed0a2b822df71 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 1 Oct 2009 17:15:23 +0000 Subject: Texture stack influences are now all separate values, and negative mapped values now have their influence negated instead. Also a few RNA changes for TextureSlot. Bumped subversion for the version patch. --- release/scripts/ui/buttons_texture.py | 6 +- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/particle.c | 42 ++++---- source/blender/blenkernel/intern/particle_system.c | 7 +- source/blender/blenkernel/intern/texture.c | 30 ++++++ source/blender/blenloader/intern/readfile.c | 93 ++++++++++++++++-- source/blender/gpu/intern/gpu_material.c | 107 ++++++++++++--------- source/blender/gpu/intern/gpu_shader_material.glsl | 42 ++++---- source/blender/makesdna/DNA_material_types.h | 2 +- source/blender/makesdna/DNA_texture_types.h | 24 ++++- source/blender/makesrna/intern/rna_brush.c | 46 ++++++++- source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_lamp.c | 2 +- source/blender/makesrna/intern/rna_material.c | 44 ++++----- source/blender/makesrna/intern/rna_texture.c | 45 +-------- source/blender/makesrna/intern/rna_world.c | 6 +- .../blender/render/extern/include/RE_render_ext.h | 2 +- .../blender/render/extern/include/RE_shader_ext.h | 1 - .../blender/render/intern/source/renderdatabase.c | 10 +- source/blender/render/intern/source/texture.c | 106 ++++++++++---------- 20 files changed, 377 insertions(+), 241 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index 9765aa93ca4..6eab84afc42 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -175,14 +175,14 @@ class TEXTURE_PT_mapping(TextureSlotPanel): row.itemR(tex, "z_mapping", text="") if br: - layout.itemR(tex, "brush_map_mode", expand=True) + layout.itemR(tex, "map_mode", expand=True) row = layout.row() - row.active = tex.brush_map_mode in ('FIXED', 'TILED') + row.active = tex.map_mode in ('FIXED', 'TILED') row.itemR(tex, "angle") row = layout.row() - row.active = tex.brush_map_mode in ('TILED', '3D') + row.active = tex.map_mode in ('TILED', '3D') row.column().itemR(tex, "size") else: row = layout.row() diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index d60737d62fe..3549d3e372d 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 3 +#define BLENDER_SUBVERSION 4 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e63b77a134e..f4f5a1364a3 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2057,7 +2057,7 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float } static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec) { - float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}; + float force[3] = {0.0f,0.0f,0.0f}; ParticleKey eff_key; EffectedPoint epoint; @@ -3410,9 +3410,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float mtex=ma->mtex[m]; if(mtex && (ma->septex & (1<pmapto){ float def=mtex->def_var; - float var=mtex->varfac; short blend=mtex->blendtype; - short neg=mtex->pmaptoneg; if((mtex->texco & TEXCO_UV) && fw) { if(!get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texco)) @@ -3427,18 +3425,18 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float ptex->time=0.0; setvars|=MAP_PA_TIME; } - ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,var,blend,neg & MAP_PA_TIME); + ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,mtex->timefac,blend); } if((event & mtex->pmapto) & MAP_PA_LENGTH) - ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH); + ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend); if((event & mtex->pmapto) & MAP_PA_CLUMP) - ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP); + ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend); if((event & mtex->pmapto) & MAP_PA_KINK) - ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK); + ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend); if((event & mtex->pmapto) & MAP_PA_ROUGH) - ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,var,blend,neg & MAP_PA_ROUGH); + ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,mtex->roughfac,blend); if((event & mtex->pmapto) & MAP_PA_DENS) - ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS); + ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend); } } if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); } @@ -3462,10 +3460,8 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p if(ma) for(m=0; mmtex[m]; if(mtex && (ma->septex & (1<pmapto){ - float var=mtex->varfac; float def=mtex->def_var; short blend=mtex->blendtype; - short neg=mtex->pmaptoneg; if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) { @@ -3482,29 +3478,31 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p if((event & mtex->pmapto) & MAP_PA_TIME){ /* the first time has to set the base value for time regardless of blend mode */ if((setvars&MAP_PA_TIME)==0){ - ptex->time *= 1.0f - var; - ptex->time += var * ((neg & MAP_PA_TIME)? 1.0f - value : value); + int flip= (mtex->timefac < 0.0f); + float timefac= fabsf(mtex->timefac); + ptex->time *= 1.0f - timefac; + ptex->time += timefac * ((flip)? 1.0f - value : value); setvars |= MAP_PA_TIME; } else - ptex->time= texture_value_blend(def,ptex->time,value,var,blend,neg & MAP_PA_TIME); + ptex->time= texture_value_blend(def,ptex->time,value,mtex->timefac,blend); } if((event & mtex->pmapto) & MAP_PA_LIFE) - ptex->life= texture_value_blend(def,ptex->life,value,var,blend,neg & MAP_PA_LIFE); + ptex->life= texture_value_blend(def,ptex->life,value,mtex->lifefac,blend); if((event & mtex->pmapto) & MAP_PA_DENS) - ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS); + ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend); if((event & mtex->pmapto) & MAP_PA_SIZE) - ptex->size= texture_value_blend(def,ptex->size,value,var,blend,neg & MAP_PA_SIZE); + ptex->size= texture_value_blend(def,ptex->size,value,mtex->sizefac,blend); if((event & mtex->pmapto) & MAP_PA_IVEL) - ptex->ivel= texture_value_blend(def,ptex->ivel,value,var,blend,neg & MAP_PA_IVEL); + ptex->ivel= texture_value_blend(def,ptex->ivel,value,mtex->ivelfac,blend); if((event & mtex->pmapto) & MAP_PA_PVEL) - texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,var,blend); + texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,mtex->pvelfac,blend); if((event & mtex->pmapto) & MAP_PA_LENGTH) - ptex->length= texture_value_blend(def,ptex->length,value,var,blend,neg & MAP_PA_LENGTH); + ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend); if((event & mtex->pmapto) & MAP_PA_CLUMP) - ptex->clump= texture_value_blend(def,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP); + ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend); if((event & mtex->pmapto) & MAP_PA_KINK) - ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_CLUMP); + ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend); } } if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 77cef689d09..d757372f17b 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2217,11 +2217,12 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra) psys->tree = BLI_kdtree_new(psys->totpart); LOOP_SHOWN_PARTICLES { - if(pa->alive == PARS_ALIVE) + if(pa->alive == PARS_ALIVE) { if(pa->state.time == cfra) BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL); else BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL); + } } BLI_kdtree_balance(psys->tree); @@ -3134,7 +3135,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) ParticleSystem *psys = sim->psys; ParticleSettings *part=psys->part; KDTree *tree=0; - IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system + //IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system /* Material *ma=give_current_material(sim->ob, part->omat); */ BoidBrainData bbd; PARTICLE_P; @@ -3331,7 +3332,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system + //IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system /* Material *ma = give_current_material(sim->ob,part->omat); */ PARTICLE_P; float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 287396a85c8..3b8ae9a6c7f 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -559,6 +559,36 @@ void default_mtex(MTex *mtex) mtex->norfac= 1.0; mtex->varfac= 1.0; mtex->dispfac=0.2; + mtex->colspecfac= 1.0f; + mtex->mirrfac= 1.0f; + mtex->alphafac= 1.0f; + mtex->difffac= 1.0f; + mtex->specfac= 1.0f; + mtex->emitfac= 1.0f; + mtex->hardfac= 1.0f; + mtex->raymirrfac= 1.0f; + mtex->translfac= 1.0f; + mtex->ambfac= 1.0f; + mtex->colemitfac= 1.0f; + mtex->colreflfac= 1.0f; + mtex->coltransfac= 1.0f; + mtex->densfac= 1.0f; + mtex->scatterfac= 1.0f; + mtex->reflfac= 1.0f; + mtex->shadowfac= 1.0f; + mtex->zenupfac= 1.0f; + mtex->zendownfac= 1.0f; + mtex->blendfac= 1.0f; + mtex->timefac= 1.0f; + mtex->lengthfac= 1.0f; + mtex->clumpfac= 1.0f; + mtex->kinkfac= 1.0f; + mtex->roughfac= 1.0f; + mtex->padensfac= 1.0f; + mtex->lifefac= 1.0f; + mtex->sizefac= 1.0f; + mtex->ivelfac= 1.0f; + mtex->pvelfac= 1.0f; mtex->normapspace= MTEX_NSPACE_TANGENT; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d1da29bef70..6fce17a4892 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6186,7 +6186,70 @@ static void do_versions_gpencil_2_50(Main *main, bScreen *screen) } } +static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype) +{ + MTex *mtex; + float varfac, colfac; + int a, neg; + if(!mtex_array) + return; + + for(a=0; amaptoneg; + varfac= mtex->varfac; + colfac= mtex->colfac; + + if(neg & MAP_DISP) mtex->dispfac= -mtex->dispfac; + if(neg & MAP_NORM) mtex->norfac= -mtex->norfac; + if(neg & MAP_WARP) mtex->warpfac= -mtex->warpfac; + + mtex->colspecfac= (neg & MAP_COLSPEC)? -colfac: colfac; + mtex->mirrfac= (neg & MAP_COLMIR)? -colfac: colfac; + mtex->alphafac= (neg & MAP_ALPHA)? -varfac: varfac; + mtex->difffac= (neg & MAP_REF)? -varfac: varfac; + mtex->specfac= (neg & MAP_SPEC)? -varfac: varfac; + mtex->emitfac= (neg & MAP_EMIT)? -varfac: varfac; + mtex->hardfac= (neg & MAP_HAR)? -varfac: varfac; + mtex->raymirrfac= (neg & MAP_RAYMIRR)? -varfac: varfac; + mtex->translfac= (neg & MAP_TRANSLU)? -varfac: varfac; + mtex->ambfac= (neg & MAP_AMB)? -varfac: varfac; + mtex->colemitfac= (neg & MAP_EMISSION_COL)? -colfac: colfac; + mtex->colreflfac= (neg & MAP_REFLECTION_COL)? -colfac: colfac; + mtex->coltransfac= (neg & MAP_TRANSMISSION_COL)? -colfac: colfac; + mtex->densfac= (neg & MAP_DENSITY)? -varfac: varfac; + mtex->scatterfac= (neg & MAP_SCATTERING)? -varfac: varfac; + mtex->reflfac= (neg & MAP_REFLECTION)? -varfac: varfac; + + mtex->timefac= (neg & MAP_PA_TIME)? -varfac: varfac; + mtex->lengthfac= (neg & MAP_PA_LENGTH)? -varfac: varfac; + mtex->clumpfac= (neg & MAP_PA_CLUMP)? -varfac: varfac; + mtex->kinkfac= (neg & MAP_PA_KINK)? -varfac: varfac; + mtex->roughfac= (neg & MAP_PA_ROUGH)? -varfac: varfac; + mtex->padensfac= (neg & MAP_PA_DENS)? -varfac: varfac; + mtex->lifefac= (neg & MAP_PA_LIFE)? -varfac: varfac; + mtex->sizefac= (neg & MAP_PA_SIZE)? -varfac: varfac; + mtex->ivelfac= (neg & MAP_PA_IVEL)? -varfac: varfac; + mtex->pvelfac= (neg & MAP_PA_PVEL)? -varfac: varfac; + + mtex->shadowfac= (neg & LAMAP_SHAD)? -colfac: colfac; + + mtex->zenupfac= (neg & WOMAP_ZENUP)? -colfac: colfac; + mtex->zendownfac= (neg & WOMAP_ZENDOWN)? -colfac: colfac; + mtex->blendfac= (neg & WOMAP_BLEND)? -varfac: varfac; + + if(idtype == ID_MA) + mtex->colfac= (neg & MAP_COL)? -colfac: colfac; + else if(idtype == ID_LA) + mtex->colfac= (neg & LAMAP_COL)? -colfac: colfac; + else if(idtype == ID_WO) + mtex->colfac= (neg & WOMAP_HORIZ)? -colfac: colfac; + } + } +} static void do_versions(FileData *fd, Library *lib, Main *main) { @@ -9728,11 +9791,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - /* put 2.50 compatibility code here until next subversion bump */ - { + if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) { Scene *sce; Object *ob; Material *ma; + Lamp *la; + World *wo; Tex *tex; ParticleSettings *part; int do_gravity = 0; @@ -9750,19 +9814,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ob->rotmode= ROT_MODE_EUL; } - for (ma = main->mat.first; ma; ma=ma->id.next) { - if (ma->vol.reflection == 0.f) { + for(ma = main->mat.first; ma; ma=ma->id.next) { + if(ma->vol.reflection == 0.f) { ma->vol.reflection = 1.f; ma->vol.transmission_col[0] = ma->vol.transmission_col[1] = ma->vol.transmission_col[2] = 1.0f; ma->vol.reflection_col[0] = ma->vol.reflection_col[1] = ma->vol.reflection_col[2] = 1.0f; } - } - for (tex = main->tex.first; tex; tex=tex->id.next) { - if (tex->vd) { - if (tex->vd->extend == 0) tex->vd->extend = TEX_CLIP; - } + do_version_mtex_factor_2_50(ma->mtex, ID_MA); } + + for(la = main->lamp.first; la; la=la->id.next) + do_version_mtex_factor_2_50(la->mtex, ID_LA); + + for(wo = main->world.first; wo; wo=wo->id.next) + do_version_mtex_factor_2_50(wo->mtex, ID_WO); + + for(tex = main->tex.first; tex; tex=tex->id.next) + if(tex->vd) + if(tex->vd->extend == 0) + tex->vd->extend = TEX_CLIP; for(sce= main->scene.first; sce; sce= sce->id.next) { @@ -9819,6 +9890,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* put 2.50 compatibility code here until next subversion bump */ + { + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index c0fb069fc41..d01266c8765 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -846,37 +846,35 @@ static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *o } } -static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, int flip, GPUNodeLink **in) +static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in) { - float flipf = (flip)? 1.0f: 0.0; - switch(blendtype) { case MTEX_BLEND: - GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in); break; case MTEX_MUL: - GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in); break; case MTEX_SCREEN: - GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in); break; case MTEX_SUB: - GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in); break; case MTEX_ADD: - GPU_link(mat, "mtex_value_add", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in); break; case MTEX_DIV: - GPU_link(mat, "mtex_value_div", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in); break; case MTEX_DIFF: - GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in); break; case MTEX_DARK: - GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in); break; case MTEX_LIGHT: - GPU_link(mat, "mtex_value_light", out, tex, fact, facg, GPU_uniform(&flipf), in); + GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in); break; default: GPU_link(mat, "set_value_zero", &in); @@ -893,7 +891,7 @@ static void do_material_tex(GPUShadeInput *shi) GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac; GPUNodeLink *texco_norm, *texco_orco, *texco_object, *texco_tangent; GPUNodeLink *texco_global, *texco_uv = NULL; - GPUNodeLink *colfac, *newnor, *varfac, *orn; + GPUNodeLink *newnor, *orn; char *lastuvname = NULL; float one = 1.0f, norfac, ofs[3]; int tex_nr, rgbnor, talpha; @@ -993,11 +991,6 @@ static void do_material_tex(GPUShadeInput *shi) /* mapping */ if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) { /* stencil maps on the texture control slider, not texture intensity value */ - if(mtex->colfac == 1.0f) - colfac = stencil; - else - GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac); - if((rgbnor & TEX_RGB)==0) { GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol); } @@ -1012,21 +1005,30 @@ static void do_material_tex(GPUShadeInput *shi) GPU_link(mat, "set_value_one", &tin); } - if(mtex->mapto & MAP_COL) + if(mtex->mapto & MAP_COL) { + GPUNodeLink *colfac; + + if(mtex->colfac == 1.0f) colfac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac); + texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb); + } - if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) - texture_rgb_blend(mat, tcol, shi->specrgb, tin, colfac, mtex->blendtype, &shi->specrgb); + if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) { + GPUNodeLink *colspecfac; + + if(mtex->colspecfac == 1.0f) colspecfac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac); + + texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb); + } } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) { - if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; - else tex->norfac= mtex->norfac; - if((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) { tex->norfac = mtex->norfac; - if(mtex->maptoneg & MAP_NORM) + if(tex->norfac < 0.0f) GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); if(mtex->normapspace == MTEX_NSPACE_TANGENT) @@ -1034,7 +1036,7 @@ static void do_material_tex(GPUShadeInput *shi) else newnor = tnor; - norfac = MIN2(mtex->norfac, 1.0); + norfac = MIN2(fabsf(mtex->norfac), 1.0); if(norfac == 1.0f && !GPU_link_changed(stencil)) { shi->vn = newnor; } @@ -1053,11 +1055,6 @@ static void do_material_tex(GPUShadeInput *shi) } if((mtex->mapto & MAP_VARS)) { - if(mtex->varfac == 1.0f) - varfac = stencil; - else - GPU_link(mat, "math_multiply", GPU_uniform(&mtex->varfac), stencil, &varfac); - if(rgbnor & TEX_RGB) { if(talpha) GPU_link(mat, "mtex_alpha_from_col", trgb, &tin); @@ -1066,34 +1063,58 @@ static void do_material_tex(GPUShadeInput *shi) } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) { - int flip= mtex->maptoneg & MAP_REF; - texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, varfac, mtex->blendtype, flip, &shi->refl); + GPUNodeLink *difffac; + + if(mtex->difffac == 1.0f) difffac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac); + + texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl); GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl); } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) { - int flip= mtex->maptoneg & MAP_SPEC; - texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, varfac, mtex->blendtype, flip, &shi->spec); + GPUNodeLink *specfac; + + if(mtex->specfac == 1.0f) specfac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac); + + texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec); GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec); } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) { - int flip= mtex->maptoneg & MAP_EMIT; - texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, varfac, mtex->blendtype, flip, &shi->emit); + GPUNodeLink *emitfac; + + if(mtex->emitfac == 1.0f) emitfac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac); + + texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit); GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit); } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) { - int flip= mtex->maptoneg & MAP_HAR; + GPUNodeLink *hardfac; + + if(mtex->hardfac == 1.0f) hardfac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac); + GPU_link(mat, "mtex_har_divide", shi->har, &shi->har); - texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, varfac, mtex->blendtype, flip, &shi->har); + texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har); GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har); } if(mtex->mapto & MAP_ALPHA) { - int flip= mtex->maptoneg & MAP_ALPHA; - texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, varfac, mtex->blendtype, flip, &shi->alpha); + GPUNodeLink *alphafac; + + if(mtex->alphafac == 1.0f) alphafac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac); + + texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha); GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha); } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) { - int flip= mtex->maptoneg & MAP_AMB; - texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, varfac, mtex->blendtype, flip, &shi->amb); + GPUNodeLink *ambfac; + + if(mtex->ambfac == 1.0f) ambfac = stencil; + else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac); + + texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb); GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb); } } diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl b/source/blender/gpu/intern/gpu_shader_material.glsl index 16ed38cb47d..0d7e00a541b 100644 --- a/source/blender/gpu/intern/gpu_shader_material.glsl +++ b/source/blender/gpu/intern/gpu_shader_material.glsl @@ -847,66 +847,66 @@ void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 i incol.rgb = col.rgb; } -void mtex_value_vars(inout float fact, float facg, out float facm, float flip) +void mtex_value_vars(inout float fact, float facg, out float facm) { - fact *= facg; + fact *= abs(facg); facm = 1.0-fact; - if(flip != 0.0) { + if(facg < 0.0) { float tmp = fact; fact = facm; facm = tmp; } } -void mtex_value_blend(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); incol = fact*texcol + facm*outcol; } -void mtex_value_mul(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); facm = 1.0 - facg; incol = (facm + fact*texcol)*outcol; } -void mtex_value_screen(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); facm = 1.0 - facg; incol = 1.0 - (facm + fact*(1.0 - texcol))*(1.0 - outcol); } -void mtex_value_sub(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); fact = -fact; incol = fact*texcol + outcol; } -void mtex_value_add(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); fact = fact; incol = fact*texcol + outcol; } -void mtex_value_div(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); if(texcol != 0.0) incol = facm*outcol + fact*outcol/texcol; @@ -914,27 +914,27 @@ void mtex_value_div(float outcol, float texcol, float fact, float facg, float fl incol = 0.0; } -void mtex_value_diff(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); incol = facm*outcol + fact*abs(texcol - outcol); } -void mtex_value_dark(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); float col = fact*texcol; if(col < outcol) incol = col; else incol = outcol; } -void mtex_value_light(float outcol, float texcol, float fact, float facg, float flip, out float incol) +void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol) { float facm; - mtex_value_vars(fact, facg, facm, flip); + mtex_value_vars(fact, facg, facm); float col = fact*texcol; if(col > outcol) incol = col; else incol = outcol; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index b3a7e74e91d..a925b60ac33 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -313,7 +313,7 @@ typedef struct Material { #define MAP_AMB 2048 #define MAP_DISPLACE 4096 #define MAP_WARP 8192 -#define MAP_LAYER 16384 +#define MAP_LAYER 16384 /* unused */ /* volume mapto - reuse definitions for now - a bit naughty! */ #define MAP_DENSITY 128 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index c8f35b4306f..a43e5c7ae13 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -61,9 +61,27 @@ typedef struct MTex { float r, g, b, k; float def_var, rt; - float colfac, norfac, varfac; - float dispfac; - float warpfac; + /* common */ + float colfac, varfac; + + /* material */ + float norfac, dispfac, warpfac; + float colspecfac, mirrfac, alphafac; + float difffac, specfac, emitfac, hardfac; + float raymirrfac, translfac, ambfac; + float colemitfac, colreflfac, coltransfac; + float densfac, scatterfac, reflfac; + + /* particles */ + float timefac, lengthfac, clumpfac; + float kinkfac, roughfac, padensfac; + float lifefac, sizefac, ivelfac, pvelfac; + + /* lamp */ + float shadowfac; + + /* world */ + float zenupfac, zendownfac, blendfac; } MTex; #ifndef DNA_USHORT_FIX diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index d5195110314..e87c8434a7d 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -96,8 +96,51 @@ static void rna_Brush_update(bContext *C, PointerRNA *ptr) WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, br); } +static float rna_BrushTextureSlot_angle_get(PointerRNA *ptr) +{ + MTex *tex= (MTex*)ptr->data; + const float conv = 57.295779506; + return tex->rot * conv; +} + +static void rna_BrushTextureSlot_angle_set(PointerRNA *ptr, float v) +{ + MTex *tex= (MTex*)ptr->data; + const float conv = 0.017453293; + tex->rot = v * conv; +} + #else +static void rna_def_brush_texture_slot(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem prop_map_mode_items[] = { + {MTEX_MAP_MODE_FIXED, "FIXED", 0, "Fixed", ""}, + {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, + {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "BrushTextureSlot", "TextureSlot"); + RNA_def_struct_sdna(srna, "MTex"); + RNA_def_struct_ui_text(srna, "Brush Texture Slot", "Texture slot for textures in a Brush datablock."); + + prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "rot"); + RNA_def_property_range(prop, 0, 360); + RNA_def_property_float_funcs(prop, "rna_BrushTextureSlot_angle_get", "rna_BrushTextureSlot_angle_set", NULL); + RNA_def_property_ui_text(prop, "Angle", "Defines brush texture rotation."); + RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); + + prop= RNA_def_property(srna, "map_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode"); + RNA_def_property_enum_items(prop, prop_map_mode_items); + RNA_def_property_ui_text(prop, "Mode", ""); + RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); +} + static void rna_def_brush(BlenderRNA *brna) { StructRNA *srna; @@ -258,7 +301,7 @@ static void rna_def_brush(BlenderRNA *brna) /* texture */ rna_def_mtex_common(srna, "rna_Brush_mtex_begin", "rna_Brush_active_texture_get", - "rna_Brush_active_texture_set", "TextureSlot", "rna_Brush_update"); + "rna_Brush_active_texture_set", "BrushTextureSlot", "rna_Brush_update"); /* clone tool */ prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE); @@ -329,6 +372,7 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna) void RNA_def_brush(BlenderRNA *brna) { rna_def_brush(brna); + rna_def_brush_texture_slot(brna); rna_def_operator_stroke_element(brna); } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 8e50ffe7b94..1ebf03425d4 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -197,6 +197,7 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, ch void rna_Object_update(struct bContext *C, struct PointerRNA *ptr); void rna_Object_update_data(struct bContext *C, struct PointerRNA *ptr); void rna_Mesh_update_draw(struct bContext *C, struct PointerRNA *ptr); +void rna_TextureSlot_update(struct bContext *C, struct PointerRNA *ptr); /* API functions */ diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index df04fe87bc5..4315a118c84 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -185,7 +185,7 @@ static void rna_def_lamp_mtex(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Lamp_update"); prop= RNA_def_property(srna, "shadow_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "shadowfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Shadow Factor", "Amount texture affects shadow."); RNA_def_property_update(prop, 0, "rna_Lamp_update"); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 9b9fbb350a1..661b1c5e1c3 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -444,17 +444,17 @@ static void rna_def_material_mtex(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Mapping", ""); RNA_def_property_update(prop, 0, "rna_Material_update"); - /* XXX: pmapto, pmaptoneg */ - prop= RNA_def_property(srna, "normal_map_space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "normapspace"); RNA_def_property_enum_items(prop, prop_normal_map_space_items); RNA_def_property_ui_text(prop, "Normal Map Space", ""); RNA_def_property_update(prop, 0, "rna_Material_update"); - /* XXX: MTex.which_output */ - - /* XXX: MTex.k */ + prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "norfac"); + RNA_def_property_ui_range(prop, 0, 5, 10, 3); + RNA_def_property_ui_text(prop, "Normal Factor", "Amount texture affects normal values."); + RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "displacement_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "dispfac"); @@ -469,7 +469,7 @@ static void rna_def_material_mtex(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "colorspec_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "colspecfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Specular Color Factor", "Amount texture affects specular color."); RNA_def_property_update(prop, 0, "rna_Material_update"); @@ -481,55 +481,55 @@ static void rna_def_material_mtex(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "mirror_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "mirrfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Mirror Factor", "Amount texture affects mirror color."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "alpha_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "alphafac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Alpha Factor", "Amount texture affects alpha."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "diffuse_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "difffac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Diffuse Factor", "Amount texture affects diffuse reflectivity."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "specular_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "specfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Specular Factor", "Amount texture affects specular reflectivity."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "emit_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "emitfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Emit Factor", "Amount texture affects emission."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "hardness_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "hardfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Hardness Factor", "Amount texture affects hardness."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "raymir_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "raymirrfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Ray Mirror Factor", "Amount texture affects ray mirror."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "translucency_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "translfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Translucency Factor", "Amount texture affects translucency."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "ambient_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "ambfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Ambient Factor", "Amount texture affects ambient."); RNA_def_property_update(prop, 0, "rna_Material_update"); @@ -571,43 +571,43 @@ static void rna_def_material_mtex(BlenderRNA *brna) RNA_def_property_update(prop, NC_TEXTURE, NULL); prop= RNA_def_property(srna, "coloremission_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "colemitfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Emission Color Factor", "Amount texture affects emission color."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "colorreflection_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "colreflfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Reflection Color Factor", "Amount texture affects color of out-scattered light"); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "colortransmission_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "coltransfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Transmission Color Factor", "Amount texture affects result color after light has been scattered/absorbed."); RNA_def_property_update(prop, NC_TEXTURE, NULL); prop= RNA_def_property(srna, "density_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "densfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Density Factor", "Amount texture affects density."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "emission_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "emitfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Emission Factor", "Amount texture affects emission."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "scattering_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "scatterfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Scattering Factor", "Amount texture affects scattering."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "reflection_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "reflfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Reflection Factor", "Amount texture affects brightness of out-scattered light."); RNA_def_property_update(prop, 0, "rna_Material_update"); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 7bc8570ce13..5c7a097a54d 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -124,7 +124,7 @@ static void rna_Texture_type_set(PointerRNA *ptr, int value) tex->type = value; } -static void rna_TextureSlot_update(bContext *C, PointerRNA *ptr) +void rna_TextureSlot_update(bContext *C, PointerRNA *ptr) { ID *id= ptr->id.data; @@ -276,20 +276,6 @@ static EnumPropertyItem *rna_ImageTexture_filter_itemf(bContext *C, PointerRNA * return item; } -static float rna_TextureSlot_angle_get(PointerRNA *ptr) -{ - MTex *tex= (MTex*)ptr->data; - const float conv = 57.295779506; - return tex->rot * conv; -} - -static void rna_TextureSlot_angle_set(PointerRNA *ptr, float v) -{ - MTex *tex= (MTex*)ptr->data; - const float conv = 0.017453293; - tex->rot = v * conv; -} - #else static void rna_def_color_ramp_element(BlenderRNA *brna) @@ -412,12 +398,6 @@ static void rna_def_mtex(BlenderRNA *brna) {MTEX_LIN_LIGHT , "LINEAR LIGHT", 0, "Linear Light", ""}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem prop_map_mode_items[] = { - {MTEX_MAP_MODE_FIXED, "FIXED", 0, "Fixed", ""}, - {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, - {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem output_node_items[] = { {0, "DUMMY", 0, "Dummy", ""}, {0, NULL, 0, NULL, NULL}}; @@ -480,35 +460,12 @@ static void rna_def_mtex(BlenderRNA *brna) RNA_def_property_ui_text(prop, "RGB to Intensity", "Converts texture RGB values to intensity (gray) values."); RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); - prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); - RNA_def_property_float_sdna(prop, NULL, "rot"); - RNA_def_property_range(prop, 0, 360); - RNA_def_property_float_funcs(prop, "rna_TextureSlot_angle_get", "rna_TextureSlot_angle_set", NULL); - RNA_def_property_ui_text(prop, "Angle", "Defines brush texture rotation."); - RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); - - prop= RNA_def_property(srna, "brush_map_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_map_mode_items); - RNA_def_property_ui_text(prop, "Mode", ""); - prop= RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "def_var"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Default Value", "Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard."); RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); - prop= RNA_def_property(srna, "variable_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); - RNA_def_property_ui_range(prop, 0, 1, 10, 3); - RNA_def_property_ui_text(prop, "Variable Factor", "Amount texture affects other values."); - RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); - - prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "norfac"); - RNA_def_property_ui_range(prop, 0, 5, 10, 3); - RNA_def_property_ui_text(prop, "Normal Factor", "Amount texture affects normal values."); - RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); - prop= RNA_def_property(srna, "output_node", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "which_output"); RNA_def_property_enum_items(prop, output_node_items); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 0cbbe28967f..b2ed90eef03 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -174,7 +174,7 @@ static void rna_def_world_mtex(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_World_update"); prop= RNA_def_property(srna, "blend_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "varfac"); + RNA_def_property_float_sdna(prop, NULL, "blendfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Blend Factor", "Amount texture affects color progression of the background."); RNA_def_property_update(prop, 0, "rna_World_update"); @@ -186,13 +186,13 @@ static void rna_def_world_mtex(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_World_update"); prop= RNA_def_property(srna, "zenith_up_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "zenupfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Zenith Up Factor", "Amount texture affects color of the zenith above."); RNA_def_property_update(prop, 0, "rna_World_update"); prop= RNA_def_property(srna, "zenith_down_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "colfac"); + RNA_def_property_float_sdna(prop, NULL, "zendownfac"); RNA_def_property_ui_range(prop, 0, 1, 10, 3); RNA_def_property_ui_text(prop, "Zenith Down Factor", "Amount texture affects color of the zenith below."); RNA_def_property_update(prop, 0, "rna_World_update"); diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 15b59f2c8cc..069861df992 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -55,7 +55,7 @@ int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, f /* particle.c */ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype); -float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip); +float texture_value_blend(float tex, float out, float fact, float facg, int blendtype); /* node_composite.c */ void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result); diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 435e3ddc07f..134be189e8f 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -128,7 +128,6 @@ typedef struct ShadeInput /* individual copies: */ int har; /* hardness */ - float layerfac; /* texture coordinates */ float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[4]; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 621831fb341..30832db5c7d 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1024,7 +1024,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta); yn= tin*mtex->colfac; - zn= tin*mtex->varfac; + zn= tin*mtex->alphafac; if(mtex->mapto & MAP_COL) { zn= 1.0-yn; @@ -1156,7 +1156,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta); //yn= tin*mtex->colfac; - //zn= tin*mtex->varfac; + //zn= tin*mtex->alphafac; if(mtex->mapto & MAP_COL) { tex[0]=tr; tex[1]=tg; @@ -1175,11 +1175,11 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater har->b= in[2]; } if(mtex->mapto & MAP_ALPHA) - har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_ALPHA); + har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->alphafac,mtex->blendtype); if(mtex->mapto & MAP_HAR) - har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_HAR); + har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->hardfac,mtex->blendtype); if(mtex->mapto & MAP_RAYMIRR) - har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_RAYMIRR); + har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->raymirrfac,mtex->blendtype); /* now what on earth is this good for?? */ //if(mtex->texco & 16) { // har->alfa= tin; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 02b7f6aad86..7b0e5d8abbc 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1468,9 +1468,12 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg } } -float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip) +float texture_value_blend(float tex, float out, float fact, float facg, int blendtype) { float in=0.0, facm, col, scf; + int flip= (facg < 0.0f); + + facg= fabsf(facg); fact*= facg; facm= 1.0-fact; @@ -1813,7 +1816,7 @@ void do_material_tex(ShadeInput *shi) TexResult ttexr = {0, 0, 0, 0, 0, texres.talpha, NULL}; // temp TexResult float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0)); - const float bf = 0.04f*Tnor*((mtex->maptoneg & MAP_NORM) ? -mtex->norfac : mtex->norfac); + const float bf = 0.04f*Tnor*mtex->norfac; // disable internal bump eval float* nvec = texres.nor; texres.nor = NULL; @@ -2020,10 +2023,9 @@ void do_material_tex(ShadeInput *shi) /* mapping */ if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { - float tcol[3], colfac; + float tcol[3]; /* stencil maps on the texture control slider, not texture intensity value */ - colfac= mtex->colfac*stencilTin; tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb; @@ -2043,15 +2045,19 @@ void do_material_tex(ShadeInput *shi) } if(mtex->mapto & MAP_COL) { + float colfac= mtex->colfac*stencilTin; texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype); } if(mtex->mapto & MAP_COLSPEC) { - texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colfac, mtex->blendtype); + float colspecfac= mtex->colspecfac*stencilTin; + texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype); } if(mtex->mapto & MAP_COLMIR) { + float mirrfac= mtex->mirrfac*stencilTin; + // exception for envmap only if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) { - fact= texres.tin*colfac; + fact= texres.tin*mirrfac; facm= 1.0- fact; shi->refcol[0]= fact + facm*shi->refcol[0]; shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1]; @@ -2059,14 +2065,13 @@ void do_material_tex(ShadeInput *shi) shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3]; } else { - texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, colfac, mtex->blendtype); + texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype); } } } if( (mtex->mapto & MAP_NORM) ) { if(texres.nor) { - if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; - else tex->norfac= mtex->norfac; + tex->norfac= mtex->norfac; /* we need to code blending modes for normals too once.. now 1 exception hardcoded */ @@ -2074,7 +2079,7 @@ void do_material_tex(ShadeInput *shi) /* qdn: for normalmaps, to invert the normalmap vector, it is better to negate x & y instead of subtracting the vector as was done before */ tex->norfac = mtex->norfac; - if (mtex->maptoneg & MAP_NORM) { + if (tex->norfac < 0.0f) { texres.nor[0] = -texres.nor[0]; texres.nor[1] = -texres.nor[1]; } @@ -2159,8 +2164,7 @@ void do_material_tex(ShadeInput *shi) /* Now that most textures offer both Nor and Intensity, allow */ /* both to work, and let user select with slider. */ if(texres.nor) { - if(mtex->maptoneg & MAP_DISPLACE) tex->norfac= -mtex->norfac; - else tex->norfac= mtex->norfac; + tex->norfac= mtex->norfac; shi->displace[0]+= 0.2f*Tnor*tex->norfac*texres.nor[0]; shi->displace[1]+= 0.2f*Tnor*tex->norfac*texres.nor[1]; @@ -2172,12 +2176,7 @@ void do_material_tex(ShadeInput *shi) else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); } - if(mtex->maptoneg & MAP_DISPLACE) { - factt= (texres.tin-0.5f)*mtex->dispfac*stencilTin; facmm= 1.0f-factt; - } - else { - factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt; - } + factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt; if(mtex->blendtype==MTEX_BLEND) { shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0]; @@ -2200,7 +2199,6 @@ void do_material_tex(ShadeInput *shi) if(mtex->mapto & MAP_VARS) { /* stencil maps on the texture control slider, not texture intensity value */ - float varfac= mtex->varfac*stencilTin; if(rgbnor & TEX_RGB) { if(texres.talpha) texres.tin= texres.ta; @@ -2208,66 +2206,59 @@ void do_material_tex(ShadeInput *shi) } if(mtex->mapto & MAP_REF) { - int flip= mtex->maptoneg & MAP_REF; + float difffac= mtex->difffac*stencilTin; - shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, varfac, mtex->blendtype, flip); + shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype); if(shi->refl<0.0) shi->refl= 0.0; } if(mtex->mapto & MAP_SPEC) { - int flip= mtex->maptoneg & MAP_SPEC; + float specfac= mtex->specfac*stencilTin; - shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, varfac, mtex->blendtype, flip); + shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype); if(shi->spec<0.0) shi->spec= 0.0; } if(mtex->mapto & MAP_EMIT) { - int flip= mtex->maptoneg & MAP_EMIT; + float emitfac= mtex->emitfac*stencilTin; - shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, varfac, mtex->blendtype, flip); + shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype); if(shi->emit<0.0) shi->emit= 0.0; } if(mtex->mapto & MAP_ALPHA) { - int flip= mtex->maptoneg & MAP_ALPHA; + float alphafac= mtex->alphafac*stencilTin; - shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, varfac, mtex->blendtype, flip); + shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype); if(shi->alpha<0.0) shi->alpha= 0.0; else if(shi->alpha>1.0) shi->alpha= 1.0; } if(mtex->mapto & MAP_HAR) { - int flip= mtex->maptoneg & MAP_HAR; float har; // have to map to 0-1 + float hardfac= mtex->hardfac*stencilTin; har= ((float)shi->har)/128.0; - har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, varfac, mtex->blendtype, flip); + har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype); if(har<1.0) shi->har= 1; else if(har>511.0) shi->har= 511; else shi->har= (int)har; } if(mtex->mapto & MAP_RAYMIRR) { - int flip= mtex->maptoneg & MAP_RAYMIRR; + float raymirrfac= mtex->raymirrfac*stencilTin; - shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, varfac, mtex->blendtype, flip); + shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype); if(shi->ray_mirror<0.0) shi->ray_mirror= 0.0; else if(shi->ray_mirror>1.0) shi->ray_mirror= 1.0; } if(mtex->mapto & MAP_TRANSLU) { - int flip= mtex->maptoneg & MAP_TRANSLU; + float translfac= mtex->translfac*stencilTin; - shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, varfac, mtex->blendtype, flip); + shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype); if(shi->translucency<0.0) shi->translucency= 0.0; else if(shi->translucency>1.0) shi->translucency= 1.0; } - if(mtex->mapto & MAP_LAYER) { - int flip= mtex->maptoneg & MAP_LAYER; - - shi->layerfac= texture_value_blend(mtex->def_var, shi->layerfac, texres.tin, varfac, mtex->blendtype, flip); - if(shi->layerfac<0.0) shi->layerfac= 0.0; - else if(shi->layerfac>1.0) shi->layerfac= 1.0; - } if(mtex->mapto & MAP_AMB) { - int flip= mtex->maptoneg & MAP_AMB; + float ambfac= mtex->ambfac*stencilTin; - shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, varfac, mtex->blendtype, flip); + shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype); if(shi->amb<0.0) shi->amb= 0.0; else if(shi->amb>1.0) shi->amb= 1.0; @@ -2386,10 +2377,9 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) { - float tcol[3], colfac; + float tcol[3]; /* stencil maps on the texture control slider, not texture intensity value */ - colfac= mtex->colfac*stencilTin; if((rgbnor & TEX_RGB)==0) { tcol[0]= mtex->r; @@ -2410,21 +2400,23 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa /* used for emit */ if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) { - texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype); + float colemitfac= mtex->colemitfac*stencilTin; + texture_rgb_blend(col, tcol, col, texres.tin, colemitfac, mtex->blendtype); } if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) { - texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype); + float colreflfac= mtex->colreflfac*stencilTin; + texture_rgb_blend(col, tcol, col, texres.tin, colreflfac, mtex->blendtype); } if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) { - texture_rgb_blend(col, tcol, col, texres.tin, colfac, mtex->blendtype); + float coltransfac= mtex->coltransfac*stencilTin; + texture_rgb_blend(col, tcol, col, texres.tin, coltransfac, mtex->blendtype); } } if((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) { /* stencil maps on the texture control slider, not texture intensity value */ - float varfac= mtex->varfac*stencilTin; /* convert RGB to intensity if intensity info isn't provided */ if (!(rgbnor & TEX_INT)) { @@ -2435,27 +2427,27 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa } if((mapto_flag & MAP_EMISSION) && (mtex->mapto & MAP_EMISSION)) { - int flip= mtex->maptoneg & MAP_EMISSION; + float emitfac= mtex->emitfac*stencilTin; - *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip); + *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype); if(*val<0.0) *val= 0.0; } if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) { - int flip= mtex->maptoneg & MAP_DENSITY; + float densfac= mtex->densfac*stencilTin; - *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip); + *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype); CLAMP(*val, 0.0, 1.0); } if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) { - int flip= mtex->maptoneg & MAP_SCATTERING; + float scatterfac= mtex->scatterfac*stencilTin; - *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip); + *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype); CLAMP(*val, 0.0, 1.0); } if((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) { - int flip= mtex->maptoneg & MAP_REFLECTION; + float reflfac= mtex->reflfac*stencilTin; - *val = texture_value_blend(mtex->def_var, *val, texres.tin, varfac, mtex->blendtype, flip); + *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype); CLAMP(*val, 0.0, 1.0); } } @@ -2770,7 +2762,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f if(mtex->mapto & WOMAP_BLEND) { if(rgb) texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); - *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->varfac, mtex->blendtype, 0); + *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype); } } } -- cgit v1.2.3 From 606e609f5d14d7bb5b2b1e75513bd6f9ed751480 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 1 Oct 2009 17:24:24 +0000 Subject: Fix cmake compilation on Windows, adding pthread includes, patch by Guillaume, thanks! --- source/blender/blenpluginapi/CMakeLists.txt | 4 ++++ source/blender/makesrna/intern/CMakeLists.txt | 4 ++++ source/blender/nodes/CMakeLists.txt | 4 ++++ source/blender/render/CMakeLists.txt | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/source/blender/blenpluginapi/CMakeLists.txt b/source/blender/blenpluginapi/CMakeLists.txt index 1c5e2697c01..e6087a001f8 100644 --- a/source/blender/blenpluginapi/CMakeLists.txt +++ b/source/blender/blenpluginapi/CMakeLists.txt @@ -30,6 +30,10 @@ SET(INC . .. ../../../intern/guardedalloc ../blenlib ../imbuf ../makesdna ) +IF(WIN32) + SET(INC ${INC} ${PTHREADS_INC}) +ENDIF(WIN32) + IF(WITH_QUICKTIME) SET(INC ${INC} ${QUICKTIME_INC}) ADD_DEFINITIONS(-DWITH_QUICKTIME) diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 50cf0b00b84..c9c02fbecde 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -42,6 +42,10 @@ SET(SRC INCLUDE_DIRECTORIES(../../../../intern/guardedalloc .. ../../makesdna ../../blenkernel ../../blenlib ../../ikplugin ../../windowmanager ../../editors/include ../../imbuf ../../render/extern/include .) FILE(GLOB INC_FILES ../*.h ../../makesdna/*.h) +IF(WIN32) + SET(INC ${INC} ${PTHREADS_INC}) +ENDIF(WIN32) + IF(WITH_GAMEENGINE) ADD_DEFINITIONS(-DGAMEBLENDER) ENDIF(WITH_GAMEENGINE) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index df2567142ca..58bee7e3acf 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -34,6 +34,10 @@ SET(INC ${ZLIB_INC} ) +IF(WIN32) + SET(INC ${INC} ${PTHREADS_INC}) +ENDIF(WIN32) + IF(WITH_OPENEXR) ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 3284f7ea79a..b30bc4936a5 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -34,6 +34,10 @@ SET(INC ../makesrna ) +IF(WIN32) + SET(INC ${INC} ${PTHREADS_INC}) +ENDIF(WIN32) + IF(WITH_OPENEXR) ADD_DEFINITIONS(-DWITH_OPENEXR) ENDIF(WITH_OPENEXR) -- cgit v1.2.3 From 57cf7d2d4a5b90efedf285f7d2782ed951b021cd Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 1 Oct 2009 18:00:00 +0000 Subject: Bug fix Snapping: transform snap in editmode couldn't snap to data in the same mesh. --- source/blender/editors/transform/transform_snap.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 9438581409b..84dc9e69e7a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -539,7 +539,6 @@ void CalcSnapGeometry(TransInfo *t, float *vec) float no[3]; int found = 0; int dist = SNAP_MIN_DISTANCE; // Use a user defined value here - SnapMode mode; if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME) { @@ -634,16 +633,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) } else { - if (t->obedit == NULL) - { - mode = SNAP_NOT_SELECTED; - } - else - { - mode = SNAP_NOT_OBEDIT; - } - - found = snapObjectsTransform(t, t->mval, &dist, loc, no, mode); + found = snapObjectsTransform(t, t->mval, &dist, loc, no, t->tsnap.mode); } if (found == 1) -- cgit v1.2.3 From 8da55763b541075dae4b1f7713c43af2b609e332 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Thu, 1 Oct 2009 18:30:59 +0000 Subject: *Updated UI options and added UI options to: control whether instances are used or not control whether vertexs are stored localy or not *Removed unsused code --- release/scripts/ui/buttons_scene.py | 7 +- source/blender/makesdna/DNA_scene_types.h | 27 ++- source/blender/makesrna/intern/rna_scene.c | 14 +- source/blender/render/SConscript | 4 +- source/blender/render/extern/include/RE_raytrace.h | 4 +- .../blender/render/intern/raytrace/rayobject.cpp | 10 +- .../render/intern/raytrace/rayobject_bih.cpp | 248 --------------------- .../render/intern/raytrace/rayobject_bvh.cpp | 233 ------------------- .../render/intern/raytrace/rayobject_qbvh.cpp | 31 +-- .../render/intern/raytrace/rayobject_svbvh.cpp | 38 +++- .../render/intern/raytrace/rayobject_vbvh.cpp | 44 +++- .../render/intern/source/rayobject_blibvh.c | 15 +- .../render/intern/source/rayobject_octree.c | 17 +- source/blender/render/intern/source/rayshade.c | 46 ++-- 14 files changed, 169 insertions(+), 569 deletions(-) delete mode 100644 source/blender/render/intern/raytrace/rayobject_bih.cpp delete mode 100644 source/blender/render/intern/raytrace/rayobject_bvh.cpp diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 88947aac86c..10a0efae33d 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -171,8 +171,11 @@ class SCENE_PT_performance(RenderButtonsPanel): sub.itemR(rd, "free_image_textures") sub = col.column() sub.active = rd.render_raytracing - sub.itemL(text="Ray Tracing Octree:") - sub.itemR(rd, "octree_resolution", text="") + sub.itemL(text="Acceleration structure:") + sub.itemR(rd, "raytrace_structure", text="") + sub.itemR(rd, "use_instances", text="Instance support") + sub.itemR(rd, "use_local_coords", text="Local coords") + sub.itemR(rd, "octree_resolution", text="Octree resolution") class SCENE_PT_post_processing(RenderButtonsPanel): __label__ = "Post Processing" diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 09e9f599d03..27ee5d47133 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -242,12 +242,23 @@ typedef struct RenderData { */ int mode; - /* render engine (deprecated), octree resolution */ - short renderer, ocres; - short raystructure; - short raytrace_tree_type; - short pad4[2]; + /** + * Flags for raytrace settings. Use bit-masking to access the settings. + */ + int raytrace_options; + + /** + * Raytrace acceleration structure + */ + short raytrace_structure; + /* renderer (deprecated) */ + short renderer; + + /* octree resolution */ + short ocres; + short pad4; + /** * What to do with the sky/background. Picks sky/premul/key * blending for the background @@ -260,6 +271,7 @@ typedef struct RenderData { short osa; short frs_sec, edgeint; + /* safety, border and display rect */ rctf safety, border; @@ -808,7 +820,10 @@ typedef struct Scene { #define R_RAYSTRUCTURE_VBVH 3 #define R_RAYSTRUCTURE_SIMD_SVBVH 4 /* needs SIMD */ #define R_RAYSTRUCTURE_SIMD_QBVH 5 /* needs SIMD */ -#define R_RAYSTRUCTURE_BIH 6 + +/* raytrace_options */ +#define R_RAYTRACE_USE_LOCAL_COORDS 0x0001 +#define R_RAYTRACE_USE_INSTANCES 0x0002 /* scemode (int now) */ #define R_DOSEQ 0x0001 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ffe07d4de62..267e29d7018 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1185,7 +1185,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {R_RAYSTRUCTURE_VBVH, "R_RAYSTRUCTURE_VBVH", 0, "vBVH", ""}, {R_RAYSTRUCTURE_SIMD_SVBVH, "R_RAYSTRUCTURE_SIMD_SVBVH", 0, "SIMD SVBVH", "Requires SIMD"}, {R_RAYSTRUCTURE_SIMD_QBVH, "R_RAYSTRUCTURE_SIMD_QBVH", 0, "SIMD QBVH", "Requires SIMD"}, - {R_RAYSTRUCTURE_BIH, "R_RAYSTRUCTURE_BIH", 0, "BIH", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1618,11 +1617,22 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "raytrace_structure", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "raystructure"); + RNA_def_property_enum_sdna(prop, NULL, "raytrace_structure"); RNA_def_property_enum_items(prop, raytrace_structure_items); RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + prop= RNA_def_property(srna, "use_instances", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "raytrace_options", R_RAYTRACE_USE_INSTANCES); + RNA_def_property_ui_text(prop, "Use Instances", "Instance support leads to effective memory reduction when using duplicates."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "use_local_coords", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "raytrace_options", R_RAYTRACE_USE_LOCAL_COORDS); + RNA_def_property_ui_text(prop, "Use Local Coords", "Vertex coordinates are stored localy on each primitive. Increases memory usage, but may have impact on speed."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA); RNA_def_property_ui_text(prop, "Anti-Aliasing", "Render and combine multiple samples per pixel to prevent jagged edges."); diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index a15dada1bec..4ad7694cbbf 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,8 +1,8 @@ #!/usr/bin/python Import ('env') -cflags = ['-msse2','-mfpmath=sse'] -cxxflags = ['-msse2','-mfpmath=sse'] +cflags = ['-O2','-msse2','-mfpmath=sse'] +cxxflags = ['-O2','-msse2','-mfpmath=sse'] sources = env.Glob('intern/source/*.c') raysources = env.Glob('intern/raytrace/*.cpp') diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index edf343b6be7..6a171a98f12 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -85,11 +85,9 @@ RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ -RayObject* RE_rayobject_bvh_create(int size); /* raytrace/rayobject_bvh.c */ RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ -RayObject* RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_qbvh.c */ RayObject* RE_rayobject_svbvh_create(int size); /* raytrace/rayobject_svbvh.c */ -RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */ +RayObject* RE_rayobject_qbvh_create(int size); /* raytrace/rayobject_qbvh.c */ /* diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index c32f61e8f0a..34faa2951ce 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -142,7 +142,7 @@ static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, return 0; } -static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) +static inline int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) { /* for baking selected to active non-traceable materials might still * be in the raytree */ @@ -156,7 +156,7 @@ static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) return (is->lay & obi->lay); } -static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) +static inline int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) { /* solid material types only */ if (vlr->mat->material_type == MA_TYPE_SURFACE) @@ -165,7 +165,7 @@ static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen return 0; } -static int rayface_check_cullface(RayFace *face, Isect *is) +static inline int rayface_check_cullface(RayFace *face, Isect *is) { float nor[3]; @@ -189,7 +189,7 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; -/* + if(is->skip & RE_SKIP_VLR_RENDER_CHECK) { if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) @@ -205,7 +205,7 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) if(rayface_check_cullface(face, is) == 0) return 0; } -*/ + RE_RC_COUNT(is->raycounter->faces.test); //Load coords diff --git a/source/blender/render/intern/raytrace/rayobject_bih.cpp b/source/blender/render/intern/raytrace/rayobject_bih.cpp deleted file mode 100644 index efbf70616b7..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_bih.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include -#include - -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" - -#define BIH_NCHILDS 4 -typedef struct BIHTree BIHTree; - -static int bih_intersect(BIHTree *obj, Isect *isec); -static void bih_add(BIHTree *o, RayObject *ob); -static void bih_done(BIHTree *o); -static void bih_free(BIHTree *o); -static void bih_bb(BIHTree *o, float *min, float *max); - -static RayObjectAPI bih_api = -{ - (RE_rayobject_raycast_callback) bih_intersect, - (RE_rayobject_add_callback) bih_add, - (RE_rayobject_done_callback) bih_done, - (RE_rayobject_free_callback) bih_free, - (RE_rayobject_merge_bb_callback)bih_bb -}; - -typedef struct BIHNode BIHNode; -struct BIHNode -{ - BIHNode *child[BIH_NCHILDS]; - float bi[BIH_NCHILDS][2]; - int split_axis; -}; - -struct BIHTree -{ - RayObject rayobj; - - BIHNode *root; - - BIHNode *node_alloc, *node_next; - RTBuilder *builder; - - float bb[2][3]; -}; - - -RayObject *RE_rayobject_bih_create(int size) -{ - BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree"); - assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bih_api; - obj->root = NULL; - - obj->node_alloc = obj->node_next = NULL; - obj->builder = rtbuild_create( size ); - - return RE_rayobject_unalignRayAPI((RayObject*) obj); -} - -static void bih_free(BIHTree *obj) -{ - if(obj->builder) - rtbuild_free(obj->builder); - - if(obj->node_alloc) - MEM_freeN(obj->node_alloc); - - MEM_freeN(obj); -} - -static void bih_bb(BIHTree *obj, float *min, float *max) -{ - DO_MIN(obj->bb[0], min); - DO_MAX(obj->bb[1], max); -} - -/* - * Tree transverse - */ -static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float tmax) -{ - int i; - int hit = 0; - - const int *const offset = isec->bv_index + node->split_axis*2; - - //TODO diving heuristic - for(i=0; ibi[i][offset[0]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; - float t2 = (node->bi[i][offset[1]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; - - if(t1 < tmin) t1 = tmin; //t1 = MAX2(t1, tmin); - if(t2 > tmax) t2 = tmax; //t2 = MIN2(t2, tmax); - - if(t1 <= t2) - { - if(RE_rayobject_isAligned(node->child[i])) - { - if(node->child[i] == 0) break; - - hit |= dfs_raycast(node->child[i], isec, t1, t2); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - - if(tmax > isec->labda) - tmax = isec->labda; - } - } - - return hit; -} - -static int bih_intersect(BIHTree *obj, Isect *isec) -{ - if(RE_rayobject_isAligned(obj->root)) - return dfs_raycast(obj->root, isec, 0, isec->labda); - else - return RE_rayobject_intersect( (RayObject*)obj->root, isec); -} - - -/* - * Builds a BIH tree from builder object - */ -static void bih_add(BIHTree *obj, RayObject *ob) -{ - rtbuild_add( obj->builder, ob ); -} - -static BIHNode *bih_new_node(BIHTree *tree, int nid) -{ - BIHNode *node = tree->node_alloc + nid - 1; - assert(RE_rayobject_isAligned(node)); - if(node+1 > tree->node_next) - tree->node_next = node+1; - - return node; -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BIH_NCHILDS+(2-BIH_NCHILDS)+nchild; -} - -static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float *bb) -{ - if(rtbuild_size(builder) == 1) - { - RayObject *child = rtbuild_get_primitive( builder, 0 ); - assert(!RE_rayobject_isAligned(child)); - - INIT_MINMAX(bb, bb+3); - RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3); - - return (BIHNode*)child; - } - else - { - int i; - int nc = rtbuild_mean_split_largest_axis(builder, BIH_NCHILDS); - RTBuilder tmp; - - BIHNode *parent = bih_new_node(tree, nid); - - INIT_MINMAX(bb, bb+3); - parent->split_axis = builder->split_axis; - for(i=0; ichild[i] = bih_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), cbb ); - - parent->bi[i][0] = cbb[parent->split_axis]; - parent->bi[i][1] = cbb[parent->split_axis+3]; - - DO_MIN(cbb , bb); - DO_MAX(cbb+3, bb+3); - } - for(; ibi[i][0] = 1.0; - parent->bi[i][1] = -1.0; - parent->child[i] = 0; - } - - return parent; - } -} - -static void bih_done(BIHTree *obj) -{ - int needed_nodes; - assert(obj->root == NULL && obj->node_alloc == NULL && obj->builder); - - //TODO exact calculate needed nodes - needed_nodes = (rtbuild_size(obj->builder)+1)*2; - assert(needed_nodes > 0); - - obj->node_alloc = (BIHNode*)MEM_mallocN( sizeof(BIHNode)*needed_nodes, "BIHTree.Nodes"); - obj->node_next = obj->node_alloc; - - obj->root = bih_rearrange( obj, obj->builder, 1, (float*)obj->bb ); - - rtbuild_free( obj->builder ); - obj->builder = NULL; - - assert(obj->node_alloc+needed_nodes >= obj->node_next); -} - diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp deleted file mode 100644 index a7e96f6d3fc..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include - -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "BLI_memarena.h" -#include "bvh.h" - -#define BVH_NCHILDS 2 -#define RAY_BB_TEST_COST (0.2f) -#define DFS_STACK_SIZE 64 -#define DYNAMIC_ALLOC - -//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ -//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ -#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ - -struct BVHNode -{ - BVHNode *child[BVH_NCHILDS]; - float bb[6]; - int split_axis; -}; - -struct BVHTree -{ - RayObject rayobj; - - BVHNode *root; - - MemArena *node_arena; - - float cost; - RTBuilder *builder; -}; - -/* - * Push nodes (used on dfs) - */ -template -inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) -{ - //push nodes in reverse visit order - if(isec->idot_axis[node->split_axis] < 0.0f) - { - int i; - for(i=0; ichild[i] == 0) - break; - else - stack[stack_pos++] = node->child[i]; - } - else - { - int i; - for(i=BVH_NCHILDS-1; i>=0; i--) - if(node->child[i] != 0) - stack[stack_pos++] = node->child[i]; - } -} - -/* - * BVH done - */ -static BVHNode *bvh_new_node(BVHTree *tree, int nid) -{ - BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); - return node; -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; -} - - -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) -{ - *cost = 0; - if(rtbuild_size(builder) == 0) - return 0; - - if(rtbuild_size(builder) == 1) - { - RayObject *child = rtbuild_get_primitive( builder, 0 ); - - if(RE_rayobject_isRayFace(child)) - { - int i; - BVHNode *parent = bvh_new_node(tree, nid); - parent->split_axis = 0; - - INIT_MINMAX(parent->bb, parent->bb+3); - - for(i=0; i<1; i++) - { - parent->child[i] = (BVHNode*)rtbuild_get_primitive( builder, i ); - bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3); - } - for(; ichild[i] = 0; - - *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; - return parent; - } - else - { - assert(!RE_rayobject_isAligned(child)); - //Its a sub-raytrace structure, assume it has it own raycast - //methods and adding a Bounding Box arround is unnecessary - - *cost = RE_rayobject_cost(child); - return (BVHNode*)child; - } - } - else - { - int i; - RTBuilder tmp; - BVHNode *parent = bvh_new_node(tree, nid); - int nc = rtbuild_split(builder, BVH_NCHILDS); - - - INIT_MINMAX(parent->bb, parent->bb+3); - parent->split_axis = builder->split_axis; - for(i=0; ichild[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); - - INIT_MINMAX(cbb, cbb+3); - bvh_node_merge_bb(parent->child[i], cbb, cbb+3); - DO_MIN(cbb, parent->bb); - DO_MAX(cbb+3, parent->bb+3); - - *cost += tcost*bb_area(cbb, cbb+3); - } - for(; ichild[i] = 0; - - *cost /= bb_area(parent->bb, parent->bb+3); - *cost += nc*RAY_BB_TEST_COST; - return parent; - } - - assert(false); -} - -template<> -void bvh_done(BVHTree *obj) -{ - int needed_nodes = (rtbuild_size(obj->builder)+1)*2; - if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) - needed_nodes = BLI_MEMARENA_STD_BUFSIZE; - - obj->node_arena = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(obj->node_arena); - - - obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); - - rtbuild_free( obj->builder ); - obj->builder = NULL; -} - -template<> -int bvh_intersect(BVHTree *obj, Isect* isec) -{ - if(RE_rayobject_isAligned(obj->root)) - return bvh_node_stack_raycast(obj->root, isec); - else - return RE_rayobject_intersect( (RayObject*) obj->root, isec ); -} - - -/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -static RayObjectAPI bvh_api = -{ - (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect), - (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add), - (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done), - (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free), - (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb), - (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost) -}; - - -RayObject *RE_rayobject_bvh_create(int size) -{ - BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); - assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bvh_api; - obj->root = NULL; - - obj->node_arena = NULL; - obj->builder = rtbuild_create( size ); - - return RE_rayobject_unalignRayAPI((RayObject*) obj); -} diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index 53579d2915f..59daf9dc962 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -44,17 +44,6 @@ struct QBVHTree }; -/* - * Cost to test N childs - */ -struct PackCost -{ - float operator()(int n) - { - return (n / 4) + ((n % 4) > 2 ? 1 : n%4); - } -}; - template<> void bvh_done(QBVHTree *obj) { @@ -68,21 +57,11 @@ void bvh_done(QBVHTree *obj) BLI_memarena_use_malloc(arena2); BLI_memarena_use_align(arena2, 16); - //Build and optimize the tree - - if(0) - { - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); - pushup_simd(root); - obj->root = Reorganize_SVBVH(arena2).transform(root); - } - else - { - //Finds the optimal packing of this tree using a given cost model - OVBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); - VBVH_optimalPackSIMD(PackCost()).transform(root); - obj->root = Reorganize_SVBVH(arena2).transform(root); - } + //Build and optimize the tree + //TODO do this in 1 pass (half memory usage during building) + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + pushup_simd(root); + obj->root = Reorganize_SVBVH(arena2).transform(root); //Cleanup BLI_memarena_free(arena1); diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp index 1bcffddd0ac..f806fcf93ef 100644 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -43,6 +43,17 @@ struct SVBVHTree RTBuilder *builder; }; +/* + * Cost to test N childs + */ +struct PackCost +{ + float operator()(int n) + { + return (n / 4) + ((n % 4) > 2 ? 1 : n%4); + } +}; + template<> void bvh_done(SVBVHTree *obj) @@ -58,16 +69,27 @@ void bvh_done(SVBVHTree *obj) BLI_memarena_use_align(arena2, 16); //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); - reorganize(root); - remove_useless(root, &root); - bvh_refit(root); + if(0) + { + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + reorganize(root); + remove_useless(root, &root); + bvh_refit(root); - pushup(root); - pushdown(root); - pushup_simd(root); + pushup(root); + pushdown(root); + pushup_simd(root); - obj->root = Reorganize_SVBVH(arena2).transform(root); + obj->root = Reorganize_SVBVH(arena2).transform(root); + } + else + { + //Finds the optimal packing of this tree using a given cost model + //TODO this uses quite a lot of memory, find ways to reduce memory usage during building + OVBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + VBVH_optimalPackSIMD(PackCost()).transform(root); + obj->root = Reorganize_SVBVH(arena2).transform(root); + } //Free data diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 4e51de0da07..5260abf67ae 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -58,6 +58,16 @@ struct VBVHTree RTBuilder *builder; }; +/* + * Cost to test N childs + */ +struct PackCost +{ + float operator()(int n) + { + return n; + } +}; template<> void bvh_done(VBVHTree *obj) @@ -67,24 +77,42 @@ void bvh_done(VBVHTree *obj) //TODO find a away to exactly calculate the needed memory MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); BLI_memarena_use_malloc(arena1); - //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + if(1) + { + VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); - reorganize(root); - remove_useless(root, &root); - bvh_refit(root); + reorganize(root); + remove_useless(root, &root); + bvh_refit(root); - pushup(root); - pushdown(root); + pushup(root); + pushdown(root); + obj->root = root; + } + else + { +/* + TODO + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena2); + + //Finds the optimal packing of this tree using a given cost model + //TODO this uses quite a lot of memory, find ways to reduce memory usage during building + OVBVHNode *root = BuildBinaryVBVH(arena2).transform(obj->builder); + VBVH_optimalPackSIMD(PackCost()).transform(root); + obj->root = Reorganize_VBVH(arena1).transform(root); + + BLI_memarena_free(arena2); + */ + } //Cleanup rtbuild_free( obj->builder ); obj->builder = NULL; obj->node_arena = arena1; - obj->root = root; obj->cost = 1.0; } diff --git a/source/blender/render/intern/source/rayobject_blibvh.c b/source/blender/render/intern/source/rayobject_blibvh.c index 6e789862207..487193ef1f2 100644 --- a/source/blender/render/intern/source/rayobject_blibvh.c +++ b/source/blender/render/intern/source/rayobject_blibvh.c @@ -42,13 +42,26 @@ static void RE_rayobject_blibvh_done(RayObject *o); static void RE_rayobject_blibvh_free(RayObject *o); static void RE_rayobject_blibvh_bb(RayObject *o, float *min, float *max); +static float RE_rayobject_blibvh_cost(RayObject *o) +{ + //TODO calculate the expected cost to raycast on this structure + return 1.0; +} + +static void RE_rayobject_blibvh_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +{ + return; +} + static RayObjectAPI bvh_api = { RE_rayobject_blibvh_intersect, RE_rayobject_blibvh_add, RE_rayobject_blibvh_done, RE_rayobject_blibvh_free, - RE_rayobject_blibvh_bb + RE_rayobject_blibvh_bb, + RE_rayobject_blibvh_cost, + RE_rayobject_blibvh_hint_bb }; typedef struct BVHObject diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c index 4246dd522db..2f0a1a3f53b 100644 --- a/source/blender/render/intern/source/rayobject_octree.c +++ b/source/blender/render/intern/source/rayobject_octree.c @@ -90,13 +90,28 @@ static void RE_rayobject_octree_done(RayObject *o); static void RE_rayobject_octree_free(RayObject *o); static void RE_rayobject_octree_bb(RayObject *o, float *min, float *max); +/* + * This function is not expected to be called by current code state. + */ +static float RE_rayobject_octree_cost(RayObject *o) +{ + return 1.0; +} + +static void RE_rayobject_octree_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +{ + return; +} + static RayObjectAPI octree_api = { RE_rayobject_octree_intersect, RE_rayobject_octree_add, RE_rayobject_octree_done, RE_rayobject_octree_free, - RE_rayobject_octree_bb + RE_rayobject_octree_bb, + RE_rayobject_octree_cost, + RE_rayobject_octree_hint_bb }; /* **************** ocval method ******************* */ diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index d84a2d9210a..641085d8cd6 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -62,7 +62,6 @@ #include "raycounter.h" -#define USE_VLAK_PRIMITIVES 1 #define RAY_TRA 1 #define RAY_TRAFLIP 2 @@ -78,15 +77,12 @@ RayObject * RE_rayobject_create(int type, int size) if(type == R_RAYSTRUCTURE_AUTO) { //TODO -// if(detect_simd()) -// type = R_RAYSTRUCTURE_SIMD_SVBVH; -// else -// type = R_RAYSTRUCTURE_VBVH; - - type = R_RAYSTRUCTURE_SIMD_QBVH; + //if(detect_simd()) + type = R_RAYSTRUCTURE_SIMD_SVBVH; + //else + // type = R_RAYSTRUCTURE_VBVH; } - - + if(type == R_RAYSTRUCTURE_OCTREE) { //TODO dynamic ocres @@ -108,10 +104,7 @@ RayObject * RE_rayobject_create(int type, int size) { return RE_rayobject_qbvh_create(size); } - if(type == R_RAYSTRUCTURE_BIH) - { -// return RE_rayobject_bih_create(size); - } + assert( NULL ); return NULL; } @@ -209,8 +202,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) if(obr->raytree == NULL) { RayObject *raytree; - RayFace *face; - VlakPrimitive *vlakprimitive; + RayFace *face = NULL; + VlakPrimitive *vlakprimitive = NULL; int v; //Count faces @@ -224,8 +217,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) assert( faces > 0 ); //Create Ray cast accelaration structure - raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces ); - if(USE_VLAK_PRIMITIVES) + raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_structure, faces ); + if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives"); else face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces"); @@ -237,7 +230,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); if(is_raytraceable_vlr(re, vlr)) { - if(USE_VLAK_PRIMITIVES) + if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { RE_rayobject_add( raytree, RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ) ); vlakprimitive++; @@ -266,7 +259,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) static int has_special_rayobject(Render *re, ObjectInstanceRen *obi) { - if( (obi->flag & R_TRANSFORMED) ) + if( (obi->flag & R_TRANSFORMED) && (re->r.raytrace_options & R_RAYTRACE_USE_INSTANCES) ) { ObjectRen *obr = obi->obr; int v, faces = 0; @@ -291,8 +284,8 @@ static void makeraytree_single(Render *re) { ObjectInstanceRen *obi; RayObject *raytree; - RayFace *face; - VlakPrimitive *vlakprimitive; + RayFace *face = NULL; + VlakPrimitive *vlakprimitive = NULL; int faces = 0, obs = 0, special = 0; for(obi=re->instancetable.first; obi; obi=obi->next) @@ -318,9 +311,9 @@ static void makeraytree_single(Render *re) } //Create raytree - raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces+special ); + raytree = re->raytree = RE_rayobject_create( re->r.raytrace_structure, faces+special ); - if(USE_VLAK_PRIMITIVES) + if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives"); } @@ -352,7 +345,7 @@ static void makeraytree_single(Render *re) VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255); if(is_raytraceable_vlr(re, vlr)) { - if(USE_VLAK_PRIMITIVES) + if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ); RE_rayobject_add( raytree, obj ); @@ -392,6 +385,11 @@ void makeraytree(Render *re) re->i.infostr= "Raytree.. preparing"; re->stats_draw(re->sdh, &re->i); + /* disable options not yet suported by octree, + they might actually never be supported (unless people really need it) */ + if(re->r.raytrace_structure == R_RAYSTRUCTURE_OCTREE) + re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS); + BENCH(makeraytree_single(re), tree_build); //Calculate raytree max_size -- cgit v1.2.3 From bc942eceacb638735dc4f4f68252c4c207147a70 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 1 Oct 2009 18:57:22 +0000 Subject: netrender: first draft for process jobs, to be able to run arbitrary commands on slaves. This could be used to bake physics on network or whatnot. --- release/scripts/io/netrender/client.py | 4 +- release/scripts/io/netrender/master.py | 40 +++++++++------- release/scripts/io/netrender/master_html.py | 13 ++---- release/scripts/io/netrender/model.py | 22 +++++++-- release/scripts/io/netrender/slave.py | 71 ++++++++++++++++++----------- 5 files changed, 91 insertions(+), 59 deletions(-) diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py index 65b2937867f..1897d1fd949 100644 --- a/release/scripts/io/netrender/client.py +++ b/release/scripts/io/netrender/client.py @@ -3,12 +3,12 @@ import sys, os, re import http, http.client, http.server, urllib import subprocess, shutil, time, hashlib +import netrender.model import netrender.slave as slave import netrender.master as master from netrender.utils import * - -def clientSendJob(conn, scene, anim = False, chunks = 5): +def clientSendJob(conn, scene, anim = False): netsettings = scene.network_render job = netrender.model.RenderJob() diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py index a3e186a9cfd..be23fda7a91 100644 --- a/release/scripts/io/netrender/master.py +++ b/release/scripts/io/netrender/master.py @@ -42,9 +42,10 @@ class MRenderSlave(netrender.model.RenderSlave): self.job = None class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []): + def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []): super().__init__() self.id = job_id + self.type = job_type self.name = name self.files = files self.frames = [] @@ -53,6 +54,10 @@ class MRenderJob(netrender.model.RenderJob): self.usage = 0.0 self.blacklist = blacklist self.last_dispatched = time.time() + + # force one chunk for process jobs + if self.type == netrender.model.JOB_PROCESS: + self.chunks = 1 # special server properties self.last_update = 0 @@ -93,8 +98,8 @@ class MRenderJob(netrender.model.RenderJob): if frame: frame.log_path = log_path - def addFrame(self, frame_number): - frame = MRenderFrame(frame_number) + def addFrame(self, frame_number, command): + frame = MRenderFrame(frame_number, command) self.frames.append(frame) return frame @@ -114,12 +119,14 @@ class MRenderJob(netrender.model.RenderJob): return frames class MRenderFrame(netrender.model.RenderFrame): - def __init__(self, frame): + def __init__(self, frame, command): super().__init__() self.number = frame self.slave = None self.time = 0 self.status = QUEUED + self.command = command + self.log_path = None def reset(self, all): @@ -368,10 +375,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_id = self.server.nextJobID() - job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) + job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) for frame in job_info.frames: - frame = job.addFrame(frame.number) + frame = job.addFrame(frame.number, frame.command) self.server.addJob(job) @@ -538,17 +545,18 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): frame = job[job_frame] if frame: - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() + if job.type == netrender.model.JOB_BLENDER: + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() - del buf - elif job_result == ERROR: - # blacklist slave on this job on error - job.blacklist.append(slave.id) + del buf + elif job_result == ERROR: + # blacklist slave on this job on error + job.blacklist.append(slave.id) self.server.stats("", "Receiving result") diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py index 6a956a70e9f..545659e8dc4 100644 --- a/release/scripts/io/netrender/master_html.py +++ b/release/scripts/io/netrender/master_html.py @@ -32,9 +32,8 @@ def get(handler): def endTable(): output("") - handler.send_head(content = "text/html") - if handler.path == "/html" or handler.path == "/": + handler.send_head(content = "text/html") output("NetRender") output("

Master

") @@ -86,6 +85,7 @@ def get(handler): output("") elif handler.path.startswith("/html/job"): + handler.send_head(content = "text/html") job_id = handler.path[9:] output("NetRender") @@ -108,10 +108,9 @@ def get(handler): output("") elif handler.path.startswith("/html/log"): + handler.send_head(content = "text/plain") pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)") - output("NetRender") - match = pattern.match(handler.path[9:]) if match: job_id = match.groups()[0] @@ -125,12 +124,8 @@ def get(handler): if frame: f = open(frame.log_path, 'rb') - output("
")
-						
 						shutil.copyfileobj(f, handler.wfile)
 						
-						output("
") - f.close() else: output("no such frame") @@ -138,5 +133,3 @@ def get(handler): output("no such job") else: output("malformed url") - - output("") diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py index be97f8d0a81..ca2a42d87f6 100644 --- a/release/scripts/io/netrender/model.py +++ b/release/scripts/io/netrender/model.py @@ -72,9 +72,18 @@ class RenderSlave: return slave +JOB_BLENDER = 1 +JOB_PROCESS = 2 + +JOB_TYPES = { + JOB_BLENDER: "Blender", + JOB_PROCESS: "Process" + } + class RenderJob: def __init__(self): self.id = "" + self.type = JOB_BLENDER self.name = "" self.files = [] self.frames = [] @@ -87,8 +96,8 @@ class RenderJob: def addFile(self, file_path, start=-1, end=-1): self.files.append((file_path, start, end)) - def addFrame(self, frame_number): - frame = RenderFrame(frame_number) + def addFrame(self, frame_number, command = ""): + frame = RenderFrame(frame_number, command) self.frames.append(frame) return frame @@ -138,6 +147,7 @@ class RenderJob: max_frame = max((f.number for f in frames)) if frames else -1 return { "id": self.id, + "type": self.type, "name": self.name, "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], "frames": [f.serialize() for f in self.frames if not frames or f in frames], @@ -155,6 +165,7 @@ class RenderJob: job = RenderJob() job.id = data["id"] + job.type = data["type"] job.name = data["name"] job.files = data["files"] job.frames = [RenderFrame.materialize(f) for f in data["frames"]] @@ -167,11 +178,12 @@ class RenderJob: return job class RenderFrame: - def __init__(self, number = 0): + def __init__(self, number = 0, command = ""): self.number = number self.time = 0 self.status = QUEUED self.slave = None + self.command = command def statusText(self): return STATUS_TEXT[self.status] @@ -181,7 +193,8 @@ class RenderFrame: "number": self.number, "time": self.time, "status": self.status, - "slave": None if not self.slave else self.slave.serialize() + "slave": None if not self.slave else self.slave.serialize(), + "command": self.command } @staticmethod @@ -194,5 +207,6 @@ class RenderFrame: frame.time = data["time"] frame.status = data["status"] frame.slave = RenderSlave.materialize(data["slave"]) + frame.command = data["command"] return frame diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py index 657e31001e0..15ca6faf297 100644 --- a/release/scripts/io/netrender/slave.py +++ b/release/scripts/io/netrender/slave.py @@ -99,37 +99,46 @@ def render_slave(engine, scene): if not os.path.exists(JOB_PREFIX): os.mkdir(JOB_PREFIX) - job_path = job.files[0][0] # data in files have format (path, start, end) - main_path, main_file = os.path.split(job_path) - - job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) - print("Fullpath", job_full_path) - print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) - engine.update_stats("", "Render File", main_file, "for job", job.id) - - for file_path, start, end in job.files[1:]: - print("\t", file_path) - testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) - - frame_args = [] - - for frame in job.frames: - print("frame", frame.number) - frame_args += ["-f", str(frame.number)] + if job.type == netrender.model.JOB_BLENDER: + job_path = job.files[0][0] # data in files have format (path, start, end) + main_path, main_file = os.path.split(job_path) + + job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) + print("Fullpath", job_full_path) + print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) + engine.update_stats("", "Render File", main_file, "for job", job.id) + + for file_path, start, end in job.files[1:]: + print("\t", file_path) + testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) + # announce log to master logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) response = conn.getresponse() - first_frame = job.frames[0].number + first_frame = job.frames[0].number + # start render start_t = time.time() - - val = SetErrorMode() - process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - RestoreErrorMode(val) + + if job.type == netrender.model.JOB_BLENDER: + frame_args = [] + + for frame in job.frames: + print("frame", frame.number) + frame_args += ["-f", str(frame.number)] + + val = SetErrorMode() + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) + elif job.type == netrender.model.JOB_PROCESS: + command = job.frames[0].command + val = SetErrorMode() + process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) headers = {"job-id":job.id, "slave-id":slave_id} @@ -155,6 +164,9 @@ def render_slave(engine, scene): if testCancel(conn, job.id, first_frame): cancelled = True + # read leftovers if needed + stdout += process.stdout.read() + if cancelled: # kill process if needed if process.poll() == None: @@ -182,11 +194,16 @@ def render_slave(engine, scene): headers["job-result"] = str(DONE) for frame in job.frames: headers["job-frame"] = str(frame.number) - # send result back to server - f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') - conn.request("PUT", "/render", f, headers=headers) - f.close() - response = conn.getresponse() + + if job.type == netrender.model.JOB_BLENDER: + # send image back to server + f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') + conn.request("PUT", "/render", f, headers=headers) + f.close() + response = conn.getresponse() + elif job.type == netrender.model.JOB_PROCESS: + conn.request("PUT", "/render", headers=headers) + response = conn.getresponse() else: headers["job-result"] = str(ERROR) for frame in job.frames: -- cgit v1.2.3 From b26ef33b8ed68ba3b5a5a78a3f23fcade4035f31 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 1 Oct 2009 23:32:57 +0000 Subject: Fix #19311: adding/opening datablocks did not always make the right one active. Now there's a function to get the pointer + property from the UI, just like for the animation operators. Also two fixes for fileselect events, regions are now preserved so that context is restored to the old region, and the cancel callback is called when the operator is cancelled. --- source/blender/blenkernel/intern/world.c | 11 +++- source/blender/editors/include/UI_interface.h | 1 + .../editors/interface/interface_templates.c | 40 +++++++++--- source/blender/editors/physics/particle_boids.c | 4 -- source/blender/editors/render/render_shading.c | 72 +++++++++++----------- source/blender/editors/screen/area.c | 25 +++++--- source/blender/editors/space_action/action_edit.c | 21 +++++-- source/blender/editors/space_image/image_ops.c | 72 +++++++++++++++++++--- source/blender/editors/space_text/text_ops.c | 58 ++++++++++++++++- source/blender/makesrna/RNA_types.h | 5 ++ .../blender/windowmanager/intern/wm_event_system.c | 20 ++++-- 11 files changed, 249 insertions(+), 80 deletions(-) diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index f795c147f54..c75c9272e5c 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -86,15 +86,20 @@ World *add_world(char *name) wrld= alloc_libblock(&G.main->world, ID_WO, name); - wrld->horb= 0.6f; - wrld->skytype= WO_SKYBLEND; + wrld->horr= 0.25f; + wrld->horg= 0.25f; + wrld->horb= 0.25f; + wrld->zenr= 0.1f; + wrld->zeng= 0.1f; + wrld->zenb= 0.1f; + wrld->skytype= 0; wrld->stardist= 15.0f; wrld->starsize= 2.0f; wrld->exp= 0.0f; wrld->exposure=wrld->range= 1.0f; - wrld->aodist= 5.0f; + wrld->aodist= 10.0f; wrld->aosamp= 5; wrld->aoenergy= 1.0f; wrld->aobias= 0.05f; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index e1762991676..7fea4b10ed9 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -670,6 +670,7 @@ void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA * /* Helpers for Operators */ void uiAnimContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index); void uiFileBrowseContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop); +void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop); /* Styled text draw */ void uiStyleFontSet(struct uiFontStyle *fs); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 57dc484f975..5b93f9ee06d 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -153,6 +153,36 @@ static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem) /************************ ID Template ***************************/ +/* for new/open operators */ +void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop) +{ + TemplateID *template; + ARegion *ar= CTX_wm_region(C); + uiBlock *block; + uiBut *but; + + memset(ptr, 0, sizeof(*ptr)); + *prop= NULL; + + if(!ar) + return; + + for(block=ar->uiblocks.first; block; block=block->next) { + for(but=block->buttons.first; but; but= but->next) { + /* find the button before the active one */ + if((but->flag & (UI_BUT_LAST_ACTIVE|UI_ACTIVE))) { + if(but->func_argN) { + template= but->func_argN; + *ptr= template->ptr; + *prop= template->prop; + return; + } + } + } + } +} + + static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) { TemplateID *template= (TemplateID*)arg_litem; @@ -167,11 +197,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) break; case UI_ID_OPEN: case UI_ID_ADD_NEW: - if(template->idlb->last) { - RNA_id_pointer_create(template->idlb->last, &idptr); - RNA_property_pointer_set(&template->ptr, template->prop, idptr); - RNA_property_update(C, &template->ptr, template->prop); - } + /* these call uiIDContextPropertySet */ break; case UI_ID_DELETE: memset(&idptr, 0, sizeof(idptr)); @@ -291,7 +317,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6; if(newop) { - but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL); + but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_DEFAULT, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } else { @@ -307,7 +333,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc int w= id?UI_UNIT_X: (flag & UI_ID_ADD_NEW)? UI_UNIT_X*3: UI_UNIT_X*6; if(openop) { - but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_REGION_WIN, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL); + but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN)); } else { diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c index 0b63f1a98ff..b7a97d1131a 100644 --- a/source/blender/editors/physics/particle_boids.c +++ b/source/blender/editors/physics/particle_boids.c @@ -52,7 +52,6 @@ /************************ add/del boid rule operators *********************/ static int rule_add_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob= ptr.id.data; @@ -152,7 +151,6 @@ void BOID_OT_rule_del(wmOperatorType *ot) /************************ move up/down boid rule operators *********************/ static int rule_move_up_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; @@ -191,7 +189,6 @@ void BOID_OT_rule_move_up(wmOperatorType *ot) static int rule_move_down_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; @@ -363,7 +360,6 @@ void BOID_OT_state_move_up(wmOperatorType *ot) static int state_move_down_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; BoidSettings *boids; diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index a31a60ecbd6..56605ad0970 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -436,9 +436,8 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot) static int new_material_exec(bContext *C, wmOperator *op) { Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; - Object *ob; - PointerRNA ptr; - int index; + PointerRNA ptr, idptr; + PropertyRNA *prop; /* add or copy material */ if(ma) @@ -446,18 +445,17 @@ static int new_material_exec(bContext *C, wmOperator *op) else ma= add_material("Material"); - ma->id.us--; /* compensating for us++ in assign_material */ - - /* attempt to assign to material slot */ - ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot); - - if(ptr.data) { - ob= ptr.id.data; - index= (Material**)ptr.data - ob->mat; + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); - assign_material(ob, ma, index+1); + if(prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + ma->id.us--; - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + RNA_id_pointer_create(&ma->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + RNA_property_update(C, &ptr, prop); } WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma); @@ -484,9 +482,8 @@ void MATERIAL_OT_new(wmOperatorType *ot) static int new_texture_exec(bContext *C, wmOperator *op) { Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - ID *id; - MTex *mtex; - PointerRNA ptr; + PointerRNA ptr, idptr; + PropertyRNA *prop; /* add or copy texture */ if(tex) @@ -494,23 +491,17 @@ static int new_texture_exec(bContext *C, wmOperator *op) else tex= add_texture("Texture"); - id_us_min(&tex->id); - - /* attempt to assign to texture slot */ - ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot); - - if(ptr.data) { - id= ptr.id.data; - mtex= ptr.data; + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); - if(mtex) { - if(mtex->tex) - id_us_min(&mtex->tex->id); - mtex->tex= tex; - id_us_plus(&tex->id); - } + if(prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + tex->id.us--; - /* XXX nodes, notifier .. */ + RNA_id_pointer_create(&tex->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + RNA_property_update(C, &ptr, prop); } WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex); @@ -536,8 +527,9 @@ void TEXTURE_OT_new(wmOperatorType *ot) static int new_world_exec(bContext *C, wmOperator *op) { - Scene *scene= CTX_data_scene(C); World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data; + PointerRNA ptr, idptr; + PropertyRNA *prop; /* add or copy world */ if(wo) @@ -545,10 +537,18 @@ static int new_world_exec(bContext *C, wmOperator *op) else wo= add_world("World"); - /* assign to scene */ - if(scene->world) - id_us_min(&scene->world->id); - scene->world= wo; + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + + if(prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + wo->id.us--; + + RNA_id_pointer_create(&wo->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + RNA_property_update(C, &ptr, prop); + } WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 87901d75494..fb782837d5e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -958,17 +958,22 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) /* Note; SPACE_EMPTY is possible on new screens */ /* regions */ - if(swap_space<2) { - st= BKE_spacetype_from_id(sa1->spacetype); - for(ar= sa1->regionbase.first; ar; ar= ar->next) - BKE_area_region_free(st, ar); - BLI_freelistN(&sa1->regionbase); + if(swap_space == 1) { + SWAP(ListBase, sa1->regionbase, sa2->regionbase); } - - st= BKE_spacetype_from_id(sa2->spacetype); - for(ar= sa2->regionbase.first; ar; ar= ar->next) { - ARegion *newar= BKE_area_region_copy(st, ar); - BLI_addtail(&sa1->regionbase, newar); + else { + if(swap_space<2) { + st= BKE_spacetype_from_id(sa1->spacetype); + for(ar= sa1->regionbase.first; ar; ar= ar->next) + BKE_area_region_free(st, ar); + BLI_freelistN(&sa1->regionbase); + } + + st= BKE_spacetype_from_id(sa2->spacetype); + for(ar= sa2->regionbase.first; ar; ar= ar->next) { + ARegion *newar= BKE_area_region_copy(st, ar); + BLI_addtail(&sa1->regionbase, newar); + } } } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 865d072d938..0bcf4b037cb 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -86,6 +86,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "UI_interface.h" + #include "action_intern.h" /* ************************************************************************** */ @@ -96,14 +98,25 @@ static int act_new_exec(bContext *C, wmOperator *op) { bAction *action; + PointerRNA ptr, idptr; + PropertyRNA *prop; // XXX need to restore behaviour to copy old actions... action= add_empty_action("Action"); - /* combined with RNA property, this will assign & increase user, - so decrease here to compensate for that */ - action->id.us--; - + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + + if(prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + action->id.us--; + + RNA_id_pointer_create(&action->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + RNA_property_update(C, &ptr, prop); + } + /* set notifier that keyframes have changed */ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 89427ba8535..91316fba4d0 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -616,27 +616,61 @@ static void image_filesel(bContext *C, wmOperator *op, const char *path) /******************** open image operator ********************/ +static void open_init(bContext *C, wmOperator *op) +{ + PropertyPointerRNA *pprop; + + op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); + uiIDContextProperty(C, &pprop->ptr, &pprop->prop); +} + +static int open_cancel(bContext *C, wmOperator *op) +{ + MEM_freeN(op->customdata); + op->customdata= NULL; + return OPERATOR_CANCELLED; +} + static int open_exec(bContext *C, wmOperator *op) { SpaceImage *sima= CTX_wm_space_image(C); Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); + PropertyPointerRNA *pprop; + PointerRNA idptr; Image *ima= NULL; char str[FILE_MAX]; RNA_string_get(op->ptr, "path", str); ima= BKE_add_image_file(str, scene->r.cfra); - if(!ima) + if(!ima) { + if(op->customdata) MEM_freeN(op->customdata); return OPERATOR_CANCELLED; + } - /* already set later */ - ima->id.us--; + if(!op->customdata) + open_init(C, op); + + /* hook into UI */ + pprop= op->customdata; + + if(pprop->prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + ima->id.us--; + + RNA_id_pointer_create(&ima->id, &idptr); + RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr); + RNA_property_update(C, &pprop->ptr, pprop->prop); + } + else if(sima) + ED_space_image_set(C, sima, scene, obedit, ima); // XXX other users? BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_RELOAD); - if(sima) - ED_space_image_set(C, sima, scene, obedit, ima); + + MEM_freeN(op->customdata); return OPERATOR_FINISHED; } @@ -649,6 +683,8 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) if(RNA_property_is_set(op->ptr, "path")) return open_exec(C, op); + open_init(C, op); + image_filesel(C, op, path); return OPERATOR_RUNNING_MODAL; @@ -663,6 +699,7 @@ void IMAGE_OT_open(wmOperatorType *ot) /* api callbacks */ ot->exec= open_exec; ot->invoke= open_invoke; + ot->cancel= open_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1060,6 +1097,8 @@ static int new_exec(bContext *C, wmOperator *op) Scene *scene; Object *obedit; Image *ima; + PointerRNA ptr, idptr; + PropertyRNA *prop; char name[22]; float color[4]; int width, height, floatbuf, uvtestgrid; @@ -1078,12 +1117,27 @@ static int new_exec(bContext *C, wmOperator *op) color[3]= RNA_float_get(op->ptr, "alpha"); ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color); - ima->id.us--; /* already set later */ - if(sima) { // XXX other users? - BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); - ED_space_image_set(C, sima, scene, obedit, ima); + if(!ima) + return OPERATOR_CANCELLED; + + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + + if(prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + ima->id.us--; + + RNA_id_pointer_create(&ima->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + RNA_property_update(C, &ptr, prop); } + else if(sima) + ED_space_image_set(C, sima, scene, obedit, ima); + + // XXX other users? + BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_USER_NEW_IMAGE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 8e81336912b..44f7a097a18 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -159,10 +159,24 @@ static int new_exec(bContext *C, wmOperator *op) { SpaceText *st= CTX_wm_space_text(C); Text *text; + PointerRNA ptr, idptr; + PropertyRNA *prop; text= add_empty_text("Text"); - if(st) { + /* hook into UI */ + uiIDContextProperty(C, &ptr, &prop); + + if(prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + text->id.us--; + + RNA_id_pointer_create(&text->id, &idptr); + RNA_property_pointer_set(&ptr, prop, idptr); + RNA_property_update(C, &ptr, prop); + } + else if(st) { st->text= text; st->top= 0; } @@ -186,23 +200,61 @@ void TEXT_OT_new(wmOperatorType *ot) /******************* open operator *********************/ +static void open_init(bContext *C, wmOperator *op) +{ + PropertyPointerRNA *pprop; + + op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); + uiIDContextProperty(C, &pprop->ptr, &pprop->prop); +} + +static int open_cancel(bContext *C, wmOperator *op) +{ + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; +} + static int open_exec(bContext *C, wmOperator *op) { SpaceText *st= CTX_wm_space_text(C); Text *text; + PropertyPointerRNA *pprop; + PointerRNA idptr; char str[FILE_MAX]; RNA_string_get(op->ptr, "path", str); text= add_text(str, G.sce); - if(st) { + if(!text) { + if(op->customdata) MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; + } + + if(!op->customdata) + open_init(C, op); + + /* hook into UI */ + pprop= op->customdata; + + if(pprop->prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + text->id.us--; + + RNA_id_pointer_create(&text->id, &idptr); + RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr); + RNA_property_update(C, &pprop->ptr, pprop->prop); + } + else if(st) { st->text= text; st->top= 0; } WM_event_add_notifier(C, NC_TEXT|NA_ADDED, text); + MEM_freeN(op->customdata); + return OPERATOR_FINISHED; } @@ -214,6 +266,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event) if(RNA_property_is_set(op->ptr, "path")) return open_exec(C, op); + open_init(C, op); RNA_string_set(op->ptr, "path", path); WM_event_add_fileselect(C, op); @@ -230,6 +283,7 @@ void TEXT_OT_open(wmOperatorType *ot) /* api callbacks */ ot->exec= open_exec; ot->invoke= open_invoke; + ot->cancel= open_cancel; ot->poll= text_new_poll; /* properties */ diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 98df8c34d58..df447894830 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -54,6 +54,11 @@ typedef struct PointerRNA { void *data; } PointerRNA; +typedef struct PropertyPointerRNA { + PointerRNA ptr; + struct PropertyRNA *prop; +} PropertyPointerRNA; + /* Property */ typedef enum PropertyType { diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index b7156a17383..80878cf6884 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -298,6 +298,8 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) uiPupMenuReports(C, op->reports); if(retval & OPERATOR_FINISHED) { + op->customdata= NULL; + if(op->type->flag & OPTYPE_UNDO) ED_undo_push_op(C, op); @@ -427,6 +429,8 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P } if(retval & OPERATOR_FINISHED) { + op->customdata= NULL; + if(ot->flag & OPTYPE_UNDO) ED_undo_push_op(C, op); @@ -813,6 +817,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand } if(retval & OPERATOR_FINISHED) { + op->customdata= NULL; + if(ot->flag & OPTYPE_UNDO) ED_undo_push_op(C, op); @@ -936,9 +942,9 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa /* remlink now, for load file case */ BLI_remlink(handlers, handler); + wm_handler_op_context(C, handler); + if(event->val==EVT_FILESELECT_EXEC) { - wm_handler_op_context(C, handler); - /* a bit weak, might become arg for WM_event_fileselect? */ /* XXX also extension code in image-save doesnt work for this yet */ if(strncmp(handler->op->type->name, "Save", 4)==0) { @@ -954,11 +960,15 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa WM_operator_free(handler->op); } - - CTX_wm_area_set(C, NULL); } - else + else { + if(handler->op->type->cancel) + handler->op->type->cancel(C, handler->op); + WM_operator_free(handler->op); + } + + CTX_wm_area_set(C, NULL); wm_event_free_handler(handler); if(path) -- cgit v1.2.3 From a9ef985b320363890a96c755bea4966d413ef9f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 2 Oct 2009 03:09:17 +0000 Subject: win32 was using iconv even when international was disabled. --- CMake/macros.cmake | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMake/macros.cmake b/CMake/macros.cmake index e8f378c0925..150bd55bfd7 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -105,7 +105,12 @@ MACRO(SETUP_LIBLINKS IF(WITH_INTERNATIONAL) TARGET_LINK_LIBRARIES(${target} ${GETTEXT_LIB}) + + IF(WIN32) + TARGET_LINK_LIBRARIES(${target} ${ICONV_LIB}) + ENDIF(WIN32) ENDIF(WITH_INTERNATIONAL) + IF(WITH_OPENAL) TARGET_LINK_LIBRARIES(${target} ${OPENAL_LIBRARY}) ENDIF(WITH_OPENAL) @@ -121,9 +126,6 @@ MACRO(SETUP_LIBLINKS IF(WITH_SDL) TARGET_LINK_LIBRARIES(${target} ${SDL_LIBRARY}) ENDIF(WITH_SDL) - IF(WIN32) - TARGET_LINK_LIBRARIES(${target} ${ICONV_LIB}) - ENDIF(WIN32) IF(WITH_QUICKTIME) TARGET_LINK_LIBRARIES(${target} ${QUICKTIME_LIB}) ENDIF(WITH_QUICKTIME) -- cgit v1.2.3 From ba2f052a374779d301aab501f9c909c6a59612f8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 2 Oct 2009 07:03:58 +0000 Subject: projection painting changes from 2.4x r23600 --- source/blender/editors/mesh/editface.c | 64 +++++++++++++++++++---- source/blender/editors/sculpt_paint/paint_image.c | 20 ++++++- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index a6c5e5beccf..f65ab7ddd67 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -89,6 +89,34 @@ static int pupmenu() {return 0;} /* ***************** XXX **************** */ +/* copy the face flags, most importantly selection from the mesh to the final derived mesh, + * use in object mode when selecting faces (while painting) */ +void object_facesel_flush_dm(Object *ob) +{ + Mesh *me= get_mesh(ob); + DerivedMesh *dm= ob->derivedFinal; + MFace *faces, *mf, *mf_orig; + int *index_array = NULL; + int totface; + int i; + + + if(me==NULL || dm==NULL || !CustomData_has_layer( &dm->faceData, CD_ORIGINDEX)) + return; + + faces = dm->getFaceArray(dm); + totface = dm->getNumFaces(dm); + + index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX); + + mf= faces; + + for (i= 0; imface + index_array[i]; + mf->flag= mf_orig->flag;; + } +} + /* returns 0 if not found, otherwise 1 */ int facesel_face_pick(View3D *v3d, Mesh *me, short *mval, unsigned int *index, short rect) { @@ -163,6 +191,7 @@ void reveal_tface(Scene *scene) mface++; } + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -197,7 +226,8 @@ void hide_tface(Scene *scene) mface++; } - + + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -237,7 +267,10 @@ void deselectall_tface(Scene *scene) sel= 0; while(a--) { if(mface->flag & ME_HIDE); - else if(mface->flag & ME_FACE_SEL) sel= 1; + else if(mface->flag & ME_FACE_SEL) { + sel= 1; + break; + } mface++; } @@ -252,6 +285,7 @@ void deselectall_tface(Scene *scene) mface++; } + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -274,7 +308,8 @@ void selectswap_tface(Scene *scene) } mface++; } - + + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 0); } @@ -655,11 +690,11 @@ void face_select(Scene *scene, View3D *v3d) /* image window redraw */ - + object_facesel_flush_dm(OBACT); // XXX notifier! object_tface_flags_changed(OBACT, 1); } -void face_borderselect(Scene *scene, ARegion *ar) +void face_borderselect(Scene *scene, ScrArea *sa, ARegion *ar) { Mesh *me; MFace *mface; @@ -675,13 +710,18 @@ void face_borderselect(Scene *scene, ARegion *ar) // XXX val= get_border(&rect, 3); - /* why readbuffer here? shouldn't be necessary (maybe a flush or so) */ - glReadBuffer(GL_BACK); -#ifdef __APPLE__ - glReadBuffer(GL_AUX0); /* apple only */ -#endif - if(val) { + View3D *v3d= sa->spacedata.first; + RegionView3D *rv3d= ar->regiondata; + + /* without this border select often fails */ +#if 0 /* XXX untested in 2.5 */ + if (v3d->flag & V3D_NEEDBACKBUFDRAW) { + check_backbuf(); + persp(PERSP_VIEW); + } +#endif + selar= MEM_callocN(me->totface+1, "selar"); sx= (rect.xmax-rect.xmin+1); @@ -722,6 +762,8 @@ void face_borderselect(Scene *scene, ARegion *ar) #ifdef __APPLE__ glReadBuffer(GL_BACK); #endif + + object_facesel_flush_dm(OBACT); } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index d223c423690..7596191e781 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -223,6 +223,7 @@ typedef struct ProjPaintState { DerivedMesh *dm; int dm_totface; int dm_totvert; + int dm_release; MVert *dm_mvert; MFace *dm_mface; @@ -2934,12 +2935,26 @@ static void project_paint_begin(ProjPaintState *ps) /* ---- end defines ---- */ /* paint onto the derived mesh */ - ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->v3d->customdata_mask); + + /* Workaround for subsurf selection, try the display mesh first */ + if(ps->ob->derivedFinal && CustomData_has_layer( &ps->ob->derivedFinal->faceData, CD_MTFACE)) { + ps->dm = ps->ob->derivedFinal; + ps->dm_release= FALSE; + } + else { + ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->v3d->customdata_mask); + ps->dm_release= TRUE; + } if ( !CustomData_has_layer( &ps->dm->faceData, CD_MTFACE) ) { + + if(ps->dm_release) + ps->dm->release(ps->dm); + ps->dm = NULL; return; } + ps->dm_mvert = ps->dm->getVertArray(ps->dm); ps->dm_mface = ps->dm->getFaceArray(ps->dm); ps->dm_mtface= ps->dm->getFaceDataArray(ps->dm, CD_MTFACE); @@ -3402,7 +3417,8 @@ static void project_paint_end(ProjPaintState *ps) BLI_memarena_free(ps->arena_mt[a]); } - ps->dm->release(ps->dm); + if(ps->dm_release) + ps->dm->release(ps->dm); } /* 1= an undo, -1 is a redo. */ -- cgit v1.2.3 From 14619ec98dd98420503b926650d2ec59f630bcba Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Fri, 2 Oct 2009 07:20:07 +0000 Subject: Move Inverse Kinematics panel to Constraint context. Make iTaSC parameter panel more readable. --- release/scripts/ui/buttons_data_bone.py | 144 ------------------------ release/scripts/ui/buttons_object_constraint.py | 141 +++++++++++++++++++++++ source/blender/blenkernel/intern/action.c | 2 +- source/blender/makesrna/intern/rna_pose.c | 29 +++-- 4 files changed, 160 insertions(+), 156 deletions(-) diff --git a/release/scripts/ui/buttons_data_bone.py b/release/scripts/ui/buttons_data_bone.py index 5971e4492ce..12db3e7277d 100644 --- a/release/scripts/ui/buttons_data_bone.py +++ b/release/scripts/ui/buttons_data_bone.py @@ -149,94 +149,6 @@ class BONE_PT_bone(BoneButtonsPanel): col.itemL(text="Custom Shape:") col.itemR(pchan, "custom_shape", text="") -class BONE_PT_inverse_kinematics(BoneButtonsPanel): - __label__ = "Inverse Kinematics" - __default_closed__ = True - - def poll(self, context): - ob = context.object - bone = context.bone - - if ob and context.bone: - pchan = ob.pose.pose_channels[context.bone.name] - return pchan.has_ik - - return False - - def draw(self, context): - layout = self.layout - - ob = context.object - bone = context.bone - pchan = ob.pose.pose_channels[context.bone.name] - - row = layout.row() - row.itemR(ob.pose, "ik_solver") - - split = layout.split(percentage=0.25) - split.itemR(pchan, "ik_dof_x", text="X") - row = split.row() - row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True) - row.active = pchan.ik_dof_x - - split = layout.split(percentage=0.25) - row = split.row() - row.itemR(pchan, "ik_limit_x", text="Limit") - row.active = pchan.ik_dof_x - row = split.row(align=True) - row.itemR(pchan, "ik_min_x", text="") - row.itemR(pchan, "ik_max_x", text="") - row.active = pchan.ik_dof_x and pchan.ik_limit_x - - split = layout.split(percentage=0.25) - split.itemR(pchan, "ik_dof_y", text="Y") - row = split.row() - row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True) - row.active = pchan.ik_dof_y - - split = layout.split(percentage=0.25) - row = split.row() - row.itemR(pchan, "ik_limit_y", text="Limit") - row.active = pchan.ik_dof_y - row = split.row(align=True) - row.itemR(pchan, "ik_min_y", text="") - row.itemR(pchan, "ik_max_y", text="") - row.active = pchan.ik_dof_y and pchan.ik_limit_y - - split = layout.split(percentage=0.25) - split.itemR(pchan, "ik_dof_z", text="Z") - row = split.row() - row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True) - row.active = pchan.ik_dof_z - - split = layout.split(percentage=0.25) - row = split.row() - row.itemR(pchan, "ik_limit_z", text="Limit") - row.active = pchan.ik_dof_z - row = split.row(align=True) - row.itemR(pchan, "ik_min_z", text="") - row.itemR(pchan, "ik_max_z", text="") - row.active = pchan.ik_dof_z and pchan.ik_limit_z - split = layout.split() - split.itemR(pchan, "ik_stretch", text="Stretch", slider=True) - split.itemL() - - if ob.pose.ik_solver == "ITASC": - layout.itemL(text="Joint constraint:") - split = layout.split(percentage=0.3) - row = split.row() - row.itemR(pchan, "ik_rot_control", text="Rotation") - row = split.row() - row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True) - row.active = pchan.ik_rot_control - # not supported yet - #split = layout.split(percentage=0.3) - #row = split.row() - #row.itemR(pchan, "ik_lin_control", text="Size") - #row = split.row() - #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True) - #row.active = pchan.ik_lin_control - class BONE_PT_deform(BoneButtonsPanel): __label__ = "Deform" __default_closed__ = True @@ -285,65 +197,9 @@ class BONE_PT_deform(BoneButtonsPanel): col.itemL(text="Offset:") col.itemR(bone, "cyclic_offset") -class BONE_PT_iksolver_itasc(BoneButtonsPanel): - __idname__ = "BONE_PT_iksolver_itasc" - __label__ = "iTaSC parameters" - __default_closed__ = True - - def poll(self, context): - ob = context.object - bone = context.bone - - if ob and context.bone: - pchan = ob.pose.pose_channels[context.bone.name] - return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param - - return False - - def draw(self, context): - layout = self.layout - - ob = context.object - itasc = ob.pose.ik_param - - layout.row().itemR(itasc, "simulation") - if itasc.simulation: - split = layout.split() - row = split.row() - row.itemR(itasc, "reiteration") - row = split.row() - if itasc.reiteration: - itasc.initial_reiteration = True - row.itemR(itasc, "initial_reiteration") - row.active = not itasc.reiteration - - flow = layout.column_flow() - flow.itemR(itasc, "precision") - flow.itemR(itasc, "num_iter") - flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration - - if itasc.simulation: - layout.itemR(itasc, "auto_step") - row = layout.row() - if itasc.auto_step: - row.itemR(itasc, "min_step") - row.itemR(itasc, "max_step") - else: - row.itemR(itasc, "num_step") - - layout.itemR(itasc, "solver") - if itasc.simulation: - layout.itemR(itasc, "feedback") - layout.itemR(itasc, "max_velocity") - if itasc.solver == "DLS": - row = layout.row() - row.itemR(itasc, "dampmax") - row.itemR(itasc, "dampeps") bpy.types.register(BONE_PT_context_bone) bpy.types.register(BONE_PT_transform) bpy.types.register(BONE_PT_transform_locks) bpy.types.register(BONE_PT_bone) bpy.types.register(BONE_PT_deform) -bpy.types.register(BONE_PT_inverse_kinematics) -bpy.types.register(BONE_PT_iksolver_itasc) diff --git a/release/scripts/ui/buttons_object_constraint.py b/release/scripts/ui/buttons_object_constraint.py index e089cff264f..6be166e8af0 100644 --- a/release/scripts/ui/buttons_object_constraint.py +++ b/release/scripts/ui/buttons_object_constraint.py @@ -536,6 +536,145 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel): for con in ob.constraints: self.draw_constraint(context, con) +class BONE_PT_inverse_kinematics(ConstraintButtonsPanel): + __label__ = "Inverse Kinematics" + __default_closed__ = True + __context__ = "bone_constraint" + + def poll(self, context): + ob = context.object + bone = context.bone + + if ob and bone: + pchan = ob.pose.pose_channels[bone.name] + return pchan.has_ik + + return False + + def draw(self, context): + layout = self.layout + + ob = context.object + bone = context.bone + pchan = ob.pose.pose_channels[bone.name] + + row = layout.row() + row.itemR(ob.pose, "ik_solver") + + split = layout.split(percentage=0.25) + split.itemR(pchan, "ik_dof_x", text="X") + row = split.row() + row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True) + row.active = pchan.ik_dof_x + + split = layout.split(percentage=0.25) + row = split.row() + row.itemR(pchan, "ik_limit_x", text="Limit") + row.active = pchan.ik_dof_x + row = split.row(align=True) + row.itemR(pchan, "ik_min_x", text="") + row.itemR(pchan, "ik_max_x", text="") + row.active = pchan.ik_dof_x and pchan.ik_limit_x + + split = layout.split(percentage=0.25) + split.itemR(pchan, "ik_dof_y", text="Y") + row = split.row() + row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True) + row.active = pchan.ik_dof_y + + split = layout.split(percentage=0.25) + row = split.row() + row.itemR(pchan, "ik_limit_y", text="Limit") + row.active = pchan.ik_dof_y + row = split.row(align=True) + row.itemR(pchan, "ik_min_y", text="") + row.itemR(pchan, "ik_max_y", text="") + row.active = pchan.ik_dof_y and pchan.ik_limit_y + + split = layout.split(percentage=0.25) + split.itemR(pchan, "ik_dof_z", text="Z") + row = split.row() + row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True) + row.active = pchan.ik_dof_z + + split = layout.split(percentage=0.25) + row = split.row() + row.itemR(pchan, "ik_limit_z", text="Limit") + row.active = pchan.ik_dof_z + row = split.row(align=True) + row.itemR(pchan, "ik_min_z", text="") + row.itemR(pchan, "ik_max_z", text="") + row.active = pchan.ik_dof_z and pchan.ik_limit_z + split = layout.split() + split.itemR(pchan, "ik_stretch", text="Stretch", slider=True) + split.itemL() + + if ob.pose.ik_solver == "ITASC": + layout.itemL(text="Joint constraint:") + split = layout.split(percentage=0.3) + row = split.row() + row.itemR(pchan, "ik_rot_control", text="Rotation") + row = split.row() + row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True) + row.active = pchan.ik_rot_control + # not supported yet + #split = layout.split(percentage=0.3) + #row = split.row() + #row.itemR(pchan, "ik_lin_control", text="Size") + #row = split.row() + #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True) + #row.active = pchan.ik_lin_control + +class BONE_PT_iksolver_itasc(ConstraintButtonsPanel): + __label__ = "iTaSC parameters" + __default_closed__ = True + __context__ = "bone_constraint" + + def poll(self, context): + ob = context.object + bone = context.bone + + if ob and bone: + pchan = ob.pose.pose_channels[bone.name] + return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param + + return False + + def draw(self, context): + layout = self.layout + + ob = context.object + itasc = ob.pose.ik_param + + layout.itemR(itasc, "mode", expand=True) + simulation = itasc.mode == "SIMULATION" + if simulation: + layout.itemL(text="Reiteration:") + layout.itemR(itasc, "reiteration", expand=True) + + flow = layout.column_flow() + flow.itemR(itasc, "precision", text="Prec") + flow.itemR(itasc, "num_iter", text="Iter") + flow.active = not simulation or itasc.reiteration != "NEVER" + + if simulation: + layout.itemR(itasc, "auto_step") + row = layout.row() + if itasc.auto_step: + row.itemR(itasc, "min_step", text="Min") + row.itemR(itasc, "max_step", text="Max") + else: + row.itemR(itasc, "num_step") + + layout.itemR(itasc, "solver") + if simulation: + layout.itemR(itasc, "feedback") + layout.itemR(itasc, "max_velocity") + if itasc.solver == "DLS": + row = layout.row() + row.itemR(itasc, "dampmax", text="Damp", slider=True) + row.itemR(itasc, "dampeps", text="Eps", slider=True) + class BONE_PT_constraints(ConstraintButtonsPanel): __label__ = "Constraints" __context__ = "bone_constraint" @@ -558,4 +697,6 @@ class BONE_PT_constraints(ConstraintButtonsPanel): self.draw_constraint(context, con) bpy.types.register(OBJECT_PT_constraints) +bpy.types.register(BONE_PT_iksolver_itasc) +bpy.types.register(BONE_PT_inverse_kinematics) bpy.types.register(BONE_PT_constraints) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index b8dc9fd049d..87868eff812 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -535,7 +535,7 @@ void init_pose_itasc(bItasc *itasc) itasc->numiter = 100; itasc->numstep = 4; itasc->precision = 0.005f; - itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION|ITASC_SIMULATION; + itasc->flag = ITASC_AUTO_STEP|ITASC_INITIAL_REITERATION; itasc->feedback = 20.f; itasc->maxvel = 50.f; itasc->solver = ITASC_SOLVER_SDLS; diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 03ced839ebe..ecb2dba0197 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -801,6 +801,16 @@ static void rna_def_pose_channel(BlenderRNA *brna) static void rna_def_pose_itasc(BlenderRNA *brna) { + static const EnumPropertyItem prop_itasc_mode_items[]= { + {0, "ANIMATION", 0, "Animation", "Stateless solver computing pose starting from current action and non-IK constraints."}, + {ITASC_SIMULATION, "SIMULATION", 0, "Simulation", "Statefull solver running in real-time context and ignoring actions and non-IK constraints."}, + {0, NULL, 0, NULL, NULL}}; + static const EnumPropertyItem prop_itasc_reiteration_items[]= { + {0, "NEVER", 0, "Never", "The solver does not reiterate, not even on first frame (starts from rest pose)."}, + {ITASC_INITIAL_REITERATION, "INITIAL", 0, "Initial", "The solver reiterates (converges) on the first frame but not on subsequent frame."}, + {ITASC_INITIAL_REITERATION|ITASC_REITERATION, "ALWAYS", 0, "Always", "The solver reiterates (converges) on all frames."}, + {0, NULL, 0, NULL, NULL}}; + StructRNA *srna; PropertyRNA *prop; @@ -826,19 +836,16 @@ static void rna_def_pose_itasc(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Num steps", "Divides the frame interval into this many steps."); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update"); - prop= RNA_def_property(srna, "simulation", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_SIMULATION); - RNA_def_property_ui_text(prop, "Simulation", "Simulation mode: solver is statefull, runs in real-time context and ignores actions and non-IK constraints (i.e. solver is in full charge of the IK chain)."); + prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_itasc_mode_items); + RNA_def_property_ui_text(prop, "Mode", NULL); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update_rebuild"); - prop= RNA_def_property(srna, "initial_reiteration", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_INITIAL_REITERATION); - RNA_def_property_ui_text(prop, "Initial Reiteration", "Allow reiteration for initial frame."); - RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update"); - - prop= RNA_def_property(srna, "reiteration", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ITASC_REITERATION); - RNA_def_property_ui_text(prop, "Reiteration", "Allow reiteration for all frames."); + prop= RNA_def_property(srna, "reiteration", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, prop_itasc_reiteration_items); + RNA_def_property_ui_text(prop, "Reiteration", "Defines if the solver is allowed to reiterate (converges until precision is met) on none, first or all frames"); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Itasc_update"); prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From aa2cd95c1b1d8875444ae41112ca9ca06aa2950a Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Fri, 2 Oct 2009 07:20:33 +0000 Subject: Cocoa port : first Cocoa version of GHOST_DisplayManagerCocoa --- intern/ghost/intern/GHOST_DisplayManagerCocoa.h | 15 +-- intern/ghost/intern/GHOST_DisplayManagerCocoa.mm | 132 +++++++++++------------ 2 files changed, 65 insertions(+), 82 deletions(-) diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h index f67f51e1380..153ee401011 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h @@ -93,19 +93,12 @@ public: */ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting); -protected: - /** - * Returns a value from a dictionary. - * @param values Dictionary to return value from. - * @param key Key to return value for. - * @return The value for this key. - */ - long getValue(CFDictionaryRef values, CFStringRef key) const; - +protected: + //Do not cache values as OS X supports screen hot plug /** Cached number of displays. */ - CGDisplayCount m_numDisplays; + //CGDisplayCount m_numDisplays; /** Cached display id's for each display. */ - CGDirectDisplayID* m_displayIDs; + //CGDirectDisplayID* m_displayIDs; }; diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm index 82e31c01d25..f105928c9a3 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm @@ -21,22 +21,13 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Maarten Gribnau 09/2001 + Damien Plisson 10/2009 * * ***** END GPL LICENSE BLOCK ***** */ -/** - * Copyright (C) 2001 NaN Technologies B.V. - * @author Maarten Gribnau - * @date September 21, 2001 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include +#include #include "GHOST_DisplayManagerCocoa.h" #include "GHOST_Debug.h" @@ -46,23 +37,16 @@ GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void) { - if (::CGGetActiveDisplayList(0, NULL, &m_numDisplays) != CGDisplayNoErr) - { - m_numDisplays = 0; - m_displayIDs = NULL; - } - if (m_numDisplays > 0) - { - m_displayIDs = new CGDirectDisplayID [m_numDisplays]; - GHOST_ASSERT((m_displayIDs!=NULL), "GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(): memory allocation failed"); - ::CGGetActiveDisplayList(m_numDisplays, m_displayIDs, &m_numDisplays); - } } GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const { - numDisplays = (GHOST_TUns8) m_numDisplays; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + numDisplays = (GHOST_TUns8) [[NSScreen screens] count]; + + [pool drain]; return GHOST_kSuccess; } @@ -71,10 +55,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 disp { GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported"); - CFArrayRef displayModes; - displayModes = ::CGDisplayAvailableModes(m_displayIDs[display]); - CFIndex numModes = ::CFArrayGetCount(displayModes); - numSettings = (GHOST_TInt32)numModes; + numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel return GHOST_kSuccess; } @@ -82,43 +63,71 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 disp GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const { + //Note that only current display setting is available + NSScreen *askedDisplay; + GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported"); - CFArrayRef displayModes; - CGDirectDisplayID d = m_displayIDs[display]; - displayModes = ::CGDisplayAvailableModes(d); - //CFIndex numModes = ::CFArrayGetCount(displayModes);/*unused*/ - //GHOST_TInt32 numSettings = (GHOST_TInt32)numModes; /*unused*/ - CFDictionaryRef displayModeValues = (CFDictionaryRef)::CFArrayGetValueAtIndex(displayModes, index); - - setting.xPixels = getValue(displayModeValues, kCGDisplayWidth); - setting.yPixels = getValue(displayModeValues, kCGDisplayHeight); - setting.bpp = getValue(displayModeValues, kCGDisplayBitsPerPixel); - setting.frequency = getValue(displayModeValues, kCGDisplayRefreshRate); - + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (display == kMainDisplay) //Screen #0 may not be the main one + askedDisplay = [NSScreen mainScreen]; + else + askedDisplay = [[NSScreen screens] objectAtIndex:display]; + + if(askedDisplay == nil) { + [pool drain]; + return GHOST_kFailure; + } + + NSRect frame = [askedDisplay visibleFrame]; + setting.xPixels = frame.size.width; + setting.yPixels = frame.size.height; + + setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]); + + setting.frequency = 0; //No more CRT display... + #ifdef GHOST_DEBUG printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency); #endif // GHOST_DEBUG + [pool drain]; return GHOST_kSuccess; } GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const { + NSScreen *askedDisplay; + GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported"); - - CFDictionaryRef displayModeValues = ::CGDisplayCurrentMode(m_displayIDs[display]); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (display == kMainDisplay) //Screen #0 may not be the main one + askedDisplay = [NSScreen mainScreen]; + else + askedDisplay = [[NSScreen screens] objectAtIndex:display]; + + if(askedDisplay == nil) { + [pool drain]; + return GHOST_kFailure; + } - setting.xPixels = getValue(displayModeValues, kCGDisplayWidth); - setting.yPixels = getValue(displayModeValues, kCGDisplayHeight); - setting.bpp = getValue(displayModeValues, kCGDisplayBitsPerPixel); - setting.frequency = getValue(displayModeValues, kCGDisplayRefreshRate); + NSRect frame = [askedDisplay visibleFrame]; + setting.xPixels = frame.size.width; + setting.yPixels = frame.size.height; + + setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]); + + setting.frequency = 0; //No more CRT display... #ifdef GHOST_DEBUG printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency); #endif // GHOST_DEBUG + [pool drain]; return GHOST_kSuccess; } @@ -135,13 +144,15 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 d printf(" setting.frequency=%d\n", setting.frequency); #endif // GHOST_DEBUG - CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate( + //Display configuration is no more available in 10.6 + +/* CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate( m_displayIDs[display], (size_t)setting.bpp, (size_t)setting.xPixels, (size_t)setting.yPixels, (CGRefreshRate)setting.frequency, - NULL); + NULL);*/ #ifdef GHOST_DEBUG printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n"); @@ -151,28 +162,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 d printf(" setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate)); #endif // GHOST_DEBUG - CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues); + //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues); - return err == CGDisplayNoErr ? GHOST_kSuccess : GHOST_kFailure; -} - - -long GHOST_DisplayManagerCocoa::getValue(CFDictionaryRef values, CFStringRef key) const -{ - CFNumberRef numberValue = (CFNumberRef) CFDictionaryGetValue(values, key); - - if (!numberValue) - { - return -1; - } - - long intValue; - - if (!CFNumberGetValue(numberValue, kCFNumberLongType, &intValue)) - { - return -1; - } - - return intValue; + return /*err == CGDisplayNoErr ? GHOST_kSuccess :*/ GHOST_kFailure; } - -- cgit v1.2.3 From fbb47e86044be300357eda6d5ade98b97d5654e9 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 2 Oct 2009 11:09:05 +0000 Subject: Smoke: * Dissolve is back * Obstacles coming back (some bugs left i think) --- intern/smoke/intern/FLUID_3D.cpp | 16 ++-------- intern/smoke/intern/FLUID_3D_STATIC.cpp | 2 +- intern/smoke/intern/WTURBULENCE.cpp | 52 +++++++++++++++----------------- source/blender/blenkernel/intern/smoke.c | 8 +++++ 4 files changed, 36 insertions(+), 42 deletions(-) diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 8a32eaa2e68..bb2227801c7 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -399,16 +399,12 @@ void FLUID_3D::project() for (y = 1; y < _yRes - 1; y++, index += 2) for (x = 1; x < _xRes - 1; x++, index++) { - // if(!_obstacles[index]) + if(!_obstacles[index]) { _xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx; _yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx; _zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx; - }/* - else - { - _xVelocity[index] = _yVelocity[index] = _zVelocity[index] = 0.0f; - }*/ + } } if (_pressure) delete[] _pressure; @@ -497,23 +493,15 @@ void FLUID_3D::setObstaclePressure(float *_pressure) if (top && !bottom) { _pressure[index] += _pressure[index - _slabSize]; pcnt += 1.; - // _zVelocity[index] += - _zVelocity[index - _slabSize]; - // vp += 1.0; } if (!top && bottom) { _pressure[index] += _pressure[index + _slabSize]; pcnt += 1.; - // _zVelocity[index] += - _zVelocity[index + _slabSize]; - // vp += 1.0; } if(pcnt > 0.000001f) _pressure[index] /= pcnt; - // test - dg - // if(vp > 0.000001f) - // _zVelocity[index] /= vp; - // TODO? set correct velocity bc's // velocities are only set to zero right now // this means it's not a full no-slip boundary condition diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index 0215dfc417f..afeca2b1faa 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -296,7 +296,7 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const const int slabSize = res[0] * res[1]; // scale dt up to grid resolution -#if PARALLEL==1 +#if PARALLEL==1 && !_WIN32 #pragma omp parallel #pragma omp for schedule(static) #endif diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp index bcfc61856af..7ea4bde3884 100644 --- a/intern/smoke/intern/WTURBULENCE.cpp +++ b/intern/smoke/intern/WTURBULENCE.cpp @@ -735,19 +735,17 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // enlarge timestep to match grid const float dt = dtOrg * _amplify; const float invAmp = 1.0f / _amplify; - float *tempBig1 = new float[_totalCellsBig]; - float *tempBig2 = new float[_totalCellsBig]; - float *bigUx = new float[_totalCellsBig]; - float *bigUy = new float[_totalCellsBig]; - float *bigUz = new float[_totalCellsBig]; - float *_energy = new float[_totalCellsSm]; - float *highFreqEnergy = new float[_totalCellsSm]; - float *eigMin = new float[_totalCellsSm]; - float *eigMax = new float[_totalCellsSm]; - - memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm); - memset(eigMin, 0, sizeof(float)*_totalCellsSm); - memset(eigMax, 0, sizeof(float)*_totalCellsSm); + float *tempBig1 = (float *)calloc(_totalCellsBig, sizeof(float)); + float *tempBig2 = (float *)calloc(_totalCellsBig, sizeof(float)); + float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float)); + float *bigUy = (float *)calloc(_totalCellsBig, sizeof(float)); + float *bigUz = (float *)calloc(_totalCellsBig, sizeof(float)); + float *_energy = (float *)calloc(_totalCellsSm, sizeof(float)); + float *highFreqEnergy = (float *)calloc(_totalCellsSm, sizeof(float)); + float *eigMin = (float *)calloc(_totalCellsSm, sizeof(float)); + float *eigMax = (float *)calloc(_totalCellsSm, sizeof(float)); + + memset(_tcTemp, 0, sizeof(float)*_totalCellsSm); // prepare textures advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2); @@ -771,16 +769,16 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // parallel region setup float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. }; -#if PARALLEL==1 +#if PARALLEL==1 && !_WIN32 #pragma omp parallel #endif { float maxVelMag1 = 0.; -#if PARALLEL==1 +#if PARALLEL==1 && !_WIN32 const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */ #endif // vector noise main loop -#if PARALLEL==1 +#if PARALLEL==1 && !_WIN32 #pragma omp for schedule(static) #endif for (int zSmall = 0; zSmall < _zResSm; zSmall++) @@ -912,7 +910,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa bigUx[index] = bigUy[index] = bigUz[index] = 0.; } // xyz -#if PARALLEL==1 +#if PARALLEL==1 && !_WIN32 maxVelMagThreads[id] = maxVelMag1; #else maxVelMagThreads[0] = maxVelMag1; @@ -922,7 +920,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // compute maximum over threads float maxVelMag = maxVelMagThreads[0]; -#if PARALLEL==1 +#if PARALLEL==1 && !_WIN32 for (int i = 1; i < 8; i++) if (maxVelMag < maxVelMagThreads[i]) maxVelMag = maxVelMagThreads[i]; @@ -957,13 +955,13 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa SWAP_POINTERS(_densityBig, _densityBigOld); } // substep - delete[] tempBig1; - delete[] tempBig2; - delete[] bigUx; - delete[] bigUy; - delete[] bigUz; - delete[] _energy; - delete[] highFreqEnergy; + free(tempBig1); + free(tempBig2); + free(bigUx); + free(bigUy); + free(bigUz); + free(_energy); + free(highFreqEnergy); // wipe the density borders FLUID_3D::setZeroBorder(_densityBig, _resBig); @@ -973,8 +971,8 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // eigenvalues stored do not reflect the underlying texture coordinates resetTextureCoordinates(eigMin, eigMax); - delete[] eigMin; - delete[] eigMax; + free(eigMin); + free(eigMax); // output files // string prefix = string("./amplified.preview/density_bigxy_"); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 4f7a8cda81b..36168a201d7 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1183,7 +1183,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM // simulate the actual smoke (c++ code in intern/smoke) // DG: interesting commenting this line + deactivating loading of noise files if(framenr!=startframe) + { + if(sds->flags & MOD_SMOKE_DISSOLVE) + smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_step(sds->fluid, smd->time); + } // create shadows before writing cache so we get nice shadows for sstartframe, too if(get_lamp(scene, light)) @@ -1194,7 +1198,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM if(sds->wt) { if(framenr!=startframe) + { + if(sds->flags & MOD_SMOKE_DISSOLVE) + smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); + } cache_wt->flag |= PTCACHE_SIMULATION_VALID; cache_wt->simframe= framenr; -- cgit v1.2.3 From 0a374e667999e7cbb4fa465f256bda89dce87d03 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 2 Oct 2009 11:15:24 +0000 Subject: Anim Bugfixes: * Add F-Modifiers (for Graph Editor) was using a buggy poll() method. Silly typo. * Bone groups now get duplicated when duplicating an armature object --- source/blender/blenkernel/intern/action.c | 7 ++++++- source/blender/editors/space_graph/graph_utils.c | 3 +-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 87868eff812..7be763eae9d 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -511,16 +511,21 @@ void copy_pose (bPose **dst, bPose *src, int copycon) outPose= MEM_callocN(sizeof(bPose), "pose"); BLI_duplicatelist(&outPose->chanbase, &src->chanbase); + outPose->iksolver = src->iksolver; outPose->ikdata = NULL; outPose->ikparam = MEM_dupallocN(src->ikparam); - + + // TODO: rename this argument... if (copycon) { for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) { copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb pchan->constraints= listb; pchan->path= NULL; } + + /* for now, duplicate Bone Groups too when doing this */ + BLI_duplicatelist(&outPose->agroups, &src->agroups); } *dst=outPose; diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index 25087441b6a..ee4e371e1f1 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -292,7 +292,6 @@ int graphop_selected_fcurve_poll (bContext *C) ListBase anim_data = {NULL, NULL}; ScrArea *sa= CTX_wm_area(C); int filter, items; - short found = 0; /* firstly, check if in Graph Editor */ // TODO: also check for region? @@ -311,7 +310,7 @@ int graphop_selected_fcurve_poll (bContext *C) /* cleanup and return findings */ BLI_freelistN(&anim_data); - return found; + return 1; } /* ************************************************************** */ -- cgit v1.2.3 From 625da05e3a497b7d9bf34d830b7c05b0a715cfe3 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 2 Oct 2009 14:40:51 +0000 Subject: Smoke: * Fix loading issue of blend files with smoke collision objects (was disabled on purpose since it will be subject of change, but can be solved using do_versions() later) --- source/blender/blenkernel/intern/smoke.c | 241 ++++++++++++++------------- source/blender/blenloader/intern/readfile.c | 13 +- source/blender/blenloader/intern/writefile.c | 2 - 3 files changed, 132 insertions(+), 124 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 36168a201d7..f1fae4fa678 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -126,6 +126,7 @@ struct SmokeModifierData; // forward declerations static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct); void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); +static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs); #define TRI_UVOFFSET (1./4.) @@ -279,151 +280,157 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive { // init collision points SmokeCollSettings *scs = smd->coll; - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getFaceArray(dm); - int i = 0, divs = 0; - int *tridivs = NULL; - float cell_len = 1.0 / 50.0; // for res = 50 - int newdivs = 0; - int quads = 0, facecounter = 0; // copy obmat Mat4CpyMat4(scs->mat, ob->obmat); Mat4CpyMat4(scs->mat_old, ob->obmat); - // count quads - for(i = 0; i < dm->getNumFaces(dm); i++) - { - if(mface[i].v4) - quads++; - } + fill_scs_points(ob, dm, scs); + } + + if(!smd->coll->bvhtree) + { + smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 ); + } + return 1; + } - calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumFaces(dm), dm->getNumFaces(dm) + quads, &tridivs, cell_len); + return 1; +} - // count triangle divisions - for(i = 0; i < dm->getNumFaces(dm) + quads; i++) - { - divs += (tridivs[3 * i] + 1) * (tridivs[3 * i + 1] + 1) * (tridivs[3 * i + 2] + 1); - } +static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) +{ + MVert *mvert = dm->getVertArray(dm); + MFace *mface = dm->getFaceArray(dm); + int i = 0, divs = 0; + int *tridivs = NULL; + float cell_len = 1.0 / 50.0; // for res = 50 + int newdivs = 0; + int quads = 0, facecounter = 0; + + // count quads + for(i = 0; i < dm->getNumFaces(dm); i++) + { + if(mface[i].v4) + quads++; + } + + calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumFaces(dm), dm->getNumFaces(dm) + quads, &tridivs, cell_len); + + // count triangle divisions + for(i = 0; i < dm->getNumFaces(dm) + quads; i++) + { + divs += (tridivs[3 * i] + 1) * (tridivs[3 * i + 1] + 1) * (tridivs[3 * i + 2] + 1); + } - // printf("divs: %d\n", divs); + // printf("divs: %d\n", divs); - scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints"); + scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints"); - for(i = 0; i < dm->getNumVerts(dm); i++) + for(i = 0; i < dm->getNumVerts(dm); i++) + { + float tmpvec[3]; + VECCOPY(tmpvec, mvert[i].co); + Mat4MulVecfl (ob->obmat, tmpvec); + VECCOPY(&scs->points[i * 3], tmpvec); + } + + for(i = 0, facecounter = 0; i < dm->getNumFaces(dm); i++) + { + int again = 0; + do + { + int j, k; + int divs1 = tridivs[3 * facecounter + 0]; + int divs2 = tridivs[3 * facecounter + 1]; + //int divs3 = tridivs[3 * facecounter + 2]; + float side1[3], side2[3], trinormorg[3], trinorm[3]; + + if(again == 1 && mface[i].v4) { - float tmpvec[3]; - VECCOPY(tmpvec, mvert[i].co); - Mat4MulVecfl (ob->obmat, tmpvec); - VECCOPY(&scs->points[i * 3], tmpvec); + VECSUB(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); + VECSUB(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); } - - for(i = 0, facecounter = 0; i < dm->getNumFaces(dm); i++) + else + { + VECSUB(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); + VECSUB(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); + } + + Crossf(trinormorg, side1, side2); + Normalize(trinormorg); + VECCOPY(trinorm, trinormorg); + VecMulf(trinorm, 0.25 * cell_len); + + for(j = 0; j <= divs1; j++) { - int again = 0; - do + for(k = 0; k <= divs2; k++) { - int j, k; - int divs1 = tridivs[3 * facecounter + 0]; - int divs2 = tridivs[3 * facecounter + 1]; - //int divs3 = tridivs[3 * facecounter + 2]; - float side1[3], side2[3], trinormorg[3], trinorm[3]; + float p1[3], p2[3], p3[3], p[3]={0,0,0}; + const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); + const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); + float tmpvec[3]; - if(again == 1 && mface[i].v4) - { - VECSUB(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - VECSUB(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); - } - else + if(uf+vf > 1.0) { - VECSUB(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); - VECSUB(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); + // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); + continue; } - Crossf(trinormorg, side1, side2); - Normalize(trinormorg); - VECCOPY(trinorm, trinormorg); - VecMulf(trinorm, 0.25 * cell_len); - - for(j = 0; j <= divs1; j++) + VECCOPY(p1, mvert[ mface[i].v1 ].co); + if(again == 1 && mface[i].v4) { - for(k = 0; k <= divs2; k++) - { - float p1[3], p2[3], p3[3], p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } - - VECCOPY(p1, mvert[ mface[i].v1 ].co); - if(again == 1 && mface[i].v4) - { - VECCOPY(p2, mvert[ mface[i].v3 ].co); - VECCOPY(p3, mvert[ mface[i].v4 ].co); - } - else - { - VECCOPY(p2, mvert[ mface[i].v2 ].co); - VECCOPY(p3, mvert[ mface[i].v3 ].co); - } - - VecMulf(p1, (1.0-uf-vf)); - VecMulf(p2, uf); - VecMulf(p3, vf); - - VECADD(p, p1, p2); - VECADD(p, p, p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - VECCOPY(tmpvec, p); - VECADD(tmpvec, tmpvec, trinorm); - Mat4MulVecfl (ob->obmat, tmpvec); - VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - VECCOPY(tmpvec, p); - VECSUB(tmpvec, tmpvec, trinorm); - Mat4MulVecfl (ob->obmat, tmpvec); - VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - } + VECCOPY(p2, mvert[ mface[i].v3 ].co); + VECCOPY(p3, mvert[ mface[i].v4 ].co); } - - if(again == 0 && mface[i].v4) - again++; else - again = 0; - - facecounter++; + { + VECCOPY(p2, mvert[ mface[i].v2 ].co); + VECCOPY(p3, mvert[ mface[i].v3 ].co); + } - } while(again!=0); + VecMulf(p1, (1.0-uf-vf)); + VecMulf(p2, uf); + VecMulf(p3, vf); + + VECADD(p, p1, p2); + VECADD(p, p, p3); + + if(newdivs > divs) + printf("mem problem\n"); + + // mMovPoints.push_back(p + trinorm); + VECCOPY(tmpvec, p); + VECADD(tmpvec, tmpvec, trinorm); + Mat4MulVecfl (ob->obmat, tmpvec); + VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); + newdivs++; + + if(newdivs > divs) + printf("mem problem\n"); + + // mMovPoints.push_back(p - trinorm); + VECCOPY(tmpvec, p); + VECSUB(tmpvec, tmpvec, trinorm); + Mat4MulVecfl (ob->obmat, tmpvec); + VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); + newdivs++; + } } - scs->numpoints = dm->getNumVerts(dm) + newdivs; + if(again == 0 && mface[i].v4) + again++; + else + again = 0; - MEM_freeN(tridivs); - } + facecounter++; - if(!smd->coll->bvhtree) - { - smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getFaceArray(dm), dm->getNumFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 ); - } - return 1; + } while(again!=0); } - return 1; + scs->numpoints = dm->getNumVerts(dm) + newdivs; + + MEM_freeN(tridivs); } /*! init triangle divisions */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6fce17a4892..b40c7e453c0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3792,12 +3792,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) { smd->flow = NULL; smd->domain = NULL; - smd->coll = NULL; - /* smd->coll = newdataadr(fd, smd->coll); - smd->coll->points = NULL; - smd->coll->numpoints = 0; - */ + if(smd->coll) + { + smd->coll->points = NULL; + smd->coll->numpoints = 0; + } + else + smd->type = 0; + } } else if (md->type==eModifierType_Collision) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 52870420833..3bd8b24eeb6 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1151,10 +1151,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain); else if(smd->type & MOD_SMOKE_TYPE_FLOW) writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow); - /* else if(smd->type & MOD_SMOKE_TYPE_COLL) writestruct(wd, DATA, "SmokeCollSettings", 1, smd->coll); - */ if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { -- cgit v1.2.3 From 9ac8a1368f2741caf7bdc57b7142c0bc617c42bc Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 2 Oct 2009 15:27:26 +0000 Subject: Fix for [#19524] Lamp icons are not updated in outliner. --- source/blender/editors/space_outliner/space_outliner.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index e7e6c2d0128..eb0e9dafbaa 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -137,10 +137,15 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn) /* all actions now, todo: check outliner view mode? */ ED_region_tag_redraw(ar); break; + case NC_LAMP: + /* For updating lamp icons, when changing lamp type */ + if(wmn->data == ND_LIGHTING_DRAW) + ED_region_tag_redraw(ar); + break; case NC_SPACE: if(wmn->data == ND_SPACE_OUTLINER) ED_region_tag_redraw(ar); - break; + break; } } -- cgit v1.2.3 From ca54ea078ea6b9d7e860ffa48f35313a61735474 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Fri, 2 Oct 2009 15:51:25 +0000 Subject: * due to the setup of headers in mingw 4.4.0, includes could mess up. Making sure that windows.h isn't included where it shouln't (outside of __cplusplus) --- source/gameengine/VideoTexture/VideoFFmpeg.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index fbd04e7e1fc..b56984588c1 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -24,6 +24,7 @@ http://www.gnu.org/copyleft/lesser.txt. #ifdef WITH_FFMPEG extern "C" { +#undef __cplusplus #include #include #include @@ -32,6 +33,7 @@ extern "C" { #include "DNA_listBase.h" #include "BLI_threads.h" #include "BLI_blenlib.h" +#define __cplusplus } -- cgit v1.2.3 From 44b74fa0acbd2dbafebc5e8bd9990661bd436cf0 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 2 Oct 2009 20:15:25 +0000 Subject: Fixed [#19506] Missing buttons : Curve Guide. Jahka: please check on the Kink type and axis RNA Wrapping. Todo: Make Curve Guide Field only available for Curve Objects. --- release/scripts/ui/buttons_physics_field.py | 41 +++++++---- source/blender/makesrna/intern/rna_object_force.c | 89 +++++++++++++++++++++-- 2 files changed, 111 insertions(+), 19 deletions(-) diff --git a/release/scripts/ui/buttons_physics_field.py b/release/scripts/ui/buttons_physics_field.py index 24740acc68f..9aec0404ab1 100644 --- a/release/scripts/ui/buttons_physics_field.py +++ b/release/scripts/ui/buttons_physics_field.py @@ -21,8 +21,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel): ob = context.object field = ob.field - - #layout.active = field.enabled split = layout.split(percentage=0.2) split.itemL(text="Type:") @@ -39,7 +37,33 @@ class PHYSICS_PT_field(PhysicButtonsPanel): if field.type == 'NONE': return # nothing to draw elif field.type == 'GUIDE': - layout.itemR(field, "guide_path_add") + col = split.column() + col.itemR(field, "guide_minimum") + col.itemR(field, "guide_free") + col.itemR(field, "falloff_power") + col.itemR(field, "guide_path_add") + + col = split.column() + col.itemL(text="Clumping:") + col.itemR(field, "guide_clump_amount") + col.itemR(field, "guide_clump_shape") + + row = layout.row() + row.itemR(field, "use_max_distance") + sub = row.row() + sub.active = field.use_max_distance + sub.itemR(field, "maximum_distance") + + layout.itemS() + + layout.itemR(field, "guide_kink_type") + if (field.guide_kink_type != "NONE"): + layout.itemR(field, "guide_kink_axis") + + flow = layout.column_flow() + flow.itemR(field, "guide_kink_frequency") + flow.itemR(field, "guide_kink_shape") + flow.itemR(field, "guide_kink_amplitude") elif field.type == 'TEXTURE': col = split.column() col.itemR(field, "strength") @@ -102,17 +126,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel): sub = col.column() sub.active = field.use_radial_max sub.itemR(field, "radial_maximum", text="Distance") - - #if ob.type in 'CURVE': - #if field.type == 'GUIDE': - #colsub = col.column(align=True) - - #if field.type != 'NONE': - #layout.itemR(field, "strength") - - #if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', "LENNARDj"): - #if ob.type in ('MESH', 'SURFACE', 'FONT', 'CURVE'): - #layout.itemR(field, "surface") class PHYSICS_PT_collision(PhysicButtonsPanel): __label__ = "Collision" diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 652a80a24eb..022c04240af 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -906,6 +906,22 @@ static void rna_def_field(BlenderRNA *brna) {PFIELD_Z_POS, "POSITIVE", 0, "+Z", ""}, {PFIELD_Z_NEG, "NEGATIVE", 0, "-Z", ""}, {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem guide_kink_items[] = { + {0, "NONE", 0, "Nothing", ""}, + {1, "CURL", 0, "Curl", ""}, + {2, "RADIAL", 0, "Radial", ""}, + {3, "WAVE", 0, "Wave", ""}, + {4, "BRAID", 0, "Braid", ""}, + {5, "ROTATION", 0, "Rotation", ""}, + {6, "ROLL", 0, "Roll", ""}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem guide_kink_axis_items[] = { + {0, "X", 0, "X", ""}, + {1, "Y", 0, "Y", ""}, + {2, "Z", 0, "Z", ""}, + {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "FieldSettings", NULL); RNA_def_struct_sdna(srna, "PartDeflect"); @@ -1067,11 +1083,6 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Max", "Use a maximum radial distance for the field to work"); // "Use a maximum angle for the field to work" RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); - - prop= RNA_def_property(srna, "guide_path_add", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_ADD); - RNA_def_property_ui_text(prop, "Additive", "Based on distance/falloff it adds a portion of the entire path"); - RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); prop= RNA_def_property(srna, "use_coordinates", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_OBJECT); @@ -1110,6 +1121,74 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Texture", "Texture to use as force"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + /********** Curve Guide Field Settings **********/ + + prop= RNA_def_property(srna, "guide_minimum", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "f_strength"); + RNA_def_property_range(prop, 0.0f, 1000.0f); + RNA_def_property_ui_text(prop, "Minimum Distance", "The distance from which particles are affected fully."); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_free", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "free_end"); + RNA_def_property_range(prop, 0.0f, 0.99f); + RNA_def_property_ui_text(prop, "Free", "Guide-free time from particle life's end"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_path_add", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_ADD); + RNA_def_property_ui_text(prop, "Additive", "Based on distance/falloff it adds a portion of the entire path"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + /* Clump Settings */ + + prop= RNA_def_property(srna, "guide_clump_amount", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "clump_fac"); + RNA_def_property_range(prop, -1.0f, 1.0f); + RNA_def_property_ui_text(prop, "Amount", "Amount of clumpimg"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_clump_shape", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "clump_pow"); + RNA_def_property_range(prop, -0.999f, 0.999f); + RNA_def_property_ui_text(prop, "Shape", "Shape of clumpimg"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + /* Kink Settings */ + + prop= RNA_def_property(srna, "guide_kink_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "kink"); + RNA_def_property_enum_items(prop, guide_kink_items); + RNA_def_property_ui_text(prop, "Kink", "Type of periodic offset on the curve"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_kink_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "kink_axis"); + RNA_def_property_enum_items(prop, guide_kink_axis_items); + RNA_def_property_ui_text(prop, "Axis", "Which axis to use for offset"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_kink_frequency", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "kink_freq"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_text(prop, "Frequency", "The frequency of the offset (1/total length)"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_kink_shape", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "kink_shape"); + RNA_def_property_range(prop, -0.999f, 0.999f); + RNA_def_property_ui_text(prop, "Shape", "djust the offset to the beginning/end"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "guide_kink_amplitude", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "kink_amp"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_text(prop, "Amplitude", "The amplitude of the offset"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + /* Variables used for Curve Guide, allready wrapped, used for other fields too */ + // falloff_power, use_max_distance, maximum_distance } static void rna_def_game_softbody(BlenderRNA *brna) -- cgit v1.2.3 From 72554c5dbbf43640981fa59ddcb5df2a4256811a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 2 Oct 2009 23:28:58 +0000 Subject: Quick Animation Editors Bugfix: The settings for expanding the set of materials and/or particles on Objects were inverted, resulting in the wrong icon being shown. --- source/blender/editors/animation/anim_channels_defines.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 8f8700cc43b..427fa47923f 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -909,7 +909,6 @@ static int acf_fillmatd_setting_flag(int setting, short *neg) switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg= 1; return OB_ADS_SHOWMATS; default: /* unsupported */ @@ -953,7 +952,6 @@ static int acf_fillpartd_setting_flag(int setting, short *neg) switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg= 1; return OB_ADS_SHOWPARTS; default: /* unsupported */ -- cgit v1.2.3 From 97d8839ad565bff1a02da59a1a2f97264ba79e68 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 2 Oct 2009 23:36:02 +0000 Subject: F-Modifiers: Fix for Function Generator's "type" field not working The field in RNA got renamed, but the UI code didn't get corrected, so the field for this wasn't working --- source/blender/editors/animation/fmodifier_ui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 4aff26105f3..65c73355ad7 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -258,7 +258,7 @@ static void draw_modifier__fn_generator(uiLayout *layout, ID *id, FModifier *fcm /* add the settings */ col= uiLayoutColumn(layout, 1); - uiItemR(col, "", 0, &ptr, "type", 0); + uiItemR(col, "", 0, &ptr, "function_type", 0); uiItemR(col, NULL, 0, &ptr, "additive", UI_ITEM_R_TOGGLE); col= uiLayoutColumn(layout, 0); // no grouping for now -- cgit v1.2.3 From f4c697cf7fc1b3bd3e040b90921fafbee8bafa4a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 3 Oct 2009 04:21:38 +0000 Subject: Keying Sets UI: Added a way to view and edit Keying Sets via the Scene Buttons. These are still some tweaks needed to make this really workable, but should still work well enough for simply viewing and tweaking existing Keying Sets created using other means. Additional bugfixes: * Adjusted the size of labels on properties that had a 'label' for their name. Now it uses 1/3 of the total width instead, which looks much better for most cases. * Added missing entries for adding Force Fields from the Info-header 'Add' menu. At some point we should unify this menu with the popup operator's one, since this is exactly the kind of situation we had hoped in avoid with new UI architectures. * Moved all the operator defines for keyframing stuff to the 'intern' anim header instead --- release/scripts/ui/buttons_scene.py | 88 +++++++++ release/scripts/ui/space_info.py | 4 + source/blender/blenkernel/intern/anim_sys.c | 2 +- source/blender/editors/animation/anim_intern.h | 40 ++++ source/blender/editors/animation/anim_ops.c | 14 +- source/blender/editors/animation/keyingsets.c | 209 +++++++++++++++++++++ source/blender/editors/include/ED_keyframing.h | 32 ---- .../blender/editors/interface/interface_layout.c | 2 +- source/blender/makesdna/DNA_anim_types.h | 6 +- source/blender/makesrna/intern/rna_animation.c | 56 ++++++ 10 files changed, 414 insertions(+), 39 deletions(-) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 2fbd176e36a..6467836961c 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -1,6 +1,14 @@ import bpy +class SceneButtonsPanel(bpy.types.Panel): + __space_type__ = 'PROPERTIES' + __region_type__ = 'WINDOW' + __context__ = "scene" + + def poll(self, context): + return (context.scene != None) + class RenderButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -450,6 +458,84 @@ class SCENE_PT_unit(RenderButtonsPanel): row.active = (unit.system != 'NONE') row.itemR(unit, "scale_length", text="Scale") row.itemR(unit, "use_separate") + +class SCENE_PT_keying_sets(SceneButtonsPanel): + __label__ = "Keying Sets" + __default_closed__ = True + + def draw(self, context): + layout = self.layout + + scene = context.scene + + row = layout.row() + + col = row.column() + col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2) + + col = row.column(align=True) + col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="") + col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="") + + ks = scene.active_keying_set + if ks: + row = layout.row() + + col = row.column() + col.itemR(ks, "name") + col.itemR(ks, "absolute") + + col = row.column() + col.itemL(text="Keyframing Settings:") + col.itemR(ks, "insertkey_needed", text="Needed") + col.itemR(ks, "insertkey_visual", text="Visual") + +class SCENE_PT_keying_set_paths(SceneButtonsPanel): + __label__ = "Active Keying Set" + __default_closed__ = True + + def poll(self, context): + return (context.scene != None) and (context.scene.active_keying_set != None) + + def draw(self, context): + layout = self.layout + + scene = context.scene + ks = scene.active_keying_set + + row = layout.row() + + col = row.column() + col.template_list(ks, "paths", ks, "active_path_index", rows=2) + + col = row.column(align=True) + col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="") + col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="") + + ksp = ks.active_path + if ksp: + col = layout.column() + col.itemL(text="Target:") + col.itemR(ksp, "id") + col.itemR(ksp, "rna_path") + + + row = layout.row() + + col = row.column() + col.itemL(text="Array Target:") + col.itemR(ksp, "entire_array") + if ksp.entire_array == False: + col.itemR(ksp, "array_index") + + col = row.column() + col.itemL(text="F-Curve Grouping:") + col.itemR(ksp, "grouping") + if ksp.grouping == 'NAMED': + col.itemR(ksp, "group") + + + class SCENE_PT_physics(RenderButtonsPanel): __label__ = "Gravity" @@ -479,4 +565,6 @@ bpy.types.register(SCENE_PT_performance) bpy.types.register(SCENE_PT_post_processing) bpy.types.register(SCENE_PT_stamp) bpy.types.register(SCENE_PT_unit) +bpy.types.register(SCENE_PT_keying_sets) +bpy.types.register(SCENE_PT_keying_set_paths) bpy.types.register(SCENE_PT_physics) diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index c1a2b1f4275..49261981ac2 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -144,6 +144,10 @@ class INFO_MT_add(bpy.types.Menu): layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA') layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP') + + layout.itemS() + + layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY') class INFO_MT_game(bpy.types.Menu): __space_type__ = 'INFO' diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index ab902bbbae5..47f5dd116d7 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -211,7 +211,7 @@ static void make_local_strips(ListBase *strips) for (strip=strips->first; strip; strip=strip->next) { if (strip->act) make_local_action(strip->act); - //if (strip->remap && strip->remap->target) make_local_action(strip->remap->target); + if (strip->remap && strip->remap->target) make_local_action(strip->remap->target); make_local_strips(&strip->strips); } diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index 462ef76ea8d..853aeb6c8f3 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -39,4 +39,44 @@ short keyingset_context_ok_poll(bContext *C, KeyingSet *ks); /* Main KeyingSet operations API call */ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks); +/* Operator Define Prototypes ------------------- */ + +/* Main Keyframe Management operators: + * These handle keyframes management from various spaces. They only make use of + * Keying Sets. + */ +void ANIM_OT_insert_keyframe(struct wmOperatorType *ot); +void ANIM_OT_delete_keyframe(struct wmOperatorType *ot); + +/* Main Keyframe Management operators: + * These handle keyframes management from various spaces. They will handle the menus + * required for each space. + */ +void ANIM_OT_insert_keyframe_menu(struct wmOperatorType *ot); +void ANIM_OT_delete_keyframe_v3d(struct wmOperatorType *ot); + +/* Keyframe managment operators for UI buttons (RMB menu). */ +void ANIM_OT_insert_keyframe_button(struct wmOperatorType *ot); +void ANIM_OT_delete_keyframe_button(struct wmOperatorType *ot); + +/* .......... */ + +/* KeyingSet managment operators for UI buttons (RMB menu) */ +void ANIM_OT_add_keyingset_button(struct wmOperatorType *ot); +void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot); + +/* KeyingSet management operators for RNA collections/UI buttons */ +void ANIM_OT_keying_set_add(struct wmOperatorType *ot); +void ANIM_OT_keying_set_remove(struct wmOperatorType *ot); +void ANIM_OT_keying_set_path_add(struct wmOperatorType *ot); +void ANIM_OT_keying_set_path_remove(struct wmOperatorType *ot); + +/* .......... */ + +/* Driver management operators for UI buttons (RMB menu) */ +void ANIM_OT_add_driver_button(struct wmOperatorType *ot); +void ANIM_OT_remove_driver_button(struct wmOperatorType *ot); +void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); +void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); + #endif // ANIM_INTERN_H diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index a4038028062..4317204f347 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -31,6 +31,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -41,6 +42,7 @@ #include "BKE_context.h" #include "BKE_utildefines.h" +#include "BKE_sound.h" #include "UI_interface.h" #include "UI_view2d.h" @@ -52,11 +54,11 @@ #include "WM_types.h" #include "ED_anim_api.h" -#include "ED_keyframing.h" // XXX remove? +#include "ED_keyframing.h" #include "ED_markers.h" #include "ED_screen.h" -#include "BKE_sound.h" +#include "anim_intern.h" /* ********************** frame change operator ***************************/ @@ -395,15 +397,21 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_delete_keyframe_v3d); WM_operatortype_append(ANIM_OT_insert_keyframe_button); WM_operatortype_append(ANIM_OT_delete_keyframe_button); - + WM_operatortype_append(ANIM_OT_add_driver_button); WM_operatortype_append(ANIM_OT_remove_driver_button); WM_operatortype_append(ANIM_OT_copy_driver_button); WM_operatortype_append(ANIM_OT_paste_driver_button); + WM_operatortype_append(ANIM_OT_add_keyingset_button); WM_operatortype_append(ANIM_OT_remove_keyingset_button); + + WM_operatortype_append(ANIM_OT_keying_set_add); + WM_operatortype_append(ANIM_OT_keying_set_remove); + WM_operatortype_append(ANIM_OT_keying_set_path_add); + WM_operatortype_append(ANIM_OT_keying_set_path_remove); } void ED_keymap_anim(wmWindowManager *wm) diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 81259ae7ced..99cdf0a86f4 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -77,6 +77,215 @@ #include "anim_intern.h" +/* ************************************************** */ +/* KEYING SETS - OPERATORS (for use in UI panels) */ +/* These operators are really duplication of existing functionality, but just for completeness, + * they're here too, and will give the basic data needed... + */ + +/* poll callback for adding default KeyingSet */ +static int keyingset_poll_default_add (bContext *C) +{ + /* as long as there's an active Scene, it's fine */ + return (CTX_data_scene(C) != NULL); +} + +/* poll callback for editing active KeyingSet */ +static int keyingset_poll_active_edit (bContext *C) +{ + Scene *scene= CTX_data_scene(C); + + if (scene == NULL) + return 0; + + /* there must be an active KeyingSet (and KeyingSets) */ + return ((scene->active_keyingset > 0) && (scene->keyingsets.first)); +} + +/* poll callback for editing active KeyingSet Path */ +static int keyingset_poll_activePath_edit (bContext *C) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks; + + if (scene == NULL) + return 0; + if (scene->active_keyingset <= 0) + return 0; + else + ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* there must be an active KeyingSet and an active path */ + return ((ks) && (ks->paths.first) && (ks->active_path > 0)); +} + + +/* Add a Default (Empty) Keying Set ------------------------- */ + +static int add_default_keyingset_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + short flag=0, keyingflag=0; + + /* validate flags + * - absolute KeyingSets should be created by default + */ + flag |= KEYINGSET_ABSOLUTE; + + if (IS_AUTOKEY_FLAG(AUTOMATKEY)) + keyingflag |= INSERTKEY_MATRIX; + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) + keyingflag |= INSERTKEY_NEEDED; + + /* call the API func, and set the active keyingset index */ + BKE_keyingset_add(&scene->keyingsets, NULL, flag, keyingflag); + + scene->active_keyingset= BLI_countlist(&scene->keyingsets); + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keying_set_add (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Empty Keying Set"; + ot->idname= "ANIM_OT_keying_set_add"; + ot->description= "Add a new (empty) Keying Set to the active Scene."; + + /* callbacks */ + ot->exec= add_default_keyingset_exec; + ot->poll= keyingset_poll_default_add; +} + +/* Remove 'Active' Keying Set ------------------------- */ + +static int remove_active_keyingset_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks; + + /* verify the Keying Set to use: + * - use the active one + * - return error if it doesn't exist + */ + if (scene->active_keyingset == 0) { + BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove"); + return OPERATOR_CANCELLED; + } + else + ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* free KeyingSet's data, then remove it from the scene */ + BKE_keyingset_free(ks); + + BLI_freelinkN(&scene->keyingsets, ks); + scene->active_keyingset= 0; + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keying_set_remove (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Removed Active Keying Set"; + ot->idname= "ANIM_OT_keying_set_remove"; + ot->description= "Remove the active Keying Set."; + + /* callbacks */ + ot->exec= remove_active_keyingset_exec; + ot->poll= keyingset_poll_active_edit; +} + +/* Add Empty Keying Set Path ------------------------- */ + +static int add_empty_ks_path_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks; + KS_Path *ksp; + + /* verify the Keying Set to use: + * - use the active one + * - return error if it doesn't exist + */ + if (scene->active_keyingset == 0) { + BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to"); + return OPERATOR_CANCELLED; + } + else + ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* don't use the API method for this, since that checks on values... */ + ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty"); + BLI_addtail(&ks->paths, ksp); + ks->active_path= BLI_countlist(&ks->paths) + 1; + + ksp->groupmode= KSP_GROUP_KSNAME; // XXX? + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keying_set_path_add (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Empty Keying Set Path"; + ot->idname= "ANIM_OT_keying_set_path_add"; + ot->description= "Add empty path to active Keying Set"; + + /* callbacks */ + ot->exec= add_empty_ks_path_exec; + ot->poll= keyingset_poll_active_edit; +} + +/* Remove Active Keying Set Path ------------------------- */ + +static int remove_active_ks_path_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + KeyingSet *ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* if there is a KeyingSet, find the nominated path to remove */ + if (ks) { + KS_Path *ksp= BLI_findlink(&ks->paths, ks->active_path-1); + + if (ksp) { + /* NOTE: sync this code with BKE_keyingset_free() */ + { + /* free RNA-path info */ + MEM_freeN(ksp->rna_path); + + /* free path itself */ + BLI_freelinkN(&ks->paths, ksp); + } + + /* fix active path index */ + ks->active_path= 0; + } + else { + BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove"); + return OPERATOR_CANCELLED; + } + } + else { + BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from"); + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +void ANIM_OT_keying_set_path_remove (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Active Keying Set Path"; + ot->idname= "ANIM_OT_keying_set_path_remove"; + ot->description= "Remove active Path from active Keying Set."; + + /* callbacks */ + ot->exec= remove_active_ks_path_exec; + ot->poll= keyingset_poll_activePath_edit; +} + /* ************************************************** */ /* KEYING SETS - OPERATORS (for use in UI menus) */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index d30fccfe4de..92dda4162cc 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -97,26 +97,6 @@ short insert_keyframe(struct ID *id, struct bAction *act, const char group[], co */ short delete_keyframe(struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag); -/* -------- */ - -/* Main Keyframe Management operators: - * These handle keyframes management from various spaces. They only make use of - * Keying Sets. - */ -void ANIM_OT_insert_keyframe(struct wmOperatorType *ot); -void ANIM_OT_delete_keyframe(struct wmOperatorType *ot); - -/* Main Keyframe Management operators: - * These handle keyframes management from various spaces. They will handle the menus - * required for each space. - */ -void ANIM_OT_insert_keyframe_menu(struct wmOperatorType *ot); -void ANIM_OT_delete_keyframe_v3d(struct wmOperatorType *ot); - -/* Keyframe managment operators for UI buttons. */ -void ANIM_OT_insert_keyframe_button(struct wmOperatorType *ot); -void ANIM_OT_delete_keyframe_button(struct wmOperatorType *ot); - /* ************ Keying Sets ********************** */ /* temporary struct to gather data combos to keyframe @@ -155,12 +135,6 @@ struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, cha /* Initialise builtin KeyingSets on startup */ void init_builtin_keyingsets(void); -/* -------- */ - -/* KeyingSet managment operators for UI buttons. */ -void ANIM_OT_add_keyingset_button(struct wmOperatorType *ot); -void ANIM_OT_remove_keyingset_button(struct wmOperatorType *ot); - /* ************ Drivers ********************** */ /* Returns whether there is a driver in the copy/paste buffer to paste */ @@ -187,12 +161,6 @@ short ANIM_copy_driver(struct ID *id, const char rna_path[], int array_index, sh */ short ANIM_paste_driver(struct ID *id, const char rna_path[], int array_index, short flag); -/* Driver management operators for UI buttons */ -void ANIM_OT_add_driver_button(struct wmOperatorType *ot); -void ANIM_OT_remove_driver_button(struct wmOperatorType *ot); -void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); -void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); - /* ************ Auto-Keyframing ********************** */ /* Notes: * - All the defines for this (User-Pref settings and Per-Scene settings) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index e9160e0e416..11dfc44906a 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -492,7 +492,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i /* XXX UI_GetStringWidth is not accurate labelw= UI_GetStringWidth(name); CLAMP(labelw, w/4, 3*w/4);*/ - labelw= w/2; + labelw= w/3; uiDefBut(block, LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, ""); w= w-labelw; } diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 9921878e926..fedde34ae18 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -654,8 +654,10 @@ typedef struct KeyingSet { char name[64]; /* user-viewable name for KeyingSet (for menus, etc.) */ - int flag; /* settings for KeyingSet */ - int keyingflag; /* settings to supply insertkey() with */ + short flag; /* settings for KeyingSet */ + short keyingflag; /* settings to supply insertkey() with */ + + int active_path; /* index of the active path */ } KeyingSet; /* KeyingSet settings */ diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 4b2c11c2e0d..a62eef66cf0 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -96,6 +96,49 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value) ksp->rna_path= NULL; } + +static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + + /* only editable if there are some paths to change to */ + return (ks->paths.first != NULL); +} + +static PointerRNA rna_KeyingSet_active_ksPath_get(PointerRNA *ptr) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_KeyingSetPath, BLI_findlink(&ks->paths, ks->active_path-1)); +} + +static void rna_KeyingSet_active_ksPath_set(PointerRNA *ptr, PointerRNA value) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + KS_Path *ksp= (KS_Path*)value.data; + ks->active_path= BLI_findindex(&ks->paths, ksp) + 1; +} + +static int rna_KeyingSet_active_ksPath_index_get(PointerRNA *ptr) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + return MAX2(ks->active_path-1, 0); +} + +static void rna_KeyingSet_active_ksPath_index_set(PointerRNA *ptr, int value) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + ks->active_path= value+1; +} + +static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, int *max) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + + *min= 0; + *max= BLI_countlist(&ks->paths)-1; + *max= MAX2(0, *max); +} + #else @@ -127,6 +170,7 @@ static void rna_def_keyingset_path(BlenderRNA *brna) //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property setting."); + RNA_def_struct_name_property(srna, prop); // XXX this is the best indicator for now... prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE); //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable @@ -157,6 +201,18 @@ static void rna_def_keyingset(BlenderRNA *brna) RNA_def_property_struct_type(prop, "KeyingSetPath"); RNA_def_property_ui_text(prop, "Paths", "Keying Set Paths to define settings that get keyframed together."); + prop= RNA_def_property(srna, "active_path", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "KeyingSetPath"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_editable_func(prop, "rna_KeyingSet_active_ksPath_editable"); + RNA_def_property_pointer_funcs(prop, "rna_KeyingSet_active_ksPath_get", "rna_KeyingSet_active_ksPath_set", NULL); + RNA_def_property_ui_text(prop, "Active Keying Set", "Active Keying Set used to insert/delete keyframes."); + + prop= RNA_def_property(srna, "active_path_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "active_path"); + RNA_def_property_int_funcs(prop, "rna_KeyingSet_active_ksPath_index_get", "rna_KeyingSet_active_ksPath_index_set", "rna_KeyingSet_active_ksPath_index_range"); + RNA_def_property_ui_text(prop, "Active Path Index", "Current Keying Set index."); + /* Flags */ prop= RNA_def_property(srna, "builtin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); -- cgit v1.2.3 From 2cbf21b58243e2ce14a1b00c7a422a6245c00954 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Sat, 3 Oct 2009 11:19:14 +0000 Subject: UI tweaks *Fixed some spacing issues in 3D View and Outliner headers *Made the Bone properties layout consistent with Object properties *Put Rotation Mode menus below transformation channels, being less important. *Tiny layout tweak for area lamps --- release/scripts/ui/buttons_data_bone.py | 68 +++++++++++++++------- release/scripts/ui/buttons_data_lamp.py | 6 +- release/scripts/ui/buttons_object.py | 4 +- .../editors/space_outliner/outliner_header.c | 2 +- .../blender/editors/space_view3d/view3d_header.c | 7 ++- 5 files changed, 59 insertions(+), 28 deletions(-) diff --git a/release/scripts/ui/buttons_data_bone.py b/release/scripts/ui/buttons_data_bone.py index 12db3e7277d..e8041cc7393 100644 --- a/release/scripts/ui/buttons_data_bone.py +++ b/release/scripts/ui/buttons_data_bone.py @@ -48,7 +48,7 @@ class BONE_PT_transform(BoneButtonsPanel): else: pchan = ob.pose.pose_channels[context.bone.name] - layout.itemR(pchan, "rotation_mode") + row = layout.row() col = row.column() @@ -67,6 +67,8 @@ class BONE_PT_transform(BoneButtonsPanel): col.itemR(pchan, "rotation_euler", text="Rotation") row.column().itemR(pchan, "scale") + + layout.itemR(pchan, "rotation_mode") class BONE_PT_transform_locks(BoneButtonsPanel): __label__ = "Transform Locks" @@ -98,8 +100,8 @@ class BONE_PT_transform_locks(BoneButtonsPanel): row.column().itemR(pchan, "lock_scale") -class BONE_PT_bone(BoneButtonsPanel): - __label__ = "Bone" +class BONE_PT_relations(BoneButtonsPanel): + __label__ = "Relations" def draw(self, context): layout = self.layout @@ -115,7 +117,17 @@ class BONE_PT_bone(BoneButtonsPanel): pchan = ob.pose.pose_channels[context.bone.name] split = layout.split() - + + col = split.column() + col.itemL(text="Layers:") + col.itemR(bone, "layer", text="") + + col.itemS() + + if ob and pchan: + col.itemL(text="Bone Group:") + col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="") + col = split.column() col.itemL(text="Parent:") if context.bone: @@ -123,32 +135,47 @@ class BONE_PT_bone(BoneButtonsPanel): else: col.item_pointerR(bone, "parent", arm, "edit_bones", text="") - row = col.row() - row.active = bone.parent != None - row.itemR(bone, "connected") + sub = col.column() + sub.active = bone.parent != None + sub.itemR(bone, "connected") + sub.itemR(bone, "hinge", text="Inherit Rotation") + sub.itemR(bone, "inherit_scale", text="Inherit Scale") + + +class BONE_PT_display(BoneButtonsPanel): + __label__ = "Display" + + def poll(self, context): + return context.bone + + def draw(self, context): + layout = self.layout - col.itemL(text="Layers:") - col.itemR(bone, "layer", text="") + ob = context.object + bone = context.bone + arm = context.armature - col = split.column() - col.itemL(text="Inherit:") - col.itemR(bone, "hinge", text="Rotation") - col.itemR(bone, "inherit_scale", text="Scale") - col.itemL(text="Display:") - col.itemR(bone, "draw_wire", text="Wireframe") - col.itemR(bone, "hidden", text="Hide") + if not bone: + bone = context.edit_bone + pchan = None + else: + pchan = ob.pose.pose_channels[context.bone.name] if ob and pchan: - split = layout.split() + split = layout.split() + col = split.column() - col.itemL(text="Bone Group:") - col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="") + + col.itemR(bone, "draw_wire", text="Wireframe") + col.itemR(bone, "hidden", text="Hide") col = split.column() + col.itemL(text="Custom Shape:") col.itemR(pchan, "custom_shape", text="") + class BONE_PT_deform(BoneButtonsPanel): __label__ = "Deform" __default_closed__ = True @@ -201,5 +228,6 @@ class BONE_PT_deform(BoneButtonsPanel): bpy.types.register(BONE_PT_context_bone) bpy.types.register(BONE_PT_transform) bpy.types.register(BONE_PT_transform_locks) -bpy.types.register(BONE_PT_bone) +bpy.types.register(BONE_PT_relations) +bpy.types.register(BONE_PT_display) bpy.types.register(BONE_PT_deform) diff --git a/release/scripts/ui/buttons_data_lamp.py b/release/scripts/ui/buttons_data_lamp.py index 86ca5beb9b5..2879da8d8d5 100644 --- a/release/scripts/ui/buttons_data_lamp.py +++ b/release/scripts/ui/buttons_data_lamp.py @@ -249,7 +249,7 @@ class DATA_PT_area(DataButtonsPanel): split = layout.split() col = split.column() - col.itemR(lamp, "shape", text="") + col.row().itemR(lamp, "shape", expand=True) sub = col.column(align=True) if (lamp.shape == 'SQUARE'): @@ -273,9 +273,9 @@ class DATA_PT_spot(DataButtonsPanel): split = layout.split() col = split.column() - sub = col.column(align=True) + sub = col.column() sub.itemR(lamp, "spot_size", text="Size") - sub.itemR(lamp, "spot_blend", text="Blend") + sub.itemR(lamp, "spot_blend", text="Blend", slider=True) col.itemR(lamp, "square") col = split.column() diff --git a/release/scripts/ui/buttons_object.py b/release/scripts/ui/buttons_object.py index c069572aa28..d546ddb8fd8 100644 --- a/release/scripts/ui/buttons_object.py +++ b/release/scripts/ui/buttons_object.py @@ -26,7 +26,7 @@ class OBJECT_PT_transform(ObjectButtonsPanel): ob = context.object - layout.itemR(ob, "rotation_mode") + row = layout.row() @@ -43,6 +43,8 @@ class OBJECT_PT_transform(ObjectButtonsPanel): row.column().itemR(ob, "scale") + layout.itemR(ob, "rotation_mode") + class OBJECT_PT_transform_locks(ObjectButtonsPanel): __label__ = "Transform Locks" __default_closed__ = True diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c index d4eeaabd1d3..b60cc075869 100644 --- a/source/blender/editors/space_outliner/outliner_header.c +++ b/source/blender/editors/space_outliner/outliner_header.c @@ -228,7 +228,7 @@ void outliner_header_buttons(const bContext *C, ARegion *ar) xco += xmax; /* header text */ - xco += XIC*2; + xco += XIC; uiBlockSetEmboss(block, UI_EMBOSS); } diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 45828d654aa..19c48bb5006 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -2128,7 +2128,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) xco+= XIC+10; } uiBlockEndAlign(block); - header_xco_step(ar, &xco, &yco, &maxco, XIC+10); + header_xco_step(ar, &xco, &yco, &maxco, 10); } /* Snap */ @@ -2147,7 +2147,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); xco+= XIC; uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode"); - xco+= XIC+70; + xco+= XIC; } else { uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)"); xco+= XIC; @@ -2169,10 +2169,11 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,yco,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)"); xco+= XIC; uiBlockEndAlign(block); + header_xco_step(ar, &xco, &yco, &maxco, 10); if(v3d->drawtype > OB_WIRE) { uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,yco,XIC,YIC, &v3d->flag, 1.0, 0.0, 0, 0, "Occlude background geometry"); - xco+= XIC; } + xco+= XIC; uiBlockEndAlign(block); header_xco_step(ar, &xco, &yco, &maxco, XIC); -- cgit v1.2.3 From 8204dffe8a73271bc99eeeaeaed56ac0bed46e6a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 3 Oct 2009 11:23:31 +0000 Subject: UI: Bugfixes * #19529: Saving in edit mode causes problems in mode buttons when reopening * Fixed compiler warning in writefile for mingw * AnimData for Lamp data was not recognised by RNA --- source/blender/blenloader/intern/readfile.c | 5 ++++- source/blender/blenloader/intern/writefile.c | 2 +- source/blender/makesrna/intern/rna_lamp.c | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b40c7e453c0..9367e2f4247 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3902,7 +3902,10 @@ static void direct_link_object(FileData *fd, Object *ob) /* weak weak... this was only meant as draw flag, now is used in give_base too */ ob->flag &= ~OB_FROMGROUP; - + + /* editmode doesn't get saved in files, so should get cleared when reloading... */ + ob->mode &= ~OB_MODE_EDIT; + ob->disp.first=ob->disp.last= NULL; ob->adt= newdataadr(fd, ob->adt); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 3bd8b24eeb6..1f46446dc2a 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1102,7 +1102,7 @@ static void write_pose(WriteData *wd, bPose *pose) /* write IK param */ if (pose->ikparam) { - const char *structname = get_ikparam_name(pose); + char *structname = (char *)get_ikparam_name(pose); if (structname) writestruct(wd, DATA, structname, 1, pose->ikparam); } diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 4315a118c84..06fecec6fb6 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -377,7 +377,10 @@ static void rna_def_lamp(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_DIFF); RNA_def_property_ui_text(prop, "Diffuse", "Lamp does diffuse shading."); RNA_def_property_update(prop, 0, "rna_Lamp_update"); - + + /* common */ + rna_def_animdata_common(srna); + /* textures */ rna_def_mtex_common(srna, "rna_Lamp_mtex_begin", "rna_Lamp_active_texture_get", "rna_Lamp_active_texture_set", "LampTextureSlot", "rna_Lamp_update"); -- cgit v1.2.3 From e80d2cc4262cf921758667c24b2c31a90d22f6ac Mon Sep 17 00:00:00 2001 From: Lukas Steiblys Date: Sat, 3 Oct 2009 15:35:01 +0000 Subject: imbusy GSoC'09 branch merge (Vertex Buffer Object support) --- release/scripts/ui/space_userpref.py | 1 + source/blender/blenkernel/BKE_DerivedMesh.h | 2 + source/blender/blenkernel/BKE_paint.h | 2 + source/blender/blenkernel/intern/DerivedMesh.c | 212 +++- source/blender/blenkernel/intern/cdderivedmesh.c | 1098 ++++++++++++----- source/blender/blenkernel/intern/customdata.c | 4 + source/blender/editors/include/BIF_glutil.h | 1 + source/blender/editors/screen/glutil.c | 12 + source/blender/editors/sculpt_paint/sculpt.c | 145 ++- source/blender/editors/space_view3d/drawmesh.c | 95 +- source/blender/editors/space_view3d/drawobject.c | 492 +++++++- source/blender/gpu/gpu_buffers.h | 157 +++ source/blender/gpu/intern/gpu_buffers.c | 1248 ++++++++++++++++++++ source/blender/makesdna/DNA_customdata_types.h | 4 +- source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/makesrna/intern/rna_userdef.c | 4 + source/blender/windowmanager/intern/wm_init_exit.c | 2 + source/blender/windowmanager/intern/wm_subwindow.c | 4 +- source/blender/windowmanager/wm_subwindow.h | 1 + 19 files changed, 3118 insertions(+), 367 deletions(-) create mode 100644 source/blender/gpu/gpu_buffers.h create mode 100644 source/blender/gpu/intern/gpu_buffers.c diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 9798e0ccab6..a9126d2c7f1 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -314,6 +314,7 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemL(text="OpenGL:") sub1.itemR(system, "clip_alpha", slider=True) sub1.itemR(system, "use_mipmaps") + sub1.itemR(system, "use_vbos") sub1.itemL(text="Window Draw Method:") sub1.row().itemR(system, "window_draw_method", expand=True) sub1.itemL(text="Textures:") diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 06103596be1..076747cb845 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -58,6 +58,7 @@ struct ModifierData; struct MCol; struct ColorBand; struct GPUVertexAttribs; +struct GPUDrawObject; /* number of sub-elements each mesh element has (for interpolation) */ #define SUB_ELEMS_VERT 0 @@ -72,6 +73,7 @@ struct DerivedMesh { int needsFree; /* checked on ->release, is set to 0 for cached results */ int deformedOnly; /* set by modifier stack if only deformed from original */ BVHCache bvhCache; + struct GPUDrawObject *drawObject; /* Misc. Queries */ diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 7dc9e4499c6..ba42aca1872 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -88,6 +88,8 @@ typedef struct SculptSession { struct SculptStroke *stroke; struct StrokeCache *cache; + + struct GPUDrawObject *drawobject; } SculptSession; void free_sculptsession(SculptSession **); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 43b9a63a2c1..86c272e3799 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -84,6 +84,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "gpu_buffers.h" #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_material.h" @@ -218,7 +219,7 @@ int DM_release(DerivedMesh *dm) { if (dm->needsFree) { bvhcache_free(&dm->bvhCache); - + GPU_drawobject_free( dm ); CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); CustomData_free(&dm->faceData, dm->numFaceData); @@ -491,14 +492,55 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us } glEnd(); } else { - glBegin(GL_LINES); - for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, i)) { - glVertex3fv(eed->v1->co); - glVertex3fv(eed->v2->co); + GPUBuffer *buffer = 0; + float *varray; + if( setDrawOptions == 0 ) { + buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 ); + } + if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { + int prevdraw = 0; + int numedges = 0; + int draw = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + varray = GPU_buffer_lock_stream( buffer ); + for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, i)) { + draw = 1; + } else { + draw = 0; + } + if( prevdraw != draw && prevdraw != 0 && numedges > 0) { + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_LINES,0,numedges*2); + varray = GPU_buffer_lock_stream( buffer ); + numedges = 0; + } + if( draw != 0 ) { + VECCOPY(&varray[numedges*6],eed->v1->co); + VECCOPY(&varray[numedges*6+3],eed->v2->co); + numedges++; + } + prevdraw = draw; + } + GPU_buffer_unlock( buffer ); + if( prevdraw != 0 && numedges > 0) { + glDrawArrays(GL_LINES,0,numedges*2); + } + GPU_buffer_unbind(); + } else { + glBegin(GL_LINES); + for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, i)) { + glVertex3fv(eed->v1->co); + glVertex3fv(eed->v2->co); + } } + glEnd(); } - glEnd(); + if( buffer != 0 ) + GPU_buffer_free( buffer, 0 ); } } static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) @@ -627,8 +669,8 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); if(draw) { if (draw==2) { /* enabled with stipple */ - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); } glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); @@ -659,41 +701,135 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us } } } else { - for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { - int drawSmooth = (efa->flag & ME_SMOOTH); - draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); - if(draw) { - if (draw==2) { /* enabled with stipple */ - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); + GPUBuffer *buffer = 0; + float *varray; + if( setDrawOptions == 0 ) { + /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */ + buffer = GPU_buffer_alloc( sizeof(float)*6*emdm->em->totface*3*2, 0 ); + } + if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { + int prevdraw = 0; + int numfaces = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + glShadeModel(GL_SMOOTH); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { + int drawSmooth = (efa->flag & ME_SMOOTH); + draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); + if( prevdraw != draw && prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + varray = GPU_buffer_lock_stream( buffer ); + numfaces = 0; } - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - glNormal3fv(efa->n); - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(efa->v4) glVertex3fv(efa->v4->co); - } else { - glNormal3fv(efa->v1->no); - glVertex3fv(efa->v1->co); - glNormal3fv(efa->v2->no); - glVertex3fv(efa->v2->co); - glNormal3fv(efa->v3->no); - glVertex3fv(efa->v3->co); - if(efa->v4) { - glNormal3fv(efa->v4->no); - glVertex3fv(efa->v4->co); + if( draw != 0 ) { + if(!drawSmooth) { + VECCOPY(&varray[numfaces*18],efa->v1->co); + VECCOPY(&varray[numfaces*18+3],efa->n); + + VECCOPY(&varray[numfaces*18+6],efa->v2->co); + VECCOPY(&varray[numfaces*18+9],efa->n); + + VECCOPY(&varray[numfaces*18+12],efa->v3->co); + VECCOPY(&varray[numfaces*18+15],efa->n); + numfaces++; + if( efa->v4 ) { + VECCOPY(&varray[numfaces*18],efa->v3->co); + VECCOPY(&varray[numfaces*18+3],efa->n); + + VECCOPY(&varray[numfaces*18+6],efa->v4->co); + VECCOPY(&varray[numfaces*18+9],efa->n); + + VECCOPY(&varray[numfaces*18+12],efa->v1->co); + VECCOPY(&varray[numfaces*18+15],efa->n); + numfaces++; + } + } + else { + VECCOPY(&varray[numfaces*18],efa->v1->co); + VECCOPY(&varray[numfaces*18+3],efa->v1->no); + + VECCOPY(&varray[numfaces*18+6],efa->v2->co); + VECCOPY(&varray[numfaces*18+9],efa->v2->no); + + VECCOPY(&varray[numfaces*18+12],efa->v3->co); + VECCOPY(&varray[numfaces*18+15],efa->v3->no); + numfaces++; + if( efa->v4 ) { + VECCOPY(&varray[numfaces*18],efa->v3->co); + VECCOPY(&varray[numfaces*18+3],efa->v3->no); + + VECCOPY(&varray[numfaces*18+6],efa->v4->co); + VECCOPY(&varray[numfaces*18+9],efa->v4->no); + + VECCOPY(&varray[numfaces*18+12],efa->v1->co); + VECCOPY(&varray[numfaces*18+15],efa->v1->no); + numfaces++; + } } } - glEnd(); - - if (draw==2) + prevdraw = draw; + } + GPU_buffer_unlock( buffer ); + if( prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { glDisable(GL_POLYGON_STIPPLE); + } + } + GPU_buffer_unbind(); + } else { + for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { + int drawSmooth = (efa->flag & ME_SMOOTH); + draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); + if(draw) { + if (draw==2) { /* enabled with stipple */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + if (!drawSmooth) { + glNormal3fv(efa->n); + glVertex3fv(efa->v1->co); + glVertex3fv(efa->v2->co); + glVertex3fv(efa->v3->co); + if(efa->v4) glVertex3fv(efa->v4->co); + } else { + glNormal3fv(efa->v1->no); + glVertex3fv(efa->v1->co); + glNormal3fv(efa->v2->no); + glVertex3fv(efa->v2->co); + glNormal3fv(efa->v3->no); + glVertex3fv(efa->v3->co); + if(efa->v4) { + glNormal3fv(efa->v4->no); + glVertex3fv(efa->v4->co); + } + } + glEnd(); + + if (draw==2) + glDisable(GL_POLYGON_STIPPLE); + } } } + if( buffer != 0 ) + GPU_buffer_free( buffer, 0 ); } } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b20da0962a7..b9aa842b6dc 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -60,6 +60,7 @@ #include "MEM_guardedalloc.h" +#include "gpu_buffers.h" #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_material.h" @@ -176,10 +177,19 @@ static void cdDM_drawVerts(DerivedMesh *dm) MVert *mv = cddm->mvert; int i; - glBegin(GL_POINTS); - for(i = 0; i < dm->numVertData; i++, mv++) - glVertex3fv(mv->co); - glEnd(); + if( GPU_buffer_legacy(dm) ) { + glBegin(GL_POINTS); + for(i = 0; i < dm->numVertData; i++, mv++) + glVertex3fv(mv->co); + glEnd(); + } + else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + GPU_vertex_setup(dm); + if( !GPU_buffer_legacy(dm) ) { + glDrawArrays(GL_POINTS,0,dm->drawObject->nelements); + } + GPU_buffer_unbind(); + } } static void cdDM_drawUVEdges(DerivedMesh *dm) @@ -190,28 +200,65 @@ static void cdDM_drawUVEdges(DerivedMesh *dm) int i; if(mf) { - glBegin(GL_LINES); - for(i = 0; i < dm->numFaceData; i++, mf++, tf++) { - if(!(mf->flag&ME_HIDE)) { - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - - if(!mf->v4) { - glVertex2fv(tf->uv[2]); + if( GPU_buffer_legacy(dm) ) { + glBegin(GL_LINES); + for(i = 0; i < dm->numFaceData; i++, mf++, tf++) { + if(!(mf->flag&ME_HIDE)) { glVertex2fv(tf->uv[0]); - } else { + glVertex2fv(tf->uv[1]); + + glVertex2fv(tf->uv[1]); glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[3]); - glVertex2fv(tf->uv[3]); - glVertex2fv(tf->uv[0]); + if(!mf->v4) { + glVertex2fv(tf->uv[2]); + glVertex2fv(tf->uv[0]); + } else { + glVertex2fv(tf->uv[2]); + glVertex2fv(tf->uv[3]); + + glVertex2fv(tf->uv[3]); + glVertex2fv(tf->uv[0]); + } } } + glEnd(); + } + else { + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + int curpos = 0; + + GPU_uvedge_setup(dm); + if( !GPU_buffer_legacy(dm) ) { + for(i = 0; i < dm->numFaceData; i++, mf++) { + if(mf->flag&ME_LOOSEEDGE) { + draw = 1; + } + else { + draw = 0; + } + if( prevdraw != draw ) { + if( prevdraw > 0 && (curpos-prevstart) > 0) { + glDrawArrays(GL_LINES,prevstart,curpos-prevstart); + } + prevstart = curpos; + } + if( mf->v4 ) { + curpos += 8; + } + else { + curpos += 6; + } + prevdraw = draw; + } + if( prevdraw > 0 && (curpos-prevstart) > 0 ) { + glDrawArrays(GL_LINES,prevstart,curpos-prevstart); + } + } + GPU_buffer_unbind(); } - glEnd(); } } @@ -221,16 +268,48 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) MVert *mvert = cddm->mvert; MEdge *medge = cddm->medge; int i; - - glBegin(GL_LINES); - for(i = 0; i < dm->numEdgeData; i++, medge++) { - if((medge->flag&ME_EDGEDRAW) - && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) { - glVertex3fv(mvert[medge->v1].co); - glVertex3fv(mvert[medge->v2].co); + + if( GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" ); + glBegin(GL_LINES); + for(i = 0; i < dm->numEdgeData; i++, medge++) { + if((medge->flag&ME_EDGEDRAW) + && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) { + glVertex3fv(mvert[medge->v1].co); + glVertex3fv(mvert[medge->v2].co); + } } + glEnd(); + } + else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + + GPU_edge_setup(dm); + if( !GPU_buffer_legacy(dm) ) { + for(i = 0; i < dm->numEdgeData; i++, medge++) { + if((medge->flag&ME_EDGEDRAW) + && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) { + draw = 1; + } + else { + draw = 0; + } + if( prevdraw != draw ) { + if( prevdraw > 0 && (i-prevstart) > 0 ) { + GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 ); + } + prevstart = i; + } + prevdraw = draw; + } + if( prevdraw > 0 && (i-prevstart) > 0 ) { + GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 ); + } + } + GPU_buffer_unbind(); } - glEnd(); } static void cdDM_drawLooseEdges(DerivedMesh *dm) @@ -240,14 +319,45 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm) MEdge *medge = cddm->medge; int i; - glBegin(GL_LINES); - for(i = 0; i < dm->numEdgeData; i++, medge++) { - if(medge->flag&ME_LOOSEEDGE) { - glVertex3fv(mvert[medge->v1].co); - glVertex3fv(mvert[medge->v2].co); + if( GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" ); + glBegin(GL_LINES); + for(i = 0; i < dm->numEdgeData; i++, medge++) { + if(medge->flag&ME_LOOSEEDGE) { + glVertex3fv(mvert[medge->v1].co); + glVertex3fv(mvert[medge->v2].co); + } } + glEnd(); + } + else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + + GPU_edge_setup(dm); + if( !GPU_buffer_legacy(dm) ) { + for(i = 0; i < dm->numEdgeData; i++, medge++) { + if(medge->flag&ME_LOOSEEDGE) { + draw = 1; + } + else { + draw = 0; + } + if( prevdraw != draw ) { + if( prevdraw > 0 && (i-prevstart) > 0) { + GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 ); + } + prevstart = i; + } + prevdraw = draw; + } + if( prevdraw > 0 && (i-prevstart) > 0 ) { + GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 ); + } + } + GPU_buffer_unbind(); } - glEnd(); } static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) @@ -266,58 +376,73 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a glVertex3fv(mvert[index].co); \ } - glBegin(glmode = GL_QUADS); - for(a = 0; a < dm->numFaceData; a++, mface++) { - int new_glmode, new_matnr, new_shademodel; + if( GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" ); + glBegin(glmode = GL_QUADS); + for(a = 0; a < dm->numFaceData; a++, mface++) { + int new_glmode, new_matnr, new_shademodel; - new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; - new_matnr = mface->mat_nr + 1; - new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT; - - if(new_glmode != glmode || new_matnr != matnr - || new_shademodel != shademodel) { - glEnd(); + new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; + new_matnr = mface->mat_nr + 1; + new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT; + + if(new_glmode != glmode || new_matnr != matnr + || new_shademodel != shademodel) { + glEnd(); - drawCurrentMat = setMaterial(matnr = new_matnr, NULL); + drawCurrentMat = setMaterial(matnr = new_matnr, NULL); - glShadeModel(shademodel = new_shademodel); - glBegin(glmode = new_glmode); - } - - if(drawCurrentMat) { - if(shademodel == GL_FLAT) { - if (nors) { - glNormal3fv(nors); - } - else { - /* TODO make this better (cache facenormals as layer?) */ - float nor[3]; - if(mface->v4) { - CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co, - mvert[mface->v3].co, mvert[mface->v4].co, - nor); - } else { - CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co, - mvert[mface->v3].co, nor); + glShadeModel(shademodel = new_shademodel); + glBegin(glmode = new_glmode); + } + + if(drawCurrentMat) { + if(shademodel == GL_FLAT) { + if (nors) { + glNormal3fv(nors); + } + else { + /* TODO make this better (cache facenormals as layer?) */ + float nor[3]; + if(mface->v4) { + CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co, + mvert[mface->v3].co, mvert[mface->v4].co, + nor); + } else { + CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co, + mvert[mface->v3].co, nor); + } + glNormal3fv(nor); } - glNormal3fv(nor); + } + + PASSVERT(mface->v1); + PASSVERT(mface->v2); + PASSVERT(mface->v3); + if(mface->v4) { + PASSVERT(mface->v4); } } - PASSVERT(mface->v1); - PASSVERT(mface->v2); - PASSVERT(mface->v3); - if(mface->v4) { - PASSVERT(mface->v4); + if(nors) nors += 3; + } + glEnd(); + } + else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + GPU_vertex_setup( dm ); + GPU_normal_setup( dm ); + if( !GPU_buffer_legacy(dm) ) { + glShadeModel(GL_SMOOTH); + for( a = 0; a < dm->drawObject->nmaterials; a++ ) { + if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) ) + glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start); } } - - if(nors) nors += 3; + GPU_buffer_unbind( ); } - glEnd(); - glShadeModel(GL_FLAT); #undef PASSVERT + glShadeModel(GL_FLAT); } static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) @@ -341,43 +466,64 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha /* we need that as mesh option builtin, next to double sided lighting */ if(col1 && col2) glEnable(GL_CULL_FACE); - - glShadeModel(GL_SMOOTH); - glBegin(glmode = GL_QUADS); - for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) { - int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; - if(new_glmode != glmode) { - glEnd(); - glBegin(glmode = new_glmode); - } - - glColor3ub(cp1[0], cp1[1], cp1[2]); - glVertex3fv(mvert[mface->v1].co); - glColor3ub(cp1[4], cp1[5], cp1[6]); - glVertex3fv(mvert[mface->v2].co); - glColor3ub(cp1[8], cp1[9], cp1[10]); - glVertex3fv(mvert[mface->v3].co); - if(mface->v4) { - glColor3ub(cp1[12], cp1[13], cp1[14]); - glVertex3fv(mvert[mface->v4].co); - } - - if(useTwoSided) { - glColor3ub(cp2[8], cp2[9], cp2[10]); - glVertex3fv(mvert[mface->v3].co ); - glColor3ub(cp2[4], cp2[5], cp2[6]); - glVertex3fv(mvert[mface->v2].co ); - glColor3ub(cp2[0], cp2[1], cp2[2]); - glVertex3fv(mvert[mface->v1].co ); + if( GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" ); + glShadeModel(GL_SMOOTH); + glBegin(glmode = GL_QUADS); + for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) { + int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; + + if(new_glmode != glmode) { + glEnd(); + glBegin(glmode = new_glmode); + } + + glColor3ub(cp1[0], cp1[1], cp1[2]); + glVertex3fv(mvert[mface->v1].co); + glColor3ub(cp1[4], cp1[5], cp1[6]); + glVertex3fv(mvert[mface->v2].co); + glColor3ub(cp1[8], cp1[9], cp1[10]); + glVertex3fv(mvert[mface->v3].co); if(mface->v4) { - glColor3ub(cp2[12], cp2[13], cp2[14]); - glVertex3fv(mvert[mface->v4].co ); + glColor3ub(cp1[12], cp1[13], cp1[14]); + glVertex3fv(mvert[mface->v4].co); } + + if(useTwoSided) { + glColor3ub(cp2[8], cp2[9], cp2[10]); + glVertex3fv(mvert[mface->v3].co ); + glColor3ub(cp2[4], cp2[5], cp2[6]); + glVertex3fv(mvert[mface->v2].co ); + glColor3ub(cp2[0], cp2[1], cp2[2]); + glVertex3fv(mvert[mface->v1].co ); + if(mface->v4) { + glColor3ub(cp2[12], cp2[13], cp2[14]); + glVertex3fv(mvert[mface->v4].co ); + } + } + if(col2) cp2 += 16; } - if(col2) cp2 += 16; + glEnd(); + } + else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + GPU_color4_upload(dm,cp1); + GPU_vertex_setup(dm); + GPU_color_setup(dm); + if( !GPU_buffer_legacy(dm) ) { + glShadeModel(GL_SMOOTH); + glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements); + + if( useTwoSided ) { + GPU_color4_upload(dm,cp2); + GPU_color_setup(dm); + glCullFace(GL_FRONT); + glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements); + glCullFace(GL_BACK); + } + } + GPU_buffer_unbind(); } - glEnd(); glShadeModel(GL_FLAT); glDisable(GL_CULL_FACE); @@ -390,85 +536,172 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; MVert *mv = cddm->mvert; - MFace *mf = cddm->mface; - MCol *mcol = dm->getFaceDataArray(dm, CD_MCOL); + MFace *mf = DM_get_face_data_layer(dm, CD_MFACE); + MCol *realcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL); float *nors= dm->getFaceDataArray(dm, CD_NORMAL); MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); - int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); + int i, j, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); + int startFace = 0, lastFlag = 0xdeadbeef; + MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); + if(!mcol) + mcol = dm->getFaceDataArray(dm, CD_MCOL); + + if( GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" ); + for(i = 0; i < dm->numFaceData; i++, mf++) { + MVert *mvert; + int flag; + unsigned char *cp = NULL; - for(i = 0; i < dm->numFaceData; i++, mf++) { - MVert *mvert; - int flag; - unsigned char *cp = NULL; + if(drawParams) { + flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr); + } + else { + if(index) { + orig = *index++; + if(orig == ORIGINDEX_NONE) { if(nors) nors += 3; continue; } + if(drawParamsMapped) flag = drawParamsMapped(userData, orig); + else { if(nors) nors += 3; continue; } + } + else + if(drawParamsMapped) flag = drawParamsMapped(userData, i); + else { if(nors) nors += 3; continue; } + } + + if(flag != 0) { + if (flag==1 && mcol) + cp= (unsigned char*) &mcol[i*4]; + + if(!(mf->flag&ME_SMOOTH)) { + if (nors) { + glNormal3fv(nors); + } + else { + float nor[3]; + if(mf->v4) { + CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co, + mv[mf->v3].co, mv[mf->v4].co, + nor); + } else { + CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co, + mv[mf->v3].co, nor); + } + glNormal3fv(nor); + } + } + + glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); + if(tf) glTexCoord2fv(tf[i].uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + mvert = &mv[mf->v1]; + if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); + glVertex3fv(mvert->co); + + if(tf) glTexCoord2fv(tf[i].uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + mvert = &mv[mf->v2]; + if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); + glVertex3fv(mvert->co); - if(drawParams) { - flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr); + if(tf) glTexCoord2fv(tf[i].uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + mvert = &mv[mf->v3]; + if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); + glVertex3fv(mvert->co); + + if(mf->v4) { + if(tf) glTexCoord2fv(tf[i].uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + mvert = &mv[mf->v4]; + if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); + glVertex3fv(mvert->co); + } + glEnd(); + } + + if(nors) nors += 3; } - else { - if(index) { - orig = *index++; - if(orig == ORIGINDEX_NONE) { if(nors) nors += 3; continue; } - if(drawParamsMapped) flag = drawParamsMapped(userData, orig); - else { if(nors) nors += 3; continue; } + } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + MCol *col = realcol; + if(!col) + col = mcol; + + GPU_vertex_setup( dm ); + GPU_normal_setup( dm ); + GPU_uv_setup( dm ); + if( col != 0 ) { + /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL ) { + col = 0; + } else if( mcol && dm->drawObject->colType == CD_MCOL ) { + col = 0; } - else - if(drawParamsMapped) flag = drawParamsMapped(userData, i); - else { if(nors) nors += 3; continue; } + + if( col != 0 ) {*/ + unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common"); + for( i=0; i < dm->getNumFaces(dm); i++ ) { + for( j=0; j < 4; j++ ) { + colors[i*12+j*3] = col[i*4+j].r; + colors[i*12+j*3+1] = col[i*4+j].g; + colors[i*12+j*3+2] = col[i*4+j].b; + } + } + GPU_color3_upload(dm,colors); + MEM_freeN(colors); + if(realcol) + dm->drawObject->colType = CD_TEXTURE_MCOL; + else if(mcol) + dm->drawObject->colType = CD_MCOL; + //} + GPU_color_setup( dm ); } - - if(flag != 0) { /* if the flag is 0 it means the face is hidden or invisible */ - if (flag==1 && mcol) - cp= (unsigned char*) &mcol[i*4]; - if(!(mf->flag&ME_SMOOTH)) { - if (nors) { - glNormal3fv(nors); + if( !GPU_buffer_legacy(dm) ) { + glShadeModel( GL_SMOOTH ); + for(i = 0; i < dm->drawObject->nelements/3; i++) { + int actualFace = dm->drawObject->faceRemap[i]; + int flag = 1; + unsigned char *cp = NULL; + + if(drawParams) { + flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr); } else { - /* TODO make this better (cache facenormals as layer?) */ - float nor[3]; - if(mf->v4) { - CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co, - mv[mf->v3].co, mv[mf->v4].co, - nor); - } else { - CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co, - mv[mf->v3].co, nor); + if(index) { + orig = index[actualFace]; + if(drawParamsMapped) + flag = drawParamsMapped(userData, orig); } - glNormal3fv(nor); + else + if(drawParamsMapped) + flag = drawParamsMapped(userData, actualFace); + } + if( flag != lastFlag ) { + if( startFace < i ) { + if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */ + if (lastFlag==1 && mcol) + GPU_color_switch(1); + else + GPU_color_switch(0); + glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3); + } + } + lastFlag = flag; + startFace = i; } } - - glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); - if(tf) glTexCoord2fv(tf[i].uv[0]); - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - mvert = &mv[mf->v1]; - if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if(tf) glTexCoord2fv(tf[i].uv[1]); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - mvert = &mv[mf->v2]; - if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if(tf) glTexCoord2fv(tf[i].uv[2]); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - mvert = &mv[mf->v3]; - if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if(mf->v4) { - if(tf) glTexCoord2fv(tf[i].uv[3]); - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - mvert = &mv[mf->v4]; - if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); + if( startFace < dm->drawObject->nelements/3 ) { + if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */ + if (lastFlag==1 && mcol) + GPU_color_switch(1); + else + GPU_color_switch(0); + glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3); + } } - glEnd(); } - - if(nors) nors += 3; + + GPU_buffer_unbind(); + glShadeModel( GL_FLAT ); } } @@ -486,79 +719,131 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us float *nors= dm->getFaceDataArray(dm, CD_NORMAL); int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); - mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL); + + mc = DM_get_face_data_layer(dm, CD_ID_MCOL); + if(!mc) + mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL); if(!mc) mc = DM_get_face_data_layer(dm, CD_MCOL); - for(i = 0; i < dm->numFaceData; i++, mf++) { - int drawSmooth = (mf->flag & ME_SMOOTH); + if( GPU_buffer_legacy(dm) ) { + DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" ); + for(i = 0; i < dm->numFaceData; i++, mf++) { + int drawSmooth = (mf->flag & ME_SMOOTH); - if(index) { - orig = *index++; - if(setDrawOptions && orig == ORIGINDEX_NONE) - { if(nors) nors += 3; continue; } - } - else - orig = i; + if(index) { + orig = *index++; + if(setDrawOptions && orig == ORIGINDEX_NONE) + { if(nors) nors += 3; continue; } + } + else + orig = i; - if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) { - unsigned char *cp = NULL; + if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) { + unsigned char *cp = NULL; - if(useColors && mc) - cp = (unsigned char *)&mc[i * 4]; + if(useColors && mc) + cp = (unsigned char *)&mc[i * 4]; - glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); + glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); - if (!drawSmooth) { - if (nors) { - glNormal3fv(nors); - } - else { - /* TODO make this better (cache facenormals as layer?) */ - float nor[3]; + if (!drawSmooth) { + if (nors) { + glNormal3fv(nors); + } + else { + float nor[3]; + if(mf->v4) { + CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co, + mv[mf->v3].co, mv[mf->v4].co, + nor); + } else { + CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co, + mv[mf->v3].co, nor); + } + glNormal3fv(nor); + } + + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(mv[mf->v1].co); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glVertex3fv(mv[mf->v2].co); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glVertex3fv(mv[mf->v3].co); if(mf->v4) { - CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co, - mv[mf->v3].co, mv[mf->v4].co, - nor); - } else { - CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co, - mv[mf->v3].co, nor); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glVertex3fv(mv[mf->v4].co); + } + } else { + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3sv(mv[mf->v1].no); + glVertex3fv(mv[mf->v1].co); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3sv(mv[mf->v2].no); + glVertex3fv(mv[mf->v2].co); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3sv(mv[mf->v3].no); + glVertex3fv(mv[mf->v3].co); + if(mf->v4) { + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3sv(mv[mf->v4].no); + glVertex3fv(mv[mf->v4].co); } - glNormal3fv(nor); } - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(mv[mf->v1].co); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - glVertex3fv(mv[mf->v2].co); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - glVertex3fv(mv[mf->v3].co); - if(mf->v4) { - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - glVertex3fv(mv[mf->v4].co); + glEnd(); + } + + if (nors) nors += 3; + } + } + else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ + int state = 1; + int prevstate = 1; + int prevstart = 0; + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + if( useColors && mc ) + GPU_color_setup(dm); + if( !GPU_buffer_legacy(dm) ) { + glShadeModel(GL_SMOOTH); + for( i = 0; i < dm->drawObject->nelements/3; i++ ) { + int actualFace = dm->drawObject->faceRemap[i]; + int drawSmooth = (mf[actualFace].flag & ME_SMOOTH); + int dontdraw = 0; + if(index) { + orig = index[actualFace]; + if(setDrawOptions && orig == ORIGINDEX_NONE) + dontdraw = 1; } - } else { - if(cp) glColor3ub(cp[3], cp[2], cp[1]); - glNormal3sv(mv[mf->v1].no); - glVertex3fv(mv[mf->v1].co); - if(cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3sv(mv[mf->v2].no); - glVertex3fv(mv[mf->v2].co); - if(cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3sv(mv[mf->v3].no); - glVertex3fv(mv[mf->v3].co); - if(mf->v4) { - if(cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3sv(mv[mf->v4].no); - glVertex3fv(mv[mf->v4].co); + else + orig = i; + if( dontdraw ) { + state = 0; + } + else { + if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) { + state = 1; + } + else { + state = 0; + } } + if( prevstate != state && prevstate == 1 ) { + if( i-prevstart > 0 ) { + glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3); + } + prevstart = i; + } + prevstate = state; } - - glEnd(); + if(state==1) { + glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3); + } + glShadeModel(GL_FLAT); } - - if (nors) nors += 3; + GPU_buffer_unbind(); } } @@ -586,106 +871,309 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo transp = GPU_get_material_blend_mode(); orig_transp = transp; - memset(&attribs, 0, sizeof(attribs)); - glShadeModel(GL_SMOOTH); - glBegin(GL_QUADS); - for(a = 0; a < dm->numFaceData; a++, mface++) { - new_matnr = mface->mat_nr + 1; + if( GPU_buffer_legacy(dm) || setDrawOptions != 0 ) { + DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" ); + memset(&attribs, 0, sizeof(attribs)); - if(new_matnr != matnr) { - glEnd(); + glBegin(GL_QUADS); - dodraw = setMaterial(matnr = new_matnr, &gattribs); - if(dodraw) - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + for(a = 0; a < dm->numFaceData; a++, mface++) { + new_matnr = mface->mat_nr + 1; - glBegin(GL_QUADS); - } + if(new_matnr != matnr) { + glEnd(); - if(!dodraw) { - continue; - } - else if(setDrawOptions) { - orig = index[a]; + dodraw = setMaterial(matnr = new_matnr, &gattribs); + if(dodraw) + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - if(orig == ORIGINDEX_NONE) - continue; - else if(!setDrawOptions(userData, orig)) + glBegin(GL_QUADS); + } + + if(!dodraw) { continue; - } + } + else if(setDrawOptions) { + orig = index[a]; + + if(orig == ORIGINDEX_NONE) + continue; + else if(!setDrawOptions(userData, orig)) + continue; + } - if(tf) { - new_transp = tf[a].transp; + if(tf) { + new_transp = tf[a].transp; - if(new_transp != transp) { - glEnd(); + if(new_transp != transp) { + glEnd(); - if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) - GPU_set_material_blend_mode(orig_transp); - else - GPU_set_material_blend_mode(new_transp); - transp = new_transp; + if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) + GPU_set_material_blend_mode(orig_transp); + else + GPU_set_material_blend_mode(new_transp); + transp = new_transp; - glBegin(GL_QUADS); + glBegin(GL_QUADS); + } } - } - smoothnormal = (mface->flag & ME_SMOOTH); + smoothnormal = (mface->flag & ME_SMOOTH); - if(!smoothnormal) { - if(nors) { - glNormal3fv(nors[a]); - } - else { - /* TODO ideally a normal layer should always be available */ - float nor[3]; - if(mface->v4) { - CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co, - mvert[mface->v3].co, mvert[mface->v4].co, - nor); - } else { - CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co, - mvert[mface->v3].co, nor); + if(!smoothnormal) { + if(nors) { + glNormal3fv(nors[a]); + } + else { + /* TODO ideally a normal layer should always be available */ + float nor[3]; + if(mface->v4) { + CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co, + mvert[mface->v3].co, mvert[mface->v4].co, + nor); + } else { + CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co, + mvert[mface->v3].co, nor); + } + glNormal3fv(nor); } - glNormal3fv(nor); } - } #define PASSVERT(index, vert) { \ - if(attribs.totorco) \ - glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \ - for(b = 0; b < attribs.tottface; b++) { \ - MTFace *tf = &attribs.tface[b].array[a]; \ - glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \ - } \ - for(b = 0; b < attribs.totmcol; b++) { \ - MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \ - GLubyte col[4]; \ - col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ - glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ - } \ - if(attribs.tottang) { \ - float *tang = attribs.tang.array[a*4 + vert]; \ - glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \ - } \ - if(smoothnormal) \ - glNormal3sv(mvert[index].no); \ - glVertex3fv(mvert[index].co); \ -} - - PASSVERT(mface->v1, 0); - PASSVERT(mface->v2, 1); - PASSVERT(mface->v3, 2); - if(mface->v4) - PASSVERT(mface->v4, 3) - else - PASSVERT(mface->v3, 2) + if(attribs.totorco) \ + glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \ + for(b = 0; b < attribs.tottface; b++) { \ + MTFace *tf = &attribs.tface[b].array[a]; \ + glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \ + } \ + for(b = 0; b < attribs.totmcol; b++) { \ + MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \ + GLubyte col[4]; \ + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ + glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ + } \ + if(attribs.tottang) { \ + float *tang = attribs.tang.array[a*4 + vert]; \ + glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \ + } \ + if(smoothnormal) \ + glNormal3sv(mvert[index].no); \ + glVertex3fv(mvert[index].co); \ + } + + PASSVERT(mface->v1, 0); + PASSVERT(mface->v2, 1); + PASSVERT(mface->v3, 2); + if(mface->v4) + PASSVERT(mface->v4, 3) + else + PASSVERT(mface->v3, 2) #undef PASSVERT + } + glEnd(); + } + else { + GPUBuffer *buffer = 0; + char *varray = 0; + int numdata = 0, elementsize = 0, offset; + int start = 0, numfaces = 0, prevdraw = 0, curface = 0; + GPUAttrib datatypes[32]; + memset(&attribs, 0, sizeof(attribs)); + + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + + if( !GPU_buffer_legacy(dm) ) { + for(a = 0; a < dm->numFaceData; a++, mface++) { + new_matnr = mface->mat_nr + 1; + + if(new_matnr != matnr ) { + numfaces = curface - start; + if( numfaces > 0 ) { + if( prevdraw ) { + GPU_buffer_unlock(buffer); + GPU_interleaved_attrib_setup(buffer,datatypes,numdata); + glDrawArrays(GL_TRIANGLES,start*3,numfaces*3); + GPU_buffer_free(buffer,0); + } + } + start = curface; + prevdraw = dodraw; + dodraw = setMaterial(matnr = new_matnr, &gattribs); + if(dodraw) { + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + + if(attribs.totorco) { + datatypes[numdata].index = attribs.orco.glIndex; + datatypes[numdata].size = 3; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + for(b = 0; b < attribs.tottface; b++) { + datatypes[numdata].index = attribs.tface[b].glIndex; + datatypes[numdata].size = 2; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + for(b = 0; b < attribs.totmcol; b++) { + datatypes[numdata].index = attribs.mcol[b].glIndex; + datatypes[numdata].size = 4; + datatypes[numdata].type = GL_UNSIGNED_BYTE; + numdata++; + } + if(attribs.tottang) { + datatypes[numdata].index = attribs.tang.glIndex; + datatypes[numdata].size = 3; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + if( numdata != 0 ) { + elementsize = GPU_attrib_element_size( datatypes, numdata ); + buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, 0 ); + if( buffer == 0 ) { + GPU_buffer_unbind(); + dm->drawObject->legacy = 1; + return; + } + varray = GPU_buffer_lock_stream(buffer); + if( varray == 0 ) { + GPU_buffer_unbind(); + GPU_buffer_free(buffer, 0); + dm->drawObject->legacy = 1; + return; + } + } + } + } + if(!dodraw) { + continue; + } + + if(tf) { + new_transp = tf[a].transp; + + if(new_transp != transp) { + numfaces = curface - start; + if( numfaces > 0 ) { + if( dodraw ) { + if( numdata != 0 ) { + GPU_buffer_unlock(buffer); + GPU_interleaved_attrib_setup(buffer,datatypes,numdata); + } + glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3); + if( numdata != 0 ) { + varray = GPU_buffer_lock_stream(buffer); + } + } + } + start = curface; + + if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) + GPU_set_material_blend_mode(orig_transp); + else + GPU_set_material_blend_mode(new_transp); + transp = new_transp; + } + } + + if( numdata != 0 ) { + offset = 0; + if(attribs.totorco) { + VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]); + VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]); + VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]); + offset += sizeof(float)*3; + } + for(b = 0; b < attribs.tottface; b++) { + MTFace *tf = &attribs.tface[b].array[a]; + VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[0]); + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]); + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]); + offset += sizeof(float)*2; + } + for(b = 0; b < attribs.totmcol; b++) { + MCol *cp = &attribs.mcol[b].array[a*4 + 0]; + GLubyte col[4]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col); + cp = &attribs.mcol[b].array[a*4 + 1]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col); + cp = &attribs.mcol[b].array[a*4 + 2]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col); + offset += sizeof(unsigned char)*4; + } + if(attribs.tottang) { + float *tang = attribs.tang.array[a*4 + 0]; + VECCOPY((float *)&varray[elementsize*curface*3+offset], tang); + tang = attribs.tang.array[a*4 + 1]; + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang); + tang = attribs.tang.array[a*4 + 2]; + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang); + offset += sizeof(float)*3; + } + } + curface++; + if(mface->v4) { + if( numdata != 0 ) { + offset = 0; + if(attribs.totorco) { + VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]); + VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]); + VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]); + offset += sizeof(float)*3; + } + for(b = 0; b < attribs.tottface; b++) { + MTFace *tf = &attribs.tface[b].array[a]; + VECCOPY((float *)&varray[elementsize*curface*3+offset],tf->uv[2]); + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]); + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]); + offset += sizeof(float)*2; + } + for(b = 0; b < attribs.totmcol; b++) { + MCol *cp = &attribs.mcol[b].array[a*4 + 2]; + GLubyte col[4]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col); + cp = &attribs.mcol[b].array[a*4 + 3]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col); + cp = &attribs.mcol[b].array[a*4 + 0]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col); + offset += sizeof(unsigned char)*4; + } + if(attribs.tottang) { + float *tang = attribs.tang.array[a*4 + 2]; + VECCOPY((float *)&varray[elementsize*curface*3+offset], tang); + tang = attribs.tang.array[a*4 + 3]; + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang); + tang = attribs.tang.array[a*4 + 0]; + VECCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang); + offset += sizeof(float)*3; + } + } + curface++; + } + } + numfaces = curface - start; + if( numfaces > 0 ) { + if( dodraw ) { + if( numdata != 0 ) { + GPU_buffer_unlock(buffer); + GPU_interleaved_attrib_setup(buffer,datatypes,numdata); + } + glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3); + } + } + GPU_buffer_unbind(); + } + GPU_buffer_free( buffer, 0 ); } - glEnd(); glShadeModel(GL_FLAT); } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 705d0b66d7f..28aaadea9c3 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -726,6 +726,10 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL}, {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, + {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol, + layerSwap_mcol, layerDefault_mcol}, + {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol, + layerSwap_mcol, layerDefault_mcol}, }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index deee3e3c8b4..e394de613e4 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -197,6 +197,7 @@ void gla2DSetMap(gla2DDrawInfo *di, struct rctf *rect); /* use this for platform hacks. glPointSize is solved here */ void bglBegin(int mode); void bglEnd(void); +int bglPointHack(); void bglVertex3fv(float *vec); void bglVertex3f(float x, float y, float z); void bglVertex2fv(float *vec); diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 5312ca26906..1445c6b5cf8 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -720,6 +720,18 @@ void bglBegin(int mode) } } +int bglPointHack() { + float value[4]; + int pointhack; + glGetFloatv(GL_POINT_SIZE_RANGE, value); + if(value[1]<2.0) { + glGetFloatv(GL_POINT_SIZE, value); + pointhack= floor(value[0]+0.5); + if(pointhack>4) pointhack= 4; + return pointhack; + } + return 0; +} void bglVertex3fv(float *vec) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 64af39ea497..e41231442ba 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -91,6 +91,7 @@ #include "RE_shader_ext.h" /*for multitex_ext*/ #include "GPU_draw.h" +#include "gpu_buffers.h" #include #include @@ -304,21 +305,34 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float out[3], const static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_verts) { float area_normal[3]; + int j; ActiveData *node= active_verts->first; + float* buffer; calc_area_normal(sd, ss, area_normal, active_verts); + buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); while(node){ float *co= ss->mvert[node->Index].co; const float val[3]= {co[0]+area_normal[0]*ss->cache->radius*node->Fade*ss->cache->scale[0], co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1], co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]}; - + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } + sculpt_clip(sd, ss, co, val); - + node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } /* For the smooth brush, uses the neighboring vertices around vert to calculate @@ -368,6 +382,7 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert) static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts) { ActiveData *node= active_verts->first; + float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); int i; for(i = 0; i < 2; ++i) { @@ -380,24 +395,45 @@ static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active val[1] = co[1]+(avg[1]-co[1])*node->Fade; val[2] = co[2]+(avg[2]-co[2])*node->Fade; - sculpt_clip(s, ss, co, val); + sculpt_clip(s, ss, co, val); + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(s, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } node= node->next; } } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void do_pinch_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts) { ActiveData *node= active_verts->first; + float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); while(node) { float *co= ss->mvert[node->Index].co; const float val[3]= {co[0]+(ss->cache->location[0]-co[0])*node->Fade, co[1]+(ss->cache->location[1]-co[1])*node->Fade, co[2]+(ss->cache->location[2]-co[2])*node->Fade}; + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(s, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } + sculpt_clip(s, ss, co, val); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void do_grab_brush(Sculpt *sd, SculptSession *ss) @@ -405,6 +441,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss) ActiveData *node= ss->cache->grab_active_verts[ss->cache->symmetry].first; float add[3]; float grab_delta[3]; + float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); VecCopyf(grab_delta, ss->cache->grab_delta_symmetry); @@ -414,10 +451,21 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss) VecCopyf(add, grab_delta); VecMulf(add, node->Fade); VecAddf(add, add, co); + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], add); + cur = cur->next; + } + } + sculpt_clip(sd, ss, co, add); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } @@ -425,6 +473,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active { float area_normal[3]; ActiveData *node= active_verts->first; + float *buffer; float lim= ss->cache->radius / 4; if(ss->cache->flip) @@ -432,6 +481,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active calc_area_normal(sd, ss, area_normal, active_verts); + buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); while(node){ float *disp= &ss->layer_disps[node->Index]; float *co= ss->mvert[node->Index].co; @@ -447,17 +497,28 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active val[1] = ss->mesh_co_orig[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1]; val[2] = ss->mesh_co_orig[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2]; + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } + sculpt_clip(sd, ss, co, val); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *active_verts) { ActiveData *node= active_verts->first; float add[3]; - + float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + while(node) { float *co= ss->mvert[node->Index].co; short *no= ss->mvert[node->Index].no; @@ -471,10 +532,20 @@ static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *activ add[2]*= ss->cache->scale[2]; VecAddf(add, add, co); + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(s, ss, &buffer[cur->element*3], add); + cur = cur->next; + } + } + sculpt_clip(s, ss, co, add); node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } static void calc_flatten_center(SculptSession *ss, ActiveData *node, float co[3]) @@ -535,7 +606,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase float area_normal[3]; float cntr[3], cntr2[3], bstr = 0; int flip = 0; - + float *buffer; calc_area_normal(sd, ss, area_normal, active_verts); calc_flatten_center(ss, node, cntr); @@ -547,7 +618,9 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase cntr2[2]=cntr[2]+area_normal[2]*bstr*ss->cache->scale[2]; flip = bstr < 0; } - + + buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + while(node){ float *co= ss->mvert[node->Index].co; float intr[3], val[3]; @@ -573,11 +646,21 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase VecAddf(val, val, co); + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[node->Index]; + while( cur != 0 && cur->element != -1 ) { + sculpt_clip(sd, ss, &buffer[cur->element*3], val); + cur = cur->next; + } + } sculpt_clip(sd, ss, co, val); + } node= node->next; } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->vertices ); } /* Uses symm to selectively flip any axis of a coordinate. */ @@ -898,7 +981,8 @@ static void add_face_normal(vec3f *norm, MVert *mvert, const MFace* face, float static void update_damaged_vert(SculptSession *ss, ListBase *lb) { ActiveData *vert; - + + float *buffer = (float *)GPU_buffer_lock( ss->drawobject->normals ); for(vert= lb->first; vert; vert= vert->next) { vec3f norm= {0,0,0}; IndexNode *face= ss->fmap[vert->Index].first; @@ -915,7 +999,32 @@ static void update_damaged_vert(SculptSession *ss, ListBase *lb) ss->mvert[vert->Index].no[0]=norm.x*32767; ss->mvert[vert->Index].no[1]=norm.y*32767; ss->mvert[vert->Index].no[2]=norm.z*32767; + + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[vert->Index]; + while( cur != 0 && cur->element != -1 ) { + int i = ss->drawobject->faceRemap[cur->element/3]; + if( ss->mface[i].flag & ME_SMOOTH ) { + VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no); + } + else { + float norm[3]; + if( ss->mface[i].v4 ) + CalcNormFloat4(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, ss->mvert[ss->mface[i].v4].co, norm); + else + CalcNormFloat(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, norm); + VECCOPY(&buffer[cur->element*3],norm); + VECCOPY(&buffer[cur->element*3],norm); + VECCOPY(&buffer[cur->element*3],norm); + } + + //VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no); + cur = cur->next; + } + } } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->normals ); } static void calc_damaged_verts(SculptSession *ss) @@ -1004,9 +1113,10 @@ static void sculpt_update_mesh_elements(bContext *C) Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; int oldtotvert = ss->totvert; + DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); if((ss->multires = sculpt_multires_active(ob))) { - DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); + //DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); ss->totvert = dm->getNumVerts(dm); ss->totface = dm->getNumFaces(dm); ss->mvert = dm->getVertDataArray(dm, CD_MVERT); @@ -1021,6 +1131,12 @@ static void sculpt_update_mesh_elements(bContext *C) ss->mface = me->mface; ss->face_normals = NULL; } + if( GPU_buffer_legacy( dm ) ) { + ss->drawobject = 0; + } + else { + ss->drawobject = dm->drawObject; + } if(ss->totvert != oldtotvert) { if(ss->projverts) MEM_freeN(ss->projverts); @@ -1332,16 +1448,27 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) { StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); + float *buffer; int i; - + /* Restore the mesh before continuing with anchored stroke */ if((brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) { + buffer = (float *)GPU_buffer_lock( ss->drawobject->normals ); for(i = 0; i < ss->totvert; ++i) { VecCopyf(ss->mvert[i].co, ss->mesh_co_orig[i]); ss->mvert[i].no[0] = cache->orig_norms[i][0]; ss->mvert[i].no[1] = cache->orig_norms[i][1]; ss->mvert[i].no[2] = cache->orig_norms[i][2]; + if( buffer != 0 ) { + IndexLink *cur = &ss->drawobject->indices[i]; + while( cur != 0 && cur->element != -1 ) { + VECCOPY(&buffer[cur->element*3],cache->orig_norms[i]); + cur = cur->next; + } + } } + if( buffer != 0 ) + GPU_buffer_unlock( ss->drawobject->normals ); if(ss->face_normals) { float *fn = ss->face_normals; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index da67bd8707e..a4d7ae802f6 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -70,6 +70,7 @@ #include "UI_resources.h" #include "UI_interface_icons.h" +#include "gpu_buffers.h" #include "GPU_extensions.h" #include "GPU_draw.h" @@ -398,8 +399,7 @@ static void draw_textured_end() glPopMatrix(); } - -static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) +static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr) { if (tface && (tface->mode&TF_INVISIBLE)) return 0; @@ -421,6 +421,87 @@ static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) return 1; /* Set color from mcol */ } } +static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) +{ + if (tface && (tface->mode&TF_INVISIBLE)) return 0; + + if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) { + return 2; /* Don't set color */ + } else if (tface && tface->mode&TF_OBCOL) { + return 2; /* Don't set color */ + } else if (!mcol) { + return 2; /* Don't set color */ + } else { + return 1; /* Set color from mcol */ + } +} +static void add_tface_color_layer(DerivedMesh *dm) +{ + MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE); + MFace *mface = DM_get_face_data_layer(dm, CD_MFACE); + MCol *finalCol; + int i,j; + MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); + if(!mcol) + mcol = dm->getFaceDataArray(dm, CD_MCOL); + + finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer"); + for(i=0;igetNumFaces(dm);i++) { + if (tface && (tface->mode&TF_INVISIBLE)) { + if( mcol ) + memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4); + else + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 255; + finalCol[i*4+j].r = 255; + } + } + else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) { + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 0; + finalCol[i*4+j].r = 255; + } + } else if (tface && tface->mode&TF_OBCOL) { + for(j=0;j<4;j++) { + finalCol[i*4+j].r = Gtexdraw.obcol[0]; + finalCol[i*4+j].g = Gtexdraw.obcol[1]; + finalCol[i*4+j].b = Gtexdraw.obcol[2]; + } + } else if (!mcol) { + if (tface) { + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 255; + finalCol[i*4+j].r = 255; + } + } + else { + Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1); + if(ma) + for(j=0;j<4;j++) { + finalCol[i*4+j].b = ma->b; + finalCol[i*4+j].g = ma->g; + finalCol[i*4+j].r = ma->r; + } + else + for(j=0;j<4;j++) { + finalCol[i*4+j].b = 255; + finalCol[i*4+j].g = 255; + finalCol[i*4+j].r = 255; + } + } + } else { + for(j=0;j<4;j++) { + finalCol[i*4+j].b = mcol[i*4+j].r; + finalCol[i*4+j].g = mcol[i*4+j].g; + finalCol[i*4+j].r = mcol[i*4+j].b; + } + } + } + CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData ); +} static int draw_tface_mapped__set_draw(void *userData, int index) { @@ -561,6 +642,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o draw_textured_begin(scene, v3d, rv3d, ob); if(ob == scene->obedit) { + glColor4f(1.0f,1.0f,1.0f,1.0f); dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh); } else if(faceselect) { if(ob->mode & OB_MODE_WEIGHT_PAINT) @@ -569,7 +651,14 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me); } else { - dm->drawFacesTex(dm, draw_tface__set_draw); + if( GPU_buffer_legacy(dm) ) + dm->drawFacesTex(dm, draw_tface__set_draw_legacy); + else { + glColor4f(1.0f,1.0f,1.0f,1.0f); + if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) ) + add_tface_color_layer(dm); + dm->drawFacesTex(dm, draw_tface__set_draw); + } } /* draw game engine text hack */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index db3b7130ab3..53e87d61ad3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -102,6 +102,7 @@ #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_extensions.h" +#include "gpu_buffers.h" #include "ED_mesh.h" #include "ED_particle.h" @@ -113,6 +114,7 @@ #include "UI_interface_icons.h" #include "WM_api.h" +#include "wm_subwindow.h" #include "BLF_api.h" #include "view3d_intern.h" // own include @@ -1550,15 +1552,72 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float * } } } +/* originally defined in DerivedMesh.c */ +typedef struct { + DerivedMesh dm; + + EditMesh *em; + float (*vertexCos)[3]; + float (*vertexNos)[3]; + float (*faceNos)[3]; +} EditMeshDerivedMesh; + static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act) { struct { int sel; EditVert *eve_act; } data; + GPUBuffer *buffer; + float *varray; data.sel = sel; data.eve_act = eve_act; - - bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); - bglEnd(); + + /* first come the unselected vertices, then the selected */ + buffer = GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 ); + + if( (varray = GPU_buffer_lock_stream( buffer )) && bglPointHack() == 0 ) { + EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; + EditVert *eve; + int i; + int numverts = 0, numselected = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + varray = GPU_buffer_lock_stream( buffer ); + + glBegin(GL_POINTS); + for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { + if (eve->h==0 && (eve->f&SELECT)==data.sel) { + if (eve==data.eve_act) { + if (emdm->vertexCos) { + VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],emdm->vertexCos[i]); + } + else { + VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],eve->co); + } + numselected++; + } else { + if (emdm->vertexCos) { + VECCOPY(&varray[3*numverts],emdm->vertexCos[i]); + } else { + VECCOPY(&varray[3*numverts],eve->co); + } + numverts++; + } + } + } + glEnd(); + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_POINTS,0,numverts); + UI_ThemeColor4(TH_EDITMESH_ACTIVE); + glDrawArrays(GL_POINTS,dm->getNumVerts(dm),numselected); + UI_ThemeColor4(data.sel?TH_VERTEX_SELECT:TH_VERTEX); + GPU_buffer_unbind(); + } + else { + bglBegin(GL_POINTS); + dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); + bglEnd(); + } + GPU_buffer_free( buffer, 0 ); } /* Draw edges with color set based on selection */ @@ -1626,12 +1685,57 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i col0[2] + (col1[2]-col0[2])*t, col0[3] + (col1[3]-col0[3])*t); } + static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) { unsigned char *cols[2]; + int elemsize = sizeof(float)*3+sizeof(unsigned char)*4; + EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm; + EditMesh *em= emdm->em; + unsigned char *varray; + int i; + GPUBuffer *buffer; cols[0] = baseCol; cols[1] = selCol; - dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); + + buffer = GPU_buffer_alloc( elemsize*em->totedge*2, 0 ); + if( (varray = GPU_buffer_lock_stream( buffer )) ) { + EditEdge *eed; + int numedges = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0,eed= em->edges.first; eed; i++,eed= eed->next) { + if(eed->h==0) { + unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0]; + unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0]; + + if( emdm->vertexCos ) { + VECCOPY(((float *)&varray[elemsize*numedges*2]),emdm->vertexCos[(int) eed->v1->tmp.l]); + } + else { + VECCOPY(((float *)&varray[elemsize*numedges*2]),eed->v1->co); + } + QUATCOPY(&varray[elemsize*numedges*2+sizeof(float)*3],col0); + if( emdm->vertexCos ) { + VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),emdm->vertexCos[(int) eed->v2->tmp.l]); + } + else { + VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),eed->v2->co); + } + QUATCOPY(&varray[elemsize*numedges*2+elemsize+sizeof(float)*3],col1); + numedges++; + } + } + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_LINES,0,numedges*2); + GPU_buffer_unbind(); + } + else { + dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); + } + GPU_buffer_free( buffer, 0 ); } /* Draw only seam edges */ @@ -1685,12 +1789,237 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) { struct { unsigned char *cols[3]; EditFace *efa_act; } data; + //EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm; + EditFace *efa; + unsigned char *col; + unsigned char *colors; + GPUBuffer *buffer; + unsigned char *varray; + unsigned char black[] = { 0, 0, 0, 0 }; + int i,j,draw=0; + int elemsize = (sizeof(float)*6+sizeof(unsigned char)*4); data.cols[0] = baseCol; data.cols[1] = selCol; data.cols[2] = actCol; data.efa_act = efa_act; - - dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0); + + + buffer = GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 ); + if( dm->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { + int prevdraw = 0; + int numfaces = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + glShadeModel(GL_SMOOTH); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0,efa= efa_act; efa; i++,efa= efa->next) { + int drawSmooth = (efa->flag & ME_SMOOTH); + if (efa->h==0) { + if (efa == data.efa_act) { + draw = 2; + } else { + col = data.cols[(efa->f&SELECT)?1:0]; + if (col[3]==0) draw = 0; + else draw = 1; + } + } + else { + draw = 0; + } + if( prevdraw != draw && prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_buffer_unlock( buffer ); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + varray = GPU_buffer_lock_stream( buffer ); + numfaces = 0; + } + + if( draw != 0 ) { + if(!drawSmooth) { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n); + /*}*/ + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + if( efa->v4 ) { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n); + /*}*/ + + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + } + } + else { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v1->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v2->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v3->no); + /*}*/ + + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + if( efa->v4 ) { + /*if (emdm->vertexCos) { + VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]); + } + else {*/ + VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v3->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v4->no); + + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co); + VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v1->no); + /*}*/ + + if( draw == 2 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]); + } + else if( draw == 1 ) { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]); + } + else { + QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black); + QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black); + } + + numfaces++; + } + } + } + prevdraw = draw; + } + GPU_buffer_unlock( buffer ); + if( prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + } + GPU_buffer_unbind(); + } else { + dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0); + } + GPU_buffer_free( buffer, 0 ); } static int draw_dm_creases__setDrawOptions(void *userData, int index) @@ -2103,12 +2432,115 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object } } else { + /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */ + GPUBuffer *buffer = GPU_buffer_alloc( sizeof(float)*6*em->totface*3*2, 0 ); + float *varray; + EditFace *efa; + int i, curmat = 0, draw = 0; + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED); glEnable(GL_LIGHTING); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0); + if( finalDM->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { + int prevdraw = 0, prevmat = 0; + int numfaces = 0; + int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END }; + GPU_buffer_unlock( buffer ); + GPU_interleaved_setup( buffer, datatype ); + glShadeModel(GL_SMOOTH); + varray = GPU_buffer_lock_stream( buffer ); + for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { + int drawSmooth = (efa->flag & ME_SMOOTH); + if( efa->h == 0 ) { + curmat = efa->mat_nr+1; + draw = 1; + } + else { + draw = 0; + } + if( ((prevdraw != draw) || (curmat != prevmat)) && prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_buffer_unlock( buffer ); + GPU_enable_material(prevmat, NULL); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + varray = GPU_buffer_lock_stream( buffer ); + numfaces = 0; + } + if( draw != 0 ) { + if(!drawSmooth) { + VECCOPY(&varray[numfaces*18],efa->v1->co); + VECCOPY(&varray[numfaces*18+3],efa->n); + + VECCOPY(&varray[numfaces*18+6],efa->v2->co); + VECCOPY(&varray[numfaces*18+9],efa->n); + + VECCOPY(&varray[numfaces*18+12],efa->v3->co); + VECCOPY(&varray[numfaces*18+15],efa->n); + numfaces++; + if( efa->v4 ) { + VECCOPY(&varray[numfaces*18],efa->v3->co); + VECCOPY(&varray[numfaces*18+3],efa->n); + + VECCOPY(&varray[numfaces*18+6],efa->v4->co); + VECCOPY(&varray[numfaces*18+9],efa->n); + + VECCOPY(&varray[numfaces*18+12],efa->v1->co); + VECCOPY(&varray[numfaces*18+15],efa->n); + numfaces++; + } + } + else { + VECCOPY(&varray[numfaces*18],efa->v1->co); + VECCOPY(&varray[numfaces*18+3],efa->v1->no); + + VECCOPY(&varray[numfaces*18+6],efa->v2->co); + VECCOPY(&varray[numfaces*18+9],efa->v2->no); + + VECCOPY(&varray[numfaces*18+12],efa->v3->co); + VECCOPY(&varray[numfaces*18+15],efa->v3->no); + numfaces++; + if( efa->v4 ) { + VECCOPY(&varray[numfaces*18],efa->v3->co); + VECCOPY(&varray[numfaces*18+3],efa->v3->no); + + VECCOPY(&varray[numfaces*18+6],efa->v4->co); + VECCOPY(&varray[numfaces*18+9],efa->v4->no); + + VECCOPY(&varray[numfaces*18+12],efa->v1->co); + VECCOPY(&varray[numfaces*18+15],efa->v1->no); + numfaces++; + } + } + } + prevdraw = draw; + prevmat = curmat; + } + GPU_buffer_unlock( buffer ); + if( prevdraw != 0 && numfaces > 0) { + if( prevdraw==2 ) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + GPU_enable_material(prevmat, NULL); + glDrawArrays(GL_TRIANGLES,0,numfaces*3); + if( prevdraw==2 ) { + glDisable(GL_POLYGON_STIPPLE); + } + } + GPU_buffer_unbind(); + } + else { + finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0); + } + GPU_buffer_free(buffer,0); glFrontFace(GL_CCW); glDisable(GL_LIGHTING); @@ -5607,6 +6039,16 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot { Mesh *me = userData; + if (!(me->mface[index].flag&ME_HIDE)) { + return 1; + } else { + return 0; + } +} +static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r) +{ + Mesh *me = userData; + if (!(me->mface[index].flag&ME_HIDE)) { WM_set_framebuffer_index_color(index+1); return 1; @@ -5620,9 +6062,41 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask); Mesh *me = (Mesh*)ob->data; + MCol *colors; + int i,j; glColor3ub(0, 0, 0); - dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0); + + if( !GPU_buffer_legacy(dm) ) { + int *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); + int ind; + colors = MEM_mallocN(dm->getNumFaces(dm)*sizeof(MCol)*4,"bbs_mesh_solid"); + for(i=0;igetNumFaces(dm);i++) { + if( index != 0 ) + ind = index[i]; + else + ind = i; + if (!(me->mface[ind].flag&ME_HIDE)) { + unsigned int fbindex = index_to_framebuffer(ind+1); + for(j=0;j<4;j++) { + colors[i*4+j].b = ((fbindex)&0xFF); + colors[i*4+j].g = (((fbindex)>>8)&0xFF); + colors[i*4+j].r = (((fbindex)>>16)&0xFF); + } + } + else { + memset(&colors[i*4],0,sizeof(MCol)*4); + } + } + + CustomData_add_layer( &dm->faceData, CD_ID_MCOL, CD_ASSIGN, colors, dm->numFaceData ); + GPU_buffer_free(dm->drawObject->colors,0); + dm->drawObject->colors = 0; + dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 1); + } + else { + dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0); + } dm->release(dm); } diff --git a/source/blender/gpu/gpu_buffers.h b/source/blender/gpu/gpu_buffers.h new file mode 100644 index 00000000000..d71c8e49acd --- /dev/null +++ b/source/blender/gpu/gpu_buffers.h @@ -0,0 +1,157 @@ +/** + * $Id: gpu_buffers.h 20687 2009-06-07 11:26:46Z imbusy $ + * + * ***** 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Brecht Van Lommel. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __GPU_BUFFERS_H__ +#define __GPU_BUFFERS_H__ + +#define MAX_FREE_GPU_BUFFERS 8 + +#ifdef _DEBUG +/*#define DEBUG_VBO(X) printf(X)*/ +#define DEBUG_VBO(X) +#else +#define DEBUG_VBO(X) +#endif + +struct DerivedMesh; + +/* V - vertex, N - normal, T - uv, C - color + F - float, UB - unsigned byte */ +#define GPU_BUFFER_INTER_V3F 1 +#define GPU_BUFFER_INTER_N3F 2 +#define GPU_BUFFER_INTER_T2F 3 +#define GPU_BUFFER_INTER_C3UB 4 +#define GPU_BUFFER_INTER_C4UB 5 +#define GPU_BUFFER_INTER_END -1 + +typedef struct GPUBuffer +{ + int size; /* in bytes */ + void *pointer; /* used with vertex arrays */ + unsigned int id; /* used with vertex buffer objects */ +} GPUBuffer; + +typedef struct GPUBufferPool +{ + int size; /* number of allocated buffers stored */ + int start; /* for a queue like structure */ + /* when running out of space for storing buffers, + the last one used will be thrown away */ + + GPUBuffer* buffers[MAX_FREE_GPU_BUFFERS]; +} GPUBufferPool; + +typedef struct GPUBufferMaterial +{ + int start; /* at which vertex in the buffer the material starts */ + int end; /* at which vertex it ends */ + char mat_nr; +} GPUBufferMaterial; + +typedef struct IndexLink { + int element; + struct IndexLink *next; +} IndexLink; + +typedef struct GPUDrawObject +{ + GPUBuffer *vertices; + GPUBuffer *normals; + GPUBuffer *uv; + GPUBuffer *colors; + GPUBuffer *edges; + GPUBuffer *uvedges; + + int *faceRemap; /* at what index was the face originally in DerivedMesh */ + IndexLink *indices; /* given an index, find all elements using it */ + IndexLink *indexMem; /* for faster memory allocation/freeing */ + int indexMemUsage; /* how many are already allocated */ + int colType; + + GPUBufferMaterial *materials; + + int nmaterials; + int nelements; /* (number of faces) * 3 */ + int nlooseverts; + int nedges; + int nindices; + int legacy; /* if there was a failure allocating some buffer, use old rendering code */ + +} GPUDrawObject; + +typedef struct GPUAttrib +{ + int index; + int size; + int type; +} GPUAttrib; + +GPUBufferPool *GPU_buffer_pool_new(); +void GPU_buffer_pool_free( GPUBufferPool *pool ); /* TODO: Find a place where to call this function on exit */ + +GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool ); +void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool ); + +GPUDrawObject *GPU_drawobject_new( struct DerivedMesh *dm ); +void GPU_drawobject_free( struct DerivedMesh *dm ); + +/* called before drawing */ +void GPU_vertex_setup( struct DerivedMesh *dm ); +void GPU_normal_setup( struct DerivedMesh *dm ); +void GPU_uv_setup( struct DerivedMesh *dm ); +void GPU_color_setup( struct DerivedMesh *dm ); +void GPU_edge_setup( struct DerivedMesh *dm ); /* does not mix with other data */ +void GPU_uvedge_setup( struct DerivedMesh *dm ); +void GPU_interleaved_setup( GPUBuffer *buffer, int data[] ); +int GPU_attrib_element_size( GPUAttrib data[], int numdata ); +void GPU_interleaved_attrib_setup( GPUBuffer *buffer, GPUAttrib data[], int numdata ); + +/* can't lock more than one buffer at once */ +void *GPU_buffer_lock( GPUBuffer *buffer ); +void *GPU_buffer_lock_stream( GPUBuffer *buffer ); +void GPU_buffer_unlock( GPUBuffer *buffer ); + +/* upload three unsigned chars, representing RGB colors, for each vertex. Resets dm->drawObject->colType to -1 */ +void GPU_color3_upload( struct DerivedMesh *dm, char *data ); +/* upload four unsigned chars, representing RGBA colors, for each vertex. Resets dm->drawObject->colType to -1 */ +void GPU_color4_upload( struct DerivedMesh *dm, char *data ); +/* switch color rendering on=1/off=0 */ +void GPU_color_switch( int mode ); + +void GPU_buffer_draw_elements( GPUBuffer *elements, unsigned int mode, int start, int count ); + +/* called after drawing */ +void GPU_buffer_unbind(); + +int GPU_buffer_legacy( struct DerivedMesh *dm ); + +#endif diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c new file mode 100644 index 00000000000..5781c852657 --- /dev/null +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -0,0 +1,1248 @@ +/** + * $Id: gpu_buffers.c 19820 2009-04-20 15:06:46Z imbusy $ + * + * ***** 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Brecht Van Lommel. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include + +#include "GL/glew.h" + +#include "DNA_userdef_types.h" + +#include "gpu_buffers.h" +#include "MEM_guardedalloc.h" +#include "BKE_DerivedMesh.h" +#include "BKE_utildefines.h" +#include "DNA_meshdata_types.h" +#include "BLI_arithb.h" + +#define GPU_BUFFER_VERTEX_STATE 1 +#define GPU_BUFFER_NORMAL_STATE 2 +#define GPU_BUFFER_TEXCOORD_STATE 4 +#define GPU_BUFFER_COLOR_STATE 8 +#define GPU_BUFFER_ELEMENT_STATE 16 + +#define MAX_GPU_ATTRIB_DATA 32 + +/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */ +int useVBOs = -1; +GPUBufferPool *globalPool = 0; +int GLStates = 0; +GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } }; + +GPUBufferPool *GPU_buffer_pool_new() +{ + GPUBufferPool *pool; + + DEBUG_VBO("GPU_buffer_pool_new\n"); + + if( useVBOs < 0 ) { + if( GL_ARB_vertex_buffer_object ) { + DEBUG_VBO( "Vertex Buffer Objects supported.\n" ); + useVBOs = 1; + } + else { + DEBUG_VBO( "Vertex Buffer Objects NOT supported.\n" ); + useVBOs = 0; + } + } + + pool = MEM_callocN(sizeof(GPUBufferPool), "GPU_buffer_pool_new"); + + return pool; +} + +void GPU_buffer_pool_free(GPUBufferPool *pool) +{ + int i; + + DEBUG_VBO("GPU_buffer_pool_free\n"); + + if( pool == 0 ) + pool = globalPool; + if( pool == 0 ) + return; + + while( pool->start < 0 ) + pool->start += MAX_FREE_GPU_BUFFERS; + + for( i = 0; i < pool->size; i++ ) { + if( useVBOs ) { + glDeleteBuffersARB( 1, &pool->buffers[(pool->start+i)%MAX_FREE_GPU_BUFFERS]->id ); + } + else { + MEM_freeN( pool->buffers[(pool->start+i)%MAX_FREE_GPU_BUFFERS]->pointer ); + } + MEM_freeN(pool->buffers[(pool->start+i)%MAX_FREE_GPU_BUFFERS]); + } + MEM_freeN(pool); +} + +void GPU_buffer_pool_remove( int index, GPUBufferPool *pool ) +{ + int i; + + DEBUG_VBO("GPU_buffer_pool_remove\n"); + + while( pool->start < 0 ) + pool->start += MAX_FREE_GPU_BUFFERS; + for( i = index; i < pool->size-1; i++ ) { + pool->buffers[(pool->start+i)%MAX_FREE_GPU_BUFFERS] = pool->buffers[(pool->start+i+1)%MAX_FREE_GPU_BUFFERS]; + } + pool->size--; +} + +void GPU_buffer_pool_delete_last( GPUBufferPool *pool ) +{ + int last; + + DEBUG_VBO("GPU_buffer_pool_delete_last\n"); + + if( pool->size == 0 ) + return; + + last = pool->start+pool->size-1; + while( last < 0 ) + last += MAX_FREE_GPU_BUFFERS; + last = (last+MAX_FREE_GPU_BUFFERS)%MAX_FREE_GPU_BUFFERS; + + if( useVBOs ) { + glDeleteBuffersARB(1,&pool->buffers[last]->id); + MEM_freeN( pool->buffers[last] ); + } + else { + MEM_freeN( pool->buffers[last]->pointer ); + MEM_freeN( pool->buffers[last] ); + } + pool->size--; +} + +GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool ) +{ + char buffer[60]; + int i; + int cursize; + GPUBuffer *allocated; + int bestfit = -1; + + DEBUG_VBO("GPU_buffer_alloc\n"); + + if( pool == 0 ) { + if( globalPool == 0 ) + globalPool = GPU_buffer_pool_new(); + pool = globalPool; + } + + while( pool->start < 0 ) + pool->start += MAX_FREE_GPU_BUFFERS; + + for( i = 0; i < pool->size; i++ ) { + int actuali = (pool->start+i)%MAX_FREE_GPU_BUFFERS; + cursize = pool->buffers[actuali]->size; + if( cursize == size ) { + allocated = pool->buffers[actuali]; + GPU_buffer_pool_remove(i,pool); + DEBUG_VBO("free buffer of exact size found\n"); + return allocated; + } + /* smaller buffers won't fit data and buffers at least twice as big are a waste of memory */ + else if( cursize > size && size > cursize/2 ) { + /* is it closer to the required size than the last appropriate buffer found. try to save memory */ + if( bestfit == -1 || pool->buffers[(pool->start+bestfit)%MAX_FREE_GPU_BUFFERS]->size > cursize ) { + bestfit = i; + } + } + } + if( bestfit == -1 ) { + DEBUG_VBO("allocating a new buffer\n"); + + allocated = MEM_mallocN(sizeof(GPUBuffer), "GPU_buffer_alloc"); + allocated->size = size; + if( useVBOs == 1 ) { + glGenBuffersARB( 1, &allocated->id ); + glBindBufferARB( GL_ARRAY_BUFFER_ARB, allocated->id ); + glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, 0, GL_STATIC_DRAW_ARB ); + glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + } + else { + allocated->pointer = MEM_mallocN(size, "GPU_buffer_alloc_vertexarray"); + while( allocated->pointer == 0 && pool->size > 0 ) { + GPU_buffer_pool_delete_last(pool); + allocated->pointer = MEM_mallocN(size, "GPU_buffer_alloc_vertexarray"); + } + if( allocated->pointer == 0 && pool->size == 0 ) { + return 0; + } + } + } + else { + sprintf(buffer,"free buffer found. Wasted %d bytes\n", pool->buffers[(pool->start+bestfit)%MAX_FREE_GPU_BUFFERS]->size-size); + DEBUG_VBO(buffer); + + allocated = pool->buffers[(pool->start+bestfit)%MAX_FREE_GPU_BUFFERS]; + GPU_buffer_pool_remove(bestfit,pool); + } + return allocated; +} + +void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool ) +{ + int place; + + DEBUG_VBO("GPU_buffer_free\n"); + + if( buffer == 0 ) + return; + if( pool == 0 ) + pool = globalPool; + if( pool == 0 ) + globalPool = GPU_buffer_pool_new(); + + while( pool->start < 0 ) + pool->start += MAX_FREE_GPU_BUFFERS; + place = (pool->start-1 + MAX_FREE_GPU_BUFFERS)%MAX_FREE_GPU_BUFFERS; + + /* free the last used buffer in the queue if no more space */ + if( pool->size == MAX_FREE_GPU_BUFFERS ) { + GPU_buffer_pool_delete_last( pool ); + } + + pool->size++; + pool->start = place; + pool->buffers[place] = buffer; +} + +GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm ) +{ + GPUDrawObject *object; + MVert *mvert; + MFace *mface; + int numverts[32768]; /* material number is an 16-bit short so there's at most 32768 materials */ + int redir[32768]; /* material number is an 16-bit short so there's at most 32768 materials */ + int *index; + int i; + int curmat, curverts; + + DEBUG_VBO("GPU_drawobject_new\n"); + + object = MEM_callocN(sizeof(GPUDrawObject),"GPU_drawobject_new_object"); + object->nindices = dm->getNumVerts(dm); + object->indices = MEM_mallocN(sizeof(IndexLink)*object->nindices, "GPU_drawobject_new_indices"); + object->nedges = dm->getNumEdges(dm); + + for( i = 0; i < object->nindices; i++ ) { + object->indices[i].element = -1; + object->indices[i].next = 0; + } + /*object->legacy = 1;*/ + memset(numverts,0,sizeof(int)*32768); + + mvert = dm->getVertArray(dm); + mface = dm->getFaceArray(dm); + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + if( mface[i].v4 ) + numverts[mface[i].mat_nr+16383] += 6; /* split every quad into two triangles */ + else + numverts[mface[i].mat_nr+16383] += 3; + } + + for( i = 0; i < 32768; i++ ) { + if( numverts[i] > 0 ) { + object->nmaterials++; + object->nelements += numverts[i]; + } + } + object->materials = MEM_mallocN(sizeof(GPUBufferMaterial)*object->nmaterials,"GPU_drawobject_new_materials"); + index = MEM_mallocN(sizeof(int)*object->nmaterials,"GPU_drawobject_new_index"); + + curmat = curverts = 0; + for( i = 0; i < 32768; i++ ) { + if( numverts[i] > 0 ) { + object->materials[curmat].mat_nr = i-16383; + object->materials[curmat].start = curverts; + index[curmat] = curverts/3; + object->materials[curmat].end = curverts+numverts[i]; + curverts += numverts[i]; + curmat++; + } + } + object->faceRemap = MEM_mallocN(sizeof(int)*object->nelements/3,"GPU_drawobject_new_faceRemap"); + for( i = 0; i < object->nmaterials; i++ ) { + redir[object->materials[i].mat_nr+16383] = i; /* material number -> material index */ + } + + object->indexMem = MEM_callocN(sizeof(IndexLink)*object->nelements,"GPU_drawobject_new_indexMem"); + object->indexMemUsage = 0; + +#define ADDLINK( INDEX, ACTUAL ) \ + if( object->indices[INDEX].element == -1 ) { \ + object->indices[INDEX].element = ACTUAL; \ + } else { \ + IndexLink *lnk = &object->indices[INDEX]; \ + while( lnk->next != 0 ) lnk = lnk->next; \ + lnk->next = &object->indexMem[object->indexMemUsage]; \ + lnk->next->element = ACTUAL; \ + object->indexMemUsage++; \ + } + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + int curInd = index[redir[mface[i].mat_nr+16383]]; + object->faceRemap[curInd] = i; + ADDLINK( mface[i].v1, curInd*3 ); + ADDLINK( mface[i].v2, curInd*3+1 ); + ADDLINK( mface[i].v3, curInd*3+2 ); + if( mface[i].v4 ) { + object->faceRemap[curInd+1] = i; + ADDLINK( mface[i].v3, curInd*3+3 ); + ADDLINK( mface[i].v4, curInd*3+4 ); + ADDLINK( mface[i].v1, curInd*3+5 ); + + index[redir[mface[i].mat_nr+16383]]+=2; + } + else { + index[redir[mface[i].mat_nr+16383]]++; + } + } + + for( i = 0; i < object->nindices; i++ ) { + if( object->indices[i].element == -1 ) { + object->indices[i].element = object->nelements + object->nlooseverts; + object->nlooseverts++; + } + } +#undef ADDLINK + + MEM_freeN(index); + return object; +} + +void GPU_drawobject_free( DerivedMesh *dm ) +{ + GPUDrawObject *object; + + DEBUG_VBO("GPU_drawobject_free\n"); + + if( dm == 0 ) + return; + object = dm->drawObject; + if( object == 0 ) + return; + + MEM_freeN(object->materials); + MEM_freeN(object->faceRemap); + MEM_freeN(object->indices); + MEM_freeN(object->indexMem); + GPU_buffer_free( object->vertices, globalPool ); + GPU_buffer_free( object->normals, globalPool ); + GPU_buffer_free( object->uv, globalPool ); + GPU_buffer_free( object->colors, globalPool ); + GPU_buffer_free( object->edges, globalPool ); + GPU_buffer_free( object->uvedges, globalPool ); + + MEM_freeN(object); + dm->drawObject = 0; +} + +GPUBuffer *GPU_buffer_setup( DerivedMesh *dm, GPUDrawObject *object, int size, GLenum target, void *user, void (*copy_f)(DerivedMesh *, float *, int *, int *, void *) ) +{ + GPUBuffer *buffer; + float *varray; + int redir[32768]; + int *index; + int i; + int success; + GLboolean uploaded; + + DEBUG_VBO("GPU_buffer_setup\n"); + + if( globalPool == 0 ) { + globalPool = GPU_buffer_pool_new(); + + /* somehow GL_NORMAL_ARRAY is enabled on startup and causes edge drawing code to crash */ + glDisableClientState( GL_VERTEX_ARRAY ); + glDisableClientState( GL_NORMAL_ARRAY ); + glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + glDisableClientState( GL_COLOR_ARRAY ); + } + buffer = GPU_buffer_alloc(size,globalPool); + if( buffer == 0 ) { + dm->drawObject->legacy = 1; + } + if( dm->drawObject->legacy ) { + return 0; + } + + index = MEM_mallocN(sizeof(int)*object->nmaterials,"GPU_buffer_setup"); + for( i = 0; i < object->nmaterials; i++ ) { + index[i] = object->materials[i].start*3; + redir[object->materials[i].mat_nr+16383] = i; + } + + if( useVBOs ) { + success = 0; + while( success == 0 ) { + glBindBufferARB( target, buffer->id ); + glBufferDataARB( target, buffer->size, 0, GL_STATIC_DRAW_ARB ); /* discard previous data, avoid stalling gpu */ + varray = glMapBufferARB( target, GL_WRITE_ONLY_ARB ); + if( varray == 0 ) { + DEBUG_VBO( "Failed to map buffer to client address space\n" ); + GPU_buffer_free( buffer, globalPool ); + GPU_buffer_pool_delete_last( globalPool ); + if( globalPool->size > 0 ) { + GPU_buffer_pool_delete_last( globalPool ); + buffer = GPU_buffer_alloc( size, globalPool ); + if( buffer == 0 ) { + dm->drawObject->legacy = 1; + success = 1; + } + } + else { + dm->drawObject->legacy = 1; + success = 1; + } + } + else { + success = 1; + } + } + + if( dm->drawObject->legacy == 0 ) { + uploaded = GL_FALSE; + while( !uploaded ) { + (*copy_f)( dm, varray, index, redir, user ); + uploaded = glUnmapBufferARB( target ); /* returns false if data got corruped during transfer */ + } + } + glBindBufferARB(target, 0); + } + else { + if( buffer->pointer != 0 ) { + varray = buffer->pointer; + (*copy_f)( dm, varray, index, redir, user ); + } + else { + dm->drawObject->legacy = 1; + } + } + + MEM_freeN(index); + + return buffer; +} + +void GPU_buffer_copy_vertex( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) +{ + int start; + int i, j; + + MVert *mvert; + MFace *mface; + + DEBUG_VBO("GPU_buffer_copy_vertex\n"); + + mvert = dm->getVertArray(dm); + mface = dm->getFaceArray(dm); + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + start = index[redir[mface[i].mat_nr+16383]]; + if( mface[i].v4 ) + index[redir[mface[i].mat_nr+16383]] += 18; + else + index[redir[mface[i].mat_nr+16383]] += 9; + + /* v1 v2 v3 */ + VECCOPY(&varray[start],mvert[mface[i].v1].co); + VECCOPY(&varray[start+3],mvert[mface[i].v2].co); + VECCOPY(&varray[start+6],mvert[mface[i].v3].co); + + if( mface[i].v4 ) { + /* v3 v4 v1 */ + VECCOPY(&varray[start+9],mvert[mface[i].v3].co); + VECCOPY(&varray[start+12],mvert[mface[i].v4].co); + VECCOPY(&varray[start+15],mvert[mface[i].v1].co); + } + } + j = dm->drawObject->nelements*3; + for( i = 0; i < dm->drawObject->nindices; i++ ) { + if( dm->drawObject->indices[i].element >= dm->drawObject->nelements ) { + VECCOPY(&varray[j],mvert[i].co); + j+=3; + } + } +} + +GPUBuffer *GPU_buffer_vertex( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_buffer_vertex\n"); + + return GPU_buffer_setup( dm, dm->drawObject, sizeof(float)*3*(dm->drawObject->nelements+dm->drawObject->nlooseverts), GL_ARRAY_BUFFER_ARB, 0, GPU_buffer_copy_vertex); +} + +void GPU_buffer_copy_normal( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) +{ + int i; + int start; + float norm[3]; + + float *nors= dm->getFaceDataArray(dm, CD_NORMAL); + MVert *mvert = dm->getVertArray(dm); + MFace *mface = dm->getFaceArray(dm); + + DEBUG_VBO("GPU_buffer_copy_normal\n"); + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + start = index[redir[mface[i].mat_nr+16383]]; + if( mface[i].v4 ) + index[redir[mface[i].mat_nr+16383]] += 18; + else + index[redir[mface[i].mat_nr+16383]] += 9; + + /* v1 v2 v3 */ + if( mface[i].flag & ME_SMOOTH ) { + VECCOPY(&varray[start],mvert[mface[i].v1].no); + VECCOPY(&varray[start+3],mvert[mface[i].v2].no); + VECCOPY(&varray[start+6],mvert[mface[i].v3].no); + } + else { + if( nors ) { + VECCOPY(&varray[start],&nors[i*3]); + VECCOPY(&varray[start+3],&nors[i*3]); + VECCOPY(&varray[start+6],&nors[i*3]); + } + if( mface[i].v4 ) + CalcNormFloat4(mvert[mface[i].v1].co, mvert[mface[i].v2].co, mvert[mface[i].v3].co, mvert[mface[i].v4].co, norm); + else + CalcNormFloat(mvert[mface[i].v1].co, mvert[mface[i].v2].co, mvert[mface[i].v3].co, norm); + VECCOPY(&varray[start],norm); + VECCOPY(&varray[start+3],norm); + VECCOPY(&varray[start+6],norm); + } + + if( mface[i].v4 ) { + /* v3 v4 v1 */ + if( mface[i].flag & ME_SMOOTH ) { + VECCOPY(&varray[start+9],mvert[mface[i].v3].no); + VECCOPY(&varray[start+12],mvert[mface[i].v4].no); + VECCOPY(&varray[start+15],mvert[mface[i].v1].no); + } + else { + VECCOPY(&varray[start+9],norm); + VECCOPY(&varray[start+12],norm); + VECCOPY(&varray[start+15],norm); + } + } + } +} + +GPUBuffer *GPU_buffer_normal( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_buffer_normal\n"); + + return GPU_buffer_setup( dm, dm->drawObject, sizeof(float)*3*dm->drawObject->nelements, GL_ARRAY_BUFFER_ARB, 0, GPU_buffer_copy_normal); +} + +void GPU_buffer_copy_uv( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) +{ + int start; + int i; + + MTFace *mtface; + MFace *mface; + + DEBUG_VBO("GPU_buffer_copy_uv\n"); + + mface = dm->getFaceArray(dm); + mtface = DM_get_face_data_layer(dm, CD_MTFACE); + + if( mtface == 0 ) { + DEBUG_VBO("Texture coordinates do not exist for this mesh"); + return; + } + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + start = index[redir[mface[i].mat_nr+16383]]; + if( mface[i].v4 ) + index[redir[mface[i].mat_nr+16383]] += 12; + else + index[redir[mface[i].mat_nr+16383]] += 6; + + /* v1 v2 v3 */ + VECCOPY2D(&varray[start],mtface[i].uv[0]); + VECCOPY2D(&varray[start+2],mtface[i].uv[1]); + VECCOPY2D(&varray[start+4],mtface[i].uv[2]); + + if( mface[i].v4 ) { + /* v3 v4 v1 */ + VECCOPY2D(&varray[start+6],mtface[i].uv[2]); + VECCOPY2D(&varray[start+8],mtface[i].uv[3]); + VECCOPY2D(&varray[start+10],mtface[i].uv[0]); + } + } +} + +GPUBuffer *GPU_buffer_uv( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_buffer_uv\n"); + if( DM_get_face_data_layer(dm, CD_MTFACE) != 0 ) + return GPU_buffer_setup( dm, dm->drawObject, sizeof(float)*2*dm->drawObject->nelements, GL_ARRAY_BUFFER_ARB, 0, GPU_buffer_copy_uv); + else + return 0; +} + +void GPU_buffer_copy_color3( DerivedMesh *dm, float *varray_, int *index, int *redir, void *user ) +{ + int i; + unsigned char *varray = (unsigned char *)varray_; + unsigned char *mcol = (unsigned char *)user; + MFace *mface = dm->getFaceArray(dm); + + DEBUG_VBO("GPU_buffer_copy_color3\n"); + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + int start = index[redir[mface[i].mat_nr+16383]]; + if( mface[i].v4 ) + index[redir[mface[i].mat_nr+16383]] += 18; + else + index[redir[mface[i].mat_nr+16383]] += 9; + + /* v1 v2 v3 */ + VECCOPY(&varray[start],&mcol[i*12]); + VECCOPY(&varray[start+3],&mcol[i*12+3]); + VECCOPY(&varray[start+6],&mcol[i*12+6]); + if( mface[i].v4 ) { + /* v3 v4 v1 */ + VECCOPY(&varray[start+9],&mcol[i*12+6]); + VECCOPY(&varray[start+12],&mcol[i*12+9]); + VECCOPY(&varray[start+15],&mcol[i*12]); + } + } +} + +void GPU_buffer_copy_color4( DerivedMesh *dm, float *varray_, int *index, int *redir, void *user ) +{ + int i; + unsigned char *varray = (unsigned char *)varray_; + unsigned char *mcol = (unsigned char *)user; + MFace *mface = dm->getFaceArray(dm); + + DEBUG_VBO("GPU_buffer_copy_color4\n"); + + for( i=0; i < dm->getNumFaces(dm); i++ ) { + int start = index[redir[mface[i].mat_nr+16383]]; + if( mface[i].v4 ) + index[redir[mface[i].mat_nr+16383]] += 18; + else + index[redir[mface[i].mat_nr+16383]] += 9; + + /* v1 v2 v3 */ + VECCOPY(&varray[start],&mcol[i*16]); + VECCOPY(&varray[start+3],&mcol[i*16+4]); + VECCOPY(&varray[start+6],&mcol[i*16+8]); + if( mface[i].v4 ) { + /* v3 v4 v1 */ + VECCOPY(&varray[start+9],&mcol[i*16+8]); + VECCOPY(&varray[start+12],&mcol[i*16+12]); + VECCOPY(&varray[start+15],&mcol[i*16]); + } + } +} + +GPUBuffer *GPU_buffer_color( DerivedMesh *dm ) +{ + unsigned char *colors; + int i; + MCol *mcol; + GPUBuffer *result; + DEBUG_VBO("GPU_buffer_color\n"); + + mcol = DM_get_face_data_layer(dm, CD_ID_MCOL); + dm->drawObject->colType = CD_ID_MCOL; + if(!mcol) { + mcol = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL); + dm->drawObject->colType = CD_WEIGHT_MCOL; + } + if(!mcol) { + mcol = DM_get_face_data_layer(dm, CD_MCOL); + dm->drawObject->colType = CD_MCOL; + } + + colors = MEM_mallocN(dm->getNumFaces(dm)*12*sizeof(unsigned char), "GPU_buffer_color"); + for( i=0; i < dm->getNumFaces(dm)*4; i++ ) { + colors[i*3] = mcol[i].b; + colors[i*3+1] = mcol[i].g; + colors[i*3+2] = mcol[i].r; + } + + result = GPU_buffer_setup( dm, dm->drawObject, sizeof(char)*3*dm->drawObject->nelements, GL_ARRAY_BUFFER_ARB, colors, GPU_buffer_copy_color3 ); + + MEM_freeN(colors); + return result; +} + +void GPU_buffer_copy_edge( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) +{ + int i; + + MVert *mvert; + MEdge *medge; + unsigned int *varray_ = (unsigned int *)varray; + + DEBUG_VBO("GPU_buffer_copy_edge\n"); + + mvert = dm->getVertArray(dm); + medge = dm->getEdgeArray(dm); + + for(i = 0; i < dm->getNumEdges(dm); i++) { + varray_[i*2] = (unsigned int)dm->drawObject->indices[medge[i].v1].element; + varray_[i*2+1] = (unsigned int)dm->drawObject->indices[medge[i].v2].element; + } +} + +GPUBuffer *GPU_buffer_edge( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_buffer_edge\n"); + + return GPU_buffer_setup( dm, dm->drawObject, sizeof(int)*2*dm->drawObject->nedges, GL_ELEMENT_ARRAY_BUFFER_ARB, 0, GPU_buffer_copy_edge); +} + +void GPU_buffer_copy_uvedge( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) +{ + MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); + int i, j=0; + + DEBUG_VBO("GPU_buffer_copy_uvedge\n"); + + if(tf) { + for(i = 0; i < dm->numFaceData; i++, tf++) { + MFace mf; + dm->getFace(dm,i,&mf); + + VECCOPY2D(&varray[j],tf->uv[0]); + VECCOPY2D(&varray[j+2],tf->uv[1]); + + VECCOPY2D(&varray[j+4],tf->uv[1]); + VECCOPY2D(&varray[j+6],tf->uv[2]); + + if(!mf.v4) { + VECCOPY2D(&varray[j+8],tf->uv[2]); + VECCOPY2D(&varray[j+10],tf->uv[0]); + j+=12; + } else { + VECCOPY2D(&varray[j+8],tf->uv[2]); + VECCOPY2D(&varray[j+10],tf->uv[3]); + + VECCOPY2D(&varray[j+12],tf->uv[3]); + VECCOPY2D(&varray[j+14],tf->uv[0]); + j+=16; + } + } + } + else { + DEBUG_VBO("Could not get MTFACE data layer"); + } +} + +GPUBuffer *GPU_buffer_uvedge( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_buffer_uvedge\n"); + + return GPU_buffer_setup( dm, dm->drawObject, sizeof(float)*2*(dm->drawObject->nelements/3)*2, GL_ARRAY_BUFFER_ARB, 0, GPU_buffer_copy_uvedge); +} + + +void GPU_vertex_setup( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_vertex_setup\n"); + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new( dm ); + if( dm->drawObject->vertices == 0 ) + dm->drawObject->vertices = GPU_buffer_vertex( dm ); + if( dm->drawObject->vertices == 0 ) { + DEBUG_VBO( "Failed to setup vertices\n" ); + return; + } + + glEnableClientState( GL_VERTEX_ARRAY ); + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, dm->drawObject->vertices->id ); + glVertexPointer( 3, GL_FLOAT, 0, 0 ); + } + else { + glVertexPointer( 3, GL_FLOAT, 0, dm->drawObject->vertices->pointer ); + } + + GLStates |= GPU_BUFFER_VERTEX_STATE; +} + +void GPU_normal_setup( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_normal_setup\n"); + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new( dm ); + if( dm->drawObject->normals == 0 ) + dm->drawObject->normals = GPU_buffer_normal( dm ); + if( dm->drawObject->normals == 0 ) { + DEBUG_VBO( "Failed to setup normals\n" ); + return; + } + glEnableClientState( GL_NORMAL_ARRAY ); + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, dm->drawObject->normals->id ); + glNormalPointer( GL_FLOAT, 0, 0 ); + } + else { + glNormalPointer( GL_FLOAT, 0, dm->drawObject->normals->pointer ); + } + + GLStates |= GPU_BUFFER_NORMAL_STATE; +} + +void GPU_uv_setup( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_uv_setup\n"); + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new( dm ); + if( dm->drawObject->uv == 0 ) + dm->drawObject->uv = GPU_buffer_uv( dm ); + + if( dm->drawObject->uv != 0 ) { + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id ); + glTexCoordPointer( 2, GL_FLOAT, 0, 0 ); + } + else { + glTexCoordPointer( 2, GL_FLOAT, 0, dm->drawObject->uv->pointer ); + } + + GLStates |= GPU_BUFFER_TEXCOORD_STATE; + } +} + +void GPU_color_setup( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_color_setup\n"); + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new( dm ); + if( dm->drawObject->colors == 0 ) + dm->drawObject->colors = GPU_buffer_color( dm ); + if( dm->drawObject->colors == 0 ) { + DEBUG_VBO( "Failed to setup colors\n" ); + return; + } + glEnableClientState( GL_COLOR_ARRAY ); + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, dm->drawObject->colors->id ); + glColorPointer( 3, GL_UNSIGNED_BYTE, 0, 0 ); + } + else { + glColorPointer( 3, GL_UNSIGNED_BYTE, 0, dm->drawObject->colors->pointer ); + } + + GLStates |= GPU_BUFFER_COLOR_STATE; +} + +void GPU_edge_setup( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_edge_setup\n"); + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new( dm ); + if( dm->drawObject->edges == 0 ) + dm->drawObject->edges = GPU_buffer_edge( dm ); + if( dm->drawObject->edges == 0 ) { + DEBUG_VBO( "Failed to setup edges\n" ); + return; + } + if( dm->drawObject->vertices == 0 ) + dm->drawObject->vertices = GPU_buffer_vertex( dm ); + if( dm->drawObject->vertices == 0 ) { + DEBUG_VBO( "Failed to setup vertices\n" ); + return; + } + + glEnableClientState( GL_VERTEX_ARRAY ); + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, dm->drawObject->vertices->id ); + glVertexPointer( 3, GL_FLOAT, 0, 0 ); + } + else { + glVertexPointer( 3, GL_FLOAT, 0, dm->drawObject->vertices->pointer ); + } + + GLStates |= GPU_BUFFER_VERTEX_STATE; + + if( useVBOs ) { + glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, dm->drawObject->edges->id ); + } + + GLStates |= GPU_BUFFER_ELEMENT_STATE; +} + +void GPU_uvedge_setup( DerivedMesh *dm ) +{ + DEBUG_VBO("GPU_uvedge_setup\n"); + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new( dm ); + if( dm->drawObject->uvedges == 0 ) + dm->drawObject->uvedges = GPU_buffer_uvedge( dm ); + if( dm->drawObject->uvedges == 0 ) { + DEBUG_VBO( "Failed to setup UV edges\n" ); + return; + } + + glEnableClientState( GL_VERTEX_ARRAY ); + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, dm->drawObject->uvedges->id ); + glVertexPointer( 2, GL_FLOAT, 0, 0 ); + } + else { + glVertexPointer( 2, GL_FLOAT, 0, dm->drawObject->uvedges->pointer ); + } + + GLStates |= GPU_BUFFER_VERTEX_STATE; +} + +void GPU_interleaved_setup( GPUBuffer *buffer, int data[] ) { + int i; + int elementsize = 0; + int offset = 0; + + DEBUG_VBO("GPU_interleaved_setup\n"); + + for( i = 0; data[i] != GPU_BUFFER_INTER_END; i++ ) { + switch( data[i] ) { + case GPU_BUFFER_INTER_V3F: + elementsize += 3*sizeof(float); + break; + case GPU_BUFFER_INTER_N3F: + elementsize += 3*sizeof(float); + break; + case GPU_BUFFER_INTER_T2F: + elementsize += 2*sizeof(float); + break; + case GPU_BUFFER_INTER_C3UB: + elementsize += 3*sizeof(unsigned char); + break; + case GPU_BUFFER_INTER_C4UB: + elementsize += 4*sizeof(unsigned char); + break; + default: + DEBUG_VBO( "Unknown element in data type array in GPU_interleaved_setup\n" ); + } + } + + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer->id ); + for( i = 0; data[i] != GPU_BUFFER_INTER_END; i++ ) { + switch( data[i] ) { + case GPU_BUFFER_INTER_V3F: + glEnableClientState( GL_VERTEX_ARRAY ); + glVertexPointer( 3, GL_FLOAT, elementsize, (void *)offset ); + GLStates |= GPU_BUFFER_VERTEX_STATE; + offset += 3*sizeof(float); + break; + case GPU_BUFFER_INTER_N3F: + glEnableClientState( GL_NORMAL_ARRAY ); + glNormalPointer( GL_FLOAT, elementsize, (void *)offset ); + GLStates |= GPU_BUFFER_NORMAL_STATE; + offset += 3*sizeof(float); + break; + case GPU_BUFFER_INTER_T2F: + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + glTexCoordPointer( 2, GL_FLOAT, elementsize, (void *)offset ); + GLStates |= GPU_BUFFER_TEXCOORD_STATE; + offset += 2*sizeof(float); + break; + case GPU_BUFFER_INTER_C3UB: + glEnableClientState( GL_COLOR_ARRAY ); + glColorPointer( 3, GL_UNSIGNED_BYTE, elementsize, (void *)offset ); + GLStates |= GPU_BUFFER_COLOR_STATE; + offset += 3*sizeof(unsigned char); + break; + case GPU_BUFFER_INTER_C4UB: + glEnableClientState( GL_COLOR_ARRAY ); + glColorPointer( 4, GL_UNSIGNED_BYTE, elementsize, (void *)offset ); + GLStates |= GPU_BUFFER_COLOR_STATE; + offset += 4*sizeof(unsigned char); + break; + } + } + } + else { + for( i = 0; data[i] != GPU_BUFFER_INTER_END; i++ ) { + switch( data[i] ) { + case GPU_BUFFER_INTER_V3F: + glEnableClientState( GL_VERTEX_ARRAY ); + glVertexPointer( 3, GL_FLOAT, elementsize, offset+(char *)buffer->pointer ); + GLStates |= GPU_BUFFER_VERTEX_STATE; + offset += 3*sizeof(float); + break; + case GPU_BUFFER_INTER_N3F: + glEnableClientState( GL_NORMAL_ARRAY ); + glNormalPointer( GL_FLOAT, elementsize, offset+(char *)buffer->pointer ); + GLStates |= GPU_BUFFER_NORMAL_STATE; + offset += 3*sizeof(float); + break; + case GPU_BUFFER_INTER_T2F: + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + glTexCoordPointer( 2, GL_FLOAT, elementsize, offset+(char *)buffer->pointer ); + GLStates |= GPU_BUFFER_TEXCOORD_STATE; + offset += 2*sizeof(float); + break; + case GPU_BUFFER_INTER_C3UB: + glEnableClientState( GL_COLOR_ARRAY ); + glColorPointer( 3, GL_UNSIGNED_BYTE, elementsize, offset+(char *)buffer->pointer ); + GLStates |= GPU_BUFFER_COLOR_STATE; + offset += 3*sizeof(unsigned char); + break; + case GPU_BUFFER_INTER_C4UB: + glEnableClientState( GL_COLOR_ARRAY ); + glColorPointer( 4, GL_UNSIGNED_BYTE, elementsize, offset+(char *)buffer->pointer ); + GLStates |= GPU_BUFFER_COLOR_STATE; + offset += 4*sizeof(unsigned char); + break; + } + } + } +} + +static int GPU_typesize( int type ) { + switch( type ) { + case GL_FLOAT: + return sizeof(float); + case GL_INT: + return sizeof(int); + case GL_UNSIGNED_INT: + return sizeof(unsigned int); + case GL_BYTE: + return sizeof(char); + case GL_UNSIGNED_BYTE: + return sizeof(unsigned char); + default: + return 0; + } +} + +int GPU_attrib_element_size( GPUAttrib data[], int numdata ) { + int i, elementsize = 0; + + for( i = 0; i < numdata; i++ ) { + int typesize = GPU_typesize(data[i].type); + if( typesize == 0 ) + DEBUG_VBO( "Unknown element in data type array in GPU_attrib_element_size\n" ); + else { + elementsize += typesize*data[i].size; + } + } + return elementsize; +} + +void GPU_interleaved_attrib_setup( GPUBuffer *buffer, GPUAttrib data[], int numdata ) { + int i; + int elementsize; + int offset = 0; + + DEBUG_VBO("GPU_interleaved_attrib_setup\n"); + + for( i = 0; i < MAX_GPU_ATTRIB_DATA; i++ ) { + if( attribData[i].index != -1 ) { + glDisableVertexAttribArrayARB( attribData[i].index ); + } + else + break; + } + elementsize = GPU_attrib_element_size( data, numdata ); + + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer->id ); + for( i = 0; i < numdata; i++ ) { + glEnableVertexAttribArrayARB( data[i].index ); + glVertexAttribPointerARB( data[i].index, data[i].size, data[i].type, GL_TRUE, elementsize, (void *)offset ); + offset += data[i].size*GPU_typesize(data[i].type); + + attribData[i].index = data[i].index; + attribData[i].size = data[i].size; + attribData[i].type = data[i].type; + } + attribData[numdata].index = -1; + } + else { + for( i = 0; i < numdata; i++ ) { + glEnableVertexAttribArrayARB( data[i].index ); + glVertexAttribPointerARB( data[i].index, data[i].size, data[i].type, GL_TRUE, elementsize, (char *)buffer->pointer + offset ); + offset += data[i].size*GPU_typesize(data[i].type); + } + } +} + + +void GPU_buffer_unbind() +{ + int i; + DEBUG_VBO("GPU_buffer_unbind\n"); + + if( GLStates & GPU_BUFFER_VERTEX_STATE ) + glDisableClientState( GL_VERTEX_ARRAY ); + if( GLStates & GPU_BUFFER_NORMAL_STATE ) + glDisableClientState( GL_NORMAL_ARRAY ); + if( GLStates & GPU_BUFFER_TEXCOORD_STATE ) + glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + if( GLStates & GPU_BUFFER_COLOR_STATE ) + glDisableClientState( GL_COLOR_ARRAY ); + if( GLStates & GPU_BUFFER_ELEMENT_STATE ) { + if( useVBOs ) { + glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); + } + } + GLStates &= !(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE | GPU_BUFFER_TEXCOORD_STATE | GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE); + + for( i = 0; i < MAX_GPU_ATTRIB_DATA; i++ ) { + if( attribData[i].index != -1 ) { + glDisableVertexAttribArrayARB( attribData[i].index ); + } + else + break; + } + if( GLStates != 0 ) + DEBUG_VBO( "Some weird OpenGL state is still set. Why?" ); + if( useVBOs ) + glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); +} + +void GPU_color3_upload( DerivedMesh *dm, char *data ) +{ + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new(dm); + GPU_buffer_free(dm->drawObject->colors,globalPool); + dm->drawObject->colors = GPU_buffer_setup( dm, dm->drawObject, sizeof(char)*3*dm->drawObject->nelements, GL_ARRAY_BUFFER_ARB, data, GPU_buffer_copy_color3 ); +} +void GPU_color4_upload( DerivedMesh *dm, char *data ) +{ + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new(dm); + GPU_buffer_free(dm->drawObject->colors,globalPool); + dm->drawObject->colors = GPU_buffer_setup( dm, dm->drawObject, sizeof(char)*3*dm->drawObject->nelements, GL_ARRAY_BUFFER_ARB, data, GPU_buffer_copy_color4 ); +} + +void GPU_color_switch( int mode ) +{ + if( mode ) { + if( !GLStates & GPU_BUFFER_COLOR_STATE ) + glEnableClientState( GL_COLOR_ARRAY ); + GLStates |= GPU_BUFFER_COLOR_STATE; + } + else { + if( GLStates & GPU_BUFFER_COLOR_STATE ) + glDisableClientState( GL_COLOR_ARRAY ); + GLStates &= (!GPU_BUFFER_COLOR_STATE); + } +} + +int GPU_buffer_legacy( DerivedMesh *dm ) +{ + int test= (U.gameflags & USER_DISABLE_VBO); + if( test ) + return 1; + + if( dm->drawObject == 0 ) + dm->drawObject = GPU_drawobject_new(dm); + return dm->drawObject->legacy; +} + +void *GPU_buffer_lock( GPUBuffer *buffer ) +{ + float *varray; + + DEBUG_VBO("GPU_buffer_lock\n"); + if( buffer == 0 ) { + DEBUG_VBO( "Failed to lock NULL buffer\n" ); + return 0; + } + + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer->id ); + varray = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB ); + if( varray == 0 ) { + DEBUG_VBO( "Failed to map buffer to client address space\n" ); + } + return varray; + } + else { + return buffer->pointer; + } +} + +void *GPU_buffer_lock_stream( GPUBuffer *buffer ) +{ + float *varray; + + DEBUG_VBO("GPU_buffer_lock_stream\n"); + if( buffer == 0 ) { + DEBUG_VBO( "Failed to lock NULL buffer\n" ); + return 0; + } + + if( useVBOs ) { + glBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer->id ); + glBufferDataARB( GL_ARRAY_BUFFER_ARB, buffer->size, 0, GL_STREAM_DRAW_ARB ); /* discard previous data, avoid stalling gpu */ + varray = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB ); + if( varray == 0 ) { + DEBUG_VBO( "Failed to map buffer to client address space\n" ); + } + return varray; + } + else { + return buffer->pointer; + } +} + +void GPU_buffer_unlock( GPUBuffer *buffer ) +{ + DEBUG_VBO( "GPU_buffer_unlock\n" ); + if( useVBOs ) { + if( buffer != 0 ) { + if( glUnmapBufferARB( GL_ARRAY_BUFFER_ARB ) == 0 ) { + DEBUG_VBO( "Failed to copy new data\n" ); + } + } + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + +void GPU_buffer_draw_elements( GPUBuffer *elements, unsigned int mode, int start, int count ) +{ + if( useVBOs ) { + glDrawElements( mode, count, GL_UNSIGNED_INT, (void *)(start*sizeof(unsigned int)) ); + } + else { + glDrawElements( mode, count, GL_UNSIGNED_INT, ((int *)elements->pointer)+start ); + } +} \ No newline at end of file diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 18c18d9e9dd..ad686e37097 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -76,7 +76,9 @@ typedef struct CustomData { #define CD_TANGENT 18 #define CD_MDISPS 19 #define CD_WEIGHT_MCOL 20 /* for displaying weightpaint colors */ -#define CD_NUMTYPES 21 +#define CD_ID_MCOL 21 +#define CD_TEXTURE_MCOL 22 +#define CD_NUMTYPES 23 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 826eea43a4d..16ab3e1e9bd 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -446,6 +446,7 @@ extern UserDef U; /* from blenkernel blender.c */ #define USER_DEPRECATED_FLAG 1 #define USER_DISABLE_SOUND 2 #define USER_DISABLE_MIPMAP 4 +#define USER_DISABLE_VBO 8 /* wm draw method */ #define USER_DRAW_TRIPLE 0 diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index e9fcb299c53..25448d0c2de 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2173,6 +2173,10 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_MIPMAP); RNA_def_property_ui_text(prop, "Mipmaps", "Scale textures for the 3d View (looks nicer but uses more memory and slows image reloading.)"); + prop= RNA_def_property(srna, "use_vbos", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO); + RNA_def_property_ui_text(prop, "VBOs", "Use Vertex Buffer Objects (or Vertex Arrays, if unsupported) for viewport rendering."); + prop= RNA_def_property(srna, "gl_texture_limit", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "glreslimit"); RNA_def_property_enum_items(prop, gl_texture_clamp_items); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index f8985fd6531..b4328d12e81 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -86,6 +86,7 @@ #include "UI_interface.h" #include "BLF_api.h" +#include "gpu_buffers.h" #include "GPU_extensions.h" #include "GPU_draw.h" @@ -252,6 +253,7 @@ void WM_exit(bContext *C) // XXX UI_filelist_free_icons(); } + GPU_buffer_pool_free(0); GPU_extensions_exit(); // if (copybuf) MEM_freeN(copybuf); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index dc2aca7b15b..081125bf7f6 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -434,7 +434,7 @@ static int wm_get_colordepth(void) /* apple seems to round colors to below and up on some configs */ -static unsigned int index_to_framebuffer(int index) +unsigned int index_to_framebuffer(int index) { unsigned int i= index; @@ -464,7 +464,7 @@ static unsigned int index_to_framebuffer(int index) /* this is the old method as being in use for ages.... seems to work? colors are rounded to lower values */ -static unsigned int index_to_framebuffer(int index) +unsigned int index_to_framebuffer(int index) { unsigned int i= index; diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h index c0c492018ff..78d73b596b2 100644 --- a/source/blender/windowmanager/wm_subwindow.h +++ b/source/blender/windowmanager/wm_subwindow.h @@ -45,6 +45,7 @@ void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y); void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y); void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]); +unsigned int index_to_framebuffer(int index); #endif /* WM_SUBWINDOW_H */ -- cgit v1.2.3 From 853f8212cae7c1558ead8cafe19174eaca5ff042 Mon Sep 17 00:00:00 2001 From: Lukas Steiblys Date: Sat, 3 Oct 2009 16:21:35 +0000 Subject: sculpt mode crash fix when VBOs disabled --- source/blender/editors/sculpt_paint/sculpt.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e41231442ba..470a10b5e50 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -311,7 +311,8 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_ calc_area_normal(sd, ss, area_normal, active_verts); - buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; + while(node){ float *co= ss->mvert[node->Index].co; @@ -382,7 +383,7 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert) static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts) { ActiveData *node= active_verts->first; - float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; int i; for(i = 0; i < 2; ++i) { @@ -413,7 +414,7 @@ static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active static void do_pinch_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts) { ActiveData *node= active_verts->first; - float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; while(node) { float *co= ss->mvert[node->Index].co; @@ -441,7 +442,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss) ActiveData *node= ss->cache->grab_active_verts[ss->cache->symmetry].first; float add[3]; float grab_delta[3]; - float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; VecCopyf(grab_delta, ss->cache->grab_delta_symmetry); @@ -481,7 +482,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active calc_area_normal(sd, ss, area_normal, active_verts); - buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; while(node){ float *disp= &ss->layer_disps[node->Index]; float *co= ss->mvert[node->Index].co; @@ -517,7 +518,7 @@ static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *activ { ActiveData *node= active_verts->first; float add[3]; - float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; while(node) { float *co= ss->mvert[node->Index].co; @@ -619,7 +620,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase flip = bstr < 0; } - buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices ); + buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->vertices ):0; while(node){ float *co= ss->mvert[node->Index].co; @@ -982,7 +983,7 @@ static void update_damaged_vert(SculptSession *ss, ListBase *lb) { ActiveData *vert; - float *buffer = (float *)GPU_buffer_lock( ss->drawobject->normals ); + float *buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->normals ):0; for(vert= lb->first; vert; vert= vert->next) { vec3f norm= {0,0,0}; IndexNode *face= ss->fmap[vert->Index].first; @@ -1453,7 +1454,7 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) /* Restore the mesh before continuing with anchored stroke */ if((brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) { - buffer = (float *)GPU_buffer_lock( ss->drawobject->normals ); + buffer = buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->normals ):0; for(i = 0; i < ss->totvert; ++i) { VecCopyf(ss->mvert[i].co, ss->mesh_co_orig[i]); ss->mvert[i].no[0] = cache->orig_norms[i][0]; -- cgit v1.2.3 From 74e10930071e5ba1f9552adba8c155dbeb16da4c Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Sat, 3 Oct 2009 16:21:47 +0000 Subject: SVN maintenance. --- source/blender/gpu/gpu_buffers.h | 2 +- source/blender/gpu/intern/gpu_buffers.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/gpu_buffers.h b/source/blender/gpu/gpu_buffers.h index d71c8e49acd..20b502387da 100644 --- a/source/blender/gpu/gpu_buffers.h +++ b/source/blender/gpu/gpu_buffers.h @@ -1,5 +1,5 @@ /** - * $Id: gpu_buffers.h 20687 2009-06-07 11:26:46Z imbusy $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 5781c852657..f19edb61df1 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1,5 +1,5 @@ /** - * $Id: gpu_buffers.c 19820 2009-04-20 15:06:46Z imbusy $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * -- cgit v1.2.3 From 14c1dd941ccf0fea706b8a8c5166c1641a23be51 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Sat, 3 Oct 2009 18:25:54 +0000 Subject: Cocoa port : added standard menu in OSX menu bar --- intern/ghost/intern/GHOST_SystemCocoa.mm | 73 +++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 252ac9e6318..d0c382e1469 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -409,17 +409,30 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { * CocoaAppDelegate * ObjC object to capture applicationShouldTerminate, and send quit event **/ -@interface CocoaAppDelegate : NSObject +@interface CocoaAppDelegate : NSObject { + GHOST_SystemCocoa *systemCocoa; +} +-(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa; - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; @end @implementation CocoaAppDelegate : NSObject +-(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa +{ + systemCocoa = sysCocoa; +} + - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { //Note that Cmd+Q is already handled by keyhandler - //FIXME: Cocoa_SendQuit(); - //sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) ); - return NSTerminateCancel; + //FIXME: Need an event "QuitRequest" + int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes may not have been saved. Do you really want to quit ?", + @"No", @"Yes", nil); + + if (shouldQuit == NSAlertAlternateReturn) + systemCocoa->pushEvent( new GHOST_Event(systemCocoa->getMilliSeconds(), GHOST_kEventQuit, NULL) ); + + return NSTerminateCancel; } @end @@ -476,12 +489,57 @@ GHOST_TSuccess GHOST_SystemCocoa::init() [NSApplication sharedApplication]; if ([NSApp mainMenu] == nil) { - //FIXME: CreateApplicationMenus(); + NSMenu *mainMenubar = [[NSMenu alloc] init]; + NSMenuItem *menuItem; + + //Create the application menu + NSMenu *appMenu = [[NSMenu alloc] initWithTitle:@"Blender"]; + + [appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + + menuItem = [appMenu addItemWithTitle:@"Hide Blender" action:@selector(hide:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + + menuItem = [appMenu addItemWithTitle:@"Hide others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; + + [appMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + menuItem = [appMenu addItemWithTitle:@"Quit Blender" action:@selector(terminate:) keyEquivalent:@"q"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:appMenu]; + + [mainMenubar addItem:menuItem]; + [menuItem release]; + [appMenu release]; + + //Create the window menu + NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + + [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; + + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:windowMenu]; + + [mainMenubar addItem:menuItem]; + [menuItem release]; + + [NSApp setMainMenu:mainMenubar]; + [NSApp setWindowsMenu:windowMenu]; + [windowMenu release]; } [NSApp finishLaunching]; } if ([NSApp delegate] == nil) { - [NSApp setDelegate:[[CocoaAppDelegate alloc] init]]; + CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init]; + [appDelegate setSystemCocoa:this]; + [NSApp setDelegate:appDelegate]; } @@ -982,6 +1040,9 @@ int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) [[event charactersIgnoringModifiers] characterAtIndex:0]); ascii= convertRomanToLatin((char)[[event characters] characterAtIndex:0]); + if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask)) + break; //Cmd-Q is directly handled by Cocoa + if ([event type] == NSKeyDown) { pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) ); //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii); -- cgit v1.2.3 From 78d9891dfebe63433b47076583df812992b3db7c Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sat, 3 Oct 2009 21:48:15 +0000 Subject: mathutils: bugfix for matrix * vector - terrible typo was making the multiplication to run in an infinite loop. - Any matrix * vector multiplication would crash Blender. eg #### import Mathutils from Mathutils import * vec_ray = Vector(0.0, 0.0, 1.0) tilt_mat = RotationMatrix(0.0, 3, "y") vec_ray = tilt_mat * vec_ray #### --- source/blender/python/generic/matrix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index edb6fb7af63..5a49118b519 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -1315,7 +1315,7 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* } vecNew[3] = 1.0f; - for(x = 0; x < mat->colSize; z++) { + for(x = 0; x < mat->colSize; x++) { for(y = 0; y < mat->rowSize; y++) { dot += mat->matrix[y][x] * vecCopy[y]; } -- cgit v1.2.3 From f82847687e413bf7627e424ad9f1a79bfea887cb Mon Sep 17 00:00:00 2001 From: Lukas Steiblys Date: Sat, 3 Oct 2009 22:14:19 +0000 Subject: VBOs weren't fully turned off in edit mode. Fixed that --- source/blender/editors/space_view3d/drawobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 53e87d61ad3..0f2a57d881c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1571,7 +1571,7 @@ static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act) data.eve_act = eve_act; /* first come the unselected vertices, then the selected */ - buffer = GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 ); + buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 ); if( (varray = GPU_buffer_lock_stream( buffer )) && bglPointHack() == 0 ) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; @@ -1698,7 +1698,7 @@ static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, un cols[0] = baseCol; cols[1] = selCol; - buffer = GPU_buffer_alloc( elemsize*em->totedge*2, 0 ); + buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*em->totedge*2, 0 ); if( (varray = GPU_buffer_lock_stream( buffer )) ) { EditEdge *eed; int numedges = 0; @@ -1804,7 +1804,7 @@ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned data.efa_act = efa_act; - buffer = GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 ); + buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 ); if( dm->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { int prevdraw = 0; int numfaces = 0; @@ -2433,7 +2433,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object } else { /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */ - GPUBuffer *buffer = GPU_buffer_alloc( sizeof(float)*6*em->totface*3*2, 0 ); + GPUBuffer *buffer = GPU_buffer_legacy(em->derivedFinal)?0:GPU_buffer_alloc( sizeof(float)*6*em->totface*3*2, 0 ); float *varray; EditFace *efa; int i, curmat = 0, draw = 0; -- cgit v1.2.3 From 55541d8a8143b97ce0d452caf4ececa8903c31a0 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sun, 4 Oct 2009 16:56:00 +0000 Subject: Added some test_break during the build process. (Maybe later this should be done with some thread_cancel function instead of doing variable/callbacks tests) --- source/blender/render/intern/include/rayobject.h | 24 +++++ .../blender/render/intern/raytrace/rayobject.cpp | 7 ++ .../render/intern/raytrace/rayobject_qbvh.cpp | 12 ++- .../render/intern/raytrace/rayobject_rtbuild.cpp | 5 +- .../render/intern/raytrace/rayobject_rtbuild.h | 2 +- .../render/intern/raytrace/rayobject_svbvh.cpp | 20 +++- .../render/intern/raytrace/rayobject_vbvh.cpp | 9 +- source/blender/render/intern/raytrace/vbvh.h | 26 +++++- source/blender/render/intern/source/rayshade.c | 104 +++++++++++++-------- 9 files changed, 158 insertions(+), 51 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 337f9ca3fdd..9e35c0feac5 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -93,6 +93,21 @@ extern "C" { #define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3) + +/* + * This class is intended as a place holder for control, configuration of the rayobject like: + * - stop building (TODO maybe when porting build to threads this could be implemented with some thread_cancel function) + * - max number of threads and threads callback to use during build + * ... + */ +typedef int (*RE_rayobjectcontrol_test_break_callback)(void *data); +typedef struct RayObjectControl RayObjectControl; +struct RayObjectControl +{ + void *data; + RE_rayobjectcontrol_test_break_callback test_break; +}; + /* * This rayobject represents a generic object. With it's own callbacks for raytrace operations. * It's suitable to implement things like LOD. @@ -100,9 +115,13 @@ extern "C" { struct RayObject { struct RayObjectAPI *api; + + struct RayObjectControl control; }; + + typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *); typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); typedef void (*RE_rayobject_done_callback)(RayObject *); @@ -144,6 +163,11 @@ int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as float RE_rayobject_cost(RayObject *r); +/* + * Returns true if for some reason a heavy processing function should stop + * (eg.: user asked to stop during a tree a build) + */ +int RE_rayobjectcontrol_test_break(RayObjectControl *c); #define ISECT_EPSILON ((float)FLT_EPSILON) diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 34faa2951ce..95387cf1ee4 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -528,3 +528,10 @@ void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max) else assert(0); } +int RE_rayobjectcontrol_test_break(RayObjectControl *control) +{ + if(control->test_break) + return control->test_break( control->data ); + + return 0; +} diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index 59daf9dc962..b18ee0824cf 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -47,7 +47,7 @@ struct QBVHTree template<> void bvh_done(QBVHTree *obj) { - rtbuild_done(obj->builder); + rtbuild_done(obj->builder, &obj->rayobj.control); //TODO find a away to exactly calculate the needed memory MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); @@ -59,7 +59,15 @@ void bvh_done(QBVHTree *obj) //Build and optimize the tree //TODO do this in 1 pass (half memory usage during building) - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + VBVHNode *root = BuildBinaryVBVH(arena1, &obj->rayobj.control).transform(obj->builder); + + if(RE_rayobjectcontrol_test_break(&obj->rayobj.control)) + { + BLI_memarena_free(arena1); + BLI_memarena_free(arena2); + return; + } + pushup_simd(root); obj->root = Reorganize_SVBVH(arena2).transform(root); diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 430045b56b6..9523e725893 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -130,11 +130,14 @@ static void object_sort(Item *begin, Item *end, int axis) assert(false); } -void rtbuild_done(RTBuilder *b) +void rtbuild_done(RTBuilder *b, RayObjectControl* ctrl) { for(int i=0; i<3; i++) if(b->sorted_begin[i]) + { + if(RE_rayobjectcontrol_test_break(ctrl)) break; object_sort( b->sorted_begin[i], b->sorted_end[i], i ); + } } RayObject* rtbuild_get_primitive(RTBuilder *b, int index) diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h index 8f471f095e2..71665681586 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -85,7 +85,7 @@ typedef struct RTBuilder RTBuilder* rtbuild_create(int size); void rtbuild_free(RTBuilder *b); void rtbuild_add(RTBuilder *b, RayObject *o); -void rtbuild_done(RTBuilder *b); +void rtbuild_done(RTBuilder *b, RayObjectControl *c); void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); int rtbuild_size(RTBuilder *b); diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp index f806fcf93ef..229e82dfa68 100644 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -58,7 +58,7 @@ struct PackCost template<> void bvh_done(SVBVHTree *obj) { - rtbuild_done(obj->builder); + rtbuild_done(obj->builder, &obj->rayobj.control); //TODO find a away to exactly calculate the needed memory MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); @@ -71,7 +71,14 @@ void bvh_done(SVBVHTree *obj) //Build and optimize the tree if(0) { - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + VBVHNode *root = BuildBinaryVBVH(arena1,&obj->rayobj.control).transform(obj->builder); + if(RE_rayobjectcontrol_test_break(&obj->rayobj.control)) + { + BLI_memarena_free(arena1); + BLI_memarena_free(arena2); + return; + } + reorganize(root); remove_useless(root, &root); bvh_refit(root); @@ -86,7 +93,14 @@ void bvh_done(SVBVHTree *obj) { //Finds the optimal packing of this tree using a given cost model //TODO this uses quite a lot of memory, find ways to reduce memory usage during building - OVBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + OVBVHNode *root = BuildBinaryVBVH(arena1,&obj->rayobj.control).transform(obj->builder); + if(RE_rayobjectcontrol_test_break(&obj->rayobj.control)) + { + BLI_memarena_free(arena1); + BLI_memarena_free(arena2); + return; + } + VBVH_optimalPackSIMD(PackCost()).transform(root); obj->root = Reorganize_SVBVH(arena2).transform(root); } diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 5260abf67ae..11f04c04141 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -72,7 +72,7 @@ struct PackCost template<> void bvh_done(VBVHTree *obj) { - rtbuild_done(obj->builder); + rtbuild_done(obj->builder, &obj->rayobj.control); //TODO find a away to exactly calculate the needed memory MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); @@ -81,7 +81,12 @@ void bvh_done(VBVHTree *obj) //Build and optimize the tree if(1) { - VBVHNode *root = BuildBinaryVBVH(arena1).transform(obj->builder); + VBVHNode *root = BuildBinaryVBVH(arena1,&obj->rayobj.control).transform(obj->builder); + if(RE_rayobjectcontrol_test_break(&obj->rayobj.control)) + { + BLI_memarena_free(arena1); + return; + } reorganize(root); remove_useless(root, &root); diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h index db1df43f665..1ff51786e52 100644 --- a/source/blender/render/intern/raytrace/vbvh.h +++ b/source/blender/render/intern/raytrace/vbvh.h @@ -107,10 +107,18 @@ template struct BuildBinaryVBVH { MemArena *arena; + RayObjectControl *control; - BuildBinaryVBVH(MemArena *a) + void test_break() + { + if(RE_rayobjectcontrol_test_break(control)) + throw "Stop"; + } + + BuildBinaryVBVH(MemArena *a, RayObjectControl *c) { arena = a; + control = c; } Node *create_node() @@ -130,6 +138,18 @@ struct BuildBinaryVBVH } Node *transform(RTBuilder *builder) + { + try + { + return _transform(builder); + + } catch(...) + { + } + return NULL; + } + + Node *_transform(RTBuilder *builder) { int size = rtbuild_size(builder); @@ -143,6 +163,8 @@ struct BuildBinaryVBVH } else { + test_break(); + Node *node = create_node(); INIT_MINMAX(node->bb, node->bb+3); @@ -157,7 +179,7 @@ struct BuildBinaryVBVH RTBuilder tmp; rtbuild_get_child(builder, i, &tmp); - *child = transform(&tmp); + *child = _transform(&tmp); child = &((*child)->sibling); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 641085d8cd6..9ef8aa3aba2 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -72,8 +72,26 @@ /* only to be used here in this file, it's for speed */ extern struct Render R; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -RayObject * RE_rayobject_create(int type, int size) +static int test_break(void *data) { + Render *re = (Render*)data; + return re->test_break(re->tbh); +} + +static RE_rayobject_config_control(RayObject *r, Render *re) +{ + if(RE_rayobject_isRayAPI(r)) + { + r = RE_rayobject_align( r ); + r->control.data = re; + r->control.test_break = test_break; + } +} + +RayObject* RE_rayobject_create(Render *re, int type, int size) +{ + RayObject * res = NULL; + if(type == R_RAYSTRUCTURE_AUTO) { //TODO @@ -83,30 +101,21 @@ RayObject * RE_rayobject_create(int type, int size) // type = R_RAYSTRUCTURE_VBVH; } - if(type == R_RAYSTRUCTURE_OCTREE) - { - //TODO dynamic ocres - return RE_rayobject_octree_create(R.r.ocres, size); - } - if(type == R_RAYSTRUCTURE_BLIBVH) - { - return RE_rayobject_blibvh_create(size); - } - if(type == R_RAYSTRUCTURE_VBVH) - { - return RE_rayobject_vbvh_create(size); - } - if(type == R_RAYSTRUCTURE_SIMD_SVBVH) - { - return RE_rayobject_svbvh_create(size); - } - if(type == R_RAYSTRUCTURE_SIMD_QBVH) - { - return RE_rayobject_qbvh_create(size); - } - assert( NULL ); + if(type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres + res = RE_rayobject_octree_create(re->r.ocres, size); + else if(type == R_RAYSTRUCTURE_BLIBVH) + res = RE_rayobject_blibvh_create(size); + else if(type == R_RAYSTRUCTURE_VBVH) + res = RE_rayobject_vbvh_create(size); + else if(type == R_RAYSTRUCTURE_SIMD_SVBVH) + res = RE_rayobject_svbvh_create(size); + else if(type == R_RAYSTRUCTURE_SIMD_QBVH) + res = RE_rayobject_qbvh_create(size); + + if(res) + RE_rayobject_config_control( res, re ); - return NULL; + return res; } #ifdef RE_RAYCOUNTER @@ -217,7 +226,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) assert( faces > 0 ); //Create Ray cast accelaration structure - raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_structure, faces ); + raytree = obr->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces ); if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives"); else @@ -311,7 +320,7 @@ static void makeraytree_single(Render *re) } //Create raytree - raytree = re->raytree = RE_rayobject_create( re->r.raytrace_structure, faces+special ); + raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special ); if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { @@ -325,6 +334,9 @@ static void makeraytree_single(Render *re) for(obi=re->instancetable.first; obi; obi=obi->next) if(is_raytraceable(re, obi)) { + if(test_break(re)) + break; + if(has_special_rayobject(re, obi)) { RayObject *obj = makeraytree_object(re, obi); @@ -371,10 +383,13 @@ static void makeraytree_single(Render *re) } } - re->i.infostr= "Raytree.. building"; - re->stats_draw(re->sdh, &re->i); + if(!test_break(re)) + { + re->i.infostr= "Raytree.. building"; + re->stats_draw(re->sdh, &re->i); - RE_rayobject_done( raytree ); + RE_rayobject_done( raytree ); + } } void makeraytree(Render *re) @@ -391,20 +406,29 @@ void makeraytree(Render *re) re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS); BENCH(makeraytree_single(re), tree_build); - - //Calculate raytree max_size - //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights - RE_rayobject_merge_bb( re->raytree, min, max ); - for(i=0; i<3; i++) + if(test_break(re)) { - min[i] += 0.01f; - max[i] += 0.01f; - sub[i] = max[i]-min[i]; + freeraytree(re); + + re->i.infostr= "Raytree building canceled"; + re->stats_draw(re->sdh, &re->i); } - re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] ); + else + { + //Calculate raytree max_size + //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights + RE_rayobject_merge_bb( re->raytree, min, max ); + for(i=0; i<3; i++) + { + min[i] += 0.01f; + max[i] += 0.01f; + sub[i] = max[i]-min[i]; + } + re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] ); - re->i.infostr= "Raytree finished"; - re->stats_draw(re->sdh, &re->i); + re->i.infostr= "Raytree finished"; + re->stats_draw(re->sdh, &re->i); + } } void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) -- cgit v1.2.3 From 729a63bbb6ba89ac32b3cef3291f28e990032cde Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sun, 4 Oct 2009 19:53:06 +0000 Subject: * update default physics settings for jahka --- source/blender/editors/datafiles/B.blend.c | 5391 ++++++++++++++-------------- 1 file changed, 2727 insertions(+), 2664 deletions(-) diff --git a/source/blender/editors/datafiles/B.blend.c b/source/blender/editors/datafiles/B.blend.c index b469f0c24cb..b22ef5b3053 100644 --- a/source/blender/editors/datafiles/B.blend.c +++ b/source/blender/editors/datafiles/B.blend.c @@ -1,682 +1,703 @@ /* DataToC output of file */ -int datatoc_B_blend_size= 100360; +int datatoc_B_blend_size= 102392; char datatoc_B_blend[]= { - 66, 76, 69, 78, 68, 69, 82, 95, -118, 50, 53, 48, 82, 69, 78, 68, 32, 0, 0, 0,208,245, 18, 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, 32, 0, 0, 0, -200,245, 18, 0,192, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 51, 3, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 1, 72, 22, 11, 7, -160, 33, 10, 7, 0, 16, 0, 0,128, 32, 4, 0, 87, 77, 0, 0,140, 0, 0, 0,192, 75, 10, 7, 86, 1, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,254, 14, 7,160,147,103, 2,160,254, 14, 7, -160,254, 14, 7, 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, 2, 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,224,183,102, 2,216, 85, 5, 7, 68, 65, 84, 65,148, 0, 0, 0,160,254, 14, 7, 87, 1, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 99, 2, 1, 0, 0, 0, 0, 0, 0, 0, 72, 22, 11, 7, 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, 62, 0, 34, 0, -186, 4,254, 2, 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 1, 0, 0, 0, 0, 0,232, 44, 99, 2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,144, 76, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0,208,229, 25, 7,176,202, 25, 7,152, 43, 99, 2, -184,231, 9, 7,200, 45, 5, 7, 56, 90, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0,140, 0, 0, 0, 72, 22, 11, 7, -186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 83, 99,114,101,101,110, - 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,208, 79, 10, 7, -176,183, 3, 7,232,192, 3, 7, 96,201, 2, 7,120,255, 14, 7, 72,136, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0,160, 33, 10, 7, - 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 16,111, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,208, 79, 10, 7, -187, 0, 0, 0, 1, 0, 0, 0,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 20, 0, 0, 0,120, 63, 11, 7,187, 0, 0, 0, 1, 0, 0, 0, 8, 11, 11, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0,254, 2, - 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 8, 11, 11, 7,187, 0, 0, 0, 1, 0, 0, 0,200, 32, 4, 7,120, 63, 11, 7, - 0, 0, 0, 0,186, 4,254, 2, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,200, 32, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, -232,251, 3, 7, 8, 11, 11, 7, 0, 0, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,232,251, 3, 7, -187, 0, 0, 0, 1, 0, 0, 0, 48, 16, 4, 7,200, 32, 4, 7, 0, 0, 0, 0, 0, 0,227, 2, 1, 0, 0, 0, 68, 65, 84, 65, - 20, 0, 0, 0, 48, 16, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,216, 43, 4, 7,232,251, 3, 7, 0, 0, 0, 0,186, 4,227, 2, - 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,216, 43, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,160, 34, 4, 7, 48, 16, 4, 7, - 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,160, 34, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, - 88,147, 4, 7,216, 43, 4, 7, 0, 0, 0, 0,186, 4, 60, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 88,147, 4, 7, -187, 0, 0, 0, 1, 0, 0, 0,136,121, 4, 7,160, 34, 4, 7, 0, 0, 0, 0,216, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 20, 0, 0, 0,136,121, 4, 7,187, 0, 0, 0, 1, 0, 0, 0,104, 25, 4, 7, 88,147, 4, 7, 0, 0, 0, 0,216, 3,227, 2, - 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,104, 25, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, 64,160, 4, 7,136,121, 4, 7, - 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 64,160, 4, 7,187, 0, 0, 0, 1, 0, 0, 0, - 32, 26, 15, 7,104, 25, 4, 7, 0, 0, 0, 0,216, 3, 72, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 32, 26, 15, 7, -187, 0, 0, 0, 1, 0, 0, 0,176,183, 3, 7, 64,160, 4, 7, 0, 0, 0, 0,216, 3, 72, 2, 0, 0, 0, 0, 68, 65, 84, 65, - 20, 0, 0, 0,176,183, 3, 7,187, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 26, 15, 7, 0, 0, 0, 0,186, 4, 72, 2, - 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,232,192, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 24,226, 3, 7, 0, 0, 0, 0, - 8, 11, 11, 7,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 24,226, 3, 7,188, 0, 0, 0, - 1, 0, 0, 0, 88, 14, 4, 7,232,192, 3, 7,232,251, 3, 7,120, 63, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 24, 0, 0, 0, 88, 14, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, 0,180, 3, 7, 24,226, 3, 7, 48, 16, 4, 7, 8, 11, 11, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,180, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,104,163, 3, 7, - 88, 14, 4, 7,232,251, 3, 7, 48, 16, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,104,163, 3, 7, -188, 0, 0, 0, 1, 0, 0, 0,248,203, 3, 7, 0,180, 3, 7, 88,147, 4, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 24, 0, 0, 0,248,203, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 16,191, 3, 7,104,163, 3, 7,200, 32, 4, 7, - 88,147, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 16,191, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, -144, 23, 4, 7,248,203, 3, 7,232,251, 3, 7,136,121, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, -144, 23, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, 0,118, 4, 7, 16,191, 3, 7, 48, 16, 4, 7,136,121, 4, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0,118, 4, 7,188, 0, 0, 0, 1, 0, 0, 0,144,109, 4, 7,144, 23, 4, 7, -104, 25, 4, 7,208, 79, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,144,109, 4, 7,188, 0, 0, 0, - 1, 0, 0, 0, 40,178, 3, 7, 0,118, 4, 7,232,251, 3, 7,104, 25, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 24, 0, 0, 0, 40,178, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,200,170, 3, 7,144,109, 4, 7,136,121, 4, 7, 64,160, 4, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,200,170, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,176,242, 3, 7, - 40,178, 3, 7, 88,147, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,176,242, 3, 7, -188, 0, 0, 0, 1, 0, 0, 0, 56,248, 3, 7,200,170, 3, 7,104, 25, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 24, 0, 0, 0, 56,248, 3, 7,188, 0, 0, 0, 1, 0, 0, 0, 80, 38, 4, 7,176,242, 3, 7, 88,147, 4, 7, - 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 80, 38, 4, 7,188, 0, 0, 0, 1, 0, 0, 0, -232,133, 3, 7, 56,248, 3, 7,136,121, 4, 7, 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, -232,133, 3, 7,188, 0, 0, 0, 1, 0, 0, 0,160,210, 2, 7, 80, 38, 4, 7,176,183, 3, 7, 48, 16, 4, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,160,210, 2, 7,188, 0, 0, 0, 1, 0, 0, 0, 96,201, 2, 7,232,133, 3, 7, -176,183, 3, 7,200, 32, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 96,201, 2, 7,188, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0,160,210, 2, 7,176,183, 3, 7, 32, 26, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 96, 0, 0, 0,120,255, 14, 7,190, 0, 0, 0, 1, 0, 0, 0, 24, 23, 11, 7, 0, 0, 0, 0,232,251, 3, 7,120, 63, 11, 7, - 8, 11, 11, 7, 48, 16, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0,186, 4, 0, 0,228, 2, 0, 0,254, 2, 0, 0, 7, 7,187, 4, - 27, 0, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 56,150, 92, 2,152,180,102, 2,152,180,102, 2, 32,173, 11, 7,112,158, 24, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 40, 47, 5, 7, 8, 48, 5, 7, 68, 65, 84, 65,248, 0, 0, 0, 32,173, 11, 7,191, 0, 0, 0, - 1, 0, 0, 0,112,158, 24, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,157, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 96,151, 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,186, 4, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, - 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, - 10, 0,187, 4, 26, 0,187, 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,186, 4, 0, 0,228, 2, 0, 0,253, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -187, 4, 26, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,151, 92, 2,184,191, 25, 7, -184,191, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,216, 49, 5, 7, 96, 50, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, -248, 0, 0, 0,112,158, 24, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32,173, 11, 7, 0, 0, 0, 0, 0, 32,240, 68, - 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 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, 0, 63, 0, 0, 0, 64, - 10, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 4, 6, 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, 0, 0, 0, 0,254, 2, 0, 0,254, 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, 1, 0, 0, 0, - 0, 0, 0, 0,224,150, 92, 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, 68, 65, 84, 65, 96, 0, 0, 0, 24, 23, 11, 7,190, 0, 0, 0, 1, 0, 0, 0,200, 33, 11, 7, -120,255, 14, 7, 88,147, 4, 7, 32, 26, 15, 7,176,183, 3, 7,200, 32, 4, 7, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, - 0, 0, 0, 0, 71, 2, 0, 0, 4, 4,226, 0, 72, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,147, 92, 2,192,160, 9, 7, -120,148, 10, 7,128,237, 11, 7,184,238, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0,232, 50, 5, 7,200, 51, 5, 7, 68, 65, 84, 65, -248, 0, 0, 0,128,237, 11, 7,191, 0, 0, 0, 1, 0, 0, 0,184,238, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 67, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0, 98, 67, 0, 0, 0, 0, 0, 0,248, 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,225, 0, 0, 0, - 0, 0, 0, 0, 30, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,226, 0, 31, 0,226, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0, 31, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,152,149, 92, 2,160,145,246, 6,160,145,246, 6, 0, 0, 0, 0, 0, 0, 0, 0,152, 53, 5, 7,168, 54, 5, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,184,238, 11, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -128,237, 11, 7, 0, 0, 0, 0, 0, 0, 80, 67, 0, 0, 68,196, 0, 0, 0, 0, 0, 0, 0, 0,254,255, 80, 67,255,191, 5,196, - 0, 0, 0, 0,209, 0, 0, 0,226, 0, 0, 0, 18, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, - 17, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 18, 0, 0, 0, 40, 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, 4, 6, 0,226, 0, 41, 2,209, 0, - 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176, 63,100, 2, 1, 0, 0, 0, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, - 31, 0, 0, 0, 71, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0, 41, 2, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,148, 92, 2, 88, 22, 6, 7, 16,102, 5, 7,248, 24, 11, 7, - 72,159, 9, 7,144, 56, 5, 7, 40, 58, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,248, 24, 11, 7, -189, 0, 0, 0, 1, 0, 0, 0,112, 26, 11, 7, 0, 0, 0, 0,200,148, 92, 2, 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,208, 0, 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, - 68, 65, 84, 65, 56, 1, 0, 0,112, 26, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,232, 27, 11, 7,248, 24, 11, 7,232,164, 2, 7, - 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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,208, 0, 61, 0, 0, 0, 0, 0, 0, 0, 2, 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, 68, 65, 84, 65, 56, 1, 0, 0,232, 27, 11, 7,189, 0, 0, 0, 1, 0, 0, 0, - 96, 29, 11, 7,112, 26, 11, 7,192,166, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 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, + 66, 76, 69, 78, 68, 69, 82, 95,118, 50, 53, 48, 82, 69, 78, 68, 32, 0, 0, 0, 36,246, 24, 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, 32, 0, 0, 0, 20,246, 24, 0,195, 0, 0, 0, 1, 0, 0, 0, 32, 32, 32, 52, + 4, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 1, 56, 79,201, 2,216,194,213, 2, 0, 16, 0, 0,128, 32, 4, 0, 87, 77, 0, 0, +140, 0, 0, 0,120, 78,201, 2, 93, 1, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,240, 49,213, 2,240, 49,213, 2,240, 49,213, 2,240, 49,213, 2, 3, 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, 2, 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,120,123,207, 2, 16,203,131, 3, 68, 65, 84, 65, +156, 0, 0, 0,240, 49,213, 2, 94, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,255,213, 2, 1, 0, 0, 0, + 0, 0, 0, 0, 56, 79,201, 2, 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, 93, 0,110, 7,219, 3, 0, 0, 0, 0, 1, 0,238, 3, 0, 0, 1, 0, + 0, 0, 0, 0,208, 64,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,103,210, 2, 0, 0, 0, 0, + 0, 0, 0, 0,160, 65,210, 2,160, 65,210, 2,136, 68,207, 2, 0, 69,207, 2,120, 69,207, 2,120, 69,207, 2, 96, 80,201, 2, + 40,174,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 83, 78, 0, 0,140, 0, 0, 0, 56, 79,201, 2,189, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82, 83, 99,114,101,101,110, 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, 72,187,200, 2,240,190,200, 2, 56,191,200, 2, +176, 51,213, 2,168,120,207, 2,232,122,207, 2, 0, 0, 0, 0, 0, 0, 0, 0,216,194,213, 2, 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,144,166, 83, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 72,187,200, 2,190, 0, 0, 0, 1, 0, 0, 0, +144,187,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,144,187,200, 2, +190, 0, 0, 0, 1, 0, 0, 0,216,187,200, 2, 72,187,200, 2, 0, 0, 0, 0, 0, 0,219, 3, 0, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0,216,187,200, 2,190, 0, 0, 0, 1, 0, 0, 0, 32,188,200, 2,144,187,200, 2, 0, 0, 0, 0,110, 7,219, 3, + 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 32,188,200, 2,190, 0, 0, 0, 1, 0, 0, 0,104,188,200, 2,216,187,200, 2, + 0, 0, 0, 0,110, 7, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,104,188,200, 2,190, 0, 0, 0, 1, 0, 0, 0, +176,188,200, 2, 32,188,200, 2, 0, 0, 0, 0, 0, 0,188, 3, 1, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,176,188,200, 2, +190, 0, 0, 0, 1, 0, 0, 0,248,188,200, 2,104,188,200, 2, 0, 0, 0, 0,110, 7,188, 3, 1, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0,248,188,200, 2,190, 0, 0, 0, 1, 0, 0, 0, 64,189,200, 2,176,188,200, 2, 0, 0, 0, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 64,189,200, 2,190, 0, 0, 0, 1, 0, 0, 0,136,189,200, 2,248,188,200, 2, + 0, 0, 0, 0,110, 7, 80, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,136,189,200, 2,190, 0, 0, 0, 1, 0, 0, 0, +208,189,200, 2, 64,189,200, 2, 0, 0, 0, 0, 16, 6, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,208,189,200, 2, +190, 0, 0, 0, 1, 0, 0, 0, 24,190,200, 2,136,189,200, 2, 0, 0, 0, 0, 16, 6,188, 3, 1, 0, 0, 0, 68, 65, 84, 65, + 20, 0, 0, 0, 24,190,200, 2,190, 0, 0, 0, 1, 0, 0, 0, 96,190,200, 2,208,189,200, 2, 0, 0, 0, 0, 0, 0, 96, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 96,190,200, 2,190, 0, 0, 0, 1, 0, 0, 0,168,190,200, 2, 24,190,200, 2, + 0, 0, 0, 0, 16, 6, 96, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,168,190,200, 2,190, 0, 0, 0, 1, 0, 0, 0, +240,190,200, 2, 96,190,200, 2, 0, 0, 0, 0, 16, 6,244, 2, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,240,190,200, 2, +190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168,190,200, 2, 0, 0, 0, 0,110, 7,244, 2, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 56,191,200, 2,191, 0, 0, 0, 1, 0, 0, 0,128,191,200, 2, 0, 0, 0, 0,144,187,200, 2,216,187,200, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,128,191,200, 2,191, 0, 0, 0, 1, 0, 0, 0,200,191,200, 2, + 56,191,200, 2,144,187,200, 2,104,188,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,200,191,200, 2, +191, 0, 0, 0, 1, 0, 0, 0, 16,192,200, 2,128,191,200, 2,216,187,200, 2,176,188,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0, 16,192,200, 2,191, 0, 0, 0, 1, 0, 0, 0, 88,192,200, 2,200,191,200, 2,104,188,200, 2, +176,188,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 88,192,200, 2,191, 0, 0, 0, 1, 0, 0, 0, +160,192,200, 2, 16,192,200, 2, 72,187,200, 2,136,189,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, +160,192,200, 2,191, 0, 0, 0, 1, 0, 0, 0,232,192,200, 2, 88,192,200, 2, 32,188,200, 2,136,189,200, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,232,192,200, 2,191, 0, 0, 0, 1, 0, 0, 0, 48,193,200, 2,160,192,200, 2, +104,188,200, 2,208,189,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 48,193,200, 2,191, 0, 0, 0, + 1, 0, 0, 0,120,193,200, 2,232,192,200, 2,176,188,200, 2,208,189,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0,120,193,200, 2,191, 0, 0, 0, 1, 0, 0, 0,192,193,200, 2, 48,193,200, 2, 72,187,200, 2, 24,190,200, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,192,193,200, 2,191, 0, 0, 0, 1, 0, 0, 0, 8,194,200, 2, +120,193,200, 2,104,188,200, 2, 24,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 8,194,200, 2, +191, 0, 0, 0, 1, 0, 0, 0, 80,194,200, 2,192,193,200, 2,208,189,200, 2, 96,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 24, 0, 0, 0, 80,194,200, 2,191, 0, 0, 0, 1, 0, 0, 0,152,194,200, 2, 8,194,200, 2,136,189,200, 2, + 96,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,152,194,200, 2,191, 0, 0, 0, 1, 0, 0, 0, +224,194,200, 2, 80,194,200, 2, 24,190,200, 2, 96,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, +224,194,200, 2,191, 0, 0, 0, 1, 0, 0, 0,216, 50,213, 2,152,194,200, 2,136,189,200, 2,168,190,200, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,216, 50,213, 2,191, 0, 0, 0, 1, 0, 0, 0, 32, 51,213, 2,224,194,200, 2, +208,189,200, 2,168,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 32, 51,213, 2,191, 0, 0, 0, + 1, 0, 0, 0,104, 51,213, 2,216, 50,213, 2,176,188,200, 2,240,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0,104, 51,213, 2,191, 0, 0, 0, 1, 0, 0, 0,176, 51,213, 2, 32, 51,213, 2, 32,188,200, 2,240,190,200, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,176, 51,213, 2,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +104, 51,213, 2,168,190,200, 2,240,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0,168,120,207, 2, +193, 0, 0, 0, 1, 0, 0, 0, 56,121,207, 2, 0, 0, 0, 0,104,188,200, 2,144,187,200, 2,216,187,200, 2,176,188,200, 2, + 0, 0, 0, 0, 0, 0, 0, 0,110, 7, 0, 0,189, 3, 0, 0,219, 3, 0, 0, 7, 7,111, 7, 31, 0, 1, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 64,202,201, 2, 32, 42,210, 2, 32, 42,210, 2,192, 66,213, 2,232, 67,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41,210, 2,192, 41,210, 2, 68, 65, 84, 65,248, 0, 0, 0,192, 66,213, 2,194, 0, 0, 0, 1, 0, 0, 0,232, 67,213, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,158, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0,224,237, 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,110, 7, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, + 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,111, 7, 26, 0,111, 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, 0, 0, 0, 0,110, 7, 0, 0, +189, 3, 0, 0,214, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 7, 26, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88,177,201, 2, 96,181,131, 3, 96,181,131, 3, 0, 0, 0, 0, + 0, 0, 0, 0,240, 69,207, 2,104, 70,207, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,232, 67,213, 2, +194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,192, 66,213, 2, 0, 0, 0, 0, 0,192,107, 69, 0, 0,128,192, 0, 0, 0, 0, + 0, 0, 0, 0,255,191,107, 69, 0, 0, 0,192, 0, 0, 0, 0, 94, 7, 0, 0,111, 7, 0, 0, 18, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 93, 7, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 93, 7, 0, 0, 18, 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, 63, 0, 0, 0, 64, 10, 0, 0, 0, 1, 0, 7, 0, + 18, 0, 0, 4, 6, 0,111, 7, 5, 0, 94, 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,110, 7, 0, 0,215, 3, 0, 0,219, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,111, 7, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,176,201, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 70,207, 2,208, 71,207, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 96, 0, 0, 0, 56,121,207, 2,193, 0, 0, 0, 1, 0, 0, 0,200,121,207, 2,168,120,207, 2,136,189,200, 2, +168,190,200, 2,240,190,200, 2, 32,188,200, 2, 0, 0, 0, 0, 17, 6, 0, 0,110, 7, 0, 0, 0, 0, 0, 0,243, 2, 0, 0, + 4, 4, 94, 1,244, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,201,201, 2,216, 86,213, 2, 64, 93,213, 2, 16, 69,213, 2, + 56, 70,213, 2, 0, 0, 0, 0, 0, 0, 0, 0,224, 39,210, 2,160, 40,210, 2, 68, 65, 84, 65,248, 0, 0, 0, 16, 69,213, 2, +194, 0, 0, 0, 1, 0, 0, 0, 56, 70,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 67, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0,175, 67, 0, 0, 0, 0, 0, 0,248, 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, 30, 0, 0, 0, + 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, + 4, 0, 12, 4, 10, 0, 94, 1, 31, 0, 94, 1, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 6, 0, 0,110, 7, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 94, 1, 31, 0, 4, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,176,201, 2, +232, 29,139, 3,232, 29,139, 3, 0, 0, 0, 0, 0, 0, 0, 0, 72, 72,207, 2, 56, 73,207, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,248, 0, 0, 0, 56, 70,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 69,213, 2, 0, 0, 0, 0, + 0, 0,166, 67, 0, 0, 89,196, 0, 0, 0, 0, 0, 0, 0, 0,253,127,166, 67,253,191, 48,196, 0, 0, 0, 0, 77, 1, 0, 0, + 94, 1, 0, 0, 18, 0, 0, 0,212, 2, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 76, 1, 0, 0, 18, 0, 0, 0,212, 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, 4, 6, 0, 94, 1,213, 2, 77, 1,195, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,136, 36,210, 2, 1, 0, 0, 0, 0, 0, 0, 0, 17, 6, 0, 0,110, 7, 0, 0, 31, 0, 0, 0,243, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1,213, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,168,175,201, 2,240,161,133, 3,120,181,138, 3, 96, 71,213, 2, 8,165,138, 3,176, 73,207, 2, + 24, 75,207, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 96, 71,213, 2,192, 0, 0, 0, 1, 0, 0, 0, +200, 72,213, 2, 0, 0, 0, 0, 56, 70,201, 2, 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, 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, 68, 65, 84, 65, 56, 1, 0, 0, - 96, 29, 11, 7,189, 0, 0, 0, 1, 0, 0, 0,216, 30, 11, 7,232, 27, 11, 7,152,168, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, - 69, 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, +200, 72,213, 2,192, 0, 0, 0, 1, 0, 0, 0, 48, 74,213, 2, 96, 71,213, 2,248, 91,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, + 69, 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, 0, 83, 67, 69, 78, - 69, 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, 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,165,254, -208, 0,178, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 69, 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, 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, 10, 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, 68, 65, 84, 65, 56, 1, 0, 0,216, 30, 11, 7,189, 0, 0, 0, 1, 0, 0, 0, 80, 32, 11, 7, 96, 29, 11, 7, -112,170, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95, 97,110,116,105, 97,108,105, 97,115,105,110,103, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 48, 74,213, 2,192, 0, 0, 0, 1, 0, 0, 0,152, 75,213, 2,200, 72,213, 2, +184, 92,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 83, 67, 69, 78, 69, 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, 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, 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, 83,254,208, 0, 58, 0, 20, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 4, 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, 10, 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, 68, 65, 84, 65, 56, 1, 0, 0, 80, 32, 11, 7,189, 0, 0, 0, - 1, 0, 0, 0,104,153, 9, 7,216, 30, 11, 7, 72,172, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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, 68, 65, 84, 65, 56, 1, 0, 0,152, 75,213, 2,192, 0, 0, 0, + 1, 0, 0, 0, 0, 77,213, 2, 48, 74,213, 2,120, 93,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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,213,253,208, 0,102, 0, 0, 0, 0, 0, - 0, 0, 2, 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,165,254, 76, 1,178, 0, 0, 0, 0, 0, + 0, 0, 10, 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, 68, 65, 84, 65, - 56, 1, 0, 0,104,153, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,224,154, 9, 7, 80, 32, 11, 7, 32,174, 2, 7, 0, 0, 0, 0, - 83, 67, 69, 78, 69, 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, + 56, 1, 0, 0, 0, 77,213, 2,192, 0, 0, 0, 1, 0, 0, 0,104, 78,213, 2,152, 75,213, 2, 56, 94,137, 3, 0, 0, 0, 0, + 83, 67, 69, 78, 69, 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, 0, - 83, 67, 69, 78, 69, 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, + 83, 67, 69, 78, 69, 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, 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, + 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, 84,253,208, 0,105, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 83,254, 76, 1, 58, 0, 20, 0, 0, 0, 0, 0, 10, 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, 68, 65, 84, 65, 56, 1, 0, 0,224,154, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 88,156, 9, 7, -104,153, 9, 7,208,177, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,112,101,114,102,111,114,109, 97,110, 99,101, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,104, 78,213, 2,192, 0, 0, 0, 1, 0, 0, 0,208, 79,213, 2, + 0, 77,213, 2,248, 94,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 83, 67, 69, 78, 69, 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, 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, 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, 60,253,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 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,213,253, 76, 1,102, 0, 0, 0, 0, 0, 0, 0, 10, 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, 68, 65, 84, 65, 56, 1, 0, 0, 88,156, 9, 7, -189, 0, 0, 0, 1, 0, 0, 0,208,157, 9, 7,224,154, 9, 7,168,179, 2, 7, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 68, 65, 84, 65, 56, 1, 0, 0,208, 79,213, 2, +192, 0, 0, 0, 1, 0, 0, 0, 56, 81,213, 2,104, 78,213, 2,184, 95,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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, 36,253,208, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 2, 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, + 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, 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, 84,253, 76, 1,105, 0, + 0, 0, 0, 0, 0, 0, 10, 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, - 68, 65, 84, 65, 56, 1, 0, 0,208,157, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 72,159, 9, 7, 88,156, 9, 7,128,181, 2, 7, - 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 95, 80, 84, 95,115,116, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 56, 1, 0, 0, 56, 81,213, 2,192, 0, 0, 0, 1, 0, 0, 0,160, 82,213, 2,208, 79,213, 2, 56, 97,137, 3, + 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 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, 83, 67, 69, 78, 69, 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, 0, 0, 0, 12,253,208, 0, 0, 0, 20, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 9, 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, 60,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 10, 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, 68, 65, 84, 65, 56, 1, 0, 0, 72,159, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0,208,157, 9, 7, 88,183, 2, 7, 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, 68, 65, 84, 65, 56, 1, 0, 0,160, 82,213, 2,192, 0, 0, 0, 1, 0, 0, 0, + 8, 84,213, 2, 56, 81,213, 2,248, 97,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, 69, 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, 0, 83, 67, 69, 78, 69, 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, 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, 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, 36,253, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 10, 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,244,252,208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 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, 68, 65, 84, 65, 56, 1, 0, 0, + 8, 84,213, 2,192, 0, 0, 0, 1, 0, 0, 0,112, 85,213, 2,160, 82,213, 2,184, 98,137, 3, 0, 0, 0, 0, 83, 67, 69, 78, + 69, 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, 0, 83, 67, 69, 78, + 69, 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, 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, 12,253, + 76, 1, 0, 0, 20, 0, 0, 0, 4, 0, 10, 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, 68, 65, 84, 65,224, 0, 0, 0, -192,160, 9, 7,158, 0, 0, 0, 1, 0, 0, 0,120,148, 10, 7, 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, 68, 65, 84, 65, 56, 1, 0, 0,112, 85,213, 2,192, 0, 0, 0, 1, 0, 0, 0,112,166,138, 3, 8, 84,213, 2, +120, 99,137, 3, 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,244,252, 76, 1, 0, 0, 0, 0, 0, 0, 4, 0, 10, 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, 2, 0, 1, 0, 0, 0, 0, 0, 80,175, 11, 7, -255, 20, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,224,161, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, - 40,144, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, - 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, - 26, 0, 20, 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, 89, 6, 0, 0, -108, 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, 20, 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, 68, 65, 84, 65,248, 0, 0, 0, - 40,144, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,224,161, 9, 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, 68, 65, 84, 65, 56, 1, 0, 0,112,166,138, 3,192, 0, 0, 0, + 1, 0, 0, 0, 8,165,138, 3,112, 85,213, 2, 56,100,137, 3, 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,220,252, 76, 1, 0, 0, 0, 0, 0, 0, + 4, 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, 68, 65, 84, 65, + 56, 1, 0, 0, 8,165,138, 3,192, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,112,166,138, 3,184,101,137, 3, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 4, 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, - 96,145, 10, 7, 68, 65, 84, 65,216, 2, 0, 0, 96,145, 10, 7,152, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, - 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, - 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, - 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65, 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, 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, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,160,252, 76, 1, 36, 0, 20, 0, 0, 0, 0, 0, 3, 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, 68, 65, 84, 65,224, 0, 0, 0,216, 86,213, 2,161, 0, 0, 0, 1, 0, 0, 0, 64, 93,213, 2, + 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,240, 0, 0, 0,120,148, 10, 7,153, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0,192,160, 9, 7,224,161, 9, 7, 40,144, 10, 7, 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, - 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, - 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 0, 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, 68, 65, 84, 65, 96, 0, 0, 0,200, 33, 11, 7, -190, 0, 0, 0, 1, 0, 0, 0, 48,124, 9, 7, 24, 23, 11, 7,208, 79, 10, 7,104, 25, 4, 7, 64,160, 4, 7, 88,147, 4, 7, - 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 15, 15,216, 3, 72, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,123, 92, 2, 24,152, 10, 7, 0,123, 9, 7,168,149, 10, 7,224,150, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, -176, 58, 5, 7,144, 59, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,168,149, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,224,150, 10, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,128, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 56, 0, 0,118, 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,215, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,224,202, 68, 0, 0,200, 65, 0,224,202, 68, - 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,216, 3, 26, 0,216, 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, 0, 0, 0, 0,215, 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,216, 3, 26, 0, 5, 0, 1, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,124, 92, 2,248, 23, 6, 7,248, 23, 6, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 61, 5, 7,112, 62, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,224,150, 10, 7, -191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168,149, 10, 7, 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,215, 3, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, 18, 0, 0, 0, 45, 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,216, 3, 46, 0, 0, 0, 0, 0, 0, 0, 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, 3, 0, 0, 26, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,216, 3, 46, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,123, 92, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 64, 5, 7,120, 66, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65,180, 0, 0, 0, 24,152, 10, 7,168, 0, 0, 0, 1, 0, 0, 0, 0,123, 9, 7, 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, - 1, 0, 0, 0, 6, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 16,153, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,176,118, 9, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,203, 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, 87, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, - 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 88, 6, 26, 0, 88, 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, 0, 0, 0, 0, 87, 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, 88, 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, 68, 65, 84, 65,248, 0, 0, 0,176,118, 9, 7, -191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16,153, 10, 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, 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, 32,153,136, 3,255, 20, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, +248, 0, 0, 0,232, 87,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 16, 89,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, + 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 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, 89, 6, 0, 0,108, 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, 20, 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, 87, 6, 0, 0, 26, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 88, 6, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, 9, 7, - 68, 65, 84, 65,216, 2, 0, 0,232,119, 9, 7,152, 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, 87,213,108, 66, 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,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 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,184,175, 31, 65, 0, 0, 32, 65,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,224, 91,138, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195, -115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 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,184,175, 31, 65, 0, 0, 32, 65, 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, 16, 89,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +232, 87,213, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52,149,147, 58, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, + 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 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, 56, 90,213, 2, 68, 65, 84, 65,216, 2, 0, 0, 56, 90,213, 2, +155, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128, +226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, +184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, + 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, +184,175, 31, 65, 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, 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, 0,123, 9, 7,153, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 24,152, 10, 7, 16,153, 10, 7,176,118, 9, 7, 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, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, 1, 0, 0, 0, - 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, - 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, - 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 0, 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, 68, 65, 84, 65, 96, 0, 0, 0, 48,124, 9, 7,190, 0, 0, 0, - 1, 0, 0, 0, 72,136, 9, 7,200, 33, 11, 7,104, 25, 4, 7,232,251, 3, 7,136,121, 4, 7, 64,160, 4, 7, 0, 0, 0, 0, - 0, 0, 0, 0,215, 3, 0, 0, 73, 0, 0, 0,226, 2, 0, 0, 1, 1,216, 3,154, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -232,124, 92, 2, 24,135, 9, 7, 24,135, 9, 7,208,124, 9, 7,160,229, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 5, 7, - 48, 69, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,208,124, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 8,126, 9, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 64, 90, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,118, 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,215, 3, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,216, 3, 26, 0,216, 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, 0, 0, 0, 0,215, 3, 0, 0, 73, 0, 0, 0, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3, 26, 0, 7, 0, 1, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,132, 92, 2, 32, 77,104, 2, 32, 77,104, 2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 71, 5, 7,152, 72, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 8,126, 9, 7,191, 0, 0, 0, - 1, 0, 0, 0, 48,130, 9, 7,208,124, 9, 7, 0, 0, 0, 0, 0, 0, 15, 67, 0, 0,251,195, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 67, 0, 0,251,195, 0, 0, 0, 0,143, 0, 0, 0,160, 0, 0, 0, 18, 0, 0, 0, 7, 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, 18, 0, 0, 0, 7, 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, 4, - 6, 0,160, 0, 8, 2,143, 0,246, 1, 0, 0, 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,219, 0, 0, 0,226, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -160, 0, 8, 2, 8, 0, 5, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,129, 92, 2, 72,117,101, 2, -136, 52,102, 2, 64,127, 9, 7,184,128, 9, 7,128, 74, 5, 7, 24, 76, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 56, 1, 0, 0, 64,127, 9, 7,189, 0, 0, 0, 1, 0, 0, 0,184,128, 9, 7, 0, 0, 0, 0,224,129, 92, 2, 0, 0, 0, 0, - 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115,104,101,108,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, - 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115,104,101,108,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, - 84,111,111,108, 32, 83,104,101,108,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,196,255,143, 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, 68, 65, 84, 65, 56, 1, 0, 0,184,128, 9, 7,189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 64,127, 9, 7, 80,129, 4, 7, 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, 27,254,143, 0,145, 1, 0, 0, 0, 0, 0, 0, 7, 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, 68, 65, 84, 65,248, 0, 0, 0, 48,130, 9, 7, -191, 0, 0, 0, 1, 0, 0, 0,152,219, 10, 7, 8,126, 9, 7, 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, - 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0, 99, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,160, 0,120, 0, 9, 0, 6, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,130, 92, 2, -120, 73, 25, 7,120, 73, 25, 7, 32,218, 10, 7, 32,218, 10, 7, 0, 78, 5, 7,152, 79, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 65, 84, 65, 56, 1, 0, 0, 32,218, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,131, 92, 2, - 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,105,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, 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, 68, 65, 84, 65,248, 0, 0, 0,152,219, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, -160,229, 10, 7, 48,130, 9, 7, 0, 0, 0, 0, 0, 0, 75, 67, 0,128,118,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 67, - 0,128, 27,196, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, 18, 0, 0, 0,127, 2, 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, 18, 0, 0, 0,127, 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,220, 0, -128, 2,203, 0,110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,215, 3, 0, 0, -215, 3, 0, 0, 99, 0, 0, 0,226, 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, 1, 0, 0, 0, 0, 0, 0, 0, 48,126, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, -208,220, 10, 7, 40,228, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, -208,220, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 72,222, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, - 51, 68, 95, 80, 84, 95,111, 98,106,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, - 51, 68, 95, 80, 84, 95,111, 98,106,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 84,114, 97,110, -115,102,111,114,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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,255, -203, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 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, 68, 65, 84, 65, 56, 1, 0, 0, 72,222, 10, 7,189, 0, 0, 0, 1, 0, 0, 0,192,223, 10, 7,208,220, 10, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 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, 86, 73, 69, 87, 51, 68, 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, 71,114,101, 97,115,101, 32, 80,101,110, 99,105,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,240, 0, 0, 0, 64, 93,213, 2,156, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,216, 86,213, 2,232, 87,213, 2, + 16, 89,213, 2, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,240,211,213, 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,200,254,203, 0, 58, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, + 1, 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, 68, 65, 84, 65, 96, 0, 0, 0,200,121,207, 2,193, 0, 0, 0, 1, 0, 0, 0, 88,122,207, 2, 56,121,207, 2, + 72,187,200, 2, 24,190,200, 2, 96,190,200, 2,136,189,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 15, 15, 16, 6, 96, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,198,201, 2,176, 96,213, 2,240,102,213, 2, + 96, 94,213, 2,136, 95,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 64, 43,210, 2,128, 42,210, 2, 68, 65, 84, 65,248, 0, 0, 0, + 96, 94,213, 2,194, 0, 0, 0, 1, 0, 0, 0,136, 95,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,129, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,194, 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, 15, 6, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,224,202, 68, 0, 0,200, 65, 0,224,202, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 16, 6, 26, 0, 16, 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, 0, 0, 0, 0, 15, 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, 16, 6, 26, 0, 6, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56,167,201, 2,136,163,133, 3,136,163,133, 3, 0, 0, 0, 0, 0, 0, 0, 0,144, 75,207, 2,128, 76,207, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0,136, 95,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 96, 94,213, 2, + 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, 15, 6, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 15, 6, 0, 0, 18, 0, 0, 0, 69, 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, 16, 6, 70, 0, 0, 0, 0, 0, 0, 0, + 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, 6, 0, 0, 26, 0, 0, 0, + 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 6, 70, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,166,201, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +248, 76,207, 2,216, 78,207, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,180, 0, 0, 0,176, 96,213, 2,171, 0, 0, 0, + 1, 0, 0, 0,240,102,213, 2, 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, 1, 0, 0, 0, 6, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, +152, 97,213, 2,194, 0, 0, 0, 1, 0, 0, 0,192, 98,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, + 0, 0,208, 65, 0, 0, 0, 0, 0, 0,203, 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, 87, 6, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, + 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 88, 6, 26, 0, 88, 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, 0, 0, 0, 0, 87, 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, 88, 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, 68, 65, 84, 65,248, 0, 0, 0,192, 98,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,152, 97,213, 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, 87, 6, 0, 0, 26, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 6, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 99,213, 2, 68, 65, 84, 65,216, 2, 0, 0,232, 99,213, 2,155, 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, 87,213,108, 66, 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,128, 0, 0, 0,128,226,215,163,188, + 0, 0, 0,128, 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, 32,193, + 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, 32, 65, + 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 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,184,175, 31, 65, + 0, 0, 32, 65,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224, 91,138, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67, +129,255, 71, 66, 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, 32,193, + 0, 0,128, 63, 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,213,108, 66, 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,184,175, 31, 65, + 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 52,149,147, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 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, 68, 65, 84, 65, 56, 1, 0, 0,192,223, 10, 7,189, 0, 0, 0, - 1, 0, 0, 0, 56,225, 10, 7, 72,222, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100, -118,105,101,119, 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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100, -118,105,101,119, 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, 86,105,101,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,253,203, 0, 47, 1, 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, 68, 65, 84, 65, - 56, 1, 0, 0, 56,225, 10, 7,189, 0, 0, 0, 1, 0, 0, 0,176,226, 10, 7,192,223, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,100,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0, +240, 0, 0, 0,240,102,213, 2,156, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,176, 96,213, 2,152, 97,213, 2,192, 98,213, 2, + 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,240,211,213, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 1, 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, + 68, 65, 84, 65, 96, 0, 0, 0, 88,122,207, 2,193, 0, 0, 0, 1, 0, 0, 0,232,122,207, 2,200,121,207, 2, 24,190,200, 2, +104,188,200, 2,208,189,200, 2, 96,190,200, 2, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 97, 0, 0, 0,187, 3, 0, 0, + 1, 1, 16, 6, 91, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,152,198,201, 2,232,151,213, 2,232,151,213, 2, 16,104,213, 2, +184,147,213, 2, 0, 0, 0, 0, 0, 0, 0, 0,128, 45,210, 2,160, 43,210, 2, 68, 65, 84, 65,248, 0, 0, 0, 16,104,213, 2, +194, 0, 0, 0, 1, 0, 0, 0, 56,105,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 68, 0, 0, 0, 0, 0, 0,208, 65, + 0, 0, 0, 0, 0, 0,194, 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, 15, 6, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, + 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, + 4, 0, 12, 4, 10, 0, 16, 6, 26, 0, 16, 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, 0, 0, 0, 0, 15, 6, 0, 0, 97, 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 6, 26, 0, 8, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,170,201, 2, + 32,165,133, 3, 32,165,133, 3, 0, 0, 0, 0, 0, 0, 0, 0, 80, 79,207, 2,184, 80,207, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65,248, 0, 0, 0, 56,105,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 48,109,213, 2, 16,104,213, 2, 0, 0, 0, 0, + 0, 0, 15, 67, 0,192, 45,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 0,192, 45,196, 0, 0, 0, 0,143, 0, 0, 0, +160, 0, 0, 0, 18, 0, 0, 0,200, 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, 18, 0, 0, 0,200, 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, 4, 6, 0,160, 0,201, 2,143, 0,183, 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,159, 0, 0, 0,243, 0, 0, 0,187, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0,201, 2, 9, 0, 5, 0, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,232,168,201, 2, 80,168,133, 3,184,166,133, 3, 96,106,213, 2,200,107,213, 2, 48, 81,207, 2, +232, 78,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 96,106,213, 2,192, 0, 0, 0, 1, 0, 0, 0, +200,107,213, 2, 0, 0, 0, 0, 56, 64,201, 2, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115, +104,101,108,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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,116,111,111,108, 95,115, +104,101,108,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, 84,111,111,108, 32, 83,104,101,108,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,196,255,143, 0, 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, - 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,100,105,115,112,108, 97,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, - 68,105,115,112,108, 97,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, 68, 65, 84, 65, 56, 1, 0, 0, +200,107,213, 2,192, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 96,106,213, 2,112,160,135, 3, 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, 52,254, +143, 0,120, 1, 0, 0, 0, 0, 0, 0, 11, 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, 68, 65, 84, 65,248, 0, 0, 0, 48,109,213, 2,194, 0, 0, 0, 1, 0, 0, 0,192,111,213, 2, 56,105,213, 2, + 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, 0, 0, 0, 0, 0, 0, 0, 0,159, 0, 0, 0,123, 0, 0, 0, +242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 0,120, 0, 10, 0, 6, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,169,201, 2,232,169,133, 3,232,169,133, 3, 88,110,213, 2, 88,110,213, 2, + 96, 79,210, 2,200, 80,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0, 88,110,213, 2,192, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 64,201, 2, 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,105,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, 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, 68, 65, 84, 65, +248, 0, 0, 0,192,111,213, 2,194, 0, 0, 0, 1, 0, 0, 0,184,147,213, 2, 48,109,213, 2, 0, 0, 0, 0, 0, 0, 75, 67, + 0,128,118,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 67, 0,128, 27,196, 0, 0, 0, 0,203, 0, 0, 0,220, 0, 0, 0, + 18, 0, 0, 0,127, 2, 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, + 18, 0, 0, 0,127, 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,220, 0,128, 2,203, 0,110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 15, 6, 0, 0,123, 0, 0, 0,187, 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, 1, 0, 0, 0, + 0, 0, 0, 0, 88,168,201, 2, 0, 0, 0, 0, 0, 0, 0, 0,232,112,213, 2, 8,120,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 56, 1, 0, 0,232,112,213, 2,192, 0, 0, 0, 1, 0, 0, 0, 80,114,213, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,111, 98,106,101, 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, 66,252,203, 0, 39, 1, 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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95,111, 98,106,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 84,114, 97,110,115,102,111,114,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,176,226, 10, 7,189, 0, 0, 0, 1, 0, 0, 0, 40,228, 10, 7, - 56,225, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115, -104,100,105,115,112,108, 97,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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115, -104,100,105,115,112,108, 97,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, 77,101,115,104, 32, 68,105,115,112,108, 97,121, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26,255,203, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254,250,203, 0,104, 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, 68, 65, 84, 65, 56, 1, 0, 0, 40,228, 10, 7, -189, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,176,226, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97,103,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, 68, 65, 84, 65, 56, 1, 0, 0, 80,114,213, 2, +192, 0, 0, 0, 1, 0, 0, 0,208,115,213, 2,232,112,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 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, 86, 73, 69, 87, 51, 68, 95, 80, - 84, 95, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97,103,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, 66, 97, 99,107,103,114,111,117, -110,100, 32, 73,109, 97,103,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, 42,252,203, 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, - 68, 65, 84, 65,248, 0, 0, 0,160,229, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,152,219, 10, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 0, 0, 99, 0, 0, 0,226, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 3,128, 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,144,125, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 81, 5, 7, - 40, 84, 5, 7, 0, 0, 0, 0, 0,132, 9, 7, 68, 65, 84, 65,216, 2, 0, 0, 0,132, 9, 7,152, 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, 1, 64,215, 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, -238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0, -228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63, -236, 4, 53, 63,244, 4, 53, 63, 0, 0, 24, 53, 0, 0, 0, 0,137,103, 59,190,118,103, 59, 62,227, 70,119, 63, 0, 0, 0, 0, -238,217, 46, 63,221,217, 46,191,213,131,132, 62, 0, 0, 0, 0,186,213, 60, 65,168,213, 60,193,221, 28,143, 64, 0, 0,128, 63, -100,253, 69, 63,248,146,157,190,223,235, 46,191,247,217, 46,191,119,253, 69, 63,197,146,157, 62,220,235, 46, 63,244,217, 46, 63, - 65,228, 68, 50,109,234,207, 63,107,145,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65, -252,128, 37, 63,186,128, 37, 63, 0, 0,180, 53, 0, 0, 60, 52,154,225,222,189,131,225,222, 61,139, 11, 19, 63, 0, 0,144, 51, - 25,255,107,194, 1,255,107, 66,239,218,178,193,208,247,159,192,220, 91,105, 66,197, 91,105,194, 49,219,176, 65, 50, 8,160, 64, -238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0,255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0, -228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63, -100,253, 69, 63,248,146,157,190,223,235, 46,191,247,217, 46,191,119,253, 69, 63,197,146,157, 62,220,235, 46, 63,244,217, 46, 63, - 65,228, 68, 50,109,234,207, 63,107,145,132,190,217,131,132,190, 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65, -166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,166, 33, 26, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, -122,163, 59, 63,235,250, 15,191,221,141,110,190,230,113,155,190,152, 60,138, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83,146,243, 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, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, - 24,135, 9, 7,153, 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, - 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 12, 66, - 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,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, 16, 0, 0, 0, 7, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0,255,255, - 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, 68, 65, 84, 65, - 96, 0, 0, 0, 72,136, 9, 7,190, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48,124, 9, 7, 32, 26, 15, 7,136,121, 4, 7, - 48, 16, 4, 7,176,183, 3, 7, 0, 0, 0, 0,217, 3, 0, 0,186, 4, 0, 0, 73, 2, 0, 0,226, 2, 0, 0, 3, 3,226, 0, -154, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,121, 92, 2, 88,139, 9, 7, 24,238, 10, 7,232,136, 9, 7, 32,138, 9, 7, - 0, 0, 0, 0, 0, 0, 0, 0,120, 86, 5, 7, 88, 87, 5, 7, 68, 65, 84, 65,248, 0, 0, 0,232,136, 9, 7,191, 0, 0, 0, - 1, 0, 0, 0, 32,138, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, - 0, 0, 98, 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,225, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 66, 67, - 0, 0,200, 65, 0, 0, 66, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, - 10, 0,226, 0, 26, 0,226, 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, -217, 3, 0, 0,186, 4, 0, 0, 73, 2, 0, 0, 98, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -226, 0, 26, 0, 11, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,122, 92, 2, 96,150, 25, 7, - 96,150, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0, 40, 89, 5, 7,176, 89, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, -248, 0, 0, 0, 32,138, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,232,136, 9, 7, 0, 0, 0, 0, 0,128,131, 67, - 0, 0,228,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 67, 0, 0,220,194, 0, 0, 0, 0,209, 0, 0, 0,226, 0, 0, 0, - 18, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,208, 0, 0, 0, - 18, 0, 0, 0,127, 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, 0, 4, 6, 0,226, 0,128, 0,209, 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,217, 3, 0, 0,186, 4, 0, 0, 99, 2, 0, 0,226, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 0,128, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,192,121, 92, 2,200,170, 25, 7,200,170, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0,152, 91, 5, 7,168, 92, 5, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 1, 0, 0, 88,139, 9, 7,162, 0, 0, 0, 1, 0, 0, 0,112,231, 10, 7, - 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,176,125, 25, 7,176,125, 25, 7, -216,143, 12, 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, 1, 0, 0, 0, - 68, 65, 84, 65, 12, 0, 0, 0,216,143, 12, 7,214, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0,160,140, 9, 7, - 68, 65, 84, 65,156, 0, 0, 0,160,140, 9, 7,213, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,160, 33, 10, 7, - 19, 0, 0, 0, 1, 0, 1, 0,160, 33, 10, 7, 20, 0, 0, 0, 1, 0, 1, 0,160, 33, 10, 7, 21, 0, 1, 0, 1, 0, 1, 0, -160, 33, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0, 64, 39, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0,224,195, 9, 7, 0, 0, 0, 0, - 1, 0, 1, 0, 48, 21, 12, 7, 0, 0, 0, 0, 1, 0, 1, 0, 48,203, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,224, 45, 10, 7, - 0, 0, 0, 0, 1, 0, 1, 0,136,199, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,208,240, 10, 7, 0, 0, 0, 0, 1, 0, 1, 0, - 56,192, 9, 7, 0, 0, 0, 0, 1, 0, 1, 0,240,143, 9, 7, 68, 65, 84, 65,248, 0, 0, 0,128,141, 9, 7,191, 0, 0, 0, - 1, 0, 0, 0,184,142, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 55, - 0, 0, 67, 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,194, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,137, 67, - 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, - 10, 0,195, 0, 26, 0,195, 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, - 53, 4, 0, 0,247, 4, 0, 0, 69, 2, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -195, 0, 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, 68, 65, 84, 65, -248, 0, 0, 0,184,142, 9, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128,141, 9, 7, 0, 0, 0, 0, 0, 0,150, 67, - 0,192,116,196, 0, 0, 0, 0, 0, 0, 0, 0,205, 85,150, 67,223,204, 35,196, 26, 85,207,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, - 0, 0, 0, 0,155, 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, - 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 4, 6, 0,195, 0,156, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 4, 0, 0,247, 4, 0, 0, 95, 2, 0, 0,250, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 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,200,254,203, 0, 58, 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, 68, 65, 84, 65,224, 0, 0, 0,112,231, 10, 7,158, 0, 0, 0, 1, 0, 0, 0, 24,238, 10, 7, - 88,139, 9, 7,128,141, 9, 7,184,142, 9, 7, 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, + 68, 65, 84, 65, 56, 1, 0, 0,208,115,213, 2,192, 0, 0, 0, 1, 0, 0, 0, 56,117,213, 2, 80,114,213, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 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, 86,105,101,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,129,253,203, 0, 47, 1, 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, 2, 0, 0, 0, 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,144,232, 10, 7,191, 0, 0, 0, 1, 0, 0, 0,200,233, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, - 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, - 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, 26, 0, 20, 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, 89, 6, 0, 0,108, 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, 20, 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, 68, 65, 84, 65,248, 0, 0, 0,200,233, 10, 7,191, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -144,232, 10, 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, 68, 65, 84, 65, 56, 1, 0, 0, 56,117,213, 2,192, 0, 0, 0, 1, 0, 0, 0, +160,118,213, 2,208,115,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, + 95,100,105,115,112,108, 97,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, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, + 95,100,105,115,112,108, 97,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, 68,105,115,112,108, 97,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, 66,252,203, 0, 39, 1, 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, 68, 65, 84, 65, 56, 1, 0, 0, +160,118,213, 2,192, 0, 0, 0, 1, 0, 0, 0, 8,120,213, 2, 56,117,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, + 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115,104,100,105,115,112,108, 97,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, 86, 73, 69, 87, + 51, 68, 95, 80, 84, 95, 51,100,118,105,101,119, 95,109,101,115,104,100,105,115,112,108, 97,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, 77,101,115,104, + 32, 68,105,115,112,108, 97,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,254,250, +203, 0,104, 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, 68, 65, 84, 65, 56, 1, 0, 0, 8,120,213, 2,192, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,160,118,213, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 73, 69, 87, 51, 68, 95, 80, 84, 95, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97, +103,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, 98, 97, 99,107,103,114,111,117,110,100, 95,105,109, 97, +103,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, 66, 97, 99,107,103,114,111,117,110,100, 32, 73,109, 97,103,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, 42,252,203, 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, 68, 65, 84, 65,248, 0, 0, 0,184,147,213, 2,194, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0,192,111,213, 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, 15, 6, 0, 0,123, 0, 0, 0,187, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 6, 65, 3, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,167,201, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 81,210, 2,176, 89,210, 2, 0, 0, 0, 0,224,148,213, 2, 68, 65, 84, 65, +216, 2, 0, 0,224,148,213, 2,155, 0, 0, 0, 1, 0, 0, 0,255,255,139, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,144,107, 2, 64, 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,238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0, +255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0,228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63,236, 4, 53, 63,244, 4, 53, 63, 0, 0, 24, 53, 0, 0, 0, 0, +137,103, 59,190,118,103, 59, 62,227, 70,119, 63, 0, 0, 0, 0,238,217, 46, 63,221,217, 46,191,213,131,132, 62, 0, 0, 0, 0, +186,213, 60, 65,168,213, 60,193,221, 28,143, 64, 0, 0,128, 63, 99,253, 69, 63,212,242,190,190,223,235, 46,191,247,217, 46,191, +117,253, 69, 63,151,242,190, 62,220,235, 46, 63,244,217, 46, 63, 64,228, 68, 50,223,243,251, 63,107,145,132,190,217,131,132,190, + 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65,252,128, 37, 63,190,128, 37, 63, 0, 0,172, 53, 0, 0, 52, 52, + 40,237,183,189, 22,237,183, 61, 53,176,242, 62, 0, 0,160, 50, 25,255,107,194, 2,255,107, 66,239,218,178,193,209,247,159,192, +220, 91,105, 66,198, 91,105,194, 49,219,176, 65, 51, 8,160, 64,238, 4, 53, 63,186,103, 59,190,247,217, 46, 63, 0, 0, 0, 0, +255, 4, 53, 63,126,103, 59, 62,244,217, 46,191, 0, 0, 0, 0,228, 3, 52, 50,248, 70,119, 63,217,131,132, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,152, 60,138,193, 0, 0,128, 63, 99,253, 69, 63,212,242,190,190,223,235, 46,191,247,217, 46,191, +117,253, 69, 63,151,242,190, 62,220,235, 46, 63,244,217, 46, 63, 64,228, 68, 50,223,243,251, 63,107,145,132,190,217,131,132,190, + 0, 0, 0, 0, 0, 0, 0, 0, 18,177,136, 65,152, 60,138, 65,240,113,195, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,240,113,195, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,113,195, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,122,163, 59, 63,235,250, 15,191,221,141,110,190,230,113,155,190, +152, 60,138, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,109,154, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,213, 2,156, 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, 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, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 7, 0,240,211,213, 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, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,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, 16, 0, 0, 0, + 7, 0, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0,255,255, 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, 68, 65, 84, 65, 96, 0, 0, 0,232,122,207, 2,193, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 88,122,207, 2,168,190,200, 2,208,189,200, 2,176,188,200, 2,240,190,200, 2, 0, 0, 0, 0, 17, 6, 0, 0, +110, 7, 0, 0,245, 2, 0, 0,187, 3, 0, 0, 3, 3, 94, 1,199, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,164,201, 2, + 88,155,213, 2,184,193,213, 2, 8,153,213, 2, 48,154,213, 2, 0, 0, 0, 0, 0, 0, 0, 0,160, 46,210, 2,224, 45,210, 2, + 68, 65, 84, 65,248, 0, 0, 0, 8,153,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 48,154,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,180, 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, 0, 66, 67, 0, 0,200, 65, 0, 0, 66, 67, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 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, 0, 0, 0, 0, 17, 6, 0, 0,110, 7, 0, 0,245, 2, 0, 0, 14, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1, 26, 0, 12, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24,166,201, 2,128,171,133, 3,128,171,133, 3, 0, 0, 0, 0, 0, 0, 0, 0, 40, 90,210, 2, +160, 90,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,248, 0, 0, 0, 48,154,213, 2,194, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 8,153,213, 2, 0, 0, 0, 0, 0,128,131, 67, 0, 0,228,194, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,166, 67, + 0, 0, 27,195, 0, 0, 0, 0, 77, 1, 0, 0, 94, 1, 0, 0, 18, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 76, 1, 0, 0, 18, 0, 0, 0,172, 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, 0, 4, 6, 0, 94, 1, +173, 0, 77, 1,155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 6, 0, 0, +110, 7, 0, 0, 15, 3, 0, 0,187, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 1,173, 0, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112,165,201, 2, 96, 83,133, 3, 96, 83,133, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 91,210, 2, 8, 92,210, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 1, 0, 0, + 88,155,213, 2,165, 0, 0, 0, 1, 0, 0, 0,160,189,213, 2, 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, 24, 6,139, 3, 24, 6,139, 3,144,156,213, 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, 1, 0, 0, 0, 68, 65, 84, 65, 12, 0, 0, 0,144,156,213, 2,217, 0, 0, 0, + 1, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0,208,156,213, 2, 68, 65, 84, 65,156, 0, 0, 0,208,156,213, 2,216, 0, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,216,194,213, 2, 19, 0, 0, 0, 1, 0, 1, 0,216,194,213, 2, 20, 0, 0, 0, + 1, 0, 1, 0,216,194,213, 2, 21, 0, 1, 0, 1, 0, 1, 0,216,194,213, 2, 0, 0, 0, 0, 1, 0, 1, 0,128,205,213, 2, + 0, 0, 0, 0, 1, 0, 1, 0,168,215,213, 2, 0, 0, 0, 0, 1, 0, 1, 0, 80,184,210, 2, 0, 0, 0, 0, 1, 0, 1, 0, + 24,223,213, 2, 0, 0, 0, 0, 1, 0, 1, 0, 32,227,213, 2, 0, 0, 0, 0, 1, 0, 1, 0, 96,219,213, 2, 0, 0, 0, 0, + 1, 0, 1, 0,152,202,213, 2, 0, 0, 0, 0, 1, 0, 1, 0,240,211,213, 2, 0, 0, 0, 0, 1, 0, 1, 0,240,201,213, 2, + 68, 65, 84, 65,248, 0, 0, 0,184,157,213, 2,194, 0, 0, 0, 1, 0, 0, 0,224,158,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,240, 67, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 55, 0, 0, 67, 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, +194, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,137, 67, 0, 0,200, 65, 0,128,137, 67, 0, 0,200, 65, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0,195, 0, 26, 0,195, 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, 53, 4, 0, 0,247, 4, 0, 0, 69, 2, 0, 0, 94, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 0, 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, 68, 65, 84, 65,248, 0, 0, 0,224,158,213, 2,194, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,184,157,213, 2, 0, 0, 0, 0, 0, 0,150, 67, 0,192,116,196, 0, 0, 0, 0, 0, 0, 0, 0,205, 85,150, 67, +223,204, 35,196, 26, 85,207,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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0,155, 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, 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 4, 6, 0,195, 0, +156, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 4, 0, 0, +247, 4, 0, 0, 95, 2, 0, 0,250, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, - 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 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, 68, 65, 84, 65,224, 0, 0, 0, +160,189,213, 2,161, 0, 0, 0, 1, 0, 0, 0,184,193,213, 2, 88,155,213, 2,184,157,213, 2,224,158,213, 2, 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,235, 10, 7, 68, 65, 84, 65,216, 2, 0, 0, 0,235, 10, 7, -152, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128, -226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, -184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, - 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0, -184,175, 31, 65, 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, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 68, 65, 84, 65,248, 0, 0, 0, 8,160,213, 2,194, 0, 0, 0, 1, 0, 0, 0, + 48,161,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 68, 0, 0, 0, 0, 0, 0,208, 65, 0, 0, 0, 0, 0, 0,138, 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, 19, 1, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0,128,237, 68, 0, 0,200, 65, + 0,128,237, 68, 0, 0,200, 65, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 2, 0, 3, 3, 4, 0, 12, 4, 10, 0, 20, 1, + 26, 0, 20, 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, 89, 6, 0, 0, +108, 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, 20, 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, 68, 65, 84, 65,248, 0, 0, 0, + 48,161,213, 2,194, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8,160,213, 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, - 68, 65, 84, 65,240, 0, 0, 0, 24,238, 10, 7,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,112,231, 10, 7,144,232, 10, 7, -200,233, 10, 7, 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, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0, 56,192, 9, 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, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, - 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, - 0, 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, 83, 67, 0, 0, 92, 5, 0, 0,160, 33, 10, 7,150, 0, 0, 0, 1, 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, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,192, 9, 7, 64, 39, 10, 7, 0, 0, 0, 0, 0, 0, 0, 0, -120,188, 2, 7, 48,241, 2, 7,120,188, 2, 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, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,239, 10, 7,152,230,101, 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,172, 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,100, 0, 0, 0,100, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 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, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 25, 0,141, 0,128, 7, 56, 4, 8, 0, 8, 0, 0, 0, - 24, 0, 17, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 23, 0, 33, 0, 0, 0,128, 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, 0, 0, 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,231, 9, 7, 48,231, 9, 7, 0, 0, 0, 0, - 0, 0,200, 66, 0, 0,200, 66, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 89, 6, 0, 0,108, 7, 0, 0, 26, 0, 0, 0, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 55, 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, +176,190,213, 2, 68, 65, 84, 65,216, 2, 0, 0,176,190,213, 2,155, 0, 0, 0, 1, 0, 0, 0,103,212,136, 64, 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, + 80, 1,128,191, 0, 0,128,191, 0, 0, 0,128, 0, 0, 0,128,226,215,163,188, 0, 0, 0,128, 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, 32,193, 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, 32, 65, 0, 0,128, 63,103,212,136, 64, 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, + 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 0, 0, 32, 65,237,122,111, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, 14,106, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +209,252,249,195,115,253, 71,194, 0, 0, 0, 0, 0, 0, 0, 0, 98,127,249, 67,129,255, 71, 66, 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, 32,193, 0, 0,128, 63,103,212,136, 64, 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, + 80, 1,128,191, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,184,175, 31, 65, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100, 32,222, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,184,193,213, 2,156, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0,160,189,213, 2, 8,160,213, 2, 48,161,213, 2, 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, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 0,240,211,213, 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, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, + 0, 0, 0, 0, 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, 16, 0, 0, 0, 7, 0, 10, 0,159, 0, 0, 0, 1, 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, 83, 67, 0, 0,108, 5, 0, 0,216,194,213, 2, +153, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +240,211,213, 2,128,205,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 48, 74,208, 2,208, 74,208, 2, 48, 74,208, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +120,200,213, 2,232,140,138, 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,172, 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, 1, 0, 0, 0, 1, 0, 0, 0,250, 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, 0, 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, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 25, 0,141, 0,128, 7, + 56, 4, 8, 0, 8, 0, 0, 0, 24, 0, 17, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 23, 0, 33, 0, + 0, 0,128, 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, 0, 0, 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, 66,207, 2, + 48, 66,207, 2, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 98, 97, 99,107, 98,117,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 98, 97, - 99,107, 98,117,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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,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, 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, 31, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 6, 0, 0, 0, 16, 0, 0, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68,172, 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, 6, 0, 0, 0, 16, 0, 0, 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, 0, 0, 0, 0, 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, 24, 11, 7, 1, 0, 0, 0, 1, 0, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 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, 28, 65, 0, 0, 0, 0, 32, 0, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, -128, 0, 5, 0, 60, 0, 5, 0, 1, 0, 5, 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, 4, 0, 1, 0,180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 5, 0,128, 7, 56, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 28, 0, 0, 0,120,188, 2, 7, -128, 0, 0, 0, 1, 0, 0, 0,136,223, 2, 7, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,236, 1, 64, 1, -224,195, 9, 7, 68, 65, 84, 65, 28, 0, 0, 0,136,223, 2, 7,128, 0, 0, 0, 1, 0, 0, 0, 48,241, 2, 7,120,188, 2, 7, - 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,121, 2, 10, 2,136,199, 9, 7, 68, 65, 84, 65, 28, 0, 0, 0, 48,241, 2, 7, -128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,136,223, 2, 7, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 38, 2, 28, 2, - 56,192, 9, 7, 68, 65, 84, 65, 72, 1, 0, 0, 72,239, 10, 7,147, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,187,200, 2, 1, 0, 0, 0, 1, 0, 10, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 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, 28, 65, + 0, 0, 0, 0, 32, 0, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 0, 5, 0, 60, 0, 5, 0, 1, 0, 5, 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, 4, 0, 1, 0, +180, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0,128, 7, 56, 4, 0, 0,128, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195,245, 28,193, 1, 0, 0, 0, 68, 65, 84, 65, 28, 0, 0, 0, 48, 74,208, 2, +130, 0, 0, 0, 1, 0, 0, 0,128, 74,208, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 8, 3,160, 1, +168,215,213, 2, 68, 65, 84, 65, 28, 0, 0, 0,128, 74,208, 2,130, 0, 0, 0, 1, 0, 0, 0,208, 74,208, 2, 48, 74,208, 2, + 1, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0,231, 3,223, 2, 96,219,213, 2, 68, 65, 84, 65, 28, 0, 0, 0,208, 74,208, 2, +130, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 74,208, 2, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0,100, 3,251, 2, +240,211,213, 2, 68, 65, 84, 65, 72, 1, 0, 0,120,200,213, 2,149, 0, 0, 0, 1, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -687,18 +708,18 @@ char datatoc_B_blend[]= { 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, 1, 0, 0, 0, 0, 0, 0, 0, 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, 48,231, 9, 7,133, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 32, 82,101, + 68, 65, 84, 65, 72, 0, 0, 0, 48, 66,207, 2,135, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 32, 82,101, 110,100,101,114, 76, 97,121,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,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, -120, 0, 0, 0,240,143, 9, 7, 29, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +120, 0, 0, 0,240,201,213, 2, 29, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 63,145,137, 68, 66,205,204,204, 61, 0, 0,200, 66, 0, 0, 12, 66, 161, 14,234, 64, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0,124, 1, 0, 0,208,240, 10, 7, 41, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0,124, 1, 0, 0,152,202,213, 2, 41, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 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, 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,144,242, 10, 7, + 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, 72,204,213, 2, 2, 0, 0, 0, 46, 26,128, 63, 25, 4,240, 65, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64, 64, 11, 3, 0, 1, 0, 0, 0, 0, 0, 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, @@ -706,20 +727,20 @@ char datatoc_B_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, 42, 4, 7, 68, 65, 84, 65, 8, 1, 0, 0, -144,242, 10, 7, 64, 1, 0, 0, 1, 0, 0, 0, 1, 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, 32, 75,208, 2, 68, 65, 84, 65, 8, 1, 0, 0, + 72,204,213, 2, 71, 1, 0, 0, 1, 0, 0, 0, 1, 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,112,236, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128, 63,243, 4, 53,191,242, 4, 53, 63,242, 4, 53,191,243, 4, 53, 63,248, 51,213, 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,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,112,236, 2, 7, - 62, 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, 32, 0, 0, 0, 0, 42, 4, 7, 19, 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, 87, 79, 0, 0,104, 1, 0, 0, 64, 39, 10, 7, -127, 0, 0, 0, 1, 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,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,248, 51,213, 2, + 69, 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, 32, 0, 0, 0, 32, 75,208, 2, 19, 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, 87, 79, 0, 0,104, 1, 0, 0,128,205,213, 2, +129, 0, 0, 0, 1, 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, 1, 0, 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,128, 62, 0, 0,128, 62, 0, 0, 0, 0,205,204,204, 61,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,128, 63, @@ -730,23 +751,24 @@ char datatoc_B_blend[]= { 0, 0,128, 62, 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, 84, 88, 0, 0,120, 0, 0, 0,232, 40, 10, 7, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 0, 0,120, 0, 0, 0, 24,207,213, 2, 27, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 84,101,120,116, 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, 7, 0, 0, 0, - 1, 0, 0, 0, 96,142, 2, 7, 96,142, 2, 7, 96,142, 2, 7, 96,142, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,160, 41, 10, 7,255,255,255,255, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, - 24, 0, 0, 0, 96,142, 2, 7, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,248, 11, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0,104,248, 11, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, - 79, 66, 0, 0,100, 3, 0, 0, 56,192, 9, 7,118, 0, 0, 0, 1, 0, 0, 0,224,195, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 64, 52,213, 2, 64, 52,213, 2, 64, 52,213, 2, 64, 52,213, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,192,207,213, 2,255,255,255,255, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 24, 0, 0, 0, 64, 52,213, 2, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,180,207, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0, 80,180,207, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 79, 66, 0, 0,136, 3, 0, 0,240,211,213, 2,118, 0, 0, 0, 1, 0, 0, 0,168,215,213, 2, 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, 1, 0, 0, 4, 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,240,143, 9, 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,240,201,213, 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,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, 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, 0, 0, 0, 0, 0, 0, 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,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, @@ -758,122 +780,127 @@ char datatoc_B_blend[]= { 0, 0,128, 53, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 79, 66, 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, 2, 0, 1, 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, 1, 0, 2, 0, 1, 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, 0, 0, 0, 0, 0, 0, 1, 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, 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, 79, 66, 0, 0,100, 3, 0, 0, -224,195, 9, 7,118, 0, 0, 0, 1, 0, 0, 0,136,199, 9, 7, 56,192, 9, 7, 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, 1, 0, 0, 4, 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,184,149, 25, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 21, 12, 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,224,127, 10, 7, -168,144, 9, 7, 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, 0, 0, 0, 0, 0,128, 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,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, -222,149, 47, 63, 52, 70, 58, 63,179, 56, 49,188, 0, 0, 0,128, 86,126,162,190,227,251,159, 62, 56, 53,101, 63, 0, 0, 0,128, - 7,165, 39, 63,149, 84, 28,191, 50,247,227, 62, 0, 0, 0,128,110,101,239, 64,151, 62,208,192, 77,255,170, 64, 0, 0,128, 63, - 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 79, 66, 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, 4, 0, 1, 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, 0, 0,128, 63, 0, 64, 1, 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,120,137, 25, 7,152,143, 25, 7, 25, 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, 68, 65, 84, 65, 4, 0, 0, 0,224,127, 10, 7, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,168,144, 9, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 79, 66, 0, 0,100, 3, 0, 0,136,199, 9, 7,118, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,224,195, 9, 7, 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, 1, 0, 0, 4, - 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,208,240, 10, 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,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,229,123, 38, 63, 87, 43, 98, 61,229,229,238, 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, 35,233,134, 49,251,110, 17,179, 0, 0, 0, 0, 49,158,141, 50, 1, 0,128, 63, -126,214,237, 50, 0, 0, 0, 0,155,248, 28,178,199,139, 96,177,254,255,127, 63, 0, 0, 0, 0, 80,136,159,178,192, 4,158,178, -209,114,143,179, 0, 0,128, 63, 53,236,148,190,222,102, 69,191, 37,255, 16, 63, 0, 0, 0,128, 24,134,116, 63, 57,174, 76,190, -240,161, 95, 62, 0, 0, 0,128,235, 13, 98,189, 34,194, 26, 63,166,111, 75, 63, 0, 0, 0,128,208, 19, 13, 63,234, 65,102,190, - 10, 10,231,192, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 68, 0, 79, 66, 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, 4, 0, 1, 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, 79, 66, 0, 0, +136, 3, 0, 0,168,215,213, 2,118, 0, 0, 0, 1, 0, 0, 0, 96,219,213, 2,240,211,213, 2, 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, 1, 0, 0, 4, 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, 64, 1, 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, 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, 77, 65, 0, 0,184, 2, 0, 0, - 48,203, 9, 7, 44, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 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, 1, 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,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 10,215, 35, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -205,204, 76, 62,205,204, 76, 62, 0, 0, 8, 0, 1, 0, 50, 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, 0, 0, - 67, 0, 0, 3, 3, 0, 1, 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,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,128, 63, 0, 0,128, 63, 40,206, 9, 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,232,154,136, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80,184,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, +136,180,207, 2,192,180,207, 2, 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, 0, 0, 0, 0, 0,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, 56,144, 2, 7, 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,205,204, 76, 63,205,204, 76, 63,205,204, 76, 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, 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,222,149, 47, 63, 52, 70, 58, 63,179, 56, 49,188, 0, 0, 0,128, 86,126,162,190,227,251,159, 62, 56, 53,101, 63, + 0, 0, 0,128, 7,165, 39, 63,149, 84, 28,191, 50,247,227, 62, 0, 0, 0,128,110,101,239, 64,151, 62,208,192, 77,255,170, 64, + 0, 0,128, 63, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68, 0, 79, 66, 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, + 1, 0, 4, 0, 1, 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, 0, 0,128, 63, 0, 64, 1, 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, 48,179,210, 2,120,180,210, 2, 25, 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, 68, 65, 84, 65, 4, 0, 0, 0, +136,180,207, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,192,180,207, 2, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0,136, 3, 0, 0, 96,219,213, 2,118, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +168,215,213, 2, 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, 1, 0, 0, 4, 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,152,202,213, 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,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,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 35,233,134, 49,251,110, 17,179, 0, 0, 0, 0, + 49,158,141, 50, 1, 0,128, 63,126,214,237, 50, 0, 0, 0, 0,155,248, 28,178,199,139, 96,177,254,255,127, 63, 0, 0, 0, 0, + 80,136,159,178,192, 4,158,178,209,114,143,179, 0, 0,128, 63, 53,236,148,190,222,102, 69,191, 37,255, 16, 63, 0, 0, 0,128, + 24,134,116, 63, 57,174, 76,190,240,161, 95, 62, 0, 0, 0,128,235, 13, 98,189, 34,194, 26, 63,166,111, 75, 63, 0, 0, 0,128, +208, 19, 13, 63,234, 65,102,190, 10, 10,231,192, 0, 0,128, 63, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 0, 1, 0, + 0, 0, 68, 0, 79, 66, 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, 1, 0, 4, 0, 1, 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, 0, 0, 0, 0, 0, 64, 1, 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, 68, 65, 84, 65,144, 0, 0, 0, 40,206, 9, 7, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0,224, 45, 10, 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, 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,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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63, 0, 0,128, 63, -205,204, 76, 62, 0, 0, 0, 0, 68, 65, 84, 65, 32, 0, 0, 0, 56,144, 2, 7, 19, 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, 84, 69, 0, 0, - 40, 1, 0, 0,224, 45, 10, 7, 39, 0, 0, 0, 1, 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, 1, 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, 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, 5, 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, 1, 0, 0, 0, 2, 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, 77, 69, 0, 0, 24, 1, 0, 0, - 48, 21, 12, 7, 54, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 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,131, 2, 7, 80, 27, 12, 7, 0, 0, 0, 0, - 0, 0, 0, 0,248,206, 9, 7, 72, 47, 10, 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,136, 22, 12, 7, 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 24, 12, 7, - 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 25, 12, 7, 1, 0, 0, 0, 5, 0, 0, 0, - 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 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, 0, 0, 0, 0, 67, 0, 0, 0, 30, 0, 4, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 80,131, 2, 7, 0, 0, 0, 0, 1, 0, 0, 0, 48,203, 9, 7, 68, 65, 84, 65, - 84, 1, 0, 0,136, 22, 12, 7, 67, 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, 1, 0, 0, 0, 0, 0, 0, 0, 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, 65, 0, 0,160, 2, 0, 0, 24,223,213, 2, 44, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 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, + 1, 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,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, 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, 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, 0, 0, 67, 0, 0, 3, 3, 0, 1, 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,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,128, 63, 0, 0,128, 63, +232,225,213, 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,112, 75,208, 2, 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,205,204, 76, 63, +205,204, 76, 63,205,204, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 8, 1, 0, 0, +232,225,213, 2, 32, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,227,213, 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, 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,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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, + 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 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,128, 63, + 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 68, 65, 84, 65, 32, 0, 0, 0,112, 75,208, 2, + 19, 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, 84, 69, 0, 0, 40, 1, 0, 0, 32,227,213, 2, 39, 0, 0, 0, 1, 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, 1, 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, 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, 5, 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, + 1, 0, 0, 0, 2, 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, 77, 69, 0, 0, 24, 1, 0, 0, 80,184,210, 2, 54, 0, 0, 0, 1, 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, + 1, 0, 0, 0, 0, 0, 0, 0, 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,180,207, 2,104, 32,131, 3, 0, 0, 0, 0, 0, 0, 0, 0,120,228,213, 2,128, 0,131, 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, 72,140,210, 2, 1, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,208,141,210, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 88,143,210, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 67, 0, 0, 0, 30, 0, 4, 0, + 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,248,180,207, 2, 0, 0, 0, 0, + 1, 0, 0, 0, 24,223,213, 2, 68, 65, 84, 65, 84, 1, 0, 0, 72,140,210, 2, 74, 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,248,206, 9, 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,120,228,213, 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, @@ -882,16 +909,16 @@ char datatoc_B_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, 68, 65, 84, 65,192, 0, 0, 0,248,206, 9, 7, 60, 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,255,127, 1, 0, 0, 0, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182, - 26,182,255,127, 1, 0, 0, 0, 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182,255,127, 1, 0, 0, 0, -250,255,127,191, 3, 0,128, 63, 0, 0,128,191, 26,182,230, 73, 26,182,255,127, 1, 0, 0, 0, 4, 0,128, 63,247,255,127, 63, - 0, 0,128, 63,230, 73,230, 73,230, 73,255,127, 1, 0, 0, 0,245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182, -230, 73,255,127, 1, 0, 0, 0, 3, 0,128,191,250,255,127,191, 0, 0,128, 63, 26,182, 26,182,230, 73,255,127, 1, 0, 0, 0, -255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73,230, 73,255,127, 1, 0, 0, 0, 68, 65, 84, 65, 84, 1, 0, 0, - 32, 24, 12, 7, 67, 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, 68, 65, 84, 65,192, 0, 0, 0,120,228,213, 2, 60, 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,255,127, 1, 0, 0, 0, 0, 0,128, 63, + 0, 0,128,191, 0, 0,128,191,230, 73, 26,182, 26,182,255,127, 1, 0, 0, 0, 1, 0,128,191,253,255,127,191, 0, 0,128,191, + 26,182, 26,182, 26,182,255,127, 1, 0, 0, 0,250,255,127,191, 3, 0,128, 63, 0, 0,128,191, 26,182,230, 73, 26,182,255,127, + 1, 0, 0, 0, 4, 0,128, 63,247,255,127, 63, 0, 0,128, 63,230, 73,230, 73,230, 73,255,127, 1, 0, 0, 0,245,255,127, 63, + 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,230, 73,255,127, 1, 0, 0, 0, 3, 0,128,191,250,255,127,191, 0, 0,128, 63, + 26,182, 26,182,230, 73,255,127, 1, 0, 0, 0,255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73,230, 73,255,127, + 1, 0, 0, 0, 68, 65, 84, 65, 84, 1, 0, 0,208,141,210, 2, 74, 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, 72, 47, 10, 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,128, 0,131, 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, @@ -900,14 +927,15 @@ char datatoc_B_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, - 68, 65, 84, 65,144, 0, 0, 0, 72, 47, 10, 7, 57, 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, 84, 1, 0, 0,184, 25, 12, 7, 67, 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, 68, 65, 84, 65,144, 0, 0, 0,128, 0,131, 3, 57, 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, 84, 1, 0, 0, 88,143,210, 2, 74, 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, 80, 27, 12, 7, 0, 0, 0, 0, + 0, 0, 0, 0,104, 32,131, 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, @@ -915,28 +943,29 @@ char datatoc_B_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, 68, 65, 84, 65,120, 0, 0, 0, +104, 32,131, 3, 56, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, + 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, + 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 2, 85, 83, 69, 82, 56, 11, 0, 0, 0, 94,252, 0,188, 0, 0, 0, 1, 0, 0, 0, 33,152, 1, 0, 63, 2, 0, 0, + 5, 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, 68, 65, 84, 65,120, 0, 0, 0, 80, 27, 12, 7, 56, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, - 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, - 5, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, - 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 2, 85, 83, 69, 82, 56, 11, 0, 0, - 0, 2, 68, 1,185, 0, 0, 0, 1, 0, 0, 0, 33,152, 1, 0, 63, 2, 0, 0, 5, 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, 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, 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, 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, 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, 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, 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, @@ -955,8 +984,8 @@ char datatoc_B_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, 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, 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, @@ -965,18 +994,17 @@ char datatoc_B_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, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 48, 52, 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 8, 0, 0, + 2, 0, 0, 0, 68,172, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0, +104,229,213, 2,120, 44,131, 3,120,175,210, 2,120,175,210, 2, 24, 76,131, 3, 24, 76,131, 3, 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, 0, 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, 0, 0, 25, 0, 15, 0,120, 0, 60, 0, 0, 0, 0, 0, +128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, 6, 0, 15, 0, 8, 0, 10, 0,250, 0, 0, 0,100, 0,100, 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, 2, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 48, 52, 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 8, 0, 0, 2, 0, 0, 0, 68,172, 0, 0, 36, 0, 0, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 64, 0, 5, 0, 2, 0,168, 3, 10, 7, 40,207, 13, 7, 48, 93, 5, 7, - 48, 93, 5, 7,128, 94, 5, 7,128, 94, 5, 7, 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, 0, 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, 0, 0, 25, 0, 15, 0,120, 0, 60, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,144, 31, 15, 0, - 6, 0, 15, 0, 8, 0, 10, 0,250, 0, 0, 0,100, 0,100, 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, @@ -985,817 +1013,830 @@ char datatoc_B_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, 2, 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,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, 68, 65, 84, 65,200, 21, 0, 0,104,229,213, 2,186, 0, 0, 0, + 1, 0, 0, 0,120, 44,131, 3, 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,255,255,255,255,255,255,255,255, + 0, 0, 0,255, 0, 0, 38, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 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, 68, 65, 84, 65,200, 21, 0, 0,168, 3, 10, 7,183, 0, 0, 0, 1, 0, 0, 0, 40,207, 13, 7, 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,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 38, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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,255,140, 25,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 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,255,255,255,128, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90,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, -165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,180,180,180,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,130,130,130,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,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, -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,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 82, 96,110,255, -124,137,150,255, 3, 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,255,255,255,128, - 0, 0, 0,255,255,133, 0,255, 3, 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,255,140, 25,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 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,255,255,255,128, - 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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 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,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255, -124,137,150,255, 3, 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,255,255,255,128, - 0, 0, 0,255,255,133, 0,255, 3, 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,255,140, 25,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,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, - 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,255,140, 25,255, 16, 64, 16,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,255,255,255, 10,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 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,255,255,255,128, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,110,110,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,132,132,132,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, - 94, 94, 94,255,172,172,172,255, 17, 27, 60,100, 94, 94, 94,255, 0, 0, 0,255,241, 88, 0,255, 0, 0, 0, 40,195,195,195,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 4, 0, 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,255,255,255,128, - 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,255,140, 25,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 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,255,255,255,128, - 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,255,140, 25,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255, -127,127,127,255,142,138,145,255,120,145,120,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,255,255,255,128, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60, -255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 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,255,255,255,128, - 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,255,140, 25,255, - 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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, - 68, 65, 84, 65,200, 21, 0, 0, 40,207, 13, 7,183, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,168, 3, 10, 7, 82,111,117,110, -100,101,100, 0, 0,101,119, 32, 85,115,101,114, 32, 84,104,101,109,101, 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, 25, 0,231,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, 0, 0, 0, 0, - 0, 0, 0, 0, 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, -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, 46,124,217,204,255,255,255,255,255,255,255,255, 0, 0, 0,255, 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, - 0, 0, 0, 0, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,175,175,175, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, -127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,107,107,107,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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, 0, 0, 0, 51, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255, -217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, - 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, -127,112,112,100,255,130, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,107,107,107,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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,107,107,107,150, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,100,143,143,143,100, 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255, -255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255,255,255,255,255,255,255,255,255,255,130, 0,255, - 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 82, 96,110,255,124,137,150,255, - 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,255,255,255,255, -255,130, 0,255, 2, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, -127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,158,158,158,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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,150, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255, -255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, - 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255, -178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255, -135,177,125,255,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,143,143,143,255,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,204, -255,255,170,204, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 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,107,107,107,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,143,143,143,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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,150, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255, -255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, - 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,255,255,255,170,255, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, -127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, - 0, 0, 0, 0, 96,192, 64,255, 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, 81,105,135,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, 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,195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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,150, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255, -255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, - 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60,255,133, 0,255, - 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 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, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,130,130,130,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 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,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,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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 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,255,255,255,128, 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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128,255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, + 3, 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,255,255,255,128, 0, 0, 0,255, +255,133, 0,255, 3, 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,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 12, 10, 10,128, +255,140, 0,255, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 3, 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,255,255,255,128, 0, 0, 0,255,255,133, 0,255, 3, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 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,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, 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,255,140, 25,255, 16, 64, 16,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,255,255,255, 10,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110,110,110,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,132,132,132,255, + 0, 0, 0,255, 0, 0, 0,255,255,255,255,255, 94, 94, 94,255,172,172,172,255, 17, 27, 60,100, 94, 94, 94,255, 0, 0, 0,255, +241, 88, 0,255, 0, 0, 0, 40,195,195,195,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 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,255,255,255,128, 0, 0, 0, 0, + 0, 0, 0, 0, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 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,255,255,255,128, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 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,255,255,255,128, 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,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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, + 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 0,155,155,155,160,100,100,100,255,108,105,111,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,255,255,255,128, 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,195,195,195,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255, -127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,153,153,153,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,153,153,153,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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,150, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255,255, 0, 0,255, 88, 88, 88,255, 0, 0, 0,255, -255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, - 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, - 2, 0, 0, 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, 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,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, -127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,158,158,158,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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,150, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255, -255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, - 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100, -127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255, 0, 0, 0, 0, - 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0,150,150,150,255,129,131,144,255,127,127,127,255, -142,138,145,255,120,145,120,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,100,100,100,255, - 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, - 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, 0, 0, 0, 51, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255, -217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, - 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, + 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,255,140, 25,255, 16, 64, 16,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, 18,255,133, 0, 60,255,133, 0,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0,255,255,255,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, 68, 78, 65, 49, - 28,222, 0, 0, 32, 80, 6, 7, 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, 78, 65, 77, 69,212, 10, 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,119, 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, 51, 50, 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, 50, 52, 93, 0,117,115, 0,105, 99,111,110, 95,105, -100, 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, 50, 52, 48, 93, 0,102,105,108,101,110, 97,109,101, 91, 50, 52, 48, 93, 0,116,111,116, 0, -112, 97,100, 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,112, 97,100, 48, 0,112, 97,100, 49, 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,112, 97,100, 50, 0, 42,119,101,105,103,104,116,115, 0,118,103,114,111,117,112, 91, 51, 50, 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, 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,112, 97,115,115,101,112, 97,114,116, 97,108,112,104, - 97, 0, 97,110,103,108,101, 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,104,105,102,116,120, 0,115,104,105,102,116,121, 0, - 89, 70, 95,100,111,102,100,105,115,116, 0, 89, 70, 95, 97,112,101,114,116,117,114,101, 0, 89, 70, 95, 98,107,104,116,121,112, -101, 0, 89, 70, 95, 98,107,104, 98,105, 97,115, 0, 89, 70, 95, 98,107,104,114,111,116, 0, 42,100,111,102, 95,111, 98, 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,109,101,110,117,110,114, 0, 42,115, 99,101,110,101, 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,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, 42,114,101,110,100,101,114, 95,116,101,120,116, 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, 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, 51, 50, 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,112, 97,100, 91, 55, 93, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114, 0, 99,111,108,102, - 97, 99, 0,110,111,114,102, 97, 99, 0,118, 97,114,102, 97, 99, 0,100,105,115,112,102, 97, 99, 0,119, 97,114,112,102, 97, 99, - 0,110, 97,109,101, 91, 49, 54, 48, 93, 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, 42,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,112,100,112, 97,100, 50, 91, 50, 93, 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, 42, 99,111, 98, 97, 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,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, 50, 52, 48, 93, 0, 42,100, 97,116, 97,115,101,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, -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,101,120,116,101,110,100, 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,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,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, 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, 0, 89, 70, 95,110,117,109,112,104, -111,116,111,110,115, 0, 89, 70, 95,110,117,109,115,101, 97,114, 99,104, 0, 89, 70, 95,112,104,100,101,112,116,104, 0, 89, 70, - 95,117,115,101,113,109, 99, 0, 89, 70, 95, 98,117,102,115,105,122,101, 0, 89, 70, 95,112, 97,100, 0, 89, 70, 95, 99, 97,117, -115,116,105, 99, 98,108,117,114, 0, 89, 70, 95,108,116,114, 97,100,105,117,115, 0, 89, 70, 95,103,108,111,119,105,110,116, 0, - 89, 70, 95,103,108,111,119,111,102,115, 0, 89, 70, 95,103,108,111,119,116,121,112,101, 0, 89, 70, 95,112, 97,100, 50, 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, 91, 51, 93, 0,100,101,110,115,105, -116,121, 0,101,109,105,115,115,105,111,110, 0, 97, 98,115,111,114,112,116,105,111,110, 0,115, 99, 97,116,116,101,114,105,110, -103, 0,101,109,105,115,115,105,111,110, 95, 99,111,108, 91, 51, 93, 0, 97, 98,115,111,114,112,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,112, -104, 97,115,101,102,117,110, 99, 95,116,121,112,101, 0,118,112, 97,100, 91, 51, 93, 0,112,104, 97,115,101,102,117,110, 99, 95, -103, 0,115,116,101,112,115,105,122,101, 0,115,104, 97,100,101, 95,115,116,101,112,115,105,122,101, 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,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,116,101,112,115, 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,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, 51, 50, 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, 89, 70, 95, 97,114, 0, 89, 70, 95, 97,103, 0, 89, 70, 95, 97, 98, 0, - 89, 70, 95,100,115, 99, 97,108,101, 0, 89, 70, 95,100,112,119,114, 0, 89, 70, 95,100,115,109,112, 0, 89, 70, 95,112,114,101, -115,101,116, 0, 89, 70, 95,100,106,105,116, 0,103,112,117,109, 97,116,101,114,105, 97,108, 0,110, 97,109,101, 91, 50, 53, 54, - 93, 0, 42, 98, 98, 0,105, 49, 0,106, 49, 0,107, 49, 0,105, 50, 0,106, 50, 0,107, 50, 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,104, 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,112, 97,100, 91, 50, 93, 0, -116,119,105,115,116, 95,115,109,111,111,116,104, 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, 98,112, 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,101,102,102,101, 99,116, 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,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,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, 97, 99,116, 95,102, 97, 99,101, - 0, 99,117, 98,101,109, 97,112,115,105,122,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, 42,109,114, 0, 42,112,118, 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,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,105,110,100,101,120, 0,102, 0,105, 0,115, 91, - 50, 53, 54, 93, 0,116,111,116,100,105,115,112, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0,118, 91, 52, 93, 0,109,105,100, - 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, 42,118,101,114,116, 95,109, 97,112, 0, 42,101,100,103,101, 95,109, 97,112, 0, 42,111,108,100, 95,102, 97, 99,101,115, - 0, 42,111,108,100, 95,101,100,103,101,115, 0, 42,101,114,114,111,114, 0,109,111,100,105,102,105,101,114, 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,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, 51, 50, 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, 42,116,101,120,116,117,114,101, 0,115,116, -114,101,110,103,116,104, 0,100,105,114,101, 99,116,105,111,110, 0,109,105,100,108,101,118,101,108, 0,116,101,120,109, 97,112, -112,105,110,103, 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, 51, 50, - 93, 0,117,118,108, 97,121,101,114, 95,116,109,112, 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,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, 51, 50, 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, 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,110,101,101,100, 98,105,110,100, 0, 42, 98,105,110,100,119,101,105,103,104,116,115, - 0, 42, 98,105,110,100, 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,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,115,121,115, 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, 42,117,110,100,111, 95,118,101,114,116,115, 0,117,110,100,111, 95,118,101,114,116,115, 95,116,111,116, - 0,117,110,100,111, 95,115,105,103,110, 97,108, 0,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, 51, 50, 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, -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, 51, 50, 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, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 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,114,111, -116, 91, 51, 93, 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, -108, 97,121, 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,105,112,111,119,105,110, 0,115, 99, 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, 0, 98,111,117, -110,100,116,121,112,101, 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,115,105,122,101,102, 97, 99, 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,100,116, 0,100,116,120, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0, -112, 97,100, 49, 91, 53, 93, 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,102,108,117,105,100,115,105,109, 70,108, 97,103, 0,114,101,115,116,114,105, 99, -116,102,108, 97,103, 0,115,104, 97,112,101,110,114, 0,115,104, 97,112,101,102,108, 97,103, 0,114,101, 99, 97,108, 99,111, 0, - 98,111,100,121, 95,116,121,112,101, 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,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, 99,117,114,105,110,100,101,120, 0, 97, 99,116,105,118,101, 0,100,101,102,108,101, 99,116, 0,102,111, -114, 99,101,102,105,101,108,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,102, - 95,115,116,114,101,110,103,116,104, 0,102, 95,112,111,119,101,114, 0,102, 95,100,105,115,116, 0,102, 95,100, 97,109,112, 0, -109, 97,120,100,105,115,116, 0,109,105,110,100,105,115,116, 0,109, 97,120,114, 97,100, 0,109,105,110,114, 97,100, 0,102, 95, -112,111,119,101,114, 95,114, 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,116,101,120, 95,109,111,100,101, 0,107,105,110,107, 0,107,105,110, -107, 95, 97,120,105,115, 0,114,116, 50, 0, 42,114,110,103, 0,102, 95,110,111,105,115,101, 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,105,110,100,101,120, 95, 97,114,114, 97,121, 0, 42, -100, 97,116, 97, 91, 56, 93, 0, 42, 99,117,114, 91, 56, 93, 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,110, 97,109,101, 91, 54, 52, 93, 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, 50, 52, 48, 93, 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, 51, 50, 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, 51, 50, 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, 51, - 50, 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,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,120, 0,103, -114, 97,118,121, 0,103,114, 97,118,122, 0, 97,110,105,109, 83,116, 97,114,116, 0, 97,110,105,109, 69,110,100, 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, 83,117,114,102, 97, 99,101, 0, 42,109,101,115,104, - 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 50, 52, 48, 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, 83,117,114,102, 78,111,114,109, 97,108,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,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, 0,104,111,114, 98, 0,104,111,114,107, 0, -122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,122,101,110,107, 0, 97,109, 98,107, 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,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, 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,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, 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, 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,102,102, 99,111,100,101, 99,100, 97,116, 97, 0, 97,117, -100,105,111, 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,114,116, 49, 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,119,105,110,112,111,115, 0,112,108, 97,110,101, -115, 0,105,109,116,121,112,101, 0,115,117, 98,105,109,116,121,112,101, 0,113,117, 97,108,105,116,121, 0,100,105,115,112,108, - 97,121,109,111,100,101, 0,114,112, 97,100, 49, 0,114,112, 97,100, 50, 0,115, 99,101,109,111,100,101, 0,114,101,110,100,101, -114,101,114, 0,111, 99,114,101,115, 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,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, 71, 73,113,117, 97,108,105,116,121, 0, 71, 73, 99, - 97, 99,104,101, 0, 71, 73,109,101,116,104,111,100, 0, 71, 73,112,104,111,116,111,110,115, 0, 71, 73,100,105,114,101, 99,116, - 0, 89, 70, 95, 65, 65, 0, 89, 70,101,120,112,111,114,116,120,109,108, 0, 89, 70, 95,110,111, 98,117,109,112, 0, 89, 70, 95, - 99,108, 97,109,112,114,103, 98, 0,121,102,112, 97,100, 49, 0, 71, 73,100,101,112,116,104, 0, 71, 73, 99, 97,117,115,100,101, -112,116,104, 0, 71, 73,112,105,120,101,108,115,112,101,114,115, 97,109,112,108,101, 0, 71, 73,112,104,111,116,111,110, 99,111, -117,110,116, 0, 71, 73,109,105,120,112,104,111,116,111,110,115, 0, 71, 73,112,104,111,116,111,110,114, 97,100,105,117,115, 0, - 89, 70, 95,114, 97,121,100,101,112,116,104, 0, 89, 70, 95, 65, 65,112, 97,115,115,101,115, 0, 89, 70, 95, 65, 65,115, 97,109, -112,108,101,115, 0,121,102,112, 97,100, 50, 0, 71, 73,115,104, 97,100,111,119,113,117, 97,108,105,116,121, 0, 71, 73,114,101, -102,105,110,101,109,101,110,116, 0, 71, 73,112,111,119,101,114, 0, 71, 73,105,110,100,105,114,112,111,119,101,114, 0, 89, 70, - 95,103, 97,109,109, 97, 0, 89, 70, 95,101,120,112,111,115,117,114,101, 0, 89, 70, 95,114, 97,121, 98,105, 97,115, 0, 89, 70, - 95, 65, 65,112,105,120,101,108,115,105,122,101, 0, 89, 70, 95, 65, 65,116,104,114,101,115,104,111,108,100, 0, 98, 97, 99,107, - 98,117,102, 91, 49, 54, 48, 93, 0,112,105, 99, 91, 49, 54, 48, 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, 49, 54, 48, 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,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,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,109, 97,116,109,111,100,101, 0,102,114, 97,109,105,110,103, 0,100,111, -109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0, 42, 42, 98,114,117,115,104,101,115, 0, 97, 99,116,105,118,101, 95, 98, -114,117,115,104, 95,105,110,100,101,120, 0, 98,114,117,115,104, 95, 99,111,117,110,116, 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,116, -111,111,108, 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, 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,110, 97,109,101, 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93, 91, 51, 93, 0,112, -105,118,111,116, 91, 51, 93, 0,116, 97, 98,108,101,116, 95,115,105,122,101, 0,116, 97, 98,108,101,116, 95,115,116,114,101,110, -103,116,104, 0,103, 97,109,109, 97, 0,109,117,108, 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, 42,118,112, 97,105,110,116, 0, 42,119,112, 97,105,110,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,112, 97,100, 91, 50, 93, 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,114,101, -116,111,112,111, 95,109,111,100,101, 0,114,101,116,111,112,111, 95,112, 97,105,110,116, 95,116,111,111,108, 0,108,105,110,101, - 95,100,105,118, 0,101,108,108,105,112,115,101, 95,100,105,118, 0,114,101,116,111,112,111, 95,104,111,116,115,112,111,116, 0, -109,117,108,116,105,114,101,115, 95,115,117, 98,100,105,118, 95,116,121,112,101, 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,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,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, 42, 99, 97,109, -101,114, 97, 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, 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,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0,115,111,117,110,100, 95,104, 97,110,100,108, -101,115, 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,106, -117,109,112,102,114, 97,109,101, 0,102,114, 97,109,101, 95,115,116,101,112, 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, 98,108,101,110,100, 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,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,118,105,101,119, - 98,117,116, 0,108, 97,115,116,109,111,100,101, 0,114,102,108, 97,103, 0,118,105,101,119,108,111, 99,107, 0,112,101,114,115, -112, 0,118,105,101,119, 0, 99,108,105,112, 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,116,111,112,111, 95,118,105,101,119, 95,100, 97,116, 97, 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,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,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,108, 97, -121, 95,117,115,101,100, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 0,111, 98, 95, 99,101,110,116, -114,101, 95, 98,111,110,101, 91, 51, 50, 93, 0,108, 97,121, 97, 99,116, 0,100,114, 97,119,116,121,112,101, 0,108,111, 99, 97, -108,118,105,101,119, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0,112,105,118,111,116, 95,108, 97,115, + 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, 68, 65, 84, 65,200, 21, 0, 0,120, 44,131, 3,186, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0,104,229,213, 2, 82,111,117,110,100,101,100, 0, 0,101,119, 32, 85,115,101,114, 32, 84,104,101,109,101, 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, 25, 0,231,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, 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 46,124,217,204,255,255,255,255,255,255,255,255, 0, 0, 0,255, + 0, 0, 25, 0,236,255, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 86,128,194,255,255,255,255,255,255,255,255,255, 0, 0, 0,255, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,175,175,175, 51, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, + 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255, +255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0, +255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100,255,130, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,107,107,107,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,100,143,143,143,100, + 96,192, 64,255, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255, +255,255,255,255,255,255,255,255,255,130, 0,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50,150, 30,200,100,200, 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, + 96,192, 64,255, 82, 96,110,255,124,137,150,255, 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,255,255,255,255,255,130, 0,255, 2, 0, 0, 0, 0, 0, 0, 0,114,114,114,255, 0, 0, 0, 0, + 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,158,158,158,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, + 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50,150, 30,200,100,200, 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, + 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, + 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100,255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 79,101, 73,255,135,177,125,255,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143,143,143,255,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,204,255,255,170,204, 96,192, 64,255, 82, 96,110,255,124,137,150,255, 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,107,107,107,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,143,143,143,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,107,107,107,255,178,178,178,100, +255,130, 0,100, 94, 94, 94,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,156,198,255,255,255,170,255, + 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, + 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,130, 0,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255, 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, 81,105,135,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, 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,195,195,195,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, + 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50,150, 30,200,100,200, 60,255,133, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 80,200,255,255, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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,255,255,255,128, 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,195,195,195,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,143,143,143,255,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,153,153,153,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,153,153,153,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,143,143,143,255,198,119,119,255, +255, 0, 0,255, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50,150, 30,200,100,200, 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, 2, 0, 0, 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, 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,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 88, 88, 88,255, 0, 0, 0,255,255,136,255,255, + 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255, +144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,150, 30,200,100,200, 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, 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,158,158,158,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,158,158,158,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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,150, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,140,140,140,255,127,112,112,100, + 0, 0, 0, 0,112,112, 96,255, 0, 0, 0,255,255,136,255,255, 0, 0, 0, 0,255,187,255,255, 0, 0, 0, 0, 0, 0, 0, 0, +255,255,255,255,255,112,255,255,255,255,112,255, 0, 0, 0,255,144,144, 48,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50,150, 30,200,100,200, 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, + 96,192, 64,255, 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,107,107,107,255, 0, 0, 0, 0, + 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 51, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, + 0, 0, 0, 40,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255, +255,255,255,255,230,150, 50,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255, +200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, +150,150,150,255,129,131,144,255,127,127,127,255,142,138,145,255,120,145,120,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,100,100,100,255, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,107,107,107,255, 0, 0, 0,255, + 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 51, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, + 0, 0, 0, 0,143,143,143,255, 0, 0, 0,255,217,217,217,255, 0, 0, 0, 40,255,255,255,255, 16, 64, 16,255,102,255,102,255, +255,130, 0,255, 0, 0, 0,255,255,130, 0,255, 0, 0, 0,255,255,255,255,255,230,150, 50,255,255, 32, 32,255, 0, 0, 0, 0, +255,255,255, 10,255,130, 0, 60,255,138, 48,255, 34,221,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 96,192, 64,255, 0, 0, 0, 0, 0, 0, 0, 0, 3, 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,255,255,255,128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,145,145,145,245, 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, 0, 0, 0, 0, 0, 0, 0,255, + 0, 0, 0,255,255,255,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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 68, 78, 65, 49,144,226, 0, 0,184,251,141, 3, 0, 0, 0, 0, 1, 0, 0, 0, 83, 68, 78, 65, + 78, 65, 77, 69, 17, 11, 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,119, 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, 51, 50, 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, 50, + 52, 93, 0,117,115, 0,105, 99,111,110, 95,105,100, 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, 50, 52, 48, 93, 0,102,105,108,101,110, 97, +109,101, 91, 50, 52, 48, 93, 0,116,111,116, 0,112, 97,100, 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,112, 97,100, 48, 0,112, 97,100, 49, 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,112, 97,100, 50, 0, 42,119,101,105,103,104,116,115, 0,118,103, +114,111,117,112, 91, 51, 50, 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, 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,112, + 97,115,115,101,112, 97,114,116, 97,108,112,104, 97, 0, 97,110,103,108,101, 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,104, +105,102,116,120, 0,115,104,105,102,116,121, 0, 89, 70, 95,100,111,102,100,105,115,116, 0, 89, 70, 95, 97,112,101,114,116,117, +114,101, 0, 89, 70, 95, 98,107,104,116,121,112,101, 0, 89, 70, 95, 98,107,104, 98,105, 97,115, 0, 89, 70, 95, 98,107,104,114, +111,116, 0, 42,100,111,102, 95,111, 98, 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,109,101,110,117,110,114, 0, 42,115, 99,101,110,101, 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,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, 42,114,101,110,100,101,114, 95,116, +101,120,116, 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, 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, 51, 50, 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,112, 97,100, 91, 55, 93, 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,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,108,105,102,101,102, 97, 99, 0, +115,105,122,101,102, 97, 99, 0,105,118,101,108,102, 97, 99, 0,112,118,101,108,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,110, + 97,109,101, 91, 49, 54, 48, 93, 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, 42,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,112,100,112, 97,100, 50, 91, 50, 93, 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, 42, 99,111, 98, 97, 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,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, 50, 52, 48, 93, 0, 42,100, 97,116, 97, +115,101,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,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,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,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, 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, 0, 89, 70, 95,110,117,109,112,104,111,116, +111,110,115, 0, 89, 70, 95,110,117,109,115,101, 97,114, 99,104, 0, 89, 70, 95,112,104,100,101,112,116,104, 0, 89, 70, 95,117, +115,101,113,109, 99, 0, 89, 70, 95, 98,117,102,115,105,122,101, 0, 89, 70, 95,112, 97,100, 0, 89, 70, 95, 99, 97,117,115,116, +105, 99, 98,108,117,114, 0, 89, 70, 95,108,116,114, 97,100,105,117,115, 0, 89, 70, 95,103,108,111,119,105,110,116, 0, 89, 70, + 95,103,108,111,119,111,102,115, 0, 89, 70, 95,103,108,111,119,116,121,112,101, 0, 89, 70, 95,112, 97,100, 50, 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, 91, 51, 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,116,101,112,115, 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,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, 51, 50, 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,103,112,117,109, 97,116,101,114,105, 97,108, 0,110, 97,109,101, 91, 50, 53, 54, 93, 0, 42, 98, 98, + 0,105, 49, 0,106, 49, 0,107, 49, 0,105, 50, 0,106, 50, 0,107, 50, 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,104, 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,112, 97,100, 91, 50, 93, 0,116,119,105,115,116, + 95,115,109,111,111,116,104, 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, 98,112, 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,101,102,102,101, 99,116, 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,109,101,115,104, 0,118,100, 97,116, 97, 0,101,100, 97,116, 97, 0,102,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, 97, 99,116, 95,102, 97, 99,101, 0, 99,117, 98,101, +109, 97,112,115,105,122,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, 42,109,114, 0, 42,112,118, 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,117,118, 91, 50, 93, 0, 99,111, 91, 50, 93, 0,105,110,100,101,120, 0,102, 0,105, 0,115, 91, 50, 53, 54, 93, 0, +116,111,116,100,105,115,112, 0, 40, 42,100,105,115,112,115, 41, 40, 41, 0,118, 91, 52, 93, 0,109,105,100, 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, 42,118,101, +114,116, 95,109, 97,112, 0, 42,101,100,103,101, 95,109, 97,112, 0, 42,111,108,100, 95,102, 97, 99,101,115, 0, 42,111,108,100, + 95,101,100,103,101,115, 0, 42,101,114,114,111,114, 0,109,111,100,105,102,105,101,114, 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, +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, 51, 50, 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, 42,116,101,120,116,117,114,101, 0,115,116,114,101,110,103,116, +104, 0,100,105,114,101, 99,116,105,111,110, 0,109,105,100,108,101,118,101,108, 0,116,101,120,109, 97,112,112,105,110,103, 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, 51, 50, 93, 0,117,118,108, + 97,121,101,114, 95,116,109,112, 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,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, 51, 50, 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, 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,110,101,101,100, 98,105,110,100, 0, 42, 98,105,110,100,119,101,105,103,104,116,115, 0, 42, 98,105,110, +100, 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,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,115,121,115, 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, 42,117,110,100,111, 95,118,101,114,116,115, 0,117,110,100,111, 95,118,101,114,116,115, 95,116,111,116, 0,117,110,100,111, + 95,115,105,103,110, 97,108, 0,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, 51, 50, + 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,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, 51, 50, 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, 99,111,110, +115,116,114, 97,105,110,116, 67,104, 97,110,110,101,108,115, 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,114,111,116, 91, 51, 93, 0, +100,113,117, 97,116, 91, 52, 93, 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,108, 97,121, 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,105,112,111,119,105,110, 0,115, 99, 97,102,108, 97,103, 0,115, 99, 97,118,105,115,102,108, 97,103, + 0, 98,111,117,110,100,116,121,112,101, 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,114,111,116,109,111,100,101, 0,100,116, 0,100,116,120, 0,101,109,112,116,121, 95,100,114, 97,119,116, +121,112,101, 0,112, 97,100, 49, 91, 51, 93, 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,102,108,117,105,100,115,105,109, 70,108, 97,103, 0,114,101,115, +116,114,105, 99,116,102,108, 97,103, 0,115,104, 97,112,101,110,114, 0,115,104, 97,112,101,102,108, 97,103, 0,114,101, 99, 97, +108, 99,111, 0, 98,111,100,121, 95,116,121,112,101, 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,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, 99,117,114,105,110,100,101,120, 0, 97, 99, +116,105,118,101, 0,111,114,105,103,108, 97,121, 0,110,111, 95,100,114, 97,119, 0, 97,110,105,109, 97,116,101,100, 0,111,109, + 97,116, 91, 52, 93, 91, 52, 93, 0,111,114, 99,111, 91, 51, 93, 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, 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,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,105,110,100,101,120, 95, 97,114,114, 97,121, 0, 42,100, 97,116, 97, 91, 56, 93, 0, 42, 99,117,114, + 91, 56, 93, 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,110, 97,109,101, 91, + 54, 52, 93, 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, + 50, 52, 48, 93, 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, 51, 50, 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, 51, 50, 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, 51, 50, 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, 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,120, 0,103,114, 97,118,121, 0,103,114, 97,118,122, 0, 97,110,105,109, 83,116, 97,114,116, 0, + 97,110,105,109, 69,110,100, 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, 83,117, +114,102, 97, 99,101, 0, 42,109,101,115,104, 66, 66, 0,115,117,114,102,100, 97,116, 97, 80, 97,116,104, 91, 50, 52, 48, 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, + 83,117,114,102, 78,111,114,109, 97,108,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,109,105,115,116,121,112,101, 0,104,111,114,114, 0,104,111,114,103, + 0,104,111,114, 98, 0,104,111,114,107, 0,122,101,110,114, 0,122,101,110,103, 0,122,101,110, 98, 0,122,101,110,107, 0, 97, +109, 98,107, 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,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, 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,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, 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,102,102, 99,111,100,101, 99,100, 97,116, 97, 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,114, +116, 49, 0,114,116, 50, 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,119,105,110,112,111,115, 0,112,108, 97,110,101,115, 0,105,109,116,121,112,101, 0,115,117, 98,105,109,116, +121,112,101, 0,113,117, 97,108,105,116,121, 0,100,105,115,112,108, 97,121,109,111,100,101, 0,114,112, 97,100, 49, 0,114,112, + 97,100, 50, 0,115, 99,101,109,111,100,101, 0,114,101,110,100,101,114,101,114, 0,111, 99,114,101,115, 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,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, 71, 73,113,117, 97,108,105,116,121, 0, 71, 73, 99, 97, 99,104,101, 0, 71, 73,109,101,116,104,111,100, 0, 71, + 73,112,104,111,116,111,110,115, 0, 71, 73,100,105,114,101, 99,116, 0, 89, 70, 95, 65, 65, 0, 89, 70,101,120,112,111,114,116, +120,109,108, 0, 89, 70, 95,110,111, 98,117,109,112, 0, 89, 70, 95, 99,108, 97,109,112,114,103, 98, 0,121,102,112, 97,100, 49, + 0, 71, 73,100,101,112,116,104, 0, 71, 73, 99, 97,117,115,100,101,112,116,104, 0, 71, 73,112,105,120,101,108,115,112,101,114, +115, 97,109,112,108,101, 0, 71, 73,112,104,111,116,111,110, 99,111,117,110,116, 0, 71, 73,109,105,120,112,104,111,116,111,110, +115, 0, 71, 73,112,104,111,116,111,110,114, 97,100,105,117,115, 0, 89, 70, 95,114, 97,121,100,101,112,116,104, 0, 89, 70, 95, + 65, 65,112, 97,115,115,101,115, 0, 89, 70, 95, 65, 65,115, 97,109,112,108,101,115, 0,121,102,112, 97,100, 50, 0, 71, 73,115, +104, 97,100,111,119,113,117, 97,108,105,116,121, 0, 71, 73,114,101,102,105,110,101,109,101,110,116, 0, 71, 73,112,111,119,101, +114, 0, 71, 73,105,110,100,105,114,112,111,119,101,114, 0, 89, 70, 95,103, 97,109,109, 97, 0, 89, 70, 95,101,120,112,111,115, +117,114,101, 0, 89, 70, 95,114, 97,121, 98,105, 97,115, 0, 89, 70, 95, 65, 65,112,105,120,101,108,115,105,122,101, 0, 89, 70, + 95, 65, 65,116,104,114,101,115,104,111,108,100, 0, 98, 97, 99,107, 98,117,102, 91, 49, 54, 48, 93, 0,112,105, 99, 91, 49, 54, + 48, 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, 49, 54, 48, 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,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,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,109, + 97,116,109,111,100,101, 0,102,114, 97,109,105,110,103, 0,100,111,109,101, 0,115,116,101,114,101,111,102,108, 97,103, 0, 42, + 42, 98,114,117,115,104,101,115, 0, 97, 99,116,105,118,101, 95, 98,114,117,115,104, 95,105,110,100,101,120, 0, 98,114,117,115, +104, 95, 99,111,117,110,116, 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,116,111,111,108, 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, 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,110, 97,109, +101, 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93, 91, 51, 93, 0,112,105,118,111,116, 91, 51, 93, 0,116, 97, 98,108,101,116, 95, +115,105,122,101, 0,116, 97, 98,108,101,116, 95,115,116,114,101,110,103,116,104, 0,103, 97,109,109, 97, 0,109,117,108, 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, 42,118,112, 97,105,110,116, + 0, 42,119,112, 97,105,110,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,112, + 97,100, 91, 50, 93, 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,114,101,116,111,112,111, 95,109,111,100,101, 0,114,101,116,111,112, +111, 95,112, 97,105,110,116, 95,116,111,111,108, 0,108,105,110,101, 95,100,105,118, 0,101,108,108,105,112,115,101, 95,100,105, +118, 0,114,101,116,111,112,111, 95,104,111,116,115,112,111,116, 0,109,117,108,116,105,114,101,115, 95,115,117, 98,100,105,118, + 95,116,121,112,101, 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,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,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,103,114, 97,118,105,116,121, 91, 51, 93, 0, 42, 99, 97,109,101,114, 97, 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, 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,115,111,117,110,100, 95,104, 97,110, +100,108,101,115, 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,106,117,109,112,102,114, 97,109,101, 0,102,114, 97,109,101, 95,115,116,101,112, 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, 98,108,101,110,100, 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,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,118,105,101,119, 98,117,116, 0,114,102,108, 97,103, 0,118,105,101, +119,108,111, 99,107, 0,112,101,114,115,112, 0,118,105,101,119, 0, 99,108,105,112, 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,116,111,112,111, 95,118,105,101,119, 95,100, 97, +116, 97, 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,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,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,108, 97,121, 95,117,115,101,100, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 42, 98,103,112, +105, 99, 0,111, 98, 95, 99,101,110,116,114,101, 95, 98,111,110,101, 91, 51, 50, 93, 0,108, 97,121, 97, 99,116, 0,100,114, 97, +119,116,121,112,101, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0,112,105,118,111,116, 95,108, 97,115, 116, 0,103,114,105,100, 0,103,114,105,100,118,105,101,119, 0,112, 97,100,102, 0,110,101, 97,114, 0,102, 97,114, 0,103,114, 105,100,108,105,110,101,115, 0,103,114,105,100,102,108, 97,103, 0,103,114,105,100,115,117, 98,100,105,118, 0,109,111,100,101, 115,101,108,101, 99,116, 0,107,101,121,102,108, 97,103,115, 0,116,119,116,121,112,101, 0,116,119,109,111,100,101, 0,116,119, @@ -1975,374 +2016,379 @@ char datatoc_B_blend[]= { 91, 51, 50, 93, 0,118, 97,108,117,101, 91, 51, 50, 93, 0,109, 97,120,118, 97,108,117,101, 91, 51, 50, 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, 51, 50, 93, 0,100, 97,109,112, 116,105,109,101,114, 0,112,114,111,112,110, 97,109,101, 91, 51, 50, 93, 0,109, 97,116,110, 97,109,101, 91, 51, 50, 93, 0, 97, -120,105,115,102,108, 97,103, 0, 42,102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 51, 50, 93, 0, - 98,111,100,121, 91, 51, 50, 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,109,111,100,117,108,101, 91, 54, 52, 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, 51, 50, 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,115,110,100,110,114, 0,112, 97,100, 49, 91, 50, 93, 0,112,105,116, - 99,104, 0,115,111,117,110,100, 51, 68, 0,109, 97,107,101, 99,111,112,121, 0, 99,111,112,121,109, 97,100,101, 0,112, 97,100, - 50, 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,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, 98,117,116,115,116, 97, 0, 98,117,116,101,110,100, 0,109,105,110, 0,109, 97,120, 0,118,105,115, -105,102, 97, 99, 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, 51, 50, 93, - 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, 51, 50, 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,103,111, 0, 97, 99, 99,101,108,108,101,114, 97,116,105,111,110, 0,109, 97,120,115, -112,101,101,100, 0,109, 97,120,114,111,116,115,112,101,101,100, 0,109, 97,120,116,105,108,116,115,112,101,101,100, 0,116,105, -108,116,100, 97,109,112, 0,115,112,101,101,100,100, 97,109,112, 0, 42,115,111,117,114, 99,101, 0,102,114, 97,109,101,115,107, -105,112, 0,109,117,116,101, 0, 99,104, 97,110,103,101,100, 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, 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, 97,114,101, 97, 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, 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,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, 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,115,107,101,116, 99,104, 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, 42,112,114,111,112, 0, 99,111,110,115,116,102,108, 97, -103, 0,105,107,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0, 97,103,114,112, 95,105,110,100,101,120, 0, 42, - 98,111,110,101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0, 42, 98, 95, 98,111,110,101, 95,109, 97,116,115, 0, - 42,100,117, 97,108, 95,113,117, 97,116, 0, 42, 98, 95, 98,111,110,101, 95,100,117, 97,108, 95,113,117, 97,116,115, 0,101,117, -108, 91, 51, 93, 0,114,111,116,109,111,100,101, 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, 42, 99,117,115,116,111,109, 0, 99,104, 97,110, - 98, 97,115,101, 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, 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,102,105,108,116,101,114, -102,108, 97,103, 0, 97,100,115, 0, 97, 99,116,110,114, 0, 97, 99,116,119,105,100,116,104, 0,116,105,109,101,115,108,105,100, -101, 0, 42,103,114,112, 0,116,101,109,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, 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, - 51, 50, 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,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,122,109,105,110, 0,122,109, 97,120, 0,112, 97,100, 91, 57, - 93, 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,115, 99, 97,108,101, 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, 42,110,101,119, 95,115,111, 99,107, 0,110,115, 0,108,105,109,105,116, 0,115,116, 97, 99,107, 95,105,110, -100,101,120, 0,105,110,116,101,114,110, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 95,101,120,116, 0,108,111, 99,120, 0, -108,111, 99,121, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, 95,105,110,100,101,120, 0, 42,116,111,115,111, 99,107, 0, - 42,108,105,110,107, 0, 42,110,101,119, 95,110,111,100,101, 0,117,115,101,114,110, 97,109,101, 91, 51, 50, 93, 0,108, 97,115, -116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97,103,101, 0,109,105,110,105,119,105,100,116,104, 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,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,110,111,100,101,115, 0,108,105,110,107,115, 0, 42,115,116, 97, 99,107, - 0, 42,116,104,114,101, 97,100,115,116, 97, 99,107, 0,105,110,105,116, 0,115,116, 97, 99,107,115,105,122,101, 0, 99,117,114, - 95,105,110,100,101,120, 0, 97,108,108,116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0, 42,115,101,108,105,110, 0, - 42,115,101,108,111,117,116, 0, 40, 42,116,105,109,101, 99,117,114,115,111,114, 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,116, 99, -104, 0, 42,115,100,104, 0, 99,121, 99,108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,115, 0,109,105,110,115, -112,101,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, 99,117,114, -118,101,100, 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,105,116,101,114, 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, -115, 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,120, 49, 0,120, 50, 0,121, 49, 0,121, 50, 0, 99,111,108,110, 97,109,101, 91, 51, 50, 93, 0, 98,107,116, -121,112,101, 0,114,111,116, 97,116,105,111,110, 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, 42,100,105, 99,116, 0, 42,110,111,100,101, 0, 97,110,103, -108,101, 95,111,102,115, 0, 99,111,108,109,111,100, 0,109,105,120, 0,116,104,114,101,115,104,111,108,100, 0,102, 97,100,101, - 0,109, 0, 99, 0,106,105,116, 0,112,114,111,106, 0,102,105,116, 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, 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,111,102,102,115,101,116, 91, 50, 93, 0, 99,108,111,110,101, - 0,105,110,110,101,114,114, 97,100,105,117,115, 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,116,111,111,108, 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,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,101,100,105,116,102, -108, 97,103, 0,118,101,108, 91, 51, 93, 0,114,111,116, 91, 52, 93, 0, 97,118,101, 91, 51, 93, 0, 42,103,114,111,117,110,100, - 0,103,114, 97,118,105,116,121, 91, 51, 93, 0,119, 97,110,100,101,114, 91, 51, 93, 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,114, 97,110,100, 91, - 51, 93, 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, 97,108,105,118,101, 0,108,111,111,112, 0,104, 97,105,114, 95,105,110, -100,101,120, 0, 42, 98,111,105,100,115, 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,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,115,105,109,112,108,105,102,121, 95,102,108, 97,103, 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,106,105,116,102, 97, 99, 0,101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114,101,115, 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, 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,114,101, 97, 99,116,115,104, 97,112,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,100, 97,109,112,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,102, 97, 99, 0, 99,108,117,109, -112,112,111,119, 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, 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,101,102,102,101, 99,116,111,114, 95,119,101,105,103,104,116, 91, 49, 48, - 93, 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,101,102,102,101, 99, -116,111,114,115, 0,114,101, 97, 99,116,101,118,101,110,116,115, 0,116,114,101,101, 95,102,114, 97,109,101, 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, 51, 50, 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,116,114,101,101, 0, 67,100,105,115, 0, 67,118,105, 0, 91, 51, - 93, 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,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,112,114,101, -115,101,116,115, 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,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, 42,116,121,112,101,115,116,114, 0, 42,109,101, -115,115, 97,103,101, 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,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,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,107,101,121,109, 97,112,115, 0, 42,103,104,111,115,116,119,105,110, 0, 42,110,101,119,115, 99,114,101,101,110, 0,115, - 99,114,101,101,110,110, 97,109,101, 91, 51, 50, 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, 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,116,105, -109,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, 42,112,116,114, 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,112,114,111,112,118, 97,108,117,101, 0,105,110, 97, 99,116,105,118,101, 0,109, 97,112,116, -121,112,101, 0,107,101,121,109, 97,112, 0,110, 97,109,101,105,100, 91, 54, 52, 93, 0,115,112, 97, 99,101,105,100, 0,114,101, -103,105,111,110,105,100, 0,105,115, 95,109,111,100, 97,108, 0, 42,105,116,101,109,115, 0, 42, 99,117,115,116,111,109,100, 97, -116, 97, 0, 42,114,101,112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0,109,118, 97,108, 91, 50, 93, 0,112, -114,101,118,120, 0,112,114,101,118,121, 0,117,110,105, 99,111,100,101, 0, 97,115, 99,105,105, 0, 42,107,101,121,109, 97,112, - 95,105,100,110, 97,109,101, 0, 99,117,115,116,111,109, 0, 99,117,115,116,111,109,100, 97,116, 97,102,114,101,101, 0, 42,101, -100, 97,116, 97, 0,105,110,102,108,117,101,110, 99,101, 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, 42,114,110, 97, 95,112, 97,116, -104, 0, 97,114,114, 97,121, 95,105,110,100,101,120, 0,101,120,112,114,101,115,115,105,111,110, 91, 50, 53, 54, 93, 0,118,101, - 99, 91, 50, 93, 0, 42,102,112,116, 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,103,114,111,117,112, 91, 54, 52, 93, 0,105,100,116,121,112,101, 0, -116,101,109,112,108, 97,116,101,115, 0,103,114,111,117,112,109,111,100,101, 0,112, 97,116,104,115, 0,107,101,121,105,110,103, -102,108, 97,103, 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, 99, 99,117,114, 97, 99,121, 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, 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, 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,118,101, -108,111, 99,105,116,121, 91, 51, 93, 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,110,117,109,112,111,105,110,116,115, 0, 0, 0, 0, 84, 89, 80, 69,182, 1, 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,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,105, 0,118,101, 99, 50,102, 0,118,101, 99, 50,100, 0, -118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51,100, 0,118,101, 99, 52,105, 0,118,101, 99, 52,102, 0,118,101, - 99, 52,100, 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, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, 86,111,120,101,108, 68, 97, -116, 97, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97,112,112,105,110,103, 0, 76, 97,109,112, 0, 67,117,114, -118,101, 77, 97,112,112,105,110,103, 0, 87, 97,118,101, 0, 86,111,108,117,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, 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, 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, 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, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 0, 77, 68,101, -102,111,114,109, 87,101,105,103,104,116, 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 85, 86, 0, 77, 76,111,111, -112, 67,111,108, 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, 77, - 68,105,115,112,115, 0, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 32, 40, 49, 60, 60, 49, - 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 32, 40, 49, 60, 60, 50, 41, 32, 35,100,101,102,105,110,101, - 32, 77, 69, 95, 70, 71, 79, 78, 32, 40, 49, 60, 60, 51, 41, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, - 82, 69, 78, 68, 69, 82, 32, 40, 49, 60, 60, 53, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, - 71, 69, 32, 40, 49, 60, 60, 55, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 32, 40, - 49, 60, 60, 56, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 32, 40, 49, 60, 60, 57, 41, 32, 32, 32, - 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, - 76, 73, 80, 86, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 32, 52, 32, 35,100,101,102, -105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, - 89, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 32, 51, 50, 32, 35,100,101,102,105,110, -101, 32, 77, 69, 95, 80, 82, 79, 74, 89, 90, 32, 54, 52, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 32, - 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, - 51, 86, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 32, 52, 32, 35,100,101,102,105,110,101, 32, - 77, 69, 95, 86, 52, 86, 49, 32, 56, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 32, 49, 32, 35, -100,101,102,105,110,101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 32, 50, 32, 32, 32, 35,100,101,102,105,110,101, 32, 77, - 69, 95, 86, 83, 69,108, 32, 48, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 32, 35,100,101,102,105, -110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, - 49, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 83, 69, 76, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 32, 56, 32, 35,100,101,102, -105,110,101, 32, 84, 70, 95, 83, 69, 76, 51, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 32, 51, - 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 32, 54, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, - 70, 95, 68, 89, 78, 65, 77, 73, 67, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, - 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, - 72, 65, 82, 69, 68, 86, 69, 82, 84, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 32, 49, 54, 32, - 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 84, 73, 76, 69, 83, 32, 49, 50, 56, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, - 82, 68, 32, 50, 53, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 32, 53, 49, 50, 32, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 32, 49, 48, 50, 52, 32, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 79, 66, 67, 79, 76, 32, 50, 48, 52, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, - 82, 68, 50, 32, 52, 48, 57, 54, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 32, 56, 49, 57, 50, - 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 32, 49, 54, 51, 56, 52, 32, 32, 35,100,101,102,105,110, -101, 32, 84, 70, 95, 83, 79, 76, 73, 68, 32, 48, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 32, 49, 32, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, 80, - 32, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 32, 51, 32, 32, 35,100,101,102,105,110,101, 32, 84, - 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, - 67, 65, 84, 69, 68, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 32, - 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 32, 56, 32, 35,100,101,102,105, -110,101, 32, 84, 70, 95, 80, 73, 78, 49, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 32, 51, 50, - 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, - 73, 78, 52, 32, 49, 50, 56, 32, 35,101,110,100,105,102, 77,117,108,116,105,114,101,115, 76,101,118,101,108, 59, 13, 10, 13, 10, -116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 77,117,108,116,105,114,101,115, 32,123, 13, 10, 9, 76,105,115,116, - 66, 97,115,101, 32,108,101,118,101,108,115, 59, 13, 10, 9, 77, 86,101,114,116, 32, 42,118,101,114,116,115, 59, 13, 10, 13, 10, - 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,108,101,118,101,108, 95, 99,111,117,110,116, 44, 32, 99,117,114,114, -101,110,116, 44, 32,110,101,119,108,118,108, 44, 32,101,100,103,101,108,118,108, 44, 32,112,105,110,108,118,108, 44, 32,114,101, -110,100,101,114,108,118,108, 59, 13, 10, 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,117,115,101, 95, 99,111,108, - 44, 32,102,108, 97,103, 59, 13, 10, 13, 10, 9, 47, 42, 32, 83,112,101, 99,105, 97,108, 32,108,101,118,101,108, 32, 49, 32,100, - 97,116, 97, 32,116,104, 97,116, 32, 99, 97,110,110,111,116, 32, 98,101, 32,109,111,100,105,102,105,101,100, 32,102,114,111,109, - 32,111,116,104,101,114, 32,108,101,118,101,108,115, 32, 42, 47, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,118,100, - 97,116, 97, 59, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,102,100, 97,116, 97, 59, 13, 10, 9,115,104,111,114,116, - 32, 42,101,100,103,101, 95,102,108, 97,103,115, 59, 13, 10, 9, 99,104, 97,114, 32, 42,101,100,103,101, 95, 99,114,101, 97,115, -101,115, 59, 13, 10,125, 32, 77,117,108,116,105,114,101,115, 59, 13, 10, 13, 10, 47, 42, 42, 32, 69,110,100, 32, 77,117,108,116, -105,114,101,115, 32, 42, 42, 47, 13, 10, 13, 10,116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 80, 97,114,116,105, - 97,108, 86,105,115,105, 98,105,108,105,116,121, 32,123, 13, 10, 9,117,110,115,105,103,110,101,100, 32,105,110,116, 32, 42,118, -101,114,116, 95,109, 97,112, 59, 32, 47, 42, 32,118,101,114,116, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, - 32, 78,101,119, 32, 73,110,100,101,120, 32, 42, 47, 13, 10, 9,105,110,116, 32, 42,101,100,103,101, 95,109, 97,112, 59, 32, 47, - 42, 32,101,100,103,101, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, 32, 78,101,119, 32, 73,110,100,101,120, - 44, 32, 45, 49, 61, 32,104,105,100,100,101,110, 32, 42, 47, 13, 10, 9, 77, 70, 97, 99,101, 32, 42,111,108,100, 95,102, 97, 99, -101,115, 59, 13, 10, 9, 77, 69,100,103,101, 32, 42,111,108,100, 95,101,100,103,101,115, 59, 13, 10, 9,117,110,115,105,103,110, -101,100, 32,105,110,116, 32,116,111,116,102, 97, 99,101, 44, 32,116,111,116,101,100,103,101, 44, 32,116,111,116,118,101,114,116, - 44, 32,112, 97,100, 59, 13, 10,125, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 59, 13, 10, 13, 10, - 47, 42, 32,109,118,101,114,116, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 32, 42, 47, 13, 10, 35,100, -101,102,105,110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 83, 84, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, - 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 77, 80, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 72, 73, 68, 69, 9, - 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 69, 82, 84, 95, 77, 69, 82, 71, 69, 68, 9, 9, 40, 49, - 60, 60, 54, 41, 13, 10, 13, 10, 47, 42, 32,109,101,100,103,101, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, - 41, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 9, 9, 9, 40, 49, 60, 60, 49, - 41, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 9, 9, 9, 9, 40, 49, 60, 60, 50, 41, 13, 10, 35,100, -101,102,105,110,101, 32, 77, 69, 95, 70, 71, 79, 78, 9, 9, 9, 9, 40, 49, 60, 60, 51, 41, 13, 10, 9, 9, 9, 9, 9, 9, 47, - 42, 32,114,101,115,101,114,118,101, 32, 49, 54, 32,102,111,114, 32, 77, 69, 95, 72, 73, 68, 69, 32, 42, 47, 13, 10, 35,100,101, -102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 9, 9, 40, 49, 60, 60, 53, 41, 13, 10, 35,100,101,102, -105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, 71, 69, 9, 9, 40, 49, 60, 60, 55, 41, 13, 10, 35,100,101,102,105,110, -101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 9, 9, 40, 49, 60, 60, 56, 41, 13, 10, 35,100,101,102,105,110,101, 32, - 77, 69, 95, 83, 72, 65, 82, 80, 9, 9, 9, 40, 49, 60, 60, 57, 41, 13, 10, 13, 10, 47, 42, 32,112,117,110,111, 32, 61, 32,118, -101,114,116,101,120,110,111,114,109, 97,108, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10, 47, 42, 32,114,101,110,100,101, -114, 32, 97,115,115,117,109,101,115, 32,102,108,105,112,115, 32,116,111, 32, 98,101, 32,111,114,100,101,114,101,100, 32,108,105, -107,101, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 9, 9, 49, - 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 50, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, - 77, 69, 95, 70, 76, 73, 80, 86, 51, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 9, - 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 89, 9, 9, 49, 54, 13, 10, 35,100,101,102,105, -110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 9, 9, 51, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, - 74, 89, 90, 9, 9, 54, 52, 13, 10, 13, 10, 47, 42, 32,101,100, 99,111,100,101, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, - 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, - 95, 86, 50, 86, 51, 9, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 49, 9, 9, 9, 52, 13, 10, - 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, - 86, 52, 86, 49, 9, 9, 9, 56, 13, 10, 13, 10, 47, 42, 32,102,108, 97,103, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10, - 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77, - 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 9, 9, 9, 50, 13, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,102,108, 97,103, 32, 77, 69, - 95, 72, 73, 68, 69, 61, 61, 49, 54, 32,105,115, 32,117,115,101,100, 32,104,101,114,101, 32,116,111,111, 32, 42, 47, 32, 13, 10, - 47, 42, 32,109,115,101,108,101, 99,116, 45, 62,116,121,112,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, - 86, 83, 69,108, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 13, 10, 35,100,101,102,105, -110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,102,108, 97,103, 32, - 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 9, 49, 32, 47, 42, 32,117,115,101, 32, 77, - 70, 97, 99,101, 32,104,105,100,101, 32,102,108, 97,103, 32, 40, 97,102,116,101,114, 32, 50, 46, 52, 51, 41, 44, 32,115,104,111, -117,108,100, 32, 98,101, 32, 97, 98,108,101, 32,116,111, 32,114,101,117,115,101, 32, 97,102,116,101,114, 32, 50, 46, 52, 52, 32, - 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 9, 50, 32, 47, 42, 32,100,101,112,114,101, - 99, 97,116,101,100, 33, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 9, 9, 52, 13, 10, 35, -100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 9, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, - 76, 51, 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 9, 9, 51, 50, 13, 10, 35,100,101, -102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 9, 9, 54, 52, 32, 47, 42, 32,117,110,117,115,101,100, 44, 32,115, 97,109,101, - 32, 97,115, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,109, -111,100,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 9, 9, 49, 13, 10, 35, -100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, - 70, 95, 84, 69, 88, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 86, 69, 82, 84, - 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 9, 9, 49, 54, 13, 10, 13, 10, 35,100,101,102, -105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, - 84, 73, 76, 69, 83, 9, 9, 49, 50, 56, 9, 9, 47, 42, 32,100,101,112,114,101, 99, 97,116,101,100, 32, 42, 47, 13, 10, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 9, 50, 53, 54, 13, 10, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 9, 9, 53, 49, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73, - 83, 73, 66, 76, 69, 9, 49, 48, 50, 52, 13, 10, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, 67, 79, 76, 9, 9, - 50, 48, 52, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 9, 52, 48, 57, 54, - 9, 47, 42, 32,119,105,116,104, 32, 90, 32, 97,120,105,115, 32, 99,111,110,115,116,114, 97,105,110,116, 32, 42, 47, 13, 10, 35, -100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 9, 9, 56, 49, 57, 50, 13, 10, 35,100,101,102,105,110,101, 32, - 84, 70, 95, 66, 77, 70, 79, 78, 84, 9, 9, 49, 54, 51, 56, 52, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,116, -114, 97,110,115,112, 44, 32,118, 97,108,117,101,115, 32, 49, 45, 52, 32, 97,114,101, 32,117,115,101,100, 32, 97,115, 32,102,108, - 97,103,115, 32,105,110, 32,116,104,101, 32, 71, 76, 44, 32, 87, 65, 82, 78, 73, 78, 71, 44, 32, 84, 70, 95, 83, 85, 66, 32, 99, - 97,110,116, 32,119,111,114,107, 32,119,105,116,104, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, - 70, 95, 83, 79, 76, 73, 68, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 9, 9, 49, 13, 10, 35,100, -101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 67, 76, 73, - 80, 9, 9, 52, 32, 47, 42, 32, 99,108,105,112,109, 97,112, 32, 97,108,112,104, 97, 47, 98,105,110, 97,114,121, 32, 97,108,112, -104, 97, 32, 97,108,108, 32,111,114, 32,110,111,116,104,105,110,103, 33, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,115,117, 98, 32, -105,115, 32,110,111,116, 32, 97,118, 97,105,108, 97, 98,108,101, 32,105,110, 32,116,104,101, 32,117,115,101,114, 32,105,110,116, -101,114,102, 97, 99,101, 32, 97,110,121,109,111,114,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, - 66, 9, 9, 51, 13, 10, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,117,110,119,114, 97,112, 32, 42, 47, 13, 10, - 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 9, 49, 13, 10, 35,100,101,102,105,110, -101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 50, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, - 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, - 84, 69, 68, 52, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 49, 9, 9, 32, 32, 32, 32, 49, 54, 13, - 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 9, 9, 32, 32, 32, 32, 51, 50, 13, 10, 35,100,101,102,105,110, -101, 32, 84, 70, 95, 80, 73, 78, 51, 9, 32, 32, 32, 9, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, - 78, 52, 9, 32, 32, 32, 32, 9, 49, 50, 56, 13, 10, 13, 10, 35,101,110,100,105,102, 13, 10,104, 79, 67, 75, 33,109, 98,101,114, - 97, 2, 67, 3,191, 16, 8, 1,232, 80,100, 0, 77,117,108,116,105,114,101,115, 67,111,108, 0, 77,117,108,116,105,114,101,115, +120,105,115,102,108, 97,103, 0,112,111,115,101, 99,104, 97,110,110,101,108, 91, 51, 50, 93, 0, 99,111,110,115,116,114, 97,105, +110,116, 91, 51, 50, 93, 0, 42,102,114,111,109, 79, 98,106,101, 99,116, 0,115,117, 98,106,101, 99,116, 91, 51, 50, 93, 0, 98, +111,100,121, 91, 51, 50, 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,109,111,100,117,108,101, 91, 54, 52, 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, 51, 50, 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,115,110,100,110,114, 0,112, 97,100, 49, 91, 50, 93, 0,112,105,116, 99, +104, 0,115,111,117,110,100, 51, 68, 0,109, 97,107,101, 99,111,112,121, 0, 99,111,112,121,109, 97,100,101, 0,112, 97,100, 50, + 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,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, 98,117,116,115,116, 97, 0, 98,117,116,101,110,100, 0,109,105,110, 0,109, 97,120, 0,118,105,115,105, +102, 97, 99, 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, 51, 50, 93, 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, 51, 50, 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, 42,115,117, 98,116, 97,114,103,101,116, 0,103,111, 0, 97, 99, 99,101,108,108,101,114, + 97,116,105,111,110, 0,109, 97,120,115,112,101,101,100, 0,109, 97,120,114,111,116,115,112,101,101,100, 0,109, 97,120,116,105, +108,116,115,112,101,101,100, 0,116,105,108,116,100, 97,109,112, 0,115,112,101,101,100,100, 97,109,112, 0, 42,115,111,117,114, + 99,101, 0,102,114, 97,109,101,115,107,105,112, 0,109,117,116,101, 0, 99,104, 97,110,103,101,100, 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, 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, 97,114,101, 97, 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, 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,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, 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,115,107,101,116, 99,104, 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, 42,112,114,111, +112, 0, 99,111,110,115,116,102,108, 97,103, 0,105,107,102,108, 97,103, 0,115,101,108,101, 99,116,102,108, 97,103, 0, 97,103, +114,112, 95,105,110,100,101,120, 0, 42, 98,111,110,101, 0, 42, 99,104,105,108,100, 0,105,107,116,114,101,101, 0, 42, 98, 95, + 98,111,110,101, 95,109, 97,116,115, 0, 42,100,117, 97,108, 95,113,117, 97,116, 0, 42, 98, 95, 98,111,110,101, 95,100,117, 97, +108, 95,113,117, 97,116,115, 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, 99,117,115,116,111,109, 0, 99,104, 97,110, 98, 97,115,101, 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,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,102,105,108,116,101,114,102,108, 97,103, 0, + 97,100,115, 0, 97, 99,116,110,114, 0, 97, 99,116,119,105,100,116,104, 0,116,105,109,101,115,108,105,100,101, 0, 42,103,114, +112, 0,116,101,109,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, 51, 50, 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,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, +122,109,105,110, 0,122,109, 97,120, 0,112, 97,100, 91, 57, 93, 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,115, 99, + 97,108,101, 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, 42,110,101,119, 95,115,111, 99,107, 0,110,115, + 0,108,105,109,105,116, 0,115,116, 97, 99,107, 95,105,110,100,101,120, 0,105,110,116,101,114,110, 0,115,116, 97, 99,107, 95, +105,110,100,101,120, 95,101,120,116, 0,108,111, 99,120, 0,108,111, 99,121, 0,111,119,110, 95,105,110,100,101,120, 0,116,111, + 95,105,110,100,101,120, 0, 42,116,111,115,111, 99,107, 0, 42,108,105,110,107, 0, 42,110,101,119, 95,110,111,100,101, 0,117, +115,101,114,110, 97,109,101, 91, 51, 50, 93, 0,108, 97,115,116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97, +103,101, 0,109,105,110,105,119,105,100,116,104, 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,110,111,100,101,115, 0,108,105,110,107,115, 0, 42,115,116, 97, 99,107, 0, 42,116,104,114,101, 97,100,115,116, + 97, 99,107, 0,105,110,105,116, 0,115,116, 97, 99,107,115,105,122,101, 0, 99,117,114, 95,105,110,100,101,120, 0, 97,108,108, +116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0, 42,115,101,108,105,110, 0, 42,115,101,108,111,117,116, 0, 40, 42, +116,105,109,101, 99,117,114,115,111,114, 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,116, 99,104, 0, 42,115,100,104, 0, 99,121, 99, +108,105, 99, 0,109,111,118,105,101, 0,115, 97,109,112,108,101,115, 0,109,105,110,115,112,101,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, 99,117,114,118,101,100, 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,105,116,101,114, 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,115, 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,120, 49, 0,120, 50, + 0,121, 49, 0,121, 50, 0, 99,111,108,110, 97,109,101, 91, 51, 50, 93, 0, 98,107,116,121,112,101, 0,114,111,116, 97,116,105, +111,110, 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, 42,100,105, 99,116, 0, 42,110,111,100,101, 0, 97,110,103,108,101, 95,111,102,115, 0, 99,111,108, +109,111,100, 0,109,105,120, 0,116,104,114,101,115,104,111,108,100, 0,102, 97,100,101, 0,109, 0, 99, 0,106,105,116, 0,112, +114,111,106, 0,102,105,116, 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, 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,111,102,102,115,101,116, 91, 50, 93, 0, 99,108,111,110,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,116,111,111,108, 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,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,101,100,105,116,102,108, 97,103, 0,118,101,108, 91, 51, 93, 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,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, 97,108,105,118,101, 0,108,111,111,112, 0,104, 97,105,114, 95,105,110,100,101, +120, 0, 42, 98,111,105,100,115, 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,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,115,105,109,112,108,105,102,121, 95,102,108, 97,103, 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,106,105,116,102, 97, 99, 0,101,102,102, 95,104, 97,105,114, 0,103,114,105,100, 95,114,101,115, 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, 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,114,101, 97, 99,116,115,104, 97,112,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,100, 97,109,112,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,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, 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, 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,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, 51, 50, 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,116,114,101,101, 0, 42,112,100,100, 0, 42,102,114, 97,110,100, 0, 67,100,105,115, 0, 67,118,105, 0, + 91, 51, 93, 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,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,112, +114,101,115,101,116,115, 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,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, 42,116,121,112,101,115,116,114, 0, 42, +109,101,115,115, 97,103,101, 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,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,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,107,101,121,109, 97,112,115, 0, 42,103,104,111,115,116,119,105,110, 0, 42,110,101,119,115, 99,114,101,101,110, + 0,115, 99,114,101,101,110,110, 97,109,101, 91, 51, 50, 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, 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, +116,105,109,101,114,115, 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, 42,112,116,114, 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,112,114,111,112,118, 97,108, +117,101, 0,105,110, 97, 99,116,105,118,101, 0,109, 97,112,116,121,112,101, 0,107,101,121,109, 97,112, 0,110, 97,109,101,105, +100, 91, 54, 52, 93, 0,115,112, 97, 99,101,105,100, 0,114,101,103,105,111,110,105,100, 0,105,115, 95,109,111,100, 97,108, 0, + 42,105,116,101,109,115, 0, 40, 42,112,111,108,108, 41, 40, 41, 0, 42, 99,117,115,116,111,109,100, 97,116, 97, 0, 42,114,101, +112,111,114,116,115, 0,109, 97, 99,114,111, 0, 42,111,112,109, 0,109,118, 97,108, 91, 50, 93, 0,112,114,101,118,120, 0,112, +114,101,118,121, 0,117,110,105, 99,111,100,101, 0, 97,115, 99,105,105, 0, 42,107,101,121,109, 97,112, 95,105,100,110, 97,109, +101, 0, 99,117,115,116,111,109, 0, 99,117,115,116,111,109,100, 97,116, 97,102,114,101,101, 0, 42,101,100, 97,116, 97, 0,105, +110,102,108,117,101,110, 99,101, 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, 42,114,110, 97, 95,112, 97,116,104, 0, 97,114,114, 97, +121, 95,105,110,100,101,120, 0,101,120,112,114,101,115,115,105,111,110, 91, 50, 53, 54, 93, 0,118,101, 99, 91, 50, 93, 0, 42, +102,112,116, 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,103,114,111,117,112, 91, 54, 52, 93, 0,105,100,116,121,112,101, 0,116,101,109,112,108, 97, +116,101,115, 0,103,114,111,117,112,109,111,100,101, 0,112, 97,116,104,115, 0,107,101,121,105,110,103,102,108, 97,103, 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, 99, 99,117,114, 97, 99,121, 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, 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, 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,118,101,108,111, 99,105,116,121, 91, 51, 93, 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,110,117,109,112,111,105,110,116,115, 0, 0, 84, 89, 80, 69,191, 1, 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,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,105, 0,118,101, 99, 50,102, 0,118,101, + 99, 50,100, 0,118,101, 99, 51,105, 0,118,101, 99, 51,102, 0,118,101, 99, 51,100, 0,118,101, 99, 52,105, 0,118,101, 99, 52, +102, 0,118,101, 99, 52,100, 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, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 0, 86,111,120, +101,108, 68, 97,116, 97, 0, 98, 78,111,100,101, 84,114,101,101, 0, 84,101,120, 77, 97,112,112,105,110,103, 0, 76, 97,109,112, + 0, 67,117,114,118,101, 77, 97,112,112,105,110,103, 0, 87, 97,118,101, 0, 86,111,108,117,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, 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, 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, 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, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, + 0, 77, 68,101,102,111,114,109, 87,101,105,103,104,116, 0, 77, 84,101,120, 80,111,108,121, 0, 77, 76,111,111,112, 85, 86, 0, + 77, 76,111,111,112, 67,111,108, 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, 77, 68,105,115,112,115, 0, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 32, 40, + 49, 60, 60, 49, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 32, 40, 49, 60, 60, 50, 41, 32, 35,100,101, +102,105,110,101, 32, 77, 69, 95, 70, 71, 79, 78, 32, 40, 49, 60, 60, 51, 41, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, + 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 32, 40, 49, 60, 60, 53, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, + 83, 69, 69, 68, 71, 69, 32, 40, 49, 60, 60, 55, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, + 83, 84, 32, 40, 49, 60, 60, 56, 41, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 32, 40, 49, 60, 60, 57, + 41, 32, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, + 77, 69, 95, 70, 76, 73, 80, 86, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 32, 52, 32, + 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 52, 32, 56, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, + 82, 79, 74, 88, 89, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 32, 51, 50, 32, 35,100, +101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 89, 90, 32, 54, 52, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, + 49, 86, 50, 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 50, 86, 51, 32, 50, 32, 35,100,101,102,105,110,101, 32, + 77, 69, 95, 86, 51, 86, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 32, 52, 32, 35,100,101,102, +105,110,101, 32, 77, 69, 95, 86, 52, 86, 49, 32, 56, 32, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, + 32, 49, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 32, 50, 32, 32, 32, 35,100,101,102,105, +110,101, 32, 77, 69, 95, 86, 83, 69,108, 32, 48, 32, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 32, 35, +100,101,102,105,110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, + 69, 67, 84, 32, 49, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 32, 50, 32, 32, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 32, 56, 32, + 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 51, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, + 76, 52, 32, 51, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 32, 54, 52, 32, 32, 32, 35,100,101,102,105, +110,101, 32, 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, + 83, 79, 82, 84, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 69, 88, 32, 52, 32, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 83, 72, 65, 82, 69, 68, 86, 69, 82, 84, 32, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, + 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 32, 54, 52, 32, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 84, 73, 76, 69, 83, 32, 49, 50, 56, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, + 76, 66, 79, 65, 82, 68, 32, 50, 53, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 32, 53, 49, + 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 73, 78, 86, 73, 83, 73, 66, 76, 69, 32, 49, 48, 50, 52, 32, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 79, 66, 67, 79, 76, 32, 50, 48, 52, 56, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, + 76, 66, 79, 65, 82, 68, 50, 32, 52, 48, 57, 54, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 32, + 56, 49, 57, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 32, 49, 54, 51, 56, 52, 32, 32, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 83, 79, 76, 73, 68, 32, 48, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 32, + 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, + 67, 76, 73, 80, 32, 52, 32, 32, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 85, 66, 32, 51, 32, 32, 35,100,101,102,105, +110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 32, 49, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, + 69, 80, 82, 69, 67, 65, 84, 69, 68, 50, 32, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, + 69, 68, 51, 32, 52, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 52, 32, 56, 32, 35, +100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 49, 32, 49, 54, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, + 50, 32, 51, 50, 32, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 32, 54, 52, 32, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 80, 73, 78, 52, 32, 49, 50, 56, 32, 35,101,110,100,105,102, 32,117,108,116,105,114,101,115, 76,101,118,101,108, 59, + 13, 10, 13, 10,116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 77,117,108,116,105,114,101,115, 32,123, 13, 10, 9, + 76,105,115,116, 66, 97,115,101, 32,108,101,118,101,108,115, 59, 13, 10, 9, 77, 86,101,114,116, 32, 42,118,101,114,116,115, 59, + 13, 10, 13, 10, 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,108,101,118,101,108, 95, 99,111,117,110,116, 44, 32, + 99,117,114,114,101,110,116, 44, 32,110,101,119,108,118,108, 44, 32,101,100,103,101,108,118,108, 44, 32,112,105,110,108,118,108, + 44, 32,114,101,110,100,101,114,108,118,108, 59, 13, 10, 9,117,110,115,105,103,110,101,100, 32, 99,104, 97,114, 32,117,115,101, + 95, 99,111,108, 44, 32,102,108, 97,103, 59, 13, 10, 13, 10, 9, 47, 42, 32, 83,112,101, 99,105, 97,108, 32,108,101,118,101,108, + 32, 49, 32,100, 97,116, 97, 32,116,104, 97,116, 32, 99, 97,110,110,111,116, 32, 98,101, 32,109,111,100,105,102,105,101,100, 32, +102,114,111,109, 32,111,116,104,101,114, 32,108,101,118,101,108,115, 32, 42, 47, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, + 97, 32,118,100, 97,116, 97, 59, 13, 10, 9, 67,117,115,116,111,109, 68, 97,116, 97, 32,102,100, 97,116, 97, 59, 13, 10, 9,115, +104,111,114,116, 32, 42,101,100,103,101, 95,102,108, 97,103,115, 59, 13, 10, 9, 99,104, 97,114, 32, 42,101,100,103,101, 95, 99, +114,101, 97,115,101,115, 59, 13, 10,125, 32, 77,117,108,116,105,114,101,115, 59, 13, 10, 13, 10, 47, 42, 42, 32, 69,110,100, 32, + 77,117,108,116,105,114,101,115, 32, 42, 42, 47, 13, 10, 13, 10,116,121,112,101,100,101,102, 32,115,116,114,117, 99,116, 32, 80, + 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 32,123, 13, 10, 9,117,110,115,105,103,110,101,100, 32,105,110, +116, 32, 42,118,101,114,116, 95,109, 97,112, 59, 32, 47, 42, 32,118,101,114,116, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100, +101,120, 93, 61, 32, 78,101,119, 32, 73,110,100,101,120, 32, 42, 47, 13, 10, 9,105,110,116, 32, 42,101,100,103,101, 95,109, 97, +112, 59, 32, 47, 42, 32,101,100,103,101, 95,109, 97,112, 91, 79,108,100, 32, 73,110,100,101,120, 93, 61, 32, 78,101,119, 32, 73, +110,100,101,120, 44, 32, 45, 49, 61, 32,104,105,100,100,101,110, 32, 42, 47, 13, 10, 9, 77, 70, 97, 99,101, 32, 42,111,108,100, + 95,102, 97, 99,101,115, 59, 13, 10, 9, 77, 69,100,103,101, 32, 42,111,108,100, 95,101,100,103,101,115, 59, 13, 10, 9,117,110, +115,105,103,110,101,100, 32,105,110,116, 32,116,111,116,102, 97, 99,101, 44, 32,116,111,116,101,100,103,101, 44, 32,116,111,116, +118,101,114,116, 44, 32,112, 97,100, 59, 13, 10,125, 32, 80, 97,114,116,105, 97,108, 86,105,115,105, 98,105,108,105,116,121, 59, + 13, 10, 13, 10, 47, 42, 32,109,118,101,114,116, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, 76, 69, 67, 84, 41, 32, 42, 47, + 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 83, 84, 9, 50, 13, 10, 35,100,101,102,105, +110,101, 32, 77, 69, 95, 83, 80, 72, 69, 82, 69, 84, 69, 77, 80, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 72, + 73, 68, 69, 9, 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 69, 82, 84, 95, 77, 69, 82, 71, 69, 68, + 9, 9, 40, 49, 60, 60, 54, 41, 13, 10, 13, 10, 47, 42, 32,109,101,100,103,101, 45, 62,102,108, 97,103, 32, 40, 49, 61, 83, 69, + 76, 69, 67, 84, 41, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 68, 82, 65, 87, 9, 9, 9, 40, + 49, 60, 60, 49, 41, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 9, 9, 9, 9, 40, 49, 60, 60, 50, 41, + 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 71, 79, 78, 9, 9, 9, 9, 40, 49, 60, 60, 51, 41, 13, 10, 9, 9, 9, + 9, 9, 9, 47, 42, 32,114,101,115,101,114,118,101, 32, 49, 54, 32,102,111,114, 32, 77, 69, 95, 72, 73, 68, 69, 32, 42, 47, 13, + 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 68, 71, 69, 82, 69, 78, 68, 69, 82, 9, 9, 40, 49, 60, 60, 53, 41, 13, 10, + 35,100,101,102,105,110,101, 32, 77, 69, 95, 76, 79, 79, 83, 69, 69, 68, 71, 69, 9, 9, 40, 49, 60, 60, 55, 41, 13, 10, 35,100, +101,102,105,110,101, 32, 77, 69, 95, 83, 69, 65, 77, 95, 76, 65, 83, 84, 9, 9, 40, 49, 60, 60, 56, 41, 13, 10, 35,100,101,102, +105,110,101, 32, 77, 69, 95, 83, 72, 65, 82, 80, 9, 9, 9, 40, 49, 60, 60, 57, 41, 13, 10, 13, 10, 47, 42, 32,112,117,110,111, + 32, 61, 32,118,101,114,116,101,120,110,111,114,109, 97,108, 32, 40,109,102, 97, 99,101, 41, 32, 42, 47, 13, 10, 47, 42, 32,114, +101,110,100,101,114, 32, 97,115,115,117,109,101,115, 32,102,108,105,112,115, 32,116,111, 32, 98,101, 32,111,114,100,101,114,101, +100, 32,108,105,107,101, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, + 49, 9, 9, 49, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 50, 9, 9, 50, 13, 10, 35,100,101,102, +105,110,101, 32, 77, 69, 95, 70, 76, 73, 80, 86, 51, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 70, 76, 73, + 80, 86, 52, 9, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 89, 9, 9, 49, 54, 13, 10, 35, +100,101,102,105,110,101, 32, 77, 69, 95, 80, 82, 79, 74, 88, 90, 9, 9, 51, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, + 95, 80, 82, 79, 74, 89, 90, 9, 9, 54, 52, 13, 10, 13, 10, 47, 42, 32,101,100, 99,111,100,101, 32, 40,109,102, 97, 99,101, 41, + 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 49, 86, 50, 9, 9, 9, 49, 13, 10, 35,100,101,102,105,110, +101, 32, 77, 69, 95, 86, 50, 86, 51, 9, 9, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 49, 9, 9, + 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 86, 51, 86, 52, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, + 32, 77, 69, 95, 86, 52, 86, 49, 9, 9, 9, 56, 13, 10, 13, 10, 47, 42, 32,102,108, 97,103, 32, 40,109,102, 97, 99,101, 41, 32, + 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 83, 77, 79, 79, 84, 72, 9, 9, 9, 49, 13, 10, 35,100,101,102,105, +110,101, 32, 77, 69, 95, 70, 65, 67, 69, 95, 83, 69, 76, 9, 9, 9, 50, 13, 10, 9, 9, 9, 9, 9, 9, 47, 42, 32,102,108, 97, +103, 32, 77, 69, 95, 72, 73, 68, 69, 61, 61, 49, 54, 32,105,115, 32,117,115,101,100, 32,104,101,114,101, 32,116,111,111, 32, 42, + 47, 32, 13, 10, 47, 42, 32,109,115,101,108,101, 99,116, 45, 62,116,121,112,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, + 32, 77, 69, 95, 86, 83, 69,108, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 77, 69, 95, 69, 83, 69,108, 32, 49, 13, 10, 35, +100,101,102,105,110,101, 32, 77, 69, 95, 70, 83, 69, 76, 32, 50, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,102, +108, 97,103, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 9, 49, 32, 47, 42, 32,117, +115,101, 32, 77, 70, 97, 99,101, 32,104,105,100,101, 32,102,108, 97,103, 32, 40, 97,102,116,101,114, 32, 50, 46, 52, 51, 41, 44, + 32,115,104,111,117,108,100, 32, 98,101, 32, 97, 98,108,101, 32,116,111, 32,114,101,117,115,101, 32, 97,102,116,101,114, 32, 50, + 46, 52, 52, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 67, 84, 73, 86, 69, 9, 50, 32, 47, 42, 32,100, +101,112,114,101, 99, 97,116,101,100, 33, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 49, 9, 9, + 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 50, 9, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 83, 69, 76, 51, 9, 9, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 69, 76, 52, 9, 9, 51, 50, 13, + 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 72, 73, 68, 69, 9, 9, 54, 52, 32, 47, 42, 32,117,110,117,115,101,100, 44, 32, +115, 97,109,101, 32, 97,115, 32, 84, 70, 95, 83, 69, 76, 69, 67, 84, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99, +101, 45, 62,109,111,100,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 89, 78, 65, 77, 73, 67, 9, 9, + 49, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 83, 79, 82, 84, 9, 50, 13, 10, 35,100,101,102,105, +110,101, 32, 84, 70, 95, 84, 69, 88, 9, 9, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, + 86, 69, 82, 84, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 76, 73, 71, 72, 84, 9, 9, 49, 54, 13, 10, 13, 10, + 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 82, 69, 68, 67, 79, 76, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, + 32, 84, 70, 95, 84, 73, 76, 69, 83, 9, 9, 49, 50, 56, 9, 9, 47, 42, 32,100,101,112,114,101, 99, 97,116,101,100, 32, 42, 47, + 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 9, 50, 53, 54, 13, 10, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 84, 87, 79, 83, 73, 68, 69, 9, 9, 53, 49, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, + 73, 78, 86, 73, 83, 73, 66, 76, 69, 9, 49, 48, 50, 52, 13, 10, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 79, 66, 67, + 79, 76, 9, 9, 50, 48, 52, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 66, 73, 76, 76, 66, 79, 65, 82, 68, 50, 9, + 52, 48, 57, 54, 9, 47, 42, 32,119,105,116,104, 32, 90, 32, 97,120,105,115, 32, 99,111,110,115,116,114, 97,105,110,116, 32, 42, + 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 83, 72, 65, 68, 79, 87, 9, 9, 56, 49, 57, 50, 13, 10, 35,100,101,102, +105,110,101, 32, 84, 70, 95, 66, 77, 70, 79, 78, 84, 9, 9, 49, 54, 51, 56, 52, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99, +101, 45, 62,116,114, 97,110,115,112, 44, 32,118, 97,108,117,101,115, 32, 49, 45, 52, 32, 97,114,101, 32,117,115,101,100, 32, 97, +115, 32,102,108, 97,103,115, 32,105,110, 32,116,104,101, 32, 71, 76, 44, 32, 87, 65, 82, 78, 73, 78, 71, 44, 32, 84, 70, 95, 83, + 85, 66, 32, 99, 97,110,116, 32,119,111,114,107, 32,119,105,116,104, 32,116,104,105,115, 32, 42, 47, 13, 10, 35,100,101,102,105, +110,101, 32, 84, 70, 95, 83, 79, 76, 73, 68, 9, 48, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 68, 68, 9, 9, 49, + 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 65, 76, 80, 72, 65, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, + 95, 67, 76, 73, 80, 9, 9, 52, 32, 47, 42, 32, 99,108,105,112,109, 97,112, 32, 97,108,112,104, 97, 47, 98,105,110, 97,114,121, + 32, 97,108,112,104, 97, 32, 97,108,108, 32,111,114, 32,110,111,116,104,105,110,103, 33, 32, 42, 47, 13, 10, 13, 10, 47, 42, 32, +115,117, 98, 32,105,115, 32,110,111,116, 32, 97,118, 97,105,108, 97, 98,108,101, 32,105,110, 32,116,104,101, 32,117,115,101,114, + 32,105,110,116,101,114,102, 97, 99,101, 32, 97,110,121,109,111,114,101, 32, 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 83, 85, 66, 9, 9, 51, 13, 10, 13, 10, 13, 10, 47, 42, 32,109,116,102, 97, 99,101, 45, 62,117,110,119,114, 97,112, 32, + 42, 47, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 49, 9, 49, 13, 10, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 50, 9, 50, 13, 10, 35,100,101,102,105,110,101, 32, + 84, 70, 95, 68, 69, 80, 82, 69, 67, 65, 84, 69, 68, 51, 9, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 68, 69, 80, + 82, 69, 67, 65, 84, 69, 68, 52, 9, 56, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 49, 9, 9, 32, 32, 32, + 32, 49, 54, 13, 10, 35,100,101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 50, 9, 9, 32, 32, 32, 32, 51, 50, 13, 10, 35,100, +101,102,105,110,101, 32, 84, 70, 95, 80, 73, 78, 51, 9, 32, 32, 32, 9, 9, 54, 52, 13, 10, 35,100,101,102,105,110,101, 32, 84, + 70, 95, 80, 73, 78, 52, 9, 32, 32, 32, 32, 9, 49, 50, 56, 13, 10, 13, 10, 35,101,110,100,105,102, 13, 10,104, 79, 67, 75, 33, +109, 98,101,114, 82,163, 81,172,147,203, 19, 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,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, @@ -2374,770 +2420,787 @@ char datatoc_B_blend[]= { 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, 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, 82, 78, 71, 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, 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, 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, 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, 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, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110, 0, 83, 99,117,108,112,116, - 0, 86, 80, 97,105,110,116, 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, 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, 66, 71,112,105, 99, 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,116,111,112,111, 86,105,101,119, 68, 97,116, 97, 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, 98, 83, 99,114,101,101,110, 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,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, 0, 83,112, - 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,105, 99, 0, 83,112, 97, 99,101, 73,109, 97, 83,101,108, 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,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, 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, 83,111,108,105,100, 76,105,103,104,116, 0, 85,115,101,114, 68,101,102, 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, 84, 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, 83,111,117,110,100, 72, 97,110,100,108,101, 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, 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, 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 83,111,117,110,100, 51, 68, 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, 70,114,101,101, 67, 97,109,101,114, 97, - 0, 83,112, 97, 99,101, 83,111,117,110,100, 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, 77,111,116,105,111,110, 80, 97, -116,104, 0, 98, 65,110,105,109, 86,105,122, 83,101,116,116,105,110,103,115, 0, 98, 80,111,115,101, 67,104, 97,110,110,101,108, - 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, 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, 77,105,110, 77, 97,120, 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, 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, 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, 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, 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, 0, 98, 78,111,100,101, 80,114, -101,118,105,101,119, 0, 98, 78,111,100,101, 84,121,112,101, 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, 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, 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, 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, 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, 97,116, 97, 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, 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, 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, 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,109, 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, 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, 68,114,105,118,101,114, 84, - 97,114,103,101,116, 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, 0, 0, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 0, 12, 0, - 8, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, 12, 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 20, 0, 76, 0, 52, 0, - 40, 2, 0, 0, 32, 0,140, 0,100, 3, 92, 0, 36, 0, 56, 0, 84, 0,112, 0,124, 0, 56, 0, 24, 0, 40, 0,120, 0, 12, 0, -120, 0, 36, 0, 92, 5,128, 1, 0, 0, 0, 0, 0, 0,144, 0, 40, 1, 84, 1, 24, 0, 8, 3,168, 0, 0, 0, 76, 0,128, 1, - 24, 1,140, 0,132, 0,124, 1, 8, 1, 56, 0, 88, 0,184, 2, 76, 0, 60, 1, 0, 0,108, 0,104, 0,148, 0, 56, 0, 8, 0, - 16, 0, 92, 1, 0, 0, 0, 0, 0, 0, 24, 1, 20, 0, 44, 0, 60, 0, 24, 0, 12, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0, - 24, 0, 76, 0, 32, 0, 8, 0, 12, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 12, 0, 0, 0, 16, 0, 64, 0, 24, 0, - 12, 0, 40, 0, 56, 0, 72, 0, 92, 0,100, 0, 72, 0,100, 0,120, 0, 68, 0, 64, 0,112, 0, 64, 0, 76, 0,176, 0, 48, 0, -168, 0,152, 0,156, 0, 64, 0, 96, 0,108, 0,188, 0,104, 0,216, 0, 56, 0, 84, 0, 0, 0,132, 0, 28, 0,240, 1,104, 0, - 0, 0, 80, 0, 0, 0, 0, 0, 68, 0, 8, 0, 8, 0,220, 0, 80, 0, 76, 0, 68, 0, 68, 0, 64, 0,164, 1,112, 0,108, 0, -188, 0, 40, 0, 0, 0, 92, 0, 56, 0, 72, 0,120, 0,128, 0,252, 0,208, 0, 0, 0, 92, 0, 0, 0, 16, 0, 0, 0, 0, 0, - 0, 0,104, 1, 28, 0,176, 0,144, 0, 52, 0, 16, 0, 72, 0, 0, 4, 56, 0, 20, 0, 16, 0, 92, 0, 80, 0, 24, 0,196, 0, - 36, 0, 8, 0,100, 0, 80, 0, 48, 0, 52, 0, 72, 1, 32, 0, 8, 0, 24, 2, 0, 0, 0, 0, 56, 0,216, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,240, 0, 40, 0,148, 0, 48, 0,140, 0,208, 0, 20, 0,224, 0,216, 0,204, 1, 60, 0, 0, 0,112, 0, - 0, 0, 4, 1, 12, 0, 12, 0,136, 0,200, 0,124, 2, 80, 2, 40, 0,180, 0,244, 0, 52, 0,148, 2, 28, 0, 80, 0, 24, 0, - 16, 1, 32, 0,224, 0, 32, 0, 32, 0, 80, 2, 16, 1, 16, 0,200, 21, 56, 0, 56, 11, 20, 0, 24, 0, 56, 1, 0, 0, 0, 0, - 96, 0, 0, 0,248, 0, 0, 0, 32, 0, 80, 0, 28, 0, 16, 0, 8, 0, 52, 0,252, 0,240, 0,168, 1,196, 0, 8, 1, 48, 0, - 16, 0, 12, 0, 24, 0, 48, 0, 16, 0, 20, 0, 16, 0, 24, 0, 56, 1, 0, 0, 56, 0, 52, 0, 48, 0, 8, 0, 44, 0, 72, 0, -104, 0, 40, 0, 8, 0, 72, 0, 44, 0, 40, 0,108, 0, 68, 0, 76, 0, 80, 0, 60, 0,128, 0, 76, 0, 60, 0, 12, 0, 92, 0, - 68, 0, 32, 0, 80, 0, 16, 0, 76, 0,108, 0, 84, 0, 28, 0, 96, 0, 60, 0, 56, 0,108, 0,140, 0, 4, 0, 20, 0, 12, 0, - 8, 0, 40, 0,196, 0, 24, 0, 4, 1,124, 0, 16, 0, 20, 0, 24, 0,172, 1,104, 0,228, 0, 64, 0, 44, 0, 64, 0,116, 0, - 60, 0,104, 0, 52, 0, 44, 0, 44, 0, 68, 0, 44, 0, 64, 0, 44, 0, 20, 0, 52, 0, 96, 0, 12, 0,108, 0, 92, 0, 28, 0, - 28, 0, 28, 0, 52, 0, 20, 0, 60, 0,140, 0, 36, 0,120, 0, 32, 0,208, 0, 0, 0, 0, 0, 16, 0, 40, 0, 28, 0, 12, 0, - 12, 0, 16, 1, 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 8, 0, 24, 0, 32, 0, 8, 0, 32, 0, 12, 0, 44, 0, 20, 0, - 68, 0, 24, 0, 56, 0, 52, 0, 20, 0, 72, 0, 28, 0,180, 0,208, 1, 96, 0, 0, 0, 0, 0, 0, 0, 16, 0, 20, 0, 24, 0, -172, 0, 24, 0, 24, 0,140, 0,148, 0, 56, 0, 0, 0, 0, 0,100, 0, 0, 0, 92, 0, 0, 0, 88, 0, 20, 0, 24, 0, 16, 0, - 20, 0, 8, 0, 8, 0, 24, 0, 20, 0, 88, 0, 24, 1, 16, 0, 68, 0, 0, 1, 20, 0,160, 0, 88, 0, 96, 0, 88, 0, 20, 0, - 56, 0, 48, 0, 68, 0, 56, 0, 92, 0, 64, 0, 56, 0, 96, 0, 0, 0, 0, 0, 83, 84, 82, 67,126, 1, 0, 0, 10, 0, 2, 0, - 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 3, 0, 11, 0, 0, 0, 11, 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0, - 9, 0, 4, 0, 13, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, 14, 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0, - 7, 0, 5, 0, 7, 0, 6, 0, 16, 0, 2, 0, 8, 0, 5, 0, 8, 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0, - 4, 0, 7, 0, 18, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0, - 8, 0, 7, 0, 20, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0, - 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 8, 0, 22, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0, - 23, 0, 4, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 4, 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0, - 7, 0, 11, 0, 7, 0, 12, 0, 25, 0, 4, 0, 9, 0, 13, 0, 12, 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0, - 26, 0, 0, 0, 26, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19, 0, 0, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0, - 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0, - 2, 0, 28, 0, 2, 0, 19, 0, 4, 0, 29, 0, 26, 0, 30, 0, 28, 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0, - 0, 0, 34, 0, 0, 0, 35, 0, 4, 0, 36, 0, 4, 0, 37, 0, 28, 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0, - 2, 0, 41, 0, 2, 0, 42, 0, 2, 0, 43, 0, 4, 0, 44, 0, 31, 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, - 2, 0, 17, 0, 2, 0, 19, 0, 0, 0, 48, 0, 33, 0, 21, 0, 33, 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0, - 24, 0, 51, 0, 24, 0, 52, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0, - 2, 0, 19, 0, 2, 0, 57, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0, - 31, 0, 62, 0, 36, 0, 7, 0, 27, 0, 31, 0, 12, 0, 63, 0, 24, 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0, - 2, 0, 37, 0, 37, 0, 16, 0, 37, 0, 0, 0, 37, 0, 1, 0, 7, 0, 67, 0, 7, 0, 61, 0, 2, 0, 17, 0, 2, 0, 47, 0, - 2, 0, 68, 0, 2, 0, 19, 0, 4, 0, 69, 0, 4, 0, 70, 0, 9, 0, 2, 0, 7, 0, 71, 0, 0, 0, 20, 0, 0, 0, 72, 0, - 7, 0, 73, 0, 7, 0, 74, 0, 38, 0, 13, 0, 27, 0, 31, 0, 39, 0, 75, 0, 37, 0, 76, 0, 0, 0, 77, 0, 4, 0, 78, 0, - 7, 0, 61, 0, 12, 0, 79, 0, 36, 0, 80, 0, 27, 0, 81, 0, 2, 0, 17, 0, 2, 0, 82, 0, 2, 0, 83, 0, 2, 0, 19, 0, - 40, 0, 6, 0, 40, 0, 0, 0, 40, 0, 1, 0, 0, 0, 84, 0, 0, 0, 85, 0, 4, 0, 23, 0, 4, 0, 86, 0, 41, 0, 10, 0, - 41, 0, 0, 0, 41, 0, 1, 0, 4, 0, 87, 0, 4, 0, 88, 0, 4, 0, 89, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, 0, 90, 0, - 0, 0, 91, 0, 0, 0, 92, 0, 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 93, 0, 4, 0, 90, 0, 4, 0, 94, 0, 12, 0, 95, 0, - 40, 0, 96, 0, 40, 0, 97, 0, 4, 0, 98, 0, 4, 0, 99, 0, 12, 0,100, 0, 0, 0,101, 0, 4, 0,102, 0, 4, 0,103, 0, - 9, 0,104, 0, 8, 0,105, 0, 43, 0, 3, 0, 4, 0,106, 0, 4, 0,107, 0, 9, 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0, - 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 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, 2, 0,119, 0, 2, 0,120, 0, - 7, 0,121, 0, 36, 0, 80, 0, 32, 0,122, 0, 45, 0, 13, 0, 4, 0,123, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, - 2, 0,127, 0, 2, 0,128, 0, 2, 0, 19, 0, 2, 0,129, 0, 2, 0,130, 0, 2, 0,131, 0, 2, 0,132, 0, 2, 0,133, 0, - 46, 0,134, 0, 47, 0, 32, 0, 27, 0, 31, 0, 0, 0, 34, 0, 12, 0,135, 0, 48, 0,136, 0, 49, 0,137, 0, 50, 0,138, 0, - 2, 0,129, 0, 2, 0, 19, 0, 2, 0,139, 0, 2, 0, 17, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, 0,140, 0, 2, 0,141, 0, - 2, 0,142, 0, 2, 0,143, 0, 2, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 4, 0,147, 0, 4, 0,148, 0, 43, 0,149, 0, - 30, 0,150, 0, 0, 0,151, 0, 7, 0,152, 0, 4, 0,153, 0, 2, 0,154, 0, 2, 0,155, 0, 2, 0,156, 0, 2, 0,157, 0, - 7, 0,158, 0, 7, 0,159, 0, 51, 0, 33, 0, 2, 0,160, 0, 2, 0,161, 0, 2, 0,162, 0, 2, 0,163, 0, 32, 0,164, 0, - 52, 0,165, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 7, 0,171, 0, 7, 0,172, 0, - 7, 0,173, 0, 2, 0,174, 0, 2, 0,175, 0, 2, 0,176, 0, 2, 0,177, 0, 2, 0,178, 0, 2, 0,179, 0, 0, 0,180, 0, - 0, 0,181, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, 7, 0,185, 0, 7, 0,186, 0, 7, 0, 57, 0, 7, 0,187, 0, - 7, 0,188, 0, 7, 0,189, 0, 7, 0,190, 0, 7, 0,191, 0, 53, 0, 15, 0, 0, 0,192, 0, 9, 0,193, 0, 0, 0,194, 0, - 0, 0,195, 0, 4, 0,196, 0, 4, 0,197, 0, 9, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 7, 0,201, 0, 4, 0,202, 0, - 9, 0,203, 0, 9, 0,204, 0, 4, 0,205, 0, 4, 0, 37, 0, 54, 0, 6, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, - 7, 0,206, 0, 7, 0, 67, 0, 4, 0, 64, 0, 55, 0, 5, 0, 2, 0, 19, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0,207, 0, - 54, 0,201, 0, 56, 0, 17, 0, 32, 0,164, 0, 47, 0,208, 0, 57, 0,209, 0, 7, 0,210, 0, 7, 0,211, 0, 2, 0, 17, 0, - 2, 0,212, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,213, 0, 4, 0,214, 0, 2, 0,215, 0, 2, 0,216, 0, 4, 0,129, 0, - 4, 0,140, 0, 2, 0,217, 0, 2, 0,218, 0, 58, 0, 23, 0, 2, 0, 19, 0, 2, 0,219, 0, 7, 0,220, 0, 7, 0,221, 0, - 2, 0,139, 0, 2, 0,222, 0, 4, 0,223, 0, 4, 0,224, 0, 32, 0,164, 0, 59, 0,225, 0, 2, 0,226, 0, 2, 0,227, 0, - 2, 0,228, 0, 9, 0,229, 0, 7, 0,230, 0, 7, 0,231, 0, 2, 0,232, 0, 2, 0,233, 0, 2, 0,234, 0, 2, 0,235, 0, - 7, 0,236, 0, 7, 0,237, 0, 55, 0,238, 0, 60, 0, 10, 0, 4, 0,239, 0, 4, 0,240, 0, 2, 0,241, 0, 2, 0, 19, 0, - 4, 0, 37, 0, 32, 0,164, 0, 7, 0,242, 0, 4, 0,243, 0, 0, 0,244, 0, 7, 0,245, 0, 52, 0, 61, 0, 27, 0, 31, 0, - 39, 0, 75, 0, 7, 0,246, 0, 7, 0,247, 0, 7, 0,248, 0, 7, 0,249, 0, 7, 0,250, 0, 7, 0,251, 0, 7, 0,252, 0, - 7, 0,253, 0, 7, 0,254, 0, 7, 0,255, 0, 7, 0, 0, 1, 7, 0, 1, 1, 7, 0, 2, 1, 7, 0, 3, 1, 7, 0, 4, 1, - 7, 0, 5, 1, 7, 0, 6, 1, 7, 0, 7, 1, 7, 0, 8, 1, 7, 0, 9, 1, 2, 0, 10, 1, 2, 0, 11, 1, 2, 0, 12, 1, - 2, 0, 13, 1, 2, 0, 14, 1, 2, 0, 15, 1, 2, 0, 16, 1, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,212, 0, 7, 0, 17, 1, - 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1, 4, 0, 21, 1, 4, 0, 22, 1, 2, 0, 23, 1, 2, 0, 24, 1, 2, 0, 25, 1, - 2, 0,127, 0, 4, 0, 23, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 7, 0, 26, 1, 7, 0, 27, 1, 7, 0,188, 0, - 45, 0, 28, 1, 61, 0, 29, 1, 36, 0, 80, 0, 47, 0,208, 0, 53, 0, 30, 1, 55, 0,238, 0, 56, 0, 31, 1, 30, 0,150, 0, - 58, 0, 32, 1, 60, 0, 33, 1, 0, 0, 34, 1, 0, 0,181, 0, 62, 0, 8, 0, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0,172, 0, - 4, 0, 19, 0, 7, 0, 37, 1, 7, 0, 38, 1, 7, 0, 39, 1, 32, 0, 45, 0, 63, 0, 82, 0, 27, 0, 31, 0, 39, 0, 75, 0, - 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 40, 1, 2, 0,175, 0, 2, 0, 41, 1, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, - 7, 0,185, 0, 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, 7, 0, 52, 1, 64, 0, 53, 1, 2, 0,219, 0, 2, 0, 70, 0, 7, 0,110, 0, - 7, 0,111, 0, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, 2, 0, 57, 1, 2, 0, 58, 1, 2, 0, 59, 1, 2, 0, 60, 1, - 0, 0, 61, 1, 0, 0, 62, 1, 2, 0, 63, 1, 2, 0, 64, 1, 2, 0, 65, 1, 2, 0, 66, 1, 2, 0, 67, 1, 7, 0, 68, 1, - 7, 0, 69, 1, 7, 0, 70, 1, 7, 0, 71, 1, 2, 0, 72, 1, 2, 0, 43, 0, 2, 0, 73, 1, 2, 0, 74, 1, 2, 0, 75, 1, - 2, 0, 76, 1, 7, 0, 77, 1, 7, 0, 78, 1, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1, - 7, 0, 84, 1, 7, 0, 85, 1, 7, 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 2, 0, 89, 1, 2, 0, 90, 1, 4, 0, 91, 1, - 4, 0, 92, 1, 2, 0, 93, 1, 2, 0, 94, 1, 2, 0, 95, 1, 2, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, - 7, 0,100, 1, 2, 0,101, 1, 2, 0,102, 1, 36, 0, 80, 0, 51, 0,103, 1, 2, 0,104, 1, 2, 0,105, 1, 30, 0,150, 0, - 65, 0, 2, 0, 27, 0, 31, 0, 36, 0, 80, 0, 66, 0, 20, 0, 7, 0,106, 1, 7, 0,107, 1, 7, 0,108, 1, 7, 0,109, 1, - 7, 0,110, 1, 7, 0,111, 1, 7, 0,112, 1, 7, 0,113, 1, 2, 0,114, 1, 2, 0,115, 1, 7, 0,116, 1, 7, 0,117, 1, - 7, 0,118, 1, 2, 0,119, 1, 2, 0,120, 1, 2, 0,121, 1, 2, 0,122, 1, 7, 0,123, 1, 7, 0,124, 1, 4, 0,125, 1, - 67, 0,130, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,126, 1, 2, 0, 19, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, - 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, 7, 0,138, 1, 7, 0,139, 1, 7, 0,140, 1, 7, 0,141, 1, 7, 0,142, 1, - 7, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 7, 0,146, 1, 66, 0,147, 1, 7, 0,148, 1, 7, 0,149, 1, 7, 0,150, 1, - 7, 0,151, 1, 7, 0,152, 1, 7, 0,153, 1, 7, 0,154, 1, 2, 0,155, 1, 2, 0,156, 1, 2, 0,157, 1, 0, 0,158, 1, - 0, 0,159, 1, 7, 0,160, 1, 7, 0,161, 1, 2, 0,162, 1, 2, 0,163, 1, 7, 0,164, 1, 7, 0,165, 1, 7, 0,166, 1, - 7, 0,167, 1, 2, 0,168, 1, 2, 0,169, 1, 4, 0, 40, 1, 4, 0,170, 1, 2, 0,171, 1, 2, 0,172, 1, 2, 0,173, 1, - 2, 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, 7, 0,184, 1, 0, 0,185, 1, 7, 0,186, 1, 7, 0,187, 1, 7, 0,188, 1, 4, 0,189, 1, - 0, 0,190, 1, 0, 0, 73, 1, 0, 0,191, 1, 0, 0, 34, 1, 2, 0,192, 1, 2, 0,193, 1, 2, 0,104, 1, 2, 0,194, 1, - 2, 0,195, 1, 2, 0,196, 1, 7, 0,197, 1, 7, 0,198, 1, 7, 0,199, 1, 7, 0,200, 1, 7, 0,201, 1, 2, 0,160, 0, - 2, 0,161, 0, 55, 0,202, 1, 55, 0,203, 1, 0, 0,204, 1, 0, 0,205, 1, 0, 0,206, 1, 0, 0,207, 1, 2, 0,208, 1, - 2, 0,209, 1, 7, 0,210, 1, 7, 0,211, 1, 51, 0,103, 1, 61, 0, 29, 1, 36, 0, 80, 0, 68, 0,212, 1, 30, 0,150, 0, - 7, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 7, 0,217, 1, 2, 0,218, 1, 2, 0, 70, 0, 7, 0,219, 1, - 7, 0,220, 1, 7, 0,221, 1, 7, 0,222, 1, 7, 0,223, 1, 7, 0,224, 1, 7, 0,225, 1, 7, 0,226, 1, 7, 0,227, 1, - 2, 0,228, 1, 2, 0,229, 1, 7, 0,230, 1, 7, 0,231, 1, 7, 0,232, 1, 7, 0,233, 1, 7, 0,234, 1, 4, 0,235, 1, - 4, 0,236, 1, 4, 0,237, 1, 12, 0,238, 1, 69, 0, 4, 0, 27, 0, 31, 0, 0, 0,239, 1, 70, 0, 2, 0, 43, 0,149, 0, - 71, 0, 26, 0, 71, 0, 0, 0, 71, 0, 1, 0, 72, 0,240, 1, 4, 0,241, 1, 4, 0,242, 1, 4, 0,243, 1, 4, 0,244, 1, - 4, 0,245, 1, 4, 0,246, 1, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,247, 1, 2, 0,248, 1, 7, 0, 5, 0, 7, 0, 6, 0, - 7, 0, 7, 0, 7, 0,249, 1, 7, 0,250, 1, 7, 0,251, 1, 7, 0,252, 1, 7, 0,253, 1, 7, 0,254, 1, 7, 0,255, 1, - 7, 0, 23, 0, 7, 0, 0, 2, 7, 0, 1, 2, 73, 0, 19, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0,240, 1, 12, 0, 2, 2, - 12, 0, 3, 2, 12, 0, 4, 2, 36, 0, 80, 0, 67, 0, 5, 2, 0, 0, 19, 0, 0, 0, 6, 2, 2, 0, 7, 2, 4, 0,174, 0, - 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 71, 0, 11, 2, 35, 0, 11, 0, - 7, 0, 12, 2, 7, 0, 13, 2, 7, 0, 14, 2, 7, 0,221, 0, 2, 0, 55, 0, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 17, 2, - 0, 0, 18, 2, 0, 0, 19, 2, 0, 0, 20, 2, 34, 0, 7, 0, 7, 0, 21, 2, 7, 0, 13, 2, 7, 0, 14, 2, 2, 0, 17, 2, - 2, 0, 20, 2, 7, 0,221, 0, 7, 0, 37, 0, 74, 0, 21, 0, 74, 0, 0, 0, 74, 0, 1, 0, 2, 0, 17, 0, 2, 0, 22, 2, - 2, 0, 20, 2, 2, 0, 19, 0, 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 27, 2, 2, 0, 28, 2, - 2, 0, 29, 2, 2, 0, 30, 2, 7, 0, 31, 2, 7, 0, 32, 2, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0, 33, 2, 2, 0, 34, 2, - 4, 0, 35, 2, 75, 0, 5, 0, 2, 0, 36, 2, 2, 0, 22, 2, 0, 0, 19, 0, 0, 0, 37, 0, 2, 0, 70, 0, 76, 0, 4, 0, - 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 8, 0, 7, 0, 37, 2, 77, 0, 67, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0,240, 1, - 12, 0, 38, 2, 12, 0, 3, 2, 12, 0, 39, 2, 32, 0, 40, 2, 32, 0, 41, 2, 32, 0, 42, 2, 36, 0, 80, 0, 78, 0, 43, 2, - 38, 0, 44, 2, 67, 0, 5, 2, 12, 0, 45, 2, 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 4, 0,174, 0, 2, 0, 46, 2, - 2, 0, 47, 2, 2, 0, 48, 2, 7, 0, 49, 2, 7, 0, 70, 0, 2, 0, 50, 2, 2, 0, 7, 2, 2, 0, 19, 0, 2, 0, 51, 2, - 7, 0, 52, 2, 7, 0, 53, 2, 7, 0, 54, 2, 2, 0, 25, 2, 2, 0, 26, 2, 2, 0, 55, 2, 2, 0, 56, 2, 4, 0, 57, 2, - 34, 0, 58, 2, 2, 0, 23, 0, 2, 0, 95, 0, 2, 0, 67, 0, 2, 0, 59, 2, 7, 0, 60, 2, 7, 0, 61, 2, 7, 0, 62, 2, - 7, 0, 63, 2, 7, 0, 64, 2, 7, 0, 65, 2, 7, 0, 66, 2, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 69, 2, 0, 0, 70, 2, - 79, 0, 71, 2, 80, 0, 72, 2, 0, 0, 73, 2, 69, 0, 74, 2, 69, 0, 75, 2, 69, 0, 76, 2, 69, 0, 77, 2, 4, 0, 78, 2, - 7, 0, 79, 2, 4, 0, 80, 2, 4, 0, 81, 2, 76, 0, 82, 2, 4, 0, 83, 2, 4, 0, 84, 2, 75, 0, 85, 2, 75, 0, 86, 2, - 81, 0, 39, 0, 27, 0, 31, 0, 72, 0,240, 1, 12, 0, 87, 2, 36, 0, 80, 0, 38, 0, 44, 2, 67, 0, 5, 2, 82, 0, 88, 2, - 83, 0, 89, 2, 84, 0, 90, 2, 85, 0, 91, 2, 86, 0, 92, 2, 87, 0, 93, 2, 88, 0, 94, 2, 89, 0, 95, 2, 81, 0, 96, 2, - 90, 0, 97, 2, 91, 0, 98, 2, 92, 0, 99, 2, 92, 0,100, 2, 92, 0,101, 2, 4, 0, 54, 0, 4, 0,102, 2, 4, 0,103, 2, - 4, 0,104, 2, 4, 0,105, 2, 4, 0,174, 0, 7, 0, 35, 1, 7, 0,172, 0, 7, 0, 36, 1, 7, 0,106, 2, 4, 0, 46, 2, - 2, 0,107, 2, 2, 0, 19, 0, 2, 0,108, 2, 2, 0,109, 2, 2, 0, 7, 2, 2, 0,110, 2, 93, 0,111, 2, 94, 0,112, 2, - 84, 0, 8, 0, 9, 0,113, 2, 7, 0,114, 2, 4, 0,115, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, - 2, 0,118, 2, 82, 0, 7, 0, 4, 0,119, 2, 4, 0,120, 2, 4, 0,121, 2, 4, 0,122, 2, 2, 0, 22, 2, 0, 0,123, 2, - 0, 0, 19, 0, 86, 0, 5, 0, 4, 0,119, 2, 4, 0,120, 2, 0, 0,124, 2, 0, 0,125, 2, 2, 0, 19, 0, 95, 0, 2, 0, - 4, 0,126, 2, 7, 0, 14, 2, 87, 0, 3, 0, 95, 0,127, 2, 4, 0,128, 2, 4, 0, 19, 0, 85, 0, 6, 0, 7, 0,129, 2, - 2, 0,130, 2, 2, 0, 22, 2, 0, 0, 19, 0, 0, 0,125, 2, 0, 0, 48, 2, 88, 0, 4, 0, 0, 0,206, 0, 0, 0,182, 0, - 0, 0,183, 0, 0, 0,184, 0, 96, 0, 6, 0, 47, 0,113, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, - 2, 0,118, 2, 97, 0, 1, 0, 7, 0,131, 2, 98, 0, 5, 0, 0, 0,206, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0,184, 0, - 4, 0, 37, 0, 89, 0, 1, 0, 7, 0,132, 2, 90, 0, 2, 0, 4, 0,133, 2, 4, 0, 17, 0, 83, 0, 7, 0, 7, 0,114, 2, - 47, 0,113, 2, 0, 0, 19, 0, 0, 0,116, 2, 2, 0, 40, 1, 2, 0,117, 2, 2, 0,118, 2, 99, 0, 1, 0, 7, 0,134, 2, -100, 0, 1, 0, 4, 0,135, 2,101, 0, 1, 0, 0, 0,136, 2,102, 0, 1, 0, 7, 0,114, 2,103, 0, 3, 0, 4, 0,137, 2, - 0, 0, 92, 0, 7, 0,138, 2,105, 0, 4, 0, 7, 0,206, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0,106, 0, 1, 0, -105, 0,115, 2,107, 0, 5, 0, 4, 0,139, 2, 4, 0,140, 2, 0, 0, 19, 0, 0, 0, 22, 2, 0, 0, 48, 2,108, 0, 2, 0, - 4, 0,141, 2, 4, 0,140, 2,109, 0, 10, 0,109, 0, 0, 0,109, 0, 1, 0,107, 0,142, 2,106, 0,143, 2,108, 0,144, 2, - 4, 0, 54, 0, 4, 0,103, 2, 4, 0,102, 2, 4, 0, 37, 0, 85, 0,145, 2, 93, 0, 14, 0, 12, 0,146, 2, 85, 0,145, 2, - 0, 0,147, 2, 0, 0,148, 2, 0, 0,149, 2, 0, 0,150, 2, 0, 0,151, 2, 0, 0,152, 2, 0, 0,153, 2, 0, 0, 19, 0, - 92, 0, 99, 2, 92, 0,101, 2, 2, 0,154, 2, 0, 0,155, 2, 94, 0, 8, 0, 4, 0,156, 2, 4, 0,157, 2, 82, 0,158, 2, - 86, 0,159, 2, 4, 0,103, 2, 4, 0,102, 2, 4, 0, 54, 0, 4, 0, 37, 0,110, 0, 7, 0,110, 0, 0, 0,110, 0, 1, 0, - 4, 0, 17, 0, 4, 0, 40, 1, 0, 0, 20, 0, 46, 0,134, 0, 0, 0,160, 2,111, 0, 7, 0,110, 0,161, 2, 2, 0,162, 2, - 2, 0,146, 2, 2, 0,163, 2, 2, 0, 90, 0, 9, 0,164, 2, 9, 0,165, 2,112, 0, 3, 0,110, 0,161, 2, 32, 0,164, 0, - 0, 0, 20, 0,113, 0, 5, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0, 20, 0, 2, 0,166, 2, 0, 0,167, 2,114, 0, 5, 0, -110, 0,161, 2, 7, 0, 88, 0, 7, 0,168, 2, 4, 0,169, 2, 4, 0,170, 2,115, 0, 5, 0,110, 0,161, 2, 32, 0,171, 2, - 0, 0, 72, 0, 4, 0, 40, 1, 4, 0, 19, 0,116, 0, 13, 0,110, 0,161, 2, 32, 0,172, 2, 32, 0,173, 2, 32, 0,174, 2, - 32, 0,175, 2, 7, 0,176, 2, 7, 0,177, 2, 7, 0,168, 2, 7, 0,178, 2, 4, 0,179, 2, 4, 0,180, 2, 4, 0, 90, 0, - 4, 0,181, 2,117, 0, 5, 0,110, 0,161, 2, 2, 0,182, 2, 2, 0, 19, 0, 7, 0,183, 2, 32, 0,184, 2,118, 0, 3, 0, -110, 0,161, 2, 7, 0,185, 2, 4, 0, 90, 0,119, 0, 10, 0,110, 0,161, 2, 7, 0,186, 2, 4, 0,187, 2, 4, 0, 37, 0, - 2, 0, 90, 0, 2, 0,188, 2, 2, 0,189, 2, 2, 0,190, 2, 7, 0,191, 2, 0, 0,192, 2,120, 0, 3, 0,110, 0,161, 2, - 7, 0, 37, 0, 4, 0, 17, 0,121, 0, 6, 0,110, 0,161, 2,122, 0,193, 2,123, 0,194, 2,124, 0,195, 2, 7, 0,196, 2, - 4, 0, 17, 0,125, 0, 11, 0,110, 0,161, 2, 52, 0,197, 2, 7, 0,198, 2, 4, 0,199, 2, 0, 0,192, 2, 7, 0,200, 2, - 4, 0,201, 2, 32, 0,202, 2, 0, 0,203, 2, 4, 0,204, 2, 4, 0, 37, 0,126, 0, 10, 0,110, 0,161, 2, 32, 0,205, 2, - 47, 0,206, 2, 4, 0, 90, 0, 4, 0,207, 2, 7, 0,208, 2, 7, 0,209, 2, 0, 0,203, 2, 4, 0,204, 2, 4, 0, 37, 0, -127, 0, 3, 0,110, 0,161, 2, 7, 0,210, 2, 4, 0,211, 2,128, 0, 5, 0,110, 0,161, 2, 7, 0,212, 2, 0, 0,192, 2, - 2, 0, 19, 0, 2, 0,213, 2,129, 0, 8, 0,110, 0,161, 2, 32, 0,164, 0, 7, 0,212, 2, 7, 0,221, 0, 7, 0,106, 0, - 0, 0,192, 2, 2, 0, 19, 0, 2, 0, 17, 0,130, 0, 21, 0,110, 0,161, 2, 32, 0,214, 2, 0, 0,192, 2, 52, 0,197, 2, - 32, 0,202, 2, 2, 0, 19, 0, 2, 0, 37, 0, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 7, 0, 52, 2, 7, 0,218, 2, - 7, 0,219, 2, 7, 0,220, 2, 7, 0,221, 2, 4, 0,201, 2, 4, 0,204, 2, 0, 0,203, 2, 7, 0,222, 2, 7, 0,223, 2, - 7, 0, 43, 0,131, 0, 7, 0,110, 0,161, 2, 2, 0,224, 2, 2, 0,225, 2, 4, 0, 70, 0, 32, 0,164, 0, 7, 0,226, 2, - 0, 0,192, 2,132, 0, 10, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0,227, 2, 7, 0,228, 2, 7, 0,229, 2, 7, 0,221, 2, - 4, 0,230, 2, 4, 0,231, 2, 7, 0,232, 2, 0, 0, 20, 0,133, 0, 1, 0,110, 0,161, 2,134, 0, 7, 0,110, 0,161, 2, - 46, 0,134, 0,135, 0,233, 2,136, 0,234, 2,137, 0,235, 2,138, 0,236, 2, 12, 0,237, 2,139, 0, 14, 0,110, 0,161, 2, - 85, 0,238, 2, 85, 0,239, 2, 85, 0,240, 2, 85, 0,241, 2, 85, 0,242, 2, 85, 0,243, 2, 82, 0,244, 2, 4, 0,245, 2, - 4, 0,246, 2, 2, 0,108, 1, 2, 0, 37, 0, 7, 0,196, 2,140, 0,247, 2,141, 0, 7, 0,110, 0,161, 2, 85, 0,238, 2, - 85, 0,248, 2,142, 0,249, 2,143, 0,247, 2, 4, 0,250, 2, 4, 0,245, 2,144, 0, 4, 0,110, 0,161, 2, 32, 0,164, 0, - 4, 0,251, 2, 4, 0, 37, 0,145, 0, 2, 0, 4, 0,252, 2, 7, 0, 14, 2,146, 0, 2, 0, 4, 0,125, 0, 4, 0,253, 2, -147, 0, 20, 0,110, 0,161, 2, 32, 0,164, 0, 0, 0,192, 2, 2, 0,254, 2, 2, 0,255, 2, 2, 0, 19, 0, 2, 0, 37, 0, - 7, 0, 0, 3, 7, 0, 1, 3, 4, 0, 54, 0, 4, 0, 2, 3,146, 0, 3, 3,145, 0, 4, 3, 4, 0, 5, 3, 4, 0, 6, 3, - 4, 0, 7, 3, 4, 0,253, 2, 7, 0, 8, 3, 7, 0, 9, 3, 7, 0, 10, 3,148, 0, 8, 0,110, 0,161, 2, 59, 0,225, 0, -142, 0,249, 2, 4, 0, 11, 3, 4, 0, 12, 3, 4, 0, 13, 3, 2, 0, 19, 0, 2, 0, 57, 0,149, 0, 8, 0,110, 0,161, 2, - 32, 0, 45, 0, 2, 0, 14, 3, 2, 0, 19, 0, 2, 0,182, 2, 2, 0, 57, 0, 7, 0, 15, 3, 7, 0, 16, 3,150, 0, 5, 0, -110, 0,161, 2, 4, 0, 17, 3, 2, 0, 19, 0, 2, 0, 18, 3, 7, 0, 19, 3,151, 0, 7, 0,110, 0,161, 2, 85, 0, 20, 3, - 4, 0, 21, 3, 0, 0, 22, 3, 0, 0, 23, 3, 0, 0, 24, 3, 0, 0, 25, 3,152, 0, 3, 0,110, 0,161, 2,153, 0, 26, 3, -138, 0,236, 2,154, 0, 10, 0,110, 0,161, 2, 32, 0, 27, 3, 32, 0, 28, 3, 0, 0, 29, 3, 7, 0, 30, 3, 2, 0, 31, 3, - 2, 0, 32, 3, 0, 0, 33, 3, 0, 0, 34, 3, 0, 0,167, 2,155, 0, 9, 0,110, 0,161, 2, 32, 0, 35, 3, 0, 0, 29, 3, - 7, 0, 36, 3, 7, 0, 37, 3, 0, 0, 40, 1, 0, 0,182, 2, 0, 0, 38, 3, 0, 0, 37, 0,156, 0, 27, 0, 27, 0, 31, 0, - 2, 0, 23, 2, 2, 0, 24, 2, 2, 0, 39, 3, 2, 0, 19, 0, 2, 0, 40, 3, 2, 0, 41, 3, 2, 0, 42, 3, 2, 0, 70, 0, - 0, 0, 43, 3, 0, 0, 44, 3, 0, 0, 45, 3, 0, 0, 17, 0, 4, 0, 37, 0, 7, 0, 46, 3, 7, 0, 47, 3, 7, 0, 48, 3, - 7, 0, 49, 3, 7, 0, 50, 3, 7, 0, 51, 3, 34, 0, 52, 3, 36, 0, 80, 0, 38, 0, 44, 2, 87, 0, 93, 2, 7, 0, 53, 3, - 7, 0, 54, 3,156, 0, 55, 3,157, 0, 3, 0,157, 0, 0, 0,157, 0, 1, 0, 0, 0, 20, 0, 72, 0, 3, 0, 7, 0, 56, 3, - 4, 0, 19, 0, 4, 0, 37, 0, 32, 0,116, 0, 27, 0, 31, 0, 39, 0, 75, 0,158, 0, 57, 3, 2, 0, 17, 0, 2, 0, 58, 3, - 4, 0, 59, 3, 4, 0, 60, 3, 4, 0, 61, 3, 0, 0, 62, 3, 32, 0, 38, 0, 32, 0, 63, 3, 32, 0, 64, 3, 32, 0, 65, 3, - 32, 0, 66, 3, 36, 0, 80, 0, 78, 0, 43, 2, 72, 0,240, 1,159, 0, 67, 3,159, 0, 68, 3,160, 0, 69, 3, 9, 0, 2, 0, -161, 0, 70, 3, 12, 0, 71, 3, 12, 0, 87, 2, 12, 0, 3, 2, 12, 0, 72, 3, 12, 0, 73, 3, 4, 0, 40, 1, 4, 0, 74, 3, - 67, 0, 5, 2, 0, 0, 75, 3, 4, 0, 7, 2, 4, 0, 76, 3, 7, 0, 35, 1, 7, 0, 77, 3, 7, 0, 78, 3, 7, 0,172, 0, - 7, 0, 79, 3, 7, 0, 36, 1, 7, 0, 80, 3, 7, 0, 81, 3, 7, 0,228, 2, 7, 0, 82, 3, 7, 0,210, 0, 4, 0, 83, 3, - 2, 0, 19, 0, 2, 0, 84, 3, 2, 0, 85, 3, 2, 0, 86, 3, 2, 0, 87, 3, 2, 0, 88, 3, 2, 0, 89, 3, 2, 0, 90, 3, - 2, 0, 91, 3, 2, 0, 92, 3, 2, 0, 93, 3, 2, 0, 94, 3, 4, 0, 95, 3, 4, 0, 96, 3, 4, 0, 97, 3, 4, 0, 98, 3, - 7, 0, 99, 3, 7, 0, 79, 2, 7, 0,100, 3, 7, 0,101, 3, 7, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 7, 0,105, 3, - 7, 0,106, 3, 7, 0,107, 3, 7, 0,108, 3, 7, 0,109, 3, 0, 0,110, 3, 0, 0,111, 3, 0, 0,112, 3, 0, 0,113, 3, - 7, 0,114, 3, 7, 0,115, 3, 12, 0,116, 3, 12, 0,117, 3, 12, 0,118, 3, 12, 0,119, 3, 7, 0,120, 3, 2, 0,133, 2, - 2, 0,121, 3, 7, 0,115, 2, 4, 0,122, 3, 4, 0,123, 3,162, 0,124, 3, 2, 0,125, 3, 2, 0,217, 0, 7, 0,126, 3, - 12, 0,127, 3, 12, 0,128, 3, 12, 0,129, 3, 12, 0,130, 3,163, 0, 32, 1,164, 0,131, 3, 68, 0,132, 3, 2, 0,133, 3, - 2, 0,134, 3, 2, 0,135, 3, 2, 0,136, 3, 7, 0,107, 2, 2, 0,137, 3, 2, 0,138, 3,153, 0,139, 3,142, 0,140, 3, -142, 0,141, 3, 4, 0,142, 3, 4, 0,143, 3, 4, 0,144, 3, 4, 0, 70, 0, 12, 0,145, 3, 12, 0,146, 3,165, 0, 14, 0, -165, 0, 0, 0,165, 0, 1, 0, 32, 0, 38, 0, 7, 0,228, 2, 7, 0, 37, 1, 7, 0,229, 2, 7, 0,221, 2, 0, 0, 20, 0, - 4, 0,230, 2, 4, 0,231, 2, 4, 0,147, 3, 2, 0, 17, 0, 2, 0,148, 3, 7, 0,232, 2,163, 0, 36, 0, 2, 0,149, 3, - 2, 0,150, 3, 2, 0, 19, 0, 2, 0,221, 2, 7, 0,151, 3, 7, 0,152, 3, 7, 0,153, 3, 7, 0,154, 3, 7, 0,155, 3, - 7, 0,156, 3, 7, 0,157, 3, 7, 0,158, 3, 7, 0,159, 3, 7, 0,160, 3, 7, 0,161, 3, 7, 0,162, 3, 7, 0,163, 3, - 7, 0,164, 3, 7, 0,165, 3, 7, 0,166, 3, 7, 0,167, 3, 7, 0,168, 3, 7, 0,169, 3, 7, 0,170, 3, 7, 0,171, 3, - 7, 0,172, 3, 7, 0,173, 3, 7, 0,174, 3, 2, 0,175, 3, 2, 0,176, 3, 2, 0,177, 3, 2, 0,178, 3, 52, 0,165, 0, -166, 0,179, 3, 7, 0,180, 3, 4, 0,170, 2,167, 0, 9, 0,167, 0, 0, 0,167, 0, 1, 0, 4, 0,181, 3, 4, 0,182, 3, - 4, 0,183, 3, 4, 0, 19, 0, 4, 0,184, 3, 9, 0,185, 3, 9, 0,186, 3,138, 0, 19, 0,138, 0, 0, 0,138, 0, 1, 0, - 4, 0, 19, 0, 4, 0,187, 3, 4, 0,188, 3, 4, 0,189, 3, 4, 0,190, 3, 4, 0,191, 3, 4, 0,192, 3, 4, 0,182, 3, - 4, 0,133, 2, 4, 0, 57, 0, 0, 0,193, 3, 0, 0,194, 3, 0, 0,195, 3, 0, 0,196, 3, 12, 0,197, 3,168, 0,198, 3, - 9, 0,199, 3,169, 0, 1, 0, 7, 0, 21, 2,162, 0, 30, 0, 4, 0, 19, 0, 7, 0,200, 3, 7, 0,201, 3, 7, 0,202, 3, - 4, 0,203, 3, 4, 0,204, 3, 4, 0,205, 3, 4, 0,206, 3, 7, 0,207, 3, 7, 0,208, 3, 7, 0,209, 3, 7, 0,210, 3, - 7, 0,211, 3, 7, 0,212, 3, 7, 0,213, 3, 7, 0,214, 3, 7, 0,215, 3, 7, 0,216, 3, 7, 0,217, 3, 7, 0,218, 3, - 7, 0,219, 3, 7, 0,220, 3, 7, 0,221, 3, 7, 0,222, 3, 7, 0,223, 3, 7, 0,224, 3, 4, 0,225, 3, 4, 0,226, 3, - 7, 0,227, 3, 7, 0,106, 3,164, 0, 49, 0, 4, 0,182, 3, 4, 0,228, 3,170, 0,229, 3,171, 0,230, 3, 0, 0, 37, 0, - 0, 0,231, 3, 2, 0,232, 3, 7, 0,233, 3, 0, 0,234, 3, 7, 0,235, 3, 7, 0,236, 3, 7, 0,237, 3, 7, 0,238, 3, - 7, 0,239, 3, 7, 0,240, 3, 7, 0,241, 3, 7, 0,242, 3, 7, 0,243, 3, 2, 0,244, 3, 0, 0,245, 3, 2, 0,246, 3, - 7, 0,247, 3, 7, 0,248, 3, 0, 0,249, 3, 4, 0,126, 0, 4, 0,250, 3, 4, 0,251, 3, 2, 0,252, 3, 2, 0,253, 3, -169, 0,254, 3, 4, 0,255, 3, 4, 0, 82, 0, 7, 0, 0, 4, 7, 0, 1, 4, 7, 0, 2, 4, 7, 0, 3, 4, 2, 0, 4, 4, - 2, 0, 5, 4, 2, 0, 6, 4, 2, 0, 7, 4, 2, 0, 8, 4, 2, 0, 9, 4, 2, 0, 10, 4, 2, 0, 11, 4,172, 0, 12, 4, - 7, 0, 13, 4, 7, 0, 14, 4,138, 0, 15, 4, 12, 0,237, 2,153, 0, 48, 0, 2, 0, 17, 0, 2, 0, 16, 4, 2, 0, 17, 4, - 2, 0, 18, 4, 7, 0, 19, 4, 2, 0, 20, 4, 2, 0, 21, 4, 7, 0, 22, 4, 2, 0, 23, 4, 2, 0, 24, 4, 7, 0, 25, 4, - 7, 0, 26, 4, 7, 0, 27, 4, 7, 0, 28, 4, 7, 0, 29, 4, 7, 0, 30, 4, 4, 0, 31, 4, 7, 0, 32, 4, 7, 0, 33, 4, - 7, 0, 34, 4, 81, 0, 35, 4, 81, 0, 36, 4, 81, 0, 37, 4, 0, 0, 38, 4, 7, 0, 39, 4, 7, 0, 40, 4, 36, 0, 80, 0, - 2, 0, 41, 4, 0, 0, 42, 4, 0, 0, 43, 4, 7, 0, 44, 4, 4, 0, 45, 4, 7, 0, 46, 4, 7, 0, 47, 4, 4, 0, 48, 4, - 4, 0, 19, 0, 7, 0, 49, 4, 7, 0, 50, 4, 7, 0, 51, 4, 85, 0, 52, 4, 7, 0, 53, 4, 7, 0, 54, 4, 7, 0, 55, 4, - 7, 0, 56, 4, 7, 0, 57, 4, 7, 0, 58, 4, 7, 0, 59, 4, 4, 0, 60, 4,173, 0, 73, 0, 27, 0, 31, 0, 39, 0, 75, 0, - 2, 0,175, 0, 2, 0, 41, 1, 2, 0, 73, 1, 2, 0, 61, 4, 7, 0, 62, 4, 7, 0, 63, 4, 7, 0, 64, 4, 7, 0, 65, 4, - 7, 0, 66, 4, 7, 0, 67, 4, 7, 0, 68, 4, 7, 0, 69, 4, 7, 0,133, 1, 7, 0,135, 1, 7, 0,134, 1, 7, 0, 70, 4, - 4, 0, 71, 4, 7, 0, 72, 4, 7, 0, 73, 4, 7, 0, 74, 4, 7, 0, 75, 4, 7, 0, 76, 4, 7, 0, 77, 4, 7, 0, 78, 4, - 2, 0, 79, 4, 2, 0, 40, 1, 2, 0, 80, 4, 2, 0, 81, 4, 2, 0, 82, 4, 2, 0, 83, 4, 2, 0, 84, 4, 2, 0, 85, 4, - 7, 0, 86, 4, 7, 0, 87, 4, 7, 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, 2, 0, 98, 4, 2, 0, 99, 4, 2, 0,100, 4, 2, 0,101, 4, - 7, 0,102, 4, 7, 0,103, 4, 7, 0,104, 4, 7, 0,105, 4, 2, 0,106, 4, 2, 0,107, 4, 2, 0,108, 4, 2, 0,109, 4, - 7, 0,110, 4, 7, 0,111, 4, 7, 0,112, 4, 7, 0,113, 4, 2, 0,114, 4, 2, 0,115, 4, 2, 0,116, 4, 2, 0, 19, 0, - 7, 0,117, 4, 7, 0,118, 4, 36, 0, 80, 0, 51, 0,103, 1, 2, 0,104, 1, 2, 0,105, 1, 30, 0,150, 0,174, 0, 8, 0, -174, 0, 0, 0,174, 0, 1, 0, 4, 0, 83, 3, 4, 0,119, 4, 4, 0, 19, 0, 2, 0,120, 4, 2, 0,121, 4, 32, 0,164, 0, -175, 0, 13, 0, 9, 0,122, 4, 9, 0,123, 4, 4, 0,124, 4, 4, 0,125, 4, 4, 0,126, 4, 4, 0,127, 4, 4, 0,128, 4, - 4, 0,129, 4, 4, 0,130, 4, 4, 0,131, 4, 4, 0,132, 4, 4, 0, 37, 0, 0, 0,133, 4,176, 0, 5, 0, 9, 0,134, 4, - 9, 0,135, 4, 4, 0,136, 4, 4, 0, 70, 0, 0, 0,137, 4,177, 0, 13, 0, 4, 0, 17, 0, 4, 0,138, 4, 4, 0,139, 4, - 4, 0,140, 4, 4, 0,141, 4, 4, 0,142, 4, 4, 0, 90, 0, 4, 0,143, 4, 4, 0,144, 4, 4, 0,145, 4, 4, 0,146, 4, - 4, 0,147, 4, 26, 0, 30, 0,178, 0, 4, 0, 4, 0,148, 4, 7, 0,149, 4, 2, 0, 19, 0, 2, 0,105, 1,179, 0, 11, 0, -179, 0, 0, 0,179, 0, 1, 0, 0, 0, 20, 0, 67, 0,150, 4, 68, 0,151, 4, 4, 0, 83, 3, 4, 0,152, 4, 4, 0,153, 4, - 4, 0, 37, 0, 4, 0,154, 4, 4, 0,155, 4,180, 0,132, 0,175, 0,156, 4,176, 0,157, 4,177, 0,158, 4,178, 0,159, 4, - 4, 0,250, 2, 4, 0,126, 0, 4, 0,250, 3, 4, 0,160, 4, 4, 0,161, 4, 4, 0,162, 4, 4, 0,163, 4, 2, 0, 19, 0, - 2, 0,164, 4, 7, 0, 79, 2, 7, 0,165, 4, 7, 0,166, 4, 7, 0,167, 4, 7, 0,168, 4, 7, 0,169, 4, 2, 0,170, 4, - 2, 0,171, 4, 2, 0,172, 4, 2, 0,173, 4, 2, 0,216, 0, 2, 0,174, 4, 2, 0,175, 4, 2, 0,178, 3, 2, 0,176, 4, - 2, 0,177, 4, 2, 0, 60, 1, 2, 0,106, 0, 2, 0,178, 4, 2, 0,179, 4, 2, 0,180, 4, 2, 0,181, 4, 2, 0,182, 4, - 2, 0,183, 4, 2, 0,184, 4, 2, 0,185, 4, 2, 0,186, 4, 2, 0, 61, 1, 2, 0,187, 4, 2, 0,188, 4, 2, 0,189, 4, - 2, 0,190, 4, 4, 0,191, 4, 4, 0, 40, 1, 2, 0,192, 4, 2, 0,193, 4, 2, 0,194, 4, 2, 0,195, 4, 2, 0,196, 4, - 2, 0,197, 4, 24, 0,198, 4, 24, 0,199, 4, 23, 0,200, 4, 12, 0,201, 4, 2, 0,202, 4, 2, 0, 37, 0, 7, 0,203, 4, - 7, 0,204, 4, 7, 0,205, 4, 7, 0,206, 4, 4, 0,207, 4, 7, 0,208, 4, 7, 0,209, 4, 7, 0,210, 4, 7, 0,211, 4, - 2, 0,212, 4, 2, 0,213, 4, 2, 0,214, 4, 2, 0,215, 4, 2, 0,216, 4, 2, 0,217, 4, 7, 0,218, 4, 7, 0,219, 4, - 7, 0,220, 4, 2, 0,221, 4, 2, 0,222, 4, 2, 0,223, 4, 2, 0,224, 4, 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4, - 2, 0,228, 4, 2, 0,229, 4, 2, 0,230, 4, 4, 0,231, 4, 4, 0,232, 4, 4, 0,233, 4, 4, 0,234, 4, 4, 0,235, 4, - 7, 0,236, 4, 4, 0,237, 4, 4, 0,238, 4, 4, 0,239, 4, 4, 0,240, 4, 7, 0,241, 4, 7, 0,242, 4, 7, 0,243, 4, - 7, 0,244, 4, 7, 0,245, 4, 7, 0,246, 4, 7, 0,247, 4, 7, 0,248, 4, 7, 0,249, 4, 0, 0,250, 4, 0, 0,251, 4, - 4, 0,252, 4, 2, 0,253, 4, 2, 0,209, 1, 0, 0,254, 4, 7, 0,255, 4, 7, 0, 0, 5, 4, 0, 1, 5, 4, 0, 2, 5, - 7, 0, 3, 5, 7, 0, 4, 5, 2, 0, 5, 5, 2, 0, 6, 5, 7, 0, 7, 5, 2, 0, 8, 5, 2, 0, 9, 5, 4, 0, 10, 5, - 2, 0, 11, 5, 2, 0, 12, 5, 2, 0, 13, 5, 2, 0, 14, 5, 7, 0, 15, 5, 7, 0, 70, 0, 42, 0, 16, 5, 0, 0, 17, 5, -181, 0, 9, 0,181, 0, 0, 0,181, 0, 1, 0, 0, 0, 20, 0, 2, 0, 18, 5, 2, 0, 19, 5, 2, 0, 20, 5, 2, 0, 43, 0, - 7, 0, 21, 5, 7, 0, 70, 0,182, 0, 7, 0, 2, 0,187, 2, 2, 0, 40, 1, 2, 0,109, 0, 2, 0, 22, 5, 7, 0, 23, 5, - 7, 0, 70, 0, 42, 0, 24, 5,183, 0, 5, 0, 7, 0, 25, 5, 0, 0, 17, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0,209, 1, -184, 0, 26, 0, 7, 0, 77, 4, 7, 0, 78, 4, 2, 0, 40, 1, 2, 0, 19, 0, 2, 0, 26, 5, 2, 0,105, 1, 2, 0, 80, 4, - 2, 0, 81, 4, 2, 0, 82, 4, 2, 0, 83, 4, 2, 0, 84, 4, 2, 0, 85, 4,183, 0, 27, 5, 2, 0,170, 4, 2, 0,171, 4, - 2, 0,172, 4, 2, 0,173, 4, 2, 0,216, 0, 2, 0,174, 4, 2, 0,175, 4, 2, 0,178, 3,182, 0, 28, 5, 2, 0, 29, 5, - 2, 0,176, 4, 2, 0,179, 4, 2, 0,180, 4,185, 0, 5, 0,185, 0, 0, 0,185, 0, 1, 0, 4, 0,181, 3, 0, 0,193, 3, - 4, 0, 19, 0,186, 0, 6, 0,187, 0, 30, 5, 4, 0, 31, 5, 4, 0, 32, 5, 9, 0, 33, 5, 0, 0, 34, 5, 4, 0, 37, 0, -188, 0, 6, 0,186, 0, 35, 5, 2, 0, 19, 0, 2, 0, 36, 5, 2, 0, 37, 5, 2, 0, 38, 5, 9, 0, 39, 5,189, 0, 4, 0, - 2, 0,106, 0, 2, 0,198, 2, 2, 0,187, 3, 2, 0, 40, 5,190, 0, 14, 0, 2, 0, 19, 0, 2, 0, 41, 5, 2, 0, 42, 5, - 2, 0, 43, 5,189, 0, 44, 5, 9, 0, 39, 5, 7, 0, 45, 5, 7, 0, 57, 0, 4, 0, 46, 5, 4, 0, 47, 5, 4, 0, 48, 5, - 4, 0, 49, 5, 46, 0,134, 0, 32, 0,164, 0,191, 0, 4, 0,191, 0, 0, 0,191, 0, 1, 0, 0, 0, 50, 5, 7, 0, 51, 5, -192, 0, 6, 0,186, 0, 35, 5, 7, 0, 52, 5, 4, 0, 90, 0, 0, 0, 53, 5, 0, 0, 54, 5, 0, 0,167, 2,193, 0, 9, 0, -186, 0, 35, 5, 7, 0, 55, 5, 7, 0, 56, 5, 2, 0, 40, 1, 2, 0, 19, 0, 4, 0, 36, 0, 4, 0, 57, 5, 87, 0, 58, 5, - 9, 0, 39, 5,194, 0, 72, 0,193, 0, 59, 5,193, 0, 60, 5,192, 0, 57, 3, 7, 0, 61, 5, 2, 0, 62, 5, 2, 0, 63, 5, - 7, 0, 64, 5, 7, 0, 65, 5, 2, 0,187, 3, 2, 0, 66, 5, 7, 0, 67, 5, 7, 0, 68, 5, 7, 0, 69, 5, 2, 0, 70, 5, - 2, 0, 46, 5, 2, 0, 71, 5, 2, 0, 72, 5, 2, 0, 73, 5, 2, 0, 74, 5, 7, 0, 75, 5, 7, 0, 76, 5, 7, 0, 77, 5, - 2, 0, 78, 5, 2, 0, 79, 5, 2, 0, 80, 5, 2, 0, 81, 5, 2, 0, 82, 5, 2, 0, 83, 5, 2, 0, 84, 5,188, 0, 85, 5, -190, 0, 86, 5, 7, 0, 87, 5, 7, 0, 88, 5, 7, 0, 89, 5, 2, 0, 90, 5, 2, 0, 91, 5, 0, 0, 92, 5, 0, 0, 93, 5, - 0, 0, 94, 5, 0, 0, 95, 5, 0, 0, 96, 5, 0, 0, 97, 5, 2, 0, 98, 5, 7, 0, 99, 5, 7, 0,100, 5, 7, 0,101, 5, - 7, 0,102, 5, 7, 0,103, 5, 7, 0,104, 5, 7, 0,105, 5, 7, 0,106, 5, 7, 0,107, 5, 7, 0,108, 5, 2, 0,109, 5, - 0, 0,110, 5, 0, 0,111, 5, 0, 0,112, 5, 0, 0,113, 5, 32, 0,114, 5, 0, 0,115, 5, 0, 0,116, 5, 0, 0,117, 5, - 0, 0,118, 5, 0, 0,119, 5, 0, 0,120, 5, 0, 0,121, 5, 0, 0,122, 5, 2, 0,123, 5, 2, 0,124, 5, 2, 0,125, 5, - 2, 0,126, 5, 2, 0,127, 5,195, 0, 8, 0, 4, 0,128, 5, 4, 0,129, 5, 4, 0,130, 5, 4, 0,131, 5, 4, 0,132, 5, - 4, 0,133, 5, 4, 0, 54, 0, 4, 0,103, 2,196, 0, 3, 0, 7, 0,134, 5, 2, 0,135, 5, 2, 0, 19, 0, 46, 0, 37, 0, - 27, 0, 31, 0, 39, 0, 75, 0, 32, 0,136, 5,173, 0,137, 5, 46, 0,138, 5, 47, 0,208, 0, 12, 0,139, 5,174, 0,140, 5, - 32, 0,141, 5, 7, 0,142, 5, 7, 0,143, 5, 7, 0,144, 5, 7, 0,145, 5, 4, 0, 83, 3, 2, 0, 19, 0, 2, 0, 34, 1, - 61, 0, 29, 1,197, 0,146, 5,194, 0,147, 5,198, 0,148, 5,180, 0,182, 0,178, 0,159, 4, 12, 0,100, 0, 12, 0,149, 5, - 12, 0,150, 5,199, 0,151, 5, 2, 0,152, 5, 2, 0,153, 5, 2, 0,217, 0, 2, 0,154, 5, 4, 0,155, 5, 4, 0,156, 5, - 12, 0,157, 5,183, 0, 27, 5,184, 0,158, 5,196, 0,159, 5,161, 0, 70, 3,200, 0, 6, 0, 47, 0,208, 0, 45, 0, 28, 1, - 7, 0, 67, 2, 7, 0, 68, 2, 7, 0,106, 0, 7, 0,160, 5,201, 0, 35, 0, 7, 0,161, 5, 7, 0,162, 5, 7, 0,163, 5, - 7, 0,164, 5, 7, 0,165, 5, 7, 0,166, 5, 7, 0,167, 5, 7, 0,168, 5, 7, 0,169, 5, 7, 0, 47, 1, 7, 0,170, 5, - 7, 0,171, 5, 7, 0,172, 5, 7, 0,173, 5, 7, 0,171, 0, 2, 0,174, 5, 2, 0,175, 5, 4, 0,176, 5, 2, 0,177, 5, - 2, 0,178, 5, 2, 0,179, 5, 2, 0,180, 5, 7, 0,181, 5, 72, 0,182, 5,161, 0, 70, 3,201, 0,183, 5,202, 0,184, 5, -203, 0,185, 5,204, 0,186, 5,205, 0,187, 5,206, 0,188, 5, 7, 0,189, 5, 2, 0,190, 5, 2, 0,191, 5, 4, 0,209, 1, -207, 0, 54, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 7, 0,169, 5, - 7, 0, 47, 1, 7, 0, 43, 0, 4, 0,196, 5, 2, 0,179, 5, 2, 0,180, 5, 32, 0,136, 5, 32, 0,197, 5,200, 0,198, 5, -207, 0,183, 5, 0, 0,199, 5, 4, 0, 83, 3, 4, 0,200, 5, 2, 0,201, 5, 2, 0,202, 5, 2, 0,203, 5, 2, 0,204, 5, - 2, 0,209, 1, 2, 0, 19, 0, 2, 0, 6, 2, 2, 0,205, 5, 7, 0,112, 0, 7, 0,206, 5, 7, 0,207, 5, 7, 0,208, 5, - 7, 0,209, 5, 7, 0,210, 5, 7, 0,171, 0, 7, 0,142, 5, 2, 0,211, 5, 2, 0, 90, 1, 2, 0,212, 5, 2, 0,213, 5, - 2, 0,214, 5, 2, 0,215, 5, 2, 0,216, 5, 2, 0,217, 5, 2, 0,218, 5, 2, 0,219, 5, 4, 0,220, 5, 12, 0,221, 5, - 2, 0,222, 5, 2, 0,116, 2, 2, 0,223, 5, 0, 0,224, 5, 0, 0,225, 5, 9, 0,226, 5,161, 0, 70, 3,209, 0, 25, 0, - 24, 0, 36, 0, 24, 0, 64, 0, 23, 0,227, 5, 23, 0,228, 5, 23, 0,229, 5, 7, 0,230, 5, 7, 0,231, 5, 7, 0,232, 5, - 7, 0,233, 5, 2, 0,234, 5, 2, 0,235, 5, 2, 0,236, 5, 2, 0,237, 5, 2, 0,238, 5, 2, 0, 19, 0, 2, 0,239, 5, - 2, 0,240, 5, 2, 0,241, 5, 2, 0,242, 5, 2, 0,243, 5, 2, 0,204, 5, 7, 0,244, 5, 7, 0,245, 5, 4, 0,246, 5, - 4, 0,247, 5,208, 0, 6, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, -210, 0, 8, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,211, 0,248, 5, - 46, 0,134, 0,212, 0, 14, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, -209, 0,249, 5,213, 0,250, 5, 12, 0,251, 5, 2, 0, 40, 1, 2, 0, 19, 0, 2, 0,252, 5, 0, 0,253, 5, 0, 0,254, 5, -214, 0, 20, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,202, 0,184, 5, -209, 0,249, 5, 2, 0,255, 5, 2, 0, 0, 6, 2, 0, 1, 6, 2, 0, 2, 6, 2, 0,239, 5, 2, 0, 3, 6, 0, 0, 19, 0, - 0, 0,105, 1, 9, 0, 43, 2, 4, 0, 4, 6, 4, 0, 5, 6, 27, 0, 6, 6,215, 0, 16, 0,208, 0, 0, 0,208, 0, 1, 0, - 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, 7, 0, 67, 2, 7, 0, 68, 2, 2, 0,255, 5, - 2, 0, 7, 6, 2, 0, 8, 6, 2, 0, 9, 6, 4, 0, 19, 0, 7, 0, 10, 6,161, 0, 70, 3,216, 0, 16, 0, 0, 0, 11, 6, - 0, 0, 12, 6, 0, 0, 13, 6, 0, 0, 14, 6, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 15, 6, 2, 0, 16, 6, 2, 0,152, 1, - 2, 0, 17, 6, 4, 0, 18, 6, 4, 0, 19, 6, 2, 0, 20, 6, 2, 0, 21, 6, 0, 0, 22, 6, 0, 0, 23, 6,217, 0, 16, 0, -208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 4, 0, 37, 0,216, 0, 24, 6,218, 0, 25, 6, 12, 0, 26, 6, - 12, 0, 27, 6,219, 0, 28, 6,206, 0, 29, 6,220, 0, 30, 6, 2, 0, 31, 6, 2, 0, 32, 6, 2, 0, 33, 6, 2, 0, 70, 0, -221, 0, 17, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, - 12, 0, 34, 6,222, 0, 35, 6, 0, 0, 36, 6,223, 0, 37, 6, 4, 0, 38, 6, 4, 0, 39, 6, 2, 0, 19, 0, 2, 0, 40, 6, - 2, 0, 41, 6, 2, 0, 37, 0,224, 0, 29, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, - 2, 0,195, 5, 47, 0,206, 2, 45, 0, 28, 1, 64, 0, 42, 6, 2, 0,133, 0, 2, 0, 43, 6, 2, 0, 70, 0, 2, 0, 44, 6, - 4, 0, 19, 0, 2, 0, 45, 6, 2, 0,254, 5, 2, 0,253, 5, 2, 0,209, 1, 0, 0, 46, 6, 0, 0, 47, 6, 0, 0, 48, 6, - 0, 0,204, 5, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 10, 6, 7, 0, 90, 1, 7, 0, 49, 6, 7, 0, 50, 6,161, 0, 70, 3, -225, 0, 11, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 2, 0,252, 5, - 2, 0, 19, 0, 4, 0, 37, 0,213, 0,250, 5,209, 0,249, 5,226, 0, 27, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, - 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 42, 0, 51, 6, 4, 0, 52, 6, 4, 0, 53, 6, 2, 0, 90, 0, 2, 0,133, 0, - 2, 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, 62, 6, 7, 0, 63, 6, 23, 0, 64, 6, 23, 0, 65, 6, 4, 0, 66, 6, 4, 0, 67, 6, 0, 0, 68, 6, 0, 0, 69, 6, -227, 0, 10, 0, 27, 0, 31, 0, 9, 0, 70, 6, 9, 0, 71, 6, 9, 0, 72, 6, 9, 0, 73, 6, 9, 0, 74, 6, 4, 0, 90, 0, - 4, 0, 75, 6, 0, 0, 76, 6, 0, 0, 77, 6,228, 0, 10, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, - 7, 0,194, 5,227, 0, 78, 6, 2, 0, 90, 0, 2, 0,133, 0, 4, 0, 43, 0, 9, 0, 79, 6,229, 0, 8, 0,208, 0, 0, 0, -208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,209, 0,249, 5, 4, 0, 19, 0, 4, 0, 80, 6,230, 0, 23, 0, -208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5,209, 0,249, 5, 27, 0, 81, 6, - 27, 0, 81, 0, 2, 0, 19, 0, 2, 0,133, 0, 7, 0, 82, 6, 9, 0, 83, 6, 7, 0, 67, 2, 7, 0, 68, 2, 7, 0, 84, 6, - 7, 0, 85, 6, 61, 0, 29, 1, 61, 0, 86, 6, 4, 0, 87, 6, 2, 0, 88, 6, 2, 0, 37, 0,161, 0, 70, 3,231, 0, 10, 0, -208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 2, 0, 19, 0, 2, 0, 92, 3, - 4, 0, 37, 0,161, 0, 70, 3,232, 0, 42, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, - 2, 0,195, 5,209, 0,249, 5,218, 0, 25, 6, 0, 0, 11, 6, 0, 0, 12, 6, 0, 0, 13, 6, 2, 0, 17, 0, 2, 0, 21, 6, - 2, 0, 19, 0, 2, 0, 15, 6, 9, 0, 83, 6, 4, 0, 18, 6, 4, 0, 89, 6, 4, 0, 90, 6, 4, 0, 19, 6, 23, 0, 91, 6, - 23, 0, 92, 6, 7, 0, 93, 6, 7, 0, 94, 6, 7, 0, 95, 6, 7, 0, 82, 6, 2, 0, 96, 6, 2, 0,207, 0, 2, 0,152, 1, - 2, 0, 17, 6, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 97, 6, 2, 0, 98, 6, 9, 0, 99, 6, 9, 0,100, 6, 9, 0,101, 6, - 9, 0,102, 6, 9, 0,103, 6, 2, 0,104, 6, 0, 0, 23, 6, 57, 0,105, 6,233, 0, 7, 0,233, 0, 0, 0,233, 0, 1, 0, - 4, 0,106, 6, 4, 0, 23, 0, 0, 0, 84, 0, 4, 0,107, 6, 4, 0, 17, 0,234, 0, 13, 0,208, 0, 0, 0,208, 0, 1, 0, - 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, 2, 0,195, 5, 4, 0, 17, 0, 4, 0,108, 6, 4, 0, 19, 0, 4, 0, 54, 6, - 12, 0,109, 6, 12, 0,110, 6, 0, 0,111, 6,235, 0, 5, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, - 4, 0, 37, 0,236, 0, 7, 0,236, 0, 0, 0,236, 0, 1, 0, 0, 0,112, 6, 2, 0,113, 6, 2, 0,114, 6, 2, 0,115, 6, - 2, 0, 37, 0,237, 0, 12, 0, 2, 0,114, 6, 2, 0,116, 6, 2, 0,117, 6, 0, 0,167, 2, 2, 0,118, 6, 2, 0,119, 6, - 2, 0,120, 6, 2, 0,121, 6, 2, 0,122, 6, 2, 0,239, 5, 7, 0,123, 6, 7, 0,124, 6,238, 0, 18, 0,238, 0, 0, 0, -238, 0, 1, 0, 0, 0,193, 3,237, 0,125, 6,237, 0,126, 6,237, 0,127, 6,237, 0,128, 6, 7, 0,129, 6, 2, 0,130, 6, - 2, 0,131, 6, 2, 0,132, 6, 2, 0,133, 6, 2, 0,134, 6, 2, 0,135, 6, 2, 0,136, 6, 2, 0,137, 6, 2, 0,138, 6, - 2, 0,139, 6,239, 0, 10, 0, 0, 0,140, 6, 0, 0,141, 6, 0, 0,142, 6, 0, 0,143, 6, 0, 0,144, 6, 0, 0,145, 6, - 2, 0,146, 6, 2, 0,147, 6, 2, 0,148, 6, 2, 0, 37, 0,240, 0, 8, 0, 0, 0,149, 6, 0, 0,150, 6, 0, 0,151, 6, - 0, 0,152, 6, 0, 0,153, 6, 0, 0,154, 6, 7, 0,160, 5, 7, 0, 37, 0,241, 0, 17, 0,239, 0,155, 6,239, 0,156, 6, -239, 0,157, 6,239, 0,158, 6,239, 0,159, 6,239, 0,160, 6,239, 0,161, 6,239, 0,162, 6,239, 0,163, 6,239, 0,164, 6, -239, 0,165, 6,239, 0,166, 6,239, 0,167, 6,239, 0,168, 6,239, 0,169, 6,240, 0,170, 6, 0, 0,171, 6,242, 0, 71, 0, - 0, 0,172, 6, 0, 0,173, 6, 0, 0,144, 6, 0, 0,174, 6, 0, 0,175, 6, 0, 0,176, 6, 0, 0,177, 6, 0, 0,178, 6, - 0, 0,179, 6, 0, 0,180, 6, 0, 0,181, 6, 0, 0,182, 6, 0, 0,183, 6, 0, 0,184, 6, 0, 0,185, 6, 0, 0,186, 6, - 0, 0,187, 6, 0, 0,188, 6, 0, 0,189, 6, 0, 0,190, 6, 0, 0,191, 6, 0, 0,192, 6, 0, 0,193, 6, 0, 0,194, 6, - 0, 0,195, 6, 0, 0,196, 6, 0, 0,197, 6, 0, 0,198, 6, 0, 0,199, 6, 0, 0,200, 6, 0, 0,201, 6, 0, 0,202, 6, - 0, 0,203, 6, 0, 0,204, 6, 0, 0,205, 6, 0, 0,206, 6, 0, 0,207, 6, 0, 0,208, 6, 0, 0,209, 6, 0, 0,210, 6, - 0, 0,211, 6, 0, 0,212, 6, 0, 0,213, 6, 0, 0,214, 6, 0, 0,215, 6, 0, 0,216, 6, 0, 0,217, 6, 0, 0,218, 6, - 0, 0,219, 6, 0, 0,220, 6, 0, 0,221, 6, 0, 0,222, 6, 0, 0,223, 6, 0, 0,224, 6, 0, 0,225, 6, 0, 0,226, 6, - 0, 0,227, 6, 0, 0,228, 6, 0, 0,229, 6, 0, 0,230, 6, 0, 0,231, 6, 0, 0,232, 6, 0, 0,233, 6, 0, 0,234, 6, - 0, 0,235, 6, 0, 0,236, 6, 0, 0,237, 6, 0, 0,238, 6, 0, 0,239, 6, 0, 0,240, 6, 0, 0, 92, 0,243, 0, 5, 0, - 0, 0,241, 6, 0, 0,196, 6, 0, 0,198, 6, 2, 0, 19, 0, 2, 0, 37, 0,244, 0, 22, 0,244, 0, 0, 0,244, 0, 1, 0, - 0, 0, 20, 0,241, 0,242, 6,242, 0,243, 6,242, 0,244, 6,242, 0,245, 6,242, 0,246, 6,242, 0,247, 6,242, 0,248, 6, -242, 0,249, 6,242, 0,250, 6,242, 0,251, 6,242, 0,252, 6,242, 0,253, 6,242, 0,254, 6,242, 0,255, 6,242, 0, 0, 7, -242, 0, 1, 7,242, 0, 2, 7,242, 0, 3, 7,243, 0, 4, 7,245, 0, 5, 0, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,115, 2, - 7, 0, 5, 7, 7, 0, 21, 2,246, 0, 71, 0, 4, 0, 19, 0, 4, 0, 6, 7, 4, 0, 7, 7, 0, 0, 8, 7, 0, 0, 9, 7, - 0, 0, 10, 7, 0, 0, 11, 7, 0, 0, 12, 7, 0, 0, 13, 7, 0, 0, 14, 7, 0, 0, 15, 7, 0, 0, 16, 7, 2, 0, 17, 7, - 2, 0, 37, 0, 4, 0, 18, 7, 4, 0, 19, 7, 4, 0, 20, 7, 4, 0, 21, 7, 2, 0, 22, 7, 2, 0, 23, 7, 4, 0, 24, 7, - 4, 0, 25, 7, 4, 0, 26, 7, 4, 0, 27, 7, 4, 0, 28, 7, 4, 0,109, 6, 4, 0, 29, 7, 2, 0, 30, 7, 2, 0, 31, 7, - 2, 0, 32, 7, 2, 0, 33, 7, 12, 0, 34, 7, 12, 0, 35, 7, 12, 0, 36, 7, 2, 0, 37, 7, 2, 0, 38, 7, 2, 0, 39, 7, - 2, 0, 40, 7, 2, 0, 41, 7, 2, 0, 42, 7, 2, 0, 43, 7, 2, 0, 44, 7,245, 0, 45, 7, 2, 0, 46, 7, 2, 0, 47, 7, - 2, 0, 48, 7, 2, 0, 49, 7, 2, 0, 50, 7, 2, 0, 51, 7, 2, 0, 52, 7, 2, 0, 53, 7, 4, 0, 54, 7, 4, 0, 55, 7, - 2, 0, 56, 7, 2, 0, 57, 7, 2, 0, 58, 7, 2, 0, 59, 7, 2, 0, 60, 7, 2, 0, 61, 7, 2, 0, 62, 7, 2, 0, 63, 7, - 2, 0, 64, 7, 2, 0, 65, 7, 2, 0, 66, 7, 2, 0, 67, 7, 0, 0, 68, 7, 0, 0, 69, 7, 7, 0, 70, 7, 2, 0, 90, 5, - 2, 0, 91, 5, 55, 0, 71, 7,211, 0, 21, 0, 27, 0, 31, 0, 12, 0, 72, 7, 12, 0, 73, 7, 12, 0, 74, 7, 12, 0,192, 5, - 46, 0,134, 0, 46, 0, 75, 7, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 79, 7, 2, 0, 80, 7, 2, 0, 81, 7, - 2, 0, 82, 7, 2, 0, 37, 0, 2, 0, 83, 7, 2, 0, 84, 7, 4, 0, 70, 0,206, 0, 85, 7, 9, 0, 86, 7, 2, 0, 87, 7, -247, 0, 5, 0,247, 0, 0, 0,247, 0, 1, 0,247, 0, 88, 7, 13, 0, 89, 7, 4, 0, 19, 0,248, 0, 7, 0,248, 0, 0, 0, -248, 0, 1, 0,247, 0, 90, 7,247, 0, 91, 7, 2, 0,199, 4, 2, 0, 19, 0, 4, 0, 37, 0,249, 0, 23, 0,249, 0, 0, 0, -249, 0, 1, 0,250, 0, 92, 7,251, 0, 30, 6, 0, 0, 93, 7, 0, 0, 94, 7, 0, 0, 95, 7, 2, 0, 96, 7, 2, 0, 97, 7, - 2, 0, 98, 7, 2, 0, 99, 7, 2, 0,100, 7, 2, 0, 37, 0, 2, 0, 19, 0, 2, 0,101, 7, 2, 0,102, 7, 2, 0,103, 7, - 4, 0,104, 7,249, 0,105, 7, 9, 0,106, 7, 4, 0,107, 7, 4, 0,108, 7, 0, 0,109, 7,252, 0, 22, 0,252, 0, 0, 0, -252, 0, 1, 0,247, 0, 90, 7,247, 0, 91, 7,247, 0,110, 7,247, 0,111, 7,211, 0,112, 7, 23, 0, 52, 0, 0, 0,193, 5, - 0, 0,113, 7, 2, 0,240, 5, 2, 0,241, 5, 2, 0,114, 7, 2, 0, 37, 0, 2, 0, 79, 7, 2, 0,107, 6, 2, 0, 19, 0, -253, 0, 92, 7, 12, 0,115, 7, 12, 0,192, 5, 12, 0,116, 7, 12, 0,117, 7,254, 0, 21, 0,254, 0, 0, 0,254, 0, 1, 0, -209, 0,249, 5, 23, 0,118, 7, 23, 0,119, 7, 2, 0,240, 5, 2, 0,241, 5, 2, 0,120, 7, 2, 0,121, 7, 2, 0,122, 7, - 2, 0, 19, 0, 7, 0, 63, 2, 2, 0, 78, 7, 2, 0, 82, 7, 4, 0, 43, 0,255, 0, 92, 7, 12, 0,123, 7, 12, 0,124, 7, - 12, 0,116, 7, 0, 0,125, 7, 9, 0,126, 7, 0, 1, 11, 0, 0, 0,127, 7, 2, 0,128, 7, 2, 0,129, 7, 2, 0,130, 7, - 2, 0,131, 7, 2, 0,188, 4, 2, 0,183, 4,211, 0,132, 7, 46, 0,133, 7, 4, 0,134, 7, 4, 0,135, 7, 1, 1, 1, 0, - 0, 0,136, 7, 2, 1, 8, 0, 57, 0,137, 7, 57, 0,138, 7, 2, 1,139, 7, 2, 1,140, 7, 2, 1,141, 7, 2, 0,129, 0, - 2, 0, 19, 0, 4, 0,142, 7, 3, 1, 4, 0, 4, 0, 52, 6, 4, 0,143, 7, 4, 0, 57, 6, 4, 0,144, 7, 4, 1, 2, 0, - 4, 0,145, 7, 4, 0,146, 7, 5, 1, 7, 0, 7, 0,147, 7, 7, 0,148, 7, 7, 0,149, 7, 4, 0, 19, 0, 4, 0, 37, 0, - 7, 0, 72, 4, 7, 0,150, 7, 6, 1, 6, 0, 0, 0,151, 7, 0, 0, 13, 6, 49, 0,137, 0, 2, 0,106, 0, 2, 0,187, 4, - 4, 0, 37, 0, 7, 1, 21, 0, 7, 1, 0, 0, 7, 1, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0,152, 7, - 4, 0,153, 7, 4, 0,154, 7, 1, 1,155, 7, 0, 0,151, 7, 4, 0,156, 7, 4, 0,157, 7, 6, 1, 64, 3, 3, 1,158, 7, - 4, 1,159, 7, 5, 1,160, 7, 2, 1,161, 7, 2, 1,162, 7, 2, 1,163, 7, 57, 0,164, 7, 57, 0,165, 7, 8, 1, 12, 0, - 0, 0,239, 1, 9, 0,193, 0, 0, 0,194, 0, 4, 0,197, 0, 4, 0,205, 0, 9, 0,198, 0, 7, 0,200, 0, 7, 0,201, 0, - 9, 0,166, 7, 9, 0,167, 7, 9, 0,202, 0, 9, 0,204, 0, 9, 1, 43, 0, 9, 1, 0, 0, 9, 1, 1, 0, 9, 0,168, 7, - 9, 0, 26, 0, 0, 0, 27, 0, 4, 0, 19, 0, 4, 0, 17, 0, 4, 0, 23, 0, 4, 0, 88, 0, 4, 0,169, 7, 4, 0,170, 7, - 4, 0,153, 7, 4, 0,154, 7, 4, 0,171, 7, 4, 0,216, 0, 4, 0,172, 7, 4, 0,173, 7, 7, 0, 56, 5, 7, 0,174, 7, - 4, 0,126, 0, 4, 0,175, 7, 7, 1,176, 7, 36, 0, 80, 0, 46, 0,134, 0, 49, 0,137, 0, 7, 0,177, 7, 7, 0,178, 7, - 8, 1, 30, 1, 9, 1,179, 7, 9, 1,180, 7, 9, 1,181, 7, 12, 0,182, 7, 10, 1,183, 7, 11, 1,184, 7, 7, 0,185, 7, - 7, 0,186, 7, 4, 0,187, 7, 7, 0,188, 7, 9, 0,189, 7, 4, 0,190, 7, 4, 0,191, 7, 4, 0,192, 7, 7, 0,193, 7, - 12, 1, 4, 0, 12, 1, 0, 0, 12, 1, 1, 0, 12, 0,194, 7, 9, 1,195, 7,197, 0, 6, 0, 12, 0,196, 7, 12, 0,182, 7, - 12, 0,197, 7, 9, 1,198, 7, 0, 0,199, 7, 0, 0,200, 7, 13, 1, 4, 0, 7, 0,201, 7, 7, 0,109, 0, 2, 0,202, 7, - 2, 0,203, 7, 14, 1, 6, 0, 7, 0,204, 7, 7, 0,205, 7, 7, 0,206, 7, 7, 0,207, 7, 4, 0,208, 7, 4, 0,209, 7, - 15, 1, 12, 0, 7, 0,210, 7, 7, 0,211, 7, 7, 0,212, 7, 7, 0,213, 7, 7, 0,214, 7, 7, 0,215, 7, 7, 0,216, 7, - 7, 0,217, 7, 7, 0,218, 7, 7, 0,219, 7, 4, 0,210, 2, 4, 0,220, 7, 16, 1, 2, 0, 7, 0, 25, 5, 7, 0, 37, 0, - 17, 1, 5, 0, 7, 0,221, 7, 7, 0,222, 7, 4, 0, 90, 0, 4, 0,168, 2, 4, 0,223, 7, 18, 1, 6, 0, 18, 1, 0, 0, - 18, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0, 57, 0, 19, 1, 8, 0, 19, 1, 0, 0, 19, 1, 1, 0, - 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0,126, 0, 20, 1, 45, 0, 20, 1, 0, 0, - 20, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,224, 7, 2, 0,212, 0, 2, 0,244, 3, 2, 0,225, 7, 7, 0,226, 7, - 7, 0, 89, 0, 7, 0,223, 2, 4, 0,227, 7, 4, 0, 82, 0, 4, 0,170, 2, 7, 0,228, 7, 7, 0,229, 7, 7, 0,230, 7, - 7, 0,231, 7, 7, 0,232, 7, 7, 0,233, 7, 7, 0,220, 2, 7, 0, 27, 1, 7, 0,234, 7, 7, 0,235, 7, 7, 0, 37, 0, - 7, 0,236, 7, 7, 0,237, 7, 7, 0,238, 7, 2, 0,239, 7, 2, 0,240, 7, 2, 0,241, 7, 2, 0,242, 7, 2, 0,243, 7, - 2, 0,244, 7, 2, 0,245, 7, 2, 0,246, 7, 2, 0, 6, 2, 2, 0,247, 7, 2, 0, 3, 2, 2, 0,248, 7, 0, 0,249, 7, - 0, 0,250, 7, 7, 0,210, 0, 21, 1,251, 7, 68, 0,212, 1, 22, 1, 16, 0, 22, 1, 0, 0, 22, 1, 1, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 2, 0,224, 7, 2, 0,212, 0, 7, 0,215, 2, 7, 0,216, 2, 7, 0,217, 2, 7, 0, 52, 2, 7, 0,218, 2, - 7, 0,219, 2, 7, 0,252, 7, 7, 0,220, 2, 7, 0,222, 2, 7, 0,223, 2,223, 0, 5, 0, 2, 0, 17, 0, 2, 0,142, 7, - 2, 0, 19, 0, 2, 0,253, 7, 27, 0, 81, 6,222, 0, 3, 0, 4, 0, 69, 0, 4, 0,254, 7,223, 0, 2, 0, 23, 1, 7, 0, - 23, 1, 0, 0, 23, 1, 1, 0, 0, 0, 20, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 22, 0, 9, 0,255, 7, 24, 1, 5, 0, - 0, 0, 20, 0, 7, 0, 47, 1, 7, 0, 0, 8, 4, 0, 1, 8, 4, 0, 37, 0, 25, 1, 4, 0, 2, 0, 17, 0, 2, 0, 19, 0, - 2, 0, 43, 0, 2, 0, 70, 0, 26, 1, 4, 0, 0, 0, 20, 0, 67, 0, 2, 8, 7, 0, 47, 1, 7, 0, 37, 0, 27, 1, 6, 0, - 2, 0, 3, 8, 2, 0, 4, 8, 2, 0, 17, 0, 2, 0, 5, 8, 0, 0, 6, 8, 0, 0, 7, 8, 28, 1, 5, 0, 4, 0, 17, 0, - 4, 0, 37, 0, 0, 0, 20, 0, 0, 0, 8, 8, 0, 0, 9, 8, 29, 1, 3, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0, - 30, 1, 4, 0, 2, 0, 10, 8, 2, 0, 11, 8, 2, 0, 19, 0, 2, 0, 37, 0, 31, 1, 6, 0, 0, 0, 20, 0, 0, 0, 12, 8, - 2, 0, 13, 8, 2, 0,220, 2, 2, 0, 40, 1, 2, 0, 70, 0, 32, 1, 5, 0, 0, 0, 20, 0, 7, 0,109, 0, 7, 0, 74, 4, - 2, 0, 19, 0, 2, 0,182, 2, 33, 1, 3, 0, 0, 0, 20, 0, 4, 0,170, 2, 4, 0, 10, 8, 34, 1, 7, 0, 0, 0, 20, 0, - 7, 0, 74, 4, 0, 0, 14, 8, 0, 0, 15, 8, 2, 0, 40, 1, 2, 0, 43, 0, 4, 0, 16, 8, 35, 1, 3, 0, 32, 0, 17, 8, - 0, 0, 18, 8, 0, 0, 19, 8, 36, 1, 18, 0, 36, 1, 0, 0, 36, 1, 1, 0, 2, 0, 17, 0, 2, 0, 20, 8, 2, 0, 19, 0, - 2, 0, 21, 8, 2, 0, 22, 8, 2, 0, 23, 8, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 20, 0, 9, 0, 2, 0, 37, 1, 24, 8, - 32, 0, 45, 0, 2, 0, 40, 5, 2, 0,185, 7, 2, 0, 25, 8, 2, 0, 37, 0, 38, 1, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0, - 0, 0, 26, 8, 2, 0, 19, 0, 2, 0,182, 2, 2, 0, 27, 8, 4, 0, 28, 8, 4, 0, 29, 8, 4, 0, 30, 8, 4, 0, 31, 8, - 4, 0, 32, 8, 39, 1, 1, 0, 0, 0, 33, 8, 40, 1, 4, 0, 42, 0, 51, 6, 0, 0, 34, 8, 4, 0, 40, 1, 4, 0, 19, 0, - 37, 1, 18, 0, 37, 1, 0, 0, 37, 1, 1, 0, 37, 1, 35, 8, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 36, 8, 2, 0, 23, 8, - 2, 0, 20, 8, 2, 0, 37, 8, 2, 0, 70, 0, 2, 0,209, 1, 0, 0, 20, 0, 9, 0, 2, 0, 41, 1, 24, 8, 36, 1, 38, 8, - 2, 0, 15, 0, 2, 0, 39, 8, 4, 0, 40, 8, 42, 1, 3, 0, 4, 0,196, 2, 4, 0, 37, 0, 32, 0, 45, 0, 43, 1, 12, 0, -159, 0, 41, 8, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0, 42, 8, 2, 0, 43, 8, - 2, 0, 44, 8, 2, 0, 45, 8, 2, 0, 46, 8, 7, 0, 47, 8, 44, 1, 13, 0, 2, 0, 19, 0, 2, 0, 48, 8, 4, 0,226, 7, - 4, 0, 89, 0, 2, 0, 49, 8, 7, 0,202, 3, 7, 0, 50, 8, 10, 1,183, 7, 45, 1, 51, 8, 2, 0, 17, 0, 2, 0, 52, 8, - 2, 0, 53, 8, 2, 0, 54, 8, 46, 1, 11, 0, 4, 0,196, 2, 2, 0, 17, 0, 2, 0, 19, 0, 32, 0, 45, 0, 81, 0, 55, 8, - 0, 0, 20, 0, 7, 0, 56, 8, 7, 0, 57, 8, 7, 0,100, 3, 2, 0, 58, 8, 2, 0, 59, 8, 47, 1, 5, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 4, 0, 37, 0, 46, 0,134, 0, 32, 0,136, 5, 48, 1, 5, 0, 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 20, 0, - 0, 0, 8, 8, 32, 0, 45, 0, 49, 1, 13, 0, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0, 20, 8, 2, 0,101, 3, 7, 0, 60, 8, - 7, 0, 61, 8, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0, 77, 3, 7, 0, 80, 3, 7, 0, 62, 8, 7, 0, 63, 8, 32, 0, 64, 8, - 50, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 0, 0, 42, 8, 2, 0, 43, 0, - 2, 0, 64, 0, 2, 0, 65, 8, 2, 0, 66, 8, 51, 1, 8, 0, 32, 0, 45, 0, 7, 0,217, 2, 7, 0, 67, 8, 7, 0, 68, 8, - 7, 0,212, 2, 2, 0, 19, 0, 2, 0,182, 2, 7, 0, 69, 8, 52, 1, 12, 0, 2, 0, 17, 0, 2, 0, 40, 1, 2, 0, 19, 0, - 2, 0,220, 2, 2, 0,196, 2, 2, 0, 70, 8, 4, 0, 37, 0, 7, 0, 71, 8, 7, 0, 72, 8, 7, 0, 73, 8, 7, 0, 74, 8, - 0, 0, 75, 8, 53, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, 4, 0, 89, 0, 0, 0, 20, 0, 2, 0,105, 1, - 2, 0, 64, 0, 2, 0, 65, 8, 2, 0, 66, 8, 68, 0,212, 1, 54, 1, 7, 0, 4, 0,170, 2, 4, 0, 76, 8, 4, 0, 77, 8, - 4, 0, 78, 8, 7, 0, 79, 8, 7, 0, 80, 8, 0, 0, 14, 8, 55, 1, 7, 0, 0, 0, 81, 8, 32, 0, 82, 8, 0, 0, 18, 8, - 2, 0, 83, 8, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0, 19, 8, 56, 1, 6, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0,226, 7, - 4, 0, 89, 0, 0, 0, 84, 8, 0, 0, 85, 8, 57, 1, 1, 0, 4, 0, 19, 0, 58, 1, 6, 0, 0, 0, 92, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 4, 0, 86, 8, 7, 0, 87, 8, 42, 0, 51, 6, 59, 1, 4, 0, 0, 0, 48, 2, 2, 0, 19, 0, 4, 0, 17, 0, - 32, 0, 45, 0, 60, 1, 2, 0, 4, 0, 17, 0, 4, 0,229, 5, 41, 1, 10, 0, 41, 1, 0, 0, 41, 1, 1, 0, 41, 1, 35, 8, - 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 20, 8, 2, 0, 88, 8, 0, 0, 20, 0, 9, 0, 2, 0, 32, 0, 45, 0, 61, 1, 10, 0, - 7, 0,100, 3, 7, 0, 89, 8, 7, 0, 90, 8, 7, 0, 91, 8, 7, 0, 92, 8, 4, 0, 19, 0, 7, 0, 70, 8, 7, 0, 93, 8, - 7, 0, 94, 8, 7, 0, 37, 0, 11, 1, 12, 0, 11, 1, 0, 0, 11, 1, 1, 0, 10, 1, 95, 8, 9, 0,193, 0, 4, 0,143, 3, - 4, 0,189, 3, 4, 0,190, 3, 4, 0, 96, 8, 4, 0, 97, 8, 4, 0, 98, 8, 7, 0,202, 3, 7, 0, 37, 0, 45, 1, 8, 0, - 7, 0, 99, 8, 7, 0,100, 8, 7, 0,101, 8, 7, 0,102, 8, 7, 0,103, 8, 7, 0,104, 8, 7, 0,105, 8, 7, 0,106, 8, - 10, 1, 15, 0, 27, 0, 31, 0, 0, 0,192, 0, 43, 0,149, 0, 9, 0,193, 0, 43, 0,107, 8, 36, 0, 80, 0, 7, 0,202, 3, - 7, 0,108, 8, 7, 0, 50, 8, 7, 0, 99, 8, 7, 0,100, 8, 7, 0,109, 8, 4, 0, 90, 0, 4, 0, 98, 8, 9, 0,110, 8, - 62, 1, 15, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5,252, 0,111, 8,209, 0,249, 5, - 10, 1,183, 7, 2, 0, 40, 1, 2, 0, 48, 8, 2, 0, 67, 2, 2, 0, 68, 2, 2, 0, 19, 0, 2, 0,254, 5, 4, 0, 70, 0, - 63, 1, 6, 0, 63, 1, 0, 0, 63, 1, 1, 0, 32, 0, 45, 0, 9, 0,112, 8, 4, 0,217, 0, 4, 0, 37, 0, 68, 0, 4, 0, - 27, 0, 31, 0, 12, 0,113, 8, 4, 0,131, 0, 7, 0,114, 8, 64, 1, 25, 0, 64, 1, 0, 0, 64, 1, 1, 0, 64, 1, 38, 0, - 12, 0,115, 8, 0, 0, 20, 0, 7, 0,116, 8, 7, 0,117, 8, 7, 0,118, 8, 7, 0,119, 8, 4, 0, 19, 0, 7, 0,120, 8, - 7, 0,121, 8, 7, 0,122, 8, 7, 0, 47, 1, 7, 0, 14, 2, 7, 0,123, 8, 7, 0,168, 2, 7, 0,124, 8, 7, 0,125, 8, - 7, 0,126, 8, 7, 0,127, 8, 7, 0,128, 8, 7, 0,172, 0, 2, 0,131, 0, 2, 0, 71, 5, 65, 1, 21, 0, 27, 0, 31, 0, - 12, 0,129, 8, 12, 0,130, 8, 12, 0,131, 8, 9, 0,132, 8, 4, 0, 19, 0, 4, 0,201, 5, 2, 0,224, 2, 2, 0, 4, 6, - 2, 0,131, 0, 2, 0,133, 8, 2, 0,134, 8, 2, 0,135, 8, 2, 0,136, 8, 2, 0,137, 8, 4, 0,138, 8, 4, 0,139, 8, - 4, 0,140, 8, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 66, 1, 2, 0, 7, 0,129, 2, 4, 0, 19, 0, 67, 1, 5, 0, - 66, 1,144, 8, 4, 0,168, 2, 4, 0,145, 8, 4, 0,146, 8, 4, 0, 19, 0, 68, 1, 6, 0, 4, 0, 37, 0, 4, 0, 4, 6, - 4, 0,140, 8, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 69, 1, 38, 0, 69, 1, 0, 0, 69, 1, 1, 0, 26, 0,147, 8, - 12, 0,127, 3, 0, 0, 20, 0, 2, 0, 19, 0, 2, 0,148, 8, 2, 0,149, 8, 2, 0,150, 8, 2, 0, 86, 3, 2, 0,151, 8, - 4, 0, 50, 2, 4, 0,140, 8, 4, 0,141, 8, 64, 1,152, 8, 69, 1, 38, 0, 69, 1,153, 8, 12, 0,154, 8, 9, 0,155, 8, - 9, 0,156, 8, 9, 0,157, 8, 7, 0, 35, 1, 7, 0,172, 0, 7, 0,158, 8, 7, 0,249, 1, 2, 0,159, 8, 2, 0, 37, 0, - 7, 0,160, 8, 7, 0,161, 8, 7, 0, 82, 3, 7, 0,162, 8, 7, 0,163, 8, 7, 0,164, 8, 7, 0,165, 8, 7, 0,166, 8, - 7, 0,167, 8, 7, 0, 43, 2, 32, 0,168, 8,160, 0, 9, 0, 12, 0,169, 8, 2, 0, 19, 0, 2, 0,170, 8, 7, 0, 79, 2, - 7, 0,171, 8, 7, 0,172, 8, 12, 0,173, 8, 4, 0,174, 8, 4, 0, 37, 0, 70, 1, 7, 0, 70, 1, 0, 0, 70, 1, 1, 0, - 12, 0,175, 8, 4, 0, 19, 0, 4, 0,176, 8, 0, 0,193, 3,243, 0,177, 8,159, 0, 7, 0, 27, 0, 31, 0, 12, 0,178, 8, - 12, 0,169, 8, 12, 0,179, 8, 12, 0,100, 0, 4, 0, 19, 0, 4, 0,180, 8,213, 0, 4, 0, 27, 0, 95, 8, 12, 0,169, 8, - 4, 0,181, 8, 4, 0, 19, 0, 71, 1, 17, 0,208, 0, 0, 0,208, 0, 1, 0, 12, 0,192, 5, 4, 0,193, 5, 7, 0,194, 5, - 2, 0,195, 5,209, 0,249, 5,159, 0, 67, 3,213, 0,182, 8, 0, 0, 40, 1, 0, 0,252, 5, 2, 0, 19, 0, 2, 0,183, 8, - 2, 0,253, 5, 2, 0,254, 5, 2, 0,184, 8, 7, 0,185, 8, 72, 1, 8, 0, 72, 1, 0, 0, 72, 1, 1, 0, 70, 1,186, 8, - 36, 0, 80, 0, 12, 0, 71, 3, 4, 0, 19, 0, 0, 0, 20, 0, 4, 0,187, 8, 73, 1, 5, 0, 73, 1, 0, 0, 73, 1, 1, 0, - 36, 0, 80, 0, 2, 0, 19, 0, 0, 0,188, 8, 74, 1, 12, 0, 74, 1, 0, 0, 74, 1, 1, 0, 9, 0, 2, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 0, 0,189, 8, 0, 0,190, 8, 0, 0,188, 8, 7, 0,191, 8, 7, 0,192, 8, 4, 0, 37, 0, 36, 0, 80, 0, - 75, 1, 9, 0, 75, 1, 0, 0, 75, 1, 1, 0, 32, 0,193, 8, 0, 0,227, 2, 7, 0,194, 8, 2, 0,195, 8, 2, 0, 19, 0, - 2, 0, 17, 0, 2, 0,196, 8, 76, 1, 7, 0, 42, 0, 51, 6, 26, 0,147, 8, 4, 0, 19, 0, 4, 0,197, 8, 12, 0,198, 8, - 32, 0,193, 8, 0, 0,227, 2, 77, 1, 12, 0, 32, 0,193, 8, 2, 0,199, 8, 2, 0, 19, 0, 2, 0,200, 8, 2, 0,201, 8, - 0, 0,227, 2, 32, 0,202, 8, 0, 0,203, 8, 7, 0,204, 8, 7, 0, 14, 2, 7, 0,205, 8, 7, 0,206, 8, 78, 1, 6, 0, - 32, 0,193, 8, 4, 0,207, 8, 4, 0,208, 8, 4, 0, 90, 0, 4, 0, 37, 0, 0, 0,227, 2, 79, 1, 4, 0, 32, 0,193, 8, - 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, 80, 1, 4, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, - 81, 1, 10, 0, 32, 0,193, 8, 4, 0,209, 8, 7, 0,125, 0, 4, 0, 19, 0, 2, 0, 47, 6, 2, 0,210, 8, 2, 0, 43, 0, - 2, 0, 70, 0, 7, 0,211, 8, 0, 0,227, 2, 82, 1, 4, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0,207, 8, 0, 0,227, 2, - 83, 1, 10, 0, 32, 0,193, 8, 2, 0, 17, 0, 2, 0,252, 3, 4, 0, 88, 0, 4, 0, 89, 0, 7, 0, 67, 8, 7, 0, 68, 8, - 4, 0, 37, 0,159, 0, 41, 8, 0, 0,227, 2, 84, 1, 4, 0, 32, 0,193, 8, 4, 0, 87, 3, 4, 0,212, 8, 0, 0,227, 2, - 85, 1, 5, 0, 32, 0,193, 8, 7, 0,125, 0, 4, 0,213, 8, 4, 0, 87, 3, 4, 0, 88, 3, 86, 1, 6, 0, 32, 0,193, 8, - 4, 0,214, 8, 4, 0,215, 8, 7, 0,216, 8, 7, 0,217, 8, 0, 0,227, 2, 87, 1, 16, 0, 32, 0,193, 8, 32, 0,153, 8, - 4, 0, 17, 0, 7, 0,218, 8, 7, 0,219, 8, 7, 0,220, 8, 7, 0,221, 8, 7, 0,222, 8, 7, 0,223, 8, 7, 0,224, 8, - 7, 0,225, 8, 7, 0,226, 8, 2, 0, 19, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, 88, 1, 3, 0, 32, 0,193, 8, - 4, 0, 19, 0, 4, 0, 6, 2, 89, 1, 5, 0, 32, 0,193, 8, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,227, 8, 0, 0,227, 2, - 90, 1, 10, 0, 32, 0,193, 8, 0, 0,227, 2, 2, 0,228, 8, 2, 0,229, 8, 0, 0,230, 8, 0, 0,231, 8, 7, 0,232, 8, - 7, 0,233, 8, 7, 0,234, 8, 7, 0,235, 8, 91, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, - 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 92, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, - 7, 0, 12, 0, 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 93, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, - 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,236, 8, 7, 0,237, 8, 2, 0, 19, 0, 2, 0, 6, 2, 94, 1, 7, 0, 32, 0,193, 8, - 0, 0,227, 2, 7, 0, 47, 1, 7, 0, 56, 1, 2, 0, 19, 0, 2, 0, 40, 1, 4, 0, 37, 0, 95, 1, 5, 0, 32, 0, 27, 3, - 7, 0, 47, 1, 2, 0, 31, 3, 0, 0, 33, 3, 0, 0,238, 8, 96, 1, 10, 0, 96, 1, 0, 0, 96, 1, 1, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 0, 0,239, 8, 7, 0,246, 0, 7, 0,247, 0, 2, 0,175, 8, 2, 0,240, 8, 32, 0, 45, 0, 97, 1, 22, 0, - 97, 1, 0, 0, 97, 1, 1, 0, 2, 0, 19, 0, 2, 0, 40, 1, 2, 0,241, 8, 2, 0,242, 8, 36, 0, 80, 0,159, 0, 41, 8, - 32, 0,164, 0, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,243, 8, 7, 0,244, 8, 7, 0,245, 8, 7, 0,246, 8, 7, 0,213, 2, - 7, 0,247, 8, 7, 0, 43, 8, 7, 0,248, 8, 0, 0,249, 8, 0, 0,250, 8, 12, 0, 73, 3, 98, 1, 8, 0, 7, 0, 21, 2, - 7, 0, 67, 8, 7, 0, 68, 8, 9, 0, 2, 0, 2, 0,251, 8, 2, 0,252, 8, 2, 0,253, 8, 2, 0,254, 8, 99, 1, 18, 0, - 99, 1, 0, 0, 99, 1, 1, 0, 99, 1,255, 8, 0, 0, 20, 0, 98, 1, 0, 9, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 1, 9, - 2, 0, 2, 9, 2, 0, 3, 9, 2, 0, 4, 9, 4, 0, 43, 0, 7, 0, 5, 9, 7, 0, 6, 9, 4, 0, 7, 9, 4, 0, 8, 9, - 99, 1, 9, 9,100, 1, 10, 9,101, 1, 33, 0,101, 1, 0, 0,101, 1, 1, 0,101, 1, 11, 9, 0, 0, 20, 0, 0, 0, 12, 9, - 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,152, 7, 2, 0,185, 7, 2, 0, 13, 9, 2, 0,133, 0, 2, 0, 2, 9, 2, 0,142, 7, - 12, 0, 36, 8, 12, 0, 14, 9, 27, 0, 81, 6, 9, 0, 15, 9, 7, 0, 5, 9, 7, 0, 6, 9, 7, 0, 52, 2, 7, 0, 16, 9, - 2, 0, 17, 9, 2, 0, 18, 9, 7, 0, 19, 9, 7, 0, 20, 9, 2, 0, 21, 9, 2, 0, 22, 9, 9, 0, 23, 9, 24, 0, 24, 9, - 24, 0, 25, 9, 24, 0, 26, 9,102, 1,150, 0,103, 1, 27, 9,100, 1, 8, 0,100, 1, 0, 0,100, 1, 1, 0,101, 1, 28, 9, -101, 1, 29, 9, 99, 1, 30, 9, 99, 1, 9, 9, 4, 0, 19, 0, 4, 0, 37, 0, 61, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0, - 12, 0, 31, 9, 12, 0, 32, 9, 98, 1, 33, 9, 12, 0, 34, 9, 4, 0, 17, 0, 4, 0, 35, 9, 4, 0, 36, 9, 4, 0, 37, 9, - 12, 0, 38, 9,103, 1, 39, 9, 99, 1, 40, 9, 99, 1, 41, 9, 9, 0, 42, 9, 9, 0, 43, 9, 4, 0, 44, 9, 9, 0, 45, 9, - 9, 0, 46, 9, 9, 0, 47, 9,104, 1, 6, 0, 4, 0,124, 0, 4, 0,126, 0, 4, 0,142, 7, 0, 0, 48, 9, 0, 0, 49, 9, - 2, 0, 37, 0,105, 1, 16, 0, 2, 0, 98, 7, 2, 0, 99, 7, 2, 0, 50, 9, 2, 0, 90, 8, 2, 0, 51, 9, 2, 0, 68, 0, - 7, 0,212, 2, 7, 0, 52, 9, 7, 0, 53, 9, 2, 0, 60, 1, 0, 0, 54, 9, 0, 0, 55, 5, 2, 0, 55, 9, 2, 0, 37, 0, - 4, 0, 56, 9, 4, 0, 57, 9,106, 1, 9, 0, 7, 0, 58, 9, 7, 0, 59, 9, 7, 0,109, 8, 7, 0,109, 0, 7, 0, 60, 9, - 7, 0, 10, 6, 2, 0, 61, 9, 0, 0, 62, 9, 0, 0, 37, 0,107, 1, 4, 0, 7, 0, 63, 9, 7, 0, 64, 9, 2, 0, 61, 9, - 2, 0, 37, 0,108, 1, 3, 0, 7, 0, 65, 9, 7, 0, 66, 9, 7, 0, 15, 0,109, 1, 7, 0, 0, 0,239, 1, 2, 0,185, 4, - 2, 0,186, 4, 2, 0,187, 4, 2, 0,138, 4, 4, 0,126, 0, 4, 0,250, 3,110, 1, 7, 0, 7, 0, 67, 9, 7, 0, 68, 9, - 7, 0, 69, 9, 7, 0, 63, 2, 7, 0, 70, 9, 7, 0, 71, 9, 7, 0, 72, 9,111, 1, 4, 0, 2, 0, 73, 9, 2, 0, 74, 9, - 2, 0, 75, 9, 2, 0, 76, 9,112, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0,113, 1, 2, 0, 0, 0,166, 0, 0, 0, 77, 9, -114, 1, 1, 0, 0, 0, 20, 0,115, 1, 10, 0, 0, 0, 78, 9, 0, 0, 79, 9, 0, 0, 3, 6, 0, 0, 80, 9, 2, 0, 50, 9, - 2, 0, 81, 9, 7, 0, 82, 9, 7, 0, 83, 9, 7, 0, 84, 9, 7, 0,247, 8,116, 1, 2, 0, 9, 0, 85, 9, 9, 0, 86, 9, -117, 1, 11, 0, 0, 0,187, 4, 0, 0, 17, 0, 0, 0, 61, 9, 0, 0,109, 0, 0, 0, 87, 9, 0, 0,106, 0, 0, 0, 48, 2, - 7, 0, 88, 9, 7, 0, 89, 9, 7, 0, 90, 9, 7, 0, 91, 9,118, 1, 8, 0, 7, 0, 3, 8, 7, 0,125, 0, 7, 0, 55, 5, - 7, 0,134, 2, 7, 0, 92, 9, 7, 0,206, 0, 7, 0, 93, 9, 4, 0, 17, 0,119, 1, 4, 0, 2, 0, 94, 9, 2, 0, 95, 9, - 2, 0, 96, 9, 2, 0, 37, 0,120, 1, 1, 0, 0, 0, 20, 0,121, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 19, 0, - 2, 0, 97, 9,122, 1, 10, 0, 2, 0,182, 3, 2, 0, 19, 0, 7, 0, 74, 4, 7, 0, 98, 9, 7, 0, 99, 9, 7, 0,100, 9, - 7, 0,101, 9,121, 1,102, 9,121, 1,103, 9,121, 1,104, 9, 64, 0, 9, 0, 4, 0, 19, 0, 4, 0, 64, 0, 24, 0,105, 9, - 24, 0,106, 9,122, 1,107, 9, 7, 0,108, 9, 7, 0,109, 9, 7, 0,110, 9, 7, 0,111, 9,123, 1, 4, 0, 47, 0,206, 2, - 7, 0,112, 9, 7, 0,141, 1, 7, 0, 37, 0,187, 0, 17, 0, 27, 0, 31, 0,123, 1,113, 9, 64, 0,102, 9, 51, 0,103, 1, - 2, 0, 19, 0, 2, 0,160, 5, 4, 0,106, 0, 7, 0,114, 9, 7, 0, 60, 2, 4, 0,115, 9, 7, 0,116, 9, 7, 0,117, 9, - 7, 0,118, 9, 7, 0,141, 1, 2, 0, 73, 1, 0, 0,119, 9, 0, 0,139, 6,124, 1, 10, 0, 4, 0, 17, 0, 4, 0,125, 0, - 4, 0, 19, 0, 4, 0,148, 3, 4, 0,120, 9, 4, 0,121, 9, 4, 0,122, 9, 0, 0, 92, 0, 0, 0, 20, 0, 9, 0, 2, 0, - 92, 0, 6, 0,124, 1,123, 9, 4, 0,124, 9, 4, 0,125, 9, 4, 0,126, 9, 4, 0, 37, 0, 9, 0,127, 9,125, 1, 5, 0, - 7, 0,129, 2, 7, 0,196, 2, 7, 0, 14, 2, 2, 0,128, 9, 2, 0, 37, 0,126, 1, 5, 0, 7, 0,129, 2, 7, 0,129, 9, - 7, 0,130, 9, 7, 0,131, 9, 7, 0,196, 2,127, 1, 5, 0, 32, 0,132, 9,128, 1, 22, 0, 7, 0,133, 9, 7, 0,134, 9, - 7, 0, 57, 0,129, 1, 7, 0, 4, 0,135, 9, 4, 0,136, 9, 4, 0,137, 9, 7, 0,138, 9, 7, 0,139, 9, 7, 0,140, 9, - 7, 0,141, 9,130, 1, 8, 0,130, 1, 0, 0,130, 1, 1, 0, 32, 0, 45, 0, 4, 0, 14, 3, 2, 0, 19, 0, 2, 0, 40, 1, - 7, 0,196, 2, 7, 0, 11, 8,131, 1, 18, 0,126, 1,143, 3,126, 1,142, 9,125, 1,143, 9,126, 1,251, 7,127, 1,144, 9, - 4, 0, 82, 0, 7, 0,196, 2, 7, 0,223, 2, 7, 0,145, 9, 4, 0,135, 9, 4, 0,146, 9, 7, 0,139, 9, 7, 0,140, 9, - 7, 0,106, 0, 2, 0, 19, 0, 2, 0,147, 9, 2, 0,148, 9, 2, 0,149, 9,132, 1,107, 0, 27, 0, 31, 0, 39, 0, 75, 0, -133, 1,150, 9, 4, 0, 19, 0, 2, 0, 17, 0, 2, 0,228, 8, 2, 0,151, 9, 2, 0,152, 9, 2, 0,159, 8, 2, 0,153, 9, - 2, 0,154, 9, 2, 0,155, 9, 2, 0,156, 9, 2, 0,157, 9, 2, 0,158, 9, 2, 0,159, 9, 2, 0,178, 3, 2, 0, 48, 5, - 2, 0,160, 9, 2, 0,161, 9, 2, 0,162, 9, 2, 0,163, 9, 2, 0,164, 9, 2, 0, 3, 2, 2, 0,244, 7, 2, 0,220, 7, - 2, 0,165, 9, 2, 0,166, 9, 2, 0,176, 3, 2, 0,177, 3, 2, 0,167, 9, 2, 0,168, 9, 2, 0,169, 9, 2, 0,170, 9, - 7, 0,171, 9, 7, 0,172, 9, 7, 0,173, 9, 2, 0,174, 9, 2, 0,175, 9, 7, 0,176, 9, 7, 0,177, 9, 7, 0,178, 9, - 7, 0,226, 7, 7, 0, 89, 0, 7, 0,223, 2, 7, 0,232, 7, 7, 0,179, 9, 7, 0,180, 9, 7, 0,181, 9, 4, 0,227, 7, - 4, 0,225, 7, 4, 0,182, 9, 7, 0,228, 7, 7, 0,229, 7, 7, 0,230, 7, 7, 0,183, 9, 7, 0,184, 9, 7, 0,185, 9, - 7, 0,186, 9, 7, 0,187, 9, 7, 0,188, 9, 7, 0,189, 9, 7, 0,190, 9, 7, 0,100, 3, 7, 0,106, 0, 7, 0,191, 9, - 7, 0,192, 9, 7, 0,193, 9, 7, 0,194, 9, 7, 0,195, 9, 7, 0,196, 9, 7, 0,197, 9, 4, 0,198, 9, 4, 0,199, 9, - 7, 0,200, 9, 7, 0,201, 9, 7, 0,202, 9, 7, 0,203, 9, 7, 0,204, 9, 7, 0,205, 9, 7, 0,206, 9, 7, 0,172, 3, - 7, 0,170, 3, 7, 0,171, 3, 7, 0,207, 9, 7, 0,208, 9, 7, 0,209, 9, 7, 0,210, 9, 7, 0,211, 9, 7, 0,212, 9, - 7, 0,213, 9, 7, 0,214, 9, 7, 0,215, 9, 7, 0,216, 9, 7, 0,217, 9, 7, 0,218, 9, 7, 0,219, 9, 4, 0,220, 9, - 4, 0,221, 9, 7, 0,222, 9, 68, 0,132, 3, 68, 0,223, 9, 32, 0,224, 9, 32, 0,225, 9, 36, 0, 80, 0,163, 0, 32, 1, -163, 0,226, 9, 59, 0, 43, 0, 59, 0, 0, 0, 59, 0, 1, 0,132, 1,227, 9,131, 1,228, 9,129, 1,153, 8,168, 0,198, 3, - 9, 0,199, 3,134, 1,229, 9,134, 1,230, 9, 12, 0,231, 9, 12, 0,232, 9,134, 0,233, 9,142, 0,234, 9,142, 0,235, 9, - 32, 0,236, 9, 32, 0,237, 9, 32, 0, 38, 0, 12, 0,238, 9, 12, 0,239, 9, 12, 0,198, 8, 0, 0, 20, 0, 7, 0,210, 0, - 7, 0,250, 2, 7, 0,240, 9, 4, 0,170, 2, 4, 0, 57, 0, 4, 0, 19, 0, 4, 0,227, 7, 4, 0,241, 9, 4, 0,242, 9, - 4, 0,243, 9, 2, 0,217, 0, 2, 0,244, 9, 2, 0,245, 9, 2, 0,246, 9, 0, 0,247, 9, 2, 0,248, 9, 2, 0,249, 9, - 2, 0,250, 9, 9, 0,251, 9,138, 0, 15, 4, 12, 0,237, 2,135, 1,252, 9,136, 0, 34, 0,136, 1,110, 8, 7, 0,241, 3, - 7, 0,253, 9, 7, 0,254, 9, 7, 0, 77, 4, 7, 0,255, 9, 7, 0,110, 3, 7, 0,100, 3, 7, 0, 0, 10, 7, 0, 62, 2, - 7, 0, 1, 10, 7, 0, 2, 10, 7, 0, 3, 10, 7, 0, 4, 10, 7, 0, 5, 10, 7, 0, 6, 10, 7, 0,242, 3, 7, 0, 7, 10, - 7, 0, 8, 10, 7, 0, 9, 10, 7, 0,243, 3, 7, 0,239, 3, 7, 0,240, 3, 7, 0, 10, 10, 4, 0, 11, 10, 4, 0, 90, 0, - 4, 0, 12, 10, 4, 0, 13, 10, 2, 0, 14, 10, 2, 0, 15, 10, 2, 0, 16, 10, 2, 0, 17, 10, 2, 0, 18, 10, 2, 0, 37, 0, -137, 0, 8, 0,136, 1, 19, 10, 7, 0, 20, 10, 7, 0, 21, 10, 7, 0,213, 1, 7, 0, 22, 10, 4, 0, 90, 0, 2, 0, 23, 10, - 2, 0, 24, 10,137, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 25, 10,138, 1, 6, 0,138, 1, 0, 0, -138, 1, 1, 0,137, 1,144, 8, 4, 0,223, 0, 2, 0, 26, 10, 2, 0, 19, 0,139, 1, 5, 0,139, 1, 0, 0,139, 1, 1, 0, - 12, 0, 27, 10, 4, 0, 28, 10, 4, 0, 19, 0,140, 1, 9, 0,140, 1, 0, 0,140, 1, 1, 0, 12, 0,124, 0,139, 1, 29, 10, - 4, 0, 19, 0, 2, 0, 26, 10, 2, 0, 30, 10, 7, 0, 91, 0, 0, 0, 31, 10,161, 0, 6, 0, 27, 0, 31, 0, 12, 0,201, 4, - 4, 0, 19, 0, 2, 0, 32, 10, 2, 0, 33, 10, 9, 0, 34, 10,141, 1, 7, 0,141, 1, 0, 0,141, 1, 1, 0, 2, 0, 17, 0, - 2, 0, 19, 0, 4, 0, 23, 0, 0, 0, 35, 10, 0, 0, 36, 10,142, 1, 5, 0, 12, 0, 37, 10, 4, 0, 38, 10, 4, 0, 39, 10, - 4, 0, 19, 0, 4, 0, 37, 0,143, 1, 13, 0, 27, 0, 31, 0,144, 1, 40, 10,144, 1, 41, 10, 12, 0, 42, 10, 4, 0, 43, 10, - 2, 0, 44, 10, 2, 0, 37, 0, 12, 0, 45, 10, 12, 0, 46, 10,142, 1, 47, 10, 12, 0, 48, 10, 12, 0, 49, 10, 12, 0, 50, 10, -144, 1, 30, 0,144, 1, 0, 0,144, 1, 1, 0, 9, 0, 51, 10, 4, 0, 77, 7, 4, 0, 37, 0,211, 0,248, 5,211, 0, 52, 10, - 0, 0, 53, 10, 2, 0, 54, 10, 2, 0, 55, 10, 2, 0, 98, 7, 2, 0, 99, 7, 2, 0, 56, 10, 2, 0, 57, 10, 2, 0,148, 3, - 2, 0,107, 6, 2, 0, 58, 10, 2, 0, 59, 10, 4, 0,209, 1,145, 1, 60, 10,146, 1, 61, 10,147, 1, 62, 10, 4, 0, 63, 10, - 4, 0, 64, 10, 9, 0, 65, 10, 12, 0, 66, 10, 12, 0, 46, 10, 12, 0,116, 7, 12, 0, 67, 10, 12, 0, 68, 10,148, 1, 16, 0, -148, 1, 0, 0,148, 1, 1, 0, 0, 0, 69, 10,149, 1, 70, 10, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 71, 10, 2, 0, 72, 10, - 2, 0, 73, 10, 2, 0, 74, 10, 2, 0, 75, 10, 2, 0, 76, 10, 2, 0, 77, 10, 2, 0, 78, 10, 2, 0, 70, 0, 2, 0,209, 1, -150, 1, 9, 0,150, 1, 0, 0,150, 1, 1, 0, 12, 0, 79, 10, 0, 0, 80, 10, 2, 0, 81, 10, 2, 0, 82, 10, 2, 0, 83, 10, - 2, 0, 37, 0, 9, 0, 84, 10,219, 0, 12, 0,219, 0, 0, 0,219, 0, 1, 0, 0, 0, 69, 10, 26, 0, 30, 0,151, 1, 92, 7, - 9, 0, 85, 10,149, 1, 70, 10,142, 1, 86, 10, 12, 0, 87, 10,219, 0, 88, 10, 2, 0, 19, 0, 2, 0,105, 1,145, 1, 23, 0, -145, 1, 0, 0,145, 1, 1, 0, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 5, 0, 2, 0, 6, 0, 2, 0, 89, 10, 2, 0, 90, 10, - 2, 0, 91, 10, 2, 0, 92, 10, 0, 0, 93, 10, 0, 0, 37, 0, 2, 0, 71, 10, 2, 0, 72, 10, 2, 0, 73, 10, 2, 0, 74, 10, - 2, 0, 75, 10, 2, 0, 43, 0, 0, 0, 94, 10, 2, 0, 95, 10, 2, 0, 96, 10, 4, 0, 70, 0, 9, 0, 85, 10,152, 1, 8, 0, -152, 1, 0, 0,152, 1, 1, 0, 9, 0, 2, 0, 9, 0, 97, 10, 0, 0,193, 3, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0, 98, 10, -153, 1, 5, 0, 7, 0, 99, 10, 4, 0,100, 10, 4, 0,101, 10, 4, 0, 40, 1, 4, 0, 19, 0,154, 1, 6, 0, 7, 0,102, 10, - 7, 0,103, 10, 7, 0,104, 10, 7, 0,105, 10, 4, 0, 17, 0, 4, 0, 19, 0,155, 1, 5, 0, 7, 0, 67, 8, 7, 0, 68, 8, - 7, 0,196, 2, 2, 0, 17, 2, 2, 0, 18, 2,156, 1, 5, 0,155, 1, 2, 0, 4, 0, 54, 0, 7, 0,106, 10, 7, 0, 67, 8, - 7, 0, 68, 8,157, 1, 4, 0, 2, 0,107, 10, 2, 0,108, 10, 2, 0,109, 10, 2, 0,110, 10,158, 1, 2, 0, 42, 0, 78, 6, - 26, 0,147, 8,159, 1, 3, 0, 24, 0,111, 10, 4, 0, 19, 0, 4, 0, 37, 0,160, 1, 6, 0, 7, 0,106, 0, 7, 0,198, 2, - 7, 0,112, 10, 7, 0, 37, 0, 2, 0,216, 0, 2, 0,113, 10,161, 1, 7, 0,161, 1, 0, 0,161, 1, 1, 0, 27, 0, 81, 6, - 0, 0,114, 10, 4, 0,115, 10, 4, 0, 90, 0, 0, 0,193, 3,162, 1, 6, 0, 12, 0,198, 8, 0, 0,116, 10, 7, 0, 61, 0, - 7, 0, 98, 10, 4, 0, 17, 0, 4, 0, 19, 0,163, 1, 3, 0, 7, 0,117, 10, 4, 0, 19, 0, 4, 0, 37, 0,164, 1, 15, 0, -164, 1, 0, 0,164, 1, 1, 0, 70, 1,186, 8,162, 1, 62, 0, 12, 0, 73, 3, 35, 0, 50, 0,163, 1,118, 10, 4, 0, 54, 0, - 7, 0, 61, 0, 2, 0, 19, 0, 2, 0, 25, 1, 4, 0,115, 10, 0, 0,114, 10, 4, 0,119, 10, 7, 0,120, 10,165, 1, 2, 0, - 0, 0,121, 10, 0, 0,122, 10,166, 1, 4, 0,166, 1, 0, 0,166, 1, 1, 0,159, 0, 27, 3, 12, 0,123, 10,167, 1, 24, 0, -167, 1, 0, 0,167, 1, 1, 0, 12, 0,124, 10,159, 0, 41, 8,166, 1,125, 10, 12, 0,126, 10, 12, 0, 73, 3, 0, 0,193, 3, - 7, 0, 98, 10, 7, 0,127, 10, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0,243, 8, 7, 0,244, 8, 7, 0,213, 2, 7, 0,247, 8, - 7, 0, 43, 8, 7, 0,248, 8, 2, 0,128, 10, 2, 0,129, 10, 2, 0, 43, 0, 2, 0, 17, 0, 4, 0, 19, 0, 4, 0, 70, 0, -168, 1, 6, 0,168, 1, 0, 0,168, 1, 1, 0, 12, 0,124, 10, 4, 0, 19, 0, 4, 0,133, 2, 0, 0,193, 3,169, 1, 10, 0, -169, 1, 0, 0,169, 1, 1, 0, 27, 0, 81, 6, 0, 0,130, 10, 4, 0,131, 10, 4, 0,132, 10, 0, 0,114, 10, 4, 0,115, 10, - 2, 0, 19, 0, 2, 0,133, 10,170, 1, 6, 0,170, 1, 0, 0,170, 1, 1, 0, 12, 0,134, 10, 0, 0,193, 3, 4, 0, 19, 0, - 4, 0,135, 10,171, 1, 5, 0,171, 1, 0, 0,171, 1, 1, 0, 0, 0,114, 10, 4, 0,115, 10, 7, 0,186, 2, 39, 0, 12, 0, -159, 0, 67, 3,159, 0,136, 10,166, 1,125, 10, 12, 0,137, 10,167, 1,138, 10, 12, 0,139, 10, 12, 0,140, 10, 4, 0, 19, 0, - 4, 0,217, 0, 2, 0,141, 10, 2, 0,142, 10, 7, 0,143, 10,172, 1, 2, 0, 27, 0, 31, 0, 39, 0, 75, 0,173, 1, 5, 0, -173, 1, 0, 0,173, 1, 1, 0, 4, 0, 17, 0, 4, 0, 19, 0, 0, 0, 20, 0,174, 1, 6, 0,173, 1,144, 10, 32, 0, 45, 0, - 4, 0,145, 10, 7, 0,146, 10, 4, 0,147, 10, 4, 0,175, 8,175, 1, 3, 0,173, 1,144, 10, 4, 0,145, 10, 7, 0,148, 10, -176, 1, 8, 0,173, 1,144, 10, 32, 0, 45, 0, 7, 0, 35, 1, 7, 0,149, 10, 7, 0,250, 2, 7, 0,109, 8, 4, 0,145, 10, - 4, 0,150, 10,177, 1, 5, 0,173, 1,144, 10, 7, 0,151, 10, 7, 0,185, 7, 7, 0,219, 2, 7, 0, 57, 0,178, 1, 3, 0, -173, 1,144, 10, 7, 0,109, 8, 7, 0,152, 10,128, 1, 4, 0, 7, 0,153, 10, 7, 0,193, 9, 2, 0,154, 10, 2, 0, 40, 1, -179, 1, 14, 0,179, 1, 0, 0,179, 1, 1, 0, 12, 0,155, 10, 12, 0,156, 10, 12, 0,157, 10, 0, 0, 20, 0, 4, 0, 31, 0, - 4, 0, 19, 0, 4, 0,158, 10, 7, 0,159, 10, 4, 0,147, 10, 4, 0,175, 8, 7, 0,202, 3, 7, 0,221, 2,133, 1, 23, 0, - 4, 0,145, 10, 4, 0,160, 10, 7, 0,161, 10, 7, 0, 57, 0, 7, 0,162, 10, 7, 0,217, 2, 7, 0,153, 10, 7, 0,163, 10, - 7, 0,198, 2, 7, 0,164, 10, 7, 0, 74, 4, 7, 0,165, 10, 7, 0,166, 10, 7, 0,167, 10, 7, 0,168, 10, 7, 0,169, 10, - 7, 0,170, 10, 7, 0,171, 10, 7, 0,172, 10, 7, 0,173, 10, 7, 0,174, 10, 7, 0,175, 10, 12, 0,176, 10,122, 0, 33, 0, -121, 0,177, 10,180, 1,178, 10, 68, 0,179, 10, 68, 0,223, 9, 68, 0,180, 10,181, 1,181, 10, 48, 0,165, 0, 48, 0,182, 10, - 48, 0,183, 10, 7, 0,184, 10, 7, 0,185, 10, 7, 0,186, 10, 7, 0,187, 10, 7, 0,188, 10, 7, 0,187, 8, 7, 0,189, 10, - 7, 0,141, 1, 7, 0,190, 10, 4, 0,191, 10, 4, 0,192, 10, 4, 0,193, 10, 4, 0, 90, 0, 4, 0, 37, 0, 4, 0,194, 10, - 2, 0,195, 10, 2, 0,196, 10, 4, 0,197, 10, 7, 0,198, 2, 4, 0,198, 10, 7, 0,199, 10, 4, 0,200, 10,138, 0,201, 10, - 12, 0,202, 10,123, 0, 11, 0,121, 0,177, 10, 59, 0,225, 0, 7, 0,106, 1, 7, 0,187, 8, 7, 0,203, 10, 7, 0,204, 10, - 2, 0,205, 10, 2, 0,206, 10, 2, 0,207, 10, 2, 0, 17, 0, 4, 0, 37, 0,124, 0, 13, 0,121, 0,177, 10,140, 0,247, 2, -142, 0,249, 2, 7, 0,144, 8, 7, 0,208, 10, 7, 0,209, 10, 7, 0, 37, 1, 7, 0,210, 10, 4, 0,211, 10, 4, 0,245, 2, +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, 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, 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, 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, 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, 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, 84,114, 97,110,115,102,111,114,109, 79,114,105,101,110,116, 97,116,105,111,110, 0, 83, 99,117,108,112,116, 0, 86, 80, 97, +105,110,116, 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, 66, 71,112,105, 99, 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,116,111,112,111, 86,105,101,119, 68, 97,116, 97, 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, 98, 83, 99,114,101,101,110, 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,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, 0, 83,112, 97, 99,101, 78,111,100,101, 0, 83,112, 97, 99,101, 76,111,103,105, 99, 0, 83, +112, 97, 99,101, 73,109, 97, 83,101,108, 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,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, 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, 83,111,108,105,100, 76,105, +103,104,116, 0, 85,115,101,114, 68,101,102, 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, 84, 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, 83,111,117,110,100, 72, 97,110,100,108,101, 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, + 98, 83,111,117,110,100, 65, 99,116,117, 97,116,111,114, 0, 83,111,117,110,100, 51, 68, 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, 70,114,101,101, 67, 97,109,101,114, 97, 0, 83,112, 97, 99,101, 83,111,117,110,100, 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, 77,111,116,105,111,110, 80, 97,116,104, 0, 98, 65,110,105,109, 86,105,122, 83,101,116,116,105,110,103, +115, 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, + 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, 77, +105,110, 77, 97,120, 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, 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, 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, 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, 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, 0, 98, 78,111,100,101, 80,114,101,118, +105,101,119, 0,117,105, 66,108,111, 99,107, 0, 98, 78,111,100,101, 84,121,112,101, 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, 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, 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, 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, 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, 97,116, 97, 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, 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, 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,109, 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, 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, 68,114,105,118,101,114, 84, 97,114,103,101,116, 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, 84, 76, 69, 78, 1, 0, 1, 0, + 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 0, 12, 0, 8, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, + 12, 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 20, 0, 76, 0, 52, 0, 40, 2, 0, 0, 32, 0,140, 0,136, 3, 92, 0, + 36, 0, 56, 0, 84, 0,112, 0,124, 0, 56, 0, 24, 0, 40, 0,120, 0, 12, 0,120, 0, 36, 0,108, 5,128, 1, 0, 0, 0, 0, + 0, 0, 8, 1, 40, 1, 84, 1, 24, 0, 8, 3,168, 0, 0, 0, 76, 0,124, 1, 24, 1,140, 0,132, 0,124, 1, 8, 1, 56, 0, + 88, 0,160, 2, 76, 0, 60, 1, 0, 0,108, 0,104, 0,148, 0, 56, 0, 8, 0, 16, 0, 92, 1, 0, 0, 0, 0, 0, 0, 24, 1, + 20, 0, 44, 0, 60, 0, 24, 0, 12, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0, 24, 0, 76, 0, 32, 0, 8, 0, 12, 0, 8, 0, + 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 12, 0, 0, 0, 16, 0, 64, 0, 24, 0, 12, 0, 40, 0, 56, 0, 72, 0, 92, 0,100, 0, + 72, 0,100, 0,120, 0, 68, 0, 64, 0,112, 0, 64, 0, 76, 0,176, 0, 48, 0,168, 0,152, 0,156, 0, 64, 0, 96, 0,108, 0, +188, 0,104, 0,216, 0, 56, 0, 84, 0, 0, 0,136, 0, 28, 0,240, 1,104, 0, 0, 0, 80, 0, 0, 0, 0, 0, 68, 0, 8, 0, + 8, 0,220, 0, 80, 0, 76, 0, 68, 0, 68, 0, 64, 0,168, 1,112, 0,108, 0,188, 0, 40, 0, 0, 0, 92, 0, 64, 0, 72, 0, +120, 0,144, 0, 0, 1,208, 0,180, 0, 0, 0, 68, 0, 92, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,104, 1, 28, 0,176, 0, +144, 0, 60, 0, 24, 0, 72, 0,248, 3, 56, 0, 20, 0, 16, 0, 92, 0, 80, 0, 24, 0,196, 0, 36, 0, 8, 0,100, 0, 80, 0, + 48, 0, 52, 0, 72, 1, 32, 0, 8, 0, 16, 0, 24, 2, 0, 0, 0, 0, 56, 0,216, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +240, 0, 40, 0,148, 0, 48, 0,140, 0,208, 0, 20, 0,224, 0,216, 0,204, 1, 60, 0, 0, 0,112, 0, 0, 0, 4, 1, 12, 0, + 12, 0,136, 0,200, 0,124, 2, 80, 2, 40, 0,180, 0,244, 0, 52, 0,148, 2, 28, 0, 80, 0, 24, 0, 16, 1, 32, 0,224, 0, + 32, 0, 32, 0, 80, 2, 16, 1, 16, 0,200, 21, 56, 0, 56, 11, 20, 0, 24, 0, 56, 1, 0, 0, 0, 0, 96, 0, 0, 0,248, 0, + 0, 0, 32, 0, 80, 0, 28, 0, 16, 0, 8, 0, 52, 0,252, 0,240, 0,168, 1,196, 0, 8, 1, 48, 0, 16, 0, 12, 0, 24, 0, + 48, 0, 16, 0, 20, 0, 16, 0, 24, 0, 56, 1, 0, 0, 56, 0, 52, 0, 48, 0, 8, 0, 44, 0, 72, 0,104, 0, 40, 0, 8, 0, + 72, 0, 44, 0, 40, 0,108, 0, 72, 0, 68, 0, 76, 0, 80, 0, 60, 0,128, 0, 76, 0, 60, 0, 12, 0, 92, 0, 68, 0, 32, 0, + 80, 0, 16, 0, 76, 0,108, 0, 84, 0, 28, 0, 96, 0, 56, 0, 56, 0,108, 0,140, 0, 4, 0, 20, 0, 12, 0, 8, 0, 80, 0, + 40, 0,196, 0, 24, 0, 4, 1,128, 0, 16, 0, 20, 0, 24, 0,180, 1, 4, 0, 40, 0,104, 0,228, 0, 64, 0, 44, 0, 72, 0, +116, 0, 60, 0,112, 0, 52, 0, 44, 0, 44, 0, 68, 0, 44, 0, 64, 0, 44, 0, 20, 0, 52, 0, 96, 0, 12, 0,108, 0, 92, 0, + 28, 0, 28, 0, 28, 0, 52, 0, 20, 0, 60, 0,140, 0, 36, 0,120, 0, 32, 0,212, 0, 0, 0, 0, 0, 0, 0, 16, 0, 40, 0, + 28, 0, 12, 0, 12, 0, 16, 1, 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 8, 0, 24, 0, 32, 0, 8, 0, 32, 0, 12, 0, + 44, 0, 20, 0, 68, 0, 24, 0, 56, 0, 52, 0, 20, 0, 64, 0, 28, 0,180, 0,172, 1, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 20, 0, 24, 0,172, 0, 24, 0, 24, 0,140, 0,156, 0, 56, 0, 0, 0, 0, 0,100, 0, 0, 0, 96, 0, 0, 0, 88, 0, + 20, 0, 24, 0, 16, 0, 20, 0, 8, 0, 8, 0, 24, 0, 20, 0, 88, 0, 24, 1, 16, 0, 68, 0, 0, 1, 20, 0,160, 0, 88, 0, + 96, 0, 88, 0, 20, 0, 56, 0, 48, 0, 68, 0, 56, 0, 92, 0, 64, 0, 56, 0, 96, 0, 0, 0, 0, 0, 0, 0, 83, 84, 82, 67, +133, 1, 0, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 3, 0, 11, 0, 0, 0, 11, 0, 1, 0, 9, 0, 2, 0, + 12, 0, 2, 0, 9, 0, 3, 0, 9, 0, 4, 0, 13, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, 14, 0, 2, 0, 4, 0, 5, 0, + 4, 0, 6, 0, 15, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 16, 0, 2, 0, 8, 0, 5, 0, 8, 0, 6, 0, 17, 0, 3, 0, + 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 18, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 19, 0, 3, 0, + 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 20, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 4, 0, 8, 0, + 21, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 8, 0, 22, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, + 8, 0, 7, 0, 8, 0, 8, 0, 23, 0, 4, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 4, 0, 12, 0, 24, 0, 4, 0, + 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 25, 0, 4, 0, 9, 0, 13, 0, 12, 0, 14, 0, 4, 0, 15, 0, + 4, 0, 16, 0, 26, 0, 10, 0, 26, 0, 0, 0, 26, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19, 0, 0, 0, 20, 0, + 4, 0, 21, 0, 25, 0, 22, 0, 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 27, 0, 25, 0, + 28, 0, 26, 0, 0, 0, 27, 0, 2, 0, 28, 0, 2, 0, 19, 0, 4, 0, 29, 0, 26, 0, 30, 0, 28, 0, 8, 0, 27, 0, 31, 0, + 27, 0, 32, 0, 29, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 4, 0, 36, 0, 4, 0, 37, 0, 28, 0, 38, 0, 30, 0, 6, 0, + 4, 0, 39, 0, 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, 2, 0, 43, 0, 4, 0, 44, 0, 31, 0, 6, 0, 32, 0, 45, 0, + 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0, 48, 0, 33, 0, 21, 0, 33, 0, 0, 0, 33, 0, 1, 0, + 34, 0, 49, 0, 35, 0, 50, 0, 24, 0, 51, 0, 24, 0, 52, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 53, 0, 2, 0, 54, 0, + 2, 0, 55, 0, 2, 0, 56, 0, 2, 0, 19, 0, 2, 0, 57, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, 0, 58, 0, 7, 0, 59, 0, + 7, 0, 60, 0, 7, 0, 61, 0, 31, 0, 62, 0, 36, 0, 7, 0, 27, 0, 31, 0, 12, 0, 63, 0, 24, 0, 64, 0, 2, 0, 46, 0, + 2, 0, 65, 0, 2, 0, 66, 0, 2, 0, 37, 0, 37, 0, 16, 0, 37, 0, 0, 0, 37, 0, 1, 0, 7, 0, 67, 0, 7, 0, 61, 0, + 2, 0, 17, 0, 2, 0, 47, 0, 2, 0, 68, 0, 2, 0, 19, 0, 4, 0, 69, 0, 4, 0, 70, 0, 9, 0, 2, 0, 7, 0, 71, 0, + 0, 0, 20, 0, 0, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0, 38, 0, 13, 0, 27, 0, 31, 0, 39, 0, 75, 0, 37, 0, 76, 0, + 0, 0, 77, 0, 4, 0, 78, 0, 7, 0, 61, 0, 12, 0, 79, 0, 36, 0, 80, 0, 27, 0, 81, 0, 2, 0, 17, 0, 2, 0, 82, 0, + 2, 0, 83, 0, 2, 0, 19, 0, 40, 0, 6, 0, 40, 0, 0, 0, 40, 0, 1, 0, 0, 0, 84, 0, 0, 0, 85, 0, 4, 0, 23, 0, + 4, 0, 86, 0, 41, 0, 10, 0, 41, 0, 0, 0, 41, 0, 1, 0, 4, 0, 87, 0, 4, 0, 88, 0, 4, 0, 89, 0, 4, 0, 43, 0, + 4, 0, 14, 0, 4, 0, 90, 0, 0, 0, 91, 0, 0, 0, 92, 0, 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 93, 0, 4, 0, 90, 0, + 4, 0, 94, 0, 12, 0, 95, 0, 40, 0, 96, 0, 40, 0, 97, 0, 4, 0, 98, 0, 4, 0, 99, 0, 12, 0,100, 0, 0, 0,101, 0, + 4, 0,102, 0, 4, 0,103, 0, 9, 0,104, 0, 8, 0,105, 0, 43, 0, 3, 0, 4, 0,106, 0, 4, 0,107, 0, 9, 0, 2, 0, + 44, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0,108, 0, 7, 0,109, 0, 7, 0,110, 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, + 2, 0,119, 0, 2, 0,120, 0, 7, 0,121, 0, 36, 0, 80, 0, 32, 0,122, 0, 45, 0, 13, 0, 4, 0,123, 0, 4, 0,124, 0, + 4, 0,125, 0, 4, 0,126, 0, 2, 0,127, 0, 2, 0,128, 0, 2, 0, 19, 0, 2, 0,129, 0, 2, 0,130, 0, 2, 0,131, 0, + 2, 0,132, 0, 2, 0,133, 0, 46, 0,134, 0, 47, 0, 32, 0, 27, 0, 31, 0, 0, 0, 34, 0, 12, 0,135, 0, 48, 0,136, 0, + 49, 0,137, 0, 50, 0,138, 0, 2, 0,129, 0, 2, 0, 19, 0, 2, 0,139, 0, 2, 0, 17, 0, 2, 0, 37, 0, 2, 0, 43, 0, + 4, 0,140, 0, 2, 0,141, 0, 2, 0,142, 0, 2, 0,143, 0, 2, 0,144, 0, 2, 0,145, 0, 2, 0,146, 0, 4, 0,147, 0, + 4, 0,148, 0, 43, 0,149, 0, 30, 0,150, 0, 0, 0,151, 0, 7, 0,152, 0, 4, 0,153, 0, 2, 0,154, 0, 2, 0,155, 0, + 2, 0,156, 0, 2, 0,157, 0, 7, 0,158, 0, 7, 0,159, 0, 51, 0, 63, 0, 2, 0,160, 0, 2, 0,161, 0, 2, 0,162, 0, + 2, 0,163, 0, 32, 0,164, 0, 52, 0,165, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, + 7, 0,171, 0, 7, 0,172, 0, 7, 0,173, 0, 2, 0,174, 0, 2, 0,175, 0, 2, 0,176, 0, 2, 0,177, 0, 2, 0,178, 0, + 2, 0,179, 0, 0, 0,180, 0, 0, 0,181, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, 7, 0,185, 0, 7, 0,186, 0, + 7, 0, 57, 0, 7, 0,187, 0, 7, 0,188, 0, 7, 0,189, 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, 53, 0, 15, 0, 0, 0,222, 0, 9, 0,223, 0, 0, 0,224, 0, + 0, 0,225, 0, 4, 0,226, 0, 4, 0,227, 0, 9, 0,228, 0, 7, 0,229, 0, 7, 0,230, 0, 7, 0,231, 0, 4, 0,232, 0, + 9, 0,233, 0, 9, 0,234, 0, 4, 0,235, 0, 4, 0, 37, 0, 54, 0, 6, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, + 7, 0,236, 0, 7, 0, 67, 0, 4, 0, 64, 0, 55, 0, 5, 0, 2, 0, 19, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0,237, 0, + 54, 0,231, 0, 56, 0, 17, 0, 32, 0,164, 0, 47, 0,238, 0, 57, 0,239, 0, 7, 0,240, 0, 7, 0,241, 0, 2, 0, 17, 0, + 2, 0,242, 0, 7, 0,110, 0, 7, 0,111, 0, 7, 0,243, 0, 4, 0,244, 0, 2, 0,245, 0, 2, 0,246, 0, 4, 0,129, 0, + 4, 0,140, 0, 2, 0,247, 0, 2, 0,248, 0, 58, 0, 23, 0, 2, 0, 19, 0, 2, 0,249, 0, 7, 0,250, 0, 7, 0,251, 0, + 2, 0,139, 0, 2, 0,252, 0, 4, 0,253, 0, 4, 0,254, 0, 32, 0,164, 0, 59, 0,255, 0, 2, 0, 0, 1, 2, 0, 1, 1, + 2, 0, 2, 1, 9, 0, 3, 1, 7, 0, 4, 1, 7, 0, 5, 1, 2, 0, 6, 1, 2, 0, 7, 1, 2, 0, 8, 1, 2, 0, 9, 1, + 7, 0, 10, 1, 7, 0, 11, 1, 55, 0, 12, 1, 60, 0, 11, 0, 4, 0, 13, 1, 4, 0, 14, 1, 2, 0, 15, 1, 2, 0, 19, 0, + 2, 0, 16, 1, 2, 0, 37, 0, 32, 0,164, 0, 7, 0, 17, 1, 4, 0, 18, 1, 0, 0, 19, 1, 7, 0, 20, 1, 52, 0, 61, 0, + 27, 0, 31, 0, 39, 0, 75, 0, 7, 0, 21, 1, 7, 0, 22, 1, 7, 0, 23, 1, 7, 0, 24, 1, 7, 0, 25, 1, 7, 0, 26, 1, + 7, 0, 27, 1, 7, 0, 28, 1, 7, 0, 29, 1, 7, 0, 30, 1, 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, 40, 1, 2, 0, 41, 1, 2, 0, 42, 1, + 2, 0, 43, 1, 2, 0, 44, 1, 2, 0, 45, 1, 2, 0, 46, 1, 2, 0, 47, 1, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,242, 0, + 7, 0, 48, 1, 7, 0, 49, 1, 7, 0, 50, 1, 7, 0, 51, 1, 4, 0, 52, 1, 4, 0, 53, 1, 2, 0, 54, 1, 2, 0, 55, 1, + 2, 0, 16, 1, 2, 0,127, 0, 4, 0, 23, 0, 4, 0,124, 0, 4, 0,125, 0, 4, 0,126, 0, 7, 0, 56, 1, 7, 0, 57, 1, + 7, 0,189, 0, 45, 0, 58, 1, 61, 0, 59, 1, 36, 0, 80, 0, 47, 0,238, 0, 53, 0, 60, 1, 55, 0, 12, 1, 56, 0, 61, 1, + 30, 0,150, 0, 58, 0, 62, 1, 60, 0, 63, 1, 0, 0, 64, 1, 0, 0,181, 0, 62, 0, 8, 0, 7, 0, 65, 1, 7, 0, 66, 1, + 7, 0,172, 0, 4, 0, 19, 0, 7, 0, 67, 1, 7, 0, 68, 1, 7, 0, 69, 1, 32, 0, 45, 0, 63, 0, 82, 0, 27, 0, 31, 0, + 39, 0, 75, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 70, 1, 2, 0,175, 0, 2, 0, 71, 1, 7, 0,182, 0, 7, 0,183, 0, + 7, 0,184, 0, 7, 0,185, 0, 7, 0, 72, 1, 7, 0, 73, 1, 7, 0, 74, 1, 7, 0, 75, 1, 7, 0, 76, 1, 7, 0, 77, 1, + 7, 0, 78, 1, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 64, 0, 83, 1, 2, 0,249, 0, 2, 0, 70, 0, + 7, 0,110, 0, 7, 0,111, 0, 7, 0, 84, 1, 7, 0, 85, 1, 7, 0, 86, 1, 2, 0, 87, 1, 2, 0, 88, 1, 2, 0, 89, 1, + 2, 0, 90, 1, 0, 0, 91, 1, 0, 0, 92, 1, 2, 0, 93, 1, 2, 0, 94, 1, 2, 0, 95, 1, 2, 0, 96, 1, 2, 0, 97, 1, + 7, 0, 98, 1, 7, 0, 99, 1, 7, 0,100, 1, 7, 0,101, 1, 2, 0,102, 1, 2, 0, 43, 0, 2, 0,103, 1, 2, 0,104, 1, + 2, 0,105, 1, 2, 0,106, 1, 7, 0,107, 1, 7, 0,108, 1, 7, 0,109, 1, 7, 0,110, 1, 7, 0,111, 1, 7, 0,112, 1, + 7, 0,113, 1, 7, 0,114, 1, 7, 0,115, 1, 7, 0,116, 1, 7, 0,117, 1, 7, 0,118, 1, 2, 0,119, 1, 2, 0,120, 1, + 4, 0,121, 1, 4, 0,122, 1, 2, 0,123, 1, 2, 0,124, 1, 2, 0,125, 1, 2, 0,126, 1, 7, 0,127, 1, 7, 0,128, 1, + 7, 0,129, 1, 7, 0,130, 1, 2, 0,131, 1, 2, 0,132, 1, 36, 0, 80, 0, 51, 0,133, 1, 2, 0,134, 1, 2, 0,135, 1, + 30, 0,150, 0, 65, 0, 2, 0, 27, 0, 31, 0, 36, 0, 80, 0, 66, 0, 18, 0, 7, 0,136, 1, 7, 0,137, 1, 7, 0,138, 1, + 7, 0,139, 1, 7, 0,140, 1, 7, 0,141, 1, 7, 0,142, 1, 7, 0,143, 1, 7, 0,144, 1, 7, 0,145, 1, 2, 0,146, 1, + 2, 0,147, 1, 2, 0,148, 1, 2, 0,149, 1, 7, 0,150, 1, 7, 0,151, 1, 7, 0,152, 1, 4, 0,153, 1, 67, 0,124, 0, + 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,154, 1, 2, 0, 19, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, 7, 0,155, 1, + 7, 0,156, 1, 7, 0,157, 1, 7, 0,158, 1, 7, 0,159, 1, 7, 0,160, 1, 7, 0,161, 1, 7, 0,162, 1, 7, 0,163, 1, + 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, 66, 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, 2, 0,183, 1, 2, 0,184, 1, 2, 0,185, 1, 0, 0,186, 1, 0, 0,187, 1, + 7, 0,188, 1, 7, 0,189, 1, 2, 0,190, 1, 2, 0,191, 1, 7, 0,192, 1, 7, 0,193, 1, 7, 0,194, 1, 7, 0,195, 1, + 2, 0,196, 1, 2, 0,197, 1, 4, 0, 70, 1, 4, 0,198, 1, 2, 0,199, 1, 2, 0,200, 1, 2, 0,201, 1, 2, 0,202, 1, + 7, 0,203, 1, 7, 0,204, 1, 7, 0,205, 1, 7, 0,206, 1, 7, 0,207, 1, 7, 0,208, 1, 7, 0,209, 1, 7, 0,210, 1, + 7, 0,211, 1, 7, 0,212, 1, 0, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 4, 0,217, 1, 0, 0,218, 1, + 0, 0,103, 1, 0, 0,219, 1, 0, 0, 64, 1, 2, 0,220, 1, 2, 0,221, 1, 2, 0,134, 1, 2, 0,222, 1, 2, 0,223, 1, + 2, 0,224, 1, 7, 0,225, 1, 7, 0,226, 1, 7, 0,227, 1, 7, 0,228, 1, 7, 0,229, 1, 2, 0,160, 0, 2, 0,161, 0, + 55, 0,230, 1, 55, 0,231, 1, 0, 0,232, 1, 0, 0,233, 1, 0, 0,234, 1, 0, 0,235, 1, 2, 0,236, 1, 2, 0,237, 1, + 7, 0,238, 1, 7, 0,239, 1, 51, 0,133, 1, 61, 0, 59, 1, 36, 0, 80, 0, 68, 0,240, 1, 30, 0,150, 0, 7, 0,241, 1, + 7, 0,242, 1, 7, 0,243, 1, 7, 0,244, 1, 7, 0,245, 1, 2, 0,246, 1, 2, 0, 70, 0, 7, 0,247, 1, 7, 0,248, 1, + 7, 0,249, 1, 7, 0,250, 1, 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, 1, 2, 4, 0, 2, 2, 4, 0,120, 1, 12, 0, 3, 2, 69, 0, 4, 0, 27, 0, 31, 0, 0, 0, 4, 2, 70, 0, 2, 0, + 43, 0,149, 0, 71, 0, 26, 0, 71, 0, 0, 0, 71, 0, 1, 0, 72, 0, 5, 2, 4, 0, 6, 2, 4, 0, 7, 2, 4, 0, 8, 2, + 4, 0, 9, 2, 4, 0, 10, 2, 4, 0, 11, 2, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 12, 2, 2, 0, 13, 2, 7, 0, 5, 0, + 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 14, 2, 7, 0, 15, 2, 7, 0, 16, 2, 7, 0, 17, 2, 7, 0, 18, 2, 7, 0, 19, 2, + 7, 0, 20, 2, 7, 0, 23, 0, 7, 0, 21, 2, 7, 0, 22, 2, 73, 0, 19, 0, 27, 0, 31, 0, 39, 0, 75, 0, 72, 0, 5, 2, + 12, 0, 23, 2, 12, 0, 24, 2, 12, 0, 25, 2, 36, 0, 80, 0, 67, 0, 26, 2, 0, 0, 19, 0, 0, 0, 27, 2, 2, 0, 28, 2, + 4, 0,174, 0, 7, 0, 65, 1, 7, 0,172, 0, 7, 0, 66, 1, 7, 0, 29, 2, 7, 0, 30, 2, 7, 0, 31, 2, 71, 0, 32, 2, + 35, 0, 11, 0, 7, 0, 33, 2, 7, 0, 34, 2, 7, 0, 35, 2, 7, 0,251, 0, 2, 0, 55, 0, 0, 0, 36, 2, 0, 0, 37, 2, + 0, 0, 38, 2, 0, 0, 39, 2, 0, 0, 40, 2, 0, 0, 41, 2, 34, 0, 7, 0, 7, 0, 42, 2, 7, 0, 34, 2, 7, 0, 35, 2, + 2, 0, 38, 2, 2, 0, 41, 2, 7, 0,251, 0, 7, 0, 37, 0, 74, 0, 21, 0, 74, 0, 0, 0, 74, 0, 1, 0, 2, 0, 17, 0, + 2, 0, 43, 2, 2, 0, 41, 2, 2, 0, 19, 0, 2, 0, 44, 2, 2, 0, 45, 2, 2, 0, 46, 2, 2, 0, 47, 2, 2, 0, 48, 2, + 2, 0, 49, 2, 2, 0, 50, 2, 2, 0, 51, 2, 7, 0, 52, 2, 7, 0, 53, 2, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0, 54, 2, + 2, 0, 55, 2, 4, 0, 56, 2, 75, 0, 5, 0, 2, 0, 57, 2, 2, 0, 43, 2, 0, 0, 19, 0, 0, 0, 37, 0, 2, 0, 70, 0, + 76, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 8, 0, 7, 0, 58, 2, 77, 0, 67, 0, 27, 0, 31, 0, 39, 0, 75, 0, + 72, 0, 5, 2, 12, 0, 59, 2, 12, 0, 24, 2, 12, 0, 60, 2, 32, 0, 61, 2, 32, 0, 62, 2, 32, 0, 63, 2, 36, 0, 80, 0, + 78, 0, 64, 2, 38, 0, 65, 2, 67, 0, 26, 2, 12, 0, 66, 2, 7, 0, 65, 1, 7, 0,172, 0, 7, 0, 66, 1, 4, 0,174, 0, + 2, 0, 67, 2, 2, 0, 68, 2, 2, 0, 69, 2, 7, 0, 70, 2, 7, 0, 70, 0, 2, 0, 71, 2, 2, 0, 28, 2, 2, 0, 19, 0, + 2, 0, 72, 2, 7, 0, 73, 2, 7, 0, 74, 2, 7, 0, 75, 2, 2, 0, 46, 2, 2, 0, 47, 2, 2, 0, 76, 2, 2, 0, 77, 2, + 4, 0, 78, 2, 34, 0, 79, 2, 2, 0, 23, 0, 2, 0, 95, 0, 2, 0, 67, 0, 2, 0, 80, 2, 7, 0, 81, 2, 7, 0, 82, 2, + 7, 0, 83, 2, 7, 0, 84, 2, 7, 0, 85, 2, 7, 0, 86, 2, 7, 0, 87, 2, 7, 0, 88, 2, 7, 0, 89, 2, 7, 0, 90, 2, + 0, 0, 91, 2, 79, 0, 92, 2, 80, 0, 93, 2, 0, 0, 94, 2, 69, 0, 95, 2, 69, 0, 96, 2, 69, 0, 97, 2, 69, 0, 98, 2, + 4, 0, 99, 2, 7, 0,100, 2, 4, 0,101, 2, 4, 0,102, 2, 76, 0,103, 2, 4, 0,104, 2, 4, 0,105, 2, 75, 0,106, 2, + 75, 0,107, 2, 81, 0, 39, 0, 27, 0, 31, 0, 72, 0, 5, 2, 12, 0,108, 2, 36, 0, 80, 0, 38, 0, 65, 2, 67, 0, 26, 2, + 82, 0,109, 2, 83, 0,110, 2, 84, 0,111, 2, 85, 0,112, 2, 86, 0,113, 2, 87, 0,114, 2, 88, 0,115, 2, 89, 0,116, 2, + 81, 0,117, 2, 90, 0,118, 2, 91, 0,119, 2, 92, 0,120, 2, 92, 0,121, 2, 92, 0,122, 2, 4, 0, 54, 0, 4, 0,123, 2, + 4, 0,124, 2, 4, 0,125, 2, 4, 0,126, 2, 4, 0,174, 0, 7, 0, 65, 1, 7, 0,172, 0, 7, 0, 66, 1, 7, 0,127, 2, + 4, 0, 67, 2, 2, 0,128, 2, 2, 0, 19, 0, 2, 0,129, 2, 2, 0,130, 2, 2, 0, 28, 2, 2, 0,131, 2, 93, 0,132, 2, + 94, 0,133, 2, 84, 0, 8, 0, 9, 0,134, 2, 7, 0,135, 2, 4, 0,136, 2, 0, 0, 19, 0, 0, 0,137, 2, 2, 0, 70, 1, + 2, 0,138, 2, 2, 0,139, 2, 82, 0, 7, 0, 4, 0,140, 2, 4, 0,141, 2, 4, 0,142, 2, 4, 0,143, 2, 2, 0, 43, 2, + 0, 0,144, 2, 0, 0, 19, 0, 86, 0, 5, 0, 4, 0,140, 2, 4, 0,141, 2, 0, 0,145, 2, 0, 0,146, 2, 2, 0, 19, 0, + 95, 0, 2, 0, 4, 0,147, 2, 7, 0, 35, 2, 87, 0, 3, 0, 95, 0,148, 2, 4, 0,149, 2, 4, 0, 19, 0, 85, 0, 6, 0, + 7, 0,150, 2, 2, 0,151, 2, 2, 0, 43, 2, 0, 0, 19, 0, 0, 0,146, 2, 0, 0, 69, 2, 88, 0, 4, 0, 0, 0,236, 0, + 0, 0,182, 0, 0, 0,183, 0, 0, 0,184, 0, 96, 0, 6, 0, 47, 0,134, 2, 0, 0, 19, 0, 0, 0,137, 2, 2, 0, 70, 1, + 2, 0,138, 2, 2, 0,139, 2, 97, 0, 1, 0, 7, 0,152, 2, 98, 0, 5, 0, 0, 0,236, 0, 0, 0,182, 0, 0, 0,183, 0, + 0, 0,184, 0, 4, 0, 37, 0, 89, 0, 1, 0, 7, 0,153, 2, 90, 0, 2, 0, 4, 0,154, 2, 4, 0, 17, 0, 83, 0, 7, 0, + 7, 0,135, 2, 47, 0,134, 2, 0, 0, 19, 0, 0, 0,137, 2, 2, 0, 70, 1, 2, 0,138, 2, 2, 0,139, 2, 99, 0, 1, 0, + 7, 0,155, 2,100, 0, 1, 0, 4, 0,156, 2,101, 0, 1, 0, 0, 0,157, 2,102, 0, 1, 0, 7, 0,135, 2,103, 0, 3, 0, + 4, 0,158, 2, 0, 0, 92, 0, 7, 0,159, 2,105, 0, 4, 0, 7, 0,236, 0, 7, 0,182, 0, 7, 0,183, 0, 7, 0,184, 0, +106, 0, 1, 0,105, 0,136, 2,107, 0, 5, 0, 4, 0,160, 2, 4, 0,161, 2, 0, 0, 19, 0, 0, 0, 43, 2, 0, 0, 69, 2, +108, 0, 2, 0, 4, 0,162, 2, 4, 0,161, 2,109, 0, 10, 0,109, 0, 0, 0,109, 0, 1, 0,107, 0,163, 2,106, 0,164, 2, +108, 0,165, 2, 4, 0, 54, 0, 4, 0,124, 2, 4, 0,123, 2, 4, 0, 37, 0, 85, 0,166, 2, 93, 0, 14, 0, 12, 0,167, 2, + 85, 0,166, 2, 0, 0,168, 2, 0, 0,169, 2, 0, 0,170, 2, 0, 0,171, 2, 0, 0,172, 2, 0, 0,173, 2, 0, 0,174, 2, + 0, 0, 19, 0, 92, 0,120, 2, 92, 0,122, 2, 2, 0,175, 2, 0, 0,176, 2, 94, 0, 8, 0, 4, 0,177, 2, 4, 0,178, 2, + 82, 0,179, 2, 86, 0,180, 2, 4, 0,124, 2, 4, 0,123, 2, 4, 0, 54, 0, 4, 0, 37, 0,110, 0, 7, 0,110, 0, 0, 0, +110, 0, 1, 0, 4, 0, 17, 0, 4, 0, 70, 1, 0, 0, 20, 0, 46, 0,134, 0, 0, 0,181, 2,111, 0, 7, 0,110, 0,182, 2, + 2, 0,183, 2, 2, 0,167, 2, 2, 0,184, 2, 2, 0, 90, 0, 9, 0,185, 2, 9, 0,186, 2,112, 0, 3, 0,110, 0,182, 2, + 32, 0,164, 0, 0, 0, 20, 0,113, 0, 5, 0,110, 0,182, 2, 32, 0,164, 0, 0, 0, 20, 0, 2, 0,187, 2, 0, 0,188, 2, +114, 0, 5, 0,110, 0,182, 2, 7, 0, 88, 0, 7, 0,189, 2, 4, 0,190, 2, 4, 0,191, 2,115, 0, 5, 0,110, 0,182, 2, + 32, 0,192, 2, 0, 0, 72, 0, 4, 0, 70, 1, 4, 0, 19, 0,116, 0, 13, 0,110, 0,182, 2, 32, 0,193, 2, 32, 0,194, 2, + 32, 0,195, 2, 32, 0,196, 2, 7, 0,197, 2, 7, 0,198, 2, 7, 0,189, 2, 7, 0,199, 2, 4, 0,200, 2, 4, 0,201, 2, + 4, 0, 90, 0, 4, 0,202, 2,117, 0, 5, 0,110, 0,182, 2, 2, 0,203, 2, 2, 0, 19, 0, 7, 0,204, 2, 32, 0,205, 2, +118, 0, 3, 0,110, 0,182, 2, 7, 0,206, 2, 4, 0, 90, 0,119, 0, 10, 0,110, 0,182, 2, 7, 0,207, 2, 4, 0,208, 2, + 4, 0, 37, 0, 2, 0, 90, 0, 2, 0,209, 2, 2, 0,210, 2, 2, 0,211, 2, 7, 0,212, 2, 0, 0,213, 2,120, 0, 3, 0, +110, 0,182, 2, 7, 0, 37, 0, 4, 0, 17, 0,121, 0, 6, 0,110, 0,182, 2,122, 0,214, 2,123, 0,215, 2,124, 0,216, 2, + 7, 0,217, 2, 4, 0, 17, 0,125, 0, 11, 0,110, 0,182, 2, 52, 0,218, 2, 7, 0,219, 2, 4, 0,220, 2, 0, 0,213, 2, + 7, 0,221, 2, 4, 0,222, 2, 32, 0,223, 2, 0, 0,224, 2, 4, 0,225, 2, 4, 0, 37, 0,126, 0, 10, 0,110, 0,182, 2, + 32, 0,226, 2, 47, 0,227, 2, 4, 0, 90, 0, 4, 0,228, 2, 7, 0,229, 2, 7, 0,230, 2, 0, 0,224, 2, 4, 0,225, 2, + 4, 0, 37, 0,127, 0, 3, 0,110, 0,182, 2, 7, 0,231, 2, 4, 0,232, 2,128, 0, 5, 0,110, 0,182, 2, 7, 0,233, 2, + 0, 0,213, 2, 2, 0, 19, 0, 2, 0,234, 2,129, 0, 8, 0,110, 0,182, 2, 32, 0,164, 0, 7, 0,233, 2, 7, 0,251, 0, + 7, 0,106, 0, 0, 0,213, 2, 2, 0, 19, 0, 2, 0, 17, 0,130, 0, 21, 0,110, 0,182, 2, 32, 0,235, 2, 0, 0,213, 2, + 52, 0,218, 2, 32, 0,223, 2, 2, 0, 19, 0, 2, 0, 37, 0, 7, 0,236, 2, 7, 0,237, 2, 7, 0,238, 2, 7, 0, 73, 2, + 7, 0,239, 2, 7, 0,240, 2, 7, 0,241, 2, 7, 0,242, 2, 4, 0,222, 2, 4, 0,225, 2, 0, 0,224, 2, 7, 0,243, 2, + 7, 0,244, 2, 7, 0, 43, 0,131, 0, 7, 0,110, 0,182, 2, 2, 0,245, 2, 2, 0,246, 2, 4, 0, 70, 0, 32, 0,164, 0, + 7, 0,247, 2, 0, 0,213, 2,132, 0, 10, 0,110, 0,182, 2, 32, 0,164, 0, 0, 0,248, 2, 7, 0,249, 2, 7, 0,250, 2, + 7, 0,242, 2, 4, 0,251, 2, 4, 0,252, 2, 7, 0,253, 2, 0, 0, 20, 0,133, 0, 1, 0,110, 0,182, 2,134, 0, 7, 0, +110, 0,182, 2, 46, 0,134, 0,135, 0,254, 2,136, 0,255, 2,137, 0, 0, 3,138, 0, 1, 3, 12, 0, 2, 3,139, 0, 13, 0, +110, 0,182, 2, 85, 0, 3, 3, 85, 0, 4, 3, 85, 0, 5, 3, 85, 0, 6, 3, 85, 0, 7, 3, 85, 0, 8, 3, 82, 0, 9, 3, + 4, 0, 10, 3, 4, 0, 11, 3, 7, 0,217, 2, 7, 0, 37, 0,140, 0, 12, 3,141, 0, 7, 0,110, 0,182, 2, 85, 0, 3, 3, + 85, 0, 13, 3,142, 0, 14, 3,143, 0, 12, 3, 4, 0, 15, 3, 4, 0, 10, 3,144, 0, 4, 0,110, 0,182, 2, 32, 0,164, 0, + 4, 0, 16, 3, 4, 0, 37, 0,145, 0, 2, 0, 4, 0, 17, 3, 7, 0, 35, 2,146, 0, 2, 0, 4, 0,125, 0, 4, 0, 18, 3, +147, 0, 20, 0,110, 0,182, 2, 32, 0,164, 0, 0, 0,213, 2, 2, 0, 19, 3, 2, 0, 20, 3, 2, 0, 19, 0, 2, 0, 37, 0, + 7, 0, 21, 3, 7, 0, 22, 3, 4, 0, 54, 0, 4, 0, 23, 3,146, 0, 24, 3,145, 0, 25, 3, 4, 0, 26, 3, 4, 0, 27, 3, + 4, 0, 28, 3, 4, 0, 18, 3, 7, 0, 29, 3, 7, 0, 30, 3, 7, 0, 31, 3,148, 0, 8, 0,110, 0,182, 2, 59, 0,255, 0, +142, 0, 14, 3, 4, 0, 32, 3, 4, 0, 33, 3, 4, 0, 34, 3, 2, 0, 19, 0, 2, 0, 57, 0,149, 0, 8, 0,110, 0,182, 2, + 32, 0, 45, 0, 2, 0, 35, 3, 2, 0, 19, 0, 2, 0,203, 2, 2, 0, 57, 0, 7, 0, 36, 3, 7, 0, 37, 3,150, 0, 5, 0, +110, 0,182, 2, 4, 0, 38, 3, 2, 0, 19, 0, 2, 0, 39, 3, 7, 0, 40, 3,151, 0, 7, 0,110, 0,182, 2, 85, 0, 41, 3, + 4, 0, 42, 3, 0, 0, 43, 3, 0, 0, 44, 3, 0, 0, 45, 3, 0, 0, 46, 3,152, 0, 3, 0,110, 0,182, 2,153, 0, 47, 3, +138, 0, 1, 3,154, 0, 10, 0,110, 0,182, 2, 32, 0, 48, 3, 32, 0, 49, 3, 0, 0, 50, 3, 7, 0, 51, 3, 2, 0, 52, 3, + 2, 0, 53, 3, 0, 0, 54, 3, 0, 0, 55, 3, 0, 0,188, 2,155, 0, 9, 0,110, 0,182, 2, 32, 0, 56, 3, 0, 0, 50, 3, + 7, 0, 57, 3, 7, 0, 58, 3, 0, 0, 70, 1, 0, 0,203, 2, 0, 0, 59, 3, 0, 0, 37, 0,156, 0, 27, 0, 27, 0, 31, 0, + 2, 0, 44, 2, 2, 0, 45, 2, 2, 0, 60, 3, 2, 0, 19, 0, 2, 0, 61, 3, 2, 0, 62, 3, 2, 0, 63, 3, 2, 0, 70, 0, + 0, 0, 64, 3, 0, 0, 65, 3, 0, 0, 66, 3, 0, 0, 17, 0, 4, 0, 37, 0, 7, 0, 67, 3, 7, 0, 68, 3, 7, 0, 69, 3, + 7, 0, 70, 3, 7, 0, 71, 3, 7, 0, 72, 3, 34, 0, 73, 3, 36, 0, 80, 0, 38, 0, 65, 2, 87, 0,114, 2, 7, 0, 74, 3, + 7, 0, 75, 3,156, 0, 76, 3,157, 0, 3, 0,157, 0, 0, 0,157, 0, 1, 0, 0, 0, 20, 0, 72, 0, 3, 0, 7, 0, 77, 3, + 4, 0, 19, 0, 4, 0, 37, 0, 32, 0,120, 0, 27, 0, 31, 0, 39, 0, 75, 0,158, 0, 78, 3, 2, 0, 17, 0, 2, 0, 79, 3, + 4, 0, 80, 3, 4, 0, 81, 3, 4, 0, 82, 3, 0, 0, 83, 3, 32, 0, 38, 0, 32, 0, 84, 3, 32, 0, 85, 3, 32, 0, 86, 3, + 32, 0, 87, 3, 36, 0, 80, 0, 78, 0, 64, 2, 72, 0, 5, 2,159, 0, 88, 3,159, 0, 89, 3,160, 0, 90, 3, 9, 0, 2, 0, +161, 0, 91, 3, 12, 0, 92, 3, 12, 0,108, 2, 12, 0, 24, 2, 12, 0, 93, 3, 12, 0, 94, 3, 4, 0, 70, 1, 4, 0, 95, 3, + 67, 0, 26, 2, 0, 0, 96, 3, 4, 0, 28, 2, 4, 0, 97, 3, 7, 0, 65, 1, 7, 0, 98, 3, 7, 0, 99, 3, 7, 0,172, 0, + 7, 0,100, 3, 7, 0, 66, 1, 7, 0,101, 3, 7, 0, 14, 2, 7, 0,102, 3, 7, 0,103, 3, 7, 0,249, 2, 7, 0,104, 3, + 7, 0,240, 0, 4, 0,105, 3, 2, 0, 19, 0, 2, 0,106, 3, 2, 0,107, 3, 2, 0,108, 3, 2, 0,109, 3, 2, 0,110, 3, + 2, 0,111, 3, 2, 0,112, 3, 2, 0,113, 3, 2, 0,114, 3, 2, 0,115, 3, 2, 0,116, 3, 4, 0,117, 3, 4, 0,118, 3, + 4, 0,119, 3, 4, 0,120, 3, 7, 0,121, 3, 7, 0,100, 2, 7, 0,122, 3, 7, 0,123, 3, 7, 0,124, 3, 7, 0,125, 3, + 7, 0,126, 3, 7, 0,215, 0, 7, 0,127, 3, 7, 0,128, 3, 7, 0,129, 3, 7, 0,130, 3, 2, 0,131, 3, 0, 0,132, 3, + 0, 0,133, 3, 0, 0,134, 3, 0, 0,135, 3, 7, 0,136, 3, 7, 0,137, 3, 12, 0,138, 3, 12, 0,139, 3, 12, 0,140, 3, + 12, 0,141, 3, 7, 0,142, 3, 2, 0,154, 2, 2, 0,143, 3, 7, 0,136, 2, 4, 0,144, 3, 4, 0,145, 3,162, 0,146, 3, + 2, 0,147, 3, 2, 0,247, 0, 7, 0,148, 3, 12, 0,149, 3, 12, 0,150, 3, 12, 0,151, 3, 12, 0,152, 3,163, 0, 62, 1, +164, 0,153, 3, 68, 0,154, 3, 2, 0,155, 3, 2, 0,156, 3, 2, 0,157, 3, 2, 0,158, 3, 7, 0,128, 2, 2, 0,159, 3, + 2, 0,160, 3,153, 0,161, 3,142, 0,162, 3,142, 0,163, 3, 4, 0,164, 3, 4, 0,165, 3, 4, 0,166, 3, 4, 0, 70, 0, + 12, 0,167, 3, 12, 0,168, 3, 12, 0,169, 3,165, 0, 14, 0,165, 0, 0, 0,165, 0, 1, 0, 32, 0, 38, 0, 7, 0,249, 2, + 7, 0, 67, 1, 7, 0,250, 2, 7, 0,242, 2, 0, 0, 20, 0, 4, 0,251, 2, 4, 0,252, 2, 4, 0,170, 3, 2, 0, 17, 0, + 2, 0,171, 3, 7, 0,253, 2,166, 0, 12, 0,166, 0, 0, 0,166, 0, 1, 0, 32, 0, 45, 0, 4, 0,172, 3, 4, 0,154, 2, + 4, 0,173, 3, 4, 0, 17, 0, 4, 0,174, 3, 7, 0, 67, 1, 7, 0,175, 3, 7, 0,176, 3, 7, 0,152, 2,163, 0, 41, 0, + 2, 0,177, 3, 2, 0,178, 3, 2, 0, 19, 0, 2, 0,242, 2, 2, 0,179, 3, 2, 0,180, 3, 2, 0,181, 3, 2, 0,182, 3, + 2, 0,183, 3, 2, 0, 57, 0, 7, 0,184, 3, 7, 0,185, 3, 7, 0,186, 3, 7, 0,187, 3, 7, 0,188, 3, 7, 0,189, 3, + 7, 0,190, 3, 7, 0,191, 3, 7, 0,192, 3, 7, 0,193, 3, 7, 0,194, 3, 7, 0,195, 3, 7, 0,196, 3, 7, 0,197, 3, + 7, 0,198, 3, 7, 0,199, 3, 7, 0, 37, 0, 7, 0,200, 3, 7, 0,201, 3, 7, 0,202, 3, 7, 0,203, 3, 7, 0,204, 3, + 7, 0,205, 3, 7, 0,206, 3, 7, 0,207, 3, 7, 0,208, 3, 7, 0,209, 3, 52, 0,165, 0,167, 0,210, 3, 7, 0,211, 3, + 4, 0,191, 2,168, 0, 5, 0, 68, 0,240, 1, 7, 0,212, 3, 7, 0,213, 3, 2, 0, 19, 0, 2, 0,214, 3,169, 0, 9, 0, +169, 0, 0, 0,169, 0, 1, 0, 4, 0,215, 3, 4, 0,216, 3, 4, 0,217, 3, 4, 0, 19, 0, 4, 0,218, 3, 9, 0,219, 3, + 9, 0,220, 3,138, 0, 19, 0,138, 0, 0, 0,138, 0, 1, 0, 4, 0, 19, 0, 4, 0,221, 3, 4, 0,222, 3, 4, 0,223, 3, + 4, 0,224, 3, 4, 0,225, 3, 4, 0,226, 3, 4, 0,216, 3, 4, 0,154, 2, 4, 0, 57, 0, 0, 0,227, 3, 0, 0,228, 3, + 0, 0,229, 3, 0, 0,230, 3, 12, 0,231, 3,170, 0,232, 3, 9, 0,233, 3,171, 0, 1, 0, 7, 0, 42, 2,162, 0, 30, 0, + 4, 0, 19, 0, 7, 0,234, 3, 7, 0,235, 3, 7, 0,236, 3, 4, 0,237, 3, 4, 0,238, 3, 4, 0,239, 3, 4, 0,240, 3, + 7, 0,241, 3, 7, 0,242, 3, 7, 0,243, 3, 7, 0,244, 3, 7, 0,245, 3, 7, 0,246, 3, 7, 0,247, 3, 7, 0,248, 3, + 7, 0,249, 3, 7, 0,250, 3, 7, 0,251, 3, 7, 0,252, 3, 7, 0,253, 3, 7, 0,254, 3, 7, 0,255, 3, 7, 0, 0, 4, + 7, 0, 1, 4, 7, 0, 2, 4, 4, 0, 3, 4, 4, 0, 4, 4, 7, 0, 5, 4, 7, 0,127, 3,164, 0, 50, 0, 4, 0,216, 3, + 4, 0, 6, 4,172, 0, 7, 4,173, 0, 8, 4, 0, 0, 37, 0, 0, 0, 9, 4, 2, 0, 10, 4, 7, 0, 11, 4, 0, 0, 12, 4, + 7, 0, 13, 4, 7, 0, 14, 4, 7, 0, 15, 4, 7, 0, 16, 4, 7, 0, 17, 4, 7, 0, 18, 4, 7, 0, 19, 4, 7, 0, 20, 4, + 7, 0, 21, 4, 2, 0, 22, 4, 0, 0, 23, 4, 2, 0, 24, 4, 7, 0, 25, 4, 7, 0, 26, 4, 0, 0, 27, 4, 4, 0,126, 0, + 4, 0, 28, 4, 4, 0, 29, 4, 2, 0, 30, 4, 2, 0, 31, 4,171, 0, 32, 4, 4, 0, 33, 4, 4, 0, 82, 0, 7, 0, 34, 4, + 7, 0, 35, 4, 7, 0, 36, 4, 7, 0, 37, 4, 2, 0, 38, 4, 2, 0, 39, 4, 2, 0, 40, 4, 2, 0, 41, 4, 2, 0, 42, 4, + 2, 0, 43, 4, 2, 0, 44, 4, 2, 0, 45, 4,174, 0, 46, 4, 7, 0, 47, 4, 7, 0, 48, 4,138, 0, 49, 4, 12, 0, 2, 3, +168, 0, 50, 4,153, 0, 49, 0,152, 0, 51, 4, 2, 0, 17, 0, 2, 0, 52, 4, 2, 0, 53, 4, 2, 0, 54, 4, 7, 0, 55, 4, + 2, 0, 56, 4, 2, 0, 57, 4, 7, 0, 58, 4, 2, 0, 59, 4, 2, 0, 60, 4, 7, 0, 61, 4, 7, 0, 62, 4, 7, 0, 63, 4, + 7, 0, 64, 4, 7, 0, 65, 4, 7, 0, 66, 4, 4, 0, 67, 4, 7, 0, 68, 4, 7, 0, 69, 4, 7, 0, 70, 4, 81, 0, 71, 4, + 81, 0, 72, 4, 81, 0, 73, 4, 0, 0, 74, 4, 7, 0, 75, 4, 7, 0, 76, 4, 36, 0, 80, 0, 2, 0, 77, 4, 0, 0, 78, 4, + 0, 0, 79, 4, 7, 0, 80, 4, 4, 0, 81, 4, 7, 0, 82, 4, 7, 0, 83, 4, 4, 0, 84, 4, 4, 0, 19, 0, 7, 0, 85, 4, + 7, 0, 86, 4, 7, 0, 87, 4, 85, 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, 4, 0, 96, 4,175, 0, 73, 0, 27, 0, 31, 0, 39, 0, 75, 0, 2, 0,175, 0, 2, 0, 71, 1, + 2, 0,103, 1, 2, 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,161, 1, 7, 0,163, 1, 7, 0,162, 1, 7, 0,106, 4, 4, 0,107, 4, 7, 0,108, 4, + 7, 0,109, 4, 7, 0,110, 4, 7, 0,111, 4, 7, 0,112, 4, 7, 0,113, 4, 7, 0,114, 4, 2, 0,115, 4, 2, 0, 70, 1, + 2, 0,116, 4, 2, 0,117, 4, 2, 0,118, 4, 2, 0,119, 4, 2, 0,120, 4, 2, 0,121, 4, 7, 0,122, 4, 7, 0,123, 4, + 7, 0,124, 4, 7, 0,125, 4, 7, 0,126, 4, 7, 0,127, 4, 7, 0,128, 4, 7, 0,129, 4, 7, 0,130, 4, 7, 0,131, 4, + 7, 0,132, 4, 7, 0,133, 4, 2, 0,134, 4, 2, 0,135, 4, 2, 0,136, 4, 2, 0,137, 4, 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, 7, 0,146, 4, 7, 0,147, 4, + 7, 0,148, 4, 7, 0,149, 4, 2, 0,150, 4, 2, 0,151, 4, 2, 0,152, 4, 2, 0, 19, 0, 7, 0,153, 4, 7, 0,154, 4, + 36, 0, 80, 0, 51, 0,133, 1, 2, 0,134, 1, 2, 0,135, 1, 30, 0,150, 0,176, 0, 8, 0,176, 0, 0, 0,176, 0, 1, 0, + 4, 0,105, 3, 4, 0,155, 4, 4, 0, 19, 0, 2, 0,156, 4, 2, 0,157, 4, 32, 0,164, 0,177, 0, 13, 0, 9, 0,158, 4, + 9, 0,159, 4, 4, 0,160, 4, 4, 0,161, 4, 4, 0,162, 4, 4, 0,163, 4, 4, 0,164, 4, 4, 0,165, 4, 4, 0,166, 4, + 4, 0,167, 4, 4, 0,168, 4, 4, 0, 37, 0, 0, 0,169, 4,178, 0, 5, 0, 9, 0,170, 4, 9, 0,171, 4, 4, 0,172, 4, + 4, 0, 70, 0, 0, 0,173, 4,179, 0, 15, 0, 4, 0, 17, 0, 4, 0,174, 4, 4, 0,175, 4, 4, 0,176, 4, 4, 0,177, 4, + 4, 0,178, 4, 7, 0,179, 4, 4, 0,180, 4, 4, 0, 90, 0, 4, 0,181, 4, 4, 0,182, 4, 4, 0,183, 4, 4, 0,184, 4, + 4, 0,185, 4, 26, 0, 30, 0,180, 0, 7, 0, 4, 0,186, 4, 7, 0,187, 4, 7, 0,188, 4, 7, 0,189, 4, 4, 0,190, 4, + 2, 0, 19, 0, 2, 0, 37, 0,181, 0, 11, 0,181, 0, 0, 0,181, 0, 1, 0, 0, 0, 20, 0, 67, 0,191, 4, 68, 0,192, 4, + 4, 0,105, 3, 4, 0,193, 4, 4, 0,194, 4, 4, 0, 37, 0, 4, 0,195, 4, 4, 0,196, 4,182, 0,131, 0,177, 0,197, 4, +178, 0,198, 4,179, 0,199, 4, 4, 0, 15, 3, 4, 0,126, 0, 4, 0, 28, 4, 4, 0,200, 4, 4, 0,201, 4, 4, 0,202, 4, + 4, 0,203, 4, 2, 0, 19, 0, 2, 0,204, 4, 7, 0,100, 2, 7, 0,205, 4, 7, 0,206, 4, 7, 0,207, 4, 7, 0,208, 4, + 7, 0,209, 4, 2, 0,210, 4, 2, 0,211, 4, 2, 0,212, 4, 2, 0,213, 4, 2, 0,246, 0, 2, 0,214, 4, 2, 0,215, 4, + 2, 0,216, 4, 2, 0,217, 4, 2, 0,218, 4, 2, 0, 90, 1, 2, 0,106, 0, 2, 0,219, 4, 2, 0,220, 4, 2, 0,221, 4, + 2, 0,222, 4, 2, 0,223, 4, 2, 0,224, 4, 2, 0,225, 4, 2, 0,226, 4, 2, 0,227, 4, 2, 0, 91, 1, 2, 0,228, 4, + 2, 0,229, 4, 2, 0,230, 4, 2, 0,231, 4, 4, 0,232, 4, 4, 0, 70, 1, 2, 0,233, 4, 2, 0,234, 4, 2, 0,235, 4, + 2, 0,236, 4, 2, 0,237, 4, 2, 0,238, 4, 24, 0,239, 4, 24, 0,240, 4, 23, 0,241, 4, 12, 0,242, 4, 2, 0,243, 4, + 2, 0, 37, 0, 7, 0,244, 4, 7, 0,245, 4, 7, 0,246, 4, 7, 0,247, 4, 4, 0,248, 4, 7, 0,249, 4, 7, 0,250, 4, + 7, 0,251, 4, 7, 0,252, 4, 2, 0,253, 4, 2, 0,254, 4, 2, 0,255, 4, 2, 0, 0, 5, 2, 0, 1, 5, 2, 0, 2, 5, + 7, 0, 3, 5, 7, 0, 4, 5, 7, 0, 5, 5, 2, 0, 6, 5, 2, 0, 7, 5, 2, 0, 8, 5, 2, 0, 9, 5, 2, 0, 10, 5, + 2, 0, 11, 5, 2, 0, 12, 5, 2, 0, 13, 5, 2, 0, 14, 5, 2, 0, 15, 5, 4, 0, 16, 5, 4, 0, 17, 5, 4, 0, 18, 5, + 4, 0, 19, 5, 4, 0, 20, 5, 7, 0, 21, 5, 4, 0, 22, 5, 4, 0, 23, 5, 4, 0, 24, 5, 4, 0, 25, 5, 7, 0, 26, 5, + 7, 0, 27, 5, 7, 0, 28, 5, 7, 0, 29, 5, 7, 0, 30, 5, 7, 0, 31, 5, 7, 0, 32, 5, 7, 0, 33, 5, 7, 0, 34, 5, + 0, 0, 35, 5, 0, 0, 36, 5, 4, 0, 37, 5, 2, 0, 38, 5, 2, 0,237, 1, 0, 0, 39, 5, 7, 0, 40, 5, 7, 0, 41, 5, + 4, 0, 42, 5, 4, 0, 43, 5, 7, 0, 44, 5, 7, 0, 45, 5, 2, 0, 46, 5, 2, 0, 47, 5, 7, 0, 48, 5, 2, 0, 49, 5, + 2, 0, 50, 5, 4, 0, 51, 5, 2, 0, 52, 5, 2, 0, 53, 5, 2, 0, 54, 5, 2, 0, 55, 5, 7, 0, 56, 5, 7, 0, 70, 0, + 42, 0, 57, 5, 0, 0, 58, 5,183, 0, 9, 0,183, 0, 0, 0,183, 0, 1, 0, 0, 0, 20, 0, 2, 0, 59, 5, 2, 0, 60, 5, + 2, 0, 61, 5, 2, 0, 43, 0, 7, 0, 62, 5, 7, 0, 70, 0,184, 0, 7, 0, 2, 0,208, 2, 2, 0, 70, 1, 2, 0,109, 0, + 2, 0, 63, 5, 7, 0, 64, 5, 7, 0, 70, 0, 42, 0, 65, 5,185, 0, 5, 0, 7, 0, 66, 5, 0, 0, 17, 0, 0, 0, 43, 0, + 0, 0, 70, 0, 0, 0,237, 1,186, 0, 26, 0, 7, 0,113, 4, 7, 0,114, 4, 2, 0, 70, 1, 2, 0, 19, 0, 2, 0, 67, 5, + 2, 0,135, 1, 2, 0,116, 4, 2, 0,117, 4, 2, 0,118, 4, 2, 0,119, 4, 2, 0,120, 4, 2, 0,121, 4,185, 0, 68, 5, + 2, 0,210, 4, 2, 0,211, 4, 2, 0,212, 4, 2, 0,213, 4, 2, 0,246, 0, 2, 0,214, 4, 2, 0,215, 4, 2, 0,216, 4, +184, 0, 69, 5, 2, 0, 70, 5, 2, 0,217, 4, 2, 0,220, 4, 2, 0,221, 4,187, 0, 5, 0,187, 0, 0, 0,187, 0, 1, 0, + 4, 0,215, 3, 0, 0,227, 3, 4, 0, 19, 0,188, 0, 6, 0,189, 0, 71, 5, 4, 0, 72, 5, 4, 0, 73, 5, 9, 0, 74, 5, + 0, 0, 75, 5, 4, 0, 37, 0,190, 0, 6, 0,188, 0, 76, 5, 2, 0, 19, 0, 2, 0, 77, 5, 2, 0, 78, 5, 2, 0, 79, 5, + 9, 0, 80, 5,191, 0, 4, 0, 2, 0,106, 0, 2, 0,219, 2, 2, 0,221, 3, 2, 0, 81, 5,192, 0, 14, 0, 2, 0, 19, 0, + 2, 0, 82, 5, 2, 0, 83, 5, 2, 0, 84, 5,191, 0, 85, 5, 9, 0, 80, 5, 7, 0, 86, 5, 7, 0, 57, 0, 4, 0, 87, 5, + 4, 0, 88, 5, 4, 0, 89, 5, 4, 0, 90, 5, 46, 0,134, 0, 32, 0,164, 0,193, 0, 4, 0,193, 0, 0, 0,193, 0, 1, 0, + 0, 0, 91, 5, 7, 0, 92, 5,194, 0, 6, 0,188, 0, 76, 5, 7, 0, 93, 5, 4, 0, 90, 0, 0, 0, 94, 5, 0, 0, 95, 5, + 0, 0,188, 2,195, 0, 9, 0,188, 0, 76, 5, 7, 0, 96, 5, 7, 0, 97, 5, 2, 0, 70, 1, 2, 0, 19, 0, 4, 0, 36, 0, + 4, 0, 98, 5, 87, 0, 99, 5, 9, 0, 80, 5,196, 0, 72, 0,195, 0,100, 5,195, 0,101, 5,194, 0, 78, 3, 7, 0,102, 5, + 2, 0,103, 5, 2, 0,104, 5, 7, 0,105, 5, 7, 0,106, 5, 2, 0,221, 3, 2, 0,107, 5, 7, 0,108, 5, 7, 0,109, 5, + 7, 0,110, 5, 2, 0,111, 5, 2, 0, 87, 5, 2, 0,112, 5, 2, 0,113, 5, 2, 0,114, 5, 2, 0,115, 5, 7, 0,116, 5, + 7, 0,117, 5, 7, 0,118, 5, 2, 0,119, 5, 2, 0,120, 5, 2, 0,121, 5, 2, 0,122, 5, 2, 0,123, 5, 2, 0,124, 5, + 2, 0,125, 5,190, 0,126, 5,192, 0,127, 5, 7, 0,128, 5, 7, 0,129, 5, 7, 0,130, 5, 2, 0,131, 5, 2, 0,132, 5, + 0, 0,133, 5, 0, 0,134, 5, 0, 0,135, 5, 0, 0,136, 5, 0, 0,137, 5, 0, 0,138, 5, 2, 0,139, 5, 7, 0,140, 5, + 7, 0,141, 5, 7, 0,142, 5, 7, 0,143, 5, 7, 0,144, 5, 7, 0,145, 5, 7, 0,146, 5, 7, 0,147, 5, 7, 0,148, 5, + 7, 0,149, 5, 2, 0,150, 5, 0, 0,151, 5, 0, 0,152, 5, 0, 0,153, 5, 0, 0,154, 5, 32, 0,155, 5, 0, 0,156, 5, + 0, 0,157, 5, 0, 0,158, 5, 0, 0,159, 5, 0, 0,160, 5, 0, 0,161, 5, 0, 0,162, 5, 0, 0,163, 5, 2, 0,164, 5, + 2, 0,165, 5, 2, 0,166, 5, 2, 0,167, 5, 2, 0,168, 5,197, 0, 8, 0, 4, 0,169, 5, 4, 0,170, 5, 4, 0,171, 5, + 4, 0,172, 5, 4, 0,173, 5, 4, 0,174, 5, 4, 0, 54, 0, 4, 0,124, 2,198, 0, 3, 0, 7, 0,175, 5, 2, 0,176, 5, + 2, 0, 19, 0,199, 0, 2, 0, 7, 0,177, 5, 4, 0, 19, 0, 46, 0, 38, 0, 27, 0, 31, 0, 39, 0, 75, 0, 32, 0,178, 5, +175, 0,179, 5, 46, 0,180, 5, 47, 0,238, 0, 12, 0,181, 5,176, 0,182, 5, 32, 0,183, 5, 7, 0,184, 5, 7, 0,185, 5, + 7, 0,186, 5, 7, 0,187, 5, 4, 0,105, 3, 2, 0, 19, 0, 2, 0, 64, 1, 61, 0, 59, 1,200, 0,188, 5,196, 0,189, 5, +201, 0,190, 5,182, 0,182, 0,180, 0,191, 5, 12, 0,100, 0, 12, 0,192, 5, 12, 0,193, 5,202, 0,194, 5, 2, 0,195, 5, + 2, 0,196, 5, 2, 0,247, 0, 2, 0,197, 5, 4, 0,198, 5, 4, 0,199, 5, 12, 0,200, 5,185, 0, 68, 5,186, 0,201, 5, +198, 0,202, 5,161, 0, 91, 3,199, 0,203, 5,203, 0, 6, 0, 47, 0,238, 0, 45, 0, 58, 1, 7, 0, 88, 2, 7, 0, 89, 2, + 7, 0,106, 0, 7, 0,204, 5,204, 0, 35, 0, 7, 0,205, 5, 7, 0,206, 5, 7, 0,207, 5, 7, 0,208, 5, 7, 0,209, 5, + 7, 0,210, 5, 7, 0,211, 5, 7, 0,212, 5, 7, 0,213, 5, 7, 0, 77, 1, 7, 0,214, 5, 7, 0,215, 5, 7, 0,216, 5, + 7, 0,217, 5, 7, 0,171, 0, 2, 0,218, 5, 2, 0,219, 5, 2, 0, 69, 2, 2, 0,220, 5, 2, 0,221, 5, 2, 0,222, 5, + 2, 0,223, 5, 7, 0,224, 5, 72, 0,225, 5,161, 0, 91, 3,204, 0,226, 5,205, 0,227, 5,206, 0,228, 5,207, 0,229, 5, +208, 0,230, 5,209, 0,231, 5, 7, 0,232, 5, 2, 0,233, 5, 2, 0,234, 5, 4, 0,237, 1,210, 0, 54, 0,211, 0, 0, 0, +211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5, 7, 0,213, 5, 7, 0, 77, 1, 7, 0, 43, 0, + 4, 0,239, 5, 2, 0,222, 5, 2, 0,223, 5, 32, 0,178, 5, 32, 0,240, 5,203, 0,241, 5,210, 0,226, 5, 0, 0,242, 5, + 4, 0,105, 3, 4, 0,243, 5, 2, 0,244, 5, 2, 0, 70, 0, 2, 0,245, 5, 2, 0,246, 5, 2, 0,237, 1, 2, 0, 19, 0, + 2, 0, 27, 2, 2, 0,247, 5, 7, 0,112, 0, 7, 0,248, 5, 7, 0,249, 5, 7, 0,250, 5, 7, 0,251, 5, 7, 0,252, 5, + 7, 0,171, 0, 7, 0,184, 5, 2, 0,253, 5, 2, 0,120, 1, 2, 0,254, 5, 2, 0,255, 5, 2, 0, 0, 6, 2, 0, 1, 6, + 2, 0, 2, 6, 2, 0, 3, 6, 2, 0, 4, 6, 2, 0, 5, 6, 4, 0, 6, 6, 12, 0, 7, 6, 2, 0, 8, 6, 2, 0,137, 2, + 2, 0, 9, 6, 0, 0, 10, 6, 0, 0, 11, 6, 9, 0, 12, 6,161, 0, 91, 3,212, 0, 25, 0, 24, 0, 36, 0, 24, 0, 64, 0, + 23, 0, 13, 6, 23, 0, 14, 6, 23, 0, 15, 6, 7, 0, 16, 6, 7, 0, 17, 6, 7, 0, 18, 6, 7, 0, 19, 6, 2, 0, 20, 6, + 2, 0, 21, 6, 2, 0, 22, 6, 2, 0, 23, 6, 2, 0, 24, 6, 2, 0, 19, 0, 2, 0, 25, 6, 2, 0, 26, 6, 2, 0, 27, 6, + 2, 0, 28, 6, 2, 0, 29, 6, 2, 0,246, 5, 7, 0, 30, 6, 7, 0, 31, 6, 4, 0, 32, 6, 4, 0, 33, 6,211, 0, 6, 0, +211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,213, 0, 8, 0,211, 0, 0, 0, +211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,214, 0, 34, 6, 46, 0,134, 0,215, 0, 14, 0, +211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,212, 0, 35, 6,216, 0, 36, 6, + 12, 0, 37, 6, 2, 0, 70, 1, 2, 0, 19, 0, 2, 0, 38, 6, 0, 0, 39, 6, 0, 0, 40, 6,217, 0, 20, 0,211, 0, 0, 0, +211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,205, 0,227, 5,212, 0, 35, 6, 2, 0, 41, 6, + 2, 0, 42, 6, 2, 0, 43, 6, 2, 0, 44, 6, 2, 0, 25, 6, 2, 0, 45, 6, 0, 0, 19, 0, 0, 0,135, 1, 9, 0, 64, 2, + 4, 0, 46, 6, 4, 0, 47, 6, 27, 0, 48, 6,218, 0, 16, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, + 7, 0,237, 5, 2, 0,238, 5,212, 0, 35, 6, 7, 0, 88, 2, 7, 0, 89, 2, 2, 0, 41, 6, 2, 0, 49, 6, 2, 0, 50, 6, + 2, 0, 51, 6, 4, 0, 19, 0, 7, 0, 52, 6,161, 0, 91, 3,219, 0, 16, 0, 0, 0, 53, 6, 0, 0, 54, 6, 0, 0, 55, 6, + 0, 0, 56, 6, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 57, 6, 2, 0, 58, 6, 2, 0,180, 1, 2, 0, 59, 6, 4, 0, 60, 6, + 4, 0, 61, 6, 2, 0, 62, 6, 2, 0, 63, 6, 0, 0, 64, 6, 0, 0, 65, 6,220, 0, 16, 0,211, 0, 0, 0,211, 0, 1, 0, + 12, 0,235, 5, 4, 0,236, 5, 4, 0, 37, 0,219, 0, 66, 6,221, 0, 67, 6, 12, 0, 68, 6, 12, 0, 69, 6,222, 0, 70, 6, +209, 0, 71, 6,223, 0, 72, 6, 2, 0, 73, 6, 2, 0, 74, 6, 2, 0, 75, 6, 2, 0, 70, 0,224, 0, 17, 0,211, 0, 0, 0, +211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,212, 0, 35, 6, 12, 0, 76, 6,225, 0, 77, 6, + 0, 0, 78, 6,226, 0, 79, 6, 4, 0, 80, 6, 4, 0, 81, 6, 2, 0, 19, 0, 2, 0, 82, 6, 2, 0, 83, 6, 2, 0, 37, 0, +227, 0, 29, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5, 47, 0,227, 2, + 45, 0, 58, 1, 64, 0, 84, 6, 2, 0,133, 0, 2, 0, 85, 6, 2, 0, 70, 0, 2, 0, 86, 6, 4, 0, 19, 0, 2, 0, 87, 6, + 2, 0, 40, 6, 2, 0, 39, 6, 2, 0,237, 1, 0, 0, 88, 6, 0, 0, 89, 6, 0, 0, 90, 6, 0, 0,246, 5, 7, 0, 88, 2, + 7, 0, 89, 2, 7, 0, 52, 6, 7, 0,120, 1, 7, 0, 91, 6, 7, 0, 92, 6,161, 0, 91, 3,228, 0, 11, 0,211, 0, 0, 0, +211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5, 2, 0, 38, 6, 2, 0, 19, 0, 4, 0, 37, 0, +216, 0, 36, 6,212, 0, 35, 6,229, 0, 27, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, + 2, 0,238, 5, 42, 0, 93, 6, 4, 0, 94, 6, 4, 0, 95, 6, 2, 0, 90, 0, 2, 0,133, 0, 2, 0, 96, 6, 0, 0, 97, 6, + 0, 0, 98, 6, 4, 0, 99, 6, 4, 0,100, 6, 4, 0,101, 6, 4, 0,102, 6, 2, 0,103, 6, 2, 0,104, 6, 7, 0,105, 6, + 23, 0,106, 6, 23, 0,107, 6, 4, 0,108, 6, 4, 0,109, 6, 0, 0,110, 6, 0, 0,111, 6,230, 0, 10, 0, 27, 0, 31, 0, + 9, 0,112, 6, 9, 0,113, 6, 9, 0,114, 6, 9, 0,115, 6, 9, 0,116, 6, 4, 0, 90, 0, 4, 0,117, 6, 0, 0,118, 6, + 0, 0,119, 6,231, 0, 10, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5,230, 0,120, 6, + 2, 0, 90, 0, 2, 0,133, 0, 4, 0, 43, 0, 9, 0,121, 6,232, 0, 8, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, + 4, 0,236, 5, 7, 0,237, 5,212, 0, 35, 6, 4, 0, 19, 0, 4, 0,122, 6,233, 0, 23, 0,211, 0, 0, 0,211, 0, 1, 0, + 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,212, 0, 35, 6, 27, 0,123, 6, 27, 0, 81, 0, 2, 0, 19, 0, + 2, 0,133, 0, 7, 0,124, 6, 9, 0,125, 6, 7, 0, 88, 2, 7, 0, 89, 2, 7, 0,126, 6, 7, 0,127, 6, 61, 0, 59, 1, + 61, 0,128, 6, 4, 0,129, 6, 2, 0,130, 6, 2, 0, 37, 0,161, 0, 91, 3,234, 0, 10, 0,211, 0, 0, 0,211, 0, 1, 0, + 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5, 2, 0, 19, 0, 2, 0,114, 3, 4, 0, 37, 0,161, 0, 91, 3, +235, 0, 42, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,212, 0, 35, 6, +221, 0, 67, 6, 0, 0, 53, 6, 0, 0, 54, 6, 0, 0, 55, 6, 2, 0, 17, 0, 2, 0, 63, 6, 2, 0, 19, 0, 2, 0, 57, 6, + 9, 0,125, 6, 4, 0, 60, 6, 4, 0,131, 6, 4, 0,132, 6, 4, 0, 61, 6, 23, 0,133, 6, 23, 0,134, 6, 7, 0,135, 6, + 7, 0,136, 6, 7, 0,137, 6, 7, 0,124, 6, 2, 0,138, 6, 2, 0,237, 0, 2, 0,180, 1, 2, 0, 59, 6, 2, 0, 37, 0, + 2, 0, 43, 0, 2, 0,139, 6, 2, 0,140, 6, 9, 0,141, 6, 9, 0,142, 6, 9, 0,143, 6, 9, 0,144, 6, 9, 0,145, 6, + 2, 0,146, 6, 0, 0, 65, 6, 57, 0,147, 6,236, 0, 7, 0,236, 0, 0, 0,236, 0, 1, 0, 4, 0,148, 6, 4, 0, 23, 0, + 0, 0, 84, 0, 4, 0,149, 6, 4, 0, 17, 0,237, 0, 13, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, + 7, 0,237, 5, 2, 0,238, 5, 4, 0, 17, 0, 4, 0,150, 6, 4, 0, 19, 0, 4, 0, 96, 6, 12, 0,151, 6, 12, 0,152, 6, + 0, 0,153, 6,238, 0, 5, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 4, 0, 37, 0,239, 0, 7, 0, +239, 0, 0, 0,239, 0, 1, 0, 0, 0,154, 6, 2, 0,155, 6, 2, 0,156, 6, 2, 0,157, 6, 2, 0, 37, 0,240, 0, 12, 0, + 2, 0,156, 6, 2, 0,158, 6, 2, 0,159, 6, 0, 0,188, 2, 2, 0,160, 6, 2, 0,161, 6, 2, 0,162, 6, 2, 0,163, 6, + 2, 0,164, 6, 2, 0, 25, 6, 7, 0,165, 6, 7, 0,166, 6,241, 0, 18, 0,241, 0, 0, 0,241, 0, 1, 0, 0, 0,227, 3, +240, 0,167, 6,240, 0,168, 6,240, 0,169, 6,240, 0,170, 6, 7, 0,171, 6, 2, 0,172, 6, 2, 0,173, 6, 2, 0,174, 6, + 2, 0,175, 6, 2, 0,176, 6, 2, 0,177, 6, 2, 0,178, 6, 2, 0,179, 6, 2, 0,180, 6, 2, 0,181, 6,242, 0, 10, 0, + 0, 0,182, 6, 0, 0,183, 6, 0, 0,184, 6, 0, 0,185, 6, 0, 0,186, 6, 0, 0,187, 6, 2, 0,188, 6, 2, 0,189, 6, + 2, 0,190, 6, 2, 0, 37, 0,243, 0, 8, 0, 0, 0,191, 6, 0, 0,192, 6, 0, 0,193, 6, 0, 0,194, 6, 0, 0,195, 6, + 0, 0,196, 6, 7, 0,204, 5, 7, 0, 37, 0,244, 0, 17, 0,242, 0,197, 6,242, 0,198, 6,242, 0,199, 6,242, 0,200, 6, +242, 0,201, 6,242, 0,202, 6,242, 0,203, 6,242, 0,204, 6,242, 0,205, 6,242, 0,206, 6,242, 0,207, 6,242, 0,208, 6, +242, 0,209, 6,242, 0,210, 6,242, 0,211, 6,243, 0,212, 6, 0, 0,213, 6,245, 0, 71, 0, 0, 0,214, 6, 0, 0,215, 6, + 0, 0,186, 6, 0, 0,216, 6, 0, 0,217, 6, 0, 0,218, 6, 0, 0,219, 6, 0, 0,220, 6, 0, 0,221, 6, 0, 0,222, 6, + 0, 0,223, 6, 0, 0,224, 6, 0, 0,225, 6, 0, 0,226, 6, 0, 0,227, 6, 0, 0,228, 6, 0, 0,229, 6, 0, 0,230, 6, + 0, 0,231, 6, 0, 0,232, 6, 0, 0,233, 6, 0, 0,234, 6, 0, 0,235, 6, 0, 0,236, 6, 0, 0,237, 6, 0, 0,238, 6, + 0, 0,239, 6, 0, 0,240, 6, 0, 0,241, 6, 0, 0,242, 6, 0, 0,243, 6, 0, 0,244, 6, 0, 0,245, 6, 0, 0,246, 6, + 0, 0,247, 6, 0, 0,248, 6, 0, 0,249, 6, 0, 0,250, 6, 0, 0,251, 6, 0, 0,252, 6, 0, 0,253, 6, 0, 0,254, 6, + 0, 0,255, 6, 0, 0, 0, 7, 0, 0, 1, 7, 0, 0, 2, 7, 0, 0, 3, 7, 0, 0, 4, 7, 0, 0, 5, 7, 0, 0, 6, 7, + 0, 0, 7, 7, 0, 0, 8, 7, 0, 0, 9, 7, 0, 0, 10, 7, 0, 0, 11, 7, 0, 0, 12, 7, 0, 0, 13, 7, 0, 0, 14, 7, + 0, 0, 15, 7, 0, 0, 16, 7, 0, 0, 17, 7, 0, 0, 18, 7, 0, 0, 19, 7, 0, 0, 20, 7, 0, 0, 21, 7, 0, 0, 22, 7, + 0, 0, 23, 7, 0, 0, 24, 7, 0, 0, 25, 7, 0, 0, 26, 7, 0, 0, 92, 0,246, 0, 5, 0, 0, 0, 27, 7, 0, 0,238, 6, + 0, 0,240, 6, 2, 0, 19, 0, 2, 0, 37, 0,247, 0, 22, 0,247, 0, 0, 0,247, 0, 1, 0, 0, 0, 20, 0,244, 0, 28, 7, +245, 0, 29, 7,245, 0, 30, 7,245, 0, 31, 7,245, 0, 32, 7,245, 0, 33, 7,245, 0, 34, 7,245, 0, 35, 7,245, 0, 36, 7, +245, 0, 37, 7,245, 0, 38, 7,245, 0, 39, 7,245, 0, 40, 7,245, 0, 41, 7,245, 0, 42, 7,245, 0, 43, 7,245, 0, 44, 7, +245, 0, 45, 7,246, 0, 46, 7,248, 0, 5, 0, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,136, 2, 7, 0, 47, 7, 7, 0, 42, 2, +249, 0, 71, 0, 4, 0, 19, 0, 4, 0, 48, 7, 4, 0, 49, 7, 0, 0, 50, 7, 0, 0, 51, 7, 0, 0, 52, 7, 0, 0, 53, 7, + 0, 0, 54, 7, 0, 0, 55, 7, 0, 0, 56, 7, 0, 0, 57, 7, 0, 0, 58, 7, 2, 0, 59, 7, 2, 0, 37, 0, 4, 0, 60, 7, + 4, 0, 61, 7, 4, 0, 62, 7, 4, 0, 63, 7, 2, 0, 64, 7, 2, 0, 65, 7, 4, 0, 66, 7, 4, 0, 67, 7, 4, 0, 68, 7, + 4, 0, 69, 7, 4, 0, 70, 7, 4, 0,151, 6, 4, 0, 71, 7, 2, 0, 72, 7, 2, 0, 73, 7, 2, 0, 74, 7, 2, 0, 75, 7, + 12, 0, 76, 7, 12, 0, 77, 7, 12, 0, 78, 7, 2, 0, 79, 7, 2, 0, 80, 7, 2, 0, 81, 7, 2, 0, 82, 7, 2, 0, 83, 7, + 2, 0, 84, 7, 2, 0, 85, 7, 2, 0, 86, 7,248, 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, 4, 0, 96, 7, 4, 0, 97, 7, 2, 0, 98, 7, 2, 0, 99, 7, + 2, 0,100, 7, 2, 0,101, 7, 2, 0,102, 7, 2, 0,103, 7, 2, 0,104, 7, 2, 0,105, 7, 2, 0,106, 7, 2, 0,107, 7, + 2, 0,108, 7, 2, 0,109, 7, 0, 0,110, 7, 0, 0,111, 7, 7, 0,112, 7, 2, 0,131, 5, 2, 0,132, 5, 55, 0,113, 7, +214, 0, 21, 0, 27, 0, 31, 0, 12, 0,114, 7, 12, 0,115, 7, 12, 0,116, 7, 12, 0,235, 5, 46, 0,134, 0, 46, 0,117, 7, + 2, 0,118, 7, 2, 0,119, 7, 2, 0,120, 7, 2, 0,121, 7, 2, 0,122, 7, 2, 0,123, 7, 2, 0,124, 7, 2, 0, 37, 0, + 2, 0,125, 7, 2, 0,126, 7, 4, 0, 70, 0,209, 0,127, 7, 9, 0,128, 7, 2, 0,129, 7,250, 0, 5, 0,250, 0, 0, 0, +250, 0, 1, 0,250, 0,130, 7, 13, 0,131, 7, 4, 0, 19, 0,251, 0, 7, 0,251, 0, 0, 0,251, 0, 1, 0,250, 0,132, 7, +250, 0,133, 7, 2, 0,240, 4, 2, 0, 19, 0, 4, 0, 37, 0,252, 0, 23, 0,252, 0, 0, 0,252, 0, 1, 0,253, 0,134, 7, +254, 0, 72, 6, 0, 0,135, 7, 0, 0,136, 7, 0, 0,137, 7, 2, 0,138, 7, 2, 0,139, 7, 2, 0,140, 7, 2, 0,141, 7, + 2, 0,142, 7, 2, 0, 37, 0, 2, 0, 19, 0, 2, 0,143, 7, 2, 0,144, 7, 2, 0,145, 7, 4, 0,146, 7,252, 0,147, 7, + 9, 0,148, 7, 4, 0,149, 7, 4, 0,150, 7, 0, 0,151, 7,255, 0, 22, 0,255, 0, 0, 0,255, 0, 1, 0,250, 0,132, 7, +250, 0,133, 7,250, 0,152, 7,250, 0,153, 7,214, 0,154, 7, 23, 0, 52, 0, 0, 0,236, 5, 0, 0,155, 7, 2, 0, 26, 6, + 2, 0, 27, 6, 2, 0,156, 7, 2, 0, 37, 0, 2, 0,121, 7, 2, 0,149, 6, 2, 0, 19, 0, 0, 1,134, 7, 12, 0,157, 7, + 12, 0,235, 5, 12, 0,158, 7, 12, 0,159, 7, 1, 1, 21, 0, 1, 1, 0, 0, 1, 1, 1, 0,212, 0, 35, 6, 23, 0,160, 7, + 23, 0,161, 7, 2, 0, 26, 6, 2, 0, 27, 6, 2, 0,162, 7, 2, 0,163, 7, 2, 0,164, 7, 2, 0, 19, 0, 7, 0, 84, 2, + 2, 0,120, 7, 2, 0,124, 7, 4, 0, 43, 0, 2, 1,134, 7, 12, 0,165, 7, 12, 0,166, 7, 12, 0,158, 7, 0, 0,167, 7, + 9, 0,168, 7, 3, 1, 11, 0, 0, 0,169, 7, 2, 0,170, 7, 2, 0,171, 7, 2, 0,172, 7, 2, 0,173, 7, 2, 0,229, 4, + 2, 0,224, 4,214, 0,174, 7, 46, 0,175, 7, 4, 0,176, 7, 4, 0,177, 7, 4, 1, 1, 0, 0, 0,178, 7, 5, 1, 8, 0, + 57, 0,179, 7, 57, 0,180, 7, 5, 1,181, 7, 5, 1,182, 7, 5, 1,183, 7, 2, 0,129, 0, 2, 0, 19, 0, 4, 0,184, 7, + 6, 1, 4, 0, 4, 0, 94, 6, 4, 0,185, 7, 4, 0, 99, 6, 4, 0,186, 7, 7, 1, 2, 0, 4, 0,187, 7, 4, 0,188, 7, + 8, 1, 7, 0, 7, 0,189, 7, 7, 0,190, 7, 7, 0,191, 7, 4, 0, 19, 0, 4, 0, 37, 0, 7, 0,108, 4, 7, 0,192, 7, + 9, 1, 6, 0, 0, 0,193, 7, 0, 0, 55, 6, 49, 0,137, 0, 2, 0,106, 0, 2, 0,228, 4, 4, 0, 37, 0, 10, 1, 21, 0, + 10, 1, 0, 0, 10, 1, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0,194, 7, 4, 0,195, 7, 4, 0,196, 7, + 4, 1,197, 7, 0, 0,193, 7, 4, 0,198, 7, 4, 0,199, 7, 9, 1, 85, 3, 6, 1,200, 7, 7, 1,201, 7, 8, 1,202, 7, + 5, 1,203, 7, 5, 1,204, 7, 5, 1,205, 7, 57, 0,206, 7, 57, 0,207, 7, 11, 1, 12, 0, 0, 0, 4, 2, 9, 0,223, 0, + 0, 0,224, 0, 4, 0,227, 0, 4, 0,235, 0, 9, 0,228, 0, 7, 0,230, 0, 7, 0,231, 0, 9, 0,208, 7, 9, 0,209, 7, + 9, 0,232, 0, 9, 0,234, 0, 12, 1, 43, 0, 12, 1, 0, 0, 12, 1, 1, 0, 9, 0,210, 7, 9, 0, 26, 0, 0, 0, 27, 0, + 4, 0, 19, 0, 4, 0, 17, 0, 4, 0, 23, 0, 4, 0, 88, 0, 4, 0,211, 7, 4, 0,212, 7, 4, 0,195, 7, 4, 0,196, 7, + 4, 0,213, 7, 4, 0,246, 0, 4, 0,214, 7, 4, 0,215, 7, 7, 0, 97, 5, 7, 0,216, 7, 4, 0,126, 0, 4, 0,217, 7, + 10, 1,218, 7, 36, 0, 80, 0, 46, 0,134, 0, 49, 0,137, 0, 7, 0,219, 7, 7, 0,220, 7, 11, 1, 60, 1, 12, 1,221, 7, + 12, 1,222, 7, 12, 1,223, 7, 12, 0,224, 7, 13, 1,225, 7, 14, 1,226, 7, 7, 0,227, 7, 7, 0,228, 7, 4, 0,229, 7, + 7, 0,230, 7, 9, 0,231, 7, 4, 0,232, 7, 4, 0,233, 7, 4, 0,234, 7, 7, 0,235, 7, 15, 1, 4, 0, 15, 1, 0, 0, + 15, 1, 1, 0, 12, 0,236, 7, 12, 1,237, 7,200, 0, 6, 0, 12, 0,238, 7, 12, 0,224, 7, 12, 0,239, 7, 12, 1,240, 7, + 0, 0,241, 7, 0, 0,242, 7, 16, 1, 4, 0, 7, 0,243, 7, 7, 0,109, 0, 2, 0,244, 7, 2, 0,245, 7, 17, 1, 6, 0, + 7, 0,246, 7, 7, 0,247, 7, 7, 0,248, 7, 7, 0,249, 7, 4, 0,250, 7, 4, 0,251, 7, 18, 1, 12, 0, 7, 0,252, 7, + 7, 0,253, 7, 7, 0,254, 7, 7, 0,255, 7, 7, 0, 0, 8, 7, 0, 1, 8, 7, 0, 2, 8, 7, 0, 3, 8, 7, 0, 4, 8, + 7, 0, 5, 8, 4, 0,231, 2, 4, 0, 6, 8, 19, 1, 2, 0, 7, 0, 66, 5, 7, 0, 37, 0, 20, 1, 5, 0, 7, 0, 7, 8, + 7, 0, 8, 8, 4, 0, 90, 0, 4, 0,189, 2, 4, 0, 9, 8, 21, 1, 6, 0, 21, 1, 0, 0, 21, 1, 1, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 2, 0, 10, 8, 2, 0, 57, 0, 22, 1, 8, 0, 22, 1, 0, 0, 22, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, + 2, 0, 10, 8, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0,126, 0, 23, 1, 45, 0, 23, 1, 0, 0, 23, 1, 1, 0, 2, 0, 17, 0, + 2, 0, 19, 0, 2, 0, 10, 8, 2, 0,242, 0, 2, 0, 22, 4, 2, 0, 11, 8, 7, 0, 12, 8, 7, 0, 89, 0, 7, 0,244, 2, + 4, 0, 13, 8, 4, 0, 82, 0, 4, 0,191, 2, 7, 0, 14, 8, 7, 0, 15, 8, 7, 0, 16, 8, 7, 0, 17, 8, 7, 0, 18, 8, + 7, 0, 19, 8, 7, 0,241, 2, 7, 0, 57, 1, 7, 0, 20, 8, 7, 0, 21, 8, 7, 0, 37, 0, 7, 0, 22, 8, 7, 0, 23, 8, + 7, 0, 24, 8, 2, 0, 25, 8, 2, 0, 26, 8, 2, 0, 27, 8, 2, 0, 28, 8, 2, 0, 29, 8, 2, 0, 30, 8, 2, 0, 31, 8, + 2, 0, 32, 8, 2, 0, 27, 2, 2, 0, 33, 8, 2, 0, 24, 2, 2, 0, 34, 8, 0, 0, 35, 8, 0, 0, 36, 8, 7, 0,240, 0, + 24, 1, 37, 8, 68, 0,240, 1, 25, 1, 16, 0, 25, 1, 0, 0, 25, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 10, 8, + 2, 0,242, 0, 7, 0,236, 2, 7, 0,237, 2, 7, 0,238, 2, 7, 0, 73, 2, 7, 0,239, 2, 7, 0,240, 2, 7, 0, 38, 8, + 7, 0,241, 2, 7, 0,243, 2, 7, 0,244, 2,226, 0, 5, 0, 2, 0, 17, 0, 2, 0,184, 7, 2, 0, 19, 0, 2, 0, 39, 8, + 27, 0,123, 6,225, 0, 3, 0, 4, 0, 69, 0, 4, 0, 40, 8,226, 0, 2, 0, 26, 1, 7, 0, 26, 1, 0, 0, 26, 1, 1, 0, + 0, 0, 20, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 22, 0, 9, 0, 41, 8, 27, 1, 5, 0, 0, 0, 20, 0, 7, 0, 77, 1, + 7, 0, 42, 8, 4, 0, 43, 8, 4, 0, 37, 0, 28, 1, 4, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 43, 0, 2, 0, 70, 0, + 29, 1, 4, 0, 0, 0, 20, 0, 67, 0, 44, 8, 7, 0, 77, 1, 7, 0, 37, 0, 30, 1, 6, 0, 2, 0, 45, 8, 2, 0, 46, 8, + 2, 0, 17, 0, 2, 0, 47, 8, 0, 0, 48, 8, 0, 0, 49, 8, 31, 1, 5, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0, + 0, 0, 50, 8, 0, 0, 51, 8, 32, 1, 3, 0, 4, 0, 17, 0, 4, 0, 37, 0, 0, 0, 20, 0, 33, 1, 4, 0, 2, 0, 52, 8, + 2, 0, 53, 8, 2, 0, 19, 0, 2, 0, 37, 0, 34, 1, 6, 0, 0, 0, 20, 0, 0, 0, 54, 8, 2, 0, 55, 8, 2, 0,241, 2, + 2, 0, 70, 1, 2, 0, 70, 0, 35, 1, 5, 0, 0, 0, 20, 0, 7, 0,109, 0, 7, 0,110, 4, 2, 0, 19, 0, 2, 0,203, 2, + 36, 1, 3, 0, 0, 0, 20, 0, 4, 0,191, 2, 4, 0, 52, 8, 37, 1, 7, 0, 0, 0, 20, 0, 7, 0,110, 4, 0, 0, 56, 8, + 0, 0, 57, 8, 2, 0, 70, 1, 2, 0, 43, 0, 4, 0, 58, 8, 38, 1, 4, 0, 0, 0, 59, 8, 0, 0, 60, 8, 4, 0, 17, 0, + 7, 0,207, 2, 39, 1, 3, 0, 32, 0, 61, 8, 0, 0, 62, 8, 0, 0, 63, 8, 40, 1, 18, 0, 40, 1, 0, 0, 40, 1, 1, 0, + 2, 0, 17, 0, 2, 0, 64, 8, 2, 0, 19, 0, 2, 0, 65, 8, 2, 0, 66, 8, 2, 0, 67, 8, 2, 0, 43, 0, 2, 0, 70, 0, + 0, 0, 20, 0, 9, 0, 2, 0, 41, 1, 68, 8, 32, 0, 45, 0, 2, 0, 81, 5, 2, 0,227, 7, 2, 0, 69, 8, 2, 0, 37, 0, + 42, 1, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0, 0, 0, 70, 8, 2, 0, 19, 0, 2, 0,203, 2, 2, 0, 71, 8, 4, 0, 72, 8, + 4, 0, 73, 8, 4, 0, 74, 8, 4, 0, 75, 8, 4, 0, 76, 8, 43, 1, 1, 0, 0, 0, 77, 8, 44, 1, 4, 0, 42, 0, 93, 6, + 0, 0, 78, 8, 4, 0, 70, 1, 4, 0, 19, 0, 41, 1, 18, 0, 41, 1, 0, 0, 41, 1, 1, 0, 41, 1, 79, 8, 2, 0, 17, 0, + 2, 0, 19, 0, 2, 0, 80, 8, 2, 0, 67, 8, 2, 0, 64, 8, 2, 0, 81, 8, 2, 0, 70, 0, 2, 0,237, 1, 0, 0, 20, 0, + 9, 0, 2, 0, 45, 1, 68, 8, 40, 1, 82, 8, 2, 0, 15, 0, 2, 0, 83, 8, 4, 0, 84, 8, 46, 1, 3, 0, 4, 0,217, 2, + 4, 0, 37, 0, 32, 0, 45, 0, 47, 1, 12, 0,159, 0, 85, 8, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 12, 8, 4, 0, 89, 0, + 0, 0, 20, 0, 0, 0, 86, 8, 2, 0, 87, 8, 2, 0, 88, 8, 2, 0, 89, 8, 2, 0, 90, 8, 7, 0, 91, 8, 48, 1, 13, 0, + 2, 0, 19, 0, 2, 0, 92, 8, 4, 0, 12, 8, 4, 0, 89, 0, 2, 0, 93, 8, 7, 0,236, 3, 7, 0, 94, 8, 13, 1,225, 7, + 49, 1, 95, 8, 2, 0, 17, 0, 2, 0, 96, 8, 2, 0, 97, 8, 2, 0, 98, 8, 50, 1, 11, 0, 4, 0,217, 2, 2, 0, 17, 0, + 2, 0, 19, 0, 32, 0, 45, 0, 81, 0, 99, 8, 0, 0, 20, 0, 7, 0,100, 8, 7, 0,101, 8, 7, 0,122, 3, 2, 0,102, 8, + 2, 0,103, 8, 51, 1, 5, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 37, 0, 46, 0,134, 0, 32, 0,178, 5, 52, 1, 5, 0, + 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 20, 0, 0, 0, 50, 8, 32, 0, 45, 0, 53, 1, 13, 0, 2, 0, 19, 0, 2, 0, 17, 0, + 2, 0, 64, 8, 2, 0,123, 3, 7, 0,104, 8, 7, 0,105, 8, 7, 0, 65, 1, 7, 0, 66, 1, 7, 0, 98, 3, 7, 0,101, 3, + 7, 0,106, 8, 7, 0,107, 8, 32, 0,108, 8, 54, 1, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0, 12, 8, 4, 0, 89, 0, + 0, 0, 20, 0, 0, 0, 86, 8, 2, 0, 43, 0, 2, 0, 64, 0, 2, 0,109, 8, 2, 0,110, 8, 55, 1, 8, 0, 32, 0, 45, 0, + 7, 0,238, 2, 7, 0,111, 8, 7, 0,112, 8, 7, 0,233, 2, 2, 0, 19, 0, 2, 0,203, 2, 7, 0,113, 8, 56, 1, 12, 0, + 2, 0, 17, 0, 2, 0, 70, 1, 2, 0, 19, 0, 2, 0,241, 2, 2, 0,217, 2, 2, 0,114, 8, 4, 0, 37, 0, 7, 0,115, 8, + 7, 0,116, 8, 7, 0,117, 8, 7, 0,118, 8, 0, 0,119, 8, 57, 1, 9, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 0, 12, 8, + 4, 0, 89, 0, 0, 0, 20, 0, 2, 0,135, 1, 2, 0, 64, 0, 2, 0,109, 8, 2, 0,110, 8, 58, 1, 7, 0, 4, 0,191, 2, + 4, 0,120, 8, 4, 0,121, 8, 4, 0,122, 8, 7, 0,123, 8, 7, 0,124, 8, 0, 0, 56, 8, 59, 1, 7, 0, 0, 0,125, 8, + 32, 0,126, 8, 0, 0, 62, 8, 2, 0,127, 8, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0, 63, 8, 60, 1, 6, 0, 2, 0, 19, 0, + 2, 0, 17, 0, 4, 0, 12, 8, 4, 0, 89, 0, 0, 0,128, 8, 0, 0,129, 8, 61, 1, 1, 0, 4, 0, 19, 0, 62, 1, 6, 0, + 0, 0, 92, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0,130, 8, 7, 0,131, 8, 42, 0, 93, 6, 63, 1, 4, 0, 0, 0, 69, 2, + 2, 0, 19, 0, 4, 0, 17, 0, 32, 0, 45, 0, 64, 1, 2, 0, 4, 0, 17, 0, 4, 0, 15, 6, 65, 1, 6, 0, 0, 0, 59, 8, + 0, 0, 60, 8, 4, 0, 17, 0, 7, 0, 35, 2, 32, 0, 48, 3, 32, 0,132, 8, 45, 1, 10, 0, 45, 1, 0, 0, 45, 1, 1, 0, + 45, 1, 79, 8, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0, 64, 8, 2, 0,133, 8, 0, 0, 20, 0, 9, 0, 2, 0, 32, 0, 45, 0, + 66, 1, 10, 0, 7, 0,122, 3, 7, 0,134, 8, 7, 0,135, 8, 7, 0,136, 8, 7, 0,137, 8, 4, 0, 19, 0, 7, 0,114, 8, + 7, 0,138, 8, 7, 0,139, 8, 7, 0, 37, 0, 14, 1, 12, 0, 14, 1, 0, 0, 14, 1, 1, 0, 13, 1,140, 8, 9, 0,223, 0, + 4, 0,165, 3, 4, 0,223, 3, 4, 0,224, 3, 4, 0,141, 8, 4, 0,142, 8, 4, 0,143, 8, 7, 0,236, 3, 7, 0, 37, 0, + 49, 1, 8, 0, 7, 0,144, 8, 7, 0,145, 8, 7, 0,146, 8, 7, 0,147, 8, 7, 0,148, 8, 7, 0,149, 8, 7, 0,150, 8, + 7, 0,151, 8, 13, 1, 15, 0, 27, 0, 31, 0, 0, 0,222, 0, 43, 0,149, 0, 9, 0,223, 0, 43, 0,152, 8, 36, 0, 80, 0, + 7, 0,236, 3, 7, 0,153, 8, 7, 0, 94, 8, 7, 0,144, 8, 7, 0,145, 8, 7, 0,154, 8, 4, 0, 90, 0, 4, 0,143, 8, + 9, 0,155, 8, 67, 1, 15, 0,211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5,255, 0,156, 8, +212, 0, 35, 6, 13, 1,225, 7, 2, 0, 70, 1, 2, 0, 92, 8, 2, 0, 88, 2, 2, 0, 89, 2, 2, 0, 19, 0, 2, 0, 40, 6, + 4, 0, 70, 0, 68, 1, 6, 0, 68, 1, 0, 0, 68, 1, 1, 0, 32, 0, 45, 0, 9, 0,157, 8, 4, 0,247, 0, 4, 0, 37, 0, + 68, 0, 4, 0, 27, 0, 31, 0, 12, 0,158, 8, 4, 0,131, 0, 7, 0,159, 8, 69, 1, 25, 0, 69, 1, 0, 0, 69, 1, 1, 0, + 69, 1, 38, 0, 12, 0,160, 8, 0, 0, 20, 0, 7, 0,161, 8, 7, 0,162, 8, 7, 0,163, 8, 7, 0,164, 8, 4, 0, 19, 0, + 7, 0,165, 8, 7, 0,166, 8, 7, 0,167, 8, 7, 0, 77, 1, 7, 0, 35, 2, 7, 0,168, 8, 7, 0,189, 2, 7, 0,169, 8, + 7, 0,170, 8, 7, 0,171, 8, 7, 0,172, 8, 7, 0,173, 8, 7, 0,172, 0, 2, 0,131, 0, 2, 0,112, 5, 70, 1, 22, 0, + 27, 0, 31, 0, 39, 0, 75, 0, 12, 0,174, 8, 12, 0,175, 8, 12, 0,176, 8, 9, 0,177, 8, 4, 0, 19, 0, 4, 0,244, 5, + 2, 0,245, 2, 2, 0, 46, 6, 2, 0,131, 0, 2, 0,178, 8, 2, 0,179, 8, 2, 0,180, 8, 2, 0,181, 8, 2, 0,182, 8, + 4, 0,183, 8, 4, 0,184, 8, 4, 0,185, 8, 4, 0,186, 8, 4, 0,187, 8, 4, 0,188, 8, 71, 1, 2, 0, 7, 0,150, 2, + 4, 0, 19, 0, 72, 1, 5, 0, 71, 1,189, 8, 4, 0,189, 2, 4, 0,190, 8, 4, 0,191, 8, 4, 0, 19, 0, 73, 1, 6, 0, + 4, 0, 37, 0, 4, 0, 46, 6, 4, 0,185, 8, 4, 0,186, 8, 4, 0,187, 8, 4, 0,188, 8, 74, 1, 40, 0, 74, 1, 0, 0, + 74, 1, 1, 0, 26, 0,192, 8, 12, 0,149, 3, 0, 0, 20, 0, 2, 0, 19, 0, 2, 0,193, 8, 2, 0,194, 8, 2, 0,195, 8, + 2, 0,108, 3, 2, 0,196, 8, 4, 0, 71, 2, 4, 0,185, 8, 4, 0,186, 8, 69, 1,197, 8, 74, 1, 38, 0, 74, 1,198, 8, + 12, 0,199, 8, 9, 0,200, 8, 9, 0,201, 8, 9, 0,202, 8, 7, 0, 65, 1, 7, 0,172, 0, 7, 0,203, 8, 7, 0, 14, 2, + 2, 0,131, 3, 2, 0, 37, 0, 7, 0,204, 8, 7, 0,205, 8, 7, 0,104, 3, 7, 0,206, 8, 7, 0,207, 8, 7, 0,208, 8, + 7, 0,209, 8, 7, 0,210, 8, 7, 0,211, 8, 7, 0,212, 8, 7, 0,213, 8, 7, 0, 64, 2, 32, 0,214, 8,160, 0, 11, 0, + 12, 0,215, 8, 2, 0, 19, 0, 2, 0,216, 8, 7, 0,100, 2, 7, 0,217, 8, 7, 0,218, 8, 12, 0,219, 8, 4, 0,220, 8, + 4, 0,221, 8, 9, 0,222, 8, 9, 0,223, 8, 75, 1, 1, 0, 4, 0,221, 8, 76, 1, 12, 0, 4, 0,221, 8, 7, 0, 76, 8, + 2, 0,224, 8, 2, 0,225, 8, 7, 0,226, 8, 7, 0,227, 8, 2, 0,228, 8, 2, 0, 19, 0, 7, 0,229, 8, 7, 0,230, 8, + 7, 0,231, 8, 7, 0,232, 8, 77, 1, 7, 0, 77, 1, 0, 0, 77, 1, 1, 0, 12, 0,233, 8, 4, 0, 19, 0, 4, 0,234, 8, + 0, 0,227, 3,246, 0,235, 8,159, 0, 7, 0, 27, 0, 31, 0, 12, 0,236, 8, 12, 0,215, 8, 12, 0,237, 8, 12, 0,100, 0, + 4, 0, 19, 0, 4, 0,238, 8,216, 0, 4, 0, 27, 0,140, 8, 12, 0,215, 8, 4, 0,239, 8, 4, 0, 19, 0, 78, 1, 17, 0, +211, 0, 0, 0,211, 0, 1, 0, 12, 0,235, 5, 4, 0,236, 5, 7, 0,237, 5, 2, 0,238, 5,212, 0, 35, 6,159, 0, 88, 3, +216, 0,240, 8, 0, 0, 70, 1, 0, 0, 38, 6, 2, 0, 19, 0, 2, 0,241, 8, 2, 0, 39, 6, 2, 0, 40, 6, 2, 0,242, 8, + 7, 0,243, 8, 79, 1, 8, 0, 79, 1, 0, 0, 79, 1, 1, 0, 77, 1,244, 8, 36, 0, 80, 0, 12, 0, 92, 3, 4, 0, 19, 0, + 0, 0, 20, 0, 4, 0,245, 8, 80, 1, 5, 0, 80, 1, 0, 0, 80, 1, 1, 0, 36, 0, 80, 0, 2, 0, 19, 0, 0, 0,246, 8, + 81, 1, 14, 0, 81, 1, 0, 0, 81, 1, 1, 0, 9, 0, 2, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0,247, 8, 0, 0,248, 8, + 0, 0,246, 8, 7, 0,249, 8, 7, 0,250, 8, 4, 0, 37, 0, 36, 0, 80, 0, 7, 0,251, 8, 7, 0,252, 8, 82, 1, 9, 0, + 82, 1, 0, 0, 82, 1, 1, 0, 32, 0,253, 8, 0, 0,248, 2, 7, 0,254, 8, 2, 0,255, 8, 2, 0, 19, 0, 2, 0, 17, 0, + 2, 0, 0, 9, 83, 1, 7, 0, 42, 0, 93, 6, 26, 0,192, 8, 4, 0, 19, 0, 4, 0, 1, 9, 12, 0, 2, 9, 32, 0,253, 8, + 0, 0,248, 2, 84, 1, 15, 0, 32, 0,253, 8, 2, 0, 3, 9, 2, 0, 19, 0, 2, 0, 4, 9, 2, 0, 5, 9, 0, 0,248, 2, + 32, 0, 6, 9, 0, 0, 7, 9, 7, 0, 8, 9, 7, 0, 35, 2, 7, 0, 9, 9, 7, 0, 10, 9, 2, 0, 17, 0, 2, 0, 70, 1, + 7, 0, 77, 1, 85, 1, 6, 0, 32, 0,253, 8, 4, 0, 11, 9, 4, 0, 12, 9, 4, 0, 90, 0, 4, 0, 37, 0, 0, 0,248, 2, + 86, 1, 4, 0, 32, 0,253, 8, 4, 0, 19, 0, 4, 0, 11, 9, 0, 0,248, 2, 87, 1, 4, 0, 32, 0,253, 8, 4, 0, 19, 0, + 4, 0, 11, 9, 0, 0,248, 2, 88, 1, 10, 0, 32, 0,253, 8, 4, 0, 13, 9, 7, 0,125, 0, 4, 0, 19, 0, 2, 0, 89, 6, + 2, 0, 14, 9, 2, 0, 43, 0, 2, 0, 70, 0, 7, 0, 15, 9, 0, 0,248, 2, 89, 1, 4, 0, 32, 0,253, 8, 4, 0, 19, 0, + 4, 0, 11, 9, 0, 0,248, 2, 90, 1, 10, 0, 32, 0,253, 8, 2, 0, 17, 0, 2, 0, 30, 4, 4, 0, 88, 0, 4, 0, 89, 0, + 7, 0,111, 8, 7, 0,112, 8, 4, 0, 37, 0,159, 0, 85, 8, 0, 0,248, 2, 91, 1, 4, 0, 32, 0,253, 8, 4, 0,109, 3, + 4, 0, 16, 9, 0, 0,248, 2, 92, 1, 5, 0, 32, 0,253, 8, 7, 0,125, 0, 4, 0, 17, 9, 4, 0,109, 3, 4, 0,110, 3, + 93, 1, 6, 0, 32, 0,253, 8, 4, 0, 18, 9, 4, 0, 19, 9, 7, 0, 20, 9, 7, 0, 21, 9, 0, 0,248, 2, 94, 1, 16, 0, + 32, 0,253, 8, 32, 0,198, 8, 4, 0, 17, 0, 7, 0, 22, 9, 7, 0, 23, 9, 7, 0, 24, 9, 7, 0, 25, 9, 7, 0, 26, 9, + 7, 0, 27, 9, 7, 0, 28, 9, 7, 0, 29, 9, 7, 0, 30, 9, 2, 0, 19, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, + 95, 1, 3, 0, 32, 0,253, 8, 4, 0, 19, 0, 4, 0, 27, 2, 96, 1, 5, 0, 32, 0,253, 8, 4, 0, 19, 0, 4, 0, 37, 0, + 7, 0, 31, 9, 0, 0,248, 2, 97, 1, 10, 0, 32, 0,253, 8, 0, 0,248, 2, 2, 0, 32, 9, 2, 0, 33, 9, 0, 0, 34, 9, + 0, 0, 35, 9, 7, 0, 36, 9, 7, 0, 37, 9, 7, 0, 38, 9, 7, 0, 39, 9, 98, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, + 7, 0, 11, 0, 7, 0, 12, 0, 7, 0, 40, 9, 7, 0, 41, 9, 2, 0, 19, 0, 2, 0, 27, 2, 99, 1, 8, 0, 7, 0, 9, 0, + 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0, 40, 9, 7, 0, 41, 9, 2, 0, 19, 0, 2, 0, 27, 2,100, 1, 8, 0, + 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0, 40, 9, 7, 0, 41, 9, 2, 0, 19, 0, 2, 0, 27, 2, +101, 1, 7, 0, 32, 0,253, 8, 0, 0,248, 2, 7, 0, 77, 1, 7, 0, 86, 1, 2, 0, 19, 0, 2, 0, 70, 1, 4, 0, 37, 0, +102, 1, 5, 0, 32, 0, 48, 3, 7, 0, 77, 1, 2, 0, 52, 3, 0, 0, 54, 3, 0, 0, 42, 9,103, 1, 10, 0,103, 1, 0, 0, +103, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 0, 43, 9, 7, 0, 21, 1, 7, 0, 22, 1, 2, 0,233, 8, 2, 0, 44, 9, + 32, 0, 45, 0,104, 1, 22, 0,104, 1, 0, 0,104, 1, 1, 0, 2, 0, 19, 0, 2, 0, 70, 1, 2, 0, 45, 9, 2, 0, 46, 9, + 36, 0, 80, 0,159, 0, 85, 8, 32, 0,164, 0, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0, 47, 9, 7, 0, 48, 9, 7, 0, 49, 9, + 7, 0, 50, 9, 7, 0,234, 2, 7, 0, 51, 9, 7, 0, 87, 8, 7, 0, 52, 9, 0, 0, 53, 9, 0, 0, 54, 9, 12, 0, 94, 3, +105, 1, 8, 0, 7, 0, 42, 2, 7, 0,111, 8, 7, 0,112, 8, 9, 0, 2, 0, 2, 0, 55, 9, 2, 0, 56, 9, 2, 0, 57, 9, + 2, 0, 58, 9,106, 1, 18, 0,106, 1, 0, 0,106, 1, 1, 0,106, 1, 59, 9, 0, 0, 20, 0,105, 1, 60, 9, 2, 0, 17, 0, + 2, 0, 19, 0, 2, 0, 61, 9, 2, 0, 62, 9, 2, 0, 63, 9, 2, 0, 64, 9, 4, 0, 43, 0, 7, 0, 65, 9, 7, 0, 66, 9, + 4, 0, 67, 9, 4, 0, 68, 9,106, 1, 69, 9,107, 1, 70, 9,108, 1, 34, 0,108, 1, 0, 0,108, 1, 1, 0,108, 1, 71, 9, + 0, 0, 20, 0, 0, 0, 72, 9, 2, 0, 17, 0, 2, 0, 19, 0, 2, 0,194, 7, 2, 0,227, 7, 2, 0, 73, 9, 2, 0,133, 0, + 2, 0, 62, 9, 2, 0,184, 7, 12, 0, 80, 8, 12, 0, 74, 9, 27, 0,123, 6, 9, 0, 75, 9, 7, 0, 65, 9, 7, 0, 66, 9, + 7, 0, 73, 2, 7, 0, 76, 9, 2, 0, 77, 9, 2, 0, 78, 9, 7, 0, 79, 9, 7, 0, 80, 9, 2, 0, 81, 9, 2, 0, 82, 9, + 9, 0, 83, 9, 24, 0, 84, 9, 24, 0, 85, 9, 24, 0, 86, 9,109, 1,150, 0,110, 1, 87, 9,111, 1, 88, 9,107, 1, 8, 0, +107, 1, 0, 0,107, 1, 1, 0,108, 1, 89, 9,108, 1, 90, 9,106, 1, 91, 9,106, 1, 69, 9, 4, 0, 19, 0, 4, 0, 37, 0, + 61, 0, 20, 0, 27, 0, 31, 0, 39, 0, 75, 0, 12, 0, 92, 9, 12, 0, 93, 9,105, 1, 94, 9, 12, 0, 95, 9, 4, 0, 17, 0, + 4, 0, 96, 9, 4, 0, 97, 9, 4, 0, 98, 9, 12, 0, 99, 9,111, 1,100, 9,106, 1,101, 9,106, 1,102, 9, 9, 0,103, 9, + 9, 0,104, 9, 4, 0,105, 9, 9, 0,106, 9, 9, 0,107, 9, 9, 0,108, 9,112, 1, 6, 0, 4, 0,124, 0, 4, 0,126, 0, + 4, 0,184, 7, 0, 0,109, 9, 0, 0,110, 9, 2, 0, 37, 0,113, 1, 16, 0, 2, 0,140, 7, 2, 0,141, 7, 2, 0,111, 9, + 2, 0,135, 8, 2, 0,112, 9, 2, 0, 68, 0, 7, 0,233, 2, 7, 0,113, 9, 7, 0,114, 9, 2, 0, 90, 1, 0, 0,115, 9, + 0, 0, 96, 5, 2, 0,116, 9, 2, 0, 37, 0, 4, 0,117, 9, 4, 0,118, 9,114, 1, 9, 0, 7, 0,119, 9, 7, 0,120, 9, + 7, 0,154, 8, 7, 0,109, 0, 7, 0,121, 9, 7, 0, 52, 6, 2, 0,122, 9, 0, 0,123, 9, 0, 0, 37, 0,115, 1, 4, 0, + 7, 0,124, 9, 7, 0,125, 9, 2, 0,122, 9, 2, 0, 37, 0,116, 1, 3, 0, 7, 0,126, 9, 7, 0,127, 9, 7, 0, 15, 0, +117, 1, 7, 0, 0, 0, 4, 2, 2, 0,226, 4, 2, 0,227, 4, 2, 0,228, 4, 2, 0,174, 4, 4, 0,126, 0, 4, 0, 28, 4, +118, 1, 7, 0, 7, 0,128, 9, 7, 0,129, 9, 7, 0,130, 9, 7, 0, 84, 2, 7, 0,131, 9, 7, 0,132, 9, 7, 0,133, 9, +119, 1, 4, 0, 2, 0,134, 9, 2, 0,135, 9, 2, 0,136, 9, 2, 0,137, 9,120, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, +121, 1, 2, 0, 0, 0,166, 0, 0, 0,138, 9,122, 1, 1, 0, 0, 0, 20, 0,123, 1, 10, 0, 0, 0,139, 9, 0, 0,140, 9, + 0, 0, 45, 6, 0, 0,141, 9, 2, 0,111, 9, 2, 0,142, 9, 7, 0,143, 9, 7, 0,144, 9, 7, 0,145, 9, 7, 0, 51, 9, +124, 1, 2, 0, 9, 0,146, 9, 9, 0,147, 9,125, 1, 11, 0, 0, 0,228, 4, 0, 0, 17, 0, 0, 0,122, 9, 0, 0,109, 0, + 0, 0,148, 9, 0, 0,106, 0, 0, 0, 69, 2, 7, 0,149, 9, 7, 0,150, 9, 7, 0,151, 9, 7, 0,152, 9,126, 1, 8, 0, + 7, 0, 45, 8, 7, 0,125, 0, 7, 0, 96, 5, 7, 0,155, 2, 7, 0,153, 9, 7, 0,236, 0, 7, 0,154, 9, 4, 0, 17, 0, +127, 1, 4, 0, 2, 0,155, 9, 2, 0,156, 9, 2, 0,157, 9, 2, 0, 37, 0,128, 1, 1, 0, 0, 0, 20, 0,129, 1, 4, 0, + 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 19, 0, 2, 0,158, 9,130, 1, 10, 0, 2, 0,216, 3, 2, 0, 19, 0, 7, 0,110, 4, + 7, 0,159, 9, 7, 0,160, 9, 7, 0,161, 9, 7, 0,162, 9,129, 1,163, 9,129, 1,164, 9,129, 1,165, 9, 64, 0, 9, 0, + 4, 0, 19, 0, 4, 0, 64, 0, 24, 0,166, 9, 24, 0,167, 9,130, 1,168, 9, 7, 0,169, 9, 7, 0,170, 9, 7, 0,171, 9, + 7, 0,172, 9,131, 1, 4, 0, 47, 0,227, 2, 7, 0,173, 9, 7, 0,169, 1, 7, 0, 37, 0,189, 0, 17, 0, 27, 0, 31, 0, +131, 1,174, 9, 64, 0,163, 9, 51, 0,133, 1, 2, 0, 19, 0, 2, 0,204, 5, 4, 0,106, 0, 7, 0,175, 9, 7, 0, 81, 2, + 4, 0,176, 9, 7, 0,177, 9, 7, 0,178, 9, 7, 0,179, 9, 7, 0,169, 1, 2, 0,103, 1, 0, 0,180, 9, 0, 0,181, 6, +132, 1, 10, 0, 4, 0, 17, 0, 4, 0,125, 0, 4, 0, 19, 0, 4, 0,171, 3, 4, 0,181, 9, 4, 0,182, 9, 4, 0,183, 9, + 0, 0, 92, 0, 0, 0, 20, 0, 9, 0, 2, 0, 92, 0, 6, 0,132, 1,184, 9, 4, 0,185, 9, 4, 0,186, 9, 4, 0,187, 9, + 4, 0, 37, 0, 9, 0,188, 9,133, 1, 5, 0, 7, 0,150, 2, 7, 0,217, 2, 7, 0, 35, 2, 2, 0,189, 9, 2, 0, 37, 0, +134, 1, 5, 0, 7, 0,150, 2, 7, 0,190, 9, 7, 0,191, 9, 7, 0,192, 9, 7, 0,217, 2,135, 1, 5, 0, 32, 0,193, 9, +136, 1, 22, 0, 7, 0,177, 5, 7, 0,194, 9, 7, 0, 57, 0,137, 1, 7, 0, 4, 0,195, 9, 4, 0,196, 9, 4, 0,197, 9, + 7, 0,198, 9, 7, 0,199, 9, 7, 0,200, 9, 7, 0, 57, 0,138, 1, 8, 0,138, 1, 0, 0,138, 1, 1, 0, 32, 0, 45, 0, + 4, 0, 35, 3, 2, 0, 19, 0, 2, 0, 70, 1, 7, 0,217, 2, 7, 0, 53, 8,139, 1, 18, 0,134, 1,165, 3,134, 1,201, 9, +133, 1,202, 9,134, 1, 37, 8,135, 1,203, 9, 4, 0, 82, 0, 7, 0,217, 2, 7, 0,244, 2, 7, 0,204, 9, 4, 0,195, 9, + 4, 0,205, 9, 7, 0,199, 9, 7, 0,200, 9, 7, 0,106, 0, 2, 0, 19, 0, 2, 0,206, 9, 2, 0,207, 9, 2, 0,208, 9, +140, 1,107, 0, 27, 0, 31, 0, 39, 0, 75, 0,141, 1,209, 9,168, 0, 50, 4, 4, 0, 19, 0, 2, 0, 17, 0, 2, 0, 32, 9, + 2, 0,210, 9, 2, 0,211, 9, 2, 0,131, 3, 2, 0,212, 9, 2, 0,213, 9, 2, 0,214, 9, 2, 0,215, 9, 2, 0,216, 9, + 2, 0,217, 9, 2, 0,218, 9, 2, 0,216, 4, 2, 0, 89, 5, 2, 0,219, 9, 2, 0,220, 9, 2, 0,221, 9, 2, 0,222, 9, + 2, 0,223, 9, 2, 0, 24, 2, 2, 0, 30, 8, 2, 0, 6, 8, 2, 0,224, 9, 2, 0,225, 9, 2, 0,181, 3, 2, 0,182, 3, + 2, 0,226, 9, 2, 0,227, 9, 2, 0,228, 9, 2, 0,229, 9, 7, 0,230, 9, 7, 0,231, 9, 7, 0,232, 9, 2, 0,233, 9, + 2, 0,234, 9, 7, 0,235, 9, 7, 0,236, 9, 7, 0,237, 9, 7, 0, 12, 8, 7, 0, 89, 0, 7, 0,244, 2, 7, 0, 18, 8, + 7, 0,238, 9, 7, 0,239, 9, 7, 0,240, 9, 4, 0, 13, 8, 4, 0, 11, 8, 4, 0,241, 9, 7, 0, 14, 8, 7, 0, 15, 8, + 7, 0, 16, 8, 7, 0,242, 9, 7, 0,243, 9, 7, 0,244, 9, 7, 0,245, 9, 7, 0,246, 9, 7, 0,247, 9, 7, 0,248, 9, + 7, 0,249, 9, 7, 0,122, 3, 7, 0,106, 0, 7, 0,250, 9, 7, 0,251, 9, 7, 0,252, 9, 7, 0,253, 9, 7, 0,254, 9, + 7, 0,255, 9, 7, 0, 0, 10, 4, 0, 1, 10, 4, 0, 2, 10, 7, 0, 3, 10, 7, 0, 4, 10, 7, 0, 5, 10, 7, 0, 6, 10, + 7, 0, 7, 10, 7, 0,210, 0, 7, 0, 8, 10, 7, 0,207, 3, 7, 0,205, 3, 7, 0,206, 3, 7, 0, 9, 10, 7, 0, 10, 10, + 7, 0, 11, 10, 7, 0, 12, 10, 7, 0, 13, 10, 7, 0, 14, 10, 7, 0, 15, 10, 7, 0, 16, 10, 7, 0, 17, 10, 7, 0, 18, 10, + 7, 0, 19, 10, 7, 0, 20, 10, 7, 0, 21, 10, 4, 0, 22, 10, 4, 0, 23, 10, 68, 0,154, 3, 68, 0, 24, 10, 32, 0, 25, 10, + 32, 0, 26, 10, 36, 0, 80, 0,163, 0, 62, 1,163, 0, 27, 10, 59, 0, 44, 0, 59, 0, 0, 0, 59, 0, 1, 0,140, 1, 28, 10, +139, 1, 29, 10,137, 1,198, 8,170, 0,232, 3, 9, 0,233, 3,142, 1, 30, 10,142, 1, 31, 10, 12, 0, 32, 10, 12, 0, 33, 10, +134, 0, 34, 10,142, 0, 35, 10,142, 0, 36, 10, 32, 0, 37, 10, 32, 0, 38, 10, 32, 0, 38, 0, 12, 0, 2, 9, 0, 0, 20, 0, + 7, 0,240, 0, 7, 0, 15, 3, 7, 0, 39, 10, 4, 0,191, 2, 4, 0, 57, 0, 4, 0, 19, 0, 4, 0, 13, 8, 4, 0, 40, 10, + 4, 0, 41, 10, 4, 0, 42, 10, 2, 0,247, 0, 2, 0, 43, 10, 2, 0, 44, 10, 2, 0, 45, 10, 0, 0, 46, 10, 2, 0, 47, 10, + 2, 0, 48, 10, 2, 0, 49, 10, 9, 0, 50, 10,138, 0, 49, 4, 12, 0, 2, 3, 12, 0, 51, 10,143, 1, 52, 10,144, 1, 53, 10, + 7, 0, 54, 10,136, 0, 35, 0,145, 1,155, 8, 7, 0, 19, 4, 7, 0, 55, 10, 7, 0, 56, 10, 7, 0,113, 4, 7, 0, 57, 10, + 7, 0,132, 3, 7, 0,122, 3, 7, 0, 58, 10, 7, 0, 83, 2, 7, 0, 59, 10, 7, 0, 60, 10, 7, 0, 61, 10, 7, 0, 62, 10, + 7, 0, 63, 10, 7, 0, 64, 10, 7, 0, 20, 4, 7, 0, 65, 10, 7, 0, 66, 10, 7, 0, 67, 10, 7, 0, 21, 4, 7, 0, 17, 4, + 7, 0, 18, 4, 7, 0, 68, 10, 4, 0, 69, 10, 4, 0, 90, 0, 4, 0, 70, 10, 4, 0, 71, 10, 2, 0, 72, 10, 2, 0, 73, 10, + 2, 0, 74, 10, 2, 0, 75, 10, 2, 0, 76, 10, 2, 0, 37, 0,168, 0, 50, 4,137, 0, 8, 0,145, 1, 77, 10, 7, 0, 78, 10, + 7, 0, 79, 10, 7, 0,241, 1, 7, 0, 80, 10, 4, 0, 90, 0, 2, 0, 81, 10, 2, 0, 82, 10,146, 1, 4, 0, 7, 0, 5, 0, + 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 83, 10,147, 1, 6, 0,147, 1, 0, 0,147, 1, 1, 0,146, 1,189, 8, 4, 0,253, 0, + 2, 0, 84, 10, 2, 0, 19, 0,148, 1, 5, 0,148, 1, 0, 0,148, 1, 1, 0, 12, 0, 85, 10, 4, 0, 86, 10, 4, 0, 19, 0, +149, 1, 9, 0,149, 1, 0, 0,149, 1, 1, 0, 12, 0,124, 0,148, 1, 87, 10, 4, 0, 19, 0, 2, 0, 84, 10, 2, 0, 88, 10, + 7, 0, 91, 0, 0, 0, 89, 10,161, 0, 6, 0, 27, 0, 31, 0, 12, 0,242, 4, 4, 0, 19, 0, 2, 0, 90, 10, 2, 0, 91, 10, + 9, 0, 92, 10,150, 1, 7, 0,150, 1, 0, 0,150, 1, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 23, 0, 0, 0, 93, 10, + 0, 0, 94, 10,151, 1, 5, 0, 12, 0, 95, 10, 4, 0, 96, 10, 4, 0, 97, 10, 4, 0, 19, 0, 4, 0, 37, 0,152, 1, 13, 0, + 27, 0, 31, 0,153, 1, 98, 10,153, 1, 99, 10, 12, 0,100, 10, 4, 0,101, 10, 2, 0,102, 10, 2, 0, 37, 0, 12, 0,103, 10, + 12, 0,104, 10,151, 1,105, 10, 12, 0,106, 10, 12, 0,107, 10, 12, 0,108, 10,153, 1, 31, 0,153, 1, 0, 0,153, 1, 1, 0, + 9, 0,109, 10, 4, 0,119, 7, 4, 0, 37, 0,214, 0, 34, 6,214, 0,110, 10, 0, 0,111, 10, 2, 0,112, 10, 2, 0,113, 10, + 2, 0,140, 7, 2, 0,141, 7, 2, 0,114, 10, 2, 0,115, 10, 2, 0,171, 3, 2, 0,149, 6, 2, 0,116, 10, 2, 0,117, 10, + 4, 0,237, 1,154, 1,118, 10,155, 1,119, 10,156, 1,120, 10, 4, 0,121, 10, 4, 0,122, 10, 9, 0,123, 10, 12, 0,124, 10, + 12, 0,104, 10, 12, 0,158, 7, 12, 0,125, 10, 12, 0,126, 10, 12, 0,127, 10,157, 1, 16, 0,157, 1, 0, 0,157, 1, 1, 0, + 0, 0,128, 10,158, 1,129, 10, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0,130, 10, 2, 0,131, 10, 2, 0,132, 10, 2, 0,133, 10, + 2, 0,134, 10, 2, 0,135, 10, 2, 0,136, 10, 2, 0,137, 10, 2, 0, 70, 0, 2, 0,237, 1,159, 1, 10, 0,159, 1, 0, 0, +159, 1, 1, 0, 12, 0,138, 10, 0, 0,139, 10, 2, 0,140, 10, 2, 0,141, 10, 2, 0,142, 10, 2, 0, 37, 0, 9, 0,143, 10, + 4, 0,144, 10,222, 0, 12, 0,222, 0, 0, 0,222, 0, 1, 0, 0, 0,128, 10, 26, 0, 30, 0,160, 1,134, 7, 9, 0,145, 10, +158, 1,129, 10,151, 1,146, 10, 12, 0,147, 10,222, 0,148, 10, 2, 0, 19, 0, 2, 0,135, 1,154, 1, 23, 0,154, 1, 0, 0, +154, 1, 1, 0, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 5, 0, 2, 0, 6, 0, 2, 0,149, 10, 2, 0,150, 10, 2, 0,151, 10, + 2, 0,152, 10, 0, 0,153, 10, 0, 0, 37, 0, 2, 0,130, 10, 2, 0,131, 10, 2, 0,132, 10, 2, 0,133, 10, 2, 0,134, 10, + 2, 0, 43, 0, 0, 0,154, 10, 2, 0,155, 10, 2, 0,156, 10, 4, 0, 70, 0, 9, 0,145, 10,161, 1, 8, 0,161, 1, 0, 0, +161, 1, 1, 0, 9, 0, 2, 0, 9, 0,157, 10, 0, 0,227, 3, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0,158, 10,162, 1, 5, 0, + 7, 0,159, 10, 4, 0,160, 10, 4, 0,161, 10, 4, 0, 70, 1, 4, 0, 19, 0,163, 1, 6, 0, 7, 0,162, 10, 7, 0,163, 10, + 7, 0,164, 10, 7, 0,165, 10, 4, 0, 17, 0, 4, 0, 19, 0,164, 1, 5, 0, 7, 0,111, 8, 7, 0,112, 8, 7, 0,217, 2, + 2, 0, 38, 2, 2, 0, 39, 2,165, 1, 5, 0,164, 1, 2, 0, 4, 0, 54, 0, 7, 0,166, 10, 7, 0,111, 8, 7, 0,112, 8, +166, 1, 4, 0, 2, 0,167, 10, 2, 0,168, 10, 2, 0,169, 10, 2, 0,170, 10,167, 1, 2, 0, 42, 0,120, 6, 26, 0,192, 8, +168, 1, 3, 0, 24, 0,171, 10, 4, 0, 19, 0, 4, 0, 37, 0,169, 1, 6, 0, 7, 0,106, 0, 7, 0,219, 2, 7, 0,172, 10, + 7, 0, 37, 0, 2, 0,246, 0, 2, 0,173, 10,170, 1, 7, 0,170, 1, 0, 0,170, 1, 1, 0, 27, 0,123, 6, 0, 0,174, 10, + 4, 0,175, 10, 4, 0, 90, 0, 0, 0,227, 3,171, 1, 6, 0, 12, 0, 2, 9, 0, 0,176, 10, 7, 0, 61, 0, 7, 0,158, 10, + 4, 0, 17, 0, 4, 0, 19, 0,172, 1, 3, 0, 7, 0,177, 10, 4, 0, 19, 0, 4, 0, 37, 0,173, 1, 15, 0,173, 1, 0, 0, +173, 1, 1, 0, 77, 1,244, 8,171, 1, 62, 0, 12, 0, 94, 3, 35, 0, 50, 0,172, 1,178, 10, 4, 0, 54, 0, 7, 0, 61, 0, + 2, 0, 19, 0, 2, 0, 16, 1, 4, 0,175, 10, 0, 0,174, 10, 4, 0,179, 10, 7, 0,180, 10,174, 1, 2, 0, 0, 0,181, 10, + 0, 0,182, 10,175, 1, 4, 0,175, 1, 0, 0,175, 1, 1, 0,159, 0, 48, 3, 12, 0,183, 10,176, 1, 24, 0,176, 1, 0, 0, +176, 1, 1, 0, 12, 0,184, 10,159, 0, 85, 8,175, 1,185, 10, 12, 0,186, 10, 12, 0, 94, 3, 0, 0,227, 3, 7, 0,158, 10, + 7, 0,187, 10, 7, 0, 88, 0, 7, 0, 89, 0, 7, 0, 47, 9, 7, 0, 48, 9, 7, 0,234, 2, 7, 0, 51, 9, 7, 0, 87, 8, + 7, 0, 52, 9, 2, 0,188, 10, 2, 0,189, 10, 2, 0, 43, 0, 2, 0, 17, 0, 4, 0, 19, 0, 4, 0, 70, 0,177, 1, 6, 0, +177, 1, 0, 0,177, 1, 1, 0, 12, 0,184, 10, 4, 0, 19, 0, 4, 0,154, 2, 0, 0,227, 3,178, 1, 10, 0,178, 1, 0, 0, +178, 1, 1, 0, 27, 0,123, 6, 0, 0,190, 10, 4, 0,191, 10, 4, 0,192, 10, 0, 0,174, 10, 4, 0,175, 10, 2, 0, 19, 0, + 2, 0,193, 10,179, 1, 7, 0,179, 1, 0, 0,179, 1, 1, 0, 12, 0,194, 10, 0, 0,227, 3, 2, 0, 19, 0, 2, 0,195, 10, + 4, 0,196, 10,180, 1, 5, 0,180, 1, 0, 0,180, 1, 1, 0, 0, 0,174, 10, 4, 0,175, 10, 7, 0,207, 2, 39, 0, 12, 0, +159, 0, 88, 3,159, 0,197, 10,175, 1,185, 10, 12, 0,198, 10,176, 1,199, 10, 12, 0,200, 10, 12, 0,201, 10, 4, 0, 19, 0, + 4, 0,247, 0, 2, 0,202, 10, 2, 0,203, 10, 7, 0,204, 10,181, 1, 2, 0, 27, 0, 31, 0, 39, 0, 75, 0,182, 1, 5, 0, +182, 1, 0, 0,182, 1, 1, 0, 4, 0, 17, 0, 4, 0, 19, 0, 0, 0, 20, 0,183, 1, 6, 0,182, 1,205, 10, 32, 0, 45, 0, + 4, 0,206, 10, 7, 0,207, 10, 4, 0,208, 10, 4, 0,233, 8,184, 1, 3, 0,182, 1,205, 10, 4, 0,206, 10, 7, 0,209, 10, +185, 1, 8, 0,182, 1,205, 10, 32, 0, 45, 0, 7, 0, 65, 1, 7, 0,210, 10, 7, 0, 15, 3, 7, 0,154, 8, 4, 0,206, 10, + 4, 0,211, 10,186, 1, 5, 0,182, 1,205, 10, 7, 0,212, 10, 7, 0,227, 7, 7, 0,240, 2, 7, 0, 57, 0,187, 1, 3, 0, +182, 1,205, 10, 7, 0,154, 8, 7, 0,213, 10,136, 1, 4, 0, 7, 0,214, 10, 7, 0,252, 9, 2, 0,215, 10, 2, 0, 70, 1, +188, 1, 14, 0,188, 1, 0, 0,188, 1, 1, 0, 12, 0,216, 10, 12, 0,217, 10, 12, 0,218, 10, 0, 0, 20, 0, 4, 0, 31, 0, + 4, 0, 19, 0, 4, 0,219, 10, 7, 0,220, 10, 4, 0,208, 10, 4, 0,233, 8, 7, 0,236, 3, 7, 0,242, 2,141, 1, 23, 0, + 4, 0,206, 10, 4, 0,221, 10, 7, 0,222, 10, 7, 0, 57, 0, 7, 0,223, 10, 7, 0,238, 2, 7, 0,214, 10, 7, 0,224, 10, + 7, 0,219, 2, 7, 0,225, 10, 7, 0,110, 4, 7, 0,226, 10, 7, 0,227, 10, 7, 0,228, 10, 7, 0,229, 10, 7, 0,230, 10, + 7, 0,231, 10, 7, 0,232, 10, 7, 0,233, 10, 7, 0,234, 10, 7, 0,235, 10, 7, 0,236, 10, 12, 0,237, 10,122, 0, 33, 0, +121, 0,238, 10,189, 1,239, 10, 68, 0,240, 10, 68, 0, 24, 10, 68, 0,241, 10,190, 1,242, 10, 48, 0,165, 0, 48, 0,243, 10, + 48, 0,244, 10, 7, 0,245, 10, 7, 0,246, 10, 7, 0,247, 10, 7, 0,248, 10, 7, 0,249, 10, 7, 0,245, 8, 7, 0,250, 10, + 7, 0,169, 1, 7, 0,251, 10, 4, 0,252, 10, 4, 0,253, 10, 4, 0,254, 10, 4, 0, 90, 0, 4, 0, 37, 0, 4, 0,255, 10, + 2, 0, 0, 11, 2, 0, 1, 11, 4, 0, 2, 11, 7, 0,219, 2, 4, 0, 3, 11, 7, 0, 4, 11, 4, 0, 5, 11,138, 0, 6, 11, + 12, 0, 7, 11,123, 0, 11, 0,121, 0,238, 10, 59, 0,255, 0, 7, 0,136, 1, 7, 0,245, 8, 7, 0, 8, 11, 7, 0, 9, 11, + 2, 0, 10, 11, 2, 0, 11, 11, 2, 0, 12, 11, 2, 0, 17, 0, 4, 0, 37, 0,124, 0, 13, 0,121, 0,238, 10,140, 0, 12, 3, +142, 0, 14, 3, 7, 0,189, 8, 7, 0, 13, 11, 7, 0, 14, 11, 7, 0, 67, 1, 7, 0, 15, 11, 4, 0, 16, 11, 4, 0, 10, 3, 2, 0, 17, 0, 2, 0, 37, 0, 4, 0, 70, 0, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -- cgit v1.2.3 From 89df4a46fcbbe11ca478418af59161c87ddbb9f1 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Sun, 4 Oct 2009 20:11:55 +0000 Subject: * Unzip python bundle at the end of the build process. Patch by b333rt, thanks! * remove /ARCH setting - is used only when building x86 --- config/win64-vc-config.py | 2 +- tools/Blender.py | 67 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index 5bb01ff16b5..5f088489b34 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -164,7 +164,7 @@ CXX = 'cl.exe' CFLAGS = [] CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267'] CXXFLAGS = ['/EHsc'] -BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE2'] +BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast'] BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr'] diff --git a/tools/Blender.py b/tools/Blender.py index 1b0573cfda4..04f2676deb3 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -327,6 +327,59 @@ def set_quiet_output(env): env['BUILDERS']['Library'] = static_lib env['BUILDERS']['Program'] = program + +def unzip_pybundle(from_zip,to_dir,exclude_re): + import zipfile + + zip= zipfile.ZipFile(from_zip, mode='r') + exclude_re= list(exclude_re) #single re object or list of re objects + debug= 0 #list files instead of unpacking + good= [] + if debug: print '\nFiles not being unpacked:\n' + for name in zip.namelist(): + is_bad= 0 + for r in exclude_re: + if r.match(name): + is_bad=1 + if debug: print name + break + if not is_bad: + good.append(name) + if debug: + print '\nFiles being unpacked:\n' + for g in good: + print g + else: + zip.extractall(to_dir, good) + +def my_winpybundle_print(target, source, env): + pass + +def WinPyBundle(target=None, source=None, env=None): + import shutil, re + py_zip= env.subst( env['LCGDIR'] ) + if py_zip[0]=='#': + py_zip= py_zip[1:] + py_zip+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '.zip' + + py_target = env.subst( env['BF_INSTALLDIR'] ) + if py_target[0]=='#': + py_target=py_target[1:] + py_target+= '/.blender/python/lib/' + def printexception(func,path,ex): + if os.path.exists(path): #do not report if path does not exist. eg on a fresh build. + print str(func) + ' failed on ' + str(path) + print "Trying to remove existing py bundle." + shutil.rmtree(py_target, False, printexception) + exclude_re=[re.compile('.*/test/.*'), + re.compile('^config/.*'), + re.compile('^distutils/.*'), + re.compile('^idlelib/.*'), + re.compile('^lib2to3/.*'), + re.compile('^tkinter/.*')] + print "Unpacking '" + py_zip + "' to '" + py_target + "'" + unzip_pybundle(py_zip,py_target,exclude_re) + def my_appit_print(target, source, env): a = '%s' % (target[0]) d, f = os.path.split(a) @@ -392,10 +445,10 @@ def AppIt(target=None, source=None, env=None): # extract copy system python, be sure to update other build systems # when making changes to the files that are copied. -def my_pyinst_print(target, source, env): +def my_unixpybundle_print(target, source, env): pass -def PyInstall(target=None, source=None, env=None): +def UnixPyBundle(target=None, source=None, env=None): # Any Unix except osx #-- .blender/python/lib/python3.1 @@ -522,6 +575,9 @@ class BlenderEnvironment(SConsEnvironment): lenv.Append(CCFLAGS = lenv['CC_WARN']) lenv.Append(CXXFLAGS = lenv['CXX_WARN']) + if lenv['OURPLATFORM'] == 'win64-vc': + lenv.Append(LINKFLAGS = ['/MACHINE:X64']) + if lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'): if lenv['BF_DEBUG']: lenv.Append(CCFLAGS = ['/MTd']) @@ -602,8 +658,11 @@ class BlenderEnvironment(SConsEnvironment): elif os.sep == '/': # any unix if lenv['WITH_BF_PYTHON']: if not lenv['WITHOUT_BF_INSTALL'] and not lenv['WITHOUT_BF_PYTHON_INSTALL']: - lenv.AddPostAction(prog,Action(PyInstall,strfunction=my_pyinst_print)) - + lenv.AddPostAction(prog,Action(UnixPyBundle,strfunction=my_unixpybundle_print)) + elif lenv['OURPLATFORM'].startswith('win'): # windows + if lenv['WITH_BF_PYTHON']: + if not lenv['WITHOUT_BF_PYTHON_INSTALL']: + lenv.AddPostAction(prog,Action(WinPyBundle,strfunction=my_winpybundle_print)) return prog def Glob(lenv, pattern): -- cgit v1.2.3 From af522abf33bd3b8caf61f596d1e0a35285e45f9a Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Mon, 5 Oct 2009 02:59:47 +0000 Subject: * changes/additions to volume lighting Volumes can now receive shadows from external objects, either raytraced shadows or shadow maps. To use external shadows, enable 'external shadows' in volume material 'lighting' panel. This an extra toggle since it causes a performance hit, but this can probably be revisited/optimised when the new raytrace accelerator is integrated. For shadow maps at least, it's still very quick. Renamed 'scattering mode' to 'lighting mode' (a bit simpler to understand), and the options inside. Now there's: - Shadeless takes light contribution, but without shadowing or self-shading (fast) good for fog-like volumes, such as mist, or underwater effects - Shadowed (new) takes light contribution with shadows, but no self-shading. (medium) good for mist etc. with directional light sources eg. http://vimeo.com/6901636 - Shaded takes light contribution with internal/external shadows, and self shading (slower) good for thicker/textured volumes like smoke - Multiple scattering etc (still doesn't work properly, on the todo). --- release/scripts/ui/buttons_material.py | 7 ++- source/blender/blenkernel/intern/material.c | 2 +- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/makesdna/DNA_material_types.h | 12 ++-- source/blender/makesrna/intern/rna_material.c | 20 ++++--- .../blender/render/intern/source/convertblender.c | 5 +- .../blender/render/intern/source/volume_precache.c | 8 +-- source/blender/render/intern/source/volumetric.c | 67 +++++++++++++++++++++- 8 files changed, 99 insertions(+), 24 deletions(-) diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index ee7193da301..2415d636dab 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -665,16 +665,17 @@ class MATERIAL_PT_volume_lighting(VolumeButtonsPanel): split = layout.split() col = split.column() - col.itemR(vol, "scattering_mode", text="") + col.itemR(vol, "lighting_mode", text="") col = split.column() - if vol.scattering_mode == 'SINGLE_SCATTERING': + if vol.lighting_mode == 'SHADED': + col.itemR(vol, "external_shadows") col.itemR(vol, "light_cache") sub = col.column() sub.active = vol.light_cache sub.itemR(vol, "cache_resolution") - elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'): + elif vol.lighting_mode in ('MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'): sub = col.column() sub.enabled = True sub.active = False diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index cbd306f6d87..7e742dc5631 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -181,7 +181,7 @@ void init_material(Material *ma) ma->vol.depth_cutoff = 0.01f; ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED; ma->vol.stepsize = 0.2f; - ma->vol.shade_type = MA_VOL_SHADE_SINGLE; + ma->vol.shade_type = MA_VOL_SHADE_SHADED; ma->vol.shadeflag |= MA_VOL_PRECACHESHADING; ma->vol.precache_resolution = 50; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9367e2f4247..a3a56e9a075 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9680,7 +9680,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ma->vol.depth_cutoff = 0.01f; ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED; ma->vol.stepsize = 0.2f; - ma->vol.shade_type = MA_VOL_SHADE_SINGLE; + ma->vol.shade_type = MA_VOL_SHADE_SHADED; ma->vol.shadeflag |= MA_VOL_PRECACHESHADING; ma->vol.precache_resolution = 50; } diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index a925b60ac33..36de890e6dc 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -374,15 +374,15 @@ typedef struct Material { #define MA_VOL_STEP_ADAPTIVE 2 /* vol_shadeflag */ -#define MA_VOL_SHADED 1 -#define MA_VOL_RECVSHADOW 4 +#define MA_VOL_RECV_EXT_SHADOW 1 #define MA_VOL_PRECACHESHADING 8 /* vol_shading_type */ -#define MA_VOL_SHADE_NONE 0 -#define MA_VOL_SHADE_SINGLE 1 -#define MA_VOL_SHADE_MULTIPLE 2 -#define MA_VOL_SHADE_SINGLEPLUSMULTIPLE 3 +#define MA_VOL_SHADE_SHADELESS 0 +#define MA_VOL_SHADE_SHADOWED 2 +#define MA_VOL_SHADE_SHADED 1 +#define MA_VOL_SHADE_MULTIPLE 3 +#define MA_VOL_SHADE_SHADEDPLUSMULTIPLE 4 #endif diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 661b1c5e1c3..b05a7e59cc3 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -953,11 +953,12 @@ static void rna_def_material_volume(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_scattering_items[] = { - {MA_VOL_SHADE_NONE, "NONE", 0, "None", ""}, - {MA_VOL_SHADE_SINGLE, "SINGLE_SCATTERING", 0, "Single Scattering", ""}, + static EnumPropertyItem prop_lighting_items[] = { + {MA_VOL_SHADE_SHADELESS, "SHADELESS", 0, "Shadeless", ""}, + {MA_VOL_SHADE_SHADOWED, "SHADOWED", 0, "Shadowed", ""}, + {MA_VOL_SHADE_SHADED, "SHADED", 0, "Shaded", ""}, {MA_VOL_SHADE_MULTIPLE, "MULTIPLE_SCATTERING", 0, "Multiple Scattering", ""}, - {MA_VOL_SHADE_SINGLEPLUSMULTIPLE, "SINGLE_PLUS_MULTIPLE_SCATTERING", 0, "Single + Multiple Scattering", ""}, + {MA_VOL_SHADE_SHADEDPLUSMULTIPLE, "SHADED_PLUS_MULTIPLE_SCATTERING", 0, "Shaded + Multiple Scattering", ""}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem prop_stepsize_items[] = { @@ -984,10 +985,15 @@ static void rna_def_material_volume(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Step Size", "Distance between subsequent volume depth samples."); RNA_def_property_update(prop, 0, "rna_Material_update"); - prop= RNA_def_property(srna, "scattering_mode", PROP_ENUM, PROP_NONE); + prop= RNA_def_property(srna, "lighting_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "shade_type"); - RNA_def_property_enum_items(prop, prop_scattering_items); - RNA_def_property_ui_text(prop, "Scattering Mode", "Method of shading, attenuating, and scattering light through the volume"); + RNA_def_property_enum_items(prop, prop_lighting_items); + RNA_def_property_ui_text(prop, "Lighting Mode", "Method of shading, attenuating, and scattering light through the volume"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + + prop= RNA_def_property(srna, "external_shadows", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "shadeflag", MA_VOL_RECV_EXT_SHADOW); /* use bitflags */ + RNA_def_property_ui_text(prop, "External Shadows", "Receive shadows from sources outside the volume (temporary)"); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "light_cache", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index b3784f26048..655c453eee7 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -942,7 +942,10 @@ static Material *give_render_material(Render *re, Object *ob, int nr) if(re->r.mode & R_SPEED) ma->texco |= NEED_UV; - if(ma->material_type == MA_TYPE_VOLUME) ma->mode |= MA_TRANSP; + if(ma->material_type == MA_TYPE_VOLUME) { + ma->mode |= MA_TRANSP; + ma->mode &= ~MA_SHADBUF; + } if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) re->flag |= R_ZTRA; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 7ecaf83ae27..2d5d38a394f 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -401,7 +401,7 @@ void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma) fac *= (energy_ss / energy_ms); /* blend multiple scattering back in the light cache */ - if (shade_type == MA_VOL_SHADE_SINGLEPLUSMULTIPLE) { + if (shade_type == MA_VOL_SHADE_SHADEDPLUSMULTIPLE) { /* conserve energy - half single, half multiple */ origf = 0.5f; fac *= 0.5f; @@ -713,7 +713,7 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat lightcache_filter(obi->volume_precache); - if (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SINGLEPLUSMULTIPLE)) + if (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)) { multiple_scattering_diffusion(re, vp, ma); } @@ -721,8 +721,8 @@ void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Mat static int using_lightcache(Material *ma) { - return (((ma->vol.shadeflag & MA_VOL_PRECACHESHADING) && (ma->vol.shade_type == MA_VOL_SHADE_SINGLE)) - || (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SINGLEPLUSMULTIPLE))); + return (((ma->vol.shadeflag & MA_VOL_PRECACHESHADING) && (ma->vol.shade_type == MA_VOL_SHADE_SHADED)) + || (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE))); } /* loop through all objects (and their associated materials) diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 381a32de027..cbb74ab752f 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -51,6 +51,7 @@ #include "render_types.h" #include "pixelshading.h" #include "shading.h" +#include "shadbuf.h" #include "texture.h" #include "volumetric.h" #include "volume_precache.h" @@ -73,6 +74,61 @@ inline float luminance(float* col) /* tracing */ +static int vlr_check_intersect_solid(Isect *is, int ob, RayFace *face) +{ + VlakRen *vlr = (VlakRen*)face; + + /* solid material types only */ + if (vlr->mat->material_type == MA_TYPE_SURFACE) + return 1; + else + return 0; +} + +static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co) +{ + float visibility = 1.f; + + if(lar->shb) { + float dot=1.f; + float dxco[3]={0.f, 0.f, 0.f}, dyco[3]={0.f, 0.f, 0.f}; + + visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0); + } else if (lar->mode & LA_SHAD_RAY) { + /* trace shadow manually, no good lamp api atm */ + Isect is; + const float maxsize = RE_ray_tree_max_size(R.raytree); + + + VecCopyf(is.start, co); + if(lar->type==LA_SUN || lar->type==LA_HEMI) { + is.end[0] = co[0] - lar->vec[0] * maxsize; + is.end[1] = co[1] - lar->vec[1] * maxsize; + is.end[2] = co[2] - lar->vec[2] * maxsize; + } else { + VecCopyf(is.end, lar->co); + } + + is.mode= RE_RAY_MIRROR; + if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) + is.lay= lar->lay; + else + is.lay= -1; + is.face_last= (RayFace*)lar->vlr_last[shi->thread]; + is.ob_last= RAY_OBJECT_SET(&R, lar->obi_last[shi->thread]); + is.faceorig= NULL; + is.oborig= RAY_OBJECT_SET(&R, shi->obi); + + if(RE_ray_tree_intersect_check(R.raytree, &is, vlr_check_intersect_solid)) { + visibility = 0.f; + } + + lar->vlr_last[shi->thread]= (VlakRen*)is.face_last; + lar->obi_last[shi->thread]= RAY_OBJECT_GET(&R, is.ob_last); + } + return visibility; +} + static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type) { float maxsize = RE_ray_tree_max_size(R.raytree); @@ -448,9 +504,18 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float * VECCOPY(lv, lar->vec); VecMulf(lv, -1.0f); - if (shi->mat->vol.shade_type != MA_VOL_SHADE_NONE) { + if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) { + VecMulf(lacol, vol_get_shadow(shi, lar, co)); + } + else if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADED) + { Isect is; + if (shi->mat->vol.shadeflag & MA_VOL_RECV_EXT_SHADOW) { + VecMulf(lacol, vol_get_shadow(shi, lar, co)); + if (luminance(lacol) < 0.001f) return; + } + /* find minimum of volume bounds, or lamp coord */ if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) { float dist = VecLenf(co, hitco); -- cgit v1.2.3 From 0f07bea06bcaaa9db9568c9b28bd00da18e5f56f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Oct 2009 07:08:59 +0000 Subject: remove unused defines, cant check every case but from grepping the souece it should go ok. --- extern/bullet2/CMakeLists.txt | 6 ++---- extern/bullet2/src/SConscript | 4 ++-- source/blender/nodes/CMakeLists.txt | 14 -------------- source/blender/nodes/SConscript | 11 ----------- source/blender/python/CMakeLists.txt | 2 -- source/blender/render/CMakeLists.txt | 4 ---- source/blender/render/SConscript | 3 --- 7 files changed, 4 insertions(+), 40 deletions(-) diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt index 2e2d8920781..3054ed98908 100644 --- a/extern/bullet2/CMakeLists.txt +++ b/extern/bullet2/CMakeLists.txt @@ -32,14 +32,12 @@ FILE(GLOB SRC src/BulletCollision/CollisionShapes/*.cpp src/BulletCollision/NarrowPhaseCollision/*.cpp src/BulletCollision/Gimpact/*.cpp - src/BulletCollision//CollisionDispatch/*.cpp + src/BulletCollision/CollisionDispatch/*.cpp src/BulletDynamics/ConstraintSolver/*.cpp src/BulletDynamics/Vehicle/*.cpp src/BulletDynamics/Dynamics/*.cpp src/BulletSoftBody/*.cpp ) -ADD_DEFINITIONS(-D_LIB) - BLENDERLIB(extern_bullet "${SRC}" "${INC}") -#, libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) + diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript index 3d0c645e7a0..c0ee56045d8 100644 --- a/extern/bullet2/src/SConscript +++ b/extern/bullet2/src/SConscript @@ -4,11 +4,11 @@ import os Import('env') -defs = 'USE_DOUBLES QHULL _LIB' +defs = '' cflags = [] if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): - defs += ' WIN32 NDEBUG _WINDOWS _LIB' + defs += ' WIN32 NDEBUG _WINDOWS' #cflags += ['/MT', '/W3', '/GX', '/O2', '/Op'] cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6', '/O3', '/EHcs'] elif env['OURPLATFORM']=='win32-mingw': diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 58bee7e3acf..ee4b9a81ccd 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -38,20 +38,6 @@ IF(WIN32) SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) -IF(WITH_OPENEXR) - ADD_DEFINITIONS(-DWITH_OPENEXR) -ENDIF(WITH_OPENEXR) - -IF(WITH_QUICKTIME) - SET(INC ${INC} ../quicktime ${QUICKTIME_INC}) - ADD_DEFINITIONS(-DWITH_QUICKTIME) -ENDIF(WITH_QUICKTIME) - -IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) - ADD_DEFINITIONS(-DWITH_FFMPEG) -ENDIF(WITH_FFMPEG) - IF(WITH_PYTHON) SET(INC ${INC} ../python ${PYTHON_INC}) ELSE(WITH_PYTHON) diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 01319dc1eb4..548f4973574 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -27,17 +27,6 @@ if env['WITH_BF_PYTHON']: else: defs.append('DISABLE_PYTHON') -if env['WITH_BF_OPENEXR']: - defs.append('WITH_OPENEXR') - -if env['WITH_BF_FFMPEG']: - defs.append('WITH_FFMPEG') - incs += ' ' + env['BF_FFMPEG_INC'] - -if env['WITH_BF_QUICKTIME']: - defs.append('WITH_QUICKTIME') - incs += ' ' + env['BF_QUICKTIME_INC'] - if env['OURPLATFORM'] == 'linux2': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt index 7abec566505..a83e29e2fab 100644 --- a/source/blender/python/CMakeLists.txt +++ b/source/blender/python/CMakeLists.txt @@ -46,8 +46,6 @@ IF(WITH_FFMPEG) ADD_DEFINITIONS(-DWITH_FFMPEG) ENDIF(WITH_FFMPEG) -ADD_DEFINITIONS(-DWITH_CCGSUBSURF) - BLENDERLIB(bf_python "${SRC}" "${INC}") BLENDERLIB(bf_gen_python "${GENSRC}" "${INC}") diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index b30bc4936a5..29539fa4d17 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -47,10 +47,6 @@ IF(WITH_QUICKTIME) ADD_DEFINITIONS(-DWITH_QUICKTIME) ENDIF(WITH_QUICKTIME) -IF(WITH_FFMPEG) - ADD_DEFINITIONS(-DWITH_FFMPEG) -ENDIF(WITH_FFMPEG) - #TODO #if env['OURPLATFORM']=='linux2': # cflags='-pthread' diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index f6193c29eba..9b2480cc437 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -14,9 +14,6 @@ if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ../quicktime ' + env['BF_QUICKTIME_INC'] -if env['WITH_BF_FFMPEG']: - defs.append('WITH_FFMPEG') - if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') -- cgit v1.2.3 From 3ec79d79e9f07346136fed4ead210c0d127ce00e Mon Sep 17 00:00:00 2001 From: Lukas Steiblys Date: Mon, 5 Oct 2009 09:03:35 +0000 Subject: normals were updated incorrectly in buffers when sculpting. Still not perfect. --- source/blender/editors/sculpt_paint/sculpt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 470a10b5e50..01a2ff3fdee 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1014,9 +1014,9 @@ static void update_damaged_vert(SculptSession *ss, ListBase *lb) CalcNormFloat4(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, ss->mvert[ss->mface[i].v4].co, norm); else CalcNormFloat(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, norm); - VECCOPY(&buffer[cur->element*3],norm); - VECCOPY(&buffer[cur->element*3],norm); - VECCOPY(&buffer[cur->element*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3+1)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3+2)*3],norm); } //VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no); -- cgit v1.2.3 From a3449771476955fd4a27eadd17ff4dce2655cc16 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Mon, 5 Oct 2009 12:55:16 +0000 Subject: Cocoa port : - Window creation at preferred size Implement in Ghost the use of Cocoa functions to get the maximum visible rect (size and position) for the window contents (all screen excluding dock, top menu, and window title bar) Thus Apple specific code in window creation (wm_window.c & wm_apple.c) is no more needed => removed in case of Cocoa build - Alert on exiting despite unsaved changes Add to GHOST method to maintain an all platforms (not apple specific anymore) status on unsaved changes Update GHOST_SystemCocoa to use this for asking or not user to confirm exit without saving changes --- intern/ghost/GHOST_C-api.h | 10 ++ intern/ghost/GHOST_IWindow.h | 13 +++ intern/ghost/GHOST_Types.h | 6 ++ intern/ghost/intern/GHOST_C-api.cpp | 7 ++ intern/ghost/intern/GHOST_SystemCocoa.h | 24 ++--- intern/ghost/intern/GHOST_SystemCocoa.mm | 117 +++++++++++++++++------- intern/ghost/intern/GHOST_Window.cpp | 14 +++ intern/ghost/intern/GHOST_Window.h | 16 ++++ intern/ghost/intern/GHOST_WindowCocoa.h | 7 ++ intern/ghost/intern/GHOST_WindowCocoa.mm | 18 ++-- intern/ghost/intern/GHOST_WindowManager.cpp | 19 +++- intern/ghost/intern/GHOST_WindowManager.h | 10 +- source/blender/windowmanager/CMakeLists.txt | 4 + source/blender/windowmanager/intern/wm_window.c | 17 +++- 14 files changed, 219 insertions(+), 63 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index c0b7077fb53..9460fb504a9 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -598,6 +598,16 @@ extern GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle); extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWindowState state); + +/** + * Sets the window "modified" status, indicating unsaved changes + * @param windowhandle The handle to the window + * @param isUnsavedChanges Unsaved changes or not + * @return Indication of success. + */ +extern GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, + GHOST_TUns8 isUnsavedChanges); + /** * Sets the order of the window (bottom, top). * @param windowhandle The handle to the window diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index d91995e35ec..ff1484909b0 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -161,6 +161,19 @@ public: */ virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0; + /** + * Sets the window "modified" status, indicating unsaved changes + * @param isUnsavedChanges Unsaved changes or not + * @return Indication of success. + */ + virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0; + + /** + * Gets the window "modified" status, indicating unsaved changes + * @return True if there are unsaved changes + */ + virtual bool getModifiedState() = 0; + /** * Sets the order of the window (bottom, top). * @param order The order of the window. diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 31819f341a0..14e3c4bb5f7 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -116,6 +116,12 @@ typedef enum { } GHOST_TWindowState; +/** Constants for the answer to the blender exit request */ +typedef enum { + GHOST_kExitCancel = 0, + GHOST_kExitNow +} GHOST_TExitRequestResponse; + typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 5c23b6c42a3..d14945d1bf8 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -629,6 +629,13 @@ GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, } +GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, GHOST_TUns8 isUnsavedChanges) +{ + GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; + + return window->setModifiedState(isUnsavedChanges); +} + GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, GHOST_TWindowOrder order) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index cd2cf12daa1..3e499f3d136 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -133,6 +133,12 @@ public: */ virtual bool processEvents(bool waitForEvent); + /** + * Handle User request to quit, from Menu bar Quit, and Cmd+Q + * Display alert panel if changes performed since last save + */ + GHOST_TUns8 handleQuitRequest(); + /*************************************************************************************** ** Cursor management functionality ***************************************************************************************/ @@ -193,39 +199,33 @@ protected: */ virtual GHOST_TSuccess init(); - /** - * Closes the system down. - * @return A success value. - */ - virtual GHOST_TSuccess exit(); - - /** * Handles a tablet event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) * @return Indication whether the event was handled. */ - int handleTabletEvent(void *eventPtr); - /** + GHOST_TSuccess handleTabletEvent(void *eventPtr); + + /** * Handles a mouse event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) * @return Indication whether the event was handled. */ - int handleMouseEvent(void *eventPtr); + GHOST_TSuccess handleMouseEvent(void *eventPtr); /** * Handles a key event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) * @return Indication whether the event was handled. */ - int handleKeyEvent(void *eventPtr); + GHOST_TSuccess handleKeyEvent(void *eventPtr); /** * Handles a window event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) * @return Indication whether the event was handled. */ - int handleWindowEvent(void *eventPtr); + GHOST_TSuccess handleWindowEvent(void *eventPtr); /** * Handles all basic Mac application stuff for a mouse down event. diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index d0c382e1469..c66153ab670 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -414,6 +414,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { } -(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa; - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; +- (void)applicationWillTerminate:(NSNotification *)aNotification; @end @implementation CocoaAppDelegate : NSObject @@ -424,15 +425,21 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { + //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled //Note that Cmd+Q is already handled by keyhandler - //FIXME: Need an event "QuitRequest" - int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes may not have been saved. Do you really want to quit ?", - @"No", @"Yes", nil); - - if (shouldQuit == NSAlertAlternateReturn) - systemCocoa->pushEvent( new GHOST_Event(systemCocoa->getMilliSeconds(), GHOST_kEventQuit, NULL) ); - - return NSTerminateCancel; + if (systemCocoa->handleQuitRequest() == GHOST_kExitNow) + return NSTerminateCancel;//NSTerminateNow; + else + return NSTerminateCancel; +} + +// To avoid cancelling a log off process, we must use Cocoa termination process +// And this function is the only chance to perform clean up +// So WM_exit needs to be called directly, as the event loop will never run before termination +- (void)applicationWillTerminate:(NSNotification *)aNotification +{ + /*G.afbreek = 0; //Let Cocoa perform the termination at the end + WM_exit(C);*/ } @end @@ -440,7 +447,6 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { #pragma mark initialization/finalization -/***/ GHOST_SystemCocoa::GHOST_SystemCocoa() { @@ -468,6 +474,8 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() GHOST_SystemCocoa::~GHOST_SystemCocoa() { + NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool; + [pool drain]; } @@ -478,7 +486,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init() if (success) { //ProcessSerialNumber psn; - //FIXME: Carbon stuff to move window & menu to foreground + //Carbon stuff to move window & menu to foreground /*if (!GetCurrentProcess(&psn)) { TransformProcessType(&psn, kProcessTransformToForegroundApplication); SetFrontProcess(&psn); @@ -566,13 +574,6 @@ GHOST_TSuccess GHOST_SystemCocoa::init() } -GHOST_TSuccess GHOST_SystemCocoa::exit() -{ - NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool; - [pool drain]; - return GHOST_System::exit(); -} - #pragma mark window management GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const @@ -602,11 +603,15 @@ GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { - //TODO: Provide visible frame or total frame, check for consistency with rest of code + //Get visible frame, that is frame excluding dock and top menu bar NSRect frame = [[NSScreen mainScreen] visibleFrame]; - width = frame.size.width; - height = frame.size.height; + //Returns max window contents (excluding title bar...) + NSRect contentRect = [NSWindow contentRectForFrameRect:frame + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + + width = contentRect.size.width; + height = contentRect.size.height; } @@ -623,7 +628,16 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( ) { GHOST_IWindow* window = 0; - + + //Get the available rect for including window contents + NSRect frame = [[NSScreen mainScreen] visibleFrame]; + NSRect contentRect = [NSWindow contentRectForFrameRect:frame + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + + //Ensures window top left is inside this available rect + left = left > contentRect.origin.x ? left : contentRect.origin.x; + top = top > contentRect.origin.y ? top : contentRect.origin.y; + window = new GHOST_WindowCocoa (title, left, top, width, height, state, type); if (window) { @@ -847,7 +861,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) } //TODO: To be called from NSWindow delegate -int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) +GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) { /*WindowRef windowRef; GHOST_WindowCocoa *window; @@ -900,7 +914,29 @@ int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) return GHOST_kSuccess; } -int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) +GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() +{ + //Check open windows if some changes are not saved + if (m_windowManager->getAnyModifiedState()) + { + int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?", + @"Cancel", @"Quit anyway", nil); + if (shouldQuit == NSAlertAlternateReturn) + { + pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) ); + return GHOST_kExitNow; + } + } + else { + pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) ); + return GHOST_kExitNow; + } + + return GHOST_kExitCancel; +} + + +GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); @@ -964,7 +1000,7 @@ int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) } -int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) +GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); @@ -1018,11 +1054,12 @@ int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } -int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) +GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); NSUInteger modifiers; + NSString *characters; GHOST_TKey keyCode; unsigned char ascii; @@ -1036,9 +1073,16 @@ int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) switch ([event type]) { case NSKeyDown: case NSKeyUp: - keyCode = convertKey([event keyCode], - [[event charactersIgnoringModifiers] characterAtIndex:0]); - ascii= convertRomanToLatin((char)[[event characters] characterAtIndex:0]); + characters = [event characters]; + if ([characters length]) { //Check for dead keys + keyCode = convertKey([event keyCode], + [[event charactersIgnoringModifiers] characterAtIndex:0]); + ascii= convertRomanToLatin((char)[characters characterAtIndex:0]); + } else { + keyCode = convertKey([event keyCode],0); + ascii= 0; + } + if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask)) break; //Cmd-Q is directly handled by Cocoa @@ -1223,9 +1267,12 @@ GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const GHOST_TUns8 * temp_buff; size_t pastedTextSize; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; if (pasteBoard = nil) { + [pool drain]; return NULL; } @@ -1235,7 +1282,10 @@ GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const NSString *bestType = [[NSPasteboard generalPasteboard] availableTypeFromArray:supportedTypes]; - if (bestType == nil) { return NULL; } + if (bestType == nil) { + [pool drain]; + return NULL; + } NSString * textPasted = [pasteBoard stringForType:@"public.utf8-plain-text"]; @@ -1249,6 +1299,8 @@ GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const temp_buff[pastedTextSize] = '\0'; + [pool drain]; + if(temp_buff) { return temp_buff; } else { @@ -1262,10 +1314,12 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const if(selection) {return;} // for copying the selection, used on X11 - + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; if (pasteBoard = nil) { + [pool drain]; return; } @@ -1277,8 +1331,7 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const [pasteBoard setString:textToCopy forType:@"public.utf8-plain-text"]; - printf("\nCopy"); - + [pool drain]; } #pragma mark Carbon stuff to remove diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 951c3bc381d..34e9f519a07 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -52,6 +52,8 @@ GHOST_Window::GHOST_Window( m_cursorShape(GHOST_kStandardCursorDefault), m_stereoVisual(stereoVisual) { + m_isUnsavedChanges = false; + m_fullScreen = state == GHOST_kWindowStateFullScreen; if (m_fullScreen) { m_fullScreenWidth = width; @@ -137,3 +139,15 @@ GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUn } } + +GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges) +{ + m_isUnsavedChanges = isUnsavedChanges; + + return GHOST_kSuccess; +} + +bool GHOST_Window::getModifiedState() +{ + return m_isUnsavedChanges; +} \ No newline at end of file diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 88178bae5b3..a2d1675f6ab 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -173,6 +173,19 @@ public: */ virtual GHOST_TSuccess setCursorGrab(bool grab); + /** + * Sets the window "modified" status, indicating unsaved changes + * @param isUnsavedChanges Unsaved changes or not + * @return Indication of success. + */ + virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges); + + /** + * Gets the window "modified" status, indicating unsaved changes + * @return True if there are unsaved changes + */ + virtual bool getModifiedState(); + /** * Returns the type of drawing context used in this window. * @return The current type of drawing context. @@ -262,6 +275,9 @@ protected: /** The current shape of the cursor */ GHOST_TStandardCursor m_cursorShape; + /** Modified state : are there unsaved changes */ + bool m_isUnsavedChanges; + /** Stores wether this is a full screen window. */ bool m_fullScreen; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 146d0ff47de..f383e3a7a81 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -143,6 +143,13 @@ public: */ virtual GHOST_TWindowState getState() const; + /** + * Sets the window "modified" status, indicating unsaved changes + * @param isUnsavedChanges Unsaved changes or not + * @return Indication of success. + */ + virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges); + /** * Converts a point in screen coordinates to client rectangle coordinates * @param inX The x-coordinate on the screen. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 53d7fa9b245..092443814b0 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -378,12 +378,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) case GHOST_kWindowStateMinimized: ::HideWindow(m_windowRef); break; - case GHOST_kWindowStateModified: - SetWindowModified(m_windowRef, 1); - break; - case GHOST_kWindowStateUnModified: - SetWindowModified(m_windowRef, 0); - break; case GHOST_kWindowStateMaximized: case GHOST_kWindowStateNormal: default: @@ -393,6 +387,18 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) return GHOST_kSuccess; } +GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) +{ + if (isUnsavedChanges) { + SetWindowModified(m_windowRef, 1); + } else { + SetWindowModified(m_windowRef, 0); + } + + return GHOST_Window::setModifiedState(isUnsavedChanges); +} + + GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) { diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp index af96653db13..15ee41e3dce 100644 --- a/intern/ghost/intern/GHOST_WindowManager.cpp +++ b/intern/ghost/intern/GHOST_WindowManager.cpp @@ -187,10 +187,21 @@ void GHOST_WindowManager::setWindowInactive(const GHOST_IWindow* window) } - std::vector & -GHOST_WindowManager:: -getWindows( -){ +std::vector &GHOST_WindowManager::getWindows() +{ return m_windows; } + +bool GHOST_WindowManager::getAnyModifiedState() +{ + bool isAnyModified = false; + std::vector::iterator iter; + + for (iter = m_windows.begin(); iter != m_windows.end(); iter++) { + if ((*iter)->getModifiedState()) + isAnyModified = true; + } + + return isAnyModified; +} \ No newline at end of file diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h index 46e80d2c603..3690ad41e2c 100644 --- a/intern/ghost/intern/GHOST_WindowManager.h +++ b/intern/ghost/intern/GHOST_WindowManager.h @@ -133,11 +133,13 @@ public: * this vector. Please do not destroy or add windows use the * interface above for this, */ + std::vector & getWindows(); - std::vector & - getWindows( - ); - + /** + * Return true if any windows has a modified status + * @return True if any window has unsaved changes + */ + bool getAnyModifiedState(); protected: /** The list of windows managed */ diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index cb2fc92a1b6..7deac8a4aa0 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -70,6 +70,10 @@ IF(WIN32) SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) +IF(WITH_COCOA) + LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/wm_apple.c") +ENDIF(WITH_COCOA) + # TODO buildinfo IF(BF_BUILDINFO) ADD_DEFINITIONS(-DNAN_BUILDINFO) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index c853afe4507..466e5868723 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -71,7 +71,8 @@ static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0; /* ******** win open & close ************ */ -/* XXX this one should correctly check for apple top header... */ +/* XXX this one should correctly check for apple top header... + done for Cocoa : returns window contents (and not frame) max size*/ static void wm_get_screensize(int *width_r, int *height_r) { unsigned int uiwidth; @@ -90,7 +91,7 @@ static void wm_window_check_position(rcti *rect) wm_get_screensize(&width, &height); -#ifdef __APPLE__ +#if defined(__APPLE__) && !defined(GHOST_COCOA) height -= 70; #endif @@ -269,7 +270,12 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) else GHOST_SetTitle(win->ghostwin, "Blender"); -#ifdef __APPLE__ + /* Informs GHOST of unsaved changes, to set window modified visual indicator (MAC OS X) + and to give hint of unsaved changes for a user warning mechanism + in case of OS application terminate request (e.g. OS Shortcut Alt+F4, Cmd+Q, (...), or session end) */ + GHOST_SetWindowModifiedState(win->ghostwin, (GHOST_TUns8)!wm->file_saved); + +#if defined(__APPLE__) && !defined(GHOST_COCOA) if(wm->file_saved) GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateUnModified); else @@ -292,7 +298,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow // inital_state = GHOST_kWindowStateMaximized; inital_state = GHOST_kWindowStateNormal; -#ifdef __APPLE__ +#if defined(__APPLE__) && !defined(GHOST_COCOA) { extern int macPrefState; /* creator.c */ inital_state += macPrefState; @@ -339,7 +345,8 @@ void wm_window_add_ghostwindows(wmWindowManager *wm) if (!prefsizx) { wm_get_screensize(&prefsizx, &prefsizy); -#ifdef __APPLE__ +#if defined(__APPLE__) && !defined(GHOST_COCOA) +//Cocoa provides functions to get correct max window size { extern void wm_set_apple_prefsize(int, int); /* wm_apple.c */ -- cgit v1.2.3 From 3816554cbc1a40dc5199c8e56e45817ec09128d5 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Mon, 5 Oct 2009 13:25:56 +0000 Subject: General particle bug fixes + few small goodies The goodies: * Curves can be used as normal dynamic effectors too with the new "curve" field shape. * Group visualization has optional duplication counts for each object in the specified group. * Object & group visualizations, which are done without taking the dupliobject's global position into account (unless the whole group is used). This is much nicer than the previous behavior, but I added a "Use Global Location" option for those who want to use it the old way. * The active particle system's particles are now drawn a with theme coloured outline instead of pure white. * Added object aligned velocity factors (buttons categorized and re-organized too). Bug fixes: * Absorption didn't work as the ui toggle button was forgotten. * Some other force field ui tweaks. * Crash after adding children and changing trails count. * Display types "cross" and "axis" crashed. * Particles weren't drawn with correct coloring. * Billboards didn't update properly in viewport to camera location changes. * Particle rotation wasn't recreated correctly from point cache. * Changing particles amount crashed sometimes. * Some files with child hair crashed on loading. * Compiler warning fixes. * Adding boids crashed on frame 1; --- release/scripts/ui/buttons_particle.py | 106 +++-- release/scripts/ui/buttons_physics_common.py | 5 +- source/blender/blenkernel/BKE_bvhutils.h | 4 + source/blender/blenkernel/BKE_effect.h | 1 + source/blender/blenkernel/BKE_particle.h | 2 + source/blender/blenkernel/intern/anim.c | 43 +- source/blender/blenkernel/intern/boids.c | 5 +- source/blender/blenkernel/intern/bvhutils.c | 88 ++++ source/blender/blenkernel/intern/effect.c | 21 +- source/blender/blenkernel/intern/modifier.c | 8 +- source/blender/blenkernel/intern/particle.c | 81 +++- source/blender/blenkernel/intern/particle_system.c | 28 +- source/blender/blenkernel/intern/pointcache.c | 24 +- source/blender/blenloader/intern/readfile.c | 7 + source/blender/blenloader/intern/writefile.c | 5 + source/blender/editors/physics/particle_object.c | 76 ++++ source/blender/editors/physics/physics_intern.h | 3 + source/blender/editors/physics/physics_ops.c | 3 + source/blender/editors/space_view3d/drawobject.c | 499 +++++++++++---------- source/blender/makesdna/DNA_object_force.h | 4 +- source/blender/makesdna/DNA_particle_types.h | 16 +- source/blender/makesrna/intern/rna_object_force.c | 35 +- source/blender/makesrna/intern/rna_particle.c | 131 +++++- 23 files changed, 873 insertions(+), 322 deletions(-) diff --git a/release/scripts/ui/buttons_particle.py b/release/scripts/ui/buttons_particle.py index 1a800fc4dfd..81ddab40ec9 100644 --- a/release/scripts/ui/buttons_particle.py +++ b/release/scripts/ui/buttons_particle.py @@ -121,17 +121,19 @@ class PARTICLE_PT_emission(ParticleButtonsPanel): layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches row = layout.row() + row.active = part.distribution != 'GRID' row.itemR(part, "amount") - split = layout.split() - - col = split.column(align=True) - col.itemR(part, "start") - col.itemR(part, "end") + if part.type != 'HAIR': + split = layout.split() + + col = split.column(align=True) + col.itemR(part, "start") + col.itemR(part, "end") - col = split.column(align=True) - col.itemR(part, "lifetime") - col.itemR(part, "random_lifetime", slider=True) + col = split.column(align=True) + col.itemR(part, "lifetime") + col.itemR(part, "random_lifetime", slider=True) layout.row().itemL(text="Emit From:") @@ -221,7 +223,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel): point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0) -class PARTICLE_PT_initial(ParticleButtonsPanel): +class PARTICLE_PT_velocity(ParticleButtonsPanel): __label__ = "Velocity" def poll(self, context): @@ -238,48 +240,66 @@ class PARTICLE_PT_initial(ParticleButtonsPanel): part = psys.settings layout.enabled = particle_panel_enabled(psys) - - layout.row().itemL(text="Direction:") split = layout.split() sub = split.column() + sub.itemL(text="Emitter Geometry:") sub.itemR(part, "normal_factor") + subsub = sub.column(align=True) + subsub.itemR(part, "tangent_factor") + subsub.itemR(part, "tangent_phase", slider=True) + + sub = split.column() + sub.itemL(text="Emitter Object") + sub.itemR(part, "object_aligned_factor", text="") + + layout.row().itemL(text="Other:") + split = layout.split() + sub = split.column() if part.emit_from=='PARTICLE': sub.itemR(part, "particle_factor") else: sub.itemR(part, "object_factor", slider=True) + sub = split.column() sub.itemR(part, "random_factor") - sub.itemR(part, "tangent_factor") - sub.itemR(part, "tangent_phase", slider=True) - sub = split.column() - sub.itemL(text="TODO:") - sub.itemL(text="Object aligned") - sub.itemL(text="direction: X, Y, Z") + #if part.type=='REACTOR': + # sub.itemR(part, "reactor_factor") + # sub.itemR(part, "reaction_shape", slider=True) - if part.type=='REACTOR': - sub.itemR(part, "reactor_factor") - sub.itemR(part, "reaction_shape", slider=True) +class PARTICLE_PT_rotation(ParticleButtonsPanel): + __label__ = "Rotation" + + def poll(self, context): + if particle_panel_poll(context): + psys = context.particle_system + return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external else: - sub.itemL(text="") + return False + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings - layout.row().itemL(text="Rotation:") - split = layout.split() - - sub = split.column() + layout.enabled = particle_panel_enabled(psys) - sub.itemR(part, "rotation_mode", text="Axis") + split = layout.split() + split.itemL(text="Initial Rotation:") + split.itemR(part, "rotation_dynamic") split = layout.split() - sub = split.column() - sub.itemR(part, "rotation_dynamic") - sub.itemR(part, "random_rotation_factor", slider=True) - sub = split.column() + sub = split.column(align=True) + sub.itemR(part, "rotation_mode", text="") + sub.itemR(part, "random_rotation_factor", slider=True, text="Random") + + sub = split.column(align=True) sub.itemR(part, "phase_factor", slider=True) sub.itemR(part, "random_phase_factor", text="Random", slider=True) - layout.row().itemL(text="Angular velocity:") + layout.row().itemL(text="Angular Velocity:") layout.row().itemR(part, "angular_velocity_mode", expand=True) split = layout.split() @@ -607,16 +627,37 @@ class PARTICLE_PT_render(ParticleButtonsPanel): elif part.ren_as == 'OBJECT': sub.itemR(part, "dupli_object") + sub.itemR(part, "use_global_dupli") elif part.ren_as == 'GROUP': sub.itemR(part, "dupli_group") split = layout.split() sub = split.column() sub.itemR(part, "whole_group") + colsub = sub.column() + colsub.active = part.whole_group == False + colsub.itemR(part, "use_group_count") + sub = split.column() colsub = sub.column() colsub.active = part.whole_group == False + colsub.itemR(part, "use_global_dupli") colsub.itemR(part, "rand_group") + if part.use_group_count and not part.whole_group: + row = layout.row() + row.template_list(part, "dupliweights", part, "active_dupliweight_index") + + col = row.column() + subrow = col.row() + subcol = subrow.column(align=True) + subcol.itemO("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="") + subcol.itemO("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="") + + weight = part.active_dupliweight + if weight: + row = layout.row() + row.itemR(weight, "count") + elif part.ren_as == 'BILLBOARD': sub.itemL(text="Align:") @@ -898,7 +939,8 @@ bpy.types.register(PARTICLE_PT_particles) bpy.types.register(PARTICLE_PT_hair_dynamics) bpy.types.register(PARTICLE_PT_cache) bpy.types.register(PARTICLE_PT_emission) -bpy.types.register(PARTICLE_PT_initial) +bpy.types.register(PARTICLE_PT_velocity) +bpy.types.register(PARTICLE_PT_rotation) bpy.types.register(PARTICLE_PT_physics) bpy.types.register(PARTICLE_PT_boidbrain) bpy.types.register(PARTICLE_PT_render) diff --git a/release/scripts/ui/buttons_physics_common.py b/release/scripts/ui/buttons_physics_common.py index b65d092fcfa..17ac1b2bbaa 100644 --- a/release/scripts/ui/buttons_physics_common.py +++ b/release/scripts/ui/buttons_physics_common.py @@ -78,7 +78,7 @@ def effector_weights_ui(self, weights): layout.itemS() flow = layout.column_flow() - flow.itemR(weights, "spherical", slider=True) + flow.itemR(weights, "force", slider=True) flow.itemR(weights, "vortex", slider=True) flow.itemR(weights, "magnetic", slider=True) flow.itemR(weights, "wind", slider=True) @@ -110,7 +110,7 @@ def basic_force_field_settings_ui(self, field): col.itemR(field, "flow") elif field.type == 'HARMONIC': col.itemR(field, "harmonic_damping", text="Damping") - elif field.type == 'VORTEX' and field.shape == 'PLANE': + elif field.type == 'VORTEX' and field.shape != 'POINT': col.itemR(field, "inflow") elif field.type == 'DRAG': col.itemR(field, "quadratic_drag", text="Quadratic") @@ -140,6 +140,7 @@ def basic_force_field_falloff_ui(self, field): col.itemR(field, "z_direction", text="") col.itemR(field, "use_min_distance", text="Use Minimum") col.itemR(field, "use_max_distance", text="Use Maximum") + col.itemR(field, "do_absorption") col = split.column() col.itemR(field, "falloff_power", text="Power") diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index 66c8d99959a..e2911a30b25 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -57,6 +57,7 @@ typedef struct BVHTreeFromMesh /* Vertex array, so that callbacks have instante access to data */ struct MVert *vert; + struct MEdge *edge; /* only used for BVHTreeFromMeshEdges */ struct MFace *face; /* radius for raycast */ @@ -96,6 +97,8 @@ BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMes */ BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); +BVHTree* bvhtree_from_mesh_edges(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); + /* * Frees data allocated by a call to bvhtree_from_mesh_*. */ @@ -109,6 +112,7 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data); //Using local coordinates #define BVHTREE_FROM_FACES 0 #define BVHTREE_FROM_VERTICES 1 +#define BVHTREE_FROM_EDGES 2 typedef LinkNode* BVHCache; diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index 83ec7c13946..9a0a724ab9a 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -138,6 +138,7 @@ int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struc /* EffectedPoint->flag */ #define PE_WIND_AS_SPEED 1 #define PE_DYNAMIC_ROTATION 2 +#define PE_USE_NORMAL_DATA 4 /* EffectorData->flag */ #define PE_VELOCITY_TO_IMPULSE 1 diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index e0259ff10dd..e9285782a1e 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -201,6 +201,8 @@ struct Object *psys_get_lattice(struct ParticleSimulationData *sim); int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys); int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys); +void psys_check_group_weights(struct ParticleSettings *part); + /* free */ void psys_free_settings(struct ParticleSettings *part); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index bd779935d55..5cd901066f8 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -776,6 +776,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p GroupObject *go; Object *ob=0, **oblist=0, obcopy, *obcopylist=0; DupliObject *dob; + ParticleDupliWeight *dw; ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)}; ParticleSettings *part; ParticleData *pa; @@ -783,7 +784,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p ParticleKey state; ParticleCacheKey *cache; float ctime, pa_time, scale = 1.0f; - float tmat[4][4], mat[4][4], pamat[4][4], size=0.0; + float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0; float (*obmat)[4], (*oldobmat)[4]; int lay, a, b, counter, hair = 0; int totpart, totchild, totgroup=0, pa_num; @@ -813,6 +814,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p ((part->ren_as == PART_DRAW_OB && part->dup_ob) || (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) { + psys_check_group_weights(part); + /* if we have a hair particle system, use the path cache */ if(part->type == PART_HAIR) { if(psys->flag & PSYS_HAIR_DONE) @@ -831,18 +834,37 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if(part->ren_as==PART_DRAW_GR) { group_handle_recalc_and_update(scene, par, part->dup_group); - for(go=part->dup_group->gobject.first; go; go=go->next) - totgroup++; + if(part->draw & PART_DRAW_COUNT_GR) { + for(dw=part->dupliweights.first; dw; dw=dw->next) + totgroup += dw->count; + } + else { + for(go=part->dup_group->gobject.first; go; go=go->next) + totgroup++; + } /* we also copy the actual objects to restore afterwards, since * where_is_object_time will change the object which breaks transform */ oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list"); obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list"); - go = part->dup_group->gobject.first; - for(a=0; anext) { - oblist[a] = go->ob; - obcopylist[a] = *go->ob; + + if(part->draw & PART_DRAW_COUNT_GR && totgroup) { + dw = part->dupliweights.first; + + for(a=0; anext) { + for(b=0; bcount; b++, a++) { + oblist[a] = dw->ob; + obcopylist[a] = *dw->ob; + } + } + } + else { + go = part->dup_group->gobject.first; + for(a=0; anext) { + oblist[a] = go->ob; + obcopylist[a] = *go->ob; + } } } else { @@ -936,11 +958,18 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else { /* to give ipos in object correct offset */ where_is_object_time(scene, ob, ctime-pa_time); + + VECCOPY(vec, obmat[3]); + obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f; Mat4CpyMat4(mat, pamat); Mat4MulMat4(tmat, obmat, mat); Mat4MulFloat3((float *)tmat, size*scale); + + if(part->draw & PART_DRAW_GLOBAL_OB) + VECADD(tmat[3], tmat[3], vec); + if(par_space_mat) Mat4MulMat4(mat, tmat, par_space_mat); else diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 76824d3a34a..712fb13cfc0 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -73,13 +73,11 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, { BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*) rule; BoidSettings *boids = bbd->part->boids; - Object *priority_ob = NULL; BoidParticle *bpa = pa->boid; EffectedPoint epoint; ListBase *effectors = bbd->sim->psys->effectors; EffectorCache *cur, *eff = NULL; EffectorData efd, cur_efd; - float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0); float priority = 0.0f, len = 0.0f; int ret = 0; @@ -1051,9 +1049,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) float wanted_dir[3]; float q[4], mat[3][3]; /* rotation */ float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f}; - float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f}; + float force[3] = {0.0f, 0.0f, 0.0f}; float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep; - int p = pa - bbd->sim->psys->particles; set_boid_values(&val, boids, pa); diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index d9e005811d0..f2526231d50 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -479,6 +479,32 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r } while(t2); } +// Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges. +// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. +static void mesh_edges_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest) +{ + const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata; + MVert *vert = data->vert; + MEdge *edge = data->edge + index; + float nearest_tmp[3], dist; + + float *t0, *t1; + t0 = vert[ edge->v1 ].co; + t1 = vert[ edge->v2 ].co; + + PclosestVL3Dfl(nearest_tmp, co, t0, t1); + dist = VecLenf(nearest_tmp, co); + + if(dist < nearest->dist) + { + nearest->index = index; + nearest->dist = dist; + VECCOPY(nearest->co, nearest_tmp); + VecSubf(nearest->no, t0, t1); + Normalize(nearest->no); + } +} + /* * BVH builders */ @@ -605,6 +631,68 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float } +// Builds a bvh tree.. where nodes are the faces of the given mesh. +BVHTree* bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) +{ + BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_EDGES); + + //Not in cache + if(tree == NULL) + { + int i; + int numEdges= mesh->getNumEdges(mesh); + MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); + MEdge *edge = mesh->getEdgeDataArray(mesh, CD_MEDGE); + + if(vert != NULL && edge != NULL) + { + /* Create a bvh-tree of the given target */ + tree = BLI_bvhtree_new(numEdges, epsilon, tree_type, axis); + if(tree != NULL) + { + for(i = 0; i < numEdges; i++) + { + float co[4][3]; + VECCOPY(co[0], vert[ edge[i].v1 ].co); + VECCOPY(co[1], vert[ edge[i].v2 ].co); + + BLI_bvhtree_insert(tree, i, co[0], 2); + } + BLI_bvhtree_balance(tree); + + //Save on cache for later use +// printf("BVHTree built and saved on cache\n"); + bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_EDGES); + } + } + } + else + { +// printf("BVHTree is already build, using cached tree\n"); + } + + + //Setup BVHTreeFromMesh + memset(data, 0, sizeof(*data)); + data->tree = tree; + + if(data->tree) + { + data->cached = TRUE; + + data->nearest_callback = mesh_edges_nearest_point; + data->raycast_callback = NULL; + + data->mesh = mesh; + data->vert = mesh->getVertDataArray(mesh, CD_MVERT); + data->edge = mesh->getEdgeDataArray(mesh, CD_MEDGE); + + data->sphere_radius = epsilon; + } + return data->tree; + +} + // Frees data allocated by a call to bvhtree_from_mesh_*. void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) { diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 7cc65de827a..9b648e2c05c 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -228,6 +228,8 @@ static void precalculate_effector(EffectorCache *eff) } else if(eff->pd->shape == PFIELD_SHAPE_SURFACE) { eff->surmd = (SurfaceModifierData *)modifiers_findByType ( eff->ob, eModifierType_Surface ); + if(eff->ob->type == OB_CURVE) + eff->flag |= PE_USE_NORMAL_DATA; } else if(eff->psys) psys_update_particle_tree(eff->psys, eff->scene->r.cfra); @@ -518,7 +520,7 @@ float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *poi float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f; float fac, r_fac; - fac = Inpf(efd->nor, efd->vec_to_point); + fac = Inpf(efd->nor, efd->vec_to_point2); if(eff->pd->zdir == PFIELD_Z_POS && fac < 0.0f) falloff=0.0f; @@ -691,10 +693,16 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin VecSubf(efd->vec_to_point, point->loc, efd->loc); efd->distance = VecLength(efd->vec_to_point); - /* for some effectors we need the object center every time */ - VecSubf(efd->vec_to_point2, point->loc, eff->ob->obmat[3]); - VECCOPY(efd->nor2, eff->ob->obmat[2]); - Normalize(efd->nor2); + if(eff->flag & PE_USE_NORMAL_DATA) { + VECCOPY(efd->vec_to_point2, efd->vec_to_point); + VECCOPY(efd->nor2, efd->nor); + } + else { + /* for some effectors we need the object center every time */ + VecSubf(efd->vec_to_point2, point->loc, eff->ob->obmat[3]); + VECCOPY(efd->nor2, eff->ob->obmat[2]); + Normalize(efd->nor2); + } } return ret; @@ -835,8 +843,7 @@ void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint * switch(pd->forcefield){ case PFIELD_WIND: - Normalize(force); - strength *= (Inpf(force, efd->nor) >= 0.0f ? 1.0f : -1.0f); + VECCOPY(force, efd->nor); VecMulf(force, strength * efd->falloff); break; case PFIELD_FORCE: diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 3b47c2f1830..55fb9f45bb3 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6211,7 +6211,8 @@ static void surfaceModifier_freeData(ModifierData *md) MEM_freeN(surmd->bvhtree); } - surmd->dm->release(surmd->dm); + if(surmd->dm) + surmd->dm->release(surmd->dm); if(surmd->x) MEM_freeN(surmd->x); @@ -6298,7 +6299,10 @@ static void surfaceModifier_deformVerts( else surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh"); - bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6); + if(surmd->dm->getNumFaces(surmd->dm)) + bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6); + else + bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6); } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index f4f5a1364a3..011d5c3f134 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -37,6 +37,7 @@ #include "DNA_scene_types.h" #include "DNA_boid_types.h" +#include "DNA_group_types.h" #include "DNA_particle_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -63,6 +64,7 @@ #include "BKE_cloth.h" #include "BKE_effect.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_main.h" #include "BKE_lattice.h" #include "BKE_utildefines.h" @@ -296,6 +298,60 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys) return 1; } +void psys_check_group_weights(ParticleSettings *part) +{ + ParticleDupliWeight *dw, *tdw; + GroupObject *go; + int current = 0; + + if(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first) { + /* first remove all weights that don't have an object in the group */ + dw = part->dupliweights.first; + while(dw) { + if(!object_in_group(dw->ob, part->dup_group)) { + tdw = dw->next; + BLI_freelinkN(&part->dupliweights, dw); + dw = tdw; + } + else + dw = dw->next; + } + + /* then add objects in the group to new list */ + go = part->dup_group->gobject.first; + while(go) { + dw = part->dupliweights.first; + while(dw && dw->ob != go->ob) + dw = dw->next; + + if(!dw) { + dw = MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight"); + dw->ob = go->ob; + dw->count = 1; + BLI_addtail(&part->dupliweights, dw); + } + + go = go->next; + } + + dw = part->dupliweights.first; + for(; dw; dw=dw->next) { + if(dw->flag & PART_DUPLIW_CURRENT) { + current = 1; + break; + } + } + + if(!current) { + dw = part->dupliweights.first; + if(dw) + dw->flag |= PART_DUPLIW_CURRENT; + } + } + else { + BLI_freelistN(&part->dupliweights); + } +} /************************************************/ /* Freeing stuff */ /************************************************/ @@ -307,6 +363,8 @@ void psys_free_settings(ParticleSettings *part) if(part->effector_weights) MEM_freeN(part->effector_weights); + BLI_freelistN(&part->dupliweights); + boid_free_settings(part->boids); } @@ -439,6 +497,9 @@ void psys_free_pdd(ParticleSystem *psys) if(psys->pdd->vedata) MEM_freeN(psys->pdd->vedata); psys->pdd->vedata = NULL; + + psys->pdd->totpoint = 0; + psys->pdd->tot_vec_size = 0; } } /* free everything */ @@ -2047,10 +2108,10 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float float roughfac; roughfac=fac*(float)pow((double)t,shape); - VECCOPY(rough,loc); + Vec2Copyf(rough,loc); rough[0]=-1.0f+2.0f*rough[0]; rough[1]=-1.0f+2.0f*rough[1]; - VecMulf(rough,roughfac); + Vec2Mulf(rough,roughfac); VECADDFAC(state->co,state->co,mat[0],rough[0]); VECADDFAC(state->co,state->co,mat[1],rough[1]); @@ -3235,6 +3296,9 @@ static void default_particle_settings(ParticleSettings *part) part->size=0.05; part->childsize=1.0; + part->rotmode = PART_ROT_VEL; + part->avemode = PART_AVE_SPIN; + part->child_nbr=10; part->ren_child_nbr=100; part->childrad=0.2f; @@ -3788,6 +3852,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * /* get different child parameters from textures & vgroups */ memset(&ctx, 0, sizeof(ParticleThreadContext)); + ctx.sim = *sim; ctx.dm = psmd->dm; ctx.ma = ma; /* TODO: assign vertex groups */ @@ -3856,6 +3921,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta ChildParticle *cpa = NULL; float cfra; int totpart = psys->totpart; + float timestep = psys_get_timestep(sim); /* negative time means "use current time" */ cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0); @@ -3924,13 +3990,14 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta calc_latt_deform(sim->psys->lattice, state->co,1.0f); } else{ - if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)) + if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED) + || pa->prev_state.time <= 0.0f) copy_particle_key(state, &pa->state, 1); else if(pa->prev_state.time==state->time) copy_particle_key(state, &pa->prev_state, 1); else { /* let's interpolate to try to be as accurate as possible */ - if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) { + if(pa->state.time + 2.0f > state->time && pa->prev_state.time - 2.0f < state->time) { ParticleKey keys[4]; float dfra, keytime, frs_sec = sim->scene->r.frs_sec; @@ -3949,13 +4016,13 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta keytime = (state->time - keys[1].time) / dfra; /* convert velocity to timestep size */ - VecMulf(keys[1].vel, dfra / frs_sec); - VecMulf(keys[2].vel, dfra / frs_sec); + VecMulf(keys[1].vel, dfra * timestep); + VecMulf(keys[2].vel, dfra * timestep); psys_interpolate_particle(-1, keys, keytime, state, 1); /* convert back to real velocity */ - VecMulf(state->vel, frs_sec / dfra); + VecMulf(state->vel, 1.0f / (dfra * timestep)); VecLerpf(state->ave, keys[1].ave, keys[2].ave, keytime); QuatInterpol(state->rot, keys[1].rot, keys[2].rot, keytime); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index d757372f17b..45050127582 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -183,6 +183,8 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart) if(totpart && totpart != psys->totpart) { newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles"); + if(psys->part->phystype == PART_PHYS_BOIDS) + newboids= MEM_callocN(totpart*sizeof(BoidParticle), "boid particles"); if(psys->particles) { totsaved=MIN2(psys->totpart,totpart); @@ -215,13 +217,12 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart) } psys->particles=newpars; + psys->totpart=totpart; if(newboids) { LOOP_PARTICLES pa->boid = newboids++; } - - psys->totpart=totpart; } if(psys->child) { @@ -1660,7 +1661,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, ParticleKey state; //IpoCurve *icu=0; // XXX old animation system float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4]; - float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0}; + float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3]={0.0,0.0,0.0}; float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0}; float q_phase[4], r_phase; int p = pa - psys->particles; @@ -1773,7 +1774,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, } } - if(part->phystype==PART_PHYS_BOIDS) { + if(part->phystype==PART_PHYS_BOIDS && pa->boid) { BoidParticle *bpa = pa->boid; float dvec[3], q[4], mat[3][3]; @@ -1839,6 +1840,23 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, VECADDFAC(vel,vel,vtan,part->tanfac); //VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f)); + /* *emitter object orientation */ + if(part->ob_vel[0]!=0.0) { + VECCOPY(vec, ob->obmat[0]); + Normalize(vec); + VECADDFAC(vel, vel, vec, part->ob_vel[0]); + } + if(part->ob_vel[1]!=0.0) { + VECCOPY(vec, ob->obmat[1]); + Normalize(vec); + VECADDFAC(vel, vel, vec, part->ob_vel[1]); + } + if(part->ob_vel[2]!=0.0) { + VECCOPY(vec, ob->obmat[2]); + Normalize(vec); + VECADDFAC(vel, vel, vec, part->ob_vel[2]); + } + /* *texture */ /* TODO */ @@ -3135,7 +3153,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) ParticleSystem *psys = sim->psys; ParticleSettings *part=psys->part; KDTree *tree=0; - //IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system + //IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system /* Material *ma=give_current_material(sim->ob, part->omat); */ BoidBrainData bbd; PARTICLE_P; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index bffe4566f74..fa0d5cba604 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -269,7 +269,7 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr /* determine rotation from velocity */ if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) { - vectoquat(pa->state.vel, OB_POSX, OB_POSZ, pa->state.rot); + vectoquat(pa->state.vel, OB_NEGX, OB_POSZ, pa->state.rot); } } static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data) @@ -292,6 +292,23 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f else BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2); + /* determine velocity from previous location */ + if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) { + if(keys[1].time > keys[2].time) { + VecSubf(keys[2].vel, keys[1].co, keys[2].co); + VecMulf(keys[2].vel, (keys[1].time - keys[2].time) / frs_sec); + } + else { + VecSubf(keys[2].vel, keys[2].co, keys[1].co); + VecMulf(keys[2].vel, (keys[2].time - keys[1].time) / frs_sec); + } + } + + /* determine rotation from velocity */ + if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) { + vectoquat(keys[2].vel, OB_NEGX, OB_POSZ, keys[2].rot); + } + if(cfra > pa->time) cfra1 = MAX2(cfra1, pa->time); @@ -301,7 +318,7 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f VecMulf(keys[2].vel, dfra / frs_sec); psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1); - QuatInterpol(pa->state.rot, keys[1].rot,keys[2].rot, (cfra - cfra1) / dfra); + QuatInterpol(pa->state.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra); VecMulf(pa->state.vel, frs_sec / dfra); @@ -594,7 +611,8 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p if(psys->part->phystype == PART_PHYS_BOIDS) pid->data_types|= (1<part->rotmode || psys->part->avemode) + if(psys->part->rotmode!=PART_ROT_VEL + || psys->part->avemode!=PART_AVE_SPIN || psys->part->avefac!=0.0f) pid->data_types|= (1<part->flag & PART_ROT_DYN) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a3a56e9a075..989e2b3fa9e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3033,6 +3033,7 @@ static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointC static void lib_link_particlesettings(FileData *fd, Main *main) { ParticleSettings *part; + ParticleDupliWeight *dw; part= main->particle.first; while(part) { @@ -3048,6 +3049,10 @@ static void lib_link_particlesettings(FileData *fd, Main *main) if(part->effector_weights) part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group); + dw = part->dupliweights.first; + for(; dw; dw=dw->next) + dw->ob = newlibadr(fd, part->id.lib, dw->ob); + if(part->boids) { BoidState *state = part->boids->states.first; BoidRule *rule; @@ -3088,6 +3093,8 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) else part->effector_weights = BKE_add_effector_weights(part->eff_group); + link_list(fd, &part->dupliweights); + part->boids= newdataadr(fd, part->boids); if(part->boids) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 1f46446dc2a..c92c0909d3b 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -610,6 +610,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches) static void write_particlesettings(WriteData *wd, ListBase *idbase) { ParticleSettings *part; + ParticleDupliWeight *dw; part= idbase->first; while(part) { @@ -622,6 +623,10 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "PartDeflect", 1, part->pd2); writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights); + dw = part->dupliweights.first; + for(; dw; dw=dw->next) + writestruct(wd, DATA, "ParticleDupliWeight", 1, dw); + if(part->boids && part->phystype == PART_PHYS_BOIDS) { BoidState *state = part->boids->states.first; diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index cef630b6711..1dc08a162b7 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -348,6 +348,82 @@ void PARTICLE_OT_target_move_down(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/************************ move up particle dupliweight operator *********************/ + +static int dupliob_move_up_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + ParticleSettings *part; + ParticleDupliWeight *dw; + + if(!psys) + return OPERATOR_CANCELLED; + + part = psys->part; + for(dw=part->dupliweights.first; dw; dw=dw->next) { + if(dw->flag & PART_DUPLIW_CURRENT && dw->prev) { + BLI_remlink(&part->dupliweights, dw); + BLI_insertlink(&part->dupliweights, dw->prev->prev, dw); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); + break; + } + } + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot) +{ + ot->name= "Move Up Dupli Object"; + ot->idname= "PARTICLE_OT_dupliob_move_up"; + ot->description= "Move dupli object up in the list."; + + ot->exec= dupliob_move_up_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/************************ move down particle dupliweight operator *********************/ + +static int dupliob_move_down_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); + ParticleSystem *psys= ptr.data; + ParticleSettings *part; + ParticleDupliWeight *dw; + + if(!psys) + return OPERATOR_CANCELLED; + + part = psys->part; + for(dw=part->dupliweights.first; dw; dw=dw->next) { + if(dw->flag & PART_DUPLIW_CURRENT && dw->next) { + BLI_remlink(&part->dupliweights, dw); + BLI_insertlink(&part->dupliweights, dw->next, dw); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL); + break; + } + } + + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot) +{ + ot->name= "Move Down Dupli Object"; + ot->idname= "PARTICLE_OT_dupliob_move_down"; + ot->description= "Move dupli object down in the list."; + + ot->exec= dupliob_move_down_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /************************ connect/disconnect hair operators *********************/ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index 956f26c478d..3847ec8032a 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -77,6 +77,9 @@ void PARTICLE_OT_target_move_down(struct wmOperatorType *ot); void PARTICLE_OT_connect_hair(struct wmOperatorType *ot); void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot); +void PARTICLE_OT_dupliob_move_up(struct wmOperatorType *ot); +void PARTICLE_OT_dupliob_move_down(struct wmOperatorType *ot); + /* particle_boids.c */ void BOID_OT_rule_add(struct wmOperatorType *ot); void BOID_OT_rule_del(struct wmOperatorType *ot); diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c index a62d3d8fd78..ddc5fb9c9b6 100644 --- a/source/blender/editors/physics/physics_ops.c +++ b/source/blender/editors/physics/physics_ops.c @@ -78,6 +78,9 @@ static void operatortypes_particle(void) WM_operatortype_append(PARTICLE_OT_target_move_down); WM_operatortype_append(PARTICLE_OT_connect_hair); WM_operatortype_append(PARTICLE_OT_disconnect_hair); + + WM_operatortype_append(PARTICLE_OT_dupliob_move_up); + WM_operatortype_append(PARTICLE_OT_dupliob_move_down); } static void keymap_particle(wmWindowManager *wm) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 0f2a57d881c..0659b5cfd11 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3358,7 +3358,30 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas } /* *********** drawing for particles ************* */ +static void draw_particle_arrays(int draw_as, int totpoint, int ob_dt, int select) +{ + /* draw created data arrays */ + switch(draw_as){ + case PART_DRAW_AXIS: + case PART_DRAW_CROSS: + glDrawArrays(GL_LINES, 0, 6*totpoint); + break; + case PART_DRAW_LINE: + glDrawArrays(GL_LINES, 0, 2*totpoint); + break; + case PART_DRAW_BB: + if(ob_dt<=OB_WIRE || select) + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDrawArrays(GL_QUADS, 0, 4*totpoint); + break; + default: + glDrawArrays(GL_POINTS, 0, totpoint); + break; + } +} static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd) { float vec[3], vec2[3]; @@ -3401,7 +3424,7 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix cd[7]=cd[10]=1.0; cd[13]=cd[12]=cd[15]=cd[16]=0.0; cd[14]=cd[17]=1.0; - cd+=18; + pdd->cd+=18; VECCOPY(vec2,state->co); } @@ -3552,7 +3575,13 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(psys_in_edit_mode(scene, psys) && (pset->flag & PE_DRAW_PART)==0) return; - if(part->draw_as==PART_DRAW_NOT) return; + if(part->draw_as == PART_DRAW_REND) + draw_as = part->ren_as; + else + draw_as = part->draw_as; + + if(draw_as == PART_DRAW_NOT) + return; /* 2. */ sim.psmd = psmd = psys_get_modifier(ob,psys); @@ -3582,26 +3611,22 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(v3d->zbuf) glDepthMask(1); - if(select) - cpack(0xFFFFFF); - else if((ma) && (part->draw&PART_DRAW_MAT_COL)) { + if((ma) && (part->draw&PART_DRAW_MAT_COL)) { glColor3f(ma->r,ma->g,ma->b); ma_r = ma->r; ma_g = ma->g; ma_b = ma->b; - - if(pdd) { - pdd->ma_r = &ma_r; - pdd->ma_g = &ma_g; - pdd->ma_b = &ma_b; - } - - create_cdata = 1; } else cpack(0); + if(pdd) { + pdd->ma_r = &ma_r; + pdd->ma_g = &ma_g; + pdd->ma_b = &ma_b; + } + timestep= psys_get_timestep(&sim); if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) { @@ -3612,11 +3637,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totpart=psys->totpart; - if(part->draw_as==PART_DRAW_REND) - draw_as = part->ren_as; - else - draw_as = part->draw_as; - //if(part->flag&PART_GLOB_TIME) cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f); @@ -3646,6 +3666,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pixsize*=2.0; else pixsize*=part->draw_size; + + if(draw_as==PART_DRAW_AXIS) + create_cdata = 1; break; case PART_DRAW_OB: if(part->dup_ob==0) @@ -3693,9 +3716,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv Normalize(imat[1]); } + if(!create_cdata && pdd && pdd->cdata) { + MEM_freeN(pdd->cdata); + pdd->cdata = pdd->cd = NULL; + } + /* 4. */ - if(draw_as && draw_as!=PART_DRAW_PATH) { + if(draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC)==0) { int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); + int create_ndata = 0; if(!pdd) pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData"); @@ -3705,37 +3734,36 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv psys_make_temp_pointcache(ob, psys); } + switch(draw_as) { + case PART_DRAW_AXIS: + case PART_DRAW_CROSS: + tot_vec_size *= 6; + if(draw_as != PART_DRAW_CROSS) + create_cdata = 1; + break; + case PART_DRAW_LINE: + tot_vec_size *= 2; + break; + case PART_DRAW_BB: + tot_vec_size *= 4; + create_ndata = 1; + break; + } + if(pdd->tot_vec_size != tot_vec_size) psys_free_pdd(psys); - if(draw_as!=PART_DRAW_CIRC) { - switch(draw_as) { - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - if(draw_as != PART_DRAW_CROSS || create_cdata) - if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); - if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); - break; - case PART_DRAW_LINE: - if(create_cdata) - if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); - if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); - break; - case PART_DRAW_BB: - if(create_cdata) - if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); - if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); - if(!pdd->ndata) pdd->ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); - break; - default: - if(create_cdata) - if(!pdd->cdata) pdd->cdata=MEM_callocN(tot_vec_size, "particle_cdata"); - if(!pdd->vdata) pdd->vdata=MEM_callocN(tot_vec_size, "particle_vdata"); - } - } + if(!pdd->vdata) + pdd->vdata = MEM_callocN(tot_vec_size, "particle_vdata"); + if(create_cdata && !pdd->cdata) + pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata"); + if(create_ndata && !pdd->ndata) + pdd->ndata = MEM_callocN(tot_vec_size, "particle_vdata"); if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { - if(!pdd->vedata) pdd->vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); + if(!pdd->vedata) + pdd->vedata = MEM_callocN(2 * (totpart + totchild) * 3 * sizeof(float), "particle_vedata"); + need_v = 1; } @@ -3744,11 +3772,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pdd->cd= pdd->cdata; pdd->nd= pdd->ndata; pdd->tot_vec_size= tot_vec_size; - - psys->lattice= psys_get_lattice(&sim); } - if(draw_as){ + psys->lattice= psys_get_lattice(&sim); + + if(draw_as!=PART_DRAW_PATH){ /* 5. */ if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED) && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) { @@ -3836,156 +3864,139 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv r_length = PSYS_FRAND(a + 22); } - if(draw_as!=PART_DRAW_PATH){ - drawn = 0; - if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) { - float length = part->path_end * (1.0 - part->randlength * r_length); - int trail_count = part->trail_count * (1.0 - part->randlength * r_length); - float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length; - float dt = length / (trail_count ? (float)trail_count : 1.0f); - int i=0; - - ct+=dt; - for(i=0; i < trail_count; i++, ct += dt) { - if(part->draw & PART_ABS_PATH_TIME) { - if(ct < pa_birthtime || ct > pa_dietime) - continue; - } - else if(ct < 0.0f || ct > 1.0f) + drawn = 0; + if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) { + float length = part->path_end * (1.0 - part->randlength * r_length); + int trail_count = part->trail_count * (1.0 - part->randlength * r_length); + float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length; + float dt = length / (trail_count ? (float)trail_count : 1.0f); + int i=0; + + ct+=dt; + for(i=0; i < trail_count; i++, ct += dt) { + if(part->draw & PART_ABS_PATH_TIME) { + if(ct < pa_birthtime || ct > pa_dietime) continue; + } + else if(ct < 0.0f || ct > 1.0f) + continue; - state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); - psys_get_particle_on_path(&sim,a,&state,need_v); - - if(psys->parent) - Mat4MulVecfl(psys->parent->obmat, state.co); - - /* create actiual particle data */ - if(draw_as == PART_DRAW_BB) { - bb.size = pa_size; - bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb.time = ct; - } + state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); + psys_get_particle_on_path(&sim,a,&state,need_v); + + if(psys->parent) + Mat4MulVecfl(psys->parent->obmat, state.co); + + /* create actiual particle data */ + if(draw_as == PART_DRAW_BB) { + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = ct; + } - draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd); + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd); - totpoint++; - drawn = 1; - } + totpoint++; + drawn = 1; } - else - { - state.time=cfra; - if(psys_get_particle_state(&sim,a,&state,0)){ - if(psys->parent) - Mat4MulVecfl(psys->parent->obmat, state.co); - - /* create actiual particle data */ - if(draw_as == PART_DRAW_BB) { - bb.size = pa_size; - bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb.time = pa_time; - } + } + else + { + state.time=cfra; + if(psys_get_particle_state(&sim,a,&state,0)){ + if(psys->parent) + Mat4MulVecfl(psys->parent->obmat, state.co); + + /* create actiual particle data */ + if(draw_as == PART_DRAW_BB) { + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = pa_time; + } - draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd); + draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd); - totpoint++; - drawn = 1; - } + totpoint++; + drawn = 1; } + } - if(drawn) { - /* additional things to draw for each particle */ - /* (velocity, size and number) */ - if(pdd->vedata){ - VECCOPY(pdd->ved,state.co); - pdd->ved+=3; - VECCOPY(vel,state.vel); - VecMulf(vel,timestep); - VECADD(pdd->ved,state.co,vel); - pdd->ved+=3; - - totve++; - } + if(drawn) { + /* additional things to draw for each particle */ + /* (velocity, size and number) */ + if(pdd->vedata){ + VECCOPY(pdd->ved,state.co); + pdd->ved+=3; + VECCOPY(vel,state.vel); + VecMulf(vel,timestep); + VECADD(pdd->ved,state.co,vel); + pdd->ved+=3; + + totve++; + } - if(part->draw & PART_DRAW_SIZE){ - setlinestyle(3); - drawcircball(GL_LINE_LOOP, state.co, pa_size, imat); - setlinestyle(0); - } + if(part->draw & PART_DRAW_SIZE){ + setlinestyle(3); + drawcircball(GL_LINE_LOOP, state.co, pa_size, imat); + setlinestyle(0); + } - if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){ - val[0]= '\0'; - - if(part->draw&PART_DRAW_NUM) - sprintf(val, " %i", a); + if((part->draw&PART_DRAW_NUM || part->draw&PART_DRAW_HEALTH) && !(G.f & G_RENDER_SHADOW)){ + val[0]= '\0'; + + if(part->draw&PART_DRAW_NUM) + sprintf(val, " %i", a); - if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH) - sprintf(val, "%s:", val); + if(part->draw&PART_DRAW_NUM && part->draw&PART_DRAW_HEALTH) + sprintf(val, "%s:", val); - if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS) - sprintf(val, "%s %.2f", val, pa_health); + if(part->draw&PART_DRAW_HEALTH && a < totpart && part->phystype==PART_PHYS_BOIDS) + sprintf(val, "%s %.2f", val, pa_health); - /* in path drawing state.co is the end point */ - view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); - } + /* in path drawing state.co is the end point */ + view3d_cached_text_draw_add(state.co[0], state.co[1], state.co[2], val, 0); } } } + } /* 6. */ - glGetIntegerv(GL_POLYGON_MODE, polygonmode); - glDisableClientState(GL_NORMAL_ARRAY); - - if(draw_as==PART_DRAW_PATH){ - ParticleCacheKey **cache, *path; - float *cd2=0,*cdata2=0; - - glEnableClientState(GL_VERTEX_ARRAY); + glGetIntegerv(GL_POLYGON_MODE, polygonmode); + glDisableClientState(GL_NORMAL_ARRAY); - /* setup gl flags */ - if(ob_dt > OB_WIRE) { - glEnableClientState(GL_NORMAL_ARRAY); + if(draw_as==PART_DRAW_PATH){ + ParticleCacheKey **cache, *path; + float *cd2=0,*cdata2=0; - if(part->draw&PART_DRAW_MAT_COL) - glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - } - else { - glDisableClientState(GL_NORMAL_ARRAY); + /* setup gl flags */ + if(ob_dt > OB_WIRE) { + glEnableClientState(GL_NORMAL_ARRAY); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - UI_ThemeColor(TH_WIRE); - } + if(part->draw&PART_DRAW_MAT_COL) + glEnableClientState(GL_COLOR_ARRAY); - if(totchild && (part->draw&PART_DRAW_PARENT)==0) - totpart=0; + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); - /* draw actual/parent particles */ - cache=psys->pathcache; - for(a=0, pa=psys->particles; asteps > 0) { - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + UI_ThemeColor(TH_WIRE); + } - if(ob_dt > OB_WIRE) { - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); - } + if(totchild && (part->draw&PART_DRAW_PARENT)==0) + totpart=0; - glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); - } - } - - /* draw child particles */ - cache=psys->childcache; - for(a=0; apathcache; + for(a=0, pa=psys->particles; asteps > 0) { glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); if(ob_dt > OB_WIRE) { @@ -3996,86 +4007,104 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } + } + + /* draw child particles */ + cache=psys->childcache; + for(a=0; aco); - - /* restore & clean up */ if(ob_dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); if(part->draw&PART_DRAW_MAT_COL) - glDisable(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); } - if(cdata2) - MEM_freeN(cdata2); - cd2=cdata2=0; + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); + } - glLineWidth(1.0f); + + /* restore & clean up */ + if(ob_dt > OB_WIRE) { + if(part->draw&PART_DRAW_MAT_COL) + glDisable(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); } - else if(draw_as!=PART_DRAW_CIRC){ - glDisableClientState(GL_COLOR_ARRAY); - /* setup created data arrays */ - if(pdd->vdata){ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, pdd->vdata); - } + if(cdata2) + MEM_freeN(cdata2); + cd2=cdata2=0; + + glLineWidth(1.0f); + } + else if(ELEM(draw_as, 0, PART_DRAW_CIRC)==0){ + int point_size = 1; + glDisableClientState(GL_COLOR_ARRAY); + + /* enable point data array */ + if(pdd->vdata){ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pdd->vdata); + } + else + glDisableClientState(GL_VERTEX_ARRAY); + + if(select) { + UI_ThemeColor(TH_ACTIVE); + + if(part->draw_size) + glPointSize(part->draw_size + 2); else - glDisableClientState(GL_VERTEX_ARRAY); + glPointSize(4.0); - /* billboards are drawn this way */ - if(pdd->ndata && ob_dt>OB_WIRE){ - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, pdd->ndata); - glEnable(GL_LIGHTING); - } - else{ - glDisableClientState(GL_NORMAL_ARRAY); - glDisable(GL_LIGHTING); - } + glLineWidth(3.0); - if(pdd->cdata){ - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, pdd->cdata); - } + draw_particle_arrays(draw_as, totpoint, ob_dt, 1); + } - /* draw created data arrays */ - switch(draw_as){ - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - glDrawArrays(GL_LINES, 0, 6*totpoint); - break; - case PART_DRAW_LINE: - glDrawArrays(GL_LINES, 0, 2*totpoint); - break; - case PART_DRAW_BB: - if(ob_dt<=OB_WIRE) - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - glDrawArrays(GL_QUADS, 0, 4*totpoint); - break; - default: - glDrawArrays(GL_POINTS, 0, totpoint); - break; - } + /* restore from select */ + glColor3f(ma_r,ma_g,ma_b); + glPointSize(part->draw_size ? part->draw_size : 2.0); + glLineWidth(1.0); + + /* enable other data arrays */ - pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; - pdd->totpoint = totpoint; + /* billboards are drawn this way */ + if(pdd->ndata && ob_dt>OB_WIRE){ + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, pdd->ndata); + glEnable(GL_LIGHTING); + } + else{ + glDisableClientState(GL_NORMAL_ARRAY); + glDisable(GL_LIGHTING); } - if(pdd->vedata){ - glDisableClientState(GL_COLOR_ARRAY); - cpack(0xC0C0C0); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, pdd->vedata); - - glDrawArrays(GL_LINES, 0, 2*totve); + if(pdd->cdata){ + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, pdd->cdata); } - glPolygonMode(GL_FRONT, polygonmode[0]); - glPolygonMode(GL_BACK, polygonmode[1]); + draw_particle_arrays(draw_as, totpoint, ob_dt, 0); + + pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; + pdd->totpoint = totpoint; + } + + if(pdd && pdd->vedata){ + glDisableClientState(GL_COLOR_ARRAY); + cpack(0xC0C0C0); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pdd->vedata); + + glDrawArrays(GL_LINES, 0, 2*totve); } + glPolygonMode(GL_FRONT, polygonmode[0]); + glPolygonMode(GL_BACK, polygonmode[1]); + /* 7. */ glDisable(GL_LIGHTING); @@ -4087,6 +4116,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv psys->flag &= ~PSYS_DRAWING; + /* draw data can't be saved for billboards as they must update to target changes */ + if(draw_as == PART_DRAW_BB) { + psys_free_pdd(psys); + pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; + } + if(psys->lattice){ end_latt_deform(psys->lattice); psys->lattice= NULL; diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index e7e785e605b..1376a08eb3e 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -56,14 +56,14 @@ typedef enum PFieldType { } PFieldType; typedef struct PartDeflect { + int flag; /* general settings flag */ short deflect; /* Deflection flag - does mesh deflect particles */ short forcefield; /* Force field type, do the vertices attract / repel particles? */ - short flag; /* general settings flag */ short falloff; /* fall-off type */ short shape; /* point, plane or surface */ short tex_mode; /* texture effector */ short kink, kink_axis; /* for curve guide */ - short zdir, rt; + short zdir; /* Main effector values */ float f_strength; /* The strength of the force (+ or - ) */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 4c620ae527e..157767e1d13 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -78,6 +78,13 @@ typedef struct ParticleTarget { float time, duration; } ParticleTarget; +typedef struct ParticleDupliWeight { + struct ParticleDupliWeight *next, *prev; + struct Object *ob; + short count; + short flag, rt[2]; +} ParticleDupliWeight; + typedef struct ParticleData { ParticleKey state; /* current global coordinates */ @@ -148,6 +155,7 @@ typedef struct ParticleSettings { /* initial velocity factors */ float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac; + float ob_vel[3], rt; float avefac, phasefac, randrotfac, randphasefac; /* physical properties */ float mass, size, randsize, reactshape; @@ -179,6 +187,7 @@ typedef struct ParticleSettings { int keyed_loops; struct Group *dup_group; + struct ListBase dupliweights; struct Group *eff_group; // deprecated struct Object *dup_ob; struct Object *bb_ob; @@ -324,12 +333,12 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in /* part->draw */ #define PART_DRAW_VEL 1 -//#define PART_DRAW_PATH_LEN 2 +#define PART_DRAW_GLOBAL_OB 2 #define PART_DRAW_SIZE 4 #define PART_DRAW_EMITTER 8 /* render emitter also */ #define PART_DRAW_HEALTH 16 #define PART_ABS_PATH_TIME 32 -//#define PART_DRAW_TRAIL 64 /* deprecated */ +#define PART_DRAW_COUNT_GR 64 #define PART_DRAW_BB_LOCK 128 #define PART_DRAW_PARENT 256 #define PART_DRAW_NUM 512 @@ -444,6 +453,9 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PARS_ALIVE 3 #define PARS_DYING 4 +/* ParticleDupliWeight->flag */ +#define PART_DUPLIW_CURRENT 1 + /* psys->vg */ #define PSYS_TOT_VG 12 diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 022c04240af..404223ab590 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -45,6 +45,13 @@ EnumPropertyItem effector_shape_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem curve_shape_items[] = { + {PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""}, + {PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""}, + {PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Curve", ""}, + {0, NULL, 0, NULL, NULL} +}; + EnumPropertyItem empty_shape_items[] = { {PFIELD_SHAPE_POINT, "POINT", 0, "Point", ""}, {PFIELD_SHAPE_PLANE, "PLANE", 0, "Plane", ""}, @@ -59,6 +66,13 @@ EnumPropertyItem vortex_shape_items[] = { {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem curve_vortex_shape_items[] = { + {PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""}, + {PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""}, + {PFIELD_SHAPE_SURFACE, "SURFACE", 0, "Curve (New)", ""}, + {0, NULL, 0, NULL, NULL} +}; + EnumPropertyItem empty_vortex_shape_items[] = { {PFIELD_SHAPE_POINT, "POINT", 0, "Old", ""}, {PFIELD_SHAPE_PLANE, "PLANE", 0, "New", ""}, @@ -538,9 +552,11 @@ static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr, /* needed for doc generation */ RNA_enum_items_add(&item, &totitem, effector_shape_items); + RNA_enum_items_add(&item, &totitem, curve_shape_items); RNA_enum_items_add(&item, &totitem, empty_shape_items); RNA_enum_items_add(&item, &totitem, vortex_shape_items); - RNA_enum_items_add(&item, &totitem, empty_shape_items); + RNA_enum_items_add(&item, &totitem, curve_vortex_shape_items); + RNA_enum_items_add(&item, &totitem, empty_vortex_shape_items); RNA_enum_item_end(&item, &totitem); *free= 1; @@ -553,7 +569,13 @@ static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr, ob= (Object*)ptr->id.data; - if(ELEM4(ob->type, OB_MESH, OB_SURF, OB_FONT, OB_CURVE)) { + if(ob->type == OB_CURVE) { + if(ob->pd->forcefield == PFIELD_VORTEX) + return curve_vortex_shape_items; + + return curve_shape_items; + } + else if(ELEM3(ob->type, OB_MESH, OB_SURF, OB_FONT)) { if(ob->pd->forcefield == PFIELD_VORTEX) return vortex_shape_items; @@ -783,11 +805,11 @@ static void rna_def_effector_weight(BlenderRNA *brna) RNA_def_property_ui_text(prop, "All", "All effector's weight."); RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); - prop= RNA_def_property(srna, "spherical", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "force", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "weight[1]"); RNA_def_property_range(prop, -200.0f, 200.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); - RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight."); + RNA_def_property_ui_text(prop, "Force", "Force effector weight."); RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); prop= RNA_def_property(srna, "vortex", PROP_FLOAT, PROP_NONE); @@ -1113,6 +1135,11 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_DO_ROTATION); RNA_def_property_ui_text(prop, "Rotation", "Effect particles' dynamic rotation"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop= RNA_def_property(srna, "do_absorption", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_VISIBILITY); + RNA_def_property_ui_text(prop, "Absorption", "Force gets absorbed by collision objects"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /* Pointer */ diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 453b5f9f91a..2c81bda121f 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -105,6 +105,7 @@ EnumPropertyItem part_hair_ren_as_items[] = { #include "BKE_pointcache.h" #include "BLI_arithb.h" +#include "BLI_listbase.h" /* property update functions */ static void particle_recalc(bContext *C, PointerRNA *ptr, short flag) @@ -433,6 +434,71 @@ static int rna_ParticleSystem_edited_get(PointerRNA *ptr) else return (psys->pointcache->edit && psys->pointcache->edit->edited); } +static PointerRNA rna_ParticleDupliWeight_active_get(PointerRNA *ptr) +{ + ParticleSettings *part= (ParticleSettings*)ptr->id.data; + ParticleDupliWeight *dw = part->dupliweights.first; + + for(; dw; dw=dw->next) { + if(dw->flag & PART_DUPLIW_CURRENT) + return rna_pointer_inherit_refine(ptr, &RNA_ParticleDupliWeight, dw); + } + return rna_pointer_inherit_refine(ptr, &RNA_ParticleTarget, NULL); +} +static void rna_ParticleDupliWeight_active_index_range(PointerRNA *ptr, int *min, int *max) +{ + ParticleSettings *part= (ParticleSettings*)ptr->id.data; + *min= 0; + *max= BLI_countlist(&part->dupliweights)-1; + *max= MAX2(0, *max); +} + +static int rna_ParticleDupliWeight_active_index_get(PointerRNA *ptr) +{ + ParticleSettings *part= (ParticleSettings*)ptr->id.data; + ParticleDupliWeight *dw = part->dupliweights.first; + int i=0; + + for(; dw; dw=dw->next, i++) + if(dw->flag & PART_DUPLIW_CURRENT) + return i; + + return 0; +} + +static void rna_ParticleDupliWeight_active_index_set(struct PointerRNA *ptr, int value) +{ + ParticleSettings *part= (ParticleSettings*)ptr->id.data; + ParticleDupliWeight *dw = part->dupliweights.first; + int i=0; + + for(; dw; dw=dw->next, i++) { + if(i==value) + dw->flag |= PART_DUPLIW_CURRENT; + else + dw->flag &= ~PART_DUPLIW_CURRENT; + } +} + +static int rna_ParticleDupliWeight_name_length(PointerRNA *ptr) +{ + ParticleDupliWeight *dw= ptr->data; + + if(dw->ob) + return strlen(dw->ob->id.name+2) + 7; + else + return 9 + 7; +} + +static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str) +{ + ParticleDupliWeight *dw= ptr->data; + + if(dw->ob) + sprintf(str, "%s: %i", dw->ob->id.name+2, dw->count); + else + strcpy(str, "No object"); +} EnumPropertyItem from_items[] = { {PART_FROM_VERT, "VERT", 0, "Vertexes", ""}, {PART_FROM_FACE, "FACE", 0, "Faces", ""}, @@ -726,6 +792,27 @@ static void rna_def_particle(BlenderRNA *brna) // short rt2; } +static void rna_def_particle_dupliweight(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ParticleDupliWeight", NULL); + RNA_def_struct_ui_text(srna, "Particle Dupliobject Weight", "Weight of a particle dupliobject in a group."); + RNA_def_struct_sdna(srna, "ParticleDupliWeight"); + + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_ParticleDupliWeight_name_get", "rna_ParticleDupliWeight_name_length", NULL); + RNA_def_property_ui_text(prop, "Name", "Particle dupliobject name."); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_struct_name_property(srna, prop); + + prop= RNA_def_property(srna, "count", PROP_INT, PROP_UNSIGNED); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Count", "The number of times this object is repeated with respect to other objects."); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); +} + static void rna_def_particle_settings(BlenderRNA *brna) { StructRNA *srna; @@ -1069,6 +1156,16 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pick Random", "Pick objects from group randomly"); RNA_def_property_update(prop, 0, "rna_Particle_redo"); + prop= RNA_def_property(srna, "use_group_count", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_COUNT_GR); + RNA_def_property_ui_text(prop, "Use Count", "Use object multiple times in the same group"); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); + + prop= RNA_def_property(srna, "use_global_dupli", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_GLOBAL_OB); + RNA_def_property_ui_text(prop, "Use Global", "Use object's global coordinates for duplication."); + RNA_def_property_update(prop, 0, "rna_Particle_redo"); + prop= RNA_def_property(srna, "render_adaptive", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_ADAPT); RNA_def_property_ui_text(prop, "Adaptive render", "Draw steps of the particle path"); @@ -1374,6 +1471,13 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Reactor", "Let the vector away from the target particles location give the particle a starting speed."); RNA_def_property_update(prop, 0, "rna_Particle_reset"); + prop= RNA_def_property(srna, "object_aligned_factor", PROP_FLOAT, PROP_VELOCITY); + RNA_def_property_float_sdna(prop, NULL, "ob_vel"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_text(prop, "Object Aligned", "Let the emitter object orientation give the particle a starting speed"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); + prop= RNA_def_property(srna, "angular_velocity_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "avefac"); RNA_def_property_range(prop, -200.0f, 200.0f); @@ -1426,19 +1530,6 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* global physical properties */ - prop= RNA_def_property(srna, "acceleration", PROP_FLOAT, PROP_ACCELERATION); - RNA_def_property_float_sdna(prop, NULL, "acc"); - RNA_def_property_array(prop, 3); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_text(prop, "Acceleration", "Constant acceleration"); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION); - RNA_def_property_float_sdna(prop, NULL, "acc[2]"); - RNA_def_property_range(prop, -200.0f, 200.0f); - RNA_def_property_ui_text(prop, "Gravity", "Constant acceleration in global Z axis direction"); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - prop= RNA_def_property(srna, "drag_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "dragfac"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -1665,6 +1756,19 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Dupli Group", "Show Objects in this Group in place of particles"); RNA_def_property_update(prop, 0, "rna_Particle_redo"); + prop= RNA_def_property(srna, "dupliweights", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "ParticleDupliWeight"); + RNA_def_property_ui_text(prop, "Dupli Group Weights", "Weights for all of the objects in the dupli group."); + + prop= RNA_def_property(srna, "active_dupliweight", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ParticleDupliWeight"); + RNA_def_property_pointer_funcs(prop, "rna_ParticleDupliWeight_active_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Active Dupli Object", ""); + + prop= RNA_def_property(srna, "active_dupliweight_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_funcs(prop, "rna_ParticleDupliWeight_active_index_get", "rna_ParticleDupliWeight_active_index_set", "rna_ParticleDupliWeight_active_index_range"); + RNA_def_property_ui_text(prop, "Active Dupli Object Index", ""); + prop= RNA_def_property(srna, "dupli_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "dup_ob"); RNA_def_property_struct_type(prop, "Object"); @@ -2024,6 +2128,7 @@ void RNA_def_particle(BlenderRNA *brna) rna_def_child_particle(brna); rna_def_particle(brna); + rna_def_particle_dupliweight(brna); rna_def_particle_system(brna); rna_def_particle_settings(brna); } -- cgit v1.2.3 From 77b8be6e1390f167bf83f0ca8b10f77fb758d4a0 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Mon, 5 Oct 2009 15:00:07 +0000 Subject: Cocoa port : Fix bugs in clipboard operations --- intern/ghost/intern/GHOST_SystemCocoa.mm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index c66153ab670..06ce2882beb 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1271,7 +1271,7 @@ GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; - if (pasteBoard = nil) { + if (pasteBoard == nil) { [pool drain]; return NULL; } @@ -1289,11 +1289,19 @@ GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const NSString * textPasted = [pasteBoard stringForType:@"public.utf8-plain-text"]; + if (textPasted == nil) { + [pool drain]; + return NULL; + } + pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); - if (temp_buff == NULL) return NULL; + if (temp_buff == NULL) { + [pool drain]; + return NULL; + } strncpy((char*)temp_buff, [textPasted UTF8String], pastedTextSize); @@ -1318,12 +1326,12 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; - if (pasteBoard = nil) { + if (pasteBoard == nil) { [pool drain]; return; } - NSArray *supportedTypes = [NSArray arrayWithObjects: @"public.utf8-plain-text",nil]; + NSArray *supportedTypes = [NSArray arrayWithObject:@"public.utf8-plain-text"]; [pasteBoard declareTypes:supportedTypes owner:nil]; -- cgit v1.2.3 From 4df1e400066b30a0bf378b17b6c2168456920be1 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 5 Oct 2009 15:59:12 +0000 Subject: Fixed [#19539] Texture > RGB Factor property doesn't appear in the UI --- release/scripts/ui/buttons_texture.py | 9 +++++++-- source/blender/makesrna/intern/rna_texture.c | 20 ++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index 6eab84afc42..c4866edcaaa 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -99,8 +99,13 @@ class TEXTURE_PT_colors(TextureButtonsPanel): layout.template_color_ramp(tex, "color_ramp", expand=True) split = layout.split() - - split.itemR(tex, "rgb_factor", text="Multiply RGB") + + col = split.column() + col.itemL(text="RGB Multiply:") + sub = col.column(align=True) + sub.itemR(tex, "factor_red", text="R") + sub.itemR(tex, "factor_green", text="G") + sub.itemR(tex, "factor_blue", text="B") col = split.column() col.itemL(text="Adjust:") diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 5c7a097a54d..78d7f012487 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1653,12 +1653,24 @@ static void rna_def_texture(BlenderRNA *brna) RNA_def_property_range(prop, 0.01, 5); RNA_def_property_ui_text(prop, "Contrast", ""); RNA_def_property_update(prop, 0, "rna_Texture_update"); - - prop= RNA_def_property(srna, "rgb_factor", PROP_FLOAT, PROP_RGB); + + /* RGB Factor */ + prop= RNA_def_property(srna, "factor_red", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rfac"); - RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0, 2); - RNA_def_property_ui_text(prop, "RGB Factor", ""); + RNA_def_property_ui_text(prop, "Factor Red", ""); + RNA_def_property_update(prop, 0, "rna_Texture_update"); + + prop= RNA_def_property(srna, "factor_green", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "gfac"); + RNA_def_property_range(prop, 0, 2); + RNA_def_property_ui_text(prop, "Factor Green", ""); + RNA_def_property_update(prop, 0, "rna_Texture_update"); + + prop= RNA_def_property(srna, "factor_blue", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "bfac"); + RNA_def_property_range(prop, 0, 2); + RNA_def_property_ui_text(prop, "Factor Blue", ""); RNA_def_property_update(prop, 0, "rna_Texture_update"); /* nodetree */ -- cgit v1.2.3 From 4211e1a58ad14cfb4641a01ae27d31ce30db1bba Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 5 Oct 2009 16:18:08 +0000 Subject: Raytrace Acceleration: small tweak to RNA and UI, hiding buttons when they are not applicable. --- release/scripts/ui/buttons_scene.py | 8 +++++--- source/blender/makesrna/intern/rna_scene.c | 13 ++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 10a0efae33d..69cf79ddc85 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -173,9 +173,11 @@ class SCENE_PT_performance(RenderButtonsPanel): sub.active = rd.render_raytracing sub.itemL(text="Acceleration structure:") sub.itemR(rd, "raytrace_structure", text="") - sub.itemR(rd, "use_instances", text="Instance support") - sub.itemR(rd, "use_local_coords", text="Local coords") - sub.itemR(rd, "octree_resolution", text="Octree resolution") + if rd.raytrace_structure == "OCTREE": + sub.itemR(rd, "octree_resolution", text="Resolution") + else: + sub.itemR(rd, "use_instances", text="Instances") + sub.itemR(rd, "use_local_coords", text="Local Coordinates") class SCENE_PT_post_processing(RenderButtonsPanel): __label__ = "Post Processing" diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 267e29d7018..5ef746adf1f 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1179,12 +1179,12 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem raytrace_structure_items[] = { - {R_RAYSTRUCTURE_AUTO, "{R_RAYSTRUCTURE_AUTO", 0, "auto", ""}, - {R_RAYSTRUCTURE_OCTREE, "R_RAYSTRUCTURE_OCTREE", 0, "octree", "Use old octree structure (no support for instances)"}, - {R_RAYSTRUCTURE_BLIBVH, "R_RAYSTRUCTURE_BLIBVH", 0, "blibvh", "Use BLI_kdopbvh.c"}, - {R_RAYSTRUCTURE_VBVH, "R_RAYSTRUCTURE_VBVH", 0, "vBVH", ""}, - {R_RAYSTRUCTURE_SIMD_SVBVH, "R_RAYSTRUCTURE_SIMD_SVBVH", 0, "SIMD SVBVH", "Requires SIMD"}, - {R_RAYSTRUCTURE_SIMD_QBVH, "R_RAYSTRUCTURE_SIMD_QBVH", 0, "SIMD QBVH", "Requires SIMD"}, + {R_RAYSTRUCTURE_AUTO, "AUTO", 0, "Auto", ""}, + {R_RAYSTRUCTURE_OCTREE, "OCTREE", 0, "Octree", "Use old Octree structure."}, + {R_RAYSTRUCTURE_BLIBVH, "BLIBVH", 0, "BLI BVH", "Use BLI K-Dop BVH.c"}, + {R_RAYSTRUCTURE_VBVH, "VBVH", 0, "vBVH", ""}, + {R_RAYSTRUCTURE_SIMD_SVBVH, "SIMD_SVBVH", 0, "SIMD SVBVH", ""}, + {R_RAYSTRUCTURE_SIMD_QBVH, "SIMD_QBVH", 0, "SIMD QBVH", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1632,7 +1632,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Local Coords", "Vertex coordinates are stored localy on each primitive. Increases memory usage, but may have impact on speed."); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA); RNA_def_property_ui_text(prop, "Anti-Aliasing", "Render and combine multiple samples per pixel to prevent jagged edges."); -- cgit v1.2.3 From 5f1b4334e2e8eb6eacf921a43548e0de2cd7c23b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 5 Oct 2009 16:40:13 +0000 Subject: VBO: disable VBO's by default. Not sure why this was not done, we agreed on this as a condition for the project to be merged. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/editors/interface/resources.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 3549d3e372d..a79bf43c354 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 4 +#define BLENDER_SUBVERSION 5 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 87026bd1a5d..ee7db07f3c8 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1259,6 +1259,9 @@ void init_userdef_do_versions(void) if(U.audiorate == 0) U.audiorate = 44100; } + + if (G.main->versionfile < 250 || (G.main->versionfile == 250 && G.main->subversionfile < 5)) + U.gameflags |= USER_DISABLE_VBO; /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { -- cgit v1.2.3 From e61e1c5ca827caafb4d7ee2f2a042c9a7ec44863 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 5 Oct 2009 16:48:52 +0000 Subject: VBO: * Fix slowdown/freeze entering editmode on a high poly mesh, dm->getNumFaces can be slow, don't call it in a loop. * Fix 64bit pointer casting warnings. --- source/blender/gpu/intern/gpu_buffers.c | 63 ++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index f19edb61df1..e750a3d05fd 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -34,14 +34,18 @@ #include "GL/glew.h" -#include "DNA_userdef_types.h" - -#include "gpu_buffers.h" #include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" + +#include "DNA_meshdata_types.h" + #include "BKE_DerivedMesh.h" #include "BKE_utildefines.h" -#include "DNA_meshdata_types.h" -#include "BLI_arithb.h" + +#include "DNA_userdef_types.h" + +#include "gpu_buffers.h" #define GPU_BUFFER_VERTEX_STATE 1 #define GPU_BUFFER_NORMAL_STATE 2 @@ -248,7 +252,7 @@ GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm ) int redir[32768]; /* material number is an 16-bit short so there's at most 32768 materials */ int *index; int i; - int curmat, curverts; + int curmat, curverts, numfaces; DEBUG_VBO("GPU_drawobject_new\n"); @@ -267,7 +271,8 @@ GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm ) mvert = dm->getVertArray(dm); mface = dm->getFaceArray(dm); - for( i=0; i < dm->getNumFaces(dm); i++ ) { + numfaces= dm->getNumFaces(dm); + for( i=0; i < numfaces; i++ ) { if( mface[i].v4 ) numverts[mface[i].mat_nr+16383] += 6; /* split every quad into two triangles */ else @@ -313,7 +318,7 @@ GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm ) object->indexMemUsage++; \ } - for( i=0; i < dm->getNumFaces(dm); i++ ) { + for( i=0; i < numfaces; i++ ) { int curInd = index[redir[mface[i].mat_nr+16383]]; object->faceRemap[curInd] = i; ADDLINK( mface[i].v1, curInd*3 ); @@ -461,7 +466,7 @@ GPUBuffer *GPU_buffer_setup( DerivedMesh *dm, GPUDrawObject *object, int size, G void GPU_buffer_copy_vertex( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) { int start; - int i, j; + int i, j, numfaces; MVert *mvert; MFace *mface; @@ -471,7 +476,8 @@ void GPU_buffer_copy_vertex( DerivedMesh *dm, float *varray, int *index, int *re mvert = dm->getVertArray(dm); mface = dm->getFaceArray(dm); - for( i=0; i < dm->getNumFaces(dm); i++ ) { + numfaces= dm->getNumFaces(dm); + for( i=0; i < numfaces; i++ ) { start = index[redir[mface[i].mat_nr+16383]]; if( mface[i].v4 ) index[redir[mface[i].mat_nr+16383]] += 18; @@ -508,7 +514,7 @@ GPUBuffer *GPU_buffer_vertex( DerivedMesh *dm ) void GPU_buffer_copy_normal( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) { - int i; + int i, numfaces; int start; float norm[3]; @@ -518,7 +524,8 @@ void GPU_buffer_copy_normal( DerivedMesh *dm, float *varray, int *index, int *re DEBUG_VBO("GPU_buffer_copy_normal\n"); - for( i=0; i < dm->getNumFaces(dm); i++ ) { + numfaces= dm->getNumFaces(dm); + for( i=0; i < numfaces; i++ ) { start = index[redir[mface[i].mat_nr+16383]]; if( mface[i].v4 ) index[redir[mface[i].mat_nr+16383]] += 18; @@ -572,7 +579,7 @@ GPUBuffer *GPU_buffer_normal( DerivedMesh *dm ) void GPU_buffer_copy_uv( DerivedMesh *dm, float *varray, int *index, int *redir, void *user ) { int start; - int i; + int i, numfaces; MTFace *mtface; MFace *mface; @@ -587,7 +594,8 @@ void GPU_buffer_copy_uv( DerivedMesh *dm, float *varray, int *index, int *redir, return; } - for( i=0; i < dm->getNumFaces(dm); i++ ) { + numfaces= dm->getNumFaces(dm); + for( i=0; i < numfaces; i++ ) { start = index[redir[mface[i].mat_nr+16383]]; if( mface[i].v4 ) index[redir[mface[i].mat_nr+16383]] += 12; @@ -619,14 +627,15 @@ GPUBuffer *GPU_buffer_uv( DerivedMesh *dm ) void GPU_buffer_copy_color3( DerivedMesh *dm, float *varray_, int *index, int *redir, void *user ) { - int i; + int i, numfaces; unsigned char *varray = (unsigned char *)varray_; unsigned char *mcol = (unsigned char *)user; MFace *mface = dm->getFaceArray(dm); DEBUG_VBO("GPU_buffer_copy_color3\n"); - for( i=0; i < dm->getNumFaces(dm); i++ ) { + numfaces= dm->getNumFaces(dm); + for( i=0; i < numfaces; i++ ) { int start = index[redir[mface[i].mat_nr+16383]]; if( mface[i].v4 ) index[redir[mface[i].mat_nr+16383]] += 18; @@ -648,14 +657,15 @@ void GPU_buffer_copy_color3( DerivedMesh *dm, float *varray_, int *index, int *r void GPU_buffer_copy_color4( DerivedMesh *dm, float *varray_, int *index, int *redir, void *user ) { - int i; + int i, numfaces; unsigned char *varray = (unsigned char *)varray_; unsigned char *mcol = (unsigned char *)user; MFace *mface = dm->getFaceArray(dm); DEBUG_VBO("GPU_buffer_copy_color4\n"); - for( i=0; i < dm->getNumFaces(dm); i++ ) { + numfaces= dm->getNumFaces(dm); + for( i=0; i < numfaces; i++ ) { int start = index[redir[mface[i].mat_nr+16383]]; if( mface[i].v4 ) index[redir[mface[i].mat_nr+16383]] += 18; @@ -678,7 +688,7 @@ void GPU_buffer_copy_color4( DerivedMesh *dm, float *varray_, int *index, int *r GPUBuffer *GPU_buffer_color( DerivedMesh *dm ) { unsigned char *colors; - int i; + int i, numfaces; MCol *mcol; GPUBuffer *result; DEBUG_VBO("GPU_buffer_color\n"); @@ -694,8 +704,9 @@ GPUBuffer *GPU_buffer_color( DerivedMesh *dm ) dm->drawObject->colType = CD_MCOL; } - colors = MEM_mallocN(dm->getNumFaces(dm)*12*sizeof(unsigned char), "GPU_buffer_color"); - for( i=0; i < dm->getNumFaces(dm)*4; i++ ) { + numfaces= dm->getNumFaces(dm); + colors = MEM_mallocN(numfaces*12*sizeof(unsigned char), "GPU_buffer_color"); + for( i=0; i < numfaces*4; i++ ) { colors[i*3] = mcol[i].b; colors[i*3+1] = mcol[i].g; colors[i*3+2] = mcol[i].r; @@ -714,13 +725,15 @@ void GPU_buffer_copy_edge( DerivedMesh *dm, float *varray, int *index, int *redi MVert *mvert; MEdge *medge; unsigned int *varray_ = (unsigned int *)varray; + int numedges; DEBUG_VBO("GPU_buffer_copy_edge\n"); mvert = dm->getVertArray(dm); medge = dm->getEdgeArray(dm); - for(i = 0; i < dm->getNumEdges(dm); i++) { + numedges= dm->getNumEdges(dm); + for(i = 0; i < numedges; i++) { varray_[i*2] = (unsigned int)dm->drawObject->indices[medge[i].v1].element; varray_[i*2+1] = (unsigned int)dm->drawObject->indices[medge[i].v2].element; } @@ -933,7 +946,7 @@ void GPU_uvedge_setup( DerivedMesh *dm ) void GPU_interleaved_setup( GPUBuffer *buffer, int data[] ) { int i; int elementsize = 0; - int offset = 0; + intptr_t offset = 0; DEBUG_VBO("GPU_interleaved_setup\n"); @@ -1068,7 +1081,7 @@ int GPU_attrib_element_size( GPUAttrib data[], int numdata ) { void GPU_interleaved_attrib_setup( GPUBuffer *buffer, GPUAttrib data[], int numdata ) { int i; int elementsize; - int offset = 0; + intptr_t offset = 0; DEBUG_VBO("GPU_interleaved_attrib_setup\n"); @@ -1245,4 +1258,4 @@ void GPU_buffer_draw_elements( GPUBuffer *elements, unsigned int mode, int start else { glDrawElements( mode, count, GL_UNSIGNED_INT, ((int *)elements->pointer)+start ); } -} \ No newline at end of file +} -- cgit v1.2.3 From 2072e7c6c7be0502961247deee21e69f9a8fa383 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 5 Oct 2009 17:29:56 +0000 Subject: VBO: * Disable use of EditMeshDerivedMesh for VBO drawing in editmode. This is crashed when using e.g. subsurf in editmode, as the DM is not an EditMeshDerivedMesh. --- source/blender/editors/space_view3d/drawobject.c | 29 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 0659b5cfd11..79412480d95 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1552,6 +1552,12 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float * } } } + +/* disabled because it crashes combined with e.g. subsurf modifier, + * the derivedmesh can't be assumed to be an EditMeshDerivedMesh, + * nor should this struct be copied around, it should be defined in + * a single place only to avoid them getting out of sync */ +#if 0 /* originally defined in DerivedMesh.c */ typedef struct { DerivedMesh dm; @@ -1561,15 +1567,17 @@ typedef struct { float (*vertexNos)[3]; float (*faceNos)[3]; } EditMeshDerivedMesh; +#endif static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act) { struct { int sel; EditVert *eve_act; } data; - GPUBuffer *buffer; - float *varray; + //GPUBuffer *buffer; + //float *varray; data.sel = sel; data.eve_act = eve_act; +#if 0 /* first come the unselected vertices, then the selected */ buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 ); @@ -1612,12 +1620,15 @@ static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act) UI_ThemeColor4(data.sel?TH_VERTEX_SELECT:TH_VERTEX); GPU_buffer_unbind(); } - else { + { +#endif bglBegin(GL_POINTS); dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); bglEnd(); +#if 0 } GPU_buffer_free( buffer, 0 ); +#endif } /* Draw edges with color set based on selection */ @@ -1688,15 +1699,14 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) { - unsigned char *cols[2]; + unsigned char *cols[2] = {baseCol, selCol}; +#if 0 int elemsize = sizeof(float)*3+sizeof(unsigned char)*4; EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm; EditMesh *em= emdm->em; unsigned char *varray; int i; GPUBuffer *buffer; - cols[0] = baseCol; - cols[1] = selCol; buffer = GPU_buffer_legacy(dm)?0:GPU_buffer_alloc( elemsize*em->totedge*2, 0 ); if( (varray = GPU_buffer_lock_stream( buffer )) ) { @@ -1733,9 +1743,12 @@ static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, un GPU_buffer_unbind(); } else { +#endif dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); +#if 0 } GPU_buffer_free( buffer, 0 ); +#endif } /* Draw only seam edges */ @@ -1792,11 +1805,10 @@ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned //EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm; EditFace *efa; unsigned char *col; - unsigned char *colors; GPUBuffer *buffer; unsigned char *varray; unsigned char black[] = { 0, 0, 0, 0 }; - int i,j,draw=0; + int i, draw=0; int elemsize = (sizeof(float)*6+sizeof(unsigned char)*4); data.cols[0] = baseCol; data.cols[1] = selCol; @@ -4039,7 +4051,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glLineWidth(1.0f); } else if(ELEM(draw_as, 0, PART_DRAW_CIRC)==0){ - int point_size = 1; glDisableClientState(GL_COLOR_ARRAY); /* enable point data array */ -- cgit v1.2.3 From a0d8d7afe08426dbc0eba72306bc5db3f5c65e47 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Oct 2009 19:42:48 +0000 Subject: edge loop delete, should be a c macro but they cant do settings atm --- release/scripts/modules/bpy_ops.py | 17 +++++++++++++++++ source/blender/editors/mesh/editmesh_tools.c | 6 +++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py index 83c2e82bf6c..834a33d305d 100644 --- a/release/scripts/modules/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py @@ -139,3 +139,20 @@ class bpy_ops_submodule_op(object): import bpy bpy.ops = bpy_ops() + +# TODO, C macro's cant define settings :| + +class MESH_OT_delete_edgeloop(bpy.types.Operator): + '''Export a single object as a stanford PLY with normals, colours and texture coordinates.''' + __idname__ = "mesh.delete_edgeloop" + __label__ = "Export PLY" + + def execute(self, context): + bpy.ops.tfm.edge_slide(value=1.0) + bpy.ops.mesh.select_more() + bpy.ops.mesh.remove_doubles() + return ('FINISHED',) + + +bpy.ops.add(MESH_OT_delete_edgeloop) + diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 510f6ab464b..88d08efe95e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1305,8 +1305,12 @@ static int delete_mesh_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + int type= RNA_enum_get(op->ptr, "type"); - delete_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type")); + if(type==6) + return WM_operator_name_call(C, "MESH_OT_delete_edgeloop", WM_OP_EXEC_DEFAULT, NULL); + + delete_mesh(obedit, em, op, type); DAG_id_flush_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); -- cgit v1.2.3 From 4e60007102c1a9cf8dad068e1d4b8ab6e46ca89b Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 5 Oct 2009 20:30:47 +0000 Subject: [#19542] Correct spacing with snapping buttons in 3d view header. --- source/blender/editors/space_view3d/view3d_header.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 19c48bb5006..0d19a720cdb 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -2145,9 +2145,9 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) xco+= XIC; } uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); - xco+= XIC; + xco+= XIC + 10; uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode"); - xco+= XIC; + xco+= 70; } else { uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)"); xco+= XIC; -- cgit v1.2.3 From 1f0ee67579f39343fbc8f5be7a74a7cf25d33a92 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 5 Oct 2009 20:31:41 +0000 Subject: [#19535] Save back proportional editing size to toolsettings after transform. --- source/blender/editors/transform/transform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 84e42294946..b109157d859 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1326,6 +1326,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) if ((t->options & CTX_NO_PET) == 0) { ts->proportional = proportional; + ts->proportional_size = t->prop_size; } if(t->spacetype == SPACE_VIEW3D) -- cgit v1.2.3 From 69a24325742c617a9902376b061006dfb24f0a3c Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Mon, 5 Oct 2009 23:04:40 +0000 Subject: Small fix for some old files crashing in particle drawing. --- source/blender/editors/space_view3d/drawobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 79412480d95..1bad1b3215c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3788,7 +3788,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv psys->lattice= psys_get_lattice(&sim); - if(draw_as!=PART_DRAW_PATH){ + if(pdd && draw_as!=PART_DRAW_PATH){ /* 5. */ if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED) && (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) { @@ -4050,7 +4050,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glLineWidth(1.0f); } - else if(ELEM(draw_as, 0, PART_DRAW_CIRC)==0){ + else if(pdd && ELEM(draw_as, 0, PART_DRAW_CIRC)==0){ glDisableClientState(GL_COLOR_ARRAY); /* enable point data array */ -- cgit v1.2.3 From a62e37bfbe5a1430b204b39dcc2e1156d2a6f2bc Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Mon, 5 Oct 2009 23:30:00 +0000 Subject: blibvh safe for 64bits --- .../render/intern/source/rayobject_blibvh.c | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/source/blender/render/intern/source/rayobject_blibvh.c b/source/blender/render/intern/source/rayobject_blibvh.c index 487193ef1f2..3fd71862f54 100644 --- a/source/blender/render/intern/source/rayobject_blibvh.c +++ b/source/blender/render/intern/source/rayobject_blibvh.c @@ -67,6 +67,7 @@ static RayObjectAPI bvh_api = typedef struct BVHObject { RayObject rayobj; + RayObject **leafs, **next_leaf; BVHTree *bvh; float bb[2][3]; @@ -80,15 +81,23 @@ RayObject *RE_rayobject_blibvh_create(int size) obj->rayobj.api = &bvh_api; obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6); + obj->next_leaf = obj->leafs = (RayObject**)MEM_callocN(size*sizeof(RayObject*), "BVHObject leafs"); INIT_MINMAX(obj->bb[0], obj->bb[1]); return RE_rayobject_unalignRayAPI((RayObject*) obj); } +struct BVHCallbackUserData +{ + Isect *isec; + RayObject **leafs; +}; + static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - Isect *isec = (Isect*)userdata; - RayObject *face = (RayObject*)index; + struct BVHCallbackUserData *data = (struct BVHCallbackUserData*)userdata; + Isect *isec = data->isec; + RayObject *face = data->leafs[index]; if(RE_rayobject_intersect(face,isec)) { @@ -106,6 +115,9 @@ static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec) BVHObject *obj = (BVHObject*)o; BVHTreeRayHit hit; float dir[3]; + struct BVHCallbackUserData data; + data.isec = isec; + data.leafs = obj->leafs; VECCOPY(dir, isec->vec); Normalize(dir); @@ -113,7 +125,7 @@ static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec) hit.index = 0; hit.dist = isec->labda*isec->dist; - return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, isec); + return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, (void*)&data); } static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob) @@ -126,7 +138,8 @@ static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob) DO_MIN(min_max , obj->bb[0]); DO_MAX(min_max+3, obj->bb[1]); - BLI_bvhtree_insert(obj->bvh, (int)ob, min_max, 2 ); + BLI_bvhtree_insert(obj->bvh, obj->next_leaf - obj->leafs, min_max, 2 ); + *(obj->next_leaf++) = ob; } static void RE_rayobject_blibvh_done(RayObject *o) @@ -142,6 +155,9 @@ static void RE_rayobject_blibvh_free(RayObject *o) if(obj->bvh) BLI_bvhtree_free(obj->bvh); + if(obj->leafs) + MEM_freeN(obj->leafs); + MEM_freeN(obj); } -- cgit v1.2.3 From 11bdf6ea10ee7bc5e2862cdddbf42eddb06c42fa Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 6 Oct 2009 00:28:07 +0000 Subject: Added #ifdef __SSE__ so it can still build when SSE is disabled at compile time --- source/blender/render/intern/raytrace/bvh.h | 7 +++++++ .../render/intern/raytrace/rayobject_qbvh.cpp | 13 +++++++++++++ .../render/intern/raytrace/rayobject_svbvh.cpp | 11 +++++++++++ source/blender/render/intern/raytrace/svbvh.h | 4 ++++ source/blender/render/intern/source/rayshade.c | 22 ++++++++++++++++++---- 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index f0302ddba3a..0e74bbc923b 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -33,11 +33,15 @@ #include "rayobject_hint.h" #include + +#ifdef __SSE__ #include +#endif #ifndef RE_RAYTRACE_BVH_H #define RE_RAYTRACE_BVH_H +#ifdef __SSE__ inline int test_bb_group4(__m128 *bb_group, const Isect *isec) { @@ -53,6 +57,7 @@ inline int test_bb_group4(__m128 *bb_group, const Isect *isec) return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3)); } +#endif /* bvh tree generics */ @@ -159,6 +164,7 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec) } +#ifdef __SSE__ /* * Generic SIMD bvh recursion * this was created to be able to use any simd (with the cost of some memmoves) @@ -287,6 +293,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec) } return hit; } +#endif /* * recursively transverse a BVH looking for a rayhit using system stack diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index b18ee0824cf..8d35848c9ec 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -30,6 +30,8 @@ #include "svbvh.h" #include "reorganize.h" +#ifdef __SSE__ + #define DFS_STACK_SIZE 256 struct QBVHTree @@ -134,3 +136,14 @@ RayObject *RE_rayobject_qbvh_create(int size) { return bvh_create_tree(size); } + + +#else + +RayObject *RE_rayobject_qbvh_create(int size) +{ + puts("WARNING: SSE disabled at compile time\n"); + return NULL; +} + +#endif \ No newline at end of file diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp index 229e82dfa68..a877b91e2ff 100644 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -30,6 +30,8 @@ #include "svbvh.h" #include "reorganize.h" +#ifdef __SSE__ + #define DFS_STACK_SIZE 256 struct SVBVHTree @@ -168,3 +170,12 @@ RayObject *RE_rayobject_svbvh_create(int size) { return bvh_create_tree(size); } +#else + +RayObject *RE_rayobject_svbvh_create(int size) +{ + puts("WARNING: SSE disabled at compile time\n"); + return NULL; +} + +#endif diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 840ccc24d1a..3c733b6b402 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -26,6 +26,8 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#ifdef __SSE__ + #ifndef RE_RAYTRACE_SVBVH_H #define RE_RAYTRACE_SVBVH_H @@ -243,3 +245,5 @@ struct Reorganize_SVBVH }; #endif + +#endif //__SSE__ \ No newline at end of file diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 9ef8aa3aba2..7f112f2e79c 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -78,7 +78,7 @@ static int test_break(void *data) return re->test_break(re->tbh); } -static RE_rayobject_config_control(RayObject *r, Render *re) +static void RE_rayobject_config_control(RayObject *r, Render *re) { if(RE_rayobject_isRayAPI(r)) { @@ -96,10 +96,21 @@ RayObject* RE_rayobject_create(Render *re, int type, int size) { //TODO //if(detect_simd()) - type = R_RAYSTRUCTURE_SIMD_SVBVH; - //else - // type = R_RAYSTRUCTURE_VBVH; +#ifdef __SSE__ + type = R_RAYSTRUCTURE_SIMD_SVBVH; +#else + type = R_RAYSTRUCTURE_VBVH; +#endif + } + +#ifndef __SSE__ + if(type == R_RAYSTRUCTURE_SIMD_SVBVH || type == R_RAYSTRUCTURE_SIMD_QBVH) + { + puts("Warning: Using VBVH (SSE was disabled at compile time)"); + type = R_RAYSTRUCTURE_VBVH; } +#endif + if(type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres res = RE_rayobject_octree_create(re->r.ocres, size); @@ -111,6 +122,9 @@ RayObject* RE_rayobject_create(Render *re, int type, int size) res = RE_rayobject_svbvh_create(size); else if(type == R_RAYSTRUCTURE_SIMD_QBVH) res = RE_rayobject_qbvh_create(size); + else + res = RE_rayobject_vbvh_create(size); //Fallback + if(res) RE_rayobject_config_control( res, re ); -- cgit v1.2.3 From d28d3194f4460a28f5ea83246725193d6c18cec8 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 6 Oct 2009 02:45:42 +0000 Subject: * Added 'set object as camera' operator 3D View: View -> Cameras -> Set Object as Camera (Ctrl Numpad 0) --- .../blender/editors/space_view3d/view3d_intern.h | 1 + source/blender/editors/space_view3d/view3d_ops.c | 2 ++ source/blender/editors/space_view3d/view3d_view.c | 32 ++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index e7ab79ab955..d80cec9ad48 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -122,6 +122,7 @@ void VIEW3D_OT_select_lasso(struct wmOperatorType *ot); /* view3d_view.c */ void VIEW3D_OT_smoothview(struct wmOperatorType *ot); void VIEW3D_OT_setcameratoview(struct wmOperatorType *ot); +void VIEW3D_OT_setobjectascamera(struct wmOperatorType *ot); void VIEW3D_OT_localview(struct wmOperatorType *ot); void VIEW3D_OT_game_start(struct wmOperatorType *ot); void VIEW3D_OT_fly(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index f9cedbd28a1..a151ff3e73a 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -82,6 +82,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_cursor3d); WM_operatortype_append(VIEW3D_OT_select_lasso); WM_operatortype_append(VIEW3D_OT_setcameratoview); + WM_operatortype_append(VIEW3D_OT_setobjectascamera); WM_operatortype_append(VIEW3D_OT_drawtype); WM_operatortype_append(VIEW3D_OT_localview); WM_operatortype_append(VIEW3D_OT_game_start); @@ -216,6 +217,7 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index f722a97963d..fc332cf6293 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -434,6 +434,38 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + Scene *scene= CTX_data_scene(C); + + if(BASACT) { + rv3d->persp= V3D_CAMOB; + v3d->camera= OBACT; + smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_setobjectascamera(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Set Active Object as Camera"; + ot->description= "Set the active object as the active camera for this view or scene."; + ot->idname= "VIEW3D_OT_object_as_camera"; + + /* api callbacks */ + ot->exec= view3d_setobjectascamera_exec; + ot->poll= ED_operator_view3d_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} /* ********************************** */ /* create intersection coordinates in view Z direction at mouse coordinates */ -- cgit v1.2.3 From 3fe274b072df205614da150df9c3743f2b1b422a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 6 Oct 2009 03:05:20 +0000 Subject: Several fixes: * Code for generating 'Object' summary of Keyframes for DopeSheet (which is also used by the TimeLine for getting keyframes to draw) now considers materials, object data, and particles too. * Rearranged the way that keyframing-related settings were presented in the User Preferences. The way the settings were grouped was plain confusing, and based on biased views from the old system. For the record, 'needed'+'visual' are always considered when inserting keyframes, 'always' is for autokeyframing, and default interpolation is only used for newly created F-Curves. * Fixed bug #19472 - Scroll wheel scrolls in the wrong direction for enum-menus that were flipped (i.e. window type menu and 3d-view mode selector). --- release/scripts/ui/space_userpref.py | 11 +-- source/blender/editors/animation/keyframes_draw.c | 100 ++++++++++++++++---- source/blender/editors/animation/keyframes_edit.c | 103 ++++++++++++++++++++- .../blender/editors/interface/interface_handlers.c | 24 ++--- source/blender/editors/space_graph/graph_edit.c | 6 +- 5 files changed, 195 insertions(+), 49 deletions(-) diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index a9126d2c7f1..15e6c7ee4be 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -199,14 +199,13 @@ class USERPREF_PT_edit(bpy.types.Panel): sub1 = sub.column() sub1.itemL(text="Keyframing:") sub1.itemR(edit, "use_visual_keying") - sub1.itemR(edit, "new_interpolation_type", text="New F-Curves") + sub1.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available") + sub1.itemR(edit, "auto_keyframe_insert_needed", text="Only Insert Needed") + sub1.itemS() + sub1.itemL(text="New F-Curve Defaults:") + sub1.itemR(edit, "new_interpolation_type", text="Interpolation") sub1.itemS() sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing") - sub2 = sub1.column() - sub2.enabled = edit.auto_keying_enable - sub2.row().itemR(edit, "auto_keying_mode", expand=True) - sub2.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available") - sub2.itemR(edit, "auto_keyframe_insert_needed", text="Only Insert Needed") sub1.itemS() sub1.itemS() diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index e8b25f70b06..d0b5e12c9df 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -54,10 +54,11 @@ #include "DNA_screen_types.h" #include "DNA_scene_types.h" #include "DNA_space_types.h" -#include "DNA_constraint_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" #include "DNA_userdef_types.h" #include "DNA_gpencil_types.h" #include "DNA_windowmanager_types.h" @@ -656,25 +657,90 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *blocks) { Key *key= ob_get_key(ob); - - if (ob) { - int filterflag; - - /* get filterflag */ - if (ads) - filterflag= ads->filterflag; - else - filterflag= 0; + int filterflag= (ads)? ads->filterflag : 0; + + /* sanity check */ + if (ob == NULL) + return; - /* Add action keyframes */ - if (ob->adt && ob->adt->action) - action_to_keylist(ob->adt, ob->adt->action, keys, blocks); + /* Add action keyframes */ + if (ob->adt && ob->adt->action) + action_to_keylist(ob->adt, ob->adt->action, keys, blocks); + + /* Add shapekey keyframes (only if dopesheet allows, if it is available) */ + if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) + action_to_keylist(key->adt, key->adt->action, keys, blocks); + + /* Add material keyframes */ + if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) { + int a; - /* Add shapekey keyframes (only if dopesheet allows, if it is available) */ - if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) - action_to_keylist(key->adt, key->adt->action, keys, blocks); + for (a=0; a < ob->totcol; a++) { + Material *ma= give_current_material(ob, a); + + /* there might not be a material */ + if (ELEM(NULL, ma, ma->adt)) + continue; + + /* add material's data */ + action_to_keylist(ma->adt, ma->adt->action, keys, blocks); + } + } + + /* Add object data keyframes */ + switch (ob->type) { + case OB_CAMERA: /* ------- Camera ------------ */ + { + Camera *ca= (Camera *)ob->data; - // TODO: restore materials, and object data, etc. + if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) + action_to_keylist(ca->adt, ca->adt->action, keys, blocks); + } + break; + case OB_LAMP: /* ---------- Lamp ----------- */ + { + Lamp *la= (Lamp *)ob->data; + + if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) + action_to_keylist(la->adt, la->adt->action, keys, blocks); + } + break; + case OB_CURVE: /* ------- Curve ---------- */ + { + Curve *cu= (Curve *)ob->data; + + if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) + action_to_keylist(cu->adt, cu->adt->action, keys, blocks); + } + break; + case OB_MBALL: /* ------- MetaBall ---------- */ + { + MetaBall *mb= (MetaBall *)ob->data; + + if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) + action_to_keylist(mb->adt, mb->adt->action, keys, blocks); + } + break; + case OB_ARMATURE: /* ------- Armature ---------- */ + { + bArmature *arm= (bArmature *)ob->data; + + if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) + action_to_keylist(arm->adt, arm->adt->action, keys, blocks); + } + break; + } + + /* Add Particle System Keyframes */ + if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) { + ParticleSystem *psys = ob->particlesystem.first; + + for(; psys; psys=psys->next) { + if (ELEM(NULL, psys->part, psys->part->adt)) + continue; + else + action_to_keylist(psys->part->adt, psys->part->adt->action, keys, blocks); + } } } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 65f7d845b29..7f0d3b4503d 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -36,9 +36,15 @@ #include "DNA_anim_types.h" #include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_world_types.h" @@ -46,6 +52,7 @@ #include "BKE_action.h" #include "BKE_fcurve.h" #include "BKE_key.h" +#include "BKE_material.h" #include "BKE_utildefines.h" #include "ED_anim_api.h" @@ -195,14 +202,100 @@ static short ob_keys_bezier_loop(BeztEditData *bed, Object *ob, BeztEditFunc bez return 0; /* firstly, Object's own AnimData */ - if (ob->adt) - adt_keys_bezier_loop(bed, ob->adt, bezt_ok, bezt_cb, fcu_cb, filterflag); + if (ob->adt) { + if (adt_keys_bezier_loop(bed, ob->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } /* shapekeys */ - if ((key && key->adt) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) - adt_keys_bezier_loop(bed, key->adt, bezt_ok, bezt_cb, fcu_cb, filterflag); + if ((key && key->adt) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) { + if (adt_keys_bezier_loop(bed, key->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + + /* Add material keyframes */ + if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) { + int a; - // FIXME: add materials, etc. (but drawing code doesn't do it yet too! :) + for (a=0; a < ob->totcol; a++) { + Material *ma= give_current_material(ob, a); + + /* there might not be a material */ + if (ELEM(NULL, ma, ma->adt)) + continue; + + /* add material's data */ + if (adt_keys_bezier_loop(bed, ma->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } + + /* Add object data keyframes */ + switch (ob->type) { + case OB_CAMERA: /* ------- Camera ------------ */ + { + Camera *ca= (Camera *)ob->data; + + if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) { + if (adt_keys_bezier_loop(bed, ca->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } + break; + case OB_LAMP: /* ---------- Lamp ----------- */ + { + Lamp *la= (Lamp *)ob->data; + + if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) { + if (adt_keys_bezier_loop(bed, la->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } + break; + case OB_CURVE: /* ------- Curve ---------- */ + { + Curve *cu= (Curve *)ob->data; + + if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) { + if (adt_keys_bezier_loop(bed, cu->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } + break; + case OB_MBALL: /* ------- MetaBall ---------- */ + { + MetaBall *mb= (MetaBall *)ob->data; + + if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) { + if (adt_keys_bezier_loop(bed, mb->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } + break; + case OB_ARMATURE: /* ------- Armature ---------- */ + { + bArmature *arm= (bArmature *)ob->data; + + if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) { + if (adt_keys_bezier_loop(bed, arm->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } + break; + } + + /* Add Particle System Keyframes */ + if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) { + ParticleSystem *psys = ob->particlesystem.first; + + for(; psys; psys=psys->next) { + if (ELEM(NULL, psys->part, psys->part->adt)) + continue; + + if (adt_keys_bezier_loop(bed, psys->part->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } + } return 0; } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c60c94a9c4d..bbf8df00b88 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4230,28 +4230,20 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, if(event->val==KM_PRESS) { but= ui_but_find_activated(ar); if(but) { - if(ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) { - if(block->direction & UI_TOP) but= ui_but_prev(but); - else but= ui_but_next(but); - } - else { - if(block->direction & UI_TOP) but= ui_but_next(but); - else but= ui_but_prev(but); - } + if(ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) + but= ui_but_next(but); + else + but= ui_but_prev(but); if(but) ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE); } if(!but) { - if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) { - if(block->direction & UI_TOP) bt= ui_but_first(block); - else bt= ui_but_last(block); - } - else { - if(block->direction & UI_TOP) bt= ui_but_last(block); - else bt= ui_but_first(block); - } + if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) + bt= ui_but_last(block); + else + bt= ui_but_first(block); if(bt) ui_handle_button_activate(C, ar, bt, BUTTON_ACTIVATE); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 3e0f9760773..22272479e4a 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1332,12 +1332,8 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op) * - only rotation curves * - for pchan curves, make sure we're only using the euler curves */ - if (ELEM(0, fcu->rna_path, strstr(fcu->rna_path, "rotation"))) + if (strstr(fcu->rna_path, "rotation_euler") == 0) continue; - if (strstr(fcu->rna_path, "pose.pose_channels")) { - if (strstr(fcu->rna_path, "rotation_euler") == 0) - continue; - } /* check if current set of 3-curves is suitable to add this curve to * - things like whether the current set of curves is 'full' should be checked later only -- cgit v1.2.3 From 1c940d7677ceca15976b69b8bab1aede6ad6d4aa Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 6 Oct 2009 03:40:50 +0000 Subject: Attempts at some compile fixes for jaguarandi's code: * mingw almost compiles again cleanly, except for a linking error when linking blender http://www.pasteall.org/8297 * win64 should compile again too to a similar degree? * silenced warnings about no newlines... --- source/blender/render/intern/include/rayobject.h | 6 +++--- source/blender/render/intern/raytrace/rayobject_qbvh.cpp | 2 +- source/blender/render/intern/raytrace/svbvh.h | 2 +- source/blender/render/intern/raytrace/vbvh.h | 2 +- source/blender/render/intern/source/rayshade.c | 1 + 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 9e35c0feac5..5579f3896c1 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -35,6 +35,7 @@ extern "C" { #include "RE_raytrace.h" #include "render_types.h" +#include #include @@ -174,11 +175,10 @@ int RE_rayobjectcontrol_test_break(RayObjectControl *c); -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(_WIN64) #include #include -#include #define BENCH(a,name) \ do { \ @@ -194,7 +194,7 @@ int RE_rayobjectcontrol_test_break(RayObjectControl *c); } while(0) #else -#define BENCH(a) (a) +#define BENCH(a,name) (a) #endif diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index 8d35848c9ec..2719675e3b8 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -146,4 +146,4 @@ RayObject *RE_rayobject_qbvh_create(int size) return NULL; } -#endif \ No newline at end of file +#endif diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 3c733b6b402..5837d51d3d4 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -246,4 +246,4 @@ struct Reorganize_SVBVH #endif -#endif //__SSE__ \ No newline at end of file +#endif //__SSE__ diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h index 1ff51786e52..7d3dbffd125 100644 --- a/source/blender/render/intern/raytrace/vbvh.h +++ b/source/blender/render/intern/raytrace/vbvh.h @@ -234,4 +234,4 @@ struct Reorganize_VBVH return node; } }; -*/ \ No newline at end of file +*/ diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index f2d61e01f50..08d1785446f 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -25,6 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include #include #include #include -- cgit v1.2.3 From 2936d791a2383d1f1026a5cf3d0572d5a4768c44 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 6 Oct 2009 04:37:01 +0000 Subject: * missed this in last commit --- release/scripts/ui/space_view3d.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index a270e053126..5827739aa53 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -156,6 +156,8 @@ class VIEW3D_MT_view_cameras(bpy.types.Menu): def draw(self, context): layout = self.layout + + layout.itemO("view3d.object_as_camera") # ********** Select menus, suffix from context.mode ********** -- cgit v1.2.3 From 58557ea737713dc654f4f313530b1acf920763c6 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 6 Oct 2009 04:37:25 +0000 Subject: * Cmake fix for raytrace accel, still not 100% but getting there... --- source/blender/render/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 29539fa4d17..279ba7698b7 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -24,7 +24,7 @@ # # ***** END GPL LICENSE BLOCK ***** -FILE(GLOB SRC intern/source/*.c) +FILE(GLOB SRC intern/source/*.c intern/raytrace/*.cpp) SET(INC intern/include ../../../intern/guardedalloc ../blenlib ../makesdna -- cgit v1.2.3 From c93127d06fd7fc0219ec103bfab94b11cc13f9e0 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 6 Oct 2009 10:23:25 +0000 Subject: Some more compile fixes for jaguarandi's commit, this time for msvc+scons * Replaced ... = {}; with ... = {0}; * Solved problem with logf(), where msvc couldn't figure out which version of log() to call (solved by casting the int argument to a float, but could also have been to double)... * The cflags and cxxflags for scons when compiling the rendering module were only valid for gcc compiles. These will still need to get added for msvc sometime, but for now, there are no more warnings about unknown options... --- source/blender/render/SConscript | 10 ++++++++-- source/blender/render/intern/raytrace/rayobject_rtbuild.cpp | 4 ++-- source/blender/render/intern/source/rayshade.c | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 88942ced027..17c20e8807a 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,8 +1,14 @@ #!/usr/bin/python Import ('env') -cflags = ['-O2','-msse2','-mfpmath=sse'] -cxxflags = ['-O2','-msse2','-mfpmath=sse'] +if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + # FIXME: need to set the appropriate flags for msvc, otherwise we get warnings + cflags = [] + cxxflags = [] +else: + cflags = ['-O2','-msse2','-mfpmath=sse'] + cxxflags = ['-O2','-msse2','-mfpmath=sse'] + sources = env.Glob('intern/source/*.c') raysources = env.Glob('intern/raytrace/*.cpp') diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 9523e725893..a16499d4f91 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -362,8 +362,8 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) //Worst case heuristic (cost of each child is linear) float hcost, left_side, right_side; - left_side = bb_area(sweep_left.bb, sweep_left.bb+3)*(sweep_left.cost+logf(i)); - right_side= bb_area(sweep[i].bb, sweep[i].bb+3)*(sweep[i].cost+logf(size-i)); + left_side = bb_area(sweep_left.bb, sweep_left.bb+3)*(sweep_left.cost+logf((float)i)); + right_side= bb_area(sweep[i].bb, sweep[i].bb+3)*(sweep[i].cost+logf((float)size-i)); hcost = left_side+right_side; assert(left_side >= 0); diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 08d1785446f..8c0920a93fa 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -134,7 +134,7 @@ RayObject* RE_rayobject_create(Render *re, int type, int size) } #ifdef RE_RAYCOUNTER -RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {}; +RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {0}; #endif @@ -180,7 +180,7 @@ void freeraytree(Render *re) #ifdef RE_RAYCOUNTER { - RayCounter sum = {}; + RayCounter sum = {0}; int i; for(i=0; i Date: Tue, 6 Oct 2009 10:32:07 +0000 Subject: One last try - this should fix the remaining issues: * Made bvh_node_merge() in svbvh.h static (fix suggested by jaguarandi). This makes mingw link again. * Also, patched my previous fix for ... = {}; since mingw didn't like the other fix (which was for msvc). --- source/blender/render/intern/raytrace/svbvh.h | 2 +- source/blender/render/intern/source/rayshade.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 5837d51d3d4..0303740ee9d 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -76,7 +76,7 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN } template<> -void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) +static void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) { if(is_leaf(node)) { diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 8c0920a93fa..7886e237c97 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -134,7 +134,7 @@ RayObject* RE_rayobject_create(Render *re, int type, int size) } #ifdef RE_RAYCOUNTER -RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {0}; +RayCounter re_rc_counter[BLENDER_MAX_THREADS]; #endif @@ -180,7 +180,7 @@ void freeraytree(Render *re) #ifdef RE_RAYCOUNTER { - RayCounter sum = {0}; + RayCounter sum; int i; for(i=0; i Date: Tue, 6 Oct 2009 10:52:14 +0000 Subject: *Added memset's to make sure counters start on zero *Disabled ray counter (can be enabled on render/extern/include/RE_raytrace.h by commenting out the define) *marked bvh_node_merge() as static inline (hopping it now compiles on gcc and mingw) --- source/blender/render/extern/include/RE_raytrace.h | 2 +- source/blender/render/intern/raytrace/bvh.h | 2 +- source/blender/render/intern/raytrace/svbvh.h | 2 +- source/blender/render/intern/source/rayshade.c | 7 +++++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 6a171a98f12..22d55bb1a91 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -35,7 +35,7 @@ extern "C" { #endif -#define RE_RAYCOUNTER /* enable counters per ray, usefull for measuring raytrace structures performance */ +// #define RE_RAYCOUNTER /* enable counters per ray, usefull for measuring raytrace structures performance */ #define RE_RAY_LCTS_MAX_SIZE 256 #define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */ diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h index 0e74bbc923b..ad7f44acb8d 100644 --- a/source/blender/render/intern/raytrace/bvh.h +++ b/source/blender/render/intern/raytrace/bvh.h @@ -112,7 +112,7 @@ template static inline int bvh_node_hit_test(Node *node, Isect *isec template -static void bvh_node_merge_bb(Node *node, float *min, float *max) +static inline void bvh_node_merge_bb(Node *node, float *min, float *max) { if(is_leaf(node)) { diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 0303740ee9d..5837d51d3d4 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -76,7 +76,7 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN } template<> -static void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) +void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) { if(is_leaf(node)) { diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 7886e237c97..881a549ad96 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -181,6 +181,7 @@ void freeraytree(Render *re) #ifdef RE_RAYCOUNTER { RayCounter sum; + memset( &sum, 0, sizeof(sum) ); int i; for(i=0; ii.infostr= "Raytree finished"; re->stats_draw(re->sdh, &re->i); } + +#ifdef RE_RAYCOUNTER + memset( re_rc_counter, 0, sizeof(re_rc_counter) ); +#endif } + + void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) { ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob; -- cgit v1.2.3 From c12cb02c56ef575720f468ed1de7dc065f153580 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 6 Oct 2009 11:21:57 +0000 Subject: sculpt was checking if multires was the last modifier, instead check if its the last displayed modifier --- source/blender/editors/sculpt_paint/sculpt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 01a2ff3fdee..982bd315b99 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1099,8 +1099,18 @@ static struct MultiresModifierData *sculpt_multires_active(Object *ob) ModifierData *md; for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) { - if(md->type == eModifierType_Multires && !md->next) { - MultiresModifierData *mmd = (MultiresModifierData*)md; + if(md->type == eModifierType_Multires) { + MultiresModifierData *mmd; + + /* Check if any of the modifiers after multires are active + * if not it can use the multires struct */ + ModifierData *md_next; + for (md_next= md->next; md_next; md_next= md_next->next) { + if(md_next->mode & eModifierMode_Realtime) + return NULL; + } + + mmd = (MultiresModifierData*)md; if(mmd->lvl != 1) return mmd; } -- cgit v1.2.3 From 22605ec759a564428b82a3de1053c0152e9d9374 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 6 Oct 2009 11:33:58 +0000 Subject: Bone Selections: Ability to set bones as unselectable In the Outliner, it is now possible to toggle per bone the selectability of the bone in the viewport, as for Objects using the restriction columns. This can also be set using the RNA-api. I've tested all commonly used tools IMO, but there may still be a few which I've missed. Please report those cases. PS. For some reason, the define was already there, but not connected up to anything. Can't remember why anymore, but here it is... --- source/blender/editors/armature/editarmature.c | 186 +++++++++++++---------- source/blender/editors/armature/poseobject.c | 10 +- source/blender/editors/object/object_select.c | 2 +- source/blender/editors/space_outliner/outliner.c | 12 +- source/blender/makesrna/intern/rna_armature.c | 5 + 5 files changed, 123 insertions(+), 92 deletions(-) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 402715dbb02..c32837be420 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -110,17 +110,20 @@ void ED_armature_sync_selection(ListBase *edbo) EditBone *ebo; for (ebo=edbo->first; ebo; ebo= ebo->next) { - if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) { - if (ebo->parent->flag & BONE_TIPSEL) - ebo->flag |= BONE_ROOTSEL; + /* if bone is not selectable, we shouldn't alter this setting... */ + if ((ebo->flag & BONE_UNSELECTABLE) == 0) { + if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) { + if (ebo->parent->flag & BONE_TIPSEL) + ebo->flag |= BONE_ROOTSEL; + else + ebo->flag &= ~BONE_ROOTSEL; + } + + if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL)) + ebo->flag |= BONE_SELECTED; else - ebo->flag &= ~BONE_ROOTSEL; + ebo->flag &= ~BONE_SELECTED; } - - if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL)) - ebo->flag |= BONE_SELECTED; - else - ebo->flag &= ~BONE_SELECTED; } } @@ -1127,7 +1130,7 @@ static void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int * /* no singular posemode, so check for correct object */ if(base->selcol == (hitresult & 0xFFFF)) { bone = get_indexed_bone(base->object, hitresult); - + if (findunsel) sel = (bone->flag & BONE_SELECTED); else @@ -1347,45 +1350,42 @@ void POSE_OT_flags_set (wmOperatorType *ot) /* **************** Posemode stuff ********************** */ -static void selectconnected_posebonechildren (Object *ob, Bone *bone) +static void selectconnected_posebonechildren (Object *ob, Bone *bone, int extend) { Bone *curBone; - int shift= 0; // XXX - if (!(bone->flag & BONE_CONNECTED)) + /* stop when unconnected child is encontered, or when unselectable bone is encountered */ + if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE)) return; // XXX old cruft! use notifiers instead //select_actionchannel_by_name (ob->action, bone->name, !(shift)); - if (shift) + if (extend) bone->flag &= ~BONE_SELECTED; else bone->flag |= BONE_SELECTED; - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - selectconnected_posebonechildren (ob, curBone); - } + for (curBone=bone->childbase.first; curBone; curBone=curBone->next) + selectconnected_posebonechildren(ob, curBone, extend); } /* within active object context */ /* previously known as "selectconnected_posearmature" */ static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event) { + ARegion *ar= CTX_wm_region(C); + Object *ob= CTX_data_edit_object(C); Bone *bone, *curBone, *next= NULL; - int shift= 0; // XXX in pose mode, Shift+L is bound to another command - // named "PoseLib Add Current Pose" + int extend= RNA_boolean_get(op->ptr, "extend"); int x, y; - ARegion *ar; - Object *ob= CTX_data_edit_object(C); - ar= CTX_wm_region(C); - + x= event->x - ar->winrct.xmin; y= event->y - ar->winrct.ymin; view3d_operator_needs_opengl(C); - if (shift) + if (extend) bone= get_nearest_bone(C, 0, x, y); else bone= get_nearest_bone(C, 1, x, y); @@ -1395,26 +1395,29 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *ev /* Select parents */ for (curBone=bone; curBone; curBone=next){ - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name (ob->action, curBone->name, !(shift)); - if (shift) - curBone->flag &= ~BONE_SELECTED; - else - curBone->flag |= BONE_SELECTED; - - if (curBone->flag & BONE_CONNECTED) - next=curBone->parent; + /* ignore bone if cannot be selected */ + if ((curBone->flag & BONE_UNSELECTABLE) == 0) { + // XXX old cruft! use notifiers instead + //select_actionchannel_by_name (ob->action, curBone->name, !(shift)); + + if (extend) + curBone->flag &= ~BONE_SELECTED; + else + curBone->flag |= BONE_SELECTED; + + if (curBone->flag & BONE_CONNECTED) + next=curBone->parent; + else + next=NULL; + } else - next=NULL; + next= NULL; } /* Select children */ - for (curBone=bone->childbase.first; curBone; curBone=next){ - selectconnected_posebonechildren (ob, curBone); - } + for (curBone=bone->childbase.first; curBone; curBone=next) + selectconnected_posebonechildren(ob, curBone, extend); - // XXX this only counted the number of pose channels selected - //countall(); // flushes selection! WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob); return OPERATOR_FINISHED; @@ -1435,6 +1438,7 @@ void POSE_OT_select_linked(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); } /* **************** END Posemode stuff ********************** */ @@ -1446,7 +1450,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e { bArmature *arm; EditBone *bone, *curBone, *next; - int shift= 0; // XXX + int extend= RNA_boolean_get(op->ptr, "extend"); int x, y; ARegion *ar; Object *obedit= CTX_data_edit_object(C); @@ -1458,7 +1462,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e view3d_operator_needs_opengl(C); - if (shift) + if (extend) bone= get_nearest_bone(C, 0, x, y); else bone= get_nearest_bone(C, 1, x, y); @@ -1467,14 +1471,16 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e return OPERATOR_CANCELLED; /* Select parents */ - for (curBone=bone; curBone; curBone=next){ - if (shift){ - curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - } - else{ - curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + for (curBone=bone; curBone; curBone=next) { + if ((curBone->flag & BONE_UNSELECTABLE) == 0) { + if (extend) { + curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } + else{ + curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } } - + if (curBone->flag & BONE_CONNECTED) next=curBone->parent; else @@ -1482,19 +1488,19 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e } /* Select children */ - while (bone){ - for (curBone=arm->edbo->first; curBone; curBone=next){ + while (bone) { + for (curBone=arm->edbo->first; curBone; curBone=next) { next = curBone->next; - if (curBone->parent == bone){ - if (curBone->flag & BONE_CONNECTED){ - if (shift) + if ((curBone->parent == bone) && (curBone->flag & BONE_UNSELECTABLE)==0) { + if (curBone->flag & BONE_CONNECTED) { + if (extend) curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); else curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); bone=curBone; break; } - else{ + else { bone=NULL; break; } @@ -1502,15 +1508,12 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e } if (!curBone) bone=NULL; - } - + ED_armature_sync_selection(arm->edbo); - - /* BIF_undo_push("Select connected"); */ - + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit); - + return OPERATOR_FINISHED; } @@ -1527,6 +1530,9 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties s*/ + RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first."); } /* does bones and points */ @@ -3966,9 +3972,12 @@ static int armature_select_inverse_exec(bContext *C, wmOperator *op) { /* Set the flags */ CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { - /* select bone */ - ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - ebone->flag &= ~BONE_ACTIVE; + /* ignore bone if selection can't change */ + if ((ebone->flag & BONE_UNSELECTABLE) == 0) { + /* select bone */ + ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + ebone->flag &= ~BONE_ACTIVE; + } } CTX_DATA_END; @@ -3979,7 +3988,6 @@ static int armature_select_inverse_exec(bContext *C, wmOperator *op) void ARMATURE_OT_select_inverse(wmOperatorType *ot) { - /* identifiers */ ot->name= "Select Inverse"; ot->idname= "ARMATURE_OT_select_inverse"; @@ -4002,15 +4010,18 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) /* Set the flags */ CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { - if (sel==1) { - /* select bone */ - ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if(ebone->parent) - ebone->parent->flag |= (BONE_TIPSEL); - } - else { - /* deselect bone */ - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); + /* ignore bone if selection can't change */ + if ((ebone->flag & BONE_UNSELECTABLE) == 0) { + if (sel==1) { + /* select bone */ + ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + if(ebone->parent) + ebone->parent->flag |= (BONE_TIPSEL); + } + else { + /* deselect bone */ + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); + } } } CTX_DATA_END; @@ -4051,7 +4062,8 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) arm= (bArmature *)ob->data; for (curbone= arm->edbo->first; curbone; curbone= curbone->next) { - if (EBONE_VISIBLE(arm, curbone)) { + /* only work on bone if it is visible and its selection can change */ + if (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_UNSELECTABLE)==0) { if (curbone->flag & (BONE_ACTIVE)) { if (direction == BONE_SELECT_PARENT) { if (curbone->parent == NULL) continue; @@ -4071,7 +4083,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) chbone = editbone_get_child(arm, curbone, 1); if (chbone == NULL) continue; - if (EBONE_VISIBLE(arm, chbone)) { + if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE)==0) { chbone->flag |= (BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); if (!add_to_sel) { @@ -4301,8 +4313,9 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor if (!ob || !ob->pose) return 0; nearBone= get_bone_from_selectbuffer(scene, base, buffer, hits, 1); - - if (nearBone) { + + /* if the bone cannot be affected, don't do anything */ + if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) { bArmature *arm= ob->data; /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */ @@ -4381,7 +4394,8 @@ void ED_pose_deselectall (Object *ob, int test, int doundo) /* Set the flags accordingly */ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) { + /* ignore the pchan if it isn't visible or if its selection cannot be changed */ + if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & (BONE_HIDDEN_P|BONE_UNSELECTABLE))) { if (test==3) { pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); pchan->bone->flag &= ~BONE_ACTIVE; @@ -4960,8 +4974,10 @@ static int pose_select_inverse_exec(bContext *C, wmOperator *op) /* Set the flags */ CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) { - pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - pchan->bone->flag &= ~BONE_ACTIVE; + if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) { + pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + pchan->bone->flag &= ~BONE_ACTIVE; + } } CTX_DATA_END; @@ -4995,9 +5011,11 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) /* Set the flags */ CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) { - /* select pchan */ - if (sel==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); - else pchan->bone->flag |= BONE_SELECTED; + /* select pchan, only if selectable */ + if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) { + if (sel==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); + else pchan->bone->flag |= BONE_SELECTED; + } } CTX_DATA_END; @@ -5031,7 +5049,7 @@ static int pose_select_parent_exec(bContext *C, wmOperator *op) pchan=CTX_data_active_pchan(C); if (pchan) { parent=pchan->parent; - if ((parent) && !(parent->bone->flag & BONE_HIDDEN_P)) { + if ((parent) && !(parent->bone->flag & (BONE_HIDDEN_P|BONE_UNSELECTABLE))) { parent->bone->flag |= BONE_SELECTED; parent->bone->flag |= BONE_ACTIVE; pchan->bone->flag &= ~BONE_ACTIVE; diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index d4b7aa149df..edbc7b9ae9b 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -543,7 +543,7 @@ void pose_select_constraint_target(Scene *scene) for (ct= targets.first; ct; ct= ct->next) { if ((ct->tar == ob) && (ct->subtarget[0])) { bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget); - if(pchanc) + if((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; } } @@ -582,7 +582,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *op) for (ct= targets.first; ct; ct= ct->next) { if ((ct->tar == ob) && (ct->subtarget[0])) { bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget); - if(pchanc) { + if((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) { pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; found= 1; } @@ -634,7 +634,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { curbone= pchan->bone; - if (arm->layer & curbone->layer) { + if ((arm->layer & curbone->layer) && (curbone->flag & BONE_UNSELECTABLE)==0) { if (curbone->flag & (BONE_ACTIVE)) { if (direction == BONE_SELECT_PARENT) { @@ -646,7 +646,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; curbone->flag &= ~BONE_ACTIVE; pabone->flag |= (BONE_ACTIVE|BONE_SELECTED); - + found= 1; break; } @@ -660,7 +660,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; curbone->flag &= ~BONE_ACTIVE; chbone->flag |= (BONE_ACTIVE|BONE_SELECTED); - + found= 1; break; } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 98603ee843a..4fa0e04728f 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -82,7 +82,7 @@ void ED_base_object_select(Base *base, short mode) if (base) { if (mode==BA_SELECT) { if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) - if (mode==BA_SELECT) base->flag |= SELECT; + base->flag |= SELECT; } else if (mode==BA_DESELECT) { base->flag &= ~SELECT; diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index e62c1dedb1b..3c10375c14b 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -4875,19 +4875,27 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar else if(tselem->type==TSE_POSE_CHANNEL) { bPoseChannel *pchan= (bPoseChannel *)te->directdata; Bone *bone = pchan->bone; - + uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); + + bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (short)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); } else if(tselem->type==TSE_EBONE) { EditBone *ebone= (EditBone *)te->directdata; - + uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); + + bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (short)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); } } diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 5dbfdd3e6f1..6c9d9263eeb 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -380,6 +380,11 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET); RNA_def_property_ui_text(prop, "Cyclic Offset", "When bone doesn't have a parent, it receives cyclic offset effects."); RNA_def_property_update(prop, 0, "rna_Armature_update_data"); + + prop= RNA_def_property(srna, "selectable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_UNSELECTABLE); + RNA_def_property_ui_text(prop, "Selectable", "Bone is able to be selected"); + RNA_def_property_update(prop, 0, "rna_Armature_redraw_data"); /* Number values */ /* envelope deform settings */ -- cgit v1.2.3 From 2011ba50c84d61eff998812944354d444bd00041 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 6 Oct 2009 12:23:25 +0000 Subject: Last fix still failed to link under mingw. This time it works! (gcc and mingw can handle compile and link) --- source/blender/render/intern/raytrace/svbvh.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 5837d51d3d4..80e6e2ea190 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -76,7 +76,7 @@ inline void bvh_node_push_childs(SVBVHNode *node, Isect *isec, SVBVHN } template<> -void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) +inline void bvh_node_merge_bb(SVBVHNode *node, float *min, float *max) { if(is_leaf(node)) { -- cgit v1.2.3 From dd8e2897ba19daac5191a341add9955e00798262 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 6 Oct 2009 13:04:31 +0000 Subject: new operator - bpy.ops.wm.call_menu(name="SOME_MT_menu") This calls a registered menu as a popup so we can reuse header menus , currently used for Node editor and Sequencer add menu (Shift+A), can be used for toolbox too. --- source/blender/blenkernel/BKE_screen.h | 2 ++ source/blender/blenkernel/intern/screen.c | 22 +++++++++++++++++ source/blender/editors/include/UI_interface.h | 1 + .../blender/editors/interface/interface_layout.c | 23 ++++++++---------- .../blender/editors/interface/interface_regions.c | 28 ++++++++++++++++++++++ source/blender/editors/space_node/node_ops.c | 4 ++++ .../editors/space_sequencer/sequencer_ops.c | 3 +++ source/blender/makesdna/DNA_space_types.h | 2 +- source/blender/makesrna/intern/rna_ui.c | 10 +++----- source/blender/windowmanager/intern/wm_operators.c | 21 ++++++++++++++++ 10 files changed, 95 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index ee04d4f47bc..b983c6f7dc4 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -222,6 +222,8 @@ const struct ListBase *BKE_spacetypes_list(void); void BKE_spacetype_register(struct SpaceType *st); void BKE_spacetypes_free(void); /* only for quitting blender */ +MenuType *BKE_spacemenu_find(const char *idname, int spacetype); + /* spacedata */ void BKE_spacedata_freelist(ListBase *lb); void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 661d0da1550..3567de5df40 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -343,3 +343,25 @@ unsigned int BKE_screen_visible_layers(bScreen *screen) return layer; } +MenuType *BKE_spacemenu_find(const char *idname, int spacetype) +{ + SpaceType *st= BKE_spacetype_from_id(spacetype); + ARegionType *art; + MenuType* mt; + + if(st==NULL) { + printf("space type %d is invalid\n", spacetype); + return NULL; + } + + if(idname==NULL) + return NULL; + + for(art= st->regiontypes.first; art; art= art->next) + for(mt=art->menutypes.first; mt; mt=mt->next) + if(strcmp(idname, mt->idname)==0) + return mt; + + return NULL; +} + diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 7fea4b10ed9..35598db9e02 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -256,6 +256,7 @@ void uiPupMenuSaveOver(struct bContext *C, struct wmOperator *op, char *filename void uiPupMenuNotice(struct bContext *C, char *str, ...); void uiPupMenuError(struct bContext *C, char *str, ...); void uiPupMenuReports(struct bContext *C, struct ReportList *reports); +void uiPupMenuInvoke(struct bContext *C, const char *idname, int spacetype); /* popup registered menu */ /* Popup Blocks * diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 11dfc44906a..b15be940eef 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1202,24 +1202,21 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname) { - ARegion *ar= CTX_wm_region(C); MenuType *mt; - if(!menuname) - return; + mt= BKE_spacemenu_find(menuname, CTX_wm_area(C)->spacetype); - for(mt=ar->type->menutypes.first; mt; mt=mt->next) { - if(strcmp(menuname, mt->idname) == 0) { - if(!name) - name= mt->label; - if(layout->root->type == UI_LAYOUT_MENU && !icon) - icon= ICON_BLANK1; - ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL); - return; - } + if(mt==NULL) { + printf("uiItemM: not found %s\n", menuname); + return; } - printf("uiItemM: not found %s\n", menuname); + if(!name) + name= mt->label; + if(layout->root->type == UI_LAYOUT_MENU && !icon) + icon= ICON_BLANK1; + + ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL); } /* label item */ diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 0f04333c6c5..dae4a54c233 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2481,6 +2481,34 @@ void uiPupMenuReports(bContext *C, ReportList *reports) BLI_dynstr_free(ds); } +void uiPupMenuInvoke(bContext *C, const char *idname, int spacetype) +{ + uiPopupMenu *pup; + uiLayout *layout; + MenuType *mt= BKE_spacemenu_find(idname, spacetype); + + if(mt==NULL) { + printf("uiPupMenuInvoke: named menu \"%s\" not found\n", idname); + return; + } + + if(mt->poll && mt->poll(C, mt)==0) + return; + + pup= uiPupMenuBegin(C, mt->label, 0); + layout= uiPupMenuLayout(pup); + + Menu menu; + + menu.layout= layout; + menu.type= mt; + + mt->draw(C, &menu); + + uiPupMenuEnd(C, pup); +} + + /*************************** Popup Block API **************************/ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext) diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index f47e9aa2a6f..880cc489838 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -70,6 +70,7 @@ void node_operatortypes(void) void node_keymap(struct wmWindowManager *wm) { wmKeyMap *keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0); + wmKeymapItem *kmi; /* mouse select in nodes used to be both keys, it's UI elements... */ RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0)->ptr, "select_type", NODE_SELECT_MOUSE); @@ -97,5 +98,8 @@ void node_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "NODE_OT_group_ungroup", GKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "NODE_OT_group_edit", TABKEY, KM_PRESS, 0, 0); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "name", "NODE_MT_add"); + transform_keymap_for_space(wm, keymap, SPACE_NODE); } diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index ac125c10b2d..1541b32f566 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -177,6 +177,9 @@ void sequencer_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SEQUENCER_OT_select_border", BKEY, KM_PRESS, 0, 0); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "name", "SEQUENCER_MT_add"); WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 2cd47e340bd..ce4f0bc8737 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -139,7 +139,7 @@ typedef struct SpaceSeq { View2D v2d; /* deprecated, copied to region */ float xof, yof; /* offset for drawing the image preview */ - short mainb; + short mainb; /* weird name for the sequencer subtype (seq, image, luma... etc) */ short render_size; short chanshown; short zebra; diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index f16180451a7..1a1172247fc 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -381,13 +381,9 @@ static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void return NULL; /* check if we have registered this menu type before, and remove it */ - for(mt=art->menutypes.first; mt; mt=mt->next) { - if(strcmp(mt->idname, dummymt.idname) == 0) { - if(mt->ext.srna) - rna_Menu_unregister(C, mt->ext.srna); - break; - } - } + mt= BKE_spacemenu_find(dummymt.idname, dummymt.space_type); + if(mt && mt->ext.srna) + rna_Menu_unregister(C, mt->ext.srna); /* create a new menu type */ mt= MEM_callocN(sizeof(MenuType), "python buttons menu"); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 486a887b354..9ec0ce0df8d 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -58,6 +58,7 @@ #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_screen.h" /* BKE_ST_MAXNAME */ #include "BKE_utildefines.h" #include "BIF_gl.h" @@ -766,6 +767,25 @@ static void WM_OT_search_menu(wmOperatorType *ot) ot->poll= wm_search_menu_poll; } +static int wm_call_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + char idname[BKE_ST_MAXNAME]; + RNA_string_get(op->ptr, "name", idname); + + uiPupMenuInvoke(C, idname, CTX_wm_area(C)->spacetype); + + return OPERATOR_CANCELLED; +} + +static void WM_OT_call_menu(wmOperatorType *ot) +{ + ot->name= "Call Menu"; + ot->idname= "WM_OT_call_menu"; + + ot->invoke= wm_call_menu_invoke; + + RNA_def_string(ot->srna, "name", "", BKE_ST_MAXNAME, "Name", "Name of the new sequence strip"); +} /* ************ window / screen operator definitions ************** */ @@ -2122,6 +2142,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_redraw_timer); WM_operatortype_append(WM_OT_debug_menu); WM_operatortype_append(WM_OT_search_menu); + WM_operatortype_append(WM_OT_call_menu); } /* default keymap for windows and screens, only call once per WM */ -- cgit v1.2.3 From 76019d5fb9812941eb9b70fe47fde386b18be286 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 6 Oct 2009 14:09:40 +0000 Subject: * Remember, C-style declarations at the *beginning* of a scope, not C++ style wherever one pleases (before first usage). --- source/blender/editors/interface/interface_regions.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index dae4a54c233..cdb62d0a4b4 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2485,6 +2485,7 @@ void uiPupMenuInvoke(bContext *C, const char *idname, int spacetype) { uiPopupMenu *pup; uiLayout *layout; + Menu menu; MenuType *mt= BKE_spacemenu_find(idname, spacetype); if(mt==NULL) { @@ -2498,8 +2499,6 @@ void uiPupMenuInvoke(bContext *C, const char *idname, int spacetype) pup= uiPupMenuBegin(C, mt->label, 0); layout= uiPupMenuLayout(pup); - Menu menu; - menu.layout= layout; menu.type= mt; -- cgit v1.2.3 From 6282b7998b212ae5ecda8bf26f4adebd747ba918 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 6 Oct 2009 14:25:55 +0000 Subject: * copying of python31.zip and zlip.pyd is not necessary anymore, since the zip is unpacked by default to .blender/python/lib --- SConstruct | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SConstruct b/SConstruct index 4d6ef7ccb49..6d18000a984 100644 --- a/SConstruct +++ b/SConstruct @@ -578,10 +578,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc'): else: dllsources.append('${BF_SDL_LIBPATH}/SDL.dll') if env['WITH_BF_PYTHON']: - ver = env["BF_PYTHON_VERSION"].replace(".", "") - - dllsources.append('${LCGDIR}/release/python' + ver + '.zip') - dllsources.append('${LCGDIR}/release/zlib.pyd') if env['BF_DEBUG']: dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll') else: -- cgit v1.2.3 From 86307b58c0991472b25bd0c24ba8d2cdbf332bc3 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Tue, 6 Oct 2009 15:01:46 +0000 Subject: == SCons == * Unzip of python31.zip now works also for Python 2.5. Patch by b333rt (thanks again!) --- tools/Blender.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/tools/Blender.py b/tools/Blender.py index 04f2676deb3..fec11685525 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -20,6 +20,9 @@ import string import glob import time import sys +import zipfile +import shutil +import cStringIO from SCons.Script.SConscript import SConsEnvironment import SCons.Action @@ -327,11 +330,80 @@ def set_quiet_output(env): env['BUILDERS']['Library'] = static_lib env['BUILDERS']['Program'] = program + +class CompZipFile(zipfile.ZipFile): + """Partial copy of python2.6's zipfile.ZipFile (see http://www.python.org) + to get a extractall() that works on py2.5 and probably earlier distributions.""" + def __init__(self, file, mode="r", compression=zipfile.ZIP_STORED, allowZip64=False): + zipfile.ZipFile.__init__(self, file, mode, compression, allowZip64) + if not hasattr(self,"extractall"): # use our method + print "Debug: Using comp_extractall!" + self.extractall= self.comp_extractall + + def comp_extractall(self, path=None, members=None, pwd=None): #renamed method + """Extract all members from the archive to the current working + directory. `path' specifies a different directory to extract to. + `members' is optional and must be a subset of the list returned + by namelist(). + """ + if members is None: + members = self.namelist() + + for zipinfo in members: + self.comp_extract(zipinfo, path, pwd) # use our method + + def comp_extract(self, member, path=None, pwd=None): #renamed method + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a ZipInfo object. You can + specify a different directory using `path'. + """ + if not isinstance(member, zipfile.ZipInfo): + member = self.getinfo(member) + + if path is None: + path = os.getcwd() + + return self.comp_extract_member(member, path, pwd) # use our method + + def comp_extract_member(self, member, targetpath, pwd): #renamed method + """Extract the ZipInfo object 'member' to a physical + file on the path targetpath. + """ + # build the destination pathname, replacing + # forward slashes to platform specific separators. + if targetpath[-1:] in (os.path.sep, os.path.altsep): + targetpath = targetpath[:-1] + + # don't include leading "/" from file name if present + if member.filename[0] == '/': + targetpath = os.path.join(targetpath, member.filename[1:]) + else: + targetpath = os.path.join(targetpath, member.filename) + + targetpath = os.path.normpath(targetpath) + + # Create all upper directories if necessary. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + os.makedirs(upperdirs) + + if member.filename[-1] == '/': + os.mkdir(targetpath) + return targetpath + + #use StrinIO instead so we don't have to reproduce more functionality. + source = cStringIO.StringIO(self.read(member.filename)) + target = file(targetpath, "wb") + shutil.copyfileobj(source, target) + source.close() + target.close() + + return targetpath def unzip_pybundle(from_zip,to_dir,exclude_re): - import zipfile - zip= zipfile.ZipFile(from_zip, mode='r') + zip= CompZipFile(from_zip, mode='r') exclude_re= list(exclude_re) #single re object or list of re objects debug= 0 #list files instead of unpacking good= [] @@ -356,7 +428,7 @@ def my_winpybundle_print(target, source, env): pass def WinPyBundle(target=None, source=None, env=None): - import shutil, re + import re py_zip= env.subst( env['LCGDIR'] ) if py_zip[0]=='#': py_zip= py_zip[1:] -- cgit v1.2.3 From 8d54982f37cf48d510fa2de0b2b45c635164a7f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 6 Oct 2009 15:31:25 +0000 Subject: Material buttons now view the active node material shading settings. Selecting a material in the node tree sets this as the active material and the buttons view redraws. Added rna prop material.active_node_material Currently its not clear what settings are used by the node material and the base material (needs some tedious research) so I made most panels use the node material with the exceptions of volumetrics, physics and halo settings. We'll probably need to split the panels up to do this properly. --- release/scripts/ui/buttons_material.py | 68 ++++++++++++++----------- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 31 +++++++++++ source/blender/editors/sculpt_paint/sculpt.c | 8 ++- source/blender/editors/space_node/node_select.c | 17 ++++++- source/blender/makesrna/intern/rna_material.c | 34 +++++++++++++ 6 files changed, 123 insertions(+), 36 deletions(-) diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index 2415d636dab..dee927415e6 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -1,6 +1,17 @@ import bpy +def active_node_mat(mat): + # TODO, 2.4x has a pipeline section, for 2.5 we need to communicate + # which settings from node-materials are used + if mat: + mat_node = mat.active_node_material + if mat_node: + return mat_node + + return None + + class MaterialButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -74,14 +85,14 @@ class MATERIAL_PT_shading(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) if mat.type in ('SURFACE', 'WIRE'): split = layout.split() @@ -117,7 +128,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material tan = mat.strand split = layout.split() @@ -152,7 +163,7 @@ class MATERIAL_PT_physics(MaterialButtonsPanel): def draw(self, context): layout = self.layout - phys = context.material.physics + phys = context.material.physics # dont use node material split = layout.split() @@ -171,14 +182,14 @@ class MATERIAL_PT_options(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) split = layout.split() @@ -211,14 +222,14 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) split = layout.split() @@ -244,14 +255,14 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) split = layout.split() @@ -298,14 +309,14 @@ class MATERIAL_PT_specular(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) layout.active = (not mat.shadeless) @@ -351,12 +362,12 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - mat = context.material + mat = active_node_mat(context.material) sss = mat.subsurface_scattering self.layout.active = (not mat.shadeless) @@ -365,7 +376,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) sss = mat.subsurface_scattering layout.active = sss.enabled @@ -396,19 +407,19 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - raym = context.material.raytrace_mirror + raym = active_node_mat(context.material).raytrace_mirror self.layout.itemR(raym, "enabled", text="") def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) raym = mat.raytrace_mirror layout.active = raym.enabled @@ -451,19 +462,19 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - mat = context.material + mat = active_node_mat(context.material) self.layout.itemR(mat, "transparency", text="") def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) rayt = mat.raytrace_transparency row = layout.row() @@ -517,7 +528,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material halo = mat.halo split = layout.split() @@ -569,7 +580,7 @@ class MATERIAL_PT_flare(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material halo = mat.halo layout.active = halo.flare_mode @@ -618,8 +629,7 @@ class MATERIAL_PT_volume_density(VolumeButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() row = split.row() @@ -635,7 +645,7 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel): def draw(self, context): layout = self.layout - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() @@ -660,7 +670,7 @@ class MATERIAL_PT_volume_lighting(VolumeButtonsPanel): def draw(self, context): layout = self.layout - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() @@ -695,7 +705,7 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material layout.itemR(mat, "transparency_method", expand=True) @@ -707,7 +717,7 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel): def draw(self, context): layout = self.layout - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index b1e7dcaff02..66776d086d6 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -181,6 +181,7 @@ int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); 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 nodeClearActiveID(struct bNodeTree *ntree, short idtype); void NodeTagChanged(struct bNodeTree *ntree, struct bNode *node); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index aa12894feb9..fad866a7201 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1575,6 +1575,37 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype) return node; } +int nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id) +{ + bNode *node; + int ok= FALSE; + + if(ntree==NULL) return ok; + + /* check for group edit */ + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & NODE_GROUP_EDIT) + break; + + if(node) + ntree= (bNodeTree*)node->id; + + /* now find active node with this id */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->id && GS(node->id->name)==idtype) { + if(id && ok==FALSE && node->id==id) { + node->flag |= NODE_ACTIVE_ID; + ok= TRUE; + } else { + node->flag &= ~NODE_ACTIVE_ID; + } + } + } + + return ok; +} + + /* two active flags, ID nodes have special flag for buttons display */ void nodeClearActiveID(bNodeTree *ntree, short idtype) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 982bd315b99..c9353f697db 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1100,17 +1100,15 @@ static struct MultiresModifierData *sculpt_multires_active(Object *ob) for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) { if(md->type == eModifierType_Multires) { - MultiresModifierData *mmd; + MultiresModifierData *mmd= (MultiresModifierData*)md; /* Check if any of the modifiers after multires are active * if not it can use the multires struct */ - ModifierData *md_next; - for (md_next= md->next; md_next; md_next= md_next->next) { - if(md_next->mode & eModifierMode_Realtime) + for (md= md->next; md; md= md->next) { + if(md->mode & eModifierMode_Realtime) return NULL; } - mmd = (MultiresModifierData*)md; if(mmd->lvl != 1) return mmd; } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 5e482758c9d..ecbd46b720f 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -38,6 +38,7 @@ #include "BKE_context.h" #include "BKE_node.h" #include "BKE_global.h" +#include "BKE_utildefines.h" #include "BLI_rect.h" @@ -55,7 +56,7 @@ #include "node_intern.h" -static void node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short extend) +static bNode *node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short extend) { bNode *node; float mx, my; @@ -101,7 +102,10 @@ static void node_mouse_select(SpaceNode *snode, ARegion *ar, short *mval, short ;// node_link_viewer(snode, node); //std_rmouse_transform(node_transform_ext); /* does undo push for select */ + } + + return node; } static int node_select_exec(bContext *C, wmOperator *op) @@ -112,6 +116,7 @@ static int node_select_exec(bContext *C, wmOperator *op) int select_type; short mval[2]; short extend; + bNode *node= NULL; select_type = RNA_enum_get(op->ptr, "select_type"); @@ -120,12 +125,20 @@ static int node_select_exec(bContext *C, wmOperator *op) mval[0] = RNA_int_get(op->ptr, "mouse_x"); mval[1] = RNA_int_get(op->ptr, "mouse_y"); extend = RNA_boolean_get(op->ptr, "extend"); - node_mouse_select(snode, ar, mval, extend); + node= node_mouse_select(snode, ar, mval, extend); break; } /* need refresh/a notifier vs compo notifier */ // XXX WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); /* Do we need to pass the scene? */ + + /* WATCH THIS, there are a few other ways to change the active material */ + if(node) { + if (node->id && GS(node->id->name)== ID_MA) { + WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING_DRAW, node->id); + } + } + ED_region_tag_redraw(ar); /* allow tweak event to work too */ diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index b05a7e59cc3..efcf4de062e 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -54,6 +54,8 @@ static EnumPropertyItem prop_texture_coordinates_items[] = { #include "MEM_guardedalloc.h" +#include "DNA_node_types.h" + #include "BKE_depsgraph.h" #include "BKE_main.h" #include "BKE_texture.h" @@ -152,6 +154,31 @@ static void rna_Material_active_texture_set(PointerRNA *ptr, PointerRNA value) } } +static PointerRNA rna_Material_active_node_material_get(PointerRNA *ptr) +{ + Material *ma= (Material*)ptr->data; + Material *ma_node= NULL; + + /* used in buttons to check context, also checks for edited groups */ + + if(ma && ma->use_nodes && ma->nodetree) { + bNode *node= nodeGetActiveID(ma->nodetree, ID_MA); + + if(node) + ma_node= (Material *)node->id; + } + + return rna_pointer_inherit_refine(ptr, &RNA_Material, ma_node); +} + +static void rna_Material_active_node_material_set(PointerRNA *ptr, PointerRNA value) +{ + Material *ma= (Material*)ptr->data; + Material *ma_act= value.data; + + nodeSetActiveID(ma->nodetree, ID_MA, ma_act); +} + static void rna_MaterialStrand_start_size_range(PointerRNA *ptr, float *min, float *max) { Material *ma= (Material*)ptr->id.data; @@ -1690,6 +1717,13 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the material."); RNA_def_property_update(prop, NC_MATERIAL, NULL); + prop= RNA_def_property(srna, "active_node_material", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Material"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, "rna_Material_active_node_material_get", "rna_Material_active_node_material_set", NULL); + RNA_def_property_ui_text(prop, "Material", "Active node material."); + RNA_def_property_update(prop, NC_MATERIAL, NULL); + /* common */ rna_def_animdata_common(srna); rna_def_mtex_common(srna, "rna_Material_mtex_begin", "rna_Material_active_texture_get", -- cgit v1.2.3 From 07aba4f933279e5940b3bf96825773dfde196455 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Tue, 6 Oct 2009 16:56:22 +0000 Subject: Cocoa port : First pure Cocoa version ! (Mostly for very early testers) Cocoa uses coordinates with y=0 at bottom : updated wm_window.c and wm_event_system.c for COCOA build to avoid double conversions in response to mouse move events and GHOST_getCursorPosition Known limitations: No fullscreen support Font issue in preference panel libSDL uses some Carbon functions --- intern/ghost/intern/GHOST_SystemCocoa.h | 20 +- intern/ghost/intern/GHOST_SystemCocoa.mm | 259 +++++++-- intern/ghost/intern/GHOST_WindowCocoa.h | 55 +- intern/ghost/intern/GHOST_WindowCocoa.mm | 642 +++++++++++++-------- .../blender/windowmanager/intern/wm_event_system.c | 10 +- source/blender/windowmanager/intern/wm_window.c | 6 + 6 files changed, 655 insertions(+), 337 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 3e499f3d136..eab5a5b28aa 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -46,6 +46,7 @@ class GHOST_EventCursor; class GHOST_EventKey; class GHOST_EventWindow; +class GHOST_WindowCocoa; class GHOST_SystemCocoa : public GHOST_System { @@ -191,6 +192,13 @@ public: */ virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const; + /** + * Handles a window event. Called by GHOST_WindowCocoa window delegate + * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) + * @return Indication whether the event was handled. + */ + GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window); + protected: /** * Initializes the system. @@ -220,13 +228,6 @@ protected: */ GHOST_TSuccess handleKeyEvent(void *eventPtr); - /** - * Handles a window event. - * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) - * @return Indication whether the event was handled. - */ - GHOST_TSuccess handleWindowEvent(void *eventPtr); - /** * Handles all basic Mac application stuff for a mouse down event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) @@ -250,10 +251,7 @@ protected: * @param tmTask Pointer to the timer task that expired. */ //static void s_timerCallback(TMTaskPtr tmTask); - - /** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */ - void* m_autoReleasePool; - + /** Event handler reference. */ //EventHandlerRef m_handler; diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 06ce2882beb..fe3cd80f265 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -89,7 +89,157 @@ const EventTypeSpec kEvents[] = };*/ -static GHOST_TButtonMask convertButton(EventMouseButton button) +/* Keycodes from Carbon include file */ +/* + * Summary: + * Virtual keycodes + * + * Discussion: + * These constants are the virtual keycodes defined originally in + * Inside Mac Volume V, pg. V-191. They identify physical keys on a + * keyboard. Those constants with "ANSI" in the name are labeled + * according to the key position on an ANSI-standard US keyboard. + * For example, kVK_ANSI_A indicates the virtual keycode for the key + * with the letter 'A' in the US keyboard layout. Other keyboard + * layouts may have the 'A' key label on a different physical key; + * in this case, pressing 'A' will generate a different virtual + * keycode. + */ +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +/* ISO keyboards only*/ +enum { + kVK_ISO_Section = 0x0A +}; + +/* JIS keyboards only*/ +enum { + kVK_JIS_Yen = 0x5D, + kVK_JIS_Underscore = 0x5E, + kVK_JIS_KeypadComma = 0x5F, + kVK_JIS_Eisu = 0x66, + kVK_JIS_Kana = 0x68 +}; + + +static GHOST_TButtonMask convertButton(int button) { switch (button) { case 0: @@ -474,8 +624,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() GHOST_SystemCocoa::~GHOST_SystemCocoa() { - NSAutoreleasePool* pool = (NSAutoreleasePool *)m_autoReleasePool; - [pool drain]; } @@ -492,16 +640,18 @@ GHOST_TSuccess GHOST_SystemCocoa::init() SetFrontProcess(&psn); }*/ - m_autoReleasePool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (NSApp == nil) { [NSApplication sharedApplication]; if ([NSApp mainMenu] == nil) { NSMenu *mainMenubar = [[NSMenu alloc] init]; NSMenuItem *menuItem; + NSMenu *windowMenu; + NSMenu *appMenu; //Create the application menu - NSMenu *appMenu = [[NSMenu alloc] initWithTitle:@"Blender"]; + appMenu = [[NSMenu alloc] initWithTitle:@"Blender"]; [appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; [appMenu addItem:[NSMenuItem separatorItem]]; @@ -525,7 +675,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init() [appMenu release]; //Create the window menu - NSMenu *windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; @@ -549,7 +699,8 @@ GHOST_TSuccess GHOST_SystemCocoa::init() [appDelegate setSystemCocoa:this]; [NSApp setDelegate:appDelegate]; } - + + [pool drain]; /* * Initialize the cursor to the standard arrow shape (so that we can change it later on). @@ -597,12 +748,18 @@ GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const { //Note that OS X supports monitor hot plug // We do not support multiple monitors at the moment - return [[NSScreen screens] count]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + GHOST_TUns8 count = [[NSScreen screens] count]; + + [pool drain]; + return count; } void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //Get visible frame, that is frame excluding dock and top menu bar NSRect frame = [[NSScreen mainScreen] visibleFrame]; @@ -612,6 +769,8 @@ void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns width = contentRect.size.width; height = contentRect.size.height; + + [pool drain]; } @@ -627,7 +786,8 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( const GHOST_TEmbedderWindowID parentWindow ) { - GHOST_IWindow* window = 0; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + GHOST_IWindow* window = 0; //Get the available rect for including window contents NSRect frame = [[NSScreen mainScreen] visibleFrame]; @@ -638,7 +798,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( left = left > contentRect.origin.x ? left : contentRect.origin.x; top = top > contentRect.origin.y ? top : contentRect.origin.y; - window = new GHOST_WindowCocoa (title, left, top, width, height, state, type); + window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type); if (window) { if (window->getValid()) { @@ -657,6 +817,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( else { GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n"); } + [pool drain]; return window; } @@ -713,7 +874,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const { - NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; + NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; //Direct query to modifierFlags can be used in 10.6 keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false); @@ -744,16 +905,9 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const */ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) { - NSAutoreleasePool* pool = (NSAutoreleasePool*)m_autoReleasePool; - //bool anyProcessed = false; + bool anyProcessed = false; NSEvent *event; - //Reinit the AutoReleasePool - //This is not done the typical Cocoa way (init at beginning of loop, and drain at the end) - //to allow pool to work with other function calls outside this loop (but in same thread) - [pool drain]; - m_autoReleasePool = [[NSAutoreleasePool alloc] init]; - // SetMouseCoalescingEnabled(false, NULL); //TODO : implement timer ?? @@ -790,14 +944,17 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) }*/ do { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; - if (event==nil) + if (event==nil) { + [pool drain]; break; + } - //anyProcessed = true; + anyProcessed = true; switch ([event type]) { case NSKeyDown: @@ -853,47 +1010,42 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) } //Resend event to NSApp to ensure Mac wide events are handled [NSApp sendEvent:event]; + [pool drain]; } while (event!= nil); //} while (waitForEvent && !anyProcessed); Needed only for timer implementation - return true; //anyProcessed; + + return anyProcessed; } -//TODO: To be called from NSWindow delegate -GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) +//Note: called from NSWindow delegate +GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window) { - /*WindowRef windowRef; - GHOST_WindowCocoa *window; - - // Check if the event was send to a GHOST window - ::GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &windowRef); - window = (GHOST_WindowCarbon*) ::GetWRefCon(windowRef); if (!validWindow(window)) { - return err; + return GHOST_kFailure; } //if (!getFullScreen()) { - err = noErr; - switch([event ]) + switch(eventType) { - case kEventWindowClose: + case GHOST_kEventWindowClose: pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) ); break; - case kEventWindowActivated: + case GHOST_kEventWindowActivate: m_windowManager->setActiveWindow(window); window->loadCursor(window->getCursorVisibility(), window->getCursorShape()); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) ); break; - case kEventWindowDeactivated: + case GHOST_kEventWindowDeactivate: m_windowManager->setWindowInactive(window); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) ); break; - case kEventWindowUpdate: + case GHOST_kEventWindowUpdate: //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n"); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) ); break; - case kEventWindowBoundsChanged: + case GHOST_kEventWindowSize: if (!m_ignoreWindowSizedMessages) { window->updateDrawingContext(); @@ -901,7 +1053,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) } break; default: - err = eventNotHandledErr; + return GHOST_kFailure; break; } // } @@ -910,7 +1062,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(void *eventPtr) //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n"); //::RemoveEventFromQueue(::GetMainEventQueue(), event); //} - */ return GHOST_kSuccess; } @@ -943,10 +1094,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData(); NSUInteger tabletEvent; - ct.Pressure = 0; - ct.Xtilt = 0; - ct.Ytilt = 0; - //Handle tablet events combined with mouse events switch ([event subtype]) { case NX_SUBTYPE_TABLET_POINT: @@ -969,6 +1116,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) break; case NSTabletProximity: + ct.Pressure = 0; + ct.Xtilt = 0; + ct.Ytilt = 0; if ([event isEnteringProximity]) { //pointer is entering tablet area proximity @@ -1005,23 +1155,24 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); + if (!window) { + printf("\nM invalid window"); + return GHOST_kFailure; + } + switch ([event type]) { case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: - if (m_windowManager->getActiveWindow()) { - pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber]))); - } + pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber]))); handleTabletEvent(eventPtr); break; case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: - if (m_windowManager->getActiveWindow()) { - pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber]))); - } + pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber]))); handleTabletEvent(eventPtr); break; @@ -1098,16 +1249,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) case NSFlagsChanged: modifiers = [event modifierFlags]; if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) ); + pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) ); } if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) ); + pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) ); } if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) ); + pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) ); } if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) { - pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) ); + pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) ); } m_modifierMask = modifiers; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index f383e3a7a81..5ff205d964f 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -40,8 +40,7 @@ #include "GHOST_Window.h" #include "STR_String.h" -#include - +class GHOST_SystemCocoa; /** * Window on Mac OSX/Cocoa. @@ -60,6 +59,7 @@ public: * Constructor. * Creates a new window and opens it. * To check if the window was created properly, use the getValid() method. + * @param systemCocoa The associated system class to forward events to * @param title The text shown in the title bar of the window. * @param left The coordinate of the left edge of the window. * @param top The coordinate of the top edge of the window. @@ -70,6 +70,7 @@ public: * @param stereoVisual Stereo visual for quad buffered stereo. */ GHOST_WindowCocoa( + const GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, @@ -210,8 +211,8 @@ public: virtual bool getFullScreenDirty(); /* accessor for fullscreen window */ - virtual void setMac_windowState(short value); - virtual short getMac_windowState(); + /*virtual void setMac_windowState(short value); + virtual short getMac_windowState();*/ const GHOST_TabletData* GetTabletData() @@ -260,48 +261,28 @@ protected: virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY); - /** - * Converts a string object to a Mac Pascal string. - * @param in The string object to be converted. - * @param out The converted string. - */ - virtual void gen2mac(const STR_String& in, Str255 out) const; - - /** - * Converts a Mac Pascal string to a string object. - * @param in The string to be converted. - * @param out The converted string object. - */ - virtual void mac2gen(const Str255 in, STR_String& out) const; + /** The window containing the OpenGL view */ + NSWindow *m_window; - WindowRef m_windowRef; - CGrafPtr m_grafPtr; - AGLContext m_aglCtx; + /** The openGL view */ + NSOpenGLView *m_openGLView; + + /** The opgnGL drawing context */ + NSOpenGLContext *m_openGLContext; + + //CGrafPtr m_grafPtr; + //AGLContext m_aglCtx; /** The first created OpenGL context (for sharing display lists) */ - static AGLContext s_firstaglCtx; + //static AGLContext s_firstaglCtx; - Cursor* m_customCursor; + NSCursor* m_customCursor; GHOST_TabletData m_tablet; /** When running in full-screen this tells whether to refresh the window. */ bool m_fullScreenDirty; - - /** specific MacOs X full screen window setting as we use partially system mechanism - values : 0 not maximizable default - 1 normal state - 2 maximized state - - this will be reworked when rebuilding GHOST carbon to use new OS X apis - in order to be unified with GHOST fullscreen/maximised settings - - (lukep) - **/ - - short mac_windowState; - - + /** * The width/height of the size rectangle in the lower right corner of a * Mac/Carbon window. This is also the height of the gutter area. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 092443814b0..4d117d25df3 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -21,26 +21,18 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Maarten Gribnau 05/2001 + Damien Plisson 10/2009 * * ***** END GPL LICENSE BLOCK ***** */ -/** - * Copyright (C) 2001 NaN Technologies B.V. - * @author Maarten Gribnau - * @date May 10, 2001 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include +#include #include "GHOST_WindowCocoa.h" +#include "GHOST_SystemCocoa.h" #include "GHOST_Debug.h" - +/* AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL; #ifdef GHOST_DRAW_CARBON_GUTTER const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16; @@ -68,7 +60,7 @@ AGL_NONE, WindowRef ugly_hack=NULL; const EventTypeSpec kWEvents[] = { - { kEventClassWindow, kEventWindowZoom }, /* for new zoom behaviour */ + { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour }; static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) { @@ -88,9 +80,86 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, } return eventNotHandledErr; +}*/ + +#pragma mark Cocoa delegate object +@interface CocoaWindowDelegate : NSObject +{ + GHOST_SystemCocoa *systemCocoa; + GHOST_WindowCocoa *associatedWindow; +} + +- (void)setSystemAndWindowCocoa:(const GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; +- (void)windowWillClose:(NSNotification *)notification; +- (void)windowDidBecomeKey:(NSNotification *)notification; +- (void)windowDidResignKey:(NSNotification *)notification; +- (void)windowDidUpdate:(NSNotification *)notification; +- (void)windowDidResize:(NSNotification *)notification; +@end + +@implementation CocoaWindowDelegate : NSObject +- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa +{ + systemCocoa = sysCocoa; + associatedWindow = winCocoa; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow); +} + +- (void)windowDidBecomeKey:(NSNotification *)notification +{ + systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow); +} + +- (void)windowDidResignKey:(NSNotification *)notification +{ + systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); +} + +- (void)windowDidUpdate:(NSNotification *)notification +{ + systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow); } +- (void)windowDidResize:(NSNotification *)notification +{ + systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow); +} +@end + +#pragma mark NSOpenGLView subclass +//We need to subclass it in order to give Cocoa the feeling key events are trapped +@interface CocoaOpenGLView : NSOpenGLView +{ + +} +@end +@implementation CocoaOpenGLView + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +//The trick to prevent Cocoa from complaining (beeping) +- (void)keyDown:(NSEvent *)theEvent +{} + +- (BOOL)isOpaque +{ + return YES; +} + +@end + + +#pragma mark initialization / finalization + GHOST_WindowCocoa::GHOST_WindowCocoa( + const GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, @@ -101,17 +170,13 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( const bool stereoVisual ) : GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone), - m_windowRef(0), - m_grafPtr(0), - m_aglCtx(0), m_customCursor(0), m_fullScreenDirty(false) { - Str255 title255; - OSStatus err; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width); - + /* if (state >= GHOST_kWindowState8Normal ) { if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal; else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized; @@ -123,26 +188,77 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( setMac_windowState(1); } else setMac_windowState(0); - +*/ if (state != GHOST_kWindowStateFullScreen) { - Rect bnds = { top, left, top+height, left+width }; - // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/ - gen2mac(title, title255); + + //Creates the window + NSRect rect; + + rect.origin.x = left; + rect.origin.y = top; + rect.size.width = width; + rect.size.height = height; + + m_window = [[NSWindow alloc] initWithContentRect:rect + styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask + backing:NSBackingStoreBuffered defer:NO]; + if (m_window == nil) { + [pool drain]; + return; + } + + [m_window setTitle:[NSString stringWithUTF8String:title]]; + + + //Creates the OpenGL View inside the window + NSOpenGLPixelFormatAttribute attributes[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAAccelerated, + NSOpenGLPFAAllowOfflineRenderers, // NOTE: Needed to connect to secondary GPUs + NSOpenGLPFADepthSize, 32, + 0 + }; + + NSOpenGLPixelFormat *pixelFormat = + [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + + m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect + pixelFormat:pixelFormat]; + + [pixelFormat release]; + + m_openGLContext = [m_openGLView openGLContext]; + + [m_window setContentView:m_openGLView]; + [m_window setInitialFirstResponder:m_openGLView]; + + [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window + + [m_window makeKeyAndOrderFront:nil]; + + setDrawingContextType(type); + updateDrawingContext(); + activateDrawingContext(); + + // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/ + /*gen2mac(title, title255); + err = ::CreateNewWindow( kDocumentWindowClass, kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute, &bnds, &m_windowRef); if ( err != noErr) { - fprintf(stderr," error creating window %i \n",err); + fprintf(stderr," error creating window %i \n",(int)err); } else { ::SetWRefCon(m_windowRef,(SInt32)this); setTitle(title); err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL); if ( err != noErr) { - fprintf(stderr," error creating handler %i \n",err); + fprintf(stderr," error creating handler %i \n",(int)err); } else { // ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL); ::ShowWindow(m_windowRef); @@ -162,7 +278,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( ProcessSerialNumber psn; GetCurrentProcess(&psn); SetFrontProcess(&psn); - } + }*/ } else { /* @@ -179,12 +295,20 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( (SInt32)this); // Store a pointer to the class in the refCon */ //GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n"); - setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);;installDrawingContext(GHOST_kDrawingContextTypeOpenGL); + setDrawingContextType(GHOST_kDrawingContextTypeOpenGL); + installDrawingContext(GHOST_kDrawingContextTypeOpenGL); updateDrawingContext(); - activateDrawingContext(); - - m_tablet.Active = GHOST_kTabletModeNone; + activateDrawingContext(); } + m_tablet.Active = GHOST_kTabletModeNone; + + CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; + [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; + [m_window setDelegate:windowDelegate]; + + [m_window setAcceptsMouseMovedEvents:YES]; + + [pool drain]; } @@ -192,21 +316,26 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() { if (m_customCursor) delete m_customCursor; - if(ugly_hack==m_windowRef) ugly_hack= NULL; + /*if(ugly_hack==m_windowRef) ugly_hack= NULL; - // printf("GHOST_WindowCocoa::~GHOST_WindowCocoa(): removing drawing context\n"); - if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone); - if (m_windowRef) { - ::DisposeWindow(m_windowRef); - m_windowRef = 0; + if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);*/ + + [m_openGLView release]; + + if (m_window) { + [m_window close]; + [m_window release]; + m_window = nil; } } +#pragma mark accessors + bool GHOST_WindowCocoa::getValid() const { bool valid; if (!m_fullScreen) { - valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef); + valid = (m_window != 0); //&& ::IsValidWindowPtr(m_windowRef); } else { valid = true; @@ -218,57 +347,73 @@ bool GHOST_WindowCocoa::getValid() const void GHOST_WindowCocoa::setTitle(const STR_String& title) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid") - Str255 title255; - gen2mac(title, title255); - ::SetWTitle(m_windowRef, title255); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSString *windowTitle = [[NSString alloc] initWithUTF8String:title]; + + [m_window setTitle:windowTitle]; + + [windowTitle release]; + [pool drain]; } void GHOST_WindowCocoa::getTitle(STR_String& title) const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid") - Str255 title255; - ::GetWTitle(m_windowRef, title255); - mac2gen(title255, title); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSString *windowTitle = [m_window title]; + + if (windowTitle != nil) { + title = [windowTitle UTF8String]; + } + + [pool drain]; } void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const { - OSStatus success; - Rect rect; + NSRect rect; GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid") - success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect); - bounds.m_b = rect.bottom; - bounds.m_l = rect.left; - bounds.m_r = rect.right; - bounds.m_t = rect.top; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSRect screenSize = [[m_window screen] visibleFrame]; + + rect = [m_window frame]; + + bounds.m_b = screenSize.size.height - (rect.origin.y -screenSize.origin.y); + bounds.m_l = rect.origin.x -screenSize.origin.x; + bounds.m_r = rect.origin.x-screenSize.origin.x + rect.size.width; + bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height -screenSize.origin.y); + + [pool drain]; } void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const { - Rect rect; + NSRect rect; GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid") - //::GetPortBounds(m_grafPtr, &rect); - ::GetWindowBounds(m_windowRef, kWindowContentRgn, &rect); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSRect screenSize = [[m_window screen] visibleFrame]; - bounds.m_b = rect.bottom; - bounds.m_l = rect.left; - bounds.m_r = rect.right; - bounds.m_t = rect.top; + //Max window contents as screen size (excluding title bar...) + NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; - // Subtract gutter height from bottom -#ifdef GHOST_DRAW_CARBON_GUTTER - if ((bounds.m_b - bounds.m_t) > s_sizeRectSize) - { - bounds.m_b -= s_sizeRectSize; - } - else - { - bounds.m_t = bounds.m_b; - } -#endif //GHOST_DRAW_CARBON_GUTTER + rect = [m_window contentRectForFrameRect:[m_window frame]]; + + bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); + bounds.m_l = rect.origin.x -contentRect.origin.x; + bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; + bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); + + [pool drain]; } @@ -278,7 +423,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); if (((GHOST_TUns32)cBnds.getWidth()) != width) { - ::SizeWindow(m_windowRef, width, cBnds.getHeight(), true); + NSSize size; + size.width=width; + size.height=cBnds.getHeight(); + [m_window setContentSize:size]; } return GHOST_kSuccess; } @@ -289,15 +437,12 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid") GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); -#ifdef GHOST_DRAW_CARBON_GUTTER - if (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize) { - ::SizeWindow(m_windowRef, cBnds.getWidth(), height+s_sizeRectSize, true); - } -#else //GHOST_DRAW_CARBON_GUTTER if (((GHOST_TUns32)cBnds.getHeight()) != height) { - ::SizeWindow(m_windowRef, cBnds.getWidth(), height, true); + NSSize size; + size.width=cBnds.getWidth(); + size.height=height; + [m_window setContentSize:size]; } -#endif //GHOST_DRAW_CARBON_GUTTER return GHOST_kSuccess; } @@ -307,17 +452,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid") GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); -#ifdef GHOST_DRAW_CARBON_GUTTER - if ((((GHOST_TUns32)cBnds.getWidth()) != width) || - (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize)) { - ::SizeWindow(m_windowRef, width, height+s_sizeRectSize, true); - } -#else //GHOST_DRAW_CARBON_GUTTER if ((((GHOST_TUns32)cBnds.getWidth()) != width) || (((GHOST_TUns32)cBnds.getHeight()) != height)) { - ::SizeWindow(m_windowRef, width, height, true); + NSSize size; + size.width=width; + size.height=height; + [m_window setContentSize:size]; } -#endif //GHOST_DRAW_CARBON_GUTTER return GHOST_kSuccess; } @@ -325,16 +466,18 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 GHOST_TWindowState GHOST_WindowCocoa::getState() const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid") + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_TWindowState state; - if (::IsWindowVisible(m_windowRef) == false) { + if ([m_window isMiniaturized]) { state = GHOST_kWindowStateMinimized; } - else if (::IsWindowInStandardState(m_windowRef, nil, nil)) { + else if ([m_window isZoomed]) { state = GHOST_kWindowStateMaximized; } else { state = GHOST_kWindowStateNormal; } + [pool drain]; return state; } @@ -342,32 +485,34 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid") - Point point; - point.h = inX; - point.v = inY; - GrafPtr oldPort; - ::GetPort(&oldPort); - ::SetPort(m_grafPtr); - ::GlobalToLocal(&point); - ::SetPort(oldPort); - outX = point.h; - outY = point.v; + + NSPoint screenCoord; + NSPoint baseCoord; + + screenCoord.x = inX; + screenCoord.y = inY; + + baseCoord = [m_window convertScreenToBase:screenCoord]; + + outX = baseCoord.x; + outY = baseCoord.y; } void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid") - Point point; - point.h = inX; - point.v = inY; - GrafPtr oldPort; - ::GetPort(&oldPort); - ::SetPort(m_grafPtr); - ::LocalToGlobal(&point); - ::SetPort(oldPort); - outX = point.h; - outY = point.v; + + NSPoint screenCoord; + NSPoint baseCoord; + + baseCoord.x = inX; + baseCoord.y = inY; + + screenCoord = [m_window convertBaseToScreen:baseCoord]; + + outX = screenCoord.x; + outY = screenCoord.y; } @@ -376,12 +521,17 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid") switch (state) { case GHOST_kWindowStateMinimized: - ::HideWindow(m_windowRef); + [m_window miniaturize:nil]; break; case GHOST_kWindowStateMaximized: + [m_window zoom:nil]; + break; case GHOST_kWindowStateNormal: default: - ::ShowWindow(m_windowRef); + if ([m_window isMiniaturized]) + [m_window deminiaturize:nil]; + else if ([m_window isZoomed]) + [m_window zoom:nil]; break; } return GHOST_kSuccess; @@ -389,11 +539,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) { - if (isUnsavedChanges) { - SetWindowModified(m_windowRef, 1); - } else { - SetWindowModified(m_windowRef, 0); - } + [m_window setDocumentEdited:isUnsavedChanges]; return GHOST_Window::setModifiedState(isUnsavedChanges); } @@ -404,61 +550,45 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid") if (order == GHOST_kWindowOrderTop) { - //::BringToFront(m_windowRef); is wrong, front window should be active for input too - ::SelectWindow(m_windowRef); + [m_window orderFront:nil]; } else { - /* doesnt work if you do this with a mouseclick */ - ::SendBehind(m_windowRef, nil); + [m_window orderBack:nil]; } return GHOST_kSuccess; } +#pragma mark Drawing context + /*#define WAIT_FOR_VSYNC 1*/ -#ifdef WAIT_FOR_VSYNC -#include -#endif GHOST_TSuccess GHOST_WindowCocoa::swapBuffers() { -#ifdef WAIT_FOR_VSYNC -/* wait for vsync, to avoid tearing artifacts */ -long VBL = 1; -CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL); -#endif - - GHOST_TSuccess succeeded = GHOST_kSuccess; if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { - if (m_aglCtx) { - ::aglSwapBuffers(m_aglCtx); - } - else { - succeeded = GHOST_kFailure; + if (m_openGLContext != nil) { + [m_openGLContext flushBuffer]; + return GHOST_kSuccess; } } - return succeeded; + return GHOST_kFailure; } GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext() { - GHOST_TSuccess succeeded = GHOST_kSuccess; if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { - if (m_aglCtx) { - ::aglUpdateContext(m_aglCtx); - } - else { - succeeded = GHOST_kFailure; + if (m_openGLContext != nil) { + [m_openGLContext update]; + return GHOST_kSuccess; } } - return succeeded; + return GHOST_kFailure; } GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext() { - GHOST_TSuccess succeeded = GHOST_kSuccess; if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { - if (m_aglCtx) { - ::aglSetCurrentContext(m_aglCtx); + if (m_openGLContext != nil) { + [m_openGLContext makeCurrentContext]; #ifdef GHOST_DRAW_CARBON_GUTTER // Restrict drawing to non-gutter area ::aglEnable(m_aglCtx, AGL_BUFFER_RECT); @@ -473,23 +603,44 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext() }; GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b); #endif //GHOST_DRAW_CARBON_GUTTER - } - else { - succeeded = GHOST_kFailure; + return GHOST_kSuccess; } } - return succeeded; + return GHOST_kFailure; } GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type) { GHOST_TSuccess success = GHOST_kFailure; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSOpenGLPixelFormat *pixelFormat; + NSOpenGLContext *tmpOpenGLContext; + switch (type) { case GHOST_kDrawingContextTypeOpenGL: - { if (!getValid()) break; - + + if(!m_fullScreen) + { + pixelFormat = [m_openGLView pixelFormat]; + tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat + shareContext:m_openGLContext]; + if (tmpOpenGLContext == nil) + break; +#ifdef WAIT_FOR_VSYNC + /* wait for vsync, to avoid tearing artifacts */ + [tmpOpenGLContext setValues:1 forParameter:NSOpenGLCPSwapInterval]; +#endif + [m_openGLView setOpenGLContext:tmpOpenGLContext]; + [tmpOpenGLContext setView:m_openGLView]; + + //[m_openGLContext release]; + m_openGLContext = tmpOpenGLContext; + } + /* AGLPixelFormat pixelFormat; if (!m_fullScreen) { pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow); @@ -507,17 +658,16 @@ GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,s //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n"); //::CGGetActiveDisplayList(0, NULL, &m_numDisplays) success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure; - /* + if (success == GHOST_kSuccess) { GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n"); } else { GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n"); } - */ + } - ::aglDestroyPixelFormat(pixelFormat); - } + ::aglDestroyPixelFormat(pixelFormat);*/ break; case GHOST_kDrawingContextTypeNone: @@ -527,41 +677,34 @@ GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,s default: break; } + [pool drain]; return success; } GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext() { - GHOST_TSuccess success = GHOST_kFailure; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; switch (m_drawingContextType) { case GHOST_kDrawingContextTypeOpenGL: - if (m_aglCtx) { - aglSetCurrentContext(NULL); - aglSetDrawable(m_aglCtx, NULL); - //aglDestroyContext(m_aglCtx); - if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL; - success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure; - m_aglCtx = 0; - } - break; + [m_openGLView clearGLContext]; + return GHOST_kSuccess; case GHOST_kDrawingContextTypeNone: - success = GHOST_kSuccess; + return GHOST_kSuccess; break; default: - break; + return GHOST_kFailure; } - return success; + [pool drain]; } GHOST_TSuccess GHOST_WindowCocoa::invalidate() { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid") + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (!m_fullScreen) { - Rect rect; - ::GetPortBounds(m_grafPtr, &rect); - ::InvalWindowRect(m_windowRef, &rect); + [m_openGLView setNeedsDisplay:YES]; } else { //EventRef event; @@ -574,77 +717,81 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate() //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n"); m_fullScreenDirty = true; } + [pool drain]; return GHOST_kSuccess; } - -void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const -{ - STR_String tempStr = in; - int num = tempStr.Length(); - if (num > 255) num = 255; - ::memcpy(out+1, tempStr.Ptr(), num); - out[0] = num; -} - - -void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const -{ - char tmp[256]; - ::memcpy(tmp, in+1, in[0]); - tmp[in[0]] = '\0'; - out = tmp; -} +#pragma mark Cursor handling void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const { static bool systemCursorVisible = true; + NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init]; + + NSCursor *tmpCursor =nil; + if (visible != systemCursorVisible) { if (visible) { - ::ShowCursor(); + [NSCursor unhide]; systemCursorVisible = true; } else { - ::HideCursor(); + [NSCursor hide]; systemCursorVisible = false; } } if (cursor == GHOST_kStandardCursorCustom && m_customCursor) { - ::SetCursor( m_customCursor ); + tmpCursor = m_customCursor; } else { - int carbon_cursor; - -#define GCMAP(ghostCursor, carbonCursor) case ghostCursor: carbon_cursor = carbonCursor; break switch (cursor) { - default: - GCMAP( GHOST_kStandardCursorDefault, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorRightArrow, kThemeAliasArrowCursor); - GCMAP( GHOST_kStandardCursorLeftArrow, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorInfo, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorDestroy, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorHelp, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorCycle, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorSpray, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorWait, kThemeWatchCursor); - GCMAP( GHOST_kStandardCursorText, kThemeIBeamCursor); - GCMAP( GHOST_kStandardCursorCrosshair, kThemeCrossCursor); - GCMAP( GHOST_kStandardCursorUpDown, kThemeClosedHandCursor); - GCMAP( GHOST_kStandardCursorLeftRight, kThemeClosedHandCursor); - GCMAP( GHOST_kStandardCursorTopSide, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorBottomSide, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorLeftSide, kThemeResizeLeftCursor); - GCMAP( GHOST_kStandardCursorRightSide, kThemeResizeRightCursor); - GCMAP( GHOST_kStandardCursorTopLeftCorner, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorTopRightCorner, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorBottomRightCorner, kThemeArrowCursor); - GCMAP( GHOST_kStandardCursorBottomLeftCorner, kThemeArrowCursor); + case GHOST_kStandardCursorDestroy: + tmpCursor = [NSCursor disappearingItemCursor]; + break; + case GHOST_kStandardCursorText: + tmpCursor = [NSCursor IBeamCursor]; + break; + case GHOST_kStandardCursorCrosshair: + tmpCursor = [NSCursor crosshairCursor]; + break; + case GHOST_kStandardCursorUpDown: + tmpCursor = [NSCursor resizeUpDownCursor]; + break; + case GHOST_kStandardCursorLeftRight: + tmpCursor = [NSCursor resizeLeftRightCursor]; + break; + case GHOST_kStandardCursorTopSide: + tmpCursor = [NSCursor resizeUpCursor]; + break; + case GHOST_kStandardCursorBottomSide: + tmpCursor = [NSCursor resizeDownCursor]; + break; + case GHOST_kStandardCursorLeftSide: + tmpCursor = [NSCursor resizeLeftCursor]; + break; + case GHOST_kStandardCursorRightSide: + tmpCursor = [NSCursor resizeRightCursor]; + break; + case GHOST_kStandardCursorRightArrow: + case GHOST_kStandardCursorInfo: + case GHOST_kStandardCursorLeftArrow: + case GHOST_kStandardCursorHelp: + case GHOST_kStandardCursorCycle: + case GHOST_kStandardCursorSpray: + case GHOST_kStandardCursorWait: + case GHOST_kStandardCursorTopLeftCorner: + case GHOST_kStandardCursorTopRightCorner: + case GHOST_kStandardCursorBottomRightCorner: + case GHOST_kStandardCursorBottomLeftCorner: + case GHOST_kStandardCursorDefault: + default: + tmpCursor = [NSCursor arrowCursor]; + break; }; -#undef GCMAP - - ::SetThemeCursor(carbon_cursor); } + [tmpCursor set]; + [pool drain]; } @@ -656,7 +803,7 @@ bool GHOST_WindowCocoa::getFullScreenDirty() GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) { - if (::FrontWindow() == m_windowRef) { + if ([m_window isVisible]) { loadCursor(visible, getCursorShape()); } @@ -666,11 +813,11 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape) { if (m_customCursor) { - delete m_customCursor; - m_customCursor = 0; + [m_customCursor release]; + m_customCursor = nil; } - if (::FrontWindow() == m_windowRef) { + if ([m_window isVisible]) { loadCursor(getCursorVisibility(), shape); } @@ -703,14 +850,15 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color) { int y; + NSPoint hotSpotPoint; + NSImage *cursorImage; if (m_customCursor) { - delete m_customCursor; - m_customCursor = 0; + [m_customCursor release]; + m_customCursor = nil; } - - m_customCursor = new Cursor; - if (!m_customCursor) return GHOST_kFailure; + /*TODO: implement this (but unused inproject at present) + cursorImage = [[NSImage alloc] initWithData:bitmap]; for (y=0; y<16; y++) { #if !defined(__LITTLE_ENDIAN__) @@ -723,13 +871,21 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap } - m_customCursor->hotSpot.h = hotX; - m_customCursor->hotSpot.v = hotY; - if (::FrontWindow() == m_windowRef) { + hotSpotPoint.x = hotX; + hotSpotPoint.y = hotY; + + m_customCursor = [[NSCursor alloc] initWithImage:cursorImage + foregroundColorHint:<#(NSColor *)fg#> + backgroundColorHint:<#(NSColor *)bg#> + hotSpot:hotSpotPoint]; + + [cursorImage release]; + + if ([m_window isVisible]) { loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom); } - + */ return GHOST_kSuccess; } @@ -739,7 +895,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[ return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1); } +#pragma mark Old carbon stuff to remove +#if 0 void GHOST_WindowCocoa::setMac_windowState(short value) { mac_windowState = value; @@ -749,3 +907,23 @@ short GHOST_WindowCocoa::getMac_windowState() { return mac_windowState; } + +void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const +{ + STR_String tempStr = in; + int num = tempStr.Length(); + if (num > 255) num = 255; + ::memcpy(out+1, tempStr.Ptr(), num); + out[0] = num; +} + + +void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const +{ + char tmp[256]; + ::memcpy(tmp, in+1, in[0]); + tmp[in[0]] = '\0'; + out = tmp; +} + +#endif \ No newline at end of file diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 80878cf6884..c15106e21c9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1569,14 +1569,18 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) case GHOST_kEventCursorMove: { if(win->active) { GHOST_TEventCursorData *cd= customdata; +#if defined(__APPLE__) && defined(GHOST_COCOA) + //Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event + event.type= MOUSEMOVE; + event.x= evt->x = cd->x; + event.y = evt->y = cd->y; +#else int cx, cy; - GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy); - event.type= MOUSEMOVE; event.x= evt->x= cx; event.y= evt->y= (win->sizey-1) - cy; - +#endif update_tablet_data(win, &event); wm_event_add(win, &event); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 466e5868723..e3cfb9ad60d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -608,7 +608,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); win->eventstate->x= cx; + +#if defined(__APPLE__) && defined(GHOST_COCOA) + //Cocoa already uses coordinates with y=0 at bottom + win->eventstate->y= cy; +#else win->eventstate->y= (win->sizey-1) - cy; +#endif wm_window_make_drawable(C, win); break; -- cgit v1.2.3 From 9e38ec2506f54a5d5c9c1e8d393309be48032df3 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Tue, 6 Oct 2009 17:01:00 +0000 Subject: Add raytrace subdir to Makefiles. The makefile is a copy of the source one, not tuned, just to unbreak build. This raises some questions: why separate dirs? why each build system takes a different approach (different libs vs all source files into one)? --- source/Makefile | 1 + source/blender/render/intern/raytrace/Makefile | 65 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 source/blender/render/intern/raytrace/Makefile diff --git a/source/Makefile b/source/Makefile index 45a15e822dc..4347c79bc79 100644 --- a/source/Makefile +++ b/source/Makefile @@ -83,6 +83,7 @@ GRPLIB += $(NAN_BOOLOP)/lib/$(DEBUG_DIR)libboolop.a GRPLIB += $(NAN_GHOST)/lib/$(DEBUG_DIR)libghost.a GRPLIB += $(NAN_STRING)/lib/$(DEBUG_DIR)libstring.a GRPLIB += $(OCGDIR)/blender/render/$(DEBUG_DIR)librender.a +GRPLIB += $(OCGDIR)/blender/render/$(DEBUG_DIR)librender_raytrace.a # nlin: the reason that some libraries appear more than once below is # to handle circular dependencies in linking among libraries... some diff --git a/source/blender/render/intern/raytrace/Makefile b/source/blender/render/intern/raytrace/Makefile new file mode 100644 index 00000000000..6e40c544c6f --- /dev/null +++ b/source/blender/render/intern/raytrace/Makefile @@ -0,0 +1,65 @@ +# +# $Id$ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL LICENSE BLOCK ***** +# +# + +LIBNAME = render_raytrace +DIR = $(OCGDIR)/blender/render + +include nan_compile.mk + +CFLAGS += $(LEVEL_1_C_WARNINGS) + +# first /include is my own includes, second is the external interface. +# The external modules follow after. There should be a nicer way to say this. +CPPFLAGS += -I../include +CPPFLAGS += -I../../extern/include +CPPFLAGS += -I../../../blenlib +CPPFLAGS += -I../../../imbuf +CPPFLAGS += -I../../../makesdna +CPPFLAGS += -I../../../makesrna +CPPFLAGS += -I../../../blenkernel +CPPFLAGS += -I../../../quicktime +CPPFLAGS += -I../../../../kernel/gen_messaging +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include +# not very neat: the rest of blender.. +CPPFLAGS += -I../../../editors/include +CPPFLAGS += $(NAN_SDLCFLAGS) +CPPFLAGS += -I../../../../../intern/smoke/extern + +ifeq ($(WITH_QUICKTIME), true) + CPPFLAGS += -DWITH_QUICKTIME +endif + +ifeq ($(WITH_FFMPEG),true) + CPPFLAGS += -DWITH_FFMPEG +endif + +ifeq ($(WITH_OPENEXR),true) + CPPFLAGS += -DWITH_OPENEXR +endif -- cgit v1.2.3 From 88ab193a21757cdcae51bc96bbd4aec06d2f67f8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 6 Oct 2009 17:15:10 +0000 Subject: Bugfix: IK constraint pole angle range was not correct. --- source/blender/makesrna/intern/rna_constraint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index b630e61a680..e6d8a2f27d7 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -87,7 +87,7 @@ EnumPropertyItem constraint_ik_type_items[] ={ {0, NULL, 0, NULL, NULL}, }; -static EnumPropertyItem constraint_distance_items[] = { +EnumPropertyItem constraint_distance_items[] = { {LIMITDIST_INSIDE, "LIMITDIST_INSIDE", 0, "Inside", ""}, {LIMITDIST_OUTSIDE, "LIMITDIST_OUTSIDE", 0, "Outside", ""}, {LIMITDIST_ONSURFACE, "LIMITDIST_ONSURFACE", 0, "On Surface", ""}, @@ -453,7 +453,7 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna) prop= RNA_def_property(srna, "pole_angle", PROP_FLOAT, PROP_ANGLE); // XXX - todo, convert to rad RNA_def_property_float_sdna(prop, NULL, "poleangle"); - RNA_def_property_range(prop, 0.0, 180.f); + RNA_def_property_range(prop, -180.0f, 180.f); RNA_def_property_ui_text(prop, "Pole Angle", "Pole rotation offset."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); -- cgit v1.2.3 From 041ce137e28bba78d24d2f321f1004d64b9aae34 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 6 Oct 2009 20:00:23 +0000 Subject: mistake in last commit --- release/scripts/ui/buttons_material.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index dee927415e6..e91e324f49d 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -8,6 +8,8 @@ def active_node_mat(mat): mat_node = mat.active_node_material if mat_node: return mat_node + else: + return mat return None -- cgit v1.2.3 From 46402ccddc84895a1be167be2421d260f24d4972 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 6 Oct 2009 21:28:45 +0000 Subject: netrender: use TEMP env var if available to set default temporary path --- release/scripts/io/netrender/ui.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py index 7681d4865e9..cc1cbf3ed4a 100644 --- a/release/scripts/io/netrender/ui.py +++ b/release/scripts/io/netrender/ui.py @@ -234,18 +234,21 @@ NetRenderSettings.BoolProperty( attr="server_broadcast", description="broadcast server address on local network", default = True) -if os.name == 'nt': - NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "C:/tmp/") -else: - NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "/tmp/") +default_path = os.environ.get("TEMP", None) + +if not default_path: + if os.name == 'nt': + default_path = "c:/tmp/" + else: + default_path = "/tmp/" +elif not default_path.endswith(os.sep): + default_path += os.sep + +NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = default_path) NetRenderSettings.StringProperty( attr="job_name", name="Job name", -- cgit v1.2.3 From 91400d9da862caf74ccdaf8389d5bc5ce9de506a Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 6 Oct 2009 23:05:53 +0000 Subject: * Fix for crash with new raytree --- source/blender/render/intern/source/volumetric.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 91c13207da8..90ac45edb60 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -139,12 +139,16 @@ static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, */ isect->mode= RE_RAY_MIRROR; - isect->orig.ob = (void*)shi->obi; isect->last_hit = NULL; isect->lay= -1; - if (intersect_type == VOL_BOUNDS_DEPTH) isect->orig.face = (void*)shi->vlr; - else if (intersect_type == VOL_BOUNDS_SS) isect->orig.face= NULL; + if (intersect_type == VOL_BOUNDS_DEPTH) { + isect->orig.face = (void*)shi->vlr; + isect->orig.ob = (void*)shi->obi; + } else if (intersect_type == VOL_BOUNDS_SS) { + isect->orig.face= NULL; + isect->orig.ob = NULL; + } if(RE_rayobject_raycast(R.raytree, isect)) { -- cgit v1.2.3 From f413091dfa3be71ffe03ddd1178ce0b22d0e8cc6 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 6 Oct 2009 23:13:07 +0000 Subject: * Fix for previous 'set object as camera' operator - now properly sets the scene active camera too, plus better notifier. --- source/blender/editors/space_view3d/view3d_view.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index fc332cf6293..505f3abf401 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -443,10 +443,12 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op) if(BASACT) { rv3d->persp= V3D_CAMOB; v3d->camera= OBACT; + if(v3d->scenelock) + scene->camera= OBACT; smooth_view(C, NULL, v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, &v3d->lens); } - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS|NC_OBJECT|ND_DRAW, CTX_data_scene(C)); return OPERATOR_FINISHED; } -- cgit v1.2.3 From a8b82a49ad41491640d390405cf8e8c8c4c05829 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 6 Oct 2009 23:37:11 +0000 Subject: * notifier fix to redraw upon changing lamp shadow type --- 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 06fecec6fb6..3d3333a7eed 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -456,7 +456,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); RNA_def_property_enum_items(prop, (spot)? prop_spot_shadow_items: prop_shadow_items); RNA_def_property_ui_text(prop, "Shadow Method", "Method to compute lamp shadow with."); - RNA_def_property_update(prop, 0, "rna_Lamp_update"); + RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); prop= RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "shdwr"); -- cgit v1.2.3 From e22b5fb27130d6408b5ecb3370ca71a5995d3af4 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 7 Oct 2009 05:13:31 +0000 Subject: * Add numpad enter as an alternative key to confirm/execute file browser --- source/blender/editors/screen/screen_ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7f2084d5a76..f8112145016 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3330,6 +3330,7 @@ void ED_keymap_screen(wmWindowManager *wm) /* files */ WM_keymap_add_item(keymap, "FILE_OT_execute", RETKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "FILE_OT_execute", PADENTER, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_cancel", ESCKEY, KM_PRESS, 0, 0); /* undo */ -- cgit v1.2.3 From 828395744ae9c70d3f69c923cd761aaf2f45abb9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 05:26:13 +0000 Subject: own warnings added last commit --- source/blender/makesrna/intern/rna_material.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index efcf4de062e..9ad42174413 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -59,6 +59,7 @@ static EnumPropertyItem prop_texture_coordinates_items[] = { #include "BKE_depsgraph.h" #include "BKE_main.h" #include "BKE_texture.h" +#include "BKE_node.h" #include "ED_node.h" @@ -176,7 +177,7 @@ static void rna_Material_active_node_material_set(PointerRNA *ptr, PointerRNA va Material *ma= (Material*)ptr->data; Material *ma_act= value.data; - nodeSetActiveID(ma->nodetree, ID_MA, ma_act); + nodeSetActiveID(ma->nodetree, ID_MA, &ma_act->id); } static void rna_MaterialStrand_start_size_range(PointerRNA *ptr, float *min, float *max) -- cgit v1.2.3 From 77476b294f8a7a74ee6f19ff8bfcbb3fb26e3bda Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 07:11:10 +0000 Subject: Experimental option to allow moving the mouse outside the view, "Continuous Grab" in the user-prefs. - Useful for dragging buttons to the far right when theyd otherwise hit the screen edge. - Useful for transform though probably NOT what you want when using the transform manipulator (should make an option). - When enabled, number buttons use this as well as a different conversion of mouse movement float numbuts: mouse 1px == 1-clickstep int numbuts: 2px == 1 (tried 1:1 but its too jitter prone) details... - access as an option to GHOST_SetCursorGrab(grab, warp) - Currently all operators that grab use this, could be made an operator flag - only Ghost/X11 supported currently --- intern/ghost/GHOST_C-api.h | 2 +- intern/ghost/GHOST_IWindow.h | 2 +- intern/ghost/intern/GHOST_C-api.cpp | 4 +- intern/ghost/intern/GHOST_SystemX11.cpp | 48 ++++-- intern/ghost/intern/GHOST_Window.cpp | 12 +- intern/ghost/intern/GHOST_Window.h | 53 +++++- intern/ghost/intern/GHOST_WindowX11.cpp | 23 ++- intern/ghost/intern/GHOST_WindowX11.h | 3 +- release/scripts/ui/space_userpref.py | 4 +- .../blender/editors/interface/interface_handlers.c | 189 ++++++++++++++------- source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/makesrna/intern/rna_userdef.c | 4 + source/blender/windowmanager/WM_api.h | 2 +- source/blender/windowmanager/intern/wm_cursors.c | 4 +- .../blender/windowmanager/intern/wm_event_system.c | 6 +- 15 files changed, 268 insertions(+), 89 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 9460fb504a9..35391d3f4cf 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -376,7 +376,7 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, * @return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab); + int grab, int warp); /*************************************************************************************** ** Access to mouse button and keyboard states. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index ff1484909b0..44ddf9a7cfb 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -271,7 +271,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; }; }; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index d14945d1bf8..b86c4703ea2 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -355,11 +355,11 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab) + int grab, int warp) { GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; - return window->setCursorGrab(grab?true:false); + return window->setCursorGrab(grab?true:false, warp?true:false); } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index cdbdce9c2ca..8c87abf16bc 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -374,12 +374,12 @@ GHOST_SystemX11::processEvent(XEvent *xe) // Only generate a single expose event // per read of the event queue. - g_event = new + g_event = new GHOST_Event( getMilliSeconds(), GHOST_kEventWindowUpdate, window - ); + ); } break; } @@ -388,14 +388,42 @@ GHOST_SystemX11::processEvent(XEvent *xe) { XMotionEvent &xme = xe->xmotion; - g_event = new - GHOST_EventCursor( - getMilliSeconds(), - GHOST_kEventCursorMove, - window, - xme.x_root, - xme.y_root - ); + if(window->getCursorWarp()) { + /* Calculate offscreen location and re-center the mouse */ + GHOST_TInt32 x_warp, y_warp, x_new, y_new, x_accum, y_accum; + + window->getCursorWarpPos(x_warp, y_warp); + getCursorPosition(x_new, y_new); + + if(x_warp != x_new || y_warp != y_new) { + window->getCursorWarpAccum(x_accum, y_accum); + x_accum += x_new - x_warp; + y_accum += y_new - y_warp; + + window->setCursorWarpAccum(x_accum, y_accum); + setCursorPosition(x_warp, y_warp); /* reset */ + + g_event = new + GHOST_EventCursor( + getMilliSeconds(), + GHOST_kEventCursorMove, + window, + x_warp + x_accum, + y_warp + y_accum + ); + + } + } + else { + g_event = new + GHOST_EventCursor( + getMilliSeconds(), + GHOST_kEventCursorMove, + window, + xme.x_root, + xme.y_root + ); + } break; } diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 34e9f519a07..531674607d1 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -48,12 +48,16 @@ GHOST_Window::GHOST_Window( : m_drawingContextType(type), m_cursorVisible(true), - m_cursorGrabbed(true), + m_cursorGrabbed(false), + m_cursorWarp(false), m_cursorShape(GHOST_kStandardCursorDefault), m_stereoVisual(stereoVisual) { m_isUnsavedChanges = false; + m_cursorWarpAccumPos[0] = 0; + m_cursorWarpAccumPos[1] = 0; + m_fullScreen = state == GHOST_kWindowStateFullScreen; if (m_fullScreen) { m_fullScreenWidth = width; @@ -94,12 +98,12 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } } -GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab) +GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp) { if(m_cursorGrabbed == grab) return GHOST_kSuccess; - if (setWindowCursorGrab(grab)) { + if (setWindowCursorGrab(grab, warp)) { m_cursorGrabbed = grab; return GHOST_kSuccess; } @@ -150,4 +154,4 @@ GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges) bool GHOST_Window::getModifiedState() { return m_isUnsavedChanges; -} \ No newline at end of file +} diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index a2d1675f6ab..36e4bac6dae 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -158,6 +158,10 @@ public: * @return The visibility state of the cursor. */ inline virtual bool getCursorVisibility() const; + inline virtual bool getCursorWarp() const; + inline virtual bool getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline virtual bool getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y); /** * Shows or hides the cursor. @@ -171,7 +175,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab); + virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp); /** * Sets the window "modified" status, indicating unsaved changes @@ -243,7 +247,7 @@ protected: * Sets the cursor grab on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCursorGrab(bool grab) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; }; /** * Sets the cursor shape on the window using @@ -272,6 +276,15 @@ protected: /** The current grabbed state of the cursor */ bool m_cursorGrabbed; + /** The current warped state of the cursor */ + bool m_cursorWarp; + + /** Initial grab location. */ + GHOST_TInt32 m_cursorWarpInitPos[2]; + + /** Accumulated offset from m_cursorWarpInitPos. */ + GHOST_TInt32 m_cursorWarpAccumPos[2]; + /** The current shape of the cursor */ GHOST_TStandardCursor m_cursorShape; @@ -304,6 +317,42 @@ inline bool GHOST_Window::getCursorVisibility() const return m_cursorVisible; } +inline bool GHOST_Window::getCursorWarp() const +{ + return m_cursorWarp; +} + +inline bool GHOST_Window::getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const +{ + if(m_cursorWarp==false) + return GHOST_kFailure; + + x= m_cursorWarpInitPos[0]; + y= m_cursorWarpInitPos[1]; + return GHOST_kSuccess; +} + +inline bool GHOST_Window::getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const +{ + if(m_cursorWarp==false) + return GHOST_kFailure; + + x= m_cursorWarpAccumPos[0]; + y= m_cursorWarpAccumPos[1]; + return GHOST_kSuccess; +} + +inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y) +{ + if(m_cursorWarp==false) + return GHOST_kFailure; + + m_cursorWarpAccumPos[0]= x; + m_cursorWarpAccumPos[1]= y; + + return GHOST_kSuccess; +} + inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const { return m_cursorShape; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 060e9ca6f6c..c2dc1048ea0 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1400,12 +1400,29 @@ setWindowCursorVisibility( GHOST_TSuccess GHOST_WindowX11:: setWindowCursorGrab( - bool grab + bool grab, bool warp ){ - if(grab) + if(grab) { + if(warp) { + m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + + setCursorWarpAccum(0, 0); + setWindowCursorVisibility(false); + m_cursorWarp= true; + } XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - else + } + else { + if(m_cursorWarp) { /* are we exiting warp */ + setWindowCursorVisibility(true); + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + + setCursorWarpAccum(0, 0); + m_cursorWarp= false; + } XUngrabPointer(m_display, CurrentTime); + } XFlush(m_display); diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 6f8940bdcbb..08fba3e2be8 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -252,10 +252,11 @@ protected: /** * Sets the cursor grab on the window using * native window system calls. + * @param warp Only used when grab is enabled, hides the mouse and allows gragging outside the screen. */ GHOST_TSuccess setWindowCursorGrab( - bool grab + bool grab, bool warp ); /** diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 15e6c7ee4be..ce8d03d3292 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -109,8 +109,8 @@ class USERPREF_PT_view(bpy.types.Panel): sub1.itemL(text="Mouse Wheel:") sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom") sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines") - sub1.itemS() - sub1.itemS() + sub1.itemL(text="Mouse Motion:") + sub1.itemR(view, "continuous_mouse", text="Continuous Grab") sub1.itemS() sub1.itemL(text="Menus:") sub1.itemR(view, "open_mouse_over") diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index bbf8df00b88..385a0eec040 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -230,6 +230,15 @@ static uiBut *ui_but_last(uiBlock *block) return NULL; } +static int ui_is_a_warp_but(uiBut *but) +{ + if(U.uiflag & USER_CONTINUOUS_MOUSE) + if(ELEM(but->type, NUM, NUMABS)) + return TRUE; + + return FALSE; +} + /* ********************** button apply/revert ************************/ static ListBase UIAfterFuncs = {NULL, NULL}; @@ -1971,6 +1980,51 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE return WM_UI_HANDLER_CONTINUE; } +/* var names match ui_numedit_but_NUM */ +static float ui_numedit_apply_snapf(float tempf, float softmin, float softmax, float softrange, int snap) +{ + if(tempf==softmin || tempf==softmax) + return tempf; + + switch(snap) { + case 0: + break; + case 1: + if(tempf==softmin || tempf==softmax) { } + else if(softrange < 2.10) tempf= 0.1*floor(10*tempf); + else if(softrange < 21.0) tempf= floor(tempf); + else tempf= 10.0*floor(tempf/10.0); + break; + case 2: + if(tempf==softmin || tempf==softmax) { } + else if(softrange < 2.10) tempf= 0.01*floor(100.0*tempf); + else if(softrange < 21.0) tempf= 0.1*floor(10.0*tempf); + else tempf= floor(tempf); + break; + } + + return tempf; +} + +static float ui_numedit_apply_snap(int temp, float softmin, float softmax, int snap) +{ + if(temp==softmin || temp==softmax) + return temp; + + switch(snap) { + case 0: + break; + case 1: + temp= 10*(temp/10); + break; + case 2: + temp= 100*(temp/100); + break; + } + + return temp; +} + static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx) { float deler, tempf, softmin, softmax, softrange; @@ -1993,74 +2047,88 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i softmax= but->softmax; softrange= softmax - softmin; - deler= 500; - if(!ui_is_but_float(but)) { - if((softrange)<100) deler= 200.0; - if((softrange)<25) deler= 50.0; - } - deler /= fac; - if(ui_is_but_float(but) && softrange > 11) { - /* non linear change in mouse input- good for high precicsion */ - data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002); - } else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */ - /* non linear change in mouse input- good for high precicsionm ints need less fine tuning */ - data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004); - } else { - /*no scaling */ - data->dragf+= ((float)(mx-data->draglastx))/deler ; - } + if(ui_is_a_warp_but(but)) { + /* Mouse location isn't screen clamped to the screen so use a linear mapping + * 2px == 1-int, or 1px == 1-ClickStep */ + if(ui_is_but_float(but)) { + tempf = data->startvalue + ((mx - data->dragstartx) * fac * 0.01*but->a1); + tempf= ui_numedit_apply_snapf(tempf, softmin, softmax, softrange, snap); + CLAMP(tempf, softmin, softmax); - if(data->dragf>1.0) data->dragf= 1.0; - if(data->dragf<0.0) data->dragf= 0.0; - data->draglastx= mx; - tempf= (softmin + data->dragf*softrange); - - if(!ui_is_but_float(but)) { - temp= floor(tempf+.5); - - if(tempf==softmin || tempf==softmax); - else if(snap) { - if(snap == 2) temp= 100*(temp/100); - else temp= 10*(temp/10); + if(tempf != data->value) { + data->dragchange= 1; + data->value= tempf; + changed= 1; + } } + else { + temp= data->startvalue + (mx - data->dragstartx)/2; /* simple 2px == 1 */ + temp= ui_numedit_apply_snap(temp, softmin, softmax, snap); + CLAMP(temp, softmin, softmax); - CLAMP(temp, softmin, softmax); - lvalue= (int)data->value; - - if(temp != lvalue) { - data->dragchange= 1; - data->value= (double)temp; - changed= 1; + if(temp != data->value) { + data->dragchange= 1; + data->value= temp; + changed= 1; + } } } else { - temp= 0; + /* Use a non-linear mapping of the mouse drag especially for large floats (normal behavior) */ + deler= 500; + if(!ui_is_but_float(but)) { + if((softrange)<100) deler= 200.0; + if((softrange)<25) deler= 50.0; + } + deler /= fac; - if(snap) { - if(snap == 2) { - if(tempf==softmin || tempf==softmax); - else if(softrange < 2.10) tempf= 0.01*floor(100.0*tempf); - else if(softrange < 21.0) tempf= 0.1*floor(10.0*tempf); - else tempf= floor(tempf); - } - else { - if(tempf==softmin || tempf==softmax); - else if(softrange < 2.10) tempf= 0.1*floor(10*tempf); - else if(softrange < 21.0) tempf= floor(tempf); - else tempf= 10.0*floor(tempf/10.0); + if(ui_is_but_float(but) && softrange > 11) { + /* non linear change in mouse input- good for high precicsion */ + data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002); + } else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */ + /* non linear change in mouse input- good for high precicsionm ints need less fine tuning */ + data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004); + } else { + /*no scaling */ + data->dragf+= ((float)(mx-data->draglastx))/deler ; + } + + if(data->dragf>1.0) data->dragf= 1.0; + if(data->dragf<0.0) data->dragf= 0.0; + data->draglastx= mx; + tempf= (softmin + data->dragf*softrange); + + + if(!ui_is_but_float(but)) { + temp= floor(tempf+.5); + + temp= ui_numedit_apply_snap(temp, softmin, softmax, snap); + + CLAMP(temp, softmin, softmax); + lvalue= (int)data->value; + + if(temp != lvalue) { + data->dragchange= 1; + data->value= (double)temp; + changed= 1; } } + else { + temp= 0; + tempf= ui_numedit_apply_snapf(tempf, softmin, softmax, softrange, snap); - CLAMP(tempf, softmin, softmax); + CLAMP(tempf, softmin, softmax); - if(tempf != data->value) { - data->dragchange= 1; - data->value= tempf; - changed= 1; + if(tempf != data->value) { + data->dragchange= 1; + data->value= tempf; + changed= 1; + } } } + return changed; } @@ -2071,7 +2139,10 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton mx= event->x; my= event->y; - ui_window_to_block(data->region, block, &mx, &my); + + if(!ui_is_a_warp_but(but)) { + ui_window_to_block(data->region, block, &mx, &my); + } if(data->state == BUTTON_STATE_HIGHLIGHT) { /* XXX hardcoded keymap check.... */ @@ -3636,11 +3707,15 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s ui_textedit_end(C, but, data); /* number editing */ - if(state == BUTTON_STATE_NUM_EDITING) + if(state == BUTTON_STATE_NUM_EDITING) { + if(ui_is_a_warp_but(but)) + WM_cursor_grab(CTX_wm_window(C), 1, 1); ui_numedit_begin(but, data); - else if(data->state == BUTTON_STATE_NUM_EDITING) + } else if(data->state == BUTTON_STATE_NUM_EDITING) { ui_numedit_end(but, data); - + if(ui_is_a_warp_but(but)) + WM_cursor_grab(CTX_wm_window(C), 0, -1); + } /* menu open */ if(state == BUTTON_STATE_MENU_OPEN) ui_blockopen_begin(C, but, data); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 16ab3e1e9bd..edfc4999d80 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -402,6 +402,7 @@ extern UserDef U; /* from blenkernel blender.c */ #define USER_SHOW_FPS (1 << 21) #define USER_MMB_PASTE (1 << 22) #define USER_MENUFIXEDORDER (1 << 23) +#define USER_CONTINUOUS_MOUSE (1 << 24) /* Auto-Keying mode */ /* AUTOKEY_ON is a bitflag */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 25448d0c2de..1c6bd6515ff 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1655,6 +1655,10 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_MENUFIXEDORDER); RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction."); + prop= RNA_def_property(srna, "continuous_mouse", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_CONTINUOUS_MOUSE); + RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction."); + prop= RNA_def_property(srna, "global_pivot", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCKAROUND); RNA_def_property_ui_text(prop, "Global Pivot", "Lock the same rotation/scaling pivot in all 3D Views."); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 489f27990cd..321afec51b7 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -75,7 +75,7 @@ void WM_cursor_set (struct wmWindow *win, int curs); void WM_cursor_modal (struct wmWindow *win, int curs); void WM_cursor_restore (struct wmWindow *win); void WM_cursor_wait (int val); -void WM_cursor_grab (struct wmWindow *win, int val); +void WM_cursor_grab (struct wmWindow *win, int val, int warp); void WM_timecursor (struct wmWindow *win, int nr); void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata); diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 56a8d76d8bf..d14cde56083 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -163,10 +163,10 @@ void WM_cursor_wait(int val) } } -void WM_cursor_grab(wmWindow *win, int val) +void WM_cursor_grab(wmWindow *win, int val, int warp) { if(win) - GHOST_SetCursorGrab(win->ghostwin, val); + GHOST_SetCursorGrab(win->ghostwin, val, warp); } /* afer this you can call restore too */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index c15106e21c9..54841f0e063 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -442,7 +442,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P else if(retval & OPERATOR_RUNNING_MODAL) { /* grab cursor during blocking modal ops (X11) */ if(ot->flag & OPTYPE_BLOCKING) - WM_cursor_grab(CTX_wm_window(C), 1); + WM_cursor_grab(CTX_wm_window(C), 1, (U.uiflag & USER_CONTINUOUS_MOUSE)); } else WM_operator_free(op); @@ -637,8 +637,8 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) CTX_wm_region_set(C, region); } + WM_cursor_grab(CTX_wm_window(C), 0, -1); WM_operator_free(handler->op); - WM_cursor_grab(CTX_wm_window(C), 0); } else if(handler->ui_remove) { ScrArea *area= CTX_wm_area(C); @@ -835,7 +835,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* remove modal handler, operator itself should have been cancelled and freed */ if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) { - WM_cursor_grab(CTX_wm_window(C), 0); + WM_cursor_grab(CTX_wm_window(C), 0, -1); BLI_remlink(handlers, handler); wm_event_free_handler(handler); -- cgit v1.2.3 From dfe7cde9f1a8dc90d6d77e2c1108bcb0e87eef82 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 09:23:29 +0000 Subject: - rna path lookup crashed if the string was null (reported by Cessen with an empty driver) - added TexMesh access ([#19505] Missing option : TexMesh) - Ctrl+Tab works again, not-so-nice workaround, disallow switching to paint modes from editmode, but would be nicer to manage this with keymaps. --- release/scripts/ui/buttons_data_mesh.py | 14 ++++++++++++++ source/blender/editors/mesh/editmesh_mods.c | 8 +++++--- source/blender/editors/object/object_edit.c | 6 ++++++ source/blender/makesrna/intern/rna_access.c | 3 +++ source/blender/makesrna/intern/rna_mesh.c | 7 ++++++- source/blender/makesrna/intern/rna_scene.c | 2 ++ 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/release/scripts/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py index 780ae3ac8f9..055cbb02e3f 100644 --- a/release/scripts/ui/buttons_data_mesh.py +++ b/release/scripts/ui/buttons_data_mesh.py @@ -48,6 +48,19 @@ class DATA_PT_normals(DataButtonsPanel): col.itemR(mesh, "vertex_normal_flip") col.itemR(mesh, "double_sided") +class DATA_PT_settings(DataButtonsPanel): + __label__ = "Settings" + + def draw(self, context): + layout = self.layout + + mesh = context.mesh + + split = layout.split() + + col = split.column() + col.itemR(mesh, "texture_mesh") + class DATA_PT_vertex_groups(DataButtonsPanel): __label__ = "Vertex Groups" @@ -197,6 +210,7 @@ class DATA_PT_vertex_colors(DataButtonsPanel): bpy.types.register(DATA_PT_context_mesh) bpy.types.register(DATA_PT_normals) +bpy.types.register(DATA_PT_settings) bpy.types.register(DATA_PT_vertex_groups) bpy.types.register(DATA_PT_shape_keys) bpy.types.register(DATA_PT_uv_texture) diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 325a1aeec99..a23a6dde652 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -78,6 +78,8 @@ editmesh_mods.c, UI level access, no geometry changes #include "WM_api.h" #include "WM_types.h" +#include "UI_resources.h" + #include "RNA_access.h" #include "RNA_define.h" @@ -3614,9 +3616,9 @@ static void mesh_selection_type(ToolSettings *ts, EditMesh *em, int val) } static EnumPropertyItem prop_mesh_edit_types[] = { - {1, "VERT", 0, "Vertices", ""}, - {2, "EDGE", 0, "Edges", ""}, - {3, "FACE", 0, "Faces", ""}, + {1, "VERT", ICON_VERTEXSEL, "Vertices", ""}, + {2, "EDGE", ICON_EDGESEL, "Edges", ""}, + {3, "FACE", ICON_FACESEL, "Faces", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 54df3ae92da..268cd3b3542 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1995,6 +1995,12 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) if(!ob || !object_mode_set_compat(C, op, ob)) return OPERATOR_PASS_THROUGH; + /* Irritating workaround! disallow paint modes from editmode since a number of shortcuts conflict + * XXX - would be much better to handle this on a keymap level */ + if(ob->mode == OB_MODE_EDIT && ELEM6(mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT, OB_MODE_PARTICLE_EDIT, OB_MODE_POSE)) { + return OPERATOR_PASS_THROUGH; + } + /* Exit current mode if it's not the mode we're setting */ if(ob->mode != OB_MODE_OBJECT && ob->mode != mode) WM_operator_name_call(C, object_mode_op_string(ob->mode), WM_OP_EXEC_REGION_WIN, NULL); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 21fbc9fa66d..780a387ddbb 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2226,6 +2226,9 @@ int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prope prop= NULL; curptr= *ptr; + if(path) + return 0; + while(*path) { /* look up property name in current struct */ token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 124fd80ce5a..84a1940de9d 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1413,8 +1413,13 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_struct_type(prop, "MeshSticky"); RNA_def_property_ui_text(prop, "Sticky", "Sticky texture coordinates."); - /* UV textures */ + /* TODO, should this be allowed to be its self? */ + prop= RNA_def_property(srna, "texture_mesh", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "texcomesh"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Texture Mesh", "Use another mesh for texture indicies (vertex indicies must be aligned)."); + /* UV textures */ prop= RNA_def_property(srna, "uv_textures", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer"); RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_textures_begin", 0, 0, 0, "rna_Mesh_uv_textures_length", 0, 0, 0, 0); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 9eea920e371..c771259d5a1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -279,6 +279,7 @@ void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd) } } +#ifdef WITH_OPENJPEG static void rna_SceneRenderData_jpeg2k_preset_set(PointerRNA *ptr, int value) { RenderData *rd= (RenderData*)ptr->data; @@ -292,6 +293,7 @@ static void rna_SceneRenderData_jpeg2k_depth_set(PointerRNA *ptr, int value) rd->jp2_depth= value; rna_SceneRenderData_jpeg2k_preset_update(rd); } +#endif static int rna_SceneRenderData_active_layer_index_get(PointerRNA *ptr) { -- cgit v1.2.3 From 60e75845fbae77e70cac0509b5ee6b19835aa920 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 7 Oct 2009 09:49:37 +0000 Subject: Fix compile warning, function does not return anything (void function). --- source/blender/editors/interface/view2d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index f7546e94f86..0bd0435362f 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -700,7 +700,7 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize) void UI_view2d_curRect_validate(View2D *v2d) { - return UI_view2d_curRect_validate_resize(v2d, 0); + UI_view2d_curRect_validate_resize(v2d, 0); } /* ------------------ */ -- cgit v1.2.3 From 395e61e77cb94fa67a15684b45bb537fb6046ab7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 09:55:18 +0000 Subject: own mistake in last commit --- source/blender/makesrna/intern/rna_access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 780a387ddbb..da467381c06 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2226,7 +2226,7 @@ int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prope prop= NULL; curptr= *ptr; - if(path) + if(path==NULL) return 0; while(*path) { -- cgit v1.2.3 From efe38580007526ff210dbf5fbeb0815ff081dc65 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 7 Oct 2009 10:54:43 +0000 Subject: Bugfix: move to layer was not assigned to M key yet. --- source/blender/editors/object/object_ops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9bfd6a4201c..91e21e77f3a 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -241,6 +241,8 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_clear", HKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, 0, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); + + WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); -- cgit v1.2.3 From a899e9dd18a988e711194b50dd670dc180e3ba28 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 11:36:29 +0000 Subject: Check if the object is in editmode with (ob->mode==OB_MODE_EDIT) rather then (ob==scene->obedit) Was trying to fix a hard to redo crash with custom bone shapes in editmode but cant redo. still, will help with future multi-editmode. --- source/blender/blenkernel/intern/anim.c | 4 ++-- source/blender/blenkernel/intern/modifier.c | 2 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/editors/space_view3d/drawmesh.c | 6 +++--- source/blender/editors/space_view3d/drawobject.c | 10 +++++----- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 5cd901066f8..bb7a792943e 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -549,7 +549,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl /* mballs have a different dupli handling */ if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ - if(par==scene->obedit) { + if(par->mode==OB_MODE_EDIT) { dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd); } else { @@ -760,7 +760,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa else go= go->next; /* group loop */ } - if(par==scene->obedit) { + if(par->mode==OB_MODE_EDIT) { MEM_freeN(mface); MEM_freeN(mvert); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 55fb9f45bb3..f36713dd8a9 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -9137,7 +9137,7 @@ int modifiers_isDeformed(Scene *scene, Object *ob) ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md=md->next) { - if(ob==scene->obedit && (md->mode & eModifierMode_Editmode)==0); + if(ob->mode==OB_MODE_EDIT && (md->mode & eModifierMode_Editmode)==0); else if(modifier_isDeformer(md)) return 1; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 579466ea626..ddf7e7ff4a3 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2367,7 +2367,7 @@ void object_handle_update(Scene *scene, Object *ob) EditMesh *em = BKE_mesh_get_editmesh(ob->data); // here was vieweditdatamask? XXX - if(ob==scene->obedit) { + if(ob->mode==OB_MODE_EDIT) { makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH); BKE_mesh_end_editmesh(ob->data, em); } else diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index a4d7ae802f6..dbe0844cbe5 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -350,7 +350,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O int istex, solidtex= 0; // XXX scene->obedit warning - if(v3d->drawtype==OB_SOLID || (ob==scene->obedit && v3d->drawtype!=OB_TEXTURE)) { + if(v3d->drawtype==OB_SOLID || (ob->mode==OB_MODE_EDIT && v3d->drawtype!=OB_TEXTURE)) { /* draw with default lights in solid draw mode and edit mode */ solidtex= 1; Gtexdraw.islit= -1; @@ -561,7 +561,7 @@ void draw_mesh_text(Scene *scene, Object *ob, int glsl) return; /* don't draw when editing */ - if(ob == scene->obedit) + if(ob->mode==OB_MODE_EDIT) return; else if(ob==OBACT) if(paint_facesel_test(ob)) @@ -641,7 +641,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o /* draw the textured mesh */ draw_textured_begin(scene, v3d, rv3d, ob); - if(ob == scene->obedit) { + if(ob->mode==OB_MODE_EDIT) { glColor4f(1.0f,1.0f,1.0f,1.0f); dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh); } else if(faceselect) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 1bad1b3215c..2d998c5ed5e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5512,7 +5512,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(ob==OBACT && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) { if(ob->type==OB_MESH) { - if(ob==scene->obedit); + if(ob->mode==OB_MODE_EDIT); else { if(dt=OB_BOUNDBOX ) { dtx= ob->dtx; - if(scene->obedit==ob) { + if(ob->mode==OB_MODE_EDIT) { // the only 2 extra drawtypes alowed in editmode dtx= dtx & (OB_DRAWWIRE|OB_TEXSPACE); } @@ -5550,7 +5550,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw outline for selected solid objects, mesh does itself */ if((v3d->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) { - if(dt>OB_WIRE && dtobedit && (flag && DRAW_SCENESET)==0) { + if(dt>OB_WIRE && dtmode!=OB_MODE_EDIT && (flag && DRAW_SCENESET)==0) { if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) { drawSolidSelect(scene, v3d, ar, base); @@ -6159,7 +6159,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec switch( ob->type) { case OB_MESH: { - if(ob == scene->obedit) { + if(ob->mode==OB_MODE_EDIT) { Mesh *me= ob->data; EditMesh *em= me->edit_mesh; @@ -6215,7 +6215,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r DerivedMesh *dm=NULL, *edm=NULL; int glsl; - if(ob == scene->obedit) + if(ob->mode == OB_MODE_EDIT) edm= editmesh_get_derived_base(ob, me->edit_mesh); else dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); -- cgit v1.2.3 From f5a9f420fb1862497bee790c0d9ace5afeb09de9 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 7 Oct 2009 12:17:29 +0000 Subject: * More fixes post-raytrace commit --- .../blender/render/intern/source/volume_precache.c | 71 ++++------------------ source/blender/render/intern/source/volumetric.c | 11 +--- 2 files changed, 15 insertions(+), 67 deletions(-) diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 01930956763..3361eea46e7 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -74,11 +74,15 @@ int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int l if (RE_rayobject_raycast(tree, isect)) { float hitco[3]; - hitco[0] = isect->start[0] + isect->labda*isect->vec[0]; - hitco[1] = isect->start[1] + isect->labda*isect->vec[1]; - hitco[2] = isect->start[2] + isect->labda*isect->vec[2]; - VecAddf(isect->start, hitco, offset); - + isect->start[0] = isect->start[0] + isect->labda*isect->vec[0]; + isect->start[1] = isect->start[1] + isect->labda*isect->vec[1]; + isect->start[2] = isect->start[2] + isect->labda*isect->vec[2]; + + isect->labda = FLT_MAX; + isect->skip = RE_SKIP_VLR_NEIGHBOUR; + isect->orig.face= isect->hit.face; + isect->orig.ob= isect->hit.ob; + return intersect_outside_volume(tree, isect, offset, limit-1, depth+1); } else { return depth; @@ -96,22 +100,14 @@ int point_inside_obi(RayObject *tree, ObjectInstanceRen *obi, float *co) memset(&isect, 0, sizeof(isect)); VECCOPY(isect.start, co); VECCOPY(isect.vec, vec); - isect.labda = FLT_MAX; - - /* - isect.end[0] = co[0] + vec[0] * maxsize; - isect.end[1] = co[1] + vec[1] * maxsize; - isect.end[2] = co[2] + vec[2] * maxsize; - */ - - /* and give it a little offset to prevent self-intersections */ - VecMulf(vec, 1e-5); - VecAddf(isect.start, isect.start, vec); - isect.mode= RE_RAY_MIRROR; isect.last_hit= NULL; isect.lay= -1; + isect.labda = FLT_MAX; + isect.orig.face= NULL; + isect.orig.ob = NULL; + final_depth = intersect_outside_volume(tree, &isect, vec, limit, depth); /* even number of intersections: point is outside @@ -120,47 +116,6 @@ int point_inside_obi(RayObject *tree, ObjectInstanceRen *obi, float *co) else return 1; } -/* -static int inside_check_func(Isect *is, int ob, RayObject *face) -{ - return 1; -} - -static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, float **v4) -{ - VlakRen *vlr= (VlakRen*)face; - - *v1 = (vlr->v1)? vlr->v1->co: NULL; - *v2 = (vlr->v2)? vlr->v2->co: NULL; - *v3 = (vlr->v3)? vlr->v3->co: NULL; - *v4 = (vlr->v4)? vlr->v4->co: NULL; -} - -RayObject *create_raytree_obi(ObjectInstanceRen *obi, float *bbmin, float *bbmax) -{ - int v; - VlakRen *vlr= NULL; - - / * create empty raytree * / - RayTree *tree = RE_ray_tree_create(64, obi->obr->totvlak, bbmin, bbmax, - vlr_face_coords, inside_check_func, NULL, NULL); - - / * fill it with faces * / - for(v=0; vobr->totvlak; v++) { - if((v & 255)==0) - vlr= obi->obr->vlaknodes[v>>8].vlak; - else - vlr++; - - RE_ray_tree_add_face(tree, 0, vlr); - } - - RE_ray_tree_done(tree); - - return tree; -} -*/ - /* *** light cache filtering *** */ static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz) diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 90ac45edb60..fd7ffc8c845 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -98,15 +98,14 @@ static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co) } is.mode = RE_RAY_MIRROR; - is.skip = RE_SKIP_VLR_NEIGHBOUR | RE_SKIP_VLR_RENDER_CHECK | RE_SKIP_VLR_NON_SOLID_MATERIAL; + is.skip = RE_SKIP_VLR_RENDER_CHECK | RE_SKIP_VLR_NON_SOLID_MATERIAL; if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) is.lay= lar->lay; else is.lay= -1; - is.last_hit = NULL; - is.orig.ob = (void*)shi->obi; + is.orig.ob = NULL; is.orig.face = NULL; is.last_hit = lar->last_hit[shi->thread]; @@ -132,12 +131,6 @@ static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, VECCOPY(isect->start, co); VECCOPY(isect->vec, vec ); isect->labda = FLT_MAX; - /* - isect->end[0] = co[0] + vec[0] * maxsize; - isect->end[1] = co[1] + vec[1] * maxsize; - isect->end[2] = co[2] + vec[2] * maxsize; - */ - isect->mode= RE_RAY_MIRROR; isect->last_hit = NULL; isect->lay= -1; -- cgit v1.2.3 From 9cf78144f1e6369bc640df783b4ec7b5f2a15235 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 12:19:47 +0000 Subject: Updated descriptions from Ron Walker --- source/blender/editors/screen/screen_ops.c | 28 +++++++++++++++++++++- source/blender/editors/space_buttons/buttons_ops.c | 4 ++-- source/blender/editors/space_file/file_ops.c | 21 +++++++++++++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index f8112145016..ad0218f3b80 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -512,6 +512,7 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot) { /* identifiers */ ot->name= "Handle area action zones"; + ot->description= "Handle area action zones for mouse actions/gestures."; ot->idname= "SCREEN_OT_actionzone"; ot->invoke= actionzone_invoke; @@ -628,6 +629,7 @@ static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event) static void SCREEN_OT_area_swap(wmOperatorType *ot) { ot->name= "Swap areas"; + ot->description= "Swap selected areas screen positions."; ot->idname= "SCREEN_OT_area_swap"; ot->invoke= area_swap_invoke; @@ -692,6 +694,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event) static void SCREEN_OT_area_dupli(wmOperatorType *ot) { ot->name= "Duplicate Area into New Window"; + ot->description= "Duplicate selected area into new window."; ot->idname= "SCREEN_OT_area_dupli"; ot->invoke= area_dupli_invoke; @@ -931,6 +934,7 @@ static void SCREEN_OT_area_move(wmOperatorType *ot) { /* identifiers */ ot->name= "Move area edges"; + ot->description= "Move selected area edges."; ot->idname= "SCREEN_OT_area_move"; ot->exec= area_move_exec; @@ -1246,6 +1250,7 @@ static EnumPropertyItem prop_direction_items[] = { static void SCREEN_OT_area_split(wmOperatorType *ot) { ot->name = "Split area"; + ot->description= "Split selected area into new windows."; ot->idname = "SCREEN_OT_area_split"; ot->exec= area_split_exec; @@ -1372,6 +1377,7 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot) { /* identifiers */ ot->name= "Scale Region Size"; + ot->description= "Scale selected area."; ot->idname= "SCREEN_OT_region_scale"; ot->invoke= region_scale_invoke; @@ -1432,6 +1438,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) static void SCREEN_OT_frame_jump(wmOperatorType *ot) { ot->name = "Jump to Endpoint"; + ot->description= "Jump to first/last frame in frame range."; ot->idname = "SCREEN_OT_frame_jump"; ot->exec= frame_jump_exec; @@ -1497,6 +1504,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) { ot->name = "Jump to Keyframe"; + ot->description= "Jump to previous/next keyframe."; ot->idname = "SCREEN_OT_keyframe_jump"; ot->exec= keyframe_jump_exec; @@ -1553,6 +1561,7 @@ static int screen_set_exec(bContext *C, wmOperator *op) static void SCREEN_OT_screen_set(wmOperatorType *ot) { ot->name = "Set Screen"; + ot->description= "Cycle through available screens."; ot->idname = "SCREEN_OT_screen_set"; ot->exec= screen_set_exec; @@ -1575,6 +1584,7 @@ static int screen_full_area_exec(bContext *C, wmOperator *op) static void SCREEN_OT_screen_full_area(wmOperatorType *ot) { ot->name = "Toggle Full Screen"; + ot->description= "Toggle display selected area as fullscreen."; ot->idname = "SCREEN_OT_screen_full_area"; ot->exec= screen_full_area_exec; @@ -1848,6 +1858,7 @@ static void SCREEN_OT_area_join(wmOperatorType *ot) { /* identifiers */ ot->name= "Join area"; + ot->description= "Join selected areas into new window."; ot->idname= "SCREEN_OT_area_join"; /* api callbacks */ @@ -1881,6 +1892,7 @@ static void SCREEN_OT_repeat_last(wmOperatorType *ot) { /* identifiers */ ot->name= "Repeat Last"; + ot->description= "Repeat last action."; ot->idname= "SCREEN_OT_repeat_last"; /* api callbacks */ @@ -1933,6 +1945,7 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot) { /* identifiers */ ot->name= "Repeat History"; + ot->description= "Display menu for previous actions performed."; ot->idname= "SCREEN_OT_repeat_history"; /* api callbacks */ @@ -1966,6 +1979,7 @@ static void SCREEN_OT_redo_last(wmOperatorType *ot) { /* identifiers */ ot->name= "Redo Last"; + ot->description= "Display menu for last action performed."; ot->idname= "SCREEN_OT_redo_last"; /* api callbacks */ @@ -2009,6 +2023,7 @@ static void SCREEN_OT_region_split(wmOperatorType *ot) { /* identifiers */ ot->name= "Split Region"; + ot->description= "Split area by directional position."; ot->idname= "SCREEN_OT_region_split"; /* api callbacks */ @@ -2098,6 +2113,7 @@ static void SCREEN_OT_region_foursplit(wmOperatorType *ot) { /* identifiers */ ot->name= "Toggle Quad View"; + ot->description= "Split selected area into camera, front, right & top views."; ot->idname= "SCREEN_OT_region_foursplit"; /* api callbacks */ @@ -2292,6 +2308,7 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot) { /* identifiers */ ot->name= "Animation Step"; + ot->description= "Step through animation by position."; ot->idname= "SCREEN_OT_animation_step"; /* api callbacks */ @@ -2348,6 +2365,7 @@ static void SCREEN_OT_animation_play(wmOperatorType *ot) { /* identifiers */ ot->name= "Play Animation"; + ot->description= "Play animation."; ot->idname= "SCREEN_OT_animation_play"; /* api callbacks */ @@ -2945,6 +2963,7 @@ static void SCREEN_OT_render(wmOperatorType *ot) { /* identifiers */ ot->name= "Render"; + ot->description= "Render active scene."; ot->idname= "SCREEN_OT_render"; /* api callbacks */ @@ -2992,6 +3011,7 @@ static void SCREEN_OT_render_view_cancel(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Cancel Render View"; + ot->description= "Cancel show render view."; ot->idname= "SCREEN_OT_render_view_cancel"; /* api callbacks */ @@ -3037,6 +3057,7 @@ static void SCREEN_OT_render_view_show(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Show/Hide Render View"; + ot->description= "Toggle show render view."; ot->idname= "SCREEN_OT_render_view_show"; /* api callbacks */ @@ -3075,6 +3096,7 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Show/Hide User Preferences"; + ot->description= "Show/hide user preferences."; ot->idname= "SCREEN_OT_userpref_show"; /* api callbacks */ @@ -3099,6 +3121,7 @@ void SCREEN_OT_new(wmOperatorType *ot) { /* identifiers */ ot->name= "New Screen"; + ot->description= "Add a new screen."; ot->idname= "SCREEN_OT_new"; /* api callbacks */ @@ -3122,7 +3145,8 @@ static int screen_delete_exec(bContext *C, wmOperator *op) void SCREEN_OT_delete(wmOperatorType *ot) { /* identifiers */ - ot->name= "Delete Scene"; + ot->name= "Delete Screen"; //was scene + ot->description= "Delete active screen."; ot->idname= "SCREEN_OT_delete"; /* api callbacks */ @@ -3164,6 +3188,7 @@ void SCENE_OT_new(wmOperatorType *ot) /* identifiers */ ot->name= "New Scene"; + ot->description= "Add new scene by type."; ot->idname= "SCENE_OT_new"; /* api callbacks */ @@ -3192,6 +3217,7 @@ void SCENE_OT_delete(wmOperatorType *ot) { /* identifiers */ ot->name= "Delete Scene"; + ot->description= "Delete active scene."; ot->idname= "SCENE_OT_delete"; /* api callbacks */ diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 2d961f78243..634b3e36ea7 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -70,8 +70,8 @@ void BUTTONS_OT_toolbox(wmOperatorType *ot) { /* identifiers */ ot->name= "Toolbox"; + ot->description="Display button panel toolbox"; ot->idname= "BUTTONS_OT_toolbox"; - ot->description="Toolbar panel? DOC_BROKEN"; /* api callbacks */ ot->invoke= toolbox_invoke; @@ -139,8 +139,8 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot) { /* identifiers */ ot->name= "File Browse"; - ot->idname= "BUTTONS_OT_file_browse"; ot->description="Open a file browser."; + ot->idname= "BUTTONS_OT_file_browse"; /* api callbacks */ ot->invoke= file_browse_invoke; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 75230813a41..c0be1ffb637 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -221,6 +221,7 @@ void FILE_OT_select_border(wmOperatorType *ot) { /* identifiers */ ot->name= "Activate/Select File"; + ot->description= "Activate/select the file(s) contained in the border."; ot->idname= "FILE_OT_select_border"; /* api callbacks */ @@ -273,6 +274,7 @@ void FILE_OT_select(wmOperatorType *ot) { /* identifiers */ ot->name= "Activate/Select File"; + ot->description= "Activate/select file."; ot->idname= "FILE_OT_select"; /* api callbacks */ @@ -317,6 +319,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) { /* identifiers */ ot->name= "Select/Deselect all files"; + ot->description= "Select/deselect all files."; ot->idname= "FILE_OT_select_all_toggle"; /* api callbacks */ @@ -352,6 +355,7 @@ void FILE_OT_select_bookmark(wmOperatorType *ot) { /* identifiers */ ot->name= "Select Directory"; + ot->description= "Select a bookmarked directory."; ot->idname= "FILE_OT_select_bookmark"; /* api callbacks */ @@ -384,6 +388,7 @@ void FILE_OT_add_bookmark(wmOperatorType *ot) { /* identifiers */ ot->name= "Add Bookmark"; + ot->description= "Add a bookmark for the selected/active directory."; ot->idname= "FILE_OT_add_bookmark"; /* api callbacks */ @@ -416,6 +421,7 @@ void FILE_OT_delete_bookmark(wmOperatorType *ot) { /* identifiers */ ot->name= "Delete Bookmark"; + ot->description= "Delete selected bookmark."; ot->idname= "FILE_OT_delete_bookmark"; /* api callbacks */ @@ -445,6 +451,7 @@ void FILE_OT_loadimages(wmOperatorType *ot) /* identifiers */ ot->name= "Load Images"; + ot->description= "Load selected image(s)."; ot->idname= "FILE_OT_loadimages"; /* api callbacks */ @@ -499,6 +506,7 @@ void FILE_OT_highlight(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Highlight File"; + ot->description= "Highlight selected file(s)."; ot->idname= "FILE_OT_highlight"; /* api callbacks */ @@ -540,6 +548,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Cancel File Load"; + ot->description= "Cancel loading of selected file."; ot->idname= "FILE_OT_cancel"; /* api callbacks */ @@ -619,6 +628,7 @@ void FILE_OT_execute(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Execute File Window"; + ot->description= "Execute selected file."; ot->idname= "FILE_OT_execute"; /* api callbacks */ @@ -649,6 +659,7 @@ void FILE_OT_parent(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Parent File"; + ot->description= "Move to parent directory."; ot->idname= "FILE_OT_parent"; /* api callbacks */ @@ -673,6 +684,7 @@ void FILE_OT_previous(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Previous Folder"; + ot->description= "Move to previous folder."; ot->idname= "FILE_OT_previous"; /* api callbacks */ @@ -703,6 +715,7 @@ void FILE_OT_next(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Next Folder"; + ot->description= "Move to next folder."; ot->idname= "FILE_OT_next"; /* api callbacks */ @@ -766,8 +779,8 @@ void FILE_OT_directory_new(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Create New Directory"; - ot->idname= "FILE_OT_directory_new"; ot->description= "Create a new directory"; + ot->idname= "FILE_OT_directory_new"; /* api callbacks */ ot->invoke= WM_operator_confirm; @@ -832,6 +845,7 @@ void FILE_OT_refresh(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Refresh Filelist"; + ot->description= "Refresh the file list."; ot->idname= "FILE_OT_refresh"; /* api callbacks */ @@ -859,6 +873,7 @@ void FILE_OT_hidedot(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Toggle Hide Dot Files"; + ot->description= "Toggle hide hidden dot files."; ot->idname= "FILE_OT_hidedot"; /* api callbacks */ @@ -908,6 +923,7 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Toggle Bookmarks"; + ot->description= "Toggle bookmarks display."; ot->idname= "FILE_OT_bookmark_toggle"; /* api callbacks */ @@ -936,6 +952,7 @@ void FILE_OT_filenum(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Increment Number in Filename"; + ot->description= "Increment number in filename."; ot->idname= "FILE_OT_filenum"; /* api callbacks */ @@ -987,6 +1004,7 @@ void FILE_OT_rename(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Rename File or Directory"; + ot->description= "Rename file or file directory."; ot->idname= "FILE_OT_rename"; /* api callbacks */ @@ -1037,6 +1055,7 @@ void FILE_OT_delete(struct wmOperatorType *ot) { /* identifiers */ ot->name= "Delete File"; + ot->description= "Delete selected file."; ot->idname= "FILE_OT_delete"; /* api callbacks */ -- cgit v1.2.3 From 568be173266d42321909b1b9e047d214775c237c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 13:22:56 +0000 Subject: Option to copy the data path of an RNA button --- source/blender/editors/animation/anim_intern.h | 2 ++ source/blender/editors/animation/anim_ops.c | 2 ++ source/blender/editors/animation/drivers.c | 44 +++++++++++++++++++++++ source/blender/editors/interface/interface_anim.c | 3 ++ 4 files changed, 51 insertions(+) diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index 853aeb6c8f3..0101e3d0ef7 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -79,4 +79,6 @@ void ANIM_OT_remove_driver_button(struct wmOperatorType *ot); void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); +void ANIM_OT_copy_clipboard_button(struct wmOperatorType *ot); + #endif // ANIM_INTERN_H diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 4317204f347..83b2e2688c9 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -404,6 +404,8 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_copy_driver_button); WM_operatortype_append(ANIM_OT_paste_driver_button); + WM_operatortype_append(ANIM_OT_copy_clipboard_button); + WM_operatortype_append(ANIM_OT_add_keyingset_button); WM_operatortype_append(ANIM_OT_remove_keyingset_button); diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 363a5a80f00..7a457548623 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -564,4 +564,48 @@ void ANIM_OT_paste_driver_button (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + +/* Paste Driver Button Operator ------------------------ */ + +static int copy_clipboard_button_exec(bContext *C, wmOperator *op) +{ + PointerRNA ptr; + PropertyRNA *prop= NULL; + char *path; + short success= 0; + int index; + + /* try to create driver using property retrieved from UI */ + memset(&ptr, 0, sizeof(PointerRNA)); + uiAnimContextProperty(C, &ptr, &prop, &index); + + if (ptr.data && prop) { // && RNA_property_animateable(ptr.data, prop) + path= RNA_path_from_ID_to_property(&ptr, prop); + + if (path) { + WM_clipboard_text_set(path, FALSE); + MEM_freeN(path); + } + } + + /* since we're just copying, we don't really need to do anything else...*/ + return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; +} + +void ANIM_OT_copy_clipboard_button(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Data Path"; + ot->idname= "ANIM_OT_copy_clipboard_button"; + ot->description= "Copy the rna data path to the clipboard."; + + /* callbacks */ + ot->exec= copy_clipboard_button_exec; + //op->poll= ??? // TODO: need to have some driver to be able to do this... + + /* flags */ + ot->flag= 0; +} + + /* ************************************************** */ diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 8037a609a2f..facda32a41e 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -310,6 +310,9 @@ void ui_but_anim_menu(bContext *C, uiBut *but) } } + uiItemS(layout); + uiItemBooleanO(layout, "Copy Data Path", 0, "ANIM_OT_copy_clipboard_button", "all", 1); + uiPupMenuEnd(C, pup); } } -- cgit v1.2.3 From 17c083a38f3a5269a3224b632f0bc129d831dc5d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 14:40:27 +0000 Subject: 'Add Group' back in the add object menu --- source/blender/editors/object/object_add.c | 78 +++++++++++++++++++++++++++ source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + 3 files changed, 80 insertions(+) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 7188368a95f..780126852ed 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -26,6 +26,7 @@ */ #include +#include #include "MEM_guardedalloc.h" @@ -704,6 +705,8 @@ static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *eve uiItemMenuEnumO(layout, "Lamp", ICON_OUTLINER_OB_LAMP, "OBJECT_OT_lamp_add", "type"); uiItemS(layout); uiItemMenuEnumO(layout, "Force Field", ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_effector_add", "type"); + uiItemS(layout); + uiItemMenuEnumO(layout, "Group Instance", ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_group_instance_add", "type"); uiPupMenuEnd(C, pup); @@ -728,6 +731,81 @@ void OBJECT_OT_primitive_add(wmOperatorType *ot) ot->flag= 0; } +/* add dupligroup */ +static EnumPropertyItem *add_dupligroup_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + EnumPropertyItem *item= NULL, item_tmp; + int totitem= 0; + int i= 0; + Group *group; + + if(C==NULL) + return NULL; + + memset(&item_tmp, 0, sizeof(item_tmp)); + + for(group= CTX_data_main(C)->group.first; group; group= group->id.next) { + item_tmp.identifier= item_tmp.name= group->id.name+2; + item_tmp.value= i++; + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + + if(i>0) { + *free= 1; + return item; + } + else { + return NULL; + } +} + +static int group_instance_add_exec(bContext *C, wmOperator *op) +{ + /* XXX, using an enum for library lookups is a bit dodgy */ + Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "type")); + + if(group) { + Object *ob= object_add_type(C, OB_EMPTY); + rename_id(&ob->id, group->id.name+2); + ob->dup_group= group; + ob->transflag |= OB_DUPLIGROUP; + id_us_plus(&group->id); + + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +/* only used as menu */ +void OBJECT_OT_group_instance_add(wmOperatorType *ot) +{ + PropertyRNA *prop; + static EnumPropertyItem prop_group_dummy_types[] = { + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Add Group Instance"; + ot->description = "Add a dupligroup instance."; + ot->idname= "OBJECT_OT_group_instance_add"; + + /* api callbacks */ + ot->exec= group_instance_add_exec; + + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= 0; + + /* properties */ + prop= RNA_def_enum(ot->srna, "type", prop_group_dummy_types, 0, "Type", ""); + RNA_def_enum_funcs(prop, add_dupligroup_itemf); +} + /**************************** Delete Object *************************/ /* remove base from a specific scene */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 474715c593b..1a7d3841aaa 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -92,6 +92,7 @@ void OBJECT_OT_armature_add(struct wmOperatorType *ot); void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_primitive_add(struct wmOperatorType *ot); /* only used as menu */ void OBJECT_OT_effector_add(struct wmOperatorType *ot); +void OBJECT_OT_group_instance_add(struct wmOperatorType *ot); void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); void OBJECT_OT_duplicate(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 91e21e77f3a..82135bf3804 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -118,6 +118,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_effector_add); + WM_operatortype_append(OBJECT_OT_group_instance_add); WM_operatortype_append(OBJECT_OT_primitive_add); WM_operatortype_append(OBJECT_OT_mesh_add); WM_operatortype_append(OBJECT_OT_metaball_add); -- cgit v1.2.3 From cf4f00b2fa6dfecc400519a635c41798bf45ca88 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 7 Oct 2009 14:48:29 +0000 Subject: Preview Render: * Fixes for texture and material nodes. * Texture node previews now work more like materials. --- source/blender/editors/include/ED_render.h | 14 ++-- source/blender/editors/render/render_preview.c | 33 ++++++---- source/blender/editors/space_node/node_draw.c | 3 + source/blender/editors/space_node/space_node.c | 6 +- source/blender/makesdna/DNA_scene_types.h | 5 +- source/blender/makesrna/intern/rna_material.c | 2 +- source/blender/makesrna/intern/rna_texture.c | 12 +++- source/blender/nodes/intern/TEX_nodes/TEX_at.c | 2 +- source/blender/nodes/intern/TEX_nodes/TEX_bricks.c | 4 +- .../blender/nodes/intern/TEX_nodes/TEX_checker.c | 4 +- .../blender/nodes/intern/TEX_nodes/TEX_compose.c | 2 +- source/blender/nodes/intern/TEX_nodes/TEX_coord.c | 4 +- source/blender/nodes/intern/TEX_nodes/TEX_curves.c | 4 +- .../blender/nodes/intern/TEX_nodes/TEX_decompose.c | 8 +-- .../blender/nodes/intern/TEX_nodes/TEX_distance.c | 4 +- .../blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c | 2 +- source/blender/nodes/intern/TEX_nodes/TEX_image.c | 4 +- source/blender/nodes/intern/TEX_nodes/TEX_invert.c | 4 +- source/blender/nodes/intern/TEX_nodes/TEX_math.c | 4 +- source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c | 4 +- source/blender/nodes/intern/TEX_nodes/TEX_output.c | 44 +++++++------ source/blender/nodes/intern/TEX_nodes/TEX_proc.c | 5 +- source/blender/nodes/intern/TEX_nodes/TEX_rotate.c | 2 +- source/blender/nodes/intern/TEX_nodes/TEX_scale.c | 2 +- .../blender/nodes/intern/TEX_nodes/TEX_texture.c | 4 +- .../blender/nodes/intern/TEX_nodes/TEX_translate.c | 2 +- .../blender/nodes/intern/TEX_nodes/TEX_valToNor.c | 4 +- .../blender/nodes/intern/TEX_nodes/TEX_valToRgb.c | 6 +- source/blender/nodes/intern/TEX_nodes/TEX_viewer.c | 11 +++- source/blender/nodes/intern/TEX_util.c | 75 +++++----------------- source/blender/nodes/intern/TEX_util.h | 5 +- source/blender/render/intern/source/shadeinput.c | 2 +- source/blender/render/intern/source/texture.c | 2 +- 33 files changed, 127 insertions(+), 162 deletions(-) diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index be93bf92e5e..13028dac1a2 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -64,21 +64,19 @@ typedef struct RenderInfo { /* Render the preview pr_method: -- PR_DRAW_RENDER: preview is rendered and drawn, as indicated by called context (buttons panel) -- PR_ICON_RENDER: the preview is not drawn and the function is not dynamic, - so no events are processed. Hopefully fast enough for at least 32x32 -- PR_DO_RENDER: preview is rendered, not drawn, but events are processed for afterqueue, - in use for node editor now. +- PR_BUTS_RENDER: preview is rendered for buttons window +- PR_ICON_RENDER: preview is rendered for icons. hopefully fast enough for at least 32x32 +- PR_NODE_RENDER: preview is rendered for node editor. */ -#define PR_DRAW_RENDER 0 +#define PR_BUTS_RENDER 0 #define PR_ICON_RENDER 1 -#define PR_DO_RENDER 2 +#define PR_NODE_RENDER 2 void ED_preview_init_dbase(void); void ED_preview_free_dbase(void); -void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey); +void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey, int method); void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey); void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 4a671e4d2ba..92380a56d3d 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -359,7 +359,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre } else { sce->lay= 1<pr_type; - if(mat->nodetree) + if(mat->nodetree && sp->pr_method==PR_NODE_RENDER) ntreeInitPreview(mat->nodetree, sp->sizex, sp->sizey); } } @@ -408,6 +408,9 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre } } } + + if(tex && tex->nodetree && sp->pr_method==PR_NODE_RENDER) + ntreeInitPreview(tex->nodetree, sp->sizex, sp->sizey); } else if(id_type==ID_LA) { Lamp *la= (Lamp *)id; @@ -529,7 +532,7 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r } if(ok==0) { - ED_preview_shader_job(C, sa, id, parent, slot, newx, newy); + ED_preview_shader_job(C, sa, id, parent, slot, newx, newy, PR_BUTS_RENDER); } } } @@ -880,11 +883,12 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs Render *re; Scene *sce; float oldlens; + short idtype= GS(id->name); char name[32]; int sizex; /* get the stuff from the builtin preview dbase */ - sce= preview_prepare_scene(sp->scene, id, GS(id->name), sp); // XXX sizex + sce= preview_prepare_scene(sp->scene, id, idtype, sp); // XXX sizex if(sce==NULL) return; if(!split || first) sprintf(name, "Preview %p", sp->owner); @@ -896,14 +900,19 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs re= RE_NewRender(name); /* sce->r gets copied in RE_InitState! */ - if(sp->pr_method==PR_DO_RENDER) { - sce->r.scemode |= R_NODE_PREVIEW; - sce->r.scemode &= ~R_NO_IMAGE_LOAD; + sce->r.scemode &= ~(R_MATNODE_PREVIEW|R_TEXNODE_PREVIEW); + sce->r.scemode &= ~R_NO_IMAGE_LOAD; + + if(sp->pr_method==PR_ICON_RENDER) { + sce->r.scemode |= R_NO_IMAGE_LOAD; + } + else if(sp->pr_method==PR_NODE_RENDER) { + if(idtype == ID_MA) sce->r.scemode |= R_MATNODE_PREVIEW; + else if(idtype == ID_TE) sce->r.scemode |= R_TEXNODE_PREVIEW; sce->r.mode |= R_OSA; } - else { /* PR_ICON_RENDER */ - sce->r.scemode &= ~R_NODE_PREVIEW; - sce->r.scemode |= R_NO_IMAGE_LOAD; + else { /* PR_BUTS_RENDER */ + sce->r.mode |= R_OSA; } /* in case of split preview, use border render */ @@ -917,7 +926,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs RE_InitState(re, NULL, &sce->r, sizex, sp->sizey, NULL); /* callbacs are cleared on GetRender() */ - if(sp->pr_method==PR_DO_RENDER) { + if(sp->pr_method==PR_BUTS_RENDER) { RE_display_draw_cb(re, sp, shader_preview_draw); RE_test_break_cb(re, sp, shader_preview_break); } @@ -1125,7 +1134,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r WM_jobs_start(CTX_wm_manager(C), steve); } -void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, MTex *slot, int sizex, int sizey) +void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, MTex *slot, int sizex, int sizey, int method) { wmJob *steve; ShaderPreview *sp; @@ -1138,7 +1147,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->owner= owner; sp->sizex= sizex; sp->sizey= sizey; - sp->pr_method= PR_DO_RENDER; + sp->pr_method= method; sp->id = id; sp->parent= parent; sp->slot= slot; diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 3fc91fea914..dd2dc0d796a 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -54,6 +54,7 @@ #include "MEM_guardedalloc.h" #include "BKE_context.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_library.h" @@ -102,6 +103,7 @@ void ED_node_changed_update(bContext *C, bNode *node) return; if(snode->treetype==NTREE_SHADER) { + DAG_id_flush_update(snode->id, 0); WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id); } else if(snode->treetype==NTREE_COMPOSIT) { @@ -127,6 +129,7 @@ void ED_node_changed_update(bContext *C, bNode *node) WM_event_add_notifier(C, NC_SCENE|ND_NODES, CTX_data_scene(C)); } else if(snode->treetype==NTREE_TEXTURE) { + DAG_id_flush_update(snode->id, 0); WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id); } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 2cfd9d99123..bdd2a65984f 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -179,12 +179,14 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa) { /* default now: refresh node is starting preview */ SpaceNode *snode= sa->spacedata.first; + + snode_set_context(snode, CTX_data_scene(C)); if(snode->nodetree) { if(snode->treetype==NTREE_SHADER) { Material *ma= (Material *)snode->id; if(ma->use_nodes) - ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100); + ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); } else if(snode->treetype==NTREE_COMPOSIT) { Scene *scene= (Scene *)snode->id; @@ -194,7 +196,7 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa) else if(snode->treetype==NTREE_TEXTURE) { Tex *tex= (Tex *)snode->id; if(tex->use_nodes) { - ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100); + ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); } } } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 63415662d2b..437b45cfda1 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -840,7 +840,7 @@ typedef struct Scene { #define R_PASSEPARTOUT 0x0004 #define R_PREVIEWBUTS 0x0008 #define R_EXTENSION 0x0010 -#define R_NODE_PREVIEW 0x0020 +#define R_MATNODE_PREVIEW 0x0020 #define R_DOCOMP 0x0040 #define R_COMP_CROP 0x0080 #define R_FREE_IMAGE 0x0100 @@ -852,7 +852,8 @@ typedef struct Scene { #define R_STAMP_INFO 0x4000 /* deprecated */ #define R_FULL_SAMPLE 0x8000 #define R_COMP_RERENDER 0x10000 -#define R_RECURS_PROTECTION 0x20000 +#define R_RECURS_PROTECTION 0x20000 +#define R_TEXNODE_PREVIEW 0x40000 /* r->stamp */ #define R_STAMP_TIME 0x0001 diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 9ad42174413..28fcc3103b8 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1716,7 +1716,7 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1); RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_nodes_set"); RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the material."); - RNA_def_property_update(prop, NC_MATERIAL, NULL); + RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "active_node_material", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Material"); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 78d7f012487..428df15ef4e 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -107,6 +107,14 @@ static void rna_Texture_update(bContext *C, PointerRNA *ptr) WM_event_add_notifier(C, NC_TEXTURE, tex); } +static void rna_Texture_nodes_update(bContext *C, PointerRNA *ptr) +{ + Tex *tex= ptr->id.data; + + DAG_id_flush_update(&tex->id, 0); + WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, tex); +} + static void rna_Texture_type_set(PointerRNA *ptr, int value) { Tex *tex= (Tex*)ptr->data; @@ -1678,12 +1686,12 @@ static void rna_def_texture(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1); RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_nodes_set"); RNA_def_property_ui_text(prop, "Use Nodes", "Make this a node-based texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_nodes_update"); prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node-based textures"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_nodes_update"); rna_def_animdata_common(srna); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_at.c b/source/blender/nodes/intern/TEX_nodes/TEX_at.c index 4d714d91130..7e6cce9f35a 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_at.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_at.c @@ -50,7 +50,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_at = { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c b/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c index f1f3b0919ae..2093679e39d 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c @@ -109,9 +109,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_bricks= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_checker.c b/source/blender/nodes/intern/TEX_nodes/TEX_checker.c index b889f1e2164..7b736206c51 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_checker.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_checker.c @@ -61,9 +61,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_checker= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_compose.c b/source/blender/nodes/intern/TEX_nodes/TEX_compose.c index 9fc4b2ff7c2..dac6ca7c3ef 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_compose.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_compose.c @@ -49,7 +49,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_compose= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_coord.c b/source/blender/nodes/intern/TEX_nodes/TEX_coord.c index e5c2b309fb3..a33a2608af0 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_coord.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_coord.c @@ -42,9 +42,7 @@ static void vectorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, sho static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &vectorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &vectorfn, data); } bNodeType tex_node_coord= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_curves.c b/source/blender/nodes/intern/TEX_nodes/TEX_curves.c index 61ebcea7360..a1b20370687 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_curves.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_curves.c @@ -50,7 +50,7 @@ static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, static void time_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &time_colorfn); + tex_output(node, in, out[0], &time_colorfn, data); } @@ -100,7 +100,7 @@ static void rgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, static void rgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &rgb_colorfn); + tex_output(node, in, out[0], &rgb_colorfn, data); } static void rgb_init(bNode *node) diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c b/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c index f7a409f0230..d5eeba2253c 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c @@ -67,10 +67,10 @@ static void valuefn_a(float *out, TexParams *p, bNode *node, bNodeStack **in, sh static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &valuefn_r); - tex_output(node, in, out[1], &valuefn_g); - tex_output(node, in, out[2], &valuefn_b); - tex_output(node, in, out[3], &valuefn_a); + tex_output(node, in, out[0], &valuefn_r, data); + tex_output(node, in, out[1], &valuefn_g, data); + tex_output(node, in, out[2], &valuefn_b, data); + tex_output(node, in, out[3], &valuefn_a, data); } bNodeType tex_node_decompose= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c index 4e145e26b72..297fc02939d 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c @@ -53,9 +53,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &valuefn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &valuefn, data); } bNodeType tex_node_distance= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c b/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c index 192c7a39ee8..b267dc7acbb 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c @@ -84,7 +84,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_hue_sat= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_image.c b/source/blender/nodes/intern/TEX_nodes/TEX_image.c index 0a55af70b52..123063a7900 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_image.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_image.c @@ -73,9 +73,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &colorfn, data); } static void init(bNode* node) diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_invert.c b/source/blender/nodes/intern/TEX_nodes/TEX_invert.c index 5663f897ff5..f2fcbfbf9eb 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_invert.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_invert.c @@ -55,9 +55,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_invert= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_math.c b/source/blender/nodes/intern/TEX_nodes/TEX_math.c index 4ee04140fca..8c400a44832 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_math.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_math.c @@ -171,9 +171,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &valuefn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &valuefn, data); } bNodeType tex_node_math= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c b/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c index 24bdde70127..f6955b47376 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c @@ -57,9 +57,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_mix_rgb= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_output.c b/source/blender/nodes/intern/TEX_nodes/TEX_output.c index 7ce5ec88c48..140c31a7986 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_output.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_output.c @@ -83,28 +83,30 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) TexCallData *cdata = (TexCallData *)data; TexResult *target = cdata->target; - if(in[1]->hasinput && !in[0]->hasinput) - tex_do_preview(node, in[1], data); - else - tex_do_preview(node, in[0], data); - - if(!cdata->do_preview) { - if(cdata->which_output == node->custom1) - { - TexParams params; - params_from_cdata(¶ms, cdata); - - osa(tex_input_rgba, &target->tr, in[0], ¶ms, cdata->thread); - - target->tin = (target->tr + target->tg + target->tb) / 3.0f; - target->talpha = 1.0f; + if(cdata->do_preview) { + TexParams params; + params_from_cdata(¶ms, cdata); + + if(in[1]->hasinput && !in[0]->hasinput) + tex_input_rgba(&target->tr, in[1], ¶ms, cdata->thread); + else + tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread); + tex_do_preview(node, params.coord, &target->tr); + } + else if(cdata->which_output == node->custom1) { + TexParams params; + params_from_cdata(¶ms, cdata); - if(target->nor) { - if(in[1]->hasinput) - osa(tex_input_vec, target->nor, in[1], ¶ms, cdata->thread); - else - target->nor = 0; - } + osa(tex_input_rgba, &target->tr, in[0], ¶ms, cdata->thread); + + target->tin = (target->tr + target->tg + target->tb) / 3.0f; + target->talpha = 1.0f; + + if(target->nor) { + if(in[1]->hasinput) + osa(tex_input_vec, target->nor, in[1], ¶ms, cdata->thread); + else + target->nor = 0; } } } diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c index ce7324e2085..9f355e6d8f0 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c @@ -125,9 +125,8 @@ static int count_outputs(bNode *node) static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) \ { \ int outs = count_outputs(node); \ - if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn); \ - if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn); \ - if(outs >= 1) tex_do_preview(node, out[0], data); \ + if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn, data); \ + if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn, data); \ } diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c index bdf5a1ce079..2184d32fcf2 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c @@ -95,7 +95,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_rotate= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_scale.c b/source/blender/nodes/intern/TEX_nodes/TEX_scale.c index 3d4415365aa..205549c97d9 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_scale.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_scale.c @@ -56,7 +56,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_scale = { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c b/source/blender/nodes/intern/TEX_nodes/TEX_texture.c index 0ca80a82271..d0536a8fda8 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_texture.c @@ -79,9 +79,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_texture= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c index ba3dcfa27a2..c2f7377da3b 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c @@ -56,7 +56,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &colorfn); + tex_output(node, in, out[0], &colorfn, data); } bNodeType tex_node_translate = { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c b/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c index 75b88c3a460..6b8349e90af 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c @@ -72,9 +72,7 @@ static void normalfn(float *out, TexParams *p, bNode *node, bNodeStack **in, sho } static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &normalfn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &normalfn, data); } bNodeType tex_node_valtonor = { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c b/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c index 90a444bcff0..669f45ec89a 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c @@ -50,7 +50,7 @@ static void valtorgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack * static void valtorgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &valtorgb_colorfn); + tex_output(node, in, out[0], &valtorgb_colorfn, data); } static void valtorgb_init(bNode *node) @@ -97,9 +97,7 @@ static void rgbtobw_valuefn(float *out, TexParams *p, bNode *node, bNodeStack ** static void rgbtobw_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_output(node, in, out[0], &rgbtobw_valuefn); - - tex_do_preview(node, out[0], data); + tex_output(node, in, out[0], &rgbtobw_valuefn, data); } bNodeType tex_node_rgbtobw= { diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c b/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c index 2d29b03b38c..5ebd971d9fb 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c @@ -39,7 +39,16 @@ static bNodeSocketType outputs[]= { static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - tex_do_preview(node, in[0], data); + TexCallData *cdata = (TexCallData *)data; + + if(cdata->do_preview) { + TexParams params; + float col[4]; + params_from_cdata(¶ms, cdata); + + tex_input_rgba(col, in[0], ¶ms, cdata->thread); + tex_do_preview(node, params.coord, col); + } } bNodeType tex_node_viewer = { diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c index f2333ffcf2e..867bbd8c14e 100644 --- a/source/blender/nodes/intern/TEX_util.c +++ b/source/blender/nodes/intern/TEX_util.c @@ -49,8 +49,12 @@ void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread) { - if(dg->node->need_exec) + if(dg->node->need_exec) { dg->fn(out, params, dg->node, dg->in, thread); + + if(dg->cdata->do_preview) + tex_do_preview(dg->node, params->coord, out); + } } void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread) @@ -95,26 +99,6 @@ float tex_input_value(bNodeStack *in, TexParams *params, short thread) return out[0]; } -static void init_preview(bNode *node) -{ - int xsize = (int)(node->prvr.xmax - node->prvr.xmin); - int ysize = (int)(node->prvr.ymax - node->prvr.ymin); - - if(xsize == 0) { - xsize = PREV_RES; - ysize = PREV_RES; - } - - if(node->preview==NULL) - node->preview= MEM_callocN(sizeof(bNodePreview), "node preview"); - - if(node->preview->rect==NULL) { - node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect"); - node->preview->xsize= xsize; - node->preview->ysize= ysize; - } -} - void params_from_cdata(TexParams *out, TexCallData *in) { out->coord = in->coord; @@ -123,48 +107,19 @@ void params_from_cdata(TexParams *out, TexCallData *in) out->cfra = in->cfra; } -void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata) +void tex_do_preview(bNode *node, float *coord, float *col) { - int x, y; - float *result; - bNodePreview *preview; - float coord[3] = {0, 0, 0}; - TexParams params; - int resolution; - int xsize, ysize; - - if(!cdata->do_preview) - return; - - if(!(node->typeinfo->flag & NODE_PREVIEW)) - return; - - init_preview(node); - - preview = node->preview; - xsize = preview->xsize; - ysize = preview->ysize; - - params.dxt = 0; - params.dyt = 0; - params.cfra = cdata->cfra; - params.coord = coord; - - resolution = (xsize < ysize) ? xsize : ysize; - - for(x=0; xrect + 4 * (xsize*y + x); - - tex_input_rgba(result, ns, ¶ms, cdata->thread); + bNodePreview *preview= node->preview; + + if(preview) { + int xs= ((coord[0] + 1.0f)*0.5f)*preview->xsize; + int ys= ((coord[1] + 1.0f)*0.5f)*preview->ysize; + + nodeAddToPreview(node, col, xs, ys); } } -void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn) +void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata) { TexDelegate *dg; if(!out->data) @@ -173,7 +128,7 @@ void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn) else dg = out->data; - + dg->cdata= cdata; dg->fn = texfn; dg->node = node; memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*)); diff --git a/source/blender/nodes/intern/TEX_util.h b/source/blender/nodes/intern/TEX_util.h index fd3d47f4729..14e2773414a 100644 --- a/source/blender/nodes/intern/TEX_util.h +++ b/source/blender/nodes/intern/TEX_util.h @@ -87,6 +87,7 @@ typedef struct TexParams { typedef void(*TexFn) (float *out, TexParams *params, bNode *node, bNodeStack **in, short thread); typedef struct TexDelegate { + TexCallData *cdata; TexFn fn; bNode *node; bNodeStack *in[MAX_SOCKET]; @@ -99,8 +100,8 @@ void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread) void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread); float tex_input_value(bNodeStack *in, TexParams *params, short thread); -void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn); -void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata); +void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data); +void tex_do_preview(bNode *node, float *coord, float *col); void params_from_cdata(TexParams *out, TexCallData *in); diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index e5684e2ebe9..30ff213b95b 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -1306,7 +1306,7 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in shi->sample= sample; shi->thread= pa->thread; - shi->do_preview= R.r.scemode & R_NODE_PREVIEW; + shi->do_preview= (R.r.scemode & R_MATNODE_PREVIEW) != 0; shi->lay= rl->lay; shi->layflag= rl->layflag; shi->passflag= rl->passflag; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 7b0e5d8abbc..aee2d8d1866 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -721,7 +721,7 @@ static int evalnodes(Tex *tex, float *texvec, float *dxt, float *dyt, TexResult short rv = TEX_INT; bNodeTree *nodes = tex->nodetree; - ntreeTexExecTree(nodes, texres, texvec, dxt, dyt, thread, tex, which_output, R.r.cfra, (R.r.scemode & R_NODE_PREVIEW)); + ntreeTexExecTree(nodes, texres, texvec, dxt, dyt, thread, tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0); if(texres->nor) rv |= TEX_NOR; rv |= TEX_RGB; -- cgit v1.2.3 From 93b5375ca17a44fbe225f7af135dc0d647d32dd4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 15:16:08 +0000 Subject: Making new faces (fkey, scanfill etc) didnt create faces with the active material. Keep the editmesh material and active material in sync --- source/blender/editors/mesh/editmesh.c | 2 ++ source/blender/makesrna/intern/rna_object.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 980d699dda5..d540151337d 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -986,6 +986,8 @@ void load_editMesh(Scene *scene, Object *ob) CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface); mesh_update_customdata_pointers(me); + em->mat_nr= ob->actcol-1; + /* the vertices, use ->tmp.l as counter */ eve= em->verts.first; a= 0; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 3a3842adbf1..4fb2db42b8b 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -99,6 +99,8 @@ EnumPropertyItem object_type_items[] = { #include "BKE_particle.h" #include "BKE_scene.h" +#include "BLI_editVert.h" /* for EditMesh->mat_nr */ + #include "ED_object.h" void rna_Object_update(bContext *C, PointerRNA *ptr) @@ -404,6 +406,13 @@ static void rna_Object_active_material_index_set(PointerRNA *ptr, int value) { Object *ob= (Object*)ptr->id.data; ob->actcol= value+1; + + if(ob->mode==OB_MODE_EDIT && ob->type==OB_MESH) { + Mesh *me= ob->data; + + if(me->edit_mesh) + me->edit_mesh->mat_nr= value; + } } static void rna_Object_active_material_index_range(PointerRNA *ptr, int *min, int *max) -- cgit v1.2.3 From df63ccd904f28c3796f15ae14afcb18b45831fe9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 7 Oct 2009 16:10:06 +0000 Subject: Transform Mirror: * Make Ctrl+M key work for mirror in 3D view. * Fix mirror along global axis, was mirroring around all axes when the object was rotated, due to wrong matrix order, was also not working in 2.4. * Pressing e.g. X twice still doesn't go to local mode, would fix but don't know how the code is intended to work. --- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform_ops.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b109157d859..07aedf5e78e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2334,7 +2334,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) { float obsizemat[3][3]; // Reorient the size mat to fit the oriented object. - Mat3MulMat3(obsizemat, tmat, td->axismtx); + Mat3MulMat3(obsizemat, td->axismtx, tmat); //printmatrix3("obsizemat", obsizemat); TransMat3ToSize(obsizemat, td->axismtx, fsize); //printvecf("fsize", fsize); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 0440a957539..7ef8ad17a69 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -767,6 +767,8 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *key km = WM_keymap_add_item(keymap, "TFM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); RNA_boolean_set(km->ptr, "use", 1); + km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); + break; case SPACE_ACTION: km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0); @@ -837,7 +839,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *key km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); - km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, 0, 0); + km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); break; default: break; -- cgit v1.2.3 From 763358fe913c9ede43921f3ccc4cd6fdbfc5f809 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 16:32:55 +0000 Subject: copy icon in the material buttons list view so you can copy the current set of materials to other selected objects, (like Ctrl+L, Materials in 2.4x) --- release/scripts/ui/buttons_material.py | 1 + source/blender/blenkernel/BKE_material.h | 1 + source/blender/blenkernel/intern/material.c | 19 +++++++++++++ source/blender/editors/render/render_intern.h | 1 + source/blender/editors/render/render_ops.c | 1 + source/blender/editors/render/render_shading.c | 38 ++++++++++++++++++++++++++ 6 files changed, 61 insertions(+) diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index e91e324f49d..03e11e003e2 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -59,6 +59,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel): col = row.column(align=True) col.itemO("object.material_slot_add", icon='ICON_ZOOMIN', text="") col.itemO("object.material_slot_remove", icon='ICON_ZOOMOUT', text="") + col.itemO("object.material_slot_copy", icon='ICON_COPYDOWN', text="") if ob.mode == 'EDIT': row = layout.row(align=True) diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 382754ee2b2..b6645ef8737 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -58,6 +58,7 @@ short *give_totcolp(struct Object *ob); struct Material *give_current_material(struct Object *ob, int act); struct ID *material_from(struct Object *ob, int act); void assign_material(struct Object *ob, struct Material *ma, int act); +void assign_matarar(struct Object *ob, struct Material ***matar, int totcol); int find_material_index(struct Object *ob, struct Material *ma); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 7e742dc5631..b44c59baaca 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -625,6 +625,25 @@ void assign_material(Object *ob, Material *ma, int act) test_object_materials(ob->data); } +/* XXX - this calls many more update calls per object then are needed, could be optimized */ +void assign_matarar(struct Object *ob, struct Material ***matar, int totcol) +{ + int i, actcol_orig= ob->actcol; + + while(ob->totcol) + object_remove_material_slot(ob); + + /* now we have the right number of slots */ + for(i=0; i ob->totcol) + actcol_orig= ob->totcol; + + ob->actcol= actcol_orig; +} + + int find_material_index(Object *ob, Material *ma) { Material ***matarar; diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index dccc2d36002..d3ecbbc56e8 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -37,6 +37,7 @@ void OBJECT_OT_material_slot_remove(struct wmOperatorType *ot); void OBJECT_OT_material_slot_assign(struct wmOperatorType *ot); void OBJECT_OT_material_slot_select(struct wmOperatorType *ot); void OBJECT_OT_material_slot_deselect(struct wmOperatorType *ot); +void OBJECT_OT_material_slot_copy(struct wmOperatorType *ot); void MATERIAL_OT_new(struct wmOperatorType *ot); void TEXTURE_OT_new(struct wmOperatorType *ot); diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index 8b60582d466..7d35dff7493 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -43,6 +43,7 @@ void ED_operatortypes_render(void) WM_operatortype_append(OBJECT_OT_material_slot_assign); WM_operatortype_append(OBJECT_OT_material_slot_select); WM_operatortype_append(OBJECT_OT_material_slot_deselect); + WM_operatortype_append(OBJECT_OT_material_slot_copy); WM_operatortype_append(MATERIAL_OT_new); WM_operatortype_append(TEXTURE_OT_new); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 56605ad0970..26df0df935b 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -431,6 +431,44 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + +static int material_slot_copy_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Material ***matar; + + if(!ob || !(matar= give_matarar(ob))) + return OPERATOR_CANCELLED; + + CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) { + if(ob != ob_iter && give_matarar(ob_iter)) { + assign_matarar(ob_iter, matar, ob->totcol); + if(ob_iter->totcol==ob->totcol) { + ob_iter->actcol= ob->actcol; + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_iter); + } + } + } + CTX_DATA_END; + + return OPERATOR_FINISHED; +} + + +void OBJECT_OT_material_slot_copy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Material to Others"; + ot->idname= "OBJECT_OT_material_slot_copy"; + ot->description="Copies materials to other selected objects."; + + /* api callbacks */ + ot->exec= material_slot_copy_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /********************** new material operator *********************/ static int new_material_exec(bContext *C, wmOperator *op) -- cgit v1.2.3 From ef13a40fed9931cce7db389d50fda547f35a951c Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Wed, 7 Oct 2009 19:29:39 +0000 Subject: Makefile: Add missing raytrace directory. --- source/blender/render/intern/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/Makefile b/source/blender/render/intern/Makefile index 859a813bd2f..4fce37df175 100644 --- a/source/blender/render/intern/Makefile +++ b/source/blender/render/intern/Makefile @@ -29,6 +29,6 @@ # Bounces make to subdirectories. SOURCEDIR = source/blender/render/intern -DIRS = source +DIRS = source raytrace include nan_subdirs.mk -- cgit v1.2.3 From a4e36f24c74dfc825347752aae2e55e0247924ef Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 7 Oct 2009 20:55:14 +0000 Subject: [#19354] Second press of axis key didn't do local orientation when global was selected as user orientation (frankly, I don't like it much to have an exception for that, but backward compatibility is ok, unless someone else has a strong argument against). --- source/blender/editors/transform/transform.c | 17 ++++++++++------- source/blender/editors/transform/transform.h | 2 +- .../blender/editors/transform/transform_constraints.c | 5 ++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 07aedf5e78e..b5920210381 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -773,10 +773,11 @@ void transformEvent(TransInfo *t, wmEvent *event) stopConstraint(t); } else { + short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, (CON_AXIS0), "along %s X"); + setUserConstraint(t, orientation, (CON_AXIS0), "along %s X"); else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, (CON_AXIS1|CON_AXIS2), "locking %s X"); + setUserConstraint(t, orientation, (CON_AXIS1|CON_AXIS2), "locking %s X"); } } } @@ -805,10 +806,11 @@ void transformEvent(TransInfo *t, wmEvent *event) stopConstraint(t); } else { + short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, (CON_AXIS1), "along %s Y"); + setUserConstraint(t, orientation, (CON_AXIS1), "along %s Y"); else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, (CON_AXIS0|CON_AXIS2), "locking %s Y"); + setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y"); } } } @@ -833,10 +835,11 @@ void transformEvent(TransInfo *t, wmEvent *event) stopConstraint(t); } else { + short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, (CON_AXIS2), "along %s Z"); + setUserConstraint(t, orientation, (CON_AXIS2), "along %s Z"); else if ((t->modifiers & MOD_CONSTRAINT_PLANE) && ((t->flag & T_2D_EDIT)==0)) - setUserConstraint(t, (CON_AXIS0|CON_AXIS1), "locking %s Z"); + setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z"); } } else if ((t->flag & T_2D_EDIT)==0) { @@ -1511,7 +1514,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->con.mode |= CON_AXIS2; } - setUserConstraint(t, t->con.mode, "%s"); + setUserConstraint(t, t->current_orientation, t->con.mode, "%s"); } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 2c19bf932eb..ee6871d67bd 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -548,7 +548,7 @@ void drawConstraint(const struct bContext *C, TransInfo *t); void getConstraintMatrix(TransInfo *t); void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]); void setLocalConstraint(TransInfo *t, int mode, const char text[]); -void setUserConstraint(TransInfo *t, int mode, const char text[]); +void setUserConstraint(TransInfo *t, short orientation, int mode, const char text[]); void constraintNumInput(TransInfo *t, float vec[3]); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 158ea98c090..1143203217b 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -551,11 +551,10 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) { ftext is a format string passed to sprintf. It will add the name of the orientation where %s is (logically). */ -void setUserConstraint(TransInfo *t, int mode, const char ftext[]) { +void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) { char text[40]; - //short twmode= (t->spacetype==SPACE_VIEW3D)? ((View3D*)t->view)->twmode: V3D_MANIP_GLOBAL; - switch(t->current_orientation) { + switch(orientation) { case V3D_MANIP_GLOBAL: { float mtx[3][3]; -- cgit v1.2.3 From 0c857a4f1462a909b111ec4533e1c1f5ab54af4f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Oct 2009 21:19:35 +0000 Subject: - made ungrab a second function - WM_cursor_ungrab - ungrab can restore the position of the mouse clamped to the window bounds (much nicer for transform) --- intern/ghost/GHOST_C-api.h | 2 +- intern/ghost/GHOST_IWindow.h | 2 +- intern/ghost/intern/GHOST_C-api.cpp | 4 ++-- intern/ghost/intern/GHOST_Window.cpp | 4 ++-- intern/ghost/intern/GHOST_Window.h | 4 ++-- intern/ghost/intern/GHOST_WindowX11.cpp | 24 ++++++++++++++++++++-- intern/ghost/intern/GHOST_WindowX11.h | 2 +- .../blender/editors/interface/interface_handlers.c | 4 ++-- source/blender/windowmanager/WM_api.h | 3 ++- source/blender/windowmanager/intern/wm_cursors.c | 10 +++++++-- .../blender/windowmanager/intern/wm_event_system.c | 6 +++--- 11 files changed, 46 insertions(+), 19 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 35391d3f4cf..00d2cdb1e3b 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -376,7 +376,7 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, * @return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab, int warp); + int grab, int warp, int restore); /*************************************************************************************** ** Access to mouse button and keyboard states. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 44ddf9a7cfb..993b41a4d4f 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -271,7 +271,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; }; }; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index b86c4703ea2..e225ad4fd90 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -355,11 +355,11 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab, int warp) + int grab, int warp, int restore) { GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; - return window->setCursorGrab(grab?true:false, warp?true:false); + return window->setCursorGrab(grab?true:false, warp?true:false, restore?true:false); } diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 531674607d1..94feb83e003 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -98,12 +98,12 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } } -GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp) +GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore) { if(m_cursorGrabbed == grab) return GHOST_kSuccess; - if (setWindowCursorGrab(grab, warp)) { + if (setWindowCursorGrab(grab, warp, restore)) { m_cursorGrabbed = grab; return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 36e4bac6dae..786918716c5 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -175,7 +175,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp); + virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore); /** * Sets the window "modified" status, indicating unsaved changes @@ -247,7 +247,7 @@ protected: * Sets the cursor grab on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; }; /** * Sets the cursor shape on the window using diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index c2dc1048ea0..d197b534352 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1400,7 +1400,7 @@ setWindowCursorVisibility( GHOST_TSuccess GHOST_WindowX11:: setWindowCursorGrab( - bool grab, bool warp + bool grab, bool warp, bool restore ){ if(grab) { if(warp) { @@ -1416,7 +1416,27 @@ setWindowCursorGrab( if(m_cursorWarp) { /* are we exiting warp */ setWindowCursorVisibility(true); /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ - m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + if(restore) { + GHOST_Rect bounds; + GHOST_TInt32 x_new, y_new, x_rel, y_rel; + + getClientBounds(bounds); + + x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0]; + y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1]; + + screenToClient(x_new, y_new, x_rel, y_rel); + + if(x_rel < 0) x_new = (x_new-x_rel) + 2; + if(y_rel < 0) y_new = (y_new-y_rel) + 2; + if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2; + if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2; + m_system->setCursorPosition(x_new, y_new); + + } + else { + m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + } setCursorWarpAccum(0, 0); m_cursorWarp= false; diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 08fba3e2be8..eb0689ab410 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -256,7 +256,7 @@ protected: */ GHOST_TSuccess setWindowCursorGrab( - bool grab, bool warp + bool grab, bool warp, bool restore ); /** diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 385a0eec040..8dea3fa1fc3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3709,12 +3709,12 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s /* number editing */ if(state == BUTTON_STATE_NUM_EDITING) { if(ui_is_a_warp_but(but)) - WM_cursor_grab(CTX_wm_window(C), 1, 1); + WM_cursor_grab(CTX_wm_window(C), TRUE); ui_numedit_begin(but, data); } else if(data->state == BUTTON_STATE_NUM_EDITING) { ui_numedit_end(but, data); if(ui_is_a_warp_but(but)) - WM_cursor_grab(CTX_wm_window(C), 0, -1); + WM_cursor_ungrab(CTX_wm_window(C), FALSE); } /* menu open */ if(state == BUTTON_STATE_MENU_OPEN) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 321afec51b7..e7f5bb3b291 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -75,7 +75,8 @@ void WM_cursor_set (struct wmWindow *win, int curs); void WM_cursor_modal (struct wmWindow *win, int curs); void WM_cursor_restore (struct wmWindow *win); void WM_cursor_wait (int val); -void WM_cursor_grab (struct wmWindow *win, int val, int warp); +void WM_cursor_grab(struct wmWindow *win, int warp); +void WM_cursor_ungrab(wmWindow *win, int restore); void WM_timecursor (struct wmWindow *win, int nr); void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata); diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index d14cde56083..e33132d18b9 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -163,10 +163,16 @@ void WM_cursor_wait(int val) } } -void WM_cursor_grab(wmWindow *win, int val, int warp) +void WM_cursor_grab(wmWindow *win, int warp) { if(win) - GHOST_SetCursorGrab(win->ghostwin, val, warp); + GHOST_SetCursorGrab(win->ghostwin, 1, warp, -1); +} + +void WM_cursor_ungrab(wmWindow *win, int restore) +{ + if(win) + GHOST_SetCursorGrab(win->ghostwin, 0, -1, restore); } /* afer this you can call restore too */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 54841f0e063..086fdd3665b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -442,7 +442,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P else if(retval & OPERATOR_RUNNING_MODAL) { /* grab cursor during blocking modal ops (X11) */ if(ot->flag & OPTYPE_BLOCKING) - WM_cursor_grab(CTX_wm_window(C), 1, (U.uiflag & USER_CONTINUOUS_MOUSE)); + WM_cursor_grab(CTX_wm_window(C), (U.uiflag & USER_CONTINUOUS_MOUSE)); } else WM_operator_free(op); @@ -637,7 +637,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) CTX_wm_region_set(C, region); } - WM_cursor_grab(CTX_wm_window(C), 0, -1); + WM_cursor_ungrab(CTX_wm_window(C), TRUE); WM_operator_free(handler->op); } else if(handler->ui_remove) { @@ -835,7 +835,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* remove modal handler, operator itself should have been cancelled and freed */ if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) { - WM_cursor_grab(CTX_wm_window(C), 0, -1); + WM_cursor_ungrab(CTX_wm_window(C), TRUE); BLI_remlink(handlers, handler); wm_event_free_handler(handler); -- cgit v1.2.3 From 1b7e5b9abe7c2431d1572cd39d687a139e7acb9a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 7 Oct 2009 21:39:24 +0000 Subject: WM: test with context-less add notifier. Notifiers are one of the main reasons for passing along context, while actually they don't need much context at all. Might be removed again, but would like to have this especially for RNA API functions. --- source/blender/windowmanager/WM_api.h | 3 ++- .../blender/windowmanager/intern/wm_event_system.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e7f5bb3b291..0054f151803 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -126,7 +126,8 @@ void WM_event_remove_handlers(struct bContext *C, ListBase *handlers); void WM_event_add_mousemove(struct bContext *C); int WM_modal_tweak_exit(struct wmEvent *evt, int tweak_event); -void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *data); +void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference); +void WM_main_add_notifier(unsigned int type, void *reference); void wm_event_add (struct wmWindow *win, struct wmEvent *event_to_add); /* XXX only for warning */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 086fdd3665b..4a8aac4525d 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -45,6 +45,7 @@ #include "BKE_context.h" #include "BKE_idprop.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_object.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -118,6 +119,26 @@ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference note->reference= reference; } +void WM_main_add_notifier(unsigned int type, void *reference) +{ + Main *bmain= G.main; + wmWindowManager *wm= bmain->wm.first; + + if(wm) { + wmNotifier *note= MEM_callocN(sizeof(wmNotifier), "notifier"); + + note->wm= wm; + BLI_addtail(¬e->wm->queue, note); + + note->category= type & NOTE_CATEGORY; + note->data= type & NOTE_DATA; + note->subtype= type & NOTE_SUBTYPE; + note->action= type & NOTE_ACTION; + + note->reference= reference; + } +} + static wmNotifier *wm_notifier_next(wmWindowManager *wm) { wmNotifier *note= wm->queue.first; -- cgit v1.2.3 From fd511eb984a23b63b373e171666667c8213579c0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 7 Oct 2009 22:05:30 +0000 Subject: Node Bugfixes: * Compo node backdrop works again. * Compo node previews and backdrop now get correct color management float to byte conversion. * Compo nodes got unecessarily recalculated while moving nodes. * Fix compo node viewer nodes not getting activated correctly. * Main compo node preview render computations are now outside of mutex lock, so better for multithreading. * Tex node outputs did not work in some files loaded from 2.4. * Change RNA updates to take into account groups that may be shared between multiple node trees. --- source/blender/blenkernel/intern/node.c | 7 +- source/blender/editors/include/ED_node.h | 3 +- source/blender/editors/space_node/drawnode.c | 18 ++++- source/blender/editors/space_node/node_draw.c | 45 +++++++----- source/blender/editors/space_node/node_edit.c | 85 ++++++++++++++-------- source/blender/editors/space_node/node_intern.h | 3 +- source/blender/editors/space_view3d/view3d_draw.c | 2 + source/blender/editors/transform/transform.c | 2 +- source/blender/makesdna/DNA_node_types.h | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 37 +++++++++- source/blender/nodes/intern/CMP_nodes/CMP_blur.c | 2 +- .../nodes/intern/CMP_nodes/CMP_channelMatte.c | 2 +- .../nodes/intern/CMP_nodes/CMP_chromaMatte.c | 2 +- .../nodes/intern/CMP_nodes/CMP_colorMatte.c | 2 +- .../blender/nodes/intern/CMP_nodes/CMP_composite.c | 4 +- .../blender/nodes/intern/CMP_nodes/CMP_diffMatte.c | 2 +- .../nodes/intern/CMP_nodes/CMP_distanceMatte.c | 2 +- source/blender/nodes/intern/CMP_nodes/CMP_filter.c | 2 +- source/blender/nodes/intern/CMP_nodes/CMP_image.c | 4 +- source/blender/nodes/intern/CMP_nodes/CMP_levels.c | 2 +- .../nodes/intern/CMP_nodes/CMP_lummaMatte.c | 2 +- source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c | 2 +- .../nodes/intern/CMP_nodes/CMP_outputFile.c | 2 +- .../nodes/intern/CMP_nodes/CMP_splitViewer.c | 2 +- .../blender/nodes/intern/CMP_nodes/CMP_texture.c | 2 +- source/blender/nodes/intern/CMP_nodes/CMP_viewer.c | 4 +- source/blender/nodes/intern/CMP_util.c | 39 +++++++--- source/blender/nodes/intern/CMP_util.h | 2 +- source/blender/nodes/intern/TEX_nodes/TEX_output.c | 29 ++++---- source/blender/nodes/intern/TEX_util.c | 4 - 30 files changed, 205 insertions(+), 111 deletions(-) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index fad866a7201..1a89de7e8d6 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1246,9 +1246,12 @@ void nodeAddToPreview(bNode *node, float *col, int x, int y) if(preview) { if(x>=0 && y>=0) { if(xxsize && yysize) { - float *tar= preview->rect+ 4*((preview->xsize*y) + x); + unsigned char *tar= preview->rect+ 4*((preview->xsize*y) + x); //if(tar[0]==0.0f) { - QUATCOPY(tar, col); + tar[0]= FTOCHAR(col[0]); + tar[1]= FTOCHAR(col[1]); + tar[2]= FTOCHAR(col[2]); + tar[3]= FTOCHAR(col[3]); //} } //else printf("prv out bound x y %d %d\n", x, y); diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 305b2a64ffe..667a4ecb144 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -33,12 +33,13 @@ struct Scene; struct Tex; struct bContext; struct bNode; +struct ID; /* drawnode.c */ void ED_init_node_butfuncs(void); /* node_draw.c */ -void ED_node_changed_update(struct bContext *C, struct bNode *node); +void ED_node_changed_update(struct ID *id, struct bNode *node); /* node_edit.c */ void ED_node_shader_default(struct Material *ma); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index b8da42079c4..33be0b83f20 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -89,6 +89,7 @@ #include "UI_resources.h" #include "RE_pipeline.h" +#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "node_intern.h" @@ -2106,12 +2107,13 @@ void node_rename_but(char *s) #endif -void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode) +void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage) { if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) { Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); - ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + void *lock; + ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock); if(ibuf) { float x, y; @@ -2126,13 +2128,21 @@ void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode) x = (ar->winx-ibuf->x)/2 + snode->xof; y = (ar->winy-ibuf->y)/2 + snode->yof; + if(!ibuf->rect) { + if(color_manage) + ibuf->profile= IB_PROFILE_SRGB; + else + ibuf->profile = IB_PROFILE_NONE; + IMB_rect_from_float(ibuf); + } + if(ibuf->rect) glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - else if(ibuf->channels==4) - glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float); wmPopMatrix(); } + + BKE_image_release_ibuf(ima, lock); } } diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index dd2dc0d796a..26601958c8a 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -95,19 +95,19 @@ extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select); extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); extern void ui_draw_tria_icon(float x, float y, float aspect, char dir); -void ED_node_changed_update(bContext *C, bNode *node) +void ED_node_changed_update(ID *id, bNode *node) { - SpaceNode *snode= CTX_wm_space_node(C); + bNodeTree *nodetree, *edittree; + int treetype; - if(!snode) - return; + node_tree_from_ID(id, &nodetree, &edittree, &treetype); - if(snode->treetype==NTREE_SHADER) { - DAG_id_flush_update(snode->id, 0); - WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id); + if(treetype==NTREE_SHADER) { + DAG_id_flush_update(id, 0); + WM_main_add_notifier(NC_MATERIAL|ND_SHADING, id); } - else if(snode->treetype==NTREE_COMPOSIT) { - NodeTagChanged(snode->edittree, node); + else if(treetype==NTREE_COMPOSIT) { + NodeTagChanged(edittree, node); /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */ /* not the best implementation of the world... but we need it to work now :) */ @@ -122,23 +122,26 @@ void ED_node_changed_update(bContext *C, bNode *node) //addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); } else { - node= node_tree_get_editgroup(snode->nodetree); + node= node_tree_get_editgroup(nodetree); if(node) - NodeTagIDChanged(snode->nodetree, node->id); + NodeTagIDChanged(nodetree, node->id); } - WM_event_add_notifier(C, NC_SCENE|ND_NODES, CTX_data_scene(C)); + + WM_main_add_notifier(NC_SCENE|ND_NODES, id); } - else if(snode->treetype==NTREE_TEXTURE) { - DAG_id_flush_update(snode->id, 0); - WM_event_add_notifier(C, NC_TEXTURE|ND_NODES, snode->id); + else if(treetype==NTREE_TEXTURE) { + DAG_id_flush_update(id, 0); + WM_main_add_notifier(NC_TEXTURE|ND_NODES, id); } - } static void do_node_internal_buttons(bContext *C, void *node_v, int event) { - if(event==B_NODE_EXEC) - ED_node_changed_update(C, node_v); + if(event==B_NODE_EXEC) { + SpaceNode *snode= CTX_wm_space_node(C); + if(snode && snode->id) + ED_node_changed_update(snode->id, node_v); + } } @@ -648,7 +651,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); /* premul graphics */ glColor4f(1.0, 1.0, 1.0, 1.0); - glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_FLOAT, preview->rect); + glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_UNSIGNED_BYTE, preview->rect); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glDisable(GL_BLEND); @@ -1075,6 +1078,8 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) float col[3]; View2DScrollers *scrollers; SpaceNode *snode= CTX_wm_space_node(C); + Scene *scene= CTX_data_scene(C); + int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; UI_GetThemeColor3fv(TH_BACK, col); glClearColor(col[0], col[1], col[2], 0); @@ -1094,7 +1099,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) UI_view2d_constant_grid_draw(C, v2d); /* backdrop */ - draw_nodespace_back_pix(ar, snode); + draw_nodespace_back_pix(ar, snode, color_manage); /* nodes */ snode_set_context(snode, CTX_data_scene(C)); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 50a99650ec0..cee90b5a148 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -62,8 +62,6 @@ #include "BKE_scene.h" #include "BKE_utildefines.h" -#include "ED_render.h" - #include "BIF_gl.h" #include "BLI_arithb.h" @@ -74,8 +72,10 @@ #include "IMB_imbuf_types.h" -#include "ED_space_api.h" +#include "ED_node.h" +#include "ED_render.h" #include "ED_screen.h" +#include "ED_space_api.h" #include "ED_transform.h" #include "ED_types.h" @@ -581,13 +581,45 @@ void ED_node_texture_default(Tex *tx) ntreeSolveOrder(tx->nodetree); /* needed for pointers */ } +void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype) +{ + bNode *node; + short idtype= GS(id->name); + + if(idtype == ID_MA) { + *ntree= ((Material*)id)->nodetree; + if(treetype) *treetype= NTREE_SHADER; + } + else if(idtype == ID_SCE) { + *ntree= ((Scene*)id)->nodetree; + if(treetype) *treetype= NTREE_COMPOSIT; + } + else if(idtype == ID_TE) { + *ntree= ((Tex*)id)->nodetree; + if(treetype) *treetype= NTREE_TEXTURE; + } + + /* find editable group */ + if(edittree) { + if(*ntree) + for(node= (*ntree)->nodes.first; node; node= node->next) + if(node->flag & NODE_GROUP_EDIT) + break; + + if(node && node->id) + *edittree= (bNodeTree *)node->id; + else + *edittree= *ntree; + } +} + /* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */ void snode_set_context(SpaceNode *snode, Scene *scene) { Object *ob= OBACT; - bNode *node= NULL; snode->nodetree= NULL; + snode->edittree= NULL; snode->id= snode->from= NULL; if(snode->treetype==NTREE_SHADER) { @@ -597,7 +629,6 @@ void snode_set_context(SpaceNode *snode, Scene *scene) if(ma) { snode->from= &ob->id; snode->id= &ma->id; - snode->nodetree= ma->nodetree; } } } @@ -608,8 +639,6 @@ void snode_set_context(SpaceNode *snode, Scene *scene) /* bit clumsy but reliable way to see if we draw first time */ if(snode->nodetree==NULL) ntreeCompositForceHidden(scene->nodetree, scene); - - snode->nodetree= scene->nodetree; } else if(snode->treetype==NTREE_TEXTURE) { Tex *tx= NULL; @@ -648,22 +677,11 @@ void snode_set_context(SpaceNode *snode, Scene *scene) tx= mtex->tex; } - if(tx) { - snode->id= &tx->id; - snode->nodetree= tx->nodetree; - } + snode->id= &tx->id; } - - /* find editable group */ - if(snode->nodetree) - for(node= snode->nodetree->nodes.first; node; node= node->next) - if(node->flag & NODE_GROUP_EDIT) - break; - - if(node && node->id) - snode->edittree= (bNodeTree *)node->id; - else - snode->edittree= snode->nodetree; + + if(snode->id) + node_tree_from_ID(snode->id, &snode->nodetree, &snode->edittree, NULL); } #if 0 @@ -691,15 +709,13 @@ static void node_active_image(Image *ima) void node_set_active(SpaceNode *snode, bNode *node) { - nodeSetActive(snode->edittree, node); - #if 0 - // XXX if(node->type!=NODE_GROUP) { - /* tree specific activate calls */ if(snode->treetype==NTREE_SHADER) { + // XXX +#if 0 /* when we select a material, active texture is cleared, for buttons */ if(node->id && GS(node->id->name)==ID_MA) @@ -709,8 +725,11 @@ void node_set_active(SpaceNode *snode, bNode *node) // allqueue(REDRAWBUTSSHADING, 1); // allqueue(REDRAWIPO, 0); +#endif } else if(snode->treetype==NTREE_COMPOSIT) { + Scene *scene= (Scene*)snode->id; + /* make active viewer, currently only 1 supported... */ if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { bNode *tnode; @@ -731,31 +750,37 @@ void node_set_active(SpaceNode *snode, bNode *node) if(gnode) NodeTagIDChanged(snode->nodetree, gnode->id); - // XXX snode_handle_recalc(snode); + ED_node_changed_update(snode->id, node); } /* addnode() doesnt link this yet... */ node->id= (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); } else if(node->type==CMP_NODE_IMAGE) { + // XXX +#if 0 if(node->id) node_active_image((Image *)node->id); +#endif } else if(node->type==CMP_NODE_R_LAYERS) { - if(node->id==NULL || node->id==(ID *)G.scene) { - G.scene->r.actlay= node->custom1; + if(node->id==NULL || node->id==(ID *)scene) { + scene->r.actlay= node->custom1; + // XXX // allqueue(REDRAWBUTSSCENE, 0); } } } else if(snode->treetype==NTREE_TEXTURE) { + // XXX +#if 0 if(node->id) ; // XXX BIF_preview_changed(-1); // allqueue(REDRAWBUTSSHADING, 1); // allqueue(REDRAWIPO, 0); +#endif } } - #endif /* 0 */ } /* ***************** Edit Group operator ************* */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 2a929472c68..9f28a5e3dcb 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -69,9 +69,10 @@ void NODE_OT_select_border(struct wmOperatorType *ot); void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int do_shaded); int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol); -void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode); +void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage); /* node_edit.c */ +void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype); void snode_handle_recalc(bContext *C, SpaceNode *snode); bNode *next_node(bNodeTree *ntree); bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float locy); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 5612e60e899..06d0832cb8b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1961,6 +1961,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) v3d->zbuf= TRUE; glEnable(GL_DEPTH_TEST); } + else + v3d->zbuf= FALSE; // needs to be done always, gridview is adjusted in drawgrid() now v3d->gridview= v3d->grid; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b5920210381..839c3543515 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -322,7 +322,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t) else if(t->spacetype == SPACE_NODE) { //ED_area_tag_redraw(t->sa); - WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE, NULL); } else if(t->spacetype == SPACE_SEQ) { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index e70221df9ab..ba1bb66c901 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -99,7 +99,7 @@ typedef struct bNodeSocket { # # typedef struct bNodePreview { - float *rect; + unsigned char *rect; short xsize, ysize; } bNodePreview; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index ebd032bb0b1..4547362e235 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -31,10 +31,12 @@ #include "rna_internal.h" +#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" +#include "BKE_main.h" #include "BKE_node.h" #include "BKE_image.h" @@ -140,11 +142,42 @@ static char *rna_Node_path(PointerRNA *ptr) return BLI_sprintfN("nodes[%d]", index); } +static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup) +{ + bNode *node; + + if(ntree == lookup) + return 1; + + for(node=ntree->nodes.first; node; node=node->next) + if(node->type == NODE_GROUP && node->id) + if(has_nodetree((bNodeTree*)node->id, lookup)) + return 1; + + return 0; +} + static void rna_Node_update(bContext *C, PointerRNA *ptr) { + Main *bmain= CTX_data_main(C); + bNodeTree *ntree= (bNodeTree*)ptr->id.data; bNode *node= (bNode*)ptr->data; - - ED_node_changed_update(C, node); + Material *ma; + Tex *tex; + Scene *sce; + + /* look through all datablocks, to support groups */ + for(ma=bmain->mat.first; ma; ma=ma->id.next) + if(ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree)) + ED_node_changed_update(&ma->id, node); + + for(tex=bmain->tex.first; tex; tex=tex->id.next) + if(tex->nodetree && tex->use_nodes && has_nodetree(tex->nodetree, ntree)) + ED_node_changed_update(&tex->id, node); + + for(sce=bmain->scene.first; sce; sce=sce->id.next) + if(sce->nodetree && sce->use_nodes && has_nodetree(sce->nodetree, ntree)) + ED_node_changed_update(&sce->id, node); } static void rna_Node_update_name(bContext *C, PointerRNA *ptr) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c index a96f3489978..68ccb04581b 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c @@ -671,7 +671,7 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN free_compbuf(img); } - generate_preview(node, out[0]->data); + generate_preview(data, node, out[0]->data); } static void node_composit_init_blur(bNode* node) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c index b0a2531ac1f..ac940d76ed6 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_channelMatte.c @@ -166,7 +166,7 @@ static void node_composit_exec_channel_matte(void *data, bNode *node, bNodeStack break; } - generate_preview(node, outbuf); + generate_preview(data, node, outbuf); out[0]->data=outbuf; if(out[1]->hasoutput) out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c index 28b81fe9f47..c8cbe4538c5 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c @@ -154,7 +154,7 @@ static void node_composit_exec_chroma_matte(void *data, bNode *node, bNodeStack if(out[1]->hasoutput) out[1]->data= valbuf_from_rgbabuf(chromabuf, CHAN_A); - generate_preview(node, chromabuf); + generate_preview(data, node, chromabuf); if(cbuf!=in[0]->data) free_compbuf(cbuf); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c index 470d04d9dcc..e1fa4d78b96 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_colorMatte.c @@ -95,7 +95,7 @@ static void node_composit_exec_color_matte(void *data, bNode *node, bNodeStack * if(out[1]->hasoutput) out[1]->data= valbuf_from_rgbabuf(colorbuf, CHAN_A); - generate_preview(node, colorbuf); + generate_preview(data, node, colorbuf); if(cbuf!=in[0]->data) free_compbuf(cbuf); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c index 800cccc2bfc..d117a3cb235 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c @@ -73,7 +73,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i zbuf->malloc= 0; free_compbuf(zbuf); } - generate_preview(node, outbuf); + generate_preview(data, node, outbuf); /* we give outbuf to rr... */ rr->rectf= outbuf->rect; @@ -91,7 +91,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i } } if(in[0]->data) - generate_preview(node, in[0]->data); + generate_preview(data, node, in[0]->data); } bNodeType cmp_node_composite= { diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c index 68a1bcd5471..d36d586211b 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_diffMatte.c @@ -108,7 +108,7 @@ static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack ** out[0]->data=outbuf; if(out[1]->hasoutput) out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A); - generate_preview(node, outbuf); + generate_preview(data, node, outbuf); if(imbuf1!=in[0]->data) free_compbuf(imbuf1); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c index f24aedd6661..27b1ac1e181 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_distanceMatte.c @@ -111,7 +111,7 @@ static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStac out[0]->data=workbuf; if(out[1]->hasoutput) out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A); - generate_preview(node, workbuf); + generate_preview(data, node, workbuf); if(inbuf!=in[0]->data) free_compbuf(inbuf); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_filter.c b/source/blender/nodes/intern/CMP_nodes/CMP_filter.c index 2c3b78e13a3..8300c791698 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_filter.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_filter.c @@ -212,7 +212,7 @@ static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, out[0]->data= stackbuf; - generate_preview(node, out[0]->data); + generate_preview(data, node, out[0]->data); } } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index 00be52a81aa..5e22f5cf016 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -254,7 +254,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b if(out[1]->hasoutput) out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); - generate_preview(node, stackbuf); + generate_preview(data, node, stackbuf); } } }; @@ -386,7 +386,7 @@ static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty); - generate_preview(node, stackbuf); + generate_preview(data, node, stackbuf); } } } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c index 6056e9a28f4..f0e314793ed 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_levels.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_levels.c @@ -305,7 +305,7 @@ static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack * if(out[1]->hasoutput) out[1]->vec[0]= std_dev; - generate_preview(node, histogram); + generate_preview(data, node, histogram); if(cbuf!=in[0]->data) free_compbuf(cbuf); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c index 350def76736..3e284cd5ed1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_lummaMatte.c @@ -87,7 +87,7 @@ static void node_composit_exec_luma_matte(void *data, bNode *node, bNodeStack ** composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_luma_matte, CB_RGBA); composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA); - generate_preview(node, outbuf); + generate_preview(data, node, outbuf); out[0]->data=outbuf; if (out[1]->hasoutput) out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c b/source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c index ca6de027b1d..25bb82b4a9f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_mixrgb.c @@ -74,7 +74,7 @@ static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, out[0]->data= stackbuf; - generate_preview(node, out[0]->data); + generate_preview(data, node, out[0]->data); } } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c b/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c index 8c63c348b57..e63e5802507 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_outputFile.c @@ -71,7 +71,7 @@ static void node_composit_exec_output_file(void *data, bNode *node, bNodeStack * IMB_freeImBuf(ibuf); - generate_preview(node, cbuf); + generate_preview(data, node, cbuf); if(in[0]->data != cbuf) free_compbuf(cbuf); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c b/source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c index 8ce5a7caa04..04383f478e9 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_splitViewer.c @@ -121,7 +121,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack * composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL); - generate_preview(node, cbuf); + generate_preview(data, node, cbuf); free_compbuf(cbuf); free_compbuf(mask); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c index b4d04076032..26e734579e3 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c @@ -105,7 +105,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, VECCOPY(prevbuf->procedural_size, in[1]->vec); prevbuf->procedural_type= CB_RGBA; composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA); - generate_preview(node, prevbuf); + generate_preview(data, node, prevbuf); free_compbuf(prevbuf); if(out[0]->hasoutput) { diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c b/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c index c9e95e768c1..d0dcc5c6973 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c @@ -106,12 +106,12 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, free_compbuf(zbuf); } - generate_preview(node, cbuf); + generate_preview(data, node, cbuf); free_compbuf(cbuf); } else if(in[0]->data) { - generate_preview(node, in[0]->data); + generate_preview(data, node, in[0]->data); } } diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c index 075eefb4368..175a0a54371 100644 --- a/source/blender/nodes/intern/CMP_util.c +++ b/source/blender/nodes/intern/CMP_util.c @@ -604,9 +604,13 @@ static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy) return outbuf; } -void generate_preview(bNode *node, CompBuf *stackbuf) +void generate_preview(void *data, bNode *node, CompBuf *stackbuf) { + RenderData *rd= data; bNodePreview *preview= node->preview; + int xsize, ysize; + int color_manage= rd->color_mgt_flag & R_COLOR_MANAGEMENT; + unsigned char *rect; if(preview && stackbuf) { CompBuf *cbuf, *stackbuf_use; @@ -615,30 +619,41 @@ void generate_preview(bNode *node, CompBuf *stackbuf) stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA); - BLI_lock_thread(LOCK_PREVIEW); - if(stackbuf->x > stackbuf->y) { - preview->xsize= 140; - preview->ysize= (140*stackbuf->y)/stackbuf->x; + xsize= 140; + ysize= (140*stackbuf->y)/stackbuf->x; } else { - preview->ysize= 140; - preview->xsize= (140*stackbuf->x)/stackbuf->y; + ysize= 140; + xsize= (140*stackbuf->x)/stackbuf->y; } if(stackbuf_use->rect_procedural) - cbuf= generate_procedural_preview(stackbuf_use, preview->xsize, preview->ysize); + cbuf= generate_procedural_preview(stackbuf_use, xsize, ysize); else - cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize); + cbuf= scalefast_compbuf(stackbuf_use, xsize, ysize); - /* this ensures free-compbuf does the right stuff */ - SWAP(float *, cbuf->rect, node->preview->rect); + /* convert to byte for preview */ + rect= MEM_callocN(sizeof(unsigned char)*4*xsize*ysize, "bNodePreview.rect"); - BLI_unlock_thread(LOCK_PREVIEW); + if(color_manage) + floatbuf_to_srgb_byte(cbuf->rect, rect, 0, xsize, 0, ysize, xsize); + else + floatbuf_to_byte(cbuf->rect, rect, 0, xsize, 0, ysize, xsize); free_compbuf(cbuf); if(stackbuf_use!=stackbuf) free_compbuf(stackbuf_use); + + BLI_lock_thread(LOCK_PREVIEW); + + if(preview->rect) + MEM_freeN(preview->rect); + preview->xsize= xsize; + preview->ysize= ysize; + preview->rect= rect; + + BLI_unlock_thread(LOCK_PREVIEW); } } diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 2a2dc97ed73..bb08a448bf4 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -141,7 +141,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 generate_preview(bNode *node, CompBuf *stackbuf); +void generate_preview(void *data, bNode *node, CompBuf *stackbuf); void do_copy_rgba(bNode *node, float *out, float *in); void do_copy_rgb(bNode *node, float *out, float *in); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_output.c b/source/blender/nodes/intern/TEX_nodes/TEX_output.c index 140c31a7986..580b4cde8bf 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_output.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_output.c @@ -93,20 +93,23 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread); tex_do_preview(node, params.coord, &target->tr); } - else if(cdata->which_output == node->custom1) { - TexParams params; - params_from_cdata(¶ms, cdata); + else { + /* 0 means don't care, so just use first */ + if(cdata->which_output == node->custom1 || (cdata->which_output == 0 && node->custom1 == 1)) { + TexParams params; + params_from_cdata(¶ms, cdata); + + osa(tex_input_rgba, &target->tr, in[0], ¶ms, cdata->thread); - osa(tex_input_rgba, &target->tr, in[0], ¶ms, cdata->thread); - - target->tin = (target->tr + target->tg + target->tb) / 3.0f; - target->talpha = 1.0f; - - if(target->nor) { - if(in[1]->hasinput) - osa(tex_input_vec, target->nor, in[1], ¶ms, cdata->thread); - else - target->nor = 0; + target->tin = (target->tr + target->tg + target->tb) / 3.0f; + target->talpha = 1.0f; + + if(target->nor) { + if(in[1]->hasinput) + osa(tex_input_vec, target->nor, in[1], ¶ms, cdata->thread); + else + target->nor = 0; + } } } } diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c index 867bbd8c14e..8b247688e8c 100644 --- a/source/blender/nodes/intern/TEX_util.c +++ b/source/blender/nodes/intern/TEX_util.c @@ -176,10 +176,6 @@ void ntreeTexExecTree( TexResult dummy_texres; TexCallData data; - /* 0 means don't care, so just use first */ - if(which_output == 0) - which_output = 1; - if(!texres) texres = &dummy_texres; data.coord = coord; data.dxt = dxt; -- cgit v1.2.3 From 475ab5ceb4875eb37dd761f7a71ff569dd493395 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 8 Oct 2009 00:57:00 +0000 Subject: Rotation Modes Bugfix: Animating rotations using different rotation modes should now work more often than before. Previously, quaternion and axis-angle values were stored in the same variable in DNA, but that was causing problems with other animation curves overwriting the values and causing the rotations to not work as expected. There are still some issues, but I'll track those down later tonight --- source/blender/blenkernel/BKE_armature.h | 2 +- source/blender/blenkernel/intern/action.c | 10 +++-- source/blender/blenkernel/intern/armature.c | 28 ++++-------- source/blender/blenkernel/intern/object.c | 8 ++-- .../blender/editors/animation/keyframes_general.c | 1 + source/blender/editors/armature/editarmature.c | 49 +++++++++++++++------ source/blender/editors/armature/poseobject.c | 14 +++--- source/blender/editors/object/object_transform.c | 50 ++++++++++++++++------ .../blender/editors/space_view3d/view3d_buttons.c | 4 +- .../editors/transform/transform_conversions.c | 4 +- source/blender/makesdna/DNA_action_types.h | 11 +++-- source/blender/makesdna/DNA_object_types.h | 6 ++- source/blender/makesrna/intern/rna_object.c | 30 +++++++++++-- source/blender/makesrna/intern/rna_pose.c | 32 +++++++++++--- 14 files changed, 172 insertions(+), 77 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index e5d0c4274b3..8f109034e3e 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -104,7 +104,7 @@ void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float * void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]); /* Rotation Mode Conversions - Used for PoseChannels + Objects... */ -void BKE_rotMode_change_values(float quat[4], float eul[3], short oldMode, short newMode); +void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode); /* B-Bone support */ typedef struct Mat4 { diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 7be763eae9d..25f539a1992 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -446,7 +446,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name) strncpy(chan->name, name, 31); /* init vars to prevent math errors */ - chan->quat[0] = 1.0f; + chan->quat[0] = chan->rotAxis[1]= 1.0f; chan->size[0] = chan->size[1] = chan->size[2] = 1.0f; chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f; @@ -607,6 +607,8 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan VECCOPY(pchan->loc, chan->loc); VECCOPY(pchan->size, chan->size); VECCOPY(pchan->eul, chan->eul); + VECCOPY(pchan->rotAxis, chan->rotAxis); + pchan->rotAngle= chan->rotAngle; QUATCOPY(pchan->quat, chan->quat); pchan->rotmode= chan->rotmode; Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat); @@ -975,14 +977,16 @@ void rest_pose(bPose *pose) memset(pose->stride_offset, 0, sizeof(pose->stride_offset)); memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset)); - for (pchan=pose->chanbase.first; pchan; pchan= pchan->next){ + for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) { for (i=0; i<3; i++) { pchan->loc[i]= 0.0f; pchan->quat[i+1]= 0.0f; pchan->eul[i]= 0.0f; pchan->size[i]= 1.0f; + pchan->rotAxis[i]= 0.0f; } - pchan->quat[0]= 1.0f; + pchan->quat[0]= pchan->rotAxis[1]= 1.0f; + pchan->rotAngle= 0.0f; pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE); } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 6220835a620..a0abe780273 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1285,16 +1285,14 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float /* Called from RNA when rotation mode changes * - the result should be that the rotations given in the provided pointers have had conversions * applied (as appropriate), such that the rotation of the element hasn't 'visually' changed - * - * - as in SDNA data, quat is used to store quaternions AND axis-angle rotations... */ -void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, short newMode) +void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float angle[3], short oldMode, short newMode) { /* check if any change - if so, need to convert data */ if (newMode > 0) { /* to euler */ if (oldMode == ROT_MODE_AXISANGLE) { /* axis-angle to euler */ - AxisAngleToEulO(&quat[1], quat[0], eul, newMode); + AxisAngleToEulO(axis, *angle, eul, newMode); } else if (oldMode == ROT_MODE_QUAT) { /* quat to euler */ @@ -1305,11 +1303,7 @@ void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, shor else if (newMode == ROT_MODE_QUAT) { /* to quat */ if (oldMode == ROT_MODE_AXISANGLE) { /* axis angle to quat */ - float q[4]; - - /* copy to temp var first, since quats and axis-angle are stored in same place */ - QuatCopy(q, quat); - AxisAngleToQuat(q, &quat[1], quat[0]); + AxisAngleToQuat(quat, axis, *angle); } else if (oldMode > 0) { /* euler to quat */ @@ -1317,24 +1311,20 @@ void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, shor } /* else { no conversion needed } */ } - else { /* to axis-angle */ + else if (newMode == ROT_MODE_AXISANGLE) { /* to axis-angle */ if (oldMode > 0) { /* euler to axis angle */ EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]); } else if (oldMode == ROT_MODE_QUAT) { /* quat to axis angle */ - float q[4]; - - /* copy to temp var first, since quats and axis-angle are stored in same place */ - QuatCopy(q, quat); - QuatToAxisAngle(q, &quat[1], &quat[0]); + QuatToAxisAngle(quat, axis, angle); } /* when converting to axis-angle, we need a special exception for the case when there is no axis */ - if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) { + if (IS_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) { /* for now, rotate around y-axis then (so that it simply becomes the roll) */ - quat[2]= 1.0f; + axis[1]= 1.0f; } } } @@ -1651,8 +1641,8 @@ void chan_calc_mat(bPoseChannel *chan) EulOToMat3(chan->eul, chan->rotmode, rmat); } else if (chan->rotmode == ROT_MODE_AXISANGLE) { - /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ - AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat); + /* axis-angle - not really that great for 3D-changing orientations */ + AxisAngleToMat3(chan->rotAxis, chan->rotAngle, rmat); } else { /* quats are normalised before use to eliminate scaling issues */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ddf7e7ff4a3..89757533fb8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1041,6 +1041,8 @@ Object *add_object(struct Scene *scene, int type) * but rotations default to quaternions */ ob->rotmode= ROT_MODE_EUL; + /* axis-angle must not have a 0,0,0 axis, so set y-axis as default... */ + ob->rotAxis[1]= ob->drotAxis[1]= 1.0f; base= scene_add_base(scene, ob); scene_select_base(scene, base); @@ -1602,9 +1604,9 @@ void object_rot_to_mat3(Object *ob, float mat[][3]) EulOToMat3(ob->drot, ob->rotmode, dmat); } else if (ob->rotmode == ROT_MODE_AXISANGLE) { - /* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */ - AxisAngleToMat3(&ob->quat[1], ob->quat[0], rmat); - AxisAngleToMat3(&ob->dquat[1], ob->dquat[0], dmat); + /* axis-angle - not really that great for 3D-changing orientations */ + AxisAngleToMat3(ob->rotAxis, ob->rotAngle, rmat); + AxisAngleToMat3(ob->drotAxis, ob->drotAngle, dmat); } else { /* quats are normalised before use to eliminate scaling issues */ diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index f13d35c7d4a..3ad6ddf2c6f 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -581,6 +581,7 @@ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data) for (aci= animcopybuf.first; aci; aci= aci->next) { /* check that paths exist */ if (aci->rna_path && fcu->rna_path) { + // FIXME: this breaks for bone names! if (strcmp(aci->rna_path, fcu->rna_path) == 0) { /* should be a match unless there's more than one of these */ if ((no_name) || (aci->array_index == fcu->array_index)) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index c32837be420..0343fea5bfb 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4875,14 +4875,39 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) /* check if convert to eulers for locking... */ if (pchan->protectflag & OB_LOCK_ROT4D) { /* perform clamping on a component by component basis */ - if ((pchan->protectflag & OB_LOCK_ROTW) == 0) - pchan->quat[0]= (pchan->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f; - if ((pchan->protectflag & OB_LOCK_ROTX) == 0) - pchan->quat[1]= 0.0f; - if ((pchan->protectflag & OB_LOCK_ROTY) == 0) - pchan->quat[2]= 0.0f; - if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) - pchan->quat[3]= 0.0f; + if (pchan->rotmode == ROT_MODE_AXISANGLE) { + if ((pchan->protectflag & OB_LOCK_ROTW) == 0) + pchan->rotAngle= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTX) == 0) + pchan->rotAxis[0]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTY) == 0) + pchan->rotAxis[1]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) + pchan->rotAxis[2]= 0.0f; + + /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */ + if (IS_EQ(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQ(pchan->rotAxis[1], pchan->rotAxis[2])) + pchan->rotAxis[1] = 1.0f; + } + else if (pchan->rotmode == ROT_MODE_QUAT) { + if ((pchan->protectflag & OB_LOCK_ROTW) == 0) + pchan->quat[0]= 1.0f; + if ((pchan->protectflag & OB_LOCK_ROTX) == 0) + pchan->quat[1]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTY) == 0) + pchan->quat[2]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) + pchan->quat[3]= 0.0f; + } + else { + /* the flag may have been set for the other modes, so just ignore the extra flag... */ + if ((pchan->protectflag & OB_LOCK_ROTX) == 0) + pchan->eul[0]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTY) == 0) + pchan->eul[1]= 0.0f; + if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) + pchan->eul[2]= 0.0f; + } } else { /* perform clamping using euler form (3-components) */ @@ -4893,7 +4918,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) QuatToEul(pchan->quat, oldeul); } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { - AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT); + AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, oldeul, EULER_ORDER_DEFAULT); } else { VECCOPY(oldeul, pchan->eul); @@ -4916,7 +4941,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) } } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { - AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT); + EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle); } else { VECCOPY(pchan->eul, eul); @@ -4930,8 +4955,8 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op) } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { /* by default, make rotation of 0 radians around y-axis (roll) */ - pchan->quat[0]=pchan->quat[1]=pchan->quat[3]= 0.0f; - pchan->quat[2]= 1.0f; + pchan->rotAxis[0]=pchan->rotAxis[2]=pchan->rotAngle= 0.0f; + pchan->rotAxis[1]= 1.0f; } else { pchan->eul[0]= pchan->eul[1]= pchan->eul[2]= 0.0f; diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index edbc7b9ae9b..461a70bbf86 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -819,7 +819,7 @@ void pose_copy_menu(Scene *scene) /* need to convert to quat first (in temp var)... */ Mat4ToQuat(delta_mat, tmp_quat); - QuatToAxisAngle(tmp_quat, &pchan->quat[1], &pchan->quat[0]); + QuatToAxisAngle(tmp_quat, pchan->rotAxis, &pchan->rotAngle); } else if (pchan->rotmode == ROT_MODE_QUAT) Mat4ToQuat(delta_mat, pchan->quat); @@ -1024,23 +1024,23 @@ static int pose_paste_exec (bContext *C, wmOperator *op) else if (pchan->rotmode > 0) { /* quat/axis-angle to euler */ if (chan->rotmode == ROT_MODE_AXISANGLE) - AxisAngleToEulO(&chan->quat[1], chan->quat[0], pchan->eul, pchan->rotmode); + AxisAngleToEulO(chan->rotAxis, chan->rotAngle, pchan->eul, pchan->rotmode); else QuatToEulO(chan->quat, pchan->eul, pchan->rotmode); } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { /* quat/euler to axis angle */ if (chan->rotmode > 0) - EulOToAxisAngle(chan->eul, chan->rotmode, &pchan->quat[1], &pchan->quat[0]); + EulOToAxisAngle(chan->eul, chan->rotmode, pchan->rotAxis, &pchan->rotAngle); else - QuatToAxisAngle(chan->quat, &pchan->quat[1], &pchan->quat[0]); + QuatToAxisAngle(chan->quat, pchan->rotAxis, &pchan->rotAngle); } else { /* euler/axis-angle to quat */ if (chan->rotmode > 0) EulOToQuat(chan->eul, chan->rotmode, pchan->quat); else - AxisAngleToQuat(pchan->quat, &chan->quat[1], chan->quat[0]); + AxisAngleToQuat(pchan->quat, chan->rotAxis, pchan->rotAngle); } /* paste flipped pose? */ @@ -1055,10 +1055,10 @@ static int pose_paste_exec (bContext *C, wmOperator *op) else if (pchan->rotmode == ROT_MODE_AXISANGLE) { float eul[3]; - AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], eul, EULER_ORDER_DEFAULT); + AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, eul, EULER_ORDER_DEFAULT); eul[1]*= -1; eul[2]*= -1; - EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]); + EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle); // experimental method (uncomment to test): #if 0 diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index cd0d97eed44..898d541d09d 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -117,17 +117,41 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) { if (ob->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) { - /* check if convert to eulers for locking... */ if (ob->protectflag & OB_LOCK_ROT4D) { /* perform clamping on a component by component basis */ - if ((ob->protectflag & OB_LOCK_ROTW) == 0) - ob->quat[0]= (ob->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f; - if ((ob->protectflag & OB_LOCK_ROTX) == 0) - ob->quat[1]= 0.0f; - if ((ob->protectflag & OB_LOCK_ROTY) == 0) - ob->quat[2]= 0.0f; - if ((ob->protectflag & OB_LOCK_ROTZ) == 0) - ob->quat[3]= 0.0f; + if (ob->rotmode == ROT_MODE_AXISANGLE) { + if ((ob->protectflag & OB_LOCK_ROTW) == 0) + ob->rotAngle= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTX) == 0) + ob->rotAxis[0]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTY) == 0) + ob->rotAxis[1]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTZ) == 0) + ob->rotAxis[2]= 0.0f; + + /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */ + if (IS_EQ(ob->rotAxis[0], ob->rotAxis[1]) && IS_EQ(ob->rotAxis[1], ob->rotAxis[2])) + ob->rotAxis[1] = 1.0f; + } + else if (ob->rotmode == ROT_MODE_QUAT) { + if ((ob->protectflag & OB_LOCK_ROTW) == 0) + ob->quat[0]= 1.0f; + if ((ob->protectflag & OB_LOCK_ROTX) == 0) + ob->quat[1]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTY) == 0) + ob->quat[2]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTZ) == 0) + ob->quat[3]= 0.0f; + } + else { + /* the flag may have been set for the other modes, so just ignore the extra flag... */ + if ((ob->protectflag & OB_LOCK_ROTX) == 0) + ob->rot[0]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTY) == 0) + ob->rot[1]= 0.0f; + if ((ob->protectflag & OB_LOCK_ROTZ) == 0) + ob->rot[2]= 0.0f; + } } else { /* perform clamping using euler form (3-components) */ @@ -138,7 +162,7 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) QuatToEul(ob->quat, oldeul); } else if (ob->rotmode == ROT_MODE_AXISANGLE) { - AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT); + AxisAngleToEulO(ob->rotAxis, ob->rotAngle, oldeul, EULER_ORDER_DEFAULT); } else { VECCOPY(oldeul, ob->rot); @@ -161,7 +185,7 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) } } else if (ob->rotmode == ROT_MODE_AXISANGLE) { - AxisAngleToEulO(&ob->quat[1], ob->quat[0], oldeul, EULER_ORDER_DEFAULT); + EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, ob->rotAxis, &ob->rotAngle); } else { VECCOPY(ob->rot, eul); @@ -175,8 +199,8 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op) } else if (ob->rotmode == ROT_MODE_AXISANGLE) { /* by default, make rotation of 0 radians around y-axis (roll) */ - ob->quat[0]=ob->quat[1]=ob->quat[3]= 0.0f; - ob->quat[2]= 1.0f; + ob->rotAxis[0]=ob->rotAxis[2]=ob->rotAngle= 0.0f; + ob->rotAxis[1]= 1.0f; } else { ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index ec72d72013b..c2f5d736875 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -689,6 +689,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) case B_OBJECTPANELROT: if(ob) { + // TODO: need to support roation modes ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0; ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0; ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0; @@ -870,13 +871,12 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) float quat[4]; /* convert to axis-angle, passing through quats */ EulToQuat(eul, quat); - QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]); + QuatToAxisAngle(quat, pchan->rotAxis, &pchan->rotAngle); } else if (pchan->rotmode == ROT_MODE_QUAT) EulToQuat(eul, pchan->quat); else VecCopyf(pchan->eul, eul); - } /* no break, pass on */ case B_ARMATUREPANEL2: diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index f6d30a7bec9..1b11d43c200 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -509,7 +509,7 @@ static short apply_targetless_ik(Object *ob) if (parchan->rotmode > 0) Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode); else if (parchan->rotmode == ROT_MODE_AXISANGLE) - Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]); + Mat3ToAxisAngle(rmat3, parchan->rotAxis, &pchan->rotAngle); else Mat3ToQuat(rmat3, parchan->quat); @@ -519,7 +519,7 @@ static short apply_targetless_ik(Object *ob) if (parchan->rotmode > 0) EulOToMat3(parchan->eul, parchan->rotmode, qrmat); else if (parchan->rotmode == ROT_MODE_AXISANGLE) - AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat); + AxisAngleToMat3(parchan->rotAxis, parchan->rotAngle, qrmat); else QuatToMat3(parchan->quat, qrmat); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 3201a1df6a5..e2eb13f0bdf 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -128,12 +128,15 @@ typedef struct bPoseChannel { void *dual_quat; void *b_bone_dual_quats; - float loc[3]; /* transforms - written in by actions or transform */ + /* transforms - written in by actions or transform */ + float loc[3]; float size[3]; - float eul[3]; /* rotations - written in by actions or transform (but only euler/quat in use at any one time!) */ - float quat[4]; - short rotmode; /* for now either quat (0), or xyz-euler (1) */ + /* rotations - written in by actions or transform (but only one representation gets used at any time) */ + float eul[3]; /* euler rotation */ + float quat[4]; /* quaternion rotation */ + float rotAxis[3], rotAngle; /* axis-angle rotation */ + short rotmode; /* eRotationModes - rotation representation to use */ short pad; float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index ade22e4ebd4..0940a88267c 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -133,8 +133,10 @@ typedef struct Object { /* rot en drot have to be together! (transform('r' en 's')) */ float loc[3], dloc[3], orig[3]; float size[3], dsize[3]; - float rot[3], drot[3]; - float quat[4], dquat[4]; + float rot[3], drot[3]; /* euler rotation */ + float quat[4], dquat[4]; /* quaternion rotation */ + float rotAxis[3], drotAxis[3]; /* axis angle rotation - axis part */ + float rotAngle, drotAngle; /* axis angle rotation - angle part */ float obmat[4][4]; float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */ float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 4fb2db42b8b..3184ebc6db2 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -484,12 +484,34 @@ static void rna_Object_rotation_euler_set(PointerRNA *ptr, const float *value) VECCOPY(ob->rot, value); } +/* rotation - axis-angle */ +static void rna_Object_rotation_axis_angle_get(PointerRNA *ptr, float *value) +{ + Object *ob= ptr->data; + + /* for now, assume that rotation mode is axis-angle */ + value[0]= ob->rotAngle; + VecCopyf(&value[1], ob->rotAxis); +} + +/* rotation - axis-angle */ +static void rna_Object_rotation_axis_angle_set(PointerRNA *ptr, const float *value) +{ + Object *ob= ptr->data; + + /* for now, assume that rotation mode is axis-angle */ + ob->rotAngle= value[0]; + VecCopyf(ob->rotAxis, (float *)&value[1]); + + // TODO: validate axis? +} + static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value) { Object *ob= ptr->data; /* use API Method for conversions... */ - BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotmode, (short)value); + BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotAxis, &ob->rotAngle, ob->rotmode, (short)value); /* finally, set the new rotation type */ ob->rotmode= value; @@ -1242,8 +1264,8 @@ static void rna_def_object(BlenderRNA *brna) * having a single one is better for Keyframing and other property-management situations... */ prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); - RNA_def_property_float_sdna(prop, NULL, "quat"); - // TODO: we may need some validation funcs + RNA_def_property_array(prop, 4); // TODO: maybe we'll need to define the 'default value' getter too... + RNA_def_property_float_funcs(prop, "rna_Object_rotation_axis_angle_get", "rna_Object_rotation_axis_angle_set", NULL); RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); @@ -1283,7 +1305,7 @@ static void rna_def_object(BlenderRNA *brna) #if 0 // XXX not supported well yet... prop= RNA_def_property(srna, "delta_rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); - RNA_def_property_float_sdna(prop, NULL, "dquat"); + RNA_def_property_float_sdna(prop, NULL, "dquat"); // FIXME: this is not a single field any more! (drotAxis and drotAngle) RNA_def_property_ui_text(prop, "Delta Rotation (Axis Angle)", "Extra added rotation to the rotation of the object (when using Axis-Angle rotations)."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); #endif diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index ecb2dba0197..27069b361fd 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -162,7 +162,7 @@ static void rna_PoseChannel_rotation_euler_get(PointerRNA *ptr, float *value) bPoseChannel *pchan= ptr->data; if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ - AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], value, EULER_ORDER_DEFAULT); + AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, value, EULER_ORDER_DEFAULT); else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ QuatToEul(pchan->quat, value); else @@ -175,19 +175,41 @@ static void rna_PoseChannel_rotation_euler_set(PointerRNA *ptr, const float *val bPoseChannel *pchan= ptr->data; if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ - EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &pchan->quat[1], &pchan->quat[0]); + EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle); else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ EulToQuat((float*)value, pchan->quat); else VECCOPY(pchan->eul, value); } +/* rotation - axis-angle */ +static void rna_PoseChannel_rotation_axis_angle_get(PointerRNA *ptr, float *value) +{ + bPoseChannel *pchan= ptr->data; + + /* for now, assume that rotation mode is axis-angle */ + value[0]= pchan->rotAngle; + VecCopyf(&value[1], pchan->rotAxis); +} + +/* rotation - axis-angle */ +static void rna_PoseChannel_rotation_axis_angle_set(PointerRNA *ptr, const float *value) +{ + bPoseChannel *pchan= ptr->data; + + /* for now, assume that rotation mode is axis-angle */ + pchan->rotAngle= value[0]; + VecCopyf(pchan->rotAxis, (float *)&value[1]); + + // TODO: validate axis? +} + static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value) { bPoseChannel *pchan= ptr->data; /* use API Method for conversions... */ - BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotmode, (short)value); + BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotAxis, &pchan->rotAngle, pchan->rotmode, (short)value); /* finally, set the new rotation type */ pchan->rotmode= value; @@ -578,8 +600,8 @@ static void rna_def_pose_channel(BlenderRNA *brna) * having a single one is better for Keyframing and other property-management situations... */ prop= RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); - RNA_def_property_float_sdna(prop, NULL, "quat"); - // TODO: we may need some validation funcs + RNA_def_property_array(prop, 4); // TODO: maybe we'll need to define the 'default value' getter too... + RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_axis_angle_get", "rna_PoseChannel_rotation_axis_angle_set", NULL); RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); -- cgit v1.2.3 From b4b031eae7569d5e08f034368417417d10da3a60 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 8 Oct 2009 05:02:04 +0000 Subject: Fixed remaining bugs with animating rotation modes: * Removed the hack-functions to set euler rotations from the values set in the other rotation representations, even when euler rotations weren't being used. I pressume that this was added for being able to represent quats in terms of eulers for the UI, but really it would break animation evaluation (i.e. euler curves after quaternion curves would always block the quaternion curves). * Object rotation values in the transform properties panel now take into account rotation modes, so the appropriate rotations will get converted to quaternions before being drawn. * Fixed a few bugs with some of the conversion code (minor stuff left out). --- source/blender/blenkernel/intern/armature.c | 2 +- .../blender/editors/space_view3d/view3d_buttons.c | 40 +++++++++++++++++----- source/blender/makesrna/intern/rna_object.c | 27 --------------- source/blender/makesrna/intern/rna_pose.c | 34 ++---------------- 4 files changed, 36 insertions(+), 67 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index a0abe780273..9894cc85784 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1314,7 +1314,7 @@ void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float else if (newMode == ROT_MODE_AXISANGLE) { /* to axis-angle */ if (oldMode > 0) { /* euler to axis angle */ - EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]); + EulOToAxisAngle(eul, oldMode, axis, angle); } else if (oldMode == ROT_MODE_QUAT) { /* quat to axis angle */ diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index c2f5d736875..161b73032f5 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -520,7 +520,7 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if (pchan->rotmode == ROT_MODE_AXISANGLE) { float quat[4]; /* convert to euler, passing through quats... */ - AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]); + AxisAngleToQuat(quat, pchan->rotAxis, pchan->rotAngle); QuatToEul(quat, tfp->ob_eul); } else if (pchan->rotmode == ROT_MODE_QUAT) @@ -689,10 +689,24 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) case B_OBJECTPANELROT: if(ob) { - // TODO: need to support roation modes - ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0; - ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0; - ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0; + float eul[3]; + + /* make a copy to eul[3], to allow TAB on buttons to work */ + eul[0]= M_PI*tfp->ob_eul[0]/180.0; + eul[1]= M_PI*tfp->ob_eul[1]/180.0; + eul[2]= M_PI*tfp->ob_eul[2]/180.0; + + if (ob->rotmode == ROT_MODE_AXISANGLE) { + float quat[4]; + /* convert to axis-angle, passing through quats */ + EulToQuat(eul, quat); + QuatToAxisAngle(quat, ob->rotAxis, &ob->rotAngle); + } + else if (ob->rotmode == ROT_MODE_QUAT) + EulToQuat(eul, ob->quat); + else + VecCopyf(ob->rot, eul); + DAG_id_flush_update(&ob->id, OB_RECALC_OB); } break; @@ -1130,9 +1144,19 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED, 125, 240, 25, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects Z Location value from being Transformed"); uiBlockEndAlign(block); - tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI; - tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI; - tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI; + if (ob->rotmode == ROT_MODE_AXISANGLE) { + float quat[4]; + /* convert to euler, passing through quats... */ + AxisAngleToQuat(quat, ob->rotAxis, ob->rotAngle); + QuatToEul(quat, tfp->ob_eul); + } + else if (ob->rotmode == ROT_MODE_QUAT) + QuatToEul(ob->quat, tfp->ob_eul); + else + VecCopyf(tfp->ob_eul, ob->rot); + tfp->ob_eul[0]*= 180.0/M_PI; + tfp->ob_eul[1]*= 180.0/M_PI; + tfp->ob_eul[2]*= 180.0/M_PI; uiBlockBeginAlign(block); if ((ob->parent) && (ob->partype == PARBONE)) { diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 3184ebc6db2..013d455b1b3 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -458,32 +458,6 @@ static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr, psys_set_current_num(ob, value); } -/* rotation - euler angles */ -static void rna_Object_rotation_euler_get(PointerRNA *ptr, float *value) -{ - Object *ob= ptr->data; - - if(ob->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ - AxisAngleToEulO(&ob->quat[1], ob->quat[0], value, EULER_ORDER_DEFAULT); - else if(ob->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ - QuatToEul(ob->quat, value); - else - VECCOPY(value, ob->rot); -} - -/* rotation - euler angles */ -static void rna_Object_rotation_euler_set(PointerRNA *ptr, const float *value) -{ - Object *ob= ptr->data; - - if(ob->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ - EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, &ob->quat[1], &ob->quat[0]); - else if(ob->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ - EulToQuat((float*)value, ob->quat); - else - VECCOPY(ob->rot, value); -} - /* rotation - axis-angle */ static void rna_Object_rotation_axis_angle_get(PointerRNA *ptr, float *value) { @@ -1271,7 +1245,6 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rot"); - RNA_def_property_float_funcs(prop, "rna_Object_rotation_euler_get", "rna_Object_rotation_euler_set", NULL); RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 27069b361fd..584c971951a 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -156,32 +156,6 @@ static void rna_Pose_ik_solver_update(bContext *C, PointerRNA *ptr) DAG_id_flush_update(&ob->id, OB_RECALC_DATA|OB_RECALC_OB); } -/* rotation - euler angles */ -static void rna_PoseChannel_rotation_euler_get(PointerRNA *ptr, float *value) -{ - bPoseChannel *pchan= ptr->data; - - if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ - AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, value, EULER_ORDER_DEFAULT); - else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ - QuatToEul(pchan->quat, value); - else - VECCOPY(value, pchan->eul); -} - -/* rotation - euler angles */ -static void rna_PoseChannel_rotation_euler_set(PointerRNA *ptr, const float *value) -{ - bPoseChannel *pchan= ptr->data; - - if(pchan->rotmode == ROT_MODE_AXISANGLE) /* default XYZ eulers */ - EulOToAxisAngle((float *)value, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle); - else if(pchan->rotmode == ROT_MODE_QUAT) /* default XYZ eulers */ - EulToQuat((float*)value, pchan->quat); - else - VECCOPY(pchan->eul, value); -} - /* rotation - axis-angle */ static void rna_PoseChannel_rotation_axis_angle_get(PointerRNA *ptr, float *value) { @@ -607,7 +581,6 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop= RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "eul"); - RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_euler_get", "rna_PoseChannel_rotation_euler_set", NULL); RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Pose_update"); @@ -617,15 +590,14 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, "rna_PoseChannel_rotation_mode_set", NULL); RNA_def_property_ui_text(prop, "Rotation Mode", ""); RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update"); - - /* These three matrix properties await an implementation of the PROP_MATRIX subtype, which currently doesn't exist. */ + + /* transform matrices - should be read-only since these are set directly by AnimSys evaluation */ prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "chan_mat"); RNA_def_property_array(prop, 16); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints."); - - /* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */ + prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "pose_mat"); RNA_def_property_array(prop, 16); -- cgit v1.2.3 From 6e43a69a8d3dc88594df6f0d15686cad8e7e6646 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 8 Oct 2009 05:53:26 +0000 Subject: Bugfix #19576: Auto keyframing does not record rotations on object level animation The hardcoded paths for rotation keyframes on objects got broken by my commits to rename the rotation properties. I've taken this opportunity to recode the auto-keyframing code here to use the builtin keyingsets instead of going through and manually calling insert_keyframe(), thus preventing this problem in future. --- source/blender/editors/animation/keyframing.c | 22 ++-- source/blender/editors/animation/keyingsets.c | 27 +---- source/blender/editors/armature/poseSlide.c | 6 +- source/blender/editors/armature/poselib.c | 9 +- source/blender/editors/armature/poseobject.c | 3 +- source/blender/editors/include/ED_keyframing.h | 2 +- .../editors/transform/transform_conversions.c | 118 ++++++++------------- 7 files changed, 72 insertions(+), 115 deletions(-) diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 10d45d53761..75218e6ea6e 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -981,12 +981,15 @@ static int insert_key_exec (bContext *C, wmOperator *op) } /* try to insert keyframes for the channels specified by KeyingSet */ - success= modify_keyframes(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); - printf("KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success); + success= modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + if (G.f & G_DEBUG) + printf("KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success); /* report failure? */ if (success == 0) BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes"); + else + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* free temp context-data if available */ if (dsources.first) { @@ -995,10 +998,7 @@ static int insert_key_exec (bContext *C, wmOperator *op) } /* send updates */ - ED_anim_dag_flush_update(C); - - /* for now, only send ND_KEYS for KeyingSets */ - WM_event_add_notifier(C, ND_KEYS, NULL); + ED_anim_dag_flush_update(C); return OPERATOR_FINISHED; } @@ -1132,12 +1132,15 @@ static int delete_key_exec (bContext *C, wmOperator *op) } /* try to insert keyframes for the channels specified by KeyingSet */ - success= modify_keyframes(C, &dsources, NULL, ks, MODIFYKEY_MODE_DELETE, cfra); - printf("KeyingSet '%s' - Successfully removed %d Keyframes \n", ks->name, success); + success= modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_DELETE, cfra); + if (G.f & G_DEBUG) + printf("KeyingSet '%s' - Successfully removed %d Keyframes \n", ks->name, success); /* report failure? */ if (success == 0) BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes"); + else + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); /* free temp context-data if available */ if (dsources.first) { @@ -1148,9 +1151,6 @@ static int delete_key_exec (bContext *C, wmOperator *op) /* send updates */ ED_anim_dag_flush_update(C); - /* for now, only send ND_KEYS for KeyingSets */ - WM_event_add_notifier(C, ND_KEYS, NULL); - return OPERATOR_FINISHED; } diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 99cdf0a86f4..a9a3612b79b 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -1252,9 +1252,8 @@ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets. * Returns the number of channels that keyframes were added to */ -int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra) +int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra) { - Scene *scene= CTX_data_scene(C); KS_Path *ksp; int kflag=0, success= 0; char *groupname= NULL; @@ -1319,24 +1318,16 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet * success+= delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag); } - /* send notifiers and set recalc-flags */ - // TODO: hopefully this doesn't result in execessive flooding of the notifier stack - if (C && ksp->id) { + /* set recalc-flags */ + if (ksp->id) { switch (GS(ksp->id->name)) { case ID_OB: /* Object (or Object-Related) Keyframes */ { Object *ob= (Object *)ksp->id; ob->recalc |= OB_RECALC; - WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, ksp->id); } break; - case ID_MA: /* Material Keyframes */ - WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, ksp->id); - break; - default: /* Any keyframes */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); - break; } } } @@ -1457,24 +1448,16 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet * MEM_freeN(path); } - /* send notifiers and set recalc-flags */ - // TODO: hopefully this doesn't result in execessive flooding of the notifier stack - if (C && cks->id) { + /* set recalc-flags */ + if (cks->id) { switch (GS(cks->id->name)) { case ID_OB: /* Object (or Object-Related) Keyframes */ { Object *ob= (Object *)cks->id; ob->recalc |= OB_RECALC; - WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, cks->id); } break; - case ID_MA: /* Material Keyframes */ - WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, cks->id); - break; - default: /* Any keyframes */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); - break; } } } diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index c73208c54c2..1e0df79d0e6 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -560,11 +560,11 @@ static void pose_slide_autoKeyframe (bContext *C, tPoseSlideOp *pso) /* insert keyframes */ if (pchan->flag & POSE_LOC) - modify_keyframes(C, &dsources, NULL, pso->ks_loc, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + modify_keyframes(pso->scene, &dsources, NULL, pso->ks_loc, MODIFYKEY_MODE_INSERT, (float)pso->cframe); if (pchan->flag & POSE_ROT) - modify_keyframes(C, &dsources, NULL, pso->ks_rot, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + modify_keyframes(pso->scene, &dsources, NULL, pso->ks_rot, MODIFYKEY_MODE_INSERT, (float)pso->cframe); if (pchan->flag & POSE_SIZE) - modify_keyframes(C, &dsources, NULL, pso->ks_scale, MODIFYKEY_MODE_INSERT, (float)pso->cframe); + modify_keyframes(pso->scene, &dsources, NULL, pso->ks_scale, MODIFYKEY_MODE_INSERT, (float)pso->cframe); } } } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 386cb6512a3..d34da201ef5 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -329,6 +329,7 @@ static int poselib_add_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int poselib_add_exec (bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); bAction *act = poselib_validate(ob); bArmature *arm= (ob) ? ob->data : NULL; @@ -385,7 +386,7 @@ static int poselib_add_exec (bContext *C, wmOperator *op) /* KeyingSet to use depends on rotation mode (but that's handled by the templates code) */ if (poselib_ks_locrotscale == NULL) poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); + modify_keyframes(scene, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame); } } } @@ -772,7 +773,7 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData cks.pchan= pchan; /* now insert the keyframe */ - modify_keyframes(C, &dsources, NULL, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); + modify_keyframes(scene, &dsources, NULL, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); /* clear any unkeyed tags */ if (pchan->bone) @@ -783,10 +784,12 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData if (pchan->bone) pchan->bone->flag |= BONE_UNKEYED; } - } } } + + /* send notifiers for this */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } /* Apply the relevant changes to the pose */ diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 461a70bbf86..1531d922e04 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1089,7 +1089,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ cks.pchan= pchan; - modify_keyframes(C, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); + modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA); /* clear any unkeyed tags */ if (chan->bone) @@ -1118,6 +1118,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_TRANSFORM, ob); + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); // XXX not really needed, but here for completeness... return OPERATOR_FINISHED; } diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 92dda4162cc..2b41cb5c9db 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -122,7 +122,7 @@ enum { } eModifyKey_Modes; /* Keyframing Helper Call - use the provided Keying Set to Add/Remove Keyframes */ -int modify_keyframes(struct bContext *C, struct ListBase *dsources, struct bAction *act, struct KeyingSet *ks, short mode, float cfra); +int modify_keyframes(struct Scene *scene, struct ListBase *dsources, struct bAction *act, struct KeyingSet *ks, short mode, float cfra); /* -------- */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 1b11d43c200..d2c1c9f55f0 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4242,10 +4242,15 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) // TODO: this should probably be done per channel instead... if (autokeyframe_cfra_can_key(scene, id)) { - AnimData *adt= ob->adt; + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; float cfra= (float)CFRA; // xxx this will do for now short flag = 0; + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &ob->id; + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; if (IS_AUTOKEY_FLAG(AUTOMATKEY)) @@ -4254,6 +4259,8 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) flag |= INSERTKEY_REPLACE; if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { + AnimData *adt= ob->adt; + /* only key on available channels */ if (adt && adt->action) { for (fcu= adt->action->curves.first; fcu; fcu= fcu->next) { @@ -4292,41 +4299,25 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) doScale = 1; } - // TODO: the group names here are temporary... - // TODO: should this be made to use the builtin KeyingSets instead? + /* insert keyframes for the affected sets of channels using the builtin KeyingSets found */ if (doLoc) { - insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doRot) { - insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doScale) { - insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } + /* insert keyframe in all (transform) channels */ else { - // TODO: the group names here are temporary... - // TODO: should this be made to use the builtin KeyingSets instead? - insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag); - - insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag); - - insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag); - insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } - - // XXX todo... find a way to send notifiers from here... } } @@ -4346,9 +4337,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, // TODO: this should probably be done per channel instead... if (autokeyframe_cfra_can_key(scene, id)) { + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; float cfra= (float)CFRA; short flag= 0; - char buf[512]; + + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &ob->id; /* flag is initialised from UserPref keyframing settings * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get @@ -4401,60 +4397,34 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, } if (doLoc) { - sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doRot) { - // FIXME: better to just use the keyingsets for this instead... - if (pchan->rotmode == ROT_MODE_QUAT) { - sprintf(buf, "pose.pose_channels[\"%s\"].rotation_quaternion", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag); - } - else { - sprintf(buf, "pose.pose_channels[\"%s\"].rotation_euler", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - } + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doScale) { - sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale"); + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } - /* insert keyframe in any channel that's appropriate */ + /* insert keyframe in all (transform) channels */ else { - sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - - // FIXME: better to just use the keyingsets for this instead... - if (pchan->rotmode == ROT_MODE_QUAT) { - sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag); - } - else { - sprintf(buf, "pose.pose_channels[\"%s\"].rotation_euler", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - } + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name); - insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } } -- cgit v1.2.3 From da698657cee0500f1f0cff6d4340e016dd34a94e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 8 Oct 2009 06:39:45 +0000 Subject: Keying Sets - Bugfixes + Auto-Keyframing * Added a new option for Auto-Keyframing which makes it only insert keyframes for the items included in the active Keying Set. This only works for Transform Auto-Keyframing so far (other tools will get it added later). The option is disabled by default. * Fixed bug where adding an 'entire' array to some KeyingSet would only start from the index of the button that the mouse was over at the time * Made some UI tweaks for Keying Sets buttons (still heaps of missing options there). --- release/scripts/ui/buttons_scene.py | 6 +++++ release/scripts/ui/space_userpref.py | 9 +++++--- source/blender/editors/animation/keyingsets.c | 27 +++++++++++++++++++++- source/blender/editors/include/ED_keyframing.h | 6 +++++ source/blender/editors/transform/transform.h | 2 +- .../editors/transform/transform_conversions.c | 17 ++++++++++++-- source/blender/makesdna/DNA_userdef_types.h | 4 +++- source/blender/makesrna/intern/rna_userdef.c | 10 +++++--- 8 files changed, 70 insertions(+), 11 deletions(-) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 666bbacea50..9bd0019bd6c 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -473,6 +473,9 @@ class SCENE_PT_keying_sets(SceneButtonsPanel): scene = context.scene + row = layout.row() + row.itemL(text="Keying Sets") + row = layout.row() col = row.column() @@ -508,6 +511,9 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): scene = context.scene ks = scene.active_keying_set + row = layout.row() + row.itemL(text="Paths") + row = layout.row() col = row.column() diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index ce8d03d3292..43c70dac4b1 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -199,13 +199,16 @@ class USERPREF_PT_edit(bpy.types.Panel): sub1 = sub.column() sub1.itemL(text="Keyframing:") sub1.itemR(edit, "use_visual_keying") - sub1.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available") - sub1.itemR(edit, "auto_keyframe_insert_needed", text="Only Insert Needed") + sub1.itemR(edit, "keyframe_insert_needed", text="Only Insert Needed") sub1.itemS() sub1.itemL(text="New F-Curve Defaults:") sub1.itemR(edit, "new_interpolation_type", text="Interpolation") sub1.itemS() - sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing") + sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing:") + sub2 = sub1.column() + sub2.active = edit.auto_keying_enable + sub2.itemR(edit, "auto_keyframe_insert_keyingset", text="Only Insert for Keying Set") + sub2.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available") sub1.itemS() sub1.itemS() diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index a9a3612b79b..afaa9e3f400 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -337,9 +337,16 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op) if (path) { /* set flags */ - if (all) + if (all) { pflag |= KSP_FLAG_WHOLE_ARRAY; + /* we need to set the index for this to 0, even though it may break in some cases, this is + * necessary if we want the entire array for most cases to get included without the user + * having to worry about where they clicked + */ + index= 0; + } + /* add path to this setting */ BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME); success= 1; @@ -1109,6 +1116,24 @@ KeyingSet *ANIM_builtin_keyingset_get_named (KeyingSet *prevKS, char name[]) return NULL; } + +/* Get the active Keying Set for the Scene provided */ +KeyingSet *ANIM_scene_get_active_keyingset (Scene *scene) +{ + if (ELEM(NULL, scene, scene->keyingsets.first)) + return NULL; + + /* currently, there are several possibilities here: + * - 0: no active keying set + * - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1) + * - < 0: a builtin keying set (XXX this isn't enabled yet so that we don't get errors on reading back files) + */ + if (scene->active_keyingset > 0) + return BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + else // for now... + return NULL; +} + /* ******************************************* */ /* KEYFRAME MODIFICATION */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 2b41cb5c9db..802ceff1c07 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -135,6 +135,12 @@ struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, cha /* Initialise builtin KeyingSets on startup */ void init_builtin_keyingsets(void); + +/* -------- */ + +/* Get the active KeyingSet for the given scene */ +struct KeyingSet *ANIM_scene_get_active_keyingset(struct Scene *scene); + /* ************ Drivers ********************** */ /* Returns whether there is a driver in the copy/paste buffer to paste */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index ee6871d67bd..1c170a31c45 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -216,7 +216,7 @@ typedef struct TransData { void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */ short flag; /* Various flags */ short protectflag; /* If set, copy of Object or PoseChannel protection */ - int rotOrder; /* rotation order (for eulers), as defined in BLI_arithb.h */ + int rotOrder; /* rotation mode, as defined in eRotationModes (DNA_action_types.h) */ } TransData; typedef struct MouseInput { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index d2c1c9f55f0..a9c3e4676a0 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4242,6 +4242,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) // TODO: this should probably be done per channel instead... if (autokeyframe_cfra_can_key(scene, id)) { + KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); bCommonKeySrc cks; ListBase dsources = {&cks, &cks}; float cfra= (float)CFRA; // xxx this will do for now @@ -4258,7 +4259,12 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE; - if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { + + if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) { + /* only insert into active keyingset */ + modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); + } + else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { AnimData *adt= ob->adt; /* only key on available channels */ @@ -4337,6 +4343,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, // TODO: this should probably be done per channel instead... if (autokeyframe_cfra_can_key(scene, id)) { + KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); bCommonKeySrc cks; ListBase dsources = {&cks, &cks}; float cfra= (float)CFRA; @@ -4363,8 +4370,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, /* clear any 'unkeyed' flag it may have */ pchan->bone->flag &= ~BONE_UNKEYED; + /* only insert into active keyingset? */ + if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) { + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); + } /* only insert into available channels? */ - if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { + else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { if (act) { for (fcu= act->curves.first; fcu; fcu= fcu->next) insert_keyframe(id, act, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index edfc4999d80..5aa1aa6dfff 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -412,10 +412,12 @@ extern UserDef U; /* from blenkernel blender.c */ #define AUTOKEY_MODE_EDITKEYS 5 /* Auto-Keying flag */ - /* U.autokey_flag */ + /* U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days) */ #define AUTOKEY_FLAG_INSERTAVAIL (1<<0) #define AUTOKEY_FLAG_INSERTNEEDED (1<<1) #define AUTOKEY_FLAG_AUTOMATKEY (1<<2) + /* U.autokey_flag (strictly autokeying only) */ +#define AUTOKEY_FLAG_ONLYKEYINGSET (1<<6) /* toolsettings->autokey_flag */ #define ANIMRECORD_FLAG_WITHNLA (1<<10) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 1c6bd6515ff..8f999300c71 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1881,10 +1881,14 @@ static void rna_def_userdef_edit(BlenderRNA *brna) prop= RNA_def_property(srna, "auto_keyframe_insert_available", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTAVAIL); RNA_def_property_ui_text(prop, "Auto Keyframe Insert Available", "Automatic keyframe insertion in available curves."); - - prop= RNA_def_property(srna, "auto_keyframe_insert_needed", PROP_BOOLEAN, PROP_NONE); + + prop= RNA_def_property(srna, "auto_keyframe_insert_keyingset", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_ONLYKEYINGSET); + RNA_def_property_ui_text(prop, "Auto Keyframe Insert Keying Set", "Automatic keyframe insertion using active Keying Set."); + + prop= RNA_def_property(srna, "keyframe_insert_needed", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTNEEDED); - RNA_def_property_ui_text(prop, "Auto Keyframe Insert Needed", "Automatic keyframe insertion only when keyframe needed."); + RNA_def_property_ui_text(prop, "Keyframe Insert Needed", "Keyframe insertion only when keyframe needed."); prop= RNA_def_property(srna, "use_visual_keying", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_AUTOMATKEY); -- cgit v1.2.3 From df6c18e9638e9be36361910e86079cd6544f769a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 07:54:20 +0000 Subject: - object.selected is now editable (uses update function to flag the scene base) - editing properties from python wasnt running their update function. - missing commas made dir(context) give joined strings. - added __undo__ as an operator class attribute so python ops can be set as undoable. (like existing __register__) --- release/scripts/ui/space_view3d.py | 43 +++++++++++++++++++++- source/blender/editors/screen/screen_context.c | 2 +- source/blender/editors/space_view3d/space_view3d.c | 6 +-- source/blender/makesrna/intern/rna_object.c | 11 +++++- source/blender/python/intern/bpy_operator_wrap.c | 18 +++++++-- source/blender/python/intern/bpy_rna.c | 5 ++- 6 files changed, 73 insertions(+), 12 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 5827739aa53..976c04a63bb 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -179,6 +179,7 @@ class VIEW3D_MT_select_object(bpy.types.Menu): layout.itemO("object.select_by_layer", text="Select All by Layer") layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...") layout.itemO("object.select_grouped", text="Select Grouped...") + layout.itemO("object.select_pattern", text="Select Pattern...") class VIEW3D_MT_select_pose(bpy.types.Menu): __space_type__ = 'VIEW_3D' @@ -1306,7 +1307,42 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel): col.itemO("TFM_OT_select_orientation", text="Select") col.itemO("TFM_OT_create_orientation", text="Create") col.itemO("TFM_OT_delete_orientation", text="Delete") - + +# Operators + +class OBJECT_OT_select_pattern(bpy.types.Operator): + '''Select object matching a naming pattern.''' + __idname__ = "object.select_pattern" + __label__ = "Select Pattern" + __register__ = True + __undo__ = True + __props__ = [ + bpy.props.StringProperty(attr="pattern", name="Pattern", description="Name filter using '*' and '?' wildcard chars", maxlen= 32, default= "*"), + bpy.props.BoolProperty(attr="case_sensitive", name="Case Sensitive", description="Do a case sensitive compare", default= False), + ] + + def execute(self, context): + + import fnmatch + if self.case_sensitive: pattern_match = fnmatch.fnmatchcase + else: pattern_match = lambda a, b: fnmatch.fnmatchcase(a.upper(), b.upper()) + + for ob in context.visible_objects: + if pattern_match(ob.name, self.pattern): + ob.selected = True + + return ('FINISHED',) + + # TODO - python cant do popups yet + ''' + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + ''' + + + bpy.types.register(VIEW3D_HT_header) # Header bpy.types.register(VIEW3D_MT_view) #View Menus @@ -1382,4 +1418,7 @@ bpy.types.register(VIEW3D_PT_3dview_display) bpy.types.register(VIEW3D_PT_3dview_meshdisplay) bpy.types.register(VIEW3D_PT_3dview_curvedisplay) bpy.types.register(VIEW3D_PT_background_image) -bpy.types.register(VIEW3D_PT_transform_orientations) \ No newline at end of file +bpy.types.register(VIEW3D_PT_transform_orientations) + +bpy.ops.add(OBJECT_OT_select_pattern) + diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 17c51a7b7d3..e573ef06247 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -52,7 +52,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult if(CTX_data_dir(member)) { static const char *dir[] = { "scene", "selected_objects", "selected_bases", - "selected_editable_objects", "selected_editable_bases" + "selected_editable_objects", "selected_editable_bases", "active_base", "active_object", "edit_object", "sculpt_object", "vertex_paint_object", "weight_paint_object", "texture_paint_object", "brush", "particle_edit_object", NULL}; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index c175f835d67..735f3df9b09 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -620,10 +620,10 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes if(CTX_data_dir(member)) { static const char *dir[] = { - "selected_objects", "selected_bases" "selected_editable_objects", - "selected_editable_bases" "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", + "selected_objects", "selected_bases", "selected_editable_objects", + "selected_editable_bases", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", "active_base", "active_object", "visible_bones", "editable_bones", - "selected_bones", "selected_editable_bones" "visible_pchans", + "selected_bones", "selected_editable_bones", "visible_pchans", "selected_pchans", "active_bone", "active_pchan", NULL}; CTX_data_dir_set(result, dir); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 013d455b1b3..694eb7e23e4 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -126,6 +126,14 @@ static void rna_Object_dependency_update(bContext *C, PointerRNA *ptr) DAG_scene_sort(CTX_data_scene(C)); } +/* when changing the selection flag the scene needs updating */ +static void rna_Object_select_update(bContext *C, PointerRNA *ptr) +{ + Object *ob= (Object*)ptr->id.data; + short mode = ob->flag & SELECT ? BA_SELECT : BA_DESELECT; + ED_base_object_select(object_in_scene(ob, CTX_data_scene(C)), mode); +} + static void rna_Object_layer_update(bContext *C, PointerRNA *ptr) { Object *ob= (Object*)ptr->id.data; @@ -1145,9 +1153,8 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Selected", "Object selection state."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_select_update"); /* parent and track */ diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index bbf657d8ce0..bb0cea9e761 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -47,6 +47,7 @@ #define PYOP_ATTR_IDNAME_BL "__idname_bl__" /* our own name converted into blender syntax, users wont see this */ #define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */ #define PYOP_ATTR_REGISTER "__register__" /* True/False. if this python operator should be registered */ +#define PYOP_ATTR_UNDO "__undo__" /* True/False. if this python operator should be undone */ static struct BPY_flag_def pyop_ret_flags[] = { {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL}, @@ -277,16 +278,27 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) ot->pyop_data= userdata; /* flags */ + ot->flag= 0; + item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER); if (item) { - ot->flag= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0; + ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0; Py_DECREF(item); } else { - ot->flag= OPTYPE_REGISTER; /* unspesified, leave on for now to help debug */ PyErr_Clear(); } - + item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO); + if (item) { + ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0; + Py_DECREF(item); + } + else { + PyErr_Clear(); + } + + + props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP); if (props) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 1f800be266b..42b905dc0d8 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -762,7 +762,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v break; } } - + + /* Run rna property functions */ + RNA_property_update(BPy_GetContext(), ptr, prop); + return 0; } -- cgit v1.2.3 From 5a7db36b1d6a17d714ad0056d02095feab371e80 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 08:01:51 +0000 Subject: missed this in last commit comments, Pattern Select operator, access from the object select menu Glob strings like "Lear*.brown" and "Tree.0?", option for case sensitive and extend the existing selection. currently the default string is "*" which needs to be edited in the redo-panel in the toolbox since there is no way to get a text input for python. This replaces 2.4x's data browser Shift+F4, pattern select. --- release/scripts/ui/space_view3d.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 976c04a63bb..ef1947dbb39 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1319,6 +1319,7 @@ class OBJECT_OT_select_pattern(bpy.types.Operator): __props__ = [ bpy.props.StringProperty(attr="pattern", name="Pattern", description="Name filter using '*' and '?' wildcard chars", maxlen= 32, default= "*"), bpy.props.BoolProperty(attr="case_sensitive", name="Case Sensitive", description="Do a case sensitive compare", default= False), + bpy.props.BoolProperty(attr="extend", name="Extend", description="Extend the existing selection", default= True), ] def execute(self, context): @@ -1330,6 +1331,8 @@ class OBJECT_OT_select_pattern(bpy.types.Operator): for ob in context.visible_objects: if pattern_match(ob.name, self.pattern): ob.selected = True + elif not self.extend: + ob.selected = False return ('FINISHED',) -- cgit v1.2.3 From 8f154364f28d53c58b9a0022f8c36ab787477492 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 09:22:39 +0000 Subject: separate material lost all materials for the new mesh --- source/blender/blenkernel/BKE_material.h | 4 ++-- source/blender/blenkernel/intern/material.c | 18 +++++++++++------- source/blender/blenkernel/intern/object.c | 1 + source/blender/editors/mesh/editmesh.c | 1 + 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index b6645ef8737..85316dddedf 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -62,8 +62,8 @@ void assign_matarar(struct Object *ob, struct Material ***matar, int totcol); int find_material_index(struct Object *ob, struct Material *ma); -void object_add_material_slot(struct Object *ob); -void object_remove_material_slot(struct Object *ob); +int object_add_material_slot(struct Object *ob); +int object_remove_material_slot(struct Object *ob); /* rendering */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b44c59baaca..c1093c119dc 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -630,8 +630,7 @@ void assign_matarar(struct Object *ob, struct Material ***matar, int totcol) { int i, actcol_orig= ob->actcol; - while(ob->totcol) - object_remove_material_slot(ob); + while(object_remove_material_slot(ob)) {}; /* now we have the right number of slots */ for(i=0; itotcol>=MAXMAT) return; + if(ob==0) return FALSE; + if(ob->totcol>=MAXMAT) return FALSE; ma= give_current_material(ob, ob->actcol); assign_material(ob, ma, ob->totcol+1); ob->actcol= ob->totcol; + return TRUE; } static void do_init_render_material(Material *ma, int r_mode, float *amb) @@ -889,7 +889,7 @@ void automatname(Material *ma) } -void object_remove_material_slot(Object *ob) +int object_remove_material_slot(Object *ob) { Material *mao, ***matarar; Object *obt; @@ -898,7 +898,7 @@ void object_remove_material_slot(Object *ob) short *totcolp; int a, actcol; - if(ob==NULL || ob->totcol==0) return; + if(ob==NULL || ob->totcol==0) return FALSE; /* take a mesh/curve/mball as starting point, remove 1 index, * AND with all objects that share the ob->data @@ -909,6 +909,8 @@ void object_remove_material_slot(Object *ob) totcolp= give_totcolp(ob); matarar= give_matarar(ob); + if(*matarar==NULL) return FALSE; + /* we delete the actcol */ if(ob->totcol) { mao= (*matarar)[ob->actcol-1]; @@ -971,6 +973,8 @@ void object_remove_material_slot(Object *ob) } freedisplist(&ob->disp); } + + return TRUE; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 89757533fb8..0b0a7a54c38 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1233,6 +1233,7 @@ Object *copy_object(Object *ob) if(ob->totcol) { obn->mat= MEM_dupallocN(ob->mat); obn->matbits= MEM_dupallocN(ob->matbits); + obn->totcol= ob->totcol; } if(ob->bb) obn->bb= MEM_dupallocN(ob->bb); diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index d540151337d..1e3105f5c97 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1343,6 +1343,7 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) /* 2 */ basenew->object->data= menew= add_mesh(me->id.name); /* empty */ + assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */ me->id.us--; make_editMesh(scene, basenew->object); emnew= menew->edit_mesh; -- cgit v1.2.3 From 14f62c132136ba8696cf204fb421ba4f10414a6a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 8 Oct 2009 10:18:14 +0000 Subject: Smoke: * Enable external forces like e.g. wind --- intern/smoke/extern/smoke_API.h | 4 ++ intern/smoke/intern/FLUID_3D.cpp | 14 +++---- intern/smoke/intern/smoke_API.cpp | 15 +++++++ release/scripts/ui/buttons_physics_smoke.py | 15 ++++++- source/blender/blenkernel/intern/smoke.c | 58 +++++++++++++++++++++++----- source/blender/blenloader/intern/readfile.c | 7 ++++ source/blender/blenloader/intern/writefile.c | 3 ++ source/blender/makesdna/DNA_smoke_types.h | 3 +- source/blender/makesrna/intern/rna_smoke.c | 5 +++ 9 files changed, 105 insertions(+), 19 deletions(-) diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h index 5607df70cf3..ea106c81303 100644 --- a/intern/smoke/extern/smoke_API.h +++ b/intern/smoke/extern/smoke_API.h @@ -50,6 +50,10 @@ float *smoke_get_velocity_x(struct FLUID_3D *fluid); float *smoke_get_velocity_y(struct FLUID_3D *fluid); float *smoke_get_velocity_z(struct FLUID_3D *fluid); +float *smoke_get_force_x(struct FLUID_3D *fluid); +float *smoke_get_force_y(struct FLUID_3D *fluid); +float *smoke_get_force_z(struct FLUID_3D *fluid); + unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid); size_t smoke_get_index(int x, int max_x, int y, int max_y, int z); diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index bb2227801c7..729d73bb4f3 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -184,13 +184,6 @@ void FLUID_3D::step() { // addSmokeTestCase(_density, _res); // addSmokeTestCase(_heat, _res); - - // wipe forces - for (int i = 0; i < _totalCells; i++) - { - _xForce[i] = _yForce[i] = _zForce[i] = 0.0f; - // _obstacles[i] &= ~2; - } wipeBoundaries(); @@ -232,6 +225,13 @@ void FLUID_3D::step() // todo xxx dg: only clear obstacles, not boundaries // memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes); + + // wipe forces + // for external forces we can't do it at the beginning of this function but at the end + for (int i = 0; i < _totalCells; i++) + { + _xForce[i] = _yForce[i] = _zForce[i] = 0.0f; + } } ////////////////////////////////////////////////////////////////////// diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index 67df6e805d8..2d1d590fcc0 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -235,6 +235,21 @@ extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid) return fluid->_zVelocity; } +extern "C" float *smoke_get_force_x(FLUID_3D *fluid) +{ + return fluid->_xForce; +} + +extern "C" float *smoke_get_force_y(FLUID_3D *fluid) +{ + return fluid->_yForce; +} + +extern "C" float *smoke_get_force_z(FLUID_3D *fluid) +{ + return fluid->_zForce; +} + extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt) { return wt ? wt->getDensityBig() : NULL; diff --git a/release/scripts/ui/buttons_physics_smoke.py b/release/scripts/ui/buttons_physics_smoke.py index 1541b0bae14..53a7ec9c10c 100644 --- a/release/scripts/ui/buttons_physics_smoke.py +++ b/release/scripts/ui/buttons_physics_smoke.py @@ -1,7 +1,8 @@ import bpy -from buttons_particle import point_cache_ui +from buttons_physics_common import point_cache_ui +from buttons_physics_common import effector_weights_ui class PhysicButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' @@ -171,8 +172,20 @@ class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel): cache = md.point_cache_high point_cache_ui(self, cache, cache.baked==False, 0, 1) + +class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel): + __label__ = "Smoke Field Weights" + __default_closed__ = True + + def poll(self, context): + return (context.smoke) + + def draw(self, context): + domain = context.smoke.domain_settings + effector_weights_ui(self, domain.effector_weights) bpy.types.register(PHYSICS_PT_smoke) +bpy.types.register(PHYSICS_PT_smoke_field_weights) bpy.types.register(PHYSICS_PT_smoke_cache) bpy.types.register(PHYSICS_PT_smoke_highres) bpy.types.register(PHYSICS_PT_smoke_groups) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index f1fae4fa678..c1e79651c59 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -53,6 +53,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" +#include "BKE_effect.h" #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_pointcache.h" @@ -547,6 +548,10 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd) if(smd->domain->wt) smoke_turbulence_free(smd->domain->wt); + if(smd->domain->effector_weights) + MEM_freeN(smd->domain->effector_weights); + smd->domain->effector_weights = NULL; + BKE_ptcache_free_list(&(smd->domain->ptcaches[0])); smd->domain->point_cache[0] = NULL; BKE_ptcache_free_list(&(smd->domain->ptcaches[1])); @@ -714,6 +719,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->diss_speed = 5; // init 3dview buffer smd->domain->viewsettings = 0; + smd->domain->effector_weights = BKE_add_effector_weights(NULL); } else if(smd->type & MOD_SMOKE_TYPE_FLOW) { @@ -938,21 +944,53 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) } // do effectors - /* - if(sds->eff_group) { - for(go = sds->eff_group->gobject.first; go; go = go->next) + ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); + + if(effectors) { - if(go->ob) - { - if(ob->pd) - { - - } + float *density = smoke_get_density(sds->fluid); + float *force_x = smoke_get_force_x(sds->fluid); + float *force_y = smoke_get_force_y(sds->fluid); + float *force_z = smoke_get_force_z(sds->fluid); + float *velocity_x = smoke_get_velocity_x(sds->fluid); + float *velocity_y = smoke_get_velocity_y(sds->fluid); + float *velocity_z = smoke_get_velocity_z(sds->fluid); + int x, y, z; + + // precalculate wind forces + for(x = 0; x < sds->res[0]; x++) + for(y = 0; y < sds->res[1]; y++) + for(z = 0; z < sds->res[2]; z++) + { + EffectedPoint epoint; + float voxelCenter[3], vel[3], retvel[3]; + + unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + + if(density[index] < FLT_EPSILON) + continue; + + vel[0] = velocity_x[index]; + vel[1] = velocity_y[index]; + vel[2] = velocity_z[index]; + + voxelCenter[0] = sds->p0[0] + sds->dx * x + sds->dx * 0.5; + voxelCenter[1] = sds->p0[1] + sds->dx * y + sds->dx * 0.5; + voxelCenter[2] = sds->p0[2] + sds->dx * z + sds->dx * 0.5; + + pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); + pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + + // TODO dg - do in force! + force_x[index] += MIN2(MAX2(-1.0, retvel[0] * 0.002), 1.0); + force_y[index] += MIN2(MAX2(-1.0, retvel[1] * 0.002), 1.0); + force_z[index] += MIN2(MAX2(-1.0, retvel[2] * 0.002), 1.0); } } + + pdEndEffectors(&effectors); } - */ // do collisions if(1) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 989e2b3fa9e..a832cae161b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3655,6 +3655,8 @@ static void lib_link_object(FileData *fd, Main *main) smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group); smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group); smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group); + + smd->domain->effector_weights->group = newlibadr(fd, ob->id.lib, smd->domain->effector_weights->group); } } @@ -3784,6 +3786,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->domain->tex_shadow = NULL; smd->domain->tex_wt = NULL; + if(smd->domain->effector_weights) + smd->domain->effector_weights = newdataadr(fd, smd->domain->effector_weights); + else + smd->domain->effector_weights = BKE_add_effector_weights(NULL); + direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0])); direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1])); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index c92c0909d3b..25cbd4b65e7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1153,7 +1153,10 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) SmokeModifierData *smd = (SmokeModifierData*) md; if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + { writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain); + writestruct(wd, DATA, "EffectorWeights", 1, smd->domain->effector_weights); + } else if(smd->type & MOD_SMOKE_TYPE_FLOW) writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow); else if(smd->type & MOD_SMOKE_TYPE_COLL) diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index 4e4714cdaa1..6cf308aa0ad 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -45,7 +45,7 @@ typedef struct SmokeDomainSettings { struct SmokeModifierData *smd; /* for fast RNA access */ struct FLUID_3D *fluid; struct Group *fluid_group; - struct Group *eff_group; // effector group for e.g. wind force + struct Group *eff_group; // UNUSED struct Group *coll_group; // collision objects group struct WTURBULENCE *wt; // WTURBULENCE object, if active struct GPUTexture *tex; @@ -75,6 +75,7 @@ typedef struct SmokeDomainSettings { int v3dnum; struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */ struct ListBase ptcaches[2]; + struct EffectorWeights *effector_weights; } SmokeDomainSettings; diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 7bccd685c1d..c8193bb4005 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -220,6 +220,11 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]"); RNA_def_property_ui_text(prop, "Point Cache", ""); + + prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "EffectorWeights"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Effector Weights", ""); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) -- cgit v1.2.3 From c1302cfa95b725601bfb35760cc670b92bc2ae57 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Thu, 8 Oct 2009 11:12:03 +0000 Subject: 2.5 MSVC9 projectfiles Quick update: * added new raytrace lib * added gpu_buffer.c --- projectfiles_vc9/blender/blender.sln | 26 ++++++++++++++++++++++- projectfiles_vc9/blender/gpu/BL_gpu.vcproj | 4 ++++ projectfiles_vc9/blender/render/BRE_render.vcproj | 16 ++++++++++++-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/projectfiles_vc9/blender/blender.sln b/projectfiles_vc9/blender/blender.sln index d7c16229049..936e444ed12 100644 --- a/projectfiles_vc9/blender/blender.sln +++ b/projectfiles_vc9/blender/blender.sln @@ -13,6 +13,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj", {884D8731-654C-4C7F-9A75-8F37A305BE1E} = {884D8731-654C-4C7F-9A75-8F37A305BE1E} {79D0B232-208C-F208-DA71-79B4AC088602} = {79D0B232-208C-F208-DA71-79B4AC088602} {E645CC32-4823-463E-82F0-46ADDE664018} = {E645CC32-4823-463E-82F0-46ADDE664018} + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1} = {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1} {7495FE37-933A-4AC1-BB2A-B3FDB4DE4284} = {7495FE37-933A-4AC1-BB2A-B3FDB4DE4284} {51FB3D48-2467-4BFA-A321-D848252B437E} = {51FB3D48-2467-4BFA-A321-D848252B437E} {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} @@ -61,6 +62,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BKE_blenkernel", "blenkernel\BKE_blenkernel.vcproj", "{CAE37E91-6570-43AC-A4B4-7A37A4B0FC94}" ProjectSection(ProjectDependencies) = postProject {02110D03-59DB-4571-8787-72B3C03B2F2D} = {02110D03-59DB-4571-8787-72B3C03B2F2D} + {138DD16C-CC78-4F6C-A898-C8DA68D89067} = {138DD16C-CC78-4F6C-A898-C8DA68D89067} {9C71A793-C177-4CAB-8EC5-923D500B39F8} = {9C71A793-C177-4CAB-8EC5-923D500B39F8} EndProjectSection EndProject @@ -231,9 +233,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EXT_build_install_all", ".. {79D0B232-208C-F208-DA71-79B4AC088602} = {79D0B232-208C-F208-DA71-79B4AC088602} {FFD3C64A-30E2-4BC7-BC8F-51818C320400} = {FFD3C64A-30E2-4BC7-BC8F-51818C320400} {EADC3C5A-6C51-4F03-8038-1553E7D7F740} = {EADC3C5A-6C51-4F03-8038-1553E7D7F740} - {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} {8BFA4082-773B-D100-BC24-659083BA023F} = {8BFA4082-773B-D100-BC24-659083BA023F} {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "INT_boolop", "..\..\intern\boolop\make\msvc_9_0\boolop.vcproj", "{EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}" @@ -328,6 +330,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EXT_lzma", "..\..\extern\lz EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EXT_lzo", "..\..\extern\lzo\make\msvc_9_0\lzo.vcproj", "{8BFA4082-773B-D100-BC24-659083BA023F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BRE_raytrace", "render\BRE_raytrace.vcproj", "{37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution 3D Plugin Debug|Win32 = 3D Plugin Debug|Win32 @@ -1545,6 +1549,26 @@ Global {8BFA4082-773B-D100-BC24-659083BA023F}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32 {8BFA4082-773B-D100-BC24-659083BA023F}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32 {8BFA4082-773B-D100-BC24-659083BA023F}.Release|Win32.Build.0 = 3D Plugin Release|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3D Plugin Debug|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3D Plugin Debug|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3D Plugin Release|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3D Plugin Release|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3DPlugin Debug|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3DPlugin Debug|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3DPlugin Release|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.3DPlugin Release|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Blender Debug|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Blender Release|Win32.ActiveCfg = Blender Release|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Blender Release|Win32.Build.0 = Blender Release|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.BlenderPlayer Release|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.BlenderPlayer Release|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Debug|Win32.ActiveCfg = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Debug|Win32.Build.0 = Blender Debug|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Release|Win32.ActiveCfg = Blender Release|Win32 + {37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Release|Win32.Build.0 = Blender Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj index db96ab440b9..0b2927e9ee2 100644 --- a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj +++ b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj @@ -474,6 +474,10 @@ Name="Source Files" Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" > + + diff --git a/projectfiles_vc9/blender/render/BRE_render.vcproj b/projectfiles_vc9/blender/render/BRE_render.vcproj index 4b223ddcdc3..358549f19c1 100644 --- a/projectfiles_vc9/blender/render/BRE_render.vcproj +++ b/projectfiles_vc9/blender/render/BRE_render.vcproj @@ -215,11 +215,23 @@ > + + + + + + Date: Thu, 8 Oct 2009 11:24:06 +0000 Subject: Fixed #19571 (was crashing when building a raytree from a scene withouth any geometry) --- source/blender/render/extern/include/RE_raytrace.h | 1 + .../blender/render/intern/raytrace/rayobject.cpp | 40 ++++++++++++++++++++++ source/blender/render/intern/source/rayshade.c | 6 ++++ 3 files changed, 47 insertions(+) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index 22d55bb1a91..7d430d5550a 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -83,6 +83,7 @@ void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max); /* RayObject constructors */ RayObject* RE_rayobject_octree_create(int ocres, int size); RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); +RayObject* RE_rayobject_empty_create(); RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ RayObject* RE_rayobject_vbvh_create(int size); /* raytrace/rayobject_vbvh.c */ diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 95387cf1ee4..621fd3f794e 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -535,3 +535,43 @@ int RE_rayobjectcontrol_test_break(RayObjectControl *control) return 0; } + + +/* + * Empty raytree + */ +static int RE_rayobject_empty_intersect(RayObject *o, Isect *is) +{ + return 0; +} + +static void RE_rayobject_empty_free(RayObject *o) +{ +} + +static void RE_rayobject_empty_bb(RayObject *o, float *min, float *max) +{ + return; +} + +static float RE_rayobject_empty_cost(RayObject *o) +{ + return 0.0; +} + +static RayObjectAPI empty_api = +{ + RE_rayobject_empty_intersect, + NULL, //static void RE_rayobject_instance_add(RayObject *o, RayObject *ob); + NULL, //static void RE_rayobject_instance_done(RayObject *o); + RE_rayobject_empty_free, + RE_rayobject_empty_bb, + RE_rayobject_empty_cost +}; + +static RayObject empty_raytree = { &empty_api, {0, 0} }; + +RayObject *RE_rayobject_empty_create() +{ + return RE_rayobject_unalignRayAPI( &empty_raytree ); +} diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 881a549ad96..4ad4d6370f8 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -335,6 +335,12 @@ static void makeraytree_single(Render *re) } } + if(faces + special == 0) + { + re->raytree = RE_rayobject_empty_create(); + return; + } + //Create raytree raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special ); -- cgit v1.2.3 From 5ce33cf2bd2def709c9124cc6a7e538e388f1d62 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 8 Oct 2009 11:29:27 +0000 Subject: A few fixes: * Loading old files didn't initialise the new rotation variables properly * Fixed some errors with the newly added operator for copying RNA-paths for properties * Auto-keyframing now correctly refreshes animation editors after adding keyframes. Made the keyingsets code send notifiers again, but now using the newly added WM_main_event_add() (thanks Brecht) * A few UI tweaks again for animation stuff (timeline, keyingsets UI) --- release/scripts/ui/buttons_object.py | 2 -- release/scripts/ui/buttons_scene.py | 4 ++-- release/scripts/ui/space_time.py | 2 +- source/blender/blenloader/intern/readfile.c | 18 ++++++++++++++++++ source/blender/editors/animation/drivers.c | 13 ++++++------- source/blender/editors/animation/keyingsets.c | 7 +++++++ source/blender/editors/interface/interface_anim.c | 7 ++++--- source/blender/editors/space_outliner/outliner.c | 2 ++ source/blender/makesrna/intern/rna_animation_api.c | 1 + 9 files changed, 41 insertions(+), 15 deletions(-) diff --git a/release/scripts/ui/buttons_object.py b/release/scripts/ui/buttons_object.py index d546ddb8fd8..98ac462f2d4 100644 --- a/release/scripts/ui/buttons_object.py +++ b/release/scripts/ui/buttons_object.py @@ -26,8 +26,6 @@ class OBJECT_PT_transform(ObjectButtonsPanel): ob = context.object - - row = layout.row() row.column().itemR(ob, "location") diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 9bd0019bd6c..2b153737be3 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -474,7 +474,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel): scene = context.scene row = layout.row() - row.itemL(text="Keying Sets") + row.itemL(text="Keying Sets:") row = layout.row() @@ -512,7 +512,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): ks = scene.active_keying_set row = layout.row() - row.itemL(text="Paths") + row.itemL(text="Paths:") row = layout.row() diff --git a/release/scripts/ui/space_time.py b/release/scripts/ui/space_time.py index 696dcf18623..fdb01d5c216 100644 --- a/release/scripts/ui/space_time.py +++ b/release/scripts/ui/space_time.py @@ -100,7 +100,7 @@ class TIME_MT_frame(bpy.types.Menu): layout.itemS() sub = layout.row() - sub.active = tools.enable_auto_key + #sub.active = tools.enable_auto_key sub.itemM("TIME_MT_autokey") class TIME_MT_playback(bpy.types.Menu): diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a832cae161b..ae18d7cac01 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9912,6 +9912,24 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put 2.50 compatibility code here until next subversion bump */ { + Object *ob; + + /* New variables for axis-angle rotations and/or quaternion rotations were added, and need proper initialisation */ + for (ob= main->object.first; ob; ob= ob->id.next) { + /* new variables for all objects */ + ob->quat[0]= 1.0f; + ob->rotAxis[1]= 1.0f; + + /* bones */ + if (ob->pose) { + bPoseChannel *pchan; + + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + /* just need to initalise rotation axis properly... */ + pchan->rotAxis[1]= 1.0f; + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 7a457548623..bf3fd0f4cf1 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -565,7 +565,7 @@ void ANIM_OT_paste_driver_button (wmOperatorType *ot) } -/* Paste Driver Button Operator ------------------------ */ +/* Copy to Clipboard Button Operator ------------------------ */ static int copy_clipboard_button_exec(bContext *C, wmOperator *op) { @@ -579,9 +579,9 @@ static int copy_clipboard_button_exec(bContext *C, wmOperator *op) memset(&ptr, 0, sizeof(PointerRNA)); uiAnimContextProperty(C, &ptr, &prop, &index); - if (ptr.data && prop) { // && RNA_property_animateable(ptr.data, prop) + if (ptr.data && prop) { path= RNA_path_from_ID_to_property(&ptr, prop); - + if (path) { WM_clipboard_text_set(path, FALSE); MEM_freeN(path); @@ -597,15 +597,14 @@ void ANIM_OT_copy_clipboard_button(wmOperatorType *ot) /* identifiers */ ot->name= "Copy Data Path"; ot->idname= "ANIM_OT_copy_clipboard_button"; - ot->description= "Copy the rna data path to the clipboard."; + ot->description= "Copy the RNA data path for this property to the clipboard."; /* callbacks */ ot->exec= copy_clipboard_button_exec; - //op->poll= ??? // TODO: need to have some driver to be able to do this... + //op->poll= ??? // TODO: need to have some valid property before this can be done /* flags */ - ot->flag= 0; + ot->flag= OPTYPE_REGISTER; } - /* ************************************************** */ diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index afaa9e3f400..d1ac624ec6f 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -349,6 +349,7 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op) /* add path to this setting */ BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME); + ks->active_path= BLI_countlist(&ks->paths); success= 1; /* free the temp path created */ @@ -1354,6 +1355,9 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet } break; } + + /* send notifiers for updates (this doesn't require context to work!) */ + WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } } } @@ -1484,6 +1488,9 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet } break; } + + /* send notifiers for updates (this doesn't require context to work!) */ + WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } } } diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index facda32a41e..ca7401c36be 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -309,10 +309,11 @@ void ui_but_anim_menu(bContext *C, uiBut *but) uiItemO(layout, "Remove from Keying Set", 0, "ANIM_OT_remove_keyingset_button"); } } - + uiItemS(layout); - uiItemBooleanO(layout, "Copy Data Path", 0, "ANIM_OT_copy_clipboard_button", "all", 1); - + + uiItemO(layout, "Copy Data Path", 0, "ANIM_OT_copy_clipboard_button"); + uiPupMenuEnd(C, pup); } } diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 3c10375c14b..641137c010b 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -3939,6 +3939,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa /* add a new path with the information obtained (only if valid) */ // TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name BKE_keyingset_add_destination(ks, id, NULL, path, array_index, flag, groupmode); + ks->active_path= BLI_countlist(&ks->paths); } break; case KEYINGSET_EDITMODE_REMOVE: @@ -3950,6 +3951,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa /* free path's data */ // TODO: we probably need an API method for this if (ksp->rna_path) MEM_freeN(ksp->rna_path); + ks->active_path= 0; /* remove path from set */ BLI_freelinkN(&ks->paths, ksp); diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c index 6af87335e02..5852c494936 100644 --- a/source/blender/makesrna/intern/rna_animation_api.c +++ b/source/blender/makesrna/intern/rna_animation_api.c @@ -54,6 +54,7 @@ static void rna_KeyingSet_add_destination(KeyingSet *keyingset, ReportList *repo /* if data is valid, call the API function for this */ if (keyingset) { BKE_keyingset_add_destination(keyingset, id, group_name, rna_path, array_index, flag, grouping_method); + keyingset->active_path= BLI_countlist(&keyingset->paths); } else { BKE_report(reports, RPT_ERROR, "Keying Set Destination could not be added."); -- cgit v1.2.3 From ab287786b1e94d6b38ffda3d595ef90c664d78fe Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Thu, 8 Oct 2009 12:13:23 +0000 Subject: 2.5 MSVC projectfiles_vc9 eek, forgot to add file in last commit --- .../blender/render/BRE_raytrace.vcproj | 230 +++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 projectfiles_vc9/blender/render/BRE_raytrace.vcproj diff --git a/projectfiles_vc9/blender/render/BRE_raytrace.vcproj b/projectfiles_vc9/blender/render/BRE_raytrace.vcproj new file mode 100644 index 00000000000..95a5f2f92fd --- /dev/null +++ b/projectfiles_vc9/blender/render/BRE_raytrace.vcproj @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 8056d27bac7e8c1122af5d854c6f0aefc7de5b55 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 12:33:51 +0000 Subject: Alt+A in the sequencer now redraws other sequencer views, not ideal but ok for now. --- source/blender/editors/screen/screen_ops.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index ad0218f3b80..8d8c2eba2a8 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2347,7 +2347,14 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event) ED_screen_animation_timer_update(C, stime->redraws); } else { - ED_screen_animation_timer(C, TIME_REGION|TIME_ALL_3D_WIN, sync, mode); + int redraws = TIME_REGION|TIME_ALL_3D_WIN; + + /* XXX - would like a better way to deal with this situation - Campbell */ + if((sa) && (sa->spacetype == SPACE_SEQ)) { + redraws |= TIME_SEQ; + } + + ED_screen_animation_timer(C, redraws, sync, mode); if(screen->animtimer) { wmTimer *wt= screen->animtimer; -- cgit v1.2.3 From b8354a2da84c997dc03d3b3fb2ce327653de320c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 14:11:06 +0000 Subject: unselected group color was too hard to see in the 3D view, made darker --- source/blender/editors/interface/resources.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index ee7db07f3c8..26a50cc3c24 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -456,7 +456,7 @@ void ui_theme_init_userdef(void) SETCOL(btheme->tv3d.lamp, 0, 0, 0, 40); SETCOL(btheme->tv3d.select, 241, 88, 0, 255); SETCOL(btheme->tv3d.active, 255, 140, 25, 255); - SETCOL(btheme->tv3d.group, 16, 64, 16, 255); + SETCOL(btheme->tv3d.group, 8, 48, 8, 255); SETCOL(btheme->tv3d.group_active, 85, 187, 85, 255); SETCOL(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255); SETCOL(btheme->tv3d.vertex, 0, 0, 0, 255); @@ -1018,7 +1018,7 @@ void init_userdef_do_versions(void) } /* Group theme colors */ if(btheme->tv3d.group[3]==0) { - SETCOL(btheme->tv3d.group, 0x10, 0x40, 0x10, 255); + SETCOL(btheme->tv3d.group, 0x0C, 0x30, 0x0C, 255); SETCOL(btheme->tv3d.group_active, 0x66, 0xFF, 0x66, 255); } /* Sequence editor theme*/ -- cgit v1.2.3 From 248de36c63a51a600303aba74bbf7b188a90fd95 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 8 Oct 2009 15:02:01 +0000 Subject: netrender: bugfix by matd on irc. unbound var when broadcast is off --- release/scripts/io/netrender/master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py index be23fda7a91..1c83e758ce5 100644 --- a/release/scripts/io/netrender/master.py +++ b/release/scripts/io/netrender/master.py @@ -744,7 +744,7 @@ def runMaster(address, broadcast, path, update_stats, test_break): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - start_time = time.time() + start_time = time.time() while not test_break(): httpd.handle_request() -- cgit v1.2.3 From e936c809851ee99736827ecb6935ffb2cc06da9b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 8 Oct 2009 15:19:57 +0000 Subject: Smoke: * Bugfix for non initialized arrays (reported by nudelZ) --- source/blender/blenkernel/intern/smoke.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index c1e79651c59..fbc052db6f3 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -964,8 +964,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) for(z = 0; z < sds->res[2]; z++) { EffectedPoint epoint; - float voxelCenter[3], vel[3], retvel[3]; - + float voxelCenter[3] = {0,0,0} , vel[3] = {0,0,0} , retvel[3] = {0,0,0}; unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); if(density[index] < FLT_EPSILON) @@ -983,9 +982,9 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); // TODO dg - do in force! - force_x[index] += MIN2(MAX2(-1.0, retvel[0] * 0.002), 1.0); - force_y[index] += MIN2(MAX2(-1.0, retvel[1] * 0.002), 1.0); - force_z[index] += MIN2(MAX2(-1.0, retvel[2] * 0.002), 1.0); + force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); + force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); + force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); } } -- cgit v1.2.3 From 88613b9184c2df08a2de58263b8f8e948543a0a1 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Thu, 8 Oct 2009 15:28:31 +0000 Subject: Cocoa port : Bug fix : newly created window not seen as activated by WM Added more conservative memory management (may need to optimize later) --- intern/ghost/intern/GHOST_SystemCocoa.mm | 6 ++++-- intern/ghost/intern/GHOST_WindowCocoa.mm | 10 +++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index fe3cd80f265..94ed5c7c2ac 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -806,7 +806,10 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( GHOST_ASSERT(m_windowManager, "m_windowManager not initialized"); m_windowManager->addWindow(window); m_windowManager->setActiveWindow(window); - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); + //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation) + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window)); + pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); + } else { GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n"); @@ -1156,7 +1159,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_IWindow* window = m_windowManager->getActiveWindow(); if (!window) { - printf("\nM invalid window"); return GHOST_kFailure; } diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 4d117d25df3..a185aa036b1 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -319,7 +319,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() /*if(ugly_hack==m_windowRef) ugly_hack= NULL; if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);*/ - + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [m_openGLView release]; if (m_window) { @@ -327,6 +327,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() [m_window release]; m_window = nil; } + [pool drain]; } #pragma mark accessors @@ -566,7 +567,9 @@ GHOST_TSuccess GHOST_WindowCocoa::swapBuffers() { if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [m_openGLContext flushBuffer]; + [pool drain]; return GHOST_kSuccess; } } @@ -577,7 +580,9 @@ GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext() { if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [m_openGLContext update]; + [pool drain]; return GHOST_kSuccess; } } @@ -588,6 +593,8 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext() { if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { if (m_openGLContext != nil) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_openGLContext makeCurrentContext]; #ifdef GHOST_DRAW_CARBON_GUTTER // Restrict drawing to non-gutter area @@ -603,6 +610,7 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext() }; GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b); #endif //GHOST_DRAW_CARBON_GUTTER + [pool drain]; return GHOST_kSuccess; } } -- cgit v1.2.3 From 66634e2be41be8530bec49b3bab27dfa4ea176d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 15:29:43 +0000 Subject: toggle buttons for texture channels (hardcoded like UV layer buttons) --- source/blender/editors/interface/interface_templates.c | 4 ++++ source/blender/makesrna/intern/rna_material.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 5b93f9ee06d..d94d2be3a94 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2070,6 +2070,10 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &itemptr, "active_render", 0, 0, 0, 0, 0, NULL); uiBlockSetEmboss(block, UI_EMBOSS); } + else if (itemptr.type == &RNA_MaterialTextureSlot) { + uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL); + } + /* XXX - end hardcoded cruft */ if(name) MEM_freeN(name); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 28fcc3103b8..b22b5916362 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1730,6 +1730,13 @@ void RNA_def_material(BlenderRNA *brna) rna_def_mtex_common(srna, "rna_Material_mtex_begin", "rna_Material_active_texture_get", "rna_Material_active_texture_set", "MaterialTextureSlot", "rna_Material_update"); + /* only material has this one */ + prop= RNA_def_property(srna, "use_textures", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "septex", 1); + RNA_def_property_array(prop, 18); + RNA_def_property_ui_text(prop, "Use Textures", "Enable/Disable each texture."); + RNA_def_property_update(prop, 0, "rna_Material_update"); + rna_def_material_colors(srna); rna_def_material_diffuse(srna); rna_def_material_specularity(srna); -- cgit v1.2.3 From ff07676b4047719236186e605d6578e1816b6cdc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 15:50:42 +0000 Subject: bring back automerge - [#19538] automerge editing doesn't work --- source/blender/editors/mesh/editmesh_mods.c | 34 ++++++++++++---------- source/blender/editors/mesh/mesh_intern.h | 2 +- .../editors/transform/transform_conversions.c | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index a23a6dde652..4c9f63f910c 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -117,22 +117,26 @@ void EM_select_mirrored(Object *obedit, EditMesh *em) } } -void EM_automerge(int update) +void EM_automerge(Scene *scene, Object *obedit, int update) { -// XXX int len; - -// if ((scene->automerge) && -// (obedit && obedit->type==OB_MESH) && -// (((Mesh*)obedit->data)->mr==NULL) -// ) { -// len = removedoublesflag(1, 1, scene->toolsettings->doublimit); -// if (len) { -// em->totvert -= len; /* saves doing a countall */ -// if (update) { -// DAG_id_flush_update(obedit->data, OB_RECALC_DATA); -// } -// } -// } + Mesh *me= (Mesh*)obedit->data; /* can be NULL */ + int len; + + if ((scene->toolsettings->automerge) && + (obedit && obedit->type==OB_MESH && obedit->mode==OB_MODE_EDIT) && + (me->mr==NULL) + ) { + Mesh *me= (Mesh*)obedit->data; + EditMesh *em= me->edit_mesh; + + len = removedoublesflag(em, 1, 1, scene->toolsettings->doublimit); + if (len) { + em->totvert -= len; /* saves doing a countall */ + if (update) { + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + } + } + } } /* ****************************** SELECTION ROUTINES **************** */ diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 37a6d0f384f..7ee7fe1ebde 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -167,7 +167,7 @@ void MESH_OT_vertices_smooth(struct wmOperatorType *ot); void MESH_OT_flip_normals(struct wmOperatorType *ot); extern EditEdge *findnearestedge(ViewContext *vc, int *dist); -extern void EM_automerge(int update); +extern void EM_automerge(Scene *scene, Object *obedit, int update); void editmesh_select_by_material(EditMesh *em, int index); void righthandfaces(EditMesh *em, int select); /* makes faces righthand turning */ void EM_select_more(EditMesh *em); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a9c3e4676a0..51ce87803fd 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4477,8 +4477,8 @@ void special_aftertrans_update(TransInfo *t) if (t->spacetype==SPACE_VIEW3D) { if (t->obedit) { if (cancelled==0) { + EM_automerge(t->scene, t->obedit, 1); #if 0 // TRANSFORM_FIX_ME - EM_automerge(1); /* when snapping, delay retopo until after automerge */ if (G.qual & LR_CTRLKEY) { retopo_do_all(); -- cgit v1.2.3 From d01c737283fddac411904a3d469495da71c48cd2 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Thu, 8 Oct 2009 17:13:57 +0000 Subject: Cocoa port : Quick&dirty bug fix to catch ad discard tablet induced exceptions. I'll make a clean fix upon getting a tablet to debug. --- intern/ghost/intern/GHOST_SystemCocoa.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 94ed5c7c2ac..7f98f67a1ba 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1098,7 +1098,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) NSUInteger tabletEvent; //Handle tablet events combined with mouse events - switch ([event subtype]) { + @try { + switch ([event subtype]) { case NX_SUBTYPE_TABLET_POINT: tabletEvent = NSTabletPoint; break; @@ -1109,8 +1110,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) default: tabletEvent = [event type]; break; + } + } + @catch (NSException * e) { + //FIXME: check why we get such exceptions when using a tablet + return GHOST_kFailure; } + switch (tabletEvent) { case NSTabletPoint: ct.Pressure = [event tangentialPressure]; -- cgit v1.2.3 From e0c5e484732bb344fb845acc2678777e4bff1d5c Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Thu, 8 Oct 2009 17:32:51 +0000 Subject: Scripts ------- Port of MDD export script to Blender 2.5. --- release/scripts/io/export_mdd.py | 188 +++++++++++++++++++++++++++++++++++++++ release/scripts/ui/space_info.py | 1 + 2 files changed, 189 insertions(+) create mode 100644 release/scripts/io/export_mdd.py diff --git a/release/scripts/io/export_mdd.py b/release/scripts/io/export_mdd.py new file mode 100644 index 00000000000..f0e366ea505 --- /dev/null +++ b/release/scripts/io/export_mdd.py @@ -0,0 +1,188 @@ +#!BPY + +""" + Name: 'Vertex Keyframe Animation (.mdd)...' + Blender: 242 + Group: 'Export' + Tooltip: 'Animated mesh to MDD vertex keyframe file.' +""" + +__author__ = "Bill L.Nieuwendorp" +__bpydoc__ = """\ +This script Exports Lightwaves MotionDesigner format. + +The .mdd format has become quite a popular Pipeline format
+for moving animations from package to package. + +Be sure not to use modifiers that change the number or order of verts in the mesh +""" +#Please send any fixes,updates,bugs to Slow67_at_Gmail.com or cbarton_at_metavr.com +#Bill Niewuendorp +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +import bpy +import Mathutils +import math +import os + +#import Blender +#from Blender import * +#import BPyMessages +try: + from struct import pack +except: + pack = None + +def zero_file(filepath): + ''' + If a file fails, this replaces it with 1 char, better not remove it? + ''' + file = open(filepath, 'w') + file.write('\n') # apparently macosx needs some data in a blank file? + file.close() + +def check_vertcount(mesh,vertcount): + ''' + check and make sure the vertcount is consistent throughout the frame range + ''' + if len(mesh.verts) != vertcount: + raise Exception('Error, number of verts has changed during animation, cannot export') + f.close() + zero_file(filepath) + return + + +def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS): + if not pack: + raise Exception('Error, this script requires the "pack" module') + + if ob.type != 'MESH': + raise Exception('Error, active object is not a mesh') + """ + Window.EditMode(0) + Blender.Window.WaitCursor(1) + + mesh_orig = Mesh.New() + mesh_orig.getFromObject(ob.name) + """ + orig_frame = sce.current_frame + sce.set_frame(PREF_STARTFRAME) + me = ob.create_mesh(True, 'PREVIEW') + + #Flip y and z + mat_flip= Mathutils.Matrix(\ + [1.0, 0.0, 0.0, 0.0],\ + [0.0, 0.0, 1.0, 0.0],\ + [0.0, 1.0, 0.0, 0.0],\ + [0.0, 0.0, 0.0, 1.0],\ + ) + + numverts = len(me.verts) + + numframes = PREF_ENDFRAME-PREF_STARTFRAME+1 + PREF_FPS= float(PREF_FPS) + f = open(filename, 'wb') #no Errors yet:Safe to create file + + # Write the header + f.write(pack(">2i", numframes, numverts)) + + # Write the frame times (should we use the time IPO??) + f.write( pack(">%df" % (numframes), *[frame/PREF_FPS for frame in range(numframes)]) ) # seconds + + #rest frame needed to keep frames in sync + """ + Blender.Set('curframe', PREF_STARTFRAME) + me_tmp.getFromObject(ob.name) + """ + + check_vertcount(me,numverts) + me.transform(mat_flip * ob.matrix) + f.write(pack(">%df" % (numverts*3), *[axis for v in me.verts for axis in v.co])) + + for frame in range(PREF_STARTFRAME,PREF_ENDFRAME+1):#in order to start at desired frame + """ + Blender.Set('curframe', frame) + me_tmp.getFromObject(ob.name) + """ + + sce.set_frame(frame) + me = ob.create_mesh(True, 'PREVIEW') + check_vertcount(me,numverts) + me.transform(mat_flip * ob.matrix) + + # Write the vertex data + f.write(pack(">%df" % (numverts*3), *[axis for v in me.verts for axis in v.co])) + + """ + me_tmp.verts= None + """ + f.close() + + print ('MDD Exported: %s frames:%d\n'% (filename, numframes-1)) + """ + Blender.Window.WaitCursor(0) + Blender.Set('curframe', orig_frame) + """ + sce.set_frame(orig_frame) + +class EXPORT_OT_mdd(bpy.types.Operator): + '''Animated mesh to MDD vertex keyframe file.''' + __idname__ = "export.mdd" + __label__ = "Export MDD" + + # get first scene to get min and max properties for frames, fps + + sce = bpy.data.scenes[bpy.data.scenes.keys()[0]] + minframe = sce.rna_type.properties["current_frame"].soft_min + maxframe = sce.rna_type.properties["current_frame"].soft_max + minfps = sce.render_data.rna_type.properties["fps"].soft_min + maxfps = sce.render_data.rna_type.properties["fps"].soft_max + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + __props__ = [ + bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "tmp.mdd"), + bpy.props.IntProperty(attr="fps", name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25), + bpy.props.IntProperty(attr="start_frame", name="Start Frame", description="Start frame for baking", min=minframe,max=maxframe,default=1), + bpy.props.IntProperty(attr="end_frame", name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default= 250), + ] + + def poll(self, context): + return context.active_object != None + + def execute(self, context): + if not self.path: + raise Exception("filename not set") + write(self.path, context.scene, context.active_object, + self.start_frame, self.end_frame, self.fps ) + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + +bpy.ops.add(EXPORT_OT_mdd) + +if __name__=='__main__': + #if not pack: +# Draw.PupMenu('Error%t|This script requires a full python install') + #Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd')) + bpy.ops.EXPORT_OT_mdd(path="/tmp/test.mdd") + diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 49261981ac2..3805a7d0dec 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -98,6 +98,7 @@ class INFO_MT_file_export(bpy.types.Menu): layout.itemO("export.3ds", text="3DS") layout.itemO("export.fbx", text="FBX") layout.itemO("export.obj", text="OBJ") + layout.itemO("export.mdd", text="MDD") layout.itemO("export.ply", text="PLY") layout.itemO("export.x3d", text="X3D") -- cgit v1.2.3 From 3ebd58673fb9a8c5ef13048b2e8e8a4cb7bb3a4e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 8 Oct 2009 18:40:03 +0000 Subject: Key Configuration Keymaps are now saveable and configurable from the user preferences, note that editing one item in a keymap means the whole keymap is now defined by the user and will not be updated by Blender, an option for syncing might be added later. The outliner interface is still there, but I will probably remove it. There's actually 3 levels now: * Default builtin key configuration. * Key configuration loaded from .py file, for configs like Blender 2.4x or other 3D applications. * Keymaps edited by the user and saved in .B.blend. These can be saved to .py files as well to make creating distributable configurations easier. Also, user preferences sections were reorganized a bit, now there is: Interface, Editing, Input, Files and System. Implementation notes: * wmKeyConfig was added which represents a key configuration containing keymaps. * wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap. * Modal maps are not wrapped yet. * User preferences DNA file reading did not support newdataadr() yet, added this now for reading keymaps. * Key configuration related settings are now RNA wrapped. * is_property_set and is_property_hidden python methods were added. --- release/scripts/ui/space_userpref.py | 367 +++++++++++++++++--- source/blender/blenkernel/BKE_screen.h | 5 +- source/blender/blenkernel/intern/blender.c | 17 + source/blender/blenloader/intern/readfile.c | 96 ++++-- source/blender/blenloader/intern/writefile.c | 16 +- .../blender/editors/animation/anim_channels_edit.c | 4 +- source/blender/editors/animation/anim_markers.c | 4 +- source/blender/editors/animation/anim_ops.c | 4 +- source/blender/editors/armature/armature_ops.c | 8 +- source/blender/editors/curve/curve_ops.c | 6 +- source/blender/editors/gpencil/gpencil_ops.c | 6 +- source/blender/editors/include/ED_anim_api.h | 6 +- source/blender/editors/include/ED_armature.h | 4 +- source/blender/editors/include/ED_curve.h | 4 +- source/blender/editors/include/ED_gpencil.h | 4 +- source/blender/editors/include/ED_markers.h | 4 +- source/blender/editors/include/ED_mball.h | 4 +- source/blender/editors/include/ED_mesh.h | 5 +- source/blender/editors/include/ED_object.h | 4 +- source/blender/editors/include/ED_particle.h | 2 +- source/blender/editors/include/ED_physics.h | 4 +- source/blender/editors/include/ED_screen.h | 5 +- source/blender/editors/include/ED_sculpt.h | 4 +- source/blender/editors/include/ED_transform.h | 3 +- source/blender/editors/include/ED_uvedit.h | 4 +- source/blender/editors/include/UI_interface.h | 3 + source/blender/editors/include/UI_view2d.h | 4 +- source/blender/editors/interface/interface.c | 11 +- .../blender/editors/interface/interface_handlers.c | 16 +- .../blender/editors/interface/interface_layout.c | 38 +- source/blender/editors/interface/interface_utils.c | 4 +- source/blender/editors/interface/view2d_ops.c | 6 +- source/blender/editors/mesh/editmesh_mods.c | 48 ++- source/blender/editors/mesh/mesh_ops.c | 6 +- source/blender/editors/metaball/mball_ops.c | 4 +- source/blender/editors/object/object_ops.c | 10 +- source/blender/editors/physics/physics_ops.c | 10 +- source/blender/editors/screen/area.c | 12 +- source/blender/editors/screen/screen_ops.c | 18 +- source/blender/editors/sculpt_paint/paint_ops.c | 10 +- .../blender/editors/space_action/action_intern.h | 2 +- source/blender/editors/space_action/action_ops.c | 12 +- source/blender/editors/space_action/space_action.c | 4 +- source/blender/editors/space_api/spacetypes.c | 38 +- .../blender/editors/space_buttons/space_buttons.c | 6 +- .../blender/editors/space_console/space_console.c | 6 +- source/blender/editors/space_file/file_panels.c | 12 +- source/blender/editors/space_file/filelist.c | 2 +- source/blender/editors/space_file/filesel.c | 32 +- source/blender/editors/space_file/space_file.c | 20 +- source/blender/editors/space_graph/graph_intern.h | 2 +- source/blender/editors/space_graph/graph_ops.c | 14 +- source/blender/editors/space_graph/space_graph.c | 10 +- source/blender/editors/space_image/space_image.c | 16 +- source/blender/editors/space_info/space_info.c | 2 +- source/blender/editors/space_logic/space_logic.c | 8 +- source/blender/editors/space_nla/nla_intern.h | 2 +- source/blender/editors/space_nla/nla_ops.c | 20 +- source/blender/editors/space_nla/space_nla.c | 10 +- source/blender/editors/space_node/node_intern.h | 2 +- source/blender/editors/space_node/node_ops.c | 8 +- source/blender/editors/space_node/space_node.c | 2 +- source/blender/editors/space_outliner/outliner.c | 28 +- .../editors/space_outliner/outliner_intern.h | 2 +- .../blender/editors/space_outliner/outliner_ops.c | 4 +- .../editors/space_outliner/space_outliner.c | 2 +- .../blender/editors/space_script/script_intern.h | 2 +- source/blender/editors/space_script/script_ops.c | 4 +- source/blender/editors/space_script/space_script.c | 2 +- .../editors/space_sequencer/sequencer_intern.h | 5 +- .../editors/space_sequencer/sequencer_ops.c | 8 +- .../editors/space_sequencer/space_sequencer.c | 2 +- source/blender/editors/space_sound/space_sound.c | 4 +- source/blender/editors/space_text/space_text.c | 6 +- source/blender/editors/space_time/space_time.c | 2 +- source/blender/editors/space_time/time_intern.h | 2 +- source/blender/editors/space_time/time_ops.c | 4 +- .../editors/space_userpref/space_userpref.c | 4 +- source/blender/editors/space_view3d/space_view3d.c | 42 +-- source/blender/editors/space_view3d/view3d_edit.c | 18 +- .../blender/editors/space_view3d/view3d_intern.h | 10 +- source/blender/editors/space_view3d/view3d_ops.c | 18 +- source/blender/editors/space_view3d/view3d_view.c | 6 +- source/blender/editors/transform/transform.c | 6 +- source/blender/editors/transform/transform.h | 2 +- source/blender/editors/transform/transform_ops.c | 6 +- source/blender/editors/uvedit/uvedit_ops.c | 6 +- source/blender/makesdna/DNA_userdef_types.h | 10 + source/blender/makesdna/DNA_windowmanager_types.h | 65 +++- source/blender/makesrna/RNA_access.h | 30 +- source/blender/makesrna/RNA_types.h | 3 + source/blender/makesrna/intern/rna_access.c | 5 +- source/blender/makesrna/intern/rna_define.c | 1 + source/blender/makesrna/intern/rna_internal.h | 3 +- source/blender/makesrna/intern/rna_ui_api.c | 6 +- source/blender/makesrna/intern/rna_userdef.c | 94 ++--- source/blender/makesrna/intern/rna_wm.c | 383 ++++++++++++++++++++- source/blender/makesrna/intern/rna_wm_api.c | 74 +++- source/blender/python/intern/bpy_rna.c | 31 +- source/blender/windowmanager/WM_api.h | 38 +- source/blender/windowmanager/intern/wm.c | 36 +- .../blender/windowmanager/intern/wm_event_system.c | 17 +- source/blender/windowmanager/intern/wm_keymap.c | 326 ++++++++++++++---- source/blender/windowmanager/intern/wm_operators.c | 43 ++- source/blender/windowmanager/intern/wm_window.c | 8 +- source/blender/windowmanager/wm.h | 2 +- source/blender/windowmanager/wm_event_system.h | 1 - source/blender/windowmanager/wm_event_types.h | 12 +- 108 files changed, 1764 insertions(+), 639 deletions(-) diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 43c70dac4b1..ff4461db02f 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -12,6 +12,10 @@ class USERPREF_HT_header(bpy.types.Header): layout.operator_context = "EXEC_AREA" layout.itemO("wm.save_homefile", text="Save As Default") + + if userpref.active_section == 'INPUT': + layout.operator_context = "INVOKE_DEFAULT" + layout.itemO("wm.keyconfig_save", "Save Key Configuration...") class USERPREF_MT_view(bpy.types.Menu): __space_type__ = 'USER_PREFERENCES' @@ -31,14 +35,14 @@ class USERPREF_PT_tabs(bpy.types.Panel): layout.itemR(userpref, "active_section", expand=True) -class USERPREF_PT_view(bpy.types.Panel): +class USERPREF_PT_interface(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' - __label__ = "View" + __label__ = "Interface" __show_header__ = False def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'VIEW_CONTROLS') + return (userpref.active_section == 'INTERFACE') def draw(self, context): layout = self.layout @@ -87,37 +91,27 @@ class USERPREF_PT_view(bpy.types.Panel): sub1.itemR(view, "perspective_orthographic_switch") sub1.itemR(view, "smooth_view") sub1.itemR(view, "rotation_angle") - sub1.itemS() - sub1.itemL(text="NDOF Device:") - sub1.itemR(view, "ndof_pan_speed", text="Pan Speed") - sub1.itemR(view, "ndof_rotate_speed", text="Orbit Speed") col = split.column() sub = col.split(percentage=0.85) sub1 = sub.column() - sub1.itemL(text="Mouse Buttons:") - - sub2 = sub1.column() - sub2.enabled = (view.select_mouse == 'RIGHT') - sub2.itemR(view, "emulate_3_button_mouse") - sub1.itemL(text="Select With:") - sub1.row().itemR(view, "select_mouse", expand=True) - sub1.itemL(text="Middle Mouse:") - sub1.row().itemR(view, "middle_mouse", expand=True) - sub1.itemR(view, "use_middle_mouse_paste") - sub1.itemL(text="Mouse Wheel:") - sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom") - sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines") - sub1.itemL(text="Mouse Motion:") - sub1.itemR(view, "continuous_mouse", text="Continuous Grab") - sub1.itemS() sub1.itemL(text="Menus:") sub1.itemR(view, "open_mouse_over") sub1.itemL(text="Menu Open Delay:") sub1.itemR(view, "open_toplevel_delay", text="Top Level") sub1.itemR(view, "open_sublevel_delay", text="Sub Level") + sub1.itemS() + sub1.itemS() + sub1.itemS() + + sub1.itemL(text="Toolbox:") + sub1.itemR(view, "use_column_layout") + sub1.itemL(text="Open Toolbox Delay:") + sub1.itemR(view, "open_left_mouse_delay", text="Hold LMB") + sub1.itemR(view, "open_right_mouse_delay", text="Hold RMB") + col = split.column() sub = col.split(percentage=0.85) @@ -129,14 +123,6 @@ class USERPREF_PT_view(bpy.types.Panel): sub2.itemR(view, "manipulator_size", text="Size") sub2.itemR(view, "manipulator_handle_size", text="Handle Size") sub2.itemR(view, "manipulator_hotspot", text="Hotspot") - sub1.itemS() - sub1.itemS() - sub1.itemS() - sub1.itemL(text="Toolbox:") - sub1.itemR(view, "use_column_layout") - sub1.itemL(text="Open Toolbox Delay:") - sub1.itemR(view, "open_left_mouse_delay", text="Hold LMB") - sub1.itemR(view, "open_right_mouse_delay", text="Hold RMB") class USERPREF_PT_edit(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' @@ -145,7 +131,7 @@ class USERPREF_PT_edit(bpy.types.Panel): def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'EDIT_METHODS') + return (userpref.active_section == 'EDITING') def draw(self, context): layout = self.layout @@ -248,7 +234,7 @@ class USERPREF_PT_system(bpy.types.Panel): def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'SYSTEM_OPENGL') + return (userpref.active_section == 'SYSTEM') def draw(self, context): layout = self.layout @@ -276,7 +262,7 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemL(text="Sound:") sub1.row().itemR(system, "audio_device", expand=True) sub2 = sub1.column() - sub2.active = system.audio_device != 'AUDIO_DEVICE_NULL' + sub2.active = system.audio_device != 'NONE' sub2.itemR(system, "enable_all_codecs") sub2.itemR(system, "game_sound") sub2.itemR(system, "audio_channels", text="Channels") @@ -332,14 +318,14 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemR(system, "prefetch_frames") sub1.itemR(system, "memory_cache_limit") -class USERPREF_PT_filepaths(bpy.types.Panel): +class USERPREF_PT_file(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' - __label__ = "File Paths" + __label__ = "Files" __show_header__ = False def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'FILE_PATHS') + return (userpref.active_section == 'FILES') def draw(self, context): layout = self.layout @@ -398,11 +384,314 @@ class USERPREF_PT_filepaths(bpy.types.Panel): sub3.enabled = paths.auto_save_temporary_files sub3.itemR(paths, "auto_save_time", text="Timer (mins)") +class USERPREF_PT_input(bpy.types.Panel): + __space_type__ = 'USER_PREFERENCES' + __label__ = "Input" + __show_header__ = False + + def poll(self, context): + userpref = context.user_preferences + return (userpref.active_section == 'INPUT') + + def draw(self, context): + layout = self.layout + + userpref = context.user_preferences + wm = context.manager + #input = userpref.input + input = userpref + view = userpref.view + + split = layout.split(percentage=0.25) + + # General settings + row = split.row() + col = row.column() + + sub = col.column() + sub.itemL(text="Configuration:") + sub.item_pointerR(wm, "active_keyconfig", wm, "keyconfigs", text="") + + col.itemS() + + sub = col.column() + sub.itemL(text="Mouse:") + sub1 = sub.column() + sub1.enabled = (view.select_mouse == 'RIGHT') + sub1.itemR(view, "emulate_3_button_mouse") + sub.itemR(view, "continuous_mouse", text="Continuous Grab") + + sub.itemL(text="Select With:") + sub.row().itemR(view, "select_mouse", expand=True) + #sub.itemL(text="Middle Mouse:") + #sub.row().itemR(view, "middle_mouse", expand=True) + #sub.itemR(view, "use_middle_mouse_paste") + + #col.itemS() + + #sub = col.column() + #sub.itemL(text="Mouse Wheel:") + #sub.itemR(view, "wheel_invert_zoom", text="Invert Zoom") + #sub.itemR(view, "wheel_scroll_lines", text="Scroll Lines") + + col.itemS() + + sub = col.column() + sub.itemL(text="NDOF Device:") + sub.itemR(view, "ndof_pan_speed", text="Pan Speed") + sub.itemR(view, "ndof_rotate_speed", text="Orbit Speed") + + row.itemS() + + # Keymap Settings + col = split.column() + + kc = wm.active_keyconfig + defkc = wm.default_keyconfig + km = wm.active_keymap + + subsplit = col.split() + subsplit.item_pointerR(wm, "active_keymap", defkc, "keymaps", text="Map:") + if km.user_defined: + row = subsplit.row() + row.itemO("WM_OT_keymap_restore", text="Restore") + row.item_booleanO("WM_OT_keymap_restore", "all", True, text="Restore All") + else: + row = subsplit.row() + row.itemO("WM_OT_keymap_edit", text="Edit") + row.itemL() + + col.itemS() + + for kmi in km.items: + subcol = col.column() + subcol.set_context_pointer("keyitem", kmi) + + row = subcol.row() + + if kmi.expanded: + row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_DOWN") + else: + row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_RIGHT") + + itemrow = row.row() + itemrow.enabled = km.user_defined + itemrow.itemR(kmi, "active", text="", icon="ICON_DOT") + + itemcol = itemrow.column() + itemcol.active = kmi.active + row = itemcol.row() + row.itemR(kmi, "idname", text="") + + sub = row.row() + sub.scale_x = 0.6 + sub.itemR(kmi, "map_type", text="") + + sub = row.row(align=True) + if kmi.map_type == 'KEYBOARD': + sub.itemR(kmi, "type", text="", full_event=True) + elif kmi.map_type == 'MOUSE': + sub.itemR(kmi, "type", text="", full_event=True) + elif kmi.map_type == 'TWEAK': + sub.scale_x = 0.5 + sub.itemR(kmi, "type", text="") + sub.itemR(kmi, "value", text="") + elif kmi.map_type == 'TIMER': + sub.itemR(kmi, "type", text="") + else: + sub.itemL() + + if kmi.expanded: + if kmi.map_type not in ('TEXTINPUT', 'TIMER'): + sub = itemcol.row(align=True) + + if kmi.map_type == 'KEYBOARD': + sub.itemR(kmi, "type", text="", event=True) + sub.itemR(kmi, "value", text="") + elif kmi.map_type == 'MOUSE': + sub.itemR(kmi, "type", text="") + sub.itemR(kmi, "value", text="") + else: + sub.itemL() + sub.itemL() + + subrow = sub.row() + subrow.scale_x = 0.75 + subrow.itemR(kmi, "shift") + subrow.itemR(kmi, "ctrl") + subrow.itemR(kmi, "alt") + subrow.itemR(kmi, "oskey") + sub.itemR(kmi, "key_modifier", text="", event=True) + + flow = itemcol.column_flow(columns=2) + props = kmi.properties + + if props != None: + for pname in dir(props): + if not props.is_property_hidden(pname): + flow.itemR(props, pname) + + itemcol.itemS() + + itemrow.itemO("wm.keyitem_remove", text="", icon="ICON_ZOOMOUT") + + itemrow = col.row() + itemrow.itemL() + itemrow.itemO("wm.keyitem_add", text="", icon="ICON_ZOOMIN") + itemrow.enabled = km.user_defined + bpy.types.register(USERPREF_HT_header) bpy.types.register(USERPREF_MT_view) bpy.types.register(USERPREF_PT_tabs) -bpy.types.register(USERPREF_PT_view) +bpy.types.register(USERPREF_PT_interface) bpy.types.register(USERPREF_PT_edit) bpy.types.register(USERPREF_PT_system) -bpy.types.register(USERPREF_PT_filepaths) +bpy.types.register(USERPREF_PT_file) +bpy.types.register(USERPREF_PT_input) + +class WM_OT_keyconfig_save(bpy.types.Operator): + "Save key configuration to a python script." + __idname__ = "wm.keyconfig_save" + __label__ = "Save Key Configuration..." + __props__ = [ + bpy.props.StringProperty(attr="path", name="File Path", description="File path to write file to.")] + + def _string_value(self, value): + result = "" + if isinstance(value, str): + if value != "": + result = "\'%s\'" % value + elif isinstance(value, bool): + if value: + result = "True" + else: + result = "False" + elif isinstance(value, float): + result = "%.10f" % value + elif isinstance(value, int): + result = "%d" % value + elif getattr(value, '__len__', False): + if len(value): + result = "[" + for i in range(0, len(value)): + result += self._string_value(value[i]) + if i != len(value)-1: + result += ", " + result += "]" + else: + print("Save key configuration: can't write ", value) + + return result + + def execute(self, context): + if not self.path: + raise Exception("File path not set.") + + f = open(self.path, "w") + if not f: + raise Exception("Could not open file.") + + wm = context.manager + kc = wm.active_keyconfig + + f.write('# Configuration %s\n' % kc.name) + + f.write("wm = bpy.data.windowmanagers[0]\n"); + f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % kc.name) + + for km in kc.keymaps: + f.write("# Map %s\n" % km.name) + f.write("km = kc.add_keymap(\'%s\', space_type=\'%s\', region_type=\'%s\')\n\n" % (km.name, km.space_type, km.region_type)) + for kmi in km.items: + f.write("kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)) + if kmi.shift: + f.write(", shift=True") + if kmi.ctrl: + f.write(", ctrl=True") + if kmi.alt: + f.write(", alt=True") + if kmi.oskey: + f.write(", oskey=True") + if kmi.key_modifier and kmi.key_modifier != 'NONE': + f.write(", key_modifier=\'%s\'" % kmi.key_modifier) + f.write(")\n") + + props = kmi.properties + + if props != None: + for pname in dir(props): + if props.is_property_set(pname) and not props.is_property_hidden(pname): + value = eval("props.%s" % pname) + value = self._string_value(value) + if value != "": + f.write("kmi.properties.%s = %s\n" % (pname, value)) + + f.write("\n") + + f.close() + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + +class WM_OT_keymap_edit(bpy.types.Operator): + "Edit key map." + __idname__ = "wm.keymap_edit" + __label__ = "Edit Key Map" + + def execute(self, context): + wm = context.manager + km = wm.active_keymap + km.copy_to_user() + return ('FINISHED',) + +class WM_OT_keymap_restore(bpy.types.Operator): + "Restore key map" + __idname__ = "wm.keymap_restore" + __label__ = "Restore Key Map" + __props__ = [bpy.props.BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default.")] + + def execute(self, context): + wm = context.manager + + if self.all: + for km in wm.default_keyconfig.keymaps: + km.restore_to_default() + else: + km = wm.active_keymap + km.restore_to_default() + + return ('FINISHED',) + +class WM_OT_keyitem_add(bpy.types.Operator): + "Add key map item." + __idname__ = "wm.keyitem_add" + __label__ = "Add Key Map Item" + + def execute(self, context): + wm = context.manager + km = wm.active_keymap + kmi = km.add_item("", "A", "PRESS") + return ('FINISHED',) + +class WM_OT_keyitem_remove(bpy.types.Operator): + "Remove key map item." + __idname__ = "wm.keyitem_remove" + __label__ = "Remove Key Map Item" + + def execute(self, context): + wm = context.manager + kmi = context.keyitem + km = wm.active_keymap + km.remove_item(kmi) + return ('FINISHED',) + +bpy.ops.add(WM_OT_keyconfig_save) +bpy.ops.add(WM_OT_keymap_edit) +bpy.ops.add(WM_OT_keymap_restore) +bpy.ops.add(WM_OT_keyitem_add) +bpy.ops.add(WM_OT_keyitem_remove) diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index b983c6f7dc4..7c62c8c6dd4 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -44,6 +44,7 @@ struct SpaceType; struct wmNotifier; struct wmWindow; struct wmWindowManager; +struct wmKeyConfig; struct uiLayout; struct uiMenuItem; @@ -81,7 +82,7 @@ typedef struct SpaceType { /* register operator types on startup */ void (*operatortypes)(void); /* add default items to WM keymap */ - void (*keymap)(struct wmWindowManager *); + void (*keymap)(struct wmKeyConfig *); /* return context data */ int (*context)(const struct bContext *, const char*, struct bContextDataResult *); @@ -122,7 +123,7 @@ typedef struct ARegionType { /* register operator types on startup */ void (*operatortypes)(void); /* add own items to keymap */ - void (*keymap)(struct wmWindowManager *); + void (*keymap)(struct wmKeyConfig *); /* allows default cursor per region */ void (*cursor)(struct wmWindow *, struct ScrArea *, struct ARegion *ar); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index f261b020717..2df5b7c173c 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -74,6 +74,7 @@ #include "BKE_displist.h" #include "BKE_font.h" #include "BKE_global.h" +#include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_ipo.h" #include "BKE_main.h" @@ -406,10 +407,26 @@ static int handle_subversion_warning(Main *main) void BKE_userdef_free(void) { + wmKeyMap *km; + wmKeyMapItem *kmi; + + for(km=U.keymaps.first; km; km=km->next) { + for(kmi=km->items.first; kmi; kmi=kmi->next) { + if(kmi->properties) { + IDP_FreeProperty(kmi->properties); + MEM_freeN(kmi->properties); + } + if(kmi->ptr) + MEM_freeN(kmi->ptr); + } + + BLI_freelistN(&km->items); + } BLI_freelistN(&U.uistyles); BLI_freelistN(&U.uifonts); BLI_freelistN(&U.themes); + BLI_freelistN(&U.keymaps); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ae18d7cac01..f2bf8b19bc6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4446,11 +4446,13 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) } wm->operators.first= wm->operators.last= NULL; - wm->keymaps.first= wm->keymaps.last= NULL; wm->paintcursors.first= wm->paintcursors.last= NULL; wm->queue.first= wm->queue.last= NULL; BKE_reports_init(&wm->reports, RPT_STORE); + wm->keyconfigs.first= wm->keyconfigs.last= NULL; + wm->defaultconf= NULL; + wm->jobs.first= wm->jobs.last= NULL; wm->windrawable= NULL; @@ -5276,6 +5278,33 @@ static char *dataname(short id_code) } +static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, char *allocname) +{ + bhead = blo_nextbhead(fd, bhead); + + while(bhead && bhead->code==DATA) { + void *data; +#if 0 + /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */ + short *sp= fd->filesdna->structs[bhead->SDNAnr]; + char *allocname = fd->filesdna->types[ sp[0] ]; + char *tmp= malloc(100); + + strcpy(tmp, allocname); + data= read_struct(fd, bhead, tmp); +#endif + data= read_struct(fd, bhead, allocname); + + if (data) { + oldnewmap_insert(fd->datamap, bhead->old, data, 0); + } + + bhead = blo_nextbhead(fd, bhead); + } + + return bhead; +} + static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **id_r) { /* this routine reads a libblock and its direct data. Use link functions @@ -5317,32 +5346,11 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID return blo_nextbhead(fd, bhead); } - bhead = blo_nextbhead(fd, bhead); - /* need a name for the mallocN, just for debugging and sane prints on leaks */ allocname= dataname(GS(id->name)); - /* read all data */ - - while(bhead && bhead->code==DATA) { - void *data; -#if 0 - /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */ - short *sp= fd->filesdna->structs[bhead->SDNAnr]; - char *allocname = fd->filesdna->types[ sp[0] ]; - char *tmp= malloc(100); - - strcpy(tmp, allocname); - data= read_struct(fd, bhead, tmp); -#endif - data= read_struct(fd, bhead, allocname); - - if (data) { - oldnewmap_insert(fd->datamap, bhead->old, data, 0); - } - - bhead = blo_nextbhead(fd, bhead); - } + /* read all data into fd->datamap */ + bhead= read_data_into_oldnewmap(fd, bhead, allocname); /* init pointers direct data */ switch( GS(id->name) ) { @@ -9975,23 +9983,39 @@ static void lib_link_all(FileData *fd, Main *main) static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) { - Link *link; + UserDef *user; + wmKeyMap *keymap; + wmKeyMapItem *kmi; - bfd->user= read_struct(fd, bhead, "user def"); - bfd->user->themes.first= bfd->user->themes.last= NULL; - // XXX - bfd->user->uifonts.first= bfd->user->uifonts.last= NULL; - bfd->user->uistyles.first= bfd->user->uistyles.last= NULL; + bfd->user= user= read_struct(fd, bhead, "user def"); - bhead = blo_nextbhead(fd, bhead); + /* read all data into fd->datamap */ + bhead= read_data_into_oldnewmap(fd, bhead, "user def"); - /* read all attached data */ - while(bhead && bhead->code==DATA) { - link= read_struct(fd, bhead, "user def data"); - BLI_addtail(&bfd->user->themes, link); - bhead = blo_nextbhead(fd, bhead); + link_list(fd, &user->themes); + link_list(fd, &user->keymaps); + + for(keymap=user->keymaps.first; keymap; keymap=keymap->next) { + keymap->modal_items= NULL; + keymap->poll= NULL; + + link_list(fd, &keymap->items); + for(kmi=keymap->items.first; kmi; kmi=kmi->next) { + kmi->properties= newdataadr(fd, kmi->properties); + if(kmi->properties) + IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + kmi->ptr= NULL; + } } + // XXX + user->uifonts.first= user->uifonts.last= NULL; + user->uistyles.first= user->uistyles.last= NULL; + + /* free fd->datamap again */ + oldnewmap_free_unused(fd->datamap); + oldnewmap_clear(fd->datamap); + return bhead; } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 25cbd4b65e7..e3d061d8e4b 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -537,13 +537,23 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon static void write_userdef(WriteData *wd) { bTheme *btheme; + wmKeyMap *keymap; + wmKeyMapItem *kmi; writestruct(wd, USER, "UserDef", 1, &U); - btheme= U.themes.first; - while(btheme) { + for(btheme= U.themes.first; btheme; btheme=btheme->next) writestruct(wd, DATA, "bTheme", 1, btheme); - btheme= btheme->next; + + for(keymap= U.keymaps.first; keymap; keymap=keymap->next) { + writestruct(wd, DATA, "wmKeyMap", 1, keymap); + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) { + writestruct(wd, DATA, "wmKeyMapItem", 1, kmi); + + if(kmi->properties) + IDP_WriteProperty(kmi->properties, wd); + } } } diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 83f5fca5af5..7ee591f8cab 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -1687,9 +1687,9 @@ void ED_operatortypes_animchannels(void) WM_operatortype_append(ANIM_OT_channels_visibility_toggle); } -void ED_keymap_animchannels(wmWindowManager *wm) +void ED_keymap_animchannels(wmKeyConfig *keyconf) { - wmKeyMap *keymap = WM_keymap_find(wm, "Animation_Channels", 0, 0); + wmKeyMap *keymap = WM_keymap_find(keyconf, "Animation_Channels", 0, 0); /* selection */ /* click-select */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 6c44086af41..f4ecb9d5def 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -990,9 +990,9 @@ void ED_operatortypes_marker(void) } /* called in screen_ops.c:ED_keymap_screen() */ -void ED_marker_keymap(wmWindowManager *wm) +void ED_marker_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Markers", 0, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Markers", 0, 0); WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 83b2e2688c9..35eac6d23f1 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -416,9 +416,9 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_keying_set_path_remove); } -void ED_keymap_anim(wmWindowManager *wm) +void ED_keymap_anim(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Animation", 0, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Animation", 0, 0); /* frame management */ /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */ diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index d465c1f8c9a..2bf414ef969 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -205,13 +205,13 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed } -void ED_keymap_armature(wmWindowManager *wm) +void ED_keymap_armature(wmKeyConfig *keyconf) { wmKeyMap *keymap; - wmKeymapItem *kmi; + wmKeyMapItem *kmi; /* Armature ------------------------ */ - keymap= WM_keymap_find(wm, "Armature", 0, 0); + keymap= WM_keymap_find(keyconf, "Armature", 0, 0); keymap->poll= ED_operator_editarmature; /* only set in editmode armature, by space_view3d listener */ @@ -297,7 +297,7 @@ void ED_keymap_armature(wmWindowManager *wm) /* Pose ------------------------ */ /* only set in posemode, by space_view3d listener */ - keymap= WM_keymap_find(wm, "Pose", 0, 0); + keymap= WM_keymap_find(keyconf, "Pose", 0, 0); keymap->poll= ED_operator_posemode; // XXX: set parent is object-based operator, but it should also be available here... diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 77c5ed1de2c..a71ff8347e8 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -161,11 +161,11 @@ void ED_operatortypes_curve(void) WM_operatortype_append(CURVE_OT_specials_menu); } -void ED_keymap_curve(wmWindowManager *wm) +void ED_keymap_curve(wmKeyConfig *keyconf) { wmKeyMap *keymap; - keymap= WM_keymap_find(wm, "Font", 0, 0); + keymap= WM_keymap_find(keyconf, "Font", 0, 0); keymap->poll= ED_operator_editfont; /* only set in editmode font, by space_view3d listener */ @@ -215,7 +215,7 @@ void ED_keymap_curve(wmWindowManager *wm) WM_keymap_add_item(keymap, "FONT_OT_text_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last! /* only set in editmode curve, by space_view3d listener */ - keymap= WM_keymap_find(wm, "Curve", 0, 0); + keymap= WM_keymap_find(keyconf, "Curve", 0, 0); keymap->poll= ED_operator_editsurfcurve; WM_keymap_add_item(keymap, "OBJECT_OT_curve_add", AKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index d311b39b9a3..6237e193a13 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -45,10 +45,10 @@ /* ****************************************** */ /* Generic Editing Keymap */ -void ED_keymap_gpencil(wmWindowManager *wm) +void ED_keymap_gpencil(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Grease Pencil", 0, 0); - wmKeymapItem *kmi; + wmKeyMap *keymap= WM_keymap_find(keyconf, "Grease Pencil", 0, 0); + wmKeyMapItem *kmi; /* Draw */ /* draw */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index d9439956569..97f4dd915e4 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -34,7 +34,7 @@ struct ListBase; struct AnimData; struct bContext; -struct wmWindowManager; +struct wmKeyConfig; struct ScrArea; struct ARegion; struct View2D; @@ -487,11 +487,11 @@ void ANIM_pose_to_action_sync(struct Object *ob, struct ScrArea *sa); /* generic animation channels */ void ED_operatortypes_animchannels(void); -void ED_keymap_animchannels(struct wmWindowManager *wm); +void ED_keymap_animchannels(struct wmKeyConfig *keyconf); /* generic time editing */ void ED_operatortypes_anim(void); -void ED_keymap_anim(struct wmWindowManager *wm); +void ED_keymap_anim(struct wmKeyConfig *keyconf); /* ************************************************ */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 8bdfe41ef80..6479030bcd1 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -35,7 +35,7 @@ struct Bone; struct bArmature; struct bPoseChannel; struct wmOperator; -struct wmWindowManager; +struct wmKeyConfig; struct ListBase; struct View3D; struct ViewContext; @@ -92,7 +92,7 @@ typedef struct EditBone /* armature_ops.c */ void ED_operatortypes_armature(void); -void ED_keymap_armature(struct wmWindowManager *wm); +void ED_keymap_armature(struct wmKeyConfig *keyconf); /* editarmature.c */ void ED_armature_from_edit(struct Object *obedit); diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 4149c6a9cca..fea684971b2 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -36,11 +36,11 @@ struct Scene; struct Text; struct View3D; struct wmOperator; -struct wmWindowManager; +struct wmKeyConfig; /* curve_ops.c */ void ED_operatortypes_curve(void); -void ED_keymap_curve (struct wmWindowManager *wm); +void ED_keymap_curve (struct wmKeyConfig *keyconf); /* editcurve.c */ void undo_push_curve (struct bContext *C, char *name); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 388da9a2acc..ff95f8ce6eb 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -41,7 +41,7 @@ struct bGPDframe; struct PointerRNA; struct Panel; struct ImBuf; -struct wmWindowManager; +struct wmKeyConfig; /* ------------- Grease-Pencil Helpers ---------------- */ @@ -62,7 +62,7 @@ struct bGPdata *gpencil_data_get_active(struct bContext *C); /* ----------- Grease Pencil Operators ----------------- */ -void ED_keymap_gpencil(struct wmWindowManager *wm); +void ED_keymap_gpencil(struct wmKeyConfig *keyconf); void ED_operatortypes_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h index 4b7a2954206..58ca85bb74c 100644 --- a/source/blender/editors/include/ED_markers.h +++ b/source/blender/editors/include/ED_markers.h @@ -28,7 +28,7 @@ #ifndef ED_MARKERS_H #define ED_MARKERS_H -struct wmWindowManager; +struct wmKeyConfig; struct bContext; struct TimeMarker; @@ -56,7 +56,7 @@ void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short sel); /* called in screen_ops.c:ED_operatortypes_screen() */ void ED_operatortypes_marker(void); /* called in screen_ops.c:ED_keymap_screen() */ -void ED_marker_keymap(struct wmWindowManager *wm); +void ED_marker_keymap(struct wmKeyConfig *keyconf); #endif /* ED_MARKERS_H */ diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 49c1d856a27..6708a73e088 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -28,10 +28,10 @@ struct bContext; struct Object; -struct wmWindowManager; +struct wmKeyConfig; void ED_operatortypes_metaball(void); -void ED_keymap_metaball(struct wmWindowManager *wm); +void ED_keymap_metaball(struct wmKeyConfig *keyconf); struct MetaElem *add_metaball_primitive(struct bContext *C, int type, int newname); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index fd88f9889ae..cf0e6eb01c3 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -38,6 +38,7 @@ struct EditFace; struct bContext; struct wmOperator; struct wmWindowManager; +struct wmKeyConfig; struct ReportList; struct EditSelection; struct ViewContext; @@ -84,13 +85,13 @@ int join_mesh_exec(struct bContext *C, struct wmOperator *op); /* mesh_ops.c */ void ED_operatortypes_mesh(void); -void ED_keymap_mesh(struct wmWindowManager *wm); +void ED_keymap_mesh(struct wmKeyConfig *keyconf); /* editmesh.c */ void ED_spacetypes_init(void); -void ED_keymap_mesh(struct wmWindowManager *wm); +void ED_keymap_mesh(struct wmKeyConfig *keyconf); void make_editMesh(struct Scene *scene, struct Object *ob); void load_editMesh(struct Scene *scene, struct Object *ob); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 363795afeab..ec763fe3dfc 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -28,7 +28,7 @@ #ifndef ED_OBJECT_H #define ED_OBJECT_H -struct wmWindowManager; +struct wmKeyConfig; struct Scene; struct Object; struct bContext; @@ -44,7 +44,7 @@ struct ModifierData; /* object_edit.c */ void ED_operatortypes_object(void); -void ED_keymap_object(struct wmWindowManager *wm); +void ED_keymap_object(struct wmKeyConfig *keyconf); /* send your own notifier for select! */ void ED_base_object_select(struct Base *base, short mode); diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index a052142102d..3d7fc5ea15b 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -36,7 +36,7 @@ struct ParticleEditSettings; struct ParticleSystem; struct RadialControl; struct rcti; -struct wmWindowManager; +struct wmKeyConfig; struct PTCacheEdit; struct Scene; diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h index ee340c54e7d..df303d7c9f1 100644 --- a/source/blender/editors/include/ED_physics.h +++ b/source/blender/editors/include/ED_physics.h @@ -30,9 +30,11 @@ #ifndef ED_PHYSICS_H #define ED_PHYSICS_H +struct wmKeyConfig; + /* operators */ void ED_operatortypes_physics(void); -void ED_keymap_physics(struct wmWindowManager *wm); +void ED_keymap_physics(struct wmKeyConfig *keyconf); #endif /* ED_PHYSICS_H */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 63b6a067389..18c86306e44 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -37,6 +37,7 @@ struct wmWindowManager; struct wmWindow; struct wmNotifier; struct wmEvent; +struct wmKeyConfig; struct bContext; struct SpaceType; struct Scene; @@ -63,7 +64,7 @@ void region_scissor_winrct(struct ARegion *ar, struct rcti *winrct); /* spaces */ void ED_spacetypes_init(void); -void ED_spacetypes_keymap(struct wmWindowManager *wm); +void ED_spacetypes_keymap(struct wmKeyConfig *keyconf); int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco); int ED_area_header_standardbuttons(const struct bContext *C, struct uiBlock *block, int yco); void ED_area_overdraw(struct bContext *C); @@ -107,7 +108,7 @@ void ED_screen_new_window(struct bContext *C, struct rcti *position, int type); void ED_update_for_newframe(const struct bContext *C, int mute); void ED_operatortypes_screen(void); -void ED_keymap_screen(struct wmWindowManager *wm); +void ED_keymap_screen(struct wmKeyConfig *keyconf); /* operators; context poll callbacks */ int ED_operator_screenactive(struct bContext *C); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index a08f0576f42..764efb4ef0c 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -29,14 +29,14 @@ #define ED_SCULPT_H struct bContext; -struct wmWindowManager; +struct wmKeyConfig; /* sculpt.c */ void ED_operatortypes_sculpt(void); /* paint_ops.c */ void ED_operatortypes_paint(void); -void ED_keymap_paint(struct wmWindowManager *wm); +void ED_keymap_paint(struct wmKeyConfig *keyconf); /* paint_image.c */ void undo_imagepaint_step(int step); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 7f08e95aceb..a7ffefba8df 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -42,8 +42,9 @@ struct uiLayout; struct EnumPropertyItem; struct wmOperatorType; struct wmKeyMap; +struct wmKeyConfig; -void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid); +void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int spaceid); void transform_operatortypes(void); /* ******************** Macros & Prototypes *********************** */ diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 74a9be75db6..8823437cf79 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -34,11 +34,11 @@ struct Object; struct MTFace; struct EditFace; struct Image; -struct wmWindowManager; +struct wmKeyConfig; /* uvedit_ops.c */ void ED_operatortypes_uvedit(void); -void ED_keymap_uvedit(struct wmWindowManager *wm); +void ED_keymap_uvedit(struct wmKeyConfig *keyconf); void ED_uvedit_assign_image(struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); void ED_uvedit_set_tile(struct bContext *C, struct Scene *scene, struct Object *obedit, struct Image *ima, int curtile, int dotile); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 35598db9e02..3c6ed1137ae 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -147,6 +147,7 @@ typedef struct uiLayout uiLayout; #define UI_BUT_INACTIVE (1<<23) #define UI_BUT_LAST_ACTIVE (1<<24) #define UI_BUT_UNDO (1<<25) +#define UI_BUT_IMMEDIATE (1<<26) #define UI_PANEL_WIDTH 340 #define UI_COMPACT_PANEL_WIDTH 160 @@ -572,6 +573,8 @@ void UI_exit(void); #define UI_ITEM_R_SLIDER 4 #define UI_ITEM_R_TOGGLE 8 #define UI_ITEM_R_ICON_ONLY 16 +#define UI_ITEM_R_EVENT 32 +#define UI_ITEM_R_FULL_EVENT 64 uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style); void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout); diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 38c4d82e6da..8fbff25589d 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -128,7 +128,7 @@ struct View2D; struct View2DGrid; struct View2DScrollers; -struct wmWindowManager; +struct wmKeyConfig; struct bScreen; struct ScrArea; struct ARegion; @@ -196,7 +196,7 @@ void UI_view2d_text_cache_draw(struct ARegion *ar); /* operators */ void ui_view2d_operatortypes(void); -void UI_view2d_keymap(struct wmWindowManager *wm); +void UI_view2d_keymap(struct wmKeyConfig *keyconf); #endif /* UI_VIEW2D_H */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 3e5cc0e6d67..fcc41e4f533 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1958,7 +1958,10 @@ void ui_check_but(uiBut *but) if (but->flag & UI_SELECT) { short *sp= (short *)but->func_arg3; - strcpy(but->drawstr, but->str); + if(but->flag & UI_BUT_IMMEDIATE) + strcpy(but->drawstr, but->str); + else + strcpy(but->drawstr, ""); if(*sp) { char *str= but->drawstr; @@ -1974,10 +1977,10 @@ void ui_check_but(uiBut *but) } else strcat(but->drawstr, "Press a key "); - } else { - /* XXX todo, button currently only used temporarily */ - strcpy(but->drawstr, WM_key_event_string((short) ui_get_but_val(but))); } + else + strcpy(but->drawstr, but->str); + break; case BUT_TOGDUAL: diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 8dea3fa1fc3..195129eac8f 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1858,6 +1858,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data if(data->state == BUTTON_STATE_HIGHLIGHT) { if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) { but->drawstr[0]= 0; + *(short *)but->func_arg3= 0; button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT); return WM_UI_HANDLER_BREAK; } @@ -1868,9 +1869,12 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data if(event->type == MOUSEMOVE) return WM_UI_HANDLER_CONTINUE; - if(ELEM(event->type, ESCKEY, LEFTMOUSE)) { + if(event->type == ESCKEY) { /* data->cancel doesnt work, this button opens immediate */ - ui_set_but_val(but, 0); + if(but->flag & UI_BUT_IMMEDIATE) + ui_set_but_val(but, 0); + else + data->cancel= 1; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } @@ -3325,6 +3329,7 @@ static uiBlock *menu_change_hotkey(bContext *C, ARegion *ar, void *arg_but) strcat(buf, " |"); but= uiDefHotKeyevtButS(block, 0, buf, 0, 0, 200, 20, dummy, dummy+1, ""); + uiButSetFlag(but, UI_BUT_IMMEDIATE); uiButSetFunc(but, do_menu_change_hotkey, arg_but, dummy); uiPopupBoundsBlock(block, 6.0f, 50, -10); @@ -3782,8 +3787,11 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); /* activate right away */ - if(but->type==HOTKEYEVT) - button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT); + if(but->flag & UI_BUT_IMMEDIATE) { + if(but->type==HOTKEYEVT) + button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT); + /* .. more to be added here */ + } if(type == BUTTON_ACTIVATE_OPEN) { button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b15be940eef..eb81044852a 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -476,8 +476,20 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, MEM_freeN(item); } +/* callback for keymap item change button */ +static void ui_keymap_but_cb(bContext *C, void *but_v, void *key_v) +{ + uiBut *but= but_v; + short modifier= *((short*)key_v); + + RNA_boolean_set(&but->rnapoin, "shift", (modifier & KM_SHIFT) != 0); + RNA_boolean_set(&but->rnapoin, "ctrl", (modifier & KM_CTRL) != 0); + RNA_boolean_set(&but->rnapoin, "alt", (modifier & KM_ALT) != 0); + RNA_boolean_set(&but->rnapoin, "oskey", (modifier & KM_OSKEY) != 0); +} + /* create label + button for RNA property */ -static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h, int icon_only) +static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h, int flag) { uiLayout *sub; uiBut *but=NULL; @@ -507,10 +519,26 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, i /* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */ but= uiDefIconButO(block, BUT, "BUTTONS_OT_file_browse", WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, "Browse for file or directory."); } - else if(subtype == PROP_DIRECTION) - uiDefButR(block, BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL); + else if(subtype == PROP_DIRECTION) { + uiDefButR(block, BUT_NORMAL, 0, name, x, y, 100, 100, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL); + } + else if(flag & UI_ITEM_R_EVENT) { + uiDefButR(block, KEYEVT, 0, name, x, y, w, h, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL); + } + else if(flag & UI_ITEM_R_FULL_EVENT) { + if(RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) { + static short dummy = 0; + char buf[128]; + + WM_keymap_item_to_string(ptr->data, buf, sizeof(buf)); + + but= uiDefButR(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL); + but->func_arg3= &dummy; // XXX abuse + uiButSetFunc(but, ui_keymap_but_cb, but, &dummy); + } + } else - but= uiDefAutoButR(block, ptr, prop, index, (type == PROP_ENUM && !icon_only)? NULL: "", icon, x, y, w, h); + but= uiDefAutoButR(block, ptr, prop, index, (type == PROP_ENUM && !(flag & UI_ITEM_R_ICON_ONLY))? NULL: "", icon, x, y, w, h); uiBlockSetCurLayout(block, layout); return but; @@ -897,7 +925,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper ui_item_enum_row(layout, block, ptr, prop, name, 0, 0, w, h, icon_only); /* property with separate label */ else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) { - but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, icon_only); + but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag); ui_but_add_search(but, ptr, prop, NULL, NULL); } /* single button */ diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 1d56ed4fb6a..eca4eef230c 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -126,10 +126,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int columns) { uiLayout *split, *col; + int flag; char *name; RNA_STRUCT_BEGIN(ptr, prop) { - if(strcmp(RNA_property_identifier(prop), "rna_type") == 0) + flag= RNA_property_flag(prop); + if(flag & PROP_HIDDEN) continue; name= (char*)RNA_property_ui_name(prop); diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 0af5a5cac97..ef37f6e530a 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1407,9 +1407,9 @@ void ui_view2d_operatortypes(void) WM_operatortype_append(VIEW2D_OT_reset); } -void UI_view2d_keymap(wmWindowManager *wm) +void UI_view2d_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "View2D", 0, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "View2D", 0, 0); /* pan/scroll */ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -1445,7 +1445,7 @@ void UI_view2d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); /* Alternative keymap for buttons listview */ - keymap= WM_keymap_find(wm, "View2D Buttons List", 0, 0); + keymap= WM_keymap_find(keyconf, "View2D Buttons List", 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 4c9f63f910c..4669f7a6741 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -1240,36 +1240,34 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, EnumPropertyItem *item= NULL; int totitem= 0; - if(C==NULL) { - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - RNA_enum_items_add(&item, &totitem, prop_simface_types); - RNA_enum_item_end(&item, &totitem); - *free= 1; + if(C) { + obedit= CTX_data_edit_object(C); - return item; - } - - obedit= CTX_data_edit_object(C); - - if(obedit && obedit->type == OB_MESH) { - EditMesh *em= BKE_mesh_get_editmesh(obedit->data); + if(obedit && obedit->type == OB_MESH) { + EditMesh *em= BKE_mesh_get_editmesh(obedit->data); - if(em->selectmode & SCE_SELECT_VERTEX) - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - else if(em->selectmode & SCE_SELECT_EDGE) - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - else if(em->selectmode & SCE_SELECT_FACE) - RNA_enum_items_add(&item, &totitem, prop_simface_types); - RNA_enum_item_end(&item, &totitem); + if(em->selectmode & SCE_SELECT_VERTEX) + RNA_enum_items_add(&item, &totitem, prop_simvertex_types); + else if(em->selectmode & SCE_SELECT_EDGE) + RNA_enum_items_add(&item, &totitem, prop_simedge_types); + else if(em->selectmode & SCE_SELECT_FACE) + RNA_enum_items_add(&item, &totitem, prop_simface_types); + RNA_enum_item_end(&item, &totitem); - *free= 1; + *free= 1; - return item; + return item; + } } + + /* needed for doc generation */ + RNA_enum_items_add(&item, &totitem, prop_simvertex_types); + RNA_enum_items_add(&item, &totitem, prop_simedge_types); + RNA_enum_items_add(&item, &totitem, prop_simface_types); + RNA_enum_item_end(&item, &totitem); + *free= 1; - return NULL; + return item; } void MESH_OT_select_similar(wmOperatorType *ot) @@ -1290,7 +1288,7 @@ void MESH_OT_select_similar(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", ""); + prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, SIMVERT_NORMAL, "Type", ""); RNA_def_enum_funcs(prop, select_similar_type_itemf); } diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 13d73faeb98..6f94db38316 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -348,12 +348,12 @@ void ED_operatortypes_mesh(void) } /* note mesh keymap also for other space? */ -void ED_keymap_mesh(wmWindowManager *wm) +void ED_keymap_mesh(wmKeyConfig *keyconf) { wmKeyMap *keymap; - wmKeymapItem *kmi; + wmKeyMapItem *kmi; - keymap= WM_keymap_find(wm, "EditMesh", 0, 0); + keymap= WM_keymap_find(keyconf, "EditMesh", 0, 0); keymap->poll= ED_operator_editmesh; WM_keymap_add_item(keymap, "MESH_OT_loopcut", RKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c index dd8a18f385c..01da90212a0 100644 --- a/source/blender/editors/metaball/mball_ops.c +++ b/source/blender/editors/metaball/mball_ops.c @@ -51,11 +51,11 @@ void ED_operatortypes_metaball(void) WM_operatortype_append(MBALL_OT_select_random_metaelems); } -void ED_keymap_metaball(wmWindowManager *wm) +void ED_keymap_metaball(wmKeyConfig *keyconf) { wmKeyMap *keymap; - keymap= WM_keymap_find(wm, "Metaball", 0, 0); + keymap= WM_keymap_find(keyconf, "Metaball", 0, 0); keymap->poll= ED_operator_editmball; WM_keymap_add_item(keymap, "OBJECT_OT_metaball_add", AKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 82135bf3804..f2f24c099bc 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -196,12 +196,12 @@ static int object_mode_poll(bContext *C) return (!ob || ob->mode == OB_MODE_OBJECT); } -void ED_keymap_object(wmWindowManager *wm) +void ED_keymap_object(wmKeyConfig *keyconf) { wmKeyMap *keymap; - wmKeymapItem *kmi; + wmKeyMapItem *kmi; - keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0); + keymap= WM_keymap_find(keyconf, "Object Non-modal", 0, 0); /* Note: this keymap works disregarding mode */ WM_keymap_add_item(keymap, "OBJECT_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0); @@ -217,7 +217,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_center_set", CKEY, KM_PRESS, KM_ALT|KM_SHIFT|KM_CTRL, 0); /* Note: this keymap gets disabled in non-objectmode, */ - keymap= WM_keymap_find(wm, "Object Mode", 0, 0); + keymap= WM_keymap_find(keyconf, "Object Mode", 0, 0); keymap->poll= object_mode_poll; WM_keymap_add_item(keymap, "OBJECT_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); @@ -264,7 +264,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); /* Lattice */ - keymap= WM_keymap_find(wm, "Lattice", 0, 0); + keymap= WM_keymap_find(keyconf, "Lattice", 0, 0); keymap->poll= ED_operator_editlattice; WM_keymap_add_item(keymap, "LATTICE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c index ddc5fb9c9b6..0ebbfa6b701 100644 --- a/source/blender/editors/physics/physics_ops.c +++ b/source/blender/editors/physics/physics_ops.c @@ -83,11 +83,11 @@ static void operatortypes_particle(void) WM_operatortype_append(PARTICLE_OT_dupliob_move_down); } -static void keymap_particle(wmWindowManager *wm) +static void keymap_particle(wmKeyConfig *keyconf) { wmKeyMap *keymap; - keymap= WM_keymap_find(wm, "Particle", 0, 0); + keymap= WM_keymap_find(keyconf, "Particle", 0, 0); keymap->poll= PE_poll; WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); @@ -166,10 +166,10 @@ void ED_operatortypes_physics(void) operatortypes_pointcache(); } -void ED_keymap_physics(wmWindowManager *wm) +void ED_keymap_physics(wmKeyConfig *keyconf) { - keymap_particle(wm); - //keymap_pointcache(wm); + keymap_particle(keyconf); + //keymap_pointcache(keyconf); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index fb782837d5e..f539020c93d 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -824,24 +824,24 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla UI_add_region_handlers(handlers); } if(flag & ED_KEYMAP_VIEW2D) { - wmKeyMap *keymap= WM_keymap_find(wm, "View2D", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "View2D", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } if(flag & ED_KEYMAP_MARKERS) { - wmKeyMap *keymap= WM_keymap_find(wm, "Markers", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "Markers", 0, 0); WM_event_add_keymap_handler(handlers, keymap); // XXX need boundbox check urgently!!! } if(flag & ED_KEYMAP_ANIMATION) { - wmKeyMap *keymap= WM_keymap_find(wm, "Animation", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "Animation", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } if(flag & ED_KEYMAP_FRAMES) { - wmKeyMap *keymap= WM_keymap_find(wm, "Frames", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "Frames", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } if(flag & ED_KEYMAP_GPENCIL) { - wmKeyMap *keymap= WM_keymap_find(wm, "Grease Pencil", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0); WM_event_add_keymap_handler(handlers, keymap); } } @@ -1371,7 +1371,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); - keymap= WM_keymap_find(wm, "View2D Buttons List", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "View2D Buttons List", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8d8c2eba2a8..7ba83753fee 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2550,7 +2550,7 @@ static ScrArea *find_empty_image_area(bContext *C) static void screen_set_image_output(bContext *C, int mx, int my) { Scene *scene= CTX_data_scene(C); - ScrArea *sa; + ScrArea *sa= NULL; SpaceImage *sima; if(scene->r.displaymode==R_OUTPUT_WINDOW) { @@ -2580,8 +2580,8 @@ static void screen_set_image_output(bContext *C, int mx, int my) ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE); sa= CTX_wm_area(C); } - else { + if(!sa) { sa= find_area_showing_r_result(C); if(sa==NULL) sa= find_area_image_empty(C); @@ -3286,7 +3286,7 @@ void ED_operatortypes_screen(void) } -static void keymap_modal_set(wmWindowManager *wm) +static void keymap_modal_set(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, @@ -3297,7 +3297,7 @@ static void keymap_modal_set(wmWindowManager *wm) wmKeyMap *keymap; /* Standard Modal keymap ------------------------------------------------ */ - keymap= WM_modalkeymap_add(wm, "Standard Modal Map", modal_items); + keymap= WM_modalkeymap_add(keyconf, "Standard Modal Map", modal_items); WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_CANCEL); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KM_MODAL_APPLY); @@ -3312,12 +3312,12 @@ static void keymap_modal_set(wmWindowManager *wm) } /* called in spacetypes.c */ -void ED_keymap_screen(wmWindowManager *wm) +void ED_keymap_screen(wmKeyConfig *keyconf) { wmKeyMap *keymap; /* Screen Editing ------------------------------------------------ */ - keymap= WM_keymap_find(wm, "Screen Editing", 0, 0); + keymap= WM_keymap_find(keyconf, "Screen Editing", 0, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1); @@ -3334,7 +3334,7 @@ void ED_keymap_screen(wmWindowManager *wm) /* Screen General ------------------------------------------------ */ - keymap= WM_keymap_find(wm, "Screen", 0, 0); + keymap= WM_keymap_find(keyconf, "Screen", 0, 0); /* standard timers */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0); @@ -3389,7 +3389,7 @@ void ED_keymap_screen(wmWindowManager *wm) /* Anim Playback ------------------------------------------------ */ - keymap= WM_keymap_find(wm, "Frames", 0, 0); + keymap= WM_keymap_find(keyconf, "Frames", 0, 0); /* frame offsets */ RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10); @@ -3409,6 +3409,6 @@ void ED_keymap_screen(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", KKEY, KM_PRESS, 0, LKEY); RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "reverse", 1); - keymap_modal_set(wm); + keymap_modal_set(keyconf); } diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 514c80d929d..11dbeffdb22 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -134,12 +134,12 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_vertex_color_set); } -void ED_keymap_paint(wmWindowManager *wm) +void ED_keymap_paint(wmKeyConfig *keyconf) { wmKeyMap *keymap; /* Sculpt mode */ - keymap= WM_keymap_find(wm, "Sculpt", 0, 0); + keymap= WM_keymap_find(keyconf, "Sculpt", 0, 0); keymap->poll= sculpt_poll; RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); @@ -150,7 +150,7 @@ void ED_keymap_paint(wmWindowManager *wm) WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); /* Vertex Paint mode */ - keymap= WM_keymap_find(wm, "Vertex Paint", 0, 0); + keymap= WM_keymap_find(keyconf, "Vertex Paint", 0, 0); keymap->poll= vertex_paint_poll; RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_vertex_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); @@ -159,7 +159,7 @@ void ED_keymap_paint(wmWindowManager *wm) WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); /* Weight Paint mode */ - keymap= WM_keymap_find(wm, "Weight Paint", 0, 0); + keymap= WM_keymap_find(keyconf, "Weight Paint", 0, 0); keymap->poll= weight_paint_poll; RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); @@ -168,7 +168,7 @@ void ED_keymap_paint(wmWindowManager *wm) WM_keymap_verify_item(keymap, "PAINT_OT_weight_paint", LEFTMOUSE, KM_PRESS, 0, 0); /* Image/Texture Paint mode */ - keymap= WM_keymap_find(wm, "Image Paint", 0, 0); + keymap= WM_keymap_find(keyconf, "Image Paint", 0, 0); keymap->poll= image_texture_paint_poll; RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_texture_paint_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index 4326bed62d3..c436475b537 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -124,7 +124,7 @@ enum { /* ***************************************** */ /* action_ops.c */ void action_operatortypes(void); -void action_keymap(struct wmWindowManager *wm); +void action_keymap(struct wmKeyConfig *keyconf); #endif /* ED_ACTION_INTERN_H */ diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index 00b22232608..ba504fa8a69 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -91,9 +91,9 @@ void action_operatortypes(void) /* ************************** registration - keymaps **********************************/ -static void action_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) +static void action_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap) { - wmKeymapItem *kmi; + wmKeyMapItem *kmi; /* action_select.c - selection tools */ /* click-select */ @@ -156,7 +156,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) WM_keymap_add_item(keymap, "ACT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); /* transform system */ - transform_keymap_for_space(wm, keymap, SPACE_ACTION); + transform_keymap_for_space(keyconf, keymap, SPACE_ACTION); /* test */ /* WM_keymap_add_item(keymap, "ACT_OT_test", QKEY, KM_PRESS, 0, 0); */ @@ -164,7 +164,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) /* --------------- */ -void action_keymap(wmWindowManager *wm) +void action_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap; @@ -175,7 +175,7 @@ void action_keymap(wmWindowManager *wm) */ /* keyframes */ - keymap= WM_keymap_find(wm, "Action_Keys", SPACE_ACTION, 0); - action_keymap_keyframes(wm, keymap); + keymap= WM_keymap_find(keyconf, "Action_Keys", SPACE_ACTION, 0); + action_keymap_keyframes(keyconf, keymap); } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 3b275cab814..07de15a26b4 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -158,7 +158,7 @@ static void action_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Action_Keys", SPACE_ACTION, 0); + keymap= WM_keymap_find(wm->defaultconf, "Action_Keys", SPACE_ACTION, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -221,7 +221,7 @@ static void action_channel_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Animation_Channels", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Animation_Channels", 0, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 8c563c98d9b..397da005543 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -110,35 +110,35 @@ void ED_spacetypes_init(void) /* called in wm.c */ /* keymap definitions are registered only once per WM initialize, usually on file read, using the keymap the actual areas/regions add the handlers */ -void ED_spacetypes_keymap(wmWindowManager *wm) +void ED_spacetypes_keymap(wmKeyConfig *keyconf) { const ListBase *spacetypes; SpaceType *stype; ARegionType *atype; - ED_keymap_screen(wm); - ED_keymap_anim(wm); - ED_keymap_animchannels(wm); - ED_keymap_gpencil(wm); - ED_keymap_object(wm); - ED_keymap_mesh(wm); - ED_keymap_uvedit(wm); - ED_keymap_curve(wm); - ED_keymap_armature(wm); - ED_keymap_physics(wm); - ED_keymap_metaball(wm); - ED_keymap_paint(wm); - ED_marker_keymap(wm); - - UI_view2d_keymap(wm); + ED_keymap_screen(keyconf); + ED_keymap_anim(keyconf); + ED_keymap_animchannels(keyconf); + ED_keymap_gpencil(keyconf); + ED_keymap_object(keyconf); + ED_keymap_mesh(keyconf); + ED_keymap_uvedit(keyconf); + ED_keymap_curve(keyconf); + ED_keymap_armature(keyconf); + ED_keymap_physics(keyconf); + ED_keymap_metaball(keyconf); + ED_keymap_paint(keyconf); + ED_marker_keymap(keyconf); + + UI_view2d_keymap(keyconf); spacetypes = BKE_spacetypes_list(); for(stype=spacetypes->first; stype; stype=stype->next) { if(stype->keymap) - stype->keymap(wm); + stype->keymap(keyconf); for(atype=stype->regiontypes.first; atype; atype=atype->next) { if(atype->keymap) - atype->keymap(wm); + atype->keymap(keyconf); } } } @@ -234,7 +234,7 @@ static void xxx_operatortypes(void) /* register operator types for this space */ } -static void xxx_keymap(wmWindowManager *wm) +static void xxx_keymap(wmKeyConfig *keyconf) { /* add default items to keymap */ } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 6ffbb79f273..03d126a3e7b 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -142,7 +142,7 @@ static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "Buttons Generic", SPACE_BUTS, 0); + keymap= WM_keymap_find(wm->defaultconf, "Buttons Generic", SPACE_BUTS, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -189,9 +189,9 @@ void buttons_operatortypes(void) WM_operatortype_append(BUTTONS_OT_file_browse); } -void buttons_keymap(struct wmWindowManager *wm) +void buttons_keymap(struct wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Buttons Generic", SPACE_BUTS, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Buttons Generic", SPACE_BUTS, 0); WM_keymap_add_item(keymap, "BUTTONS_OT_toolbox", RIGHTMOUSE, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 19fb575ed16..49bc3adb5b9 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -152,7 +152,7 @@ static void console_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0); + keymap= WM_keymap_find(wm->defaultconf, "Console", SPACE_CONSOLE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -232,9 +232,9 @@ void console_operatortypes(void) WM_operatortype_append(CONSOLE_OT_report_copy); } -void console_keymap(struct wmWindowManager *wm) +void console_keymap(struct wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Console", SPACE_CONSOLE, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Console", SPACE_CONSOLE, 0); #ifdef __APPLE__ RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 1b54277c383..afdb0d24917 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -172,16 +172,16 @@ static void file_panel_operator(const bContext *C, Panel *pa) { SpaceFile *sfile= CTX_wm_space_file(C); wmOperator *op= sfile->op; - int empty= 1; + int empty= 1, flag; if(op->type->ui) { op->type->ui((bContext*)C, op->ptr, pa->layout); } else { RNA_STRUCT_BEGIN(op->ptr, prop) { - if(strcmp(RNA_property_identifier(prop), "rna_type") == 0) - continue; - if(strcmp(RNA_property_identifier(prop), "filemode") == 0) + flag= RNA_property_flag(prop); + + if(flag & PROP_HIDDEN) continue; if(strcmp(RNA_property_identifier(prop), "path") == 0) continue; @@ -189,10 +189,6 @@ static void file_panel_operator(const bContext *C, Panel *pa) continue; if(strcmp(RNA_property_identifier(prop), "filename") == 0) continue; - if(strcmp(RNA_property_identifier(prop), "display") == 0) - continue; - if(strncmp(RNA_property_identifier(prop), "filter", 6) == 0) - continue; uiItemFullR(pa->layout, NULL, 0, op->ptr, prop, -1, 0, 0); empty= 0; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 8257aa5482f..94d90929d80 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -406,7 +406,7 @@ void folderlist_pushdir(ListBase* folderlist, const char *dir) previous_folder = folderlist->last; // check if already exists - if(previous_folder){ + if(previous_folder && previous_folder->foldername){ if(! strcmp(previous_folder->foldername, dir)){ return; } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 1f461f1bbd5..9f5d889c7b9 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -124,7 +124,10 @@ short ED_fileselect_set_params(SpaceFile *sfile) if (op) { BLI_strncpy(params->title, op->type->name, sizeof(params->title)); - params->type = RNA_int_get(op->ptr, "filemode"); + if(RNA_struct_find_property(op->ptr, "filename")) + params->type = RNA_int_get(op->ptr, "filemode"); + else + params->type = FILE_SPECIAL; if (RNA_property_is_set(op->ptr, "path")) { RNA_string_get(op->ptr, "path", name); @@ -140,15 +143,24 @@ short ED_fileselect_set_params(SpaceFile *sfile) } } params->filter = 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_movie") ? MOVIEFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_python") ? PYSCRIPTFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_font") ? FTFONTFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_sound") ? SOUNDFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; - params->filter |= RNA_boolean_get(op->ptr, "filter_folder") ? FOLDERFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_blender")) + params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_image")) + params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_movie")) + params->filter |= RNA_boolean_get(op->ptr, "filter_movie") ? MOVIEFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_text")) + params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_python")) + params->filter |= RNA_boolean_get(op->ptr, "filter_python") ? PYSCRIPTFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_font")) + params->filter |= RNA_boolean_get(op->ptr, "filter_font") ? FTFONTFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_sound")) + params->filter |= RNA_boolean_get(op->ptr, "filter_sound") ? SOUNDFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_text")) + params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; + if(RNA_struct_find_property(op->ptr, "filter_folder")) + params->filter |= RNA_boolean_get(op->ptr, "filter_folder") ? FOLDERFILE : 0; if (params->filter != 0) params->flag |= FILE_FILTER; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 77f50d91e77..4d3376e0e1f 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -253,10 +253,10 @@ static void file_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymaps */ - keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); + keymap= WM_keymap_find(wm->defaultconf, "File", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "FileMain", SPACE_FILE, 0); + keymap= WM_keymap_find(wm->defaultconf, "FileMain", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -364,11 +364,11 @@ void file_operatortypes(void) } /* NOTE: do not add .blend file reading on this level */ -void file_keymap(struct wmWindowManager *wm) +void file_keymap(struct wmKeyConfig *keyconf) { - wmKeymapItem *kmi; + wmKeyMapItem *kmi; /* keys for all areas */ - wmKeyMap *keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "File", SPACE_FILE, 0); WM_keymap_add_item(keymap, "FILE_OT_bookmark_toggle", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_add_bookmark", BKEY, KM_PRESS, KM_CTRL, 0); @@ -380,7 +380,7 @@ void file_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "FILE_OT_delete", DELKEY, KM_PRESS, 0, 0); /* keys for main area */ - keymap= WM_keymap_find(wm, "FileMain", SPACE_FILE, 0); + keymap= WM_keymap_find(keyconf, "FileMain", SPACE_FILE, 0); WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0); @@ -401,7 +401,7 @@ void file_keymap(struct wmWindowManager *wm) RNA_int_set(kmi->ptr, "increment",-100); /* keys for button area (top) */ - keymap= WM_keymap_find(wm, "FileButtons", SPACE_FILE, 0); + keymap= WM_keymap_find(keyconf, "FileButtons", SPACE_FILE, 0); WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0); RNA_int_set(kmi->ptr, "increment", 1); @@ -425,7 +425,7 @@ static void file_channel_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); /* own keymaps */ - keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); + keymap= WM_keymap_find(wm->defaultconf, "File", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -461,10 +461,10 @@ static void file_ui_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "File", SPACE_FILE, 0); + keymap= WM_keymap_find(wm->defaultconf, "File", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "FileButtons", SPACE_FILE, 0); + keymap= WM_keymap_find(wm->defaultconf, "FileButtons", SPACE_FILE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 83a565e485f..9b7c2eb3656 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -159,7 +159,7 @@ int graphop_selected_fcurve_poll(struct bContext *C); /* ***************************************** */ /* graph_ops.c */ -void graphedit_keymap(struct wmWindowManager *wm); +void graphedit_keymap(struct wmKeyConfig *keyconf); void graphedit_operatortypes(void); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index b82055064f8..ab35bda0e2f 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -141,9 +141,9 @@ void graphedit_operatortypes(void) /* ************************** registration - keymaps **********************************/ -static void graphedit_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) +static void graphedit_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap) { - wmKeymapItem *kmi; + wmKeyMapItem *kmi; /* view */ WM_keymap_add_item(keymap, "GRAPH_OT_handles_view_toggle", HKEY, KM_PRESS, KM_CTRL, 0); @@ -225,17 +225,17 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, wmKeyMap *keymap) /* transform system */ - transform_keymap_for_space(wm, keymap, SPACE_IPO); + transform_keymap_for_space(keyconf, keymap, SPACE_IPO); } /* --------------- */ -void graphedit_keymap(wmWindowManager *wm) +void graphedit_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap; /* keymap for all regions */ - keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(keyconf, "GraphEdit Generic", SPACE_IPO, 0); WM_keymap_add_item(keymap, "GRAPH_OT_properties", NKEY, KM_PRESS, 0, 0); /* channels */ @@ -245,7 +245,7 @@ void graphedit_keymap(wmWindowManager *wm) */ /* keyframes */ - keymap= WM_keymap_find(wm, "GraphEdit Keys", SPACE_IPO, 0); - graphedit_keymap_keyframes(wm, keymap); + keymap= WM_keymap_find(keyconf, "GraphEdit Keys", SPACE_IPO, 0); + graphedit_keymap_keyframes(keyconf, keymap); } diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index a7ea2294ed4..c8d2c571a16 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -208,9 +208,9 @@ static void graph_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "GraphEdit Keys", SPACE_IPO, 0); + keymap= WM_keymap_find(wm->defaultconf, "GraphEdit Keys", SPACE_IPO, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm->defaultconf, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -286,9 +286,9 @@ static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Animation_Channels", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Animation_Channels", 0, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm->defaultconf, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -356,7 +356,7 @@ static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "GraphEdit Generic", SPACE_IPO, 0); + keymap= WM_keymap_find(wm->defaultconf, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 4cf59c9a28e..e64bb1a4209 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -202,9 +202,9 @@ void image_operatortypes(void) WM_operatortype_append(IMAGE_OT_properties); } -void image_keymap(struct wmWindowManager *wm) +void image_keymap(struct wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0); WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0); @@ -212,7 +212,7 @@ void image_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0); - keymap= WM_keymap_find(wm, "Image", SPACE_IMAGE, 0); + keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); @@ -389,16 +389,16 @@ static void image_main_area_init(wmWindowManager *wm, ARegion *ar) // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* image paint polls for mode */ - keymap= WM_keymap_find(wm, "Image Paint", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm->defaultconf, "Image Paint", SPACE_IMAGE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "UVEdit", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "UVEdit", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* own keymaps */ - keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Image", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -463,7 +463,7 @@ static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "Image Generic", SPACE_IMAGE, 0); + keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index d3f9c97205c..518553c9a7a 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -134,7 +134,7 @@ void info_operatortypes(void) WM_operatortype_append(FILE_OT_find_missing_files); } -void info_keymap(struct wmWindowManager *wm) +void info_keymap(struct wmKeyConfig *keyconf) { } diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c index 7043d625ab0..836ac4c6659 100644 --- a/source/blender/editors/space_logic/space_logic.c +++ b/source/blender/editors/space_logic/space_logic.c @@ -186,9 +186,9 @@ void logic_operatortypes(void) } -void logic_keymap(struct wmWindowManager *wm) +void logic_keymap(struct wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Logic Generic", SPACE_LOGIC, 0); WM_keymap_add_item(keymap, "LOGIC_OT_properties", NKEY, KM_PRESS, 0, 0); } @@ -239,7 +239,7 @@ static void logic_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymaps */ - keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0); + keymap= WM_keymap_find(wm->defaultconf, "Logic Generic", SPACE_LOGIC, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -280,7 +280,7 @@ static void logic_buttons_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "Logic Generic", SPACE_LOGIC, 0); + keymap= WM_keymap_find(wm->defaultconf, "Logic Generic", SPACE_LOGIC, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h index e4557ec878f..91c1decc576 100644 --- a/source/blender/editors/space_nla/nla_intern.h +++ b/source/blender/editors/space_nla/nla_intern.h @@ -130,7 +130,7 @@ short nlaedit_is_tweakmode_on(bAnimContext *ac); /* --- */ void nla_operatortypes(void); -void nla_keymap(wmWindowManager *wm); +void nla_keymap(wmKeyConfig *keyconf); #endif /* ED_NLA_INTERN_H */ diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c index 5ea2e99ad6a..6c940f32c24 100644 --- a/source/blender/editors/space_nla/nla_ops.c +++ b/source/blender/editors/space_nla/nla_ops.c @@ -167,7 +167,7 @@ void nla_operatortypes(void) /* ************************** registration - keymaps **********************************/ -static void nla_keymap_channels (wmWindowManager *wm, wmKeyMap *keymap) +static void nla_keymap_channels (wmKeyConfig *keyconf, wmKeyMap *keymap) { /* NLA-specific (different to standard channels keymap) -------------------------- */ /* selection */ @@ -210,9 +210,9 @@ static void nla_keymap_channels (wmWindowManager *wm, wmKeyMap *keymap) RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0)->ptr, "all", 1); } -static void nla_keymap_main (wmWindowManager *wm, wmKeyMap *keymap) +static void nla_keymap_main (wmKeyConfig *keyconf, wmKeyMap *keymap) { - wmKeymapItem *kmi; + wmKeyMapItem *kmi; /* selection */ /* click select */ @@ -277,17 +277,17 @@ static void nla_keymap_main (wmWindowManager *wm, wmKeyMap *keymap) WM_keymap_add_item(keymap, "NLA_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); /* transform system */ - transform_keymap_for_space(wm, keymap, SPACE_NLA); + transform_keymap_for_space(keyconf, keymap, SPACE_NLA); } /* --------------- */ -void nla_keymap(wmWindowManager *wm) +void nla_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap; /* keymap for all regions */ - keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(keyconf, "NLA Generic", SPACE_NLA, 0); WM_keymap_add_item(keymap, "NLA_OT_properties", NKEY, KM_PRESS, 0, 0); /* channels */ @@ -297,11 +297,11 @@ void nla_keymap(wmWindowManager *wm) * * However, those operations which involve clicking on channels and/or the placement of them in the view are implemented here instead */ - keymap= WM_keymap_find(wm, "NLA Channels", SPACE_NLA, 0); - nla_keymap_channels(wm, keymap); + keymap= WM_keymap_find(keyconf, "NLA Channels", SPACE_NLA, 0); + nla_keymap_channels(keyconf, keymap); /* data */ - keymap= WM_keymap_find(wm, "NLA Data", SPACE_NLA, 0); - nla_keymap_main(wm, keymap); + keymap= WM_keymap_find(keyconf, "NLA Data", SPACE_NLA, 0); + nla_keymap_main(keyconf, keymap); } diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 41435810889..32ff7766690 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -214,9 +214,9 @@ static void nla_channel_area_init(wmWindowManager *wm, ARegion *ar) /* own keymap */ // TODO: cannot use generic copy, need special NLA version - keymap= WM_keymap_find(wm, "NLA Channels", SPACE_NLA, 0); + keymap= WM_keymap_find(wm->defaultconf, "NLA Channels", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -259,9 +259,9 @@ static void nla_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "NLA Data", SPACE_NLA, 0); + keymap= WM_keymap_find(wm->defaultconf, "NLA Data", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); - keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -358,7 +358,7 @@ static void nla_buttons_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "NLA Generic", SPACE_NLA, 0); + keymap= WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 9f28a5e3dcb..f55ecf1d0f4 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -53,7 +53,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d); /* node_ops.c */ void node_operatortypes(void); -void node_keymap(wmWindowManager *wm); +void node_keymap(wmKeyConfig *keyconf); /* node_select.c */ void NODE_OT_select(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 880cc489838..443b83a91bc 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -67,10 +67,10 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_group_edit); } -void node_keymap(struct wmWindowManager *wm) +void node_keymap(struct wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0); - wmKeymapItem *kmi; + wmKeyMap *keymap= WM_keymap_find(keyconf, "Node", SPACE_NODE, 0); + wmKeyMapItem *kmi; /* mouse select in nodes used to be both keys, it's UI elements... */ RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0)->ptr, "select_type", NODE_SELECT_MOUSE); @@ -101,5 +101,5 @@ void node_keymap(struct wmWindowManager *wm) kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(kmi->ptr, "name", "NODE_MT_add"); - transform_keymap_for_space(wm, keymap, SPACE_NODE); + transform_keymap_for_space(keyconf, keymap, SPACE_NODE); } diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index bdd2a65984f..41140eae776 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -252,7 +252,7 @@ static void node_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Node", SPACE_NODE, 0); + keymap= WM_keymap_find(wm->defaultconf, "Node", SPACE_NODE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 641137c010b..28fdc4708df 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1113,16 +1113,16 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } else if(type == TSE_KEYMAP) { wmKeyMap *km= (wmKeyMap *)idv; - wmKeymapItem *kmi; + wmKeyMapItem *kmi; char opname[OP_MAX_TYPENAME]; te->directdata= idv; - te->name= km->nameid; + te->name= km->idname; if(!(tselem->flag & TSE_CLOSED)) { a= 0; - for (kmi= km->keymap.first; kmi; kmi= kmi->next, a++) { + for (kmi= km->items.first; kmi; kmi= kmi->next, a++) { const char *key= WM_key_event_string(kmi->type); if(key[0]) { @@ -1408,7 +1408,7 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) wmWindowManager *wm= mainvar->wm.first; wmKeyMap *km; - for(km= wm->keymaps.first; km; km= km->next) { + for(km= wm->defaultconf->keymaps.first; km; km= km->next) { ten= outliner_add_element(soops, &soops->tree, (void*)km, NULL, TSE_KEYMAP, 0); } } @@ -2229,14 +2229,14 @@ static int tree_element_active_sequence_dup(bContext *C, Scene *scene, TreeEleme static int tree_element_active_keymap_item(bContext *C, TreeElement *te, TreeStoreElem *tselem, int set) { - wmKeymapItem *kmi= te->directdata; + wmKeyMapItem *kmi= te->directdata; if(set==0) { - if(kmi->inactive) return 0; + if(kmi->flag & KMI_INACTIVE) return 0; return 1; } else { - kmi->inactive= !kmi->inactive; + kmi->flag ^= KMI_INACTIVE; } return 0; } @@ -4957,7 +4957,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa static void operator_call_cb(struct bContext *C, void *arg_kmi, void *arg2) { wmOperatorType *ot= arg2; - wmKeymapItem *kmi= arg_kmi; + wmKeyMapItem *kmi= arg_kmi; if(ot) BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME); @@ -4987,7 +4987,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) static char search[OP_MAX_TYPENAME]; wmEvent event; wmWindow *win= CTX_wm_window(C); - wmKeymapItem *kmi= arg_kmi; + wmKeyMapItem *kmi= arg_kmi; wmOperatorType *ot= WM_operatortype_find(kmi->idname, 0); uiBlock *block; uiBut *but; @@ -5026,8 +5026,8 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) static short keymap_menu_type(short type) { if(ISKEYBOARD(type)) return OL_KM_KEYBOARD; - if(WM_key_event_is_tweak(type)) return OL_KM_TWEAK; - if(type >= LEFTMOUSE && type <= WHEELOUTMOUSE) return OL_KM_MOUSE; + if(ISTWEAK(type)) return OL_KM_TWEAK; + if(ISMOUSE(type)) return OL_KM_MOUSE; // return OL_KM_SPECIALS; return 0; } @@ -5083,8 +5083,6 @@ static char *keymap_tweak_menu(void) str += sprintf(str, formatstr, "Left Mouse", EVT_TWEAK_L); str += sprintf(str, formatstr, "Middle Mouse", EVT_TWEAK_M); str += sprintf(str, formatstr, "Right Mouse", EVT_TWEAK_R); - str += sprintf(str, formatstr, "Button4 Mouse ", BUTTON4MOUSE); - str += sprintf(str, formatstr, "Button5 Mouse ", BUTTON5MOUSE); str += sprintf(str, formatstr, "Action Mouse", EVT_TWEAK_A); str += sprintf(str, formatstr, "Select Mouse", EVT_TWEAK_S); @@ -5115,7 +5113,7 @@ static char *keymap_tweak_dir_menu(void) static void keymap_type_cb(bContext *C, void *kmi_v, void *unused_v) { - wmKeymapItem *kmi= kmi_v; + wmKeyMapItem *kmi= kmi_v; short maptype= keymap_menu_type(kmi->type); if(maptype!=kmi->maptype) { @@ -5158,7 +5156,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo int butw3= 43; /* modifiers */ if(tselem->type == TSE_KEYMAP_ITEM) { - wmKeymapItem *kmi= te->directdata; + wmKeyMapItem *kmi= te->directdata; /* modal map? */ if(kmi->propvalue); diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 4f9a0f686b9..c71b5181d16 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -110,7 +110,7 @@ typedef struct TreeElement { /* outliner_ops.c */ void outliner_operatortypes(void); -void outliner_keymap(struct wmWindowManager *wm); +void outliner_keymap(struct wmKeyConfig *keyconf); /* outliner_header.c */ void outliner_header_buttons(const struct bContext *C, struct ARegion *ar); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index a35b91249db..3cdd054fe0e 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -74,9 +74,9 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_drivers_delete); } -void outliner_keymap(wmWindowManager *wm) +void outliner_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Outliner", SPACE_OUTLINER, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Outliner", SPACE_OUTLINER, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index eb0e9dafbaa..fabe889ace6 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -77,7 +77,7 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Outliner", SPACE_OUTLINER, 0); + keymap= WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_script/script_intern.h b/source/blender/editors/space_script/script_intern.h index 59858ee6289..7534fc98de1 100644 --- a/source/blender/editors/space_script/script_intern.h +++ b/source/blender/editors/space_script/script_intern.h @@ -36,7 +36,7 @@ void script_header_buttons(const bContext *C, ARegion *ar); /* script_ops.c */ void script_operatortypes(void); -void script_keymap(struct wmWindowManager *wm); +void script_keymap(struct wmKeyConfig *keyconf); /* script_edit.c */ void SCRIPT_OT_python_file_run(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c index 0e6ea9cf4fd..bf0a7e5769e 100644 --- a/source/blender/editors/space_script/script_ops.c +++ b/source/blender/editors/space_script/script_ops.c @@ -63,9 +63,9 @@ void script_operatortypes(void) WM_operatortype_append(SCRIPT_OT_python_run_ui_scripts); } -void script_keymap(wmWindowManager *wm) +void script_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Script", SPACE_SCRIPT, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Script", SPACE_SCRIPT, 0); /* TODO - this is just while we have no way to load a text datablock */ RNA_string_set(WM_keymap_add_item(keymap, "SCRIPT_OT_python_file_run", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT|KM_ALT, 0)->ptr, "path", "test.py"); diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index a0e73082701..eae0f77d0e1 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -138,7 +138,7 @@ static void script_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, "Script", SPACE_SCRIPT, 0); + keymap= WM_keymap_find(wm->defaultconf, "Script", SPACE_SCRIPT, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index ac396440a00..d45d7bf4d18 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -75,7 +75,8 @@ extern EnumPropertyItem prop_side_types[]; /* operators */ struct wmOperatorType; -struct wmWindowManager; +struct wmKeyConfig; + void SEQUENCER_OT_cut(struct wmOperatorType *ot); void SEQUENCER_OT_mute(struct wmOperatorType *ot); void SEQUENCER_OT_unmute(struct wmOperatorType *ot); @@ -137,7 +138,7 @@ enum { /* sequencer_ops.c */ void sequencer_operatortypes(void); -void sequencer_keymap(struct wmWindowManager *wm); +void sequencer_keymap(struct wmKeyConfig *keyconf); /* sequencer_scope.c */ struct ImBuf *make_waveform_view_from_ibuf(struct ImBuf * ibuf); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 1541b32f566..eedbab779c0 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -103,10 +103,10 @@ void sequencer_operatortypes(void) } -void sequencer_keymap(wmWindowManager *wm) +void sequencer_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Sequencer", SPACE_SEQ, 0); - wmKeymapItem *kmi; + wmKeyMap *keymap= WM_keymap_find(keyconf, "Sequencer", SPACE_SEQ, 0); + wmKeyMapItem *kmi; WM_keymap_add_item(keymap, "SEQUENCER_OT_properties", NKEY, KM_PRESS, 0, 0); @@ -183,6 +183,6 @@ void sequencer_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); - transform_keymap_for_space(wm, keymap, SPACE_SEQ); + transform_keymap_for_space(keyconf, keymap, SPACE_SEQ); } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index c2756b05946..626a3e6e2e0 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -190,7 +190,7 @@ static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Sequencer", SPACE_SEQ, 0); + keymap= WM_keymap_find(wm->defaultconf, "Sequencer", SPACE_SEQ, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_sound/space_sound.c b/source/blender/editors/space_sound/space_sound.c index 6713e19b6de..7cd9988eea0 100644 --- a/source/blender/editors/space_sound/space_sound.c +++ b/source/blender/editors/space_sound/space_sound.c @@ -147,7 +147,7 @@ static void sound_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "Sound", SPACE_SOUND, 0); + keymap= WM_keymap_find(wm->defaultconf, "Sound", SPACE_SOUND, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } @@ -179,7 +179,7 @@ void sound_operatortypes(void) } -void sound_keymap(struct wmWindowManager *wm) +void sound_keymap(struct wmKeyConfig *keyconf) { } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index e068c1a70bb..e3816ed7495 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -206,11 +206,11 @@ static void text_operatortypes(void) WM_operatortype_append(TEXT_OT_resolve_conflict); } -static void text_keymap(struct wmWindowManager *wm) +static void text_keymap(struct wmKeyConfig *keyconf) { wmKeyMap *keymap; - keymap= WM_keymap_find(wm, "Text", SPACE_TEXT, 0); + keymap= WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0); #ifdef __APPLE__ RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN); @@ -336,7 +336,7 @@ static void text_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, "Text", SPACE_TEXT, 0); + keymap= WM_keymap_find(wm->defaultconf, "Text", SPACE_TEXT, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 0f05eb0149d..501ac1c0cba 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -207,7 +207,7 @@ static void time_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); /* own keymap */ - keymap= WM_keymap_find(wm, "TimeLine", SPACE_TIME, 0); + keymap= WM_keymap_find(wm->defaultconf, "TimeLine", SPACE_TIME, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } diff --git a/source/blender/editors/space_time/time_intern.h b/source/blender/editors/space_time/time_intern.h index 25f4c63fed1..ac6b407d117 100644 --- a/source/blender/editors/space_time/time_intern.h +++ b/source/blender/editors/space_time/time_intern.h @@ -35,7 +35,7 @@ struct wmWindowManager; /* time_ops.c */ void time_operatortypes(void); -void time_keymap(struct wmWindowManager *wm); +void time_keymap(struct wmKeyConfig *keyconf); /* time_header.c */ void time_header_buttons(const bContext *C, ARegion *ar); diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index 2b073f269bf..7d91c6d0fc7 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -140,9 +140,9 @@ void time_operatortypes(void) WM_operatortype_append(TIME_OT_end_frame_set); } -void time_keymap(wmWindowManager *wm) +void time_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "TimeLine", SPACE_TIME, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "TimeLine", SPACE_TIME, 0); WM_keymap_add_item(keymap, "TIME_OT_start_frame_set", SKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "TIME_OT_end_frame_set", EKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index 8c9d723ce2c..39fc2fd2bd1 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -115,7 +115,7 @@ void userpref_operatortypes(void) { } -void userpref_keymap(struct wmWindowManager *wm) +void userpref_keymap(struct wmKeyConfig *keyconf) { } @@ -167,7 +167,7 @@ void ED_spacetype_userpref(void) art->init= userpref_main_area_init; art->draw= userpref_main_area_draw; art->listener= userpref_main_area_listener; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; + art->keymapflag= ED_KEYMAP_UI; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 735f3df9b09..e1bd48e002f 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -280,62 +280,62 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) wmKeyMap *keymap; /* object ops. */ - keymap= WM_keymap_find(wm, "Object Non-modal", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* pose is not modal, operator poll checks for this */ - keymap= WM_keymap_find(wm, "Pose", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Object Mode", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Image Paint", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Vertex Paint", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Vertex Paint", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Weight Paint", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Weight Paint", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Sculpt", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "EditMesh", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "EditMesh", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Curve", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Curve", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Armature", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Armature", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Pose", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Metaball", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Metaball", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Lattice", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Lattice", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* armature sketching needs to take over mouse */ - keymap= WM_keymap_find(wm, "Armature_Sketch", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Armature_Sketch", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "Particle", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Particle", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* editfont keymap swallows all... */ - keymap= WM_keymap_find(wm, "Font", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Font", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); /* own keymap, last so modes can override it */ - keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "View3D", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -491,7 +491,7 @@ static void view3d_main_area_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar) { - wmKeyMap *keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -531,7 +531,7 @@ static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } @@ -602,7 +602,7 @@ static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar) ED_region_panels_init(wm, ar); - keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index c07d9108993..4c96e1fee39 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -371,7 +371,7 @@ enum { /* called in transform_ops.c, on each regeneration of keymaps */ -void viewrotate_modal_keymap(wmWindowManager *wm) +void viewrotate_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Cancel", ""}, @@ -381,12 +381,12 @@ void viewrotate_modal_keymap(wmWindowManager *wm) {0, NULL, 0, NULL, NULL}}; - wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Rotate Modal"); + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Rotate Modal"); /* this function is called for each spacetype, only needs to add map once */ if(keymap) return; - keymap= WM_modalkeymap_add(wm, "View3D Rotate Modal", modal_items); + keymap= WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items); /* items for modal map */ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); @@ -630,19 +630,19 @@ void VIEW3D_OT_rotate(wmOperatorType *ot) /* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ /* called in transform_ops.c, on each regeneration of keymaps */ -void viewmove_modal_keymap(wmWindowManager *wm) +void viewmove_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, {0, NULL, 0, NULL, NULL}}; - wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Move Modal"); + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Move Modal"); /* this function is called for each spacetype, only needs to add map once */ if(keymap) return; - keymap= WM_modalkeymap_add(wm, "View3D Move Modal", modal_items); + keymap= WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items); /* items for modal map */ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); @@ -749,19 +749,19 @@ void VIEW3D_OT_move(wmOperatorType *ot) /* ************************ viewzoom ******************************** */ /* called in transform_ops.c, on each regeneration of keymaps */ -void viewzoom_modal_keymap(wmWindowManager *wm) +void viewzoom_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {VIEW_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, {0, NULL, 0, NULL, NULL}}; - wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Zoom Modal"); + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Zoom Modal"); /* this function is called for each spacetype, only needs to add map once */ if(keymap) return; - keymap= WM_modalkeymap_add(wm, "View3D Zoom Modal", modal_items); + keymap= WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items); /* items for modal map */ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index d80cec9ad48..84d1a1275a9 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -62,7 +62,7 @@ void VIEW3D_OT_layers(struct wmOperatorType *ot); /* view3d_ops.c */ void view3d_operatortypes(void); -void view3d_keymap(struct wmWindowManager *wm); +void view3d_keymap(struct wmKeyConfig *keyconf); /* view3d_edit.c */ void VIEW3D_OT_zoom(struct wmOperatorType *ot); @@ -137,10 +137,10 @@ void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); /* rect: for picking */ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); -void fly_modal_keymap(struct wmWindowManager *wm); -void viewrotate_modal_keymap(struct wmWindowManager *wm); -void viewmove_modal_keymap(struct wmWindowManager *wm); -void viewzoom_modal_keymap(struct wmWindowManager *wm); +void fly_modal_keymap(struct wmKeyConfig *keyconf); +void viewrotate_modal_keymap(struct wmKeyConfig *keyconf); +void viewmove_modal_keymap(struct wmKeyConfig *keyconf); +void viewzoom_modal_keymap(struct wmKeyConfig *keyconf); /* view3d_buttons.c */ void VIEW3D_OT_properties(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index a151ff3e73a..74074a04188 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -103,18 +103,18 @@ void view3d_operatortypes(void) transform_operatortypes(); } -void view3d_keymap(wmWindowManager *wm) +void view3d_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap; - wmKeymapItem *km; + wmKeyMapItem *km; - keymap= WM_keymap_find(wm, "View3D Generic", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(keyconf, "View3D Generic", SPACE_VIEW3D, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_toolbar", TKEY, KM_PRESS, 0, 0); /* only for region 3D window */ - keymap= WM_keymap_find(wm, "View3D", SPACE_VIEW3D, 0); + keymap= WM_keymap_find(keyconf, "View3D", SPACE_VIEW3D, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, 0, 0); /* manipulator always on left mouse, not on action mouse*/ @@ -221,11 +221,11 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0); - transform_keymap_for_space(wm, keymap, SPACE_VIEW3D); + transform_keymap_for_space(keyconf, keymap, SPACE_VIEW3D); - fly_modal_keymap(wm); - viewrotate_modal_keymap(wm); - viewmove_modal_keymap(wm); - viewzoom_modal_keymap(wm); + fly_modal_keymap(keyconf); + viewrotate_modal_keymap(keyconf); + viewmove_modal_keymap(keyconf); + viewzoom_modal_keymap(keyconf); } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 505f3abf401..d26141e3b54 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1633,7 +1633,7 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) #define FLY_MODAL_PRECISION_DISABLE 16 /* called in transform_ops.c, on each regeneration of keymaps */ -void fly_modal_keymap(wmWindowManager *wm) +void fly_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, @@ -1659,12 +1659,12 @@ void fly_modal_keymap(wmWindowManager *wm) {0, NULL, 0, NULL, NULL}}; - wmKeyMap *keymap= WM_modalkeymap_get(wm, "View3D Fly Modal"); + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Fly Modal"); /* this function is called for each spacetype, only needs to add map once */ if(keymap) return; - keymap= WM_modalkeymap_add(wm, "View3D Fly Modal", modal_items); + keymap= WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items); /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, FLY_MODAL_CANCEL); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 839c3543515..ad89d8a3a59 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -515,7 +515,7 @@ static char *transform_to_undostr(TransInfo *t) #define TFM_MODAL_SNAP_GEARS_OFF 7 /* called in transform_ops.c, on each regeneration of keymaps */ -void transform_modal_keymap(wmWindowManager *wm) +void transform_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, @@ -527,12 +527,12 @@ void transform_modal_keymap(wmWindowManager *wm) {TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""}, {0, NULL, 0, NULL, NULL}}; - wmKeyMap *keymap= WM_modalkeymap_get(wm, "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) return; - keymap= WM_modalkeymap_add(wm, "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); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 1c170a31c45..60786127e3a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -508,7 +508,7 @@ int Align(TransInfo *t, short mval[2]); void drawPropCircle(const struct bContext *C, TransInfo *t); -void transform_modal_keymap(struct wmWindowManager *wm); +void transform_modal_keymap(struct wmKeyConfig *keyconf); /*********************** transform_conversions.c ********** */ diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 7ef8ad17a69..0913f0ea273 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -734,12 +734,12 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_delete_orientation); } -void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid) +void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int spaceid) { - wmKeymapItem *km; + wmKeyMapItem *km; /* transform.c, only adds modal map once, checks if it's there */ - transform_modal_keymap(wm); + transform_modal_keymap(keyconf); switch(spaceid) { diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 9216cfb5cdc..0f79420d3a7 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -3084,11 +3084,11 @@ void ED_operatortypes_uvedit(void) WM_operatortype_append(UV_OT_tile_set); } -void ED_keymap_uvedit(wmWindowManager *wm) +void ED_keymap_uvedit(wmKeyConfig *keyconf) { wmKeyMap *keymap; - keymap= WM_keymap_find(wm, "UVEdit", 0, 0); + keymap= WM_keymap_find(keyconf, "UVEdit", 0, 0); keymap->poll= ED_operator_uvedit; /* pick selection */ @@ -3129,6 +3129,6 @@ void ED_keymap_uvedit(wmWindowManager *wm) WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "UV_OT_tile_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); - transform_keymap_for_space(wm, keymap, SPACE_IMAGE); + transform_keymap_for_space(keyconf, keymap, SPACE_IMAGE); } diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 5aa1aa6dfff..6a1b22e1ed5 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -308,6 +308,8 @@ typedef struct UserDef { struct ListBase themes; struct ListBase uifonts; struct ListBase uistyles; + struct ListBase keymaps; + char keyconfigstr[64]; short undosteps; short undomemory; @@ -345,6 +347,14 @@ extern UserDef U; /* from blenkernel blender.c */ /* ***************** USERDEF ****************** */ +/* userpref/section */ +#define USER_SECTION_INTERFACE 0 +#define USER_SECTION_EDIT 1 +#define USER_SECTION_FILE 2 +#define USER_SECTION_SYSTEM 3 +#define USER_SECTION_THEME 4 +#define USER_SECTION_INPUT 5 + /* flag */ #define USER_AUTOSAVE (1 << 0) #define USER_AUTOGRABGRID (1 << 1) diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index ea9d0e86c38..2b986d6d802 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -42,6 +42,7 @@ struct wmGesture; struct wmOperatorType; struct wmOperator; struct wmKeyMap; +struct wmKeyConfig; /* forwards */ struct bContext; @@ -120,9 +121,9 @@ typedef struct wmWindowManager { ListBase paintcursors; /* extra overlay cursors to draw, like circles */ - /* used keymaps, optionally/partially saved */ - ListBase keymaps; - + ListBase keyconfigs; /* known key configurations */ + struct wmKeyConfig *defaultconf; /* default configuration, not saved */ + int defaultactmap, pad2; /* active keymap from default for editing */ } wmWindowManager; /* wmWindowManager.initialized */ @@ -234,44 +235,70 @@ typedef struct wmOperatorType { /* partial copy of the event, for matching by eventhandler */ -typedef struct wmKeymapItem { - struct wmKeymapItem *next, *prev; +typedef struct wmKeyMapItem { + struct wmKeyMapItem *next, *prev; + /* operator */ char idname[64]; /* used to retrieve operator type pointer */ - struct PointerRNA *ptr; /* rna pointer to access properties */ + IDProperty *properties; /* operator properties */ + /* modal */ + short propvalue; /* if used, the item is from modal map */ + + /* event */ short type; /* event code itself */ short val; /* 0=any, 1=click, 2=release, or wheelvalue, or... */ short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ short keymodifier; /* rawkey modifier */ - short propvalue; /* if used, the item is from modal map */ - - short inactive; /* if set, deactivated item */ - short maptype; /* keymap editor */ - short pad2, pad3; -} wmKeymapItem; + /* flag: inactive, expanded */ + short flag; + /* runtime */ + short maptype, pad[2]; /* keymap editor */ + struct PointerRNA *ptr; /* rna pointer to access properties */ +} wmKeyMapItem; + +/* wmKeyMapItem.flag */ +#define KMI_INACTIVE 1 +#define KMI_EXPANDED 2 /* stored in WM, the actively used keymaps */ typedef struct wmKeyMap { struct wmKeyMap *next, *prev; - ListBase keymap; + ListBase items; - char nameid[64]; /* global editor keymaps, or for more per space/region */ + char idname[64]; /* global editor keymaps, or for more per space/region */ short spaceid; /* same IDs as in DNA_space_types.h */ short regionid; /* see above */ - short is_modal; /* modal map, not using operatornames */ + short flag; /* general flags */ short pad; - void *items; /* struct EnumPropertyItem for now */ - - /* verify if the keymap is enabled in the current context */ - int (*poll)(struct bContext *); + /* runtime */ + int (*poll)(struct bContext *); /* verify if enabled in the current context */ + void *modal_items; /* for modal, EnumPropertyItem for now */ } wmKeyMap; +/* wmKeyMap.flag */ +#define KEYMAP_MODAL 1 /* modal map, not using operatornames */ +#define KEYMAP_USER 2 /* user created keymap */ + +typedef struct wmKeyConfig { + struct wmKeyConfig *next, *prev; + + char idname[64]; /* unique name */ + char basename[64]; /* idname of configuration this is derives from, "" if none */ + + ListBase keymaps; + int actkeymap, flag; +} wmKeyConfig; + +/* wmKeyConfig.flag */ +#define KEYCONF_TWOBUTTONMOUSE (1 << 1) +#define KEYCONF_LMOUSESELECT (1 << 2) +#define KEYCONF_NONUMPAD (1 << 3) /* this one is the operator itself, stored in files for macros etc */ /* operator + operatortype should be able to redo entirely, but for different contextes */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 9ea7725b855..810fb110f7a 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -56,6 +56,7 @@ extern StructRNA RNA_Area; extern StructRNA RNA_AreaLamp; extern StructRNA RNA_Armature; extern StructRNA RNA_ArmatureModifier; +extern StructRNA RNA_ArmatureSensor; extern StructRNA RNA_ArrayModifier; extern StructRNA RNA_BackgroundImage; extern StructRNA RNA_BevelModifier; @@ -76,6 +77,7 @@ extern StructRNA RNA_BoneGroup; extern StructRNA RNA_BooleanModifier; extern StructRNA RNA_BooleanProperty; extern StructRNA RNA_Brush; +extern StructRNA RNA_BrushTextureSlot; extern StructRNA RNA_BuildModifier; extern StructRNA RNA_Camera; extern StructRNA RNA_CastModifier; @@ -99,7 +101,8 @@ extern StructRNA RNA_CompositorNodeBilateralblur; extern StructRNA RNA_CompositorNodeBlur; extern StructRNA RNA_CompositorNodeBrightContrast; extern StructRNA RNA_CompositorNodeChannelMatte; -extern StructRNA RNA_CompositorNodeChroma; +extern StructRNA RNA_CompositorNodeChromaMatte; +extern StructRNA RNA_CompositorNodeColorMatte; extern StructRNA RNA_CompositorNodeColorSpill; extern StructRNA RNA_CompositorNodeCombHSVA; extern StructRNA RNA_CompositorNodeCombRGBA; @@ -114,6 +117,7 @@ extern StructRNA RNA_CompositorNodeDefocus; extern StructRNA RNA_CompositorNodeDiffMatte; extern StructRNA RNA_CompositorNodeDilateErode; extern StructRNA RNA_CompositorNodeDisplace; +extern StructRNA RNA_CompositorNodeDistanceMatte; extern StructRNA RNA_CompositorNodeFilter; extern StructRNA RNA_CompositorNodeFlip; extern StructRNA RNA_CompositorNodeGamma; @@ -123,6 +127,7 @@ extern StructRNA RNA_CompositorNodeIDMask; extern StructRNA RNA_CompositorNodeImage; extern StructRNA RNA_CompositorNodeInvert; extern StructRNA RNA_CompositorNodeLensdist; +extern StructRNA RNA_CompositorNodeLevels; extern StructRNA RNA_CompositorNodeLumaMatte; extern StructRNA RNA_CompositorNodeMapUV; extern StructRNA RNA_CompositorNodeMapValue; @@ -174,9 +179,11 @@ extern StructRNA RNA_DistortedNoiseTexture; extern StructRNA RNA_DomainFluidSettings; extern StructRNA RNA_Driver; extern StructRNA RNA_DriverTarget; +extern StructRNA RNA_DupliObject; extern StructRNA RNA_EdgeSplitModifier; extern StructRNA RNA_EditBone; extern StructRNA RNA_EffectSequence; +extern StructRNA RNA_EffectorWeights; extern StructRNA RNA_EnumProperty; extern StructRNA RNA_EnumPropertyItem; extern StructRNA RNA_EnvironmentMap; @@ -204,6 +211,10 @@ extern StructRNA RNA_FluidSettings; extern StructRNA RNA_FluidSimulationModifier; extern StructRNA RNA_FollowPathConstraint; extern StructRNA RNA_Function; +extern StructRNA RNA_GPencilFrame; +extern StructRNA RNA_GPencilLayer; +extern StructRNA RNA_GPencilStroke; +extern StructRNA RNA_GPencilStrokePoint; extern StructRNA RNA_GameBooleanProperty; extern StructRNA RNA_GameFloatProperty; extern StructRNA RNA_GameIntProperty; @@ -214,10 +225,6 @@ extern StructRNA RNA_GameStringProperty; extern StructRNA RNA_GameTimerProperty; extern StructRNA RNA_GlowSequence; extern StructRNA RNA_GreasePencil; -extern StructRNA RNA_GPencilLayer; -extern StructRNA RNA_GPencilFrame; -extern StructRNA RNA_GPencilStroke; -extern StructRNA RNA_GPencilStrokePoint; extern StructRNA RNA_Group; extern StructRNA RNA_Header; extern StructRNA RNA_HemiLamp; @@ -225,6 +232,7 @@ extern StructRNA RNA_HookModifier; extern StructRNA RNA_ID; extern StructRNA RNA_IDProperty; extern StructRNA RNA_IDPropertyGroup; +extern StructRNA RNA_IKParam; extern StructRNA RNA_Image; extern StructRNA RNA_ImagePaint; extern StructRNA RNA_ImageSequence; @@ -232,8 +240,12 @@ extern StructRNA RNA_ImageTexture; extern StructRNA RNA_ImageUser; extern StructRNA RNA_InflowFluidSettings; extern StructRNA RNA_IntProperty; +extern StructRNA RNA_Itasc; extern StructRNA RNA_JoystickSensor; extern StructRNA RNA_Key; +extern StructRNA RNA_KeyConfig; +extern StructRNA RNA_KeyMap; +extern StructRNA RNA_KeyMapItem; extern StructRNA RNA_KeyboardSensor; extern StructRNA RNA_KeyingSet; extern StructRNA RNA_KeyingSetPath; @@ -263,6 +275,7 @@ extern StructRNA RNA_MaterialSlot; extern StructRNA RNA_MaterialStrand; extern StructRNA RNA_MaterialSubsurfaceScattering; extern StructRNA RNA_MaterialTextureSlot; +extern StructRNA RNA_MaterialVolume; extern StructRNA RNA_Menu; extern StructRNA RNA_Mesh; extern StructRNA RNA_MeshColor; @@ -313,6 +326,7 @@ extern StructRNA RNA_Paint; extern StructRNA RNA_Panel; extern StructRNA RNA_Particle; extern StructRNA RNA_ParticleBrush; +extern StructRNA RNA_ParticleDupliWeight; extern StructRNA RNA_ParticleEdit; extern StructRNA RNA_ParticleFluidSettings; extern StructRNA RNA_ParticleHairKey; @@ -327,13 +341,12 @@ extern StructRNA RNA_PluginTexture; extern StructRNA RNA_PointCache; extern StructRNA RNA_PointDensity; extern StructRNA RNA_PointDensityTexture; -extern StructRNA RNA_PointerProperty; extern StructRNA RNA_PointLamp; +extern StructRNA RNA_PointerProperty; extern StructRNA RNA_Pose; extern StructRNA RNA_PoseChannel; extern StructRNA RNA_Property; extern StructRNA RNA_PropertySensor; -extern StructRNA RNA_ArmatureSensor; extern StructRNA RNA_PythonConstraint; extern StructRNA RNA_PythonController; extern StructRNA RNA_RadarSensor; @@ -344,7 +357,6 @@ extern StructRNA RNA_RenderEngine; extern StructRNA RNA_RenderLayer; extern StructRNA RNA_RenderPass; extern StructRNA RNA_RenderResult; -extern StructRNA RNA_RenderValue; extern StructRNA RNA_RigidBodyJointConstraint; extern StructRNA RNA_Scene; extern StructRNA RNA_SceneGameData; @@ -492,12 +504,12 @@ extern StructRNA RNA_TransformSequence; extern StructRNA RNA_UILayout; extern StructRNA RNA_UIListItem; extern StructRNA RNA_UVProjectModifier; +extern StructRNA RNA_UVProjector; extern StructRNA RNA_UnitSettings; extern StructRNA RNA_UnknownType; extern StructRNA RNA_UserPreferences; extern StructRNA RNA_UserPreferencesEdit; extern StructRNA RNA_UserPreferencesFilePaths; -extern StructRNA RNA_UserPreferencesLanguage; extern StructRNA RNA_UserPreferencesSystem; extern StructRNA RNA_UserPreferencesView; extern StructRNA RNA_UserSolidLight; diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index df447894830..576f5cbb984 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -142,6 +142,9 @@ typedef enum PropertyFlag { /* icon */ PROP_ICONS_CONSECUTIVE = 4096, + /* hidden in the user interface */ + PROP_HIDDEN = 524288, + /* function paramater flags */ PROP_REQUIRED = 4, PROP_RETURN = 8, diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index da467381c06..bec2025907a 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2785,7 +2785,10 @@ int RNA_property_is_set(PointerRNA *ptr, const char *name) PropertyRNA *prop= RNA_struct_find_property(ptr, name); if(prop) { - return (rna_idproperty_find(ptr, name) != NULL); + if(prop->flag & PROP_IDPROPERTY) + return (rna_idproperty_find(ptr, name) != NULL); + else + return 1; } else { // printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index cc86da18a0b..f3fb1244565 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -667,6 +667,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * } prop= RNA_def_property(&srna->cont, "rna_type", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_HIDDEN); RNA_def_property_ui_text(prop, "RNA", "RNA type definition."); if(DefRNA.preprocess) { diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 1ebf03425d4..23592212f68 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -203,7 +203,9 @@ void rna_TextureSlot_update(struct bContext *C, struct PointerRNA *ptr); void RNA_api_action(StructRNA *srna); void RNA_api_image(struct StructRNA *srna); +void RNA_api_keyconfig(struct StructRNA *srna); void RNA_api_keyingset(struct StructRNA *srna); +void RNA_api_keymap(struct StructRNA *srna); void RNA_api_main(struct StructRNA *srna); void RNA_api_material(StructRNA *srna); void RNA_api_mesh(struct StructRNA *srna); @@ -213,7 +215,6 @@ void RNA_api_text(struct StructRNA *srna); void RNA_api_ui_layout(struct StructRNA *srna); void RNA_api_wm(struct StructRNA *srna); - /* ID Properties */ extern StringPropertyRNA rna_IDProperty_string; diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 17846651c3b..436efbcb2cf 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -37,7 +37,7 @@ #ifdef RNA_RUNTIME -static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle, int icon_only) +static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider, int toggle, int icon_only, int event, int full_event) { int flag= 0; @@ -45,6 +45,8 @@ static void rna_uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, flag |= (expand)? UI_ITEM_R_EXPAND: 0; flag |= (toggle)? UI_ITEM_R_TOGGLE: 0; flag |= (icon_only)? UI_ITEM_R_ICON_ONLY: 0; + flag |= (event)? UI_ITEM_R_EVENT: 0; + flag |= (full_event)? UI_ITEM_R_FULL_EVENT: 0; uiItemR(layout, name, icon, ptr, propname, flag); } @@ -147,6 +149,8 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "slider", 0, "", "Use slider widget for numeric values."); RNA_def_boolean(func, "toggle", 0, "", "Use toggle widget for boolean values."); RNA_def_boolean(func, "icon_only", 0, "", "Draw only icons in buttons, no text."); + RNA_def_boolean(func, "event", 0, "", "Use button to input key events."); + RNA_def_boolean(func, "full_event", 0, "", "Use button to input full events including modifiers."); func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); api_ui_item_rna_common(func); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 8f999300c71..3e3ed669e02 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1977,68 +1977,68 @@ static void rna_def_userdef_system(BlenderRNA *brna) StructRNA *srna; static EnumPropertyItem gl_texture_clamp_items[] = { - {0, "GL_CLAMP_OFF", 0, "Off", ""}, - {8192, "GL_CLAMP_8192", 0, "8192", ""}, - {4096, "GL_CLAMP_4096", 0, "4096", ""}, - {2048, "GL_CLAMP_2048", 0, "2048", ""}, - {1024, "GL_CLAMP_1024", 0, "1024", ""}, - {512, "GL_CLAMP_512", 0, "512", ""}, - {256, "GL_CLAMP_256", 0, "256", ""}, - {128, "GL_CLAMP_128", 0, "128", ""}, + {0, "CLAMP_OFF", 0, "Off", ""}, + {8192, "CLAMP_8192", 0, "8192", ""}, + {4096, "CLAMP_4096", 0, "4096", ""}, + {2048, "CLAMP_2048", 0, "2048", ""}, + {1024, "CLAMP_1024", 0, "1024", ""}, + {512, "CLAMP_512", 0, "512", ""}, + {256, "CLAMP_256", 0, "256", ""}, + {128, "CLAMP_128", 0, "128", ""}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem audio_mixing_samples_items[] = { - {256, "AUDIO_SAMPLES_256", 0, "256", "Set audio mixing buffer size to 256 samples"}, - {512, "AUDIO_SAMPLES_512", 0, "512", "Set audio mixing buffer size to 512 samples"}, - {1024, "AUDIO_SAMPLES_1024", 0, "1024", "Set audio mixing buffer size to 1024 samples"}, - {2048, "AUDIO_SAMPLES_2048", 0, "2048", "Set audio mixing buffer size to 2048 samples"}, - {4096, "AUDIO_SAMPLES_4096", 0, "4096", "Set audio mixing buffer size to 4096 samples"}, - {8192, "AUDIO_SAMPLES_8192", 0, "8192", "Set audio mixing buffer size to 8192 samples"}, - {16384, "AUDIO_SAMPLES_16384", 0, "16384", "Set audio mixing buffer size to 16384 samples"}, - {32768, "AUDIO_SAMPLES_32768", 0, "32768", "Set audio mixing buffer size to 32768 samples"}, + {256, "SAMPLES_256", 0, "256", "Set audio mixing buffer size to 256 samples"}, + {512, "SAMPLES_512", 0, "512", "Set audio mixing buffer size to 512 samples"}, + {1024, "SAMPLES_1024", 0, "1024", "Set audio mixing buffer size to 1024 samples"}, + {2048, "SAMPLES_2048", 0, "2048", "Set audio mixing buffer size to 2048 samples"}, + {4096, "SAMPLES_4096", 0, "4096", "Set audio mixing buffer size to 4096 samples"}, + {8192, "SAMPLES_8192", 0, "8192", "Set audio mixing buffer size to 8192 samples"}, + {16384, "SAMPLES_16384", 0, "16384", "Set audio mixing buffer size to 16384 samples"}, + {32768, "SAMPLES_32768", 0, "32768", "Set audio mixing buffer size to 32768 samples"}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem audio_device_items[] = { - {0, "AUDIO_DEVICE_NULL", 0, "No Audio", "Null device - there will be no audio output."}, + {0, "NONE", 0, "None", "Null device - there will be no audio output."}, #ifdef WITH_SDL - {1, "AUDIO_DEVICE_SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage."}, + {1, "SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage."}, #endif #ifdef WITH_OPENAL - {2, "AUDIO_DEVICE_OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage."}, + {2, "OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage."}, #endif #ifdef WITH_JACK - {3, "AUDIO_DEVICE_JACK", 0, "Jack", "Jack device - open source pro audio, recommended for pro audio users."}, + {3, "JACK", 0, "Jack", "Jack device - open source pro audio, recommended for pro audio users."}, #endif {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem audio_rate_items[] = { -// {8000, "AUDIO_RATE_8000", 0, "8 kHz", "Set audio sampling rate to 8000 samples per second."}, -// {11025, "AUDIO_RATE_11025", 0, "11.025 kHz", "Set audio sampling rate to 11025 samples per second."}, -// {16000, "AUDIO_RATE_16000", 0, "16 kHz", "Set audio sampling rate to 16000 samples per second."}, -// {22050, "AUDIO_RATE_22050", 0, "22.05 kHz", "Set audio sampling rate to 22050 samples per second."}, -// {32000, "AUDIO_RATE_32000", 0, "32 kHz", "Set audio sampling rate to 32000 samples per second."}, - {44100, "AUDIO_RATE_44100", 0, "44.1 kHz", "Set audio sampling rate to 44100 samples per second."}, - {48000, "AUDIO_RATE_48000", 0, "48 kHz", "Set audio sampling rate to 48000 samples per second."}, -// {88200, "AUDIO_RATE_88200", 0, "88.2 kHz", "Set audio sampling rate to 88200 samples per second."}, - {96000, "AUDIO_RATE_96000", 0, "96 kHz", "Set audio sampling rate to 96000 samples per second."}, - {192000, "AUDIO_RATE_192000", 0, "192 kHz", "Set audio sampling rate to 192000 samples per second."}, +// {8000, "RATE_8000", 0, "8 kHz", "Set audio sampling rate to 8000 samples per second."}, +// {11025, "RATE_11025", 0, "11.025 kHz", "Set audio sampling rate to 11025 samples per second."}, +// {16000, "RATE_16000", 0, "16 kHz", "Set audio sampling rate to 16000 samples per second."}, +// {22050, "RATE_22050", 0, "22.05 kHz", "Set audio sampling rate to 22050 samples per second."}, +// {32000, "RATE_32000", 0, "32 kHz", "Set audio sampling rate to 32000 samples per second."}, + {44100, "RATE_44100", 0, "44.1 kHz", "Set audio sampling rate to 44100 samples per second."}, + {48000, "RATE_48000", 0, "48 kHz", "Set audio sampling rate to 48000 samples per second."}, +// {88200, "RATE_88200", 0, "88.2 kHz", "Set audio sampling rate to 88200 samples per second."}, + {96000, "RATE_96000", 0, "96 kHz", "Set audio sampling rate to 96000 samples per second."}, + {192000, "RATE_192000", 0, "192 kHz", "Set audio sampling rate to 192000 samples per second."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem audio_format_items[] = { - {0x01, "AUDIO_FORMAT_U8", 0, "8-bit Unsigned", "Set audio sample format to 8 bit unsigned integer."}, - {0x12, "AUDIO_FORMAT_S16", 0, "16-bit Signed", "Set audio sample format to 16 bit signed integer."}, - {0x13, "AUDIO_FORMAT_S24", 0, "24-bit Signed", "Set audio sample format to 24 bit signed integer."}, - {0x14, "AUDIO_FORMAT_S32", 0, "32-bit Signed", "Set audio sample format to 32 bit signed integer."}, - {0x24, "AUDIO_FORMAT_FLOAT", 0, "32-bit Float", "Set audio sample format to 32 bit float."}, - {0x28, "AUDIO_FORMAT_DOUBLE", 0, "64-bit Float", "Set audio sample format to 64 bit float."}, + {0x01, "U8", 0, "8-bit Unsigned", "Set audio sample format to 8 bit unsigned integer."}, + {0x12, "S16", 0, "16-bit Signed", "Set audio sample format to 16 bit signed integer."}, + {0x13, "S24", 0, "24-bit Signed", "Set audio sample format to 24 bit signed integer."}, + {0x14, "S32", 0, "32-bit Signed", "Set audio sample format to 32 bit signed integer."}, + {0x24, "FLOAT", 0, "32-bit Float", "Set audio sample format to 32 bit float."}, + {0x28, "DOUBLE", 0, "64-bit Float", "Set audio sample format to 64 bit float."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem audio_channel_items[] = { - {1, "AUDIO_CHANNELS_MONO", 0, "Mono", "Set audio channels to mono."}, - {2, "AUDIO_CHANNELS_STEREO", 0, "Stereo", "Set audio channels to stereo."}, - {4, "AUDIO_CHANNELS_SURROUND4", 0, "4 Channels", "Set audio channels to 4 channels."}, - {6, "AUDIO_CHANNELS_SURROUND51", 0, "5.1 Surround", "Set audio channels to 5.1 surround sound."}, - {8, "AUDIO_CHANNELS_SURROUND71", 0, "7.1 Surround", "Set audio channels to 7.1 surround sound."}, + {1, "MONO", 0, "Mono", "Set audio channels to mono."}, + {2, "STEREO", 0, "Stereo", "Set audio channels to stereo."}, + {4, "SURROUND4", 0, "4 Channels", "Set audio channels to 4 channels."}, + {6, "SURROUND51", 0, "5.1 Surround", "Set audio channels to 5.1 surround sound."}, + {8, "SURROUND71", 0, "7.1 Surround", "Set audio channels to 7.1 surround sound."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem draw_method_items[] = { @@ -2340,11 +2340,12 @@ void RNA_def_userdef(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem user_pref_sections[] = { - {0, "VIEW_CONTROLS", 0, "View", ""}, - {1, "EDIT_METHODS", 0, "Editing", ""}, - {2, "FILE_PATHS", 0, "File", ""}, - {3, "SYSTEM_OPENGL", 0, "System", ""}, -// {4, "THEMES", 0, "Themes", ""}, // Leave this out until we figure out a way to manage themes in the prefs. + {USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""}, + {USER_SECTION_EDIT, "EDITING", 0, "Editing", ""}, + {USER_SECTION_INPUT, "INPUT", 0, "Input", ""}, +// {USER_SECTION_THEME, "THEMES", 0, "Themes", ""}, // Leave this out until we figure out a way to manage themes in the prefs. + {USER_SECTION_FILE, "FILES", 0, "File", ""}, + {USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""}, {0, NULL, 0, NULL, NULL}}; rna_def_userdef_dothemes(brna); @@ -2358,6 +2359,7 @@ void RNA_def_userdef(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "userpref"); RNA_def_property_enum_items(prop, user_pref_sections); RNA_def_property_ui_text(prop, "Active Section", "Active section of the user preferences shown in the user interface."); + RNA_def_property_update(prop, 0, "rna_userdef_update"); prop= RNA_def_property(srna, "themes", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "themes", NULL); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 0dd9e3aed42..82b244fa702 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -24,14 +24,37 @@ #include +#include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "RNA_types.h" #include "rna_internal.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" -#include "WM_types.h" /* wmEvent */ +#include "WM_types.h" + +EnumPropertyItem event_keymouse_value_items[] = { + {KM_ANY, "ANY", 0, "Any", ""}, + {KM_PRESS, "PRESS", 0, "Press", ""}, + {KM_RELEASE, "RELEASE", 0, "Release", ""}, + {0, NULL, 0, NULL, NULL}}; + +EnumPropertyItem event_tweak_value_items[]= { + {KM_ANY, "ANY", 0, "Any", ""}, + {EVT_GESTURE_N, "NORTH", 0, "North", ""}, + {EVT_GESTURE_NE, "NORTH_EAST", 0, "North-East", ""}, + {EVT_GESTURE_E, "EAST", 0, "East", ""}, + {EVT_GESTURE_SE, "SOUTH_EAST", 0, "South-East", ""}, + {EVT_GESTURE_S, "SOUTH", 0, "South", ""}, + {EVT_GESTURE_SW, "SOUTH_WEST", 0, "South-West", ""}, + {EVT_GESTURE_W, "WEST", 0, "West", ""}, + {EVT_GESTURE_NW, "NORTH_WEST", 0, "North-West", ""}, + {0, NULL, 0, NULL, NULL}}; EnumPropertyItem event_value_items[] = { {KM_ANY, "ANY", 0, "Any", ""}, @@ -40,9 +63,43 @@ EnumPropertyItem event_value_items[] = { {KM_RELEASE, "RELEASE", 0, "Release", ""}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem event_tweak_type_items[]= { + {EVT_TWEAK_L, "EVT_TWEAK_L", 0, "Left", ""}, + {EVT_TWEAK_M, "EVT_TWEAK_M", 0, "Middle", ""}, + {EVT_TWEAK_R, "EVT_TWEAK_R", 0, "Right", ""}, + {EVT_TWEAK_A, "EVT_TWEAK_A", 0, "Action", ""}, + {EVT_TWEAK_S, "EVT_TWEAK_S", 0, "Select", ""}, + {0, NULL, 0, NULL, NULL}}; + +EnumPropertyItem event_mouse_type_items[]= { + {LEFTMOUSE, "LEFTMOUSE", 0, "Left", ""}, + {MIDDLEMOUSE, "MIDDLEMOUSE", 0, "Middle", ""}, + {RIGHTMOUSE, "RIGHTMOUSE", 0, "Right", ""}, + {BUTTON4MOUSE, "BUTTON4MOUSE", 0, "Button4", ""}, + {BUTTON5MOUSE, "BUTTON5MOUSE", 0, "Button5", ""}, + {ACTIONMOUSE, "ACTIONMOUSE", 0, "Action", ""}, + {SELECTMOUSE, "SELECTMOUSE", 0, "Select", ""}, + {0, "", 0, NULL, NULL}, + {MOUSEMOVE, "MOUSEMOVE", 0, "Move", ""}, + {0, "", 0, NULL, NULL}, + {WHEELUPMOUSE, "WHEELUPMOUSE", 0, "Wheel Up", ""}, + {WHEELDOWNMOUSE, "WHEELDOWNMOUSE", 0, "Wheel Down", ""}, + {WHEELINMOUSE, "WHEELINMOUSE", 0, "Wheel In", ""}, + {WHEELOUTMOUSE, "WHEELOUTMOUSE", 0, "Wheel Out", ""}, + {0, NULL, 0, NULL, NULL}}; + +EnumPropertyItem event_timer_type_items[]= { + {TIMER, "TIMER", 0, "Timer", ""}, + {TIMER0, "TIMER0", 0, "Timer 0", ""}, + {TIMER1, "TIMER1", 0, "Timer 1", ""}, + {TIMER2, "TIMER2", 0, "Timer 2", ""}, + {TIMERJOBS, "JOBS_TIMER", 0, "Jobs Timer", ""}, + {0, NULL, 0, NULL, NULL}}; + /* not returned: CAPSLOCKKEY, UNKNOWNKEY, GRLESSKEY */ EnumPropertyItem event_type_items[] = { + {0, "NONE", 0, "", ""}, {LEFTMOUSE, "LEFTMOUSE", 0, "Left Mouse", ""}, {MIDDLEMOUSE, "MIDDLEMOUSE", 0, "Middle Mouse", ""}, {RIGHTMOUSE, "RIGHTMOUSE", 0, "Right Mouse", ""}, @@ -50,20 +107,20 @@ EnumPropertyItem event_type_items[] = { {BUTTON5MOUSE, "BUTTON5MOUSE", 0, "Button5 Mouse", ""}, {ACTIONMOUSE, "ACTIONMOUSE", 0, "Action Mouse", ""}, {SELECTMOUSE, "SELECTMOUSE", 0, "Select Mouse", ""}, - + {0, "", 0, NULL, NULL}, {MOUSEMOVE, "MOUSEMOVE", 0, "Mouse Move", ""}, - + {0, "", 0, NULL, NULL}, {WHEELUPMOUSE, "WHEELUPMOUSE", 0, "Wheel Up", ""}, {WHEELDOWNMOUSE, "WHEELDOWNMOUSE", 0, "Wheel Down", ""}, {WHEELINMOUSE, "WHEELINMOUSE", 0, "Wheel In", ""}, {WHEELOUTMOUSE, "WHEELOUTMOUSE", 0, "Wheel Out", ""}, - + {0, "", 0, NULL, NULL}, {EVT_TWEAK_L, "EVT_TWEAK_L", 0, "Tweak Left", ""}, {EVT_TWEAK_M, "EVT_TWEAK_M", 0, "Tweak Middle", ""}, {EVT_TWEAK_R, "EVT_TWEAK_R", 0, "Tweak Right", ""}, {EVT_TWEAK_A, "EVT_TWEAK_A", 0, "Tweak Action", ""}, {EVT_TWEAK_S, "EVT_TWEAK_S", 0, "Tweak Select", ""}, - + {0, "", 0, NULL, NULL}, {AKEY, "A", 0, "A", ""}, {BKEY, "B", 0, "B", ""}, {CKEY, "C", 0, "C", ""}, @@ -90,7 +147,7 @@ EnumPropertyItem event_type_items[] = { {XKEY, "X", 0, "X", ""}, {YKEY, "Y", 0, "Y", ""}, {ZKEY, "Z", 0, "Z", ""}, - + {0, "", 0, NULL, NULL}, {ZEROKEY, "ZERO", 0, "0", ""}, {ONEKEY, "ONE", 0, "1", ""}, {TWOKEY, "TWO", 0, "2", ""}, @@ -101,16 +158,16 @@ EnumPropertyItem event_type_items[] = { {SEVENKEY, "SEVEN", 0, "7", ""}, {EIGHTKEY, "EIGHT", 0, "8", ""}, {NINEKEY, "NINE", 0, "9", ""}, - + {0, "", 0, NULL, NULL}, {LEFTCTRLKEY, "LEFT_CTRL", 0, "Left Ctrl", ""}, {LEFTALTKEY, "LEFT_ALT", 0, "Left Alt", ""}, {LEFTSHIFTKEY, "LEFT_SHIFT", 0, "Left Shift", ""}, {RIGHTALTKEY, "RIGHT_ALT", 0, "Right Alt", ""}, {RIGHTCTRLKEY, "RIGHT_CTRL", 0, "Right Ctrl", ""}, {RIGHTSHIFTKEY, "RIGHT_SHIFT", 0, "Right Shift", ""}, - + {0, "", 0, NULL, NULL}, {COMMANDKEY, "COMMAND", 0, "Command", ""}, - + {0, "", 0, NULL, NULL}, {ESCKEY, "ESC", 0, "Esc", ""}, {TABKEY, "TAB", 0, "Tab", ""}, {RETKEY, "RET", 0, "Return", ""}, @@ -167,8 +224,20 @@ EnumPropertyItem event_type_items[] = { {PAGEUPKEY, "PAGE_UP", 0, "Page Up", ""}, {PAGEDOWNKEY, "PAGE_DOWN", 0, "Page Down", ""}, {ENDKEY, "END", 0, "End", ""}, + {0, "", 0, NULL, NULL}, + {TIMER, "TIMER", 0, "Timer", ""}, + {TIMER0, "TIMER0", 0, "Timer 0", ""}, + {TIMER1, "TIMER1", 0, "Timer 1", ""}, + {TIMER2, "TIMER2", 0, "Timer 2", ""}, + {TIMERJOBS, "JOBS_TIMER", 0, "Jobs Timer", ""}, {0, NULL, 0, NULL, NULL}}; +#define KMI_TYPE_KEYBOARD 0 +#define KMI_TYPE_MOUSE 1 +#define KMI_TYPE_TWEAK 2 +#define KMI_TYPE_TEXTINPUT 3 +#define KMI_TYPE_TIMER 4 + #ifdef RNA_RUNTIME #include "WM_api.h" @@ -263,6 +332,156 @@ static void rna_Window_screen_update(bContext *C, PointerRNA *ptr) } } +static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr) +{ + wmKeyMapItem *kmi= ptr->data; + + if(kmi->ptr) + return *(kmi->ptr); + + //return rna_pointer_inherit_refine(ptr, &RNA_OperatorProperties, op->properties); + return PointerRNA_NULL; +} + +static int rna_wmKeyMapItem_map_type_get(PointerRNA *ptr) +{ + wmKeyMapItem *kmi= ptr->data; + + if(ISTIMER(kmi->type)) return KMI_TYPE_TIMER; + if(ISKEYBOARD(kmi->type)) return KMI_TYPE_KEYBOARD; + if(ISTWEAK(kmi->type)) return KMI_TYPE_TWEAK; + if(ISMOUSE(kmi->type)) return KMI_TYPE_MOUSE; + if(kmi->type == KM_TEXTINPUT) return KMI_TYPE_TEXTINPUT; + return KMI_TYPE_KEYBOARD; +} + +static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value) +{ + wmKeyMapItem *kmi= ptr->data; + int map_type= rna_wmKeyMapItem_map_type_get(ptr); + + if(value != map_type) { + switch(value) { + case KMI_TYPE_KEYBOARD: + kmi->type= AKEY; + kmi->val= KM_PRESS; + break; + case KMI_TYPE_TWEAK: + kmi->type= EVT_TWEAK_L; + kmi->val= KM_ANY; + break; + case KMI_TYPE_MOUSE: + kmi->type= LEFTMOUSE; + kmi->val= KM_PRESS; + break; + case KMI_TYPE_TEXTINPUT: + kmi->type= KM_TEXTINPUT; + kmi->val= KM_NOTHING; + break; + case KMI_TYPE_TIMER: + kmi->type= TIMER; + kmi->val= KM_NOTHING; + break; + } + } +} + +static EnumPropertyItem *rna_KeyMapItem_type_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + int map_type= rna_wmKeyMapItem_map_type_get(ptr); + + if(map_type == KMI_TYPE_MOUSE) return event_mouse_type_items; + if(map_type == KMI_TYPE_TWEAK) return event_tweak_type_items; + if(map_type == KMI_TYPE_TIMER) return event_timer_type_items; + else return event_type_items; +} + +static EnumPropertyItem *rna_KeyMapItem_value_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + int map_type= rna_wmKeyMapItem_map_type_get(ptr); + + if(map_type == KMI_TYPE_MOUSE || map_type == KMI_TYPE_KEYBOARD) return event_keymouse_value_items; + if(map_type == KMI_TYPE_TWEAK) return event_tweak_value_items; + else return event_value_items; +} + +static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr) +{ + wmWindowManager *wm= ptr->data; + wmKeyConfig *kc; + + for(kc=wm->keyconfigs.first; kc; kc=kc->next) + if(strcmp(kc->idname, U.keyconfigstr) == 0) + break; + + if(!kc) + kc= wm->defaultconf; + + return rna_pointer_inherit_refine(ptr, &RNA_KeyConfig, kc); +} + +static void rna_WindowManager_active_keyconfig_set(PointerRNA *ptr, PointerRNA value) +{ + wmKeyConfig *kc= value.data; + + if(kc) + BLI_strncpy(U.keyconfigstr, kc->idname, sizeof(U.keyconfigstr)); +} + +static PointerRNA rna_WindowManager_active_keymap_get(PointerRNA *ptr) +{ + wmWindowManager *wm= ptr->data; + wmKeyMap *km= NULL; + + if(wm->defaultconf) { + km= BLI_findlink(&wm->defaultconf->keymaps, wm->defaultactmap); + + if(!km) + km= wm->defaultconf->keymaps.first; + } + + return rna_pointer_inherit_refine(ptr, &RNA_KeyMap, WM_keymap_active(wm, km)); +} + +static void rna_WindowManager_active_keymap_set(PointerRNA *ptr, PointerRNA value) +{ + wmWindowManager *wm= ptr->data; + wmKeyMap *km= value.data; + int index; + + if(wm->defaultconf && km) { + km= WM_keymap_find(wm->defaultconf, km->idname, km->spaceid, km->regionid); + index= BLI_findindex(&wm->defaultconf->keymaps, km); + + if(index != -1) wm->defaultactmap= index; + else wm->defaultactmap= 0; + } +} + +static void rna_wmKeyMapItem_idname_get(PointerRNA *ptr, char *value) +{ + wmKeyMapItem *kmi= ptr->data; + WM_operator_py_idname(value, kmi->idname); +} + +static int rna_wmKeyMapItem_idname_length(PointerRNA *ptr) +{ + wmKeyMapItem *kmi= ptr->data; + char pyname[OP_MAX_TYPENAME]; + + WM_operator_py_idname(pyname, kmi->idname); + return strlen(pyname); +} + +static void rna_wmKeyMapItem_idname_set(PointerRNA *ptr, const char *value) +{ + wmKeyMapItem *kmi= ptr->data; + char idname[OP_MAX_TYPENAME]; + + WM_operator_bl_idname(idname, value); + BLI_strncpy(kmi->idname, idname, sizeof(kmi->idname)); +} + #else static void rna_def_operator(BlenderRNA *brna) @@ -434,9 +653,154 @@ static void rna_def_windowmanager(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Window"); RNA_def_property_ui_text(prop, "Windows", "Open windows."); + prop= RNA_def_property(srna, "keyconfigs", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_ui_text(prop, "Key Configurations", "Registered key configurations."); + + prop= RNA_def_property(srna, "active_keyconfig", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, "rna_WindowManager_active_keyconfig_get", "rna_WindowManager_active_keyconfig_set", 0); + RNA_def_property_ui_text(prop, "Active Key Configuration", ""); + + prop= RNA_def_property(srna, "default_keyconfig", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "defaultconf"); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_ui_text(prop, "Default Key Configuration", ""); + + prop= RNA_def_property(srna, "active_keymap", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "KeyMap"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, "rna_WindowManager_active_keymap_get", "rna_WindowManager_active_keymap_set", 0); + RNA_def_property_ui_text(prop, "Active Key Map", ""); + RNA_api_wm(srna); } +static void rna_def_keyconfig(BlenderRNA *brna) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *prop, *parm; + + static EnumPropertyItem map_type_items[] = { + {KMI_TYPE_KEYBOARD, "KEYBOARD", 0, "Keyboard", ""}, + {KMI_TYPE_TWEAK, "TWEAK", 0, "Tweak", ""}, + {KMI_TYPE_MOUSE, "MOUSE", 0, "Mouse", ""}, + {KMI_TYPE_TEXTINPUT, "TEXTINPUT", 0, "Text Input", ""}, + {KMI_TYPE_TIMER, "TIMER", 0, "Timer", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* KeyConfig */ + srna= RNA_def_struct(brna, "KeyConfig", NULL); + RNA_def_struct_sdna(srna, "wmKeyConfig"); + RNA_def_struct_ui_text(srna, "Key Configuration", "Input configuration, including keymaps."); + + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "idname"); + RNA_def_property_ui_text(prop, "Name", "Name of the key configuration."); + RNA_def_struct_name_property(srna, prop); + + prop= RNA_def_property(srna, "keymaps", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "KeyMap"); + RNA_def_property_ui_text(prop, "Key Maps", "Key maps configured as part of this configuration."); + + RNA_api_keyconfig(srna); + + /* KeyMap */ + srna= RNA_def_struct(brna, "KeyMap", NULL); + RNA_def_struct_sdna(srna, "wmKeyMap"); + RNA_def_struct_ui_text(srna, "Key Map", "Input configuration, including keymaps."); + + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "idname"); + RNA_def_property_ui_text(prop, "Name", "Name of the key map."); + RNA_def_struct_name_property(srna, prop); + + prop= RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "spaceid"); + RNA_def_property_enum_items(prop, space_type_items); + RNA_def_property_ui_text(prop, "Space Type", "Optional space type keymap is associated with."); + + prop= RNA_def_property(srna, "region_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "regionid"); + RNA_def_property_enum_items(prop, region_type_items); + RNA_def_property_ui_text(prop, "Region Type", "Optional region type keymap is associated with."); + + prop= RNA_def_property(srna, "items", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "KeyMapItem"); + RNA_def_property_ui_text(prop, "Items", "Items in the keymap, linking an operator to an input event."); + + prop= RNA_def_property(srna, "user_defined", PROP_BOOLEAN, PROP_NEVER_NULL); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER); + RNA_def_property_ui_text(prop, "User Defined", "Keymap is defined by the user."); + + RNA_api_keymap(srna); + + /* KeyMapItem */ + srna= RNA_def_struct(brna, "KeyMapItem", NULL); + RNA_def_struct_sdna(srna, "wmKeyMapItem"); + RNA_def_struct_ui_text(srna, "Key Map Item", "Item in a Key Map."); + + prop= RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "idname"); + RNA_def_property_ui_text(prop, "Identifier", "Identifier of operator to call on input event."); + RNA_def_property_string_funcs(prop, "rna_wmKeyMapItem_idname_get", "rna_wmKeyMapItem_idname_length", "rna_wmKeyMapItem_idname_set"); + RNA_def_struct_name_property(srna, prop); + + prop= RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "OperatorProperties"); + RNA_def_property_pointer_funcs(prop, "rna_KeyMapItem_properties_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Properties", "Properties to set when the operator is called."); + + prop= RNA_def_property(srna, "map_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "maptype"); + RNA_def_property_enum_items(prop, map_type_items); + RNA_def_property_enum_funcs(prop, "rna_wmKeyMapItem_map_type_get", "rna_wmKeyMapItem_map_type_set", NULL); + RNA_def_property_ui_text(prop, "Map Type", "Type of event mapping."); + + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, event_type_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_type_itemf"); + RNA_def_property_ui_text(prop, "Type", "Type of event."); + + prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "val"); + RNA_def_property_enum_items(prop, event_value_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_value_itemf"); + RNA_def_property_ui_text(prop, "Value", ""); + + prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "shift", 0); + RNA_def_property_ui_text(prop, "Shift", "Shift key pressed."); + + prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 0); + RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed."); + + prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "alt", 0); + RNA_def_property_ui_text(prop, "Alt", "Alt key pressed."); + + prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "oskey", 0); + RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed."); + + prop= RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "keymodifier"); + RNA_def_property_enum_items(prop, event_type_items); + RNA_def_property_ui_text(prop, "Key Modifier", "Regular key pressed as a modifier."); + + prop= RNA_def_property(srna, "expanded", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_EXPANDED); + RNA_def_property_ui_text(prop, "Expanded", "Expanded in the user interface."); + + prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", KMI_INACTIVE); + RNA_def_property_ui_text(prop, "Active", "Activate or deactivate item."); +} + void RNA_def_wm(BlenderRNA *brna) { rna_def_operator(brna); @@ -445,6 +809,7 @@ void RNA_def_wm(BlenderRNA *brna) rna_def_event(brna); rna_def_window(brna); rna_def_windowmanager(brna); + rna_def_keyconfig(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index fd34d7c4d70..44c6967189d 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -31,25 +31,93 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" + +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #ifdef RNA_RUNTIME #include "BKE_context.h" #include "WM_api.h" +#include "WM_types.h" + +static wmKeyMapItem *rna_KeyMap_add_item(wmKeyMap *km, char *idname, int type, int value, int shift, int ctrl, int alt, int oskey, int keymodifier) +{ + int modifier= 0; + + if(shift) modifier |= KM_SHIFT; + if(ctrl) modifier |= KM_CTRL; + if(alt) modifier |= KM_ALT; + if(oskey) modifier |= KM_OSKEY; + + return WM_keymap_add_item(km, idname, type, value, modifier, keymodifier); +} #else void RNA_api_wm(StructRNA *srna) { FunctionRNA *func; - PropertyRNA *prop; + PropertyRNA *parm; func= RNA_def_function(srna, "add_fileselect", "WM_event_add_fileselect"); RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_USE_CONTEXT); RNA_def_function_ui_description(func, "Show up the file selector."); - prop= RNA_def_pointer(func, "operator", "Operator", "", "Operator to call."); - RNA_def_property_flag(prop, PROP_REQUIRED); + parm= RNA_def_pointer(func, "operator", "Operator", "", "Operator to call."); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "add_keyconfig", "WM_keyconfig_add"); + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration."); + RNA_def_function_return(func, parm); +} + +void RNA_api_keyconfig(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "add_keymap", "WM_keymap_find"); + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); + RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map."); + RNA_def_function_return(func, parm); +} + +void RNA_api_keymap(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "add_item", "rna_KeyMap_add_item"); + parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "shift", 0, "Shift", ""); + RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); + RNA_def_boolean(func, "alt", 0, "Alt", ""); + RNA_def_boolean(func, "oskey", 0, "OS Key", ""); + RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "remove_item", "WM_keymap_remove_item"); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "copy_to_user", "WM_keymap_copy_to_user"); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "User editable key map."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default"); } #endif diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 42b905dc0d8..44b419e8ae9 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -433,7 +433,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) { PointerRNA newptr; newptr= RNA_property_pointer_get(ptr, prop); - if (newptr.data) { + if (newptr.type) { ret = pyrna_struct_CreatePyObject(&newptr); } else { ret = Py_None; @@ -1153,6 +1153,31 @@ static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA * self, PyObject *ar return PyBool_FromLong( insert_keyframe((ID *)self->ptr.data, NULL, NULL, path, index, cfra, 0)); } +static PyObject *pyrna_struct_is_property_set(BPy_StructRNA * self, PyObject *args) +{ + char *name; + + if (!PyArg_ParseTuple(args, "s:is_property_set", &name)) + return NULL; + + return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); +} + +static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA * self, PyObject *args) +{ + PropertyRNA *prop; + char *name; + int hidden; + + if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) + return NULL; + + prop= RNA_struct_find_property(&self->ptr, name); + hidden= (prop)? (RNA_property_flag(prop) & PROP_HIDDEN): 1; + + return PyBool_FromLong(hidden); +} + static PyObject *pyrna_struct_dir(BPy_StructRNA * self) { @@ -1272,7 +1297,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) CTX_data_get(self->ptr.data, name, &newptr, &newlb); - if (newptr.data) { + if (newptr.type) { ret = pyrna_struct_CreatePyObject(&newptr); } else if (newlb.first) { @@ -1745,6 +1770,8 @@ static struct PyMethodDef pyrna_struct_methods[] = { /* maybe this become and ID function */ {"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, NULL}, + {"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, NULL}, + {"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL}, {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 0054f151803..b29dbec6364 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -82,22 +82,30 @@ void WM_timecursor (struct wmWindow *win, int nr); void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata); void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle); - /* keymap */ + /* keyconfig and keymap */ +wmKeyConfig *WM_keyconfig_add (struct wmWindowManager *wm, char *idname); +void WM_keyconfig_free (struct wmKeyConfig *keyconf); +void WM_keyconfig_userdef(struct wmWindowManager *wm); + void WM_keymap_init (struct bContext *C); -wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, - short val, int modifier, short keymodifier); -wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, - short val, int modifier, short keymodifier); -void WM_keymap_tweak (wmKeyMap *keymap, short type, short val, int modifier, short keymodifier); -wmKeyMap *WM_keymap_find (struct wmWindowManager *wm, const char *nameid, - short spaceid, short regionid); - -wmKeyMap *WM_modalkeymap_add(struct wmWindowManager *wm, const char *nameid, struct EnumPropertyItem *items); -wmKeyMap *WM_modalkeymap_get(struct wmWindowManager *wm, const char *nameid); -void WM_modalkeymap_add_item(wmKeyMap *km, short type, short val, int modifier, short keymodifier, short value); -void WM_modalkeymap_assign(wmKeyMap *km, const char *opname); - -int WM_key_event_is_tweak(short type); +void WM_keymap_free (struct wmKeyMap *keymap); + +wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, char *idname, int type, + int val, int modifier, int keymodifier); +wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, char *idname, int type, + int val, int modifier, int keymodifier); +void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); +char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); + +wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap); +wmKeyMap *WM_keymap_copy_to_user(struct wmKeyMap *keymap); +void WM_keymap_restore_to_default(struct wmKeyMap *keymap); + +wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, char *idname, struct EnumPropertyItem *items); +wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, char *idname); +void WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); +void WM_modalkeymap_assign(struct wmKeyMap *km, char *opname); const char *WM_key_event_string(short type); char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 4405b52888d..a068f84ae29 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -132,12 +132,18 @@ void WM_keymap_init(bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); + if(!wm->defaultconf) + wm->defaultconf= WM_keyconfig_add(wm, "Blender"); + if(wm && CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) { - wm_window_keymap(wm); - ED_spacetypes_keymap(wm); + /* create default key config */ + wm_window_keymap(wm->defaultconf); + ED_spacetypes_keymap(wm->defaultconf); wm->initialized |= WM_INIT_KEYMAP; } + + WM_keyconfig_userdef(wm); } void wm_check(bContext *C) @@ -151,15 +157,16 @@ void wm_check(bContext *C) } if(wm==NULL) return; if(wm->windows.first==NULL) return; + + /* case: fileread */ + if((wm->initialized & WM_INIT_WINDOW) == 0) + WM_keymap_init(C); /* case: no open windows at all, for old file reads */ wm_window_add_ghostwindows(wm); /* case: fileread */ if((wm->initialized & WM_INIT_WINDOW) == 0) { - - WM_keymap_init(C); - ED_screens_initialize(wm); wm->initialized |= WM_INIT_WINDOW; } @@ -211,8 +218,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) { wmWindow *win; wmOperator *op; - wmKeyMap *km; - wmKeymapItem *kmi; + wmKeyConfig *keyconf; while((win= wm->windows.first)) { BLI_remlink(&wm->windows, win); @@ -226,19 +232,11 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) WM_operator_free(op); } - while((km= wm->keymaps.first)) { - for(kmi=km->keymap.first; kmi; kmi=kmi->next) { - if(kmi->ptr) { - WM_operator_properties_free(kmi->ptr); - MEM_freeN(kmi->ptr); - } - } - - BLI_freelistN(&km->keymap); - BLI_remlink(&wm->keymaps, km); - MEM_freeN(km); + while((keyconf=wm->keyconfigs.first)) { + BLI_remlink(&wm->keyconfigs, keyconf); + WM_keyconfig_free(keyconf); } - + BLI_freelistN(&wm->queue); BLI_freelistN(&wm->paintcursors); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 4a8aac4525d..ea73ed38123 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -725,16 +725,16 @@ static int wm_userdef_event_map(int kmitype) return kmitype; } -static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) +static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi) { int kmitype= wm_userdef_event_map(kmi->type); - if(kmi->inactive) return 0; + if(kmi->flag & KMI_INACTIVE) return 0; /* exception for middlemouse emulation */ if((U.flag & USER_TWOBUTTONMOUSE) && (kmi->type == MIDDLEMOUSE)) { if(winevent->type == LEFTMOUSE && winevent->alt) { - wmKeymapItem tmp= *kmi; + wmKeyMapItem tmp= *kmi; tmp.type= winevent->type; tmp.alt= winevent->alt; @@ -784,9 +784,9 @@ static int wm_event_always_pass(wmEvent *event) static void wm_event_modalkeymap(wmOperator *op, wmEvent *event) { if(op->type->modalkeymap) { - wmKeymapItem *kmi; + wmKeyMapItem *kmi; - for(kmi= op->type->modalkeymap->keymap.first; kmi; kmi= kmi->next) { + for(kmi= op->type->modalkeymap->items.first; kmi; kmi= kmi->next) { if(wm_eventmatch(event, kmi)) { event->type= EVT_MODAL_MAP; @@ -1031,6 +1031,7 @@ static int handler_boundbox_test(wmEventHandler *handler, wmEvent *event) static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { + wmWindowManager *wm= CTX_wm_manager(C); wmEventHandler *handler, *nexthandler; int action= WM_HANDLER_CONTINUE; int always_pass; @@ -1051,11 +1052,11 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= WM_HANDLER_BREAK; if(handler->keymap) { - wmKeyMap *keymap= handler->keymap; - wmKeymapItem *kmi; + wmKeyMap *keymap= WM_keymap_active(wm, handler->keymap); + wmKeyMapItem *kmi; if(!keymap->poll || keymap->poll(C)) { - for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) { + for(kmi= keymap->items.first; kmi; kmi= kmi->next) { if(wm_eventmatch(event, kmi)) { event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 7d25fb8172e..3d3a6e46fb2 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -29,6 +29,7 @@ #include #include "DNA_screen_types.h" +#include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" #include "MEM_guardedalloc.h" @@ -52,9 +53,86 @@ #include "wm_event_system.h" #include "wm_event_types.h" +/* ********************* key config ***********************/ + +static void keymap_properties_set(wmKeyMapItem *kmi) +{ + if(!kmi->properties) { + IDPropertyTemplate val = {0}; + kmi->properties= IDP_New(IDP_GROUP, val, "wmKeyMapItemProperties"); + } + + if(!kmi->ptr) { + kmi->ptr= MEM_callocN(sizeof(PointerRNA), "wmKeyMapItemPtr"); + WM_operator_properties_create(kmi->ptr, kmi->idname); + } + + kmi->ptr->data= kmi->properties; +} + +wmKeyConfig *WM_keyconfig_add(wmWindowManager *wm, char *idname) +{ + wmKeyConfig *keyconf; + + keyconf= MEM_callocN(sizeof(wmKeyConfig), "wmKeyConfig"); + BLI_strncpy(keyconf->idname, idname, sizeof(keyconf->idname)); + BLI_addtail(&wm->keyconfigs, keyconf); + + return keyconf; +} + +void WM_keyconfig_free(wmKeyConfig *keyconf) +{ + wmKeyMap *km; + + while((km= keyconf->keymaps.first)) { + WM_keymap_free(km); + BLI_freelinkN(&keyconf->keymaps, km); + } + + MEM_freeN(keyconf); +} + +void WM_keyconfig_userdef(wmWindowManager *wm) +{ + wmKeyMap *km; + wmKeyMapItem *kmi; + + for(km=U.keymaps.first; km; km=km->next) + for(kmi=km->items.first; kmi; kmi=kmi->next) + keymap_properties_set(kmi); +} + +static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname) +{ + wmKeyConfig *kc; + + for(kc= lb->first; kc; kc= kc->next) + if(0==strncmp(idname, kc->idname, KMAP_MAX_NAME)) + return kc; + + return NULL; +} + +/* ************************ free ************************* */ + +void WM_keymap_free(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) { + if(kmi->ptr) { + WM_operator_properties_free(kmi->ptr); + MEM_freeN(kmi->ptr); + } + } + + BLI_freelistN(&keymap->items); +} + /* ***************** generic call, exported **************** */ -static void keymap_event_set(wmKeymapItem *kmi, short type, short val, int modifier, short keymodifier) +static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier) { kmi->type= type; kmi->val= val; @@ -87,26 +165,18 @@ static void keymap_event_set(wmKeymapItem *kmi, short type, short val, int modif } } -static void keymap_properties_set(wmKeymapItem *kmi) -{ - if(!kmi->ptr) { - kmi->ptr= MEM_callocN(sizeof(PointerRNA), "wmKeymapItemPtr"); - WM_operator_properties_create(kmi->ptr, kmi->idname); - } -} - /* if item was added, then bail out */ -wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier) +wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, int type, int val, int modifier, int keymodifier) { - wmKeymapItem *kmi; + wmKeyMapItem *kmi; - for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) + for(kmi= keymap->items.first; kmi; kmi= kmi->next) if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0) break; if(kmi==NULL) { - kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + kmi= MEM_callocN(sizeof(wmKeyMapItem), "keymap entry"); - BLI_addtail(&keymap->keymap, kmi); + BLI_addtail(&keymap->items, kmi); BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); @@ -116,11 +186,11 @@ wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, } /* always add item */ -wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier) +wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, int type, int val, int modifier, int keymodifier) { - wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + wmKeyMapItem *kmi= MEM_callocN(sizeof(wmKeyMapItem), "keymap entry"); - BLI_addtail(&keymap->keymap, kmi); + BLI_addtail(&keymap->items, kmi); BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); @@ -128,27 +198,45 @@ wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, sho return kmi; } +void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) +{ + if(BLI_findindex(&keymap->items, kmi) != -1) { + if(kmi->ptr) { + WM_operator_properties_free(kmi->ptr); + MEM_freeN(kmi->ptr); + } + BLI_freelinkN(&keymap->items, kmi); + } +} + /* ****************** storage in WM ************ */ /* name id's are for storing general or multiple keymaps, space/region ids are same as DNA_space_types.h */ /* gets free'd in wm.c */ -wmKeyMap *WM_keymap_find(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) +static wmKeyMap *wm_keymap_list_find(ListBase *lb, char *idname, int spaceid, int regionid) { wmKeyMap *km; - - for(km= wm->keymaps.first; km; km= km->next) + + for(km= lb->first; km; km= km->next) if(km->spaceid==spaceid && km->regionid==regionid) - if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME)) + if(0==strncmp(idname, km->idname, KMAP_MAX_NAME)) return km; + return NULL; +} + +wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, char *idname, int spaceid, int regionid) +{ + wmKeyMap *km= wm_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); + if(km==NULL) { km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); - BLI_strncpy(km->nameid, nameid, KMAP_MAX_NAME); + BLI_strncpy(km->idname, idname, KMAP_MAX_NAME); km->spaceid= spaceid; km->regionid= regionid; - BLI_addtail(&wm->keymaps, km); + BLI_addtail(&keyconf->keymaps, km); } return km; @@ -158,39 +246,39 @@ wmKeyMap *WM_keymap_find(wmWindowManager *wm, const char *nameid, short spaceid, /* modal maps get linked to a running operator, and filter the keys before sending to modal() callback */ -wmKeyMap *WM_modalkeymap_add(wmWindowManager *wm, const char *nameid, EnumPropertyItem *items) +wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf, char *idname, EnumPropertyItem *items) { - wmKeyMap *km= WM_keymap_find(wm, nameid, 0, 0); - km->is_modal= 1; - km->items= items; + wmKeyMap *km= WM_keymap_find(keyconf, idname, 0, 0); + km->flag |= KEYMAP_MODAL; + km->modal_items= items; return km; } -wmKeyMap *WM_modalkeymap_get(wmWindowManager *wm, const char *nameid) +wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, char *idname) { wmKeyMap *km; - for(km= wm->keymaps.first; km; km= km->next) - if(km->is_modal) - if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME)) + for(km= keyconf->keymaps.first; km; km= km->next) + if(km->flag & KEYMAP_MODAL) + if(0==strncmp(idname, km->idname, KMAP_MAX_NAME)) break; return km; } -void WM_modalkeymap_add_item(wmKeyMap *km, short type, short val, int modifier, short keymodifier, short value) +void WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value) { - wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); + wmKeyMapItem *kmi= MEM_callocN(sizeof(wmKeyMapItem), "keymap entry"); - BLI_addtail(&km->keymap, kmi); + BLI_addtail(&km->items, kmi); kmi->propvalue= value; keymap_event_set(kmi, type, val, modifier, keymodifier); } -void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) +void WM_modalkeymap_assign(wmKeyMap *km, char *opname) { wmOperatorType *ot= WM_operatortype_find(opname, 0); @@ -200,7 +288,6 @@ void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) printf("error: modalkeymap_assign, unknown operator %s\n", opname); } - /* ***************** get string from key events **************** */ const char *WM_key_event_string(short type) @@ -212,9 +299,9 @@ const char *WM_key_event_string(short type) return ""; } -static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len) +char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len) { - char buf[100]; + char buf[128]; buf[0]= 0; @@ -236,25 +323,30 @@ static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len) return str; } -static wmKeymapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props) +static wmKeyMapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props, wmKeyMap **keymap_r) { + wmWindowManager *wm= CTX_wm_manager(C); wmEventHandler *handler; wmKeyMap *keymap; - wmKeymapItem *kmi; + wmKeyMapItem *kmi; /* find keymap item in handlers */ for(handler=handlers->first; handler; handler=handler->next) { - keymap= handler->keymap; + keymap= WM_keymap_active(wm, handler->keymap); if(keymap && (!keymap->poll || keymap->poll((bContext*)C))) { - for(kmi=keymap->keymap.first; kmi; kmi=kmi->next) { + for(kmi=keymap->items.first; kmi; kmi=kmi->next) { if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) { if(compare_props) { - if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) + if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) { + if(keymap_r) *keymap_r= keymap; return kmi; + } } - else + else { + if(keymap_r) *keymap_r= keymap; return kmi; + } } } } @@ -263,74 +355,162 @@ static wmKeymapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *h return NULL; } -static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, int opcontext, IDProperty *properties, int compare_props) +static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, const char *opname, int opcontext, IDProperty *properties, int compare_props, wmKeyMap **keymap_r) { - wmKeymapItem *found= NULL; + wmWindow *win= CTX_wm_window(C); + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= CTX_wm_region(C); + wmKeyMapItem *found= NULL; /* look into multiple handler lists to find the item */ - if(CTX_wm_window(C)) - found= wm_keymap_item_find_handlers(C, &CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props); + if(win) + found= wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, compare_props, keymap_r); - if(CTX_wm_area(C) && found==NULL) - found= wm_keymap_item_find_handlers(C, &CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props); + if(sa && found==NULL) + found= wm_keymap_item_find_handlers(C, &sa->handlers, opname, opcontext, properties, compare_props, keymap_r); if(found==NULL) { if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) { - if(CTX_wm_area(C)) { - ARegion *ar= CTX_wm_area(C)->regionbase.first; + if(sa) { + ARegion *ar= sa->regionbase.first; for(; ar; ar= ar->next) if(ar->regiontype==RGN_TYPE_WINDOW) break; if(ar) - found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, keymap_r); } } else { - if(CTX_wm_region(C)) - found= wm_keymap_item_find_handlers(C, &CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props); + if(ar) + found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, keymap_r); } } return found; } -char *WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, IDProperty *properties, char *str, int len) +static wmKeyMapItem *wm_keymap_item_find(const bContext *C, const char *opname, int opcontext, IDProperty *properties, wmKeyMap **keymap_r) { - wmKeymapItem *found= wm_keymap_item_find(C, opname, opcontext, properties, 1); + wmKeyMapItem *found= wm_keymap_item_find_props(C, opname, opcontext, properties, 1, keymap_r); if(!found) - found= wm_keymap_item_find(C, opname, opcontext, properties, 0); + found= wm_keymap_item_find_props(C, opname, opcontext, properties, 0, keymap_r); + + return found; +} + +char *WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, IDProperty *properties, char *str, int len) +{ + wmKeyMapItem *kmi= wm_keymap_item_find(C, opname, opcontext, properties, NULL); - if(found) { - wm_keymap_item_to_string(found, str, len); + if(kmi) { + WM_keymap_item_to_string(kmi, str, len); return str; } return NULL; } -/* searches context and changes keymap item, if found */ -void WM_key_event_operator_change(const bContext *C, const char *opname, int opcontext, IDProperty *properties, short key, short modifier) -{ - wmKeymapItem *found= wm_keymap_item_find(C, opname, opcontext, properties, 1); +/* ***************** user preferences ******************* */ - if(!found) - found= wm_keymap_item_find(C, opname, opcontext, properties, 0); +wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) +{ + wmKeyConfig *keyconf; + wmKeyMap *km; - if(found) { - keymap_event_set(found, key, KM_PRESS, modifier, 0); + if(!keymap) + return NULL; + + /* first user defined keymaps */ + km= wm_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + if(km) + return km; + + /* then user key config */ + keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); + if(keyconf) { + km= wm_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + if(km) + return km; } + + /* then use default */ + km= wm_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + return km; } -/* ********************* */ +wmKeyMap *WM_keymap_copy_to_user(wmKeyMap *keymap) +{ + wmKeyMap *usermap; + wmKeyMapItem *kmi; + + usermap= wm_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + + if(!usermap) { + /* not saved yet, duplicate existing */ + usermap= MEM_dupallocN(keymap); + usermap->modal_items= NULL; + usermap->poll= NULL; + usermap->flag |= KEYMAP_USER; + + BLI_addtail(&U.keymaps, usermap); + } + else { + /* already saved, free items for re-copy */ + WM_keymap_free(usermap); + } + + BLI_duplicatelist(&usermap->items, &keymap->items); + + for(kmi=usermap->items.first; kmi; kmi=kmi->next) { + if(kmi->properties) { + kmi->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr"); + WM_operator_properties_create(kmi->ptr, kmi->idname); + + kmi->properties= IDP_CopyProperty(kmi->properties); + kmi->ptr->data= kmi->properties; + } + } + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + kmi->flag &= ~KMI_EXPANDED; + + return usermap; +} -int WM_key_event_is_tweak(short type) +void WM_keymap_restore_to_default(wmKeyMap *keymap) { - if(type>=EVT_TWEAK_L && type<=EVT_GESTURE) - return 1; - return 0; + wmKeyMap *usermap; + + usermap= wm_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + + if(usermap) { + WM_keymap_free(usermap); + BLI_freelinkN(&U.keymaps, usermap); + } } +/* searches context and changes keymap item, if found */ +void WM_key_event_operator_change(const bContext *C, const char *opname, int opcontext, IDProperty *properties, short key, short modifier) +{ + wmWindowManager *wm= CTX_wm_manager(C); + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + kmi= wm_keymap_item_find(C, opname, opcontext, properties, &keymap); + + if(kmi) { + /* if the existing one is in a default keymap, copy it + to user preferences, and lookup again so we get a + key map item from the user preferences we can modify */ + if(BLI_findindex(&wm->defaultconf->keymaps, keymap) >= 0) { + WM_keymap_copy_to_user(keymap); + kmi= wm_keymap_item_find(C, opname, opcontext, properties, NULL); + } + + keymap_event_set(kmi, key, KM_PRESS, modifier, 0); + } +} diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 9ec0ce0df8d..a92fcee48e2 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -517,22 +517,33 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) /* default properties for fileselect */ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type) { - RNA_def_string_file_path(ot->srna, "path", "", FILE_MAX, "FilePath", "Path to file."); - RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "FileName", "Name of the file."); - RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Directory of the file."); + PropertyRNA *prop; - RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", ""); - RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", ""); - RNA_def_boolean(ot->srna, "filter_movie", (filter & MOVIEFILE), "Filter movie files", ""); - RNA_def_boolean(ot->srna, "filter_python", (filter & PYSCRIPTFILE), "Filter python files", ""); - RNA_def_boolean(ot->srna, "filter_font", (filter & FTFONTFILE), "Filter font files", ""); - RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", ""); - RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); - RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); + RNA_def_string_file_path(ot->srna, "path", "", FILE_MAX, "File Path", "Path to file."); + RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "File Name", "Name of the file."); + RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Directory of the file."); - RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL, + prop= RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_movie", (filter & MOVIEFILE), "Filter movie files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_python", (filter & PYSCRIPTFILE), "Filter python files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_font", (filter & FTFONTFILE), "Filter font files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + prop= RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); + RNA_def_property_flag(prop, PROP_HIDDEN); + + prop= RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL, "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file.", FILE_LOADLIB, FILE_SPECIAL); + RNA_def_property_flag(prop, PROP_HIDDEN); } /* op->poll */ @@ -1103,6 +1114,8 @@ static void WM_OT_link_append(wmOperatorType *ot) ot->exec= wm_link_append_exec; ot->poll= WM_operator_winactive; + ot->flag |= OPTYPE_UNDO; + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB); RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending."); @@ -1382,7 +1395,7 @@ static void wm_gesture_end(bContext *C, wmOperator *op) int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if(WM_key_event_is_tweak(event->type)) + if(ISTWEAK(event->type)) op->customdata= WM_gesture_new(C, event, WM_GESTURE_RECT); else op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT); @@ -2146,9 +2159,9 @@ void wm_operatortype_init(void) } /* default keymap for windows and screens, only call once per WM */ -void wm_window_keymap(wmWindowManager *wm) +void wm_window_keymap(wmKeyConfig *keyconf) { - wmKeyMap *keymap= WM_keymap_find(wm, "Window", 0, 0); + wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0); /* items to make WM work */ WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index e3cfb9ad60d..44b7b60e451 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -373,15 +373,15 @@ void wm_window_add_ghostwindows(wmWindowManager *wm) /* happens after fileread */ if(win->eventstate==NULL) win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state"); - + /* add keymap handlers (1 handler for all keys in map!) */ - keymap= WM_keymap_find(wm, "Window", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Window", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); - keymap= WM_keymap_find(wm, "Screen", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Screen", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); - keymap= WM_keymap_find(wm, "Screen Editing", 0, 0); + keymap= WM_keymap_find(wm->defaultconf, "Screen Editing", 0, 0); WM_event_add_keymap_handler(&win->modalhandlers, keymap); wm_window_title(wm, win); diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index a7529157072..832558b961f 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -54,7 +54,7 @@ extern void wm_report_free(wmReport *report); /* wm_operator.c, for init/exit */ void wm_operatortype_free(void); void wm_operatortype_init(void); -void wm_window_keymap(wmWindowManager *wm); +void wm_window_keymap(wmKeyConfig *keyconf); void wm_tweakevent_test(bContext *C, wmEvent *event, int action); diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 4360e49e371..4322f70ea61 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -44,7 +44,6 @@ typedef struct wmEventHandler { /* keymap handler */ wmKeyMap *keymap; /* pointer to builtin/custom keymaps */ - rcti *bblocal, *bbwin; /* optional local and windowspace bb */ /* modal operator handler */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index cc6041ce529..b33c4bd14e8 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -199,9 +199,17 @@ /* test wether the event is a key on the keyboard */ #define ISKEYBOARD(event) (event >=' ' && event <=320) -/* test whether event type is acceptable as hotkey, excluding modifiers */ -#define ISHOTKEY(event) (ISKEYBOARD(event) && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY)) + /* test wether the event is a mouse button */ +#define ISMOUSE(event) (event >= LEFTMOUSE && event <= WHEELOUTMOUSE) + + /* test wether the event is timer event */ +#define ISTIMER(event) (event >= TIMER && event <= TIMERJOBS) + /* test wether the event is tweak event */ +#define ISTWEAK(event) (event >= EVT_TWEAK_L && event <= EVT_GESTURE) + +/* test whether event type is acceptable as hotkey, excluding modifiers */ +#define ISHOTKEY(event) ((ISKEYBOARD(event) || ISMOUSE(event)) && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY)) /* **************** BLENDER GESTURE EVENTS ********************* */ -- cgit v1.2.3 From 5c867406aa66a1d89260c233a6bbc1a2a7912dbe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 19:06:32 +0000 Subject: menus are now global (like operators), so for eg, the info add menu and the 3D add menu can be shared. --- release/scripts/ui/space_buttons.py | 1 - release/scripts/ui/space_console.py | 2 - release/scripts/ui/space_image.py | 8 ---- release/scripts/ui/space_info.py | 8 ---- release/scripts/ui/space_node.py | 3 -- release/scripts/ui/space_outliner.py | 1 - release/scripts/ui/space_sequencer.py | 6 --- release/scripts/ui/space_text.py | 7 --- release/scripts/ui/space_time.py | 4 -- release/scripts/ui/space_userpref.py | 1 - release/scripts/ui/space_view3d.py | 50 ---------------------- source/blender/blenkernel/BKE_screen.h | 6 +-- source/blender/blenkernel/intern/screen.c | 27 ------------ source/blender/editors/include/UI_interface.h | 2 +- .../blender/editors/interface/interface_layout.c | 2 +- .../blender/editors/interface/interface_regions.c | 4 +- source/blender/editors/mesh/editmesh_mods.c | 2 +- source/blender/editors/object/object_add.c | 45 ------------------- source/blender/editors/object/object_intern.h | 1 - source/blender/editors/object/object_ops.c | 5 ++- source/blender/editors/space_node/node_header.c | 2 +- source/blender/makesrna/intern/rna_ui.c | 17 ++------ source/blender/python/intern/bpy_operator.c | 2 +- source/blender/windowmanager/WM_api.h | 7 +++ source/blender/windowmanager/intern/wm.c | 46 ++++++++++++++++++++ source/blender/windowmanager/intern/wm_init_exit.c | 1 + source/blender/windowmanager/intern/wm_operators.c | 2 +- source/blender/windowmanager/intern/wm_window.c | 1 - source/blender/windowmanager/wm_window.h | 1 - 29 files changed, 70 insertions(+), 194 deletions(-) diff --git a/release/scripts/ui/space_buttons.py b/release/scripts/ui/space_buttons.py index aa89c06ea08..299e8bc9dae 100644 --- a/release/scripts/ui/space_buttons.py +++ b/release/scripts/ui/space_buttons.py @@ -22,7 +22,6 @@ class Buttons_HT_header(bpy.types.Header): row.itemR(scene, "current_frame") class Buttons_MT_view(bpy.types.Menu): - __space_type__ = 'PROPERTIES' __label__ = "View" def draw(self, context): diff --git a/release/scripts/ui/space_console.py b/release/scripts/ui/space_console.py index a65d7577c7a..5bb211f7d98 100644 --- a/release/scripts/ui/space_console.py +++ b/release/scripts/ui/space_console.py @@ -38,7 +38,6 @@ class CONSOLE_HT_header(bpy.types.Header): row.itemO("console.autocomplete", text="Autocomplete") class CONSOLE_MT_console(bpy.types.Menu): - __space_type__ = 'CONSOLE' __label__ = "Console" def draw(self, context): @@ -51,7 +50,6 @@ class CONSOLE_MT_console(bpy.types.Menu): layout.itemO("console.paste") class CONSOLE_MT_report(bpy.types.Menu): - __space_type__ = 'CONSOLE' __label__ = "Report" def draw(self, context): diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py index b14bec0e40e..c1a4fc723ca 100644 --- a/release/scripts/ui/space_image.py +++ b/release/scripts/ui/space_image.py @@ -2,7 +2,6 @@ import bpy class IMAGE_MT_view(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "View" def draw(self, context): @@ -44,7 +43,6 @@ class IMAGE_MT_view(bpy.types.Menu): layout.itemO("screen.screen_full_area") class IMAGE_MT_select(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Select" def draw(self, context): @@ -65,7 +63,6 @@ class IMAGE_MT_select(bpy.types.Menu): layout.itemO("uv.select_linked") class IMAGE_MT_image(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Image" def draw(self, context): @@ -109,7 +106,6 @@ class IMAGE_MT_image(bpy.types.Menu): layout.itemR(sima, "image_painting") class IMAGE_MT_uvs_showhide(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Show/Hide Faces" def draw(self, context): @@ -120,7 +116,6 @@ class IMAGE_MT_uvs_showhide(bpy.types.Menu): layout.item_booleanO("uv.hide", "unselected", True) class IMAGE_MT_uvs_transform(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Transform" def draw(self, context): @@ -131,7 +126,6 @@ class IMAGE_MT_uvs_transform(bpy.types.Menu): layout.itemO("tfm.resize") class IMAGE_MT_uvs_mirror(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Mirror" def draw(self, context): @@ -145,7 +139,6 @@ class IMAGE_MT_uvs_mirror(bpy.types.Menu): props.constraint_axis[1]= True class IMAGE_MT_uvs_weldalign(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Weld/Align" def draw(self, context): @@ -155,7 +148,6 @@ class IMAGE_MT_uvs_weldalign(bpy.types.Menu): layout.items_enumO("uv.align", "axis") # W, 2/3/4 class IMAGE_MT_uvs(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "UVs" def draw(self, context): diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 3805a7d0dec..32068f1b941 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -38,7 +38,6 @@ class INFO_HT_header(bpy.types.Header): layout.itemL(text=scene.statistics()) class INFO_MT_file(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "File" def draw(self, context): @@ -78,7 +77,6 @@ class INFO_MT_file(bpy.types.Menu): layout.itemO("wm.exit_blender", text="Quit") class INFO_MT_file_import(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Import" def draw(self, context): @@ -89,7 +87,6 @@ class INFO_MT_file_import(bpy.types.Menu): class INFO_MT_file_export(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Export" def draw(self, context): @@ -104,7 +101,6 @@ class INFO_MT_file_export(bpy.types.Menu): class INFO_MT_file_external_data(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "External Data" def draw(self, context): @@ -121,7 +117,6 @@ class INFO_MT_file_external_data(bpy.types.Menu): layout.itemO("file.find_missing_files") class INFO_MT_add(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Add" def draw(self, context): @@ -151,7 +146,6 @@ class INFO_MT_add(bpy.types.Menu): layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY') class INFO_MT_game(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Game" def draw(self, context): @@ -169,7 +163,6 @@ class INFO_MT_game(bpy.types.Menu): layout.itemR(gs, "deprecation_warnings") class INFO_MT_render(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Render" def draw(self, context): @@ -185,7 +178,6 @@ class INFO_MT_render(bpy.types.Menu): layout.itemO("screen.render_view_show") class INFO_MT_help(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Help" def draw(self, context): diff --git a/release/scripts/ui/space_node.py b/release/scripts/ui/space_node.py index b32e6a9f61a..5c5c49afbc7 100644 --- a/release/scripts/ui/space_node.py +++ b/release/scripts/ui/space_node.py @@ -48,7 +48,6 @@ class NODE_HT_header(bpy.types.Header): layout.itemR(snode, "backdrop") class NODE_MT_view(bpy.types.Menu): - __space_type__ = 'NODE_EDITOR' __label__ = "View" def draw(self, context): @@ -66,7 +65,6 @@ class NODE_MT_view(bpy.types.Menu): layout.itemO("screen.screen_full_area") class NODE_MT_select(bpy.types.Menu): - __space_type__ = 'NODE_EDITOR' __label__ = "Select" def draw(self, context): @@ -80,7 +78,6 @@ class NODE_MT_select(bpy.types.Menu): layout.itemO("node.select_linked_to") class NODE_MT_node(bpy.types.Menu): - __space_type__ = 'NODE_EDITOR' __label__ = "Node" def draw(self, context): diff --git a/release/scripts/ui/space_outliner.py b/release/scripts/ui/space_outliner.py index 522b620e29d..f3c45983d76 100644 --- a/release/scripts/ui/space_outliner.py +++ b/release/scripts/ui/space_outliner.py @@ -36,7 +36,6 @@ class OUTLINER_HT_header(bpy.types.Header): class OUTLINER_MT_view(bpy.types.Menu): - __space_type__ = 'OUTLINER' __label__ = "View" def draw(self, context): diff --git a/release/scripts/ui/space_sequencer.py b/release/scripts/ui/space_sequencer.py index a804998cdaa..582481401a6 100644 --- a/release/scripts/ui/space_sequencer.py +++ b/release/scripts/ui/space_sequencer.py @@ -38,7 +38,6 @@ class SEQUENCER_HT_header(bpy.types.Header): layout.itemR(st, "display_channel", text="Channel") class SEQUENCER_MT_view(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "View" def draw(self, context): @@ -106,7 +105,6 @@ class SEQUENCER_MT_view(bpy.types.Menu): """ class SEQUENCER_MT_select(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Select" def draw(self, context): @@ -127,7 +125,6 @@ class SEQUENCER_MT_select(bpy.types.Menu): layout.itemO("sequencer.select_inverse") class SEQUENCER_MT_marker(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Marker (TODO)" def draw(self, context): @@ -146,7 +143,6 @@ class SEQUENCER_MT_marker(bpy.types.Menu): #layout.itemO("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS) class SEQUENCER_MT_add(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Add" def draw(self, context): @@ -163,7 +159,6 @@ class SEQUENCER_MT_add(bpy.types.Menu): layout.itemM("SEQUENCER_MT_add_effect") class SEQUENCER_MT_add_effect(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Effect Strip..." def draw(self, context): @@ -187,7 +182,6 @@ class SEQUENCER_MT_add_effect(bpy.types.Menu): layout.item_enumO("sequencer.effect_strip_add", 'type', 'SPEED') class SEQUENCER_MT_strip(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Strip" def draw(self, context): diff --git a/release/scripts/ui/space_text.py b/release/scripts/ui/space_text.py index 117033c50a1..4860767d69d 100644 --- a/release/scripts/ui/space_text.py +++ b/release/scripts/ui/space_text.py @@ -98,7 +98,6 @@ class TEXT_PT_find(bpy.types.Panel): row.itemR(st, "find_all", text="All") class TEXT_MT_text(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Text" def draw(self, context): @@ -140,7 +139,6 @@ class TEXT_MT_text(bpy.types.Menu): #endif class TEXT_MT_edit_view(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "View" def draw(self, context): @@ -150,7 +148,6 @@ class TEXT_MT_edit_view(bpy.types.Menu): layout.item_enumO("text.move", "type", 'FILE_BOTTOM', text="Bottom of File") class TEXT_MT_edit_select(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Select" def draw(self, context): @@ -160,7 +157,6 @@ class TEXT_MT_edit_select(bpy.types.Menu): layout.itemO("text.select_line") class TEXT_MT_edit_markers(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Markers" def draw(self, context): @@ -171,7 +167,6 @@ class TEXT_MT_edit_markers(bpy.types.Menu): layout.itemO("text.previous_marker") class TEXT_MT_format(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Format" def draw(self, context): @@ -190,7 +185,6 @@ class TEXT_MT_format(bpy.types.Menu): layout.item_menu_enumO("text.convert_whitespace", "type") class TEXT_MT_edit_to3d(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Text To 3D Object" def draw(self, context): @@ -200,7 +194,6 @@ class TEXT_MT_edit_to3d(bpy.types.Menu): layout.item_booleanO("text.to_3d_object", "split_lines", True, text="One Object Per Line"); class TEXT_MT_edit(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Edit" def poll(self, context): diff --git a/release/scripts/ui/space_time.py b/release/scripts/ui/space_time.py index fdb01d5c216..2ead4305960 100644 --- a/release/scripts/ui/space_time.py +++ b/release/scripts/ui/space_time.py @@ -64,7 +64,6 @@ class TIME_HT_header(bpy.types.Header): row.itemO("anim.delete_keyframe", text="", icon='ICON_KEY_DEHLT') class TIME_MT_view(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "View" def draw(self, context): @@ -79,7 +78,6 @@ class TIME_MT_view(bpy.types.Menu): layout.itemR(st, "only_selected") class TIME_MT_frame(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "Frame" def draw(self, context): @@ -104,7 +102,6 @@ class TIME_MT_frame(bpy.types.Menu): sub.itemM("TIME_MT_autokey") class TIME_MT_playback(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "Playback" def draw(self, context): @@ -132,7 +129,6 @@ class TIME_MT_playback(bpy.types.Menu): layout.itemR(scene, "scrub_audio") class TIME_MT_autokey(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "Auto-Keyframing Mode" def draw(self, context): diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index ff4461db02f..27c826b133b 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -18,7 +18,6 @@ class USERPREF_HT_header(bpy.types.Header): layout.itemO("wm.keyconfig_save", "Save Key Configuration...") class USERPREF_MT_view(bpy.types.Menu): - __space_type__ = 'USER_PREFERENCES' __label__ = "View" def draw(self, context): diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index ef1947dbb39..ecc4d298b94 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -44,7 +44,6 @@ class VIEW3D_HT_header(bpy.types.Header): # ********** Utilities ********** class VIEW3D_MT_showhide(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" _operator_name = "" @@ -56,7 +55,6 @@ class VIEW3D_MT_showhide(bpy.types.Menu): layout.item_booleanO("%s.hide" % self._operator_name, "unselected", True, text="Hide Unselected") class VIEW3D_MT_snap(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Snap" def draw(self, context): @@ -75,7 +73,6 @@ class VIEW3D_MT_snap(bpy.types.Menu): # ********** View menus ********** class VIEW3D_MT_view(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "View" def draw(self, context): @@ -120,7 +117,6 @@ class VIEW3D_MT_view(bpy.types.Menu): layout.itemO("screen.screen_full_area", text="Toggle Full Screen") class VIEW3D_MT_view_navigation(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Navigation" def draw(self, context): @@ -142,7 +138,6 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu): layout.itemO("view3d.fly") class VIEW3D_MT_view_align(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Align View" def draw(self, context): @@ -151,7 +146,6 @@ class VIEW3D_MT_view_align(bpy.types.Menu): layout.itemO("view3d.view_center") class VIEW3D_MT_view_cameras(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Cameras" def draw(self, context): @@ -162,7 +156,6 @@ class VIEW3D_MT_view_cameras(bpy.types.Menu): # ********** Select menus, suffix from context.mode ********** class VIEW3D_MT_select_object(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -182,7 +175,6 @@ class VIEW3D_MT_select_object(bpy.types.Menu): layout.itemO("object.select_pattern", text="Select Pattern...") class VIEW3D_MT_select_pose(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -213,7 +205,6 @@ class VIEW3D_MT_select_pose(bpy.types.Menu): props.direction = 'CHILD' class VIEW3D_MT_select_particle(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -232,7 +223,6 @@ class VIEW3D_MT_select_particle(bpy.types.Menu): layout.itemO("particle.select_less") class VIEW3D_MT_select_edit_mesh(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -276,7 +266,6 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu): layout.itemO("mesh.region_to_loop") class VIEW3D_MT_select_edit_curve(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -305,7 +294,6 @@ class VIEW3D_MT_select_edit_curve(bpy.types.Menu): layout.itemO("curve.select_less") class VIEW3D_MT_select_edit_surface(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -331,7 +319,6 @@ class VIEW3D_MT_select_edit_surface(bpy.types.Menu): layout.itemO("curve.select_less") class VIEW3D_MT_select_edit_metaball(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -349,7 +336,6 @@ class VIEW3D_MT_select_edit_metaball(bpy.types.Menu): layout.itemO("mball.select_random_metaelems") class VIEW3D_MT_select_edit_lattice(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -362,7 +348,6 @@ class VIEW3D_MT_select_edit_lattice(bpy.types.Menu): layout.itemO("lattice.select_all_toggle", text="Select/Deselect All") class VIEW3D_MT_select_edit_armature(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -391,7 +376,6 @@ class VIEW3D_MT_select_edit_armature(bpy.types.Menu): props.direction = 'CHILD' class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -402,7 +386,6 @@ class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum # ********** Object menu ********** class VIEW3D_MT_object(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __context__ = "objectmode" __label__ = "Object" @@ -440,7 +423,6 @@ class VIEW3D_MT_object(bpy.types.Menu): layout.itemM("VIEW3D_MT_object_showhide") class VIEW3D_MT_object_clear(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Clear" def draw(self, context): @@ -452,7 +434,6 @@ class VIEW3D_MT_object_clear(bpy.types.Menu): layout.itemO("object.origin_clear", text="Origin") class VIEW3D_MT_object_parent(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Parent" def draw(self, context): @@ -462,7 +443,6 @@ class VIEW3D_MT_object_parent(bpy.types.Menu): layout.itemO("object.parent_clear", text="Clear") class VIEW3D_MT_object_track(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Track" def draw(self, context): @@ -472,7 +452,6 @@ class VIEW3D_MT_object_track(bpy.types.Menu): layout.itemO("object.track_clear", text="Clear") class VIEW3D_MT_object_group(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Group" def draw(self, context): @@ -487,7 +466,6 @@ class VIEW3D_MT_object_group(bpy.types.Menu): layout.itemO("group.objects_remove_active") class VIEW3D_MT_object_constraints(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Constraints" def draw(self, context): @@ -497,7 +475,6 @@ class VIEW3D_MT_object_constraints(bpy.types.Menu): layout.itemO("object.constraints_clear") class VIEW3D_MT_object_showhide(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" def draw(self, context): @@ -510,7 +487,6 @@ class VIEW3D_MT_object_showhide(bpy.types.Menu): # ********** Vertex paint menu ********** class VIEW3D_MT_paint_vertex(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Paint" def draw(self, context): @@ -525,7 +501,6 @@ class VIEW3D_MT_paint_vertex(bpy.types.Menu): # ********** Sculpt menu ********** class VIEW3D_MT_sculpt(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Sculpt" def draw(self, context): @@ -561,7 +536,6 @@ class VIEW3D_MT_sculpt(bpy.types.Menu): # ********** Particle menu ********** class VIEW3D_MT_particle(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Particle" def draw(self, context): @@ -591,7 +565,6 @@ class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide): # ********** Pose Menu ********** class VIEW3D_MT_pose(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Pose" def draw(self, context): @@ -651,7 +624,6 @@ class VIEW3D_MT_pose(bpy.types.Menu): layout.item_menu_enumO("pose.flags_set", 'mode', text="Bone Settings") class VIEW3D_MT_pose_transform(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Clear Transform" def draw(self, context): @@ -666,7 +638,6 @@ class VIEW3D_MT_pose_transform(bpy.types.Menu): layout.itemL(text="Origin") class VIEW3D_MT_pose_pose(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Pose Library" def draw(self, context): @@ -681,7 +652,6 @@ class VIEW3D_MT_pose_pose(bpy.types.Menu): layout.itemO("poselib.pose_remove", text="Remove Pose...") class VIEW3D_MT_pose_motion(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Motion Paths" def draw(self, context): @@ -691,7 +661,6 @@ class VIEW3D_MT_pose_motion(bpy.types.Menu): layout.itemO("pose.paths_clear", text="Clear") class VIEW3D_MT_pose_group(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Bone Groups" def draw(self, context): @@ -706,7 +675,6 @@ class VIEW3D_MT_pose_group(bpy.types.Menu): class VIEW3D_MT_pose_ik(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Inverse Kinematics" def draw(self, context): @@ -716,7 +684,6 @@ class VIEW3D_MT_pose_ik(bpy.types.Menu): layout.itemO("pose.ik_clear") class VIEW3D_MT_pose_constraints(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Constraints" def draw(self, context): @@ -732,7 +699,6 @@ class VIEW3D_MT_pose_showhide(VIEW3D_MT_showhide): # Edit MESH class VIEW3D_MT_edit_mesh(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Mesh" def draw(self, context): @@ -775,7 +741,6 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu): layout.itemM("VIEW3D_MT_edit_mesh_showhide") class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Vertices" def draw(self, context): @@ -792,7 +757,6 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): layout.itemO("mesh.remove_doubles") class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Edges" def draw(self, context): @@ -817,7 +781,6 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): layout.item_enumO("mesh.edge_rotate", "direction", 'CCW', text="Rotate Edge CCW") class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Faces" def draw(self, context): @@ -839,7 +802,6 @@ class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): layout.itemO("mesh.faces_shade_flat") class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Normals" def draw(self, context): @@ -889,13 +851,11 @@ def draw_curve(self, context): layout.itemM("VIEW3D_MT_edit_curve_showhide") class VIEW3D_MT_edit_curve(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Curve" draw = draw_curve class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Control Points" def draw(self, context): @@ -913,7 +873,6 @@ class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu): layout.item_menu_enumO("curve.handle_type_set", "type") class VIEW3D_MT_edit_curve_segments(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Segments" def draw(self, context): @@ -927,14 +886,12 @@ class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide): # Edit SURFACE class VIEW3D_MT_edit_surface(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Surface" draw = draw_curve # Edit TEXT class VIEW3D_MT_edit_text(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Text" def draw(self, context): @@ -947,7 +904,6 @@ class VIEW3D_MT_edit_text(bpy.types.Menu): layout.itemm("view3d_mt_edit_text_chars") class VIEW3D_MT_edit_text_chars(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Special Characters" def draw(self, context): @@ -982,7 +938,6 @@ class VIEW3D_MT_edit_text_chars(bpy.types.Menu): # Edit META class VIEW3D_MT_edit_meta(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Metaball" def draw(self, context): @@ -1012,7 +967,6 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu): layout.itemM("VIEW3D_MT_edit_meta_showhide") class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" def draw(self, context): @@ -1024,7 +978,6 @@ class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu): # Edit LATTICE class VIEW3D_MT_edit_lattice(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Lattice" def draw(self, context): @@ -1045,7 +998,6 @@ class VIEW3D_MT_edit_lattice(bpy.types.Menu): # Edit ARMATURE class VIEW3D_MT_edit_armature(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Armature" def draw(self, context): @@ -1102,7 +1054,6 @@ class VIEW3D_MT_edit_armature(bpy.types.Menu): layout.item_menu_enumO("armature.flags_set", "mode", text="Bone Settings") class VIEW3D_MT_edit_armature_parent(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Parent" def draw(self, context): @@ -1112,7 +1063,6 @@ class VIEW3D_MT_edit_armature_parent(bpy.types.Menu): layout.itemO("armature.parent_clear", text="Clear") class VIEW3D_MT_edit_armature_roll(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Bone Roll" def draw(self, context): diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 7c62c8c6dd4..39a90fe3074 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -138,9 +138,6 @@ typedef struct ARegionType { /* header type definitions */ ListBase headertypes; - - /* menu type definitions */ - ListBase menutypes; /* hardcoded constraints, smaller than these values region is not visible */ int minsizex, minsizey; @@ -200,7 +197,6 @@ typedef struct MenuType { char idname[BKE_ST_MAXNAME]; /* unique name */ char label[BKE_ST_MAXNAME]; /* for button text */ - int space_type; /* verify if the menu should draw or not */ int (*poll)(const struct bContext *, struct MenuType *); @@ -223,7 +219,7 @@ const struct ListBase *BKE_spacetypes_list(void); void BKE_spacetype_register(struct SpaceType *st); void BKE_spacetypes_free(void); /* only for quitting blender */ -MenuType *BKE_spacemenu_find(const char *idname, int spacetype); +// MenuType *BKE_spacemenu_find(const char *idname, int spacetype); /* spacedata */ void BKE_spacedata_freelist(ListBase *lb); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 3567de5df40..918a67311a0 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -70,13 +70,8 @@ static void spacetype_free(SpaceType *st) if(ht->ext.free) ht->ext.free(ht->ext.data); - for(mt= art->menutypes.first; mt; mt= mt->next) - if(mt->ext.free) - mt->ext.free(mt->ext.data); - BLI_freelistN(&art->paneltypes); BLI_freelistN(&art->headertypes); - BLI_freelistN(&art->menutypes); } BLI_freelistN(&st->regiontypes); @@ -343,25 +338,3 @@ unsigned int BKE_screen_visible_layers(bScreen *screen) return layer; } -MenuType *BKE_spacemenu_find(const char *idname, int spacetype) -{ - SpaceType *st= BKE_spacetype_from_id(spacetype); - ARegionType *art; - MenuType* mt; - - if(st==NULL) { - printf("space type %d is invalid\n", spacetype); - return NULL; - } - - if(idname==NULL) - return NULL; - - for(art= st->regiontypes.first; art; art= art->next) - for(mt=art->menutypes.first; mt; mt=mt->next) - if(strcmp(idname, mt->idname)==0) - return mt; - - return NULL; -} - diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 3c6ed1137ae..5766fcfdb1f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -257,7 +257,7 @@ void uiPupMenuSaveOver(struct bContext *C, struct wmOperator *op, char *filename void uiPupMenuNotice(struct bContext *C, char *str, ...); void uiPupMenuError(struct bContext *C, char *str, ...); void uiPupMenuReports(struct bContext *C, struct ReportList *reports); -void uiPupMenuInvoke(struct bContext *C, const char *idname, int spacetype); /* popup registered menu */ +void uiPupMenuInvoke(struct bContext *C, const char *idname); /* popup registered menu */ /* Popup Blocks * diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index eb81044852a..b0f93472240 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1232,7 +1232,7 @@ void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname { MenuType *mt; - mt= BKE_spacemenu_find(menuname, CTX_wm_area(C)->spacetype); + mt= WM_menutype_find(menuname, FALSE); if(mt==NULL) { printf("uiItemM: not found %s\n", menuname); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index cdb62d0a4b4..c837599baf3 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2481,12 +2481,12 @@ void uiPupMenuReports(bContext *C, ReportList *reports) BLI_dynstr_free(ds); } -void uiPupMenuInvoke(bContext *C, const char *idname, int spacetype) +void uiPupMenuInvoke(bContext *C, const char *idname) { uiPopupMenu *pup; uiLayout *layout; Menu menu; - MenuType *mt= BKE_spacemenu_find(idname, spacetype); + MenuType *mt= WM_menutype_find(idname, TRUE); if(mt==NULL) { printf("uiPupMenuInvoke: named menu \"%s\" not found\n", idname); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 4669f7a6741..3c3cdf25d7b 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -119,7 +119,7 @@ void EM_select_mirrored(Object *obedit, EditMesh *em) void EM_automerge(Scene *scene, Object *obedit, int update) { - Mesh *me= (Mesh*)obedit->data; /* can be NULL */ + Mesh *me= obedit ? obedit->data : NULL; /* can be NULL */ int len; if ((scene->toolsettings->automerge) && diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 780126852ed..c552a2954b7 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -686,51 +686,6 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", ""); } -static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup= uiPupMenuBegin(C, "Add Object", 0); - uiLayout *layout= uiPupMenuLayout(pup); - - uiItemMenuEnumO(layout, "Mesh", ICON_OUTLINER_OB_MESH, "OBJECT_OT_mesh_add", "type"); - uiItemMenuEnumO(layout, "Curve", ICON_OUTLINER_OB_CURVE, "OBJECT_OT_curve_add", "type"); - uiItemMenuEnumO(layout, "Surface", ICON_OUTLINER_OB_SURFACE, "OBJECT_OT_surface_add", "type"); - uiItemMenuEnumO(layout, "Metaball", ICON_OUTLINER_OB_META, "OBJECT_OT_metaball_add", "type"); - uiItemO(layout, "Text", ICON_OUTLINER_OB_FONT, "OBJECT_OT_text_add"); - uiItemS(layout); - uiItemO(layout, "Armature", ICON_OUTLINER_OB_ARMATURE, "OBJECT_OT_armature_add"); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_LATTICE, "OBJECT_OT_add", "type", OB_LATTICE); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_add", "type", OB_EMPTY); - uiItemS(layout); - uiItemEnumO(layout, NULL, ICON_OUTLINER_OB_CAMERA, "OBJECT_OT_add", "type", OB_CAMERA); - uiItemMenuEnumO(layout, "Lamp", ICON_OUTLINER_OB_LAMP, "OBJECT_OT_lamp_add", "type"); - uiItemS(layout); - uiItemMenuEnumO(layout, "Force Field", ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_effector_add", "type"); - uiItemS(layout); - uiItemMenuEnumO(layout, "Group Instance", ICON_OUTLINER_OB_EMPTY, "OBJECT_OT_group_instance_add", "type"); - - uiPupMenuEnd(C, pup); - - /* this operator is only for a menu, not used further */ - return OPERATOR_CANCELLED; -} - -/* only used as menu */ -void OBJECT_OT_primitive_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Primitive"; - ot->description = "Add a primitive object."; - ot->idname= "OBJECT_OT_primitive_add"; - - /* api callbacks */ - ot->invoke= object_primitive_add_invoke; - - ot->poll= ED_operator_scene_editable; - - /* flags */ - ot->flag= 0; -} - /* add dupligroup */ static EnumPropertyItem *add_dupligroup_itemf(bContext *C, PointerRNA *ptr, int *free) { diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 1a7d3841aaa..353622526d3 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -90,7 +90,6 @@ void OBJECT_OT_metaball_add(struct wmOperatorType *ot); void OBJECT_OT_text_add(struct wmOperatorType *ot); void OBJECT_OT_armature_add(struct wmOperatorType *ot); void OBJECT_OT_lamp_add(struct wmOperatorType *ot); -void OBJECT_OT_primitive_add(struct wmOperatorType *ot); /* only used as menu */ void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_group_instance_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index f2f24c099bc..d75cf63c1d4 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -119,7 +119,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_effector_add); WM_operatortype_append(OBJECT_OT_group_instance_add); - WM_operatortype_append(OBJECT_OT_primitive_add); WM_operatortype_append(OBJECT_OT_mesh_add); WM_operatortype_append(OBJECT_OT_metaball_add); WM_operatortype_append(OBJECT_OT_duplicates_make_real); @@ -247,7 +246,9 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "OBJECT_OT_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "name", "INFO_MT_add"); + WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1); WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index 2abcd2f2135..a0eae40f579 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -199,7 +199,7 @@ void node_menus_register(ARegionType *art) strcpy(mt->idname, "NODE_MT_add"); strcpy(mt->label, "Add"); mt->draw= node_menu_add; - BLI_addtail(&art->menutypes, mt); + WM_menutype_add(mt); } #if 0 diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 1a1172247fc..a1b412c70f4 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -348,12 +348,11 @@ static void rna_Menu_unregister(const bContext *C, StructRNA *type) if(!mt) return; - if(!(art=region_type_find(NULL, mt->space_type, RGN_TYPE_HEADER))) - return; RNA_struct_free_extension(type, &mt->ext); - BLI_freelinkN(&art->menutypes, mt); + WM_menutype_freelink(mt); + RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ @@ -376,12 +375,9 @@ static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void /* validate the python class */ if(validate(&dummymtr, data, have_function) != 0) return NULL; - - if(!(art=region_type_find(reports, dummymt.space_type, RGN_TYPE_HEADER))) - return NULL; /* check if we have registered this menu type before, and remove it */ - mt= BKE_spacemenu_find(dummymt.idname, dummymt.space_type); + mt= WM_menutype_find(dummymt.idname, TRUE); if(mt && mt->ext.srna) rna_Menu_unregister(C, mt->ext.srna); @@ -398,7 +394,7 @@ static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void mt->poll= (have_function[0])? menu_poll: NULL; mt->draw= (have_function[1])? menu_draw: NULL; - BLI_addtail(&art->menutypes, mt); + WM_menutype_add(mt); /* update while blender is running */ if(C) @@ -734,11 +730,6 @@ static void rna_def_menu(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "type->label"); RNA_def_property_flag(prop, PROP_REGISTER); - prop= RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type->space_type"); - RNA_def_property_enum_items(prop, space_type_items); - RNA_def_property_flag(prop, PROP_REGISTER); - RNA_define_verify_sdna(1); } diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 301204d3e2b..87752ca9c58 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -94,7 +94,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args) char *report_str= BKE_reports_string(reports, 0); /* all reports */ if(report_str) { - PySys_WriteStdout(report_str); + PySys_WriteStdout("%s\n", report_str); MEM_freeN(report_str); } } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index b29dbec6364..eaf8b00163c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -41,6 +41,7 @@ struct wmNotifier; struct rcti; struct PointerRNA; struct EnumPropertyItem; +struct MenuType; typedef struct wmJob wmJob; @@ -187,6 +188,12 @@ char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struc void WM_operator_bl_idname(char *to, const char *from); void WM_operator_py_idname(char *to, const char *from); +/* *************** menu types ******************** */ +struct MenuType *WM_menutype_find(const char *idname, int quiet); +int WM_menutype_add(struct MenuType* mt); +void WM_menutype_freelink(struct MenuType* mt); +void WM_menutype_free(void); + /* default operator callbacks for border/circle/lasso */ int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_border_select_modal (struct bContext *C, struct wmOperator *op, struct wmEvent *event); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index a068f84ae29..dbb8fc400c0 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -26,6 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "string.h" + #include "DNA_windowmanager_types.h" #include "MEM_guardedalloc.h" @@ -39,6 +41,7 @@ #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_screen.h" #include "BKE_report.h" #include "WM_api.h" @@ -128,6 +131,49 @@ void WM_operator_stack_clear(bContext *C) /* ****************************************** */ +static ListBase menutypes = {NULL, NULL}; /* global menutype list */ + +MenuType *WM_menutype_find(const char *idname, int quiet) +{ + MenuType* mt; + + if (idname[0]) { + for(mt=menutypes.first; mt; mt=mt->next) + if(strcmp(idname, mt->idname)==0) + return mt; + } + + if(!quiet) + printf("search for unknown menutype %s\n", idname); + + return NULL; +} + +int WM_menutype_add(MenuType* mt) +{ + BLI_addtail(&menutypes, mt); + return 1; +} + +void WM_menutype_freelink(MenuType* mt) +{ + BLI_freelinkN(&menutypes, mt); +} + +void WM_menutype_free(void) +{ + MenuType* mt; + + for(mt= menutypes.first; mt; mt= mt->next) { + if(mt->ext.free) { + mt->ext.free(mt->ext.data); + } + WM_menutype_freelink(mt); + } +} + +/* ****************************************** */ + void WM_keymap_init(bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 490ef12a523..2e456669cb1 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -195,6 +195,7 @@ void WM_exit(bContext *C) } } wm_operatortype_free(); + WM_menutype_free(); /* all non-screen and non-space stuff editors did, like editmode */ if(C) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a92fcee48e2..915f4c80663 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -783,7 +783,7 @@ static int wm_call_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) char idname[BKE_ST_MAXNAME]; RNA_string_get(op->ptr, "name", idname); - uiPupMenuInvoke(C, idname, CTX_wm_area(C)->spacetype); + uiPupMenuInvoke(C, idname); return OPERATOR_CANCELLED; } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 44b7b60e451..f7116a2bd1f 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -68,7 +68,6 @@ GHOST_SystemHandle g_system= NULL; /* set by commandline */ static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0; - /* ******** win open & close ************ */ /* XXX this one should correctly check for apple top header... diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index f159f7f098d..44c31e7cb69 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -62,6 +62,5 @@ void wm_window_testbreak (void); int wm_window_duplicate_op (bContext *C, wmOperator *op); int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op); - #endif /* WM_WINDOW_H */ -- cgit v1.2.3 From dadd8466d524ca8fa8a7152e88049f43d139b63d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 8 Oct 2009 19:32:06 +0000 Subject: scons - ignore removing _tkinter.so when its not there --- tools/Blender.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Blender.py b/tools/Blender.py index fec11685525..38d2747889a 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -555,7 +555,7 @@ def UnixPyBundle(target=None, source=None, env=None): run('rm -rf "%s/site-packages"' % py_target) run('mkdir "%s/site-packages"' % py_target) # python needs it.' - run('rm "%s/lib-dynload/_tkinter.so"' % py_target) + run('rm -f "%s/lib-dynload/_tkinter.so"' % py_target) run('find "%s" -name "test" -prune -exec rm -rf {} \;' % py_target) run('find "%s" -name "*.py?" -exec rm -rf {} \;' % py_target) run('find "%s" -name "*.so"-exec strip -s {} \;' % py_target) -- cgit v1.2.3 From 1b6a09847a7a397810b154396b45161ccf97be36 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 9 Oct 2009 01:34:46 +0000 Subject: Partial revert of rev 23723 BRECHT, CHECK THIS The change made it return RNA python properties with null data pointer instead of None. That would make the particles and physics properties crash like this: 1. A valid property instead of None makes is seem like smoke (or other) modifier data is in context when it is Null. 2. UI code would try to access RNA properties of the (Null) modifier, which would crash --- source/blender/python/intern/bpy_rna.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 44b419e8ae9..ee202d7fcff 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -433,7 +433,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) { PointerRNA newptr; newptr= RNA_property_pointer_get(ptr, prop); - if (newptr.type) { + if (newptr.data) { ret = pyrna_struct_CreatePyObject(&newptr); } else { ret = Py_None; @@ -1297,7 +1297,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) CTX_data_get(self->ptr.data, name, &newptr, &newlb); - if (newptr.type) { + if (newptr.data) { ret = pyrna_struct_CreatePyObject(&newptr); } else if (newlb.first) { -- cgit v1.2.3 From cc4dd3f04e150613e8c160e4d58f4a557e59c63c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 9 Oct 2009 01:52:57 +0000 Subject: netrender Support for fluid files and better support for point cache (including external cache for particles) This also fixes a couple of bugs with frame based dependencies and with file transfer. NOTE: With external point cache and fluids, the path needs to be relative or relative to the file (starting with //) if the files are not on a shared drive. It should eventually warn if that is not the case, but doesn't right now, so be careful. --- release/scripts/io/netrender/client.py | 144 ++++++++++++++++++++------------- release/scripts/io/netrender/model.py | 2 +- release/scripts/io/netrender/utils.py | 2 +- 3 files changed, 91 insertions(+), 57 deletions(-) diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py index 1897d1fd949..d4a7b242cab 100644 --- a/release/scripts/io/netrender/client.py +++ b/release/scripts/io/netrender/client.py @@ -8,6 +8,68 @@ import netrender.slave as slave import netrender.master as master from netrender.utils import * +def addFluidFiles(job, path): + if os.path.exists(path): + pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz") + + for fluid_file in sorted(os.listdir(path)): + match = pattern.match(fluid_file) + + if match: + current_frame = int(match.groups()[1]) + job.addFile(path + fluid_file, current_frame, current_frame) + +def addPointCache(job, ob, point_cache, default_path): + if not point_cache.disk_cache: + return + + + name = point_cache.name + if name == "": + name = "".join(["%02X" % ord(c) for c in ob.name]) + + cache_path = bpy.sys.expandpath(point_cache.filepath) if point_cache.external else default_path + + index = "%02i" % point_cache.index + + if os.path.exists(cache_path): + pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys") + + cache_files = [] + + for cache_file in sorted(os.listdir(cache_path)): + match = pattern.match(cache_file) + + if match: + cache_frame = int(match.groups()[0]) + cache_files.append((cache_frame, cache_file)) + + cache_files.sort() + + if len(cache_files) == 1: + cache_frame, cache_file = cache_files[0] + job.addFile(cache_path + cache_file, cache_frame, cache_frame) + else: + for i in range(len(cache_files)): + current_item = cache_files[i] + next_item = cache_files[i+1] if i + 1 < len(cache_files) else None + previous_item = cache_files[i - 1] if i > 0 else None + + current_frame, current_file = current_item + + if not next_item and not previous_item: + job.addFile(cache_path + current_file, current_frame, current_frame) + elif next_item and not previous_item: + next_frame = next_item[0] + job.addFile(cache_path + current_file, current_frame, next_frame - 1) + elif not next_item and previous_item: + previous_frame = previous_item[0] + job.addFile(cache_path + current_file, previous_frame + 1, current_frame) + else: + next_frame = next_item[0] + previous_frame = previous_item[0] + job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) + def clientSendJob(conn, scene, anim = False): netsettings = scene.network_render job = netrender.model.RenderJob() @@ -23,6 +85,7 @@ def clientSendJob(conn, scene, anim = False): job_name = netsettings.job_name path, name = os.path.split(filename) + path += os.sep if job_name == "[default]": job_name = name @@ -30,67 +93,38 @@ def clientSendJob(conn, scene, anim = False): # LIBRARIES ########################### for lib in bpy.data.libraries: - lib_path = lib.filename - - if lib_path.startswith("//"): - lib_path = path + os.sep + lib_path[2:] - - job.addFile(lib_path) - - ########################### - # POINT CACHES - ########################### - - root, ext = os.path.splitext(name) - cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - - if os.path.exists(cache_path): - caches = {} - pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") - for cache_file in sorted(os.listdir(cache_path)): - match = pattern.match(cache_file) - - if match: - cache_id = match.groups()[0] - cache_frame = int(match.groups()[1]) - - cache_files = caches.get(cache_id, []) - cache_files.append((cache_frame, cache_file)) - caches[cache_id] = cache_files - - for cache in caches.values(): - cache.sort() - - if len(cache) == 1: - cache_frame, cache_file = cache[0] - job.addFile(cache_path + cache_file, cache_frame, cache_frame) - else: - for i in range(len(cache)): - current_item = cache[i] - next_item = cache[i+1] if i + 1 < len(cache) else None - previous_item = cache[i - 1] if i > 0 else None - - current_frame, current_file = current_item - - if not next_item and not previous_item: - job.addFile(cache_path + current_file, current_frame, current_frame) - elif next_item and not previous_item: - next_frame = next_item[0] - job.addFile(cache_path + current_file, current_frame, next_frame - 1) - elif not next_item and previous_item: - previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, current_frame) - else: - next_frame = next_item[0] - previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) + job.addFile(bpy.sys.expandpath(lib_path)) ########################### # IMAGES ########################### for image in bpy.data.images: if image.source == "FILE" and not image.packed_file: - job.addFile(image.filename) + job.addFile(bpy.sys.expandpath(image.filename)) + + ########################### + # FLUID + POINT CACHE + ########################### + root, ext = os.path.splitext(name) + default_path = path + "blendcache_" + root + os.sep # need an API call for that + + for object in bpy.data.objects: + for modifier in object.modifiers: + if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN": + addFluidFiles(job, bpy.sys.expandpath(modifier.settings.path)) + elif modifier.type == "CLOTH": + addPointCache(job, object, modifier.point_cache, default_path) + elif modifier.type == "SOFT_BODY": + addPointCache(job, object, modifier.point_cache, default_path) + elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN": + addPointCache(job, object, modifier.domain_settings.point_cache_low, default_path) + if modifier.domain_settings.highres: + addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path) + + # particles modifier are stupid and don't contain data + # we have to go through the object property + for psys in object.particle_systems: + addPointCache(job, object, psys.point_cache, default_path) # print(job.files) diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py index ca2a42d87f6..bef6f0e68af 100644 --- a/release/scripts/io/netrender/model.py +++ b/release/scripts/io/netrender/model.py @@ -149,7 +149,7 @@ class RenderJob: "id": self.id, "type": self.type, "name": self.name, - "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], + "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= max_frame and f[2] >= min_frame)], "frames": [f.serialize() for f in self.frames if not frames or f in frames], "chunks": self.chunks, "priority": self.priority, diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py index 06393a738a0..b10648b8d62 100644 --- a/release/scripts/io/netrender/utils.py +++ b/release/scripts/io/netrender/utils.py @@ -75,7 +75,7 @@ def prefixPath(prefix_directory, file_path, prefix_path): if prefix_path and p.startswith(prefix_path): directory = prefix_directory + p[len(prefix_path):] - full_path = directory + n + full_path = directory + os.sep + n if not os.path.exists(directory): os.mkdir(directory) else: -- cgit v1.2.3 From 9ebcd9c5e46c8addd80c8adb97fcee91a1916d57 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 9 Oct 2009 09:48:04 +0000 Subject: A few bugfixes: * #19583: Keying Sets list issues Deleting a Keying Set (or a Keying Set Path) set the active index to 0, but that would mean that the first item would be selected but not visible. * #19590: Keyframing properties of a modifier with more than one of it's type the property will highlight in all - Modifiers now always have a unique name, so renaming a modifier should check that the name is unique. Most of the files changed in this commit were just to make sure that modifiers got unique names when they were created - Modifiers path getter was wrapped a bit wrong (missing the "s around the name) * Constraints Bugs - Constraints renaming now also makes sure the names stay unique - Fixed (or attempted to fix) compiler warnings about some enum declaration for distance constraint --- source/blender/blenkernel/BKE_modifier.h | 2 ++ source/blender/blenkernel/intern/modifier.c | 13 ++++++++- source/blender/blenkernel/intern/multires.c | 1 + source/blender/blenloader/intern/readfile.c | 4 +++ source/blender/editors/animation/keyingsets.c | 9 +++--- .../editors/interface/interface_templates.c | 2 ++ source/blender/editors/object/object_edit.c | 8 +++-- source/blender/editors/object/object_hook.c | 1 + source/blender/editors/object/object_modifier.c | 22 ++++++++++---- source/blender/makesrna/intern/rna_constraint.c | 34 +++++++++++++++++----- source/blender/makesrna/intern/rna_fluidsim.c | 1 + source/blender/makesrna/intern/rna_modifier.c | 18 +++++++++++- 12 files changed, 94 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 27c75126026..9957ced9555 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -274,6 +274,8 @@ ModifierTypeInfo *modifierType_getInfo (ModifierType type); struct ModifierData *modifier_new(int type); void modifier_free(struct ModifierData *md); +void modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md); + void modifier_copyData(struct ModifierData *md, struct ModifierData *target); int modifier_dependsOnTime(struct ModifierData *md); int modifier_supportsMapping(struct ModifierData *md); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f36713dd8a9..532c3e5da73 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -34,6 +34,7 @@ * */ +#include "stddef.h" #include "string.h" #include "stdarg.h" #include "math.h" @@ -8761,7 +8762,8 @@ ModifierData *modifier_new(int type) { ModifierTypeInfo *mti = modifierType_getInfo(type); ModifierData *md = MEM_callocN(mti->structSize, mti->structName); - + + // FIXME: we need to make the name always be unique somehow... strcpy(md->name, mti->name); md->type = type; @@ -8786,6 +8788,15 @@ void modifier_free(ModifierData *md) MEM_freeN(md); } +void modifier_unique_name(ListBase *modifiers, ModifierData *md) +{ + if (modifiers && md) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + BLI_uniquename(modifiers, md, mti->name, '.', offsetof(ModifierData, name), sizeof(md->name)); + } +} + int modifier_dependsOnTime(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index e7159b82d49..ecffbb3d15f 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -142,6 +142,7 @@ void multiresModifier_join(Object *ob) mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires); BLI_insertlinkbefore(&base->object->modifiers, md, mmd); + modifier_unique_name(&base->object->modifiers, mmd); } if(mmd) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f2bf8b19bc6..49dae2af168 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4095,6 +4095,8 @@ static void direct_link_object(FileData *fd, Object *ob) BLI_addhead(&ob->modifiers, hmd); BLI_remlink(&ob->hooks, hook); + + modifier_unique_name(&ob->modifiers, hmd); MEM_freeN(hook); } @@ -7659,6 +7661,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) smd->flags |= eSubsurfModifierFlag_ControlEdges; BLI_addtail(&ob->modifiers, smd); + + modifier_unique_name(&ob->modifiers, smd); } } diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index d1ac624ec6f..a044e867d56 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -177,9 +177,10 @@ static int remove_active_keyingset_exec (bContext *C, wmOperator *op) /* free KeyingSet's data, then remove it from the scene */ BKE_keyingset_free(ks); - BLI_freelinkN(&scene->keyingsets, ks); - scene->active_keyingset= 0; + + /* the active one should now be the previously second-to-last one */ + scene->active_keyingset--; return OPERATOR_FINISHED; } @@ -258,8 +259,8 @@ static int remove_active_ks_path_exec (bContext *C, wmOperator *op) BLI_freelinkN(&ks->paths, ksp); } - /* fix active path index */ - ks->active_path= 0; + /* the active path should now be the previously second-to-last active one */ + ks->active_path--; } else { BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove"); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d94d2be3a94..24bff19555f 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -458,6 +458,8 @@ static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v) nmd->mode &= ~eModifierMode_Virtual; BLI_addhead(&ob->modifiers, nmd); + + modifier_unique_name(&ob->modifiers, nmd); ob->partype = PAROBJECT; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 268cd3b3542..55f95f451d2 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -848,6 +848,7 @@ void special_editmenu(Scene *scene, View3D *v3d) BooleanModifierData *bmd = NULL; bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean); BLI_addtail(&ob->modifiers, bmd); + modifier_unique_name(&ob->modifiers, bmd); bmd->object = base_select->object; bmd->modifier.mode |= eModifierMode_Realtime; switch(nr){ @@ -978,9 +979,10 @@ static void object_flip_subdivison_particles(Scene *scene, Object *ob, int *set, } else if(depth == 0 && *set != 0) { SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf); - + BLI_addtail(&ob->modifiers, smd); - + modifier_unique_name(&ob->modifiers, smd); + if (level!=-1) { smd->levels = level; } @@ -1197,6 +1199,7 @@ static void copymenu_modifiers(Scene *scene, View3D *v3d, Object *ob) nmd = modifier_new(md->type); modifier_copyData(md, nmd); BLI_addtail(&base->object->modifiers, nmd); + modifier_unique_name(&base->object->modifiers, nmd); } copy_object_particlesystems(base->object, ob); @@ -1220,6 +1223,7 @@ static void copymenu_modifiers(Scene *scene, View3D *v3d, Object *ob) mdn = modifier_new(event); BLI_addtail(&base->object->modifiers, mdn); + modifier_unique_name(&base->object->modifiers, mdn); modifier_copyData(md, mdn); } diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index ab7bcbc989d..63182e943bb 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -480,6 +480,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode) hmd = (HookModifierData*) modifier_new(eModifierType_Hook); BLI_insertlinkbefore(&obedit->modifiers, md, hmd); sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2); + modifier_unique_name(&obedit->modifiers, hmd); } else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */ diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 7f0f1876417..252fdb5522a 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -76,7 +76,7 @@ int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int type) { - ModifierData *md; + ModifierData *md=NULL, *new_md=NULL; ModifierTypeInfo *mti = modifierType_getInfo(type); if(mti->flags&eModifierTypeFlag_Single) { @@ -87,19 +87,28 @@ int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int ty } if(type == eModifierType_ParticleSystem) { + /* don't need to worry about the new modifier's name, since that is set to the number + * of particle systems which shouldn't have too many duplicates + */ object_add_particle_system(scene, ob); } else { + /* get new modifier data to add */ + new_md= modifier_new(type); + if(mti->flags&eModifierTypeFlag_RequiresOriginalData) { md = ob->modifiers.first; - + while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) md = md->next; - - BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type)); + + BLI_insertlinkbefore(&ob->modifiers, md, new_md); } else - BLI_addtail(&ob->modifiers, modifier_new(type)); + BLI_addtail(&ob->modifiers, new_md); + + /* make sure modifier data has unique name */ + modifier_unique_name(&ob->modifiers, new_md); /* special cases */ if(type == eModifierType_Softbody) { @@ -111,7 +120,7 @@ int ED_object_modifier_add(ReportList *reports, Scene *scene, Object *ob, int ty else if(type == eModifierType_Collision) { if(!ob->pd) ob->pd= object_add_collision_fields(0); - + ob->pd->deflect= 1; DAG_scene_sort(scene); } @@ -400,6 +409,7 @@ int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md) nmd = modifier_new(md->type); modifier_copyData(md, nmd); BLI_insertlink(&ob->modifiers, md, nmd); + modifier_unique_name(&ob->modifiers, nmd); return 1; } diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index e6d8a2f27d7..325318ba34a 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -87,13 +87,6 @@ EnumPropertyItem constraint_ik_type_items[] ={ {0, NULL, 0, NULL, NULL}, }; -EnumPropertyItem constraint_distance_items[] = { - {LIMITDIST_INSIDE, "LIMITDIST_INSIDE", 0, "Inside", ""}, - {LIMITDIST_OUTSIDE, "LIMITDIST_OUTSIDE", 0, "Outside", ""}, - {LIMITDIST_ONSURFACE, "LIMITDIST_ONSURFACE", 0, "On Surface", ""}, - {0, NULL, 0, NULL, NULL} -}; - #ifdef RNA_RUNTIME #include "BKE_action.h" @@ -153,6 +146,24 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr) } } +static void rna_Constraint_name_set(PointerRNA *ptr, const char *value) +{ + bConstraint *con= ptr->data; + + /* copy the new name into the name slot */ + BLI_strncpy(con->name, value, sizeof(con->name)); + + /* make sure name is unique */ + if (ptr->id.data) { + Object *ob= ptr->id.data; + ListBase *list= get_active_constraints(ob); + + /* if we have the list, check for unique name, otherwise give up */ + if (list) + unique_constraint_name(con, list); + } +} + static char *rna_Constraint_path(PointerRNA *ptr) { Object *ob= ptr->id.data; @@ -291,6 +302,14 @@ static void rna_ActionConstraint_minmax_range(PointerRNA *ptr, float *min, float #else +EnumPropertyItem constraint_distance_items[] = { + {LIMITDIST_INSIDE, "LIMITDIST_INSIDE", 0, "Inside", ""}, + {LIMITDIST_OUTSIDE, "LIMITDIST_OUTSIDE", 0, "Outside", ""}, + {LIMITDIST_ONSURFACE, "LIMITDIST_ONSURFACE", 0, "On Surface", ""}, + {0, NULL, 0, NULL, NULL} +}; + + static void rna_def_constrainttarget(BlenderRNA *brna) { StructRNA *srna; @@ -1606,6 +1625,7 @@ void RNA_def_constraint(BlenderRNA *brna) /* strings */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Constraint_name_set"); RNA_def_property_ui_text(prop, "Name", ""); RNA_def_struct_name_property(srna, prop); diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index c415b3d716a..5b05948857e 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -114,6 +114,7 @@ static void rna_FluidSettings_update_type(bContext *C, PointerRNA *ptr) sprintf(psmd->modifier.name, "FluidParticleSystem" ); psmd->psys= psys; BLI_addtail(&ob->modifiers, psmd); + modifier_unique_name(&ob->modifiers, psmd); } } else { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 480abff19cb..b04f0a865ef 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -85,6 +85,7 @@ EnumPropertyItem modifier_type_items[] ={ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_library.h" +#include "BKE_modifier.h" static void rna_UVProject_projectors_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { @@ -164,9 +165,23 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr) } } +void rna_Modifier_name_set(PointerRNA *ptr, const char *value) +{ + ModifierData *md= ptr->data; + + /* copy the new name into the name slot */ + BLI_strncpy(md->name, value, sizeof(md->name)); + + /* make sure the name is truly unique */ + if (ptr->id.data) { + Object *ob= ptr->id.data; + modifier_unique_name(&ob->modifiers, md); + } +} + static char *rna_Modifier_path(PointerRNA *ptr) { - return BLI_sprintfN("modifiers[%s]", ((ModifierData*)ptr->data)->name); // XXX not unique + return BLI_sprintfN("modifiers[\"%s\"]", ((ModifierData*)ptr->data)->name); } static void rna_Modifier_update(bContext *C, PointerRNA *ptr) @@ -1911,6 +1926,7 @@ void RNA_def_modifier(BlenderRNA *brna) /* strings */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Modifier_name_set"); RNA_def_property_ui_text(prop, "Name", "Modifier name."); RNA_def_struct_name_property(srna, prop); -- cgit v1.2.3 From 2226a5139a2ad78d4de2eaaf09e734adf1ce0ae4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 09:50:49 +0000 Subject: Fix some issues with showing the current textures when using material nodes and texture nodes. Made it all use the same give_current_*_texture functions now. --- release/scripts/ui/buttons_texture.py | 8 +- source/blender/blenkernel/BKE_texture.h | 25 +++-- source/blender/blenkernel/intern/texture.c | 102 ++++++++++++--------- .../editors/space_buttons/buttons_context.c | 14 +-- source/blender/editors/space_node/node_edit.c | 12 +-- 5 files changed, 89 insertions(+), 72 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index c4866edcaaa..b76f35c3ec3 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -75,11 +75,13 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): layout.itemR(tex, "use_nodes") split = layout.split(percentage=0.2) - + if tex.use_nodes: slot = context.texture_slot - split.itemL(text="Output:") - split.itemR(slot, "output_node", text="") + + if slot: + split.itemL(text="Output:") + split.itemR(slot, "output_node", text="") else: split.itemL(text="Type:") diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index a9862ba586b..407dc94adfa 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -31,17 +31,20 @@ #ifndef BKE_TEXTURE_H #define BKE_TEXTURE_H -struct Scene; -struct Tex; -struct MTex; -struct PluginTex; -struct LampRen; +struct Brush; struct ColorBand; -struct HaloRen; -struct TexMapping; struct EnvMap; +struct HaloRen; +struct Lamp; +struct LampRen; +struct Material; +struct MTex; +struct PluginTex; struct PointDensity; +struct Tex; +struct TexMapping; struct VoxelData; +struct World; /* in ColorBand struct */ #define MAXCOLORBAND 32 @@ -65,8 +68,12 @@ struct MTex *add_mtex(void); struct Tex *copy_texture(struct Tex *tex); void make_local_texture(struct Tex *tex); void autotexname(struct Tex *tex); -struct Tex *give_current_texture(struct Object *ob, int act); -struct Tex *give_current_world_texture(struct Scene *scene); + +struct Tex *give_current_object_texture(struct Object *ob); +struct Tex *give_current_material_texture(struct Material *ma); +struct Tex *give_current_lamp_texture(struct Lamp *la); +struct Tex *give_current_world_texture(struct World *world); +struct Tex *give_current_brush_texture(struct Brush *br); struct TexMapping *add_mapping(void); void init_mapping(struct TexMapping *texmap); diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 3b8ae9a6c7f..f09abf93bb8 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -809,72 +809,90 @@ void autotexname(Tex *tex) /* ------------------------------------------------------------------------- */ -Tex *give_current_texture(Object *ob, int act) +Tex *give_current_object_texture(Object *ob) { - Material ***matarar, *ma; - Lamp *la = 0; - MTex *mtex = 0; - Tex *tex = 0; - bNode *node; + Material *ma; + Tex *tex= NULL; if(ob==0) return 0; if(ob->totcol==0 && !(ob->type==OB_LAMP)) return 0; if(ob->type==OB_LAMP) { - la=(Lamp *)ob->data; - if(la) { - mtex= la->mtex[(int)(la->texact)]; - if(mtex) tex= mtex->tex; - } + tex= give_current_lamp_texture(ob->data); } else { - if(act>ob->totcol) act= ob->totcol; - else if(act==0) act= 1; - - if(ob->matbits[act-1]) { /* in object */ - ma= ob->mat[act-1]; - } - else { /* in data */ - matarar= give_matarar(ob); - - if(matarar && *matarar) ma= (*matarar)[act-1]; - else ma= 0; - } + ma= give_current_material(ob, ob->actcol); + tex= give_current_material_texture(ma); + } + + return tex; +} - if(ma && ma->use_nodes && ma->nodetree) { - node= nodeGetActiveID(ma->nodetree, ID_TE); +Tex *give_current_lamp_texture(Lamp *la) +{ + MTex *mtex= NULL; + Tex *tex= NULL; - if(node) { - tex= (Tex *)node->id; - ma= NULL; - } - else { - node= nodeGetActiveID(ma->nodetree, ID_MA); - if(node) - ma= (Material*)node->id; - } + if(la) { + mtex= la->mtex[(int)(la->texact)]; + if(mtex) tex= mtex->tex; + } + + return tex; +} + +Tex *give_current_material_texture(Material *ma) +{ + MTex *mtex= NULL; + Tex *tex= NULL; + bNode *node; + + if(ma && ma->use_nodes && ma->nodetree) { + node= nodeGetActiveID(ma->nodetree, ID_TE); + + if(node) { + tex= (Tex *)node->id; + ma= NULL; } - if(ma) { - mtex= ma->mtex[(int)(ma->texact)]; - if(mtex) tex= mtex->tex; + else { + node= nodeGetActiveID(ma->nodetree, ID_MA); + if(node) + ma= (Material*)node->id; } } + if(ma) { + mtex= ma->mtex[(int)(ma->texact)]; + if(mtex) tex= mtex->tex; + } return tex; } -Tex *give_current_world_texture(Scene *scene) +Tex *give_current_world_texture(World *world) { - MTex *mtex = 0; - Tex *tex = 0; + MTex *mtex= NULL; + Tex *tex= NULL; - if(!(scene->world)) return 0; + if(!world) return 0; - mtex= scene->world->mtex[(int)(scene->world->texact)]; + mtex= world->mtex[(int)(world->texact)]; if(mtex) tex= mtex->tex; return tex; } +Tex *give_current_brush_texture(Brush *br) +{ + MTex *mtex= NULL; + Tex *tex= NULL; + + if(br) { + mtex= br->mtex[(int)(br->texact)]; + if(mtex) tex= mtex->tex; + } + + return tex; +} + /* ------------------------------------------------------------------------- */ EnvMap *BKE_add_envmap(void) diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 9333ba9209c..a5a7524e584 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -52,6 +52,7 @@ #include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_screen.h" +#include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_world.h" @@ -342,7 +343,6 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path Lamp *la; Brush *br; World *wo; - MTex *mtex; Tex *tex; PointerRNA *ptr= &path->ptr[path->len-1]; @@ -355,8 +355,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path br= path->ptr[path->len-1].data; if(br) { - mtex= br->mtex[(int)br->texact]; - tex= (mtex)? mtex->tex: NULL; + tex= give_current_brush_texture(br); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; @@ -368,8 +367,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path wo= path->ptr[path->len-1].data; if(wo) { - mtex= wo->mtex[(int)wo->texact]; - tex= (mtex)? mtex->tex: NULL; + give_current_world_texture(wo); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; @@ -381,8 +379,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path ma= path->ptr[path->len-1].data; if(ma) { - mtex= ma->mtex[(int)ma->texact]; - tex= (mtex)? mtex->tex: NULL; + tex= give_current_material_texture(ma); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; @@ -394,8 +391,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path la= path->ptr[path->len-1].data; if(la) { - mtex= la->mtex[(int)la->texact]; - tex= (mtex)? mtex->tex: NULL; + tex= give_current_lamp_texture(la); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index cee90b5a148..13421adf6e6 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -645,7 +645,7 @@ void snode_set_context(SpaceNode *snode, Scene *scene) if(snode->texfrom==SNODE_TEX_OBJECT) { if(ob) { - tx= give_current_texture(ob, ob->actcol); + tx= give_current_object_texture(ob); if(ob->type == OB_LAMP) snode->from= (ID*)ob->data; @@ -656,11 +656,10 @@ void snode_set_context(SpaceNode *snode, Scene *scene) } } else if(snode->texfrom==SNODE_TEX_WORLD) { - tx= give_current_world_texture(scene); + tx= give_current_world_texture(scene->world); snode->from= (ID *)scene->world; } else { - MTex *mtex= NULL; Brush *brush= NULL; if(ob && (ob->mode & OB_MODE_SCULPT)) @@ -668,13 +667,8 @@ void snode_set_context(SpaceNode *snode, Scene *scene) else brush= paint_brush(&scene->toolsettings->imapaint.paint); - if(brush && brush->texact != -1) - mtex= brush->mtex[brush->texact]; - snode->from= (ID *)brush; - - if(mtex) - tx= mtex->tex; + tx= give_current_brush_texture(brush); } snode->id= &tx->id; -- cgit v1.2.3 From be3da5dfffd23b0dc2f9bffc2e7d2012f1c63494 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 10:45:11 +0000 Subject: 3D View panels now show object and bone name again, not sure it belongs here still, but this came up often, it avoids having to switch tabs a lot when creating things. Also renamed uiLayoutFreeBlock to uiLayoutAbsoluteBlock. --- source/blender/editors/include/UI_interface.h | 2 +- .../blender/editors/interface/interface_layout.c | 22 ++++---- .../editors/interface/interface_templates.c | 8 +-- source/blender/editors/space_graph/graph_buttons.c | 4 +- source/blender/editors/space_image/image_buttons.c | 2 +- source/blender/editors/space_logic/logic_buttons.c | 4 +- source/blender/editors/space_node/drawnode.c | 48 ++++++++--------- .../editors/space_sequencer/sequencer_buttons.c | 4 +- .../blender/editors/space_view3d/view3d_buttons.c | 62 +++++++++++++++++----- .../blender/editors/space_view3d/view3d_header.c | 2 +- 10 files changed, 96 insertions(+), 62 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 5766fcfdb1f..adbfd731a09 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -614,7 +614,7 @@ uiLayout *uiLayoutListBox(uiLayout *layout); uiLayout *uiLayoutFree(uiLayout *layout, int align); uiLayout *uiLayoutSplit(uiLayout *layout, float percentage); -uiBlock *uiLayoutFreeBlock(uiLayout *layout); +uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout); /* templates */ void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b0f93472240..233d3b214ae 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -96,7 +96,7 @@ typedef enum uiItemType { ITEM_LAYOUT_COLUMN_FLOW, ITEM_LAYOUT_ROW_FLOW, ITEM_LAYOUT_BOX, - ITEM_LAYOUT_FREE, + ITEM_LAYOUT_ABSOLUTE, ITEM_LAYOUT_SPLIT, ITEM_LAYOUT_ROOT @@ -290,7 +290,7 @@ static int ui_layout_local_dir(uiLayout *layout) case ITEM_LAYOUT_COLUMN: case ITEM_LAYOUT_COLUMN_FLOW: case ITEM_LAYOUT_SPLIT: - case ITEM_LAYOUT_FREE: + case ITEM_LAYOUT_ABSOLUTE: case ITEM_LAYOUT_BOX: default: return UI_LAYOUT_VERTICAL; @@ -1731,7 +1731,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) } /* free layout */ -static void ui_litem_estimate_free(uiLayout *litem) +static void ui_litem_estimate_absolute(uiLayout *litem) { uiItem *item; int itemx, itemy, itemw, itemh, minx, miny; @@ -1756,7 +1756,7 @@ static void ui_litem_estimate_free(uiLayout *litem) litem->h -= miny; } -static void ui_litem_layout_free(uiLayout *litem) +static void ui_litem_layout_absolute(uiLayout *litem) { uiItem *item; float scalex=1.0f, scaley=1.0f; @@ -1962,7 +1962,7 @@ uiLayout *uiLayoutFree(uiLayout *layout, int align) uiLayout *litem; litem= MEM_callocN(sizeof(uiLayout), "uiLayoutFree"); - litem->item.type= ITEM_LAYOUT_FREE; + litem->item.type= ITEM_LAYOUT_ABSOLUTE; litem->root= layout->root; litem->align= align; litem->active= 1; @@ -1975,7 +1975,7 @@ uiLayout *uiLayoutFree(uiLayout *layout, int align) return litem; } -uiBlock *uiLayoutFreeBlock(uiLayout *layout) +uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout) { uiBlock *block; @@ -2136,8 +2136,8 @@ static void ui_item_estimate(uiItem *item) case ITEM_LAYOUT_ROOT: ui_litem_estimate_root(litem); break; - case ITEM_LAYOUT_FREE: - ui_litem_estimate_free(litem); + case ITEM_LAYOUT_ABSOLUTE: + ui_litem_estimate_absolute(litem); break; case ITEM_LAYOUT_SPLIT: ui_litem_estimate_split(litem); @@ -2161,7 +2161,7 @@ static void ui_item_align(uiLayout *litem, int nr) if(!bitem->but->alignnr) bitem->but->alignnr= nr; } - else if(item->type == ITEM_LAYOUT_FREE); + else if(item->type == ITEM_LAYOUT_ABSOLUTE); else if(item->type == ITEM_LAYOUT_BOX) { box= (uiLayoutItemBx*)item; box->roundbox->alignnr= nr; @@ -2221,8 +2221,8 @@ static void ui_item_layout(uiItem *item) case ITEM_LAYOUT_ROOT: ui_litem_layout_root(litem); break; - case ITEM_LAYOUT_FREE: - ui_litem_layout_free(litem); + case ITEM_LAYOUT_ABSOLUTE: + ui_litem_layout_absolute(litem); break; case ITEM_LAYOUT_SPLIT: ui_litem_layout_split(litem); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 24bff19555f..7f768a42956 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -61,7 +61,7 @@ void uiTemplateHeader(uiLayout *layout, bContext *C, int menus) { uiBlock *block; - block= uiLayoutFreeBlock(layout); + block= uiLayoutAbsoluteBlock(layout); if(menus) ED_area_header_standardbuttons(C, block, 0); else ED_area_header_switchbutton(C, block, 0); } @@ -603,7 +603,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i } result= uiLayoutColumn(box, 0); - block= uiLayoutFreeBlock(box); + block= uiLayoutAbsoluteBlock(box); } if(md->error) { @@ -948,7 +948,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) } else { box= uiLayoutBox(col); - block= uiLayoutFreeBlock(box); + block= uiLayoutAbsoluteBlock(box); switch (con->type) { #ifndef DISABLE_PYTHON @@ -1459,7 +1459,7 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, char *propname, int rect.xmin= 0; rect.xmax= 200; rect.ymin= 0; rect.ymax= 190; - block= uiLayoutFreeBlock(layout); + block= uiLayoutAbsoluteBlock(layout); colorband_buttons_layout(block, cptr.data, &rect, !expand, cb); MEM_freeN(cb); diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 09008f8d2d1..afc86309ffb 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -146,7 +146,7 @@ static void graph_panel_properties(const bContext *C, Panel *pa) if(!graph_panel_context(C, &ale, &fcu)) return; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); /* Info - Active F-Curve */ @@ -285,7 +285,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) driver= fcu->driver; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); /* general actions */ diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 67fb95b1f6b..e2990a6d919 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -1105,7 +1105,7 @@ static void image_panel_uv(const bContext *C, Panel *pa) ARegion *ar= CTX_wm_region(C); uiBlock *block; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_image_panel_events, NULL); image_editvertex_buts(C, block); diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c index 304c3601cdd..5761432ee29 100644 --- a/source/blender/editors/space_logic/logic_buttons.c +++ b/source/blender/editors/space_logic/logic_buttons.c @@ -83,7 +83,7 @@ static void logic_panel_properties(const bContext *C, Panel *pa) // SpaceLogic *slogic= CTX_wm_space_logic(C); uiBlock *block; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_logic_panel_events, NULL); } @@ -93,7 +93,7 @@ static void logic_panel_view_properties(const bContext *C, Panel *pa) // SpaceLogic *slogic= CTX_wm_space_logic(C); uiBlock *block; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_logic_panel_events, NULL); } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 33be0b83f20..42c664520fe 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -173,7 +173,7 @@ static void node_group_alone_cb(bContext *C, void *node_v, void *unused_v) static void node_buts_group(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; @@ -207,7 +207,7 @@ static void node_buts_group(uiLayout *layout, PointerRNA *ptr) static void node_buts_value(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; bNodeSocket *sock= node->outputs.first; /* first socket stores value */ @@ -219,7 +219,7 @@ static void node_buts_value(uiLayout *layout, PointerRNA *ptr) static void node_buts_rgb(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; bNodeSocket *sock= node->outputs.first; /* first socket stores value */ @@ -279,7 +279,7 @@ static void node_buts_time(uiLayout *layout, PointerRNA *ptr) static void node_buts_valtorgb(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; @@ -316,7 +316,7 @@ static void node_buts_curvecol(uiLayout *layout, PointerRNA *ptr) static void node_buts_normal(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ @@ -389,7 +389,7 @@ static void node_dynamic_update_cb(bContext *C, void *ntree_v, void *node_v) static void node_buts_texture(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -432,7 +432,7 @@ static void node_buts_texture(uiLayout *layout, PointerRNA *ptr) static void node_buts_math(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; uiBut *bt; @@ -544,7 +544,7 @@ static void node_texmap_cb(bContext *C, void *texmap_v, void *unused_v) static void node_shader_buts_material(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -616,7 +616,7 @@ static void node_shader_buts_material(uiLayout *layout, PointerRNA *ptr) static void node_shader_buts_mapping(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; TexMapping *texmap= node->storage; @@ -664,7 +664,7 @@ static void node_shader_buts_mapping(uiLayout *layout, PointerRNA *ptr) static void node_shader_buts_vect_math(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; uiBut *bt; @@ -675,7 +675,7 @@ static void node_shader_buts_vect_math(uiLayout *layout, PointerRNA *ptr) static void node_shader_buts_geometry(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; uiBut *but; @@ -694,7 +694,7 @@ static void node_shader_buts_geometry(uiLayout *layout, PointerRNA *ptr) static void node_shader_buts_dynamic(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -867,7 +867,7 @@ static void image_layer_cb(bContext *C, void *ima_v, void *iuser_v) static void node_composit_buts_image(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -1035,7 +1035,7 @@ static void node_browse_scene_cb(bContext *C, void *ntree_v, void *node_v) static void node_composit_buts_renderlayers(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -1402,7 +1402,7 @@ static void node_composit_buts_chroma_matte(uiLayout *layout, PointerRNA *ptr) uiItemR(col, NULL, 0, ptr, "gain", UI_ITEM_R_SLIDER); uiItemR(col, NULL, 0, ptr, "shadow_adjust", UI_ITEM_R_SLIDER); -// uiBlock *block= uiLayoutFreeBlock(layout); +// uiBlock *block= uiLayoutAbsoluteBlock(layout); // bNode *node= ptr->data; // rctf *butr= &node->butr; // short dx=(butr->xmax-butr->xmin)/2; @@ -1435,7 +1435,7 @@ static void node_composit_buts_color_matte(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_channel_matte(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; short sx= (butr->xmax-butr->xmin)/4; @@ -1492,7 +1492,7 @@ static void node_composit_buts_channel_matte(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_luma_matte(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; NodeChroma *c=node->storage; @@ -1519,7 +1519,7 @@ static void node_composit_buts_map_uv(uiLayout *layout, PointerRNA *ptr) static void node_composit_buts_id_mask(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; @@ -1554,7 +1554,7 @@ static void node_set_image_cb(bContext *C, void *ntree_v, void *node_v) static void node_composit_buts_file_output(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -1626,7 +1626,7 @@ static void node_scale_cb(bContext *C, void *node_v, void *unused_v) static void node_composit_buts_scale(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; uiBut *bt= uiDefButS(block, MENU, B_NODE_EXEC, "Relative %x0|Absolute %x1|Scene Size % %x2|", @@ -1799,7 +1799,7 @@ static void node_composit_set_butfunc(bNodeType *ntype) static void node_texture_buts_bricks(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; short w = butr->xmax-butr->xmin; @@ -1848,7 +1848,7 @@ static char* noisebasis_menu() static void node_texture_buts_proc(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; Tex *tex = (Tex *)node->storage; @@ -1927,7 +1927,7 @@ static void node_texture_buts_proc(uiLayout *layout, PointerRNA *ptr) static void node_texture_buts_image(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; bNodeTree *ntree= ptr->id.data; rctf *butr= &node->butr; @@ -1966,7 +1966,7 @@ static void node_texture_buts_image(uiLayout *layout, PointerRNA *ptr) static void node_texture_buts_output(uiLayout *layout, PointerRNA *ptr) { - uiBlock *block= uiLayoutFreeBlock(layout); + uiBlock *block= uiLayoutAbsoluteBlock(layout); bNode *node= ptr->data; rctf *butr= &node->butr; uiBut *bt; diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 72cbacd9b6d..70f3cc955b8 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -72,7 +72,7 @@ static void sequencer_panel_view_properties(const bContext *C, Panel *pa) { uiBlock *block; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_sequencer_panel_events, NULL); } @@ -82,7 +82,7 @@ static void sequencer_panel_properties(const bContext *C, Panel *pa) { uiBlock *block; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_sequencer_panel_events, NULL); } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 161b73032f5..2ce7da4c073 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -152,8 +152,9 @@ typedef struct { /* is used for both read and write... */ -static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim) +static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d, Object *ob, float lim) { + uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL; MDeformVert *dvert=NULL; TransformProperties *tfp= v3d->properties_storage; float median[5], ve_median[5]; @@ -497,12 +498,15 @@ static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev) } #endif -static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim) +static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { + uiBlock *block= uiLayoutGetBlock(layout); bArmature *arm; bPoseChannel *pchan; Bone *bone= NULL; TransformProperties *tfp= v3d->properties_storage; + PointerRNA pchanptr; + uiLayout *row; arm = ob->data; if (!arm || !ob->pose) return; @@ -516,7 +520,15 @@ static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float uiDefBut(block, LABEL, 0, "No Bone Active", 0, 240, 100, 20, 0, 0, 0, 0, 0, ""); return; } + else { + row= uiLayoutRow(layout, 0); + RNA_pointer_create(&ob->id, &RNA_PoseChannel, pchan, &pchanptr); + uiItemL(row, "", ICON_BONE_DATA); + uiItemR(row, "", 0, &pchanptr, "name", 0); + } + uiLayoutAbsoluteBlock(layout); + if (pchan->rotmode == ROT_MODE_AXISANGLE) { float quat[4]; /* convert to euler, passing through quats... */ @@ -587,11 +599,14 @@ void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev) WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix } -static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim) +static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { + uiBlock *block= uiLayoutGetBlock(layout); bArmature *arm= ob->data; EditBone *ebone; TransformProperties *tfp= v3d->properties_storage; + uiLayout *row; + PointerRNA eboneptr; ebone= arm->edbo->first; @@ -603,6 +618,13 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float if (!ebone) return; + row= uiLayoutRow(layout, 0); + RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr); + uiItemL(row, "", ICON_BONE_DATA); + uiItemR(row, "", 0, &eboneptr, "name", 0); + + uiLayoutAbsoluteBlock(layout); + uiDefBut(block, LABEL, 0, "Head:", 0, 210, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_ARMATUREPANEL1, "X:", 0, 190, 100, 19, ebone->head, -lim, lim, 10, 3, "X Location of the head end of the bone"); @@ -630,8 +652,9 @@ static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float } -static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim) +static void v3d_editmetaball_buts(uiLayout *layout, Object *ob, float lim) { + uiBlock *block= uiLayoutAbsoluteBlock(layout); MetaElem *lastelem= NULL; // XXX if(lastelem) { @@ -1013,7 +1036,7 @@ static void view3d_panel_transform_spaces(const bContext *C, Panel *pa) int xco = 20, yco = 70; int index; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockBeginAlign(block); @@ -1095,6 +1118,8 @@ static void view3d_panel_object(const bContext *C, Panel *pa) //uiBut *bt; Object *ob= OBACT; TransformProperties *tfp; + PointerRNA obptr; + uiLayout *col, *row; float lim; if(ob==NULL) return; @@ -1104,9 +1129,6 @@ static void view3d_panel_object(const bContext *C, Panel *pa) v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties"); tfp= v3d->properties_storage; - block= uiLayoutFreeBlock(pa->layout); - uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); - // XXX uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) { @@ -1120,17 +1142,29 @@ static void view3d_panel_object(const bContext *C, Panel *pa) lim= 10000.0f*MAX2(1.0, v3d->grid); + block= uiLayoutGetBlock(pa->layout); + uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); + + col= uiLayoutColumn(pa->layout, 0); + row= uiLayoutRow(col, 0); + RNA_id_pointer_create(&ob->id, &obptr); + uiItemL(row, "", ICON_OBJECT_DATA); + uiItemR(row, "", 0, &obptr, "name", 0); + if(ob==obedit) { - if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim); - if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim); - else v3d_editvertex_buts(C, block, v3d, ob, lim); + if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, v3d, ob, lim); + if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob, lim); + else v3d_editvertex_buts(C, col, v3d, ob, lim); } else if(ob->mode & OB_MODE_POSE) { - v3d_posearmature_buts(block, v3d, ob, lim); + v3d_posearmature_buts(col, v3d, ob, lim); } else { BoundBox *bb = NULL; - + + uiLayoutAbsoluteBlock(col); + + block= uiLayoutAbsoluteBlock(col); uiDefBut(block, LABEL, 0, "Location:", 0, 300, 100, 20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_OBJECTPANEL, "X:", 0, 280, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, ""); @@ -1307,7 +1341,7 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa) }; - block= uiLayoutFreeBlock(pa->layout); + block= uiLayoutAbsoluteBlock(pa->layout); uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); uiBlockBeginAlign(block); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 0d19a720cdb..a44e3743bb4 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -1964,7 +1964,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiBlock *block; int a, xco=0, maxco=0, yco= 0; - block= uiLayoutFreeBlock(layout); + block= uiLayoutAbsoluteBlock(layout); uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); if((sa->flag & HEADER_NO_PULLDOWN)==0) -- cgit v1.2.3 From 488c06d1827d5bf5d02a22fcc11a1dfeb50143a7 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 9 Oct 2009 12:15:46 +0000 Subject: Cessen Request: In Animation Editors, F-Curves for Pose Channel Constraints now include the Pose Channel and Constraint names in the 'owner' part of the name displayed, making it easier to identify which Pose Channel some constraint F-Curve belonged to. e.g. The influence setting for an IK Constraint on bone "Boney" Old Version: Influence (IK) New Version: Influence (Boney : IK) We can experiment with different representations of this later (maybe '>' instead of ':' ?) --- source/blender/editors/animation/anim_ipo_utils.c | 69 ++++++++++++++++++----- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index 26edf930f0b..1590aa57463 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -35,6 +35,7 @@ #include #include +#include #include "MEM_guardedalloc.h" @@ -92,6 +93,30 @@ int geticon_anim_blocktype(short blocktype) } } +/* helper function for getname_*() - grabs the text within the "" that starts with 'blahblah' + * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples" + * + * - str: is the entire string to chop + * - prefix: is the part of the string to leave out + * + * Assume that the strings returned must be freed afterwards, and that the inputs will contain + * data we want... + */ +static char *grab_quoted_text (const char *str, const char *prefix) +{ + int prefixLen = strlen(prefix); + char *startMatch, *endMatch; + + /* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */ + startMatch= strstr(str, prefix) + prefixLen + 1; + + /* get the end point (i.e. where the next occurance of " is after the starting point) */ + endMatch= strchr(startMatch, '"'); // " NOTE: this comment here is just so that my text editor still shows the functions ok... + + /* return the slice indicated */ + return BLI_strdupn(startMatch, (int)(endMatch-startMatch)); +} + /* Write into "name" buffer, the name of the property (retrieved using RNA from the curve's settings) * WARNING: name buffer we're writing to cannot exceed 256 chars (check anim_channels_defines.c for details) */ @@ -118,7 +143,7 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu) /* try to resolve the path */ if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) { char *structname=NULL, *propname=NULL, *arrayname=NULL, arrayindbuf[16]; - PropertyRNA *nameprop; + short free_structname = 0; /* For now, name will consist of 3 parts: struct-name, property name, array index * There are several options possible: @@ -132,16 +157,34 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu) * hierarchy though, which isn't so clear with option 2. */ - /* for structname, we use a custom name if one is available */ - // xxx we might want an icon from types? - // xxx it is hard to differentiate between object and bone channels then, if ob + bone motion occur together... - nameprop= RNA_struct_name_property(ptr.type); - if (nameprop) { - /* this gets a string which will need to be freed */ - structname= RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0); + /* for structname + * - as base, we use a custom name from the structs if one is available + * - however, if we're showing subdata of bones (probably there will be other exceptions later) + * need to include that info too since it gets confusing otherwise + */ + if (strstr(fcu->rna_path, "pose_channels") && strstr(fcu->rna_path, "constraints")) { + /* perform string 'chopping' to get "Bone Name : Constraint Name" */ + char *pchanName= grab_quoted_text(fcu->rna_path, "pose_channels["); + char *constName= grab_quoted_text(fcu->rna_path, "constraints["); + + /* assemble the string to display in the UI... */ + structname= BLI_sprintfN("%s : %s", pchanName, constName); + free_structname= 1; + + /* free the temp names */ + if (pchanName) MEM_freeN(pchanName); + if (constName) MEM_freeN(constName); + } + else { + PropertyRNA *nameprop= RNA_struct_name_property(ptr.type); + if (nameprop) { + /* this gets a string which will need to be freed */ + structname= RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0); + free_structname= 1; + } + else + structname= (char *)RNA_struct_ui_name(ptr.type); } - else - structname= (char *)RNA_struct_ui_name(ptr.type); /* Property Name is straightforward */ propname= (char *)RNA_property_ui_name(prop); @@ -151,9 +194,9 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu) char c= RNA_property_array_item_char(prop, fcu->array_index); /* we need to write the index to a temp buffer (in py syntax) */ - if(c) sprintf(arrayindbuf, "%c ", c); + if (c) sprintf(arrayindbuf, "%c ", c); else sprintf(arrayindbuf, "[%d]", fcu->array_index); - + arrayname= &arrayindbuf[0]; } else { @@ -166,7 +209,7 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu) BLI_snprintf(name, 128, "%s%s (%s)", arrayname, propname, structname); /* free temp name if nameprop is set */ - if (nameprop) + if (free_structname) MEM_freeN(structname); } else { -- cgit v1.2.3 From 9f7038c5a73d8e73b858a129561d4721481f62e2 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 9 Oct 2009 12:16:58 +0000 Subject: * Warning fixes for previous commit for Modifier renaming. * Removed some old code (depsgraph) that was already commented out --- source/blender/blenkernel/intern/depsgraph.c | 25 +------------------------ source/blender/blenkernel/intern/library.c | 3 ++- source/blender/blenloader/intern/readfile.c | 4 ++-- source/blender/editors/object/object_edit.c | 4 ++-- source/blender/editors/object/object_hook.c | 2 +- 5 files changed, 8 insertions(+), 30 deletions(-) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index a8cec6070a0..ec054bc47cd 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2391,29 +2391,6 @@ void DAG_pose_sort(Object *ob) ListBase targets = {NULL, NULL}; bConstraintTarget *ct; -#if 0 // XXX old animation system... driver stuff to watch out for - if(con->ipo) { - IpoCurve *icu; - for(icu= con->ipo->curve.first; icu; icu= icu->next) { - /* icu->driver->ob should actually point to ob->proxy if it - * is a proxy, but since it wasn't set correct it older - * files comparing with ob->proxy makes it work for those */ - if(icu->driver && (icu->driver->ob==ob || icu->driver->ob==ob->proxy)) { - bPoseChannel *target= get_pose_channel(ob->pose, icu->driver->name); - if(target) { - node2 = dag_get_node(dag, target); - dag_add_relation(dag, node2, node, 0, "Ipo Driver"); - - /* uncommented this line, results in dependencies - * not being added properly for this constraint, - * what is the purpose of this? - brecht */ - /*cti= NULL;*/ /* trick to get next loop skipped */ - } - } - } - } -#endif // XXX old animation system... driver stuff to watch out for - if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); @@ -2423,7 +2400,7 @@ void DAG_pose_sort(Object *ob) if (target) { node2= dag_get_node(dag, target); dag_add_relation(dag, node2, node, 0, "IK Constraint"); - + if (con->type==CONSTRAINT_TYPE_KINEMATIC) { bKinematicConstraint *data = (bKinematicConstraint *)con->data; bPoseChannel *parchan; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 0f65be207d9..a79c3472426 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1208,12 +1208,13 @@ static void lib_indirect_test_id(ID *id) int a; - // XXX old animation system! + // XXX old animation system! -------------------------------------- for (strip=ob->nlastrips.first; strip; strip=strip->next){ LIBTAG(strip->object); LIBTAG(strip->act); LIBTAG(strip->ipo); } + // XXX: new animation system needs something like this? for(a=0; atotcol; a++) { LIBTAG(ob->mat[a]); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 49dae2af168..9b4ed4d11a7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4096,7 +4096,7 @@ static void direct_link_object(FileData *fd, Object *ob) BLI_addhead(&ob->modifiers, hmd); BLI_remlink(&ob->hooks, hook); - modifier_unique_name(&ob->modifiers, hmd); + modifier_unique_name(&ob->modifiers, (ModifierData*)hmd); MEM_freeN(hook); } @@ -7662,7 +7662,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) BLI_addtail(&ob->modifiers, smd); - modifier_unique_name(&ob->modifiers, smd); + modifier_unique_name(&ob->modifiers, (ModifierData*)smd); } } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 55f95f451d2..ac47556c7f7 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -848,7 +848,7 @@ void special_editmenu(Scene *scene, View3D *v3d) BooleanModifierData *bmd = NULL; bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean); BLI_addtail(&ob->modifiers, bmd); - modifier_unique_name(&ob->modifiers, bmd); + modifier_unique_name(&ob->modifiers, (ModifierData*)bmd); bmd->object = base_select->object; bmd->modifier.mode |= eModifierMode_Realtime; switch(nr){ @@ -981,7 +981,7 @@ static void object_flip_subdivison_particles(Scene *scene, Object *ob, int *set, SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf); BLI_addtail(&ob->modifiers, smd); - modifier_unique_name(&ob->modifiers, smd); + modifier_unique_name(&ob->modifiers, (ModifierData*)smd); if (level!=-1) { smd->levels = level; diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 63182e943bb..4643b875872 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -480,7 +480,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode) hmd = (HookModifierData*) modifier_new(eModifierType_Hook); BLI_insertlinkbefore(&obedit->modifiers, md, hmd); sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2); - modifier_unique_name(&obedit->modifiers, hmd); + modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd); } else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */ -- cgit v1.2.3 From 2cf7d4867d4f6651fa54c3824f5e9f8f8a3e3770 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 9 Oct 2009 12:18:32 +0000 Subject: (Untested) String Replacement Function in blenlib Currently this hasn't been tested yet, but committing this first before I potentially use it for fixing RNA-paths... --- source/blender/blenlib/BLI_string.h | 12 ++++++ source/blender/blenlib/intern/string.c | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index bf93dc19cc5..53563f85eb9 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -68,6 +68,18 @@ char *BLI_strdupn(const char *str, int len); */ char *BLI_strncpy(char *dst, const char *src, int maxncpy); + /** + * Returns a copy of the cstring @a str into a newly mallocN'd + * string with all instances of oldText replaced with newText, + * and returns it. + * + * @param str The string to replace occurances of oldText in + * @param oldText The text in the string to find and replace + * @param newText The text in the string to find and replace + * @retval Returns the duplicated string + */ +char *BLI_replacestr(char *str, const char *oldText, const char *newText); + /* * Replacement for snprintf */ diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 4cd04aa232c..de4b53cbd93 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -100,6 +100,77 @@ char *BLI_sprintfN(const char *format, ...) return n; } +/* Replaces all occurances of oldText with newText in str, returning a new string that doesn't + * contain the 'replaced' occurances. + */ +// A rather wasteful string-replacement utility, though this shall do for now... +// Feel free to replace this with an even safe + nicer alternative +char *BLI_replacestr(char *str, const char *oldText, const char *newText) +{ + DynStr *ds= NULL; + int lenOld= strlen(oldText); + char *match; + + /* sanity checks */ + if ((str == NULL) || (str[0]==0)) + return NULL; + else if ((oldText == NULL) || (newText == NULL) || (oldText[0]==0)) + return BLI_strdup(str); + + /* while we can still find a match for the old substring that we're searching for, + * keep dicing and replacing + */ + while ( (match = strstr(str, oldText)) ) { + /* the assembly buffer only gets created when we actually need to rebuild the string */ + if (ds == NULL) + ds= BLI_dynstr_new(); + + /* if the match position does not match the current position in the string, + * copy the text up to this position and advance the current position in the string + */ + if (str != match) { + /* replace the token at the 'match' position with \0 so that the copied string will be ok, + * add the segment of the string from str to match to the buffer, then restore the value at match + */ + match[0]= 0; + BLI_dynstr_append(ds, str); + match[0]= oldText[0]; + + /* now our current position should be set on the start of the match */ + str= match; + } + + /* add the replacement text to the accumulation buffer */ + BLI_dynstr_append(ds, newText); + + /* advance the current position of the string up to the end of the replaced segment */ + str += lenOld; + } + + /* finish off and return a new string that has had all occurances of */ + if (ds) { + char *newStr; + + /* add what's left of the string to the assembly buffer + * - we've been adjusting str to point at the end of the replaced segments + */ + if (str != NULL) + BLI_dynstr_append(ds, str); + + /* convert to new c-string (MEM_malloc'd), and free the buffer */ + newStr= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + + return newStr; + } + else { + /* just create a new copy of the entire string - we avoid going through the assembly buffer + * for what should be a bit more efficiency... + */ + return BLI_strdup(str); + } +} + int BLI_streq(const char *a, const char *b) { return (strcmp(a, b)==0); -- cgit v1.2.3 From 3d771d88d85486800c9a4eae5b596215e816141d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 9 Oct 2009 12:34:37 +0000 Subject: wm menu freeing was using freed memory, bone-parent names were being set to "" on menu draw WHY??? - r23247, you know who you are ;) --- source/blender/editors/space_view3d/view3d_buttons.c | 1 - source/blender/windowmanager/intern/wm.c | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 2ce7da4c073..b5a0ca079bc 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1135,7 +1135,6 @@ static void view3d_panel_object(const bContext *C, Panel *pa) } else { if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) { - strcpy(ob->parsubstr, ""); uiBlockEndAlign(block); } } diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index dbb8fc400c0..5b7f892592b 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -162,13 +162,17 @@ void WM_menutype_freelink(MenuType* mt) void WM_menutype_free(void) { - MenuType* mt; + MenuType* mt= menutypes.first, *mt_next; + + while(mt) { + mt_next= mt->next; - for(mt= menutypes.first; mt; mt= mt->next) { - if(mt->ext.free) { + if(mt->ext.free) mt->ext.free(mt->ext.data); - } + WM_menutype_freelink(mt); + + mt= mt_next; } } -- cgit v1.2.3 From ae6c08ac5e7009dca591c39569a16802664dd0c4 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 9 Oct 2009 12:47:25 +0000 Subject: Wrong Tooltip for Continuous Grab. --- release/scripts/ui/space_userpref.py | 2 +- source/blender/makesrna/intern/rna_userdef.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 27c826b133b..7af8766e256 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -418,7 +418,7 @@ class USERPREF_PT_input(bpy.types.Panel): sub1 = sub.column() sub1.enabled = (view.select_mouse == 'RIGHT') sub1.itemR(view, "emulate_3_button_mouse") - sub.itemR(view, "continuous_mouse", text="Continuous Grab") + sub.itemR(view, "continuous_mouse") sub.itemL(text="Select With:") sub.row().itemR(view, "select_mouse", expand=True) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 3e3ed669e02..f8135f32eda 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1657,7 +1657,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop= RNA_def_property(srna, "continuous_mouse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_CONTINUOUS_MOUSE); - RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction."); + RNA_def_property_ui_text(prop, "Continuous Grab", "Experimental option to allow moving the mouse outside the view (Linux only at the moment)"); prop= RNA_def_property(srna, "global_pivot", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCKAROUND); -- cgit v1.2.3 From ca3e77813446a8fbdd654dff1e4f5739f462543b Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Fri, 9 Oct 2009 12:48:28 +0000 Subject: Cocoa port : - Fullscreen mode is back! - Cleaner fix for tablet events handling --- intern/ghost/intern/GHOST_SystemCocoa.h | 3 +- intern/ghost/intern/GHOST_SystemCocoa.mm | 310 +++++-------------------- intern/ghost/intern/GHOST_WindowCocoa.h | 24 +- intern/ghost/intern/GHOST_WindowCocoa.mm | 378 +++++++++++-------------------- 4 files changed, 204 insertions(+), 511 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index eab5a5b28aa..ee7f9d8ed37 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -210,9 +210,10 @@ protected: /** * Handles a tablet event. * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) + * @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event * @return Indication whether the event was handled. */ - GHOST_TSuccess handleTabletEvent(void *eventPtr); + GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType); /** * Handles a mouse event. diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 7f98f67a1ba..481dd705265 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -51,43 +51,6 @@ #pragma mark KeyMap, mouse converters -//TODO: remove (kept as reminder to implement window events) -/* -const EventTypeSpec kEvents[] = -{ - { kEventClassAppleEvent, kEventAppleEvent }, - -// { kEventClassApplication, kEventAppActivated }, -// { kEventClassApplication, kEventAppDeactivated }, - - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyRepeat }, - { kEventClassKeyboard, kEventRawKeyUp }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseMoved }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved }, - - { kEventClassWindow, kEventWindowClickZoomRgn } , // for new zoom behaviour - { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour - { kEventClassWindow, kEventWindowExpand } , // for new zoom behaviour - { kEventClassWindow, kEventWindowExpandAll }, // for new zoom behaviour - - { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowActivated }, - { kEventClassWindow, kEventWindowDeactivated }, - { kEventClassWindow, kEventWindowUpdate }, - { kEventClassWindow, kEventWindowBoundsChanged }, - - { kEventClassBlender, kEventBlenderNdofAxis }, - { kEventClassBlender, kEventBlenderNdofButtons } - - - -};*/ /* Keycodes from Carbon include file */ /* @@ -701,25 +664,6 @@ GHOST_TSuccess GHOST_SystemCocoa::init() } [pool drain]; - - /* - * Initialize the cursor to the standard arrow shape (so that we can change it later on). - * This initializes the cursor's visibility counter to 0. - */ - /*::InitCursor(); - - MenuRef windMenu; - ::CreateStandardWindowMenu(0, &windMenu); - ::InsertMenu(windMenu, 0); - ::DrawMenuBar(); - - ::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler); - - ::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false); - ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false); - ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false); - ::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false); - */ } return success; } @@ -789,6 +733,13 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_IWindow* window = 0; + //First check if we are in fullscreen mode + //If so, exit it before creating a new window + window = m_windowManager->getActiveWindow(); + if (window && (window->getState() == GHOST_kWindowStateFullScreen)) + window->setState(GHOST_kWindowStateNormal); + window = NULL; + //Get the available rect for including window contents NSRect frame = [[NSScreen mainScreen] visibleFrame]; NSRect contentRect = [NSWindow contentRectForFrameRect:frame @@ -826,27 +777,18 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual) { - GHOST_TSuccess success = GHOST_kFailure; + GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow(); - //TODO: update this method - // need yo make this Carbon all on 10.5 for fullscreen to work correctly - CGCaptureAllDisplays(); - - success = GHOST_System::beginFullScreen( setting, window, stereoVisual); + *window = currentWindow; - if( success != GHOST_kSuccess ) { - // fullscreen failed for other reasons, release - CGReleaseAllDisplays(); - } - - return success; + return currentWindow->setState(GHOST_kWindowStateFullScreen); } GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void) { - //TODO: update this method - CGReleaseAllDisplays(); - return GHOST_System::endFullScreen(); + GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow(); + + return currentWindow->setState(GHOST_kWindowStateNormal); } @@ -936,8 +878,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) anyProcessed = true; } - //TODO: check fullscreen redrawing issues - if (getFullScreen()) { + if (getFullScreen()) { // Check if the full-screen window is dirty GHOST_IWindow* window = m_windowManager->getFullScreenWindow(); if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) { @@ -987,7 +928,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) case NSTabletPoint: case NSTabletProximity: - handleTabletEvent(event); + handleTabletEvent(event,[event type]); break; /* Trackpad features, will need OS X 10.6 for implementation @@ -1028,8 +969,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, if (!validWindow(window)) { return GHOST_kFailure; } - - //if (!getFullScreen()) { switch(eventType) { case GHOST_kEventWindowClose: @@ -1045,7 +984,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) ); break; case GHOST_kEventWindowUpdate: - //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n"); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) ); break; case GHOST_kEventWindowSize: @@ -1059,12 +997,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, return GHOST_kFailure; break; } -// } - //else { - //window = (GHOST_WindowCarbon*) m_windowManager->getFullScreenWindow(); - //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n"); - //::RemoveEventFromQueue(::GetMainEventQueue(), event); - //} return GHOST_kSuccess; } @@ -1073,6 +1005,13 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() //Check open windows if some changes are not saved if (m_windowManager->getAnyModifiedState()) { + //First check if we are in fullscreen mode + //If so, exit it before creating a new window + GHOST_IWindow *window = m_windowManager->getActiveWindow(); + if (window && (window->getState() == GHOST_kWindowStateFullScreen)) + window->setState(GHOST_kWindowStateNormal); + window = NULL; + int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?", @"Cancel", @"Quit anyway", nil); if (shouldQuit == NSAlertAlternateReturn) @@ -1090,35 +1029,13 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() } -GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) +GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData(); - NSUInteger tabletEvent; - - //Handle tablet events combined with mouse events - @try { - switch ([event subtype]) { - case NX_SUBTYPE_TABLET_POINT: - tabletEvent = NSTabletPoint; - break; - case NX_SUBTYPE_TABLET_PROXIMITY: - tabletEvent = NSTabletProximity; - break; - - default: - tabletEvent = [event type]; - break; - } - } - @catch (NSException * e) { - //FIXME: check why we get such exceptions when using a tablet - return GHOST_kFailure; - } - - switch (tabletEvent) { + switch (eventType) { case NSTabletPoint: ct.Pressure = [event tangentialPressure]; ct.Xtilt = [event tilt].x; @@ -1175,20 +1092,53 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSRightMouseDown: case NSOtherMouseDown: pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber]))); - handleTabletEvent(eventPtr); + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + handleTabletEvent(eventPtr, NSTabletPoint); + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + handleTabletEvent(eventPtr, NSTabletProximity); + break; + default: + //No tablet event included : do nothing + break; + } break; case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber]))); - handleTabletEvent(eventPtr); + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + handleTabletEvent(eventPtr, NSTabletPoint); + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + handleTabletEvent(eventPtr, NSTabletProximity); + break; + default: + //No tablet event included : do nothing + break; + } break; case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: - handleTabletEvent(eventPtr); + //Handle tablet events combined with mouse events + switch ([event subtype]) { + case NX_SUBTYPE_TABLET_POINT: + handleTabletEvent(eventPtr, NSTabletPoint); + break; + case NX_SUBTYPE_TABLET_PROXIMITY: + handleTabletEvent(eventPtr, NSTabletProximity); + break; + default: + //No tablet event included : do nothing + break; + } case NSMouseMoved: { NSPoint mousePos = [event locationInWindow]; @@ -1227,6 +1177,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) * the window go away and we still get an HKey up. */ if (!window) { + printf("\nW failure"); return GHOST_kFailure; } @@ -1246,7 +1197,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask)) break; //Cmd-Q is directly handled by Cocoa - + if ([event type] == NSKeyDown) { pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) ); //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii); @@ -1282,143 +1233,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) } -/* System wide mouse clicks are handled directly through systematic event forwarding to Cocoa -bool GHOST_SystemCarbon::handleMouseDown(void *eventPtr) -{ - NSEvent *event = (NSEvent *)eventPtr; - WindowPtr window; - short part; - BitMap screenBits; - bool handled = true; - GHOST_WindowCarbon* ghostWindow; - Point mousePos = {0 , 0}; - - ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos); - - part = ::FindWindow(mousePos, &window); - ghostWindow = (GHOST_WindowCarbon*) ::GetWRefCon(window); - - switch (part) { - case inMenuBar: - handleMenuCommand(::MenuSelect(mousePos)); - break; - - case inDrag: - // * - // * The DragWindow() routine creates a lot of kEventWindowBoundsChanged - // * events. By setting m_ignoreWindowSizedMessages these are suppressed. - // * @see GHOST_SystemCarbon::handleWindowEvent(EventRef event) - // * - // even worse: scale window also generates a load of events, and nothing - // is handled (read: client's event proc called) until you release mouse (ton) - - GHOST_ASSERT(validWindow(ghostWindow), "GHOST_SystemCarbon::handleMouseDown: invalid window"); - m_ignoreWindowSizedMessages = true; - ::DragWindow(window, mousePos, &GetQDGlobalsScreenBits(&screenBits)->bounds); - m_ignoreWindowSizedMessages = false; - - pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, ghostWindow) ); - - break; - - case inContent: - if (window != ::FrontWindow()) { - ::SelectWindow(window); - // - // * We add a mouse down event on the newly actived window - // * - //GHOST_PRINT("GHOST_SystemCarbon::handleMouseDown(): adding mouse down event, " << ghostWindow << "\n"); - EventMouseButton button; - ::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button); - pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonDown, ghostWindow, convertButton(button))); - } else { - handled = false; - } - break; - - case inGoAway: - GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0"); - if (::TrackGoAway(window, mousePos)) - { - // todo: add option-close, because itÿs in the HIG - // if (event.modifiers & optionKey) { - // Close the clean documents, others will be confirmed one by one. - //} - // else { - pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, ghostWindow)); - //} - } - break; - - case inGrow: - GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0"); - ::ResizeWindow(window, mousePos, NULL, NULL); - break; - - case inZoomIn: - case inZoomOut: - GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0"); - if (::TrackBox(window, mousePos, part)) { - int macState; - - macState = ghostWindow->getMac_windowState(); - if ( macState== 0) - ::ZoomWindow(window, part, true); - else - if (macState == 2) { // always ok - ::ZoomWindow(window, part, true); - ghostWindow->setMac_windowState(1); - } else { // need to force size again - // GHOST_TUns32 scr_x,scr_y; //unused - Rect outAvailableRect; - - ghostWindow->setMac_windowState(2); - ::GetAvailableWindowPositioningBounds ( GetMainDevice(), &outAvailableRect); - - //this->getMainDisplayDimensions(scr_x,scr_y); - ::SizeWindow (window, outAvailableRect.right-outAvailableRect.left,outAvailableRect.bottom-outAvailableRect.top-1,false); - ::MoveWindow (window, outAvailableRect.left, outAvailableRect.top,true); - } - - } - break; - - default: - handled = false; - break; - } - - return handled; -} - - -bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult) -{ - short menuID; - short menuItem; - UInt32 command; - bool handled; - OSErr err; - - menuID = HiWord(menuResult); - menuItem = LoWord(menuResult); - - err = ::GetMenuItemCommandID(::GetMenuHandle(menuID), menuItem, &command); - - handled = false; - - if (err || command == 0) { - } - else { - switch(command) { - } - } - - ::HiliteMenu(0); - return handled; -}*/ - - #pragma mark Clipboard get/set diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 5ff205d964f..8c2919d1ce2 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -70,7 +70,7 @@ public: * @param stereoVisual Stereo visual for quad buffered stereo. */ GHOST_WindowCocoa( - const GHOST_SystemCocoa *systemCocoa, + GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, @@ -204,16 +204,6 @@ public: virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const; - /** - * Returns the dirty state of the window when in full-screen mode. - * @return Whether it is dirty. - */ - virtual bool getFullScreenDirty(); - - /* accessor for fullscreen window */ - /*virtual void setMac_windowState(short value); - virtual short getMac_windowState();*/ - const GHOST_TabletData* GetTabletData() { return &m_tablet; } @@ -270,19 +260,13 @@ protected: /** The opgnGL drawing context */ NSOpenGLContext *m_openGLContext; - //CGrafPtr m_grafPtr; - //AGLContext m_aglCtx; - - /** The first created OpenGL context (for sharing display lists) */ - //static AGLContext s_firstaglCtx; - + /** The mother SystemCocoa class to send events */ + GHOST_SystemCocoa *m_systemCocoa; + NSCursor* m_customCursor; GHOST_TabletData m_tablet; - /** When running in full-screen this tells whether to refresh the window. */ - bool m_fullScreenDirty; - /** * The width/height of the size rectangle in the lower right corner of a * Mac/Carbon window. This is also the height of the gutter area. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index a185aa036b1..f4c9172c668 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -32,57 +32,20 @@ #include "GHOST_WindowCocoa.h" #include "GHOST_SystemCocoa.h" #include "GHOST_Debug.h" -/* -AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL; -#ifdef GHOST_DRAW_CARBON_GUTTER -const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16; -#endif //GHOST_DRAW_CARBON_GUTTER - -static const GLint sPreferredFormatWindow[8] = { -AGL_RGBA, -AGL_DOUBLEBUFFER, -AGL_ACCELERATED, -AGL_DEPTH_SIZE, 32, -AGL_NONE, -}; - -static const GLint sPreferredFormatFullScreen[9] = { -AGL_RGBA, -AGL_DOUBLEBUFFER, -AGL_ACCELERATED, -AGL_FULLSCREEN, -AGL_DEPTH_SIZE, 32, -AGL_NONE, -}; - -WindowRef ugly_hack=NULL; - -const EventTypeSpec kWEvents[] = { - { kEventClassWindow, kEventWindowZoom }, // for new zoom behaviour +// Pixel Format Attributes for the windowed NSOpenGLContext +static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = +{ + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAAccelerated, + NSOpenGLPFAAllowOfflineRenderers, // NOTE: Needed to connect to secondary GPUs + NSOpenGLPFADepthSize, 32, + 0 }; -static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) { - WindowRef mywindow; - GHOST_WindowCocoa *ghost_window; - OSStatus err; - int theState; - - if (::GetEventKind(event) == kEventWindowZoom) { - err = ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow); - ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow); - theState = ghost_window->getMac_windowState(); - if (theState == 1) - ghost_window->setMac_windowState(2); - else if (theState == 2) - ghost_window->setMac_windowState(1); - - } - return eventNotHandledErr; -}*/ - #pragma mark Cocoa delegate object + @interface CocoaWindowDelegate : NSObject { GHOST_SystemCocoa *systemCocoa; @@ -116,7 +79,10 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, - (void)windowDidResignKey:(NSNotification *)notification { - systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); + //The window is no more key when its own view becomes fullscreen + //but ghost doesn't know the view/window difference, so hide this fact + if (associatedWindow->getState() != GHOST_kWindowStateFullScreen) + systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow); } - (void)windowDidUpdate:(NSNotification *)notification @@ -159,7 +125,7 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, #pragma mark initialization / finalization GHOST_WindowCocoa::GHOST_WindowCocoa( - const GHOST_SystemCocoa *systemCocoa, + GHOST_SystemCocoa *systemCocoa, const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, @@ -170,136 +136,55 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( const bool stereoVisual ) : GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone), - m_customCursor(0), - m_fullScreenDirty(false) + m_customCursor(0) { + m_systemCocoa = systemCocoa; + m_fullScreen = false; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - //fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width); - /* - if (state >= GHOST_kWindowState8Normal ) { - if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal; - else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized; - else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized; - else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen; - - // state = state - 8; this was the simple version of above code, doesnt work in gcc 4.0 - - setMac_windowState(1); - } else - setMac_windowState(0); -*/ - if (state != GHOST_kWindowStateFullScreen) { - - //Creates the window - NSRect rect; - - rect.origin.x = left; - rect.origin.y = top; - rect.size.width = width; - rect.size.height = height; - - m_window = [[NSWindow alloc] initWithContentRect:rect - styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask - backing:NSBackingStoreBuffered defer:NO]; - if (m_window == nil) { - [pool drain]; - return; - } - - [m_window setTitle:[NSString stringWithUTF8String:title]]; - - - //Creates the OpenGL View inside the window - NSOpenGLPixelFormatAttribute attributes[] = - { - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAAccelerated, - NSOpenGLPFAAllowOfflineRenderers, // NOTE: Needed to connect to secondary GPUs - NSOpenGLPFADepthSize, 32, - 0 - }; - - NSOpenGLPixelFormat *pixelFormat = - [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - - m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect - pixelFormat:pixelFormat]; - - [pixelFormat release]; - - m_openGLContext = [m_openGLView openGLContext]; - - [m_window setContentView:m_openGLView]; - [m_window setInitialFirstResponder:m_openGLView]; - - [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window - - [m_window makeKeyAndOrderFront:nil]; - - setDrawingContextType(type); - updateDrawingContext(); - activateDrawingContext(); - - // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/ - /*gen2mac(title, title255); - - - err = ::CreateNewWindow( kDocumentWindowClass, - kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute, - &bnds, - &m_windowRef); - - if ( err != noErr) { - fprintf(stderr," error creating window %i \n",(int)err); - } else { + + //Creates the window + NSRect rect; + + rect.origin.x = left; + rect.origin.y = top; + rect.size.width = width; + rect.size.height = height; + + m_window = [[NSWindow alloc] initWithContentRect:rect + styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask + backing:NSBackingStoreBuffered defer:NO]; + if (m_window == nil) { + [pool drain]; + return; + } + + [m_window setTitle:[NSString stringWithUTF8String:title]]; + - ::SetWRefCon(m_windowRef,(SInt32)this); - setTitle(title); - err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL); - if ( err != noErr) { - fprintf(stderr," error creating handler %i \n",(int)err); - } else { - // ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL); - ::ShowWindow(m_windowRef); - ::MoveWindow (m_windowRef, left, top,true); - - } - } - if (m_windowRef) { - m_grafPtr = ::GetWindowPort(m_windowRef); - setDrawingContextType(type); - updateDrawingContext(); - activateDrawingContext(); - } - if(ugly_hack==NULL) { - ugly_hack= m_windowRef; - // when started from commandline, window remains in the back... also for play anim - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - SetFrontProcess(&psn); - }*/ - } - else { - /* - Rect bnds = { top, left, top+height, left+width }; - gen2mac("", title255); - m_windowRef = ::NewCWindow( - nil, // Storage - &bnds, // Bounding rectangle of the window - title255, // Title of the window - 0, // Window initially visible - plainDBox, // procID - (WindowRef)-1L, // Put window before all other windows - 0, // Window has minimize box - (SInt32)this); // Store a pointer to the class in the refCon - */ - //GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n"); - setDrawingContextType(GHOST_kDrawingContextTypeOpenGL); - installDrawingContext(GHOST_kDrawingContextTypeOpenGL); - updateDrawingContext(); - activateDrawingContext(); - } + //Creates the OpenGL View inside the window + NSOpenGLPixelFormat *pixelFormat = + [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow]; + + m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect + pixelFormat:pixelFormat]; + + [pixelFormat release]; + + m_openGLContext = [m_openGLView openGLContext]; + + [m_window setContentView:m_openGLView]; + [m_window setInitialFirstResponder:m_openGLView]; + + [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window + + [m_window makeKeyAndOrderFront:nil]; + + setDrawingContextType(type); + updateDrawingContext(); + activateDrawingContext(); + m_tablet.Active = GHOST_kTabletModeNone; CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; @@ -308,6 +193,9 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( [m_window setAcceptsMouseMovedEvents:YES]; + if (state == GHOST_kWindowStateFullScreen) + setState(GHOST_kWindowStateFullScreen); + [pool drain]; } @@ -401,19 +289,30 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid") NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSRect screenSize = [[m_window screen] visibleFrame]; + + if (!m_fullScreen) + { + NSRect screenSize = [[m_window screen] visibleFrame]; - //Max window contents as screen size (excluding title bar...) - NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize - styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + //Max window contents as screen size (excluding title bar...) + NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; - rect = [m_window contentRectForFrameRect:[m_window frame]]; - - bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); - bounds.m_l = rect.origin.x -contentRect.origin.x; - bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; - bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); - + rect = [m_window contentRectForFrameRect:[m_window frame]]; + + bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); + bounds.m_l = rect.origin.x -contentRect.origin.x; + bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; + bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); + } + else { + NSRect screenSize = [[m_window screen] frame]; + + bounds.m_b = screenSize.origin.y + screenSize.size.height; + bounds.m_l = screenSize.origin.x; + bounds.m_r = screenSize.origin.x + screenSize.size.width; + bounds.m_t = screenSize.origin.y; + } [pool drain]; } @@ -469,7 +368,10 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid") NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_TWindowState state; - if ([m_window isMiniaturized]) { + if (m_fullScreen) { + state = GHOST_kWindowStateFullScreen; + } + else if ([m_window isMiniaturized]) { state = GHOST_kWindowStateMinimized; } else if ([m_window isZoomed]) { @@ -521,15 +423,50 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid") switch (state) { - case GHOST_kWindowStateMinimized: + case GHOST_kWindowStateMinimized: [m_window miniaturize:nil]; break; - case GHOST_kWindowStateMaximized: + case GHOST_kWindowStateMaximized: [m_window zoom:nil]; break; - case GHOST_kWindowStateNormal: + + case GHOST_kWindowStateFullScreen: + if (!m_fullScreen) + { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + //This status change needs to be done before Cocoa call to enter fullscreen mode + //to give window delegate hint not to forward its deactivation to ghost wm that doesn't know view/window difference + m_fullScreen = true; + + //Only 10.6 API will enable to manage several display in fullscreen mode, and topmenu autoshow + [m_openGLView enterFullScreenMode:[m_window screen] withOptions:nil]; + + //Tell WM of view new size + m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this); + + [pool drain]; + } + break; + case GHOST_kWindowStateNormal: default: - if ([m_window isMiniaturized]) + if (m_fullScreen) + { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + m_fullScreen = false; + + //Exit fullscreen + [m_openGLView exitFullScreenModeWithOptions:nil]; + + [m_window makeKeyAndOrderFront:nil]; + [m_window makeFirstResponder:m_openGLView]; + + //Tell WM of view new size + m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this); + + [pool drain]; + } + else if ([m_window isMiniaturized]) [m_window deminiaturize:nil]; else if ([m_window isZoomed]) [m_window zoom:nil]; @@ -540,8 +477,11 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [m_window setDocumentEdited:isUnsavedChanges]; + [pool drain]; return GHOST_Window::setModifiedState(isUnsavedChanges); } @@ -631,12 +571,11 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp case GHOST_kDrawingContextTypeOpenGL: if (!getValid()) break; - if(!m_fullScreen) - { pixelFormat = [m_openGLView pixelFormat]; tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_openGLContext]; if (tmpOpenGLContext == nil) + success = GHOST_kFailure; break; #ifdef WAIT_FOR_VSYNC /* wait for vsync, to avoid tearing artifacts */ @@ -645,37 +584,8 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp [m_openGLView setOpenGLContext:tmpOpenGLContext]; [tmpOpenGLContext setView:m_openGLView]; - //[m_openGLContext release]; + [m_openGLContext release]; m_openGLContext = tmpOpenGLContext; - } - /* - AGLPixelFormat pixelFormat; - if (!m_fullScreen) { - pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow); - m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx); - if (!m_aglCtx) break; - if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx; - success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure; - } - else { - //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n"); -GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen); - m_aglCtx = ::aglCreateContext(pixelFormat, 0); - if (!m_aglCtx) break; - if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx; - //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n"); - //::CGGetActiveDisplayList(0, NULL, &m_numDisplays) - success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure; - - if (success == GHOST_kSuccess) { - GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n"); - } - else { - GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n"); - } - - } - ::aglDestroyPixelFormat(pixelFormat);*/ break; case GHOST_kDrawingContextTypeNone: @@ -696,14 +606,16 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext() switch (m_drawingContextType) { case GHOST_kDrawingContextTypeOpenGL: [m_openGLView clearGLContext]; + [pool drain]; return GHOST_kSuccess; case GHOST_kDrawingContextTypeNone: + [pool drain]; return GHOST_kSuccess; break; default: + [pool drain]; return GHOST_kFailure; } - [pool drain]; } @@ -711,20 +623,7 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate() { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid") NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (!m_fullScreen) { - [m_openGLView setNeedsDisplay:YES]; - } - else { - //EventRef event; - //OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event); - //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n"); - //status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this); - //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n"); - //status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard); - //status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget()); - //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n"); - m_fullScreenDirty = true; - } + [m_openGLView setNeedsDisplay:YES]; [pool drain]; return GHOST_kSuccess; } @@ -803,11 +702,6 @@ void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) c } -bool GHOST_WindowCocoa::getFullScreenDirty() -{ - return m_fullScreen && m_fullScreenDirty; -} - GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) { -- cgit v1.2.3 From 3b8925c65505c1125a07da60a901ffb2fb21e9b0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 13:25:54 +0000 Subject: Particle Edit Mode: * Fix crash trying to enter particle mode when the particle modifier is disabled in the stack. * Fix redraw being very slow due to the draw function causing the object to be recalculated on each redraw (through PE_draw_object). * Removed the system where PE_get_current would automatically create the particle edit, this would run from poll() functions, which gave all kinds of issues, now it only creates the data on enter/exit and switching active particle system. --- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/editors/include/ED_particle.h | 2 ++ source/blender/editors/physics/particle_edit.c | 39 ++++++++++++++++++-------- source/blender/makesrna/intern/rna_object.c | 13 +++++++-- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9b4ed4d11a7..184b584d188 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3918,7 +3918,7 @@ static void direct_link_object(FileData *fd, Object *ob) ob->flag &= ~OB_FROMGROUP; /* editmode doesn't get saved in files, so should get cleared when reloading... */ - ob->mode &= ~OB_MODE_EDIT; + ob->mode &= ~(OB_MODE_EDIT|OB_MODE_PARTICLE_EDIT); ob->disp.first=ob->disp.last= NULL; diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index 3d7fc5ea15b..fcdaf8cb59d 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -46,6 +46,8 @@ int PE_start_edit(struct PTCacheEdit *edit); /* access */ struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob); +struct PTCacheEdit *PE_create_current(struct Scene *scene, struct Object *ob); +void PE_current_changed(struct Scene *scene, struct Object *ob); int PE_minmax(struct Scene *scene, float *min, float *max); struct ParticleEditSettings *PE_settings(struct Scene *scene); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index ac47ddebc1f..e3f54158fbb 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -194,7 +194,7 @@ ParticleEditSettings *PE_settings(Scene *scene) } /* always gets atleast the first particlesystem even if PSYS_CURRENT flag is not set */ -PTCacheEdit *PE_get_current(Scene *scene, Object *ob) +static PTCacheEdit *pe_get_current(Scene *scene, Object *ob, int create) { ParticleEditSettings *pset= PE_settings(scene); PTCacheEdit *edit = NULL; @@ -232,18 +232,18 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) if(psys->flag & PSYS_CURRENT) { if(psys->part && psys->part->type == PART_HAIR) { if(psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) { - if(!psys->pointcache->edit) + if(create && !psys->pointcache->edit) PE_create_particle_edit(scene, ob, pid->cache, NULL); edit = pid->cache->edit; } else { - if(!psys->edit && psys->flag & PSYS_HAIR_DONE) + if(create && !psys->edit && psys->flag & PSYS_HAIR_DONE) PE_create_particle_edit(scene, ob, NULL, psys); edit = psys->edit; } } else { - if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) PE_create_particle_edit(scene, ob, pid->cache, psys); edit = pid->cache->edit; } @@ -252,13 +252,13 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) } } else if(pset->edittype == PE_TYPE_SOFTBODY && pid->type == PTCACHE_TYPE_SOFTBODY) { - if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) PE_create_particle_edit(scene, ob, pid->cache, NULL); edit = pid->cache->edit; break; } else if(pset->edittype == PE_TYPE_CLOTH && pid->type == PTCACHE_TYPE_CLOTH) { - if(pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) + if(create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) PE_create_particle_edit(scene, ob, pid->cache, NULL); edit = pid->cache->edit; break; @@ -273,6 +273,22 @@ PTCacheEdit *PE_get_current(Scene *scene, Object *ob) return edit; } +PTCacheEdit *PE_get_current(Scene *scene, Object *ob) +{ + return pe_get_current(scene, ob, 0); +} + +PTCacheEdit *PE_create_current(Scene *scene, Object *ob) +{ + return pe_get_current(scene, ob, 1); +} + +void PE_current_changed(Scene *scene, Object *ob) +{ + if(ob->mode == OB_MODE_PARTICLE_EDIT) + PE_create_current(scene, ob); +} + void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra) { ParticleEditSettings *pset=PE_settings(scene); @@ -1195,8 +1211,6 @@ void PE_update_object(Scene *scene, Object *ob, int useflag) if(edit->psys) edit->psys->flag &= ~PSYS_HAIR_UPDATED; - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); } /************************************************/ @@ -2409,7 +2423,6 @@ static int delete_exec(bContext *C, wmOperator *op) } PE_update_object(data.scene, data.ob, 0); - DAG_id_flush_update(&data.ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE_DATA, data.ob); @@ -3734,13 +3747,15 @@ int PE_minmax(Scene *scene, float *min, float *max) /* initialize needed data for bake edit */ static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys) { - PTCacheEdit *edit= psys ? psys->edit : cache->edit; + PTCacheEdit *edit= (psys)? psys->edit : cache->edit; + ParticleSystemModifierData *psmd= (psys)? psys_get_modifier(ob, psys): NULL; POINT_P; KEY_K; ParticleData *pa = NULL; HairKey *hkey; int totpoint; - if(!psys && !cache) + /* no psmd->dm happens in case particle system modifier is not enabled */ + if(!(psys && psmd && psmd->dm) && !cache) return; if(cache && cache->flag & PTCACHE_DISK_CACHE) @@ -3850,10 +3865,12 @@ static int particle_edit_toggle_poll(bContext *C) static int particle_edit_toggle_exec(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_active_object(C); if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { ob->mode |= OB_MODE_PARTICLE_EDIT; + PE_create_current(scene, ob); toggle_particle_cursor(C, 1); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL); } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 694eb7e23e4..611585c8809 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -102,6 +102,7 @@ EnumPropertyItem object_type_items[] = { #include "BLI_editVert.h" /* for EditMesh->mat_nr */ #include "ED_object.h" +#include "ED_particle.h" void rna_Object_update(bContext *C, PointerRNA *ptr) { @@ -460,12 +461,20 @@ static int rna_Object_active_particle_system_index_get(PointerRNA *ptr) return psys_get_current_num(ob); } -static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr, int value) +static void rna_Object_active_particle_system_index_set(PointerRNA *ptr, int value) { Object *ob= (Object*)ptr->id.data; psys_set_current_num(ob, value); } +static void rna_Object_particle_update(bContext *C, PointerRNA *ptr) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= (Object*)ptr->id.data; + + PE_current_changed(scene, ob); +} + /* rotation - axis-angle */ static void rna_Object_rotation_axis_angle_get(PointerRNA *ptr, float *value) { @@ -1418,7 +1427,7 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "active_particle_system_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_funcs(prop, "rna_Object_active_particle_system_index_get", "rna_Object_active_particle_system_index_set", "rna_Object_active_particle_system_index_range"); RNA_def_property_ui_text(prop, "Active Particle System Index", "Index of active particle system slot."); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_particle_update"); /* restrict */ prop= RNA_def_property(srna, "restrict_view", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From 105a53a29d3da99625b894ba13769fefb53e0974 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 9 Oct 2009 13:34:24 +0000 Subject: Bugfix for crash when clicking on "View->Properties". Was accessing unused memory here (uiBlock *block is uninitialized). If there is the need of uiBlockEndAlign() please get the valid uiBlock pointer from somewhere! --- source/blender/editors/space_view3d/view3d_buttons.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index b5a0ca079bc..0cdf849d453 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1130,7 +1130,7 @@ static void view3d_panel_object(const bContext *C, Panel *pa) tfp= v3d->properties_storage; // XXX uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - + /* if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) { } else { @@ -1138,6 +1138,7 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiBlockEndAlign(block); } } + */ lim= 10000.0f*MAX2(1.0, v3d->grid); -- cgit v1.2.3 From cbd511743286b9af79e3deb86b9157fea3ec8eac Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 9 Oct 2009 13:56:35 +0000 Subject: * Show Smoke Field Weights only for Domains. --- release/scripts/ui/buttons_physics_smoke.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release/scripts/ui/buttons_physics_smoke.py b/release/scripts/ui/buttons_physics_smoke.py index 53a7ec9c10c..b1523148a30 100644 --- a/release/scripts/ui/buttons_physics_smoke.py +++ b/release/scripts/ui/buttons_physics_smoke.py @@ -178,7 +178,8 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel): __default_closed__ = True def poll(self, context): - return (context.smoke) + smoke = context.smoke + return (smoke and smoke.smoke_type == 'TYPE_DOMAIN') def draw(self, context): domain = context.smoke.domain_settings -- cgit v1.2.3 From 8c96e2f4d284f76b6e0bdfbbd5fa9d1bc34b28ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 9 Oct 2009 14:35:54 +0000 Subject: - added ramp diffuse & spec factor rna props - made 3dspace camera editable - convert in object menu --- release/scripts/ui/buttons_material.py | 4 ++++ release/scripts/ui/space_view3d.py | 2 ++ source/blender/makesrna/intern/rna_material.c | 11 +++++++++++ source/blender/makesrna/intern/rna_space.c | 1 + 4 files changed, 18 insertions(+) diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index 03e11e003e2..fbd2df381e0 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -306,6 +306,8 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel): split = row.split(percentage=0.3) split.itemL(text="Blend:") split.itemR(mat, "diffuse_ramp_blend", text="") + row = layout.row() + row.itemR(mat, "diffuse_ramp_factor", text="Factor") class MATERIAL_PT_specular(MaterialButtonsPanel): __label__ = "Specular" @@ -358,6 +360,8 @@ class MATERIAL_PT_specular(MaterialButtonsPanel): split = row.split(percentage=0.3) split.itemL(text="Blend:") split.itemR(mat, "specular_ramp_blend", text="") + row = layout.row() + row.itemR(mat, "specular_ramp_factor", text="Factor") class MATERIAL_PT_sss(MaterialButtonsPanel): __label__ = "Subsurface Scattering" diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index ecc4d298b94..33ae3472053 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -422,6 +422,8 @@ class VIEW3D_MT_object(bpy.types.Menu): layout.itemM("VIEW3D_MT_object_showhide") + layout.item_menu_enumO("object.convert", "target") + class VIEW3D_MT_object_clear(bpy.types.Menu): __label__ = "Clear" diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index b22b5916362..3366bc04c70 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -763,6 +763,17 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_ui_text(prop, "Specular Ramp Input", ""); RNA_def_property_update(prop, 0, "rna_Material_update"); + prop= RNA_def_property(srna, "diffuse_ramp_factor", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "rampfac_col"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Diffuse Ramp Factor", "Blending factor (also uses alpha in Colorband)."); + RNA_def_property_update(prop, 0, "rna_Material_update"); + + prop= RNA_def_property(srna, "specular_ramp_factor", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "rampfac_spec"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Specular Ramp Factor", "Blending factor (also uses alpha in Colorband)."); + RNA_def_property_update(prop, 0, "rna_Material_update"); } static void rna_def_material_diffuse(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 422283c940f..f2ab9360856 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -593,6 +593,7 @@ static void rna_def_space_3dview(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data"); prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_sdna(prop, NULL, "camera"); RNA_def_property_ui_text(prop, "Camera", "Active camera used in this view (when unlocked from the scene's active camera)."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); -- cgit v1.2.3 From 8f57b368ca89b8fdd6e2c3bd4f0adf145ab820a1 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Fri, 9 Oct 2009 14:42:36 +0000 Subject: Cocoa : Implement OS X support for Campbell's new continuous grab feature --- intern/ghost/intern/GHOST_SystemCocoa.mm | 27 +++++++++++++---- intern/ghost/intern/GHOST_WindowCocoa.h | 7 +++++ intern/ghost/intern/GHOST_WindowCocoa.mm | 50 ++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 481dd705265..2dfdcf7bcec 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -798,7 +798,7 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3 { NSPoint mouseLoc = [NSEvent mouseLocation]; - // Convert the coordinates to screen coordinates + // Returns the mouse location in screen coordinates x = (GHOST_TInt32)mouseLoc.x; y = (GHOST_TInt32)mouseLoc.y; return GHOST_kSuccess; @@ -808,7 +808,10 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3 GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const { float xf=(float)x, yf=(float)y; - + + //Quartz Display Services uses the old coordinates (top left origin) + yf = [[NSScreen mainScreen] frame].size.height -yf; + CGAssociateMouseAndMouseCursorPosition(false); CGWarpMouseCursorPosition(CGPointMake(xf, yf)); CGAssociateMouseAndMouseCursorPosition(true); @@ -1080,7 +1083,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; - GHOST_IWindow* window = m_windowManager->getActiveWindow(); + GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow(); if (!window) { return GHOST_kFailure; @@ -1141,8 +1144,22 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } case NSMouseMoved: { - NSPoint mousePos = [event locationInWindow]; - pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y)); + if(window->getCursorWarp()) { + GHOST_TInt32 x_warp, y_warp, x_accum, y_accum; + + window->getCursorWarpPos(x_warp, y_warp); + + window->getCursorWarpAccum(x_accum, y_accum); + x_accum += [event deltaX]; + y_accum += [event deltaY]; + window->setCursorWarpAccum(x_accum, y_accum); + + pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum)); + } + else { //Normal cursor operation: send mouse position in window + NSPoint mousePos = [event locationInWindow]; + pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y)); + } break; } diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 8c2919d1ce2..7a39d9ab54a 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -236,6 +236,13 @@ protected: */ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible); + /** + * Sets the cursor grab on the window using + * native window system calls. + * @param warp Only used when grab is enabled, hides the mouse and allows gragging outside the screen. + */ + virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore); + /** * Sets the cursor shape on the window using * native window system calls. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index f4c9172c668..1d604553cc1 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -711,6 +711,56 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) return GHOST_kSuccess; } + +GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore) +{ + if (grab) + { + if(warp) { + m_systemCocoa->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + + setCursorWarpAccum(0, 0); + setWindowCursorVisibility(false); + m_cursorWarp= true; + } + return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; + } + else { + if(m_cursorWarp) + {/* are we exiting warp */ + setWindowCursorVisibility(true); + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + if(restore) { + GHOST_Rect bounds; + GHOST_TInt32 x_new, y_new, x_rel, y_rel; + + getClientBounds(bounds); + printf("\ncursor ungrab with restore"); + x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0]; + y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1]; + + screenToClient(x_new, y_new, x_rel, y_rel); + + if(x_rel < 0) x_new = (x_new-x_rel) + 2; + if(y_rel < 0) y_new = (y_new-y_rel) + 2; + if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2; + if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2; + + clientToScreen(x_new, y_new, x_rel, y_rel); + m_systemCocoa->setCursorPosition(x_rel, y_rel); + + } + else { + m_systemCocoa->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + } + + setCursorWarpAccum(0, 0); + m_cursorWarp= false; + } + return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; + } + +} GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape) { -- cgit v1.2.3 From dfbe2f9974f8e6d45d821fc6a16e7d3d32cd5faa Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 15:09:21 +0000 Subject: Fix for crash when saving a render result image, then rendering again. The saved image would still point to the render buffer, which was freed again on render. This is not a real solution but avoids the crash for now. --- source/blender/editors/space_image/image_ops.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 91316fba4d0..d5bd736f307 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -813,12 +813,25 @@ static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOpera ibuf->userflags &= ~IB_BITMAPDIRTY; /* change type? */ + if(ima->type==IMA_TYPE_R_RESULT) { + ima->type= IMA_TYPE_IMAGE; + + /* workaround to ensure the render result buffer is no longer used + * by this image, otherwise can crash when a new render result is + * created. */ + if(ibuf->rect && !(ibuf->mall & IB_rect)) + imb_freerectImBuf(ibuf); + if(ibuf->rect_float && !(ibuf->mall & IB_rectfloat)) + imb_freerectfloatImBuf(ibuf); + if(ibuf->zbuf && !(ibuf->mall & IB_zbuf)) + IMB_freezbufImBuf(ibuf); + if(ibuf->zbuf_float && !(ibuf->mall & IB_zbuffloat)) + IMB_freezbuffloatImBuf(ibuf); + } if( ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) { ima->source= IMA_SRC_FILE; ima->type= IMA_TYPE_IMAGE; } - if(ima->type==IMA_TYPE_R_RESULT) - ima->type= IMA_TYPE_IMAGE; /* name image as how we saved it */ len= strlen(name); -- cgit v1.2.3 From 9bf20b5ec0dd4886cd66c51ea4984861bf49611a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 15:25:19 +0000 Subject: UI scripts: * Fix AAO showing Distance property even though it is not supported. * Fix texture buttons not displaying texture stack from the node material. * Small visual tweak to particle mode options. --- release/scripts/ui/buttons_texture.py | 18 ++++++++++++++---- release/scripts/ui/buttons_world.py | 3 ++- release/scripts/ui/space_view3d_toolbar.py | 4 +--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index b76f35c3ec3..62281695177 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -1,6 +1,16 @@ import bpy +def active_node_mat(mat): + if mat: + mat_node = mat.active_node_material + if mat_node: + return mat_node + else: + return mat + + return None + class TextureButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -18,7 +28,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel): tex = context.texture slot = context.texture_slot - ma = context.material + ma = active_node_mat(context.material) la = context.lamp wo = context.world br = context.brush @@ -45,7 +55,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): tex = context.texture - id = context.material + id = active_node_mat(context.material) if not id: id = context.lamp if not id: id = context.world if not id: id = context.brush @@ -129,7 +139,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel): def draw(self, context): layout = self.layout - ma = context.material + ma = active_node_mat(context.material) la = context.lamp wo = context.world br = context.brush @@ -202,7 +212,7 @@ class TEXTURE_PT_influence(TextureSlotPanel): def draw(self, context): layout = self.layout - ma = context.material + ma = active_node_mat(context.material) la = context.lamp wo = context.world br = context.brush diff --git a/release/scripts/ui/buttons_world.py b/release/scripts/ui/buttons_world.py index 3134c0ce46b..b64efc1048d 100644 --- a/release/scripts/ui/buttons_world.py +++ b/release/scripts/ui/buttons_world.py @@ -129,7 +129,8 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel): col = split.column() col.itemL(text="Attenuation:") - col.itemR(ao, "distance") + if ao.gather_method == 'RAYTRACE': + col.itemR(ao, "distance") col.itemR(ao, "falloff") sub = col.row() sub.active = ao.falloff diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index 4c1b54ea8e6..ab1e161b928 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -676,9 +676,7 @@ class VIEW3D_PT_tools_particlemode(View3DPanel): pe = context.tool_settings.particle_edit ob = pe.object - row = layout.row() - row.itemL(text="Edit:") - row.itemR(pe, "type", text="") + layout.itemR(pe, "type", text="") if pe.type == 'PARTICLES': if ob.particle_systems: -- cgit v1.2.3 From 638ed7d0a840fdde028cff27dd5a54290a7ab60f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 15:47:35 +0000 Subject: Fix background image sometimes drawing into depth buffer, causing wireframes to be occluded. --- source/blender/editors/space_view3d/view3d_draw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 06d0832cb8b..fac3f9fb555 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1413,6 +1413,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) } if(v3d->zbuf) glDisable(GL_DEPTH_TEST); + glDepthMask(0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1433,6 +1434,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) wmPopMatrix(); glDisable(GL_BLEND); + + glDepthMask(1); if(v3d->zbuf) glEnable(GL_DEPTH_TEST); } -- cgit v1.2.3 From 1234f4709b3e65e44016a8d3419f64d9cf25aae8 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Fri, 9 Oct 2009 17:42:31 +0000 Subject: Cocoa : Bug fix for continuous grab feature implementation --- intern/ghost/intern/GHOST_SystemCocoa.mm | 7 +++-- intern/ghost/intern/GHOST_WindowCocoa.h | 5 +++ intern/ghost/intern/GHOST_WindowCocoa.mm | 54 +++++++++++++++++++++----------- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 2dfdcf7bcec..8bbe446616d 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -812,9 +812,9 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 //Quartz Display Services uses the old coordinates (top left origin) yf = [[NSScreen mainScreen] frame].size.height -yf; - CGAssociateMouseAndMouseCursorPosition(false); + //CGAssociateMouseAndMouseCursorPosition(false); CGWarpMouseCursorPosition(CGPointMake(xf, yf)); - CGAssociateMouseAndMouseCursorPosition(true); + //CGAssociateMouseAndMouseCursorPosition(true); return GHOST_kSuccess; } @@ -1151,7 +1151,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) window->getCursorWarpAccum(x_accum, y_accum); x_accum += [event deltaX]; - y_accum += [event deltaY]; + y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ... window->setCursorWarpAccum(x_accum, y_accum); pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum)); @@ -1159,6 +1159,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) else { //Normal cursor operation: send mouse position in window NSPoint mousePos = [event locationInWindow]; pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y)); + window->setCursorWarpAccum(0, 0); //Mouse motion occured between two cursor warps, so we can reset the delta counter } break; } diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 7a39d9ab54a..bc0dd9db13d 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -236,6 +236,11 @@ protected: */ virtual GHOST_TSuccess setWindowCursorVisibility(bool visible); + /** + * Sets the cursor warp accumulator. Overriden for workaround due to Cocoa next event after cursor set giving delta values non zero + */ + inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y); + /** * Sets the cursor grab on the window using * native window system calls. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 1d604553cc1..205c18e29ba 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -712,18 +712,33 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) return GHOST_kSuccess; } + +//Override this method to provide set feature even if not in warp +inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y) +{ + m_cursorWarpAccumPos[0]= x; + m_cursorWarpAccumPos[1]= y; + + return GHOST_kSuccess; +} + + GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore) { + printf("\ncursor grab %i",grab); if (grab) { + //No need to perform grab without warp as it is always on in OS X if(warp) { - m_systemCocoa->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); - - setCursorWarpAccum(0, 0); - setWindowCursorVisibility(false); + GHOST_TInt32 x_old,y_old; + m_cursorWarp= true; + m_systemCocoa->getCursorPosition(x_old,y_old); + screenToClient(x_old, y_old, m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + //Warp position is stored in client (window base) coordinates + setWindowCursorVisibility(false); + return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; } - return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; } else { if(m_cursorWarp) @@ -732,34 +747,37 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ if(restore) { GHOST_Rect bounds; - GHOST_TInt32 x_new, y_new, x_rel, y_rel; + GHOST_TInt32 x_new, y_new, x_cur, y_cur; getClientBounds(bounds); - printf("\ncursor ungrab with restore"); x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0]; y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1]; - screenToClient(x_new, y_new, x_rel, y_rel); + if(x_new < 0) x_new = 0; + if(y_new < 0) y_new = 0; + if(x_new > bounds.getWidth()) x_new = bounds.getWidth(); + if(y_new > bounds.getHeight()) y_new = bounds.getHeight(); - if(x_rel < 0) x_new = (x_new-x_rel) + 2; - if(y_rel < 0) y_new = (y_new-y_rel) + 2; - if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2; - if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2; - - clientToScreen(x_new, y_new, x_rel, y_rel); - m_systemCocoa->setCursorPosition(x_rel, y_rel); + //get/set cursor position works in screen coordinates + clientToScreen(x_new, y_new, x_cur, y_cur); + m_systemCocoa->setCursorPosition(x_cur, y_cur); + //As Cocoa will give as first deltaX,deltaY this change in cursor position, we need to compensate for it + //Issue appearing in case of two transform operations conducted w/o mouse motion in between + x_new=m_cursorWarpAccumPos[0]; + y_new=m_cursorWarpAccumPos[1]; + setCursorWarpAccum(-x_new, -y_new); } else { m_systemCocoa->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + setCursorWarpAccum(0, 0); } - setCursorWarpAccum(0, 0); m_cursorWarp= false; + return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; } - return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; } - + return GHOST_kSuccess; } GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape) -- cgit v1.2.3 From 7d07342c09f82cea15ad4767eed407483c5661a9 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 9 Oct 2009 20:44:50 +0000 Subject: -f argument uses MINFRAME instead of 1 (makes it possible to render negative frames on command line). Not that useful, but it's good to use the same limit everywhere. --- source/creator/creator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/creator/creator.c b/source/creator/creator.c index 6f64628b467..6f90c2ffe84 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -619,7 +619,7 @@ int main(int argc, char **argv) int frame = atoi(argv[a]); Render *re = RE_NewRender(scene->id.name); - frame = MIN2(MAXFRAME, MAX2(1, frame)); + frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame)); RE_BlenderAnim(re, scene, frame, frame, scene->frame_step); } -- cgit v1.2.3 From a5b30906ad7ae583631fb0f20ca5cf1cbebebd2f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 20:59:44 +0000 Subject: Bugfix: texture nodes render without OSA was using uninitialized variables, giving incorrect results. --- source/blender/render/intern/source/texture.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index aee2d8d1866..64683e8e7da 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1182,7 +1182,8 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */ if(tex->use_nodes && tex->nodetree) { - retval = evalnodes(tex, texvec, dxt, dyt, texres, thread, which_output); + if(osatex) retval = evalnodes(tex, texvec, dxt, dyt, texres, thread, which_output); + else retval = evalnodes(tex, texvec, NULL, NULL, texres, thread, which_output); } else switch(tex->type) { -- cgit v1.2.3 From e5d61c7f41e59bf8b8edf19bd9e57d87741f9cee Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 21:45:14 +0000 Subject: Bugfix: separate mesh did not preserve UV/Color layers. --- source/blender/editors/mesh/editmesh.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 1e3105f5c97..52744c81b7e 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1342,11 +1342,14 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) ED_base_object_select(basenew, BA_DESELECT); /* 2 */ - basenew->object->data= menew= add_mesh(me->id.name); /* empty */ + basenew->object->data= menew= add_mesh(me->id.name+2); /* empty */ assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */ me->id.us--; make_editMesh(scene, basenew->object); emnew= menew->edit_mesh; + CustomData_copy(&em->vdata, &emnew->vdata, CD_MASK_EDITMESH, CD_DEFAULT, 0); + CustomData_copy(&em->edata, &emnew->edata, CD_MASK_EDITMESH, CD_DEFAULT, 0); + CustomData_copy(&em->fdata, &emnew->fdata, CD_MASK_EDITMESH, CD_DEFAULT, 0); /* 3 */ /* SPLIT: first make duplicate */ @@ -1389,6 +1392,8 @@ static int mesh_separate_selected(Scene *scene, Base *editbase) /* 5 */ load_editMesh(scene, basenew->object); free_editMesh(emnew); + MEM_freeN(menew->edit_mesh); + menew->edit_mesh= NULL; /* hashedges are invalid now, make new! */ editMesh_set_hash(em); -- cgit v1.2.3 From ca77d6dabb0c9fba7f5862cc09294fc82bdd795a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 21:50:33 +0000 Subject: Animation playback can now also be cancelled with ESC key. --- source/blender/editors/screen/screen_ops.c | 35 +++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7ba83753fee..30fdb5b2c95 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2384,6 +2384,29 @@ static void SCREEN_OT_animation_play(wmOperatorType *ot) RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate and stay in sync with audio."); } +static int screen_animation_cancel(bContext *C, wmOperator *op, wmEvent *event) +{ + bScreen *screen= CTX_wm_screen(C); + + if(screen->animtimer) + return screen_animation_play(C, op, event); + + return OPERATOR_PASS_THROUGH; +} + +static void SCREEN_OT_animation_cancel(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Cancel Animation"; + ot->description= "Cancel animation."; + ot->idname= "SCREEN_OT_animation_cancel"; + + /* api callbacks */ + ot->invoke= screen_animation_cancel; + + ot->poll= ED_operator_screenactive; +} + /* ************** border select operator (template) ***************************** */ /* operator state vars used: (added by default WM callbacks) @@ -2994,6 +3017,7 @@ static int render_view_cancel_exec(bContext *C, wmOperator *unused) /* test if we have a temp screen in front */ if(CTX_wm_window(C)->screen->full==SCREENTEMP) { wm_window_lower(CTX_wm_window(C)); + return OPERATOR_FINISHED; } /* determine if render already shows */ else if(sima->flag & SI_PREVSPACE) { @@ -3005,13 +3029,16 @@ static int render_view_cancel_exec(bContext *C, wmOperator *unused) } else ED_area_prevspace(C); + + return OPERATOR_FINISHED; } else if(sima->flag & SI_FULLWINDOW) { sima->flag &= ~SI_FULLWINDOW; ed_screen_fullarea(C, sa); - } - - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; + } + + return OPERATOR_PASS_THROUGH; } static void SCREEN_OT_render_view_cancel(struct wmOperatorType *ot) @@ -3268,6 +3295,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_animation_step); WM_operatortype_append(SCREEN_OT_animation_play); + WM_operatortype_append(SCREEN_OT_animation_cancel); /* render */ WM_operatortype_append(SCREEN_OT_render); @@ -3408,6 +3436,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", KKEY, KM_PRESS, 0, LKEY); RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "reverse", 1); + WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", ESCKEY, KM_PRESS, 0, 0); keymap_modal_set(keyconf); } -- cgit v1.2.3 From 578bb93ada1c9d6e6e158149ba2cb0926ce1ea6c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Oct 2009 22:00:33 +0000 Subject: Add reload button for image textures. --- source/blender/editors/space_image/image_buttons.c | 6 ++++-- source/blender/editors/space_image/image_ops.c | 22 ++++++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index e2990a6d919..87b6ec8bb71 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -943,6 +943,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn cb->prop= prop; cb->iuser= iuser; + uiLayoutSetContextPointer(layout, "edit_image", &imaptr); + if(!compact) uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); @@ -992,9 +994,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn uiItemR(row, NULL, 0, &imaptr, "source", (compact)? 0: UI_ITEM_R_EXPAND); if(ima->source != IMA_SRC_GENERATED) { - row= uiLayoutRow(layout, 0); + row= uiLayoutRow(layout, 1); uiItemR(row, "", 0, &imaptr, "filename", 0); - //uiItemO(row, "Reload", 0, "image.reload"); + uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); } // XXX what was this for? diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index d5bd736f307..482750e5b2e 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -108,6 +108,11 @@ static void sima_zoom_set_factor(SpaceImage *sima, ARegion *ar, float zoomfac) sima_zoom_set(sima, ar, sima->zoom*zoomfac); } +static int image_poll(bContext *C) +{ + return (CTX_data_edit_image(C) != NULL); +} + static int space_image_poll(bContext *C) { SpaceImage *sima= CTX_wm_space_image(C); @@ -1070,19 +1075,16 @@ void IMAGE_OT_save_sequence(wmOperatorType *ot) static int reload_exec(bContext *C, wmOperator *op) { - SpaceImage *sima; - - /* retrieve state */ - sima= CTX_wm_space_image(C); + Image *ima= CTX_data_edit_image(C); + SpaceImage *sima= CTX_wm_space_image(C); - if(!sima->image) + if(!ima) return OPERATOR_CANCELLED; - BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD); - /* ED_space_image_set(C, sima, scene, obedit, NULL); - do we really need this? */ + // XXX other users? + BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_RELOAD); - // XXX BIF_preview_changed(ID_TE); - WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, sima->image); + WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, ima); ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; @@ -1096,7 +1098,7 @@ void IMAGE_OT_reload(wmOperatorType *ot) /* api callbacks */ ot->exec= reload_exec; - ot->poll= space_image_poll; + ot->poll= image_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -- cgit v1.2.3 From 0b23e65e86466837f2a8329797e907da3cd98fdc Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 9 Oct 2009 22:06:23 +0000 Subject: * more small raytrace fixes --- source/blender/render/intern/source/volumetric.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index fd7ffc8c845..7cb165ccaea 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -136,6 +136,7 @@ static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, isect->lay= -1; if (intersect_type == VOL_BOUNDS_DEPTH) { + isect->skip = RE_SKIP_VLR_NEIGHBOUR; isect->orig.face = (void*)shi->vlr; isect->orig.ob = (void*)shi->obi; } else if (intersect_type == VOL_BOUNDS_SS) { -- cgit v1.2.3 From fb561fb4c8849523ce11483f8f8d6a2c4f8aef36 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 9 Oct 2009 22:09:48 +0000 Subject: added mesh to curve conversion (edge loops only) like the script in 2.4x --- source/blender/blenkernel/BKE_mesh.h | 1 + source/blender/blenkernel/intern/mesh.c | 175 ++++++++++++++++++++++++++ source/blender/editors/object/object_add.c | 15 ++- source/blender/makesrna/intern/rna_fluidsim.c | 2 +- 4 files changed, 191 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 24e7b3957a7..d2f5e0faa0f 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -71,6 +71,7 @@ struct Mesh *get_mesh(struct Object *ob); void set_mesh(struct Object *ob, struct Mesh *me); void mball_to_mesh(struct ListBase *lb, struct Mesh *me); void nurbs_to_mesh(struct Object *ob); +void mesh_to_curve(struct Scene *scene, struct Object *ob); void free_dverts(struct MDeformVert *dvert, int totvert); void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */ void mesh_delete_material_index(struct Mesh *me, int index); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 431543f8dbd..391aa0ec32f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -42,6 +42,7 @@ #include "DNA_ID.h" #include "DNA_curve_types.h" +#include "DNA_scene_types.h" #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_image_types.h" @@ -70,6 +71,7 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BLI_arithb.h" +#include "BLI_edgehash.h" EditMesh *BKE_mesh_get_editmesh(Mesh *me) @@ -952,6 +954,179 @@ void nurbs_to_mesh(Object *ob) } +typedef struct EdgeLink { + Link *next, *prev; + void *edge; +} EdgeLink; + +typedef struct VertLink { + Link *next, *prev; + int index; +} VertLink; + +static void prependPolyLineVert(ListBase *lb, int index) +{ + VertLink *vl= MEM_callocN(sizeof(VertLink), "VertLink"); + vl->index = index; + BLI_addhead(lb, vl); +} + +static void appendPolyLineVert(ListBase *lb, int index) +{ + VertLink *vl= MEM_callocN(sizeof(VertLink), "VertLink"); + vl->index = index; + BLI_addtail(lb, vl); +} + +void mesh_to_curve(Scene *scene, Object *ob) +{ + /* make new mesh data from the original copy */ + DerivedMesh *dm= mesh_get_derived_final(scene, ob, CD_MASK_MESH); + + MVert *mv, *mverts= dm->getVertArray(dm); + MEdge *med, *medge= dm->getEdgeArray(dm); + MFace *mf, *mface= dm->getFaceArray(dm); + + int totvert = dm->getNumVerts(dm); + int totedge = dm->getNumEdges(dm); + int totface = dm->getNumFaces(dm); + int totedges = 0; + int i; + + EdgeHash *eh = BLI_edgehash_new(); + EdgeHash *eh_edge = BLI_edgehash_new(); + + mf= mface; + for (i = 0; i < totface; i++, mf++) { + if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) + BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL); + if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3)) + BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL); + + if (mf->v4) { + if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4)) + BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL); + if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1)) + BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL); + } else { + if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1)) + BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL); + } + } + + ListBase edges = {NULL, NULL}; + EdgeLink *edl; + + med= medge; + for(i=0; iv1, med->v2)) { + BLI_edgehash_insert(eh_edge, med->v1, med->v2, NULL); + + edl= MEM_callocN(sizeof(EdgeLink), "EdgeLink"); + edl->edge= med; + + BLI_addtail(&edges, edl); totedges++; + } + } + BLI_edgehash_free(eh_edge, NULL); + BLI_edgehash_free(eh, NULL); + + if(edges.first) { + Curve *cu = add_curve(ob->id.name+2, OB_CURVE); + cu->flag |= CU_3D; + + while(edges.first) { + ListBase polyline = {NULL, NULL}; + int closed = FALSE; + int totpoly= 0; + MEdge *med_current= ((EdgeLink *)edges.last)->edge; + int startVert= med_current->v1; + int endVert= med_current->v2; + + appendPolyLineVert(&polyline, startVert); totpoly++; + appendPolyLineVert(&polyline, endVert); totpoly++; + BLI_freelinkN(&edges, edges.last); totedges--; + + int ok= TRUE; + + while(ok) { + ok = FALSE; + i= totedges; + while(i) { + i-=1; + edl= BLI_findlink(&edges, i); + MEdge *ed= edl->edge; + + if(ed->v1==endVert) { + endVert = ed->v2; + appendPolyLineVert(&polyline, ed->v2); totpoly++; + BLI_freelinkN(&edges, edl); totedges--; + ok= TRUE; + } + else if(ed->v2==endVert) { + endVert = ed->v1; + appendPolyLineVert(&polyline, endVert); totpoly++; + BLI_freelinkN(&edges, edl); totedges--; + ok= TRUE; + } + else if(ed->v1==startVert) { + startVert = ed->v2; + prependPolyLineVert(&polyline, startVert); totpoly++; + BLI_freelinkN(&edges, edl); totedges--; + ok= TRUE; + } + else if(ed->v2==startVert) { + startVert = ed->v1; + prependPolyLineVert(&polyline, startVert); totpoly++; + BLI_freelinkN(&edges, edl); totedges--; + ok= TRUE; + } + } + } + + /* Now we have a polyline, make into a curve */ + if(startVert==endVert) { + BLI_freelinkN(&polyline, polyline.last); + totpoly--; + closed = TRUE; + } + + /* --- nurbs --- */ + Nurb *nu; + BPoint *bp; + + /* create new 'nurb' within the curve */ + nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb"); + + nu->pntsu= totpoly; + nu->pntsv= 1; + nu->orderu= 4; + nu->flagu= 2 | (closed ? CU_CYCLIC:0); /* endpoint */ + nu->resolu= 12; + + nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*totpoly, "bpoints"); + + /* add points */ + VertLink *vl= polyline.first; + for (i=0, bp=nu->bp; i < totpoly; i++, bp++, vl=vl->next) { + VecCopyf(bp->vec, mverts[vl->index].co); + bp->f1= SELECT; + bp->radius = bp->weight = 1.0; + } + BLI_freelistN(&polyline); + + /* add nurb to curve */ + BLI_addtail(&cu->nurb, nu); + /* --- done with nurbs --- */ + } + + ob->data= cu; + ob->type= OB_CURVE; + } + + dm->release(dm); +} + void mesh_delete_material_index(Mesh *me, int index) { int i; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index c552a2954b7..47053ea6d93 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1035,6 +1035,14 @@ static void curvetomesh(Scene *scene, Object *ob) object_free_modifiers(ob); } +static void meshtocurve(Scene *scene, Object *ob) +{ + mesh_to_curve(scene, ob); + + if(ob->type == OB_CURVE) + object_free_modifiers(ob); +} + static int convert_poll(bContext *C) { Object *obact= CTX_data_active_object(C); @@ -1071,6 +1079,11 @@ static int convert_exec(bContext *C, wmOperator *op) if(ob->flag & OB_DONE) continue; + else if (ob->type==OB_MESH && target == OB_CURVE) { + ob->flag |= OB_DONE; + meshtocurve(scene, ob); + ob->recalc |= OB_RECALC; + } else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ ob->flag |= OB_DONE; basedel = base; @@ -1096,7 +1109,7 @@ static int convert_exec(bContext *C, wmOperator *op) /* make new mesh data from the original copy */ dm= mesh_get_derived_final(scene, ob1, CD_MASK_MESH); /* dm= mesh_create_derived_no_deform(ob1, NULL); this was called original (instead of get_derived). man o man why! (ton) */ - + DM_to_mesh(dm, ob1->data); dm->release(dm); diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index 5b05948857e..ae52c811c92 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -114,7 +114,7 @@ static void rna_FluidSettings_update_type(bContext *C, PointerRNA *ptr) sprintf(psmd->modifier.name, "FluidParticleSystem" ); psmd->psys= psys; BLI_addtail(&ob->modifiers, psmd); - modifier_unique_name(&ob->modifiers, psmd); + modifier_unique_name(&ob->modifiers, (ModifierData *)psmd); } } else { -- cgit v1.2.3 From f9bb4e3195d6b1c6be31306d83fe15d7b034a2cb Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 9 Oct 2009 23:34:52 +0000 Subject: * Added Grease Pencil Operator buttons to the Toolshelf * Cancelling loopcuts with EscKey or RMB now works again. --- release/scripts/ui/space_view3d_toolbar.py | 48 ++++++++++++++++++++++++++++++ source/blender/editors/mesh/loopcut.c | 16 ++++++++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index ab1e161b928..d93a2d26040 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -38,6 +38,12 @@ class VIEW3D_PT_tools_objectmode(View3DPanel): col.itemO("anim.insert_keyframe_menu", text="Insert") col.itemO("anim.delete_keyframe_v3d", text="Remove") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -85,6 +91,12 @@ class VIEW3D_PT_tools_meshedit(View3DPanel): col.itemO("mesh.uvs_rotate") col.itemO("mesh.uvs_mirror") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -126,6 +138,12 @@ class VIEW3D_PT_tools_curveedit(View3DPanel): col.itemO("curve.extrude") col.itemO("curve.subdivide") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -159,6 +177,12 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel): col.itemO("curve.extrude") col.itemO("curve.subdivide") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -216,6 +240,12 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel): col.itemL(text="Modeling:") col.itemO("armature.extrude") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -237,6 +267,12 @@ class VIEW3D_PT_tools_mballedit(View3DPanel): col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -258,6 +294,12 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel): col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -302,6 +344,12 @@ class VIEW3D_PT_tools_posemode(View3DPanel): col.itemO("pose.push", text="Push") col.itemO("pose.breakdown", text="Breakdowner") + col = layout.column(align=True) + col.itemL(text="Grease Pencil:") + col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") + col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") + col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c index e58025ac6ce..4ef25238a84 100644 --- a/source/blender/editors/mesh/loopcut.c +++ b/source/blender/editors/mesh/loopcut.c @@ -384,18 +384,28 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event) switch (event->type) { - case RIGHTMOUSE: case LEFTMOUSE: /* confirm */ // XXX hardcoded if (event->val == KM_RELEASE) { /* finish */ ED_region_tag_redraw(lcd->ar); - + ringsel_finish(C, op); ringsel_exit(C, op); return OPERATOR_FINISHED; } - + + ED_region_tag_redraw(lcd->ar); + break; + case RIGHTMOUSE: /* abort */ // XXX hardcoded + case ESCKEY: + if (event->val == KM_RELEASE) { + /* cancel */ + ED_region_tag_redraw(lcd->ar); + + return ringsel_cancel(C, op); + } + ED_region_tag_redraw(lcd->ar); break; case WHEELUPMOUSE: /* change number of cuts */ -- cgit v1.2.3 From 1cc79c1a95b76f36a4cc4f20ef508f122a40278f Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 10 Oct 2009 03:29:03 +0000 Subject: Fixing mixed code and declaration. PEOPLE, PLEASE CHECK YOUR WARNINGS BEFORE COMMIT --- source/blender/blenkernel/intern/mesh.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 391aa0ec32f..ce30075c424 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -996,6 +996,10 @@ void mesh_to_curve(Scene *scene, Object *ob) EdgeHash *eh = BLI_edgehash_new(); EdgeHash *eh_edge = BLI_edgehash_new(); + ListBase edges = {NULL, NULL}; + EdgeLink *edl; + + mf= mface; for (i = 0; i < totface; i++, mf++) { if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) @@ -1014,9 +1018,6 @@ void mesh_to_curve(Scene *scene, Object *ob) } } - ListBase edges = {NULL, NULL}; - EdgeLink *edl; - med= medge; for(i=0; iv1, med->v2)) { @@ -1042,20 +1043,24 @@ void mesh_to_curve(Scene *scene, Object *ob) MEdge *med_current= ((EdgeLink *)edges.last)->edge; int startVert= med_current->v1; int endVert= med_current->v2; + int ok= TRUE; + + Nurb *nu; + BPoint *bp; + VertLink *vl; appendPolyLineVert(&polyline, startVert); totpoly++; appendPolyLineVert(&polyline, endVert); totpoly++; BLI_freelinkN(&edges, edges.last); totedges--; - int ok= TRUE; while(ok) { ok = FALSE; i= totedges; while(i) { + MEdge *ed= edl->edge; i-=1; edl= BLI_findlink(&edges, i); - MEdge *ed= edl->edge; if(ed->v1==endVert) { endVert = ed->v2; @@ -1092,8 +1097,6 @@ void mesh_to_curve(Scene *scene, Object *ob) } /* --- nurbs --- */ - Nurb *nu; - BPoint *bp; /* create new 'nurb' within the curve */ nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb"); @@ -1107,7 +1110,7 @@ void mesh_to_curve(Scene *scene, Object *ob) nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*totpoly, "bpoints"); /* add points */ - VertLink *vl= polyline.first; + vl= polyline.first; for (i=0, bp=nu->bp; i < totpoly; i++, bp++, vl=vl->next) { VecCopyf(bp->vec, mverts[vl->index].co); bp->f1= SELECT; -- cgit v1.2.3 From d30be46ad8b13d8b641a4a67ffc37a1fad53be7b Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sat, 10 Oct 2009 08:40:44 +0000 Subject: * icon set updates, thanks jendryzch --- release/datafiles/blenderbuttons | Bin 182512 -> 190499 bytes release/scripts/ui/buttons_scene.py | 2 +- release/scripts/ui/space_info.py | 12 +- source/blender/editors/datafiles/blenderbuttons.c | 11660 ++++++++++---------- source/blender/editors/include/UI_icons.h | 16 +- source/blender/editors/space_graph/graph_header.c | 4 +- source/blender/makesrna/intern/rna_scene.c | 50 +- 7 files changed, 5997 insertions(+), 5747 deletions(-) diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons index 79d6138e3f0..aa7870f6712 100644 Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 2b153737be3..49635071342 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -29,7 +29,7 @@ class SCENE_PT_render(RenderButtonsPanel): rd = context.scene.render_data row = layout.row() - row.itemO("screen.render", text="Image", icon='ICON_RENDER_RESULT') + row.itemO("screen.render", text="Image", icon='ICON_RENDER_STILL') row.item_booleanO("screen.render", "animation", True, text="Animation", icon='ICON_RENDER_ANIMATION') layout.itemR(rd, "display_mode", text="Display") diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 32068f1b941..3b4eed0c298 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -183,15 +183,15 @@ class INFO_MT_help(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.itemO("help.manual") - layout.itemO("help.release_logs") + layout.itemO("help.manual", icon='ICON_URL') + layout.itemO("help.release_logs", icon='ICON_URL') layout.itemS() - layout.itemO("help.blender_website") - layout.itemO("help.blender_eshop") - layout.itemO("help.developer_community") - layout.itemO("help.user_community") + layout.itemO("help.blender_website", icon='ICON_URL') + layout.itemO("help.blender_eshop", icon='ICON_URL') + layout.itemO("help.developer_community", icon='ICON_URL') + layout.itemO("help.user_community", icon='ICON_URL') layout.itemS() layout.itemO("help.operator_cheat_sheet") diff --git a/source/blender/editors/datafiles/blenderbuttons.c b/source/blender/editors/datafiles/blenderbuttons.c index cfd526d82ef..8d8cb8af4d6 100644 --- a/source/blender/editors/datafiles/blenderbuttons.c +++ b/source/blender/editors/datafiles/blenderbuttons.c @@ -1,5710 +1,5960 @@ /* DataToC output of file */ -int datatoc_blenderbuttons_size= 182512; +int datatoc_blenderbuttons_size= 190499; char datatoc_blenderbuttons[]= { -137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, - 0, 0, 2, 88, 0, 0, 2,128, 8, 6, 0, 0, 0, 64, 11, 6,158, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13, -215, 1, 66, 40,155,120, 0, 0, 10, 79,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102, -105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139, -128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44, - 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157, -179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16, - 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135, -255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38, - 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1, -160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73, - 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132, -153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46, - 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224, -131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225, -116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160, -233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, - 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98, -220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, - 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16, - 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73, -146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5, -220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47, -212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8, - 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, - 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178, - 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231, -208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172, - 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76, - 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, - 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18, -210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195, -228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50, - 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75, -165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244, -119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49, -235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, - 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, - 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, - 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, - 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, - 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89, -251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107, -165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250, -167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, - 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33, - 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231, -155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, - 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169, -183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7, - 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16, -207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46, -155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220, -159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181, -231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, - 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137, -129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229, -193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39, -133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57, -175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42, -174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46, - 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, - 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, - 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230, -102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40, -215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194, - 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184, -138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133, -125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120, -229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14, -110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201, -206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188, -247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109, -113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239, -119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31, -118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15, -156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123, -231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, - 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233, - 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253, -206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119, -160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63, -114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242, -151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29, -239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45, -219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234, - 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 2,190, 27, 73, 68, 65, 84,120,218,236,157,119,120, 20,197, 31,198,223, -217,221,235,119,233, 33, 61,144,132, 26, 8, 61,116, 66,111, 34, 77, 69,186, 10, 22, 64,129,159, 32,205,134, 32,130, 93, 1,149, -174, 34, 32, 34, 72, 85,148, 42,189, 73,239, 61,129, 52,210,235,245,178,243,251, 35,185,243, 18,146,220, 37, 32, 22,230,243, 60, -251, 92,178,187,247,222,236,236,236,236,187,223, 41, 75, 40,165, 96, 48, 24, 12, 6,131,193, 96, 60, 56, 56,150, 5, 12, 6,131, -193, 96, 48, 24,255, 34,131, 69, 8,233,198, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 12, 22,131,193, 96, 48, 24, 12, - 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 48,131, -197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12,198,127, 3,194, 38, 26,101, 48, 24, 12, 6,131,193,120,176, 8, -229,109,104,214,172,217,207, 10,133,162, 86,121,219,117, 58, 93,234,153, 51,103, 58,179, 44,100, 48, 24, 46,159,228, 8,225,240, -103,196, 92, 4, 64, 41,123,186, 99, 48, 24,143,162,193,146, 74,165, 81,251,247,239,175, 35,138, 34,108, 54, 27,172, 86,171,227, -211,100, 50,225,169,167,158, 18, 42,251, 99, 77,154, 52,217,207,113, 92, 68,101,190, 99,179,217,238,156, 61,123,182,125,121,219, - 3, 3, 3, 15, 3,136, 34,132,216, 43,242, 50, 63, 1,128,227, 28, 45,162, 41,137,137,137,205, 42,210, 36,132, 68, 57,221, 28, -238,209,178,255,237,174,102,189,122,245, 78, 8,130, 16, 86,250,251,101,253,111,255, 91, 20,197, 91,231,207,159,111,203,138,233, -195,161, 73,147, 38,251,121,158,175,116,249, 60,115,230, 76,185,229,179, 97,195,134,167, 57,142, 11, 41,235, 28,151,117,206, 1, -240, 54,155,237,234,217,179,103,219,151,103, 64,130,131,131, 15, 3,136,170,168,236,148, 42,155, 0,144,148,152,152, 24,235,234, - 58,170,232, 26, 42,163,204, 87,168,233,108,174, 66, 67, 67, 63,168, 86,173,218, 88,157, 78,103, 0, 64,121,158,167,245,235,215, - 47,145, 15, 54,155, 45,227,242,229,203, 13, 89, 73,100, 48, 24,255,105,131, 37,138, 34,103, 52, 26,113,237,218, 53,148, 85,207, -115, 28,103,171,236,143, 81, 74,235,236, 94,179, 42, 64, 89, 45, 16, 54,139, 25,114,191,106, 14,237,220,203, 23, 32,154,205,176, -153, 77,240,143,109,109,175,112,209,185,115,103,222,133,108,216,164, 73,147, 2, 60, 60, 60, 96, 48, 24, 96, 48, 24, 96, 52, 26, - 97, 48, 24, 96, 50,153, 96, 50,153, 96, 54,155, 97, 54,155, 97,181, 90, 97, 52, 26,113,238,220, 57,155,139, 27, 66,216,132, 9, - 19, 2, 60, 61, 61, 29,122,246,197,174,105,215,181, 88, 44, 48, 24, 12,184,112,225, 66,133,154,130, 32,132,157, 58,117, 42, 64, - 42,149,130, 82, 10, 81, 20, 65, 41, 45,177,148,166,109,219,182,102, 86, 68, 31, 42,117, 54,125, 52, 55, 64,238,235, 7,209, 98, -129, 95,147,230,246,114,139,148, 61,219, 97, 51,155, 33, 90, 44,168,209,247, 73,199,250,142, 29, 59,186, 42,159, 53,126,154,241, -186,183,212,195, 3, 86,131, 1,145,125,158,112,108,184,184,120, 30, 68,139, 25,212, 98, 70,163, 73,111, 1, 0, 50, 51, 51,245, -209,209,209, 41, 0, 8,128,242, 34, 60, 97,183,110,221, 10,176,167,161, 44,211,239,188, 28, 58,116, 8,195,135, 15,119,117,236, - 97,111,190,249,102,128,253, 26, 41, 93,206,173, 86,171,227,211,106,181,194, 96, 48,224,244,233,211,110, 69,174,130,131,131, 63, -140,139,139, 27,181,122,245,106,245,166, 77,155,212, 17, 17, 17,144, 74,165,224,121, 30, 60,207,131,227, 56, 8,130,128,126,253, -250, 17, 86, 4, 25, 12,198,127,222, 96,153,205,230,248, 30, 61,122, 80, 0, 48,153, 76,161, 50,153, 76, 90,202,128,133,180,107, -215,238,106,233,239,185,106, 58, 84, 86, 11,196, 55,145,190, 0,128,167,111,102, 57,110, 12,235,227,154, 56,246, 25,122, 59,175, -104, 95,165, 18, 28,199, 17, 23, 21, 56,212,106, 53,186,119,239, 14,153, 76,134,216,216, 88, 72, 36,146, 50, 23,169, 84, 10,137, - 68,114, 79,244,168, 44, 52, 26, 13,102,205,154,101, 55, 71, 80, 43,228, 24,223, 54, 22, 10, 80, 44,189,112, 29, 38,145, 66, 16, - 4,199,226,142,166, 84, 42,197,249,243,231, 33, 8, 2,120,158,119,124,218,255,222,178,101, 11, 6, 14, 28, 8, 65, 16,160, 84, - 42, 81,124,147,101, 60, 68, 20,126,254, 88,223,161, 41, 0, 96,120, 98,129,163,140,253, 58,184,143, 99,159,103,146,181, 32,132, - 64, 42,149,186,119,222, 61, 60,176,109,224, 99, 0,128, 39,175,165, 67, 34,145, 64, 16, 4,156,251,236, 61, 72,100, 50, 8, 82, - 41, 26, 77,122, 11,153,153,153,250, 39,158,120,226,160, 66,161,216,238,198,195, 10, 18, 19, 19, 33, 8, 66,185,229,157,227, 56, -172, 88,177, 2,183,111,223,118,235,216,245,122, 61,222,127,255,125, 16, 66, 74, 92, 47,229,253,237,234,216, 9, 33, 92, 80, 80, -208,123,113,113,113, 35, 86,175, 94,237, 67, 8,193,151, 95,126, 9,169, 84,138,222,189,123,195,207,207, 15, 59,118,236,128, 84, - 42,197,212,169, 83, 89,225, 99, 48, 24,143,134,193, 58,115,230,204, 99,246,191, 91,183,110,125,249,224,193,131,245,156, 66,249, -176, 90,173, 82,171,213, 90,199,222,108,104,127,242, 29, 58,116,104,133, 79,244, 54,139,249, 30,131, 84, 86, 69,237,206,141,203, -201, 12, 98,208,160, 65, 0, 80,238,205,198,121,113,227,169, 27, 38,147, 9,130, 32,160,110,120, 53,188,221,179, 41, 90, 82, 11, -180,133, 4,214, 60, 45,250,107, 44,184, 92,191, 25,150,220,201,192,237,252, 66, 8,130,123,173,165,162, 40,150,107,174,120,158, -199,162, 69,139, 48,100,200, 16,240, 60, 95,110,190, 48,254, 90,108,102,179,203,114, 88,217,115, 99, 53, 24,138, 34, 75, 2,239, - 48, 87, 18,137, 4, 18,185, 28,130, 84, 10, 65, 38, 69,102,102,166,190, 91,183,110, 71,101, 50,217,119,129,129,129, 41, 73, 73, - 73, 21,150, 79, 74,105, 73,173, 50, 30, 38,190,253,246, 91,172, 92,185, 18,173, 90,181,114,199, 12,193,100, 50, 65, 42,149,226, -189,247,222,187,103,251,226,197,139,239, 49, 88, 46,244, 8, 0, 46, 48, 48,240,229, 53,107,214,120,218,127,223,223,223, 31, 18, -137, 4, 13, 27, 54,132,135,135, 7, 14, 30, 60, 8,155,205,230,246,131, 15,131,193, 96,252,235, 13, 86, 41, 99,192, 25,141, 70, - 92,185,114, 5,174,250,165, 82, 74, 43,172, 37,229,126,213, 28,145,171,117, 53,253, 28,235,135, 36,228, 58,110, 92,219, 90,214, -130, 76,163, 70,236, 59, 31,187,109,134,210,211,211, 29, 79,222,174, 22,119, 42,114,147,201, 4,149, 82,129, 93, 19, 27, 34, 49, - 75,134,153, 71,178,241,203,153, 27,144, 72, 36,232, 85,191, 33, 30,147,122,224,173, 26, 50, 76,188,158, 0, 11,165,110,221,192, - 40,165,101, 26, 43,251,223,246,166, 18,187,193, 98, 60,124,252,154, 52,119, 68,174, 86,135,123,220, 19,181, 2,128, 45,205, 34, - 32,247,208,160,225,255,166,187, 85, 62, 35,251, 60,225,136, 92,253,210, 60, 18,188, 68, 2,137, 76,134,167,207, 39, 3, 40,106, - 22,236,220, 48,122, 95, 46, 47, 91, 49, 98,196,136,248,223,127,255, 93,233, 78, 90,203, 50, 88,118,243,243,237,183,223, 98,213, -170, 85, 16, 4, 1,102,179,217,173,116, 26,141,198,114,141, 83, 85, 34, 88, 0,160,211,233, 76,155, 55,111,198, 23, 95,124, 1, - 63, 63, 63,244,232,209, 3,193,193,193, 88,183,110, 29, 40,165, 24, 55,110, 28,148, 74, 37,148, 74, 37, 43,243, 12, 6,227,209, - 51, 88,102,179, 57,190, 91,183,110,110,141,248,209,235,245,119, 93, 24,176, 50, 35, 3,206, 81, 1,185,135, 6,114,141, 6,156, -155,179,116, 89, 44, 22,135, 65,217,185,115, 39,148, 74, 37,122,247,238,125, 95, 17, 44,179,217, 12,153, 84, 2,206, 63, 16,207, -126,254, 59,178, 10,244,142, 27,218,222, 91,241, 56,149,150,142,137,109,186, 66,173, 76, 71,161,201,228,118, 4,171,180,185, 18, - 4, 1,131, 6, 13,130,209,104, 4, 33,164, 68,191, 20, 87,102,149,241,215, 81,222, 32, 4, 66, 8, 20,158, 30,144,169,213,224, -121,222, 45, 45,231,104,147, 32,147, 65, 34,151, 65, 40, 46,135,246,200, 85, 46, 47, 91,145,156,156,124, 20,128,162,101,203,150, - 74,119,210,230,108,176,156, 13,144,179,185,226,121, 30, 22,139,197, 45,243, 98, 52, 26, 33,149,254,217, 19,224,206,157, 59, 21, - 26, 44, 23,199, 76, 9, 33, 34, 33, 68,140,138,138,114,124, 55, 40, 40, 8,222,222,222, 16, 69, 17,162, 40, 66,161, 80, 64,169, - 84,150,248, 93, 6,131,193,120,100, 12,150,115,115,225,131,186,121, 85,116, 3, 83,122,122, 66,170, 86,219, 71, 43, 81,119,204, -144,189,207,201,216,177, 99, 43,236,151, 98, 55, 98,110,152, 74,112, 2,143,212,160, 72,216,184, 3,127,222, 32,139, 23, 78,144, -224,118, 80, 61,240, 87, 78, 67, 34,138,110,221,192, 74, 71,176,198,141, 27,135,101,203,150,129,227, 56, 71,158, 8,130,128,218, -181,107, 35, 62, 62,158,149,206,191, 1, 90, 65, 52,210,190, 94,225,225, 1,153, 70, 3,222,141,190,119,165,205,144, 84, 46,135, - 32,147, 66,144, 22, 53, 11,246,237,219,119, 95,110,110,238,138, 6, 13, 26, 92, 71,209, 52, 6,156,187,215,144, 32, 8, 37,140, - 79, 89,230, 74, 16, 4, 88,173, 86,183, 31, 42, 74, 27,157, 57,115,230,220,179,239, 83, 79, 61,229,110, 4,139, 18, 66,168, 84, - 42, 69,247,238,221,209,168, 81, 35,108,218,180, 9,162, 40,226,149, 87, 94,129, 82,169,196,188,121,243, 96,181, 90,241,225,135, - 31,178, 8, 22,131,193,120,244, 12,214,131, 36,247,210,121, 71, 39, 98,231,102,193,223,218,214,131, 92,163,134, 92,163, 65,187, - 77, 7, 28, 79,205,120,239, 83,183, 34, 88,118,131,149,149,149, 85,161,185,114, 39,130,229, 48, 88, 50, 1,235,195,114, 64,101, - 18, 8, 38, 75, 9,131,197, 11, 18, 36,250, 69,130,147, 72, 33,216,172,110,105, 82, 74,239,105, 18,124,238,185,231, 64, 8,113, -140,248,106,220,184,177,243,141,134,221,113, 30, 50, 41,123,182, 59, 58,180, 59, 55, 11,254,220,178, 22, 20, 30, 26,200,212,106, -116,216,122,216, 17,109,196,188,165, 46, 53,175,126,253, 21,206,207,155, 11,137, 76,134, 39, 79,223,118, 68,174,218,214,173,117, -212,164,246, 92,113,231,206,157,163, 0,184,193,131, 7,123, 55,110,220,216,173,107,210,222,201,190, 60,115,229,108,176, 44, 22, -139,219,101,222,157,235,195, 30,197,114,163,188,211,232,232,104,112, 28, 7, 79, 79, 79,104, 52, 26,199, 8, 90,133, 66, 1,149, - 74,229,232,191,233,238,117,201, 96, 48, 24,255,106,131,213,164, 73,147, 95, 85, 42, 85,164,187, 34,149,153,116,212,185, 19,177, -221, 92, 17, 66,160,208,104, 32,211,168, 33,247,208,148, 27,229, 42,239, 70, 99,111, 34,228,121,222,113,179,249,238,187,239,160, -209,104, 48,114,228,200, 74,247,193,178, 63,205,115, 82, 14, 59,228,123,192,203,132, 18,230, 74, 16, 4,240, 18, 9,238,106,130, -193, 73, 36, 16,172,174,163, 98,132, 16,228,229,229, 65, 16, 4,188,253,246,219,142, 39,118,103,115,197, 58,182,255,253,136, 78, -102,164, 68, 84,213,195,195, 81, 62,157,215,187,234,147, 72, 8, 1,181, 90, 32,145,203, 33, 41, 30,136,107,143, 92,153,212,158, - 43,234,213,171,231,136, 92,169, 84, 42,251,232, 81,151,154, 28,199,149, 40,211, 43, 86,172, 40, 97,174, 74, 71,176,220, 45,243, - 82,169, 20,203,150, 45,171,208, 68, 73,165, 82,183, 71, 80, 2, 69,211, 70,236,219,183, 15,167, 78,157,194,216,177, 99,161, 84, - 42,177, 96,193, 2, 88,173, 86,204,158, 61, 27, 74,165, 18, 50,153,140, 21, 62, 6,131,241,223, 55, 88, 50,153, 44,242,208,161, - 67,142, 73, 70, 43,250, 52,153, 76, 24, 52,104,144,219,145, 48,177,120, 20, 33, 87,106,164,156,220, 83, 3,121,113,211,139,243, -122,226, 70, 45,110,127, 2,118, 54, 88,239,188,243, 14, 4, 65,192,178,101,203, 0, 0,147, 39, 79,118,187, 15,150, 93, 19, 54, -130, 36,122, 19, 77, 63, 31, 8,211,106, 11,210, 14,157,133, 32, 8, 8,104,253, 24,196,150, 3,161, 83,106, 32,216,172,110,143, - 34,204,206,206, 70,124,124, 60,120,158,199,164, 73,147, 74,204, 85, 84,234,152,177,115,231, 78,214, 7,235,111, 52, 88, 92,113, -255,170,178,202,103, 41,243,229,186,157,204,102, 45,234,119, 37,253,115,180, 96,110,110,238,138, 59,119,238, 28, 3,192,141, 24, - 49,194, 91,165, 82,225,235,175,191,214, 1,144,173, 91,183,206,165,203,178,151,155,242,204, 85, 85,154, 8,237,145, 96,231,126, - 93,247,107,176,236,102,144, 16, 2,155,205, 6,165, 82, 89, 34,114,165, 80, 40, 32,151,203, 89,193, 99, 48, 24,143,134,193,226, - 56, 14, 70,163, 17,151, 46, 93,114,247, 9,213,237, 73, 71,253,154,183,194,208,219,121, 32,132, 96, 71, 92, 3, 71,179, 75,219, -159,246, 57, 42,236,219,239, 79,134, 68,173,129, 95, 92,143, 74,221, 24,156, 13, 86,110,110, 46, 36, 18, 9,222,123,239, 61,112, - 28,135, 15, 63,252, 16,161,161,161, 72, 77, 77, 69,199,142, 29,221,122,154,231,109, 60,130,159,137,134,234, 57, 47,120, 62,211, - 1, 62,221,223, 65,178, 73,192, 97,131, 10, 29, 12, 23, 33,219, 49, 31, 38,209,230,150,193, 34,132,192,106,181, 98,223,190,125, - 37, 58,178, 3, 69, 77,135,246,233, 46, 44, 22, 11,204,102, 51, 62,252,240, 67, 86, 58,255, 6,194, 31, 31,128,103, 83,116, 0, -128, 95,157,154,173,219,111, 60,224, 40,159,241,115, 38, 65,162,214,192,167, 69,156, 91,154,245, 95,153,130,250,175, 76, 65,102, -102,166,190,107,147, 6,251, 11,165,170,111, 27, 54,108, 88, 34,114,165, 80, 40, 72,241,255,196,157,178,196,113, 28,120,158,119, -152, 43,187,153, 42,203, 96,185,251, 0, 96,177, 88, 32,149, 74,221, 54, 88,238,194,113, 28,158,127,254,121, 4, 7, 7, 59, 34, - 87,239,190,251, 46,148, 74, 37, 94,127,253,117, 88, 44, 22,204,159, 63,159, 21, 62, 6,131,241,223, 55, 88, 70,163, 49,161,107, -215,174, 40,103, 91,168, 92, 46, 47, 17, 6,178, 79, 58, 90,186,169,144, 16,210,141, 82,186,171,172, 27,132,243,104, 44,121,169, -168,149,212,195, 19, 18,181, 6, 92, 25,209,166,210,154,246, 39,227,210, 6,203,190,228,229,229, 65, 34,145,224,139, 47,190,128, -167,167,167, 99,180, 94, 69,154,246, 8, 22,207,243,208, 37, 22,224,242,220, 93,144, 41, 14,163, 86,143, 33, 8,150, 40, 33, 61, -184, 1,122,155,165,194,137, 70,203,210,172, 83,167, 14,102,204,152,113,207,244, 12,229,209,172, 89, 51,151,154,247, 11,211, 44, - 91,211,157,242,201,203,229, 46,207,187,125,187, 61,114, 85, 40, 85,125, 27, 31, 31,111,143, 92,121,169, 84, 42, 44, 94,188, 88, - 7,128,155, 61,123,182,170, 70,141, 26,188, 59,233,228,121, 30,223,125,247,221, 61, 29,218,203, 50, 87,101, 77,251, 81, 86, 58, -173, 86,235, 61, 6,107,208,160, 65,247,140, 30, 44, 47,130, 85, 86, 58,237,125,213,252,252,252, 28,145, 43,155,205,230, 24, 61, -104,177, 88, 96,181, 90,203,109,106,101,229,147,105, 50,205, 71, 71,243,145, 48, 88,167, 79,159,238, 85,222, 23,218,181,107,119, -237,208,161, 67,181,109, 54,155,243, 59, 10,165, 6,131,161, 78,255,254,253, 93, 62, 42,139,162, 8,185, 92, 14, 74, 41,154,190, -245, 1, 8,185,183,191,149,119,219,174, 32,130, 0,155,205, 6,139,197,226,114,122, 8,189, 94,239,184,153,148,215,193,189,176, -176,176,194,121,126, 74,223, 20, 12, 6, 67,137, 27, 21,161, 34,110,239,254,241,158,209,132,149,137, 16, 0,128, 66,161, 40,209, -239,202, 85, 82, 88, 17,125,184,216,167, 84,160,148,162,193,248,105, 69,231,169,184,185,208,110, 2,188, 98,227, 64, 36, 2, 68, - 0,102,179,217, 85,249, 36,246, 62, 87,148,210,111,250,247,239,127, 21,128, 17, 0,213,104, 52,114,137, 68, 34, 2,200, 6, 64, -115,114,114,188,146,147,147, 69,131,193, 80,221, 85, 58,247,237,219,135, 27, 55,110,160,121,243,230,142, 87, 54,217,155,221,236, - 38,198,217, 96,185, 27,193, 42,107, 78,173,242,102,115,119, 23,158,231,225,229,229,229,152,196, 84, 42,149, 66,165, 82, 1, 0, -230,207,159,239,200,115, 6,131,193,248,207, 27, 44, 23, 6,137, 47,175,249,208, 85, 83,161,205,102, 75,106,217,178,101,101,127, - 47,205,197, 13, 49,105,255,254,253,210,138, 94,242, 92,198, 58,151,154,199,142, 29,147, 86,240,253,178,254, 78,115,117,236,173, - 90,181, 42,243,251,229, 97,181, 90,147, 89, 17,125,120, 88,173,214,242,203,231, 59, 31,148,119, 94,211, 92,152,150,235,181,107, -215, 78,209,104, 52,191, 4, 6, 6,102, 29, 58,116,200,175, 69,139, 22,126,206,251,180,104,209, 34,184,212,215, 76,168, 96,122, - 18, 66, 72,210,179,207, 62, 43,117, 81,198, 75,255,159,228,226,161, 34,233,194,133, 11,210,178,180,202,251,164,148, 38,185,145, -173,183,123,245,234,197, 57,127,183,188,178,111,181, 90, 51, 88, 41,100, 48, 24,143,172,193, 50, 24, 12,137, 93,187,118, 45,179, -215,172, 78,167,187, 83,209,119, 47, 92,184, 16,251,160, 15, 32, 41, 41,169,237,191, 65,243,175, 56,118,198, 63,255, 28, 93,184, -112,161,229,131,214,188,115,231, 78,219,127,131, 38, 0, 92,188,120,177, 13, 43, 89, 12, 6,131, 25, 44, 55,112,119, 58, 6, 6, -131,193, 96, 48, 24,140, 71, 21,142,101, 1,131,193, 96, 48, 24, 12,198,131,133, 0,232, 86,214,134,202,140, 14, 32,132,116,171, -236, 15,187,210,103,154, 76,147,105, 50, 77,166,201, 52,153,230,127, 79,211,149,246,127,102,116, 34,165,244, 47, 91, 0,116, 99, -154, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,212, 22,214, 68,200, 96, 48, 24, 12, 6,131,241,128, 17, 88, 22,252, 61, 16, - 66,120, 74,169,237, 1, 74,250, 0, 40,239,133,110, 38, 0, 57, 85, 73, 38, 0,105,241, 98,159,168,200, 2,192, 92,188, 80,215, - 18,179,184,148, 20,159, 24,106,147,180,160,132, 72, 68, 17,103,170, 87, 15, 63, 13,244, 50, 1,128, 38,168,126,125,141, 90,217, -205,104, 54, 69,202, 37,178, 75,185,218,194,157,134,180,171, 9,172,132, 48, 24, 15,159,216,216,216, 81,148,210, 57, 69, 85, 20, -121,239,196,137, 19, 95,178, 92, 97, 48, 30,176,193,170, 85,171,214, 9,142,227,194,236,147, 97, 86, 52,231,142,253,211,102,179, - 37, 93,190,124,217,173,161,238,132, 16, 33, 56, 56,248,105,181, 90,221,153,231,249,118,197,223, 63,164,213,106,127, 79, 77, 77, - 93, 71, 41,181, 86,229,128,162,162,162, 60, 13, 6,195, 32, 66,200, 48, 0,160,148,126,175, 80, 40,126,188,117,235, 86,126, 21, -141, 80,173,160,160,160,239, 37, 18, 9,159,152,152,216, 25, 0,194,195,195,127, 55,153, 76,182,244,244,244, 97,148,210, 27,149, -212,227,164, 82,233, 7,113,113,113,237, 9, 33, 43, 41,165,139, 30,208,185,148,115, 28, 87,166, 49, 17, 69, 49,162, 10,122, 82, - 0, 94, 95,124,241,133,223,170, 85,171,154, 38, 37, 37, 53, 4,128,176,176,176,243, 35, 70,140, 56, 61,126,252,248, 44, 0,121, -197, 70,171, 92, 82, 82,124, 98,210,239,222, 26,155,150,126,105, 16, 0, 4, 5, 55,252,145,231, 57,105,104,232,169, 35, 42,255, - 97,254,117,235,213, 28,243,195,215, 95, 72, 35, 34,195,177,231,240,169, 38,227,255,247, 70,140, 34,176,238,167,204,100, 61, 60, -234,212,169,115,130,227,184,176,202,204, 37, 87,252, 6,133,164,139, 23, 47,198,150,167,201,243,124,152,171,185,186, 74,175, 19, - 69,241,214,133, 11, 23,202,156, 50,162,110,221,186, 71,120,158,143,116,183, 62,114, 78,103,121, 83,112,212,173, 91,247, 4,207, -243, 97,174, 52, 75,175, 19, 69,241,214,249,243,231,219,186,171,233, 98, 14,189, 42,165,211, 29,205,138,210, 9, 0,157, 58,117, -146,107,181,218,239, 53, 26, 77, 99,173, 86, 59,138, 82, 58, 99,239,222,189,129, 28,199,161, 91,183,110, 51, 98, 99, 99,227, 21, - 10,197, 66,189, 94,127, 90,163,209, 12,221,187,119,175,145, 93, 49, 12,198,125, 26, 44,142,227,194, 78,157, 58, 21,160, 86,171, - 81,108, 84, 96,159,189, 93, 20, 69,136,162, 8, 74,169,227,211,106,181,162, 83,167, 78,110,253,104, 88, 88, 88,195,186,117,235, -174, 31, 55,110, 92,245,190,125,251,202, 2, 3, 3, 65, 8,193,221,187,119,235,252,242,203, 47,195, 23, 44, 88,240, 78, 88, 88, -216,192,164,164,164,243,238,154,150,224,224,224,174, 0,158,107,216,176,225,147,147, 39, 79,150,182,107,215, 14, 54,155, 13,123, -246,236,137,155, 55,111,222, 23, 33, 33, 33, 27, 0,172, 72, 77, 77,221, 77, 41, 21,221,212,109, 26, 25, 25,249,227,129, 3, 7, - 34, 19, 18, 18,108, 3, 6, 12, 88, 9, 0,135, 15, 31,110, 44,138, 34,105,215,174,221,175,132,144, 65,148,210,211,149,200,243, -254,227,199,143, 31, 56,110,220,184,106, 35, 71,142,124, 6,192,162,226,223, 34,197,249, 76, 43,121, 14, 29,145, 43, 74,105, 69, -211,107, 7, 85, 34,146,165,142,143,143,247,105,219,182,237,203,233,233,233, 19,157,117,211,210,210,112,242,228, 73,243,220,185, -115, 63, 63,124,248,240,194,200,200,200, 28, 0,218,242,132,168, 77,210, 34, 45,253,210,160, 14,109,190,240, 2,128,117, 91, 94, - 30,114,252,116,134,199,207,191, 45, 25, 46, 83, 72,141,171,150,126, 46,173, 93, 43, 2,123, 79, 92,199,177, 75,217,164, 97,251, - 62, 66,222,207, 43,187, 3, 88,194, 46,207,135, 3,207,243,161, 39, 78,156, 8, 80,169, 84,101,190,208,189, 84,191, 11, 16, 66, - 64, 41, 69, 92, 92, 92, 69,154, 97,167, 78,157, 10, 80, 40, 20,142,186,163,116,157, 97,175, 87, 28,101,133, 82,116,232,208,193, - 92, 65,157, 84,227,143, 63,254, 8, 80,169, 84, 14,157,178,210, 87,218,104,116,232,208,161,194,116,158, 60,121,210,145, 78,119, - 52, 41,165,104,215,174,157,205,213,177,219,223, 88,225,234,184,237,154,109,218,180,161,149,209,116, 51,157, 21, 62, 0,105,181, -218,239,215,173, 91,247, 68, 96, 96, 32,250,247,239,191,163, 65,131, 6, 50,149, 74,133,223,126,251, 13,225,225,225,254, 30, 30, - 30,219,222,127,255,125,124,250,233,167,213,119,238,220,185, 6,192, 19,236,138, 97, 48,238,223, 96, 65,173, 86, 99,237,218,181, -142,215,195,216, 95,147, 81,214,223,213,171, 87,119,235, 7,131,130,130, 98, 35, 34, 34,246,109,218,180, 73, 25, 16, 16,224, 88, -111, 50,153,224,233,233,137,231,158,123, 78,214,189,123,247,218,195,134, 13, 59, 26, 20, 20,212,241,238,221,187, 39, 42,210, 11, - 14, 14,126, 50, 38, 38,230,203,137, 19, 39, 6,246,235,215, 15, 62, 62, 62, 37,182,247,233,211, 7,189,123,247,150,222,186,117, -107,200,186,117,235,134,172, 92,185,242,110,112,112,240,248,212,212,212, 13, 21, 58, 12,181,186, 91,147, 38, 77,190,222,179,103, - 79,152,183,183, 55, 66, 66, 66,184,183,223,126,187, 97,205,154, 53,149, 65, 65, 65, 92,106,106, 42, 54,108,216, 80,115,196,136, - 17,155, 21, 10,197, 40,131,193,176,219, 13,195, 38,243,245,245,157, 50,122,244,104,191,252,252,124,235,169, 83,167,174,219,215, -203,229,242, 25,173, 91,183,110, 70, 8, 89, 75, 41, 93, 81,149,200, 21,165, 52, 31,127, 54,229,217,177,216,183,187, 25,201,146, -157, 57,115,198,183, 77,155, 54, 27,140, 70, 99,179,177, 99,199,222,153, 59,119,174,210,211,211,211, 19, 0,201,207,207,207,153, - 53,107,150,105,222,188,121,211,234,215,175,223,245,200,145, 35, 79, 54,105,210,196, 82,108,222,238, 53, 88,132, 56,210,147,152, -156,129,125,135, 69,217,140,215, 39,135,125, 52, 39,242,246, 31, 23, 19, 69, 65,233,137,173,251, 47, 32, 45,171, 16,191, 30,185, -136, 32, 63, 15, 34,149, 75, 98,188,195, 98, 58,230, 37, 95,220, 95, 5,195,201,168, 2, 42,149, 10, 91,183,110,189,231, 21, 83, -101,189,126, 74, 16, 4,120,123,123, 87,248, 54, 2, 66, 8, 20, 10, 5,118,238,220, 89,226,245, 82,101,253,109,255,244,242,242, - 2,165,180,194, 87, 28, 40, 20, 10, 28, 58,116, 8, 28,199,221,243,253,210,105, 22, 4, 1,106,181, 26,132, 16,206,149,230,254, -253,251, 93,106,217, 63, 53, 26, 13, 0, 84,248,254, 33,185, 92,142,131, 7, 15,150,123,204,165,255,214, 20,191,239,210,149,230, -161, 67,135, 74,188,162,171,244,171,187,156,255, 47,126, 56,174, 80, 84,169, 84, 54, 14, 12, 12,196,241,227,199, 49,115,230, 76, - 89, 76, 76, 12,174, 95,191, 14, 66, 8, 70,142, 28,137, 6, 13, 26, 32, 53, 53, 21, 13, 26, 52,192,193,131, 7,155,178, 43,133, -193,120, 0, 6,203,142, 59,230,202,254, 30,177,210, 21, 68,233,161,150, 17, 17, 17,114,141, 70,243,211,214,173, 91,149,126,126, -127,190, 45,196,104, 52,162,160,160, 0,133,133,133, 40, 40, 40,128,135,135, 7, 22, 46, 92,168, 28, 58,116,232, 79, 17, 17, 17, -117, 18, 18, 18,140,229,105, 18, 66, 62, 63,115,230, 76,160,213,106,133, 76, 38, 43,215, 44,214,170, 85, 11,227,199,143, 71, 92, - 92, 92,208,224,193,131, 63, 7,176,161, 60,205, 98,227,246,213,225,195,135,195,164, 82, 41,174, 93,187,134,164,164, 36,140, 25, - 51,166,134, 40,138, 72, 76, 76,196,245,235,215,145,156,156,140,101,203,150,133, 13, 29, 58,116, 33,128,218, 21, 29,123, 49, 47, - 78,154, 52,169,142,175,175, 47,247,241,199, 31,231, 21, 22, 22, 46, 45, 94,255,250,252,249,243,135,118,232,208,161,218, 11, 47, -188, 0, 66,200, 15,148,210,123, 12, 75, 41,205,178, 34, 87, 54, 0,151, 75,125, 45,186, 84,100, 43, 8, 69,239,194,203, 45, 67, -147, 0,240,234,209,163,199, 36,163,209,216,236,224,193,131, 55,218,181,107, 87, 3, 64, 42,128, 12, 0,240,242,242, 82,127,254, -249,231,129,125,250,244,185,218,165, 75,151,102, 61,122,244,152,148,145,145, 49,183,120, 59, 45,173, 41,138, 56, 19, 20,220,240, -199,253, 71,198, 15,218,123,200, 36,157,252,191,119,238, 84, 15,143,200, 59,115, 45,219,118,241, 86, 6, 10,244, 86, 60,209,165, - 17, 0,160,117,195,234,248,114,237, 65,188,242,234,155,146, 13, 63,174,124,234, 6,133, 26,192, 47, 21,228,231,125,193, 52,255, - 52, 67,162, 40, 66, 34,145,224,177,199, 30, 3, 33,228,158,119,109, 74, 36, 18, 28, 57,114, 4, 93,186,116,129, 68, 34,193,243, -207, 63,239, 50,157,162, 40, 66, 16, 4,244,232,209, 3, 86,171,245, 30,189,210,102,193,254,142,206,138, 52, 41,165, 16, 4, 1, - 28,199,149,105,126, 74, 47,101,153,150,178,142,221,149,150,243,182,178, 94,247, 83, 90,211,158, 78,119,204,149, 93,211,221,116, - 10,130,128,182,109,219,226,244,233,211, 21,154, 45,142,227, 92,214,201, 90,173,246,185,254,253,251,239, 24, 59,118,172, 2, 0, -178,178,178, 28, 47,162,231,121, 30, 87,174, 92,129,201,100,194,234,213,171, 97, 52, 26,199,178,235,136,105,254,149,154,143,140, -193,178, 87, 18,238, 26, 44,119,222,173, 71, 41, 29,247,250,235,175, 7, 86,100,174, 10, 11, 11,145,146,146,130, 26, 53,106,224, -233,167,159, 14, 92,185,114,229, 56, 0,159, 84, 32, 43,229,121, 30,199,143, 31, 71,122,122, 58, 26, 53,106,132,200,200,200, 18, - 59,220,188,121, 19,219,182,109, 67,110,110, 46,154, 55,111, 14, 20,245, 47, 42,147, 38, 77,154,204,140,142,142,238,209,169, 83, - 39,185, 68, 34,193,153, 51,103,208,172, 89, 51,172, 93,187, 22,213,171, 87,135, 74,165,194,213,171, 87,209,168, 81, 35,236,219, -183, 15,213,170, 85, 67, 76, 76,140,188,121,243,230, 7,178,179,179,127, 79, 72, 72,152, 89, 78,126, 74, 67, 67, 67,223, 24, 61, -122,180, 44, 37, 37, 69,252,238,187,239, 14, 83, 74, 15, 19, 66,198,188,249,230,155,207,244,236,217,179,218,169, 83,167,242,255, -248,227,143, 63,202, 50, 87,110, 70,174,172,165,111, 70, 54,155,205,168,215,235, 77, 70,163,209,194,113, 92, 2, 33,196,100,179, -217,234,148,247, 48,255,220,115,207,213,204,204,204,124,229,213, 87, 95,141, 47, 54, 87, 87, 80,212,177, 29, 0, 96,181, 90,141, -133,133,133,249,109,218,180,169, 49,116,232,208, 27,107,214,172,121,229,185,231,158, 91,183, 98,197,138, 66, 0,250,210,130,213, -171,135,159,230,121, 78,170, 45,240,189,181,126,221,242,137,219,182,140, 11, 79, 76, 76,174,237,231, 95, 77, 43,213, 84, 75, 89, -247,253,183, 39, 0,152, 82, 50,242,113,238,230, 93, 72, 36, 60, 46, 37,230,161, 67,175,167, 37, 55,174,205,105,111, 55, 88,140, -191, 20,106,127, 57,244,222,189,123, 43,140, 96, 29, 57,114, 4, 18,137, 4, 74,165, 18,107,215,174,173, 80,212,110, 8,236,209, - 33, 87, 38,198,213,203,207,237, 38,195,254, 2,246,210,203, 87, 95,125,133, 87, 95,125,181,196,111, 20,107, 18,119,210, 89, 86, -250,106, 68, 68, 32, 61, 45,173,196, 58, 55, 94,210, 14,155,205, 6,137, 68,130,101,203,150,161, 79,159, 62,248,249,231,159, 43, -252, 44, 54,182,212,157,116,182,109,219, 22,102,179,217,145,230, 43, 87,174,148,169,187,104, 81,197,221, 59, 99, 99, 99, 71, 17, - 66,230,212,173, 91, 87,222,185,115,103,236,223,191, 31,115,230,204, 17,173, 86,107, 38, 0,180,109,219,182,218,196,137, 19,201, -201,147, 39,161,209,104,144,145,145,177, 34, 54, 54,118, 54,235,248,206, 96, 60,128, 8,150,189,210,117,101,174,236, 79,138,174, - 76,150, 70,163,233,221,171, 87, 47,135,185, 49, 24, 12, 14, 99,101, 55, 87,246,255,175, 94,189,138,152,152, 24,169, 70,163,233, -237,194, 96, 21, 29,136, 32, 32, 36, 36, 4,153,153,153, 56,127,254, 60,106,212,168, 1,139,197,130,237,219,183, 35, 47, 47, 15, - 18,137, 4, 82,169, 20,102,115,133, 93, 18, 16, 29, 29,253,216,170, 85,171, 98, 87,174, 92,153, 99,127,130,251,254,251,239, 65, - 41, 69,181,106,213,160,211,233,144,150,150,134,223,127,255, 29, 86,171, 21, 26,141, 6,161,161,161,138,113,227,198,181,159, 53, -107,150, 4,192,204,114,164, 91, 61,245,212, 83,158,158,158,158,248,223,255,254, 71,205,102,243, 39,132,144,214, 79, 62,249,228, - 27,227,199,143,247, 77, 72, 72, 48,189,248,226,139, 39,204,102,243,231,197, 55, 19, 9,165,212,226,194,176,150, 27,185,178, 88, - 44,246, 60,141, 47, 44, 44,132,191,191,127, 13, 23,125,180, 0, 64,122,232,208,161,182, 0,248,217,179,103, 43, 80,244, 2,107, - 71, 26, 76, 38, 19, 10, 11, 11,161,213,106, 45,121,121,121,233, 83,166, 76,177,174, 89,179,134, 47,254,206,165,178, 12, 22,208, -203,212,160,129, 90, 70, 41,255,230,146, 37, 75, 52, 61,123,246,228, 52, 26, 13, 10, 10, 10, 60,127,253,237, 55, 77,215,206,237, -163,230,126,240,209, 14,207,176, 70,105,135,206,220, 66,242,221, 60,152, 44, 22, 68, 5,123, 21,197,191, 24,127, 57,197, 29,172, - 29, 17, 44,103, 51,177,127,255,126,244,234,213,203,113,173, 75,165, 82,199,126,238,104, 10,130,128, 94,189,122,221, 19,209,217, -187,119,111,153,209, 38, 87,117,136,179, 25, 42,109,138,202, 50, 94, 28,199,193, 85, 43,179, 61,122, 87,150,201,114,142,226,151, - 50,109,174, 30, 38, 33, 8, 2,198,143, 31, 15,137, 68,130,169, 83,167, 66, 16, 4, 52,109,218, 20,130, 32,160, 77,155, 54,144, - 72, 36,232,210,165, 75,185,145,182,178,204,165, 32, 8, 56,122,244, 40,154, 53,107,230, 72, 83,211,166, 77,209,162, 69, 11, 8, -130,128,184,184, 56, 72, 36, 18,244,232,209,195,165,166,189, 67,187, 70,163,193,213,171, 87,193,243, 60, 8, 33, 89, 39, 79,158, - 12, 4,128,153, 51,103,102,234,245,122, 63,131,193,128,174, 93,187,162,125,251,246,213,190,255,254,251,183, 1, 48,131,197, 96, -220,111, 4,203, 94,233,186,107,176, 92, 97, 48, 24,154,216,163, 87,101,153, 43,231, 79,147,201,132,154, 53,107,194, 96, 48, 52, -169,236,205, 34, 56, 56, 24,102,179, 25,203,151, 47,135, 84, 42,133, 84,250,167,175, 48,153, 42, 14, 14, 93,188,120, 49,254,232, -209,163,205,154, 55,111,238,179,113,227,198,140,238,221,187, 87,235,217,179, 39,148, 74, 37,244,122, 61, 44, 22, 11, 90,183,110, -141,232,232,104,164,167,167,227,215, 95,127,205,172, 83,167,142,255,177, 99,199,196,187,119,239,222,174, 64,186,107,215,174, 93, - 65, 8,193,175,191,254,154, 69, 41, 61,169, 84, 42, 55,206,157, 59,215,219,100, 50,137,207, 60,243, 76, 98,118,118,246, 20, 0, - 22,185, 92,254, 73,207,158, 61, 91,241, 60,191,214,102,179, 85,186, 50, 43,157,183, 90,173, 22, 10,133,194,157, 41, 33, 36,217, -217,217, 13, 1, 64,173, 86,251, 2,112,140,144,212,235,245, 37, 76,176,201,100, 50,248,250,250,170, 1,160,248, 59,146,114,206, - 71, 53,149, 74,181,254,246,237, 91, 30,206,145, 75,111,111,111, 12, 27, 58,148,107,215,182,173,172,113,147, 38, 61,222,250,116, -229,218, 16, 63, 79, 83, 84,136, 31, 44, 54, 11,118,237,216, 46, 82,209,178,131, 93,162, 15, 7,187,201, 40, 29,193,146, 72, 36, -216,183,111,223, 61,235,164, 82, 41,182,110,221,234,150, 25,178,155,169,242,154,200, 74,153, 33,226, 78, 84,157,231,121, 44, 91, -182, 12,162, 40, 98,226,196,137, 37,154, 13,157,245,237,102,199,149,166,253, 59,209,239,136, 0, 76, 72,250, 76,238,248,126,233, -244, 22,107, 18,119,204,208, 23, 95,124,225, 86, 4,235,241,199, 31,119,203,180, 57, 31,151, 61, 93,167, 79,159, 46, 83,119,201, -146, 37, 46,251,180,137,162,136, 95,126,249,197, 97, 78,237,188,253,246,219,163, 61, 61, 61, 53,251,247,239,199,221,187,119,161, -213,106, 81, 88, 88, 8, 31, 31, 31,239,110,221,186,157,185,123,247,110,194,197,139, 23, 89,135,119, 6,163,170, 17, 44,123,165, -235, 78, 51, 97, 89,237,253,101,232, 9,132, 16, 24, 12,134, 50,141,149,179, 41, 48,155,205,200,202,202,130, 40,138, 85,158,171, -171,172,138,213,149,193, 58,127,254,252,200, 81,163, 70,165,120,121,121, 53,206,202,202, 74,149,203,229,113,251,247,239, 15, 55, -155,205,240,244,244,132,167,167, 39,182,109,219, 6,111,111,111,188,250,234,171,119,244,122,253, 97,181, 90, 29,168,215,235,207, -222,189,123,247,173,114,157,139, 68,210,181, 67,135, 14, 56,121,242, 36,114,115,115,247, 16, 66, 26,191,240,194, 11,221,195,195, -195,201,156, 57,115, 12, 55,110,220,248, 10, 64,134, 90,173, 94,190,106,213,170,142,205,155, 55,215,140, 24, 49, 2,132,144,175, - 41,165, 6,119,143, 89,171,213,150, 48, 86,249,249,249, 40, 40, 40,128, 90,173,182,186,153,103, 18, 20,245,165,178,247,167,114, -156,155,226,232,149,253,252, 80, 65, 16,104,209, 46, 84, 82,158,158, 90,173,158,189,114,229,202, 18,125,238,236,209,209,180,180, - 52,120,122,122,226,237,183,222,146,190,251,218, 11,205,120, 77,224, 17,142, 35, 48,153,105, 46, 21, 77,219,181,105,131, 15,176, - 75,244,225, 68,176,236,134,160, 95,191,126,247, 52, 11, 74,165, 82,236,220,185, 19, 3, 6, 12,112, 60,176, 20, 55,181,187,101, - 8,250,246,237,235,136, 4,109,223,190,189,204,230, 61,123, 4,202, 29, 35,104,223,119,194,132, 9, 16, 4, 1, 95,126,249, 37, - 38, 77,154, 4,142,227,240,217,103,159,129,227, 56,204,152, 49,163, 82,245,132,189, 46, 75,248,168,232, 51,108, 82, 62,178, 22, - 5, 2, 0, 60, 60, 61,237, 59, 86, 74, 83, 16, 4, 71,228,170, 73,147, 38,144, 72, 36,104,211,166, 13, 4, 65,112, 68,174,122, -247,238,237, 60,173, 2,117, 71, 83, 16, 4, 92,187,118,205,145,230, 54,109,218,148,136, 92, 9,130,224,150, 97, 35,132,188,219, -165, 75,151, 57, 97, 97, 97, 1, 99,199,142, 37, 60,207, 35, 54, 54,214,127,198,140, 25,121, 18,137, 68, 57,121,242,228,178,174, -107, 9,128,198,245,235,215, 87,179, 43,135,193,184,143, 8, 86,101, 12,150, 59,149,163, 74,165, 58,151,153,153,217, 70, 46,151, -151, 48, 87,101, 25, 45,158,231,145,158,158, 14,149, 74,117,238, 65, 30,176,171, 38,194, 98, 51,243,154, 83, 62,180,120,250,233, -167,215,172, 93,187, 54,106,215,174, 93, 56,118,236, 24,170, 85,171,134,185,115,231,222, 74, 72, 72, 24, 74, 41,253,195,157,223, -173, 89,179,102, 3,181, 90,141,195,135, 15, 3,192, 1, 0,207,189,242,202, 43,196,106,181, 98,225,194,133, 58, 0, 59,189,188, -188, 54,252,244,211, 79, 77, 26, 53,106, 36,219,181,107, 87,193,177, 99,199,246,186,105,174,108,162, 40,222, 99,172,156,243,212, -195,195,195,157, 8,150,197,203,203,235,124,126,126,254,211,122,189, 62, 95, 46,151,123,228,231,231, 27,157,141,149, 93, 95, 16, - 4,201,181,107,215, 82, 0, 68,121,121,121,157,135, 83, 83, 98,137, 2, 38, 8, 93,187,118,237, 42,148, 62, 7,105,105,105,184, -123,247, 46,204,102, 51,154, 55,111, 78,120, 98,225,179,239,156, 29,205, 46,201,135, 15,199,113,212,126,173,219, 71,253,149, 53, -114,112,251,246,237,142,255, 57,142,195,175,191,254,234,150,105,219,185,115,103,133, 29,209, 75,117, 72,119, 25, 10,183,239,191, -112,225,194,162,215, 81, 20, 71,174, 56,142,195,244,233,211, 33,151,203, 49,103,206, 28, 76,159, 62,189, 68, 84,198, 85, 4, 75, - 16, 4, 68, 76,213, 57, 63, 20, 21, 93, 20,197,253,157, 8, 33,206, 38,203,173, 72,155,171, 14,238,238, 68,254,203, 74,167, 66, -161, 40,183,131,123, 41,205,114,127,224,196,137, 19,223, 52,107,214,236, 70,181,106,213,118,182,105,211, 70,126,226,196, 9,140, - 27, 55,142, 24,141, 70,207, 93,187,118, 57,126,183, 44,163,167,213,106,149,236,202, 97, 48,238, 35,130, 85,153, 78,238,238,244, - 75,208,235,245,187,247,238,221,219,162,127,255,254, 66, 69,205,131, 90,173, 22,129,129,129,184,121,243,166, 85,175,215,187,156, -254,192,102,115,127, 66,116, 87, 6,171,140, 60,248, 35, 38, 38,198,106,177, 88, 80,187,118,109,132,134,134,194, 96, 48, 96,222, -188,121, 86,119,205, 21, 33, 68, 26, 27, 27,203, 3, 64, 78, 78, 14, 0,100, 1,168, 83,167, 78, 29,156, 60,121, 18, 57, 57, 57, -155, 1,116,123,247,221,119,155,182,106,213, 74,186,118,237, 90,221,216,177, 99, 55, 91, 44,150, 57,238,232,139,162,104,178, 90, -173,145, 28,199,153,115,115,115,147,157,243, 51, 48, 48,208, 87,173, 86,147,180,180, 52,139, 59, 6,171,113,227,198,199,239,220, -185,131,217,179,103,103,204,157, 59,183, 78, 65, 65, 65, 78, 94, 94,158,213,217,100, 25, 12, 6,206,223,223, 95,190,104,209, 34, - 37, 0, 52,110,220,248,120,121, 6, 75,171,213,134,171, 84, 42,199,255, 70,163, 17,119,239,222,197,221,187,119,145,150,150,134, -130,130, 2, 68, 69, 69, 65,167,211,213, 96,151,227,223,135,115, 51,153,243,245,237,124, 3,175,204,181,238,172,217,175, 95, 63, - 71,223, 45,123, 68,204,190,172, 95,191,190, 68,199,113, 87, 77,111,118,131,181,112,225, 66, 76,152, 48, 1, 10,133, 2,159,127, -254,121,137, 38,194, 50, 76, 1,113, 39,157,145,211,244,184,187,192, 23, 18,137, 4,126, 99,211, 74, 52,197,149, 49, 26,207, 45, - 35, 56,119,238,220, 7,214, 68,104,215,172, 81,163,232, 82, 89,182,108, 25,158,126,250,105, 28, 56,112,160,202, 77,132,145,145, -145,171,230,207,159, 47,191,120,241, 34,242,243,243,145,145,145, 1,163,209,136,164,164, 36, 71,222,148,133, 78,167, 83,176,171, -134,193,184, 15,131,229,220,249,211,149,193, 42,238, 32,233,202, 8,124,254,206, 59,239,188,210,190,125,123, 95, 15, 15, 15,164, -164,164,220, 99,174, 10, 11, 11,161,209,104, 96, 50,153,176,119,239,222,124, 81, 20, 63,119,101, 10, 44, 22, 11, 2, 2, 2,144, -153,153, 9,177,156,126,209, 28,199, 65,169, 84, 66,171,213,162, 60, 51, 80, 81, 5,108, 54,155, 97,177, 88, 96,177, 88, 42,109, -210, 0, 40,237, 19,182, 22,255,190, 54, 36, 36,164,166, 66,161, 64,124,124, 60, 0, 92, 3,208,185,103,207,158,146,172,172, 44, -250,226,139, 47, 30,161,148,142,119, 49,155,189,105,255,254,253,145, 0,160, 84, 42,175, 2, 64, 82, 82,146, 37, 55, 55,183, 68, -100, 80,165, 82,209, 1, 3, 6, 4, 83, 74,177,127,255,254, 72,169, 84, 74, 81,206,156, 85, 0, 12,155, 55,111,190,232,229,229, -181,230,131, 15, 62, 24,218,167, 79,159, 11, 13, 27, 54,140,212,106,181,233,122,189, 94,111, 48, 24, 40,207,243, 82, 31, 31, 31, -197,142, 29, 59,110, 28, 57,114,164,155,167,167,231,154,205,155, 55, 95, 4, 80,102,164, 77,173, 86, 39,233,116,186, 8,141, 70, - 3,189, 94, 95,194, 92,221,189,123, 23,148, 82,220,186,117, 11, 42,149,234, 14,187, 28,255, 30,156, 35, 46,165, 35, 45,165,215, -185,107,174,156,205,208,142, 29, 59, 42,156, 3,203, 93, 77,103, 51, 52,105,210, 36, 44, 88,176,224,158, 8,214,156, 57, 69,207, - 36,111,189,245,150,203,232,149, 51, 18,137, 4,119, 23,248, 34,104, 66,118, 9, 51, 3, 0,196,158,190, 74, 78,201, 38, 8, 2, -102,207,158,125, 79,231,115,231, 38, 60,119,141,149,115, 58,211,211,211, 33, 8, 2,124,125,125, 49,108,216, 48,244,232,209,195, -209,212, 88, 89,221,196,196,196,211,159,126,250,105,245,208,208, 80,172, 93,187,214,164, 86,171,101, 93,186,116,161,185,185,185, -164,162, 8, 22, 51, 88, 12,134,107, 56,119, 42, 72,119,154, 9,203,170, 36, 9, 33,221,156,255, 79, 72, 72,200,211,106,181,195, -134, 12, 25,162, 55, 26,141,168, 89,179, 38,228,114, 57, 44, 22, 11, 76, 38, 19,164, 82, 41,130,131,131, 65, 41,197,134, 13, 27, -244, 58,157,110, 88, 66, 66, 66, 94, 69,154,132,144, 55, 31,123,236, 49, 67,124,124, 60,170, 87,175, 14, 15, 15,143,123, 94, 27, -225,233,233, 9,111,111,111, 92,190,124, 25,203,151, 47,215, 19, 66,222,172, 72,179, 44,163,105, 55, 86,118,163,229,106,100, 82, - 41, 77,181, 61,138,163,211,233, 0,192, 90,189,122,245, 64, 0,184,117,235, 22, 0,220,142,138,138,234, 88,171, 86, 45,114,224, -192, 1, 80, 74,119,149,101,174, 74,105,102,199,197,197,221,142,139,139, 51,153, 76, 38,169,201,100,146,230,229,229,153,253,253, -253, 3,252,253,253,253, 3, 3, 3,125, 3, 2, 2,188, 83, 82, 82,172, 86,171, 85,106,179,217,164,113,113,113,166, 86,173, 90, -221,129,211,108,238,165, 52, 69, 0,249, 75,150, 44,153, 37,145, 72,110,183,109,219, 54,102,218,180,105, 9, 22,139,197, 24, 26, - 26,234, 19, 20, 20,164,212,233,116, 5,239,191,255,126,250,130, 5, 11,186, 73, 36,146,219, 75,150, 44,153, 5, 32,191,248,187, -247,104, 90,173,214,221,187,118,237,178, 90, 44, 22, 36, 39, 39, 35, 37, 37, 5,169,169,169,142, 79,111,111,111, 28, 63,126,220, -102, 54,155,119, 85, 34, 63, 31,148,177, 96,154,248,179,239, 79, 69,198,202,157,110, 0,165,211,105, 55, 67, 79, 63,253, 52, 6, - 15, 30,140, 33, 67,134, 96,216,176, 97, 24, 49, 98, 68,101,166,102, 40,125,189, 59,190, 59,109,218, 52,188,245,214, 91,120,231, -157,119, 32,151,203,241,246,219,111, 99,230,204,153,152, 57,115,102,105,115, 69, 42, 56,246, 18,245, 92,222,178, 80,232, 86, 68, -192,180,186, 86, 81, 19, 33,165,127, 46,238,231,167,195, 12,189,253,246,219, 56,114,228, 8,166, 76,153,130, 61,123,246, 96,220, -184,113,216,182,109, 27, 70,143, 30,141, 95,126,249,197,241, 89,252, 16, 72,221, 73,167, 32, 8,232,216,177, 35,116, 58,157,195, -192,142, 25, 51,166,132,222,232,209,163,221,202, 79,165, 82, 57,116,243,230,205, 27,151, 47, 95,126, 43, 59, 59,187, 71, 66, 66, -194, 29,173, 86, 75,242,242,242, 28,231,176,244, 82, 28,137,150,179,235,136,105, 50, 11,117, 31, 17, 44,171,213,138,240,240,240, - 18,239,182,226, 56,174,196, 82,153,126, 4, 0,144,154,154,186, 35, 56, 56,248,201, 39,158,120, 98,245,115,207, 61,231, 17, 29, - 29, 45,137,136,136,128, 78,167,195,237,219,183,145,144,144, 96,221,179,103, 79,190, 78,167, 27,158,154,154,234,114, 20, 89,114, -114,242,202,192,192,192,237,195,135, 15,159,209,180,105,211, 49, 19, 39, 78,228,163,162,162,144,151,151, 7, 31, 31, 31, 4, 4, - 4, 32, 62, 62, 30,251,246,237,179,229,230,230, 46,182,217,108,239,166,165,165,101, 84, 38,147,172, 86, 43,111, 54,155, 49,100, -200, 16,136,162,136,121,243,230,193,106,181,242,149,144, 48,155,205,102, 10,128,100,102,102, 2,128,206,110,184,174, 95,191, 14, - 0,119, 34, 34, 34, 52, 0,176,107,215, 46, 2,224,176,187, 15,244,206,145,172,232,232,232,120,123,165,232,124,147,179,111, 47, -142, 92,185,122, 12, 55, 12, 26, 52, 40, 93,167,211,245,156, 52,105,210,140,133, 11, 23, 14, 93,184,112,225, 61, 59,121,122,122, -174,249,236,179,207,222, 29, 52,104, 80,122,121,209,171,226,136,221, 91,207, 62,251,236,160,115,231,206,121, 40, 20, 10,104,181, - 90,100,101,101,193,108, 54, 35, 42, 42, 10,233,233,233, 88,185,114,101,129, 94,175,159,201, 46,199,191,151,242,140,149,187,125, - 44,203,139,226,108,221,186,181,204, 57,166, 42,171, 89,218,100,184, 59, 55,149, 27, 15, 67,101, 78,253, 80,153,122,173, 60,205, -143, 63,254,216, 49,217,106, 89,145,171,202, 68,176,236,154,190,190,190, 0,138,102,223, 23, 69, 17,143, 63,254,120,149,117,139, -223, 45,248,164,253,255,216,216,216,119,215,174, 93, 59,135, 82,234, 7, 64,112,206, 3,246, 82, 5, 6,227, 1, 25, 44,155,205, -150,212,177, 99,199, 18, 21, 91, 69, 47, 85, 45, 54, 34, 73,110,154,172,237, 81, 81, 81, 81,203,150, 45,251,159, 90,173,238,102, - 48, 24, 26, 1,128, 66,161, 56,167,213,106,119,113, 28, 55, 63, 53, 53,213,237,151, 51, 23, 27,166,113, 97, 97, 97,243, 70,140, - 24, 49,167,109,219,182, 3, 95,124,241, 69, 34, 8, 2,214,173, 91, 71,147,146,146,214,115, 28,247,102, 74, 74,202,205,170,100, -146, 74,165,186,186,126,253,250,154, 91,183,110,133,197, 98,193,162, 69,139,160, 80, 40,174,186,251,125, 74,105,134, 32, 8,171, -219,182,109, 59,244,200,145, 35,107, 40,165,231,229,114,249,247,113,113,113,195, 14, 31, 62,252, 35,165,244,146, 32, 8,223,183, -105,211,102,216,241,227,199, 55, 80, 74,207, 86, 34,121,217,113,113,113, 57, 0,130,172,214,178, 91, 20,227,226,226, 76, 0,238, -186, 97,174,236,228,143, 26, 53,202, 60,106,212,168,215, 6, 13, 26,180,252,143, 63,254,104,153,155,155,219, 8, 0,188,189,189, -207,181,104,209,226,248,143, 63,254,120,165, 56,114,101,112,117,236,132,144, 1,141, 26, 53,218,240,222,123,239,169, 99, 98, 98, -132,218,181,107, 35, 33, 33, 1,231,207,159,183,126,243,205, 55,133,122,189,190, 31,165, 52,135, 93,142,127, 15,246, 38, 66,111, -111,239, 18, 15, 79,246,161,251,149,105,194, 43, 75,179,244,131, 25,207,243, 21,105,186,116, 53, 26,141,198, 49,106,217,157,174, - 9, 21,189,123,212,158, 78,187,166,125,113,195, 92, 81, 87,154,197,175,233,169,140, 38,220,209,180, 88, 44, 14, 93, 55, 52, 43, -245,163, 39, 78,156,248, 6,192, 55,181,107,215,190, 14,160, 22, 51, 85, 12,198, 95, 96,176, 46, 95,190, 28,251, 87,254,240,173, - 91,183,242, 1,188, 91,188, 60, 16,146,146,146,110, 2, 24, 20, 20, 20,244,201,225,195,135,223, 6, 0, 81, 20,103,187,122,159, -161, 43,206,158, 61, 59, 64, 34,145, 44, 92,177, 98, 69, 91, 74, 41,188,188,188, 14, 95,191,126,253,229, 74, 70,193,198, 16, 66, - 38,218, 71, 5, 26,141,198, 49,132,144,201,148, 82,173,211,118,199,255,149,132, 2, 48, 82, 74, 67,202,217,110,172,132,185,114, - 68,178, 0,152,126,252,241,199, 66, 0,103,240,231, 60, 87,150,226,197, 0,167,102, 65, 23, 55,184,223, 9, 33,181,223,126,251, -237,185, 60,207,119,213,106,181,161,106,181, 58,209,106,181,238,214,233,116,111, 82, 74,179,216,165,248,247, 97,181, 90,147, 59, -118,236, 40,148,245,224, 84,209, 13,188,162, 7, 42,155,205,150, 20, 23, 23,135, 42,104, 38, 87,144,212,219,109,218,180,225,220, -213,178, 99,177, 88,210, 43, 74,103,155, 54,109,202,125,104,172,234,177,183,105,211,166, 82,105, 44,174,171,146, 31,180,166,139, -252, 44, 23,189, 94,159, 83,173, 90,181, 66,131,193, 32, 49, 26,141,146,210, 17,123,165, 82,153,193,174, 28, 6,163,138, 6,235, -223, 76,177,161,234,251,160,244,138,251, 67,189,244, 0,116, 12,165,254,215, 86,244,127, 37,249, 43, 34, 64, 34, 0,221, 3,202, -195, 76, 0, 47,178, 75,238,159,199,249,243,231, 91, 61,104,205,139, 23, 47,198,254, 5,233,108,243,160, 53, 47, 92,184, 16,251, -168,106, 86, 68,114,114,114, 43,118,101, 48, 24,247, 7,199,178,128,193, 96, 48, 24, 12, 6,227,193, 66, 0,148, 57, 18,160, 50, -111,202,174,202,104, 2, 87,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,252,239,105,186,210,174,140,255,248, 71, 83,214, 48, -220, 7,181, 0,232,198, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,249,168, 45,172,137,144,193, 96, 48, 24, 12, 6,227, 1, -195, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193,120,132, 32,132,144, -176,176,176,142, 33, 33, 33,109, 30,213, 60, 16, 88, 49, 96, 48, 24, 12, 6,131,241, 32,168, 94,189,186,183,205,102,123, 46, 36, - 36,228,229,154, 53,107,214, 4,128,208,208,208,243,148,210,249, 74,165,242,251, 27, 55,110,152, 30, 25,147,201, 94,133,192, 96, - 48, 24, 12, 6,227,126, 8, 9, 9,105, 10,224,101,165, 82, 57,188, 85,171, 86,178, 46, 93,186,192,199,199, 7, 86,171, 21,169, -169,169,248,253,247,223,113,250,244,233,108,139,197,178,208, 98,177, 44,204,200,200, 72, 99, 6,139,193, 96, 48, 24, 12, 6,163, - 28,130,131,131, 63,237,213,171,215, 36, 31, 31, 31,212,174, 93, 27, 65, 65, 65, 48, 26,141,208,235,245,160,148, 66, 16, 4, 80, - 74, 81, 80, 80,128, 19, 39, 78,224,216,177, 99,214,252,252,252, 53,132,144,249, 41, 41, 41,167,153,193, 98, 48, 24, 12, 6,131, -193, 40, 69, 72, 72, 72,218,158, 61,123, 2,172, 86, 43, 50, 51, 51, 97, 52, 26,161,211,233, 28, 6,139,231,121, 80, 74, 97,181, - 90, 1, 0,162, 40,226,210,165, 75, 56,114,228, 8, 18, 19, 19, 63, 75, 77, 77,125,237,191,152, 47,172,147, 59,131,193, 96, 48, - 24,140,251,194,104, 52, 98,213,170, 85,200,204,204, 68,120,120, 56, 66, 67, 67,225,237,237, 13,165, 82, 9, 0, 14,115, 5, 0, - 28,199, 33, 38, 38, 6,195,135, 15, 7, 33,100,216,127, 53, 79, 88, 39,119, 6,131,193, 96, 48, 24,247,131,197,100, 50, 33, 54, - 54, 22,241,241,241, 56,121,242, 36,154, 53,107,134,250,245,235, 35, 51, 51, 19, 41, 41, 41, 37,118, 62,126,252, 56, 78,157, 58, -133, 14, 29, 58,252,167, 51,133, 53, 17, 50, 24, 12, 6,131,193,168, 50,161,161,161,207, 84,171, 86,109,209,136, 17, 35,148, 77, -154, 52, 65, 82, 82, 18,146,147,147,145,147,147,131,166, 77,155, 34, 38, 38, 6, 55,111,222,196,246,237,219,113,234,212, 41,200, -229,114,132,133,133, 65,179,230, 7,252, 18, 18,156,156,146,146, 18,198, 12, 22,131,193, 96, 48, 24, 12, 70, 41, 66, 66, 66,252, - 8, 33,111,134,134,134,190, 50,108,216, 48, 73,237,218,181,145,148,148,132,140,140, 12,228,228,228,224,232,209,163,118, 51,134, -176,176, 48, 36, 36, 36,224,220,185,115,122,163,209, 56, 54, 57, 57,121, 37, 51, 88, 12, 6,131,193, 96, 48, 24,229, 27,173,112, - 0,179,106,213,170,245,204,211, 79, 63,205,133,132,132, 32, 57, 57, 25,123,246,236, 65,173, 90,181,144,150,150,134, 19, 39, 78, -216,242,243,243, 23,219,108,182,119,211,210,210, 50,254,171,121,241,151,118,114, 39,132,116, 99,154, 76,147,105, 50, 77,166,201, - 52,153,230,163,161,153,146,146,146,152,146,146, 50,242,218,181,107, 49,115,230,204,217,188,104,209, 34,240, 60,143,208,208, 80, -236,217,179,135,238,222,189,123,125, 97, 97, 97,221,148,148,148,113,255,101,115, 5,176, 78,238, 12, 6,131,193, 96, 48, 30, 48, -119,239,222,189, 12, 96, 64,104,104,104,171, 11, 23, 46,188, 1, 0,162, 40,206,190,123,247,238,137, 71, 37, 15,152,193, 98, 48, - 24, 12, 6,131,241,151,144,156,156,124, 12, 64,223, 71,241,216,217, 60, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6, -131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,241, 72, 65, 0,148, 57, 18,128, 82,186,203,109,145, 42,140, 80,112,165,207, 52, -153, 38,211,100,154, 76,147,105, 50,205,255,158,166, 43,237,202,248,143,127, 52,148, 82,151, 11,138,231,203,170,236, 2,160, 91, - 85,190,199, 52,153, 38,211,100,154, 76,243,225,107, 86,165,174, 47, 75,179,248,225,157,160,168,149,132,179,255,255, 79, 75,231, -191,229,216, 31, 21,205,255,218, 34,184,112,151,142, 76, 34,132,136, 0, 68,250, 0,102, 38, 37,132,216, 79,192, 3,209, 99,252, - 5,161,205,162,115, 68,254,244,225,236, 60, 49, 24,255,225,235,253,129,213,245, 78,117, 7,239,116,147,181, 1,176, 17, 66,112, - 63,117,201, 95,113, 79,250,167, 31,251,163,172,249,111, 71,168, 40,163,170, 85,171,182, 35, 32, 32,160,115,102,102,166, 88,188, - 30,161,161,161,224, 56, 14,130, 32,232,227,227,227, 61, 43,251,131,129,129,129, 95,199,196,196, 60,151,149,149, 37,114, 28,135, -240,240,112, 16, 66,192,243, 60,120,158,215,223,184,113,195,243,239,206,148,230,205,155,231,152, 76, 38, 77,233,245, 50,153,204, -112,242,228, 73,143, 71,193, 92,249,251,251, 63, 25, 24, 24,232,157,157,157, 77, 1, 32, 44, 44, 12, 60,207, 23, 21, 26, 65,176, -222,188,121,115,133,187,122,145,145,145,199,149, 74,165,183, 32, 8,224,121, 30,130, 32, 64,171,213,230, 94,186,116,169,101,241, -246, 67, 74,165,210,143,231,121,123,217,130,193, 96,200,186,120,241, 98, 59,118,235,251,119,178,126,253,122,190,103,232,243,181, - 4,170,111,204,113,212, 75, 20, 73,158,149, 40,207,110, 79,254,250,134, 59,223, 31, 56,112,160,237,111,190, 6,170, 3,176, 82, - 74, 83,170,240,101,174,140,138,182,151, 13, 24, 92,252,175,129, 3,178, 8,112,173, 46,176,225, 34,160, 47,213,172, 32, 62,236, - 7,169,234,213,171,207,175, 86,173,218,200,194,194, 66, 29,199,113, 32,132,208,152,152, 24,251, 62, 37, 62, 69, 81, 76,186,112, -225, 66,172,139,155,172,164,122,245,234,159, 85,171, 86,237, 89,157, 78,167, 35,132,128, 16, 66, 9, 33,104,212,168,209, 61,154, - 54,155, 45,233,252,249,243,177, 15, 43,157,127,215,177, 55,108,216,176, 76,205,242,142,189, 44, 77,231,116, 18, 66, 16, 19, 19, -115,223,233,252, 39,106,254,103, 13, 22, 0, 46, 32, 32, 96,115,203,150, 45, 59,109,217,178,133,187,124,249, 50, 23, 29, 29, 13, -155,205, 6, 81, 44,186,246,155, 53,107,166,170,236,143, 5, 5, 5,125,215,178,101,203, 33, 91,182,108,225, 54,111,222,204,181, -104,209, 2,132, 16,216,108, 54,216,108, 54,116,237,218, 85,121,159,149,133, 70, 16,132,137, 50,153,172,163,213,106,173, 15, 0, - 18,137,228,146,209,104,220,103,181, 90, 63,167,148, 22,186,163, 99,177, 88, 84, 23, 46, 92,184, 39,111, 90,182,108, 41,171,106, -218,234,212,169,115,152,227,184,168,178, 46,218,242, 62, 41,165,183, 46, 92,184,208,182, 60,205,122,245,234, 29,230, 56, 46,202, -190,127, 89, 26,165,215,137,162,120,235,252,249,243,109, 43,170,116, 2, 3, 3,159,106,219,182,173,215, 79, 63,253, 68, 18, 19, - 19,137, 82,169,132, 40,138,176,217,108,176, 88, 44,232,210,165, 75,165,230, 79, 83,169, 84,158,187,119,239,174, 21, 16, 16,128, -244,244,116,100,101,101, 97,244,232,209,215,236,219,149, 74,165,223,239,191,255, 94,199,215,215, 23, 58,157, 14,121,121,121, 24, - 54,108,216,191,254,226,234,209,161,230,123, 4,240,181,255,111, 19,145,189,235,224,205,183,238, 87,183, 94,189,122,167,100, 50, - 89, 96,121,231,188,172,115,111, 50,153,210, 46, 92,184,208,204,197,245, 19, 1,160, 47,207,243,181, 5, 65,168, 7, 32,194,106, -181, 6, 2,128, 84, 42, 77,227,121, 62,193, 98,177, 92, 49,153, 76,215, 1,108,165,148, 38,148,167,213, 51,244,249, 90,196,170, - 27, 88, 96, 20,123,171,106,126, 80, 87,119,115,250, 85,149, 92,183,173,103,232,243,235,221, 53, 89,127,163,185,138, 12, 9, 9, -249,184,248,239, 41,148,210,248,251,213,180, 1,131, 41,165, 94, 0,144,151,151,231,149,152,152, 24,180,117,235,214,152,185,115, -231,118,145, 25, 12, 31,153,128,203, 21,125,191,123,199, 90, 39, 4,142,132,161, 56, 6, 96,165, 98,210,206,125, 55, 31,196,141, -137, 11, 13, 13,157,223,179,103,207, 17,139, 23, 47, 86, 29, 59,118, 76,213,176, 97, 67,240, 60,111,175, 47, 80, 58,240,208,186, -117,235, 10,179, 15,128, 16, 18, 18, 50,239,177,199, 30, 27,186,112,225, 66,213,149, 43, 87, 84,145,145,145, 40,190,217,150, 40, -155,246,117, 77,155, 54,125,216,233,252, 75,143,189, 87,175, 94, 67, 23, 45, 90,164, 58,119,238,156,170,118,237,218,224, 56, 14, - 28,199,221,163,199,113, 28, 98, 99, 99,221,210,236,209,163,199,208, 37, 75,150,168, 78,157, 58,165,170, 87,175,158, 35,239,156, -154,231, 42,157,206,127,184,230,127,207, 96, 17, 66,184,106,213,170,173,138,141,141,237,185,101,203, 22, 30, 0, 78,157, 58,133, -236,236,108,132,134,134, 66,163,209, 64, 46,151,195, 96, 48, 84, 42,220, 23, 24, 24,248,117,177,185,146, 0,192,134,225, 3,112, - 75, 2,140, 79, 55, 65, 42,149,226,230,205,155,224,121,254,126, 66,199, 29, 60, 61, 61, 87,110,220,184,209,167, 89,179,102, 92, -102,102, 38, 34, 35, 35,145,157,157,221,114,255,254,253,205,159,127,254,249,231, 9, 33,207, 80, 74,247,187,171,185,109,219, 54, -168,213,106,168, 84, 42,168,213,106,152,205,102, 82,213,244,241, 60, 31,118,236,216,177, 0,141, 70, 3, 81, 20, 29, 75,169,246, -107, 7,162, 40,162, 67,135, 14,230, 10, 79,158, 32,132, 29, 59,118, 44, 64,169, 84,130, 82, 90, 66,207,102,179, 65, 46,151, 59, - 63, 33,194,102,179,161, 77,155, 54,102, 87,145, 43,187,185, 2,128, 53,107,214, 32, 40, 40, 8, 1, 1, 1, 80,171,213, 80, 42, -149, 85, 57,118,248,249,249,225,149, 87, 94,193,224,193,131,177,122,245,106, 72, 36, 18,231,227,128,175,175, 47,126,251,237, 55, -120,122,122,162, 70,141, 26, 37,182,255,107, 35,129,128,239,246,253, 55, 29, 17,217,129,125,154, 8,221,226,162, 22, 58, 42,215, -162,157,168, 88,180, 47, 21,109,182,156,221,135,110,207,112,121, 87,224,184,144, 99,199,142, 5,200,229,114,247,110,238, 54, 27, -154, 53,107,198,187,184,126,122,199,196,196,108,120,249,229,151,165,181,107,215, 38, 82,169, 20,130, 32, 64, 16, 4,123,121,172, - 65, 41,173, 33,138, 98,167,180,180, 52,250,197, 23, 95,124, 68, 8,121,130, 82,186,173,204,178, 73,245,141, 11,140, 98,239, 3, -167,209,114, 96,183,105,248,109,221,244,150,113, 77, 69,120,168,244, 55, 0,252, 99, 13, 22, 33,196, 83,169, 84,190,189,110,221, - 58, 41, 0,116,235,214,237,109, 66,200,171,148,210,252, 7,245, 27, 94, 94, 94,240,242,242, 66,195,134, 13,241,228,147, 79,122, - 55,109,218,116,114, 39,163,113,204, 94,160,220,107, 83,224,184,176, 95,127,191, 22, 96,255,127,232,128,230,210,158,157,106,165, - 21, 61,136,149,222,155, 66,180,209,164, 93, 7,111,197,186, 56, 86, 46, 40, 40,232,147, 94,189,122, 13, 90,188,120,177, 7, 0, -124,253,245,215,120,252,241,199, 17, 24, 24, 8,165, 82, 9,153, 76, 6,137, 68, 2,169, 84,234,248,116, 17, 17,226,131,130,130, - 62,122,252,241,199, 7, 46, 92,184,208, 3, 0,190,251,238, 59,244,233,211, 7,126,126,126,240,244,244,132, 92, 46,135, 76, 38, -131, 84, 42, 45, 97,184, 42,147,206, 23,122,116, 65, 77,165, 28,125,222,251, 8, 62, 62, 62,216,253,218,203,144,112, 28,198,109, -223, 15, 15, 15,143, 10,211, 89,158,230,201,147, 39,145,158,158, 94,230,177, 19, 66, 42,172,251,156,143,189,119,239,222, 3, 23, - 45, 90,228, 56,246,158, 61,123,194,207,207, 15, 30, 30, 30,144,203,229,144, 74,165, 37,150,242,242,192, 89,179, 87,175, 94, 3, -151, 44, 89,226, 1, 0, 43, 86,172, 64,183,110,221,224,227,227, 3, 15, 15, 15, 71, 94, 86,246, 28,253,147, 53,255,147, 6,203, -222, 55, 42, 32, 32, 96,208,207, 63,255,204, 57,223, 0,229,114,185,227,194,144,201,100,224, 56,174, 50,149, 22,137,137,137,121, -110,203,150, 45,142, 47,153, 74, 85, 10,114,185,188, 82,154,165,244,187,117,238,220,249,135,159,127,254, 89, 33,149, 74,161,215, -235,113,225,194, 5,120,121,121, 65, 38,147,161,127,255,254,124,187,118,237,252, 58,117,234,244, 19, 33,100,168, 59, 35, 20, 40, -165,208,104, 52, 37, 12,214,253, 52, 33,219, 47,208, 45, 91,182,128,231,249, 18,133,204,254,233,252,119, 64, 64,128, 91,186,114, -185, 28,135, 15, 31, 6,207,243,144, 72, 36, 16, 4, 1, 18,137, 4,191,252,242, 11, 94,123,237, 53,100,102,102,130, 16, 2,137, - 68, 2, 15, 15,151,173,155, 36, 48, 48,208,219,110,174,138, 35,128, 80, 42,149,144, 72, 36, 68, 16, 4, 98,111,198, 35,132, 16, -119,219,212, 5, 65, 64, 66, 66, 2,134, 15, 31,142, 21, 43, 86, 96,246,236,217, 24, 58,116,104,137,237,249,249,249,240,241,241, -129,143,143, 15, 20, 10, 69,149,203,194, 63, 9,177, 84,238,188, 59,231, 99, 21, 68,138,162, 78, 30, 34, 32, 2, 20, 20, 34, 21, -145,150,124, 3,159,126,178,128,119,183, 44,201,229,114, 28, 58,116,200, 97,130, 4, 65, 0, 33, 4,206,198,200,190, 4, 5, 5, -185,212,148, 74,165,179, 54,109,218, 36, 91,189,122, 53,214,174, 93,235,248, 13,181, 90, 13,111,111,111,248,249,249, 57,150,176, -176, 48,242,205, 55,223, 72, 27, 55,110, 60, 11,192,182,178, 77, 32,245, 82,213,252,160,238,192,110,211,138,204,229, 52,138,156, -107,115,154,112,185, 51,188,254,193,230, 74, 0,240,250,151, 95,126,233,215,188,121,115, 0,192,151, 95,126,233, 55,106,212,168, -215, 9, 33,111, 81, 74,173, 85,126,192, 2,214, 18, 66, 6, 23, 71,108, 21,221,187,119,151,125,245,213, 87,168, 87,175, 30, 38, - 76,152,224,251,233, 71, 31,245, 5,240, 83,249,101,169,100, 97,250,224,227,249,222,148, 22,149, 31, 42,210, 18,159,217,233, 9, -120,251,237,247, 92,214,201, 0,184,144,144,144,231,151, 46, 93,234,232, 14,225,227,227, 83,102,221, 36,145, 72, 28, 75, 5,166, -136, 20, 71,133, 70, 45, 94,188,216,161,233,239,239, 15,169, 84, 90,226, 6,123,251,242, 25,108, 91,254, 62,212,190, 65, 24, 62, -229,195, 74,167, 51, 76, 46, 67,152, 82,134, 38, 77,154, 64,165, 82,225,164,164,232, 86,230,225,225,225, 50,157,229,105, 58,215, -203, 0,160,211,233, 28, 81,123,147,201,132,216,216, 88,183,142,125,201,146, 37, 14, 77, 63, 63, 63,199,177,219,211,229, 92,215, -219, 31, 96, 42,210, 12, 9, 9, 25,181,108,217, 50,135,166,175,175,111, 9, 13,137, 68,130,149, 43, 87,222, 83, 71,220,175,102, -101,207,123,105,205,132,132, 4,204,157, 59,215, 81, 39,217,163,120,246,174, 70, 11, 22, 44,112,203, 96,255,167, 34, 88, 0, 72, -102,102,166,120,249,242,101,238,228,201,147,144, 72, 36, 8, 8, 8, 64,139, 22, 45, 0, 0,102,179,217,126,211, 37,245,234,213, - 75,227, 56, 14,246,155, 46,199,113,176, 90,173,142,246,100, 39, 35,195,101,103,103,139, 59,119,238,228, 86, 61,209, 3, 38, 10, - 52,125,251,125,244,236,211, 7,219, 67,101,224, 1,180,188,156, 9,153, 76, 38, 4, 7, 7, 91,236, 39,193,174,237,220, 55,171, -180, 57, 34,132,120,168,213,234,111,182,110,221,170,224, 56, 14, 5, 5, 5, 16, 69, 17,237,218,181, 3,199,113, 56,127,254, 60, -222,124,243, 77,108,216,176, 1,155, 54,109, 82, 54,107,214,236, 27, 66, 72,125, 74,105,129,147,153,218, 85, 86,225,244,240,240, -128, 74,165,114, 24, 44,251, 49, 23,183,169,151,110,146, 73,190,112,225, 66,243,242, 52,237,145,132, 1, 3, 6, 56,250,156,217, -205, 80,233, 79,169, 84,138,243,231,207,151,101,250,238,209, 20, 69, 17,237,219,183,183, 55,197, 65,163,209, 96,239,222,189,142, -237, 77,155, 54,133,201,100,130,191,191, 63, 46, 93,186,228, 82, 51, 35, 35,131,166,164,164,144, 85,171, 86, 65, 34,145,192,207, -207, 15, 42,149,138,252,244,211, 79,175, 43, 20,138, 48,163,209, 40, 90, 44, 22,132,133,133, 45,168, 81,163,134,253, 28,105,111, -220,184,225, 87,158, 38,207,243, 80, 40, 20,248,238,187,239, 48,119,238, 92,188,241,198, 27, 37, 46, 44,158,231, 97, 48, 24,224, -239,239,239, 48, 89,165, 47,188,191, 98,216,238, 95,173, 73, 65,113,225,212,118, 92, 60,183, 11,162, 77,132, 77,164,160,212, 6, -209, 10,156,220,121,180, 78,234,173,148, 80, 10, 10, 20,247,184,177, 20,106,173,157,252,229,245, 0,108,222,155,105,156,231, 42, -157,130, 32,192, 98,177, 96,235,214,173,184,113,227, 6,118,236,216, 1,189, 94,239,200,199, 54,109,218, 96,212,168, 81, 8, 10, - 10,114,153,159,148,210,239, 18, 19, 19,155,182,111,223,158,228,230,230, 34, 55, 55, 23,122,189, 30, 54,155, 13, 86,171, 21,130, - 32, 64,161, 80, 64,169, 84, 34, 48, 48, 16, 6,131,129, 26,141,198,239,202,211, 20, 69,146,167,187, 57,253,234,111,235,166,183, - 28, 56,141, 98,253,135, 4,117, 34,228,186,125,103,188, 71,109, 59,246,122,119, 66, 57, 10, 20, 29, 58, 71, 64,109, 54, 91,230, - 75,227, 63, 24,247,176,207, 81, 41,198, 76,156, 56,177,190,115,243,244,176, 97,195,112,225,194,133,250,159,127,254,249, 24, 0, - 95, 86, 86,211, 7, 8, 5, 0, 43,240, 27,138, 22,172,215,235,201,144,205,155, 7, 0,120,118,211,166, 77, 24, 58,116, 40, 62, -249,232,163,134,165, 13, 86,137,178, 68, 41, 18,174, 29, 64,194,245,131, 16, 69,234, 20, 5, 47,251,111,234, 94, 58, 73, 97, 97, -161,225,216,177, 99,154, 21, 43, 86,192,219,219, 27, 81, 81, 81,142, 86,138,210, 55, 88,251,255,174,202,146, 78,167, 51, 92,190, -124, 89,243,195, 15, 63,192,215,215, 23, 53,106,212,128, 74,165,114,104,202,100, 50, 28,221,190, 17, 99,134,247, 70,102,194, 69, -204,127,117,144,219,233,124,161,123, 23,132, 43,100, 24, 48,251, 3, 68, 71, 71, 99,253,224,126,224, 8, 48,118,207, 81, 72,165, - 82,172,232,221, 1, 50,185, 12, 99,247,252,225, 42,157, 14,205, 19, 39, 78, 64, 20, 69, 68, 68, 68, 64,167,211,193,211,211, 19, - 10,133, 2, 18,137, 4, 59,119,238, 68,255,254,253,177,122,245,106,180,105,211,198,229,177, 23, 22, 22, 26,206,157, 59,167,249, -254,251,239,225,235,235,139,240,240,112,168, 84, 42, 71, 96,194,110,180,120,158, 71, 84, 84, 20,242,242,242, 80,179,102,205, 10, - 53,181, 90,173,225,228,201,147,154,239,191,255, 30, 62, 62, 62, 8, 11, 11,115, 68,216,236,166,104,230,204,153, 37, 52,154, 52, -105,114,223,154,149, 61,239,165, 53, 7, 12, 24,128, 90,181,106,193,211,211, 19,106,181,218,161, 93,145,230,127,218, 96, 81, 74, -105,241, 40, 10, 68, 71, 71, 35, 59, 59, 27,114,185, 28, 45, 90,180, 64,102,102, 38, 52, 26, 13,164, 82, 41, 40,165, 24, 60,120, - 48, 63,101,202,148,128, 98, 83,229,168,240,203,105, 75, 23, 57,142, 67,219,182,109,113,161,184,229,167,103,159, 62, 8, 11, 11, -131,189, 19,135, 66,161,192,208,161, 67,201,107,175,189, 38,216,163, 23,148, 82,232,245,122, 52,110,220, 88, 89, 65,116,228,213, -159,126,250,201, 75, 38,147,161,160,160,192,209, 68,198,243, 60, 46, 95,190,140, 79, 62,249, 4,207, 62,251, 44,238,220,185,131, -144,144, 16, 76,158, 60, 89,243,193, 7, 31,188, 10,224, 93, 87,153,163,209,104, 28,230, 74,165, 82, 97,196,136, 17, 66,187,118, -237, 2, 52, 26, 13, 60, 60, 60, 96,111,238,179,217,108,104,219,182, 45,113, 21,117, 16, 69, 17,219,183,111,135, 32, 8, 46, 35, - 88,197,109,214,110,105, 30, 59,118,204, 97,206,156,159,138, 8, 33,184,112,225,130,195,204, 21, 23,230,138, 52, 41,207,243, 80, -171,213, 8, 10, 10,130, 82,169,132, 74,165, 34, 91,182,108,121, 43, 34, 34, 34,248,229,151, 95,230,242,243,243,185,216,216, 88, -244,238,221, 91, 16, 69, 17,102,179, 25, 93,186,116,169, 48, 31, 37, 18, 9,142, 31, 63,142, 15, 62,248, 0,211,166, 77,195,146, - 37, 75,208,173, 91,183, 18, 70,129, 16,130,106,213,170,193,211,211,243,191,115,117,137,128,217,106,129,174, 80,239,104,194,181, -217,108, 56,183,247, 76,157, 91,103,174,197,252,252,195,106, 9, 0, 24,246,110,116,254, 86,240,147, 11,127,172,219,201, 87,122, -108,111,182,249,152,139,166, 66, 76,152, 48, 1, 51,102,204,192,224,193,131,177,115,231, 78,188,249,230,155,120,254,249,231, 75, - 68,176,220,193, 98,177, 44,125,230,153,103, 70,175, 95,191,190,222,180,105,211, 56,123, 4, 75,165, 82,129, 16, 2,131,193, 0, -163,209, 8,189, 94,143, 43, 87,174,136, 47,190,248,226, 85,147,201,180,180, 60, 61, 43, 81,158, 85,201,117,219,106, 87,231,107, -105,227, 63,246,104,223, 42, 66, 79,148,205,243, 30,175,221,141,118, 27, 26,225, 3, 74, 65,197,162, 40,159,209,168,197,235, 83, - 39,243,127,231,169, 34,132,244,238,222,189,123,143, 57,115,230,220,179,109,206,156, 57,184,116,233, 82, 15, 66, 72, 66,121, 77, -162,101,225, 13,132, 41,130,130, 62, 3, 0,239,187,119, 39,229, 2, 73, 0, 48, 4,232,105, 3,250,237,220,185, 19, 0, 80,189, -122,117,136, 64, 3, 2,124,199, 3,107,173,101, 69, 5, 41,133,197, 98,133, 94,111,172,208, 88,217,255,119, 21, 92,182,215,245, - 60,207,163, 97,195,134,232,217,179, 39,164, 82, 41, 60, 60, 60, 28,205, 57,101, 69, 49, 92, 52,221, 83, 0, 34, 33, 4, 81, 81, - 81,232,209,163, 7,164, 82, 41,212,106,181,195,180,200,100, 50,240, 60,143, 70,237,186, 98,245,202, 57,120,174, 79, 51, 60, 27, - 23,136, 13,231,178,220, 74,103,132, 82,134, 26, 42, 57,162,163,163,225,225,225, 1, 66, 0,129,255,179, 62, 85,169,148,144,201, -101, 21,166,179,180,102, 90, 90, 26,226,227,227, 17, 31, 31, 15,142,227,208,190,125,123, 71,212,229,250,245,235,120,247,221,119, - 97, 52, 26,221, 58,118,142,227, 80,187,118,109,116,233,210, 5, 50,153, 12, 42,149,170, 68,211,160, 61, 79, 11, 10, 10, 80,171, - 86, 45,108,222,188, 25, 29, 58,116,112,169, 25, 29, 29,141,142, 29, 59, 66, 42,149, 58, 30,164,149, 74,165,227,190, 81,108,238, - 28,191,209,172, 89,179, 74,105,238, 56,126, 7,203,119,254, 14,163, 73, 68,190,206, 82,226, 11,193,254,158, 56,248,253, 52,183, -142,221,174,185,108,217, 50,228,230,230, 58,234, 32,123, 0,198, 30, 60, 9, 15, 15,199,162, 69,139, 30,173, 38, 66,251,109,193, -238, 42, 67, 67, 67, 97,239,231,161,209,104, 32,147,253,217,199,219,106,181, 98,195,134, 13, 8, 8, 8,112, 44, 94, 94, 94,229, - 22,232,234,213,171,131, 82,138, 9, 25, 69,221, 12,126, 11,145, 34, 1,192,227, 25,212, 17,221,177,217,108,248,233,167,159,224, -108, 96, 60, 60, 60, 42,108, 46,146,201,100,157, 90,180,104,193, 25,141,198,123,204,213, 7, 31,124,128,161, 67,135,162,110,221, -186, 16, 69, 17,133,133,133,232,220,185,179,100,193,130, 5,157, 42, 99,176, 84,170,162,254,252, 38,147, 9,123,247,238,133,143, -143, 15,252,252,252,224,235,235, 11, 15, 15, 15, 40, 20, 10, 16, 66, 92, 54,151, 81, 74, 49, 96,192, 0, 71,161,115,142, 90,149, - 54, 91,135, 15, 31,118,171,153,140, 82,138, 86,173, 90, 65,173, 86, 67,163,209, 64,163,209, 96,251,246,237,142,237, 45, 91,182, -132, 40,138, 8, 8, 8,192,145, 35, 71, 92, 86,186, 97, 97, 97,142,253, 37, 18, 9,249,233,167,159, 94,143,140,140, 12, 30, 59, -118, 44,199,243, 60, 78,157, 58,133,139, 23, 47, 34, 40, 40,200,209, 39,203, 85, 58,181, 90,109,234,130, 5, 11,108, 95,125,245, - 21, 0,160, 75,151, 46,200,203,203, 75,119,218,158, 53,124,248,112,199, 40, 69, 0,200,206,206,206,250, 15,248, 43, 88,205, 86, -232, 12, 6, 20, 22,232, 28,209,160,244,148, 52,239,105,175, 77,148,124, 50,110, 36, 0,224,181,121, 95,162, 96,201,159, 21,216, -198,215,134, 4, 60,241,233,218,233, 0,250, 87,164,175,211,233, 96, 52, 26, 81,163, 70, 13, 28, 63,126, 28, 5, 5, 5,232,214, -173, 91,137, 8,169,115,158,186, 56,247, 38, 66, 72,187, 62,125,250,252,241,249,231,159,215,172, 95,191, 62,209,106,181,208,233, -116,112,254, 60,119,238, 28, 93,179,102,205, 45,157, 78,215,150, 82,106, 42, 79,111,123,242,215, 55,122,134, 62,191,126,255, 89, - 89, 31,255,168,171,158,201, 57, 53,173, 89,201,114,109,190,254,138,193, 70, 47,130,218, 0, 27, 68, 80,171, 8, 27, 40,254,206, -241,219,132,144,176, 58,117,234,188,180,122,245,234, 50,243,139,231,121,172, 94,189, 26,237,219,183,127,137, 16,114,185,162,206, -253,118,218, 0, 50,131, 68, 50,109,235,143, 63, 22,245,229,234,210,101, 90, 27,139,229,181, 35,128,169, 65,163, 70, 79, 29, 62, -124,216,203, 94,175,120,121,121,129, 82,202,235,116, 58,175,182,109,219, 62, 85, 86,179, 43, 21, 1,139,197, 2,189,222,136,188, -188, 2,152,204,150,226, 58, 83,132,205,102, 45,254, 20, 97, 45,174, 71, 37, 2,239,209,169, 77,245,194, 34,163, 69,114,247, 29, -189, 19, 94, 78, 93, 79, 9, 33, 8, 12, 12,132, 84, 42, 45, 17,101,114, 39,122, 85, 6, 54,123, 93,232,231,231, 7,153, 76,134, -179,123,127, 70,250,165,131,144, 18, 10,209,102,129,104, 53,195,102, 53,131,231,120, 92,185,153,130,232, 96,151, 99,135, 28,233, -236,249,246,108,180,110,221, 26,235, 7,247, 3, 33,192,203,123,142, 66, 34,145,224,251, 1, 93, 33,151, 73,241,226,206,163,238, -166,179,196,177,159, 56,113, 2, 19, 38, 76,192,135, 31,126, 8,165, 82,105,111, 57,193,229,203,151,241,227,143, 63,162,123,247, -238,110, 31, 59, 33,196,113,236,130, 32, 96,250,244,233, 72, 73, 73,193,188,121,243,208,188,121,115, 72, 36, 18,228,230,230,162, -109,219,182, 72, 75, 75,115, 59, 63,237,205,120, 50,153,172, 68,180,201,110,252,170,114,142,236,154, 35, 7, 4, 99,203,161, 53, - 32, 32, 56,250,253,196, 18,247,162, 69,107, 15, 84, 90,115,198,140, 25, 37,210,249, 40, 70,175,202, 52, 88,148, 82, 26, 26, 26, - 10, 81, 20, 75,152,170,210, 29,106,237, 33, 63,231,144, 98,133,125, 16,120, 30,162, 40, 58, 10, 3, 95,198,246, 35, 71,142,220, - 99, 2,150, 47, 95, 94,225, 13,220,106,181,214,247,240,240, 40, 17,189,146, 74,165,152, 62,125, 58, 70,140, 24,225, 48, 87, 82, -169, 20, 43, 86,172, 64,108,108, 44, 76, 38, 83,253,138,210, 42,149, 74,117,141, 26, 53,226,236, 81, 32,165, 82, 73,134, 14, 29, -202, 91,173, 86, 71,158,216, 23,123,223, 52, 87, 38,195, 30,109,218,177, 99,135, 91, 17, 44,119,251, 32, 81, 74,113,230,204,153, - 18,166,205, 62, 10, 6, 0,206,156, 57,227,232,159,229,174,166,205,102,131, 82,169, 36, 82,169,148, 40, 20,138, 48,187,185,226, -121,222,113,190,157,251,228,185,186, 80,206,158, 61,219,185,162,237,231,206,157,251, 79, 78,199, 32, 66,132,217, 98,129, 94,103, - 66, 65,161, 30,179,222,255,182,104,195, 44, 28, 3,112,172,221,152, 9,120,185,103,247, 46, 0,170, 85,210, 16,192,126, 3,251, -233,167,159, 32,145, 72,176,121,243,102,120,122,122,162, 95,191,126,240,244,244,196,180,105,211, 48,120,240, 96,183, 35, 88,197, -101, 41,143, 16,210,238,213, 87, 95,253,227,227,143, 63,174, 30, 30, 30, 14,147,201, 4,179,217, 12,147,201,132, 27, 55,110, 96, -205,154, 53,137, 58,157,174, 29,165, 52,207,149,222,246,228,175,111,252,124,228,245,148,184, 39,159,212, 95, 78,251, 13,119,239, -102,193,106, 77,134,104,179,194,108, 45, 26,145,108,179, 90, 97,181,218, 32,240,156,231,162,207,167,236, 44,234,240, 79, 76, 3, - 7, 14,124,236, 33,158, 42,122,237,218,181,172,106,213,170,217, 43, 49, 79,147,201, 68,138, 31,224, 40, 0,123, 7,119, 45, 42, -232,136,238,204,113, 96,244, 39, 31,126, 24,102,111,190,127,255,195, 15,195, 38, 79,154, 52, 26,192,130, 75,231,206,173, 30, 57, -114,228,171,235,214,173, 43,241,157,145, 35, 71,226,210,185,115,171,203, 14, 17, 20, 71,176, 12, 6,100,100,229,224,133, 49,111, - 57, 66, 7, 0,133,179, 67,165, 69,255, 43, 0, 32, 51,237, 6,198, 79,120, 77, 94,222, 3, 85,131, 6, 13, 32,138, 98,137,104, - 72, 21,250, 94, 57, 71,134, 28,251,121,122,122, 66, 42,149,226,198,225,159, 49,105,204, 32,192,102, 6,181,232, 1,179, 14, 48, - 23, 66, 52,233, 64,164, 74,192,162,119,169,107, 79,167,167,167,103, 81,159, 80,129,135, 76,250,167,249,115,142, 92,185,115,227, - 46,125,236, 9, 9, 9,120,249,229,151, 97, 54,155, 49, 96,192, 0,152, 76, 38, 24, 12, 6,232,245,122, 68, 69, 69, 65,167,211, -185,125,236,246,123,167, 84, 42,197,196,137, 19, 17, 27, 27,139,119,223,125, 23, 83,167, 78, 69, 84, 84, 20,198,142, 29,139, 53, -107,214, 32, 38, 38,166, 66, 93,187,102, 81,147,123,145,166,253,120, 75, 55,229,217, 91, 10,220, 61, 71,101,105,218,103, 23, 41, -125,222,255,247, 76,215, 74,107,126,240,193, 7,200,200,200,184, 39,114,101,255, 59, 52, 52, 20, 11, 23, 46,124, 36, 35, 88,142, -225,164,246, 27,168,253, 70,238, 92,185,171, 84, 42,108,216,176,161, 68,231,186,138,194,210, 28,199, 65, 20, 69,108,171, 86,244, -253,222,197,145, 43,231,255,251,246,237,139,200,200,200, 18,209, 43,165, 82, 89, 97,161, 17, 69, 17,183,111,223,198,133, 11, 23, -208,186,117,107,228,229,229, 65,194,113,120,237,220, 57, 52,120,230, 25,152,164, 82,136,162, 8,153, 76,134,209,163, 71,187,213, - 81,253,143, 63,254,240,113,254,191, 65,131, 6, 73,113,113,113,161,199,143, 31,119,116,124, 47,110, 62,115, 24, 13, 55, 47,106, - 60,245,212, 83, 37,162, 86,206,230,202,121,249,237,183,223,220,106, 34,164,148, 34, 46, 46,206, 17,189,242,240,240,192,166, 77, -155, 28,219,237,225,231,192,192, 64,183, 52,237, 79,240,197, 29,219, 97, 52, 26,197,130,130, 2,238,228,201,147,144,201,100,142, -115,162, 84, 42,161, 80, 40,238,107,112,194,127, 30,155, 8,147,197, 2,189, 94,143,194,194,162, 25, 66,110,156, 47,217,143,217, -108,172,250,224, 52,123,148,170,160,160, 0,187,119,239,198,198,141, 27,209,188,121,243,123, 58,185, 59, 95,183,110,148,209, 12, - 66, 72,251, 41, 83,166, 28,125,239,189,247, 66,124,125,125, 97, 54,155,113,231,206, 29,124,243,205, 55, 41, 58,157,174, 61,165, - 52,163, 18,174, 13, 22,139, 21, 6,157, 17,121,249, 5,152, 57,103, 69,185, 85, 4, 0,100,167, 95,193,208,161,195,100, 15,243, - 52, 81, 74,147, 1, 60,239,116, 93,173, 2, 96, 15,199,231, 83, 74, 71, 84, 70, 79, 2,116,122,114,224,192, 46, 19, 39, 78,116, -172,155, 56,113, 34,142, 30, 61,218, 69,178,126,253, 5, 11,176,151, 95,191, 62,230,243,207, 63,119,236,243,249,231,159, 99,195, -250,245,123,108,192,222,242,234, 14,123, 19, 97, 97,161, 30,158,222,193, 72,142,223,231, 50, 45, 82,222, 0, 42,138, 46, 31,252, - 74,247,187, 41, 93, 63, 85,162,252,208, 70,141, 26,217, 91, 23, 32,149, 74,209,176,203, 64,124, 58,127, 41,228, 28,197,147,221, - 26,162,154,194, 6, 40,125, 33,237, 48, 13,196,187, 70,241, 67, 71, 83,183, 30, 80,247,191, 53, 25,183,212, 10,188,184,227, 32, -164, 82, 41,126, 26,220, 27,114,185, 20,207,254,188, 31, 82,169, 20, 63,143,122, 2, 82,153, 20, 61, 23,255,232,214,131,138,253, -216,111,220,184,129,195,135, 15, 35, 58, 58, 26,215,175, 95,135,115, 63, 91, 74,169,219,166,173, 97,195,134,142,128,132, 68, 34, -193,221,187,119,209,167, 79, 31,199, 3,254,190,125,251, 48,101,202, 20,140, 26, 53, 10,157, 58,117, 42,179, 95,108,105,205,152, -152, 24, 71,224,160,180, 9,118,110,182,173,204, 57, 42, 75,211, 81,126,171,120,222,157, 53,223,123,239,189, 50,205,122,101, 52, -255,211, 6,203,126,129,148,215,238,172, 86,171,241,202, 43,175, 96,198,140, 25,240,247,247,119,217,119,198,238, 92, 43, 98,235, -214,173,247,172,219,188,121,179,171, 38,194,203, 94, 94, 94,177,157, 59,119, 70, 94, 94, 30, 18, 19, 19,161, 86,171,209,224,211, - 79,113,238,229,151,209,100,241, 98,112, 93,186,128, 16, 2,153, 76,134,115,231,206, 65,169, 84, 94,174,108,196,192,195,195, 3, - 62, 62, 62,142, 54,117,187,209,114, 50, 88,212, 29, 51,180,109,219,182, 50, 71,232, 84,165, 15,150,189,226, 61,122,244,104,137, -254, 87,206,205, 28, 71,143, 30,117, 68,176,138,247, 39,174,206, 83,241, 83, 29,181,235,169, 84, 42,248,250,250, 66, 46,151, 59, -140,149,221, 92,185, 99, 46, 93, 77, 36, 26, 17, 17, 81, 98, 34, 82,137, 68, 82, 98, 34,210,127,123, 19,161, 94,111, 64, 97,129, -254, 65, 54,105, 21,153,179,226, 1, 39, 27, 54,108, 64,171, 86,173,238, 49, 87,246,168, 99, 21, 12, 71, 18, 33,164,211,252,249, -243,143,125,246,217,103, 62,133,133,133,248,246,219,111,243, 10, 11, 11, 59, 81, 74,147, 42,165, 5,192, 98, 54, 67,103, 48, 66, - 91, 88,148, 7, 55, 47,252,228,210,148,253,155,169,223,168,209,240,111,191,253,246,158,245,223,126,251, 45,174, 95,191, 62, 28, -231,206,237,109, 9, 44,121,125,218,180,218,205,155, 55, 15, 3,128,215,167, 77, 75,106, 9, 44,169,232, 58, 55, 23, 55, 17, 22, - 22, 22, 69, 61, 12,218,204, 7, 83, 78,139, 77, 70,121,125,174,170,114, 67,180,215,183, 82,169, 20, 61, 6,191,128,148, 91, 87, - 16,173,206, 68, 53,111, 21,104,126, 50,164, 93,222,193,185,108, 21,230, 45,222, 94,169,116,170,229, 50, 40, 20,114,167, 62, 87, - 10,200, 20,114, 71, 58, 21, 74, 37, 36,114, 89,165,143,253,234,213,171, 80, 42,149,176,217,108,247,220,111, 42,123,252,206,198, -229,243,207, 63,199,148, 41, 83,176, 98,197, 10,156, 59,119, 14, 77,154, 52, 65,183,110,221,144,158,158,142,179,103,207,194,104, - 52,186,157, 78,231,126,113, 23, 47, 94,196,175,191,254,138,248,248,120, 36, 38, 38, 86,249,188, 59,107,150, 54, 88, 27,118,157, -198, 83,221,155, 85, 73,115,230,204,153, 72, 79, 79, 47, 17,185,114,142,110, 62,210, 17, 44,123, 19,147,211, 77,249,158, 40,149, - 90,173,118,116,136,244,244,244,116, 25, 25,178, 27,172,184, 91, 5, 37,250,114,217, 35, 89, 0, 48,106,212,168,123, 34, 88,165, - 39,167, 43,141,209,104,220,183,111,223,190,166,125,251,246,229, 47, 95,190,236,104,138, 52,181,105,131, 38,139, 23,227,252,196, -137,232,152,144, 0,131,217, 12,133, 66,129,237,219,183,155,117, 58,221,190, 74, 86, 22,196,217, 96,169,213,106,120,121,121, 57, - 12, 70,101, 92,121,121, 79,136,206,255, 87, 38, 34,100,239,115,102, 95,236, 55, 86, 66, 8,244,122,189,163,179,102,101,162, 34, - 54,155,205,113,225,217, 59, 40,122,123,123, 59, 42, 13,251,104, 50,119,155, 71, 93, 77, 36,170, 80, 40, 60, 15, 28, 56, 80,203, - 62,141, 68,102,102, 38, 6, 15, 30,124,237,223,126,113, 81, 80,152,173, 54, 20,234, 13, 40,212,235, 30,184,254,234,213,171,113, -227,198, 13,152,205,102,188,255,254,251,247, 24,171,202,116,114, 47,163, 92,221,104,214,172,153,216,171, 87, 47, 28, 61,122, 20, -114,185,220, 66, 41,173,244,252, 85, 84, 20, 97,182, 90, 97,208,235, 81,168,213, 62, 18, 79,173, 23,207,157,251, 73,173, 86, 15, - 6,160,201,205,205,229,189,188,188,160, 82,169,160,215,235,243,248,226,145,130, 71, 0,147,183,197,242,225,160, 65,131, 62, 3, - 0,133,197,242,225, 17,192, 84,209,117,110,177, 22,155,245, 7,152,143,246,122,171,188, 58,169, 42,209,105,251,141, 84, 42,149, - 66,224,121,124, 59,119, 50,162,213, 25,104, 22,233, 1, 99,218,117,200, 60,252, 65,188, 35, 48,111,241,118, 92, 74,200,174, 84, - 58,135,172, 92,143,240,240,112,108,121,166, 31, 20,114, 5,134,108,216, 13,137, 68,130, 29, 99, 7, 67, 42,147,161,219, 87,223, - 87,233,216,181, 90,109,185,145, 42,119, 35, 88,165,143, 93, 34,145,160,105,211,166,168, 83,167, 14,246,238,221,139,102,205,154, -225,250,245,235,184,126,253, 58, 18, 18, 18,112,238,220, 57,228,228,228, 84,250, 28,173, 93,187, 22,217,217,217,144,201,100,200, -204,204, 68,124,124,188, 91, 83,177,184, 58,239,118,234, 61, 62, 19, 0, 16, 82,205,171, 82, 6,203, 89,243,163,143, 62,186,199, -180, 63,138, 45, 29, 66, 57, 38, 64, 95,175, 94, 61,165,115,251, 41,199,113,240,240,240, 32, 83,166, 76,225,139,255,134,151,151, - 23,170, 85,171,230, 86,179,155, 68, 34,209,183,108,217, 82,105, 47,128,118,227,164, 86,171,249,169, 83,167,146,229,203,151,151, - 27,213,114,209, 7,235,179, 17, 35, 70, 60,159,148,148,228, 19, 16, 16,128,212,212, 84,200,100,178,162,139,162,115,103,196,221, -186, 5,115, 81,159, 34, 92,189,122, 21, 75,151, 46,213, 26,141,198,207, 42,155, 81, 26,141, 6,126,126,126,142,166, 65,123, 4, -199,201, 44,210,170, 84,100,165,151,202, 68, 28,236,154,206, 6,203,126, 99, 29, 51,102, 76, 9,179,229,118,129, 16, 4,107,199, -142, 29, 5,123, 58, 44, 22, 11, 26, 53,106,132,244,244,116, 72, 36, 18,200,100,178, 18,145, 59,119, 12,150,171,137, 68, 5, 65, -128,201,100, 66,135, 14, 29, 64, 8,193,151, 95,126, 89,165,200,203, 63,206, 96, 89, 69,162,209,248, 33, 36,164, 46,170, 5, 24, - 32,138, 15,238,237, 47, 86,171, 21, 99,199,142, 45, 17,177,178,143, 84,180, 55,241, 23, 53, 43, 89,170, 60,105,171,253,186,190, -159,249,223, 68, 10, 71,211,150, 86,107,248,215,157,195, 26, 53,106,120, 22, 55, 25,150,230, 7, 74,233,175,101,158,155,226, 41, - 25,120, 96,246,157, 59,119, 26,122,121,121,161, 71,143, 30,216,186,105,211,150, 31, 0, 71,200, 38, 23, 72,242,185,123,119, 98, -241,223,201,174,130,122, 69,125,176,140,208,106,245, 15,252, 56,239,247, 65,175,172, 7,106,158,231,177, 97,241, 7,136, 86,165, -161,105,117, 57, 14, 31, 61,141, 86,225, 0, 76, 85,111, 1,182,247,109, 82,169,148,144,202,228,142,116, 42, 84, 42, 72,164,178, - 42, 31,187,115,125, 90,186,190,172, 74, 4,207, 57, 63, 95,120,225, 5, 76,155, 54, 13, 61,122,244,192,245,235,215,177,127,255, -126, 92,191,126, 29, 19, 38, 76, 64, 76, 76, 12,122,246,236, 89, 41,205,245,235,215, 35, 47, 47, 15, 28,199, 33, 43, 43, 11,122, -189, 30, 51,102,204,184,239,243,110, 39,126,215,251, 0,128,159,118,158,170,178,230,155,111,190,137,187,119,239,150,136, 92, 61, - 42, 81, 43,151, 6,235,234,213,171,101,182,247,197,196,196,164,117,239,222, 61, 32, 53, 53, 21, 26,141,198,165,185, 34,132,116, -179,207,149,113,225,194,133, 50, 53,107,214,172,105,238,222,189,187, 36, 56, 56,184,196,232, 65,181, 90, 93,226, 98, 45, 75,179, -184,242, 47, 32,132,188,212,174, 93,187,239,126,251,237, 55, 85,157, 58,117,144,159,159, 15, 74, 41, 86,172, 88,129,113,227,198, - 65,161, 80,224,234,213,171,232,215,175,159, 78,167,211,189,228, 60, 7, 86, 89,154,101, 25, 25,142,227, 28,243,195,148, 97,174, - 42, 60,118,103,230,207,159,239,152, 11,170, 34,150, 44, 89, 2,148,154, 82,161, 44, 77, 74, 41, 62,249,228,147, 7,166,121,229, -202,149, 21,206,219, 35, 35, 35,191,124,236,177,199,132,196,196,196, 18,166,202,121, 41,163, 66, 42,161,233,106, 34, 81,158,231, - 17, 24, 24,136,247,222,123, 15,126,126,126, 8, 10, 10,186, 39,242,226,234, 28, 85,241,233,253, 47,213,164, 28, 61, 57,255,179, -153,237,151,124,189, 81, 34,151, 1, 71,246,255,132,252,156,187, 37, 35,176,230, 63,135, 68,203,154,117,133,233,212,110,183,210, -105, 52, 26,241,209, 71, 31, 97,230,204,153,247,204,129, 83,206,121,191,175, 99,119,199,100,149,165, 41,138, 34, 81,169,125,160, - 80,135,160, 65,140, 15, 68, 55,230,234, 20,255,254,243,174, 75, 76, 76,244, 10, 15, 15,199,181,107,215, 8,254,236,143,245,231, -185,146,201,134, 0,248,181, 34, 77, 2,156, 91,179,102, 77,195, 70,141, 26,225,203, 47,191, 4,128,103,159,219,177, 99,240,211, -122,189, 1, 40,154,124,180,216,140,185, 76,167,141, 82,162, 84,121, 67,161, 14, 70,131,134,222, 16, 69,247,231, 60,165, 21, 28, -187,253,230, 87, 58,122, 85,201,137,164,239,209,180, 63, 32,221, 60,242, 11,250,244, 14,195,161, 99,231,177, 59, 81,133, 48, 89, - 42, 66,116, 25, 16, 51, 46,227,213,129,205, 48,111,125,209, 77,252,252, 73,215,154,132, 16, 28,122,237, 69,168, 85, 10, 60,185, -230, 87, 72,165, 82,252,254,234, 51,144, 74,229,232,248, 89, 81,147,236,185, 15,167, 67, 34,151, 35,250,127, 51,221, 74,103,233, -150, 26,123, 87, 14,231,125, 42,138, 96, 85,116,236, 5, 5, 5,200,205,205,197,119,223,125,135,145, 35, 71, 34, 61, 61, 29, 9, - 9, 9,184,118,237, 26,126,248,225, 7,199,232,244,202,164,211,110, 94, 38, 77,154, 4, 74, 41, 26, 52,104,128,153, 51,103,162, - 77,155, 54,149, 62, 71,165,207,123,105, 92, 69,175, 42,210,156, 55,111, 94,149,202,210, 35, 97,176, 42,122, 42,225, 56, 14,254, -254,254,142,194,225, 92,240,170,242,164,203,243, 60,172, 86,171,163,227,180,125, 1,128,190,125,251, 98,235,214,173,238,140,140, -248,141, 16, 50,188,126,253,250,223,204,154, 53, 75,211,177, 99, 71, 33, 36, 36, 4, 45, 90,180,192,213,171, 87,241,203, 47,191, - 88, 22, 46, 92,168,213,233,116,163, 40,165, 59,171, 82, 39,219, 95, 61,227,188, 84, 6,155,205,150, 24, 31, 31, 31,252,201, 39, -159,240, 28,199, 97,222,188,121,206, 47,185,190,167, 16, 30, 61,122,212,234,170, 73,198,106,181, 38,198,199,199, 7,127,250,233, -167, 60, 33,196,161,233, 60,249,171,115,222,185,163, 89,150,185,180, 15,120, 40,107, 41, 43,237,101,157,227,138, 38, 18, 21, 4, - 1, 87,175, 94,197,140, 25, 51, 64, 8,193, 79, 63,253,244,159,184,184, 14, 29, 79, 89,222, 54, 54,196,103,200,192, 78,141, 8, - 56,152,204,247, 14, 64,227,179,114, 29,230,234,137, 79,215, 98,227,107,131,221, 49, 59, 55,142, 31, 63,238,251,209, 71, 31, 9, - 60,207,227,243,207, 63, 47, 49,217,111,233,243,126,236,216, 49,107,149,154,247,138,175,103,179,217, 12,189,190,106, 81, 19,202, -145,195,243, 62,122,167,251,146,111,183, 74, 8, 49,225,200,190,159,144,151, 91,246,208,116,153, 68,192,170, 53, 91,172, 2,207, - 37,254,205,167,110, 73,183,110,221,102,236,218,181, 75, 8, 15, 15,175,178, 72,123, 96,235,130, 5, 11, 30,123,230,153,103,124, -235,215,175,143,141, 27, 55, 2,128,172,120, 65,241,204,238,191,185,103,146,196,205,159,127,252,206,179, 75,191,221, 42,227,136, - 25, 71,246,255,132,188, 82,102,189, 52, 82,169, 4,171,215,108, 54, 11, 2,127,197, 85,189,238, 28,189,186,223, 27,162,115,217, -107,214,231,121,124,249,203, 82, 4, 52,234,133, 65,125,227,112,240,203,103, 48, 40,218, 0,243,186, 97,104, 56,112, 37, 86,188, - 94, 20,189,105,186,254, 13,183,238, 63, 30, 30,106, 71, 7,114,142,227, 32, 87,168, 32,145,255,217,127, 72,166, 82, 65,168, 68, - 36,203,126,236, 21, 69,170, 42, 27,193,226, 56, 14,145,145,145,168, 89,179, 38,218,181,107,135,102,205,154,161,115,231,206, 56, -123,246, 44,206,158, 61,139, 9, 19, 38,148,107,174,220, 57, 71,221,187,119,199,149, 43, 87,238,187,144,151, 62,239, 15, 2,119, -202,210,203, 47,191, 12, 0,143,110, 31, 44, 87,153,103, 47,144,244, 1,116, 70, 37,132,192,100, 50, 57,154,222,156,231, 85,178, -119,122,119,115, 62,168,157,132,144,152,183,223,126,123,162, 66,161,232,172,211,233,234, 2,128, 90,173,190,106, 52, 26,127,215, -235,245,159, 83, 74,115,239, 39,173,206,211, 50,148,113, 28, 21,102, 70, 70, 70, 70,207, 17, 35, 70,236,228, 56, 46,178,162,151, -243, 58, 61,249, 39,164,165,165, 61,230, 74,115,248,240,225,101,106,150,165,235,142,102, 89,231, 92, 20,197,114,205,149, 59, 21, -144,171,137, 68, 37, 18, 9,212,106, 53, 54,109,218, 4,127,127,255,255,212, 5,118,248, 68,202, 71, 21,109,239,228, 47,223, 7, -160,218, 19,159,174,189,179, 55,211, 84,163,147,191,236,246,198,215, 6, 87,175,232, 59, 57, 57, 57, 61, 38, 77,154,244,171, 32, - 8,145, 21,157,111, 39, 35, 30,159,145,145, 81,233,105, 15, 40,165,184,114,229,138,248,194, 11, 47,100,102,100,100, 60, 93,149, -227, 31, 63,241,227,207, 22,124,242,170,223,192,254,237, 91,128, 16,152, 76,229,116,234, 37,160,148, 82, 42,240, 92,226, 43,147, - 62,125,241,239, 60,103,148,210, 51,132,144,119,107,213,170, 53, 26, 64,121,119,194, 31, 92,233,236, 5,204, 50,163,241,147,216, -216,216,169,111,188,241,134,119,223,190,125, 17, 30, 30, 94,238,124,129, 21,113,240, 88,210,232, 54,177,193, 97, 79,245,107,223, -147, 35,132, 26, 77, 70, 23,245,106,113,126, 10,252,149,125, 71, 19, 27,187,138,206,115, 28, 87,233, 46, 10,238,208,117,224, 72, -116, 29, 56,210, 81,158,118,173,235,132,147, 41, 59,209,156, 75,130,113,105,123, 16, 79,123, 81,231, 93,222, 39, 56,142, 67,191, - 21,155, 75,164,179,221,135, 37,163,179,117,199,189, 93,169,123,143,243,224,171, 7,213, 7,139,231,121,100,102,102,226,234,213, -171, 72, 75, 75,131, 78,167,195,165, 75,151, 96, 54,155,145,147,147, 3,251, 72,195,170,164,243, 65,157,163,191, 83,243, 81,106, - 38,172,148,193,178,217,108, 73,174,222,122,110,181, 90, 43, 53,202, 72, 16, 4, 67,251,246,237, 73, 89,163, 13,236,127, 43,149, - 74,189,155, 21, 99, 46,128, 25, 0,102, 20,191,111, 10,217,217,217,247,237, 2,109, 54, 91, 74,203,150, 45,249,138, 12,145,205, -102, 75,115, 97,134,180, 0,218, 60,200,147,247, 87,104,150,113,126,180, 29, 59,118,188,103, 30, 19,231,243,163, 80, 40, 42,236, -117,235,106, 34, 81,157, 78,151, 58, 98,196, 8,155,115,179,160,243, 68,164,255,105, 8,189,221,123,200,243, 53,246,102,154,106, - 0,128,221,100,129,210,219,229,125, 37, 37, 37, 69, 15,160,227, 95,157,180, 91,183,110,153, 90,181,106,181,186,160,160,224,101, - 74,105,149,123,233, 79,152, 60,239,141,127,219,105,161,148,158, 1, 48,230,126,117, 76,192,229, 6, 6,195,203, 51,223,126,251, -201,119,222,126,187,142, 8,248, 1, 69,115, 84,241,192,218,202,104, 29, 57,145,250,192,231, 6,179,217,108, 73,109,219,182,173, - 84,164,198, 85, 29,111,181, 90, 43,188, 79,172, 65, 56,112,162,114,154,127, 69, 58,157, 53,155, 52,105,130,166, 77,155, 58, 62, -237,148, 94,239,142,102,243,230,205,209,160, 65,131,114,103,104, 47,221,231,234,239, 62,118,187,166,221,246, 55,109,186,227,129, -105,222,111, 58, 31, 41,131,101,127,199,224,131,228,226,197,139,127,201,187, 81, 40,125,112, 99,189, 47, 94,188,216, 2,143, 40, - 87,174, 92,241,187, 95, 13, 87, 19,137,158, 59,119,174,243,163,154,191,123, 51, 76,207,221,179,174,216,108,253,221,104,181,218, -234,148,210, 42,245,204, 31, 56,112,160,237, 81, 61,167,160,180,196,196, 83, 23,139, 38, 40,253,238,159,152,212, 11, 23, 46, 60, -240, 58,253,175,184, 79,252, 21,233,100,199,254,207,215,252,183,195,102,136,100, 48, 24,229, 61,164,216, 88, 46, 48, 24, 12, 70, -213, 32, 0,186,149, 83,185,186, 61,114,135, 16,210,173, 10,149,247, 46,166,201, 52,153, 38,211,100,154, 76,147,105, 62, 90,154, -174,180, 31,244,200,225,191,243, 41,245, 47, 91, 0,116, 99,154, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,212, 22,214, 68, -200, 96, 48, 24, 12, 6,131,241,128, 97, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, - 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 84, 29,242, 0,231,227,100, 48, 24, 12, 6,131,193, 96,128, 69,176, - 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, - 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, -248, 39, 24, 44, 66, 72, 55,166,201, 52,153, 38,211,100,154, 76,147,105, 50, 77,102,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, - 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, - 96, 48, 24,140,191, 9, 2,160,204,145, 0,148,210, 93,110,139, 84, 97, 52,129, 43,125,166,201, 52,153, 38,211,100,154, 76,147, -105,254,247, 52, 93,105, 87,198,127,252,163,161,148,254,101, 11,128,110, 76,147,105, 50, 77,166,201, 52,153, 38,211,100,154,143, -218,194,154, 8, 25,174,158, 48, 4, 66,136, 80,213,237, 15, 75,147,193, 96, 48, 24,140,127, 18,236, 38,198,168,200, 8,181, 1, -208,167,248,239,159, 41,165, 71, 42,179,253, 97,105, 62, 44,154, 55,111,174, 84, 40, 20, 61,246,236,217, 35,187,116,233, 18,254, -248,227, 15,186,122,245,106,179,193, 96,216,113,242,228, 73, 61, 43, 49,255,126,154, 53,107,214, 19,192,244,226,127, 63, 56,117, -234,212,246,251,188,134, 72,173, 90,181, 38,200,100,178,222, 82,169, 52,196,106,181, 18,163,209,152,162,215,235,119, 38, 39, 39, -127, 74, 41, 21,171,160,217,194,223,223,127, 76, 76, 76, 76,157, 91,183,110, 37,222,185,115,103, 21,128,237, 0,122, 86,175, 94, -125, 68, 84, 84, 84,248,133, 11, 23,174,101,102,102, 46,166,148,254,241,119,165,147,193, 96, 6,203,189,139,143,243,241,241,233, -174, 84, 42,255, 87, 88, 88,216,212,211,211,243,162,213,106, 93,144,154,154,250, 51,187,240,254,179,230, 74, 0,208,135, 82, 42, - 1, 0,158,231,251,183,105,211,166, 6, 33, 68, 36,132, 80, 74, 41,225, 56,174,169,205,102,227,138,247,239, 67, 8,249,131, 82, -106,173,140,102,171, 86,173,194, 5, 65,160,148, 82, 66, 41,229, 56,142,107, 92, 25,205, 7, 69, 76, 76,204, 92, 74,105, 72, 69, -251,168,213,234,216, 61,123,246,212,219,188,121,179,109,213,170, 85,185, 67,134, 12,209,140, 28, 57, 82,248,246,219,111,191, 2, -240,191,210,251, 55,104,208,224, 51,142,227,252,221,249,125, 81, 20, 51, 47, 94,188, 56,137,149,188,191,157,233, 47,124,184,175, - 3,165,192,215,211, 59,114,197,198,165,202, 52,109,218,244,187, 1, 3, 6, 12,169, 91,183,174, 32,138, 34, 44, 22, 11, 76, 38, - 83,189, 83,167, 78,117,218,177, 99, 71, 44,128,167, 43,121, 93,246,153, 62,125,250,178,119,223,125,183,154, 68, 34, 33, 22,139, -165,245,143, 63,254,216,107,204,152, 49,103, 22, 47, 94,220,100,208,160, 65, 30,246,245,239,188,243,206, 99,132,144,137,148,210, - 31, 30,118, 58, 25, 12,134, 11,131,229,225,225, 81,187, 90,181,106,175,249,249,249, 61, 22, 27, 27,155,247,210, 75, 47,221,188, -113,227,198,249,200,200, 72,221,183,223,126, 59,199, 98,177, 44,172, 91,183,238,142,252,252,252, 79,239,222,189,123,169,146, 21, - 69,109, 0, 47, 1,120, 12, 64, 24,128, 20, 0,191, 2, 88, 70, 41,189, 82,149,131, 9, 13, 13,109,164, 86,171,167, 18, 66, 90, -107,181,218, 48,181, 90,157, 66, 41, 61, 86, 80, 80,240,113,106,106,234,169,170,104,134,133,133,213, 4, 48, 94, 16,132, 56,155, -205, 22,201,243,252,109,155,205,118,192,102,179,125,153,146,146,114,173, 42,154,237,194, 61,250,138, 26,207, 79, 45,188, 50,188, -208, 96,149,106,228,130, 69, 34, 26, 18, 69,109,238,244, 99,119, 10,127,250, 39, 22, 20,153, 76,198,173, 90,181,170,137, 76, 38, - 3, 0,152, 76, 38,196,196,196,144,251,209,148, 72, 36,220,167,159,126,218, 76, 16, 4,152,205,102,177,160,160,128, 62,249,228, -147,127, 75,179, 53, 33, 36,236,228,201,147, 94, 82,169,180,204,237, 54,155, 13,253,250,245,139,148, 74,165, 88,180,104,145, 37, - 43, 43,171,233,242,229,203, 79, 45, 92,184,208,127,197,138, 21, 3,203, 50, 88, 28,199,249,151,167,105,179,217, 96, 54,155, 97, -181, 90, 97, 50,153,208,185,115,103, 86, 27,253, 51,168, 1, 0,219,206, 26, 0,192,247,126,197,148, 74,101,244, 19, 79, 60, 33, -100,100,100, 64, 34,145,192,108, 54,227,238,221,187,168, 85,171, 22,191,121,243,230,186,149,213,171, 87,175,222,152,247,223,127, - 63, 96,219,182,109,230,213,171, 87, 27,187,117,235, 38, 29, 53,106,148,103,135, 14, 29,226,194,194,194,184,111,190,249,198,184, -107,215, 46,243,240,225,195,229,115,231,206, 13,248,245,215, 95,135, 0,248,225, 97,167,147,193, 96, 84, 96,176, 60, 60, 60,246, -105, 52,154, 90, 47,190,248,226,149,151, 95,126,121,135, 70,163,177, 1,192,247,223,127, 47,244,239,223, 63,227,201, 39,159, 76, -215,233,116,252,194,133, 11,171,127,241,197, 23, 59, 61, 60, 60,146, 11, 10, 10, 90,186,113, 35, 35, 0,254,199,113,220,248, 30, - 61,122,236,179, 88, 44, 25, 91,182,108, 89,247,196, 19, 79,196, 81, 74,213,123,246,236,249,133, 16,178, 4,192, 39,238, 70,199, - 8, 33,124, 84, 84,212,204,176,176,176,201,139, 22, 45,146, 71, 69, 69, 65,169, 84,162,160,160,160,250,181,107,215,194,255,247, -191,255,245,171, 89,179,230, 2, 47, 47,175,183, 78,158, 60,105,113, 83,147,132,132,132,188,234,233,233,249,222,220,185,115, 21, -245,235,215, 39,106,181, 26,241,241,241, 13,143, 30, 61, 26,179,124,249,242, 81, 97, 97, 97,179,146,147,147,221, 78,103, 39, 66, - 4, 67,205,106, 59,124,234,181,236,180,120,217,215,196, 95,173,130, 64, 8, 44,102,179, 36, 77,167,143, 26, 55,118,244,186, 54, -117,130, 14, 21, 72,210,186, 94,188, 72,205,127,147,209,144, 3, 0,165,212, 72, 8,249,153,231,249,254, 50,153,140,235,223,191, - 63,118,237,218, 69, 12, 6,131, 0, 0, 10,133,194,218,191,127,127, 40,149, 74,152, 76, 38, 17,192,207,229, 69,154,202,210,148, - 72, 36, 92,231,206,157,117,199,143, 31,207,182,107,170, 84, 42, 75,231,206,157,253,100, 50,153,210,106,181,210,138, 52,255, 34, - 19,137, 27, 55,110,148, 88, 87, 80, 80,128,140,140, 12,100,101,101,193,100, 50, 33, 55, 55, 23,162, 40, 18,163,209,152, 33,138, - 34, 56,174, 40,216, 86,158,166, 84, 42,197,213,171, 87, 75,172,179, 90,173,208,106,181, 48, 26,141, 48,155,205,208,235,245, 74, -133, 66, 81, 59, 46, 46, 46, 9,192,230,194,194,194, 79,207,156, 57,115,155, 85, 79,127, 11,119,126, 62,109,168, 14,192, 4, 32, -254, 1, 92, 79, 34, 0, 28, 56,112, 0,105,105,105,200,204,204, 68, 70, 70, 6,194,194,194, 80,149,232,255,149, 43, 87,230, 55, -109,218,148,156, 57,115,102, 43,128,101,107,215,174,125, 34, 59, 59,123,209,148, 41, 83,124, 63,254,248,227,236,169, 83,167,142, - 5,176,113,237,218,181, 35, 27, 53,106,212,247,220,185,115,243,254,142,116, 50, 24,140, 10,230,193,162,148,134,212,174, 93, 59, -251,243,207, 63,175, 55,125,250,116,191,194,194, 66,190, 56, 74,100, 32,132, 80,157, 78,199, 79,155, 54,173,218, 7, 31,124, 80, - 79, 46,151,231, 88,173,214,106,101,104,148, 53,212,114,188,167,167,103,191,248,248,248,181,245,234,213,243,125,255,253,247, 79, - 43,149, 74, 58,127,254,252,147, 53,107,214, 12,190,125,251,246, 74, 79, 79,207, 46, 0, 38,151,147,174,123, 52, 35, 35, 35,223, - 27, 56,112,224,228, 67,135, 14,201, 27, 55,110, 12,141, 70, 3,158,231,225,237,237,141, 86,173, 90,145,253,251,247,203,123,247, -238, 61, 33, 47, 47,239, 99,119, 53, 67, 66, 66,222,232,213,171,215,156,147, 39, 79, 42,187,118,237, 74,100, 50, 25,114,114,114, - 32,151,203,209,186,117,107,178,120,225, 87,202,134, 13,234,191, 19, 22, 22,246,174,187,154,230,218,254, 59,135,188, 50,173,243, -207,191,110, 39,129,129,129,184,249,201,187, 56,208, 33, 6,215,103, 79, 71,112,112, 48,182,110,251,141,244,125,246,149,246,158, -150,192, 61,238,106,222, 47,206,154,132,144,151, 1,100, 3,200, 38,132,188, 76, 41, 61, 18, 19, 19,115,242,210,165, 75,136,139, -139,195,186,117,235, 26, 79,153, 50,229,229, 41, 83,166,188,188,110,221,186,198,113,113,113,184,116,233, 18, 98, 98, 98, 78, 58, -247,149,114, 71,115,223,190,125,232,210,165, 75,206,186,117,235,162,102,204,152, 49,119,198,140, 25,115,215,174, 93, 91,179, 75, -151, 46, 57,243,230,205, 51, 86,164,249, 87, 28,187,115,100,201,121, 17,197, 63,239, 45, 1, 1, 1,233, 63,255,252, 51,250,246, -237,203, 5, 6, 6,166,246,239,223, 95,126,252,248,113, 10,224,231,202,164,211, 96, 48, 64,175,215, 67,171,213,226,206,157, 59, -202,133, 11, 23,182,159, 60,121,114,173,117,235,214,133, 78,152, 48, 97,172,167,167,231,169, 38, 77,154,212,120,216,199,206, 52, - 1,142,227,238, 2, 48, 3,208,114, 28,119,251,126, 52,159,122,234,169,134, 17, 17, 17,129, 63, 94,240, 65,142,180, 30, 68,169, - 55, 68,169, 55,108,126, 45,112, 67,246, 24, 66, 67, 67, 3,107,212,168,209,166, 50,154,148,210,157,167, 79,159,126,140, 82,186, -152, 82,106,163,148,174,159, 58,117,234, 11,132,144,159,166, 78,157, 58,154, 82,186,190,120,253,242,179,103,207,246,165,148,254, -254,119,164,147,149, 37,166,201,168,192, 96, 17, 66, 44, 31,125,244,209,209,175,191,254,122, 87,106,106,106,112, 84, 84,212,227, - 79, 60,241, 68,141,188,188, 60,242,196, 19, 79, 68, 6, 7, 7,247,217,183,111, 95,208,192,129, 3,247, 12, 28, 56,240, 8, 33, -196,101,164,129, 16, 82,147,231,249,137,103,206,156, 57, 88,189,122,117,115, 74, 74,138, 71,211,166, 77, 11, 0,160, 78,157, 58, -186,172,172, 44,165,151,151, 23,126,251,237,183,227,132,144,151, 8, 33,245, 92,105, 6, 7, 7, 55,243,243,243,251,223,123,239, -189, 39,231,121,190,204,125,228,114, 57,222,123,239, 61,185,167,167,231,139,161,161,161,173, 93,105, 6, 5, 5,213,247,240,240, -120,243,139, 47,190, 80, 24,141, 70,152, 76, 38, 4, 6, 6, 66,163,209, 32, 53, 37, 5, 41, 9,241, 72,139,191,133, 9, 47, 60, -175, 84, 43,149, 19, 67, 66, 66,154,184,210,140,139,240,232,175, 14,107,208,105,220,248,255,225,194,132,145,216, 21, 42, 67,208, -248,105,104,188,247, 60,194,102,125,138,223,163, 60,113,242,233,238,120,245,213, 73,144, 6, 68,181,109, 27,174, 25,252, 55, 68, -174, 62,166,148, 42, 41,165, 74, 66,200,252,182,109,219,174, 86, 42,149, 47,191,255,254,251, 61,119,236,216,209,107,255,254,253, -157,172, 86,171,196,106,181, 74, 14, 28, 56, 16,103, 48, 24, 4,185, 92, 14, 65, 16,168,187,154,109,218,180,249, 78,169, 84,142, - 93,180,104, 81,207,223,127,255,125,196,137, 19, 39, 94,177,217,108, 50,155,205, 38, 59,113,226,196,104,189, 94, 47,161,148,218, -202,211,124,216, 72, 36, 18, 72,165, 82, 40,149, 74, 52,109,218,244,230,154, 53,107, 44,193,193,193,146,101,203,150,249, 4, 6, - 6,170, 87,172, 88,145,155,155,155,251,161,187,122,102,179, 25, 70,163, 17,122,189, 30, 6,131, 1,135, 15, 31,142, 28, 53,106, -148, 96, 50,153,108, 35, 70,140,200,182, 88, 44,198,113,227,198,121,106, 52,154,215, 88,245,244,240, 41,142,152, 22, 2,208, 82, - 74,141,246,245, 17, 17, 17,242,208,208,208, 70, 17, 17, 17,114,119,181, 10, 11, 11,151,124,246,217,103, 97,156,220, 27, 7, 77, -189,241,131, 56, 11, 59,188,190, 68,122,141,201, 8, 8,171,133, 94,189,122, 5, 16, 66,190,124, 0,105,222, 76, 41, 29, 72, 41, -221, 80,149,239,255,213,233,108,209,162, 69, 92,108,108,236,137,230,205,155,167,198,198,198,158,104,209,162, 69,220,253, 30,243, -211, 49,164,219,136, 38,124,210,192, 6,132,142,104,194, 39, 61, 29, 83,249,185,154, 24,140,191, 26,151,157,220,171, 85,171,102, -122,227,141, 55,206, 24, 12,134,243,223,125,247, 93,173,225,195,135, 55,173, 81,163,198,213, 39,159,124,242, 23,141, 70, 99,181, -247,201,113,147,231,123,247,238,189,205,223,223, 31,121,121,121,130,197, 98,225,181, 90, 45, 15, 0,162, 40,194, 96, 48,240,183, -110,221, 18,140, 70, 35,109,221,186,245,150, 35, 71,142,188, 4, 96, 98, 69,130,106,181,250,229,165, 75,151, 42,202, 51, 87, 54, -155, 13, 5, 5, 5,176, 90,173,152, 53,107,150, 98,242,228,201,255, 3,112,212,197, 77,117,252,252,249,243,229, 86,171, 21, 28, -199,129, 82,138, 83,167, 78, 33, 43, 61, 29,134,130,124, 24,243,243, 96,206,207, 3,175, 45,192,136,199,122, 42, 22,111,216, 52, - 9,192,136,138, 52, 77,114,205, 7,223, 45, 93, 14,155,205,134,212,205, 63,150,185, 79,246,161,189,176, 89, 45,120,255,195,143, -201,171,207, 15,122, 31,192,218,191,171, 96,200,229,114, 97,213,170, 85, 67,101, 50, 25, 40,165,196,100, 50, 97,199,142, 29,247, -173,185,114,229,202, 17,118, 77,179,217, 76, 27, 54,108,120, 79,243,154,209,104,164,255,148, 11, 68, 38,147, 65,161, 80,192,108, - 54,163,122,245,234,250,126,253,250, 29,158, 63,127,126,117,158,231,213,130, 32,252,150,151,151, 55,247,194,133, 11,183,220,213, - 43,238, 60, 12,147,201, 4,189, 94,143, 59,119,238, 4,133,134,134,146, 55,223,124,211,166,211,233,162,150, 47, 95,126,227,199, - 31,127, 84,125,241,197, 23, 79, 2, 24,207,170,168,135, 71,173, 90,181,100,158,158,158, 94,213,253, 4,173,132, 71, 97, 58,165, - 30, 17, 17, 17, 53, 44, 22,203,147,132,144,214,117,234,212,241,185,126,253,122, 78,104,104,232, 81,142,227,126, 72, 76, 76, 76, -117, 97,124,136,213,106,197,232,150,185,120,185, 13, 15,139, 37, 15,121,121,121,184,125,251, 54, 46, 94,188,136, 99,199, 46, 84, - 41,157,145,145,145,207, 43, 20,138, 30, 50,153, 44,194,102,179,113, 58,157,238,182,209,104,220,149,146,146,178,132, 22, 79, 80, - 84, 73,131,246,151,164,211, 73,255,211, 39,158,120, 34,196,203,203, 11,167, 79,159, 14, 57,123,246,236,167, 0, 98,239,235,186, - 20,184,111,102,127,242,101,104,176,191, 55, 46, 28,218, 26, 58,111,217,143,223,160,168, 47, 47,131,241,239, 49, 88,118, 20, 10, -133,109,204,152, 49, 87,183,108,217, 18, 17, 27, 27,123,185,188,206,192, 46,104, 23, 29, 29,125,251,240,225,195,240,245,245, 53, - 91, 44, 22,222, 96, 48,112, 82,169,148,102,103,103, 19,189, 94,207,157, 61,123, 86,145,148,148, 36,245,241,241,145, 0,104,230, - 70,132,161, 77,100,100,100,217,166,198,100, 66, 97, 97, 33, 10, 10, 10, 96, 52, 26, 17, 24, 24, 72, 56,142,107,229, 50,172,199, -113,237,235,214,173, 75,114,114,114, 16, 18, 18,130, 67,135, 14,161, 48, 55, 23,134,130,124,152,242,243, 96,206,203,133, 37, 47, - 23,185,233, 41,136, 8, 14, 35,197, 83, 11, 84,136,149, 87,214, 8,208,168,113,125,246, 52,180, 56,117, 27, 68, 34,197,241,134, -193,160,150,162,174, 86, 45,207,165,128, 72,101,184, 60,225, 57, 4, 14,127, 17, 22, 78, 30,250,144,159,220,141,132,144, 41, 28, -199,205,151,203,229,194,216,177, 99,145,154,154, 90,194,252,140, 29, 59,214,209,231,170, 67,135, 14, 7, 20, 10,133, 53, 35, 35, - 3, 70,163, 81,226,142,102, 68, 68,196,237,183,222,122,235,184,201,100, 10, 11, 9, 9,241, 54, 26,141,250,186,117,235,134, 40, -149,202, 64,147,201,100,139,141,141, 93,162, 84, 42, 45,133,133,133,212,106,181,146,127,194, 5, 66, 8, 1, 33, 4, 86,171, 21, - 86,171, 21,222,222,222,218,172,172,172, 99, 55,111,222, 28, 90, 21, 61,139,197, 2,139,197,226,136, 98,137,162,136,115,231,206, - 65,161, 80, 72, 68, 81,188, 96,179,217, 84, 18,137, 4, 60,207,179, 57,234, 30, 34,205,155, 55,239,212, 56,208,243,179,177, 33, - 70,239,154,125,213, 90,149,140,215,126,156,165,140,248,229, 59,237,218, 62,189, 7,123, 76,158, 60,185,134,175,175,175,226,214, -173, 91,134,121,243,230, 69,110,220,184,145, 0,248,164, 34,205,148,148,148,159, 62,248,224, 3,223, 78,157, 58, 69, 73, 36, 18, -146,155,155,139,140,140, 12,164,167,167,227,206,157, 59, 52, 33, 33,225,166,213,106, 93, 87,153,116, 54,110,220,120,249,240,225, -195,159,105,208,160,129,132, 82, 10,179,217, 12,157, 78,215,244,216,177, 99,253, 14, 30, 60, 24, 7,160,210,229, 50, 53, 53,117, -221,135, 31,126,168,238,216,177, 99, 61,137, 68,194, 61,136,116,150,170, 7, 66, 52, 26, 13,118,237,218, 5,111,111,111,184, 26, -173,235, 14, 70,139, 24, 26, 20,224, 7,195,161,207, 80,219,183, 6,140, 22, 49,148,149, 98,198,191,214, 96,101,100,100,200,180, - 90,173, 32,138, 34,159,151,151,167, 82,169, 84, 86,153, 76,102,170,228,239, 53,232,215,175,223,241, 86,173, 90, 21, 22, 71, 52, - 44, 1, 1, 1,230,188,188, 60,136,162, 8, 81, 20,173,158,158,158,133, 22,139, 5, 81, 81, 81, 28, 0,151, 77,132,122,189,190, -186, 82,169,188,103,189, 78,167,115,152,171,194,194, 66,232,116, 58,120,121,121, 65,171,213,186,188,184,109, 54, 91,132, 74,165, - 66, 74, 74, 10, 0,160, 32, 39, 27,198,252,124,152, 10,254, 52, 87,182,220, 28,136,122, 45,188,195,194, 97,181, 90,195, 93,105, -106,141, 54, 25, 15,138,244,173, 63, 33,240,229, 41,229,238,151,115,112, 47, 60,106, 71, 67,175, 55, 63,244, 57,202, 40,165, 11, -155, 54,109,218,108,227,198,141,163,146,147,147,239,217, 62, 96,192, 0,140, 31, 63, 30,227,198,141,187,252,248,227,143,159,221, -186,117, 43, 94,121,229, 21,136,162,216,132, 16,146, 71, 41,253,181, 34,205,233,211,167,159, 72, 76, 76,220,123,237,218,181,177, - 1, 1, 1,242, 70,141, 26, 93,111,212,168, 17,191,113,227,198,192, 23, 95,124,241,100,175, 94,189, 18,118,239,222,237,187,107, -215, 46,133, 40,138,205, 9, 33,201,127,247, 60, 88,246, 38, 98,147,201, 4,131,193, 0,179,217, 12,155,205, 70, 42,145,167, 37, -254, 23, 69,209, 97,214,140, 70, 35, 44, 22, 11,217,185,115, 7,182,110,221,202, 93,186,116, 49,108,250,244,215,145,151,151, 7, -155,205,198,106,167,135, 64,108,108,236, 99, 2, 21,151, 14, 15,178, 42,134, 6, 90,181, 82, 66, 11,175, 45,125,171, 48,190,134, - 70,235,233,207,155, 60,253, 36, 33,211,166, 79, 11,190,121,227,166,241,163,143, 62,186,212,167, 79,159,128, 23, 95,124,177,254, -182,109,219,226,170, 87,175,254,245,157, 59,119,114,203, 49,230,210, 81,163, 70, 29,243,246,246,174,185,122,245,234,244,228,228, -100, 31,139,197,162,178, 88, 44,102,131,193,112,195,108, 54, 31, 52,153, 76,187, 82, 83, 83, 79, 86, 38,189, 26,141,166,241,160, - 65,131, 36,185,185,185, 40, 30,125,139,244,244,116, 52,107,214,140,223,189,123,119,131,170,228,193,197,139, 23, 63, 11, 9, 9, -217,187,101,203,150, 30,106,181,186,185, 76, 38, 11, 18, 69,209,166,215,235,211, 12, 6,195,153,170,164,179, 84, 94,164,156, 58, -117, 42,196,211,211, 19,137,137,137, 32,132,164,220,239,121, 83, 72,185,196, 75, 7,183,132,215,246,141,196,177,163, 71,161,144, -114,137,172, 52, 51,254, 85, 6,171,160,160, 64, 56,117,234,148, 79, 98, 98,162,198,223,223,223, 80,191,126,253, 60, 66,136,200, -113, 28, 77, 77, 77,245,141,143,143, 87,248,249,249,105,107,214,172,153,237,230,239, 93,155, 48, 97, 66,220,140, 25, 51, 78,118, -239,222, 61, 19, 0,114,114,114,144,149,149,133,140,140, 12,152,205,102,164,164,164,112, 39, 78,156,240,253,237,183,223,154, 2, -112,217,244,162, 84, 42,239, 20, 20, 20,212,245,246,246,118,220,208,236,166,202,217, 96,217,163, 89,106,181,218,229,197,205,113, - 92,114,114,114,114, 45,131, 94,143, 59,215,175,195, 88, 80,212, 36,232, 48, 87,121,217, 64, 97, 1,212, 10, 5, 10,178,179,192, -243,252, 93, 87,154,106, 57,111,178, 88,109,178,106,189,250, 1,164,252,251,179, 87,203,118, 16,235, 53,130, 82,185,222,242,119, - 20, 8,142,227,108, 21, 53,251,202,100, 50, 4, 6, 6,138,173, 91,183,198, 43,175,188, 98, 55, 2,132, 16,210,137, 16,114,144, - 82, 90, 88,158,166, 40,138,220,165, 75,151,158,184,113,227, 6, 47,145, 72,184, 86,173, 90,197,180,111,223,222, 36,147,201, 32, -149, 74,133,194,194, 66,143, 93,187,118, 41, 44, 22, 11, 41,214,124,104,243, 96, 1, 69,163,251,202, 48,240,208,106,181,208,235, -245, 40, 44, 44, 68,110,110,174,160, 84, 42,235,118,232,208,225,168,209,104, 92,103,179,217,190, 57,121,242,100,126,121,154,102, -179,185,132,217, 18, 69, 17,148, 82,216,108, 54, 88, 44, 22, 72, 36, 18,113,203,150,173,248, 98,225,124,172, 95,187,129,118,235, -214,141,252,246,219,111, 16, 69, 49,137, 85, 79,127, 61,162, 40,126,250,251,180,167, 20,176,218,180,198,125,107, 10,183,103, 11, -218,175, 47,252,126, 66, 47,112,249,213,235,163, 81, 68,120, 77,222,203,211,139, 91,177,114,105,214,111,219,246,220, 72, 74, 74, -202,159, 61,123,118,155,168,168, 40,175,171, 87,175,134, 2,200, 45,199, 8, 69,140, 28, 57,114,100, 78, 78,142,116,217,178,101, - 43,146,147,147,247, 81, 74,111,150, 50, 30,205, 8, 33, 31, 3,144, 0, 8, 4, 96, 5,176,147, 82,186,178, 2,179, 34, 18, 66, -240,251,239,191,223, 51,218, 79,116, 30,145, 81,249, 40, 86, 78,171, 86,173, 26, 95,187,118,109,115, 78, 78,206,234,210,219, 85, - 42, 85,191,152,152,152, 33,199,143, 31,127,155, 82,122,163,146, 15,110, 19, 47, 93,186,244,145, 40,138, 53, 56,142,187, 77, 41, -157,250, 0, 34, 88, 47,204, 91,182,118,153,193,108,171,174,144,242,119,140, 22,241, 69, 86,154, 25,255, 26,131,101,181, 90, 53, -111,189,245, 86,155, 38, 77,154,164,118,232,208,225,110,100,100,164,206,190,205,195,195, 67,239,231,231,167, 55, 24, 12,202,219, -183,111, 7,111,218,180,169,142,205,102, 83,185,241,123,123,188,189,189,125, 79,156, 56,225,247,195, 15, 63,212, 62,117,234, 84, -141, 97,195,134,117, 52,153, 76, 48, 26,141,184,117,235, 86,141,165, 75,151,138, 82,169, 52,151, 16,242, 7, 0,151,143,241, 22, -139,229,200,181,107,215,234,180,106,213,138, 88, 44, 22,135,161,114, 54, 89,133,133,133,144, 74,165, 72, 73, 73,161,162, 40, 30, -115, 35,157, 71, 79, 28, 63, 94,171, 97,253,104, 24,243,114,138,205, 85, 30,172,121, 57, 16,243,178,193,105, 11,225,231, 43, 64, -165,208,224,106, 74, 42,138,211, 90, 33, 18,171, 62, 33, 57, 47,191,110,173,153,159,224,247, 40, 79, 80,139,217,209, 44, 8,192, -209, 92,216,246,114, 6, 14, 28, 62, 2,193,102, 76,254,167, 22,154,179,103,207,166, 15, 27, 54,236,164, 40,138,205, 80,193, 20, - 5, 21, 60,133, 23, 20, 22, 22, 34, 51, 51,211,150,149,149,101, 0,128,244,244,244,156, 45, 91,182, 92, 18, 69,177,101, 85, 52, - 31, 4, 22,139,229,158,232,147,205,102,131,213,106,133,217,108, 70, 70, 70,134,236,224,193,131, 29,142, 30, 61, 42,189,120,241, - 34,142, 30, 61,218,100,211,166, 77,175, 71, 71, 71, 55,186,124,249,242, 93, 87,166,141,148,109,172,121, 0,216,178,241,103, 12, - 25, 50,132,100,102,102, 98,211,166, 77, 15,164, 25,133,225, 22, 90, 88,109, 74,211,190, 53,133,175, 93,151, 23, 92,208,241,179, - 79,158, 60,185,157, 82, 74,123,247,238,125,182,110,189, 40,127, 0,144,203, 52, 65, 13, 27, 54,236,232,227,227, 35, 3,128,144, -144,144,230, 22,139,101, 33,128,246,101,137, 14, 24, 48,160,109, 64, 64, 64,211, 95,127,253,245, 76,114,114,242,254,210,230, 10, - 0,234,214,173, 59,235,252,249,243,143, 73, 36, 18,226, 84, 70, 40,128, 50, 13,214, 83, 79, 61, 85, 55, 44, 44,204,111,219, 53, - 47,228, 75,107,129,242,121,128,160,128,205,187, 49,110, 75,235, 35, 40,232,138, 95,173, 90,181,154,220,184,113,227, 76, 37, 35, - 76,213, 7, 13, 26,244,203,242,229,203,163,123,245,234, 37, 3,112,143,193,138,142,142,126,114,247,238,221, 3,199,142, 29,219, -152, 16,210,151, 82,122,221, 93,253,147, 39, 79, 30, 2,208,230, 65,158,180,117, 23,232, 46, 20,207, 89,198, 96,252,235, 12,150, -217,108,222,121,253,250,245, 22, 79, 61,245, 84,166,179,185,162,148, 58, 42, 3, 47, 47, 47,189,191,191,127,246,153, 51,103,170, -137,162,184,207,141,223, 91,182,123,247,238,223, 23, 44, 88,176,198,215,215,215, 50, 98,196, 8,110,218,180,105, 7,178,178,178, -104, 86, 86, 22,190,252,242,203, 14,113,113,113, 7,110,223,190,109, 59,121,242,228, 72, 0,189, 92,214,142, 90,237,194, 87, 94, -121,101,200,129, 3, 7, 20,246,121,138, 74, 71,175, 44, 22, 11, 4, 65,192,194,133, 11,141, 90,173,118,190, 27,145,140, 37, 95, -125,245,213,192,165, 95, 44, 80,240,102, 51, 44,185,217,176,230,229,194,150,155, 13, 78,167,133,135,130,160,118,179,106,200, 73, -150, 99,213,246, 67,122,171,213,250,149, 75,131,101, 40,156, 50,118,244, 75, 63,239,220,243, 59,124,219,119, 65,214,239,191,221, - 27, 29,170, 22, 8,147,217,140,247,222,157, 73,137, 62,119,218,223,244, 68,207,155, 76,229,183,252,154, 76, 38,136,162,152,116, -241,226,197,181,132,144, 2, 66, 72,167,226, 77,123,203,138, 94, 57,107,114, 28, 39,214,175, 95,127, 99, 96, 96,224, 19, 0,180, -245,235,215,223, 40,151,203,187,152, 76,166, 86,162, 40, 38,157, 62,125,122, 3, 33,228, 46, 33,164, 79,241, 87, 31,234, 60, 88, - 22,139, 5, 51,102,204,192, 7, 31,124,128,233,211,167, 59,142,215,222, 76,104, 54,155, 35,119,236,216, 33, 61,116,232, 16,253, -238,187,239,178,158,126,250,105,239, 97,195,134,121,175, 90,181,106, 34,128,169,229,105, 78,157, 58, 21,139, 23, 47,198,152, 49, - 99,238,117, 87, 60, 47, 38, 39, 39,193,100, 54,209,149, 43, 87,166, 8,130,224,243,249,231,159, 43, 39, 79,158, 76, 88,245,244, -215, 99,179,217,222,108,247,233,166, 87, 9, 81,154,173, 86,235,252,179,103, 79,239,117,122, 16, 80,126,250,201,167, 2, 0,124, -242,241,167, 18, 74,169,151,125, 98,216,217,179,103, 43, 70,143, 30, 29, 80,158,238,250,245,235,115,103,207,158,237,247,194, 11, - 47,244,218,187,119,175,138, 16,178, 13,192, 31, 0, 50,139, 31, 28,253, 1, 28,170, 86,173, 90,240,218,181,107,107,245,232,209, - 67,237, 70, 93,247,245,162, 69,139, 34, 62,221,239,129,109,218, 39,144, 40, 62, 13,234, 77,225, 27, 80,128,250,154, 59,232, 28, -154, 28,178,122,245,234,101, 0,154, 87,194, 92, 53,120,234,169,167, 54, 45, 95,190, 60,242,165,151, 94, 74, 58,116,232, 80, 34, - 33,100, 86, 25,187,102, 61,247,220,115,183, 87,172, 88, 81, 75, 20,197,237,132,144, 94,148,210,107,172, 4, 49, 24, 85,139, 96, - 61, 79, 8,137,153, 62,125,250, 71, 33, 33, 33,213,103,206,156, 25, 95,191,126,125,173,227,106,203,202,210,236,219,183, 47, 42, - 63, 63,191,192,106,181,142,160,148,158, 45,227,226,237,230, 60, 87, 6,165,244, 54, 33,228,163, 38, 77,154, 12,249,241,199, 31, -247,121,120,120,228, 31, 61,122,212,211,211,211, 51,239,210,165, 75,106,158,231,117,241,241,241,216,177, 99, 71, 7, 0, 95,148, -245,148, 84, 90, 51, 53, 53,245, 84, 84, 84,212,252,201,147, 39,255,239,237,183,223, 86, 80, 74,161,211,233,144,159,159, 15,163, -209, 8, 65, 16, 64, 8,193,154, 53,107,140, 70,163,113,105,114,114,242, 81, 87,154, 41, 41, 41, 71,194,195,195,191,153, 63,111, -222, 11, 47, 14, 25, 44, 67, 94, 22,114, 83,147, 65,116,133,208, 40,229,136,233, 26, 6,109, 22,193,242,125,127,152,178,141,230, -181,201,201,201,123, 93,105, 30,188, 83,240, 75,155, 58, 1,187,103,207,158,217,245,245,111, 55, 64, 20, 69, 92,126,229, 25,228, -236,223, 9, 85,253, 70,104,123, 57, 3, 38,147, 9,211,167, 78, 6,175, 75, 59,112,244, 78,225,122, 87,154, 15, 2,103, 77, 66, -200,203,132,144,103,162,163,163, 49,118,236, 88, 12, 24, 48,160,196,190,155, 54,109,194,162, 69,139, 96, 52, 26,159, 33,132,156, -162,148, 46, 36,132, 28, 44, 62,183,133,174, 52, 35, 34, 34, 90,196,196,196, 32, 36, 36, 68, 87,108, 46,186, 95,188,120,177,121, -116,116,116,105,205, 63,138, 53,173, 15,235,216, 41,165, 57,215,175, 95,247,252,248,227,143,137,217,108,198,172, 89,179, 96, 55, -154,246,150,151, 55,222,120, 35, 68,163,209,224,147, 79, 62, 49,101,102,102,118, 89,180,104,209,158, 5, 11, 22,248,175, 89,179, -102,168,221, 96,149,210, 76,191,116,233,146,199,226,197,139, 57,171,213,138,207, 62,251,236,158,102,200,137, 19, 39,194,108,182, - 64,224, 5,147, 65,111,104,160, 80, 40,110,248,248,248, 40, 69, 81,164, 15,235,216, 31,101,205,179,103,207,238, 4,176,211,157, -239, 25, 12, 6,100,100,100, 32, 51, 51, 19,197, 93, 18, 72,121,233, 52, 24, 12,167,167, 78,157,122,114,201,146, 37,189, 14, 29, - 58, 52,112,255,254,253,189,118,237,218,101,184,125,251,182,213, 98,177,208,224,224, 96,161,125,251,246,138,222,189,123,171,229, -114, 57,247,230,155,111,102,206,153, 51,199, 31, 64, 86, 5,245, 39, 79, 41,197,107, 29, 10, 48,181, 51, 15,147,201,140,220,220, - 92, 36, 39, 39,225,226,197,139, 56,114,228, 50, 40,165, 92, 37,243,115,254,234,213,171,163,100, 50, 25, 89,179,102, 77,245, 53, -107,214, 76,112,149, 15, 43, 87,174,140, 88,179,102,205,194, 98, 45,145,149, 37,166,201,168,164,193, 42,190,160, 47, 0,232, 69, - 8,105,255,210, 75, 47,125, 24, 29, 29,109,180, 90,173,146,237,219,183,215,203,204,204,148, 89,173,214,169,148,210,253,149,249, - 65, 74,233, 98, 66, 8,250,247,239, 63,181,102,205,154,187, 79,157, 58,213,184, 95,191,126,219, 55,110,220,216,222,106,181,222, - 60,127,254,252, 51, 0,230, 3,248,194, 93,205,248,248,248,183,118,237,218,101, 61,122,244,232,107,211,166, 77,147, 7, 4, 4, - 16, 31, 31, 31,164,164,164, 32, 41, 41,137,126,251,237,183, 70,163,209,248,133,151,151,215, 91,238,106,202,100,178,215,246,159, - 56, 73,174,222,184, 49,242,249,199,122, 40,194,235,212,133,134,212, 69, 65, 86, 38,246,239, 77,195,138, 63,206, 24,210, 12,166, -239,121,158,119,123, 40,125,232,245,140,158, 59,127, 88,254,235,222,221,123,186,205,253,224, 35, 18, 50,252, 5,168, 35, 34, 33, - 70,212,198,190,189,123, 49,103,246, 44,202, 23,166,237,183,220, 72,235,254,176, 11,130,125,206, 42, 81, 20, 5, 0, 80, 42,149, - 24, 63,126, 60,156, 95,141,179,104,209, 34,232,245,122, 0, 16, 8, 33, 31, 19, 66,190, 41, 47,106, 85,142,102,245,109,219,182, - 85,119,214,140,142,142, 46, 75,211,248,176,143, 63, 45, 45,237,173,231,158,123,238,125,137, 68,226, 93,222, 62,106,181, 26, 5, - 5, 5,176,217,108, 54, 95, 95,223, 43,246,200,104,121,215,145, 86,171,125,107,204,152, 49,239, 17, 66,202,141,116, 40,149,202, -219, 7, 15, 30,172, 61,108,216, 48,110,237,218,181,183,134, 14, 29, 42, 63,120,240,160, 13,192, 6, 86, 61,253,179,112, 30,176, -160,213,106, 1,128, 86,176,239, 29, 66,200,212,147, 39, 79, 42,198,140, 25,211,124,248,240,225,158,157, 59,119,214, 56,239,163, -215,235,197,173, 91,183,106, 23, 47, 94,156,181,127,255,254, 63, 70,141, 26,245, 4,138,102,144, 47,147,148,148,148, 95,190,248, -226, 11,175, 78,157, 58,213,177,217,108,142,254, 87, 25, 25, 25, 72, 74, 74, 66, 66, 66,194,109, 81, 20,183, 84,242,176, 94, 25, - 54,108,216,182, 21, 43, 86,212,120,233,165,151,146,126,248,225,135, 45, 0,242,202,216, 79,243,228,147, 79,246, 91,177, 98, 69, -141,209,163, 71,223, 1, 48,129,205,240,206, 96,220,135,193,114,170, 44, 14, 2,104, 67, 8,233,207,243,252,148,194,194,194,207, - 40,165,155,239,163,162, 90, 76, 8,217,126,253,250,245, 23, 0,196,126,246,217,103,175, 3, 72, 68, 81, 8,189, 71, 89,253, 21, - 92,232,217, 0,188, 29, 26, 26,250,211,172, 89,179, 30,200,187, 8,111,220,184, 97, 2,240, 74, 72, 72,200, 15,239,255,176,254, - 45, 74,105, 51,158,138,126, 54,194,229,112, 28,119,218,102,179,205, 73, 74, 74,218, 87, 25,205,117, 69,233,236,209,186,186, 71, -159,169,163,135,125,100,149, 40, 35, 10, 13, 86,153, 90, 46,152,164, 54,227,109, 78,159,243,230,209,219,133,255,136, 27,171,209, -104,180, 62,241,196, 19, 95,115, 28, 39, 2,128,205,102, 19,140, 70,227, 72, 84, 98,228,105, 89,154, 3, 6, 12,248,150,231,121, -107,113,100,136, 51, 26,141,207,223,143,230,131, 34, 51, 51,179, 16,192,184,138,246,137,139,139, 91,245,235,175,191, 14,235,222, -189,187,237,151, 95,126, 73,127,252,241,199,133, 83,167, 78, 81, 66, 72,153, 79,113, 9, 9, 9, 70,148,243, 70, 2, 59, 77,154, - 52,169,241,205, 55,223,156,122,225,133, 23, 60, 23, 46, 92,232,123,252,248,113,219,242,229,203,243, 11, 11, 11, 63,101,213,211, - 63, 11,137, 68, 2,149, 74, 5,147,201,132,140,140, 12,184,234, 83, 78, 41,189, 65, 8,121,124,202,148, 41,113, 83,166, 76,121, - 60, 44, 44,172, 65,245,234,213,171,115, 28,199,165,166,166,102, 36, 38, 38, 38,152,205,230,221, 0,126, 1, 32,173, 89,179,230, -105, 0,171,202,211,187,120,241,226,123, 33, 33, 33,191,111,220,184,241,113,185, 92, 94, 95, 38,147,249, 90,173, 86,174,176,176, - 48,219,108, 54, 95, 50, 26,141, 63,167,164,164, 28,174,100,221,121,149, 16,210, 89, 16,132, 95,150, 47, 95, 30,157,154,154, 26, -177,111,223,190,190,165,247,107,222,188,249,138, 21, 43, 86,212, 24, 59,118,236,141, 53,107,214, 84,170, 15, 22,131,193, 12,150, -123, 23,227,102, 0,155, 31,196, 15, 83, 74,111, 3,120,171,120,121, 32, 36, 39, 39,159, 3, 48,236, 65,102, 80, 74, 74,202, 33, - 0, 61,129,162,217,156, 19,139,110,154,247,197,209, 59, 5, 63,195,233,245, 42,255,144,167,115, 35, 33,100, 74,241,168, 38, 0, -152,114,250,244,233,133,165, 34, 82,103,157,183,187,138, 52,149,165,121,230,204,153,210,154,231, 43,163,249,119,146,147,147,243, -191, 21, 43, 86, 28,127,229,149, 87,228,131, 6, 13,194,229,203,151,241,213, 87, 95, 25,115,114,114,214, 84, 85,243,204,153, 51, -183,155, 52,105,210,108,217,178,101,175, 45, 93,186,180, 63, 33,132,189,139,240, 31,130,193, 96,184, 57,100,200, 16,112, 28, 71, - 40,165,212,106,181, 58, 6, 61, 20,207,103,118,211,141,235,202, 10,224,247,226,197, 21, 31,187, 81, 31, 29, 1,112,228, 1, 95, -251,119, 8, 33,143, 39, 36, 36,204,189,122,245,234,111,101,237,115,225,194,133, 77, 61,122,244, 80, 29, 57,114,228,141,202,142, - 34,100, 48,152,193, 98,184, 36,225, 1,152,171,127, 50,197,253,159,190,177,155,163,202,110,127, 88,154,127, 23, 23, 47, 94,204, - 1,224,120,101, 72, 84, 84, 20,250,244,233,115,223,186,197,102,106, 60,216,204,237,255, 40,182,108,217,242,216,163,114,172,148, -210, 59, 21, 61,156,154, 76,166, 45, 0,182,176, 82,193, 96, 48,131,197,168,122, 69,107,188,159,237, 15, 75,147,193, 96, 48, 24, -140,127, 50, 4, 64,183,114,110,122,110,143, 14, 32,164,242, 47,218,116,165,207, 52,153, 38,211,100,154, 76,147,105, 50,205,255, -158,166, 43,237,255,204,232, 68, 74,233, 95,182, 0,232,198, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,249,168, 45,236,133, -178, 12, 6, 3,237,171, 19,239,158, 97,196,167,172,109, 61,195,136, 79,251,234,196,155,229, 18,131,193, 96,184, 15,235,131,197, -248,215,241,244,211, 79,243,149,217, 63,222,219,155,203, 75,170,254,169, 70, 37,239,171, 51, 24, 63,189,254,203, 27, 95,252, 23, -242, 33, 56, 56,184,158,167,167,231, 8, 0, 13,116, 58, 93,128, 74,165, 74, 7,112, 49, 63, 63,127, 85,106,106,234, 21,119,117, - 58, 69,145,233, 2,143,153, 70, 30,164,115, 4,153,243,123, 2,125,215,190,173,115, 4,153, 33, 74,240,166, 0,208, 78,145,228, -189,189,241,244, 61,119,117,123,214, 34, 6, 10,200, 9,129,121,251,117,234,120,193,101,175,218,196, 32,210,123,215,247,172, 77, - 76,148, 66, 74, 0,227,246, 27, 84,193, 74, 58,131,193,248,207, 27, 44,153, 76, 22, 67, 41, 29, 69, 8, 9, 34,132,220,165,148, -126, 99, 50,153, 46, 60,106,153, 37,147,201, 98, 8, 33,163, 40,165, 65,148,210,187,132,144,191, 57, 31, 8, 89,255,116, 81, 20, -114,224, 58,136, 0,165,172, 72,151, 97,174,146,171, 47, 29,217,191,197,115,211, 70,117, 70,179, 65,159, 77, 69, 37, 38,177,253, - 39, 66, 8,225,163,162,162, 94,169, 81,163,198,224, 37, 75,150, 72,163,162,162,160, 80, 40,160,215,235,131,111,222,188, 25, 60, -118,236,216,142, 53,107,214, 92,123,235,214,173,175,138,231,136, 43,223, 4,133, 17, 31, 72, 48,115,239,194,177, 50, 0,232, 56, -118,209,140,200,208, 0,106,134, 68, 47,133, 69, 25, 46,193,140,125, 11,199,242,197,219,102, 70,134, 6, 16, 51, 36,122, 39,137, -164,228,228,228,117,101,105, 83, 64,246,243,202, 79,208,239,153,201, 66,104,104,232,107,246,245, 77, 52,132,252,188,106, 30,122, - 13,249, 95,137,245, 49, 10, 8, 91, 87,126,130, 62,207, 76, 46,247,109,227,189,234,112, 22, 81,164,229,214, 91, 28, 71,172, 23, -116,193,211,203,216, 84,102, 58,251, 68, 11,105,102,139,173,204,137, 96,165, 18, 62,253,231,203,214,192,208,208,208,167, 1,132, -185,171,201, 96, 48, 24, 21, 26,172,136,240,240, 65, 28, 79, 22,152, 45, 54, 31,111,111,111,238,203, 47,191,228,250,246,237,139, -159,183,110,197,248,241,227, 39,132,134,134,136, 82, 65,200,161,162,117, 66, 66, 98,202,143,238,252,216,147, 79, 62,153,102,177, - 88,202,157,213,154,231,249,244, 77,155, 54, 5,222,239, 65,133, 54, 31,148,102, 49,155,203,253, 29, 65,144,164,167,156, 94,231, -214,239,132,135,135, 12,226, 9,183,192, 98, 19,125,124,124,124,184, 47,190,248,130,235,219,183, 47,182,110,221,138,113,227,198, - 77, 8, 11, 13, 21,165, 18, 62, 71,180,209, 9, 9,137,137, 63, 62,188, 83, 71,200,250,245,224, 48,176,232,191,245,235,193, 13, - 28, 72, 30,105,147,149,153,153, 73, 0,192,223,223,159,150, 48, 87,253, 90, 60,247,230, 75, 93, 49,103,233,110,232,141,166,213, -255,246,227,140,138,138,122,229,233,167,159, 30,252,222,123,239, 73, 57,174,168,149, 95,171,213, 66,175,215, 35, 52, 52, 20,123, -247,238,149,190,245,214, 91,131, 55,109,218, 4, 0, 11, 42,163,205,243, 60,249,125,231,254, 40,223,192, 16, 83,118, 90,138,236, -249, 94, 13, 72, 89,219,236,235,234,213,171,231, 82,179,154,175,167,241,202,174, 43,181,237,255,143,235, 22,102, 43,103,189, 17, -128,178, 34, 45, 81,164,194,142, 47,198,150,187,125,204,251,107,109,235,126,249, 83,211, 85, 58,205, 22, 91, 64,121,122, 61,198, - 47,178,215, 33, 97, 87,174,184,175,201, 96, 48, 24, 21, 26, 44,194, 97,225,154, 37, 31,251,100,101,231,224,135, 77,219, 17, 29, - 29,141,139, 23, 47,162, 94,116, 52,226, 90, 54,225,122,180,109,204, 9,132, 84,123,251,139,149, 11, 1,184,101, 44, 44, 22, 75, -192,198,141, 27, 65, 8,129,205,102,131,205,102,179, 79,216,135,194,194, 66, 76,152, 48, 33,224, 65, 28,148,197,108, 14,184,249, -199, 6, 72,120, 2,171,141,194, 98,163, 48, 91, 69,152,173, 20,249, 58, 43,186, 60, 62,204,237,223,225,192, 45,252,246,139, 79, -124,114,114,115,177,241,215, 93,142,124,136,142,142, 70,151,118, 45,185,167, 31,239,200,169, 21,242,106, 47, 78,123,223,237,124, -120, 16,172,127,250, 79,115,229,188,110,224, 58,216, 30,165, 2,124,249,242,101,222,104, 52, 14,241,244,244,108, 45,145, 72, 2, - 85,222,193, 98,174,180,102,150,150, 4,221, 50,107,101, 29, 70, 13,168,213,235,141, 23, 58, 97,206,210,221,248,118,203, 31, 43, -188, 66, 19,103,252,155,143, 55, 56, 56,184, 94,141, 26, 53, 74,152, 43,251, 75,205,243,243,243, 81, 80, 80, 0,142,227, 48,117, -234, 84,233,190,125,251, 6, 7, 7, 7,239,170,168,185,112,123, 18,205,233, 20, 69,102,118,124,121,209,108,158,227, 57,153, 79, -248,169,217, 31,124,156,175, 86,171,169, 66,161,208, 87,139,136, 57,213,101,220,210,102,148, 82,234, 21, 90,231,143, 37,223,124, -151,167, 86,171,169, 92, 46,151,191,244,210, 75,110,245,225,212, 27,244,152, 52,105,146, 81,169, 84, 82,133, 66, 65,141,166,162, - 89, 57, 12, 70, 3,222,124,243, 77,163, 74,165,162,106,181,154,154,204, 38,183,243,225,214,221, 2, 72, 5, 14, 82, 9, 15,169, -192, 67, 25, 84, 23,178,194,120,152,205,230, 18,154,238,166,115,207,217,100, 40,101, 18,168,228, 2,106, 71,134, 65, 78,245,247, -236, 51,118,236, 88,209,203,203,203,172,209,104,164,111,188,241, 6,235,191,202, 96, 48,170,102,176, 76, 22,155, 79,144,159, 55, -190,253,230, 91, 76,125,125, 54,234,213,171, 7, 74, 41, 8, 33,120,125,198, 44,124,254,238,116, 12,126,172, 35, 44, 86,209,167, - 60,141,178,134, 90, 18, 66, 16, 31, 31, 15,131,193, 0,189, 94,239, 88, 98, 98, 98,220, 74,176,187,195, 55, 37, 60,193, 47,167, - 10,138,140,149, 69,132,217, 42,194, 98, 21,209, 57,198,163, 82,154, 22,155,232,227,229,161,198,210,197, 11, 49,245,221,143, 75, -228,195,180, 55,222,194, 87, 31,190,141,137, 99,158,133,201, 98,243,169, 74, 58, 43, 3,211, 44,201,225,195,135,131, 85, 42,213, -103,195,134, 13, 11,153, 48, 97,130,140, 10,106, 97,251,177,219, 94,159,124,179, 59,196, 96, 50,243,143,183,175,137,231, 7,196, - 98,206,178,223,139,205,213,157,151, 34,115,115,197,127,243,177,123,122,122,142, 88,178,100,201, 61,230, 42, 45, 45,141, 43, 44, - 44,132,217,108, 22,139,223,151,136,233,211,167, 75,222,122,235,173, 17,132,144,119,139,117,140,101,105,238,189, 69, 63,168, 17, - 26, 40,236,219,187,175,230,187,239,127,148, 63, 96,192,128,235, 28,199, 65, 34,145,224, 70,120, 56,125,172, 91,231,203,239,127, -248,161,241,185,231, 95,186,192,113, 28,120,158,199,213,171, 87,163, 0,168,220, 57,118, 2,208,126,253,250, 57, 52,191,217, 57, -159,218,215, 15, 25, 50,228,186, 93,243,210,198, 57,212,221,252, 20,120,130, 48,127,245,159,191, 32, 87, 2,197,111,197,116,214, -116, 55,157, 2,207,161,117,189,226,231,174,208,102, 64,210,193,123,126, 83,161, 80,152,159,122,234,169,235, 9, 9, 9,110, 31, - 59,187,222,153, 38,211,100, 6,171, 76,204, 70, 61, 98,170,251, 98,241,167,239, 65,164, 28, 40, 40,168, 72, 65,169, 13,145,254, -106, 24,117,218, 74,255,160, 40,138,176, 88, 44, 48,155,205, 88,178,100, 9, 10, 11, 11, 33,138, 34,234,215,175, 15, 0,104,222, -188,185,115, 37,123,231,228,201,147, 53, 92,105, 6, 52, 26,112, 27, 20,213,157,215,189,243,241,215, 56,124,250, 38, 68, 17,144, - 43, 85, 24, 56, 98, 52,172, 54, 10,147,165,242,239, 39, 53,234,117, 8,209, 72, 48,111,238, 12, 16, 65, 2,158, 16, 16, 66,192, - 17, 17,245, 66,189, 97, 50,232, 30,250,137, 27,184, 14,226,250,245, 37, 71,129, 22,245,195,122,116, 34, 87, 42,149,234,179, 85, -171, 86,213,104,209,162, 5, 7, 0,199,175,229,200, 63,249,102,119,200,215, 51,159, 32,205,234, 5, 33, 43, 79,143, 57,203,247, - 97,207,169,148,223, 74,155,171,127, 49, 13,162,162,162, 74,152,171, 79, 62,249,196,127,225,194,133,161, 0,240,212, 83, 79, 37, -119,237,218, 53,243,234,213,171, 8, 14, 14, 38,153,153,153,143, 3,248, 95,241,195,205, 20, 74,233,194,178, 68,173, 16, 12,190, -129, 33, 38,153, 76, 6,137, 68, 2,142,227, 28,139,111, 96,136, 73,237,233, 99, 42,189,222, 93, 8, 33, 37, 52, 75, 60, 8,149, -179,222,101,197, 85,193,254, 85, 73, 39,207, 17, 39,241,178,187,128,201,100, 50, 8,130, 80,233,180, 50, 24, 12,102,176,238,141, - 98, 25,245, 8,243,150, 33, 72, 35,192, 98,177,226,162, 37, 4, 5, 58, 3,204,102, 11,238,152,205,184,117,230, 46,218,181,107, -135, 39,158,120,194,102, 54,155, 33,149, 74,243, 54,110,220,232,235,202, 96,153,205,102,152,205,102,104,181, 90,172, 94,189, 26, -130, 32, 56, 94,156,234,252,198,250,182,109,219, 86,119,207, 74,163,250,141,227, 63,193, 67,193,195, 42, 82, 88,173, 20, 86, 17, -176,218, 40,244,102,138, 39, 70,189, 9,155,141,194, 38, 82,152,172,174,187, 40,149, 48,108,190, 45,208,111,250, 15, 0, 52,142, -237,158,114,138,169,237,120,200,100, 18,200,100, 2, 12, 58,253,223,112,234, 40, 29, 56,144,136,143,106, 39,119,163,209, 56,116, -216,176, 97, 33,118,115, 5, 0, 57,249, 70,193, 96, 50,243,205,234, 5,161,251,224,201,216,185,246, 19,252,122,232, 26,124, 52, -194,254,176,255,134,185,130, 78,167, 11, 80, 40, 20,208,106,181,142,200,213,194,133, 11, 67, 77, 38, 19, 7, 0,130, 32, 9,203, - 16, 67, 21, 54, 17,240,242, 76, 69, 78, 78,158, 31,165,148, 20, 27,157,143, 9, 33,223,148, 53,115,190, 20, 22,101, 86, 90,138, - 76, 46,151, 27,236,198,132,231,121,112, 28,135,172,180, 20, 25,103, 51,209,210,235, 43,131,243,119,157,141, 87, 89,235,221,170, -184,120, 82,162, 2, 40, 79,211,221,116, 10,188,211,126,124,217, 6, 75, 46,151, 83,158,231, 43,157, 86, 6,131,193, 12,214,189, - 17, 44,189, 30, 22,139, 21, 86,171, 13, 22,171, 13,121,133,122,124,248,225,135,144,203,229, 32,132, 64, 20, 69, 20,191, 0,149, -179, 88, 44,120,252,241,199,125, 92,253,160,115,191, 43, 74, 41,120,158, 71,171, 86,173,238,217,239,232,209,163,149, 58, 16, 15, - 5,143,200,110,175,223,179,254,216, 79,239,129, 82,192, 38, 22, 27, 44,179, 27,247, 89, 23,134,173, 73,135,129, 48,153,204, 69, - 17, 61, 74,171, 20,201,123, 96, 38,235, 17,235,115,229, 20, 77,232, 54, 97,194,132, 18,119, 66, 31, 79,185, 85, 33,147,218, 78, - 93, 78, 37, 59,215,126,194,157,184,148, 34,202, 36, 2, 85,211,187, 81,255,149,227, 86,169, 84,233, 58,157, 46, 88,175,215, 35, - 63, 63, 31,249,249,249, 37, 47,104,137,132,188, 52,102,156,191, 68, 42,131,197,108,194,175,171,230,184,212,236, 28, 65,102,132, - 75, 48,227,197,199, 98,224, 87,163,193,233, 27,181,106,137,118,131,114,252,183, 85,109,214,125,252, 74,115, 81, 20, 73,222,157, -179,199, 59, 13,124,249, 24,199,113, 48,153, 76,238, 79,163, 64, 8,185,113,227, 70,148,195, 72, 17, 66,236,235, 47, 95,190, 28, -101, 55, 68,180,232,205, 18,110,161,241,240, 0, 52,213, 0,185,125,122,174, 63,191,234,172,233,110, 58, 27,212, 12, 1,130, 26, - 1, 50,175,138,202,156,236,234,213,171, 81, 54,155,141, 77, 33,193, 96, 48,238,207, 96, 25, 13, 58, 88,172, 54, 88, 45, 69,111, -144, 55,153, 76, 80, 42,149,232,208,161, 67,137,104, 19,165, 20, 59,118,236,128,201,228,186,147,170,213,106,117, 68,176, 68, 81, - 4,165, 20, 63,252,240, 3, 36, 18, 9,164, 82, 41, 36, 18, 9, 36, 18,137,163, 14,118, 23,171,141,226,141,105,175, 65, 34,112, -144, 10, 28, 36, 2,129, 84,224, 96,163, 20, 20, 20, 86, 91,209, 98,178,186, 23,200,168,200,176, 1,128,209,100, 41,122,110,166, -128, 78,167, 99, 37,233, 33,146,153,153, 73,244,122,125,132,183,183,183,147,213,164,168,166,178, 25, 71,246,109,146, 50,242,157, - 13, 33, 38,139, 21, 82,129,167, 67,123, 68,167,236,222,184,215, 47,211,152, 75,236,163, 11,255,229, 92,188,113,227, 70,112,120, -120, 56,242,243,243, 97,181, 90,197,167,158,122, 42, 89, 16, 36, 97,130, 68, 66,250, 12, 25, 39,222,189,155, 98,225, 56, 30,148, -218,240,216,211, 99,137, 92,161,148,154, 77, 38, 43,128, 41,165,163, 87, 61,195,136,143, 40,193,155,246,169, 24,186,140, 91,218, -236,177,110,157, 47,219, 71, 17,254,248,209,203,205,119,127,241,162,125, 91,203, 55, 63, 90,126,221,121, 20,161, 59,200,101,114, -140, 24, 49,194,209,103,233,208,215, 83,138, 12,139, 84,134,126,253,250, 57,214,255, 54, 79,234,182,166,146,183, 2,133,119, 1, -237,221, 18,235, 37, 18, 73, 9, 77,119, 81, 11, 86,224,238,169, 10,247,153, 62,125, 58,135, 82,125,175, 24, 12, 6,163,106, 6, - 75,175,135,213, 98,117,152, 44,179,217, 12, 0,248,244,211, 79,239, 49, 68,148, 82,199,246, 10, 53,141, 70, 68, 69, 69,193,100, - 50, 33, 58, 58, 26,148, 82, 12, 25, 50,228,158,253,142, 31, 63, 94,169, 3,177,216, 40,230,126,248,233, 61,235, 15,174,123, 15, -141,163, 35,209,170,182, 10, 6,139,136, 60,173,245,190, 13, 27, 0,152, 76,102,160,120, 58,124,189, 86,203, 74,210,223,136,197, - 98, 65, 78, 78, 14,140,133, 57,214,186, 65, 52,239,133, 62, 53,141, 25,217, 58,129,163, 6,107,152,135,206, 88,152,157,204,171, - 84,255,141,251, 98,126,126,254,170,177, 99,199,118,220,191,127,191,148,227, 56,228,231,231,163,115,231,206,153, 25, 98,168,226, -165, 49,227,252, 83, 82,146,173,158, 74,193, 40,149, 74,144,158,158, 46,118,236, 61, 76, 63,100,212,171, 33,175,190,249,254,146, -148, 67, 11,239,233,127,165,227, 64, 5,167, 54, 54, 74, 41,253,240,227,143,140, 94,190, 1, 70,129,216,108,206, 77,246,148, 82, -250,205,138,111, 13,190,213,130,141,114,185, 92, 62,116,232, 80,183,218,223, 12, 70, 3,222,126,251,109,163, 66,161, 40, 49, 90, -208, 96, 52, 96,238,220,185, 70,141, 70, 67, 85, 42, 21, 53, 91, 92,215, 31, 28, 71,172, 99,222, 95,107,179,215, 53, 78,193, 48, - 8,130, 0,179,141,104,157, 53,221, 77,167, 59,163, 8, 39, 77,154, 36,250,248,248,152, 61, 61, 61,165,227,199,143,103, 29,177, - 24, 12,198,125, 24, 44,157, 22, 22,139,173,184,137,208,234,136, 58,141, 31, 63,254,158,125,119,239,222,237,210, 96, 9,130,144, -254,194, 11, 47,148,152, 34,129, 82,138, 13, 27, 54,192,222,185,214,110,218,170, 18,193,154,249,214,100,200, 36,124,177, 33, 42, - 50, 70, 34,165,216,242,203, 14,108,249,101,135, 99, 95,158,151,164,223,143, 97, 43, 50,138, 22, 80, 90,116,103,210, 23, 50,131, -245, 48,241,247,247,167, 25, 25, 25, 9,185,185,185,117,213,106, 53,178,178,178,144,157,157,141,220,220, 92,232,243,115,172,106, -107,174,214,100,205,134, 32, 8,184,155,152, 6,155,205,118,247, 63, 18,189, 66,106,106,234,149,154, 53,107,174,125,227,141, 55, -134, 76,159, 62, 93, 34,138, 34,174, 94,189, 10, 16, 66, 37, 82, 25,138, 70,234, 9,200,203,203, 23, 85, 26,239, 84, 51,229, 85, - 18,169, 12, 28, 47, 45,179, 41,249,224, 29,154,219, 41,130,188,211,241,229, 69,179, 37, 82, 41,241, 10,171,119,236,153,145, 47, - 94,176,119, 20,207, 78, 56,115,168,219,171, 95,183,181, 89,173,104,210,182,219,182,103, 70,190,120, 81, 34,145,224,252,249,243, - 81,174,162, 57, 4,176, 14,120,110, 42,239,225,161, 46, 28, 52,104,208,117,187,230,141, 95,231, 23, 62, 59,110, 6, 4,169,162, -112,228,200,145,142,209,133,231,126,122,191,112,192,115, 83,229, 4,229, 55,123, 95,208, 5, 79, 95,247,203,149,218,175,191,254, -186,113,216,176, 97, 14,205,203,151, 47, 71,245,235,215, 79,245,222,123,239, 25,157, 53,221, 73, 39,224,222, 40, 66,149, 74,101, -126,230,153,103,174,151, 53, 50,145,193, 96, 48, 42,111,176,172, 86, 88, 45, 69,125,176,204,102, 51,172, 86, 43,150, 46, 93, 90, -194, 12, 73,165, 82,112, 28,231,210, 96,109,220,184,177,196,228,158,205,155, 55,167,148, 82, 60,245,212, 83,142,230,198,145, 35, - 71, 98,244,232,209,149,238, 68,107,177, 1,179,230,124,234,208,233,221, 61, 14,253, 31,235, 8, 42, 22, 25,181,244,243,155, 42, -229,216, 42, 50,108,142, 8, 22, 40, 64, 41, 10, 11, 10, 88, 73,122,200,152, 76,166, 93, 11, 22, 44,136,120,235,173,183,100,217, -217,217,200,204,204, 68, 78, 78,142, 99, 41, 44, 44, 68, 80, 80, 16,126,251,237, 55,115,126,126,254,209,255,210,177,223,186,117, -235,171, 45, 91,182, 96,223,190,125,131,167, 79,159, 46, 9, 10, 10, 34, 94, 94,105,196, 98, 54, 1,160, 52, 35, 35, 67, 84,105, -188, 83,253, 3,195,238,164,220, 77,143,182,152, 77, 16,109,230,114,123,102,239, 77,160, 31,134,135, 6,242, 71,247, 31,171,249, -217,188, 47, 10,237,166, 69, 34,145,160, 93,159,145,167,223,252,104, 89,252,130, 47, 22,152, 94,124,233,229,139,149, 25,245,119, -209, 16,242,250,149, 43, 87,106,207,156, 57,211,232,172,217,253,149,121,107,250,244,233,163,250,248,227,143,141,246,117, 28,199, -225,201,233, 95,175,137,139,139, 83,213,171, 87,239,186, 43,109,231,209,142,246, 79,251,122,231,117, 15,114, 20,161, 66,161,168, -210,136, 71, 6,131,193, 12, 86, 9, 36, 2,151,119,237,118,170, 87, 53,181, 18, 86,209, 8,155,169,104,106, 5,155,205,134,151, - 94,122,201,177,223,208,161, 67,241,236,179,207,218, 59,148,150,124,130, 37,164,155,171,185, 50, 68, 81,196,193,131, 7, 75,140, -254,169,168, 2, 43, 79, 83,107,180,225,208,143,239, 66,164,128, 88,228,123, 64, 65,220, 26, 53, 88,150,166, 43,195,166,240,240, - 1, 7, 10,240,192,205,228,116, 8, 60,151, 87,217, 99,175, 44, 76,243, 79, 77,185, 92,190,230,135, 31,126,232, 29, 23, 23, 87, -163,113,227,198, 92,118,118, 54, 10, 11, 11, 81, 88, 88,104,143,114,225,210,165, 75,226,237,219,183,147,229,114,249, 15,255,165, - 99, 47,126,253,205,130,224,224,224, 93, 51,102,204, 24,145,153,153,249,120, 78, 78,174,223,207,223,206, 70,175,167,199,146,142, -189,135,106, 77, 84, 80, 36,165,166,213,219,187,237,123,223, 95,215,126, 5,179,201, 52,154,144, 69,151,237,211, 52,148,214, 20, - 33,152, 60,188,124, 45, 74,165,146, 58, 27, 20, 65, 16,224,225,229,107,241,246,169,102,114, 54, 52,101,141,164, 43,239,216,203, -210,180,175,255,167,104, 86,102, 20,161,253,183,216,181,201, 52,153, 38,155, 11,171, 74, 6,139,218,232,132,197, 63, 31, 93, 96, -177,137, 94,246,117, 13, 26, 52,128,217,108,198,111,191,253,230, 48, 30,130, 32, 56,230,134,113,167, 15, 86, 41,238,116,232,208, -161,162,169, 24,238,184,119,166,113, 39,182,243,160,234, 21,109,175,108,194, 92, 25,182,101,123,207,255,153,137, 28,151, 7, 74, - 39,176,226,244,240,136,142,142,182, 29, 62,124,120,210,216,177, 99, 63,235,218,181,107,104,255,254,253,165,225,225,225,144,203, -229,184,121,243, 38, 14, 28, 56, 96,190,117,235, 86,178, 78,167,155,212,184,113,227,255,228, 72,203,212,212,212, 43,197,147,136, -254,207, 62, 21,131, 92,161,148, 14, 29,245,106,152, 99, 20,225,218,175, 96, 52,232, 1, 64,168,104,154, 6, 59, 30, 30, 30, 50, -251, 40, 60, 65, 16, 28,163,240, 60, 61, 61,101,231,207,159,119,140, 4,172,204, 40,194,135,169, 41,145, 72,170,164,233,206, 40, - 66,137, 68, 34,187,116,233, 18, 27, 69,200, 96, 48,238,207, 96,221, 73, 78, 94, 5, 96,149,243,186,199, 31,127,188,176, 95,191, -126, 74,251,136, 66,251,104, 64,147,201, 4,147,201, 4,133, 66, 81,169, 9,161,220,153, 68,212, 29,210,207,109,170,241, 64,115, -197, 13,195,150,146,146, 82,131, 21,159,191,151,182,109,219,166, 94,190,124,121,216,206,157, 59,135,238,223,191,191,155, 78,167, -139, 32,132, 64,169, 84, 38,152, 76,166, 93,114,185,124,205,127,213, 92,149,135,217,108,182, 78,159,245,201,119,188, 32,181,138, -162,153,152,205,230, 81,112,243,165,238, 0, 48,102,204,152, 50, 71,202, 13, 31, 62,188,202, 35,232, 30,166,102,241,107,113,254, -146, 81,132,197, 29,219, 89,223, 43, 6,131,113,127, 6,171, 44,116, 58,157, 55, 33, 68, 72, 73, 73,185,103,155, 84, 42,197,237, -219,183,173,255,133, 76,121,224,134,141,241,151, 17, 29, 29,109, 43,126, 16, 88, 85,250,101,207,143, 2,148, 82, 35, 33,100, 10, - 33,228,227,226, 85, 83,110,253, 62,223, 49, 90,144,144, 5,231,156,183, 85, 16,189, 74,170,226,203,139,147, 42,218,246, 79,215, -148, 74,248,116,167,151, 58,223,179,205,197,111, 38,177, 43,144,193, 96, 60, 16,131,181,119,239, 94, 43,128,202,152,168,244,191, - 32,205,233,236,180, 61,218,172, 91,183,206,198,114,161,132,201, 90, 72, 8,249,198,110,184,220,221,230, 76,114,114,242,186, 7, -157,174,127,131,230,207,151,173,129,127,199,113, 48, 24, 12,102,176, 24, 12,198,191,195,100, 25,171,178,141,193, 96, 48, 24,127, - 13, 4, 64,195,114, 42,229,243,110,139, 16,210,176, 10, 55,132,243,255, 32,205,128, 10, 52,119,185,208,236, 86,133,116, 50, 77, -166,201, 52,153, 38,211,100,154,143,164,166, 43,237,255,204,232, 68, 90, 60, 27,249, 95,177, 0,104,248, 47,209,236,198, 52,153, - 38,211,100,154, 76,147,105, 50,205,191, 79,243,191,182,176, 25,243, 24, 12, 6,131,193, 96, 48, 30, 48,101,246,193,170, 22, 51, - 0, 92,169,121,207, 69, 10,100, 92,216, 84,165,253, 0, 96,214,172, 89,247,101,230,222,121,231, 29,183,222,210, 92,173,225, 0, -112,110,140, 33, 19, 9,144,113,126,147,219,191, 79,106, 12,120, 11, 34,222, 40,250, 7, 31,209, 59,155,102,178,226, 83, 53,154, -106,136,191,133, 72,250,120, 40, 36,253, 34, 60, 36,109,110,230, 26, 15,235,204,226, 86, 74, 44,155, 47,230,211, 28,150, 67, 12, -198, 95,143, 79, 84,187, 97,126,254, 65,163, 69, 74,149, 0, 96, 50, 25, 44,201,137,119,230,211,156,139,107, 75,212,125,190,245, - 7, 6,133,132,141, 87, 42,212,202,162,234,143,152,178,179,238, 46,204,185,117,232,251,135,149, 86, 82,252,238,180,208,208, 80, -239, 67,135, 14,213,104,215,174,221,237,228,228,228, 92,231,125,202,218, 70,157, 95,166, 89,134,102, 96, 84,179,103, 60, 52,234, -151, 13, 70, 99,164,151,167,103,122,118, 86,214,226,212, 91,167,191,178,239, 83,163, 70, 13,207,181,107,215, 6, 15, 29, 58, 52, - 37, 62, 62,190,192,149, 38,131,225,210, 96,113, 4, 88,183,110, 45, 40,165,197,147,108, 82, 12, 29, 50,180,204,253,194,229, 41, -145,162, 40, 62, 11, 96, 56,165,244, 76,138, 37,252,169,170, 36,100,247,238,221,161, 22,139,165,133,213,106,109, 6,160,153, 82, -165,105, 98, 52, 26,210, 9,232,115,143, 61,246,216,105,119,117, 56, 10, 44,251,118, 37,102,141,233,244, 11,128,222,229, 92, 88, -179,146,140,161,149, 51, 72, 34,125,243,143,253, 27,228,222, 42,130, 90,205,159,156, 10,224, 31,105,176, 66, 66, 66,148, 0,158, -227, 56,174,171, 92, 46,175, 99, 48, 24, 18, 0,156, 35,132, 44, 76, 74, 74, 74,169, 98,229,198,197,104, 36,207,171,148,170, 94, -193,106, 89,179,212,220,252,100,157, 69, 60, 32, 18,243,199,149, 53, 68,181, 8,145,213, 12,247,222,247, 90,255,184,232,198,209, - 53, 97,187,176, 31, 38,179,185,223,137, 84, 93,191, 37,167,211, 38,213, 34,164,217, 13, 74, 77,110,166, 43, 24,128, 64, 41, 77, - 4,128,176,176, 48, 31, 81, 20,227, 0, 52, 1,112,134,227,184, 3, 73, 73, 73,247,101,216,254, 69,154, 33,162, 40,190, 16, 24, - 24,248,120, 90, 90,218, 47, 28,199, 45,175,234,249,102, 60, 26,248,250, 5,189,252,229, 55,235, 29,211,214, 83, 81,148, 12,233, -223,105, 4,128, 18, 6,203,219,219,239,185,111,215,252,170, 36,127,190, 97, 67, 54,110,212,192,209, 0, 30,138,193, 34,132, 16, - 74, 41,102,205,154, 69,150, 45, 91, 54,178,122,245,234,181, 41,165, 87,103,206,156, 57,223,121,191,210,219,222,121,231, 29, 90, -252, 93, 90,150,102, 84, 76,251,205,207, 63, 59,184,211,132,177,207,105, 84, 74, 37,244,122,131,223,162,101, 43, 63,249,106,249, -170, 62,207, 62,213,173, 23, 0, 44, 93,186,116, 64,120,120,120,132,201,100,138,159, 57,115,230,202,138, 52, 25, 12,183, 12, 86, -177, 75,199,245,203,103,240,203,207,219,112,252,204, 37,136, 78,197,169, 65,131, 6,106,153, 76, 54, 48, 76,198, 61,215,168, 89, -155,246,253,158,126,142, 88,136, 10,115, 38, 15,173,244, 60, 88,167, 78,157,146,167,166,166,206,142,172,215,252,213, 78, 61,250, -115,245,163,235,193,223,207, 7, 34, 39,195,138,223,174,249,237, 93, 50,242, 75, 0,109,220,246, 65, 4,120,113,228, 51, 8,149, -161,247,143,219,142, 33, 53,215, 6, 66, 0, 66,138, 12, 97,161, 65,196, 27,163,218,191, 83,121,131, 68, 56,111, 21,193,196, 53, - 6, 0,224,255,137, 39, 51, 56, 56,184,153,159,159,223, 87, 35, 71,142,244,169, 83,167, 78,176, 76, 38, 83, 25, 12,134,218,119, -238,220,137,252,236,179,207,186, 7, 7, 7,127,144,154,154,186,161, 50,154,209,222,138,234,143,213,171,241,227,180, 49,207,181, -172, 27, 17, 14,193, 88, 8,209,168, 13,191,125,235, 70,155,185,223,110,120, 49,198, 75, 50,228, 66,158,197,237, 14,137, 10, 15, -233,155,111, 60, 63, 52,186,150,154,194,116,254, 16, 36, 60, 15,133,167, 15, 90,241, 60, 56, 66,235,191,115, 32,249, 13, 0,239, -184, 81,233,190, 11,224, 13, 0, 68, 42,149,110, 8, 12, 12,188,218,182,109,219,198,131, 7, 15, 38, 13, 27, 54,196,153, 51,103, -154,254,252,243,207,163,194,195,195,207, 90, 44,150,223,213,106,245,209, 27, 55,110,184,101,220,106,213,170, 37,211,106,181,173, - 37, 18, 73,231,127,178,102, 72, 72,136,210,100, 50, 61, 27, 22, 22,246, 82,191,126,253, 26,245,237,219,151,212,173, 91, 23, 87, -174, 92,105,254,235,175,191,190,211,164, 73,147,115, 73, 73, 73, 75,101, 50,217,119, 41, 41, 41,110, 77, 2, 60,184, 33,185,178, -246, 60,173, 87,213,237,165,206,145, 55, 0, 37,165, 52,197,141,125, 3, 1,168, 41,165, 55, 31,182,230, 95,244,160,115, 9,128, -175,253,165,245, 28,199, 57, 94, 96,239,252,105,255,219,102,179,105,239,220,185, 83,211,133,102, 93, 81, 20,221,110, 9, 32,132, -208,212,212,212, 43,229,214,241,160, 50, 0,152,251,206,100, 36, 39,222,134,222,160,213,231,230,102,173, 40,189, 95,110, 78,246, -170, 23,134,247,249,159, 76,166,144,132,134,215,192, 27,179, 62,129, 61,234,245,176,152, 53,107, 22,121,231,157,119,176,116,233, -210,190, 0,226, 40,165, 7,162,163,163, 23,148,186,103, 57,182,189,243,206, 59,243,103,205,154, 69, 0,148,105,132,170, 69, 53, - 25, 49, 98,200,128, 78,175,191,246,178,198,190, 78,169, 84,224,181,255,141,150,233,141,166, 54,139,190, 94,249,210,252, 57,211, -150, 1,232, 2, 32,150, 82,122, 2,192,202,138, 52, 25, 12,183, 13,150, 72,129, 95,126,222,134,215,166,191,141,111, 86,124,135, -239, 62, 28, 77, 98, 99, 99, 59, 80, 74,159,139,136,170, 53,240,201, 97,163,149, 17,181, 27,162, 80,244, 68,124,166,136, 83,191, -175, 65,233, 39, 31, 87,108,223,190, 61,150, 82,124, 59,118,250,103,245, 26, 55,109,129,243,201, 86, 28, 74,180, 65,123,195, 6, -129,215, 67, 20, 43, 63,196,220,222,236,215,188,121,115, 36,229, 88,113,224,138, 9, 60, 7,112, 92,209, 11, 93,121, 82,197,156, - 18, 77,215,102,127,123, 42, 38, 51, 77, 4, 68,211,181,127,218,137, 12, 13, 13,237, 18, 21, 21, 53,239,127,255,251, 95, 80,106, -106,170,239,241,227,199, 33,151,203,225,227,227, 35,248,249,249,213,155, 62,125,122,222,220,185,115,167, 4, 6, 6,158, 78, 75, - 75, 75,112, 71,179,129, 70, 22,221,177, 89,204,225, 25, 51,223,241, 50, 29,251, 21, 57,107,214,129,231, 40,164,106, 13, 66,148, - 74, 44,232, 17,225, 59,109, 79,226,134, 70, 74,101,244, 57,189, 62,217, 29,205,240, 0,223, 30,181,235,214, 67,206,198, 47,113, - 61,223,136, 35, 25, 70,244,239,216, 18,181,124,149,104, 98,181,193, 79, 33,116,113,101,176, 8, 33, 62, 0,166,153, 76, 38, 78, - 42,149, 18,133, 66, 49,112,197,138, 21,123,234,214,173,107,176,239,211,186,117,107,180,110,221,154,104,181,218, 38,135, 14, 29, -106,178,113,227, 70,115,112,112,240,193,212,212,212,121,229,233, 42,149,170, 59, 6,131, 62, 92,165, 86,155,150, 47, 91,182,187, -117,235,214, 84, 34,145,224,126, 52, 1, 32, 40, 40,104, 67, 68, 68,132,255,156, 57,115, 10, 90,182,108,249, 64, 52, 35, 35, 35, -119,196,197,197,117,238,209,163,135,208,174, 93, 59,132,132,132, 56,182,249,251,251, 35, 46, 46,142, 36, 38, 38, 54, 62,112,224, -192,194, 29, 59,118, 44,136,140,140,252, 61, 62, 62,190,135,171,243, 67,129,186,247,179,189, 20, 60,128,185,132,144,101,148,210, - 67, 21,156,207,102, 0,134, 1,248,240,111,210,172, 16,165, 82,153,102, 48, 24, 2, 0, 64,161, 80,164,235,245,122,151,115,103, - 17, 66, 52, 31,125,244, 81,128, 84, 42, 5,207,243,176,217,108,142,133, 82, 10, 81, 20, 75,116,134,253,240,195, 15,221,154,219, -237,238,221,187, 90, 20,141,254,166, 78,139, 88,214,103, 68, 68,132,191, 59,154,201,137,183,225, 97,137,207, 10,244, 80,214,136, -244,240,158,221,174, 93,187,217,206,219,219, 70,123, 1,200,135, 94,127,247,118,114, 34,252,254,134,186,205,123,217,178,101,207, - 46, 93,186,180, 63, 33, 68, 91,156,191,141, 94,125,245,213,223, 75,229,121,163,226, 79,109, 72, 72,200, 94, 66,200,214,208,208, -208,111, 1,220, 19, 29,246,210,120,140,158, 52,238, 69,205,255,217, 59,239,168, 42,174,181,141, 63,123, 78, 47,244, 94, 5, 20, -164, 8, 54, 64,196,138,189,196,222,141, 37, 38, 26, 75, 98, 55,150,104,236, 81, 99, 76,108,177, 37,246, 30, 77,236,189,247,138, - 21, 4, 20, 5,164,247,126,250, 57,179,191, 63, 0, 47, 26,133, 3,122,111,242,153,249,173, 53, 11,157, 51,243,204,158,153, 61, -123,158,121,119, 3,128,121,251,179, 48,119,127, 38,190,235,105,133,169,159,200, 49,108, 80,111,249,230,237,191,143, 4,240, 91, - 57,237,104, 95, 95, 95, 18, 21, 21,197,153, 43,142, 15, 19,193,186,253,224, 9, 54,111,221,134, 65,131, 6, 35,226,236,134,227, -157,122, 14,233,216,184, 69,123,232,133,118,136,206, 32, 72,140,163,224,243,244, 96,192,226,197,157, 67,148, 97,152,109,111,104, -188,115,216,132,227,199,143, 79,170,225, 89,127,201,183,115, 23,243, 30,167,139,176,229,138, 18, 6,117, 62,148, 89,177, 40,206, -120,138,194,180, 39,200, 75,126,252,136, 97,152,185,198,106,254,245, 28, 0,150, 82, 16, 74, 74,138, 28, 80,252,165,209, 24,140, -236, 18,170, 45,142,170,233,237,239,159, 43, 50, 0,218,226,168,202,143,253,225,187,153,190, 75,211,201,201,169,157,187,187,251, -143, 35, 71,142,116,121,244,232,145,153, 66,161, 40,190,117,235,214,165,212,212, 84,123, 27, 27,155,196,254,253,251, 55,177,183, -183,183,107,209,162,133,236,212,169, 83, 51, 1, 12,175, 76, 51, 64, 46,242,111, 30, 28,112, 99,225,210,159,228, 89,251, 86, 67, - 19,251, 16, 55,178,148,120,148,173,164,206,166,121,164,159,175, 21,100, 34, 62, 70, 6,218,155,140, 63, 21,247, 67,233,203,172, -210,115,247,112,180,175,165, 83, 42,160, 82,234,112,252,121,190,242, 70, 65,190, 29,243,240,101,230,212,174,193, 18, 94,102, 10, - 28, 76, 4, 94, 85,189,158,132, 16, 72, 36,111,159, 30,206,194,194, 2,161,161,161,168, 89,179,166,112,224,192,129,173, 1,172, -120,151,166, 86,171,113,100, 89, 10, 51, 51, 51, 97,155, 54,109, 8, 33,132,190, 57,129,121, 85, 53, 1, 64, 46,151,119,168, 95, -191, 62,111,247,238,221, 69,105,105,105,241,159,124,242, 73,150, 68, 34, 97,223,216, 6,110,110,110,248,234,171,175,132,195,135, - 15,175, 84,211,222,222,190,221,142, 29, 59, 64, 8,121,245,226,126, 19, 55, 55, 55, 56, 56, 56,160,115,231,206,252,222,189,123, -183,171,232,122,246, 15, 32,209,101,230,169, 95, 0,169,240, 37,210, 47,128, 80, 2,196,188, 25,201,122, 83,147, 82,154, 77, 8, - 89, 15,224, 0, 33,164,207,219, 12, 17, 33,164, 41,128,253, 0, 58, 81, 74, 51, 42,187,239,229, 53, 69, 34,145, 80,171,213, 90, -190,105,124,170,170, 89, 62,226, 19, 30, 30,142,192,192, 64,148,255,171, 82,169, 94,205,189, 74, 8,177, 51, 54,127,242,120, 60, -252,252,243,207,224,241,120, 16, 10,133, 16,137, 68,111,253, 27, 28, 28, 92,213, 50, 36,145, 16,194,212,168, 81, 99, 26,143,199, - 27,174,209,104, 92,196, 98,113,138,193, 96,216,106,101,101,245,125,120,120,184, 14,128,197,219,230,134, 45,175,169, 84, 21, 43, - 41,203, 74, 53, 26,149, 78, 42,151,186, 93,187,118,173,246,187,238,185, 90,173, 70,155, 54,109,144, 94, 88,156, 89,182,207,255, -170,172,187,118,237,154, 91,141, 26, 53,188, 1, 52, 47, 93,117, 57, 57, 57,185, 69,185,255,151,231,114,114,114,114,167,210,127, -199,188,124,249,210,173,204, 96,149,215,212,104,180, 30, 38, 38,114, 0,192,220,253,153, 80,239,168, 5,241,224,231,248, 60, 68, - 13, 83, 83, 83, 24, 12,122,239, 9, 19, 38,108, 67,201, 51,113,135, 82,218, 99,194,132, 9, 62, 0,206,187,185,185, 29, 4,144, -255,191, 46,231,255, 13,154, 31,165,193, 42,173, 82, 46,171, 90, 38, 44, 5, 6, 14, 24, 8,150, 2, 39, 79,158, 4, 91, 82,118, -155, 37, 41, 45, 80, 20,103, 3, 62,195,130,207, 35,224,243, 0,128, 32, 59,233, 9, 52,197,217, 87,147, 52,206,113,172, 17,254, -254,228,201,147,161,238,126,141,126,152,187,112, 25,179,249,178, 18,249, 10, 21,178, 34, 15, 35,245,246,166, 84, 86,175, 61,204, - 48,204, 93,134, 97,238, 53,172, 87, 55,218,209,209,177,218,163,118,179, 20, 48,148, 55, 86, 44, 64, 62,178,232,174,139,139, 75, - 39, 79, 79,207,197,163, 70,141,114, 11, 15, 15, 55, 45, 44, 44,204, 60,123,246,108,180, 86,171,189,207, 48,204,202,148,148,148, -150, 59,118,236,144, 77,157, 58,181,189,183,183,183,247,233,211,167, 21,149, 70,174,228,194,122, 67, 62,237,127,163,251,168,113, -146,200,223,215, 64,252, 36, 28, 27,158,230, 26,238,102, 42,103,170,138,244, 43,164, 50,126,211, 92,181,254,204,148, 16, 39,198, - 81, 46,128,171,153, 32,204,216,244,138, 68, 18, 62,229, 75,160,209,232, 81,172, 99, 53,145,153,180,120, 82,203,186, 90, 42,183, -145, 0, 0,159, 97,248, 70, 60,216,185,132,144, 31, 68, 34,209, 44, 66, 8,237,222,189,123,124,195,134, 13, 85, 0,160, 84, 42, -161, 86,171, 33, 16, 8,160, 82,169,240,226,197, 11,220,188,121, 19,150,150,150, 85,186,174,185,185,185,112,115,115,131,137,137, -201,123,107, 26, 12, 6,178,102,205, 26, 81, 68, 68,132,232,143, 63,254, 48,155, 50,101, 74,113, 72, 72, 72,194, 39,159,124,146, - 97,102,102,166,127,240,224, 1,110,220,184,129,188,188, 60, 52,106,212,200, 40, 77,141, 70, 3, 62,159, 15,165, 82, 9,177, 88, - 12, 62,159, 15,189, 94, 15,150,101, 95,153,174,162,162, 34,228,228,228, 64, 40, 20,226,109, 70,177, 60,101,102,169, 95, 0,161, -191, 31,191,158, 1,176, 20,154, 66, 29, 52,249, 58,168,203,150, 92, 93,191,137, 63,213,255,253, 49, 37, 85, 40,132,111, 18, 66, -250, 0,216,255,166,201, 42,103,132,250, 80, 74, 31, 84, 85, 83,171,213, 94, 45, 51, 62, 18,137,196,142,144, 18, 99, 40, 22,139, -117,106,181,186, 85, 85, 52, 1, 32, 60, 60, 28, 13, 27, 54,228,149,106,150,111,102,195, 86,245,185, 36,132,128,199,227, 65, 44, - 22,131, 97, 24,132,132,132,160,119,239,222,240,245,245, 69, 98, 98, 34, 78,159, 62,141,168,168, 40, 8,133,194,215,170, 10,141, - 33, 44, 44,140,231,225,225,113,189, 93,187,118,254, 99,199,142,149,184,185,185, 33, 58, 58,186,198,218,181,107,167, 93,189,122, -181,123, 96, 96, 96, 80,120,120,120,165,105, 78, 75, 73, 90, 61,160,123,216,103,121,185, 57, 59,106,248,154,207, 85,171,213,120, -242,228,137,209,251,252,175,202,184,166, 77,155, 38, 80, 74,159, 81, 74,175, 16, 66,234, 38, 39, 39,183,112,118,118, 62, 65, 41, -149,191,113,205,139,147,147,147, 59, 57, 59, 59, 23, 80, 74, 31, 17, 66, 98, 8, 33, 9, 73, 73,127,157,209,200,194,220, 44,179, -168,168,216,222,196, 68,142,153,221, 45, 32, 30,252, 28, 99, 91,241,160,211,233,240,226, 69, 60, 60,220, 93,201,158,205,135,130, - 0,220, 1, 16, 28, 30, 30, 14, 0, 65, 0,226, 18, 19, 19, 29,203, 12, 22, 7, 71,149, 35, 88,111,246, 2,180,171,219, 3, 53, - 68,188, 94,143, 79,174,184,233,165,165,110,246,254,159,148, 70,162, 75, 34,213, 9, 15, 78,130,101,217,173,233, 70,244,202,187, -113,227,134, 68,207, 98,243,212,111,231, 51, 27, 46, 40,145,158,150,130,148, 75, 75,161,204,120,178, 69, 42,149, 78,110,211,177, - 75, 65,117, 78,164,124,143, 70,103, 97,146,191,133,181, 3,212, 90, 90,106,176, 94, 55, 89, 31, 11, 78, 78, 78, 93, 61, 61, 61, -231, 31, 62,124,216, 77,169, 84,154, 94,187,118, 45,239,204,153, 51,207,180, 90,237,198,212,212,212,157,165,133,206, 97, 62,159, -191, 0, 0, 76, 77, 77,249, 60, 30, 79, 90, 81, 35,205, 0,115, 97,195, 97,159, 13,186, 58,105,229,111,146,103,143, 31, 96,229, -254,227, 16, 27, 52,134,200, 92, 77,143,199,133,186,163,165,155,157,239,236, 36, 75,166,160,174, 2,134,192, 74, 42,116, 8, 37, - 68,114,131, 82, 85,101,105,182,113,117, 99,116, 53, 60,112, 69,175,130,137,169, 80, 4, 0,206,181,253,120,247,149, 58, 92,123, -248, 4, 18,137,165,208,200,151,236,108, 59, 59,187,198,151, 46, 93, 34, 69, 69, 69,170, 71,143, 30,193,202,202, 10,246,246,246, - 48, 55, 55,199,147, 39, 79,112,238,220, 57,196,196,196,128, 82,138,122,245,234, 85,233,218,166,167,167,163,160,160, 0, 61,122, -244,108,157,146,146, 44,177,179,119,208,156, 63,119,246,108,117, 52, 89,150, 37, 0,224,239,239, 15,127,127,127, 65,114,114,178, -197,209,163, 71, 77, 22, 47, 94,236,100,107,107,123, 71,169, 84,190,102,156,140, 53, 88, 0,160, 82,169,160, 86,171, 33, 20, 10, - 33,145, 72, 32, 20, 10, 81, 80, 80,128,244,244,116, 20, 22, 22,190,138,184, 25,171,251,234,211,100,123,179,187,127,205, 28,159, -217, 85,243, 75,247, 90,169,201, 58, 79, 8, 41,187,191,233,165,127,251, 84, 84,213, 87,137,230,107, 17,150,114, 81, 38, 65,117, - 52, 3, 3, 3,203, 52, 94, 43, 37, 36, 18, 73, 70, 89,228, 74, 34,145, 24, 53, 85, 23, 33, 4, 44,203, 66, 40, 20,162, 94,189, -122,152, 57,115, 38, 34, 35, 35,113,225,194, 5, 56, 58, 58,162,107,215,174, 16, 8, 4,136,143,143,127,173,125,150, 49, 55, 39, - 62, 62,126, 90,251,246,237,253, 87,174, 92, 41, 73, 72, 72, 64, 84, 84, 20,204,204,204, 48,127,254,124,241,244,233,211, 61,175, - 95,191, 62, 27,192,143,149, 94,195,156, 39,251, 75, 13, 46, 26, 52,104,240, 89,155, 54,109,254, 90,174,218,218,154,239,222,189, -219,174,204,120,149,223,231,127, 69,114,114,114,222,220,185,115,151,251,250,250,174, 40,173, 22,108, 78, 41,149,167,164,164,132, -237,223,191,159, 0, 64,159, 62,125,168,147,147,211,197,210,188,241,104,197,138, 21,173,162,162,162,232,220,185,115,223, 90,206, -165,102,164,174,255,113,213,134,229,115,103, 76, 20,125,211, 89,134,207, 67,212, 96, 89, 22, 60, 30, 15, 43,215,109,214,197, 68, - 62,122, 24, 20, 20,116,148, 82,218,163, 52,154, 89, 4, 32,134, 16, 18, 39, 18,137, 82, 94,188,120,193,185, 7,142, 74, 97,202, -135,199,223,181, 81,198,163,131, 96, 89,214,209,194,214,217,106,228,167, 29,192,178,128,158, 5,244, 6, 10,165,162, 24,105,209, - 23, 20, 26,141,198,168,135, 46, 59, 59,123,193,176, 9, 75, 60,239,190,228, 35, 53, 87,131,164,115,243,169, 58, 43,186,119,215, -174, 93,135,183,105,211,166,160,218, 39, 82,218,243,209, 89,152,228,111,105,227,116,241,187,165,155,112,231,133, 6, 44,253, 79, - 36,203,192, 2,236, 71, 18,192,114,118,118,246,178,180,180, 92,118,248,240, 97,119,145, 72,100, 26, 27, 27,107,184,120,241, 98, -138, 78,167, 91, 91,102,174, 74, 77,216,160,128,128, 0,157, 76, 38,131, 66,161, 80,233,116,186,162,119,153, 43,127,169,212, 37, - 48, 32,224,242,164,149,191, 73, 84, 26, 13,242,149,106,216, 58, 58, 24, 30,229, 42,122, 60, 42, 84, 31,125, 21,225, 50, 21, 52, - 9,170,229,236, 76, 36,166,160, 0,146, 11, 53, 41,198,152, 43, 0,144,155,154, 51, 46, 65, 97, 8, 26,191, 26, 74,158, 57, 5, - 0, 75, 59, 39,166,213,152,239,209,113,229, 37,168,249,166, 70, 91, 96, 62,159,175,246,242,242, 82,149, 22,170,200,206,206, 70, -100,100, 36,114,114,114,176,122,245,106, 68, 71, 71,191,122,233, 86,205, 96,188,122,137, 35, 51, 51, 67, 76, 41, 69, 70,122,154, -168,186,154,101, 6,171,220,189,195,232,209,163,249,197,197,197,146,242,230,170,170, 6,171, 44, 29,148, 82,104, 52, 26,228,231, -231, 67,163,209,224,217,179,103,175,204, 85,105, 4,173,106,231,175, 41,212,189,117,189, 42, 71,247, 30,213, 9,215, 0, 8,203, - 13, 82,104, 95, 93,115,245,134,241,169, 82,244,167,178, 8, 22,222,210,128, 89,169, 84,218, 83, 74, 73,120,120, 56,140,105,127, - 85,222, 96,137, 68, 34,244,237,219, 23, 17, 17, 17, 72, 76, 76, 4,159,207,135, 74,165,130, 74,165, 66,163, 70,141, 32, 18,137, -170, 26,193,162, 2,129, 96,208,216,177, 99, 37,113,113,113,200,202,202, 2,195, 48,208,235,245, 48, 24, 12, 24, 62,124,184, 84, - 36, 18, 13, 66, 21, 27, 98,223,191,127,191,195,181,107,215,188,223, 92, 50, 51, 51,243,197, 98,241, 63,178, 12,220,191,127, 63, -233,211,167, 15,237,211,167, 15, 45, 51, 90,198,146, 25,247,120,253,206, 61, 7,207,204,156,187,180, 40, 43, 59, 7,114,185, 28, -153, 89,217,248,110,193, 50,221,133,171,183, 47,142, 30,254,105,232,242,229,203,151, 0,136, 41,221, 37,102,197,138, 21, 67, 71, -140, 24,177,189,108,184, 6, 14, 14,163, 35, 88,101, 85,132,239,248,178,107, 96, 97,227,124, 97,198,162,223, 76, 14, 60,228, 33, - 55, 53, 6,170,140, 24,184, 54,236,142,244,152,107,160, 6,221,159,145,145,145,197,149, 29,236,212,169, 83,181, 93,189,131,198, -215, 15, 12,193,210, 99, 69, 40,138,220, 3, 77,110,220,186, 46, 93,186, 28,124,223, 19, 97, 41, 48,105, 80, 19,127, 75,107,199, -139,223, 46,249,205,234, 72,132, 0,217, 41, 49,136, 62, 52, 13, 6,237, 95,106,197,142, 87, 85, 95,202,106, 68, 69,121,233,208, - 20, 26, 32, 97, 20,146,191,251,198, 37, 39, 39, 63,243,247,247,223,246,235,175,191,142,170, 87,175,158,108,252,248,241, 79, 11, - 10, 10, 22,166,164,164,252, 94,238, 69,222,186,102,205,154, 83,230,207,159,239,249,242,229, 75, 92,190,124,249, 25,143,199,187, -243, 46,205, 8,165, 50,169,174,185,120,237,213, 93, 27,191,225,185,121, 99,239,220,169,250,235,143,159,116,139, 44,212,159,120, -101,174, 76, 68,190,161,254, 94, 71,191, 30, 59,138, 49,220, 59,137,232,196, 12,164, 22,235,206, 25,157,238, 66,133, 78, 32,150, -194,196,193, 29, 9, 42, 86,232,226,226,114,123, 68,207,174, 66,134,199, 7,195, 23,226, 69,158,218,232,151,184, 94,175, 23, 63, -121,242,132, 0,120,205,220,169, 84,170,119, 70,124, 62, 36,198,106,190,173,125, 20, 0,232,116,186,106,107,150,143,216, 84,118, - 44,150,101,161, 86, 87,161,175,136, 58,239,237,247, 64,153,165,251, 16,151,173,244,175,232,125,204, 85,153,241, 41,107,128, 46, - 22,139, 95,153, 20, 99,163, 76, 21, 68,176,170,245,251,219, 12,186, 80, 40,132,143,143, 15, 46, 95,190, 12, 11, 11, 11,152,152, -152, 64, 46,151, 67, 34,145,192,194,194, 2, 34,145, 8, 12, 83,165, 33, 2,169, 86,171,173,225,226,226,130,103,207,158, 65, 34, -145,188, 90,196, 98, 49,124,124,124,160, 80, 40,156,241, 81,197,234,255, 59, 12,237,211,182,251,250, 93, 7,134,236, 61,112,116, -140, 90,165, 10,240,241,246,162, 81,143,239, 61, 28, 61,124, 80, 71,238,234,112,124, 80,131, 85, 65,161,210,192,194,198,249,194, -180,239,127, 53,219,119,143, 65, 94,106, 52, 18, 78,126, 91,104,208, 42,114, 89, 86,231,150,251,252, 42, 0,108, 53,242, 75, 62, -184, 73,235,238,204,197, 40, 13,180,133, 41, 40,136,216, 27, 47, 22,139,167,127,136, 19,113, 21, 37,249, 91, 90, 59, 94,156,190, -248, 55,171, 3, 15,249,200, 73,137,193,243,227, 51,242, 13, 90, 69,235,240,240,240, 87,227,104,217,251,247,192,231,211,150, 99, -243, 15, 19,141,214, 30, 44, 18,117,239,239,103,209,101,120,243, 20, 24,136, 1,131,158, 68,117,114,106, 78,186,167, 92,161,135, -254,206,155, 23, 17, 17,241,189,151,151, 23,163,215,235, 63,215,106,181,115, 83, 82, 82,246,151,139, 92,181,115,115,115, 91,186, - 96,193, 2,151,132,132, 4,209,141, 27, 55,114,238,223,191,207, 26, 12,134, 37, 21,105, 62,202, 87, 79, 13, 48, 21,242,188, 92, -157,198, 62, 75, 74,234,246,184, 64,127,178,236,183, 0,185,200,191,121,125,223,107, 11,230,126,107,170,185,186, 31,197,169,137, - 88, 29,158, 86,192, 26,116, 51,140,140,186, 89,185, 9, 41,153, 49,226, 51,182,176,176, 16, 50,145,144, 77,140,126,206, 27,210, -182,133,225,135,105,147,153,180,180, 52, 40,138,139,249,206,206,206, 86,201,201,201, 57,149, 68, 8,230, 3,104, 93,175, 94, 61, -180,111,223, 62,126,222,188,121, 81,229,205,199, 63,204, 96,189,245,235, 90,171,213,146,234,106,150,143, 96, 85,102,176,170, 28, -193, 82, 23,188,221, 72, 41, 50,223,215, 96,189, 36,132,212, 40,251,247,135,184, 7, 42,149,202,174, 92,213, 32, 40,165,213, 14, -103,149, 70,176,170,253,123,121, 24,134, 1,165, 20, 34,145, 8, 49, 49, 49,112,112,112,128, 94,175,135, 92, 46,135, 76, 38, 67, -105, 68, 25, 34,145, 8,124, 62,191, 42,201,100, 69, 34,209,203,152,152, 24,111, 75, 75, 75, 24, 12,134,215, 76, 86, 92, 92, 28, -228,114,121,114, 85, 35, 88, 13, 26, 52, 56, 37,149, 74,221,222, 92,111,107,107,107,254, 79,125,121,149,143, 92,245,233,211,135, - 78,152, 48,161,202, 26,171,190,255,102, 7,128, 29, 19, 38, 76,216,182,107,227,241,160,160,160,160, 99,190,190,190, 4, 0,184, - 30,131, 28, 31,196, 96,149, 21, 74,101,127,203,218, 51, 57, 11,147, 26, 88, 88, 59, 93,152,178, 96,131,217,174,187, 12,242, 83, -163,144,114,118, 86, 62,171, 85,180,102, 24, 38, 53,241,250,175,251, 1, 40,238,221,187,119,201,214,191, 7, 8, 41,233,185,247, -182,145,220, 75, 11,250,134, 62,181,107, 99, 95,132, 30,170,180,135, 96, 8,221,218,182,109, 91,197,251,158, 68, 96, 96,160,191, -165,181,227,197,169,139,126,181,218,119,159,143,220, 18, 19,152,207,106, 21,173,147,181, 46,175, 13, 82,202, 18, 96,243, 15, 19, -193, 26, 81, 12, 15, 39,196,146, 39,151,172, 29,210, 62,184,159, 91, 45, 23,176, 84, 7, 86, 72,209,107,170, 13, 63,230,158,226, - 96,141,246,188,223,217, 34,118, 76,210,141,191,111,244,241,103,207,158, 45,112,112,112, 56,144,150,150,246,170,117,170,139,139, - 75, 39,119,119,247, 69,243,231,207,119, 79, 74, 74, 50,189,127,255,126,193,254,253,251,227, 24,134,153,159,154,154, 90,233,215, -253,227, 66,237,100,127, 19,209,198,136, 34,253,171, 49,116,234,200,133,245, 62, 27, 50,240, 70,219,129,159, 73,158,159,221, 1, -171,184, 39, 88,121, 47,221,144, 92,168, 26, 24,165,160,105,198,152, 43,177, 88,188,127,245,254,253,207,234,214,173, 75,138,139, -139,161,211,233,144,149,149,133, 31,119,238,139,164,148,194,210,210, 18,103,207,158,101,199,143, 31,191,223,217,217,185,207,187, - 76, 86,185, 97, 26, 32, 20, 10,137, 84, 42,245,136,143,143,143,119,119,119, 87,189,205,164,136,197,226, 42, 27, 44,169, 84, 10, -150,125,119, 16,160, 42,154,122,189,158, 24,179,190, 42,154,101,105, 43,107,220,254,230,250, 50,120, 60, 30, 88,150,173,240, 92, -254,234,222,222, 17,193, 82,100,188,151,193,162,148,186,149,117,164,249,167, 21,132,165,145, 48, 0, 96,223, 53, 20, 67, 85, 34, - 88,165,102, 15, 34,145, 8,151, 47, 95, 70,215,174, 93, 65, 41,133, 88, 44,134, 76, 38,131, 68, 34,193,181,107,215, 32, 18,137, -192,227,241,170, 18,197,162,122,189,126,231, 47,191,252,242,237,226,197,139,165,101,199, 40, 51, 88, 63,253,244,147, 82,173, 86, -239, 52,198, 96, 17,203, 58,253, 45, 44,173, 6,231,229,101,111,109,226, 99, 81, 97, 47,194,183,237, 83,218, 30,235,191, 78,217, - 48, 13,148,210,238,111, 14,197, 80,182,205,132, 9, 19,240,230, 16, 14, 21, 13,211,224,228,228,100,185,113,227,198, 17, 44,203, -214, 41, 93,245,102,111,193,178,251, 88,246,126, 42,235, 85,248, 90, 47, 66, 14,142, 42, 71,176, 24, 2, 56,242, 95,250, 90, 88, -187, 92,152,180, 96,131,217,182, 91, 60,228,167, 62, 65,214,133,239,242,169, 94,217, 58, 60, 60,252,190, 93,221, 30, 8,105,218, -186, 89,219, 79,250,192,254,200, 62,220,185,126, 30, 63,174,222,140,111,198,126, 81,225,135,146,157,157, 53,178,174,171,160,203, -125, 6, 66,200,189,247, 61,129, 70,141, 26,121, 89, 88, 57, 92,156,178,240, 87,171,221,225,124,228,165,252,199, 4,206, 88,115, -225,254, 87, 35,134,190,182,189,177,211,227, 12, 22,137,186,251,215,118,217, 52,160, 83, 83, 75,115,162,135, 62, 33, 10, 27, 63, -235,135,240,174, 90, 52,237,111,142, 70,157, 77,225,217, 64,210,239,248,111, 57,109,156,154,147,225,127,103, 52,171,188,185,114, -114,114,234,234,226,226, 50,239,216,177, 99,110,122,189,222,244,242,229,203,133,251,247,239,127,174,215,235, 87,165,166,166, 30, - 51, 58, 58, 86,164,121,101,174, 2,204,133, 13,135,127, 62,244,234,248, 21,235, 37,145,225,119,176,116,231, 17,152,241,116,134, -187,105,170,190, 17, 69,255,169, 62,172, 48,163,241,249, 11,118,239,222, 45,247,243,243, 35,217,217,217,175, 34, 45, 90,173, 22, -249,249,249, 40, 44, 44,132, 90,173, 70, 64, 64, 0, 51,119,238, 92,249,119,223,125,183, 0,192, 24, 99,211,107,107,107, 11,161, - 80, 8,173, 86,251,202,164,136, 68, 34, 88, 88, 88, 32, 63, 63, 31,103,206,156, 65,101,131, 83, 10,133,162, 84,134, 33,174, 38, -166,166, 58,185, 92, 78,229,114,249, 95,182,169,170,102,169,201,201,236,212,169,147,237,252,249,243, 5,129,129,129,175,214,151, - 85, 17, 86, 71,147, 82,170,104,223,190,189,108,213,170, 85,112,115,115,131, 70,163,121,205, 72, 49, 12, 3,161, 80,136,196,196, - 68, 44, 92,184, 16,148, 82,227, 63,100, 84,185, 58, 4, 12,181,131, 50, 91, 7,101,182, 14,170, 44, 45,138, 51,116,208, 41, 12, -255,180, 2,172, 58, 13,208,141,136,132,217,189,111, 4,171,172,186, 82, 44, 22, 35, 62, 62, 30,167, 78,157, 66,104,104, 40,204, -204,204, 80, 92, 92,140, 43, 87,174, 32, 57, 57, 25, 98,177, 24, 60, 30,175, 74,141,220,107,212,168,241,195,237,219,183,187,142, - 27, 55,174,206,151, 95,126, 41,245,245,245, 69, 92, 92, 28,150, 47, 95,174,122,244,232, 81,172,165,165,229,124,160,242,121,102, -157, 93,107,140,223,184,243,168, 96,216,192, 78, 99,129, 98, 24,211,139,240,245,125,254, 55,141,221,223, 49, 76, 67,167,119,108, - 94,126, 8,135,215,134,105, 40,207,193,131, 7, 61,156,157,157,125, 81,210, 51, 16,248,107,111,193,242,220, 9, 15, 15, 15, 6, -215,139,144,227, 67, 24,172,210, 2,122, 98, 72,239,153,102, 91,111,242,145,155, 28,129,252, 43,115, 94,153, 43,160,164,225,187, - 93,221, 30, 48,176, 20,173, 59,246, 46, 27, 20,244,205, 66, 38,160,252,184, 85, 2,137,105,128,158, 10, 1,168,160,207,123, 14, -145, 72,116,191,170, 9,126, 83,147,101,217,201,141,123,207,180,218,126,135,143,252,148, 39,200,188, 56, 59,159,213, 42, 90, 39, -106, 92,238,127, 53, 98,168, 81,141,218, 9, 33,109,203,198,244, 24, 44, 18,125, 39,224,145, 89,159,180,104, 40,108,214,160, 54, -228, 25,241, 72, 75, 74,193,222, 39,153, 57,177,185,234,225,215,136, 22, 9,207,213, 27, 59,143,176,178,178,116, 16,160,203, 40, -107,171,155, 71, 10, 14, 58,183,102,180, 84, 75, 23,167, 92,165,115,223,212,252, 80, 84,166,233,236,236,236,101,106,106,250,227, -201,147, 39,109, 69, 34,145, 89,100,100,164,225,192,129, 3,137, 6,131,225,167,212,212,212, 61,213,209,244,151, 74, 93,234,120, -123, 92, 26,255,243, 58, 73, 81,177, 2,197, 26, 45,156, 92,157, 13,151,238, 69,245,142, 40,210, 28, 50, 70,211,222,222,190,213, -192,129, 3,235, 5, 6, 6, 50,229,205,149, 70,163, 65, 65, 65, 1, 10, 11, 11, 81, 80, 80,128,130,130, 2, 36, 39, 39,163,105, -211,166,140,175,175,111,128,189,189,125,171,244,244,244, 11,111,106,150, 27,166,225, 91, 0,140, 76, 38,139,185,126,253,186,170, -119,239,222,144, 74,165, 40, 46, 46,134,139,139, 11, 88,150,197,149, 43, 87, 16, 19, 19,147, 7, 96,119, 90, 90,218,217,138,210, -169, 84, 42,106, 16, 66,120,102,166,166,109, 59,116,232, 48,112,248,240,225, 22,229,183,175,142, 38, 0,100,102,102,186, 95,190, -124,249,187,238,221,187,143,237,216,177,163,108,198,140, 25, 2, 15, 15, 15,232,245,122, 82, 93,205,220,220, 92,243,123,247,238, - 45,107,214,172,217, 87, 29, 59,118,228, 47, 90,180, 8,230,230,230, 48, 24, 12,144, 74,165, 40, 40, 40,192,252,249,243,113,245, -234, 85, 61,165,116, 77,126,126,254,148,138, 52, 95, 27, 7,107,210,207,245, 43,202,135,239, 26, 7,235,239,200,243, 74,165,210, -190,170, 81, 49, 99,210,121,239,222, 61,250,230,120, 88, 21, 69,176,222,166, 89, 22, 93,226,243,249, 72, 75, 75,195,209,163, 71, - 95, 27, 3,171,108,121, 87, 21,225, 59,210, 73, 47, 94,188,104, 32,132,132,234,245,250,105, 19, 38, 76, 24,174, 80, 40, 92,228, -114,121,138, 86,171,221,106, 97, 97, 81, 54, 14,150,176, 50, 77,145, 72, 34, 32, 12, 3,169, 68, 46, 85, 42, 51, 19,222,214,139, -240,141,107,157, 32, 18,217, 91,151,237,243,191,186,239,111, 12,211,240,218, 80, 12,111,236,243,218, 16, 14,111, 14,211, 80, 94, -179, 71,143, 30,113, 0,162, 41,165, 12, 33, 36,250,205,222,130,229,100,189,195,195,195,131,131,130,130, 46, 81, 74,101,111,246, - 34,252, 59,242,252,199,172,249,175, 49, 88, 0, 36,215,194,159,130, 17,103,160,240,214,143,175,153,171, 87, 79, 58, 11,220,185, -126, 30, 44, 11,180,104,223,179, 82, 51,163, 87, 23,199, 46,216,251,162,129, 65,163,132,190, 32, 33,166,227, 39,157, 51,222, 39, -241,182, 1, 61,225, 42,164,242,171,247, 98,193,151,100, 35,239,230, 15,121,196,160,110, 29, 30, 30,254,160,218,153, 6,152,177, -238,196,126, 33, 49,183,194,195, 9,195,144,146, 87,140, 19, 47,114,127,167, 10,245,152, 29,180,164, 42,208, 37,148, 92,217, 52, - 51,109,109,243, 94,230,253,108,156, 5,248,249,155,173,144, 76,183, 22, 54,106,211,226,111,157,163,176,172,225,251,198,141, 27, - 71, 7, 6, 6,154,124,253,245,215, 79,243,243,243, 95,107,248, 94, 85, 34,148,202, 36,127, 83,209,186, 11,191,254,252,141,212, - 63, 4,251, 23,206, 48, 92,190, 23,221,227,113,161,230,168,177, 26, 98,177, 56,108,204,152, 49,194,226,226,226,191,152,171, 55, - 13, 86, 65, 65, 1, 30, 62,124,136, 62,125,250,136,163,162,162,194, 0, 92,120, 71, 4,103,118,233,128,147,124, 27, 27,155,204, -117,235,214,117,223,190,125,123,175,225,195,135,139,195,194,194, 16, 25, 25,137,219,183,111,171, 53, 26,205,159, 66,161,240, 80, -124,124,188, 81,173,188, 41,165, 6, 0,167,220,221,221, 47,173, 91,183,174, 59,203,178,175,230,179,124, 15, 77, 29,128,217, 86, - 86, 86,203,246,239,223,191,244,252,249,243, 3,135, 12, 25, 34,209,233,116,228, 61, 52,245, 0, 38,216,218,218,206, 58,126,252, -248,214,211,167, 79,247, 24, 60,120, 48, 51,110,220, 56,172, 94,189, 26,127,252,241, 7,107, 48, 24, 14, 9, 4,130,161,153,153, -153,149,118, 64,121,109, 28,172, 10,198,185,170,236,119, 35,184,251, 95,200,250,239,173,249,102, 36,172, 97,195,134,246,229,123, -105,150,255,107,108, 4,139, 16,130,160,160,160,215,254, 95, 54, 36, 3,143,199,123,109,169, 74, 21, 33, 0, 11, 74, 41, 11, 96, - 13,128,213,120,125, 20,119, 30,254, 51,210,187, 81, 56,187,186, 33, 57, 17,214, 89,197,170,188,138, 39,123,182,183,118,118,117, -251, 59,202,181,188,185,115,231, 46,159, 51,103,206,242, 55,135, 98, 40,191,221,155, 67, 56,204,155, 55, 15,239, 26,166, 33, 37, - 37, 37,119,238,220,185, 63, 0,128,175,175, 47, 41,173, 22, 12, 66,105,111,193,114,154,219, 80, 50, 85,142,236,203, 47,191, 28, - 2,224,157,154, 28, 28, 85, 49, 88,223, 22,133,175,212, 1,176, 38,132,204, 72,214,186, 68,254,181, 16, 1,126, 92,189,249,181, - 73,161, 43,130,199, 99,102,100, 28, 25,182,138, 2,185, 60,130, 25,239,155,120, 75, 11, 51, 24, 10, 13, 51,139,239,173, 98, 41, -165, 22,132,144,233,119,239,222,141,124,111,103,110,110,133,194,249,163,241, 71, 68, 10, 77, 43,214,245,220,161,121, 61, 82, 83, -218,230,170,191, 83,115,178,215,210, 73,112, 96, 66,107,107,114, 44,103,200, 63,226,134, 70, 68, 68, 44,242,242,242,226,173, 95, -191,254,115,141, 70,243, 90,195,247,106,107, 22,106,166, 6,152, 10,121,190, 30,174, 99,163,226, 19,186, 63, 46, 52,174, 90,176, - 28, 34,103,103,231,199, 10,133, 2,132, 16,168,213,234, 87,198,170,176,176, 16,249,249,249,175,254,175,213,106,145,153,153, 9, - 15, 15, 15,148, 27, 51,233, 93, 38, 35,181,188, 71,176,180,180, 60,185,106,213,170,129,171, 86,173,106, 3,224,156, 82,169,220, -157,155,155, 91,173,161, 63, 74,141,206, 94,169, 84,246, 35, 33,196, 89, 44,145,106,174, 94,189,122,226,125, 52,115,114,114, 10, - 1,140,146, 74,165, 11,126,249,229,151, 85, 18,137, 36, 56, 35, 35,227,189, 52, 75,205, 83,111,107,107,107,167,109,219,182,237, -219,180,105, 83, 99, 62,159,127,147, 16,210, 55, 47, 47,175,202,147, 61,147,215,191,222,171,252,187, 17,252,241, 95,200,246,239, -173,105,236,240, 11,198,162,215,235,139,230,204,153,147,241,182,121, 7,203,204, 84,249,117, 90,173,214,168, 97, 78, 28, 28, 28, -140, 30,139,172,162,161,119, 0,128, 33, 68, 9, 64,250,237,188,101,165, 31,204, 70, 79,246, 12, 2,162,249, 95,150,107,115,230, -204,161,243,230,205, 35,132,144, 67, 40, 25,143,234,217,155,141,208,203,255, 54,111,222, 60,204,153, 51,135,206,157, 59,183, 82, -205,168,168, 40, 74, 8, 57, 7, 32, 14, 64,124,121,221,242,235,203,246,169, 72,147,131,163, 82,131,197, 82, 32, 89,235,146, 8, - 96, 88,249,117,127,125,193,225, 47,109,174, 42,242, 88, 29, 59,118, 60, 7,192,247, 67, 37, 62, 47, 55, 31,196,170, 97, 66,110, -110,246,224,140,199,135, 62,136, 38, 11,252, 56,188, 81,216, 55, 0, 8, 5,126,126,211, 92,189,246, 21,116,133, 30,114,108, 74, - 22, 55,106,211, 98, 98,233,203,103,209, 63,225,166,190,173,225,251,251,242,182,134,239, 85,120,217,156, 22,139,197,164,176,176, - 16, 74,165,242,181,104, 85, 65, 65, 1, 20, 10, 5,138,138,138, 80, 54,181, 71, 81, 81, 17, 76, 76, 76,160,211,233,170,244,165, - 88,106, 82,214, 5, 6, 6,110, 44,173, 38,121,111,148, 74,133, 11, 0, 4, 6, 6, 10, 62,156,166, 50, 5, 64,175, 15,169,153, -157,157,157, 2,160,137,167,167,167,200,216,201,162, 43,138,100, 85,247,119, 35, 88,255, 95,200,242, 59,240, 15, 35, 33, 33,193, -239, 67,107,166,164,164,196,124, 72,189,236,172,180, 13, 95, 13,235, 51,166,108,210,103, 99, 38,123, 46, 51,102, 57,217,105, 27, -254, 87,215,178,108,154, 17, 0,212,217,217,121,219,203,151, 47,221, 8, 33, 9,111, 70,146,222,252,109,238,220,185,120,215,152, -127,229, 53, 1,192,195,195,227, 96, 98, 98,162,147, 80, 40, 76, 45,175,251,230,250,138, 52, 57, 56,222,150,209,254,107, 11,128, -128,255, 39,154,109, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252,251, 52, 63,182,133,225, 44, 38, 7, 7, 7, 7, 7, 7, - 7,199,135,133, 0, 8,120, 71,100,235,177,209, 34,132, 4, 84, 35,114,246,248, 31,164,105, 87,129,230,217, 74, 52,219, 86, 35, -157,156, 38,167,201,105,114,154,156, 38,167,249,175,212,172, 76,251,163,233,157,200, 85, 17,114, 97, 94, 78,147,211,228, 52, 57, - 77, 78,147,211,228,170, 8,185, 42, 66, 14, 14, 14, 14, 14, 14, 14,142,127, 52,239, 28,166,161, 87,221,146,238,195,127, 62,226, - 58, 76,112, 0, 60, 30,111,113,139, 22, 45,198, 92,189,122,245, 39,157, 78, 55,191, 58, 26,132, 16, 39,123,123,251,239, 41,165, - 77, 8, 33, 98, 62,159,255, 36, 61, 61,125,145, 78,167,187, 82,221,116, 17, 66, 92, 29, 28, 28,190,103, 89,182, 49, 0, 33,159, -207,143, 72, 73, 73, 89, 72, 41,189,249, 30,154,102, 14, 14, 14,173, 88,150,117, 41, 57,117, 94, 70,106,106,234, 21, 74,105, 50, -151, 19, 56, 56, 56, 56, 56,170,109,176,122,215, 33, 96, 0,212, 9,131,227,188,145,132, 63,103, 3, 77, 44,123,241,160,100, 48, - 54, 95, 0, 81, 0,238, 82, 74, 11,222, 39, 1,255, 95, 52,255,233, 16, 66, 24, 11, 11,139,246, 50,153,108,124, 81, 81, 81, 3, - 51, 51,179,136,210,233,113,142,150, 14, 74,248, 62,218,118, 3, 7, 14,156,190,113,227, 70,244,235,215,111, 22, 33,100, 57,165, -180,168, 42, 26,214,214,214,221, 60, 60, 60, 54,172, 90,181,218,182, 89,179,102, 68, 42,149, 34, 42, 42,202,121,204,152,209, 65, - 78, 78, 78,123, 83, 82, 82,190,170,106,186,108,109,109,251,214,170, 85,107,213,154, 53,107,108,155, 52,105, 66, 4, 2, 1,194, -195,195, 93,198,143, 31, 31,226,232,232,184, 53, 53, 53,117,114, 85, 53,173,172,172,252,106,214,172,217,113,237,218,181,178,166, - 77,155, 66, 44, 22,227,225,195,135,166, 35, 71,142,116,118,114,114,122,152,146,146,114,166, 42,122,129, 35,239, 9,132, 50, 45, - 31, 0,180, 10,161, 62,124, 67, 67,157,177,235,184,226,137,131,131,131,227, 35, 50, 88,125,235, 16, 16, 0,254,205, 48,159,232, -241, 45, 24,144, 9, 3,201,239,171,127,103,110,183,109,219,214,231,139, 47,190, 32,165, 83, 71,248,237,217,179,167, 55,143,199, -139,102, 89,246, 22,128, 7,206,206,206,218,178,105, 9,222,164,131, 23,121, 53, 70,214,153,231, 16, 2,168,207, 48, 76, 72,101, -154,237,106, 65, 75, 8,112,234,217,219, 35,105,237, 61, 9, 64,129, 51, 47,170,166,121, 58,246,227,136,204,153,154,154,122,217, -218,218, 78,182,182,182,238, 20, 20, 20, 84, 48,106,212,168,248,200,200,200,167, 62, 62, 62,170, 77,155, 54, 45,210,233,116,107, -107,215,174,125,166,176,176,112,217,123,140,139,229,174,211,233, 16, 29, 29, 13,134, 97, 4, 0, 60, 0, 60,170,130, 65,115,116, -119,119, 95,127,225,218, 61,187, 2, 13, 15,207, 50, 41, 0, 5, 88,161, 3,214,109,222,107, 57,123,218,216,129,102,102,102, 87, - 11, 10, 10,246, 86, 65,211,181, 86,173, 90,171, 30, 63,126,108, 39,145, 72,192,178, 44, 10, 11, 11,225,228,228,132, 77,155, 54, - 89,126,243,205, 55,159,203,100,178,203, 10,133,226, 72, 85,140,121,205,154, 53, 59, 70, 70, 70,202,196, 98, 49,209,235,245, 68, -173, 86,195,213,213,149,238,218,181, 75, 50,110,220,184,250, 98,177,248,165, 90,173,126,106,148,185,250,245,158,160, 32,235, 66, - 40, 77, 84,206, 2, 0, 34,145, 46, 12,155,103,117,187, 32,235, 66,163,202,214, 5,254,138, 27,225, 95,114, 38,139,227,127,139, -163,163, 99,160,165,165,229,254,188,188,188, 75,169,169,169,195, 75,103, 54,120,223,143, 63, 39, 62,159,239, 65, 41,181, 40,253, -127,158, 94,175,143, 51,102,206,205,119, 97,227,217,170, 43,196,178, 97,160,108,125, 6, 0, 97,152, 7, 6,173, 98, 75, 86,204, -133, 35,239,165, 41,146,126, 14,208,250, 12,192, 18,134,121,200,234, 21,191,101, 70, 93, 56,193,229, 12,142, 15, 22,193,170, 19, - 2, 75, 2, 76,155, 49,234, 75,134,207,227,145, 69, 27,126, 29,112,231,250, 17,234, 88,163,254,171, 41, 55,154, 55,111,142,230, -205,155,147,165, 75,151,250,158, 63,127,222,119,215,174, 93,186,235,215,175,135, 3,216,250, 54, 77, 74,129,150, 29,165, 47,245, - 58,165,107,211,118, 82,149,123,227,181,187,154, 52,105,206,138,197, 98, 84,164,121,230,250,245,240,118,181,222,174, 89, 34, 12, -212,106,192, 63,227,220,208,149,132,117,153,157, 96,172,230,187,210,249,255,204, 92, 93, 50, 53, 53,245, 28, 57,114,228,179,209, -163, 71, 95,150,203,229, 20, 0, 20, 10,133,184,107,215,174,185, 61,122,244,200, 86, 40, 20, 88,183,110,157,235,170, 85,171,206, -152,153,153, 37, 23, 20, 20, 52,170, 74, 84, 12,192,156,110,221,186,205,250,250,235,175, 81,163, 70, 13,140, 27, 55, 14, 58,157, - 46,156, 16, 50, 27,192, 18, 99, 6,221,179,179,179,155,179, 98,197, 10,187, 98,157, 0,223,109,143, 69, 78, 81,201,128,162, 50, - 17,131,175,218, 74, 48,118,236, 56,243,219,183,111, 47,197, 27, 35, 72, 87,132,131,131,195,247,107,214,172,177,149, 72, 36,160, -148,162,168,168, 8,133,133,133, 40, 42, 42, 66,113,113, 49, 70,143, 30,109, 30, 17, 17,177, 2,192,145, 42,104,182, 90,187,118, -173, 76, 44, 22,227,204,153, 51,222,106,181,154,167,209,104, 96, 48, 24, 12,181,106,213,138,254,250,235,175,197,143, 31, 63,238, - 0,192, 40,131,229,152, 6, 65,190, 82,185,230,151, 31,190,177, 5,128,175,167,253,184, 6, 80,134, 80, 35,214, 57,166, 33, 24, - 0,103,176, 42,206,159, 60, 0, 61, 5, 2, 65, 47, 79, 79,207,160,103,207,158,221,215,235,245,127, 2,248,179,116,122,162,247, -209,110,227,228,228,244,125, 74, 74,202, 47,148,210, 29,255,150,107,106,103,103,247,231,129, 3, 7, 92,183,111,223,254,217,111, -191,253,118, 28,239, 49, 74, 62, 33, 68, 0, 32,180, 81,163, 70, 54,189,122,245, 18, 56, 56, 56, 64,161, 80, 32, 54, 54, 86,118, -246,236, 89, 91,137, 68,146,173, 86,171,111, 84,229, 94,217,120, 55, 53, 1,223,108, 79,104,171,182,205,250,245,238,105,106,111, -109, 14,165,198,128,103, 9,169, 53, 78, 30, 63,220,210, 41,224,147,235, 90,109,254,128,172,152,107, 69, 85,213,108,213,177, 75, -179,182,109,218,152,154, 91,152, 35,191, 88,139,231,241,201,110, 23,206, 28,105,238, 24,240,201,101,150,232, 6,167, 63, 58,173, -224,158, 58,142,170,240,151, 70,238,251, 34,233,219, 30, 20,200, 77,228,111, 21, 48, 55, 55, 71, 88, 88, 24, 22, 45, 90, 36, 0, -208,248,117, 83,245,159, 97, 19, 24, 0, 6,131,198,113,214, 87, 99, 33,226, 83,241, 39,157, 58, 16, 51, 51, 51,163, 52,121,239, -208, 4, 0,202, 8, 97,111,165,111, 27,226,173,108,153,254, 96,220,160, 7,151,190, 15,208,168,242, 4,111,106,202,100, 50,120, -121,121, 97,230,204,153,111, 75,231, 7,239, 18,250,191,208,164,148, 58,249,249,249, 21,174, 88,177,194,123,238,220,185,150, 42, -149, 74, 14,192,213,179, 78, 35, 23,134, 97, 92, 85, 42,149,217,156, 57,115,108,151, 46, 93,234,109,107,107,155, 71, 41,181,173, - 98, 58, 23,172, 89,179,102,246,161, 67,135,152,230,205,155,195,210,210, 18,173, 90,181,194,241,227,199,249, 63,253,244,211, 34, - 0,179,140, 73, 39,195, 48,205,155, 53,107, 70, 88,150, 34,183, 72,135, 11,139, 3,113,237,199, 96, 40, 52, 44,114,243, 10,160, - 82,169, 32,147,201,164,132, 16, 19, 99,207,157,101,217,198, 77,154, 52, 33, 64,201,200,239, 37, 75, 49, 10, 11, 75,254,106, 52, - 90, 8, 4, 2, 83, 66,136,184, 10,154, 46, 77,155, 54, 5, 0, 40,149, 74,126,155, 54,109, 72,235,214,173, 73, 97, 97, 33,191, -108, 26, 31,129, 64, 32, 34,132,240,141,209,212,200, 4,132,165,172,189, 92, 38,181,145,203,164, 54, 44,101,237, 1,192,152,117, - 26,153,128,252,157,249,147, 16, 98,203,227,241, 54,123,122,122, 62,225,241,120,219, 8, 33, 14,239,163, 73, 8, 9, 38,132, 44, -146,201,100,103,253,252,252, 18,229,114,249,121, 66,200, 18, 66, 72,104,117, 52, 9, 33, 34,153, 76,118,126,209,162, 69,251,238, -223,191,223,239,220,185,115, 30,143, 30, 61,234,189,116,233,210, 61, 38, 38, 38, 87, 8, 33,178,247,121, 54, 61, 60, 60, 54,221, -186,117, 43,184, 73,147, 38, 27, 43,202, 67, 85,209, 36,132,240, 8, 33, 13, 72,217,252, 56,255,128, 50,164, 60, 46, 46, 46, 78, -254,254,254,174, 98,177, 24,205,154, 53, 3,165, 52,236, 61, 53, 67, 71,141, 26,229, 48,105,210, 36,193,131, 7, 15,176,113,227, - 70, 28, 58,116, 8, 25, 25, 25,232,210,165,139,176,117,235,214, 14, 98,177, 56,180, 74,154,124,179, 61,227, 39, 76,236,248,205, -184, 17,166, 15, 95,106,177,229,236, 75, 28,188,145,138, 12,133, 8, 93,123, 15, 53,239,208,189,127, 7,145,216,124, 79, 85, 53, -167, 79,155,214,241,203,207, 63, 53,141, 76,101,113,248,102, 26,110, 70,231, 67, 47,176, 64,231,222,195, 45,235, 55,237,248, 9, - 31,130,173,255,132,123,244,177,107,254, 43, 34, 88,115, 54,210,220,249,163,201, 15,139,214,253, 58,139, 33,132,186,212,238, 16, -233,225,213,184,152,101, 89, 40,149,202,178, 23, 13,148, 74, 37, 18, 18, 18,112,235,214, 45,152,155,155, 87,120,160,147,177, 20, - 11,191,250,207,225,242,242,243,225,236,226, 1,153, 76, 86,169,230,137, 10,170,243,248,180, 36, 26, 50,162, 79, 15,254,203,212, - 84,254,245,123, 23, 2,247,174,220, 21,232, 90,171, 93, 84,253,176,169,143, 77,204,107, 40, 31, 60,120,128, 27, 55,110, 32, 55, - 55, 23,141, 26, 53,250,104,110, 30, 33, 68,183,108,217,178,123, 41, 41, 41,228,234,213,171,245,231,175,216,229,241,168,160, 38, - 47,179,136, 10,108, 77, 94,122,248,201,158, 26,242,243,243,227, 38, 79,158,124,193,193,193, 65, 61,118,236,216,150, 70,234, 74, - 0,248,244,233,211,103,250,152, 49, 99, 16, 27, 27,139, 17, 35, 70, 40,111,223,190,157,221,164, 73, 19,235,223,126,251, 77, 58, -105,210, 36, 92,186,116,105, 14, 33,228, 0,128, 56, 74,233, 59,231, 82, 99, 89, 86, 36,149, 74,129,130,146, 15, 85,173,190,108, -110, 90,160,184,184, 24,124,228, 65, 36, 18, 49, 0,108, 1, 24,251,229, 41, 20,139,197,175,204, 85, 82, 70, 33, 18, 50,138, 80, - 88,164,134, 82,169,131, 70, 5,136,205,236,121, 64,162, 53, 0, 99, 27,167,243,196, 98, 49,244,122, 61,180, 90, 45, 84, 42, 21, - 84, 42, 21,212,106, 53,242,243,243, 81, 88, 88, 8, 62,159, 47, 3, 96, 6, 32,167, 82, 49,145, 84,207, 99,132,139,190, 93,184, -102, 46, 0,240, 24,225, 34, 19,168, 88, 99,214,241, 68, 82,253,223,152,175,196,182,182,182, 23,246,237,219,231,231,229,229,133, -184,184, 56,223,190,125,251,134, 16, 66, 26, 80, 74, 21, 85,212,146, 49, 12,243,195,176, 97,195,198, 12, 28, 56,144,212,174, 93, - 27,124, 62, 31,122,189,222, 37, 54, 54,182,213,239,191,255, 62,141,207,231,255,102, 48, 24, 38, 27,219,174,143, 16,194,136, 68, -162,189, 27, 54,108,104, 17, 18, 18,130,109,219,182,225,246,237,219,108,112,112, 48, 51,100,200, 16,184,185,185,133, 12, 25, 50, -228, 32, 33,164,115,117, 34, 89,132, 16,183, 65,131, 6,185,242,120, 60, 52,105,210, 68,120,253,250,245,134, 0,174,191,231, 53, - 53,113,113,113,185, 20, 22, 22,214,224,236,217,179,247, 8, 33, 97, 85,105,199,232,228,228,212,221,222,222,126,169,169,169,169, -165,177,251, 20, 21, 21, 41,210,211,211,167, 36, 39, 39, 27, 53, 31, 41,165,180,113, 64, 64, 0,146,147,147,225,233,233, 9,161, - 80, 24,234,236,236, 60,146, 82,218,145,101,217,153, 85,105, 98, 64, 8,113, 10, 13, 13,181, 9, 11, 11, 35, 75,150, 44, 1, 0, - 8, 4, 2, 24, 12, 6, 48, 12, 3,129, 64, 0, 95, 95, 95,242,226,197, 11, 43, 66,136,147, 49,213,133, 54,158,173,186, 54,105, -211,177, 89,139,144,122,204, 79,251,159,193,192, 26,192, 35,122,240, 9, 11, 86, 39,134, 88,200, 67,109,255, 32, 94,116,196,195, - 16, 27,239,118, 93,179, 98,206, 28, 49, 70,179, 99,215,110,205,253,124,106, 51, 43, 15, 62, 71, 94,242, 19, 67,114,212,229, 44, -134,199,192, 47,176,181, 77,237, 58, 13,120, 13, 66,194, 4, 41,113, 17,173,172,188, 90,182,205,121,118,137, 51, 21, 28, 85, 55, - 88,132, 16, 74, 41,125,245,101, 53,123, 29,157,109, 99, 73,220, 35, 31, 63,100, 18,211, 52,197, 15, 31, 62,132,181,181, 53,236, -236,236, 96,102,102,134,232,232,104,156, 61,123, 22, 49, 49, 49,160,148,162, 65,131, 6, 85, 58,112,122, 90, 26,178,115, 10,223, - 91,243, 68, 44,197,130,209, 37,201,174,225,232,136, 26,142,142,252,172,220, 60,220,120,248,200,239,200,111,109,125,210,153,145, - 91,148, 74,229,171,237,117,186,143,175,214,197,222,222, 94,255,213, 87, 95,231,124,185, 54,174,214,128,214, 78,188,238,161, 14, - 56,120, 61,149,183,231, 34,143,206,254,162, 94,230,179,103, 79,141, 62,105,145, 72,244,125,167, 78,157,190,161,148, 10,198,143, - 31, 15, 0, 24, 58,116,104,193,205,155, 55,107, 83, 74, 51, 8, 33, 78, 95,124,241,197,211, 11, 23, 46,200, 38, 78,156,200,211, -235,245,145,124, 62,159, 18, 66,230, 83, 74,231,190, 53,147,241,249,247, 31, 60,120,224, 14, 19, 55,216,152,242,208, 97,214, 61, - 0,128,137, 24,200, 76, 75,194,173, 71, 23, 97,109,109,109,222,188,121,243, 40, 47, 47, 47,117,106,106,234,248,226,226,226,173, - 21,102, 92, 62, 63, 34, 60, 60,220,197,197,197,165,196, 96,101, 41,177,229, 6, 3,133, 90, 10, 64, 10,194,202, 97,102,231,110, - 90, 91, 91,240,192,214,214, 86,171,209,104,166, 23, 20, 20, 84, 88,213,195,227,241, 50, 30, 63,126,108,234,234,234, 10, 0,186, -131, 7, 15,242, 53, 26, 13, 40,165,134, 99,199,142,117, 76, 76, 76,108,224,225,225,193,184,184,184, 76,247,242,242, 82, 38, 39, - 39,143, 80, 42,149,239,172, 66, 57, 57,206, 83,219,114,238,197,181,121,113,137,191, 3,128,115,136, 95,206,209,185, 13, 53, 45, -231, 22, 85,186,238,228, 56, 79, 45,198,254,109,237, 4,135,125,251,237,183,126, 86, 86, 86, 24, 53,106, 20,230,205,155,135,217, -179,103,123,141, 26, 53,234, 75, 0,203,171,240,146,149, 58, 56, 56,220, 89,185,114,165,111,211,166, 77,113,252,248,113,236,222, -189, 27, 47, 94,188,208,123,120,120,240, 67, 66, 66, 48,103,206, 28,116,232,208, 97,196,216,177, 99, 91, 18, 66, 26, 26,105, 58, - 62,159, 51,103, 78,247,102,205,154,225,179,207, 62, 83, 95,188,120,177, 31,128,211,103,206,156,105,125,233,210,165,253, 59,119, -238,148, 46, 90,180,168,237,164, 73,147, 70, 1, 88, 93,141,243,239,209,162, 69, 11, 0, 64,179,102,205,176,116,233,210, 14,239, - 99,176, 8, 33, 34,107,107,235, 99,219,182,109,107,224,237,237,141,193,131, 7, 55,236,215,175,223, 49, 66, 72, 59, 74,169, 81, -243, 70, 58, 58, 58,254,176, 97,195, 6, 79,169, 84,106,244,113, 53, 26,141,213,200,145, 35,151, 0, 48,202, 96,177, 44,219, 56, - 32, 32, 0, 7, 15, 30,196,200,145, 35,225,231,231, 87,175, 65,131, 6,235, 7, 13, 26,132, 81,163, 70,181,177,181,181,181, 47, -157, 92,188,242, 23, 11,159,239,209,165, 75, 23,193,159,127,254, 9, 0,104,209,162, 5,218,182,109,139,199,143, 31,227,234,213, -171,224,241,120,144,203,229,104,218,180,169, 40, 37, 37,197, 3, 64,165, 6,139, 17,203,134,117,239,210,217,244,240,205, 84, 24, - 88, 61,130, 60,205, 16,226,107,135,232,164, 2,132, 63, 73,130, 65, 35,132,153,149, 53, 66, 91,182,183, 74, 75,126, 49, 12,198, - 52, 15, 16,203,134,245,234,254,137,201,225, 27, 41,200, 75,137,162,207,110, 31, 56,175, 83, 21,143, 0,128,187,231,246,172,119, -176,150,182,171, 29, 24,196, 11,107,215,205,242,207,221,105,195, 0,112, 6,139,227,253, 34, 88,101,100,231, 65,105,237,224,135, -196,180,251, 37,255,207,206, 70,118,118, 54,106,214,172,137, 85,171, 86,189,182,173, 74,165,170, 86, 2,254, 27,154, 54,150, 22, -232,214,170, 37,239,113,244, 58,158,146, 85,126, 16,205,127, 42,165,147,150, 50, 9, 89, 58,139,204,124,173,176,127, 43, 87, 42, -224, 49, 24,208,170, 6,249,229, 72,130, 48,163, 88, 96,193, 48, 76, 2,203, 86,222,145,144, 16, 34,232,222,189,251, 55,123,247, -238, 21, 68, 69, 69,161, 86,173, 90,208,106,181,184,121,243,102, 18,165, 52,163,244,120, 41, 60, 30, 47,133,101, 89,175,250,245, -235, 99,241,226,197,240,245,245, 37,157, 59,119,158, 86,106,178,254,114,160,148,148,148, 69, 95,127,253,117,139, 95,183,236,177, - 30,220,152,160,176, 80, 13,133, 66,129,232,199,119, 80,156, 94,140,245,235, 55, 64, 38,147, 17, 0,194,180,180, 52,225,164, 73, - 19, 55,186,184,184,116, 73, 74, 74,234,245,174,180,166,164,164, 44, 28, 59,118,108,200,246,237,219, 45, 75,218, 93, 41, 81,168, - 20,227,214,207, 37, 17,202,144, 73,183,241,219,175, 27,153,186,238,114,235,194,194, 66,140, 24, 49, 98,165,163,163, 99,211,212, -212,212,145,239,210, 76, 77, 77,189, 50, 98,196, 8,231,223,127,255, 93,226,229,229, 21,147,159,159,143,156,156, 28,102,231,206, -157, 99, 29, 29, 29,205, 15, 30, 60, 68,228,114, 57, 0,240,226,227,227,133, 95,127,253,213, 94, 7, 7,135,157,105,105,105,159, -189,235,222, 0, 80, 19,130, 84, 39,167,154,158,138, 27,204, 92, 39, 39,213,213,139,115,146,183, 19,130,212,146,109, 64, 29, 55, - 56, 14,122,185, 77,220, 76,173,102, 87,164,165, 37,196, 80, 10,138, 57,127, 95, 39, 12, 27, 27,155,177,221,187,119,199,146, 37, - 75,112,228,200,145, 73, 86, 86, 86, 63,207,155, 55, 15, 78, 78, 78, 95, 19, 66, 86, 84, 97,178,219, 31,151, 47, 95,238,235,235, -235,139,161, 67,135,106,206,158, 61,251, 45,128,131, 0, 18,174, 92,185, 82, 99,235,214,173, 93,247,238,221,187,100,229,202,149, -146,213,171, 87,123,246,238,221,123, 5,128, 47,140,248,160,152, 56,112,224, 64, 44, 91,182, 12, 23, 47, 94,236, 77, 41, 61, 94, -246,189, 69, 8,233,186,104,209,162,115,179,102,205,194,242,229,203,199, 87,213, 96, 17, 66, 76,252,252,252,190,235,216,177, 35, -174, 92,185,130,230,205,155, 35, 52, 52,116, 18, 33,100, 21,165, 52,171, 26,230,138, 49, 49, 49,217,187,101,203,150,230,238,238, -238, 88,184,112, 33,190,249,230, 27,108,218,180,169,249,224,193,131,247, 18, 66,122, 25,211,203,215,196,196,196, 68, 42,149, 98, -201,146, 37,244,229,203,151,185, 70, 24, 50,203,239,190,251,142,152, 87, 86,181,240,159, 8,153, 84, 44, 22, 55,241,241,241,193, - 79, 63,253,132, 43, 87,174, 96,220,184,113,240,241,241, 65, 82, 82, 18,186,117,235, 38,123,250,244,105, 31, 0, 91,140, 44,151, -204,173,173,173,145,145,145, 1,129, 64,128,166, 77,155,226,224,193,131, 80,171,213,176,179,179, 67, 94, 94,222,171,218, 4, 62, -159,111,110,100,105, 23, 96, 99,101,142,140,136,100,240,161, 71, 96,109, 27, 92,120,156, 13,173,142,133,157,181, 5,210, 50,210, -209, 56,192, 5, 26, 77, 13, 80,202, 26, 53, 19,136,136,199, 4,138, 37, 82,228, 20,102, 33,249,201,197,108,173, 65, 61, 50,239, -197,213, 68, 0,176,170,213, 98,228,221,171,103,238,246,253,164,133, 93, 81,177, 43, 8,101, 27,129,131,163, 10, 84, 58,208,232, -219, 94,204,229, 35, 66,101,104,181,218,247, 74,200,127, 67,243,109,252, 55, 52,255, 1, 38,139,117,182,228,231,203, 37,140,254, - 76,120,134, 65,167, 55,224,212,221, 52,131, 76, 76,244,150, 98, 77, 1,203,178,148, 16, 66,141,208,209,157, 58,117,106,219,184, -113,227,240,243,207, 63,227,233,211,167, 16, 10,133, 8, 8, 8,112, 44,107, 31, 69, 8, 49, 15, 12, 12,180, 99, 24, 6,209,209, -209,248,233,167,159,240,249,231,159,211,235,215,175,111,122,215,139,130, 82,122, 63, 53, 53,117,195,148,241, 35,243, 24, 69, 34, -228, 52, 11,218,156,167, 96,149,153,248,118,206, 34,196,101,179,184,247,162, 16,247, 94, 20, 34, 75, 35,199, 79,191,108,230,249, -251,251,119, 21, 8, 4, 29, 42, 72,235,205,212,212,212,109, 19, 39, 78,204,203,200,200,120,101,156,181,122, 22, 90,253,235,201, - 48, 53, 53,197,250,245,235, 45, 92, 93, 93,251, 8, 4,130, 86, 21,104, 38,167,164,164, 60, 26, 51,102,140, 58, 53, 53, 21,249, -249,249, 56,125,250,116, 59, 23, 23, 23,243,185,139,150,147,184,108,250, 42,157, 69,196, 26,155,119,254,201,171, 93,187,246,167, - 2,129, 32,180,226,151,151,179,167,159, 95,173,125, 55,111,222,252,204,211,211,115, 76,153,177,162, 20, 20, 0, 60, 60, 60, 70, -133,135,135,127,222,160, 65,157,125,246,246, 14, 62,127,103, 94, 34,132,180,234,223,191,191, 15,203,178,216,183,111,223, 35, 74, -233,242, 3, 7, 14,220, 81,171,213, 24, 48, 96,128, 7,128,142, 70,234, 4,127,250,233,167, 99,154, 55,111,142, 9, 19, 38,104, -207,158, 61, 27, 72, 41,253,153, 82, 26, 79, 75, 72,160,148,174,186,116,233, 82,253,177, 99,199,170, 27, 53,106,132,207, 62,251, -236,115, 66, 72,243, 74,116,155, 12, 28, 56,208,151,101, 89,236,217,179,231, 97, 57,115, 85,118, 15,207,239,223,191,255,166, 70, -163,193,160, 65,131,106, 18, 66, 90, 87,225,220,133, 98,177,120,223,130, 5, 11, 44,146,147,147, 49,100,200, 16,117,116,116, 52, -230,206,157, 43, 53, 55, 55, 63, 94, 81, 27,193,119, 6, 72,196,226, 95,215,173, 91,215,189,110,221,186, 24, 61,122,180,102,237, -218,181,227,198,140, 25,163, 9, 12, 12,196,154, 53,107,186,139, 68,162, 95,171, 20,249, 79, 79,207,187,120,241,162,117,101, 75, - 90, 90, 90,186,145,209,111,153,151,151,215,141,218,181,107, 23,248,249,249, 5,233,245,122, 60,125,250,244,249, 31,127,252,193, -250,248,248, 96,235,214,173, 88,191,126, 61,218,180,105, 3,134, 97,250, 84, 37,173,197,197,197,144, 72, 36, 16, 10,133, 8, 15, - 15,135, 90,173,134, 76, 38,131, 68, 34, 1,143,199,131,133,133, 5, 76, 77, 77, 1,128, 26,119,127, 64, 11, 20, 58, 8, 4, 12, -248, 12,139,168,132,124,104,117, 44, 36, 66, 30, 4,124, 2, 80, 22, 22,114, 1, 36, 34, 30, 24, 66, 88, 35, 53,145, 95,172,133, - 72,200, 64, 32, 20, 17, 70,111,120, 21, 34,100,248, 6,169, 84, 42, 34, 54,102, 98, 72,132,220,152,220, 28, 31, 56,130, 5, 0, - 6,195, 95,123,233,190, 45, 10,164,209,104,222, 43, 33,255, 13,205,119,132,205, 63,170, 27, 88, 80, 80,192,191,113,227,134,169, - 80, 40, 20,119,111, 16,146,181,244,247,167,182,243,118,198, 64,204, 7,233,228, 79,211, 79, 28, 63, 34, 42, 44, 44,180,241,241, -241,201, 54,242, 62,140, 32,132, 44, 4, 80,135,207,231, 31,221,178,101, 11,217,177, 99,135,229,192,129, 3, 99, 9, 33,201,254, -254,254,110, 91,182,108, 49, 3,128, 85,171, 86,209,189,123,247,118, 0, 16, 65, 41, 77,171, 72, 55, 53, 53,117,150, 88, 44,190, - 30, 29, 29,189, 74, 32, 16, 88,152,153,153, 89, 94,186,116,137,164,231,107,241,221,246, 23,175,122, 22,202,197, 60,204,232,101, -135, 97,195, 62,231, 71, 70, 70,254, 8,224,212,187, 52,147,147,147, 39,201,100,178, 75,143, 30, 61, 90,110,234, 92,207,202, 38, -116,146, 89,235, 25, 37,213,143, 14,150, 34, 48,165,101, 98, 94, 94, 30,178,178,178, 48,105,210, 36,139,201,147, 39, 79, 5,112, -161,130,116,158, 22,139,197, 9, 17, 17, 17,237,249,124,190,216,196,196,164,193,141, 27, 55,200,203, 60, 29,102,108,125,142, 66, - 85, 73,109,171,169, 68,128,121, 3, 93, 48,118,236, 88,126,108,108,236, 15, 0,154,189, 77,207,217,217,217,203,207,207,111,223, -174, 93,187,252, 86,172, 88,145,243,236,217,179, 98, 39, 39,167,121,111,108,166, 94,188,120,113,246,246,237,219,189,135, 12, 25, -178,207,193,193,161,223,123, 12,169,241, 94,152,153,153, 45, 25, 57,114, 36,246,238,221,139,220,220,220, 21,165,121,108,249,174, - 93,187,246,140, 24, 49, 2,219,183,111, 95, 66, 8, 57,105, 68, 20,171,211,128, 1, 3,112,226,196, 9,156, 59,119,238, 59, 74, -105,228, 59, 76,237, 83, 66,200,180, 67,135, 14,173, 28, 56,112, 32, 54,111,222,220, 17, 64, 69, 3,207,182,235,208,161, 3,142, - 31, 63,142,236,236,236, 53,111,219, 32, 47, 47,111,237,225,195,135, 27,119,232,208, 1,139, 23, 47,110, 7,224,188, 17,230,202, -215,220,220,124,203,202,149, 43,131,235,214,173,139, 79, 63,253, 84,165,213,106, 59,126,243,205, 55, 71,118,239,222,109,186,109, -219,182,160, 47,191,252,242, 22, 33,100,184,177,131,216,242,120,188, 69,171, 87,175,254, 34, 44, 44, 12,147, 38, 77,210,159, 58, -117,170, 27,165,244, 52, 33, 36,118,234,212,169,199,126,250,233, 39,222,178,101,203,190,224,241,120,153, 6,131,225,219,191,229, - 11,155, 97, 22,204,159, 63,191,113,139, 22, 45,144,144,144,128,123,247,238, 65,175,215,111,191,123,247,238,229, 22, 45, 90, 44, -208,106,181, 71, 36, 18,201, 80, 19, 19, 19,127,127,127,255,214,246,246,246,178,244,244,116,133, 17,215, 51, 47, 54, 54, 86,110, -103,103, 7,129, 64,128,135, 15, 31,194,206,174,100,202,215,140,140, 12, 4, 4, 4,128,199,227, 33, 47, 47, 15, 0,242,141, 51, - 67,204,163,216,248,148,154, 86,166,114,192, 32,193,253,232, 36,216,218, 88,194, 64, 24,164,165,165,162,129,143, 11, 8, 33,200, -203, 78, 3, 33,196,168,185,116, 13,148, 13,127,153,146,225,108,109, 42, 70,221,198,237,173,111,156,204,220, 97, 94,171,217,151, -124, 30,225,137, 37,102, 27,190,248,236, 51, 27,150,165,200,203, 78, 7,159, 97,110,115,150,129,227,131, 26, 44,150,101, 33,149, - 74, 95,139, 48,189, 25, 5,146, 74,165, 80,171,213, 85, 58,176, 84, 42,133, 86,143, 15,170,105,204, 49, 63,180,230,223,137, 94, -175, 55,157, 60,121,114, 72, 72, 72, 72,114,155, 54,109,226,188,189,173, 18,187, 52,150,218,172,220,116,160, 65,231,150,117,239, -229,229,100,100,189, 48, 51, 83,199,199,199,219,253,246,219,111, 33, 58,157, 78,102,100, 68,236, 37,128,151,132,144,181, 29, 59, -118,252,170,111,223,190,136,140,140,180, 83, 40, 20,118, 50, 89,137,196,142, 29, 59,176,119,239,222,159, 41,165, 70, 15,188,169, - 86,171, 79, 2,240, 36,132, 88,212,168, 81, 35,221,202,202, 74,152, 90, 84,252,170,103,161,144,207,160,233, 55,119,144,155, 87, - 0, 27, 27, 27,152,154,154,122, 84,166, 89, 58,206,213, 17,175,118, 83,235, 41, 31,109,184,184,117,203, 22,115, 0,224, 49, 4, -182,230, 66,228,229,229, 33, 51, 51, 19, 89, 89, 89, 96, 24, 6,122,189,222,207,136,116, 62, 5,240,148, 16,226,212,186,117,235, - 5,166,166,166, 96,115,138,145, 91,164,125,173, 10,178,168, 72, 1,119,119,119,152,154,154,190,181, 58,194,202,202,202, 84, 44, - 22,111,221,184,113,163,175,169,169, 41,111,196,136, 17, 22, 35, 70,140,104,246, 46, 51, 38,147,201,120,155, 55,111,174,221,160, - 65,131, 45,238,238,238,237,226,227,227,243,255, 87,121,169,116,200,131, 81, 83,166, 76, 9,146, 72, 36,248,229,151, 95, 94, 0, -216, 89,250,243,190,181,107,215,206, 30, 56,112,160,207,184,113,227,252,103,205,154, 53,169,180,170,240,157, 99, 36, 9,133,194, - 64, 63, 63, 63, 28, 56,112, 0, 0, 14, 84,114,248,253,215,175, 95, 95,217,165, 75, 23, 72, 36,146,224, 74,182,245,112,117,117, -197,161, 67,135, 0,224,254, 59,182,185, 31, 29, 29,141, 94,189,122,129, 16,226, 97,196,185,119,111,223,190,253,254,197,139, 23, -243, 77, 77, 77,241,197, 23, 95,104,110,221,186,213,153, 82,122,153, 16,210,106,208,160, 65,151,118,238,220, 41,191,116,233,146, -239,247,223,127,127,157,199,227, 45, 50, 24, 12,179, 42,209,252,124,225,194,133, 51,122,244,232,129,121,243,230,209,223,127,255, -253, 83, 74,233,233,210,231,235, 20, 33,100,136,165,165,229,206,153, 51,103,146,252,252,252, 25,132,144, 36, 74,233,186, 10,242, -121,190,193, 96,112, 80, 40, 20, 70,125, 33, 26,187,189,181,181,117,167, 22, 45, 90,224,199, 31,127,196,184,113,227,176,117,235, - 86, 10,224,104,106,106,234, 67, 0, 45, 74, 34,176, 78,166,225,225,225,254,205,155, 55, 23, 62,122,244,232, 19, 0,191, 27, 81, - 54,197, 95,184,112,193,174,115,231,206, 66,153, 76, 6,131,193,128,236,236,108,168, 84, 42, 4, 4, 4,160,113,227,198,200,200, -200,192,209,163, 71,181,121,121,121,241, 70,149,119,154,226,109,103,142,253,217,170,235,128,145,230, 82, 33, 15, 6,157, 8,233, -233,153, 40, 52,232, 17,232,231,134,230, 13,106, 32, 33, 93,137, 83, 71,255,204, 45, 44, 84,108, 51, 70, 83,167, 86,108, 57,123, -242, 72,203,230,157, 6,153,203,125,252,225,225, 56,174,193,221,235,103,207, 72, 68, 2, 50,104, 96, 63,139,166, 13,189,240,240, - 69, 1, 78, 28, 61,144,155, 95, 80,176, 5, 28, 28,213, 49, 88,229, 27,184,151, 35, 99,210,164, 73,118,147, 39, 79,134,153,153, - 25,178,179,179,161,211,233, 94, 69,155,196, 98, 49, 44, 44, 44,144,157,157,141, 61,123,246, 0, 64, 70,197, 95,116,162,212,133, -107, 86,187, 18,158, 92, 35,150,202,168,149,236,253, 53, 1, 64,163,227,103,172,219,243,135, 85,167, 22,161,252, 26,142,142,111, - 11,211, 87, 89,243,255, 3, 90,173,246,116, 92, 92, 92,240,128, 1, 3, 50, 93, 93, 93,149, 42,149, 10, 74,165,178,240,232,238, -149,181,156,205, 70,191, 96, 24,134,154,154,154,178,118,118,118,249,231,206,157,179,211,235,245, 23,171,120,136, 73,253,250,245, - 99,206,158, 61, 59,106,204,152, 49,196,203,203, 11,225,225,225,248,229,151, 95,232,182,109,219, 86, 2,152, 94,205,164, 23,169, -213,234,215, 34, 32,229,123, 22, 22, 21, 21, 65,163, 76,135,174, 10, 61, 18, 98,207,254, 24, 93,179,102, 77,157,191,219,127,134, - 19,201,205,205, 69,102, 86,214, 43,131,149,153,153, 9, 0, 85, 9, 97, 22,252, 53,157,255,169,121, 40, 46, 46,134, 74,145, 6, -131,193,240, 86,205,156,156,156, 66, 39, 39,167,213,171, 86,173,250,105,193,130, 5,118,203,151, 47,207,137,138,138, 42, 96, 24, - 70,245,198, 71,140,196,211,211,211,116,217,178,101,246,171, 86,173,202, 97, 89,118,245,255,216, 92,245,168, 91,183,238,214, 78, -157, 58,153,142, 25, 51, 6,171, 86,173, 66,106,106,234,116, 74,169,190,180,108, 96, 9, 33, 83,215,172, 89,115,116,218,180,105, -208,106,181,203,142, 31, 63, 62,143, 16, 50,138, 82,186,243,109,154,182,182,182, 46,124, 62, 31,247,238,221, 43,160,148, 62,175, -196,208,167,121,123,123,167, 19, 66,236, 29, 29, 29,107, 85,180,173,149,149,149,167,169,169, 41,146,147,147, 1, 32,238, 29,155, -197,167,164,164, 80,145, 72, 68,156,156,156,188, 42, 59,127, 75, 75,203,169, 27, 55,110,228, 95,184,112, 1,115,230,204, 73, 74, - 72, 72, 24, 68, 41,189, 82,154,182,123,132,144,230,173, 90,181,218, 61,109,218, 52,239, 31,126,248,129, 68, 71, 71,143,198, 59, -134, 40, 41,195,205,205,109,212,231,159,127,142,213,171, 87, 99,195,134, 13,163, 41,165,251,222, 56,231,221,132, 16, 75,107,107, -235,213, 35, 71,142,196,150, 45, 91, 6, 1, 88, 87, 65,180,118, 90,255,254,253,103,231,228,228, 44, 50,230,158, 26,179,189,179, -179,115,171,214,173, 91,123,170, 84, 42,236,219,183,239,249,254,253,251,115, 13, 6,195,158, 82,115, 85, 62,127, 28, 60,121,242, -228,236,169, 83,167,226,194,133, 11, 91,156,156,156,120, 41, 41, 41,187, 43,185,167, 41, 18,137, 36,235,225,195,135, 14,190,190, -190,140,163,163, 35, 26, 53,106, 4, 11, 11, 11,240,120, 60,100,100,100,224,242,229,203,108,108,108,108,150,177, 3,142,102,197, - 92, 56,226, 80,183,243,181,123,183, 46,183,247,111,216, 84,224,108, 99,133, 80,127,103, 88,152, 8, 65, 0, 36,100, 40,113,254, -252, 25, 93, 92,220,243, 27,198,244, 32, 44,211,116,170,247,201,117, 11,187, 26,237,235, 52,104,202,175,229, 83, 27,237, 91,212, -183,180,148, 11,193, 82,138,135, 47,242,113,230,244, 73, 93, 74, 82,226, 5,174, 7, 33,199,135,142, 96,205,221,176, 97, 67,211, - 77,155, 54,117,153, 52,105,146,233,208,161, 67, 33,149, 74, 81, 92, 92, 12, 87, 87, 87,232,245,122, 28, 63,126, 28,247,238,221, - 43,100, 89,246, 40,128,107,111, 60,152, 1,229,199,173,154,177, 74, 81,163,100,240,202,226,166,243, 54,212,251, 32,154, 0,112, -253,133,222,217, 41, 53,107,110,118,238,241,137,110,206,142,194, 14,205, 26,243,109, 44, 75,122, 51, 27,169,217,246, 67,143,233, -241,191,208,212,235,245, 95, 16, 66,252,167, 78,157,186,212,217,217,217,105,222,188,121, 47,235,212,169,163, 44, 40, 40,160, 26, -141,134,205,202,202,146,237,219,183,207, 35, 59, 59,187, 80,167,211, 13,161,148, 62,172, 74, 58, 41,165, 90, 0, 99, 8, 33,135, -243,243,243, 79,125,243,205, 55,248,254,251,239,113,228,200,145,230,148,210,107,213, 61,119, 74,169,222,195,195, 35,239,254,253, -251,246, 34,235,218,176,183, 16,162,227,119, 37,193, 8, 83, 49,129,178,184, 16, 81,143, 31,162,160,160,224,110, 21, 52, 53,206, -206,206,249,233,233,233, 54,246,246,246, 37,230, 42, 51,243,149,185,202,201,201, 65,118,118, 54, 45,127,239,141,208, 44,246,244, -244, 84, 68, 69, 69,137,120, 50, 87, 56, 88,138, 81, 82, 5, 73, 97,107,202, 71,113,113, 33,158,220,188,129,252,252,252,139,239, -210, 76, 73, 73,217,227,228,228, 4, 0, 63,205,158, 61,219,166, 99,199,142,207,110,223,190,221,178,252,113, 2, 3, 3, 15,206, -155, 55,239,147,239,191,255, 62,107,235,214,173,211, 82, 83, 83,119,252, 47,243,146,181,181,245,228, 99,199,142,153,106,181, 90, -172, 90,181, 10, 63,255,252,243, 38, 74,233, 31,111, 92,139, 99, 60, 30,111, 13,195, 48, 95,125,253,245,215, 24, 57,114,164, 44, - 40, 40,104, 82,185, 40,215,107,154,201,201,201,179, 2, 3, 3,103,103,100,100, 24,101, 8,158, 62,125,250,101, 96, 96,224,172, -140,140,140,165, 21,157,187, 92, 46,151, 27, 12, 6,196,197,197,229, 82, 74,243,223,113,223, 84,181,107,215, 78, 54, 24, 12, 46, - 50,153,204,170,178,252,153,155,155,187, 40, 40, 40,104,110,122,122,250,105, 0, 11,223, 28,114,132, 82,250,128, 16,226, 63,126, -252,248,177, 75,150, 44,233,149,150,150,182,167, 50,205,132,132,132, 69,173, 90,181,250, 46, 38, 38,102, 43,165,116,195, 59,210, -249, 11, 33, 68,187, 99,199,142,209,113,113,113,139, 43,210, 76, 73, 73, 57, 10,224,168,177,247,247, 93,219,151,215,100, 24,102, -234,140, 25, 51,152,157, 59,119, 2,192,178,164,164,164, 13,239, 48,107, 15,157,157,157,183, 5, 5, 5, 13, 93,183,110,157,164, - 77,155, 54, 35, 1,236,174, 44,127,170,213,234,155,215,175, 95,111, 28, 31, 31,111,211,170, 85, 43, 33, 0, 20, 20, 20, 32, 47, - 47, 15, 71,143, 30,213,198,198,198,102, 21, 23, 23,223,172, 74, 25,162,215, 20, 12,188,126,254,208,238,248,167,143, 67,195, 58, -118,183,212,104, 93, 32,206,230, 33, 47, 59, 13, 39,143,254,153, 27, 23,247,252,134, 66,145, 55,176, 42,154, 90,117,254,128, 27, - 23, 14,239, 73,138,139,106,220,162, 85,103, 75,149,198, 13, 98, 33,131,236,244,100,156, 60,118, 40, 39, 46,238,197, 21,149, 78, -253,217,223, 85,206,255,155, 52, 63, 58,104, 89,107,219, 10, 22, 0, 34, 0,159,152,154,154,174,154, 51,103,206,134, 91,183,110, -109,232,210,165,203, 6,145, 72,180, 10,192, 39, 0, 68,239,216, 47,224,127,169,217,177, 17, 76, 63,239,198,108, 94, 48,154,175, - 61,184,220, 71, 55,127, 20,168,145,154,109,141,185, 14, 85, 89,254,215,154, 0,154, 9, 4,130, 27,117,235,214,189, 96,106,106, -154,233,238,238,126, 69, 32, 16,220, 6,208,226,125,211, 9,192,166,127,255,254,108, 97, 97, 33,237,215,175, 31, 5, 96,254,190, -154, 98,177,184,117, 88, 88,152,238,101,106, 46,189,242, 32,145, 30,189, 20, 73,119, 29,185, 65, 55,236, 62, 69,151,175,217, 76, -235,213,171,167, 1,224, 86, 21, 77,145, 72,212, 49, 44, 44, 44, 47, 43, 43,139, 70, 71, 71,211,203,151, 47,211,253,251,247,211, - 13, 27, 54,208,181,107,215, 82, 39, 39,167,108, 0, 78, 85,209,148, 74,165,221, 59,118,236,168, 79,206, 44,162, 55, 35,211,232, -217, 91,207,233,193,115, 15,233,158,163, 55,232,166, 29,127, 80, 95, 95, 95, 21, 0,251,202, 52, 29, 29, 29,251,247,235,215,239, -153,183,183,247,250, 55,127,243,242,242, 90,211,175, 95,191, 4, 39, 39,167, 33,127, 71, 94, 2,208,209,217,217, 57, 90, 40, 20, - 30, 3, 48,164,146,253, 6,240,249,252, 35, 14, 14, 14,119, 0,244,252, 95,231,121, 0, 93,236,236,236,110, 2,232, 86,201,126, -101,219,245,248, 24,159,247, 15,161,233,228,228,212,218,213,213,245,178,147,147,211,204,202,246,243,243,243, 19, 58, 56, 56, 44, -112,118,118, 62,238,232,232,216,166, 42,233, 4,224,100, 98, 98,210,204,196,196,164,171,137,137, 73, 87, 11, 11,139,102,229,159, -195,234,156,187,117,237,182, 93,107, 52,236,118,208,181,254, 39, 9, 53, 26,116, 73,240, 8,236,126,208,186,118,219,174,239,171, -233, 22,216,253, 80,141, 6, 93, 94,214,104,208, 53,190,102,112,247,131, 54, 62,109, 59,125,108,247,253,159,172,249,177, 45, 70, -111,216,167,164,229,138, 9,128, 1, 12,195,252, 2, 96, 0, 0,147, 74,110, 64,128, 17, 55,233,131,107,118,108, 9,231, 49,125, -120,199,167,127, 38,200, 52, 82,243,163,201,208, 0,186,243,249,252,235, 0,186,127,200,116,154,153,153,109,236,219,183,175, 65, - 32, 16,172,254, 80,154,214,214,214, 63,133,134,134,106, 87,174, 92, 73, 15, 28, 56, 64, 55,108,216, 64,199,142, 29, 75, 3, 2, - 2,212, 86, 86, 86,159, 85, 71,211,193,193, 97, 97,221,186,117,115,118,236,216, 65,247,236,217, 67, 87,175, 94, 77,231,206,157, -203,214,168, 81, 35,211,202,202,170, 91,117, 52,237,236,236,126,109,214,172,153,246,215, 95,127,165,103,206,156,161,187,118,237, -162,147, 39, 79,166,126,126,126, 42,185, 92,222,219, 88,205, 90,181,106,137,222,245, 91,195,134, 13, 5, 92,129,203,105,114,154, -156, 38,103,176, 62,158,133,111,108,164,107, 95, 36, 69,239, 58,164,136, 0,123,254,120,194,238,239,229, 7,253, 31,145,239, 63, - 86, 79,205,154, 53,139, 8, 33,123,158, 63,127,190,223,205,205, 77, 31, 31, 31,255,222,154, 39, 46,210,228,246, 30,164,243,153, -120, 3, 31,128,222,248, 97,123, 62,138,136,228, 33, 0,135, 62,180,110,126,126,254,112, 66,200, 56, 74,169,242, 67,105,102,101, -101, 77, 38,132,236,120,254,252,249, 50,185, 92,222,192, 96, 48,232, 84, 42,213,213,204,204,204, 73,148,210,196,234,104,166,166, -166,206, 34,132, 28,152, 62,125,250,116, 0,245, 8, 33, 26,157, 78,119, 61, 35, 35, 99, 62,165, 52,181, 58,154,233,233,233, 95, - 10,133,194,205,177,177,177,139,165, 82,105, 61,150,101, 53, 10,133,226, 98, 86, 86,214, 68, 74,105,186,177, 58,177,177,177,239, -108,255, 21, 30, 30,206,205, 59,200,193,193,193,241, 47,106,131,245, 26,127, 68, 82,244,170, 75,208, 51, 0,250, 63, 30,125, 24, -211,242,252,249,171,246,175, 31,116,106,144,211,113,244,131,107,114,213,201, 31,206, 92,149,211,124, 8,160,205, 7,214,188, 15, -160,239,135,212,212,106,181,183, 0,132,113,185,128,131,131,131,131,227,131, 27, 44, 0,248,243, 17,229,174, 26, 7, 7, 7, 7, - 7, 7, 7, 71, 5, 16, 0, 1,239,136, 2, 60, 54, 90,132,144,128,170, 30,184, 50,253,255,177,166, 93, 5,154,103, 43,209,108, - 91,141,116,114,154,156, 38,167,201,105,114,154,156,230,191, 82,179, 50,237,143,166,119,226,127,181, 5,189, 17, 13,210,255, 33, -154, 92, 67, 69, 78,147,211,228, 52, 57, 77, 78,147,211,228, 26,185,127,176,133,155, 96,137,131,131,131,131,131,131,131,227, 3, -195, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112,112, 6,139,131,131,131,131,131,131,131,131, - 51, 88, 31, 16,187,255, 39,154, 28, 28, 28, 28, 28, 28, 28, 28, 31, 12,242,111, 26,229,156,131,131,131,131,131,131,131,227,127, - 1, 87, 69,200,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112, -112, 6,139,131,131,131,131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224,224,224, -224, 12, 22, 7, 7, 7, 7, 7, 7, 7, 7,199,223,111,176, 8, 33,109, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,228, 52, - 57,131,197,193,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112, -112, 6,139,131,131,131,131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,127, 19, 4,192, 91,123, 2, 80, 74,207, - 26, 45, 82,141,222, 4,149,233,115,154,156, 38,167,201,105,114,154,156, 38,167,249,241,105, 86,166, 93, 21,255,241,143,134, 82, -250, 95, 91, 0,180,229, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252,183, 45,124, 46,136,199,193,241,255,156,253,132, -135, 92, 31, 15, 80,234, 4,158, 40, 21,169,143,158, 99, 14,101,223, 91, 51,189,142, 27,164, 58,123,232, 37,153, 72,127,248,226, -189, 53, 57, 56, 56, 56,254, 69,112, 6,139,131,227,255, 59,153,190,222,224, 99, 49, 24, 56,130,106, 99, 97, 91,103, 49,128,199, -239,173, 41,100, 23,194,192,184,128,106, 99, 96,231,179, 4, 64, 36,119,177, 57, 56, 56, 56,140,227,111,105,228, 30, 28, 28, 28, - 30, 28, 28,188, 32, 44, 44, 76,204,221, 2,142,255, 22, 97, 97, 97,226,224,224,224, 5, 33, 33, 33,225, 31,237, 73,238,168, 43, - 3, 99,232,164,209,177,206, 39, 31,229,217, 41,212, 6,111, 48,250,206,216,236,109,242, 94,154,124,210, 94,165,101,107,236,188, -173,176, 47,214,232,253, 64,241,126,154,165, 4, 4, 4, 88, 52,106,212,232,100,131, 6, 13,108,184, 28,202,193,193,193, 25,172, - 15, 12,203,178, 13,237,236,236, 38, 41,149,202,132,160,160,160,110,255,166, 11,222,184,113,227,235,161,161,161,233, 77,154, 52, - 73,111,210,164,201,189,202,214,127,140, 56, 57, 57,121,215,173, 91, 55,193,223,223, 63,166,252,122,187,250,189,154,248,181, 24, - 58,199,198,191, 71,203,247, 61, 70, 80, 80, 80, 55,149, 74,149, 80,163, 70,141,137,122,189,190,225, 71,123, 49, 85,172, 61, 24, - 94,171,136, 84,133, 44,181, 64,103, 31, 30,175, 48, 5,120, 97,208,192,177,218,154,249,172, 61, 64, 91, 63, 72, 82,202,175,231, -216,218, 95,121,174, 54, 3,195,180,130,138, 56,188,111,114, 69, 34,209,104, 74,105, 59,129, 64, 48,129, 43,126,255,221, 16, 66, - 2, 8, 33,221, 8, 33,193, 31, 80,243, 7, 95, 95,223,100, 66,200,120,238, 10,115,252,191, 49, 88,125,107,146,166,159,214, 34, -151,250,215, 36,133, 3,106,145,162, 33,181,200,213, 62, 53, 73,235,234, 30,248,143, 63,254,144,110,223,190,221,174, 78,157, 58, -123, 66, 66, 66,174, 6, 5, 5,213,174,142, 78,112,112,240,201,224,224,224,190,111,174, 11, 10, 10,234, 95,126, 93,163, 70,141, - 34, 26, 53,106,148, 31, 28, 28,252,220, 24,221,192,192,192,103, 65, 65, 65,197,193,193,193,207,222,120,113,247,111,212,168,209, -201, 55,142,215,247,205,117,239,130,199,227,185, 28, 57,114,196,238,216,177, 99,118,124, 62,223,254,213,141, 96,152,183,174,175, -198,245, 24, 17, 28, 28,124,253,141,115, 25,254,230,186, 74,204,201,245,192,192,192,225,111,232, 94, 15, 14, 14, 30,241, 33,204, - 85,139, 22, 45,174,222,191,127,191,134,169,169,169, 69,249,223, 28,172, 45, 58, 92, 63,186,102,210,103,125,219,143,182,171,211, -179,110, 53,141, 85,237,198,141, 27, 95,245,244,244,220,179,120,241, 98,187, 57,115,230,200, 62,218,167,119,127, 29, 33, 8,219, -130,165,212,246, 73,178,202,246,147,110,125,249,247, 19,149,182, 58,131,193, 10,224,133, 97,171,187,184, 90,154,124, 93,115,150, - 82,251,115,241, 2,219, 86,253,198,242,206,199,243,109,117, 6,131, 53, 24,180,172,150,230,127,242,161,128,199,227, 77, 26, 57, -114, 36, 67, 8,249,218,211,211, 83,244,111, 42,108, 67,156,137,115, 27, 47,254,237, 64, 39,210,244, 3, 26, 10,127,185, 92,126, -151, 16,226,253,255,204, 92, 53, 4, 32,163,148, 30, 6, 96, 79, 8,225,127, 0,205,229,243,231,207,159, 26, 17, 17,225, 84,179, -102,205,121,132, 16, 30,247,138,231,248,199, 27,172, 1, 53,201, 92,123, 7,231,211, 51,151,239,106,177,241,210, 11,147,181, 71, -239,203, 39, 78, 91,212,212,193,218,246,200,160, 90,228,135,119,237, 87, 81, 87, 75,145, 72,132, 23, 47, 94, 96,213,170, 85,146, -185,115,231, 54, 49, 55, 55,127, 24, 18, 18,178,162, 78,157, 58,242,138,210,242,166, 38,165,180,169, 64, 32,216, 24, 18, 18,178, -165,172,192, 38,132, 52, 21,139,197,191,134,132,132,236, 40,171,134, 12, 12, 12,172,121,251,246,109, 51, 66,136,189, 49,233,108, -212,168,145,227,221,187,119,101, 64, 73, 36, 32, 44, 44, 76,220,168, 81,163,237,206,206,206, 27, 0, 52, 5, 0, 79, 79, 79, 81, - 72, 72,200, 22, 87, 87,215,223, 8,121,189,208,124,215,185, 19, 66, 96, 97, 97,129, 93,187,118,129,199,227,253,101,253,142, 29, - 59, 64, 8,169,242,245,172, 83,167,142, 60, 56, 56,248, 15, 71, 71,199, 21, 44,203,134, 2, 64,221,186,117,101,141, 26, 53,218, -239,226,226,178,178,108,157, 49,154,148,210, 80,161, 80,184,162, 81,163, 70,251,235,214,173, 43, 3, 0,150,101, 67,249,124,254, -242,224,224,224, 63,170,114,143, 26, 54,108, 56,178, 94,189,122, 41,245,234,213, 75,241,241,241,249,222,222,222,254,226,234,213, -171,173,203,159,123, 89,228, 42, 61, 35, 59,247,250,157,136,232, 73, 35,251,132,213,112,181, 31,100, 81,191,135,185, 49,231, 94, -118,254, 33, 33, 33, 43,204,205,205, 31,206,152, 49, 35,116,225,194,133, 18,173, 86, 11,161, 80,136,234,228,207,234,242, 63,213, -204, 34,118,160,180,109,116,154, 82,226,238, 23, 36,183, 11,234, 13, 59, 51,129,248,198,243, 98, 83, 16,180,129, 86,102, 91, 45, - 77,194,111, 19,145,172,148, 90,250,119,150, 5,135,182, 0, 99, 93, 91,124, 49,166,216, 12, 12, 83, 61,205,255,208, 39, 52, 52, - 84,212,182,109, 91, 56, 57, 57,241,204,205,205, 7,253,163,174,231,127, 81, 51,196,153, 56,155,154,136,110,253, 52,103, 98,144, -147,149,236,144, 49, 38,203,136,238,243,254,118,118,118, 23,214,172, 89, 19,104,106,106,122,217, 24,147,245, 79,184,158,165,230, - 74, 72, 41,189, 89,186, 42, 18, 64,243,247,212, 92, 62,119,238,220, 9, 51,102,204, 64, 65, 65, 1,134, 13, 27,102, 6,224, 39, - 99, 53, 77, 77, 77,189,234,213,171,183,195,223,223,255,101,131, 6, 13, 52,117,234,212, 81,249,248,248,196, 7, 4, 4,108,149, - 72, 36, 30, 31,123,254,252,167,104,254,235, 12, 86,191, 90,164,137,141,131,243,212, 31, 14,222,145, 26, 34,239,226,238,103, 45, - 17,245, 85,103, 72, 99,194, 49, 99,220,183, 82, 51, 51,203,175,251,214, 34,173,170,115,240,152,152, 24,236,221,187, 23, 54, 54, - 54,100,243,230,205,226,190,125,251,142, 54, 51, 51, 75, 12, 14, 14, 30,100,172, 6,143,199, 51,108,217,178,197,164,123,247,238, - 3,172,172,172, 34, 2, 3, 3,107, 50, 12, 99,216,182,109,155, 73,255,254,253,251,106, 52,154, 39, 65, 65, 65,181,239,221,187, -103,184,115,231, 14, 24,198,184,160, 93,120,120,184,254,196,137, 19,175,162, 34,148,210, 39, 75,150, 44, 25,112,224,192, 1, 83, -115,115,115, 54, 48, 48,176,166,171,171,107,196, 15, 63,252, 48,104,255,254,253,166,102,102,102,172,145, 5, 1, 84, 42, 21,164, - 82,233,107, 70,138, 16, 2,165, 82, 9,137, 68,242,154,241, 50, 50, 50,224,111,109,109, 29,181,120,241,226,238, 7, 15, 30,148, -154,154,154, 34, 56, 56,216,207,194,194, 34,122,233,210,165, 61,202,214, 25,139, 80, 40,196,174, 93,187,100,159,126,250,105, 55, -177, 88, 28, 21, 28, 28,236, 39, 20, 10,177,123,247,110,217,160, 65,131,186,200,100,178, 39,129,129,129,254,198,104,233,116,186, -217,119,238,220,113,188,116,233,146,163,155,155,219,184,181,107,215,218, 11, 4, 2, 0,128,193, 96,120, 45,114, 53,168, 87,187, -144, 9,179,215, 92, 80,170,212,154,133,211, 63, 15, 19, 24,208,216,200,168,221, 32, 51, 51,179,196, 47,190,248, 98,204,174, 93, -187,196, 14, 14, 14, 76,120,120, 56, 10, 11, 11,171,124, 45,255,255, 68,175, 8, 15,124, 67, 67, 0,158,225,241, 74,155,250,109, - 7,243, 17,123, 4,141, 60, 76,248, 23, 98, 10,237, 40, 67,221, 0,218, 8,243,194,248, 85,210, 20,208,250, 96,216,218,167, 99, -137, 77,147,206,131,248, 9, 9, 9,240,168, 31,198, 59, 22, 3,123, 74,168, 7, 88, 4, 85, 73,179, 28, 2,129, 96, 78,191,126, -253,228, 9, 9, 9,104,218,180,169, 76, 36, 18,205,254, 32, 81,188,245, 62,110,216,232,211, 18,155,189, 29,113, 41,236, 31,215, -113, 39,196,153, 56,155,153,136,110,238,222,189,215,169,110,199, 47,201,134,161,238, 86,182,102,130, 67,239, 19,201, 42, 53, 87, -231,111,221,186,101,221,190,125,123,204,157, 59,215,214,204,204,236,242, 63, 61,146, 85,222, 92, 17, 66,164,165,213,131,201, 0, - 92,222, 67,115,229,220,185,115, 39,204,156, 57, 19, 55,111,222,196,210,165, 75,209,177, 99, 71, 88, 90, 90, 86, 90,126, 12, 25, - 50, 68,214,180,105,211,240,110,221,186, 61,152, 56,113,226,160,163, 71,143,186,110,217,178, 69,248,217,103,159,137,251,245,235, -231, 54,113,226,196,161,157, 59,119,126,220,184,113,227, 91,125,251,246,149, 84, 49,105,124, 0,162,210, 69, 80,146, 84, 66, 8, - 33,124, 66,136,128,139,176,113, 6, 11,124,138,249, 95, 78, 94, 32,137,219,250, 51,210,247,254, 2, 94, 94, 58, 4,133,217, 80, - 95, 61, 6,221,213,195, 24, 18, 26, 42,149, 18,178,176, 58, 7, 55, 49, 49,129, 80, 40,196,179,103,207, 16, 25, 25,137,206,157, - 59, 11, 87,175, 94,109,225,239,239,255,107,211,166, 77, 31, 4, 7, 7,215, 51,198,176,120,121,121, 97,192,128, 1,162,241,227, -199,215,146, 72, 36,247, 40,165, 2, 15, 15, 15,244,239,223, 95, 56,109,218, 52,119,137, 68,114,135,101, 89,161, 76, 38,123,103, -116,232,109,186, 82,169, 20, 0, 4,181,107,215,190,187,103,207, 30,143,166, 77,155,242,207,156, 57,131,130,130, 2,190,183,183, -247,131,221,187,119,123, 54,105,210,132,127,237,218, 53, 20, 23, 23, 83, 99,117, 21, 10, 5, 36, 18,201, 95, 12,150, 66,161,128, - 88, 44, 54, 58,141,165,230, 98,132,167,167,231,157, 61,123,246,184, 52,111,222,156,119,241,226, 69, 20, 22, 22,194,205,205,237, -238,158, 61,123, 92,154, 54,109,202,187,113,227, 6, 10, 11, 11,141,214, 20,137, 68,112,119,119, 71,191,126,253, 4, 83,166, 76, -113, 17, 8, 4,119, 68, 34, 17,220,220,220,208,175, 95, 63,225,228,201,147, 93, 68, 34,209, 45, 35,171, 12,121,165, 70, 11,253, -250,245,147,203,100, 50, 36, 38, 38,130,101, 89,176,108,137, 39, 77,205,204,126,116,237,206,227,168, 73,163,250,182, 44, 86,171, -213,167, 46,222,125, 82,167,182,155, 11, 33,212,189,146,115,175, 23, 18, 18,242, 32, 44, 44,236,183,195,135, 15, 91,180,107,215, - 78,112,231,206, 29,188,124,249, 18, 98,177, 24, 38, 38, 38,224,243, 63,210,142,178, 5,117,172,193,162, 93, 66,166, 70, 44,182, -112, 49, 53,113,244, 6, 94, 94, 70, 77, 91, 49,120, 12, 79,114,231,133, 66, 14,208,118,168,145,101, 93, 53, 77,182,221,139, 12, -141, 88,103, 21, 96,226,228, 82, 3,217,217,217,112,173,229, 11,149,200, 86,116,253, 89,177, 9, 72, 21, 53, 75,105,208,160, 65, -115, 87, 87, 87, 7,119,119,119,100,101,101,193,203,203, 11, 38, 38, 38,150,129,129,129,237,170,125, 13,182,186,139, 81,128,166, - 0,179, 12, 6, 50, 15, 58,254, 98, 60,203,108,136, 95, 3, 5,255, 56,115,181,103,175,179,117, 13, 63,224,216,231,176,183, 16, - 99,211,232,134, 86,182,230,226,106,153, 44, 66,136,191,189,189,253,249, 91,183,110,217, 72, 36, 18,220,187,119, 15,117,234,212, -193,207, 63,255,108,107,105,105,249,143, 53, 89,111,152, 43, 43, 74,169, 18, 0, 11, 96, 32,170,209,235,181,212,172,252,178, 96, -193,130,113,223,126,251, 45,174, 95,191, 14, 23, 23, 23,100,102,102,162,121,243,230, 9,185,185,185, 21,190,151,252,253,253, 93, -158, 62,125,154, 60,105,210,164,134, 59,118,236,144,202,100, 50,228,229,229,225,183,223,126,195,140, 25, 51, 64, 8, 1,165, 20, -155, 55,111,150, 13, 27, 54,172, 81,108,108,108,178,187,187,187, 49,205, 55, 8, 0, 9, 0, 89,233, 34, 7, 32,219,189,123,183, -121,247,238,221,205, 74,215, 73, 1, 72, 9, 33, 92, 71,175,127,179,193,162, 64, 61, 7, 15, 31,228,159,217, 7, 41,159, 64,202, - 43, 93,248, 4,204,243, 71,112,149, 8,160,163,212,191, 58, 7, 55, 49, 49,121,181, 48, 12,131,212,212, 84, 48, 12,131,217,179, -103, 75,198,141, 27, 87, 87, 36, 18,221,104,209,162,197,226, 10, 79,160, 52, 34,117,231,206, 29,212,174, 93,155,204,156, 57,211, - 44, 44,172,228, 43,246,209,163, 71,240,244,244, 36,139, 22, 45, 50,237,218,181, 43,145,203,229, 70, 71,176, 24,134,129, 84, 42, - 69,171, 86,173,200,150, 45, 91, 76,196, 98, 49,142, 29, 59,134,204,204, 76,180,111,223,158,191,101,203, 22, 19,137, 68,130,203, -151, 47, 35, 63, 63,223,104,221,202, 34, 88,165,166,206, 40,154, 52,105,178,201,193,193, 97,197,246,237,219,197, 82,169, 20, 23, - 47, 94, 68, 94, 94, 30, 6, 12, 24,160,223,185,115,167,196,204,204, 12, 55,110,220, 64, 94, 94, 94,181, 50,199,157, 59,119,224, -229,229, 69,102,205,154, 37, 13, 13, 13,213, 1,192,253,251,247,203,174,179,212,204,204,108,121,179,102,205, 54, 85,164,193,178, - 44, 82, 83, 83, 17, 17, 17,129,231,207,159, 35, 51, 51, 19, 89, 89, 89, 40, 44, 44,132, 94,175, 7, 0,200, 10, 11,142,253,178, -229,200, 3,185, 84, 42, 11,169, 91,187,198,173,123,145, 25,114,169, 84, 86,219,163,134, 55, 33,243,222,122, 97, 67, 67, 67, 23, -243,120,188, 27, 11, 23, 46,172, 55,107,214, 44,113,116,116, 52,238,221,187,247,151,124,245, 81, 26, 44, 66, 8,136,166, 54, 8, -105,120,243,121,177, 85,243, 46, 3,133,120,113, 18, 96,117, 0,195, 71, 88, 61, 23,254,161, 71,197,246,160,168, 7, 53,124, 1, - 35, 28, 59, 33, 4,208,122, 1, 36,232,244, 83,189,117,211,158,163,133,201,201,201, 16, 10,133, 16,139,197,104,216,186, 55,127, -247, 3,157, 3, 8,234, 67, 11, 31,163, 52,203, 33, 22,139,191,251,252,243,207,229,229, 53, 59,117,234, 36,151,201,100,115,170, -109,174,138,101,161,208,211,241, 17,201, 10,247,239,143,165,249,197,102, 40,125, 64,233, 36, 64,215,224,125, 77,150,155,155, 91, -152,183,183,247, 11, 15, 15,143,102,239,101,174, 76, 69, 55,246,236,217,235,108,229, 90, 98,174,160, 87, 1, 2, 41, 28,108, 45, -176,105, 98, 43, 43, 91, 11,105,149, 76, 86,169,185, 58,119,243,230, 77, 27,137, 68,130,240,240,112, 8,133, 66, 72, 36, 18,212, -173, 91, 23, 27, 54,108,176,181,178,178,250, 71,152, 44, 66,136, 37, 33,164, 3, 33,164, 15, 33,164,119, 57,115,229, 1,160, 53, - 33,164, 29, 0, 7, 0,151, 40,165, 15,140,212,108,198,231,243,143,213,175, 95, 63,133,207,231, 71, 46, 90,180,232,171,105,211, -166, 97,229,202,149, 8, 11, 11,123, 62,109,218, 52, 68, 69, 69,233, 21, 10, 69, 55, 74,233,209,138,180,138,138,138, 14,207,154, - 53,203,188,103,207,158,101,255,199,213,171, 87,177,109,219, 54,200,229,175,183,130,232,214,173, 27, 70,140, 24, 97,169,209,104, -254,168, 72,211,222,222,190,205,205,155, 55,235, 0, 16, 2, 16,151, 25,172,199,143, 31, 91, 20, 20, 20, 88,152,152,152, 88, 56, - 58, 58,154,150,153,172,158, 61,123, 90, 8, 4,130,102,224,248,119, 26, 44, 0,208,230,164, 67, 12, 3,164, 60, 2, 25,175,156, -201, 2, 11,126,126, 70, 21,139,218,183, 27, 44, 83, 83,211, 87, 70, 75,169, 84, 26, 29,113, 41, 51, 54,150,150,150, 40, 44, 44, -132, 78,167,123,245,112, 88, 90, 90, 66,173, 86, 3, 0,228,114, 57,170, 25,193,194,245,235,215,113,237,218, 53,240,249,124, 88, - 89, 89, 1, 0,238,222,189,139, 71,143, 30, 65, 40, 20,194,202,202,170, 74,186, 90,173,246,173, 17, 44,173, 86, 11,177, 88, 92, - 37, 19,168, 82,169,232,221,187,119,241,248,241, 99,136,197, 98,216,218,218, 66, 36, 18, 33, 49, 49, 17, 81, 81, 81, 16,137, 68, -176,181,181,173,214,253, 49, 51, 51, 67,110,110, 46, 12, 6,195,171,107, 97,110,110,142,226,226, 98, 48, 12, 99, 84, 58, 89,150, - 69, 74, 74, 10, 50, 51, 51,145,152,152,136,172,172,172, 87, 38,171,172,138,176, 90, 25,151, 97, 64, 8,193,189,123,247,232,249, -243,231, 81, 88, 88,248,151,188, 84, 22, 33,253,232, 88,235,111, 14,157,160,125, 86,145, 78,156,169, 21,154,219,251,183, 5, 94, -156, 0, 24, 62, 32,177, 68,227,128,154, 72,200, 53,200,163,211, 53, 18, 16,116,192, 26,111, 75,163, 52, 13,130,118,153,133, 58, -113,188,214,214,204,175, 94, 32,210,211,211, 33, 22,139, 33, 22,139, 17,212,180, 45, 94,100, 27,100,145,201, 74, 25, 40,218, 27, -165, 89, 74,195,134, 13,107, 73,165,210,208,134, 13, 27,146,242,154,161,161,161, 96, 24,166,110,131, 6, 13,124,171,116,254,171, - 61, 69,208,202, 26,131, 79,199, 71,166, 42,156, 14, 61, 86,121,119,237,209,219,106,229,217, 12,191, 39,105,106, 15, 80,221,100, - 80,109, 96,117, 77,150,187,187,123, 75, 19, 19,147,163,223,125,247,157,135, 88, 44, 62,225,225,225,209,188, 90,229,155,148,183, -254,187,175, 6, 58, 91,150,153, 43,157, 2,224, 75, 1,129, 20,224, 75,225, 96,103,131,133, 35,218, 89,201, 36,130, 63,141,213, -148, 74,165,187,215,172, 89, 99,251,166,185, 42, 91, 26, 54,108,136,217,179,103,219, 90, 89, 89,237,250,155,205,149, 21, 74,218, - 85, 61, 4,240, 7,128,115,229,204,149, 23,128, 63, 75,163, 86,247, 40,165, 9, 70,106, 54,233,216,177,227,133,231,207,159,119, -126,240,224,129, 99, 90, 90,154,239,228,201,147,177,114,229, 74, 76,155, 54,109, 23,165,212,123,223,190,125, 13,110,223,190, 93, -151, 82, 90,105, 68, 44, 45, 45,237,211,105,211,166,101,101,101,101, 1, 0,234,214,173,139,188,188, 60, 76,153, 50, 5, 19, 38, - 76, 40,139,188,130, 82,138,244,244,116, 44, 91,182, 44, 61, 45, 45,237,179,138, 52, 13, 6, 67,226,190,125,251, 26,105,181, 90, - 23,148, 84, 11,138,243,242,242,204,114,114,114, 76,181, 90,173,156,101, 89,185,133,133,133, 9, 0,217,144, 33, 67,248,145,145, -145,126,122,189, 62,153,179, 34,255, 82,131,197, 35,120,248,242,238,101, 88,249, 7,190, 22,189,146,241, 8,164,102,230,120,145, -152, 0, 33, 72, 68, 85, 15, 76, 41,125,205, 96,149,189, 24, 83, 83, 83, 49,125,250,116,197,142, 29, 59, 30,105, 52,154,208,203, -151, 47,207,168,244,195, 27,128,173,173, 45, 18, 18, 18,232,143, 63,254, 88,112,226,196, 9, 61, 0,216,217,217, 33, 49, 49,145, -206,154, 53,171,112,239,222,189,180, 42, 6,139, 97, 24, 72, 36, 18, 92,188,120,145,206,153, 51, 39, 63, 53, 53,149, 90, 91, 91, -195,218,218, 26,103,207,158,213,207,152, 49, 35, 63, 54, 54,246,213,186,170, 24,172, 50,195, 82,222,160,188,203,120, 85,196,213, -171, 87,191,200,207,207,159, 56,101,202, 20,229,147, 39, 79,168,173,173, 45,108,109,109,177,117,235, 86,254,208,161, 67,149, 15, - 31, 62,124,181,174, 58, 88, 91, 91, 35, 38, 38,134, 46, 90,180, 72,121,238,220, 57, 1, 0,216,216,216, 32, 42, 42,138,206,159, - 63, 95,153,151,151, 55,241,234,213,171, 95, 84, 82,224,224,249,243,231,175, 34, 86, 42,149, 10, 89, 89, 89, 72, 76, 76,124,101, -176,148,114,179,142, 95, 15,235, 90,191, 88,169, 84,220,122,244,244,101, 72,195, 58,118,197, 74,165,226,105,220,203, 24, 74,231, -188,181,109,219,181,107,215,102,232,245,250,208, 35, 71,142, 60,218,176, 97,131, 34, 39, 39,231,173,134,253,163, 52, 88, 12,235, - 0, 66,155, 93,121, 90,100,209,174,107,127, 17, 73,187, 13,104,139, 0,177, 37, 32,182, 4, 95,110,141, 78,205, 27,240,182,222, - 44,112, 0,101,155, 64, 40,174,188,125,139,128,218, 3,108,243, 51, 49, 42,203,102,125,198,138,114,114,114,192,227,241, 94,153, - 33,153, 92,142, 54, 61,134, 48,155,111,171, 29, 0,218, 20,132,103,116,155, 25,161, 80, 56,117,216,176, 97,194,220,220, 92, 48, - 12,243, 74, 83, 42,149,162,103,207,158, 98, 83, 83,211, 89, 70,159,251,254, 58, 66, 8,196,141, 1, 58, 33, 58, 77,229,116,248, -145,210,103,242,146, 77, 82,255, 6,141, 48, 50,204, 78,186,228, 88,134,255,131, 68,101, 77,192, 48, 17,122, 77, 80, 85, 77,150, -135,135, 71,115,185, 92,126,236,208,161, 67,178, 86,173, 90, 97,202,148, 41,114,137, 68,114,194,221,221,189, 69, 85,111, 83,113, -145,225,235,249,171,182,167, 63, 92,222, 1,208, 22,151, 24,171,114, 75, 70, 17,139,217,155,206,231,235,116,116,160,177,154, 74, -165,114,232,240,225,195,179,255,252,243,207,191,152, 43,137, 68,130,184,184, 56,124,255,253,247, 57, 57, 57, 57,159,253,205,185, -180, 1,128,251, 0, 84, 0, 90, 2,144,149,246, 20, 12, 5,112,150, 82,106,160,148,166, 83, 74, 83,141, 21,228,241,120,211,214, -174, 93,203, 87, 42,149, 24, 49, 98, 4, 18, 19, 19,145,146,146,130,111,191,253, 54,142,101,217,161,165,154, 15, 40,165, 81,198, -232,105, 52,154,232,220,220,220, 46, 29, 58,116,200,203,205,205, 69,189,122,245,208,181,107, 87, 56, 56, 56,192,201,201, 9,221, -187,119,135,183,183, 55,178,179,179, 49,112,224,192,156,204,204,204, 14,148,210, 10,123,161,103,103,103,199,238,218,181, 43,102, -236,216,177, 13,147,146,146,252, 0, 88, 23, 22, 22,202, 11, 11, 11,197, 26,141, 70,106,105,105,105,217,160, 65, 3,155, 47,191, -252,210,228,254,253,251,126, 73, 73, 73, 69, 0, 18,192,241,239, 52, 88, 90, 96,246,182,125, 91, 85,162, 26, 94, 48,247,169, 15, -153, 68, 2,169, 72, 4,169,165, 53,212, 44,139,141,113,105,138, 98, 74,103, 85,245,192,148,210,215, 34, 13, 6,131, 1,235,215, -175, 87, 45, 92,184, 48, 47, 45, 45,109,212,229,203,151,235,223,185,115,231,161, 49, 70,168,160,160, 0,251,246,237, 83,110,217, -178,229,185, 82,169,108, 40, 20, 10,117, 26,141, 6,187,118,237, 82,173, 88,177, 34, 94,161, 80, 4, 11, 4, 2,109, 85,204, 75, - 89, 4, 75, 32, 16,232, 84, 42, 85,195,221,187,119,199, 30, 61,122, 84,105,102,102, 6,129, 64,160, 83, 40, 20,117,183,111,223, - 30,189,123,247,110,165,169,169,105,149,140, 27,203,178,111,173, 34,100, 89,182, 74, 6, 11, 0,238,220,185,243,155, 86,171, 13, -217,181,107, 87,210,166, 77,155, 84,102,102,102, 0, 0,157, 78, 23,188,109,219,182,164,117,235,214,169,171,210,192,189,180,224, -129,193, 96,192,246,237,219,213,187,119,239, 78,210,235,245,193,101,235, 54,111,222,172,218,190,125,123,146, 86,171, 13,185,115, -231,206,111,149,105, 25, 12, 6, 67, 65, 65, 1,248,124, 62,158, 63,127,174, 46,139,208, 61,123,246,236,149,193,178,179,177,170, -211, 52, 56,192,247,231,245,251, 46,201,197, 98,113,135,176, 32,191,200,167, 9, 73,148,146,248, 74,206,253,225,245,235,215,235, -231,228,228,140,218,176, 97, 67,222,206,157, 59, 85, 6,131,225, 53,147, 37, 18,137, 62,198,167, 86, 6, 2,233,211, 12,181,169, -132,209, 19,196, 28, 44, 49, 87, 18, 11, 64, 98, 9, 72, 44,225,236,236,130,219,113, 10, 83, 48, 16,193,160,179, 51,226,129,148, -131, 64,246, 56, 29,166, 2,145,148,164,165,165,189, 50, 66,101,139,135,151, 31,238, 37, 20,153,128, 80, 49,120,176,175,194,179, -222,197,212,212,148,159,154,154,250, 87, 77, 15, 15,158, 78,167,235, 96,244,185,167, 24, 28, 1,246,171,152, 52,149,227,129, 7, -197, 62, 19, 23,111,150, 74, 13,121,192,221, 85,240,175,229,132,137,125, 26,136,102, 30,206,244,191, 19,175,168, 5, 30, 29, 9, -182,200,232,175, 11, 15, 15,143,102, 50,153,236,196,193,131, 7,101, 50,153, 12,207,159, 63, 71,221,186,117, 49,127,254,124,153, - 76, 38, 59,238,230,230, 22, 86,149,219,116, 51,141, 38, 20, 21, 26, 66,167,238,123,153,246, 48, 85,255,154,185,202, 44,166, 24, -254,195,225,188,220, 2, 85,239, 27, 47,117,231,171,112, 45,239,231,229,229,181,159, 53,107, 86,118,102,102,230,107,230, 42, 33, - 33,161,204, 8,132, 81, 74, 35,254,230, 92, 42, 71, 73,227,117, 31, 0,158, 0,234, 83, 74,245, 0, 10, 41,165,213, 10, 93,215, -169, 83,167,161,155,155, 27,214,173, 91,135,141, 27, 55,230,254,252,243,207,160,148,162,118,237,218,102,213,213, 76, 79, 79,191, - 29, 29, 29,221,161, 94,189,122, 79, 86,175, 94,157,228,232,232,200,126,249,229,151, 24, 62,124, 56,108,109,109, 13, 43, 86,172, -120,217,188,121,243,199,177,177,177,109,139,139,139, 31, 25,113,127,104, 86, 86,214,245, 95,127,253,245,102,235,214,173,101, 67, -135, 14,181, 61,116,232,144,181, 66,161,112, 18,139,197,118, 26,141, 70,244,228,201, 19,222,254,253,251, 29, 34, 35, 35,227,148, - 74,229,109, 90, 58,177, 31,199,191,208, 96,253,254,156, 94, 47, 46,204, 91, 58,127,243, 6,229, 11, 61,129,190,102, 29,168,172, -157,113, 39, 79,137, 41, 79,146, 20,122,150,174,217,247,156, 94,168,110, 4, 75, 38,147,225,220,185,115,134,175,190,250, 74,117, -251,246,237, 95,243,243,243, 93,239,220,185,179,211, 88, 29,150,101,121,159,127,254,121,209,181,107,215,246,165,166,166,250,135, -135,135,191, 96, 89,150, 55,104,208,160,162, 51,103,206,252, 73, 8,241,187,123,247,238,211,106,132,184, 33, 20, 10, 65, 8,193, -157, 59,119,226,114,114,114,252,111,222,188,185,123,198,140, 25, 69,148, 82, 94,120,120,120, 98,113,113,113,189,235,215,175,239, -248,250,235,175,139, 40,165, 60, 99,117,203,204, 91,121, 35, 85, 22,205,170,170,193, 2,128,240,240,240,136,188,188, 60,191,219, -183,111,159,248,242,203, 47, 21,165,230,227, 73, 97, 97,161,239,205,155, 55,143, 13, 29, 58, 84, 81, 21, 61,173, 86,139, 30, 61, -122, 40,110,220,184,113,172,176,176,208,247,206,157, 59, 79,202,214, 93,187,118,237, 68, 94, 94,158, 95,120,120,184,177, 5,248, -252, 21, 43, 86,164, 46, 92,184, 48, 53, 51, 51,243,231,229,203,151,103,218,218,218, 66,171,213,190, 50, 88, 25, 89, 57,231,155, -124, 50,246,135, 29,127,156,189,179, 98,254, 87,173,164, 18,177,104,214,146,205, 23,117, 60,220, 52,210,100,238, 44, 40, 40,112, -125,240,224,193,175, 19, 39, 78, 84,157, 62,125,218, 32,149, 74, 97, 98, 98, 2,177,248, 99,108, 67,106, 40, 0, 75, 82,250, 6, - 89, 38,175, 88,251,155,250,241,139,244, 87,198, 10, 98, 11,220,137,205,195,119,171,247,177,223,119,179,125, 1,138, 68, 48,136, -174, 92,147, 95, 0,150,100, 12,111, 36, 76,250,253,167, 9,234, 23,209,143, 94, 51, 66, 81, 15,239, 96,249,156,177,236,162,174, - 86, 47,192,146, 20, 16, 68, 25,155, 90,189, 94,223,103,241,226,197,197,177,177,177,175,105,198,199,199, 99,201,146, 37, 74,181, - 90,221,219,232,135, 82,204,175,111,160,212,110,231,141,236,218,163,190, 28, 38,149,234,115,128, 91, 63, 2, 2, 25, 32, 54, 71, - 3,223, 90,152, 61,226, 19,193,228,253,105,254, 0,235, 6, 70,232,103,108, 58,249,124,254,177,197,139, 23,203,164, 82, 41,158, - 61,123, 6,137, 68, 2,169, 84,138,160,160, 32,172, 92,185, 82, 38, 18,137, 78,148,181,239,172,178,201,218,253, 44,237, 97,162, - 10, 16, 72,144, 85, 12, 12,255,225, 72,110, 78,190,178, 79, 85,204,213,155, 38,107,194,132, 9,217,233,233,233,144, 72, 36, 72, - 76, 76,196,128, 1, 3,178,255, 33,230, 10, 0,138, 1, 56, 3,136, 1, 16, 11,224, 1, 33, 68,132,247,152,158, 45, 50, 50,242, - 94, 66, 66, 2,190,248,226, 11, 12, 30, 60,216,242,211, 79, 63,197,139, 23, 47, 16, 19, 19,115,255,125, 18,170, 84, 42,239, 36, - 37, 37,213,157, 48, 97,194,108, 23, 23,151, 45,214,214,214, 23,173,172,172, 46,184,184,184,108,158, 49, 99,198,119,169,169,169, -245,181, 90,237,131, 42,220, 31, 74, 41,125, 22, 27, 27,123,120,251,246,237,225, 19, 38, 76,136,251,244,211, 79,147,198,143, 31, -159,250,235,175,191,166,220,191,127,255,105, 94, 94,222,169,202,162, 97, 28, 31, 1,198,206, 10,221,199, 3, 77,135,213, 34,151, - 62,173,137,194,129, 53, 81,244,185, 39,185,218,219, 3,173,171, 51,219,118,195,134, 13,169, 94,175,167,167, 79,159,166,157, 58, -117, 42,110,214,172,217,213,192,192,192,218,213,153,193, 59, 44, 44,236,100, 80, 80, 80,223, 55,215, 53,106,212,168,127,249,117, - 45, 91,182,140,104,217,178,101,126,139, 22, 45,158, 27,147,206, 22, 45, 90, 68, 53,109,218,180,184, 69,139, 22, 81,229,215, 7, - 7, 7,119,111,221,186,245,177,242,235, 26, 53,106,212,237,205,117,239, 58,247,182,109,219, 38,198,196,196,208,151, 47, 95,210, -206,157, 59,167,148,173,111,211,166, 77,226,163, 71,143,232,211,167, 79,105,199,142, 29, 83,170, 59,123,121, 80, 80,208,136,230, -205,155, 95,127, 35,205,195,223, 92, 87,145,102,243,230,205,175, 7, 7, 7, 15,127,115, 93, 80, 80,208,136,247,157,101,221,209, -209,209,187, 65,131, 6, 25, 43, 86,172,160, 53,107,214,204, 40,255,155,127,216,231,223,229, 21, 20, 21, 76,153,191,238,119, 91, -191, 30,117,171, 51,115,123, 96, 96, 96,237, 22, 45, 90, 92,253,228,147, 79,138,111,223,190, 77, 41,165,180, 97,195,134,244,163, -154,181,126,159,159,144,110,240,107, 74,215,251, 29,139,154,227,246,228,179, 16,185, 58,252,167,206,148,158,159, 74,111,174, 27, - 78, 67, 61, 68,134,107, 83, 92, 99,232, 6,223, 19,116,179,119, 11,186,170,150,200, 40,205,141,158,205,233, 6,223, 19,145,179, -221,158,244, 12,180,213,236,222,186,129, 62,123,246,140, 30,222,191,139, 54,174, 41, 43,209, 92,239,119,154,174,243,107,101,148, -230,235,207,124,211,208,208,208,162,223,127,255,157, 62,123,246,140,158, 57,115,134, 54,109,218, 84,209,160, 65,131, 86, 70,159, - 59, 64,232,186, 58, 61,244,107,125,174,204,104,107,146, 55, 60, 68,162, 30,216, 64,164,233,238, 47,212,182,247, 18,234,155,184, -241, 13,245, 29, 25,214,207, 22,180,189,143, 84, 77,215,251, 92,166,235,253, 58, 24,155,206,218,181,107,191,116,119,119,167,239, - 90,188,189,189, 51, 91,182,108,201,175,206,125, 15,177,135, 91, 91,111,113,234,185,249,173,105,215,122,166,217,141, 93,249,173, -223, 55, 47, 1,104, 96, 99, 99,147,181,101,203, 22,106,111,111,159, 9,192,255, 31,145, 63, 75,214, 89, 1,232, 14,192,182,244, -255, 38, 0, 90, 1,168,249, 30,154, 77,218,183,111,175,187,119,239, 30,125,254,252, 57, 61,121,242, 36,109,218,180,169, 30, 64, -216, 63,230,217,228, 52,185,165,220, 66,254,155,209, 73, 66, 72,219,183, 13, 70, 22, 24, 24, 72, 59,116,232,160,188,116,233, 82, -145, 70,163, 25,121,247,238,221,195,239,171,249,223, 72,231,127, 67,179,117,235,214,215, 25,134,169, 89,218, 5, 56,229,236,217, -179, 13, 1,160, 85,171, 86,215,121, 60, 94,205, 82,211,155,114,238,220,185,134, 31,219,185,151,225,228,228,228,205, 48,204, 41, - 0,234,164,164,164, 87,189,157,236,252,187,135, 90, 89,154,183,202,203,203,191,159,246,248,208,137,247, 73,103, 80, 80, 80, 55, -177, 88,188, 33, 52, 52, 84,126,254,252,121, 89,120,120, 56,249,168,174,231,106, 79, 17, 68,162, 32, 80, 76,127,156,172,240,248, -238, 72, 86,173, 79,218, 52, 21,108, 61,120,137, 93,218,203, 46,182,137,167, 60, 14, 2,246, 7, 16,245,109,124, 22,175, 54, 90, - 83, 74, 26,193, 32,152,254, 32, 81,225, 54,229,207, 92,175,182,189,135,243,142,236,217,192,254,216,195, 58,182, 73, 45,147,151, -160,248, 1, 98,197, 13,163, 53, 95,127,238,155,138,197,226, 19, 3, 7, 14, 52,217,189,123,183, 82,165, 82,117,185,119,239,222, -133, 42,157,251, 38,223, 26, 48,144,133,160,212,181,242,175, 71, 60,131, 1, 11,241, 85,212,203,127,194,125,111,236, 64,220,228, -230,226,163, 10,165,126,130, 49,145, 43, 99, 52, 9, 33, 13, 44, 45, 45,119,228,230,230,246, 55, 38,114,245,191, 60,119, 66,136, - 45,128,224,210,168, 21, 1, 16, 97,108,212,166, 2,205,102, 60, 30,111, 90,173, 90,181,234, 61,127,254,252,177,193, 96,248,145, - 82,122,241,223,240,238,248, 55,104,126,108,252, 45,125,216,165, 82,233,189,139, 23, 47,158, 20, 10,133,223, 95,187,118, 77,253, -111,186,224,231,207,159,111,242,182,245, 23, 46, 92,104,242,111,185, 6, 41, 41, 41, 49, 0,220,222, 92,159, 17,113,232, 6,128, - 27, 31,226, 24,119,239,222, 61, 28, 22, 22,118,250,218,181,107, 51,229,114,121,199,143,238, 34,142,141,213, 96,181,231, 93,136, - 68, 75, 2,156,101,211,191,235, 76,201,226, 83,215,221,150,246,178,123, 89,153,185,170, 68,243, 54,164,186, 37,245, 93,101,211, - 23,117, 7,249,225,196, 86,183, 31,123, 88,191,172,204, 92, 25, 67,120,120,248,181,192,192,192, 78,123,246,236,217,166, 82,169, - 70, 84,102,174,222,138, 41,147,134, 98,221, 28,232,120, 1,160, 16, 85, 16,154, 87,128,225, 61, 70, 6,210,255, 41,183,236,102, - 26, 77, 0,224,255, 33, 53, 41,165,247, 1,248,253, 19,179, 40,165, 52, 19,192,177, 15,172,121, 21,192, 85,238,213,205,193, 25, -172,119,112,229,202,149, 64,238,210,115,252,183,185,120,241,162, 26,192,119,165,203,199, 71, 57,147, 21, 88, 67, 58,246,207, 81, - 82, 5, 40, 73,130,128, 93, 81,101,115,245, 22,147,213,200, 77, 58,225,192, 72,169, 2, 20,105,160, 88,254, 62,230,170,188,201, - 2, 80,179,218, 2,125, 34,181, 0,226, 64, 72, 60,230,226,221,141, 21,231,226, 85, 61, 6, 7, 7, 7,199,191,198, 96,113,112, -112,124, 64,147,181,191,206, 29,100,241,166,128, 65, 77, 64,159,128, 98,125, 26,198,198,107,222, 83,243, 22,178,200,120,240,224, - 13,145, 62, 22, 69,154, 52,140,122, 15,205, 15, 77,137,121,122,183,129,154,195,101, 13, 14, 14, 14,206, 96,113,112,112,188, 15, - 37, 81,157,164,210,229,159,171,201,193,193,193,241, 47,130, 0,104,251,142, 15, 68,163, 27,175, 17, 66,218, 86,227, 3,244, 44, -167,201,105,114,154,156, 38,167,201,105,114,154,255, 46,205,202,180, 63,154,198,243,255,205, 46,138,224,186,176,114,154,156, 38, -167,201,105,114,154,156, 38,167,249, 47, 92, 24,112,112,112,112,112,112,112,112,112,124, 80,254,214, 54, 88, 50, 27,111, 71,240, -153,122,132,165,190, 0, 64, 25, 18, 5, 61,251, 80,145, 21,147,250,190,218,196,190,174,204, 68,192,219, 85,164, 51,124, 74,211, - 31, 41, 62, 68,122, 9, 33,205, 80, 50,188, 64, 66,105,119, 97,227,246,179,241, 54,177, 55, 55,105,175,209,104,189, 68, 66,126, -106,122,161,230, 15,154, 25, 89,204,101, 63, 14, 14, 14, 14, 14,142,127,153,193,242,110,210,243,138,137, 76,238, 5, 0, 6,150, -194,192, 2, 5,185, 25, 55, 18, 30,158,233, 9, 0, 78,254,109, 14,136,229, 54,161, 6,150,130,165, 20, 6,150, 66,167, 86, 62, -203,140, 60,102,212,204,243, 38,118, 62, 61,219,182,111,219,171, 75,151, 79,124,234, 6,212,245, 4,128, 71,143, 31,197, 30, 61, -122, 44,218,196,206,231,207,162,140,232, 3,239,115, 98, 38, 2,193,119,193,141, 66, 58,220,185,115,107, 38,128,111, 63,208,245, - 18,210,171,157,183,147,102,199,219, 84,101, 39,123,115,147,246, 61, 58,183,247,157, 50, 97, 20, 25,254,205, 98,151,194, 43, 23, - 38,201, 29,235, 22, 82,170,190,174, 76,127,118,143, 82,202,114, 89,145,131,131,131,131,131,227, 95, 96,176, 76,100,114,175,115, - 7, 55,217, 29,184,154, 8, 0,104,219,208, 1,243,126,218,210,131, 16, 18, 13, 0,189,191,254,201,251,187,137,195,112, 61, 34, - 3,148, 82, 52,240,178, 70,247, 79,199, 24,117, 80,169, 67,157,224,254,253,250,125, 58,101,202,228,110,207,158, 61,139,223,189, -123,247, 21, 0,104,222,162,133,215,162, 69,139,250, 45,179,180, 18, 75, 29,234, 36, 43,211, 34,239, 84,203, 92, 57,120,218,248, -249, 7, 15,223,189,241, 71,126,171, 78, 3,190, 48,113,240, 92, 94,148, 22,155, 85, 29, 45,177,171,127, 77,115,129,112, 30, 97, - 24,190,185,157,187, 29, 0,152, 57,250, 29,183,243,108,102, 48,177,176,123, 80,172, 84,110,203,120,114,114, 99, 69, 19,118,106, - 52, 90,175, 9, 95,127, 78,238, 63,207, 70, 77,255,102,204,170,197, 51,193,234,245,102, 19,103,204,111,127,235, 22, 0,224, 46, -151, 21, 57, 56, 56, 56, 56, 56,254, 5, 6, 11, 0, 76,164,124, 68,191, 72, 3, 0, 88, 72,129, 47,135,246, 65,122,122,154,183, -214,192, 98, 72,255,158,184, 23,149,138,232,184, 76, 80, 74,225,237, 34, 51,250,160, 60,176, 65,159,127,241,121,203, 83,167, 79, -223,254,110,214,119,219, 9, 41, 25,189,123,195,175,191,133,206,158, 51,123,196,224,161,131,219,237,223,191, 63, 2, 64,181, 12, - 22, 35,176, 88,241,195,162,185, 38, 73,153, 42,213,132,201, 83,121,147, 38,142, 91, 6, 96,104,117,204,149,159,171,203,247, 87, - 78,239,151,201,100, 50,108,220,184, 81, 12, 28,194,192,110, 45, 68,157, 63,249, 4,181,125, 3,154,252,184,102,119,189,211, 34, -209, 23, 54,222,237,122,102,197,156,121,107,213,166, 72, 36,124, 54,119,201, 47,190,212,194,151,204, 28,217, 9,117,106, 57, 34, - 57, 51, 31, 45,218,119,231,221,190,125,183, 9,103,176, 56, 56, 56, 56, 56, 56, 62, 46, 42,108,228,110, 48, 80, 68,199,165, 34, - 58, 46, 21,183,163, 50,161,101,121,248,105,225,116,252, 48,119, 42,178, 21,192,129,235,137,136,137, 75, 67, 76, 92, 26,178,114, -139,254,178,255,155, 93, 45,127, 90, 34,107,184, 98,133,249,143,237, 91,200,195,172, 44, 45, 45,159, 70,108, 47,158, 61, 41,221, -111,222,132, 68,161, 64, 98,159,100,105, 95,163,201,190,253,251,235,216,219,218,201,205,204,204,167, 90,249,182,223,100,225, 30, -102, 94,145,230, 95, 76,161,131,127,203,174, 93, 59,119,118,176,183, 99, 71,173, 8,143,170,227, 91, 91, 95,219,219, 55,204,196, -193,167,229,187,246,121,155,166,216,213,191,166,167,163,253,247,151, 78,238,151,169, 84, 42, 60,126,252, 24,217,217,217,165,219, - 3,246,246,142,112,115,113,194, 47,139,167,200,230, 78, 31, 19, 40,150,200, 14, 17, 66,200,219, 52,211,243,139, 78, 31, 59,113, - 38,253,216,158, 95, 88, 0,200,204, 45,198,133, 59,207,112,247, 73, 98,149,110,214,127,163,235, 42,167,201,105,114,154,156, 38, -167,201,105,254, 19, 52, 63, 54, 42,140, 96,197, 38,230, 32,250, 69, 26, 6,119, 9,130,139,179, 35,110,199,228, 34,191, 88,135, -188, 98, 45,242,138,181, 96,249,166, 72, 43,200, 67, 65, 78, 58,158, 38,100,161,178,137, 41,120, 98, 65,255, 9, 19,242,167, 20, - 45,172,157,122,241,196, 88, 56,219, 62,173, 51,109, 90, 94,187, 21, 43,204, 53,118, 14, 22,126,163,135, 15,233,112,232,192, 31, - 68,163,214,192,195,221, 85,210,188, 93,247, 97,191,109,217,233, 0,160,147, 49, 39, 99,107, 91, 71, 46, 54, 49,217,254,253,119, -147, 37,139,127,143,142, 47,214,160,248,207,235,233,207,167, 76,159,109, 54,242,179,126,191,218,218,214,105,144,105, 68,227,114, -177,171,127, 77, 55,107,235,239,175,158,218, 47,211,106,213, 72, 77, 77,133, 70,163,129, 94,175, 47,249, 93, 34,129, 88, 34, 65, -129, 82,143,172,124, 53, 90, 54,111,194,107,120,234,170,175, 86,171, 29, 9, 96,253, 95, 50, 98, 86, 76,145,169,115,128,252,248, -161,189,204,158, 51,247, 97, 33,151,226,250,189,103,184,123,249,184,129, 82,245,245,178,237, 76,157,106,123, 3,146, 83, 32, 68, -252,106,103,194, 38, 21, 38, 61, 10,226,178, 42, 7, 7, 7, 7, 7,199, 71, 96,176,138, 20,197,207,134,142,154, 12, 79, 59, 7, -243,238, 97,126,162,240,216, 60,100,166, 38,224, 89,204, 99, 40, 84, 58, 8, 45,107, 2, 18, 7,184,123,184, 33, 42,233,154,102, -253,186,219,249,172, 94,245,236, 93,122,221,187, 59,185, 56,218,202,153, 31,151,214,184, 25, 19,157, 27,184,107,214, 22,124,250, -169,137,205,143, 75,107,220,140,127, 46,103,100, 98, 67,147,161, 3,186, 19,232, 20,152, 54,109, 10,186,119,233,136,207,135,245, - 35, 59,119,255,222,216,216,147,209,136, 36, 75,102,127, 55,223, 52, 45, 79,171,189, 29, 83,164,150,201,165,210,107, 79,139,138, -253, 61, 44,165,221,250,143, 42, 56,184,123,205,124, 0,147, 42, 51, 87,142,102,102,223, 95, 63,251,135,140, 82,138,228,228,100, -104,181, 90,232,116,186, 87, 6,203,194,194, 2,121,197, 90,104, 50, 20,200,200, 83, 67,111, 96,209,169, 99, 39,217,221,123,145, -131,222,102,176, 0,128,101, 9,171,215,107,113,224,244, 93, 36,222,217, 71, 9, 17,190,106,228, 94,102,174, 28, 28,106, 92,238, -210,107,136,173, 72, 82, 82,221, 90, 88,172,198,182,245, 75,185, 92,202,193,193,193,193,193,241,177, 24,172,152,235, 7,154, 3, - 64, 96,219, 33,233, 38, 18,190, 29,159, 33, 72, 79,138,197,182,101,227,193,178, 20,157, 71,252, 8, 83, 15, 7, 72,133, 60,168, -139,115,242, 83,239,239,179,175,232, 64,132,232,218,173,217,144,236, 49,102,116, 45,179, 93,187,138, 4, 0,176,107, 87,145, 96, -244, 40, 87,179,181, 27,226, 60,154,180,105, 9,106, 48,160, 75,247,222,232, 63,160, 63,226,211, 20,248,227,242, 75, 40,148, 90, -163,230, 63,147,216,123,187, 59,185,122,245, 30, 63,184,141, 41,159, 71, 72,109, 55,115, 94, 98,166, 78,207,227, 9, 12, 71,238, -228,167,244,234,218,195,230,204,145,157, 29, 37,246,222,171, 85,233, 49,241,239,210, 49, 23, 8,231, 93, 59,253,135,140,199,227, - 33, 33, 33, 1, 90,173,246,213,162,211,233, 74,140,143, 82,135,212,108, 53,132, 58, 37, 50,242,212,200, 45,214,194,209,204, 2, - 58,157, 46,224, 93,186, 6, 86,125,164,107,207,193, 93,193, 80,134,165,244,160, 42,237,209,171, 52,148,153,171,142,221, 63,181, -189, 28, 30,139,103,119, 79,228, 82, 86, 95,114, 48,194,114, 83,149,112,112,112,112,112,112,252, 63,195,168,129, 70,147,211,115, - 96,109,194,135,173,147, 7, 6,141,255,169,196, 48, 24,116,160, 20,208, 27, 88, 24, 51,103, 61,165,130, 51, 95,141,246,136,115, -247, 32,249,131, 62,149, 41, 1, 96,208,167, 50,165,187, 7,201,255,106,180, 71,156, 66,107,169,213, 27, 12,184, 22,145,129, 31, -247, 62,193,236,173,143,112,242,174,241,195, 97,241, 5,210, 9, 63, 44, 94, 36,227,243, 8,137, 72, 40, 42, 74,202,214, 23,241, - 4, 2,173, 76, 38,162, 26,202, 87,199,103, 26,178, 59,246, 29, 29,207,227, 9,198, 84,158, 86, 22,148, 82,168,213,106,104, 52, - 26,104,181, 90,104, 52,154, 87, 6, 43,191, 88,135,212, 28, 21, 18, 51,149,120,153,169, 68, 82,166, 18,233,185, 42,188,171, 35, -161,169, 83,109,111,107, 11,171, 11,214,150,166,211,173,204,204,166, 90,152, 88, 92, 44,169, 14,124,221, 92,221,140, 72, 65,236, -253,179,233, 6,173,162, 95, 97,242, 3,251,194,228, 7,246, 92,245, 32, 7, 7, 7, 7, 7,199, 71,104,176, 88, 0, 79, 19,178, - 32,226,179,112,113,247, 4, 45, 55,129, 61, 5,160, 55, 84, 60,169,125, 25,135, 14,165, 36,213,242, 42,102,167, 78,125, 25, 26, - 80,215,250,225,232, 81,174, 81, 1,117,173, 31, 78,157,250, 50,180,150, 87, 49,171, 51,136, 12,148, 82,176, 20,165, 11, 5, 53, -198,185,149, 66, 8,175,113, 3, 95, 55,254,188, 93, 79, 95,142, 89, 27, 19, 45, 20, 10,117, 46, 54, 50,226,102, 47,227,213,176, -149,138,212, 58, 70,237, 83,183,145,150, 0, 13, 43,210,201,215,105,231, 52,235,208, 87,161,213,234,225,234,234,250,154,185, 42, -171, 34,204, 87,104,145,154,171,194,203, 76, 5, 18, 51, 21, 80,168,245,120, 28, 19, 7,194,240, 30,191, 77,211,204,212,234,212, -177,131,251,106,212,247,171,101, 87,199,219,221,110,227,214,237, 53, 36, 18,139, 83,166, 78,181,189,107,120,248,132,223, 58,251, -187,237,205,136, 20, 36, 68,223, 77,211,171, 11,118, 23,167, 71,157,227,178, 38, 7, 7, 7, 7, 7,199, 71,108,176, 0,192,205, -197, 30,183, 30, 39,192,205, 86, 2,115, 51, 83, 68,197, 38,129,199, 8,192, 16, 64,167, 55,222, 4, 81,173,110,239,207, 63,155, - 47, 75,136, 51,220, 90,187,238,249,179,132, 56,195,173,159,127, 54, 95, 70,181,186,189, 64, 73,239,188, 18,147, 85, 98,180, 12, - 85, 24,126,147, 82,214,206,214, 66,194,191,251,188, 56,155, 97,120,106,107,115, 9,107,109, 46,102, 28, 45,196, 2, 23,107,161, - 80, 36, 98,224, 96,107,163, 7,165, 21, 86,101,170, 19, 35, 94,164, 22, 20,204,108,222,190,183, 66, 32, 16,192,195,195, 3, 26, -141,230,181, 70,238, 25,153,185,175, 34, 88,169, 57,106, 72, 69, 12,238, 95, 59,167, 48, 24,116,219,222,166,201, 19, 8,205,109, -108,172,241,237,130,159, 49,117,206,207, 72, 46,224, 67, 40, 22, 59,184,123,248, 63, 24, 58,102,150,236,235, 13,207, 48,180,133, - 57, 20, 89,177,201,138,116,201,116, 46, 91,114,112,112,112,112,112,252,255,166,242,169,114, 40, 96, 34,147,128,242, 36,184, 18, - 30, 11,159, 58,245,176,245,240,109,120,213,109,140,212, 66, 61,170, 50,157,225,228,233,138,123, 0,238,117,239,238,228,210,179, -167,115, 59, 74, 5,103,214,174,207, 79, 2,128, 77, 71,122,129, 2, 96, 89, 90, 98,180, 74, 71,136, 55, 22, 2,164, 36,164, 23, -154,122, 56,200, 17,153,164, 85,203,197, 66,198, 82, 46,226,217,154,139,132, 66, 62, 31, 6, 74,212,217, 57, 25,133, 0, 73,169, - 76, 75,157, 24,241, 66,236,234, 63,179, 69,167, 1,223, 95, 57,249,187,204,211,211, 19,247,239,223,127,101,176, 10,139,138,145, - 83,160,132,204, 10,240,118,145,227, 73,248, 21, 67,118, 70,114,100,110,204,201,141,111,211, 99, 89,240, 84, 90, 3, 30, 60,207, - 71, 94,177, 14,121, 69, 90, 52,109,213, 85,216,180,109, 55, 92,126,156,133,220,124, 5,230,110,249,179,192, 64,117,253, 41,141, -212,113,217,146,131,131,131,131,131,227,255, 55, 70,185, 35, 3, 75, 97, 99,109, 5,137,220, 12,113,233, 90, 20, 18, 59,228, 42, - 40, 12,134,138, 35, 88,132,144,182,111, 91,127,232, 80, 74,210,193,131,153,155, 14, 29, 74, 73, 42,239,228,216, 87, 85,132,165, -127, 89,106,180, 38,165,134, 19, 71,206, 92,207,233, 22, 98,107,201,240,120, 74,161,128, 81,243,133, 60,173,144,207,232,132,124, - 70, 99,111, 38,224,157, 63,188,147, 33,132,158, 55, 70, 83,157, 24,241, 34, 46, 35, 99,102,235, 46, 3, 21,118,246,246, 24, 60, -120, 48, 92, 93, 93, 1, 0, 38, 18, 2, 27,145, 2, 60, 85, 10, 46, 29,222, 92, 28, 21,126, 33, 28, 6,117,207,242,163,185,191, -166, 73, 41,155,149,167,134, 82,163, 71,110,145, 22,185,197, 90,232,109, 67,113,240,122, 10,178,242, 53,136,189,190, 93,161, 86, -228, 78, 80,165, 63,141,171,208, 68,190,227,220,223, 7, 78,147,211,228, 52, 57, 77, 78,147,211,252, 39,104,126,108, 24, 49,217, - 51, 69, 45, 71, 57,188,156,229, 80,105,237,160,210, 24, 80,172, 50,160, 64,161, 69,129, 66,135,184, 52, 5,158, 94,120,255,132, - 80, 0,148, 5, 8, 74,170, 10, 65, 74,140, 29, 37,198,237, 95, 44, 40, 88,246,227,162,185, 3,246,236,251, 19,227, 62,113,116, -125, 24,167, 73, 33,132, 81, 50, 60,190,206,202,148, 47,120, 30, 27,157,122,233,244,254,160, 98,145, 98,184,177,105, 42,139,100, -249, 52,108, 61, 15, 20,124,141, 50, 95, 62,189,105, 29, 60,120,240, 80, 21, 21,155,166,231, 73, 44, 30,178, 6,237,142,220,152, -138,167,202, 97,132,146, 39, 55,195, 31, 53,150, 90,187,161, 72,169, 67,161, 82, 7,133,186, 36, 26,246,242,254, 33, 77, 94,114, -212,239,133,201, 15,182,114,217,145,131,131,131,131,131,227, 95, 98,176, 20, 74,197,179,118,189,134,191,154,208,217, 96,160, 96, - 89, 10, 67,105,132,137,165, 20,122,173,242,217,251, 38,196,192,178,183,215,109,221,211,185,126,131,198,188, 58, 53, 76, 80,144, -155,137, 59,183,110,232, 41,203,222, 48,202,160,197,199,171, 77,236,125,251,245,235,221,115,207, 23,163,198, 21,180,104,209, 74, -108,109, 99,166, 77,207,204, 40,216,185,113,183,225,232,159,123,130,192,178, 67,104,124,188,186, 42,233, 82, 39, 70,188, 0, 48, -168,212,177,183, 6,234,180, 84,102, 62,237,162,200,136, 57,111,172, 70, 86,114, 98,175,159,126, 88, 24,223,109,208, 87, 34, 75, -123, 79,104,116, 60,164,167,167,227,249,237, 3,170,162,148,136,131, 69,201, 15,134,115, 89,145,131,131,131,131,131,227, 95,100, -176,158,222, 40, 25, 15,235,191, 77, 78, 78,250,224, 29,187,255, 92,184,115,239,225,166,106,173,214,153, 5, 47,209,160,211, 93, - 18, 23,102,207, 54, 86,163, 40, 61, 42,146,184,187, 7,253,246,203,178,137,191,174,249,185, 13, 88,131, 15, 8,137, 35,132,158, - 47, 18, 42,190,172,170,185,122,155, 87, 34,205,142,183, 7, 80,165,137,163, 21, 89, 81,105, 38,246,181, 92,119,255,186,244, 71, -134,225,181, 55, 24, 88, 1,107,208, 61, 51,104, 85, 63, 40, 51,163, 15,211,170,116,151,228,224,224,224,224,224,224,248,255,111, -176,254, 87,228,196,222, 42, 4, 48,238,125,117, 74, 77,212,226,210,229,131, 66, 41,125, 12,224,113,117,246, 45, 74,127,158,137, -106, 76, 56,205,193,193,193,193,193,193,241,255, 15,134,187, 4, 28, 28, 28, 28, 28, 28, 28, 28, 31, 22, 2,224, 29,189,242,140, -159, 41,187, 58,189, 9, 42,211,231, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78,243,227,211,172, 76,187, 42,254,227, 31, 13, 45, - 29, 49,253,191,177, 0,104,203,105,114,154,156, 38,167,201,105,114,154,156, 38,167,249,111, 91,184, 42, 66, 14, 14, 14, 14,142, -127, 29, 54,222,221, 76,108,188,187,153, 24,187,189,109,157,190,246,182,117,250,218,115, 87,142,195, 88,248,220, 37,120,127, 8, - 33, 98, 0, 44,165, 84,251,119,165,193,210,178,166,153,222,212,230, 0,195,170,127,200, 79,124,120,230, 67,159, 95,157, 58,117, - 26, 0, 64,100,100,228,125, 74,233,251,246,198,132,220,222,103,160,165,153,197, 72, 45,171, 49, 40,138, 21,235,138,210, 98,246, -127,200, 52,219,218,214,145,107,196,210,165, 32,180, 19, 40, 24, 74,200,121, 94,161,110, 98, 94,222,131,252,138,246,171,209,125, -177,239, 23,253, 62,153,181,233,247, 99, 11, 95, 30,154, 17,245,230,239, 86,157, 86,155,142, 29,210,126,218,154, 61,135,150,100, - 29,158, 90,196,229,254,170, 83,163,217,167, 22,122,190, 3, 47,229,226,178,236,170,236,231,226, 19, 26, 33, 16, 8,108,181, 90, -109, 70,114,204,205, 0, 99,246,113,245,109,114,143,199, 99,156, 12,122, 54, 41, 49,250, 58, 55,113,186, 17, 72,237,106,133, 66, -175,255,150, 2, 4,132,255,147, 42,251,249,123,141,116,232,228,228, 36, 53, 55, 55,111, 97,102,102,230, 42,147,201, 36,185,185, -185,202,220,220,220,151, 9, 9, 9,231, 41,165,250,191,227, 28,109,253,123,204,224,139,152, 57,165,255,158,151, 25,113,112,113, -197,219,119, 95, 72, 24, 50,163,244,223,139, 51, 35, 14,205,250, 39,220, 43,251,186,189, 66, 64,217,137, 12,195,107, 98,160,250, - 69, 25,143, 14,173,173,202,254,161,161,161, 61,116, 58,157,184,236,255, 2,129, 64,125,227,198,141,131,220, 83,240, 55, 25, 44, -151, 58,125, 45,117,124, 58,151,207, 99,122,179,148,154,166,222,223, 39,255, 39,159,160, 91,200,144,187, 12,195,184,148, 95,199, -178,108, 82,194,173,237, 31,164,176, 37,132,184,252, 52, 33,112, 90,122,182,178,128, 16,178,224, 93,230,195,190,193,192,235,132, - 33, 53, 9, 33, 96, 24, 2, 94,201, 0,170, 41, 47,111,237,104,248, 22, 77, 71, 51, 57,223,187,160, 88,255,152, 82, 90,233, 75, - 72,106, 93,219, 73,102,237,124, 41,172,199, 88,143,187,167,183,248,153,216,251,182, 41, 74,143,138,252, 0,231,102,235,233,233, - 25,236,237,237,109, 61,118,236, 88, 33, 0, 44, 95,190,220,203,203,203, 43, 59, 54, 54,246, 14,165, 52,179, 90,230,202,206,119, -240,202,101,243,183,119,234,212, 25, 41, 89,197, 88,250,243,154, 48, 19, 7,239,190, 31,202,100, 17,167, 64,169,133, 92, 30,241, -245,196,217,206,157, 91, 5,243,115,139,181, 56,126,254,246,160,253,155,126,104,109, 97, 81, 63,160, 34,147,197, 42,242,103,217, -155,208,142,172, 34, 31, 0, 6,190,249,187,179,137,174,173,173,212,208,209, 81,204,191, 15,224,207, 74, 95, 46,193, 67, 79, 9, -132, 66, 55, 66, 24, 48, 4,224,241, 8, 24, 66,192, 16, 64,175,211, 36, 60,187,178,185,195, 63,162,160, 14, 28,156, 70, 8,177, -102,152,146,244, 17, 2, 48, 12, 3,126,201,200,191, 5,207,175,111,177,254, 0,249,201, 60,192,203,194,255,147,166,205, 54, 95, -122,145, 35,175,209,114,226, 49, 66,153,181, 9,151,127,122, 96,204,254, 18,137,196,242,200,145, 35,182, 29, 59,118, 52,183, 15, -232,113,201,152,125, 76, 68,146, 58, 71,143, 30, 22,118,236,216,161, 10,249,211,167, 29, 24,102, 7, 1, 4, 44, 75,151,243, 88, -250,123, 81,118, 76,108, 85,135, 83,177, 11,232, 49, 31, 4,126, 70,239, 64,241, 36,227,241,193,217,213,188,182, 60,169,157,207, -103, 82,137,100, 74,109, 31, 63,239,184, 23,177, 49, 5, 5,249, 63, 43, 51, 98, 54, 81, 74,217, 42,137,233,244,223,156,189, 18, -222,137, 47, 16,144,142,109, 66,120, 0,222,203, 96,217,219,219,247, 88,189,122,117,173,208,208, 80, 0,128, 94,175, 55,219,183, -111,159,195,130, 5, 11,228,198, 60, 67,111,195,217,217,217,217,220,220,188,134, 84, 42,117, 6, 0,165, 82,153,156,159,159,255, - 50, 57, 57, 57,185,178,125, 29, 26,244,181, 97, 24,204, 63,249,231,175,124, 0,232,208,107,228, 66,143,176,111, 44, 9, 79,160, -124,219,246, 6,189, 70,206, 16, 50,241,220,145, 45, 4, 0,218,116, 27, 54,221,182, 78,223, 95, 50, 35,247,165,255, 45, 31,244, -125,251,242,108,158,106,123, 16, 74, 38, 5, 6, 5, 55,238,221,189, 19,252, 60,157,208, 99,192,232, 41, 0,170,100,176,116, 58, -157,120,255,254,253, 46, 12,195,240,244,122,189,170, 95,191,126, 25,239,147,182,218,205,134, 94, 7, 33,174, 90,189,254,183,132, -155,158, 11, 41,157,195,190,153,118,199, 56,254, 76, 16,102, 4,101,217,196,212,123,187,155,112, 6,171, 20, 27,239,110, 38, 60, -177,240,113,171,230,141,173,167,143,238, 41, 90,255,251, 21, 56, 53,232,151,156,114,255,119,231,127,234, 9, 50, 12,227,114,112, -215,106, 59,153,136, 7, 0, 40, 82,233,209,107,112,229,163, 65, 56, 7, 15,186, 8, 2,159,178, 58, 84,131, 65, 47,225,243, 5, - 42, 2, 0,164,164,119,128, 84, 42,186,185,105,102,104,254,176,174, 53,135, 76,251,229,222, 86, 0, 22, 0,210,222,250, 80, 48, -140,203,158,205,203,237,156,173, 37,224,243, 8,138,148,122,244, 28, 50,201,240, 54,195,182,105,102,232,252,193,157,220,251,219, -117,252,163, 23,128, 19, 21,190, 64, 28,234,248,154,218, 56,157,233, 61,114,190,147, 2,102,248,110,225,114,187,107,167,247, 93, -105,219, 99,184,246,101, 82,146, 66,175,213, 69,103,231,164, 78, 46, 76,137,121,106,108, 65,109, 98, 98, 82,203,196,196,164,126, -167, 78,157, 36, 83,166, 76, 17,132,133,133,189,250,253,203, 47,191, 20, 94,188,120,209,113,217,178,101,157,157,156,156, 84, 69, - 69, 69, 15,138,138,138,158, 83, 74, 13,198,222, 19, 7, 7,219,175,123,247,236,138,214,189,190,130,129, 37,248,114,204, 68,156, - 58,241,231, 40, 0, 31,196, 96,153,240,152,121, 35,198,126,235,220, 34,180, 33,127,241,190,167,176,144, 9,209, 62,164, 33, 95, - 34,248,198, 97,247,111,203,126, 6,240,249,219, 34, 87,172, 34,127, 86,128,141,102, 64,183,208,154, 56,188, 91, 51,192,165,237, - 52, 48, 50,243, 87,145, 44,207, 78,227, 76, 45,165,210,213, 78, 22, 60, 59,177, 33,115,181,103,167,113,103, 99, 79,172, 42,172, - 40, 45, 2,161,208,109,211,234,239,107, 91,154, 10,193,103, 8,120, 60, 2, 62,143,129, 74, 99,192,144,209, 51, 62, 84,132,145, - 39,181,171,221,153, 1,134, 1, 0, 11,108, 81,102, 60, 61, 94,149,123, 66, 24,158,245,190,205,203,248,118,230, 98,240,120, 4, - 60, 6,224, 49, 4,241,233, 74,140,157, 50,215,252,125,141,122,167,166,118,193, 23,127,105,217,161,113,128, 85,189,189, 55,136, -121,227, 78,253,173,179, 84,178,207,246, 28,186, 48,160, 70,139, 73,183, 40,101,127, 76,188,178,226,116, 69, 58,106,181, 58,189, - 67,199, 78,102,132, 47,151,157, 61,184,181, 5,159, 33,208, 25, 40,244,134,146, 65,144, 89, 74, 81,242,221, 82,242, 17, 67, 89, -138, 17, 35,190, 64,135,142,157, 20,172,158, 77,170, 66,161,177,227,228,217,107,182,106, 29,139,101,171, 55,205, 47,206,207,156, -255, 34,202, 58, 94,102,239, 61, 81,145, 30,115,216,248, 19,135, 95,204,245,125, 61,119, 29,189,137,128, 58,126, 37, 3, 53,179, - 20, 62, 46,114,236, 58,118, 19,190, 62,190, 37,233,102, 41,188, 93, 77,208,242,147, 33,213,188,190, 97,124,185,189,239,238,110, -125,134,246,233,213,103, 32,172, 44,205,160,209,170,189,207,157, 58,254,235,186,213, 75,155, 18, 66, 62,171,146, 57,164,134, 87, -239, 5,202,178,239, 93,203,225,228,228,100, 27, 28, 28,252,234,255,122,189, 30, 30, 30, 30, 72, 78, 78,246,169,134, 89,147, 57, - 57, 57,125,178,116,233, 82,187, 86,173, 90, 9,108,109,109, 1, 0,153,153,153,206,151, 46, 93,106,216,176, 97,195,140,148,148, -148, 99,233,233,233,138,119,154, 10, 86, 37,228, 81, 62, 79, 44,150,150,250, 90, 48, 83,198,126, 90,207,214,214,246,173, 31,199, -217,217, 57,162, 57,115,102, 19, 62, 95, 80,178, 61,165, 12,101, 13,239,156, 99,164, 73,147, 38,221,180, 90,173,228,109,191,101, -233,109, 59,171, 88, 81,255,146,183, 8,192,231,241,114, 83,238,239,183, 53,218,180,215,235,222,222,145, 17,172,235,218,189,187, -123,143,206, 97,112,180, 53,199,249,155, 49, 24, 63,243, 39,232,244,134, 21,213,185, 63, 60, 30,143,159,145,145, 17,111,105,105, -233,240, 1,222,183, 53, 15,237, 90,101,119,225,202,221,233,191,136,247,140,174,213,108,152,174,164, 61, 82,201,204, 44, 62, 18, - 51, 65,203, 30,109,205,172,156,125, 37, 27, 87, 47, 22,112, 17,172,242, 55, 66,196, 91,208,172, 73,176,245,244, 9, 95,136, 22, -108,186,132, 27,167,142, 41, 83,238,239,251, 32,230,202,212,206, 39,148,240,248, 35, 9,143, 39, 39, 12, 17,177, 6, 54, 81,175, -209, 44, 84,100,197,164,190,175, 54,203, 82,252,113,189,138,198,156, 82,175, 95,127, 89,102,103,111, 33,134, 74,107,192,176,175, -191,195,134, 21,243, 77,109,205, 69, 80,107, 13,216,122,248,110, 86, 93,197,114, 58,172, 99,205, 33,223,111,138,248,243,199, 29, - 81,127,150, 60,171,239,204,120,176, 51, 23,227,251, 61, 49, 48,147, 10, 96,105, 42, 4,195,188,221, 92, 13,235, 90,162,153, 87, -168,209, 19, 66, 68,148, 82,205, 91,141,132, 99, 64,115, 51, 91,151,253, 61, 71,204,183,141, 73, 39,160,208, 34,214, 76,130,222, -131, 71, 91,212,114,144, 66, 46,225, 33, 62, 49,213,227,155,169, 83,131, 36,142,190,193,170,212,168,151,149,157,182,187,187,123, -175, 46, 93,186,200, 38, 79,158, 44,112,117,117,197,142,125,167,220,218,245, 25,215, 53, 57, 45,219,149,165,128,189,157, 85,226, - 23,253, 59, 31, 57,126,252,120, 66, 98, 98,162, 96,233,210,165, 33, 7, 14, 28,168, 83,149, 47, 81, 3,165, 80,169, 13, 48,148, -190, 24, 51,243,213,213,120,169, 16,230,221, 95,230,180,123,135,176, 96,254,242,131,207, 81,168,208, 67, 38,226, 35, 54,181, 24, -161, 33,193,252,189, 27, 73,171,183,237,241, 69,191, 79,102,217,155,208,142,221, 66,107,194,206, 82,134,205,191,124,143,195, 55, - 94,116, 76, 47, 34,176,233,182,116,164,163,152,223,206, 86, 38, 92, 29, 22,228,233,208, 58,208, 13,119,130, 60, 29, 46,135, 71, -199,212,237,247,243,216,228, 34,193,217,156, 19, 99,223,106,180, 24,194,192,202, 84,136, 77,167, 18, 32,147,240, 33,151,240, 33, - 23,151,252,101, 24,242, 94,249, 90,234, 84,199,149,199, 26,190, 48,115,170,243,197,128,126,125,157, 62, 29,208,151,130,199, 96, -223, 31, 71,186,239,220,185, 35,213,196,193,103,163,129,225,109, 82,166, 68, 38, 86,126, 61, 1, 59,115, 17,190,217,248, 24,102, - 82, 1, 76,101, 2,152,201, 4,104, 93,207,182,218,233, 36,132, 88,142,234, 94,171,243,195,237,109, 91,249,212, 48,169,253, 32, - 54, 63,242,139,133,119, 87, 92,204,107, 53,225,151,229,117,172,139,242, 52,252,217, 83, 70,240,147, 82, 82, 90,237, 59,114,169, -181, 83,163, 47,162,245,218,226,111, 51, 30,252,126,232,109,122,137, 81,215, 27,186,132,246,149,104,139,116,143, 30, 68, 39,121, -230,170,197,136,136, 47,128, 92,194,135, 73,217,181,149,240, 33,151, 8, 96, 34,225, 35, 37, 41, 14, 57,197,188,171,201,214, 76, - 43,122,241,122,149,170,162, 84, 90, 3,238,191, 40,130,187, 79, 3, 56, 58, 58, 65,211,121,144,251,173,243,127, 28,146, 59,250, - 45, 46, 78,125,242,173,177, 58,187,142,222,196,130,197,203,159,130,224, 73,233,219,220,111,242,164,177,181,127,250,121,245,107, -235, 70,127, 53,166,118,117,205,181,204,222,103,103,203, 79, 6,247,169,219,184, 61,158,199,197,225,196,145,187,104,211,174, 19, - 58,119,237, 5,141, 70, 61,100,211,134, 85,119, 0,172,249, 75,153,235,232,215,172,110,128,223, 78,103, 39, 39, 87,150, 45,153, - 3,150, 82,160, 89,203,214,152, 58, 97, 4, 88, 74, 81,191, 97,163,214,157, 7,140,165,148,150, 24,193,172,236,172,226,232,168, -200,182,202,244,168, 91, 70, 95, 75,149, 74,151,153,153,137,251,247,239, 35, 38, 38, 6, 17, 17, 17,200,206,206,134,185,185,121, -149,170,216, 45, 45, 45,205,130,130,130, 62,253,253,247,223, 37,230,230,255,241,252, 26,141, 6, 50,153, 12,221,186,117, 19, 52, -107,214,204,121,232,208,161, 67, 45, 45, 45,119,229,230,230, 22,188,213, 48, 61, 60,154,226, 80,183,199,250,206,125,190, 28, 13, - 0, 66,177,201,139,149,191,253, 25, 81,209,177,133, 18, 51,183,182, 61, 62,247, 4,165, 32,132,172,204,138,250, 51,237, 93,219, -106,181, 90,233,222,189,123,157, 9, 33,175,189, 95,231,173,220,211,244,241,179,180, 54,235,230, 78,227,155,153, 72,144,153,167, -198,200,209, 99,109,140, 54, 87,117,187,143, 9,110,216,112,205,119, 83, 70, 64, 46,147,226,244,173,231,152, 56, 99,137, 62, 39, - 43,125, 59, 8, 89,158, 25,113,224,125,107, 45, 62,200,128,215,181,157, 77, 96,218, 33, 84, 50,162, 95,152, 68,163, 51, 32,175, - 88, 7,181,214, 0, 3, 75,145, 95,172, 67,228,203, 66,216,152,137,176, 17, 31, 63, 85, 50, 88,124,129,168,203,184,207, 58,139, -150,237,186,133, 27,167,118, 41, 83,238,237,147,149,253,230, 26, 52,224, 69,226,221, 61, 53, 95,247, 40,149,119,181,148, 58,213, -113,229, 19,222,207, 45,195, 90,180, 31, 61,102, 12,124,106,185, 8, 13, 6, 3,125, 28,243, 66,183,117,211,230,207,204, 93,235, -174, 40, 72,122, 60,171,236,101, 90,213,238,155, 44,203, 38,189, 25,177, 98,217,215,191,102,223,166, 73, 8, 96, 97, 34,194,250, - 19,113,160, 20, 32,160, 48,151, 11,176,231, 98, 18,242,179, 83,178,234, 41,150, 95,251,162,163, 77,183,133,155, 34, 15,173, 61, -146, 30, 14, 32,130, 82,154,254, 46, 77, 66, 8,248, 60, 2, 51,153, 0,230, 50, 33, 44,228, 66, 48,132,188,211, 92,125,247,235, -195,173, 0,162,203,155,171,242,154,114,123, 31,127, 51, 27,183,131,189, 70, 45,182,124,248, 82, 11, 62,143,160,166,131, 20, 86, -166, 66,104,244, 4,241,153,218,210,125,204,240,213,228,121,182,211, 38,141, 62, 78, 72, 88, 61, 74, 47,234, 43, 58,119,133, 66, - 33, 26, 60,120,176, 64,167,211,105,135,141, 95,216, 62, 45, 35,187,251,138, 69, 83,197,182, 54,214, 40, 86,233,112,239, 73,130, -223,146,101,191,212, 60,118,238,230,193,111,191,234,121,168, 99,199,142,230,123,247,238,101,171,114,223, 51,211,179,126,217,188, -115,255,246,229,203, 22, 33, 58, 33, 23,155, 54,172, 1, 53,232,215, 87,236,119, 95,215, 92,189,122,181,125, 72, 72, 8,115,251, -246,237,172, 55, 13, 40, 33,144,103, 23,168, 97, 33, 23, 66, 38,230,195,222, 82, 2,107, 19, 17, 68, 2, 6, 12,243,159, 66,164, -188,230,166,223,143, 45,100, 21,249, 56,188, 91, 51, 96,243, 47,223,227,243,175,103,226,113,150,232, 36, 35, 51, 95,248,213,128, - 94,211,109,165,134,142, 78, 22,140, 93,235, 64,119,200, 37, 66,204, 24, 55, 24,141,194,227,237,146,243,216,153,153, 74, 94, 3, - 0, 51,223,150, 78,166, 52, 98,101, 42, 19,224,226,209,221, 25,197,133,121,249,132, 87, 82, 69,168,211,104, 19,140,243,250,127, -189,158,114,123,159,233,129, 13,234,125, 63,250,203, 47,152,166,161,141, 40,195, 8,144, 85,168, 33,148, 2, 19,198,142,194, 87, -163, 70, 56, 36,166,100,204, 94,179,102,253, 44, 19, 59,191, 5, 69, 25, 79,230, 86,164,201, 35, 12, 24,134,192, 68,194,135,137, -180,196,176,152, 72,248, 80,105, 12, 32, 4, 60,151,192, 1,249, 32, 0, 33, 36, 37,241,206,110, 63, 99,210,233, 84,183,211,185, - 75, 25, 66, 95,197,113,213,141,103, 79,239, 45,188,253,240,229,109, 74,105, 78,141,150,147,134,106,245, 20, 69, 42, 61,226,210, - 21,208,107, 41,249,188,147, 27, 60,250, 16,159, 69,155,239,109, 39,132,152,149, 69, 92,222,212, 76,186,177, 79,101, 83,183, 87, -255,229,171, 54,220, 89,246,253, 76, 94, 86,190, 6, 44,165,144,136,120,144,138,248,165, 11, 15,202,226,124,172, 89,247, 91,154, - 30,164, 23,189, 88,113,158,255,107,161, 65, 7,245,236,220, 98, 15, 1, 68,132, 17, 38, 57,185,185,187,181,233,250,153,164, 77, -183,193, 48,232, 53,211,229,246,190, 23,138,211,163,206, 25,163, 25, 80,199, 15, 32,120,146,241,232, 96,175,146,151,100,143, 63, -125,125,124,107,191,185,206,203,203,167,182, 49,247,189,236,227, 66,106, 91,251, 75, 47,223,186, 83, 71,127,183,193, 61, 46, 85, - 1, 43,215,218,136,120,116, 31, 39,246,254,114, 79, 89,152,187,236,196,225, 63,167, 46,248, 97,101,253,174, 61,250,225,208,129, -189,147, 9, 33,107,105, 9,103,203, 69,167, 6,109,221,248,171,171, 64, 36,134, 78,207, 66,103,160, 37,127,245, 6,228,228,228, - 66,167,103, 33,145,153, 66,207, 18,232, 12, 44,116,122, 22,106,141, 94, 62,106,240, 39, 99, 0,220,122, 91, 58, 61, 66, 6,223, - 5, 67, 92, 74,214,151,172, 19, 49,230, 10, 71, 71,199,237, 0, 32, 22,139, 33, 22,139,193,178, 44, 30,165,144, 9, 78,193,131, -102,128,150,190,217, 89, 54, 41,245,222,238,160,119,157,187,171,171,107,215, 55,205,149, 74,165, 66, 81, 81, 17,174,221,121,104, -190,109,223,217,142,241,137,105,181, 88,131,157, 90,234, 80,191, 3,128,174,239,186,158,105,143, 14,142,169, 17, 54,129,153, 60, -122,176,215,202,223,246,223,126,122,114, 65,133,225,228,154,109,167,107,166,142, 25, 24,244,195,202,205, 79,147, 46,173,152, 88, -217, 61, 18, 10,133,130,204,204,204, 87,207,247,252,213,127,116,122,153, 94,208,102,217,247,179,132,247, 94, 20,225, 81, 92, 26, -134,182,173, 97,244,243,238,232,223,211,199,205,195,117,197,138, 5,227, 17,147,162,196,234, 63,110,227,210,177,237,225, 90, 85, -225, 39, 25, 17,135, 51,170, 83,134,188,175,193,170, 72,243,194,195, 44, 20,169,244, 80,107,244,208,177, 20, 5, 10, 29, 50,242, - 52, 40, 80,104, 81,164,212, 99,104,187, 26,248, 55, 80, 37,131,101,208,235, 92,156,156, 28,193,210,164,178, 8,103, 73,212, 35, -100,128, 98,226,151,125,165, 78, 13,250, 20,167,220,223,111,116,155, 44, 83, 59,239, 38, 82,169,236,216, 79, 63,253,132, 1, 93, -155, 75, 95,102,233,138, 30,190, 84,166, 23,107,160,183,179,245, 22, 45, 92,180,196,100,201,210, 31,191, 58,122,152,205, 3,240, -227, 91,195,207,193, 3,239,242, 72,185, 54, 86,132,128,178,108, 82,210,157, 93, 65, 0,240, 62,109,173,138, 84, 58,240,152,146, -182, 51,132, 0, 10,149, 30,197,185,105,217,229,205,213,173,100,135,231, 60, 94,166,150, 82, 90, 97, 21, 4, 67,128, 2,133, 14, -230, 50, 1, 44, 76, 4, 48,151,255, 39,130,245, 14,115, 21, 81,145,166, 80,171, 77, 52,232, 53, 42,106, 48,160, 75,176, 45,236, - 44, 68,112,180, 20, 67, 44,226, 67,167, 7,148, 26, 22, 42,141, 1,241, 25, 74, 20, 42, 69,168, 23,214,223, 43,197,241,166,194, -198, 61,120,107, 86,252,157,145, 21,222,103,131, 1, 59,247,159,242, 74, 73,203,236,126,104,251,207,226,140, 2, 45, 30,196, 23, - 33, 35, 79, 13, 16,115, 76,159, 57, 75, 60,123,246,156, 30, 59,255, 56,157,208, 50,196, 47,161,170,215,181, 56, 35,106, 71,189, -166,159,252,210,165, 75, 15,211,136, 91,199,241,244,254,185,239,138,210,171,214,254,202,203,203, 75,255,203, 47,191,216,110,216, -176,193,203,206,206,238,101, 70, 70,198,139,178,234, 40,143, 58,161, 41,103,207, 93,177,110,209,180, 57, 63, 41, 75, 5,107, 83, - 33,220,237,229, 8,191,113, 65,195, 16,114,242,109,122,165,213,128, 3, 93,218, 78,195,225, 27, 47, 58, 70,100, 75, 46,142,248, - 98,104,194,233,203,209,217,171,183,159,254,193,217, 68,119, 95,194,102,174,190, 27,228,233, 48,125,236, 96, 44, 94,181, 3,151, -194,163, 51,138, 25,199,239, 83,213,250, 51,115,251, 79,125,123,212,151, 1,248, 60, 2, 83,169, 0,197,197,121,249,143,207,174, -245,254, 64,207,238,208,211, 7,119, 48, 57,133, 58, 36,102,169, 72, 74, 78, 33, 12, 44,133,133, 76, 8, 61, 75,145,151,147, 69, -118,238,216,142, 59,119,110, 48,224, 49,195, 1,204,173, 36, 18, 2, 30, 67, 96, 34, 17,148, 68,128,164, 37,127,117, 6, 22,181, -107,186, 98,229,252,113,102, 54,118,246,104,223,107,164,241, 17, 54,185,101,253,109,235, 22,226,226,141,251, 97, 23,158,237, 14, -182, 11,168,191,202,165, 78,223,101,140,149,179, 74,173, 53, 32, 63, 47, 23, 34, 77, 34, 26, 57,103,194, 74,102, 64,124,129, 35, - 30,167, 61, 53,169,172, 58, 43,235,209,159,247,109, 3,122,206,218,127,228,252,226, 14,237,194,240, 56,190, 0, 82, 17, 31, 18, - 17, 15, 18, 17, 15, 2, 98,192,207,235,214,235,114,243, 11,187,100, 61, 62,152, 85,141,252,121, 22,192,171, 54,103, 38,246,181, -108,119,172,154,181,109,196,212,165, 29, 58,246,252,140, 60,190,115,225, 91, 0,231,140, 42, 51, 89,106,212, 58,150, 53,238,221, - 70, 8, 97,236, 60,131,118,109,217,186,187,127,157,218,174, 72,207,211, 33, 37, 87,139, 43,247, 98,177,109,227,172,188,220,244, -231,131,160, 45, 42, 98,137, 62,255,212,201, 35, 39,191, 30, 63, 21,254, 1,245,221, 11,146, 10,204, 0,228,191,118, 76, 30,217, - 48,228,139,145,253,237,237,237, 77,255, 19,193,162,240,246,169,131,206,221,122,227,212,161, 3,136,140,120, 8,150,150, 12,231, -195,178, 20,121,185,217,105,122,157,102,235, 59,211,199,227,185,108, 89,191,204,142, 97, 8,180, 58, 22, 26, 61,139,233,211,103, -105,198,207, 94,221,172, 67,211,122, 17, 60,176, 5, 47, 83,243, 44,194,163,211,234, 18,129,169,227,160, 81,211,132, 42,181, 1, -249, 10, 29,206,238, 91,249,238,106,198, 90,245, 67, 61,252,154,125,241,229,204,245, 98, 49,143,209,250,123,187,190,104,217,216, - 63,177,134,147, 77,225,162,149, 59, 27, 93,191, 23,221,185, 87,175, 94,146,254,181,252,136,147,181,196,116,212,152,177,245, 28, -106, 55, 27,146,246,244,234,246,119,190,252,248,226, 60, 87, 23,215, 87, 85,137,118, 1, 61, 30, 2,112,123, 99,179,132,140,199, - 7,235, 1,128,157,189,131,138, 8,196,133, 85, 48, 32, 20, 0,230,173,218,223, 57, 41,179,168, 79,153,185,186,255, 60, 31, 98, - 33, 3,173,206,248,166,113, 6, 66, 39, 76, 27,251,185, 32,167, 88,143,139, 15, 51, 17,113,247, 2,213,107, 11, 62,163,132, 63, -204, 54,160,199, 16, 2,120, 80, 32,142, 33,248, 85,195, 96,107,222,131,131,249, 85,175,233, 41, 73,143, 93,157, 94, 77, 8, 15, -157,121,124, 97, 48,192,250,234,117, 58, 59,134,199,203, 74,123,176,191,210, 30,148,229,207,168, 56, 61, 6, 75, 23,205,198,202, -141, 7,144,146,173,130,185, 33, 17,135, 54, 45,196,228,197,187,160, 84, 27,240,111,192,104,131,101, 95,183,123, 35,128,225, 57, - 88,153,192,171,166, 43, 76,250, 14,147,186, 4,246, 47,230,241, 24,102,235,138,111, 37,217, 74, 62,248, 60, 94,177,209,133,175, -189,111,136,169,169,233,241, 63,255, 56,128, 90, 53,236,132, 59,175,228,196,221,123,161,124, 21,210, 45,200, 76, 16,121,152, 41, -248,189,122,246,148,157, 59,127, 97,194,187, 12, 22,143, 48, 46, 43,127,254,193,206, 84, 42, 0, 33, 64,161, 82,143,241,147,166, -189,247,133,161,160,188,175, 39,205, 1, 41, 53, 87,133,249, 57,248,126,229,214,162, 94,206,231,175,150,153,171,211, 79,164,207, -122,246,108,157, 31, 31, 31,159, 91,105,193, 72, 13, 73,125,134,142, 23, 50, 76, 73,181, 17, 67, 8, 40, 12,233,213, 49, 87, 0, -144,155,251,162, 64,234, 80,175,231,142,229, 99, 55,214,112,118,182, 52,149, 73,136,137, 92, 76,252,124, 60, 37,141, 27,135, 74, -106,120,250,139, 46, 71, 22,225,101,166, 18, 47, 82,242, 33,178,241, 23,244,111,217, 22, 59, 86, 78,235,108,204,249,159,191,241, -184,235,218,101,179,196,105,121, 26, 68,189, 44, 66, 90,174, 10,169,185,106,164,229,168, 96, 34, 21, 32,180,109, 47,241,137, 51, -251,186,182, 12,241, 91, 85,157,235,251, 60,246,197,129,248,228,212,207,234, 53,108,132,157,219,182, 52, 38, 46, 46, 18,154,148, -164, 50,118,255,141, 27, 55,230, 4, 7, 7,219, 46, 89,178,164,216,199,199,167,129,143,143, 79,205,152,152,152,139, 94, 94, 94, -221,214,174, 92,112,105,252,204,101,110, 60,162, 51,111,210,180, 25, 79, 34, 36,184,113,249,148,122,235,198,245, 41,218,188,162, -169, 21, 26, 97,153,249,194,244, 34, 2, 91,103,231, 8, 19,145,161, 29,159,201,139,201, 57, 49,118, 59,128, 63, 61, 59,141, 59, -123,225,110,116, 76, 80,120,188,221,249,240,103, 25, 57, 10,173,119,236,137, 73, 21, 22,184, 60, 66, 32,224, 49, 48,149,242, 95, - 69, 44,237,235,247,125, 70, 9,177, 45,139,148, 18,148, 68,180, 72,201,103, 75, 74, 82,248, 94, 35, 26, 70, 19,202, 82, 32, 58, -169, 24, 69,170,146, 16,188,139,141, 12,153,233, 73, 88,187,106, 43,238,221,189,131,246,157,186, 97,205,111, 59, 49, 98, 72,223, - 74,175, 43,195,160, 36,130, 85, 46,122,101, 34,229, 3, 32,200, 43,214,225,143,171,137,240,172,201,128, 84,161,182,208,212, 68, -138,252, 66, 37, 24,129, 9,162,174,108,151,157,184,112,123,198,220, 31, 55,125, 83, 80,148,246, 50, 54,242, 6,124, 44,179, 81, -211, 89,139,136, 52, 51,220,205,246,128,143, 87, 45, 48,194, 59, 70,105,103, 69,212, 93,122,136,249,163, 75, 80,131, 58,161,110, -118, 22, 80,106, 12,165, 81, 44, 30,182,108,222,142,248,184,164, 47,178, 34, 14,222,251, 16,133,100, 81,250,243, 76,137,125,237, -175, 30,221, 58,247,162,231,167, 95,193,209,185, 70,253,170, 52, 79, 48,102,157,193, 8,131, 69, 8, 97,172,220, 27,108,219,182, - 99, 95,255,154, 53, 28,112,230, 86, 28,110,199,100,195,198,198, 26, 60,153, 3,106,183, 28,102,241,232,228,202,222,202,172,162, -109, 2,161,108,120, 72,227,166,160,148, 34,250, 73, 68, 78,126,190,249, 95,202,102, 69, 74,212,125, 0,102,229,215,201,108,253, -234,155,152, 91,221, 87,107, 13, 72, 78, 78,194,181,235, 23, 27,150,110,103, 52, 98, 33, 15,167,239,101, 64,171, 99,161,213,179, - 8, 9,244,215, 8, 68,210,230, 63,108, 60,214, 56, 61, 61,147,145,154,152,177,230,118,181,132, 86,186, 52,245,131,231,249, 66, -173,142, 69, 45,167,138,191,203,101, 86,181, 22, 77,154, 60,222,143, 39,148,162,176, 88,173, 73, 77, 73,118,248,117,247,133,162, - 39,209,145,206, 30,238, 53,204, 22, 46,152, 43,204, 87, 2, 25,249,106,228, 20,106, 73,191, 79,191,112,218,190,105,205, 32, 0, -219,171,144,244,186,123,183,175,215, 89,154, 8, 73,161, 82, 71, 51,243,213,134, 49, 95,141,175,251, 62,121,167,204, 92,253,248, -253, 76,225,189, 23, 69,120,240, 60, 31, 18, 33, 15, 34, 33, 3,141,145, 6,203,182, 78, 95,185,173,173,197,160,144,250,181,113, -234, 94, 38,120, 60, 6,138,226,124,141, 68,108,242,216,215,183, 54,211,160,126, 0,194,154, 53, 65,236,139,120,159, 83,103,206, - 47,191,125,231,222,247,182, 1, 61,167,102, 62, 62,176,166, 42,105, 77, 76,205,150,165,235, 93,199,219, 57,216, 4,116,235,222, - 85, 92,195,217,158,216, 90, 89,192, 64,132, 24, 53,250,107, 59,163,243, 60, 45,137, 94, 46, 89, 48, 3,106,181, 6,182, 22, 34, - 80, 10,108, 94, 53, 23, 26,141, 6, 78,214, 98,228, 23,235, 56,131,245,234, 6,215,235,217, 84, 42,150,159, 94,179,120, 2,147, - 87,172,131, 68,200, 67,173, 90, 53, 49,118,252, 4, 89,155,250,182, 80, 18, 51,252,177,123,107,129,222,160, 59,106,140,158,204, -161,118,144,169,220,236,212,182, 29,123, 89, 27,107,107,102,237,233,204,231,217,133,250, 87, 67, 28,196,220, 58,204,222, 61,245, -171, 35, 5, 57, 41,145, 72,188, 52, 26,141,101,101, 55,116,243,233,132,210,198,185,228,131, 92, 24,134, 97, 12,191,174, 90, 0, - 27, 51, 17,212, 58, 22,243,151,111, 47,236, 98,123,242,124,121,115, 21, 24, 24,152, 95,191,126,253, 60,134,169,124, 56,177,151, -183,119, 54,121, 75,129, 89, 45,115, 85,134, 50,237,225, 29, 0, 1,175,107, 6, 10,108, 60,246, 77, 30, 48,104,200, 12, 7,255, - 79, 76,227, 82,243, 33, 36, 90, 4,251, 57,226,226,169, 63,217,196, 23, 79, 70, 25,163,157,145,157,239,106, 99, 99,141,123,207, - 11,145,156,173, 68, 90,169,185, 74,205, 85,163, 80, 89,136,250,238,182,200,203, 47,114,173,182,129, 37,244,224,169, 83,167, 62, -235,220,189, 63,198,126, 51,175,211,198,181,203, 30, 74,237,253,134, 40,211,159,220, 54,102,255,125,251,246, 25,220,221,221,159, -103,102,102, 54,154, 50,101, 74, 65,173, 90,181, 28, 22, 44, 88,240,101,173, 90,181,156, 90,183,106,149,127,251, 66,227,109,227, -191,153,219,106,250,184,141, 53, 25,134, 73,167, 44, 61,156, 82,172,155, 67, 51, 35,149, 21,222,167, 67, 51,162, 72,157,121,159, -181,107,110,123,216, 74,198,248,139,169,102, 0,169, 51,111, 47,141,156,163,141, 61,177,170,176,110,191,159,199,166,228,177, 51, - 85,140,221,247,149,153,171,146, 8, 22,129, 70,111,128,169, 84,240,159,188, 73,225,184,118,245,207, 50, 91,115, 17, 4, 60, 6, -124, 30, 65,129, 66,135,172, 2, 45,190,153,250,141,177, 87,144,213, 27, 40,148, 26, 61, 20,165, 95,131,133, 5, 89,152,241,205, - 36,116,234,218, 19,195, 71, 77, 66,174, 18,184,251,162, 16, 90,157,174,210,135,130, 71, 8, 20,106, 61, 62,111,239,134,156, 34, - 45,138,149,122,104,244, 44,100, 34, 62,248,124, 6,114, 9, 31,102, 50, 1, 8,161, 66, 71, 71,199, 47, 1, 64, 32, 16,168, 94, -190,124,185,163,130, 47,120,120,184,218, 67,169, 99,208,168,255, 50,180, 13,245,198,131,179,155,248,151,110, 62,170,249,205,220, -229, 24, 51, 48, 20,251,163, 60, 97,101,231, 6, 19,185, 20, 58,202, 0, 48,110, 8, 16, 74,231,176,142,190,189, 6,174,255,109, -115,244,252,217,211, 37,121,197, 4, 98, 33, 15,231,207,157,197,141, 91,119, 87,102, 70, 28,220,241, 33, 11, 74, 1,101,236,205, -204,204, 32, 17,241,160,209,170, 53, 70, 71, 30, 88, 10, 80,248,217,213,237,241,103,233,189,247, 51,176,120,203, 58, 90,153,185, - 34,230, 78, 1, 91,214,111,220, 57,200,201,193, 14, 7,206, 61,196,150,223, 86,163,102,131, 46,184,122,108, 11,204, 61, 26, 67, - 94,163, 25, 68,166,251,190,100,120,252,186, 95, 79,248,182, 87, 96,112, 40,174, 93, 57,143,140,180,212,245,148, 70, 25,213, 6, -141, 39, 32,227, 90,183,235, 10,149,198,128,230,109,186,224,228,145, 3, 99, 81,218,121,194, 88,222, 52,225, 44, 11,253,215,195, - 7, 8, 50,242, 52,130,204, 2, 13,146, 50, 21,136, 75, 87,224,208,158, 77,212,216,183, 54,195,231, 5,183,168,231, 34,248,114, -233,249, 68, 87, 23, 71,181, 64,173,148,198,196, 62,247, 29,254,217, 32, 65, 77, 47, 95, 38, 35, 95,141,204,124, 53,178,242,213, - 40, 82,233,225,229, 88,131, 81,235,249,161, 85,189,207,182, 22, 18,193,154, 35, 47, 96, 38, 23,160,137,175,117,181, 27, 97,179, - 44,251,154,185,186,255,162, 24, 15, 95,228, 67, 44,228, 65, 44,100, 32, 22,242,160, 55, 80, 35,223, 69,250, 1, 35,135,245,151, -106,116, 20,217,249, 26,240,121, 4, 14, 54,214, 98, 87, 71,111,108, 94,246, 53, 0, 96,196,180,181, 24,254,249, 96,248,120,123, - 33, 63,191, 80, 58,124,244,248,159,241,150,118,119,239, 74,235,206, 67,151,235,220,125,156, 48,249,179, 97, 67, 5,253,186, 54, -103,238, 63, 47, 64,106,142, 26,207, 99, 21,208,234,170, 54, 26,141,222,192,130,130, 98,235,222,163,144,138,248,200,204,215,130, - 82,138,133,171,127,135,169, 84,128,212,220,146,106,125,206, 96,149,153, 43,145,228,244,246,213,223, 74,207,199, 0, 43,207,220, -197, 39, 33,142, 16,242, 25,136, 77, 28,240,224, 69, 46,206,158, 59, 84,120,245,198, 45, 21, 24, 93,165,221,162,100,142, 62, 13, -229, 82,179,179,107,126,221,166,183,177,179,195,142, 43, 57, 73,185,197,122,221,127,170,167,116,228,238,169, 95,107,234, 89, 93, - 71,101,218,211, 74, 63,103, 89, 74,133,139,215, 29, 2, 64,193,178, 44, 40,203,130, 39, 20,203,221, 26, 15, 78, 47,209, 99, 37, -124, 30,163, 42,255,228, 83,214,144,148,112,107, 87,133, 85,135, 4,128,185, 76,128,189,151,146,145,159,147,146,213,197,246,228, -171,106,193,147, 17,226,103,129,129, 13,242,131,131,131,243,164, 82, 41,120, 60, 94,149, 47,252,251,154,171,119,191,120,194,117, - 0,150, 56,249,182,236,214, 73,230, 31, 34, 98,248, 8,244,113,196,197,211, 7,216, 27, 39, 54,245, 84,164,199, 28, 51, 50,188, -141, 34,165, 14, 41,217, 42, 36,103,171,144,150,171, 66, 90,142, 26,105,185, 42, 16, 66,160,210,188,223,240, 53,138,244,152, 35, - 38,206,254,235,213, 90,140,106,209,190, 39, 38,207, 93,227,181, 99,253, 15, 87,228,118,181,131,139, 51,158, 62, 50, 70, 35, 62, - 62, 94,109,111,111, 31,158,151,151,215,126,249,242,229, 69,126,126,126, 34, 19, 19,147,108, 0,210,103, 49, 49,194,243,199,247, -197,101,166,164,140,212,106,181,119,140, 77,151,123,216, 48,177,239,255,177,119,214,225, 81, 92,251, 27,127,103, 93,226,196, 29, -136,144, 64,130, 4,151,160,193,221, 10, 20, 41,165, 69, 90, 42, 72, 91, 40, 45, 82, 10,133,150, 34, 53,104,161,197, 29,138, 21, -119, 11, 30,136, 64, 8, 16,119,221,205,102,125,103,230,252,254,128,228,166,220,200,134,210,223,189,151,158,207,243,204,147, 77, - 50,243,206, 57,179,103,230,188,243, 61,102, 95, 60,217,207,166, 67,239, 0, 15, 37,252,108, 52,189, 67,109,239,126,227,214,227, -195,165,249,103, 86,231,231, 24,217, 83, 5,122, 97,139,172, 50,177, 85,125, 1, 89,179, 41,237,245, 41,115, 33,100, 24,152,141, -166,180,242,194,229,230, 32,197,194,109, 15, 96, 43, 23,195, 78, 33,130,173, 66,140, 78, 77,234,161, 14,175, 7,196,194,241,208, - 25, 57,232,141, 44, 12, 38, 22, 46,190, 78, 88,191,117, 15,210,243,245, 56,120,179, 16,137,105, 26, 4,251,216,128,144,218,227, - 78, 60, 97,181,175, 77,158,103, 39, 20, 8, 32,100, 32, 8, 13,170,143,226, 50, 19, 36, 34, 1,164, 82, 41,108,100, 34,216, 43, -196, 16,139,196,184,113,239, 30,140, 70, 35,218,182,109, 43,175,217, 2, 62,141, 98, 5, 55,244,130,217,194,226,232,197, 4, 44, -153, 49, 12, 61, 59,183,194, 71, 66, 41, 30, 24, 35, 96, 87,207, 14,188, 64, 0, 51,203,195,100,230, 0, 8,170,141,182,249,249, -249,117,183,177,177,177,209,233,116,154,180,180,180,243, 57, 15,246,167,187,133, 13,153,124,252,228,217,173, 3,250,246,196,157, -123,241,216,251,251,161, 75,133,206,234,217,229,199,132,135,135,183,115,113,113,177, 45, 42, 42, 42,141,141,141,189,241, 34,101, -149, 97, 24,198,198, 61,244,195,246,157,186,162, 76,149,143,188,140,148, 35,214, 30,219,216,223, 14, 51,103,188, 23, 28,210, 40, - 36,152,123, 54,146,170,137,159, 29,166, 78,123, 39, 56, 48,184, 81,112,249, 64,143,198,126, 53,207,119,105,227, 30,242,206,146, -149,107,199,251,249,250,226,216,149, 7,248,106,222,212, 59, 54, 74,187, 6, 62,238, 78,142,146,176, 86,136,137,185, 10, 55, 72, - 97,239, 30,236, 51,122,208, 20,159,222,125, 7, 33,246,238, 45,172,254,122,113,180, 86,168, 88,106, 77, 90,109,221, 3, 92, 91, -180,238,252,186, 93, 61,119,168,212, 26,216, 57,185,161,113,179,214,175,219,186, 7,124,242,108,177,250, 23, 51, 27,132,192,104, - 38, 40, 41, 51, 35,163, 64,143,212,220,167, 6,139,231,235,208,231,135,128,177,149,139, 68,245, 44,143,252, 98, 79,159, 37,254, -190,238,204,215,139, 63, 18,154,241,180,179,120,129,218,136,130, 82, 19, 10,212, 38,148, 25, 44,168,103, 35, 2, 79,248, 58,191, -109,151,148,153, 97,247,172,159, 44,199,191,184, 9, 88,184,106, 71,135,204, 2, 93,143,111,190,156, 39,185,155, 82,201, 92,137, -159, 70,175,100, 18, 33, 56,222,186, 8,150, 80, 36,120,175,127,143, 54,200, 40,212, 63, 29,133, 44, 96, 16, 20, 22, 1, 23, 5, -143, 30,163,230, 0, 0, 6,246,123, 58, 13, 73,114,142, 22,135,175,229, 0,128,196,218,180, 22, 21,105,100,191,159,186,243,193, -142,245,223, 72,141,188, 24, 63, 31, 75,131,206,200, 66, 46, 17, 66, 38, 17, 66, 33,169, 91,253,198,114, 79, 7, 75,164, 23, 90, -160, 51, 24, 80,170,183,128, 0,184,241,168, 12,122, 19, 11,181,214,130,118,161, 78,212, 96,149,155,171,205,223,125,170, 56,243, -144,224,220,221, 34,140,136,244, 65, 81,126, 38,214,255,180,134, 39, 4,144,201,165,185, 28,203, 31,211,243,236,199,170,187,135, -213, 53, 62, 36, 92,155, 52, 83, 40,149,103,151,175,254,217,236,230,238,205,239,191,166,202, 87,235,184, 63,197, 10, 57,163, 81, - 64,120, 34,177,198, 92, 61,139, 52,153, 23,188, 55, 20, 60, 33, 88,184,122, 15,150,206, 30, 5, 91,133, 72,201, 48,140, 82,107, - 96, 49, 99,209, 6,124,251,249, 36, 59,165, 76, 4,134, 1, 12, 38, 14, 83,223,179, 46, 74,160, 51,114,208,170,114,139,154,150, -173,124,206, 92,181, 84,183,109,219, 86,229,228,228,132, 23, 49, 88, 85,153, 43, 15, 15, 15, 47,165, 82, 89, 47, 56,248,105, 95, - 87,161, 80, 8,142,227,180, 73, 73, 73, 47, 52,233, 91,169,170,224, 64, 78, 74,108,219, 14, 93,251,227,194,201, 3,124,244,209, - 13, 67,235, 50,196,220,209,193, 62,227, 78, 66, 90, 99, 6,182, 79, 35, 88,207,204,149,201,194,195,223, 93,137,204,140,116, 56, - 58,216,102, 88,171,167,244, 8,238, 35, 32,194, 41, 60,131,245,186,220, 7, 71, 1,160, 44, 43,126,154,210,173, 81,108,124,252, -221,213, 3,198,188, 39,237, 53, 98,154,100,221, 87,239,206, 1, 48,218, 90,221,188,188, 60,157,171,171,107,180,167,167,231,128, - 69,139, 22, 25, 1,200,140, 70,163, 96,226,196,137,202,180,180,180, 25,132, 16,171,210, 24,249,230, 94, 23, 70,166,233, 27, 24, -220,122,140,191,157,166,103,183,200,246,104, 31,230,139,140,200,246, 0,240,126, 90,153,109, 72,167,105,191,238,106,232,234,115, -116,221,198,195, 75,223, 30, 21, 53,195,107,224,162,149,217,135, 23,212, 24, 17, 75,188,248,107,239,170,236,187, 72, 40,128,157, - 66, 12, 91,133, 8,118, 10, 49,236,228, 98, 88, 88, 82,151, 38, 56, 98, 97,249,167, 17, 44, 19,139, 50, 61,139,179, 49,121,200, - 85,155,160,210,152,161, 55,115, 32, 32, 48, 91,248,242, 89, 69,106, 54,171, 87, 55, 57,150,127,246,105, 57, 90,189,230,139,247, -236,247, 93,206,172, 24,161,231,160,148,194, 78, 41, 6, 64,112,241,226, 69, 56, 59,215, 62, 45, 22,207,243,216,123,252, 6, 86, -110, 58,139,227,191,125, 12,185, 68,136,102,131, 23,225,141, 33,109,193,243, 4,143, 19,227,243,130,155, 52,119, 23, 8, 20, 16, - 48, 12,140, 22, 30, 0,169,246,122,154, 76, 38,231,244,244,244,210,160,160, 32, 15,111,111,239, 17, 66,161,144,200, 0,227,129, -157,197,186, 51, 71,182, 43,181,122, 35,167,100,213,191, 5,229,232,251, 7, 7, 7,131, 97, 24,226,226,226, 34, 57,123,246,108, - 89,211,166, 77, 93, 95,228, 62, 98, 24, 70,160,112,107,180,230,173,105, 31,142, 8, 12, 8,192,158,237,191,129, 16,102,159,181, -199,111, 59, 28,141,149,171,254, 60, 98,112,234,180,119,130,215,173,253,233, 79,127, 27, 63,105,114,112, 77, 6,207, 39,188,251, -199,161,161, 77, 16, 29,159,137,175, 63,155,118,199,144,159, 60,198,100,235, 60,197, 92,150, 51,179, 69, 68, 43,120, 56,219, 35, -187,216,136, 65, 99,135,160, 99,167, 72,196,222,189,133,197,159,127, 20, 13,157,169, 87,109, 81,219,127, 25, 33,241,212,110,189, -135,136,245, 70, 51,190,251,122, 62,166,204, 94,130,118,221, 7,138,227, 98,174, 77, 5,240,133,181,121, 54,154, 57,116,107,234, -242,212, 52, 91,120, 28, 74, 22,138,170, 42,129, 34, 33, 35,104, 17,224, 8,189,137, 69,169,206, 82, 75, 4,139,201, 85,105,180, -245,127, 88,250,161, 80,107, 96, 81,160, 54, 33, 95,109, 68,161,234, 95,198,170, 80,109, 68,129,218, 4,177,136,193,195,148,108, - 8,133, 76,157,251,223,149,148, 89,208,166,145,211,211,123,244, 5, 91, 67, 10, 89,215,190,119, 31,102,247,248,122,241, 92,201, -221, 84, 45,238, 37,151, 62,139, 92, 9, 33, 19, 11, 32,125,246,153,179,194, 95,185, 53, 25,212, 97,252,232,193, 97,246, 54,114, -100, 63,212, 64, 36,124, 58,213,139,131,155, 47, 28,100, 6, 76,159, 54, 25, 46,206,142, 72, 47, 52, 98,205,239, 15,113, 47,225, - 17,120,125,221,178,253,195,246,227, 67, 39,140, 27, 37, 19, 74,100,216,114, 36, 5, 50,137, 16, 34, 98, 66,252,181,139,198,188, -204, 20,179,166, 84,101, 35, 18,137,173, 18,101, 0, 82, 30,153, 91,186,112, 14,118,110,250, 9, 39,110,231, 87,116,159,191,188, -239, 91,124, 56,247, 75, 20,150,154, 0, 48,175,124, 24, 75, 84,147,185,146, 75,165, 39, 55,173,153,171, 56,243, 16, 56,127,239, -169,185,210,151, 21, 98,203,175, 63,151, 17,240, 81,121,113, 7,173,126, 35,180,113,107, 20, 46,179,177,185,240,217,151,107,140, -238,222,245,217,163, 49,165, 69, 26, 3,247,111, 97, 16,137,210,134,179,113,112, 53, 56,250, 71,172, 20,235, 77,243, 11, 10, 18, -180,181, 69,154,120, 66,112,228,122, 46, 8,121,250, 74,180,251, 98, 22,132,130,167,205,133, 28,255,180,249,228, 84, 76, 62, 68, - 2,198,234, 33,231, 12, 3,236, 62, 25, 83, 24, 94,133,185,106,221,186,181,202,222,222, 30,142,142,142,176,181,181,173,235, 3, -187,202,200,149, 82,169,172,119,226,196, 9,185,189,189, 61,132, 66, 33,140, 70, 35,122,246,236,249, 66, 95,170,141,123,200,232, -118, 61,134,125,213,177, 91,127,156, 59,177,159,143, 62,186,113,152, 46,191, 14,243,247, 0,232,219,185,217,225,229,223,126,223, -240,163, 57,159,201,236,228, 34,220, 47, 51, 65,192, 48,240,119, 87,194,217, 86,136,232,179, 71, 12, 35,122, 54, 61,108,173,158, -159, 79,253, 45, 43,190, 91,231,188,114,217,162, 94, 78, 78, 13,221, 75, 74,146, 75, 1, 64,151,255,112,157,173, 71, 72,162,143, -223,201, 11,205,187, 12,133,187,119, 80,191,186,230,183,160,160, 32, 47, 44, 44,236,126,147, 38, 77, 90,141, 24, 49,130,124,245, -213, 87, 78,153,153,153,123,172, 53, 87, 0,208,163,103,216, 12, 91, 41,215,174,158, 82, 16, 22,224,161, 68,251,176,167,173,159, -163,250,119,130,175,159, 31,158,228,234, 90, 20,235,120,113,153, 73, 24,240,227,207,247,110, 54,112, 17,190,205,234, 77, 9, 0, - 14,214,185,210,198,191, 58,190,151, 71,175,236, 20, 98,240, 79,203, 71,157, 12,150,209,204, 65,111,228,160, 55,177,208,154, 56, -232, 76, 28,120,242,244,158, 96, 24, 6,102,150, 47, 63,101,157, 18,104, 95,207, 5, 1, 13,158,142,122,181, 83, 60,157,178,225, -105, 19, 33,224,236,236, 12, 55,183,218, 27,119, 8, 33, 48,153,159,222,226, 38, 11, 95,209, 68,106, 50,179, 32,132,224,225,195, -196,143, 83,147,147, 7, 7, 5, 7,117,110,210,172,121, 61,165, 76, 0, 0,213,154, 1,157, 78,199,217,217,217,185,213,171, 87, - 79,144,149,149, 85,209,239, 49,168, 69, 55,246,247,253,251, 48,108,216,208,178,251, 55,238, 86,140,168,210,235,245, 76,199,142, - 29,237,125,125,125, 5, 70,163,177,180,206, 81, 43,215, 70, 67,124, 67, 59, 44, 25, 63,113, 74,163,110, 81,125,112,238,204, 73, - 28,220,191, 99,179, 54, 63,241,164,181, 58, 33, 33,161,255, 54,138, 48, 48,184,209,191,141, 34,172,223, 48,184, 90,131,229,224, -208,204,190, 89,235,174,190,169,133,102, 28, 59,118, 20, 90,117,238,231, 38, 83,153, 14, 98,178,225,200,142, 31, 39,189,245,225, - 34,251,174, 93, 34,225,100,175,132, 72, 36,196,237,155,209, 88,246,197,167,209,208,153,122,213,246,252,172,200,111,147, 38,146, - 32,191,250, 31,248, 5,134,227,246,181, 75,120,252, 48, 46,254,238,205,232,176,160,166,237,224,234,229,255, 1,211,164,201, 50, -146,144, 80,235, 74, 21,132,227, 50, 39, 76,158,249,236,251,127,250,183,246, 45, 26, 74,153,231,111, 0, 0, 22,214,204,109, 89, -183, 44,191,242, 40,194,234,116, 13, 26,213,222,139,215,238,205, 30,216, 43, 82, 80, 88,106,122, 26,177, 82,155,158,109, 70, 20, -150,127, 46, 53, 34,216,203, 22,143,227,238,243, 22,173,122, 95,221,238, 76,146, 55,237,157,247, 20, 79,211,206,131,240,164, 70, -195, 95,109, 90, 57,201,235,235,190,152,195,220, 75,213,226, 94, 74,233,211, 38, 65,177,240,169,177, 18, 11, 42,204,150, 85,173, -100, 2,193,215,227, 71,246, 70, 97,169, 25, 60, 15,136,132,130,103,155, 4,233, 26, 6, 25, 26, 29, 10, 75, 10,144,156,154, 6, - 85,238, 99, 8, 4, 2,184,120, 53,130, 46,221,186,180,106, 56,219, 70, 22, 14,129, 35,251, 71, 10,127,143,206,133, 82, 38, 66, -105, 81, 6,174,156,216,165,231, 89,110,157,201, 98,218,233, 70,164,113, 9,177,123,204, 86, 62, 58, 10, 74,181, 70,119,153, 88, -136, 61,155,126,192,200, 55,166,149, 71, 32, 1, 0, 31,207, 91, 12, 8, 24,148,168,180, 0,152, 23,142,138,254,207, 27, 44,177, - 64,120,106,227,234, 79,229, 9, 5,114,220, 72,204,193,136, 72, 31,232, 52,133,248,249,135, 53,101, 6,139,177,111, 65,236,193, -186,133,219, 5,130,222,163,222,156, 29, 31,208,168,137,241, 92, 92, 89,138, 74,107,169,182, 31, 67,251, 17,159,197,223,250,227, -251,126,106,203,147,119,108,189,194, 56,158,101,191,214,229, 39, 46,170,250, 45,153, 72, 23,173,217, 83,209, 60,248,201,178, 45, - 79, 63,115, 28, 56,194,131,240,192,244,207,215,130,229, 57,240, 28, 7,158, 35, 96, 44,156,178,214,112,185, 92,114, 50,188,108, -165, 67, 85,230,202,209,209, 17,206,206,206,112,118,118, 70,185, 33,250,171,205,130,193,193,193,176,181,181,197,165, 75,151,160, - 80, 40, 96, 99,243, 98, 19,228,219,186,135,190,214,182,251,208,109,221, 6,190, 41, 56,253,251,207,220,245,243, 71, 70,232,243, - 31, 88,109, 2, 56,142, 99, 44, 22, 11,122,119,109,153, 22,147,152,126,252,139, 69, 11,251,180,238, 62, 92,214, 33,196, 13,122, - 19,139,172,204, 76, 68,159, 61,104, 8,242,115, 62,209,165,109,227, 52,139,197, 2,142,227,106,173,192, 13, 70, 83,145, 80,172, -112, 30, 53,250,117,217,205, 27, 55,182,217,184,135,236, 16, 8,249,187,132, 19, 54, 3,200,107,205,154, 53,134,217,194, 67,167, -211, 20,191, 72,190, 19, 18, 18,110,172, 90,181,170,145, 88, 44,246,221,189,123,119, 97, 73, 73, 73,157,150, 11, 58,121, 49,113, -181,136, 41, 73,146,242,230, 49,254,118,154,158,233,157,218, 99,244,128, 78,216,249,199,101,156,191, 20,141,180, 50,219,152, 50, - 86,116, 32, 35, 45,219, 24, 86,175,116,223,160,246,245,133,123, 54,149,236,115,235, 54,247, 53, 66,100, 39, 11,206, 47,208, 90, - 95,121, 3, 26,189, 5,246,202,167,243, 53,149, 71,178,132, 12, 99,181, 19, 98,128,228, 75,209,183,195, 91, 5, 55,193,157,100, - 53,242, 85, 70,232,141, 44,120,158,128, 7,129,179,157, 20,114,137, 0,233,169,201,224,137, 57,165,110,245, 12, 10,250, 14,159, - 34,122,122, 30, 94, 36, 22,139, 64,158,213,139, 10,185,180,204,205,205,205,170, 8,150,153,101, 49,172, 79, 91,180,107,221, 12, -131,167,172, 0, 0,156,217, 60, 7, 78,182, 98,236,221,187, 23,233,151, 87,109, 13,232, 48,237,100, 92,108,252,240,248, 59, 87, - 95,239,219, 82,209,194, 67,148, 93,109,211, 70, 89, 89,217, 62,134, 97,164, 18,137,164, 79,231,206,157,235,237,219,183, 79,229, -226,226,194, 75, 37,146,130, 65, 3, 7,240, 98,137,164,162,236, 92,185,114, 69, 60,101,202, 20,187,146,146,146,244,188,188,188, -104, 66,136,165,230, 23,192,208, 40, 8,176, 3, 12, 35,183, 85, 40,211,218, 71,141,246,106,221,174,173,195,144, 97, 35, 33,147, -202,112,234,228,113,124,183,106,217,238,178,156,251,111,214,229, 82,190,140, 81,132,106,181,131, 54, 41,225,110, 73, 74,190,201, - 73,236, 24, 12,177,204,110, 10,227,224,181, 70, 40,179, 93,224,218,124,136,253,222, 67, 71, 17, 27, 23,135,122, 10, 11,158, 60, - 78,210,197,197,220,249, 73,199,136, 23,145,130, 4,157,213, 17,230, 34,110,120,251,113,125,156,140,102, 14, 23,207,254, 97,224, - 89,190, 79,244,133,163,143,125, 26,181,150,135,183,238,225, 84,120,112,195, 48, 0, 59,107,211, 73,185,190,245,223,186, 94, 4, -180,125, 45,251,232,201, 11,182,158,254, 65, 66, 6, 66, 24,244, 58, 20,164,197,178, 6,117,174, 46, 47,246,128,151, 53,233, 75, - 99,179, 62,255,252,171,181,239,180,106, 30,102, 67,136,228, 79, 17,171,114, 99, 85, 88,106,130,139,157, 20, 70,109, 9, 30,223, -187,100, 40, 16,231,125, 90,243,179,206,162, 44, 42, 42,150,150,255,174, 40,115,172,175,118, 80,203, 42, 76,160, 16,112, 80, 59, - 26,255,213,148, 86, 44,229, 56,139,210,154,219,211,193, 86,142,216,148,156,138, 14,237, 50,241,211,190, 87, 82,177,176,162, 31, -150,149,247,121, 75,145,212, 22, 89, 69, 6, 48, 32,224, 57, 22,172,197, 4, 77,105, 41,178,178,115,145,151,155, 7,141, 70, 5, -165,173, 19,194, 91,180,129,157,173, 13, 30,220, 62, 15,128,177,234,229,215,192, 75,130, 91,183,106, 37,142, 79, 43,131,217,194, - 67, 12, 51, 46, 31,219,105,176, 88, 76, 3,243, 98, 15,156,173,235,115,152,229,201,233,184,196,180, 48, 31, 87, 79, 38,230,177, - 26, 91,215,127, 15,211,179, 72,166,197,194, 33, 46, 93,139,156, 98, 29, 50, 51,210, 8,120,238, 52, 94,113,170, 53, 88, 44,203, -202,253,252, 27, 96,244,148,177,248,233,167,181,120,248, 36, 29,191,252,248,204, 92,221,251,253,138,149,134, 34,170,124,174, 12, -109,238,131,175,223,252, 41, 37,243,208,157, 98,129,222, 84,243,250, 83,114, 87,127, 68,190,249,237, 9,189,166, 88,202, 25,117, -162,195, 91,223,220, 81,149,230, 83,223,198,152,150,204, 26, 5, 91,133, 8, 12,195,160,188, 89,240,199,197,147,161,148, 9,193, - 48, 12,244, 70, 22, 99,103,172,196,214,149, 51, 65, 0,188,245,206, 44, 93,117,233,172,100,132,152,137,125, 26, 14,250,242,215, -132,131,151, 83,157,159,244,239,223, 69,221,178,101, 75,149, 66,161,128, 66,161,128,189,189, 61,156,156,156,224,232,232, 88,107, -222,159,253,238, 94, 91,159, 43,129, 64, 0, 27, 27, 27,216,218,218,194,198,198,230,223,140,219,243,154,255,102,174, 60, 26,141, -108,211,109,232,142,238,131, 38, 9, 78,255,254, 11,127,235,252,225,145,250,252,196, 3,214,126, 71,207,154,117,238, 14, 27, 54, -172,233,148, 41, 83, 36,159,190, 51,236,196,137,243,183, 31,238, 63,181,111, 96,177, 74,227, 75, 8,129,163,131,109,198,136,158, - 77, 15, 71,182, 14, 73, 59,115,230, 12,191, 99,199, 14, 35,195, 48,177,181,165,179,176, 48,127,227,153,211,103,151, 71,118,233, -138,245,155,118,244,143, 79,184,223,255,241,227, 36,248,250, 7,160, 65,195, 96,232, 24, 39,156,189,112, 9,154,226,220,141,214, -164,179, 50, 77,155, 54,245,110,222,188,185,143, 74,165, 50,204,159, 63, 63,132, 16,114, 32, 60, 60,188, 85,203,150, 45,115,239, -220,185,147, 89,221,176,255,202,154, 87,215, 14, 41, 0,176,185,126,215,137,187,179,204,170, 15, 0, 44,243,243,247,195,249, 75, -209,136,190,124,125,109,161,210,111,209,155, 99, 39, 78,174, 63, 72,248,214,160,246,245,133,110, 78, 74,108,255,229, 91,225,161, -232,212,149,169, 69,220, 6, 0,139,173,249,142, 42, 30,214, 26, 51, 58, 54,174, 7, 11, 71,192,147,167,166,203, 78, 46,174,178, -137,176, 42, 77,145, 73,246,230,212, 41, 83, 30,135, 55,107,241,225,216,137, 83, 37, 45, 2,124,113,227,145, 10, 96, 24,212,243, -176, 65, 78, 78, 14, 46,238,253,133, 45,201,122,176, 86, 40,228,191,168,203,245,204,188,189, 51,168,252,179,167,167,231,228,152, -184, 56,156, 63,127, 30,229,198,202,213,213,181, 74,131,245,188,102, 73,137,230,202,226, 21,235, 59,190, 61,110, 48, 6,116, 13, -195,133,155,143, 97,122, 54,223, 82,249,144,240,228,232,117,210, 15, 70, 5,152,222, 25,214,168, 84,111,145,166,126,158,162,190, - 88,121, 18,217,231, 53, 9, 33, 38,134, 97, 14, 37, 38, 38,118,106,222,188,121,253,163, 71,143, 22,199, 95, 63,241,167,137,238, -102,205,154,101,251,211, 79, 63, 41, 9, 33, 87,140, 70,227, 19,171,242, 46,192,246,219,183,110, 57,155, 45, 60, 46, 93,191,219, -184, 71,199, 22,224, 9,112,243,230, 77,108,248,117,131, 33,246, 94,204, 10,109,158,199, 23,213, 77,110, 91,221,245,228,254,194, - 40,194,114, 77, 66,206,179,182,238,161,107,175, 92,186, 48, 79,230,213, 10,161,253, 62, 29,148,117,247,208, 32,143, 38,189,225, - 18,208, 1,217,247, 14,225,202,137,109, 71,121,150,157, 35,231, 5,105,218,130, 7, 90,107,239,247,114,100, 10,229,123, 77, 90, -118, 65,122, 90, 42, 82,146,226, 54,235,139,146,178,109, 61, 66, 55,103,103,166, 77,109, 24,214, 17,151, 79,236,124,191, 58,131, - 85, 91,153,119,147,107,214,158,187,124,117,116,214,158, 67,238,154, 50,189, 66, 36, 18,232,100, 34, 38, 79,162,123,188,203,218, -116,146,132, 4,179, 91, 96,135, 97, 99,166,124,246,199,202,175,230,137,221, 29,101,200, 45, 49,160, 84,111,134, 70,103,134,128, - 97, 16,228,101, 3,189,182, 20,209, 71,183, 88, 56, 67,209, 40,242,232,207, 17,183,202,154,174, 97,131,191,100, 24, 76,255,236, -179,185, 16, 74,237,189, 26,246,248,212, 44,104,232, 1, 39, 60, 55,153,121, 61,160, 97,143, 79, 97,212,228, 13,252,236,179,185, - 33,132,144, 30,174, 97,131, 53,229,107, 17, 86,151,247, 34,141, 25,175,119,243,133,153,125, 58,127, 24,203, 3, 28,255,244,133, -159, 16,128,212,208,110, 95, 89,147, 0,146, 93,127, 92, 65,118,158, 10,122,147, 5, 70, 19, 11,179,133,131, 64, 40,132,163,147, - 35,130, 27, 68,192,209,209, 1,249,133,133,184, 25,125, 25,215, 18, 99,146, 9,240,101, 97, 61,245, 54,107,190, 35, 70,100, 19, -228,238,230,194,228,149,154,160,144, 10,113,237,246,121, 11, 1, 54, 90, 99,174,170,210, 84,235, 84, 43,231, 44, 94, 51,230,167, -111, 23,120, 52,109,104,143,204, 66, 61, 50, 11, 12,208, 24,158,190,223,176, 28, 15,147, 94,141,196,155,199,114, 89,232, 86,254, -115, 35, 88, 98,177,241,230,189, 68,217,156, 69,223,224,254,163,100,108, 88,251,189,214,104, 49, 91,109,174,170,226,183,119, 26, -236,172,219, 17,207,230, 45,253, 34,181,150, 23,238,231,154, 5, 9, 15,158, 16, 28,190,158, 91,209, 44,200, 63,235, 81,121,231, -177,170,182, 66, 35,254,230,189, 22, 31,151, 27,161,239,126,207,186, 38,147, 21,242,233,233,233, 37,219,182,109,171, 48, 61, 66, -161, 16,229,163, 7, 77, 38, 83,173,163,138,156,236,165, 97,227,250,214, 31, 85,157,185, 18, 10,133,224,121, 30,246,246,246, 80, - 40, 20,117,110,122,180,113, 11,233,217,166,251,208,157,221, 7,191, 37, 56,115, 96, 61,127,235,252,161, 17,101,249,137,191,215, -245, 59, 42, 41, 41,137,103, 24, 38,105,197,138, 21, 45, 54,108,216,208,112,246,236,217, 79,214,127, 53,245,187,167,111,112, 79, -151, 69,188,115,231, 14,153, 54,109,154,209, 96, 48, 36,151,148,148,220,182,102,145,107, 93, 94,226,138,223,126, 90, 30,146,145, -149,243, 70, 64,120, 27,184, 54,108, 3,143,160,182, 40,209,152,113,227, 81, 54,158,220, 63,131,132, 43,123,119,233, 11,220,151, -214, 37,189, 45, 90,180,240, 19,139,197, 3, 1,132, 40, 20,138,250, 12,195, 72,197, 98,241,107, 12,195, 36, 49, 12,115, 63, 36, - 36,228, 12,170, 89,190,168, 42, 82,207,111, 52,214,239, 58,113, 77,154,198,174,219,147, 92, 93, 68,154,198,238,142, 78,230, 48, - 51,255,204,106,163,123,175, 21, 43,137,185, 48,126,207,166,210,125,219,127,249, 86, 56,118,242, 44, 46, 78,237,244,129, 72, 33, - 61,245,213, 27,214,143,230, 22, 48, 76,206,236,217, 31,253,107,154,134,103,145,171,103, 83, 54,100, 91,163,241,108, 61,197, 79, - 20, 94, 97, 63,196,125, 48,101,113,179,214, 29,199,117,238, 59, 74,192, 74,108,113,226,247,117, 36,249,222,217, 61, 34,194,205, -211,229, 63, 78,254,171, 15, 9,147,201, 84,171,185,170,178,233,214, 89,221,245,143,147,231,223, 56,114,252,194, 87,125,123,118, -114,254,241,243,215,240,205,207, 7, 96,163,144,129,240, 28, 70,117,247, 27,113,127, 71,239,129,190,238,114,239,125,231, 50, 47, - 78, 95, 21,247,137, 78,103,126, 88,219,218,121,207, 12,243, 37, 59, 59,187,130, 78,157, 58,181,147,201,100, 76, 97, 97,161,200, -205,205,141,117,112,112, 48,101,102,102,234,140, 70,227, 62, 66,136,182, 46,249, 52, 91,120,164,228, 25,112,112,255, 62,220,189, -126, 6,247,239, 39,106,238, 39,220,255,158, 17,145, 85,101,185, 15, 95, 40,178,202, 87, 57,138,144,212,121, 20,161, 86,168, 88, -122,231,200, 55, 93,131,187,191,223,222, 57,176, 35,156,252,159, 6,138,212,153,113,200,184,185,231,160, 38, 91, 50,146,144,184, - 23, 30,251,238,229,211, 48,152, 8,165,184,122,254, 15, 16,158, 95, 11, 0,132,231,215,222,185,124,116,106,219,126,111,161,158, - 91,253,230, 12,195, 48,117, 93,143, 17, 0,100, 2,179,250,143, 77, 75,247,164,164,164,224,193,131, 7,120,244,232, 17,138,139, -139,177, 61,229,162,186, 46, 58,249,143,175,158,114,111,212,185,247,152, 55,103, 28, 30, 58,124,168,220,175, 65,144, 32,196,199, - 30, 46,182, 34, 36, 38,103,225,113, 92, 18,255,232,222, 69, 3,209,231, 15, 41,124,116,165, 90,195,231,218,100,164,187, 64,200, -204, 57,115,232,233,218,130, 81,131,223, 12,249,120,250,236,118,245,156,157,170,124,142, 23, 23,149, 72, 23, 46,156, 31, 82,190, -127,109,107, 17, 10,132, 66,205,228,169,239,217, 8, 24, 1,202, 47, 23, 41,111, 35,171,248,241,244,131, 68, 44,170,181,140, 78, - 28, 26, 9,150,231,161,213, 91,160,209,155,160,214, 24,145, 83,168, 66,252,253, 71,184,126,233, 56, 82, 30, 39,105, 88,150, 61, - 7,130,253, 5,206,234, 93,207, 79,172, 91, 99,249,132,208,175,158,147, 61, 82, 85, 6,200,165, 34,100,167, 63,102,205,172,225, -133, 39, 89, 47,140, 57,148,227, 30, 62,184,215,196,119, 62, 61,222,185,115,164, 67,179,136, 86, 74, 23,123,123, 72, 68,192,227, -244,124,220,187,125, 67,155,246, 48,166,148,179,232,251, 20,198, 29,250,203,171,180,252,207, 26, 44, 51,199, 70,205,250,116,217, - 73,142,227, 20, 34,161, 80,111, 33,124,159,191, 98,174,254, 46, 8,225, 51,223,121,255,163,138,168, 46, 0, 88, 56, 94,241,214, - 59,179,245,149,223, 16, 24, 11,167, 44,143, 92,213, 50, 82, 79, 88,160, 50,106,230,254,116,119,243,242,205, 9,123, 1, 36,252, -213,145,125, 0, 80, 82,106,186,235,220,115,247, 96,141,142,101, 0,220,175, 66, 83,219,189,123,247, 10,179,245,172,185,206,234, - 10, 66, 42, 87, 78,237, 54,240, 77,193,153,131, 27,248,155,231, 14,142,124, 17,115, 85,169, 2, 51, 3,184,206, 48, 76,220,188, -121,243, 90,187,187,187,187,207,159, 63, 95, 94, 90, 90, 42,254,241,199, 31, 13,133,133,133,185,165,165,165,209,132, 88,223, 63, -225, 89,165, 57, 81,225,222,120, 29,179,119, 67, 47, 39, 55,239,222,142, 46,190,141, 74, 10, 50, 31,151, 22,101, 30,103,120,156, -210,228, 39, 70,215, 53,173, 49, 49, 49,233, 77,155, 54, 61, 32, 20, 10,111, 3,112, 1, 96, 71, 8, 41,102, 89,182, 68, 44, 22, -231, 38, 38, 38,214,121, 65,214,212,243, 27,141,157,223,249,117, 71,177,142,151,152, 4,146, 29,169,231, 55, 26, 1, 32,239,228, -108, 29,128,131,238,221,230, 12, 59, 20,157,250, 93,124,137,195,251,249,231,150, 30,170,171,126,214,157, 93, 65, 47,171,252,235, -179,227, 51, 1,188, 97,227, 30,242,109,236,157,232, 5, 12,129,152, 3,251,165, 46, 47,233,214,203,208, 23,139,197,134, 86,173, - 90, 85, 57, 90, 80, 38,147,213, 56,191,214,179, 7,253, 6,166,107,215, 77,199,207, 92,122,227,216,169,203, 95,181,107,223,201, - 89,238,227, 13,127, 39, 51, 54,125,212,242,253, 51,119, 10,110, 12,250,232,226, 79, 79,178, 13,247, 8, 33,134,186,164, 77,163, -209, 60,100, 24,166,164,172,172,108, 48, 33, 36,131, 97, 24,223,146,146,146, 24,139,197, 18, 91,103, 35,192,227,245,246,237,219, -108,103, 24, 70, 68, 88,254,235,104,177,112,135, 33,231,126,230,139, 24,138, 63, 69, 87, 27,216, 99,242,212,105,193,129, 65,141, -130,203,215, 34, 12,171,111,135,177, 19,223, 14,174,223, 48, 56,248, 95,235, 19,214,252, 66, 69,178,111,235, 25,247,166, 61, 19, - 79,174,248,220,249,241,149,119, 20,245,124,108,181,133,169,197, 37,169,183, 86,232,242,221, 87, 60,191, 66, 67, 93, 73,121, 20, -191,106,195,138, 79,102,231,100, 37,111,208,230, 63,140, 3, 0,109,254,195, 56,165,123,163,207, 11,115, 51,103, 23,229, 63, 89, -241,162,215, 66,171,213,102,111,219,182,205,177, 99,199,142, 2,119,119,119, 20, 20, 20,224,220,185,115, 60,207,243, 89,117,213, -202,123,120,241, 28, 19, 24, 88,111,199, 38,245,215, 34,133, 93, 63,150,131, 23, 33,128, 72,128, 28,179, 81,125,188,192, 81,255, - 17,185, 23, 93,115,185,228, 57,134, 8,136,160,124,109, 65,158,231,153,111,126,216,146, 42, 20, 75,171,108, 82,229, 44, 38, 37, -207,243, 86,175, 69,152, 39, 76,115, 14,183,132, 90, 53,138, 47,142,121, 80,203,203, 41, 57,209,161,239,248,222, 44,203, 89, 0, - 24, 42,109,249,132, 48,103,193,112, 39, 11,235,105,162,235, 98,170,254, 84,207,155,205,142, 16, 74, 96,167,176,128, 1,131, 82, -181, 74,230,202, 73,239,255,149,178,148, 23,119, 48,158,233,218,213,223,116,250,236,132, 11,151,174,142, 36, 60,215,128, 35, 0, - 8,147, 98, 50, 27,246,228,219, 23,110,126,209,244,254,175,193,144,191,113, 62, 10,107,155, 75,254,219, 52, 25,134,145, 60,171, -172,185,202,203,223,188,140,116,214,180,182,224, 95,201,187,157,103,227, 78, 50,185,242, 35,157, 78,179, 65,151,247,240,240,203, -188,158, 12,195, 56,200,100,178, 8, 91, 91, 91,113, 97, 97,225,117, 66,136,250, 85,252,222, 43, 19,249,230, 94,151, 30, 61,195, -102,156,188,152,184,250, 89,243, 97, 5, 62, 35, 87,201,199,245,235, 54,107,243,254,131,255, 54,138,240, 85,200,251,223,165,201, -116,237, 42,114, 43,177,127,131,227,248, 47,187, 7,107,116,185,201,137,211, 46,197, 22, 92, 39,132,104,254, 74, 58,165, 82,233, - 88,179,217,172,144, 72, 36,122,147,201,180,237,191, 37,239,110,225, 67,190, 0,131,198, 86,139, 16,220,207,143, 59, 48,191,214, -103, 72,147, 38, 18,101, 1,156,116,133, 46, 69,117, 53, 86,255,145,239,157, 97,132, 77,155, 54,141,148, 72, 36,126, 28,199, 41, - 77, 38,147, 78,175,215,167,164,166,166, 94,173,110, 65,242,191, 59,157,238, 77,135,172, 18,139,197, 31, 0,128,197, 98, 89,147, - 23,123, 96, 70, 77,199, 86,183,255,255, 75,125, 52,114,164,144,236,217,195,253, 29,223,145,119,196, 8,149,197,194, 58,148,255, - 46, 17,139,212,153,119,246, 58,254,167,202,210, 43, 7,121,182, 60,194,223,177, 1,136,162,154, 84,147,106, 82,205, 42,246, 21, -208,235, 73, 53,255,147,154,158,141, 7,248,122, 54, 30,224,107,237,241, 85,237, 79,175, 39, 1,221,170,223, 68,212, 98, 82, 40, -148,255,192,139, 29, 79,175, 2,229, 63, 73,118,194,225,140,191,115,127, 10,133, 1, 16, 85,205, 3,208,234,208, 31,195, 48, 81, - 47,240,128, 61, 77, 53,169, 38,213,164,154, 84,147,106, 82,205,127,150,102,109,218,175, 76,211, 35,109, 34,164,154, 84,147,106, - 82, 77,170, 73, 53,169, 38,109, 34,124,185,155, 0, 20, 10,133, 66,161, 80, 40,148,151, 10, 53, 88, 20, 10,133, 66,161, 80, 40, -212, 96, 81, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10,229,197,249, 91, -103,114,167, 80, 40, 20, 10,133, 66,249, 39, 66, 35, 88, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161, 80,131, - 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66,161, 80, 40, 20,106,176, 40, 20, 10, -133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161,252,231, 13, 22,195, 48, 81, 84,147,106, 82, 77,170, 73, 53,169, 38,213, -164,154,212, 96, 81, 40, 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10,133, 26, - 44, 10,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,255, 33, 24, 0, 85,142, 4, 32,132,156,182, 90,228, 5, - 70, 19,212,166, 79, 53,169, 38,213,164,154, 84,147,106, 82,205, 87, 79,179, 54,237,186,248,143,255,106, 8, 33,127,219, 6, 32, -138,106, 82, 77,170, 73, 53,169, 38,213,164,154, 84,243,159,182,209, 38, 66, 10,133, 66,161, 80, 40,148,151, 12, 53, 88, 20, 10, -133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, - 10,229,197, 97,158,141, 6,160, 80, 40, 20, 10,133, 66,161,188, 36,104, 4,139, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66, -161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, - 66, 13, 22,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,148,255,188,193, 98, 24, 38,138,106, 82, 77,170, 73, - 53,169, 38,213,164,154, 84,147, 26, 44, 10,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, - 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10,229, 63, 4, 3,160,202,145, 0,132, -144,211, 86,139,188,192,104,130,218,244,169, 38,213,164,154, 84,147,106, 82, 77,170,249,234,105,214,166, 93, 23,255,241, 95, 13, - 33,228,111,219, 0, 68, 81, 77,170, 73, 53,169, 38,213,164,154, 84,147,106,254,211, 54,218, 68, 72,161, 80, 40, 20, 10,133,242, -146,161, 6,139, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66,161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80,168,193,162, - 80, 40, 20, 10,133, 66,161,188, 56,204,179,209, 0, 20, 10,133, 66,161, 80, 40,148,151, 4,141, 96, 81, 40, 20, 10,133, 66,161, - 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40, 20,106,176, 40, - 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10,133,242,159, 55, 88, 12,195, 68, - 81, 77,170, 73, 53,169, 38,213,164,154, 84,147,106, 82,131, 69,161, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, 10, -133, 26, 44, 10,133, 66,161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161,252,135, 96, - 0, 84, 57, 18,128, 16,114,218,106,145, 23, 24, 77, 80,155, 62,213,164,154, 84,147,106, 82, 77,170, 73, 53, 95, 61,205,218,180, -235,226, 63,254,171, 33,132,252,109, 27,128, 40,170, 73, 53,169, 38,213,164,154, 84,147,106, 82,205,127,218, 70,155, 8, 41, 20, - 10,133, 66,161, 80, 94, 50,212, 96, 81, 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, - 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,148, 23,135,121, 54, 26,128, 66,161, 80, 40, 20, 10,133,242,146,160, 17, 44, 10, -133, 66,161, 80, 40, 20,106,176, 40, 20, 10,133, 66,161, 80,168,193,162, 80, 40, 20, 10,133, 66,161, 6,139, 66,161, 80, 40, 20, - 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10, 53, 88, 20, 10,133, 66,161, 80, 40,212, 96, 81, 40, 20, 10,133, 66,161, 80,254, -243, 6,139, 97,152, 40,170, 73, 53,169, 38,213,164,154, 84,147,106, 82, 77,106,176, 40, 20, 10,133, 66,161, 80, 40,212, 96, 81, - 40, 20, 10,133, 66,161, 80,131, 69,161, 80, 40, 20, 10,133, 66, 13, 22,133, 66,161, 80, 40, 20, 10,133, 26, 44, 10,133, 66,161, - 80, 40,148,255, 16, 12,128, 42, 71, 2, 16, 66, 78, 91, 45,242, 2,163, 9,106,211,167,154, 84,147,106, 82, 77,170, 73, 53,169, -230,171,167, 89,155,118, 93,252,199,127, 53,132,144,191,109, 3, 16, 69, 53,169, 38,213,164,154, 84,147,106, 82, 77,170,249, 79, -219,104, 19, 33,133, 66,161, 80, 40, 20,202, 75, 70, 84,213, 31,197,109,151,228,177, 44,235, 6, 0, 34,145, 40,223,114,227, 51, -207,154, 68,124, 61, 61,123,112,192,122, 0, 16, 2,111,103,100,103,159,170, 66,243, 20,203,178, 78,207, 52, 75, 44, 55, 62,235, - 93,147,166,184,205,151, 39,254,180,255,245,121, 61,171,136, 47, 10,197,109,190,204,126, 46,173, 94,117, 8,223,113,255, 31,233, -252, 95,209,252, 39, 35,105,183, 36,207, 98,121, 90,142,196, 98, 81,190,249,122,205,229, 72,210,246,203,236, 63,237,127,109,158, -123, 77,154, 74,133,172, 40,208,219,117,101, 77,154, 79,178, 11,103,106,117, 6,231,154, 52,255,103,238, 77, 43,241,240,240,104, - 37, 16, 8, 62, 99, 24,198,190,210,159,239,101,101,101,125, 72, 75, 37,133, 66,121,229, 12, 22,203,178,110,183,127, 95, 0,173, - 17,232, 49,254, 75,183,128, 33, 63,111,255,183,125, 12, 37, 82,125,210,129,166, 82,104,157, 20, 98,214, 62, 41, 41,137, 1, 0, - 47, 47,175,245, 0,252,170,208,116,186,253,251, 2,232, 76, 64,231,209,139,156, 58,249,250,218,231, 10,133,179,100, 10, 69, 55, -131,193, 16, 6, 0,114,185, 60,222,168,215,159,243,224,184,111,159,223,191,186, 12, 84, 78,107,247,113, 95,186,133, 14,249,249, -125,142,231,165,250, 39,123, 58,243,154, 52,145,132, 51,253,248, 70, 78,206,177, 5, 0,103,205, 5,169,124,222, 46,163, 62,117, -246,243,244,236, 46,149,203,155,219,217,219, 71,242,132, 52,230,121,158,225, 88, 54, 65, 91, 86,118,137,103,217,187,156, 69,231, -124,251,192, 82,190,166,116, 62,159,151,145,128,232,154,135,199, 8,165,141, 77, 55,129, 72,212, 1, 0,120,150,189,170,211,106, -207,181,203,205,221,107, 77,222,173,189, 62, 47,186,255, 63, 13,139,133,117, 75, 62,177, 0, 70, 11, 16, 49,252, 43,183,102,175, -111,222, 14, 0,166,252,187,238,101, 73,135,218, 2,128, 77,224,128,235, 50,143,136, 60, 0, 16,165,229,184, 61, 60, 50, 15, 70, - 11,208,120,192, 34,183,218, 52, 39,206,223,237,252,241,228, 97, 50, 0, 56,185,239,135, 70,103,247,175,237, 11, 0,221,135, 77, - 59,214,107,248,244,135, 0,240,245, 47,251,157,119,126,245, 90,141,154,214,221,155,106,137, 58,233, 72,144,169, 52,199,209,215, - 70,228,145,148,148, 36,168,203,189,233, 3, 56,228, 0,239, 10,132,194,200,192,160,160, 8, 0,228,201,227,199,119, 56,150,189, -236, 9,252,248, 50,203,146, 80, 40,124, 63, 43, 43,107, 96,229,191,121,123,123,211, 2, 73,161, 80, 94, 77,131, 5, 0, 90, 35, -112,225, 17,208,165, 93, 51, 76,126,189,159,109,229,255,237,255,117,177, 95,102,220,169,208,165, 27,191, 22,132,133,133,225,201, -147, 39, 86,157, 76,103, 2,206, 39, 1, 50, 67,138, 93,190, 84,250,120,254,103,159,217, 71, 70, 70,138, 60, 61,159,190,132,231, -231,231,183,187,124,249,114,171,133, 11, 23, 78,149, 25, 82, 74,116, 38,104,206, 39,213,174, 91,158,214,176, 70,245,241,217,244, -215, 28, 0, 96,213,236,189,173,142, 94,189, 91, 47, 37, 37,165,199,210,165, 75,139,188,163,163,215,214,227,184,141,177,249,249, - 25,214,164,115,215,137, 24,121,160,233, 84,192,136,137, 19,247,249,251,251,219,122,121,121, 49, 74,165, 18, 66,161, 16,165,165, -165,126,137,137,137,125,239,222,189,171,189,116,237,160, 52,246,238,240, 39,153,194, 22, 6,107,242, 46, 97, 11,229,113,193,193, -241, 35,250,246,245, 25, 48, 96,128,188, 65,131, 6, 0,128,148,148,148,224, 63,254,248, 99,244,209,163, 71,231, 75,216, 66, 86, -103,130,161,182,188,151,107, 2,128, 28,232,224,232,230, 54, 86, 40, 22,135,177, 44,235,253, 44,186,144,197, 89, 44,241,170,252, -252,109,207,239, 79,249,119,140, 22,224,126, 14, 16, 21, 25,129,113,195,162,108, 0,224,147, 81, 75,218,165,165, 60,146,152, 76, - 38, 52, 10,105,220,113,241, 87, 43, 79, 64, 32,192,214,253,167, 43,246,183, 70,243,222,253,100, 44, 88,188, 10,217,177,123,219, -113,234, 71,221, 52,165,106, 33, 0,216, 59, 56, 12,219,187,107,199, 57,175,166, 35,174, 61, 42, 52, 91,165, 89,211,189,121,124, -215,247,158,153,113,231,154,252,116,242, 55,177,159,159, 31, 98, 99, 99,235,116,111, 66,157,104,199,123,122, 38,124,251,209, 71, - 30,157, 59,119,134,173,173, 45, 68, 34, 17, 88,150,141,186,124,249,114,212,130, 5, 11,166, 65,157,168,181,246,222,180,130,111, -189,188,188,186, 13, 30, 62,214,179, 91,239, 1, 24,214,167, 35, 45,136, 20, 10,229,213, 53, 88, 34,145, 40,191,231,132,165,110, -145,109,195,113,243,238, 67,117,106,122, 78, 89,249,255, 84,247,247, 55, 26, 29, 21,216,100,221,209, 63, 96, 52, 26,113,229,202, - 21,220,189,123, 23, 41, 41, 41,152, 55,111,158, 81, 8,188, 93,141,102, 73,231,209,139,156,100,198, 12,219,150,206, 25, 13,118, -110, 63, 39,212,235,245, 56,127,254, 60, 74, 74, 74, 32,149, 74,225,227,227,131, 78,157, 58,137,206,159, 63, 95,111,212,152,177, - 14,189,134, 76, 74, 54,202,124,203, 68, 34, 81, 73,181, 25, 16,137,242,123,140,255,210,173, 73,112,125, 60, 78,205, 86,127,246, -213,175,101, 60, 79, 68,186,180, 76,243,133, 11, 23, 16, 17, 17,129, 93,187,118, 57,151,148,148,124,190,105,211,166,207, 60,191, -223,184, 38, 39, 51,113,118, 13,122, 37,157, 71, 47,114,106,196,157,245,223,187,227, 55,201,221,187,119, 37,235,214,173, 67, 81, - 81, 17,164, 82, 41, 28, 29, 29,225,225,225,129, 70,141, 26, 49,239,190,251,174,109,183,110,137,248,124,230, 36,255, 28,199,193, -137,213,165,179, 92, 83, 98,202, 81, 6, 11,111, 5,174,223,188, 89,208,166, 77, 27,166,242, 62,126,126,126,232,218,181,171,124, -232,208,161,129,211,222,125,143,143, 26, 58,229,177, 89,234,169,171, 77, 19,218, 12,133,179, 46,218, 43,106,244,232, 67,139, 22, - 45,114,244,240,240,128,141,141, 13, 0, 64,173, 86,251,164,166,166,182,155, 63,127,254,240,235,247,118,137, 58, 15,200,200,134, -141,175,190,166,235,249, 79, 69, 44, 22,229,151, 71,141,236,108, 20, 37, 25,153,121, 90, 0, 48,153, 76, 48,153, 76, 48, 26,141, -120,103,218, 20,225,219,195,219, 4,249, 71,190, 31,147,146,149, 87,220,248,244,181,122,229,199,214,166, 41,210,165,168, 84,233, -103,222, 94,240,209, 71, 30,238,238,255,106,249,219,186,101,139,176,184,184, 56,106,193,130, 5, 77,136,178,171,170,241,128, 69, -142, 53,105,214,120,111, 62,252,163,193,226,233,189,155,255,252,213, 17,112, 28,135,232,232,104, 92,188,120, 17, 43, 87,174, 36, -199,142, 29, 83,219,219,216,212,120,111, 66,157,104,215,201, 51, 55, 96,249,242,125,140, 76, 38,195,193,131, 7,241,224,193, 3, - 8, 4, 2, 52,107,214, 12,227,198,141, 67, 84, 84,148,199,228,201, 83, 72,231, 62,163,158,192, 33, 68,243, 87,202, 18,195, 48, - 2, 79, 79,207,247,223,249,240, 83,207, 97,163,223,192,247,223,124, 65, 13, 22,133, 66,121,117,168,178,247, 59, 32,104, 56,228, -231,157,123,110,241,127, 52, 28,242,243, 78, 2, 8, 8, 32,176, 7,234, 71, 70, 70, 90, 84, 42, 21,185,113,227, 6,121,231,157, -119,180,107,214,172, 57,247,199, 31,127,236,101,205,230, 13, 17,205,155,175, 32,128,160, 58,205,102, 14, 14, 14, 1, 1, 1, 5, - 25, 25, 25,228,232,209,163,100,225,194,133,100,219,182,109,228,216,177, 99,228,244,233,211,228,216,177, 99,100,231,206,157,228, -222,189,123,228,209,163, 71, 36, 48, 48,176,160,153,131,131, 67, 13,154, 66, 2, 8, 27, 13, 89, 55,123,223, 77,203,162,144, 33, - 63,207, 32,128,176,177,187,123,104,207,158, 61,185,189,123,247,146,173, 91,183,146,205,155, 55,147,123,247,238,145,194,194, 66, -226,237, 31, 80, 80,126, 92,117,233, 36,128, 32, 34, 34,162, 64,165, 82, 17, 95, 95, 95, 34,149, 74,137,187,187, 59,105,212,168, - 17,105,215,174, 29,233,219,183, 47,121,253,245,215,201,231,159,127, 78, 84, 42, 21,241,247,247,207, 43, 63,174, 58,205, 1,158, -158,138,192,192,192,244,216,216, 88, 82, 29,122,189,158, 20, 22, 22,146,179,103,207,146,192,192,192,244, 1,158,158,138,154, 52, - 21, 64,203,166, 77,155, 22, 20, 22, 22, 18,179,217, 76,210,211,211, 73, 92, 92, 28,121,240,224, 1, 73, 79, 79, 39,122,189,190, - 66,251,225,195,135, 36, 32, 32,160, 64, 1,180,172, 86,243,159,188,149,151,137,231, 54, 63,119,247,190, 30, 30, 30,250,125,251, -246,145,172,172, 44,178,105,211, 38, 34, 0,150,252,219,190, 53,104, 74,129, 94,157, 58,117,226,162,163,163, 73, 76, 76, 12,153, - 51,103, 14,233,221,187, 55,233,211,167, 15, 89,176, 96, 1,201,204,204, 36,153,153,153,164,111,223,190,156, 20,232, 85, 91,249, -172,234,222,116, 0,252, 6, 12, 24,160, 55,155,205,228,201,147, 39, 36, 44, 44, 44, 83, 8,140,181, 1,154,116, 1,100,181,149, - 79,111,192,201,211,211, 51, 39, 58, 58,154,236,223,191,159,248,251,251, 23, 8,129,137,246, 64, 67,123,160,161, 16,152,216,176, - 97,195,130,232,232,104, 82, 84, 84, 68,252,252,252,114,188, 1,167, 23, 45, 75, 0, 4,158,158,158,191,125,249,245, 15, 36, 49, - 83, 75,190,252,250, 7,226,233,233,153, 78, 8, 33,158,158,158,167,104,153,164, 27,221,232,246,191,190,137,234,100,198,108,108, -150, 46, 94,188, 88,100, 48, 24,240,235,175,191,106,198,140, 26,181,223,209,209,145, 21,139,197, 96, 4,181, 15, 72,212, 56, 56, -124, 48,111,238, 92, 71,163,209,136, 91,183,110,161, 85,171, 86,144,201,100,144, 72, 36, 16,139,197, 16,139,197,240,244,244, 68, -126,126, 62,194,194,194, 48,117,234, 84,135, 31,191,255,254, 3,168,213,139,107,210,229,121, 34, 2, 0,142,231,165,245,189,188, - 38,135, 54,109,186, 98,218,180,105, 2, 27, 27, 27, 24, 12, 6, 24,141, 70, 60,120,240, 0,206,206,206, 80, 42, 20, 86,229, 89, - 32, 16, 8,108,109,109,113,246,236, 89,252,242,203, 47, 72, 73, 73, 65, 78, 78, 14,236,236,236, 16, 22, 22,134,198,141, 27,163, - 75,151, 46,120,242,228, 9, 24,134, 97,106,211, 75, 16,139,223, 29, 55,122,180, 91,120,120,120,149,255, 55, 24, 12, 80,169, 84, - 80,171,213,112,119,119, 71,223,190,125,221, 14, 31, 60,248, 46,128,111,171,218,223, 25,240,240, 9, 14, 62,116,227,198, 13, 23, - 66, 8,182,110,221,138,178,178, 50,152, 76, 38, 8, 4, 2,200,229,114, 56, 57, 57,161,123,247,238,112,117,117, 69,112,112, 48, -118,239,222,237,210,183,111,223, 35,206,249,249, 45,139,128,108,250,122, 81, 59,105,121,121, 39,123, 1, 46, 99, 95,127,253,216, -221,123,247, 34,199,142, 29,139,188,188,188, 79,197,115,230,168, 44,192,170,218,142, 15, 1, 28,234,121,122,110, 92,190,124,185, - 32, 55, 55, 23,179,102,205, 42,204, 78, 75,155,227, 0, 92, 2,128, 51,199,143, 71,110,219,182,109,217,214,173, 91, 93,182,108, -217, 34,136,136,136,216, 24,146,158, 30,150, 8,168,235,146, 78, 13,240,254,234,213,171,229, 6,131, 1, 61,123,246,124, 34, 79, - 73,105,206, 2,122,107,143,207, 1,222, 93,249,241,199, 30, 50,153, 12,179,102,205, 42,212,165,165,133,179, 64, 65,165, 93, 82, - 93,147,147,143,143, 31, 63, 62,238,222,189,123, 46,171, 86,173,242, 24, 62,116,232,187, 0,150, 88,123,142,202, 29,218, 61, 61, - 61,131, 7, 15, 31,235,222,168, 73, 83,236,223,185, 9, 63,173, 94,186,145,227,184,159,189,189,189,167, 11, 4,130,111,104,201, -163, 80, 40,175,100, 19, 97,117, 56,187,186,182, 10, 13, 13,197,133, 11, 23,208,180,105,211, 27,142,142,142,172, 68, 38,131, 88, - 44, 6,225,249, 90,143, 87,216,216,244,232,220,185,179,232,234,213,171, 8, 8, 8,128, 66,161,168, 48, 86,229,155, 68, 34,129, -167,167, 39, 74, 75, 75, 17, 25, 25, 41,222,184,113, 99, 15, 0,139,107,211,206, 78, 77,180, 69,242,198,215,151,125,187,162, 97, -155, 54,109,160, 86,151,130,231,121, 40,149, 74,152, 76, 38,136, 68, 34,152, 76, 38, 24, 76,164,212,154,188,114, 28,199, 9,133, - 66, 4, 4, 4, 96,233,210,165, 48, 24, 12,144, 72, 36, 0,128,210,210, 82,168, 84, 42,196,197,197, 33, 53, 53, 21,228,217, 43, -121, 77,216,216,218,246, 27, 52,104,144,180,170,255, 25,141, 70,168,213,106,168,213,106,168, 84, 42, 24, 12, 6, 52,107,214, 76, -122,238,236,217,126,213, 25, 44,163, 92, 62,124,203,150, 45,110, 82,169, 20,122,189, 30, 26,141, 6, 25, 25, 25, 72, 75, 75, 51, -228,231,231,179,118,118,118, 2,127,127,127,129, 76, 38,147, 13, 25, 50,132, 41, 45, 45, 5,195, 48, 24, 48, 96,128,243,246,173, - 91, 95, 3,176,146, 22,127,235, 56, 9, 24, 91,154, 76, 3,219,182,105,115,246,198,205,155, 17, 31,124,240, 1,238,221,187,183, - 92,185,107,215, 5, 29,112,183,166, 99,159, 0,239,174,168,100, 92, 72, 90, 90, 83,243,115,198,197,255,169,113,137, 45, 55, 46, - 35,235,104, 92, 0,192,206,193,161,181,167,167, 39,142, 29, 59,134,244,148,148, 79,234, 98,174, 0, 64, 32, 20,118,234,220,185, - 51, 14, 30, 60,136,204,180,180, 79,158, 51, 87, 0,128, 2,160, 64,244,228,201, 39, 27, 55,110,252,237,205, 55,223,132, 80, 36, -234, 4,150,181,250, 28, 85,117,104,127,247,131, 79,112,112,223,182,141, 57, 57, 57,111, 17, 66,120, 0, 55,104,137,163, 80, 40, -175, 2,117,154, 7,203,195,195,195,219,198,198, 6,217,217,217,104, 28, 26,154, 47,147,201, 32, 21,139, 33,151, 74,173, 58,222, - 96, 48, 52,245,240,240,128, 90,173,134,139,139, 11, 36, 18, 73,197, 38,149, 74, 43, 62,219,217,217, 65, 32, 16,192,219,219, 27, - 6,131,161,105,109,186,172, 42,201,237,248,166, 57,239, 28,222,183,165, 97,223,190,253,224,228, 84, 15,190,190, 62,112,115,115, -131, 66,161,128,175,175, 47,130,130,130,200,250,245,235, 33,176, 15,178,234, 1, 94,217, 52,137, 68, 34,112, 28,135,188,188, 60, - 36, 38, 38,226,222,189,123,136,142,142, 70, 76, 76, 12, 52, 26, 13,172,240, 87,208,234,116,205,171, 10,116, 25,141, 70,168, 84, -170,138,232,149, 74,165, 66, 65, 65, 1,158, 60,121,130, 82,141,166, 69,117,122, 78,206,206,195,194,195,195,133, 0,160, 80, 40, -208,162, 69, 11,252,252,243,207,236,225, 3, 7, 70, 53,137,142,174,231,123,226,132,227,250,117,235, 70,141, 24, 49,130,187,118, -237, 26, 74, 75, 75,113,255,254,125,184,186,186,138,164,114,249,107,180,232,215,141,219,128,214, 69,163,233,211,161, 67,135,100, -181, 90,141,111,190,249, 70, 32,182,179,251,101, 17, 32,172,197, 85,116,236,220,185, 51, 14, 29, 58,132,236,180,180, 57,105, 85, - 24,151, 52,160, 32,253,201,147, 57, 27, 55,110, 68,175, 94,189,192,136, 68,117,238,136,212,174, 93,187,112,158,231, 17, 27, 27, - 11, 71,224,122, 93,143, 15, 12, 10,138,176,181,181,197,131, 7, 15, 96,243, 44,186, 86,229,139, 2,112,233,206,157, 59, 80, 40, - 20,104,220,164, 73,203, 58,158,230, 91, 47, 47,175,156,119, 63,248, 4,251,143, 95, 1, 0, 28,220,183, 45,175,146,185,162, 80, - 40,148,127,166,193, 42, 71, 44, 22, 67, 42,147, 65, 42,149, 62, 53, 70, 50,153,213,199, 50, 12, 3,185, 92, 94, 97,168, 42, 27, -171,202,159,149, 74,165, 85,198, 5, 0, 44,185, 87, 34, 95, 27, 57, 66, 42,145, 72, 96, 50, 25, 65, 8,129, 76, 38,135,163,163, - 35, 2, 2, 2,160,211,105, 49,104,240, 48, 99,134, 74,114, 68,226,211,227,222,139,228,153,101, 89,104,181, 90,148,148,148,160, -184,184, 24,165,165,165,208,235,245,176,162,117,176,162,170, 77, 79, 79,199,142, 29, 59, 80, 84, 84, 4,224,105, 7,234,114, 83, - 85,254, 51, 57, 57, 25, 91,183,110, 69, 74, 74, 10,132, 66,161,213,223, 79,100,100, 36,142, 28, 57, 34,236,218,163,199,134, 83, -254,254,217,167,252,253,179,187,246,232,177,225,208,161, 67, 66,111,111,111,164,166,166,226,214,173, 91, 40, 41, 41, 1, 33,132, -161, 69,191,238, 60, 6, 74,116,197,197,111,126,250,233,167,196,214,214, 22,223,172, 88,209,124, 9, 48,198, 90,227,226, 80,131, -113,113,248,107,198, 5,132, 16,240, 60, 15,142,227, 94, 40,111, 12,195, 48, 98,177,184, 46,229, 25,120,186,212,150,181,250, 2, - 66,200,251,239,124,248,169,231,123, 31,205,199,185, 19, 71,202,255,158, 68,205, 21,133, 66,121, 21,169, 83, 19, 97,118,118,118, -150, 86,171,109,232,239,239,143,204,204, 76, 55, 63, 63,191, 52,169, 88, 12,137, 84,106, 85, 31, 44,185, 92, 30,155,151,151,215, -209,219,219, 27, 44,203, 86,152,169,231,155, 8,203,163, 50,247,239,223,135, 92, 46,175,117,156,185,128, 43,171, 31, 22, 22, 86, - 17, 9,114,116,116,132,163,163, 3,100, 50, 57,150, 45, 91,198,111,248,229,151, 31,229, 97,239,170, 63,156,244, 49,185,189,100, -195, 75,189,128,214, 86, 72, 74,165, 50,182, 65,131, 6,237,149, 74, 37,246,239,223,143,212,212, 84,148,148,148, 64,167,211,193, -104, 52, 66,167,211,193,100, 50, 65, 46,151,163, 73,147, 38,168, 87,175, 30,226,227,227,171,205,123, 73, 81,209,254,216,216,216, -246,109,218,180,169,136,160,116,235,214,141,233,214,173,155, 75,249,239, 58,157, 14,133,133,133,184,113,227, 6, 78,159, 62, 13, -134, 97,144,148,148,196, 25,245,250,157,180,232,191, 24, 6,224,170,112,227,198,223,166, 78,157, 58,169, 99,199,142,224,128,190, - 0,182,254,167,140, 75, 57,209,209,209,113, 28,199,117,108,212,168, 17, 84, 64, 91, 0, 7,235,100, 30, 31, 61,186,195,178,108, -143,230,205,155, 99,255,158, 61,145, 0, 82,171,218, 79, 11, 68, 70, 68, 68, 64,175,215,227,126, 66,194,109,107,205,149,167,167, -231,134,119, 62,252,116,226,176,209,111, 96,255,206, 77, 56,184,111, 91,198,143,107,150,251, 18, 66,204,180, 84, 81, 40,148,127, -188,193, 42, 41, 42,186, 29, 23, 23,215,176,101,203,150,216,176, 97, 67,155, 14,237,219,103, 73,164, 82, 86, 42,145, 64, 96, 69, - 5,162,215,106,207, 92,190,124,185,109,175, 94,189, 68,215,174, 93,131,135,135, 71,133,193, 42,255, 41, 18,137, 64, 8,129, 82, -169,196,177, 99,199,204,122,173,246, 76,109,186, 28,203,113,130,103, 6,143, 16, 2,149, 74, 5,137, 68,130,245,235, 55, 96,211, - 47,191,188,158,153,147,179, 55,184,149,211, 71, 0,228,255,177,138, 89,167, 59,123,230,204,153, 86, 51,103,206, 20,251,248,248, - 64,165, 82,161,164,164, 4, 69, 69, 69, 40, 45, 45, 69,105,105, 41, 74, 74, 74,160, 82,169, 32,151,203,241,232,209, 35,139, 65, -167, 59, 91,157,158,204, 96,216, 55, 97,194,132,143,239,220,185,227, 41, 18,137, 96,177, 88,192,243, 60,120,158,135,217,108,198, -163, 71,143, 16, 31, 31,143, 7, 15, 30,160,184,184, 24, 98,177, 24, 66,161, 16, 49, 49, 49, 37, 54, 22,203, 30, 90,244, 95, 28, - 49,176,255,242,229,203,147,198,141, 27, 7, 47, 31,159, 46,200,204,180,202,184, 28,168,193,184,168, 95,192,184,252,201,248,104, - 52, 55,147,147,147, 59,118,237,218, 21,158, 62, 62,203,155,100,102,158, 74,168, 67, 63, 44,142,101, 47, 93,190,124,185,199,248, -241,227,177, 97,195,134,229,174,201,201,199, 11,158,107,206,116, 5, 92, 27, 4, 6, 46,159, 56,113, 34, 78,158, 60, 9,142,101, -171,141,200, 61,215,161,189,254,224,225, 99,125,105,135,118, 10,133,242, 79,162, 78, 77,132,140, 86, 59,119,222,188,121, 22,161, - 80,136, 97,195,134,217, 29, 60,116,104, 68,204,221,187, 1,249,249,249,142, 28,199,213,170,101,167, 86,175, 89,188,120,177,202, - 98,177, 32, 36, 36, 4,197,197,197,224, 56, 14, 34,145, 8, 34,145, 8, 12,195, 64, 32, 16,192,214,214, 22,241,241,241,216,181, -107, 87,169,157, 90,189,166, 54, 93,158,231, 99,127,255,253,119,136, 68, 34, 34,151,203,193, 48, 12, 68, 34, 17,214,175, 95,159, - 63, 55, 39,103, 63, 0, 8, 5, 2, 19, 0, 8, 4,140, 85,189,114, 25,134,169,181,125, 82, 42,149,130,127,218,185,191,214,125, - 93, 45,150,213,235,214,173,211, 36, 37, 37, 65,171,213, 86, 68,219,202,202,202, 42, 58,205,171, 84, 42, 48, 12, 3,131,193,128, -139, 23, 47,106, 92, 45,150,213,213,233, 21, 1,185,153, 73, 73,131,218,180,105, 83,148,156,156, 12,181, 90,141,216,216, 88,156, - 62,125, 26,187,119,239,198,201,147, 39,241,232,209, 35,176, 44, 11,111,111,111, 16, 66,112,224,192, 1, 53,171,209,244, 45, 2, -114,105,209,175,158,250, 30, 30, 61,220,221,220,210, 93, 93, 92, 50,235,123,120,244,120,254,255, 14,192,195,135, 15, 31,130,101, - 89, 4, 4, 4,212,171,169, 31, 22, 97,217,203,151, 47, 95,198,248,241,227,225,219,176,225, 50,127,192,245,249,125,252, 1, 87, -255,192,192,101,229,198,133,176,236,229,186,166,217, 14,248,238,163,143, 62,210, 75, 36, 18,236,218,181, 43,192, 18, 20,244, 64, - 4,140,177, 5, 66,187, 2,146,218,142,247, 4,126,252,252,243,207,115, 25,134,193,182,109,219, 92, 28, 2, 3,227, 68,192, 4, - 7,160,190, 3, 80, 95, 4, 76,112, 8, 12,140,219,181,107,151, 11,203,178,152, 49, 99, 70,174, 39,240, 99,117,122, 66,161,240, -253,236,236,236,129, 89, 89, 89,157,179,179,179,125,127, 92,179, 28,231, 78, 28,193, 79,171,151,110,204,201,201,121, 43, 47, 47, -239, 70, 86, 86,214,184,204,204,204, 56, 90,226, 40, 20,202,171, 8, 83, 85, 63, 39,113,219, 37,121, 0,113,235,210,174, 25,110, -222, 77, 84,187, 56,217,159, 40,255,159,234,254,254, 70, 3,218,121, 52,251,230,155,111, 32, 18,137,144,145,145,129,132,132, 4, -216,219,219,227,131, 15, 62, 48, 90,140,198, 65,229,235,157, 49, 12, 19, 69, 8, 57,253, 76,243, 20,203,178, 78, 50, 99,134,109, -132, 83,114,195,173,155, 55, 10,237,236,236, 80, 86, 86, 86, 49,173,128, 82,169,132, 66,161,192,189,123,247, 48,254,141, 55,185, -199,108,243,138,137, 70,203,215, 59,171,172, 9,134, 17, 2, 64, 95, 39, 39,229,125,153,108,150,179,187,251,236,247,222,123, 79, -209,165, 75, 23, 72, 36, 18,180,106, 27,153,107,211, 98,246,119, 2, 1,195,102, 22,149,206, 11,172,239,229,144,144,148, 10,128, -121,186,102,225,179,181, 8,171, 74,103, 83,249,189,128,173, 63,125, 97, 31, 22, 22,246, 52,223, 42, 21,242,242,242,144,159,159, - 15,149, 74, 5,173, 86, 11, 0, 56,125,250, 52,206,222, 72, 46,205,177,237,249,164,186,116,254, 43,239,169,118,141, 21, 15, 27, -124,183,122,165,208,209,209, 17,121,121,121, 40, 40, 40,128, 74,165,130, 94,175, 7,199,113, 40, 45, 45,197,161, 35, 71,185, 39, - 92,211, 20,163,172,190,166, 54, 77,104, 51, 20,245,202,174,120, 71, 52,241, 39,147, 38, 77,178,179,183,183, 7,207,243, 40, 41, - 41, 65,122,122, 58,146,147,147,113,241,226, 69,109,190,202, 4,173, 75,207,204,242,137, 70,171,188,158, 47,171, 80,253, 47,106, - 62, 43, 75, 0,224,229,233,153,157,150,150,230,198,113, 28,188,189,189, 89, 85,113,241, 50, 41,112,210, 14,200, 1, 64, 10,129, -207, 86,127,247,221,155,131, 7, 15, 70,235,214,173, 51,114,243,242, 26, 84, 85,150,192, 48,194, 16,192, 65,231,227, 19,127,227, -198, 13,143,244,244,116,140, 31, 63,190, 48,237,241,227,138,105, 26,212, 64,164,127, 96,224,178, 93,187,118,185, 52,108,216, 16, - 77,155, 54,205,149,151, 79,211, 80,117,249,172,254,222,124,248, 71,131,105, 67,195, 91,191,243,206, 59, 96, 89, 22, 23, 47, 94, -196,245,235,215,145,150,150,134, 43, 87,174,168,236,109,108, 70,213,116,111, 66,157,104,215, 55, 88, 27,176,109,219, 86, 70, 34, -145, 96,227,198,141,184,115,231, 14, 0, 32, 34, 34, 2, 19, 39, 78, 4,203,178, 24, 59,118, 28,249, 35, 81, 81, 49,209,104, 85, -101,201,199,199, 39,156,231,249, 21, 12,195, 72, 8, 33,173,179,179,179,229,222,222,222,217,217,217,217,190,117,233,115, 69,203, - 39,213,164,154,255, 28,205, 87,141, 90,215, 34,252,114, 45, 28,254,188, 28,199,219,217,191,255,186, 68,212,187, 79,223,208,121, -159,206, 21, 68, 68, 68,192,215,215, 23, 17, 17, 17,184,115,231,142,172,113,227,198,181,173,119, 86,214,107,200,164,228, 94,189, -122, 57,190,251,238,187, 14, 93,186,116, 17,123,121, 61, 93, 87, 55, 62, 62, 30,199,142, 29, 51,239,216,177,163, 52, 75, 26,169, -186,114,236,215, 50,107,214, 59, 59, 86, 82,162, 3,240, 69, 51,147,233,151,207,231,205, 91, 16,214,180,233,164, 15, 63,252, 80, - 96,107,163, 20, 47,153,247,150, 28, 0,190,252, 97,183,195,224, 17,175, 99,117, 16,208,101, 76,213,235,188, 85, 78,103,102, 78, -126,218,152,137, 35,130,222,125,107, 12, 55,112,224, 64, 27, 91, 91, 91,248,250,250,194,201,201, 9, 41, 41, 41,136,141,141, 37, -167, 78,157, 42,187, 29,159, 34,222,180,251,100,154,212,214,205,154,117, 3, 53,189, 6, 79, 72,153, 48, 97,130,211,208,161, 67, -237,194,194,194,196, 98,177, 24,114,185, 28, 69, 69, 69,200,200,200, 48,159, 63,127,190, 44, 75,210,190,228,202,241, 77, 26, 43, -215, 34,212,119, 30,189,232,209,165, 83, 11,103,196,199,198,142,227,129,230,102,179,217,155,227, 56, 70, 32, 16,228,240, 60, 31, -107,214,104,126, 51, 70, 44, 92, 69,215, 34,180, 14,142,227, 36, 28,199, 65,165, 82,225,212,169, 83,162,199,143, 31,127,118,247, -238,221,207,178,179,179, 97,177, 88, 48,124,248,112, 68, 68, 68,224,220,185,115, 40,200,203, 59, 92,147, 86, 34,160,150,101,102, - 78,124,251,237,183,143,109,221,186, 85,112,247,238, 93,151,141, 27, 55,254, 90,149,113, 25, 55,110, 28,159,151,158, 62,209, 88, -195, 28, 88,181,220,155,133,199,119,125,127,119,200,176, 17, 77, 22,206,255, 76,220,161, 67, 7,184,184,184, 32, 50, 50, 18,102, -179,217,209,138,123, 83,211,185,207,168, 39,205,155, 55,183, 89,181,106,149,199,155,111,190,137,233,211,167, 3, 0,244,122, 61, - 78,158, 60,137, 25, 51,102,228,166,139,218,106,111,159,219, 85, 99,249,124, 22,153,234, 9, 0,222,222,222, 23, 0,116, 6,240, -132,118,104,167, 80, 40,255,104,131, 5,252,107,189,179, 75,215,227, 80,121, 57,142,167,184, 38,176, 46,195, 31, 79,157,189,188, -169, 20, 90, 39, 49, 99,180,143,185,115,135, 73, 78, 78,174,241,100,229,235,157, 25,101,190,101,202,236,194, 54,223,173, 94,253, -193,134, 13, 27,122,148, 79,197, 32,151,203, 99,245, 90,237, 25, 59,181,122,141,177,161,239,153,186,174,157,119,175,184, 56, 15, -192,180, 80,142,251,238,141, 73, 83,190, 22,216,250,136, 63, 93,178,193, 32, 20, 8, 76,143,178, 11,176, 58, 8,176,177, 98,192, -163,206, 4,196, 22,185,177, 9,232,154,184,124,209,162, 89,171,191,253,182,141,210,214,182,139,133,101,131,121,158, 7,225,184, - 36,189, 94,127, 1,102,243,141, 76,175,201,223, 74,109,221,136,181,235, 6, 26,229, 13, 52,238,218, 11,109,246,237,217,243,254, -177, 99,199,254, 45,239,158, 60,255,221, 19,251, 6,167,173,201,123,229,125, 12,192, 85,228,231, 95,173,246,109, 3,116, 45, 66, -171,111, 10,158,159,236,228,228,180,165, 71,143, 30,242,168,168, 40,244,239,223, 31, 29, 58,116, 0,207,243, 32,132, 64,163,209, - 96,247,238,221,248,250,235,175,147, 26, 0, 95,212,166,103, 4,206,200,142, 30,237,219,188,121,243,141, 53, 25,151,103,230,170, -214, 62,135, 53,223,155,178, 36,214, 97, 80,234,232,119,151, 6,153, 74,115, 28,157,149,172, 71,124, 92,172,192,218,123, 19, 14, - 33, 26,238,206,238,182,195,135, 14,125, 87, 40, 18, 69, 62, 27,209, 72,238, 39, 36,220, 46, 95,236, 25, 17, 19, 79,213,165, 44, - 17,242,116,238, 57,218,161,157, 66,161,252,227, 13,150, 72, 36,202, 47,143,242,136, 68,162,252, 39, 7,166,188, 94,147,136,175, -167,103,143,103,111,199,168,109, 45,194,242,207,119,213,106,205,179, 25,218,171,156, 68, 84,252,220,254,117,201,212,131,252,252, - 68, 0, 3,128, 52, 32,241,105,119, 22,113,155, 47, 63,169,156,167,106, 47,200,159,206, 43, 41, 78,205,203,187,132,167,205, 57, - 85,118,198, 21,251, 73,138,107, 75,231,243,121,191,156,145, 81,250, 44,223, 85,231,221,163,246,188,139,234,120,125, 68,127,225, -122,254,211,200, 42, 44, 60, 0,192,214,231,200, 17,247,227, 71,142,188, 54,107,230,204,225,158, 94, 94,129, 46, 46, 46, 78,118, -118,118,130,107,215,174, 37,179, 6,195,119, 45,128, 77,215, 1,157, 53,154, 70,224, 76, 72,122,122,216,200,161, 67,223,101, 68, -162, 78,149,141, 11, 97,217, 43, 1,192,143, 70, 43,102,111,175,243,189, 41,171,251,189,153,249, 52, 29, 75,192,178, 75,112,239, -222, 95,190, 55,121,158,255,210,219,219, 91, 67, 59,180, 83, 40,148,127, 20,127,231, 58, 60, 0,162,168, 38,213,124, 85, 52,159, -122, 20,216,211,235, 73, 53,169, 38,213,164,154, 47, 95,243, 31,189, 22, 33,133,242, 15,127, 25,225, 0,148,210, 43, 65,161, 80, - 40,148,218, 96, 0, 68, 85, 83,153, 88, 61, 58,128, 97,152,168, 23,168,172, 78, 83, 77,170, 73, 53,169, 38,213,164,154, 84,243, -159,165, 89,155,246, 43, 51, 58,145, 54, 17, 82, 77,170, 73, 53,169, 38,213,164,154, 84,147, 54, 17,190,220, 77, 0, 10,133, 66, -161, 96,209, 34, 70, 0, 48, 12,176, 72, 0,236, 21, 2, 35,133, 79,127,127,113, 70,142,100,170,156,132,246,253,247, 25, 59,122, -197, 41,148, 87, 27,218, 7,235, 63,136,167,167,167,159,187,187,251,207,132, 16, 38, 63, 63,127,114, 78, 78, 78, 58,189, 42,255, -125, 56, 59, 59,247, 96, 89, 22,106,181,250,204,171,152,191,176, 32,102, 40, 17,160,241,191,194,218, 72, 79, 72, 34, 91,170,218, -183, 73, 48, 51, 30,204,191,230,210, 98,120,220,143,127, 68,126,183,246, 92, 12,195, 8,134,244,117, 93, 1, 0, 7,142, 21,204, -254, 59,230,197,242,242,242,106,228,236,236,124, 66, 40, 20,138, 56,142,155, 22, 27, 27,123,164,122, 3, 52, 82, 8, 0,174,138, -253,115, 29,235,185,204,249,124, 22, 35, 54, 25,191, 81, 25, 13, 6,181, 64, 36, 74,145, 74,148,151, 89,129,205,177,204,188,190, - 9, 85, 29,191,103,207,158,106, 87,215, 14, 15,102,250,134, 54,105, 50,176,101, 83,197,147, 21,107,218,172,238, 18,224, 34, 78, -206,136,177, 93,187, 37,253,103, 87, 39,239,129, 31,188, 37, 58, 34, 35,220,184,229,191,146, 50,122,151, 89,207, 87, 12, 83,207, - 12, 52, 21,203,100,190, 28,203,186, 51, 0, 17,138, 68,121, 22,163, 49, 67, 2,220,155, 67,136,234, 85,215,148,200,100, 62, 28, -203,186, 3,192,127, 99, 58, 41,181, 24,172,192,192,192, 91, 2,129,192,167,124,141,191,202,139,213,150,127,126,254, 39,199,113, -153, 15, 30, 60,104,101,237,201, 27, 54,108,104,111, 48, 24, 94, 99, 24,230,117, 0, 32,132,108,151,203,229,187,147,147,147, 95, -168, 35,113,195,134, 13,237, 9, 33,179, 21, 10, 69,119,131,193, 16, 6, 0,114,185, 60, 94,175,215,159,101, 24,102,197,139,232, - 50, 12, 35,242,244,244, 28,105, 99, 99,211,141,101,217,110,132, 16, 70, 36, 18,157,211,233,116,103,115,114,114,246, 16, 66,216, -186,106,122,121,121, 41,156,157,157,151, 4, 5, 5,141,121,247,221,119,139,234,213,171, 23,178,104,209,162,155,225,225,225, 59, -138,139,139,231,101,103,103,235,255, 27, 10, 7,195, 48,129, 30, 30, 30,219,197, 98,177, 48, 35, 35,163, 27, 0,248,250,250,158, - 51,153, 76, 92,126,126,254,235,132,144,199,117,209,115,117,117,181, 17,139,197,237,108,108,108, 90,217,216,216,116,230, 56,174, -241,179,245, 19,239,107,181,218,139, 22,139,229,150,197, 98,185, 86, 80, 80,160,253,111,185, 65, 24,134,177,115,115,115,219,202, - 48, 12, 24,134, 9, 38,132,104, 94,181,135, 0, 17,160,113, 66,252,131,144, 10, 19, 21, 22, 90,195, 5,129, 95, 21,251, 90,109, -176,250,245,112,236, 51,112, 96,115, 1, 0,152,205, 55,251, 0, 56,250,178,205, 85,191,126,253,174,126,247,221,119, 78, 6,131, - 1, 31,125,244,209,246,224,224,224, 31,147,146,146,230,214,116,156,157,157,221,140, 47, 22,255,160,124,246, 44,115,227,121,222, - 45, 39, 39, 35, 56,241, 65,108,159,196,196,184,165,102,237,239,215,204, 68, 56, 69,165, 27,244,192,154,116, 52, 9,100, 6, 12, - 30, 57,180,255, 23, 95, 44,196,152, 81, 99,234,199,199, 27, 20,222,246, 79,164,165,102,155, 32, 23, 23,159, 65,159,124,186,156, -185, 22,125,126,208,158,221, 27,206,126, 50,137,233, 78, 77,150, 85,247, 34,243,165, 72,212,206, 41, 52,180,243,168, 3, 7, 96, -235,235, 43, 18,201,100, 2, 0, 96,141, 70,223,178,140, 12,207, 93,131, 6,181, 93,196, 48,231, 23, 16,114,157,106,254,255,107, - 82,172, 52, 88, 2,129,192,231,206,157, 59,110, 54, 54, 54,120,102,126,192,113, 28, 56,142,171, 88, 84,152, 16, 82,241,147,101, - 89,116,237,218,213,170, 55, 88, 79, 79,207,238, 0,222, 8, 15, 15, 31, 62,123,246,108, 73,199,142, 29,193,113, 28,206,158, 61, - 27,185,122,245,234,239,189,188,188,246, 3,216,148,147,147,115,198,218, 55, 92, 79, 79,207,222, 54, 54, 54,219, 62,251,236, 51, -251,200,200, 72,145,167,167, 39, 0, 32, 63, 63,191,221,229,203,151, 91, 45, 92,184,112,154,167,167,231,216,156,156,156, 19,214, - 94, 28, 31, 31,159,240,224,224,224,189,125,251,246,245,105,213,170,149,188, 81,163, 70, 32,132, 32, 38, 38,230,205,196,196,196, -209, 71,143, 30, 93,224,227,227, 51,194,218,245,212, 24,134, 97, 2, 3, 3, 39,120,120,120, 44,153, 57,115,102,189, 33, 67,134, - 72,227,226,226, 74, 2, 2, 2,152,253,251,247,187, 30, 62,124,120,218, 79, 63,253, 52, 50, 40, 40,104,222,227,199,143, 55,147, -170,214, 49,122,142,224,224,224, 91, 2,129,192,199, 26, 3,204, 48, 12, 88,150,181,202, 4, 51, 12,211,162, 65,131, 6,187, 47, - 93,186,212, 32, 53, 53,149, 27, 50,100,200, 22, 0, 56,123,246,108, 83,139,197,194,244,234,213,235, 24,195, 48,175, 17, 66, 98, -172,201,187,183,183,119, 51, 87, 87,215,131, 67,134, 12,169,231,231,231,167,244,241,241, 97,228,114, 57,132, 66, 33,202,202,202, -188, 18, 19, 19,163, 98, 98, 98,244, 87,174, 92, 41,246,246,246, 30,148,149,149,117,175, 14, 15,222, 14,110,110,110,227,196, 98, -113, 56,203,178,222, 0, 32, 18,137,178, 44, 22, 75, 92,126,126,254, 86, 66,200,213, 23,189, 65,220,221,221,191, 95,178,100,137, - 75,126,126, 62, 89,182,108,217,247, 0, 38,188,170, 15,131,237, 59,246,224,214,205,235, 0, 32, 97, 24,134,121,190,252, 49, 12, -195, 52, 14,134,228,195, 15,103,162, 85,235,182,120,125,204,200, 90, 53,135,244,119,249, 66, 42, 20, 57,235, 76,198,235,133,106, -193, 65, 63, 55,233,208,177, 35, 91, 61, 1,128,227,199, 98,135,182,109, 91,239,178,139, 3, 63, 88, 41,149,181, 53,113,108,209, -129, 63, 10,231,215,197, 76,121,120,120,156,176,179,179, 83,150,148,148,228, 22, 21, 21,173,237,215,175,223,151,171, 86,173,114, -122,242,228, 9, 50, 50, 50,240,198, 27,111,216,102,101,101,189,235,231,231, 23,157,158,158, 94,109, 36, 75,163,209,172, 89,178, -120,230,124, 59,123, 39,161, 82, 97, 3, 91, 59,123, 52,104, 16,140,214,109, 34, 17,213,115, 16,158, 60, 73,108,183,123,231,134, - 59,194,156,189, 95,113,210,136, 47, 85,170, 6,213, 62,151,194, 66,152, 46,229,230,106,254,252,133,120,248,224,129, 38, 53, 69, -240,222, 31, 7, 68,202,190, 61, 66,101, 38,115, 89,234,181,232,243, 13,218,181,239, 10, 0,173,246,236,222,112,118,209, 88,166, -199,130,109,175,158,121,127,153,230,234, 11,177,120, 66,239, 85,171,220, 34,166, 77,147,148,165,164,152,159,172, 91,167,203,187, -120,145, 19,201,100,196,183, 79, 31,198,181, 91, 55,249,180,251,247, 37, 87,150, 45,235,188, 84, 42, 13,248,212,100,218, 70, 53, -255,255, 52, 41,117, 51, 88,176,177,177,193,174, 93,187, 32, 22,139, 33, 18,137, 32, 22,139,171,253,236,231,231,103,141, 9, 26, - 22, 22, 22,246,195,204,153, 51,221, 7, 14, 28, 8, 39,167, 63,175,178, 49, 96,192, 0,244,235,215, 79,146,156,156, 60,122,207, -158, 61,163,183,108,217,146,235,233,233,249, 94,206,179, 5,155,107,168,188,187, 5, 4, 4,236,223,177, 99,135, 66,175,215,227, -252,249,243, 40, 41, 41,129, 84, 42,133,143,143, 15, 58,117,234, 36, 58,127,254,124,189,209,163, 71,239,247,246,246, 30,144,149, -149,117,174,182,180,122,120,120,180,114,117,117,189,240,203, 47,191,200, 67, 67, 67,153, 71,143, 30,161,121,243,230, 0,128,162, -162, 34, 12, 24, 48, 64, 62,116,232,208,192,119,222,121,231,154,135,135, 71,151,220,220,220, 91,181,228,189,101,243,230,205, 55, -247,233,211,199,107,206,156, 57,246,182,182,182, 72, 77, 77,205,241,240,240, 8, 46, 55, 63,131, 7, 15,150,246,236,217,211,115, -237,218,181,107,142, 30, 61,250,145,167,167,231,132,156,156,156,219, 53,233, 10, 4, 2,159,219,183,111,187, 41,149, 74,228,229, -229, 97,251,246,237,120,247,221,119, 33, 20, 10,145,159,159,143,221,187,119,227,189,247,222,131, 80, 40,132, 90,173,182,202, 4, -219,216,216, 68, 53,111,222,252,215,179,103,207,250, 56, 58, 58,194,203,203, 75,240,249,231,159,135, 7, 4, 4, 40,234,215,175, - 47,204,201,201,193,254,253,251, 3,198,141, 27,119, 80, 46,151,191,105, 48, 24,106,109, 58,115,118,118,254,109,243,230,205,126, -119,239,222,197,186,117,235, 80, 92, 92, 12,169, 84, 10, 71, 71, 71,120,120,120, 32, 56, 56,152,153, 54,109,154,178,123,247,238, -202,133, 11, 23,254, 6,160,133, 21, 15,221,230,110,110,110, 63,143, 30, 61, 58, 96,209,162, 69,142, 30, 30, 30, 40,127, 33, 80, -171,213, 62,169,169,169,237,230,207,159, 63,194,221,221, 61, 57, 63, 63,127, 10, 33,228,110, 29, 31,234, 45,122,244,232, 49, 96, -200,144, 33,194,156,156, 28,108,221,186,117, 0,195, 48, 45,172, 53,149,255,107,220,186,121, 29,147,223,249,160,204,203,215, 87, -114,248,208,206,193,101,101,191, 92,182, 21, 56,138, 0,160,140, 87,177, 29,219,217,118, 26, 56,104,180,164, 95,255, 33,101,191, -252,180,198,214, 26,131, 37, 21,138,156,119,109,155,154,113,241, 74, 82,227, 19,167, 83,163,134, 12,138, 18,136, 36, 33,129, 0, - 48,107,230,219,210, 3,135, 78,255,216, 59,170,126, 78,231,142,193, 25,163,198,174,243,173,139,185, 10, 8, 8, 56,127,226,196, - 9,119,169, 84,138,146,146, 18,231,141, 27, 55,174,108,219,182,173,224,241,227,199,120,240,224, 1, 82, 82, 82,160, 86,171,209, -166, 77, 27,219,132,132,132,181, 0,170, 53, 88, 5,250, 97, 75, 2,220, 10,191,243,118,118,106, 96, 48,171,221, 56,182,168,201, -217,211,119,155,237,219,163,139,112,243,240, 9, 30, 61,122, 50, 62,153,187, 92,252,251,190,205,243, 47, 92, 60, 9,160, 65,245, - 51,248, 19,116,248,116,222, 92,148,106,140, 24, 59,230,109,140, 27,243,182, 51,129,201,147,112, 6, 27,147,190,196,209, 65, 18, -127,100,243,206, 61, 67, 1,248, 84, 50, 89,103,168,201,170,158, 47, 68,162,182, 3,126,248,193, 53,252,173,183,100,119, 23, 45, -210, 22, 94,188,168, 15,234,215,175, 36, 98,234, 84, 35, 0,104, 82, 82, 36, 15, 23, 44, 80,186,118,238,172,104, 63,123,182, 19, -103, 50,121, 44,102,152, 54,159, 19,114,163,174,154, 13,198,140,225, 86,236,223,223,250,218,178,101, 93,177,120,177,176, 91, 68, - 68,204,188,159,126,202,250, 43,154, 47, 51,157,217, 23, 46, 24,181,141, 27,163,233,240,225, 69,222,206,206,198,151,153,247,191, -146, 78, 74, 21,117, 72,117, 65,146,144,144,144,188,196,196, 68,183,253,251,247,215,106,174,196, 98, 49, 60, 61, 61, 17, 25, 25, -153, 31, 27, 27,235, 94,195, 67, 49, 35, 35, 35,195,135,101, 89, 72,165,210, 26, 19,166,209,104, 16, 27, 27,139, 81,163, 70,101, -102,103,103, 87,251,224,173, 87,175,158,157,147,147,211,147,115,231,206,185,196,199,199,227,214,173, 91, 8, 8, 8,128,147,147, - 19,196, 98, 49, 44, 22, 11, 74, 75, 75, 17, 18, 18, 2,133, 66,129,126,253,250, 21, 22, 23, 23, 7, 20, 23, 23, 87,251, 32,171, - 95,191,190, 76, 44, 22, 39,237,219,183,207, 55, 60, 60, 28, 55,110,220,128,175,175, 47, 60, 60, 60, 0, 0, 41, 41, 41,184,124, -249, 50,250,245,235,135,184,184, 56, 76,157, 58, 53,195, 98,177, 4,167,166,166, 26,171,109, 50,104,210, 36,103,207,158, 61,153, -161,161,161, 6,173, 86, 43,200,203,203, 19, 95,188,120,145,213,104, 52,182,106,181, 90,172, 82,169,196,165,165,165, 34,173, 86, - 43, 22, 8, 4, 18,163,209, 40,190,118,237,154,176,168,168,200,190,166,235, 20, 26, 26,154,247,224,193, 3,183, 67,135, 14,161, -105,211,166,216,191,127, 63,102,205,154,133, 43, 87,174,192,215,215, 23,123,246,236,193,236,217,179,145,152,152, 8, 23, 23, 23, -116,239,222,189,198,239, 8, 0,130,130,130, 30,197,198,198, 6, 74, 36, 18, 60,121,242, 4,153,153,153,229,235,217,161,160,160, - 0,143, 31, 63, 70, 86, 86, 22,130,130,130, 48,102,204,152,199,153,153,153, 65,181, 21,180,150, 45, 91, 22,156, 57,115,198,165, - 89,179,102,200,203,203,131,163,163, 35, 28, 28, 28,224,232,232, 88,241, 57, 32, 32, 0, 51,103,206, 68,179,102,205,242, 83, 83, - 83,221,107, 51, 63, 77,155, 54, 61,113,230,204, 25, 23,123,123,123,228,230,230,162,180,180, 20, 34,145, 8, 74,165, 18, 46, 46, - 46,144,203,229, 0,128,164,164, 36,244,239,223,191,240,201,147, 39,189,173, 53, 71, 12,195, 8,220,221,221, 31,220,187,119, 47, -152, 16,130,244,244,116, 36, 38, 38,226,157,119,222, 73, 50, 24, 12,161,175,210,154,122,149,250, 85, 73, 38, 76,156, 44, 25, 50, -104,176, 46,230,214,113, 94,129, 11,104,211, 66,161, 2,128, 27, 49,122, 71, 61,186,160, 69,171, 62,130, 3,135, 14, 42, 55,111, -250, 69, 12, 30,238, 96,144,152,240,144, 44,174, 78,123, 64,111,199,241,179, 63,232,211,184,115,199,206,162,210, 82,226,241,235, -150,245,109,210,146,159,184, 3,128,127,195,128,188, 73,227,223,190, 97,111,207,228, 94,188,114,145, 93,177,230,248,253, 35, 39, - 84, 91,172,136, 44, 7,248,249,249, 69,255,246,219,111, 46,174,174,174,112,112,112,128, 86,171,133,217,108, 70, 66, 66,130, 97, -215,174, 93, 22,123,123,123,187,220,220, 92,168, 84, 42,136, 68, 34, 68, 71, 71,167,231,230,230,250, 63,175, 85,222, 7, 11, 0, -222,233,219, 88,220,164,123,176,147, 68,198, 42, 20,226,135,158, 96, 56, 25, 67,108,221,207,158,141,110,118,238,194,165,215,251, - 13, 24,229,218,190,125, 55, 44, 95,250,137, 37, 61, 55, 47, 66,165, 27,244,160,170, 62, 88,141,131,153,238, 67,134, 15, 29,249, -197, 23, 11,177,112,254, 34, 28, 57,116, 64,109,107, 35, 48,218, 59,138, 29, 58,183,235,104,152,249,238,224, 12, 93, 89,166,239, -202, 31,215,143,233,217,123,164, 79,187,246, 93,113, 45,250, 60,246,236,222,112, 75,194, 89,104,115,225,115, 44, 98, 24, 39,199, -128,128, 41,239, 39, 37, 73,238, 46, 92, 88,198,102,103,151,180,154, 49,163,176,170,125, 51, 79,157,178,145,122,121,217, 59, 13, - 26, 84,111,141,191, 63,177,228,231,255, 92, 85, 31,162,170, 52,111,120,122, 58,254,126,238, 92, 15, 94, 36,234,242,238,244,233, -138,168,168, 40,148,150,150,226,200,145, 35,216,177,125,187,209,195,221, 61,214,241,230,205, 59, 1, 57, 57,159, 89,171,217,106, -198,140, 66,142,227,152,169, 75,151,246,124,152,145,209, 61,191,168,168, 62, 0,184, 57, 56,100,132,251,248,220, 90,181,109, 91, -226,247, 13, 26,240,214,166,115,215,149, 43,238,199, 10, 10,222,114,116,116, 84, 20, 20, 22,138,100, 82,105, 81, 68, 80,208,158, -175,166, 79, 63,111,186,115, 71, 34,247,241,177,119, 24, 48,160,206,121,111, 53, 99, 70,161, 90,167, 19,205,251,238,187,142,217, - 69, 69,245,181, 38, 83,144,186,172,204,131, 53,155, 5,118, 10, 69,145,127, 80, 80,190,230,204,153, 28,255,178,178, 15, 86,107, -181,249,180, 84,254,197, 8, 22,195, 48, 32,132, 88, 21,189, 18,139,197,127,234,163, 85, 3, 18,161, 80,136, 27, 55,110, 32, 63, - 63, 31, 77,155, 54, 69,131, 6, 13,254,180,195,147, 39, 79,112,244,232, 81,168, 84, 42,180,108,217, 18, 0, 36, 53, 9,218,217, -217,125, 56,119,238, 92, 71,163,209,136, 91,183,110,161, 85,171, 86,144,201,100,144, 72, 36,127, 50,127,249,249,249, 8, 11, 11, -195,212,169, 83, 29,190,255,254,251, 15, 81,195, 26,114,132,144,233,163, 71,143,118, 11, 15, 15, 7, 0,100,100,100,148,167, 5, - 0,224,234,234,138,152,152, 24,180,106,213, 10,238,238,238,232,219,183,175,219,193,131, 7,167, 3, 88, 81,109,198, 37, 18, 65, -104,104,104,235,103, 17, 34, 8, 4,130,135,246,246,246,174,238,238,238, 54,246,246,246,255,150,199,141, 27, 55,170,164, 82,169, -197,154,139,154,155,155,139,240,240,112,168,213,106, 0,128, 86,171, 69, 80, 80, 16, 74, 75,159,118, 57, 51, 26,141,240,242,242, -130, 94, 95,115,215,174,230,205,155, 47, 12, 13, 13,237,213,181,107, 87,153, 88, 44,198,221,187,119, 17, 17, 17,129, 93,187,118, -193,207,207, 15, 74,165, 18, 73, 73, 73,104,218,180, 41, 46, 92,184, 0, 87, 87, 87,132,133,133,201, 90,182,108,121,169,184,184, -248, 92,106,106,234,194, 26, 34,109, 2, 91, 91, 91, 92,184,112, 1,191,253,246, 27, 82, 82, 82,144,157,157, 13, 59, 59, 59,180, -104,209, 2, 77,154, 52, 65,135, 14, 29,144,148,148, 4,166,150,194,196, 48,140, 71,112,112,240,145, 27, 55,110,184, 16, 66,176, -117,235, 86,148,149,149,193,100, 50, 65, 32, 16, 64, 46,151,195,201,201, 9,221,187,119,135,171,171, 43,130,131,131,177,123,247, -110,151,190,125,251, 30,125, 22,129,202,173,237,154, 58, 57, 57,125,176, 96,193, 2, 95, 55, 55, 55,164,166,166, 66,173, 86,195, -221,221, 29, 93,187,118,245, 62,125,250,244, 7, 0, 86,189, 42, 15,129,242, 14,237, 12,195, 48,135, 15,237, 28,236,231, 41,109, -220, 38, 66,227, 31,123, 91, 20,120,244,244,163,102, 79,175,135,255,189, 54, 45, 53,143,111,220, 58,158,118,248,208,206,235,247, - 31,226,160, 53, 77,216,133,106,193,193, 19,167, 83,163,154,133, 69, 10,191,251,113,193,224,201,147,122,203,234, 57, 69, 50,165, -249,187,113,229,122,172,255,231, 11,231,184, 45, 94,184,236,240,137,211,169, 92,161, 90,176,196,154,244, 6, 6,212,251,126,223, -122,145,139,198,244, 35, 98,174, 59, 0,226,246,104, 24,208, 8,165,165,165,144,203,229,242, 49, 99,198,112,115,231,206,213,217, -219,219, 43, 69, 34, 17, 98, 98, 98,242, 5, 2, 65,239,218,116, 13,110, 78,132, 51, 91, 88, 34, 21,242,132,177,211, 51, 92,177, - 52, 46, 33, 25, 93,186,244,205,107,221, 42, 98,233,178,111, 86,125, 26, 16, 16,226, 58,102,236, 20,241,138, 21,159,173, 3, 16, - 89,149,206,253, 36,114,182, 73, 32,163, 0,208,255,139,197, 11,241,228, 73,146,211,228, 55, 84,139, 68, 50,133, 87,168,127, 71, -187,117,191,157,235, 19, 20,212,160,254,228,137,111,254,241,203,198,223,250, 87,142,100,237,220,241,203, 65,134, 97,122, 88,115, -109,255, 65, 52, 27,119,228, 8,202,210,211, 45,197,151, 46, 25,122,252,240, 67, 97,203,241,227, 87, 89, 88,214,165,188,174, 42, -255,201, 48, 12,192,243,140,104,197, 10, 1,241,242,130,197,209,241,141, 57, 64,163,218, 52,151, 89, 44,195,134,180,104,209,255, -215,109,219,224,239,239, 95,161,233,224,224,128,233,211,167, 99,218,180,105,178,123,247,238,181, 57,122,244,104,155, 45, 63,254, -232, 62, 7, 24,102, 77, 58, 47,222,189,235,244,241,154, 53,243, 26,135,135,251,173,254,225, 7, 89,121,125,151,154,154, 26,252, -195,247,223,251,119,143,138,202,251,228,227,143, 55,221,153, 53, 43, 12, 79,151,100,171, 86, 51,247,226, 69,211,177,226,226,183, -246,236,221,235, 24, 18,242,180, 27,228,227,199,143,221,126,253,245,215,183,187,191,251,238,216, 89,163, 71,127,214,253,209, 35, -149,125, 65,129,108,192,247,223,139,118,142, 28, 89,171,102,121, 58, 1, 96,248,236,217, 31,182,237,216,177, 73,223, 49, 99,234, -121,121,121, 49, 10,133, 2,102,179, 25,121,121,121, 78,137,137,137,129,167, 85,170,210,147, 49, 49, 91,241,108, 17,119,202, 95, - 48, 88, 0,192,113,156, 85,230, 74, 36, 18,253,171,112, 91,115, 82,145, 8, 94, 94, 94, 40, 44, 44, 68, 92, 92, 28,252,253,253, - 97,177, 88,112,226,196, 9,168,213,106,136,197, 98, 72, 36, 18,152,205,181,175, 13,107, 99, 99, 19,213,185,115,103,209,213,171, - 87, 17, 16, 16, 0,133, 66, 81,145,174,242, 77, 34,145,192,211,211, 19,165,165,165,136,140,140, 20,111,220,184, 49,170, 38,131, -101,107,107,219,111,240,224,193, 21, 33,182,178,178, 50, 8,133,194, 10,179, 82, 86, 86,134,226,226, 98,168, 84, 42, 24, 12, 6, - 52,107,214, 76,122,246,236,217,126, 53, 25,172,202,232,116,186,178,252,252,124,199,200,200, 72,167, 77,155, 54, 37,182,111,223, - 62,164,242,255,207,159, 63,111, 48, 24, 12, 98,169, 84, 90,235, 58,119, 12,195, 96,219,182,109, 21,215, 62, 43, 43, 11,235,214, -173,171,248,127, 82, 82, 18,190,251,238,187,138,121, 57,106,250,142, 66, 67, 67,251,110,221,186,181,213,150, 45, 91, 74,132, 66, - 33, 18, 19, 19,177,125,251,118, 16, 66,224,234,234, 10,157, 78,135,188,188, 60,156, 59,119, 14, 44,203,194,214,214, 22,222,222, -222,242,233,211,167,119, 90,180,104,145, 24,192,194, 26,202, 18, 39, 20, 10,225,239,239,143,249,243,231,195, 96, 48, 64, 34,121, -234, 43, 75, 75, 75,161, 82,169,112,231,206, 29,164,166,166,162,182,202, 69, 46,151,143,216,178,101,139,155, 84, 42,133, 94,175, -135, 70,163, 65, 70, 70, 6,210,210,210, 12,249,249,249,172,157,157,157,192,223,223, 95, 32,147,201,100, 67,134, 12, 97,202,141, -230,128, 1, 3,156,183,110,221, 58,170, 54,115,196, 48,140,107,227,198,141, 63,125,251,237,183,229,149, 76, 55,114,115,115, 49, -108,216, 48,229,213,171, 87,231, 50, 12,179,157, 16, 82,240, 42, 61, 12, 8, 33,164,172,236,151,203, 23, 15,254,208, 56,246,182, - 40,208,100, 42,105,223,179,223, 7, 34, 0,184,122, 97, 99,251,216,219,113, 80, 48,108,218,177,147, 43, 46,219,218, 78, 38,181, - 69, 0,251,245,112,236,227,231, 38, 29, 58,100, 80,148,224,215, 45,235,219, 76,158,212, 91,230,214,112, 61, 3, 0, 78, 18, 31, -116,224,102, 9, 12, 70,173,252,215, 45,235,219, 12, 25,212,239,122, 74,114,218,170,254, 81, 78,191, 31, 61,163, 58, 94, 83,132, -208,211, 77,228,237,100, 87, 8, 39,187, 8,248, 7,216,225, 78,204, 61, 28,220,127, 9,193,161,157, 96, 52, 26,193,178,172,205, -192,129, 3,117,123,246,236, 49, 20, 21, 21,105,204,102,115,151,236,236,236,135,181,229, 63, 51, 51,129, 15,241,104,103,150, 40, -100,172, 70, 45,209,205,249,108,239,200,150,109,123,181,114,242,244, 22,187,218,240,135,187,117,137,220,190, 99,219,207, 51,102, -125,180, 24, 45, 90,180,111,127,255,209,177, 38, 0, 98,171, 52,173,143,201,145,240, 96,134,125,242,232, 81,255,180,212,212,204, - 70,238, 30,166,199, 42, 98,249, 96,206,250,158,145, 93, 70, 52, 11,108,220, 89, 26,159,112,129,153,249,238,219, 59, 86,254,184, -126, 76,185,201,186,120,241, 68,151,133, 11, 83,165, 0,140,180,122,122,246,114, 42,147,249,216,250,251,139, 82, 54,109,210, 7, - 12, 28, 88, 2, 0, 22,150,117,137,190,118,205, 65,169, 84,130, 16, 2,139,197,242,167, 62,194,229,253,130,163,186,118,117,183, - 70, 51,227,167,159,154,189,251,238,187,200,205,205, 5,203,178, 16,139,197,207, 63,179,161,209,104, 48,124,248,112,108, 92,187, -182,157, 53,154, 28,199, 49, 31,175, 89, 51,111,250, 7, 31, 4,142, 29, 59, 86, 80,249,217,235,232,232,136, 95,214,175,151,110, -218,180,201,103,249,111,191,189,209, 83, 38,123, 82,155,166, 38, 44, 12,142,177,177,138,114,115, 5, 0,129,129,129, 88,182,108, -153,108,244,232,209,210, 9, 19, 38,124, 27, 31, 18,178,102, 97, 90,218, 35,231, 70,141,236,165, 50,153,143,181,215, 19, 0,202, - 76,166,240, 5, 95,124,225,116,253,250,117,100,103,103,151,207,117, 5,134, 97,208,180,105, 83,102,228,200,145, 14,237, 90,181, -106, 67, 75,228, 75,138, 96,113, 28,247, 39,163, 82,155,193,170,115,251, 36,195,192,211,211, 19,102,179, 25, 27, 54,108,128, 68, - 34,169,168,116, 1,192,100, 50,213,170, 97, 48, 24,154,122,120,120, 64,173, 86,163, 81,163, 70,127,138, 92, 73, 36, 18,136, 68, - 34, 72, 36, 18,200,100, 50, 24,141, 70,120,123,123,195, 96, 48, 52,173,197, 0,181,176,183,183,175,168, 88,141, 70, 99,133,185, - 82,169, 84, 80,169, 84, 48,153, 76, 40, 41, 41, 65, 89, 89, 25, 84, 42, 21, 52, 26, 77,132, 53,121,230,121, 30,113,113,113,143, - 67, 66, 66, 90, 8,133, 66,216,218,218,218,104,181,218,138,190, 67,197,197,197,216,188,121,179,118,252,248,241, 46,215,175, 95, -183,106, 33,225,247,222,123, 15, 50,153, 12, 58,157, 14,107,215,174,197,251,239,191, 15,137, 68, 2,141, 70,131,117,235,214, 97, -230,204,153, 16,137, 68, 48,153, 76,216,181,107, 87,245,145,140,132,132,148,107,215,174, 69,180,108,217,210,233,247,223,127, 47, -232,217,179,167,107,239,222,189,161, 80, 40,160,215,235, 97,177, 88,208,174, 93, 59,132,134,134, 34, 63, 63, 31,199,142, 29, 43, - 12, 14, 14,118,185,126,253, 58,159,155,155,155, 86, 91,229, 93,217, 96,115, 28,135,188,188, 60,168, 84, 42, 20, 20, 20, 32, 59, - 59, 27,153,153,153, 16,137, 68,168,237,229,221,217,217,121,120,120,120,184, 16, 0, 20, 10, 5, 90,180,104,129,121,243,230,177, -122,189,254, 53, 0,199,158,237,214,119,253,250,245,191, 95,190,124, 89,228,229,229,133, 7, 15, 30,192,213,213, 85, 36,151,203, -107, 53, 88, 30, 30, 30, 27, 15, 31, 62, 92,175,220, 84,151,151, 85,157,238,233,215, 49,108,216,176,122, 91,182,108,217, 8,160, -223,171,246, 64,176, 21, 56,138,218,180, 80,168,142,158,126,212,172,103,191, 15, 68,158,129, 11, 0, 0, 29, 0,209,169,163,107, -154,245,139, 10,218, 83,222, 47,171, 38,134,244,117, 93, 49,112, 96,115,193,216,145,173,158,136, 36, 33,129,219,182,172,113,175, -231, 20,249,175,135,132,176, 30,108, 20, 64,104, 32, 39,136,222,249,196,125,230, 7, 33,166,237,155,222,122,178,109,207,173, 40, -137,228,110,119, 0, 51,171,211,142, 79,180, 28, 82,107,235, 53,118,144,156,103, 32, 31,132,136, 22,193,112,117, 85, 97,237, 47, - 91,224,237,215, 17, 70,163, 17,246,246,246, 74, 0,102,179,217,188,205, 26,115, 5, 0,103,206,168,248,176, 48,149, 73,168,225, -217,119,223, 95, 49,180,103,223, 65, 77,186,119,143,226, 79,158, 58,105,238, 24, 97,206,233,222,189,125,222,185,243, 23,147,114, -115,179,130, 67, 67,155,225, 97, 98, 76, 31,128,137, 3,170, 46,176,113, 73,228,120, 96, 32,115,110,215,174,201,188,158,191,163, -248,114, 73,108,223,254,253, 39,132,119,142,236,204,159, 58,125,214, 36, 69,225,125,219, 78, 29,178, 38,140,126,237,247, 93,251, -127,239,117,238,236,145, 32,117,105,222,145,111,126, 36,212, 92, 85,126, 57, 99, 89,119,145, 76, 38, 40, 56,119,142,109, 58,105, - 82,197,181, 81, 42,149, 56,120,240, 32,164, 82,105,197, 38,145, 72, 42, 62,187,187,187,131, 33, 68, 80, 23,205,156,156, 28,228, -230,230,194,193,193, 1,174,174,174,200,205,205,197,213,171, 87,241,240,225, 67,136,197, 98,244,233,211, 7,130,106,234,205,231, - 53,167, 46, 93,218,179, 81,227,198,126,207,155, 43, 60, 45,152, 40, 46, 46, 70, 84, 84,148,224,204,153, 51, 30,209,143, 30, 13, - 2,176,173, 70,205, 65,131,138, 10,206,156,169,242,220,225,225,225,204,193,131, 7,101, 99, 70,143,158,177,232,251,239,127, 92, -242,195, 15, 25, 28,203,122,212, 37,239, 12,195, 8, 24,134,129,175,175, 47,138,139,139, 81, 86, 86, 86, 30,112,128,147,147, 19, - 44, 22, 11,120,158, 23,211, 18,105, 61,130,218,204,128, 53,230, 74, 44, 22, 67, 32, 16,188,144,201,170, 28, 33,120, 30,107, 12, - 86,121,229, 39,151,203,255,116,131,149,155,181,202,159,203,223,118,172, 64, 88, 90, 90,138,125,251,246, 85, 20, 52,147,201, 4, -181, 90, 13,149, 74, 5,181, 90, 13,131,193,128,148,148, 20,236,220,185, 19,217,217,217, 16, 10,133, 86, 77,218,250,228,201,147, - 91, 13, 26, 52,104, 81, 94,121,119,235,214,205,231,226,197,139,217,229,215,224,179,207, 62, 43,108,215,174,157, 75,229,202,189, -214,196, 10,133,184,122,245, 42,244,122, 61, 8, 33,144, 72, 36, 72, 76, 76, 4,203,178,224,121, 30, 34,145, 8, 5, 5, 5,181, - 70,176,226,226,226, 38,190,249,230,155,171, 39, 77,154,116,238,227,143, 63, 62,213,173, 91,183, 12,134, 97, 96, 54,155, 97,111, -111, 15, 15, 15, 15, 36, 38, 38,194, 96, 48,224,195, 15, 63, 76,223,178,101,203,233,181,107,215,158,219,176, 97,195,234,204,204, -204, 55,235,242,125,179, 44, 11,173, 86,139,146,146, 18, 20, 23, 23,163,180,180, 20, 6,131,225,133,202, 80,100,100, 36,142, 28, - 57, 34,236,209,163,199,175,254,254,254,185,254,254,254,185, 61,122,244,248,245,208,161, 67, 66,111,111,111,164,166,166,226,214, -173, 91, 40, 41, 41, 1, 33,164,198, 19,136,197,226,110,227,199,143,239,228,231,231,199,152,205,102, 24,141, 70, 24,141, 70,152, -205,102,240, 60,143,212,212, 84, 52,110,220, 88,224,239,239,223,158, 97,152,110,244, 17, 98, 61,165,249,187, 65,116, 63,128, 24, -119,130, 47,253, 17,218, 23,156,140,164,164,164,100,201, 59,115,212,249,156, 49, 6, 9,177,231,161,209,121,195,167,225, 68,188, -253,102, 55,220,184,118, 18,197,197,197, 72, 72, 72, 64,151, 46, 93, 36, 12,195,212,169, 92,158, 58,117,141,123,109,220,251, 35, -186,245, 26,212, 42, 42,170, 31,123,226,196,105,211,237,155, 39,110, 5, 5, 58,229, 19,190, 44,207,209, 81,121,231,209,163,251, - 8,110,212, 4,102,139, 37, 18, 88, 88, 99,121,122,252,152,152,254,248,195,147,123,109, 82,220,184,222,125,222,104,222,163, 71, -111,203,137, 83,135,185, 75,231,246,222,233,221, 59,240,194, 87,107,118,251, 22,155, 66,195,228,246, 30, 71,219,119, 82, 70, 78, -125,221,111, 50, 45, 41,213, 68, 3,228,114, 30,207,158,139,229, 93, 88, 42,155,171,231, 55,107,234,164,202,154,149,235, 34,149, - 74,133,164,164, 36,124,243,205, 55,136,137,137, 1,199, 61,237,106, 87, 91, 55,139,202,154,137,233,233,221,223,127,255,125, 89, - 85,230,170,168,168, 8,133,133,133,200,202,202,194,128, 1, 3, 36,197, 78, 78, 45,107,211,244,118,115, 51, 42,229,242,188,135, - 15, 31,254, 91,122, 75, 75, 75, 33,149, 74,241,253, 15, 63, 72, 78, 60,120,240,206,137,179,103, 93,234,114, 61, 43,215,165,110, -110,110, 8, 12, 12, 68, 68, 68, 4,154, 54,109, 10,185, 92,142,248,248,120,252,252,243,207, 16, 50, 12, 75, 75,226, 75,138, 96, -213,197, 96,213,197, 16, 88,139, 53, 77,132,114,185, 60, 54, 47, 47,175,163,183,183, 55, 88,150,173, 48, 83,207, 55, 17,150, 71, - 59,238,223,191, 15,185, 92, 30, 91,147,166, 82,169,140, 21, 10,133,237,219,180,105,131,253,251,247,227,220,185,115, 72, 78, 78, -134, 78,167,131,209,104,132, 94,175, 71,124,124, 60,120,158, 71,120,120, 56, 28, 28, 28,160, 84, 42, 99,107, 75,171, 86,171,205, - 17,139,197, 33, 10,133,226, 95,205, 29,158,158, 40, 42, 42,226, 45, 22, 11, 54,111,222, 92,234,225,225, 97,163, 80, 40, 80, 62, -255,152, 53,230, 50, 63, 63, 31, 62, 62, 62, 21,125,176, 52, 26, 13,220,220,220, 96, 54,155, 43, 34,112,118,118,118,181,154, 75, - 66,136, 1,192,172, 74,218,173, 71,142, 28,185, 99,215,174, 93, 13, 79,159, 62,141,235,215,175,195,213,213, 21, 75,151, 46, 77, - 78, 77, 77, 29, 67, 8,185,249,178,191,115,107, 12, 86, 81, 81,209,190,216,216,216,246,109,218,180,169, 40,116,221,186,117, 99, -186,117,235,230, 82, 57,164, 95, 80, 80,128, 27, 55,110,224,244,233,211, 96, 24, 6, 73, 73, 73,156, 94,175,223, 81,195,185, 37, -254,254,254,155,230,205,155,103,203,178,108, 69,217, 86, 40, 20,144,203,229,144, 72, 36, 16, 10,133, 72, 77, 77,197,224,193,131, - 29,126,248,225,135,141, 12,195, 4, 18, 66,204,175,202, 3,161,140, 87,177, 55, 98,244,142, 78, 78,254,247,174, 94,216,216,190, -195,179,103,196,213, 11, 27, 89, 39, 39,255,123, 55, 98,244,142,157,125, 85,172,109, 45, 58, 7,142, 21,204, 54,155,111,246, 57, -126, 44,118,232,172,153,111, 75,253, 27, 6,228, 93,185, 30,235,223,129,155, 37,176, 81, 0, 90, 61, 80,172, 2, 30, 60, 22,242, -254, 13, 3,242,110,222, 78,148,126,187,114, 67,128, 78,111,250,253,232, 25,213,241,154,180, 51, 51, 51, 13,222,222,222, 67,102, - 45, 82, 94, 24, 61,198, 77, 42,145,251, 66, 83,114, 27,245,253,157,241,218,240, 16,252,248,203,109,216,219,215,123, 26,193, 96, - 24, 27,107,243, 94, 88, 88,200,236,219,121,105,210,248, 55,222,110,215,187, 87,127,246,248,137, 63, 68,231, 78, 30,186,186,241, -151, 79,127, 39, 66,173,146, 33, 26,133,175,159,207,189,148,228,135, 99, 58,119,238, 5,133, 84, 25, 4,132, 86, 89, 96, 43, 6, - 14, 16,164, 11, 4,144,143,127, 99,114,135,222,189, 7,177, 39, 78, 28,192,137,163, 91,174, 45, 88, 80,255,104,114,214,118, 73, -244,205, 76,249,144, 17,211, 74,142, 28,187,111, 26, 62,176,193, 67, 47,155, 22,122, 90, 45, 61,247, 2, 41, 18,229,177, 70,163, -175, 79,239,222, 66, 93, 90,154,216,214,221,157, 5, 0,139,197,242,111,166,170,114, 4, 75, 32, 16, 0, 2, 1,111,141,166,181, -105,209,233,116,224, 1,214, 26,205,130,226,226,250,207,247, 49,182, 88, 44, 40, 42, 42,170,216, 84, 42, 21,228,114, 57, 74,158, - 77, 26, 90,155,102,231,102,205, 54,175,252,246,219,217,191,172, 95, 47,169,108,174,202, 55,129, 64,128,185,159,126, 42,153,255, -213, 87,211,134,137, 68, 31,212,229,122,150,191,172, 11,133, 66,136, 68, 34,164,165,165, 33, 61, 61, 29,105,105,105, 72, 75, 75, -131, 66,161, 0, 97, 24,158,150,200,151, 96,176,202,191, 60,107, 59,185, 91,107, 8,202,223, 4, 94,150,193,210,106,181,167, 47, - 95,190,220,182, 87,175, 94,162,107,215,174,193,195,195,163,194, 96,149,255, 44,111,118, 82, 42,149, 56,118,236,152, 89,171,213, -214,184,144,164, 94,175, 63,115,230,204,153, 86, 51,103,206, 20, 79,156, 56, 17, 9, 9, 9,152, 50,101, 10, 84, 42, 21, 74, 75, - 75, 81, 84, 84, 4,157, 78,135,182,109,219, 66, 46,151,227,209,163, 71, 22,189, 94, 95,219, 84, 5, 36, 63, 63,191,204,213,213, -213,243,249,127,140, 24, 49,194,253,167,159,126,210, 61,120,240,192,210,177, 99, 71,123,107,141, 70, 57, 59,119,238,172, 48, 79, - 15, 31, 62,196, 79, 63,253, 84,209,231,234,246,237,219, 88,177, 98, 69,197,220,101,117,140, 42,222, 12, 11, 11, 99, 45, 22, 11, -130,130,130,202,155, 87,177,122,245,106,246,239, 48, 87,214, 98, 48, 24,246, 78,152, 48,225,147, 59,119,238,120,138, 68,162,242, -208, 53,120,158,135,217,108,198,163, 71,143, 16, 31, 31,143, 7, 15, 30,160,184,184,184,226, 5, 32, 38, 38,166,196, 98,177,236, -174, 78,215,213,213,245,179,223,126,251,205, 67,169, 84,254,169, 60, 11, 4,130,138,135,142, 68, 34, 65, 65, 65, 1, 28, 29, 29, -209,163, 71, 15,183, 51,103,206,124, 6, 96,254,171,240, 48, 96, 24,134,233,216,206,182,211,123,211,222, 64,155,150,154,199,177, -183,227,112,234,232,154,102,192,211, 78,238, 77, 91,134, 63,190,113,199, 14,125,123,205,238,116,229,218,148, 26, 59,185, 63,235, - 67,117,180,109,219,122,151, 15, 28, 58,253,227,156,153,111,223,248,124,225, 28, 55,131, 81, 43, 15, 13,228, 4,192, 83,115, 21, -125,199,198,176,120,225,219, 55,150,173,220,204,167,231,155,103, 92,191, 94, 82,237,232,222,202,166,197,201, 22,114, 15,223, 25, -217,245, 3,186, 55,136,189,189, 1, 46, 14, 37,176, 11,234,136,190,189,219,226,244,153, 88,164,101, 25,144,159,159, 15, 0, 53, - 78,123,240,224,222,239,227, 8, 67,252, 24,194,164, 51, 2, 34, 31, 55,225,173,200,254,253, 7,145, 35, 71, 14,177, 7,126,223, -118,121,247,214,239,246, 10, 36, 98,145,222,228, 96, 98, 24,131,154, 23,216, 37,104,181, 69, 79, 31,158, 18, 73,245,203,221, 60, -155,144,181, 73, 88,168,199,184, 9, 83, 28,250,245, 29, 76,142, 30, 61,192,239,222,181,249,220,238, 13, 77,183,241,130, 82, 73, - 78,134, 78,166, 46,181,168, 9, 35,117, 44, 43,229,117,121, 79, 2, 13, 94,253, 71,152,105,181,244, 92, 61, 96, 52,102,150,101, -100,120,214,235,210, 69,246,104,225, 66,165,123,219,182,134,242, 46, 44, 53, 25, 44,161, 80, 8, 2,240,214,104, 90,155, 22,189, - 94, 15,194, 48,150, 23,209,100, 89,246, 79,230,170,220, 96, 61,123,214, 91,149,206,111, 62,252,240, 90,235, 55,222, 40,142,142, -142,118,111,223,190, 61,163,209,104,160,209,104,254,100,178, 92, 93, 93,153,134, 1, 1,202, 19, 57, 57, 1,243,173,188,158,214, -228, 93, 32, 16, 84,123, 61, 41, 47, 96,176,202, 35, 88,214, 24, 44,161, 80,104,141, 41,176, 88, 44, 22,184,185,185,161,176,176, -176,218, 10, 95, 32, 16, 64,161, 80, 64,171,213, 2, 64,141, 35,233, 52, 26,205,234,197,139, 23, 79,239,214,173,155, 75, 72, 72, - 8, 10, 10, 10,224,238,238, 14,185, 92, 94,209, 55,172, 92, 47, 46, 46, 14,187,118,237, 42,213,104, 52,171,107,201,247,170,117, -235,214,189,219,175, 95,191,122, 46, 46, 46,112,114,114,194,189,123,247,224,228,228,132,210,210, 82, 36, 38, 38,194,206,206, 14, - 12,195,192, 96, 48,224,226,197,139, 26,158,231, 87,213,114, 99,146, 43, 87,174,152,149, 74,229,189,130,130, 2, 97,113,113,177, -168,164,164, 68, 84, 90, 90, 42, 86,171,213,226,227,199,143,187, 56, 56, 56,232,206,158, 61, 91,224,231,231, 39, 76, 73, 73, 17, -154, 76, 38,129, 21,149, 34, 62,248,224, 3, 72, 36, 18, 24,141, 70,172, 94,189, 26,179,103,207,174,232,115,245,245,215, 95, 99, -222,188,121, 21, 33,245,195,135, 15,215,213,100,193,108, 54,195, 98,177,192, 98,177, 88,101,122,255, 10,214, 24,117, 66, 72, 46, -195, 48, 3,218,180,105,115,114,207,158, 61,206,118,118,118, 72, 77, 77, 69, 94, 94, 30,242,242,242, 80, 80, 80,128,178,178, 50, -176, 44, 11,111,111,111,228,229,229,225,192,129, 3,106,141, 70,211,187,166, 17,132, 66,161,112, 66,100,100,164,232,249, 52,148, -191,213,149,155,118,153, 76,134,236,236,108,116,235,214, 77,122,254,252,249, 9,255,235, 6,171,220,184, 52, 14,134,100,224,160, -209,146, 22,173,250,232,110,220, 58,158,166, 96,216,180,126, 81, 65,123,128,167,211, 52,220,184, 99,135, 22,173,250, 8, 6,230, -152,218,170, 74,126,105,209,164, 17, 99,174,105, 89, 29, 0,112,113,224, 7,247,142,170,159, 99,111,207,136, 22, 47, 92,118,248, -215, 45,235,219, 68,239,252,215, 52, 13,139, 23, 62,157,166,161,119, 84,125, 54,225,193,195,193, 0,182, 88,107, 90, 6, 12,232, -125,231,183,141,187,144,149,114,216,107,213, 23, 10, 41, 12, 37,128, 56, 4,145,237,236,113,243,199, 76,100,101,101,229,242, 60, - 95, 99, 51, 46, 97,136, 95,124, 66, 92,163,166, 97, 77, 60,198, 77,152,108, 63, 96,192, 96, 28, 57,114, 16, 91, 55,111,184, 56, -124,244,176, 95,179, 74, 74,133,110, 98,165, 68, 73,120,169, 80,226, 32,146, 43,149,249,230,236,236,167, 15, 79,145,216, 30, 24, -201, 3,213, 71,134,167, 78, 30,235,208, 61,106, 48,254, 56,122, 16, 91, 55,255,114,225,243,176, 17, 27, 26, 68, 52,102,218,182, -252,102, 90,131,134, 13,252,181,101,121,165, 2, 70,106, 54, 24,120,187,111, 54,167,174,124, 50,111,194,147, 59,113, 35,191,165, -163, 8,255,196,189,173,253,250,181,121,255,241, 99,137,107,167, 78,138,236,115,231,148,214, 24, 44,145, 72, 4, 8, 4,172, 53, -154,204,169, 83, 2, 0, 53, 14,174,146, 72, 36,208,233,116, 96, 25,198,108,141,166, 91, 76, 76, 70,106,106,106,176,163,163,227, -159,204, 85,113,113,113,197,103,131,193, 0,147,201, 4,133, 92, 30,111,141,102,222,197,139,134,121, 19, 39,206,127,247,157,119, -190,219,185,107,151,220,193,193, 1,106,181,250, 79, 6,203,100, 50,161, 77,219,182,146,141, 15, 30,140, 3,176,192,154,235,233, -222,173, 91,173,253,125,159, 25, 86,218, 68, 88,151,250,172,182,166, 26,107, 71, 17, 86, 85, 49, 50, 12, 19,245,220,239,243,250, -246,237,107, 72, 78, 78,134,159,159, 95,133, 73,169,124, 78,123,123,123, 56, 58, 58,226,193,131, 7,216,176, 97,131,158, 97,152, -121, 53,105, 22, 23, 23,107, 12, 6,195,168,209,163, 71,235, 37, 18, 9, 66, 67, 67, 43,230,191,226,121, 30, 82,169, 20, 54, 54, - 54,136,139,139,195,132, 9, 19,116, 6,131, 97,212,243,115, 96, 61,175,153,154,154,170,214,106,181,175,191,254,250,235,186,135, - 15, 31, 34, 50, 50, 18,119,239,222, 69, 89, 89, 25,202,202,202,144,146,146,130, 38, 77,154,192,100, 50, 97,239,222,189,122,173, - 86,251,122,106,106,170,186, 38, 77,141, 70, 51,112,249,242,229,194,163, 71,143, 54,240,241,241, 9,107,221,186,117, 72,143, 30, - 61, 2,135, 14, 29,234,223,175, 95, 63,207,224,224, 96, 67,239,222,189, 93,251,246,237,235, 42, 20, 10,197,143, 31, 63,206, 33, -132,244,173, 73,179,178, 41,121,248,240, 97, 69,147,160, 72, 36, 66, 97, 97, 97,197, 76,251,229, 15,163,170, 12,112,117,154,149, - 77,118,185,177, 42, 55, 90,181, 61,251,171,210,100, 24,166,214, 10, 67, 42,149,150, 71, 56, 73,109,154,132,144,152,251,247,239, -247,236,210,165, 75,204,164, 73,147, 52,185,185,185,176,179,179, 67, 64, 64, 0, 26, 53,106, 4, 23, 23, 23,152,205,102,252,254, -251,239,218, 3, 7, 14,196,170,213,234,110,207,207,129,245,188,166, 64, 32, 72,169,234,225, 90, 30,189, 42, 55, 88,114,185, 28, -222,222,222,229,215, 54,165, 46,215,243, 5, 35, 75,127,175,230, 51,227,210,163,123,239,134,253,250, 15,113, 56,112,232,160,242, -251,181,155,238,119, 30, 60,125,157,139,255,172,253, 46,254,179,246,119, 30, 60,125,221,247,107, 55,221, 63,112,232,160,178, 95, -255, 33, 14, 61,186,247,110,152, 16,255, 32,228, 79,235, 18, 86,145, 78,165, 84,214,182,115,199, 96,213,197, 43, 23,217,101, 43, - 55,115, 29, 59,244,187,254,221,119,235,118,127,247,221,186,221, 29, 59,244,187,190,108,229,102,238,226,149,139,108,231,142,193, - 42,165, 84,214,214,154,188, 79,157, 60,214,161,127,191,193, 56,114,228,119,118,199,214,213, 95, 31, 60, 97,234, 50, 98,178, 33, - 47, 45,229, 54,129,110, 19, 92,237, 99,145,158,158,174,102, 89,182, 91, 85, 29,220,171,210,156,242,246,216,202,230,234,146,179, - 71,228,250,251,247,193,157, 58,117,216,114,230,204, 29,253,165,152,124,245,173,132,194,226,162, 82, 67,178, 86, 83,106,226,121, - 30,132,231,132,139, 22,129,169,233, 59,234,216,177, 43,206,158,222,142,205,155,126, 86,243, 60, 12, 35,246,236,225, 70,142, 92, - 72,252,235,215,247,223,182,115, 59, 51, 96,208, 16, 7, 2,240, 3,135, 13,118,220,177,107, 7,211, 48,168, 97,253,128,128,167, - 83,211,252, 79,150,165,191, 65,115, 1, 33, 37,165,105,105, 23,110,255,240,131,209,125,212,168,122, 82,119,119,123,240, 60, 83, -254,124,175,110, 19,137, 68,127,138,184,212,164,233, 94,175, 94,214,137, 19, 39, 16, 18, 18, 2,111,111,239, 63,117,121, 41,159, - 72,219,197,197, 5,167, 78,157, 2, 1,110, 89,163,217,196,203,235,246,143, 63,252, 96,226,121, 30, 37, 37, 37,255, 22,189, 42, - 41, 41, 1,207,243,184,120,225,130, 73, 93, 86,182,217,218,188,183, 53,153,202,134,180,106,245,213,248,241,227,205, 41, 41, 41, -224,121, 30,149, 35, 89,249,249,249, 80, 42,149,208,233,245,190,238,238,238, 74,107, 52,243,143, 31,183, 65, 45,207,117,129, 64, -240,167, 38,194,191,227,123,255, 71, 69,176, 88,150,133,175,175,239,159,230, 25, 17, 8, 4,127,218,234, 50,130, 48, 43, 43,107, -139,187,187,251,137,113,227,198,205,111,209,162,197,212, 25, 51,102, 8, 27, 54,108, 8,181, 90, 13, 39, 39, 39,184,185,185, 33, - 37, 37, 5, 23, 46, 92,224, 84, 42,213, 58,142,227,190,200,203,203, 43,176, 66,247,156,183,183,247,128, 94,189,122,237,122,247, -221,119, 29,186,116,233, 34,246,242,242, 2, 0,196,199,199,227,216,177, 99,230, 29, 59,118,148, 26, 12,134, 81,214,204,226, 14, - 0, 57, 57, 57, 39, 61, 61, 61,135, 79,152, 48, 97,219,208,161, 67,237, 12, 6,131, 56, 37, 37, 5, 38,147, 9, 44,203,162,184, -184,216,124,225,194,133, 50,157, 78, 55, 54, 39, 39,231,164, 21,122,183, 25,134,105, 98, 54,155, 39,220,185,115,103,201,240,225, -195,157, 59,116,232, 32, 97, 89, 22,151, 47, 95, 46,136,136,136,112, 43, 45, 45, 53, 95,185,114,165,200, 96, 48,204,203,206,206, -182,106,169, 28,134, 97, 80, 90, 90, 10, 23, 23, 23, 24,141, 70,240, 60, 15,147,201, 4, 91, 91,219,138,229,141, 8, 33, 47,220, - 71,142,101, 89,161,217,108,198,232,209,163,193,243, 60, 86,175, 94, 13,150,101,235, 44,102,107,107,123, 43, 62, 62,126, 64, 88, - 88, 88,133,105, 41, 47, 67, 50,153, 12, 46, 46, 46,112,118,118,198,233,211,167, 33, 20, 10,111, 89, 25, 93,187, 11, 32,130, 97, -152, 14,177,177,177,227, 1,180, 48,155,205,222, 28,199, 49, 2,129, 32,135, 16,114,175,180,180,244, 87,107,151,202,201,207,207, - 95,242,198, 27,111, 68,108,223,190,221, 86, 36,250,215,173, 33, 18,137, 32,147,201,224,230,230, 6, 7, 7, 7, 16, 66, 96, 50, -153,240,217,103,159,149,106,181,218, 37,175,202,195,160, 85,235,182,248,229,167, 53,182,103,206,158, 40,184,159,132,131,149,167, - 98,176, 5,112,229,218,148,131,170,146, 95, 90,100,103,100,216,182,106,221,214, 42, 77, 19,199, 22,141, 26,187,206,247,217, 82, - 57, 75, 82,146,211, 86,109,223,244,214, 19, 0,248,118,229,134,128,244,124,243,140,132, 7, 15, 7,175, 93,119,190,173,137, 99, -139,172,209,252,151,105,217,166, 6,129, 33, 43, 43,235,186,143,143, 79,131,200,193,230,121, 33,129,204,160,188, 66, 62,139, 97, -152,247,178,178,178,158, 88,155,247, 78, 29,187,224,236,201, 29,216,186,121, 91, 41,225,133, 6, 23, 23, 23, 2, 0,247,239,187, -144,251,247, 85, 4, 40,159,175,209, 81,235,170, 44,248, 98,222,220,169, 51, 53, 26,205,170, 31,191,169,121,194,217,102,205,219, -161, 89,243,118,152,254,222,167, 14, 77,194, 66,253, 0, 96,207, 30,194,133, 7, 51,135,231,127,190,112,208, 23, 95, 44, 68,169, -198,136, 47,190,120,186,172, 78, 98, 92,194, 31,143, 31, 19, 19,173,154,254,204,124,150,189,142,153, 51,131,117,197,197,174,157, - 62,249,196, 69,244,205, 55,130,170, 58,185,151, 71,176, 42,223,191,214,104, 30, 63,115,230,143,143,102,206,204, 90,241,205, 55, -189,151, 45, 95,174,104,220,184, 49,114,115,115, 17, 26, 26, 10,111,111,111, 92,185,114, 5, 39,142, 30,213,150,233,245,243, 60, - 60, 60,214, 90,163,249,253,142, 29,137,157,187,119, 47,220,178,101,139, 87,247,238,221, 25,173, 86, 11,181, 90, 13,181, 90, 13, -163,209, 8,137, 68,130,172,172, 44,146,158,145,113, 63, 51, 51,115,157,181,121,231, 10, 10,228,179,210,211, 51, 69,155, 54, 45, -159, 50,121,242,236,153,179,102,201,124,124,124, 24,163,209, 88, 17,197, 50,155,205, 80, 42,149,102,141, 70,227, 12, 64,103,141, -166,236,240, 97,182,168,168, 8,206,206,206, 21,211, 46, 85,158, 87, 80,171,213,130, 16, 58, 9,110,157, 94, 20,170,171,195, 67, - 67, 67,111,137, 68, 34,159,202,209,172,234,126, 86,170,140, 51,227,226,226, 90, 85,118,184,132,144, 42,251, 59,249,248,248, 4, -240, 60,191,180, 67,135, 14,195,223,126,251,109,230,194,133, 11, 56,123,246, 44,201,204,204,220, 43, 16, 8,230,101,102,102, 62, -169,238,205,166, 58,205,122,245,234,217,217,217,217,125,104, 99, 99, 19, 85, 62, 21,131, 92, 46,143,213,106,181,167, 53, 26,205, -234,234,102,111,175, 73,179, 97,195,134,246, 60,207,127, 96, 99, 99,211,179,176,176,176, 5, 0,184,184,184,196,104,181,218, 83, - 2,129, 96, 77,117, 11, 72,215,164,233,229,229,165,176,181,181, 93, 82,175, 94,189,215,223,126,251,109,231, 11, 23, 46,228,196, -196,196, 72, 74, 75, 75,183,179, 44, 91,237, 98,207, 85,105, 54,105,210,228, 79,107, 17,190,204,239, 8, 0,154, 55,111,126,100, -224,192,129,253,199,142, 29, 11,139,197,130,181,107,215,226,212,169, 83,127, 36, 37, 37, 13,168,233,237,243,121, 77, 15, 15, 15, - 23,111,111,239,243,227,198,141,243, 31, 50,100,136,210,222,222, 30, 66,161, 16, 90,173, 22,201,201,201,184,119,239, 30, 57,117, -234, 84, 89,124,124,124,166, 94,175,239,154,155,155, 91,104,237,245,252, 43,111,201,207,107,138,197,226, 46,190,190,190, 59, 23, - 44, 88, 96,215,179,103, 79,133,179,179, 51,132, 66, 33, 44, 22, 11,114,114,114, 16, 23, 23,135, 19, 39, 78,104,247,238,221,171, - 45, 42, 42, 26, 77, 8,185,240,159, 72,231,203,212,108,210,136,249,252,185, 5,156,171,157,157,189,166,125,173, 73,103,255, 40, -167,126,195,135,183,142, 2,128,125,251,110,158,254,227,116,201,209, 23, 77,103,109,105,181, 70,179,113,176,112, 65,124, 66,220, -159, 38,162, 12,107, 18,254,176,113,211, 97, 95, 90,163, 85, 62,147,251,243,121,175, 52, 59,126,165, 55,130, 63, 55,167,150, 47, - 8,253,233,188,185, 88,186,228, 43, 28,220,243,251, 31, 9,143,201,145,255,229,178,244,119,106,150, 47, 78,172,244,244,236,188, -195,197,101,238,201,211,167,109, 43,191,168,149, 71,154, 43,191, 76,182,104,209, 34, 63, 38, 38,198,221, 26,205, 1,223,127,111, - 54,216,217,201,150,173, 91,215, 69,103, 50,117,153, 53,107,150,232,246,237,219,216,177,109, 27,171,207,200,216,150,203,113, 31, - 84,213,250, 81,147,102,224, 71, 31,201,151,110,223, 62,177,126,195,134,110,131, 7, 15, 22, 11,133, 66,104, 52, 26,100,103,103, -227,234,149, 43,166,228,148,148, 4,157, 78, 55, 40, 51, 51, 51,219, 90,205, 1,223,127,111,118, 12, 8,128,210,213,149, 92,137, -142,118,248,120,193,130,169, 30,158,158, 14,157, 34, 35,197, 74,165, 18, 37, 37, 37, 72, 79, 79,199,165, 75,151,242,159, 60,121, -226, 69, 8,225,172,209, 60, 20, 27,219,236,236,245,235, 35, 62,254,248, 99,105, 72, 72, 8,236,236,236,160,209,104,144,144,144, -128,171, 87,175, 26,119,238,220,169,214,106,181, 83, 51, 50, 50, 14,253, 93,223,251, 63,198, 96,253,127,221,120, 30, 30, 30,173, - 4, 2,193,231,207,154,163, 22,215,182,166,223,171,244,208,241,244,244,244,115,114,114,250, 69,175,215, 19,163,209, 56, 37, 39, - 39, 39,253,191, 45,157, 12,195,136, 90,181,106,245, 83,126,126,126, 7, 66, 8, 28, 28, 28,174,198,199,199,191, 67, 8, 97,235, -170,201, 48,140,208,195,195,163,131,141,141, 77, 91, 27, 27,155, 46,102,179,185,241,179,126,120,247,117, 58,221, 5,139,197,114, - 61, 55, 55,247, 42, 33,132,251, 79,230,157, 97, 24, 33,128,158, 94, 94, 94,111,241, 60, 31,196, 48,140, 35,199,113,176, 88, 44, - 42,158,231, 31,169,213,234, 13, 0, 78,253,167,211,249,178, 52,195,130,152,161, 68,128,198,213, 25,129, 63, 25,154,231,140, 3, -195,227,126,252, 35,242,187,181,233,100, 24, 70, 48,164,175,235, 10,224,233, 72,195,218,150, 28,250,147,193,178,194,180,212,217, - 92, 6,137,222, 32, 12,241,251,243, 67,145, 73, 15,109, 54,116,235, 95, 49, 88,214, 18, 22,194,116, 1, 65, 7,158,224,250,253, - 36,114,246, 85,125,214,189, 76,205,175, 24,166,222,158, 70,141,174, 10, 68, 34, 15,134, 97, 4, 0,192, 8, 4, 60, 15,112, 16, - 8,216,202,205,130,149, 95, 40,107,211, 52, 3, 77,197, 50,153, 47,199,178,238,197, 18,137,237, 21, 27,155,150, 70,160,204,131, -227, 62, 63, 93, 84,148,248, 34,233, 52, 3, 77,133, 50,153,223, 21, 59,187,193, 42, 39,167,102, 37,102,179, 43, 0,162, 80, 40, -238,151,233,116,155, 83, 83, 83,127,172, 98, 81,245, 90, 53, 37, 50,153, 15,247,108,228,161, 64, 36,202, 63, 33,147,249, 22,184, -186,142,215,233,245,254,114,185,220, 66, 8, 41, 53,155,205, 99,211,211,211,207,212, 37,239,233, 66, 97,147,123,118,118,145,156, -189,189,179,133, 97,108, 76, 28,103, 54, 91, 44, 25, 70,163, 49, 86, 40, 20,174,204,204,204,124,252,119,126,239,175, 28,229,163, -205,254,142, 13, 64, 20,213,164,154, 84,147,106, 82, 77,170, 73, 53,255,126, 77, 55, 55, 55,165,135,135,135, 31, 0,225,255, 98, -222, 95,181, 77, 68, 45, 38,133, 66,161, 80, 40,255,251,228,229,229,233, 80, 69,159, 43,202,127,168,137, 16, 64, 84, 53,145, 45, -171, 67,127, 47, 50,154,192,138,166, 4,170, 73, 53,169, 38,213,164,154, 84,147,106,190, 98,154,181,105,191, 50, 77,143,180,137, -144,106, 82, 77,170, 73, 53,169, 38,213,164,154,180,137,240,229,110, 2, 80,170,115,214,238, 12,195,184,191,236,125, 41,175,118, - 89,168,226, 88,111,134, 97,188,235,184,191, 39,189,234, 20, 10,133,242,191,205,255,123, 31,172,242,138,138, 16,146,247, 50,246, -123,217,199, 62, 59,254, 43,134,193,199,207, 62,127, 77, 8,153,251, 50,246,173, 13, 47, 47, 47,223,122,245,234,189,225,226,226, -210,177,168,168,232, 98, 78, 78,206,198,194,194,194,156, 58, 28, 31, 44,151,203,223, 17, 8, 4,225, 0,192,243,124,156,193, 96, -248, 41, 59, 59, 59,233, 37,124,111, 12,128,201, 50,153,236, 53, 39, 39,167,160,226,226,226, 71, 38,147,105, 15,128,159, 95,100, -214,105, 79, 79,207,150, 28,199,189,143,167, 35, 89,127, 46, 40, 40,184, 98,237,177,238,225, 67,118, 19, 32, 24,128,128,103,248, - 17, 2, 34,216, 11,128,103,128,164,188,184, 3,175,189,228,242,250,194,223,111, 93,143,101, 24,102, 37, 3,124, 8, 6,228,175, -150, 37, 10,133, 66,161,252, 15, 25, 44,111,111,239, 9, 0,102,227,233, 76,219,223,102,101,101,109,254, 59, 42,171,151, 88,169, -173, 38,132,204,170,123,180, 2, 31,243, 60, 17, 0,128, 64,192,124,226,238,238, 30, 46, 18,137,140,207,239,203,178,172,140, 97, -208,135,231, 9,243,108,223,143, 25,134, 89,243, 34,198,206,217,217,217,107,204,152, 49,219,190,248,226, 11,133, 82,169, 68,122, -122,250,144,185,115,231, 70,121,121,121,141,207,206,206,206,168,237,248,134, 13, 27,142,105,218,172,197,204,185,159,126,110,235, -234,230,102,195,178,156, 57, 35, 43, 83,249,205, 87,139,219, 54,108,216,112, 77,114,114,242,142,186, 24, 41,145, 72,244,154, 92, - 46, 15, 52, 24, 12,143, 89,150,221, 43, 20, 10,123, 47, 89,178, 36,188, 95,191,126,242,210,210, 82, 41,203,178, 65, 91,183,110, -157,249,219,111,191,245,101, 24,102,112, 77,195,237,203, 35, 56,132,144,172, 74,215,238,157,219,183,111,119, 23,139,197,204,179, - 69,155,175,212,180,127,101, 8, 16, 28,127,121, 79, 83, 0, 8,235, 52,242, 97,252,229, 61,120,246,249,165,191, 12, 60, 95, 22, -156,156,156,182,151,148,148, 36,212,102,228,171, 58,150, 97,152,239, 8, 33,185, 94, 94, 94, 29, 1,188,243,108,215,159,178,179, -179,175, 48, 12,227, 33,151,201, 62,212, 27, 12, 12, 0,230,175,148, 37, 10,133, 66,161,252,239, 69,176,230, 62,124,248,208,142, - 16,130,144,144,144, 57, 0,172, 54, 88,207, 87, 56, 66,161, 96, 78,207,158, 61, 39,202,100,178, 63, 85,204, 70,163, 81, 32, 16, - 48,110, 28,247,244,207,117,169,104,202,207, 97, 50, 25, 5, 98,177, 20, 66,161, 96,102,139, 22, 45,250,230,229,229, 29,147,201, -100, 95,167,164,164,228,191, 72,228,102,243,230,205, 17,206,206,206,255,102, 32,138,138,138, 4,125,251,246, 97,234,162, 55,145, - 97,100, 70,153,172,173,132, 97, 60, 57,150,117, 4, 0,145, 72, 84, 18,228,238,222,229,179,185,115, 21,207,116, 81, 86, 86,134, - 55,222,120, 67,249,232,209,163,177, 0,150,214, 18,185,106,212, 60,162,213,140, 29,219,183, 53, 46, 45, 46, 49,172, 95,245,243, -109,189, 72,162,107,208, 36, 84,178,248,171,149, 78,159,125, 50,243, 61, 47, 47,175,152,170,150, 13,121, 46,175, 2, 0,191,127, -248,225,135, 97, 3, 6, 12,144,106, 52, 26,185, 94,175,175,191,109,219,182,207, 90,181,106,101,219,162, 69, 11,233,206,157, 59, - 25,181, 90, 13, 66,136, 50, 52, 52,148,188,246,218,107,134, 93,187,118, 77, 7,240, 93, 93,204, 50,207,243,194,170,202,161, 53, -230,154, 1,146,194, 58,141, 4, 24, 4,197, 95,222, 35, 15,139, 28,105, 0,193, 35, 6, 72,122,246, 34,240, 5, 80,105, 94,167, - 63,115, 63, 43, 43,235,133,214, 14,236,223,127, 0, 67, 8,249,221,203,203,235, 76, 97, 97,161, 29,195, 96,116, 29,162, 83,140, -171,171,235,123, 0, 62, 37,132,124,120,238,220,185,246, 0,208,173, 91, 55, 9,128, 43, 14, 14, 14, 61, 76, 70, 35, 67, 31, 73, - 20, 10,133,242, 15, 52, 88,132, 16, 25, 0, 92,186,116, 9,132, 16,249,139, 4, 5, 42,255, 50,107,214, 44, 56, 59, 59, 63,111, - 90,112,246,236,153,106,143,169,235, 57,190,250,234, 43,199,252,252,252,209,191,254,250,235, 16, 15, 15,143,119,115,115,115,143, -215,146,199, 60,134, 97,190,126, 22,113, 96,228,114, 69,201,164, 73,147,174, 62,251, 95,227,195,135, 15,219, 13, 28, 56, 80,195, - 48,204,125, 0,144,203, 21, 93,132, 66,129, 19, 33,132, 16,130,175,107, 50,130, 35, 25, 38, 64, 42,149,118,159,242,253,247,108, -203,129, 3, 69, 54,174,174, 12, 0,164, 61,120,224,242,221, 15, 63,116, 86,101,100,200, 68,118,118,101,121, 37, 37,166,135, 15, - 31, 66, 46,151, 51, 2,129,160, 99,109, 25, 86, 42,149,239,207,154, 61,199,166,180, 88,165, 55,148,106, 76, 66,214, 98,180, 83, - 40,185,188,220,252, 34, 91,133,141,110,242,187,239, 75, 23,124, 58,251,253, 74, 81,147,234,152, 62,115,230,204,198,109,218,180, -241,222,189,123, 55,163, 86,171, 33, 18,137,108, 91,180,104,129, 86,173, 90,113,103,207,158,101, 26, 52,104,128,240,240,112, 92, -190,124, 25, 87,175, 94,101, 34, 34, 34,148,251,247,239, 31, 87,149,193,170,202, 84,143, 25, 51,102,162, 84, 42,229,187,116,233, -130,183,222,122, 11,132, 16, 68, 68, 68,116, 28, 55,110, 92,142, 94,175,183,202, 92,151, 55, 3,186,133, 15,185, 7,160, 41, 8, - 30,229,199, 29,104, 86,105,151,198,137,137,137,237, 74, 74, 74, 42, 58, 27,150, 47, 44,222,185,115,231,186,148,247, 60,134, 97, -190, 30, 56,112,192, 28,128, 65, 84, 84, 84,217,244,233,211, 73, 98, 98, 98,175, 33, 67, 6, 55, 72, 74,122, 84,109, 58,159, 47, - 71, 83,167, 78,211,138,197,226, 55,188,188,188, 18, 24,134, 17,139,197,226,242,107, 36,170, 95,191,190,123,211,166, 77,231,122, -122,122,234,132, 2,129,146,160,246,178, 68,161, 80, 40,148, 87,200, 96, 49, 12,147,125,247,238,221,250, 58,157, 14, 12,195,100, - 91, 81, 65,157,174, 92,225,136, 68,162, 95,132, 66,193, 20, 0,104,221,186,141,118,249,242,229, 85, 53, 43,241,173, 91,183,209, - 10,133, 2,155,167,149,151,240,103,150,101,243,170,210,172,166, 66,252, 70, 42,149,125, 4,128,241,241,241, 45, 59,120,240, 32, - 63,124,248,112,124,243,205, 55,178, 57,115,230,252, 88,191,126,253,110,169,169,169,105,213,165,243,217,239,115,221,221,221,195, - 55,111,222, 28, 49,105,210,164,171, 89, 89, 89,195,158, 69, 70,246, 3,104,199, 48,204,253,202,127,219,191,127,127,135, 9, 19, - 38,220,201,203,203,155, 91,157,230,112,134, 9,244, 15, 13,237,254,197,197,139, 68, 96, 52, 50,133,151, 46,149, 22, 23, 20,152, - 31, 23, 22,218,108,143,141, 29,253,241,162, 69, 18, 15,111,111, 92, 57,121,210, 46, 87,165,210,168,116, 58, 83, 74, 74, 10,207, -113,220, 25, 43,242, 30,230,234,226,162,252,121,229,218,155,118, 98, 33,239,230,227,205,136,235,213, 19, 9,148,246, 82,161, 72, - 96,108, 80, 63, 64, 10, 32,172,182,239, 72, 34,145,140,235,213,171,151,114,215,174, 93, 76,120,120, 56, 28, 29, 29,113,233,210, - 37,196,196,196,160,164,164, 68, 96,177, 88,208,186,117,107, 44, 95,190, 28,126,126,126, 80,169, 84, 72, 79, 79,119,145, 74,165, -174, 53, 92, 79,166, 82,249,193, 39,159,124, 2, 87, 87, 87, 88, 44, 22, 20, 23, 23,131,227, 56,216,216,216, 0, 0,114,115,115, -113,240,224,129, 90,203,146,149,230, 8,237,219,183,175, 48,194,149, 35, 88,117,209,244,246,246,190, 84, 80, 80, 56,178,123,247, -238, 40, 46, 46,102, 23, 46, 92,136,230,205,155,163, 81,163, 70,214,148,249,185, 50,153,236, 55,127,127,255, 77, 83,167, 78,173, -239,228,228, 4,163,209,184,162,168,168, 8, 31,127,252, 49, 0,160, 77,155, 54,173, 9, 33, 49,147, 38, 77, 66,253,250,245, 53, -185,185,185,133,247,238,221, 27,162, 82,169,238,189,104,222,173,188, 62, 84,147,106, 82, 77,170,249, 95,165,249,143, 54, 88, 0, -242,188,189,189,235, 43, 20, 10, 0,168,243,219, 53,203,178, 83,221,220,220, 4,159,125,246,217,192,134, 13, 27,242,211,167, 79, -191,146,146,146,242,167,142, 51, 13, 26, 52,216,243,195, 15, 63,116, 76, 78, 78,214,125,249,229,151,135,243,243,243,167,213,241, - 75,255,132, 97,152, 85, 0,144,145,145, 81,116,224,192,129,200,139, 23, 47,126,181,106,213, 42,159,233,211,167,203,166, 79,159, -254, 9,128, 90, 53, 69, 34,145,177,170,102,193,170,112,118,118,230,171,234,163, 85,206, 64,134, 81,216, 75,165,221,190,184,120, -145,152, 82, 83,117,187,126,252, 81,177,238,230,205,249, 22, 66, 60,221,221,221,133, 93, 58,117, 50,218, 73,165,154,188,236,108, -222,201,199,135, 73,126,252,216,214, 34, 20,154,143, 31, 63, 94, 86, 80, 80,176,205,138, 36,148,242,132,152,108,125,252, 44, 35, -134,244, 12,191,121, 61,230,129,157,155,139, 32,162, 69,120,179, 7, 15, 83,111,131,231,204, 0, 74,107, 19,113,112,112,104, 84, - 84, 84,132,210,210, 82,184,186,186, 98,245,234,213,240,240,240,128, 78,167, 67,124,124, 60,241,241,241, 97, 46, 94,188, 8, 31, - 31, 31, 20, 20, 20,192,100, 50, 65,163,209,228, 27,141, 70,125,117,134, 87, 36, 18,253, 38, 16, 48,147, 24,134, 65, 72, 72,168, -118,213,170, 85, 60, 33, 4,141, 27, 55,198,176, 97,195,176,111,223, 62,196,199,199,151, 71,154,248,192,192, 32,173, 64,192,216, - 0,224,255, 74, 20,135,231,121, 84, 54,194,117,197,203,203, 75, 1,224,227,224,224,224, 81,175,191,254, 58, 43,145, 72,160,213, -106,161,215,235, 17, 23, 23,199,246,239, 63,160,108,224,192, 1,182,127,252,241, 71,141,233, 52, 26,141,143,253,253,253,135,207, -152, 49,227,228,207, 63,255,236, 60,111,222, 60,240, 60, 95,177,177, 44, 91,177, 40,247,129, 3, 7,240,232,209,163,185,149,205, - 21,133, 66,161, 80,254, 25, 6,235, 47, 35, 22,139,191,248,227,143, 63,122, 45, 93,186, 84,220,163, 71,143,142, 94, 94, 94, 29, -178,179,179,175, 62,171,212, 58,244,235,215,175,163,155,155, 27,214,172, 89, 99, 18,139,197, 95,188,160,179,174, 92,217,157,243, -240,240,152,190,127,255,254, 67, 83,166, 76,129,167,167,103,219,255,239, 60,219,203,100, 17,147, 86,175,102,197, 22,139, 96,231, -207, 63,203,150,158, 57,179,122,215,238,221,226, 54,173, 91,131, 0, 72,136,143,151,125,253,253,247,178,145, 3, 6,228,199, 63, -122,132,227,167, 79,155, 84,197,197,217, 5,165,165,179,243,242,242, 10,172, 48,174,209,201, 41,201, 94,145, 93,218,123, 95,184, - 17, 23, 51, 98, 72,191,238, 98,145,128,121,148,154,121,203,211,195,197,225,234,229,203,122,150,101,163,107,211,209,106,181, 41, - 44,203,214, 35,132,184,158, 63,127, 30,174,174,174, 40, 41, 41,129,197, 98,129,201,100, 50,233,116, 58,121, 81, 81, 17, 12, 6, - 3,140, 70, 35,236,237,237, 17, 27, 27,155,199,178,236,217, 26,210,246, 22,195, 48, 11, 9, 33, 72, 72, 72,200, 2, 0, 95, 95, -223, 38,142,142,142,167,202, 23, 80,190,120,241, 98,175,204,204,204,248, 74,145,174, 26, 59,185, 91, 27,193,122, 81, 60, 61, 61, - 91,202,229,242,175,231,204,249,196,171,121,243,230, 40, 40, 40, 4,207,243,176,181,181,133, 94,175,135,157,157, 29, 58,118,236, -152,187,112,225,194,100, 66,208,151, 16,146, 91,147, 94, 90, 90, 90,174,159,159,223,232, 41, 83,166,124, 31, 28, 28,220,136, 16, -130,224,224, 96,244,234,213, 11,199,142, 29,195,195,135, 15, 81, 86, 86,198,222,184,113, 99,125,118,118,246, 46,250, 88,162, 80, - 40, 20,106,176,234, 76, 86, 86, 86,150,183,183,247,150, 59,119,238, 76,122,237,181,215,112,238,220,185,121, 0,250, 2,128, 92, - 46,159,247,218,107,175,225,206,157, 59,184,127,255,254,150,172,172,172,172,151,113, 78,169, 84,170, 53,153, 76,120,118, 14,101, - 29, 43,234,198,207,154, 6, 65, 8,105, 92,221,223,106, 66, 32, 18,121, 54,237,211, 71, 84, 18, 19, 83,186,234,242,229,197, 59, -118,238, 20,183,109,211, 6,102,139, 5, 60,199,193,215,207, 15,221,163,162,100, 91,118,239,182, 97,181,218, 43,159,127,240,193, -177,181,111,188, 81,118,173,172,236,145, 53,105,212,106,181,223,125,254,233, 39, 81,187,118,239,243,110, 18, 26, 88,239,248,201, -115,119,156,157, 29,148,141,130,130,108, 84, 42, 53,183,114,197, 82, 81, 89, 89,217,247,181,233,232,245,250,223, 79,159, 62, 61, -196,215,215,215, 53, 46, 46, 14, 38,147, 9, 28,199,161, 71,143, 30,229,253,239,120,145, 72,132, 7, 15, 30,192,108, 54,231, 39, - 37, 37,101, 63,122,244, 72, 6, 96, 89, 45,215,240,249,239,113, 82,255,254,253, 97,177, 88,208,171, 87, 47, 28, 56,112,224, 77, - 0, 51,106,216,255,133, 12, 86,229,239, 9, 86,118,110,247,242,242,234, 25, 20, 20,180,102,249,242,229, 2, 31, 31, 31,240, 60, - 15, 39, 39, 39,232,116, 58, 20, 22, 22,161, 73,147, 38,240,245,245,197,178,101,203, 0, 96,103,109,230,170,156,244,244,244,251, - 0,186, 5, 6, 6, 74, 13, 6, 67,199,168,168,168,173, 61,122,244,192,157, 59,119,112,245,234,213,238, 12,195,228, 26, 12, 6, -139,183,183,247, 44, 0,142,132,144, 95,172, 25, 61, 74,161, 80, 40,148,255,113,131, 21, 24, 24,104, 39, 22,139,186, 78,155, 54, -213,150,227,120,136,197,162,110,245,235,215,119, 72, 77, 77, 85,191, 64,229,183,102,219,182,109,175,175, 92,185, 82,214,191,127, -255,102,158,158,158,189, 0, 96,228,200,145,205,236,237,237,177,109,219, 54, 35, 33,100,205,203,202, 36,203,178, 67, 90,181,106, -133,226,226, 98,164,166,166, 94,173,203,177,135, 15, 31,182, 3,208,174,182,191,213,120,126,147,201,201,209,219, 91,144,117,238, -156,185,184,180,212,171,220, 92, 9, 4, 2, 20, 23, 23, 35, 45, 53, 21,246,118,118, 72, 72, 76,148,173,125,255,253, 93,254,225, -225, 98,206,100,114,182, 86,191,160,160, 64,235,225,225, 49,113,254,231,159,253,254,253, 15, 63,184,170, 74, 75, 31, 43, 20, 74, -163, 76, 38,241,152, 63,127, 30,167, 86,171, 39, 20, 22, 22,150, 89, 33,181,108,251,246,237,125,250,244,233,115,207,207,207,207, -173,160,160,192, 67,173, 86,147,226,226, 98, 6, 79,251, 82, 49, 0,112,239,222, 61,164,166,166,178, 28,199, 93, 4,240, 5, 33, -196,100,109, 90,189,188,188,156,219,183,111, 63,212,205,205,173,162, 41,178, 69,139, 22, 67,189,188,188,150,100,103,103, 23,189, -204,194,125,234,212, 41, 59, 66, 72, 59, 66, 8,250,244,233, 99,237, 97,239, 12, 24, 48, 64,192, 48, 12,244,122, 61,100, 50, 25, -108,108,108, 97,103,103,143, 70,141, 66,144,149,149,133, 94,189,122,113,143, 31, 63,222, 33,145, 72,190,171,107,154,244,122,253, -152,142, 29, 59, 46,154, 54,109, 26,120,158,199,224,193,131,145,145,145,177, 41, 57, 57,121,131,143,143,207,180, 73,147, 38,185, - 59, 59, 59, 99,214,172, 89,202,202,166,147, 66,161, 80, 40,175,160,193,242,242,242,138,114,114,114, 90,225,232,232,110,123,226, -196, 73, 17, 0,116,233,210,217,198, 98, 97,163,189,188,188,230,100,103,103, 31,174,203, 73,179,179,179,139,188,188,188,126,190, -122,245,234, 7,195,134, 13,195,169, 83,167, 62, 5,128, 97,195,134,225,234,213,171, 72, 78, 78,254,249,101, 85,182,222,222,222, - 19,186,116,233,242,110,155, 54,109,112,228,200, 17,112, 28,119,180, 46,199, 87, 30, 49, 88,213, 40,194,242,191, 89, 37, 38, 20, -130, 97, 24,112, 28, 7,194,243, 40, 44, 42,194,131,196, 68,148,148,148,128,227, 56,232,117, 58, 75,112,195,134, 90,181,201,100, -207, 60,157,107,204,106,114,115,115,211, 2, 3, 3,211,117, 6,189,155,179, 83, 61,189, 82, 41,131, 70, 83, 38,137,189, 23, 83, -150,153,153,249,216, 74,227,107, 98, 24,166,203,177, 99,199,230, 11,133,194,215,188,189,189, 49,114,228, 72,166, 71,143, 30,144, - 74,165, 48, 24, 12, 40, 41, 41,193,225,195,135,193,178,108, 67, 0,112,117,117,117,175, 95,191,254, 62,129, 64,144,151,156,156, - 60,169,182,115, 48, 12, 51,126,224,192,129, 98,147,201,132,197,139, 23, 99,193,130, 5,232,219,183,175,248,246,237,219,227, 1, -172,124, 89, 5,155,231,121,244,236,217,179,114, 39,247,251,181, 29,211,181,107, 87,145, 80, 40, 12, 9, 12, 12, 68, 65, 65, 1, - 10, 10, 10,224,234,234, 10, 47, 47, 47,184,185,185, 97,229,202,149, 88,189,122,245, 13, 66,200,178,220,220,220, 7,117, 77,147, -175,175,239,172, 55,222,120, 99,214,168, 81,163,160,209,104,112,245,234, 85,116,236,216, 17,203,151, 47,247,185,116,233,210,162, - 86,173, 90, 65, 34,145,224,252,249,243, 96, 89, 54,133, 62,158, 40, 20, 10,229, 21, 53, 88,222,222,222,245,120,158, 95, 50, 96, -192,128,129, 67,135, 14,197,242,229,203, 42,121, 5, 17, 54,110,220,228,176,127,255,254,117,190,190,190, 67,133, 66,225,156,212, -212, 84,171, 59, 36, 43, 20,138,181,219,183,111,159,216,190,125,123,187,168,168,168, 96, 0,144,201,100,252,246,237,219, 53, 10, -133, 98,109, 93, 51,242,252,164,143,158,158,158,157,164, 82,233,244,129, 3, 7,118,154, 56,113, 34,226,227,227,177,117,235,214, -187, 94, 94, 94,135,234,168,123,191,182, 81,132,181, 69,179,132, 82,105,145, 42, 55,215,209,214,207, 79,236,236,224,144,125,238, -220, 57,255,182,109,219, 34, 45, 61, 29,170,146, 18,232,245,122,196,199,199, 19,137, 72,148, 44,114,114, 98,210,162,163, 25,161, - 84, 90,103,131,105, 35,103,130, 63,255,120,114,125,131,193, 16,166, 86,171, 89,177, 68, 34, 86, 72, 73,157,154,153, 8, 33, 70, - 63, 63,191,193, 28,199,185,152, 76, 38,139,187,187,187,248,244,233,211,144, 74,165, 96, 24, 6, 77,155, 54,133, 84, 42, 53,249, -248,248,104, 0,192,217,217, 89,176,108,217, 50,241,135, 31,126, 24, 95,155,118,203,150, 45,197,254,254,254,147, 66, 66, 66,112, -245,234, 85, 36, 36, 36, 36, 94,187,118, 45, 36, 34, 34, 2,222,222,222,147, 90,182,108,249,253,237,219,183, 45, 47,163, 96, 19, - 66,234,220,201,253,194,133, 11,196,203,203, 11, 2,129, 0, 2,129, 0, 60,207,163,160,160, 0, 13, 27, 54,196,218,181,107,177, -122,245,234,159,114,114,114, 94, 40,178, 26, 24, 24, 40,109,222,188,249,187,163, 70,141,194,227,199,143,177,116,233,210,252,188, -188,188,163, 39, 79,158, 28, 63,109,218, 52, 81,199,142, 29, 81, 84, 84,132,141, 27, 55, 90,238,220,185,243, 93, 78, 78,206, 90, -250,120,162, 80, 40,148, 87,208, 96,249,250,250, 78,148,203,229,139, 70,141, 26, 37, 10, 9, 9, 65, 94, 94, 30, 52,154, 50,174, -105,211,112, 14, 96,136,173,173, 13,163, 84, 42, 49,101,202, 20, 52,107,214,172,231, 39,159,124,210,195,203,203,235,171,236,236, -236, 31,173, 57,241,227,199,143, 53, 94, 94, 94,223,205,156, 57,115,121,116,244, 85, 27, 0,136,137,137,209,102,103,103,127,153, -157,157,173,169,163, 9, 42,159,156,146,177,177,177, 73, 10, 10, 10,178,244,239,223,223,121,232,208,161,112,113,113,193,157, 59, -119,176,108,217,178, 59, 90,173,118, 76,106,106,170,229,255,251, 34,179, 70, 99,238,173, 3, 7,236,186,190,254,186,253,199, 67, -134, 44,125,251,237,183,127, 92,176,112,161, 56, 48, 32, 0, 38,179, 25, 9, 9, 9,100,231,142, 29,230, 29,203,151,127, 11, 27, - 27,113,244,190,125, 82,147,201,148, 86,151,115,248,248,248,116,233,215,167, 75,200,138,149,223,193,160, 47,195,245,171,127,160, -164,164, 0, 63,255,178, 63,196,199,199,167, 75,102,102,230, 5,171,211,203,178, 1,123,247,238, 5, 0, 72,165, 82,124,241,197, - 23,240,242,242,130,189,189, 61, 52, 26, 13, 38, 79,158, 44,253,240,195, 15, 1, 0,241,241,241,176,181,181,181, 54,202,214,111, -242,228,201,142, 22,139, 5,199,142, 29, 51, 72, 36,146,215, 79,158, 60,121,181, 89,179,102,242,206,157, 59, 59,110,221,186,181, - 63,128, 3, 47,203, 96,189,192, 49,156,183,183,119,242,201,147, 39, 27,142, 28, 57, 18, 18,137, 4, 37, 37, 37,176,183,183,199, - 15, 63,252,192, 43,149,202,141,127, 33, 73, 82,165, 82, 41,227, 56, 14,187,119,239, 70, 94, 94,222,128,242,254,136,179,103,207, -254, 50, 52, 52, 52,240,193,131, 7, 79, 12, 6,195,188,172,172,172, 71,244,209, 68,161, 80, 40,175,168,193,226,121,254,227, 19, - 39, 78,136, 56,142,195,250,245,235,113,243,230, 77,146,151,151,247,173,217,108,254, 74,169, 84,178,197,197,197,179,223,126,251, -237,169, 11, 22, 44, 16, 68, 70, 70, 34, 58, 58, 90,208,176, 97,195,233, 0,126,172,100,124,162,106,154, 43,163,164,164,228,104, -110,110,206,143, 60,255,180, 50, 20, 8, 24, 27,169, 84,118,180, 22, 51,245, 39,205, 42, 38,179,108,244,213, 87, 95,229, 59, 59, - 59,243,241,241,241, 88,187,118, 45,119,235,214,173,125, 60,207,127, 86, 88, 88,168,179, 70,243,101, 80, 89, 83,202,178,183,183, -206,158,221,184,229,224,193,252,176,183,222, 50, 10, 68,162,119,150,174, 90,245,105,137, 74,229, 5,134, 33, 46, 78, 78,105, 27, -150, 44, 89,220,161, 91, 55, 67,252,133, 11,242,152, 83,167,196,174, 22,203,221,186,164, 51, 51, 51,243, 66,112,160, 31, 54,173, - 95, 9,179,217,136,156,172,167,254,172,176, 72,141,154,204, 85, 85,154, 2,129, 64,245,198, 27,111, 40, 77, 38, 19, 51,122,244, -104,113,126,126, 62, 2, 3, 3, 1, 0,165,165,165,248,227,143, 63, 16, 26, 26, 10, 0,136,141,141,173,248, 92, 91, 58, 21, 10, -197,164,142, 29, 59, 34, 45, 45, 13, 9, 9, 9,123,179,179,179,243,188,188,188,246,166,165,165,141,111,221,186, 53,246,237,219, -247,102,117, 6,171,174,223,145, 53, 6,171,154,188,191,181,127,255,254,143,162,163,163,251,204,154, 53,139,233,214,173, 27, 0, -160,172,172,140,207,201,201,209,188,136,102,229, 52,177, 44, 11, 0,144,203,229, 26, 0,120,102,166, 70,190,168,230,203, 40,159, - 84,147,106, 82, 77,170,249,223,160,249,143, 49, 88, 0,204, 28,199,225,194,133, 11,216,191,127, 63,107, 48, 24,134,229,230,230, -222,170,244,255, 47,125,124,124, 14, 13, 31, 62,252,104, 98, 98,162, 40, 33, 33, 1, 0,216,186,156,220,104, 52,154, 24, 6, 4, -255,154,140,146, 24,141, 70,211,139,124,215,149,127,249,245,215, 95,145,147,147, 99, 76, 75, 75,219, 73, 8, 89,151,147,147,147, -249, 23, 34, 33,127,121, 20,225, 70, 66,140,175, 51,204,233, 5,157, 58,245,156,127,234,148,236,181, 25, 51,204,195, 70,141,154, -205,153, 76, 22,161, 68,194, 75,109,108, 4,156, 76, 38,142,191,112, 65,190,102,218,180,122,122,163,241,248,214, 58,116, 28,175, - 20,193,194, 27,111,205,128,190, 82, 4, 43,250,230, 67,212, 53,130, 37, 18,137,252, 44, 22,139,140,101,217, 44,158,231, 49,126, -252,120,240, 60, 15,189, 94, 15,141, 70,131,226,226, 98,195,123,239,189, 39, 0, 0,165, 82,137, 94,189,122, 73,173,209, 13, 8, - 8,104, 32, 22,139,113,252,248,113,136,197,226,205, 0, 32, 22,139, 55,159, 58,117,106,252,152, 49, 99,224,231,231,215,132, 97, - 24,166,182,197,163, 43, 22,123,102, 16,244,236,219, 15,114, 11, 31,114,175,210, 98,207,247, 35, 34, 34, 0, 43,250, 93, 61, 79, - 70, 70, 70, 14,128, 25, 62, 62, 62, 27, 63,250,232,163,143,219,182,109,219,106,225,194,133, 96, 24, 70,248, 87,111, 54,158,231, - 97,177, 88,254,210, 20, 18, 20, 10,133, 66,249,223, 55, 88, 43,187,117,235, 54,147, 16, 34, 98, 24,230,155,231,204, 85,121,212, - 36,222,219,219,251,243,134, 13, 27, 86, 44, 0, 93, 71,243,146,199, 48,204,114,129,128,249,248,233,239,117,159, 88,178,146,198, - 39, 79,205,129,120,215,173, 91,183, 62, 77, 75, 75,203, 34,132,176,127,245, 2,189,140, 81,132, 0,176,157,144,148,209, 12,115, - 98, 86,120,120, 84,159,105,211,208,172, 79, 31,123, 47,127,127, 78,111, 54,243,177,151, 47, 51, 87,247,238,149,196,156, 58, 37, -214, 27,141,199,247, 19,146, 94,215,116,102,102,102, 94, 8, 12,240, 57, 57, 98, 88,191, 94, 1, 13,188, 0, 0, 79, 82,178, 81, - 88,172, 62, 89, 23,115, 5, 0,169,169,169, 70, 0, 70, 79, 79,207, 97,187,119,239,222,251,204,244, 84, 44, 59, 3,192, 40, 18, -137,130, 1, 64,163,209,248,255,254,251,239,219, 69, 34, 81,173, 38,246,254,253,251, 27, 22, 44, 88, 48,229,201,147, 39, 59, 51, - 51, 51, 19, 1, 32, 45, 45, 45,209,219,219,251,235,156,156,156,169, 25, 25, 25,107,137, 21,238,227,185,197,158, 17,127,121,143, - 28, 64,211,242,197,158, 95,116,173,193,231,174,103, 28,128,177,222,222,222,221,122,247,238, 61, 29, 64,238, 95,209, 51, 26,141, - 22,163,209,104,225,121, 94,108, 54,155,137,209,104,180,208,199, 15,133, 66,161,252, 3, 13, 86, 86, 86,214,102, 88,177,152,179, -181,251,213, 96,144,230, 50, 12,179,166,220, 44,253, 85, 13,179,217,252,178,214,111,187, 63,104,208,160, 58,237, 95,219, 14, 59, - 9, 73,123,159, 97,182, 28,249,254,251, 22,199,215,173,243,230, 88,214,153, 1,136, 80, 42, 45, 50,153, 76,169,174, 22,203,221, -186, 70,174, 42,243,248, 73,102,111, 0, 8, 14, 14, 38,143, 30, 61, 2, 33,228, 47, 45, 30,156,147,147,115,210,199,199,199, 77, - 36, 18, 73, 25,230, 79, 82,198,103, 38, 12, 0,238, 49, 12,211, 4, 64,173, 17,158,140,140,140, 85, 0, 86, 85, 81,134, 86, 3, - 88,109,109,186, 42, 22,123, 6, 4, 60,195,143, 8,235, 52,114, 47, 0,190,124,177,231,151, 73, 86, 86,214, 57, 0,231, 94,130, - 97, 51,212,175, 95,127,221,242,229,203,167,222,189,123,247,215,204,204, 76, 3,125,252, 80, 40, 20,202, 63,208, 96,253,127,242, - 50, 22,181,125,217, 11,227,190,140, 40, 72, 85,124,247,212, 64, 93,251, 59,175,103, 82, 82, 18,243,178,180,158, 25, 1, 67, 45, -215,158,160,142,205,195,127,133,242,197,158, 43, 17,254,191,112,179,165,166,166,126,213,178,101,203, 21,153,153,153, 52,122, 69, -161, 80, 40,175, 56, 2,122, 9, 40,148,255, 63, 94,214, 52, 20, 20, 10,133, 66,249,239,134, 1, 16, 85,213, 63,234, 50, 58,128, - 97,152,168,186,158,184, 54,125,170, 73, 53,169, 38,213,164,154, 84,147,106,190,122,154,181,105,191, 50,163, 19, 43,119, 94,126, -217, 27,128, 40,170, 73, 53,169, 38,213,164,154, 84,147,106, 82,205,127,218, 70,155, 8, 41, 20, 10,133, 66,161, 80, 94, 50, 34, -122, 9,170,166,133,167,112,177,159,143, 91,171,138, 40, 31,207, 3, 0,248,103,179, 8, 84, 76, 39,192,243, 32,132, 32, 59, 95, -117,251, 94, 30,249,252, 69,207, 23,226,205,212,115,147,203, 87,243,132,116,122,246,167, 11,234, 34,227,140, 56, 53, 81, 89,171, -209,216,131,105, 44, 23,224, 35,158,160, 25, 0, 8, 24,220, 51,240,248,230,126, 46,185,255, 87,175, 7,195, 48, 76,152, 43, 38, - 75, 21,202, 81, 14,142, 78, 65, 37, 37,133, 73,102,131,113, 79, 66, 1,126, 38, 47, 48,177, 83, 96, 61,166, 29, 79,240, 41, 0, -129, 88,128,111, 31, 22,145,115,180,212, 81, 40,148,255, 39,254,234,188,118, 92, 85,143,201,191,168, 73, 39,200,251, 39, 27,172, - 48, 55,102, 26, 24, 44, 4, 64, 64,176, 40, 62,159,212,105,189,180, 48, 47, 38, 74, 46, 20,110, 0, 32, 52,152,185, 89,132,199, -197, 42, 43,115, 1, 58,203, 37,194,111, 1,240, 6,142,155, 20,159,109,125,123,108,184, 15,211, 71,196, 11,182,242,132,136, 57, -158,108, 6,193, 17, 91, 9,174, 68,103,146, 58, 13,139,247,243,113,107,117,224, 70, 78,175,115,107, 63, 64,219,102,129, 32, 28, - 11,240, 22, 40, 35, 63,194,153, 85,227,209,182,177, 31, 8,111, 1,120, 22,182,125, 87,160,111,184,195, 11,223, 28, 33,222, 76, - 61,127, 23,183,184,245,235, 55,120,120, 5, 52, 97,120,214,140,196, 27, 39,199,126,248,241,252,238,225, 14, 76,184, 53, 38,171, -185, 23,243, 86, 96,195,144,143,102, 44, 92, 41,244,244,242,181,225, 45, 70, 54, 55,229,126,196,119, 95,207,223,215,220,139,249, -246,110, 54,217, 96,173,145,106,226,138, 41, 34,153,116,164, 66,110, 19,164,211,105, 30,113,102,203,158,112, 47, 81,159,111, 86, -172,110,209,181,103, 63, 91, 78,147, 43,176,240,104,178,123,215, 78,255,239,127,252,169, 31,195, 48,131, 8, 33,124, 93,242,204, - 19,124,252,112,203,228,126, 98,145,144,105,252,230,122, 33, 94,112, 42,132, 38,238,204, 24,134, 32,178,214, 39, 23,131, 75, 9, -121,100,199,139,156,163,177, 59,243, 43, 67,208, 8, 12,246, 50, 4, 59,227,243, 73, 62,125,116, 80, 40,175, 22, 62, 62, 62,231, - 50, 51, 51,187,189, 76, 77, 47, 47,175,118,217,217,217,215,232,213,165, 6,203,138,218, 23, 95,198, 63,206,112, 2,103, 70, 88, -163,128,197, 0,234,100,176,228, 66,225,230,155, 73,121, 30, 96,205, 88,191,228,157, 93, 38, 11,192, 90,204,224, 88, 11, 56,214, - 2,150, 53,131,179, 88, 64, 44, 70,204,255,237, 28, 96,210,160, 85,120,240,102, 0,158,214,158, 67, 76, 4, 91,111, 95, 62, 89, -143, 49,169,177, 99,237, 87,239,101, 20,148,189,119,250, 94,118, 97,152, 59, 51, 55, 33, 31, 27,235, 98, 4,206,173,251, 0,219, -126,255, 35,115,205,175,218, 7, 60, 33,168,103,175, 8, 25, 59, 32,222,119,203,193,115, 25,171, 55, 27, 30, 0,128,131,141, 52, -100,194,189, 36,191,191,242, 37,184,201,229,171,127,254,233,123, 15, 79,103, 5,195, 94, 93, 6,150,227,224,235,223, 95, 56,119, -250, 88,207, 47, 87,109, 88, 5,224,141,154,142, 15,117,103,154, 52, 10,108, 60,107,243, 31, 87,253,180,165,249,166,147,219, 63, -125, 12, 35, 44, 30,222,141,197,139,191, 90, 41,156,247,201, 7, 51, 67,221,153,235, 15,242, 72, 66, 45,230, 74,208,216, 13, 7, -191, 90,182,162, 89,247,190, 3,108,249,178, 2,161, 65, 91,214,104,253,111, 27, 22,134, 54,107,163,140, 12,247,145,228,239,153, -202,232, 53,197, 48, 11,228,178,238, 97, 81,246,250,113,163, 45,235, 55,109,155, 14,224,187, 58,189,254,145,127,149, 61,158,127, -241,183, 73,134, 32, 50,230,218,185, 41, 92,246, 77, 16,206, 2,112,230,138,159,224, 44, 32,252,211,159,109,167,254, 6, 0, 47, -100,176, 4, 4,189, 78, 95,190,233,153,151,155,211,122,213,138,165,115,155,184, 49,199,192, 97,235,253, 98, 92,168,171,177,164, - 80, 40,255,189,120,121,121,177,217,217,217, 47,181,101,199,219,219,187, 95, 86, 86,214,209,191,152,174,143, 0,188,245,236,215, - 13,217,217,217,223,252,213,116,181,110,221,218,135, 16,226,241,236,217,159,123,243,230,205, 76, 90, 2,254,147, 6, 11,144,131, -240,192,222, 33, 0,160,168,235,201, 8, 32, 7, 35, 4, 44, 90, 12,238,219, 19, 46,110, 30,128, 69, 7,152,117,128, 69, 15, 88, -180,128, 69,143,194,156, 52,192,172, 5,158, 28, 3, 75,136,172,206,185, 50,170,129,135,123,208, 35,194, 15,174, 14,114,124, 48, -184,137,203, 47,199, 31,110,216,112, 50, 49, 10,192, 40,171,210, 74, 8,218, 54, 13,194,154, 13,218, 7,135,110,231,247, 6,128, -254, 45, 92,142,183,109,226,239,187,122,179,225,193, 31,247,138,251, 0, 64,223,112,135, 99,109, 66, 60,253,248,191, 16,221,229, - 9,137,244,170, 31,196,112, 49, 63,131, 47,205, 68,105,169, 30,153, 41, 91,224,228,221, 82,192,241,232, 82,219,241, 10, 33,230, -188, 63,111,185, 88, 87,154,103,226,205, 5,156,171,176, 68, 40,146,242, 12,178, 46, 24,203,120, 21, 55, 99,242,120,118,214,231, - 75,230, 0, 24, 91, 99, 52,200, 13,211,191,253,118,117,211,142,173, 66,221,114,247,125,192,148,149,228,129, 21, 42,101,131,219, -119,132, 99,112, 19, 62,239,252,183,140, 52, 32, 10,142,206, 1,200,186,186, 29,169,215,246, 51,157, 34,134,201, 54,238,144,140, -171,206, 96, 5,187, 50,157,122,119,110,179, 43,192,207,203,147, 16, 30, 60, 79, 64,120, 14,111,142,232,133,185,187,159,128,227, - 56, 12,239,221,169,199,242, 41,221, 9,207,243, 32,132, 71, 70,110,145,238,236,245, 7, 61, 30, 23,147,235,214, 68,166,154,183, -235,214,233,222,237,107,161,150,135,135,209,106,236, 87, 15, 24,224,114,165, 50,215,233,206,137,141,161,192,111, 47,102,224, 24, -134,105,236, 6, 46,245,248, 50,248,117,158, 44,252,121,199,113, 87,117, 65,214,132,125, 91,126, 26,177,246,231,159,183, 1,152, - 74, 31, 35, 20,202,171, 65,118,118,246, 75, 55, 89, 87,175, 94,205,254, 43, 38,171,117,235,214,157, 1,124,157,157,157, 93,110, -182,190,110,219,182,237,252,202,117, 85, 37,212,132,144,177, 55,111,222,188, 88,147,230,204,153, 51,189, 0, 52,184,117,235, 86, -249, 57, 26,180,110,221,186, 65, 85,251, 42,149, 74,174,121,243,230,169, 43, 87,174,204,166, 37,228,239, 53, 88, 15,210,247,124, - 16, 97,204, 41, 3,128, 7, 86,152,148, 63, 53,237, 25, 44,220,178, 77, 11,199, 47, 11,171, 95, 15, 26,173, 9, 39,111,165,130, -227, 44,224, 88,246, 89, 36,139, 5,199, 90,208,187,185, 11, 58, 24,166,226,187, 35,137, 96, 57,254,171,154, 52,159,199, 76,248, - 49, 45,162, 94,219,205,243, 68, 42, 19, 11,212,141,124,157,221,102, 13,111, 46,248, 96,112, 24,244,102,246,181, 38,238,204,217, -132, 60,178,222, 42, 77,254,223,231,206, 36, 85,253,141, 99,107,205,123, 13,209,167,182,163, 7,244,180, 39, 70, 53, 44,133, 79, -160,209, 89,240,164,200,130, 92,131, 10, 50, 38,199, 42, 77,158,160,153,143,183,167,242,202,174, 79, 82,156,133,165, 34, 55, 33, - 43,145, 10, 88,112, 60, 17, 18, 85,130,177, 94,104, 79,113,121,191,172,154,210,169, 80,218,141,239,220,171,191, 67,250,246,201, -140,162, 81,111,184, 69,248, 34,229,226, 38,228,223, 58,130,162,236, 84,198,222,160,130,187,115, 32,250,142, 29,133,111, 70,181, -134,166, 84, 3, 97,206, 99, 7,169, 88,230, 88,157, 38,225, 48,246,219,229, 75, 60, 69, 66,193,211,235, 89,190,113, 22,232,141, - 70,128, 99, 33, 23,241, 96, 72,249,255, 44,224, 44,102,101,179, 97,159,188, 3,224,122,109,121, 79,200, 35, 59,194,220,152, 72, -240,150, 80, 98,209,131, 1, 46,199,231,147, 10,211,211,196,157, 25,211,178,247,196, 72,194,224,210,139,124, 71,225,206, 24,208, -170,129,173,141, 77,233, 3,100,238,125, 15,143, 33, 39,238, 29,223,194,152, 55,167, 43,127,249,229,151,129, 12,195, 76,171,220, - 7,237,239, 24, 94, 76, 53,169,230,255,170,166,131,131, 67,195,250,245,235,207,183, 88, 44,157, 37, 18,137,187,217,108, 6,207, -243,185, 82,169,244, 82,106,106,234, 23,106,181, 58,249,191, 45,239,199,142, 29,179,218,100, 89,163, 41, 22,139,113,230,204,153, - 71,214,154,172, 42, 22,160,223,186,119,239, 94,236,222,189, 27, 0,112,238,220, 57, 4, 7, 7,219, 84,117,108, 70, 70,134,205, -240,225,195,183, 2,240,173, 73, 51, 41, 41,169,225,146, 37, 75,176,119,239, 94, 0,192,150, 45, 91,208,168, 81,163, 42,211,115, -247,238, 93,225,103,159,125,214, 16, 64,246,223,253, 29,253,211, 13,214, 19, 63, 39,105, 4, 12, 28, 0, 60,169,235,201, 18,114, -201,242,230,158,226, 62,103,246,254,216, 89, 46, 17, 96,193,250, 89, 25, 5,197,154,118, 34, 6, 60, 0,176, 4, 2, 39, 91,105, -244, 87, 19,154,251,149,148, 25,112,232, 70,214,197,248, 60, 82,167, 80,104,124, 54, 57, 5,192,241, 95, 21, 36,211,104,194, 55, -167,118,238,156,211,167,217,140,193,205,112,240,106,234, 12, 0,235,107, 45,228, 60, 15,194,179, 21,157,218,159, 58, 25, 30,224, -217, 63,189, 49,240, 32, 79,255,198,215, 45,130,213,149, 97, 68, 37,110,232, 91, 79, 41,253, 97,202,148,183,237, 45, 5, 73, 40, - 54, 73,144, 81, 98, 64,174, 94,140, 50,145, 27,178, 30,196,114, 2, 6,167,106,143,178,160,148,176, 6, 71, 39,169,173, 32,188, -231, 59,222,165,199, 63, 45,145, 50,172,208,126,232,151,142,133,103, 86,166,178,218, 2, 45,195,160,214, 9, 46, 29, 28, 28,131, - 13, 69,169, 66,117, 73, 33, 28, 61,194,208,231,181, 1, 88,212,191, 9, 52,165, 90, 20, 20, 71,147, 32, 79,123, 38,237,210, 54, -204,235,219, 24, 69,121, 57, 48, 90, 0, 70,107, 44, 54,152, 12,101,213, 94, 71, 1,126,254,112,246,199, 99,252, 61, 93,109,202, - 7, 11, 16,158, 67,243,198, 1,232,217,185, 45, 78, 93,190,130,155,177, 15,193, 63, 27, 44, 64,120, 30,153,249, 37,121, 6, 51, -183,169, 78, 23,148, 99, 65, 44,134, 42, 13, 24, 94,160,105,176,169, 59,163,228,128,207,219, 5,217, 77,154, 51,192,223,206, 70, -198,192, 96,225, 96, 48, 89,160,185,242, 3,156,235, 55,133, 82, 46,103, 34,160, 23, 1,160,147,135, 82, 40,149, 24, 57,114,164, - 60, 47, 47,239,124,255,254,253,155,244,236,217, 83, 25, 25, 25, 9,173, 86,139,147, 39, 79, 66,171,213,250,251,250,250,250,159, - 60,121,114, 88,187,118,237, 18,124,124,124,186,238,217,179,167, 46,125,100, 69,248, 87, 39,117, 30, 0,251,108, 41, 47, 33,158, -118, 52,231, 9, 33,220,139,166, 93, 42,149, 34, 58, 58,250,165, 71,178,110,220,184,241,232, 69, 34, 89, 90,173, 86,226,233,233, - 9,103,103,103,112, 28, 7,173, 86,139, 3, 7, 14, 64,173, 86,131,231,121, 40, 20, 10,124,249,237,122, 60,184,115, 30,215,175, - 95,135, 90,173,150,212,166, 89, 88, 88,200,132,132,132,192,104, 52,130,101, 89, 24, 12, 6,156, 62,125,186,226,119,145, 72,132, -143, 23,175,194,195, 91,231, 17, 19, 19,131,194,194, 66,134,150,234,191,223, 96,253,101, 56,142,157,251,203,230,157,209,115,167, -142,194,244,209, 81,190, 95,252,184, 63, 42,161,128,108, 6,128, 38,174,204,132,113,221,130,252, 28,149, 98, 44,218,126, 11, 32, -100,238, 95, 61, 95, 92, 17,121, 24,230,193,204,248,253,250,255,177,119,222, 97, 81, 29,109, 27,191,231,108,103,119,233,125, 1, - 65, 80, 17, 81, 81,192,174, 17, 21,187,198,104, 52, 70,141, 45,177, 27, 53, 26, 75,140, 70, 99,236, 38,182, 24,141,154,166,177, -183, 24,123,199, 6, 54, 84, 80, 80, 20,145,186,244, 94,182,239,153,239, 15,202,171,134,178,160,249,222,188,230,252,174,107, 47, -216,118,239,156, 57,101,238,243,204,204, 51, 9, 33,243,135,250,195,203,217,162, 81,131, 6, 68, 20, 27,107,194,154,127,172, 1, -214,114,113,227,190, 45,237, 78,131,101, 97,101, 46,246,129,209, 0, 43,185,184,113,239,102,150,167, 0,192, 74, 42,244,169, 44, -210, 85,101,184,183,158,112,188, 84,204, 31, 47, 11,112,174, 55,186,127,119,179, 62,253, 7,153,201, 5, 6,100,223, 60,139, 2, -129, 43,244, 54,238,208,232,115,144, 28, 23,107,188,112, 35, 58, 37,171, 80, 51,171,198, 98, 82, 92, 73,137,123,108,239,233,215, -221, 58,235,248,151, 25,158, 99,118,215,103,192, 50,133,187, 6,166,203, 28, 90,155,221,122, 22, 87,196,210,191, 70,112, 94,165, - 32, 63, 63, 94,111,132,179,202,200, 55,143,189,244, 43,230,245,110,142,220,156, 12,168,117, 6,228,171, 12, 58, 39, 43,137, 88, - 19,247, 0, 26,157, 1, 90, 61, 11,129,149, 11,206,134, 69,102,177,122,253,169,170, 52, 99,179,232, 61, 0,242, 23, 95,107, 96, - 79, 90,204,181, 48,187, 7,189, 10, 9,201, 74,236, 56, 17,230, 95,246,185,186,223,157,178,134,210,110,230, 23, 34, 87,132,162, - 83, 93, 6,183, 55,113, 36,173,205, 36,194,239, 87,127, 54,220,183,157,183,141,152, 77, 14, 3, 97,117,144, 25,249, 80,137,140, -176,116,243, 2,171, 45,164, 37,106,117,222,195,255,199, 37,130, 56, 56,254, 23,240,241,241,113,178,180,180,124,248,249,231,159, -219, 12, 28, 56, 16, 71,142, 28, 65, 65, 65, 1,126,251,237, 55,172, 95,191, 30,139, 23, 47,134, 94,175,199,182,109,219,164,135, - 14, 29,106,189,121,243,230,100,119,119,247,166, 9, 9, 9, 53, 45,168, 78, 0,136, 1, 8,202,218, 46, 2,128, 61,121,242, 36, -250,244,233,131,147, 39, 79,178,101,175, 25, 9, 33,122, 74,169,166,174, 6, 75, 36, 18,225,209,163, 71,111,196,100, 9, 4, 2, -200,229,114,136, 68, 34, 60,126,252,184,214, 38,203, 96, 48,240,146,147,147,145,159,159,143,238,253,251, 99,221,138, 21,232,210, -165, 11,186,119,239, 14, 74, 41,206,159, 63,143,224, 14,205, 48,244,221, 32, 68, 71, 71, 67,175,215,155, 84,222,180,180, 52,164, -167,167,163, 87,255,254,216,190,121, 51,218,180,105,131,198,141, 27,195, 96, 48, 32, 36, 36, 4,131,123,118,128,228,189, 96,196, -196,196,112, 7,245,255,138,193,122,144, 65,111,248,218,147,227, 31,246,108,221,175,127, 71, 95,108,223,119, 97,153,175, 47,217, - 11, 0,182,230,226,165, 35,187,120, 33, 42, 49, 23, 23,238, 41,143, 71,101,210, 55, 50,251,130, 53,194,206,214, 66, 10,240, 68, - 80,233, 88,131,197, 51,212, 56, 48,153,165, 20,210,119,230,226,163,254, 81,110,109,124,221,220,202,103, 17,202,251,172,197,168, -200,167,245, 90, 53,118,170, 7,163, 30, 48,234, 97, 49,116, 55,240,141,172,198,114,116,244, 20,159,155, 59,235,179,246,189,223, -251,192, 76, 36,181,132,177, 32, 9,250,180, 72,100, 63,185,130, 98,105, 35,164, 37, 60,195,254, 51, 55,243,159, 36,103, 23, 48, - 12,206,166,231,107,102,199,230,208,162,154,116,213,122,172,248,234,203, 89,125,247,239,221,103, 46,246,234, 72, 98, 55,245,201, - 23,241, 13, 98,251,250, 1, 76,137,196,142, 46,255,109,159, 69,177, 22, 43,107,210, 41, 41, 46, 56,124,254,236,233,161, 13, 61, - 59,154, 63,191,125, 2, 42,181, 6, 26, 61,208,180,117, 16,140, 70, 42, 34, 12, 97, 45,120, 60,146,145,157, 11,162, 55,166, 95, -189,255, 60,245,218,253,103, 60,141,121,205,218, 47, 29,116,132, 55,173,127, 80, 75, 64,175,194,187,239, 52,199,186, 93, 23, 62, - 5, 48,230,245,118,114,105, 4,139, 2, 29,155, 58,144, 31, 1,116,188,243,199,122,159,192,247,102,160, 54, 17,172,102,246,164, -119,179, 6,138, 95,215, 45,157,107, 99,235,218,136, 71, 88, 61,168,147, 31, 80,144, 76, 73,114, 24, 44, 93,218,192,168,232,128, -109, 27,191, 45, 98, 89,186,183, 46, 41, 42, 56, 56,222,102,212,106,245,225, 85,171, 86,217,244,235,215, 15, 0, 80, 84, 84,132, -176,176, 48,252,244,211, 79,144,201, 94,190, 78,246,233,211, 7,148, 82,155, 69,139, 22, 29, 6,208,174, 42,205, 14, 29, 58,244, -223,184,113,163,178,101,203,150,207,202, 76,150, 16, 0,243,224,193, 3, 38, 41, 41,137, 88, 91, 91, 83,133, 66,161, 87, 42,149, - 44, 0,227,216,177, 99,121,114,185,188, 97, 81, 81,209,229,186, 26, 44,145, 72,244, 70,198,100, 9, 4, 2, 16, 66, 32, 18,137, - 32, 20, 10,145,146,146, 82, 43,147,101, 48, 24,248, 39, 79,158,196,157, 59,119,176,184,101, 75,124,230,226, 2, 27, 27, 27,132, -132,132,128, 82, 10,153, 76,134,156,156, 28,236,221,187, 23, 93,187,118,133,193, 96, 16,154,162,123,240,224, 65,132,135,135,227, -155,192, 64,124,102,105, 9,185, 92,142,243,231, 75,123,253,196, 98, 49, 18, 18, 18,112,254,252,121, 4, 5, 5,113, 7,245,223, -109,176,130, 8,225, 19, 71, 56,233,180, 42, 80, 3, 5, 8, 20,190,190, 68, 24, 21, 69,117,181,253, 81,134,193,151, 27,119, 28, -239,187,118, 70,127, 50,126,128,191, 98,201,175,151, 38, 1,192,199,239,123,187, 72,197,124,108, 56, 26, 69, 25, 6, 95,190,137, - 13,244,245, 37, 66,134,193,164,238,109, 26, 67,153,167, 69,172, 50,239, 98, 20,165, 38,117,233, 92, 88,251, 17,118,254, 25,146, -180,126,167,250, 17,165, 20, 86,114,113,227, 81, 17,177,245,126, 61, 25,158,248,221,126,245, 35,202, 82, 88, 73, 5, 62, 99,162, - 59,212, 56,139,176, 85, 61,225,248, 47,230,206,238, 48, 96,204,231, 18,195,163, 3,208,198,158, 1,171, 83,161, 64, 39, 68, 30, -207, 9,201,137,137, 88,190,237,120, 82, 65,177,118,232,131,140,218, 25,203,152, 44, 90,228,107, 79, 6, 46,255,122,254,185, 21, - 75, 23,201, 85,207, 66,138,120,196,160,226,121,116,230, 47, 93,188,150, 20,106,180, 31,196,230,208,194,154,116, 52,230, 88,185, -234,187,141,125,199,141, 24,244,200,187, 81,103, 91,163, 50,206, 86, 93, 80,144,177,251,116,184, 83,217,157, 33, 1,128,216,228, -108,100,230, 23, 27,140, 6,253,101,115, 1,150, 60, 52, 37, 26, 88,134,151, 35,177, 31,216,201,111,184,189,185, 16,170,162, 60, - 56,152, 11,208,179, 77,131,225, 94,142,100,238,179,116,154, 89,119,131,165, 7,213,171,112, 99,101, 87, 31,106,212,251,192,168, -135, 46,226,247,218, 71,194, 8, 62,155,250,142,220,194, 90,251,156, 65,177, 12, 48,179, 3,177,112, 7, 44,235, 19, 65,147, 15, -160,124,246,208,240,233,240, 17,217,113,241,201, 63,219,153, 97, 13,119, 9,225,224,120,153,132,132,132,145, 95,124,241,197,181, - 54,109,218, 56,218,217,217,161,121,243,230,248,243,207, 63,241,249,231,159, 87,124,166,101,203,150,160,148, 34, 39, 39, 7,171, - 86,173, 74, 83, 42,149, 35,171,211,124,248,240,225,163,157, 59,119,190,227,235,235,171, 19, 10,133,121, 0,196,121,121,121,146, -156,156, 28,162, 86,171,193,178, 44,107,105,105,105, 84, 42,149,250,161, 67,135,106, 66, 67, 67, 27, 20, 23, 23, 39,188, 78, 4, -171, 85,171, 86, 15,242,242,242,242, 25,134,121,237, 20, 14,229,230,170, 89,179,102,246,197,197,197, 44,128,220,186,164,112, 48, - 24, 12, 8, 12, 12,196,153, 43,119,113,242, 66, 40, 10,148,143, 49,105,220, 72, 52,111,222, 28,103,206,156,169,243, 62,107,209, -162, 5, 78,159,191,134,107,119,238, 35, 33, 38, 2,159, 78, 26,135,166, 77,155,226,244,233,211,220, 1,253,119, 27,172, 38,246, -164,133,162,161,232,247, 69,189, 27, 52, 17,116, 95, 4, 34, 48,195,129, 70,167, 59,124,185,124,211,163,230,142,100, 68,100,122, -205,179,189, 94,138, 98,165,211,135, 77, 29,200,158,251,209, 62,195,223,109,227,134,237,127, 74, 23, 2,192, 7,157, 60,113,235, - 73, 38,110,198,100,236,121,152, 65, 31,190,238,198, 53,119, 36, 82, 80,236, 89, 53,109, 64,144,187,171, 19,126, 58,114, 13,132, -224,176, 73, 13, 45,165,180,141,175, 59,214,239,124,117,198,160, 83,189,239,246,171, 31,157,121, 80,208, 27, 0,122, 52,145,157, -106,213,192,186, 94, 77,145, 12, 51, 17,127, 66,239, 65, 31, 73, 12, 49,127, 2,241,231, 65, 12, 26,168,116, 44, 82,179, 10, 81, - 98,233,134,144,176,251,170,124,181,118,198,195,140,186, 69,237,162, 50,233,179,150,206, 36,177,168, 88,229, 44,181,111,160,230, - 49, 44, 91,164,161,184, 21, 21, 95,240, 48,149, 62, 54, 69, 35, 54,150,106,219,185,146, 78, 63,238,216,255,149, 64, 40,250,128, - 71, 64, 28,172,100,246, 63,174,253, 6,230,230,114,176,218, 34,160, 56, 19, 3,167, 44,207,140, 76,209,121, 2,128,183, 29,145, -191,227, 37,220,193,103, 72,242,197,167,218, 5, 53,253, 6,209, 99,226,136,158, 45, 5,172,182, 24,211, 86,237,195,214,185, 3, -240, 81,183, 38,130, 19,215, 99, 38, 2, 88, 82,215,125, 77,141, 6, 80,189, 10,237,230, 95,121, 68,128,107, 20,232,120,103,255, - 82, 31,224,174,201, 26, 1,132, 8,248,206,164,137, 95, 61,153,144, 77,190, 14, 54,249, 58,229,185,117, 0,169,247, 14, 33, 78, -129,244,251,213,139,139,183,111,255,233, 44,203,224,235,154, 82, 94,112,112,252, 91,161,148, 62,179,178,178,234,213,167, 79,159, - 11,103,206,156,177,105,214,172, 25, 0,160,124,198, 90, 96, 96, 32,188,189,189,145,158,158,142, 15, 63,252, 48, 43, 53, 53,181, - 23,165,180,218, 49,189,133,133,133,113, 7, 15, 30,116, 44, 46, 46,110,185, 96,193,130, 12,119,119,247, 2,181, 90, 77,242,242, -242, 88,131,193, 0,107,107,107, 81,203,150, 45,209,190,125,251,162,176,176, 48,143,164,164,164, 66, 0,241,117, 41,255, 39,159, -124,130,195,135, 75,155,137, 55,145, 23, 75, 40, 20, 34, 56, 56,216, 37, 52, 52, 52, 5, 0,234,146, 23,235,197,230,229,254,253, -251,184,124, 55, 25,124,173, 10,162, 76, 37,110, 28, 57,136,254, 19, 38,195, 96,168,251,104,133,251,247,239,227,143,243, 55, 32, - 19,243,241,248,241, 67, 28, 60,120, 16,147, 38, 77,122, 45, 77,142, 26, 12, 86,131, 6, 68, 36, 46,194,162,158,129, 46,115, 62, -232,216,128,167, 47, 80,130, 53,178,224, 9, 0, 7, 59, 11,252,254,251, 30,207, 61,251,246,133,181,112, 17,108,100, 13,134, 47, - 35,211,105, 73, 45,126,123,209,218,125,215, 62,248,125, 86, 16,127, 82,111, 31, 27, 0, 16,242, 25,108,248,243,161, 1,192,162, -215,217,168,118,174, 68, 82,164,199,120, 39, 91,203,133, 95,124,210,215, 38, 40,208, 27,151,111, 62,192,198,131, 97, 87, 68, 25, -216,105,242, 65,205,234, 95,157, 2, 91,233, 44, 66,176, 53,143,167, 52, 26,169,147, 80,102, 13, 93,252, 37, 64,167,134, 90,163, - 67, 82,182, 17, 73, 57,106,240,165, 66,220,137, 73, 86,217,166,225,120, 93,183,153, 16, 66, 58,122, 73, 20, 95, 45,251,206, 85, -173, 42, 50, 20,228,102, 25,132,162, 27, 2,169,153, 56,181, 54, 58, 97,201, 84,221,217, 83, 24, 0,176, 60,145,132,150,204,159, - 57, 90,150, 18,117, 6, 13, 25, 37, 8,165, 48,107,210, 23,230,102, 60, 97,167,250,194, 68, 0,168,239,100, 41, 90,245,245,231, -150, 51,230,126, 93,227, 24, 47, 95, 66,132,205, 91, 57,205,104,230,110,141, 43,225,143,112, 37, 50,225,225,149, 59,143,155,118, -105,174,128,183,171,213,116, 95, 66, 86, 70,209,218, 71, 68, 75,119,140, 1,208,171, 43,102, 17,250, 58,146, 97,173, 62, 88, 80, -233,236,193,170,168, 15,176, 49, 70, 10,194,227, 1,132, 41,157,209,152,116, 29,124, 43, 47,186,103,255, 31, 37, 63,253,180,243, -155,168, 76,202, 69,173, 56, 56,106, 32, 47, 47, 47, 66, 42,149,246,244,243,243,251,109,218,180,105,230, 35, 70,140, 80,140, 27, - 55,142, 1,128,244,244,116,118,253,250,245,202,239,191,255, 62, 63, 43, 43,107,140, 78,167,139, 52,229,134,151, 16, 18,250,243, -207, 63,103, 94,189,122,181,105,235,214,173,197, 1, 1, 1,172,181,181, 53, 95, 44, 22, 27,181, 90,173, 58, 38, 38,198,248,236, -217, 51,231,188,188,188,167, 0, 98,235,210,125,175, 80, 40,192, 48,204, 18, 87, 87,215,175,148, 74,101,179, 55, 49, 6,171, 97, -195,134, 10, 0, 79, 93, 92, 92, 26,214,182,123,240, 47, 13, 54,159,143,220,220, 92,148,164, 61,132, 36,249, 9,252,100, 12,124, -173,229,176,176,176,120, 45, 51,148,159,159, 15, 20,167,224,218,181,251,128,193, 0, 75, 75, 75, 88, 90, 90,114, 6,235,239, 50, - 88, 77, 29,200, 36,107, 17,214, 79,232,219, 64, 88,191,158, 43, 52,201,119,112, 63,169, 8, 95,182,109, 29,197, 19,155,171, 39, -140, 28, 16, 56,104,176, 7,130,218,183, 34,245,157, 45,167,175, 92,187,101, 74, 83, 71,242,249,195,116,186,193,148, 31,126,152, - 65,227,154, 56,144,159, 46, 69, 36, 79,116,149,170,192,178, 20,151, 34, 83, 17, 25,159,251, 83,116, 6,141,171,205, 70, 52, 85, -144, 96, 62,152,125,148, 82,137,165, 76, 86,216,178,133,143, 93,112,187, 22, 76,175,206,129, 16,242,128,107,183,238,227,179,181, -135,111,176, 44,237, 27,110, 98,247, 96,233,140,193,151,141, 83,233,140, 65,253, 75, 51, 6, 41,165,180,116, 22, 97,245,195,186, -120, 60,146, 86,146,112,219, 73, 96,219, 8,170,216, 75,136,207,101,145,144, 81,136, 2,190, 19, 52, 41, 41, 0,101, 19, 67, 40, -173,243,209,108,103,103,231,224,233,235,221, 96,211,142,131,208,149,228, 35, 46,228, 55, 20,229,166, 98,233,143,127, 54,112,117, -117,237,156,156,156,124,185, 22,102,205,251,194,241, 61, 14,160, 0, 79, 32,198,137,205,251,145,101,107, 6, 59,169, 16,172, 42, - 19, 19,102,140,176,236,221,125,132, 37, 0, 36, 60,190, 7,119,169,202, 36, 93,157, 45, 6,125,208,165,177, 21,244, 42,236, 56, -125, 79,205, 0,189,118,158,125, 24,219,197,199, 74,242, 65, 71,119,235, 37,202,188,247, 81,199,100,160,229, 17,172,138,136, 94, - 29,102, 15, 30,160,212,216,196,158,196,238, 11,205,144, 13,238, 30, 32, 21,242, 9,161, 69, 41,160,102,118,216,178,227, 64,145, - 72,143,109,220, 37,131,131,195, 52, 74, 74, 74,194, 9, 33,205,103,207,158, 61,108,254,252,249,239,200,100, 50, 79, 0, 40, 46, - 46,142,211,235,245, 87, 0,236,169,205,108,191, 50,195,244,148, 16, 18, 23, 27, 27,235,184,107,215, 46, 43, 0,146,178,183,213, - 0,242, 0,164,191,206, 12,194,114, 51,165, 80, 40,190,122, 83,245, 80,110,166, 92, 92, 92, 26,214,229,251, 60, 30,207, 72, 8, - 1, 33, 4, 98,177, 24, 87,175, 94,197,144,190,221, 17,125, 34, 15,205,172,228,104, 61,102, 2,246,157, 59, 7, 30,143, 7, 66, - 8,120, 60, 94,173,218, 17, 62,159,143,107,215,174,225,163, 15, 7, 67,204, 7, 44, 45, 45, 49,123,246,108, 28, 61,122, 20,124, - 62,183,154,222,223, 19,193, 34, 88,114,238,183,229, 66, 24,245, 56,246,219,183, 56,254,160, 72,251, 56, 19, 95, 54,206,196,250, -131, 40,100, 51,215,238,156,120,238,218,131, 53, 99,135,246,147,118,237,210, 29, 93,131,186,240,155,182,234,188, 16,192,134, 23, - 26,234,224,234,114,101, 24, 89,124,179,237,244,163, 9,251, 66, 98, 8,116,133, 24,218,163, 21, 53,178,248,166,134,198,255, 47, -154,150,102,242,125,215,194,194,172,161, 43, 66,252,189,139, 18, 15,207, 6,128, 81,135,167, 79,159,224,251, 29, 71,216,144, 91, -143,127,215, 26, 48, 45, 54,135, 22,155,170, 89,234,168, 12,176,148,137, 26,247,110,102,121,138, 5,133,149, 84,232, 67, 89, 35, -172,164, 2,159, 30, 77,100,167, 40,165,212,220, 76,224, 67,141,250, 26, 53, 85, 90,195,214, 29,191,252,244,221,199, 31,127, 44, -203, 74, 78,131,178,224, 1,138, 68, 46,208, 75,221, 16,123,239,138,170, 68, 99,168,177,241,174,174, 62,179,178,178, 50,194,111, -230, 96,223,143, 43,160,215,106,144,145, 92,234, 81,149, 89, 5,176,176,115, 9,171,141,166,206,192,230, 15, 26, 49, 94,104,102, - 14,179,143, 6,245, 19,197,102,107,224,175, 48, 47,189,200, 21,101, 34,250,252, 53, 4, 21,151,250,181,103, 73, 12,220, 91, 40, - 76, 42,167,185, 68, 56,173,119,128, 11,226, 18, 83,113,245, 97,202,142,103,217, 84,233,101, 75,118,196, 42,243, 38, 14,104, 91, - 15,235,142, 70,125, 90,149, 41,170, 74,211,215,145, 12, 3,208,177,116,144,187, 10, 20,232,232,235, 72,134,153, 50,115,176, 50, - 77,190, 16,195,191, 59,149,176,224,192,237,172, 1,115,134,119,178,104,223,190,143, 8, 6, 45, 10, 85, 26,125, 84, 46, 45,120, -157,125,244, 26,209, 73, 78,147,211,252,159,212, 44, 51, 59,191,151, 61,222,164,166, 18,175,228,101,122,221,109,127,177, 59, 80, -169, 84,242,203,162, 87,213, 14,114,175, 73,243,197,238,192,148,148,148,147,101,209,171,106,163, 88,149,104, 42,219,180,105, 99, -211,191,127,127, 24,141, 70, 60,121,242, 4, 9, 73, 73, 8,158,248, 41,172,172,172,112, 37, 34, 2,143, 31, 63,198, 87, 95,125, - 5,150,101,113,227,198,141,228,154, 52, 5, 2,129,174, 69,139, 22,194,247,222,123, 15, 6,131, 1,207,158, 61, 67, 74, 74, 10, - 62,251,236, 51, 88, 90, 90, 34, 60, 60,188, 66, 83,163,209, 32, 46, 46, 78,247,255,113, 44,253,123, 12, 22, 96,132, 81,143,252, -115,139,176,225, 42,116, 58, 61,124, 30,102,208,231, 47,188,191,197,207,150, 28,139,120,240, 40, 46,252,122, 87, 17, 50, 34, 75, -191, 83, 11, 98,178,104,106, 43, 55,126, 33,116,133, 22,120,118, 10,207,211, 11,139, 98,178,104,106,109, 55,130,178, 70, 2, 93, - 9,144,122, 7,161, 87, 46, 35,228,198,125,220,142,124,100, 12, 13,143,217,199,176,248, 38, 42,139, 62,169,181, 38,165,144,247, - 93,135,209,145, 79,235,181,242,118,172, 7,163, 1,148,213,195,114,232, 30,140,137,106, 95,175,149,151, 85,189,210,200,149, 30, -214,159, 92, 4,190,147, 84,171,119, 59, 81,183,173,163,167,248,253,194,188,236,182,221, 58,183,147, 89, 54,233,141,172,167, 49, -120,114,255,154, 42,252, 65,108,232,237, 68,221,107, 69, 71, 92, 92, 92,222,233,214,185, 49,134, 78,248, 2,186,146,124, 60, 11, -249, 5, 69, 57,105,184, 26, 38,199,163,130,130,118, 0, 76,142, 96,133, 38,232,155, 2, 64,199,250,194, 68,115,104,156, 70,246, -235, 15, 49, 81,131,213, 20,128,148,100, 33, 54, 69,155,255,254,143, 73, 70, 0,144,138, 9, 95, 70,243, 45, 76,209,245,117,183, -109, 36,229,233,177,243,220, 67,176,108,233, 50, 75, 44,139, 45, 59, 47,198, 78,252,230, 35,127,248,214,179,110, 65, 8, 33,181, - 9,237, 19,138, 78,183,247,125,237,163,190,176, 16, 96,117,184, 54,221,198,167,211,134,156, 78,117,141,132, 69,166,208, 20, 0, - 19,155, 40,200,214,233, 27, 78, 47, 12, 60, 23,213,113,214, 39, 3, 44, 64,185,133,209, 57, 56, 56,254, 43,145,192, 9,115,231, -206,221,202,227,241,236, 1, 16, 74, 41, 52, 26, 13,255,199, 31,127, 20, 24, 12, 6,134,199,227, 25, 37, 18,137, 33, 60, 60, 92, -207,178,108,166, 78,167,155, 80,147,166, 86,171,141,221,180,105, 83, 3,189, 94, 95, 49,227, 80,163,209,224,151, 95,126,129, 70, -163,129, 88, 44,134, 92, 46,199,179,103,207, 64, 8,209, 25,141,198, 88,110, 79,188, 73,131, 69,241,117,135,143, 22, 45, 2, 64, - 64,177,248, 21,115, 5, 0,136,200,166,202,166, 14,228,179,166,173, 58, 47, 42,255, 78,109, 11,160, 54, 26, 7,183,106,238,189, - 23, 0, 52,212,248, 81, 93, 54,162, 64,163,250,160,101,171,118,251, 88, 74,249, 6, 74,127, 98, 88, 28, 82, 27, 16,109,202,204, -185, 42,239, 60, 50,242,194,203, 23,112,102, 65,255,211, 45, 88,150,142,129, 82, 74, 43,186, 5,191,149, 32, 43, 95, 83, 99, 30, -167,107,113,154,238,173,234, 9,199,159,189,126,111,130,209, 72,157,120, 60,146,166,210, 26,182,190,174,185, 42,187,251,186,236, -235, 64,206, 70,180,112,236, 97, 39, 45,139,106,149, 0, 89, 37, 56,155,156, 81,120,185, 46,154,185,197,250, 1,243,215, 31,253, - 83, 36,224,241, 65,105,105, 34, 80, 74,161,214, 25,115,202, 77,152,159, 45, 81,204,254,195,176,151,199, 35, 9, 53,233,221,124, -156,186,110,232,202,243,159, 63,140,207,253,233,121, 46,125, 0, 0,207,115,233,131,134,182,100, 97,108, 90,225,231, 15, 18,114, -191,173,237,184, 9, 74,112,181,213,208, 69,127,121,237,117,235, 51, 90, 73,239, 3, 24,216,212,129,116, 31, 58,235,251, 89,132, -128, 91, 38,130,131,227, 95, 68,121, 20,139, 97,152, 37,111, 74,179, 60,138, 5,224,105, 45,190,115, 19, 64,243, 55,185,109,225, -225,225,217, 0,178,185,189,252, 95, 50, 88, 15, 51,232, 22,152,176,152,179,169,159,171,242,251, 74,122, 30,128,237,235,108, 68, -153,134,205,155,172,152,136,116,186,240,239,168,240, 50, 51,245,183,140,229,137,202,160, 61, 1,160, 81,163, 70,244,233,211,167, -160,148,190, 86,246,221,232, 76,122, 31,175, 44,185, 80,153,201, 6,208,201, 20,189,152, 44,250, 13,240,215, 46,224,167,217,116, - 41,128,165,117,218,230, 58,102,106, 55,249,216,202,160,231,128,154,179,233,115,112,112,188,157, 38,235, 77,107,190,238,194,207, - 28,111,129,193,226,248,223,229,201,147, 39,220,178, 6, 28, 28, 28, 28, 85, 99,252, 27, 52,185,164,195, 28, 47,193,112, 85,192, -193,193,193,193,193,193,193,241,102, 33, 0,130, 43,181,226,181,152, 29, 64, 8, 9,174,181,213,175, 65,159,211,228, 52, 57, 77, - 78,147,211,228, 52, 57,205,183, 79,179, 38,237,183,102,118, 34,125, 97,240,242,155,126, 0, 8,230, 52, 57, 77, 78,147,211,228, - 52, 57, 77, 78,147,211,252,183, 61,184, 46, 66, 14, 14, 14, 14, 14, 14, 14,142, 55, 12,103,176, 56, 56, 56, 56, 56, 56, 56, 56, - 56,131,197,193,193,193,193,193,193,193,193, 25, 44, 14, 14, 14, 14, 14, 14, 14, 14,206, 96,113,112,112,112,112,112,112,112,112, -212, 29, 82,203,149, 73, 56, 56, 56, 56, 56, 56, 56, 56, 56,106,128,139, 96,113,112,112,112,112,112,112,112,112, 6,139,131,131, -131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224,224,224,224,224, 12, 22, 7, 7, - 7, 7, 7, 7, 7, 7,103,176, 56, 56, 56, 56, 56, 56, 56, 56, 56,131,197,193,193,193,193,193,193,193,193,241,223, 55, 88,132, -144, 96, 78,147,211,228, 52, 57, 77, 78,147,211,228, 52, 57, 77,206, 96,113,112,112,112,112,112,112,112,112,112, 6,139,131,131, -131,131,131,131,131,131, 51, 88, 28, 28, 28, 28, 28, 28, 28, 28,156,193,226,224,224,224,224,224,224,224,224,224, 12, 22, 7, 7, - 7, 7, 7, 7, 7,199,127, 9, 2,160,210,153, 0,148,210,243, 38,139,212, 97, 54, 65, 77,250,156, 38,167,201,105,114,154,156, - 38,167,201,105,190,125,154, 53,105,215,198,127,252,163,161,148,254,109, 15, 0,193,156, 38,167,201,105,114,154,156, 38,167,201, -105,114,154,255,182, 7,215, 69,200, 97,106,148,210,145, 16,226,200,213, 4, 7, 7, 7, 7, 7, 71,205,240,223,164,152, 15, 33, -109,214,188, 83,111, 81,159,203, 9,189, 76,104,176, 25,252,103, 12, 24, 91, 26, 76, 43,181,197,175, 97, 2,222,184, 38, 7, 64, - 8, 89, 65, 8,230,148,253,191,154, 82,250,197,219,184,157,115,230,204, 25,236,239,223, 10,214,146,116,180,242,122, 2,228,238, - 1,172, 63,192,130, 51, 93,208,202,191, 3,174,220, 77,194,149, 27, 15, 17,182,185, 63, 62,153,177, 8,106,181, 14, 89, 89, 74, -220,191,118,250,224, 91,180,175,219, 10, 4,130, 15,172,173,173,205, 51, 50, 50, 46, 0,248, 19,192,187, 14, 14, 14,221,114,115, -115, 11,245,122,253,126, 74,233,141,186,104,191,211,146,204, 21, 9, 5, 99,213, 58,253,170,107,247,232, 47, 65, 1,196,214,192, - 98,165, 68,200,239,164,209, 26, 86, 95,189, 79,127,170,101, 89,201, 43,209,248, 90,159,235, 7, 9,225,153,250,217, 63,172,173, -189, 45,228,242, 11, 18, 30,239,121, 74, 73,201,136,193, 25, 25, 73,131, 41, 53,190, 77,231, 64,215,174, 93, 71,243,120,188,101, - 0, 96, 52, 26,191,188,120,241,226,111,111, 66, 87,161, 80, 12,163,148,202,202,246, 91,177, 82,169,220, 99,234,119, 3, 2, 2, - 18, 0,212, 43,123,154, 24, 30, 30,238,110,202,123, 28,181,227,206,157, 59,212,221,221, 29,205,155, 55,127,156,150,150,246, 61, -165,116, 11, 87, 43,255, 16,131,213,152,144,134, 19,251,180, 63,215,227,253,158, 50, 83,140,144,139,139,203, 74,123,123,251, 73, - 37, 37, 37,106, 0,148,199,227,209, 38, 77,154,128, 16,130,242,235,166,209,104,204,124,244,232, 81, 51, 83,205,213,155,210,244, -246,246,190,195, 48,140,235,139,215,239,154,254,103, 89, 54, 57, 42, 42, 42,176,166,114, 58, 59, 59,247,100, 24,102, 94, 77,159, - 99, 89,118,101,106,106,234,153,234, 62,211,188,121,243,187, 50,153,204,145, 97, 24, 82,213,103, 94,108,115, 12, 6, 3, 45, 41, - 41, 73,127,248,240,161,127, 45, 26, 49, 71, 66, 48,135,101, 41, 3, 0, 12, 67,230, 90, 91, 91,239,206,205,205,141, 42,127,191, -236,119,210,107,115,188,184,184,184,140, 2,240, 57, 0, 10,224,187,148,148,148, 29,181,249,126,163, 70,141,238, 8,133, 66, 87, - 30,143, 71, 94,221, 39,149, 61,103, 89,150,106,181,218,228,199,143, 31, 87,185,143, 66, 66, 46, 31, 88,189,122,245,221,109, 63, -255,228,223,162,229, 96, 48,210, 46,208, 81, 11,220,141,215,160, 85, 11, 2,202,178, 80, 23,100,128,101, 89,148,168, 53,184,112, -228,151,187,245,234, 55,240, 71,233, 88,198,183,193, 92,245, 26, 53,106,212,242, 85,171, 86,217,137, 68, 34,102,255,254,253,237, - 62,251,236,179,177,235,214,173,115,249,224,131, 15,204,181, 90, 45, 59,119,238,220,119, 8, 33, 95, 83, 74,143,214, 70,187,125, - 75,210,182,113,125,231,175,166,142,232,138,207, 87,236,157,218,177, 57,201, 50,147, 9,183,188,223,169,129, 85, 83, 79,107,124, -189, 53,116, 26,128,159,106, 81, 86,226,230,230,214,210,209,209,177,190, 74,165, 50, 2, 64,211,166, 77, 41,143,247,178, 95,210, -233,116,186, 71,143, 30,157,124,221,186,249, 92, 34,105,211, 73, 38, 61,247,197,196,113,102,185, 89, 89,142, 91, 15, 30,142, 56, -232,224,224, 55, 24,136,127,155, 26, 4, 30,143,183,236,244,233,211,206,148, 82,244,236,217,115, 25,128, 55, 98,176, 40,165,178, -212,212,212,242,107,160,172,150, 95,175, 23, 30, 30, 94,110,168,234,213,226, 61,147,105,215,174,157,196,160,211, 77,230, 49, 76, - 15, 10, 52, 71,233, 73, 29,105, 4,206,241,249,252, 31,194,194,194,212,111,187, 25, 56,119,238, 28,198,143, 31,143,200,200,200, -198, 39, 79,158,220,172, 80, 40,166,164,166,166,118,161,148,102,114, 86,233,191,104,176,154, 18,226,208, 47,160,241,213,201, 31, - 13,150,178, 7,215, 19,140, 94, 80,173, 17,114,118,118, 94,213,169, 83,167,177,187,118,237,146,253,241,199, 31, 50, 15, 15, 15, - 8,133, 66,240,120, 60,240,120, 60, 48, 12, 3, 62,159,143,119,223,125,215,164,134,235, 85,205, 11, 23, 46,200,188,189,189,255, -210,200, 50, 12,131,222,189,123,215,168,201, 48,140,235,221,187,119, 29, 36, 18, 73,133, 73, 97, 89,246,165,199, 11,253,208, 48, - 24, 12,232,212,169,147, 73,117,197, 48,204,188,232,232,232,119,138,139,139,171,237,187, 45,211, 59, 83,131,150,226,250,213, 11, - 14, 68, 23, 7, 24,114, 64,121, 54,128,200, 19, 96,196,149,126, 62, 39, 39, 7, 93,186,116,225,189,206,190,238,219,183, 31,161, -148, 30, 81, 40, 20, 23,178,178,178,204, 9,193,135,117,140,108,125, 17, 19, 19, 99, 78, 41, 69,227,198,141,231, 1,168,149,193, -226,241,120,174,103,207,158,117, 16,139,197, 21,251,185,170,191, 70,163, 17, 58,157, 14,189,122,245, 50,212, 96,106,241,195,214, - 95,252,213, 26, 61,212,212, 3, 15,163,139,113,234,212, 17,212, 47,214, 35,246,129, 26, 44,171,128,186, 48, 3,148, 82,168,212, - 90,180, 8,122,223,159,101,223,158, 0,169,165,165,229,224,117,235,214,217,255,244,211, 79, 5,143, 31, 63,214,253,248,227,143, -246, 19, 38, 76,240,209,233,116,152, 56,113, 98,102,227,198,141,133,235,214,173,179, 63,114,228, 72, 79, 0,181, 50, 88,124,130, -111, 62, 28,208, 3,106, 61, 3,189,222, 96,239,108,111,254,251,244, 81, 65, 2, 74,181,216,121, 52, 28,122, 3,251, 75,109,205, - 85,239,222,189,221,183,108,217,194,143,142,142,230, 55,105,210, 4, 70,163,177,226,193,178, 44,140, 70,163,201,231,101,117,140, - 5,188,157,172,173,207,181,233,211,215,204, 73, 38,133,248,249, 83,244,183,150,153,159, 76,205,218, 5,160,253,219,214, 40,240, -120, 60, 36, 37, 37,193,210,210,210, 44, 40, 40, 40,149, 16,178,248,210,165, 75,219,254,142,223,122,157,200,214,155, 34, 32, 32, -160, 53,159, 97, 14, 45,156, 63,213,201,175,101, 75,158,131,163, 61, 98,158, 36, 66,200, 99,131,159, 62,138, 9, 90,254,237,150, -233, 1, 1, 1,239,135,135,135,223,122,219,246,181,251,160,159, 54,179, 6,221,164,210,103, 86, 0,182,161,176,176, 16,159,124, -242, 9,142, 30, 61,218,164,109,219,182, 43, 75, 79, 1,142,255,138,193,242, 37, 68,214,194,195, 41,228,155,207, 39, 88,211, 83, -191, 50, 37,217, 25, 16, 86, 99,132,156,156,156,150,118,234,212,233,163, 93,187,118, 89, 19, 66,112,110,234, 88, 88,235,212, 80, -124,181, 26,214,118,246,208,206, 27, 15,115,163, 1,126,151, 34, 76,189,216,254, 69,243,241,227,199,200,205,205,133,157,157, 29, -164, 82, 41, 36, 18, 9,132, 66, 33, 68, 34,145,169,154,144, 72, 36, 56,127,254, 60,248,124, 62,120, 60, 30,248,124,126,197,227, -197,231, 60, 30, 15,142,142,166, 15, 77, 98, 89,118,165,143,143,143, 95, 76, 76,140, 69, 94, 94, 30,218,182,109, 91, 64, 8,137, -120,225, 78,207, 47, 34, 34,194,194,228,198, 70, 23,135,162,196, 31, 65,115, 15, 1, 86,131, 96,180, 24, 10, 53, 60, 43, 26,152, - 23,255,178, 44, 91,151, 59,207,116, 66,200,234,254,253,251,205, 3, 8,130,131,131,139,166, 78,157, 74, 31, 63,126,220,227,189, -247, 6,212,127,242,228,105,153,217, 35,115, 8, 33, 27, 76,141,100, 81, 74,197, 0,112,245,234, 85, 80, 74, 37,117, 57,246,196, - 98, 49,194,194,194, 42, 34,148, 12,195,128, 97, 24,240,120, 60, 28,123,106,135, 98, 45,131,146,244, 7,248,180, 95, 61,120,122, -122,254,197,112,255,101,223, 80,138, 41, 19,198,222, 93,178,106,189,191,209,104,196,169, 83,167,176,118,237, 90,104, 52, 26, 4, -117,235,129,231,180, 5,154,121,218,129,101, 89,168,212, 90, 68, 92, 62,116, 87, 81,207,211,255,109,185, 24,228,231,231,255,238, -237,237,205,203,204,204,188, 8, 32, 78,175,215,111,250,253,247,223, 29, 62,254,248,227,140, 93,187,118, 77, 5,224,182,102,205, -154,158, 69, 69, 69,251,106,163,219,169, 5,233, 19,216,178, 89,219,122,110,110,184, 28,122, 11, 66,145,192,106,242,232,126,144, -203,249,248,246,167, 19,108, 66,114,206,212,171,247,233, 14, 19,207, 77,226,236,236,236,215,163, 71, 15,183, 45, 91,182, 8, 1, -224,193,131, 7,200,200,200,128,173,173, 45, 36, 18, 9, 4, 2, 65,197, 13,219, 27, 49, 87,118,118, 55, 15, 30, 60,104, 6,189, - 30,155,190, 93,141,126,170,124,152, 17, 64, 11, 82,255,109,106, 12, 2, 2, 2,188,187,116,233, 34, 49, 26,141, 40, 46, 46,198, -150, 45, 91, 44,205,204,204, 44,123,247,238,189, 8,128,201, 6,171,125,251,246,233, 90,173,214, 1, 0, 68, 34, 81, 70,104,104, -168, 35,128,146,250,245,235,155,149,125, 68, 85,203,200, 86,226, 11,209,169,196, 90,188, 87, 35,129,129,129,173,154,120,215, 63, -191, 98,197, 98,121, 94, 65, 26, 44, 45,211,193, 32, 15,219,182,253, 0, 51, 51, 11, 44, 90, 52,159, 31,216,166,141,203,244,207, -230,159, 15, 8, 8, 8,126,219, 76, 22,107,208, 77,106, 17,248,159,123,132, 29,231, 54, 66, 99,233,143,148,197,139,177,126,253, -122, 52,106,212,168, 53,103,147,254, 75, 6, 43,136, 16,190,171,141,252,216,230, 69,211,235, 51, 97,199, 5,170,196,167, 80,170, -141,176,250,207,201,115,254,197, 11, 35, 0,198,209,209,113,242,158, 61,123, 44,202, 27,187,198,196, 8, 43,232, 80,191,105, 83, - 72, 45,173,144,102,208,129,234,117, 16, 10, 4,149, 54,136,166,104,150, 71,192,132, 66, 33,132, 66, 97,197, 5, 87, 40, 20,214, -168,249, 82,229,240,249, 96, 24, 6,231,206,157,131,193, 96,192,224,193,131,255, 98,174,248,124,254, 75, 93,144, 53,105,166,166, -166,158,113,113,113,137,160,148,190, 99, 52, 26, 65, 8,137, 72, 73, 73,233, 92,254,190,179,179,115,207, 22, 45, 90,204, 99, 89, -118,165, 73,229, 52,100,131,230,236,129,121,187, 44, 20,132,217,129,200,130,193, 18, 15, 68, 62, 73,197,197,219,241,200,204, 45, - 70,128,183, 61,122,182,111, 0,163,209,104,242,182,191,136,139,139,203,213,204,204,172, 33, 93,187,118, 69, 78, 78,142, 97,241, -226,197,104,209,162, 5,188,189,189,171, 50, 79, 53,106, 18, 66,148, 17, 17, 17, 30, 42,149, 10,132, 16,165, 9,134,236,124,101, - 70,248,247,223,127,135, 90,253,215,232,189,117,231,229,248,124,144, 59,198,124,186, 3,171, 31,239,199,230,205,155,241,234, 16, -157, 87, 53, 89,150,197,146,149,235,253, 85, 26,109, 69, 93,105, 52, 26,132,133,133, 65, 83, 82,136, 75,187,198, 85, 68, 47, 85, -106, 45, 92,253,186,251,215,164,249, 38,248,255,210,164,148,134, 0, 8,121,161,126, 23,236,218,181,107, 8,128,195,148,210, 80, - 0,161, 0,246,214,186,156, 4, 99, 62, 24,244, 30,248, 66,115, 60,122,154,140,206,237,252,225,232,224,128,136,232, 88, 36,164, -228,164, 19,130,209,189, 58,136, 87,170, 84,218, 5, 87,238,209,159,107,210,116,118,118,246,220,182,109,155,224,197,136, 11,143, -199,123,233, 92, 47,127,173, 50,147,101,106,125,142, 5,188, 93,172,173,111, 30,253,242, 75, 89,218,175,191, 34,191, 99, 71, 8, - 90,183,197,246,115,167,145,153,171, 82,107,141,108,183,183, 97,191,151,155,171,160,160,160,208,165, 75,151, 90, 37, 37, 37,225, -250,245,235,240,240,240, 64, 73, 73, 9,106, 26,218,246,170,166, 86,171,117,120,161,219,206, 1, 0,210,210,210,246,226, 63, 93, -233,180, 54,229,172,110, 92, 85,109,198, 92,189, 90,206, 6, 13, 26,136,236,172,173, 15,172, 92,181, 68, 30, 21,125, 5, 45, 91, -180,133,220,210, 23,172, 49, 13,217, 57, 69,200,125,170,196,210,165,171,177,104,241,151, 88,189,106,169,124,232,176, 49,135,218, -181,107,215,240,197,238,194,255,245,253,206,240,133, 91,238,223, 9,157, 4, 0, 5,209,135, 49,125, 88,123, 20, 22, 62,197,196, -137, 11,145,146,146,130, 39, 79,158,132,255,127,150,147, 51, 88, 47,152,155, 64,177, 96,247,222, 69, 83, 91,139,227, 35, 69,154, - 7, 97, 80,106, 88,250, 91,146, 33,229,219,106,190, 87, 82, 82,162, 61,122,244, 40,206, 78, 25,139,134,196, 0,155,175,214,192, -209,197, 5,121, 99,222, 69,161, 94,135, 6,167,110, 65, 44,151, 67, 36,147,215, 24,113,120, 81,243,210,165, 75,120,248,240, 33, -248,124, 62,228,114, 57,228,114, 57,196, 98, 49, 68, 34, 81,133,185,170,202, 96, 85,113,240,128,199,227,225,193,131, 7, 72, 72, - 72,128,149,149, 21,174, 95,191,142,110,221,186,253, 37,138, 85,199, 3,190,210,136, 82,217,184,171, 51,166,106, 64, 96, 7,216, -124,132,194, 27, 10,192,122, 4,244,176,130,209,104,196,189,167,217, 24,255, 81, 95, 0,192,228, 5, 63, 34,184, 77,253, 10,115, - 80,139,240,189, 25,128, 57,141, 26, 53, 26, 58,124,248,112,131, 80, 40, 68,113,113, 49, 84, 42, 21, 30, 60,120, 96,232,219,183, - 95, 81,255,254,253,228, 39, 78,156, 96, 41,197,234, 90,142,195, 74, 87, 40, 20, 30,101,221,176,233,117, 56,254, 64, 8,193,254, -253,251, 43,125,127,244,218, 40,240, 75,135,103, 97,203,150, 45, 48, 26,141,160,148,146,154,234,243,171,121, 51,238, 78,159,187, -196,159,101, 89,116,235,214, 13,179,102,205,194,179,103,207, 48,100,200,144,138,104, 32,165, 20, 42,141, 6, 41,145,231,239, 58, -187,213,247,127, 91, 47, 14,148,210,147, 0, 78,190,190, 16, 92, 28,156,220,192, 80, 61,148, 25,217,120,175,111, 15,240,132,114, - 60, 79,202, 66, 11, 95, 47,231,225,239,118,112,230, 17, 3,230,172,220, 51, 25,192,207, 38,156,239,198,232,232,104,193,253,251, -247,193,227,241, 96, 97, 97, 1,169, 84, 90,113,142,191,104,184, 94, 39,114,229, 98,109,125,243,207, 69,139,100, 13,175, 95, 71, -195,131, 7,177,236,202, 21,168,122,247,198,190, 71, 79,212, 40, 41, 9,254, 86,173,142,249, 95,222,191,221,187,119,159, 0, 96, - 17,165, 52, 47, 40, 40,200,113,217,178,101,214, 41, 41, 41,136,138,138,194,254,253,251, 51, 13, 6,131, 1, 0,161,148,126,253, - 6,142, 37,246,197,200, 86,251,246,237, 51, 66, 67, 67, 29, 9, 33,197,229,145, 43, 66, 72,113, 29,162,110,130,130,188,212, 79, -173,101,116, 0,159, 49,175,111, 40, 40,122,158,107, 96,142, 90,216, 59,126, 31, 30, 30,174,175,238,187,150,150,150,159, 44, 91, - 50, 83, 97,103,199, 34,168,115, 87,164,166,235,176,124,230, 40,100,103, 23,226,231,237, 43, 0,136,160, 51,240,240, 78,208,251, -112,112,112, 65,167,142,157,156, 46, 95,187, 58, 5,192,183,111,203, 57,158,112,248,147,201,132,144,111,234,213,171,119,249,199, - 21, 43, 26,118,235, 86,122,207,112,225,194, 5,252, 50,108, 24, 22, 3, 35, 55, 18,146, 58,237, 45,157,216,244,143, 53, 88,245, -197,242,203,219, 62, 27,210,214,214, 88, 34,208, 94, 59,134, 20, 13,107,248,246,169,174,228,118, 30, 29,246,109,229, 39, 24, 37, -132,176,132, 16,214,211,211, 19, 22,122, 53,172,168, 22,142, 10, 5,204,109,108,145,163, 47,141, 92,137,100, 50,136,100,114,147, - 46,142, 47,106,250,250,250, 34, 61, 61, 29, 34,145, 8,114,185, 28,230,230,230,127, 49, 87,166, 94,112, 9, 33, 96, 89, 22,124, - 62, 31, 17, 17, 17,232,216,177, 35,220,220,220,176,127,255,126,244,236,217,243, 47, 93,134,166,154,182, 87, 27,243, 23, 35, 74, -229,131,223, 77, 25,220,254, 18,162, 6, 48,152,127, 0, 70,218, 13,122, 88, 66,205, 58,149,118, 7, 82,138,147,183,210,241, 56, - 33, 27,172,145,173,117, 23,161,179,179,115,128, 68, 34, 89, 61,111,222, 92, 69,139, 22, 45,144,153,153, 5,150,101, 33,151,203, -161, 82,169, 96,110,110,142, 14, 29, 58,164, 45, 94,188, 56,142, 82,244,166,148,166,253, 55, 14,224,179,103,207,190,212, 61, 88, -254, 40, 78, 77,198,152,105,187, 32,226, 3, 17, 17, 17,240,241,241,169, 57, 92,206, 82, 76,155,251,181,191, 90,163,133, 72, 36, - 66,251,246,237,209,182,109,219,138,113,113,229, 6, 85,167,211,193,104,100,225,228,219,213,159,188,133, 23, 5, 66, 72, 43, 0, - 31, 91, 90, 90,122,148,148,148,164,233,245,250,253,101,166,191,167, 64, 32,248, 64, 42,149, 58,229,231,231,199, 3,248,153, 82, -122,187, 38, 61, 51,137,196, 86, 44,177, 0,107,208,128,207,231,195,205,173, 62,168, 81,139,220, 2, 21, 70, 15,237,143,187, 17, -209, 56,125,233,134, 65,175,103, 55,154, 90, 70,111,111,111,100,103,103,131,199,227, 65, 42,149, 66, 38,147,161,113,227,198, 72, - 74, 74,170, 48, 87,117,237, 34, 44, 51, 87, 55,202,205, 21, 61,120, 16, 49, 50, 25, 60, 37, 18,124,249,235,175,197,185, 5, 5, -109,126, 1, 98,222,130, 93,253,245,169, 83,167, 28,248,124,190,147,209,104, 68, 98, 98, 34, 30, 62,124,136, 13, 27, 54,164, 23, - 22, 22, 6,133,135,135,215,105, 27, 69, 34, 81, 70,121,228, 74, 36, 18,101, 84, 23,217,122,157, 49, 87,174,174,174, 94, 46, 14, -226,115,191,109,152, 90,207,175,101,107,198,140, 39,207, 45,126,150,222,241,214,141, 27,237, 23,252,124,112,138,171,171,107,143, -228,228,228,103, 85, 54,126, 12,211,187,133,127, 75, 62,104, 26,248,162,142, 88,189,106, 40, 50,179, 10,144,155, 83, 8,161, 80, - 6,173,158, 7, 35, 75,208,190, 99, 39,252,186, 99, 31,154, 54,109,198,227, 1,221,223, 38,131, 85, 22, 1, 94,249,199, 31,127, - 52,148, 72, 36, 88,182,108, 25,204,205,205,113,227,155,111,240,139, 80, 8, 51, 0, 91,116,186,121, 0, 56,131,245,255,101,176, -100,142,141,135,237,253,168,123, 7, 95, 79, 23, 70,191,127, 3,146, 75, 12,234, 69,143,117,234, 71,133,244,221, 40, 74,175, 87, -231, 43, 8, 33, 84, 40, 20,194,113,238, 55,112,111,214, 28,197,227, 7, 33, 71,175,131,215,137, 27, 16,203,229,120,212,221, 31, - 84,171,197, 59,143, 50, 76, 53, 46,148, 16, 66, 1,192,222,222, 30, 66,161, 16, 18,137, 4, 98,177, 24, 98,177,184,194, 88,137, - 68, 34,136, 68, 34,147,205, 16,203,178, 40, 44, 44,196,243,231,207, 49,126,252,120, 72,165, 82,148,133,186,225,238,238, 14, 62, -159,143,148,148, 20, 92,188,120, 17,158,158,158, 16,137, 68,181,106,107, 95,104,176,253, 92, 92, 92, 46, 19, 66,252,238,220,185, - 99, 17, 24, 24, 8, 83, 35, 88,165,173,161, 16, 26,184,131, 37,110, 47,141,181,210,235, 13, 47,109, 75,121,244,197,196,200, 85, -247,134, 13, 27,110, 88,181,106, 21,227,234,234, 10,150,101, 97,109,109,141,146,146, 18,100,101,101,195,215,215, 23,110,110,110, - 88,181,106, 21, 0,236,253,111,153, 43,160,180, 59,184,220, 96,189,104,180,166,189, 91, 15, 57, 57,114,240,120, 76,133, 97,174, -113,159, 83,138,141,171, 22,221, 29, 62,126,150,255,140, 5,171,161,214,232,160,210,104,161,214,104,161,214,232,202,254,106, 81, - 62,176, 61, 45,234,226, 91, 23,193, 34,132,244, 11, 14, 14,222,180,118,237, 90, 39, 39, 39, 39, 65,102,102,166,225,135, 31,126, -232,249,195, 15, 63, 68, 77,153, 50,197,119,202,148, 41,214,246,246,246,252,180,180, 52,253,204,153, 51,123, 18, 66,230, 81, 74, -247, 86,123,189,144,153,219,240,132, 50, 16,194,135,149,165, 53,248, 34, 25, 88, 3, 31, 70, 22,176,176,180, 71,232,221,131,184, - 30, 89, 56, 33, 35, 27, 7, 76,185,169,106,214,172, 25,229,241,120,176,181,181,125,169,107, 16, 0, 28, 29, 29, 81, 80, 80, 0, - 30,143, 87,241, 90, 93,204,213,177, 69,139,228, 13,202,205,149, 84,138, 8, 79, 79, 44, 75, 72,200,203, 42, 40,232,248,150,152, -171,138, 27,135,184,184, 56,148,148,148, 32, 52, 52, 20,135, 14, 29,202,124,213, 92, 5, 7, 7,143,147,203,229,139, 85, 42,213, -234, 51,103,206,108,168, 73,183,108,204,213, 27,163,178, 84, 12, 1, 1, 1, 2, 39, 91,222,153,179,135,215,185,155,179,247, 8, -226, 63, 1,158, 20, 60,148,223,116,120,167, 91,171,190, 76,243,111,166,123,244,158,255,221,153,128,128,128,198, 85, 69,178, 40, -165,254,102, 50, 57,128,116,132,223, 9,169, 48, 87,217, 57,249,208,232,120,208,104, 9,212, 58, 6, 93,131,123, 97,211,143,191, - 35, 37, 61, 27,229, 51, 12,223, 38, 26, 53,106, 20,224,226,226,130, 25, 51,102, 64,189,103, 15,138, 0,244, 3,240,135, 78, 7, - 0, 48, 7,102,113, 86,233,255,201, 96, 89, 57, 53,238,188, 96,238,244,245, 29,223,239,197,164,143,107,135,188, 34,141,102, 78, -148,129, 77, 46,169,209, 92,129, 82, 74,125,124,124,192, 48, 12,228,150, 86, 48,179,176,128,250,133,200,149, 88,110, 14,170,213, -130,213,105, 33, 52,241,226, 88,174, 73, 41,133,153,153, 25,132, 66,225, 75, 93,131,229,198,170, 54, 17, 44, 0,200,203,203,195, -129, 3, 7,208,186,117,107, 72,165, 82,240,249,124,248,249,249, 33, 58, 58, 26, 94, 94, 94, 32,132,224,143, 63,254,192,192,129, - 3,241,236,217, 51,248,250,250,202,235, 98,176,206,157, 59,103, 65, 41,125,135, 82,138,172,172,172, 58,237, 68,150,101, 81, 84, - 84,132,179,103,207, 34, 53, 53, 21,142,142,142,200,205,147,194, 82,209,164,244,183, 94, 48, 89, 38, 50,185, 95,191,126, 12, 33, - 4, 42,149, 10, 98,177, 24, 50,153, 28,230,230, 22,240,246,110,140,148,148, 20,244,232,209,195, 24, 27, 27,187, 71, 40, 20,110, -172,109,121, 27, 52,104, 96,158,151,151,215,183,126,253,250, 66, 0, 48, 51, 51,235,231,225,225, 97, 25, 31, 31,159, 95, 75, 51, - 80, 97,172, 8, 33, 21, 51, 80, 25,134, 1,159, 97,224,236,228, 80,241,188,108,219, 73, 77,245, 56,108,220, 44,127,214,168,197, -206,181, 35, 65, 12,217, 48,192, 18, 26,184,192, 96,228, 85, 24, 88,153, 76,134,166,157, 63,120, 43, 35, 88, 66,161,112,212,246, -237,219, 93,126,251,237,183,188,163, 71,143,230,183,105,211, 70,182,126,253,122,135, 77,155, 54,117,209,106,181,152, 49, 99, 70, -198,205,155, 55,139, 7, 12, 24, 96,185,109,219, 54,151,134, 13, 27,190,139, 74,198,101, 17, 66,100, 0,134, 2,248, 40,168,181, - 37, 63,175, 80, 5,214,160, 69, 92,252,115,228, 23,105,193, 26,117, 72, 76, 86,162, 72,109, 68,118, 78, 33,252,252,123,124, 31, - 18, 18,242, 37, 33,100, 62,165,244,120, 77,229, 52, 26,141,184,113,227, 6,174, 95,191,142, 43, 87,174, 32, 33, 33,161,226, 61, - 11, 11, 11,156, 59,119, 14, 93,186,116,121,163,230, 42,241, 45, 50, 87,101,215,160, 69, 61,122,244, 88,100,107,107, 43,217,184, -113,163,165,187,187, 59, 12, 6,131,246,213,200, 85, 96, 96,224,130, 5, 11, 22, 56,191,247,222,123, 83, 1,108,168,235,239, 85, - 21,217, 50,129,191,164, 98,200,204, 76, 27,247,253,246, 81,118, 50, 97,130, 18, 79,190,115, 41,139,197, 0, 37, 5, 64,200,110, -144, 14, 11,159,143, 14,158,108,189,234,232,166,113, 0, 54, 87, 37, 28,251, 44, 9, 91,182,108,194,103, 51, 70,227,215,159, 87, -131,101,249,208,232,121,168, 87,191, 45, 52, 58, 22,132,225,163,133,127, 32, 46,133, 92,133,128, 1,166, 79,184,249,214,153,128, - 39, 79,158,220, 74, 72, 72,240, 89,184,112, 33,126,117,113,129,185,185, 57,102, 46, 90, 20,102, 48, 24,222,186, 25,178,255, 88, -131, 21,224,237,245,141,165,141,245,216,246,173,154,216,206,156, 58, 78,240, 44, 77,141,139, 29,191,200, 59,184,106,174, 60,137, -202,167, 36,208,188,235,181,137, 58, 24,150,204, 68,182, 81,139,250,199, 66, 33,150,203, 17,211, 51, 16, 84,171, 69,135,187, 9, - 16,203,229,224, 75,204,234,114, 2,191,212, 29,248,234,115,134, 49, 45,113,189, 78,167,179,234,222,189, 59,186,117,235,134,247, -223,127,191, 98,204, 85,203,150, 45,177,119,239, 94, 12, 26, 52, 8,247,238,221,131,179,179, 51,124,124,124,224,227,227,131,139, - 23, 47,214,250,238,209,104, 52,162,103,207,158, 5,132,144, 8, 74,169,223,173, 91,183, 44,106,171, 81,222,216,156, 61,123, 22, -125,251,246,133,151,151, 23,194,195,195,113,246,235,111, 33,181,169, 7,192, 10,172,209, 8,173, 86, 11,134, 97,106, 28,131, 21, - 20, 20,196,231,241,120,141, 27, 52,104,128,204,204, 76,100,102,102,194,222,222, 30, 10,133, 2, 14, 14, 14, 88,187,118, 45,214, -175, 95,127,139, 82,186, 50, 45, 45,237, 81,109,247,145, 66,161, 8,182,182,182,254, 86,165, 82, 9,203,203, 66, 8, 17, 56, 59, - 59,135, 41, 20,138,121, 74,165,242, 88,109, 12,150, 78,167, 3, 33, 4, 39,226, 20, 40,214, 18, 20, 36,135, 99,250,187,238, 47, - 25, 46,129, 64,240, 82, 90,141,170, 13, 22,197,158,237,223,221,157,247,197,199,254,200,217, 5, 67,246, 46, 16,235, 97, 56,244, -176, 23,126,191,105, 11, 0,240,118, 98,240,221, 88,249, 91, 27,193,210,233,116,219, 26, 53,106, 4,173, 86,123, 1,192,246,136, -136,136,129,169,169,169,235,254,252,243, 79,197,144, 33, 67,148,199,142, 29,251, 12,192,145,136,136,136, 49,203,150, 45,235,166, -215,235,183, 85,209,237,240,235,204,153, 51,131,134, 12, 25, 66,132,140, 94,123,246,204, 14,190,193,160, 39,179,231,255,100, 12, -185,118,153, 49, 24,244,228,253, 15,103,178, 39, 47, 70, 50, 19,166,173, 49,182,108,219, 23, 15, 30, 60,112,234,215,175,223, 82, - 0, 38, 25, 44,129, 64, 80, 97,160, 43,249,253, 90,117, 17,126, 12,120,185, 90, 91,223, 56,182,120,177,220,235,218,181,151,205, - 85, 98,226, 91,103,174, 0,224,194,133, 11, 91, 1,108, 13, 10, 10, 74,151,201,100, 40, 42, 42,250,203, 57,210,174, 93, 59,137, - 66,161,144, 8, 4, 2,180,110,221,218,166,103,207,158, 49, 12,195,108, 56,117,234, 84,173,147, 80, 86, 22,217,170,107,154, 6, -115,107,182, 95,203,182, 77,205, 31,155, 47, 54,151,240,213,247, 60, 98, 36, 22, 4, 64,190,198, 49, 46, 52, 97,104, 1,201, 16, -183,108, 22,236, 1, 41, 35,233, 87,149,193, 34,132,220, 45,200,203,239, 93, 80,168,197,181,235, 15,240,225,208,134,208,232, 8, - 88,150, 65, 81,177, 6,224, 9,192, 0, 24, 54,124, 20, 40,225, 35, 55, 43, 13, 4,136,124,219, 76,128,209,104,156, 55, 96,192, -128, 86,203,150, 45,107, 50,115,230,204,242,253,210, 78,161, 80, 68,113,121,176,254, 31, 12, 86, 35, 47,215, 94,157, 91, 5, 78, -251,114,254,151,230, 79,110, 93,193,151, 75,191,103, 27, 6,246,204, 95,185,231,143,194,124,121,189,110, 37,202, 71,247,106, 27, -117, 16, 24,244,160, 6, 29,196,114,249, 75,145, 43,145, 76, 6,129,153,180, 86, 27, 65, 8, 1,165,244, 47,221,129, 47,154,171, -218, 92,108, 69, 34, 81,222,213,171, 87, 29,146,147,147, 95, 26,208, 94,191,126,125, 16, 66,112,243,230, 77,220,184,113, 3, 31, -126,248, 33,248,124, 62, 4, 2, 1, 34, 34, 34, 10,235, 18,193, 42,159, 69,232,236,236,220,179, 77,155, 54,149,206, 30, 52, 37, -130,149,152,152, 8, 47, 47, 47,104, 52, 26, 88, 91, 91, 35, 39, 45, 14,207,158, 60, 66,137, 70, 15, 15, 7, 17,178,178,178, 80, -158,215,171, 58, 46, 95,190, 76, 21, 10,197, 75,145,159,204,204, 76,120,122,122, 98,203,150, 45, 88,191,126,253,230,212,212,212, - 90,223,197,186,184,184,216,176, 44,187,172, 95,191,126,253, 7, 14, 28,136,158, 61,123,190,244,254,174, 93,187, 44, 15, 31, 62, -252,163,155,155,219, 64, 30,143, 55, 47, 62, 62, 62,189,166,125, 14, 0,191,252, 82,154, 62, 73,218,118, 17,230, 13,241,192, 71, -147,119,224,187,239, 14, 67, 44, 22,191,212,216, 46, 89,178,164,230,122,164, 20,221,223,255,196,191,139,159, 22,198,236, 63, 96, -209, 62, 23, 5,161,214,200, 47,244,199,205,181,125, 0, 0,205, 63, 62, 14, 74, 61, 0,224,173,140, 96, 81, 74,207, 1, 56,247, -194, 75, 7, 9, 33,122, 66,200,112, 0,251, 40,165,135,203, 94,255, 9,213, 36, 6,109,219,182,109,203,249,243,231, 11,202,211, -102, 40,234, 45, 51,232,116, 58, 22, 0, 26,251,189,243, 82, 95,245,211,167, 79,241,221,119,223,161,184,184, 24,194, 90,132,153, -131,131,131, 43,198, 68, 10,133, 66,216,217,217, 65,167,211,193, 96, 48,212,122,252,149,157,171,235,247,119,174, 95, 55,138,126, -216,160,162, 7, 15,154,197,152,153,189,213,230,234, 21, 22,245,233,211,103, 17,165,148,178, 44,187,240,133,155, 45,177,181,181, -245,213,239,191,255,222,214, 96, 48, 96,214,172, 89, 86,217,217,217, 86, 19, 39, 78,156, 7,160, 74,131, 85, 69,154,134,170,142, -183, 58,165,105, 96, 89,120,203,229, 22,200, 70, 50, 52,118,250,150,121,182,134,156,115,169,227,238, 41, 18,252,125,101, 70,189, - 39, 83,160,133,165,196, 28,148, 82,239,170,126,219,192,178,167, 30, 69, 69,245,168,231,214,144,247,231,241, 43, 24, 48,112, 8, - 52, 26, 6,106, 61, 1,225, 9, 64,120, 66, 52,247,243,135, 79, 83, 63, 80, 0, 49, 15, 35, 12,198,151,207,141,255,121,220, 7, -253,180,217,181,255, 15,147, 0, 96,214,134, 11,248,242,155,117, 24,241,126, 79,140, 25, 51,134,203,131,245,255, 97,176,234,213, -171,103,229, 32,151,254, 50,229,227,177,230, 9,247,195,144, 28, 17,134,235,215, 98,114,119, 31, 58,154, 82,144,159,249,113,109, -204,213,139, 17, 44,175, 93, 39,224,226,236, 92, 17,185,106, 31, 30, 15,177, 92,142,144,230, 46, 96, 53, 26,244,120, 94, 80,235, -141,169, 44,106, 37, 20, 10,235, 52,211,175,220, 84,189, 58,160,125,194,132, 9,216,190,125, 59, 58,116,232,128, 70,141, 26,213, -250, 78,249, 69, 83,244,226,152,168,218,204, 30,172, 76,171, 94,189,122,136,140,140,132,165,165, 37,118,238,220, 9, 87, 87, 23, -140,233,229, 5, 30,175,180,107,139, 97, 24,147,198, 96, 81, 74,141, 46, 46, 46,113,103,207,158,245, 28, 50,100, 8,132, 66, 33, -114,115,115, 97, 97, 97,129, 77,155, 54,177, 82,169,244,215,218,150,207,205,205,109,140, 68, 34,249,122,232,208,161,252,198,141, - 27, 35, 61, 61, 29,150,150,150,108,217,210, 70,176,177,177,102,165, 82, 41, 38, 76,152, 0, 63, 63,191,238,115,231,206,237,166, - 80, 40, 86, 40,149,202, 31,106, 50, 89,123,247,150,246, 78,125,188,225, 17,180,218,210,161, 22,155, 55,111,134,179,179,243,203, - 93, 1,177,177, 53,207, 34,100, 89,156, 59,244,211,221,201, 83,135,250, 19,235, 97, 40, 8,181, 6,181,252, 16,233, 69,230,216, -117, 57, 3,151,239, 38, 84, 36, 26,125,219, 34, 88,132,144, 1, 40, 29,122,113,146, 82,122,132, 16, 50, 24, 64,207,242,231,168, -101, 98, 81,131,193, 64, 25,134, 33, 73, 73, 73, 58,169, 84, 74,108,108,108,248, 98,177, 24, 26,141,166,194,104, 61,125,250, 20, -199,143, 31, 71,114,114, 50,108,108,108, 24, 75, 75, 75,232,116,186, 92, 19,239,186,255,146,158,161,236,119,107,125, 62,142, 6, -154,109, 94, 60,223, 67,197,207,181,204, 26,211, 21,236,189,235,170,200, 76,141,217,191,196, 92, 33, 36, 36,100, 43,128,173,229, -207,187,118,237, 58,134,207,231,127, 9,192,114,219,182,109, 86, 86, 86, 86,228,216,177, 99,250,109,219,182,229,241,120,188, 92, - 0,235,170,211,171,108, 48,251,235, 80, 89, 42, 6, 74, 17,149,147, 31,231, 46,176, 82,176,247,213, 52,116, 70,210, 60,159, 92, - 65, 67,123,210,180, 25, 6,102, 68, 95, 27, 99,136,109,159,153,150,193, 80,208,168,170,116,243,243,243,127,250,117,199,129,217, -251,247,253, 82, 79, 44, 23, 99,194,196,249, 56,113,250, 18, 8, 35,192,213,208,155,208,234,140,200,202,201,199,208, 97, 35,224, -234,108, 7, 20,165,100, 10, 68,162, 31,222,166,125,255, 82, 30,172,192,246,184,126,120, 13,246,198,212, 67,202, 55,223,112,121, -176,254, 78,131,229,225,225, 33,150, 9, 48,222,198, 76, 56,103,202,240,247,236, 51, 98, 31, 34, 57,250, 46, 0, 64,163, 81,233, - 83, 99, 46,183, 48,225,162, 29,252,106,174,140,242,174, 27, 27,123,135,138,200,213,139,179, 7, 89,141, 6,172, 78, 11, 84,209, -157, 83,149, 38,195, 48,127, 49, 86, 47, 94,120,107, 83,206,242,232, 72,101, 9, 70,221,220,220,176, 98,197,138,191,228,193, 50, -165,156,101,119,105, 61, 9, 33,126,229,198,136, 82,234,231,236,236,220,211,148,153,131, 85,105,150,103,172, 62,117,234, 20,162, -162,162, 64, 41, 69,191,126,253, 32, 16, 8, 96,110,110, 94, 97,178, 42, 27,131, 85,153, 38,195, 48,159, 28, 62,124,120,118, 88, - 88, 88,175, 89,179,102,145,242,177, 44, 69, 69, 69,108,106,106,106, 97,109,203,201,178,236,156, 51,103,206,240,141, 70, 35,182, -111,223,142,219,183,111, 83,169, 84,186, 82, 32, 16,172,144, 74,165, 6,189, 94,255,249,184,113,227, 38, 46, 94,188,152,233,212, -169, 19,194,194,194, 24, 79, 79,207,169, 0,126,168,105,219,111,222,188, 89,218,229,156,147,136,201,243,246, 65,102,198,199,163, - 71,143,144,147,147,243,151,228,163, 53,151,147,194,191,203, 16,127,150,234,160,147, 15, 1, 99,214,181,116,169,156,231, 26,180, -242, 43,141, 58,170, 10, 50, 43,234,177,178, 8, 86, 85,229,124, 77,243,243,183,106, 18, 66,250, 55,105,210,228,139,168,168, 40, -215,230,205,155,251, 18, 66,130,154, 53,107,214, 42, 50, 50,178,252,185,128, 82,186,191, 54,154,183,111,223, 62,184,105,211,166, -137,163, 71,143, 22,178, 44,107, 76, 72, 72,208, 3, 32, 78, 78, 78,188,219,183,111,179,127,254,249, 39, 84, 42, 21, 92, 93, 93, - 25, 23, 23, 23,114,238,220, 57, 54, 58, 58,250, 38,165,116,190,169,219, 94, 30,153, 22, 8, 4,224,241,120, 80,169, 84, 38,153, -171, 87, 53,221, 27,121, 45,239,220,222,195, 45, 75, 25,129,132,132,120, 36, 6, 54,212,111,222,124,188, 86,230,234,127,113,191, - 87,115,115,185,228,208,161, 67, 46, 26,141, 6, 66,161, 16, 7, 14, 28,208,237,216,177, 35, 42, 63, 63,191, 99,120,120,184,170, -174,229,172, 77, 2,210,154, 52,139,242,120, 39, 78,159,121,208,138,215,235, 39, 76, 86,102,118,172, 48, 94,132,216, 28,118,244, -237, 40,109,221, 60,197,252,202, 26,166, 4,234, 19, 85,105,198,198,198,106, 3, 3, 3,135,204,157,179,232,194,215, 75,191,150, - 47, 92,180, 8,215,111, 70, 34, 59,175, 8, 44,229,129, 37, 4, 95,126,185, 16, 78,118, 54,176, 17,233, 75,178,139,201,192, 87, -151,204,249, 95,223,239,175,147, 7,235,239, 40,231,191,198, 96,153,243,241,160,163,175,151, 75, 39,255,166, 18,190, 81,133,228, -232, 88,228, 20,171,113,238, 97, 66, 30, 67,153, 95, 95,231, 71,121, 60, 30, 44, 45, 45, 33, 20, 10,209, 46, 50, 5, 34,161, 16, - 98,185, 57, 0,148, 70,174, 40, 5, 35, 18,215,246, 0,170,212, 96,213, 21,163,209, 8, 71, 71,199,151,150, 93,121,177,193, 46, - 55,138,181, 77,209,192, 48,204,188,176,176, 48,139,196,196, 68, 80, 74,113,228,200, 17,139, 65,131, 6,205,171, 75,244,138, 82, -138,236,236,108,176, 44, 11,177, 88,140, 94,189,122,161, 83,167, 78,208,149,205,254, 40,111,128,106,155,201, 61, 41, 41, 41, 21, -192,103,174,174,174,191,206,158, 61,123, 78,155, 54,109, 2, 23, 47, 94, 12, 82,139,133,113, 95, 65,103, 52, 26,113,249,242,101, - 28, 62,124,216,160, 86,171, 7,165,165,165,221,121,225,253,165,174,174,174,127, 14, 26, 52,232,228,227,199,143,249, 81, 81, 81, - 0, 96,168, 73, 84,165, 82,161, 81,163, 70, 48, 24, 12, 88, 53,217, 13,133,133,205, 97, 48, 24, 96, 52, 26, 33,147,201, 94,202, -251,101,202,126, 98, 41,139,187,151, 14,220,117,111,217,211,191,166,165,114,222,178, 8, 86,175,168,168, 40,215,225,195,135,103, - 68, 70, 70,186, 30, 63,126,220,170, 95,191,126,178, 97,195,134,101, 68, 70, 70,186, 18, 66,222, 1,176,191,150,231,207, 23,132, -144,211,203,151, 47,159, 55,109,218,180, 54,163, 71,143, 22, 8, 4, 2, 54, 37, 37,197,176,103,207, 30,210,168, 81, 35, 70, 40, - 20,146, 51,103,206,176,183,110,221,186, 97, 48, 24, 86, 81, 74,175,214,246, 58, 82,110,174,234, 26, 73, 94, 7,140,106,156,152, -220,113,255,146, 53,140,160,137,179,238,216,169,155, 73,119,239, 60,127, 6,157,113,198, 47,192,179,127,105,187,176,127,200,144, - 33, 99, 6, 13, 26,100,214,186,117,107,241, 79, 63,253,148, 95, 82, 82, 82,169,185,170,140,218,164,105,168,109, 2,210,114,148, - 74,229,207, 43,150, 92,153,241,145,207, 48,175, 79,236, 60,112,190, 56, 3,185,124, 30, 99, 97,197,192,223,157, 7, 85,222,115, -251, 11, 55, 15, 61, 79, 85, 42,171,205,171,118,231,206,157,219, 1, 1, 1,193, 31,125, 52,230,208,132,143,199, 57, 44,252, 98, -174,224,224,159, 39, 1,131, 14,183,174, 94,133,149,148, 80, 67,113,106,122,182,150,188,247, 54, 46,149,147,112,248,147,201, 0, - 38, 19, 66, 62, 92,180,104,209,158,201,147, 39,131,101, 89,132,132,132,224,135,185,115,177,216,104, 28,185,145,144,146,105,148, - 78,230,236,210, 27, 52, 88, 96, 72,225,141, 39, 9, 69, 55,159, 36, 20,129,165,148,165, 84,195, 48, 72, 42,214,233,150,199, 60, - 75, 62,243, 58,251,180, 87,175, 94,204,171,198,165,138,110, 6, 83, 7,215, 37, 4, 7, 7,191, 49, 77,150,101,147, 59,118,236, -248,151,134,185,170,255,203,116,147, 77, 10,201,178,236,202,118,237,218,253,229,181, 58,133,119, 89, 54,174, 91,183,110,186, 87, - 77, 87,117,207,141, 70, 99,178,169,250,201,201,201, 15, 0,140,112,113,113,233,210,179,103,207,169, 0,234,154,142, 97,109,151, - 46, 93,102, 82, 74,249,132,144, 53,175,152,171,242,223,122,232,226,226,178,208,211,211,179, 98, 1,232,154,182, 61, 56, 56, 88, - 87,211, 34,207, 47, 14,128,102, 89, 54,185,122, 77,138,122, 45,122,248,235,244,165, 38,173,186,165,114,170,138, 96,253,143,178, -143, 16, 34, 0,144, 27, 21, 21,245, 78, 89,228, 42,249,193,131, 7,231,247,238,221,235, 8,212,156, 62,161,138, 27,128,171, 0, -174, 18, 66, 58,109,222,188,249,139, 9, 19, 38,180,254,240,195, 15,249, 65, 65, 65, 56,113,226,132, 49, 36, 36,228,166, 74,165, - 90, 89, 91, 99, 69, 8, 41,122,245, 28,170,166, 12,213, 46,210,235,205, 48,155, 86, 8,132,146,113, 7, 46, 23, 93, 22,146, 80, -163,202, 48,255, 55,224,193,191,185, 81, 56,119,238,220,231,237,218,181, 91,120,224,192, 1,165,151,151,151, 88, 32, 16,104, 77, - 53, 87, 64,237,210, 52, 80, 74,217, 58, 30, 91, 6, 71, 71,199, 62,187,134, 79, 62,218, 98,202,232,250,189, 58, 4, 74, 93, 60, - 28, 92, 30, 63,207, 66,114,228,249,226,103, 33,155,226,141,234,156, 1,148,210, 26,111,212,194,195,195,111,181,107,215,174,225, -230,109, 63, 78,230, 49, 76, 15,131,209,232, 55,115,242, 8, 74,128, 72, 22, 56, 39, 20,139,222,250,197,158,197, 66,225,200, 41, - 83,166,224,247,223,127,199,145,245,235,209, 51, 57, 25,123,133, 66,152, 9,133,216,162,211, 77, 2,192, 25,172, 55,105,176, 34, -159, 60, 15,248, 59,126, 48, 42, 42,170,221, 63, 93, 51, 42, 42, 42,240,239,170,240,215, 25,107, 85, 73, 57,255, 95,166,209,166, -164,164, 92, 2,112,233, 53,190,191, 3, 38, 44,230,108,234,231, 0,224,209,163, 71,111,124,219,169,216,114, 72,226,253,179,121, - 78, 77,186, 90, 25, 12, 6, 16, 66,160, 86,171,113,227,198, 13,104, 74, 10, 17,178,123,124, 69, 38,119, 80, 32, 45,250, 98,158, - 83,253,102, 86,255,235, 23, 1, 74,233, 21, 0, 87,202,204,203, 64, 66, 72, 31, 0,103, 40,165, 7,223,144,126,133,209,218,182, -109,219, 12, 74, 41, 10, 10, 10,214,215,214, 88, 85, 92,155, 34, 35, 47,190,169,109,143,103,217,139, 11, 75, 74,186,102,179,236, -140,159, 13,181, 91,112,252,109, 38, 44, 44, 76,221,173, 91,183, 95,151, 45, 91,214,150,101,217,223,222,132,230,107,164,105,168, -148,244,244,244,231,132,144, 22,236, 55, 27,198,134, 91,153,247,165,122,166, 49,209,243,143, 17,109,246,137,180,180,180, 95, 40, -165,198,218,108,111,217, 77,221,119,255,198,253,125, 63, 50,178, 39, 0,244,238,221, 27,170, 89,165,105,175,118,252, 39, 15,214, - 22,238,140,120,211, 17, 44, 14,142,127, 25, 41, 49,225, 7, 1, 32, 45,186,180,253,254,254,251,239, 1, 0, 61,123,246,252,203, -172,199,242,207,164, 61,127,187,130, 29,101, 3,218,143,252, 77,218, 87, 1, 92,253, 39,109,111, 8,165,253,184, 35,191,114, 46, - 92,184,240, 70, 19, 76,190,233, 4,164,101,199,148, 17,192,246,178, 7, 71, 29,241,246,246, 38, 0, 96,103,103,135, 5,181, 88, - 78,141,163,122, 24,174, 10, 56, 56, 56, 56, 56, 56, 56, 56,222, 44, 4, 64,112, 21,119, 6, 38,207, 14, 32,132, 4,215,225,206, -227, 60,167,201,105,114,154,156, 38,167,201,105,114,154,255, 46,205,154,180,223,154,217,137,229, 25,174,255,142, 7,128, 96, 78, -147,211,228, 52, 57, 77, 78,147,211,228, 52, 57,205,127,219,163,154, 49, 88, 7,121, 41, 41,176, 16,137,164, 66, 0,208,106, 75, -116, 46, 46, 40, 0, 6, 27,193,193, 81,155, 48, 41, 33,142,101,102, 62,253, 77,126,150,131,131,131,131,131,227,159, 10,191, 42, -115,149,149, 37,181,227,243,115,189,141, 70,181, 15, 0,240,249,204,163,172, 44,235, 24, 59,187,131, 89,111,218,100,245,238,221, -123, 62,165,212, 81, 32, 16,156,112,114,114, 10,217,186,117,171,254,223,108, 52, 94,199,100,252,127, 24, 20, 91, 91, 91,133,163, -163,227,112, 43, 43,171,160,252,252,252,171,105,105,105, 59,179,179,179,149, 85,148,103, 5, 33,152, 83,246,255,106, 74,233, 23, -213,148,221,228,207,190,138, 66,161,104, 36,145, 72, 38, 51, 12,211, 12, 0, 88,150,125,160, 86,171, 55, 43,149,202, 39,255,182, -147, 90,161, 80,152, 81, 74,223, 19, 8, 4,163,108,108,108, 90,103,102,102, 46, 78, 73, 73, 89, 87,199, 99,150, 15, 96,150,149, -149,213,135, 86, 86, 86,158, 57, 57, 57,207, 10, 10, 10,246, 3,248,142, 82, 90,227,121,250,245,116, 69,187,160,158, 65, 11, 66, -206,132, 44, 93,180, 65, 25,246,151,247, 63, 87,216,246,232,222, 97, 97,200,177,208, 37, 95,108, 74,201,169,101,217, 24,252,103, - 28, 41, 91,122,216,255,115, 71,232, 58, 56, 56,180, 45, 75,164,202, 48, 12,243, 93,122,122,250,165,127,242,113,100,111,111, 47, -115,114,114, 90, 69, 8,233,207,227,241,162,210,211,211,199, 43,149,202,228, 55,116, 45,100,220,221,221,205, 19, 18, 18, 10,235, -154,170,225,223, 72,187,118,237,210,117, 58, 93,181,217,241,133, 66, 97, 70, 88, 88,152, 35, 87, 91,255, 80,131,149,146, 2, 11, - 62, 63,215, 59, 35, 45,114,168, 50, 53,226, 3, 0, 80, 56,251,237,119,112,106,190, 47, 37, 69,164,107,213,125,144, 92, 32,229, -111,230,241, 4, 45,213, 90,141,157,128, 47,200,210, 25,244,247, 24, 45,157,156,250,232,112,162, 41, 63,220,191,127,127,111, 0, -150,254,254,254,183,181, 90,109,235,117,235,214, 57, 31, 58,116,200, 47, 60, 60,124,216,187,239,190,123,140, 82,122,230,216,177, - 99,170, 90,157,180, 65, 65,124,135, 60,155,145, 60, 62,191, 63, 0, 63, 74, 1, 16, 94, 4,171,211,158,204, 16,218,252, 70,195, -235,110,220,218, 53,178,245, 38, 84, 55, 91, 64,104, 39, 61, 37, 87, 41, 17,174, 9,123,146, 29, 83,139, 11,138, 73,230,225,117, - 76,198, 43,223, 93, 79, 41,157,245,166, 15, 24, 39, 39, 39,187,193,131, 7,239, 90,186,116,169,204,220,220,156,196,199,199, 15, -252,226,139, 47,122, 42, 20,138,143,148, 74,101,210,171,102,143, 16,204, 97, 89,202, 0, 0,195,144,185,142,142,142,205,248,124, -190,230, 85, 93,131,193, 32, 38, 4,189, 88,182,116, 57, 27,134, 33,115, 8, 33, 27, 76, 49,138,158,158,158,195,154,251,181,156, -249,197,252,133,114,123, 7, 7,153,193, 96,212, 37,165, 36, 75,215,172,248,166,141,167,167,231,134,184,184,184, 61,181,221, 78, - 66, 8,113,117,117, 29, 42, 16, 8,250, 1,104, 82,246,114,180, 94,175, 63,158,156,156,188,207,212,134,188, 69,139, 22, 87, 24, -134,241,168,205,111, 27,141,198,196,136,136,136,142,117,217, 63, 46, 46, 46, 67, 92, 92, 92,126,105,219,182,173,180,101,203,150, - 16, 10,133, 88,189,122,245, 44,212,176,188, 73,185,145,146, 74,165, 67,101, 50,153, 87, 81, 81, 81,172, 74,165, 58, 36, 18,137, -130, 55,108,216,224,214,161, 67, 7,243,244,244,116,194,227,241, 28,143, 31, 63, 62,114,227,198,141, 61, 9, 33,221,106,202, 51, -148, 31, 75, 23,136,251, 55,233,148, 31,123,105, 1,128,222,127,217,239,106,201, 40,202,115,235,167,162,119,147, 80,139, 41,242, -132, 16,198,213,213,117,131,163,163,227, 24,149, 74,165, 38,132, 80, 66, 8,109,222,188,121,249,251, 0, 0,173, 86,155,251,248, -241,227,198,213,105,213,111,103,115,135,199,240, 92,171,220, 31,172, 49,249,121, 88,206,107,167,110, 49, 26,141,115,162,162,162, -250, 8, 4, 2,210,162, 69, 11, 30,106,145,250, 68,161, 80,120, 19, 66,190,164,148,222, 78, 77, 77,221, 92,182,164, 85, 23, 74, -105,197,181,162, 44,157, 10, 92, 92, 92, 54, 55,108,216,240,221,167, 79,159,110, 73, 73, 73, 89,250, 26, 70,125,235,242,229,203, - 63,232,217,179, 39, 47, 59, 59,219,165, 71,143, 30,187, 1,116,122,157, 58, 8, 8, 8, 16,164,165,165,205,106,209,162,197,167, -173, 90,181,114,126,248,240, 97,154, 66,161,216,232,228,228,244, 93,120,120,120,141,215,103, 63, 63, 63, 5,159,207, 31, 3, 96, - 36, 0, 30,165,116, 47,128,223,238,222,189,251,175, 72, 10,171,211,233, 28,206, 47, 93, 8,194,231, 67,210,177, 27, 88,150, 69, -214,154, 69, 48,228,100,193,110,233, 70, 24, 12, 6, 4, 7, 7, 59,128,227,159,107,176, 68, 34,169,208,104, 84,251, 40, 83, 35, - 62,120,167,243,247,150, 0,112,229,242,167, 31, 56, 56, 53,125, 32, 18, 73, 99,196, 22,146,195,131,250, 7,183, 28,220,175, 51, -113,117,118, 64,114,106,134,227,207,123,207,244, 58,126,230,210, 97, 0, 38,229,207, 42, 40, 40, 88,230,238,238,110,127,225,194, -133,120,145, 72,100, 38,145, 72,200,144, 33, 67,204,134, 13, 27,230,123,241,226, 69,175,211,167, 79, 15, 30, 48, 96,192,105,161, - 80,120,226,192,129, 3, 53,174, 79,230,216,124,160,175, 19,223,233,224,128,247,122,123,244,237,238, 32,114,119,178, 7,101, 37, -120, 20,167,171,119,238,234,221, 94, 39, 78,157,153,227,224, 59,240,253,140,168, 35, 38,175,134,222,172,153,165,149,153,138,206, - 52, 19,210, 15,123,181,241,173,223,191,123,123,226,233,233,137,152,199, 49, 94,151,174,223, 30,211,197,199,252,185, 74, 71,246, -170,204,200,218, 7, 15,242,243,170,139, 42,189,104, 52,120, 60,102, 94,247,238,221,199,136,197,226,151,238,220, 52, 26, 13,195, - 48,196,193,104, 44,125,185, 54, 38,163,252, 55,180, 90, 13, 35, 16,136,192,227, 49, 51, 91,182,108,217, 59, 61, 61,253,148, 88, - 44, 94,253,252,249,243, 90,229,157,153, 70,136, 40,151,207, 15, 96,196, 98,103,163, 86,107, 11, 0, 68, 36,202,173,103,107,219, -246,171,175,190,146,243,120, 60,100,103,103, 67,173, 86,147, 79, 62,249,196, 44, 54, 54,118, 52,128, 37, 53,153,150, 29, 59,118, -248,219,218,218,254,229,142, 53, 59, 59,155,233,221,187, 87,173,243,118, 42, 20, 10,239, 22,254,129,159,237,217,189,171, 73, 65, - 78,174,122,251,186,173,225,122,137, 84,227,217,164,177,224,155, 21,107, 45, 23,204,157,249,169, 66,161,184,167, 84, 42, 77, 54, -195,206,206,206,245, 60, 60, 60, 14,207,159, 63,191, 89,199,142, 29, 5, 14, 14, 14, 72, 79, 79,199,227,199,143,155, 93,191,126, -253,189, 63,254,248, 99,150,179,179,243,160,212,212,212, 26,111, 38, 40,165,141,142,174, 89,225, 32,182,177, 5,171,215,195,198, -207,191, 34,249,107,234,165,179, 48,234,116, 96,245,122,184,245,125, 15,101,145, 55,116,237,218,181, 78, 25,243, 93, 93, 93, 21, -222,222,222,191,207,155, 55, 79,168,213,106,113,247,238, 93,132,133,133,177, 25, 25, 25, 43,107, 50, 87,132,144,179,139, 22, 45, -114,237,216,177,163,121, 86, 86, 22,140, 70,163,221, 31,127,252, 49,217,223,223,223,194,205,205, 77,180,115,231, 78, 20, 21, 21, -193, 96, 48,216,120,121,121,217, 12, 27, 54, 76,187,115,231,206, 89, 0, 86, 85, 21,185, 42,136,165, 11,210,136, 87,175,198, 1, -163,144, 70, 78,247,154,217,219,249,148, 69, 3, 82, 17,201,234,221,160,129,185,151,143,108,174,220,162,185, 77, 65,202,249,185, -189, 27, 52,216,126, 42, 54,214,148,165,152, 24, 23, 23,151, 13,125,250,244, 25,190,101,203, 22,105,116,116,180,180, 73,147, 38, - 96, 89,182, 34,147,127,249,202, 5,157, 58,213,236, 7,120, 12,207,245,250,225,135, 14,102,102,102, 21,107,132,150,255, 45, 46, - 46, 70,207, 81,109,255,142,235,109,109,247,241,215,161,161,161, 67, 78,157, 58, 53, 98,233,210,165,141, 0, 76,101, 89,118, 97, -116,116,116,103, 0,104,210,164,137, 8,192, 37,133, 66, 49,118,210,164, 73,147,166, 78,157,138,145, 35, 71, 46, 36,132, 44,171, - 75, 84,143, 16,194,107,218,180,105,159,158, 61,123,242,244,122, 61,204,204,204,160,211,233, 26,188,206,198,251,250,250, 10, 75, - 74, 74, 14, 45, 89,178,164,223,128, 1, 3,192,231,243,193,178,172,211,149, 43, 87, 86,204,154, 53,171,125, 64, 64,192,192,170, - 76, 86, 64, 64, 64, 75, 0, 75, 26, 54,108,216,115,212,168, 81,188, 14, 29, 58,160,168,168, 8,103,207,158,253,242,240,225,195, - 95, 6, 4, 4,132, 2, 88, 24, 30, 30, 30,242,182, 55,218, 60,185, 57, 30, 15,234, 2,175,232,108, 0, 64,218,230, 53, 0, 0, -139,175,190,229, 28,205,255,130,193,170,137,146,146, 18,255, 47,166,141, 4,195,148,182,135, 13, 61,235, 97,197,252,241,228,232, -241, 51,254, 53,132, 55,215, 26,141,198, 70, 54, 54, 54,179,213,106,181,100,253,250,245, 18,165, 82,233,115,240,224, 65,122,255, -254,125, 8,133, 66, 88, 90, 90,162, 91,183,110,226, 94,189,122, 53, 8, 13, 13,173,119,248,240,225, 1,125,251,246,253,237,196, -137, 19,199,170, 51, 87,118,246,246,151,191, 93, 58,206,166,153,167, 23,116,122, 61,146, 50, 82, 64,137, 8,206, 14, 50,124, 52, -176,165,176, 99,160,200,235,219, 31,206,135, 56, 54, 27,240, 78,250,131,163, 15,107,218,198, 78, 13,101,183, 6, 6, 52, 8,232, - 31,220,158,105,212,216, 23, 66,137,180,226,189,230, 45,253,209,188,165, 63, 25, 63,166,208,243,254,253,251, 11, 78, 95,190, 57, -191, 83, 67, 89,248,213,167,197,213, 45,140,249,146,121,152, 53,107, 22,108,109,109, 95, 53, 25,184,120,241, 66,149,223, 49,229, -186,248,226,147, 21, 43, 86, 88,101,100,100,124,248,243,207, 63,191,231,228,228, 52, 37, 45, 45,237,180, 41, 34, 35, 9,241,128, - 88,220,109,204,119,223,177, 45,223,125,151,103,229,228,196,176, 70, 35, 73,142,141,181,251,110,253,250,224,194,164, 36,169,202, -220,188, 40, 51, 63, 95, 27, 19, 19, 3, 51, 51, 51,194,227,241, 58, 84, 98, 46,210, 9, 33,171, 25,134,204, 37,132, 16,137,196, - 44,247,227,143, 63, 14, 45,123,175,201,177, 99,199,204,251,247,239, 95, 72, 8,137, 6, 0,137,196,172, 51,143,199, 88,211,210, -142,158,213,166, 24, 75,169, 84, 58,109,214,231,243,100, 5, 57,121, 42, 93,113,177,222,222, 66, 78,136,220,156, 87,144, 95, 88, -152,146,154,169,153,244,233, 12,222,130,121, 51,167,193,196, 76,196,206,206,206,245,124,124,124,110,109,223,190,221,193,214,214, - 22,121,121,121,200,206,206,198,173, 91,183,192,178, 44,122,247,238, 45,246,247,243,243,255,110,237,218, 48,103,103,231,118,166, -152, 44,137,173, 29, 14,190,211, 18, 0, 48,228, 89,118, 69,132,229,212,208,255,164, 96, 26,150,144, 95,250, 89,137,164,214,203, - 47,189, 80,223,237, 58,116,232, 32, 4,128,153, 51,103, 22, 20, 23, 23,175, 32,132,236, 86, 42,149, 41, 53,124,117,214,130, 5, - 11, 92, 60, 61, 61,221,119,239,222,141,162,162, 34, 0,112,240,244,244, 68,227,198,141,141, 33, 33, 33,240,246,246,134,185,185, - 57,174, 92,185,130, 27, 55,110, 32, 32, 32,192, 92, 40, 20,126, 80,149,193, 10,234, 25,180, 64,220,191, 73,167,198, 1,163, 32, -183,112,198,246, 61,251,240, 56,124, 71, 39,141, 46,122,193,138,169, 46, 31,169,168,120,180,107, 35,243,121, 30,129,157,109, 27, - 54,125, 23,238, 1,119,237,212,198,171,113, 11,167,120,173,228, 75,212, 59, 22,125,171,204,174,202, 92, 57, 57, 57,173,233,221, -187,247,144, 45, 91,182, 88, 1, 64,100,100, 36,210,211,211, 97,111,111, 15,137, 68, 2,129, 64, 80,177,126,168,169,152,153,153, - 33, 53, 53,181, 98,153, 41,163,209,136,194,194, 66, 56, 57, 57,149,186,155,175, 9,179,104,145,105, 93, 89,206,206,206, 29,253, -253,253,119,185,186,186,186,189,248,122,207,158, 61, 49,126,252,120, 80, 74,209,161, 67,135,110,227,199,143,167,148, 82,176, 44, -139,244,244,244,162,200,200,200,238, 41, 41, 41, 55,171,216,110, 85, 90, 90, 26, 38, 77,154,132,196,196,196, 41, 10,133, 34,129, - 97, 24, 73,249,114, 96,132, 16,145, 66,161,240,246,246,246,222, 48,126,252,120,196,199,199, 35, 38, 38,230, 86, 93,187, 76, 41, -165,198,182,109,219, 62,213,235,245,129, 6,131, 1, 42,149, 10,189,122,245,146,248,248,248,164, 11, 4,130, 71,121,121,121, 35, -202,150,212, 50,197,172,241,157,157,157,157, 4, 2,193,150,113,227,198,245,105,223,190, 61, 30, 61,122,132, 83,167, 78, 97,192, -128, 1, 8, 10, 10,194,130, 5, 11,250, 46, 88,176, 96, 22,128,170,110, 6, 14, 30, 58,116,168,190,171,171,107,197,146, 72, 22, - 22, 22,248,248,227,143, 49,114,228, 72,156, 60,121,178,253,242,229,203, 15, 5, 5, 5, 57,132,132,132, 24,222,230, 70, 91, 28, -216, 30, 94,209,217,120,214,164,180,253, 40, 55, 90,229,207,225,226, 15,142,127,176,193,210,106, 75,116,124, 62,243, 72,225,236, -183,255,202,229, 79, 43,186, 8, 1,230,145, 86, 91,162, 43, 13,155, 83, 20,148, 24, 96, 38,102, 16,159, 86,136,135,207,178, 42, - 59, 73,207,191, 98,204, 62,219,184,113, 35, 86,175, 94,221, 91,165, 82, 21,197,197,197,165, 22, 21, 21, 21,127,244,209, 71,132, -207,231,227,250,245,235,120,254,252, 57,154, 55,111, 14,107,107,107,116,236,216, 81,216,163, 71, 15,183,177, 99,199,126, 4,224, - 88,101,154, 36, 40,136,239, 44,182, 63,188,102,233, 80, 27, 48, 49,136, 73,204, 67, 3,215,214,176,179,114, 67, 74,102, 17,110, - 71,157,196,147,216, 19,104,224,226,142,241,195, 27, 90,173,219,122,253, 56, 9,152,208,224,197,238,194,202,166,132, 74,120,198, - 86,139,247,220,135, 49, 39, 22, 52, 63, 17,180,248,175,171,196, 72,237,220,224,211,206, 17, 82, 43,123, 38,242,209,186, 86, 85, -109, 59,165, 52,157,207,231,111,227,241,152, 9, 0,208,170, 85,235,226, 85,171, 86, 85,118,177,102, 91,181,106, 93,204,227, 49, -178,210, 8, 22,111,171,193, 96, 72,175,174,156,175,152,153, 53, 34,145,120, 54, 0,226,234,234, 86,116,244,232, 81,246,253,247, -223,199,154, 53,107,196,243,230,205,251,193,195,195,163, 75,124,124,124, 66,117,251,104, 16, 33,245, 92, 26, 52,232,177,236,250, -117, 42,208,235, 73,206,173, 91, 5,133,233,233,250,148,194, 66,201,111,119,239, 14,158, 50,103,142,196,201,203, 11,161,231,207, -155,167,229,230, 22,230,149,148,104,227,226,226,168,209,104,188, 90,197,182,127,225,232,232,216,108,199,142, 29,254, 31,127,252, -113,104, 74, 74,202,160,178,110,140,195, 0,218, 18, 66,162, 95,124,237,240,225,195,237, 71,141, 26,117, 55, 61, 61,253,139,234, -202,249, 2, 77,237,237,236,164,123,182,238,140,176, 49, 55, 99,236, 93, 21,140,192,202,138,111, 16,153, 9, 89, 64, 85,207,173, -190, 12, 64,211, 42,234,236,213, 69,195,137,135,135,199,225, 95,127,253,213, 65, 32, 16,192,104, 52,194,222,222, 30,207,159, 63, - 71, 94, 94, 30, 10, 11, 11, 17,247, 40, 26,245,221,220, 48,125,252, 39,206, 95,127,187,246, 48, 33, 36,240,197, 70,172,210,197, -184,117,186, 87, 27,156,170, 22, 8,135, 41,229,172, 10,150,101,159, 43,149, 74, 72,165, 82, 52,105,210, 68,126,251,246,237,171, - 41, 41, 41, 41, 53,105, 74, 36,146, 15, 58,116,232, 96,190,103,207, 30, 4, 4, 4,192,210,210, 18, 33, 33, 33,136,140,140,132, - 78,167, 99,138,138,138, 96,110,110,142,149, 43, 87,194,221,221, 29, 5, 5, 5, 72, 76, 76,180, 21, 8, 4,118, 85,105,134,156, - 9, 89,154, 31,123,105, 65, 26, 57,221,107,251,158,125, 24, 55,108, 40,156,232,179,171,150, 13,200,210, 30,253, 59,124, 69,121, -110,253,100,230,126,214,141,154,245,135, 80, 36,199,212, 57, 75, 16,243,224,152,117, 73, 97,196, 20, 98, 76,114, 3, 48,253, 85, - 77, 82, 90, 65,140, 66,161,248,100,235,214,173,230, 21,119,244,101,107, 18,190,104,172,202, 31,149,213,105, 85, 11,166,235,116, - 58,232,116, 58, 24,141, 70,100,101,101,161,176,176, 16, 86, 86,101,137,250, 23, 1, 4,132,208, 42, 86,161,127, 81,147, 97,152, - 17,251,246,237,115,147, 74,165,175,126, 6,101,209, 65, 72,165, 82,176, 44, 11,157, 78, 7,131,193, 0,141, 70, 35, 15, 10, 10, -154, 12,224,102,101,154, 60, 30,111,230,164, 73,147, 58, 28, 63,126,220,107,233,210,165,208,233,116,107, 50, 51, 51, 49,126,252, -120,176, 44,139,142, 29, 59,182,165,148, 62,158, 62,125, 58, 0, 96,241,226,197,250,162,162,162,137,117, 61,150, 28, 29, 29,125, -251,247,239,239,117,225,194, 5,116,234,212, 9, 26,141, 6, 95,125,245,149,197,234,213,171, 45,246,239,223,111,191, 98,197,138, - 95, 0,244,172, 78, 51, 32, 32, 64,144,158,158, 62,119,196,136, 17,179,130,131,131, 45, 19, 19, 19, 97,102,102,134,163, 71,143, - 98,235,214,173,167,116, 58,221,130, 67,135, 14, 45,219,182,109, 91,175, 1, 3, 6, 96,235,214,173,211,202,134, 69,176,149,104, - 42,220,220,220, 16, 17, 17, 1,107,107,107,216,217,217, 33, 63, 63, 31, 55,110,220,192,173, 91,183,224,227,227, 3, 66,136,117, - 89,155,102,120,157,243,168,150, 70,244,255, 93,179,124,134, 26,251,194,177, 75, 41, 45,221,104, 90,247,114, 18, 66,248, 10,133, - 98,128,149,149,213, 20, 74, 41, 63, 55, 55,119,171, 84, 42, 61, 24, 27, 27,171,253,255,218,246,127,133,193,114,113, 65, 65, 86, -150,117,140,131, 83,243,125, 14, 78, 77,203, 82, 85, 51,143,120, 60,235, 24, 71,199,146, 2, 0,208, 25, 40, 66, 31,229, 33,226, -105, 26, 34,159,166, 65, 38,174,249,174,219,214,214, 22,237,219,183,199,209,163, 71,145,148,148, 36, 95,185,114,101, 35,157, 78, -167,235,223,191,191,210,195,195, 35,183, 99,199,142, 16, 8, 4,184,125,251, 54, 10, 10, 10,192, 48, 12,196, 98, 49, 88,150,173, -242, 86,212, 33,215,122,212,168,241,205, 61,237,172, 24, 28,187,118, 26,109,125, 6, 66, 42, 22, 32, 51, 79, 5, 2,130,103,207, -207,131, 53,200,113, 63, 58, 30,237,253,164,120,167,181,149,107,209,133,156,241, 0,126, 48,165,130,116,113, 33, 16,249, 14, 2, -216,166,160,185,177, 96, 11, 82, 64,165, 14, 40,102,205,144,165, 76,192,163,171, 7, 64,117, 53, 15, 21, 51, 24, 12, 19, 29, 28, - 28,152, 5, 11, 22,244,247,244,244,100,167, 78,157,122,253,249,243,231, 67, 94,252, 76,253,250,245, 15,108,218,180,169, 67, 92, - 92, 92,201,210,165, 75,143,101,100,100, 76,170,229,137, 57,151, 16,178, 14, 0,146,146,146,178,255,248,227,143, 78, 87,174, 92, - 89,177,110,221, 58,215,169, 83,167,138,167, 78,157, 58, 23,192,164,234,186, 5,101, 98,113,240,178, 43, 87,168, 33, 57, 89,115, -100,235, 86,222,250,176,176,121, 58,150,173,103,239,224,192, 15,234,212, 73,109,103,101, 85,156,158,150,198, 90, 41, 20,228,121, -108,172,156, 21, 8,116,167, 79,159, 46,204,201,201,169,114,153, 17, 62,159,175,169,172, 91,176,138, 99,132,173,108,140, 86, 53, - 20,176,148,234,172, 60, 61,105,143,110,237, 26, 62,125,252,236,153,196,202,138,215,168, 97,253,198, 15, 31, 61,191, 69,141, 6, - 53,128, 2, 19,187,216,134, 46, 90,180,168,185,133,133, 5, 88,150,133,165,165, 37, 50, 51, 51,161,213,106, 81, 80, 80, 0,109, - 97, 62,180,249,249,136, 76,120,142, 14, 65, 65,232,209,174,109,147, 19,122,253, 80, 0,123,171,211,181,241,243,175,136, 92, 29, -240,250, 79,212,242,195,248,188, 10,179,117,178,117, 3,136,228, 50, 52,159,241, 69,157, 79,230,212,212,212,187,238,238,238, 39, -123,247,238,221,103,194,132, 9, 76, 90, 90,218,105, 71, 71,199, 14,233,233,233, 81,213,125, 79, 46,151, 55, 40, 55, 20,150,150, -150, 88,191,126, 61, 28, 29, 29, 81, 82, 82,130,219,183,111, 83, 87, 87, 87,114,233,210, 37,184,186,186, 34, 43, 43, 11, 58,157, - 14,197,197,197,105, 90,173,182,202, 3,191,172, 27,176,247,204,222,206,167, 30,135,239,232,228, 66,226,110,127, 48,171,243,211, -199,145,143, 18,207,158,187,254,141, 65, 45, 73,202, 75, 62, 63,215,179,213, 93,187, 41,179,191,198,166, 53,139,240,248,230,149, - 28,199,122, 5, 63,152, 17,205,111,109,186, 87, 27, 65, 87, 63,122,244,200,252,254,253,251, 32,132,192,210,210, 18, 82,169,180, - 82,147,101, 42, 70,163,177,226,111, 86, 86, 22, 50, 51, 51, 17,155, 16,131, 67, 23,119, 64,111,208,219,253,218,198, 34,205, 75, - 40,140,176,203, 39,243,179, 30,208,187, 53,156,135, 91, 63,252,240,195,161, 46, 46, 46,230, 47,190,222,162, 69, 11,140, 24, 49, - 2, 59,119,238,196,157, 59,119, 42,186, 49, 41,165,200,204,204, 76, 53, 26,141,191, 85,165,153,152,152,152,231,234,234,218,235, -147, 79, 62, 9, 63,114,228,136,197,183,223,126, 11,163,209, 8,131,193, 80,209, 45, 90,254,119,247,238,221, 8, 15, 15, 95,152, -150,150,246,168, 46,199,145,147,147,147, 79,255,254,253,175,252,240,195, 15, 86, 25, 25, 25,200,202,202, 66, 81, 81, 17,138,139, -139, 97, 52, 26, 81,191,126,125, 98, 48, 24, 26,215,212, 29,200, 48,204,209,139, 23, 47,246,106,212,168, 17, 0, 64,175,215, 35, - 52, 52, 20,227,199,143,207,150, 74,165, 31,196,199,199, 23, 43, 20,138, 47, 79,156, 56,209,171,101,203,150,240,243,243,115,202, -200,200, 48, 7,144, 95,197, 13, 4,140, 70, 35, 50, 51, 51,145,153,153,137,159,127,254,207, 58,206, 26,141,166, 44, 56,160, 37, -173, 90,181,170,127,251,246,237,231,111,107,163, 29,255,251,118,196,207,255, 20, 30, 87, 31, 3, 0,194,125, 75,135, 92,185, 95, -142, 46, 29,126, 48,106, 84,173,244, 20, 10,133, 45,165,116, 92,112,112,240,140, 94,189,122,217, 43, 20, 10,216,216,216, 32, 50, - 50,178,195,153, 51,103,190,119,117,117,253,209,104, 52,254,104, 74,180,158,195,164, 46,194,193, 70, 59,187,131, 89, 41, 41, 34, -157, 72, 36,141, 41,143,106,149,154,171,193, 70, 96, 15, 12, 58,125,217, 5,130,150, 61, 76,235,214, 80,167,190, 15, 86,245, 39, - 28,164, 3,176,109,219, 17,100,100,100, 8,215,175, 95,239,113,228,200, 17,215, 17, 35, 70, 36, 54,108,216, 48, 63, 40, 40, 8, - 59,118,236,128,147,147, 19, 52, 26, 13,216,106,196,205,109,140,131,219, 54,111,200,123,146,240, 0,129,222,131, 81, 95,209, 17, -207, 82,242,145, 83,168, 65,118,190, 10,141,189,103, 35, 61,187, 4,249,197,106, 68, 62,222, 13, 23, 39, 79,134, 39,136,237,101, -170,193, 82,223,223, 5, 77,228, 62, 8,189,186, 64,212,116, 40, 4,174,237,144, 20, 25,130,123, 39,191, 67,242,195,107,160,172, - 17,142, 30, 77, 76,218,118,129, 64,176,228,196,137, 19, 61,150, 47, 95, 46,232,214,173, 91, 7,133, 66,209, 94,169, 84,134,150, - 29,228,237,251,244,233,211,193,193,193, 1, 27, 54,108,208, 10, 4,130, 37,117,188,251,121,177, 91,237,146,147,147,211,212,195, -135, 15,255, 57, 97,194, 4, 56, 59, 59,183,169,238,187,153, 2, 65,139,209,203,151, 83, 1,143, 71, 79,252,242, 11,153,127,242, -228,198,157,191,255, 46,234,208,161, 3, 8,128,136,200, 72,201,202,245,235,205,134, 14, 24,144, 17,243,252, 57,206, 94,188,168, -201, 72, 75,203,202, 44, 46,158,243,166,102, 23,213, 22,131,193, 16,150,152,148,232, 18,216,166,165,253,221,232,184,135, 61,187, -182,111,207, 48, 12,243,248, 89, 66,168,189,189,133,244,234,213, 43, 58,131,193, 16,102,226,254,233,215,177, 99, 71,126,110,110, - 46, 20, 10, 5, 50, 51, 51,145,146,146, 2,189, 94, 15,117,126, 46,116,249,249,208, 23,228,193, 88, 92,132,184,219,183,224,235, -230, 34, 62, 91, 58, 8,126,111, 77,119,156,149, 69,168, 94,140,100,137,205,229, 16,203,229, 47, 45, 78,109,226,197,113,128,133, -133,197,220,194,194,194,147, 41, 41, 41, 75,181, 90,237,212,229,203,151,183, 90,178,100,137,221,188,121,243, 44,230,204,153,115, -192,195,195,163,101,124,124,124,149,166,181,168,168, 40,214, 96, 48,216, 1,112,184,112,225, 2, 28, 28, 28,144,159,159, 95,186, -221,106,181,182,164,164, 68,146,157,157, 13,141, 70, 3,173, 86, 11, 11, 11, 11,220,185,115, 39,215, 96, 48,252, 89, 83,249, 44, - 26,144,165, 26, 93,244, 2,219, 38, 50,165,206, 96,221, 57, 35,135,205, 93,244,173,114, 9,128,239,122, 55,104,176, 93,199, 94, -137,123,242,224,152,245,243,219, 33, 57,202, 39,197, 94,219, 79, 60, 43,172,166, 30, 41, 33,132, 37,132, 80,111,111,111,100,102, -102,130,199,227, 65, 42,149, 66, 46,151,195,199,199, 7, 73, 73, 73,117, 54, 88, 6,131,161,194, 92,157, 11, 59,142,236,162, 84, -108, 95,179, 7, 46, 78,110, 12, 0,251,148,180,164,238, 99,103, 13,105,227,217,209,122, 69,220,181,220, 42,199,181, 41,149,202, -123, 0, 44, 94,190,105,117,233, 98, 99, 99,115, 81,171,213, 34, 62, 62, 30,103,207,158, 13, 74, 78, 78,190, 92,155,125,157,156, -156,252,204,197,197,165,215,123,239,189,183,163,121,243,230, 13, 40,165,240,241,241,193,128, 1, 3,112,232,208, 33, 68, 69, 69, -161,160,160,128,189,122,245,234,175,169,169,169,181, 26,144, 67, 8, 33,148, 82,234,236,236,220,184, 95,191,126,215, 54,109,218, -100,157,149,149, 5,149, 74,133,226,226, 98, 28, 60,120, 16,157, 58,117,130,141,141, 13,254,248,227, 15, 67,121,143, 66, 85,230, -138, 82,122,244,200,145, 35,189,188,188,188,240,232,209, 35,156, 59,119, 14,158,158,158, 16, 8, 4,232,215,175,159,237,190,125, -251,166,250,250,250,174, 21, 8, 4,223,244,233,211, 7, 70,163, 17,119,238,220, 73, 77, 72, 72, 40,172,201, 4, 87,134, 74,165, - 2,165, 20,122,189,126, 61,195, 48, 31, 4, 4, 4,244, 8, 15, 15,191,245,182, 52,212,174,174,174, 77, 5, 2,193,116,107,107, -107,100,103,101, 33,159, 5,114,114,114, 64, 41, 69, 62, 91, 26,184,146,101,255,167, 87,189, 81,163, 70, 39, 84, 42,213,252,228, -228,228, 42,215,242,114,113,113,241,147, 74,165, 51,250,247,239, 63,162,111,223,190, 60,189, 94,143, 99,199,142, 97,211,166, 77, -232,213,171, 23, 26, 54,108,136, 57,115,230, 88,170,213,234,121,167, 79,159,158,219,164, 73,147,211,133,133,133, 95, 84,167,201, - 97,146,193, 42, 53, 89, 46, 46,200, 45,187,163,177,179,177,177,217,100, 52, 26,187, 0, 95,193,156,111,137, 71,119,111, 35, 39, -155, 7,141,202, 8,150,150,154, 44,147,186, 49, 84,127,194,194,155,162, 32,134, 64,175,215,195,209,209, 17, 43, 87,174, 68,126, -126, 62,127,236,216,177,245,191,254,250,235,123, 90,173, 22,197,197,197, 80,169, 84, 80,169, 84, 48, 26,141, 85, 26, 44,161, 88, -211,188,158, 99, 35, 20,170, 90, 67, 42, 22, 33,167, 64, 83,106,174,242,212, 56,244,231,135,208,148,168, 96,212,233, 96,208,234, - 33,119, 28,136, 6,190, 93, 0, 60,109,102,162, 89, 41,253,203, 26,160,125,122, 14,218,167,231, 32,235,178, 0, 71,151,143,120, -229,196, 55,109,114, 98, 74, 74, 74,138,139,139,203,206,187,119,239,126,252,193, 7, 31,224,210,165, 75, 95,162,108,102,149, 68, - 34,249,242,131, 15, 62,192,221,187,119, 17, 29, 29,189,179,170,174,157,218, 34, 18,137,138,181, 90,109,121, 87,144,180,134,207, -186,180, 26, 52,136,201,191,123,183, 96,249,197,139,139,126,251,237, 55,209, 59,157, 58, 65,175, 47, 53,211,245,235,215, 71,143, -158, 61,197,187,246,239,151,171,242,242,110,207,159, 58,245,207,205,163, 70, 21,220, 42, 42,122, 96, 98,125, 54, 41,235, 26, 4, -165,180, 73, 85,175,213,134,226,226,226,141,243,231,205, 10, 62,120,232,168, 91, 61, 55, 23,139, 51,231, 46,223, 23,155,137, 24, -175,250, 13,120,133,133,121,252, 77,235,191, 51, 43, 42, 42,250,222, 68,185, 38,118,118,118, 72, 75, 75,195,211,167, 79,161,209, -104, 74,183,189,164, 24,218,220, 60,104,243,115, 64,212, 42,136,141, 70,168,179,210,225,225,229, 9,252,103,134, 97, 77, 13, 88, -165, 6,171,252,175,153,133, 5,132, 50, 25,120, 2,129,201, 99,176,156,157,157, 3,252,253,253,247,111,219,182, 77, 56,115,230, -204, 54, 30, 30, 30,155,210,210,210, 18, 92, 93, 93,187,173, 89,179,230,214,178,101,203,196, 35, 70,140,104,188,117,235,214, 81, - 0,182, 86,121, 19,161, 86,239, 63,113,226,196,112,119,119,119,135,200,200, 72,168,213,234,242,241,102, 0, 32, 41,255,220,227, -199,143, 85,106,181, 58,227,193,131, 7, 5, 9, 9, 9, 90,152, 48,235,111,209, 6,101,216,204, 33,174,131, 28,157, 92,110, 72, -204, 60,234,211,162,187, 3,103, 14,113, 93,179,246, 64,178,250, 84,108,108,225,194, 41, 94, 43,139, 11, 35,166, 88,185, 22,253, -112,234,216,179, 66, 83, 14,163,178, 25,131,176,181,181, 5,159,207,135, 64, 32, 64,249, 88, 36, 71, 71, 71,228,231,231, 87,219, - 69, 88, 85,227, 93, 80, 80,128,252,252,124, 60,121,254, 8,217, 69,169, 56,187, 39, 12, 70,163, 17,106,181,186,212,204, 58,186, -226,252,222, 91,230, 65,131, 91,205,183,245, 35,151,178, 35,232,109, 83,143, 83,134, 97,102, 12, 26, 52, 8, 58,157, 14, 3, 6, - 12,192,158, 61,123,102, 0,184, 92,219,227, 61, 37, 37,229, 6, 33,164,209,211,167, 79, 45,244,122,253,187,253,251,247,255,173, - 79,159, 62, 8, 11, 11,195,133, 11, 23,130,180, 90,109,140,209,104, 84, 57, 59, 59,175,112,118,118,118, 32,132,172,168,110,130, - 71, 89, 42,134,205, 77,155, 54,125,183, 75,151, 46,247,251,244,233,211,108,211,166, 77, 86, 25, 25, 25,229,147, 26,144,156,156, -140,147, 39, 79,166, 30, 59,118,172,128,101, 89, 91,134, 97, 78,100,101,101,125, 81, 85,183,160, 78,167, 59,114,236,216,177, 94, - 94, 94, 94,184,124,249, 50,150, 47, 95,142,230,205,155,227,196,137, 19,240,240,240,128,143,143, 15,108,108,108,166, 23, 20, 20, -180, 91,189,122,117, 31,127,127,127, 28, 57,114, 4,233,233,233,223, 87,151,178,193, 96, 48,212,104,176,186,118,237, 58,126,230, -204,153,232,223,191,255,217,192,192,192,214,119,238,220,249,159, 79,211,162, 80, 40, 86, 6, 7, 7,207,109,209,162, 5,126,255, -253,119,168, 3, 58, 64,246,235, 49, 60,232,215, 1, 20,128,226,215,163,160,148,226,225,128,119, 64, 1,212,239, 54, 24,115,231, -206,237, 51,112,224,192,122,168, 98,120,132, 66,161,248,246,163,143, 62,154, 53,114,228, 72,132,135,135, 99,235,214,173,184,119, -239, 94, 69,155,167,215,235, 17, 29, 29,141,232,232,104, 56, 59, 59,163, 95,191,126,100,194,132, 9,189,123,247,238,109, 15, 32, - 16, 28,175,107,176, 42,194,197,118,214,214,214, 15,127,248,225, 7,219,214,173, 91,243, 12, 6, 3, 46,133,132, 96,241, 87,179, -208,187,231,199,208,177,150, 48,104,133, 96,133, 18,211,126, 81,220, 15, 5, 49, 4,172,176, 15,180, 90, 45,198,237, 22,192,138, -100, 96,253,104, 71, 0, 32,106,181,186,194, 88,149,223, 61, 85, 23,193, 42,204,151,233,244,122, 10,101, 70, 2,146, 83, 31,194, - 66,238, 6,202,115, 67, 70, 78, 9, 8, 28, 97,208,196,192,168, 47, 53, 64, 26, 85, 50, 74,180,228,181, 42,204,152,243,215,217, -192, 70,131,233, 99, 42, 41,165, 27,118,237,218, 53,124,237,218,181,226,190,125,251,250, 57, 59, 59,247, 0,128, 33, 67,134,248, - 89, 88, 88, 96,215,174, 93, 26, 74,233,134, 55, 24,225,121, 47, 48, 48, 16, 57, 57, 57,136,143,143, 15,173,118,219,180, 90, 91, -185,131, 3, 47,227,210, 37,125, 78, 97, 97,189, 78,101,230,138, 97, 24,228,230,230,226,249,243,231,144,203,100,120, 16, 21, 37, -254,110,210,164, 93, 62,126,126, 76,249, 12, 67, 83, 56,118,236,152, 57,128,182, 53,189, 86, 27, 50, 51, 51,139,157,156,156,198, -124, 57,127,254,145,239,191,255,222, 50, 61, 35, 61, 70, 44, 18, 25,228,114,137, 98,250,244,201,252,130,130,130,225, 89, 89, 89, - 69,166,234,229,230,230, 34, 46, 46, 14,102,102,102, 16, 10, 4, 96, 85, 37, 48, 22, 23, 65,157,147, 9,158, 78, 11,145,209, 8, - 27,169, 24,110,142,142,168,103,111,103, 90,215,221,165,179, 21, 3,218, 95,236, 22, 60,221,190, 49,196,114, 25,196,114, 57, 58, -252, 81, 58,132, 77, 40, 20, 2,235,183,153,210,141, 99,167, 80, 40,254,220,180,105,147, 48, 59, 59, 27, 15, 31, 62,188, 31, 31, - 31,159,111, 99, 99, 99, 46, 16, 8,216, 39, 79,158,156,127,244,232, 81, 63, 79, 79, 79, 80, 74,107,154,253,245,221,225,195,135, -187,119,236,216,209, 80,191,126,125, 89, 70, 70, 70,189,252,252,124,146,154,250,242, 24,230,219,183,111, 75, 18, 19, 19,139, 89, -150, 61,130,210, 60, 88, 53, 30,248, 51,135,184, 74, 66,239, 98, 90,231,158, 30,205, 45,236,252,144, 99,184,219,252,198,253,212, -105, 51,135,184,110, 92,123, 32, 89,109, 70, 52,191, 17, 99,146, 27, 95,162,222, 97,226,249, 67,125,125,125, 65, 41,197,173, 91, -183,112,237,218, 53, 92,185,114, 5, 9, 9, 9, 21,159,177,180,180,196,185,115,231,208,165, 75, 23,147,143,163,146,146, 18, 56, - 59, 59,195,218,218, 26,135, 47,237,196,246, 53,123, 42, 6,186,151,147,149,149, 5,169, 84,138,101,159,175,149,143,157, 51,248, - 27, 0, 61, 76,209,118,115,115,243,236,208,161, 67, 95, 71, 71, 71,228,230,230,194,193,193, 1,173, 90,181,234,239,232,232, 88, - 63, 61, 61,189, 78, 93, 89, 90,173,118,114,151, 46, 93,150,126,254,249,231, 48, 24, 12,248,240,195, 15, 17, 23, 23,183,255,217, -179,103,235,221,221,221,167, 77,153, 50,197,209,206,206, 14,147, 39, 79,150, 1, 24, 84,141,193, 90,177,122,245,234,225,193,193, -193,140, 94,175,127,231,194,133, 11,136,143,143,135, 86,171,133,193, 96, 64,124,124, 60, 22, 45, 90,148, 90, 80, 80,208, 57, 57, - 57, 57,182,166,114,165,165,165,205,250,227,143, 63,250,120,123,123,227,204,153, 51,152, 56,113,226, 9, 11, 11,139,166,126,126, -126,245,234,213,171,135, 63,255,252, 19,102,102,102,112,118,118,118,156, 55,111, 94,191,158, 61,123,226,252,249,243, 88,178,100, -201,113, 39, 39,167,239,106, 50,193,124, 62, 31,122,253,203, 55,180, 60, 30, 15,247,238,221, 67,215,174, 93, 49,119,238, 92, 0, -192,249,243,231, 45,122,244,232,241, 32, 40, 40,200, 34, 36, 36, 68,131,255, 97,100, 50,217,152, 95,127,253, 21, 79,159, 62,197, -213,171, 87,145,149,149, 5,173, 86,139,188, 50, 43, 42, 46,139,100, 81, 23,119,180,159, 53, 31,195,250, 13, 66,106,106, 42, 24, -134,177,171,230,134,111,196,252,249,243,113,234,212, 41,172, 90,181, 10,249,249,249,149,126,206,204,204, 12,173, 90,181, 66,203, -150, 45, 17, 23, 23, 7, 0,118,224,120,115, 6,203,218,218,122,253,230,205,155,109, 59,116,232,192, 43, 51, 59,104,221,170, 21, - 70,141, 25,131,115,135,143,195,193,187, 23,136, 86, 14,131, 84,100, 90, 4,203, 98, 7,178,245,217,144, 8, 37, 16,107,181, 96, - 89, 51, 68, 36,171, 43, 92,179, 74,165, 66,185,201, 42, 46, 46,134, 76, 38,171,222, 64,104, 69,225,209,113, 6,183,252,194,123, -184,113,119, 39,244, 90, 61, 26,120,207,135, 74,111, 11,153,253,199, 80,107,255,132, 49,175,116,230,174,200, 34, 8,105,105, 89, - 0,136,169, 17,151,191,158,228,133,127, 29,236,206, 26, 77,207,187,170, 84, 42,179, 21, 10,197,214,208,208,208,233,131, 6, 13, -194,185,115,231,230, 3,192,160, 65,131, 16, 26, 26,138,184,184,184,173, 74,101,229, 51,168,106,139,139,139,203,168,206,157, 59, - 79,105,221,186, 53,142, 31, 63, 14,163,209,120,210,148,239,241, 4, 2, 74, 8, 65,249, 12,167,156,220, 92, 60,126,252, 24, 57, -217,217, 48, 26,141, 40, 81,169, 12, 77, 27, 55, 46,160, 44,107, 94,155,242,188, 56, 99,176,178, 89,132,229,175,213,118, 59,211, -210,210, 18, 26, 52,104,144, 88, 82, 82,108,111,109,101, 93, 40, 18,137,140, 5,133,133,249, 79, 99, 30,105, 77,105, 20, 94, 32, - 58, 42, 42,170, 89,114,114, 50, 18, 19, 19, 97, 40, 46, 4, 79,163, 5,163, 41, 65,183,246,237, 96, 6, 10, 9, 88, 8, 88, 61, - 4, 60, 1, 10, 75,103,219, 69,215,120,204,191,208, 32,148,155, 43, 66, 8, 36,114, 57, 68,114, 25,196,230,242,151, 34, 90,166, - 76,252, 50, 51, 51,219,189,117,235, 86,103, 39, 39, 39,172, 93,187, 22,206,206,206, 62,193,193,193, 37,157, 59,119, 54,179,179, -179,131,183,183, 55, 2, 3, 3,113,233,210, 37, 16, 66, 98,107, 56,206, 13,132,144, 30, 87,175, 94,157,117,253,250,245, 33, 10, -133,130,140, 28, 57, 18,189,122,245,130, 68, 34, 65, 73, 73, 9,114,115,115,113,226,196, 9, 98, 52, 26,253,203, 12,158,187,135, -135,199, 30, 66, 72,242,243,231,207, 63,120, 85,115,231, 58, 63, 69, 70, 14,251,177,163,147,203,192,206, 61, 61,154,119,237, 25, - 12,207, 70, 93,209,181,103, 34, 0,172,180,225,199,127,184,102, 65,179, 35,118,110, 54,191,156, 61,125,110, 81,199,206, 93,191, -156, 55,193,122,233,202,173,185, 53,142,151, 35,132, 84, 52,182, 12,195, 84, 26,165,226,243,249, 21,179,205,106,188,105, 98,141, -201,189, 70,183,171,120,174, 55,232,237, 92,156,220,152,242,200, 21, 0,228,231,231, 35, 41, 41, 9,122,189, 30,182,182,182,208, -235,117,126,181,232,126,156, 54,116,232, 80,162, 86,171, 49,107,214, 44,124,251,237,183, 24, 48, 96, 0,185,121,243,230, 52, 0, - 51,234, 16,209, 88, 51,101,202,148, 89, 99,198,140, 65, 94, 94, 30, 46, 94,188,136, 46, 93,186, 96,203,150, 45,246, 23, 47, 94, - 92,222,190,125,123,240,120, 60,156, 59,119, 14, 58,157,238,113,181, 13, 0,159,255,110,112,112, 48,147,148,148, 4,161, 80,136, -192,192, 64, 36, 39, 39,163,164,164, 4, 25, 25, 25,248,250,235,175,211,242,243,243,131, 82, 82, 82, 98, 77,216, 47, 76,135, 14, - 29,166, 55,108,216, 16, 23, 47, 94,196,164, 73,147, 78,201,100,178, 65,217,217,217, 19,212,106,245,198,161, 67,135,194,199,199, - 7, 49, 49, 49,232,219,183, 47, 90,181,106,133,139, 23, 47, 98,206,156, 57, 39,164, 82,233,251, 53,228,193,122, 18, 18, 18,210, - 44, 48, 48, 16, 37, 37, 37, 40, 40, 40,128, 64, 32,128,149,149, 21,162,163,163,209,168, 81, 35,204,157, 59, 23,107,215,174,197, -204,153, 51,217, 30, 61,122, 24,116, 58,157, 80, 36, 18,253,207, 55,210,197,197,197, 52, 53, 53, 21, 22, 22, 22, 56,112,224, 0, - 34,207,159,193,201, 79, 63,134,100,193, 26, 80, 74,145,180,116, 30,186,205, 89,128,182,247,159, 33, 53, 53, 21, 59,118,236, 0, -195, 48, 21, 51, 98,171,106,219,242,243,243,209,178,101, 75,220,186,117, 11, 59,118,236,192,186,117,235, 42,162,181, 2,129, 0, - 65, 65, 65,232,222,189, 59,158, 60,121,130,173, 91,183,194,194,194,130,115, 76,111,218, 96,177, 44,219,181, 85,171, 86,188,162, -162, 34,168,213,106,164,165,165, 33, 62, 62, 30,102, 82, 51, 36,101,165,160,133,191, 14,105,108, 1,162,239, 63, 52, 18,158,224, - 94, 77,119, 32, 90,173, 22, 90,173, 22, 17, 17, 17,165, 83,223, 27,173,168, 24,232,169,215,235,161,209,104,160, 82,169,112,241, -226, 69, 42, 22,139, 33,147,201, 72,117,125,239,172, 65,115,234,226,181,251,125, 70, 12,236, 34, 58, 23,178, 29,122, 45,139, 2, -181, 5,138, 84, 26, 20,169, 5,208,136,123,130,144,171, 96,120, 98,180,111,217, 16, 23,175,197,168,141,122,157, 73,233, 10,192, - 26,193,119,246,131, 33, 53,226, 63, 47,189, 50,155, 80, 40,149,131, 53,214,110, 86,176,153,153,217,150,221,187,119,143,105,215, -174,157,121,112,112,112, 35, 0, 16,139,197,236,238,221,187, 11,205,204,204,182,212,118, 39,190,154,189,221,217,217,185,163, 72, - 36,154,218,191,127,255,142, 99,198,140,193,195,135, 15,241,251,239,191,223, 87, 40, 20,213,142,153,225,137, 68,217, 69, 25, 25, - 86,242,250,245,249, 86,230,230,202, 51,103,206,120,188,211,185, 51, 18,226,227,145,147,147, 3,149, 74,133,168,232,104, 42,100, -152, 68, 98, 97,193, 60,190,123,151,225,137, 68,217,181, 40,103,116, 77,179, 8,235, 26,205,146,153,145, 6, 11,230, 78,240, 84, -171,213,205, 10, 10, 10, 12, 2,129, 64, 32, 21,209,132,218,104,232,245,250,227, 87,175, 94,125,175, 67,135, 14,226,152,136,123, - 48,228,231, 67,155,159, 11, 33,107,132,141,127, 11,240,116, 26, 64,171,135, 75, 19, 10,117,158, 20,215,239, 61,211,235,245,250, -227,166, 26, 44,134,199,123,121,220,149,133, 28, 98,115,115,136,228,242,151, 94, 39, 53,244,107, 57, 58, 58, 74,123,247,238,221, -205,223,191, 52,167,214,154, 53,107,160,211,233, 68,122,189,190, 98, 38, 92, 81, 81, 17, 14, 30, 60,136,157, 59,119, 94,183,180, -180,252,213,132,155, 9,131,171,171,235, 84,150,101, 29, 12, 6,131,206,222,222, 94,184,127,255,126, 72, 36, 18, 48, 12,131,150, - 45, 91, 66, 34,145,104, 20, 10,133,174,172, 12,250,181,107,215,242, 63,254,248, 99, 97,101,122,141,155,251,204,246, 52, 88,119, -150,152,121,212,183,176,243,131,103,163,174, 0,128,238,253,198,194,179, 97, 61, 20,100, 69,212, 87,171,226, 7, 10,249,185,214, - 15, 55,166, 68,153,245,109, 54,166, 56, 35,228, 9,128,159, 76, 58, 53, 89, 22,193,193,193,232,217,179,103, 69,119,160,131,131, - 3,180, 90, 45,140, 70, 99,173,198,178,149, 39, 17,253,250,107,194, 96, 17,240,107, 27,139, 52, 0,246, 47,154,171,196,196, 68, - 36, 38, 38, 86,220, 8,178,212,180, 20, 42, 10,133,194,204,211,211,115,116,179,102,205,112,225,194, 5, 68, 68, 68,164,132,132, -132,184,180,110,221, 26,174,174,174, 99, 20, 10,197,124,165, 82,105,114, 66,101,123,123,123, 89,167, 78,157, 62, 29, 51,102, 12, - 30, 61,122,132,121,243,230,101,167,166,166, 30, 57,118,236,216, 39,159,125,246, 25,211,185,115,103,100,100,100, 96,203,150, 45, -198, 91,183,110,125,107,109,109,189,164,134,253,254, 72,169, 84,186,170,213,106,228,228,228,192, 96, 48,160,164,164, 4,167, 79, -159,198,153, 51,103,210,243,242,242,130,148, 74,229, 83, 83,202,230,238,238,110, 30, 24, 24,232,248,228,201, 19,236,217,179, 7, - 58,157,110, 65,124,124,188,206,210,210,114,215,242,229,203, 23, 89, 90, 90,218, 4, 7, 7,163,252,184,253,243,207, 63,177,120, -241,226, 19,102,102,102,131,162,162,162,116, 53,200, 15,252,230,155,111,190,177,179,179,251, 96,248,240,225, 76, 96, 96, 32,238, -220,185, 3,163,209,136,110,221,186, 85,152,171,211,167, 79,239, 62,125,250,244, 96, 0, 66,185, 92, 46,249, 95,143, 94,149,163, - 86,171, 17, 19, 19, 3, 71, 71, 71, 52,108,221, 14,115, 31, 60,199,213,208, 48, 80, 74,209,241,225,115, 20, 21, 21,227,215, 95, -127, 69,120,120, 56,120, 60, 30,188,188,188,106,212,212,233,116,120,250,244, 41, 50, 51, 51, 49, 96,192, 0,140, 24, 49, 2,171, - 87,175,134, 78,167,195,151, 95,126,137,156,156, 28,108,219,182, 13, 79,159, 62, 5,159,207,135, 92, 46,231, 28,211,155, 54, 88, -101,221, 76, 96, 89, 22, 41, 41, 41,184,115,231, 14,158, 63,127, 14,153, 76, 6,149,193,200,110, 57,127,141, 37, 68,152,204, 82, -122,157, 26, 74,179,136, 87,231,196,245,122, 61,225,243,249, 8, 13, 13,197,179,103,207, 96,222,144, 86,152,171,242, 8, 86, 73, - 73, 9, 4, 2, 65, 81, 88, 88, 88,124,120,120,184, 39,159,207,215, 86,165,153, 97,157,187,227,220,133,243,179, 3, 90,250, 54, -234,222,121, 49,142, 31, 95,132,220,252, 2,148,104, 5, 40, 84,233, 80,172,162,112,177,104,132,214,126,126,200,204,209,226,201, -195,240,228, 44,161, 77,141,125, 48,122,202,228,239, 94, 57,209,242,221, 17,147, 96,230,241, 14, 52, 15, 15,128, 45, 76, 3, 91, - 88,218,109, 34,146, 89,192,220,206, 13, 69, 37,106, 92,123,240, 12,122,202,228,155, 90,233,177,177,177,133, 10,133, 98,227,204, -153, 51, 87,133,133,133,202, 0,224,222,189,123,197, 74,165,114,169, 82,169, 44,172,205, 14,124, 33,123, 59,145,201,100, 79, 26, - 54,108,168,239,219,183,175,237,192,129, 3, 97,103,103,135,187,119,239, 98,229,202,149,119,139,139,139,135,197,199,199,235,107, -232,118, 72, 9,255,227, 15,139,160,145, 35,173,230, 13, 24,176,114,242,228,201,223, 47, 89,178, 68,216,160, 97, 67,176, 70, 35, -162,162,162,232,174, 93,187, 12, 63, 45, 92,184, 70, 36,147,241,111, 29, 61, 42, 48,104, 52, 41,255,237,131,216,213,213,181,115, -159, 94,157,155,124,187,118, 35,212,170, 34,220, 12, 61,129,220,220, 76,108,221,118,184,137,171,171,107,103, 83, 7, 19, 39, 39, - 39,239, 59,116,232,208, 44, 63,223, 38,254, 94,110,110,136, 76,120, 14, 17,107,132,208, 96, 0, 79,167, 1, 99, 80,195,173, 25, - 5, 97,204,145,150, 86,136, 45,103, 46, 62, 72, 78, 78,222, 87, 99, 36,177,247,187, 24,150,144, 15, 66, 8,206,118,242,133,196, - 92, 14,145, 76,134,246,135, 46, 87,152,170,132, 21,159, 67, 32,147,195,186,245, 59, 53,150, 51, 61, 61,189,164, 97,195,134,119, - 30, 61,122,212,170,113,227,198,248,250,235,175,145,148,148, 4, 74, 41, 50, 50, 50,212,153,153,153, 41,217,217,217,241,132,144, - 35, 74,165,114,187,169, 75,145,176, 44,235,112,236,216, 49, 0, 16, 2,192,133, 11, 23,160, 80, 40, 96,105,105,137,130,130, 2, -140, 28, 57, 82,252,213, 87, 95, 1, 0,238,220,185, 35, 48, 51, 51,171, 82, 43, 50, 60,250,219,188, 66,154, 75,139,238, 14,204, - 49,220,109,222,181,103, 18,186,247, 27,131,115,199,127,197,197, 51,231, 97,195,143,127, 14, 89,225,169,172,231, 89, 5,201,197, -141,126,108, 18,240, 9, 47,181,248,204,143,211, 6, 88,243,156,157,217, 3,243, 54, 87,157,184,183,252, 14,156,199,227, 85,140, -193, 42, 31,208, 94, 91,115,245, 34,139, 22, 81,150,128, 16, 47,161, 48, 34, 37, 45,169,187,194,209, 21,233,233,233, 72, 74, 74, - 66, 98, 98, 34,146,146,146,208,176, 97, 67, 60, 79,120, 6,145, 72,120,207,196, 40,248,240,254,253,251,155,107,181, 90,252,241, -199, 31, 6, 66, 72,191, 99,199,142,221,105,209,162, 5,191, 75,151, 46,230,191,254,250,235,112, 0,219,107,115, 47, 33,151,203, -133, 58,157, 14,191,253,246, 27,146,147,147, 59,167,165,165, 69, 43, 20,138, 31, 39, 78,156,184,185, 73,147, 38, 13,163,163,163, -159,168, 84,170,201, 74,165, 50,162, 38,177,188,188,188,177,189,122,245, 58,192,178,172,123,199,142, 29,101,139, 22, 45,178,120, -252,248, 49, 60, 60, 60, 64, 41,141,172,205, 82, 83, 9, 9, 9,133,215,174, 93, 75,111,218,180,169,163,179,179, 51,132, 66,225, - 74,103,103,231,165,114,185,252,219, 46, 93,186,216,236,218,181, 11,103,206,156,129, 64, 32,192,179,103,207,148,143, 30, 61, 90, -239,228,228,180,193,148, 12,238,225,225,225,113, 0,134,181,110,221,122,241,186,117,235, 22, 48, 12,243,209,217,179,103, 33, 16, - 8, 0,160,194, 92,213,175, 95,127,212,129, 3, 7, 70,188,101,237,180, 94,171,213,194,214,214, 22,153,153,153,200,200,200, 64, -189,122,245,208,174, 93, 59,232,245,122, 28, 61,126, 2, 87,175, 94, 5,165, 20,118,118,118,176,180,180,196,253,251,247, 1,160, -186,217,195,122,157, 78, 7, 27, 27, 27,228,229,229,225,254,253,251,112,112,112,192,204,153, 51,161,213,106,177,127,255,126,220, -187,119, 15, 12,195,192,193,193, 1,230,230,230,166,104,114,212,214, 96,241,120,188, 75,151, 46, 93, 26,236,231,231,199,127,250, -244, 41,158, 62, 45,189,153, 81,169, 84, 6, 62, 15, 7,211, 35,254, 24, 86, 77,227, 31,252, 98,174, 12,145, 72,180,101,240,224, -193,147,199,142, 29,139,169, 83,167,130, 16,130, 95,238,105,145,152,200, 66,175,215, 35, 61, 61, 29,145,145,145,180, 85,171, 86, -132,101, 89, 93, 80, 80,208,184,240,240,240,214, 60, 30,175,160, 42, 77, 26, 18, 98,112,108, 62,240,253, 31,182,108,191, 60,122, -244,104,155,254, 3,126,192,189,232, 40,228,151,216, 3,148,194,197, 94,142,214,222,159, 35, 35, 91,141, 51,167,142,231,178, 6, -245,251,244,193, 94,125,117,229, 4,128, 76,190,202,225,199,157,135,214,236, 61,112,120,220,248, 49,195, 37, 65,193, 35, 33,204, -138,132, 65, 25, 14, 23,223,142,160,124, 51,220, 10,191,139,136,167, 73,234, 18, 29,111,123,129, 80, 53,187, 38,205, 23,201,205, -205, 61,153,150,150,250, 67,249,228, 0,134, 33, 50,145, 72,124,178, 6, 51, 21,252, 74, 94,160, 87, 51,196,123,175, 88,177, 34, -195,214,214,150,125,248,240, 33,182,108,217, 98,188,115,231,206, 33,150,101, 23,100,101,101,149,212,164,105,175,215,223,223, 61, -111,158,111,235, 65,131,232,192,113,227,212,140, 68, 50,121,229,218,181,243,179,243,243, 93, 0,192,198,202, 42,105,235,226,197, - 75,122,247,233, 83,248,240,218, 53,179,208, 63,254, 48, 19, 25, 12,225, 53,149,243, 77, 80,157,102,114,114,242,229, 70, 13,234, -225,183,237,107,161,211,105,144,154, 82, 26,184,202,202,206, 71,117,230,234, 47,199, 82,233, 44,170, 65,235,214,111,184, 49,105, -228, 71, 78,239,116, 11, 70,226,253,123,208,229,100,130,232, 13, 16, 16, 62,138, 51,164,200, 72, 47,194,138,147,231, 51, 84,106, -245,160, 87, 19, 57, 86, 85,206,138,110, 65, 11,115,136,100,165,227,174, 94,140, 90, 9,205, 45, 32,144,201,193, 19, 10, 43, 27, - 12, 31, 92, 73, 78,185,247,199,143, 31, 31,113,242,228, 73,235, 97,195,134,225,221,119,223,189,155,151,151,215, 37, 39, 39,167, -176,174,245,201, 48, 76, 70,159, 62,125, 28,180, 90,173, 97,232,208,161,252,172,172, 44,148, 79,177, 47, 42, 42,194,169, 83,167, -208,184,113,233,236,252,135, 15, 31,162,105,211,166, 85,106,126, 50, 39, 50, 5,192,146,153, 67, 92,215,220,184,159, 58, 13,192, - 74,207,134,110,184,120,230, 60,174, 94, 12,157,215,182, 25,187,177,207,136, 86,223, 72,187,124, 48,187, 73,192, 39, 60,185,133, - 51,118, 28, 62,196,139, 14,255,105, 89, 73, 73,100, 3, 0,159, 87, 85,206,242,238,235, 87, 83, 50,168, 84, 42,147,204, 85,117, -199, 18, 5,165,118,249,100,254,216, 89, 67,218,156,219,115,211, 92, 46,151, 67,167,211,129, 82,138, 6, 13, 26,128, 47,224,227, -231, 35,223, 23,231,229,101, 45, 52, 69, 83, 38,147, 77, 13, 10, 10, 66,108,108, 44, 34, 34, 34, 14, 41,149,202, 8,133, 66,113, - 40, 46, 46,110,104,155, 54,109,176,111,223,190,169, 85, 25,172,170, 52,203, 51,214, 83, 74, 97, 52, 26,115, 0, 64,169, 84,222, - 55, 37,250,251,170,102, 89,178,208, 14, 0,208,164, 73,147, 36, 71, 71, 71,139,251,247,239,195,217,217, 25, 58,157,174, 77,109, -142, 37, 74, 41,171, 80, 40, 54,220,186,117,107, 69,203,150, 45,241,225,135, 31,118,191,115,231, 78,247, 22, 45, 90,192,203,203, - 11,215,175, 95,199,217,179,103,127,103, 89,118, 98,106,106,170,186,186, 36,168, 85,109,251,173, 91,183,158, 2, 24, 25, 16, 16, -240, 1,159,207,135,133,133, 5, 47, 37, 37,133,119,246,236, 89, 0, 24,127,224,192, 1, 99, 93,246,251,223,113, 93,122, 83,154, -132,144, 47, 71,141, 26,245,227,132, 9, 19, 36,109,218,180,121, 41,162,122,242,228, 73,176, 44, 11, 91, 91, 91,216,218,218,226, -233,211,167, 56,114,228,136, 54, 63, 63,127,189, 80, 40, 92, 89,157,230,200,145, 35,127,156, 48, 97,130,164,117,235,214,200,207, -207,175, 48,111,199,143, 31, 7, 33, 4,118,118,118,176,181,181,197,147, 39, 79,112,228,200, 17,117,110,110,238, 90,173, 86,187, -250,239,220,246,127,157,193,202,201,201,153,254,197, 23, 95,116, 25, 55,110,156,109,113,113, 49,207,214,214, 22,105,105,105,134, -211,167, 79,231, 20, 22, 22, 78,175,205,143,133,134,134, 78,233,215,175,223,250, 95,126,249,101,219,246,237,219, 59, 15, 29, 58, - 20, 35,251,246,197,164,182, 82,104, 52, 26, 16, 66,112,230,204,153,199,151, 46, 93,242, 20, 10,133,154, 69,139, 22,177, 0,110, -212,120, 71, 31,121, 36,202,177,249,192,206, 27,191,223,124,208, 63,176,173,187, 71,125, 15,113,123, 87, 75,232,244, 70,164,103, -100,227,114,232, 67, 77, 76,212,189, 20,170,211,189,159, 17, 85,115, 22,119, 0,136,138,162, 58, 0,211,125,125, 45,190, 94,253, -227,174, 45, 59,247, 28, 28, 56,126,196, 32,190,127,139,110,136, 11, 61,130, 43, 55, 46, 26,114,213,244, 72,161,128, 55, 41,234, -105, 65,110,109, 43, 94,163,209,104, 9, 1,197,127,178,175, 83,141, 70,163,173,203,249,248,226,147,159,127,254, 25,169,169,169, -154,132,132,132,189,148,210, 31, 83, 83, 83, 77, 78,159,176,145, 82,237, 32, 66,206, 47,232,216,177,215,130, 51,103, 36, 67, 62, -253, 84, 59,240,253,247,103, 67,163,209, 65, 36,162,124,153,140,129, 88, 44,120,120,237,154,217,134, 73,147,108,136, 86,123,238, - 87, 74, 77, 14,193,255, 29,179, 8, 95,136, 96, 97,244, 39,159, 65,245, 66, 4, 43,236,118, 12,106, 19,193, 2,128,212,212,212, - 68,103,103,231,182, 75, 55,108, 60,220,187,109,235, 38,141, 20,206, 98,219,250, 30,144, 59, 57, 33, 39, 43, 11, 55,239,197,234, -191, 63,127,249,129, 74,173, 30,100,106, 94, 24,150,101, 43,102,185,249,126, 58, 23, 12,143, 87, 97, 4,202,147, 6, 90, 4,118, - 4,225,243, 97,164, 20, 58,157,174,198, 65, 88, 74,165, 50,217,197,197,229,253, 79, 63,253,244,194,111,191,253,198, 4, 5, 5, -181,252,243,207, 63, 95,107,209,220,228,228,100,215,178,110,173, 2, 11, 11, 11,254,152, 49, 99,160,215,235, 81, 82, 82,130,252, -252,124,100,103,103,107,102,204,152, 33, 6, 0,161, 80,168,239,213,171, 87,141,215,143,181, 7,146,213, 51,135,184,110,180,225, -199,127, 88,144, 21, 81,223,134, 31,255,188,109, 51,118,227,218, 3,201,234,175, 63,179, 90,154, 21,127, 57, 38,181,248,204,143, - 59, 14, 31,226,141, 26,248,190,209, 85,254,100,158,196,129, 30,236,218,191,198, 70,232, 47, 73, 69,235, 26,185,122,149,172, 7, -244,174,103, 71,235, 21, 93,134,180,158,191,116,214, 90,185,131,131, 61, 12, 70, 3,158, 39,198,225,151,195,155,138, 11, 53,185, -203,178,163,232, 29, 83,180, 60, 61, 61,235,243,120, 60, 28, 61,122, 20, 0, 54,149,189,188,233,244,233,211, 67,135, 13, 27, 6, -119,119,119, 95, 15, 15, 15,113,117,105, 52, 42,139,222,233,245,122,188,233,117,173, 9, 33,207,182,108,217,226, 98, 99, 99, 67, -174, 94,189,106, 96, 24,230, 88,109, 53,156,156,156,190, 59,113,226, 68, 39, 74,105, 47,127,127,127,184,187,187,151, 93, 79,163, -112,245,234,213, 61, 41, 41, 41,163,223,208,226,206,148, 16,130,130,130,130,242,129,118, 58,185, 92,254, 86, 46, 26,157,146,146, -178,211,209,209,241,204,226,197,139,191,106,208,160,193,196,241,227,199,243,188,189,189,145,159,159, 15, 11, 11, 11, 40, 20, 10, -164,164,164, 96,231,206,157,198,140,140,140, 95, 24,134,249, 90,169, 84, 42,235,170,105,109,109, 13,103,103,103, 36, 39, 39,151, -107,110,211,235,245, 75, 50, 51, 51,211,193,241,102, 13, 86, 90, 90, 90,150,147,147, 83,211,159,127,254,121, 67,105,154,134,210, -168, 86, 97, 97,225,244,180,210, 17,227,181,226,248,241,227,177, 0,130,250,245,235,215,224,224,193,131,219,118,239,222,221,121, -192,128, 1, 24, 58,116, 40, 12, 6, 3,122,247,238, 61,250,213,168,149, 41,164, 71, 30,137, 34, 65, 65, 77,239,220,188, 50,242, -238,157, 27,253, 40,165,126, 0, 8, 97,152,255, 44,246, 28, 85,251,197,158,163,162, 10,114, 1,124,224,239,106,225,181,108,211, -174,237,102,124,182,163,202,192, 92, 83,105,152,113,119,147, 11,234,188,192,104, 89,230,245, 85, 12, 67,230,148, 62, 55,109,105, -152, 42, 52,230, 2, 0,159, 47,216,119,231,206,157,249, 9, 9, 9, 41,166,204,240,170,140,195,148, 38,142, 36,228,236,108, 63, -191,110,253,102,204, 16, 4,244,232, 97,110,227,230,198, 82, 74,141,207,111,222, 36, 97, 71,143, 10,194,142, 30,149,232, 53,154, - 11, 7, 40,173,213, 12,168,191, 99, 22, 97,121, 4,171,129,151,235,217,193,131,250,244,240,170,175, 0, 0, 60,123,174, 68, 86, - 78,254,217,218,230, 26, 42, 55, 89,132,144,192, 63, 13,134,161, 2,129,160, 31, 41, 75,197, 64,235,176,216,179,209,104, 76,110, -219,182,138,205, 91,180,178, 42, 67,150,110,226,133, 55, 68,161, 80,124,212,190,125,251,149, 74,165,242,112,102,102,102,241, 27, -186, 46,244,222,189,123,247, 73,150,101,205, 94,137,112, 21, 40,149, 74,243,178,134,212,253,244,233,211,123, 8, 33, 53, 26,248, -181, 7,146,213,107, 22, 52, 59,162, 86,197, 15, 36,242,146, 35,107, 55,148,206,106, 89,180, 46, 47, 31,192, 79,211, 6,218,176, -209,225, 63,173,118,177,120, 50,103,195,145,156, 95,106,210, 99, 24,230, 73,155, 54,109, 42,140, 86, 13,245,175,172, 75, 5,196, - 93,203, 93,105,235, 71, 46,125, 60,119,240, 55, 90,157,174, 5, 67, 64, 5, 66,225,253,188,188,172,133,166,154,171, 50, 99,241, -195,172, 89,179,166,199,198,198,238, 41,207,121,167, 84, 42, 67, 21, 10,197,119,137,137,137, 83,146,146,146, 54, 37, 37, 37,153, -108,174,228,114,185, 90,165, 82,177, 6,131,129,209,104, 52, 16,137, 68,186, 55,213, 24, 20, 23, 23, 15,223,188,121,243,207,122, -189,190, 9, 33,228, 88, 94, 94, 94,173,179,222,134,135,135,235,125,125,125, 7,156, 56,113, 98,250,131, 7, 15,102, 58, 58, 58, - 58,166,167,167, 39, 36, 38, 38,174, 72, 75, 75,251,233, 13,153, 43,132,135,135,139, 3, 2, 2, 52, 47,212,139,197,219, 50,222, -170,210,246, 45, 61, 61, 19,192, 84, 87, 87,215,245,179,103,207, 94,214,162, 69,139,193, 99,199,142, 37, 82,169, 20,251,247,239, - 71,124,124,252, 17, 74,233,252,218,116,233, 86,165,105,102,102,134,253,251,247,211,248,248,248, 3, 12,195, 44, 80, 42,149,255, -138,133,180,255, 14,200,155,190, 11,170,109,248,180, 95,191,126, 13,178,178,178,182,105, 52,154,119, 0, 20, 71, 68, 68,152,255, -183, 67,178,213, 17,228,107, 47, 11,137,170,185, 33, 51, 85,243,213, 1,234,117,209,172,141,134,169,154, 85, 45,246,204,106, 52, - 74, 91,131,225,206, 70, 74,181,166,106,186,184,184, 44,129,137,249,162,202,136, 78, 73, 73,249,170, 46,245,217,168, 81, 35,250, -244,233, 83, 80, 74,201,155,220,239,127,199,177,244,111,210,220,185,206, 79,209,184,185,207,236,200,240,232,111,203,186, 15, 43, -248,122,154,141,121,199,174, 65, 11,175, 93, 12,249,102,209,198,151,187, 56,223,134,109, 39,132, 48,149, 25,139,242,228,158,181, -213,172, 87,175,222,143,254,254,254,227,238,222,189,251,115, 98, 98,226,248,127,234,182, 19, 66,136,187,187,187,168, 54,209, 57, -238, 60, 50, 77,211,201,201, 41,144, 97,152,133,101, 55, 28,203,146,147,147,111,189, 65, 77, 35,165,116,105,106,106,234,221,255, -239,109,255,215, 69,176,254,110,202, 35, 90,239,190,251,174, 3,143,199,251,199, 47,210,105,138,185,170,109, 20,234,159,160,241, - 42,101, 6, 42,244, 77,104,189,106,150,254, 78,158, 60,121, 66,184,211,250,159,199,200,207, 34,148, 0,102, 4, 86,146,154,170, -204, 84,205,238,242,238,219,185,237, 85, 69,109,234,186, 16,115, 98, 98,226, 68,133, 66, 49,179, 54,179, 15,255, 75,219, 77, 1, -104,184,163,255,205,147,150,150,118, 7, 64,255,127,186, 38,103,176,254, 33,252,249,231,159, 25,220,238,224,224,224,224,168,153, -127,186,185,226,224,224, 40, 29, 32, 29, 92,197,221,135,201,161, 63, 66, 72,112, 29,238,110,206,115,154,156, 38,167,201,105,114, -154,156, 38,167,249,239,210,252,215, 80, 62,139,233,239,120, 0, 8,230, 52, 57, 77, 78,147,211,228, 52, 57, 77, 78,147,211,252, -183, 61, 24,206, 98,114,252,221,124, 63,136,184,124, 63,136,184,252, 93,159,231,224,224,224,224,224,248,167,193,127,219, 54, 40, - 48, 48,208,151, 82, 58,156, 16, 50,184, 44, 66,119,144, 16,178,251,206,157, 59, 38,101,160, 53, 51, 51, 75, 87,171,213, 14, 0, - 32,145, 72, 50,212,106,181,211,139,209, 82,224, 47, 75,100,208,210,159,169,122,192,170,167,167,103,186, 70,163,113, 48, 33,154, -120,153, 16,114,133, 97,152,203,117, 73, 47,208,181,107,215,209, 60, 30,111, 25, 0, 24,141,198, 47, 47, 94,188,248,219,223, 85, -207,132,144, 54,110, 10,167, 95,117,122,157, 33, 61, 51,103, 33,165,244,104,101,159,219,220,159,172,224, 19,204, 46,251,127,205, -228, 99,180,218,169,223,181,253,124, 53,229, 11, 20, 8, 4, 83, 29, 29, 29,123, 39, 39, 39,223, 1, 48,135, 82, 90,227, 49, 96, -229,226, 59, 82, 32, 16,140,208, 27,141, 94, 2, 30,239,153, 94,175,223,149,151, 18,181,147,187, 84,112,112,112,112,112,252,109, - 6,171, 93, 35, 91,111, 66,117,179, 5,132,118,210, 83,114,149, 18,225,154,176, 39,217, 49,175, 83, 0,133, 66,225, 70, 8, 9, -162,148, 54, 97, 24, 38,146,101,217,179,181, 93,236, 56, 32, 32,192, 13,192,135, 0,134,181,109,219,182,217,164, 73,147,208,176, - 97, 67,168,213,106,220,186,117,107,222,174, 93,187,230, 5, 4, 4, 60, 0,176, 7,192,222,240,240,240,164,170,180,212,106,181, - 67,185, 87, 34,132, 56, 12, 30, 60,248,214,139,166,170,108,113, 89, 66, 41, 13, 35,132,132, 26,141,198, 27, 7, 14, 28, 72,242, - 33,164,205,132,250,194,131,211,227,180,174,175,106,106, 52, 26,135,227, 51,167,128, 82, 22,234,236, 44,116, 88,185,161,226,189, - 83,189,218,130, 49,234, 33, 18, 11, 47, 7, 29, 11,187, 2,224,114,217,163,214,240,120,188,101,167, 79,159,118,166,148,162,103, -207,158,203, 0,252, 45, 6,139, 16, 34,110, 27,216,226,210,177, 67,123, 36, 69, 57,233,232, 53, 96,232, 46, 66,200,104, 74,233, -161,151,204, 82, 31,226, 72,248,152, 61,105,249,110, 30, 0,108,158, 63,124,206,250,158,100,227,140, 51, 52,205,197,197,165, 11, -165,116, 78,153,222,234,148,148,148, 75,155,251, 16, 71,240, 48,119,210,242,221, 4, 0,182,204, 31, 62,123,115, 31,178, 97,242, -201,218,205,146, 36,132, 76, 30, 61,122,244,198,101,203,150,241,156,157,157,145,146,146,210,203,215,215,215,155, 16,226, 75, 41, -173,114,112,176, 77, 61,191,125,189,122,245,246,252,112,200, 32,169,189,157, 53,146, 83,179, 44,126,223,181,123,130, 77, 61,191, -222, 57,137, 17, 67,185,203, 5, 7, 7, 7, 7,199, 27, 51, 88,205,154, 89, 90,153,169,232, 76, 51, 33,253,176, 87, 27,223,250, -253,187,183, 39,158,158,158,136,121, 28,227,117,233,250,237, 49, 93,124,204,159,171,116,100,175,202,140,172,125,240,160,250,245, -195, 70,251, 19,189,222, 88,250,155, 66, 62,140, 23, 51, 93,143, 4, 7, 7,215, 31, 59,118, 44,252,253,253,113,231,206,157, 46, - 7, 14, 28,152,238,230,230,118, 91,175,215,159, 20,139,197, 33, 53,229, 80, 9, 8, 8, 88,233,226,226, 50,103,214,172, 89, 36, - 48, 48, 16, 98,177,184,226, 61,185, 92,142,110,221,186,161, 91,183,110, 72, 79, 79,111,118,233,210,165,102,187,119,239, 94, 17, - 16, 16,176, 58, 60, 60,124,158, 41, 21,180,112,225,194,192, 74, 94, 62, 77, 8,137, 53, 24, 12,247,252,252,252,146, 26, 19,210, -112, 98,159,246,231, 38,119,104, 36,171, 38, 58,133,219,203, 74, 87,215,120,209, 96,209,146, 66, 8, 44,204, 47, 11,228,242,191, -152,171, 38,132,180,104,107,205,252,250, 83,142,209,175, 22, 38, 11, 73, 73, 73,176,180,180, 52, 11, 10, 10, 74, 37,132, 44,190, -116,233,210,182, 55,124,220,180, 89, 60,123,178, 48, 55, 62, 2,105,143,194, 48,115, 72, 71,233,140,239,255,252, 6,192,161,234, -141, 15,195,252,246,204,110,222, 12, 96, 58,203,178, 11,163,163,163, 59, 3, 64,147, 38, 77, 68, 0, 46,237,120,106,221,103,116, -147,252, 58,167, 89, 32,132, 8,121, 60,222, 15, 59,118,236,248,100,228,200,145, 72, 72, 72,192,181,107,215, 32,151,203,177,100, -201, 18,143, 89,179,102,173, 0, 48,189,170,200, 85,207, 94,125, 60,183,124,187,192,183, 48, 39, 95,179,245,135,253,183, 21,205, - 26, 51, 51,166, 77, 49,215, 26,116, 78, 86, 46,190, 35,185, 72, 22, 7, 7, 7, 7,199, 27, 49, 88,157, 26,202,110, 13, 12,104, - 16,208, 63,184, 61,211,168,177, 47,132, 18,105,197,123,205, 91,250,163,121, 75,127, 50,126, 76,161,231,253,251,247, 23,156,190, -124,115,126,167,134,178,240,171, 79,139, 91, 87,165,167, 55,130,191,123,247,110, 0,192,119,159, 15,231,253,112, 53,166,254,139, - 11,198,118,238,220, 25,157, 59,119,102, 86,172, 88,209,230,210,165, 75,109,246,238,221,171,115,113,113, 89,159,146,146,114,160, -154, 98,206, 57,112,224, 0,225,241,120,224,241,120, 85,126,200,209,209, 17,221,187,119,135,179,179, 51,249,252,243,207,231, 0, -168,212, 96, 73, 36,146, 12, 66,136, 3, 0,216,216,216, 24, 23, 47, 94,124,143,210,138, 30, 64, 74, 41, 13, 99, 24,230, 6,203, -178, 55,143, 30, 61,154,220,148, 16,135,126, 1,141,175, 78,254,104,176,148, 30, 92, 95,165, 57,208,228,229, 84,250,186, 72, 38, -189, 44,146,201,174,136,205,204, 94, 50, 87, 77, 9,113,109,219,184,254,217,205,159, 13, 55, 55, 49,138,231,221,165, 75, 23,137, -209,104, 68,113,113, 49,182,108,217, 98,105,102,102,102,217,187,119,239, 69, 0, 42, 12,150, 47, 33,205,223, 87,240,198, 47, 78, - 49, 76,169,131,129,177,234,212, 46, 48,254,251,149,139, 44, 2,219,118,194,147, 75,191, 35, 39,167, 16,249,121, 69,120, 53,235, - 55, 0, 76, 62, 73,211, 55,247, 39,107, 54,127, 49,124, 46, 97, 24,210, 98,224, 28,244,244,166,211, 20, 10,197, 67, 66,136,160, -124,249, 24, 66, 8,223,213,213, 85,225,237,221,114, 77,163,158, 62,216,242,229, 71,160,165,139, 52,174, 49, 53,122, 69, 8,113, - 48, 55, 55, 63,122,246,236,217, 54,173, 90,181,194,141, 27, 55, 16, 23, 23,135,201,147, 39,107,167, 76,153, 34, 28, 53,106, 20, -153, 57,115,230,167,132,144,131,148,210,235,175,126, 95, 32, 16,140,248, 96,208,123,162,162,188, 2,181, 86,163,211,218,216, 89, -177,154, 98,117, 73, 86,110,129,250,163,225, 35,180,247,238,132,143, 0,240, 23,131,245, 58,245,201,193,193,193,193,241, 47, 53, - 88, 18,158,177,213,226, 61,247, 97,204,137, 5,205, 79, 4, 45, 78,251,203,103,164,118,110,240,105,231, 8,169,149, 61, 19,249, -104, 93,171, 87,162, 54,213, 78,213, 44, 55, 87, 91,135, 43,154, 22,231,166, 10, 1, 64,102,237,172, 27,191, 43,229, 97,171, 86, -173, 96,111,111, 47, 12, 13, 13,157, 9,224, 64, 53,154, 68, 27, 25,142, 71,253,218,163,193,163, 28, 72,165, 82,136, 68,162,151, - 62, 16, 19, 19,131, 43, 87,174, 32, 49, 49, 17, 94, 94, 94,192, 43,227,168, 94,212, 84,169, 84,142,189,122,245, 10, 89,189,122, -117,231,239,190,251,238,193,142, 29, 59, 58, 87,213,173,228, 75,136,172,133,135, 83,200, 55,159, 79,176,166,167,126,101, 74,178, - 51, 32,172,162,156,237,151,173, 69,251,101,107, 1, 0,251,125,157, 33,177, 48,135, 68, 46,191, 28,124,230,206, 95, 34, 87, 1, -132, 88,120, 57,219, 94,220,180,120,186, 12, 23,247,137, 48,110, 73,181,245, 25, 16, 16,224, 29, 20, 20, 20,186,116,233, 82,171, -164,164, 36, 92,191,126, 29, 30, 30, 30, 40, 41, 41,121,105,189, 50, 95, 66, 28, 91, 55,118, 63, 59,127,214, 24, 75, 0, 83, 76, -217, 71, 47,153, 16, 30,239,155,111, 23,207,177,176, 20, 83,196, 94, 63,130,184,216,231,184, 21,245, 92,191,243, 92,132, 81,171, - 55,142,173,172, 62, 39, 31,163, 95,204,234, 38,254,245, 78,161,215,177,126, 93,166, 52, 90, 58,204, 17, 58,157,110,123,102,102, - 38,198,143, 31, 15,150,101,209,177, 99,199, 14,148,210,148,105,211,166,193,203,203, 11,219,206,196,148,240,115,110, 6,237, 10, - 45,184, 99,202,177, 68, 8,105,230,238,238,126,246,210,165, 75,142, 46, 46, 46, 8, 9, 9, 65, 90, 90, 26,156,156,156, 48,101, -202, 20,209,202,149, 43,119, 20, 20, 20, 12, 89,182,108,153,228,193,131, 7,123, 9, 33,110,101,166,185, 66,211,200, 26, 21,158, - 30, 10,249,161,189,103,238, 91,155, 75, 81,207,203, 77,200,147, 91, 24, 41, 72, 73, 61,103,123,161,145, 53, 42, 42,217,255,175, - 85,159,166,194,105,114,154,156, 38,167,249,111,208,252, 87, 25,172,114,116,113, 33, 16,249, 14, 2,216,166,160,185,177, 96, 11, - 82, 64,165, 14, 40,102,205,144,165, 76,192,163,171, 7, 64,117, 53,231,189, 19,240, 96, 88, 48,101, 56,223, 74, 2,136,204,237, -117,133,133,133,144,201,100, 40,206, 77, 21,206,250,182, 34,178, 37,188,116,233, 18,194,195,195,161, 80, 40, 76, 42, 35,213,150, -246, 34,106,181, 90,104,181, 90,164,245,105, 13, 89,219,119,144,251,209, 20, 92,184,112, 1, 25, 25, 25, 16, 10,133, 16,137, 68, - 48, 24,106, 78, 22,207,148,173, 26, 91, 30,181,170,236, 51, 65,132,240, 93,109,228,199, 54, 47,154, 94,159, 9, 59, 46, 80, 37, - 62,133, 82,109,132,149, 9,245, 41,150,203, 32,146,154, 93, 22,201,101,149,153, 43,129, 76, 46, 57,246,235,210,153, 78,188,187, - 23, 36,170,167, 17, 21,166,237, 69,186,119,239, 62, 1,192, 34, 74,105, 94, 80, 80,144,227,178,101,203,172, 83, 82, 82, 16, 21, - 21,133,253,251,247,103, 26, 74, 55,148, 80, 74,191, 6,128,118,132, 72,234,217, 91,157,217,244,213,116,115, 92,218, 39,194,199, -181, 79,174,110,217,164,255,137,247, 71, 77,154,178,113,122,127, 20, 23,170,176,251,220, 93,156, 14,143,125, 23,192, 53, 74,105, -149, 25,238,191,187,160,121,234,226,226,210,109,220,184,113,247, 14, 31, 62,108,247,237,183,223,194,104, 52,194, 96, 48,192, 96, - 48, 84,252,111, 52, 26,177,103,207, 30, 92,187, 19, 53, 77,169, 44, 48,105,189, 55, 66,136,162,126,253,250,231,111,222,188,105, - 47,149, 74,113,238,220, 57,228,229,229, 85, 68,174, 70,143, 30, 77,242,242,242, 62,220,178,101,203,251,241,241,241,223, 94,189, -122, 53, 27, 0, 15,128,225,229,125,206,143, 53, 24,244, 62,206, 77, 26,242,135,244,239,212,169, 40, 59, 2,114, 91, 63,132,221, -143, 61,150,155,155,167, 98, 24,126,236,139,159,127, 19,245,201,193,193,193,193,241, 47, 55, 88,234,251,187,160,137,220, 7,161, - 87, 23,136,154, 14,133,192,181, 29,146, 34, 67,112,239,228,119, 72,126,120, 13,148, 53,194,209,163,230,165,230,126,187, 75, 5, - 10,133, 34, 92,169, 84,226,238,221,187,136,141,141,133, 68, 34,249,203,231, 46, 92,184, 0, 0,112,114,114, 50,105, 35, 68,129, -237,225,118, 63, 21, 73, 45,156, 1, 0,110,247, 83, 1, 0, 43,230,207,135, 80, 40,132, 80, 40,172, 88, 20,214, 20,131, 69,202, - 62,204,150,118, 83,209,202,222, 15, 20, 11,118,239, 93, 52,181,181, 56, 62, 82,164,121, 16, 6,165,134,165,199,210,141, 39,124, - 77, 49, 88, 82,233,101,145, 92,126, 69, 40,147,189,100,174, 0,128, 10, 4, 59,127,255,122,170,159, 44,253,153, 76,125,251, 2, - 82,213,172,206,162,114,153,175, 79,157, 58,229,192,231,243,157,140, 70, 35, 18, 19, 19,241,240,225, 67,108,216,176, 33,189,176, -176, 48, 40, 60, 60, 60,230,133,242, 50,173,204, 68,251,119, 46,153,238,201,143,184, 44,209,196, 62,168,212,180, 85,135,125,243, -129, 61,223, 13,106,113, 98,194, 71, 95,226,189, 62, 61, 48, 42,200,151, 62, 87,230,168, 1,156,163,148, 26,107,250,126, 74, 74, - 74,138,139,139, 75,247, 65,131, 6,237,106,218,180,105, 19, 74, 41,124,124,124, 48, 96,192, 0, 28, 58,116, 8, 81, 81, 81, 40, - 44, 44,212, 93,189,122,117,189, 82,169,252,197,148, 50, 17, 66,164,214,214,214,167, 47, 94,188,104, 47,149, 74,113,246,236, 89, -168, 84, 42, 56, 59, 59,191, 20,185, 90,177, 98,133,228,249,243,231,155,206,156, 57,227, 1,128,169,108, 33,108,157, 65,179,237, -151, 29,123, 55,206,252,116,156,203,197, 27, 81, 23, 52, 69,133,150,238,238, 73, 5,246,214,114,243,101, 43, 86,213,211, 25,180, - 19, 42,175,207,144, 58,213, 39, 7, 7, 7, 7,199,191,220, 96,149,119, 49, 81,214, 0,237,211,115,208, 62, 61, 7, 89,151, 5, - 56,186,124,196, 75,159, 51, 26,245,117, 42,128, 90,173,134, 80,110,171,251,238,243,225, 66, 0, 96, 5,178,138,213,225, 89,214, -180,133,215,107,179,164, 87,109, 12, 86,153,238, 95,204, 67,125,177,252,242,182,207,134,180,181, 53,150, 8,180,215,142, 33, 69, -195, 26,190,125,170, 43,185,157, 71, 87,207,175, 66,243,120,247,214,208,231,102, 65, 98, 46,187,220,235,210,131, 74,103, 11,214, -151, 88, 92,216, 63,115, 88, 71, 39, 33,132,218, 19, 7,160,212,176,154, 31,227,245,191,108,168, 98,155, 41,165,136,139,139, 67, - 73, 73, 9, 66, 67, 67,113,232,208,161,204, 87,205, 85, 89,121, 67,126,158, 51,162,141, 69, 97,154, 80,123,251, 60,148, 26, 86, -227,109,138,169,242, 27,216, 65,200,144,179,132,225,153,245,233,228,139, 25,227, 6, 98,221,207,127, 26,180, 14,157,250,109, 60, -122,242,131, 34,141,110,190, 41,230,234, 5,147, 21, 1,192,215,195,195, 67,108, 48, 24,186,244,239,223,255,100,159, 62,125, 16, - 22, 22,134,243,231,207, 55,210,233,116,169, 0,160, 80, 40,150, 0,112,100, 24,102,117,114,114,242,179, 42,246, 17, 35, 20, 10, -247,158, 63,127,190,169, 66,161,192,249,243,231,161, 82,169, 48,105,210, 36,237,212,169, 83,133,163, 71,143, 38,249,249,249, 21, -145,171,208,208,208,236,170,204, 21, 0, 20, 36, 63, 58,101,237,214,180,125,151,206,237, 6, 54,106,212,208,226, 89, 97, 65,134, - 84, 42, 49,187,116,249,170,240,230,141,155,155, 10,146,163,111, 85, 94,159, 23, 76,174, 79, 14, 14, 14, 14, 14,206, 96, 85,139, - 49,231,175,109,158,209, 80,247,117,154,219,205, 61,243,208,204,204, 12, 91,182,108,129, 84, 42,173,181,113, 42, 57,117, 4, 73, -147,135, 87, 68,174,202, 35, 89,232, 53,250,181, 12, 22,203,178,161, 0, 94,114,121, 50,199,198,195,246,126,212,189,131,175,167, - 11,163,223,191, 1,201, 37, 6,245,162,199, 58,245,163, 66,250,110, 84, 37,131,167, 43,208,107, 33,145,149, 70,174, 42, 51, 87, -114, 39,239,247,119, 12,235, 18,212,162,113, 3,198,176,111, 45, 82, 74,244, 69,243,162,117,186,103,197,244,112, 21,166,114, 81, -143, 30, 61, 22,217,218,218, 74, 54,110,220,104,233,238,238, 14,131,193,160,125,213, 92,201, 28, 27, 15,219, 55,186, 87, 7,111, - 39,107, 70,127,240,123, 36,169,140, 37, 27,158,233,119,252,104,130,185,178,179,148,159,249,113,249,100, 51,169, 88, 0,181, 90, -141,149,155, 15,226,236,245, 7,253, 50, 35,143,156, 1,112,166,174,251, 91,167,211,125, 18, 28, 28,188,110,246,236,217, 48, 24, - 12,248,240,195, 15, 17, 31, 31,127,246,233,211,167, 27, 92, 93, 93, 63,159, 60,121,178,194,222,222, 30, 19, 39, 78, 20, 2, 24, - 93,133,204,170,221,187,119,247,107,209,162, 5, 46, 95,190,140,188,188, 60, 56, 59, 59, 99,234,212,169,162, 21, 43, 86,236, 40, - 40, 40, 24,178,124,249,114, 73, 92, 92, 92,181,145,171, 23,201,163,249, 75,127, 90, 55,241,243,214,109, 59, 48, 79,159,198, 24, - 18, 91,119,102, 46,156, 63,121, 37,215, 65,188,227,165,250, 28,211,187,214,245,201,193,193,193,193,193, 25,172, 26,163, 67,198, -194,191, 14,118,103,141, 38, 7, 50, 76, 54, 78, 70, 19, 53, 89,141,186, 38,195, 84, 43,131, 85, 54, 6,235, 52,165,244, 37,131, -101,229,212,184,243,130,185,211,215,119,124,191, 23,147, 62,174, 29,242,138, 52,154, 57, 81, 6, 54,185,164, 6,115, 5,128, 49, -234, 46, 11, 44, 44,174, 8, 95,153, 45, 8, 0,102,142, 13, 91,207,251,236,211,205, 93,135,245, 39,153,147, 58, 34, 55, 79,165, -249,252,161,129,164,168,232,144, 40, 74, 47, 85,166,119,225,194,133,173, 0,182, 6, 5, 5,165,203,100, 50, 20, 21, 21,253,165, - 94,203,203,219,225,253, 94, 76,250, 39,109,144, 83,172,211,204,121,104,128, 82,197,238,173,201, 92,217, 91,153,159,249,113,217, -100,169, 50, 57, 30, 66,161, 16,114,185, 28,231,174, 69, 34,243,193, 31,103, 94,231,128,115,117,117, 93, 60,109,218,180, 69,163, - 71,143, 70,110,110, 46,206,157, 59,135,174, 93,187,226,135, 31,126,112,191,120,241,226,186,246,237,219,131,199,227,225,220,185, -115,208,235,245, 79,170,216,159, 3,199,143, 31,255,249,251,239,191,143, 91,183,110, 33, 53, 53,245,165,200, 85, 94, 94,222,135, -155, 55,111,126,255,249,243,231, 53, 70,174, 94,196, 5,104,237,217,160,165,240,139,133,223, 65, 83,146,193,207, 76,185,113,249, -194, 57, 26,230,158,147, 35, 5,144, 95,215,250,228,224,224,224,224,224, 12, 86, 37,238,197, 8,190,179, 31, 12,169, 17,255,121, -233,149,217,132, 66,169, 28,172,177,102,227, 50,218,159,232,199, 52, 0,127,109,111, 6, 66,185,173,174,221,220, 51, 15,171,250, -172, 92, 46, 55,181,139,208, 40,236,243, 62,175, 65,207,247,240,172,185, 19,168, 94, 87, 17,201,194,252,249, 47,153, 44,161, 80, - 8,173, 86, 11, 84,210,237,247, 10, 55, 9, 33,241, 0,194, 40,165, 52,192,219,235, 27,137, 76, 54, 38,208,175,129,221,140,201, -159, 8,158,103,104,112,177,227, 23,121, 7, 87,205,149, 39, 81,249,148, 4,154,119,189, 6, 67,121,185,207,213, 71,127,137, 92, -249,123,123,125, 41,145, 74,198,181,109,230,237, 52,111,230,100,193,243,116, 13,185,216,122, 78,193,161,213,115,164,113, 48,255, - 60,137,230, 94, 50, 97,251, 23,245,233,211,103, 17,165,148,178, 44,187, 16, 0, 94, 44,239,204,169,227, 4,207,210,212,184,208, -241,203,220, 67,171,230,154, 39,161,250,242,218,251, 13,236,224,104,109,113,230,199,229, 83,164,169, 41, 9, 16,139,197, 48, 55, - 55, 71, 82,122, 62, 4,124,158,234,117, 14, 54, 15, 15, 15,113,155, 54,109,230,142, 26, 53, 10,209,209,209,152, 55,111, 94,170, - 82,169, 60,124,244,232,209, 73, 51,103,206,228,119,238,220, 25, 25, 25, 25,216,178,101,139,254,214,173, 91,203,211,210,210,214, - 84,122,208,242,249,159,124,243,205, 55, 84,169, 84,146,184,184, 56, 56, 59, 59,227,211, 79, 63, 21, 45, 95,190,188, 98,204, 85, -109, 34, 87,229, 36, 39, 39, 95,110,212,160, 30,222, 61,181, 30, 6,189,230,114, 94,118,226,149, 71,207,114, 47,219,136, 68,179, - 58, 6,248,213,169, 62, 57, 56, 56, 56, 56, 56,131,245, 23,244,148,201,223,189,114,162,229,187, 35, 38,193,204,227, 29,104, 30, - 30, 0, 91,152, 6,182,176,212,192,136,100, 22, 48,183,115, 67, 81,137, 26,215, 30, 60,131,158, 50,249,213,234, 25,193, 95,250, -195,127,102, 11, 90, 89, 89, 33, 63, 63,255,165,200,139, 84, 42,133, 66,161, 64, 65, 65, 1, 14, 30, 60, 8, 90, 67,100,136, 82, -250,205,168, 81,163,190,154, 60,121, 50,211, 96,216, 88, 20,221,184,250,106, 52, 10,102,102,102,144, 72, 36, 72, 78, 78,198,227, -199,143, 89, 74,233, 55, 53, 68,188,110, 26, 12,134,251,123,247,238, 77,110,228,229,218, 43,168, 85,235,105,243,191,152,103, 30, -117,245, 44, 22, 46,223,196, 54, 12,236,153,191,114,207, 31,133,249,242,122,221, 74,148,143,238,213, 84,201,132,144,191, 38, 17, -245,172,215,181,157,127,203,217, 11, 23,126,105,241,240,234, 57,124,181,250, 71,218,168, 69,112,254,234, 67, 71, 11,178,164, 30, - 61, 84,233,255, 25,243, 83, 29, 33, 33, 33, 91, 1,108, 45,127,254,106,121,231, 45,217,192,122,183,234,149,187,114,207,161,226, - 2,243,122,193,213,149,215,193,119, 80,123, 55,103,155, 51,223, 47,157, 40, 77, 75, 73,132, 88, 44,134, 92, 46, 71, 98,106, 30, - 22,173,223, 95,172, 99,217, 94,175,121,188,137,101, 50,153, 88,167,211,225,183,223,126, 67, 74, 74, 74,187,212,212,212, 68, 39, - 39,167, 31, 39, 78,156,184,177, 73,147, 38, 62,143, 31, 63,126, 82, 84, 84, 52, 37, 45, 45,237, 81, 85, 34, 86, 86, 86,237,236, -237,237, 73, 88, 88, 24, 38, 78,156,168,253,244,211, 79,133,163, 70,141, 34,185,185,185,117,138, 92,189, 16, 93,235, 60,160,111, -123,116,232, 62,233,178, 86,157,119,229,249,163, 29,151, 25,122, 93, 18,208,210,175, 78,245,201,193,193,193,193,193, 25,172, 74, -201,228,171, 28,126,220,121,104,205,222, 3,135,199,141, 31, 51, 92, 18, 20, 60, 18,194,172, 72, 24,148,225,112,241,237, 8,202, - 55,195,173, 59,119, 17, 17,155,164, 46,209,241,182, 23, 8, 85,179, 95, 49, 22,193,213,229,202,200,207,207,135,135,135, 7,246, - 76,106,220, 84, 83,144, 33,172, 7,128, 73,177,212, 93,140,233,243,240,202,149, 43, 69, 0,182, 55,106,212,232, 64,117,154,119, -239,222,253,186,101,203,150, 71,191,248,226,139, 21,141, 26, 53,234, 53,126,201, 15, 16,206, 24, 5, 85, 84, 4,164, 65, 67, 96, - 99, 99,131,236,236,108,220,186,117, 11,133,133,133,167, 41,165, 95,220,187,119, 47,178, 58, 77, 74,233, 13, 63, 63,191,228,122, -245,234, 89, 57,200,205,126,153,244,241, 40,243,132,136, 27, 72,143,185,143,235,215, 98,114,119, 31, 58,154, 82,144,159,249,113, -117,141,235,139,154, 12,195,188,100,174,188,189,237,228, 50,177,245,206, 41,227,199, 90, 36, 70,222, 66, 70,204, 61, 92,189,254, - 36,119,207,222, 35,153,217,217,233, 99,170, 50, 87, 53,213,103,101,229,189,113,245,113,238,222, 3, 71,146, 11,139,115, 63,169, -172,188, 47,106,202,101,130,217, 71,127, 91, 42, 85, 38, 39, 84,152,171,132,212, 92,124,181,126,111,177, 74,171,239,149, 25,113, -196,164, 72, 77,117,229,100, 89, 22, 6,131, 1,148, 82,136, 68,162, 2, 0, 40, 51, 83,221, 76,213,204,202,202, 10,137,143,143, - 31, 32,151,203, 43, 34, 87,249,249,249, 67, 86,174, 92, 89,171,200,213,171,229, 76, 78, 78,190,220,192,211,117, 85,234,208, 33, - 26,103,103,251,203,199, 78,221,142,116,144,155, 61,170,107,125,190, 41, 56, 77, 78,147,211,228, 52,255, 13,154,255, 42,131, 21, - 21, 69,117, 0,166,251,250, 90,124,189,250,199, 93, 91,118,238, 57, 56,112,252,136, 65,124,255, 22,221, 16, 23,122, 4, 87,110, - 92, 52,228,170,233,145, 66, 1,111, 82,212,211,130,220,154,126, 76,192,131, 97,248,240,225,124, 0, 16,241, 97, 88,219,175, 95, - 72,211,166, 77, 59,182,213,103, 8, 23,109, 44,141,108,125, 61,109,184, 48,228, 86,200, 1,177, 88,188, 53, 46, 46,174,192,148, -141, 40, 51, 76,189, 91,181,106,245,206,231,159,127,190,170, 79,125,215,214, 3,219,119,129, 64, 32,192,173, 91,183,144,157,157, -125,139, 97,152,185,119,239,222,189, 98,138, 94,100,100,100, 86,211,134, 30,211,109,204,132,179,167, 12, 31,104,159, 25, 27,133, -228,232,187, 0, 0,141, 70,165, 79,141,185,220,162, 54,149, 92,190,112,179,175,175,175,208,168, 41, 26, 45,225, 91, 44,156,244, -225, 0,135,236,231,143,144,244,176, 52,221,147, 70, 93,162, 75,138,185,232, 83,151,157,232,225,225, 33,150, 9, 48,161,210,242, -106,213,250,180, 39,209, 45, 77,209, 41,209,104,151,127,189,110,103,143,165,179,199,136, 45, 44, 44, 16,254,224, 41, 22,174,221, - 83, 43,115, 85, 19,148, 82,232,245,250, 90,205,252,172,132,185, 45, 90,180,104,188,108,217,178, 70,101, 99,185, 94, 43,114,245, - 34,177,113,201,243,130,130,130,124,159, 62, 14,239, 98, 99, 38,220,245, 58,245,201,193,193,193,193,193, 25, 44, 84,111,180, 10, -114, 1,124,224,239,106,225,181,108,211,174,237,102,124,182,163,202,192, 92, 83,105,152,113,119,147, 11,158,153,250, 99,191,221, -165,130, 87, 95,243,245,245,149, 61,229,163,168,252,249,211, 28, 64,169, 84,174,174,203,198,220,190,125,251, 10,128, 54,254,254, -254, 3, 79, 18, 50, 31,120, 6, 74,233,242,187,119,239, 30,169,141,142, 57, 31, 15, 58,250,122,185,116,242,111, 42,225, 25, 85, - 72,142,142, 69, 78,177, 26,231, 30, 38,228, 49,148,249,181,174,149,205,232, 74,238,119,242,109, 80,239,157,128,166, 82, 1,209, - 34, 57, 42, 28,249, 42, 45,206, 62, 76,200, 7, 33,117, 30, 40,253,166,202,155, 22,241,199,109,123,191,129,193,132,144,243,243, -167, 14, 19, 47, 90,187,247,141,154, 43, 27, 27,155,146,180,180,180,108,181, 90,109,155,158,158,174,181,177,177, 41,169,163, 73, -123, 74, 8,105, 62, 99,198,140, 37,159,127,254,249,236, 85,171, 86, 9,235, 50,230,170, 42,114, 83, 18,142,188,211,244,205,239, -127, 14, 14, 14, 14, 14,206, 96, 85, 74,153,153, 10, 10,242,181,151, 93,123,156, 89,252, 38, 10, 16, 21, 21, 85, 60,218,159, 84, - 68,182, 4, 60, 24, 94, 87,179,204, 80, 29,169,179, 0, 67, 10,111, 60, 73, 40,186,249, 36,161, 8, 44,165, 44,165, 26,134, 65, - 82,177, 78,183, 60,230, 89,114,221,103,209, 17, 98,188,253, 52, 81,117, 39, 54, 73, 77, 89,150,178,148,106, 9, 65,154, 94,207, - 46,127,240, 44,254,232, 63,161,188,153, 17, 71,174, 59,249, 14,234,116,253,230,131,153,197,197,186, 77,153, 81, 71, 66,223,212, -193, 22, 30, 30,174,119,118,118, 30,209,191,127,255,177, 44,203,254,152,146,146,162,175,171, 22,165, 84, 11, 96, 46, 33,228,112, -100,100,228,254,208,208,208,212, 55, 97,174,254,214,253,207,193,193,193,193,193, 25,172,234, 8,137,122, 51,230,170,156,202, 34, - 91,255, 77, 34,159, 60, 15,248, 59,116, 31, 60,121,222,236,127,161,188,105, 81,135,239, 0,248,240,239, 40,107,106,106,234, 89, - 0,103,223,148, 30,165,244, 54, 33,164, 62, 0,222, 27, 49, 87,127,227,254,231,224,224,224,224,224, 12, 22, 7,199,255, 12,180, -116, 64,151,129,171, 9, 14, 14, 14, 14,142,127, 10, 4, 64,112, 21,141,150,201,179, 3, 8, 33,193,117,104, 20,207,115,154,156, - 38,167,201,105,190, 37,154, 25,213,104, 62,168, 65,179,170,200,182,195,255, 80,125,182,172, 66,115, 85, 13,154,115,171,121,251, - 30,119,124,190,157,154,255,166,187,255,191,237, 1, 32,152,211,228, 52, 57, 77, 78,243, 95,160,217,140,171,207, 55,170, 57,151, -171,207,127,159,230,219,246, 96, 56,139,201,193,193,193,193,241,183,117,147, 16, 34, 38,132,136,235,250, 62, 7,199,255, 42,181, - 30,131,213,186,117,235,134, 0,112,235,214,173,167,127,227, 9, 57,213,217,217,121,188,159,159, 95, 19,161, 80,200, 20, 22, 22, -126,125,241,226,197,197,175,126,238,157,166,130, 59, 60, 6,174, 47,124, 19, 32, 60,128, 97, 96,164, 72,190,114,191, 36,144,219, -197,255, 93,156,157,157,207, 72, 36, 18,119,150,101, 97, 96, 41,140, 6, 99,233, 95, 35, 11,189,145, 66,167, 85, 39,104,138,243, -123,214, 73,187,229,160,122, 6, 35, 93, 9,176,155, 9,152, 73, 20,236, 22, 66,153, 73,148,193,102,194, 98, 34,248,250, 53, 48, - 8, 62,231, 11,249, 95, 42,195, 15, 36,189, 13,245,121,240,224, 65,222,235,124,127,240,224,193,149, 46, 19,229,239,239,127, 92, - 34,145, 52,168,234,123, 37, 37, 37,169,247,239,223,239,242, 54, 31,171, 78, 78, 78,239, 48, 12,243, 61,128,166,175,188,245, 8, -192,116,165, 82,121,225,117,127,163,181, 84,202,183,227,241, 38, 8, 8,153, 3, 0,122, 74, 87,103, 25,141, 91,111,149,148,252, - 99,198, 16, 58, 56, 56, 92,225,241,248,141,138, 75,138,139, 11, 11, 10,188,204,205, 45,158,153, 73,165, 50,163,193,248, 36, 43, - 43,227,157, 90, 94,203, 39, 3, 88, 83,246,255,108, 74,233,230,218,188,207,193,241, 86, 27,172,128,128, 0,111, 0,157, 9, 33, -157, 41,165,239,248,248,248, 56,150,148,148, 32, 32, 32, 32,157, 16,114,133, 82,122, 25,192,229,240,240,240,152, 55, 81, 32, 30, -143,247,237,134, 13, 27,102,125,250,233,167, 21,139, 52, 71, 68, 68, 84,254, 89, 6,174,151,142,157,119,184, 29, 25,131, 86,193, -131,203, 12, 22, 3, 20,167,162, 75,247,214,117,250,125, 27, 27, 27,115, 7, 7,135,175, 9, 33, 67, 24,134,169,177, 49, 99, 89, -214, 72, 41, 61,144,145,145,177, 40, 39, 39,167,176, 54,191,213, 42,208, 79, 95,234, 8, 43,131, 26,111,223,137,168,118,118,165, -143,143,207, 29, 30,143,231, 90,118,113,122,245,194, 86,233,255, 70,163, 49,249,225,195,135,129,166,214,133, 68, 42,157, 77, 24, -126, 48, 40, 91,154, 4,149, 48,143, 40,107, 56,175, 46, 41, 89, 99,202,246,138,197, 98,247,240,187,247, 26, 69,197, 60,131, 87, -253,122,208,234, 12,208,234, 12, 56,122,254, 22, 90,248,212, 71,255, 62,221,235,124,172, 24, 41,249,122,225,244, 17, 93,150,109, -216,221,234,203,233,195,101,203, 54,236,110,245,229,140,225,242,101, 27,119, 7,126, 57, 99,132,124,233,198, 93,129, 11,102,140, -176, 88,182,113,183, 14,192,199,117,249,141,143,155,187, 23, 51, 70, 67,165,119,215, 44,143,175,249, 57, 50, 65,246,223, 56,113, -199,142, 29,235, 93, 92, 92, 28, 53,182, 95,235,111,154,120, 56, 86, 58,254, 39, 47, 59,221,225,201,131, 91, 11,249, 18,153,239, -123,179,127,169,246,252, 20, 10,133,158, 87,174, 92,105,196,178, 44,140, 70, 35, 12, 6, 67,197, 95,173, 86,139,247,223,127,255, -141, 76,136, 9, 12, 12, 28, 75, 41, 93, 86,122, 88,146,165,119,238,220,217,244, 26, 55, 98,114, 62,159,255,153, 72, 36,234,108, - 48, 24,154, 0,128, 64, 32,136,214,104, 52,151, 13, 6,195, 58, 74,105, 81,109,244, 24,134, 89,127,251,246,109, 95,185, 92, 14, -157, 78, 87,177, 48, 60,143,199,243,105,211,166,205, 15, 0, 26,189,238,246,219,241,120, 19,218,119,236,184, 97,236,140, 25,188, -220,219,183,241,253,246,237,235,145,155, 11, 0, 63,212,244, 93, 87, 87,215, 59,132, 16,215,218,252, 30,165, 52, 57, 57, 57, 57, -176,118,215, 96,126,163,132, 36,165,131,187,155, 2, 0, 32,149, 74,101,183, 31, 60,119, 8,104, 90,191,214,145, 43, 0,107, 40, -165,102,101,245,187,161,125,251,246,237, 8, 33, 6, 0,148,101, 89,134, 16, 50,140,101, 89,126,217,231,215, 16, 66,126,161,148, -106,184,166,153,227,173, 54, 88, 1, 1, 1, 39, 1,116,246,241,241, 49,235,222,189, 59,252,253,253,225,238,238, 14,137, 68, 2, - 0,200,201,201,113,140,138,138,250,224,222,189,123, 31,132,133,133, 33, 32, 32, 64, 5,224, 90,120,120,120,165,209,136,224,254, -157, 62,149,200,197, 27, 1, 32, 51, 57, 59, 53, 57, 46, 99, 99,106,106,234, 26, 74, 41,251,194, 9,233, 53,106,212,168,153,211, -166, 77,195,241,227,199,177,103,207, 30,104, 52, 26, 20, 22, 22,226,226,197,139, 85,220, 90,103, 32,247,226, 74, 64,246, 28, 72, -188, 12, 72, 29, 0,153,227,235,220,189,125, 61,116,232,208, 25,255,199,222,117,135, 69,113,181,223,115,103,182, 23,122, 95, 80, - 81, 16, 21, 84,164, 40,246, 30,187, 81, 99,139,189,151, 88,163,137, 49,198,196,154,216, 75,140, 93, 99,141,189,247, 22,123, 23, -176, 34,130,130, 74, 89,122,103,217, 58, 59,243,251,131, 18, 36,148,133,248,125,201,247,203,158,231,153,103,119,103,102,207,220, -185,115,231,222,115,223,251,222,247,250,248,248, 20, 69, 29, 55, 24, 12, 96, 24, 6, 6,131, 1, 25, 25, 25,152, 49, 99, 70, 97, -229, 5,150,101,113,245,234,213, 41,179,102,205, 2,128, 47, 75,227,252,164,141,103, 48,143, 16, 55,246, 15, 81, 22,119,249,102, - 84, 32, 64,232, 71,193, 79, 72,233,226,171, 17, 93,113, 69, 72,187,133,134,134, 58, 10, 4, 2,147,238,141,101, 89,248,251,251, -155,116,174,171,171,107, 59,153,220,114,255,103,131,198,216,248,249,251,241, 93, 93, 92, 96, 96, 24, 68,191,141,105,242,228,113, -136,223,165,211, 7,199,186,186,186, 14,138,143,143, 47,119, 65,106,163,145,197,147,176, 72, 92,185,253, 24, 61,249, 98,168, 52, - 58,168,212, 58,236, 57,117, 23,113,201, 89, 85,126, 78, 65, 65, 65,174, 82,218,161,201,148, 81,189,101,203,127,217, 45,155, 50, -170, 55, 86,172,223, 83,240,185, 91, 54,101, 84, 47,172, 88,191, 75, 62,101, 84, 47,252,188,113, 71,211,160,160, 32,215, 7, 15, - 30,196,151,197, 87,214, 51,162,140,140,104, 91, 88, 60, 13, 0, 41,155, 55,195,144,156, 12,197,188,121, 0,128,177, 62,174, 38, - 15,107, 52,104,208, 32,152,199,227, 85,216, 56, 50, 12, 19,247,252,249,243, 64, 83,196, 21,195, 48, 28,143,199,251,254,246,111, -139,142,180,240,171,243, 65,102, 70, 68, 68, 88,253,240,195,247,253, 14,133,228,112, 3, 2, 44,194, 78,172, 24, 85,174,200, 98, - 89,150,210,106,181,136,140,140, 44, 53,202, 62, 69, 81,198,170, 60,167,182,109,219,138, 84, 42,213, 62,185, 92,238,171, 82,169, - 70,113, 28,247,195,245,235,215,157, 40,138, 66,199,142, 29,127, 8, 12, 12,124, 43, 22,139, 55,170,213,234,199,114,185,124,208, -245,235,215, 77,106, 92, 9, 33,173, 45, 45, 45,247, 28, 63,126,220,198,223,223,159, 74, 77, 77, 69,205,154, 53,145,158,158,222, -228,230,205,155, 1,163, 71,143, 30, 77, 8, 25,198,113,220,205, 74, 36,183,174, 84, 42,229,134, 15, 31, 78,140,198, 63,110,247, -215, 95,127, 69,128, 75,146,231,132, 46,178, 60,141,142,203,250, 61,210,106,130, 64, 32,184,253,238,221,187, 74, 23, 96, 62, 33, -179, 70, 77,159, 78, 11, 18, 18, 32,139,136, 64, 15, 66,120, 91,243,173, 89, 27, 76,184,103,183,213,235, 86, 56, 10,133, 66, 48, - 12, 83, 36, 2, 11,235, 40,131,193, 0,189, 94, 15,131,193, 0,163,209, 8,131,222,128,109,155,119, 84,249, 29,147,202,164, 82, -103, 23,151, 36,137, 84, 38,253, 24,141,141, 72, 36,226,237,222,189,123,144, 80, 40, 4, 0,232,116, 58, 52,104,208,128,152,155, - 97, 51,254,141, 22,172,174,215,175, 95, 7,195, 48,176,176,176, 0, 77,211, 37,173, 27,104,221,186, 53,130,130,130,208,177, 99, - 71,188,122,245, 74,178,108,217,178, 50,205, 17,131,103,246, 64, 53,175,124,225, 99, 48,176, 46,119,206, 62, 94,250,235,162, 35, - 14, 0,102, 22, 55, 24,140, 31, 63,158,164,165,165,161,127,255,254, 55,181, 90,237,167, 28,199,149,185, 92,142,145, 69, 92,187, -207,135,128,229,136,100,205,131,109, 68,167, 81,115, 20, 69,169, 11,135, 8,171,216, 43,238,175, 80, 40,112,224,192, 1,232,116, -186, 63, 29,183,180,180,196,139, 23, 47,138,139, 28,248,249,249,209,132,144,254,101, 9, 44,138, 16,183,243,215, 95, 23,205, 8, - 26,248,169,159,160, 83, 27,207, 36, 30, 37,228, 0,144,239,190,251,174, 72,176, 1,192,130, 5, 11, 76, 78,175, 64, 32,192,171, - 87,175, 64,211, 52,222,180,200,239, 96, 55, 8,141, 5, 77,211,120,226,155,223, 3,109,254, 58, 19, 52, 77, 67, 46,151,155, 42, -174,218, 58,185,184,157,248,118,222, 18, 11,141,129,195,217,171, 15, 17,163,188, 12,142,227,224,226,104,139,230, 1,254,252,250, - 13, 27, 57,254,186, 97,249, 9, 87, 87,215, 94,241,241,241,215,203,226, 50, 48, 70,120,123,213,194,238,227, 55,177,120,227, 81, -164,101,171,145,147,151,159,175, 29,154,250, 96,123,213, 45,157, 43,234,186,187, 87,219,121,232, 2,154, 53,109,140, 93,135, 46, -162, 89, 80, 99,228,255, 14,194,174, 67, 23,208,188, 89,254,103,125,111,207,234,233,239,178, 86,160,156,216, 94,127,122, 70,189, -242,159, 81, 77, 90, 80,212, 0,188,155, 56, 17, 0,138, 4, 86,165, 94, 52, 30,207,237,241,227,199,142, 21,157,231,231,231,103, -146,229,138, 97, 24, 36, 39, 39,147,204,204, 76,206,218,218,186, 95,113,145, 85, 40,174, 14, 6,103, 67,125,127, 61,249,237,212, - 13,118,200,167,109,194, 78,172, 24,229,211,175, 95,191,151,165,241,234,245,250,183,157, 58,117,226, 10, 26, 62, 87,161, 80, 40, - 40, 33,192, 20, 45, 90,180,248,147, 64,171,104,232, 80,165, 82,237,219,186,117,107, 31, 79, 79, 79,124,246,217,103,151,124,124, -124,132, 82,169, 20, 23, 46, 92, 64,181,106,213,236, 45, 44, 44,206, 45, 89,178, 4,171, 87,175,174,126,233,210,165,253, 0,250, -152,240,142,118,108,215,174,221,129, 51,103,206,136, 5, 2, 1,212,106, 53, 94,188,120, 1, 43, 43, 43, 8,133, 66,244,234,213, -139,110,209,162,133, 93,219,182,109,143, 18, 66, 6, 85,102, 70,147, 70,163,225,230,204,153, 3,169, 84, 10,169, 84, 10,153, 76, - 6,153, 76, 6,137,128, 37,155,167,213,148, 76,221,154, 41,249,114,222,230,165,123, 54,206,191, 86,189,122,245, 31, 98, 98, 98, - 50, 43, 91, 22, 50, 30, 61,130, 44, 34, 2,154,224,224, 74,151, 35, 43,153, 45,102,207,158, 93, 81, 89,131, 64, 32, 64,243,230, -205, 43,228,243,246,246,222, 76,211,180,195,135, 98,154,208,223,127,247, 45,243,252, 69,132, 76,111,228,100, 26, 45,131,197, 11, -191,103,104,138,162, 27, 52,104,112,156,227,184,148, 23, 47, 94, 76, 48,193,122,166, 37,132,124, 77, 81,212,207, 34,145,136,231, -238,238,254,254,251,239,191,191,151, 63,212, 0,112, 28, 71,185,187,187, 55,145, 72, 36, 53,180, 90, 45, 3,224,107,179,245,202, -140,127,139,192,130, 92, 46,199,163, 71,143, 64, 8,129,133,133, 5, 44, 45, 45, 97,101,101,133,236,236,108,132,133,133, 33, 60, - 60, 28,239,222,189, 3, 33, 4, 30, 30, 30, 40,124,113,138,189, 96, 69, 21,219,190, 85,103, 32,150,139, 64, 8,224,223,222, 23, -190,173, 27,160,241,195,168,105, 10,133, 98,171, 82,169,140, 36,132,240, 26, 52,104, 48,186,105,211,166, 88,189,122, 53,180, 90, -237,234,210,196, 85,113,206,155, 47, 12,129, 0,160, 80, 40,190,218,123,225,141,116,104, 23,207, 60,165, 82,185,178,178,153, 80, -178, 2, 78, 77, 77, 5,203,178, 38, 91,133, 50, 51, 51,203,229, 44,105, 17, 88,188,116,141,117, 78, 86, 18, 22, 45,219, 11,131, -193,128,153, 51,103,130,101,217,162,173, 52,190,210,210, 89, 56,244, 71,211,244, 7, 2,184,162,223,229,113, 58, 56, 56,200, 68, - 98,233,254,175,190, 91,100,241, 52, 34, 14,103,174, 62, 4,199,113, 56,185,245, 7, 0, 64,175,113, 11, 17,159,152,138, 22, 1, -245, 48, 98,194, 12,139, 53, 63,205,217,239,224,224,224,153,146,242, 71,240,217,226,156, 6,134,197,209, 11,247,160, 76,203,197, -240,207, 58, 64,163,213, 35, 37, 57, 17, 59, 54, 44,199, 23, 35,142,194, 70, 46,113,246,240,240,136, 40,158, 71, 28,199, 17,129, - 64,112, 59, 34, 34, 98, 76, 89,233, 52, 24, 12, 93,191,157, 49, 22, 63,111, 59,138, 6,181,157,113,250,242, 93, 4,214,175,129, -243, 87, 31,162,105,195,154,184,120, 35, 4, 77,125,107,225,198,253, 23,152, 62, 97, 24,190,158,118,187,107,101,158,209,143, 75, -214, 88,231,100, 39,225,204,143,187,145,188, 97, 3,222, 79,158,140, 38, 5,231, 60, 36, 4, 2, 55, 55,192,162,226,252, 44,137, -151, 47, 95, 66,171,213,150,214,187,135,183,183,119,133,207,168,208,114,149,148,148, 68,146,146,146, 32,147,201,200,203, 23,207, -141,222,245, 27,244,227,194,143,108, 3,128,124,203, 85, 54,242,238,174,131,250,222, 47, 16,212,124, 74,109, 91, 56, 65, 55,246, -135,205, 97,197, 26,183, 15,210,249,228,201,147,162,252,105,218,180,105,248,237,219,183,235, 22,150,175,130,161, 66, 1,195, 48, - 94,133,195,134, 12,195, 64,171,213, 98,208,160, 65,116,121,247, 46,145, 72,124, 61, 60, 60, 16, 18, 18,130, 9, 19, 38, 8,219, -181,107,135,215,175, 95,131, 16,130,145, 35, 71,194,199,199, 7, 41, 41, 41,104,220,184, 49,110,221,186,229,103, 66,153,183,144, -201,100, 59, 78,159, 62, 45,166, 40, 10, 57, 57, 57, 96, 89, 22, 45, 90,180, 0, 69, 81,120,254,252, 57,190,251,238, 59, 28, 59, -118, 12, 39, 78,156,144, 4, 4, 4,236, 32,132,120,115, 28,151, 99,194, 51,226, 52, 26, 13, 39, 18,137, 32, 18,137, 32, 22,139, - 33, 22,139, 33, 20, 10,161,214, 83, 24,183,230,189,150, 22,219,179,245,253, 90,122,142,156,250, 19,181,242,251, 81, 87, 1,156, - 44,224,124,110, 74,125, 97,224,184,229,235,183,111, 95,215, 29,249, 19,140, 14,231,228,176, 6,142, 91,110,202,187, 9, 0,185, -154, 44,212,240,112,195,209,131, 39,208,119, 96,239, 82,197, 21,159, 47,128,128,207,135,165,173,172, 66, 78, 62,159,111, 31, 26, - 26,106, 93,188,126, 96, 24,230,229,148, 41, 83, 60,122,247,234,238,116,232,216, 25,122,232,192, 94, 70,103, 39,135,212,216,216, -247,175, 1, 88, 7, 4, 4,112,166,150,121,142,227, 54,250,249,249,249, 31, 63,126,124,212,236,217,179,131,191,250,234,171, 69, -197,143,175, 88,177, 98,225,185,115,231,106,244,233,211,103,207,227,199,143, 55, 22,251,223,178,143,221,216,253, 39, 66, 7,152, - 57,205,168,178,192, 42,222,248,100,103,103, 35, 59, 59, 27,177,177,177,216,188,121,115,193,139,204, 7,143,199, 3,143,199, 43, -242, 87, 40, 11, 87, 78,223,250, 5,192, 47, 1, 1, 1,252,103,247, 14,159,159,181,117,106,135,192,142,254,116,200,239,207,250, - 1, 88, 12,160,235,240,225,195,237, 1, 96,247,238,221,169, 0,206,255, 29, 25,194,113,220,225,200,200,200,233, 46, 46, 46, 69, - 62, 40,197,135, 9, 25,134,129, 88, 44, 70,161,175,138, 86,171,197,190,125,251, 24,142,227, 14,151,151,127, 17, 47,174, 34,242, -197,181,252,255,177, 44, 88, 99,254,255, 53, 26, 13,230,207,159, 95,124,234, 43, 38, 78,156, 8, 84, 98, 45,228,178, 44, 87,205, - 34, 51,192,227,241,112,171, 86,190, 18,232,150,194,253,201, 87,235, 79, 67, 24, 66,241,204,110,159, 13,177,101, 56,186, 72, 92, -229,223, 67,190,224, 20, 10,120,144,136, 4,136,136,138,129,187,107, 0, 58,116,235,109,115,229,204,209,153, 0, 74, 53,187,233, -141, 44,186,182, 13,192,134,131,215,145,157,171, 70, 86, 70, 58, 82, 98, 94,226,229,211, 71,224,241,120, 8, 14, 14,182,176,180, -180,178,168, 85,171, 38,140, 44,139, 59,247,130,193,129,224,244,169,227, 30, 53,106,214,194,251,183,209, 99,202, 16,182,188, 22, -129, 62,200, 77,139, 3, 77,211,104,238,231, 9,154,166,209, 42,176, 14,104,154, 70,203,198,117,193,227,241,208,182,169, 15,106, -215,174,141, 66, 63,143,242,159,209,239,136,124,113,189,152,216,229,192, 1,208, 39, 36,252,185,161, 76, 72, 0,103,225, 88,217, -178,133,111,190,249, 38, 51, 33, 33, 65, 95, 82,208, 41, 20, 10,193,177, 99,199,172, 43, 90, 4, 91, 38,147,249,240,120,188,176, -244,244,116, 86, 42,149, 82, 44,107,100,189,235, 55,160,111,255,182,232, 72,225, 57, 11, 23, 46, 58, 50, 32,192,178,223,222,195, -103, 56,129,123, 75, 66,248, 34,102,236, 15,155,133, 60,177,204,199,196, 78, 3,165,213,106,241,234,213,171, 10, 23,229,230, 56, -174,220, 2,165, 82,169, 70,244,237,219,247,210,196,137, 19,197,132, 16,220,186,117,171, 72,240,211, 52,141,168,168, 40, 80, 20, -133,173, 91,183, 66,171,213, 78, 52,193, 18, 56,253,232,209,163, 86, 66,161, 16, 57, 57, 57, 69,239, 13, 77,211, 8, 15, 15,199, -202,149, 43, 49,124,248,112,196,196,196, 64,161, 80, 96,230,204,153,242,165, 75,151, 78, 7,176,208,132, 91,127,170,211,233, 2, -165, 82, 41,196, 98, 49, 10,133, 22, 0,132, 36, 56, 61,143,142,142,110,104,111,111,239,236,112,227,204,169,230,237, 62,109,100, -231,224,210,172, 80, 96,153,138, 24,131, 97,171, 82,165,154,219,127,199, 14,199,155,167, 78,177,207, 79,157,138,227, 25,141, 91, - 76, 46, 67, 6, 10,239,163,226, 16, 16, 16,128,144,144, 16, 4, 4, 4,124, 96,205, 22, 10,133, 16, 8, 4, 16, 8, 4,176,183, - 49,201, 85,130,163,105, 26,137,137,137, 31,236, 27, 55,110,220,251, 33, 67,134, 56, 2, 64,130, 50,142,251,114,250,148,248,212, -212, 84,206,201,169,124,206, 70,141, 26,221,164, 40,202,189,132, 40,182, 25, 63,126, 60, 50, 51, 51,187, 77,156, 56,177,101,190, -149,140,138,223,176, 97,195, 80, 0, 16, 10,133, 85, 30,130, 54,195,140,255,121,129,101, 10, 42, 18, 88,133, 8, 9, 9, 49,184, -186,186,110,139,124,252,174,131,167,175, 7, 36, 50, 81, 39, 66,200, 47, 34,145,104,198,176, 97,195,112,255,254,125, 60,127,254, -252,215,191,186,236, 73,195,134, 13, 47,138, 68,162, 26,165, 29,211,106,181,239,159, 61,123, 86,170,175, 88,114,114,242,188,135, - 15, 31,162, 60, 39,247, 1, 3, 6, 20,111,140,138,156,220,203,172,193, 88, 14, 6,189, 1,170, 60,245, 31,141,119,129,192, 82, -169, 84, 24, 56,112,224, 7, 22,172,228,228,228, 42,221,115,101, 44, 87,101,129,162,233,206,190,141,252,249, 87,239, 62,253,160, -113,237, 61,126, 49, 68, 2, 30,164, 34, 1,196, 34, 62, 36, 34, 1, 98,227,147, 80,175, 94, 3,193,141,139,103, 58,151, 37,176, - 12, 12,139,229,191,158, 5, 0, 28, 62,125, 21,129, 53,165, 88, 48,247, 27,244,239,223, 31, 66,161, 24, 71,143, 30,198,202, 13, -187, 49,161, 70,254,163,106,210,216, 15, 43, 54, 29,192,162,133, 11,168,195,135, 14,183, 52,161,193, 5,143,199, 3, 77,211,127, -250, 44,252,110,138, 53,146, 99, 57,232, 75, 62, 35,150, 3, 56, 14,110, 63,254, 8,183, 31,127,196,195, 2,113,234,163, 82, 65, -173, 86, 3,109,125, 43, 37,174,116, 58, 29,148, 74,165,254,201,147, 39, 78,165, 52, 76, 73, 58,157,174, 66, 65,179, 99,199,142, -136, 81,163, 70,249,216,218,218,134, 61,125,242,196,224,219,168, 17,191,164, 15, 86,157, 58,117,178, 22, 46, 92,116,100,104,255, - 30,253, 54,127,251, 57, 51, 97,225, 30,158, 41,142,238, 69,162, 88,175,127,219,177, 99, 71,147, 36,190, 90,173, 78, 44,235, 88, - 96, 96,224, 40, 66,200,143,117,234,212, 17,181,107,215, 14, 55,111,222,196,143, 63,254,200, 50, 12,147, 10, 0,205,155, 55,119, - 88,180,104, 17, 9, 11, 11,131,181,181, 53,146,147,147,119, 5, 6, 6, 46, 42,207,241, 93, 40, 20,182,109,220,184, 49,165,213, -106,255, 36,174,150, 46, 93,138, 65,131, 6,161, 78,157, 58, 96, 89, 22,185,185,185,104,215,174, 29,127,221,186,117,109, 77, 17, - 88, 20, 69, 77,235,208,161,195, 74,228,207, 34, 44, 46, 28, 95, 2,248,186,192,186,157,216,163,239,240, 23,173, 58,126, 22,232, - 94,187,129, 75, 69,156, 78, 78, 78,223, 82, 20, 53, 0, 0, 13, 32,150,178,181,173,237,224,224,224,212,186, 71, 15,228, 18, 66, -111,185,112,129,240, 36, 18, 57, 0,147,134, 26, 53, 6, 21,106,120,228,187,242,245, 29,216, 27, 33, 33, 33,232,247,121, 31, 8, - 4, 2,240,120,124, 8,248,124,240, 5,249, 22, 44,107,123,203, 42,213, 35, 5,157, 71, 98,101,101, 5,112,128,165,149, 85,161, - 37,147, 0,224, 40,138,226,202, 41,231, 94,123, 39,143,115, 20, 88, 90,129,101, 12,168,254,105,191,162, 50, 29,185, 99,163, 4, - 44, 43,201,141,121,139,105,215, 30,242, 97,134, 25,102,129,101, 26,138, 59,133,150,134,246,237,219, 79,177,176,176, 88, 87, 80, -241, 34,246,126, 60, 98,239,199,195,187,110,253, 22,254,141, 2,179, 6, 13, 26, 4, 59, 59, 59,124,245,213, 87, 28,128, 95, 43, -123,253,168,136, 23,114, 0,156, 66,161,248,170,192, 34,208,232,225,195,135, 14,143, 30, 61, 66,227,198,141,139, 55, 30,104,217, -178,236,118,187, 96,102,220,151, 40,195,159,170,138, 86, 49,232,245,122,228,229,169,161,211,233,193, 24, 88, 48, 12,131,128,250, - 22,216,179,117,118,254, 62,166,208, 90,150,111, 37, 19, 9,180,104,211,180,154, 1,132, 82,223,184,247,190,220,154,178, 52,203, - 21, 77,211,184,237,145,255,183, 78, 9, 6,147,133, 22,199, 26,235, 58, 59, 57, 33,230,194, 3, 0,128, 92, 42,198,197,221,139, - 32,147,230, 79,110,232, 54,124, 14, 36, 34, 1, 36, 34, 62,244,122, 61,156, 28,107,130, 49, 26,234,150, 41,188, 13, 58, 93, 13, - 39, 43,184,116,107,138, 39,143,238,225,203, 41, 99, 49,106,212,104, 8,196, 22,184,113,227, 26, 98,148,201,120, 29,151,129, 41, -243, 54,194,192,176,208, 51, 70,232, 13, 70,172,221,117, 22,122, 35, 87, 97, 35, 47, 16, 8, 48,115,230, 76, 73, 89,199, 15, 28, - 56,160, 54,253, 25, 25,160, 82,169,161,213,106,161,215, 49,208, 27, 24, 24,107, 9,176,104,238, 96, 48,122, 6,121,159, 55,131, -222,192,128,157,222, 7,122,157, 1,177, 82, 30,213,178,177,194, 0, 80,234,219,143,226, 44, 43,226, 47, 20, 5,229, 9, 48, 83, - 80, 40,178,124, 27, 53, 10, 27,209,189,201,210, 59,247, 30,165,220,185,247,232, 79,231,121,212,111, 18, 61, 97,201,129,217,149, - 17, 87,192,135,195,133,127,177,220,255,112,253,250,117, 39,185, 92,142,136,136, 8,208, 52, 13, 66, 72, 90, 72, 72,136, 19, 0, -204,159, 63, 63,149,207,231,219,209, 52,141,233,211,167,131,199,227, 57,124,241,197, 23,223, 3, 88, 95, 78, 71,206,219,194,194, -226, 3,235,149, 64, 32,192,236,217,179, 49,116,232,208, 34,113, 37, 16, 8,176,107,215, 46, 4, 6, 6, 66,167,211,121,155,146, -222,184,184,184, 71, 0, 90,153, 32, 64, 72,129, 40,175,176,124, 82, 20, 53,226,201,196,137,181, 53, 15, 31,226, 11,150,245,169, - 91,183, 46, 52, 26, 77,209,113, 79, 79,207,234,113,113,113,137, 10,133,226, 55, 0, 27,149, 74,229,227,242,248, 12, 26, 22,239, -163,226, 10, 59,171,104,210,164, 73,145,197,170,184,245, 74, 32, 16, 64, 34,148, 87,250,153,177, 44,139,236,236,108,122,215,174, - 93,181,124,124,234, 19, 0,240,246,174, 79,206,158, 61, 87, 93, 46,151, 71,219,218,218,234, 43,124, 39, 45,173,112,101,244, 64, - 0, 64,255,246, 93, 10,173, 88, 8, 94, 52, 7, 60, 62, 31,141,102,204, 1,240,176,232,124,157, 78, 7,150,101,105,152, 97,134, - 89, 96,149,241,226, 27, 12,229, 30, 95,189,122, 53, 26, 54,108, 88,110, 3,180,110,221, 58,236,221,187,119, 53,199,113, 81,149, -189,126,143, 14,254,245,177,230,248, 11,143, 58,249,149,194,194,233, 61, 41,149, 74,133, 59,119,238,192,202,202, 10,175, 95,155, - 22,182,235, 63, 17,166,129,227, 0,189,129,129, 42, 79, 3,157, 78,135,233,179, 76,154,153, 78,244,186, 28, 94,247, 46,173,203, - 20, 15,133,195,125, 20, 69, 85,232,131, 85,209,208,224, 7, 22, 12,131, 1,133, 77, 71,110,158, 6,237, 7,127,139,135, 39,215, - 2, 64,190,184, 18,243, 33, 17, 10, 32, 17,242, 64, 17,128,160,108,110,131, 58,251,211, 53,139,102,221,218,244,235, 30,183,222, -173,199, 98,202,228, 41,224, 9,165,176,177,115, 0,195,114,168,174,112,196,155,248, 12, 28,253,101, 86,193,168, 40,135,214, 67, -230, 99,245,220,177, 88, 49,175, 98, 35, 38,143,199,195,250,245,235,213, 37,173, 86,197, 63,185,138,219,193, 63, 4, 86,158, 26, -106,141, 22, 95,125,187,209,244,103,212,185,149,196,148,147,203, 19, 80, 21, 9,176,210, 68,150, 41,239,111,163,222,152,251,119, - 86, 48, 44,203,226,236,217,179, 69,207,163,172,103,104,170,181,149,101, 89,188,127,255, 30, 47, 94,188, 64,211,166, 77,145,149, -149, 5, 62, 69, 97,230,179,103,240, 25, 54, 12, 58,129, 0, 44,203, 66, 40, 20, 98,252,248,241, 38,231,103, 37,149, 99,129, 31, -155,177, 92,114, 23, 23,151, 85,245,234,213,171, 29,149,145,129,144, 39, 79,208,100,220, 56, 0,192,237,219,183,139, 91, 0, 49, -120,240, 96, 97,116,116,244,232,240,240,240,209, 46, 46, 46,171, 19, 18, 18,102,150,249, 62,113,218, 34, 31,172, 1,131,251,162, -118,189, 90,216,187,115,127,209,241, 25, 95, 79, 3,159, 47, 0, 95,192,135,181,149,117,165,111, 45, 59, 59,155,183,106,213,106, -223,160,160,166,146, 33,195, 70, 82,122,134,195,162,101,107,233, 67,251,247,216,237,222,179, 87, 34, 22,139, 95, 86,248,140, 12, -250, 63,213, 83,132, 16,240,248,124,240,132, 2,128,101,193,113,156,108,197,138, 21, 11, 95,188,120,209,184, 94,189,122,208,106, -181,195, 8, 33,161,230, 56, 88,102,252,171, 4, 22, 77,211, 21, 90,167, 40,138,170,112,136,112,198,140, 25,176,176,176, 40,171, -225,225,158, 61,123, 22,150,144,144,176,149,227,184, 42,197,197, 57,243,123,232,139, 5, 95,246,201, 1,160, 6, 0,107,107,235, -212,246,237,219,231, 2,208, 31, 58,116,232,131,115,181, 90,237,251,178,120, 28, 29, 29, 23, 44, 95,190,124,106,215,174, 93, 41, -138,162,254, 84,185,151,220, 12, 6, 3, 78,159, 62, 61,117,201,146, 37, 40,203,234, 85,216,120,231,169,212, 80, 23, 56, 56,191, -121,126,196,212,202,188,194, 83,158, 54,114, 45,213,114,245,137, 82, 15,154,166,113,222, 49,255, 62,186,165, 84,204, 69, 40, 58, -226,237,251,216, 38,206,246,214,200,200,202,133, 72,200,135, 68,244,135, 53, 95, 34,206,183, 94, 73, 68,124,216, 88, 91, 32, 45, - 45, 9,124, 62, 63,162, 28,225,240,158, 16,210,106, 96,159,110,151, 40,154, 39, 46,126,140, 47,177,148, 94,190,243,204, 38, 41, - 93,133,226,198, 0,150,229, 48,117,209, 78,211, 10, 48,143,135, 73,147, 38,149, 41,112, 78,157, 58, 85,105, 11,150, 90, 83,201, -103,100, 34,127,121, 67,128, 21, 29,175, 8,133,179, 11,101, 50,153, 79,129,248, 50, 25,141, 26, 53, 58, 47,149, 74, 77, 14,114, -100,106,208, 81, 66,200,194,246,237,219,255,232,230,230,230, 56,113,226, 68, 66,211, 52, 2, 3, 3,237,127,248,225,135,172,124, -203,136,183, 69, 97, 29,179,102,205, 26,188,124,249, 50,133, 16,178,168, 60, 78,161, 80, 24,110,101,101, 21,216,174, 93, 59,100, -101,101, 33, 54, 54, 22, 50,153, 12, 62,171, 86,225,217, 23, 95,160,209,230,205,160,218,183, 7, 33, 4, 66,161, 16,207,158, 61, -131, 68, 34, 9, 47,139,207,213,213, 53,136,203,119, 50,111,129, 63,134, 5, 57, 0,119, 8, 33,179,226,227,227, 31,148, 82,223, - 81, 0, 96,100, 89,174,130,251, 31,252,237,183,223,130,146, 72,224,210,172, 25,212, 81, 81,208,235,245,104,218,180,105,145, 85, -189,105,211,166,160,105, 26,181,107,215,134,173,173, 45,142, 29, 59, 54, 24, 31,206,172,254, 0,154, 92, 61,222, 71,197,161, 89, -179,102, 69,150,170,238,221,187, 23, 89,176,248,124,126,145, 37,139, 24, 43, 22,172,132, 16,174, 68, 93, 76,132, 66,129,104,248, -200,209,212,172,175,190,100, 13,140,129,165,105, 62,245,213,220, 37,212,235, 87,207, 69, 42,149,138, 34, 21,244,214,170,247,234, -143,254, 29,242,141,160, 71,107, 59,128, 46, 16, 86,189,158,199, 21, 61, 23,203, 51,191, 11,151, 46, 93,218,175, 94,189,122,249, -195,237, 0,207, 28, 7,203,140,127,147,192,138,124,242,228,137, 87,253,250,245, 17, 19, 19,243,167,153,109,133,239,152, 76, 38, -131, 68, 34, 41,180, 16, 69,150, 69,118,245,234,213, 95, 0,252, 82,248, 91,161, 80, 52,107, 55,160,237,221, 38, 93, 26, 99,223, -146,253, 89, 9, 9, 9,190,133, 49,177, 8, 33, 68,161, 80, 12,229, 11,121, 3, 61, 26, 84,111, 3,150, 93,126,229,212,237,249, -229,221,136, 71,157,250,185, 0,212,197,102, 17,174,172, 74,134, 16, 66,250,119,237,218,149, 10, 11, 11,195,192,129, 3,177,119, -239,222, 50,207, 29, 58,116, 40, 14, 28, 56,128,206,157, 59, 83, 75,151, 46,237, 95,145,192,202,183,142,232,254, 99, 15,179, 52, -203, 85, 73,145, 88,161, 16, 96,153, 43,207, 30,135,248,249, 6, 54,231,191,139, 75,130, 88,200,131, 88,244,199,140,125, 73,129, -255,149, 68,196,135,179,131, 13, 30,222,189,174,103, 24,195,149, 10,196,197,123,148, 18,164, 81,100, 97, 31,241, 73,139,134, 54, -165,253,103,213,183,195,208,240,224,170, 10,211,203,231,243,177, 99,199, 14,117, 89,214, 43, 83,243, 32,223,202,104, 64, 94,158, - 26,121,106,205, 71,123, 38, 78, 78, 78, 14,142,142,142,155,172,173,173,197,165, 9,168,146,199,255,138,184, 42,136,139, 21, 54, -106,212,168, 74,137, 44,161, 80, 88,243,206,157, 59, 69, 65, 70,203,251,212,233,116, 24, 48, 96,128, 73,150,239,224,224,224, 29, -254,254,254,111, 28, 28, 28, 46,251,248,248,136,222,188,121,131,197,139, 23, 19, 62,159,111, 89, 88,127,228,228,228,128,166,105, -100,100,100,128, 16, 50, 34, 56, 56,248, 66,121,156, 90,173,246,198,141, 27, 55,252,122,246,236, 73,135,135,135,131,166,233,252, -116, 53,107,134, 70,155, 55,227,249,151, 95,162,205,187,119,208,232,245, 16,139,197,184,120,241,162, 62, 47, 47,239, 70, 57,247, -190,245,222,189,123,245,197, 98, 49,244,122, 61, 88,150, 5, 69, 81,132,199,227,181,244,241,241, 89, 7,160,113,137, 14,152,227, -248, 25,203,234, 26, 25,198,152, 16,243, 38,197, 4,139, 16,246,238,221,139,166, 77,155,162, 77,155, 54,136,143,143, 71, 84, 84, - 20,186,117,235, 86,116,206,147, 39, 79, 16, 26, 26, 10, 79, 79,207,138, 45,120,148, 1,158,117,107, 66, 32, 16,128,207,231, 67, -192,207,255,204,223,242, 45, 87, 2,190, 0,124, 30, 31, 98,137,216, 68,237,255, 97,153,180, 42,176,124, 73,165, 18,182,118,237, -218, 97,175,223, 68,249,128, 3,101,105,105,101,146,175,109, 33, 31, 33,164, 72, 92,241,133,130, 34, 75, 22, 0,100,101,101,105, -122,247,238,253,155, 86,171, 29,137,143, 56,146, 98,134, 25,255, 43, 2,171,219,152, 49, 99, 54,119,234,212,169,195,204,153, 51, - 33,151,203,145,144,144, 80,244,130, 9,133, 66, 84,171, 86, 13,121,121,121,184,121,243, 38, 50, 51, 51,175, 2, 24,111,234,133, - 19, 18, 18,238,191,126, 28,153,214,174, 95,115,187,250,205,235, 90,199, 70,198, 53, 5,112,183, 64, 92,253, 58,104, 70,183,145, -237, 62,107, 2,129,144,143,216,215,137,255,181, 12,161, 40,138, 38,132, 96,224,192,129, 38,157,255,249,231,159,227,198,141, 27, - 40,111, 56,177,200,130,149,167,129, 74,253,241, 58,103,132, 16, 24,141, 70, 52,141, 72,255, 96,102, 86,161,229,170, 80, 88,152, - 98,185, 42,234, 33,231,229,173,184,117,229,228,184,122, 13, 26, 57, 52,245,243,194,235,232, 56, 44,159, 51,182,232,248, 87, 19, - 6, 97,215,193, 83,112,117,182,135, 38, 47, 7, 23,206,157,206,202,206,206, 94, 81,213,123,216,125, 34, 63, 14,100,171,193, 31, -206, 17, 24,248,229,207, 38,253,159,207,231, 99,228,200,145,101, 90,176, 46, 95,190,172, 54,101,120,148,227, 56,232,117, 6,228, -170,212, 80,231,125, 28,129,165, 80, 40, 26, 53,109,218,244,242,150, 45, 91,236,236,237,237,161, 84, 42, 63, 16, 88, 10,133,162, - 81, 80, 80,208,229, 45, 91,182,216, 57, 56, 56, 32, 54, 54,214,228,240, 32,165,136, 43,164,164,164,144,140,140, 12,214,198,198, -166, 82, 34,139,162, 40,104,181, 90,188,124,249,210,212,119,196,228, 25, 95,114,185,124,231,146, 37, 75, 68,201,201,201,160,105, - 26, 47, 95,190,252,160,172, 22,110,223,126,251, 45,230,204,153,179, 9, 64,141,242,248, 24,134, 89, 61,116,232,208,209,241,241, -241, 54,142,142,142, 72, 72, 72,128, 80, 40, 4,199,113, 32,237,218,161, 85,116, 52,244, 70, 35, 36, 18, 9, 34, 34, 34,176,117, -235, 86,149, 86,171, 93, 93, 26,151,167,167,167,144,162, 40, 47,129, 64,128, 33, 67,134,124, 88, 46,119,239, 70,179, 26, 25,129, -227, 62, 17,229, 50, 16,107,147, 36, 93,207,211, 52, 77,198,127,181,188, 78, 80,235,238, 13, 94, 61,127,240, 38, 37, 41,238, 78, - 5,183,111,208,233,116,168, 87,175, 30, 30, 61,122,132, 43, 87,174,160,125,251,246,104,221,186, 53,174, 95,191,142,224,224, 96, -132,134,134,130, 16, 2, 59, 59,187, 66, 55,139,114,125, 45,116,121, 12,146,149,105,127,178, 86,149,252, 45, 16, 8,160, 85,235, - 77,122, 70,197, 69, 19, 33, 4,182,182,182,218,181,107, 86,136,228,114,185, 17, 0,228, 50,169,241,208,238, 13,176,183,179,213, -114, 38,154, 88,139,134, 5, 11,196, 21,205,231,127,224,166,192,113, 92,206,211,167, 79,199, 17, 66,158, 18, 66, 10,235, 15,115, - 28, 44, 51,254, 29, 2, 43, 36, 36, 36, 26, 64, 71,127,127,255,193, 55,111,222, 92, 61, 99,198, 12,135,150, 45, 91, 34, 61, 61, - 29, 53,106,212,128, 66,161,192,163, 71,143,240,228,201,147, 84,142,227,102, 6, 7, 7,239, 45,229, 37,235, 88, 86,172, 12,142, -227, 56,133, 66,113, 88,155,155,251, 69, 64, 27,111, 92, 61,116,107,137,139,139,203,120, 87, 87,215,233, 35,230,244, 26,217,182, -119, 99, 68,132,190,197,253, 75,207,144, 20,147,138, 17,173,102,149,203, 89,210,201,221,218,218,122,180, 84, 42, 21, 2,208,151, -210, 11,254, 96, 22, 97,113, 78,150,101,141, 58,157, 14, 7, 15, 30, 52, 73,100,237,223,191, 31, 26,141, 6, 44,203, 26,203,186, -119, 35,203, 18, 30, 95, 4, 69,181,122,208,235, 85, 96, 89,211, 39, 72,114, 21,228, 39,195, 48, 88,176, 96, 1,190,254,250,107, - 44, 90, 84,246,232, 10,143,199,195,134, 13, 27, 80,209, 51, 74, 79, 79,207, 81, 40, 20, 67, 15,108,255,249,200,144,177, 83, 45, -220,154,251, 98,231,161,243, 48,232,245, 16,137,248,176,177,148,161,118, 77, 55,232, 52, 42,108, 94,191, 38, 91,163, 86, 15, 45, -233,123, 86,222,115, 47,137,225,189, 91, 99,233,214,147,184,181,239,143, 73,136,173, 6,207,195,111, 43, 38,195,223,127, 71,185, -156, 70,163, 17, 60, 30, 15, 7, 14, 28, 80,151, 54,123,144,166,105,240,249,252, 50, 45, 88, 31, 62, 35, 35,225, 11,196,168, 86, -195, 7, 58,109,238, 71,121, 70,118,118,118, 95,111,223,190,221, 78,163,209,224,213,171, 87,120,249,242, 37, 8, 33, 69, 42,166, -240,120, 94, 94, 30,158, 63,127, 94, 40,112, 94, 86,230, 61, 42,180, 92,165,164,164,144,132,132, 4, 72,165, 82,234,233,211,167, - 26, 95, 95,223,176,242,222,239,226,156, 90,173,246, 93,135, 14, 29,202,178, 24,185,138, 68,162, 15,102,124, 21, 6, 29, 45, 57, - 84, 88, 90, 58,243,242,242,158,173, 94,189,186, 86,227,198,141,177,101,203, 22,157,133,133,133,112,198,140, 25, 28, 77,211,100, -237,218,181,200,200,200,208,205,158, 61, 91,120,235,214, 45,168, 84,170,199, 21,221, 59,199,113, 57,132,144,113,205,155, 55,223, -125,225,194, 5,169,151,151, 23,178,179,179,193,113, 28,118,237,218,133,201,147, 39, 67, 44, 22, 35, 34, 34, 2,159,126,250,105, - 94, 94, 94,222,184,226, 49,176,138,115, 50, 12, 67,248,124, 62,199,178, 44,190,255,254,251,162,160,162,133, 65, 70, 37, 2, 35, -182,206,240,144, 77,219,150, 37, 27,252,195,182, 97, 0, 96,100, 24,227,171,231, 15,222,236, 90,255,195, 53,129, 64,112,179, 24, -103,131,146,177,176, 8, 33,223,253,244,211, 79,155, 90,180,104, 33,145,203,229,240,242,242,194,157, 59,119,112,231,206, 29,220, -186,117,171,176, 12,192,214,214, 22,153,153,153,136,141,141, 85, 19, 66,190, 43, 47, 63,133, 82, 62, 60,234,212,204,159, 45, 88, - 96,177,226, 23,155, 61, 88,220,154, 37,224,243, 43,124,223, 75,186,119,216,218,218, 50, 1, 1,254, 97,106,181,154, 46,212, 82, -246,246,246,207, 11,206,229,170, 85,171,166, 43, 81,228,255,196, 25,185,125, 3,130, 23,127,151, 63, 44,248, 44,182, 72,108, 93, -251,196, 31, 60,129, 0,213,122,244, 45,222, 14,108, 36,132,236, 40,248,174, 45,198,249,205,199,142,133, 85,153,122,201,204,249, -247,112,254,155, 44, 88, 0,128,208,208,208,125, 13, 26, 52, 56,191,116,233,210,165,199,143, 31, 31, 59,117,234, 84, 98,105,105, -137,195,135, 15,115,105,105,105, 59,133, 66,225,215,247,238,221,203,168,202,197, 57,142,219,121,253,216,221,137,195,103,247, 38, - 51,214,142,104, 25,252,251,243,240,134,205,189,208,176,185, 23,130,175,134, 97,253,156,253,123,141, 6,227,247, 9, 9, 9, 49, - 21, 80,105, 59,182,168, 91,210,201,221,238,198,181,223,237, 42, 59,139,144,227,184,195,199,143, 31,159,218,173, 91, 55,234,225, -195,135,127,242,185, 42, 92, 30,135,101, 89, 92,190,124, 25,122,189, 30,135, 15, 31,102,203,139,131,197,130, 59,185,121,227,138, -225,155,183, 31, 19, 10, 5, 4,247,110, 30, 69, 86, 70,249, 86, 57,129,128,143,223,246,159,212,243,120,244,171,114,210,250, 62, - 52, 52,212,110,249,242,229, 52, 33, 4, 27, 55,110, 4, 69, 81,101, 58,180, 63,127,254,156, 53, 24, 12, 21, 62, 43,165, 82,121, -217,217,217,249,243,141,171, 23,236,106,215,185,151,181,119, 61, 31,158,163, 99,117,240,104,130,140,180, 84, 4,223,191,197, 92, - 56,123, 50, 83,171,213,142, 80, 42,149,151,255, 74, 1, 92,178,229, 68,169,251,251, 78, 93, 93,145, 21,133, 49, 24, 12, 60,153, - 76, 6,134, 97, 74, 13,213,208,190,125,123,201,157, 59,119,212,122,189, 30, 52, 77,151,171,152, 88,224,163, 63, 35,163,209,232, -157,145,145, 1,149, 74,133,144,144, 16,110,253,250,245, 41,153,153,153,115,138, 31, 79, 79, 79, 71, 78, 78, 14,130,131,131,185, - 45, 91,182,164,100,103,103,207,169, 76,254, 21,198,197,202,200,200, 96,165, 82, 41,101, 48, 24, 12,190,190,190, 98,153,204,180, -152, 87, 0,240,248,241,227, 46,101, 29,107,209,162, 69,228,157, 59,119,106, 27,141,198,226,107, 20, 10, 52, 26,141, 87,175, 94, -189,120, 38,164,111,240,165, 75,151,246,221,186,117,171,161, 86,171, 29,157,156,156,188, 27, 64,117, 30,143,135,215,175, 95,167, -232,116,186,190,223,125,247,221, 78,149, 74,245, 76, 46,151, 15, 54,177,222,184, 64, 8, 25,226,237,237,189, 99,193,130, 5,242, - 54,109,218,240, 20, 10, 5, 26, 55,110,140,136,136, 8,156, 61,123,214,176,113,227, 70, 85, 94, 94,222, 40,142,227, 46,151,211, -233,224, 0, 16,134, 97, 32, 20, 10,139, 54,145, 72, 4,129, 64,128, 60, 29,133, 49,171,162,212, 12, 36,234,213,243,199,157,229, - 0,146, 24, 27,149,154,156, 24,251,128, 16,114, 83,169, 84,102,149,101, 25,211,104, 52,126, 28,199,241,178,179,179,215,106,181, -218, 17, 51,102,204,112, 89,190,124, 57,124,125,125,145,154,154, 10, 91, 91, 91,184,184,184, 32, 55, 55, 23,209,209,209, 70,189, - 94,191,217,104, 52, 46, 76, 74, 74, 42,119,216, 49, 51, 53, 27,110,206,213, 63,176,116,114, 28, 7,206, 8, 24,180, 70, 24,245, - 28,116,196, 0, 62,223, 0, 19,151,208,226, 24,134, 65,143, 30, 61,112,230,204, 25,244,238,221,155, 3, 80,166, 21,233,204,153, - 51, 21, 15,185,179, 44,248, 34, 33,120,130, 63,134, 5,243,173, 89,249,251, 40,242,167,231,105,182, 90,153,241,239, 20, 88, 5, - 13,115, 38,128,241,141, 27, 55,222, 61,101,202,148, 51, 44,203,242, 89,150,237,254,248,241,227, 91,127,229,226, 9, 9, 9, 33, - 10,133,226, 91, 39, 55,155,165, 93,135,182, 68, 93,191, 26, 48, 50, 70,220, 57,247, 24, 59,127, 58,113, 32, 62, 54,126, 68,241, -181, 10,203,126,159,217,107, 45, 2,235, 82, 0, 4,197,134, 95,216,170,204, 34, 76, 78, 78,158,183,120,241, 98,252,248,227,143, -149,158, 69, 88,214, 57,119, 31,197,143,111, 22,232,226,246,121,223,246,157, 41, 66,113, 90,157,182,156, 94, 1,184, 66,175, 8, - 30,143,126,117,227,126,172,111, 89,231, 38, 38, 38,118,152, 56,113,226,239, 20, 69,213, 40,110,154, 47, 11, 70,163, 49, 33, 45, - 45,173,147, 41,249,144,152,152,120,222,205,205,173,206,141, 11, 39,191,189,125,229, 92, 91,163, 81,239, 73, 64, 32, 16, 8,222, - 24,140,204,117,131, 78,183, 36, 46, 46, 46,227,175, 22,192,111,199,247,198,123,101, 42,120, 60, 58, 63,176,103,193,227, 62,186, -110, 6,252,253,127, 43,243,127, 34,145,232,252,142, 29, 59,122, 12, 31, 62,156, 20,250,157,113, 28,247, 65,133,254,224,193, 3, -181, 78,167,195,206,157, 59, 57,137, 68, 82,110,224,218, 15,159, 17,225,180,229,248, 67,153,250,140,114,115,115, 71,245,234,213, -107, 23, 0, 17,128,215, 89, 89, 89, 19,148, 74,101, 92,241,227,189,123,247,222, 5, 64, 68, 8,249,211,113, 83, 80, 24,178,193, -198,198, 38,172,192,114, 37,174,138,163,123, 57,229,155, 46,107,248,208,148,161,194,130,181, 5, 63, 43,252, 29, 24, 24,184,112, -226,196,137, 69,139, 61,135,134,134,222, 6,224, 81,133,206,217,101, 66, 72,253,239,191,255,254, 75,177, 88,220, 46, 47, 47,175, - 78,129,160,139,208,106,181,215,212,106,245, 26,142,227,202,141, 45,245,230,205, 27, 93,173, 90,181, 34, 24,134,105,224,224,224, - 0, 30,143, 87, 36,178, 0,224,126,140,109,112,124,124,124,227,202,166,237,220,185,115,238, 54, 54, 54,157, 8, 33,253, 56,142, -171,155,147,147,163,253,225,135, 31,238,222,184,113, 35, 59, 60, 60,188, 75,171, 86,173,136,179,179, 51,222,190,125,203,229,230, -230, 30,161, 40,234, 59,165, 82, 25,101,194, 61,199,237,220,185,179,178,249, 84,110,121,210,233,116, 41,247,238,221,179,189,114, -229, 10,109, 52, 26,113,225,194,133,162,142,100,105,163,129, 81, 81, 81,208,233,116,229,142,161,235,179, 50,224, 59,237, 27,112, - 5,179, 57, 11, 81,189,123, 95, 16,112,224,116,102, 61,101,198,191, 3,228, 63, 50,141,185,146, 38, 68,133, 66, 49, 80, 44, 19, - 77,170, 81,199,197, 87, 25,149, 28,150,147,149,183, 55, 33, 33, 97, 11,199,113,198,170,114, 86, 38,208,168,217,204,251,247,112, - 10,165,150, 23, 9, 45,168, 81,102,227, 96,212,191,215,229,101,119, 46,141, 51, 40, 40,200, 85, 32, 16,172,208,106,181, 93,203, -139,210, 78,211, 52, 35,145, 72,206,107, 52,154,175, 75, 46,246,252,191,152,159, 71,142, 28, 41, 85,244,155, 58,139,176, 95,191, -126,198,202,164,179, 81,163, 70,215,164, 82,105,169, 1, 53,243,242,242, 98,158, 60,121,210,233,159,144,159,133, 51,219, 76,241, - 17, 42,206, 89,149, 89,132,101,112, 22, 13, 17,186,187,187,139,244,122,189, 63,128, 58, 0,172, 1,164, 27, 12,134, 11, 41, 41, - 41, 73,206,206,206,129, 20, 69,125, 95, 32, 94, 23, 37, 38, 38, 6,255,157,239,166,155,155,155,216,210,210,114, 5, 69, 81, 46, -166,252,159,101, 89, 93,114,114,242,140,212,212,212,196,210, 56,235,215,175, 31, 76,211,116,133,139,154, 27,141,198,184, 23, 47, - 94, 4,150,147, 78,243, 16,225,191,144,243, 95,105,193,250, 79, 67,169, 84, 30, 4,112,240, 99,114,150, 21,169,221,140,127, 14, - 10,197, 83, 85, 80, 32,150, 62,255,183,229, 89,161, 64, 42,101,255, 75, 0,228, 99, 95,207,148,112, 12,255, 4,112, 85,236, 41, - 22, 8,168, 86, 31, 51, 45,239,222,189,211, 2,184, 91,176,125,128, 2, 65,213,243,159,146,111,113,113,113, 26, 0,147, 63, 22, - 95,121,162,201, 12, 51,254,109,160,204, 89, 96,134, 25,102,152, 97,134, 25,102,152,241,113, 65, 0,116, 44,163, 71,104,178,233, -143, 16,210,177, 10, 61,206, 43,102, 78, 51,167,153,211,204,249,255,132, 51,185, 28,206,231, 21,112, 54, 40,227,144,227,255, 80, -126,250,149,193,185,172, 2,206,111,202, 57,252,216, 92, 62,255,127,114,254,107, 80,232,204,248,159,216, 0,116, 52,115,154, 57, -205,156,102, 78, 51,167,153,211,204,105,230,252,183,109,230, 33, 66, 51,204, 48,195, 12, 51,204, 48,195,140,143, 12,147, 5,150, -220,217,219,219,193,189,209, 46,219,106,190, 79,109,171,249, 62,117,112,111,180, 75,238,236,237,253,111,204, 52,133, 66, 33,113, -113,113, 25, 92,189,122,245,203,126,126,126,217,174,174,174, 95,154,139, 82,229,209,150, 16,222,231,132, 76, 26, 78, 72,204,112, - 66, 98, 62, 39,100, 82, 91, 66,254,223, 45,155,177, 96,154,162,217,173, 11, 67,206, 47,152,166,104, 86,234,241,175, 20,118, 15, - 46, 15,248,121,201,100, 87,219,143,113, 61, 66,136,133,147,147,211, 86,103,103,231,119, 78, 78, 78,239,157,156,156,118, 16, 66, -172,204, 37,206, 12, 51,204, 48,227,191, 7,147, 26, 51,219, 26, 13,199,120,215,171,251,245,226,249,115,136,179,163,189,148, 49, -178,250,183,239, 98,125,230, 45, 94,122,196,182, 70,195,213,233,239,159,109,175, 66, 35, 64,220,220,220, 6,242,249,252, 30, 0, - 10,133,218, 75,131,193,112, 38, 46, 46,238,160,169,179,130,124,125,125,111,211, 52, 93,189, 50,215,102, 89,246,221,147, 39, 79, - 90, 87, 37,195, 92, 93, 93,251,187,186,186,238,104,218,180,169,212,207,207, 15, 2,129, 0,203,151, 47,159, 9, 96,141,201,247, -222,182, 45,207, 49,211,118, 24,205,227,245, 4,224,203,113, 0, 8,253,148,213,235,206, 37, 11,108,119,113, 33, 91, 12,166,240, -184,184,184,204, 33,132,140, 64,254,180,242,237, 74,165,114,197,127,162,144, 40, 20,138,106,132,144,118, 28,199,213,163, 40,234, - 25,203,178,151,148, 74,101,218, 95,229,117, 2,198, 55,111,217,242,231,225, 51,103,210,234,155, 55,241,243,142, 29,107,145,157, - 13, 0, 27, 42, 91,150,130,130,252,250, 89, 88,160, 7, 1,252, 65, 64, 40,112,143,211, 51,169,115,143, 30,133, 30, 52, 37,150, - 90, 89, 8, 8, 8, 56, 11,160,112,225,184,115, 33, 33, 33,221, 43,203,145,245,134,155, 43,234,233,221, 42,235,205,181,185, 0, -186,150, 60,206,104,196,195, 57,186, 90, 15, 53, 23, 26, 11, 96,213, 95,201, 83, 66,136,212,193,193,225,233,201,147, 39,221,154, - 52,105,194, 3,128,224,224,224, 97, 61,122,244,104, 95, 16, 74, 32,251,239,168,104,154, 53,107,102,195, 48,204,110,154,144,166, - 44,203, 90, 3, 0, 69, 81,153, 70,142,187,207,227,241,134, 87, 53, 88,177, 25,102,152, 97,198,255,172,192,146, 59,213,243,169, - 95,223,123,230,133,227,187,171,101,166,103,106,126, 89,185, 59, 68,197, 19,230,121,249,120, 9,126, 89,179,194,102,210,180, 25, -211,229, 78,245, 30,228, 38,133,135,153,122, 81, 23, 23,151,234,238,238,238,199,230,204,153,211,160,101,203,150,124, 71, 71, 71, - 36, 37, 37,225,213,171, 87, 13,238,220,185,211,251,196,137, 19, 51, 93, 92, 92, 62, 51, 33,130, 59,100, 66, 65,173,131,203,151, - 56, 11,173,172,193, 25, 25,216, 52,240,203, 31,255,100, 89, 36,222,184, 2,163, 94, 15,142, 53,194,173,203,167,133,226, 10, 65, - 65, 65,130,170,100,150,155,155,155,162, 78,157, 58,123,103,207,158, 45,208,233,116, 8, 13, 13,197,189,123,247,216,228,228,228, -165, 38,139,138,134,125,124,156,121,206, 71,122,245,238,234,222,253, 19, 71, 97, 13,103, 7,112,172, 24,225,209,250,234,151,111, -133,118, 57,123,254,226, 44, 71,159, 62,125,147,195,142, 63, 43,143,167, 65,131, 6, 77, 41,138,250, 49, 62, 62,190, 80, 4, 45, - 15, 10, 10,250,161,248, 57, 37, 53, 42,203,178,224,241,120, 73,121,121,121, 3,159, 63,127, 30, 90, 26,239, 8,127, 98, 48, 24, -243,203,133,128, 7,227,213, 20,183,227, 29, 59,118,172, 57,106,212, 40,248,251,251, 35, 56, 56,184,221,225,195,135,167, 85,171, - 86,237,145,193, 96, 56, 39, 18,137,174, 23, 76, 75,175, 52, 4,192,172,225, 51,103,210,242,119,239, 32,127,242, 4, 67,178,179, -121,203,128, 89,149, 17, 88, 1, 1, 1,181, 58,117,244, 63,210,251,179, 54,222,206,206, 62, 2, 62,223, 30, 28,199,193, 96, 72, -175,147,146,242,178,159,149, 21,102, 55,105,210,164,239,195,135, 15, 77,138, 52,219,184,113, 99, 39,150,101, 55,115, 28, 39, 32, -132, 76, 1,208,237,194,133, 11, 48, 26,141,232,222,189,123,183,128,128,128, 90, 28,199,253, 34,151,203, 57,181, 90, 61,250,209, -163, 71, 73,229, 89,174,178,223,112,115, 19,137, 71,151,186, 1,195,145, 72, 46,116,153,209,213,229,188,165, 39, 89, 60,239,103, -229, 61, 0,232,234,233,105,225, 81, 79,246,141,220,178,161,109,118,252,149,111,186,122,122,110, 59,255,230, 77, 78, 85, 58, 44, - 5,229, 96,197,158, 61,123,170, 5, 5, 5, 21,197,203,242,243,243,163, 87,172, 88,225,250,229,151, 95,174, 5, 48,210, 68, 81, - 93,199,206,206,238, 34,203,178,218, 23, 47, 94,212, 41,220,239,216,232,179,230,118, 22,178, 14, 41, 25, 57, 55, 83, 95,156,184, - 97, 10, 87, 96, 96,224, 40, 1, 69,109, 93,243,253,100,186, 94,195, 70,144, 58, 56, 64, 31,167,132,202,104,176,189,255,228, 69, -247,101,107,182,166, 4, 6, 6,142, 11, 14, 14,222, 97,174,146,205, 48,195,140,127,141,192, 18,137,132,179,231,125,247, 13,201, - 76,203, 84,107,178,115,116, 6,141, 70, 67, 9, 56,205,179,176,232,100,138, 71,103,126, 57,109,170,197,236,111,191,155, 13, 96, -136,169,226,170, 94,189,122, 15,183,109,219,230,104,107,107,139,172,172, 44,164,165,165,225,225,195,135,224, 56, 14, 93,187,118, - 21, 53,106,216,192,127,245,154,181,247, 92, 92, 92,154, 85, 36,178,120,124, 30,225, 75,165, 56,218,198, 31,148, 64,128,190,225, - 9,249,226,194,160,199,249,129, 61, 0, 0,180, 80,136, 1,145,249,147,124,196, 98,113,149, 51,139,227,184,102, 45, 90,180, 16, - 0,192,140, 25, 51,178, 85, 42,213, 18, 66,200, 62,165, 82, 25,111,170,184,178,119,112,184,177,114,241, 88,219, 6,181, 60,160, - 55, 24, 16,155, 28, 15,142, 8,225,226, 40,195,208, 62,126,130,150,129, 66,143,149, 27,174, 92,119,106,208,171,117,210,243,147, - 47,202, 20,150, 50,217,238,181,107,215,226,208,161, 67, 0,128,107,215,174,193,203,203, 75, 86, 81, 26, 94,189,122,229, 49, 98, -196,136, 3, 0,106,151,118,220, 96, 4,111,223,190,125, 0,128, 85, 95, 13,166, 55,220,138,168, 41,145,252,177,150,114,155, 54, -109,208,166, 77, 27,106,201,146, 37, 65,215,174, 93, 11, 58,112,224,128,222,213,213,117,109,124,124,252,225,170,228,169,250,230, - 77,200,159, 60, 1,110,220,168,244,127, 3, 2, 2,106,213,171,103,119,127,245,170, 31,236, 79,159,121,129,149, 43,119,224,205, -155, 55, 0, 0, 15, 15, 15, 12, 30,212,159,191,239,183,205,245,103,207,158,127, 55, 32, 32,160,101, 72, 72, 72,133,209,205, 89, -150,221,252,213, 87, 95,125,234,234,234,138,185,115,231, 70,212,170, 85, 11,150,150,150,216,178,101, 11,108,108,108, 96, 48, 24, - 34,150, 47, 95,206, 83, 42,149, 88,183,110,221,175,197,172, 91,127, 66,219,206,109,231,138,122,122,183,170, 27, 48, 28,114, 75, - 23,108,219,127, 16,175, 66,118,183,210,234, 95,206, 93, 50,217,117,168,154, 19,141,112,243,178,152,237, 30,216,198,174,118,253, - 79, 81, 35, 32,212, 94, 99,188, 21,253,253, 36,143,165, 60,177,102,247,188,149,127,182, 18,146,254, 71,232, 6,217,225,182,207, - 47, 35,141,227,230,177, 5,194,170, 40,254,149,145,195,167,173, 91,183, 46, 18, 87,239,222,189,131, 86,171,133,183,183, 55,165, -211,233, 76,138,105,165, 80, 40,234,180,110,221,250,246,222,189,123,237, 90,181,106,245,193,210, 45,206,118,214,157,111, 28, 91, - 59,245,199,159,127,171,231,232,211, 39,179,162,142, 64, 96, 96,224,168,134,117, 61,183,175, 93,254, 3,161,115, 98,193,179, 78, - 1,140,169, 72, 56,248, 43,136,212, 22,221, 39,204, 64,227,160, 32,122,234,151,115,182, 55,110,220,152,123,244,232,209, 78,115, -181,108,134, 25,102,252, 43, 4, 22,203,177,190, 78,142,118,146,181, 43,119, 61,162,245, 58,157,204,218, 74,199,183,178,100,137, -133, 21,173,215, 25,114,107,120,212, 16,178, 28,235, 91,134, 32,185, 82,178,151,237,238,238,126,108,231,206,157,142,124, 62, 31, - 44,203,194,193,193, 1,111,223,190, 69,102,102, 38,114,114,114,240,230,229, 75,212,172, 94, 13, 83,199,141,117, 89,180,114,213, - 49, 66, 72, 96,241,225,194,146,156, 28,203,129,101,152,146,189,121,160,148, 37, 99,202, 90, 70,198,212, 41,165, 44,203,190, 85, - 42,149,144, 74,165,240,246,246,150, 63,122,244,232, 86,124,161, 9,169,162,123,111,219,150,231, 34,114, 56,182, 98,241, 64, 91, - 80, 17,136,136,201,132,167, 91, 19,216, 91, 87, 67,124, 74, 46, 30,133,157, 67,228,155,179,240,116,173,129,113,131,107, 91,175, -217,114,231, 12, 9, 24,239, 89,124,184,176, 56,103, 78, 78,142,188, 70,141, 26,112,117,117, 5,203,178, 48, 26,141, 8, 11, 11, -131,209,104, 44,250, 93,252,115,215,209,171, 96,178,223, 99,248,176, 97, 72, 79, 79,151,155,122,239,133,226,106,203, 96, 69,125, - 85, 70,130, 0, 0,100, 54, 46,250,113,191,197,191,104,220,184, 49, 28, 28, 28, 4,119,239,222,157, 1,224,112,101,243, 83, 15, - 44,255,121,231,206,117, 67,178,178, 40, 0,216, 78, 8,171,207,143,170,109, 82, 89,234,216,177,209,209,181,107,191,183, 39, 92, - 24,108,173,150,225,225,195,247,208,235,243,139, 74, 90, 90, 50,166, 76,202, 6,143,103,129, 85,171,231,219, 13, 24, 48,225,104, -193, 16, 25, 91, 94, 58, 57,142, 19, 92,189,122, 21,131, 6, 13,194,129, 3, 7,120, 52, 77,227,193,131, 7,144, 72, 36, 24, 57, -114, 36,234,215,175,207,147, 72, 36,184,125,251, 54,178,179,179, 73,121,233,188,126,241,250,226,172, 55,215,230, 38,146, 11, 93, -182,237, 63,136,177,131, 6,194,153,139,186,101,229, 73, 22,119,234,217,226, 7,142,174,214, 67,102,225,107,227,213,160, 39, 4, - 66, 57, 38,207, 90,136,136,231,167,109,242,114,158, 78, 34,198,216,106, 0,166,149,228,228, 14,247, 51,174,219,127, 55,224,114, -245, 71, 53, 20, 1,227, 31, 0,120,250,135,192,242,224, 17,202,104, 85,104,189,124,253,250, 53,222,188,121, 3, 30,143, 7,181, - 90,253,193,162,190,197, 57,253,253,253,199, 27,141,198, 31, 0, 64,167,211,237,114,114,114, 26,245,203, 47,191,216, 21, 46, 65, - 84,220,114,149,158,153,157,113,247,209,139, 87, 51,198,247,107,123,243,254,243, 88,235, 70,189, 99, 50,159,156,200, 42, 45, 63, -155, 53,107,102, 35,164,233,173, 63,175,152, 71,140, 81, 87, 33,242,110, 11,158,220, 11, 70, 67, 60, 52, 25, 42,104,162, 19,160, -219,178, 30, 30, 19,191,196,138,101, 63,146, 65, 67, 71,111,245,244,244, 60,246,166,152, 5,239, 63, 49,221,219,204,105,230, 52, -115,254, 51, 57,255,117, 2,139, 16, 42,219,104,100, 69, 2, 7, 71,205,232, 1, 29, 26, 94,186, 18,252, 88,106,111,201,235,220, -214,191,205,195,103,209,247, 8, 69, 12,132, 80, 38,249,117,184,185,185, 13,156, 55,111, 94, 67, 75, 75, 75,176, 44, 11, 43, 43, - 43,164,164,164, 64,167,211, 33, 43, 43, 11,218,156,108,232,115,178,241, 36,246, 29, 90,180,105,139,142,205,154,122,159, 55, 24, - 6, 2, 56, 80, 22,167,145,162, 57, 59,255, 38,232, 31,149, 6, 86,175,195, 97, 15,187, 34,171,213,231,239, 50, 65, 8, 1,171, -215,225,124, 80,109, 8,229, 50, 52,250,122, 94,149, 51, 43, 33, 33, 33,180, 70,141, 26,231,187,118,237,218,117,252,248,241, 84, - 98, 98,226, 5, 39, 39,167, 22, 73, 73, 73, 21, 14,143, 58,102,216, 12, 31, 62,174, 97, 45,123,107, 10,167,111, 95, 64,211,122, -125, 32, 21,241,145,146,169, 6, 1, 65,212,219, 43, 96, 25, 57,158,188,124,135,230,190, 82,180,110, 98,237,150,251,123,250, 56, -148, 61, 92, 70, 50, 50, 50,144,156,156, 12,131,193, 0,131,193,128,126,253,251, 99,207,238,221, 80,169, 84, 80,171,213,208,233, -116, 48, 26,141,160, 40, 10,151,207, 28, 70,108,244, 75, 52,111,214, 12, 40, 39,226, 55,159, 6,179,234,171,193, 60, 0, 16, 90, - 56,232,115,114,114, 32,147,201,160,202, 72, 16,204, 92, 89,100,217, 18, 92,187,118, 13, 33, 33, 33, 80, 40, 20, 38,149,163,210, -240, 6,216,250,214,104,156,219,245,248,113,199, 59,199,143,179,247, 79,159,142, 19,229,228,108, 49,229,191, 65, 65,126,253,166, - 78,233, 94, 87, 34,150, 32, 46,102, 45,234,213, 19, 96,230,151,118, 88,178, 44, 21, 0, 48,117,138, 27, 26, 7,218, 35, 59,243, - 8,236, 29, 61, 49,115, 70,111,207,220, 92,110, 24,128, 93,229,151,119, 50,229,233,211,167, 17, 78, 78, 78,188,208,208, 80, 8, -133, 66, 72, 36, 18, 72, 36, 18,136,197, 98, 36, 38, 38, 66,167,211,225,208,161, 67, 76,193, 16, 98,153, 40, 24, 6,236, 58,163, -171,203,249, 87, 33,187, 91,185,210,209, 79,250, 78,110,249,238,233,253,208,156, 75,151,239, 44, 98, 52,226,216,204,184, 43,223, -212,106, 28,106, 63,233,235, 5, 88,191, 98, 30, 94, 61,184,153,238, 84, 61,123,131,132,104,119, 5,125, 82,138, 85,172,237, 2, -222,164,239, 7, 48,227, 71,244,181, 62,237,116,119,252, 57, 30, 73, 73, 76, 13, 89,137,183,161,106, 81,109,255,161,117, 60, 40, -221,213,171, 87, 37,173, 91,183,134, 70,147,191,100, 28, 77,211,216,187,119, 47,203, 48,204,181, 82,173,150, 6,195, 15, 33, 33, - 33, 46,106,181, 26,159,127,254,249,212,249,243,231,203,248,124,126,254,251,101, 52,126, 96,185, 90,188,102,207,197,233, 63,108, -184,118,241,192, 50,197,226,217,163,218, 14,153,252,227, 53, 0, 23, 74,227,101, 24,102,247,218,101,223,210, 34,107, 3, 72,227, - 78,208, 39,169,241,126,219, 88,232,178, 53,168,179,104, 1, 0, 33,116, 6, 10,103,123,245, 3,101,171,192,152, 86, 45,120, 91, -110,222,222, 13,160,183,185,106, 54,195, 12, 51,254,255, 91,176, 88,246,230,235,232,119,221, 58,117, 12,114, 59,115,227,217,163, -241, 35,187,119,166, 40,138, 60, 14,123,127,195,179,134,179,253,181,235, 55, 57,150,101,111,154,114, 49, 62,159,223,163,101,203, -150,188,140,140, 12, 40, 20, 10,164,164,164, 32, 62, 62, 30, 6,131, 1,154,172, 76,232,114,178,161,203,206,130, 81,149,131, 55, -193, 15, 81,175,186,155,232, 74,190, 19,252, 1, 83,248, 75, 90,168, 10, 23,253, 5, 33, 16, 89,200, 33,146,203, 43, 94, 9,190, - 4, 20, 10, 69, 47, 75, 75,203,111,114,114,114,206,197,199,199, 47,214,233,116,147,126,250,233,167, 71, 11, 23, 46,180,159, 61, -123,182,229,172, 89,179, 14,187,187,187,251, 85,228,135,100, 97,107,236,215,180, 97,109, 58,242,253,115, 4,214,233,135,154,138, -150,136,138,207, 66,122,142, 22,105, 89,106,212,173,243, 53,146,210,242,144,165,210,224,217,171,125,112,117,174, 69,209,252, 55, - 93,202, 17, 88, 72, 74, 74,250,224,158, 15,236,223,143,188,172, 44,120,122,122,194,219,219, 27, 14, 14, 14,120,255,254, 61,110, -223,190,141, 33, 3, 62, 5,159,223, 23,201,201,201,229,222,239,174, 80,142,175, 80, 40, 66,148, 74, 37, 66, 67, 67,241,230,205, -155, 82,135, 85,127,255,253,247,252,134,215,217,217,228,188,116,114,114,250,150,162,168, 1, 0,104, 0,177,148, 66, 81,219,193, -193,193,169, 69,239,222,200,226,243,233, 95,174, 93, 35, 60, 43, 43, 57,128,204,138,184, 44, 45,209, 61, 48,176,165, 48, 51, 99, - 7,128,124,163,212,168,145, 14,232,218,197, 9,132, 18, 65,225, 98, 1, 66,137, 64,136, 16,121,170,171,240,169,239, 43,176,176, - 56,214,163, 60,129, 85,232,208, 94,191,126,125, 76,152, 48, 1, 39, 78,156,192,174, 93,127,156,222,183,111, 95,124,246,217,103, -200,205,205,133,147,147, 19, 79,169, 84, 70, 5, 4, 4, 84,232,248,110,233, 73, 22,107,245, 47,231, 90,123,201, 82,140,176,111, -158,107, 16,165,205, 91, 25, 53, 15,192,170,174,158,158,219,244,236,205,232,200,231,167,109,222, 62,186,158,174,140, 84,121,108, - 59, 27, 85,166, 15,214,141, 27, 96,157,124,111,232, 63,237,210,134,215,187,103,187, 60, 87, 55,167, 58,191,108,208,237, 77,119, -181, 91,236, 94,221,109,200,188,159,190,209, 15,237,211, 74,255,205,204, 41,252,250, 62,222, 36, 59, 59, 27, 7, 15, 30,100,206, -159, 63,159,192,178,236,244, 50,104,233, 2,161,133, 1, 3, 6,200,164, 82, 41, 98, 99, 99, 81,175, 94, 61,176,108,126,222, 38, -164,164, 61,187,243,232,121,248,140, 9,253,219,236, 59,117,237,229,197,235,193, 47,123,119,105,209,136, 16,206,189,172,180,210, -132, 52,245,241,245, 5,199,197,131,230,215, 65,220,222, 81,208,164,229, 64,171,210,128,226,203,160, 51,208,208,179, 4, 34,223, - 38,120,125,226, 20,106, 15,174, 15, 30, 33, 45,204,213,178, 25,102,152,241,255, 1, 21,170, 13, 90,163, 91,242,213, 55,115, 97, - 99, 37,177,106,226,239,229,124,242,194,141,224,155,119,131, 95,186, 87,179,119,224, 12, 58,155,229,171,215,187,145, 60,181,169, - 78,222,222,246,246,246,208,235,245,120,253,250, 53,226,226,226,160,215,235,193,168, 84,208,102,102, 66,147,145, 1,163, 42, 7, - 2,163, 17,234,148,100,216,136,133,192, 31, 51, 12,203, 51, 85,254, 33,166, 74, 17, 92,132, 16, 72, 44, 45, 33,178,176, 0,197, -163, 77,206, 28, 23, 23,151, 0, 63, 63,191, 67, 87,175, 94, 13,106,217,178,229, 34,119,119,119,171,196,196,196,247, 73, 73, 73, - 29, 86,172, 88,161,117,112,112,192,144, 33, 67,234, 26, 12,134,225, 21,113, 9, 68,218,134,213,157,188, 80,205,233, 83, 40,236, -155, 34, 61, 91,139,228, 76, 53,146,210,242,112,240,216, 64, 92, 58,247, 57, 30,223, 30,134,215, 15, 70, 33, 53,215, 18, 98,219, -118, 0,184, 6,229,113,222,189,123, 23,155, 55,111,198,230,205,155,177,105,211, 38,172, 95,191, 30, 25, 25, 25,104,208,160, 1, - 98, 98, 98,112,254,252,121, 36, 36, 36,192,222,222, 30,143, 31, 63,198,150, 45, 91,240,240,225,195, 74, 23, 18,141, 70, 3,129, -220, 78,191,234,171,193, 88,245,213, 96,176,124,153,190,152, 0, 55,189,176, 81,212,136,132,222,189, 27, 38, 88, 91,251,248,250, -250,118, 29, 48, 96,128, 71, 80, 80, 80,209,113, 79, 79,207,234, 60, 30, 47, 81,161, 80,108, 87, 40, 20,126,229, 43,127,206,223, -198,214, 27, 58,109,120,193, 51,230,131, 16, 49,218,127,242, 18, 45, 90, 5, 67,111, 16,128, 34, 34, 80,148, 24, 12,147, 6, 75, - 11, 39,112, 28,105, 80, 65, 18,187, 93,184,112, 1,155, 55,111,198,219,183,111,139,132,101,143, 30, 61,166, 12, 26, 52,232,152, -209,104,196,153, 51,103,112,226,196, 9,212,172, 89, 19,141, 26, 53,130, 94,175,239, 86,209,125,207,251, 89,121,111,223,234,243, -159,243, 13, 54,126, 98,137,123, 77,168,228,189, 38,181,117,144, 1,192,249, 55,111,114, 28,171,103, 47, 85,229, 60,141,177,118, -203, 93, 86,145,131, 59,199,205, 99, 67, 34,195,239,239, 59,126, 33, 43, 57, 41,131,239,223,176,190,122,201,194,175, 5,238, 53, -107, 47,159,247,205, 4,231,248,108,113,230, 39, 83,207,135, 31,187,240, 48,119,232,200,177,204,232,113,147, 53,231, 47, 92, 62, -206,178,108,195,178,102, 16,178, 44,139,132,132, 4,188,120,241, 2, 81, 81, 81, 72, 73, 73, 65,106,106, 42,114,114,114,138,134, - 21,165, 57,217,103,215,239, 60,253, 68, 38,145, 72,131, 26,122, 85,127, 16, 26,150, 44,147, 72,164, 94, 53,171,215, 33,100, 1, - 85, 6,175,181, 88, 34, 6, 64,144,243,252, 38, 52,233,185, 80,103,230, 66,147,145, 11,173,158,134, 70, 75, 65,173,163, 96,223, -170, 19,114, 85, 26,104,210, 50,192,114,156,141,185, 90, 54,195, 12, 51,254, 21, 22,172,212,212,136, 92, 75, 7,159,207,190,156, -245,195,249,253,191,254,226,168,213,230,197,216,217,200,141,114,169,208,126,244,248, 31,145,147,155,209, 39, 55,221,244, 89, 79, - 25, 25, 25,136,142,142,134, 68, 34,129,128,207,135, 81,173,134, 81,173,130, 58, 35, 13,148, 94, 11,129,209, 8, 91,169, 4, 53, - 20,206,112,119,170,216, 58, 66,179, 70,162,188,124, 14, 23,135,246,249,211,176,224,133,230,117, 33,146,203, 32,182,182, 65,139, - 19,183,242,133,142, 64, 0,204,171,120,145,118,103,103,103,123,133, 66,113,106,253,250,245,130,180,180, 52,188,120,241,226,201, -187,119,239,178,108,109,109, 45,248,124, 62, 27, 25, 25,121, 37, 60, 60,188, 71,173, 90,181,192,113,156,103, 69,124, 57, 89, 50, -189,193,192, 65,153,252, 30,113, 9, 47, 96, 41,175, 6,142,174,134,228,244, 60, 16, 56,129,209, 70,192,104,200,119,183,210,170, -227,144,167, 51,109,221, 94,189, 94, 15,189, 94, 15,131,193, 0,173, 86,139,161, 67,135,226,206,221,187, 56,112,226,119, 68,191, -137, 64,221,154,206, 24, 54,108, 40,252,252,252,240,232,209,163, 42, 23,148,102,223, 92,124, 33,145, 72,176,105,211, 38, 72,165, -210, 15,196,173,137, 98,117, 85,135, 14, 29,106, 71,168, 84,120, 17, 30,142, 38,253,251, 3, 0,110,223,190, 93,116,142, 90,173, -198,224,193,131,133,209,209,209,163,195,195,195, 71,187,184,184,172, 78, 72, 72,152, 89, 22,231,217,179,247, 48, 97, 66, 24, 82, - 82,242,253,176, 15,238,175, 95,116,236,109,180, 30, 93,186,231,143, 92, 89, 91, 91, 99,245,234, 6, 38,165,211,104, 52, 98,235, -214,173, 69,195,130, 0,192,227,241, 90,204,152, 49,227,179,210,206,247,241,241,169,144,115, 70,127, 55,241,227,247,146, 73, 86, -181,221,235, 91,218,251, 34,205, 16,218, 32, 52, 62, 97,202,140,254,110,107, 87, 31,142,211, 72,136,118, 23, 49,198, 86,227,137, - 53,187, 77, 73,227,155,243,235,116,214,238, 35,119, 39,166,100,127, 55,121,236, 96, 59, 75,107, 71,213,246,245, 75,108, 40,154, -226, 78, 5,235, 51,235,123,216, 89,247,106,250,115,238,132, 47,191, 15,213, 49,177,147, 17,123, 42,162,188, 80, 21, 44,203, 66, -169, 84, 34, 37, 37, 5, 49, 49, 49, 72, 77, 77, 45,120,247, 83,139,134, 8,171, 2, 66, 8,116, 49, 49, 72, 58,177, 29,206, 67, -134,162,206,194,133, 48,178, 60,104,242,140, 56,210,186, 3,178, 51,213,208,177, 4,214, 1,205,209,233,204, 45, 16,214, 8,220, -191,107,174,149,205, 48,195,140,127,135,192, 2,128,236,148,176, 40,187, 26,190, 74,149, 90, 37,117,114,116,208, 74,197, 34, 54, - 43, 59,135, 14,125,246, 68,159,155,240,250, 85, 37,174,247, 50, 44, 44,172, 65, 92, 92, 28, 98,222,191, 7,163, 86,129,210,234, -192,105,242,208,177,101,115,136, 1,136, 41, 2, 1,171, 7,143, 22, 34, 39, 55, 27, 0, 94, 86, 68,202, 26, 12, 31, 84,234,132, - 16, 16,138,130, 88, 46,135,208, 66, 6,145,165,197, 7, 22, 45, 83, 32,145, 72,246,109,217,178,197,197,217,217, 25,171, 87,175, -134,139,139, 75,189,142, 29, 59,230,181,105,211, 70, 98,111,111,143, 58,117,234, 32, 48, 48, 16,215,174, 93, 3, 33,228, 77, 69, -124,140, 78, 24,242, 50,154,169,150,149,243, 24,247, 67,247,192,160, 51,192,179,206, 28,168, 13,118,144, 57,140,134, 70,119, 10, -198,204,235, 0, 0,161,101, 91, 36, 38,166, 2, 32,207, 43,243, 48, 57,142,195,211,167, 79,177,255,228, 13,184,212,240, 70, 76, -100, 56,194,175, 93,193, 29, 7, 59,184,251,212,135,193, 96, 48, 89, 16,153,122,158,169, 13, 48, 33,100,240,216,177, 99,145,201, -227, 1,221,187, 67, 16, 21, 5,189, 94,143,166, 77,155,162,113,227,198, 0,128,166, 77,155,130,166,105,212,174, 93, 27,118,118, -118, 56,122,244,232, 96, 0,165, 10, 44,142,144,199,172, 49,173,158,135,135, 71,145,192,218,189, 39, 5,161,193,159,128, 64,136, -117,235,255,136,202, 80,189,122,117, 36, 38, 70,131, 16,174,162,252, 60,215,189,123,247,110, 54, 54, 54, 24, 53,106, 20,196, 98, - 49,250,244,233, 3,141, 70, 51, 0, 0,150, 46, 93,138,111,191,253, 54,223, 42, 53,111, 30,230,207,159,143,188,188,188, 50,135, -134,247,172,241, 85, 36,167,179,163,157,156, 93,251,180,179,119,111,216,190,115, 71,212,242,106,143,246,157, 99, 0,224, 39, 91, -222,187, 1, 43,230, 54, 56,110, 95,205,118,199,165, 11,151,231,181,108,211,254,187,217,227,109, 22, 47,221,146, 81,161, 79, 99, -214,251, 93, 57,175,132, 3,215,252,178,121,207,154, 31,190,157, 38,142, 73,209,101,196,103,112,185,114, 17, 79,238,233, 68,228, - 83,102, 45,138, 86, 42,163,102, 34,246, 66,132, 41,207, 48, 42, 42,170,200,103, 79,163,209, 64,165, 82, 33, 54, 54,182,232,249, -170,101,150, 93, 38,143,236,217, 72,165, 86,231, 61,120, 22, 25, 51,119,234,144,102, 42,181, 58, 47,242,109, 76, 4,199,253,204, -150,241,204, 51,243, 84,121,182,218, 44, 13,178,158,188,130, 93,251, 26,208, 51, 4, 90,163, 17, 25,169, 57,208, 49,128,129,230, -195,173,223, 48, 24,192, 67,118, 74, 34, 40, 66,204,241,176,204, 48,195,140,127,143,192, 34,132,144, 70, 13,107, 40, 86,204, 27, -226,198, 50, 76,221,228,212, 36,134,199, 19,241,171, 89,169, 19, 42,115, 49,131,193,112,230,214,173, 91,189, 91,182,108, 41,138, -124,246, 4,186,172, 44,232,178, 50,193,103, 25,216, 74, 2, 65,233,181, 32, 58, 29, 92,235,177,208,228, 72,112,247,225, 43,131, -193, 96, 56, 83,174, 16, 0,199,177, 76,190,192, 34, 20,245,193, 80,161,200,202, 2, 34,185, 28, 34, 11,139, 82,135, 16,203,130, -147,147,147,180,107,215,174, 29,252,253,253,193,113, 28, 86,172, 88, 1,189, 94, 47, 52, 24, 12, 69, 22,163,220,220, 92, 28, 57, -114, 4,123,246,236,185, 99,101,101, 85,225,212,114,150,209,158,191,122,251, 73,183, 33,125,218, 9, 47, 95,223, 6,131,142, 69, -182,198, 18,185,106, 45,114, 53,124,104, 69,157, 65,200, 45, 80,180, 8,205,253,106,227,234,237, 8,141,209,160,191, 80, 89, 33, -164,209,104, 16, 27,243, 14,113,111, 34, 32,207, 78,132,131,165, 20,121, 81, 17,240, 27, 54, 28, 58,157,174,194,123, 31,225, 79, - 12, 51, 26,128,183,186, 43, 5,129,220, 78,223,236,155,139,101,134,138,144,203,229,149, 26, 34, 76, 77, 77,197,233,211,167,209, -180,105, 83,180,105,211, 6,241,241,241,136,138,138, 66,183,110,127,140,178, 61,121,242, 4,161,161,161,240,244, 44,223, 40,152, -157,205,157, 75, 79,127,221,191, 87,175, 94,130,251,247,239,131,227, 56,120,121, 89,194,210, 66, 6, 66,137,224,237,237, 8, 32, - 95,251,183,109,219, 22, 58, 93, 60,163, 82,225, 92,121,156, 33, 33, 33,221, 3, 2, 2,106, 25, 12,134,136, 54,109,218,240, 94, -191,126,141,126,253,250,225,224,193,131, 0,128,217,179,103, 99,246,236,217, 31,252, 39, 55, 55, 87, 83, 22, 95,221,134,245,190, -174,197,216,180, 17, 75,220,107, 90,218,251,162,150, 87,123, 0,192, 39, 61, 70,161, 86,237,234,200, 78,125, 90, 83,163,126,215, - 71,192,203,176,121,186, 46, 62, 76,210,189,193, 72, 77,242,245, 72, 0,166, 4,238,229,212,145, 7,147, 98,248, 67, 15,157, 56, -117,126,124,183, 30,159,242, 13, 70,134,105, 80,131,111,125,248,248,217,228,248,247, 49, 63, 35,230,194,243,162,215,164,124,129, -101,204,206,206,134, 76, 38, 67, 84, 84,148,182,103,207,158, 34,181, 90,141,215,175, 95, 23, 9, 44, 71,123, 91,159, 22,141, 27, -212, 91,188,102,207, 69,153, 72, 36,234,220, 54,208, 59, 44,242,125, 28,199,145,119,101,242,114,220,253,215, 47, 95,117,119,116, -169, 13,229,141,251,144,182,236, 6,173,150,130, 70,199, 66,203, 0, 12, 45,128, 85,163, 32, 72, 60,188,193, 1,120,249,236, 9, - 24,142,187, 99,174,150,205, 48,195,140,127,141,192,178,183,183,119,244,247, 15,244,220,246,235, 33,112, 28,135, 87,161, 43,145, -145, 28,142,239,127,186,231,233,230,230,214, 38, 46, 46,238,134, 41, 60,113,113,113, 7,143, 30, 61, 58,211,215,199,199,191,166, -155, 27,158,188,123, 11, 1,103,132,192,104, 4,165,215,130,103,212,193,173,129, 17, 20,145, 35, 33, 33, 27, 91, 46, 92,121, 30, - 23, 23,119,176,220,198,129,208,168,214,179, 47, 6,125,210, 29,156, 65,143, 75,173,124, 32,182,144, 67,100,109,141,230, 71,174, -131, 16, 2,142, 49,224,253,146,175,192,151,201, 97,219,172,226, 80, 64, 73, 73, 73,121,181,107,215, 14, 14, 15, 15,111, 92,183, -110, 93, 44, 88,176, 0,177,177,177,224, 56, 14,201,201,201,154,148,148,148,248,180,180,180,119,132,144,227, 74,165,114,155, 41, -145,194,147,109, 50,118, 95,254,253,202,215, 1,126, 62, 94,159,180,153,143, 51,103,230, 33, 35, 43, 27,121, 58, 62,114,212,122, -168,212, 28, 92, 45,189,208,196,215, 23, 41,233, 58, 68,190, 8,137, 75, 21,216,110,173,140,245,138,162, 40, 60,121,242, 4, 30, - 10, 11, 68,220,186, 1,123, 41, 31,141, 20,206, 80,180,104,137,168,168, 40,211, 68,176, 17,188,226,179, 5,173,173,173,145,149, -149,245,129,144,147, 74,165, 80, 40, 20,200,206,206,198,145, 35, 71,192,153,214, 40, 26,116, 58, 29,234,213,171,135, 71,143, 30, -225,202,149, 43,104,223,190, 61,218,180,105,131,167, 79,159,226,210,165, 75, 8, 13, 13, 5, 33, 4,118,118,118,133,190, 63,101, - 70,180,127,248,240,201, 97,185,156,204, 25, 57,114, 98,253, 33, 67,134,224,232,209, 3, 24, 53,178,110,129, 99,187, 8,159,246, -172,139,133,139, 30, 33, 40,168, 45, 28,236, 5,184,124,229, 69, 52,143,103,181,199,132,124,252,229,151, 95,126,225,169,213,106, -228,230,230, 66, 46,151, 35, 45, 45, 63, 28, 85, 25, 22,172, 50, 3,171, 61, 11,121,185, 50, 51,135,203,224,114, 67,251,164, 51, -161, 13,219,119,142,197, 39, 61, 70,226,242,153,157,184,122,241, 10,108,121,239,222, 66,150,115, 62,245,109,106,118,130,202,107, -179,119,192, 24, 58, 78,117,113,243,212, 94, 54,180,139, 11,123,120,246,198,172,204,114,210,201, 17, 66, 72,122,216,222, 83,199, - 57,124,218,188, 89, 80,237, 6,213, 93,132, 25,169,201,220,145,147,231,159,235,223, 30, 61, 93, 40,172, 76, 88, 21, 97,225,218, -181,107,127, 0, 0,150,101,119,173, 89,179,102,204,215, 95,127,237,160, 84, 42,139, 4, 86,114,106,250,213,230,221,167, 24,211, - 50,179,116, 59,214,204,234, 39, 17,139,132,115,151,238,184,110,160,113,191,204,202,133,199, 27, 62,103,211,111, 41, 71, 15,239, -164,237,197, 2,220,153, 61, 15,111,174, 92,131,158, 18,160,243,165, 7,208,233,141,200, 78, 73,195,181,209,147, 96,237,108,131, -115,169,145,198,172,156,236,225,230,106,217, 12, 51,204,248,255, 0,147,166,212,165,166,166, 38,223,188,249, 0,215,207, 44,198, -141, 51,139,241, 34,244, 9,148,241, 58,196, 39,105, 96,105,105,121,175, 28,203, 87,199,146,141,130, 70,163,249,108,205,218,181, -137, 82,153, 12,173, 59,116,128,179,131, 35,164, 2, 62,104,134, 5, 77,248,200, 77,177, 70,228, 51, 53,150, 28, 63,147,172,214, -104, 62, 43,217, 56,148,228, 44,182, 31, 32, 4, 18, 75, 11, 8,229,114,136,139, 91,173, 8,129,192,194, 18, 2, 11, 75,208, 2, - 97,133,233, 4,128,188,188,188,190,227,198,141,203,200,201,201,193,160, 65,131,112,255,254,253,208, 11, 23, 46, 88, 94,185,114, - 69,242,236,217,179,218, 74,165,178, 83,124,124,252,150,178,196,213,159,238,253,250,117,134, 99,244,125, 55,108,218,150,174, 54, - 56,161,103,175, 13,176, 20,166,193,192, 24, 1,142,131,171,131, 28, 77, 90,124,133,100,109,115,156, 57,125, 38,131,101, 52,125, - 75, 46,153, 83,156,147,227, 56,206,206,206,238, 3,171, 28, 69, 81,184,126,253, 58,250,247,235,139,206,125,122,195,161,166, 7, - 28, 59,118, 67,231, 49, 19,176,101,203, 22, 80, 20, 5, 91, 91,219, 15, 44, 26,101,229,103, 33,178,178,178,224,238,238,142, 7, - 43,186,213, 63, 63,163,158,127,245, 55,191,248, 75, 31,175,170,127,245,234, 85,172, 90,181, 42, 55, 34, 34, 98,181,151,151,215, - 87, 21,229, 39, 33,228,187,159,126,250, 73,253,254,253,123,200,229,114, 48, 12,131, 59,119,238, 96,227,198,141, 88,181,106, 21, - 66, 67, 67, 97,103,103,135,218,181,107,131,162, 40,196,196,196,168, 9, 33,223,149, 83,150,216,156, 28, 94,223, 75,151,142,167, -245,236,217, 26, 59,118,172,135,179,115,115,240,121,206,224,241, 29, 32,147,215,195,246,109,203,208,189, 91, 0, 94,134, 63, 78, -207,205,229,245,189,126,253, 58, 99, 66, 58,245,207,158, 61,195,177, 99,199,176,112,225, 66,102,193,130, 5,200,202,202, 42,178, - 96, 21,174,146, 62,127,254,124, 0,128, 86,171, 21,149,197, 57,102,214,179,248,175, 23, 63, 95,152,148, 24,223,244,198,181,123, -131,175, 94,188,130,232,200,171,184,122,241, 10,110, 93,189, 59, 59, 41, 49,190,169,127,147, 58,130,207,198, 76,254,122,247,177, -163,180,220,210, 5,187,143, 29,165, 7, 77,153,254, 99, 96,231,246,223,153,240,140, 56, 0, 92,110,114,210,183, 63,173,252, 37, -151,209,107,168, 21, 63,111, 80,170, 83, 18,190, 67,225,212,202, 50,172, 87,197, 57,163,162,162,182,188,125,251, 86,241,246,237, - 91,197,251,247,239,191,139,143,143,111,189,100,201,146,148, 2,193,149, 47,176, 94,156,188,247,242,214,206,159, 28,237,109, 36, -205, 27,215,175,187,122,203,145,235, 49,177, 73,191, 21,198,192, 42, 45,157,247,238,221,203,208, 26,152,113, 95,205,154,207,101, -102,234, 80,119,218,108, 48, 34, 57,180, 12,160,103,105,232,193, 67,232,226,213,176,176,179,192, 29, 46,131,211,210,212,216, 55, - 37,156,252, 43, 42,159, 85,129,153,211,204,105,230,252,103,114,254, 43, 45, 88,174,174,174,173,123,125,218, 17,109,123,204, 5, -199,113, 8, 15, 89,142,140,148, 87,112,117, 22, 33, 42, 38,187, 25,128, 27,166, 94, 48, 33, 33, 33,198,197,197,165,233,226,181, -235,142,117, 14,106,226,237,229,234, 34,178,118,175, 1,153,163, 35, 82, 83, 83,112, 63, 56,194,176,233,210,213,231,106,141,198, -164,165,114, 88,150,229, 88,150,133, 64, 32, 0, 71,211,240,153, 58, 27,132,162, 64,241,121, 69,150, 29, 16, 2,203,128, 22, 32, -124, 62, 12, 38,250, 12, 41,149,202, 56, 87, 87,215,190, 83,166, 76,249,125,215,174, 93, 84,219,182,109,253, 78,157, 58,197,254, -149,204, 78,122,118, 60,204,169, 97,159, 54,235,126,217,120,196, 63,176,105, 13,247,154,238,162,230,110, 86,208, 27,140, 72, 74, - 78,195,141,187, 47,180, 17, 97,143,227, 57,189,190,111,114, 88,217, 81,220, 1,192, 96, 48,196,184,185,185, 57, 45, 88,176, 0, - 12,195,128, 97, 24, 24,141, 70,164,166,166,226,222,189,123,104,216, 56, 8,222, 35, 71, 35, 37, 37, 5,235,214,173,131,155,155, - 27,126,250,233, 39,228,228,228,224,230,205,155,101,230, 43,159, 6, 51,120,112, 65, 28, 44, 30,152,213, 61,122, 92,175, 95,191, -126,203,166,134,100,193,188,117,249,150,173,105, 99, 7, 11,174,199, 92, 63, 44, 18,137,182, 68, 71, 71,151,235, 47,228,233,233, - 41,212,104, 52,126, 28,199,209,217,217,217,107, 53, 26,205,136, 25, 51,102,184, 44, 93,186, 20, 94, 94, 94, 72, 77, 77,133, 76, - 38,131,151,151, 23,114,114,114, 16, 29, 29,109,212,235,245,155,141, 70,227,194,164,164,164,148,242,184, 31, 62,124,248,218,223, -223,191,105,114,210,166, 99, 19, 39,116,246, 50, 48,129, 66, 75,203, 86,224, 56, 3, 50, 51,226, 0, 60,213, 31, 63,113,229, 77, -102, 38,253, 89,112,112,112,164, 73, 61, 14,138,154,176,102,205, 26, 20, 46,149, 19, 31, 31, 95,100,250, 43,205,130,101, 10, 86, - 31,142,211, 0,216,191,226,203,230, 95,102,167, 62,245,178,229,189,123,219,180, 1,187,110,245,225, 56,205,130, 47,173, 23,167, -190,187, 17,145,160,186,184,121,247,177,163,244,240, 62,125,141,110,242,200,217, 98, 71,238, 72,251,158, 21, 90,219, 56, 63, 63, -191,106,132,164,215, 74, 78,123, 21, 60,106,204,248, 1, 86, 2,245,185, 70,110,105,158, 84,117,127,113,104,104,232, 91, 83,215, -244, 44, 81,246, 35, 20, 10, 69,235,149, 43, 87, 94, 4,240,129,143, 89,114,106,250,213,102, 61, 38,115,153,153, 89,143,147,195, - 78, 62,171,136, 43, 56, 56,120, 71, 96, 96, 32,134, 13, 29,181,117,236,232,177,116,131,169, 95, 35,254,250, 85,192,104, 64,226, -173, 27,144,200,141, 56,147,250,206,152, 71, 83,227,130,131,131,205, 81,220,205, 48,195,140,127,151,192,138,139,139,187,225,233, -225,118, 41, 34,162,117,167,234,110, 14,249,189,222,183, 74,196, 39,105, 47,153, 58, 60, 88, 82,100, 17, 66, 2,207, 50,204,192, - 75,124,126, 15, 82, 16,138,129,171,194, 98,207,121,121,121, 73, 77,155, 54, 45, 35,246,194, 79,165,238, 53, 26,141,113,166,112, -199,199,199, 95, 87, 40, 20, 67,155, 55,111,190, 84,169, 84, 30, 75, 73, 73, 81,253,213, 12, 79,122,118, 60,140,180,109, 91, 63, -248,193,205, 97,161,193,247,123,112, 28,231, 11,128, 16,138,250, 99,177,231,176,138, 23,123, 86,171,213,227,231,206,157,187,133, -199,227, 85, 71, 65,224,208,194, 44,211,235,245,244,142, 29, 59,196, 58,157,142, 6, 64, 4, 2, 1, 35,151,203, 53,119,238,220, - 97,140, 70, 99,140,193, 96, 24, 95, 22,239,174, 80,142, 95,114,159,143,143,143,236, 53, 15,185,133,191,211,212,128, 82,169, 92, -110,202,253,158, 59,119,206,221,198,198,166, 19, 33,164, 31,199,113,245,114,114,114,180, 63,252,240,195,221,107,215,174,101,191, -122,245,170, 75,171, 86,173,136,179,179, 51,162,163,163,185,220,220,220, 35, 20, 69,125,167, 84, 42,163, 76,205,207,208,208,208, - 40, 66, 72, 35, 85, 30,247,185,133,252, 66,119,150, 67, 35,128, 35,132,144,103,185,185,228,156,139,139,199,111,151, 47, 31, 54, -121, 42, 92,193,218,130,189, 10,127, 7, 4, 4,156,123,245,234, 85,183, 66, 11, 86, 73, 31,172, 74, 65,154,123, 74,163,126,215, -151,200,243,142,175,254, 57, 78, 3, 0,243,214,100,102, 1,216, 62,181,143, 45,251, 50,100,251,114, 87,203,200, 89, 63, 31, 79, - 55,105, 77, 62,127,127,127, 15,138,162, 6, 2,104,224, 40,202,172,237, 32,204, 50, 18,194,181, 35,132,178, 7,240,212,199,199, -231, 12,128,184,170, 36, 85,169, 84, 70, 0,168, 81,114,127,242,139,147,247, 0,220,171, 12, 87,112,112,240,142,102,205,154,157, -220,176,117,243,110,154,144,166,196,104,180, 54, 78, 24,244,199, 98,207, 34,225,240, 96,243, 98,207,102,152, 97,198,191, 81, 96, - 1,192,155,168,184,206, 0,224,229,229,197,189,126,253, 26, 28,199,145,191,114,225, 2, 1,117, 0, 38, 6, 17, 45, 11,207,159, - 63,247,255, 79,102,144, 82,169,220, 15, 96,255,199,228,228,242,135,170,118, 20,108, 85, 66,124,124,252, 51, 0, 65,255,141, 66, - 18, 22, 22,166, 26,225, 79,138, 44, 91,124, 26,140,169,255,237,212,169,211,123,189, 94,127, 5, 64, 44, 33,196, 26, 64,186, 94, -175,191,152,146,146,146,228,236,236, 28,248,254,253,251,239, 11, 44,145,139, 18, 19, 19,131,171, 88,150, 88, 0,251, 10,182,143, -138,144,144,144,238, 10,133, 34,212,206,206,206, 83,163,209, 8, 53, 26,141,160,184,246,151, 72, 36, 41,166,114, 89, 91,144, 93, - 2, 94,134,157,181, 5,249,211,115,183,117,197, 81,181,234,121, 93, 91, 87, 28,173,140,184,244,243,243,219, 75, 81, 84, 77,142, -227,156, 0,206,138,227,144,194,113, 92, 42,143,199,139, 15, 11, 11,139,255,167, 84, 52,247,242, 5, 84, 15,115,149,107,134, 25, -102,152, 5, 86, 25,136,140,140, 36,230,108,251,247,161, 52,203,150, 41, 40,136,112,127,183, 96,251, 0, 5,130,170,231, 63,253, -222,149, 74,229, 71, 17,241, 99,102, 61,139, 7, 48, 61,176,148,121, 22,243,214,165,231, 0,248,186,221,167,149,227,124,252,248, -113, 12,128, 24,115, 9, 53,195, 12, 51,204,248,103,129, 50,103,129, 25,102,152, 97,134, 25,102,152, 97,198,199, 5, 1, 80,234, - 76,128,202,172,148, 93,149,217, 4, 21,241,155, 57,205,156,102, 78, 51,167,153,211,204,105,230,252,255,199,249,175, 65,225,180, -243,255,196, 6,160,163,153,211,204,105,230, 52,115,154, 57,205,156,102, 78, 51,231,191,109, 51, 15, 17,154, 97,134, 25,102,152, - 97,134, 25,102,124,100,148,233,228,238,225, 81,205,135, 50,178, 45, 56,142,162, 57,138, 51,144,108,245,193, 55,233,233, 31, 4, - 1,172, 94,189,186, 53,159, 66, 79,194,113, 50, 66, 88, 35, 75, 83,119,162,162, 98,195, 76,185,176,143,143,143, 0,192, 8, 62, -159,223,210, 96, 48,184,240,120,188, 4,141, 70,115,155,207,231,239, 10, 11, 11,211,255,147, 50,169,101,203,150,131,142, 28, 57, - 98,221,163, 71, 15,173, 94,175,103, 68, 34, 17,111,223,190,125,162,145, 35, 71,102,222,190,125,187, 74, 51, 12,253,252,252,218, -175, 88,177,162, 86,251,246,237,209,178,101, 75, 85,183,110,221, 4,129,129,129,130,175,191,254, 58,250,241,227,199, 87, 43,195, -229,228,228,228,195,227,241,246, 16, 66,104,142,227,134, 21,204, 48,252,143,128, 16, 50, 8, 64,127, 0, 46, 0, 18, 1, 28,226, - 56,110,127, 21,185,186, 32,223,201,221,183, 96,215, 83, 0,167, 57,142,187,240, 23,210,215, 5, 64, 79,154,166,253, 0,192,104, - 52, 62,254, 88,156,124, 62,191, 17, 0, 24, 12,134, 39, 31,139,147, 16,210,168,192,146, 92, 37,206,128,128,128, 31,132, 66,225, - 88, 0,208,233,116, 59,228,114,249,146,210,206,187,113,227,134,174,172,208, 39, 62,181, 8, 23, 54,171, 94,254,247,229,225, 0, -128, 10,127, 71, 87,113, 22,241, 22,111,174, 52, 94,140,127, 89,229,201, 51, 10,133,226,139,110,221,186,125,115,225,194,133, 31, -227,226,226,182, 86,246,255, 71,142, 28,161, 77, 57,239,243, 89,219,123,200,229, 54,223,231,102,103, 45, 61,176,114,212,241,194, -253,253,250,245, 51,194, 12, 51,204, 48,195, 20,129,229,225, 81,205,167, 95,239,207,126,154, 48,126, 34,161,105, 10, 47,195,195, -121,147,166,126,217,201,219,219,219, 85,166,209,120,115, 0,171,150, 72,158,211, 52, 21,191,105,195, 47, 22,117,235,212, 49, 26, -141, 44, 54,111,217,212,213,195,163,218,156,138, 68,150,163,163, 99, 45, 23, 23,151,181, 83,167, 78,117,236,212,169, 19,229,228, -228,132,184,184, 56,203,227,199,143,215,254,245,215, 95,123, 56, 58, 58, 78, 79, 78, 78,142,174,202, 13,185,184,184,180,114,180, - 70, 39,185,152,235,128,108,130, 92, 35,126, 79,214,226, 82, 66, 66,194,173,170,102,146, 78,167,155,146,151,151, 23,228,237,237, -205,109,222,188,153,140, 29, 59,150, 35,132, 16,181, 90,189, 11, 85, 12,225, 32,149, 74, 55,180,111,223,222,171, 69,139, 22, 81, -119,239,222,237,198,113,220,185,126,253,250,121, 72,165,210, 72, 0,117, 42,195, 69,211,244,206,176,176,176, 70, 26,141, 6, 1, - 1, 1,191, 2, 8,248, 15,137,171, 95,237,236,236,216, 77,155, 54,109,105,216,176,161,167, 74,165,202, 27, 51,102, 76,103, 66, - 72,123,142,227, 70, 87,130, 71, 6, 96,157,149,149,149, 96,241,226,197,247,219,182,109, 27, 35, 20, 10,165, 17, 17, 17,220,212, -169, 83, 71, 17, 66,250, 1,152,202,113,156,170,178,156, 10,133,194,114,217,178,101,175,252,253,253,239, 10,133, 66,193,219,183, -111, 49,109,218,180, 9,127,133,179, 94,189,122,210,101,203,150, 61,241,246,246, 78, 19,139,197,130,247,239,223, 99,198,140, 25, - 99,104,154,238,199,178,108,149, 56, 29, 29, 29,101, 75,150, 44,121, 22, 24, 24,152, 41, 22,139, 5,111,222,188,225,190,252,242, -203,177,149, 73,103,155, 54,109, 62,167, 40,106,193,205,155, 55, 1, 0,205,154, 53,251, 65,167,211,205, 45,121, 30,199,113,104, -217,178,165,166, 77,155, 54, 99,111,220,184, 81,106, 88,148,221,162, 89,131, 0,224,235, 31, 10,126, 23,236, 47,237,247,112,237, -242, 74,151,121,159, 90,132, 3,128, 73, 95,109, 28,154,255,153,191,127, 83, 65,232,222, 13,181, 8, 87, 25,209,230,234,234, 58, -190, 73,147, 38,223, 62,120,240, 96,119, 96, 96,224,180,173, 91,183,242,123,244,232,177, 88,161, 80,120,118,233,210,165,223,189, -123,247, 86,132,135,135,111,248,152,229,223,217,185,218,250, 85, 63,111, 85, 76,159, 60,122, 41,128,227,230,230,195, 12, 51,204, -168,180,192,162,140,108,139, 9,227, 39,146,129,131, 62, 79, 76, 72, 74,102,229, 22, 86,131, 14, 29, 62, 44,173, 83,167, 14,165, -249,229, 23, 48, 41, 41, 48,206,156,217,252,198,141, 27,134,201,211,103,170,181,154,188,157, 46, 78,142,210,131,251, 15, 56, 31, - 59,122,164, 5,128,176,242, 44, 87, 46, 46, 46,107,143, 30, 61,234, 92,171, 86, 45,232,116, 58,164,165,165,193, 96, 48,160, 79, -159, 62,116,211,166, 77,157, 71,141, 26,181,214,199,199,231,179,202, 88,178, 28, 28, 28,156,188,170,243,207,204,155,222,181, 78, -251, 54, 1, 50,103,215,154, 64, 28,139,248,232,215,141,175, 60, 8,153,218,210,211, 45, 34, 50, 91,215, 35, 37, 37, 37,169,178, -153,148,150,150, 54,107,252,248,241, 71,125,125,125, 29, 68, 34, 17,156,157,157,201,152, 49, 99,146, 19, 18, 18, 22,252, 5,177, -146,159,215, 20,101, 44,254,105,234,130,212, 37,224,102,101,101, 5, 43, 43, 43, 0,112,253, 43, 5,162,127,255,254,116, 76, 76, -204, 88,150,101,189,139,239, 79, 72, 72,240,112,112,112, 72,122,251,246, 93, 35,181, 78, 31, 56,113,242,156,249, 3,251,117,180, -190,123,247, 46,186,119,239, 78, 17, 66, 6, 85,194,146,181, 46, 40, 40, 40,114,233,210,165,130,200,168,183,245,239, 63,122, 12, -153, 88, 96,116,115,115, 21, 61,125,250, 84,184,108,217,178,164, 31,127,252,113, 29,128, 81,149, 72,250,186,254,253,251,103, 76, -159, 62, 61, 47,226,205,219,154, 15, 66,159,113,114,145,192,224,228,228, 64,223,189,123,151,191, 97,195, 6,242,221,119,223, 85, -154,115,204,152, 49, 9,211,167, 79,231,165,164,101,214, 78, 76, 74,229,132, 2, 90,111,109,109,205,187,124,249, 50,181,115,231, - 78,253,212,169, 83, 43,205,217,189,123,247,164,217,179,103,243,195, 35,163, 60,238,135, 60,131, 92,196, 55, 56, 59, 59,210,247, -239,223,167,215,173, 91,199,204,155, 55,207, 36, 78,142,227, 54,175, 92,185, 18, 39, 79,158, 4, 0,236,223,191, 31, 30, 30, 30, - 31, 12,251,171, 53, 90, 80, 4,120,251,246,173,116,194,132, 9,155, 81, 74,220,185,176, 89,245,176, 27,192,240,225,195, 19, 77, -179, 66, 45,175, 92,161,218,226,205, 21, 10,171,137, 19, 39,150, 21,155,107,168, 79, 37, 68, 86,139, 22, 45,190, 57,120,240,160, -253,225,195,135,191, 58,126,252,120, 97,167, 69,186,126,253,250, 47,122,245,234,133,209,163, 71,127, 3,224,163, 10, 44,161, 64, - 36, 34, 20,129, 68, 44,181, 52, 55, 29,102,152, 97, 70,149, 4, 22,199, 81, 52, 77, 83, 72, 78, 74, 53,124,210,177,211,168,245, - 27, 55,138,132, 66, 33,116, 58, 29, 84, 87,175,130,211,104, 96, 45,149,162, 91,183,110,252, 6, 13, 26, 88,142, 31, 51,102, 76, - 82,162,114, 11, 77, 83,206, 28, 71, 85,100,110, 31, 49,117,234, 84,199, 90,181,106,125,176,211,104, 52, 34, 61, 61, 29, 22, 22, - 22, 24, 48, 96,128,253,222,189,123, 71, 0, 48,201,220,239,228,228,228, 94,199,195,233,206,145,237, 51, 93, 28,173, 41, 32,229, - 8,240,254, 53,176, 79, 12, 47,199,234,240,106,215, 86,214,171, 73, 67,255, 1, 43,118,132, 58, 57, 57,181, 72, 74, 74,122, 87, -153, 76,122,251,246,237,109,133, 66, 49, 70,173, 86,159, 4, 64,221,185,115,135,139,137,137, 25,159,152,152,248,190,170, 25,207, -178, 44, 50, 51, 51,193,178, 44, 93,240,187,240,243,111, 43, 12,253,251,247,167, 99, 99, 99,199,123,123,123,215,222,182,109, 27, -146,147,147, 33,145, 72, 96, 52, 26,209,188,121,243,234, 29, 58,116,120,147,146,150,105, 99, 96, 12,186,132,184, 55, 77, 14,108, -125,151,215,200,203,235,238,161, 67,135, 26,218,217,217, 13, 48,197,154, 71, 8,233, 98, 97, 97,193,251,233,167,159, 40, 11,107, -231,238, 77,130, 20,252,103, 97,175,222, 9, 68, 60, 54, 43, 43, 59,237,201,147, 39,225,243,230,205,107,117,234,212,169, 68, 66, - 72, 23, 83,134,204, 8, 33, 93,156,157,157, 45,166, 77,155,166,146, 88,216,183,108, 28,228,200,123, 30,246, 58,158, 47,160, 12, - 45, 90,180,104,119,239,222,189,157, 51,103,206,244, 61,123,246,108, 86,101, 56,107,215,174, 45,153, 62,125, 58,109,101,109,223, -209,193, 89, 65, 59,216, 90,123, 2, 64, 84, 84,212,222,164,164,164,200,137, 19, 39, 54, 62,123,246,108, 78,101, 56,237,237,237, -165,179,103,207,230,213,244,168,219,215,195,171, 46,117,229,250,131,103, 66, 33,101, 80,171,213,233, 47, 95,190,124,253,205, 55, -223, 4,158, 61,123, 54,219, 20,206,188,188, 60, 11, 87, 87, 87, 56, 57, 57,129, 85,171,145,149,149,133, 99,199,142, 33, 39, 39, - 7, 70,163, 17, 18,137, 4, 63,174,222,130, 55,207,239,227,214,173, 91, 80,171,213, 22, 31,163,156,248, 44, 15, 71,216,120,211, -197,213, 38,118,242,208,114,132, 21,138, 9,175,161,216,226,205,149, 55, 92, 88,204,114, 21,119,248,240, 97, 71, 79, 79, 79,180, -109,219, 22, 0, 48,106,212, 40,116,236,216, 17, 39, 79,158,196,165, 75,151, 98,154, 53,107,246, 58, 54, 54,118, 85,124,124,252, -150,143,113,223, 70,206,168, 7, 0,145, 88, 36, 10, 15, 15, 39,245,234,213,227,204, 77,136, 25,102,152, 81, 22, 74,117,114,231, - 8, 81,189,120,249,146, 47,183,182, 30,186,126,227, 70, 17,159,207,199,251,247,239, 17, 22, 22,134,188,223,127,135,250,238, 93, - 36, 37, 37, 33, 55, 55, 23, 14, 14, 14, 88,178,124,185, 76, 32,145,141,138,124,253,154,230, 40,206, 80,172,135,253,167,169,154, - 66,161,176,101,183,110,221,202,116,174, 79, 76, 76, 68,167, 78,157,120, 60, 30,175,101, 25,189,246, 43, 37, 26, 45,162,112, 32, -167, 15,111,157,230,226,200,123, 6,188,158, 1,228,132, 2,156, 22, 96,116, 64, 76, 56,112, 98, 53, 92,211, 34,201,254, 41, 3, -156, 93, 37,130,211,164,132,153,168,162, 41,165,110,110,110, 30, 30, 30, 30,219,251,245,235, 71, 1, 64,203,150, 45,137,135,135, -199, 86, 55, 55, 55,143,114,172, 11,229,114,106, 52,154,251, 25, 25, 25,232,209,163,135, 93,243,230,205,175,244,232,209,195,174, -112,127, 85, 57, 11, 96,215,190,125,251, 52, 15, 15,143,253,238,238,238, 34, 19,172, 32, 69,156, 49, 49, 49, 99,235,213,171, 87, -123,219,182,109, 52, 77,211,216,182,109, 27, 14, 30, 60,136,219,183,111, 35, 57, 57, 89, 58, 99,198, 12,235, 51, 87,238, 95,184, -115,251,225,169,149,115,191,178,235,211,161,173,135, 77, 86, 74,182,173,173,109, 55, 0,206, 38,166,179,231,220,185,115,111, 60, -126, 25,229, 72,241,248, 2,145,128, 47,113,176,183,174,225,236, 96, 83,219,213,206,166,182,133,144,111,157,157,157, 29,125,226, -196, 9, 6,197,130,144, 86,196,185, 98,197,138,151,225, 81,177,118, 20,205,227,243,105,190,208,218, 74,110,247,105,143, 78,237, - 0, 64, 66, 19, 81,118,118,118,236,222,189,123, 43,197,185,116,233,210,144,132,148, 12, 71,190, 64,200, 19, 9,248,226,194, 3, - 54,150,114, 39,153, 72, 36,201,203,203,123,191,125,251,118, 93, 37, 57,159,188,136,124,111, 79, 40,208, 20, 8,223,198,198,194, -209,193,218,194,217,209, 82,238, 44,166, 32,206,206,206,126,183,127,255,126,189,169,156,201,201,201, 8, 15, 15, 71,181,198,141, -113,229,202, 21, 84,175, 94, 29, 3, 6, 12,192,231,159,127, 14,137, 68,130,246,205, 26, 98,206,156, 57,120,243,230, 77,153,207, -189,208, 31,170, 60, 40, 20,138,235,149, 41, 75, 64,254,176, 96,121,226,170, 36,103,105,231,149,228,108,209,162,197, 55,199,142, - 29,179, 95,179,102,141,223,151, 95,126, 25,117,236,216, 49,248,250,250,226,229,203,151,112,117,117,197,129, 3, 7, 48,121,242, -228,168,249,243,231,251, 93,190,124, 89,161, 80, 40,102,153,250, 30, 13, 27, 54,172,101,255,254,253,111,245,239,223,255,241,192, -129, 3,183,142, 31, 63, 94,241,129, 21, 87, 25, 23,172,211,233,208,200,191,177,116,209,175, 15,134, 84,225,221,172, 20,204,156, -102,206,127, 27,231,191, 66, 96, 25, 88,156,158, 50,109, 70,222,238,221,187,165, 66,161, 16,239,223,191, 71, 98, 98, 34,142, 31, - 61,106, 28,220,176, 97,206, 48, 63,191,236,227, 71,143,114,122,189, 30, 28,199,161,118,237,218,232,214,173,155,100,204,184,137, -201, 36, 91,125,176,130,135,226,232,224,224, 80,180,104,238, 7,166,173, 17, 35,192, 48, 12, 44, 44, 44, 64, 8,113, 52,229, 6, - 92, 92, 92,250,143,250,186,131,155,101, 13,203, 36, 46,113,119, 58,104, 49,192,179, 0,120,150,128,196, 18, 16,203, 0,129, 24, -218, 71,183,211, 57,180,120,215,217,191,191,171,139,139, 75,255,202,100,146,189,189,253,247, 71,142, 28,113,120,250,244, 41,151, -147,147,131,164,164, 36,238,155,111,190,113,176,183,183,255,190,170, 25,175, 84, 42, 23,141, 26, 53, 42,169,111,223,190, 86,187, -119,239,174,214,183,111, 95,171, 81,163, 70, 37, 41,149,202, 69,127,229,129,242,249,124,250,234,213,171,182, 95,125,245,213,231, - 6,131, 33,184, 67,135, 14,105,254,254,254,193,206,206,206, 53, 76,176,170,121, 23,138, 43, 0,160, 40, 10, 66,161, 16, 66,161, - 16, 86, 86, 86,153, 81, 81, 81, 70,119, 39,137, 80,204,228, 26,109,120, 20,191,166,139,179,157,181,179, 75, 91,149, 74,117, 27, - 64,130,137, 73,244,109,219,182,173,152, 97,105,227,196, 17,237,107, 79, 30,217,190,230,182,165, 19,125, 55,252, 52,177,254,202, -133, 19, 90, 45,253, 97,244, 48,194, 48, 57, 53,107,214,244,192, 31,206,239, 21, 89,134, 26,249,250,250,138, 56,240,241,228, 69, - 84,220,219,152,248,236, 46,237, 91,212, 45,186, 96,147,166,159, 59, 58, 58,126,234,225,225,209, 17, 64,103,147, 76,187, 60, 94, -163,134, 13, 27, 74,120,124, 17, 28,237,173, 60, 44,228,178,162,161, 87, 27,123,199,142,206,110,110,163,121, 64,154,139,139,139, - 27,143,199,107,100,106, 58, 3, 3, 3,197, 44, 4,112,118,176,181,117,176,183,177,236,214,161,165, 79,139, 86,205, 27,250, 55, -111,217,206,191, 89,139,145,148,209,152,225,238,238,238, 90,232,252, 94, 17, 78,156, 56,129,117,235,214,161,101,253,250,112,119, -119,135,131,131, 3,126,255,253,119,252,254,251,239,144,203,229,200,204,204,196,166, 77,155,112,241,226,197,191, 92, 89, 20, 10, -162, 34,199,244,143,128,146, 34,171, 34,177,119,251,246,237, 99,135, 15, 31,134,167,167, 39, 70,142, 28,233,177,115,231,206,168, -168,168, 40,200,229,114, 60,121,242, 4, 95,127,253,117,212,252,249,243, 61, 70,140, 24,129, 3, 7, 14, 32, 62, 62,254, 55, 83, -210, 49,112,224,192, 73,126,126,126, 87, 19, 19, 19,155,165,167,167, 55, 56,118,236,216,168, 62,125,250, 68, 15, 26, 52,168, 67, -145, 5,203, 96,216,119,246,212, 81,116,255,244, 51,212,173,223, 96,243,136, 57,123, 27,154,155, 16, 51,204, 48,163,204,118,164, -180,157, 49, 49, 49,153,222,222,222,174,158,158,158,148, 78,167, 67, 86, 86, 22, 46,158, 63,111, 60,112,232,208, 89,157, 78, 55, -149,162, 40,193,174, 61,123, 54, 59,187,184,180,251,172,111, 95, 98, 48, 24,208,177, 99, 71,225,213,171, 87,237,158,198,196,228, -148,119, 65,154,166,139,172, 71, 95,124,241, 5,214,172, 89, 83,216,123,252, 67,224, 25, 12, 38,251, 34, 73,228,108,183, 54, 29, - 27, 88,198,202,126,177,212, 55, 55,228,186,191,177,184, 47,203,149, 4,130, 18,242, 32, 17,131,213,137,153,200,204,142,193,111, -222,214,244,145,104,146,107,182,168, 27,132,131,247,143,119, 3,112,200,212, 76,146, 72, 36, 77,164, 82, 41,194,195,195,211, 3, - 2, 2, 50, 45, 45, 45,173,188,188,188,236, 37, 18, 73,147,170,102,124, 82, 82,210, 91, 87, 87,215,214,159,125,246,217,100,138, -162, 58,178, 44,123, 37, 45, 45,109,125, 82, 82,210, 91, 83,254,239,234,234, 58,145,227,184,121, 0,142, 20,238,211,233,116,160, - 40, 10, 28,199,161,103,207,158, 88,186,116,169,207,149, 43, 87,112,243,230, 77,219,193,131, 7,223, 87, 40, 20,153,132,144,209, -241,241,241,101, 90,201,210,210,210,176,121,243,102,240,120, 60, 88, 91, 91,195,194,194, 2, 98,177, 24,109,219,182, 77, 90,185, -114,165,215,254,253,251, 13,153,201,201, 68,146,147,165, 37,118,118, 98, 40,170,119, 25, 58, 96,224,125, 0,135, 77,189,119,185, - 92, 46, 17, 66,155, 67, 25, 53,212,138,249, 27,120, 82,129,128,136, 5, 60,136,216, 60,122,206,210,197,156,152,112,252,194, 33, - 83, 83, 33, 22,139,133, 50, 33,167,229,139, 40,131,148,226, 62,202, 56, 43,143,199, 19,137,248, 80,151,117, 92, 64, 17,154, 16, - 34, 1,160,173, 76, 58,229, 66, 99,153,231,139, 41,208, 20, 69,137,203,226,236, 95,159,112,135, 39, 23, 10,156, 34,163, 26, 24, -134, 65,147, 38, 77,112,224,228, 53,156,251,253, 46, 82,223, 63,197,212,137,163,224,229,229, 85,161,184, 42,244,193, 50,161, 83, - 0,133, 66,113, 93,249,131, 85,197, 39, 23,248, 93, 85, 52, 52, 88,156,211,103,121,120,185,179, 19,221,220,220,198,249,249,249, - 13, 63,126,252, 56,218,181,107,135, 30, 61,122,160,110,221,186, 30,131, 7, 15, 6, 0,180,110,221, 26,223,127,255,189,199,231, -159,127,142, 19, 39, 78,224,220,185,115, 8, 12, 12,156,166, 80, 40,146,149, 74,229,198,114,196,213,252, 49, 99,198,204, 93,191, -126, 61,248,252,252, 21,161,122,247,238, 93, 88, 63,238,232,223,191,127, 90,225,185,135,183,199,221,173,229,225,213,124,210,212, -175,132,147, 39, 12,155, 13,224,115,115, 51, 98,134, 25,102,152, 44,176, 0, 64,164,215,215,213,110,222, 12,213,149, 43, 16, 94, -186,132, 51,141, 26,229, 50, 12, 51, 83,169, 84,198, 2,128,147,147,211,244, 67,135, 15,223,233,248,251,239,150,186,240,112,184, - 61,123, 6, 94,157, 58,126,166, 94,120,201,146, 37, 69,162, 0, 0,246,236,217,131,172,172, 44,100,101,101,129, 97, 76, 94, 75, - 24,124, 33, 90, 58,218, 85, 71, 2, 34,193,242, 40,249,187,186,121, 77,229, 26, 11,165,107,140,147, 42, 75, 80, 7,225,113,245, -101,234, 76,109, 83, 66,235,160, 73,205,131, 91, 75, 47,240, 80,250,240, 99,153,102, 62,138, 42,108, 28,211, 67, 66, 66,122,182, -108,217,242, 52, 0,251,194,253, 85, 69,124,124,252,107, 0, 83,171,242, 95,154,166,231,221,186,117,203,241,208,161, 67,147,127, -254,249,103,174,184,192, 42,252,206,227,241,192,113, 28,100, 50, 25,120, 60,158,211,137, 19, 39,156, 62,253,244,211, 13, 0,202, -124, 78, 82,169, 20,142,142,142, 16, 10,133,176,176,176,128, 42, 59, 67,182,233,167,185,109,165, 54, 78,182, 83,167,205,164,198, -141, 27, 23,182,118,237,218,106,206,117,235,122, 63,127,254,252,109,159,129,159,223, 61,121,242,164,186, 18, 14,238, 79,195,195, -195,105, 47, 79,119, 1,107, 80,179, 50, 1, 32,126,242, 51, 43,180,112,134,152,166,193, 35,224, 36, 82,153, 99,108, 66, 66,140, -169, 86, 49,142,227,158,188,123,247,142,184, 41,156,120, 57, 42, 77,166,140,199, 10,163, 31, 61,124, 89,171,113, 19,111, 0,208, - 60,186,123, 92, 84,183,190,133, 50, 59, 71,226,234,234, 26,101, 10, 39,195, 48, 79,226,226,226,136,173,173, 45, 63, 50,242,245, -111,118,150, 22, 10, 91, 39,167,182, 0,160, 75, 79,185, 73,212, 26, 37,159,207,119, 77, 73, 75, 75, 96, 24, 38,198,212,116, 70, - 71, 71, 19, 55,133, 19,239,244,217,115, 7,156,101, 82, 23,107,137,200, 74, 76,129,136, 57, 54, 75,200, 48,137, 18,169, 76, 17, - 23, 31,159,196,113, 92,153,126,130,155,216,201, 67,243,191,253,186,183,132,117, 7,215,130,163, 97, 69, 27,193, 55,168,112,255, -216, 33,124, 54,229, 75,147,222,167, 21, 11, 71,236, 95,177,112, 68,153,225, 25, 74, 8, 34, 40,199,255,197,154,103,139,247,245, - 63,113, 42,203,119,112,239,210,165,203,119, 91,183,110,149, 22,254,126,249,242, 37, 90,182,204,127,149, 23, 44, 88,128,206,157, - 59,163, 81,163, 70,120,249,242, 37,106,212,168,129, 99,199,142,129,166,105,254,184,113,227,190, 1,176,177, 28,203,109,207, 45, - 91, 62,116,211,210,235,245, 96, 24, 6, 6,131,193,133, 97, 24,151,194, 78,223,207, 63,175, 75,189,116,241, 12,190,153,179, 0, -142, 14,206,126,230, 38,196, 12, 51,204, 40, 83, 59,148, 89,233,112, 28,203,164,167,131,211,230,119,164, 5, 2, 1,199,113, 92, - 81,229,198,231,243,165, 86, 86, 86,132,239,230, 6, 34, 42,112,245, 33,228, 47,199,131,225,241,120, 48, 26, 77,167, 49, 26, 65, -131,232,193,225, 15,127, 83,149,152,224, 71,251, 14,152, 42,251, 18,137, 66,171,226, 45, 28, 56,134,133, 17,149,179,142, 16, 66, - 56,149, 74, 5,173, 86,107,227,233,233,121, 86,163,209,216, 20, 52,152,127,155,147, 43,195, 48, 81, 60, 30, 15, 35, 70,140, 0, -242,151, 60,130, 78,167,195,227,199,143,161,213,106,161,211,233,112,231,206, 29,100,101,101, 65,167,211,225,242,229,203,168, 81, -163, 6,120, 60,158, 75,121,188, 44,203,194,193,193, 1, 78, 78, 78,208,170,178,101, 71,183,174,237,190,124,254,183,246,131, 60, - 57,234,215,117,171, 88, 79, 79,207,140, 6, 13, 26,216, 74, 36,146,140,128,128,128,204, 19, 39, 78,156,170, 76,136, 6, 0,167, -103,207,158,237, 27, 20, 20,228,110, 45,151,233, 69, 66, 26, 34, 70,197,137,180,105, 28, 79,157,202,213,112,115,215, 67, 38,111, -210,183,111, 95, 35,128,211,166,114, 78,157, 58,181,186,183,183,183,189,181,165, 44,155, 71, 33, 94, 96, 52,198,103, 4,223,189, - 12, 0, 2,123, 71, 53,100,242, 38,131, 7, 15, 54, 84,134,115,230,204,153,158,174,174,174,118, 20, 69, 50, 25,189,254,125, 81, -121,208,168,147,104,145, 88, 5,145,184,213,232,209,163,153, 74,166,211,195,215,215,215,206,198,202, 50,147, 79,145, 24,129,145, -137,149,112,198, 56,161, 65,159, 34,114,116,202,133, 76,222, 98,208,160, 65,101,166,179,208,122, 85,210, 50,196,227,241, 16, 31, - 31,143, 60,229, 83, 8,226,195,209, 72,206, 71, 83,103,123,200,100,178,138, 5,214,248,151, 36, 44,154, 35, 97,209, 28,193,248, -151,164,180,223,165,136,172,114,203,126,185, 67,125, 91,188,175, 87,133,243,220,185,115,203,122,245,234,101, 24, 56,112, 32, 46, - 95,190, 12, 66, 8,110,223,190,141,248,248,120,116,238,220, 25, 28,199,225,241,227,199, 69,226,171, 95,191,126,232,209,163, 71, -222,133, 11, 23,126, 52,181,112,110,221,186, 21, 12,195,128,207,231, 67, 34,145,192,210,210, 18,182,182,182,112,114,114,122,227, -232,232,248,124,201,230, 19,175, 59,117,238,129,244,180, 84, 36,167, 36, 62, 54, 55, 33,102,152, 97, 70,165, 5,150, 65, 36,122, -193, 78,153, 2,235, 83,167,192,143,140, 68,191,207, 62,179, 20,137, 68,235, 92, 92, 92, 2, 20, 10, 69, 11,137, 68,178, 97,230, -140, 25, 22,246, 75,150, 64,113,243, 38, 18,175, 92,129,129,207,127, 84,153,139,171,213,234, 66, 1, 3,109,129,144,179,182,182, -174,148,192, 98, 25,220, 75, 72,137,132, 16,238, 96,193,229, 94,200,110,253, 96, 80,212, 92,199, 51,217,181,188, 94,171, 4, 94, - 11, 29,154, 58,174,171,209,242,129,138,240,114,133,214, 98, 40,227,149, 48,130,189, 87,153,116,106, 52,154, 44,149, 74,133,218, -181,107,219,133,132,132,120,122,121,121,217, 22, 8,154,135,127, 37,243, 21, 10, 69, 51,127,127,255,195, 1, 1, 1,111,253,253, -253, 15, 43, 20,138,102,149,248,251,175,143, 30, 61, 2, 77,211, 24, 55,110, 28,114,114,114,160,215,235,145,150,150,134,152,152, - 24,232,116, 58,196,197,197,225,213,171, 87,208,233,116,120,247,238, 93, 81, 30,151, 7,131,193, 0, 11, 11, 11,100,166, 37,203, - 14,110, 90,213,125,241,252,239, 36, 89,111, 66, 16,167, 76, 2,107, 84, 43,191,255,254,251, 40, 79, 79,207,219, 90,173,182, 30, -195, 48,221, 56,142, 59, 88, 9,161, 74, 1,120,236,229,229,213,105,229,202,149, 45,191, 95,186, 93,100, 65,231,112, 66, 11, 17, - 43,180, 16,114,194,122, 77, 49,102,222,122,241,234,213, 43,238, 5, 7, 7,103,153, 56, 51,143, 2,240, 56, 32, 32,160, 89, 98, - 98, 98,203, 70,141, 26,249, 57,215,174, 35, 22,185, 42, 82,133,138, 26,105,156, 58,239, 10, 85,189,102,207,157, 59,119,222,186, -121,243,102, 82,101, 56,157,156,156, 90,110,222,188,217,191,122,245,234,141,197, 86, 86,146,220,204,204,173,218,204,244,237,124, -123,103, 9,101,103,223,255,232,209,163,191,159, 61,123, 54,173, 50,156,117,235,214,109,177,100,201,146, 70,254,254,254, 1, 46, -117,234,138, 37,174,110, 41, 2,215, 26,201, 18,223, 64, 49, 85,195,163,223,246,237,219,175,221,185,115, 39,213,212,128,163, 20, - 69,129,207,231, 67, 38,147,225,198,141, 27, 24,244, 89, 23, 56, 59, 90,162, 78,221,186,104, 59,126, 10,206,158, 61, 11,161, 80, -136,191,106,109, 45, 9, 83, 4, 81,101,197, 87, 69,156, 74,165,114, 99,112,112,240,207, 3, 6, 12, 64,199,142, 29,241,228,201, - 19,204,154, 53, 43,234,236,217,179, 0,128, 39, 79,158, 96,241,226,197, 81,247,238,221,195,200,145, 35,209,178,101, 75, 60,126, -252,120,119,101,130,143,142, 26, 53, 10, 6,131, 1,185,185,185, 72, 79, 79,199,153, 51,103,208,168, 81, 35, 78, 42,149,126, 70, - 87,235,244, 99,255, 49,115,154, 55,240,245,195,134,117, 43,117, 66, 30,127,169,185, 9, 49,195, 12, 51, 42, 37,176, 60,109,109, - 45, 52,154,188,184,155, 55,111,234, 41,138,130, 84, 42, 69,255,129, 3,169,159,126,250,169, 85,239, 70,141,174, 14,110,214,236, -252,161,131, 7,253,253,252,253,243,215,219,161, 40,156, 60,121, 82,157,149,149,153, 86,189,122,117,107, 83, 47,158,146,146, 82, -212,251, 86,171,213,224, 56, 14, 22, 22, 22,149, 18, 88,234, 92,234,202,173, 27, 97, 25,156,241,139,152,110,175,215,232,151, 38, -246, 14,202,100,141,188, 44,163, 1, 89,106, 14, 57, 26,240, 30, 80,182, 65, 35,188,250,232,163, 59, 6,189,122,240, 54, 52, 77, -199,233, 42, 53,251, 33, 35, 35,227,187,137, 19, 39,166, 57, 57, 57, 17, 11, 11, 11, 56, 57, 57, 81, 99,198,140, 73,141,141,141, - 93, 88,213,140,247,241,241,249,188, 89,179,102,167, 67, 67, 67,251, 29, 58,116,200,253,240,225,195,253,154, 53,107,118,218,199, -199,199, 84,159,142, 67,203,150, 45, 83, 9,133, 66, 52,109,218, 20, 57, 57, 57,208,233,116, 21,110, 21, 10, 86,150,133, 88, 44, -198,225,237,107, 59, 45,158,255,157, 36, 61,252, 1,158,222,190,140, 11,111,181,121,243,150,254,124, 95, 44, 22, 87,233,126,189, - 28,101, 13, 27, 42, 44, 94,126, 57,106,160,114,246, 55,223, 88, 61,123,246, 76, 58,227,203,233,156, 50, 37,147, 19,119, 95, 77, - 83,109,191,167, 94,104,236, 73,175, 30,237,241,227,130, 89,157, 96,194,208,169,143,163,172, 97, 3,133, 69,216, 87,227, 6, 69, - 77,157, 58, 85,186,108,217,178,188,150, 45, 91,102,102,101,101, 73,172,156, 92,252, 69,142, 78, 65,202,140, 76, 89,243, 22, 45, - 30,143, 26, 53, 74, 85, 89,206,239,191,255, 94,118,235,214, 45, 81,151, 46, 93,114,178,179,179,101, 98,185, 60, 72, 96,105,221, - 58, 37, 43,203,178,107,215,174,161, 3, 6, 12, 48, 84,133,243,213,171, 87,162,230,205,155,231,100,101,101,201, 44,157, 92,154, -136, 29,157, 91,197,167,103, 88, 52,109,214, 44,116,236,216,177,186,242, 56,251,175,255, 67,156, 72,165,210,116,111,111,111,204, -157, 59, 23, 11, 22, 44, 64,255,254,253, 17,253, 54, 26,109, 70,142, 67,173, 17, 19,112,250,222, 3,196,199,199, 99,206,156, 57, -240,242,242, 2, 69, 81, 9, 31,179,242, 40, 79, 16,149,229, 8,239, 83,139, 92, 47,207,207,170, 34,145,213,169, 83,167,145,189, -122,245,194,201,147, 39, 49,107,214,172,168,249,243,231,123, 12, 25,146, 63,161,207,207,207, 15, 51,103,206,244, 88,185,114,101, -212,234,213,171,209,172, 89, 51,184,185,185,125, 90, 9,171, 48,118,236,216, 1,134, 97, 32,151,203, 97,107,107,139, 30, 61,122, -224,249,243,231, 19,118,238,220, 25, 78,243,249,131,187,127,218, 23,103, 79, 29,195,171, 23,207, 39,236,250,105,232, 51,115, 19, - 98,134, 25,102,148,133,210,227, 96, 89, 74, 6,110,221,184,193,106,242,244,153, 42,111,111,111, 27,103,103,103, 16, 66,208,165, - 75, 23,210,236,194, 5, 11,190, 66, 1,187,134, 13,139, 22, 52,188,117,243, 38,174, 94,189,170,218,187,227, 87,215, 81, 99,198, -244, 4,202,246,153, 45, 62,172,150,150,150, 6,103,103,231,162,217,106, 74,165, 18,206,206,206, 16, 8, 4,160,105,154, 87,176, -244, 75,185,106,203,217,217,121,207,210,197, 47,102,199,249,206,172, 21, 36,165,200,121, 85, 34,140, 28, 7, 62, 49, 2,106, 14, - 6, 35,160, 53,112, 8,172, 73,219,254,174,131,205,131, 23,151,162,157,157,157,247, 84, 38,147,162,162,162,174,185,184,184,140, -207,203,203, 59, 2,128,186,127,255, 62,251,246,237,219, 73,166, 58,164,151, 6,137, 68, 50,235,200,145, 35,182, 11, 23, 46,204, -184,122,245,106, 86,251,246,237,173,150, 46, 93,106,251,249,231,159,207, 66, 41,193, 32, 75,105,136,212, 10,133, 98,119, 66, 66, -194,164,198,141, 27, 35, 61, 61, 29,122,189, 30, 33, 33, 33,240,242,242, 66,112,112, 48,234,212,169,131, 71,143, 30,161,110,221, -186, 48, 26,141,208,104, 52, 48,154,160, 94,149,177,239,229, 82,109,134,165,242,193,121, 68, 60, 11,193,185, 40,109,222,138, 29, - 7,207, 53,244, 11, 84, 21,206, 48,172, 12,234, 58,201,234,187, 58,218, 93, 90,186,224, 7,199,119,215, 14,226,216,142,245,236, -181,115,231, 26, 72, 44, 49,188,197,192,105,159,235, 13,112, 7,129,168,117,139,230,232,105, 27, 97, 20, 84, 67,210,239, 47,202, -143,100, 94,215, 73, 86, 95,225, 96,119,113,197,146,133, 22,111, 46,236,194,161, 45,171,185, 35,123,246,251,107,128,250,158,158, -158, 61,105,154,118, 2,160, 54, 26,141,111, 96,226, 18, 52,165,113,254,126,230, 76,128, 6,168,239,230,230,214,147,207,231, 87, - 3,160, 53, 24, 12,239, 63, 6,103,237,218,181,123, 18, 66, 92, 1,104, 10,124,174, 42,181, 84, 78,199,142, 29, 87,108,223,190, -125,134, 86,171,181, 45,102,109, 37, 39, 79,158,132, 94,175, 39, 2,129,128,149,201,100,136,137,137,225, 0, 36,112, 28, 55,225, - 99, 85, 28,125,251,246,197,253,251,247, 23, 0,152, 87,222,121,233,233,233, 60, 91, 91, 91,166, 34,225,101, 42,231,131, 7, 15, -150,141, 29, 59,246,235, 11, 23, 46,196,205,159, 63,223,111,196,136, 17, 56,113,226, 4,170, 87,175,142, 87,175, 94, 97,198,140, - 25, 32,132,120,172, 92,185,242,241,129, 3, 7, 92, 18, 19, 19, 87,153,114, 63, 70,163, 17, 12,195, 96,208,160, 65, 48, 24, 12, - 72, 73, 73, 65, 68, 68, 4,110,221,186,133, 9, 19, 38,136, 1,192, 69,225, 22, 40, 20, 10,241, 36,244, 81,222,247,163,131,126, - 51, 55, 31,102,152, 97, 70,165, 45, 88,132, 37,124,175,218,181,141,186,188,220,157, 99, 70,142,204,123,241,226, 69, 81, 5,164, -121,248, 16,170, 11, 23, 96, 52, 26,193,113, 28, 30,220,191,143,169, 83,166,228,106,242,114,183,215,172,233,206, 17,142,147, 21, -241, 16,210,177, 36,183,174,152, 25, 69,173, 86, 67,173, 86,131,199,227,193,194,194, 2,201,201,201, 16, 10,133,144, 72, 36,104, -212,168, 17,229,230,230,214,227, 79,105, 43,193, 25, 18, 18, 98, 64,182,182,223,201, 17,211, 18,220,242, 24,110,188,117, 77,212, - 16, 72,138,102, 33, 58, 91, 18,124,218,136, 15, 39, 65, 42,247,116,215, 32, 37, 97,178,250,133,132,132, 24,202,227, 44, 9,133, - 66, 81,199,199,199,103, 99,223,190,125, 41, 0,104,213,170, 21, 85,191,126,253, 95, 20, 10, 69,153, 75,218, 84,196, 41, 22,139, - 69, 0,112,229,202,149,244, 91,183,110,117,185,114,229, 74,122,241,253,166,112, 82, 20,181,117,211,166, 77,144, 74,165, 96, 24, - 6, 58,157,174,200,255,170,248,167, 94,175,135,189,189, 61,126,255,253,119,176, 44,123,182,162,116,122, 55,240,205,205,226, 89, - 39,237, 62,125, 21,231,223,233,115, 43, 43,174,138,115,214,118,145,215,117,182,183,187,188,226,167, 69, 14, 25,175, 67, 16, 23, - 23,199, 93,188,112,246,158,154,227,226,211,178,184, 31,211,115, 56,159, 92, 13, 39, 13,172,137,216,179,191,204,224,190,106, 6, - 6, 4, 92,121,156,245, 93,228,117, 93, 29,236, 46,174, 90,241,147, 69,230,235, 16, 36, 36, 38,226,220,217,211,143,213, 28, 23, -207,113,220, 5,142,227, 38, 50, 12,211,132, 97,152, 38, 28,199, 77, 44, 75,180, 84,150, 83,175,215, 7,233,245,250,160,143,201, -201,178,108, 16,203,178, 38,115,254, 49,131, 16,152, 59,119,238,195,155, 55,111, 14,120,248,240, 97,135,194,237,249,243,231,237, -163,163,163,219,199,197,197,181,139,158, 37,162,159, 61,123,198,123,244,232, 17,255,209,163, 71,213,131,131,131, 47,152, 90, 62, -203,121, 23,138,139,252,249, 74,165,146,148,202, 57,254, 37,217,176,242,139,189,135, 15, 31,118,250,104,156, 0,194,195,195, 55, -108,223,190,189,134,171,171,171,203,231,159,127,142, 93,187,118, 97,251,246,237, 0,242, 35,217, 23,179, 92, 57, 6, 7, 7,215, - 42, 45,200,104,105,247,110, 48, 24,192, 48, 12,246,239,223, 15,134, 97,224,224,224, 0, 31, 31, 31, 76,154, 52,233,218,152, 49, - 99, 54, 2, 0, 77,104, 1, 0,104, 53, 90,109,201, 32,163, 85,205, 79, 83,223, 35, 51,167,153,243,223,192,249,239, 16, 88,132, - 53, 26,141, 44, 28,157, 28, 45, 82,146,147,215, 79,156, 56, 33,109,225,194,133,154, 27, 55,110, 64, 23, 30, 14, 77,104, 40, 46, - 95,190,140,105,211,166,229,141, 27, 63, 62, 65,147,151,187,214,217,201,209,222,104,100, 65, 8, 91,174,133,132,162,168,168,200, -200,200,194,222, 54,214,175, 95,207,232,245,122, 88, 88,228, 7,153,222,182,109, 27,203,113, 28, 58,116,232, 32,227,243,249, 38, - 45, 65, 18, 31, 31,255, 52, 59, 70,217,249,232,192, 9,111, 94, 30, 60,149,225,155,166,199, 16,137, 2, 3, 3, 0, 31,139, 24, -196, 63,248, 53,227,238,198,222,111,242,210, 99,187,196,199,199, 63,173,108, 38, 57, 57, 57,205,219,183,111,159, 99, 72, 72, 8, -167,213,106, 17, 31, 31,207,205,154, 53,203,209,201,201,105, 94, 85, 51,158,227, 56,146,153,153, 9, 66, 8, 91, 80, 88,217,194, -253,166,114,196,197,197, 61, 63,124,248,240,201,107,215,174,193,205,205,173, 72,100,149, 20, 88, 60, 30, 15,132, 16,108,218,180, - 41,147, 16,242,109, 69,188, 34,145, 8,219,142, 92, 56,255,213,166, 99,135, 14, 93,121,120,172,170,150, 43, 0, 16, 82,212,252, -101,139,126,112, 76,125,121,159, 60,191,119,149, 61,248, 36, 33,137, 49,114,147, 75, 61, 57, 71,201, 21, 20,202,242,125,123, 40, -122,254,178,159, 22, 90, 21, 14, 95,238, 11, 81,102, 19, 35, 55,229,175,189, 9,255, 35,156,127, 35,242,103,250, 41,137, 66,161, -192,209,163, 71, 43,237,131,229, 83,139,252,201,185,189,170,156, 74,165,114,249, 39,159,124,162,156, 63,127,254, 70,141, 70,163, - 42,232,188,233, 87,173, 90,181,114,242,228,201, 73,241,241,241,171, 76,126, 76, 20,181,167, 83,167, 78,220,205,155, 55,209,187, -119,111, 24, 12, 6,196,198,198, 98,219,182,109, 96, 24, 38,187, 67,135, 14, 44, 0,168, 53,121,217, 28,203, 65,167,215,106, 97, -134, 25,102,152, 81, 1, 74, 29, 34,100,105,234,206,230, 45,155,186, 30,220,127,192,153,166, 41,231,232,232,183,143,134,141, 30, - 29,127,243,230, 77, 91,126,237,218, 77, 40,138, 98,117,179,103,223,203,205,206, 74,223,179,115, 71,141,154, 53,221, 27, 21, 44, -246,204,177, 52,117,167,188, 11,166,167,167,239,154, 62,125,122,147,221,187,119, 11,150, 47, 95,174,138,143,143,191,116,255,254, -253,174, 27, 55,110, 20,111,219,182, 45, 47, 39, 39,231,212,185,115,231,122,181,107,215,142,209,233,116,121,166,222, 72, 82, 82, - 82, 24, 33,196,155, 90,181,125,240,171, 77,251, 62,225,104,210, 2, 90, 1, 8,199,220,161, 24,213,229, 36,165,114, 31,199,113, - 76, 85, 50, 73, 34,145, 52,146, 72, 36,120,253,250,117, 70,147, 38, 77,116, 66,161, 80,224,238,238,110, 39,145, 72, 26, 85, 53, -227, 57,142,227, 50, 50, 50,192,113, 28, 15, 0, 97, 89,150, 87,176,191, 82, 49,156, 4, 2,193,231,163, 70,141, 58,185,113,227, -198, 78, 29, 59,118,132,135,135, 7, 12, 6, 3,234,212,169, 3,157, 78, 7, 47, 47, 47,104,181, 90,172, 93,187, 22,185,185,185, - 51,226,227,227, 51, 42,226, 20,139,197, 16, 10,133,168,235,221, 32, 79, 44, 22,163,170,226, 10, 0,100,124,202,227,213,153, 29, - 72, 78, 75,101, 15, 61, 73, 74,202,211, 27, 59, 71, 38,171, 94,148, 60, 47,207, 8, 85,187,145, 83,227, 1, 64,203, 34,183, 92, - 78, 33, 60, 34,206,110, 67, 82,114, 42, 14,134, 38,100,170,244,108,151, 87,165,112, 86, 42,157,255, 35,156,253,215,135,163,237, - 23,166,159,123,120,252,199,169, 40,138, 91,149, 76, 69, 88, 52, 71,176,197,155,195,150,245,165,198,184,170, 10,103,177, 78,213, - 22, 0, 91, 0,192,205,205,237,205,212,169, 83,191,142,143,143, 95, 83, 16,239,170, 82, 29,159,131, 7, 15,174, 29, 53,106,212, -133,158, 61,123,126,195,178,172,111,177, 30,122,180,163,163, 99, 81, 14,166, 36, 37,206, 30, 63,122,208,236,220,220,140, 69, 48, -195, 12, 51,204,168,138,192,138,138,138, 13,243,240,168, 54,231,216,209, 35, 45, 56,142,162, 57, 66, 84, 0,117,250,197,139, 23, -153,197,207,243,180,181,181, 24, 53,118,212, 64,194, 18, 62, 33,172,145,165,169, 59, 81, 81,177, 97, 21, 84,140,207,134, 15, 31, -190,190, 93,187,118,163,141, 70,227,242,200,200,200, 75,117,235,214,125,220,165, 75,151,175, 24,134, 89,249,230,205,155, 75,245, -234,213,187,124,240,224,193, 89, 70,163,241,135, 74,138, 22, 6,249,254, 95,187, 63,102, 38, 81, 20,181,144,227, 56, 43,137, 68, -146, 21, 28, 28,188,191,117,235,214,131, 56,142,179,162, 40, 42,171,170,156, 58,157,110, 74, 78, 78,142,253,231,159,127,110, 32, -132,212,237,211,167,207,236,200,200, 72,190, 74,165,138,170, 12,207,187,119,239,180,238,238,238,189,190,248,226,139,237, 2,129, -160, 3,242, 67, 54,112,197,242, 4, 28,199,193,104, 52,158, 82, 42,149,229,230, 11,159,207,207,237,218,181,171,188, 66,171,148, - 80,152,107,106,250,114,116,198,233,155,174,190, 88,162, 49,112, 28,195,114,227, 95, 37,169, 74,157, 66,246,240, 21, 87,223,100, - 78, 13, 59,125,221,197,176, 37, 90, 3,203, 50, 44, 55,161, 44,206,202,224,127,133, 19, 0, 38, 82,235,247, 98,203,250, 34,135, -247,194, 97,195,146,191,255, 83, 40,176, 56,113, 0, 42, 94,236,188,192, 98, 85,209,218,133,149,226, 44,129,130, 89,130, 91,255, -202, 61,237,216,177, 35, 18, 21, 44,176,125, 96,229,168,227, 0,142,155,155, 13, 51,204, 48,195, 84, 81,242, 31,219, 0,116, 52, -115,154, 57,205,156,102, 78, 51,167,153,211,204,105,230,252,183,109,148, 89, 98,154, 97,134, 25,102,152, 97,134, 25,102,124, 92, - 16, 0, 29,203,176,108,153, 28, 43,170, 42,179, 9, 42,226, 55,115,154, 57,205,156,102, 78, 51,167,153,211,204,249,255,143,243, - 95, 3,243, 16,161,153,211,204,105,230, 52,115,154, 57,205,156,102, 78,243, 16,161,121,136,208, 12, 51,204, 48,195, 12, 51,204, - 48,227, 31, 13,179,192,170, 2, 8, 33,195, 8, 33, 23, 8, 33,207, 9, 33, 23, 9, 33,195,254, 2,151,132, 16, 50,187, 24,223, -121, 66,200, 44, 66,136,200,156,211,255,232, 50, 64,155,115,193,140,170,162, 32,120,113, 72,121,193,138,205, 48,195,140,255,109, -240,202, 58,224,233,233,121,151,162,168, 90,133,139,196, 22, 70, 70, 47,252, 94,242, 55, 0,112, 28, 23, 29, 22, 22,214,188, 44, -206, 90,181,106, 21,113, 22,110,132, 16, 24, 12, 6, 11,154,166,115, 74,227, 52, 26,141,113,175, 94,189, 10,252, 7, 53,172,123, -109,109,109,217,205,155, 55,111,240,245,245,173,157,147,147,147, 55,118,236,216,110,132,144,142, 28,199, 13,173, 36, 87, 3, 66, -200,158,198,141, 27, 31,155, 60,121,242, 97, 31, 31, 31, 75,181, 90, 45,220,191,127,191,243,230,205,155,111, 17, 66, 70,113, 28, - 23,102, 46,166,255, 28,184,184,184,248, 19, 66,214,123,121,121, 5, 42, 20,138, 71, 0, 38, 41,149,202, 39,230,156,249,175,190, -131, 99,132, 66, 97, 23, 47, 47,175, 38, 90,173, 54, 35, 58, 58,250,161,209,104,252,129,227,184,196,143,196,111, 5,224, 7,145, - 72, 20,228,233,233, 89, 45, 50, 50, 50, 86,175,215, 63, 0,176,144,227,184,172,143, 33,174,130,130,130,110,255,244,211, 79,118, -223,126,251,237,109,133, 66,209, 82,169, 84, 70,152,159,172, 25,127, 7,170, 87,175,110,173, 82,169,182,243,120, 60,127,145, 72, -228, 44,151,203, 33,151,203, 19, 69, 34,209, 99,169, 84, 58,250,236,217,179,153,230, 92,250,200, 2,139,166,105,183,135, 15, 31, - 58, 22, 46,190,204,178, 44, 88,150, 5,199,113, 69,159,133, 40,136,179,132,118,237,218,233,203,189, 24,143, 87, 45, 36, 36,196, - 81, 46,255, 35,212,146, 94,175,135,175,175, 47, 27, 26, 26,234, 88,114, 33, 97,157, 78,135,128,128, 0,238,159,146, 89,132,144, - 33,118,118,118,170,247,239, 99, 90,107,180,250,160,177, 83,190,157, 51,164,223, 39, 54,119,238,220, 65,207,158, 61,105, 66,200, - 48,142,227,246,152,200, 37, 33,132,252, 58,103,206,156,101,124,161,212,241,232,217,219,244,218,173,123,223,251,213,169, 73,166, - 78,157, 36,159, 60,121,242, 35, 31, 31,159, 29,132,144, 86, 28,199,153, 35, 71,255, 51,158, 63,175, 90,181,106, 39,151, 44, 89, -226,154,152,144,128,213,107,214, 52, 5,176, 17, 64, 83,115,238,252,215,158,193,236, 5, 11, 22, 44, 25, 60,120, 48,140, 70, 35, -212,106,181,226,245,235,215,245,231,206,157,219,135, 16,210,132,227,184,168,191,200,239,224,229,229, 21, 62,125,250,116,219, 38, - 77,154,128,162, 40,100,101,101, 41,110,221,186,213,244,215, 95,127, 29, 70, 8,169,199,113, 92,202, 95,185,134,141,141,205,111, - 43, 87,174,180, 19,137, 68,216,185,115,167,221,128, 1, 3,110, 41, 20,138, 86, 85, 21, 89,132, 16,202,206,206,110, 42,128,246, - 44,203, 10, 1, 60,200,200,200, 88,204,113,156,222, 92, 98,204, 40, 15,246,246,246, 99,114,114,114, 54, 72,165, 82,129,165,165, - 37,164, 82, 41,248,124, 62,132, 66, 97,117, 27, 27,155,234,114,185,188,219,160, 65,131, 38,237,223,191,127,187, 57,183, 62,162, -192,162, 40, 10, 18,137, 4,135, 14, 29, 2, 77,211,224,243,249,224,243,249, 16, 8, 4,165,126,175, 94,189,186, 41, 21, 1, 0, -224,244,233,211,176,180,180,132,149,149, 21,234,213,171, 7, 66, 8, 68, 34, 17,126,255,253,119,240,249,124,240,120, 60,240,249, -124, 4, 6, 6,126, 96, 41,251,111,160,127,125,194, 1,165, 7,111,236, 94, 95,142,158, 83,126,234,155,167,209,119, 0,160,202, -204,200,200,120,116,236,152,210,175, 78, 29,193,161, 67,135, 26,217,218,218, 14, 2, 96,234, 66,210,211,154, 54,109,122,138, 19, -200,156,134,143, 24, 57,124, 52,143,210, 15, 27,255,213,143,177, 9,169,170,113,227,198, 29, 59,117,234,212,240,117,235,214, 69, - 78,154, 52,105, 42,128,229,166,166,223,221,221,253, 46, 77,211,133,150, 71,229,235,215,175,253,255, 33, 13,163, 2,192, 10, 0, - 6, 0,203, 56,142, 11, 47,118,172,142, 64, 32, 88,174,215,235,211, 1,204,227, 56, 46,246,159,248,178,184,186,186,214, 27, 58, -116,168,125,122,106, 42, 86,175, 89, 83,184, 59,208,148, 69,201, 63, 54, 2, 2, 2,106,137,197,226, 21, 0,252,181, 90,173, 43, - 0, 72, 36,146,120,142,227,142,171,213,234,239, 66, 66, 66,212, 85,124, 78,213, 0,212, 71,254, 12,227,210,192, 45, 89,178, 36, -114,246,236,217, 81,255,109, 78, 66,136,187,147,147,211, 79,253,251,247,199,217,179,103,113,238,220, 57,131, 68, 34,225,141, 24, - 49,130, 76,154, 52,201,102,250,244,233,221, 0,252,252, 23,179,182,219,130, 5, 11,108,189,189,189,113,228,200, 17, 60,125,250, - 84,237,229,229, 37,105,219,182, 45,120, 60,158,237,156, 57,115,186, 2,216,245, 87, 46,144,145,145,177,120,209,162, 69,187,215, -175, 95,111, 17, 29, 29,141,133, 11, 23,218, 79,158, 60,249,134, 66,161,104, 99,170,200, 42,112, 33,152, 10,160, 29, 77,211,173, - 70,140, 24,193, 76,153, 50,133, 79, 81,148, 97,205,154, 53, 14,191,254,250,235, 64,123,123,123,255,212,212,212, 92,152,129,114, - 12, 9,122,150,101,249, 0,196, 28,199,105, 43,250,253,255,233,222,237,236,236, 38,102,100,100,108, 84, 40, 20,112,112,112, 40, -106,107, 89,150,133, 74,165,130, 90,173, 70,173, 90,181, 4,222,222,222,219, 38, 79,158,204, 95,191,126,253, 38,115,137,249, 72, - 2,139, 16, 2,150,101,193,231,243, 63, 16, 88,133,226,167,228,247, 82,107,205, 18, 83, 53, 41,138, 34,185,185,185, 69,226,202, -210,210,178,200, 18,102, 48, 24,254,196,107, 52, 26, 65, 81, 20, 87, 30,103, 25,105,159, 8,224,119,142,227,222,152,146, 9,197, - 57, 15, 79,174,135,221,162, 89,131, 10, 67,158,119,251, 42,255,115, 55,128, 43,175,199, 47, 95,222,162, 69,181,169,223,175,155, -175, 78, 83,166,206, 25,218,211,221,203,217, 78, 34,203, 76,206,178,169, 91,183, 39,128,164, 74,164,179,229,184,113,227,142, 28, -187,242, 66, 44, 22, 11, 4, 60,154,230,183,108, 88,199,174,154, 21,109,101, 1, 88,197, 70, 69,222, 29, 54,108,216,216, 73,147, - 38,217, 22, 10, 44, 83,238,157,207,231,187, 61,120,240,192,145,199,227,161, 69,139, 22,198,202,220,251,199, 66, 25,156,115,147, -146,146, 62,215,104, 52, 8, 12, 12,252,148, 16,210,142,227,184,199,132,144,134,189,122,245,186,117,248,240, 97,139,208,208, 80, - 52,109,218, 84, 2, 96,192,223,152,206, 63, 65,161, 80, 92, 2,240, 9, 77,211,208,105, 52,186, 21,171, 62, 88,230, 46,184,184, -184,250,111,164,211,207,207,175,158, 84, 42,189,187,106,213, 42, 75, 31, 31, 31,194,231,243,193, 48, 12, 34, 35, 35,171,237,221, -187,119,252,163, 71,143,186, 6, 4, 4,248,148, 92,212,220,196,123,175,127,235,214, 45,149,135,135, 71,169,101, 39, 59, 59,155, - 87,167, 78,157, 54, 0,162,254, 6,206,184,164,164,164,222,159,124,242,201,132,196,196,196,112,134, 97,190, 1,208,192,222,222, - 62,244,179,207, 62,131, 68, 34,105,103,138,192, 42,239, 25, 57, 58, 58,246,106,222,188, 57,214,175, 95,143,101,203,150,117,228, - 56,238,119, 66, 72,135,236,236,236, 43,159,126,250, 41,172,173,173,123,151, 38,176, 42, 81,150,234, 52,105,210,100,219,140, 25, - 51, 44,206,158, 61, 11, 47, 47, 47,100,101,101, 97,228,200,145,142,235,214,173,187,174, 80, 40,218, 22,138,172,178, 56, 9, 33, - 62, 34,145,104,215,254,253,251,229, 30, 30, 30, 30, 2,129,128,242,240,240, 64,122,122, 58, 52, 26,141,232,199, 31,127,108, 40, -145, 72,158,252,252,243,207,187, 0,124,246,119,190, 71,132,144, 44, 0,150, 0,172, 43, 51,188, 90,206,189,103, 1, 16, 21,171, -239, 32, 22,139, 33, 22,139, 33, 18,137, 16, 29, 29,125,148,166,233,145, 5, 29,185, 10, 57,201, 31, 61,248, 70,132,144,135, 52, - 77,151,251,187,228, 82,102,127, 71,189, 68, 8,113, 35,132,172, 5,208, 14,249,126,212, 55, 28, 29, 29,167, 37, 38, 38,190, 55, -149, 83,161, 80,216,229,230,230,254,172, 80, 40,224,232,232, 88, 40, 54, 17, 24, 24, 8,141, 70,131, 23, 47, 94,128,101, 89,188, -121,243, 6,150,150,150,104,216,176,225,207, 11, 22, 44, 56, 50,111,222,188,180,255,228,189,255,107, 4, 86,161,146,229,241,120, - 31, 8,172,146, 91,161, 24, 34,132, 84,184, 80, 49, 33,132,210,233,116, 69,226,202,202,202,170,232,191, 12,195,148, 42,176,170, -168,204,125, 89,150,173, 69, 8,217, 98,170,200, 42,137,225,195,135,255,201,159, 99,246,236,217,113,169,169,169,108,223,206,141, -100,225,231,149, 9,158, 54,114,137,131,133, 69, 77,177,141,173,117,110,110,238, 77, 0,242, 74, 92,194,213,219,219,219,106,195, -238,243,202,177, 95, 46, 89, 20,232, 97,103,233,235,102,111,227,108, 37, 17,202, 41,162, 18, 51,134, 56,153, 76,230, 3, 32,173, - 50,233,166, 40, 10,150,150,150, 56,117,234, 20, 10,253,231,254, 33,176, 81,171,213,200,200,200,192,230,205,155, 45, 39, 76,152, -112,141, 16, 50,173,119,239,222,235, 15, 31, 62, 44,203,204,204,132, 94,175, 7, 0,245, 63,240, 61, 89,100, 99, 99,211,186, 93, -187,118,194, 3,135, 14, 9, 57,142, 83, 33,127, 57,162, 92,142, 43, 99,225,234,255, 32,196, 98,241, 87,139, 23, 47,182,244,241, -241, 33,105,105,105, 96, 89, 22, 20, 69,193,222,222, 30, 95,127,253,181,120,238,220,185,174,175, 94,189,154,131, 42, 44, 59, 3, -128,148, 37,132, 0,192,210,210,146, 65,229, 39,199,148,202,201, 48, 12,105,209,162,197,215,169,169,169, 13,213,106,245,143, 38, - 52, 60, 12,128, 83, 5, 91, 97,157,242, 36, 60, 60, 92, 61, 96,192, 0, 73,205,154, 53,131,254,106,222,214,169, 83,167, 25,159, -207,199,131, 7, 15,180, 0,110, 20,236,190,241,244,233, 83,237,103,159,125, 38,170, 86,173, 90, 51, 83,185, 20, 10, 69, 29, 79, - 79,207,203,246,246,246,146,194,105,219,221,187,119,231,175, 88,177,194, 34, 46, 46, 14,122,189, 30,179,103,207, 70,143, 30, 61, - 96, 99, 99,131, 81,163, 70, 57,109,221,186,245, 55, 0, 1,229,212,161, 98,161, 80,184,231,245,235,215, 94, 46, 46, 46,146,251, -247,239,195,215,215, 23,169,169,169, 72, 76, 76, 68,110,110, 46, 18, 19, 19, 49,122,244,104,199,213,171, 87, 43,254, 65,239, 80, -166, 64, 32,128, 84, 42,181,206,204,204,204,250, 11, 60, 34, 0,194,226,226, 74, 36, 18, 65, 36, 18,161,164,139,201,255, 71, 16, - 66, 92, 9, 33, 97, 2,129, 64, 36,149, 74, 5, 20, 69, 65, 38,147,117,174, 86,173,218,139, 97,195,134, 53,216,179,103,207, 59, - 83,120, 52, 26,205, 30,137, 68,194,119,112,112, 0, 0,116,234,212, 9, 35, 70,140, 64, 74, 74, 10,171, 84, 42, 81,175, 94, 61, -234,250,245,235, 72, 74, 74,194,147, 39, 79,208,164, 73, 19,190,173,173,237, 30, 0, 93,205,178,233, 35, 90,176,120, 60, 94,209, - 86,154,229,170,112, 43,233,248, 94, 22,167,209,104,132,147,147, 19,164, 82, 41,164, 82,105,113,103,246, 63,241,115, 28, 87,165, - 33, 66,153, 76,134,193,131, 7,115,155, 54,109,154, 80, 32,178, 94,155,250,223,254,235,195,139,172, 86, 37,225,235,235,123,231, -187,239,190,235,114,241,226,197,140, 64,143,154, 60,153,242,125,174,216,210,218, 26,110,213,187, 15,235, 63,240, 46,128,253,149, - 72,166, 82,171,213, 10, 60,221,164, 58,138,210,144,234, 34,158,133,139, 76, 32,114,182,177,113, 21,232,180,201,150, 54, 54,194, -130, 33, 51,101, 69, 68,133,147, 7, 8, 33,176,182,182,230, 23,124,194,209,209, 81,212,160, 65,131, 36,138,162,192,113,156,242, -217,179,103, 38, 15, 23,122,120,120, 4, 83, 20,229, 70, 8,249, 96, 66, 66,241,141,101,217,184, 23, 47, 94,152, 58, 1,225,187, - 70,141, 26,181,217,184,113,163,131,151,151, 23, 54,111,222,108,121,228,200,145, 93,191,253,246, 27, 50, 51, 51,241,238,221, 59, -140, 30, 61, 58, 27,249,195,136,255, 40,216,218,218,222,238,223,191, 63,182,109,219,198, 21,116, 34,100,132, 16, 95, 43, 43,171, - 87, 97, 97, 97,255,117, 63, 23,138,162, 58,215,171, 87,143,100,101,101,129,101, 89,208, 52, 93,212, 17,162,105, 26, 95,125,245, -149,100,244,232,209,115,155, 53,107,246, 53,159,207,207,102, 24,230, 64,110,110,238,143,207,159, 63,255, 71, 57,171,182,106,213, -234,203,216,216,216, 30, 53,106,212, 56,253, 23,122,251, 92,227,198,141,117, 0, 36, 52, 77,243, 63, 66, 3, 70, 23,212, 71,154, -194,197,225, 57,142, 99, 2, 2, 2, 52, 5,141, 59, 93,137,114,243,219,222,189,123,221,220,220,220, 96, 48, 24,192, 48, 12,114, -115,115,113,253,250,117,104,181, 90, 48, 12,131,122,245,234, 97,217,178,101,154, 73,147, 38,137, 15, 30, 60,152,172, 86,171,135, - 84, 64, 59,237,200,145, 35, 50, 23, 23, 23,137, 90,173, 70, 84, 84, 20, 2, 2, 2,144,147,147, 3,149, 74,133,188,188, 60,232, -245,122,100,103,103, 91, 27,141, 70,221, 63,166,161,225,241, 32, 18,137, 32, 16, 8, 50,107,212,168, 1, 66,136,248,221,187,119, - 85, 25,114,179, 4,144,205,231,243,133,197,133,149, 72, 36,194,179,103,207, 14,150,101,189, 42,175,252, 84,230,247, 63, 64, 96, -173, 21, 8, 4, 34, 91, 91, 91, 65,225, 62,189, 94, 47,176,177,177, 65,205,154, 53,215, 3,232,102, 98, 29,226,103, 99, 99, 3, - 66, 8, 4, 2, 1,198,142, 29,139,135, 15, 31, 30,143,139,139, 27,150,156,156,140,188,188,188, 61, 86, 86, 86,125,146,147,147, - 97, 52, 26,241,246,237, 91,248,249,249,249,153, 37,211, 71,182, 96,149, 37,168, 74, 10, 46, 83,172, 37,122,189, 94,222,189,123, -119,182,120, 35, 93,240, 63, 82,142,192,170, 82, 1,231,243,249, 22, 19, 39, 78,204,217,180,105,211,120, 66,200, 86,142,227, 34, -171,154, 73,167,143,238,119, 90,246,195,236, 31,108, 21, 53, 61,191,249,230, 27,222,103,159,125,118,117,231,206,157,141,109,189, -189, 63,185,118,105,175,211,250,111,230,156, 56,121,242,100,158,169, 14,238, 5,184,115,252,248,113,151, 25, 83, 39, 9,126,248, -106,218, 5, 75, 47,123,161,156,216,202,196, 90, 85,138, 28,156, 90, 84,187, 94,143, 51, 23, 47,198, 2,184,109, 66,229,229,246, -224,193, 3, 71,107,107,107, 0,249,147, 3,172,173,173,177,105,211, 38,155, 66, 75,161, 41,195,133, 37, 94, 64,183,208,208, 80, - 71,185, 92, 14,149, 74, 85,212, 32,112, 28, 87, 84, 89,182,110,221,186, 50, 13, 97, 20, 33,164,245, 23, 95,124,113,115,227,198, -141, 14,158,158,158, 88,180,104, 17,210,210,210, 16, 19, 19,131, 33, 67,134,100, 71, 69, 69,181, 43,238,155,245, 79, 64,195,134, - 13,185, 59,119,238,224,194,133, 11,248,244,211, 79,201,201,147, 39,245, 70,163, 81, 16, 31, 31,255,236,239, 74, 19,195, 48, 22, - 2,129,160,104, 88,189, 80, 88, 21,110,110,110,110,184,114,229, 10, 47, 47, 47,143,151,154,154, 42,253,245,215, 95,167, 4, 7, - 7,187, 0, 24,244,119,230,229,166, 77,155,106,140, 29, 59, 54,134,199,227,113, 93,186,116, 25,250,254,253,251,222, 46, 46, 46, -191, 95,187,118,109, 21,128, 74,135, 43,104,208,160, 65, 48,143,199,115,227, 56, 78,112,226,196, 9,131,209,104, 20, 52,108,216, - 48,169, 68, 48, 68, 48, 12, 19, 23, 17, 17, 17,104, 10,159, 88, 44, 22,108,221,186,213,160,209,104, 4,190,190,190, 73,197,120, - 4, 39, 79,158, 52, 24, 12, 6, 65,221,186,117,131, 77,153,217,156,158,158, 62,100,250,244,233,183, 14, 29, 58,100, 79,211, 52, -222,191,127,143,180,180, 52, 88, 91, 91, 99,207,158, 61,168, 89,179, 38, 46, 95,190,156,206, 48,204,152,109,219,182,205, 85,171, -213, 67, 76,240,193,106, 29, 20, 20, 84, 35, 51, 51, 19,214,214,214, 80,169, 84, 8, 14, 14,134,143,143, 15,148, 74, 37, 40,138, -130,181,181, 53, 54,110,220,152, 71, 8, 73,255, 39,188, 67, 52, 77, 23, 89,153,138,137, 34, 77,179,102,205,112,251,246,237,125, -149, 17, 69, 28,199,233,248,124,254, 7,194,170,240, 59, 77,211,149, 30,242, 48, 26,141, 2, 66,136, 31, 10,252, 3, 43,250,253, - 15, 64, 27,169, 84, 42, 40,165,172, 9,234,212,169,211,202, 84, 18,161, 80,104, 39,145, 72,242, 9,219,180, 65,114,114,178,209, -195,195, 99,224,128, 1, 3, 12, 0, 48,126,252,248,129,201,201,201, 26,134, 97,104,154,166,145,146,146,130,154, 53,107,218,153, - 37,211,127,192,130, 85,158,229,170,184, 5,171,162, 66, 72, 81, 84,102, 72, 72,136, 76, 38,147, 21,237, 51, 24, 12,240,243,243, - 99, 89,150, 37, 37,175, 83,152,142,170,130,207,231, 91,124,251,237,183,153, 27, 55,110, 28, 6,224, 59, 83,254,115,120,114, 61, -236, 46, 33,174, 54, 47, 91,184,254,151,101,139,109,223, 92,216,137,237,235, 86, 26,249, 66,121,176,159,159, 95,235,172,172, 44, -173,181, 76,139,196, 52, 28,231, 56,238,183, 74,244, 66, 40, 0, 7,239,221,187,247,184, 83,167, 78,247,119, 28, 60,102,171,140, -138,186, 39,202, 78, 77,176,172,237,197, 19,184,214,232,163,210,233,248,125,250,244,145, 3, 88,103, 2, 31, 98, 98, 98,112,247, -238, 93, 88, 90, 90,194,210,210, 18,214,214,214, 69,223,171,146,135,133,195,182,103,206,156,129, 76, 38, 67,193,212, 93,200,100, - 50, 8,133, 66, 20,127,134,149, 16, 89, 17,132,144,105,199,142, 29, 59,176,100,201, 18,164,167,167, 67,165, 82, 97,222,188,121, -136,138,138,154,206,113,220,227,127,210,203,225,235,235,203,221,187,119, 15,119,238,220,129, 74,165,194, 47,191,252, 2, 23, 23, -151,246, 0,190,255, 59,211,197,178,172,160,208,162, 88, 92, 88, 21,183, 98,209, 52, 13,177, 88, 12,123,123,123,204,153, 51, 71, -240,233,167,159,246,248, 59,211,188,124,249,242,218,107,215,174,253,117,247,238,221,231,135, 12, 25,114,232,249,243,231, 35,173, -172,172,158, 93,189,122,117,177, 72, 36, 98,171,104, 21,113,123,252,248,177, 99,241, 87,158,101, 89, 41,195, 48, 96, 24, 6, 6, -131, 1,121,121,121,232,216,177,163,201,124, 15, 31, 62,148, 2,192,247,223,127,207, 7, 32,101, 89, 22, 70,163, 17,133,156,121, -121,121,252, 14, 29, 58,184,153,100,162, 86, 42, 35, 20, 10, 69,171, 1, 3, 6,220, 61,112,224,128, 77,141, 26, 53, 16, 31, 31, -143,248,248,120,212,174, 93, 27,235,214,173, 83,113, 28,215,162, 64, 84,157, 52,241,182, 21, 54, 54, 54,252,152,152, 24, 48, 12, - 3, 63, 63, 63,108,220,184, 17, 3, 7, 14, 68,131, 6, 13,144,157,157,141,176,176, 48,236,218,181,203, 70, 32, 16,244,253,187, -223, 33,138,162,254, 36,174,138,111, 85,236, 96, 88,138,197,226,108,145, 72, 36, 44,244,191,122,248,240, 97,165,173, 87,197,234, -165,199,149,249,253,119,194,194,194, 2,114,185, 28, 6,195,135,183, 41,147,201, 80,187,118,109,147,121,228,114, 57, 41, 52, 98, - 24, 12, 6, 36, 36, 36, 24,159, 63,127,110,244,247,207, 31,228,112,113,113, 49, 62,120,240,192,168,209,104,104, 11, 11, 11, 20, -140,138, 16,152,241,241, 44, 88,133,214,138,242, 44, 87,133,223, 11, 45, 81, 21,189,108, 52, 77,227,194,133, 11, 69, 5,165, 94, -189,122, 69,215,250,216, 2,203,206,206, 78, 21, 20, 20,100, 25, 27, 27,187,191, 42,255, 47, 20, 87, 75, 22,205,179, 77,127,121, - 31,113,202, 4,164, 39, 27, 66,110, 63,123,123, 9,192, 37, 0,192, 22,239,235, 24,255,210,100,113,229,237, 32,109,212, 80, 97, -113,252,147,110, 61,170, 13, 24,247, 37, 53,105,210,164,166, 35, 71,142, 76, 27, 50,100,200, 36,137, 68,226,205, 48, 76,218,153, -139, 23,223,244,233,211,199,153, 97,152, 17, 28,199,153,226,147, 20, 55,120,240, 96, 1, 33, 4,142,142,142,252,221,187,119,219, - 88, 90, 90, 98,228,200,145, 25,111,223,190, 53, 20,244,196,146, 42,121,251,113, 45, 90,180,248,211,176, 96, 97,195, 94,104, 25, -168,164,104,243,235,209,163,199,182, 67,135, 14, 33, 53, 53, 21, 42,149, 10,124, 62, 31, 43, 86,172, 64, 76, 76,204,207,132,144, -231,255,148,202,172, 81,163, 70,220,131, 7, 15,240,236,217, 51,104,181, 90,140, 25, 51,166,184,143, 97,167,191,123,164, 32, 62, - 62, 30,123,247,238, 5,203,178, 24, 50,100, 8,106,212,168, 81, 36,172, 18, 19, 19,177, 99,199, 14, 24,141, 70,140, 29, 59, 22, -213,171, 87,135,193, 96, 16,183,109,219,150,119,253,250,117,230,239, 72,240,140, 25, 51,222, 28, 63,126,252,124,108,108,108,215, -101,203,150,181, 33,132,176, 95,127,253,245, 82, 75, 75,203,191, 52,251, 50, 35, 43, 7,175, 94,191, 47, 18, 64, 37, 55, 7,123, -219, 74,243, 69, 70,197, 22,253,223,104, 44,206,103,132,157,173, 77,165,248, 18, 18, 18,242,210,210,210, 84, 99,198,140,177,222, -182,109, 27,169, 93,187, 54,162,163,163,193,231,243, 97, 97, 97,145, 23, 30, 30, 94,217,208, 12,241,233,233,233, 94, 52, 77, 11, - 94,191,126, 13,119,119,119, 4, 5, 5,225,199, 31,127, 68,106,106, 42, 24,134,129,163,163, 35,107, 48, 24, 66,117, 58,221,205, -191,251, 61, 42,110,101, 42,190,221,185,115,103, 31, 77,211, 20,128,211, 0, 42, 37,176, 57,142,211, 85,175, 94,253, 3,238,170, - 88,175,254,131, 22,187,255,216,204,196, 58,117,234,220,144,201,100, 61, 94,189,122,245,129, 21,107,240,224,193,122, 79, 79,207, - 91,166,242, 88, 90, 90,102, 8, 4, 2, 59,141, 70,131,123,247,238,193,219,219, 91,144,149,149,181,132, 16, 50,187,160,115,185, - 36, 41, 41, 73,160, 80,228,187,241,213,173, 91, 23, 57, 57, 57, 25,102,201,244,145, 5, 86,105,150,171,210, 68, 22, 77, 87,236, -154, 64, 8,129, 90,173,134, 76, 38, 43,218, 10,253,172, 74, 19, 88, 5,190, 63, 85, 26, 34, 44, 16, 87,146, 3, 7, 14,236, 91, -183,110,221, 29, 83,255, 87,220, 7,107,203,170, 69,203, 10,197,213,211, 59,151,113, 50, 60, 43,117,214,146, 53,107,171,154,217, - 62, 14, 50, 95,103, 39,251,235, 43,126, 90,104,249,230,194, 46, 28,218,178,154,123,250,240, 97,227, 9, 15, 31,246,157, 48, 97, -130, 45,128, 4, 0,241, 0,238, 1,248,217, 68,113,133,136,136,136,162,224,174,254,254,254,177, 54, 54, 54, 54, 18,137, 4, 74, -165, 82,251,248,241,227, 42, 57,186, 70, 70, 70,126,212,224,174,132,144, 58, 61,123,246,188,121,244,232, 81, 89,102,102, 38,222, -191,127,143,175,191,254, 26, 27, 54,108,128,165,165, 37,206,158, 61,107,209,163, 71,143,235,132,144,230,127,119,112, 85, 63, 63, - 63,238,209,163, 71,120,247,238, 29, 24,134, 65,175, 94,189, 42,156,192,241, 95,182, 96,113,211,167, 79,199,182,109,219, 64,211, - 52,134, 13, 27,134,236,236,236,162,227,182,182,182,165, 29,163, 11,222,247,191, 69, 96,241,120, 60,238,198,141, 27,203,218,180, -105,131,216,216,216,174, 1, 1, 1,191,140, 28, 57, 50,254,175,242,218, 88, 89,160,145,143, 7,180, 90, 45,180, 90, 45, 20, 10, - 5,114,114,114,240,230,205, 27,104,181, 90, 56, 57, 90, 87,154,207,191, 65,237, 34, 62, 71, 71, 71,168, 84, 42,188,125,251, 22, - 58,157, 14,246,246, 54,149, 41,243,213, 58,119,238,124,109,223,190,125,118,251,246,237,211,125,246,217,103,194,133, 11, 23, 18, - 75, 75, 75, 36, 39, 39,163,138,238, 61, 55,110,223,190, 93,163, 99,199,142,117, 95,190,124,137, 27, 55,110, 64,167,211,193,223, -223, 31,145,145,145,104,214,172, 25,114,115,115, 31, 60,122,244,232,212, 63,161,172, 22, 14,223, 21,110,193,193,193, 7, 5, 2, - 1, 7,160, 74,214,166, 66,196,196,196,136,124,125,125,181, 98,177, 88, 88, 32,214,254, 18,223, 71,174,235,254,210,204,196,242, -224,225,225, 49,221,205,205,173,163,191,191, 63, 94,190,124, 41, 16,137, 68, 24, 58,116,168,190, 91,183,110,122, 30,143,103,242, -132, 27,137, 68,242, 82, 46,151,183,214,106,181,208,233,116,184,124,249, 50,236,236,236,102,245,236,217,115, 90, 66, 66, 2,148, - 74,165, 80, 40, 20, 22,249,223,182,109,219, 22,105,105,105, 47,205,146,233, 35, 9,172,194, 50, 98,202,240,160,169, 62, 88, 20, - 69, 65,167,211, 65, 38,147, 65, 42,149, 66, 38,147, 21, 93,135, 16, 82,170,192,170, 10,170, 85,171,134,160,160, 32,201,161, 67, -135,126, 91,185,114,229,221,170,112, 28,217,183,215,197,138,205,171,166,124,112, 14, 17,207, 66,112, 60, 44, 51,117,214,146, 53, - 83,123,246, 29,148, 84, 82,144, 29, 30,111, 66,207,195, 81,214,192,213,201,238,250,170,229, 75, 44,211, 95,222, 71, 66, 98, 34, -206, 61,120, 20,162,205,247, 13,251,241, 35,190,220, 40, 28, 91,255, 39, 65, 36, 18, 77, 63,114,228,136, 44, 51, 51, 19, 81, 81, - 81, 24, 50,100, 72,230,187,119,239,190,232,221,187,247,134, 75,151, 46,217, 88, 91, 91,227,210,165, 75, 22,213,170, 85, 91, 2, -160,199,223, 88, 57,114, 70,163, 17,233,233,249,238, 43, 45, 90,180,248, 71,137, 43, 0, 8, 14, 14, 22,244,236,217,243,119, 0, -237, 95,190,124, 9,150,101,239,134,132,132,180, 40, 60, 94,222, 49, 83,244, 91, 78, 78, 14,223,194,194,162,212,198, 74, 32, 16, - 8, 42,107,113, 40,206,121,231,206,157,165,171, 86,173, 58, 62,115,230,204,215,127,145,179, 84, 11, 86,143, 30, 61,160,214,234, - 17,151,148, 5,163,145,129, 90,159,252,151, 44, 88, 61,122,244, 64,158, 70,135,152,132,116, 48,140, 17, 57,106,198,212,114, 36, -253,228,147, 79, 46, 30, 56,112,192,249,222,189,123,208,106,181,108,112,112,240,219,113,227,198, 89,142, 30, 61,218,174,172,208, - 54, 38, 96,221,160, 65,131,250,221,185,115, 39,189,110,221,186,182, 15, 30, 60, 64,114,114, 50, 24,134, 65,251,246,237, 33, 20, - 10, 99,150, 44, 89, 34,128, 9,174, 5,255, 45,129, 37, 18,137, 16, 22, 22, 86, 40,172,134,127, 44, 33, 36, 20, 10,171, 60,204, -248,191,138,223,126,251, 45,126,231,206,157, 62,174,174,174,107,135, 15, 31,222, 78,161, 80, 80, 34,145,232, 6,143,199,155, 6, -224,189,169, 60, 2,129, 96,164,181,181,245, 27,138,162,232,248,248,120,188,126,253, 26,209,209,209, 0, 32,204,203,203,131,163, -163, 99,145,209,100,208,160, 65,168, 86,173,154, 49, 50, 50,114,164, 89, 50,125,100, 11,214,194,133, 11,177,101,203, 22,140, 31, - 95,190,138, 56,125,250, 52, 80, 98,136,176, 96,249,152, 43,197, 27,127,163,209,136,121,243,230,125,240,191,194,225,167, 47,190, -248,226, 3,206, 19, 39, 78,252,105,136,176, 36,103,105, 72, 78, 78,126,121,248,240,225, 71,203,151, 47,127, 96, 98,101, 88,196, - 89,232,131,213,111,240,208,132,245, 75,127,120,190,251,244,213, 6, 9,106, 46, 97,214,146, 53, 51, 75,138, 43, 83, 57,189,157, -229,222,110,142,118, 55, 86, 46, 95, 98, 85,104, 13, 59, 16,154,152, 5,134, 27, 95,153,135,101,202,189, 51, 12, 19,231,231,231, - 39, 0, 76, 27, 22, 52,133,179, 10, 34,229, 79,156, 90,173, 22,247,239,223, 7, 0,140, 26, 53, 42,243,221,187,119,173, 57,142, -123, 65, 8,121,217,185,115,231, 27, 23, 47, 94,180, 97, 89, 22, 40, 35, 44,197,127, 43,157, 5,249, 6, 30,143, 7, 47, 47,175, - 74,139,171,255, 86, 58, 19, 18, 18,198, 79,152, 48, 97,139, 86,171,229,169, 84,170,241,166, 30,171, 40,157,135, 15, 31,126,237, -229,229,213, 6,101,135, 98, 96, 11, 44,172, 85,230, 92,187,118, 45, 0,212,253, 43,156,101, 89,176, 14, 30, 60, 8,150,101, 81, -205,217, 26, 90,173, 22, 82,169,180, 82,156, 37, 45, 88,135, 14, 29, 2,203,178,168,238, 98, 11,157, 78, 87,102,231,165, 36,167, -157,157,221,234,221,187,119,187,133,135,135, 35, 46, 46, 14,107,214,172,121,159,146,146,210,141,199,227,137,126,249,229,151,235, -221,187,119,119, 98, 24, 70, 91,217,231,206,113,156,150, 16, 50,178,121,243,230,123, 22, 47, 94, 28, 93,175, 94,189,234, 45, 90, -180,176, 78, 75, 75, 75,121,252,248,241,219, 45, 91,182,200, 25,134, 25, 89,214,208,211,127,243, 61, 2,128,248,248,248, 83, 0, -248,149, 21, 86,166,164,243,225,195,135,135, 10,184,207,153,194,253,223,186,247,191, 58, 51,177,162,116,142, 28, 57, 50, 14, 37, -226,155, 85, 54,157,151, 46, 93,122, 55,120,240,224, 69, 13, 26, 52,152, 47,151,203, 17, 17, 17, 81, 20, 22,169,176,140, 19, 66, -208,191,127,127,124,241,197, 23,184,120,241,226,162,126,253,250,189,251, 79,231,231,191, 70, 96, 25,141,198,216,119,239,222,185, -236,222,189,155, 38,132,224,183,223,126, 67,241, 41,251, 52, 77,131,162, 40,240,120,249, 20,247,239,223,103, 42,138, 57,101, 52, - 26, 99,131,131,131,157,118,237,218,197, 47, 52, 25,199,199,199,131,101, 89, 54, 41, 41,137,218,183,111, 95,145, 53,140,199,227, -225,254,253,251,140, 94,175,143,169,236, 77, 69, 68, 68,124,148,222,219,205, 23,239,166, 93, 60,119,194,190,105, 80,171, 76, 75, - 91,219, 82,187,174,133, 17,223,203, 45,220, 60,234,199,101, 63, 45,180, 46, 20, 87, 7, 67, 19, 51, 53, 90, 99,187,151, 41,121, - 79, 63,246, 3,125,250,244,105,243,127,104, 89,155,215,166, 77, 27, 22,128, 61,128,185,133,179, 58, 11, 68, 86,211,218,181,107, -207, 4, 32, 1, 48,239,239,180, 94, 21, 15, 13,242, 79,179, 92, 21, 71, 72, 72, 72, 52,128, 14,149, 61, 86, 17,250,245,235, 23, -133, 82, 2,126,254, 21,252, 39, 56, 11,145,158,153,141,168,119,241,200,119, 70,103, 97,124,159, 84,228, 55,101, 48, 48, 72,207, -174, 84, 24, 57,100,100,229,224,205,219,248,130,165,193,140, 48, 26,149, 5,124,249,142,238, 92, 70, 94,133, 28,124, 62,191,229, -218,181,107,187, 81, 20, 69,221,191,127, 95,187,124,249,242,216,148,148,148, 94, 28,199,197, 0,128, 66,161,104,123,226,196,137, -223, 76, 8,201, 80, 86,199, 55,140, 16,210,236,155,111,190,153, 10,160, 37,128,234, 0, 98,144, 63,227,120,221, 63, 44,226,248, -240,255, 81,238, 42,227,127,101,102,226,190,125,251, 22,124,241,197, 23,188,160,160,160, 57,141, 27, 55,166,222,190,125,139,228, -228,100,240,120, 60,212,169, 83, 7,157, 58,117,130,187,187, 59,123,246,236,217,159,250,244,233,179, 0,102,124, 60,129,149,154, -154,218,121,248,240,225,151, 41,138,170, 89,124, 24,175,180, 79, 0, 96, 89,246, 93, 82, 82, 82,185, 65,200, 82, 83, 83, 59,207, -155, 55,239, 50,143,199,171, 89, 44,254,149, 54, 45, 45,237,139,254,253,251,111,228,243,249,162,226,214, 46,150,101,223, 39, 36, - 36,252, 87, 29,138, 75,198,193,234,220,173,119,234, 95,229,148, 11, 40,207,136,179,219,144,148,156,138,131,161,137, 25, 57, 58, - 99,219,136, 20,213,243,127, 83, 65,227, 56, 46, 25,192, 23,101, 28,123, 13, 96,252, 63, 32,141,164, 64,100,153,103,203,252, 15, -128, 97,152,184,142,237,219,162,100, 88,134,146,191,141, 70, 99,156,169,124, 29,218,181, 41,147,167,240,123, 69,124, 52, 77,207, - 12, 10, 10,162,103,206,156,153,116,254,252,249,223, 51, 50, 50,102,112, 28, 87,164,204, 10,102, 13, 6,252,197,178,170, 69,254, - 10, 15,203,205, 37,225, 31, 89,223,253, 79,204, 76,220,184,113,227,247,179,102,205,218,229,230,230,182,183,101,203,150,117, 61, - 61, 61, 45, 45, 44, 44,144,157,157,157,147,145,145,241,234,204,153, 51, 67,134, 15, 31, 30,109,126,162, 31, 89, 96,165,164,164, -168, 0, 52,251,152, 23,171,128,179,198, 63,166,203,165, 93,190, 31, 91,150,127,176, 14, 97,161,248, 42,245,119, 5,210, 32, 75, -205, 76, 90,119,241,197, 74, 45,195,177,122,134, 29, 21,145,172, 10, 51, 23,189,127,108,197,104, 22, 87,255, 35,120,254,252,121, -224, 63,145, 79,167,211, 77,107,222,188,249,207, 70,163,113,149,193, 96,184,109,126, 82,102,252,147,177,124,249,242,232,194,118, -185,127,255,254, 52, 0, 28, 62,124,216,104,206,153,255,160,192,250,183,226,240,139, 63, 26,216,146,194,169,162,223,101,225, 85, - 98,238,141,191,218, 99, 53,195, 12, 51,254,103, 68,122, 12,128, 94,230,156, 48,227,127,174,253, 51, 11,171,143, 10,202,156, 5, -102,152, 97,134, 25,102,152, 97,134, 25, 31, 23, 4, 64,199, 50,122, 97, 38,207, 14, 32,132,116,172,236,133, 77, 88, 49,220,204, -105,230, 52,115,154, 57,205,156,102, 78, 51,231,255, 51,206,127, 13,138, 59,114,126,236, 13, 64, 71, 51,167,153,211,204,105,230, - 52,115,154, 57,205,156,102,206,127,219,102, 30, 34, 52,195, 12, 51,204, 48,195, 12, 51,204,248,200, 48, 59,185,155, 97,134, 25, -102, 20,131, 66,161,232, 9, 96, 1,242, 93, 40,150, 40,149,202, 67,230, 92, 49,227,255, 19, 28, 28, 28,100,118,118,118,191, 83, - 20, 85, 3,248, 48,228, 82, 41,193,189, 97, 52, 26, 19,210,211,211, 59, 37, 38, 38,166,254, 55, 57,255,117, 2,171,125,109,235, - 86, 30,181,220,247,165, 36,167,134,230,106,178, 71,255,254, 42, 39,189, 42, 23, 38,132,216, 9,133,194,129, 50,153,172, 35,199, -113, 30, 52, 77,135,103,101,101, 93, 49, 24, 12, 7, 56,142,203, 53,191, 2,102,252,221,240,243,243,107, 40, 20, 10,103, 17, 66, -154, 50, 12,227,198,231,243,149, 0, 30,104,181,218, 21,161,161,161,161,230, 28,250,255, 1, 66, 8,229,226,226,242,179,181,181, -117, 80,102,102,230, 16, 0,115, 34, 34, 34,124, 41,138,130,143,143,207, 28,133, 66,241,198,210,210,114,123,118,118,246,221,132, -132,132,105,149, 89, 59,206,140,127, 46, 60, 61, 61,131, 41,138,114, 43, 92,146,173,164, 32, 40, 77, 32,112, 28, 23, 29, 22, 22, - 86,102, 48,103, 55, 55, 55, 15, 75, 75,203,141, 0, 26,151, 20, 21, 37, 81, 48,204,246, 40, 59, 59,251,139,184,184,184, 82, 3, -241,218,218,218, 90, 56, 58, 58, 46, 32,132,244,167, 40,170,194, 5,127, 89,150, 53,114, 28,119, 56, 57, 57,121, 94,122,122,122, - 78, 89,231,217,217,217, 93,185,121,243,102, 99,123,123,251, 10,195,210, 48, 12,131,248,248,120,135,238,221,187,223, 4, 80,239, -191,201,249,175, 19, 88,224,168,161, 43,190, 27,235,154, 18,251,198,117,206,218, 99,117, 90,213,179,111,123, 43, 60, 53,177, 50, - 20, 18,137,100,160,175,175,239,186,159,127,254,217,206,221,221,157, 72,165, 82, 36, 36, 36,212,123,252,248,113,159,249,243,231, -207,227,243,249, 35, 13, 6,195,229,191, 88,105, 90,219, 74,121,179,210, 84,134,111,205, 85,137, 25,149, 65,255,254,253,233,216, -216,216,249,246,246,246, 95,205,158, 61, 91, 84,179,102, 77,200,229,114, 36, 39, 39, 87,127,253,250,117,181, 13, 27, 54,244,108, -222,188,249, 47, 58,157,110,110, 72, 72,136,193,156, 99,255,219,112,113,113,249,249,228,201,147,147,235,214,173,139,214,173, 91, -223,245,243,243,179,148, 74,165,184,112,225, 2, 60, 61, 61,235, 91, 90, 90, 62,216,188,121, 51,127,193,130, 5,141,142, 29, 59, - 6, 0, 83,204,185,246,191, 15,138,162,220, 66, 67, 67, 29,165, 82, 41,140, 70, 99, 65,244,126, 22, 28,199, 21,125, 22, 23, 67, - 70,163, 17,237,218,181,211,151,199, 41, 22,139, 55, 60,123,246,172, 99,225, 58,126,197,132, 84,169, 80, 42,149, 29,219,181,107, -183, 1, 64,169, 1,181, 29, 29, 29, 23, 12, 24, 48, 96,122,131, 6, 13, 0,160, 40,157,133,159,169,169,169,152, 52,105, 82,209, - 53, 88,150,197,205,155, 55,167,126,249,229,151, 0,240,101, 57,247, 94,195,222,222,158, 84,180, 4,222,252,249,243, 49,127,254, -124,172, 91,183,142,240,120, 60,235, 10,242,243,163,115,254,235, 4, 22,161,200,185,245,155,119,141,158, 49,160, 41, 89, 62,174, -149,215,119,219,175,223,235, 88,203,166,245,149,232,140, 88, 19,197,213,212, 9, 19, 38, 44, 93,184,112,161,248,213,171, 87, 8, - 11, 11, 3,195, 48,176,176,176,128,175,175, 47,117,238,220, 57,151,105,211,166, 29, 17, 10,133,163,116, 58,221,177,170,222,152, -179, 37,127,133, 76, 68, 13, 22,242,120, 15,116, 12,115,234,159,152,249,238,238,238,151, 12, 6,195,178,248,248,248,107,255, 43, - 5, 70,161, 80,180, 16, 10,133,243,222,189,123,215,133,227, 56,230,255,227, 75, 17, 19, 19,179,176,101,203,150, 51,230,207,159, - 47,122,251,246, 45, 34, 35, 35,161, 84, 42, 81,179,102, 77,184,187,187,147,117,235,214,137,127,249,229,151, 41, 79,158, 60,225, - 3,152, 81, 25, 75,137,179,179,243,152, 14, 29, 58,244,181,183,183,183,138,143,143,207,186,115,231,206,201,132,132,132,173, 85, -205, 75, 66, 8,101,111,111, 63,162, 71,143, 30,125,109,109,109,109, 19, 19, 19, 51,174, 92,185,114, 34, 57, 57,121,251, 95,177, -180, 16, 66, 92, 0,248, 2,176, 43,216,149,224,238,238,254,226,237,219,183,201, 31,145, 83,233,238,238, 30, 86, 21, 78, 7, 7, - 7, 25,143,199, 59, 68, 8, 81,148, 99, 33, 80, 50, 12, 51,160, 32,192,113,153,176,180,180,108,234,229,229,133,144,144, 16,204, -157,251,127,236, 93,123, 92, 84, 85, 30,255,158,123,231,197,188, 96, 24, 64, 96, 24, 5,149, 55,152,138, 6,152,226,170,169,105, -202, 90,138,149,181,165,105,166,100, 46,110, 9,169,176,226, 35,205, 30,102,143, 13,113, 85,220,245, 85,150, 86,102, 25,161,109, -186,105,226, 11,197,215,240, 88, 69,112, 16, 70, 30, 34,143,153,185, 51,115,239,254, 1, 51,226,198, 99,134,220, 36,155,239,231, -115, 62,115,239,157,225,203,185,231,156,251, 59,223,251, 59,191,115, 78,170,114,228,200,145, 40, 44, 44, 4, 33, 4,175,188,242, - 10,137,136,136,224,151,151,151, 99,240,224,193,200,201,201,121, 8, 78, 56, 82,231,187, 0, 40, 0, 76,227, 56,238, 70,171,235, -158, 0, 62, 7, 80,201,113,220,228,123,149, 63,177, 88,140,157, 59,119,130,207,231,131,207,231,163,166,166, 6,106,181,218,118, - 46, 16, 8,108,199,189,122,245,234,148,143,101,217,104,154,166, 81, 95, 95, 15,139,197, 98, 75,181,181,181,224, 56, 14, 34,145, - 8, 22, 75,243,182, 75,214,239, 88,150,141,238,160,252,166,170, 84, 42,236,216,177, 3, 70,163,177,173,182,139,252,252,219,155, -130,208, 52,141, 1, 3, 6, 80,132,144,169, 29, 9, 44, 66, 8, 7, 0,179,103,207, 6, 77,211,182,173,239,172,199,214,100,177, - 88,144,158,158,222, 28,176, 77, 81,157,213,245, 93,231,252,205,183,255,142,212,245,200, 64,247,196, 17,113,177,111,185,136,120, - 98,214,108,130,197,108, 2,107, 54,130, 38, 44,226,194,123, 32,170,151, 11,170,107,110, 33,117,107, 94,157,182, 74, 31,147, 93, - 80,165,233,164, 2, 2, 98, 98, 98, 78, 29, 60,120, 80,113,224,192, 1,104, 52, 26,188,254,250,235, 0, 0,169, 84,138,253,251, -247,131,166,105,176, 44,139,113,227,198,233,180, 90,109, 24,199,113,213, 93,120,168,253,135,247, 83,159,220,189,104,184, 50,114, -238,167, 37,215,111, 26,251,114, 28,215,237, 22, 80, 83,169, 84, 28,159,207,111, 52,155,205,241,191, 5,145,165, 82,169,134,242, -249,252,253,102,179, 89,194,231,243,197, 87,174, 92, 49,220,111, 15,196,192,129, 3, 31, 80, 42,149, 63,237,217,179,199, 37, 55, - 55, 23, 53, 53, 53,168,172,172,196,252,249,243,145,145,145,129,200,200, 72, 72,165, 82, 8,133, 66,188,244,210, 75, 77,183,110, -221, 26,113,226,196,137,227,118,180, 73,122,248,240,225, 59,182,109,219, 22, 96, 54,155, 41, 0, 48, 26,141, 40, 45, 45,181, 44, - 89,178,228,234,137, 19, 39,166, 57, 42,178, 8, 33,212, 67, 15, 61,180,117,219,182,109,129, 66,161,144, 98, 89, 22, 38,147, 9, -133,133,133,150, 37, 75,150, 92, 57,121,242,228,211, 93,105,247,132,144,129, 18,137, 36, 34, 49, 49, 81, 55,105,210, 36, 6, 0, -142, 31, 63, 78,157, 57,115,198,181, 79,159, 62, 37,105,105,105,167,186,192, 57, 72, 46,151,135,190,248,226,139, 55, 38, 78,156, -104, 18, 8, 4,236,143, 63,254,200,211,104, 52,174, 1, 1, 1,197,139, 23, 47, 62,227, 96, 91,220,183,103,207,158, 17, 42,149, -202, 2,128,179, 26,120,138,162,184,150, 79, 20, 23, 23,243, 18, 18, 18,254,165,213,106,255,216,225,203,152,143, 79,184,175,175, -239,161,180,180, 52,165,181,147,106,157,172,117,149,158,158,206,148,151,151,199,106,181,218,211,112,194,222,122, 63, 6, 32, 26, -192, 57, 0,163, 56,142,187,209, 34,174,190, 7, 16, 1,224, 71,142,227,134,221,139,188,133,134,134, 86,228,231,231,247,248,226, -139, 47,192,231,243,241,221,119,223, 33, 35, 35, 3, 59,119,238,108, 83,100,249,250,250, 34, 46, 46,174,236,244,233,211, 61,219, -227, 12, 12, 12,188, 89, 84, 84,228,122,243,230, 77, 88, 44, 22, 28, 59,118, 12, 27, 55,110, 68,143, 30, 61,224,233,233, 9, 47, - 47, 47, 68, 71, 71, 67, 42,149,218, 68,214,212,169, 83,235,138,138,138,220,218,226, 11, 15, 15,215, 62,243,204, 51,190, 39, 79, -158,132,201,100,106, 83, 96, 37, 37, 37,181,246, 34, 65, 42,149, 98,210,164, 73,229, 23, 46, 92,104,247,229, 35, 50, 50,178,252, -220,185,115, 62,103,206,156,185,163,173,183, 37,136,104,154,134, 92, 46,199,144, 33, 67, 42, 78,159, 62,237,243,107,114,222,215, - 30,172, 96,127,159, 37,139,230, 60, 38,134,133, 1,103,106, 2,152, 70,128,169, 7,107,108, 4, 17,136, 1, 83, 19,148,194,106, -188,255, 92, 31,215,213, 95, 92,185, 48,170,175,215,132,131,197,186,253,237,241, 41, 20,138,244,245,235,215, 43,242,243,243,161, -209,104,176,118,237, 90,172, 88,177, 2, 2,129, 0,213,213,213,136,143,143,199,145, 35, 71,192, 48, 12, 82, 83, 83,149, 41, 41, - 41,243,208, 28,108,234,160,247,138,151,241,201,230,247,149, 74,186, 10,207,143, 58,225,241,183,236,203,137, 0, 62,232,142, 21, -240,214, 91,111, 73,146,147,147,247,250,249,249,117,107,145,165, 82,169,134,138,197,226,253, 73, 73, 73,210, 55,222,120,227,174, -136, 85,181, 90, 29,201,227,241, 62, 54, 26,141,175,148,151,151,127,219, 5,227,221, 59, 38, 38,230,141,243,231,207,127, 86, 95, - 95,191,171,173,223,200,100,178,169,161,161,161,143,157, 56,113, 98, 9,199,113,151, 59,227, 20,137, 68,243, 23, 46, 92,232,114, -237,218, 53,212,214,214, 66, 40, 20,218,118,153, 39,132, 64, 36, 18,129,162, 40, 8,133, 66, 60,251,236,179, 46,155, 54,109, 90, - 0,224,169, 78,219,164,143,207,204,173, 91,183, 6, 48, 12, 67, 53, 52, 52, 64, 32, 16, 64, 32, 16,224,129, 7, 30,160, 23, 46, - 92,216,115,254,252,249,115, 0,124,232,200,253,187,187,187, 63,183,117,235,214, 64,161, 80, 72,149,151,151, 99,232,208,161, 56, -118,236, 24, 98, 98, 98,232,228,228,228, 94,243,230,205,155, 13, 32,195, 81, 47,147, 68, 34,233,247,253,247,223,151,246,236,217, -211,246,246,213,187,119,111,203,132, 9, 19,170, 47, 94,188, 24,122,244,232,209,170, 33, 67,134, 92,117,128,211, 79, 34,145,132, -125,253,245,215,229,203,151, 47,127, 56, 51, 51,115, 18, 0, 68, 71, 71,127,185, 98,197,138,131,213,213,213,145,135, 15, 31,174, -142,139,139, 43,115, 32,171, 30,222,222,222,230,196,196, 68,121,123, 63,216,178,101, 75, 21,128, 30,157,180,235,120,138,162,150, - 69, 70, 70,186,142, 28, 57, 18,135, 14, 29,194,203, 47,191,108, 48,153, 76, 5, 0, 48,122,244,232,144,244,244,116,225,201,147, - 39,161, 80, 40,248,229,229,229,155, 85, 42,149, 51,240,221,126, 76, 2,240, 47, 0,145, 0, 14, 18, 66,158, 0,240, 41,128,112, - 0, 26, 0, 9,247, 50,115, 22,139, 5, 60, 30, 15,101,101,101,216,180,105, 19, 86,173, 90,133,224,224, 96,152, 76, 38,155,192, -226,241,120,224,243,249, 32,132,216,189,149,150,217,108,198,241,227,199,177,245,159,255, 68,234,146, 37,144,203,155,155, 41,195, - 48,168,174,169,129,139,139,139,205,131,213, 17, 56,142,219, 85, 88, 88,152,164, 86,171,239, 24, 26,180,126,182,216, 56,176, 44, - 11,179,217, 12,131,193,128,191,255,253,239,102,142,227,118,117,242, 76,218, 60, 94, 73, 73, 73, 48, 24,110,191, 43,247,239,223, - 31, 0, 16, 16, 16,128, 1, 3, 6,216,206,173, 30, 42,123, 56,255,254, 80, 63, 52,181,250,117,104,250,219, 86,155,143,208,208, - 80,248,250,250,218,197,121, 95, 11,172,130,171,149,107,146,151,189,247,182, 84, 72,243,103,140, 15,135,202,149, 15,136,149, 16, - 12, 79, 1, 81,248, 55, 55,128,234,255, 0,217, 41, 72, 29, 91, 69,189,214,196,124, 62, 62, 80,233,245, 77, 81,187,193,117,209, - 61,123,246,196,225,195,135,209,167, 79, 31,164,165,165, 33, 44, 44, 12, 82,169, 20, 21, 21, 21,104,104,104,128, 84, 42, 69, 93, - 93, 29,162,162,162,104,185, 92, 62,210, 81,129, 69, 8,137,154, 21, 31, 19,205,243, 14,199,208,135, 99,145,189,116,132,116,203, - 15,215, 22, 17, 66, 54,183,222,112,181,187, 32, 33, 33, 1,215,175, 95,151,172, 91,183,174,203, 34, 43, 32, 32, 32,155, 97,152, - 49,118,184,195,191, 47, 42, 42, 26,213, 85,113,181,119,239, 94,169, 92, 46,199, 27,111,188,113,183,196,213,191, 31,121,228, 17, -215,111,191,253,118,143,175,175,239,227,142,136, 44, 66, 72,239,169, 83,167,126,181,113,227,198,144, 81,163, 70, 89, 0,180,105, - 80, 34, 34, 34,166,100,103,103, 79,158, 53,107, 86, 63, 66,200,196,206, 68, 22, 33,228,161,222,189,123,163,180,180, 20, 21, 21, - 21,208,235,245,168,168,168, 0, 0,148,149,149, 65,173, 86, 67,161, 80, 64,173, 86, 35, 36, 36,132, 80, 20, 21, 99, 79,126, 71, -142, 28, 57, 9, 0, 85, 92, 92, 12,157, 78, 7, 55, 55, 55, 72,165, 82,168,213,106,140, 24, 49,130, 23, 24, 24,248,168,163, 2, -107,252,248,241, 83, 36, 18, 9, 85, 90, 90,138,203,151, 47,195, 96, 48,160,160,160, 0,110,110,110,120,248,225,135,249,129,129, -129, 19, 29, 21, 88, 0,250,205,158, 61,187,162,181,184,178, 66, 42,149,146,144,144,144,106, 15, 15,143, 65, 0,174, 58,194, 57, -111,222,188,202,213,171, 87, 15,207,201,201, 73,177, 94,204,201,201, 73, 6,128,247,222,123,239,176,151,151,215, 32, 0,142, 8, - 44,112, 28,199,206,154, 53,171, 80, 32, 16, 64, 40, 20,218,146, 72, 36, 2,159,207, 7, 77,211,110,118,208, 44,214,104, 52,253, -101, 50, 25, 52, 26, 13,104,154, 6, 33,164, 80,171,213,246, 7,128,148,148,148,162,166,166,166,190,122,189, 30, 9, 9, 9, 36, - 62, 62,254,129,181,107,215, 46, 1,208, 45, 4, 22, 33,228, 65, 0,107, 1, 24, 1, 44,225, 56,238, 88,119,178,111, 28,199, 85, - 16, 66, 70,180, 18, 89,167, 1,136, 90,196,213, 8,142,227, 42,238, 97,217,129,101, 89,240,249,124,188,253,246,219, 96, 24, 6, -219,182,109,195,167,159,126, 10,138,162,108,129,238,174,174,174,120,255,253,247,127, 22,248,222,153,112,219,178,101, 11, 82,146, -147,109,226, 10, 0, 4, 2, 1,124,188,189,225,225,233,137,226,226,226, 78, 5, 86,101,101,229,210,220,220, 92,116, 20,228, 62, -121,242,237, 17,214,214, 65,238,246,228,147,166,105, 24, 12, 6,140, 25,115,187,251,152, 55,111,158,237,184,186,186,218,250, 76, -128,216,121,243, 52, 77,163,137, 3, 30,115,185,125,237,209, 87, 94,177, 29,223,184,113,195, 97,206,251, 82, 96, 13, 47,170,254, -240, 8,193,128,228,231, 31,158,174,242,116, 5, 87, 95, 1,193,168,165, 56, 91, 45,193,186,245,205,125, 97, 82, 66, 20,250,141, - 94, 9, 99,214, 88,204, 28,104, 17, 46, 40,199, 66, 0,105,109,241,121,122,122,122,152,205,102, 16, 66, 32,149, 74, 17, 30, 30, - 14, 23, 23, 23,232,116, 58,188,252,242,203,216,191,127, 63, 24,134,129, 64, 32, 64,159, 62,125,192, 48, 76,223, 46,120,175, 54, -190,251,214, 42, 69,213,169, 29, 56,249,159, 90, 72, 60,122, 98,201,180,104,247,244,109,185, 75, 1, 36,119,199, 74, 24, 48, 96, - 0,150, 47, 95, 46, 89,186,116,105,151, 68, 22,195, 48, 43,248,124,254,208, 85,171, 86,137,167, 77,155,246,179,239,243,242,242, -144,144,144,208,164,215,235, 95,239,170,184,250,242,203, 47,165, 74,165, 18,165,165,165,248,165,207,132, 85, 92,109,223,190,221, -213,223,223, 31,145,145,145, 46,239,188,243,142,221, 34,139, 16,210,127,242,228,201,187, 55,110,220,232, 63, 99,198,140,146, 19, - 39, 78, 84, 16, 66,218, 19,226,218,231,159,127,190, 36, 43, 43, 43,132, 16,242, 85,103, 34,203,108, 54,247,146, 72, 36,208,233, -116,248,243,159,255,124, 71,128,170,117, 56, 27, 0, 52, 26, 13,212,106, 53,244,122,189,159, 61,247,172, 84, 42,221, 1,224,133, - 23, 94, 64,105,233,237,112, 69, 63, 63, 63,148,150,150,194,108, 54, 43, 29, 45, 71,165, 82,169, 52,153, 76,136,139,139,131, 94, -175, 7, 0, 60,241,196, 19,224,243,249,168,172,172, 4,195, 48, 30, 93,168, 30,207, 9, 19, 38,104,219,251,210,213,213,149,113, -119,119, 15,119,144,211, 35, 62, 62,254,218,134, 13, 27,126, 54, 84,151,155,155,251, 71,165, 82,153,163, 84, 42, 67,186,144, 87, -182,181,160,178, 30, 11,133, 66,171,199,193,174,183, 99,150,101,177,111,223, 62,208, 52, 13, 30,239,182, 73, 76, 75, 75,123, 81, -161, 80,120, 31, 58,116, 8,215,175, 95, 71, 67, 67, 3,234,235,235, 17, 20, 20,212,103,244,232,209,121,215,175, 95,191,114,254, -252,249,199,239,181, 19, 28,128, 53, 46, 44, 3,192,128,238,102,223, 90, 68,214, 84, 0, 39, 90,196,149, 17,192,148,123, 41,174, - 90,215, 61,143,199,179, 61,231, 46, 46, 46,136,138,138,178,137, 41, 66, 8, 26, 27, 27,193,227,241,172,241, 66,118, 25,191,218, -218, 90,248,250,248, 64, 46,151, 35, 40, 56, 24,133, 5, 5, 0, 96, 59, 22,137, 68, 32,132,192,108,238, 56, 42,160,101, 38,224, - 2,116, 16, 79,213, 69,113,201, 89,197, 80, 39,246, 31, 44,203, 90,109, 62,119, 55, 56, 61, 61, 61, 81, 95, 95,111, 23,231,125, - 43,176,150, 17, 66, 29, 9, 82,110, 74,158, 62, 98,122, 92,136, 59,244,186,203, 16,201, 61, 65, 20, 1, 88,183,254, 91, 92,184, -210, 28, 26,181,238,211, 83,216,178,232, 17, 64,172, 68, 95,153, 6,158, 82,201,227,237, 9,172,234,234,234, 6,147,201,164, 20, -139,197,224,241,120, 16, 10,133,168,170,170, 66, 90, 90, 26, 62,249,228, 19, 4, 4, 4,192, 98,177, 64, 36, 18,161,178,178, 18, - 2,129,192,161,217,137, 60, 30,153,144,254,194,248,222, 82,159, 96, 84,125,183,162,249,162,247, 64,204,142,167,132,239,236, 62, -251, 28, 33,228, 29,142,227, 42,187, 91, 37,200,100, 50, 68, 71, 71, 99,238,220,185,146,245,235,215,255, 3,128,218,145,191,215, -106,181, 63,170, 84,170,177, 75,150, 44,201,190,118,237,154, 56, 54, 54, 22, 50,153, 12, 50,153, 12, 23, 47, 94, 68, 82, 82,146, -222,104, 52, 78,236,138,119,140,207,231,103,141, 31, 63, 94, 42, 18,137, 80, 84, 84, 4,165, 82,249,139,238,213, 42,174,118,238, -220,233, 26, 18, 18,130, 75,151, 46, 97,200,144, 33,240,245,245,117,121,245,213, 87, 59, 21, 89, 45,111, 60,239,125,252,241,199, - 1, 60, 30,143,124,246,217,103,189, 1, 36,217,243,191,183,111,223, 30,186,107,215,174,181,132,144,199,184,118,130, 15, 5, 2, - 65,153, 78,167, 11,236,217,179, 39, 54,109,218, 4,138,162, 80, 94, 94,142,197,139, 23, 99,245,234,213,136,137,137,129, 92, 46, - 71,207,158, 61, 81, 84, 84, 4, 23, 23,151,114,123,254,247,181,107,215,170, 89,150,237,177,127,255,126,232,116, 58,219,117,127, -127,127,212,212,212,192, 96, 48, 84, 57, 90,150,101,101,101, 85, 0,188,243,242,242,112,229,202, 21,140, 27, 55, 14,159,127,254, - 57, 6, 15, 30,140,150,120,172,170, 46, 84,145,133,166,105,174,147,242,119,191,155,156, 45,157,150,163,156,224, 56,142,107, 45, -168,172,199,214,196,227,241,236, 9,242, 95, 21, 22, 22,182,172, 79,159, 62,225,169,169,169,124,154,166, 49,108,216,176,144,133, - 11, 23,150,184,184,184,120,188,246,218,107,146,182,156,193, 0,250,135,135,135, 75,187,129,249,104,237,165,235,150,147, 78, 8, - 33, 61, 90, 60,126, 66, 0, 76,203,231, 78, 66,200,168,214,129,239,247,210,131,181,108,217, 50,204,153, 51, 7,222,222,222, 72, - 73, 73, 1,143,199,179, 37, 66,136,205,163,229, 8,122,120,123,119,248,189, 53, 6,171,147,151,168,255,203, 50, 13,246,138,161, -230,126,149,103,151,247,238,255,193,121, 95, 10, 44,171,184, 74,121, 46,110,250,176, 16, 87,228, 28, 58,129,145,125, 41,192, 40, -236,192,132,154, 64, 4, 82,120,203, 41,117, 7,174,195,188,146,146,146, 94, 10,133, 2, 12,195, 64, 40, 20, 34, 50, 50, 18, 71, -143, 30,133,209,104,132,193, 96,176, 25,199,243,231,207,131, 97,152, 67, 14, 60, 44,180,183,156,255,126,114,234, 10, 57,242, 55, - 67, 33, 21, 98,228,160, 64,192, 35, 12,116,181, 6,107, 23,196, 43, 95, 92,179,103, 29,236,136,151,185, 23, 2,171,176,176, 16, -153,153,153,141, 6,131,225,185,174,112, 88, 69, 86, 70, 70, 70,182, 66,161, 16,255,225, 15,127, 64,126,126, 62, 94,125,245, 85, -189,209,104,156,208,213,248, 46,147,201, 52,227,171,175,190,218, 31, 24, 24, 40,141,139,139,187,195,221,221, 21,113, 69,211,244, -191,103,206,156, 41, 15, 8, 8, 64,113,113, 49,220,220,220, 32,147,201,208,187,119,111,236,216,177,195,229,233,167,159,238, 80, -100,113, 28,199, 17, 66, 18,159,124,242,201,189, 89, 89, 89,254, 51,102,204, 40,217,189,123,247, 94, 0,237, 25, 19,249,228,201, -147,227,179,178,178,252,103,205,154,165, 1,240, 23,174,131,153, 29, 44,203, 30, 41, 42, 42,234, 27, 22, 22, 70, 66, 66, 66, 32, - 20, 10,225,231,215,236,164,234,223,191, 63,194,195,195,193,231,243, 1, 0,133,133,133, 0,144,107,207,189, 31, 62,124,248,203, -130,130,130,153,131, 7, 15,166,125,124,124,108,193,179, 2,129, 0, 43, 87,174,100, 74, 74, 74,246, 57, 90,158, 7, 15, 30,252, - 60, 63, 63,255,133, 97,195,134,241,220,221,221, 33, 18,137,208,175, 95, 63,168, 84, 42,172, 92,185,146,185,124,249,242,190, 46, - 84,211,213,252,252,124,151,224,224,224, 54, 45,191, 88, 44,118, 5,224,168,231,161,244,248,241,227,194,216,216,216, 47,191,249, -230,155,200,214, 95, 68, 71, 71,127, 41,147,201,220, 0,148,119, 33,175,108,107, 65,101, 77,214, 33, 67,123, 4,150, 86,171,221, -235,227,227,243, 31,111,111,239, 31, 35, 34, 34,220,242,243,243,145,154,154, 42, 48, 24, 12,189,114,114,114,108, 29,113, 27,237, - 16, 13, 13, 13,226,110, 96, 62,146, 0,188, 11, 64, 2, 32,165, 27,138, 43,111, 52, 7,180,135,162,121, 88,240,137, 22,177,101, -141,201,186,167, 34,139,227, 56,240,249,124,132,134,134, 98,193,130, 5, 88,179,102, 13, 18, 19, 19, 17, 28, 28,108,171,123,107, -144,187, 35, 30, 44,129, 64, 0,111,111,239,230, 73, 39, 45,222, 43, 0, 40, 44, 40, 0,143,199, 3,203,178, 48, 26,141,157,122, -176,122,244,232,177,236,205, 55,223,156, 63,126,252,120,234,127,103,220, 89,151,149,104,157, 76, 38, 19,246,238,221, 59,127,245, -234,213,176,199,235, 69,211, 52,250,247,239,127,199,176,224,135, 31,222,142, 84,136,138,138,194,152, 49, 99,236, 18, 77,173, 57, - 67,211,223,190, 99, 88,240,107,175,219,197,214,243,217,217, 8, 94,245,129, 67,156,191, 85,180, 57, 71,242, 72,144, 98,101,202, - 51, 67,167, 15, 11,146,227,187, 67,167,177,238,235,203,151, 74,202,171,192, 86,228,131,213, 93, 68, 82, 66, 20,194, 3,148, 8, - 15, 80, 34, 41, 33, 10,108,229, 57,112, 53,197,224, 68, 10,148,214, 66,219,129,219,116,205,138, 21, 43,106,149, 74, 37,196, 98, - 49,132, 66, 33,202,202,202, 16, 17, 17, 1,145, 72,100,123, 3,165, 40, 10,169,169,169, 58,157, 78,183,222,222, 27,145, 10,169, -217,107, 94,121,194, 91,224, 34, 3, 74, 15,193, 85, 46,195,166,191,189, 13,212,107, 1, 90,128,248, 63, 12,160,125, 61, 21,163, - 8, 33, 33,221,173, 18,138,139,139, 49,127,254,252, 70,189, 94,255,139, 2,221,181, 90,237,143, 12,195,140, 93,189,122,117,211, -246,237,219,127,177,184,178,114, 26,141,198,113,239,190,251,110, 67, 81, 81,209, 47, 18, 88, 60, 30,239, 53,147,201,228,154,153, -153,201, 14, 26, 52,200,242,216, 99,143, 89,198,142, 29,107, 25, 50,100,136, 37, 34, 34,194, 50,101,202, 20,139, 94,175, 23, 73, - 36,146, 55, 59, 49,138, 23,118,239,222, 61,122,214,172, 89,154,172,172, 44,255,152,152, 24, 21,199,113, 75,219, 74,131, 7, 15, -246,182,138,171, 93,187,118,117, 26,131,101, 48, 24, 62,204,200,200,208, 91,103,185, 8,133, 66,120,121,121,217,132,176, 64, 32, -128, 72, 36, 2,195, 48,248,232,163,143,154,154,154,154,214,217,115,239, 85, 85, 85,155,147,147,147,175,102,103,103,155,234,234, -234, 64, 8,193,181,107,215,176,114,229, 74,102,195,134, 13,215,106,107,107, 55, 56, 90,158,117,117,117, 89,201,201,201, 87,246, -237,219,103,162, 40, 10, 53, 53, 53,112,117,117,181,113,222,186,117,203, 97,206, 33, 67,134, 20,149,148,148,184, 54, 54, 54,182, -229,205, 36, 82,169,244, 65, 0, 7, 29,225,140,138,138, 42,190,122,245,170,124,229,202,149, 63,140, 30, 61,122,141, 92, 46, 47, -144,203,229, 5,163, 71,143,126,243,131, 15, 62,248,151,139,139, 75, 52, 0,135, 55,135,165, 40,138,109,109, 55, 90,199, 96,137, - 68, 34, 8, 4, 2,187,150,169,112,115,115,219,146,145,145,225, 86, 94, 94, 14,131,193,128,188,188, 60,228,229,229,161,172,172, -204,214, 9,183,177, 15, 27, 26, 27, 27, 93,238,181,237,224, 56,238, 95, 28,199,245,231, 56, 46,144,227,184,238, 56, 73,230,211, - 86,226,106, 4,199,113,249, 0, 70,180,156, 71, 2,248,226, 94,122,176,172, 2,139,199,227, 97,218,180,105, 56,112,224, 0,130, -130,130,108,129,237,173,131,220, 29, 17, 4,102,179, 25,253,250,245,131,193,104,188, 67,160,243,120, 60,120,245,232,129,162,162, - 34,187, 60, 88,132,144,169,227,199,143,167,206,159, 63,143,176,176, 48,156, 58,117,202,150,242,242,242,112,246,236, 89,156, 59, -119, 14, 23, 46, 92,192,160, 65,131, 80, 82, 82,130, 71, 30,121,196,186, 76, 67,135, 77,199, 94,111,147,117, 38,160, 29,222,166, -255, 7,231,253,231,193, 82,123, 73,102, 12,237, 77,240,221,225,211,120, 63, 91,187,133,227,184,221,251,243,235,190,154, 51,200, - 12,102,215,211,232,151,240,207,230, 97, 65, 0,108,229, 57, 48,187,254, 4, 34,241, 68,110,133, 16,117,122, 83,187,111,205, 12, -195, 28,115,119,119,223,185,121,243,230,153,207, 63,255,188, 16, 0, 36, 18, 9,254,242,151,191,128,227, 56, 8,133, 66,208, 52, -141,185,115,231,214, 87, 86, 86,190,203,113, 92,145,157, 15,138,216,207, 93,152,250,204, 75,105, 46,200,219, 0, 80, 2,220,144, - 69,161,255, 35, 51, 81,169, 57, 10, 84, 93, 4,104, 1,214,167,191,224,249,199,121,111,111, 0, 16,215, 93, 42,224,220,185,115, -152, 55,111,222, 47, 22, 87,255,235,201,218,177, 99,199, 63,140, 70,227, 11,119,145,115, 92, 74, 74,202,126,111,111,239, 46, 15, -139,148,148,148, 60,235,239,239, 63,179,179, 7,175,184,184,184,211,161, 14,142,227, 46, 19, 66, 38, 94,185,114,229,245, 75,151, - 46,125,222,222,239, 46, 93,186,244,249,152, 49, 99,232, 99,199,142,189,102,207, 44,194, 83,167, 78,157,138,141,141,205, 88,183, -110,221,220,164,164, 36,177, 72, 36,130,171,171, 43, 52, 26,141,109, 29, 28,163,209,136, 69,139, 22, 53,153, 76,166, 45,199,143, - 31, 63,106,103, 71,104, 38,132, 60, 53,103,206,156, 89, 33, 33, 33,127,100, 89,214,195,104, 52, 86,149,148,148,236,187,117,235, - 86,151,214,193,226, 56,142, 37,132, 60, 61,119,238,220,233,193,193,193, 83, 24,134,241,176, 88, 44, 85, 87,175, 94,253,178,174, -174,110, 83, 87, 56,143, 28, 57,162,251,232,163,143,254,163,211,233,194,212,106,245, 77,153, 76,102, 52, 26,141,180, 88, 44,118, -149, 74,165, 81, 0,142, 2,184,224, 8,231,201,147, 39,175,175, 95,191,254,138,193, 96, 8, 93,191,126,253, 97, 87, 87,215, 3, -132, 16, 34, 16, 8,220,197, 98,241, 72, 0, 63, 0, 40,116, 52,175, 52, 77,119,232,193,130,157,241, 29,183,110,221, 58,150,158, -158, 62,104,224,192,129,200,200,200,168,150,201,100,242, 41, 83,166,240,106,107,107, 73, 71, 30,172,238, 32,176,126, 3,168,106, -241,242, 78,178,198, 92,181, 10,124,255, 20, 64,237, 61, 22,168,119, 8,169, 94,189,122,217,206, 91,167, 86, 49, 88,118,193, 98, -177, 64, 32, 16,128,199,227,193, 87,165,178,137, 57,142,227, 80, 84, 84,132,234,234,106,187, 4, 22, 69, 81, 52, 33, 4, 79, 62, -249,164, 93,255,247,169,167,158,194, 15, 63,252,128,206,134, 19, 91,207,248, 11, 8, 8,232, 84, 12,181,228,197,238, 89,132,106, -181,250,174,112,222,151, 2,235,170, 78,191,114,193,134,227,139,138, 43, 13,187, 31, 42,172, 89,144, 14,112,128,123,118,152,146, -140,141,163,202, 96,216, 48, 12,196,181,185,179,225,234,203, 65,164,222, 40,135, 26,239,101, 23, 95, 55,113, 76,135,222,135,218, -218,218,164, 15, 63,252,144,206,206,206,126, 98,245,234,213,110, 97, 97, 97,248,211,159,254, 4,163,209,136,179,103,207, 98,206, -156, 57,213, 58,157, 46,179,182,182,118,141,189, 55,225, 41,227,253,117,221,203, 99, 61, 40, 83, 61,112,253, 20, 32,114,131,167, -187, 12,103,114, 15, 1,215, 79, 2,180, 0,160,133, 24,252, 64, 24,250,135, 7,134, 17, 66,134,113, 28,247,239,238, 80, 1,143, - 63,254,248, 93, 19, 87,173, 5, 17,128, 62,119, 51,159, 86,145, 53,125,250,244,253, 44,203, 74,186,226,222,109, 89,147,201,114, - 23,141,227,101,116, 50,228,219,178,124,195, 46, 71,120, 77, 38,211,162,252,252,124,204,157, 59,119,238,179,207, 62, 43, 14, 9, - 9, 65, 64, 64, 0, 10, 10, 10,160,209,104,144,153,153,217,100, 54,155, 55,213,214,214,190,218,133,251,207,108, 73,119,171, 12, - 88, 0,155, 91,210, 93, 65, 98, 98,226,153,226,226,226, 42, 47, 47,175, 24,129, 64,240, 0,154,227,124,174,183,252,143,194,174, -112,206,153, 51, 39,175,184,184,248,134,159,159, 95,108, 11,167, 2,192, 53, 0, 27,187,200, 89,149,151,151, 23, 24, 29, 29,205, -242,120, 60,174,197,195,192,241,249,124,142,207,231,115, 0,144,157,157, 45, 2,208,105,204,101,121,121,249,159,247,236,217,131, -156,156,156,152,250,250,250,103, 0,252,163,177,177, 49,250,230,205,155,182, 78,184, 29,111,167,200,169,159, 58,109,159,143,181, -115,189, 2,192,176,110,144, 63, 44, 95,190, 28,153,153,153,232,108, 5,242,189,123,247, 2,157, 12, 17, 90,219,138, 85, 60, 49, - 12,131,115,231,206, 89,247,222,179, 13, 11, 90,151,104, 48,155,205, 29,174,244,206,178,172,197,104, 52,226,227,143, 63,182, 75, -100,237,216,177, 3,122,189, 30, 44,203,218,101,103, 91, 22, 38, 69,117,117, 53, 84, 42,149,213,227,220,218, 41,226,112,153,210, - 52,141,208,208, 80,220,184,113, 3,158,158,158, 0,154,135, 5,109,222,189,134,134,223, 77,251,239,112,161,209,214, 24, 17,160, -112,163, 4,100,207,195, 65,130, 17, 19,251,201,209,211, 75, 6,158, 80,132,202, 58, 11,254, 93, 92,143, 79,142,234, 74,141, 22, -203,196, 3,154,154,124, 59,189, 78,177,190,190,190,139, 45, 22, 75, 36, 69, 81, 18,142,227,234,105,154, 62,173,213,106,151,113, - 28,119,206,145,155, 80,136,233, 66,119, 41,237,198,231, 11, 57, 11,203, 2,160, 0, 98, 77,116,243, 39,213,124,222,164,103, 4, - 22,142,236,174,208,221,152,117,175, 11, 63, 36, 36, 36,187,161,161,225, 55,183,146,187, 84, 42, 93, 90, 88, 88,120,223,174,228, -110,197,131, 15, 62, 56, 88, 44, 22, 47,102, 89,246, 65,189, 94,239, 35, 22,139, 43, 8, 33, 39,110,221,186,245,198,233,211,167, -127,114,118,159,247, 14,119,115, 37,247, 54,218,120, 60,128,101, 30, 30, 30, 33,103,207,158, 21,181,246, 96,181,182,151,142,172, -139,228, 68,247, 67,120,120,248,177,237,219,183, 15,238,213,171, 23,213, 58,144,157,162, 40,219,226,152, 20, 69,217,102,150,254, -244,211, 79,230,196,196,196,163,121,121,121,195,219,227, 12, 10, 10,202,206,201,201, 25, 83, 91, 91,251, 51, 33,213,122,101,119, -235,121, 83, 83, 19,254,250,215,191,126, 87, 88, 88,216,230, 86, 57, 97, 97, 97,239,166,166,166,206,127,244,209, 71, 41,138,162, -126, 22,115,101,221,214,199,154, 24,134,193,238,221,187,217,172,172,172,247, 47, 94,188,216,110, 12, 86, 84, 84, 84,233,169, 83, -167,212,214, 37, 19,218, 75,173, 17, 27, 27, 91,254,211, 79, 63,169,126, 77,206,223,141,192,106, 49, 40,100, 84,144,226, 9,142, - 35, 83, 9, 72, 63,138,112, 66, 51, 7, 13, 1,178, 37,141,162,143,246,106,181, 77,206,199,214,137,251,242, 65, 33,132,114,110, -242,251,251, 66, 80, 80, 80, 97, 97, 97, 97, 96, 7,109,194, 41,176,126,227, 34,221,203,203,235, 0, 69, 81,254, 86, 17,221,222, -103,139, 55,233, 74, 69, 69,197,195, 21, 21, 21,237,174,167,168, 86,171,251,186,184,184,252,141,101,217,104,123, 54,123,166, 40, - 42, 87,175,215,191,244,107,111,246, 28, 25, 25, 89,148,155,155,219, 87, 44, 22,223, 17, 87,104,189,231,255,205,251,229,203,151, - 49,121,242,228,146,188,188,188,128, 95,147,243,119, 37,176,156,112,194, 9, 39,126, 47,240,243,243, 59,198, 48, 76,152, 94,175, -231, 27, 12, 6,190,217,108,190,163,131, 19,139,197,186,198,198,198, 30,206,146,114,226,183, 6,149, 74, 21,162, 80, 40,190,229, -243,249,162,182, 94, 28,254, 23, 22,139, 69, 95, 85, 85, 53, 78,171,213,106,126, 77,206,223, 60,218,154, 33,115,183, 18,128,209, - 78, 78, 39,167,147,211,201,233,228,116,114, 58, 57,157,156,191,183, 68, 57,181,188, 19, 78, 56,225,132, 19, 78, 56,225,196,221, -133, 83, 96, 57,225,132, 19, 78, 56,225,132, 19, 78, 56, 5,150, 19, 78, 56,225,132, 19, 78, 56,225,132, 83, 96, 57,225,132, 19, - 78, 56,225,132, 19, 78,252,174,240,223, 1, 0, 29, 13,182,141,194,138, 6,132, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, + 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 88, 0, 0, 2,128, 8, 6, 0, 0, 0, 64, 11, 6,158, 0, 0, + 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 10, 79,105, 67, 67, 80, 80,104,111,116,111, +115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, + 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69, + 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44, 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107, +214,188,247,230,205,254,181,215, 62,231,172,243,157,179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131, +199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16, 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, 7,190, 0, + 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,128, 20, 0, + 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38, 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,127,230,211, + 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, 69, 0, 88, + 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73, 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, 48, 81,136, +133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,153,178, 60, +185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46, 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,153, 25, 50, +129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191, 6,255, + 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,238, 4,104, + 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, + 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71, 4, +248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20, +227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, 0,176,106, + 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16, 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,104,131,225, +207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, 68,160,129, + 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, + 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15, +250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8, 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, 33,193, 72, + 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, 70,186,145, + 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178, 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154, +143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,108, 48, 46, +198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172, 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, 18,129, 69, +192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76, 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, 81,194, 39, + 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18, +137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107, +178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82, +202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50, 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, + 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, + 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, 25,119, 24, +175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74, +149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169, 9, +212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,195, 76,195, + 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, + 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,116, 78, 9, +231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, + 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, 83,217, 83, +221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167, +222,121,189,231,250, 28,125, 47,253, 84,253,109,250,167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, 53,113,111, + 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, + 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33, 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205, +204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178, +228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78, +147, 78,171,158,214,103,195,176,241,182,201,182,169,183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197, +174,195,238,147,189,147,125,186,125,141,253, 61, 7, 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206, +156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185, +115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179, +155,194,237,168,219,175,238, 54,238,105,238,135,220,159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11, +159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62, +246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255, +100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217, +237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80, +126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67, +115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, + 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47, +200, 93,112,121,161,206,194,244,133,167, 22,169, 46, 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, + 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53, +121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146, +145,144,113, 66,170, 33, 77,147,182,103,234,103,230,102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,201,107,179, +144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237, +204,179,202,219,144, 55,156,239,159,255,237, 18,194, 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113, +121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94, +193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21, +137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102, +233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219, +187,131,182, 67,185,163,191, 60,184,188,101,167,201,206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248, +110,209,238, 27,123,188,246, 52,236,213,219, 91,188,247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,251,179,247, + 63,174,137,170,233,248,150,251,109, 93,173, 78,109,113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,210, 61, 84, + 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,247, 9,223, +247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, + 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140, +157,149,157,125,126, 46,249,220, 96,219,162,182,123,231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, + 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154, +174,185, 92,107,185,238,122,189,181,123,102,247,233, 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243, +122,111,247,197,247,245,223, 22,221,126,114, 39,253,206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221, +135,213, 63, 91,254,220,216,239,220,127,106,192,119,160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, 5,143,153, +143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, + 47,126,248,213,235,215,206,209,152,209,161,151,242,151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201, +120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251, +147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,131, 0, 0, +249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234, 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 2,221, 78, 73, 68, + 65, 84,120,218,236, 93,119,120, 83, 85, 31,126,207,189, 55, 59,105,186, 91,104,203,104,153,101, 79,217, 8,178, 28,108,113,128, + 11, 20, 5, 4, 62, 21,193,130,136,128, 76, 23, 67,100, 56, 89,178,101,136,202, 82,217, 75, 64,100,239, 89, 74,247,110,118,114, +207,247, 71,115, 99, 26,210, 38,133, 50,196,243, 62,207,125,146,187,222,123,246,121,207,239, 44, 66, 41, 5, 3, 3, 3, 3, 3, + 3, 3, 3, 67,217,129, 48,129,197,192,192,192,192,192,192,192, 80,182,224, 74,173,200, 8,161,165,120,182,163,191,156,206,227, +209, 7,157,243, 46,250,157,150, 33,231,163, 78,206,241,255, 18,119, 62,250,160,114, 74,254,245,151,183, 52,156,254,166,169, 82, +186,147,150,181, 59,239, 22,103, 89,229, 35, 47,238,164,119, 33,222,199,255, 75,220,249,232,131,198,233,153,126,252,225, 45, 45, +167, 63,105,234, 54,220, 73,203,218,157,119,139,243, 78,243, 81, 9,238,164,119,154,150,138,137,251,241,248, 15, 64,184, 91,226, +170, 52,160,148, 18, 55,126,242,160,114,186,135,131,196, 95,150,110, 45, 67,108, 47,107, 78,143,240, 44, 43,140,167,148, 18, 66, +200, 14, 0,143,150,165,223,203, 34,222, 61,252, 90, 38,188,165, 21, 87,165,229, 44,171,116,127,183, 57,203, 42, 47,121,114,150, + 69,186,247, 22,239,119, 49,142,202,202,157,101,146,151,238, 70,154,247,146,126,238,152,215,147,179, 44,242,146, 39,103, 89,164, +251,123,193, 89, 22,121,201, 27,103, 89,164,251,226,226,158, 89,176,238,141, 16,240,204,216,237, 30,100, 33,116,183, 68,166,191, + 22,151, 7,129,179,140,227,104,188,147,179, 44, 91, 51,237,202, 42,142,238, 70,122,119,231, 44, 43,126, 79,158,178,136, 39,111, +156,119,234,222, 98,220, 89,230,126,191,211,116,127,175, 56,203, 56,142,202, 36, 47,121,112,182, 43,227, 70, 64, 59,183,243,241, +101,201, 89, 86,121,201,139, 59,239, 56,158,188,113,222,169,123,139,113,103,153,251,189, 44,234,144,187,197,251,208, 89,176,238, +166,184,186, 91,149, 89, 89,114,223, 13, 43,206,221,178,180,149,149, 21,199, 11,239,142, 50,164,219, 94,214,238,116,186,143,220, + 45,107,235,131, 14,150,151, 88, 94,122,208,242,146,183,116, 67, 41, 29, 79, 8,249,240, 65,107, 60,187,115,150,149, 16,242,226, +247, 59,202, 75,158,239,150, 69, 94,242,193, 73,238,134,255,203, 58, 63, 61,136,224, 30, 20,135,248, 59,190,231, 54,248,218, 61, +200, 17,112,151,220,217,238,223,224,247,187,225, 78, 66,200,248,187,228,247,127, 75,152,178,188,196,242,210, 3,151,151, 60,210, +100,187,178,178, 12,149,117, 67,202,147,179, 44,190,225,206, 81, 86,105,244,110,251,189, 44,243,210,221,136,251,127, 11, 74,109, +193,186,219,221, 38, 15, 50,231,221,224,190, 75,126,223,113, 55, 90, 7,119, 97, 92, 87,153,187,147, 82, 58, 30,101,216,229, 40, +249,185, 44,221,122, 55,187, 9,239, 70,218,188,155,233,189, 44,199,121,220, 37,191,255, 91,226,189,204,221, 89, 86,121,201, 75, +156,223,177, 91,189,133, 95, 89,119, 97,151,101,218,188,155,156,101,193,125, 55,220,121,183,226,254,223, 4, 14, 12, 12, 12, 12, + 12, 12, 12, 12, 12,101, 10,182, 14, 22, 3, 3, 3, 3, 3, 3, 3,195,189, 18, 88,209,209,209, 27, 53, 26, 77,213,226, 94, 44, + 40, 40,184,153,148,148,212,158, 5, 33, 3, 3,131,207,130,134, 16, 14,255, 88,204, 69, 0,148,178,214, 29, 3, 3,195, 67,140, + 98,199, 96, 41,149,202,184,211,167, 79, 87, 23, 69, 17, 14,135, 3,118,187,221,245,107,177, 88,208,182,109,219, 82,143,223, 42, + 87,174,220, 78,158,231, 43,151,230, 29,135,195,113, 45, 57, 57,185,117, 9, 5,247, 94, 0,113,132, 16,247,107, 37,254, 2, 72, +178, 90,173,141, 74,226, 36,132,196,121,242, 21,195, 37,253, 47,145, 51, 40, 40,232,144, 32, 8, 49,222,184,138,251, 47,138,226, +165,212,212,212,150, 44,153,222, 27,148, 43, 87,110,167, 32, 8,165, 78,159, 55,111,222, 44, 54,125, 70, 68, 68,252,197,113, 92, +148,175, 52,201,113,133,218,131, 82,202,139,162,120, 54, 41, 41,169,117,113, 2,132,227, 56,159,105,222,243, 63,128, 68,171,213, +218,196, 87, 62,242, 55, 15, 57,127, 75,228,116, 23, 87,130, 32, 76,139,136,136, 24,108, 48, 24, 76, 0, 40,207,243, 52, 52, 52, + 20,132, 16, 23,167,221,110, 79,203,202,202,170,203, 82, 34, 3, 3,195, 67, 45,176, 68, 81,228,204,102, 51,206,157, 59,135, 98, +202,121,199,109,124,175,250,137,223,183, 70,168,195, 35,225,176, 89,161, 12, 13,119,113,103,159, 62, 1,209,106,133,195,106, 65, + 88,147,230, 82,229,133,218,181,107,243, 62, 56, 99,166, 79,159, 30, 17, 16, 16, 0,147,201, 4,147,201, 4,179,217, 12,147,201, + 4,139,197, 2,139,197, 2,171,213, 10,171,213, 10,187,221, 14,179,217,140,109,219,182,249,114,123,204,228,201,147, 35,244,122, +189,139, 79, 58, 36, 78,137,215,102,179,193,100, 50,225,247,223,127, 47,145, 83, 16,132,152,164,164,164, 8,185, 92, 14, 74, 41, + 68, 81, 4,165,180,200,225,137, 42, 85,170, 88, 89, 18,189,167,168,190,111,209,183, 17,202,144, 80,136, 54, 27, 66, 27, 52,150, + 68, 15,146,126,223, 12,135,213, 10,209,102, 67,165,110,189, 93,215,227,227,227, 75, 76,159,148,210, 74,187,191,156, 25, 36, 15, + 8,128,221,100, 66,108,215, 94,174,123, 39,231,207,132,104,179,130,218,172,168,247,206, 88, 0, 64,122,122,186,177,106,213,170, + 73, 40, 28, 8, 74,139, 17, 44, 49, 5, 5, 5, 17,146, 27, 60, 69, 17,199,113, 69,142, 61,123,246,160, 99, 71,159,139, 46,199, +204,158, 61, 59, 66,202, 35,158,233,220,110,183,187,126,237,118, 59, 76, 38, 19, 54,109,218,228,175,229,106,122,167, 78,157, 6, +252,252,243,207,218,117,235,214,105, 43, 87,174, 12,185, 92, 14,158,231,193,243, 60, 56,142,131, 32, 8,104,214,172, 25, 97, 73, +144,129,129,225,161, 23, 88,102,179,249,114,195,134, 13,169,243,127,180, 82,169,148,123, 20,156, 81,213,171, 87, 63,235,249,158, +175,174, 67,117,120, 36,190,139, 13, 1, 0, 60,115, 49,195, 85, 49,172,110,211,192,245, 76,223,171, 57,133,207,170,213, 32, 30, +205,112,111,208,106,181,232,212,169, 19, 20, 10, 5,154, 52,105, 2,153, 76,230,245,144,203,229,144,201,100,254, 84, 10,208,233, +116,152, 48, 97,130, 36,142,160, 85, 41, 49,172,101, 19,168, 64,241,213,137,243,176,136, 20,130, 32,184, 14,127, 56,229,114, 57, +142, 31, 63, 14, 65, 16,192,243,188,235, 87,250,191, 97,195, 6,244,233,211, 7,130, 32, 64,173, 86, 3,255,161,217, 22, 15, 10, + 84,161, 97, 88,221,182, 33, 0,224,133,235,121,174,184,251,245,185,174,174,103, 94,186, 81,224,138, 79,201,242, 84, 28, 56,142, +131, 60, 32, 0,191,244,121, 2, 0,208,251, 92, 42,100, 50, 25, 4, 65,192,177,207, 39, 65,166, 80, 64,144,203, 81,239,157,177, + 72, 79, 79, 55,246,234,213,107,119, 64, 64,192,230,220,220, 92,248, 16,110,184,126,253, 58, 4, 65, 40, 54,189,115, 28,135,133, + 11, 23,226,234,213,171,126,249,221,104, 52, 98,234,212,169, 32,132, 20,201, 47,197,253,247, 83, 92, 77,234,220,185,243,139, 63, +255,252,115, 48, 33, 4,115,230,204,129, 92, 46,199,147, 79, 62,137,208,208, 80,108,217,178, 5,114,185, 28,163, 70,141, 98,137, +143,129,129,161, 36,200, 0, 52, 0, 16,238, 52,240,228, 1, 8,114,187,159,230,252, 13,119, 59,255,211, 11, 79, 83,231, 51,210, +125,233,220, 2, 64,225,229,122, 6, 0,181,243, 48, 3,216, 11,160,142,219,119,164,247,224,249, 93,193, 89, 16, 62, 10, 96, 59, +128,118,210,226,119, 55,111,222,124,194,205,146,114,250,236,217,179, 53, 37,173,227,236, 42,148,219,237,246,234, 82,183,161,212, +242,237,216,177, 99,137, 45,122,135,205,122,139,240,240,166,161,188,117,121, 20, 39, 92,172, 86, 43,158,125,246,217,194, 24, 40, +166,178,113, 63,252,208,108,176, 88, 44, 16, 4, 1, 53, 42,132,227,131, 46, 13,241, 8,181,161, 32,159,192,158, 83,128, 30, 58, + 27, 78,215,106,132, 5,215,210,112, 53, 55, 31,130, 32,248,197, 41,138, 98,177,226,138,231,121,204,155, 55, 15,207, 63,255, 60, +120,158,247,139,143,161,236,225,176, 90,189,166,195,226,210,172, 63,241,100, 55,153, 10,197,150,192,187,196,149, 76, 38,131, 76, +169,132, 32,151, 67, 80,200,145,158,158,110,236,216,177,227,126,133, 66,177, 40, 50, 50, 50, 41, 49, 49,209,167,192, 42,194,229, +165, 49,241,253,247,223, 99,241,226,197,104,214,172,153, 95,249,200, 98,177, 64, 46,151, 99,210,164, 73,183,220,159, 63,127,254, + 45, 2,171, 36, 78,103,195,136,139,138,138, 26,178,105,211, 38,189,244,108, 88, 88, 24,100, 50, 25,234,214,173,139,128,128, 0, +236,222,189, 27, 14,135,195,239,124,201,192,192,240,240,194,155, 22,113, 67,219,209,163, 71, 55,153, 54,109,218,148, 22, 45, 90, + 44,223,187,119,239, 50, 66,200, 70,183, 50,177,171,147, 99,163,219,121, 83, 15,145, 37, 3, 16, 78, 8,217, 40, 61,239,126,238, +118,189, 35, 0,133,116, 62,122,244,232, 58,211,166, 77,155,146,144,144, 48,102,234,212,169,242,209,163, 71,215,155, 54,109,218, + 20,233, 59,222,220,225,110,193, 42,113, 21, 96,169,187,240,204,153, 51,240, 53, 46,213,215,250, 25,202,208,112,151,229,106, 85, +149, 80,215,245,231,175,100,187, 42,174, 95, 30,169, 10,133, 78,139, 38, 31,126,226,151,101,200, 98,177, 32, 53, 53,213,213,242, +246,117,248,203,169, 81,171,176,237,237,186,184,158,161,192,248,125,153,248,249,232, 5,200,100, 50, 60, 94,171, 46,158,144, 7, + 96,108, 37, 5,222, 62,127, 5, 54, 63,199,234, 82, 74,189, 10, 43,233,191,212, 85,194, 4,214,253, 67,104,131,198, 46,203,213, +210, 10, 1,183, 88,173, 0, 96, 67,163,202, 80, 6,232, 80,247,127, 9,126,165,165,216,174,189, 92,150,171,159, 27,199,130,151, +201, 32, 83, 40,240,204,241, 27, 0, 10,187, 5,219,215,141,223,145,205, 43, 22,190,248,226,139,151,255,248,227, 15,181, 47, 78, +169, 49,225, 41,176, 36,241,243,253,247,223, 99,201,146, 37, 16, 4, 1, 86,171,127, 61,205,102,179,185,216,252,225,205,130,229, + 79, 26, 45, 40, 40,176,172, 95,191, 30, 95,124,241, 5, 66, 67, 67,209,185,115,103,148, 47, 95, 30,171, 86,173, 2,165, 20, 67, +135, 14,133, 90,173,150,172,213, 44, 1, 50, 48,252,183, 81,146, 22, 81, 78,155, 54,109,138,187,128,241, 20, 52,238,194,201, 67, + 68,185,139,180, 58, 62,202,215,141,158,162, 73,250, 46, 33,100,227,212,169, 83,187,250,112, 71,154,167,192, 42,113,153,125,179, +217,124,185,126,253,250,126,169, 8,131,193,144,236, 75,100,120,107,249,187, 91, 5,148, 1, 58, 40,117, 58,112,126,174,210,101, +179,217, 92, 2,101,235,214,173, 80,171,213,120,242,201, 39,239,200,130,101,181, 90,161,144,203,192,133, 69,226,229, 25,127, 32, + 35,207,232,170,208,182, 95,186,140, 35, 41,169,120,187, 69, 7,104,213,169,200,183, 88,252,178, 16,136,162,120,139,184, 18, 4, + 1,207, 62,251, 44,204,102, 51, 8, 33, 69,198,165,128,117, 17,222,207,150,148,215,115, 66, 8, 84,250, 0, 40,180, 90,240, 60, +239, 23,151,187,181, 73, 80, 40, 32, 83, 42, 32, 56,133,140,100,185,202,230, 21, 11,111,220,184,177, 31,128,234,145, 71, 30, 81, +251,195,235, 46,176,220, 5,144,187,184,226,121, 30, 54,155,205, 47,255,154,205,102,200,229,255,140, 4,184,118,237, 90,137, 2, +203,135,159, 41, 33, 68, 4, 32,198,197,197,185,222, 45, 87,174, 28,130,130,130, 32,138, 34, 68, 81,132, 74,165,130, 90,173, 46, +242, 93, 6, 6,134,255,116,217, 91,156,214, 48, 38, 36, 36,140, 33,132,108,116, 90,146, 78,148, 32,164,188,161,169,135, 72, 75, + 43,166,236,234,234, 77,100,185,255,151, 48,122,244,232, 58, 94,220,241,231, 45, 2,203, 77, 53,222, 2,247,238,194,178,170,188, + 74,170,192,212,122, 61,228, 90, 45, 56,142,243,185,191,146,212, 69, 40,141, 57, 25, 60,120,112,137,227, 82,252, 29, 47,101,181, + 90,193, 9, 60,110,150,139,133,131,219,245, 79, 5,233, 60, 56, 65,134,171,229,106,130, 63,243, 23,100,162,120, 91, 22,172,161, + 67,135,226,235,175,191,150,252, 9, 66, 8, 4, 65, 64,181,106,213,112,249,242,101,150,211,238, 3, 40,165,197,138,101,233,186, + 42, 32, 0, 10,157, 14,188,159,105,201, 93, 12,201,149, 74, 8, 10, 57, 4,121, 97,183, 96,183,110,221,118,100,103,103, 47,172, + 93,187,246,121, 20, 46, 99,192,249,155,135, 4, 65, 40, 34,124,188,137, 43, 65, 16, 96,183,219,253,110, 84,120, 10,157,201,147, + 39,223,242,220,211, 79, 63,237,111, 67,133,114, 28, 71,229,114, 57, 58,117,234,132,122,245,234, 97,221,186,117, 16, 69, 17,111, +190,249, 38,212,106, 53,102,206,156, 9,187,221,142,233,211,167, 51, 11, 22, 3, 3, 67, 73, 90,196, 60,117,234,212, 19, 83,167, + 78,117, 89,146, 60, 45, 88,197,224, 41,167,152, 10,151,196, 25, 10,199, 82,253, 89,130, 27,186, 22, 39,188,220,175, 77,155, 54, +109,138, 23,119,184,186, 37,239,249,102,207,217,167,142,187, 6, 17,187,119, 11,110,106, 89, 19, 74,157, 22, 74,157, 14,173,214, +237,114,181,154, 1,223,221, 48, 54,155,205, 37,176, 50, 50, 50, 74, 20, 87,165,177, 96,113, 10, 1,171, 99,178, 64, 21, 50, 8, + 22, 91, 17,129,197, 11, 50, 92, 15,141, 5, 39,147, 67,112,248, 87,129, 81, 74,111,233, 18,124,229,149, 87, 64, 8,113,205,248, +170, 95,191,190, 59, 23,171,113,238, 49,146,126,223,236, 26,208,238,222, 45,184,241,145,170, 80, 5,232,160,208,106,209,246,167, +189, 46,107, 35,222,159,236,147,243,236,183, 95,226,248,204, 41,144, 41, 20,232,253,215, 85,151,229,170,101,141,170,251, 45, 90, +253,194,107,215,174,237, 7,192, 61,247,220,115, 65,245,235,215,247,153, 39, 37, 65, 94,146,184,114, 23, 88,254, 90,176,164,134, +138, 63,150, 51,127, 44, 78,148, 82, 26, 18, 18, 2,142,227,160,215,235,161,211,233, 92, 51,104, 85, 42, 21, 52, 26,141,107,252, +166, 63,223,101, 96, 96,248, 79, 35, 88, 18, 56, 78,145, 84,196,178, 68, 41,237,234, 46,130,138,235, 42,116, 90,156,118,250,248, +214,207, 78, 97,230, 21,146, 37,205,163, 12,221,232, 41,206, 4, 73, 49,186,255,150, 47, 95,254, 87,157, 78, 23,235,175,175, 75, +179,232,168,251, 32, 98, 73, 92, 17, 66,160,210,233,160,208,105,161, 12,208, 21,107,229, 42, 73, 96, 73, 21,138, 84,217, 44, 90, +180, 8, 58,157, 14,253,251,247, 47,245, 24, 44,151,192,146,115,216,162,252, 29,188, 66, 40, 34,174, 4, 65, 0, 47,147, 33, 89, + 87, 30,156, 76, 6,193,238,159, 37, 35, 39, 39, 7,130, 32,224,131, 15, 62,112,181,216,221,197, 85,105,252,204,112,119, 32,186, +137,145, 34, 86,213,128, 0, 87,250, 44,205, 0,119, 0,160,118, 27,100, 74, 37,100, 10,185, 75, 92,117,235,214,109,135, 69,171, + 95, 88,179,102, 77,151,229, 74,163,209, 72,179, 71,125,130,227,184, 34,105,122,225,194,133, 69,196,149,167, 5,203, 31, 62,201, +130,245,245,215, 95,151, 40,162,228,114, 57,228,114,185,223,254,231, 56, 14, 59,118,236,192,145, 35, 71, 48,120,240, 96,168,213, +106,204,158, 61, 27,118,187, 29, 31,125,244, 17,212,106, 53, 20, 10, 5, 75,124, 12, 12,204,122, 85,210,190,162,105, 30,227,156, +136,135,165, 41,205,155,176,114,239, 14,116,251,111,243,194,107,241,232, 58,244,188, 46,253,102, 76,157, 58,245, 15,201,114,229, +118,189,136, 59,138,181, 96, 41,149,202,216,115,231,206,185, 22, 25, 45,233,215, 98,177,160,125,251,246,126, 91,194, 68,231, 44, + 66,206, 57,144,219, 53,238, 74,175,131,210,217,245,226, 33, 52,136,175,194, 91,106, 1,187, 11,172, 15, 63,252, 16,130, 32,224, +235,175,191, 6, 0,188,251,238,187,126,143,193,146, 56,225, 32, 72,164, 23,209,112, 70, 31, 88,150,218,144,178,231,111, 8,130, +128,136,230, 79, 64,124,164, 15, 12,106, 29, 4,135,221,239, 89,132,153,153,153,184,124,249, 50,120,158,199, 59,239,188, 83,100, +173, 34,207,153,105, 91,183,110,101, 22,172,251, 40,176, 56,231,248, 42,111,233,211, 67, 92, 17, 95,194,154, 58,236,133,227,174, +228,255,204, 22,204,206,206, 94,120,237,218,181, 3, 0,184, 23, 95,124, 49, 72,163,209,224,219,111,191, 53, 0, 80,172, 90,181, +202,231, 32,119, 41,221, 20, 39,174,110,167,139, 80,178, 4,187,143,235, 42, 73, 96,249, 3,201,173,132, 16, 56, 28, 14,168,213, +234, 34,150, 43,149, 74, 5,165, 82,201, 18, 30, 3, 3,131, 47,252, 89,138,103,155,186,137,165, 63,111,147,247,207, 59,117,176, + 80,156,192, 48,155,205, 56,117,234,148,191, 60,126, 47, 58, 26,218,184, 25,250, 94,205, 1, 33, 4, 91,218,212,118,117,187,180, + 92,179,195, 85, 9, 92,157,250, 46,100, 90, 29, 66,219,116,246,171, 0,151, 42, 6,119,129,149,157,157, 13,153, 76,134, 73,147, + 38,129,227, 56, 76,159, 62, 29,209,209,209,184,121,243, 38, 86,173, 90,229,151, 5,139,119,240, 40,255, 82, 60, 52,175, 4, 66, +255, 82, 91, 4,119,250, 16, 55, 44, 2,246,154, 52,104,107, 58, 9,197,150, 89,176,136, 14,191,198,117, 1,128,221,110,199,142, + 29, 59, 60, 7,178,131, 82,234, 90, 37,223,102,179,193,106,181, 98,250,244,233, 96, 59,137,220,123, 84,120,170, 39, 94, 78, 50, + 0, 0,126,117,235,182,110,189,118,151, 43,125, 94,158,252, 14,100, 90, 29,130,155,182,241,139,179,214,155, 35, 81,235,205,145, + 72, 79, 79, 55,118,104, 80,123,103,190, 92,243,125,221,186,117,139, 88,174, 84, 42, 21,113,158,251, 37,170, 57,142, 3,207,243, + 46,113, 37,137, 41,111, 2,203,223,113,135, 54,155, 13,114,185,220,111,129, 85, 26, 11,214,171,175,190,138,242,229,203,187, 44, + 87, 19, 39, 78,132, 90,173,198,232,209,163, 97,179,217, 48,107,214, 44,150,248, 24, 24, 24,238,135, 24,187,107,240, 90,242,154, + 76,166, 43,245,234,213, 67, 49,247,162, 85, 42,149,204,163,112,142,170, 94,189,250, 89,207,174, 66, 66, 72, 71, 74,233, 54,111, +133,185,251,108, 44,165,135,213, 74, 30,160,135, 76,171, 3,231,165, 59,207, 27,167,180,142,142,187,192,146,142,156,156, 28,200, +100, 50,124,241,197, 23,208,235,245, 48,155,205, 62, 57, 9, 33,176,219,237,224,121, 30,134,235,121, 56, 61,101, 27, 20,170,189, +168,218,249,121,148,151,169, 33,223,253, 35,140, 14, 91,137, 11,141,122,227,172, 94,189, 58,198,141, 27,119,203,242, 12,197, 33, + 58, 58,218,167,223,239, 20,140,211, 59,167, 63,233,147, 87, 42,189, 77,214,184, 37,222,129,127,102, 11,230,203, 53,223, 95,190, +124, 89,178, 92, 5,106, 52, 26,204,159, 63,223, 0,128,251,232,163,143, 52,149, 42, 85,226,253, 73, 75, 60,207, 99,209,162, 69, +183, 12,104,247, 38,174,188, 45,251,225,205,239,118,187,253, 22,129,245,236,179,207,222, 50,123,176, 56, 11,150, 55, 78,201,173, +161,161,161, 46,203,149,195,225,112,205, 30,180,217,108,176,219,237,197, 54, 38, 88,250,100,156,140,243,191,195,249,176,193,107, +237,158,148,148,244,120,113, 47, 84,173, 90,245,220,185,115,231,170, 57, 28, 14,247, 61, 10,229, 38,147,169,122,203,150, 45,125, + 54,149, 69, 81,132, 82,169, 4,165, 20, 13,199, 78, 3, 33,183,142,183, 10,106,217, 1, 68, 16,224,112, 56, 96,177, 88,124,206, + 34, 52, 26,141,174,202,164,184, 1,238,249,249,249,174,117,126, 56, 63,214,127, 48,153, 76, 69, 42, 42, 66, 69, 92,253,109,229, + 45,179, 9,165,195,223,214,188, 74,165, 42,210,197, 83, 18,124,173, 41,198, 80,246,144,150, 84,160,148,162,246,176,247, 10,227, +201,217, 93, 40,137,128,192, 38,109, 64,100, 2, 68, 0,102,179,217,151,153,145, 72, 99,174, 40,165,223,245,232,209,227, 44, 10, +103,176, 80,157, 78,167,148,201,100, 34,128, 76, 0, 52, 43, 43, 43,240,198,141, 27,162,201,100,170,232,203,157, 59,118,236,192, +133, 11, 23,208,184,113, 99,215,150, 77, 82,183,155, 36, 98,220, 5,150,191, 22, 44,111,107,106, 21,183,154,187,191,105,158,231, +121, 4, 6, 6,186, 22, 49,149,203,229,208,104, 52, 0,128, 89,179,102,185,194,156,129,129,129,225,161, 23, 88,190,202,203, 18, +186, 15, 75,236, 42,180,219,237,137,149, 42, 85, 42,213,199, 28, 14, 71,138, 15,193,150,184,106,213, 42,185,187,181,192,215, 47, +165, 52,197, 71, 37,155,184, 97,195, 6,185,167, 21,162,184,255,132, 16,159,156, 14,135, 35,177,114,229,202, 94,121,138,131,205, +102,187,193,146,232,189,131,195,225, 72,172, 88,177, 56,109,243,214,109,165, 79,187,221,126, 62, 54, 54, 54, 41, 40, 40,232,231, +200,200,200,140, 61,123,246,132, 54,109,218, 52,212,253,153,166, 77,155,150,247,120,205,130, 98,246, 33,148,210,124,151, 46, 93, +188,166,121,111,105, 83, 74,211,190,210,252,111,191,253,230, 87, 62,146,254,139,162,152,232,135, 96,189,218,176, 97, 67,206,157, +163,184,180,111,179,217,210, 88, 42,100, 96, 96,248,207, 10, 44,163,209,120,189, 94,189,122,246, 98,238, 93, 43,233,221,244,244, +244, 38,101,237, 1,171,213,218,242,223,192,153,150,150,214,132, 37,183, 7, 27,119, 35,142, 82, 82, 82, 30,249, 55,164, 79,139, +197,210,242,110,132,105, 70, 70, 70, 11,150,178, 24, 24, 24,152,192,242, 3,254, 46,199,192,192,192,192,192,192,192,192,240, 95, + 5,199,130,128,129,129,129,129,129,129,129,161,108, 65, 80,184,107,244, 45, 40,205,236, 0, 66, 72,199,210,126,216, 23, 63,227, +100,156,140,147,113, 50, 78,198,201, 56, 31, 62, 78, 95,220, 15,205,236, 68, 74,233, 93, 59, 0,116,100,156,140,147,113, 50, 78, +198,201, 56, 25, 39,227,252,175, 29,172,139,144,129,129,129,129,129,129,129,161,140, 33,176, 32,184, 63, 32,132,240,148, 82, 71, + 25, 82, 6, 3, 40,110, 67, 55, 11,128,172,219,113, 38, 0,185,243,144, 22, 42,178, 1,176, 58, 15, 63,150,154,159,192, 37, 37, + 5,215,161, 14, 89, 83, 74,136, 76, 20,113,180, 98,197, 10,127, 1,143, 91, 0, 64, 87,174, 86, 45,157, 86,221,209,108,181,196, + 42,101,138, 83,217, 5,249, 91, 77, 41,103,175,176, 20,194,192,112, 95,202,165,110, 0, 38, 56,243,254, 84, 74,233, 74, 22, 42, + 12, 12,101, 44,176, 2, 2, 2, 14,113, 28, 23,227,190,102,141,180, 48,102,113,235,226, 56, 28,142,196,204,204,204, 38,126,102, +100, 1,192, 51, 58,157,174,189, 76, 38,107, 5, 0, 54,155,109, 79,126,126,254, 31, 0, 86, 81, 74,237,183, 89, 64,232, 1, 60, + 11,160,159,243,210, 15, 0, 86, 82, 74,115,111,147,175, 94, 96, 96,224, 26,153, 76, 70,211,211,211,155, 3, 64,104,104,232,126, +155,205, 70,114,115,115,159,166,148, 30, 43, 37, 31, 39,151,203,167,181,105,211,166, 53, 33,100, 49,165,116, 94, 25,197,165,146, +227, 56,175,194, 68, 20,197,202,183,193, 39, 7, 16,248,197, 23, 95,132, 46, 89,178,164, 97, 98, 98, 98, 93, 0,136,137,137, 57, +254,226,139, 47,254, 53,108,216,176, 12, 0, 57, 78,161, 85, 44,146,146,130,235,164, 38, 95, 26,156,146,122,234, 89, 0, 40, 87, +190,238, 74,158,231,228,209,209, 71,246,105,194,250,133,213,168, 89,101,208,242,111,191,144, 87,142,173,128,223,247, 30,105, 48, +236,127, 99,234,168, 34,107,124,198, 68,214,189,131, 94,175, 63,196,113, 92, 76, 73,121,220, 91,158,119, 56, 28,137, 25, 25, 25, + 77,138,227, 20, 4, 33,166,164,242,194,219, 53, 81, 20, 47,165,165,165,121, 93, 50, 34, 48, 48,112,159, 32, 8,177,254,114, 73, +191,118,187, 61,177,184, 37, 98, 2, 3, 3, 15,241, 60, 31,227,107,205, 47,207, 95, 81, 20, 47,165,166,166, 22,231,206, 91,252, + 94, 22,238,188, 29,206,146,220, 41,149, 71, 0,102,133,134,134, 54,203,200,200,120, 1,192,152,220,220,220,250, 60,207, 35, 36, + 36,100, 12, 33,228, 66, 96, 96,224, 55, 57, 57, 57,123, 1,252,143, 82, 42,178, 28,195,192,112,135, 2,139,227,184,152, 27, 55, +110, 68,104,181, 90, 0,255,236,151, 39,109,242, 44,138, 34, 40,165,174, 95,187,221,142,248,248,120,127, 69, 70, 93,189, 94,191, +122,244,232,209, 21,159,121,230, 25,133,180, 37, 76, 82, 82, 82,245, 53,107,214,188, 48,105,210,164, 15, 9, 33,125, 40,165,199, +253, 21, 45, 0, 58, 0,120,165, 97,195,134,189, 39, 78,156, 40,127,236,177,199,224,112, 56,240,203, 47,191,180,249,232,163,143, +190, 32,132,252, 8, 96, 33,128,223,252, 45, 36, 8, 33,173,203,149, 43,183,108,247,238,221,229, 47, 95,190,236,120,230,153,103, + 86, 0,192,161, 67,135,226, 28, 14, 7,105,222,188,249,207,132,144,190,148,210,221,165, 8,243, 30,195,134, 13,235, 51,116,232, +208,240,254,253,251,191, 4, 96,158,243, 91,210, 46,226,165,221,128,208,101,185,162,148,150,180, 3,111,185, 82, 88,178,180,151, + 47, 95, 14,110,217,178,229,144,212,212,212,183,221,121, 83, 82, 82,112,248,240, 97,235,148, 41, 83,102,236,221,187,119,110,108, +108,108, 22,128,130,226,136,168, 67,214, 52, 37,245,212,179,109, 91,124, 17, 8, 0,171, 54, 12,121,254,224, 95,105, 1, 27, 55, + 45,120, 65,161,146,155,151,124, 53, 67, 94,173,106,101,108, 63,116, 30, 7, 78,101,146,186,173,187, 10, 57, 27, 23,119, 2,176, +128,101,207,123, 3,158,231,163, 19, 19, 19, 35, 52, 26,141,215, 13,221, 61,198, 93, 72, 11,235,162,122,245,234,197, 23, 44,130, + 16,115,227,198,141, 8,149, 74,229, 42, 59, 60,203, 12,169, 92,113,165, 21, 74, 81,163, 70, 13,107, 9,101, 82,165,107,215,174, + 69,104, 52, 26, 23,143, 55,247,121, 10,141, 26, 53,106,148,228,247, 34,238,244,135,147, 82,138,106,213,170, 57,124,249, 93,218, +177,194,151,191, 37,206,216,216, 88, 90, 26, 78,127,220, 89,165, 74, 21,171,143,232,159,117,246,236,217,161, 21, 42, 84, 64,181, +106,213,246, 54,107,214, 76,175,213,106,177,105,211, 38,212,170, 85,171,142, 94,175, 63,176,106,213, 42,217,168, 81,163, 26,124, +255,253,247, 0, 48,140,229, 24, 6,134, 59, 20, 88,132, 16,104,181, 90,172, 88,177,194,181, 61,140,180, 77,134,183,255,197,175, +128,125, 11,111,147,216,216,216, 29,187,119,239, 86,151, 47,255,207, 2,214, 22,139, 5,193,193,193,120,243,205, 55, 21,221,186, +117,171,214,185,115,231,253,132,144, 71, 41,165,135,124,240,245, 14, 15, 15,159,243,193, 7, 31, 68, 62,247,220,115, 8, 13, 45, +178, 72, 54,158,121,230, 25, 60,253,244,211,242,179,103,207, 62,191,104,209,162,231,231,205,155,151, 76, 8, 25, 70, 41,253,177, + 36, 94,141, 70,211,163,106,213,170,243,119,239,222, 29, 17, 17, 17,129,184,184, 56,110,212,168, 81,213,170, 87,175,174,142,137, +137,225,110,222,188,137,117,235,214, 69,247,237,219,119,181, 66,161, 24,100,177, 88,214,251,225,119, 69, 72, 72,200,200, 55,222, +120, 35, 52, 55, 55,215,126,228,200,145,243,210,117,165, 82, 57,174,121,243,230,141, 8, 33, 43, 40,165, 11,111,199,114,229,180, +210,121,238, 57, 98,147,238,251,105,201, 82, 28, 61,122, 52,164, 69,139, 22, 63,154,205,230, 70,131, 7, 15,190, 54,101,202, 20, +181, 94,175,215, 3, 32,185,185,185, 89, 19, 38, 76,176,204,156, 57,243,189, 90,181,106,117,216,183,111, 95,239, 6, 13, 26,216, +156,226,237, 86,129, 69,136,203, 61,215,111,164, 97,199, 94, 81, 49,110,244,187, 49, 31, 79,142,189,250,231,201,235,162,160,214, +227,167,157, 39,144,146,145,143, 95,247,157, 68,185,208, 0, 34, 87,202,234, 4,197,212,121, 52,231,198,201,157,148,237,120,125, +215, 65, 8,129, 70,163,193, 79, 63,253,116,203, 22, 83,222,182,159, 18, 4, 1, 65, 65, 65, 62,119, 35, 80,169, 84,216,186,117, +107,145,237,165,188,253,151,126, 3, 3, 3,129, 18, 54,187, 38,132, 64,165, 82, 97,207,158, 61,224, 56,238,150,247, 61,221, 44, + 8, 2,180, 90, 45,184, 18,246,164,146, 56,119,238,220,233,147, 75,250,213,233,116, 0, 80,226,254, 67, 74,165, 18,187,119,239, + 46,214,207,158,255,117,206,253, 46,125,113,238,217,179,167,200, 22, 93,158, 91,119,185,159,107,181, 90, 87,195,173,216,214, 89, +112,112,243,152,152, 24, 28, 60,120, 16,171, 86,173, 10,169, 83,167, 14,206,159, 63, 15, 66, 8,166, 76,153, 66,106,215,174, 45, + 75, 78, 78, 70,155, 54,109,176,118,237,218,150, 44,183, 48,220, 71,200, 0, 52, 0, 16,142,194, 93, 99,242, 0, 4, 57,235, 30, + 5,128, 12, 0,106,231, 97, 6,144, 15, 32,204,249,110,186,179,108,113, 23, 8,105, 40,186, 41,116, 83, 39,183,180,163, 68,184, +219, 61,233, 27,158,231,158,191, 69,184, 5,103, 33, 35, 85, 98,237, 40,165, 59,138,248,200, 15,113, 37,237, 35,230,153,151,189, +108,252,170,212,106,181,107,246,239,223,175, 14, 15,255,199,237,102,179, 25,121,121,121,200,207,207, 71, 94, 94, 30, 2, 2, 2, +176,106,213, 42,117,135, 14, 29,214, 16, 66,170, 83, 74,205,197,113, 2,152,113,243,230,205, 72,187,221, 14,133, 66, 81, 92,203, + 23,241,241,241, 24, 51,102, 12,186,116,233, 82,174,125,251,246, 51, 0,252, 88, 2, 39, 52, 26,205,252,195,135, 15, 71,104, 52, + 26,156, 59,119, 14,137,137,137, 24, 49, 98, 68, 5, 81, 20,113,253,250,117,156, 63,127, 30, 55,110,220,192,162, 69,139, 34,122, +246,236, 57, 31,192,250,146,252,238,196,192,119,222,121,167,122, 72, 72, 8,247,201, 39,159,228,228,231,231,127,229,188, 62,122, +214,172, 89,125,219,182,109, 27,254,218,107,175,129, 16,178,156, 82,122,139, 96,241,224,244,102,185,114, 0, 56,237,241, 90,188, +135,101,171,156, 51,241,101,123,225, 36, 0, 2, 59,119,238,252,142,217,108,110,180,123,247,238, 11,173, 90,181,170, 4,224,166, +148,232, 2, 3, 3,181, 51,102,204,136,236,218,181,235,217,199, 30,123,172, 81,231,206,157,223, 73, 75, 75,155,226,188, 79, 61, + 57, 69, 17, 71,203,149,175,187,114,231,190, 97,207,110,223, 99,145,191,251,191, 15,175, 85,172, 80, 57,231,232,185, 76,199,201, + 75,105,200, 51,218,209,235,177,194,141,197,155,215,173,136, 57, 43,118,227,205,183,222,151,253,184,114,241,211, 23, 40,180, 0, +126, 46, 33, 60,239, 8,140,243, 31,145, 33,138, 34,100, 50, 25,158,120,226, 9, 16, 66,110,217,107, 83, 38,147, 97,223,190,125, +120,236,177,199, 32,147,201,240,234,171,175,250,197, 41, 8, 2, 58,119,238, 12,187,221,126, 11,159,167, 88,240,166, 5, 60,253, + 78, 41,133, 32, 8,224, 56,206,171,248,241,182, 71,168,175,114, 73,114,103, 73, 92,238,247,124,185, 83,178, 30,249, 43,174,252, +229,148,220, 41, 8, 2, 90,182,108,137,191,254,250,171, 68,177,229, 77, 87,122,250, 61, 43, 43,235,229,234,213,171,239,252,226, +139, 47, 66, 0, 32, 35, 35,195,181, 17, 61,207,243, 56,115,230, 12, 44, 22, 11,198,143, 31,111,205,205,205,125,141,229, 35,198, +121, 55, 57, 75,210, 34, 0,218,142, 30, 61,186,201,180,105,211,166,180,104,209, 98,249,222,189,123,151, 17, 66, 54, 82, 74,187, + 74,191,163, 71,143,174, 51,109,218,180, 41, 9, 9, 9, 99,166, 78,157,122,130, 16,178, 17, 0, 60,207,157,238,239,234, 33,222, +194, 37, 30,167, 91,138, 60,235,237,220,243,215,147, 91,112,187, 64,156,158, 35,238,133,153,191, 2,203,159,189,245, 4, 65, 24, + 58,101,202,148,200,146,196, 85,126,126, 62,146,146,146, 80,169, 82, 37,188,250,234,171,145, 95,124,241,197, 80, 0,159,150, 64, + 43,231,121, 30, 7, 15, 30, 68,106,106, 42,234,213,171,135,216,216,216, 34, 15, 92,188,120, 17,191,252,242, 11,178,179,179,209, +184,113, 99,160,112,124,145, 87, 52,104,208, 96,124,124,124,124,231,206,157, 59,219,213,106, 53,142, 30, 61,138, 70,141, 26, 97, +197,138, 21,168, 88,177, 34, 52, 26, 13,206,158, 61,139,122,245,234, 97,199,142, 29, 8, 15, 15, 71,195,134, 13,237,141, 27, 55, +222,149,153,153,249,199,149, 43, 87,198, 23,147,112,228,209,209,209, 99,222,120,227, 13, 69, 82, 82,146,184,104,209,162,189,148, +210,189,132,144, 65,239,191,255,254, 75, 93,186,116, 9, 63,114,228, 72,238,159,127,254,249,167, 55,113,229,167,229,202,238, 89, + 25, 57, 28, 14,179,209,104,180,152,205,102, 27,199,113, 87, 8, 33, 22,135,195, 81, 92,223,142,234,149, 87, 94,169,146,158,158, +254,230, 91,111,189,117,217, 41,174,206,160,112, 96, 59, 0,192,110,183,155,243,243,243,115, 91,180,104, 81,169,111,223,190, 23, +150, 45, 91,246,230, 43,175,188,178,106,225,194,133,249, 0,140,158,132, 21, 43, 86,248,139,231, 57,121, 65, 94,200,165,213,171, +190,121,251,151, 13, 67, 43, 92,191,126,163, 90,104, 88,120,129, 92, 23,158,180,234,135,239, 15, 1,176, 36,165,229,226,216,197, +100,200,100, 60, 78, 93,207, 65,219,199,159,145, 93, 56, 55,185,181, 36,176, 24,238, 42,168,180, 57,244,246,237,219, 75,180, 96, +237,219,183, 15, 50,153, 12,106,181, 26, 51,103,206, 44,145, 84, 18, 4,146,117,200,151,136,225, 56,174,196,114, 68, 18, 25,210, + 6,236,158,199,151, 95,126,137,183,222,122,171,200, 55,156, 34,131,248,226, 44,206,125,149, 42, 87, 70,106, 74, 74,145,107,254, +108, 22,239,112, 56, 32,147,201,240,245,215, 95,163,107,215,174,216,184,113, 99,137,191, 79, 60,241, 4, 56,142,163,254,132,103, +203,150, 45, 97,181, 90, 93,110, 62,115,230,140, 87,222,121,243,230,249,170,204,186, 1,152,208,168, 81, 35,125,251,246,237,177, +115,231, 78, 60,253,244,211,102,171,213,122, 14, 0,158,122,234,169, 26, 95,124,241,133,226,240,225,195, 8, 13, 13,149, 93,187, +118,237, 59, 66, 8, 27,248,206,112,119, 11, 35, 47, 90, 68,170,243,166, 77,155, 54,197, 67, 24, 21,129,116,159, 16,178,113,234, +212,169, 93,221,197,144,251,185,155,149,201, 93,188,213,113,183, 64,185,139,167, 98, 68,153,167,187,221,159, 79, 43, 34,176,156, + 30,106,231,110,245,145, 10, 93, 95,226,170,184,150,162, 39, 2, 3, 3,159,236,213,171,151, 75,220,152, 76, 38,151,176,146,196, +149,116,126,246,236, 89, 52,105,210, 68, 30, 24, 24,248,164, 15,129, 37,137, 55, 68, 69, 69, 33, 61, 61, 29,199,143, 31, 71,165, + 74,149, 96,179,217,176,121,243,102,228,228,228, 64, 38,147, 65, 46,151,195,106, 45,121, 72, 66,124,124,252, 19, 75,150, 44,105, +178,120,241,226, 44,169, 5,247,195, 15, 63,128, 82,138,240,240,112, 24, 12, 6,164,164,164,224,143, 63,254,128,221,110,135, 78, +167, 67, 92, 92,156,162, 71,143, 30,173, 39, 76,152, 32, 3, 48,190, 24,234,102, 79, 63,253,180, 94,175,215,227,127,255,251, 31, +181, 90,173,159, 18, 66,154,247,238,221,123,204,176, 97,195, 66,174, 92,185, 98, 25, 56,112,224, 33,171,213, 58,195, 25, 31, 50, + 74,169,205, 71, 66, 44,214,114,101,179,217,164, 48,189,156,159,159,143,176,176,176, 74, 62,198,104, 1,128,124,207,158, 61, 45, + 1,240, 31,125,244,145, 10, 64,138,187,184,178, 88, 44,200,207,207, 71, 65, 65,129, 45, 39, 39, 39,117,228,200,145,246,101,203, +150,241,206,119, 78,121, 19, 88,192,227,150,218,181,181, 10, 74,249,247, 23, 44, 88,160,235,210,165, 11,167,211,233,144,151,151, +167,255,117,211, 38, 93,135,246,173,227,166, 76,251,120,139, 62,166, 94,202,158,163,151,112, 35, 57, 7, 22,155, 13,113,229, 3, + 11,237, 95, 12,119, 29,206, 9, 42, 46, 11,150,187,152,216,185,115, 39, 30,127,252,113, 87, 94,151,203,229, 69, 44, 93,190, 56, + 5, 65,192,227,143, 63,126,139, 69,103,251,246,237, 94,173, 77,190,224, 46,134, 60, 69,145, 55,225,197,113, 28,124,245, 50, 75, +214, 59,111, 34,203,221,138,239, 33,218,124, 85, 18, 16, 4, 1,195,134, 13,131, 76, 38,195,168, 81,163, 32, 8, 2, 26, 54,108, + 8, 65, 16,208,162, 69, 11,200,100, 50, 60,246,216, 99,165,246,251,254,253,251,209,168, 81, 35,151,155, 26, 54,108,136,166, 77, +155, 66, 16, 4,180,105,211, 6, 50,153, 12,157, 59,119,246,135,115, 76, 94, 94, 94,125,157, 78,135,179,103,207,130,231,121, 16, + 66,206, 83, 74,235, 3,192, 27,111,188,113,193, 96, 48, 84, 49,153, 76,120,227,141, 55,136,197, 98,169, 55,106,212,168,247, 1, + 48,129,197,112, 55,203,163, 34, 90,196, 13,198,132,132,132, 49,132,144,141,146, 69,202,211,210,228,237,220, 11,191, 36,130,164, +238,193,166, 30,226, 77,234, 58,124,170,132,119, 45, 30,130,202,179,139,240, 79,159, 22, 44,169,208,245, 87, 96,249,130,201,100, +106, 16, 17, 17, 81,172,184,114,255,181, 88, 44,136,141,141,133,201,100,106, 80,218,202,162,124,249,242,176, 90,173,248,230,155, +111, 32,151,203, 33,151,255,163, 43, 44,150,146,141, 67, 39, 79,158,188,188,127,255,254, 70,141, 27, 55, 14, 94,187,118,109,218, +163,143, 62, 26,222,165, 75, 23,168,213,106, 24,141, 70,216,108, 54, 52,111,222, 28,241,241,241, 72, 76, 76,196,175,191,254,154, + 94,189,122,245,176, 3, 7, 14,136,201,201,201, 87, 75,160,238,208,161, 67, 7, 16, 66,240,235,175,191,102, 80, 74, 15,171,213, +234,181, 83,166, 76, 9,178, 88, 44,226, 75, 47,189,116, 61, 51, 51,115, 36, 0,155, 82,169,252,180, 75,151, 46,205,120,158, 95, +225,112, 56,230,148, 54,129,122,134,109, 65, 65, 1, 84, 42,149, 63, 75, 66,200, 50, 51, 51,235, 2,128, 86,171, 13, 1,112,193, +149,178,141,198, 34, 34,216, 98,177,152, 66, 66, 66,180, 0,224,124, 71, 86, 76,124,132,107, 52,154,213, 87,175, 94, 10,112, 31, + 31, 23, 20, 20,132,126,125,251,114,173, 90,182, 84,212,111,208,160,243,216,207, 22,175,136, 10,213, 91,226,162, 66, 97,115,216, +176,109,203,102,145,138,182, 45,172,184,185, 55, 2, 75, 18, 25,158, 22, 44,153, 76,134, 29, 59,118,220,114, 77, 46,151,227,171, +175,190,242, 75, 16, 72, 98,170,184, 46, 50,143, 46, 45,226, 75,184,200,100, 50,240, 60,143,175,191,254, 26,162, 40,226,237,183, +223, 46,210,109,232,206,239,103,139,217,245, 78,252,135, 34, 0, 11, 18, 63, 87,186,222,247,116,175, 84, 94,250, 99, 21,251,226, +139, 47,252,178, 96, 61,245,212, 83, 62, 5,171,123,143,130,187,187,254,250,235, 47,175,188, 11, 22, 44,240, 25,158, 14,135, 3, + 63,255,252,179, 75,156, 74,248,224,131, 15,222,136,137,137,137,220,181,107, 23,146,147,147, 81, 80, 80,128,252,252,124, 52,111, +222, 60,174, 99,199,142, 71,147,147,147,175,156, 60,121,178, 23,203, 61, 12,247,208,130,101,158, 58,117,234,137,169, 83,167,122, +181, 80,121, 90,146, 74,178, 52,185, 9,171, 63,225,236, 26, 76, 72, 72, 24,131,194,225, 51,127,250,241,174,194,179,139,208,171, +225,199, 67, 53, 78,240, 86,232,250,211, 77,232,167,217, 92, 32,132,192,100, 50,121, 21, 86,238,162,192,106,181, 34, 51, 51, 19, + 14,135, 67,184,131,136,186,229,154, 47,129,117,252,248,241,254, 3, 6, 12, 72, 10, 12, 12,172,159,150,150,150, 42,138,226, 99, +251,246,237, 11, 23, 4, 1,122,189, 30,122,189, 30,191,252,242, 11, 52, 26, 13,134, 13, 27,150,234,112, 56,118, 6, 4, 4,132, + 26,141,198,191,147,147,147,199, 22,171, 92,100,178, 14,109,219,182,197,225,195,135,145,157,157,253, 59, 33,164,254,107,175,189, +214,169, 66,133, 10,100,242,228,201,166, 11, 23, 46,124, 9, 32, 77,171,213,126,179,100,201,146, 71, 27, 55,110,172,123,241,197, + 23, 65, 8,249,150, 82,106,242,215,207, 5, 5, 5, 69,132, 85,110,110, 46,242,242,242,160,213,106,237,126,134,153, 12,133, 99, +169,164,241, 84,174,184,113, 90,175,164,248,161,130, 32,208,194, 71,168,172, 56, 62,173, 86,251,209,226,197,139,213,158,147, 15, + 28, 14, 7, 82, 82, 82,160,215,235,241,193,216,177,242,137, 35, 94,107,196,235, 34,247,113, 28,129,197, 74,179,169,104,217, 92, +144,242,220, 46, 86,220,220, 27, 72,130,160,123,247,238,183,116, 11,202,229,114,108,221,186, 21, 61,123,246,116, 53, 88, 26, 55, +110,236,179, 81, 37, 9,130,110,221,186,185, 44, 65,155, 55,111,246,218,189, 39, 89,160,252, 17,130,210,179,195,135, 15,135, 32, + 8,152, 51,103, 14,222,121,231, 29,112, 28,135,207, 63,255, 28, 28,199, 97,220,184,113,126,139, 75,119,225,114,229,227,194,223, +152,119,114,145, 49, 47, 18, 0, 16,160,215, 75, 30, 42, 85,217, 35, 8,130,203,114,213,160, 65, 3,200,100, 50,180,104,209, 2, +130, 32,184, 44, 87, 79, 62,249,164,123, 56, 82,127, 56, 5, 65,192,185,115,231, 92,110,110,209,162, 69, 17,203,149, 32, 8,120, +234,169,167,252,113,230,148,160,160,160, 9,241,241,241,181,102,204,152, 33,227,121, 30, 29, 58,116,168, 49,112,224,192,171,161, +161,161,161, 31,125,244,145,198,203, 59,106, 0,245,107,213,170,165,101,185,134,225, 46, 90,176, 38,120,185, 21,236, 62,166,170, + 20,124, 27,221,159,151, 56, 60, 69,145,211, 34,182,211, 23,151,183,119,139,131, 80, 82,107,172, 52, 2,203,105, 94, 46,241, 99, + 26,141,230, 88,106,106,106, 11,181, 90, 93, 68, 92,121, 19, 90, 60,207, 35, 57, 57, 25, 26,141,230, 88, 89, 70,158,175, 46, 66, +167,152, 25,225, 22,160, 29,159,124,242,201,133, 91,183,110, 45,191,109,219, 54, 28, 56,112, 0,225,225,225,248,226,139, 47,110, +166,164,164,244,167,148,110,245,231,187, 85,170, 84,169,173,213,106,177,119,239, 94, 0,216, 5,224,149, 55,223,124,147,216,237, +118,204,157, 59,215, 0, 96,107, 96, 96,224,143,107,214,172,105, 80,175, 94, 61,197,182,109,219,242, 14, 28, 56,176,221, 79,113, +229, 16, 69,241, 22, 97,229, 30,166, 1, 1, 1,254, 88,176,108,129,129,129,199,115,115,115,159, 49, 26,141,185, 74,165, 50, 32, + 55, 55,215,236, 46,172, 36,126, 65, 16,100,231,206,157, 75, 2, 16, 23, 24, 24,120, 28,110, 93,137, 69, 18,152, 32,116,232,208, +161,131,224, 25, 7, 41, 41, 41, 72, 78, 78,134,213,106, 69,227,198,141, 9, 79,108,124,230,181,191,223, 96,197,203,253, 41,208, +164,188, 46,205,250,243, 54,115,112,243,230,205,174,115,142,227,224,156,182,239, 83, 12,109,221,186,181,196,129,232, 30, 93,132, + 62, 77,225,210,243,115,231,206, 45,220,142,194,105,185,226, 56, 14, 9, 9, 9, 80, 42,149,152, 60,121, 50, 18, 18, 18, 32, 8, +130,207, 46, 66,119,225, 82,121,148,193,189, 81, 84,152, 41,156,227,157, 8, 33,238, 34,139,248, 43,218, 74,178,222,249, 99,249, +119,231,148,222, 83,169, 84,197, 14,112,247,224, 36, 37,248,251, 39, 66,200,165,242,229,203,239,105,209,162, 69,224,161, 67,135, +240,249,231,159,203,205,102,115,197,109,219,182,185,190,235, 45,188, 10, 10, 10,212, 44,231, 48,220, 13,235, 85, 9,183,211, 60, +198, 79, 17,247,238,186, 18,126, 61,159,135,219, 53,119,222, 52,143,122,204,253,186,167,168,242,252,134,251, 51,105,183, 88,176, +124, 21, 18,190,132,150, 63, 22, 44,131,193,240,219,166, 77,155,154,246,237,219, 87, 40,169,123,176,160,160, 0,145,145,145, 56, +113,226,132,221, 96, 48,252,230,135,101,172,204, 4,150,151, 8,223, 86,174, 92, 57,222,102,179,161, 90,181,106,136,142,142,134, +201,100, 66,118,118, 54,239,175,184, 34,132,200,155, 52,105,194, 3, 64, 86, 86, 22, 80, 56,157,180,122,245,234,213,113,248,240, + 97,100,101,101,173, 7,208,113,226,196,137, 13,155, 53,107, 38, 95,177, 98,133, 97,240,224,193,235,109, 54,219,100, 63,173, 15, + 22,187,221, 30,203,113,156, 53, 59, 59,251,134,123,120, 70, 70, 70,134,104,181, 90,146,146,146, 98,243, 71, 96,213,175, 95,255, +224,181,107,215,240,209, 71, 31,165, 77,153, 50,165,122, 94, 94, 94, 86, 78, 78,142,221, 93,100,153, 76, 38, 46, 44, 44, 76, 57, +111,222, 60, 53, 0,212,175, 95,255, 96,113, 2,171,160,160,160,130, 70,243, 79, 67,216,108, 54, 35, 57, 57, 25,201,201,201, 72, + 73, 73, 65, 94, 94, 30,226,226,226, 96, 48, 24, 42,177,226,229,190, 9,172, 34,221,100,238,249,219,189, 2, 47, 77, 94,119, 23, + 46,221,187,119,119,141,221,146, 44, 98,210,177,122,245,106,207,129,227,126, 9,172,185,115,231, 98,248,240,225, 80,169, 84,152, + 49, 99, 70,145, 46, 66, 79, 81, 32,138, 34,241,199,239,177,239, 25,145, 60, 59, 4, 50,153, 12,161,131, 83,138,116,197,121, 17, + 26,126,185,115,202,148, 41,101,210, 69,232,206, 89,169, 82, 97, 86,249,250,235,175,241,204, 51,207, 96,215,174, 93,183,221, 69, + 88,167, 78,157, 31, 54,110,220, 24,120,242,228, 73,228,230,230, 34, 45, 45, 13,102,179, 25,137,137,137,197,246, 2, 56,203,114, + 21,203, 57, 12,247, 24,127,222, 99,222, 59,254,158,224,163,226,246, 91, 96,249, 99,193, 50,155,205, 51,254,247,191,255,189,217, +177, 99,199,144,128,128, 0, 36, 37, 37,221, 34,174,242,243,243,161,211,233, 96, 52, 26,177, 97,195,134, 92,179,217, 60,195,151, + 40,176,217,108,136,136,136, 64,122,122, 58,196, 98,198, 69,115, 28, 7,181, 90,141,252,252,124, 20, 39, 6, 74,170, 40,172, 86, + 43,108, 54, 27,108, 54, 27,172, 86, 43, 74,185, 60,147, 90, 90,176,181,160,160, 0, 0, 10,162,162,162,170,168, 84, 42, 92,190, +124, 25, 0,206, 1,104,223,165, 75, 23, 89, 70, 70, 6, 29, 56,112,224, 62, 74,233, 48, 31,171,217, 91,118,238,220, 25, 11, 0, +106,181,250, 44, 0, 36, 38, 38,218,178,179,179,139, 88, 6, 53, 26, 13,237,217,179,103,121, 74, 41,118,238,220, 25, 43,151,203, + 41,138, 89,179, 10,128,105,253,250,245, 39, 3, 3, 3,151, 77,155, 54,173,111,215,174, 93, 79,212,173, 91, 55,182,160,160, 32, +213,104, 52, 26, 77, 38, 19,229,121, 94, 30, 28, 28,172,218,178,101,203,133,125,251,246,117,212,235,245,203,214,175, 95,127, 18, +128, 87, 75,155, 86,171, 77, 52, 24, 12,149,165, 56,117, 23, 87,201,201,201,160,148,226,210,165, 75,208,104, 52,215, 88,249,113, + 95, 91,142,183, 8, 43,111, 98,203, 95,113,229, 46, 8,182,108,217, 82,226, 26, 88,254,114,186,139,161,119,222,121, 7,179,103, +207,190,197,130, 53,121,114, 97,155,100,236,216,177,126,143,193,146,172, 85,201,179, 67, 80,110,120,102, 17,183, 3, 0,145,220, + 87,202, 37,217, 4, 65,192, 71, 31,125,116,203,224,115,247, 46, 60, 63,187,242,138,184, 51, 53, 53, 21,130, 32, 32, 36, 36, 4, +253,250,245, 67,231,206,157, 93, 93,141,165,229, 61,125,250,244,158,247,222,123,175, 94,157, 58,117, 48,105,210,164,204,160,160, +160,128,215, 95,127, 93,200,206,206, 38, 37, 89,176,152,192, 98, 96,184, 3,129, 37,101, 44,127,103, 17,122, 43, 36, 9, 33, 29, +221,215,202,160,148,230, 16, 66,250,117,234,212,105,237,202,149, 43,213, 85,170, 84,193,233,211,167,145,153,153, 9,139,197, 2, +185, 92,142,242,229,203, 35, 59, 59, 27,223,127,255,189,209, 96, 48,244,163,148,230,148,196, 9,224,253, 38, 77,154,204,255,244, +211, 79, 85, 13, 27, 54, 68,102,102, 38,242,243,243,139,172, 58,173,215,235,161, 86,171,113,240,224, 65,108,222,188,217, 8,224, +125, 31,156,222, 84, 28,172, 86,171, 75,104,249, 18, 88, 30,156, 90,201,138, 99, 48, 24, 0,192, 94,177, 98,197, 72, 0,184,116, +233, 18, 0, 92,141,139,139, 27, 91,181,106, 85,178,100,201, 18, 74, 41,221,230, 77, 92,121,112,102,182,105,211, 38, 11, 64, 57, +139,197, 34, 7,128,156,156, 28,107, 88, 88, 88,132, 82,169, 20,213,106,181,168, 82,169,196,164,164, 36,187,221,110,151, 3, 64, +155, 54,109, 44, 0,146,225, 54,214,195,131, 83, 4,144,187, 96,193,130, 9, 47,190,248, 98,139,150, 45, 91,214, 25, 50,100,200, +241,129, 3, 7,114,209,209,209,193,121,121,121,166,243,231,207,103,125,246,217,103,121,251,247,239,239, 40,147,201,174, 46, 88, +176, 96, 2,128, 92,231,187,183,112,218,237,246,223,182,109,219,214,191,107,215,174,194,141, 27, 55,144,146,146,226, 18, 87, 41, + 41, 41,136,143,143,199,190,125,251, 28, 86,171,117, 91, 41,194,179,172, 44, 55,140,179,176,241, 65,165,188, 94,156,176,146, 26, + 81,254,114,186,139,161,103,158,121,166,136,213, 74, 46,151, 99,205,154, 53, 94,203, 13, 47, 43,146,119,244, 92, 15, 74,114,211, +123,239,189, 87, 68,172,125,240,193, 7,197, 58,205, 87,120, 74, 60, 57, 95, 71, 23,157, 69, 88, 76, 62, 47,201,157, 82,217, 41, +147,201,240,193, 7, 31,248,109,193,130,199, 24, 44,111,156,146,223, 31,125,244, 81, 24, 12, 6,151,128, 45,206,130,229, 43, 60, + 29, 14,199,240,217,179,103, 83,189, 94,223, 44, 55, 55,247,133,107,215,174, 45, 50, 24, 12,143,228,228,228,148,104,193, 50,155, +205, 74,150,143, 24,231,221, 88, 11,235, 63, 33,176,156,149, 35, 42, 84,168, 80,100,111, 43,142,227,138, 28,165, 25, 71,224,204, +176, 91, 8, 33,189, 91,181,106,181,116,248,240,225, 1, 13, 27, 54,148, 85,174, 92, 25, 5, 5, 5,184,124,249, 50, 78,156, 56, + 97, 95,191,126,125,174,193, 96,120,129, 82,186,197, 15,190,197,132,144,205, 93,186,116, 25,215,188,121,243, 65, 31,126,248, 33, + 95,163, 70, 13,228,228,228, 32, 56, 56, 24, 17, 17, 17, 56,115,230, 12, 54,108,216,224, 72, 79, 79,159, 15, 96, 34,165, 52,173, +180, 13,124,171,213,138,231,159,127, 30,162, 40, 98,230,204,153,238, 11,162,249, 3,171,213,106,165, 0, 72,122,122, 58, 0, 24, + 36,193,117,254,252,121, 0,184, 86,185,114,101, 29, 0,108,219,182,141, 0,216,235,175,187,220, 45, 89,241,241,241,151, 61, 11, + 69,201,114, 37, 89,189,224,123,131,102,211,179,207, 62,155,106, 48, 24,186,188,243,206, 59,227,230,206,157,219,119,238,220,185, +183, 60,164,215,235,151,125,254,249,231, 19,159,125,246,217,212,226,172, 87, 78,139,221,216,151, 95,126,249,217, 99,199,142, 5, +168, 84, 42, 20, 20, 20, 32, 35, 35, 3, 86,171, 21,113,113,113, 72, 77, 77,197,226,197,139,243,140, 70,227,120,150, 29,239, 15, +220, 5, 65,113, 86, 44, 95,226,170, 36, 43,206, 79, 63,253,228,117,141,169,210,114,122,138, 12,127,215,166, 42,169, 49, 36, 45, + 47,227,109,233,135,210,148,107,222,120, 5, 65,192, 39,159,124,226, 90,108,213,155,229,170, 52, 22, 44,137, 51, 36, 36, 4, 0, + 32,109,109,244,212, 83, 79,221, 54,175,115,219,176, 97,110,223,152, 50,114,228,200, 9,241,241,241, 53, 0, 40,221,195,128,109, +170,192,192, 80, 70, 2,203,225,112, 36,214,172, 89,179, 72,193,230,107,147, 81,155,205,150,232,103,166,222, 76, 8,137,251,252, +243,207,255,167,213,106, 59, 26, 12,134,122,206, 2,227, 88, 65, 65,193, 54,179,217, 60,171, 52,155, 51, 59, 5,211, 80, 66,200, +204, 46, 93,186, 76,126,236,177,199,250,140, 24, 49,130, 80, 74, 49,111,222, 60,122,241,226,197,213, 0,222,167,148, 94,188,157, + 64, 10, 9, 9, 57,249,253,247,223, 71,174, 93,187, 22, 54,155, 13,179,102,205, 66, 64, 64,192,201,210,184, 79, 16,132,165, 45, + 91,182,236,187,111,223,190,101,148,210,227, 74,165,242,135, 54,109,218,244,219,187,119,239, 74, 74,233, 41, 65, 16,126,104,209, +162, 69,191,131, 7, 15,254, 72, 41,253,187, 20,206,115, 89,178,236,118,239, 61,138,222, 44, 87, 62,144, 59, 96,192, 0,235,128, + 1, 3, 70, 60,251,236,179,223,252,249,231,159,143,100,103,103,215, 3,128,160,160,160, 99, 77,155, 54, 61,184,114,229,202, 51, + 78,203,149,201,151,223, 9, 33, 61,235,213,171,247,227,164, 73,147,180,117,234,212, 17,170, 85,171,134, 43, 87,174,224,248,241, +227,246,239,190,251, 46,223,104, 52,118,167,148,102,177,236,120,255, 4, 22,165, 20, 65, 65, 65, 69, 26, 79,210,212,253,210,118, + 11,186, 87,200,210,150, 58,158,188,197,113,250, 24,228, 10, 0,208,233,116,174, 69, 73,253, 25,154, 32,138, 37,175,167, 70, 41, +117,113, 74,135, 31,226,202,231,140, 63,231, 86, 53,126,115,250,179, 76,131, 86,171,133,205,102,115,241,250, 49,147,147,148, 50, +206,126, 2,240, 83,181,106,213,206, 3,168,202, 68, 21, 3,195, 93, 16, 88,153,153,153, 77,238,230,135,157, 2,106,162,243, 40, + 43,206,139, 0,158, 37,132,124,250,251,239,191, 75,253, 5, 31,249,218,207,208, 23, 78,159, 62,221, 85, 38,147,125,181,108,217, +178,230,148, 82, 4, 6, 6,238,191,114,229,202,235,165,225,176,219,237,131, 8, 33,111, 75,179, 2,205,102,243, 32, 66,200,187, +148,210, 2,183,251,174,243,210,122, 29,128,153, 82, 26, 85,204,125,115, 41,196,149,203,146, 5,192,178,114,229,202,124, 0, 71, +241,207, 58, 87, 54,231, 97,130, 91,183,160,143,120,249,131, 16, 82,237,131, 15, 62,152,194,243,124,135,130,130,130,104,173, 86, +123,221,110,183,255,102, 48, 24,222,167,148,102,176,172,120,255, 96,177, 88,110,212,172, 89, 83,240,214,112, 42,169, 2, 47,169, + 65,229,112, 56, 18,171, 87,175,238,179, 81,230,133,243, 70, 9,233,232,106, 92, 92, 28,231, 47,151, 4,171,213,154, 90,146, 59, +227,226,226, 80, 90, 78, 95,126,143,141,141,245,234,119, 31, 66,240, 70, 9,229,199,109,113,150, 20,158, 37,193,104, 52,102,133, +135,135,231,155, 76, 38,153,217,108,150,217,237,246, 34,230, 70,181, 90,157,198,114, 14, 3,195,109, 10,172,127, 51,156,130,170, + 91, 25,242,153, 1,188, 84, 6, 60, 38,143,243,130,146,206, 75,137,187, 97, 1, 18, 1, 24,202, 40, 12,211, 1, 12,100, 89,238, +193, 67,122,122,122,179,178,230,204,200,200, 40,243, 6, 90, 90, 90, 90,139,187,224,247, 38,255, 85,206,146,112,227,198,141,102, + 44,103, 48, 48,220, 25, 56, 22, 4, 12, 12, 12, 12, 12, 12, 12, 12,101, 11, 2,160,163,183, 27,165,153, 29, 64, 8,233, 88,218, + 15,251,226,103,156,140,147,113, 50, 78,198,201, 56, 25,231,195,199,233,139,251,161,153,157, 72, 41,189,107, 7,128,142,140,147, +113, 50, 78,198,201, 56, 25, 39,227,100,156,255,181,131,117, 17, 50, 48, 48, 48, 48, 48, 48, 48,148, 49,152,192, 98, 96, 96, 96, + 96, 96, 96, 96, 96, 2,139,129,129,129,129,129,129,129,129, 9, 44, 6, 6, 6, 6, 6, 6,134,255, 24, 8, 33,117, 9, 33,245, +254,171,254, 23, 88, 18, 96, 96, 96, 96, 96, 96, 96, 40, 35, 81,165, 4,240, 12, 33,228,205,186,117,235, 54,117,110,200,190,159, + 82, 58, 19,192, 90,111,251,236, 62,180, 97,225,182, 41,242, 14, 0,160,148, 62,202,146, 8, 3, 3, 3, 3, 3, 3, 67, 41,132, + 85,101, 0,131,116, 58,221,107,237,218,181, 11,238,222,189, 59, 66, 67, 67, 97,183,219,113,253,250,117,108,220,184, 17,123,247, +238, 77,178, 88, 44,179, 1,124, 77, 41,205, 46,134,231,161,209, 34,132, 82, 42,109, 92,220,206,233,169, 29, 44,169, 48, 48, 48, + 48, 48, 48, 48,248, 41,174, 18,122,247,238, 61, 57, 50, 50,146,171, 91,183, 46,202,151, 47, 15,179,217, 12,163,209, 8, 74, 41, + 4, 65, 0,165, 20, 57, 57, 57,216,185,115, 39,254,248,227, 15,115, 86, 86,214,247, 0,102, 81, 74,207,185,241, 60, 84, 90,196, + 37,176, 74,187, 41, 40, 3, 3, 3, 3, 3, 3, 3, 3, 33,228,236,233,211,167,171, 59, 28, 14,164,167,167,195,108, 54,195, 96, + 48,184, 4, 22,207,243,160,148,194,110, 47,236, 29, 20, 69, 17,135, 15, 31,198,182,109,219,232,165, 75,151, 62,164,148,126, 36, + 9,172,135, 73,139,176, 65,238, 12, 12, 12, 12, 12, 12, 12,119, 4,139,197,130, 37, 75,150, 32, 61, 61, 29, 21, 42, 84, 64,116, +116, 52,130,130,130,160, 86,171, 1,192, 37,174, 0,128,227, 56, 52,109,218, 20, 67,135, 14, 37, 0,250, 61,172, 97, 34, 13,114, +159,192,198, 96, 49, 48, 48, 48, 48, 48, 48,220, 6,108, 22,139, 5, 77,154, 52,193,229,203,151,113,248,240, 97, 52,106,212, 8, +181,106,213, 66,122,122, 58,146,146,146,138, 60,124,240,224, 65, 28, 57,114, 4,109,219,182,245,228,153,240,208,141,193, 2, 0, + 66,200,163, 78, 79,237, 96,105,133,129,129,129,129,129,129,193, 47, 33, 65, 72,207,168,168,168,239,222,124,243,205,192,230,205, +155, 35, 49, 49, 17, 55,110,220, 64, 86, 86, 22, 26, 54,108,136, 58,117,234,224,226,197,139,216,188,121, 51,142, 28, 57, 2,165, + 82,137,152,152, 24,232,150, 45,199, 87, 4, 39, 41,165,117,220,184, 30, 26, 45,226, 18, 88, 12, 12, 12, 12, 12, 12, 12, 12,183, + 41,178, 2, 0,140,140,139,139,123,119,240,224,193,202,218,181,107, 35, 49, 49, 17,105,105,105,200,202,202,194,254,253,251, 1, + 0,209,209,209,136,142,142,198,153, 51,103,176,103,207,158,220,252,252,252, 1,148,210,181, 15,101,152, 48,129,197,192,192,192, +192,192,192, 80, 70, 66, 43, 2,192,216,218,181,107, 15,122,237,181,215,132, 74,149, 42,225,198,141, 27,248,253,247,223, 81,181, +106, 85, 92,191,126, 29,127,252,241,135, 37, 45, 45,109, 38,128,105,148,210,156,135, 53, 44,184,187, 28,208, 29, 25, 39,227,100, +156,140,147,113, 50, 78,198,249,223,224,164,148,166, 82, 74,135,157, 60,121,178,218, 91,111,189,181,116,210,164, 73,162, 40,138, +136,136,136,192,170, 85,171,196, 21, 43, 86,124,151,150,150, 86,133, 82,154,240, 48,139, 43,128,173,228,206,192,192,192,192,192, +192, 80,198,160,148, 94, 1,240, 34, 33,228,227,195,135, 15,191, 15,128, 2,152, 68, 41, 61,245, 95, 9, 3, 38,176, 24, 24, 24, + 24, 24, 24, 24,238,150,208, 58, 1,224,185,255,162,223,217, 58, 88, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, 48, 48, 48, + 48, 48, 48, 48,129,197,192,192,192,192,192,192,192,240,159, 2, 1, 80,220, 76,128,109,126,147,220,198, 12, 5, 95,252,140,147, +113, 50, 78,198,201, 56, 25, 39,227,124,248, 56,125,113,151, 70,127, 60,208,160,148,250, 60,224, 92, 47,171,180, 7,128,142,183, +243, 30,227,100,156,140,147,113, 50,206,127, 47,167,179,241, 78, 80,216, 75,194, 73,231, 15,178,223,111,167,158,187, 87,126,255, +175,112, 62,108,135,224, 67, 93,186, 2,137, 16, 34, 2, 16,105, 25,172, 76, 74, 8,145, 34,160, 76,248, 24,238,130,105,179, 48, +142,200, 63, 58,156,197, 19, 3, 3, 67,169,202, 14,222,173,146,117, 0,112, 16, 66,240,160,149, 37,101, 89,207,221, 13,191,255, +151, 57,255,237, 16, 74, 10, 40,158,231,183,132,133,133,181, 79, 79, 79, 23,157,215,161, 80, 40,192,113, 28,100, 50,153, 49, 47, + 47, 79,127, 27,145,240,109,100,100,228, 43, 25, 25, 25, 34,199,113, 80,169, 84, 32,132,184, 56,179,179,179,245,247, 59, 80, 42, + 87,174,156,101, 52, 26,117,158,215, 85, 42,149,233,234,213,171, 1,255,133, 2, 82, 46,151,247, 14, 9, 9, 9, 74, 75, 75,163, + 28,199, 65, 46,151,131,231,121, 56,255,219,179,179,179, 23,250,203, 23, 18, 18,114, 48, 36, 36, 36, 72,122,159, 16,130,140,140, +140,236,148,148,148, 71, 0, 64,173, 86,239,209,106,181,161,130, 32,128,231,121,240, 60, 15,131,193,144,145,158,158,222,138, 85, + 87,255, 78,172, 94,189,154,239, 18,253,106, 85,129, 26,235,115, 28, 13, 20, 69,146, 99, 39,234,191, 55,223,248,246,130, 63,239, +247,233,211,199,113,159,243, 64, 69, 0,118, 74,105, 82, 25,241, 61, 1,224,121,231,169, 9, 64, 58,128,243, 0, 86, 83, 74,141, +247, 59,190,148, 74,229,204,200,200,200,215,242,243,243, 13,132, 16, 74, 8, 65, 97, 53,128, 91,126, 29, 14, 71, 98,122,122,122, + 19, 31,149,172, 76,161, 80,124, 30, 25, 25,249,114, 65, 65,129,193,201, 71, 9, 33,136,140,140,188,133,211,110,183, 39,166,165, +165, 53,241,199,173, 17, 17, 17, 11, 52, 26,205, 11, 6,131,161,192, 41,136, 92,189, 49, 40, 92,107, 73,194,197,212,212,212, 54, +190, 4,129, 66,161,152, 21, 25, 25,217,223,233,119, 16, 66,104,120,120,248, 93,241,123, 68, 68,132, 87,206,226,252,238,141,211, +221,157,132, 16,132,135,135,223,177, 59, 31, 68,206,135, 86, 96, 1,224, 8, 33,235, 91,181,106,213,110,199,142, 29,220,233,211, +167,185,248,248,120, 56, 28, 14,136, 98, 97,122,142,137,137,209,220, 70, 33,179,168, 77,155, 54,207,239,220,185,147, 91,191,126, + 61,215,180,105, 83, 16, 66,224,112, 56,224,112, 56, 80,183,110, 93,245, 29, 22, 98, 58, 65, 16,222, 86, 40, 20,143,218,237,246, + 90, 0, 32,147,201, 78,153,205,230, 29,118,187,125, 6,165, 52,223, 31, 30,171,213,170, 73, 77, 77,189, 37,108,226,226,226, 20, +183,235, 54,189, 94,191,151,227,184, 56, 87, 0, 59,133,134,183, 76, 44,253, 82, 74, 47,165,165,165,181, 44,142, 51, 56, 56,216, +197, 89, 28,135,231, 53, 81, 20, 47,165,166,166,182,244, 33,174,158,110,211,166, 77,224,182,109,219,200,245,235,215,137, 90,173, +134, 40,138,112, 56, 28,176,217,108,168, 93,187,118,169,214, 79, 11, 10, 10,210, 39, 36, 36, 84,125,226,137, 39,176,102,205, 26, +188,244,210, 75,104,221,186,245, 57,233,190, 86,171, 13, 61,121,242,100,245,144,144, 16, 24, 12, 6,228,228,228,160, 83,167, 78, +255,250,204,213,188, 81,133, 73,132, 35, 33,174, 10,192,238,200,220,127,244,198,216, 59,229, 13, 10, 10, 58,162, 80, 40, 34,165, +120,229, 56,206,107, 92,187, 95, 51,153, 76, 41,233,233,233,141,124,228,159,202, 0,186,241, 60, 95, 77, 16,132,154, 0, 42,219, +237,246, 72, 0,144,203,229, 41, 60,207, 95,177,217,108,103, 44, 22,203,121, 0, 63, 57, 23, 18,244,138, 46,209,175, 86, 37,118, + 67,159, 60,179,248,164,166,202,180, 26,134,139, 9,103, 53, 74,195, 47, 93,162, 95, 93,237,175,200,186,143,226, 42, 54, 42, 42, +234, 19,231,255,145,148,210,203,101, 64,251, 60,165, 52, 16, 0,114,114,114, 2,175, 95,191, 94,238,167,159,126,170, 59,101,202, +148,199, 8, 33,211,125, 45,190,216,162, 73,197, 67, 28,199,197, 72,242, 65,164,142,196,125,135,174,151, 73,197,196,243,252,172, + 94,189,122,245, 95,189,122,181,230,240,225,195,154, 90,181,106,185,202, 39, 81, 20,225,105,120,136,141,141, 45, 49,248, 0, 8, + 28,199,205,236,213,171, 87,223,101,203,150,105,206,156, 57,163,137,141,141, 45, 82,230, 73,233, 82,186, 22, 21, 21,229,151, 91, +195,195,195,191,125,252,241,199, 95, 92,180,104,145,108,243,230,205,234,136,136, 8,132,132,132, 64,161,184,181,104,110,220,184, +177,232,131,142,227, 56,110, 86,143, 30, 61, 94, 92,177, 98,133,230,192,129, 3,154,186,117,235,130,231,249, 59,246,123,207,158, + 61,251, 46, 95,190, 92,115,236,216, 49, 77,181,106,213,192,113, 28, 56,142,187,133,143,227, 56, 84,168, 80,193, 47,206,238,221, +187,247, 93,185,114,165,230,200,145, 35,154,154, 53,107,186,194,206,173,123,174,212,238,124,192, 57, 31, 62,129,229, 52,151, 46, +105,213,170, 85,151, 29, 59,118,240, 0,112,228,200, 17,100,102,102, 34, 58, 58, 26, 58,157, 14, 74,165, 18, 38,147,137,150,178, +208,250,214, 41,174,100, 0,240,227, 11, 61,113, 73, 6, 12, 75,181, 64, 46,151,227,226,197,139,224,121,158,222, 65,161,216, 86, +175,215, 47, 94,187,118,109,112,163, 70,141,184,244,244,116,196,198,198, 34, 51, 51,243,145,157, 59,119, 54,126,245,213, 87, 95, + 37,132,188, 68, 41,221,233, 47,231, 47,191,252, 2,173, 86, 11,141, 70, 3,173, 86, 11,139,197, 66,110, 59,160, 5, 33,230,202, +149, 43, 17, 58,157, 14,162, 40,186, 14,143,254,107, 23, 68, 81, 68,245,234,213,173, 62, 10,198,152,171, 87,175, 70,168,213,106, + 80, 74,139,240, 57, 28, 14, 40,149, 74,247,150, 2, 28, 14, 7,226,226,226,172,190, 44, 87,146,184, 2,128,101,203,150,161, 92, +185,114,136,136,136,128, 86,171,133, 90,173, 46, 82,161,251, 89,128,163, 75,151, 46, 24, 63,126, 60,166, 77,155,134,145, 35, 71, + 22, 41,104,101, 50, 25, 66, 66, 66,176,105,211, 38,232,245,122, 84,170, 84, 9, 50,153,236,223,111, 9,228, 72,200,190, 67,215, + 92, 22,217,199, 31,139, 23,154, 55,174, 52,215, 25,195,224, 56, 64, 20, 11,171, 76, 66, 64,237, 54, 49,235,207,191,111,140,243, + 35, 60,163,174, 94,189, 26,161, 84, 42,253,114,135,195,225, 64,116,116, 52,239, 35,255, 60, 89,167, 78,157, 31,135, 12, 25, 34, +175, 86,173, 26,145,203,229, 16, 4, 1,130, 32, 72,233,177, 18,165,180,146, 40,138,237, 82, 82, 82,232, 23, 95,124,241, 49, 33, +164, 23,165,244, 23,175,233,157, 26,235,231,153,197, 39,119,253,133, 71,250,116,124, 15,155, 86, 37, 60,210,166,161,136, 0,141, +241, 2,128, 7, 86, 96, 17, 66,244,106,181,250,131, 85,171, 86,201, 1,160, 99,199,142, 31, 16, 66,222,162,148,230,150,213, 55, + 2, 3, 3, 17, 24, 24,136,186,117,235,162,119,239,222, 65, 13, 27, 54, 28, 73, 8,121,157, 82,106, 45, 94, 9,240, 49,123, 14, + 94,142,144,206,187,119,169, 39,111,217,180, 82, 74, 97, 67,204,243,105, 10,209, 33, 38, 30,248, 43,177,137, 31,254,253,184,119, +239,222,253, 86,175, 94,173, 3,128,121,243,230,161,119,239,222, 8, 9, 9,129, 70,163,129, 92, 46,135, 76, 38, 43,242,235,195, + 34,196, 3,248,248,233,167,159,238,179,108,217,178, 0, 0, 88,180,104, 17,186,118,237,138,208,208, 80,232,245,122, 40,149, 74, + 40, 20, 10,200,229,242, 34,229,128, 63,226,170,101,147, 38, 3, 22, 45, 90, 4, 0, 24, 61,108, 24, 58, 54,110, 12,157, 70, 13, +141, 90, 1, 41, 44, 20,188, 12,189,223, 75,240,229,111, 14,192,167,189,123,247,126,118,197,138, 21, 1, 0,112,248,240, 97,164, +166,166, 34, 50, 50, 18,106,181, 26, 10,133,194,229,103, 66, 8,212,106,181, 95,126,239,221,187,119,159,229,203,151,187,252,222, +165, 75, 23,132,134,134, 34, 32, 32, 0, 74,165, 18,114,185,188,200, 81, 92, 24,184,115,246,234,213,171,207,202,149, 43, 3, 0, + 96,225,194,133,232,216,177, 35,130,131,131, 17, 16, 16,224, 10,203,210,198,209,131,204,249, 80, 10, 44,105,108, 84,100,100,228, +179,187,118,237,226,220,196, 1,148, 74,165, 43, 99, 72,221,132,165, 40,180, 72,100,100,228, 43, 59,119,238,116,189,100,161,183, +152,168, 75, 93,113,187,241,119,108,223,190,253,242,141, 27, 55,170,228,114, 57,140, 70, 35, 78,156, 56,129,192,192, 64, 40, 20, + 10,244,232,209,131,111,213,170, 85,104,187,118,237,214, 16, 66,250,250, 51, 67,129, 82, 10,157, 78, 87, 68, 96,221,105, 23,178, + 90,173,198,134, 13, 27,192,243,188,215,130,203,253,127, 68, 68,132, 63,254,134, 82,169,196,222,189,123,193,243, 60,100, 50, 25, + 4, 65,128, 76, 38,195,207, 63,255,140, 17, 35, 70, 32, 61, 61, 29,132, 16,200,100, 50, 4, 4,248,236,221, 36, 33, 33, 33, 65, +146,184,146,196,143, 90,173,134, 76, 38, 35,130, 32, 16,169, 11,143, 16, 66,252,237, 83,231, 56, 14, 75,151, 46,197,244,233,211, + 49,106,212, 40, 44, 88,176, 0,245,235,215,119, 23,159,200,205,205, 69,112,112, 48,130,131,131,161, 82,169,110, 59, 45, 60, 72, +240, 12,157,207,103,204,214, 64,164, 40, 28,228, 33, 2, 34, 64, 65, 33, 82, 17, 41, 55, 46,224,195,241,159,240,165,232,210,193, +158, 61,123, 92, 34, 72, 16, 4, 16, 66,224, 46,140,164,163, 92,185,114, 62,249,228,114,249,132,117,235,214, 41,150, 46, 93,138, + 21, 43, 86,184,210,150, 86,171, 69, 80, 80, 16, 66, 67, 67, 93, 71, 76, 76, 12,249,238,187,239,228,245,235,215,159, 0,224, 23, +239,113, 78, 3, 53, 85,166,213,232,211,241, 61, 0, 64,159,247, 40,178,206, 77,110,192,101,143, 11,124,128,197,149, 0, 96,244, +156, 57,115, 66, 27, 55,110, 12, 0,152, 51,103, 78,232,128, 1, 3, 70, 19, 66,198, 82, 74,237,119, 64,191,156, 16,242,188,179, + 28, 80,117,234,212, 73,241,229,151, 95,162,102,205,154, 24, 62,124,120,200,199, 31,127,220, 29,192,234,146,202, 35,119,124, 49, +103,110, 16,165,133,233,135,138,180,200,111,102,234, 21,188,245,206,135,126, 57,170, 66,133, 10,131,214,172, 89,227, 26, 14, 17, + 21, 21, 85,164,242,119, 47,163,164,163, 4, 81, 68, 0,112, 21, 43, 86, 28,176,114,229, 74, 23,103, 88, 88, 24,228,114,121,145, + 10,246,196,209,195,248,230,179, 9,208,135,149,195,251, 83,103,249,116,103, 68, 68,196,130, 39,159,124,242,133,239,191,255,222, +117,237,145,154, 53,241, 84,171,102,136, 8,211, 35, 44,184,176,108,163, 34,193,223,103, 46,251,172,143, 0,112, 21, 42, 84,120, +117,213,170, 85, 58,247,134,160,228, 87, 0, 48, 24, 12, 46,171,189,197, 98, 65,147, 38, 77,252,242,187, 59,103,104,104,168,203, +239, 82,248,185,135,173,212,128, 41,137,179, 66,133, 10, 3, 36, 1, 12, 0, 33, 33, 33, 69, 56,100, 50, 25, 86,109, 90,124, 75, +221,112,167,156,165,141,119, 79,206, 43, 87,174, 96,202,148, 41,174, 50, 73,178,226, 17, 66, 16, 29, 29,141,217,179,103,151, 74, + 96, 3,104, 10, 32,220,237,220, 2, 64,225,246,155, 6,224, 79, 47,207, 73,215,101, 0, 26, 56,239, 57, 0,228, 1, 8,242,194, + 87, 28, 79, 58, 10,187,160,195, 61,158,247,252, 78, 81,129, 69, 8,145,114,111,123, 0,123,210,211,211,197,211,167, 79,115,135, + 15, 31,134, 76, 38, 67, 68, 68, 4,154, 54,109, 42,117,159, 65, 38,147, 65,171,213,146,160,160,160, 20,169,194,149, 2,207,102, +179,185,250,147,221,132, 12,151,153,153, 41,110,221,186,149, 91,210,171, 51, 44, 20,104,248,193, 84,116,233,218, 21,155,163, 21, +224, 1, 60,114, 58, 29, 26,141, 70,144,201,100, 54, 41, 18, 36, 78,247,177, 89,158,226,136, 16, 18,160,213,106,191,251,233,167, +159, 84, 28,199, 33, 47, 47, 15,162, 40,162, 85,171, 86,224, 56, 14,199,143, 31,199,251,239,191,143, 31,127,252, 17,235,214,173, + 83, 55,106,212,232, 59, 66, 72, 45, 74,105,158, 91,225,181,205, 91,226, 12, 8, 8,128, 70,163,113, 9, 44,201,207,146,251,220, +187, 99, 40,165, 55,210,211,211, 27,151,196,233,112, 56,208,179,103, 79, 16, 66,192,243,188, 75, 12,121,254,202,229,114, 28, 63, +126,252,150,196,231, 77, 24,138,162,136,214,173, 91, 3, 0, 52, 26, 13,116, 58, 29,182,111,223,238,186,223,176, 97, 67, 88, 44, + 22,132,133,133,225,212,169, 83,222, 10,238, 34,156,105,105,105, 52, 41, 41,137, 44, 89,178, 4, 50,153, 12,161,161,161,208,104, + 52,100,241,226,197,163,229,114,121,140,201,100, 18, 45, 22, 11, 20, 10,197,108,201,154, 37, 8, 66, 65, 78, 78, 78,104,113,156, + 60,207, 99,200,144, 33,120,247,221,119,177, 96,193, 2,188,241,198, 27,183, 88,184, 76, 38, 19,194,194,194, 92, 34,203, 31,191, +223,185, 0,186,203,156, 34,197,137, 35,155,113,242,216, 54,136, 14, 17, 14,145,130, 82, 7, 68, 59,112,120,235,254,234, 55, 47, + 37, 69, 83, 80,192,217,145,161,204,201,183,183, 11, 83,214, 4,176,126,123,186,121,166,175,244, 41, 8, 2,108, 54, 27,126,250, +233, 39, 92,184,112, 1, 91,182,108,129,209,104,116,133, 99,139, 22, 45, 48, 96,192, 0,175, 2,203,147,147, 82,186,232,250,245, +235, 13, 91,183,110, 77,178,179,179,145,157,157, 13,163,209, 8,135,195, 1,187,221, 14, 65, 16,160, 82,169,160, 86,171, 17, 25, + 25, 9,147,201, 68,205,102,243,162,226, 56, 69,145,228, 24, 46, 38,156,221,180, 42,225,145, 62,239, 81,172,158, 78, 80,181,162, +210,240,219,161,128, 1,235,119,143,236, 4,128,138,206, 82,135, 3,168,205, 33,166,191, 59,250,179,161,247, 60,142,138, 98,208, +219,111,191, 93,171, 95,191,126,174, 11,253,250,245,195,137, 19, 39,106,205,152, 49, 99, 16,128, 57,165,229, 36,132, 68, 59,239, +255, 10,224, 87,169,130, 95,191,126,125, 47, 0,175,172, 91,183, 14,125,251,246,197,199, 31,127, 92,215, 83, 96,185,115, 82, 74, +113,229,220, 46, 92, 57,191, 27,162, 72,221,172,224,222,255, 83, 63,221, 89, 80, 80, 96,250,235,175,191,116,223,124,243, 13, 34, + 34, 34, 16, 27, 27, 11,141, 70, 3,149, 74, 85,164,114,117,175,112,125,229,205,130,130, 2,211,233,211,167,117,203,151, 47, 71, + 72, 72, 8, 42, 85,170, 4,141, 70,227,178,222, 40, 20, 10,108,252,113, 37, 62,121,171, 55,110, 92, 56,142,161,253,186,250,116, +167, 70,163,121,225,251,239,191, 47, 98,242,136, 14, 15,131, 32,227,192,203, 8,130, 59,244, 2, 0,100,253,190,182,216,213, 29, + 61, 56, 73, 94, 94,158,233,192,129, 3,186, 67,135, 14, 65, 20, 69, 84,174, 92, 25, 6,131, 1,122,189,222,229,255,173, 91,183, +162, 71,143, 30, 88,186,116, 41, 90,180,104,225,211,239,249,249,249,166, 99,199,142,233,126,248,225, 7,132,132,132,160, 66,133, + 10,208,104, 52, 46,195,132, 36,180,120,158, 71, 92, 92, 28,114,114,114,160,211,233,124,134,231,225,195,135,117, 63,252,240, 3, +130,131,131, 17, 19, 19,227,178,176, 73,162,104,250,220,241, 69, 56, 84,164,252, 29,115,222, 78,188,187,115,246,236,217, 19, 85, +171, 86,133, 94,175,135, 86,171,117,113,151,196,233,166, 69,218, 81, 74,119,120, 26, 49, 9, 33, 27,221,190,223,149, 16,178,209, +253,183,184,231,156,127,219,142, 30, 61,186,201,180,105,211,166,180,104,209, 98,249,222,189,123,151, 21,199, 87, 28,207,232,209, +163,235, 76,155, 54,109,138,251,243, 94,190,115,171, 5,139, 82, 74,156,158, 19, 0, 32, 62, 62, 30,153,153,153, 80, 42,149,104, +218,180, 41,210,211,211,161,211,233, 32,151,203, 65, 41,197,208,161, 67,249,145, 35, 71, 70,112, 28, 7,187,221,238, 42,240,139, +233, 75, 23, 57,142, 67,203,150, 45,113,194,217,243,211,165,107, 87,196,196,196, 64, 26,196,161, 82,169, 48,116,232, 80, 50, 98, +196, 8, 65,178, 94, 80, 74, 97, 52, 26, 81,190,124,121,117, 9, 93,111,111,173, 89,179, 38, 80,161, 80, 32, 47, 47,207,213, 69, +198,243, 60, 78,159, 62,141, 79, 63,253, 20, 47,191,252, 50,174, 93,187,134,168,168, 40,188,251,238,187,186,105,211,166,189, 5, + 96,162,175,130, 88,167,211,185,196,149, 70,163,193, 91,111,189, 37,180,106,213, 42, 66,167,211, 33, 32, 32, 0, 82,119,159,195, +225, 64,149, 42, 85,124, 74,113, 81, 20,177,121,243,102, 8,130,224,211,130,229, 76,120,126,113, 30, 56,112,192, 37,206,220, 91, + 69,132, 16,156, 56,113,194, 37,230,252,224,164, 28,199, 65,171,213,162, 92,185,114, 80,171,213,208,104, 52,100,249,242,229, 99, + 99, 99, 99,203,143, 24, 49,130,203,205,205,229, 90,182,108,137,222,189,123, 11,162, 40,194,106,181,162, 78,157, 58, 62, 45,109, + 59,118,236,192,252,249,243,241,198, 27,111,120,181, 96, 73,131, 32,245,250,251, 62,199,161,204, 32, 2,176,218,109, 48,228, 27, + 93, 93,184, 14,135, 3,199,182, 31,173,126,233,232,185, 58, 27,151, 47,149, 1,128,105,251, 90,247,215,202,247,158,187,178, 70, +187, 16,249,129,237,153,214, 3,190, 44,131,195,135, 15,199,184,113,227,240,220,115,207, 97,235,214,173,120,255,253,247,241,234, +171,175, 22,177, 96,249, 3,155,205,246,213, 75, 47,189,244,198,234,213,171,107,190,247,222,123,156,100,193,210,104, 52,210, 24, + 46,152,205,102, 24,141, 70,156, 57,115, 70, 28, 56,112,224, 89,139,197,242, 85,113,124,118,162,254, 91,163, 52,252, 82, 37,134, +171, 90,112,249,147,128,214,205, 42, 27,137,186,113, 78,175, 26, 29,233,147,175, 84, 14, 6,165,160, 34, 32, 82,192,108, 46,192, +208,161,255,227,239,103, 92, 17, 66,158,236,212,169, 83,231,201,147, 39,223,114,111,242,228,201, 56,117,234, 84,103, 66,200,149, +226,186, 68,139,225,140, 41, 87,174,220, 76,231,255,183, 40,165,137, 82,111, 49,128, 30, 91,183,110, 5, 0, 84,172, 88, 17, 0, +234, 16, 66,150, 0, 88,238, 20, 99,183,152, 67,109, 54, 59,140, 70,115,137,194, 74, 58,167, 84,244,215,141,180,102,205,154,232, +214,173, 27,100, 50,153,171,145,230,222, 61,230, 41,180, 74, 42, 63, 0,136,132, 16,196,197,197,161,115,231,206,144,203,229,208, +106,181, 46,209,162, 80, 40,192,243, 60, 30,237,208, 25,147,103, 77,192,132,151, 91, 97,124,143,202,216,126,236,106,137,238, 52, + 26,141,249,251,247,239, 87,143, 24, 56, 16,205,227,227, 17, 30, 20,132,184,168,242, 80, 43, 21,144,187,187,137,248, 54,170,211, +194,202, 78,228,121, 30,117,235,214, 69, 74, 74, 10, 46, 95,190,140,203,151, 47,131,227, 56,180,110,221,218,101,117, 57,127,254, + 60, 38, 78,156, 8,179,217,236,183,223,171, 85,171,134,199, 30,123, 12, 10,133, 2, 26,141,166, 72,215,160, 20,166,121,121,121, +168, 90,181, 42,214,175, 95,143, 26, 53,106,248,228,140,143,143,199,163,143, 62, 10,185, 92,238,138, 35,181, 90,237,170, 55, 0, +224,250,129,124,215, 55,162,163,163, 75,197,185,229,224, 53,124,179,245, 15,152, 45, 34,114, 13,182, 34, 47,148, 15,211, 99,247, + 15,239,249,229,119,137,243,235,175,191, 70,118,118,182,171, 12,146,140, 37,146,113,162, 66,133, 10,152, 55,111, 94,113,241, 35, +105, 17, 82,204,253,174,126, 54,164,164,231, 82, 36,195,255,180,105,211,166,120,190,239,139,207,253,190,199,251, 22, 15, 81,150, + 82, 98, 23,161, 84, 47, 72,170, 50, 58, 58, 26,210, 56, 15, 41,211,185, 10, 80,187, 29, 63,254,248, 35, 34, 34, 34, 92, 71, 96, + 96, 96,177, 9, 90, 26, 39, 52, 60,173,112,152,193,166, 40, 57,174, 0,120, 42,173, 48, 67, 72, 99,132,214,172, 89, 3,119, 1, + 19, 16, 16, 80, 98,119,145, 66,161,104,215,180,105, 83,206,108, 54,223, 34,174,166, 77,155,134,190,125,251,162, 70,141, 26, 16, + 69, 17,249,249,249,104,223,190,189,108,246,236,217,237, 74, 35,176, 52,154,194,241,252, 22,139, 5,219,183,111, 71,112,112, 48, + 66, 67, 67, 17, 18, 18,130,128,128, 0,105, 38, 36,245, 37, 50, 40,165,232,217,179,167, 43,209,185, 91,173, 60,197,214,222,189, +123,253,234,122,163,148,162, 89,179,102,208,106,181,208,233,116,208,233,116,216,188,121,243, 63,102,244, 71, 30,129, 40,138,136, +136,136,192,190,125,251, 74,236,230,164,148, 82,185, 92,238,122, 94, 38,147,145,197,139, 23,143,142,139,139, 43,255,206, 59,239, +112, 60,207,227,200,145, 35, 56,121,242, 36, 42, 87,174,236,247,152,172,236,236,236,155,163, 71,143,118,140, 30, 61, 26, 0, 80, +167, 78, 29,100,103,103,167, 74,247,115,115,115, 51, 58,119,238, 12,158,255,167,142, 77, 79, 79,207,248,215, 11, 44, 81,132,221, +106,135,193,100, 66,126,158,193,101, 13, 74, 77, 74, 9,122,111,196,219,178, 79,135,246, 7, 0,140,152, 57, 7,121, 11,254, 41, +192,214,142,120, 62,162,215,103, 43, 18, 0,244, 40,137,223, 96, 48,192,108, 54,163, 82,165, 74, 56,120,240, 32,242,242,242,208, +177, 99,199, 34, 22, 82, 41, 76,125,153,226, 41,165, 22, 66, 72,171,174, 93,187,254, 57, 99,198,140, 42,181,106,213, 34, 5, 5, + 5, 48, 24, 12,112,255, 61,118,236, 24, 93,182,108,217, 37,131,193,208,146, 82,106, 41,142,111,243,141,111, 47,116,137,126,117, +245,111, 71,248,174, 17, 85,207,234,111,100, 85,177,103,220, 80, 22,228, 26,207,152, 28,244, 36,168, 3,112, 64, 4,181,139,112, + 56,187,183,238,163,184,138,169, 94,189,250,235, 75,151, 46, 45,146, 6,221, 45,172, 75,151, 46, 69,235,214,173, 95, 39,132,156, + 46,105,112,191, 27,167, 66, 38,147, 37,172, 92,185, 82, 14, 0,143, 61,246, 88, 2, 33,228, 29, 74,169,165, 94,189,122,125,246, +238,221, 27, 40,149, 43,129,129,129,160,148,242, 6,131, 33,176,101,203,150,125, 36, 75, 87,145,248, 17, 1,155,205, 6,163,209, +140,156,156, 60, 88,172, 54,103,153, 41,194,225,176, 59,127, 69,216,157,229,168, 66, 46, 4, 52,174, 87, 62,159, 82, 10,142,144, +236, 67,199,110, 86, 40,174, 92, 42,174, 43,203, 31,235,149, 23, 56,164,178, 48, 52, 52, 20, 10,133, 2, 91, 55,174,197,229,191, +182, 67,198, 3,162,221, 6,135,221, 10,135,205, 2,129,231,113,224,228, 53,180,136,211,248, 19, 71, 52, 52, 52, 20, 29, 26, 53, + 66,215, 22, 45, 10,167,171, 9, 2,116, 74, 37, 52,114, 85,161,229, 10, 0,117,112,128,127, 73, 73,116,159,213,120,232,208, 33, + 12, 31, 62, 28,211,167, 79,135, 90,173,118,205,102, 62,125,250, 52, 86,174, 92,137, 78,157, 58,249,237,119, 66,136,203,239,130, + 32, 32, 33, 33, 1, 73, 73, 73,152, 57,115, 38, 26, 55,110, 12,153, 76,134,236,236,108,180,108,217, 18, 41, 41, 41,126,135,167, +212,141,167, 80, 40,138, 88,155, 36,225,119, 59,113, 36,113,246,239, 89, 30, 27,246, 44, 3, 1,193,254, 31,222, 46, 82, 23,205, + 91,177,171,212,156,227,198,141, 43,226, 78,127,172, 87,165,200,175, 27,253, 17, 89,110,207, 29,150,116,122, 66, 66,194, 24, 66, +200,198,132,132,132, 49, 83,167, 78, 61,225, 15, 95, 49,247,127,118,254, 62,229,118,237,176, 79,129, 69, 41,165, 10,133, 2,162, + 40, 22, 17, 85,158, 3,106, 37,147,159,187, 73,209,151, 24, 16, 69,209,149, 24,120, 47,133,216,190,125,251,176,111,223,190, 34, +215,191,249,230,155, 18, 43,112,187,221, 94, 43, 32, 32,160,136,245, 74, 46,151, 35, 33, 33, 1, 47,190,248,162, 75, 92,201,229, +114, 44, 92,184, 16, 77,154, 52,129,197, 98,169,229, 99, 60,138,161, 92,185,114,156, 84, 0,105,181, 90, 50,124,248,112,222,110, +183,187,194, 68, 58,164,177,105,190, 18,139, 52, 43,101,203,150, 45,126, 89,176,252, 29,131, 68, 41,197,209,163, 71,139,136, 54, +105, 22, 12, 0, 28, 61,122,212, 53, 62,203, 31, 78,158,231,225,112, 56,160, 86,171,137, 92, 46, 39,114,185, 60, 70, 18, 87, 60, +207,187,226,219,125, 76,158, 47,191,223,184,113,163,125, 73,247, 83, 83, 83, 31,218,229, 24,172, 54, 27,140, 6, 11,242,242,141, +152, 48,213, 57,126,100, 2, 14, 0, 56,208,106,208,112, 12,233,210,233, 49,143,126,126,127, 10, 24, 87,165,184,102,205, 26,200, +100, 50,172, 95,191, 30,122,189, 30,221,187,119,135, 94,175,199,123,239,189,135,231,158,123,206,111, 11,150, 51, 45,229, 16, 66, + 90,189,245,214, 91,127,126,242,201, 39, 21, 43, 84,168, 0,139,197, 2,171,213, 10,139,197,130, 11, 23, 46, 96,217,178,101,215, + 13, 6, 67, 43, 74,105,142, 47,190,205, 55,190,189,240,227,206, 17, 73, 29,159,235,109, 60,157,178, 9,201,201, 25,176,219,111, + 64,116,216, 97,181, 23,206, 72,118,216,237,176,219, 29,144,203,121,253, 39,147,223,222, 42,130,130,227,136,165, 79,159, 62, 79, +220,195,104,162,231,206,157,203, 8, 15, 15,151, 10, 49,189, 52,161, 69,161, 80, 80, 0,210, 0,247, 2, 0, 86, 63, 57, 7, 77, +159, 62,189,130,212,125, 63,125,250,244, 10,239,188,243,206, 32, 0,179,142, 29, 59,182,184,127,255,254,239,172, 90,181,170,200, + 11,253,251,247,199,177, 99,199, 22,123, 55, 17, 56, 45, 88, 38, 19,210, 50,178,240,218,160,177, 46,211, 1, 64,139,136, 10, 10, +138,193,195,160, 2,128,244,148, 11,232,255,218,112,165,175,134,128,183, 10,176, 20, 99,112,220, 45, 67,174,231,244,122, 61,228, +114, 57, 14,109, 91,139,249,227,250, 3, 14, 43,168,205, 8, 88, 13,128, 53, 31,162,197, 0, 34, 87, 3, 54,223,171, 84,112, 28, + 71, 3, 2, 2,160, 83,171, 17, 17, 20, 84,184,136, 35,207, 67, 38, 19, 32,218, 0,226, 32, 46, 33, 42, 58,252, 74,235, 52, 44, + 44, 12,162, 40, 66,173, 86,227,202,149, 43, 24, 50,100, 8,172, 86, 43,122,246,236, 9,139,197, 2,147,201, 4,163,209,136,184, +184, 56, 24, 12, 6,191,253, 46,213,157,114,185, 28,111,191,253, 54,154, 52,105,130,137, 19, 39, 98,212,168, 81,136,139,139,195, +224,193,131,177,108,217, 50,212,169, 83,167, 68, 94,137, 83,138, 35,157, 78,231,138, 23,207,174, 60, 0,165,138, 35,111,156,133, +227,254,113, 75,188,255,239,165, 14,165,230,156, 54,109, 26,210,210,210,110,177, 92, 73,255,163,163,163, 49,119,238,220,219,237, +226,151,172, 69,145, 94,110, 63,229,197,242,212, 20,133, 99,163,204, 83,167, 78, 61, 49,117,234,212,174,132,144,141, 83,167, 78, +237, 90,130, 5,235, 41, 31, 22,174,167, 80, 56,230,170, 68, 8, 30,125,159,237,220, 45, 35, 82, 5, 42, 85,228,238,133,187, 70, +163,193,143, 63,254,136,197,139, 23, 23,169,236,125, 9,172, 95,194, 11,223,127,210,105,185,114, 63,239,214,173, 27, 98, 99, 99, +139, 88,175,212,106,117,137,137, 70, 20, 69, 92,189,122, 21, 39, 78,156, 64,243,230,205,145,147,147, 3, 25,199, 97,196,177, 99, +168,253,210, 75,176, 56, 45, 50, 10,133, 2,111,188,241,134, 95, 3,213, 47, 95,190, 28,236,126, 30, 22, 22,150,216,166, 77,155, +232,131, 7, 15,186, 6,190, 59,187,207, 92, 66,195, 31,241, 66, 41,197,211, 79, 63, 93,196,106,229, 46,174,220,143, 77,155, 54, +249,213, 69, 72, 41, 69,155, 54,109, 92,214,171,128,128, 0,172, 91,183,206, 21, 87,109,219,182, 5, 0, 68, 70, 70,250,197, 41, +249,195, 57,176, 29, 38,147, 73,204,203,203,227, 14, 31, 62, 12,133, 66,225,178,216,169,213,106,168, 84, 42, 40,149, 74,175,173, +126, 6,128, 82, 17, 22,155, 13, 70,163, 17,249,249,133, 43,132, 92, 56,190,166,168, 0, 51,223,254,228, 52,201, 74,149,151,151, +135,223,126,251, 13,107,215,174, 69,227,198,141,111, 25,228,238,143, 5,203, 45, 61,165, 17, 66, 90,143, 28, 57,114,255,164, 73, +147,162, 66, 66, 66, 96,181, 90,113,237,218, 53,124,247,221,119, 73, 6,131,161, 53,165, 52,205,255, 64, 0,108, 54, 59, 76, 6, + 51,114,114,243, 48,126,242,194, 98,147, 30, 0,100,166,158, 65,183,238,207, 40,238,109, 60,209, 27, 0, 94,117, 43, 11,151, 0, +144,204,241,185,148,210, 23, 75, 41,128,219,245,233,211,167,195,219,111,191,237,186,246,246,219,111, 99,255,254,253, 29, 8, 33, +199, 41,165,219, 9, 33,117,103,204,152,225,122,102,198,140, 25, 88,189,122,245,111,148,210,237,197,165, 37,169,139, 48, 63,223, + 8,125, 80,121,220,184,188,195,167, 91,228,188, 9, 84, 20,125, 54,252,188, 89,173,220,203,167, 82,164, 31, 26, 25, 25, 41,245, + 46, 64, 46,151,163,213, 83,207,227,141, 49, 51,161,146, 81,188,221,167, 41, 98,116, 20, 80,135, 64,222,246, 61,144,160, 74,133, + 47, 14,249,201, 47,254, 81,243,231,227,200,185,194, 21, 94, 98,194,195, 49,242,185,231, 64,109,192,222,147, 39,177,226,143, 63, +240, 92,251,246,208,168, 84,126, 55, 84,164,198,247,133, 11, 23,176,119,239, 94,196,199,199,227,252,249,243,174, 49,182, 82,207, +131, 63,254,167,148, 82,105,114,146, 82,169,132, 76, 38, 67,114,114, 50,186,118,237,234,106,224,239,216,177, 3, 35, 71,142,196, +128, 1, 3,208,174, 93, 59,175,227, 98, 61, 57,195,195,195, 93,134, 3,207, 9, 8,238,221,182,165,137, 35,111,156, 18,110, 55, +222,221, 57, 39, 77,154,228,117,162,132, 63,156,238, 90,164, 4, 28,246,176, 30, 65, 26, 15, 37, 9, 34,207,115, 0,193,210,181, +132,132,132, 49,254,190,231,126, 46, 89,192,252,237,170, 20,164, 62, 79,111,149,172,100, 46,246, 6,173, 86,139, 55,223,124, 19, +227,198,141, 67, 88, 88,152,207,177, 51,146,114, 45, 9, 63,253,116,107, 38, 91,191,126,189,175, 46,194,211,129,129,129, 77,218, +183,111,143,156,156, 28, 92,191,126, 29, 90,173, 22,181, 63,251, 12,199,134, 12, 65,131,249,243,193, 61,246,152,107,145,212, 99, +199,142, 65,173, 86,159, 46,173,197, 32, 32, 32, 0,193,193,193,174, 62,117, 73,104,185, 89,176,168, 31,137, 16,191,252,242,139, +215, 86,226,237,140,193,146, 50,255,254,253,251,139,140,191,114, 23, 60,251,247,239,119, 89,176,164,215,252,233,218, 82,171,213, + 84,226,211,104, 52, 8, 9, 9,129, 82,169,132, 90,173, 46, 34,174,252,177,222,249, 90, 72, 84,173, 86, 31,212,106,181, 65,210, +125,153, 76,134,188,188,188,236,140,140,140, 71,254,213, 93,132,160,176, 91,237, 48, 26, 77,200,207, 43,251,181, 36,165, 9, 39, + 63,254,248, 35,154, 53,107,118,139,184,146,194,250, 54, 4, 71, 34, 33,164,221,172, 89,179, 14,124,254,249,231,193,249,249,249, +248,254,251,239,115,242,243,243,219,185,141, 35,242,143, 75,164,176, 89,173, 48,152,204, 40,200, 47, 12,131,139, 39,214, 60,212, +194,186, 94,189,122, 47,185,207,118,147,240,253,247,223,227,252,249,243, 47, 1,216, 14, 96,254,123,239,189, 87,173,113,227,198, + 21, 0,224,189,247,222,187, 14, 96,126, 73,101,135,213,217, 69,152,159, 95,104,245, 48, 21,164,151, 77, 58,117,138,140,226,198, + 92,221, 78, 87,142, 84,222,202,229,114,188, 52,112, 8, 46,158, 57,133,102, 97, 89,136, 9,211,129,230,222,128,252,177, 15,113, + 44, 83,131,153,243, 55,151,154,123,165,219, 36,158, 79, 87,174,244,122,239,102,223,190,165,242,251,217,179,103,161, 86,171,225, +112, 56,110,169,111, 74,235,127,119,225, 50, 99,198, 12,140, 28, 57, 18, 11, 23, 46,196,177, 99,199,208,160, 65, 3,116,236,216, + 17,169,169,169,248,251,239,191, 97, 54,155,253,118,167,251,184,184,179,151, 78, 98,219,222, 95,113, 53,241, 50,146,146,175,223, +118,188,187,115,122, 10,172, 31,183,253,133,167, 59, 53,186, 45,206,241,227,199, 35, 53, 53,181,136,229,202,221,186, 89,156, 5, +203, 83,139,120, 32,221, 99,172,147,116,110,241, 16, 59,158,231,158,207, 3, 64, 42, 0,222,199,123,158,231,233, 83,167, 78,221, + 46, 89,190,156,188,124,113,227,175,188,118, 17, 74, 98, 72,154,218,239,105,153,146,254,107,181, 90, 4, 4, 4, 32, 32, 32, 0, +122,189,222,167,101, 72, 18, 88,109, 46,229, 21, 25,203, 37, 89,178, 0, 96,192,128, 1,183, 88,176, 60, 23,167,243,132,217,108, +222,177, 99,199,142,134,221,186,117,227, 79,159, 62, 13,158,231, 33,138, 34, 44, 45, 90,160,193,252,249, 56,254,246,219,120,244, +202, 21,152,172, 86,168, 84, 42,108,222,188,217,106, 48, 24,118,148,182,188,112, 23, 88, 90,173, 22,129,129,129, 46,129,225,143, + 42,151, 50,109, 73,227, 27,164,195,125,144,191, 63,153, 89,170, 72,221,199,221, 16, 66, 96, 52, 26, 93,131, 53,253,177, 50,186, +119, 17,186,103, 60,142,227, 16, 20, 20,228, 42, 52, 36, 11,150,191,214, 59, 95, 11,137,106, 52, 26,253,153, 51,103,170, 74,203, + 72,164,167,167,227,177,199, 30, 59,247,175,175,105, 69,192,106,119, 32,223,104, 66,190,209, 80,102,180, 82, 90, 91,186,116, 41, + 46, 92,184, 0,171,213,138,169, 83,167,222, 34,172, 74, 51,200,221, 75,186,186,208,168, 81, 35,241,241,199, 31,199,254,253,251, +161, 84, 42,109,148,210, 82,175, 95, 37, 82, 17, 86,187, 29, 38,163, 17,249, 5, 5,255, 9,203,229,177, 99,199, 86,107,181,218, +231, 1,232,178,179,179,249,192,192, 64,104, 52, 26, 24,141,198, 28, 56,103, 10, 58,199,188, 77,123,246,217,103,103, 2,128,205, +102,155, 86,210,152, 54, 74, 41,108,118,167, 88, 47,195,112,148,210, 82,113,101,210,237, 44,151, 34, 85,164,210,238, 15, 31,142, + 24,138,230, 97,153,232, 88, 59, 4,198,228,243, 80,233,195, 64,130, 42, 99,230,252,205, 56,117, 37,179, 20,182, 80,224,241, 71, +123,160,126,252,173,203,123,181,238, 80,216, 22,219,253,219, 65,164,164, 39,149,218,239, 5, 5, 5,197, 90,170,252,181, 96,121, +250, 93, 38,147,161, 97,195,134,168, 94,189, 58,182,111,223,142, 70,141, 26,225,252,249,243, 56,127,254, 60,174, 92,185,130, 99, +199,142, 33, 43, 43,171,212,113,180,110,203, 10,100,229,101, 66, 33, 87, 32, 51, 59, 29, 87,111, 92, 70,100,104,185, 59,142,119, + 9, 53,159, 26, 15, 0,136, 10, 15, 44,149,192,114,231,252,248,227,143,111, 17,237,101,176,244,206, 65, 31,231,165,125,255,174, + 67, 40,198, 42,100, 12, 9, 9, 81,187,247,159,114, 28,135,192,192, 64, 50,125,250,116,158,227, 56, 4, 4, 4, 32, 48, 48, 16, +146, 89,208, 23, 20, 10,133,177,114,229,202,106, 41, 1, 74,194, 73,175,215,243,211,167, 79, 39,223,124,243, 77,177, 86, 45, 31, + 99,176, 62,127,241,197, 23, 95, 77, 76, 76, 12,142,136,136,192,205,155, 55,161, 80, 40, 10, 51, 69,251,246,104,115,233, 18,172, +133, 99,138,112,246,236, 89,124,245,213, 87, 5,102,179,249,243,210, 6,148, 78,167, 67,104,104,168,171,107, 80,178,224,184,137, + 69,191,134, 86,150,100,138,151,198, 79,221, 78, 87,145,167,200, 26, 52,104, 80, 17,177,229, 47,228,114,185, 93, 90,169,157,227, + 56, 88,173, 86, 52,106,212, 8,169,169,169,174,204,226,110,185,243, 71, 96,249, 90, 72, 84, 16, 4, 88, 44, 22,180,109,219, 22, +132, 16,204,153, 51,231,225,232,118, 20, 69,162,211,133, 34, 42,170, 6,194, 35, 76, 16,197,178,219,253,197,110,183, 99,240,224, +193, 69, 44, 86,210, 76, 69,169,139,159, 82, 10,155,205,118,219,139,182, 74,249,250, 78,214,127,163,128,171,107,171,160,192,244, +175,139,194, 74,149, 42,233,157, 93,134,158,240, 62,219, 15,255, 44,201, 64, 8,153,116,237,218,181,122,129,129,129,232,220,185, + 51,214,173, 91,183, 30,192, 38, 15, 75,225,255,156,255,111,148, 28, 23,206,112, 52,153, 81, 80, 80,246,214,208,146, 26,122,183, + 3,142,227,192,243, 60,102, 77,155,128,230,161,233,232, 80, 83,135,245,191, 29,192, 83, 53,229,128,165,244, 61,192, 82, 25, 22, + 18, 21,139,202,117,154,223,114, 95,169, 47,236,154,171, 92,167, 57,184,235,231, 75,237,119,247,111,120, 89, 58,224,142,194,243, +181,215, 94,195,123,239,189,135,206,157, 59,227,252,249,243,216,185,115, 39,206,159, 63,143,225,195,135,163, 78,157, 58,104,208, +160, 65,169, 56, 55,108, 91,141,220,252, 28,112,132, 67,102, 78, 6, 76,102, 35, 70, 13, 30,119,199,241, 46,225,242,182,169, 0, +128, 53, 91,143,220, 54,231,251,239,191,143,228,228,228, 34,150,171, 59, 25,119,245,111,133, 87,129,149,145,145,225,181,191, 47, + 60, 60, 60,165, 83,167, 78, 17, 55,111,222,132, 78,167,243, 41,174, 8, 33, 29,165,181, 50,146,147,147,189,114, 6, 4, 4, 88, + 59,117,234, 36, 43, 95,190,124,145,217,131, 90,173,246, 22,235,143, 39,167,179, 96,202, 35,132,188,222,170, 85,171, 69,155, 54, +109,210, 84,175, 94, 29,185,185,185,160,148, 98,225,194,133, 24, 58,116, 40, 84, 42, 21,206,158, 61,139,238,221,187, 27, 12, 6, +195,235,238,107, 96,121,227,244,150,185, 57,142,115,173, 98,239, 69, 92,149,232,119,247, 76, 58,107,214, 44, 76,153, 50, 5, 99, +198,140, 41, 49, 98, 22, 44, 88, 0,120,116,231,121,227,164,148,226,211, 79, 63, 45, 51,206,140,140,140,133, 30,214,167, 57,189, +122,245, 18,174, 95,191, 94, 68, 84,185, 31, 94, 10,164, 34,156,190, 22, 18,229,121, 30,145,145,145,152, 52,105, 18, 66, 67, 67, + 81,174, 92,185, 91, 44, 47,190,226,232, 54, 91,239,119,149,211, 65,197,195,159, 76,251,160,245,247, 75, 54,200,148, 10, 96,223, +206, 53,200,205, 74, 46,106,129,181,254, 51, 37, 90,209,168, 3, 44, 71,126,243,203,157,102,179, 25, 31,127,252, 49,198,143, 31, +143,241,227,199,251, 19,239,119,228,119,127, 68,150, 87, 78,145, 18,141, 54, 24, 42,109, 20,106,215, 9,134, 88,202,181, 58,239, + 83,188, 27,174, 95,191, 30, 88,161, 66, 5,156, 59,119,142,224,159,241, 88,238, 13,198,231,225, 54,219,175, 24,206, 99,203,150, + 45,171, 87,175, 94, 61,204,153, 51, 7, 0, 94,217,178,101,203,243,132, 16,147, 47,145,230,201, 41, 82, 74,212,154, 32,168,180, +229, 81,187,110, 16, 68,209, 94, 38,126,151, 42, 63, 79,235, 85, 41, 23,146,190,133, 83,106, 32, 29,219,249, 19, 6,191, 82, 13, +235,126, 63,140, 31, 78,200, 80, 67,155,142,170,193,105, 16,211, 78,227,173, 62,141, 48,115,117, 97, 37,126,211,119, 28,149,152, + 0, 77, 70,235, 29,249,221,221, 82,229,158,214,125,141,193, 42,201,239,121,121,121,200,206,206,198,162, 69,139,208,191,127,127, +164,166,166,226,202,149, 43, 56,119,238, 28,150, 47, 95,238,154,157, 94,218, 56, 26, 49,240,125,140,253,244, 29, 80, 80,212,172, + 90, 27, 9, 67,198,163,105,253, 22,119, 28,239,158,240,101,189, 42,137,115,230,204,153,183,149,150,254, 19, 2,171,164, 86, 9, +199,113, 8, 11, 11,115, 37, 14,247,132,119, 59, 45, 93,158,231, 97,183,219, 93, 99,123,164, 3, 0,186,117,235,134,159,126,250, +201,159,153, 17,155, 8, 33, 47,212,170, 85,235,187, 9, 19, 38,232, 30,125,244, 81, 33, 42, 42, 10, 77,155, 54,197,217,179,103, +241,243,207, 63,219,230,206,157, 91, 96, 48, 24, 6, 80, 74,183,222, 78,185, 36,109, 61,227,126,148,166,149, 99,181, 90,175,159, + 63,127,190,252,167,159,126,202,115, 28,135,153, 51,103,186, 50,163,180, 80,171, 59,118,238,220,105, 23, 69,177,196, 46, 25,155, +205,118,253,252,249,243,229, 63,251,236, 51,158, 16,226,226,148, 90,143,158,221,171,254,112,122, 19,151,210,132, 7,111,135, 55, +183,123,139,227,146, 22, 18, 21, 4, 1,103,207,158,197,184,113,227, 64, 8,193,154, 53, 15,199, 24,157, 99,167,211,191,105, 80, + 59, 34,184,219, 19,173,235,129, 16, 88, 45,183,246, 0,233,178,242, 93,226,170,215,103, 43,176,118,196,115,254,136,157, 11,187, +119,239, 14,249,248,227,143, 5,158,231, 49, 99,198,140, 34,139,253,122,198,251,174, 93,187,236,183,211,189, 39,229,103,171,213, + 10,163,241,246,172, 38,148,210,189, 83, 39,143,237,180,120,233, 47, 50, 66, 44,216,183, 99, 13,114,178,189, 79, 77, 87,200, 4, +124,179,232, 71,187, 92,198, 95,191,207, 81,183,160, 99,199,142,227,182,109,219, 38,248,216, 39,206, 23, 54,204,158, 61,251,201, +151, 94,122, 41,164, 86,173, 90, 88,187,118, 45, 80,184,242,179,194,153,183,138,136, 52, 31,225,184,126,218,228,177, 47, 47,250, +225, 23, 5, 71,172,216,183,115, 13,114, 60,196,250,173,214,104, 25,190, 93,248,163, 85, 46,151,157,241, 85,174,187, 91,175,238, +180, 66,116, 79,123, 29,158,121, 3,195, 23,125,137,138,141, 58,227,157, 15,218,227,199, 79,158,199,123,173, 0,235,170,126,168, +219,103, 49, 22,142,238, 2, 0,136,154,227, 95,122,148, 9,114, 92,243, 98,161,202,206, 81, 57, 69, 77,233,172,164,146,223, 75, + 42,195, 75,107,193,226, 56, 14,177,177,177,168, 82,165, 10, 90,181,106,133, 70,141, 26,161,125,251,246,248,251,239,191,241,247, +223,127, 99,248,240,225,197,138, 43,127,226,168, 93,203, 78, 56,208,230,204, 29, 39,114,207,120, 47, 11,248,147,150,134, 12, 25, + 2, 0,255, 9,107,150,112, 59,129, 39, 37,200, 59,221, 58, 70,226,180, 88, 44,174,174, 55,247,117,149,164, 65,239,126,206,208, +219, 74, 8,169,243,193, 7, 31,188,173, 82,169,218, 27, 12,134, 26, 78, 11,204, 89,179,217,252,135,209,104,156, 65, 41,205,190, + 19,183,186, 47,203,224,205, 9, 37,189,155,149,149,213,165, 75,151, 46, 91, 5, 65,136,245,220,240,212, 91, 6, 22, 69,241, 74, + 74, 74, 74,137, 83,213, 51, 50, 50,186,116,238,220,217, 43,167,183,130,193, 31, 78,111,241, 35,138, 98,177,226,202,159, 2,200, +215, 66,162,130, 32, 64,171,213, 98,221,186,117, 8, 11, 11,123,168, 50,216,209,147,169, 31,151,116,191, 93,152,114, 7,128,240, + 94,159,173,184,182, 61,221, 82,169, 93,152,226,234,218, 17,207, 85, 44,233,157,244,244,244,206,253,251,247,255, 85, 16,132, 88, +207,240,247, 22, 23,118,187,253,114,114,114,114,169,151, 61,160,148,226,204,153, 51,226,107,175,189,150,158,150,150,246,204,237, +248, 63, 97,220,236,207,167, 76, 24, 26,250,120,167,230, 77,193, 1,150,226, 7,245, 82, 2, 80, 65,198, 95, 31, 57,102,230,192, +251, 25,103,148,210,163,132,144,137, 85,171, 86,125, 3, 64,113, 53,225,114, 63,120,172,132,144, 79,154, 52,105,242,222,152, 49, + 99,130,186,117,235,134, 10, 21, 42, 20,187, 94, 96,201,233, 40,229,141, 6,181,194, 99, 30,239,216,172, 11, 8,161, 22,139,217, +135,200, 1, 5,165, 84, 46,151,157, 57,120, 52,169,190, 47,235,188,115,199,140, 50,239,154,239,219,255,117,244,237,255,186, 43, + 61,253,240,221,163,216,114,126, 59, 58,215, 72,132,249,171,214, 32,250,138,165, 18,109,147,167, 14, 47, 75, 75,102,145,201, 87, +101, 53, 6,139,231,121,164,167,167,227,236,217,179, 72, 73, 73,129,193, 96,192,169, 83,167, 96,181, 90,145,149,149,133,186,117, +235,222,182, 59,203, 42,142,238, 39,231,127,169,155,176, 84, 2,203,110,183, 39,250,218,245,220,102,179,149,106,150,145, 76, 38, + 51, 85,175, 94,157,120,155,109, 32,253,215,106,181, 70, 63, 11,198,108, 0,227, 0,140,115,238, 55,133,204,204,204, 59, 86,129, + 14,135, 35,169, 82,165, 74,124,113,194,197, 25, 54, 41, 62,220, 86, 0,160, 69, 25, 87, 4,101,206,233, 37,126, 10,226,227,227, + 93, 99,185, 60,215, 52,113,110,130, 90,226,168, 91, 95, 11,137, 22, 20, 20,220,236,210,165,139,195,253,190,251, 66,164, 15, 53, + 8,189,250,228,243,175, 86,218,158,110,169, 4, 0,146,200, 2,165, 87, 75,136,119, 35,128, 71,239,182,211, 46, 93,186,100,105, +214,172,217,210,188,188,188, 33,148,210,219, 30,165, 63,230,195, 57, 99,254,109,209, 66, 41, 61, 10, 96, 80, 25,240,156, 34,132, + 12,250,224,131, 15,250,124,240,193, 7,213, 0,132, 1, 80,249, 43,210,138,136,172, 83,105,101,190, 54,152,221,110, 79,172, 82, +165, 74,169, 44, 53,190,202,120,155,205, 86, 98, 61,241, 43,180,133,243, 40,161, 0,144,225, 23,167,209,104,204,108,216,176, 97, +169,204, 44, 54,155, 45,213, 95,191,151, 47, 95, 30, 81, 81, 81,174, 95, 9,158,215,125,185,211,110,183, 39,198,196,196, 32, 44, + 44,172,216, 21,218, 61,199, 92,249,195, 89,214,113, 84, 18,103, 84,212,226, 50,231, 44, 43,189,240, 80, 11, 44,105,143,193,178, + 68, 74, 74,202, 93,217, 27,133,150,133,121,237, 31, 75, 81, 83,252, 71,145,145,145, 17,122,167, 28,190, 22, 18, 77, 73, 73,105, +255, 95, 13,223,237,105,150, 87,110,185,230, 20, 91,247, 27, 5, 5, 5, 21, 41,165,183, 53, 50,191, 79,159, 62, 14, 48,184, 11, +226, 69, 15,162,219,210,211,211,203,188, 76,191, 27,245, 68,102,102,102,189,255,170,223,239,134, 59,255, 45,156,255,118,112, 44, + 8, 24, 24, 24,138, 17, 6, 76, 36, 49, 48, 48, 48,220, 38, 8,128,142,197, 20,174,126,207,220, 33,132,116,188,141,194,123, 27, +227,100,156,140,147,113, 50, 78,198,201, 56,255, 91,156,190,184,203,122,230,240,253,108,165,222,181, 3, 64, 71,198,201, 56, 25, + 39,227,100,156,140,147,113, 50,206,255,218,193,186, 8, 25, 24, 24, 24, 24, 24, 24, 24,202, 24, 76, 96, 49, 48, 48, 48, 48, 48, + 48, 48, 48,129,197,192,192,192,192,192,192,192,192, 4, 22, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 12, 12, 12, 12, 12, 12, 12, + 12, 12,183, 15, 82,134,235,113, 50, 48, 48, 48, 48, 48, 48, 48, 48, 72, 2,139, 16,226, 82, 89,148, 82,194,130,133,129,129,129, +129,129,129,225,158, 10,146,135, 76,139,184, 4, 22, 19, 86, 12, 12, 12, 12, 12, 12, 12,247, 83, 96, 61, 76, 90,164,136, 5,139, +137, 44, 6, 6, 6, 6, 6, 6,134,251, 37,176, 30, 38, 45,194, 44, 88, 12, 12, 12, 12, 12, 12, 12, 15,132,192,122,104, 45, 88, + 15,147,114,100, 96, 96, 96, 96, 96, 96,248,119, 9,172,135, 73,139,176, 89,132, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, + 48, 48, 48, 48, 48, 48, 60,216,184,171, 11,141, 18, 66, 58, 50, 78,198,201, 56, 25, 39,227,100,156,140,147,113, 50,129,197,192, +192,192,192,192,192,192,192,192, 4, 22, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, + 48, 48, 48, 48, 48, 48, 48, 48,129,197,192,192,192,192,192,192,192,112,159, 64, 0,120,157, 9, 64, 41,221,230, 55,201,109,204, + 38,240,197,207, 56, 25, 39,227,100,156,140,147,113, 50,206,135,143,211, 23,119,105,244,199, 3, 13, 74,233, 93, 59, 0,116,100, +156,140,147,113, 50, 78,198,201, 56, 25, 39,227,252,175, 29,172,139,144,193, 87, 11, 67, 32,132, 8,183,123,255, 94,113, 50, 48, + 48, 48, 48, 48, 60, 72, 96,149, 24, 67, 73, 66,168, 5,128,174,206,255, 27, 41,165,251, 74,115,255, 94,113,222, 43, 68, 69, 69, +169,131,131,131, 59, 31, 57,114, 68,113,234,212, 41,236,218,181,139,126,243,205, 55,214,172,172,172, 45, 73, 73, 73, 70,150, 98, + 30,138, 52,223, 5, 64,130,243,116, 26,165,116,243, 29,242, 17,141, 70, 51, 92,171,213, 62,169, 84, 42,163,236,118, 59, 49, 24, + 12, 73, 5, 5, 5, 91,237,118,251,103,148, 82,241, 54, 56,155,134,133,133, 13,170, 83,167, 78,245, 75,151, 46, 93,191,118,237, +218, 18, 0,155, 1,116,169, 88,177,226,139,113,113,113, 21, 78,156, 56,113, 46, 61, 61,125, 62,165,244,207,251,229, 78, 6, 6, + 38,176,252,203,124, 92,112,112,112, 39,181, 90,253,191,252,252,252,134,122,189,254,164,221,110,159,125,243,230,205,141, 44,227, + 61,180, 21,141, 0,160, 43,165, 84, 6, 0, 60,207,247,104,209,162, 69, 37, 66,136, 40,237,120,206,113, 92, 67,135,195,193, 57, +159,239, 74, 8,249,147, 82,106, 47, 13,103,179,102,205, 42, 8,130, 64, 41,165,132, 82,202,113, 28, 87,191, 52,156,101,133,240, +240,240, 41,162, 40, 70,149,244, 76, 96, 96, 96,147, 35, 71,142,212, 92,185,114,165,227,171,175,190,202, 30, 48, 96,128,110,200, +144, 33,194,156, 57,115,190, 4,240, 63,207,231,195,194,194, 62,231, 56, 46,204,159,239,139,162,152,158,158,158,254, 14, 75,121, +247, 29, 9,115,183,229,181,165, 20,120,179, 83, 0,231, 20, 46,183,141,232,232,232, 69, 47,191,252,242,243,245,234,213, 19, 40, +165,176,217,108, 48,155,205, 53,247,237,219,215,110,205,154, 53, 77, 0, 60, 83,202,124,217, 53, 33, 33,225,235,137, 19, 39,134, +203,100, 50, 98,179,217,154,175, 92,185,242,241, 65,131, 6, 29,157, 63,127,126,131,103,159,125, 54, 64,186,254,225,135, 31, 62, + 65, 8,121,155, 82,186,252, 94,187,147,129,129,193,135,192, 10, 8, 8,168, 22, 30, 30, 62, 34, 52, 52,244,137, 38, 77,154,228, +188,254,250,235, 23, 47, 92,184,112, 60, 54, 54,214,240,253,247,223, 79,182,217,108,115,107,212,168,177, 37, 55, 55,247,179,228, +228,228, 83,165, 44, 40,170, 1,120, 29,192, 19, 0, 98, 0, 36, 1,248, 21,192,215,148,210, 51,183, 41, 10,234, 5, 4, 4,140, +226, 56,174,121,126,126,126,140, 78,167, 75,162,148, 30,200,205,205,253,132, 82,122,228, 54, 57,163, 5, 65,120, 93, 38,147, 61, + 42,138, 98, 21,142,227, 46, 59, 28,142, 29, 86,171,245,107, 74,233,181,219,228,172,166,215,235,223,146,203,229,173, 77, 38, 83, + 5,165, 82,153,232,112, 56,246,102,103,103,207,188, 93,191,223,109, 40, 20, 10,110,201,146, 37, 13, 20, 10, 5, 0,192, 98,177, +160, 78,157, 58,119,180,219,185, 76, 38,227, 62,251,236,179, 70,130, 32,192,106,181,138,121,121,121,180,119,239,222,247,165,219, +154, 16, 18,147,148,148, 20, 40,151,203,189,222,119, 56, 28,104,219,182,109,172, 92, 46,199,103,159,125,102, 75, 79, 79,111,248, +197, 23, 95, 28, 89,182,108, 89,216,151, 95,126,217,199,155,192,226, 56, 46, 44, 49, 49,209, 43,167,195,225,128,213,106,133,221, +110,135,197, 98, 65,173, 90,181, 88,105,244, 96,160, 18, 0,252,242,183, 9, 0, 66,238,148, 76,171,213,198,247,237,219, 87, 72, + 75, 75,131, 76, 38,131,213,106, 69,114,114, 50,234,212,169,195, 47, 93,186,180, 70,105,249,106,214,172, 57,104,234,212,169, 17, +191,252,242,139,117,233,210,165,230,142, 29, 59,202, 7, 12, 24,160,111,219,182,109,155,152,152, 24,238,187,239,190, 51,111,219, +182,205,250,194, 11, 47, 40,167, 76,153, 18,241,235,175,191, 62, 15, 96,249,189,118, 39, 3, 3, 67, 9, 2, 43, 32, 32, 96,135, + 78,167,171, 58,112,224,192, 51, 67,134, 12,217,162,211,233, 28, 0,240,195, 15, 63, 8, 61,122,244, 72,235,221,187,119,170,193, + 96,224,231,206,157, 91,241,139, 47,190,216, 26, 16, 16,112, 35, 47, 47,239, 17, 63, 42, 50, 2,224,127, 28,199, 13,235,220,185, +243, 14,155,205,150,182, 97,195,134, 85,189,122,245,106, 67, 41,213,254,254,251,239, 63, 19, 66, 22, 0,248,212, 95,235, 24, 33, +132, 87,171,213,227, 99, 99, 99,223, 93,190,124,185,178,122,245,234,208,106,181,200,201,201,169,120,242,228,201, 10,175,188,242, + 74,119,173, 86, 59,219, 96, 48,140,165,148,218,252, 14, 28, 65,120, 53, 60, 60,252,211,121,243,230,233,235,214,173, 75,180, 90, + 45, 46, 95,190, 92,110,207,158, 61, 45, 62,254,248,227,161, 60,207,143,113, 56, 28,115, 75, 81,137, 19,141, 70, 51,178, 90,181, +106, 99, 22, 47, 94, 28, 16,167,215, 17, 5,117,192, 66, 81,235,138,193, 28,255,242,203, 47, 63,167,211,233, 62, 41, 40, 40,152, +114,191, 44,131,132, 16, 37, 0, 80, 74,205,132,144,141, 60,207,247, 80, 40, 20, 92,143, 30, 61,176,109,219, 54, 98, 50,153, 4, + 0, 80,169, 84,246, 30, 61,122, 64,173, 86,195, 98,177,136, 0, 54, 22,103,105,242,198, 41,147,201,184,246,237,219, 27, 14, 30, + 60,152, 41,113,106, 52, 26, 91,251,246,237, 67, 21, 10,133,218,110,183,211,146, 56,239,146,136,196,133, 11, 23,138, 92,203,203, +203, 67, 90, 90, 26, 50, 50, 50, 96, 54,155,145,157,157, 13, 81, 20,137, 90,173, 78, 19, 69, 17, 28, 87,104,108, 43,142, 83, 46, +151,227,236,217,179, 69,174,217,237,118, 20, 20, 20,192,108, 54,195,106,181, 34, 47, 47, 79, 29, 16, 16, 80,173,118,237,218,137, + 0,214,103,102,102,126,150,156,156,124,149, 21, 79,247, 5,215, 54,254,101,170, 8,192, 2,224,114, 25,240,137, 0,176,107,215, + 46,164,164,164, 32, 61, 61, 29,105,105,105,136,137,137,193,237,228,241, 51,103,206,204,106,216,176, 33, 57,122,244,232, 79, 0, +190, 94,177, 98, 69,175,204,204,204,121, 35, 71,142, 12,249,228,147, 79, 50, 71,141, 26, 53, 24,192,218, 21, 43, 86,244,175, 87, +175, 94,183, 99,199,142,205,188, 31,238,100, 96,184, 11,104, 10, 32,220,249, 63,221, 89,238,134,186,157,255,237,204,183,210,115, + 22, 0, 10, 47,191, 18,164,243, 52, 0,127,186,189, 39,157,223, 49,164,174, 24, 42, 29,210, 13, 74,105, 84,181,106,213, 50,103, +204,152, 81, 51, 33, 33, 33, 52, 63, 63,159, 7,128,232,232,104, 19, 33,132, 26, 12, 6,254,189,247,222, 11,159, 54,109, 90, 77, +165, 82,153,101,183,219,195, 61,201,139,153,106, 57, 76,175,215,119,191,124,249,242,138,154, 53,107,134, 76,157, 58,245, 47,181, + 90, 77,103,205,154,117,184, 74,149, 42,229,175, 94,189,186, 88,175,215, 63, 6,224, 93,111, 14,246,198,169, 84, 42, 39,189,244, +210, 75,239,158, 63,127, 94,217,180,105, 83,232,245,122,240, 60,143,144,144, 16,180,109,219,150,156, 62,125, 90,217,187,119,239, +225, 42,149,234, 19,127, 57,121,158,127,163,119,239,222,179,175, 94,189, 26,216,185,115,103,162, 80, 40,144,149,149, 5,165, 82, +137, 86,173, 90,145,181,171, 87,233, 91, 52,107, 54, 93, 46,151,191,229, 47,167, 70,163,121,231,133, 23, 94,248,240,216,177, 99, +250, 58,117,234,144,171,159,127,132,253,221,218,224,242,228, 49,136,143,143, 39, 71,143, 30, 13,232,223,191,255, 24,173, 86, 59, +198, 95,206, 59,133, 59, 39, 33,100, 8,128, 76, 0,153,132,144, 33,148,210,125,117,234,212, 57,124,234,212, 41,180,105,211, 6, +171, 86,173,170, 63,114,228,200, 33, 35, 71,142, 28,178,106,213,170,250,109,218,180,193,169, 83,167, 80,167, 78,157,195,238, 99, +165,252,225,220,177, 99, 7, 30,123,236,177,172, 85,171, 86,197,141, 27, 55,110,202,184,113,227,166,172, 88,177,162,202, 99,143, + 61,150, 53,115,230, 76,115, 73,156,119,195,239,238,150, 37,247, 67, 20,255,169, 91,162,162,162, 82,127,252,241, 71, 60,251,236, +179,156, 66,161,184,249,220,115,207, 41,119,239,222, 77, 1,108, 44,141, 59, 77, 38, 19,140, 70, 35, 10, 10, 10,112,233,210, 37, +245,199, 31,127,220,122,252,248,241, 85,183,109,219, 22, 61,102,204,152,193,225,225,225, 71,202,149, 43, 87,233, 94,251,157,113, + 2, 0,146, 1, 88, 1, 20, 0,184,122, 39,156, 29, 58,116,168, 91,181,106,213,200,149, 39,130,145, 37,175, 9, 81, 30, 4, 81, + 30, 4, 71,104, 83, 92, 80, 60,129,138, 21, 43, 70, 6, 4, 4,180, 40, 13, 39,165,116,235, 95,127,253,245, 4,165,116, 62,165, +212, 65, 41, 93, 61,106,212,168,215, 8, 33,107, 70,141, 26,245, 6,165,116,181,243,250, 55,127,255,253,119, 55, 74,233, 31,247, +195,157, 44, 45, 49,206,219,108,224,223,162, 69,220, 16, 78, 8,217, 72, 8,217, 56,122,244,232,246, 0, 66, 61,206, 91,186, 63, + 7, 64,225,237, 87, 58,220,174,135, 3,120,202,237,189,240,178,242, 15,231, 22, 88,132, 82, 74,220, 60,106,251,248,227,143,247, +127,251,237,183,219,110,222,188, 89, 62, 46, 46,238,169, 94,189,122, 85,202,201,201, 33,189,122,245,138, 45, 95,190,124,215, 29, + 59,118,148,235,211,167,207,239,125,250,244,217, 71, 8,177,251, 17,120, 85,120,158,127,251,232,209,163,187, 43, 86,172,104, 77, + 74, 74, 10,104,216,176, 97, 30, 0, 84,175, 94,221,144,145,145,161, 14, 12, 12,196,166, 77,155, 14, 18, 66, 94, 39,132,212,244, +131,179, 81, 68, 68,196,255,230,204,153,163,228,121,222,235, 51, 42,149, 10, 95,124,241,133, 50, 56, 56,120, 32, 33,164,185, 31, +156, 49,161,161,161,211, 23, 45, 90,164, 54,155,205,176, 88, 44,136,140,140,132, 78,167,195,205,164, 36, 36, 93,185,140,228,203, +151, 48,246,157,183,180,122,157,110, 60, 33, 36,214, 31,191, 71, 68, 68,140,155, 57,115,166,250,232, 51,157,177,189,146, 6,149, + 38,124,134, 70, 7, 46, 34,110,246, 66,236,172, 22,140, 63, 31,111,134,169,147, 39,171, 34, 34, 34, 70,250,227,247,187, 96,185, +250,132, 82,170,166,148,170, 9, 33,179, 90,182,108,185, 84,173, 86, 15,153, 58,117,106,151, 45, 91,182, 60,190,115,231,206,118, +118,187, 93,102,183,219,101,187,118,237,106, 99, 50,153, 4,165, 82, 9, 65, 16,168,191,156, 45, 90,180, 88,164, 86,171, 7,207, +155, 55,175,203, 31,127,252,241,226,161, 67,135,222,116, 56, 28, 10,135,195,161, 56,116,232,208, 27, 70,163, 81, 70, 41,117, 20, +199,121,175, 33,147,201, 32,151,203,161, 86,171,209,186,117,235,139,223,124,243,141, 45, 38, 38, 70,182,102,205,154,224,168,168, + 40,237,156, 57,115,178,243,242,242,166,251,203,103,181, 90, 97, 54,155, 97, 52, 26, 97, 50,153,240,251,239,191,199, 14, 29, 58, + 84, 48,153, 76,142,110,221,186,101,218,108, 54,243,168, 81,163,244, 33, 33, 33, 35, 88,131,245,190,192, 14, 32,223, 41,176,204, +238,105,153, 16, 82, 79,178,198,250,131,236,236,236, 5,223,126,251,109, 12,167, 12,194,110,203,147, 88, 46, 78,192,150,192, 57, + 72,173,244, 46, 34, 98,170,226,249,231,159,143,160,148,206, 41,131,138,110, 61,165,180, 15,165,244,199,219,121,255,110,187,147, + 16, 82, 73,167,211,173,210,235,245,187,117, 58,221, 42, 66, 72,165, 59,245,115,231,106,164, 99,143, 90,124, 98,231,170,132,246, +168,197, 39,118,174, 86,250,181,154, 24, 30, 76,120,106, 17, 55,164, 81, 74,187, 82, 74,187, 78,155, 54,109,138,219,243,210,185, +218, 79,254,174,148,210,174, 30,105,116,227,221,240,139,224,174, 28,189,121, 42, 60, 60,220, 50,102,204,152,163, 38,147,233,248, +162, 69,139,170,190,240,194, 11, 13, 43, 85,170,116,182,119,239,222, 63,235,116, 58,187, 52, 38,199, 79,188,250,228,147, 79,254, + 18, 22, 22,134,156,156, 28,193,102,179,241, 5, 5, 5, 60, 0,136,162, 8,147,201,196, 95,186,116, 73, 48,155,205,180,121,243, +230, 27,246,237,219,247, 58,128,183, 75, 34,212,104, 52, 67,214,172, 89,163, 42, 78, 92, 57, 28, 14,228,229,229,193,110,183, 99, +214,172, 89,170, 87, 95,125,245,127, 0,246,251,168, 84,223, 93,180,104, 81,128,221,110, 7,199,113,160,148,226,200,145, 35,200, + 72, 77,133, 41, 47, 23,230,220, 28, 88,115,115,192, 23,228, 97, 88,191,231, 3,166,124,245,205, 24, 0,175,149,196, 25, 16, 16, +240,206,162, 69,139,116,162, 40, 34,251,200, 1,175,207,228,157,252, 27,162,195,142,185,115,231,234,158,125,246,217, 4, 0, 47, +223,175, 68,174, 84, 42,133, 37, 75,150,244, 85, 40, 20,160,148, 18,139,197,130, 45, 91,182,220, 49,231,226,197,139, 95,148, 56, +173, 86, 43,173, 91,183,238, 45,105,206,108, 54,211, 7, 37,179, 43, 20, 10,168, 84, 42, 88,173, 86, 84,174, 92,217,216,175, 95, +191,189,147, 39, 79,174,200,113,156, 86, 46,151,111,202,200,200,152,146,148,148,116,201, 95, 62,155,205, 6,139,197, 2,139,197, + 2,163,209,136,139, 23, 47,150,139,141,141, 37, 67,134, 12,113, 24, 12,134,184,217,179,103, 95,216,178,101,139,102,250,244,233, +189, 1, 12, 99,197,237, 61,109,100, 40, 0, 4, 86, 12, 21, 10,100, 60,242, 1, 4, 56,197, 64,111, 66, 72,243, 90,181,106, 5, +159, 58,117, 42,139, 16,178, 31,192,114, 74,233,205,146,248, 68, 81, 36,162, 40,226,141, 71,178, 49,164, 5, 15,155, 45, 7, 57, + 57, 57,184,122,245, 42, 78,158, 60,137, 3, 7, 78,222,150, 59, 85, 42,213,171, 58,157,174,179, 74,165,170,108,183,219,185,252, +252,252,171, 6,131, 97,155, 40,138, 11,168,115,129,162,210,224,110,185, 83,130, 86,171,253,120,204,152, 49,173, 2, 3, 3,241, +215, 95,127,197,173, 88,177,226, 99,220,225,160,121,149,140,251,238,243,153,115,162,163, 35,130,240,247,206,159,162,167,204, 95, +249, 29, 10,199,242, 50,252,251,243, 33, 45, 70, 96,253, 9,224, 41,231,236,242,174,119,192,127, 71,239,223,150,192, 42,198, 67, +238,153,218, 49,104,208,160,179, 27, 54,108,168,220,164, 73,147,211,197, 13, 6,246,129, 86,241,241,241, 87,247,238,221,139,144, +144, 16,171,205,102,227, 77, 38, 19, 39,151,203,105,102,102, 38, 49, 26,141,220,223,127,255,173, 74, 76, 76,148, 7, 7, 7,203, + 0, 52,242, 69, 40,151,203, 91, 84,173, 90,213,235, 61,139,197,130,252,252,124,228,229,229,193,108, 54, 35, 58, 58,154,112, 28, +215,204,103,160, 8, 66,155, 90,181,106,145,172,172, 44, 68, 69, 69, 97,207,158, 61,200,207,206,134, 41, 47, 23,150,220, 28, 88, +115,178, 97,203,201, 70,118,106, 18,170,150,139, 38,132,144,150,126,112,182,170, 22, 24, 64,206,188,253, 26,154, 30,185, 10, 34, +147,227, 96,221,242,160, 54, 43, 0,224,145, 99, 73, 32,114, 5, 78, 15,121, 1,149,159, 27, 64, 4,158,111,126, 47, 19,181,115, +124,212, 72,142,227,102, 41,149, 74, 97,240,224,193,184,121,243,102,145, 52, 49,120,240, 96,215,152,171,182,109,219,238, 82,169, + 84,246,180,180, 52,152,205,102,153, 63,156,149, 43, 87,190, 58,118,236,216,131, 22,139, 37, 38, 42, 42, 42,200,108, 54, 27,107, +212,168, 17,165, 86,171, 35, 45, 22,139,163, 73,147, 38, 11,212,106,181, 45, 63, 63,159,218,237,118,242,128,100,118, 16, 66, 96, +183,219, 97,183,219, 17, 22, 22, 86,144,158,158,126, 32, 43, 43,171,239,237,240,217,108, 54,105,134, 22,140, 70, 35, 40,165,248, +235,175,191,160, 82,169,100, 14,135,227,132,221,110,215,200,100, 50,112,206,193, 93, 12,247, 44,158,219,213, 12, 82,124, 62,181, +121, 68, 80,131,110,218, 2,141,130, 47, 16,175, 54,168,252,253, 39, 39, 87,188,244,226,171, 1, 19, 39, 78,172, 20, 22, 22,166, +186,112,225,130,233,163,143, 62,138, 93,178,100, 9, 1,240,105, 73,156,215,175, 95, 95, 51,102,204,152,144, 39,159,124, 50, 78, +169, 84,146,156,156, 28,164,165,165, 33, 37, 37, 5,151, 47, 95,166,127,255,253,247, 69,179,217,188,170, 52,238,140,138,138,250, +102,232,208,161, 47, 53,110,220, 88, 38, 89, 68, 11, 10, 10, 26,238,216,177,163,251,175,191,254,218, 6, 64,169,211,229,245,235, +215, 87,189,255,254,251,218, 39,158,120,162,166, 82,169,228,202,194,157,238,224, 56, 46, 82,167,211, 97,219,182,109, 8, 10, 10, + 2,199,113,145,119, 26, 95, 38,171, 24, 29, 85, 46, 20,166, 61,159,163,102,120, 37,152,172, 98, 52, 75,197, 15,143, 5,171,152, + 91, 77, 37, 11,148, 15,145,100, 76, 72, 72, 24, 67, 8,217,152,144,144, 48,198,155, 5, 75,178,191,184, 63,231,246,188,185,204, + 5,150, 47,164,165,165, 41, 10, 10, 10, 4, 81, 20,249,156,156, 28,141, 70,163,177, 43, 20, 10, 75, 41,191, 87,187,123,247,238, + 7,155, 53,107,150,239,180,104,216, 34, 34, 34,172, 57, 57, 57, 16, 69, 17,162, 40,218,245,122,125,190,205,102, 67, 92, 92, 28, + 7,192,103, 55,153,209,104,172,168,213,106,111,185,110, 48, 24, 92,226, 42, 63, 63, 31, 6,131, 1,122,189, 30,249,249,249, 81, +126, 84,130,177, 26,141, 6, 73, 73, 73,133,150,165,172, 76,152,115,115, 97,201,251, 71, 92, 57,178,179, 32, 26, 11, 16, 82,161, + 34,108, 54, 91, 69, 95,156,102,179,185,162, 66,180, 35,115,251, 22, 84, 28, 95,124,185,156,189,127, 55,116, 85,170,195,102, 52, + 68,223,135,132, 61,183, 97,195,134,141,214,174, 93, 59,224,198,141, 27,183,220,239,217,179, 39,134, 13, 27,134,161, 67,135,158, +126,234,169,167,254,254,233,167,159,240,230,155,111, 66, 20,197, 6,132,144, 28, 74,233,175, 37,113, 38, 36, 36, 28,186,126,253, +250,246,115,231,206, 13,142,136,136, 80,214,171, 87,239,124,189,122,245,248,181,107,215, 70, 14, 28, 56,240,240,227,143, 63,126, +229,183,223,126, 11,217,182,109,155, 74, 20,197,198,132,144, 27,247,123, 29, 44,169,139,216, 98,177,192,100, 50,193,106,181, 2, + 37, 12,106,247,226,127, 79,107,129, 75,172, 57,185,201,218,181, 63, 98,215,174, 93,220,201,147, 39, 98, 6, 15, 30, 34, 13,164, +103, 37,237,189, 17, 86, 79, 40, 56,242,213,200, 6,161,170, 17,245, 67, 11, 20, 2,201, 63,251,213,152,252,203, 21,245, 5,145, + 21, 52,150,152,216,160,168, 41, 83, 38,151, 63,125,250,140,121,236,216,177,167,158,123,238,185,136, 17, 35, 70,212, 90,179,102, + 77, 27, 66,200,183,148,210,236, 98,120,229, 3, 6, 12, 56, 16, 17, 17, 81,101,254,252,249,169,215,175, 95, 15,182,217,108, 26, +155,205,102, 45, 40, 40,184, 96, 48, 24,118, 91,173,214,109,148,210,195,165,113,111, 64, 64, 64,253, 87, 94,121, 69,150,157,157, + 13,231,236, 91,164,166,166,162, 85,171, 86,252,134, 13, 27,106,223, 78, 24,100,102,102,126, 78, 8,217,190,108,217,178,206,122, +189,190,177, 82,169, 44, 7,192,145,151,151,151, 82, 80, 80,112,244,118,220,233, 14,135,195,145,114,248,240,225, 42,122,189, 30, +215,174, 93,131,195,225, 72,185,211,120, 83,201,185,235,199,118,110,168, 16, 31, 22,139,221,123,247, 67, 37,231,174,179,212,252, +208, 67, 26, 35, 5,119,225,228, 69, 24,237,157, 58,117,170,122,218,180,105,152, 58,117,234, 9,111, 22, 44, 73,104, 77,157, 58, +245,132,244,156,219,243, 59,203, 84, 96, 21,167, 24,243,242,242,132, 35, 71,142, 4, 95,191,126, 93, 23, 22, 22,102,170, 85,171, + 86, 14, 33, 68,228, 56,142,222,188,121, 51,228,242,229,203,170,208,208,208,130, 42, 85,170,100,250,249,189,115,195,135, 15,111, + 51,110,220,184,195,157, 58,117, 74, 7,128,172,172, 44,100,100,100, 32, 45, 45, 13, 86,171, 21, 73, 73, 73,220,161, 67,135, 66, + 54,109,218,212, 16,128,207,174, 23,181, 90,125, 45, 39, 39,167, 70, 72, 72,136,171, 66,147, 68,149,187,192,178, 88, 44,200,201, +201,129, 78,167, 75,242,197,201,243,124,226,141, 27, 55,106,153,140, 70, 92, 59,127, 30,230,188,194, 46, 65,151,184,202,201, 4, +242,243,160, 85,169,144,147,158, 6,153, 76,150,236,139, 83,169, 84, 94,179,112, 66,157,144,118,157, 1, 82,124,253, 28,248, 72, + 43,208,186, 77, 32, 83, 47,190,113, 63, 82, 48,199,113,142,146,186,125, 21, 10, 5, 34, 35, 35,197,230,205,155,227,205, 55,223, +132,195,225,112,166, 89,210,142, 16,178,155, 82,154, 95, 28,167, 40,138,220,169, 83,167,122, 93,184,112,129,151,201,100, 92,179, +102,205,234,180,110,221,218,162, 80, 40, 32,151,203,133,252,252,252,128,109,219,182,169,108, 54, 27,113,114,222,179,117,176,128, +194,217,125, 94, 4, 60, 10, 10, 10, 96, 52, 26,145,159,159,143,172,172, 44, 65,173, 86,215,168, 91,183,238,126,139,197,178,202, +110,183,127,119,233,210,165,220,226, 56,157,130,204,149, 54, 69, 81, 4,165, 20, 14,135, 3, 54,155, 13,114,185, 92,220,177, 99, + 39, 62,157,241, 49, 22,125,183,132,118,239,222,157,108,216,176, 1,162, 40, 38,178,242,244,158,224,179,236,229,147, 85,176, 59, + 10,204, 59,150,229, 47, 61,151, 91, 48,113,233,204, 67, 22, 5,159,219,228,209,200,122,113,177, 53,248,160,160, 96,110,222,130, + 89, 25, 63, 44, 89,125,225,218,181,107,185, 95,126,249,101,139, 26, 53,106, 4, 30, 61,122, 52, 26,128, 87,129,165,211,233, 42, +247,239,223,191,127, 86, 86,150,124,201,146, 37, 11,111,220,184,177,131, 82,122,209,163,160,111, 68, 8,249, 4,128, 12, 64, 36, + 10,199,127,109,165,148, 46, 46,193,189, 34, 33, 4,127,252,241,199, 45,179,253,196, 59, 83,229, 89,245,234,213,171,127,238,220, +185,245,201,201,201, 75, 61,111,106, 52,154,238,117,234,212,121,254,224,193,131, 31, 80, 74, 47,148,134,216, 96, 48,140, 90,189, +122,245, 39, 60,207, 71, 57, 28,142, 36,163,209, 56,234,142, 45, 88, 54,241,181,169,243, 86,124,109,180, 56, 42,170, 21,252, 53, +147, 77, 28,200,146,242, 67,109,189, 2,156, 99,176,164,255, 0,136,199,249, 81,231,127,139,219,179,105,110, 86, 43,139,135,213, +203,219,189, 52, 0,182,178,242,143, 80, 66,101,163, 27, 59,118,108,139, 6, 13, 26,220,108,219,182,109,114,108,108,172,193,173, + 21,101, 12, 13, 13, 53,154, 76, 38,245,213,171, 87,203,175, 91,183,174,186,195,225,208,248,241,189,223,131,130,130, 66, 14, 29, + 58, 20,186,124,249,242,106, 71,142, 28,169,212,175, 95,191, 71, 45, 22, 11,204,102, 51, 46, 93,186, 84,233,171,175,190, 18,229, +114,121, 54, 33,228, 79, 0, 14, 95,132, 86,171,117,223,201,147, 39,171,183,109,219,150,216,108, 54,151,160,114, 23, 89,249,249, +249,144,203,229,184,114,229, 10, 21, 69,241,128, 47, 78, 81, 20,247,237,223,187,183, 86,195,122,117, 97,206,201,114,138,171, 28, +216,115,178, 32,230,100,130, 43,200, 71,104,136, 0,141, 74,135, 19,215, 19, 1,192, 39,167,221,110,223,115, 62, 39,175,118,195, + 25,223,144, 29, 85,131, 64,109, 86, 87,183, 32, 0, 87,119, 97,203,211,105,216,250,199,118,106,119, 56,246, 63,168,153,224,239, +191,255, 78,237,215,175,223, 97, 81, 20, 27,149,198,154,227, 86,249,228,229,231,231, 35, 61, 61,221,145,145,145, 97, 2,128,212, +212,212,172, 13, 27, 54,156, 18, 69,241,145,219,225, 44, 11,216,108,182, 91,172, 79, 14,135, 3,118,187, 93,178, 20, 40,126,254, +249,231,182,167, 78,157,146, 31, 63,126, 28,187,118,237,106,240,195, 15, 63,140,174, 84,169, 82,189,171, 87,175, 38,251, 18,109, +196,187,176,230, 1, 96,229,178, 85, 24, 52,104, 16, 73, 78, 78,198,242,229,203,225,107,209, 83,134, 50, 67, 1,236, 14,181,101, +199,178,252,167,126,185,150,183,239,166,241, 35, 0,155,169,209, 78, 43, 84,168,240,119,227,198,193, 97, 0, 96, 54, 57,202, 85, +171, 86,237, 81, 65, 16, 20,206, 52,220, 56, 52, 52,116, 46,128,214,222, 72,123,246,236,217, 50, 34, 34,162,225,175,191,254,122, +244,198,141, 27, 59, 61,197, 21, 0,212,168, 81, 99,194,241,227,199,159,144,201,100,238,147,139, 40, 0,175, 2,171, 93,187,118, + 53, 42, 85,170, 20,250,203,185, 64,228,202,171,130,242, 57,128,160,130, 35,168, 62,174,202,107, 33, 38,102,127,104, 80, 80, 80, +131,236,236,236,163,165,180,226, 85,124,246,217,103,127,254,230,155,111,226, 31,127,252,113, 5,128, 91, 4, 86,124,124,124,239, +223,126,251,173,207,224,193,131,235, 19, 66,186, 81, 74,207,151,162,210,188, 10,160, 79, 89, 70,218,150,243,116, 27,156,107,150, + 49,252,103,240,231, 93,122,246,174, 65, 40, 65,184,108, 61,127,254,124,211,167,159,126, 58,221, 93, 92,185, 43,204,192,192, 64, + 99, 88, 88, 88,230,209,163, 71,195, 69, 81,220,225,199,247,190,254,237,183,223,254,152, 61,123,246,178,144,144, 16,219,139, 47, +190,200,189,247,222,123,187, 50, 50, 50,104, 70, 70, 6,230,204,153,211,182, 77,155, 54,187,174, 94,189,234, 56,124,248,112,127, + 0,143,251,209, 58,154,219,183,111,223,231,207,157, 59,167,178, 90,173,200,206,206,190,197,122,101,179,217,192,243, 60,166, 76, +153, 98,206,205,205,157,229, 71, 69, 59,107,242,164, 73,207,174, 93,177, 60,128,183, 90, 97,203,206,132, 61, 39, 27,142,236, 76, +112,134, 2, 4,168, 8,170, 53, 10, 71,214, 13, 37,190, 92,246, 83,158,217,108,254,212, 23,103, 94, 94,222,231, 47,191,252,114, +191, 83,167, 78, 5,232,235, 53, 70,206,225, 91,123,190, 20,225,145,176, 88, 44,120,231,157,119,242,114,114,114,166,221,143, 4, + 33,138, 34,111,177, 20,223,243,107,177, 88, 32,138, 98,226,201,147, 39, 87, 16, 66,242, 8, 33,237,156,183,182,123,179, 94,185, +115,114, 28, 39,214,170, 85,107,109,100,100,100, 47, 0, 5,181,106,213, 90,171, 84, 42, 31,179, 88, 44,205, 68, 81, 76,252,235, +175,191,126, 36,132, 36, 19, 66,164, 86,198, 61, 93, 7,203,102,179, 97,220,184,113,152, 54,109, 26, 18, 18, 18, 92,254,149,186, + 9,179,179,179, 99,119,239,222, 45,223,177, 99, 7,157, 63,127,126,198,203, 47,191, 28,244,250,235,175, 7,125,245,213, 87,111, + 3, 24, 85, 28,231,168, 81,163, 48,127,254,124, 12, 26, 52,200,155,181, 84, 76, 76,188, 14,147,201, 68,103,207,158,157, 36,147, +201,130,191,253,246, 91,245,192,129, 3, 9, 43, 79,239, 9,222, 87,247,251,224, 45, 20, 46,205, 48,139, 82,186, 93,186,161,215, +235,213,107,215,174, 19, 0, 96,205,234, 31,101,148,210, 64,105, 97,216,165, 75,151,170, 90,181,106, 21, 81, 28,233,234,213,171, +179, 63,250,232,163,208,215, 94,123,237,241,237,219,183,107, 8, 33,191, 56, 11,253,116,103,195, 49, 12,192,158,240,240,240,242, + 43, 86,172,168,218,185,115,103,173, 31,101,200,183, 43, 86,172,168, 60, 99,119, 32,126, 41,232,133,235,226, 51,160, 65, 20, 33, + 17,121,168,165,187,134,190,125,251, 70,205,154, 53,235,107, 0,141, 75, 33,174,106, 63,253,244,211,235,190,249,230,155,216,215, + 95,127, 61,113,207,158, 61,215, 9, 33, 19,188, 60,154,241,202, 43,175, 92, 93,184,112, 97, 85, 81, 20, 55, 19, 66, 30,167,148, +158, 99,201,135,129,225,246, 44, 88,175, 18, 66,234, 36, 36, 36,124, 28, 21, 21, 85,113,252,248,241,151,107,213,170, 85,224,202, +109, 25, 25,186, 29, 59,118,196,229,230,230,230,217,237,246, 23, 41,165,127,123,201,188, 29,221,215,202,160,148, 94, 37,132,124, +220,160, 65,131,231, 87,174, 92,185, 35, 32, 32, 32,119,255,254,253,122,189, 94,159,115,234,212, 41, 45,207,243,134,203,151, 47, + 99,203,150, 45,109, 1,124,225,173,149,228,133,243,136, 74,165,154,245,234,171,175,254,239,243,207, 63, 87, 81, 74, 97, 48, 24, +144,155,155, 11,179,217, 12, 65, 40,244,226,220,185,115,205, 5, 5, 5, 95, 81, 74,247,251,193,121, 74,161, 80,124, 62,109,218, +212,247,134, 15, 24,160, 66, 78, 6,178,111,222, 0, 49,228, 67,167, 86,162, 78,135, 24, 24, 50,121,204,217,244,135, 57, 53,223, + 48,143, 82,122,212, 15,206,139, 90,173,118,226,208,161, 67, 39,206, 92,181, 69, 13, 0,167,222,120, 30,217,123,254,128,182,118, + 61,180, 60,157, 6,179,217,140, 65,131, 6, 25,114,115,115, 63,245,182,162,187, 39,103, 89,192,157,147, 16, 50,132, 16,242, 82, +124,124, 60, 6, 15, 30,140,158, 61,123, 22,121,118,221,186,117,152, 55,111, 30,204,102,243, 75,132,144, 35,148,210,185,132,144, +221, 78,255,229,251,226,172, 92,185,114,211, 58,117,234, 32, 42, 42,202,224, 20, 23,157, 78,158, 60,217, 56, 62, 62,222,147,243, + 79, 39,167,253, 94,249,221,225,112,100,157, 61,123, 86,255,201, 39,159, 16,171,213,138, 9, 19, 38, 64, 18,154, 82,207,203,155, +111,190, 25, 21, 16, 16,128,241,227,199, 91,210,211,211, 31,251,248,227,143,127, 95,178,100, 73,216,183,223,126,219, 87, 18, 88, +238,156,162, 40,166, 30, 59,118, 44, 96,254,252,249,156,221,110,199,231,159,127,126, 75, 55,228,128, 1, 3, 96,181,218,192,243, +130,197,100, 50,215, 86,171,213, 23, 66, 67, 67,213,238,179,193,238,182,223,255,203,156,148,210,173, 0,182,250,243,158,201,100, + 66, 90, 90, 26,210,211,211, 17, 20, 20, 4,158,231, 73,113,238, 52,153, 76,127,141, 26, 53,234,240,130, 5, 11, 30,223,179,103, + 79,159,157, 59,119, 62,190,109,219, 54,211,213,171, 87,237, 54,155,141,150, 47, 95, 94,104,221,186,181,234,201, 39,159,212, 42, +149, 74,238,253,247,223, 79,159, 60,121,114, 24,128,140, 18,252,206, 19, 66, 48,162,109, 30, 70,181,231, 97,177, 20, 54, 40,111, +220, 72,196,201,147, 39,177,111,223, 25, 80, 74,185, 82,134,231,172,165, 75,151,198, 41, 20, 10,178,108,217,178,138,203,150, 45, + 27,238, 43, 28, 22, 47, 94, 92,121,217,178,101,115,157, 92, 34, 75, 75,140,147,161,148, 2,203, 89,248,156, 0,240, 56, 33,164, +245,235,175,191, 62, 61, 62, 62,222,108,183,219,101,155, 55,111,174,153,158,158,174,176,219,237,163, 40,165,165, 26, 16, 70, 41, +157, 79, 8, 65,143, 30, 61, 70, 85,169, 82,229,183, 35, 71,142,212,239,222,189,251,230,181,107,215,182,182,219,237, 23,143, 31, + 63,254, 18,128, 89, 0,190,240,151,211,108, 54,143,253,249,231,159,237,187,119,239, 30, 49,121,242,100,101,116,116, 52, 9, 14, + 14,198,245,235,215,113,229,202, 21, 58,115,230, 76,179,209,104,252,194,100, 50,141,245,151,211,106,181,126,180,241,183, 63, 84, + 71,255, 62, 54,228,221, 23,158,215, 85,174, 81, 19, 90, 82, 3,249, 25, 25,216,254, 71, 18,102,110,221,145,151,152,155,255,157, +213,106,245,155,211, 96, 48,124,190, 98,197, 10,126,251,246,237, 99,190,252,242,203,128,184,126,175, 17, 93,108, 21,136,113, 53, +177,121,243,102, 58, 98,196,136,188,220,220,220, 79, 11, 10, 10,166,220,235,132, 32,173, 89, 37,138,162, 0, 0,106,181, 26,195, +134, 13,131,251,214, 56,243,230,205,131,209,104, 4, 0,129, 16,242, 9, 33,228,187,226,172, 86,197,112, 86,252,229,151, 95, 42, +186,115,198,199,199,123,227, 52,223,107,255,103,102,102,142,125,226,137, 39,166, 10,130, 16, 84,220, 51,193,193,193,210,146, 31, +142, 27, 55,110,156, 9, 14, 14,134, 76, 38, 3,165,212,107, 62,202,200,200, 24,251,244,211, 79, 79,226, 56,174, 88, 75,135, 94, +175,191,250,251,239,191, 87, 27, 56,112, 32,247,253,247,223, 95,122,237,181,215,148,191,255,254,187,227,118,215, 52, 98,184,123, +112,159,176, 80, 80, 80, 0,135,195, 65, 75,120,246, 26, 33,100,212,225,195,135, 85,131, 6, 13,106,252,194, 11, 47,232,219,183, +111,175,115,127,198,104, 52,138, 63,253,244, 83,193,252,249,243, 51,118,238,220,249,231,128, 1, 3,122,161,112,252,136, 87, 92, +187,118,237,231, 41, 83,166, 4, 62,249,228,147,213, 1,184,198, 95,165,165,165,225,234,213,171, 56,126,252,248, 85,171,213,186, +161,148,222,122,179, 95,191,126,191, 44, 92,184,176,210,235,175,191,158,184,124,249,242, 13, 0,114,188, 60,167,235,221,187,119, +247,133, 11, 23, 86,122,227,141, 55,174, 1, 24,206, 86,120,103, 96,184, 3,129,229, 86, 88,236, 6,208,130, 16,210,131,231,249, +145,249,249,249,159, 83, 74,215,223, 65, 65, 53,159, 16,178,249,252,249,243,175, 1,104,242,249,231,159,143, 6,112, 29,133, 38, +244,206,222,198, 43,248,224,115, 0,248,128, 16,178,230,173,183,222, 42,147,189, 8,157,133, 71, 2, 33,100,229,136, 47,230,141, +161,148, 54,229,169, 24,234, 32, 92, 38, 33,228,144,201,100,154, 70, 41, 61, 84, 74, 78, 10,224, 99, 66,200,250,231,158,123,238, +129,222,139,208,108, 54,219,123,245,234,245, 45,199,113,162,211,194, 35,152,205,230,254, 40,197,204, 83,111,156, 61,123,246,252, +158,231,121,187,211,194,195,153,205,230, 87,239,132,179, 12, 43,207,124, 0, 67, 75,122,166,110,221,186, 75, 54,108,216,208,175, +123,247,238, 14,171,213,154,218,173, 91, 55,225,192,129, 3,148,227,184,109,197,112,154, 81,204,142, 4, 18,202,149, 43, 87,105, +206,156, 57, 71,134, 15, 31,174, 95,182,108, 89,200,238,221,187, 29,179,103,207,206,205,204,204,252,140, 21, 79, 15, 22,100, 50, + 25, 52, 26, 13, 44, 22, 11,210,210,210,224,107,201, 41, 74,233, 5, 66,200, 83, 35, 71,142,108, 51,114,228,200,167, 98, 98, 98, +106, 87,172, 88,177, 34,199,113,220,205,155, 55,211,174, 95,191,126,197,106,181,254, 6,224,103, 0,242, 42, 85,170,252, 5, 96, + 73,113,124, 25, 25, 25,147, 8, 33,127, 44, 94,188,248, 41,173, 86, 91, 75,165, 82,133,216,108, 54, 46, 47, 47, 47,211,104, 52, +158, 50,153, 76, 27, 41,165,123, 75,153,238,207, 18, 66,218, 11,130,240,243, 55,223,124, 19,127,243,230,205,202, 59,118,236,232, +230,249, 92,227,198,141, 23, 46, 92,184,176,210,224,193,131, 47, 44, 91,182,172, 84, 99,176, 24, 24,152,192,242, 47, 51,174, 7, +176,190, 44, 62,236, 28,248, 56,214,121,148, 85, 37,121, 12, 64,191, 50,174,120,143,162,140, 7,104, 58, 11,167, 33, 15, 88,235, +220, 76, 8, 25,233,156,213, 4, 0, 35,255,250,235,175,185, 30, 22,169,191,221,239,251,178, 52,121,227, 60,122,244,168, 39,231, +241,210,112,222, 79,100,103,103,255,111,206,156, 57, 7, 19, 18, 18,148,175,188,242, 10,142, 31, 63,142,105,211,166,153,179,179, +179,151,221, 46,103,114,114,242,213,114,229,202, 53,154, 57,115,230,136, 25, 51,102,244, 32,132,176,189, 8, 31, 16, 24,141,198, +139,245,235,215,151,246, 79,165,118,187,221, 53,251,211,185, 34,255, 69, 63,242,149, 29,192, 31,206,195, 23, 62,241,131,111, 31, +128,125,101,156,247,175, 17, 66,158,186,114,229,202,148,179,103,207,110,242,246,204,137, 19, 39,214,117,238,220, 89,179,111,223, +190, 49,165,157, 69,200,192,192, 4, 22,195,127, 30,206,241, 79,223,185, 89, 95, 74,117,255, 94,113,222, 47, 36, 38, 38,102, 1, +112,109, 25, 18, 23, 23,119,203, 56,181,219, 21, 89, 40, 92,181,157,173,220,254, 0,225,210,165, 75, 79,252,135,242,254,181,146, + 26,167, 22,139,101, 3,128, 13, 44, 85, 48, 48, 48,129,197,112,251, 5,173,249, 78,238,223, 43, 78, 6, 6, 6, 6,134,135, 3, +132,144,215,125,212, 17, 95,253, 43,253, 5,160, 99, 49, 30,218, 86,138,192, 41,245, 70,155,190,248, 25, 39,227,100,156,140,147, +113, 50, 78,198,249,240,113,250,226,118,127,159, 16,242,250,191, 85, 96,129, 82,122,215, 14, 0, 29, 25, 39,227,100,156,140,147, +113, 50, 78,198,201, 56,111,243, 59,175,223,139,239,220,141,131,109, 40,203,192,192,128, 46, 49, 36,184, 75, 12, 9, 46,238, 94, +235,138, 36,136,133, 18, 3, 3, 3,131,255, 96, 99,176, 24,254,117,120,230,153,103,248,210, 60,127, 57, 40,136,203, 73,172,248, +153, 78,163,236,102, 48,153, 63, 59,255,243,152, 47, 30,134,112, 40, 95,190,124, 77,189, 94,255, 34,128,218, 6,131, 33, 66,163, +209,164, 2, 56,153,155,155,187,228,230,205,155,126, 47,247,209,190, 50, 25, 39,202,240,190,243,255,228, 63,174,208,137,158,247, + 4,128,182,171, 76, 62,220,126,133, 78,247, 91,180, 85, 37, 38, 10, 40, 9,129,117,243,121,234,218,224,242,241,106,196, 36,210, + 91,175,119,169, 70, 44,148, 66, 78, 0,243,230, 11, 84,197, 82, 58, 3, 3,195, 67, 47,176, 20, 10, 69, 29, 74,233, 0, 66, 72, + 57, 66, 72, 50,165,244, 59,139,197,114,226,191, 22, 88, 10,133,162, 14, 33,100, 0,165,180, 28,165, 52,153, 16,114,159,195,129, +144,213,207, 20, 90, 33,251,172,130, 8,248, 88,152,231, 63,136,203, 65, 65, 92,206,141,138, 95,245,239,209,244,149,247, 6,180, + 71,163,103, 63, 31,133, 82, 44, 98,251, 32,130, 16,194,199,197,197,189, 89,169, 82,165,231, 22, 44, 88, 32,143,139,139,131, 74, +165,130,209,104, 44,127,241,226,197,242,131, 7, 15,126,180, 74,149, 42, 43, 46, 93,186,244,165,115,141,184,226, 69, 80, 12, 9, + 22,101,120,127,199,220,193,114, 0,120,116,240,188,113, 26, 25,161, 70, 59,140,106, 1,234, 38,209, 24,183, 99,238, 96, 30, 0, + 30, 29, 50,239, 35,133,140,240, 86,123,145,197, 48, 19, 41,165,171,188,113, 83, 64,177,113,241,167,232,254,210,187, 2, 33,100, +132,116,253,201,234, 32,155,150,206,194,227,207,255,175,200,245, 46, 85, 32,252,180,248, 83,116,125,233,221, 98,119, 27,127,188, + 58,103, 19, 69, 90,108,185,197,113,196,190,249, 60, 77,240,114,203,171, 59,187,198, 11, 41, 86,155,195,235, 66,176,114, 25,159, +186,241,180, 61,146, 16,242, 12,128, 24,127, 57, 25, 24, 24, 24, 74, 20, 88, 42,149,234, 81,141,146,255, 18, 34, 13,210,105,213, + 1, 11,190,250, 90,217,245,169,174,252,198,159, 55, 58, 6,189,254,250,192, 96,157, 58, 15,160,217, 38,187,253, 77,147,201,182, +195,159,143,133,135,135, 31,226,121, 62,198, 75, 31, 43, 40,165,176,219,237,137, 57, 57, 57, 77,238,212, 83,209,141,159, 77,177, + 89,173,197,174,158, 45, 8,178,212,164,191, 86, 69,250,195,165, 82,201, 30, 85,242,194,151, 0,130, 2,180,154,128,249, 95,125, + 85, 24, 14, 27, 55, 58,222,120, 99,224,192, 80,189, 38, 15, 28,201, 54,152, 29,111,154, 76,166, 29,247, 46,234, 8, 89,189, 26, +156,180, 66,215,234,213,224,250,244, 33,255,105,145,149,158,158, 78, 0, 32, 44, 44,140, 22, 17, 87,221,155,190,242,254,235, 29, + 48,249,171,223, 96, 52, 91,150,254,219,253, 25, 23, 23,247,230, 51,207, 60,243,220,164, 73,147,228, 28, 87,216,203, 95, 80, 80, + 0,163,209,136,232,232,104,108,223,190, 93, 62,118,236,216,231,214,173, 91, 7, 0,179, 75,195,205,243, 60, 57,117,250,100, 92, + 72,100,148, 37, 51, 37, 73,241,234,227,181, 93,219,193,200,100, 50,114,249,242,249, 42, 1,129, 33,174, 93,177, 3, 2, 2,124, +231,251, 16,189, 57,239,175,196,106,210,249,208,142, 49,142, 98,174,155, 1,168, 75,226, 18, 69, 42,108,249, 98,112,177,247, 7, + 77, 93,225,200, 59,124,173,154,231,245,226,220,105,181, 57, 34,138,227,235, 60,108,158, 84,134,196,228,229,229,249,205,201,192, +192,192, 80,162,192,210,200,249,175,254, 88,183,184,106, 82, 74, 58,150,173,221,132,154, 53,227,113,242,212, 41,212,172, 25,207, +119,104,211, 76,211,165,101, 3,141, 90,198,149, 27,248,254,167, 95, 1,168,230,103,225, 29,147,152,152, 24, 65, 8,129,195,225, +112, 45,218,103,179,217,144,159,159,143, 6, 13, 26,148,137,167,108, 86,107,196,197, 63,127,132,140, 39,176, 59, 40,108, 14, 10, +171, 93,132,213, 78,145,107,176,227,177,167,250, 69,248,203, 37, 35,220, 87, 63,175, 92, 88, 53, 53, 51, 7,107,127,217,250, 79, + 56,196,199,243, 93,218,183,209, 60,251,212,163,154,176, 64,109,185,167, 94,122,219,239,112, 40, 11,172,126,230, 31,113,229,126, +173,207, 42, 56,254, 75, 9,248,244,233,211,188,217,108,126, 94,175,215, 55,151,201,100,145,154,160,242, 98,182,188, 74, 70, 1, + 41,119,201, 90,160,104, 59,160,103,213,199,199,188,214, 14,147,191,250, 13,223,111,248,115, 97, 96,244,245,113,255,102,255,150, + 47, 95,190,102,165, 74,149,138,136, 43,105, 83,243,220,220, 92,228,229,229,129,227, 56,140, 26, 53, 74,190, 99,199,142,231,202, +151, 47,191,173,164,238,194,205,137, 52,171,125,101, 50,249,209,193,243,198,241, 60, 79,228, 65, 49, 71,198, 79,158,150,171, 82, +169,168, 86,171, 53,134, 86,140, 63,242,216,208,175, 26,137,162, 72,131,162,107, 30,156, 49,107, 78,158, 86,171,165, 50,153, 76, + 57,124,248,112,191,198,112, 26, 77, 70, 12, 27, 54,204,236,228,164,102,139,217,117, 61, 33, 33,193,117,221, 98,181,248, 29, 14, +151,146,243, 32, 23, 56,200,101, 60,228, 2, 15,117,185, 26, 80,228, 95,134,213,106, 45,194,233,175, 59,127,255,251, 6,212, 10, + 25, 52, 74, 1,213, 98, 99,160,164,198, 91,158,121,237,181,215,196,192,192, 64,171, 78,167,147,127,248,225,135,108,252, 42, 3, + 3,131,111,129, 69, 8,121, 20,192,118,167, 37,137, 20, 94, 67, 64, 96,128, 14,115,231,127,141,145,163, 63, 66,205,154, 53, 65, + 41, 5, 33, 4, 9, 31, 76,192,140,137, 9,120,238,137, 71, 1,160,216,102,156,183,169,154,132, 16, 92,190,124, 25, 38,147, 9, + 70,163,209,117,212,169, 83,199, 47, 7,251, 59,253, 83,198, 19,252,124, 36,175, 80, 88,217, 68, 88,237, 34,108,118, 17,237,235, + 4,148,146,147, 4,104, 52, 90,172,249,114, 46, 70, 77,252,164, 72, 56,140, 26, 61, 22, 95, 78,255, 0,111, 15,122, 25,132, 20, + 13,135,187,177, 9, 38,227, 44,138,189,123,247,150,215,104, 52,159,247,235,215, 47,106,248,240,225, 10, 42,104,133,205, 7,174, + 6,126,250,221,111, 81, 38,139,149,127,170,117, 21,188,218,179, 9, 38,127,253,135, 83, 92, 93,123, 61, 54, 59, 91,252, 55,251, + 93,175,215,191,184, 96,193,130, 91,196, 85, 74, 74, 10,151,159,159, 15,171,213, 42,230,229,229,193,225,112, 32, 33, 33, 65, 54, +118,236,216, 23, 9, 33, 19,157, 60,102,111,156,127, 92,161, 19, 53, 50, 66, 79,157, 62, 25, 55,118,194,164,220,167,159,126,250, + 60,199,113,144,201,100, 56, 89,190, 60,237,249,212,227,167, 39, 78,154,100, 30, 56,232,205, 19, 28,199,129,231,121, 28, 59,118, + 44, 14,128,198, 31,191, 19,128,186,115,126,247,251, 28, 10, 0, 28, 33,244,133, 23, 94, 56, 47,113,158,223,248, 49,245, 55, 60, + 5,158, 32, 38, 76,251,207, 23,148,106,192,185, 43,166, 59,167,191,238, 20,120, 14,205,107, 58,219, 93,209,141,128,196,221,183, + 54, 58, 53, 26,235,243,207, 63,127,254,236,217,179,126,251,157,229,119,198,201, 56,253,135, 55, 45,242, 48, 88,176,182,123,243, +140,213,108, 68,157,138, 33,152,255,217, 36,136,148, 3, 5, 5, 21, 41, 40,117, 32, 54, 76, 11,179,161, 0,165,237,143, 18, 69, +209,181,213,196,130, 5, 11,144,159,159, 15, 81, 20, 81,171, 86, 45,136,162, 24, 66, 8,249,219,237,241, 52, 74,105, 39, 95,156, + 17,245,122, 94, 5, 69, 69,247,107, 31,126,242, 45,246,254,117, 17,162, 8, 40,213, 26,244,121,241, 13,216, 29, 20, 22, 91,233, +246, 39,165, 16, 97, 54, 26, 16,165,147, 97,230,148,113, 32,130, 12, 60, 33, 32,132,128, 35, 34,106, 70, 7,193, 98, 50,220,243, +136,235,179, 10,226,234,213, 69,103,129, 22,142,195,250,239, 88,174, 52, 26,205,231, 75,150, 44,169,212,180,105, 83, 14, 0, 14, +158,203, 82,126,250,221,111, 81,223,142,239, 69, 26,213, 44,135,140, 28, 35, 38,127,179, 3,191, 31, 73,218,228, 41,174,254,197, +168, 29, 23, 23, 87, 68, 92,125,250,233,167, 97,115,231,206,141, 6,128,167,159,126,250, 70,135, 14, 29,210,207,158, 61,139,242, +229,203,147,244,244,244,167, 0,252,207, 89,120,141,164,148,206,245,106,101,178,195, 24, 18, 25,101, 81, 40, 20,144,132, 16,199, +113,224, 56, 14, 33,145, 81, 22,173, 62,216,226,121,189, 52,112,127,215,159,235, 62, 11,174, 18,158,191, 29,119,242,156, 91,241, + 39,120, 31, 2, 38,133, 77,105,221,202,192,192,224, 55,182, 63, 12,194,202, 83, 96,185,212, 35,165,116, 71,161,122, 4, 44,102, + 35, 98,130, 20, 40,167, 19, 96,179,217,177, 35,137, 71, 78,190, 9, 54,155, 21,169,201, 54, 28,188,113, 12,117, 27, 52, 14,111, +209,162, 69,158,205,102, 3,199,113,233, 7, 15, 30,140, 43, 65,241, 66, 20, 69, 88,173, 86, 88,173, 86, 20, 20, 20, 96,233,210, +165, 16, 4, 1,162, 40,226,131, 15, 62, 16, 40,165,245,164,231,149, 74,229, 49, 63, 85, 80,197, 11, 7,215, 32, 64,197,195, 46, + 82,216,237, 20,118, 17,176, 59, 40,140, 86,138, 94, 3,222,135,195, 65,225, 16, 41, 44,118,223,146,208, 93,176,169,171, 60,137, +238, 9,203, 1,232, 92,247,245, 74,138, 81,173,120, 40, 20, 50, 40, 20, 2, 76, 6,163,207,141, 95,203, 30,148,246,233, 67,196, +255,234, 32,119,179,217,220,183, 95,191,126, 81,146,184, 2,128,172, 92,179, 96,178, 88,249, 70, 53,203,161,211,115,239, 98,235, +138, 79,241,235,158,115, 8,214, 9, 59, 99, 30, 14,113, 5,131,193, 16,161, 82,169, 80, 80, 80,224,178, 92,205,157, 59, 55,218, + 98,177,112, 0, 32, 8,178,152, 52, 49, 90,229, 16,129, 64,253, 77,100,101,229,132,254, 99,149, 38,159, 16, 66,190,243,182,114, +190, 90,128, 58, 35, 37, 73,161, 84, 42, 77, 60,207, 67,178, 0,241, 60,143,204,148, 36, 5, 47,218,168,251,117, 65,240,127, 2, + 50, 33, 4,238,239,250,186,238, 87,193,197,147, 34, 5, 64, 17,177,116, 27,238, 20,120, 55,209,196,123, 23, 88,114,185,156,202, +100,178, 82,187,149,129,129,161,244,150, 44, 73,139, 60, 52, 2,203,105,154, 35, 82,161,101, 53, 26, 97,179,217, 97,183, 59, 96, +179, 59,144, 83, 96,197,119, 11, 23, 65,161, 80,128, 16, 2, 81, 20, 97,183,219,137, 40,138, 58,187,221,142, 71, 30,121,132,148, + 44, 9,104,145,113, 87,148, 82,240, 60, 15,153, 76,118,203,179, 86,171,181, 84, 30, 9, 80,241,136,237, 56,250,150,235, 7,214, + 76, 2,165,128, 67,116, 10, 44,171, 31,245,172, 15,193,214,160,109, 31, 88, 44,214, 66,139, 30,165,133,150,188,251, 34,109, 40, +253,175,141,185,114,179, 38,116, 28, 62,124,120,145,154, 48, 88,175,180,171, 20,114,199,145,211, 55,201,214, 21,159,114,135, 78, + 37,137, 10,153, 64,181, 52, 57,238, 97,241,183, 70,163, 73, 53, 24, 12,229,141, 70, 35,114,115,115,145,155,155, 91, 52, 67,203, +100,228,245, 65, 67,195,100,114, 5,108, 86, 11,126, 93, 50,217, 39,103,251,202,100, 92,147,104,140, 27,248, 68, 29, 4, 70,215, + 60,124,186, 74, 21, 81, 18, 40,127,254,186,184,213,186,153,111, 53,162,148, 34,239,250,177,131,173,122, 14, 60, 32, 8, 2,204, +102,179,223,203, 40, 80,128,156, 62,125, 58, 78,226,164,206, 50,134, 2,228,232,209,163,113,130, 32, 64, 16, 4,215,117,191,226, + 95,165, 1,116,229, 0,165,180, 60, 23,113,137, 54,119, 78,127,221, 89,187, 74, 20, 80,174, 30,160, 8, 44,246, 25,153, 76,166, + 56,118,236, 88,156, 40,138,108, 9, 9, 6,134,187,108,201, 66, 41,202,131, 7, 93, 96,181, 35,132, 80,143, 66, 17,102,147, 1, + 54,187, 3,118,155, 3,118,187, 29, 86,139, 21, 42,149, 10,122,189,222, 37,152,164, 35, 45, 45,205, 47, 81,100,183,219, 93, 22, + 44, 81, 20, 65, 41,197,249,243,231, 33,147,201, 32,151,203, 33,147,201, 32,147,201, 80,184,129,189,255,176, 59, 40,198,188, 55, + 2, 50,129,131, 92,224, 32, 19, 8,228, 2, 7, 7,165,160,160,176, 59, 10, 15,139,221, 63, 67, 70, 73,130, 13, 0,204, 22, 91, + 97,187,153, 2, 6,131, 1, 34,216, 10, 9,247, 10,233,233,233,196,104, 52, 86, 14, 10, 10, 42, 34,222,195, 53, 14,115,255,110, + 13,146,250,127,248, 99,148,197,102,135, 92,224,105,223,206,241, 73,191,173,221, 30,154,110,206, 38,210,236,194,127, 57, 78, 94, +184,112,161,124,133, 10, 21,144,155,155, 11,187,221, 46, 62,253,244,211, 55, 4, 65, 22, 35,200,100,164,235,243, 67,197,228,228, + 36, 27,199,241,160,212,129, 39,158, 25, 76,148, 42,181,220,106,177,216, 1,140,244,180, 94,185, 45,211,192, 3, 64,199,255,125, +211,232,153,167,123,158, 14, 8, 12,177,101,166, 36, 41,214,205,124,171,209,239,115, 94,231, 0,224,177,161, 95, 61,242,193,103, +223,157, 15,137,140,178,148,198,193, 42,165, 10,175,189,246,154,107,204,210,161,165, 99, 1, 0, 74,133, 18,207, 61,247,156,235, +250,111, 95,250,191,215,117,160,146, 2,249,201, 64, 65,178,167, 8, 42,194,233, 47,180,130, 29, 72, 62, 82,226, 51,206,129,237, + 26,150, 3, 25, 24,238, 26,110,209, 34,255,122,129,229, 52,197, 17,207,102,167,217,104,132,221,102,119,137, 44,139,165, 80, 64, +109,219,182,237, 22, 65,228, 79, 23, 25,165, 20,102,179, 25,113,113,113,176, 88, 44,136,143,143, 7,165, 20,213,170, 85,243, 42, +196, 74, 3,155,131, 98,202,244,207,110,185,190,123,213, 36,212,143,143, 69,179,106, 26,152,108, 34,114, 10,252,227, 45, 73,176, + 1, 40, 12, 11,167,184, 52, 22, 20,128,233,171,251, 7,155,205,134,172,172, 44,152,243,179,236, 53,202,209,156,215,186, 86, 49, +167,101, 26, 4,142,154,236, 49, 1, 6,115,126,230, 13, 94,163,121, 56,234,197,220,220,220, 37,131, 7, 15,126,116,231,206,157, +114,142,227,144,155,155,139,246,237,219,167,167,137,209,170,215, 7, 13, 13, 75, 74,186, 97,215,171, 5,179, 92, 46, 67,106,106, +170,248,232,147,253,140,207, 15,120, 43,234,173,247,167, 46, 72,218, 51,247,150,241, 87, 6, 14, 84,112, 75,189,118,135, 3, 19, + 39, 78, 52,235,131, 66,173, 28,181, 57,168, 91,198,166,148,210, 5, 95,127,101, 10, 9, 47,111,150,203,229,202,254,253,251,251, + 61,139, 48, 33, 33,193,172,209,104,168, 90,173,118,205, 22, 52,153, 77,152, 56,113,162, 89,171,213, 82,141, 70,227,215, 44, 66, +142, 35,246, 65, 83, 87, 56,220, 27,115, 82, 99, 76, 38,147,193,234, 32, 5,238,156,254,186,211,159, 89,132,195,134, 13, 19,131, +131,131,173, 1, 1, 1,242, 17, 35, 70,176,129, 88, 12, 12,101, 12,175, 90,228, 33,176, 96,221, 2, 17,133, 93, 95, 54,155,195, +217, 69,104,135,197, 98,129, 40,138,104,221,186,245, 45,207,103,101,101,249,180, 58, 57, 28,142,196, 90,181,106,185,172, 94, 14, +135, 35,100,236,216,177,194,213,171, 87,161, 80, 40,138,136,182,219,177, 96,141, 31,251, 46, 20, 50,222, 41,136, 10,133,145, 72, + 41, 54,252,188, 5, 27,126,222,226,122,150,231,101,169,119, 34,216, 0,192,108,182,129,210,194,154,201,152, 95,112, 31,198, 96, +253,119, 17, 22, 22, 70,211,210,210,174,100,103,103,215,208,106,181,200,200,200, 64,102,102, 38,178,179,179, 97,204,205,178,107, +237,217, 5, 22,123, 38, 4, 65, 64,242,245, 20, 56, 28,142,228,135,196,122,133,155, 55,111,158,169, 82,165,202,138, 49, 99,198, + 60,159,144,144, 32, 19, 69, 17,103,207,158, 5, 8,161, 50,185, 52, 64, 93, 64, 78, 78,174,168,209, 5,221,180, 82, 94, 35,147, + 43,192,241,114,175, 93,201,187,175,209,236,118,149,201,135,143, 14,153,247,145, 76, 46, 39,250,168, 26,251, 95, 25, 48,240,148, + 52, 72, 60,235,210,145,253, 29,255,247, 77, 51,135,195,129, 6, 45, 59,254,242,234,235, 67, 78,202,100, 50, 28, 58,116, 40,206, +151, 53,135, 0,246,158,175,140,226,117, 58, 77,254, 11, 47,188,112, 94,226,188,188,245,203,252,151,135,142, 3, 47, 83,230, 15, + 28, 56,208, 53,187,240,212,250, 79,242,123,190, 50, 74, 73, 80,124,183,247,230,243, 52, 33,239,240,181,106,239,190,251,174,249, +149, 87, 94,113,113, 30, 59,118, 44,238,233,167,159,214,124,248,225,135,102,119, 78,127,220, 9,248, 55,139, 80,171,213, 90, 95, +125,245,213,243,222,102, 38, 50, 48, 48, 48,248, 45,176, 64, 81, 40,176,236,118,216,109,133, 99,176,108, 54, 27,236,118, 59,254, +252,243,207, 34, 98, 72, 46,151,251, 53,179, 38, 51, 51,179,200, 34,162,132,144,191, 41,165,245, 42, 87,174,236, 18, 40, 99,198, +140,193,132, 9, 19, 74, 61, 83,199,230, 0, 38, 76,254,204,197,243,100,167, 54,232,241,196,163,160, 98,161, 80, 75, 61,190,174, + 84,138,173, 36,193,230,178, 96,129, 2,148, 34, 63, 47,143, 25,176,238, 49, 44, 22,203,182,217,179,103, 87, 30, 59,118,172, 34, + 51, 51, 19,233,233,233,200,202,202,114, 29,249,249,249, 40, 87,174, 28, 54,109,218,100,205,205,205,221,255, 48,249,253,210,165, + 75, 95,110,216,176, 1, 59,118,236,120, 46, 33, 33, 65, 86,174, 92, 57, 18, 24,152, 66,108, 86, 11, 0, 74,211,210,210, 68,141, + 46,232,102, 88,100,204,181,164,228,212,120,155,213, 2,209, 97, 45,118,100,246,246, 43,116,186, 66, 70,248,203,151,207, 85,153, +254,201,231,249,146,104,145,201,100,104,217,253,213, 67, 31,206, 90,124, 97,198,140, 25,150, 65, 67,134,157,148,238,249, 51,208, +123,203, 69,140,206,203,203,169,246,254,251,239,155,221, 57, 31,123,227,211,101,189,122,245,210, 76,153, 50,197,236, 62,227,175, +219,136,249,203, 58,116,232,160, 9, 8, 8, 56,239,139, 91,106,144,121,206, 66,244,156, 5,233,239,128,116,127,103, 17, 2, 40, +213, 0,127, 6, 6,134,255, 46,184,226,245, 21,205, 79, 76, 78,129, 32, 87, 3,188, 12, 14,135, 8,139,197, 2,135,195,129,166, + 77,155,162, 65,131, 6,168, 85,171, 22, 22, 44, 88, 0,141, 70, 3,142,227,110,177, 58, 17, 66, 58,250,114,128, 40,138, 48, 26, +141, 48,155,205,176, 90,173,152, 56,113, 98,137,133, 98,113,156, 5,102, 7,246,172,156,136,221, 43, 63,194,206, 21, 31, 97,100, +255,142,168, 18, 33,247,107,214,160, 55, 78, 73,176,141,254,112, 58, 70,188, 63, 21, 91,126,223, 13,158, 39, 46,193,166, 10, 8, +134,160,208, 2,130, 2, 55, 82,210, 64, 69,154, 95, 90,191,151, 22,140,243, 31, 40,149,202,101,203,151, 47, 79,218,181,107,151, + 24, 21, 21, 5,142,227,144,159,159,143,252,252,124,201,202,133, 83,167, 78,137, 87,175, 94,189,161, 84, 42,151, 63, 76,126,167, +148, 58, 46, 94,188, 56, 59, 57, 57,249,213,113,227,198,109,123,225,133, 23,228, 63,206, 31, 27,250, 98,151,234,216,190,105, 53, + 33,170,144, 2, 11,149,171, 18,111,166,212,252,253,231,165, 33, 47,118,169,142,228,125, 11,222, 32,132, 12, 41,142,211,106,135, + 37, 32, 48,196,166, 86,171,169,231, 50, 7, 1,129, 33,182,128,192, 16,139, 55, 65,227,143,223,189,113, 2,128, 74,165,162, 15, + 10,167, 63,179, 8,149, 74, 37, 45,173, 59, 89,126,103,156,140,147, 89,176,110,129,217,108, 31,242,193,130,245,115, 1,162,147, +134,104, 84,140,171, 22,110,181, 90, 73, 74, 74,138,203, 82, 36, 8,194,109,173, 99,227, 68,154, 86,171, 45,105, 41,134, 52,255, + 98, 26,215,154,180,127,182, 98, 73,247, 75,235, 48, 73,176,137, 20, 16, 11, 13, 85,160, 32, 46,193,246,233,154,223, 82,157,137, + 12, 0,201,183,217,197, 33, 44, 57,221, 59,196,199,199, 59,246,238,221,251,206,224,193,131, 63,239,208,161, 67,116,143, 30, 61, +228, 21, 42, 84,128, 82,169,196,197,139, 23,177,107,215, 46,235,165, 75,151,110, 24, 12,134,119,234,215,175,255, 80,206,180,188, +121,243,230, 25,231, 34,162,255,147,150, 98, 80,170,212,242,190, 3,222,138,113,205, 34, 92,241, 37,204, 38, 35, 0, 8, 37, 45, +211,224, 42, 16, 4, 65, 33,205,194,227, 56, 14, 22,139, 69, 37, 93, 63,116,232, 80,156,180, 4,130,116,221,175, 66,230, 95,192, +233,207, 44, 66,185, 92,174, 56,124,248,112, 28,165,108, 35,106, 6, 6,134, 59, 17, 88, 54,219, 54, 0, 85,221,175,213,170, 85, + 43,169, 73,147, 38,129, 64,225, 98,126,162, 40, 22, 17, 86, 60,207,231,149,230,227,254, 44, 34,234, 15, 82,143,173,171, 84,182, +210,220,183, 96, 43, 48,219, 42,177,228,115,127,209,178,101,203,155,167, 79,159,238,183,117,235,214,190, 59,119,238,236,104, 48, + 24, 42, 19, 66,160, 86,171,175, 88, 44,150,109, 74,165,114,217,195, 42,174,138,131,213,106,181, 39, 76,248,116, 17, 47,200,237, +162,104, 37, 86,171,117, 0,252,220,212, 29, 0,222,123,239, 61,175, 51,229,134, 13, 27,118,219, 51,232,254, 13,156,254,204, 34, +124,231,157,119,216, 44, 66, 6, 6,134, 59, 23, 88,222,112,234,212,169,168,255, 66,160,148,185, 96, 99,184,107,136,143,143,119, + 0, 88, 2, 96,137,231,102,207,255, 5, 80, 74,205,132,144,145,132,144, 79,156,151, 70, 94,250, 99,150,107,182, 32, 33,179,143, +185,223, 43,193,122,149,120,155,155, 23, 39,150,116,239, 65,231,148,203,248, 84,183, 77,157,111,185,231,227,155,137, 44, 7, 50, + 48, 48,148,137,192, 98, 96,120, 16,176,106,213, 42, 7, 11,133, 34, 34,107, 46, 33,228, 59, 73,112,249,123,207,227,185, 85,119, +193, 93, 15, 60,231,198,211,246,200,251,225, 15, 6, 6, 6, 38,176, 24, 24, 24,254, 29, 34,203,124, 59,247, 24, 24, 24, 24, 24, +238, 14, 8,128,142,197, 20,202,126,239,148,125, 59,179, 9,124,241, 51, 78,198,201, 56, 25, 39,227,100,156,140,243,225,227,244, +197,237,254, 62, 33,228,117, 74,233, 87,255,214,150,239, 93, 59, 0,116,100,156,140,147,113, 50, 78,198,201, 56, 25, 39,227,188, +205,239,188,126, 47,190,115, 55, 14,182,221, 3, 3, 3, 3, 3, 3, 3, 3, 67, 25,131,141,193,242, 19,164, 82,207,177, 16, 49, +166,240, 4, 31,211,107,235,198,179, 80,185, 61, 52,212,145, 48, 27,145,117, 13, 80,201,186, 87, 14,144,181,184,152,109,222,107, +176,138, 63, 81, 98, 91,127, 50,151,102,177, 16, 98, 96,184,251, 8,142,107,213, 47, 52,172,220, 27, 34,165,106, 0,176, 88, 76, +182, 27,215,175,205,162, 89, 39, 87, 20, 41,251, 66,106,245, 41, 23, 21, 51, 76,173,210,170, 11,139, 63, 98,201,204, 72,158,155, +117,105,207, 15, 94,203,202,127, 86,156, 14,186,112,225, 66,165,170, 85,171, 94, 5,144,237,241,216, 45,247,104, 9,251,141, 17, + 66, 72, 88, 92,163,151, 52, 42,205, 16,139,197, 18,171, 11, 8, 72,205,204, 72,155,159,121,237,216,151,110,143,233, 15, 28, 56, + 80,190, 89,179,102, 73, 0,242,124,113, 50, 48, 60,240, 2,171,105,211,166,177,162, 40,190, 12,224, 5, 74,233,209, 35, 71,142, + 60,125, 59, 60,205,154, 53,139,118, 56, 28,143, 80, 74, 27, 1,104,164,214,232, 26,154,205,166, 84,209, 97,127,233,240,225,195, +127,149,150,175,113,227,198, 63, 3,120,178,152,204, 58,225,208,161, 67,165, 19, 72, 34,125,255,207,157, 63, 42,131, 52, 4, 85, + 27,247, 30, 5,224,129, 20, 88,132, 16, 53,128, 87, 8, 33, 29, 52, 26, 77,117,131,193,112,133, 82,122, 12,192, 92, 74,105,210, +109,114,114,117,116,178, 87, 53,106,205,227,229,181,138, 70, 55,179,115,111, 24,108,226, 46,145, 88, 63, 41,173, 32,170, 74,136, +162, 74,133,160, 29, 35,122,180,137,175, 31, 95, 5,142, 19, 59, 97,177, 90,187, 31,186,105,232,190,224,175,148,119,170, 18,210, +232, 2,165, 22, 63,221, 85, 30,128, 64, 41,189,238, 60, 15, 6,208, 6, 64, 3, 0, 71, 1,236,162,244,206, 4,219,191,133, 51, + 38, 38, 38, 74, 20,197,215, 34, 35, 35,159, 74, 73, 73,249,153,227,184,111, 18, 19, 19,147, 88, 17,199, 80, 28, 66, 66,203, 13, +153,243,221,106,215,178,245, 84, 20,101,207,247,104,247, 34,128, 34, 2, 43, 40, 40,244,149,239,151,253,170, 38,255,172,121,168, + 24, 58,160,207, 27, 0,126,240, 38,132, 40,165,152, 48, 97, 2,153, 56,113, 98,255, 42, 85,170, 84,227, 56,238,236,184,113,227, +102,185, 63,231,121,239,195, 15, 63,164,206,119,169, 55,206,152, 26, 45,215, 63,247,252, 51,237,222,124,253, 21, 93,116,184, 14, + 55,211, 11, 66,231,125,187,228,211, 37, 75,126,232,250,218,115,157, 30, 7,128,143, 62,250,168,103,133, 10, 21, 42,243, 60,127, +249,131, 15, 62, 88, 92, 18, 39, 3,195, 3, 43,176,106,215,174,173, 85, 40, 20,125, 56,142,123,165,126,227, 22,173,187, 63,243, + 10,177, 17, 13, 38,191,219,215, 94, 90,174,118,237,218, 41,243,243,243, 39,197,214,108,252,118,187,206, 61,184, 90,241, 53, 17, + 22, 26, 12,145, 83, 96,225,166,115,161,219, 23,244,159, 11,160,217,109, 56,243,201,149,191, 28,192,205,108, 7, 8, 1, 8, 1, + 56, 2,228,155, 68,140, 25,208,250,195,210, 11, 36,194, 5,105, 8,222, 94,102, 2, 0,254, 65,140, 76, 66, 72,163,240,240,240, + 47,135, 15, 31, 30, 92,175, 94,189,242, 42,149, 74, 99, 52, 26,171, 93,184,112, 33,118,236,216,177,157, 8, 33,211, 40,165, 63, +150,134, 51, 62, 72, 85,241,137,154,149, 86,190, 55,232,149, 71,106, 84,174, 0,193,156, 15,209, 92, 80,225,234,165, 11, 45,166, +124,255,227,192, 58,129,178,231, 79,228,216,252,158, 16,161, 10,144,191, 63,230,213,190,241, 85,181, 20,150,227,123, 32,227,121, +168,244,193,104,198,243,224, 8,173,245,225,174, 27, 99, 0,124,232,135, 95, 39, 2, 24,227, 44,127,127,228, 56,238,108,199,142, + 29,235, 15, 28, 56,144, 52,104,208, 0, 71,142, 28,105,184,124,249,242, 1, 60,207,255, 45,138,226, 31, 0,246, 83,255,133,155, + 2, 64,115,142,227,218, 63,200,156, 81, 81, 81,106,139,197,242,114, 76, 76,204,235,221,187,119,175,215,173, 91, 55, 82,163, 70, + 13,156, 57,115,166,241,175,191,254,250, 97,131, 6, 13,142, 37, 38, 38,126,165, 80, 40, 22, 37, 37, 37, 25,253,225,252, 63,123, + 87, 29, 30,197,241,191,223, 57,247,248,197,133, 64,136, 64,208,224,238,110,165,184,151, 22,105, 11, 45, 82,188,184, 21, 43, 94, +164, 20,247, 22,183,226, 82, 60, 72, 32,144, 64,136, 16,119,185, 92,206,111,231,247, 7, 9,223,144, 70, 46,129,254,218,210,125, +159,103,159,189,155,221,125,119,108,103,223,253,204,204,103,250,215, 32, 97, 7,158, 80,255,138, 30, 47,146,102, 27, 0, 18, 75, +132, 61, 33,196, 9,128,140, 82,250,234,255,155,243, 47,122, 22,159, 17, 66,236,242,127,163,180, 61,135,195,129,201,100, 82,155, + 76,166, 42,101,112,250, 1,229, 26,214, 65, 41,165, 97, 37, 30, 4, 21, 2,192,226, 57,147, 17, 31, 27, 3,141, 86,173,201,202, + 74,223, 81,244,188,172,204,140,221,159, 15,238,246,141, 80, 40,230,187,121,120, 97,198,188, 21, 40,176,122, 21,135,121,243,230, +145, 57,115,230, 96,238,220,185,221, 1, 52,103, 24,230,122, 64, 64,192,218,119,190, 87, 25,230,237,177, 57,115,230,172,153, 55, +111, 30, 1,138, 95,210,213,174, 82,237, 33,159,124,210,179,213,162,153,227,228,241,233, 6, 60,138,210,192, 78, 46,192,156,239, +198, 10,117, 58, 99,227,141,187,118,143, 90,191,116,234, 86,179,217,220, 6, 64, 61,179,217,124, 31,192,174,210, 56, 89,176,248, + 71, 9, 44, 66, 8, 9, 10, 10,106, 65, 41, 29, 94,169,178, 79,159,222,131, 70, 75, 42, 85,173,129, 92,198, 10, 81,105, 12, 30, + 92,222,135,162, 95, 62, 22, 88,191,234,113, 56,220,157, 99,167,173,242,175, 85,167, 62,158,196,155,240, 71,172, 25,121,175,204, +224,114, 52, 96, 24, 0,128,182,162,137,139,203, 52,225, 70,184, 30, 28, 2,112, 57, 0,135, 67,192,173,232,168, 51, 70,255, 98, +193,246, 7,129,105,201, 12,192,232, 95,252, 3,197, 85, 27, 95, 95,223,213,243,231,207,119, 78, 78, 78,182,187,127,255, 62, 68, + 34, 17,108,109,109,121,174,174,174,254,171, 87,175,206, 30, 55,110,220,119,132,144,135,148,210,104,139,132,180, 92, 24,208,178, +110,224,205,217,115,231, 88,235,239,156, 65,230,190, 67,224,114, 40, 4, 50, 57, 92, 37, 18,172,237, 80,201,110,234,165,216,223, +106, 74, 36, 1, 33, 26, 77,188, 37,156, 30,142,118, 29,170,250,249, 35,243,200,122,188,204,209,225, 86,170, 14, 61, 91, 54,128, +143,157, 4,181, 77,102,216,139,121,109,202, 18, 88,249, 22,160,169,122,189,158, 35, 16, 8,136, 88, 44,238,115,242,228,201, 75, + 1, 1, 1,111,235, 74,179,102,205,208,172, 89, 51,178,108,217,178,218,151, 46, 93,170,189,123,247,110, 3, 33,228, 6,165,116, +117, 73,188, 18,137,244,181, 86,171,241,144, 72,165,250, 77, 63,253,116,177,105,211,166,180, 96,129,223,138,114, 2,128,181,181, +245,111,129,129,129, 14, 83,166, 76, 81, 53,105,210,228,131,112,122,123,123,255,222,188,121,243,214, 29, 58,116,224, 53,109,218, + 20,174,174,255,243, 1,236,224,224,128,230,205,155,147,216,216,216, 90,215,175, 95,223,248,251,239,191,175,245,246,246,190, 28, + 21, 21,213,161,204, 55, 50,224,247, 62,199,139,128, 11, 96, 49, 33,100, 43,165,244,143,210, 62, 12, 0, 12, 2,240,195,223,196, + 89, 42, 36, 18, 73,178, 86,171,117, 4, 0,177, 88,156,162,209,104,156, 44,120, 30,229,155, 55,111,118, 20, 8, 4,224,112, 56, + 48, 26,141, 48,155,205,111,247, 5, 27,195, 48, 48,155,205, 88,180,104,145, 69,190,221, 40,165,106,188,153,253, 77, 11,109, 76, +113,123,161, 80,232, 96, 9,103,124,108, 12,180,241,183,211,229, 50,153,151,220, 30, 11,124,125,125, 23, 20, 62, 94,213, 1,128, +246, 21,212,105,234,152,120,192,190, 12, 58,155,249,243,231, 15,155, 59,119,110, 79, 0,234,252,176,154,125,251,246,189, 92,228, +188,154,249,123, 53, 33,228, 10,135,195, 57, 1, 96, 59,128, 63, 89,114,165, 82,249,232,241, 95,126, 46,143, 75, 51, 96,225,111, +105,216,126, 45, 7,195,154, 43, 48,161,179, 53, 6, 13,236, 47, 59,244,235,225,209, 0,182, 22,186, 36, 44, 32, 32,128, 60,127, +254,156, 21, 87, 31, 23,234, 3, 80, 22,250,175, 7, 80,208,152,166,229, 63, 23,246, 69,194, 11,159, 87,176, 47, 88,130, 79,153, +127, 29, 45,196,155, 10,224,222, 7, 21, 88,249, 86,212, 2,107, 42, 41,238,196, 58,117,234,156,238,252,201,208, 78,141, 90,116, +128, 73,224,136,176, 20,130,216,104, 10, 30,199, 4, 46, 24, 68,222, 59, 70, 57, 28,206,206, 34,141, 65,137,150,141,160,160,160, + 73,149,124,235,254, 48, 99,238, 18,238,147,100, 33,182, 95,215,128,209,101, 35, 47, 45, 2,234,148, 23, 80, 37, 61, 67, 86,252, +147, 16,134, 97,230, 88,202,249,231,198, 8, 48, 51,249,223,124, 76,254,235, 1,164,184, 70,171,108, 78,131,250,121,101,191,192, +192, 76,161, 25, 48,168,159, 91,208, 16, 94,248,208,181,171, 36, 78, 66, 72,123, 31, 31,159,229, 51,103,206,116,127,250,244,169, +149, 90,173, 86,159, 57,115,230,106, 76, 76,140,147,179,179,115,236,216,177, 99,155,184,185,185, 57,126,242,201, 39,210, 3, 7, + 14,204, 4,240,121, 89,156, 53,100,194,192,230,245,107,220, 90,184,108,165, 44,237,208, 58,232, 35, 30,227, 86,154, 6, 33,233, + 26,234,166,200, 34,253, 2,236, 32, 21,242, 48, 58,200, 73,254,205,185,168, 31,242, 95,102,101,166,221,219,197,169,138, 81,147, + 7,173,198,136,211,175,178, 53,183,114,178, 29, 57,143, 95,167, 78,233, 94, 95,204, 77, 77,128,179,156, 95,181,188,249, 73, 8, +129, 84, 90,252, 10, 38, 54, 54, 54,104,213,170, 21, 2, 2, 2, 4, 45, 91,182,108, 3, 96,117, 73,156, 6,131,222,133, 97, 40, +172,172,172, 4,157, 58,117, 34,132, 16,170,215,235,223,139, 19, 0,236,236,236, 58, 54,107,214,140,251,235,175,191,230,102,100, +100, 68,119,237,218, 53, 77, 44, 22, 51,133,207,145,201,100,240,245,245,197,247,223,127, 47,232,220,185,115,153,156, 78, 78, 78, +237,119,239,222, 13, 66,200,219,151,117, 81,120,121,121,193,217,217, 25, 93,186,116,225,125,250,233,167,237, 75,203,207,254, 53, + 72, 88,129,120,234, 87,131,148,250, 98,234, 87,131, 80, 2,132, 23,181,100, 21,229,164,148,166, 19, 66, 54, 1, 56, 66, 8,233, + 83,156, 32, 34,132, 52, 5,112, 24, 64,103, 74,105, 74, 89,229, 94,152, 83, 40, 20, 10, 12, 6,131,109, 81,225, 83, 94,206, 66, +113,161,193,193,193, 8, 10, 10, 66,225,189, 86,171,125,187,246, 42, 33,196,209,210,250,201,225,112, 48,107,214, 44, 16, 66,192, +231,243, 33, 16, 8,138,221,183,106,213,170,188,109, 72, 44, 33,132, 35, 16, 8,166,242,120,188,207,117, 58,157,187, 88, 44, 78, + 48,155,205, 59,116, 58,221, 34, 74,169, 17,128,141,193, 96, 40,149, 83,163, 85,107, 40,195, 72,244,122,173, 81, 38,147,121,189, +120,241,194,183,164, 50,215,233,116,168, 89,179, 38,114,181,234,212,130,107,138,227,140,136,136,240,170, 82,165,138, 31,222,116, +129, 3,192, 53, 74,105,139, 66,255, 11,227, 26,165,180,115,254,239,240, 87,175, 94,121, 21, 8,172,194,156, 70,131,193,219,221, +209, 10,143,162, 53,216,126, 45, 7, 23,103,186,162,237,162, 4,244,174,203, 67,128,167, 28, 38,131,209,175,111,223,190, 59,241, +166,254,222, 3,208,171,111,223,190,254, 92, 46,247, 18,128,163, 0,178,255,191,219,100,150,179,194,134,130,210,180,136,146, 16, +114,178,208,253,187, 21,252,159, 54,109,218,140, 37, 75,150, 60, 37,132,156, 44, 28, 94,248,188,194,251,252,123,157,164,148,118, +155, 62,125,122,224,210,165, 75, 23, 23,156,251,183, 88,176, 0, 88,197,105,108,144, 27,229, 0, 30,151, 1,143, 67,192,227, 2, +160, 4,201,113,207,160, 87,167,223,184,127,255,126,148, 37, 68, 65, 65, 65, 77, 43, 7, 54, 90, 54,119,225, 10,206, 47,215, 52, +200,206,211, 34, 45,244, 56, 18,239,108, 75, 98,204,134,163,148,210,251, 28, 14, 39,216,187, 82,165,176,247,241,218,253, 70, 96, +229,139,170,119, 68,214,199, 3, 66, 72,103,127,127,255, 37,179,102,205,242,122,248,240,161, 34, 39, 39, 39,117,207,158, 61, 97, + 58,157,238, 33,128, 53,175, 95,191,110,185,102,205, 26,233,138, 21, 43, 58,212,168, 81,195,239,224,193,131,121,101, 90,174,100, +130, 90, 67, 7,245,191,213,115,204,120,113,232,193, 13, 16, 61, 11,198,230, 23,153,230,251,169,154,153,218, 92,211,106,137,148, +215, 52, 83,103, 58, 63,185,161, 43,199, 69,198,135,135, 21,191,149,165,241, 21, 10,197, 60,202, 19, 67,175, 55, 65,109,100,244, +161,169, 84, 61,177,101, 77, 3,149, 57,188, 89,172,151,195,225, 89,240, 96,103, 18, 66,126, 16, 10,133,179, 8, 33,180,103,207, +158,209,117,235,214,213, 2,128, 70,163,129, 78,167, 3,159,207,135, 86,171, 69,100,100, 36,110,223,190, 13, 91, 91,219,114,229, +107,102,102, 38,188,188,188, 32,151,203,223,155,211,108, 54,147, 13, 27, 54, 8,159, 62,125, 42,252,245,215, 95,173, 38, 79,158, +172,110,216,176, 97, 76,215,174, 93, 83,172,172,172, 76,143, 30, 61,194,173, 91,183,144,149,149,133, 6, 13, 26, 88,196,169,215, +235,193,227,241,160,209,104, 32, 18,137,192,227,241, 96, 50,153,192, 48,204, 91,209,149,155,155,139,140,140, 12, 8, 4, 2, 20, + 39, 20, 11,163, 64, 44,245,171, 65,232,193,211, 55, 83, 0,134, 66,175, 50, 66,159,109,132,174, 96,203, 52,246,155,176,178,246, +193, 39,197,127,132,149, 80, 86,183, 9, 33,125, 0, 28, 46, 42,178, 10, 9,161, 62,148,210, 71,229,229, 52, 24, 12, 55, 10,132, +143, 88, 44,118, 36,228,141, 48, 20,137, 68, 70,157, 78,215,186, 60,156, 0, 16, 28, 28,140,186,117,235,114,243, 57, 11, 15,221, + 97, 42,240, 92,130,203,229, 66, 32, 16,128, 16,130, 22, 45, 90, 96,228,200,145,168, 91,183, 46, 34, 34, 34,176,127,255,126,220, +187,119, 15,124, 62,255,237,249,150,162, 85,171, 86, 92,177, 88,124,179, 71,143, 30,129, 51,103,206, 20, 87,170, 84, 9,207,158, + 61,243, 92,186,116,233,212, 11, 23, 46,244, 36,132,212,163,148,150, 25,231,164,132,184,117, 3,122,182, 26,158,149,153,177,187, +170, 3,230,234,116, 58, 60,123,246,204,226,107,138, 59,238,227,227, 19,195,225,112, 94, 50, 12,115, 29, 64, 77, 74,105, 11, 66, +200, 25, 0,178, 34,167,170, 41,165,157, 9, 33, 57, 0, 66, 56, 28, 78, 56,195, 48, 49,197, 13,151, 82, 40, 20,169,113, 41, 57, + 78,246,114, 49,134, 54,147,163,237,162, 4,244,169, 39,130, 72, 64, 16, 22,149, 4,159, 42,149,200,163, 27,199,234,229,139,171, +250,137,137,137, 0, 80, 15, 64, 84,108,108,172, 75,129,192, 98,241,113,160,168, 8, 42, 16, 78, 75,150, 44,233, 86,156,168, 42, +230,217,124, 39,124,233,210,165,139, 11,253,255,160,147,172,120,133,149, 99,169,118,121, 46,183,247,147,179,171,111, 87, 53, 80, + 47,167,192,174,133,172, 65, 20, 49,143,206,130, 97,152, 29, 22,138, 43, 9,225,240,119, 76,153, 49,159,179,249,178, 6,201, 73, + 9, 72,184,186, 12,186,180,176,237,148,210, 9,193,193,193, 57,239,155,168,160,160,160, 64, 27,123,103,104, 13, 20, 12, 5,240, + 39,145,245,209,136,171,238,126,126,126,243,111,221,186,229,165,213,106, 21,127,252,241, 71,214,238,221,187, 95,234,245,250,159, + 41,165,123,242,207, 57,158,150,150,182,128, 82, 10, 43, 43, 43, 30,159,207,151,148, 54,240,179,134,181,160,238,136,225,131,111, + 76, 92,179, 85,252,242,201, 35,172, 57,124, 26, 34,179,222, 28,154,169,239,245, 68,101, 44,248, 42,184,212,197, 85, 26, 79, 65, + 61,248, 28, 2, 59,137,192,185, 49, 33,226, 91,148,150,217,157,235,224,225,197, 49,122,122,227,186, 73, 11,185, 66, 32, 4, 0, + 55,223,106,220,135, 26, 35,254,120,252, 12, 98,177,173,192,194,135,108, 54, 33,164,209,179,103,207, 72,110,110,174, 54, 36, 36, + 4,118,118,118,112,114,114,130,181,181, 53,158, 61,123,134,139, 23, 47, 34, 60, 60, 28,148, 82,212,170, 85,171, 92,121,155,156, +156,140,156,156, 28,244,234,245, 73,155,132,132,120,177,163,147,179,254,210,197, 11, 23, 42,194,201, 48, 12, 1,128,192,192, 64, + 4, 6, 6,242,227,227,227,109, 78,158, 60, 41, 95,178,100,137,171, 82,169,188,167,209,104,222, 17, 78,150, 10, 44, 0,208,106, +181,208,233,116, 16, 8, 4, 16,139,197, 16, 8, 4,200,201,201, 65,114,114, 50, 84, 42,213, 91,139,155,165,188,249, 49,166,216, +213,236,254,159, 43,199,112,199, 10, 54,136,127,228,139,172, 75,132,144,130,242, 77,206,223,247, 41,173,171,175, 12,206,119, 44, + 44,133,172, 76,252,138,112, 6, 5, 5, 21,112,188,211, 74,136,197,226,148, 2,203,149, 88, 44, 78,177, 84, 96,153, 76, 38, 8, + 4, 2, 52,108,216, 16,235,214,173,195,189,123,247,112,244,232, 81,120,122,122, 98,248,240,225,224,112, 56,120,250,244,105,121, +163,201,220,186,117,107,106,175, 94,189, 2,119,238,220, 41,142,137,137, 65, 88, 88, 24,108,108,108,176,110,221, 58,209,168, 81, +163,124, 46, 95,190, 60, 27,192,242, 50,243, 48,227,217,225,124,129, 11, 87, 87,215,225, 53,107,214,252,211, 57,206,206,206,214, +231,206,157,115, 44, 16, 94,133,175, 41, 1, 89,179,103,207,254, 49, 32, 32, 96,117,126,183, 96,115,188, 25, 7,215,234,240,225, +195, 4, 0,250,244,233, 67, 9, 33, 87,242,207, 15, 57,116,232, 80,235,231,207,159,211,185,115,231, 22,219, 38,165,166, 36,110, +250,113,221,230, 31,127,152,247,157,112, 98, 23,107,244,169,199,135, 88, 64, 96, 37,229, 99,209,218,173,198, 7,119,174, 61,118, +113,113, 57, 9,160, 87, 98, 98, 34, 92, 92, 92,114, 1,132,115,185,220, 40,179,217,156,192,142,113,255,215,189,215,138,155,232, + 48,138, 82,154, 88,156, 64,170,136, 64, 43,108,225, 42,192,244,233,211, 3,151, 44, 89,114,247, 67,166,133, 83,232,166,164,140, +151,132,139,141,210,205,110,244,160,142, 96, 24,192,100, 6, 76,102, 10,109,158, 26, 73, 97,151,243,244,122,253, 97, 11, 51,111, +217,240,111,151, 84, 14,142,229, 33, 49, 83,143,184,139,243,169, 46, 45,236,211,251,247,239,127,246,161,196,149,173,131,235,149, +239,151,109,195,189, 72, 61,204,204, 27,125,197, 48,244,237,239,143,164, 18, 86,117,112,112, 88,113,251,246,237, 74, 34,145, 72, +241,226,197, 11,243,161, 67,135, 18,244,122,253,198, 2,113,149,143,193, 65, 65, 65, 70,153, 76, 6,181, 90,173, 53, 24, 12,185, + 37,137,171, 64,137,196, 61,168, 70,141,107, 19,215,108, 21,107,245,122,100,107,116, 80,186, 56,155, 67, 50,243,122,133,168,116, +111, 43,100,117, 5,191, 73,189, 42,110,110, 68,172, 0, 5, 16,175,210, 39, 88, 34,174, 0, 64,166,176,230,184,215,107,133,122, +223,172,131,134,107, 77, 1,192,214,209,149,211,250,203, 69,232,180,230, 42,116, 60, 69,121, 36,176,174,106,213,170,218,252,250, +139,244,244,116,132,134,134, 34, 35, 35, 3,235,214,173, 67, 88, 88,216,219,151,110,249, 4,198,219,103, 2,169,169, 41, 34, 74, + 41, 82,146,147,132, 21,229, 44, 16, 88, 5,112,115,115,195,216,177, 99,121,106,181, 90, 92, 88, 92,149, 87, 96, 21,196,131, 82, + 10,189, 94,143,236,236,108,232,245,122,188,124,249,242,173,184,202,183,160,149, 47,253,122,149,177,216,112,109,134,241, 61, 26, +181, 63, 0, 8, 10, 57, 15,116,170,168,184, 42, 34,124,202,101,253, 41,203,130, 85,156,137, 91,163,209, 56, 81, 74, 73,112,112, + 48, 44, 25,127, 85, 56,223, 5, 2, 1, 70,142, 28,137,187,119,239, 34, 34, 34, 2, 92, 46, 23,106,181, 26,121,121,121,104,223, +190, 61, 10,198,227,149, 35, 13, 84, 32, 16, 12,158, 49, 99,134, 56, 42, 42, 10,105,105,105, 5,131,228, 97, 54,155, 49, 97,194, + 4,137, 72, 36, 26, 92, 94, 83,125, 66, 66, 66,199, 23, 47, 94,248, 21,221,146,146,146,178, 69, 34,209,123,231,237,225,195,135, + 73,159, 62,125,104,159, 62,125,104,129,208,178, 20, 89,113,161,155,142, 30, 63,121,126,210,247,203,114,243,212, 42, 84,113,149, + 32, 87,149,141, 69, 75,126, 48,222,186,117,253,202,212, 9, 99, 26, 31, 58,116,104, 41,128,240,252, 75,194, 15, 29, 58, 52,236, +251,239,191,223,133,124,119, 13, 44,254, 85, 22, 42, 82, 76,216,150,146, 44, 88, 31,194, 10, 86, 96,201, 2, 32,249, 75, 44, 88, +101,136,150, 58, 54, 14,110,151,167, 47,222, 42, 63,250,152,139,140,196,112,104, 83,194,225, 81,183, 39,146,195,255, 0, 53, 27, +127, 11, 13, 13, 85,151,197, 83,175, 94, 61, 95, 87,159, 58, 95,214,169,215, 16,203, 78,230, 66, 21,186, 31,250,204,168,245,193, +193,193,191,125,136,196, 4, 5, 5, 5,218,218,187, 92,153,177,116,171,221,137,167,124,164, 39,132, 35,236,216, 84,152, 13,127, +234, 21, 59, 93, 94,110, 9,163, 23,230,102, 37, 67,175, 50, 67,204,201, 19,255, 3, 42,225, 75,165, 82,185,243,199, 31,127, 28, +211,184,113, 99,233,192,129, 3, 95,100,102,102, 46,164,148, 30, 44, 36,194,218,248,249,249, 77, 94,191,126,189, 79,108,108, 44, +206,159, 63,255, 18,165, 12,224,123,170,209,196,213,180, 22,109,188,177,247,231,239,184, 94,126, 56, 48,119,138,233,230,147,103, + 61, 66, 85,166, 51,111,197,149, 92, 24,208, 56,176,234,201,175,199,141,225,152, 31,156, 69, 88,108, 10, 18,213,198,139,150,198, + 59, 94,149,103,228,139, 36,144, 59, 87, 66,180,198, 44,224,241,120,119,191,255,114,148,128,195,229,129,195, 19, 32, 50, 75, 87, +158,151,184,232,217,179,103, 4, 69, 38, 66,104,181,218, 18, 45, 62, 31, 18,150,114, 22, 55, 62, 10, 0,140, 70, 99,133, 57, 11, + 91,108,202,186, 23,195, 48,208,233,202,177, 28,161, 46,171,248, 50,208,164, 25, 63, 68,182,229,239,133,239, 35,174, 10,132, 79, +193, 0,116,145, 72,244, 86,164, 88,106,101, 42,197,130, 85,161,227,239,124,185,114, 56, 96, 24, 6, 2,129, 0,181,107,215,198, +201,147, 39, 97,103,103, 7, 43, 43, 43, 88, 89, 89, 65, 34,145,192,222,222,254,173,192,226,112, 44,158,125, 67,117, 58,157,167, +167,167, 39, 94,190,124, 9,177, 88,252,118, 19,137, 68, 8, 12, 12,132, 90,173,118,195, 71,101,171, 7,190,232,223,174,231,134, +221, 71,134,158, 60,121,234, 75,131, 78, 91,195,223,223,143,222,191,117,249,241,212, 9, 99, 58,177,146,228, 63,103,225, 58, 89, + 88, 36, 17, 66, 78, 78,155, 54,109, 70, 69,249,166, 77,155, 54,163, 56,139,214, 7, 19, 88, 5,138,177, 56,229, 88, 32,174,166, + 46,218, 98,117,248, 1, 7,153,137, 97,136, 57, 59, 67,101, 54,228,101, 50,140,209, 43,243,213, 13, 0,216, 97,225,253, 26, 52, +109,219,139,156,127,170,135, 94,149,128,156,167, 7,162,141, 70,227,244, 15, 41,174,166, 45,217,106,119,228, 49, 15, 25, 9,225, +120,117,122,122,182,217,144,215,166, 34,126,180, 10, 99,136, 80,216,179,127, 53,155,110,159, 55, 79,128,153,152, 49,248,217,243, +206,174,205, 73,207,132,235,244,216,223, 89,209, 82, 83, 83, 23,201,229,114,206,242,229,203, 63,211,106,181,115, 41,165,135, 11, + 85,194,246, 85,170, 84, 89,182,105,211, 38,247,215,175, 95, 11,111,220,184,145,113,229,202, 21, 6,192,210,210, 56, 67,178,117, + 83,106, 40, 4,220,170, 30,174,227, 94,198,197,245,120,146, 99, 58, 91,112,172,134, 76, 24,216,188,118,192, 31, 11,230,206, 80, +232,111, 28,134, 58, 49, 22,235,130,147,114, 24,179,101,101, 72, 8,177,107,236,229, 76,166,127, 49,156, 81,169, 84,144,137,132, +140,209,104,228, 14,109,215,194,252,195,212, 73,156,164,164, 36,168,115,115,121,132, 16, 59, 74,105, 70, 25, 92,243, 1,180,169, + 85,171, 22, 58,116,232, 16, 61,111,222,188,231,133,197,199, 63, 73, 96, 21,181, 96, 21,192, 96, 48,144,138,114, 22,182, 96,149, + 37,176,202,109,193,210,229, 20, 47,164,242, 82,223, 87, 96,189, 38,132,120, 22,252,254, 16,101,160,213,106, 29, 11,117, 13,150, +105,137,183,192,130, 85,225,227, 69,234,231, 91, 11,214,163, 71,143,224,225,225, 1,131,193, 0,133, 66, 1,133, 66, 1,185, 92, + 14,149, 74, 5, 62,159, 95, 94, 11, 28, 35, 22,139, 95,135,134,134,250, 41,149, 74,152,205,230,119, 68,214,139, 23, 47, 32,147, +201,226,203,107,193,114,117,117, 61, 39,147,201,188,138,134, 59, 59, 59, 91,127,136,114, 42,108,185,234,211,167, 79,133,250, 17, + 54, 44,249,110, 55,128,221,125,251,246,221, 25,114,235, 84, 61, 23, 23,151, 83, 1, 1, 1, 4, 0,216, 25,131, 31,151,245,170, +132,231, 56,181,136,229, 73, 95,232,127, 42, 0,146,255, 63,181,144, 0, 43,252, 91, 95, 76, 88,250,146, 37, 75, 46, 23, 26,191, +149,250,255,102,193, 10, 10, 10,170, 99, 99,239,122,249,187, 5,155,173,246,222,231, 32, 59,241, 57, 18, 46,204,202,102, 12,121, +109, 56, 28, 78, 98,236,205, 45,135, 1,228, 61,120,240,224,170,133,153, 87,215,223,215, 23, 7, 66,140,208, 38, 61, 6,168,121, +123, 72, 72, 72,222,251, 38,162, 64, 92, 77, 89,188,197,238,208, 67, 94,129, 8,204,102,222, 83, 92,125, 78,136, 45, 87, 38,222, + 56,180, 67,253,126, 94, 85,220,193, 80, 35, 24, 1, 69,239, 41, 14,188,240, 7,121, 71, 61, 59,112, 15, 50,185,204,151,113,183, +254, 62,239,227,185,185,185, 11, 8, 33, 71, 40,165,207, 10, 53,238,157,125,124,124, 22,255,244,211, 79,149,226,227,227, 21, 15, + 30, 60,200,217,178,101, 75, 20,195, 48,243,139,155, 85, 85, 20, 79, 84,134, 73,129,114,225,207, 79,115, 77,111,125,232, 84,151, + 9,106, 13, 31, 58,240, 86,187,129,195,197,175, 46,236,134, 93,212, 51,172,121,144,108,142, 87,105, 7, 62,207,163, 73,150,136, + 43,145, 72,116,120,245,161,227, 47,235,214,173, 75,212,106, 53,140, 70, 35,210,210,210,176,124,207,161, 80, 74, 41,108,109,109, +113,250,244,105,102,208,160, 65, 5, 3,162, 51, 74,224, 42,112,211, 0,129, 64, 64, 36, 18,137,119,116,116,116,116,165, 74,149, +180,197,137, 20,145, 72, 84,110,129, 37,145, 72,192, 48, 37, 27, 1,202,195,105, 50,153,136, 37,225,229,225, 44,136, 91,193,224, +246,162,225, 5,224,114,185, 96, 24,166,212,180,252, 89,189,149, 96,193,202, 75, 49,190,103,227,233, 85,218, 76,229,191, 19,249, +150,176, 2, 1, 83,172, 43,134,242, 88,176, 10,202, 66, 32, 16,224,248,241,227, 24, 49, 98, 4,204,102, 51,164, 82, 41,228,114, + 57,100, 50, 25,126,251,237, 55, 20,184,113, 40, 79, 54, 26,141,198, 61, 75,150, 44,153,177,105,211, 38, 9,165, 20, 66,161,240, +173,192,154, 59,119,174,198, 96, 48,236,177, 68, 96, 17,219,234,253,109,108,237,134,100,101,165,239,168,106, 95,250, 44,194,226, +174,201, 31,143, 85, 20, 54,243,231,207, 31,198, 48, 76, 79, 20,113,197, 80,228,188,119, 92, 56,148,230,166, 1,128,237,252,249, +243,191, 96, 24,166,122,254,255,119,102, 11, 22,174,161, 5,199,251,246,237,187,179,232, 44, 66, 22,255,122,220,251,183, 69,184, + 68,129, 85,167, 78,157, 0, 59,165,251,229,137, 11, 54, 91,237,184,195, 69,118,226, 51,164, 93,254, 62,155,154, 52,133, 69, 75, +179,114,222,175,174, 82,105,143, 12,181, 22,198,204,151, 32,132, 60,120,223, 4, 52,104,208,160,170,141,157,243,149,201, 11,183, +216,237, 11,230, 35, 43,225,127, 34,240,125,196,213, 16,161,176,103,160,175,251,182, 1,157,155,218, 90, 19, 19, 76, 49,207,241, +243,240,126, 8,238,110, 64,211,254,214,104,208, 69, 1,159, 58,226,126,167,183,102,180,117,109, 78, 62,255, 59,173, 89, 69,196, + 85,247, 74,149, 42,205,187,115,231,142, 23,195, 48,138,171, 87,175,170, 54,109,218,244, 74,171,213,174,165,148,158,178,148,243, +105,174,254,173,184,170, 97, 45,168,251,249,103,195,110,124,179,122,147, 56, 52,248, 30,150,237, 57, 1, 43,174,209,124, 63, 73, +219,247,105,238,255,186, 15, 75,131, 80, 40, 92,112,233,210, 37, 89,205,154, 53, 73,122,122,250, 91, 75,139,193, 96, 64,118,118, + 54, 84, 42, 21,116, 58, 29,130,130,130, 56,107,215,174,149,141, 27, 55,110, 1,128, 47, 45,141,175, 82,169,132, 64, 32,128,193, + 96,120, 43, 82,132, 66, 33,108,108,108,144,158,158,142,253,251,247, 3, 64,169,206, 41, 5, 2, 97, 34,135, 67, 60,100,114,185, + 81, 42,149, 82,185, 92, 94, 92, 58,202,197, 89,240, 85,212,169, 83, 39,229,130, 5, 11,248, 65, 65, 65,111, 3, 11,186, 8, 43, +194, 73, 41,205,235,208,161,131,116,237,218,181,240,242,242,130, 94,175,127, 71, 72,113, 56, 28, 8, 4, 2,196,198,198, 98,225, +194,133,160,148, 90,254, 33,163,205, 52,162,198, 48, 71,104,210,141,208,164, 27,161, 77, 51, 64,157, 98,132, 49,207,252, 79,107, +192, 42, 50, 0,221, 2, 75,152,227,135,176, 96, 21, 8,172,103,207,158, 97,231,206,157,232,210,165, 11,108,109,109,145,153,153, +137,131, 7, 15,226,249,243,231, 16, 10,133, 40,231, 56, 50,166, 97,195,134, 63, 92,191,126,189,251,192,129, 3,171, 79,158, 60, + 89, 82,163, 70, 13,132,135,135, 99,254,252,249,218,224,224,224, 8,141, 70, 51, 31, 22, 56, 36,117,243,240,252,230,231, 61, 39, +249, 35, 6,118, 30, 7,125, 52, 44,153, 69,248,206, 53,197, 12,118, 47,193, 77, 67,231, 18,232, 10,187,112,120,199, 77, 67, 97, +220,188,121,211,187, 82,165, 74, 1,120, 51, 51,176,224, 69, 91,120,182,224, 59, 47,225,196,196,196,250, 96,103, 17,178,248, 39, + 11, 44, 14,135, 51,161,225,167, 51,173,118,220,230, 33, 51,254, 41,178,175,207, 41, 42,174, 44,105,100,218, 21,246,149,193, 23, + 43,106,152, 32, 0,160,133, 41,235, 21,184, 92,110,185, 5, 86, 81, 78,134, 97, 38, 53,250,116,166,221,174,123, 60,100, 39, 60, + 67,234,149,239,203, 45,174, 10,115, 14, 17, 10,191,231,115,201,172,174, 45,234, 10,154,213,241,133, 44, 37, 26, 73,113, 9, 56, +240, 44, 53, 35, 34, 83,247,249, 31,196,128,152, 87,186,159,187,124, 97,103,103,235,204, 71,183, 49,246,118,183, 79,228, 28,117, +107,195, 49, 80, 3, 93,146,112,131,206, 45, 46,158, 31, 2,101,113, 18, 66,170, 90, 89, 89, 45, 15, 14, 14, 86,138,197, 98,171, +251,247,239,155, 55,111,222, 28,171,213,106, 87, 82, 74,247, 87,132, 51, 80, 34,113,175,238,231,125,245,155, 85, 63,137,115,213, +121, 80,235, 13,112,245,112, 51, 95,125,240,252,211,167,185,250, 99,150,112, 18, 66, 90,127,246,217,103,181, 26, 54,108,200, 41, + 44,174,244,122, 61,114,114,114,160, 82,169,144,147,147,131,156,156, 28,196,199,199,163,101,203,150,156, 90,181,106,213, 32,132, +180,166,148, 94, 46,202, 89,200, 77,195, 12, 0, 28, 66, 72,248,249,243,231,181, 67,135, 14,133, 68, 34,129, 90,173,134,187,187, + 59, 76, 38, 19,206,156, 57,131,224,224,224, 44,134, 97,246, 1,184, 80, 90, 60, 53,154, 60, 79, 66, 8, 87,157,155,219,174,102, +205,154, 3, 39, 77,154,100, 83,248,252,138,112, 2, 64,102,102,102,165,115,231,206,125, 31, 18, 18, 50,174,115,231,206,210, 25, + 51,102,240,189,189,189, 97, 50,153,200,123,112, 90, 63,120,240, 96, 69,179,102,205,190,234,212,169, 19,111,241,226,197,176,182, +182,134,217,108,134, 68, 34, 65, 78, 78, 14,230,207,159,143, 27, 55,110,152, 40,165, 27,178,179,179, 39,151,198,249,142, 31,172, +137,171,106,151, 86, 15, 75,242,131,245,119,212,121,141, 70,227, 84, 94,171,152, 37,241,124,240,224, 1, 45,234, 15,171, 52, 11, + 86,113,156, 5, 2,139,203,229, 34, 58, 58, 26,155, 55,111,254,147, 31,172, 2, 55, 14,197, 9,172, 18,226, 73,175, 92,185, 98, + 38,132, 52,190,127,255,254,212,161, 67,135,126,174, 86,171,221,101, 50, 89,130,209,104,220,161,209,104, 10,252, 96, 9,202,138, +167, 80, 40,230, 19, 14, 7, 18,177, 76,162,206, 80,199, 20, 55,139,240, 29,147,147, 90, 29, 35,182, 22,219, 23, 92, 83, 28,103, + 17, 55, 13,239,184, 98, 40, 66,247,142, 11,135,162,110, 26, 10,115, 54,105,210, 36,138,195,225,132, 49, 12,195, 1, 16,134, 34, +179, 5, 11,113,250, 37, 38, 38,214,119,113,113,185, 10, 64, 90,116, 22,225,223, 81, 63, 89, 78, 86, 96,149,248,113,248, 71,240, + 11,112, 68, 41, 80,221, 89, 94,110,113, 85, 28, 76, 58,117,196,194, 3,145,117,204,122, 13, 76, 57, 49,225,193,247,239,165,188, +111, 2, 40,165,178, 27, 15, 34,192,147,164, 35,235,214, 15, 89,196,172,107, 19, 28, 28,252,168,194,149, 6,152,254,211,153,195, + 2, 98,109,135,199,223,142, 64, 66,150, 26,103, 34, 51, 15,210, 60,221,151,187,243,215,139,115,111, 76,174,111,155,153,180,177, +121,111,235,126, 14,110,124,172,250,110, 7,196,211,236, 5, 13,218,182,248, 91,215, 40, 44, 24,248,190,102,205,154,177,205,155, + 55,151,247,235,215,239, 69, 70, 70,198, 59, 3,223,203,139,167, 26, 77, 92,160, 66,248,211,229, 45,171,190,147, 4, 54,196,225, +133,211,205,215, 30,132,245,122,162,210, 91, 60, 40, 80, 32, 16,180,154, 54,109,154, 64,173, 86,255, 73, 92, 21, 21, 88, 57, 57, + 57,120,252,248, 49,134, 15, 31, 46,122,244,232, 81, 43, 0,151, 75, 72,235,236,124,135,147, 60, 74,105,234,210,165, 75,123,110, +216,176,161,247,183,223,126, 43,234,220,185, 51,238,222,189,139,243,231,207,235,244,122,253,111, 0,142, 81, 74,117, 22,230,161, + 25,192, 57, 66,200,213,165, 75,151,246,228,114,185,111,215,179,124, 15, 78, 35,128,217,132,144, 21,187,118,237, 90,118,225,194, +133,129,195,135, 15, 23, 27,141, 70,242, 30,156, 38, 0,223, 42,149,202, 89,167, 79,159,222,241,251,239,191,247, 26, 50,100, 8, +103,252,248,241, 88,183,110, 29,126,253,245, 87,198,108, 54, 31,227,243,249,195, 82, 83, 83,203,156,128,242,142, 31,172, 82,252, + 92,149,117,220, 2,220,255, 11,170,254,123,115, 22,181,132,213,173, 91,215,169,240, 44,205,194,123, 75, 45, 88, 0,208,170, 85, +171,183, 86,197, 66, 51, 40,223,158, 67, 8, 41,119, 23, 33, 0,155,124, 63, 87, 27, 0,172,195,187, 94,220,185,248,159,167,119, +139,224,230,225,133,120,192, 94,163,215,102,149,186,216,179,181,204,222,205,195,171, 44,186,172,217,179,103,255, 56,103,206,156, + 31,139,186, 98, 40,124, 82, 81, 23, 14,243,230,205, 67, 73,110, 26, 0,100,206,158, 61,251, 7, 0, 8, 8, 8, 32,249,221,130, +245,144, 63, 91,176, 16,231,206,252,112,233,220,185,115,135, 2, 40,141,147, 5,139,191, 85, 96,205,200, 13, 94, 99, 4, 96, 79, + 8,153, 30, 28, 28, 28,250, 1, 36,192,180,148, 19, 35,214, 81, 32, 19,140,121,234,135, 72,128,217,108,158,169,126,176,150,161, +148,218, 16, 66,166,221,191,127,255,189,227, 73,172,237,160,154, 63, 22,191, 62, 77,160, 73,106,227, 39,187,245,239, 90,106,242, +199, 92,245,119,109, 78, 14,216,186,242,143,124,219,198,158,156,202, 24,250,143, 40,208,212,212,212,197,114,185,156,187, 98,197, +138,207, 52, 26,205, 59, 3,223, 43, 44,178, 84,250, 41, 53, 20, 2,110,128,183,199,184,231,209, 49, 61,159,168, 44,235, 22, 44, +244, 34, 17,186,186,186, 62,209,106,181, 32,132, 64,167,211,189, 21, 86, 42,149, 10,217,217,217,111,255, 27, 12, 6,164,166,166, +194,211,211, 19,133,124, 38,149, 36, 50, 18, 11,107, 4, 66,200,217, 5, 11, 22, 12, 92,184,112, 97, 91, 74,233, 69, 0,251, 40, +165, 21,114,253,145, 47,116, 14, 72, 36,210,229,132, 16, 55,129, 80,164, 63,121,242,228,153,247,228, 84, 1, 24, 67, 8, 89,176, + 98,197,138,181, 82,169,180,254,195,135, 15,223,139, 51, 95, 60,125,106,111,111,239,186,115,231,206, 67,219,182,109,107,196,227, +241,110, 19, 66,250,102,101,101,149,123,177,103,242,174, 69,160,220,199, 45,192,175,127, 65,181,127,111,206,242,184, 95,176,176, + 93,202,157, 53,107, 86, 74, 81,193, 85,212, 90, 85,240,223, 96, 48,104, 45,124,150,202,227,139,172, 84,113,193, 33, 68, 3, 64, + 50, 99,222,138, 55, 39, 91,190,216, 51, 8, 72,137,131, 5,231,204,153, 67,231,205,155, 71, 56, 28,206, 49, 0,225, 28, 14,231, +101,209, 65,232,133,143,205,155, 55, 15,115,230,204,161,115,231,150,252,109, 90,192,249,252,249,115,202,229,114, 47, 2,136,226, +114,185,209,133,121, 11,135, 23, 92, 83, 26, 39, 11, 22,127, 53,200, 95,233,132,237,223,104,234, 28, 44, 20,206,227, 0,223, 1, + 32, 20, 88,181, 91,175,159, 89,218,181, 46, 77,201, 34, 74, 48, 33,255,229,179, 56,241, 6, 93,248, 79, 72, 59, 33,164, 90,225, +177, 89, 31,130, 51, 80, 46,244, 47, 60, 54,203, 82, 78, 62,159,223,198,104, 52,146,212,212, 84,168,213,234,119,172, 85, 57, 57, + 57,200,203,203, 67, 78, 78,206, 59, 99,167,154, 54,109,138, 86,173, 90, 81,163,209,120,169, 2,105,231,231, 91,141, 62,100,126, +254, 43, 56,125,124,124,132, 17, 17, 17,250,127,234,179, 73, 8, 81,228, 11,205, 15,201,233, 76,105,217, 19, 45,254,205,237,210, + 95,193,105, 91,185,233, 32, 59,123,231, 47, 11, 22,125,214,104,213,154,164,132,184,117, 69, 7,175, 19,219,234,253,221, 60, 60, +191, 17, 10,197,252, 2, 97,150,158,150,180, 57, 51,242,143,189,197,197,147,252, 79, 65,218, 68, 68, 68,120,249,248,248,196, 0, +200, 42, 18,149, 63, 29, 43,236,159,175, 20, 78, 0, 80,220,185,115,199,181, 97,195,134,137, 0,114, 74, 11, 47,141,243,191, 90, +238,255,100,206, 18,238, 51,170,176, 31,172,143,197,130,245,159,196, 30,189,126, 14,202, 88,108,184, 48, 18,255,160, 51, 1,204, +252,167,165,195, 18,113, 85,110, 75,150, 5,226,170, 56, 20,136, 36,165, 82, 9,165, 82, 89,158,235, 42,154,118,227, 95,144,159, +255, 10, 78, 75,196,213,223, 92, 47, 85,127, 1,103, 18, 88,148, 27,249, 2,105,111,153,249,251,166,203,240, 64, 57,202,163, 64, +212,100, 2,200, 44,225, 35,190,180, 99,165,113, 34, 95, 60,229, 20,115,109, 73,225, 44, 88,252, 45,224,176, 89,192,130, 5, 11, + 22, 44, 88,176, 96,241, 97, 65, 0,180, 43,225,139,193, 98,211, 31, 33,164, 93, 5,190, 58, 47,176,156, 44, 39,203,201,114,178, +156, 44, 39,203,249,223,226, 44,139,187, 72,247,240,191,182,139,240,237,204,150,191, 98, 3,208,142,229,100, 57, 89, 78,150,147, +229,100, 57, 89, 78,150,179,130,247, 25,245,255,113,159,191, 98, 99,187, 8, 89,176, 96,193,130, 5, 11, 22, 44, 62, 48,216, 65, +238, 44, 44, 2,151,203, 93,210,162, 69,139, 47,111,220,184,177,210,104, 52,206,175, 8, 7, 33,196,213,201,201,105, 17,165,180, + 9, 33, 68,196,227,241,158, 37, 39, 39, 47, 54, 26,141,215, 43, 26, 47, 66,136,135,179,179,243, 34,134, 97, 26, 1, 16,240,120, +188,167, 9, 9, 9, 11, 41,165,183,223,131,211,202,217,217,185, 53,195, 48,238,111,146,206, 77, 73, 76, 76,188, 78, 41,141,103, +107, 2, 11, 22, 44, 88,176,120,111,129, 53,192,143,184,152,121,224, 29, 10,165,177,249, 47, 30, 5,128,218, 0,170, 2,120, 9, +224,209,251,206, 10,250,183,112,254,211, 65, 8,225,216,216,216,116,144, 74,165,223,228,230,230,214,177,178,178,122,106, 50,153, +214, 38, 38, 38,158,204,119, 74,248, 62,220,142, 3, 7, 14,156,246,243,207, 63,163, 95,191,126,179, 8, 33, 63, 82, 74,115,203, +195, 97,111,111,223,195,219,219,123,243,218,181,235,148,205,154, 53, 35, 18,137, 4,207,159, 63,119,251,242,203,177,245, 92, 93, + 93, 15, 36, 36, 36,124, 85,222,120, 41,149,202,190, 85,170, 84, 89,187, 97,195, 6,101,147, 38, 77, 8,159,207, 71,112,112,176, +251, 55,223,124,211,208,197,197,101, 71, 98, 98,226,164,242,114,218,217,217, 85,171, 92,185,114,167,141, 27, 55, 74,155, 54,109, + 10,145, 72,132,199,143, 31, 43, 70,143, 30,237,230,234,234,250, 56, 33, 33,225,124,121,248,130, 70, 63,224, 11,164, 6, 30, 0, + 24,242, 4,166,224,205,117,141,150,134,177,205, 19, 11, 22, 44, 88,124,132, 2,171, 79,117, 50, 31, 60,204, 0, 64, 58, 87, 37, +251,207, 71,113,175,183,111,223,222,103,228,200,145,164,110,221,186, 8, 14, 14,246,221,191,127,127, 87, 30,143, 23, 97, 54,155, +131, 1, 60,181,116,218, 57, 33,132, 15, 32,144,203,229, 6,253,147, 57,255, 13, 80, 40, 20, 85,149, 74,229, 36,123,123,251,206, +245,234,213,203, 25, 51,102, 76,116,104,104,232, 11,127,127,127,237,182,109,219, 22, 27,141,198,141,190,190,190,231, 85, 42,213, +138,164,164,164,138,186,110,168,100, 52, 26, 17, 22, 22, 6, 14,135,195, 7,224,141, 63, 47,125, 81, 90,217,184, 84,170, 84,105, +211,229, 63, 30, 56,230,232,185,120,153, 74, 1,228,129, 17, 56,227,167, 95, 14,216,206,158, 58,110,160,149,149,213,141,156,156, +156, 3,229,224,244,168, 82,165,202,218, 39, 79,158, 56,138,197, 98, 48, 12, 3,149, 74, 5, 87, 87, 87,108,219,182,205,246,187, +239,190,251, 76, 42,149, 94,203,203,203, 59, 81, 14, 78,171,202,149, 43,119, 10, 13, 13,149,138, 68, 34, 98, 50,153,136, 78,167, +131,135,135, 7,221,187,119,175,120,252,248,241,181, 69, 34,209,107,157, 78,247,194, 34,113,181,229, 1, 63, 39,237,114, 99, 26, +171,153, 5, 0, 68, 44, 89,216,106,158,221,221,156,180,203, 13,202, 10, 11,218,130, 91,193,163, 88,145,197,226,255,253, 67, 45, +200,193,193,225,112, 90, 90,218, 85, 0,159,231,175,108,240,190,156,174, 60, 30,207,155, 82,106,147,255, 63,203,100, 50, 69, 81, + 74, 19, 42,202,233,224,211,186, 59, 68,210, 17,160, 76,109, 14, 0,194,225, 60, 50, 27,242,182,167,133, 95, 62,241, 94,156, 66, +201,103, 0,173,205, 1, 24,194,225, 60,102, 76,121, 91, 83,159, 95, 62,195,214, 12, 22, 31, 76, 96,245,173, 78,108, 1, 76,221, +255,195, 40, 14,143,203, 37, 3,167,111, 25,116,245,220, 49, 77,229,106,117,223, 90,129,154, 55,111,142,230,205,155,147,101,203, +150, 85,189,120,241, 98,213,189,123,247,154, 8, 33,143, 41,165, 37,190, 36, 59,249, 16, 13, 3,136, 59,251,113,243, 6,204,220, +190,165, 73,147,166,140, 72, 36,194,251,112, 2, 64,135,170,220,200, 46, 13,125, 30, 15, 28, 55, 59,166, 81,163, 38,244, 67,112, +254, 75,196,213, 85,133, 66,225, 51,122,244,232,151, 99,199,142,189, 38,147,201, 40, 0,228,229,229,137,186,119,239,158,217,171, + 87,175,244,188,188, 60,252,244,211, 79, 30,107,215,174, 61,111,101,101, 21,159,147,147,211,160, 60, 86, 49, 0,115,122,244,232, + 49,235,235,175,191,134,167,167, 39,198,143, 31, 15,163,209, 24, 76, 8,153, 13, 96, 41,181,192,233,140,163,163,227,156,213,171, + 87, 59,170,141,124,124,191, 43, 2, 25,185, 6, 0,128, 84,200,193, 87,237,196, 24, 55,110,188,245,221,187,119,151,161, 28,190, +118,156,157,157, 23,109,216,176, 65, 41, 22,139, 65, 41, 69,110,110, 46, 84, 42, 21,114,115,115,161, 86,171, 49,118,236, 88,235, +167, 79,159,174, 6,112,162, 28,156,173, 55,110,220, 40, 21,137, 68, 56,127,254,188,159, 78,167,227,234,245,122,152,205,102,115, +149, 42, 85,194,190,254,250,107,209,147, 39, 79, 58, 2,176, 72, 96,185, 36,129,159,173,209,108, 88,255,195,119, 74, 0,248,122, +234,242, 13,128,166, 33,181, 32,204, 37, 9,245, 1,176, 2,171,244,250,201, 5,240, 9,159,207,239,237,227,227, 83,239,229,203, +151, 15, 77, 38,211,111, 0,126,123,223,143, 40, 66, 72, 91, 87, 87,215, 69, 9, 9, 9,235, 41,165,187,255, 43,121,234,228,228, +244,219,205,155, 55, 61, 54,110,220, 56,124,229,202,149,167,241, 30, 94,242,243, 63,122, 27, 55,104,208,192,161,119,239,222,124, +103,103,103,228,229,229, 33, 34, 34, 66,122,225,194, 5,165, 88, 44, 78,215,233,116,183,202, 83, 86, 14,126, 77,229,224, 89,237, +111,220,186, 93,179,126,159,126,162,112,178,183,134, 70,111,198,203,152, 68,207,179,167,143,183,116,173,209,245,166,193,144, 61, + 32, 45,252,143,220,242,114,182,238,212,173, 89,187,182,109, 21,214, 54,214,200, 86, 27,240, 42, 58,222,235,242,249, 19,205, 93, +106,116,189,198, 16,227,144,228,144,223,243,216,167,142, 69,121,192,177,240, 65,129, 76, 38, 45,246,152,181,181, 53, 90,183,110, +141, 37, 75,150,240, 0, 4, 21, 62,246,167,197, 79, 1,209,209, 13, 83,205,110, 74, 91,115,231,142, 29,137,149,149,213,123,115, +190, 9,100,188,155,120,210,206,247,118,205, 24,126, 97,239,170, 64,181, 42,139, 95,244, 20,185, 92, 14, 63, 63, 63,204,154, 53, +203, 50,206,247,196,255, 7, 39,165,212,181, 90,181,106,170,213,171, 87,251,205,157, 59,215, 86,171,213,202, 0,120,248, 84,111, +224,206,225,112, 60,180, 90,173,213,156, 57,115,148,203,150, 45,243, 83, 42,149, 89,148, 82,101, 57,227,185, 96,195,134, 13,179, +143, 29, 59,198,105,222,188, 57,108,109,109,209,186,117,107,156, 62,125,154,183,114,229,202,197, 0,102, 89, 18, 79, 14,135,211, +188, 89,179,102,132, 97, 40, 50,115,141,184,188, 36, 8,127, 44,175,143, 60, 61,131,204,172, 28,104,181, 90, 72,165, 82, 9, 33, + 68,110,105,218, 25,134,105,212,164, 73, 19, 2, 0,185,185,185,249,155, 26, 42,213,155,189, 94,111, 0,159,207, 87, 16, 66, 68, +229,224,116,111,218,180, 41, 0, 64,163,209,240,218,182,109, 75,218,180,105, 67, 84, 42, 21,175, 96, 25, 31, 62,159, 47, 36,132, +240, 44,225,212, 75,249,132,161,140,147, 76, 42,113,144, 73, 37, 14, 12,101,156, 0,192,146, 48,189,148, 79,254,206,250, 73, 8, + 81,114,185,220, 95,124,124,124,158,113,185,220,157,132, 16,231,247,225, 36,132,212, 39,132, 44,150, 74,165, 23,170, 85,171, 22, + 43,147,201, 46, 17, 66,150, 18, 66, 26, 87,132,147, 16, 34,148, 74,165,151, 22, 47, 94,124,232,225,195,135,253, 46, 94,188,232, + 29, 18, 18,242,233,178,101,203,246,203,229,242,235,132, 16,233,251, 60,155,222,222,222,219,238,220,185, 83,191, 73,147, 38, 63, +151, 86,135,202,195, 73, 8,225, 18, 66,234,144,226, 86,118,254,155,218,144,162,150,166,186,117,235,122,136,197, 98,180,107,215, + 14, 0, 90,189, 39,103,227, 49, 99,198, 56, 79,156, 56,145,255,232,209, 35,252,252,243,207, 56,118,236, 24, 82, 82, 82,208,173, + 91, 55, 65,155, 54,109,156, 69, 34, 81,227,114,113,242,172,246,127,243,237,132, 78,223,141,255, 66,241,248,181, 1,219, 47,188, +198,209, 91,137, 72,201, 19,162,251,167,195,172, 59,246,236,223, 81, 40,178,222, 95, 94,206,105, 83,167,118, 26,245,217, 32, 69, +104, 34,131,227,183,147,112, 59, 44, 27, 38,190, 13,186,124,250,185,109,237,166,157,186,242,192,223,241, 79, 40,163,143,157,243, +163,181, 96, 21, 94,145,254, 80, 40,205,236, 83,157,252,208,127,202,150, 89,132, 67,104,245, 6,109, 31, 86,171,219, 84,149,111, + 29,129, 78,167,131, 64, 32,128, 86,171,197,235,215,175,113,251,246,109,216,218,218,150,235,198,217,217,217,112,247,244,130, 92, + 46,255, 32,156,211,135,183, 19,189,138, 77, 21,157,187,125,165,229,154, 47,127,109, 84,165, 78,171,144,182,253,199, 63,177, 82, +186,106, 67, 66, 66,112,243,230, 77,100,102,102,162, 97,195,134, 31,211, 23,188,113,197,138, 21, 15, 18, 18, 18,200,141, 27, 55, +106,207, 95,189,215, 59, 36,167, 50, 55, 53,151,242,149,242,215,222,213,164, 47,204,217,217,217, 81,147, 38, 77,186,236,236,236, +172, 27, 55,110, 92, 75, 11,121,197, 0,252,251,244,233, 51,237,203, 47,191, 68, 68, 68, 4,190,248,226, 11,205,221,187,119,211, +155, 52,105, 98,191,117,235, 86,201,196,137, 19,113,245,234,213, 57,132,144, 35, 0,162, 40,165, 37,174,165,198, 48,140, 80, 34, +145, 0, 57,111, 62, 84, 13,166,130,181,105, 1,181, 90, 13, 30,178, 32, 20, 10, 57, 0,148, 0, 44,253,242, 20,136, 68,162,183, +226, 42, 46, 69,133,152,148, 92,168,114,117,208,104,140,208,107, 1,145,149, 19, 23,136,181, 7, 96,233,224,116,174, 72, 36,130, +201,100,130,193, 96,128, 86,171,133, 86,171,133, 78,167, 67,118,118, 54, 84, 42, 21,120, 60,158, 20,128, 21,128,140, 50,201,132, + 18, 19,151, 35, 88, 60, 99,225,134,185, 0,192,229, 8, 22,203,161,101, 44, 9,227, 10, 37,166,191,177, 94,137,148, 74,229,229, + 67,135, 14, 85,171, 90,181, 42,162,162,162, 2,250,246,237,219,144, 16, 82,135, 82,154, 87, 78, 46, 41,135,195,249, 97,196,136, + 17, 95, 14, 28, 56,144,248,250,250,130,199,227,193,100, 50,185, 71, 68, 68,180, 62,120,240,224, 84, 30,143,183,213,108, 54, 79, +178,116, 92, 31, 33,132, 35, 20, 10, 15,108,222,188,185, 69,195,134, 13,177,115,231, 78,220,189,123,151,169, 95,191, 62,103,232, +208,161,240,242,242,106, 56,116,232,208,163,132,144, 46, 21,177,100, 17, 66,188, 6, 15, 30,236,193,229,114,209,164, 73, 19,193, +205,155, 55,235, 2,184,249,158,121, 42,119,119,119,191,218,170, 85,171, 58, 23, 46, 92,120, 64, 8,105, 85,158,113,140,132,144, +158,174,174,174,203,172,173,173, 45,110, 20,115,114,114,242,226,227,227, 39,151, 99, 61,210, 70, 65, 65, 65,136,137,137,129,191, +191, 63, 4, 2, 65, 99, 66,200,104, 0,157, 0,204, 44,207,234, 16,132, 16,215,198,141, 27, 59,180,106,213,138, 44, 93,186, 20, + 0,192,231,243, 97, 54,155,193,225,112,192,231,243, 17, 16, 16, 64, 34, 35, 35,237, 8, 33,174,150,116, 23, 58,248,180,238,222, +164,109,167,102, 45, 26,214,226,172, 60,252, 18,102,198, 12, 46, 49,129, 71, 24, 48, 70, 17, 68, 2, 46,124, 3,235,113,195,158, + 62,110,232,224,215,190,123, 90,248,249, 19,150,112,118,234,222,163,121, 53,127, 95,206,154,163,175,144, 21,255,204, 28,255,252, + 90, 26,135,203, 65,181,160, 54, 14,190,213,235,112,235, 52,108,197, 79,136,122,218,218,174,106,203,118, 25, 47,175,178,162,226, +175,111,127,222,106,145,143, 70, 96, 21,197,225, 80, 58,219, 90, 68,148,143, 30, 5,115, 82, 85, 70,213,227,199,143, 97,107,107, + 11, 23, 23, 23, 88, 91, 91, 35, 52, 52, 20,151, 46, 93, 66,120,120, 56, 24,134, 65,237,218,181,203,117,227,132,196, 4,100,100, +101,127, 80,206, 42, 30, 74,124,237,161, 20, 36,167,231, 8, 46,220, 13,111,184,101,250,167,213, 57, 1,159,110,211,106,255,247, +238, 47, 88,239,238, 99,130,147,147,147,233,171,175,190,206, 24,181, 49,170,202,128, 54,174,220,158,141,157,113,244,102, 34,119, +255, 21, 46,157, 61,178, 86,234,203,151, 47, 44,126,201, 8,133,194, 69,157, 59,119,254,142, 82,202,255,230,155,111, 0, 0,195, +134, 13,203,185,125,251,182, 47,165, 52,133, 16,226, 58,114,228,200, 23,151, 47, 95,150, 78,152, 48,129,107, 50,153, 66,121, 60, + 30, 37,132,204,167,148,206, 45,182,146,241,120, 15, 31, 61,122, 84, 9,114, 47, 56, 40,184,232, 56,235,193, 27,171,162, 8, 72, + 77,138,195,157,144, 43,176,183,183,183,110,222,188,249,243,170, 85,171,234, 18, 19, 19,191, 81,171,213, 59, 74,173,184, 60,222, +211,224,224, 96,119,119,119,247, 55, 2, 43, 77,131,237,183, 56,200,211, 73, 0, 72, 64, 24, 25,172, 28, 43, 41,124, 13, 57,143, +148, 74,165, 65,175,215, 79,203,201,201, 41,181,171,135,203,229,166, 60,121,242, 68,225,225,225, 1, 0,198,163, 71,143,242,244, +122, 61, 40,165,230, 83,167, 78,117,138,141,141,173,227,237,237,205,113,119,119,159, 86,181,106, 85, 77,124,124,252, 23, 26,141, +166,196, 46,148,179,227,125, 12, 45,231, 94,217,152, 21, 21,123, 16, 0,220, 26, 86,203, 56, 57,183,174,190,229,220,220, 50,195, +206,142,247, 49, 96,220,223,182,228,199,136, 25, 51,102, 84,179,179,179,195,152, 49, 99, 48,111,222, 60,204,158, 61,187,234,152, + 49, 99, 70, 1,248,177, 28, 13,165,196,217,217,249,222,154, 53,107, 2,154, 54,109,138,211,167, 79, 99,223,190,125,136,140,140, + 52,121,123,123,243, 26, 54,108,136, 57,115,230,160, 99,199,142, 95,140, 27, 55,174, 37, 33,164,174,133,162,227,179, 57,115,230, +244,108,214,172, 25,134, 15, 31,174,187,114,229, 74, 63, 0,191,159, 63,127,190,205,213,171, 87, 15,239,217,179, 71,178,120,241, +226,118, 19, 39, 78, 28, 3, 96, 93, 5,210,223,171, 69,139, 22, 0,128,102,205,154, 97,217,178,101, 29,223, 71, 96, 17, 66,132, +246,246,246,167,118,238,220, 89,199,207,207, 15, 67,134, 12,169,219,175, 95,191, 83,132,144,246,148, 82,139, 26, 36, 55, 55,183, + 31,142, 29, 59,230, 35,149, 74, 45,190,175, 78,167,179,251,228,147, 79,150, 2, 40,151,192,218,187,119, 47, 38, 79,158,140,218, +181,107,215,106,212,168,209,166,209,163, 71,163, 79,159, 62,109, 9, 33, 78,148, 82,181, 69, 47, 22, 30,207,187, 91,183,110,252, +223,126,251, 13, 0,208,162, 69, 11,180,107,215, 14, 79,158, 60,193,141, 27, 55,192,229,114, 33,147,201,208,180,105, 83, 97, 66, + 66,130, 55,128, 50, 5, 22, 71, 36, 29,209,179, 91, 23,197,241,219,137, 48, 51, 38,212,243,177, 66,195, 0, 71,132,197,229, 32, +248, 89, 28,204,122, 1,172,236,236,209,184,101, 7,187,164,248,200, 17,176,100,120,128, 72, 58,162,119,207,174,242,227,183, 18, +144,149,240,156,190,188,123,228,146, 81,171,254, 2, 0,238, 95,220,191,201,217, 94,210,222, 55,168, 30,183, 85,251, 30,182,191, +237, 75, 26, 1,128, 21, 88, 44,222, 95, 96, 1, 64,142, 30,106,119,159, 26, 72,125,240, 0, 12,195, 32, 61, 61, 29,233,233,233, +240,241,241,193,186,117,239,182, 91, 21, 17, 46,127, 5, 39, 0, 56,217, 91, 97, 72,151, 6,188, 63, 66, 14,136,160,213,126, 16, +206,127, 42, 40,165,148, 16,194,137, 73, 51,218,164,102, 27, 4,253, 91,123, 80, 62,151,131, 1,173, 61,201,250, 19, 49,130, 20, + 53,223,134,195,225,196, 48, 76,217, 19, 9, 9, 33,252,158, 61,123,126,119,224,192, 1,254,243,231,207, 81,165, 74, 21, 24, 12, + 6,220,190,125, 59,142, 82,154,146,127,191, 4, 46,151,155,192, 48, 76,213,218,181,107, 99,201,146, 37, 8, 8, 8, 32, 93,186, +116,153,154, 47,178,254,116,163,132,132,132,197, 95,127,253,117,139, 45,219,247,219, 15,105, 68,160, 82,233,144,151,151,135,176, + 39,247,160, 78, 86, 99,211,166,205,144, 74,165, 4,128, 32, 41, 41, 73, 48,113,226,132,159,221,221,221,187,197,197,197,245, 46, + 81,160, 39, 36, 44, 28, 55,110, 92,195, 93,187,118,217,190, 25,119,165,129, 74, 35,194,157, 85,111,134,152, 53,156,120, 23, 91, +183,252,204,169, 89, 73,102,175, 82,169,240,197, 23, 95,172,113,113,113,105,154,152,152, 56,186, 36,206,196,196,196,235, 95,124, +241,133,219,193,131, 7,197, 85,171, 86, 13,207,206,206, 70, 70, 70, 6,103,207,158, 61,227, 92, 92, 92,172,143, 30, 61, 70,100, + 50, 25, 0,112,163,163,163, 5, 95,127,253,213, 1,103,103,231, 61, 73, 73, 73,195, 75, 42, 27, 0, 58, 66,144, 8,136,124, 36, + 18,238, 92, 64,115,227,202, 28,186,235, 77, 24, 64, 41, 40,153, 75, 6,223, 89, 42,106,166,211, 49,171, 1,125, 56,165,160,152, +243,247,173,167,230,224,224, 48,174,103,207,158, 88,186,116, 41, 78,156, 56, 49,209,206,206,110,213,188,121,243,224,234,234,250, + 53, 33,100, 53,181,124,177,183,229, 63,254,248, 99, 64, 64, 64, 0,134, 13, 27,166,191,112,225,194, 12, 0, 71, 1,196, 92,191, +126,221,115,199,142, 29,221, 15, 28, 56,176,116,205,154, 53,226,117,235,214,249,124,250,233,167,171, 1,140,180,224,131, 98,194, +192,129, 3,177, 98,197, 10, 92,185,114,229, 83, 74,233,233,252, 67,103, 8, 33,221, 23, 47, 94,124,113,214,172, 89,248,241,199, + 31,191, 41,175,192, 34,132,200,171, 85,171,246,125,167, 78,157,112,253,250,117, 52,111,222, 28,141, 27, 55,158, 72, 8, 89, 75, + 41, 77,171,128,184,226,200,229,242, 3,219,183,111,111, 94,169, 82, 37, 44, 92,184, 16,223,125,247, 29,182,109,219,214,124,200, +144, 33, 7, 8, 33,189, 45,153,229,107,109,109, 45,151, 74,165,152, 58,117, 42,141,140,140,204, 44,235,124, 15, 15, 15,219, 85, +171, 86, 17, 91, 91, 91,107, 75,197,176, 88, 44,110, 82,163, 70, 13,204,153, 51, 7,231,207,159,199,172, 89,179, 80,163, 70, 13, +196,196,196, 96,192,128, 1,210,153, 51,103,246, 1,176,221,194,118,201,218,222,222, 30, 41, 41, 41,224,243,249,104,218,180, 41, +142, 30, 61, 10,157, 78, 7, 71, 71, 71,100,101,101,161, 65,131, 6, 5, 98,204,218,194,214,174,134,131,157, 53, 82,158,198,131, + 7, 19,130,124, 29,112,249, 73, 58, 12, 70, 6,142,246, 54, 72, 74, 73, 70,163, 26,238,208,235, 61, 65, 41, 83,195,162, 15, 74, + 46, 39, 72, 36,150, 32, 67,149,134,248,103, 87,210, 13,102,221,232,172,200, 27,177, 0, 96, 87,165,197,232,251, 55,206,223,239, +219,181,133, 99,174,218, 3,132, 50, 13,192,130, 69, 57,192,177,224, 65,249, 83, 88, 94,222,159,123, 9,222, 87,184,252, 21,156, +197,181, 91, 31,163, 5,139, 82,202,184,217,242,178,101, 98,142,233,124,112,138,217,104, 50,227,220,253, 36,179, 84, 68, 76,182, + 34,125, 14,195, 48,148, 16, 66, 45,224, 49,158, 59,119,110,231,248,241,227,177,106,213, 42,188,120,241, 2, 2,129, 0, 53,106, +212,112, 41, 24, 31, 69, 8,177, 14, 10, 10,114,228,112, 56, 8, 11, 11,195,202,149, 43,241,217,103,159,209,155, 55,111,110, 43, +233, 69, 65, 41,125,152,152,152,184,121,242, 55,163,179, 56,121,177,144,209, 52, 24, 50, 94,128,209,164, 98,198,156,197,136, 74, +103,240, 32, 82,133, 7,145, 42,164,233,101, 88,185,254, 23,110, 96, 96, 96,119, 62,159,223,177,148,184,222, 78, 76, 76,220, 57, + 97,194,132,172,148,148, 20, 20, 88, 41, 13, 38, 6, 6,211,187,209, 80, 40, 20,216,180,105,147,141,135,135, 71, 31, 62,159,223, +186, 20,206,248,132,132,132,144, 47,191,252, 82,151,152,152,136,236,236,108,252,254,251,239,237,221,221,221,173,231, 46,254,145, + 68,165,211,183,241,204, 37,246,248,101,207,111, 92, 95, 95,223, 65,124, 62,191,113, 25,175, 47,159,218,181, 3, 14, 69, 71, 71, + 15, 15, 8, 8,248,178, 64, 88, 81, 10, 10, 0, 85,170, 84, 25, 19, 23, 23,247, 89,253,250,181, 14, 1,196,255,111, 54,207,183, +238,223,191,191, 63,195, 48, 56,116,232, 80, 8,165,244,199, 35, 71,142,220,211,233,116, 24, 48, 96,128, 55,222,116, 23, 89,194, + 83,127,208,160, 65, 95, 54,111,222, 28,223,126,251,173,225,194,133, 11, 65,148,210, 85,148,210,104,250, 6, 49,148,210,181, 87, +175, 94,173, 61,110,220, 56, 93,131, 6, 13, 48,124,248,240,207, 8, 33,205,203,224,109, 50,112,224,192, 0,134, 97,176,127,255, +254,199,133,196, 85, 65, 25, 94, 58,124,248,240,109,189, 94,143,193,131, 7, 87, 38,132,180, 41, 71,218, 5, 34,145,232,208,130, + 5, 11,108,226,227,227, 49,116,232, 80, 93, 88, 88, 24,230,206,157, 43,177,182,182, 62, 93,218, 24,193, 18, 13, 36, 34,209,150, +159,126,250,169,103,205,154, 53, 49,118,236, 88,253,198,141, 27,199,127,249,229,151,250,160,160, 32,108,216,176,161,167, 80, 40, + 44,215, 18, 32, 9, 9, 9, 89,161,161,161,246,101,109,113,113,113,201, 22,166, 89,170, 80, 40,110, 5, 6, 6,230,212,168, 81, +163,158,201,100, 66,104,104,232,171,157, 59,119, 50, 53,106,212,192,250,245,235,177,108,217, 50,116,235,214, 13, 92, 46,183, 79, +121,226,170, 86,171, 33, 22,139, 33, 16, 8, 16, 28, 28, 12,157, 78, 7,169, 84, 10,177, 88, 12, 46,151, 11, 27, 27, 27, 40, 20, + 10, 0,160,150,197, 21, 52, 39,207, 8, 62,159, 3, 30,135,193,243,152,108, 24,140, 12,196, 2, 46,248, 60, 2, 80, 6, 54, 50, + 62,196, 66, 46, 56,132, 48, 22,114, 34, 91,109,128, 80,192, 1, 95, 32, 36, 28,147, 89,242,246,229,200, 51, 75, 36, 18, 33,113, +176, 18, 65, 44, 96,125,114,179,248,192, 22,172, 2, 43,147, 37, 34, 69,167,211,189, 87, 68,254, 10,206, 18,204,230, 31, 85, 1, +230,228,228,240,110,221,186,165, 16, 8, 4,162,158,117, 26,166, 45, 59,248, 66, 57,111, 79, 56, 68, 60,144,206,129, 52,249,204, +233, 19, 66,149, 74,229,224,239,239,159,110, 9,159, 86,171,253,130, 16,178, 16, 64,117, 30,143,119,114,251,246,237,100,247,238, +221,182, 3, 7, 14,140, 32,132,196, 7, 6, 6,122,109,223,190,221, 10, 0,214,174, 93, 75, 15, 28, 56,208, 17,111, 92, 95, 36, +149,198,155,152,152, 56, 75, 36, 18,221, 12, 11, 11, 91,203,231,243,109,172,172,172,108,175, 94,189, 74,146,179, 13,248,126, 87, +228,219,153,133, 50, 17, 23,211,123, 59, 98,196,136,207,120,161,161,161,203, 1,156, 43,137, 51, 62, 62,126,162, 84, 42,189, 26, + 18, 18,242,163,194,173,150,157, 67,227,137, 86,109,166,191,233,126,116,182, 21,130,147,223, 38,102,101,101, 33, 45, 45, 13, 19, + 39, 78,180,153, 52,105,210, 20, 0,151, 75,137,231,239, 34,145, 40,230,233,211,167, 29,120, 60,158, 72, 46,151,215,185,117,235, + 22,121,157,101,196,244, 29,175,160,210,190,233,109, 85,136,249,152, 55,208, 29,227,198,141,227, 69, 68, 68,252, 0,160, 89, 9, + 47,176,170,181,107,215, 62,116,238,220,185,106, 11, 22, 44,200,120,254,252,185,154, 16, 50,175,104,181,156, 62,125,122,250,233, +211,167,253,186,116,233,114,136, 16,210,175, 60,227, 93, 62, 36,172,172,172,150,142, 30, 61, 26, 7, 14, 28, 64,102,102,230,234, +252, 58,246,227,222,189,123,247,127,241,197, 23,216,181,107,215, 82, 66,200, 89, 11,172, 88,157, 7, 12, 24,128, 51,103,206,224, +226,197,139,223, 83, 74, 67, 75, 16,181, 47, 8, 33, 83,143, 29, 59,182,102,224,192,129,248,229,151, 95, 58, 1, 40,205,241,108, +251,142, 29, 59,226,244,233,211, 72, 79, 79,223, 80,220, 9, 89, 89, 89, 27,143, 31, 63,222,168, 99,199,142, 88,178,100, 73,123, + 0,151, 44, 16, 26, 1,214,214,214,219,215,172, 89, 83,191,102,205,154, 24, 52,104,144,214, 96, 48,116,250,238,187,239, 78,236, +219,183, 79,177,115,231,206,122,163, 70,141,186, 67, 8,249,220, 82, 39,182, 92, 46,119,241,186,117,235, 70,182,106,213, 10, 19, + 39, 78, 52,157, 59,119,174, 7,165,244,119, 66, 72,196,148, 41, 83, 78,173, 92,185,146,187, 98,197,138,145, 92, 46, 55,213,108, + 54,207,248,155,154,144, 5,107,215,174,109,212,161, 67, 7,188,122,245, 10,183,111,223,134,193, 96,216,117,235,214,173,107, 85, +171, 86, 93,160,215,235, 79,200,100,178, 97, 10,133, 34,176, 78,157, 58,109, 8, 33, 82, 75,198,225, 17, 66,178, 34, 34, 34,100, +142,142,142,224,243,249,120,252,248, 49, 28, 29, 29, 1, 0, 41, 41, 41,168, 81,163, 6,184, 92, 46,178,178,178, 0, 32,219, 50, + 49,196, 9,137,136, 78,168,108,167,144, 1,102, 49, 30,134,197, 65,233, 96, 11, 51,225, 32, 41, 41, 17,117,252,221, 65, 8, 65, + 86,122, 18, 8, 33, 79, 44,225, 52, 83, 38,248,117, 66,138,155,189, 66,132,154,141, 58,216,223, 58,155,186,219,186, 74,179, 81, + 60, 46,225,138,196, 86,155, 71, 14, 31,238,192, 48, 20, 89,233,201,224,113, 56,119, 89,201,192,162, 66, 2,171,164, 65,101, 12, +195, 64, 42,149,190, 99, 97, 42, 42, 82,196, 98, 49,140,198,242,141, 37,149, 74,164, 48,154,153, 15,202, 89, 22,254, 10,206,191, + 19, 38,147, 73, 49,105,210,164,134, 13, 27, 54,140,111,219,182,109,148,159,159, 93,108,183, 70, 18,135, 53,219,142,212,233,210, +178,230,131,172,140,148,180, 72, 43, 43, 93,116,116,180,227,214,173, 91, 27, 26,141, 70,139, 6,112, 80, 74, 95, 3,120, 77, 8, +217,216,169, 83,167,175,250,246,237,139,208,208, 80,199,188,188, 60,199,130, 49, 32,187,119,239,198,129, 3, 7, 86, 81, 74, 45, +118,188,169,211,233,206, 2,240, 33,132,216,120,122,122, 38,219,217,217, 9, 18,115,213,111,103, 22, 10,120, 28, 52,253,238, 30, + 50,179,114,224,224,224, 0,133, 66,225,109,129,229,243, 4,128, 19, 85,219, 79,169,165, 9,217,124,101,199,246,237,214, 0,192, +229, 16, 40,173, 5,200,202,202, 66,106,106, 42,210,210,210,192,225,112, 96, 50,153,170, 89, 16,207, 23, 0, 94, 16, 66, 92,219, +180,105,179, 64,161, 80,128,201, 80, 35, 51,215,240, 78, 23,100,110,110, 30, 42, 85,170, 4,133, 66, 81,163,132,151,140, 2,192, +142, 35, 71,142, 4, 88, 89, 89,113, 39, 76,152, 96, 51, 97,194,132,102, 37,137, 49,153, 76,198, 61,126,252,184,175,179,179,243, +246,252,241, 57,217,255, 95,117, 41,223,229,193,152,201,147, 39,215, 19,139,197, 88,191,126,125, 36,128, 61,249,135, 15,109,220, +184,113,246,192,129, 3,253,199,143, 31, 31, 56,107,214,172,137,249, 93,133, 37,250, 72, 18, 8, 4, 65,213,170, 85,195,145, 35, + 71, 0,224, 72, 25,183, 63,124,243,230,205, 53,221,186,117,131, 88, 44,174, 95,198,185,222, 30, 30, 30, 56,118,236, 24, 0, 60, + 44,225,156,135, 97, 97, 97,232,221,187, 55, 8, 33,222, 22,164,189,103,135, 14, 29, 14, 47, 89,178,132,167, 80, 40, 48,114,228, + 72,253,157, 59,119,186, 80, 74,175, 17, 66, 90, 15, 30, 60,248,234,158, 61,123,100, 87,175, 94, 13, 88,180,104,209, 77, 46,151, +187,216,108, 54,207, 42,131,243,179,133, 11, 23, 78,239,213,171, 23,230,205,155, 71, 15, 30, 60, 56,136, 82,250,123,254,243,117, +142, 16, 50,212,214,214,118,207,204,153, 51, 73,118,118,246,116, 66, 72, 28,165,244,167, 82,172, 65,217,102,179,217, 89,173, 86, + 91,100,130,183,244,124, 7, 7,135,206, 29, 58,116,192,172, 89,179, 48,107,214, 44,172, 95,191,158, 2, 56, 73, 41,125, 12,160, + 69, 65, 61,190,117,235, 86, 96,251,246,237, 5,247,239,223,239, 10,224,160, 5,109, 83,244,229,203,151, 29,187,116,233, 34,144, + 74,165, 48,155,205, 72, 79, 79,135, 86,171, 69,141, 26, 53,208,168, 81, 35,164,164,164,224,228,201,147,134,172,172,172,104,139, +218, 59,189,122,231,249, 83,191,181,238, 62, 96,180,181, 68,192,133,217, 40, 68,114,114, 42, 84,102, 19,130,170,121,161,121, 29, + 79,196, 36,107,112,238,228,111,153, 42, 85,222, 78, 75, 56,141,186,188,237, 23,206,158,104,217,188,243, 96,107,153,127, 32,188, + 93,198,215,185,127,243,194,121,177,144, 79, 6, 15,236,103,211,180,110, 85, 60,142,204,193,153,147, 71, 50,179,115,114,182,131, +197, 95,142,143,101,128,187, 37, 22,172,180,137, 19, 39, 58, 76,154, 52, 9, 86, 86, 86,200,204,204,132, 78,167,123, 43, 82,132, + 66, 33,236,236,236,144,150,150,134,253,251,247, 3, 64,169, 99, 20, 56,128,182,247, 87, 63,136, 20, 86, 50,173, 88, 42,161, 14, + 50,197,123,115, 2, 0,135,195,209,125, 58,229, 23,193,200, 30, 13, 56,157,154,252,249,253, 89, 17,206,127, 3, 12, 6,195,239, + 81, 81, 81,245, 7, 12, 24,144,234,225,225,161,209,106,181,208,104, 52,170,147,251,214, 84,113,179, 26, 27,201,225,112,168, 66, +161, 96, 28, 29, 29,179, 47, 94,188,232,104, 50,153,174,148,243, 22, 19,251,245,235,199,185,112,225,194,152, 47,191,252,146, 84, +173, 90, 21,193,193,193, 88,191,126, 61,221,185,115,231, 26, 0,211, 42, 24,245, 92,157, 78,247,142, 5,164,240,204,194,220,220, + 92,232, 53,201, 48,150, 67, 13, 71, 92, 88, 30, 86,185,114,101, 99,160,151,236,109, 88,102,102, 38, 82,211,210,222, 10,172,212, +212, 84, 0, 40, 79, 31,113,206,159,227,201, 20,126,137, 65,155,151, 4,179,217,172, 47,161,161, 80, 17, 66,214, 45, 94,188,120, +229,154, 53,107, 28,231,205,155,151, 17, 18, 18,146,195,229,114,223, 25, 24,104, 54,155,197, 1, 1, 1,138,159,127,254,217,105, +209,162, 69, 25, 0,214,253, 63,139,171, 94, 53,107,214,220,209,185,115,103,197,151, 95,126,137,181,107,215, 34, 49, 49,113, 26, +165,212,148,159, 14,134, 16, 50,101,195,134, 13, 39,167, 78,157, 10,131,193,176,226,244,233,211,243, 8, 33, 99, 40,165,123,138, +227, 84, 42,149,238, 60, 30, 15, 15, 30, 60,200,161,148,190, 42,163, 65, 77,242,243,243, 75, 38,132, 56,185,184,184, 84, 41,237, + 92, 59, 59, 59, 31,133, 66,129,248,248,120, 0,136, 42,225,180,232,132,132, 4, 42, 20, 10,137,171,171,107,213,178,210,111,107, +107, 59,229,231,159,127,230, 93,190,124, 25,115,230,204,137,139,137,137, 25, 76, 41,189,158, 31,183, 7,132,144,230,173, 91,183, +222, 55,117,234, 84,191, 31,126,248,129,132,133,133,141, 69, 9, 46, 74, 10,224,229,229, 53,230,179,207, 62,195,186,117,235,176, +121,243,230,177,148,210, 67, 69,210,188,143, 16, 98,107,111,111,191,110,244,232,209,216,190,125,251, 96, 0, 37, 10,172,152,152, +152,169,173, 90,181,154,157,150,150,182,216,146, 50,181,228,124, 66, 72,235,110,221,186,249,104, 52, 26,108,223,190,253,213,206, +157, 59, 51,205,102,243,254,124,113, 85, 24, 71,127,251,237,183,217,139, 22, 45,194,153, 51,103,182, 19, 66,184,148,210,125,101, +148,105,130, 88, 44, 78,123,252,248,177,115, 64, 64, 0,199,197,197, 5, 13, 26, 52,128,141,141, 13,184, 92, 46, 82, 82, 82,112, +237,218, 53, 38, 34, 34, 34,205, 82,135,163,105,225,151, 79, 56,215,236,242,199,131, 59,215, 58, 4,214,109,202,119,115,176, 67, +227, 64, 55,216,200, 5, 32, 0, 98, 82, 52,184,116,233,188, 49, 42,234,213, 45, 75,102, 16, 22,112,186,214,234,122,211,198,209, +179, 67,245, 58, 77,121, 85,252,125,209,161, 69,109, 91, 91,153, 0, 12,165,120, 28,153,141,243,191,159, 53, 38,196,197, 94,102, +103, 16,178,248,208, 2,107,249,166, 77,155, 26,252,252,243,207,237, 39, 78,156, 40, 31, 54,108, 24,196, 98, 49,242,242,242,224, +238,238, 14,179,217,140,179,103,207,226,254,253,251,185, 12,195,156, 7,112,183,200, 3,220,174,176,175,140,179, 17, 84,250,198, +121,165,186,193,145, 26,181, 62, 8, 39, 0,200, 95, 50, 86,233,149,244,187,215, 30,186,209,123,239,185, 7,228,219,129, 45, 57, + 65,254, 30, 0, 80, 97,206, 15,240,210,250,203, 57, 77, 38,211, 72, 66, 72,224,148, 41, 83,150,185,185,185,185,206,155, 55,239, +117,245,234,213, 53, 57, 57, 57, 84,175,215, 51,105,105,105,210, 67,135, 14,121,167,167,167,171,140, 70,227,208, 98, 26,206, 82, +227, 73, 41, 53, 0,248,146, 16,114, 60, 59, 59,251,220,119,223,125,135, 69,139, 22,225,196,137, 19,205, 41,165,127, 84, 52,237, +148, 82,147,183,183,119,214,195,135, 15,157,132,246,190,112,178, 17,160,211,247,111,140, 17, 10, 17,129, 70,173,194,243, 39,143, +145,147,147,115,191, 28,156,122, 55, 55,183,236,228,228,100, 7, 39, 39,167, 55,226, 42, 53,245,173,184,202,200,200, 64,122,122, + 58, 5,240, 71, 57, 56,213, 62, 62, 62,121,207,159, 63, 23,114,165, 30,112,182, 21,225, 77, 23, 36,133, 82,193,131, 90,173,194, +179,219,183,144,157,157,125,165, 36, 78, 74,233,254,124,183, 71, 43, 87,174, 92,233, 80,175, 94,189,151,209,209,209, 45, 11,223, +199,221,221,253,232,234,213,171,187, 78,157, 58, 53,109,253,250,245, 83,139, 58,182,252,171,235,146,189,189,253,164, 83,167, 78, + 41, 12, 6, 3,214,174, 93,139, 85,171, 86,109,163,148,254, 90, 36, 47, 78,113,185,220, 13, 28, 14,231,171,175,191,254, 26,163, + 71,143,150,214,171, 87,111, 98, 33, 43,215, 59,156,241,241,241,179,130,130,130,102,167,164,164, 88, 36, 8, 94,188,120, 49, 42, + 40, 40,104, 86, 74, 74,202,178,210,210, 46,147,201,100,102,179, 25, 81, 81, 81,153, 37,137, 80, 74,169,214,215,215, 55,222,108, + 54,187, 75,165, 82,187,178,234,103,102,102,230,226,122,245,234,205, 77, 78, 78,254, 29,192,194,162, 46, 71, 40,165,143, 8, 33, +129,223,124,243,205,184,165, 75,151,246, 78, 74, 74,218, 95, 22,103, 76, 76,204,226,214,173, 91,127, 31, 30, 30,190,131, 82,186, +185,132,120,174, 39,132, 24,118,239,222, 61, 54, 42, 42,106, 73,105,156,148,210,147, 0, 78,150,195, 10, 80,236,249,133, 57,185, + 92,238,148,165, 75,151,114, 54,109,218, 4, 74,233, 10,147,201, 84, 82, 60, 31,115,185,220,157, 77,155, 54, 29,118,232,208, 33, +113, 96, 96,224,104, 0,251,202,170,159, 58,157,238,246,205,155, 55, 27, 69, 71, 71, 59,180,110,221, 90, 0, 0, 57, 57, 57,200, +202,202,194,201,147, 39, 13, 17, 17, 17,105,106,181,250,118,121,218, 16,147, 62,103,224,205, 75,199,246, 69,191,120,210,184, 85, +167,158,182,122,131, 59, 68,233, 92,100,165, 39,225,236,201,223, 50,163,162, 94,221,202,203,203, 26, 88, 30, 78,131, 46,123,192, +173,203,199,247,199, 69, 61,111,212,162,117, 23, 91,173,222, 11, 34, 1, 7,233,201,241, 56,123,234, 88, 70, 84, 84,228,117,173, + 81, 55,252,239,106,231,255, 75,156, 31,163, 57,174,204, 13,128, 0, 64, 59,185, 92,190,104,246,236,217, 43,238,220,185,179,162, + 91,183,110, 43, 68, 34,209, 34, 0,237, 0, 8, 74,184,174,221,255, 39,103,125, 87,216,181,174, 66,174,117,240, 33,204,152,230, +182,230, 17,141,100,186,247,229,172,232,246,255,205, 9,160, 25,159,207,191, 85,179,102,205,203, 10,133, 34,181, 82,165, 74,215, +249,124,254, 93, 0, 45,222, 55,158, 0, 28,250,247,239,207,168, 84, 42,218,175, 95, 63, 10,192,250,125, 57, 69, 34, 81,155, 86, +173, 90, 25, 95, 39,102,210,235,143, 98,233,201,171,161,116,239,137, 91,116,243,190,115,244,199, 13,191,208, 90,181,106,233, 1, +120,149,135, 83, 40, 20,118,106,213,170, 85, 86, 90, 90, 26, 13, 11, 11,163,215,174, 93,163,135, 15, 31,166,155, 55,111,166, 27, + 55,110,164,174,174,174,233, 0, 92,203,195, 41,145, 72,122,118,234,212,201, 20,159,154, 75,111,135, 38,209, 11,119, 94,209,163, + 23, 31,211,253, 39,111,209,109,187,127,165, 1, 1, 1, 90, 0, 78,101,113, 2,232,223,182,109,219,151, 54, 54, 54,155,138, 30, +147,201,100, 27,218,180,105, 19, 3, 96,232,223, 81,151, 0,116,114,115,115, 11, 19, 8, 4,167, 74,138, 67,161,115, 7,240,120, +188, 19,206,206,206,247, 0,124,242,255, 93,231, 1,116,115,116,116,188, 13,160, 71, 25,215, 21,156,215,235, 99,124,222, 63, 80, +185,183,225,241,120,215,240,198,199,149, 37,239,128, 5, 92, 46,247, 52,128,182,229,137, 39, 0, 87,185, 92,222, 76, 46,151,119, +151,203,229,221,109,108,108,154, 21,126, 14, 43,146,118,123,223,118,221, 61,235,246, 56,234, 81,187,107,140,103,157,110, 49,222, + 65, 61,143,218,251,182,235,254,190,156, 94, 65, 61,143,121,214,233,246,218,179, 78,247,232,202,245,123, 30,117,240,111,215,249, + 99, 43,247,127, 50,103, 9,247, 25,245,255,113,159,191, 98, 35,150,207,184, 6, 8, 33, 50, 0,237, 1,212, 3,112, 31,192,249, +210,252,162, 88,162,112,255, 10,206,198,174,196, 79, 38, 37, 71, 4, 60,174,227,233, 48,211, 23, 31,130,243,223,242,197, 64, 8, +233,201,227,241,190, 51,153, 76,203, 41,165,199, 62, 84, 60,173,173,173,127,238,208,161,195,136,163, 71,143,110, 52, 24, 12,227, + 62, 4,167,131,131,195,202,170, 85,171,142,235,215,175, 31,223,221,221, 29,105,105,105, 8, 13, 13,197,181,107,215,244, 9, 9, + 9, 99,210,211,211,119,148,151,211,197,197,101,161, 82,169, 28, 59,121,242,100, 91, 30,143,135,244,244,116,100,100,100,208,237, +219,183,167,171,213,234, 47,210,211,211,143,151,151,211,201,201,105, 75,213,170, 85,135, 15, 25, 50,132,239,229,229,133,180,180, + 52, 60,124,248, 16,231,206,157,211,189,126,253,122, 72,110,110,238,175,150,112, 18, 66,132, 37,249, 61, 34,132,240, 75,114,138, +201,126, 37,179,156, 44, 39,203,249, 95,181, 96, 17, 66, 70, 81, 74,183,224, 95, 8, 94,121, 78,206, 23, 41, 71, 8, 33, 39, 10, +198,103,124, 0, 11,218, 7,231,188,149, 64,195, 1, 4, 16, 66,120, 31,138,243, 95,100,145, 60, 6,224,216,135,230,205,206,206, +254,156, 16, 50,158, 82,170,249, 80,156,105,105,105,147, 8, 33,187, 95,189,122,181, 66, 38,147,213, 49,155,205, 70,173, 86,123, + 35, 53, 53,117, 34,165, 52,182, 34,156,137,137,137,179, 8, 33, 71,166, 77,155, 54, 13, 64, 45, 66,136,222,104, 52,222, 76, 73, + 73,153, 79, 41, 77,172, 8,103,114,114,242, 40,129, 64,240, 75, 68, 68,196, 18,137, 68, 82,139, 97, 24,125, 94, 94,222,149,180, +180,180, 9,148,210,228,114,148,141,190,148, 99,236,186,131, 44, 88,176, 96,241, 17,129, 87,145,139,254, 10,209,242,111,225,252, + 47,227, 67,138,171, 66,156,143, 1,180,253,192,156, 15, 1,244,253,144,156, 6,131,225, 14, 44, 92,155,141, 5, 11, 22, 44, 88, +176,224,177, 89,192,130, 5, 11, 22, 44, 88,176,248,187, 64, 8, 25,245, 81,166, 11,111, 6,127, 23,103, 5,184, 80,142,204,105, + 87,222, 27, 91, 48,150,136,229,100, 57, 89, 78,150,147,229,100, 57, 89,206,143,140,179, 44,238,143,102,118,226, 95, 60,250,159, +157, 97,193,114,178,156, 44, 39,203,201,114,178,156, 44,231,127,110, 99, 23, 88, 98,193,130, 5, 11, 22, 44, 88,176,248,192, 96, + 5, 22, 11, 22, 44, 88,176, 96,193,130, 5, 43,176, 88,176, 96,193,130, 5, 11, 22, 44, 88,129,197,130, 5, 11, 22, 44, 88,176, + 96,193, 10, 44, 22, 44, 88,176, 96,193,130, 5, 11, 22, 21,199, 59, 75,229, 16, 66, 40,165,148,176,217,194,130, 5, 11, 22, 44, + 88,176,248, 91,132,201, 71,162, 69, 88,129,197,130, 5, 11, 22, 44, 88,176, 96, 5, 22, 43,176, 88,176, 96,193,130, 5, 11, 22, +172,192,250, 23, 8,172,130,196,176, 2,139, 5, 11, 22, 44, 88,176, 96,241,119, 10,171,143, 69,139, 20, 12,114,111, 69, 8,161, + 96, 23,179,101,193,130, 5, 11, 22, 44, 88,252, 61,248,168,180,200, 59, 93,132, 44, 88,176, 96,193,130, 5, 11, 22, 44, 88,129, +197,130, 5, 11, 22, 44, 88,176, 96,193, 10, 44, 22, 44, 88,176, 96,193,130, 5,139,143, 29,127,169,163, 81, 66, 72, 59,150,147, +229,100, 57, 89, 78,150,147,229,100, 57, 89, 78, 86, 96,177, 96,193,130, 5, 11, 22, 44, 88,176, 96, 5, 22, 11, 22, 44, 88,176, + 96,193,130, 5, 43,176, 88,176, 96,193,130, 5, 11, 22, 44, 88,129,197,130, 5, 11, 22, 44, 88,176, 96,193,130, 21, 88, 44, 88, +176, 96,193,130, 5, 11, 22,127, 19, 8,128, 98,103, 2, 80, 74, 47, 88, 76, 82,129,217, 4,101,241,179,156, 44, 39,203,201,114, +178,156, 44, 39,203,249,241,113,150,197, 93, 30,253,241,143, 6,165,244, 47,219, 0,180, 99, 57, 89, 78,150,147,229,100, 57, 89, + 78,150,147,229,252,175,109, 60,214,136,199,130,197,191, 28,135, 9, 23,153,254,222,160,212, 21, 92, 97, 34, 18, 67, 94, 97, 14, +101,222,155, 51,185,186, 23, 36, 70, 39,152,196,169, 72,126, 28,249,222,156, 44, 88,176, 96,241, 31, 2, 43,176, 88,176,248,183, + 35, 53,192, 15, 60, 44, 1, 7, 46,160,134, 8, 40,171, 47, 1,240,228,189, 57, 5,204, 66,152, 57,238,160,134,112, 56,250, 47, + 5, 16,202,102, 54, 11, 22, 44, 88, 88,134,191,101,144, 59,159,207, 15,230,243,249, 11, 8, 33, 34,182, 8, 88,252, 85, 32,132, +136,248,124,254, 2,177, 88, 28,252,209, 38,114,119, 77, 41, 56,230,206,122, 35,227,118, 54, 36,203, 49, 79,103,246, 3,199,212, + 5,191,248,201,223,139,147, 71, 58,104, 13,140,231,158,187,121, 78,106,189,169, 26, 40,222,143,243,127,101, 98, 35, 20, 10,207, + 18, 66, 28,216, 26,250,113,162, 58, 33,245,234,243,249,147,171, 17,210,134, 16, 66,216, 28, 97,193, 10,172,255, 71,152, 76,166, +186,190,190,190, 19,121, 60, 94, 12, 33,164,199,127, 41,195, 37, 18,201, 77,185, 92,158, 44,151,203,147,101, 50,217,131,194,225, + 50,153,236, 79,225, 31,169,240,241,115,116,116,140,177,183,183, 15, 47, 28,238, 88,187,119, 19,223,102,195,230, 56, 4,246,106, +249, 1,238,209,131,207,231,199, 4, 6, 6, 78,208,233,116,117, 63,218,204,212, 50, 78,224,112, 91, 63, 77,204,147, 38,230, 24, +157,130,163,243, 20, 0,183, 21,244,112,169, 48,103, 54,227, 4,208, 54,143,226, 52,178,155, 25, 74,167,235,175,116, 86,224,112, + 90, 67, 75,156,223,187,193,225,112,198, 50, 12,211, 94, 32, 16,124,203, 54,191, 31, 39,132, 28, 78,211,155, 61,122, 44,156, 90, +171,214,184, 0,160,123,113, 34,139,188,193,248,106,213,170,157, 33,132, 12,248,128,109,203, 15, 1, 1, 1,241,132,144,111,216, +146, 96,241,175, 17, 88,125, 43,147,166,131,170,144,171,253, 43, 19,213,128, 42, 36,119,104, 21,114,163, 79,101,210,166,162, 55, +126,240,224,129, 36, 36, 36,196,177, 73,147, 38,251,197, 98,241, 13, 66,136,111,133, 30,102,161,240, 44,143,199,235, 91, 76, 88, +255, 34, 97, 79,133, 66, 97,182, 80, 40,124,101, 9, 47,159,207,127,201,227,241,212, 2,129,224,101,225,112, 30,143,215, 95, 36, + 18,157, 45, 18,214,183,104, 88, 41,188,238,209,209,209,142,177,177,177,142, 66,161,208,169, 32,156,203,229,186,199,196,196,252, + 41,188,188,224,243,249,109, 68, 34,209,225,178,194, 74,131, 72, 36,250,149,207,231,183, 41, 43,172,162,226,170, 67,135, 14, 55, + 18, 19, 19, 61,109,108,108,108, 10, 31,179,179,182,233,184,107,219,134,137, 61,187,116, 24,235, 88,253,147,154, 21,228,247, 21, +139,197, 55,130,130,130,246,159, 60,121,210,113,215,174, 93,210,143,246,233, 61, 92, 93, 0,194,180, 96, 40, 85, 62,139,215, 42, +187,246,232,203,123, 24,171, 81, 26,205,102, 59,128,219, 10, 59, 42,137, 42,196,201, 51, 54,103, 40,117,186, 24,205, 87,182,238, + 55,142,123, 41,154,167, 52,154,205,246,224,160,101,133, 56,255, 87, 54,124, 46,151, 59,113,229,202,149, 28, 0, 95, 19, 66,132, +255,165,198,182,161, 27,113,107, 91,149,119, 55,200,149, 52,253,128,130, 34, 80, 38,147,221, 39,132,248,253, 83,210,169,103,152, +176,253,145,145,231,134,248,248,116,155, 90,171,214,136,162, 34, 43,255,247,212,165, 75,151, 14,125,250,244,169,178,114,229,202, +163, 9, 33,156, 15,144, 23,171,151, 46, 93, 58,229,233,211,167,174,222,222,222,243, 62, 4, 39,139,127,150,118, 7,208, 26, 64, + 87, 0,109, 1, 52,200,255, 93, 63,127,235,138, 55, 94, 17, 10,239,235,231, 95, 91,112,188, 97, 9, 28, 93,139,185,174,126,161, +240,194,255,139,254, 46, 25,249,179, 1,104,225,125,209,173,191, 55,230,142,107,226,150,247,236,196, 94,154, 27, 27, 73, 51,159, + 63,164, 15,183, 44,166,227,234, 43,243, 6, 85,198, 15, 21,152,125, 64, 41,165,244,244,233,211, 84,165, 82,209, 95,127,253,149, +113,116,116,212, 10,133,194,213, 0,100,229, 26,165,207,227,229, 90, 89, 89,169, 4, 2,193,118, 0, 66, 74, 41,248,124,126,174, +173,173,173, 74, 32, 16,236, 6, 32,162,148,162,125,251,246, 26, 74, 41, 21, 8, 4,106, 75,120, 59,116,232,160,166,148, 82, 30, +143,167,206,143,179, 72, 32, 16,236,170, 86,173, 90, 14,159,207,207,205, 15, 19,138, 68,162,237,129,129,129, 57, 2,129, 32,215, + 18, 94, 43, 43,171, 88,147,201, 68,215,173, 91, 71,237,237,237, 19, 10,194, 21, 10, 69,172,201,100,162,107,214,172,161,118,118, +118, 9, 21,200, 83,142, 88, 44, 94, 94,179,102,205, 44,177, 88,156, 94, 40,108, 69,237,218,181,179, 37, 18, 73,186,165, 92, 34, +145, 40,221,222,222, 62, 83, 40, 20,174, 0,192,161,148, 66, 44, 22,167, 59, 58, 58,102,136,197,226,229, 5, 97,150,108,174,174, +174,163, 29, 29, 29, 19, 28, 29, 29, 19,108,108,108, 22,185,184,184, 36,165,166,166, 82, 74, 41,173, 82,165, 74, 10,165, 20,202, + 90,159, 52,169,218,116,232, 28,199,192, 30, 19, 54, 29,186,117,231,218,147,244,212, 90,237,199, 46,183,174,213,211,186, 28,233, +151,241,249,252,213, 78, 78, 78,218,125,251,246,153, 35, 35, 35,233,185,115,231,232,139, 23, 47,104, 73,245,250, 95,191,109,168, +238, 78, 55,251,239, 15,157,237,249,252,218,210, 78, 70, 26,125,137,238, 29,161, 52, 94,157,224, 22, 65,127, 10,248,149,110,174, +230, 81, 33,206,159,170,237,125, 60,211, 51,108,221,188,241,198,152,152, 24, 58,121, 88, 39,211,239,227,220, 94,209, 77, 1,135, + 42,196,249,191, 50, 26,248,201, 39,159,228,190,126,253,154, 86,175, 94, 93,205,229,114, 71,254, 87,102, 19, 53,112,133, 91, 59, + 63, 97,252,227, 61,147,153,238,129,210,244,186, 46,104,250, 1,102,113, 5, 58, 58, 58,166,237,216,177,131, 42, 20,138, 20, 0, +126,255,132,180, 2, 32, 1, 64,143,157,181,106, 29, 99,250,244, 49,239,172, 85,235, 88, 0,208, 3,111,220, 2, 17, 0,211,150, + 45, 91, 22,108, 52, 26,131,183,111,223, 30,220,163, 71,143, 96, 0,147,223,243,158,107,126,248,225, 7,106, 52, 26,233,246,237, +219,105,143, 30, 61, 40,128,181,150, 94, 47,151,203,171,214,172, 89,115,119,245,234,213, 95,215,174, 93, 91, 95,173, 90, 53,173, +159,159, 95,116, 96, 96,224, 14,145, 72,228,205,206,136,251,127,171, 59,165,105,145, 6,211,166, 77,155, 14,128, 78,155, 54,109, + 58,165,180,107,254,121, 93, 11,255, 46,186,167,148,182, 43,252,191, 56,142,130,173, 56,206,226,238, 81,228,119,201,233, 41, 72, + 12,128,150, 0,174, 22, 61,161,111,101, 52, 25,215,196, 77,163, 73, 77,164, 79, 22,127, 75, 47,183,118,167,127,180,114,166,225, + 19, 63,161,137,123, 86,211, 47,235,216,230,245,169,140,214, 21, 17, 88, 43, 87,174,164, 91,182,108,161,193,193,193, 52, 38, 38, +134, 78,157, 58, 85, 47,149, 74, 51,185, 92,238, 96, 75,185,132, 66, 97,246,139, 23, 47,232,196,137, 19,117, 66,161,240, 37,128, +202, 98,177, 56, 59, 50, 50,146,206,156, 57, 83, 47, 18,137, 34, 1,248, 10, 4,130,220,187,119,239, 82,161, 80,104,145,192, 18, + 8, 4,217,167, 79,159,166,124, 62, 95, 13,192,215,214,214, 54,242,212,169, 83, 70,134, 97,168,179,179,115, 14,128,202,246,246, +246, 47,207,156, 57, 99,100, 24,134,186,184,184,228, 88,194,107,109,109, 29,155,155,155, 75,183,109,219, 70, 29, 28, 28, 18, 10, + 11, 47,149, 74, 69,183,108,217,242, 78,184,133,249,233,228,228,228,244,176, 32, 46,158,158,158,169, 0,156, 28, 29, 29, 31,157, + 63,127,222, 72, 41,165,149, 42, 85, 74,181,148,207,193,193, 33, 37, 42, 42,138, 46, 94,188, 88, 39,149, 74, 31, 0,112, 82, 42, +149, 41, 49, 49, 49,116,201,146, 37, 58,169, 84, 26, 12,192,201, 66,174, 4,189, 94, 79,179,178,178,104,195,134, 13,115,255,248, +227, 15,154,147,147, 67,243,227,148, 66, 41,133,127,203,145, 11,238,188,200,205,249,108,202,134,131,222, 13, 6, 45, 62,119, 55, + 62,238,231,163,247,131, 29, 2,123,118,178,228, 30, 92, 46,119,176, 68, 34,201, 92,178,100,137, 33, 57, 57,153,222,187,119,143, + 30, 60,120,144, 30, 58,116,136,190,122,245,234,227, 20, 88,135,192,165,155,253,123,210,205,254,193, 59,134, 56,164,169, 30,236, +163,244,252, 55,244,213,130,202,116,118, 39,133,138,217,236, 31, 76, 55, 7,244,161,115, 91,242,202,197,185,165, 90,119,186,217, + 63,248,135,190, 94,233, 15,131,239,209,171, 87,175,210,141,171,151,209,113,237,220,212,204,102,255, 96,250, 83,181,222,229,226, +124, 87,184,191,184,113,227, 6,189,118,237, 26,157, 55,111, 30,149, 74,165,175,223, 63, 31,170, 9,232, 79,126, 94,116,171, 95, + 75,186,205,215,133, 94,169, 88,220,254,106,113,213,222, 79, 24,151,246,240, 40,165, 25, 47,105,210,138,234,180,147, 63,255,189, + 68, 86,190,184, 74,141,142,142,166, 73, 73, 73,116,213,170, 85,212,202,202,234, 31, 45,178,252,129,158, 0,166, 47, 95,190,252, +173,184,218,176, 97, 67,112, 72, 72, 72,176,167,167,231,233,247,184,215,218,229,203,151,191, 21, 87, 27, 54,108,160, 33, 33, 33, +212,203,203, 43,182,172,107,135, 12, 25, 34,109,210,164, 73,240,224,193,131,243,118,236,216, 65,163,163,163,233,227,199,143,233, +242,229,203,233,156, 57,115,232, 47,191,252, 66,123,247,238,173,110,216,176,225,157, 62,125,250,136,203, 25, 55, 30,165, 84,152, +191,241, 41,165, 5, 2,147, 7,128, 15,128,203,138,170, 63,107,131,146,180, 72, 73, 34,170, 36, 97, 85,244, 88, 41, 2,172, 84, +161, 86,214,253, 74, 75, 79, 97, 19,234, 21, 74,233,159,198,190,240, 40,230,143,154,180, 64, 28,181, 99, 21,146, 15,172, 7, 55, + 43, 25,124, 85, 58,116, 55, 78,193,120,227, 56,134, 54,110, 44,145, 16,178,176, 34,246, 62,185, 92, 14,129, 64,128,151, 47, 95, +226,249,243,231, 24, 49, 98,132,224,226,197,139, 54, 77,154, 52,217, 34,147,201, 30, 17, 66,106, 89, 48,166, 3, 85,171, 86,197, +248,241,227,133, 27, 54,108,168, 34,147,201, 30,152,205,102,190,183,183, 55,190,254,250,107,193,246,237,219, 43, 89, 89, 89,221, + 99, 24, 70, 32,149, 74, 97,233,152, 75, 46,151, 11,137, 68, 2,134, 97,248, 65, 65, 65,247,159, 60,121,226,221,190,125,123,222, +249,243,231,145,145,145,193, 11, 10, 10,122, 20, 18, 18,226,211,174, 93, 59,222, 31,127,252,129,156,156, 28,106,161, 25, 27,121, +121,121, 16,139,197,239,196,165, 32, 92, 36, 18,161, 60,227, 66,249,124,126,155,198,141, 27, 63,125,248,240, 97,237,182,109,219, +242,174, 92,185,130,244,244,116,126,189,122,245,158, 62,122,244,168, 86,235,214,173,121,183,110,221, 66, 86, 86,150,197, 83,236, + 37, 18, 9, 42, 85,170,132,207, 62,251, 76,248,203, 47,191,212,182,179,179,123,204,231,243,133,158,158,158, 24, 49, 98,132,112, +219,182,109,117,236,237,237, 31, 89,216,101,200, 5, 0,163,209,136,209,163, 71,203,172,172,172, 16, 27, 27, 11,134, 97, 96, 54, +155, 1, 0,233,153,233, 33,143, 66,158, 60, 31, 58,176,111, 75,141, 65,167,187,117,247,254,179, 42,149,188,220, 9,161,149,202, +200,203, 90, 34,145,232,209,167,159,126,186, 53, 58, 58,218,102,192,128, 1,252,251,247,239,227,245,235,215, 16,137, 68,144,203, +229,224,241, 62,210,137,178, 57,213,237,193,160,125, 76,170, 94, 36,178,113, 87,200, 93,252,128,215,215, 80, 89, 41, 2,151,195, + 21,223,139,204,147, 1,180, 61, 60,211,236,203,199,201,180,143, 76,209,139,140,118, 53,228,174,238,158, 72, 79, 79,135, 71,149, + 0,104,133, 74,225,205,151,106, 57, 72, 57, 57,255, 87, 86,205,125,125,125,157,171, 86,173,138,180,180, 52,212,173, 91, 23,182, +182,182,182,132,144,246, 21,206,131, 29,149, 68,200, 65, 83,128,179, 2,102, 50, 15, 70,222, 18,188, 76,173,139, 45, 65,252,127, + 82,183,160,149, 92,120,123,223,254, 3,110,246,158,213,128, 83,159,193,201, 70,132,109, 99,235,218, 41,173, 69,199, 42,210, 93, + 72, 8, 9,116,114,114,186,116,231,206, 29, 7,177, 88,140, 7, 15, 30,160,122,245,234, 88,181,106,149,210,214,214,246,218, 63, +161,187,144, 82, 74,159, 3, 39,126,120,252,120,251,238,136,136,147, 67,124,124,186, 13,246,243, 91, 52,102,192,128,145,227,199, +143,199,178,101,203,112,236,216, 49, 52,109,218, 20,163, 70,141, 50,190,126,253,122,103, 5,187, 5,215,175, 88,177, 98,220, 55, +223,124, 83,148,211, 16, 19, 19,243, 67,105,215, 6, 6, 6,186,191,120,241, 34,126,226,196,137,117,119,239,222, 45,145, 74,165, +200,202,202,194,214,173, 91, 49,125,250,116, 16, 66, 64, 41,197, 47,191,252, 34, 29, 49, 98, 68,131,136,136,136,248, 74,149, 42, + 89, 50,124,131, 0, 16, 3,144,230,111, 50, 0,210,125,251,246, 89,247,236,217,211, 42, 63, 76, 2, 64,194, 78,244, 42, 22,197, +106,145, 66,101,126,178, 72, 93,235, 86, 52,172,232, 49, 74,105,183,210, 56,202, 89,183,187, 89,122,125, 97,129,213,138, 16,114, +245, 79,100, 64, 45,103,111,127,100,159, 63, 4, 9,143, 64,194,205,223,120, 4,156, 87, 33,240, 16,243, 97,164, 52,176,162, 2, +171, 96,227,112, 56, 72, 76, 76,132, 72, 36,194,174, 93,187,196, 43, 87,174,172, 41,149, 74,111, 89, 91, 91, 47, 41, 75, 96, 1, +192,189,123,247, 80,187,118,109,178,119,239, 94,171, 65,131, 6,241, 0, 32, 36, 36, 4, 53,106,212, 32,199,143, 31, 87,140, 29, + 59,150,200,100, 50,139,197, 11, 33, 4, 18,137, 4, 35, 70,140, 32,183,110,221,146, 75, 36, 18,156, 58,117, 10,169,169,169, 24, + 57,114, 36,239,214,173, 91,114,153, 76,134,107,215,174, 33, 59, 59,187, 92,188, 90,173, 22, 18,137,228, 79, 2, 75,163,209, 64, + 34,145, 88,156,127,118,118,118,115,106,214,172,121,248,234,213,171,246, 18,137, 4, 87,174, 92, 65, 86, 86, 22,102,206,156, 41, +189,121,243,166,189,149,149, 21,242,197, 21,184, 92,174,229, 3,243, 10,229,169,175,175, 47,217,183,111,159, 99,255,254,253,197, + 0,240,240,225, 67,248,249,249,145,189,123,247, 58, 85,169, 82,229,144,157,157,221,236,210,184, 24,134, 65, 98, 98, 34,158, 62, +125,138, 87,175, 94, 33, 53, 53, 21,105,105,105, 80,169, 84, 48,153, 76, 0, 0,169, 42,231,212,190,131, 39, 30, 73, 36, 18,105, +117, 63, 95,207,144, 39,161, 41, 18,137, 68,234,229,233,233, 71,200, 60, 78, 9, 34,112,137, 72, 36,186,117,232,208,161, 90, 91, +183,110, 21,189,120,241, 2, 15, 30, 60,248, 83,189,250, 40, 5, 22, 33, 4, 68,239, 11, 66,234,222,126,165,182,107,222,109,160, + 0,145,103, 1,198, 8,112,120,104, 85,203,157,119, 44, 68,237, 4,138, 90,208, 33, 0,176,160,114, 18, 66, 0, 67, 85,128,212, +251,253,133,201,190,233, 39, 99, 5,241,241,241, 16, 8, 4, 16,137, 68,168,219,230, 83,222,190, 71, 70,103, 16,212,134, 1,254, + 22,113,190, 91, 94,223,207,153, 51, 71, 86,152,115,228,200,145, 50,107,107,235, 57, 21, 22, 87,106,105, 99,152,232, 55, 79,227, +243, 42, 45, 58,149, 84, 45, 34, 69,227, 15, 74, 39, 2,198, 58,239, 43,178, 8, 33,173,196, 98,113, 36, 33,164,217,123,137, 43, +133,240,214,254,253, 7,220,236, 60,222,136, 43,152,180, 0, 95, 2,103,165, 13,182, 77,104,109,167,180,145,148, 75,100,229,139, +171,139,183,111,223,118, 16,139,197, 8, 14, 14,134, 64, 32,128, 88, 44, 70,205,154, 53,177,121,243,102,165,157,157,221, 63, 74, +100, 45,125,252,120,199,146,167, 79,195,167, 5, 6, 6,244,146,201,236,190, 26, 60,216,122,230,204,153, 39,143, 31, 63,190,189, +107,215,174,105,119,239,222,253,145, 82,122,168,156,229, 67, 8, 33, 27, 86,174, 92,249, 85,129, 96,155, 57,115,230, 47,199,143, + 31, 95,210,181,107,215,196,187,119,239, 78,164,148,110, 40,141, 35, 55, 55,247,248,172, 89,179,172, 63,249,228,147,130,255,184, +113,227, 6,118,238,220, 9,153, 76,246,206,185, 61,122,244,192, 23, 95,124, 97,171,215,235,127, 45,141,211,201,201,169,237,237, +219,183,171, 3, 16, 0, 16, 21, 8,172, 39, 79,158,216,228,228,228,216,200,229,114, 27, 23, 23, 23, 69,129,200,250,228,147, 79, +108,248,124,126, 51,176, 64, 89, 90,164,176,192,177, 36,172,162,231, 91, 42,178,202, 37,176, 40,165, 87, 1,180, 40,238, 36, 67, + 70, 50, 68, 48, 67,194, 37,144,114, 11,137, 44, 48,224,101,167,160,162, 19,113, 11,191, 8, 21, 10,197, 91,161,149,151,151,103, +177,104, 41, 56,199,214,214, 22, 42,149, 10, 70,163, 17,114,185,252,109,152, 78,167,131,217,108,134, 76, 38, 67,121, 44, 88, 5, + 2,139, 97, 24, 92,187,118, 13,127,252,241, 7,120, 60, 30,236,236,236,192, 48, 12,110,221,186,133,144,144, 16, 8, 4, 2,216, +217,217,149,139,215, 96, 48, 20,107,193, 50, 24, 12, 16,137, 68,111, 5,142, 37, 66, 72,171,213,210, 71,143, 30,225,201,147, 39, + 16,137, 68, 80, 42,149, 16,139,197,136,143,143,199,243,231,207, 33, 20, 10,161, 84, 42, 45,230, 44, 44,176,172,172,172,144,153, +153,249, 70, 4, 73,223,140, 21,183,182,182,134, 90,173, 6,143,199,123,187,149, 6,179,217,140,132,132, 4,164,166,166, 34, 54, + 54, 22,105,105,105,111, 69, 22,195, 84,220,111,101, 65, 28,111,220,184, 65, 47, 93,186, 4,149, 74,245,167,186, 84, 96, 33,253, +232,176, 49,208, 26, 70,126,135,180, 92,163, 40,213, 32,176,118, 10,108, 7, 68,158, 1, 56, 60, 64,108,139, 70, 53, 42, 35, 38, +211, 44, 11, 75,214,139, 65,208, 17, 27,252,108, 45,226, 52,243,219,167,170,140,162,104,131,210,170, 90,173, 32, 36, 39, 39, 67, + 36, 18, 65, 36, 18,161, 94,211,118,136, 76, 55, 75, 67,227, 53, 82, 80,116,176,136,243,127,117,187,138, 92, 46,111,220,172, 89, + 51, 82,152,179, 75,151, 46, 32,132,212, 36,132, 4,148, 43,253,235,124,132, 48, 72, 27,129, 71,191, 9, 77,204,115, 61,246, 68, +235,215,189,215,167,118,107, 46,164, 84,123,150,164,243, 6, 53, 78, 2, 53, 4, 85, 84,100, 17, 66, 90, 42, 20,138,147,235,214, +173,243, 22,139,197,103, 8, 33,205, 43,212,190, 73,184,155,190,255,106,160,155,109,129,184, 50,230, 1, 60, 9,192,151, 0, 60, + 9,156, 29, 29,176,240,139,246,118, 82, 49,255,183,114, 8,213,125, 27, 54,108, 80, 22, 21, 87, 5, 91,221,186,117, 49,123,246, +108,165,157,157,221,222,191,249, 27,160,131,141,141,205,238,118,237,218,221, 78, 80, 40,190, 72, 12, 10, 18, 94,180,182,206,110, +155,157,109,237,245,228,137,193, 31, 8, 1,176, 49, 54, 54,182,147,165,226,138, 16, 50,192,218,218, 58,184, 93,187,118, 6,133, + 66,241,122,213,170, 85, 95,126,253,245,215, 88,182,108, 25,102,205,154,181, 21,192,231,148,210, 25,177,177,177,174,101,137, 43, + 0, 72, 74, 74, 26, 52,117,234,212,180,180,180, 52, 0, 64,205,154, 53,145,149,149,133,201,147, 39,227,219,111,191, 5, 0,212, +169, 83, 7,148, 82, 36, 39, 39, 99,197,138, 21,201, 73, 73, 73,195,203,104,239, 98, 15, 29, 58,212,192, 96, 48,184,231,119, 3, +138,178,178,178,172, 50, 50, 50, 20, 6,131, 65,198, 48,140,204,198,198, 70, 14, 64, 58,116,232, 80, 94,104,104,104, 53,147,201, + 20,207,106,170,119,196, 75,137, 90,164,130, 56,245, 62,150,170,226, 44, 96, 22,191,167,242,137, 72,225,125, 97,112, 9, 30,191, +190,127, 13,118,129, 65,239, 88,175,164, 92, 2,137,149, 53, 34, 99, 99, 32, 0,121, 90,129,200,191, 35,176, 10, 94,140, 17, 17, + 17,232,209,163, 71,222,226,197,139, 67,212,106,117,227,236,236,236,233,150, 8, 44,165, 82,137, 71,143, 30,209, 17, 35, 70,228, +108,221,186,213, 4, 0,142,142,142,120,242,228, 9,237,221,187,183,106,197,138, 21, 84, 42,149, 90,108,201, 33,132, 64, 44, 22, + 99,247,238,221,180,119,239,222,217,207,159, 63,167,246,246,246,176,183,183,199,174, 93,187, 76,221,187,119,207,190,119,239,222, +219,176,242, 8, 44,179,217, 12,137, 68,242, 78, 92, 10, 11, 47, 75,197, 80, 90, 90,218,188,151, 47, 95,246,237,214,173, 91,114, + 68, 68, 4, 85, 42,149, 80, 42,149,152, 59,119,110, 94,195,134, 13, 83,194,194,194,222,134, 85, 68, 96,217,219,219, 35, 42, 42, +138, 14, 30, 60, 56,101,231,206,157, 90, 0,112,112,112, 64,100,100, 36, 29, 56,112, 96,114,120,120,120,223,148,148,148,249,101, + 89,176, 94,189,122,245,214, 98,165,213,106,145,150,150,134,216,216,216,183, 93,132, 26,153, 85,167,129,253,186,215,214,104, 52, +121,161,225, 47, 94,215,172, 81,221, 81,163,209,228,197,188,126, 29, 78,233,156, 98, 85,152, 90,173,158,174,211,233, 26,111,220, +184, 49,100,252,248,241,121,175, 95,191, 46, 86,176,127,148, 2,139,195, 56,131,208,102,215, 95,228,218,180,239,222, 95, 72,146, +238, 2,134, 92, 64,100, 11,136,108,193,147,217,163,115,243, 58,220, 29,183,115,156, 65,153, 38, 16,136,220,203,228,228, 83, 39, +128,105,126, 62, 92,107,219,172,207, 56, 97, 70, 70, 6,184, 92,238, 91, 49, 36,149,201,208,182,215, 80,206, 47,119,117,206, 0, +109, 10,194,117,183, 52,186, 66,161,112,202,247,223,127, 47,200,204,204, 4,135,195,249, 31,167, 84,138, 49, 99,198,136,172,172, +172,102, 89,156,246,195,213, 5,224,139, 26, 1,244,219,176, 36,173,235,241, 16,141,255,164,165,219, 36,129,117, 26, 96,116, 43, + 71,201,210, 83, 41,129,143, 98, 53,149, 1,243, 4,152,244,245,202, 43,178, 8, 33,205, 21, 10,197,169,251,247,239, 75,187,116, +233,130, 21, 43, 86,200, 36, 18,201, 25, 66, 72,185, 27,124,117,174,249,235,249,107,119, 37, 63,254,177, 35, 96, 80,191, 17, 86, +133,182,148, 92, 6,179,183, 93,202, 54, 26,233, 64, 75, 57, 53, 26,205,176,207, 63,255, 60,253,183,223,126,251,147,184, 18,139, +197,136,138,138,194,162, 69,139, 50, 50, 50, 50,134,255,157,226,234,235,175,191, 94, 20, 23, 23,231,127,254,252,121, 94,106,106, +170,227,202,159,127,206, 62,156,157,157,177,228,201,147,176, 25, 53,106,248, 78,171, 85,107,120, 73, 46, 28, 74, 18, 87, 95,125, +245,213,190,184,184,184,186, 23, 46, 92,224,167,166,166,186,127,245,213, 87, 88,190,124, 57,102,205,154,181, 25,192,232,130,209, +209,150, 66,175,215,135,101,102,102,118,235,216,177, 99, 86,102,102, 38,106,213,170,133,238,221,187,195,217,217, 25,174,174,174, +232,217,179, 39,252,252,252,144,158,158,142,129, 3, 7,102,164,166,166,118,164,148,150, 58, 11, 61, 61, 61, 61, 98,239,222,189, +225,227,198,141,171, 27, 23, 23, 87, 13,128,189, 74,165,146,169, 84, 42,145, 94,175,151,216,218,218,218,214,169, 83,199, 97,212, +168, 81,242,135, 15, 31, 86,139,139,139,203, 5, 16,195,202,170,183,186,160, 68, 45, 2, 32, 53, 95,232,232,139,236, 83,203, 56, +102,233,181,197,254,182,224,188,178, 45, 88, 37,193, 0,204,222,121,104,135, 86,232, 89, 21,214,254,181, 33, 21,139, 33, 17, 10, + 33,177,181,135,142, 97,240,115, 84, 82,158,154,210, 89, 21,200,200,119, 44, 13, 58,157, 14, 83,166, 76,209, 14, 29, 58, 52, 43, + 58, 58,122, 76, 78, 78, 78,109, 74,233, 99, 75,196, 64, 78, 78, 14,150, 47, 95,174,153, 59,119,238,171,220,220,220,186, 66,161, +208,168,211,233,176,116,233, 82,237,183,223,126, 27,157,157,157, 93, 95, 40, 20, 26,196, 98,113,185,122, 97, 36, 18, 9,120, 60, +158, 81,165, 82,213, 93,188,120,113,196,134, 13, 27, 52, 10,133, 2, 2,129,192,168, 82,169,106, 46, 92,184, 48,108,201,146, 37, +154, 2,203,155,165,188, 12,195, 20,219, 69,200, 48,204,159, 44, 91,101,193,104, 52, 94, 74, 77, 77,173, 61,109,218,180,135, 91, +182,108,201,179,183,183,135, 88, 44,214,167,166,166,214,154, 52,105,210,163,245,235,215,231,217,219,219,151, 75, 96, 25, 12, 6, +152,205,102,252,242,203, 47,121,211,166, 77,123,148,150,150, 86,139, 16,162,103, 24, 6, 91,183,110,205,155, 60,121,242,195,148, +148,148,218, 70,163,241, 82, 89, 92,102,179,217,156,147,147, 3, 30,143,135, 39, 79,158,232, 4, 2, 1, 56, 28, 14, 94,190,124, +249, 86, 96,217,217,217, 85,175, 93,179, 70,192,174,125,135,174, 74, 4, 34, 81,227, 6,245,170,189,138,142,137,163,148, 68,151, + 81,135, 30,231,229,229,213, 78, 76, 76, 28, 51,121,242,228,172,249,243,231,107,117, 58,221, 59, 34, 75, 40,252, 8, 61, 1,112, + 32, 5,129,228, 69,138, 78, 33,230,152, 8,194,143,190, 17, 87, 98, 27, 64,108, 11,136,109,225,230,230,142,187, 81,121, 10,112, + 32,132,217,232,104,193, 3, 41, 3,129,244, 73, 50, 20,124,161,132, 36, 37, 37,189, 21, 66, 5,155,119,213,106,120, 16,147, 43, + 7,161, 34,112, 81, 30, 87, 34,221,236,237,237,121, 5, 67, 0, 10,111,213,171, 87,231, 26,141,198,142, 22, 51, 37,152, 93, 0, +230,171,240, 36,173,203,145, 71,106,255, 9, 75,126,145, 72,204, 89,192,253,181, 8,172,226,138, 9,125,234, 8,103, 30, 79, 13, +188, 23,157, 87, 5, 92, 58, 26, 76,174,178, 28,207,124, 51,133, 66,113,230,222,189,123, 82,133, 66,129, 87,175, 94,161, 65,131, + 6,216,178,101,139, 84, 42,149,158, 38,132,180, 42, 79, 49,221, 78,162, 49,185, 42,115,227, 41,135, 94, 39, 61, 78, 52,189, 35, +174, 82,213, 20,159,255,112, 60, 43, 51, 71,251,233,173,215,101, 63, 71,133,234,252,195,172,172,172, 14,179,102,205, 74, 79, 77, + 77,125, 71, 92,197,196,196, 20, 8,129, 86,148,210,167,127, 87,245,180,182,182, 30,188,100,201, 18,220,187,119, 15, 93,186,116, +193,181,107,215,144,145,145,129,253,103,206,188,216,251,226,197,140,130, 49, 89,197,185,112, 40, 9, 86, 86, 86,147,150, 44, 89, +130,251,247,239,191,229, 76, 79, 79,199,146, 37, 75,226, 0,140, 45,175,184, 42, 64,114,114,242,221,176,176,176,142,181,106,213, +122,182,110,221,186, 56, 23, 23, 23,102,212,168, 81,248,252,243,207,161, 84, 42,205,171, 87,175,126,221,188,121,243, 39, 17, 17, + 17,237,212,106,117,136, 5,229, 67,211,210,210,110,110,217,178,229,118,155, 54,109,164,195,134, 13, 83, 30, 59,118,204, 62, 47, + 47,207, 85, 36, 18, 57,234,245,122,225,179,103,207,184,135, 15, 31,118, 14, 13, 13,141,210,104, 52,119, 43, 26,247,255, 32,238, +229, 91,163, 46, 20,217,223, 43,227,152,165,215,150,244,187,172,243, 74, 23, 58,101,109,131,171, 96,238,152, 26,138,188,155, 67, + 26,209,164, 81,205,104,114,255,106,244, 70, 75, 59, 58,210,135,168,135, 85,208, 77,131,201,100,162,175, 94,189,162, 81, 81, 81, +116,246,236,217, 38,137, 68,162,145, 74,165,171, 81, 78, 55, 13,114,185, 60,215,207,207, 79,101,109,109,253,214, 77,131, 66,161, +200,245,247,247, 87,217,216,216,188,117,211, 32,147,201,114, 41,165, 84, 46,151, 91, 52,139, 80,161, 80,100,167,167,167, 83,137, + 68, 82,224,166, 65, 96,109,109,189,213,215,215, 87, 37,151,203, 11,220, 52,240,109,109,109, 55,249,249,249,169, 20, 10,133, 69, +110, 26, 28, 29, 29, 99,159, 61,123, 70,195,194,194,168,187,187,123, 66,161,217,118,177,143, 30, 61,162,143, 30, 61,162,110,110, +110, 21,114,211,160, 84, 42,151,215,175, 95, 63, 67,169, 84,166, 23, 10, 91, 81,191,126,253,204,130, 48, 11,103,254,165,231, 95, +243,214, 77,131, 82,169, 76,207,231, 46,151,155, 6,137, 68, 50, 90, 44, 22, 39,136,197,226, 4,145, 72,180,168, 82,165, 74, 41, + 7, 15, 30,164,171, 87,175,166, 10,133,226,141,155,134,234, 61, 26, 87,109, 50,124,134,178,122,207, 73,239,227,166, 65, 42,149, +174,150, 72, 36,154,249,243,231,155,178,178,178,168, 94,175,167,249,141,215,199, 53,139,112,139, 95, 85,250, 83,192,241,136,249, +222,161,223,180,144,106, 67, 22,214,166,244,215, 79, 40, 61,253, 57,165,151,166,208,187,155, 71,209, 38,222, 34,243, 31,147, 61, +194,233, 38,255, 35, 22,185, 86,216, 82,179, 42,253, 41,224,244,139,121,222,161,195,154,187,106,127,222,184,154,222,185,115,135, + 62,121,242,132,190,122,245,138,158, 62,122,144, 54,169, 34,125,195,249, 83,192,241,242,184,107, 0,208, 84, 36, 18,229,174, 90, +181,138,222,190,125,251, 45,231,241,227,199,169, 84, 42,205, 3, 44,156,133, 12, 16,250, 83,245, 94,166,141,254,215,103,182,151, +171,210, 79, 78,161, 52,100, 7,165, 91, 2, 41,221,222,144,210,131, 93, 41, 61, 49,156,222, 94,221,135, 54,245, 22, 24,233, 38, +255,107,116,115,245,246,150,198,147,207,231,231,252,246,219,111, 52, 33, 33,129, 94,187,118,141,222,191,127,159, 62,127,254,156, +190,126,253,154,158, 58,117,138,242,249,124, 45,128,114,207, 82,108,232, 4,175,118,190,130,196, 71, 75,155, 82,122,108, 32, 77, +221, 59,152,118,171,161,200,104,228,193,107,243, 30,179,173,234,216,219,219,167,157, 58,117,138, 70, 69, 69,209,171, 87,175, 82, + 71, 71,199, 52, 0,129,127,119,253,108,215,174,221, 29, 74,105,112,151, 46, 93,130, 1,156,109,215,174, 93,112,100,100,100,112, +131, 6, 13,110,163, 20, 23, 14,165,113,182,109,219,214, 64, 41,165, 93,186,116,161, 0, 18,218,181,107, 71, 35, 35, 35,105,131, + 6, 13,244, 31,104,246, 26, 23,192,112, 62,159,255,179,157,157,221,101, 91, 91,219, 75, 92, 46,119, 11,128, 33,229,105,239,138, +225,116, 5, 80, 29, 64,189,252,173, 90,126, 24, 59,131,240,191, 48, 43,210,210, 19,251,120,163,233,136, 42,228,234,160,202, 80, + 13,172,140,220,207,124,200,141, 79,189,209,166, 34,171,109, 23, 8,172, 95,127,253,149,122,120,120,168, 21, 10,197, 13, 0,190, + 21, 89,193,219,214,214,246, 44,151,203,237, 91, 76, 88,255, 34,238, 17,158,218,216,216,100, 91, 89, 89,189,178, 36,158, 86, 86, + 86,207,165, 82,169,218,202,202,234,121, 17,151, 0, 61,237,237,237, 79, 21, 9,235, 81, 52,172,164,180, 59, 57, 57,197,134,135, +135,211,215,175, 95, 83, 15, 15,143,132,194,194, 43, 36, 36,132,190,120,241,226, 29,225, 85,222,213,203,121, 60, 94, 27,165, 82, +121,184,172,176,210, 56,157,156,156,126,229,241,222,109,252,139, 11,171,200, 42,235, 0,252,220,220,220, 82, 86,174, 92, 73,229, +114,121, 74,225, 99,254, 45, 62,251,254,206,139,220,156,207,167,254,116, 80, 89,173, 87,205,138,172,220, 14,192, 87,161, 80,220, +240,242,242, 82, 95,188,120,177, 84,129,133,127,235,170,245,135,170, 9,232,230,106, 77,233,166,106,167,158,207,241,122, 54,188, +161, 76, 23,188,178, 11,165,151,166,208,219, 63,125, 78, 27,123, 11,223, 8,161,205, 1,103,232, 47,126, 45,232,218, 42, 66,139, + 56,127,246,105, 78, 55, 7,156, 9,157,237,245,236,147, 32,165,126,223,142,205,244,229,203,151,244,248,225,189,180, 81,229,124, +113,181,169,218,239,244,167,106,173, 45,226, 44, 70,100,109,219,182,141,190,124,249,146, 30, 57,114,196, 34,113,245, 14,103, 33, +129, 53,189,157, 60,235,243,134, 98,221,192, 58, 66,125,207, 64,129,161, 67, 85,129,169,137, 23,207, 92,219,133,195, 84, 83,130, +118,240,151,232,232, 38,255,107,116, 83,181,142,150,198, 83, 40, 20,190, 70, 33,159, 56, 69, 55,145, 72,148, 90,146,192, 42,171, +220, 27, 58,193,171,157,159, 40,241,226,252, 54,180,123, 45, 69,186, 37,226,170, 44, 78, 0,117, 28, 28, 28,210,182,111,223, 78, +157,156,156, 82, 45, 17, 87,255, 31,245,211,218,218,122,119,110,110,110,240,185,115,231,130,219,181,107, 23,188,123,247,238,224, + 27, 55,110, 4, 75,165,210,221, 37,185,112,168, 6,116, 44,141,211,202,202, 42, 88,165, 82,209,115,231,206,209,118,237,218,209, +221,187,119,211, 27, 55,110, 80,169, 84, 26,252,143,122, 54, 89, 78,118,171,136,192,250,144, 5, 0,128, 14, 26, 52, 40, 79, 42, +149, 38, 3,232,241, 95,170,124,118,118,118, 55, 29, 29, 29,147,157,156,156,146, 29, 28, 28, 30, 20, 18,133, 55,149, 74,101,178, +163,163,227, 59,225, 31,227,131, 7,192, 79, 32, 16,196,240,249,252,240,194,225,202,234, 61, 26,251, 52, 29, 54,203, 41,176, 71, +231,247,141, 39,128, 30, 82,169, 52,185,119,239,222,234,143, 78, 96, 81, 10,186,182,138,176, 64,100,133,204,242,122,222,189,134, +212,176,101, 98, 7,218,184, 82, 17,113,181,221, 75, 84, 46,206,124,145,245,112,166,231,243,214,126,114,211,146, 89, 19,104,163, +202,146,119,197, 85,121, 56,139,136, 44,169, 84,170,154, 51,103,142,197,150,171, 63,113,254,236,239, 73, 55, 7,236,126, 35,158, +202,216,126,242,223, 74,215,251,123,254, 83,202,189,161, 19,188,218,250,137,158, 90,106,185,178,132, 19, 64, 29, 91, 91,219,103, +150, 90,174,254, 63,210, 14,160,195,152, 49, 99,130, 35, 35, 35,131, 95,189,122, 21,124,227,198,141,224, 94,189,122, 5, 3,232, + 80,156,159, 44, 67,239,222,186, 58, 28,206,132, 50, 56, 7,140, 25, 51,134, 70, 70, 70,210, 87,175, 94,209, 27, 55,110,208, 94, +189,122, 81, 0, 3, 88,225,194, 10,172,127,234,246,183,204, 97, 87, 40, 20, 15,142, 30, 61,122, 86,163,209, 44,162,148,234,254, + 75,157,200,233,233,233, 77,138, 11,207,200,200,104,242, 31, 26,200, 24, 14,192,171,104,120,202,211, 99,183, 0,220,250, 64,247, + 56, 78, 8,249,253,236,217,179, 51, 21, 10, 69,167,143, 46, 19,199, 69,232,177,206,231, 62,132,194,165, 53,220,164,211,190,239, + 66,201,146,115, 55,189,150,245,118,124,221,196, 71, 22, 5, 62,243, 3,136,238, 46,134, 71,235,202,201,121, 23, 18,227,210,218, + 30,210,105,139,123,130,252,112,102,135,215,242, 94,246,175,155, 84,145,191, 6,197, 15, 16,229,221, 42, 23,231,187,101,242, 7, + 33,164,243,202,149, 43,119,230,229,229,125, 65, 41,189, 92,254,198,131,147, 4,181,113, 14,140,220, 26,160, 16,150,114,179, 60, +112,184, 79,144,130,228,127, 74,145,221, 78,162, 49, 0, 2, 63,240,179,244, 48,191,219,233,159,244,124,255, 78, 8,193,222,189, +123, 7, 7, 4, 4, 84, 9, 13, 13,125,149,151,151,183,135, 82,250,123,225,177, 74,132,144, 19, 63, 60,126,172, 94, 31, 26,250, +135,158, 97,254, 40,131,115,127, 62,231,164,128,128,128,192,208,208,208,167,121,121,121, 43, 41,165,251,217,161, 73, 44,254,169, +248, 91, 4, 86, 78, 78, 78, 16,155,245, 44,254, 31, 26,122, 29,128,239,243,183,143, 15,133, 68, 86,144,167,100,220,111, 99, 36, +121,160, 36, 14,124,102,117,185,197, 85, 49, 34,171,129,151,228,219, 35,163, 37,121,160, 72, 2,197,143,239, 35,174, 10,139, 44, + 0,149, 43, 76,208, 39,212, 0, 32, 10,132, 68, 99, 46, 74, 30, 28, 61, 23,111, 63,179, 89,252, 61, 34, 11,192,239,101,156, 67, + 1, 92,202,223, 44,225,220, 15,128, 21, 84, 44, 88,129,197,130, 5,139,255, 39,145,117,184,250, 61,164,113, 39,131,131,202,128, + 41, 6,106, 83, 18,198, 69,235,223,147,243, 14,210,200, 55,224,194, 15, 66, 83, 4,114,245, 73, 24,243, 30,156,127,193, 27, 28, +111,198, 70, 21,143, 57,108,213, 96,193,130, 5, 43,176, 88,176, 96,241, 62,120, 99,213,137,203,223,254,185,156, 44, 88,176, 96, +241, 31, 2, 1,208,174,132, 15,196, 11, 22,147, 16,210,174, 2, 31,160, 23, 88, 78,150,147,229,100, 57, 89, 78,150,147,229,252, +111,113,150,197, 93, 30,253,241,143,198,223, 49,139,144,229,100, 57, 89, 78,150,147,229,100, 57, 89, 78,150,243, 99,222, 56, 96, +193,130, 5, 11, 22, 44, 88,176, 96,241, 65,241,183,142,193,146, 58,248,185,128,199,169, 69, 24, 26, 0, 0,148, 67,158,195,196, + 60,206, 75, 11, 79,124, 95,110,133,155,191, 29,133,240, 16,129,190,175, 42, 62, 44,227,125,249,106,250, 91,247,118,114, 80, 12, + 78, 74,207,222,249,228,185,234, 88,121,174,181,177,169,100, 45,182,179,237,163, 51, 24,107, 8, 5,130,215,134,172,156, 45, 25, + 25, 17, 42,182,250,177, 96,193,130, 5, 11, 22,255, 49,129, 85, 41,176,249, 61,177, 88,226, 13, 0, 12,165, 96, 40,160,206,201, + 10, 78,140,184,215, 17, 0,148,222, 65,231,248, 98,171, 32,134,190, 57,110,102, 0,147, 65, 27,149, 29,125,187,190, 37, 55,150, + 59,250,127,210,174, 67,187,222,221,186,117,245,175, 89,163,166, 15, 0,132, 60, 9,137, 56,121,242, 84,152,220,209,255,183,220, +148,176, 35,239,147, 48, 10,241,130,122,245,234, 52,187,127,255,193,124, 0, 95,189,111, 70,217,219,203,199,253,254,235,228, 22, +109,123,175,144, 1, 40,151,192, 18,219,217,246,233,217,189, 83,157,239,198,143,225,124, 62,121,177,247,189, 63,174, 44, 83,184, +214,200,162,140,241,119,117,114,255,235, 37, 45,104,204,130, 5, 11, 22, 44, 88,176,248,200, 4,150, 88, 44,241,190,125,229,164, +221,145, 27,177, 0,128,118,117,157, 49, 99,225,186, 14,132,144, 48, 0,232,241,249, 92,191,249,211,199,227,230,211, 20, 80, 74, + 81,167,170, 61, 58,247,236,107,209, 77, 37,206,213,235,247,239,215,111,208,228,201,147,122,188,124,249, 50,122,223,190,125,215, + 1,160,121,139, 22, 85, 23, 47, 94,220,111,133,173,157, 72,226, 92, 61, 94,147, 20,122,175, 34,137,146,184,249,184, 85,247,173, + 53,248,192, 47,235, 56,173, 58,126, 58, 80,226,230,179, 68, 19, 31, 17,111,201,181, 74,165,242, 27, 62,159,111, 13, 0, 12,243, + 63,221, 83,197,131,235, 12, 0, 38, 51,163,176,115, 11, 80,113, 5, 98,179, 72, 36, 8, 85,229,230,238,204,142, 11,253,185, 52, + 78,157,209, 24,248,237,216, 17,156,135,175,210,225, 29,216,156,187,122,201, 76, 48,102,163,237,132,233, 11,251,220,191,115, 0, +192,156,171,108, 85,100,193,130, 5, 11, 22, 44,254, 3, 2, 11, 0,228, 18, 30,194, 34,147, 0, 0, 54, 18, 96,220,232, 97, 72, + 79, 75,245,211,155, 24,124, 54,108, 8, 30, 60, 79, 68, 88, 84, 42, 40,165,240,115,151, 90,124, 83, 46,152,122,159,141,252,172, +229,185,223,127,191,251,253,172,239,119, 17,242,198,123,247,230, 45, 91, 27,207,158, 51,251,139, 33,195,134,180, 63,124,248,240, + 83,148,181, 82,117, 73,137, 34,138,117,203,151, 46, 18,198,165,105,181,223, 76,158,198, 76,154,248,205,106, 0,159, 90,114, 45, +159,207,183,142,139,139,147,115, 56,239, 14, 79,251, 97,209,180,107,237,123,175,120, 17,253, 58,235,225,185,227,199,235, 87,175, + 94, 29,113,241, 73, 77,151,173,217, 84,219,197,167,254, 8, 85,142,166,183, 58, 53,180, 88,175,209, 34, 62,255,233,188,101, 63, +213, 97,108,170,114,102,124,209, 5,129, 62,174,136, 79,201, 66,139,142, 61,120,193,247,238,117, 0,192, 10, 44, 22, 44, 88,176, + 96,193,226, 35, 2, 7, 0, 8, 33,197, 58,236, 51,155, 41,194,162, 18, 17, 22,149,136,187,207, 83, 97,160,124,172, 94, 54, 15, + 43,151,204, 65,134,134,131, 35, 55, 99, 17, 30,149,132,240,168, 36,164,101,230,254,233,250,162, 83, 45, 87, 46,149,214, 93,189, +218,122,121,135, 22,178, 86,118,182,182,182, 47,158,238, 82,207,158,152, 92,109,222,183,177, 2,190, 94, 20, 39,147,203,154, 28, + 58,116,176,186,147,210, 81, 38,151, 43,166,200,220,235,108,179,177,169,109, 93, 26,103, 81, 72,157,170,245,232,209,181, 83, 27, +103,103, 39,102,204,234,224,231, 53,170, 5, 24,125,171,250, 54,149, 58,249,245, 40,233,154,194,156, 12,195,128,195,225, 32, 57, + 57, 25, 9, 9, 9,136,140,140, 68,120,120, 56, 98, 99,163,147, 25, 74,249,102, 48, 28, 23, 23,119,240,120, 66,120, 87,242,194, + 79,171,151, 72, 23,206,157,209, 64, 44, 19, 30, 35,132,144,226, 56,181, 25,153,135, 79,159,253, 61,254,204,190,159,204, 0,144, +146,153,139, 75,247, 94,226, 65,104,108,185, 10,235,175,152,186,202,114,178,156, 44, 39,203,201,114,178,156,255, 4,206,146,180, +200,191, 90, 96,149,132,136,216, 12,132, 69, 38, 33, 40,192, 13, 62,149, 92,112, 55, 60, 19,123, 46,197, 98,219,185, 24, 92,122, +148, 10,134,167, 64, 82, 14,240, 34, 58, 25, 47, 98,210, 74,243,171, 12, 0,224,138,248,253,191,253, 54,123,114,205,234, 57,141, +174,156, 25, 7, 55,229,139,234, 83,167,102,141,227,138,248,253,109, 61, 20,251,166, 77,158, 48, 88, 33,149, 10,245, 58, 61,170, + 84,246, 18,143,255,122,220, 8, 98, 43,218,103,105, 98,172,220,171,219,138, 36,146,159, 23,206,157, 34,250,241,200,139,215,106, + 61,212,191,221, 74,126, 53,105,218,236, 12, 30, 95,252,147,149,123,117, 91, 75,185,140, 70, 35,116, 58, 29,244,122, 61, 12, 6, + 3,226, 99,159,245,184,120,228,187,142,149, 61,236, 58,138,196, 98, 80, 0, 57, 26, 19, 34, 19,243,208,186,109,123,110, 80,221, +186,129,114,151,106, 35,139,227,202,202,138,206,102, 40, 87,113,242,232, 94,238,193,243, 15,177,235,228, 61, 28,187,252, 16,119, +175,158, 49, 81,198,248,118, 57, 9,133,171,175,159,194,181, 86,140,194,173,118,242,219,205,189,230,125,246, 59,128, 5, 11, 22, + 44, 88,176,248,119,161,196, 46, 66,173, 86, 19,245,105,255, 33,112,113,116,150,247,108, 53, 92, 16, 28,145,133,212,196, 24,188, + 12,127,130, 60,173, 17, 2,219,202,128,216, 25,149,188,189,240, 56,236,152, 97,237,242, 83,185,140, 73, 23, 85, 18, 95,207,158, +174,238, 46, 74, 25,103,249, 50,207,219,225, 97,153, 65,123,103,109,199,160, 65,114,135,229,203, 60,111, 71,191,146,113,164, 98, +218,100,196,176,129,132, 67, 40,166, 78,157,140,158,221, 58,225,179, 17, 67,201,206,157, 59, 26, 89,154, 24, 6,252,245,211,103, +206, 19, 38,103,153,244,119,195,115,117, 82,153, 68,242,199,139, 92,117,160,183,167,164, 75,239,225, 9,167, 14,253,252, 35,128, + 97,150,112, 21, 8, 43,163,209, 8,131,193, 0, 0,102, 0,224,112,222,236,211, 85,122,164,100,233,144,156,165,131,201,204,160, +119,255, 97,146,123,247, 31, 13, 3, 80,194,120, 44,134, 49,154,140,248,237,252, 3,196,223, 59,204, 16, 14, 55,187, 96,144,123, +129,184,114,118,246,188,214,173,247, 80,165, 80,252,166,187, 85,165,214, 97,231,166,101,108, 45,101,193,130, 5, 11, 22, 44, 62, + 22,129, 21,253,244,122,125, 0,240,175,223, 49, 93, 46,230,217,241, 56, 4,201,113, 17,216,185,226, 27, 48, 12, 69,151, 47,150, + 67,225,237, 12,137,128, 11, 93,110,122,110,250,203, 43,246,165,221,136, 16, 99,251, 13,155,227,189,191, 28, 91,197,106,239,222, + 92, 62, 0,236,221,155,203, 31, 59,198,195,106,227,230, 40,239,134,205,130, 64,205,102,116,235,249, 41,250, 15,232,143,232,164, + 60,252,122,237, 53,212, 26,189, 69,235,159, 73,149,213,106, 59,186,186,117,250,118,120, 39, 25,143, 75,136,175,151, 53, 55, 54, +213,104,226,114,249,230, 19,247,178, 19,122,247, 30,224,112,233,244,193, 54, 82,101,181,218,121,169,207, 30,149,197,167,211,233, + 96, 54,155,161,211,233, 96, 52, 26, 97,231, 80,249,116,251, 79, 87,196, 37, 38,169, 78, 37,101,106, 27,170,141, 38, 36,103,233, +144,146,165, 67,150,218, 0,103,133, 45, 76, 70,125,205,146,248, 40,165,187,122,125, 58,100, 40, 0, 14,225,152,182,171, 18,158, +133, 23, 28, 43, 16, 87,157,122, 14, 82, 94, 11,142,192,203,251,103, 50, 41, 99, 50,190,201, 56,134, 93,170,132, 5, 11, 22, 44, + 88,176,248,151,129,243, 63, 1, 68,104, 73,253,159,241,201, 25,176,151,243,160,116,245,198,224,111, 86, 2, 0,204,102, 35, 40, + 5, 76,102,203, 60, 12, 80,202, 63,255,213, 88,239,168, 74,222, 36,123,240, 32,169, 6, 0, 6, 15,146,106, 42,121,147,236,175, +198,122, 71,169,180,114,131,201,108,198, 31, 79, 83,176,252,192, 51,204,222, 17,130,179,247, 45,119,135,197, 21, 10,198, 46, 91, +186, 68,192,227, 18,242, 52, 38, 55, 55, 46,221,148,203,229,243, 13, 82,169,144,234, 41, 79, 23,157, 70,211,219,246, 26,241,146, +195, 37, 35, 75,227, 41,152, 57, 88,208, 69, 88, 96,193,162,148, 82, 2, 48, 12, 49,155,227,210,180,136, 77,213, 32, 54,229,127, + 91,114,166,174,196, 30, 82,133,171,175,159,181,149,252,172,173,141,213, 8, 27,107,171, 97, 50,137,237, 57,133,171,175, 95, 81, +113,117,251,105, 2, 34, 30, 94, 72, 54, 27,242,250,169,226, 31, 57,169,226, 31, 57,169,226, 66,234,177,213,148, 5, 11, 22, 44, + 88,252, 23, 80,154, 22,249, 87, 10, 44, 74, 41, 41,216,254, 44,140,128, 23, 49,105, 16,242, 24,184, 87,242, 1, 45, 36, 35, 40, + 0,147,217,178,124, 56,118, 44, 33,174, 74, 85, 53, 51,101,202,235,198, 53,106,218, 63, 30, 59,198,227,121,141,154,246,143,167, + 76,121,221,184, 74, 85, 53, 99, 52,241,205, 52,223,223, 86,129,111,173,124,119,252,150, 38,165, 65,237,234,149,185,243,246,190, +120,253,229,198,240, 48,129, 64, 96,116,119,144, 18, 47, 39, 41,215, 83, 41, 17,234,140, 28,157, 95, 96, 93, 61, 56,164,174, 37, + 2, 75,175,215,191,179,165,167, 70,244,248,253,215,201, 61,221,156,108,135,199,167,106,240, 58, 37, 15,177,169,121,120,157,154, +135, 60,157, 9, 33,207, 94, 1, 92,193,147,226, 56,173, 20,118,231,246,237,217,229, 89,187, 90, 21,199,234,126,149, 28,127,222, +177,203, 83, 44,182, 57,167,112,245,245,243,244,246, 15,190,115,225,160,242,246,211, 4,196,132,221, 79, 50,233,114,246,169,147, +159, 95,100, 31, 51, 22, 44, 88,176, 96,241, 95, 66,105, 90,228,223, 8,139, 60,185,123,185, 59,225,206,147, 40,212, 12,168, 12, +107, 43, 5,158, 71,196,129,203,225,131, 67, 0,163,201,114, 17, 68, 13,198, 3,171, 86, 89, 35, 38, 74,198,217,248, 83,148,247, + 87, 99,189,163, 86,173,178,190, 69, 13,198, 3, 0,134, 80,250,102,109,196, 2,199,166,230,114,184,223,164,140,209,195,201, 78, +202,189,255, 74,157,206,225,112,117,246,214, 98,198,222, 90,196,177, 87, 8,249, 2, 62,151, 49, 81,142,193,221,209, 91, 75, 25, +166,182, 37,124,133,187, 8,205,102, 51, 8,225,152,243, 5,152, 44, 54, 93,131,108, 45, 23,201, 89, 58,100,170, 12,240,117,147, +225,194,165,195,121,102,163,102,111,113, 92, 92,190,192,218,199,219, 29, 51, 22,172,130, 70,103,198,139,248, 92, 8, 68, 34,103, + 39,231,192, 71, 67,190,156, 38, 26,191, 37, 2, 35,219,216, 99,226,245,136,248,188,100,241, 52,246, 49, 99,193,130, 5, 11, 22, + 44,254, 3, 2, 75, 46, 21,131,114,197,184, 30, 28, 1,255,234,181,176,227,248, 93, 84,173,217, 8,137, 42, 19, 40, 56,101,206, + 30, 44,192,164,105,121, 15, 0, 60,232,217,211,213,253,147, 79,220,218, 83,202, 63,191,113, 83,118, 28, 0,252,180,191, 37, 40, + 0,134,161,160, 20,160,204, 27,161,101, 49, 8, 47, 38, 42, 49,167,146,183,179, 12,161,113, 6,157, 76, 36,224,216,202,132, 92, +165,181, 80, 32,224,241, 96,166, 68,151,152, 24,161, 35, 64,180, 37,116, 5, 93,131, 5,123,169,220,229,116,219, 94,203, 83,163, + 95,103,223,247,205,200,171,157,109, 16,130, 82,192,215, 77,134, 39,183, 79,153,147,227, 95,190,208, 36,135,109, 42,142,139, 97, +192, 53,152, 24, 60,122,149,141, 44,181, 17, 89,185, 6, 52,109,221, 93,208,180, 93, 15, 92,127,146, 6,198,100,196,178,173,167, + 84,102,106,236, 79,105,168,145,173,150, 44, 88,176, 96,193,130,197,191, 27, 22, 45,246,108,102, 40, 28,236,237, 32,150, 89, 33, + 42,217, 0, 21,113, 68,102, 30,133,217,252,198,130, 85,146,161,137, 16,210,174,184,240, 99,199, 18,226,142, 30, 77,221,118,236, + 88, 66,161, 1,220,255,179, 92,189,221, 51,212, 98, 78, 66,205, 23,142,159,185,146,221,163,161,210,150,195,229,106, 4,124,142, +142, 39,224, 26, 4, 60,142, 81,192,227,232,157,172,248,220, 43, 39,246, 11, 41,193,149,178, 56,181, 90, 45,218,181,107,135, 46, + 93,186,160,103,207,158,232,219,183, 47,252,252,170, 57,114,184, 68, 79, 9,195, 40,133, 42,248, 40, 9,120,218, 88, 92,220,255, + 67,222,147, 63,142, 62, 50,235,180,221,105,161, 62,205,119, 56, 41,101, 50,178,117,208, 26,204,200,204, 53, 32, 83,109,128, 73, +217, 24, 71,111, 38, 64,163, 55, 35, 38,248,176, 38, 53, 41,238, 27,109,242,139,168, 82, 53,100, 9,105,127, 31,176,156, 44, 39, +203,201,114,178,156, 44,231, 63,129,243, 99,131, 5, 22, 44,138, 42, 46, 50, 84,117,147, 65,107,112,132, 86,111,134, 90,107, 70, + 78,158, 1, 57,121, 70, 68, 37,229,225,201,241,247,143,200, 27,171, 21, 64,242,127,131,188, 17,118,150,218,176,132, 6,253,130, +149,203, 22,247,219, 95,183,142,126,124, 87, 23,143,199, 81,250, 4, 66, 56, 26, 14,151,103,180, 83,240,248,207,159, 63, 78,189, +117,237,116, 11,177,201, 60,180, 52, 30,147,201,148,237,230,230, 6,224,221,165,114,170,249, 72,122,254,113,106,106,229,150, 61, +150, 41,127, 92, 52, 57,143,195, 21, 48,132, 39,120, 98, 54,106,246,105,146,195,126,162,165, 12, 24,227, 8,196,207,238, 60, 12, +109,100, 99,231,129,151,241,106,168,181, 38, 24, 76, 12,108,229, 2,196,133,156, 51, 68, 61,191,127, 80, 21,255,104, 7, 91, 29, + 89,176, 96,193,130, 5,139,255,136,192,210,106,181, 81,205,218,117, 7,195, 80,152, 41,192,152,243, 45, 77,204,255,172, 77,102, +163, 54,234,125, 35,194, 48,230,187,235,183,108,235, 82,183, 65, 75,110,117, 79, 57,114,210,147,112,251,143,203, 38, 48,244,150, + 37,215,167,165,133,231, 74,157,125, 63,237,215,231,147, 67,195, 62, 27,147,213,162,117,107,153,163,163,179, 46, 46, 62, 46,239, +151,221,123,140,231, 78, 31,107,193,192, 52, 32, 45,237, 69,110,105, 60, 89, 89, 89,107,138, 11,111,219,204,163, 41,128,202, 92, + 30,209,231,165,132,203,202,147,182,180,248,216,222,139, 23,204,141, 30,244,197, 4, 97, 21, 55, 31,164,100,115, 17, 21,151,132, +231,215,142,233,226,195,239, 29,201,137,123, 48,146,173,138, 44, 88,176, 96,193,130,197,127, 72, 96,189, 14,125,227, 15,235,175, +134, 42, 41,101,200,142, 29,187, 22,238,218,189,191,169, 86,175,119,163, 16,196,154, 77,250,171,185,102,204,182,148, 35, 47,233, +197,125, 7, 7,191, 26,191,108, 93, 63,243,151,109, 27, 91,130, 49, 7, 16, 32,154, 18, 92, 17, 27,205,195,202, 18, 87,165, 11, + 56,213,230,246,159,174,208,164,167,231,238, 42,239,181,121,105,207,147,228, 78, 85, 60, 54,175, 94,176,156,195,225,118, 48,155, + 25, 62, 99, 54,190, 52, 27,180, 63,104, 82,195,142,211,242, 77,151,100,193,130, 5, 11, 22, 44, 88,252,219, 5,214,255, 23, 50, + 50, 34, 84, 0,198,191, 47, 79, 90, 90,120, 46,128, 15, 62, 19, 47, 36, 60,251, 87, 0,191, 86,244,250,220,228, 87,169,176,208, +139, 60, 11, 22, 44, 88,176, 96,193,226,223, 13, 14,155, 5, 44, 88,176, 96,193,130, 5, 11, 22, 31, 22, 4, 64,177, 51, 1,202, +179, 82,118, 69,102, 19,148,197,207,114,178,156, 44, 39,203,201,114,178,156, 44,231,199,199, 89, 22,119,121,244,199, 63, 26, 52, +223, 99,250, 95,177, 1,104,199,114,178,156, 44, 39,203,201,114,178,156, 44, 39,203,249, 95,219,216, 46, 66, 22, 44, 88,176, 96, +241,159,131,131,131,159,220,193,193, 79,110,233,249, 50,101,117, 39,153,178,186, 19,155,115, 44, 44, 5, 43,176,222, 19,132, 16, +226,239, 45, 31,215,161,165,199,209,128, 42,210,158,127, 23,167,220,169,138, 82,225, 89,255, 15, 43,247, 26,157,255,130, 52,138, + 2, 3, 3, 27, 7, 6, 6, 54, 38,132,136, 62, 4,167,204,201,127,160,135,111,227,107, 78, 62,117, 47,203,157,253,250,124,232, + 56, 43, 92,125,237, 21,158,245,126, 85,184,213,206, 84,184,214,206, 81,120,212,187,106,165,172, 94,165,172,235, 60,123, 46, 9, +152,191,255,233, 62,207,158, 75, 2,138, 59,110,215,121,157, 98,238,129,151,139, 28,122, 44,147,179,181,191, 98,240,108, 54,200, +198,181,213,100,251,242, 94,231,238,223,248,169,119,141, 22, 41,110,126,141,158, 88,122,141, 71, 64,147, 7,149, 2,155, 37,123, +248, 55,185,207,230,188,101,144, 56, 86,105, 44,177,243, 58, 37,182,243, 58, 45,182,175,210,250,125,249, 92, 93, 93, 37,213,170, + 85,235,212,184,113,227,209,237,218,181,251,182,110,221,186,163, 42, 85,170,212,129, 16,242,183, 77,178,146, 57,249, 79,215,241, + 73,154,142, 79,210,100, 78,254,211,203,110, 95, 3, 22, 18,142, 57,129,112,204, 9,114,167,128,133,255,148,178, 18, 59,251,123, +201,156,252, 87, 89,185, 4,222,149, 58,249,117, 47,239,245,118,118,118, 29, 28, 29, 29,123, 21,108,118,118,118, 29,216, 39,224, +195,161,220, 21,156,144, 32,190,220,197,248,173, 80, 44, 25,206,225,192, 42,229,229,109,183,127,114, 2,149, 85, 26,222,231,114, +184,238,133,195,204,140, 57, 46,245,213,157,122, 31,130,223,191,146,100,228,204, 73, 93, 39, 14,252,180,161, 87,187, 79,150, 17, + 0,199,138,125,225,123,214,191, 73, 8,167, 50,135, 0, 28, 14, 1,135, 0, 0, 77, 72,123,117,167,110, 69, 57, 11, 96,237,232, + 83, 89, 40, 87, 94,107,214,243, 43,231,224, 11,123,118,200,148,213,219,171, 83, 67, 31,127, 0, 97,165,244,241,241,169,239,231, +231,103, 63,110,220, 56, 1, 0,252,248,227,143, 85,171, 86,173,154, 30, 17, 17,113,143, 82,154, 90,161,198,205, 49, 96,200,154, + 21,243,119,117,238,220, 5, 9,105,106, 44, 91,181,161,149,220,217,175,111,110, 82,248,225, 15, 81, 38,182,182,149,173,120, 86, +182, 33,223, 76,153,239,216,169, 85,125,110,174,214,132,179,215, 30, 54,223,179, 97,254, 93, 43,101,245, 6, 57,169,161,175, 74, +186,150,201,203,158,229, 36,167,157,152,188,108, 0, 24, 88,244,184,155,220,216, 78, 41, 49,119,114, 17,241, 30, 2,248,173,204, +184,120, 55, 59,199, 23,137,188, 56, 28, 14, 10,202,158, 75,222,148,191,209,160,137,137,123,118,173,227, 63,225, 57,177,242,106, +152, 4, 46,207,158, 67,254, 23, 63,146, 95, 79, 9,165, 57,137,225,215,237, 63, 64,125,178,174, 81,213, 38,176,107,211,102,191, + 92,141,204,144,121,182,156,112,138, 80,206,198,152,107, 43, 31, 89,244, 50, 17,139,109, 79,156, 56,161,236,212,169,147,181, 83, +141, 94, 87, 45,250,240, 16,138,171,159, 60,121, 92,208,169, 83,199,114,212, 79,255,246,224,112,118, 19,128,207, 48,244, 71, 46, + 67, 15,230,166,135, 71,148,215,157,138,212, 41, 96, 36, 7,212,226,118,134, 1,185,159,151,252,124, 91, 5,243,150, 43,113,244, + 31, 46, 17,139, 39,251,250, 87,243,139,138,140, 8,207,201,201, 94,165, 73, 9,223, 70, 41,101,202, 69,102, 52,125,119,225,122, +112,103, 30,159, 79, 58,181,109,200, 5,112,249,125,202,221,201,201,169,215,186,117,235,170, 52,110,220, 24, 0, 96, 50,153,172, + 14, 29, 58,228,188, 96,193, 2,153, 37,207, 80, 9,233,117, 83, 42,149,158, 66,161,208, 13, 0,244,122,125,124,106,106,234,107, + 74,105,124,153,117,194,217,199,129,128, 55,255,250,181,107, 60, 0,104,222,188,197, 66,175,230,227,108,185, 2,185,166,216,236, +208,171,100, 0, 38,220,190,115,139, 0, 64,163,134,141,167,201,148,213,215,171, 83, 67,147,255, 54, 17,236, 20,208,144, 3, 76, +108,218,162,125,239,254, 3,134,112, 2,125, 61,209,161,125,155,169, 0, 78,148, 75, 0,240,120,146,187,119,239,250,112, 56, 28, +174,201,100,210, 54,106,212,232,245,251,196,203,205,191,201, 77, 2,142,135,193,164,223,154,250,234,254,194,162,117,143, 16,194, +181,246,168, 59, 19, 92,222, 23, 12,195,196,230,196,220,107,194, 10,172, 66,153, 99,229, 94,231, 70,191,254,131,107, 44,152, 50, + 74,188,118,247,121,216, 85,110, 16,154, 17,121,183,250, 63, 53,129, 92, 14,215,253,220,239,231, 28,165, 66, 46, 0, 32, 87,107, + 66,231, 78,157,202,188,206,198,187,225, 21, 14, 33,254, 5, 75,122,155, 77, 6, 49,143, 47,212, 18, 0, 32,111,102, 7, 56,184, + 86,186,228,226,108, 45, 29,248,105, 67,175,221,135,110,199,189,142,207, 42,177,209,231,112,184,238,199,142,159,112,116,179, 23, +131,199, 37,200,213,152,208,169, 75,119,115,113,231,186, 56, 91,119, 29,248,105, 67,175,189,135,239,188, 78, 76,202, 62, 85,106, + 35,238,226, 23, 36,179,118, 58,219,123,244, 2,123, 45,199, 14,179, 23,173,113,184,118,102,239,213,150, 93,135, 48, 49, 49,177, + 90, 74, 72,104,102, 70,226,183,185,137, 47,195, 44, 45, 99,185, 92, 94, 69, 46,151,215,238,220,185,179,120,242,228,201,252, 86, +173, 90,189, 61, 62,106,212, 40,193,149, 43, 87, 92, 86,172, 88,209,197,213,213, 85,155,155,155,251, 40, 55, 55,247, 21,165,212, +108,105,153, 56, 59, 43,191,254,244,147,238,104,211,251, 43,152, 25,130, 81, 95, 78,192,185, 51,191,141, 1,240, 65, 4,150, 81, +106,181,224,139,209,147,149,141,234,215,225,206,223, 27, 6,137,144,135,142,245,252,201,136,113,179,108,182,173,157,255, 51,128, +150,197, 89,174,152,188,236, 89, 53, 28,244, 3,122, 52,174,140,227,251,244, 3,220,219, 77, 5, 71,106,189,240,245,177,233,207, + 1,192,167,243,120,133,173, 68,178,206,213,134,235, 40, 50,167,174,243,233, 60,254, 66,196,153,181,170,210,226,194, 23,137,188, +246,237,221,235,107,171, 16,128,199, 33,224,114, 9,120, 92, 14,180,122, 51,250,246, 27,240,161, 44,140, 92,137,163,111, 23, 14, + 48,226,205,139, 26,219, 53, 41, 47, 78,151,167, 76, 8, 87, 96,127,242,248, 17,158,163,181, 8, 92, 46, 1,151, 3,112, 57, 4, +209,201, 26,140, 28, 57,194,250,125,133,122,231,166,142,245,175,172,111,217,177, 81, 13,187, 90, 7,110, 17,235, 70,157,251,219, +167,105,165,195,247, 31,187, 60,192,179,197,196, 59,148, 50,203, 99,175,175,254,189, 52, 30,157, 78,151,220,177, 83,103, 43,194, +147, 73, 47, 28,221,209,130,199, 33, 48,154, 41, 76,102, 10,115,254,218,165,111,158, 87, 2, 14,135,128, 50, 20, 95,124, 49, 18, + 29, 59,117,206, 99, 76, 76,156,197, 17,230,112,118,159,189,240,135, 82,103,100,176, 98,221,182,249,234,236,212,249,145,207,237, +163,165, 78,126, 19,242,146,195, 45, 94,183,130, 3, 90, 47,246,213,147,209,123, 79,222, 70,141,234,213, 96,102,222,196,211,223, + 93,134,189,167,110, 35,192, 63,224, 77,188, 25, 10, 63, 15, 57,234,215,171, 15, 0,219,202,159,191,173,120, 50,167,128,125, 61, +250, 12,235,211,187,207, 64,216,217, 90, 65,111,208,249, 93, 60,119,122,203, 79,235,150, 53, 37,132, 12, 47,151, 56,164,230,183, +239, 5,202, 48,239,109,101,114,117,117, 85,214,175,255, 63,119,138, 38,147, 9,222,222,222,136,143,143,247,175, 64, 93,146,186, +184,184,116,221,188,121,179, 99,151, 46, 93,248,206,206,206, 0,128,164,164, 36,183,179,103,207,214,117,117,117, 77, 73, 76, 76, + 60, 69, 41,205, 43,137,195,108,228, 8, 56, 60,112,197, 98,233,155, 52,130,112, 38,127, 61,180,150,147,139,171,174,184,243, 83, + 83,147,132, 83,190,186, 76,120, 60, 65,254,249,224, 80,202,144, 82,172, 66,237,248,124,190,164,184, 99, 6,174, 85, 35,202,183, +254,156,195,229,188,169,172, 38, 99,106, 70, 76,112,181,114, 88,222, 2,249, 66,193, 79,131,134,141,110,210,167,119, 79,184, 40, +173,113,225,198, 99,140,249,122,162,209,100, 48,174,170,208, 59,146,203,229,165,164,164, 68,219,218,218, 58,191,255,251,150, 84, + 62,127,238,140,227,133,139,151,166,173, 92,189,118,172,171, 95,115, 35, 67,233,219,117,134, 61,107,180,225,183,239,214,207,202, +209,167,145,120,237,156,207,249,172, 5,171,176,242,119,173,254,109,223,126,253,106,124, 53,102,148,248,219,117, 55,112,113,223, +143,105, 31, 74, 92, 41, 28,253, 27, 19, 46,111, 52,225,114,101,132, 67,132,140,153,137, 53,233,245, 11,243,210,194, 19,223,151, +155, 97, 40,126,189,153, 82,190, 7,153,162,234,238, 3, 71, 28,157,108, 68,208, 26,204,232, 63,112, 8,118,237,218,165, 80, 90, + 11,161,213,155,176,124,229, 74, 85,110,244, 49,199,232,216,156,248,118,159,174,248,253, 85, 84,198,147,215,137,218,131, 37, 55, + 12, 28, 56, 90,139,176,104,127, 56,172, 36,124,216, 42, 4,224,112, 72,225,134,131,248, 85,146,125,237,225, 97,211, 58, 33, 41, + 39,187, 16,231,158, 18, 31, 54,151,154, 29,173,109, 93,247,125, 50,122,145,205,139, 20, 30, 40, 12,136,176, 18,163,223,240,241, + 86, 85,156, 37,144,137,185, 54,145, 49,241, 46,147,191,251,238,134,181,163, 79,131,236,148,136,200,178,210, 93,169, 82,165,222, +221,186,117,147, 78,154, 52,137,239,225,225,129,237,123, 15,121, 53,239,216,183,123, 66, 98,178, 7,165, 20, 78,142,142,177, 95, +140,232,123,226,244,233,211, 49,177,177,177,252,101,203,150, 53, 60,114,228, 72,245,242,124,137,154, 41,133, 86,103,134, 57,255, +197,152,154,173, 43,111, 35, 75,220,220,220, 68,241,241,241,186,130, 23, 7, 33,228,109,102,202,221,234,116,108,219,178, 33,111, +243,153, 40,228,106,205,144,137,249,136, 74,206, 67,189, 58, 53,201, 86,179,169,118,113,156, 35,251,117,157,229, 36,167,157,122, + 52,174, 12, 71, 91, 41,126, 89,191, 8,199,111, 69,118, 74,206, 37,112,232,177,108,180,139,136,215, 94, 41, 21,172,107, 85,207, +199,185, 77,144, 23,238,213,243,113,190, 22, 28, 22, 94,179,223,170,113,241,185,252, 11, 25,103,198,169,138,111,112, 56,176, 83, + 8,176,237, 92, 12,164, 98, 30,100, 98, 30,100,162, 55,251,194,229, 95,161,175, 88,215,234, 30, 92,198, 60,210,202,181,250,200, + 1,253,250,186, 14, 26,208,151,130,203,193,161, 95, 79,244,220,179,103,119,162,220,217,255,103, 51,135,187, 77,147, 16, 26, 91, +102,158,114, 0, 71,107, 33,190,251,249, 9,172, 36,124, 40,164,124, 88, 73,249,104, 83, 75, 9,110, 5, 7, 18, 16, 66,108,199, +244,172,210,229,241,174,118,173,253, 61,229,190,143, 34,178, 67, 71, 46,188,191,250, 74, 86,235,111,215,255, 88,221, 62, 55, 75, +207,155, 61,249, 11, 94, 92, 66, 66,235, 67, 39,174,182,113,109, 48, 50,204,100, 80,207, 72,121,116,176, 88,139,109,236,243,155, +117,221, 27,247, 21, 27,114,141, 33,143,194,226,124, 50,117, 34, 60,141,206,129, 76,204,131,188, 32,111,197, 60,200,196,124,200, +197, 60, 36,196, 69, 33, 67,205,189, 17,111,207,105, 77,175,220, 52,149, 39,238, 90,131, 25, 15, 35,115, 81,201,191, 14, 92, 92, + 92,161,239, 50,184,210,157, 75,191, 30,147,185, 84, 91,162, 78,124, 54,195, 82,158,189, 39,111, 99,218,132,209,193, 4,120,144, +255,114,174, 59,123,233,134,160,249,211,190,122, 39,108,242,188,181, 65, 21, 21,215, 82, 39,255, 61, 45,187, 14,233, 83,179, 81, + 7,188,138,138,194,153, 19,247,209,182,125,103,116,233,222, 27,122,189,110,232,182,205,107,239, 1,216,240,167, 54,215,165, 90, +179,154, 53,170,237,113,115,117,245, 96,152, 55,171,114, 80, 10, 52,107,217, 6, 83,190,253, 2, 12,165,168, 93,183, 65,155, 46, + 3,198, 81,154,191,122, 71, 90,122,154, 58,236,121,104, 59, 77,242,243, 59, 22,231,165, 86,107, 76, 77, 77,197,195,135, 15, 17, + 30, 30,142,167, 79,159, 34, 61, 61, 29,214,214,214,185,229, 76,171, 85,173, 90,181, 6, 93,186,116, 73,108,107,107,251, 54, 92, +175,215, 67,161, 80, 96,208,160, 65,252, 14, 29, 58,184,117,237,218,117, 24, 33,100, 47,165, 52,167, 56, 30, 77,250,139, 4, 43, +231,128, 77, 45, 91,181, 28, 11, 0, 18, 43,151,200,117,219, 79, 60, 45,245, 89,179,118,245,106,210,164,169, 15, 40, 5, 1, 93, +163, 78, 11, 75, 42,197, 42, 36,187,125,251,118, 21, 46,151,203,251,223, 59,136,193,198, 95, 14, 4,156,191, 30,210,123,233,242, + 21, 98, 43,153, 8,169,217,122,124, 62,248, 19,139,223,193, 82,231,128, 46, 77,155,182, 60, 54,127,222,247, 60,185, 76,134,223, +239,188,194,184,111,191,211, 38, 70, 63, 89, 65, 25,254, 6,117, 74, 88,202,123,190, 42, 63,136,195,107, 95,119, 57, 20, 61, 58, +138,199, 12,237, 33,214, 27,205,200, 82, 27,161, 51,152, 97,102, 40,178,213, 70,132,190, 86,193,193, 74, 88, 17,234,250, 0,148, + 0, 82, 1,220, 43,242, 31,249,191, 81,204,255,180, 55,102, 17,216, 3,208, 3, 40,124,243,130,255, 37,133, 23, 92, 31, 10,160, + 90, 62,167, 25,192, 93, 0,153,101, 10, 44, 66, 8,165,148,146, 66,149,248,157,255,133, 33, 16,202,251, 77, 27, 55, 68,188, 96, +111, 48, 46,238, 91,156,150, 26,113,171, 32, 1,112,244,105,248, 32, 37,226,221,238, 46, 75,166, 90, 74, 92,171,123,240, 8,119, + 85,203, 86, 45, 58,140,253,242, 75,248, 87,113, 23,152,205,102,250, 36, 60,210,184, 99,219, 47,195,173, 61,106,174,206,137,123, + 50,171,192,212, 88,222,233,155,102,198, 28, 87,212, 98,101,102,204,113,101,197,147, 16,192, 70, 46,196,166, 51, 81,160, 20, 32, +160,176,150,241,177,255, 74, 28, 34,131,127,203,233, 86,227,181,122,208,252, 81,109, 90,247, 92,118, 41, 52,194,120, 48, 37, 69, +123,142, 82,154, 84, 18, 39,135, 0, 60, 46,129,149,148, 15,107,169, 0, 54, 50, 1, 72,161, 23, 87,225,110,193, 86, 61,126, 56, +127,233,143,248, 25, 0, 82, 41,165,186,226, 56, 37,206,190,245,173,108,220, 15,246, 30,187, 76, 17, 18,103, 2,143, 11, 84,118, +150,192, 78, 33,128,222, 68, 16,157,106,200,127, 98,108, 48,110,242, 60,187,105, 19,199,158, 38,164,122, 13, 74, 67, 13,165,165, + 61, 47, 47, 79, 56,100,200, 16,190,209,104, 52, 12,250,252,155, 14, 73, 73,169, 61, 55,174,249, 65,228,232,232,132, 60,173, 9, +193, 79, 95, 86,155, 63,127, 94,229, 19,103,175, 28,157,251,221,152, 99,157, 58,117,178, 62,112,224, 0, 83,158,114, 79, 77, 78, + 91,255,203,158,195,187,126, 92,177, 24, 97, 49,153,216,182,121, 3,168,217,180,169,212, 39,191, 16, 39,165,148,206,152, 49, 67, +114,244,232, 81,119,153, 76,150,147,151,151,151,250,142,253,129, 67,120,201, 25,121,112, 80, 8, 33,224,113,224,100, 43,134,163, +181, 8,124, 46,192, 33,196, 92, 28,231,182,131,167, 22, 50,121,217, 56,190, 79, 63,224,151,245,139,240,217,215, 51,241, 36, 77, +120,150, 35,181, 94,248,213,128,222,211,148, 18,115, 39, 87, 27,142, 99,155,160, 74,144,137, 5,152, 62,126, 8, 26, 4, 71, 59, +198,103, 49, 51, 83, 53,220, 58, 0,102, 22, 91,238,156, 55, 22, 43,133,148,143,179,123,150,167,168,179, 83,179, 11,186,222,244, + 58,109,140, 69,173, 94, 49,249, 41,115,242,159, 22, 84,167,214,162,177,163, 70,114,154, 54,110, 64, 57, 28, 62,210, 84,122, 66, + 41,240,237,184, 49,248,106,204, 23,206,177, 9, 41,179, 55,108,216, 52, 75,238, 88,109, 65,110,202,179,185,165,113,114,200, 27, +171,143, 92,204,131, 92,242, 70,176,200,197, 60,104,245,102, 16, 2,174,173, 87, 80, 54,121, 99,185, 77, 72,143, 46,254,139,187, + 40,167,157,103,224,197,243,145,138,128,204,131,153,183,162, 18,158, 46, 12,126,156,124,151, 82,154,225,217,114,226, 48,131,137, + 34, 87,107, 66, 84,114, 30, 76, 6, 74, 62,235,236, 5,239, 62,196,127,241, 47, 15,118, 17, 66,172, 10,132,115, 81,206,184, 91, +135,180, 14, 53,123,247,255,113,237,230,123, 43, 22,205,228,166,101,235,193, 80, 10,177,144, 11,137,144,151,191,113,161, 81,103, + 99,195, 79, 91,147, 76, 32,189,233,149, 43,166,114,181, 75, 12, 29,252, 73,151, 22,251, 9, 32, 36, 28, 65,156,171, 87, 37,175, +182,221,135,139,219,246, 24, 2,179, 73, 63, 77,230, 20,112, 89,157,252,252,162, 37,156, 53,170, 87, 3, 1, 30,228, 38,135,141, + 1, 0,185,147,255,166, 0,255,128,160,162, 97, 85,171,250, 7, 89, 82,238,249,109, 52, 71,162,244, 29, 85, 53,160,230,148,177, +223,111,174, 20,149,152, 7, 59, 15, 95, 60, 13,121,136, 51, 7,214, 63,208,168, 50, 87,156, 57,254,219,148, 5, 63,172,169,221, +189, 87, 63, 28, 59,114, 96, 18, 33,100, 35,125,131, 11,133,172, 83,131,119,252,188,197,131, 47, 20,193,104, 98, 96, 52,211, 55, +123,147, 25, 25, 25,153, 48,154, 24,136,165, 10,152, 24, 2,163,153,129,209,196, 64,167, 55,201,198, 12,233,250, 37,128, 59,197, +197,211,189, 90,171,115, 2,145,200,139,226,205,218,178,148, 82,112, 77,122,142,139,139,203, 94, 0, 16,137, 68, 16,137, 68, 96, + 24, 6,193, 97,169, 95, 43, 3,218,141, 69,190,176, 51, 27,244, 49,153, 81, 55, 58,150,148,118,103,103,231,238, 69,197,149, 86, +171, 69,110,110, 46,174,223,186,103,253,243,174,195,157,162, 98,226,170, 48,212, 90,167,112,172,210, 17, 64,247,146,242, 51, 39, +233,249,151, 30,141, 71,113, 38,125, 53,172,234,218, 29, 39,239,190, 56,187,160,212,113, 88,149,219, 77,211, 79, 26,253,105,189, +165,107,182,189,200,184,241,211,132,178,202,136,199,227,241, 83, 83, 83,223, 62,223,235,182,238,171,247, 32, 44,190,215,234, 31, + 87,139,131, 95,169, 16, 18,149,128, 97,237, 60,241,206, 75,160, 20, 78,185,179,143,131,143, 79,192,222, 13,107,150,242, 94, 36, +104,177,254,183,187,184,116,108,211,245,164,148, 59,157,104, 82,130,166, 34,109,200,251, 10,172,210, 56, 47, 63, 78, 67,174,214, + 4,157,222, 4, 35, 67,145,147,103, 68, 74,150, 30, 57,121, 6,228,106, 76, 24,214,222,179, 36, 17, 93,154, 30, 81, 18, 66, 78, + 82, 74,187,225,141,123, 41, 97,161,255, 32,132,156,204,143,215, 59,255,167, 77,155, 54, 99,201,146, 37, 79, 11,206, 45, 8, 47, + 56,183,180,240, 66,215,219, 79,159, 62,189,198,210,165, 75, 23, 55,110,220,120,255,205,155, 55, 35, 45, 18, 88,133, 19, 65, 8, + 41, 53,131, 69, 2,158,171, 84, 97,251, 70,112,252,207, 96,128, 74, 53, 90,165,175, 94, 54,223,206,197,183, 81, 76,226,139,219, + 94,150, 91,173,252,154, 72, 36,210, 83, 43, 87,174,196,128,238,205, 37,175,211,140,185,143, 95,107,146,213,122,152, 28,149,126, +194,133,139,151,202,151, 46, 91,254,213,201,227, 76, 22,128,229,197,119,229,213,191,207, 37,133,198, 88, 17, 2,202,152,227, 50, +162,238,214, 3,128,247, 25,107,149,171, 53,130,155, 63,118,134, 16, 32, 79,107, 2,151, 75, 82,178,158,239, 11, 29,244,253,216, + 54,187, 15,222, 78,160, 92, 59,149, 90, 29, 37,165,148,198,149,110, 33, 32,200,201, 51,194, 90,202,135,141,156, 15,107,153, 0, +220, 66, 15, 87, 65,183,224,238,131,183,226, 99, 98,179,238,229,139,171, 18, 57,121, 92, 78, 36, 53, 27,181,148,154, 21,221,234, + 43,225,104, 35,132,139,173, 8, 34, 33, 15, 70, 19,160,209, 51,208,234,205,136, 78,209, 64,165,145,160,102,203,190,149,237, 93, +238,235,236,189,234, 31, 77,143,185,215,187, 84, 81,106, 54, 99,199,222,195, 85, 19, 18,146,123,158, 62,186, 71,148,154, 99,196, +227,104, 53, 82,178,116, 0, 87,137, 57,139,215,139,166, 78, 24,213,107,199,190, 95, 99,218, 54,111, 24, 83,222,124, 85,167, 60, +223, 93,179, 73,215, 77,221,186,245,146, 60,189,115, 26, 47, 30, 94, 92,148,155,108,249,248, 43, 66, 8,231,208,161, 67,166, 81, +163, 70,169, 22, 47, 94,236,113,252,248,113,239,212,212,212,135, 0,140, 54, 54, 54, 1,126, 85,189, 30,253,126,246,140, 91,215, + 94,125,249,113,105, 26, 88, 75, 5,240,114,148,226,214,245,115, 70,161,144, 95,236,120,146,252,110,192,129,238,237,166,226,248, +173,200, 78, 79,211,197, 87,190, 24, 57, 44,230,247,107, 97,233,235,118,253,254,131,155,220,248, 80,204,164,174,187, 95,207,199, +121,218,184, 33, 88,178,118, 55,174, 6,135,165,168, 57, 46,139, 18,117,166,243,115,251, 79, 41,193,100,254, 70, 88, 43, 36,124, +168,115, 82,179, 95, 6,159,241,251, 64,214,231, 97,191, 31,221,205,201, 80, 25, 17,155,166, 37, 9, 25, 42,152, 25, 10, 27,169, + 0, 38,134, 34, 43, 35,141,236,217,189, 11,247,238,221,226,128,203,249, 28,192,220, 82,187,179,200,155, 46, 65,185,152,255,198, + 2, 36,121,179, 55,154, 25,248, 87,245,193,150,117,171,172, 28, 28,157,208,172,133,229, 99,158, 21,246, 94,181,247,111, 95,135, + 43, 55, 31,180,186,186,122,125,125,185,171,114,173,149,123,245, 21,214,222,237,181, 58,131, 25,217, 89,153, 16,234, 99,209,192, + 45, 21,118, 82, 51,162,115, 92,240, 36,233,133,188,172,238,172,180,144,223, 30, 42,107,124, 50,235,240,137, 75, 75, 58,182,111, +133, 39,209, 57,144, 8,121, 16, 11,185, 16, 11,185,224, 19, 51, 86,253,180,201,152,153,173,234,150,246,228,104, 90, 5,234,231, +133,252,175,221, 55, 47, 55,167, 42,202,221,107,103,237,252, 98,202,178,142,157, 62, 25, 78,158,220,187, 60, 3,192, 69,203, 62, +240,168, 69, 97, 12, 67, 45,174,251,142, 62,245,246,110,223,177,175,127,117, 95, 15, 36,103, 25,145,144,105,192,245, 7, 17,216, +249,243,172,172,204,228, 87,131, 97,200,205,101,136, 41,251,220,217, 19,103,191,254,102, 10, 2,107,212,174,148, 19,151, 99, 5, + 32,251,157,123,114,201,230,161, 35, 71,247,119,114,114, 82,252,207,130, 69,225,231, 95, 29, 93,122,124,138,115,199,142, 32,244, +233, 99, 48,244,141, 80, 98, 24,138,172,204,244, 36,147, 81,191,163,164,248, 9,197, 98,175, 95,182,239,242,229,112, 8, 12, 70, + 6,122, 19,131, 9, 95,142,208,143,249,118, 70,179, 46, 29, 90, 62, 21,114,145, 19,253, 58,209,230,214,131,103, 53, 25,190,220, + 99,228,228, 85, 2,173,206,140,236, 60, 35, 78,111, 43, 89,227, 72,236,188, 26,215,110,210,107,228,152,239,183,136, 68, 92,142, + 33,208,207, 35,178,101,163,192, 88, 79, 87, 7,213,252,165,235, 27,220,184,243,160, 75,191, 65, 35,197,195, 2,130,136,171,189, + 68, 49, 98,208, 39,181,100,246,158, 67,213,233,175, 75, 92,218,140, 47,181,205,242,244,174,154,247, 63, 11,145,255,111,132,162, +242, 59, 34,130, 32, 50, 47, 41,172, 55, 0,184,184,122,106,249, 34, 43, 85, 57, 4, 8, 5,128,181, 91,247,213,123, 20,158,240, +197,143, 63,174,150, 6,191, 82,225,225,171,108,136, 4, 28, 24,140, 12,136,133, 70,108,134,114, 71,207,156, 62,205, 42, 83,109, +198,149,199,169,120,122,255, 50,213,231,106, 7, 73, 77, 86,189,101, 78,254, 67, 1,248, 0,136, 32,132,110, 86, 39, 59, 31,163, +244,138,169,188,245,158, 97,222,124, 39, 91, 59,250, 84, 54,243, 68, 93,248, 66, 89, 99, 66,104, 32,161,176, 5,104,124,122,254, + 59,213, 82,133,166, 78, 14,199,178,197,179,177,230,231, 35, 72, 72,215,194,218, 28,139, 99,219, 22, 98,210,146,189,208,232,204, +165,213,241, 82,245, 72,113,130,168,168,208, 42,248, 93,112,222,146, 37, 75,186, 21, 41,155,110, 37,148,217,159,206, 43,184,126, +233,210,165,139, 11, 29,207,179,184,139,176, 32, 49,165, 37,202, 74, 89,189,138,192, 74, 46,178,146,240,225,237,233,130, 1, 99, +231, 58, 56,251, 54, 77, 17, 9,121,220,163,251,182,216,165,105, 68, 32, 28,142,218,226,238, 13,167,128,134, 10,133,226,244,111, +191, 30, 65, 21, 79, 71,193,158,235, 25, 81, 15, 34, 53,111, 77,186, 57,169, 49, 66,111,171, 60, 94,239, 79, 62,145, 94,188,116, +249,219,146, 4, 22,151,112,221,183,238,250,213, 81, 33,225,131, 16, 64,165, 49,225,139,161,159,190,255,235,139, 50,220,145,195, +135,129,228,139,171,156,244, 36,204,152,250,165, 86,102,124, 22,250, 58, 38, 62,190,221,167, 43, 47,230,228,242,181,253,135,124, +121, 47, 52,124, 73,102,217,181,215, 24,215,165,107, 23,193, 27, 75, 1,192, 37, 4, 12,101,146,253,189,229,227,254,212, 45,152, +164,219, 90,150, 96, 83,197,135,101, 40, 92,106,246,217,189,242,235,173,174, 78,142,246,114,153,132,202,165, 34, 18, 24,224, 43, +104,212,168,137,208,219,191,150,224,250, 51, 13, 94,167,106, 16,153,144, 13,145, 83, 29,222,128, 54,157,177,123,245,228, 86,132, + 16, 78, 89, 3, 95,207, 95,185,221,253,231,159,126, 20, 37,103, 25,240,252,117, 46,146, 50,181, 72,204,212, 33, 41, 67, 11,185, +132,143, 22, 61, 70,137, 78, 29,219,220,189,109,243,134,107, 43,146,189,145,145, 81,167,162,227, 19,251,214,170,219, 0,187,119, +110,111,110,107, 91,217, 42, 51, 51, 50,199,210,210, 89,184,112,161,112,233,210,165,188,117,235,214,229, 52,106,212,200,121,250, +244,233, 29, 83, 82, 82,238, 86,170, 84,201,255,220,111, 59, 46,213,105,209,179, 62, 24,131,178,121,203,214, 2, 17,195,195,239, + 39, 79, 26, 14, 30,216,147,174,209,168,198,148, 42, 52,164,214, 11,147,115, 9,148,110,110, 79,229, 66,115,123, 30, 39, 43, 60, +227,204,184, 93, 0,126,243,233, 60,254,194,229,251, 97,225,245,130,163, 29, 47, 5,191, 76,201,200, 51,248, 69,156,153, 88,106, +131,203, 37, 4,124, 46, 7, 10, 9, 15,156,252,214, 84,225, 86,251, 37, 8, 81, 22, 88, 74, 9, 72,254, 30, 32, 4, 9, 25, 49, + 15, 44, 24,147, 65, 40, 67,129,176, 56, 53,114,181,111, 76,240,238, 14, 82,164, 38,199, 97,227,218, 29,120,112,255, 30, 58,116, +238,129, 13, 91,247,224,139,161,125,181,101,177,113, 56,249, 22,172, 66,214, 43,185,132, 7,128, 32, 75,109,196,175, 55, 98,225, + 83,153, 99,241, 11, 1, 0, 20,114, 41,178, 85, 26,112, 4, 10, 68, 4,159,150,158,185,124,103,250,172, 5, 63,126,151,153,248, +248,245,203,144,235,240,119,200, 70,101, 55, 3,158, 38, 89,225,126,186, 55,252,171, 86, 1, 71,112,207, 34,238,180,167, 53,151, + 29,227,252,218,173, 94,157,234,141,189, 28,109,160,209,155,243,173, 88, 92,108,255,101, 23,162,163,226, 70,166, 61, 61,250,224, + 67, 40,217,220,228, 87,169, 98, 39,223,175, 66,238, 92,140,252,100,208, 87,112,113,243,172, 93,158,225, 9,150,132,153, 45, 16, + 88,132, 16,142, 93,165, 58, 59,119,238, 62,212,191,178,167, 51,206,223,137,194,221,240,116, 56, 56,216,131, 43,117,134,111,203, + 17, 54, 33,103,215,124,170, 73,203,221,201, 23, 72, 63,111,216,168, 41, 40,165, 8,123,246, 52, 35, 59,219,250, 79,109,115, 94, +194,243,135, 0,172,222,233,134, 82, 86,171, 45,183,182,123,168, 51,152, 17, 31, 31,135, 63,110, 94,169,155,127,158,197, 16, 9, +184,248,253, 65, 10, 12, 70, 6, 6, 19,131, 22, 45,219,235, 5, 28, 93,243, 69, 63,254,210, 40, 49, 33,145, 35,179,114, 96,236, +220,170, 9, 92, 68, 6,221,163, 87,217, 2,131,145, 65, 21, 87, 89,169,156, 74,215,170,139, 39, 79,158, 80,141, 43,144, 64,165, +214,233, 19, 19,226,157,183,236,187,156,251,236,121,136,155,187,163,181,213, 15,171, 55, 11,114,180, 4, 41,217, 58,100,168,114, +200,160,209, 83, 92,127, 94,191,100, 48, 0,139,215,142, 37, 20,149, 79,253,126, 61,192, 86, 33, 32,185, 90, 19,147,158, 99, 48, + 15,234,245,126,147, 40,243,197,213,168, 31, 87,173,150, 62,120,165,194,163, 87,217, 16, 11,184, 16, 10, 56,208, 27, 25, 88,242, + 56, 17, 66, 56,149,107,180, 28,211,164, 94, 77,156,123,152, 6, 46,151, 3,141, 42, 51,143,135,244,240,122,173, 58, 72,131, 26, + 52, 66,235, 86, 45,241, 50, 60,204,243,228,241, 95,219,222,250,227,106,146,220,209,255,235,220,148,176, 35,229,170,231,121,121, + 92,163,208,121,132,139, 91,165,166,189, 7,140,176,246,242,116, 35,142, 14,246, 48, 81, 30, 70, 13,253,212,226, 39,255,141, 32, + 7,150, 46,152, 14,157, 78, 15,165,141, 16,148, 2,191,172,157, 11,189, 94, 15, 87,123, 17,178,213,198,210,132,105,169,122,164, + 36,171, 83, 57,187,155, 79, 22, 39,178,138,134, 19, 66, 78, 78,155, 54,109, 6, 0, 58,109,218,180, 25, 5,255,151, 44, 89,162, + 1,144, 96,145,192, 42, 72, 84,137, 13,165,171,175,159,173,163,235,141,131, 59,215,219,102,230, 26, 32, 22,112,225,238,225,133, +169,243,215, 40, 59,215,115, 64,170, 86,138, 67,135,183,103,232,181,121, 7, 44,235, 75,246,173,167,144, 89,157,219,185,251, 0, +227, 96,111,207,217,248,123,234,171,116,149,233,109,215, 85,248,157,227,204,253,115, 91, 92, 40,200, 89,177, 88, 92, 85,175,215, +219,150, 85,160,191,252, 30,147, 63, 56,151,124,136, 54, 21,132,203, 53,239,222,179, 27, 14, 86, 66,232,140, 12,166,125,247,141, +102, 88, 91,115,214,160, 79,223,116, 11,242,101,213, 46, 54,169,235, 75,235,212,169,147,197,229,114,203,228, 75,143,188,251,167, +217, 18, 1,222,210,207,103, 78,234, 62,179,152,110, 65,139, 6,228,170, 18, 67,110, 0,120,199, 34, 66,124,124,132,123, 15, 29, +251,166, 79,191,254,179,220,106,247,146, 71, 37,102, 67, 64, 12,168, 95,205, 5,151,207, 30,161,113,209,225, 19, 44,153, 85,148, +146,154,225,161, 84, 58,225, 65,100, 46,226,211, 53, 72,202, 23, 87,137,153, 58,168, 52, 42,212,242,114, 69, 86,118,182, 71,133, +243, 23, 56,114,238,220,185,190, 93,122,246,199,248,239,230, 53,219,246,211,138,199,114,103,191,207,114,147,194,175, 88,242,101, + 72, 8,201,152, 58,117,170,207,214,173, 91, 57,131, 7, 15,214,212,172, 89, 83, 60,100,200,144,102,187,118,237, 18, 75,165, 98, +205,163,235,199,103,125, 62,110, 90,207, 45,107, 22,214,206,204,204, 36, 38,163,241,140, 33, 51,115,154,170, 12, 17,247,250,216, +244,231,164,250,188,225,237,155, 43,143,219, 73, 57,129, 34,170, 31, 64,170,207, 59, 64, 67,231, 24, 34,206,172, 85,213,236,183, +106, 92, 66, 22, 51, 83,203,113, 92, 84,150,184, 2, 0, 14,151,252, 31,123,103, 29, 94,197,209,182,241,123,142,231, 72,220, 29, + 8,132,132, 16, 92,139,187,107,209, 82,161, 45, 82, 42, 20,105, 75, 75,139,150, 66, 41, 20,105,105,177,226,180,184,187,187,107, + 2, 17, 8, 81,226,114, 36,199,101,231,251, 35,242, 6, 26, 57,161,244,123,251,210,249, 93,215, 94, 73, 78,118,239, 51,179, 59, +187,123,207, 51, 6,147,213, 6, 71,169, 16, 60, 30,175,196,188,251,174,223,118, 68,230,233, 44,134,144,207,131,128, 95, 20,221, +204, 85,155,241,225,232, 1,118,215, 0,172, 54, 10,189,201, 10, 93,113,109, 80,163,206,197,151,159, 77, 70,175,126,131,240,254, +248,201, 40,208, 3, 55,159,104, 96,182, 88,170,188, 41,120,132, 7,157,209,138,119,187, 7, 35,191,208, 12,173,222, 10,147,149, +131, 76, 44,128, 80,192,131,220, 65, 0, 39,153, 16,160, 84, 68, 8, 25, 11, 0, 66,161,208, 96, 54,155, 55, 87,114,157, 80, 51, +208, 27,122, 11, 15, 45,134, 47, 66,215,214,117, 17,125,113,151,224,220,213,251,181, 62,253,108, 58, 38,142,233,135,157, 49,181, +225,230, 21, 12,133, 92, 10, 11,229, 1,160,118,117,200,163,116, 38,231, 27, 62,120,228,202, 53,235, 98,231,204,152,230,160,212, + 18, 72, 68,124,156, 62,117, 18, 87,174,221, 92,150, 19,189,119, 51, 94, 34, 66,202,243,118,114,114,130,131,152, 15,147,217,104, +178,191,139, 2, 5, 5,154, 40,188,195, 86, 22,215,240,155,216, 56,148,243, 25,173,234,133, 64,156,253, 34,215,175, 92,187,101, +148,159,143, 23,246,156,186,135,245,107,126, 66,173,198,125,113,241,208,122, 56,215,108, 5,121, 80, 91,136, 29,119,140,229,241, + 5, 13, 62,250,244,171,193, 77,155,183,198,165, 11,167,145,157,153,177,146,210, 24,187, 34, 26,124, 33,249,164,115,183,126, 48, +152,108,104,215,165, 47,142, 30,216,243, 49,138, 7, 79,216,255,242,122,238,249, 12,158,117,242,164, 79,132,217, 74,147, 48, 71, +109, 66, 90,142, 14,137, 89, 58,236,251,227, 55,106,255,243,194,212,188,125,195, 0,225,216,133,167, 83, 3, 3,124,141, 66,163, + 94, 26,247, 56, 33,252,253,209,111, 11,107,213, 9,231,101,171,140,200, 81, 25,145,171, 50,162,208, 96, 69,157,128, 80,158,197, + 74, 90, 87,247, 58,123, 56,139,133, 43, 14, 60,129,147, 92,136,215,194, 95,124,224, 44,199,113,255, 49, 87, 75,138,204,213,189, + 39, 42, 72, 68,124, 72, 68, 60, 72, 68,124, 88,109,212,174, 10,139,212,171,110,239, 15, 63,154,224,103,178, 2,121, 42, 19, 4, +124, 2, 47, 15, 87,121,243, 70, 35,177,110,209,199, 0,128, 49, 95,252,130,247,223,125, 19,245,234, 55,128,178,160,192,103,228, +144,222, 75, 0,236,177, 55,173,135,143,159, 13, 58,126,254,246, 23, 31, 78,157,169, 24,214,175, 19,255, 78,130, 10, 25,249, 70, + 60,142,211, 84, 43,210, 6, 0, 86, 27, 7, 10,138, 13,219, 14, 66, 42, 22, 32, 71,101, 6,165, 20,223,254,180, 29,142, 82, 33, + 50, 10,138,154,245,171,120,198,147, 42,254,223,247, 47,197, 79,138,142,207,193,127,250,105, 85, 25,193,154, 63,127,126,244,252, +249,243,203,141,136, 85,105,176, 42, 51, 87, 46,174,190,151,246,111, 91,227,182,231,182, 9, 87,119,220, 68,159,150,190, 16, 9, +120,144, 57,123,226,238, 19, 45,142, 29,253, 93,121,120,255,206,167,249, 66,221, 15, 85,154, 43,223,176, 38,114,169,211,201, 21, +171, 55, 90, 61,188,188,176,249, 66,126, 90,129,214,106,249, 79,243,148,133,220, 60,182,186,150,149,179,244,212,103,198, 87, 89, +157,229, 40, 68,243,127,221, 7,128,130,227, 56, 80,142,131,208, 65, 33,247,172,221, 58,171,248, 1,231, 32,224, 17, 67,217, 59, +159,114,214,180,156,132,202,195,157, 4,128,179, 76,136,109,231,158, 2, 64, 22, 95,125,253,225, 27,175, 23, 53, 11, 26,204, 50, +117,253,218,181,105,243,230,205,149, 82,169,244,133, 47,114,117,155, 5,237, 42, 56,143, 31,155, 0, 44,244, 11,107, 55,168,135, +162, 97, 11, 49, 79,132,166, 97,190, 56,115,108, 47,189,122,116,221, 24, 93, 86,236, 70, 59, 11, 32, 10, 13, 22,164,231, 25,240, + 52,207,128,204, 2, 3, 50,243,141,200, 44, 48,128, 16, 2,131,201,250,151, 94, 88,218,236,216, 29,155, 55,174,237,111, 52, 99, + 68,251,238,131, 48,121,230,138,224,205, 43, 23,156,148,122,135,183,177,167, 3, 45,165,212, 70, 8, 73, 26, 61,122,116,163,223, +127,255,157, 31, 25, 25,169,127,248,240,161, 12, 0, 7,192,172, 80,200,164,191,253, 60,255, 88,139, 22, 45,254,120, 26, 23,115, + 26, 64,129, 61, 35,169,106,116, 28, 45, 9,119,202, 31, 27, 36,127,173, 71,136,143, 12, 65,114, 77,143,112,197,221, 31,188,186, +124,250, 93,246,169,165,217, 25, 70,235,137, 28, 61,191,241,211, 66,161, 93,125, 1, 45, 70, 67,242,224, 33, 35,192, 39, 60,152, + 13,186,228,146,194,229,229, 44,198,172, 45, 49, 80, 56, 8,225, 40, 21, 64, 33, 21,162,109,132, 27,170,241, 28,163, 22, 27, 7, +157,209, 6,189,209, 10,131,201, 10,143, 64, 87,172,217,188, 3, 41,217,122,236,187,145,139,216,100, 13, 66, 3,228,160,180,234, +199, 35,103,179,104,251,189, 62,202,145,207, 35,224,243, 8, 47, 34,188, 46,242, 11,205, 16, 9,120, 16, 57, 72, 33,151, 8,224, + 36, 21, 66, 36, 18, 34, 59, 59, 27, 70,163, 17, 65, 65, 65, 14,149, 91, 64, 10, 71,133, 20,161,181,252, 96,182, 88,113,248,252, + 3,204,155, 52, 24,221,218, 55, 3, 17, 42, 16, 99,108, 2, 71, 55, 71,112, 60, 30,204, 86, 14, 38,179, 13, 0,175,194,104, 91, + 80, 80, 80,103,185, 92, 46,215,233,116,154,228,228,228,179, 25, 49,187, 83,188,234, 15, 28,123,244,248,233,205,125,123,117,195, +237,123,209,216,185,103,255,133, 92,119,213,212,146, 99, 34, 35, 35, 91,121,120,120, 40,242,242,242,212,247,239,223,191,254,130, +181, 93, 34,247, 14,255,180,117,219,142, 40, 84,102, 35, 43, 53,209,238, 90,115,189, 96, 71,124, 51,127, 69,211,176,186, 97, 77, +109,180,200,112, 69, 4, 57, 98,202,204,229, 77,107,135,214,109, 90, 50,208,163, 94, 80,229,211,170,201,189,195, 38,204,251,241, +215,183,130, 2, 3,113,228, 82, 12,230, 79, 31,127, 91, 46,115,172, 25,224,237,234, 34,170,223, 12,119,238, 92,134, 23,196,112, +242, 14, 13, 24,209,127, 92, 64,143, 94,253,113,255,238, 77, 44, 93, 56,247,138,150, 47,253,206,158,180, 42,188, 67, 60, 27, 55, +111,255,134,163,155, 55,148, 42, 13, 28, 93,189, 80,175, 97,243, 55, 20,222, 33, 95, 20, 47, 86,255, 98,102,131, 82, 24,205, 20, + 5,133,102,164,230,232,145,148, 89,100,176, 56,174, 26,125,126,108, 28, 81, 56, 8, 4,110,150, 71, 65,247, 79,158,166,193,129, +222,100,225,220,207,248,102, 56, 32, 71, 89,100,174,114,212, 38,228,168, 76, 40, 52, 88,224, 38, 23,128,179,113,213,174,109, 23, + 20,154,225, 88,220, 79,214,198,189,120,159,239, 95,215,111, 11,187, 27,151, 62,240,199, 31,151,202,238, 60, 41, 99,174,132, 69, +209, 43,137,136, 15, 27,199, 21,191,105,170, 48,247, 2,225, 39, 3,122,119, 69,106,174,190,104, 20, 50,143, 32,180, 65, 11,120, + 72, 57,116, 25, 62, 13, 0,208,175,119,209, 52, 36, 79, 50,180, 56,112, 53, 7,120,182,195,118,229,207, 98,189,158,191,122,203, +161, 79,119,108,255,195,217, 96, 19, 96,213,145, 36,232,140, 86, 56,136,248,144,136,248,144,138,248,207,116, 9,170,218, 96, 21, +245,169, 75,201,181, 64,103, 48, 64,173,183,128, 2,184,254,168, 16,122,147, 21, 42,173, 5,173,194, 93,255,106,157,231, 16,128, + 62,207, 27,161,231, 77, 82,153, 8, 84,121,220, 40,171, 81,178,127, 69, 6,174,108,159, 44, 0,118, 85, 4, 5,207, 59,197,178, +127, 59,250,133,214,117,113,241,189,180,255,143, 53,110,187,111, 27,113,230,110, 30,134,180, 11,128, 78,149,137, 5,243, 63,207, + 39,160, 38, 30,159,167, 52, 26,244,187,243,100,230,121,244,193, 99,115,165, 15, 9,207,136,134, 82,153,236,244,247, 75, 87,153, +189,188,253,185,221, 87,149,217, 42,157,237,153, 88,161,205,104,228, 81,142,138,236, 49, 87,197, 77, 27,230,153, 31, 15, 2, 71, + 41,102, 45,221,129,239,166, 14,135, 66, 58, 74, 70, 8,145,105, 13, 86, 76,154,189, 22,139,191,121,207, 81, 38, 17,128, 16,192, + 96,178,225,173, 17,131,236, 43,120, 6, 43, 30, 95,251,189, 80,243,100,239,195,178,205,130, 45,219,246,186,217,178,101, 75,165, +171,171, 43,164, 82,233,127, 34, 19,118, 62,172,203, 27, 45,152,173, 68,154,163,163, 99, 7, 39, 39,167,178,122, 90,165, 82,185, +247, 69, 74,159, 70,153,123, 58, 51,233,126,139, 54,157,250,225,236,177,189,244,234,145,223,198, 84,103,142, 29, 87, 55,215,212, + 91,247, 31,215, 35,196,173, 40,130, 85,108,174, 76, 22, 14,193,222, 50,164, 38, 61,134,139,179,115,170,189,122, 50,175,240, 1, +132, 71,199, 19,208,117,133,153,113, 59,138,205,206, 72,185, 79,248,189,232,168, 59,243,250,190,241,137,160,251,144, 9,252,149, +243, 63,250, 10,207,117, 78,173, 4,115,108,108,236,131,247,222,123,239,181, 43, 87,174,216, 0,232, 8, 33, 22, 62,159, 47, 51, +153, 76,162, 78,157, 58,169, 98, 98, 98,206,193,142,206,136,237,222,221,233, 65, 36,154, 94,181, 67,155,143, 12,118,212,116,235, +212,174, 53, 90,215, 15, 68,106,187,214, 0,240, 73,114,161, 34,172,237, 7,191,109,171,229, 25,112,120,229,250, 3,223,141, 25, +222,117,146, 95,191,217, 63,166, 31,152, 89,105, 7,211,148, 7,103,123,148,103,223, 5,124, 30, 28,165, 66, 40,164, 2, 56, 74, +133,112,116, 16,194, 98,165,213,169, 41, 82,139,149, 43,138, 96,153,172, 40,212, 91,113,250, 78, 22, 50, 85, 38, 40, 53,102,232, +205, 54, 80,208,162,218,167, 29, 79,241,236,248,139, 46,165,215, 62,184,169,106,245, 79,139,156,118, 93, 76, 43, 29,161,231, 44, + 19,195, 81, 86, 52,170,250,252,249,243,112,119,175,186,118,207,113, 28,118, 30,189,142, 31, 55,156,198,209,117,159,195, 65,196, + 71,195, 1,179,241,206,192,150,224, 40,135,199,177,209, 89,161, 17,141,188,121, 60, 41,120,132,192,104,225, 0,208, 10,207,167, +201,100,114, 79, 73, 73, 81,215,169, 83,199,199,223,223,127, 8,159,207,167, 18,192,184,247,143,124,221,169,131, 91,101, 90,189, +209, 38,179,170,214,213,201,208,247, 9, 13, 13, 5, 33,132,122,120,120,136, 78,159, 62, 93,216,160, 65, 3,207, 23, 52, 87, 60, +169, 87,221,101,239,127,240,233,144,218, 33, 33,216,177,117, 29, 40, 37,187,236, 61,126,203,129, 43,152,251,229,179, 35, 6,167, +204, 92,222,116,241,236, 79,158,249,236,131, 47,127,108, 90,217, 51, 35, 32,178,243,231,225,225, 17,184, 18,157,134,133, 95,127, +112,219,144,253,100,164, 73,225, 62,206, 92,152, 49,185,113,147,102,240,113,119, 66,122,190, 17,253, 71, 13, 68,155,182,237,112, +255,238, 77,204,253,230,179, 43,208,153,186,211,156, 7,122,123,210,202, 81,225,248, 78, 61, 6, 10,245, 70, 51,150, 47,156,129, +113, 83,231,161, 85,231,126,194,168, 59, 87,199, 3,152, 99,111,158,141,102, 27, 58, 53,240, 40, 50,205, 22, 14,251,159,240, 5, +229,149, 64, 1,159,240, 26,135,184, 64,111,178, 66,173,179, 84,254,162, 18, 9, 51,149, 42,117,141,159,191,251,148,175, 53, 88, +145,163, 50, 33, 91,101, 68,174,242, 63,198, 42, 87,101, 68,142,202, 4,161,128, 32, 46, 33, 25, 60,161,160,218,253,239, 10, 10, + 45,104, 81,215,181,232, 30,125,193,214, 16,139,192,169,229,209,115,119, 7,255,248,227, 18,135,187,137, 26,220,123,162, 46,142, + 92,241, 33, 17,242, 32, 46,254,221,198, 1, 85,125,133,179, 87,237, 90,111,191, 55,166,139,147, 66,138,244,248,108, 8,248, 69, + 83,189, 56,123, 5,194, 89, 98,192, 71, 31,140,133,135,187, 11, 82,114,141, 88,182, 39, 14,247, 30, 60, 2,167,175, 94,182,151, +175,250,163,231,251, 31, 78,113,225, 9,197,216,116, 44,177, 40,157,124, 27, 98,174, 30, 48,164, 63,190,175, 45, 84,231, 81, 80, +155,157, 21,127, 66,173,182, 34, 99,250,221,172,105,248, 99,195, 47, 56,118, 43,187,180,115,214,197, 93,139,241,233,151,223, 34, + 87,109, 42, 46,250,149, 71,174,158,251, 59,167, 76,228,233, 79,127,151, 49, 69,229,253, 77,138,255, 54, 85,160, 97,122,206, 84, +153,158,251,220,244,156,158, 93,115,247, 9, 42,139, 92, 57,187,250, 92,218,183,109,181,219,238, 91, 38,156,189, 87,100,174,172, + 70, 37,126, 93,248,101,134, 78,169,110, 95,217,132,141,127, 50, 87, 94,117, 35, 37,114,249,185,175,191, 93,102,244,246,175, 97, + 61,124, 71,157,167, 49,216,254, 20, 6, 17,201,228, 54,185,179,167,193, 37,184,201,143, 66,189,105, 70, 78,206, 3,109, 85,145, + 38,142, 82, 28,188,150, 9, 74,139,170, 68,219,207, 63, 69,113, 77, 28, 54,174,168,249,228,196,157,108, 8,138,251,153,216, 27, +230,254,117,213, 47,234, 62, 17,201,218, 55,102,253,167, 89,176, 85,163,162,200,149,147,147, 19, 92, 92, 92,160, 80, 40, 96, 79, + 19, 97, 9, 21,141, 22,116,116,116,236,112,231,206, 29, 7, 39, 39, 39,240,249,124, 24,141, 70,212,175, 95,255,133,110,112,133, + 79,248,135, 45, 58, 15,250,170,109,231,126, 56,125,116, 55,189,122,116,253,216,234, 78, 96,216,167,235,107, 7,230,206,157, 85, +235,235,121, 63, 75, 28, 29, 4,120, 88,104, 2,143, 16, 4,123,203,224, 46,231,225,236,222, 77,134,225,253, 94,179,123, 82,187, +192, 64,255,205,139,127, 90, 45, 95,188, 96,118, 39, 71,255,176,211,154,167,177,249, 0,160,205,140, 89, 40,243, 9,127, 16,112, +249,248,225, 70, 29, 6,193,219, 47,164, 91, 53,194,188,148, 16,162, 75, 72, 72,120,242,245,215, 95,135, 45, 88,176,128,242,249, +124, 14,128,100,233,210,165,186,248,248,248, 59, 40, 26, 98,139,170,162, 87, 93,186,213,159,164, 16,219, 90,185,201,120,245, 67, +124,100,104, 93,191,168,245,115,120,159,182, 8, 12, 10, 66, 66,166,174,113,190,142, 19, 22,154,248, 33, 43, 86,221,187, 81,211, +131, 63,198,170, 55, 61, 64, 21,147,192, 86, 84,102, 75, 58,190,151, 68,175, 28,165, 66,112, 64,117,106,138,212, 98,229, 96, 52, +219,160, 55,218,160, 55, 89,161, 53,217,160, 51,217,192,209,162,123,130, 16, 2,179,149,131, 93,213,228,231,202,190,147,155, 7, + 66,106, 22,141,122,117,148, 22, 77,217,224, 36, 19, 22,141,117,118,119,135,151,151,151, 93, 81, 80,147,185,232, 22, 55, 89,184, +210,230,123,147,217, 10, 74, 41,226,226, 98, 63, 79,122,242,100, 64,157,208, 58,237, 35, 26, 54,114,147, 73,120, 0, 80,161, 25, +208,233,116, 54, 71, 71, 71, 47, 55, 55, 55,222,211,167, 79, 75, 77,115,157,198,157,172,123,118,239,194,224,193,131, 10, 31, 94, +191, 91, 58, 84, 93,175,215,147, 54,109,218, 56, 5, 6, 6,242,140, 70,163,186,122,231,128, 16,185,103,221,129,129,225,175,205, +123,107,244,184,186,157,186,246,196,153, 83,199,177,111,247,239, 27,181,217,177,199,237,190,223,195,194,255, 52,138,176,118,104, +221, 63,141, 34,172, 81, 43,180, 66,131,229,236,220,208,169, 97,243,142,129, 73,185,102, 28, 57,114, 24, 90, 85,230, 55, 38, 83, +161, 14, 66,186,246,224,239, 43,222,123,255,211,217, 78, 29, 59,180,131,171,147, 12, 2, 1, 31,183,110, 92,193,130, 57, 95, 93, +129,206,212,189,170,231,103,105,126, 35, 34, 68,117,130,106, 76, 12,170, 29,137, 91, 87, 47,224,113, 92, 84,244,221, 27, 87,234, +215,105,208, 10,158,126,193, 19, 73, 68,196, 2,250,224,129,185, 42, 29,147,193,144,252,206,219,111,162,236, 40,194,214, 77,194, +220,201,243, 55, 0, 0,157, 38,219,252,219,162, 73,241, 37,163, 8, 57,179, 41,185, 34, 93, 85, 65,206,206,179,151,174, 77, 29, +208,167, 39, 47, 87,109, 42,138, 88,169, 76,197,155, 17,185, 37,191,171,141, 8,245, 83, 32, 54,250, 22,103, 80,229,238,170,230, +125,105,120,103,104,143, 7, 37,101,151,227, 40, 8, 96,168,238,253, 77,133, 78, 99, 23,254,240,163,195,221, 39,133,184,151,168, + 46,106, 18, 20,242,139,140,149,144, 87,106,182,138, 70,167, 87, 17, 13, 34,252,239,222,125,123, 4,114,213,102,112, 28, 32,224, +243,138, 55, 17, 82, 52, 4,169, 26, 29,114, 11,114,240, 36, 41, 25,202,204,199,224,241,120,240,240,171, 11,123,195,141, 54, 42, +246,213,153,104,131, 33,125,218, 11,118, 95,206,128, 76, 34,128, 81,147,133, 35,219, 22,229, 24, 11,213,243,244,186,194,221,250, +188,248,116,123,243,206, 35, 36, 71, 93,104,240,150, 8,249,216,177,225,103, 12,125,231,131,226,147, 82,244,227,243,233,115, 1, + 30, 65,126,129, 6,132,144,234, 70, 69,111, 84,241,247,139,240, 50, 52,170,111,176,100, 50,247,147,251,254, 88,237,118,249, 9, + 15,215, 99, 11, 48,164, 93, 0, 44,134, 2, 44,251,118,114,166, 90,157,221, 89,147, 19,159, 80,173,111,226,241,122, 12,127,119, +106,116, 72,221, 8,227,153,168,194, 68,165,214, 82, 97, 63,134,214, 67,190,142,190,121,232,167,222, 42, 75,194, 4,133, 95,125, + 27,103,181, 46,212,101,199,206,174,160,137, 80, 60,123,217,142,210,230,193, 47, 22,108, 42,250,221,102,131,141,114,160, 28,240, +209, 55,191,194,202,217,192,217,108,224,108, 20, 22, 27,149, 85,149, 92, 47,191, 26,187, 11, 30,254, 30,254,198,215,127,110, 22, +116,113,113,129,187,187, 59,220,221,221, 81, 98,136,254,106,179,160,147,147, 19, 20, 10, 5, 46, 92,184, 0,169, 84, 10,185, 92, + 94, 45,221, 50,230,106, 66,243,142, 3,126,238,220,255, 61,156,216,189,138,222, 56,127, 96,156, 46, 43,118,173,221,145,120,155, +141, 88, 44, 22,244,233,222, 49,249,118,244,163,163,211,167,142,239,249, 90,223,113,146,214, 97,254, 48,152,108, 72, 75,122,140, +179,123,215, 27,234,214,242, 61,214,165, 93,203,100,139,197, 2,155,205, 86,229, 11,220, 96, 50,231,242,133, 82,249,136, 17,111, + 8,111, 92,191,190, 75,225, 85,119,135,141,240,238, 18,202, 53, 36,132, 12,110,216,176, 30,204, 22, 14, 58,157,186,160,186,121, +214,104, 52, 79,214,173, 91, 87,235,237,183,223,150, 69, 68, 68, 8, 31, 63,126,140,197,139, 23,231,105, 52,154, 39,246,106, 28, + 63, 31,187, 84, 64, 10,226,197,156,121,100,176,163,166, 91, 74,219,214, 24,209,183, 45,254, 56,116, 17,103, 47, 92, 65,114,161, +226, 78,161, 85,176, 55, 53, 57,221, 88,223, 77,189,171,127,235, 26,252, 29, 27, 10,118,121,117,250,114, 24,165,146,227, 57,103, +103,106,237,127,121, 3, 26,189, 5, 78,178,162,249,154, 74, 34, 89,124, 66,236,118, 66, 4,120,114,225,202,173,200,102,161, 17, +184,253, 68,133,108,165, 17,122,163, 21, 28, 71,193,129,194,221, 81, 12, 7, 17, 15, 41, 73, 79,192, 81,115, 98, 53, 95, 17, 57, + 29,218,119, 16, 0, 4,132, 80,129, 80, 32, 0, 69,209,188,136, 82,169,180,208,203,203,203,174, 8,150,217,106,197,224,158, 45, +209,170,121, 67, 12, 24,183, 8, 0,112,106,227, 52,184, 42,132,248, 99,243, 90,164,156, 91,178, 57,228,181, 15,142, 71,221,143, +126, 61,250,246,229, 55,122, 53,149, 54,246, 17,164,139, 42,210, 43, 44, 44,220, 69, 8, 17,139, 68,162,158,237,219,183,119,219, +181,107,151,210,195,195,131, 19,139, 68, 57,253,251,245,229,132, 34, 81,126,201,190,151, 46, 93, 18,142, 27, 55,206,177,160,160, + 32, 37, 43, 43,235, 10,165,212, 82,121, 5, 48,188, 43,120,248, 29,132, 56, 40,164,178,228,214, 93, 71,248, 53,111,213,210,121, +224,224,161,144,136, 37, 56,113,252, 40,150, 47, 89,176,189, 48,227,225,187,213, 57,147, 47, 99, 20,161, 74,229,172,141,127,112, +183, 32, 49,219,228, 42,116, 9,133, 80,226, 56,142, 56,251, 45,227, 75, 20, 51, 61, 27, 13,116,218,185,255, 48,238, 71, 69,193, + 77,106, 65,194,227,120, 93,212,157,219,191,232,136,112, 54,205,121,160,179, 55,157,178, 60,219,235,173,223,236,233,106, 52,219, +112,254,244, 33, 3,103,229,122, 94, 57,119,248,113, 64,221,230, 14,145,205,187,184,230,238, 91, 59, 24,192, 31, 85,233,164, 61, +252,115,196, 54, 40,172, 69,226,169,211, 39,157,189,131,235,243, 9, 8,204, 70, 3,114, 18,110, 88,117, 89, 49,106, 85,218,125, +187, 70,213,230,165,226,155, 47,103,126, 63,161,121,179,102,114, 10,135,103, 34, 86, 37,198, 42, 87,109,130,135,163, 24,122,117, + 14,226,111, 28, 53,232,114,248,149,206, 87,102, 53,105,101,185,217, 89,165, 77,105,133, 89,177,173, 42,219, 63, 55, 59, 75,108, + 53,105,101, 85,191,234,248,112,146,139,113, 63,241,105,105,135,118,137,176,168,239,149, 88,200, 47,237,135, 85,242, 44,168,130, +142, 34, 7, 23, 60,205, 51,128,128,130,179, 89, 97,181,152,160, 81,171,241, 52, 61, 19, 89,153, 89,208,104,148,144, 41, 92, 17, +217,184, 5, 28,229, 14,184,123,118, 59, 40,165,118,205, 75,104, 33,194,176,230,173,218, 73,162,146,138,250, 90, 57, 8, 41, 14, +252,190, 32,175, 80,157,221, 78,147, 30, 23, 95,221,103,177,213,102, 59,121,239, 65,124,253, 0,223,154,228,206, 99, 21, 54,175, +249, 9,166,226, 72,166,197, 98, 67, 84,138, 22, 25,249, 58,164, 36, 60,164,156,205,118, 18,175, 56, 21, 26, 44,145, 88, 40,117, +114,243,195,220,145,163,240,203, 47,191, 34, 49,245, 41,150,207,157,148,169,214,228,116,210,164,199,199,217, 89, 11,236, 90, 50, + 87,134, 54, 51,102,225,187,191, 36,166,237,191,157,207,211,155,104,165, 29,120, 28, 60,131,209,238,221,197,199,244,154,124,177, +205,168, 19, 28,216,252,238,239,229,105, 22, 57,102,152,230, 77, 25, 14,133, 84, 0, 66, 8, 74,154, 5, 87,204, 29, 11,153,164, +168,237, 88,111,180, 98,212,164, 31,177,249,199,201,160, 0, 70, 14,189,168,171, 40,157,101,154,240, 2,146,147, 11,158,118,125, +125,241, 41,131, 89,110,236, 59,232,237,155,205,154, 53, 83, 74,165, 82, 72,165, 82, 56, 57, 57,193,213,213, 21, 46, 46, 46, 85, +230,189,194, 73, 68,203,140, 22,228,241,120,224,241,120,144,203,229, 80, 40, 20,144,203,229,149,106, 86,104,174, 58,244, 95,209, +101,192,251, 56,177,123, 53,189,113,254,192,120, 93, 86,236, 26,123,175, 81,113,179,206,221,193,131, 7, 55, 24, 55,110,156,104, +230,212,113,199, 14, 29, 63, 27,183,227,224,234,126, 5, 5,202, 64, 74, 41, 92,156,157, 83,135,247,123,237, 64,167, 54,205,147, + 79,157, 58,197,253,254,251,239, 70, 66,200,253,170,210,153,155,157,189,241,212,201,211,179,218,117,232,136,181, 27,126,239, 16, +253,224, 97,135,199,143,227, 17, 24, 28,130,154,181, 66,161, 35,174, 56,125,238, 2, 10,149,217, 27,237, 73,231,115, 81, 44, 82, + 80, 80,112,121,248,240,225,221, 47, 94,188,200, 27, 62,124,184, 46, 55, 55,247, 82, 73,189,169,162,232, 85, 89,205,203,191, 14, +204, 1,176,177, 70,199,209,219,159,154,149, 19, 1, 44, 8, 10, 14,194,217, 11, 87,112,229,226,181, 95,115,101, 65,179,223, 29, + 53,122,108,141,254,252,247,251,183,174,193,247,114,149, 97,235,234,197,252,253, 87,146,126, 76,202,179,173, 5, 48,215,158,107, + 84,250,194,208,152,209,166,158, 27, 44, 54, 10,142, 22, 61,104, 29, 29,132,229, 62,112,203,211, 20,152, 36,239,142, 31, 55,238, +113,100,195,198,159,142, 26, 61, 94,212, 56, 36, 16,215, 31, 41, 1, 66,224,230, 35, 71, 70, 70, 6,206,239, 92,109, 45,120, 26, +243, 43,159,207,205,169, 78, 89,202, 79,186, 93,167,204,126, 99,115,115,115,113,246,236, 89,148, 24, 43, 79, 79,207,114, 13,214, +243,154,121, 89,233,151,230,254,176,170,205,152,183, 6,161,111,199,250, 56,119,227, 49, 76,197,243, 45,149, 12, 9,127,114,101, +165,120,226,240, 16,211,132,193,117,213,122,139, 56,233,155, 68,213,249,178,163, 92,159,215,164,148,154, 8, 33,251, 99, 99, 99, +219, 54,106,212,168,198,225,195,135,243,163,175, 29,251,164,108, 58,166, 76,153,162,248,229,151, 95,100,148,210, 75, 70,163, 49, +193,174,188,243,176,245,214,205,155,238,102, 11,135, 11,215,238,214,235,210,166, 49, 56, 10,220,184,113, 3,107,127, 91,107,184, +127,239,206, 34,109,150,207,156,138, 6,136, 84,116, 62,109,127, 97, 20, 97,137, 38,165,103,173, 10,239,240, 95, 47, 93, 56, 55, + 93,226,215, 12,225,189,191,234,255,244,238,254,254, 62, 17, 61,224, 17,242, 26,210,239,237,199,165, 99, 91, 14,115, 86,235, 52, + 7,142,151,172,205,137,209,218,123,191,151, 32,145,202, 62,142,104,218, 1, 41,201, 73, 72,140,143,218,168,207,139, 79, 87,248, +132,111, 76, 79, 75, 30, 95,171,126, 27, 92, 60,246,199, 39, 21, 25,172,170,202,124,160,167,116,245,225,131,251, 71,164,165,173, +244,209,234, 13, 18, 74,169, 65, 34, 22,100, 42,120,154,109,246,166,147,210, 7,102,185, 91,205,193, 67, 71,141, 63,180,124,249, + 18,161,183,139, 12,153, 5, 6,168,245,102,104,116,102,240, 8, 65, 29, 63, 57,116,154,124,156,219,249,131,197, 84, 88, 48,156, +210, 71,230,138, 52,139,214, 19,164, 31, 77,249,224, 12,196,206,129,126,181,186,124, 85,105,116, 78,147,126,175,223,148, 15, 14, +132, 81, 74,187, 40,188,195, 53,133, 89, 49, 95, 87,148,119, 66,138,238,239, 55, 58, 5,194,108, 45,154, 63,204,202, 1, 54,142, + 43,142,234, 1,180,180,221,158, 84,145,119,194,109, 59,116, 9,233, 89, 74,232, 77, 22, 24, 77, 86,152, 45, 54,240,248,124,184, +184,186, 32,180,102, 19, 56,187, 56, 33, 43, 51, 29, 87, 78,237, 71,220,189,115,151, 8,197,108, 93,118,220, 41,123,174,145, 72, +234, 18,230,235,231,195,203, 80,155, 32, 21,243,113,231,220, 97,179,197,100, 92,100,143,185, 42, 79, 83,153,151,255,227,167, 83, + 63, 27,185,126,221, 6,159, 6,181,156,144,150,171, 71, 90,142, 1, 26,131,165,216,128,113, 48, 22,230,226,222,233, 13,153, 54, +131,230,199,127,173,193,226,172, 54, 83,236,163, 4, 76,155,253, 3, 18,146,146,177,124,254,103, 89,133,213, 48, 87,229,177,110, + 66,205, 63,170,119, 68,241,148, 36,115,146, 42,175,111, 63,223, 44, 72, 57,112,148,226,192,181,204,210,102, 65,174,184, 71,229, +237,199,202,106, 53,225,221,139,213,111,209,235,243,156, 99, 30, 45, 42, 0, 0, 62,159, 95,186,149,244,149, 50, 24, 12,166, 23, +105, 22,124,190, 67, 59,199,113,112,114,114,130, 84, 42,173,118,211,163,220, 59,108, 68,243,142, 3,126,238, 50,112, 12, 78,238, + 89, 67,111,156,219,255,129, 46, 59,118,117,181,251, 32, 20, 20, 68, 19, 66,226, 23, 45, 90,212,120,237,218,181,181,166, 78,157, +154,176,233,231, 89,203, 1, 32, 47, 47, 15, 0,112,251,246,109,250,193, 7, 31, 24, 13, 6,195,147,130,130,130, 91,148,210, 42, +155, 14,244, 57,178,239,214,174, 88, 16,153,250, 52, 99, 80, 72,100, 11,120,214,106, 1,159, 58, 45, 81,160, 49,227,250,163,116, + 36, 60, 60,133,135, 23,118, 30,214, 41,172,179,170,155,230, 70,141, 26, 5,242,120,188,154,133,133,133, 62, 17, 17, 17,141,228, +114,249,237, 70,141, 26, 53, 17, 8, 4,105, 55,111,222, 76,170,142, 86,210,217,245,198, 26, 29, 71, 47, 75,214, 56,118, 74,200, +212, 53, 73,214, 56,222,214, 73,156, 39,103,159, 90,106,244,238,190,232, 71,106,206,141,222,177, 65,189,107,235,234,197,252, 81, + 99,167,216,162, 84,174, 19, 5, 82,241,137,249,239, 52,168, 70,243, 19, 47, 99,194,219, 3,254, 51, 77, 67,113,228,170,248,119, +187,194,241, 74,229, 93, 21,128, 47,164,126,245,127,142,154, 56,110,110,195,230,109,222,108,223,107, 56,207, 42, 82,224,216,158, +149,244,201,189,211, 59, 4,212, 54, 93,103,199,236,253, 85, 54,251,152, 76, 85,154,171,114, 35, 47,169,242,142, 59,126,255,237, +157, 93,123,118,207, 31,216,127,128,251,138,111,134,225,135, 85,123, 33,151, 74, 64, 57, 14,195, 59, 7, 13,121,248,123,143,126, +129,222, 14,254,187,206,164,157,255,104, 73,212, 23, 58,157, 57,174,170, 81,174,197,134,249,130,163,163, 99, 78,219,182,109, 91, + 73, 36, 18,146,155,155, 43,240,242,242,178, 58, 59, 59,155,210,210,210,116, 70,163,113, 23,165, 84, 91,157,124,154, 45, 28, 18, +179, 12,216,183,123, 23,238, 94, 59,133,135, 15, 99, 53, 15, 31, 60,252,137, 8,232,146,194,204,184,252, 23, 57,119, 92,185,163, + 8,105,181, 71, 17,106,249,210,239,110, 31,252,161, 99,104,231, 79, 90,187,215,110, 3,215,224,162, 49, 58,170,180, 40,164,222, +216,177, 79,147, 46, 26, 74,105,148,229, 69,175,177, 95, 64,173, 80,202, 23,227,242,217, 67,160, 28,247, 43, 0, 80,142,251,245, +246,197,195,227, 91,246,126, 31,110, 94, 53, 26,149,140,157,175,174,182, 72,192,211, 30,217,181,126, 79, 98, 98, 34, 98, 98, 98, +240,232,209, 35,228,231,231, 99,235,214,196,106, 93, 31,109,126,226, 9,133,123, 72,143,215,135,189,113, 96,200,136,183, 28,106, +133, 54,224,133, 5,184,194, 93, 33, 64,236,163, 36,196,221,188,199,197, 94, 63,108, 48,171,179, 7,234,242, 19, 43, 52,124,114, +207, 8,111,194,163,211, 74,214, 22,108,221,186, 77,216,103,243,230,183,114,247,244, 42,247, 57,158,151,147, 45,254,252,163,253, + 97, 87,174, 94,182,107, 45, 66,206,102,203, 27,251,206,112,142, 95,180,144, 39, 74,227,210,164,232, 98, 23, 85,162,138, 62,167, +156,181,202,136,253,232, 65,237, 96,229, 56,104,245,102,168,181, 70,168, 52, 6,100,100,231,225,238,189,123, 56,119, 96, 63, 30, +199,222,125, 98, 49,153,142,243,120,100,167, 46, 51,246, 92,245, 90,150, 4,181,220,221,220,240, 36,191, 16, 14, 98, 1,146,226, +110, 26,181,106,213,150, 23, 45, 71,186,220,184, 12,185,119, 88,247,225,195, 71, 28,237,220,163,191,115,243,215,186,202, 60,156, + 92, 32, 18, 80,196, 39,166,227,214,165,163,218,132,187,231,213, 22, 83, 97,207,151,177, 74,203,255,172,193, 82,107,114, 58,189, +247,238,184, 99, 60, 1, 95, 2,202, 25,116,186,130,158,127,197, 92,253, 93, 80,106, 75,123,103,228,160,103,234, 2, 86,142, 74, + 71, 14, 61,166, 47, 91, 55,176,216,168,108,228,208, 75,186,162, 7, 71,197, 29,246, 74,155,240,118, 92, 77, 75, 78, 85,222,200, +207, 55,158,249,171, 35,251,202,174, 45, 88,201,104, 65,109,120,120,120,169,169,226,243,249,176,217,108,118, 63,128, 68, 18,233, +152,206,253,223, 35, 39,247,174,161,215,207,238,157,160,203,142, 91,245,226,231,148,154, 1, 92, 35,132, 68, 77,159, 62,189,185, +183,183,183,247,140, 25, 51, 28,212,106,181,112,197,138, 21,134,220,220,220, 76,181, 90,125,133, 82,170,183, 95,243,150, 5,192, + 96,133,119,221, 78,116,215,154,110, 46, 30,254,221,157, 61, 3,106, 43,115,158, 62, 81,229,164, 31, 7,112,178,120,130,199,106, +209,164, 73,147, 16, 30,143, 55, 28, 64,164, 92, 46,175,163, 80, 40, 36,148,210,112, 66, 72, 52,199,113,247, 34, 34, 34, 14, 2, +168,214,245, 75, 58,187,222,216,126,194,111,191,231,235, 56,145,137, 39,250, 61,233,236,122, 35, 0,100, 29,159,170, 3,176,207, +187,211,180,193,251,175, 36, 45,143, 46,112,254, 36,251,204,119,251,171,155,102,101,234,157, 58, 47,171,252,235,211,163,211, 0, +188, 35,247, 14, 91,124,255,246,149,153,132, 66,104,131,245, 91, 93, 86,252,205,151,161, 47, 20, 10, 13,254,254,254,229,142, 22, +148, 72, 36,134,202,175,249, 89, 43,128,181,132,116,220,176,123,251,134,119,246,238,223, 55,191,125,151,129,238, 14, 1, 1,168, +233, 69,176, 97, 90,211, 79, 78,221,206,185,222,255,179,243,191, 36,164, 27,238, 81, 74,171,213,223, 69,163,209,196, 17, 66, 10, + 10, 11, 11, 7, 80, 74, 83, 9, 33,129, 5, 5, 5,119, 44, 22,203,253,106, 27, 1, 14,111,180,110,221, 98, 43, 33, 68, 64,173, +220,194, 43, 66,254,239,134,140,135,105, 47, 98, 40,202,210,160,166, 19, 38,205, 88,214,180,118,157,186, 77, 75,214, 34,172, 95, +195, 17,227,190, 88,220,180, 70,173,208,166,255, 89,159,176,242, 81,132, 52,253,150,158,120, 55,232, 22,123,124,209, 55,238,143, + 47, 77,144,186, 5, 40,180,185, 73,249, 5, 73, 55, 23,233,178,189, 23,189,200,196,146,101, 73,124, 20,189,100,237,162, 47,166, +102, 60,125,178, 86,155, 29, 23, 5, 0,218,236,184, 40,153,119,221,111,114, 51,211,166,230,101, 39, 44,122,209,115,161,213,106, +211,183,108,217,226,210,166, 77, 27,158,183,183, 55,114,114,114,112,230,204, 25,142,227,184,167,213,213, 42,204, 75, 56, 67, 72, +109,183,141,171,126, 94, 40,146, 59,246,182, 90,173,126,148, 2, 2,129, 32,195,164, 83, 31,213,240,228,159,209,252,196, 42,202, + 37, 71, 0,240, 74,214, 22,228, 56,142, 44, 92,190, 33, 73,232,224, 88,110,147,170,197,160,145,113, 28,103,247, 90,132, 5,201, + 55,107,191,172,251,155, 80, 58,187, 81,179, 86, 95, 89, 44,102, 3,138,250,131, 25, 0, 24, 40, 69, 30,143, 71,206,241, 57,203, + 49,213, 95,168, 68, 17, 2, 39, 74, 4,112,148, 10, 64, 64, 80,168,202,167,213,233,115, 85,238,245,206,138,141, 38,164, 99,240, + 17,211,246,183, 79,159, 56, 60,212,102,179,213, 44, 46, 57,137, 70,189,118, 71, 97,134,235, 70, 74,111, 88,241, 47, 64, 80,113, + 72, 52, 62, 14, 64,240, 63, 61, 3,121, 79,174, 55,123,153,122, 25,217,170, 13, 61,134, 45,166,137, 73, 5,215, 83, 50,141, 27, +203, 46,127,243, 87, 53, 83, 83,149,103,138,155, 5,141,127,142, 72,188,216,104,193,210,218,183, 65,255,253,210,233, 35, 96,208, +107, 55,233,178,227, 54,188, 28,243, 74,245, 0,206, 17, 66,156, 39, 76,152,208, 68,161, 80, 8,115,115,115,175, 81, 74, 85, 47, +170, 89,152, 21,119, 6,192, 25, 0,211, 94, 70, 26,111,223,190,157,208,184,113,227,205, 60, 30,175, 38,165,212,155, 82,234, 92, +108, 96,115, 5, 2,193,211, 7, 15, 30, 60,125,161,188, 27, 29,143, 20,154,248,161, 86,234,122,244, 79,166,195,221,235, 68,114, +190,109, 13, 95,238,240,143,233, 67,160,205,138,141, 6,240,250,203,214,173,108,158, 43,251,203,209,127,140,214,217, 67,235,223, +225,137,157,191,237, 18,102,208,117,255,244,233,220, 11,247,115,174, 81, 74, 53,127,161,140,230,136,197, 98, 61, 33, 36, 80, 36, + 18,233, 77, 38,211,189, 23, 58,127, 69,230,222,243,101,158, 59, 14,228,102,211,166,205,170,181,127,165,121,205,186,175, 3, 48, +141, 68, 68,204,144, 61,190,225,170,203,245,200,163, 52,246,165,188,168, 10, 51, 99,230,162,184,153,251,153,136, 68, 86,220,183, + 0,190,253, 43,218, 55,110,220, 56,176,104,209, 34,213,242,229,203,131,108, 54,155,204,100, 50,233,244,122,125, 98, 90, 90,218, +229, 23,187,230,143, 77, 0, 38, 22,111, 47, 16,101,137,201, 84,120,215, 93,246, 90,235,215, 38, 22, 85,204,233,178,196,115,203, + 38, 85,118,140,194,187,174,190,236,254,149,173, 69,248, 50, 41,204,142,251, 21,192,175,127, 95,132,130,203,121, 99,200, 0,160, +120, 66,109,206,106,205,121, 41,178, 69,247,252,111,120,129,197,203, 95, 41,104,241,242, 8,127,199, 6,160, 43,211,100,154, 76, +147,105,150,179, 47,143,157, 79,166,249,223,212,116,240,173, 23,232,224, 91, 47,208,222,227,203,219,159,157, 79, 10,182, 85,188, + 9,192, 96, 48, 24,255,255, 21, 59,142,157, 5,198,127, 19,125,250,131,212,191,115,127, 6,131,160,104, 85,234,242, 30,128,118, + 55,127, 16, 66,186,190,192, 3,246, 36,211,100,154, 76,147,105, 50, 77,166,201, 52,255, 93,154, 85,105, 87,199,127,252,211,107, +146,172,137,144,105, 50, 77,166,201, 52,153, 38,211,100,154,172,137,240, 37,110, 60, 48, 24, 12, 6,131,193, 96, 48, 94, 42,204, + 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131, +193, 96, 48, 24,140, 23,135, 80, 74, 81,188,196, 20, 1,240,204,239, 12, 6,131,193, 96, 48, 24,255, 47,134,228, 21,243, 34,165, + 6, 11, 0, 40,165,132, 25, 44, 6,131,193, 96, 48, 24,255, 13,131,245, 42,121,145,103, 34, 88,101, 51,199, 46, 53,131,193, 96, + 48, 24,140,255, 79,131,245, 42,121, 17,214, 68,200, 96, 48, 24, 12, 6,227, 31, 99,176, 94, 21, 47,194, 58,185, 51, 24, 12, 6, +131,193, 96,188,108,195, 88, 60,229, 61,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6, +131,193, 96, 48,254, 21,252,173,125,176, 8, 33, 93,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,153,193, 98, 48, 24, 12, + 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24, + 12,102,176, 24, 12, 6,131,193, 96, 48,254, 75, 16, 0,229,142, 4,160,148,158,180, 91,228, 5, 70, 19, 84,165,207, 52,153, 38, +211,100,154, 76,147,105, 50,205, 87, 79,179, 42,237,234,248,143,127, 52,148,210,191,109, 3,208,149,105, 50, 77,166,201, 52,153, + 38,211,100,154, 76,243,223,182,177, 38, 66, 6,131,193, 96, 48, 24,140,151, 12, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, + 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,227,197, 33,197,163, 1, 64, + 8,161,148, 82,194, 78, 9,131,193, 96, 48, 24,140,255,138, 41,121,133,188, 8,161,148,150,102,136,153, 44, 6,131,193, 96, 48, + 24,255, 77,115,245,170,120, 17,214, 68,200, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12,198, 63, 27,214, 7,139, +193, 96, 48, 24, 12,198, 63,195,148,188,106,125,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131, +197, 96, 48, 24, 12, 6,131,241,111,225,111,237,228, 78, 8,233,202, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 12, 22, +131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, + 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,241, 95,130, 0, 40,119, 36, 0,165,244,164,221, 34, 47, 48,154,160, 42,125, +166,201, 52,153, 38,211,100,154, 76,147,105,190,122,154, 85,105, 87,199,127,252,163,161,148,254,109, 27,128,174, 76,147,105, 50, + 77,166,201, 52,153, 38,211,100,154,255,182,141, 53, 17, 50, 24, 12, 6,131,193, 96,188,100,152,193, 98, 48, 24, 12, 6,131,193, + 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48, 24, 47, 14,161, +148,130, 16, 66,139,255,238, 72, 41, 61,199, 78, 11,131,193, 96, 48, 24,140,255, 87, 67,242,138,121,145, 82,131, 69, 41, 37, 37, + 63,217,101,102, 48, 24, 12, 6,131,241,255,109,176, 94, 37, 47,194,123,206, 57,118,100,151,152,193, 96, 48, 24, 12,198,127,203, +100,189, 42, 94,228,153, 8, 22,187,180, 12, 6,131,193, 96, 48,254, 91,230,234, 85,242, 34,204, 96, 49, 24, 12, 6,131,193, 96, + 6,235,239, 48, 88, 12, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193,248, +183,240,183, 78, 52, 74, 8,233,202, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 12, 22,131,193, 96, 48, 24, 12, 6,131, + 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 48,131,197, 96, + 48, 24, 12, 6,131,241, 95,130, 0, 40,119, 36, 0,165,244,164,221, 34, 47, 48,154,160, 42,125,166,201, 52,153, 38,211,100,154, + 76,147,105,190,122,154, 85,105, 87,199,127,252,163,161,148,254,109, 27,128,174, 76,147,105, 50, 77,166,201, 52,153, 38,211,100, +154,255,182,141, 53, 17, 50, 24, 12, 6,131,193, 96,188,100,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, + 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48, 24, 47, 14, 41, 30, 13, 0, 66, 8,165,148, 18, +118, 74, 24, 12, 6,131,193, 96,252, 87, 76,201, 43,228, 69, 8,165,180, 52, 67,204,100, 49, 24, 12, 6,131,193,248,111,154,171, + 87,197,139,176, 38, 66, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,254,217,176, 62, 88, 12, 6,131,193, 96, + 48,254, 25,166,228, 85,235,131,245, 42,102,140,193, 96, 48, 24, 12, 6, 51, 89,255, 8,131,197, 96, 48, 24, 12, 6,131,193, 96, + 6,139,193, 96, 48, 24, 12, 6,227, 31,199,223,218,201,157, 16,210,149,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,147, 25, + 44, 6,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, + 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227,191, 4, 1, 80,238, 72, 0, 74,233, 73,187, 69, 94, 96, 52, 65, 85, +250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,245, 52,171,210,174,142,255,248, 71, 67, 41,253,219, 54, 0, 93,153, 38,211, +100,154, 76,147,105, 50, 77,166,201, 52,255,109, 27,107, 34,100, 48, 24, 12, 6,131,193,120,201, 8,202,251, 80,216,114, 94,150, +213,106,245, 2, 0,129, 64,144,109,185,254,181,111,101, 34, 66,160,139, 21, 88, 83, 44, 56,198, 66,233,137,114, 52, 79, 88,173, + 86,215, 98,205, 2,203,245,175,123, 84,170,217,226,219, 99,207,236,127,109,122,183,114,226,139,124, 97,139,111,211,159, 75,171, + 95, 53,194,119,182,255,143,116,254,175,104,254,155, 17,181,154,151,101,177, 20,149, 35,161, 80,144,109,190, 86,121, 57, 18,181, +252, 54,253,153,253,175, 78,247,174, 76, 83, 38,149,228,213,246,247,252,177, 50,205,132,244,220,201, 90,157,193,189, 50,205,234, +222,155,129,190,190, 93,108,197,247, 38, 31, 24,147,154,158,126,226,159, 84,150, 8, 33,205, 0,124, 13,192,169,204,199,247, 40, +165,159,178, 82,201, 96, 48, 94, 57,131,101,181, 90,189,110,237,153, 9,173, 17,232,242,214,183, 94, 33, 3, 87,109,253,211, 62, +134, 2,177, 50,122, 91, 3,190, 69,237,234, 41, 48, 59,165,167,167,147,226, 7,230, 26, 0, 65,229,104,186,222,218, 51, 19, 58, + 19,208,126,196,108,215, 32,192, 41, 71, 36,154, 34,149,203, 59,233,245,250,250, 0, 32,149, 74,163,245, 90,237, 25, 79,179,121, +241,243,251, 87,148,129,178,105,237,252,230,183, 94,225, 3, 87,125, 98,227, 56,241,211, 27, 43,219, 27,114,227, 5, 66,171,113, +197, 87,192,145,153,128,205,158, 19,242,204,247, 14,253,210, 93, 8,116, 22, 59, 56, 52,114,113,117,109,199, 81, 90,143,227, 56, + 98,179, 90, 31,168, 85,170, 11,156,213,122,215,106,210,186,223,218, 63,159,171, 44,157,207,231,101, 40, 32,216, 3, 12,145, 43, + 20,157,248, 66,225,107, 0, 96,179, 88, 46,107, 11, 11,207, 12, 2,118,218,147,119,123,207,207,139,238,255,111,195, 98,177,122, + 61, 57, 54, 19, 70, 11,208,228,245,249, 94, 13,223,216,184, 21, 0, 76,217,119,189, 11,227,247,183, 4, 0,121,237,190,215, 36, + 62, 77,178, 0, 64,144,156,225, 21,119,112, 58,140, 22,160, 94,223,217, 94, 85,105,142,158,177,221,253,243,177,131, 37, 0,112, +124,215,207,117, 79,239,254,181, 23, 0,116, 30,252,193,145,238,175,127, 20, 7, 0, 11, 87,239,118,255, 99,254,176, 74, 53,237, +187, 55, 85, 34, 85,252,193, 58, 38,117,134, 75,160, 92,224, 19, 31, 31,207, 3, 0, 63, 63, 63,187,238,205, 0,192, 57, 3,248, +144,199,231,183,171, 93,167, 78, 19, 0, 52,225,241,227,219, 54,171,245,162, 47,176,226, 37,151,165, 79, 40,165,253,158, 51, 93, +172, 64, 50, 24,140, 87,211, 96, 1,128,214, 8,156,123, 4,116,104,213, 16, 99,223,232,173, 40,251,191,157,171,102, 7,197,223, +216, 23,254,219,198,197,188,134, 13, 27,226,201,147, 39,118,125,153,206, 4,156,141, 7,160,124,232, 88, 32,151, 63, 94,242,195, + 15, 78,221,186,117, 19,248,249,249,129, 16,130,204,204,204, 86, 39, 79,158,108, 54,105,210,164,241, 80, 62, 44,208,153,160, 57, + 27, 95,181,110, 73, 90,235,215,173,129,175, 63, 26,230, 12, 0, 95,189,181,162,217,141,216, 44,183,199,143, 31,119,249,226,139, + 47,242,248,103,206,252,234, 1,172,207, 2, 82,237, 73,231,166, 3,215, 28,156, 51,126, 15, 25,245,209, 71,187,234,212,169,163, + 8, 14, 14, 38,142,142,142,224,243,249, 40, 40, 40, 8,138,138,138,234,117,253,250,117,237,201,115,107,196, 55,175,247, 79,200, +118,104,105,176, 43,239,250,116,135,227,142,142,209,111, 14, 26, 20, 48,108,216, 48,135,218,181,107, 3, 0, 30, 63,126, 28,186, +115,231,206, 17,187,118,237,154, 1,125,186, 85,103,130,161,170,188,151,106, 2,112, 0, 94,115,241,242, 26,197, 23, 10,235, 91, +173, 86,255,226,232,194, 83,155,197, 18,173,204,206,222,242,252,254,140, 63, 99,180, 0, 15, 51,128,174,237,154,224,205,193, 93, +229, 0,240,197,240,121,173,146, 19, 31,137, 76, 38, 19,234,134,213,107, 51,119,254,143,199,192,227, 97,243,238,147,165,251,219, +163,121,239,225, 19,204,156,187, 4,233,247,119,182,178,169, 30,117,210,168, 85,124, 0,112,114,118, 30,188,115,219,239,103,252, + 26, 12,185,250, 40,215,108,151,102,101,247,230,209,109, 63,249,166, 69,157,137,248,229,248, 58, 97, 80, 80, 16,238,223,191, 95, +189,123, 83, 21,235,200,249,250, 62, 88,252,217,103, 62,237,219,183,135, 66,161,128, 64, 32,128,213,106,237,122,241,226,197,174, + 51,103,206,252, 0,170, 88,173,189,247,166, 29, 44, 38,132,116, 26, 61,246, 19,223,222, 3,134, 96,112,207, 54,172, 32, 50, 24, +140, 87,215, 96, 9, 4,130,236,110,111,127,231,213,174,101, 36,110,220,141, 83, 37,165,100, 20,150,252, 47, 63,122,103,221, 1, +109,252, 35,206,159, 63, 7,163,209,136,203,151, 47,227,238,221,187, 72, 76, 76,196,184,113,227,140, 2, 96, 76, 5,154, 5,237, + 71,204,118,133, 42, 94, 17, 42,142,173,121, 50, 38,134,111, 48, 24,112,254,252,121, 20, 20, 20, 64, 44, 22, 35, 32, 32, 0,221, +187,119, 23,196,196,196,184,117,233,214,211,185,125,207,145, 79,224, 28, 90, 40, 16, 8, 10, 42,204,128, 64,144,221,229,173,111, +189, 34, 66,107,224,113, 82,186,234,235,249,191, 21,114, 28, 21, 36, 36, 38,155,207,157, 59,135, 38, 77,154,224,196,137, 19,238, +249,249,249,223,172, 88,177,226,107,225,247,191, 44,179,152,242,166, 86,162, 87,208,126,196,108, 87,247,236, 29,193,167,143,238, + 21, 69, 71, 71,139, 86,174, 92,137,188,188, 60,136,197, 98,184,184,184,192,199,199, 7,117,235,214, 37, 95,125,245,149,162,111, +223,104,124, 60,102, 72,176, 57,228,253,216,138,210, 89,154,247,194,100,153,135,250,120,237,221,135, 14,241,218,182,109,251, 76, + 53,189, 86,173, 90,232,209,163,135,195,168, 81,163,106, 15, 27,241, 6,215,190,207,232,199, 80, 4,235,170,212,212,166, 74,221, +117, 87,252,186,142, 24,177,127,246,236,217, 46, 62, 62, 62,144,203,229, 0, 0,149, 74, 21,144,148,148,212,106,198,140, 25,175, + 95,187,183, 77,208,190,111,106, 58,228,129,250,202,206,231,191, 21,161, 80,144, 93, 18, 53,114,148, 75, 11, 82,211,178,180, 0, + 96, 50,153, 96, 50,153, 96, 52, 26, 49,225,131,113,252, 49,175,183,168, 19,220,238,147, 59,137, 79,179,242,235,157,188,234, 86, +114,108, 85,154, 2, 93,162, 82,153,114,106,204,204,207, 62,243,241,246,254, 79,203,223,230, 77,155,248,249,249,249, 93,103,206, +156, 25, 65,101, 29,149,245,250,206,118,169, 76,179,178,123, 83, 25,119,168,230,220,143,122, 52, 90, 53,255, 32,108, 54, 27,174, + 92,185,130,243,231,207,227,199, 31,127,164, 71,142, 28, 81, 57,201,229, 85,220,155,177,142,109,125, 51, 67,190,255,126, 23,145, + 72, 36,216,183,111, 31, 98, 98, 98,192,227,241,208,176, 97, 67,188,249,230,155,232,218,181,171,207,216,177,227,104,251,158,195, + 19,224, 28,166,249, 43,101,137, 16,194, 3,240,201,151, 51,191,247,125,235,253, 15,177,112,238, 87,204, 96, 49, 24,140, 87,135, +226,209, 0,180,120,235, 64, 41, 5, 5,120,181, 6,174,250, 99,199, 77,238, 80,173,129,171,254,160, 0,143, 2, 60, 39,160, 70, +227,198,141, 45, 74,165,146, 94,191,126,157, 78,152, 48, 65,187,108,217,178, 51,135, 14, 29,218,105, 53,155,215,250,249,250, 46, +162, 0,175,220, 30,245, 0, 47, 24,112,150,201,100, 57, 41, 41, 41,244,240,225,195,116,214,172, 89,116,203,150, 45,244,200,145, + 35,244,228,201,147,244,200,145, 35,244,143, 63,254,160,247,238,221,163,113,113,113, 84, 46,151,231, 4, 3,206,149,104,242, 41, +192,175, 59,112,229,212, 93, 55, 44,179,195, 6,174,154, 68, 1,190, 43, 16,222,184,113, 99,219,206,157, 59,233,230,205,155,233, +198,141, 27,233,189,123,247,104,110,110, 46, 21, 72,228, 57, 37,199, 85,148, 78, 10,240,252,253,253,115,148, 74, 37, 13, 12, 12, +164, 98,177,152,122,123,123,211,186,117,235,210, 86,173, 90,209, 94,189,122,209, 55,222,120,131,126,243,205, 55, 84,169, 84, 82, + 7, 7,135,172,146,227, 42,210,108, 2, 72,229,114,121,202,173, 91,183,104, 69,232,245,122,154,155,155, 75,143, 29, 59, 70,229, +114,121, 74, 19, 64, 90,153,166, 20,104,218,160, 65,131,156,220,220, 92,106, 54,155,105, 74, 74, 10,141,138,138,162, 49, 49, 49, + 52, 37, 37,133,234,245,250, 82,237,184,184, 56, 26, 18, 18,146, 35, 5,154, 86,168,249,111,222, 74,202,196,115, 91,144,183,119, + 47, 31, 31, 31,253,174, 93,187,232,211,167, 79,233,134, 13, 27, 40, 15,152,247,167,125, 43,209, 20, 3,221,219,182,109,107,187, +114,229, 10,189,115,231, 14,157, 54,109, 26,237,209,163, 7,237,217,179, 39,157, 57,115, 38, 77, 75, 75,163,105,105,105,180, 87, +175, 94, 54, 49,208,189,170,242, 89,222,189,233, 12, 4,245,237,219, 87,111, 54,155,105, 66, 66, 2,173, 95,191,126, 26, 31, 24, + 37, 7, 34, 58, 0,146,170,202,167, 63,224,234,235,235,155,113,229,202, 21,186,123,247,110, 26, 28, 28,156,195, 7, 70, 59, 1, +181,156,128, 90,124, 96,116,173, 90,181,114,174, 92,185, 66,243,242,242,104, 80, 80, 80,134, 63,224,250,162,101, 9, 69,115,240, +173,251,114,230,247, 52, 54, 77, 75,191,156,249, 61, 5,144, 66,139,254,121,130,149, 73,182,177,237,223,183,253,201,139,252,143, +111,130, 50, 70,139, 16, 66, 40,138,230,198, 42, 23, 61,159,255,221,194,133, 11, 5, 6,131, 1,191,253,246,155,102,228,240,225, +187, 93, 92, 92,172, 66,161, 16,132, 87,245,128,196, 28,137,100,226, 15, 11, 23,186,152, 76, 38,220,188,121, 19,205,154, 53,131, + 68, 34,129, 72, 36,130, 80, 40,132, 80, 40,132,175,175, 47,178,179,179, 81,191,126,125,124,254,249,231,206, 11,190,251,110, 34, +140,198,185,149,233,114, 28, 21, 0,128,141,227,196, 34, 96,108,163,230,205, 23,125,245,213, 87, 60, 39, 39, 39, 24, 12, 6, 24, +141, 70,196,196,196,192,221,221, 29, 50,169, 76, 0,163,182,202,180,242,120, 60,158, 66,161,192,233,211,167,177,122,245,106, 36, + 38, 38, 34, 35, 35, 3,142,142,142,168, 95,191, 62,234,213,171,135, 14, 29, 58, 32, 33, 33, 1,196,142, 78, 35, 15, 4,130, 15, + 39,140, 25,227,213,164, 73,147,114,255,111, 48, 24,160, 84, 42,161, 82,169, 16, 16, 16,128, 33, 67,134,120,253,190,121,243,135, +176, 90, 23,151,183,191, 59,224, 19, 16, 26,186,255,250,245,235, 30,148, 82,108,222,188, 25,133,133,133, 48,153, 76,224,241,120, +112,112,112,128,171,171, 43, 58,119,238, 12, 79, 79, 79,132,134,134, 98,251,246,237, 30,189,122,245, 58,232,158,157,221, 52, 15, + 72,103,213,139,170, 73,206,202, 58,222, 29,240, 24,245,198, 27, 71,238,222,187,215,110,212,168, 81,200,202,202,250, 74, 56,109, +154,210, 2, 44,169,234,248, 48,192,217,205,215,119,253,247,223,127,207,203,204,204,196,148, 41, 83,114,211,147,147,167, 57, 3, + 23, 0,224,212,209,163,237,182,108,217,178, 96,243,230,205, 30,155, 54,109,226, 53,105,210,100,125, 88, 74, 74,253, 88, 64, 85, +157,116,106,128, 79,150, 46, 93,234, 96, 48, 24,208,173, 91,183, 4,135,196,196, 70, 86, 64,111,239,241, 25,192,135, 63,126,254, +185,143, 68, 34,193,148, 41, 83,114,117,201,201,145, 86, 32,167,204, 46, 73,158, 79,158, 28,125,235,173,183,162,238,221,187,231, +177,100,201, 18,159,215, 7, 13,250, 16,192,188,106, 68,172,202,118,104, 15, 29, 61,246, 19,239, 38, 45, 90, 99,211,218, 21,152, + 63,251,139,245, 0, 86, 17, 66, 62, 2,240, 3, 43,121, 12,198,191, 54,232, 83,165, 23,249,159,107, 34, 44,206, 80,199,202,118, +118,117,119,111, 22, 25, 25,137,243,231,207,163, 65,131, 6,215, 93, 92, 92,172, 34,137, 4, 66,161, 16,148,227,170,252, 50,169, + 92,222,165,107,215,174,130,171, 87,175, 34, 36, 36, 4, 82,169,180,212, 88,149,108, 34,145, 8,190,190,190, 80,171,213,232,210, +165,139,112,249,242,229, 93,170, 50, 88, 0,144, 28, 31,165,200,185,250,253, 27,107, 54,172,175,213,190,125,123,168, 84,106,112, + 28, 7,153, 76, 6,147,201, 4,129, 64, 80,212,212, 99,161,106,123, 78,140,205,102,179,241,249,124,132,132,132,224,187,239,190, +131,193, 96,128, 72, 36, 2, 0,168,213,106, 40,149, 74, 68, 69, 69, 33, 41, 41, 9,197,181,238, 74,113,116,118,238, 61,108,216, + 48,113,121,255, 51, 26,141, 80,169, 84, 80,169, 84, 80, 42,149, 48, 24, 12,104,221,186,181,248,208,193,131,189,145,151, 87,174, +193, 50, 58, 56,188,190,105,211, 38, 47,177, 88, 12,189, 94, 15,141, 70,131,212,212, 84, 36, 39, 39, 27,178,179,179,173,142,142, +142,188,224,224, 96,158, 68, 34,145, 12, 28, 56,144,168,213,106, 16, 66,208,183,111, 95,247,173,155, 55, 15, 3,240, 35,187,149, +237,227, 56, 96,108,106, 50,245,107,217,162,197,233,235, 55,110, 52,153, 56,113, 34,238,221,187,247,189,108,219,182,115, 58,224, +110,101,199, 38, 0, 31, 46, 42, 99, 92,104,114,114, 3,243,115,198, 37,184,200,184,220, 47, 49, 46, 67,171,105, 92,138,203, 87, +115, 95, 95, 95, 28, 57,114, 4, 41,137,137, 95, 84,199, 92, 1, 0,143,207,111,219,190,125,123,236,219,183, 15,105,201,201, 95, + 60,103,174,138, 42, 72, 64,142, 32, 33,225,139,245,235,215,175,123,247,221,119,193, 23, 8,218,194,106,173,206,215,252,169, 67, +251,187,227, 38, 98,253,234,229,235, 1,188, 79, 41,229, 0, 92,103, 37,142,193,248,247, 98,143, 23,249, 95,129, 87,214, 53, 2, + 56, 91,217,206, 94, 94, 94,254, 10,133, 2,233,233,233,168, 23, 30,158, 45,145, 72, 32, 22, 10,225, 32, 22,219,245,101, 58,157, +174,129,159,159, 31, 84, 42, 21, 60, 60, 60, 32, 18,137, 74, 55,177, 88, 92,250,187,163,163, 35,120, 60, 30,130,130,130,160,211, +233, 26, 84,169,155, 21,229,181,109,249, 7, 19,174,156, 59, 82,107,208,160,193,112,117,117, 67, 96, 96, 0,188,188,188, 32,149, + 74, 17, 24, 24,136,218,181,107,211,197,139, 23, 67,230,213,208,174, 7,120, 89,211, 36, 16, 8, 96,179,217,144,149,149,133,216, +216, 88,220,187,119, 15, 87,174, 92,193,157, 59,119,160,209,104, 96,135,191,130, 78,175,111, 36, 16, 8,202, 53, 87, 74,165,178, + 52,122,165, 84, 42,145,147,147,131,164,164, 36, 20,106,181,141, 43, 49,187,131, 35, 35, 35,249, 0, 32,149, 74,209,184,113, 99, +172, 90,181,202,122, 96,239,222,225, 17, 87,174,184, 5, 30, 59,230,178,102,229,202,225, 67,134, 12,177, 93,189,122, 21,106,181, + 26, 15, 31, 62,132,167,167,167, 64,236,224, 48,140,221,198,213,227, 22,160,245,208,104,122,190,246,218,107, 79, 84, 42, 21,126, +248,225, 7,158,208,209,113,245,108,128, 95,233,129,124,126,155,246,237,219, 99,255,254,253, 72, 79, 78,158,150, 92,142,113, 73, + 6,114, 82, 18, 18,166,173, 95,191, 30,221,187,119, 7, 17, 8,170,221, 17,169, 85,171, 86,145, 28,199,225,254,253,251,112, 1, +174, 85,247,248,218,117,234, 52, 81, 40, 20,136,137,137,129,188, 56,186, 86, 30,114,224,194,237,219,183, 33,149, 74, 81, 47, 34, +162,105, 53,191,102, 49, 33, 36,227,221,113, 19,177,251,232, 37, 0,192,250,213,203,179,202,152, 43, 6,131,193, 34, 88, 85,122, +145,255, 57,131,101,103,198, 1, 0, 66,161, 16, 98,137, 4, 98,177,184,200, 24, 73, 36,213,113,167,112,112,112, 40, 53, 84,101, +141, 85,217,223,101, 50,153, 93,198, 5, 0, 10, 30, 29,109,247,254,123,239,138, 37, 18, 9, 76, 38, 35, 40,165,144, 72, 28,224, +226,226,130,144,144, 16,168,213,106,188,214,166,131, 49, 85, 41, 58,232, 94,111,224,189, 23, 57, 81, 86,171, 21, 90,173, 22, 5, + 5, 5,200,207,207,135, 90,173,134, 94,175,183,123, 72, 57,199,113,252,212,212, 84,252,254,251,239,200,203,203, 3, 80,212,129, +186,196, 84,149,252,124,242,228, 9, 54,111,222,140,196,196,196,106, 93,159,118,237,218,225,224,193,131,252,142, 93,186,172, 61, + 17, 28,156,126, 34, 56, 56,189, 99,151, 46,107,247,239,223,207,247,247,247, 71, 82, 82, 18,110,222,188,137,130,130,130,146, 2, +204,168, 38,143,129, 2, 93,126,254,187, 95,125,245, 21, 85, 40, 20,248, 97,209,162, 70,243,128,145,246, 26, 23,231, 74,140,139, +243, 95, 51, 46,160,148,130,227, 56,216,108,182, 23,202, 27, 33,132, 8,133,194,234, 78,145, 64,170,161, 95,218,161,253,243,111, +190,195,225,125, 59, 75,254, 21,207,204, 21,131,193,120, 21, 17,148,113,140, 85,190,120,179,178,178,158,106,181,218, 90,193,193, +193, 72, 75, 75,243, 10, 10, 10, 74, 22, 11,133, 16,137,197,118,245,193,146,201,100,247,211,211,211,219,248,251,251,195,106,181, +150,154,169,231,155, 8, 75,162, 50,119,238,220,129, 76, 38,187, 15, 67,165, 51, 32,192,102, 42,168,209,180,105,211,210, 72,144, +139,139, 11, 92, 92,156, 33,145, 56, 96,250,244,233,220,146,197,139, 87, 4,117,158,173,122,103,210, 87,244,171,121,107, 95,234, + 9,180,247,133, 36,147,201,238, 7, 6, 6,182,118,118,118,198,238,221,187,145,148,148,132,130,130, 2,232,116, 58, 24,141, 70, +232,116, 58,152, 76, 38, 56, 56, 56, 32, 34, 34, 2, 78, 78, 78, 56,121,242,228,125, 24,141,229,155,202,188,188,221,247,239,223, +111,221,162, 69,139,210, 8, 74,167, 78,157, 72,167, 78,157, 60, 74,163,102, 58, 29,114,115,115,113,253,250,117,156, 60,121, 18, +132, 16,196,199,199,219,140,122,253, 31,172,232,191, 24, 6,224, 50,127,253,250,117,227,199,143,127,175, 77,155, 54,176, 1,189, + 0,108,254,111, 25,151, 18,174, 92,185, 18,101,179,217,218,212,173, 91, 23, 74,160, 37,128,125,213, 50,143,143, 30,221,182, 90, +173, 93, 26, 53,106,132,221, 59,118,180, 3,144, 84,222,126, 90,160, 93,147, 38, 77,160,215,235,241,240,193,131, 91,213, 48, 87, +107,191,156,249,253,232,183,222,255, 16,155,214,174,192,250,213,203, 83,215,173, 90, 22, 8,192,204, 74, 21,131,193,168,142, 23, +121, 37, 35, 88,170,130,130, 91,183,111,223, 70,211,166, 77,241,248,241,227, 22,148,227, 4, 34,177, 24, 98,145, 8, 60, 59, 94, + 32,122,173,246,212,169, 83,167,172,141, 27, 55, 70, 97, 97, 33, 4, 2,193, 51,209, 43,177, 88, 12,161, 80, 8,129, 64, 0,153, + 76,134, 61,123,246,152,245, 90,237,169, 42,163, 67, 54,206,198,227,241, 74, 95, 98, 74,165, 18, 58,157, 30,223,125,247, 29,126, + 90,188,248, 13, 27, 48, 73, 40,247,212,255, 55, 79,180, 65,167, 59,125,248,240, 97, 75,173, 90,181, 48,122,244,104, 76,154, 52, + 9,147, 38, 77,194,248,241,227, 49,122,244,104,188,249,230,155, 24, 52,104, 16, 90,182,108, 9, 79, 79, 79,196,198,198, 90, 12, + 58,221,233,138,244, 36, 6,195,174,183,223,126, 59,187,196,152,105,181, 90,104, 52, 26,168, 84, 42,228,228,228,224,210,165, 75, +216,180,105, 19, 22, 47, 94,140, 61,123,246,192,104, 52,194,108, 54,227,206,157, 59, 5,114,139,101, 7,187,149, 95, 28, 33,176, +251,226,197,139,112,115,115,131, 95, 64, 64, 7, 59,140, 11, 26, 53,106, 4, 21,208,174,194,123,235, 5,140,203, 51,198, 71,163, +185,241,228,201, 19,116,236,216, 17,190, 1, 1,223, 71, 0,210,234, 28,111,179, 90, 47, 92,188,120, 17,111,189,245, 22,130,107, +213,250,222, 19,240,124,126, 31, 79,192,179,102,237,218,223,143, 30, 61, 26,199,143, 31,135,205,106,189, 80,137,169,106, 70, 8, +217, 79, 8, 57, 7, 32,105,244,216, 79, 70, 63,215,161,125, 40, 33,100, 11,128,169,172, 68, 49, 24,140, 87,145,106, 25, 44,169, +205,246,229,212,169, 83, 45, 60, 30, 15,131, 7, 15,118,220,183,127,255,144, 59,119,239,134,100,103,103,187,216,108,182, 42,181, + 60,141,198,101, 83,167, 78, 85,154, 76, 38,132,133,133, 33, 63, 63, 31, 54,155, 13, 2,129, 0, 2,129, 0,132, 16,240,120, 60, + 40, 20, 10,220,190,125, 27,235,214,173, 83,123, 26,141,203,170,124, 57,216,108,247, 55,111,222, 12, 62,159, 79, 29, 28, 28, 64, + 8,129, 64, 32,192,146, 37, 75,178,127, 2,118, 3, 0,159,199, 51, 1, 0,143, 71,236,237,149, 91,101,251,164, 88, 44, 6, 87, +212,185,191,202,125, 93,141,198,165, 11, 23, 46,212, 60,124,248, 16, 90,173,182, 52,218, 86, 88, 88, 88,218,105, 94,169, 84,130, + 16, 2,173, 86,139,253,251,247,107, 92,141,198,165, 21,233,229, 1,153,105,241,241,253, 91,180,104,145,247,228,201, 19,168, 84, + 42,220,191,127, 31, 39, 79,158,196,246,237,219,113,252,248,113, 60,122,244, 8, 86,171, 21,254,254,254,160,148, 98,239,222,189, + 42,171, 70,211, 43, 15,200,100, 69,191, 98,106,248,248,116,241,246,242, 74,241,244,240, 72,171,225,227,211,229,249,255, 59, 3, +113,113,113,113,176, 90,173, 8, 9, 9,113,171,172, 31, 22,181, 90, 47,150, 24,151,192, 90,181, 22, 4,151, 99, 92,130, 1,207, +224,218,181, 23,148, 24, 23,106,181, 94,172,110,154, 29,129,229,159,125,246,153, 94, 36, 18, 97,219,182,109, 33,150, 58,117, 98, + 4,192, 72, 5, 16,222, 17, 16, 85,117,188, 47,176,226,155,111,190,201, 36,132, 96,203,150, 45, 30,206,181,107, 71, 9,128,183, +157,129, 26,206, 64, 13, 1,240,182,115,237,218, 81,219,182,109,243,176, 90,173,152, 52,105, 82,166, 47,176,162, 18,201, 79, 40, +165,253, 40,165,237, 41,165,129,235, 86, 45,195,225,125, 59, 75,204,213,251,148,210,235,148,210, 55, 41,165, 81,172,196, 49, 24, +140, 87, 17, 82, 94, 63, 39, 97,203,121, 89, 0,245,234,208,170, 33,110,220,141, 85,121,184, 58, 29, 43,249, 95,126,244,206,186, +157, 27, 56, 53,252,229,151, 95, 32, 20, 10,145,154,154,138, 7, 15, 30,192,201,201, 9,111,188,241,134, 81,175,209,244, 47, 89, +139,144, 16,210,149, 82,122,178, 88,179,104,189, 51, 85,188,162,182,224, 94,173,163,135, 15,242,157,157,157, 81, 88, 88, 88, 58, +173,128, 76, 38,131, 84, 42,197,205,155, 55,209,167,223, 0, 91,142,172,125,233, 68,163, 37,235,157,149,213, 4, 33,124, 0,104, + 9,200,110, 3, 83,188,252,252,166,126,253,245,215,210, 30, 61,122, 64, 36, 18, 33,160, 70,104,102, 72,207, 31,150,243,120,196, +154,150,167,158, 94,187,134,159,243,131,248, 36, 0,164,104,205,194,226,181, 8,203, 75,103,144,233, 92,200,158,141,139,157, 26, + 55,110, 92, 26, 21,203,202,202, 66,118,118, 54,148, 74, 37,180,218,162,169, 30, 14, 30, 60,136,195,231, 99,212,250,128, 33, 9, + 21,165,243, 63,121,143,117,244, 51, 95,171,185,117,243, 70,190,167,167, 39,178,178,178,144,147,147, 3,165, 82, 9,189, 94, 15, +155,205,134,252,252,124,252,182,126,163, 45, 79,209, 62,177,100, 34,199, 74, 53,181,169, 82,183,194, 75,254, 77, 34,130,233,123, +239,189,231,232,228,228, 4,142,227, 80, 80, 80,128,148,148, 20, 60,121,242, 4,231,207,159,215,102, 43, 77,208,122,116, 75, 43, +153,104,180,220,243,249,178, 10,213,255,162,102,113, 89, 2, 0, 63, 95,223,244,228,228,100, 47,155,205, 6,127,127,127,171, 50, + 63,127,129, 24, 56,238, 8,100, 0,160,185,192,215, 75,151, 47,127,119,192,128, 1,104,222,188,121,106,102, 86, 86,205,242,202, + 18, 8,225,135, 1,206,186,128,128,232,235,215,175,251,164,164,164,224,173,183,222,202, 77,126,252,184,116,154, 6, 21,208, 46, +184,118,237, 5,219,182,109,243,168, 85,171, 22, 26, 52,104,144,233, 80, 50, 77, 67,249,229,179,194,123, 83, 25,119,168,230, 7, +131, 34,155, 79,152, 48, 1, 86,171, 21,231,207,159,199,181,107,215,144,156,156,140, 75,151, 46, 41,157,228,242,225, 37,107, 17, + 86, 84, 62,123,133,106, 67,182,108,217, 76, 68, 34, 17,214,175, 95,143,219,183,111, 3, 0,154, 52,105,130,209,163, 71,195,106, +181, 98,212,168, 55,233,161, 88,105, 66,101,229,147, 16, 18, 9, 96, 17,138,204, 93,115, 74,169, 3, 33, 36, 29, 64, 96,117,250, + 92,177,242,201, 52,153,230,191, 71,243, 85,163,202,181, 8,191,253, 21,206,207, 46,199, 49, 38,125,231,170,217,130,182,237,218, +135,207,158, 53,147,215,162, 69, 11, 4, 6, 6,162, 73,147, 38, 72, 73, 73,145,184,184,184, 84,181,222, 89, 97,251,158, 35,159, + 52,108,216,208,101,218,180,105,206,221,187,119, 23, 6, 6, 6,130, 82,138,219,183,111, 99,247,238,221,230,181,107,215,170,117, +222,253,148,183,206,252, 94,104,207,122,103,215, 0, 29,128, 57, 1,233,233,171, 63,252,224,131,153,141,155, 54,125,111,214,172, + 89, 60,133, 76, 42,252,110,250,251, 14, 0,240,237,207,219,157, 7, 12,121, 3, 75,235, 0, 29, 70,150,191,206, 91,217,116,166, +164,141, 73,238, 61,168, 75,157, 41, 31,189,107, 27, 54,108,152,220,201,201, 9,129,129,129,112,117,117, 69, 66, 66, 2,210,210, +210,232,129, 3, 7, 10,175,220,137, 19,238, 61,126, 35,217,193,217,215,158,117, 3, 53,237,123, 12, 77,236,221,187,183,235,219, +111,191,237,216,172, 89, 51,161, 68, 34,129, 68, 34, 65, 86, 86, 22, 30, 61,122,100, 62,112,224, 64,161,206,171, 87,193,173, 51, +219, 52,118,174, 69,168,111, 63, 98,246,163, 11, 39,102, 77,138,190,127,255, 77, 14,104,100, 54,155,253,109, 54, 27,225,241,120, + 25, 28,199,221, 55,107, 52,235,140, 77,102, 45, 97,107, 17,218,135,205,102, 19,217,108, 54, 40,149, 74,156, 56,113, 66,240,248, +241,227,175,239,222,189,251,117,122,122, 58, 44, 22, 11, 94,127,253,117, 52,105,210, 4,103,206,156, 65, 78, 86,214,129,202,180, + 98, 1,149, 36, 45,109,244,152, 49, 99,142,108,222,188,153,119,247,238, 93,143,245,235,215,255, 86,158,113,121,243,205, 55,185, +172,148,148,209,198, 74,230,192,170,226,222,204, 61,186,237,167,187, 3, 7, 15,137,152, 53,227,107,225,107,175,189, 6, 15, 15, + 15,180,107,215, 14,102,179,217,165, 94,189,122, 85,221,155,154,246, 61,135, 39, 52,106,212, 72,190,100,201, 18,159,119,223,125, + 23, 31,125,244, 17, 0, 64,175,215,227,248,241,227,152, 52,105, 82,102,138,160,165,182,170,242, 89, 28,153, 42, 49, 94,231, 0, +180, 7,144,192, 58,180, 51, 24,140,127,181,193, 2,254,179,222,217,133,107, 81, 40,187, 28, 71, 17,190, 15,172, 65,111, 63, 30, + 55,117, 65, 3,190, 69,237, 42, 36, 6,167,248,184, 56, 82,213,154,132,165,235,157, 57,135, 22,186, 63,249,163,197,119,223,126, + 59,113,233,210,165, 93, 74,166, 98,144,201,100,247,245, 90,237, 41, 79,163,113,153,206, 57,244, 84,117,215,206, 75, 3,178, 0, +124,224,122,235,214,242,190, 3, 94, 95,232,224, 22, 34,252,106,222, 90, 3,159,199, 51, 61, 74,207,193,210, 58,128,220,142, 1, +143, 58, 19, 16,173,244,181,102,185, 15,137,253,230,179,207,166,124, 59,103, 78, 11,133, 66,209,193,108,181,134,114, 28, 7,112, + 92,188, 78,171, 61, 71,205,230,235,198, 38, 51, 22, 59, 56,251, 82,187,215, 13,116,169,167,113, 75,220,217, 98,195,186,117,159, +236,216,177,227, 79,121,119, 55, 26,151,235, 92,234,157,180, 39,239,101,247, 49, 0,151,145,157,125,185,194,218, 6,216, 90,132, +118,223, 20, 28, 55,214,213,213,117, 83,151, 46, 93, 28,186,118,237,138, 62,125,250,224,181,215, 94, 3,199,113,160,148, 66,163, +209, 96,251,246,237, 88,184,112, 97,124, 77, 96, 78, 85,122, 70,224,148,228,240,225, 94,141, 26, 53, 90, 95,153,113, 41, 54, 87, + 85,246, 57,172,252,222,148,196, 91,157,251, 39,141,248,240,187, 58, 38,117,134,139,187,204,234, 19, 29,117,159,103,255,189, 25, +166,177,221,222,222,242,245, 65,131, 62,228, 11, 4,237,138, 71, 52,210,135, 15, 30,220, 42, 89,236, 25, 77, 70,159,168,102, 89, + 42,153,123,142,117,104,103, 48, 24,255,110,131, 37, 16, 8,178, 75,162, 60, 2,129, 32, 59, 97,239,184, 55, 42, 19, 17, 2, 93, +138, 35, 87,168,114, 45,194,226,223,147, 0, 13,140,198,185,207, 76, 34, 90,102,180,160,240,185,253,171,147,169, 2, 32, 22, 86, + 99, 95,100, 63, 0,246,127, 80,164,215,226,219, 47,202,230,169,194, 19,242,204,247,138,242, 13,192, 5, 20, 22, 94, 64, 97, 97, +185,179, 75, 11, 5,162,252,170,210,249,124,222, 83, 0,245, 95,205,187,160,154,231, 71,240, 23,206,231,191,141,167,185,185,123, + 1, 40, 2, 14, 30,244, 62,122,240,224,176, 41,147, 39,191,238,235,231, 87,219,195,195,195,213,209,209,145,119,245,234,213, 39, + 86,131, 97,121, 99, 96, 67,113,244,180, 74,140,192,169,176,148,148,250, 67, 7, 13,250,144, 8, 4,109,203, 26, 23,106,181, 94, + 10, 1, 86, 24,237,152,189,189,186,247,102,160,196,183, 75,113,228, 10,124, 59,239,205,180,162,116,204,131,213, 58, 15,247,238, +149, 83,230,171, 93,150,190, 37,132,104,192,102,104,103, 48, 24,255, 38,254,230,117,133,186, 50, 77,166,249,170,104, 22,121, 20, + 56,177,243,201, 52,153, 38,211,100,154, 47, 95,243, 85,219, 4,204, 98, 50, 24,118, 87, 70,108,248, 79,115, 23,131,193, 96, 48, + 24, 21, 66, 0,116,173,224,101, 98,247,232, 0, 66, 72,215, 23,120, 89,157,100,154, 76,147,105, 50, 77,166,201, 52,153,230,191, + 75,179, 42,237, 87,102,116, 34,107, 34,100,154, 76,147,105, 50, 77,166,201, 52,153, 38,107, 34,124,185, 27, 15, 12, 6,131,193, +192,236,217,132, 7, 16, 2,204,230, 1, 59,249,192, 80,126,209,223, 47,206,208,161,164,220, 73,104, 63,249,132, 56,178, 51,206, + 96,188,218,176, 62, 88,255, 69, 8, 33, 65, 62, 62, 62,171, 0,144,204,204,204,177,148,210, 20,118, 86,254,121,184,187,187,119, +177, 90,173, 80,169, 84,167, 94,197,252,213,175, 67, 6, 81, 30,234,253, 39,172,141,148, 7,241,116, 83,121,251, 70,132,146,183, + 64,254, 51,151, 22,225,240, 48,250, 17,221, 83,141, 50,207, 27,216,203,115, 17, 0,236, 61,146, 51,245,239,152, 23,139, 16, 82, +215,211,211,243,152, 64, 32, 16,216,108,182, 15,178,178,178, 14, 86,108,128,134,242, 1,192, 83,186,251, 75, 23, 55,143,105,223, + 76, 33, 66,147,241, 7,165,209, 96, 80,241, 4,130, 68,177, 72,118,209,202,147, 31, 73,203,234,245,160,188,227,119,236,216, 81, +225,234,218,145,161,164, 87,120, 68, 68,191,166, 13,164, 9,139,150,181, 88,218, 33,196, 67,248, 36,245,142,226,215, 77, 41,171, + 60, 93,253,251, 77,124, 95,112, 80, 66,109,111,126,255, 27, 45,100,119,153,253,204, 39,196,205, 12, 52, 16, 74, 36,129, 54,171, +213,155, 0,148, 47, 16,100, 89,140,198, 84, 17,112,111, 26,165,202, 87, 93, 83, 36,145, 4,216,172, 86,111, 0,248, 39,166,147, + 81,133,193,114,116,116,188,201,227,241, 2,202, 46, 82,203, 43, 94,208,185,228,179,178,255, 35,132,192,102,179,165,229,231,231, + 55,171,198,131,208, 9,192, 48, 0, 37, 67,205,183, 2,216, 78, 41, 85,191,224,131,213, 73, 36, 18, 77,149,203,229,157,245,122, +125,125, 0,144, 74,165,209, 90,173,246,180,217,108, 94,244, 34,186,132, 16, 1,128,161, 10,133,162, 19,143,199,235, 68, 41, 37, +148,210, 51,133,133,133,167, 1,236,160,148, 90, 95, 64, 83,234,229,229, 53, 47, 60, 60,124,228,151, 95,126,153,231,238,238, 30, + 54,105,210,164, 27,158,158,158,191,231,230,230, 78,167,148,234,255, 9,133,131, 16, 82,219,199,199,103,171, 80, 40,228,167,166, +166,118, 2,128,192,192,192, 51, 38,147,201,150,157,157,253, 6,165,244,113, 53,245,228, 0, 90, 41, 20,138,102, 10,133,162,189, +205,102,171,199,113, 28, 56,142,123, 88, 88, 88,120,222,108, 54,223, 4,112,149, 82,170,253, 7,153, 96, 71, 47, 47,175,205,132, + 16, 16, 66, 66, 41,165,154, 87,237, 33, 64,121,168,247, 32, 58, 38,172,212, 68,213, 15,175,228,132, 32,168,156,125,237, 54, 88, +189,187,184,244,236,215,175, 17, 15, 0,204,230, 27, 61, 1, 28,126,217,230,106,240,224,193,151, 55,111,222,236,106, 52, 26, 49, +118,236,216,173,206,206,206, 43, 84, 42,213,151,149, 29,231,232,232, 56,105,206,220,159,101,197,207, 52, 47,142,227,188, 50, 50, + 82, 67, 99, 99,238,247,140,141,141,250,206,172,221,115,213, 76,249,227,148,186,254, 49,246,164, 35,162, 54,233, 59, 96,232,160, + 62,115,230,204,194,200,225, 35,107, 68, 71, 27,164,254, 78, 9, 98,181, 89, 94,199,195, 35,160,255, 23, 95,125, 79,174, 94, 57, +219,127,199,246,181,167,191,120,143,116,102, 38,203,174,107, 75,190, 21, 8, 90,185,134,135,183, 31,190,119, 47, 20,129,129, 2, +129, 68,194, 3, 0,171,209, 24, 88,152,154,234,187,173,127,255,150,179, 9, 57, 59,147,210,107, 76,243,255, 95,147, 97,167,193, +226,241,120, 1, 79,159, 62,245,146,203,229, 69, 15, 97, 74, 97,179,217, 96,179,217, 80,252, 82, 4,165,180,244,167,213,106, 69, +120,120,184, 93, 53, 88, 0,157, 1,188,211,184,113,227,215,231,204,153, 35,234,220,185, 51,108, 54, 27, 14, 31, 62,220,110,238, +220,185, 63, 17, 66,118, 3,216, 0,224,148,189, 53, 92, 66, 72, 15,185, 92,190,229,135, 31,126,112,234,214,173,155,192,207,207, + 15,132, 16,100,102,102,182, 58,121,242,100,179, 73,147, 38,125, 64, 8, 25, 69, 41, 61, 86,141, 27, 58,210,209,209,113,231,160, + 65,131, 2, 58,116,232,224, 16, 17, 17, 1,155,205,134, 59,119,238,188,123,243,230,205, 17,187,118,237,154, 73, 8, 25, 98,239, +122,106,132, 16,162, 80, 40,222,246,247,247,159, 55, 99,198, 12,183, 81,163, 70,137,163,162,162, 10, 66, 66, 66,200,197,139, 23, + 61,183,111,223,254,193,130, 5, 11,134, 58, 58, 58, 78, 47, 44, 44,220, 72,203, 91,199,232, 57,156,156,156,110,242,120,188, 0, +123, 12, 48, 0,187, 77, 48, 33,164,113,205,154, 53,183, 95,184,112,161,102, 82, 82,146,109,224,192,129,155, 0,224,244,233,211, + 13, 44, 22, 11,233,222,189,251, 17, 66,200, 48, 74,233, 29, 59,243,222,208,205,205,109,223,200,145, 35,221,106,215,174, 45,171, + 89,179, 38,145,203,229,224,243,249, 80,169, 84,126, 81, 81, 81, 93,175, 93,187,166, 63,121,242,100, 62, 33,164, 63,165,244, 94, + 53,174,211,107, 94, 94, 94,111, 10,133,194, 72,171,213,234, 15, 0, 2,129,224,169,197, 98,137,202,206,206,222, 76, 41,189,252, +162, 55,136,183,183,247, 79,243,230,205,243,200,206,206,166, 11, 22, 44,248, 9,192,219,175,234,195, 96,235,239, 59,112,243,198, + 53, 0, 16, 17, 66,200,243,229,143, 16, 66,234,133, 66,244,233,167,147,209,172,121, 75,188, 49,114,104,149,154, 3,251,120,204, + 17,243, 5,238, 58,147,241, 90,174,138,183, 47,200, 75, 60,104,212,208,102, 9, 0,112,244,200,253, 65, 45, 91,186, 93,244,112, +230, 6,200,196,146,150, 38,155, 53,111,239,161,220, 25,213, 49, 83,254,254,254,199, 92, 93, 93,101,249,249,249,153, 57, 57, 57, +191, 14, 30, 60,248,219, 13, 27, 54,184, 62,121,242, 4,169,169,169,152, 56,113,162, 34, 45, 45,237, 67,137, 68,114,197,104, 52, + 86, 24,201,210,104, 52,203,230,205,157, 60,195,209,201,149, 47,147,202,161,112,116, 66,205,154,161,104,222,162, 29,186,118,235, +143,132,132,216, 86,219,255, 88,123,155,159,177,115,190, 77,220,228, 91,165,178,102,133,207,165,250, 97,164, 67,137,185,154, 49, + 99, 22,226, 98, 98, 52, 73,137,188,143, 15,237, 21,200,122,117, 9,151,152,204,133, 73, 87,175,156,173,217,170,117, 71, 0,104, +182, 99,251,218,211,179, 71,145, 46, 51,183,188,122,230,253,101,154,171, 57, 66,225,219, 61,150, 44,241,106,242,193, 7,162,194, +196, 68,115,194,202,149,186,172,243,231,109, 2,137,132, 6,246,236, 73, 60, 59,117,114,248,224,225, 67,209,165, 5, 11,218,127, + 39, 22,135,124,101, 50,109, 97,154,255,127,154,140,106, 24, 44, 66, 8,228,114, 57,182,109,219, 6,161, 80, 8,129, 64, 0,161, + 80, 88,225,239, 65, 65, 65,246,220, 36,131, 61, 61, 61,127,158, 49, 99,134,247,176, 97,195,224,238,238,254,124,184, 30,175,191, +254,186, 40, 46, 46,110,196,198,141, 27, 71,252,250,235,175,153,132,144,143, 41,165,187,171,208,237, 20, 22, 22,182,251,248,241, +227, 82,131,193,128,243,231,207,163,160,160, 0, 98,177, 24, 1, 1, 1,232,222,189,187, 32, 38, 38,198,173, 91,183,110,187, 9, + 33,125, 41,165,103,236, 72,107, 51, 47, 47,175,115, 59,118,236,112,104,212,168, 17,121,244,232, 17,154, 52,105, 2, 0, 80,169, + 84, 24, 56,112,160,195,168, 81,163,106,143, 24, 49,226, 42, 33,164, 3,165,244,102, 21,122, 77,125,124,124, 54, 14, 26, 52,200, +239,187,239,190,115,114,116,116, 68, 82, 82, 82,134,143,143, 79,104,201,249, 30, 49, 98,132,184, 95,191,126,190, 11, 23, 46, 92, +182,115,231,206,207, 8, 33,111, 83, 74,111, 85,166, 91, 98,132,101, 50, 25,178,178,178,176,117,235, 86,124,248,225,135,224,243, +249,200,206,206,198,246,237,219,241,241,199, 31,151, 24, 25,187, 76,176, 92, 46,239,218,168, 81,163,223, 78,159, 62, 29,224,226, +226, 2, 63, 63, 63,222, 55,223,124, 19, 25, 18, 18, 34,173, 81,163, 6, 63, 35, 35, 3,187,119,239, 14,121,243,205, 55,247, 57, + 56, 56,188,107, 48, 24,170,108, 58,243,246,246, 94,119,232,208,161,160,232,232,104,172, 92,185, 18,249,249,249, 16,139,197,112, +113,113,129,143,143, 15, 66, 67, 67,201,180,105,211,100,253,250,245,147,125,244,209, 71,235, 0, 52,182,227, 26, 53,242,242,242, + 90, 53, 98,196,136,144,217,179,103,187,248,248,248,160,164, 66,160, 82,169, 2,146,146,146, 90,205,152, 49, 99,136,183,183,247, +147,236,236,236,113,148,210,187,213,124,168, 55,238,210,165, 75,223,129, 3, 7,242, 51, 50, 50,176,121,243,230,190,132,144,198, +246,154,202,255, 53,110,222,184,134,177, 19, 38, 22,250, 5, 6,138, 14,236,255, 99, 64, 97,225,234,139, 10,158,139, 0, 0, 10, + 57,165,181, 77, 43, 69,219,126,253, 71,136,122,247, 25, 88,184,250,151,101, 10,123, 12,150,152, 47,112,223,182,101,124,234,249, + 75,241,245,142,157, 76,234, 58,176,127, 87,158, 64, 20, 86, 27, 0,166, 76, 30, 35,222,187,255,228,138, 30, 93,107,100,180,111, + 19,154, 58,124,212,202,192,234,152,171,186,117,235,158,189,125,251,182,183, 68, 34, 65,126,126,190,251,234,213,171,127,108,219, +182, 45, 47, 33, 33, 1, 49, 49, 49, 72, 76, 76,132, 74,165, 66,183,110,221, 20,183,110,221,250, 21, 64,133, 6, 43, 71, 63,120, + 94,136, 87,238,114,127,119,215,154, 6,179,202,203,102,205,139, 56,125,242,110,195, 93, 59,116, 77,188,124, 2, 66, 71,140, 24, +139, 47,190,252, 94,184,103,215,198, 25,231,206, 31, 7, 80,179,226, 25,252, 41, 94,251,106,250,151, 80,107,140, 24, 53,114, 12, +222, 28, 57,198,157,194,228, 75,109, 6,185, 73, 95,224,226, 44,138, 62,184,241,143, 29,131, 0, 4,148, 49, 89,167,152,201,170, +152, 57, 2, 65,203,190, 63,255,236, 25,249,254,251,146,187,179,103,107,115,207,159,215,215,233,221,187,160,201,248,241, 70, 0, +208, 36, 38,138,226,102,206,148,121,182,111, 47,109, 61,117,170,171,205,100,242,153, 75, 72,139,111, 40,189, 94, 93,205,160, 97, +195,108, 51,214,175,111,126,126,242,228,142,196, 98,225,247,108,221,250,206,130,205,155,159,254, 21,205,151,153,206,244,115,231, +140,249, 33, 33,104, 50,112, 96, 94,144,151,151,241,101,230,253,175,164,147, 81,206,115,138, 82, 10, 66, 72, 7, 0,103, 1,204, +166,148,206, 2, 0, 23, 23,151, 44,165, 82,233,181,123,247,238, 42,205,149, 80, 40,132,175,175, 47, 66, 67, 67,179,179,178,178, +188, 43,121, 40,166, 90,173,214, 0,171,213, 10,177, 88, 92,105,194,212,106, 53,238,220,185,131, 78,157, 58,165, 81, 74, 3, 43, +107,194,145,201,100, 9, 49, 49, 49, 30, 15, 30, 60,192,205,155, 55, 17, 18, 18, 2, 87, 87, 87, 8,133, 66, 88, 44, 22,168,213, +106,132,133,133, 65, 34,145,160,105,211,166,185, 90,173, 54,164,178,166, 30, 66,136, 68, 46,151,199,159, 59,119, 46,176, 73,147, + 38,184,126,253, 58, 2, 3, 3,225,227,227, 3, 0, 72, 76, 76,196,197,139, 23,209,187,119,111,220,190,125, 27,175,191,254,122, +170, 86,171, 13,165,148, 26, 43,210,116,119,119,207, 56,125,250,116, 90,131, 6, 13, 12, 90,173,150,151,149,149, 37, 60,127,254, +188, 85,163,209, 40, 84, 42,149, 80,169, 84, 10,213,106,181, 64,171,213, 10,121, 60,158, 72,175,215, 11, 79,157, 58,197, 55,153, + 76, 78,149,157,167,146,235,180,127,255,126, 52,104,208, 0,187,119,239,198,148, 41, 83,112,233,210, 37, 4, 6, 6, 98,199,142, + 29,152, 58,117, 42, 98, 99, 99,225,225,225,129,136,136,136, 74,175, 17, 0,212,169, 83,231,209,253,251,247,107,139, 68,162,146, +117, 23, 75,214,179, 67, 78, 78, 14, 30, 63,126,140,167, 79,159,162, 78,157, 58, 24, 57,114,228,227,180,180,180, 58, 85, 21,180, +128,128,128,156,232,232,104,143,134, 13, 27, 34, 43, 43, 11, 46, 46, 46,112,118,118,134,139,139, 75,233,239, 33, 33, 33,152, 60, +121, 50,124,124,124,178,245,122,189,119, 85,230,167, 65,131, 6,199, 78,157, 58,229,225,228,228,132,204,204, 76,168,213,106, 8, + 4, 2,200,100, 50,120,120,120,192,193,193, 1, 0, 16, 31, 31,143, 62,125,250,228, 38, 36, 36,244,168, 70,196,141,231,237,237, + 29,115,239,222,189, 80, 74, 41, 82, 82, 82, 16, 27, 27,139, 9, 19, 38,196, 27, 12,134,240, 87,105, 77,189, 50,253,170, 68,111, +143, 30, 43, 26,216,127,128,238,206,205,163,156, 20,231,208,162,177, 84, 9, 0,215,239,232, 93,244,232,128,198,205,122,242,246, +238,223, 39,219,184, 97,181, 16, 28,188, 65, 16,251, 32,142,206,173, 72,187,111, 15,151,183,166, 78,236, 89,175,125,155,246, 2, +181,154,250,252,182,105, 77,139,228, 39, 9,222, 0, 16, 92, 43, 36,235,189,183,198, 92,119,114, 34,153,231, 47,157,183, 46, 90, +118,244,225,193, 99,202, 77,118, 92,155,144,208,208,208, 43,251,247,239,247,240,242,242,130,179,179, 51,180, 90, 45,204,102, 51, + 30, 60,120, 96,216,182,109,155,197,201,201,201, 49, 51, 51, 19, 74,165, 18,132, 16,236,223,191, 63,133, 82, 26,252,188, 86, 73, + 31, 44, 0,152,208,171,158, 48,162,115,168,171, 72, 98,149, 74,133,113,190, 32, 54, 9,161, 10,239,211,167,175, 52, 60,115,238, +194, 27,189,251, 14,247,108,221,186, 19,190,255,238, 11, 75, 74,102, 86, 19,165,174,127, 76,121,125,176,234,133,146,206, 3, 95, + 31, 52,116,206,156, 89,152, 53, 99, 54, 14,238,223,171, 82,200,121, 70, 39, 23,161,115,251, 86,109, 12,147, 63, 28,144,170, 43, + 76, 11,252,113,197,154,145,221,122, 12, 13,104,213,186, 35,174, 94, 57,139, 29,219,215,222, 20,217, 44,172,185,240, 57,102, 19, +226,234, 18, 18, 50,238,147,248,120,209,221, 89,179, 10,173,233,233, 5,205, 38, 77,202, 45,111,223,180, 19, 39,228, 98, 63, 63, + 39,215,254,253,221,150, 5, 7, 83, 75,118,246,170,242,250, 16,149,167,121, 82,161,112,249,227,200,145, 46, 84, 40,236,240,249, + 23, 95, 72,251,246,237, 11,181, 90,141, 93,187,118, 97,213,202,149, 70, 95, 95,223,251,126, 81, 81,183, 35,213,234,175,237,213, +108, 54,105, 82,174,205,102, 35, 67,167, 78,237, 22,157,152,216, 57, 51, 59,187, 6, 0,248,186,185,165, 54, 11, 9,185,185,238, +224,193,216,159,106,214,228,236, 77,231,154,163, 71,189,119, 38, 37,189,239,230,230, 38,205,202,206, 22, 72,196,226,188, 86, 17, + 17, 59,126,153, 62,253,172,245,222, 61,145, 67, 64,128,147,115,223,190,213,206,123,179, 73,147,114,243, 53, 26,193, 39,223,126, +219, 38, 57, 43,171, 70,161,209, 88, 71,169,209,248,216, 44, 22,158,147, 76,150, 87, 43, 44, 44, 91,127,254,124, 70, 45,157,110, +226, 26, 74,179,255,198, 72,229,159,188,200,171, 16,193, 58, 75, 41,253,211,104, 25, 74,169, 93,209, 43,161, 80,248, 76,115, 84, + 37,136,248,124, 62,174, 95,191,142,236,236,108, 52,104,208, 0, 53,107,214,124,102,135,132,132, 4, 28, 62,124, 24, 74,165, 18, + 77,155, 54, 5, 0, 81,101,130, 18,137,228,211,133, 11, 23,186,152, 76, 38,220,188,121, 19,205,154, 53,131, 68, 34,129, 72, 36, +122,198,252,101,103,103,163,126,253,250,248,252,243,207,157,191,251,238,187, 79, 81,201, 26,114, 2,129,224,163, 49, 99,198,120, +149, 68,172, 82, 83, 83, 75,210, 2, 0,240,244,244,196,157, 59,119,208,172, 89, 51, 4, 4, 4, 96,200,144, 33, 94,155, 55,111, +254, 8,192,162, 10,107,242, 98, 49,175, 65,131, 6,205,139, 35, 68,224,241,120,113, 78, 78, 78,158,222,222,222,114, 39, 39,167, + 63,229,113,253,250,245, 74, 30,143,103,169,234,132,242,120, 60,100,102,102, 34, 50, 50, 18, 42,149, 10, 0,160,213,106, 81,167, + 78, 29,168,213, 69, 93,206,140, 70, 35,252,252,252,160,215, 87,222,181,171, 81,163, 70,179,194,195,195,187,119,236,216, 81, 34, + 20, 10,113,247,238, 93, 52,105,210, 4,219,182,109, 67, 80, 80, 16,100, 50, 25,226,227,227,209,160, 65, 3,156, 59,119, 14,158, +158,158,168, 95,191,190,164,105,211,166, 23,242,243,243,207, 36, 37, 37,205,170, 36,157, 60,133, 66,129,115,231,206, 97,221,186, +117, 72, 76, 76, 68,122,122, 58, 28, 29, 29,209,184,113, 99, 68, 68, 68,224,181,215, 94, 67,124,124, 60, 72, 21,133,137, 16,226, + 19, 26, 26,122,240,250,245,235, 30,148, 82,108,222,188, 25,133,133,133, 48,153, 76,224,241,120,112,112,112,128,171,171, 43, 58, +119,238, 12, 79, 79, 79,132,134,134, 98,251,246,237, 30,189,122,245, 58, 92, 28,129,202,172,234,188,186,186,186, 78,156, 57,115, +102,160,151,151, 23,146,146,146,160, 82,169,224,237,237,141,142, 29, 59,250,159, 60,121,114, 34,128, 37,175,202, 11,172,164, 67, + 59, 33,132, 28,216,255,199,128, 32, 95,113,189, 22, 77, 52,193,247,111, 9,106, 31, 62,249,168, 97,209,249, 8,190,215,162,169, +230,241,245,155, 71,147, 15,236,255,227,218,195, 56,236,179,167, 9, 59, 87,197,219,119,236,100, 82,215,134,245,219,241,151,175, +152, 57, 96,236,123, 61, 36,110,174,237,136, 58,123, 59, 46, 93,187, 31,252,205,172,105, 94,115,103, 45, 56,112,236,100,146, 45, + 87,197,155,103, 79,122,235,215,243,253,233,236, 94, 47,143, 66,243, 47,184,115,205, 25, 16,182, 70,173,144,186, 80,171,213,112, +112,112,112, 24, 57,114,164,237,203, 47,191,212, 57, 57, 57,201, 8, 33, 56,115,230, 76, 54,128, 30, 85,233, 26,188, 92,169,205, +108,177, 82, 49,159,163,196, 81, 79,108,249,226,168, 7, 79,208,161, 67,175,172,230,205,154,124,183,224,135, 37, 95,133,132,132, +121,142, 28, 53, 78,184,104,209,215, 43, 1,180, 43, 79,231, 97, 60, 61, 29, 81,155, 72, 1,244,153, 51,119, 22, 18, 18,226, 93, +199,190,163,156, 45,144, 72,253,194,131,219, 56,174, 92,119,166,103,157, 58, 53,107,140, 29,253,238,161,213,235,215,245, 41, 27, +201,250,227,247,213,251, 8, 33, 93,236, 57,183,255, 34, 26,190,121,240, 32, 10, 83, 82, 44,249, 23, 46, 24,186,252,252,115,110, + 96,143, 30, 75, 76,102,179, 71,201,163,130, 71, 8, 72, 73, 23, 9,142, 35,130,207, 63,231, 81,129, 0, 22, 87,215,119,166, 1, +117,171,210,156,146,145, 49,248,141,247,223,239,179,239,232, 81,212,172, 89,179,244,125,230,226,226,130,169, 83,167, 98,210,164, + 73,146, 59,119,238,180,216,185,115,103,139, 69, 63,252,224, 61, 13, 24,108, 79, 58,143, 95,189,234, 58,126,206,156,233,141,154, + 53, 11,218,180,117,171,164,118,237,218, 0,128,199,143, 31,135,126,191, 96, 65,112,100,131, 6, 89,223,125,250,233,134,232, 47, +191,172, 15,224, 66,101,154,153,231,207,155,118, 38, 37,189,127,250,204, 25,151,200,200, 72, 0, 64,108,108,172,215,178,101,203, +198,212, 31, 50,100,212,156, 15, 62,248,186,175,193,160,116,202,201,145,244,253,233, 39,193, 31, 67,135, 86,169, 89,146, 78, 0, +232,248,238,187,159,182,235,212, 41, 98,240,251,239,187, 5, 5, 5, 17,133, 66, 1,179,217,140,244,244,116,215,232,232,232,218, + 7, 53, 26,245,158,171, 87, 55,175, 41, 94,196,253,111,162, 92, 47,242,191,110,176, 58, 18, 66, 40,128,142,148,210,115, 37, 47, +110,155,205,102,151,185, 18, 8, 4, 40,238, 4,108,223,151, 10, 4,240,243,243, 67,110,110, 46,162,162,162, 16, 28, 28, 12,139, +197,130, 99,199,142, 65,165, 82, 65, 40, 20, 66, 36, 18,193,108,174,122,109, 88,185, 92,222,181,107,215,174,130,171, 87,175, 34, + 36, 36, 4, 82,169,180, 52, 93, 37,155, 72, 36,130,175,175, 47,212,106, 53,186,116,233, 34, 92,190,124,121,215,202, 12,150,179, +179,115,239, 97,195,134,149,134,216, 10, 11, 11,193,231,243, 75,205, 74, 97, 97, 33,242,243,243,161, 84, 42, 97, 48, 24,208,186, +117,107,241,193,131, 7,123, 87,102,176,202,162,211,233, 10,179,179,179, 93,218,181,107,231,186, 97,195,134,216,214,173, 91,135, + 61, 83,194,206,158, 53, 24, 12, 6, 33,143,199,179,107,157,187, 45, 91,182,148,158,251,167, 79,159, 98,229,202,149,165,255,139, +143,143,199,242,229,203, 75,231,229,168,236, 26,133,135,135,247,218,188,121,115,179, 77,155, 54, 21,240,249,124,196,198,198, 98, +235,214,173,160,148,194,211,211, 19, 58,157, 14, 89, 89, 89, 56,115,230, 12,172, 86, 43, 20, 10, 5,252,253,253, 29, 62,250,232, +163,182,179,103,207, 22, 2,168,208, 96,217,108, 54, 27,159,207, 71,112,112, 48,102,204,152, 1,131,193, 0,145, 72, 84, 26,173, + 84, 42,149,184,125,251, 54,146,146,146, 80,213,203,197,193,193, 97,200,166, 77,155,188,196, 98, 49,244,122, 61, 52, 26, 13, 82, + 83, 83,145,156,156,108,200,206,206,182, 58, 58, 58,242,130,131,131,121, 18,137, 68, 50,112,224, 64, 82, 98, 52,251,246,237,235, +190,121,243,230,225, 85,153, 35, 66,136,103,189,122,245,190, 26, 51,102,140, 67,217,202, 70,102,102, 38, 6, 15, 30, 44,187,124, +249,242,151,132,144,173,148,210,156, 87,233, 45, 70, 41,165,133,133,171, 47,158,223,247,115,189,251,183, 4,181, 77,166,130,214, +221,122, 79, 20, 0,192,229,115,235, 91,223,191, 21, 5, 41,177, 38, 31, 57,190,232,162, 66, 49,150, 86, 21, 1,236,221,197,165, +103,144,151,120,208,192,254, 93,121,191,109, 90,211, 98,236,123, 61, 36, 94,181,214, 16, 0,112, 21, 5,224, 53,219, 20,158,193, +168,117,248,109,211,154, 22, 3,251,247,190,150,248, 36,121, 73,159,174,174,123, 14,159, 82, 30,173, 44, 66,232,235, 35,244,119, +115,202,131,155, 99, 19, 4,135, 56,226,246,157,123,216,183,251, 2, 66,195,219,194,104, 52,194,106,181,202,251,245,235,167,219, +182,109,155, 33, 46, 46, 78,163,215,235, 59, 80, 74,227,170,202,127, 90,218, 3, 46,204,167,149, 89, 36,149, 88, 53, 42,145,110, +218,215, 59,135, 54,109,217,189,153,171,175,191,208, 83,206, 29,232,212,161,221,214,223,183,172,154, 52,229,179,185,104,220,184, +117,235,135,143,142, 68, 0,184, 95,174,105,125, 76, 15, 70,134, 18,107,194,163, 71,125,146,147,146,210,234,122,251,152, 30, 43, +169,101,226,180, 53,221,218,117, 24,210,176,118,189,246,226,232, 7,231,200,228, 15,199,252,254,227,138, 53, 35, 75, 76,214,249, +243,199, 58,204,154,149, 36, 6, 96,100,190,170,184, 86, 46,145, 4, 40,130,131, 5,137, 27, 54,232, 67,250,245, 43, 0, 0,147, +217,236,145,152,148,228, 44,147,201, 64, 41,133,197, 98,121,166,143,112, 73,191,224,200,176, 48,111,123, 52, 19,191,249,166,225, +231,159,127,142,204,204, 76, 88,173, 86, 8,133,194,231,159,217,208,106,181,120,231,157,119,240,211, 15, 63,180,178, 71,211,102, +179,145,241,115,230, 76,255, 98,250,244,218,227,198,141,227,149,125,246,186,185,185, 97,231,174, 93,226, 21, 43, 86, 4,124,245, +211, 79,239,188, 33,145, 36, 84,165,153, 91,167, 14,220,178,178,164, 37,230, 10, 0,194,194,194,176,114,229, 74,201,123,239,189, + 39,238,215,175,223,226, 59,141, 26, 45, 91,210,182,237, 35,247,186,117,157,196, 18, 73,128,189,231, 19, 0, 52, 6, 67,228,146, +101,203, 92,175, 93,187,134,172,172, 44,100,102,102,150,220,203,104,222,188, 57,121,243,205, 55,157,107, 5, 6,182,248,155, 47, +247,159,188,200,255,188,193, 42,206, 8, 41,206, 24, 41,243, 82,124,198,168, 84,101,176, 94, 32, 28, 8, 95, 95, 95,152,205,102, +172, 93,187, 22, 34,145,168,244,165, 11, 0, 38,147,201, 30,179,210,192,207,207, 15, 42,149, 10,117,235,214,125, 38,114, 37, 18, +137, 32, 16, 8, 32, 18,137, 32,145, 72, 96, 52, 26, 17, 20, 20, 4,157, 78,215,160, 50, 77,189, 94,223,216,205,205,173,244,197, +106, 52, 26, 75,205,149, 82,169,132, 82,169,132,201,100, 66, 65, 65, 1, 10, 11, 11,161,209,104,160,213,106,155,216,147,103,142, +227, 16, 21, 21,245, 56, 44, 44,172, 49,159,207,135, 66,161,144,107,181,218,210,190, 67,249,249,249,216,184,113,163,246,173,183, +222,242,216,191,127,191,206,158,115,248,241,199, 31, 67, 34,145, 64,167,211,225,215, 95,127,197, 39,159,124, 2,145, 72, 4,141, + 70,131,149, 43, 87, 98,242,228,201, 16, 8, 4, 48,153, 76, 88,182,108, 89,197,145,140, 7, 15, 18,175, 94,189,218,164,105,211, +166,174,123,246,236,201,233,214,173,155,103,143, 30, 61, 32,149, 74,161,215,235, 97,177, 88,208,170, 85, 43,132,135,135, 35, 59, + 59, 27, 71,142, 28,201, 13, 13, 13,245,184,118,237, 26,151,153,153,153, 92,213,203,187,172,193,182,217,108,200,202,202,130, 82, +169, 68, 78, 78, 14,210,211,211,145,150,150, 6,129, 64,128,170, 42,239,238,238,238,175, 71, 70, 70,242, 1, 64, 42,149,162,113, +227,198,152, 62,125,186, 85,175,215, 15, 3,112,164,120,183, 94,107,214,172,217,115,241,226, 69,129,159,159, 31, 98, 98, 98,224, +233,233, 41,112,112,112,168,210, 96,249,248,248,172, 63,112,224,128, 91,137,169, 46, 57,207, 58, 93,209,229, 24, 60,120,176,219, +166, 77,155,214, 3,232,253,170,189,204, 20, 60, 23, 65,139,198, 82,229,225,147,143, 26,118,235, 61, 81,224, 91,123, 38, 0,224, + 53, 64,112,226,240,178,134,189,187,214,217, 81,210, 47,171, 50, 6,246,242, 92,212,175, 95, 35,222,168,161,205, 18, 4,162,176, +218, 91, 54, 45,243,118,115,109,247,159,135, 4,223, 13,114, 41, 16, 94,219,198,187,242, 71,130,247,228,137, 97,166,173, 27,222, + 79,216,178,227,102, 87,145,232,110,103, 0,147, 43,210,190, 23,109,220, 95,160,241,175,231, 42, 58, 75,224,208, 31, 77, 26,135, +194,211, 83,137, 95, 87,111,130,127, 80, 27, 24,141, 70, 56, 57, 57,201,108, 54,155,153,207,231,111,177,199, 92, 1,192,169, 83, + 74,174,126,125,165,137,175,225,172, 31,126,178,104, 80,183, 94,253, 35, 58,119,238,202, 29, 63,113,220,220,166,137, 57,163,115, +231,214, 89,103,206,158,143,207,204,124, 26, 26, 30,222, 16,113,177,119,122, 2, 36, 10, 40,191,192, 70,197,211,163,181,107,147, + 51,219,182,141,229,244,220,109,233,183,243,238,247,234,211,231,237,200,246,237,218,115, 39, 78,158, 54,137,145,251, 80,209,246, +181,167,111,143, 24,182,103,219,238, 61,221,207,156, 62, 88, 71,165,206, 58,248,195, 10,202,204, 85,217,202,153,213,234, 45,144, + 72,120, 57,103,206, 88, 27,188,247,158,177,228,126,148,201,100,216,183,111, 31,196, 98,113,233, 38, 18,137, 74,127,247,246,246, + 46, 25, 84,101,151, 38, 0,100,100,100, 32, 51, 51, 19,206,206,206,240,244,244, 68,102,102, 38, 46, 95,190,140,184,184, 56, 8, +133, 66,244,236,217, 19,188, 10,250, 46, 63,175, 57,116,234,212,110,245, 26, 52, 8,122,222, 92, 1,128,217,108, 70,126,126, 62, + 6, 12, 24,192, 59,114,228,136,207,209,148,148,254,223, 0, 91, 42,211,108,210,167, 79, 94,214,206,157,229,126,119,211,166, 77, +201,165, 75,151, 36, 61,123,244,152, 52,101,222,188, 21, 63,109,218,148,106,179, 90,125,170,147,119, 30,143,199, 35,132, 32, 48, + 48, 16,249,249,249, 40, 44, 44,106,169, 86, 40, 20,112,117,117,133,197, 98, 1, 71,169,240,111,174,228,149,235, 69,254,167, 13, + 86,113,102, 0,160, 99,217, 23, 10,199,113,118,153, 43,161, 80, 88, 58,130,237, 47,156,216, 63,125,102,143,193, 42, 73,171,131, +131, 67,233, 13, 86,214, 88,149,164,147,199,227,129,207,231,195,158,200, 59,199,113,124,141, 70,131, 93,187,118,161, 67,135, 14, +165,205, 79, 42,149, 10, 74,165, 18, 42,149, 10, 6,131, 1,137,137,137, 56,117,234, 20,234,212,169, 3,192,190, 73, 91, 19, 18, + 18,110,214,172, 89,179, 89,201,203,187, 83,167, 78, 1, 27, 54,108, 72,239,221,187,183, 31,165, 20, 95,127,253,117,110,171, 86, +173, 60,202,190,220,171,130,207,231,227,242,229,203,168, 83,167, 14, 40,165, 16,137, 68,136,141,141,133,151,151, 23, 56,142,131, + 64, 32, 64, 78, 78, 14, 28, 29, 43,159,219, 48, 42, 42,106,244,187,239,190,155,238,236,236,220, 48, 47, 47, 47, 67, 34,145,180, + 59,127,254,124,160,217,108,134,147,147, 19,156,156,156,112,248,240, 97,184,184,184,224,211, 79, 63, 77,209,235,245,151,229,114, +185,183, 94,175,191,151,153,153,249,117,117,174,183,213,106,133, 86,171, 69, 65, 65, 1,242,243,243,161, 86,171, 97, 48, 24,170, + 76, 99,121,180,107,215, 14, 7, 15, 30,228,207,159, 63,255,183,132,132,162,138, 96, 72, 72, 8, 62,253,244, 83,190,191,191, 63, + 18, 19, 19,113,243,230, 77,152,205,102, 84, 21,126, 22, 10,133,157,166, 76,153,210, 54, 40, 40,136,152,205,102,112, 28, 7,163, +209,136,146,223, 83, 82, 82, 80,175, 94, 61, 94,112,112,112,107, 66, 72, 39,123, 6, 76, 48,138, 80,103,111,135,171, 40, 0,224, +187,129, 83,175,128,246, 5, 39, 35,201,206,206,158, 55,114, 28,255,189,195, 91, 11,189, 99, 31, 57, 34, 48,228, 77, 4,212, 26, +128, 49,239,218, 48,235,219,131,240, 15,140, 64,114,114, 50, 58,117,234, 36, 74, 79, 79,127, 23,192, 84,123,181, 79,156,184,106, + 59,126,248,200,144,161,195,223,110,214,181,107,111,235,177, 99,135, 17,117,239, 88,244,187,195, 95,207,166, 92, 33,113,113,145, +221,126,244,232, 97,104,100,100, 83,152, 45,150,118,192,172,133, 0, 42,124,168, 60,126, 76, 77,179,103,207,230, 29,218,187,254, +205,145,163,222,105,212,165, 75,119,203,177, 19, 7,112,243,202,137,187,139, 23,142, 57, 55,127,217,246, 78,221,122,190, 94,223, +193,233,234,225,200,250,250,247, 3,157,130, 30,179,146, 82,193,203,202,193,129, 67,241,115,145, 71, 8, 40,165,207,152,171,231, + 13, 22,143,199,171,178,226, 95, 86,179,236,187,168,164, 34,189,106,213, 42, 72, 36, 18,136,197, 98, 8,133,194, 42,187, 89,148, +213,140, 78, 76,236,188,113,203, 22, 73,121,230, 42, 47, 47, 15,121,121,121, 40, 44, 44,196,136, 17, 35, 68,179,111,220,104, 90, +149,102,144,175,175, 81, 46,149,102, 61,120,240,192, 47, 34, 34,226,153,244,170,213,106, 72,165, 82,108,217,186, 85,212,183, 79, +159, 9, 93, 14, 31, 94, 12, 64, 89,221,188, 19, 66,224,229,229, 5, 87, 87, 87, 16, 66, 96,181, 90,145,153,153,137,232,232,104, +220,184,113, 3,124, 66,172,127,231, 53, 46,207,139,188, 10, 17, 44, 82, 81,180,197, 94,131,197,231,243, 95, 40,138, 85, 25,246, + 52, 17,202,100,178,251,233,233,233,109,252,253,253, 97,181, 90, 75, 13,214,243, 77,132, 37,209,142, 59,119,238, 64, 38,147,221, +175, 74,147, 82,218,186, 69,139, 22,216,189,123, 55,206,156, 57,131, 39, 79,158, 64,167,211,193,104, 52, 66,175,215, 35, 58, 58, + 26, 28,199, 33, 50, 50, 18,114,185,188, 74, 77, 0,208,106,181, 25, 66,161, 48, 76, 42,149,254,167,185,195,215, 23,121,121,121, +156,197, 98,193,198,141, 27,213, 62, 62, 62,114,169, 84,106,183, 97, 37,132, 32, 59, 59, 27, 1, 1, 1,165,125,176, 52, 26, 13, +188,188,188, 74, 12, 5,140, 70, 35, 28, 29, 29,171,108, 34,164,148, 26, 0, 76, 41,163,221,124,232,208,161,191,111,219,182,173, +214,201,147, 39,113,237,218, 53,120,122,122,226,187,239,190,123,146,148,148, 52,146, 82,122,227,111,184,193,170,220, 39, 47, 47, +111,215,253,251,247, 91,183,104,209,162,244,233,208,169, 83, 39,210,169, 83, 39,143,178, 33,253,156,156, 28, 92,191,126, 29, 39, + 79,158, 4, 33, 4,241,241,241, 54,189, 94,255,123, 37,223, 45, 10, 14, 14,222, 48,125,250,116,133,213,106, 45, 45,219, 82,169, + 20, 14, 14, 14, 16,137, 68,224,243,249, 72, 74, 74,194,128, 1, 3,156,127,254,249,231,245,132,144,218,148, 82, 51, 94, 17, 10, + 57,165,245,250, 29,189,139,171,107,240,189,203,231,214,183,126,173,248, 25,113,249,220,122,171,171,107,240,189,235,119,244, 46, +237, 3,149, 86, 69, 21, 58,123,143,228, 76, 53,155,111,244, 60,122,228,254,160, 41,147,199,136,131,107,133,100, 93,186,118, 63, +248, 53,219, 20,158, 92, 10,104,245, 64,190, 18,136,121,204,231,130,107,133,100,221,184, 21, 43, 94,252,227,218, 16,157,222,180, +231,240, 41,229,209, 42, 42, 99, 6, 66,200,192,143,191, 18,158,123,123,180,151, 88,228, 16, 8, 77,193, 45,212, 8,118,199,176, +215,195,176, 98,245, 45, 56, 57,185,193,219,219, 27, 60, 30, 79,110,111,222,115,115,115,201,174, 63, 46,188,247,214, 59, 99, 90, +245,232,222,199,122,244,216, 33,193,153,227,251, 47,175, 95,253,213, 30,202,215,202, 8,213, 72, 3,131, 2,238, 37, 62,137, 27, +217,190,125,119, 72,197,178, 58, 64,120,185, 5,182,116,224, 0, 69, 10,143, 7,135,183,222, 25,251, 90,143, 30,253,173,199,142, +237,197,177,195,155,174,206,156, 89,227,240,147,167, 91, 69, 87,110,164, 57, 12, 28,242, 65,193,193, 35, 15, 77,175,247,171, 25, +231, 39,111,172, 7,227,217, 10,164, 64,144,101, 53, 26, 3, 3,122,244,224,235,146,147,133, 10,111,111, 43, 0, 88, 44,150, 42, + 13, 22, 0,206, 30, 77,123,211,162,211,233,192, 1, 86,123, 52, 51,179,179,107, 20, 87,190, 75,177, 88, 44,165,230, 42, 47, 47, + 15, 74,165, 18,114,185, 28, 57, 70,163,183, 61,154,221, 91,182,220, 56,123,214,172,169, 59,119,237, 18,149, 53, 87, 37,155, 80, + 40,196,247, 11, 23,138, 62,249,236,179, 15, 38, 8, 4, 19,171,115, 62, 75, 42,235,124, 62, 31, 2,129, 0,201,201,201, 72, 73, + 73, 65,114,114, 50,146,147,147, 33,149, 74, 65, 43, 56,159, 47, 49,130, 69, 94,165,178, 91,233, 52, 13,213,233,228,110,175, 33, +176,217,108, 47,213, 96,105,181,218,147,167, 78,157,106, 57,112,224, 64,193,213,171, 87,225,227,227, 83,106,176, 74,126,150, 52, + 59,201,100, 50,236,217,179,199,172,213,106, 79, 86,113, 19,157, 58,124,248,112,179, 25, 51,102, 8, 71,143, 30,141, 7, 15, 30, + 96,220,184,113, 80, 42,149, 80,171,213,200,203,203,131, 78,167, 67,203,150, 45,225,224,224,128,123,247,238, 89,116, 58,221,169, + 42, 10, 14,205,206,206, 46,244,244,244,244,125,254,127, 67,134, 12,241,254,229,151, 95,116, 49, 49, 49,150, 54,109,218, 56,217, +107, 52, 74,248,227,143, 63, 74, 35,115,113,113,113,248,229,151, 95, 74,251, 92,221,186,117, 11,139, 22, 45, 42,157,187,172,154, +133,253, 70,253,250,245,173, 22,139, 5,117,234,212,129,191,191, 63, 12, 6, 3,150, 46, 93,106,253, 59,204,149,189, 24, 12,134, +157,111,191,253,246, 23,183,111,223,246, 21, 8, 4, 69,161,235,226,252,153,205,102, 60,122,244, 8,209,209,209,136,137,137, 65, +126,126,126,105, 5,224,206,157, 59, 5, 22,139,101,123, 69,186,158,158,158, 95,175, 91,183,206, 71, 38,147, 61, 83,158, 75,162, +159, 37, 81,209,156,156, 28,184,184,184,160, 75,151, 46, 94,167, 78,157,250, 26,192,140, 87,225, 97, 64, 8, 33,109, 90, 41,218, +126,252,193, 59,104,209, 84,243,248,254,173, 40,156, 56,188,172, 33, 80,212,201,189, 65,211,200,199,215,111, 59,162, 87,247,169, +109, 47, 93, 29, 87,105, 39,247,226, 62, 84,135, 91,182,116,187,184,119,255,201, 21,211, 38,143,185,254,205,172,105, 94, 6,163, +214, 33,188,182,141, 7, 20,153,171, 43,183,229,134,185,179,198, 92, 95,240,227, 70, 46, 37,219, 60,233,218,181,130, 10, 71,247, +150, 53, 45,245,235,194,193, 39,184, 79,122,112,173, 78, 53,239,223, 90, 11, 15,231, 2, 56,214,105,131, 94, 61, 90,226,228,169, +251, 72,126,106, 64, 70, 70, 6,140, 70, 99,165,211, 30,196,220,219,243, 38, 37, 52,136, 80,146, 66,120,212,225,205,183,223,111, +215,167, 79,127,122,240,224,126,235,222, 61, 91, 46,110,223,188,124, 39, 79, 36, 20,232, 77,206, 38, 66, 12, 42,142,231,248, 64, +171,205, 43,122,120,138, 68, 21,135, 91,139, 39,100,141,168, 31,238,243,230,219,227,156,123,247, 26, 64, 15, 31,222,203,109,223, +182,241,204,246,181, 13,182,112, 60,181, 40, 35, 85, 39, 81,169, 45, 42, 74,196, 46,133,106, 78,151,149, 80,219,224,215,103,136, + 25,140,103,223, 3, 70, 99, 90, 97,106,170,175, 91,135, 14,146, 71,179,102,201,188, 91,182, 52,144,226, 62,194,149, 25, 44, 62, +159, 15,240,120,156, 61,154,246,166, 69,175,215,131, 3, 44, 47,162,105,181, 90,159, 49, 87, 37, 6,171, 36,158, 97,143,230,234, +153, 51,175, 6,245,232,145,127,246,236, 89,239,142, 29, 59, 18,141, 70, 3,141, 70,243,140,201,242,243,243, 35, 17,145,145,178, + 63,206,156, 9,153, 97,231,249,180, 39,239, 60, 30,239,111, 55, 88,175, 92,212,181,178,127,150, 68,176,236, 49, 88,118, 70,176, + 44, 22,139, 5, 94, 94, 94,200,205,205,173,240,133,207,227,241, 32,149, 74, 75,218,128, 43, 29, 73,103, 52, 26,151, 78,157, 58, +245,163, 94,189,122,121,132,133,133, 33, 39, 39, 7,222,222,222,112,112,112, 40,237, 27, 86,162,119,235,214, 45,172, 91,183, 78, +109, 52, 26,151, 86,161,185,100,225,194,133, 31, 14, 30, 60,216,205,199,199, 7,174,174,174,184,119,239, 30, 92, 93, 93,161, 86, +171, 17, 27, 27, 11, 71, 71,199,210,126, 57,251,247,239,215, 24,141,198, 37, 85,152, 54,122,254,252,121,179,163,163,227,189,156, +156, 28,126,126,126,190,160,160,160, 64,160, 86,171,133, 42,149, 74,120,244,232, 81, 15,103,103,103,221,233,211,167,115,130,130, +130,248, 79,158, 60,225, 91, 44, 22,158, 29, 47, 69, 76,156, 56, 17, 34,145, 8, 70,163, 17, 75,151, 46,197,212,169, 83, 75,251, + 92, 45, 92,184, 16,211,167, 79, 47, 53,204,107,214,172,169,174,201,130,217,108,134,197, 98,129,197, 98,177,203,244,254, 21,236, + 49,234,148,210, 76, 66, 72,223, 22, 45, 90, 28,223,177, 99,135,123,241,156, 98,200,202,202, 66, 86, 86, 22,114,114,114, 80, 88, + 88, 8,171,213, 10,127,127,127,100,101,101, 97,239,222,189, 42,141, 70,211,163,178, 17,132,124, 62,255,237,118,237,218, 9,158, + 79, 67, 73,173,174,196,180, 75, 36, 18,164,167,167,163, 83,167, 78,226,179,103,207,190,253,191,110,176, 74,140, 75,189, 80,136, +250,245, 31, 33,106,220,172,167,238,250,205,163,201, 82, 98, 77,238,221,181,206, 14,160,104,154,134,235,183, 29,209,184, 89, 79, + 94,191, 12, 83, 75,101,193,234,198, 17,117,137,185,178,101,117, 0,192,195,153, 27,208,163,107,141, 12, 39, 39, 34,152, 59,107, +193,129,223, 54,173,105,113,229,143,255, 76,211, 48,119, 86,209, 52, 13, 61,186,214,176, 62,136,137, 27, 0, 96,147,189,166,165, +111,223,126,183, 87,175,221,140,180,132,253,126, 43, 22,184,136, 97, 40, 0,132, 97,104,215,202, 9,215,126, 74,193,221,187,119, + 51, 77, 38, 83,167, 74,203, 18,161, 65,209, 15,162,234, 54,168, 31,225,243,230,219, 99,157,250,246, 29,128,131, 7,247, 97,243, +198,181,231, 95, 31, 49,248,183,167, 5,106,190,151, 80, 38,146, 81, 78,204, 23, 57, 11, 28,100,178,108,115,122,122,209,195, 83, + 32,116, 2,134,114,149,180, 16, 98,252,216, 81,206,157,187, 14,192,161,195,251,176,121,227,234,115,223,212, 31,178,182,102,147, +122,164,101,211, 31, 62,168, 89,171,102,176,182, 48, 75,205, 35, 98,179,193,192, 57,254,176, 49,233,199,132,233,111, 39,220,142, + 26,186,152,141, 34,124,134,123,155,123,247,110,241,201,227,199, 34,207,182,109,165,233,103,206,200,138, 87, 14,169,212, 96, 9, + 4, 2,208,138,155,180,158,209, 36,155, 54,241, 0, 84, 58,184, 74, 36, 18, 65,167,211,193, 2,152,237,209,244, 61,118, 44,245, +241,227,199,161,110,110,110,207,152,171,252,252,252,210,223, 13, 6, 3,116, 58, 29,164, 82,105,180, 61,154, 89,231,207, 27, 22, + 76,156, 56, 99,228,136, 17,203, 79,158, 58,229,224,238,238, 14,149, 74,245,140,193, 50,153, 76,232,220,165,139,104,225,237,219, +111, 2,152,105,207,249,244,238,212,169,202,254,190,124, 62, 31,220,223,220, 68,248,170,193,171,170,169,198,222, 81,132,229,189, + 24, 9, 33, 93,159,251,104,122,179,102,205, 12,113,113,113, 8, 10, 10, 42, 53, 41,101,191,211,201,201, 9, 46, 46, 46,184,117, +235, 22,230,205,155,167, 7, 48,189, 50, 77, 74,169, 70,167,211, 13,239,214,173,155, 94, 32, 16, 32, 60, 60,188,116,254, 43,142, +227, 32, 22,139, 33,151,203,113,251,246,109,244,235,215, 79,167,211,233,134, 63, 63, 7, 86, 57,154, 42,157, 78,247, 70,247,238, +221,117, 15, 30, 60, 64,187,118,237,112,247,238, 93, 20, 22, 22,162,176,176, 16,137,137,137,136,136,136,128, 78,167,195, 47,191, +252,162,215,233,116,111, 80, 74, 85,149,105,106, 52,154,126, 83,167, 78,229,255,254,251,239, 53,253,253,253,235, 55,111,222, 60, +172, 75,151, 46,181, 7, 13, 26, 20,220,187,119,111,223,208,208, 80, 67,143, 30, 61, 60,123,245,234,229,169,211,233,132,151, 46, + 93,202,176, 88, 44,189,170, 56,159,165,166, 36, 46, 46,174,180, 73, 80, 32, 16, 32, 55, 55,183,116,166,253,146,135, 81,121, 6, +184, 34,205,178, 38,187,196, 88,149, 24,173,170,158,253, 21,104, 86,249,194, 16,139,197, 37, 17, 78, 90,149, 38,165,244,206,195, +135, 15,187,117,232,208,225,206,123,239,189,167,201,204,204,132,163,163, 35, 66, 66, 66, 80,183,110, 93,120,120,120,192,108, 54, + 99,207,158, 61,218,189,123,247,222, 87,169, 84,157,158,159, 3,235,121, 77, 30,143,151, 88,222,195,181, 36,122, 85, 98,176, 28, + 28, 28,224,239,239, 95,114,110, 19,171,115, 62, 95, 48,178,244,247,106, 22, 27,151, 46,157,123,212,234,221,103,160,243,222,253, +251,100, 63,253,186,225, 97,251, 1, 31,173,244, 8,158,178,219, 35,120,202,238,246, 3, 62, 90,249,211,175, 27, 30,238,221,191, + 79,214,187,207, 64,231, 46,157,123,212,122, 16, 29, 19,246,204,186,132,229,164, 83, 38,150,180,108,223, 38, 84,121,254,210,121, +235,130, 31, 55,218,218,188,214,251,218,242,229, 43,183, 47, 95,190,114,123,155,215,122, 95, 91,240,227, 70,219,249, 75,231,173, +237,219,132, 42,101, 98, 73, 75,123,242, 62,126,236, 40,231, 62,189, 7,224,224,193, 61,214,157,127,252,178,112,205,230,244, 14, +157, 6,165,101, 37, 38,220,160,208,109,128,135,227, 61, 60,124,248, 80,101, 50,153, 58,149,215,193,189, 60,205,113, 99, 70,149, + 53, 87, 23,220,125,218,173,121,248, 16,182, 19, 39, 14, 88, 78,157,186,173,191,112, 39, 91,117,243, 65,110,126,158,218,240, 68, +171, 81,155, 56,142, 3,229,108,252,217,179,139, 58,226, 86,116,141,218,180,233,136,211, 39,183, 98,227,134, 85, 42,142,131, 97, +200,142, 29,182,161, 67,103,209,224, 26, 53,130,183,252,177,149,244,237, 63,208,153, 2, 92,191,193, 3, 92,126,223,246, 59,169, + 85,167, 86,141,144,144,162,169,105,254, 39,203,210,223,160, 57,147,210, 2,117,114,242,185, 91, 63,255,108,244, 30, 62,220, 77, +236,237,237, 4,155,141,148, 60,223, 43,218, 4, 2,193, 51, 17,151,202, 52,253, 61, 60,158,238,223,191, 31,117,235,214,133,191, +191, 63,202,246,129, 45,153, 72,219,221,221, 29,187,118,237, 2, 5,110,218,163,217,164,102,205, 91,223, 47, 88, 96,226, 56, 14, + 5, 5, 5,127,138, 94, 21, 20, 20,128,227, 56, 28, 62,116,200,164, 46, 44,220,104,111,222, 59,241,249,133, 35,219,183,159,223, +167, 79, 31,243,227,199,143,193,113, 28,202, 70,178,178,179,179,161, 80, 40, 96, 48, 26, 3, 9, 33, 50,123, 52,179,143, 30,149, +163,138,231,250,243, 17,172,191,227,186,255,171, 34, 88, 86,171, 21,129,129,129,207, 44,189,194,227,241,158,217,170, 51,130,144, + 82,186,137, 16,114,172, 71,143, 30, 51, 90,181,106, 53,126,198,140, 25,252,176,176, 48,168, 84, 42,184,186,186,194,203,203, 11, +177,177,177,216,191,127,191, 45, 55, 55,119, 37,128, 57,246, 12,133,167,148,158, 33,132,244,109,216,176,225,182,105,211,166, 57, +119,239,222, 93, 24, 24, 24, 8, 74, 41,110,223,190,141,221,187,119,155,215,174, 93,171, 46, 54, 87,103,236, 76,235,113, 66,200, +235,189,122,245,218,242,246,219,111, 59,218,108, 54, 97, 98, 98, 34,140, 70, 35, 44, 22, 11, 82, 82, 82,204, 7, 15, 30, 44,212, +233,116,163, 40,165,199,237,208,187, 69, 8,137, 56,113,226,196,219,151, 46, 93,154,247,222,123,239,185,119,233,210, 69,100,181, + 90,113,241,226,197,156, 38, 77,154,120,101,103,103,155,119,237,218,149,103, 48, 24,166,219,108, 54,187,150,202, 33,132, 64,173, + 86,195,195,195, 3, 70,163, 17, 28,199,193,100, 50, 65,161, 80,148, 46,111, 68, 41, 69,117, 58,205, 63, 87, 6,248,102,179, 25, + 35, 70,140, 0,199,113, 88,186,116, 41,172, 86,107,181,197,156,157,157,111,222,185,115,167,111,227,198,141, 75, 77, 75, 73, 25, +146, 72, 36,240,240,240,128,187,187, 59, 14, 30, 60, 8,161, 80,120,211,206,107,116, 23, 64, 19, 66,200,107,247,239,223,127, 11, + 64, 99,179,217,236,111,179,217, 8,143,199,203,160,148,222, 83,171,213,191,217,187, 84, 78,118,118,246,188,119,222,121,167,201, +214,173, 91, 21, 2,193,127,110, 13,129, 64, 0,137, 68,130,146, 73, 45, 41,165, 48,153, 76,248,250,235,175,213, 90,173,118,222, +171,242, 48,104,214,188, 37, 86,255,178, 76,113,234,244,177,156,135,241,216, 87,118, 42, 6, 5,128, 75, 87,199,237, 83, 22,172, +110,156,158,154,170,104,214,188,165, 93,154, 38,155, 53,111,248,168,149,129,197, 75,229,204, 75,124,146,188,100,235,134,247, 19, + 0, 96,241,143,107, 67, 82,178,205,147, 30,196,196, 13,248,117,229,217,150, 38,155, 53,207, 30,205,255,152,150, 45, 42, 80, 24, + 40,165,215, 8, 33, 53,195, 94, 51, 76,143, 12, 23,245, 79,207,178, 60, 45, 44, 52,125, 76, 41, 77,176, 55,239,109,219,116,192, +233,227,191, 99,243,198, 45,106,202,241, 13, 30, 30, 30, 20, 0, 30, 62,244,160, 15, 31, 42,233,127,250, 11,187,104, 61,101, 57, +115,166,127, 57,126,178, 70,163, 89,178,226,135,202, 39,156,109,216,168, 21, 26, 54,106,133,143, 62,254,202, 57,162,126,120, 16, + 0,236,216, 65,109,145,161,228,192,140,111,102,245,159, 51,103, 22,212, 26, 35,230,204, 41, 90, 86, 39, 54,234,193,161,199,143, +169,137,189,154,158,101,134,213,122, 13,147, 39,135,234,242,243, 61,219,126,241,133,135,224,179,207,120,149,117,114, 47,123,255, +218,163,121,227,222,189, 67,227,222,127,255,233,204, 25, 51,122,172, 92,181, 74,218,160, 65, 3,100,102,102, 34, 60, 60, 28,254, +254,254, 56,113,226, 4,118,109,223,174, 85,106, 52,211, 1,252,106,143,230,166,195,135, 99,195,234,215,207, 93,181,106,149, 95, +159, 62,125,136, 86,171,133, 74,165,130, 74,165,130,209,104, 68,241, 68,206, 52, 46, 62,254,161,197, 98, 89,105,111,222,109, 57, + 57, 14,115, 90,182, 76, 19,113,220,247,175, 15, 30, 60,117,206,220,185,146, 90,181,106, 17,163,209, 88, 26,197, 50,155,205, 80, + 40, 20,102,147,201,228, 14, 64,103,143,166,100,237, 90,107, 78, 78, 14, 60, 61, 61, 75,167, 93, 42, 59,175,160, 70,163, 1,165, +108, 18,220,106, 85, 20, 42,122,135,187,185,185,221, 20, 8, 4, 1,101,163, 89,229,173,109, 87,246, 51,139,197,146,150,147,147, +211,172,172,195,165,148,158,172,192, 24,132, 0,248,174,115,231,206,175, 79,153, 50,133,156, 61,123, 22,123,247,238,165, 9, 9, + 9, 59, 1, 76,175,232,225, 88,133,166,163, 68, 34,249, 84, 46,151,119, 45,153,138, 65, 38,147,221,215,106,181, 39,141, 70,227, +210,138,102,111,175, 66,211, 73, 34,145, 76,148,203,229,221, 52, 26, 77, 99, 0,112,116,116,188,163,213,106, 79, 24,141,198,101, + 21, 45, 32, 93,133,166,212,217,217,121,158,135,135,199, 27,159,125,246,153,251,249,243,231, 51, 78,159, 62, 45, 82, 42,149, 91, + 77, 38, 83,133,139, 61,151,167,233,238,238,126,147,207,231, 7,252, 29,215, 8, 0, 26, 53,106,116,176, 95,191,126,125, 70,141, + 26, 5,139,197,130, 95,127,253, 21, 39, 78,156, 56, 20, 31, 31,223,183,178,218,231,243,154,132, 16,143,128,128,128,179,227,199, +143, 15, 30, 49, 98,132,204,213,213, 21, 2,129, 0, 90,173, 22,143, 30, 61,194,237,219,183,233,190,125,251, 10,111,221,186,149, +166,211,233, 58, 82, 74,115,237, 61,159,127,165,150,252,188,166, 80, 40,236, 16, 24, 24,248,199,204,153, 51, 29,187,117,235, 38, +117,119,119, 7,159,207,135,197, 98, 65, 70, 70, 6,162,162,162,112,236,216, 49,237,206,157, 59,181,121,121,121, 35,158,159,171, +229,255, 43,157, 47, 83, 51,162, 46,249,230,185, 5,156, 43,156,157,189,178,125,237, 73,103,159,174,174,189, 95,127,189,121, 87, + 0,216,181,235,198,201, 67, 39, 11, 14,191,104, 58,171, 74,171, 61,154,245, 66,249, 51,163, 31, 68, 61, 51, 17,101,253,136,200, +184,122, 13, 6,127,107,143, 86,201, 76,238,207,231,189,204,236,248,101, 99,184,207, 52,167,150, 44, 8,253,213,244, 47,241,221, +188,249,216,183, 99,207,161, 7,143,233,193,255,229,178,244,119,106,150, 44, 78, 44,243,245,109,191,148,227,190,188, 27, 21,165, + 40, 91, 81, 43,137, 52,151,173, 76,250,249,249,101,167,167,167,123,219,163,217,247,167,159,204, 58,185, 92,242,229,247,223,119, + 40, 52, 24, 58,204,153, 51, 71,112,227,198, 13,252,242,243,207, 86, 67, 90,218,150, 28, 96, 98,121,173, 31,149,105, 6, 79,156, +232,240,249, 47,191,140, 14,169, 83,199,235,173,183,222, 18, 10,133, 66,104,181, 90,164,166,166,226,248,177, 99,166, 7, 15, 31, + 62, 80,171,213,253, 41,165,233,246,106,246,253,233, 39,179, 75, 72, 8,100,158,158,244,212,153, 51,206,227, 62,253,116,124,141, +154, 53,157,123,244,236, 41,116,114,114, 66, 65, 65, 1, 18, 19, 19,177,103,207,158,236,194,194, 66, 63, 74,169,205, 30,205, 45, +151, 46, 53, 60,124,238,220,144,111,191,253, 86, 28, 25, 25, 9,103,103,103,104, 52, 26, 68, 69, 69,225,220,185,115,198,149, 43, + 87,170, 84, 42,213,120,171,213,186,255,239,186,238,255, 26,131,245,255,117,227, 17, 66,154, 1,248,166,248,207,185,118,172,233, +247,202, 60,116, 8, 33, 65,110,110,110,171, 13, 6, 3,213,235,245,227, 40,165, 41,255,180,116, 18, 66, 4,205,154, 53,251, 37, + 59, 59,251, 53, 74, 41,156,157,157, 47, 71, 71, 71, 79,160,148, 90,171,171, 73, 8,225, 3,120, 77,161, 80,180,116,116,116,236, + 96, 52, 26,235, 21, 55,179, 61,212,106,181,231,204,102,243, 53, 0,151, 41,165,182,255,102,222,139,211,217,205,207,207,239,125, +142,227,234, 16, 66, 92,108, 54, 27, 44, 22,139,146,227,184, 71, 42,149,106, 45,128, 19,255,237,116,190, 44,205,250,117,200, 32, +202, 67,189,138,140,192, 51,134,230, 57,227, 64, 56, 60,140,126, 68,247, 84,163,204,243, 6,246,242, 92, 4, 20,141, 52,172,106, +201,161,103, 12,150, 29,166,165,218,230,178,142,224, 29, 74,104,208,179, 15, 69,146, 18,222,112,208,230,191, 98,176,236,165,126, + 24,233, 0,138,215, 56,138,107, 15,227,233,233, 87,245, 89,247, 50, 53,231, 19,226,246,179,171,235,101,158, 64,224, 3,128, 87, + 28,109,225, 56, 66,108,148, 16,107,217,102,172,178, 21,202,170, 52,205, 64, 3,161, 68, 18,104,179, 90,189, 51, 1,197, 97,155, +173,169,129,210,194, 0,224,155,219,148,198,190, 72, 58,205, 64, 3,190, 68, 18,116,152,210, 1, 57,114,121,195,108,189,222, 19, + 0, 85,200,229, 15,213, 90,237, 70,131,193,176,162,156, 69,213,171,212, 20, 73, 36, 1, 54,171,213, 27, 0,120, 2, 65,246, 54, +163, 49, 48,205,201,233, 45,131,209, 24,172, 80, 40, 44, 38,147, 73,109, 48, 24, 70, 89, 44,150, 83,213,201,251, 35,171, 53,226, + 18,143,215,206, 44,151,187,155, 9,145,155,172, 86,179,201,108, 78, 53, 24, 12,247, 1,252, 72, 41,125,252,119, 94,247, 87,142, +146,209,102,127,199, 6,160, 43,211,100,154, 76,147,105, 50, 77,166,201, 52,255,126, 77, 0, 50, 0, 65, 0,248,255,139,121,127, +213, 54, 1,179,152, 12, 6,131,193, 96,188, 18, 1, 19, 29,202,233,115,197,248, 47, 53, 17, 2,232, 90,193,133,178, 59,244,247, + 34,163, 9,236,104, 74, 96,154, 76,147,105, 50, 77,166,201, 52,153,230, 43,166, 89,149,246, 43,211,244,200,154, 8,153, 38,211, +100,154, 76,147,105, 50, 77,166,201,154, 8, 95,238,198, 3,163, 34,103,237, 77, 8,241,126,217,251, 50, 94,237,178, 80,206,177, +254,132, 16,255,106,238,239,203,206, 58,131,193, 96,252,111,243,255,110,176,236,125, 89,253,197,151,218, 95, 50, 60,132,144,249, +132, 32,189,104, 35,243, 95,214,190,118,124,175,159,167,167,231, 39,245,235,215,223,226,227,227,243, 17, 33,196,171,154,199,135, +202,229,242,101, 10,133,226,172, 66,161, 56, 43,151,203,151, 17, 66, 66, 95,210,117, 35,132,144,113, 14, 14, 14,103,252,252,252, +158, 74, 36,146, 51,132,144,241,228, 5, 23,160, 36,132,212, 38,132, 76, 38,132, 76, 33,132,132, 85,231, 88,239,200,129,219,189, + 34, 7,222,243,138, 28, 24,229,209,160,127,168, 87,228,192, 40,175,200,129,247,188, 35, 7,110,255, 27,202,235, 11, 95,223,226, + 99, 83,138,182,170,143, 37,132,252, 72,128, 84, 66,144,246, 87,203, 18,131,193, 96, 48,254,187, 84,171,147,123, 64, 64, 64, 47, +142,227, 70, 2, 0,143,199,251, 61, 45, 45,237,200, 11,188,112, 62, 47,254,125, 33,165,244,203,191,178,159, 29,199, 46,161,148, + 78,173,190, 57,195,231, 28, 71,121, 69,249, 36, 95,120,123,123,203,248,124,254,159, 58, 14,218,108, 54, 25, 33,248,136,227,138, + 22,168,228,241,200,231,132,144,101,148,210,172, 23, 49,133,111,190,249,230,146,101,203,150, 57,200,100, 50, 36, 39, 39,119, 31, + 63,126,124, 27, 66,200,100, 74,105, 70, 85,199, 75,165,210,145, 45, 90,190, 54,249,251, 31, 22, 43,188,189,188,228, 86, 27,103, + 78, 76, 78,146,125, 61,109,106, 75,169, 84,186,172,178, 69,142,159, 55, 82, 0,198, 10, 4,130, 97, 14, 14, 14,181, 13, 6,195, + 99,171,213,186,147,207,231,247,152, 55,111, 94,100,239,222,189, 29,212,106,181,216,106,181,214,217,188,121,243,228,117,235,214, +245, 34,132, 12,168,108,184,125, 73, 4,135, 82,250,180,204,199,189, 82, 82, 82, 26, 8,133, 66,212,174, 93,155, 0,136,173, 98, +255, 82, 40, 16, 26,125,113, 71, 3, 0,168,223,118,104, 92,244,197, 29, 40,254,253,111,168, 12, 60, 91, 22,164, 82,233,175,122, +189, 62,181,228,255,197,233,204,178,231, 88, 66,200,242,226,101,126, 34, 1, 12, 46,222,117, 55,165, 52,138, 16,226,227, 32,145, +124,170, 55, 24, 8, 0,242, 87,202, 18,131,193, 96, 48,254,199, 12, 22,165,244,173, 71,143, 30,201, 56,142, 67, 88, 88,216,155, + 0,236, 54, 88,229,189,112,186,116,233,210, 68, 42,149, 62, 51,107,177, 94,175, 23, 19,130, 46, 47, 98, 90, 74,190,195,100, 50, +242,132, 66, 49,120, 60, 50,185, 97,195,134, 53,114,115,115,207,243,120,188, 45,105,105,105, 5, 47,240,146,197,154, 53,107,234, +250,250,250,254,105,118,229,140,140, 12,241,128, 1,253,171,165, 55,154, 16,137, 81, 34,105, 41, 34,196,215,102,181,186, 0,128, + 64, 32, 40, 8,115,118,110,246,221,183,223,202, 8, 33, 92, 94, 94, 30,244,122, 61, 38, 77,154, 36,125,240,224,193, 64, 0, 43, +170, 72, 99,221, 86,173,219, 76, 58,118,236,104, 61,117,126,129, 97,205,146, 85,183,244, 2,145,174,102, 68,184,232,151,213, 27, + 93,199,142, 30,245, 49, 33,228, 78,121,203,134, 60,167,195, 3,176,231,211, 79, 63,173,223,183,111, 95,177, 70,163,113,208,235, +245, 53,182,108,217,242,117,179,102,205, 20,141, 27, 55, 22,255,241,199, 31, 68,165, 82,129, 82, 42, 11, 15, 15,167,195,134, 13, + 51,108,219,182,237, 35, 0,203,237, 49,188,190,190,190, 51,138, 13,122,217,178, 39,244,243,243,147, 22,159,211, 57,132, 96, 82, +101,230,154, 0,241,245,219, 14, 5, 8,234, 68, 95,220,225, 80,191,221, 80, 3, 40, 30, 17, 32, 30, 0,252,253,253,231, 0,101, +230,117,122,150,135, 79,159, 62,125,161,181, 3,251,244,233, 11, 0,191,250,251,251, 31,204,202,202,138, 36, 4,227,236,173, 4, + 16, 66,224,238,238,254, 58,128,159, 0, 12,143,137,137,169, 15, 0,225,225,225, 66, 0, 81, 46, 46, 46, 77,141, 69,230,138,193, + 96, 48, 24,255, 66,131, 37, 2,128,243,231,207,131, 82, 42,126,145,160, 64,217, 23,206,196,137, 19,225,235,235,251,188,105,193, +217,179,103,254, 74,158,158,249,142,185,115,231, 42,148, 74,101,215,223,126,251,173,189,191,191,255,162,167, 79,159, 94,173, 34, +143, 89,132,144,133,197, 17, 7, 72, 36, 14,113,227,199,143,191, 93,252,239, 26, 7, 14, 28,144,245,235,215, 79, 7, 32, 9, 0, + 36, 18, 7,127, 62,159, 87,183,168, 83, 27, 22, 86,102, 4,135, 18, 18, 34, 22,139, 59,143,251,233, 39,107,211,126,253, 4,114, + 79, 79, 2, 0, 73, 49, 49,238, 11,127,248,161, 77, 65, 66,130, 88,239,238,158,151,167,213,234,227,226,226, 32,145, 72, 8,159, +207,111, 90, 85,134,229,114,249, 39,223,126,247,189, 92,157,175,212, 27,212, 26, 19,223,106, 49, 58, 74,101,182,172,204,236, 60, +133, 84,174,251,226,155, 89,226, 15,199,188,253, 9,128, 9, 85, 72,125, 52,121,242,228,122, 45, 90,180,240,223,190,125, 59, 81, +169, 84, 16, 8, 4,138,198,141, 27,163, 89,179,102,182,211,167, 79,147,154, 53,107, 34, 50, 50, 18, 23, 47, 94,196,229,203,151, + 73,147, 38, 77,100,187,119,239,126,179, 60,131, 85,142,169,158,220,186,117,235, 64,133, 66, 97, 80,171,213,120,239,189,247, 0, + 0,221,186,117,171, 43,151,203,127, 45, 44, 44,116,216,191,127,223,235, 85,153,235,172,168,189,195, 0,192, 43,114,224, 61, 0, + 13, 64,241, 40, 59,106,111,195, 50,187,212,139,141,141,109, 85, 80, 80, 80,218,217,176,100, 97,241,246,237,219, 87,167,188,103, + 17, 66, 22,246,235,215,247, 11,128,160, 83,167, 78, 89, 19, 39, 78,164, 81, 81, 81,131,134, 14, 29,210, 37, 62,254, 81,133,233, +124,190, 28,141, 28,249,198, 19, 55, 55,183,110,126,126,126,241, 0, 4, 66,161,176,100, 87,190,191,191,191, 91,100,100,228, 8, +133, 66,145,200,231,241,106, 82, 80, 90, 85, 89, 98, 48, 24, 12,198,255,128,193, 34,132,208, 50, 47, 6, 82, 73, 45, 60,247,206, +157, 59,190, 6,131, 1,132,144, 92, 59, 94, 80, 39,203,190,112,248,124,254, 47, 60, 30,153, 64, 8, 65,100,100,131, 39, 75,151, + 46, 45,111,205, 45, 83,100,100,131, 39,124, 62,175, 22,165, 20,132,240,126,229, 56, 91, 86,121,154, 21,189, 16,197, 98,201,231, + 0,224,227,227,155,112,228,200, 17,211,144, 33, 67,240,195, 15, 63,136,166, 77,155, 54, 53, 56, 56,248,163,228,228,228,204,138, +210, 89,252,247,151,222,222,222,178, 53,107,214,212, 29, 63,126,252,237,244,244,244, 47, 1,192,207,207,111, 62,128, 8, 0, 73, +101, 62,195,202,149,219,158,142, 25, 51, 38, 46, 43, 43,235,203,138, 52, 95, 39,164,118,112,120,120,231, 57,231,207, 83,158,209, + 72,114, 47, 92, 80,231,100,101, 89, 30,231,228,200, 54,220,188,217,247,235,249,243,133,129, 65, 65, 56,187,127,191, 71,174, 78, +151,163, 50, 26, 13, 89, 89, 89,212,106,181, 94,182, 35,239,245,189, 60,189,100,171,126,252,245,134,163,144,207,121, 5,248, 19, +161,155,155,128, 39,115, 18,243, 5, 60, 99,173, 26,161, 98, 0,245,171,186, 70, 34,145,232,205,238,221,187,203,182,109,219, 70, + 34, 35, 35,225,226,226,130, 11, 23, 46,224,206,157, 59, 40, 40, 40,224, 89, 44, 22, 52,111,222, 28,223,127,255, 61,130,130,130, +160, 84, 42,145,146,146,226, 33, 22,139, 61, 43, 57,159,207, 24,222,169, 83,167, 34, 48, 48, 16, 86,171, 21,249,249,249,176, 90, +173,144,203,229, 0,128,164,164, 36, 28, 56,176,191,202,178,100,167, 57, 66,235,214,173, 53,132,144,135,207, 71,176,170,163,233, +235,235,187, 49, 39, 39,183, 73,167, 78,157,160, 82,169, 76, 51,103,206, 68,195,134, 13, 17, 26, 90,215,158, 50,255,165, 68, 34, + 89, 27, 20, 20,244,205,103,159,125,230,230,230,230, 6,163,209,248,113, 70, 70, 6,198,143, 31, 95, 28, 21,235, 19, 46, 16, 8, + 54,188,247,222,123,168, 81,163, 70,140, 70,163,137,189,115,231,206,180,194,194,194, 7, 47,154,119, 59,207, 15,211,100,154, 76, +147,105,254,163, 52,237,245, 34,255, 83, 6,139, 82, 74, 8, 33,180,170, 12, 81, 74, 11,252,253,253,125,165, 82, 41, 40,165,213, +110,110,179,217,108, 31,121,120,120,100,127,249,229,151,109,235,214,173,107,250,232,163,143,162, 18, 19, 19,167,151,221,167,102, +205,154,243,126,254,249,103,196,197,197, 37,205,159, 63,255, 98,110,110,238,220,106, 94,244,105,132,144,165,197,209,176,220,253, +251,247, 55, 60,127,254,252,132, 37, 75,150,120,126,248,225,135,162, 79, 62,249,100, 20,128, 31,170,210,225,243,249,186,242,154, + 5, 43,120, 9,155,202,235,163, 85, 66, 63, 66,164, 78, 98,113,167, 57,231,207, 83, 83, 82,146,110,221,226,197,142,171,174, 95, +159,105,161,212,219,203,203, 11,237,218,180, 41,116,224,243,115,179, 51, 51, 57,175,218,181,249,137, 71,142,120,232,197,226,244, +109,219,182,169,242,242,242,246,218, 81, 40,213, 28,165, 38, 69, 64,144,101,200,192,110,145, 55,174,221,137,113,244,242,224, 53, +105, 28,217, 48, 38, 46,233, 22, 56,206, 76, 8, 81, 87,165,227,236,236, 92, 55, 47, 47, 15,106,181, 26,158,158,158, 88,186,116, + 41,124,124,124,160,211,233, 16, 29, 29, 77, 3, 2, 2,200,249,243,231, 17, 16, 16,128,156,156, 28,152, 76, 38,104, 52,154,108, +163,209,168,175,200,240, 10, 4,130,181, 60, 30,121, 31, 0,106,212,168,249,240,215, 95,127, 53, 0, 64,189,122,245, 48,104,208, + 32,236,218,181, 11, 15, 30, 60, 0,199,113,160,148, 26, 2, 2, 2, 31,242,120,164, 94,177, 71,122,225, 40, 78,201, 18, 60, 79, +159, 62, 29,252,130, 55, 58,241,241,241, 25, 20, 30, 30, 62,106,228,200,145, 38,161, 80, 8,157, 78, 7,157, 78,135,135, 15, 31, +154,122,244,232,145,213,175, 95, 95,239, 67,135, 14, 85,154, 78,163,209,248,196,207,207,111,234,228,201,147,151,174, 92,185,210, +233,235,175,191,134,205,102, 3,199,113,165, 63, 75,126,223,187,119, 47, 18, 18, 18,150,149, 53, 87, 12, 6,131,241,111,193, 94, + 47,242, 63,101,176,254, 63,225,243,249,171,142, 31, 63,222,184,125,251,246,130, 46, 93,186, 68, 6, 4, 4, 68,166,165,165, 69, + 1, 64, 64, 64, 64,100,207,158, 61, 35,189,188,188,176,108,217, 50, 29,159,207, 95,245,130, 23,169,236,203,238,182,175,175,239, +162,221,187,119, 47, 28, 55,110, 28,124,124,124, 34,254,191,243,236, 36,145, 52,121,111,233, 82,171,208, 98,225,253,180,104,145, +211,226, 51,103, 22,110,223,177, 67,208,186,117,107, 66, 41,197,253,123,247,164,223, 47, 95, 46, 27, 49,112, 96, 82,108, 66,130, +117,223,177, 99,150,172,167, 79,243,159,230,228,204,160,148,230, 87,165,111,177, 88,174,196,199,199,251,181,235,208,218,255,220, +245,168, 59, 67, 6,246,238, 44, 20,240,200,163,164,180,155,190, 62, 30,206,103,207,156,212, 91, 44,150, 43, 85,233,104,181,218, + 68,171,213,234, 70, 41,245, 60,123,246, 44, 60, 61, 61, 81, 80, 80, 0,139,197, 2,147,201,100,210,233,116, 14,121,121,121, 48, + 24, 12, 48, 26,141,112,114,114,194,253,251,247,179,172, 86,235,233,138, 52,173, 86,235, 88, 7, 7,135,239, 40,165, 66,163,209, +152,126,242,228, 73,136, 68,162, 64,103,103,231, 47, 45, 22, 11,210,211,211,113,233,210,165,249,102,179, 57,181,228, 24,177, 88, +226,105, 52, 26,173, 21,117,114,183, 55,130,245,162, 4, 4, 4,248,213,172, 89,115,242,180,105,159,215,105,216,176, 49,114,115, +115,193,113, 28, 20, 10, 5,116, 58, 29,156,156,156,240,218,107,175,221,158, 55,111, 94, 62,165,152, 86,149, 9, 76, 79, 79,207, + 11, 10, 10,154, 49,126,252,248,201,117,234,212, 9, 2,128,208,208, 80,116,239,222, 29, 71,142, 28, 65, 92, 92, 28, 10, 11, 11, +109, 55,110,220, 56,144,158,158,206,214,246, 98, 48, 24, 12,102,176,170, 79, 86, 86, 86, 78, 64, 64,192,209, 91,183,110,245, 29, + 54,108, 24,206,158, 61,251, 14,128,201, 0, 32,145, 72,222, 25, 54,108, 24,110,221,186,133,152,152,152,163, 89, 89, 89, 57, 47, +227, 59,197, 98,177,193,100, 42, 10, 70, 57, 56, 56, 56, 84,243,240, 26,197, 77,131, 0, 80,163,146,207, 42,132, 39, 16,248, 54, +232,217, 83, 80,112,231,142,122,205,181,107,115,183,108,217, 34,104,219,182, 45,177,152,205,176,113, 28, 66, 66, 66, 72,151,174, + 93,229,235,183,108,113,179,105,181,231,191,253,226,139, 11,171,223,123,175, 48,142,210, 36,123, 18,104, 52, 26,151, 79,248,224, +253,174,103,206, 94,240,143, 8,175,237,118,244,248,153,219,238,238,206,178,186,117,234,200,243, 10,242,109,211,167,125, 38, 48, + 26,141, 63, 85,165,163,215,235,247,156, 60,121,114, 96, 96, 96,160,103, 84, 84, 20, 76, 38, 19,108, 54, 27,186,116,233, 2, 74, +169, 4, 0, 39, 16, 8, 16, 19, 19, 3,179,217,156, 29, 31, 31,159,254,232,209, 35, 9,128, 5,149,233, 26, 12,134,228,178,127, + 7, 5, 5,181,237,211,167, 15,172, 86, 43,122,246,236,137,253,251,247,183, 77, 79, 79, 95, 83,102,151,228,151, 80, 19, 2,165, +180,158,191,191,255,238,226,143,236,234,220,238,235,235, 27, 22, 26, 26, 58,111,254,252,249,194,192,192, 64,112, 28, 7, 55, 55, + 23,104,181,122,228,229,229, 33, 34, 34, 2,129,129,129,248,254,251,239,129,162, 17,128,118, 69,216, 82, 82, 82, 18, 1,124, 20, + 17, 17, 33,210,104, 52,145,122,189,126,102,151, 46, 93,112,251,246,109, 92,185,114,229, 99,173, 86,155, 47,151,203, 45,126,126, +126, 35,121, 60,158,220,108, 54,239,207,206,206,206,102,143, 40, 6,131,193,120,197, 13,150,183,183,183,204,193,193,225,141,247, +223,127,223,133,227, 56,136, 68,162, 6, 30, 30, 30,223,229,230,230, 22, 86,247, 75,117, 58,221,246, 45, 91,182,116,255,241,199, + 31, 69,189,123,247,174, 29, 16, 16,208, 2, 0, 6, 15, 30, 92,219,209,209, 17, 91,182,108, 49,235,116,186,151, 54,167,145,197, + 98,105,223,188,121,115,228,231,231, 35, 41, 41, 41,170, 58,199, 30, 56,112, 64,134,162,126, 87,149,126, 86, 25, 86,147,201,213, +197,223,159,247,244,204, 25,115,190, 90,237,219,190, 67, 7, 98, 49,155,193,227,241,144,151,151,135,148,148, 20, 56,187,184,144, +152,248,120,197,218,207, 63, 63, 80,163, 81, 35,177,205,100,114,175,134,153,208, 18, 66, 70,127,252,209,135,123,182,110,253,221, + 83,169, 86, 63,150, 74,101, 70,137, 68,228, 51,241,227,143,109,249,249,249,111, 83, 74,237,185, 78, 11,182,110,221,218,179,103, +207,158,247,130,130,130,188,114,114,114,124,148, 74,165, 45, 63, 63,159,143,162,190, 84, 4, 0,206,156, 57, 3,181, 90,109,181, +217,108,231, 1,204,161,148,154,236, 77,171,155,155,155, 99,167, 78,157, 90,121,123,123, 67,173, 86,195,195,195, 3, 77,154, 52, +105,229,230,230,182, 61, 63, 63, 95,243, 50, 11,247,137, 19, 39, 28, 41,165,173, 40,165,232,217,179,167, 93,199, 16, 66,134,244, +233,211, 71,200,227,241,160,215,235, 32,145, 56, 64,161,112,130,163,163, 51,234,214,173,139,244,244,116,244,232,209,195, 28, 31, + 31,191, 57, 35, 35,227, 80,117,211,164, 82,169,186,181,110,221,250,253, 9, 19, 38,192,102,179, 97,192,128, 1, 72, 77, 77,253, + 38, 49, 49,241,128,135,135,199,192,119,223,125,215,205,221,221, 29, 83,166, 76,145, 2, 88,202, 30, 81, 12, 6,131,241, 63,110, +176, 42,107,243, 12, 8, 8,104,238,225,225,241,177,163,163,163,203,233,211,167,229, 0,208,182,109, 91,112, 28,183,202,207,207, +239,151,244,244,244, 75,213,249,210,130,130, 2,181,175,175,239,190, 43, 87,174, 12, 29, 60,120, 48, 78,156, 56,241,118,177,193, +194,149, 43, 87,240,228,201,147,125, 5, 5, 5,234,151,145,193,128,128,128, 94, 29, 59,118, 28,220,188,121,115, 28, 60,120, 16, + 54,155,237,114,117,142, 47, 59, 98, 16,229,140, 34, 44,249,204, 46, 49, 62, 31,132, 16, 88,173, 86, 0, 64,110, 78, 14,226, 98, + 99,145, 95, 80, 0,163,193, 0,173, 78,103,171, 91,179,166, 94,101, 50, 9, 9, 80,173, 54, 46, 74,105,178, 66,161, 72,209,105, +181, 94,238,174,110,122,153, 76, 2,165, 90, 37,186,121,227,106, 33,165,244,177,157, 26, 38, 66, 72,135, 35, 71,142,204,224,243, +249,195, 20, 10, 5, 38, 76,152,192,239,216,177, 35, 68, 34, 17,140, 70, 35,148, 74, 37,182,108,217,146, 99,181, 90,107, 21, 27, + 18,133, 92, 46,223,200,231,243,211,212,106,245,215, 85,125,135, 68, 34,233,216,191,127,127,190,209,104,196,156, 57,115, 48, 99, +198, 12,244,236,217,147,127,253,250,245,142, 0,246,191,172,130,205,113, 28,186,117,235, 86,182,147,251, 67,123,142, 19, 10,133, +117,235,212,169,131,156,156, 28,228,228,228,192,211,211, 19,126,126,126,240,246,246,198,146, 37, 75,232,210,165, 75,207,217,108, +182,205,153,153,153,185, 47, 80, 22, 71,190,243,206, 59, 35,134, 14, 29, 10,173, 86,139,211,167, 79,163, 77,155, 54,248,254,251, +239, 61, 47, 92,184,240,126,243,230,205, 33, 20, 10,113,238,220, 57,152,205,230,116,246,120, 98, 48, 24,255, 54, 94,149,254, 87, + 85, 70,176, 92, 93, 93,157, 28, 28, 28,198,245,237,219,183,237,192,129, 3,241,221,119,243, 74,255,199,227,241,176,105,211, 38, +197,158, 61,123,190, 8, 12, 12,236,192,113,220,175, 79,159, 62,205,183,247,139, 57,142,219,179,117,235,214,222,173, 91,183,150, +117,234,212, 41,164,248,229,107,218,186,117,171,142,227,184, 61,213,205,200,243,147, 62,250,251,251, 55, 20, 8, 4,131,251,246, +237,219,112,244,232,209,136,142,142,198,150, 45, 91, 30,213,173, 91,247, 98, 53,165,147,170, 24, 69, 56,191,170,104, 22, 95, 44, +206, 83,102,102,186, 40,130,130,132,174,142,142, 25, 7, 15, 30, 12,236,218,181, 43, 73, 77, 77, 69, 65, 65, 1, 12, 6, 3,110, +220,184,193, 9,128,100,129,171, 43, 73,190,114,133,240,197,226,188,234,158,131, 64, 95,215,208,111,166,141,175, 97, 48, 26,234, +171, 84, 42,171, 64, 40, 20, 6,248,184,164, 86,179,112, 27,229,114,121, 51, 0, 2,142,227,116,110,110,110,178,227,199,143, 67, + 44, 22,131, 16,130, 6, 13, 26,192,193,193, 65, 36,151,203, 83, 0,192,199,199, 71,188,106,213, 42,231, 81,163, 70, 93,168, 74, +187, 99,199,142,130,224,224,224,238,117,235,214,197,229,203,151,241,240,225,195,167, 87,175, 94,245,111,214,172, 25,252,253,253, +187,119,236,216,241,240,217,179,103,173, 47,233, 38,125,161, 78,238, 54,155,141, 18, 66,192,227,241,192,113, 28,114,114,114, 80, +171, 86, 45,172, 88,177, 2, 75,150, 44,249,233, 69,251, 72, 69, 68, 68,136, 26, 55,110, 60,120,232,208,161,120,252,248, 49,230, +207,159, 95,144,157,157,125,249,248,241,227,189, 38, 76,152,192,111,211,166, 13,242,242,242,176,110,221, 58,235,237,219,183,119, +102,101,101,237, 97,143, 90, 6,131,193,120, 5, 13,150,191,191,127, 31, 55, 55,183,247,135, 15, 31,206, 15, 11, 11, 67, 86, 86, + 22, 52,154, 66, 67,195,134,145, 28,192,163, 98,177,200, 44,151,203, 49,118,236, 88, 52,104,208,160,197, 23, 95,124,209,220,199, +199,103, 83,102,102,230, 46,123,190, 56, 43, 43, 75,231,235,235,187,115,194,132, 9, 11,238,220,185, 93, 11, 0,174, 95,191,254, + 36, 61, 61,125, 90, 86, 86,150,174,154,230,170,100, 50, 75, 34,149, 74,175,133,134,134, 38,246,234,213,203,105,224,192,129,240, +244,244,196,173, 91,183,240,253,247,223,199,155, 76,166, 25, 47,235, 5, 94, 29,172, 70, 99,230,205,189,123, 29, 59,190,241,134, +211,196, 62,125, 22,125, 56, 97,194,143,223,124,243,141, 32, 44, 44,140,232,116, 58, 92,187,118,141,238,218,181,203,178,126,238, +220,165,144,203,133, 87,118,237, 18,155, 76,166,228,106, 70, 71, 58,244,238,217, 33,108,209,143,203, 97,208, 23,226,218,229, 67, + 40, 40,200,193,170,213,187,195, 2, 2, 2, 58,164,165,165,157,171,198,249,172,123,226,196, 9, 47, 74, 41,196, 98, 49,230,204, +153, 3, 63, 63, 63, 56, 57, 57, 65,163,209, 96,242,228,201,206,159,126,250,169, 51, 0, 68, 71, 71, 67,161, 80,216,165, 27, 27, + 27,219,116,252,248,241, 50,155,205,134,163, 71,143,154,249,124,254,162, 19, 39, 78, 44,108,212,168,145,168, 99,199,142,178,245, +235,215, 55, 3,112,245,101, 25,172, 23,193,102,179, 37, 29, 63,126,188,193,176, 97,195,168, 64, 32, 32, 74,165, 18,206,206,206, + 88,177, 98,133, 46, 35, 35,227,133, 39,104,203,203,203, 19,214,175, 95, 95,196,113, 28,118,238,220,137,167, 79,159,126,150,149, +149,149,227,231,231,119,116,234,212,169,227,194,194,194, 2, 98, 98, 98,158,234,245,250,149,233,233,233,105,236,209,196, 96, 48, + 24,175,110, 4,235,141,163, 71,143,242, 57,142,195,234,213,171,113,235,214, 45,154,155,155, 59,131, 16,178,209,201,201,201,150, +155,155,251,198,152, 49, 99, 6,206,152, 49,131,180,107,215, 14, 87,174, 92, 33,181,106,213, 26, 12, 96, 87,153, 23,117,215,202, +230,202, 80,169, 84, 55,178,178, 50,107,149,153, 88,178,150, 68,226,112,163,138,151,255, 51,154,207, 79,102,201,231,243, 90,206, +153, 51, 71,235,235,235,107,138,138,138,194,202,149, 43,185,155, 55,111,158, 17,139,197,171,210,211,211,141,246,104,190, 12,202, +106,138,173,214, 91,155,167, 78,173,215,116,192, 0,238,253, 41, 83, 10, 69, 82,233, 39,139,150, 47,255, 92,169,209,248,129, 16, +234,238,236,156,188,122,206,156,249, 61,251,247, 47,140, 62,119,206,225,206,137, 19, 66, 79,139,229,110,117,210,153,150,150,118, + 46,180,118, 16, 54,172,249, 17,102,179, 17, 25, 79,139,252, 89,110,158, 10,149,153,171,242, 52,173, 86,171,234,245,215, 95, 23, + 1,144,190,249,230,155,226,236,236,108,212,174, 93, 27, 0,160, 86,171,113,232,208, 33,132,135,135, 3, 0,238,223,191, 95,250, +123, 85,233,116,116,116,236,218,190,125,123, 36, 39, 39,227,193,131, 7,151,159, 62,125,170,244,247,247,191,156,146,146,210,177, +121,243,230,216,181,107, 87,151,138, 12, 86,117,175,145, 61, 6,171,130,188, 47,216,179,103,207,208, 43, 87,174,244,157, 50,101, +138,160,115,231,206, 0, 0,173, 86,107,160,148,218, 94, 68,179, 44, 22,139,165,100,210, 83, 29, 0, 20,155,169,175,255,138,230, + 95, 45,159, 76,147,105, 50, 77,166,249, 79,208,252, 55, 25, 44, 43,199,113, 56,123,246, 44,118,239,222,109, 51,153, 76, 95,102, +100,100,196,150,249,255,250,192,192,192, 11,131, 7, 15, 94, 28, 23, 23,199,127,240,224, 1,236,121, 1,149,197, 96, 48, 88,158, + 95, 42,216, 96, 48, 88,254,106,166, 54,108,216,128,204,204, 76,115,106,106,234, 73,171,213,186,231, 47,142, 70,252,203,163, 8, +215, 83,106,124,131,144,147, 51,219,182,237, 54,227,196, 9,201,251, 95,125,101,124,103,244,232,207,108, 38,147,133, 47, 18,113, + 98,185,156,103,147, 72,132,209,231,206, 57, 44,251,224, 3, 55,189,209,120,116,115, 53, 58,142,151,137, 96,225,157,247, 39, 65, + 95, 38,130,117,229, 70, 28,170, 27,193, 50, 24, 12,245, 1, 64, 42,149,166, 0,240,121,235,173,183,192,113, 28,244,122, 61, 52, + 26, 13,210,211,211, 85,163, 71,143,182, 1,128, 92, 46, 23, 12, 30, 60,216,201,174, 19, 89,163,134, 15,159,207,199,225,195,135, + 33,145, 72, 78, 3,128, 68, 34, 57,125,226,196,137,142, 35, 71,142, 68, 96, 96, 96, 80,201, 36, 40,149,233,120, 71, 14,220, 78, +129, 80, 16,212, 41,186,211, 81,199, 43,114,224, 61, 2,196, 23,207,242,254,176, 73,147, 38,128,157,253,174,202,146,147,147,163, + 5,176,206,219,219,251,208,103,159,125,246, 86,171, 86,173,218,205,152, 49,131, 80, 74,255,242,194,232,148, 82,216,108, 54,246, +212, 97, 48, 24,140,127,179,193, 34,132,252,209,169, 83,167, 17,148, 82, 62,143,199,219,242,156,185, 2, 0,164,166,166, 62, 9, + 8, 8, 88, 93,179,102,205,210, 5,160,171,249,194,201, 34,132,124,207,227,145,207,139,254,174,254,196,146,101,150, 36,249, 28, + 0,225,241,248, 27,111,223,190,253, 85, 74, 74, 74, 78,117, 13, 95,121,188,140, 81,132, 0,176,149,210,196, 17,132, 28,155, 18, + 25,217,181,231, 7, 31,160, 97,207,158, 78,126,193,193, 54,189,217,204,221,191,120,145, 92,222,185, 83,116,231,196, 9,161,222, +104, 60,186,155,210,148,234,166, 51, 45, 45,237, 92,237,144,128,227, 67, 6,247,238, 30, 82,211, 15, 0,144,144,152,142,220,124, +213,241,234,152,171,231,140,214,128, 21, 43, 86,236, 23,137, 68,130,178, 75,206,152,205,230,252, 18, 19, 70, 8,241, 91,189,122, +245, 31, 60, 30, 47,185, 42,189,216,216,216,227, 51,103,206,236,249,228,201,147,243,169,169,169,105, 0,144,144,144,144,230,231, +231,183, 59, 61, 61,189, 87, 74, 74,202, 17,106, 71,232,233,185,197,158, 17,125,113,135, 3,128, 6, 37,139, 61,191,232, 90,131, +101, 41, 54,229,139, 2, 2, 2,246,245,234,213,107, 4, 33, 36,243,175,232, 41, 20, 10,171, 94,175,183,114, 28, 39, 48,155,205, + 84,161, 80, 88,217,227,135,193, 96, 48,170, 69,115, 0, 37, 43,135,148, 4, 78, 60,159,251,221, 4,160,236, 82,126, 37,127,231, + 0,184, 81, 70,163,236,231, 85, 29, 11, 0,185, 0,238, 21,127,246,215, 12, 86, 90, 90,218, 17,216,177,152,179,189,251, 85, 98, +144,190, 36,132, 44, 43, 49, 75,127, 85,195,106,181,190,148,245,219,120, 60, 94, 98,191,126,253,170,181,127, 85,251,252, 65,105, +242, 39,132,108, 58,248,211, 79,141,143,174, 92,233,111,179, 90,221, 9, 64,249, 98,113,158,201,100, 74,242,180, 88,238, 86, 55, +114, 85,150,199, 9,105, 61, 0, 32, 52, 52,148, 62,122,244,232, 47,143,198,160,148,222, 5, 16, 88,197, 62,233, 0,218,217,163, +151,154,154,186, 31,229,140, 20, 76, 79, 79, 63, 0,224,128,189,233, 42, 93,236, 25,224,113,132, 27, 82,191,237,208,157, 0,184, +146,197,158, 95, 38,105,105,105, 9, 0,230,254, 85,157,199,143, 31,155,106,214,172,185,119,193,130, 5, 3,239,221,187,119, 48, + 53, 53,213, 4, 6,131,193, 96, 84,203, 92, 17, 66, 14, 22,191,123,250, 22, 87,242, 15, 62,255,123,201, 62, 37,251,149,221,167, + 68,227,249,207, 43, 59, 22, 0,166, 77,155,246,213,252,249,243,101, 0,236,238,139, 43,248, 39,156,181,151,177,168,237,203, 94, + 24, 55, 45, 45,109,205,223,145,215,229, 69, 6,234,234,223,121, 62,227,227,227,201,171,124,151,149, 44,246, 92,134,200,255,133, +116, 39, 38, 38,110,234,216,177,227,239,169,169,169, 44,122,197, 96, 48, 24,213,195,179, 60, 67, 84,129, 31,232, 91,217,255,159, +169,176,151,179, 95,121,127, 19, 66, 14,206,159, 63,191,111,117, 18,204, 99,215,140,193,248,255,227,191, 49,138,149,193, 96, 48, + 24,229,243,124,212,170,196,116, 61,255,247,180,105,211,190, 66, 53,154, 7,129,162,153,185,187, 86,240,165,118,143, 14, 32,132, +116,125,129, 76,157,100,154, 76,147,105, 50, 77,166,201, 52,153,230,191, 75,179, 42,237, 10,142,239, 83, 81,147, 94,101,205,133, +207,255, 94,213,177,118,236,123,168, 58, 39,226,111,219, 0,116,101,154, 76,147,105, 50, 77,166,201, 52,153, 38,211,252,139, 91, +115, 74,105, 31, 20,173,114, 66, 41,165,125, 40,165, 61,167, 77,155,246,101,201,103,211,166, 77,251,146, 82,218,165,100,191,226, +125, 74,143, 41,249,236,249,159,207,127, 86,197,190,118,167,249, 31,209, 7,139,193, 96, 48, 24, 12, 6,163, 18,110, 0,104, 94, + 38,186,148, 3,224,254,252,249,243, 11,202,244,141,202, 1,112, 23, 64,163,226,253,114,138, 3, 73,101,251, 78,153,138,255, 54, +149,179,143,201,158,125,237,133, 25,172, 10,104,236,203,159, 27, 20,224,213,172, 52,202, 87, 52, 57, 36,184,226, 89, 4, 74,167, + 19,224, 56, 80, 74,145,158,173,188,117, 47,139,126,243,162,223, 23,230, 79,220,188, 28, 28,150,114,148,182, 45,254,232,156, 42, +207, 56, 41, 74, 69,149,246,106,212,243, 33,245, 28,120,248,140,163,104, 8, 0, 60,130,123, 6, 14, 63, 60,204,164, 15,255,234, +249, 32,132,144,250,158, 24, 43,150,202,134, 59,187,184,214, 41, 40,200,141, 55, 27,140, 59, 30,228, 96, 21,125,129,105,211,107, +187,145, 86, 28,197, 87, 0,120, 66, 30, 22,199,229,209, 51,172,212, 49, 24,140,255, 39,248,127,241,248,242,166, 0,250,171,131, +139, 40,187, 44,118,153,172,231,185,110,231,126,255,239, 84,203, 96,213,247, 34, 31,128, 96, 22, 0, 10,138,217,209,217,244,215, +106, 29,239, 71,186, 58,240,249,107, 1,240, 13,102,219, 20,202,225,124,185, 47,115, 30,218, 59,136,248,139, 1,112, 6,155,237, +189,232,116,251,251,131, 69, 6,144,158, 2,142,183,153,163, 84,104,227,232, 70, 80, 28, 84,136,112,233, 74, 26, 53, 84, 39,173, + 65, 1, 94,205,246, 94,207,232,126,230,215,137,104,217,176, 54,168,205, 10,112, 22,200,218,125,134, 83, 75,222, 66,203,122, 65, +160,156, 5,224,172, 80,244, 90,132, 94,145,206, 47,124,115,132,249, 19,183, 96, 15,175,168, 53,107,214,250,248,133, 68, 16,206, +106, 70,236,245,227,163, 62,253,124, 70,231, 72,103, 18,105,143,201,106,228, 71,222,175, 93, 43,236,179, 73,179,126,228,251,250, + 5,202, 57,139,209,154,153,248,176,201,242,133, 51,118, 53,242, 35,139,239,166,211,181,246, 26,169, 8, 79,140, 19, 72,196, 67, +165, 14,242, 58, 58,157,230,145,205,108,217, 17,233, 39,232,249,195,162,165,141, 59,118,235,173,176,105, 50,121, 22, 14, 17,219, +183,253, 17,252,211,138, 95,122, 19, 66,250, 83, 74,185,234,228,153,163,248, 60,110,211,216,222, 66, 1,159,212,123,119, 13, 31, +213, 24,250, 90,150, 8,111, 50,146,208,170,167,137,160, 4, 23, 30,100,209,223, 95,228, 59,234,121,147,223, 8, 69, 93, 16,236, + 36, 20,127, 68,103,211,108,246,156, 99, 48, 94, 45,120, 60,222, 25,142,227, 58,189, 76, 77, 66, 72, 43, 74,233, 85,118,118,255, +157, 84, 47,130, 69,240,109,244,227, 84, 87,216,204,168, 95, 55,100, 46,128,106, 25, 44, 7, 62,127,227,141,248, 44, 31, 88,205, + 88, 51,111,194, 54,147, 5,176, 90,204,176, 89, 45,176, 89, 45,176, 90,205,176, 89, 44,160, 22, 35,102,172, 59, 3,152, 52,104, + 22, 25,186, 17,128,175,189,223, 33,164,188,205,183, 46, 30,119, 35, 38, 21,126,255,117,254,199,169, 57,133, 31,159,188,151,158, + 91,223,155,124,249, 32, 27,235,171, 99, 4,206,172,156,136, 45,123, 14,165, 45,251, 77, 27,195, 81, 10, 55, 39,105,216,168,190, +209,129,155,246,157, 73, 93,186,209, 16, 3, 0,206,114,113,216,219,247,226,131,254,202, 69,240,114,112, 88,186,234,151,159,124, +124,221,165,196,122,121, 1,172, 54, 27, 2,131,251,240,191,252,104,148,239,183, 75,214, 46, 1,240, 78,101,199,135,123,147,136, +186,181,235, 77,217,120,232,114,144, 86,157,109, 58,190,245,171,199, 48,194,226,227, 95, 79, 56,119,254,143,252,233, 95, 76,156, + 28,238, 77,174,197,100,209, 7, 85, 60, 12,120,245,188,176,111,254,130, 69, 13, 59,247,234,171,224, 10,115,248, 6,109, 97,221, + 53,235,214,206, 10,111,216, 66,214, 46, 50, 64,148,189, 99, 60,209,107,242, 97,230, 57, 72, 58,215,239,234,164,127,115,132,101, +205,134, 45, 31, 1, 88, 94,173,234, 95,153,230,105,142,123,241,218, 36,161,104,119,231,234,153,113,182,244, 27,160, 54, 11, 96, + 51,151,254,132,205, 2,202, 21,253,108, 57,126, 29, 0,188,144,193,226, 81,116, 63,121,241,134,111, 86,102, 70,243, 37,139,190, +251, 50,194,139, 28,129, 13,155, 31,230,227, 92,117,141, 37,131,193,248,231, 66, 8,177, 82, 74, 5, 47, 89,179, 55,165,244,240, + 95,212,248, 12,192,251,197,127,174,165,148,254,240, 18,210, 21, 0,192,167,248,207, 76, 74, 41, 91, 3,245,191,106,176, 0, 7, + 80, 14,216, 57, 16, 0,164,213,253, 50, 10, 56,128,240, 1,139, 22, 3,122,117,131,135,151, 15, 96,209, 1,102, 29, 96,209, 3, + 22, 45, 96,209, 35, 55, 35, 25, 48,107,129,132, 35,176, 82, 42,169,118,174,140, 42, 32,110, 7,186, 52, 9,130,167,179, 3, 38, + 14,136,240, 88,125, 52,110,237,218,227,177, 93, 1, 12,183, 43,173,148,162,101,131, 58, 88,182, 86, 27,179,255, 86,118, 15, 0, +232,211,216,227,104,203,136,224,192,165, 27, 13, 49,135,238,229,247, 4,128, 94,145,206, 71, 90,132,249, 6,113,127, 33,186,203, + 81,218,206,175, 70, 29, 98,187,179, 10,156, 58, 13,106,181, 30,105,137,155,224,234,223,148,103,227,208,161,170,227,165,124, 76, +251,100,250,247, 66,157, 58,203,196,153,115,108,158,252, 2,190, 64,204, 17, 60, 61,103, 44,228,148,182, 73, 99,223,178, 78,249, +102,222, 52, 0,163, 42,141, 6,121,225,163,197,139,151, 54,104,211, 44,220, 43,115,215, 68, 82, 88,144, 5, 43, 95, 38, 25,208, +186, 13, 92, 66, 35,184,172,179,139,137, 56,164, 43, 92,220, 67,240,244,242, 86, 36, 93,221, 77,218, 54, 25, 44, 89,255,187,232, +205,138, 12, 86,168, 39,105,219,163,125,139,109, 33, 65,126,190,148,114,224, 56, 10,202,217,240,238,144,238,248,114,123, 2,108, + 54, 27, 94,239,209,182,203,247,227, 58, 83,142,227, 64, 41,135,212,204, 60,221,233,107, 49, 93, 30,231,211,107,246, 68,166, 26, +181,234,212,246,222,173,171,225,150,184, 3,104, 54,234,255,216,187,234,240, 42,142,183,123,230,238,213,220,184,123, 66, 2, 36, + 65,130, 59,193, 37,104,113,111,129, 10, 80,160, 88,139,182, 64, 75,139,180, 80,172, 56,180,197,181,184,107,130, 91,176, 16, 32, + 36, 1,226,238,114,117,119,231,251, 35,210, 0,145,123, 3,109,127,237,183,231,121,246,185,119,237,236,216,206,156,125,103,230, +157,197, 79, 9,112,181, 84,153, 11,184,119,230,247, 90,192,111, 85,173,132, 72,109, 7,112,175, 78, 47,129, 71,219, 49,204,198, +221,167,237,179, 83,227, 71,254,177,125,221,192,245, 27, 55,238, 4, 48, 78,168, 70, 4, 8,248,111,128, 82,250,222, 69, 86,116, +116,116,194,187,136, 44, 55, 55,183,182, 0,126, 42, 30,137, 65, 8,249,201,203,203,107,222,159, 31,168,175,125,227,101,115, 28, + 55, 34, 46, 46,238,114, 69,156,189,122,245,114, 1,224, 85,138,211,139, 16,226, 85,214,181, 86, 86, 86, 92,171, 86,173, 94, 29, + 63,126, 60, 65, 40, 33,127,173,192,122, 26,179,127,114, 35, 77, 98, 30, 0, 60, 53,160,176,190,214,181,167,214,115, 75,182,126, +251,209,146,186,213,108,144,155,175,197,217,187,175,192,113,122,112, 44, 91,100,201, 98,193,177,122, 4, 54,176, 67, 43,245, 56, +172, 62,254, 12, 44,199, 47,174,136,243, 77,232, 40, 63,172, 97,231,193,251,120,158,202,228, 18, 81,182,175,187,173,195,151, 3, + 26,136, 38,247,169, 11,149,142, 29, 92,199,145, 92, 12, 75,166,155, 13,226,228,223,118, 89, 68,203, 58,198,177,149,198,189, 2, +235, 83,243,161,189,186, 88, 80, 77, 54,244,105, 81,200, 45,208, 35, 42, 93,143, 36,117, 22,228, 36,209, 32, 78,158,162,190,155, +171,179,242,218,222,153, 47,109,153, 28,177, 3,195, 74,101, 34, 22, 28, 79, 25,154, 21,166,177,169,213, 69, 82, 60, 46,171,162, +112,154, 40,205, 63,106,219,181,167,101,204,174, 49,196,196, 55, 16, 14,141,220,241,242,242, 86,164,220, 61,142,244,132, 87,196, + 66,157, 5, 71,219, 26,232, 62, 98, 8,150, 14,105,138,220,156, 92, 48,137,145,150, 50,137,220,170, 60, 78,202, 97,196,207, 63, + 46,116, 22, 51,162,194,244, 44,222, 56, 61, 84, 26, 13,192,177, 80,136,121, 16, 90,124, 78, 15, 78,175, 83,214,239, 63,115, 60, +128, 91,149,197, 61, 44,153,238,174,235, 64,218,128,215,215,162,122, 21, 8,112,245,113, 10, 45, 17, 61,117, 28,201,176,198,129, +163,219, 80,130, 43, 85,201, 35,127, 91,244,106,226,101,102,106,154,243, 20,113, 7,190, 64, 36, 20,212,177,245,167, 24,246,241, + 68,229,166, 77,155,122, 19, 66, 62, 47, 61, 6,237,175, 88,252, 84,224, 20, 56,255,173,156,150,150,150,222,213,170, 85,155,167, +215,235,219, 74,165, 82, 71,157, 78, 7,158,231,147,100, 50,217,149, 87,175, 94, 45,200,206,206,126,241,191, 22,247,135, 15, 31, + 26, 44,178, 12,225,148, 72, 36,120,246,236, 89,132,161, 34,235, 77, 78,137, 68,178,227,234,213,171,216,183,111, 31, 0, 32, 60, + 60, 28, 62, 62, 62,166,101,221,251,242,229, 75,211,246,237,219,239,192, 27, 43,112,188,201,249,232,209, 35,239, 99,199,142,225, +192,129, 3, 0,128,103,207,158,193,215,215,183,204,240, 92,189,122,149, 25, 62,124,184, 55,128,132,191, 58,143,254,147, 2,171, +104,125, 93,242,230,255, 50, 16,229, 97, 45,107, 4, 53, 7, 0, 81,198, 62, 44, 44,137,254,216,192, 89,210,237,194,129,181,109, + 21, 82, 17,230,111,254, 50, 54, 53, 35,183,133,152,128, 7, 0,150, 66,100,109, 38,187,177,120,100, 3,143,204, 60, 53,142,222, +142,191,252, 56,217, 56, 83,232,227, 4,122, 14,128,213,159, 13, 36,241, 29,185,244,220,158, 61,179,186,213,159,218,167, 62,142, + 92,127, 53, 21, 64,165, 94,218, 41,207,131,242,108,201,160,246,162, 79, 5,128,103, 81,122, 76, 55, 15, 90,120,140, 55,206,130, +213,158, 16,113,166, 3,186,219, 40,101,107,198,142,253,204, 66,159,250, 28, 25, 90, 41, 98, 51,213, 72, 82, 73,144, 39,118, 64, +252,211, 71,156,136,224, 92,229, 86, 22,228, 80, 86,109,101, 45, 51, 19,249,119, 25,239,154,115,122, 78,166,140,176,140, 69,191, + 31,172,210, 46, 44,127,197,230,167,230, 19,130, 74, 23,209,182,180,180,242, 81,167,191, 98,178, 51,211, 96,229, 84, 23,221, 6, +247,194,119, 61,235, 32, 55, 39, 31,169, 25, 55,104, 77,103, 11, 18,125,101, 39,190,238, 94, 27,233,201,137,208,232, 1,146,175, +201, 80,107,213,121,229,166,163, 8, 27,167,124, 53, 99,152,167,179,189,105,241,100, 1,202,115,104, 80,187, 58,186,180,109,142, +115, 87,175,225,206,163,112,240, 69,147, 5, 40,207, 35, 46, 37, 51, 89,173,227,182, 26,149,160, 28, 11,170, 87,151, 41,192, 80, +133,174,193,122,142, 68,201, 1,115, 91,212, 52,255,100, 86, 47, 79,115, 83, 57,129, 90,207, 65,173,213, 35,247,218, 26,216, 86, +171, 7,165, 66, 65, 26, 65, 37, 6,160, 23,170, 18, 1, 2,254,196,160, 65,131, 20,201,201,201, 65, 61,123,246,172,211,165, 75, + 23,101,155, 54,109,144,159,159,143,179,103,207, 34, 63, 63,223,211,221,221,221,243,236,217,179,253, 91,180,104, 17,230,230,230, +214,126,255,254,253,198,140,145, 21,227,207, 65,234, 60, 0,150, 16,130,162, 99, 4, 0,255, 46,235,208,202,100, 50, 68, 71, 71, +191,119, 75, 86,124,124,124, 68, 85, 44, 89,121,121,121, 82, 87, 87, 87,216,219,219,131,227, 56,228,231,231,227,240,225,195,200, +206,206, 6,207,243, 48, 49, 49,193, 15, 63,111,198,211,123, 65,184,117,235, 22,178,179,179,165,149,113,198,197,197,145, 6, 13, + 26, 64,163,209,128,101, 89,168,213,106,156, 63,127,190,100, 95, 44, 22, 99,198,247, 43, 16,126, 55, 8,247,239,223, 71, 92, 92, +220,223,178, 58,136, 17, 90,228, 63,105,193,122,103,112, 28, 59,123,211,182, 61, 55,102,143, 27,130,137, 67, 59,187, 47, 88,123, +176,115, 88, 42,221, 6, 0,117,236,201,200, 15, 59,212,244,176, 82, 74,240,221,174,187, 0,165,179,223,245,121,161,233, 52,188, +174, 19,153,122,232, 86,116,208,156, 33,141, 80,221,217,194,167, 70, 13, 34,139,140, 52, 96,205, 63,158,133,181,153,220,175,103, + 67,187,211,224,121, 88,153,203,107,129, 99, 97,101, 38,247,235,238,111,121, 10, 0,172,148,210, 90,101, 89,186,202, 67, 83, 15, +233, 24,165, 92, 60,198,180,177,179,199,168,222, 93, 76,122,244,238,111, 98, 38, 97,145,126,235, 44,114, 36,110,208,219,120, 66, +163,207, 64,220,139, 72,238,194,205, 39,241,105,185,154, 47, 43, 13, 38,197,229,248, 23,207,236,189,235,119,177, 78, 59,254,117, +138,247,232, 93, 94, 34,240,162,220,157,253,146, 77, 29,154,153,220,142,122,145,199,211,183, 45, 56,111, 34, 39, 59,251,149,158, +131,179,138, 19,155, 71, 94,250, 29,179,186,215, 67,102, 70, 10,212, 58, 22,217, 42, 86,231,100,165,144,107, 94,132, 66,163, 99, +161,213,243,144, 88,185,226,236,141, 71,105,188, 94, 95,238, 90,148,145,105,244, 62, 0,179,210,199,106,216,147, 6, 51, 45, 76, +238, 67,175, 66,116, 92, 2,182,157,184,209,168,232,186,170,127,157,242,108, 97, 55,115, 41,203, 21,161,104, 83,149,193,237,181, + 29, 73, 51, 19,133,244,151,159,166, 14,175,211,210,215, 70,206,199,221, 0,225,117, 48,229,196, 80,201, 56, 88,186, 87, 7,175, +205,165, 5,106,117,214, 99, 64,240,204, 46, 64, 64, 41,212,170, 85,203,201,210,210,242,241, 87, 95,125,101,211,175, 95, 63, 28, + 58,116, 8, 57, 57, 57,216,186,117, 43, 86,174, 92,137,111,191,253, 22,122,189, 30,155, 54,109, 82,254,241,199, 31,205,214,173, + 91, 23,231,233,233, 89, 55, 58, 58,186,178, 5,213, 9, 0, 57, 0, 73, 81,219, 69, 0,240, 39, 79,158, 68,143, 30, 61,112,242, +228, 73,190,232, 24, 71, 8,209, 83, 74, 53, 85, 21, 88, 50,153, 12,217,217,217,239, 69,100, 73, 36, 18,152,153,153, 65, 38,147, + 33, 55, 55,215,104,145,197,178, 44, 19, 23, 23,135,236,236,108,116,233,221, 27, 43, 22, 47, 70,135, 14, 29,208,165, 75, 23, 80, + 74,113,254,252,121,116,110,237,143, 33, 31,180,199,147, 39, 79,192,178,172, 65,225, 77, 74, 74, 66,114,114, 50,186,245,238,141, +205,235,214,161,121,243,230,240,243,243, 3,203,178, 8, 10, 10,194,192,192,214, 80,244,237,140,240,240,112,161, 80,255, 91, 4, + 86,104, 10,189, 89,199,158, 28, 31, 26,216,172, 87,239,128, 58,216,188,247,194,194, 58,117,200, 30, 0,176, 53,151,255,240, 81, +135,234, 8,139,201,196,133,251, 9,199,195, 82,223,207,236, 11,158,131,157,173,133, 18, 96,100, 80,233,120,214, 34, 10,149, 14, + 76,230, 41,133,178,237, 76,124,216, 59,204,189,121, 29,119,247,226, 89,132,102, 61,150, 99,228,163, 8,143,166,126, 78, 30,224, +244, 0,167,135,197,144, 93,192,247,166,149,134, 35,192, 91,126,110,230,151, 83, 91,117,239, 59,216, 68,166,180, 4,151, 19, 11, +125,210, 35,164, 63,191,140,124,165, 15,146,162,163,176,239,204,173,236,231,113,233, 57, 34, 17,206, 38,103,107,166, 71,102,208, +188,202,120,213,122, 44,158,247,245,151, 61,247,237,217,107, 46,175, 30, 64, 34,215,244,200,150,137, 89,185,189, 87, 99, 81,129, +194,142, 46,218,186,215, 34, 95,139, 37,149,241, 20,228,231, 28, 60,127,246,244,144,154,222, 1,230, 47,239,156,128, 74,173,129, + 70, 15,212,109,214, 30, 28, 71,101, 68, 68,120, 11,134, 33, 41,233,153, 32,122, 46,249,202,131,151,137, 87, 31, 68, 49, 26,243, +202,185, 95, 43,116,132,153,212,187,125, 67, 64,175,194, 7,109,235, 97,197,206, 11, 95, 0, 24,253,110,153, 92,104,193,162, 64, + 64, 93, 7,178, 1, 64,192,221,195, 43,107, 53,233, 59, 5,198, 88,176,252,237, 73,119,255, 26, 46,191,175,248, 97,166,141,173, +155, 15, 67,120, 61,168, 83,125, 32, 39,142,146,184, 27,176,116,109, 14,206,165, 53, 54,173, 94,150,199,243,116, 79, 85, 92, 84, + 8, 16,240, 95,134, 90,173, 62,248,227,143, 63,218,244,234,213,171,216, 2,131, 27, 55,110, 96,203,150, 45, 48, 53,125,189,158, +236,209,163, 7, 40,165, 54,243,231,207, 63, 8,160,101,121,156,173, 91,183,238,189,122,245,234,132,134, 13, 27, 70, 21,137, 44, + 41, 0, 81,104,104,168, 40, 54, 54,150, 88, 91, 91, 83, 23, 23, 23,125, 66, 66, 2, 15,128,251,248,227,143, 25, 51, 51,179,154, +121,121,121,193, 85, 21, 88, 50,153,236,189,140,201,146, 72, 36, 32,132, 64, 38,147, 65, 42,149,130, 82,106,148,200,226, 56, 78, +124,242,228, 73,220,189,123, 23,223, 54,108,136,169,174,174,176,177,177, 65, 80, 80, 16, 40,165, 48, 53, 53, 69, 70, 70, 6,246, +236,217,131,142, 29, 59,130,101, 89,169, 33,188, 7, 14, 28, 64, 72, 72, 8,190,111,210, 4, 83, 45, 45, 97,102,102,134,243,231, + 11,123,253,228,114, 57,162,163,163,113,254,252,121,180,111,223, 94, 40,212,127,181,192,106, 79,136,152, 56,194, 73,167, 85,129, +178, 20, 32,112,169, 83,135, 72,195,194,168,206,216,135,138, 68,248,122,245,182,227, 61,151, 79,233, 77,198,244,105,228,178,224, +247, 75,159, 3,192, 39, 3,124, 93,149,114, 49, 86, 29, 9,163, 34, 17,190,126, 31, 17,172, 83,135, 72, 69, 34,124,222,165,185, + 31, 18,178,180,136, 76,200,186, 24, 70,169, 65, 93, 58, 23,150,127,136,237, 71,131, 98, 87,110, 87, 63,165,148,194,202, 76,238, + 55,242, 97,164,199,239, 39, 67, 98,126,222,167,126, 74,121, 10, 43,165,164,214,232, 39,173, 43,157, 69,216,212, 67, 58,102,246, +204,233,173,251,140,254, 74,193, 62,221, 15,109,228, 25,240, 58, 21,114,116, 82,100, 49, 78,136,139,137,193,162, 77,199, 99,115, +242,181, 67, 66, 83,140, 19,150,225,105, 52,175,142, 61,233,183,232,187, 57,231, 22,255, 48,223, 76, 21, 21,148,199, 16, 86,197, + 84,107, 39,254,225,219,229, 36, 87,163, 29, 28,153, 65,115, 43,227,209,152, 99,201,143, 63,175,238,249,217,136,254, 79,125,125, +218,217,114, 9, 47,108,213, 57, 57, 41,187, 78,135, 56, 21,125, 25, 18, 0,136,140, 75, 71,106,118, 62,203,177,250, 96,115, 9, + 22, 60, 54,196, 26, 88,132,234,142,196,190, 95,155,250,195,237,205,165, 80,229,101,193,193, 92,130,192,230, 53,134, 87,119, 36, + 51,163,146,105,106,149, 51,154,215,131,234, 85,184,185,164, 99, 45,202,233,107,129,211, 67,247,112,135,241,150, 48,130,169, 19, +219,154, 89, 88,107, 95,138,144,111, 10,152,216,129, 88,120, 2,150, 94, 68, 82,123, 48, 18,162, 30,179, 95, 12, 31,145,254,226, + 85,220,175,118, 38, 88, 42, 84, 33, 2, 4,188,142,232,232,232,143,102,207,158,125,181,121,243,230,142,118,118,118,168, 87,175, + 30,142, 30, 61,138,175,190,250,170,228,154,134, 13, 27,130, 82,138,140,140, 12,252,248,227,143, 73, 9, 9, 9, 31, 85,196,249, +248,241,227,167,219,183,111,111, 91,167, 78, 29,157, 84, 42,205, 2, 32,207,202,202, 82,100,100,100, 16,181, 90, 13,158,231,121, + 75, 75, 75, 46, 33, 33, 65, 63,100,200, 16,205,245,235,215,107,228,231,231, 71,191,139, 5,203,221,221, 61, 52, 61, 61, 61,155, + 16,242,206, 46, 28,138,197,149,157,157,157,125, 94, 94, 30, 15, 32,179, 42, 46, 28, 88,150, 69,147, 38, 77,112,230,242, 61,156, +188,112, 29, 57, 9,207,240,249,103, 31,161, 94,189,122, 56,115,230, 76,149,243,172, 65,131, 6, 56,125,254, 42,174,222,125,128, +232,240,135,248,226,243,207, 80,183,110, 93,156, 62,125, 90, 40,208,239, 65, 96,181, 39,132, 20,127,137,191, 37, 87,107,219,147, + 6, 46, 53,101, 59,230,119,175, 81, 91,210,101, 62,136,196, 4,251,125, 78,183,254,122,209,154,167,245, 28,201,136, 71,201,149, +207,246,122,205,138,149, 76, 31,215,117, 32,187, 31, 60,169, 53,252,131,230,238,216,124, 84, 57, 23, 0, 6,183,241,198,237,231, +169,184, 21,158,178,251,113, 10,125,252,174,145,171,231, 72,148,160,216,253,227,164, 62,237, 61,221,156,176,229,208, 85, 16,130, +131, 6, 53,180,148,210,230,117, 60,177,114,251,155, 51, 6,157, 60,126,222,167,126,122, 38, 52,167, 59, 0,116,173,109,122,170, +105, 13,107,143,202, 44, 25, 38, 50,241,216,238,253, 63, 84,176,225, 71,129, 87,231, 65, 88, 13, 84, 58, 30,137,105,185, 40,176, +116, 71,208,141, 7,170,108,181,118,202,227,148,170, 89,237,194, 82,105, 84, 67,103, 18,147,151,175,114, 86,218,215, 80, 51, 34, +158,207,211, 80,220, 14,123,149,243, 56,145, 62, 51,132, 35, 50,146,106, 91,186,145, 54, 27,182,237,155, 39,145,202, 6, 51, 4, +196,193,202,212,126,195,242,239, 97,110,110, 6, 94,155, 7,228,167,162,223,132, 69,169,143,226,117,222, 0,224,107, 71,204,218, + 86,151,110, 19,139, 72,220,197, 8,237, 55,149, 61,131,232, 49,110, 68, 96, 67, 9,175,205,199,164, 31,247, 98,227,204, 62,248, +176, 83,109,201,137,107,225,227, 0, 44,168,106, 94, 83,142, 5,213,171,208,114,206,229,167, 4,184, 74,129,128,187,251,126,168, + 5,220, 51,152,163, 49, 33, 18,177, 51,169, 93,223,195, 84,202,199, 93, 3, 31,119,141, 50,238,173, 65, 60,218, 18,226,212,132, +254,242,211,183,249,155, 55,111, 57,203,139,240, 93,101, 46, 47, 4, 8,248,255, 10, 74,105,148,149,149, 85,183, 30, 61,122, 92, + 56,115,230,140,141,191,191, 63, 0,224,238,221,187, 0,128, 38, 77,154,192,215,215, 23,201,201,201, 24, 58,116,104, 90, 98, 98, + 98, 55, 74,105,133, 99,122,115,115,115, 95, 28, 56,112,192, 49, 63, 63,191,225, 55,223,124,147,226,233,233,153,163, 86,171, 73, + 86, 86, 22,207,178, 44,172,173,173,101, 13, 27, 54, 68,171, 86,173,242,110,220,184, 81, 45, 54, 54, 54, 23,192,171,170,132,191, + 79,159, 62,184,124,185,112, 18,222,251,240,139, 37,149, 74,225,239,239,239, 26, 21, 21, 21, 95,148, 62, 55,171,144,166, 37,255, + 31, 60,120,128,224,123,113, 16,107, 85,144,165, 38,224,230,161, 3,232, 61,118, 60, 88,182,234,163, 21, 30, 60,120,128,195,231, +111,194, 84, 46,198,179,103,143,113,224,192, 1,124,254,249,231,239,196, 89, 69, 84,168, 69,254,149, 2,139, 82, 26,140, 50,188, +208,214,168, 65,100,242, 60,204, 15,108,226, 58, 99,112, 64, 13, 70,159,147, 0,158,227,193, 72, 0, 7, 59, 11,236,216,177,219, +123,247,222,189, 55, 26,184, 74, 86,243, 44,251,245,163,100, 90, 96,196,179,231, 47,223,123,117,240,142, 47,219,139, 63,239, 94, +203, 6, 0,164, 98, 17, 86, 29,125,204, 2,152,255, 46,145,106,233, 70, 20,121,122,140,113,178,181,156, 59,251,211,158, 54,237, +155,248, 34,248, 86, 40, 86, 31,184,113, 89,150,130,237, 6, 23,106, 94,143, 55,117, 83, 89,179, 8,193, 87, 62,158,146,227,168, +147,212,212, 26,186, 87,151, 0,157, 26,106,141, 14,177,233, 28, 98, 51,212, 16, 43,165,184, 27, 30,167,178, 77,194,241,170,198, +153, 16, 66, 2,170, 43, 92,230, 45,252,217, 77,173,202, 99,115, 50,211, 88,169,236,166, 68,105, 34, 79, 52,134,231, 70, 28, 85, +183,243,150, 54, 6,120, 70,166,160, 5,115,166,141, 50,141, 15, 59,131,154,162, 4, 16, 74, 97, 82,187, 39,204, 77, 24,105, 27, + 47,105, 12, 0,120, 57, 89,202,126,252,238, 43,203, 41, 51,191,171,116,140, 87, 29, 66,164,245,154, 58, 77,241,247,180,198,229, +144,167,184,252, 40,250,241,229,187,207,234,118,168,231, 2, 95, 55,171,201,117, 8, 89, 18, 70,141,183,136, 22,102, 12, 11,232, +213, 37,179, 8,235, 56,146, 97, 77, 7,127, 83,230,236,193,242,224, 5,240,225, 28, 5, 97, 24,128,136, 10,103, 52,198, 94,131, +216,170, 58,221,189,239,112,193,150, 45,219,191, 15, 75,165,130,213, 74,128,128, 74,144,149,149,245, 80,169, 84, 6,214,175, 95, +127,235,164, 73,147,204, 71,140, 24,225,242,217,103,159,137, 0, 32, 57, 57,153, 95,185,114,101,194, 47,191,252,146,157,150,150, + 54, 90,167,211, 61, 50,228,131,151, 16,114,253,215, 95,127, 77,189,114,229, 74,221,102,205,154,201, 27, 55,110,204, 91, 91, 91, +139,229,114, 57,167,213,106,213,225,225,225, 92, 84, 84,148,115, 86, 86, 86, 4,128,200,170,116,223, 23, 89,171, 22, 48, 12, 51, +143, 82,234,255, 62,198, 96, 41,149, 74, 23, 0, 17,132,144,154,198,118, 15,190,213, 96,139,197,200,204,204, 68, 65,210, 99, 40, +226,158,163,190,169, 8,117,172,205, 96, 97, 97,241, 78, 98, 40, 59, 59, 27,200,143,199,213,171, 15, 0,150,133,165,165, 37, 44, + 45, 45,255,118,129, 85,158, 22,249,183, 91,176,222, 66, 93, 7,242,185,181, 12, 43,199,246,172, 33,245,242,112,131, 38,238, 46, + 30,196,230,225,235, 22,205,194, 24,185,185,122,236, 71,125,154,244, 31, 88, 13,237, 91, 53, 37, 94,206,150,147,151, 44, 95, 63, +161,174, 35,249,234,113, 50, 93,101,200,131, 31,167,208, 23,181, 29,200,150, 75, 15,227,198,185, 41, 85,224,121,138, 75,143, 18, +241,232, 85,230,150, 39, 41,244,133, 49,145,168,235, 66, 58,139, 33,218, 75, 41, 85, 88,154,154,230, 54,108, 80,203,174,115,203, + 6,162,110,237,154, 64,202, 0, 87,111, 63,192,212,229, 7,111,242, 60,237, 25, 98, 96,247, 96,225,140,193,215,133, 83,225,140, + 65,253,107, 51, 6, 41,165,180,112, 22, 97,197,195,186, 24,134, 36, 21, 68,223,113,146,216,250, 64, 21,121, 9,175, 50,121, 68, +167,228, 34, 71,236, 4, 77,124, 60, 64,249,152, 32, 74,171, 92,154,237,236,236, 28,188,235,248,214, 88,179,237, 0,116, 5,217, +120, 17,180, 21,121,153,137,248, 97,195,209, 26,110,110,110,237,226,226,226,130,141,168,100,124, 47, 28,223,237, 0, 10, 48, 18, + 57, 78,172,219,135, 52, 91, 19,216, 41,165,224, 85,169, 24, 59,101,132,101,247, 46, 35, 44, 1, 32,250,217,125,120, 42, 85, 6, +241,234,108,209,127,112, 7, 63, 43,232, 85,216,118,250,190, 90, 4,116,219,126,246,113,100,135, 90, 86,138,193, 1,158,214, 11, + 18,178, 6,160,138,206, 64,139, 45, 88, 37, 22,189, 42,204, 30,220, 79, 41, 87,219,158, 68,238,189,158, 98, 58,176, 75, 99,165, + 84, 76, 8,205,139, 7, 53,177,195,250,109,251,243,100,122,108, 18,154, 78, 1, 2, 12, 67, 65, 65, 65, 8, 33,164,222,244,233, +211,135,205,153, 51,167,173,169,169,169, 55, 0,228,231,231,191,208,235,245,151, 1,236, 54,102,182, 95,145, 96,138, 32,132,188, +136,140,140,116,220,185,115,167, 21, 0, 69,209,105, 53,128, 44, 0,201,239, 50,131,176, 88, 76, 17, 66,230,189, 71,209,112,178, +136,179,102, 85,238, 23,137, 68, 28, 33, 4,132, 16,200,229,114, 92,185,114, 5,131,122,118,193,147, 19, 89,240,183, 50, 67,179, +209, 99,177,247,220, 57, 48, 12, 3, 66, 8, 24,134, 49,170, 29, 17,139,197,184,122,245, 42, 62, 28, 58, 16,114, 49, 96,105,105, +137,233,211,167,227,200,145, 35, 16,139,133,213,244,254, 18,129, 5,130, 5,231,182, 46,146,130,211,227,216,214,101, 56, 30,154, +167,125,150,138,175,253, 82,177,242, 0,114,249,212,229,219,199,157,187, 26,186,244,227, 33,189,148, 29, 59,116, 65,199,246, 29, +196,117,155,182,155, 11, 96, 85,169,134,186,115, 69,190, 50, 56, 30,223,111, 58,253,116,236,222,160,112, 2, 93, 46,134,116,109, + 74, 57, 30,223, 87,210,248,191,197,105,105, 98,182,247,234,141, 27,214,208,229,225,213,253,139,138,106,222, 53, 0, 78,135,136, +136,231,248,101,219, 33, 62,232,246,179, 29, 90, 22,147, 34, 51,104,190,161,156,133,138,138,133,165,169,204,175,187,191,229, 41, + 30, 20, 86, 74,105, 45,202,115,176, 82, 74,106,117,173,109,122,138, 82, 74,205, 77, 36,181, 40,167,175,148, 83,165,101, 55,110, +251,109,203,207,159,124,242,137,105, 90, 92, 18, 18,114, 66,145, 39,115,133, 94,233,142,200,251,151, 85, 5, 26,182,210,198,187, +162,244, 76, 75, 75, 75, 9,185,149,129,189, 27, 22, 67,175,213, 32, 37,174, 80,163, 38,164,229,192,194,206,245,134, 49,156, 58, +150,207,238, 63, 98,140,212,196, 28, 38, 31,246,239, 37,139, 76,215,160,145,139,121, 97,101,145,151,138, 39,231,175,162,125,126, +161, 94,139,138, 21,193,179,129,139, 65,225, 52, 87, 72, 39,117,111,236,138, 23, 49,137,184,242, 56,126, 91, 84, 58, 77,168,110, + 75,182, 69, 38,100,141,235,211,194, 3, 43,142,132,125, 81,158, 40, 42,143,179,142, 35, 25, 6, 32,160,112,144,187, 10, 20, 8, +168,227, 72,134, 25, 50,115,176, 44, 78,177, 20,195,127, 62, 21,253,205,254, 59,105,125,102, 12,111, 99,209,170, 85, 15, 25, 88, + 45,114, 85, 26,125, 88, 38,205,121,151, 60,122, 7,235,164,192, 41,112,254, 43, 57,139,196,206,142,162,237,125,114, 38,224, 13, +191, 76,239, 26,247,210,221,129,148, 82,113,145,245,170,194, 65,238,149,113,150,238, 14,164,148,158, 44,178, 94, 85,104,197,122, +147,147,231,249,132, 38, 77,154,216,244,238,221, 27, 28,199,225,249,243,231,136,142,141, 69,231,113, 95,192,202,202, 10,151, 31, + 62,196,179,103,207, 48,111,222, 60,232,245,122, 28, 62,124, 56,174, 50, 78,177, 88,172,171, 81,163,134,180,111,223,190, 96, 89, + 22, 81, 81, 81,136,143,143,199,212,169, 83, 97,105,105,137,144,144,144, 18,206,180,180, 52,136,197, 98,221,223, 81,150,254,255, + 8, 44,128, 3,167, 71,246,185,249, 88,117, 5, 58,157, 30,181, 30,167,208,151,165,206,175,175,111, 75,142, 61, 12,125,250, 34, +228, 90, 71, 25, 82, 30, 21,222, 99, 4,194,211,104, 98, 83,119,113, 46,116,185, 22,136, 58,133,151,201,185,121,225,105, 52,209, +216, 72, 80,158, 35,208, 21, 0,137,119,113,253,114, 48,130,110, 62,192,157, 71, 79,185,235, 33,225,123, 69, 60,190, 15, 75,163, +207,171,240,213, 1,179,158, 43, 48,234, 81,132, 71, 83, 95, 71, 15,112, 44, 40,175,135,229,144,221, 24, 29,214,202,163,105,117, + 43,143, 66,203,149, 30,214,159, 94, 4,126, 86, 84,200,119, 39, 70,183, 41,192, 91, 62, 32, 55, 43,189, 69,167,118, 45, 77, 45, +107,119, 71, 90, 68, 56,158, 63,184,170, 10, 9,141,188,126, 39, 70,247, 78,214, 17, 87, 87,215,182,157,218,249, 97,200,216,217, +208, 21,100, 35, 42,232, 55,228,101, 36,225,202, 13, 51, 60,205,201,105, 9,192, 96, 11,214,245,104,125, 93, 0, 8,240,146,198, +152, 67,227,244, 81,175,222,144, 19, 53,120, 77, 14, 72, 65, 26, 34,227,181,217, 3, 54,196,114, 0,160,148, 19,177, 41,205,182, + 48,132,183,142,167,173,143,146,209, 99,251,185,199,224,249,194,101,150,120, 30,235,183, 95,140, 28,247,253,135,141, 80,199,195, +186, 1, 41,114,126, 98,112,165, 73,209,230,206,222,239,106,169, 47,204, 5,120, 29,174, 78,182,169,213,102, 85, 70,155,170, 90, +194, 30,197,211,120, 0,227,106,187,144,141,147, 87,157,158,219,228, 92, 88,192,151,159,246,177, 0, 21, 22, 70, 23, 32, 64,192, +223,143,188,188,188,177,163, 71,143,222, 40,145, 72,236, 1, 16,158,231,193,243,188,120,233,210,165, 18,142,227, 68, 34,145,136, + 99, 24,134, 61,121,242,164,158,227,184, 84,181, 90, 61,182, 50, 78,150,101, 35,199,143, 31, 95,163,178, 25,135,123,246,236,129, + 88, 44,214,177, 44, 27, 41,228,196,251, 20, 88, 20,223,181,254,112,254,124, 0, 4, 20,223,190, 33,174, 0, 0, 15,211,105, 66, + 93, 7, 50,181,110,211,118,243,139,239, 49, 54, 0,106,142, 27,216,180,158,239, 30, 0,208, 80,238,195,170, 68, 34, 71,163, 26, +220,176,105,203,189, 60,165, 98,150,210, 45, 34, 30,127,168, 89, 60, 49,100,230, 92,121, 72, 72,201, 10, 41, 94,192,153, 7,253, +179, 91,176,200, 29, 3,165,148,150,116, 11, 46, 83, 32, 45, 91, 83,169, 31,167,171, 47, 52, 93,154,122, 72,199,156,189,118,127, + 44,199, 81, 39,134, 33, 73, 42, 45,187,241, 93,197, 21, 0,196,197,197, 5,215,113, 32,103, 31, 54,112,236,106,167, 44,178,106, + 21, 0,105, 5, 56, 27,151,146, 27, 92, 21,206,204,124,125,159, 57, 43,143, 28,149, 73, 24, 49, 40, 45,116, 4, 74, 41,212, 58, + 46,163, 88,132,213,183, 37, 46,211, 15,179,123, 24,134, 68, 87,198,119,235, 89,226,138, 33, 75,206,127,245,248, 85,230,150,151, +153, 52, 20, 0, 94,102,210,208,154,182,100,110,100, 82,238, 87,161,209,153,203,140, 29, 55, 65, 9,174, 52, 29, 50,255,173, 99, +239,154,158, 79, 18,232, 3, 0,253,234, 58,144, 46, 67,190,252,229, 75, 66, 32, 44, 19, 33, 64,192,255, 35, 20, 91,177, 68, 34, +209,130,247,200,121,146, 16,210, 3, 64,132, 17,247,220, 2, 80,239, 61,199, 45, 29, 64,186,144,203,255,144,192,122,156, 66,215, +195,128,197,156, 13,189,174,220,251, 19,232,121, 0,182,239, 18,137, 34, 14,155,247,153, 48, 15,147,233,220,191, 34,193,139,196, +212, 95, 50,150, 39, 44,133, 6, 2,128,143,143, 15,141,136,136,192,187,122,193,125,146, 74, 31,224,141, 37, 23,202, 18,217, 0, +218, 24,194, 23,158, 70,191, 7,222,238, 2,142, 72,167, 63, 0,248,161, 74,113,174,162,167,118,131,203, 86, 10, 61, 7, 84,238, + 77, 95,128, 0, 1,255, 77,145,245, 23,112,158, 20, 82,246,255,185,192, 18,240,239,197,243,231,207,137,144, 10, 2, 4, 8, 16, + 80, 46,184,191,128, 83,112, 58, 44,224, 53,136,132, 36, 16, 32, 64,128, 0, 1, 2, 4, 8,120,191, 32, 0, 58,151, 41,197,141, +152, 29, 64, 8,233,108,180,212,175,132, 95,224, 20, 56, 5, 78,129, 83,224, 20, 56, 5,206,255, 30,103,101,220,255,153,217,137, +180,212,224,229,247,189, 1,232, 44,112, 10,156, 2,167,192, 41,112, 10,156, 2,167,192,249,255,109, 19,186, 8, 5, 8, 16, 32, + 64,128, 0, 1, 2,222, 51, 4,129, 37, 64,128, 0, 1, 2, 4, 8, 16, 32, 8, 44, 1, 2, 4, 8, 16, 32, 64,128, 0, 65, 96, + 9, 16, 32, 64,128, 0, 1, 2, 4, 8, 2, 75,128, 0, 1, 2, 4, 8, 16, 32, 64, 64,213, 65,140, 92,153, 68,128, 0, 1, 2, + 4, 8, 16, 32, 64,128, 33, 2,171,104,125,221,226,117,118, 5, 47,224, 2, 4, 8, 16, 32, 64,128,128,191, 87,144,252,199,180, +136,208, 69, 40, 64,128, 0, 1, 2, 4, 8, 16, 32, 8, 44, 1, 2, 4, 8, 16, 32, 64,128,128,127,135,192,106, 79, 8,161, 0, +218, 11, 73, 34, 64,128, 0, 1, 2, 4, 8,248, 7,240,159,210, 34, 37,131,220,133,241, 87, 2, 4, 8, 16, 32, 64,128,128,127, + 84,148,252,135,180,136, 48,139, 80,128, 0, 1, 2, 4, 8, 16, 32, 64, 16, 88, 2, 4, 8, 16, 32, 64,128, 0, 1,255,219,248, + 75, 7,185, 19, 66, 58, 11,156, 2,167,192, 41,112, 10,156, 2,167,192, 41,112, 10, 2, 75,128, 0, 1, 2, 4, 8, 16, 32, 64, +128, 32,176, 4, 8, 16, 32, 64,128, 0, 1, 2, 4,129, 37, 64,128, 0, 1, 2, 4, 8, 16, 32, 8, 44, 1, 2, 4, 8, 16, 32, + 64,128, 0, 1,130,192, 18, 32, 64,128, 0, 1, 2, 4, 8,248,135, 64, 0,148, 57, 19,128, 82,122,222, 96,146, 42,204, 38,168, +140, 95,224, 20, 56, 5, 78,129, 83,224, 20, 56, 5,206,255, 30,103,101,220,198,232,143,255,105, 80, 74,255,178, 13, 64,103,129, + 83,224, 20, 56, 5, 78,129, 83,224, 20, 56, 5,206,255,111,155,208, 69, 40,192, 80, 43,165, 35, 33,196, 81, 72, 9, 1, 2, 4, + 8, 16, 32,160,114,136,223, 39, 89,109, 66, 58,142,175,239,184,127,194,131, 36,155,202,174,117,112,112,216,168, 84, 42, 71, 20, + 20, 20,228, 19, 66,248,210, 22, 53, 0,165,221,203, 71,165,164,164,180,169,140, 79, 46,151,175,116,116,116,252, 52, 47, 47,175, +128, 16, 66, 9, 33, 32,132, 20,139,131,215,126, 57,142,139, 75, 75, 75,107,242,175, 22, 60, 0, 99,231,232,120, 91,194, 48,174, +198,222,203,241,252,203,228,164,164,150, 70,136,171,197,132, 96, 70,209,255,159, 40,165,179,255,131, 10,146, 49,228, 50,127,192, + 60, 28, 24,194,137, 68, 95, 72,128,181, 26,158,223, 80, 84,112,185,170, 62, 90,123,155,212, 32, 20, 13, 8,129, 37,165,200,166, + 4, 15,100,205,104,228, 63, 36,164, 91, 72, 36,146,193,214,214,214,230, 41, 41, 41, 23, 0, 28, 5,240,129,131,131, 67,167,204, +204,204, 92,189, 94,191,143, 82,122,179, 42,220,109, 27,146,153, 50,169,228, 99,181, 78,255,227,213,251,244,183,246,141,137, 45, +203, 99,137, 66, 42,110,163,209,178, 63, 93,121, 64,183, 24, 25, 86,242,134, 53,222,232,101, 41, 14, 24,152,239, 0,112,216,218, +218, 87,110,111,113, 65, 34, 99, 94,102, 37,231,141, 24,152,146, 18, 59,240, 29,242,253,127, 17,246,246,246,163, 68, 34,209, 66, + 74, 41, 56,142,251, 58, 61, 61,125,235,123, 42, 87,195, 0,152, 22,237,230, 83, 74,119, 27,113,111, 52, 0,143,162,221, 24, 74, +169,103, 69,199,255,163, 31,184,235, 15, 29, 58, 52,174, 67,135, 14, 88,177, 98, 5,214,175, 95,255, 42, 53, 53,117, 9,128,109, +148, 82,237,255, 42,183, 32,176,222, 19,234, 16, 82,239,147,110, 45, 79,140, 29,212, 77,102,192, 75,252,107,183,110,221, 62,220, +182,109,155, 36, 60, 60,220,196,203,203, 11, 34,145,168, 68, 0,149,174, 39,171, 85,171,198, 87,198,199, 48,204,170,126,253,250, +141, 62,112,224,128, 50, 36, 36, 68, 89,187,118,237, 18, 62,158,231,241,102,189,235,229,229, 85, 33,159,165,165,229, 93,134, 97, +220,202, 18,103,229,253,231, 56, 46, 46, 61, 61,189,137, 1,133, 57, 16,192, 44, 3,146,116, 9,165,244, 76, 69, 23, 72, 24,198, + 53, 33, 33,193,193,216,188,114,119,119,215, 25,241,242, 57, 18,130, 25, 60, 79, 69, 0, 32, 18,145,153, 38, 38, 38,235, 85, 42, + 85,108,241,249,162, 60, 75, 54, 38, 12,110,110,110,221,121,158, 31, 86,200, 41,218, 29, 23, 23,119,202,152,251, 45, 44, 44,238, +202,100, 50, 55,177, 88, 76,202,202,151, 55,247, 57,142,163, 58,157, 46, 46, 35, 35,195,104, 97, 29, 12,144,110, 64, 91,150, 97, +166,216,218,217,181, 9, 57,123,214,212,223,223, 95,196, 48,204,108, 0, 27,222,229,189,209,222, 38, 53, 56, 61, 6,169,244,242, + 94,114,207,111,125, 53,209,223,134,155, 72, 52,199,181,183,201,254,191, 91,100, 17, 66,186,141, 28, 57,114,209,143, 63,254,104, + 39,147,201, 68,251,246,237,107, 57,117,234,212,143, 87,172, 88,225, 58,120,240, 96,115,173, 86,203,207,156, 57,179, 45, 33,228, + 59, 74,233, 17, 99,184, 91, 53, 36, 45,252,188,156,231, 77, 28,209, 17, 95, 45,222, 51, 49,160, 30, 73, 51, 49,149,174, 31,208, +166,134, 85, 93,111,107,124,183,241,250, 36, 0, 91,140, 8, 43,145, 72, 36, 13,157,156,156,188, 52, 26, 13, 87,244,209, 70, 75, +213, 9, 0, 0,141, 70,163,203,204,204, 60,249,174,105,243,149, 66,209,188,185,149,217,185,249,195, 70,154,228,100,102, 56,174, + 58,113,244,225, 1, 56,212, 31, 8,188,250, 47, 53, 8, 34,145,104, 97,124,124,188, 51,165, 20,206,206,206, 11, 1,108,125, 79, +212,166,197,245, 48, 33,196,212,200,123, 61, 74,221,235, 97,192,241,170,148,125,133, 88, 36, 26, 47,147, 72,186,114, 28, 87,175, +168, 12, 61,210,234,245,231, 88,158, 95, 75, 41, 85,255,195, 89, 51, 99,220,184,113, 93,230,204,153,227, 53, 99,198, 12,204,152, + 49,163,218,230,205,155, 55, 46, 90,180,104, 38, 33,164, 62,165, 52,239,127,148, 91, 16, 88,239, 65, 92,185, 7, 54,244, 13,250, + 98,228, 32, 41,127, 96, 37,193,168,111, 42, 20, 87, 45,155, 52,249,120,219,182,109, 0,128, 17,125,250,160,107,179,102, 48, 55, + 51,133, 76, 86, 24, 28, 66, 9,164, 18, 41,250, 78,157,102,200,139,241, 83,255,254,253,135, 31, 56,112,192, 12, 0,214,175, 95, +143,254,253,251,195,198,198, 6, 74,165, 18, 82,169, 20, 18,137,228,181, 95, 3, 4,155, 91,124,124,188,131, 66,161, 40, 17,124, + 60,207,191,182,149,234,135, 6,203,178,240,241,241, 49, 52,185,102,101,103,103,183,205,207,207,175,176,239,214,219,219, 27, 0, +206, 24, 66, 56,103,198, 88,112,108, 62,196, 12,192,178,128, 70, 75,193,151,241, 45,239,226,226,134, 25,115, 22,227, 93,214,159, +236,217,179, 23, 0,172,119,117,117, 61,158,156,156,236, 79, 8,198, 86,197,178, 69, 41,253, 40, 34, 34, 66,201,243, 60,252,252, +252, 62, 4, 96,148,192, 18,139,197,110, 15, 31, 62,116,144,203,229,229, 90, 42, 75,137, 95,232,116, 58, 52,106,212,136, 53,230, + 25,142,128, 71,134, 72,244, 89,195,198,141,199,204,239,219, 87,113,251,246,109,133, 72, 36, 2,203,178, 88,186,116, 41, 75, 41, +181,170, 3, 88,132, 1, 57, 21,148,207, 57, 0, 70, 21, 89,101,183, 80, 74,151,190,118,158,162,129, 74, 47,239, 21,149,215,183, + 89,243,106, 51, 17,246,248, 81,179,234,102,135, 97, 46,214, 68, 2,248, 91, 5,150,165,165,229,192, 21, 43, 86,216,111,217,178, + 37,231,217,179,103,186, 13, 27, 54,216,143, 29, 59,182,150, 78,167,195,184,113,227, 82,253,252,252,164, 43, 86,172,176, 63,116, +232, 80, 32, 0,163, 4,150,152,224,251,161,125,186, 66,173, 23, 65,175,103,237,157,237,205,119, 76, 30,217, 94, 66,169, 22,219, +143,132, 64,207,242,191, 25,105,185,106, 56, 96,192, 0,207,221,187,119,139,159, 60,121, 34,174, 93,187, 54, 56,142, 43,217,120, +158, 7,199,113,240,245,245,125,231,116,249, 24,240,181,115,180, 57,215,178, 71,119, 19,103,133, 28, 54,153,169,248, 68, 42, 54, +223,170,212,236, 4,208,234,191,212, 32, 80, 74, 33, 22,139, 17, 27, 27, 11, 7, 7, 7, 19, 27, 27,155, 68, 0,223,102,100,100, +108,250,139, 68,125,149, 45, 91,239, 49, 12,205,100, 98,241, 31,219,127, 91,229,212,188, 85, 43,198,209,217, 1,225,207, 99, 32, + 38, 92,231,135,119, 66,218,127,252,249,151,147, 9, 33, 3, 40,165,183,255,137, 60,113,110, 49,161,159, 83,171,137,235, 65, 41, +230,255,114, 52,119,209, 79, 43,149,159,127, 54,146,153, 58,117, 42,220,221,221,189,250,245,235,247, 19,128,207,171,196,221,122, + 66, 63,231,128, 47,214, 19,202,227,187, 53, 71,115, 23,255,180, 82, 57,238, 61,113, 11,120, 15, 2,203,159, 16,171,250,158,142, +193, 63,204, 24,107, 70, 79,253, 46, 42, 72, 79, 65,121, 18,198,193,193, 97, 99,247,238,221, 71,108,221,250,231, 71, 81, 75,127, +127,244,235, 24, 0, 7, 91, 75, 40, 77,101,133,205, 16, 79,240,224,217, 75,131,132,128,187,187,251,184, 63,254,248,195,236, 79, + 17,225, 2,169, 84, 90,178,149, 22, 87,197,219,155,150,142,178,160, 80, 40,112,254,252,121,136,197, 98, 48, 12, 3,177, 88, 92, +178,149,222,103, 24, 6,142,142, 70, 13, 77, 90, 98,105,105, 89, 63, 55, 55,215, 34, 43, 43, 11, 30, 30, 30, 57, 0, 30,150, 58, + 95, 63, 53, 53,213,194, 24, 66, 78,159,135,121,211,186, 64,162,189, 5,157,180, 41,212,146, 86,184,118,251, 41,142,157,190,140, +248,196, 36,180,105,217, 0,163,134,245,199,158,157,155,192,113,156,177, 21,110, 50, 33,228,167,222,189,123,205, 4, 8, 58,116, +232,144, 60,121,242,100, 26, 26, 26,218,111,208,160,129,157,158, 63,143, 32, 69,150,173, 25,132,144, 85,134, 90,178, 40,165, 82, + 0,184,124,249, 50, 40,165,178,170,148, 61,185, 92,142, 27, 55,110,160,184, 59, 88, 36, 18, 65, 36, 18,129, 97, 24, 28,139,176, + 67,190, 86,132,130,228, 80,124,209,203, 3,222,222,222, 16,137, 42, 31,114,216, 30, 80, 92, 7,250, 17,137,100,170,179,139,139, + 87,187,234,213,149,231,207,159,103, 0,192,211,211,147, 38, 38, 38,102, 29, 57,114, 36, 87, 12,172,247,164,116, 91, 69,226,202, +195,195,163,181, 72, 36, 90, 88,156,230,132,144,159,188,188,188,230, 21,159,231,121, 30,195,186,216, 72, 38, 79,158, 34,109,222, +190,240,163,164,121,239,221,200,137, 90, 92,155,100,204,177,252,187, 43,131,236,236,236, 29,190,190,190, 76,106,106,234, 69, 0, + 47,244,122,253,154, 29, 59,118, 56,124,242,201, 39, 41, 59,119,238,156, 8,192,125,233,210,165,129,121,121,121,123,141,225,109, +211,128,244,104,210,208,191,133,135,187, 59,130,175,223,134, 84, 38,177, 26, 63,170, 23,204,204,196, 88,182,229, 4, 31, 29,151, + 49,241,202, 3,186,205, 8,113, 85,127,224,192,129,238,187,119,239,150, 2, 64,104,104, 40, 82, 82, 82, 96,107,107, 11,133, 66, + 81,242,206, 23, 91,177,222, 85, 92, 89,186,219,222, 58,124,248,136,137,141,141, 21,214, 76,155,140,143, 18,226, 96,193,136,160, +215,195,235,191,212, 24, 16, 66,124, 7, 12, 24,160,224, 56, 14,249,249,249, 8, 10, 10,178, 52, 49, 49,177,116,115,115,155, 15, +192, 96,129,101, 98, 98,146,172, 86,171, 29,138,234,209, 20,149, 74,229, 8,160, 64,161, 80,152, 20, 93,162, 50,210,178, 21, 83, +202, 66, 21, 99,192,113, 99,226,220,180, 89,211,250,231, 15, 30,216,101,150,157,155, 4, 43,235, 20,136,144,141, 77,155,214,194, +196,196, 2,243,231,207, 17,191,236,220,209, 53,176,199,128,243,132,144,206,255,132,200,162, 4,155,234,181, 29,108, 35, 83, 20, + 54,115, 60,167,199,134, 61, 95, 65, 36, 18, 97,222,236,177, 24,218,219,123,204,131,157,228,116,221,234,200, 45,172, 91,161,146, +136, 16,131,102, 52,197, 0,242, 77,157,123,143,176, 49, 81,154, 23,114,179,122,108,221, 60,185,144,123,222, 60,212,173, 91,119, + 12, 33,228, 27, 74,105,198,223, 80,254,218, 81, 74,131,203,219,255, 87, 10, 44, 66, 8,165,148,150,238,102,121,109,191, 34, 84, + 35, 68,238, 99,109,118,102,221,183,147, 93,152, 27, 39,196,170,152, 8, 36,168, 57, 88,253,217,136,190, 54,213, 82,169, 84,142, +216,186,117,235,107,250,203,195,209, 1, 82,169, 4, 18, 41,129, 85,155, 94, 0,128,172, 43,199, 65, 8, 45,175, 97,126,141, 51, + 63, 63, 95,125,255,254,125,179, 45, 91,182,192,193,193, 1, 94, 94, 94, 80, 42,149, 37, 21,109,233,173, 88,104,189, 41,176,222, +228, 44, 62, 47, 22,139, 33, 18,137,112,238,220, 57,176, 44,139,129, 3, 7,190, 37,174,196, 98,113,153,130,173,188,105,166,148, +210, 51,132,144,135,148,210,182, 69, 13,239, 67, 74,105,187, 82,207, 14,180,183,183,159, 5, 96,137,161,156, 98, 49,192,168,175, +131,119, 91, 5, 38,118, 18,116,124,125, 92,188,122, 15,191,111, 92, 9, 0,240,174,213, 4, 67,251,119, 7, 79, 11,173,111,134, +112,190,246,149,227,236,188, 45, 53, 53,173, 81,135, 14, 29,144,157,157,173,157, 63,127, 62,234,215,175, 15, 31, 31, 95,131,242, +168,156,151, 41,237,193,131, 7,206,106,181, 26,132,144, 52, 3, 4,217,249, 50, 56,176, 99,199, 14,168,213,111, 91,239,173,219, + 45,194, 87,253, 61, 49,250,139,109,248,233,217, 62,172, 91,183,174,194,184, 43,129,250,106,203,154,171,100, 12, 91,127,201,156, + 9,242,143, 62,250,136, 25, 61,122, 52, 98, 98, 98,240,201, 39,159,168,207,157, 59,167, 77, 74, 76, 60, 34,227,249, 53,186,215, + 5,113,185,156,114,185,124,251,153, 51,103,176,111,223, 62, 0, 64,120,120, 56,124,124,124, 94,107, 68,248,140,253,200,141, 94, +131, 91,199,158,162,121,239,221,184,117,108, 24,184,172, 19,146, 38, 62,200, 54, 38, 61,171, 96,169, 56, 95,198,177, 32, 0, 65, +165,210,247,155,157, 59,119, 14, 2,112,144, 82,122, 29,192,117, 0,123,140,225, 44, 36,194,232,193,253,251, 66, 44, 53,199,211, +136, 56,180,107,217, 8,142, 14, 14,120,248, 36, 18,209,241, 25,201,132, 96, 84,183,214,242, 37, 42,149,246,155,203,247,233,175, +149,113,186,187,187,123,239,223,191, 95, 82,202,226, 12,134, 97, 94,251,160, 42, 62, 86,213,242, 89, 44,174,204,221,204,110,125, +191,182,181,233,173, 71, 59,225,227,217, 3, 22,129, 61,176,124,207,110,196,165,101,171,217, 2,182,211,223,157, 71,127, 21, 39, + 33,196,183,127,255,254,215,119,237,218,101, 21, 27, 27,139,203,151, 47,195,203,203, 11, 5, 5, 5,149,126,232,190,201,169, 86, +171, 29, 74,137,166,226, 33, 12,123, 52, 26, 77,113, 69, 73,141, 9,103,121, 99,171,140, 29,115, 85, 70, 61, 47, 83, 72,165,251, + 15, 31,220, 99, 22,246,244, 50, 26, 54,104, 1, 51,203, 58,224,185, 36,164,103,228, 33, 51, 34, 1, 63,252,240, 19,230,127,251, + 53,142, 30, 58, 96,230, 87,187,193, 31,132,144,154,165,187, 11,255,142, 60, 34, 20, 99, 66, 47,239, 91, 15, 74,161, 74,121, 42, +151,170, 94, 40, 71, 14, 31,196,124, 52,180, 43,110, 94, 92,133,174, 13, 95,132,186, 56,160, 95,102, 81, 71,158,152, 65,186, 92, +129,107, 38,183,201,205, 98,145, 85,254,187, 73,199,156, 63,182,115, 61,161, 60, 84,201, 79,229,146,252, 23,202, 17,195, 6, 48, + 67,134, 12,193,209,163, 71,241,248,241,227,245,229,137,171,191, 32,238, 65, 69,223, 80,197,194, 42, 8,133,174,164,254,253, 22, + 44, 99,132, 85,209,245, 76, 99,153,248,224,111,243, 39,248, 43, 94,133, 74, 53,161, 55,144,160,225,233,150, 24, 54,115,101, 57, +247, 20, 20, 20,228, 71, 70, 70,154,140,234,215, 15,173,252,253,225,108,107,139,154,110,110, 48,145,203, 32,147, 74, 74,213,199, + 70,169, 94,234,231,231,135,222,189,123, 67, 34,145, 64,169, 84,194,204,204, 12, 50,153,172, 76,235,149, 68, 34, 49,216, 84,206, + 48, 12, 66, 67, 67, 17, 29, 29, 13, 43, 43, 43, 92,187,118, 13,157, 58,117,122,203,138, 85, 90,148, 25, 99,138,127,179,193, 47, + 22, 96, 48,176,107,176, 24,122, 61,144,143,250, 80, 68, 79,132,138, 52,128, 86,171,131, 86,163,193,175, 87,117,184, 29,153, 15, +157, 78, 11,173, 70, 93,238, 51, 43,178, 22, 56, 57, 57,245,171, 85,171,214,136, 97,195,134,105, 37, 18, 9, 10, 10, 10, 80, 80, + 80,128, 39, 79,158,104, 3, 3, 3,147,123,247,238,229,120,226,196, 9, 74, 41,126, 50,102, 28, 22,165, 52,211,197,197,197, 89, +161, 80,128, 82,154, 89,197, 47,158, 18,241,242, 38, 70, 45, 15,131,152, 41,204,147,245,235,215,131,227, 56, 84, 84,190,213,132, + 92,248,118,209,207,150, 63,174,252, 13,150, 54,142, 8, 14, 14,230, 78,159, 62,157, 75,128,240,231,143, 31, 47,255, 0, 56,185, + 31,208, 25, 19,190,204,204, 76, 19, 47, 47, 47,184,185,185,129,231,121,232,245,122, 60,124,248, 16, 73, 73, 73, 72, 79, 79,135, + 74,165,130,141,105, 22,106,216,186,129,205, 13, 66, 98,232,119,112, 54,123,138,109,103,180,250,198,190,120,240, 79, 87, 14,148, +210,147, 0, 78,190, 59, 17, 92, 29,156,220, 33,162,122, 36,164,164,163,111,207,174, 96,164,102,120, 25,155,134, 6,117,170, 59, + 15,255,160,181, 51, 67, 88,204, 88,178,123, 60,128, 95, 43,163, 43, 40, 40,224,158, 60,121, 34,121,240,224, 1, 24,134,129,133, +133, 69,201,112,128,210,226,202,144,225, 0,149,137,171, 69,235, 59,153,138, 36,249,200,225,206, 99,195,239, 55,225,227,209, 9, + 91,159, 62, 87,139,179,242, 58, 47, 83,171,195,255,205,149,191,179,179,243, 88,158,231,231, 83, 74,179,250,247,239,239,184,123, +247,110,235,248,248,120,132,132,132, 96,222,188,121,169, 28,199,177,148, 82, 66, 41,253,238, 61,148, 37,190,180,101,203,196,196, +164,216,178,149, 95,202,114,149, 95,133, 58, 64,162, 84,224, 11, 59, 11,210, 71, 44,178,240, 98,115,242, 94,166,105,233,145, 2, +150,255,133, 82,170,175,232, 94,145, 72,244,233,129,189,235, 93,236,236,121,180,183,239,136,196,100, 29, 22, 77, 27,137,244,244, + 92,252,186,121, 49, 0, 25,116, 44,131,182,237, 7,192,193,193, 21, 99, 62, 27,227,180,126,227,134, 9, 0,150,253,157,249,148, +120,115,237, 33, 66,200,121,123,123,251,199,147,199,141,179,175, 93,123, 28,228,114, 57, 46,158,254, 29,234,164, 29,185, 61, 91, + 65, 87,160, 70,207,106,189,169,205,171, 99, 36, 67, 34, 65, 4, 0, 72, 20, 72,148, 0, 21, 90,177, 18,175,253,201, 61, 97,204, + 24,123, 47,175, 15,161, 80, 40,176,103,207, 30,236, 94,179,134, 91, 9, 12,218, 72,200,165,177,148, 30,250, 27,163,252,175, 23, + 86,111, 9, 44, 99, 81, 93,170,188,190,121,218,224, 70,246,188, 74,172,189,122, 12,241, 26,158, 93, 26,161,211,221,205,162, 35, + 42, 40,208,188,135,135, 7, 58, 54,105,130,126,109,218, 64, 44, 22, 67, 33,147,194, 92, 97, 2,202, 21, 90,174,138,187, 8, 13, +213,122,197,194,198,214,214, 22, 82,169,180, 68, 88, 25,106,189, 42,143,147,231,121,136,197, 98, 60,124,248, 16, 1, 1, 1,112, +119,119,199,190,125,251, 16, 24, 24,248, 86,151,161,177,226,170, 88, 96,149,238,174, 43, 53,248,189,210,193,237,111, 66,163,165, +200,210,215, 71, 38,106,131,231, 69,224,120, 10,141, 90, 13, 74, 1, 74, 1,189, 78, 11, 77,145,192, 42, 18, 26,149,114,186,185, +185,185,120,121,121, 77,155, 53,107, 70,205,250,245, 27, 34, 45, 45, 13, 60,207,195,204,204, 12, 5, 5, 5,176,176,176, 64,171, + 86,173,238, 45, 92,184, 48,131, 82,204, 50,118,144,251,123, 48, 39, 3, 0,206,158, 61,251, 90,247, 96,241,150,159, 24,135,209, +147,118, 66, 38, 6, 30, 62,124,136, 90,181,106, 85, 38, 46, 69, 29,218,182,198,245,123,225,236,167, 51, 86,105, 36,233, 33, 75, +156,120,126,107, 28,144,252, 14,141, 10,210,210,210,144,156,156,140, 62,125,251, 98,247,174, 93,120,245,234, 21,234,212,169,131, + 14, 29, 58,192,193,193, 1,175, 94,189,194,237, 43, 26,104, 50, 51,144,161, 13,129,210,188, 57, 14, 7, 71,106,230,174,211, 70, +254, 83,149, 2, 33,164, 41,128, 79, 44, 45, 45,171, 21, 20, 20, 36,233,245,250,125, 69,162, 63, 80, 34,145, 12, 86, 42,149, 78, +217,217,217,175, 0,252, 74, 41,189, 83,105,151,145, 66, 97, 43, 87, 88,128,103, 53, 16,139,197,112,119,247, 2,229,180,200,204, + 81, 97,212,144,222,184,247,240, 9, 78, 95,186,201,234,245,252,106, 67,195,232,235,235,139,244,244,116, 48, 12, 3,165, 82, 9, + 83, 83, 83,248,249,249, 33, 54, 54,182, 68, 92, 85,181,139,240, 99,192,215,194,195,236,230,194,181,133,226, 42, 41, 33, 17,241, +175, 40,228, 50, 25, 54,110, 90,159, 95,144,148,217,252, 55, 32,252,223, 94,249,243, 60,255, 93,124,124,188,131, 88, 44,118, 98, + 89, 22,177,177,177,184,123,247, 46, 38, 78,156,152,156,158,158,222,158, 82, 90,165, 56, 42, 20,138,148, 98,203,149, 66,161, 72, +169,200,178,245, 46, 99,174, 8, 33,213,189,220,204,207,109, 94, 49,213,163,105,243, 86, 34,165,216, 34, 51, 47, 34, 41,224,234, +229,224, 86, 19, 87,252, 58,129, 16,210,149, 82, 26, 85,222,253,114,137,164,123,139,214,173,197,160,201, 16,203, 2,240,211,143, + 67,144,154,150,131,204,140, 92, 72,165,166,208,234, 25,112, 60, 65,171,128, 54,248,125,219, 94,212,253,236, 19, 70, 38,145,116, +249,187, 5, 86, 17, 22,255,242,203, 47, 30,117,235,214,197,111,191,253,134, 29, 59,118,196,140,232,148,242,199,212, 17,112,208, +233,208, 45,228, 25,108,170,245, 6, 66,158,193,166,177, 31,106,178, 98, 68, 16, 2, 19, 99,184,253,252,252,176,117,235, 86, 92, +218,190, 29, 31,101,103, 35, 88, 36, 98,244, 18,137,221, 73,189,126, 19,128, 67,127, 83,221,211,174,244,239,127, 65, 96,181, 39, +133,253,113, 37,191,149,221,100,234,232, 55,108,215,135, 93,154,212,241,118, 19,233,247,173, 66,124, 1,171,158,247, 76,199, 63, +203,165, 3,194, 42, 16, 7, 34,145,136, 50, 12, 3,115, 19, 19,216, 91, 89, 21,126,105,138, 68, 0, 15,240,122,128,112,133, 47, + 31,229, 9,140,153,252,204,243, 60,100, 50, 89,153, 3,218,141, 29,123, 85,154, 51, 55, 55, 23, 47, 95,190,196,152, 49, 99,160, + 84, 42, 1, 0, 73, 73, 73,240,244,244,132, 88, 44, 70,124,124, 60, 46, 94,188, 8,111,111,111,200,229,114,163, 84, 86, 41,107, + 82,125, 66, 72, 48,128,250,137,137,137, 22,206,206,206, 48,214,130,197, 81, 64,165,165,208,104, 89, 60, 15,143, 66,108,124, 2, + 94,188,136, 68,227,252, 28, 80, 48,160, 0,180, 90, 53, 96,160, 5,203,217,217,217,207,199,199,103,225,226,197,139, 37,238,238, +238,224,121, 30, 54, 54, 86,200,207, 87, 33, 61, 61, 29,117,234,212,129,187,187, 59,126,250,233, 39,160,176,251, 40,249,159, 42, +192,197,179, 69, 75,255,138, 68, 34, 76,250,192, 3, 25, 25,102, 96,152, 63,103,147, 86, 50, 6, 75, 10, 0,237,187,246, 23,159, + 59,125,210,148, 5, 22, 36, 49,204, 2,113,229,249,168,231,120, 94, 89,222,249,216,216, 88, 72, 36, 18, 28,216,191, 31, 25,201, +201,104,208,160, 1,154, 53,107,134,136,136, 8,220,187,119, 15,182,182,182,176,119,107,137,224, 23, 58,132, 37,168, 96,105,105, +137,200, 56,209, 63, 54,245,159, 16,210,171,115,231,206,107,150, 47, 95,238,228,228,228, 36, 73, 77, 77,101,215,174, 93, 27,184, +118,237,218,176, 9, 19, 38,212,153, 48, 97,130,181,189,189,189, 56, 41, 41, 73, 63,109,218,180, 64, 66,200, 44, 74,233,158, 10, +235, 11, 83,115, 27, 70,106, 10, 66,196,176,178,180,134, 88,102, 10,158, 21,131,227, 1, 11, 75,123, 92,191,119, 0,215, 30,229, +142, 77, 73,199,126, 3,222, 27,106,107,107, 75, 25,134,129,173,173,237,107, 93,131, 0,224,232,232,136,156,156, 28, 48, 12, 3, +137, 68, 98,180,200, 42, 22, 87,139,214,118, 50, 35,165,196, 85, 94,154, 45, 46,157,121,146, 85,144,148, 25,240, 95, 16, 87,197, +117, 28,165, 20, 47, 94,188, 64, 65, 65, 1,174, 92,185,130,239,190,251, 46,245, 77,113,229,232,232,248,153,133,133,197,183,121, +121,121, 63, 37, 38, 38,174,170,140,183,200, 50,245, 62,203,100, 52,222,112,199, 64, 8,145,184, 59, 43,206,220,187,178,211,211, +146, 62, 32,136, 30, 3, 60,207,121,108,126,203,161,109,143,166, 61, 69,141,214,125, 95,173,217,216,217,103, 8, 33,126,229, 89, +178,120,142,107,100,106,102, 14, 32, 5, 33,119,131, 74,196, 85,122, 70, 54, 52, 58, 6, 26, 45,129, 90, 39, 66,199,206,221,176, +102,195, 14,196,167,100,160,120,134,225,223,252, 78,218,248,251,251,143, 27, 52,104, 16, 22, 44, 88,128,101,203,150, 29, 6, 48, +100,201, 68,180,204,204,195, 40,151,222,212,166, 90,239,194,107, 7,206,164, 0, 96,147,122,158, 84,137,251,252,242,229,218,207, + 9,201, 17, 3,244, 4,199,129,167,148,136,254,166, 65,238,148, 82, 82,220,147,102,108,143,218,255,172,192,162,148, 6, 19, 66, + 80,250,183,162, 27,172,156,252,218,125, 51,115,242,202,214,125, 58,139,146, 62, 15, 64, 86,142, 70, 59,243,137, 94, 20, 87, 64, +251,133, 25,104,121,153,190,118, 45,238,133, 23,190,191,110, 14, 14,152, 49,124, 56, 40, 11, 92,123, 28,134,189,231,207, 99, 72, +231,206, 48, 45,154,193,103,168,181,169, 44,171, 85,105,235,149,177, 86,166,172,172, 44,236,223,191, 31,205,154, 53,131, 82,169, +132, 88, 44, 70,253,250,245,241,228,201, 19, 84,175, 94, 29,132, 16, 28, 62,124, 24,253,250,245, 67, 84, 84, 20, 90,182,108,105, + 86, 21,129, 21, 22, 22,102, 65, 41,109, 91,108,237,168, 98,201,132, 86,163,198,147, 39,207,208,173,103,127, 88, 89,217,192,201, +121, 55,206,159,217, 9,165,255, 71, 32, 40, 60, 95,214, 24,172,114,210,116, 96,207,158, 61, 37, 34,145, 8, 42, 85, 1,228,114, + 5,204,204, 44, 96,110,110, 9, 95, 95, 95, 36, 36, 36, 32, 48, 48, 80,247,252,249,243, 29,137,137,137, 39,140, 13,174,163,163, +163, 50, 55, 55,119,178,151,151,151,162,232, 43,183,163,157,157,221,162,180,180,180, 60, 35, 43,158, 18, 97, 69, 8, 1,195, 48, + 37, 2, 75, 44, 18,193,217,201,161,100,191,104,246, 39,169,128, 43, 39, 62, 93, 35, 7, 0, 15, 15, 15,172,217,120, 84,212,179, +103, 79, 76,158, 60, 25,122,189, 30,235,214,173, 3, 0, 12, 27, 54, 12, 58,157, 14,127,252,241, 71,225, 11, 36, 22, 87,216,231, +124,247,238, 93,132,132,132, 64,175,215, 35, 59, 59, 27,167, 78,157, 66,240,229,203,216,115,248, 2, 94,189,136, 64,125, 63, 79, +124,242,201,199,144, 72, 36,216,182,109, 27, 2, 2, 2,254,209, 10, 65, 42,149,142,220,188,121,179,235,214,173, 91,179,142, 28, + 57,146,221,188,121,115,211,149, 43, 87, 58,172, 89,179,166,131, 86,171,197,148, 41, 83, 82,110,221,186,149,223,167, 79, 31,203, + 77,155, 54,185,214,172, 89,243, 3,148, 49, 46,171,168,219,103, 8,128, 15,219, 55,179, 20,103,229,170,192,179, 90,188,120,245, + 18,217,121, 90,240,156, 14, 49,113, 9,200, 83,115, 72,207,200, 69,253, 70, 93,127, 9, 10, 10,250,154, 16, 50,135, 82,122,188, +210,143, 10,142,195,205,155, 55,113,237,218, 53, 92,190,124, 25,209,209,209, 37,231, 44, 44, 44,112,238,220, 57,116,232,208,225, +189,136,171,220,212, 66,113,149, 21,147,241,159, 17, 87, 69,117,208,124,103,103,231,249,206,206,206,138,179,103,207, 90, 86,171, + 86, 13, 44,203,106,223,180, 92,181,111,223,254,155,205,155, 55, 59, 87,175, 94,125, 34,128, 85, 85,125, 94,121,150, 45, 3,240, +150, 59, 6,145, 8,159,253,180,126,156,157,185, 44, 38, 1,207,127, 46,242, 5,200, 0, 5, 57, 64,208, 46,136, 91,207,125, 57, +177,239, 76,235, 89, 91, 23,124, 6, 96, 93,121,196,145, 81,177, 88,191,126, 13,166, 78, 25,133,223,127,253, 9, 60, 47,134, 70, +207,192,195,171, 5, 52, 58, 30, 68, 36, 70,131, 70, 77,112, 41,232, 10, 36, 34, 96,255,214,245,255, 68, 62,101, 16, 66,214, 29, + 62,124,248,139,201,147, 39,131,231,249,190,235,215,175,127, 62,107, 77,234,193,169, 35,192,188, 58, 70, 50, 66,158,193,102,224, + 76,138, 3, 63, 18, 52,246, 67,134, 82, 81,101,110,217,183,235,215,171, 82, 83, 83, 23,227,159,241,131,117,249,141,223,127,189, + 5,171,100,108, 74, 69,138,177,177,111,245,239, 45,109,172, 63,110,213,180,182,237,180,137,159, 73,162,146,212, 56,211,100, 90, +246,209, 21,115,205, 98,120,211, 41,209, 52,199, 40,171,203,222,139, 23, 75,254, 47,221,189,187,204,115,137, 3, 7, 26,252, 37, + 86,158,213,202, 88,203, 21, 0, 40,149, 74,171, 46, 93,186,160, 83,167, 78, 24, 48, 96, 64,201,152,171,134, 13, 27, 98,207,158, + 61,232,223,191, 63,238,223,191, 15,103,103,103,212,170, 85, 11,181,106,213,194,201,147, 39,141,125,105,192,113, 28,252,253,253, +139,103, 17,214,143,139,139,179,168,210, 11, 8, 10,141, 86,141,180,244, 12, 88, 91,219, 66, 38,147,161,121,243,102,248, 98, 82, +115,216,187,252,138,250,117,125,144,151,151, 7,158,167, 6,205, 34,148, 72, 36,190, 53,107,214, 68,106,106, 42, 82, 83, 83, 97, +111,111, 15, 23, 23, 23, 56, 58, 58, 98,197,138, 21,116,229,202,149,193, 28,199,237, 72, 74, 74, 50, 90, 17,186,185,185, 53,181, +179,179,251, 34, 37, 37, 69, 81,170,210, 84, 52,104,208, 96,163,139,139,203,186,132,132,132,107,198, 8, 44,157, 78, 7, 66, 8, + 78,188,112, 65,190,150, 32, 39, 46, 4,147, 63,240,124, 77,112, 73, 36, 18, 67, 6,234,230, 15, 29, 58,212,193,221,221, 13,177, +145,143,113,224, 0,197,242,229,203,113,249,114,225,123, 30, 94,244, 65, 80,188,223,161, 67, 7,120,121,121, 25,229,220,146,231, +121, 60,124,248, 16,187,143, 4,195,217,179, 54, 98,158, 63,197,189,147,199, 80,205,222, 6,117, 27, 53,129, 94,175,127, 39, 23, + 26,239, 3, 58,157,110,147,143,143, 15,180, 90,237, 5, 0,155, 31, 62,124,216, 47, 49, 49,113,197,209,163, 71, 93, 6, 13, 26, +148,112,236,216,177,169, 0, 14, 61,124,248,112,244,194,133, 11, 59,233, 11,187, 15,222, 2,195, 48,191, 79,155, 54,173,253,160, + 65,131,136, 84,164,215,158, 61,179, 77,204,178,122, 50,125,206, 22, 46,232,106,176,136,101,245,100,192,208,105,252,201,139,143, + 68, 99, 39, 45,229, 26,182,232,137,208,208, 80,167, 94,189,122,253, 0,160, 66,129,197, 48, 12, 56,142,131, 68, 34, 41, 17,208, +101, 93, 99,140,245,234, 19,160,186,133,167,217,205, 69,107, 59,155, 17,113,222,127, 94, 92, 1, 64, 90, 90,218, 70, 0, 27,109, +108,108,146, 77, 77, 77,145,155,155,251, 86,249, 35,132, 40,252,252,252, 20, 50,153, 12, 93,187,118,181,113,118,118, 14, 23,137, + 68,171,226,227,227,141, 86, 26,101, 89,182,170,234,166,193,218, 30,189,154,183,105,100,254,204,114,129,185, 66,172,190, 95, 45, + 92, 97, 65, 0,100,107, 28, 95, 92,143, 30,146, 67, 82,228, 13,155,116,104, 12, 11,177,105,175,242, 4,150,136, 97,238,101,103, +102,117,207,201,213,226,234,181, 80, 12, 29, 82, 19, 26, 29, 1,207,139,144,151,175, 1, 24, 9, 68, 0,134, 13, 31, 9, 74,196, +200, 72, 78, 0,195, 48,143,254,161,236,154, 61,110,220,184,238,115,230,204,241, 46,242, 85,229,121,108,207,220, 47,143, 92,217, +144,221,179,149,234,121, 99, 63, 0,128, 77, 99, 63,100, 72, 36,136, 16, 51, 72,167,244,181,217,154, 70,113, 23,249,193,154, 65, + 8,169, 71, 41, 45,248, 27,197,100,187,210,191,255, 9,129, 85, 25,124,170,187,117,107,215,180,201,164,175,231,124,109,254,252, +246,101,124,253,195, 47,124,205, 38,129,217, 63, 31, 58,157,155,109, 81,173, 99, 65,194,211,251, 6,107, 1, 0,221, 58,246, 71, +253, 58,205,222, 58, 25,208,161,208, 7,228,213, 75,119,145,156, 26,111,112, 35, 91, 36, 10,202, 28,115,101,200,212,252, 50, 42, +130,172,208,208, 80,135,184,184,184,215, 6,180,123,121,121,129, 16,130, 91,183,110,225,230,205,155, 24, 58,116, 40,196, 98, 49, + 36, 18, 9,130,131,131,115,171, 98,193, 66,209, 44, 66, 66, 72,160,155,155, 91,153,179, 7, 13, 73, 85,181,170, 0, 57,217, 89, + 56,123,246, 52,106,212,240,193,226,197, 11,225,234, 98,143,239,231, 79, 4,199,113,200,201,205, 45,241, 15,100,128,117,128, 22, + 91,135,120,158, 71,106,106, 42,188,189,189,177,118,237, 90,172, 88,177,226,151,132,132, 4,163,103,143, 88, 91, 91, 91, 40, 20, +138,177,189,122,245, 10,232,219,183, 47, 2, 3, 3, 95, 59,191,115,231, 78,179, 67,135, 14,205,116,119,119,111,199,243,252,250, +248,248,120,131,166, 5,255,246, 91,161,251, 36,101,139,249,152, 53,168, 26, 62, 28,191, 13, 63,255,124, 16,114,185,252,181,198, +118,193,130, 5, 21,138, 23,158, 82, 31,105,218,245,132, 47,103, 46,115, 88,188,248, 60,206,159, 79,129, 72, 36,130,179,179, 51, + 68, 34, 17, 94,190,124, 9,145, 72, 4, 79, 79, 79,136, 68, 34,196,199,199, 23,143,249,203,132,218, 48, 31,132, 34,145, 8,106, +181, 26,177, 49,175, 16, 23, 25, 14,179,156, 36,216, 91, 40,145,249,248, 33,234,127,242, 25,244,122,253,255,130, 85,227, 28,128, +115,165, 14, 29, 32,132,232, 9, 33,195, 1,236,165,148, 30, 44, 58,190, 5, 21, 56, 6,109,209,162, 69,195, 57,115,230, 72,138, +221,102,184,120, 44,100,117, 58, 29, 15, 0,126,245,219,190,166,242, 35, 34, 34,240,243,207, 63, 35, 63, 63, 31, 82, 35, 70,166, +119,238,220,185,100, 76,164, 84, 42,133,157,157, 29,116, 58, 29, 88,150, 53,186,107,208,214,211,237,151, 91, 33,193,220,131,200, + 13,170, 71,207, 78,153,196,189,228,145,151,102,247,159, 21, 87,111, 90,178,220,220,220,230,243, 60, 79, 41,165,115, 75,213,173, +114, 15, 15,143, 43,103,207,158,181,101, 89, 22,171, 87,175,182, 74, 74, 74,178,106,219,182,237, 44, 0,229, 10,172,114,220, 52, +148,135, 42,185,105,224, 56,248, 90,152, 91, 33, 19,113,208,216,233, 27,102,217,178, 25,231, 18, 63,187,239, 18,221,168,142, 41, +167,247, 22,229,104,225,170,180, 2, 79,105,185,142,208, 52,122,253,169,251, 33,247,186,122,184,215,100,142, 30,191,140, 62,253, + 6, 65,163, 17, 65,173, 39, 32,140, 4,132,145,162, 94,253, 70,168, 85,183, 62, 40,128,187,183,175,179, 90,189,254,220,223,157, + 63,142, 45, 39, 13,117,106,245,197, 42, 80,158,150,246,131, 53,237,139,113,120,124, 91, 98,121, 57,228, 71,105, 96, 11,156, 72, + 61, 79,160, 84,252, 57,139, 80, 34,170,220,117,133, 75,192,164,161, 46, 1,133,220,101,248,193,242,238,215,175,223, 98, 0,147, + 32,224,175, 17, 88, 30, 30, 30, 86, 14,102,202,223, 38,124,242,177,121,244,131, 27,136,123,120, 3,215,174,134,103,238,250,227, + 72,124, 78,118,234, 39, 70,136,171,146,238, 60, 91,167,106,240,170,253,182,192, 82,152,217, 3, 0,188,106, 55, 3, 99,106,105, + 84, 68,202,178, 94, 85, 69, 92,149,110,148,203,242,129, 53,118,236, 88,108,222,188, 25,173, 91,183,134,143,143, 79,201,151,178, +177, 86,178, 98, 71,136,165, 42, 57,163,103, 15,150, 22,107, 57,185,185,240,170,230,142, 95, 55,175,199,253,135, 97,176, 48, 55, +197,200,225,253,255, 20, 86, 28, 95,242,204,202,172, 36, 28,199,189, 58,123,246,108,189,193,131, 7, 83,177, 88, 76,178,178,178, + 96,105,105,137,181,107,215, 22, 36, 38, 38, 94, 50, 54,124,174,174,174, 61,109,108,108, 62, 29, 50,100, 8,227,231,231,135,228, +228,100, 88, 88,152,107, 9, 33, 50, 0,176,180,180,212,154,154,154, 98,204,152, 49,168, 87,175, 94,179,153, 51,103, 54,117,114, +114,218,158,148,148,244, 71, 69,101,137, 16,130, 61,123, 10,123,167, 62, 89,245, 20, 90,109,161, 64, 89,183,110, 29,138,198,178, +253,217, 21, 16, 25, 9, 24, 48, 51,197,204,204, 12, 62, 62, 62,101,230,125,155, 54,109,112,247,238,221,194, 46, 72,177, 24, 14, + 14, 14,184,118,237, 26,111,104, 30,137,197, 98,132,134,134,162,182,151, 29, 30,157, 63, 11, 59,165, 4, 13, 92,156,224,214,166, + 29,194,195,195,255, 81,235, 21, 33,164, 15,128, 94, 0, 78, 82, 74, 15, 17, 66, 6, 2, 8, 44,222,135,145,142, 69, 89,150,165, + 34,145,136,196,198,198,234,148, 74, 37,177,177,177, 17,203,229,114,104, 52,154, 18,161, 21, 17, 17,129,227,199,143, 35, 46, 46, + 14, 54, 54, 54, 34, 75, 75, 75,232,116, 58,131,102,148,114, 28,247,150,123,134,162,231, 26, 45,174, 70, 1,254,155, 23, 46,169, + 38, 23, 49,150,181,237,186, 33,234,113,132, 42, 47, 45,203,228,255,131,184, 2,128,204,204,204,141, 0, 54, 22,239,219,219,219, +143,102, 24,230,107, 75, 75, 75,203,224,224, 96, 43,123,123,123,178,109,219, 54,253,220,185,115,179, 24,134,201, 36,132,172,168, +136,175, 28, 55, 13,239, 34, 0, 61,223, 62,134,176,180,236, 72, 79,137,181, 11,255, 64, 77,175, 79,137,157, 85, 43, 83, 82,211, +158,212,245, 71,191,148, 39, 87, 71,179,145,173,146, 19,147, 68, 20,124, 88, 5,117,240,150, 89,115, 22, 76, 15,127,122,207, 67, + 97,161,192,216,113,115,112,226,244, 37, 16,145, 4, 87,174,223,130, 86,199, 33, 45, 35, 27, 67,134,141,128,155,179, 29,194,110, +158, 73,101,121,126,237,223,255,110,242,107,234,181, 27,102, 45,149, 23, 14,245,164, 60,135, 77,251,103, 21,249,193,154,138,181, + 27,255,168, 87,215,235,197,183, 85,241,131, 69, 41,191,166,107,159,209,214,114, 19,101, 81,154,112,216,241,235,151, 16,137, 86, + 97,222,188,121,240,247,247, 31, 95,180,114, 67, 6, 4,188, 63,129, 85,173, 90, 53,185,169, 4, 99,108, 76,164, 51, 38, 12,239, +107,159, 18,249, 24,113, 79,238, 21, 42,127,141, 74,159, 24, 30,220,192,128, 74,187,243, 27,190, 50,104, 69, 93, 84,106,181, 30, +198,114, 22, 55,180,111, 90,175,140, 17, 87,101,113,150, 22, 89,165,253, 94,185,187,187, 99,241,226,197,149,250,193, 42, 35,238, +197,199, 3, 1,212, 47, 22, 89, 40, 28,228, 30,104,200,204,193,242, 56, 29, 28, 29, 16,246,184,112, 86,191,127,109, 79,248,215, +246, 4, 5,133, 90,157,141,216,152,108, 80,158,130, 2,176,178,178,121,203,130, 85, 22, 39,203,178, 75, 14, 29, 58, 52,232,198, +141, 27,189,190,252,242, 75,113,199,142, 29, 11,237,247,249,249,106,106,192,218,107,101,112, 14, 63,125,250, 52,195,243, 60, 54, +109,218,132,144,144, 16,106,106,106, 54,197,204,204,124,155,133,133, 5,151,149,149, 53,252,179,207, 62,235,251,237,183,223,146, + 54,109,218,224,198,141, 27,196,219,219,187, 63,128, 63, 42,139,251,173, 91,183, 32, 18,137,192,102,196, 96,252,172,189, 48, 53, + 17,227,233,211,167,200,200,200,120,203,249,168, 33,233,201,243,124, 73,195, 93,188,181,105,211,166,164,187,177,121,243,230, 96, + 24, 6,247,239,223, 47,179,187,245, 13, 78,106,107,107, 91, 82, 62,164, 82, 41, 46, 93,186,132,239,191,255, 30, 30, 54, 86,200, +124,242, 8, 78,237, 59,162,203,199,159, 97,232,208,161, 96, 24, 6, 54, 54, 54, 37,150,222,202,226,254,142,130,170,132,147, 16, +210,187,118,237,218,179,195,194,194,220,234,213,171, 87,135, 16,210,222,223,223,191,233,163, 71,143,138,247, 37,148,210,125,198, +112,222,185,115,231,192,154, 53,107,198,141, 26, 53, 74,202,243, 60, 23, 29, 29,173, 7, 64,156,156,156,152, 59,119,238,240, 71, +143, 30,133, 74,165,130,155,155,155,200,213,213,149,156, 59,119,142,127,242,228,201, 45, 74,233, 28, 67,227, 94, 60, 83,176,120, + 48,187, 74,165, 50, 72, 92,189,201, 89,173,150,239,162, 78,109,253,220,211, 18,238, 35, 49, 62, 18,234, 12,107,253,165, 51,215, +140, 18, 87,127,117, 30,253,205,156, 11,158, 63,127,238,170,209,104, 32,147,201,176,110,221, 58,221,226,197,139,195,210,210,210, + 2, 40,165,170,170,134,211, 24, 7,164,149,113,102,167,227,196,225, 35,119,154,154,245,219,130,241, 9,169, 37, 3, 23, 41, 33, + 54, 7, 29,235, 4, 40,155,213,139, 23,157,156, 47,202,229, 10, 78,148,199, 73, 41,213, 18, 66, 6,245,235, 63,236,194,158, 61, +187,205,230,206,159,143,107,183, 30, 33, 61, 43, 15, 60,101,192, 19,130,175,191,158, 11, 39, 59, 27,228, 36, 60, 47,208,232,116, +253,222, 92, 50,231,239,200, 35, 74, 69, 19, 31, 5,239, 93, 69, 0, 94,149,250, 76, 46,206,123,161, 28, 57,188,159,120,232,208, +161, 56,116,252, 58,246, 28,123,177,126,247, 81,122,172, 42,249, 78,136,104,226,185,163,219, 86,137, 8,248,252,228,103,114, 38, + 55, 82,249,225,208,126,226, 65,131, 6,225,224,193,131, 8, 13, 13,221, 80,158,184,250, 43,226,254,255, 70, 96,153,139, 17, 26, + 80,167,186,107,155, 70,117, 21, 98, 78,133,184, 39,145,200,200, 87,227,220,227,232, 44, 17, 21,253, 94,213, 7, 22,142,157,144, + 34, 38,230,249, 91,231,178,178, 10, 71,230,229,230, 26,183,236,147, 72, 36,122,205,122,245, 46,150,171,210,225,116,116,116,124, +109,217,149,210, 13,118,241, 24,159, 42,184,104,152, 21, 19, 19, 99, 17, 19, 19, 3, 74, 41,110,221,186,101,209,188,121,243, 89, + 85,181, 94, 1,192,252, 5,171, 95, 91, 30,164,244,111, 89,199, 42, 67,106,106,106, 62,128,223, 28, 29, 29, 79, 76,159, 62,253, +163, 22, 45, 90,180,153, 55,111, 30,161,148, 86, 53, 97, 89,158,231, 17, 20, 20,132,131, 7, 15,114, 90,173,118,118, 98, 98,226, +179, 82,231,127,119,119,119,191,210,183,111,223,159,195,195,195,153,176,176, 48, 24, 34,228, 84, 42, 21,124,124,124,192,178, 44, +126, 28,239,142,220,220,122, 96, 89, 22, 28,199,193,212,212,244,181,117, 40, 13,201, 39,145, 72,244,154,101,164,120,187,117,235, + 22, 24,134, 65, 64, 64, 0,238,221,187, 87, 98,193,170,204,226,164,211,233, 98, 28, 29, 29, 29, 23, 44, 88, 80, 18,174,212,212, + 84,156, 61,123, 22, 45, 90,182, 66,157, 49, 99,145,144,144,128, 21, 43, 86,192,197,197, 5,139, 22, 45, 66, 70, 70, 6, 88,150, +141,249,155,235,129,110, 97, 97, 97,110,195,135, 15, 79,121,244,232,145,219,241,227,199,173,122,245,234,101, 58,108,216,176,148, + 71,143, 30,185, 17, 66,218, 2,216,103,228,251, 51,155, 16,114,122,209,162, 69,179, 38, 77,154,212,124,212,168, 81, 18,137, 68, +194,199,199,199,179,187,119,239, 38, 62, 62, 62, 34,169, 84, 74,206,156, 57,195,223,190,125,251, 38,203,178, 63, 82, 74,175, 24, +107,101, 46, 22, 87,198,142,185, 42,198, 20, 7,249, 72,115, 81,106,192,154,117,139, 69,126, 94,110,186,237,187,207,198, 94,185, +241, 60,138,209,176, 83,126, 3,162,254, 63, 54, 10, 12,195,236,171, 93,187,246,232,137, 19, 39,154, 4, 6, 6,202,191,253,246, +219,236,220,220,220, 50,197, 85, 89, 48,198, 77, 3,140,116, 64, 90, 10,191,206,254,234,248,148,105,245, 70, 87,255,212,169, 26, +206,231,167, 32, 83,204,136, 44,172, 68,104,228,201, 32, 55, 45,194,254,216,133,173, 47, 81,137, 95, 53, 74,233, 29, 66, 72,231, +186,245, 26,254,241,227,162, 31, 29,190,153, 57, 67,242,199,241, 83,160,172, 14,183,130,131, 97, 38,229,232,147,144,243,201, 26, +157,182,239, 63,181, 84, 78,242,141,213,123, 8, 33, 71,108,108,108,238,127,246,241,199,190,141, 26,125, 10,165, 82,137,253,251, +247, 99,219,202,149,220, 74, 96,240, 70, 66,238,141,165,212,232,118, 57,225,106, 9,247,131,143, 71,141,242,169, 93,123, 24,148, + 74, 37, 14, 28, 56,128, 29,171, 87,191, 19,183,128,138,186, 8, 69, 36,247,230,243,232,188, 91,207,163,243,192, 83,202, 83,170, + 17,137, 16,155,175,211, 45, 10,143,138,171,146, 24, 40,238, 34,252, 97,225,196,247,169,246, 75, 68, 79, 85,166,101,151,211, 56, +196,213,172, 89, 19,111, 90,180, 42,250,175,215,235,227, 12,164, 95,226,225,241,214,186,164, 75,170, 26,214,226,193,242,134,138, + 43, 67,253, 96, 1, 64,114,114,114, 42,128,101,110,110,110, 71,186,119,239, 62,148, 16,146, 84,197, 60,218,211,161, 67,135,161, +148, 82, 70, 36, 18,237,124, 67, 92, 1, 0, 98, 99, 99, 95,184,185,185,109,242,242,242, 42, 89, 0,186, 34, 78,158,231, 95,212, +171, 87, 79, 87, 86, 94,148,183,207,243,124,165,121,148,149,149,133,102,205,154,189,181,230, 36,165, 20,209,209,209,197, 22,166, +146,180,175, 72,184,229,229,229,141,253,226,139, 47, 54, 74, 36, 18, 15, 0,164, 88,220,114, 28,199,252,242,203, 47, 10,142,227, + 24, 0, 68, 36, 18,177, 18,137, 68,125,240,224, 65,150,101,217, 24,141, 70, 51,246,111,174, 7,246, 18, 66, 36, 0, 50,195,194, +194,218, 22, 89,174,226, 66, 67, 67,207,239,217,179,199, 17,168,220,125, 66, 57,101,243, 10,128, 43,132,144, 54,235,214,173,155, + 61,118,236,216,102, 67,135, 14, 21,183,111,223, 30, 39, 78,156,224,130,130,130,110,169, 84,170, 37,198, 10, 43, 66, 72,158,167, +167,103, 97, 5, 38,174,120,148, 3,203,178, 21,126,173,217,122,202,215,140,248,220, 69,177,105,201,217,188,180, 4,237,117,125, +158,118,206, 86, 32,244,255,115,163,144,148,148,244, 21, 33,100,238,138, 21, 43, 18, 26, 52,104, 32,151, 74,165, 90, 67,197, 85, +209,135,143,163, 17,101,132,175, 98,217, 98, 9, 33, 61,150,119, 25,120,164,221,215, 95,120,117,233, 16,160,116,175,230,224,250, + 36, 50, 25, 17, 55, 78,228, 63, 56,182,240, 21,213,100,246,161,148,178, 6,112,221, 38,132,212,252,114,198,151,197,139, 61,215, +239,116,238, 48,253, 31, 91,236,249,135,159,127,254,217,215,223,223, 31,251,246,237,195,153,109,219, 48, 56, 45, 13,151, 24,134, + 17, 73,165,182,199,116,186,101, 0,170, 42,130,126, 88,186,116,169, 79,237,218,181,113,224,192, 1,156,219,185, 19, 67,222, 31, +247,251, 68, 83, 0,246, 69,255,211, 0, 60, 3,208, 24,128, 9, 0, 13,128, 60, 0,118,165,174, 79, 47, 58, 87,124,254, 50,128, +191,117,160,107,185,181,211,163,231, 47, 27,191,239,135,169, 84,170, 12, 31, 31, 31,137, 49,247,232,245,250,148, 74, 42,208,184, +234,213,171, 27,108,165, 48, 68, 12,165,167,167, 55,249,171, 18,252, 93,198, 90,189, 37, 4,121,254,149,179,179, 51, 95,220,216, +151, 37,190,202, 58, 70,129,151,198, 60, 39, 46, 46, 46, 10,192,247, 85, 13,103, 92, 92,220, 41, 24,176,152,179,161,215, 1, 64, + 70, 70,198,123, 95,100,151, 80, 26,255,237,183,223, 26, 37,172, 65,105,124, 5,121,253, 8, 64,243,255,245, 6,149, 82,122,185, +168,242, 1, 33,164, 31, 33,164, 7,128, 51,148,210, 3,239,137,191, 68,104,109,218,180,105, 10,165, 20, 57, 57, 57, 43,141, 21, + 86,165,132,255,197,247, 21,247,140,100,237,197,221, 27,226, 58,170,178,116, 83, 54,231,105,183, 65, 64,113,158,169, 29, 28, 28, +126,255,240,195, 15, 91, 0,216,250, 62, 56,223,193, 77, 67,121, 97,124, 73, 8,105,112,233,203,239, 63,190,100,101,222, 19,156, +216, 15, 90,209, 49,104,211, 79, 0,248,205, 16, 43,120,233,248, 2,248,185,104,251,159, 66,145,175,170, 41, 35, 71,142,196,220, +185,115,113,242,199, 31,117,159, 19,146, 45, 1,232,233,194,143, 64, 17, 1,102,190, 11,247,232,209,163, 49,119,238, 92,156, 89, +182,236,189,113,255, 5,176, 39,132, 28, 7,128, 89,179,102,205, 89,188,120,177,245,236,217,179,235, 47, 89,178,100, 81,209,254, +227,226,243, 69,121,218,107,246,236,217,117, 75,157,207, 5,112,231,239,126,145,254,178, 13, 64,103,129, 83,224, 20, 56, 5, 78, +129, 83,224, 20, 56, 5,206,119,220,122, 22, 74,150,242,127,203,251, 95,234,216,223, 25, 94,136,132,111, 53, 1, 2, 4, 8, 16, + 32, 64,192,191, 17,165,173, 86, 85, 57,255,151,134, 13, 64,231,114, 44, 91,231,141,136, 96,231, 42, 88,206,206, 11,156, 2,167, +192, 41,112, 10,156, 2,167,192,249,255,139,179, 50,238,114,238,239, 73, 8, 57, 78, 41,237, 85,222,111,177,160,122,243,127,169, + 99, 70,175, 60,242, 78, 16,186, 8, 5, 78,129, 83,224, 20, 56, 5, 78,129, 83,224,252, 55,116, 17, 2,160,179,102,205,154,253, +111,232, 34,172, 96, 10,206, 1, 38, 62, 30, 22, 50,153, 82, 10, 0, 90,109,129,206,213, 21, 57,192,192,127,108, 33, 90, 1,255, + 90, 19,174, 99,145,152, 79,126,159,215, 10, 16, 32, 64,128,128,255, 55, 72, 45,182, 76, 1, 72, 5, 64,138,246,181, 69,191,169, + 69,109,199,155,255, 95, 59,255,119, 66, 92,158,184, 74, 75, 83,218,137,197,153,190, 28,167,174, 5, 0, 98,177,232,105, 90,154, +117,184,157,221,129,180,170,136, 44,123, 71,199, 16, 9,195,184, 26,114,173,158,227,226,211,146,147, 95,115,245, 78,129,127,189, +176, 51, 84, 60,188,139,200,248, 59, 4,138,189,189,189,163,163,163,227, 7, 22, 22, 22, 45,179,178,178,110,167,166,166, 30, 74, + 77, 77, 77, 46, 39, 60,139, 9,193,140,162,255, 63, 81, 74,103, 87, 16,118,131,175, 45,227, 94, 31,165, 82, 57,158, 16,226, 95, + 20,255,208,130,130,130,117,148,210,231,255, 15, 5,173, 9,128,190, 98,177,120,164,157,157, 93,179,164,164,164,111, 41,165, 43, +170,200, 37, 6,240,165,149,149,213, 80, 43, 43, 43,239,140,140,140,168,156,156,156,125, 0,126,166,148, 86, 58,229,249,187,201, + 46, 45,219, 7,182,255, 38,232, 76,208, 15,243, 87, 37,220,120,235,252, 87, 46,182, 93,187,180,158, 27,116,236,250,130,217,107, +226, 51,140, 12,155, 8, 40, 25, 71,202, 23,125,165,210,255,225,124,105, 1, 96, 78, 81,152,127,166,148, 94,250, 31, 47, 71,166, +142,142,142, 63, 2,232, 45, 22,139,195,226,227,227,199, 80, 74,227,222, 19,183, 4,128, 13,128, 12, 67,202,145,128,215, 33,151, +203, 87, 58, 57, 57,125,170, 82,169, 10, 8, 33,180,180,191, 70,150,101,227, 82, 83, 83,155,252, 7,163,125,231,223, 22,224, 50, + 5, 86,124, 60, 44,196,226, 76,223,148,164, 71, 67, 18, 18, 31, 14, 6, 0, 23,231,250,251, 28,156,234,237,141,143,151,233,154, +118,233,111, 38, 81,138,215, 49,140,164,161, 90,171,177,147,136, 37,105, 58, 86,127, 95,164,165,227, 19,159, 30, 44,211, 73,162, +132, 97, 92, 95,133, 95,114, 96,117, 25,144, 40, 92, 32, 49,241, 40, 55, 80, 46, 46, 46, 85,138,140,141, 77, 13,115,157, 92, 49, + 69, 34, 97,186,240,148,245,167, 60, 32, 34,146, 80,150,211, 95,144,106, 52,203, 51, 50, 34,115,171,154, 80, 45,125,108,125, 9, +213, 77,151, 16,218, 70, 79,201, 21, 74,164, 75,111, 60, 79, 15, 55,162, 66, 49, 72, 60,188,163,200, 40,125,239, 10, 74,233, 87, +239,187,192,184,185,185, 89, 15, 24, 48, 96,229,247,223,127,111, 98,102,102, 70, 98, 98, 98, 2,103,206,156,217,214,205,205,109, + 90, 92, 92, 92,194,155, 98,143, 16,204,224,249, 66, 7,165, 34, 17,153,233,232,232,168,100, 24,230,173,197, 67, 57,142, 83, 18, +130,137, 60, 95,184,224,184, 72, 68,102, 16, 66, 86, 25, 34, 20, 77, 76, 76,134, 53,107,222,106,218,143, 75,127, 54,115,116,112, + 48,101, 57, 94,247, 50,250,149,242,155, 89, 95, 53, 55, 49, 49, 89,165, 82,169,118, 27, 27, 79, 66, 8, 97, 24,102,136, 92, 46, +239, 5,160,118,209,225, 39, 26,141,230, 56,199,113,123, 13,109,200,157,156,156, 46, 51, 12, 83,205,152,103,115, 28, 23,147,148, +148, 20, 80,197,134,107,144,135,135,199,111,237,218,181, 83, 54,107,214, 12, 50,153, 12,115,231,206,253, 18,192, 10, 67,132,148, + 82,169, 28, 98,106,106, 90, 61, 47, 47, 47, 82,165, 82,253, 33,147,201, 58,175, 90,181,202,189,117,235,214,230,201,201,201,132, + 97, 24,199,227,199,143,127,180,122,245,234, 64, 66, 72,167,202,252, 12,101, 71,210,111,228,189,107,183,201,142,188,244, 13,128, +238,111,158,103,213,138,145,148,113,239,165,162,247, 98, 97,196, 20,121, 66,136, 72, 34,145,172,114,114,114, 26,173, 86,171,213, + 0, 40, 33,132, 58, 58, 58,150, 52, 52, 0,160,213,106, 51, 51, 51, 51,253, 42,226,170, 85,171,214, 93,134, 97,220, 42,200,143, +184,167, 79,159,190,143, 6,107, 70, 82, 82, 82, 15,137, 68, 66,220,221,221, 25, 0,151,140,136,175, 47,128,175,139, 26,153,117, +148, 82,142, 16,210, 1, 40,124,223, 1,252, 84, 44,216, 24,134, 89,231,231,231,247,193,147, 39, 79,214, 83, 74,127,168,106, 96, +157,156,156, 54,174, 93,187,118,112,159, 62,125,152,212,212, 84,215, 6, 13, 26,236, 2,208,230, 29,133,149, 12,192,108, 39, 39, +167, 9, 1, 1, 1,182,247,238,221,203, 32,132,172, 5,176,196, 16, 95, 83,132, 16, 37,128, 65, 0, 70, 2, 96, 0,236, 6,176, +135, 82,154,253,255, 69, 92, 49, 12,179,106,200,144, 33,163,119,237,218,165,124,245,234,149,210,213,213,181,196,233, 53, 33,164, +202,237,167,128,191, 73, 96,201,100, 74, 41,199,169,107, 37, 36, 62, 28,220,182,221, 47,150, 0,112, 57,248,139,193, 14, 78,117, + 67,101, 50,101,184,220, 66,113,176,127,239,206, 13, 7,246,106, 71,220,156, 29, 16,151,152,226,248,235,158, 51,221,142,159,185, +116, 16,133,142,191,202, 4,171,203,128,137,238, 60,158, 94, 93, 5, 81,195, 23,216,126, 41, 5,119, 30, 71,163, 32, 59, 13,110, +118, 50,204,250,164, 29, 26,214,176,175, 82, 68,204, 28,125, 59,136, 20,202,189,195,135,125,104,249, 65,223,218, 18, 79, 39, 39, + 80, 42, 71,120,100, 94,171, 83,103, 47, 53,253, 99,255,238,241,102,142,190, 67,242,146,195, 13,174,212,252,253, 45,173, 76, 84, +116,154,137,148, 14,237,214,188,142, 87,239, 46,173,136,183,183, 55,194,159,133, 87,191,116,237,206,232, 14,181,204, 95,170,116, +100,143,202,132, 44, 15, 13,205,206,170,200,170,244,166,208,232,212,169, 83, 35, 19, 19, 19,109,233,235, 84, 42,149,140, 16,116, +170,138,200, 40,126,134, 86,171, 17, 73, 36, 50,136, 68,100, 90,253,250,245,171,165,165,165, 93, 22,137, 68, 59,227,226,226, 50, +141, 73,207, 73,132,200, 50,197,226,198, 34,185,220,153,211,106,109, 1,128,200,100,153,110,214,214,245,190,158, 51,199,140, 97, + 24, 62, 61, 61, 29, 5, 5, 5,228,179,207, 62, 83, 68, 70, 70,246, 7,176,186,146, 48, 98,243,230,205,190,206,206,206,218, 55, +207, 37, 38, 38,202,250,244,249,160, 42, 21,182,111,139,150,173,167,158, 57,115,186,118, 78, 70,166,122,243,138,141, 33,122,133, + 82,227, 93,219, 79,178,110,211, 54,203, 49,163, 71,124, 65, 8,185, 79, 41, 53, 70, 12,123,152,152,152, 28, 92,182,108,153,127, +135, 14, 29, 36, 14, 14, 14, 72, 78, 78,198,147, 39, 79,252, 47, 94,188,216,119,219,182,109, 95, 18, 66,250, 83, 74, 13,241,184, +238,115,118,219,111, 14,102, 54,182,224,244,122,184, 53,104, 84,226,159,236,217,133,179, 96,245, 58,112,122, 61,234,245,234, 91, +104,134,225,121,212,169, 83,167, 74,222,114, 9, 33, 46,117,235,214,221,177,104,209, 34,169, 70,163,193,173, 91,183,112,233,210, + 37, 62, 49, 49,113, 73,101,226,138, 16,114,118,254,252,249,110, 1, 1, 1,230,105,105,105,224, 56,206,238,240,225,195,227, 27, + 53,106,100,225,238,238, 46,219,190,125, 59,242,242,242,192,178,172, 77,245,234,213,109,134, 13, 27,166,221,190,125,251,151, 0, +126, 44,207,114,149, 19, 73,191, 73, 34,213,187,249, 53, 30,137, 36,114,186,219,180,238,206,167, 44,106,144, 18, 75, 86,247, 26, + 53,204,171,215, 50,157,105,102, 81,207, 38, 39,254,252,204,238, 53,106,108, 62, 21, 89,249, 71, 16, 33, 68, 36, 18,137, 86,245, +239,223,127,248,158, 61,123,148, 79,158, 60, 81,214,174, 93, 27, 60,207,151,120,204, 47,118, 20,235,227,227, 99, 72,131,229,118, +225,194, 5, 7, 19, 19,147,183,156,242,230,231,231,163, 79,159, 62,127, 69,125,107,108, 30,127,247,226,197,139, 65, 7, 15, 30, + 28, 49, 99,198, 12, 31, 0, 19, 1,204, 77, 79, 79,111, 7, 0,182,182,182, 50, 0,151, 8, 33, 31, 79,159, 62,253,243, 89,179, +102,161, 71,143, 30,115, 9, 33, 11,171, 98,213, 35,132, 48,118,118,118, 61,250,244,233,195,232,245,122,152,154,154, 66,175,215, +215,120, 71,113, 37,151, 74,165, 71,151, 45, 91,214,101,216,176, 97, 16,139,197,224,121,222,230,236,217,179,243, 70,143, 30,221, +134, 16,210,189, 60,145, 69, 8,241, 2, 48,179,110,221,186, 35,102,205,154,101,210,173, 91, 55,228,229,229,225,192,129, 3,173, +215,172, 89,179,138, 16,114, 24,192, 66, 74,233,127,218, 73, 44, 33,228,167, 33, 67,134, 12,223,181,107,151, 25, 0, 44, 93,186, + 20, 83,167, 78,133,163,163, 35,204,204,204, 4, 69,243,111, 16, 88,149,161,160,160,160,209,236, 73, 31, 65, 36, 42,252, 74,172, +233,237,129,197,115,198,144, 35,199,207, 52,170,232, 62,137,194, 5, 79,175,172, 2,107, 55, 1,170, 2, 45, 66, 30,191,194,133, +159,187, 21,114, 4,206, 65,118,126, 11, 0, 0,165,212, 70,102, 98,242,147,150,227,174,193,201,233, 22,162,163, 83, 43, 19, 87, +246, 78,142,199, 55,108,248,209,196,191,134, 31,116,172, 30,241, 41,241, 32, 68, 14, 55, 87,115,124, 60,178,187,164, 93, 59, 23, +187,239,190,219,120,194,212,222,183, 95,126,106,120,165,142, 62,219,212, 52,189,221,175,113,141,198,189, 59,183, 18,249,248,213, +129, 84,161, 44, 57, 87,175, 97, 35,212,107,216,136,140, 25,157,235,253,224,193,131,111, 78, 7,223,154,211,166,166,105,200,149, +136,252,102, 21,189, 27,165,133,198,228,201,147,223, 90,144, 56, 49, 49, 17, 65, 65,239,212,107,240,218, 51,190,255,254,123,179, +172,172,172,206,191,254,250,107, 91, 87, 87,215,101,241,241,241, 55, 13, 33,249,136,144,106,144,203, 59,141,254,249,103,190,225, + 7, 31, 48, 86, 78, 78, 34,158,227, 72, 66, 84,148,237,138,213,171,219,103, 68, 68,152,228,219,216,100,100,170, 84, 5,225,225, +225, 80, 40, 20, 68, 44, 22, 55,125,147,135, 82,154, 76, 8,249, 73, 36, 34, 51, 9, 33,144,203, 21,225,227,198,141,187, 87,116, +186,218,177, 99,199,148,189,123,247, 46, 0,240,170,208,236,173,112,101, 24,145,111,225, 0, 65,252,100,136,176, 52, 53, 53,157, +244,195,162, 31, 77,115, 50,178, 84,186,252,124,189,189,133, 25, 33,102,230, 76, 78,118,110,110,124, 98,170,230,235,111, 23, 48, + 99, 63,254,112, 18,128,241,134,138,171, 6, 13, 26,220, 62,120,240,160,131,173,173, 45,178,178,178,144,158,158,142,219,183,111, +131,231,121,244,239,223, 95,222,170,121,179, 70,115,190,254,230, 6, 33,164,165, 33, 34,203,204,214, 14,223,183,106, 8, 0, 88, + 18,147, 94,146, 63,191, 12,236, 85,114,205,178,132,194, 15,112,133, 66,241, 46, 75, 61,181,236,212,169,147, 20, 0, 62,249,228, +147,156,220,220,220,197, 0,118,209, 10,156,161, 22,225,203,111,190,249,198,213,219,219,219,115,215,174, 93,200,203,203, 3, 0, + 7,111,111,111,248,249,249,113, 65, 65, 65,240,245,245,133,185,185, 57, 46, 95,190,140,155, 55,111,162,113,227,198,230, 82,169, +116,112,121, 2,171,125, 96,251,111,228,189,107,183,241,107, 60, 18,102, 22,206,216,188,123, 47,158,133,108,107,163,209, 61,249, +102,241, 68,215, 15, 85, 84, 62,202,205,199,124, 86,181, 38,237,108,107,214,253, 0,158,141,239,217,169,185, 43, 47,230, 78,168, +190, 68,172, 80,111,155,191, 44, 33,189, 60,113, 5, 96,105,255,254,253, 7,237,217,179,199, 10, 0, 30, 61,122,132,228,228,100, +216,219,219, 67,161, 80, 64, 34,145,148,172, 31,106, 40, 76, 76, 76,144,152,152, 8,157, 78, 87,108,181, 66,110,110, 46,156,156, +156, 10,213,205,119, 68, 52,127,190, 97, 94,199, 9, 33, 1,205,155, 55,223,233,233,233,233, 94,250,120,207,158, 61, 49,116,232, + 80, 0, 64,187,118,237, 58, 13, 28, 56,144, 22, 11,193,196,196,196,188, 59,119,238,116,161,148,222, 42,139, 83, 36, 18,169,226, +227,227, 49,125,250,116,188,124,249,114, 2, 33, 36, 26,128, 66, 38,147,149,124, 23, 19, 66,124,235,214,173,187,106,234,212,169, +136,140,140, 68, 88, 88,216,237,170,118,153, 82, 74, 57, 47, 47,175, 8,189, 94,223,132,101, 89,168, 84, 42,244,235,215, 79, 97, + 99, 99,147,204, 48,204,211,180,180,180, 17,148,210, 68, 35,172, 86,158, 98,177,120,205,244,233,211, 59,117,238,220, 25, 15, 31, + 62,196,193,131, 7, 49,108,216, 48,116,235,214, 13,203,150, 45,107, 55,113,226,196, 89, 0,230,151, 67,179, 35, 34, 34,162,165, +151,151, 87,201,106, 29, 86, 86, 86,248,242,203, 47, 49,105,210, 36,201,161, 67,135, 6,141, 24, 49,162, 54,128, 58,255,229, 6, +219,211,211,115,220,158, 61,123,204, 74,247,246,200,229,114,148, 42, 7, 2,254,215, 5,150, 86, 91,160, 19,139, 69, 79, 93,156, +235,239,187, 28,252, 69, 73, 23, 33, 32,122,170,213, 22,232, 0,128,227, 41,114, 10, 88,152,200, 69,120,149,148,139,199, 81,105, +101,189,164,175, 77,181,148,152,120, 32,201,227, 17,120,158,130,207,215, 66,149,157,132,197, 39, 10,240, 36, 78, 13,109,126, 38, +114,242, 11, 43, 55, 59, 59, 59,241,153, 51,167,166,158, 63,127,241,243,223,127,255,157,137,179,180, 12, 67,118,118,163,178, 56, +109,108,106,152,139, 77, 77,246,173,223, 48,215,132, 50, 81, 8,143,201, 71, 77,183,102,176,179,114, 71, 82, 90, 62,174,133,157, +196,211,231,199,225,237,236,137, 41,147,186, 41,126, 88,180,107,175,181,181,183, 71,102,230,139,156,242,194, 9, 0, 10,134,107, +250,237,238, 7,224, 50, 34, 65,179, 99, 64,243,223, 94, 37, 70,105,231,142, 90, 45, 29,161,180,178, 23, 61,122,186,162,105,121, +113,167,148, 38, 51, 12,179, 78, 36, 34,227, 9, 33,240,247,175,247, 98,229,202,149,218,178,146,222,223,191,222, 11,134, 17,121, + 23, 46,195, 34, 90,207,243, 92,114, 69,225,124, 83,204,200,100,242, 25,133,230,125,231,168, 83,167, 78,105, 7, 14, 28,136,165, + 75,151, 74,103,205,154,245,149,167,167,231,196,232,232,232,164,138,242,168, 63, 33, 30,174, 53,106,116, 93,120,237, 26,149,232, +245, 36,227,246,237,156,172,196, 68, 54, 41, 55, 87,182,255,233,211, 30,159,126,245,149,204,221,221, 29, 87,143, 31,183, 77,205, +207,167, 89, 26,141, 42, 43, 43,139,178, 44,123,187,156,184,207,118,116,116, 84,110,222,188,217,119,220,184,113,247, 18, 18, 18, +102, 23, 85, 12,139,139, 42,195, 87,165,142, 97,195,134,189,241,159,125,246, 89,120,114,114,242,236,138,194, 89, 10,117, 29,236, + 29,148,187, 55,110,127,104, 99,110, 34,178,119,115, 17, 73,172,172,196,172,204, 68,202, 3, 42,111,247, 26,166, 0,234,150,147, +102,231,223,104, 8,136,137,137,201,193,163, 71,143, 58, 72, 36, 18,112, 28, 7,123,123,123,188,124,249, 18, 89, 89, 89,200,205, +205,197,139,167, 79,224,229,238,142,239,102,205,116,158, 56,115,214, 65, 66, 72,147,210,141, 88, 89,225,228,116,186,183, 44,121, +229, 44, 16,254,218,175, 33,249,254, 6, 94,198,196,196,192,204,204, 12,254,254,254,102,215,174, 93,187, 82,158,184, 42,205,169, + 80, 40, 6,183,110,221,218,124,247,238,221,104,220,184, 49, 44, 45, 45, 17, 20, 20,132, 71,143, 30, 65,167,211,137,242,242,242, + 96,110,110,142, 37, 75,150,192,211,211, 19, 57, 57, 57,136,137,137,177,149, 72, 36,118,229,113, 6,157, 9,250, 33, 59,242,210, + 55, 73,228,116,183,205,187,247,226,179, 97, 67,224, 68,163,174, 88,214, 32, 63,116,237,221,122, 30,101,220,123,153,154,215,183, +246,241,239, 13,169,204, 12, 19,103, 44, 64,120,232, 49,235,130,220,135, 19, 8, 23,235, 14, 96,242,155,156,164, 48, 97, 68,238, +238,238,159,238,223,191,223,188,148, 5,170,100, 29,210,210,139,179,151,183, 16,123,153,121,196,113,208,233,116,208,233,116,224, + 56, 14,105,105,105,200,205,205,133,149,149, 85,225, 5,243, 1, 2, 66, 40,202, 22, 44,111,112,142, 56,127,254,188,187,169,169, +233,155,215, 32, 45, 45, 13, 44,203, 66,169, 84,150, 60, 83,175,215, 67,173, 86,155,213,169, 83,103, 60,128, 91,101,113,242, 60, + 63,109,240,224,193,173,111,221,186, 85,125,245,234,213,208,106,181, 75,147,146,146, 48, 96,192, 0,240, 60,143, 78,157, 58,181, +160,148, 62,251,250,235,175, 1, 0, 83,167, 78,213,231,231,231,143, 51, 36,238,229,136,162, 58, 3, 7, 14,172,126,225,194, 5, +180,105,211, 6, 26,141, 6,203,150, 45,179,216,176, 97,131,197,246,237,219,237,103,204,152,241, 27,128,192,138, 56,139,132,213, +156,110,221,186, 77,235,211,167,143,105,124,124, 60,172,172,172,176,119,239, 94, 44, 89,178,228,178, 86,171,157,179,125,251,246, +197, 7, 15, 30,108, 51,108,216, 48, 44, 91,182,108, 2, 33,228, 7, 74,169,190, 12, 78, 23,111,111,111, 60,124,248, 16,214,214, +214,176,179,179, 67,118,118, 54,110,222,188,137,219,183,111,163, 86,173, 90, 32,132,216, 87, 34, 26,223,251,194,196,127, 55,167, + 74,165, 82,199,196,196,152,253,248,227,143,112,118,118,134,167,167, 39, 20, 10, 5, 8, 33,208,235,245,229, 46,131,102, 72, 56, +219,183, 39,226,180,120,235, 62,150, 86,214, 19, 40,165,226,236,236,204,141, 58,100, 29,136,140,164,218,191, 43,238,255, 73,129, + 69, 8,161,148, 82, 82,252,235,234,138,156,180, 52,235,112, 7,167,122,123, 29,156,234, 22,153, 92, 69, 79, 25,198, 58,220,209, +177, 32, 7, 0,116, 44,197,245,167, 89,120, 24,145,132, 71, 17, 73, 48,149, 27,182, 76, 77,118,190, 22, 60,165,224,121, 10,117, +222,159,162, 76, 91,144,133,236,130,194,124,212,106, 10,144,157, 26, 70, 6,245,235,162,248,252,243,177,112,118,118, 45,247,197, +209,201, 21, 83, 38, 78,237, 97,101, 99, 37,193,241,107,167,209,162, 86, 63, 40,228, 18,164,103,171, 1, 2, 60,143, 58, 7,240, +230, 8, 13,143, 65,243,186, 74, 4,118,173,109,118,232,192,179,175, 0,204, 53, 36,188,186, 23, 65,144,213,233, 15,240,117, 65, + 51, 35,193,231,196,131, 42, 29,144,207,155, 32, 45, 33, 26, 79,175,236, 7,213, 85,190, 76, 23,199,113, 19,237,236,236, 82,102, +207,158, 29,224,235,235,171,157, 56,113, 98,232,203,151, 47,191, 46,125,141,151,151,215,194, 53,107,214, 32, 60, 60,252,213,226, +197,139,175,166,165,165,125,111,228,139, 57,139, 16,178,178,200, 26,150,118,244,232,209,250,151, 47, 95, 30,191, 98,197, 10,251, + 9, 19, 38, 72, 39, 77,154, 52, 2,192,210,138,186, 5, 77,229,242,206, 11, 47, 95,166,108, 92,156,102,199, 47,191,200,214, 94, +191,254,181,142,231, 93,236, 28, 28, 72,171,230,205,243,149, 34, 81, 90,122,114, 50,107, 95,189, 58,243,242,220, 57, 91,106, 98, +146,112,234,212,169,156,188,188,188, 63, 42,232,130, 41, 40,171, 91,176, 44, 56, 59, 59,107,203, 26,163, 85, 65, 67,144,195, 83, +170,179,242,246,166, 93, 59,181,172, 25,241, 44, 42, 74, 97,101,197,248,212,244,242,123,252,244,229,109,202,113,106, 66, 72,142, + 33, 92, 12,195, 12, 89,185,114,101, 61, 11, 11, 11,240, 60, 15, 75, 75, 75,164,166,166, 66,171,213, 34, 39, 39, 7,218,220,108, +104,179,179,241, 40,250, 37, 90,183,111,143, 65,221,186,214,222,126,248,232, 16, 0,123, 42,226,117,107,208,168,196,114, 53,203, +195,182,228,248,210,248,172, 18,177,245, 93, 67, 31,200, 77,205,208,237,203, 89,239, 82, 49,223,147,201,100, 39,251,247,239,223, +227,171,175,190, 18, 37, 38, 38,158, 38,132,180,166,148,134, 85,104, 97, 51, 51,171, 81, 44, 40, 44, 45, 45,177,114,229, 74, 56, + 58, 58,162,160,160, 0,119,238,220,161,110,110,110,228,210,165, 75,112,115,115, 67, 90, 90, 26,116, 58, 29,242,243,243,147,180, + 90,109,185, 5,191,168, 27,176,251,180,238,206,167,158,133,108,107,227, 74, 94,220, 25,252,101,187,136,103,143,158,198,156, 61, +119,237,123, 86,173,136,205,138, 59, 63,211,187,233, 61,187, 9,211,191,195,154,165,243,241,236,214,229, 12, 71,143,156,181, 38, + 68,179,181,121,151,242,195,155,159,159,175,126,250,244,169,249,131, 7, 15, 64, 8,129,165,165, 37,148, 74,101,153, 34,203, 80, +112, 28, 87,242,155,150,150,134,212,212, 84,132,135,135, 99,219,182,109, 72, 72, 72,176, 91, 97,105,145,100, 39,147, 62,148,102, +145, 57, 58, 29,189, 87, 9,221,198, 46, 93,186, 12,241,240,240, 48, 47,125,176,105,211,166, 24, 59,118, 44,214,175, 95,143,235, +215,175,191,182,222,101, 82, 82, 82,162, 94,175,223, 90, 65,222,102, 17, 66,186,245,235,215, 47,228,202,149, 43, 22, 91,182,108, + 1,203,178,101,110,155, 55,111,198,205,155, 55,231, 82, 74,159, 86,177, 27,170,214,128, 1, 3, 46,239,220,185,211, 42, 53, 53, + 21,105,105,105,200,203,203, 67,126,126, 62, 56,142,131,159,159, 31, 97, 89,214,175,178,238, 64,123,123,251,147,193,193,193, 29, +252,252, 10, 47,213,235,245,184,118,237, 26, 62,248,224,131, 28,173, 86, 59,128, 82,154, 78, 8,153,125,224,192,129,235,205,155, + 55, 71,211,166, 77,109,162,163,163,109, 0,148,105,185, 46,238,182, 77, 77, 77, 69,106,106, 42,126,253,245,207,117,156, 53, 26, + 77,105, 17, 94,141, 82,250,242,191,216, 96, 19, 66,136, 68, 34,193, 39,159,124, 2,177, 88, 12, 19, 19, 19,168,213,106,232,245, +250, 18, 17, 15, 35,187,159,125,124,204,109,197,144,126,230,235,219,118,202,160,201,189,236,157, 93, 92, 97,101, 33,199,147, 39, + 97,173, 47, 94, 56,247, 75, 29, 63,251, 13,188, 86,191,225,233,203,172,152,191, 33,126,175,105,145,255,104, 23,225, 64,206,206, +238, 64, 90,124,188, 76, 39,147, 41,195,139,173, 90,133,226,106, 32, 7,236, 6,171,211, 23, 85, 16,180,104, 51, 44, 45,114, 10, +180, 72,138,126,142,152,208, 75,112, 84, 39, 32,237, 69, 99, 64, 90, 15, 58, 85, 22,178,114,242,138, 94, 36, 14, 15, 66, 46, 32, + 39, 59, 3,254, 77,122, 1, 34, 81,185, 93, 91,150,182,164, 87,171,198,245,153,136,152, 80, 52,245, 29,136,234,110,109, 16,157, +152,131,172, 60, 13, 50,115,212,104,232, 63, 11,169,153, 42,228, 20,168, 17, 22,177, 29,174, 46,213, 69, 68, 28,213,201, 80,129, +165,126,176, 19,154, 71,123, 33,173,222, 1,178,186, 67, 32,113,107,137,216, 71, 65,184,127,242,103,196, 61,190, 10,202,115,112, +172, 86,219,160,184, 51, 12,179,241,236,217,179, 13,219,182,109, 43,238,212,169,147,191,155,155,155,127, 92, 92, 92, 40, 0,184, +185,185,249,119,235,214,205,223,193,193, 1,171, 86,173, 42, 96, 24,102, 99, 21, 27,217,210,149,211, 61,103,103,231,101, 7, 15, + 30,252,105,236,216,177,112,114,114,170,208,124,158, 42,145, 52, 24,181,104, 17,149, 48, 12,221,179,102,141,244,187,211,167,127, +254,125,235, 86,105,199, 14, 29, 8,165, 20,247,239,223, 87,254,184,102,141,114,120,159, 62,175,162, 83, 82,216,224,235,215,117, +137,113,113,185, 41,249,249,223, 37, 36, 36, 36,253, 19, 5, 88,175,215,223,120,241,242,133,107,147,230, 13,237,239, 61,121,241, + 56,176, 99,171, 86, 34,145, 72,244, 44, 42,250,186,189,189,133,242,220,217,115, 58,189, 94,127,195, 16, 46,185, 92,222,171, 99, +199,142,226,204,204, 76,184,184,184, 32, 53, 53, 21,241,241,241,133, 22,134,236, 76,232,178,179,161,207,201, 2,151,159,135, 23, +119,110,163, 97,117,111,249,254,194, 65,240,123, 42,201,147, 50, 45, 83,165, 45, 89,114, 51,115,200,205,205, 64,140,236, 30, 36, +132,244,177,178,178,154,153,149,149,117,146, 82,250,131, 78,167,155, 56,115,230,204,166,171, 87,175,182, 91,184,112,161,197,152, + 49, 99,246, 19, 66, 26, 82, 74, 53,229,113,228,229,229, 69,178, 44,107, 7,192,225,194,133, 11,112,112,112, 64,118,118,118,177, +101, 69, 91, 80, 80,160, 72, 79, 79,135, 70,163,129, 86,171,133,133,133, 5,238,222,189,155,201,178,236,209,202,194,103, 81,131, +252,160,209, 61,249,198,182,182,105,130,142,181,110,151,146,193,103,206, 95,150,176, 0,192,207,221,107,212,216,172,227, 47,191, +120, 30,122,204,250,229,157,160,140,132,231,249,213, 55,159,136,202,173, 32, 29, 41, 33,132, 39,132, 80, 95, 95, 95,164,166,166, +130, 97, 24, 40,149, 74,152,153,153,161, 86,173, 90,136,141,141,173,178,192, 98, 89,182, 68, 92, 29, 63,126, 28,137,137,137,216, +189,123, 55,220,221,221, 69, 0,236, 99, 99, 99,187, 12, 26, 52,168,185,173,173,245,226,244,244,204, 37, 21,132,243, 62, 0,139, + 55,242,169,131,157,157,221, 69,141, 70,131,168,168, 40, 28, 62,124,184, 61,165, 52,216,200,119, 59,138, 16,210, 45, 32, 32, 96, + 91,227,198,141,107, 80, 74, 81,175, 94, 61, 12, 29, 58, 20,219,183,111,199,131, 7, 15,144,157,157,205,159, 59,119,238,119, 0, +203,140,109,184,139,210,215,111,192,128, 1, 87,119,237,218,101,157,158,158, 14,149, 74,133,252,252,124,236,223,191, 31,173, 91, +183,134,157,157, 29,118,238,220,201, 82, 74,143, 85,192,165,176,178,178, 58,121,245,234,213,246, 53,107,214, 68, 88, 88, 24, 46, + 92,184,128,106,213,170, 65, 38,147, 97,196,136, 17, 22,235,215,175,255,130, 16,178, 68, 34,145,252, 48, 96,192, 0,112, 28,135, +107,215,174,165, 3,200,168, 76, 4,151, 99,217, 41,126,207,214,138,197,226, 97,132,144,174,148,210,219,255, 21, 97,229,231,103, + 93, 87,198,200, 39, 75,165, 18,219,204,204,204,146,186, 67,171,213, 66,163,209,188,102,185,146, 74, 37,182,205, 26,121,158, 80, + 21,228,206,121, 28,158, 89,238,152,180, 58, 53,173,234, 43, 77, 45,167,244,236, 54,104, 68,215,110,125, 25, 86,175,199,153, 51, +199,240,235,175,235,208, 33,192, 23,213,107,214,195, 23,147, 38, 91,106,180,236,172,115,231, 78,207,108,213,204,251,116,110, 78, +214,236,138, 56, 5,148, 33,176,202, 86,140, 3, 57, 87, 87,100, 22,189, 48,118,214,214,214,107, 56,142,235, 0,124, 6,137,153, + 19,194,238,222, 66, 70,166, 4, 26, 21, 87, 98,145, 50, 4, 89,217,185,136,126,120, 1,107,127, 89,137,244,244,116, 4,180,109, +143, 44,226, 6,107, 59, 7,100,166,167, 22, 85, 36,128, 78,171,135,189,163, 39,238,221,123,160,207,201,207, 47,183, 34,146, 42, +116,181, 61, 28,125,161,209,181,132, 66, 38, 67,118,174, 22,153, 69,226,106,231,129,193,208, 20,168,192,106,117, 96,181,122,216, +123, 12, 64, 45,199,142,224,185, 99,117, 13,172,208, 10,127,121, 22,218,136,115,208, 70,156,131,105,135,111,112,100,209,136, 55, + 94,124,195,102, 25, 39, 39, 39,167,186,185,185,157, 14, 9, 9,233, 53,120,240, 96, 4, 5, 5,141, 2, 48,173,168,113, 31, 53, +120,240, 96,132,132,132,224,233,211,167,167,147,147,147,223,139,207, 14,153, 76,166,214,106,181,197, 93, 65,138, 74,174,117,109, +218,191,191, 40,251,222,189,156, 21,215,174,205,223,188,101,139,180,115,167, 78, 68,207,178,224, 57, 14, 53,125,124, 72,215,174, + 93, 77,183,239,219,103,203,232,245, 55,167, 79,156,120, 97,253,135, 31,230,222,202,203, 51,116, 0,121,181,162,174, 65, 0,168, + 86,193, 49,131,161,209,104, 86,143,251,108,116,231,224,203, 87,221, 61,220, 93, 45,206,156, 11,126, 32, 55,145,137,170,123,213, + 96, 50,179, 51,196, 11,230,207, 49,209,104, 52,191, 24, 72, 87,219,206,206, 14, 73, 73, 73,136,136,136,128, 70,163,129, 94,175, + 7, 95,144, 15,109,102, 22,180,217, 25, 32,106, 21,228, 28, 7,117, 90, 50,170, 85,247, 6,254,156, 97, 88, 89, 3, 86,166,192, + 42,254, 85, 88, 90, 64,110,106, 6, 70, 34, 49,120,209,114, 66, 72,227,102,205,154,237,251,227,143, 63,164, 31,127,252,113,115, + 66,200, 26, 74,105, 52, 33,164,211,220,185,115,111,175, 89,179, 70, 62,118,236, 88,191,101,203,150,141, 4, 80,174, 96, 87,171, +213,251, 78,156, 56, 49,220,211,211,211,225,209,163, 71, 80,171,213,224,121, 30,221,187,119, 7,128,146, 50,243,236,217, 51,149, + 90,173, 78, 9, 13, 13,205,137,142,142,214,194,128, 89,127,243, 87, 37,220,152, 54,200,173,191,163,147,235, 77,133, 73, 53, 47, +154,119,175,223,180, 65,110, 75,151,239,143, 83,159,138,140,204,157, 59,161,250,146,252,220,135, 19,172,220,242,214,158, 58, 22, +101,200, 44, 95, 90, 60, 45,221,214,214, 22, 98,177, 24, 18,137, 4, 82,169, 20, 0,224,232,232,136,236,236,236, 10,187, 8,203, +107,188,115,114,114,144,157,157,141,167, 79,159, 34, 49, 49, 17, 55,110,220, 0,199,113, 40,156,164, 8,184,185,185,225,246,237, +219,230, 77,155, 54,157, 67,164,228, 18,213, 81,131,167,141, 51, 12, 51,229,195, 15, 63,132, 86,171,197,208,161, 67,177,121,243, +230, 41, 0,130,141, 45,239,148,210,155,132, 16,159, 7, 15, 30, 88, 0,248, 96,200,144, 33, 91, 7, 12, 24,128,224,224, 96, 28, + 59,118,172, 61,128,112, 0, 42, 0,139,139, 22, 86, 94, 92,209, 4,143, 34, 87, 12,235,236,237,237, 63,168, 91,183,238,131, 1, + 3, 6,248,239,218,181,203, 42, 37, 37,165,120, 82, 3, 94,190,124,137,223,126,251, 45,113,203,150, 45, 57, 28,199,217,138, 68, +162, 19, 89, 89, 89,229,205,130, 86,152,154,154,158,186,122,245,106,187,154, 53,107,226,252,249,243,152, 51,103, 14,218,181,107, +135,221,187,119,163, 86,173, 90,168, 87,175, 30, 28, 28, 28, 38,100,100,100,180,218,180,105, 83,251, 22, 45, 90, 96,231,206,157, + 72, 76, 76, 92, 87,145,203, 6,150,101, 43, 20, 88, 60,207,155, 14, 26, 52,232,243,149, 43, 87,194,195,195,227, 44, 33,164,217, +127,193, 77, 75, 45, 31,219, 37,205,154,182,155,233,236, 90, 19, 59,119,237, 70, 70, 70, 70, 73,251, 84,210, 70, 81,138,220,220, + 92, 36, 37, 37,193,210,194, 28, 75,151,253,208, 99,252,152,209,238, 0,252,203,172,232,106,216, 44, 27, 56,244,211, 47,135, 14, + 31,141, 71, 15, 66,176,125,235, 70,132, 62,186, 95,194,199,234,117, 8,127,114, 23,225, 79,238,194,209,201, 19, 93, 59,183, 39, +195,134, 13,235,254,225,240, 33,246, 0,254, 50, 23, 16,255, 37,235, 85,185, 93,132,111,188, 48,118,214,214,214,143,247,238,221, +107, 27, 16, 16,192,176, 44,139,211,103,206, 96,194,231, 31, 97,228,135,179,160,131, 53, 88,173, 20,188, 84, 97,208, 3, 51,210, + 83, 65,121, 30,249,249,249,184,126,253, 58, 56,189, 14, 31,142, 25, 9,158,231, 74, 4, 22, 64,161,213,233,224,234,225,135,117, +155, 23,178,144, 72,202,173,200,114,210, 25, 78,207, 82,196,167,196, 32, 38, 49, 20,150,230, 30, 16, 75, 60,144,158, 85, 0,177, +200, 9,122,245, 51,112, 69,230,211,130,252, 56,168,116,239,150,111, 92, 70,212,219,199, 88,214,224,251, 11, 10, 10,246,237,220, +185,179,235,242,229,203,165, 61,122,244,168,225,230,230,214, 12, 0,250,247,239, 95,195,220,220, 28, 59,119,238,212, 21, 20, 20, +236,123,143, 22,158,182, 77,155, 54, 69, 70, 70, 6, 94,189,122, 85,225,151, 7,167,213,218,154, 57, 56, 48, 41,151, 46,233, 83, + 51, 51,221, 59,118,236, 72,244, 44, 11, 17, 33,200,200,206, 70,244,171, 87,176,178,178, 34,143,159, 61, 51,251,229,139, 47, 14, +249,250,251,139,139,103, 24, 26,130, 99,199,142, 41,241,198, 32,212,178,142, 25,249, 66,230, 19, 66, 70, 79,156, 56,241,208,142, + 29, 59, 45,147, 83,146,195,229, 50, 25,107,102,166,112,249,112,196,120,113, 86, 86,214,112, 74,105,158,161,124,153,153,153,120, +241,226, 5, 76, 76, 76, 32,149, 72,192,171, 10,192,229,231, 65,157,145, 10, 70,167,133,140,227, 96,163,148,195,221,209, 17, 30, +246,118, 6,113, 62,187,112,182,100, 64,123,233,110,193,239,155,214,134,220,212, 12,114, 51, 51, 76, 61, 17, 84,244,245, 41, 5, +230, 85,222, 51, 76, 8,177,115,117,117, 61,186,107,215, 46,105,106,106, 42,238,223,191,255,128, 82,154, 77, 8, 49, 7,192, 63, +121,242,228,124,104,104,104,175,162, 89,116,149,205,254,250,249,224,193,131, 93, 2, 2, 2, 88, 47, 47, 47,211,228,228,100,143, +244,244,116,146,152,248,250, 24,230,147, 39, 79, 42, 84, 42, 85, 62,207,243,135, 80,232,199,169,210,130, 63,109,144,155,226,250, + 61, 76,106, 23, 88,173,158,133, 93,125,100,176,247,234,221,124,144, 56,105,218, 32,183,213,203,247,199,169, 77,136,102, 43,225, + 98,221,197, 10,245, 54, 3,243,155,218,217,217,129, 82,138,219,183,111,227,234,213,171,184,124,249, 50,162,163,163,255,180,106, + 91, 90,226,220,185,115,232,208,161,131, 49,239, 37,156,157,157, 97,109,109,141,237,219,183, 99,247,238,221, 37, 3,221,139,145, +150,150, 6,165, 82,137,229,203,151,155, 13, 28, 56,240,123, 0, 93, 13, 20,194,222, 93,186,116,233,233,236,236,140,244,244,116, + 56, 57, 57, 33, 32, 32,160, 55, 33,196,235, 29,186,178,198, 7, 6, 6,254,240,221,119,223, 65,175,215,227,147, 79, 62,193,243, +231,207,247, 61,127,254,124,165,135,135,199,164, 25, 51,102, 56, 58, 58, 58, 98,240,224,193,166, 0,250,151, 71, 98, 99, 99,179, +120,227,198,141,195,123,246,236, 41,210,233,116,109, 47, 94,188,136, 87,175, 94, 65,171,213,130,101, 89, 68, 70, 70, 98,226,196, +137,137,233,233,233,237, 40,165,145, 6,132,107,214,217,179,103,219,213,174, 93, 27,199,143, 31, 71,255,254,253, 47, 89, 89, 89, +249,214,175, 95,223,217,197,197, 5,251,247,239,135,133,133, 5, 60, 60, 60,108, 22, 46, 92,216,177,111,223,190, 56,126,252, 56, +166, 78,157, 26, 4,160,194,217,174, 44,203, 66, 44, 22,151,116,135,149, 18,175, 56,114,228, 8, 6, 12, 24,160, 88,191,126, 61, + 8, 33,200,200,200,176,176,183,183, 15, 37,132, 88, 84,100,189,253, 55,128, 17,145, 81,139, 22, 76,199,157,123,207,112,240,160, + 20,119,238,220,129,163,163, 35,228,114, 57, 40,165,208,104, 52, 72, 77, 77,133, 94,167, 65,189,186,222,216,182,101, 9, 82, 82, + 82, 1, 81,249, 99,210,136,136,140, 24,253, 81, 63, 92,185,122, 6,235,215,111, 68, 94, 94,126, 57, 31,221, 10,212,244,173, 13, + 87, 23, 7,196,198,197,130,136, 96,247, 87,198,245,255, 73, 23,225,159,176,178,178, 90,185,103,207, 30,219, 14, 29, 58, 48,249, +249,249,224,121, 30,109, 2, 2, 48,105,202, 20, 28,219,181, 11, 62,205,135,130,104,205,192, 42, 13,155,197,144,153,158, 10,189, +210, 25,125,251, 13, 68, 92, 92, 12,170,213,105,129,204,140,212,162,169,209, 92,137, 5, 75,171,213,193,206,193, 29,103,207,158, +101,240,201, 39,143,203, 21, 5, 58,217,195,240, 72,117,235, 44,213, 61, 92,191,179, 29, 58,141, 14,245,234,205,133,142,183,133, +131,219, 24,232,245,135,145,147,122,177,176,187,194,182, 3,226, 98, 98, 32, 98,164,143,141,177, 96,189,246,188,220,183,123,194, +120,206,112, 31,168,153,153,153, 57,206,206,206, 71,110,220,184, 49,168,127,255,254, 56,119,238,220,200, 34,129,133, 27, 55,110, +224,197,139, 23, 71, 50, 51, 51,115,222, 71,230,186,185,185,117,111,223,190,125,255,166, 77,155,226,248,241,227,224, 56,238,186, + 65, 47,180, 68, 66, 69, 34, 17,120,158, 7, 1,144,158,149,133,231,207,159, 35, 61, 45, 13,122,189, 30,249,121,121,124,109, 95, +223, 60,202,243,230,198,132,167,244,140, 65,148, 49,139,176,248, 88, 21, 68, 86,180,153,153, 89, 76,110, 94,158,189,181,149,117, +174, 76, 38,227, 50,179,178,178,195, 30, 63,210, 26,216, 40, 20,227, 73,104,104,168,127, 66, 66, 2, 98, 98, 98,192,230,231,130, +209,104, 33,210, 20,160, 83,171,150, 48, 1,133, 2, 60, 36,188, 30, 18, 70,130,220,194,217,118, 79, 42, 21,229,165, 26,132, 98, +113, 69, 8,129,194,204, 28, 82, 83, 83,200,205,205, 95,179,104, 25, 50,241, 75, 46,151,239,218,191,127,191,179,171,171, 43, 22, + 44, 88, 0, 55, 55,183, 90,245,234,213, 43,104,211,166,141,137,163,163, 35,234,212,169,131, 86,173, 90,225,212,169, 83, 0, 16, + 89, 73,250,177,132,144,174, 87,174, 92,249,242,218,181,107,131, 8, 33,100,214,172, 89,232,214,173, 27, 20, 10, 5, 10, 10, 10, +144,153,153,137, 77,155, 54, 17, 74,105,163,162,176,122, 42, 20,138,221,132,144, 56,149, 74, 53,248, 77,206,237, 43,234,187,164, +100,240,159, 56, 58,185,246,107, 23, 88,173, 94,199,192,206,240,246,233,136,142,129, 49, 0,176,196, 70,252,106,232,210,111,252, + 15,217,185,219,252,118,246,244,185,249, 1,237, 58,126, 61,107,172,245, 15, 75, 54, 86, 94,246, 9, 33,224, 56, 14, 98,177, 24, + 34,145,168, 76, 43,149, 88, 44, 46,153,109,102,128,245, 42,174,111,223,190, 37,251, 9, 9, 9,118,238,238,238,162, 98,203, 21, + 0,100,103,103, 35, 54, 54, 22,122,189, 30,182,182,182,208,233,116,245,141, 40, 87,147, 62,254,248, 99,162, 82,169,240,233,167, +159, 98,243,230,205, 24, 58,116, 40, 9, 14, 14,158, 4, 96,138,177,229, 93, 36, 18, 45,157, 49, 99,198,151, 19, 39, 78, 68, 70, + 70, 6, 78,158, 60,137,238,221,187, 99,239,222,189,246, 39, 79,158, 92,212,161, 67, 7, 48, 12,131,227,199,143,131,101,217,103, + 21,113, 73,165,210, 15,122,246,236, 41,138,141,141,133, 84, 42, 69,147, 38, 77, 16, 23, 23,135,130,130, 2,196,199,199, 99,242, +228,201, 73,233,233,233,237, 13,121,143, 8, 33,146,154, 53,107, 78,172, 85,171, 22,206,157, 59,135,129, 3, 7, 6,235,245,250, +158,169,169,169, 19, 51, 51, 51,127, 26, 49, 98, 4,252,253,253, 17, 30, 30,142, 46, 93,186,160,117,235,214, 56,121,242, 36, 62, +253,244,211, 32,189, 94,223,179, 18, 63, 88,207,142, 30, 61,234,209,169, 83, 39, 20, 20, 20, 32, 39, 39, 7, 18,137, 4, 86, 86, + 86, 56,117,234, 20,170, 87,175,142,245,235,215, 99,202,148, 41, 88,185,114, 37,111,111,111,207,106, 52, 26,233,127,193, 10,194, +115, 60, 0, 30, 94,238,102, 56,115,108, 11, 66, 30, 68, 33,228, 65, 40,100,242,194,193,237, 42, 85, 1, 26,213,171,137,230, 77, +154, 33, 33, 49, 30, 59,182,111,129,141,157,107,133,245, 8,165, 20, 82, 49,135,218,190, 78,216,181,125, 35,142,159,188,128,237, + 59,118,163,184,183, 67, 44,150,160, 97,163,230,104,210, 36, 0, 81, 47, 34,177,101,203,122,216, 59,184, 11,125,126, 85,237, 34, + 44,253,251, 90,230,242,124,199,128,128, 0, 38, 47, 47, 15,106,181, 26, 73, 73, 73,120,245,234, 21,172,172,173, 16,149,240, 18, +237,149, 58, 36,241, 57,120,242,224, 49, 71, 24,201,253,202, 30,184,225,187,207, 42,111, 48, 65, 97,106, 97, 7,141, 70, 3,157, + 94, 31,129,213,171,203,253, 82,102, 57,253,249, 51,231, 46, 54,251,120,228, 7,146,179, 23, 55, 67,175,229,161,210, 91, 34, 95, +173, 69,190, 78, 2,145,101,119, 32, 45, 24,140, 88,142, 22, 13,106,226,208,193, 83, 58,202,234, 47, 24, 88,178, 33,118,174, 15, + 54,241,225,159,135,222,152, 77, 40, 85,154,129,231, 88,227, 94, 24,158, 63,180,107,215,174, 30, 45, 91,182, 84,118,232,208,161, +122, 81,131,169,221,181,107, 87, 65,145,117,192, 88,213,255,154,247,118, 87, 87,215,250, 98,177,184,127,175, 94,189,234,143, 30, + 61, 26,143, 31, 63,198,206,157, 59, 35,124,125,125,175, 86, 40,172,100,178,244,188,148, 20, 43, 51, 47, 47,177,181,185,121,194, +169,147, 39, 61, 59,119,233, 66, 98, 98, 98,144,158,158, 14,181, 90,141,251, 15, 30, 80, 9,195,196, 17, 11, 11,209,179,123,247, + 68,140, 76,150,110, 68, 80, 95, 85, 50,139,112,113, 85,173, 89,238,206,214, 53,230,207, 26,231,173,214,168,253,115,114,114, 88, +177, 68, 34,113,115,178,138, 54,178,187,241,248,249,243,231,251,118,238,220, 89, 30,254,240, 62,216,236,108,104,179, 51, 33,229, + 57,216, 52,106, 0, 70,167, 1,180,122,184,214,166, 80,103, 41, 17,124,235,153, 94,163,209, 84,186, 82, 59,199, 22, 10, 44, 81, + 41,103,128, 0, 32, 51, 55,131,194,220, 2, 10, 51,179, 55,187, 16, 73, 37,249,173,252,224,131, 15, 58,181,104,209, 2,148, 82, +108,218,180, 9, 58,157, 78,166,211,233,160,213,106,161,211,233,144,147,147,131,237,219,183, 99,221,186,117,215, 0,252,110,128, + 72,101, 37, 18,201, 68,150,101, 29,228,114,185,206,222,222, 94,186,111,223,190, 18,183, 17, 13, 27, 54,132,169,169,169,134, 16, +162, 3, 0, 39, 39, 39,253,214,173, 91,197,125,250,244, 41,179, 17,243,171, 87,107,186, 55,107,221, 78, 97, 82,205,203,194,174, + 62,188,125, 58, 2, 0,186,244,250, 24,222, 53, 61,144,147,246,208, 75,173,122,213, 79, 42,206,180,126,188, 58, 62,204,164,167, +255,232,252,148,160,231, 0,182, 24,248, 14,161,115,231,206, 8, 12, 12, 44,233, 14,116,112,112,128, 86,171, 5,199,113, 70,185, +186, 40,118, 34,250,221,119, 68,132,249,192, 10, 75,139, 36, 0,246,165,197, 85, 76, 76, 12, 98, 98, 98,138,173,194,149,230, 81, +169,188, 50,241,241,241, 25,213,168, 81, 35,156, 60,121, 18,119,238,220,137, 63,115,230,140,107, 64, 64, 0,188,188,188, 70, 19, + 66,230, 80, 74, 85, 70,188,235,166,109,219,182,253, 98,226,196,137, 8, 13, 13,197,184,113,227,210, 99, 99, 99, 15,237,219,183, +239,211,249,243,231,139, 2, 3, 3,145,152,152,136,165, 75,151,114, 87,175, 94, 93, 6, 96, 65, 37,249,254, 52, 54, 54,214, 77, +173, 86, 35, 35, 35, 3, 44,203,162,160,160, 0,167, 78,157,194,246,237,219,147,139,196, 85,132,129,193,179, 9, 8, 8,176,126, +254,252, 57,182,108,217, 2,173, 86,251, 53,165, 84, 77, 8,249,125,230,204,153,115, 28, 29, 29, 45,187,116,233,130, 70,141, 10, +125,193,237,221,187, 23,147, 39, 79, 14,210,106,181, 61, 13, 72,131,225, 35, 71,142,252,202,197,197,101,242,140, 25, 51, 76, 58, +119,238,140,141, 27, 55,130,101, 89, 12, 26, 52,168, 68, 92,237,216,177, 99,215,142, 29, 59, 6, 2,144, 2, 80,252,219,173, 87, +127,230, 19,135,130,204, 80,112, 26,107, 52,172,231,135,134,254,213,112,230, 98, 8, 0,160,211,128, 0, 20,228,231, 98,235,214, + 77,136,136,120, 14,177, 68, 2, 43, 27, 39,131,222, 33,109,206, 83,100,233, 18,209,185, 67, 19,116, 15,108,143,223,183,237, 5, +171,215,225,211,143,135, 35, 51, 43, 11,219,182,109, 65,212,139, 72,136, 37, 18,216,218,185,252, 13,241, 44, 95,139,252, 39, 45, + 88,197, 21, 10,207,243,136,143,143,199,221,187,119,241,242,229, 75, 40,149, 74,168, 88,142, 95,127,254, 42, 79,136, 52,142,167, +244, 26,101, 75,188, 10,191,205,193,113,241,165, 60,204, 90, 90, 91, 91,203, 52, 26, 21, 88, 86, 95,170,166, 34, 0, 1,164, 98, +192,217,197, 27,177, 49,177, 84,165, 86, 7, 85,248, 5,166, 81,175, 60,114,104,255,196, 86,173, 3,236,186,119,250, 14,135, 14, +207, 69,102, 78, 14,212, 58, 9,242,213, 58, 20,168, 1, 43, 27, 95, 52,173, 87, 31, 9, 9,233,120,120, 39, 56, 79,172, 41,168, +116, 0,168,158,138,178,119, 45, 25,103,249,193,136,207, 97, 82,173, 45, 52,143,247,131,207, 77, 2,159, 91,216,109, 34, 51,181, +128,185,157, 59,242, 10,212,184, 26, 26, 5, 61, 21,101, 27,154,232,201,201,201, 5,206,206,206, 7,198,143, 31,191,228,254,253, +123,222, 0,112,251,246,237, 23, 9, 9, 9,179,146,147,147, 11,140,201,192, 82,222,219,137,137,137,201, 45, 31, 31,159,151,221, +187,119,183,232,219,183, 47,236,237,237, 17, 18, 18,130, 31,127,252,241,185, 86,171,157, 23, 20, 20, 84,161, 18,212,106,181,241, + 33,135, 15, 91,180,255,232, 35,171,233,189,123, 47,157, 56,113,226,202, 5, 11, 22, 72,124,124,124,136, 94,167,195,163, 71,143, +232,174,157, 59,245,235,102,207, 94, 33, 51, 53, 21,223, 62,114, 68,194,106, 52,241,255,116, 33,118,115,115,107,215,163, 91,187, +218,203,150,175,134, 90,149,135, 91,215, 79, 32, 51, 51, 21, 27, 55, 29,172,237,230,230,214, 46, 46, 46, 46,216, 64, 75,198,222, +223,126,251,237,203,230,141, 26, 53,170,238,238,142, 71,209, 47, 33,227, 57, 72, 89, 22,140, 78, 3, 17,171,134,187, 63, 5, 17, +153, 35, 49, 41, 7, 11,247, 28, 8,229, 56,110,111,101,188,117,123,124,128,101, 9,217, 32,132, 96, 97, 11,127,200,205,204, 32, + 51, 51,195,148, 99, 23, 75, 68,213,145, 5,179, 33, 55, 53, 67,205, 22, 1,134, 84, 66, 5,230,230,230,119, 31, 61,122,212,212, +223,223, 31, 95,126,249, 37, 94,189,122, 5,158,231,145,156,156,172, 78, 76, 76,140, 79, 77, 77,125, 5,224, 16,128,205,148, 26, +230,191,137,101, 89,135,144,144, 16, 20, 53, 78,184,112,225, 2, 92, 92, 92, 96,105,105,137,156,156, 28, 76,159, 62, 93, 62,111, +222, 60, 0,192,221,187,119, 37, 38, 38, 38,229,114, 61, 10,121,178, 44, 43,151,102,210,188,123,253, 50,216,123,245, 58, 6,198, +162, 75,175,209, 56,119,252,119, 92, 60,115, 30, 54,226, 87, 47, 97,154,123, 42,237,101, 90, 78, 92,190,207,134,218,141, 63,101, + 18,243,207,108,152,212,199,154,113,118,230,247,207, 90, 87,190,227,222,226, 47,112,134, 97, 74,198, 96, 21, 15,104, 55, 86, 92, +149,198,252,249,148, 39, 32,196, 78, 38,125, 24, 27, 27,219,197,205,205, 13,201,201,201,136,141,141, 69, 76, 76, 12, 98, 99, 99, + 81,179,102, 77, 68, 69, 69, 65, 42,149,222, 55,144,118,248,224,193,131,205,181, 90, 45,118,239,222,205, 2,232,181,127,255,254, +187, 77,155, 54, 21,119,235,214,205,124,237,218,181,195, 1,108, 54, 34,152,166, 22, 22, 22, 82,157, 78,135,181,107,215, 34, 54, + 54,182, 29,165,244, 9, 33,100,195,224,193,131,215,249,251,251,215, 12, 13, 13,125,158,151,151, 55,158, 82,250,208,128,186,232, +227, 38, 77,154,236,231,121,222,179,115,231,206,166,203,151, 47,183,120,246,236, 25,220,220,220,192,243,252, 35, 35,199, 48,101, +156, 63,127, 62,179, 85,171, 86,214, 69, 3,218, 23, 18, 66,190,103, 24,102, 73,255,254,253, 45,119,237,218,133,147, 39, 79, 66, +171,213,226,233,211,167,169,161,161,161,191, 0, 88,102,136, 8,162,148,102, 2,152, 67, 8, 89, 58,121,242,228,169,132,144,185, +169,169,169, 37,254,159,138,197, 21,128,145,148,210, 17,255, 49, 67,136, 94,167,211,194,194,198, 27,121, 89, 49, 72,141,189, 14, +165,185, 19, 2, 59, 54, 64,129, 74,139, 99, 71,254,192,195, 71, 15, 32, 18,137,224,232,228, 14, 43,107, 59,132,135, 63, 7,128, +176,138, 57,117, 48,183,174,134,188,236, 88,104, 83, 66, 96, 98,230,128,209, 31,245, 67,129, 74,135,131,135,254, 64,104,232, 67, + 48, 12, 3, 39,103,119, 88, 90, 21,114, 18, 90, 33,167, 0, 99, 5, 22,195, 48,151, 78,159, 62, 61,176,121,243,230,226,136,136, + 8, 68, 68, 68, 20,119,117,177, 4,220,129,228,135,135,135, 85,208,248,119, 46,246,149, 81,122,109, 65, 51,115,243,248,103, 79, +159, 56,102,102, 36,227,193,189,171,136, 8,127,132,151, 81, 79,160,211,169,193,136, 68, 16, 49, 34, 84,243,174,139,171,215,174, +107,181, 28,119,163, 60, 78, 0,200,200,136,204, 53,115,244, 29,242,195,130, 57,199,167, 78,255,214,100,208,192,245,120,248, 44, + 12,121,172, 19, 40, 5,156,108, 77,209,176,250, 12,196, 39,164, 98,207,239,107, 11,120,157,110, 68,105, 31, 88,101,113, 2, 64, +170, 88,229,176, 97,251, 31, 75,247,236, 63,248,217,152,209,195, 21,237, 59,127, 4,105,218, 35,176, 9, 33,112,173, 19, 0, 42, + 54,193,237,144,123,120, 24, 17,171, 46,208, 49,155,115,164,170,233,149,113,150, 70,118,118,246,157,228,228, 36,239, 82, 94,219, +189,229,114,197,157, 74,196, 84,231, 55,252, 2,189,230, 33,158, 97, 68,205, 23, 44, 88,144,239,236,236,172, 13, 13, 13,197,134, + 13, 27,248,187,119,239, 94,146,201,100, 27, 19, 18, 18, 52,149,113,218,235,245, 15,118,205,154, 85,167, 89,255,254,116,216, 23, + 95, 20, 64, 46,159,180,244,231,159,103,165,102,102,186, 80,158,135,189,141, 77,220,210,217,179, 23, 15, 28, 60, 56,243,241,213, +171, 38,215, 15, 31, 54,145,177,108, 72,101,225,124, 31,168,136, 51, 46, 46, 46,216,167,134, 7,182,110, 94, 14,157, 78,131,196, +248, 66,195, 85, 90,122, 54, 42, 18, 87,111,114, 22,117,254,247,255,102,222,188,155,223, 76,157,226,212,182, 83,103,196, 60,184, + 15, 93, 70, 42,136,158,133,132,136,145,159,162, 68, 74,114, 30,102,238,216,151,146, 87, 80,208,255, 77, 71,142,229,133,179,164, + 91,208,220,188, 72, 96,153,191,102,181, 82,152, 23, 14,114, 23,203,100,101, 13,134,127,139, 51, 47, 47,111,192,192,129, 3, 31, +222,190,125,219,250,211, 79, 63, 69,171, 86,173,238,169, 84,170, 14,148,210,220,170,166,167, 88, 44, 78,105,220,184,177,131, 68, + 34, 97, 63,249,228, 19,113, 90, 90, 90,137, 39,244,188,188, 60,156, 58,117, 10,197, 83,238, 31, 63,126,140,186,117,235,150,203, +249,233,140, 71,241, 0, 22, 76, 27,228,182,244,230,131,196, 73, 0,150,120,215,116,199,197, 51,231,113,229,226,245, 89, 45,252, +249,213, 61, 70, 52,253, 94,217, 97,240,244,218,141, 63,101,204, 44,156,177,237,224, 31,204,147,144, 45, 11, 11, 10, 30,213, 0, +240, 85,121,225, 36,132,128, 82,250,150, 75, 6,149, 74,101,144,184,170,168, 44, 81, 80, 42,205, 34,115, 6, 13, 26,212,252,214, +173, 91,230,102,102,102,208,233,116,160,148,162, 70,141, 26, 16,139,197,248,229,151, 95,242,211,210,210,230, 26,194,105,106,106, + 58, 49, 48, 48, 16, 79,159, 62,197,157, 59,119,254,160,148, 62, 36,132,252, 17, 17, 17, 49,164, 77,155, 54,248,253,247,223, 39, +150, 39,176,202,227,228,121,190,180,207,163,140,162,178,251, 0, 64, 11, 99,227, 94,228, 44,180, 53, 0,216,218,218,198, 58, 58, + 58, 90, 60,120,240, 0, 30, 30, 30,208,233,116,205,141, 41, 75,148, 82, 61, 33,100, 77, 80, 80,208,188,214,173, 91, 99,226,196, +137,237,130,130,130,218,181,110,221, 26,181,107,215,198,197,139, 23,177,115,231,206, 3, 28,199,141, 7,144, 69, 41,229,140,205, + 35, 74,105, 22,128,121,132,144, 25, 50,153, 12,230,230,230,226,248,248,120,102,247,238,221, 0, 48,166, 42,156,127, 85,189,244, +190, 56, 41, 33, 95,127,250,217,164, 13,159,125, 58, 92,209,164,113, 67, 20,228,196, 65,149,151,140,130,220, 36,252,178,249, 44, + 8, 17,193,222,222, 25, 14, 78,110,136,142,142,193,181, 19, 39,181,249, 5,170,149, 50, 61,191,164, 98,206, 47, 10, 57, 27, 21, +114, 22,228,167, 64,149,151, 82,194,233,224,224, 82,196, 25,141,171,215, 79,170, 85,249,249,203,181,148,252,244, 87,198,253,255, +157,192,202,204,204,156, 60,118,236,216, 14, 51,103,206,180,101, 89,150,177,177,177, 65,116,116, 52,123,224,192,129,140,188,188, +188,201, 85,122,168, 68,242,208,199,215,175, 67,159, 62,125,216, 15, 62,232, 45,253,240,227,110, 98,123, 7, 7,100,103,165, 35, +252,233,125, 60, 11, 11,129,143, 95, 3,204, 95,176, 2,176,178,170,116,166, 78, 94,114,248, 37, 51, 71,223, 94,223,125,243,213, +222,214,237,186, 90,248,213,109, 32,109, 88,195, 18, 58, 61,139,184,184, 56, 28, 57,252, 64, 23,122,247, 74, 14,207,106,135,228, +167, 26,182, 84, 78, 88, 24,213, 1,152, 92,167,142,197,119, 63,109,216,185,126,251,238, 3,253,198,140,232, 47,110,212,160, 19, + 94, 92, 63,132,203, 55, 47,178,153,106,122, 40, 87,194,124, 30, 22,145,147,105,108, 26,168,213,106,253,155, 67, 71,212,106,245, + 59, 47,122,186,117,235, 86, 36, 37, 37,233, 98, 99, 99,207,179, 44,123,200,152,217,136,171, 41,213,246, 39,228,252, 55, 1, 1, +221,190, 57,115, 70, 49,106,198, 12,237,136, 15, 63,252, 10, 26,141, 14, 50, 25, 21,155,154,138, 32,151, 75, 30, 95,189,106,178, +234,243,207,109,136, 86,123,238,119,227, 76,240,239,125, 22, 97, 41, 11, 22, 70,125, 58, 21,170, 82, 22,172, 27,119,194, 97,140, + 5,171,168, 2,143, 33,132,180,152,244,245, 55, 7,135, 4,118,170,237,239, 89, 77,110,239, 85, 13,102, 78, 78, 72, 79, 77,197, +213, 59,207,244, 11,246, 30, 12, 45, 18, 87, 6,249,133,225,121,190,100,150, 91,224,212,153, 32, 12, 83,226,142,161,120, 38,144, +119,179, 86, 96,196, 98,112,148,135, 70,163,161, 6,132, 51,142, 16, 50, 96,196,136, 17, 23,142, 31, 63, 46, 10, 12, 12,108,120, +232,208, 33,254, 93,202,142, 94,175,119, 43, 18, 90, 57, 74,165, 82, 60,122,244,104,232,245,122, 20, 20, 20, 32, 59, 59, 27, 79, +158, 60,209, 12, 26, 52, 72, 94, 36, 28,244, 67,134, 12,169,180,254, 88,190, 63, 78, 61,109,144,219,106, 27,241,171,161, 57,105, + 15,189,108,196,175, 94,182,240,231, 87, 47,223, 31,167,254,110,170,213, 15,105,175,130,195, 19,243,207,108,216,118,240, 15,102, +100,191, 1,156,155,217,243, 89, 10, 7,122,160, 99,239, 74, 27,161,183,156,138,190,131, 7,252,215,160,211,209,123,182,182,214, +139,155, 53,107, 54,103,249,242,229,102,246,246,246, 96, 89, 22, 47, 94,188,192,154, 53,107,242, 51, 51, 51, 23, 82, 74,239, 26, +194,229,235,235,235, 37, 22,139,177,103,207, 30, 0, 88, 83,116,120,205,161, 67,135,134,124,250,233,167,168, 86,173, 90, 29, 66, +136,220,152,174, 44, 74,105, 73,175,194,123,110,216,163, 86,173, 90,229,234,228,228, 68, 78,157, 58,197, 50, 12,115,172, 10, 52, +139,119,238,220,217,146,231,249, 78,109,218,180, 65,205,154, 53,139, 45,158, 56,124,248,240, 94,142,227, 70, 84, 36,130,140, 69, +110,110,110,241, 64, 59, 29, 10, 23,252,254,207,225,233,243,244,237,245,170, 59,158, 89,240,195,242,121, 53,170,123,141,251,100, +244, 96,198,215,167, 46,242,179,227, 96,107,231, 8, 55,119,111,164,166,164,225,244,233, 83, 92, 90, 90,214,111,156,136,124,247, +252,121,122,194,187,112,186,186,121, 35, 37, 37, 5, 39, 79,158,228,178, 50,115, 54, 65, 47, 90, 16,246, 42, 51, 25, 2,140,123, +167, 12, 25, 80, 91, 52,147,112, 85,161,155,134, 66,171, 86,102,102,230,100, 74,105,154,161, 74,156,188,233,252,108,208, 32, 41, + 78,156,168, 15,189,190,133,149,185,121, 39,202,243, 77, 27, 52,104, 96, 54,120,240, 96, 62, 32,160,149,204,194,194,130,212,169, +227,159,155,157,149,101, 93,248,101, 9,174, 50,213, 92,188,216,179,152,145,116,230, 56, 93,189,194,176, 86,190,216,179, 33, 74, +188,145,155, 69,117, 19, 57,191,217, 68,204, 7,168, 88,209, 85,149, 70,244,217,189,184,156,168,119,249,178, 41,189, 56,115,209, +210, 48,179,141,253, 90, 42,221, 69, 40, 18, 49,219, 92, 93, 93,231,196,196,196,164, 26, 90,137,149,197, 89,188, 84, 78,175, 41, + 83,244,141,187,118,101,109,220,221,121, 74, 41,247, 50, 36,132,220, 56,114, 68,114,227,200, 17,133, 94,163,185,180,159,210, 40, + 67, 56, 93, 92, 92, 22, 31, 59,118,204,224,177, 85,189,123,247, 14, 43, 30,151,101,104,122,214,168,238,118,166,186,151,107,215, +234, 94,133,221,208, 81, 47, 19, 16,245, 50,254,108,100, 84, 92, 96, 85,242,168,244, 98,207,164,200, 21, 3, 53, 96,177,231, 55, + 57,237,236,236,238,138,197, 98, 55, 99, 94, 74,142,227, 18, 82, 83, 83, 27, 25, 24,206, 97, 94, 94, 94, 75,162,163,163, 15,114, + 28, 55,245,125,124,121, 19, 66, 90, 49, 12,115,146,227, 56,147, 55, 45, 92,197, 34,140, 16,226, 41,151,203, 95, 27,228, 94, 17, +231,210,111,252,231,181,108,211,166,223,141, 43, 87, 14, 77,255, 33,244,181,113, 65,147,250,217,124, 60,108,194,228,159,118,175, + 93, 53, 99,245,161,140,223, 42, 11,167,163,163, 99, 16, 0,159, 98,161,101, 64, 90, 54,169,138,213,129, 72, 73, 83, 59, 75,187, +239,117, 58, 93, 3, 0, 84, 42,149, 62, 72, 75, 75,155, 91,150,184, 42,143,147, 97,152, 37,181,106,213,154,252,236,217,179,221, + 44,203,126, 82,234,250,101, 53,106,212,152,240,234,213,171, 53,122,189,126,186, 17,239,187, 69,155, 54,109, 50, 87,173, 90, 37, +154, 58,117, 42,130,131,131,109,138,186,207,222, 71,190, 59, 89, 91, 91,255,202,113, 92,109, 74,233,177,220,220,220,217,148,210, +124, 99, 57, 9, 33, 82, 0,211,170, 87,175, 62,217,205,205,205, 49, 46, 46, 46, 54, 42, 42,234, 39, 0,235, 13,237,174, 54,176, +254,212, 0, 40,158, 93, 85,233,120,171,127,171, 5,171, 52,234, 84,183,175, 78, 25,110, 97, 3,255,218, 3, 63, 26,209,143,220, +184,243, 28, 55,111, 92, 71, 92, 66,194, 33, 94, 36,154, 19, 30,158,246,252, 93, 57,175,223, 9,199,205,235,215,105, 98, 66,226, +126, 80,230,155,176,168,212,168,191, 43,238,255, 47, 5,214,251, 40, 40,196, 16,239,178, 46, 46, 46, 72, 79,111,174, 16,139, 3, +228,114,121, 7,145, 72,116, 57, 35, 45,237, 11, 67, 5,214,223,241,146,180,175, 99,111, 26, 20,150,154,255,190, 56,223, 28,160, + 94, 21, 78, 99, 56, 12,229, 44,111,177,103, 94,163, 73,176,101,217,187,171, 41,213, 26,202,233,230,230,246, 25,207,243, 94,134, +134, 73, 36, 18,189,140,139,139,219, 92,149,244,244,241,241,161, 17, 17, 17, 6, 13,146,252, 47, 84,184,255, 22,206,237, 43,234, +187,248,213,171, 53,253, 81,200,147,101, 69,221,135, 37,248,110,146,141,121, 64,199,246,115,175, 94, 12,250,126,254,234,140,220, +255, 90,220, 9, 33,162,178,132, 69,241, 92,116, 99, 57,165, 82,233,134,102,205,154,125,118,243,230,205, 95, 89,150, 29,243,191, + 26,247, 34,175,234,178,170, 12, 52, 23,222,163,138, 57,235,248,216, 54,161,180,196, 89,246,194, 39, 17,233,183,223, 27, 39,229, + 57,158, 50, 63, 60,139, 74,187,247,119,199,253,191, 6,241,223,245,160, 98,129, 84, 33, 18, 18, 98, 1,196, 2,216,255,191,154, + 96,134,136, 43,163,210,165, 10,162,232,175,224,120, 19, 69, 2,234,250,251,224,122, 83, 44,253,149,120,254,252, 57, 17, 94,235, +255, 61,124, 52,245, 97, 2,128, 41, 77,202,112, 77, 85, 36,170,166,119,248,224,191, 25,247,242,172, 54, 85, 93,136, 89,167,211, +141, 35,132, 76, 51,102,246,225, 63, 20,111, 10, 64, 35,148,254,247,143,176,231,233,119, 1,244,254, 95,231,252,255, 14,145,144, + 4, 2, 4, 8, 16,240,175, 19,109, 42, 33, 21, 4, 8,248,223, 6, 1,208,185,156, 23,216, 96,211, 31, 33,164,115, 21, 42,136, +243, 2,167,192, 41,112, 10,156, 2,167,192, 41,112,254,255,226,252,255,244, 37,244,151,109, 0, 58, 11,156, 2,167,192, 41,112, + 10,156, 2,167,192, 41,112,254,127,219,132, 46, 66, 1,127, 57,126,233, 79, 92,127,233, 79, 92,255,170,235, 5, 8, 16, 32, 64, +128,128,255, 53,136,255,107, 17, 34,132,216, 1, 24, 76, 8, 25, 84,100,161,219, 15, 96, 95,101, 46, 37,138, 97, 98, 98,146,172, + 86,171, 29, 0, 64,161, 80,164,168,213,234,210,107, 14, 16,188,189, 68, 6, 45,124, 76,249, 3, 86,189,189,189,147, 53, 26,141, +131, 1,214,196, 96, 66,200,101,145, 72, 20,108,140,239,166, 98,116,236,216,113, 20,195, 48, 11, 1,128,227,184,175, 47, 94,188, +184,245, 47, 76,231,230,238, 46, 78,191,235,244, 58, 54, 57, 53, 99, 46,165,244, 72, 89,215,173,235, 77, 22,139, 9,166, 23,253, + 95, 58,254, 88,197,174, 40,140,189,190,130,240, 53,145, 72, 36, 19, 29, 29, 29,187,199,197,197,221, 5, 48,131, 82, 90,169, 23, + 98, 15, 15,143,143,196, 98,241, 8,142,227,170, 51, 12, 19,197,178,236,206,152,152,152,237, 66, 85, 33, 64,128, 0, 1, 2,254, + 50,129,213,210,199,214,151, 80,221,116, 9,161,109,244,148, 92,161, 68,186,244,198,243,244,240,119,108,168,221, 1,180, 71,161, +175,161, 71, 0,206, 82, 74,211,141,228, 48, 5,208, 7,192,240,192,192,192,206,223,127,255, 61, 83,175, 94, 61,104, 52, 26, 4, + 5, 5, 5, 44, 93,186,116, 37, 33,228, 60,128, 93, 0,142, 84,228,219, 69,173, 86, 59, 20,107, 37, 66,136,195,192,129, 3,111, +151, 22, 85, 69,139,203, 18, 74,233, 13, 66,200,117,142,227,110,238,223,191, 63,182, 22, 33,205,199,122, 73, 15, 76,126,161,125, +203,231,145, 70,163,113, 56, 62,109, 2, 40,229,161, 78, 79, 67,235, 37,171, 74,206,157,234,214, 2, 34, 78, 15,153, 92, 26,220, +254,216,141,203, 0,130,139, 54,163,193, 48,204,194,211,167, 79, 59, 83, 74, 17, 24, 24,184, 16,192, 95, 34,176, 8, 33,242, 22, + 77, 26, 92, 58,246,199,110, 69, 94, 70, 50,186,245, 25,178,147, 16, 50,138, 82,250,199,107, 98,169, 7,113, 36, 98, 76,255,124, +209, 46, 6, 0,214,205, 25, 62, 99,101, 32, 89, 61,229, 12, 77, 34,132,116, 0, 74,150, 86,250,137, 82,122,105, 93, 15,226, 8, + 6, 51, 63, 95,180,139, 0,192,250, 57,195,167,175,235, 65, 86,141, 63,105,220, 44, 73, 66,200,248, 81,163, 70,173, 94,184,112, + 33,227,236,236,140,248,248,248,110,117,234,212,241, 37,132,212,169,104,112,176,151,151,215,222,246, 93,250,122,247, 31, 52, 84, +105,111,103,141,132,196, 52,139,189,187,127, 29,235,229,229,213,253,229,203,151, 67,132,234, 66,128, 0, 1, 2, 4,188, 55,129, +229,239,111,105,101,162,162,211, 76,164,116,104,183,230,117,188,122,119,105, 69,188,189,189, 17,254, 44,188,250,165,107,119, 70, +119,168,101,254, 82,165, 35,123, 84, 38,100,121,104,104,197,235,135,141,106, 68,244,122,174,240,153, 82, 49,184, 29, 15,153, 67, + 61,123,246,244,250,226,139, 47,208,178,101, 75,220,190,125,187,195,111,191,253, 54, 89, 44, 22,223,225, 56,238, 36,128, 32, 3, +156,199, 77,172, 81,163,198,210, 21, 43, 86,200, 59,116,232, 0,133, 66, 81,114, 78, 34,145,160,119,239,222,232,221,187, 55,147, +144,144, 16,120,236,216,177,192,159,126,250, 73, 75, 8,249,138, 82,186,198,144, 4,154, 59,119,110,147, 50, 14,159, 38,132, 68, +178, 44,123,191,126,253,250,177,126,132,212, 28,215,163,213,185,241,173,125, 76, 43,176, 78,225,206,194, 66,183, 37,165, 5, 22, + 45,200,133,196,194, 60, 88, 98,102,246,150,184,170, 77, 72,131, 22,214,162,223,183,100,112,245,141, 16, 89,136,141,141,133,165, +165,165, 73,251,246,237, 19, 9, 33,223, 94,186,116,105,211,123, 46, 55,205,191,157, 62, 94,154,249,234, 33,146,158,222,192,180, + 65, 1,202, 41,191, 28,253, 30,192, 31, 21,231,149, 72,244,211,117,126,214, 20, 96, 50,128,185,233,233,233,237, 0,192,214,214, + 86, 6,224,210,138, 91,232, 49,181, 53,169,178,155, 5, 66,136,148, 97,152,181,219,182,109,251,244,163,143, 62, 42, 92,226,225, +234, 85,152,153,153, 97,193,130, 5,213,190,252,242,203,197, 40,124,118,153,150,171,246, 93,250,122,175, 90,246,125,157,220,140, +108,205,198,181,251,238,184,248,251,137, 62,159,248,165,249, 42,157,198,201,195,195,227, 35,193,146, 37, 64,128, 0, 1, 2,222, +139,192,106, 83,211,244,118,191,198, 53, 26,247,238,220, 74,228,227, 87, 7, 82,133,178,228, 92,189,134,141, 80,175, 97, 35, 50, +102,116,174,247,131, 7, 15,190, 57, 29,124,107, 78,155,154,166, 33, 87, 34,242,155,149,199,167,231, 32,222,181,107, 23, 0,224, +231,175,134, 51, 57, 57, 57, 94, 74,229,159,156, 29, 59,118, 68,199,142, 29, 69,235,214,173,107,126,230,204,153,230, 91,182,108, +209, 17, 66, 86, 22,117,243,149,135, 57, 97, 97, 97,114,134, 97,192, 48,229,251, 50,117,113,113,193,192,129, 3,225,231,231, 39, +107,223,190,253, 28,252,185,108,197,107, 80, 40, 20, 41,132, 16, 7, 0,176,177,177,225,190,253,246,219,251,148,150,244, 0, 82, + 74,233, 13,145, 72,116,147,231,249, 91, 71,142, 28,137,171, 75,136, 67,175,198,126, 87,198,127, 56, 80, 73, 15,172, 44, 87, 28, +104,178, 50,202, 60, 46, 51, 85, 6,203, 76, 77, 47,203, 77, 76, 94, 19, 87,117, 9,113,107,225,231,117,118,221,212,225,230,134, +100,100,227,198,141,125, 59,116,232,160,224, 56, 14,249,249,249, 88,191,126,189,165,137,137,137,101,247,238,221,231, 3, 40, 17, + 88,117, 8,169, 55,192,133, 25,243,109, 60, 59,161, 10, 2,198,170, 77,203, 38,175,126, 89, 50,223,162, 73,139, 54,120,126,105, + 7, 50, 50,114,145,157,149, 7,158,231,223, 90,249,119,252, 73,154,188,174, 55, 89,186,110,246,240,153, 68, 36, 34, 13,250,205, +192, 7, 78,217,147, 8, 33,143, 1, 72,138, 23,106, 5, 32, 38,132,184,248,251,251, 47,173,217,181, 13,214,127,253, 33, 40,207, + 83, 0, 75, 13,181, 94, 17, 66, 28,204,205,205,143,156, 61,123,182,121,211,166, 77,113,243,230, 77,188,120,241, 2,227,199,143, +215, 78,152, 48, 65, 58,114,228, 72, 50,109,218,180, 47, 8, 33, 7, 40,165,215,222,122, 17,196,226, 17,125,250, 15,145,229,101, +229,168,181, 26,157,214,198,206,138,215,228,171, 11,210, 50,115,212, 67,134,127,166,125,124,239,214, 8, 0,111, 9,172,119, 73, + 79, 1, 2, 4, 8, 16, 96, 48,154, 2,176, 7,144, 10,224,206, 27,251, 40,250,143, 50,246,211, 80,216, 11,101, 91,138, 43, 13, +133,195,123,236, 81,232,163,243, 54,128,204,247, 30,226, 82,194,161,228,183,120,235,226, 43,167,148, 82,202,166, 71, 80,125,212, +121,170,123,184,253,237, 45,252, 24, 77, 14,249,131,222,222, 49,155, 22, 93, 95,238,136,250, 97,245, 64,105,216, 46, 74,195,118, +209,101,129,160,148,210, 16, 74,105,200,134, 97,206,218,101,129,160,203, 2, 65, 55, 12,115,214,242, 60, 31, 18, 31, 31, 31,114, +237,218,181, 16, 0,183, 42,153,201,144,156,123,231, 58,189,229, 0,154,145,145, 65, 53, 26, 13,125, 19,207,158, 61,163, 27, 54, +108,160,179,103,207,166,191,254,250, 43, 5,144, 92, 17,103, 96, 96, 96, 80,104,104, 40, 29, 57,114,228,125, 0, 38,229, 93, 87, + 27, 48, 29, 81,205,233,169,102,239, 74,157,246,163,122, 52,179,173,162,204,248, 59, 59, 59,191, 22,158,189,181,157,232,209,150, + 62,244, 92,215,198, 65,148,210,111, 41,165,237, 74, 95,223, 8,176,232,227,108, 27,161,222,183, 74,165, 29,211,130, 86, 54, 83, +161, 81,163, 70,190, 95,125,245, 85,134, 86,171,165, 47, 95,190,164, 27, 55,110,164,231,206,157,163,135, 15, 31,166, 1, 1, 1, + 9,165,194,235,248,177,159,103,178,118,203,119,154,170,204,136,144, 48,204,154, 59,231, 14,208,136, 43,251,233,237, 61,139,233, +206,111,134,209, 47,250, 52,215, 89,152,200,213, 0, 58,150,119,223,132,214,168,233, 87,205, 62, 60, 58, 58,154,234,116, 58, 58, +122,244,104, 26, 24, 24, 72,187,118,237, 74, 59,119,238, 76, 59,117,234, 68, 59,118,236, 72, 47, 94,188, 72, 19, 18, 18,104,231, + 54,141,243,123,213, 70, 19, 35,102,179,248,123,122,122, 38,189,124,249,146,234,116, 58,122,225,194, 5,186, 99,199, 14,122,225, +194, 5, 58,107,214, 44, 10, 96,235,231,159,127,174,202,204,204,164,129,129,129,113, 40, 90,193,160,244,230,233,233,249, 36, 52, + 60, 54,118,197,162,205, 23,183,173,217,125,241,224,129,115, 23,143,156,185,125,226,240,153, 59,251,110, 61,136, 58,236,233,233, +249,164,140,252,127,167,244, 20, 54, 97, 19, 54, 97, 19,182,215,234,242, 50,181, 72,209,214,179,232,120, 79, 74,105,231, 55,246, +123,226,207,241,208,175,237,207,154, 53,107,118,233,253,226,107,102,205,154, 53, 27, 0,109,217,178,229,110, 74,105,205,191, 34, + 62, 6,141,193,210,189, 8,130,172, 78,127,128,175, 11,154, 25, 9, 62, 39, 30, 84,233,128,124,222, 4,105, 9,209,120,122,101, + 63,168,174,114,191,119, 18, 6,236, 55, 19,134,139,173, 20,128,204,220, 94,151,155,155, 11, 83, 83, 83,228,103, 38, 74,191, 92, + 86, 98,217,146, 94,186,116, 9, 33, 33, 33,112,113,113, 49,168, 27,147,106, 11,123, 17,181, 90, 45,180, 90, 45,146,122, 52,131, +105,139,182,200,252,112, 2, 46, 92,184,128,148,148, 20, 72,165, 82,200,100, 50,176, 44, 91,105, 56, 69, 69,171,198, 22,103,116, + 89,215,180, 39, 68,236,102, 99,118,108,221,252,201, 94,162, 27,199, 37,170,152, 8, 36,168, 57, 88, 25,144,158,114, 51, 83,200, +148, 38,193, 50, 51,211,183,186, 5, 27, 19, 34, 49, 53, 83, 28,251,253,135,105, 78,204,189, 11, 10, 85,196, 67, 72,203,224,232, +210,165,203, 88, 0,243, 41,165, 89,237,219,183,119, 92,184,112,161,117,124,124, 60,194,194,194,176,111,223,190, 84,182, 48,162, +132, 82,250, 29, 0,180, 36, 68,225, 97,111,117,102,205,188,201,230,184,180, 87,134, 79,230, 25, 45,198, 45,107,247, 62, 49, 96, +228,231, 19, 86, 79,238,141,252, 92, 21,118,157,187,135,211, 33,145, 31, 0,184, 90,209,184,182, 53, 87,105, 4, 33,164, 83,255, +254,253,239, 95,190,124,217,110,203,150, 45, 96, 89,182,204,109,203,150, 45, 56,127, 37,100,146,161,139,233, 18, 66, 92,188,188, +188,206,223,186,117,203, 94,169, 84,226,220,185,115,200,202,202, 42,177, 92,141, 26, 53,138,100,101,101, 13, 93,191,126,253,128, + 87,175, 94, 45,187,114,229, 74, 58, 10,151,109, 98,223,232, 90,141,100, 89, 93, 45,231,218, 53,197,131,122,183,105,147,151,254, + 16,102,182,245,113,227, 65,228,177,172,204,116, 21,195, 48,145,165,175,127, 31,233, 41, 64,128, 0, 1, 2,140,238, 73, 57, 78, + 41,237, 69, 8, 57,254,230,177, 55,255, 23, 95,183,120,241,226,146,253,226,123,150, 44, 89,178,168,212,126,193, 95,217, 69,216, +158, 16, 66, 81, 56,216,252, 45,168, 31,236,132,230,209, 94, 72,171,119,128,172,238, 16, 72,220, 90, 34,246, 81, 16,238,159,252, + 25,113,143,175,130,242, 28, 28,171,213,174,244, 97, 91,239, 81, 9, 33, 36,132, 82,138,123,247,238, 33, 50, 50,242,181, 49, 83, +197,184,112,225, 2, 0,192,201,201,201,160, 72,200,154,180,130,251,131, 68,196, 54,112, 6, 0,184, 63, 72, 4, 0, 44,158, 51, + 7, 82,169, 20, 82,169,180,100, 81, 88, 67, 4, 86,209, 26, 90,224, 11,187,169,104, 89,231,155,200, 37,187,246,204,159,216, 76, +254,234,145, 76, 19,122, 3, 9, 26,158, 30, 75,230, 78, 24,178,162,177, 92,169, 12,150,153,153, 93,150,154,154,190, 38,174, 0, +128, 74, 36,219,119,124, 55,177,190,105,114,148,169,250,206, 5, 36,170,121,157, 69,217, 52,223,157, 58,117,202, 65, 44, 22, 59, +113, 28,135,152,152, 24, 60,126,252, 24,171, 86,173, 74,206,205,205,109, 31, 18, 18, 18, 94, 42,188,162,166, 38,178,125,219, 23, + 76,246, 22, 63, 12, 86,104, 34, 67,203, 20,109, 21,193,190, 94,191,192, 15,218, 55, 56, 49,246,195,175,209,183, 71, 87,140,108, + 95,135,190, 76,200, 80, 3, 56,103,200,194,210,148,210,120, 66, 72,151,182,109,219,238,108,216,176, 97,109, 74, 41,234,213,171, +135,161, 67,135, 98,251,246,237,120,240,224, 1,114,114,114,116,103,207,158, 93, 73, 41,253,205,192, 23, 77,105,109,109,125,250, +226,197,139,246, 74,165, 18,103,207,158,133, 74,165,130,179,179, 51, 38, 76,152, 32, 91,178,100,201,182,156,156,156, 65,139, 23, + 47, 86,188,124,249,114,205,153, 51,103,170, 1, 16, 81, 74,223, 42, 4, 90,173,118,211,174,237, 91, 87, 79,152,248,133,235,197, +155, 97, 23, 52,121,185,150,158,158,177, 57,246,214,102,230, 43,127,252,206, 67,171,213,142, 45, 59, 61,131,170,148,158, 2, 4, + 8, 16, 32,160, 44,219, 69,249, 90,164,180,104,122, 83,100, 25, 35,206, 0,168,102,205,154, 53,135, 16,114,124,214,172, 89,115, + 22, 47, 94,172, 2,144,240,151, 8,172, 34,247, 0,160,148, 6,151,211,133, 8,202,179,208, 70,156,131, 54,226, 28, 76, 59,124, +131, 35,139, 70,188,118, 29,199,233,171, 20, 0,181, 90, 13,169,153,173,238,231,175,134, 75, 1,128,151,152,234,138,207,241,188, + 65, 11,175,195,152, 37,189,140, 17, 88, 69,188,111,137, 7, 47,185, 89,240,166,169,131, 90,216,114, 5, 18,237,213, 99,136,215, +240,236,178, 8, 93,193,157, 44,250,211,156,114, 56,143,119,105, 6,125,102, 26, 20,230,166,193,221, 46,133,150, 57, 91,208, 75, + 97,113, 97,223,180, 97, 1, 78, 82, 72,181, 39,246, 35, 65,195,107, 54,188,210,255,182,170,156, 56, 83, 74,241,226,197, 11, 20, + 20, 20,224,250,245,235,248,227,143, 63, 82,223, 20, 87, 69,225, 13,250,117,198,136,230, 22,185, 73, 82,237,157,243, 72,208,240, + 26, 95, 67, 68, 85,253,126,173,165, 34,114,150,136, 24,147, 30,109,234, 96,202,103,253,176,226,215,163,172,214,161, 77,175,213, + 71, 78, 14,206,211,232,230, 24, 34,174, 74,133,249, 33,128, 58,132, 16, 57,128, 14, 67,135, 14, 61, 57, 96,192, 0, 4, 7, 7, +227,216,177, 99, 62, 0, 18,139,210,127, 1, 0, 71, 20,206, 46, 44,111, 37,119,145, 84, 42,221,115,254,252,249,186, 46, 46, 46, + 56,127,254, 60, 84, 42, 21, 62,255,252,115,237,196,137, 19,165,163, 70,141, 34,217,217,217, 37,150,171,235,215,175,167,151, 39, +174, 0, 32, 46, 46,238,148,167,167,103,171,182,109,219,246,243,246,241,179,136,202,205, 73, 81, 42, 21, 38, 87,130, 47, 73,239, +220,186,182, 38, 46, 46,238,118,217,233,121,193,224,244, 20, 32, 64,128, 0, 1, 21,182, 17,229,106,145, 55, 69, 86, 21,249,139, +239,147, 44, 94,188,248,241,226,197,139, 95,179,112,253, 85, 22, 44,163,192,101,188,221,230,113, 6, 8,151,242,208,114,230,153, +199, 38, 38, 38, 88,191,126, 61, 74, 15,122, 55, 84, 56, 21,156, 58,132,216,241,195, 75, 44, 87,197,150, 44,116, 27,245, 78, 2, +139,231,249,235, 0, 94, 83,121,166,142,126,195,246,124,216,165,117, 29,111, 87,145,126,223, 42,196, 21,176,234,249,207,116,234, +167,185,244,131,176, 50, 6, 79,151, 64,175,133,194,180,208,114, 85,150,184, 50,115,242, 29,176,109, 88,135,246, 13,252,106,136, +216,189,203, 17, 95,160,207,155,245, 68,167,139,202,167, 7,203, 41, 40,243,187,118,237, 58,223,214,214, 86,177,122,245,106, 75, + 79, 79, 79,176, 44,171,125, 83, 92,153, 58,250, 13,219, 59,170, 91,107, 95, 39,107,145,254,192, 47,136, 85,113, 5,171,162,244, +219, 54, 24, 32,174,236, 44,205,206,108, 88, 52,222, 68, 41,151, 64,173, 86, 99,201,186, 3, 56,123, 45,180, 87,234,163, 67,103, + 0,156,121,135,114,247,105,175, 94,189, 86, 44, 88,176, 0,122,189, 30,159,124,242, 9, 34, 35, 35,207, 62,123,246,108,149,135, +135,199, 87, 51,102,204,112,113,114,114,194,224,193,131,165, 0, 70,149,195,241,227,174, 93,187,122, 53,104,208, 0,193,193,193, +200,202,202,130,179,179, 51, 38, 78,156, 40, 91,188,120,241,182,156,156,156, 65,139, 22, 45, 82,188,120,241,162, 66,203,213,235, + 31, 9,220, 15, 27, 87,140,255,170,105,139, 0, 81, 68, 68, 56, 27,211,172,157,232,210,249, 99,151,109,109,109,183,189,150,158, +163,187, 27,157,158, 2, 4, 8, 16, 32,224,189,225, 4,128,158,111, 90,181,222, 20, 95,197, 22,170,210,251,111, 94, 95,116,254, + 47, 89,148, 92, 92, 42,128,196, 80,235, 16,151,155,244,214, 49,158, 51,216,144, 97,176,112,226, 12,228,228, 53,234,202, 4,147, + 81, 2,171,104, 12,214,105, 74,233,107, 2,203,202,201,175,221, 55, 51, 39,175, 12, 24,208, 77,148,252, 89, 75,100,229,105, 52, + 51,194, 88, 62,174,160, 18,113, 5, 64,196,233,130, 37, 22, 22,151,165,111,204, 22, 4, 0, 19,199,154,205,102, 77,253, 98, 93, +199, 97,189, 73,234,231, 1,200,204, 82,105,190,122,204,146,120, 21, 29, 20, 70,233,165,178,248, 46, 92,184,176, 17,192,198,246, +237,219, 39,155,154,154, 34, 47, 47,239,173,116, 45, 14,111,235, 1,221, 68,201,159, 54, 71, 70,190, 78, 51,227, 49,139, 4, 21, +191,167, 50,113,101,111,101,126,102,195,194,241,202,132,184, 87,144, 74,165, 48, 51, 51,195,185,171,143,144, 26,122,248, 93,132, + 21, 24,134,249,118,206,156, 57,243, 39, 76,152,128,244,244,116, 28, 59,118, 12, 61,122,244,192,238,221,187, 61, 79,158, 60,185, +162, 67,135, 14, 96, 24, 6,199,143, 31,135, 94,175,127, 94, 78,126,246, 27, 51,102,204, 87, 3, 6, 12,192,237,219,183,145,152, +152,248,154,229, 42, 43, 43,107,232,186,117,235, 6,188,124,249,178, 82,203,213, 27,104,230, 85,163,145,116,246,220,159,161, 41, + 72, 17,167,198,223, 12,190,112, 78,116, 35, 35, 35, 67, 9, 32,187,170,233, 41, 64,128, 0, 1, 2, 12,214, 7,229,205,198, 79, + 45, 18, 79,169,101,237,151, 18, 86,101,237,147, 55,172, 94,218, 55,206, 63,248,103, 44, 88, 60, 7,177,115,125,176,137, 15,255, + 60,148,255,186,192,146, 42,205,192,115,149,183, 95,163, 26, 17,253,215,109, 33, 94,222, 93, 4,169,153,173,174,229,204, 51,143, +203,187,214,204,204,204,208, 46, 66, 86,220,173, 31,106, 4,246, 69, 84, 61, 39, 80,189,174,196,146,133, 57,115, 94, 19, 89, 82, +169, 20,106,181, 26,120, 99,128,115, 25,184, 69, 8,121, 5,224, 6,165,148, 54,246,173,254,189,194,212,116,116,147,250, 53,236, +166,140,255, 84,242, 50, 69,131,139, 1,179,179, 14,252, 56,211, 44,150,154, 77,136,166, 89,215, 42, 41, 48,193, 61,174, 60,125, +203,114,213,200,183,250,215, 10,165,226,179, 22,254,190, 78,179,166,141,151,188, 76,214,144,139,205,102,228,252,241,211, 12,229, + 11,152,127, 21, 75, 51, 47, 25, 16,255,249, 61,122,244,152, 79, 41,165, 60,207,207, 5,128,210,225,157, 54,241, 51, 73, 84,146, + 26, 23, 2,190,206,252,227,199,153,230,177,168, 56,188,246,245,251,181,118,180,182, 56,179, 97,209, 4,101, 98,124, 52,228,114, + 57,204,205,205, 17,155,156, 13,137,152, 81,189, 75, 97, 35,132,200,219,181,107, 55,115,252,248,241,120,244,232, 17, 62,255,252, +243,196,152,152,152,131,123,247,238,253,124,222,188,121,226,192,192, 64, 36, 38, 38, 98,233,210,165,250,171, 87,175, 46, 2,176, +180,204, 66, 43, 22,127,250,253,247,223,211,132,132, 4,242,226,197, 11, 56, 59, 59,227,139, 47,190,144, 45, 90,180,168,100,204, +149, 49,150,171, 98,196,197,197, 5,251,212,240,192, 7,167, 86,130,213,107,130,179,210, 99, 46, 63,141,202, 12,182,145,201,190, + 12,104, 92,191, 74,233, 41, 64,128, 0, 1, 2,222, 11,238, 84,178,255, 63,135, 10, 5,150,158,138,178,119, 45, 25,103,249,193, +136,207, 97, 82,173, 45, 52,143,247,131,207, 77, 2,159, 91, 40, 96,100,166, 22, 48,183,115, 71, 94,129, 26, 87, 67,163,160,167, +162,236, 10,249, 56,136,127, 88,251,231,108, 65, 43, 43, 43,100,103,103,191,102,121, 81, 42,149,112,113,113, 65, 70, 70, 6, 54, +110,220, 8, 0,149, 53, 94,223, 54,109,218,116,205,162, 69,139,100,141,135,125,140,188,155, 87,222,180, 70,193,196,196, 4,114, +185, 28, 15, 31, 62,196,197,139, 23,181, 0,190,173, 68, 8,220, 98, 89,246,193,158, 61,123,226,124,170,187,117,107,223,180,217, +164, 57,179,103,153,135, 93, 57,139,185,139,214,240, 53,155, 4,102, 47,217,125, 56, 55,219,204,163, 83, 65,194,211,251, 6, 8, +139,183,157,136,122,123,116,108,217,168,225,244,185,115,191,182,120,124,229, 28,230,253,180,129,250, 52,232,156,253,211, 31, 71, +114,210,148,213,186,170,146,159,220, 54, 36, 3,131,130,130, 54, 2,216, 88,188,255,102,120,103, 45, 88,197,251, 54,237,150,185, +100,247, 31,249, 57,230, 30,157, 43, 10,175, 67,157,254,173,220,157,109,206,252,242,195, 56,101, 82,124, 12,228,114, 57,204,204, +204, 16,147,152,133,249, 43,247,229,235,120,190,219, 59,150, 55,185,185,185,185, 92,167,211, 97,237,218,181,136,137,137,105, 73, + 41,141, 33,132,108, 24, 50,100,200,234,122,245,234,213,122,252,248,241,243,188,188,188, 9,148,210,167,229,145, 88, 89, 89,181, +180,183,183, 39, 55,110,220,248, 63,246,174, 58, 60,170,227,237,158,185,235,155,221,184, 11, 65, 18,226, 64,112,119, 40, 45,238, +238, 45,210,226, 80, 8, 86, 92, 90, 40, 86,220,138,187,187, 75,139, 59, 33, 64, 66, 2,241, 16, 79, 54,217,172,223, 59,223, 31, +145,134, 52,178, 1,250,253, 42,123,158,231, 62,187,215,206,157, 59, 51,119,230,204, 59, 51,239, 96,212,168, 81,218,177, 99,199, + 10, 7, 15, 30, 76,210,211,211, 63,214,114, 5, 0,112,115,115,107,222,165, 67, 35, 52,110, 59,250,134, 86,157,113,243,221,171, +157, 55, 24,122, 75, 82,187,102,141,143,138, 79, 19, 76, 48,193, 4, 19,254,187, 40, 85, 96, 37,243, 85, 14, 27,119, 29, 89,182, +255,208,209,111, 70, 12,237, 47,105,209,102, 16,132, 41,207, 97,136,127, 4, 87,255, 38,160,124, 41,238, 63,124,140,103,225, 49, +234, 28, 29,111,139, 66,168,250,190,136,176,104, 67, 41,189, 92, 18,127,122,122, 58,170, 84,169,130,125,163,125, 2, 52,138, 36, +161, 59, 0, 38,206, 82,119,226, 97,211, 23,103,207,158,205,102, 89,118, 11,128, 67,165,113, 82, 74,183, 18, 66,206,245,234,213, +107,110,205,154, 53,135,205,157,187,148, 39,156, 48, 24,170,144,103, 48,107,209, 11, 54, 54, 54,120,251,246, 45, 46, 95,190,204, + 38, 39, 39,111, 7, 48,151, 82,154, 80, 6,231,221, 26, 53,106,196,186,187,187, 91, 57,200,165,219, 71, 15, 31,108, 30,245,236, + 46, 18, 67,159,226,214,239,161,233,123,143,156,136, 83,100, 38, 15, 47,173,114, 45,204,201, 48,204, 7,226,202,219,219, 78, 46, + 19, 91,239,250,110,196, 48,139,232,231,247,145, 20,250, 4,191,221, 10, 75,223,183,255, 88,114,106,106,226,208,146,196, 85, 89, +241, 89, 92,120,239,254,246, 58,125,255,161, 99,177, 89,202,244,175,139, 11,111, 97, 78,185, 76,240,253,137, 29, 11,205,226, 99, +163, 10,196, 85, 84, 66, 58,126, 88,181, 95,169,210,234,191, 76,126,118,204, 40, 75, 77,105,225,228, 56, 14,122,189, 62, 95, 84, + 43,242,226,251, 21,128,214,198,114,166,164,164, 92,143,140,140,236, 34,151,203, 11, 44, 87,153,153,153,189,150, 46, 93, 90, 46, +203, 85,209,112,198,198,198,222,240,172,226,246, 99, 66,159, 94, 26,103,103,251, 27,167,206, 61,120,238, 32,151,190,250,216,248, +252, 92, 48,113,154, 56, 77,156, 38,206,255, 2,231,127, 74, 96,133,132, 80, 29,128,241,254,254, 22,243,126,218,184,103,195,174, +125,135,187,141, 24,208,157, 95, 43,176, 53,222,222, 62,134,155,119,175, 26,210,213,244, 88,150,128, 55, 58,228,141,162, 76, 47, +168, 2, 30, 12,253,251,247,231, 3,128,136, 15,195,148, 58,117,174,215,170, 85,171, 73, 71,139, 36,225,156, 53,185,150,173,121, +227,250, 11, 79, 93, 59,117, 8,192, 38, 74,169,194,152,151,200, 19, 76, 35, 8, 33, 63,119,234,212,105,209,208, 6,181,186,143, +169,223, 28,122,189, 30,187,118,237, 66, 84, 84,212, 81, 0, 51, 41,165, 97,198,240, 61,127,254, 60, 37,160,106,165,241, 54, 82, +225,247,223,245,239,102,159, 28, 30,130,216,151,143, 1, 0, 26,141, 74,159, 16,122, 35,176, 60,145,156,191,112,179,191,191,191, +144,213,100, 15,145,240, 45,102,143,238,219,197, 33,245,221, 43,196,188,200,117,247,164, 81,231,232, 98, 66,175,250,126, 76, 34, + 86,170, 84, 73, 44, 19, 96,100,177,225,213,170,245,239,195, 94,214, 52,134, 39, 71,163, 93, 60,111,229,174, 47, 22,126, 63, 84, +108, 97, 97,129, 71,193,111, 48,123,197,190,114,137, 43, 35,210, 10,122,189,222,232, 25,162, 37, 96, 90, 96, 96,160,207,162, 69, +139,188,134, 12, 25,130, 79,181, 92, 21, 70,248,219,216,160, 22, 45, 90,248,191,121,253,168,165,141, 84,184,231, 83,226,211, 4, + 19, 76, 48,193, 4,147,192, 66,233, 66, 75,145, 14,160,119, 45, 55, 11,143, 69,107,247,108,145,242,185, 38, 42, 3,243,187, 74, +195,124,243, 56, 86, 17, 97,236,195,118, 60,166,130,194,251,219,115, 85,176,204,171, 58,178,243,143,189, 73, 3, 40,165, 63,125, +100,229, 29, 6,160, 7, 33,164,238,175,119, 31,207,202, 59,188,144, 82, 90,174,190, 90,115, 62,130,155,248,123,184, 54,173, 21, + 32,225,177, 42,196,190, 12, 71,154, 82,141, 75, 47,162, 50, 24,202,252,250,177,145,205,232,114,158, 54,245,247,116,111, 86, 59, +192, 76, 64,180,136, 13,121,132, 76,149, 22, 23, 95, 68,101,130,144,143, 30, 40,253,185,194,251,254,217,241, 7,246, 53,186,181, + 33,132, 92,158, 49,166,159,120,206,138,253,159, 85, 92, 1,200,137,139,139, 75,205,201,201,177,141,143,143,215,226, 35,157,187, + 81, 74,223, 16, 66,170, 79,152, 48, 97,254,148, 41, 83,190,255,241,199, 31,133, 31, 51,230,170, 36,164,199, 69, 29,107, 22,240, +249,211,223, 4, 19, 76, 48,193, 4,147,192, 42, 22,121, 98,170, 69, 11,127,123,217,239,175,147,149,159,201,162,161, 28, 82,139, + 20, 88,182, 4, 60, 24, 62, 3,231, 3, 0,157, 62,154,128, 33, 89,119,195,162,178,239,133, 69,101,131,163,148,163, 84,195, 48, +136, 81,234,116,139, 67, 35, 98, 63,126, 22, 29, 33,236,131, 55,209,170,135,225, 49,106,202,113,148,163, 84, 75, 8,222,235,245, +220,226,224,136,200, 19,127,135,240, 38, 63, 59,118,203,201,191,123,211, 91,247,130, 39, 41,149,186,181,201, 33,199,110,127,174, +204, 70, 41,213, 19, 66, 6, 52,108,216,112, 24,203,178, 27, 41,165,250, 79,224,210, 2,152, 70, 8, 57,250,252,249,243,131,183, +111,223, 78,248, 28,226,234, 47, 77,127, 19, 76, 48,193, 4, 19, 76, 2,171, 52, 92, 15,249, 60,226, 42, 31, 69, 45, 91,255,107, + 60, 15,123, 87,251,175,224, 13, 14,123, 87,237,159, 16,222,247, 33, 71, 31, 2,232,251, 87,132,149, 82,122, 17,192,197,207,200, +247,128, 16, 82, 25, 0,239,179,136,171,191, 48,253, 77, 48,193, 4, 19, 76, 48, 9, 44, 19, 76,248,199, 32,111,117, 80,131, 41, + 38, 76, 48,193, 4, 19, 76,248,187,128, 0,104, 83, 66,165,101,244,236, 0, 66, 72,155,143,168, 20, 47,155, 56, 77,156, 38, 78, + 19,167,137,211,196,105,226,252,111,113,254,151, 90,255,127,217, 6,160,141,137,211,196,105,226, 52,113,154, 56, 77,156, 38, 78, + 19,231,127,109, 99, 76, 18,211, 4, 19, 76, 48,193,132,191,172,155,132, 16,113,222, 2,239, 31,117,222, 4, 19,254,169,224,127, +196,199, 82, 53,207,242,245,230, 47,252, 32,199, 56, 59, 59,143,168, 81,163,134,159, 80, 40,100,178,178,178,230, 93,189,122,117, +110,209,235,154, 5, 8, 30,242, 24,184, 21,186, 19, 32, 60,128, 97,192, 82,196,222,124,154, 83,199,148,196,127,235,130,183,162, +212,194,254, 36, 97,120, 34,214,160, 3,171,215, 1,248,195,171, 63,199, 25,162, 12, 90,117,187,146,238,119,174,217,221,221,192, +210,165, 0,183,158,128, 25, 77,193,109, 32,148, 25, 77, 25,172, 39, 28, 70,129,175, 95, 6,131, 96, 10, 95,200,159, 25,255,232, + 80,204,191, 33,206, 14, 31, 62,204,251,148,251,123,246,236, 89,236, 2,159,174,174,174,167,205,204,204, 60, 75,186, 79,169, 84, + 38,196,199,199,183,252,151,231,199,102, 0,126, 1, 16, 80,228,212, 43, 0,227, 41,165, 87, 62,245, 25, 45, 8,225, 59, 2, 35, +133,192, 84, 0,208, 1, 63, 37, 2,155,174,127,166, 9, 26,159, 3, 14, 14, 14, 55,249,124,190,151, 82,169, 84, 42, 20, 10, 15, + 11, 11,139, 8,153, 76, 38, 51, 24, 12, 97, 73, 73, 73,205,202, 25,167,223, 34,111,201, 43, 66,200,247,148,210,245,229, 57,111, +130, 9,255,106,129, 69, 8,241, 6,208, 60,111,107, 86,183,110, 93, 71,165, 82, 9, 66, 72, 34,128,130, 37, 96, 40,165,161,159, + 35, 64, 60, 30,111,249,234,213,171, 39,143, 29, 59,182, 96,145,230,103,207,158, 21,127, 45, 3,183,107,167, 46, 59, 60,120, 30, +138,186,109,122,230, 9, 44, 6, 80, 38,160,101,219,122, 31, 91,200,154, 91, 91, 91,207, 35,132,244, 98, 24,166,204,202,140,227, + 56,150, 82,122, 40, 61, 61,125, 14,165, 52,171, 60,207,146,203, 36,122, 3,203, 22,251, 12, 62,143,199,102, 43,213, 37,206,174, +180,181,181,189,205, 48, 76,149,194, 11, 89,231,133,191,216,255,133,247, 13, 6, 67,108,114,114,114, 29, 99,226,130,225, 11,191, +103, 24,126, 27,202, 25,124, 1,128, 48,252, 87, 28,103,184,204, 25,116,203,202,251,190, 69,197,149,115, 5,143,223, 38,206, 92, +234, 22,252,242, 21,102,140,233,143, 31,127,217,129,233,227,135, 97,245,230,125, 24, 63,162, 31,252,253, 3, 74,229, 96, 41,153, + 55,123,252,128,150,139, 86,239,173, 59,115,124,127,217,162,213,123,235,206,156,208, 95,190,104,205,222, 58, 51, 39, 12,144, 47, + 92,179,167,206,172, 9, 3, 44, 22,173,217,171, 3, 48,252, 99,194,217,223,219, 85, 73, 12,134, 98, 91,215,148,207,215,236, 13, +141,147,253, 47, 62,220, 33, 67,134,212, 80,169, 84,143,250,183,173,181,180,166,183,107, 92,113,215,164,190,143,115,141,120,253, + 56, 72, 32,148,214,238, 18,180,227, 89,105,124, 98,177,184,202,171, 87,175,188, 56,142, 3,203,178, 48, 24, 12, 5,191, 90,173, + 22,205,154, 53,251, 44, 19, 98, 8, 33,157, 0,204,203,253, 88,177,132, 82,122,240, 19,184,228,124, 62,127,162, 72, 36,106,110, + 48, 24,252, 0, 64, 32, 16,188,212,104, 52, 55, 12, 6,195, 74, 74,105,118, 57, 41, 87,197,197,197,249,203,229,114,232,116,186, +130,133,225,121, 60,158,175,187,187,251, 58, 0, 94,159,250,254,142,192,200, 70, 77,154,172, 30, 60,121, 50, 79,117,243, 38, 86, +111,223,190, 10, 10, 5, 0,172, 43,235, 94,177, 88,124,129, 97,152,138,229,121, 30,199,113, 81, 26,141,166, 93,185, 42, 5, 62, +223, 43, 62, 62,222,193,197,197, 5, 0, 32,147,201,100,133,247,203, 99,185, 2,176,140, 82, 42, 5, 0,134, 97, 86, 55,106,212, +168, 33, 33,196, 0,128,114, 28,199, 16, 66,250,113, 28,199,207,187,126, 25, 33,100, 59,165, 84, 99,170,154, 77,248, 87, 11, 44, + 66,200, 89, 0,205,235,214,173, 43,237,219,183, 47,154, 55,111, 14, 47, 47, 47, 72, 36,146,220,194, 59, 53,213,241,201,147, 39, +189,111,222,188,217,251,212,169, 83, 32,132,168, 0,252, 78, 41, 45,246, 99,110,211,169,233, 88,137, 92,188, 6, 0,146, 99, 83, + 19, 98,223, 38,173, 73, 72, 72, 88, 70, 41,229, 10, 61,211, 99,240,224,193,147,198,141, 27,135,211,167, 79, 99,223,190,125,208, +104, 52,200,202,202,194,213,171, 87,139, 15,104, 78, 18,210,175, 46, 5,100,239,128,232, 27,128,153, 3, 32,115,252,232, 8,177, +182,182,158, 55,126,252,248, 9,254,254,254, 5, 94,199,245,122, 61, 12, 6, 3,244,122, 61,210,211,211, 49,105,210, 36,228, 89, +241,192,113, 28,206,157, 59, 55,118,196,136, 17, 0, 48,177, 56,206,134,117,220, 31, 50,132,113,203,183,205, 80,150,141,189,243, + 56,166,142,129,101,121,106,181,174,216,149,195, 37, 18, 97,169,226, 78, 32, 16,184,133,156, 60,233,192,136, 68,160, 44, 11,112, + 28, 40,199, 1, 40,180,209,220, 99,148,229, 64,245, 44, 56, 3, 7,131, 74,131,122,223,126,107, 76,225,216, 82, 32,146,236, 27, + 62,122,146,117,131,134, 13, 5,110,174, 46,208, 27, 88,132, 71,188,171,119,255,238,157,154,135,118,111,250,134, 16,210,143, 82, +122,237, 99,226, 89,100,102,113,113,237,134, 45,110, 15,158, 4,227,202,181,155,184,124,245, 6, 0,224,194,181, 92,183, 91, 12, +195,148, 21, 62,107, 91,175,150, 53,198, 14,235, 42, 91,248,243, 86,241,216, 97, 93,249,127,252,110, 17,143, 29,214,133,191,104, +229, 22,241,216, 97, 93, 4, 11,126, 90, 91,147, 16, 98, 77, 41, 45,113,181,129,146,210,136, 24, 12,226, 61, 17,137, 60, 0, 72, +222,184, 17,250,164, 36,184,204,153, 3, 0, 24,224,225,104,116,183,134,189,189,253, 67,129, 64,224, 86,214,117,122,189,190, 76, +241, 59,100,200,144, 64,149, 74,245,208, 96, 48, 80, 62,159, 31,212,191,219, 23,199,191,108, 26,152, 90,248,154,103,207,158,218, + 46, 94,124,178,235,193, 71, 89,180,119,109,243, 71,167,151, 15,169,211,113,202,142,167,165, 84,196,140, 70,163, 65, 88, 88,216, + 7,107,131, 22,214,179, 31, 41,130, 24, 0,171,109,109,109,235,167,166,166, 14, 0, 48, 67,161, 80,212,224,241,120,176,177,177, +153, 65, 8, 9,183,180,180,220,154,153,153,121, 59,207, 74,196, 25,201,219,204,194,194, 98,215,177, 99,199,172,107,213,170,197, +164,164,164,160,114,229,202, 72, 75, 75,171,119,243,230,205,218,195,135, 15, 31, 78, 8, 25, 68, 41,189, 89,142,224,250,152,153, +153,209,193,131, 7, 19,150,253,227,117,183,109,219,134,118,213, 12,158,163,190,148,229,168,181, 52,243, 74,152,229, 40,161, 80, +248,123,100,100,100,102,121,227, 67, 8, 76, 29, 60,121, 50, 79, 30, 25, 9,249,211,167, 24,160, 80,240,127,204,181,102,149, 41, +176, 24,134,169,184,107,223,175, 94, 34,145, 8, 6,131,161, 64, 4,230,151, 81,122,189, 30, 58,157, 14,122,189, 30, 44,203, 66, +175,211, 99,201,194,159, 62,186, 44, 52, 51, 51, 51,115,113,113, 73, 52, 51, 51, 51,251, 28,149,141, 88, 44,230,239,220,185,179, +159, 72, 36, 2, 0,104,181, 90, 84,171, 86,141,152,170, 97, 19,254,139, 22,172,175, 20, 10, 5, 88,150,133,185,185, 57,120, 60, + 94, 81, 11, 10,218,182,109,139,102,205,154,161,111,223,190, 8, 9, 9,145,246,237,219,183,109,137,150,128,201, 29, 81,193,203, + 49,175, 18,225,156,111,157,121,178,116,219,130,195,246, 0, 38, 23,186,108,248,200,145, 35, 73,106,106, 42,122,245,234,117, 83, +163,209,116, 46,109,185, 28,150, 67,108,203,190, 3,192, 81, 34, 93,121,111, 11,209,170, 85,148, 97, 24, 85,126, 23,225, 71, 86, + 8,189, 92, 92, 92,176,127,255,126,104,181,218, 63,157,183,176,176,192,139, 23, 47, 10, 91,220,208,160, 65, 3, 30, 33,164, 87, + 73, 2,139, 16,198,237,214,131, 72,135,252,253,142,109, 3,132, 13,235, 84, 76,180,183, 53,167, 0,200,204,153, 51, 11, 4, 27, + 0,204,155, 55,207,152,112,130, 17, 8,144,124,227,198, 31, 5, 48,159, 1, 35, 36, 32, 2,128,225,231,246,150,130, 2,148, 5, + 56, 3,192,233, 1,137,115, 5, 99,184, 91, 84,168,232,113,124,249, 47,155,205,181, 6,224,204,213,251,136,142,191, 2, 74, 41, +156, 29,108,208,168,110, 99, 65,173,186,245, 29,126,154, 55,237, 56, 33,164, 11,165,244,122,185, 35,154,163, 18, 79,119, 59,108, +221,246, 8,246,214,114,244,234,218, 30, 82,137, 24, 63,254,242, 43, 22, 78, 31, 3, 47,143,138,216,180,106, 81,137,183, 91, 90, + 90,206,175, 85,221,215,227,215,131,231,209,188, 89, 35,254,142,131, 23,208,162, 89, 99,254,175, 7,207,163, 69,243,166,252, 29, + 7,207,163, 69,179, 38,130, 29, 7,207,163, 65,157,234,158,183, 83,159,205, 7, 48,166,228,119, 46,146, 70, 95,228,166,145, 23, + 95, 88, 80, 1, 68,142, 30, 13, 0, 5, 2,171, 60, 16, 8, 4,110,241,241,241, 14,101, 93, 87,150,149, 32,207,114,245,208, 96, + 48, 32, 41, 41,137,100,100,100, 80, 43, 43,171,174,231, 55,205, 56,214,174, 73, 96, 26, 0, 60,125,250,212,102,201,146,197, 93, + 15, 60, 84, 64,117,119, 45,217,115,242, 6, 55,160,115,243,135, 39,150, 14,169,221,179,103,207,199,197,241,106, 52,154,119, 53, +107,214,164,121,255, 93,197, 98,177,176, 72,158,112,241,242,242,250,147,149,218,136,174,195,213,119,238,220, 25,227,239,239, 15, + 95, 95,223,219,245,235,215,183,144,201,100, 56,127,254, 60,252,252,252, 2, 44, 44, 44,238, 29, 58,116, 72, 48,109,218,180,192, +237,219,183, 3,192, 88, 35,242,103,155,150, 45, 91,238, 63,125,250,180, 68, 40, 20, 66,165, 82,225,197,139, 23,176,180,180,132, + 72, 36, 66,151, 46, 93,120,141, 27, 55,182,109,209,162,197,145,188, 70,128,209, 51,154,212,106, 53,157, 49, 99, 6,204,204,204, + 96,102,102, 6,153, 76, 6,153, 76, 6,185, 4,100,227,120,119,233,184,205, 25,210,137,115, 54, 46,221,181,126,238, 53,119,119, +247, 31,162,163,163, 51,202,155, 23, 84, 55,111, 66,254,244, 41, 80,232,219, 53, 22,150, 50, 27, 4, 5, 5,149,101,129,130, 80, + 40, 68,163, 70,141,202,228,179,181,181, 61,202,231,243, 63,104,145, 82, 74, 37, 65, 65, 65,108,104,104,168,140, 97, 24, 25,199, +113, 8, 10, 10, 98, 13, 6,131,196,209,209,241, 54,199,113,137,201,201,201,221,203,226,166,148,106, 8, 33,223, 51, 12,179, 90, + 44, 22,243, 43, 85,170, 20, 53,123,246,236, 59,121,214, 75, 80, 74,153, 74,149, 42,213,147, 74,165, 21, 53, 26,141, 1,192,247, + 38,235,149, 9,165,160,118,174, 17,184, 0, 90, 0,162,124,131,125,110,109, 7,187, 34,199, 1, 32, 37,175,129,232, 88,194,126, + 42,128, 16, 0, 62, 0, 28,242,206, 61, 0,144,246, 89, 4, 22, 33,132, 22,250, 40, 10, 42, 20,115,115,115, 60,120,240, 0,132, + 16,152,155,155,195,194,194, 2,150,150,150, 80, 40, 20, 8, 9, 9,193,171, 87,175, 16, 25, 25, 9, 66, 8, 60, 60, 60,144,255, +225, 20,226, 42, 40,216,246,254,124, 26, 18,185, 24,132, 0,181, 90,213, 64,141,102,213, 80,247,126,196,120, 23, 23,151,205,241, +241,241, 97,132, 16,126,181,106,213,134, 55,104,208, 0, 43, 86,172,128, 70,163, 89, 81,156,184, 42,204,121,243,133,190, 78, 94, +165, 52,101,247,249,112,179,129, 95,122,230,196,199,199, 47, 47,111, 36, 20, 45,128, 83, 82, 82,140, 94, 43,143,227, 56,164,167, +167,151,202, 89,212, 34,176,114,245, 90,171,172,204, 68, 44,248,113, 55,244,122, 61, 38, 79,158, 12,142,227, 10,182,140,140, 12, +163,194, 73,217, 34, 70, 5, 38,119, 35, 12, 64,248,128,123,159, 92, 61, 17,189,127, 45, 8, 5, 8, 11,160,200,123, 21,229, 36, +132,200,248, 66,241,190, 37, 43,214,155, 7,135,197,225,244,213,251,160,148,226,196,230, 31, 0, 0, 93, 70,204, 71,220,251, 20, + 52,174,237,139,201,179, 22,154,207,152,240,205, 62, 66,136, 39,165, 84, 89, 18,103,241,239,194, 98,193,252,249,216,188,102, 5, +126, 90,177, 6,138,204, 12, 8, 4,118, 0, 0,131,129, 5, 91,228,221,254,244,238,148,126, 57,107,202, 72,178,122,203, 17, 84, +171,234,132, 83,151,110,163, 78, 64, 69,156,187,122, 31, 13,170, 87,198,133, 27,143,208,160, 70, 21,220,184,251, 2,147,191, 27, + 76,110,157,219,241,101,121,210,104,213,170,181, 86, 89,138, 68,156, 94,180, 19, 73,235,214, 33,106,204, 24,212,203,187,230, 62, + 33, 16,186,185, 1,194,178,211,168, 40, 94,190,124, 9,141, 70, 83, 92,235, 30,126,126,126,101,166,187, 74,165,122,100, 48, 24, +104, 98, 98, 34, 73, 76, 76,132, 76, 38, 35, 47, 94, 4,179, 1, 1,213,186,209, 87,135,183, 0,192,146, 37,139,187, 29,124,164, + 64,206,237, 53, 80,221,249, 5,194,202,207,152,205,243, 70,234, 70,204,217,244,168, 80,229,246, 65, 56, 19, 18, 18,190,202,255, +239,225,225,241, 42, 52, 52,212, 39,191, 75, 57,175,171, 80,104, 48, 24,188,242,187, 13, 13, 6, 3, 52, 26, 13,218,180,105,195, + 43,237,221,173,173,173, 27,248,249,249,225,241,227,199, 88,179,102,141, 77,203,150, 45,241,230,205, 27, 16, 66,176,120,241, 98, +226,239,239, 47, 72, 73, 73, 65,187,118,237,112,244,232,209, 70,101,197, 39, 33,196, 92, 38,147,109, 63,117,234,148,132, 97, 24, +100,101,101,129,227, 56, 52,110,220, 24, 12,195, 32, 56, 56, 24, 51,103,206,196,209,163, 71,113,252,248,113,105,237,218,181,183, + 19, 66,252, 10,119,103,151,146, 70, 84,173, 86, 83,177, 88, 12,177, 88, 12,137, 68, 2,137, 68, 2,145, 72,132,108, 53, 48, 98, +101,148,134, 39,177,227, 2,106, 54,241, 28, 58,110, 49,179,124,246,176,171, 0, 78, 24,155,231,129,220, 49, 87,171,127,253,117, +205,128,204, 76, 6, 0,182, 18,194,233, 74, 88, 26,172, 56,206,108,117, 38, 42,122,184,225,200,129,227,232,209,167,107,177,226, + 74, 32, 16, 66, 40, 16,192,194, 70, 86, 38,167, 80, 40,116,124,245,234,149,173, 64, 32, 40,176,200,235,245,250,196,217,179,103, +219,119,232,208,193,252,220,185,115, 76,135, 14, 29, 56, 59, 59, 59,229,227,199,143,147,116, 58,157,109,227,198,141,141,206,243, +148,210,245, 53,107,214,172,117,236,216,177, 97, 65, 65, 65, 15,167, 76,153,178,160,240,249,101,203,150,205, 63,123,246,108,197, +110,221,186,237,122,242,228,201,250,242,148, 33,159, 90,206,155, 56,255,126,156, 37,105,145, 60, 56, 18, 66, 78, 23, 58,223, 49, +127, 63, 40, 40,104,198,146, 37, 75, 94, 16, 66, 78, 23, 62,158,127, 93, 30,247,233,226,246,243,238,181,153, 62,125,122,181,165, + 75,151, 46,110,216,176,225,254,219,183,111,191,253,108, 2, 43,255, 69, 10,191, 92,145,136,132, 66,161,128, 66,161, 64, 76, 76, + 12, 54,110,220,152,247, 33, 11,192,231,243,193,231,243, 11,198, 43,148,132,203,167,126,251, 5,192, 47,181,107,215, 22, 60,191, +115,232,220,212,205,227, 90,215,105, 83,139,247,232,202,243,158, 0, 22, 2,248,106,240,224,193,118, 0,176,115,231,206, 20, 0, +231,254, 23, 18,153, 82,122, 40, 44, 44,108,130,179,179,115,193, 24,148,194,221,132, 6,131, 1, 18,137, 4,249, 99, 85,212,106, + 53, 54,110,220,104,160,148, 30, 42,133, 19,161, 47,174, 34,236,197,181,220,251, 56, 14, 28,251,199,253,115,231,206, 45, 60,245, + 21,163,243, 44, 37,101,138,187,226,226,156, 22,249, 45,114,252, 79,162,172,104, 55, 4, 95, 56,185,255,176,111,109, 56,194, 47, + 16, 87,185,239,144, 43,204, 68, 66, 62,164, 98, 33, 66, 35,162, 81,201,181, 54,186,246, 30,100,125,108,255,175,147,145, 59,174, +166, 92,240,173,209, 16,227, 39, 76,192,150,205,155, 49,115,206,252, 2,117,110, 96, 89, 24,202, 10, 39,195, 48,141,235,248, 35, + 59, 53, 22, 60, 30, 15,141,106,122,130,199,227,161,105, 29,111,240,120, 60, 52,169,235, 3, 62,159,143, 22, 13,252, 81,181,106, + 85,240,249,124,166,140,116, 71,232,139, 43, 8,123,113,189,144,216,165,160, 0,116, 9, 9,127,186, 94,159,144, 0,234,110, 91, +222,188,133,225,195,135,103,196,196,196,232,138,158,171, 80,161,130,240,230,205,155, 86, 37,116,207, 21, 64, 42,149,214,230,243, +249,143,210,210,210, 56, 51, 51, 51,134,227, 88, 46, 32,160, 26,239,252,166, 25,199,242,175,153, 62,125,198,177,222,181, 45,186, +237, 62,116,154, 10, 43, 53, 33, 68, 32, 54,124, 51,103,147, 80, 32,148, 26,229,161, 62,191,187,240,245,235,215, 40, 43, 60,197, + 20,130, 31, 32, 61, 61,125,176,159,159,223,205, 95,126,249,197,134, 16,130,223,126,251, 13, 60, 30,175, 96,139,136,136, 0,195, + 48,152, 58,117,170, 78,161, 80,124, 93,102,129,197,231, 79, 56,114,228,136,165, 72, 36, 66, 86, 86, 86,193,119,195,227,241,240, +234,213, 43, 44, 95,190, 28,131, 7, 15, 70,116,116, 52, 92, 92, 92, 48,121,242,100,249,210,165, 75, 39, 0,152,111,196,171, 63, +211,106,181,117,204,204,204, 32,145, 72,144, 47,180, 0,224,226, 11, 65,112, 78, 78, 78,117, 59, 59, 59, 39,251, 27,167, 79, 54, +106,217, 57,208,214,222,185, 97,190,192, 50, 22,225,192,230,119, 44, 59,235,171, 99,199, 28,110, 29, 59,198,221, 61,117, 42, 86, +156,149,181,201,232, 60,164,103, 16, 21, 17,139,218,181,107,227,209,163, 71,168, 93,187,118, 97,177, 4,145, 72, 4,161, 80, 8, +161, 80, 8, 59,107,163,134, 74, 80,134, 97,112,235,214,135,203,141, 54,109,218, 52,237,218,181,107,114, 0,136,138,138,162, 29, + 59,118,204, 8, 9, 9,129,151, 87,233,195,208,156,156,156,110,242,120,188, 74, 69,190, 85,235,238,221,187, 35, 61, 61,189,125, +247,238,221,155,228, 29,139, 59,124,248,240, 64, 0, 16,137, 68, 96, 24,134,133, 9,255,121,148,165, 69, 10, 11,164,162, 66,107, +201,146, 37, 29,139, 30, 43, 44,166,138,251, 95,248,222,165, 75,151, 46, 46,196,173,250, 28,239,195, 47,172, 28,203, 42, 44, 75, + 67, 89, 2, 43, 31,143, 30, 61,210,187,186,186,110, 9,123, 18,217,218,179,134, 7,164, 50,241, 23,132,144, 95,196, 98,241,164, + 65,131, 6,225,238,221,187, 8, 14, 14,222,246,169,203,158, 84,175, 94,253,130, 88, 44,174, 88, 66,119, 72,212,243,231,207,219, +149, 80, 33,204,201, 27, 83, 86,226, 32,247,194,227,193, 10, 15,114, 47, 49, 67,112, 20,122,157, 30,202, 28,213, 31,149,119,158, +192, 82, 42,149,232,211,167,207, 7, 22,172,164,164, 36, 99,148, 62,246, 63,124,136,187, 23, 47,162,129,187, 59,110, 68, 68, 96, + 84,211, 70,168,228, 96, 3,202, 18, 80, 2, 68,239, 91, 11,133, 74,131,139,207, 66,161, 80,105,241,133,143, 15,220, 45,236,202, + 16, 46,252,118,245,234, 53, 18, 92,189,253,236,131,202,181,235,200,133, 16, 11,249, 48, 19, 11, 33, 17, 11, 32, 21, 11, 17, 19, +151,136,154,181,234, 10, 79, 29,221,215,238, 99, 4, 86,133,138,149,193,178, 44, 6, 15, 30,140,253,251,247,195,214,169, 34, 44, + 43, 84,195,194, 21,155,209,190, 77,211, 50,223, 63,191,197,206,231,243,193,227,241,254,244,155,255,223, 24,107, 36,229, 40,116, + 69,211,136,163, 0,165,112, 91,180, 8,110,139, 22,225,126,222, 51,253,149, 74,168, 84, 42,160,126, 64,185,196,149, 86,171, 69, + 76, 76,140, 46, 33, 33,193,177,152,138, 41, 81,171,213,150, 41,104,118,236,216,241,108,200,144, 33,117,108,108,108, 30, 62,123, +250, 84, 95, 35, 48, 80,112,110,227,140,227,249,221,131, 0, 16, 24, 24,152, 54, 99,198,140,227, 3,123,117,236,186, 62,168, 47, +251,237,252, 93,124,177, 84, 90,167,227,148,210, 7,186, 23,250, 62,222,213,168, 81,131, 26,115,109, 78, 78,206,251, 82,210,168, + 19,128,121,181,106,213,178,104,217,178, 37,110,222,188,137, 30, 61,122,104,116, 58, 93, 24, 0,116,232,208,193,123,239,222,189, +162,144,144, 16,216,219,219, 11,162,162,162,182, 19, 66, 74, 29,248, 46, 18,137, 90,212,173, 91,151,209,104, 52,127, 18, 87, 75, +151, 46, 69,191,126,253,224,237,237, 13,142,227,144,157,157,141,150, 45, 91, 10,214,172, 89,211,194, 72,129, 53,222,215,215,119, + 57,114,103, 17, 22, 46, 11, 95, 2,248, 62,207,186,253,190, 99,143,193, 47,154,182,233, 94,167, 82,213,106,206,101, 17, 58, 58, + 58, 78,103, 24,166, 55,199,113, 60,133, 66, 17,163, 37,164,170,127,197,138,142,141,187,118, 69,166, 64,192, 91,125,229, 10,147, +152,149, 37, 7, 96, 84, 87,163, 90,175, 68, 69,143,220,161,124, 61,250,116,197,163, 71,143,208,179,111, 55, 8,133, 66,240,249, + 2, 8, 5, 2, 8,132,185, 22, 44, 43, 59, 11,163,242,166, 94,175,255, 83, 94,165,148,194,194,194,162,160, 39, 35,255,152, 94, +175, 47,181,242, 3,224,117,105,193,108, 7,161,133, 37, 56,131, 30,238,157,123, 22,228,233,176,237,235,165,224, 56,105,118,244, + 59,244,217,127,234,111,181, 60,154, 9,127, 31,148,165, 69, 10, 11,164,207,240,172,211, 65, 65, 65, 51, 0,208,160,160,160, 25, +249,251, 75,150, 44, 81, 1,136,251, 44, 2,235, 83,197, 85,126, 55, 66,105,104,213,170,213, 88,115,115,243, 53, 0, 80,167, 78, + 29,196,220,141, 67,204,221, 56,248,249, 4, 52,174, 21, 88, 39,179, 95,191,126,176,181,181,197,148, 41, 83, 40,128,109,229,125, +126, 68,232, 11, 57, 0,234,226,226, 50, 5, 0, 92, 92, 92, 2,239,223,191,111,255,224,193, 3,212,173, 91,247, 15, 19,189, 78, +135, 38, 77,154,148, 86, 17,102, 33,119, 44,213,196,207,167,202, 57,232,116, 58,228,228,168,160,213,234, 96,208,115, 48, 24, 12, +168, 29, 96,142, 93,155,131,114,143, 25,242,173,101,185, 86, 50, 55, 39,115,212,174,238,164,103, 24,162,122,240, 52,193,162,164, +130, 49, 60, 37, 5,111,146,147,115, 45, 23, 39,207,148, 26,142, 11,193,175, 81,165, 74,149,210,173, 23,172,222,199,197,197, 9, +209,151, 30, 0, 0,228,102, 18, 92,216,185, 0, 50,179,220,201, 13,237, 7,207,128, 84, 44,132, 84, 44,128, 78,167,131,179,115, + 37, 24,116, 58,159,146,248,100, 54,206, 23,248, 66, 73, 69,202,114,160,148, 3,229, 88, 80,202, 65,108,110,107, 54,118,244, 48, +112, 28,139,122,245,234,129,240,120, 96,245, 26,244,234,212, 22,233,153, 89,176,181, 50,174,114, 16, 10,133,104,222,188,185,180, +164,243,111,222,188, 81, 21, 22,100,165,167,145, 30, 74,165, 10, 26,141, 6, 58,173, 1, 58,189, 1,108, 21, 33, 22,204,234, 15, +131,206,128,156,190, 13,161,211, 27,192, 77,232, 6,157, 86,143,104, 51,134, 9,244,183,215, 51, 32,170,199, 33, 73, 22,101, 9, +172,124, 81, 80, 18,138, 27,243, 87,130,200,122, 58,100,200,144,218, 53, 2, 3, 31,245,110, 19,248,243,243,224, 23,241,207,131, + 95,252,233,186,138,222,129,239,190, 93,186,127,178, 64, 40,173,109,172,184, 2, 62,236, 46,252, 68,204,200,202,202,170, 33,151, +203, 17, 26, 26, 10, 30,143, 7, 66,200, 27, 74,105, 13, 0, 24, 57,114,100, 56,159,207,247,224,241,120, 88,183,110, 29,225,243, +249,213, 27, 54,108, 56, 3,192,193, 82, 26,114,126,230,230,230, 31, 88,175,132, 66, 33,130,130,130, 48,112,224,192, 2,113, 37, + 20, 10,177, 99,199, 14,212,169, 83, 7, 90,173,214,207, 72, 17,252, 0, 64, 83, 35, 44,124, 36, 79,148,151, 41, 66, 13, 6,195, +144,212,222,189,171,226,198, 13, 52,246,240,240,175, 93,187, 54,116,186, 63, 12,152, 30, 30, 30, 21,178,178,178,222, 19, 66,246, + 0, 88, 79, 41,125, 82,170, 24, 82,115,136,138,136,205,111,172,162, 94,189,122, 5, 22,171,194,214, 43,161, 80, 8,169, 72, 94, +110,129, 69, 41,133, 82,169,100,206,159, 63,111,231,231,231, 71, 0,192,223,223,159,220,189,123,215, 70, 42,149,166,184,184,184, +148,217,240, 21, 90, 88,226,242,240, 62, 0,128, 94,173,190, 44,104, 16, 61, 92, 48, 3,124,129, 0,129,147,102,252, 41,223,115, + 28,199,131, 9, 38,113,101,132, 22,249, 92,226,170,168, 5,107,201,146, 37, 47,150, 44, 89,242, 39,107,216,103,179, 96, 25, 99, +242, 55,182, 21, 84, 20, 43, 86,172, 64,245,234,213, 75,173,128,214,172, 89,131,221,187,119,175,160,148, 70,148,247,249, 29, 91, +215, 10,192,202, 99, 47, 60,188, 3, 8, 0,204,159,208,137, 81, 42,149,184,117,235, 22, 44, 45, 45,241,230,205, 27, 99, 19,216, +220,210,210,114, 30,195, 48,189,120, 69, 71,246, 23, 47, 44, 89,142,227, 14,101,102,102,150,232,166,129, 82, 64,167, 55, 64,153, +163,134, 86,171,197,132,169,107,203, 12,199, 18,128,232,180, 89,252,230,205, 26, 74, 75,178,224,248, 85,240, 65,207,102, 93,255, + 84,105, 51, 12,114,199,186, 53,201,157,140,246,248,247,135,160, 52,119,248,149,149,173, 21,238,222,190, 93,234,179,181, 58, 3, +242, 41,179,115,212,104,213,127, 58,238,159, 88, 5, 0,185,226, 74, 34,128, 84, 36,132, 84,196, 7, 67,242, 92, 99,148, 84,216, +138,164, 21,211, 19, 34,188, 54,159,126,142, 17, 29,171,227,240,229,103,232,217,166, 6,174,221, 11, 65,203,250,254,120, 17, 22, +137, 0,175, 74, 88,183,253, 16, 40, 69,214,134,149, 11,223,255, 81,145, 25,162,140,177, 96,221,189,123, 87, 85,212,106, 85,248, +151,150, 93, 15,130,210, 63, 44, 88, 42,181, 6, 83,166, 27,229,142, 39, 55,141,154, 54,144, 26,115,113,105, 22, 42, 99, 4, 88, + 81, 75, 22,202,112,179, 82, 5, 64, 29, 96,218,255,178,192,100, 89, 22,103,206,156, 41, 72,143,226,210,177,112,218, 25, 33,110, + 16, 21, 21,133, 23, 47, 94,160, 65,131, 6,200,204,204,132,128, 97, 48,249,249,115,248, 15, 26, 4,173, 80, 8,142,227, 32, 18, +137, 48,114,228, 72,163,227,179,156,165,114,222, 56, 54,150,150, 81,150,252,220,177, 99,199,170,161, 74, 37, 94,188,122,133, 54, +115,231, 2, 0,206,158, 61,251, 65,158,152, 52,105,146, 40, 36, 36,100,248,195,135, 15,135, 19, 66, 86, 80, 74, 39,151, 88,206, + 82, 77,193, 24,172,222,253,123,160,170,111, 21,236,254,117, 95,193,249, 73,223,143,135, 64, 32,132, 64, 40,128,149,165,149, 81, +111, 83,184,236,206,201,201, 97, 14, 31, 62,236,214,162, 69, 11,225,136, 17, 35, 8, 0,108,222,188,153,217,186,117,171,236,226, +197,139, 66, 75, 75,203,132, 50,211, 72,175,251, 83, 26, 19, 66,192, 23, 8,192, 23, 9, 1,142, 3, 33, 68,182,108,217,178,249, + 47, 94,188,168,235,235,235, 11,141, 70, 51,136, 16,242,216,228, 7,203,132,178,180, 72,113, 99,169,242,172, 80, 37, 33,185,240, +184,172,146, 4, 90,225, 49, 89, 0, 62,203,100, 11,126, 89,162,138,199,227,149,105,157, 98, 24,166,204, 46,194, 73,147, 38,193, +220,220,188,164,138,135, 62,127,254, 60, 36, 33, 33, 97, 51,165,116,237,199,188,200,233, 43,143, 95,204,155,216, 45, 11,121,125, +167, 86, 86, 86, 41,173, 90,181,202, 6,160, 59,120,240,195, 6,177, 70,163, 41,177,226,182,180,180,156,183,117,235,214,113, 93, +187,118,101,138,186, 10, 40,220,141,151,191,233,245,122, 28, 60,120,112,220,180,105,211, 80,146,213, 43,191,242,206, 81,170,160, +202, 27,224, 28, 30,124,216,216,194,188,196, 83,246, 14,174,240,241, 47, 89, 64, 72, 37,185, 99,132,170,250,252, 49, 78, 67, 98, + 38, 6, 91, 10, 39,195, 19,132, 70,188,139,172,231,100,103,133,244,204,108,136, 69, 2, 72,197,130, 66,156,185,214, 43,169, 88, + 0,107, 43,115, 36, 39,198, 67, 36, 18,150,234, 3,109,225,222,199,184, 23, 28,137, 35,151,159, 64,167, 86, 98,229,206,243,208, +105,178,161, 83, 43,161, 83,231,254, 46,158,246, 13, 8,193,123,157, 58,219,187, 92, 25,152,207, 71,253,250,245, 75, 20, 56,113, +113,113, 70, 90,176,104,129, 5, 75,165, 46,103, 26, 25,215, 82, 42,213, 66,149,127,254, 99, 5, 65,190,235, 6,169, 84, 90,103, +199,142,146,221, 49, 20, 7,103,103,231,115,114,185,188,178,177,215,151,195,233,232, 98, 43, 43,171,121,190,190,190,126, 43, 87, +174, 20,240,120, 60,180,110,221,218,251,155,111,190,137, 2,128,234,213,171,187,228,151, 49,223,126,251, 45,189,123,247,110,112, +110,219,162,100,136, 68,162, 87,150,150,150,117, 90,182,108,137,204,204, 76,196,196,196, 64, 38,147,193,255,231,159,241,252,219, +111, 17,184,113, 35,152, 86,173, 64, 8,129, 72, 36,194,243,231,207, 33,149, 74, 95,149, 82,152,215, 7,240, 19,128,198,248,163, + 91,144, 2,184, 5, 96, 42,165,244, 94, 49,229, 29, 3, 0, 44,199,149,149, 88,253,167, 76,153,130, 12,129, 0,232,208, 1,194, +136, 8,232,116, 58, 52,104,208,160,192,170,222,160, 65, 3,240,249,124,212,168, 81, 3, 46, 46, 46, 88,183,110, 93,127,124, 56, +179,250, 3,168,179,117,136,138,136, 69,195,134, 13, 11, 44, 85, 29, 58,116, 40,176, 96, 9, 4,130, 2, 75, 22, 97,121, 70, 85, +102,133, 5,150, 94,175, 39, 66,161,144, 63,106,212, 40,242,245,215, 95, 83,189, 94,207, 9,133, 66,102,203,150, 45,228,238,221, +187,124,149, 74, 85,102, 3,220,189, 75, 47,244,106,157,107, 4, 61, 82,213, 30,188, 60, 97,213, 37, 56,182, 32, 93, 44,182,239, + 23, 45, 93,186,180,167,175,175,111,110,119, 59,192, 55,249,193, 50,161, 12, 3, 79,114, 17,113,164, 45,180,159, 12,128,228,237, + 39, 23, 18, 82,201,200,157, 17, 88,183,200,181,249,231,181, 69,126,243,207, 63,253, 28,239, 83, 90, 11, 56,236,206,157, 59, 94, +181,107,215, 70,116,116,244,159,102,182,229, 87, 88, 50,153, 12, 82,169, 20,183,115,173, 34, 97, 37,145, 93,189,122,245, 23,228, +122, 73, 6, 0,184,184,184, 52,108,217,187,197,237,122, 95,214,197,222, 37,251, 50, 19, 18, 18,106,228,251,192, 33,132, 16, 23, + 23,151,129, 2, 17,191,143, 71, 53,247,230,224,184,159, 46,159,252,125,110,105, 47,226,225, 29,144, 13, 64, 85,104, 22,225,242, +143,137, 16,134, 97,122,117,237,218,149, 9, 9, 9, 65,159, 62,125,176,123,247,238, 18,175, 29, 56,112, 32,246,239,223,143,174, + 93,187, 50,211,167, 79,239, 85,150,192,202,181,142,104, 63, 91,102,124,242,226, 49,182,108,219, 82,226, 24, 35, 23,215,220, 41, +255,241,113,241, 5,199,154, 55,106, 81,134,133,192,112,249,193,189,219, 53, 27, 52,109, 35,136,140, 77,132, 68,196,135,164,208, +140,125,105,222,248, 43,169, 88, 0, 39,123,107, 92,189,120, 90,167,215,105, 75,157, 77, 50,174,107, 0,190,237,228, 7, 80, 14, +221, 38,111,195,233,181, 99, 11,186,119,154,244, 24,143, 43, 7, 87, 27, 61,134,175, 40, 4, 2, 1,158, 63,127,174, 42,201,122, +197,227,241,202,244,169,245,135,149, 81,143,156, 28, 21,114, 84,234,207,217, 26,179,119,116,116,220, 96, 99, 99, 35, 41, 78, 64, + 17, 66,236,237,237,237, 55,216,218,218, 74,140,237, 34, 44, 73, 92,229,249,197,122, 56,100,200,144,114,137, 44,177, 88, 92, 57, + 44, 44,172,192,201,104,105,191, 90,173, 22, 45, 91,182,228, 27, 89, 88,158, 34,132,188,117,118,118,190,229,239,239,111, 25, 30, + 30,142,125,251,246, 9, 5, 2,129,123,126,249,145,149,149, 5, 30,143,135,164,164, 36, 61,128, 97,101,117,145,105, 52,154, 27, + 55,110,220,168,217,169, 83, 39,222,171, 87,175,192,227,241,114,195,213,176, 33, 2, 55,110, 68,240,196,137,104, 30, 25, 9,181, + 78, 7,137, 68,130, 11, 23, 46,232,114,114,114,110,148,196, 39,149, 74, 55,191,123,247, 46, 64, 34,145, 64,167,211,129,227, 56, + 48, 12, 67,248,124,126, 19, 43, 43,171, 53, 0,234, 22,190,222,193,193,193, 97,228,164, 31,125, 88,131,129, 77,136, 14, 79, 46, + 43, 14, 82, 83, 83,113,234,212, 41, 52,104,208, 0,205,155, 55, 71, 92, 92, 28, 34, 34, 34,208,190,125,251,130,107,158, 62,125, +138,199,143, 31,195,211,211,179,108, 11, 30,163,135,167, 79,101, 8,133, 66, 8, 4, 2, 8, 5,185,191,185, 91,174,229, 74, 40, + 16, 66,192, 23, 64, 34,149,148,219,130, 5, 0,114,185, 60, 63, 95,112,149, 43, 87, 78, 72, 72, 72,112, 6,192,203,119,192,106, + 76, 99, 37,191,142,200, 23, 87, 2,145,176,192,146, 5, 0, 25, 25, 25,234,174, 93,187,238,209,104, 52, 67,241, 17, 43,138,152, +240,159,196,131,255,209,189,127,137,192,106,223,168, 81,163,141,253,250,245,107,189,106,213, 42,200,229,114, 36, 36, 36, 20, 84, +132, 34,145, 8, 21, 42, 84, 64, 90, 90, 26, 54,109,218,132,216,216,216,171, 0, 70, 26,251,224,132,132,132,187,111,158,132,165, +182,236,217,200, 54,160,145,143, 85, 76, 88,108, 3, 0,183,243,196,213,182,126,147,218, 15,109,217,189, 30,132, 34, 1, 98,222, +188,255,127,139, 16, 30,143,199, 35,132,160, 79,159, 62, 70, 93,223,183,111, 95,220,184,113, 3,165,117, 39,114,249, 22,172, 28, + 53,148,170,207,215, 56,235, 63,172, 15,250, 15,235, 83, 32, 34,140,233, 98, 1,128,189,199,119,150, 92,128, 27,116,203,206, 28, +222, 53,162,102,237,250,246, 13,106,122,225,205,219, 88,252, 52,227,155,130,243, 83, 70,245,195,142, 3, 39,225,234,100, 7,101, + 86, 6, 14, 31,216,151,169,209,104,150,125,164, 17, 46, 87,212, 18, 2, 35,253, 75,126, 96, 53,205, 23, 88,213,170, 85, 43,209, +130,149,150,150,166, 42,171, 66, 40, 72, 35,173, 30,217, 74, 21, 84, 57,159, 71, 96, 17, 66, 2,155, 52,105,114,233,208,161, 67, +182, 14, 14, 14,136,143,143,255, 64, 96, 17, 66, 2, 27, 55,110,124,233,208,161, 67,182,142,142,142,136,137,137, 49,218, 61, 72, + 49,226, 10,201,201,201, 36, 61, 61,157,179,182,182, 46,151,200, 98, 24, 6, 26,141, 6, 47, 95,190, 52,246,177, 70,207,248,178, +180,180,220,177,127,255,126,203,148,148, 20,240,120, 60,188,124,249,242,131, 89,132,249,219,182,109,219,132,221,186,117,219, 10, +160,102,105,124, 6,131, 97,197,192,129, 3,135,199,197,197, 89, 59, 56, 56, 32, 33, 33, 1, 34,145, 8,148, 82,144,150, 45,209, +244,237, 91,232, 88, 22, 82,169, 20,161,161,161,216,188,121,179, 82,163,209,172, 40, 33,125, 68,102,102,102, 94, 66,161, 16, 3, + 6, 12,248,224,220,206,157, 59,209,185, 14,175,206,136,182,226,108, 3, 36,154, 68,233, 87,231,120, 60, 30, 25, 57,229, 39,239, +250,205, 58, 84,123, 29,124, 47, 60, 57, 49,246, 86, 25,175,175,215,106,181,240,245,245,197,131, 7, 15,112,249,242,101,180,106, +213, 10,205,155, 55,199,179,103,207,112,241,226, 69, 60,126,252, 24,132, 16,216,218,218,230, 15,179, 40,117,172,133, 54,199,128, +164,248,212, 63, 89,171,138,238, 11,133, 66,104, 84, 58,163,210,232,213,171, 87,120,240, 32,183,254,201,201,201, 1,159,207, 55, + 76,153, 50, 5, 12,195,208,224,224, 96, 56, 56, 56,208,169, 83,167,178,124, 62,223, 16, 29, 29,109,108,222,207,237, 22,204, 19, + 87, 60,129,224, 3, 97,198,113, 92,214,211,167, 79, 71, 16, 66,158, 17, 66,242,203, 15,147, 31, 44, 19,254, 85,224,151,210, 10, +121, 11,160, 13, 33,164,255,241,227,199, 87,172, 89,179,198,190, 99,199,142, 72, 79, 79, 71,197,138, 21,225,236,236,140,211,167, + 79,227,236,217,179, 41, 44,203, 78,166,148,238, 46,230, 35,107, 83,146,175, 12, 74, 41,117,113,113, 57,164,201,206,254,182,118, +115, 63, 92, 61,248,219, 18,103,103,231,145,174,174,174, 19,134,204,232, 50,180, 69,215,186, 8,125,252, 14,119, 47, 62, 71, 98, +116, 10,134, 52,157, 90, 42,103,209, 65,238, 86, 86, 86,195,205,204,204, 68, 0,116,197,180,130, 63,152, 69, 88,152,147,101, 89, + 86,171,213,226,192,129, 3, 70,137,172,125,251,246, 65,173, 86,131, 45,210,143, 90,152,147,114,148,240, 5, 98,184, 84,240,133, + 78,167, 4,199,125,156,181,166, 48, 39, 33, 4, 12,195, 32, 92, 36,130,205,251,247,184,118,205, 56,135,234,253,250,245, 43, 53, +141, 40,165, 89,132,144,129,107,127,154,115,120,220,180,121,230,173, 26,213,192,175, 7,207, 65,175,211, 65, 44, 22,192,218, 66, +134,170,149,221,160, 82, 42,176,104,222, 44, 69, 78,142,114, 96,209,177,103,127,226, 44,173, 39,133, 2, 44,199,225,242,205,251, + 70,191,123, 65, 45,207,178,224,243,249,120,243,230,141,170,184,217,131, 60, 30, 15, 2,129, 0, 12,195, 20,219,234,254, 48,141, + 56, 34, 16, 74, 80,161,162, 63,180,154,236,207,146, 70, 14, 14, 14,223, 31, 59,118,204, 54,223,229,193,179,103,207, 64, 8,121, + 89,200, 26,242,253,177, 99,199,108, 85, 42, 21,130,131,131,243,151,132,122, 89,158,239, 40,223,114,149,156,156, 76, 18, 18, 18, + 96,102,102,198, 60,123,246, 76, 83,163, 70,141,135, 40,125,165,134, 2, 78,181, 90, 29, 89,210,248, 72,181, 90,237, 42,145, 72, + 4, 69,238,117,241,242,242, 10, 45,218, 85, 88, 92, 56, 51, 51, 51,239, 77,155, 54,173,246,151, 95,126,137,239,191,255, 62,205, +218,218,218,124,195,134, 13,124, 30,143, 71,198,140, 25,195, 38, 37, 37,101,111,217,178,197,242,248,241,227,200,200,200,184, 93, +214,187,231,229,207, 17,141, 26, 53,218,121,254,252,121, 51, 47, 47, 47, 40, 20, 10, 80, 74,177, 99,199, 14,140, 25, 51, 6, 18, +137, 4,161,161,161,232,220,185,115, 78, 78, 78,206,136, 82,242, 39, 33,132, 80,142,227, 48,123,246,236, 2,167,162,249, 78, 70, +205,165, 4,155, 39, 85,145,141,223,146, 41,235,255,195,150, 65, 0,192, 26, 12,236,235,224,123,225, 59,214,254,112, 77, 40, 20, +222, 44, 35,141,102,142, 31, 63,126, 67,135, 14, 29,164,114,185, 28,105,105,105,184,117,235, 22,238,220,185,131,187,119,239, 66, +171,213,194,214,214, 22,214,214,214, 72, 72, 72,192,171, 87,175, 84, 0,102,150,198, 41, 50, 19,192,195,187,114,238,108,193, 60, +139,149,160,208,236,193,194,214, 44,161, 64, 96,212,119,212,172, 89, 51,212,175, 95, 63, 95,248,176, 81, 81, 81, 9, 26,141,134, + 20, 18,251,113,249, 66,220,221,221,221,176,109,219, 54, 90, 26,103,216,214,117,120,184,112,102,110,183,224,243,152, 2,177,117, +173,109, 45,240,133, 66, 84,232,216,163,112, 61,176,158, 16,178, 61,239,191,198,152, 60,255, 9, 13, 30, 19,231,223,156,243, 63, + 35,176, 10,125, 0,123, 9, 33,231,190,249,230,155,165,129,129,129,223,172, 92,185,146, 8,133, 66,204,157, 59,151,198,199,199, +255,154,215,234, 72,255,152,135, 83, 74,127,189,126,244,246,232,193, 65, 93,201,164, 85, 67,154, 60,188, 18,252,170,122, 35, 47, + 84,111,228,133,135, 87, 67,176,118,198,190,221,172,158,157,157,144,144, 80, 86,179, 73,211,166,177, 79,209, 65,238,182, 55,174, + 93,177, 45,239, 44, 66,142,227, 14,237,219,183,111, 92,247,238,221,153,251,247,239,255,105,204, 85,190, 51, 62,142,227,112,233, +210, 37,232,116, 58,252,250,235,175, 28,199,113, 37,251,193, 2, 61,177,122,213,210,193,191,238, 58, 33, 18, 9, 9,238,220, 60, +130,204,244,210,173,114, 66,161, 0,219,118, 28,213, 9,133,130,215,197,157,215,233,116, 49, 87,174, 92,113,108,199,178, 2,134, + 97,254, 36,156, 74,194,161, 67,135,244, 28,199, 69,149,145, 46,151, 8, 33,125,231, 5,125,183,163,107,207, 65, 86, 53,106,213, +226,187, 56, 87, 0,159, 97,144,146,244, 30, 55,174, 94, 48, 28,220,187, 43, 67,163, 81, 15,161,148, 94, 42,235,153,195,150, 95, + 47, 24,115, 5, 0, 29,199,172, 41, 24,127, 5, 0,157,134, 76, 67,203, 6, 1, 32,198,152,154,254, 16, 87,156,193, 96,128, 76, + 38,131,193, 96, 40,214, 85,131,165,165,165, 84,173, 86,171, 40,165, 96, 89,182, 84,211, 16, 5, 62,123, 26,177, 44,235,151,158, +158, 14,165, 82,137, 59,119,238,208, 69,139, 22, 37, 39, 39, 39, 23, 12,198,212,235,245,126,105,105,105,200,206,206,198,237,219, +183,233,210,165, 75,147, 83, 83, 83,103,148,231, 27,146, 74,165,117,248,124,254,195,244,244,116,206,204,204,140,209,235,245,250, + 26, 53,106,136,165, 82,169,209, 11,157,199,199,199,127, 89,210, 57, 79, 79,207,176,176,176,176,170, 44,203, 22, 94,163, 80,168, + 86,171,189, 26, 53,106,100, 76,215,206,248,237,219,183,227,232,209,163,245, 20, 10,197,192,168,168,168,157, 0,234,241,249,124, + 60,121,242,228,165, 90,173,238,215,189,123,247, 29,233,233,233,247, 0,140, 55,178,220, 56, 79, 8, 25,224,231,231,183,125,222, +188,121,242,230,205,155,243, 93, 92, 92, 80,183,110, 93,132,134,134,226,204,153, 51,250,245,235,215, 43,115,114,114,134,149,145, + 63, 41, 0, 98, 48, 24, 32, 18,137, 10, 54,177, 88, 12,161, 80,136, 44, 21,197,215, 63, 71,168, 12,144,170, 86,204, 29,113,134, + 2,228,125, 76, 68, 74,210,251,152,123,132,144,155,241,241,241,153, 37,196,153, 72,173, 86,215,116,118,118,230, 17, 66, 86,233, +116,186, 33, 99,199,142,117, 94,188,120, 49,124,124,124,144,146,146, 2,153, 76, 6, 47, 47, 47, 36, 39, 39,227,254,253,251,108, + 78, 78,206, 70, 0,243, 41,165,165,118, 59,102,164, 40,224,230,228,254,129,165,147, 82, 10,202, 2,122, 13, 11, 86, 71,161, 37, +122, 8, 4,122, 8,133, 66, 99, 42, 73,202,113, 28,210,157,157, 17,119,225, 2,242, 86,149, 40,209,138,118,250,244,233,178, 19, +136,227, 32, 16,139,192, 23,254,209, 45,152,107,205,202, 61,198,144, 63,165,167,201,106,101,194,127, 83, 96,229,125, 0, 25, 0, + 70, 18, 66,118,182,104,209,226, 52,165, 84, 0,160, 3,165,244,183, 79,121,120, 66, 66,194, 35, 23, 23,151,233,142,110,214, 75, +191, 26,216, 4, 62, 53, 43,130, 53,176,184,117,246, 9,126, 93,124,124,127, 92, 76,220, 16, 99,214, 38,227, 56,238, 90,227, 58, + 62, 12, 10,249,214,118,113,113,225, 62,102, 22, 97,102,102,230,156,201,147, 39,227,251,239,191, 47,247, 44,194,146,174,121,246, + 50,105,100,160,159,189, 91,167,175,154,182, 3, 97,168, 86,171, 41,165,192, 67,129,199, 81,161, 80,240,250,254,211,248, 26,197, + 93,151,156,156,220,110,232,208,161,151,248,124,126,229,242,196, 57,199,113, 81,137,137,137,173,141, 72,243,115,132, 16,239, 19, +135,119, 76, 63,123,114,127, 11,189, 86,235, 9, 2,136, 69,226,112,189, 94,119, 93,173, 86, 47, 49, 86, 88, 47, 27,217, 16,227, + 87, 95,196,186,239, 59, 97,236,210,131,216, 58,251,107, 76,255,121, 31,126,250,126, 60, 22,173,217,131, 31,198, 15, 64,207,254, + 67, 57, 74,152,223,141,125, 15, 30,143,119,126,211,166, 77,131,191,254,250,235,130,201, 8,148,210, 15, 10,116,189, 94,175,226, + 56, 14, 27, 55,110,228, 0,156, 47,141,239,195, 52, 34,180,180,241, 80,198,166,145, 66,161, 24,214,176, 97,195, 29, 0,196,148, +210, 55,233,233,233,163, 40,165, 5, 75, 56,101,103,103, 15,107,212,168,209, 14, 74,169,152, 16,242,167,243,198, 32,207,101, 67, + 29,107,107,235,135,121,150, 43,241,199, 12,116, 47, 45,170, 75,233, 62,100,141,200, 71, 28, 10, 45,127, 67, 8, 89, 92,175, 94, +189,194,139, 61,191, 4, 80,167,188,129,202,107, 4, 4,204,158, 61,123,162, 68, 34,105,153,147,147,227, 13, 0, 50,153, 44, 84, +163,209, 92, 83,169, 84, 43,243,202,173,210, 56,180,102,102,102,161, 6,131,161,154,189,189, 61,248,124,126,129,200, 2,128,147, + 15,217,135,148, 26,234,150, 55,108,103,207,158,173,100,109,109,253, 5, 33,164, 39,165,212, 55, 43, 43, 75, 51,123,246,236,219, +135, 14, 29,202,172, 92,185,242, 87, 29, 58,116, 32, 54, 54, 54,120,240,224, 1, 77, 77, 77, 61, 2, 96,134, 49, 51,167, 57,142, +139, 90,182,108, 25,202,251,189,151,118, 94,167,211,189, 63,123,246,172,221,151, 73, 73,124, 27,142,195,153, 51,103, 62, 16,110, + 69,241,250,245,107,104, 52,154, 82,157, 48,234, 50,211, 81, 99,252, 52,208,188,217,156,249,112,239,208, 3, 4, 20, 84,107,210, + 83, 38,252, 55, 64,254,146,105,204,229, 52, 33,186,184,184,244,145,200,196,223, 85,244,118,174, 17, 31,145, 20,146,149,153,179, + 59, 33, 33, 97, 19,165,148,253, 88,206,242, 56, 26, 53,153,121,255, 58,206, 63,252, 96,177,160,148, 5,229, 40, 40,229,192,113, +108,238, 66,212,148, 3,101, 89, 66, 8,126,215,228,100,126,109,108, 56, 9, 33,214,118,118,118,243, 41,165, 95,242,120, 60,166, +176,241,171,240,255, 60,203,213,249,228,228,228, 31,138, 10,194,127, 98,124, 30, 62,124,184, 88,209,111,236, 44,194,158, 61,123, +178,229,252, 54,175,201,100,178, 98, 29,106, 42,149,202,232,248,248,248, 47,254, 14,241,153,111,253,164, 70, 20,104, 69,186,218, +203, 61,139,176, 44,206, 74,149, 42,137,117, 58, 93, 45, 0, 94,132, 16, 43, 0,105, 58,157,238, 66,114,114,114, 34, 33,164, 14, +128,217,121,183, 45,160,148, 62,252, 95,126,239,132, 16,169,157,157,221,118,134, 97,220,140,185,223, 96, 48,104,211,210,210, 6, + 23,110, 8, 20,230,180,179,179,123,200,231,243,221,140,224,137, 77, 73, 73,169, 99, 42, 63, 77,156,255,121, 11,214, 95,141,248, +248,248, 3, 0, 14,124, 78,206,146, 60,181,155,240,255, 11,101, 90,194, 95,146, 14,121, 98,105,204,127, 45, 62,243, 5, 82, 49, +199, 31,161,200, 90,160,159,233,219,108,249, 79,136, 23,250,145, 45,197, 60, 1,213,244,115,134, 37, 50, 50, 82, 3,224,118,222, + 86,244,121, 15, 1,116,250, 27,197,155, 10, 64,159,207,197, 87,154,104, 50,193,132,255, 26, 24, 83, 20,152, 96,130, 9, 38,152, + 96,130, 9, 38,124, 94, 16, 0,109, 74,104,217, 24,109,250, 35,132,180,249,136,150,211,101, 19,167,137,211,196,105,226, 52,113, +154, 56, 77,156,255, 45,206,255, 12,242, 29, 62,254, 21, 27,128, 54, 38, 78, 19,167,137,211,196,105,226, 52,113,154, 56, 77,156, +255,181,205,212, 69,104,130, 9, 38,152, 96,130, 9, 38,152,240,153, 97,180,192,146, 59,249,249,217, 87, 10,220, 97, 83,161,198, + 51,155, 10, 53,158,217, 87, 10,220, 33,119,242,243,251, 47, 70, 26, 33, 68, 74, 8,233, 47, 16, 8, 46, 57, 59, 59, 43, 8, 33, + 19, 77, 89,169,252,104, 65, 8,191, 47, 33,223, 13, 38, 36,122, 48, 33,209,125, 9,249,174, 5, 33,255,186,101, 51,230,141,119, +105,248,219,249, 1,231,230,141,119,105, 88,236,249, 41, 46,182,247, 46,245, 94,189,100,140,171,205,103,202,159,230,142,142,142, +155,157,156,156, 34, 29, 29, 29,163, 28, 29, 29,183, 19, 66, 44, 77, 57,206, 4, 19, 76, 48,225,255, 15,252,188, 2,185, 57,128, +235, 0, 90, 80, 74,111, 20,189,200,166, 98,245,175,253,124,125,190, 95, 56,119, 6,113,114,176, 51, 51,176,156,238, 93,100,140, +255,156,133, 75, 15,219, 84,172,190, 34, 45,234,249,214,143,168, 4, 8,143,199,235, 35, 22,139, 59, 2,200, 23,106, 47, 53, 26, +205,105,150,101, 15, 24, 59, 43,200,201,201,233, 38,143,199,171, 84,158,103,179, 44, 27,253,254,253,251, 38, 31, 89,121,245,114, +119,119,223,222,188,121,115,179,122,245,234, 65, 36, 18, 97,246,236,217,147, 1,172, 52,150,195,198,198,211, 92, 39,150, 76,224, +139, 68,109,169, 94, 91,141,130, 2,140, 56,152, 51,104,174, 8, 53,154, 21,105,105,225, 89, 70,134,101, 6,128, 33,200,157, 86, +190,149, 82,186,236,175,200, 36,132,144, 10, 0, 90, 2,240, 5,240, 28,192, 69, 74,105,234,167,242, 58, 2, 35, 27, 53,105,178, +122,240,228,201, 60,213,205,155, 88,189,125,251, 42, 40, 20, 0,176,174,188,121, 73, 40, 68, 79, 59, 59, 65, 71, 74, 81,139, 0, +132, 0, 79,146, 83,185,179, 58, 29,123,128,150,119, 29,158, 15,185,251,227,195,105,245,123,203,203,145, 25, 78,103,137, 59,249, + 53,205, 12,191, 54, 11,192, 87, 69,207, 27,212,146,193,148, 87,161,163,138, 62,142, 1,240,243, 39,166,149,153,189,189,253,179, + 19, 39, 78,184,213,171, 87,143, 15, 0, 15, 31, 62, 28,212,177, 99,199, 86,132,144,106,148, 82,197,255,168, 81, 34,225, 51,204, +119, 34,129,160, 45,203,178,213, 1,128,199,227, 61,215,234,245,151, 12, 28,183,142, 82,170, 54, 21,199, 38,152,240,223, 70, 89, + 90,228, 31, 41,176, 0, 92,167,148, 18, 66, 8, 69,145,169,222,114, 71, 95,255,128, 0,191,201,231,143,237,172,144,145,150,161, +254,101,249,206, 71, 74,190, 40,199,203,223, 75,248,203,202,101,214,223,141,159, 52, 65,238,232,123, 47, 59,241, 85, 72, 57, 34, +209, 93, 42,149, 30, 93,190,124,121,181,150, 45, 91, 10, 28, 28, 28,144,152,152,136,151, 47, 95, 86,187,122,245,106,215,157, 59, +119, 78, 38,132,116,167,148, 26,179,240,149,215,197,157,219, 29,228, 54,182, 96,245,122,184, 5,214, 42,112,144,247,250,202, 69, + 24,244, 58,176,122, 61,170,119,236, 10, 0,224, 56, 14,254,254,254,188,143, 76,124,151,128,128,128,221,139, 23, 47, 22,106, 52, + 26,220,187,119, 15,215,174, 93,227, 18, 18, 18,150, 26,203, 33,119,244,110,201, 72,101, 7,250, 12,248,198,178, 75,199, 42, 2, +119, 71,123, 0,102,120,253,206,208,232,220,197,171,117,143, 29,248,245, 91,185,163,119,159,236,196,208,107,165,139, 52,155, 6, +132,144, 69,249, 30,157, 9, 33, 63, 85,174, 92,249,135,194,215, 20, 93,215,142, 82, 10, 62,159,159,152,149,149,213, 39, 37, 37, +229,113,113,188, 67,106, 17,189,158,205,205, 23, 66, 62,216,221,207,120,199, 58,116,232, 80,121,236,216,177,104,216,176, 33,238, +223,191,223,114,251,246,237,227,249,124,254, 3,150,101,207,230,229,157,143,242, 28, 40, 4,166, 14,158, 60,153, 39,143,140,132, +252,233, 83, 12, 80, 40,248, 63, 2, 83,203, 35,176, 8, 33, 85,156,156, 4,135, 39, 79, 26,234,231,225,217, 64, 40, 20,218,229, + 46,174,173, 77,241,142,142,126,220,115,233,143,155,131, 8, 33, 61, 40,165,111,140,228,227, 3,152, 7, 64, 2, 96, 22,128,217, +201,201,201, 94, 44,203,194,201,201,105, 54, 33,228, 56,128,133,246,246,246, 52, 57, 57,121, 26,165,212, 80,154,229, 74, 17, 78, +103,189, 39, 30, 95,250,212, 30,140,247,228,252,151,147,190,114, 62,103,225, 73, 22,206, 89, 29,127, 7, 0,190,242,244, 52,247, +240,149, 77,147, 91, 84,183, 81,196, 93,158,246,149,167,231,150,115,225,198, 9,236,162, 34, 19, 0, 92, 92, 92,150,237,218,181, +171, 66,253,250,245, 11,242,120,205,154, 53,121,203,150, 45,115,157, 56,113,226, 42, 0, 67,141,228,243,182,183,183,191,192,178, +172, 38, 53, 53,213, 59,255,184, 67, 96,247, 70,182,230,178,214,201,233, 89, 55, 83, 94, 28,191, 97, 36, 87, 61,137, 80,120,228, +212,238,213,206, 53,235, 55,100,100,118, 14,208,197,197, 35, 75,175,107,115,229,214,221, 22, 35,190,155, 58, 62, 47,141,238,155, +170, 24, 19, 76,248, 79,163, 68, 45,242, 79, 22, 88,200,123,161, 63, 65, 44, 22, 5,205,153, 57,141,100,164,102,168,212,138, 44, +173, 94,173, 86, 51, 66,170,126, 30,242, 54,137,225,243, 50, 38,142, 31,103, 30, 52,125,102, 16,128, 1,198,138,171,192,192,192, +251, 71,143, 30,117,176,177,177, 65,102,102, 38, 82, 83, 83,113,255,254,125, 80, 74,209,189,123,119,113,253,186,117,107,205,154, + 61,251, 14, 33,164,161, 49, 34, 75,110,107,135, 5,141,114,215,136, 93, 26,157,154,255, 28,252,210,179, 99,193, 53,203,243, 86, +181,144, 72, 36, 5, 11, 5,127, 4, 26,182,110,221, 90, 8, 0,195,135, 15, 87,100,101,101, 45, 1,176,151, 82, 26,103,172,184, +178,115,118, 57,189, 97,227, 50,105,117, 79, 47,232,244, 6, 68,189,143, 7, 95, 96, 5, 55, 55, 33,134, 14,104, 43,104,214,200, +198,110,209,130,205,103,100,246,222,221,148,201,161, 23, 74,226,178,178,178,218,121,224,192, 1, 28, 60,120, 16, 0, 16, 26, 26, + 10, 47, 47, 47, 89, 89, 97, 8, 14, 14,246,232,220,185,243,126, 0, 85,139, 59,175,103,193,223,187, 55,215, 72,243,243,148,254, + 60,133, 66, 81,217,204,204,172,224,124,171, 86,173,208,170, 85, 43,102,253,250,245,245, 47, 92,184, 80,127,235,214,173, 58, 66, +200, 42, 74,233,161,143,137, 80,213,205,155,144, 63,125, 10,220, 40,127, 99,133, 16, 82,165,118,237,138,119,207,158,217,109,119, +230,236, 75,252,252,243,118,132,135,135, 3, 0, 60, 60, 60,208,191, 95, 47,193,243,231,183, 3,122,246,236,127,155, 16,210,132, + 82, 26,106, 4,237,188, 45, 91,182,204,168, 92,185, 50,122,246,236,217, 43, 32, 32,192,201,194,194, 2,155, 54,109,130,179,179, +179,135, 86,171,125,115,226,196, 9,151,247,239,223, 99,220,184,113, 0, 48,185, 36,162, 22,237, 90,204, 18,119,242,107,234, 83, +123, 48,228, 22,206,216,178,239, 0, 94, 63,218,217, 84,163,123, 57,107,201, 24,215,129, 42, 42, 30,226,230,101, 30, 84,169, 78, +115,219,170, 1,157, 81,177,246, 99, 59, 53,251,219,219,217,223,121, 44,229, 75,212, 59,231, 44,143,255,147,149,144,244, 58,204, +171,166,120,101, 19,124, 9,169,148,206,225,242,132, 85, 65, 65,196, 82,116,110,214,172, 89,129,184,138,140,140,132, 70,163,129, +159,159, 31,163,213,106, 91, 26, 25,175,222, 95,124,241,197,239,103,207,158,181,245,246,246,254, 96,233, 22, 39, 91,171,118, 55, +142,174, 26,183,104,245, 30, 95, 7,255,110, 25, 73, 33,199,158,151, 37,174, 26, 55,168,125,249,252,209,221,114, 94,118, 12,248, + 86, 41, 0,151,138,132, 3,219, 64,204,108,208,119,212, 36,126,203,214,173, 92,219,126,213,227, 50, 33,164, 53,165,244,129,169, +142, 49,193,132,255,180, 21,139,254, 91,222,133, 95,200,186, 65,138,123, 49,142,114, 53, 28, 29,108,165,171,150,239,120,192,211, +105,181, 50, 43, 75,173,192,210,130, 35,230,150, 60,157, 86,159, 93,209,163,162,136,163, 92,141,226,200,139, 78,213, 36,132, 16, +169, 84,122,244,228,201,147, 14, 2,129, 0, 28,199,193,222,222, 30,239,222,189, 67, 70, 70, 6,178,178,178, 16,254,242, 37, 42, +187, 87,192,220,160,105,206,227,166, 5, 29, 37,132,212, 41,220, 93, 88,220,244, 79, 86,167, 43,154, 64, 37, 45,238,251,193,111, +105,156, 37,224, 93,116,116, 52,228,114, 57,170, 85,171, 38,191,117,235,214,111, 37,137,171,162,156, 54, 54,158,230,124,185,244, +224,250, 13,179,165, 58,125, 48, 66, 34,210,224, 83,185, 41, 28,109,221, 17,159,166,197,221,251, 39, 17,252,108, 47, 60, 93,221, + 49,102,116, 43,201,210,101,135, 15, 88, 91, 87,113, 79, 79,127,171, 40,142, 83,161, 80,200,171, 84,169, 2,119,247,220,117,201, + 88,150, 69, 72, 72, 8, 88,150, 45,216, 47,252,187,227,200, 85, 24, 20, 81, 24, 60,104, 16, 82, 83, 83,229,198,190,123,190,184, +218,212,223, 37, 64,153,158, 32, 4, 0,153,181,179,110,196,158,184, 23,141, 27, 55,134,171,171,171,240,202,149, 43,147, 0, 28, + 42,111,124,234,128,159, 86,255,250,235,154, 1,153,153, 12, 0,108, 37,132,211, 81,250,147,177,121,201,193, 65,112,228,252,185, + 93,118, 60,230, 21,108, 44,127,196,253,251, 81,208,233,114,179, 74,106,106, 18,198,126,167,128, 80, 96,142, 19, 39,246,216,250, +249, 53, 57,146,215, 69,198,149, 17, 78,201,185,115,231, 48,118,236, 88,132,132,132,184,240,120, 60,220,187,119, 15, 82,169, 20, +203,151, 47,231,249,249,249,185,200,100, 50,156, 63,127, 30,137,137,137,164,180,112, 94,191,112,125, 97,102,248,181, 89,239,201, +249, 47,183,236, 59,128,111,250,245,129, 19,141,248,205,210,147, 44,252,162, 83,227, 31, 40,175, 66, 71,153,121, 13,107,175,106, +157, 32, 20,201, 49,102,234,124,132, 6,159,178,206,201,122,246, 29, 97, 99, 42, 32,111,109,190, 15, 22, 59, 62,212,147, 93,179, +239,118,237, 75,238, 15, 42,186,212, 30,121, 15,192,179, 63, 4,150, 7,159, 48,172,101,190,181,242,205,155, 55, 8, 15, 15, 7, +159,207,135, 74,165,130,193, 96, 40, 54,156,174,174,174, 35, 13, 6,195, 15, 0,160,211,233,118, 56, 59, 59, 15,219,189,123,183, +109,225,149,162,242, 45, 87,105, 25,138,244,219, 15, 94,188,158, 52,178,103,139,155,119,131, 99,172, 2,187, 70,103, 60, 61,158, + 89, 66, 26, 73,164, 34,209,145,243,199,246,200,185,183, 87, 33,246,107, 1,190,220, 11,172, 62, 14,234,116, 37,212,111, 19,160, +221,180, 22, 30,163, 39,226,212,241,195,242,128,234,117, 14, 17, 66,188, 40,165,218,143,248, 54,141,134,137,211,196,105,226,252, +123,114,150,166, 69, 0,212, 6,224,152,247, 63, 21,185, 67, 99,236, 0,164, 32,119,217, 46, 71, 0, 90, 0,162, 66,247, 20,221, + 47,124,109,209,253,194,255, 83,243,254, 59,228,253, 62, 0,144, 86,222,119, 41,211,148, 67, 8,163, 96, 89, 78, 39,180,119, 80, +143,152, 60, 44,192,209,189, 2, 83,193,163, 2,255,155,222, 45,154,123, 84,114,148, 18,134,232, 9, 97,140, 26,215,193,227,241, +250,172, 90,181,170,186,133,133, 5,196, 98, 49, 44, 45, 45,145,149,149, 5,173, 86,139,204,204, 76,168, 50, 51,160,206, 72,195, +211,223,111, 66,202, 16,244,248,242, 11, 63, 30,143, 87,166,151, 97,183,192, 90, 88, 26,157,138,165,209,169, 8,114,183,197,180, + 10, 54,152,234,102,141,101,113, 25, 88, 30,159,137,159, 19, 20,152, 95,203, 27, 63, 54,173,141, 7, 7,247,124, 74,194, 63, 62, +115,230,204,185,248,248,120, 76,153, 50,133,169, 92,185,242,121, 66,136,191, 81, 98, 66, 44,153, 48, 98, 66, 71,107,107, 57,197, +205,135, 39,161,214,100,194, 76,196,131, 90,203,129, 16,224,229,139,163, 32,196, 6,207, 66, 19,160,211,102,225,139,118,126,114, + 86,108, 54,165,180,164, 73, 79, 79, 71,120,120, 56, 66, 67, 67,241,242,229, 75,248, 7, 4,224,249,243,231,184,123,247, 46,110, +220,184,129,203,151, 47,227,242,229,203,184,126,253, 58, 46,157, 62,132, 29,191,254,138,136,136, 8,148,102,122, 21,240, 96,248, +121, 74,127,252, 60,165, 63, 68,230,246,186,172,172, 44,112, 28, 7,101,122,130,112,242,242,189,152,188,124, 47,148,233, 9,194, +107,215,174, 97,207,158, 61,136,140,140,252, 64,168,151, 7,225,192,230,171, 44,155,156,126,236, 24, 61, 53, 96, 0,123, 87, 46, +143, 73, 4, 54, 25,115,175, 80,136,158,203,126, 26,237, 35,147,201,144,154,178, 10,190,190, 66, 76,158,104, 91,112,126,220, 88, + 55,212,173, 99, 7, 69,198, 97,136,132, 6,172, 89, 51,222,211,204,140, 55,200, 8,234, 89, 39, 79,158,140,189,116,233, 18,221, +187,119, 47, 14, 30, 60,136,240,240,112, 72,165, 82, 72, 36, 18, 36, 37, 37, 33, 56, 56,152, 46, 91,182, 44, 22,185, 93,136, 37, + 98,206,234,248, 59, 43,207, 37,124,229, 76, 35,206,191,126,180, 51,199,149,247,246, 86,239, 9, 77, 34, 29,172, 37, 89, 23, 47, +221, 90,112,238,216,241,117,155, 22, 44, 75, 91,183,108, 14,116,218,108,172, 93, 54, 7,191,204, 91,145,118,238,216,241,117,215, + 79,221,158, 95,172, 85,172,197, 60,190,179,163,141, 97,228,144, 30, 86, 95,125,213, 98,164, 83,189,145,243, 80,185,150, 12, 0, + 35,174, 90,107,160,119,181,250,218,171, 87,175, 66,167,211, 65,173, 86,231,127,119,216,189,123, 55,103, 48, 24,138,237,118,214, +233,116, 63,196,196,196, 56,135,134,134, 58,123,121,121,141, 59,116,232,144, 99,254, 26,114, 44,203, 22, 88,174,110,159, 94, 55, +105, 64,247,182,245, 39,252,176,238,154, 74,173,209, 46, 12, 26,214, 66,192,162, 65,137,173, 55,134,249,238,212,177,237, 78, 18, +107, 61,100,117,191,128, 33,219,128,136,101,223, 32,116, 94, 16,188, 23,204, 67,224,218,245,168, 48,228, 27,156,233,210, 19,193, + 11, 23,226,199,111,134,185, 48, 12, 51,218,212,134, 55,193, 4, 19,138,129, 35, 33,228, 52, 33,228,244,244,233,211, 91, 0,176, + 35,132,156,206, 19, 89,142,121,255, 69,249,215,148,176,111, 87,152,167,200,189,133,255,219, 78,159, 62,189, 53, 33,228,116,163, + 70,141, 6, 2,248,168, 9, 72,252,124,197, 88,248,247, 3, 11, 22,199,221,124,243, 54,178,253, 23,109,234,187,157,190,241,252, +193,200,161, 29,218, 49, 12, 67,158,132, 68,221,240,172,232,100,119,237,250, 77,202,113,220, 77, 99, 30, 38, 22,139, 59,182,106, +213,138,159,158,158, 14, 23, 23, 23, 36, 39, 39, 35, 46, 46, 14,122,189, 30,234,204, 12,104,179, 20,208, 42, 50,193, 42,179, 16, +254,240, 62,106,120,122,136,143,228, 14,130,223, 95,134,240, 41,214, 50, 85,216,146, 37,150,155, 67,108, 46, 7, 41,103,247, 32, + 33,164,139,149,149,213,180,140,140,140,179,148,210,133, 58,157,238,187,105,211,166, 61, 88,179,102,141,221,162, 69,139, 44, 70, +140, 24,113,136, 16, 82,179,172,113, 72,230,246,188,142, 13,107, 86, 99, 94,189,123,134, 38,129,131,225, 93,165, 45,222, 37,170, +144,174,212, 35, 45, 75,143,186,205,126, 65, 82,166, 22, 10,165, 6, 47,163, 86,194,197,213,139, 1,255,109,107,252, 49,192,250, + 79, 72, 76, 76,252,224,157,247,239,219,135,156,204, 76,120,122,122,194,207,207, 15,246,246,246,136,138,138,194,239,191,255,142, + 1,189, 59, 67, 32,232,129,164,164,164, 82,223,119,199, 99, 42, 32,132, 60,162,148,226,241,227,199, 8, 15, 15,135, 68, 34,249, +211,117, 87,174, 92,201,173,120,157,156,140,255, 58, 28, 29,167, 51, 12,211,155,227, 56,158, 66,161,136,209, 18, 82,213,191, 98, + 69,199,198, 93,187, 34, 83, 32,224,173,190,114,133, 36,102,101,201, 1,100,148,197,101,103, 35,232,208,178,213, 87,162,140,244, +237, 0,114,141, 82,195,134,218,227,171, 47, 29, 65, 24, 49, 92,156,205, 65, 24, 49, 8, 17, 33, 71,121, 21,245,235, 53, 20, 90, + 89,173,236, 8, 96, 71, 41,105,221, 31,192,236,198,141, 27,187,140, 25, 51,134, 28, 63,126, 28, 99,199,142,213, 1,136, 4,128, +239,190,251,206, 99,252,248,241,188,236,236,108, 82,161, 66, 5,231,183,111,223, 62, 33,132,148, 57,240,221,194,147, 44,212,232, + 94,206,178,242,146, 37,179,176,107,148,173, 23,167,206, 89, 30, 49, 7,192,207, 95,121,122,110,209,113, 55,223,134, 5,159,178, +126,247,224,122, 90,124,152,210, 99,203,153,136, 18,199, 96,221,184, 1,206,177,198, 13, 93,231, 47,155,243,187,118,106,153,227, +234,230,232,253,203, 58,237,238, 52, 87,219,133,149,220,221, 6,204, 89, 60, 77, 55,176, 91, 83,221,180,201, 99, 5, 1,254,126, + 68,161, 80,224,192,129, 3,134,115,231,206, 37,112, 28, 55,161,164,182, 15, 0,232,245,122,140, 28, 57, 82,102, 97, 97,129,152, +152, 24,248,250,250, 22, 8,172,132,228,212,231,183, 30, 4,191,154, 52,170, 87,243,189, 39,175,189,188,112,253,225,203,174, 95, + 54, 14, 36,132,150, 56,193, 68, 36, 16,180,173, 83,191, 62,143,210,120,240, 4,222,136,221, 61, 12,234,212, 44,104,148,106, 48, + 2, 25,180,122, 30,116, 28,129,184, 70, 61,188, 57,126, 18,158,125, 7,241,197, 2, 65, 59, 0,171, 76,117,137, 9, 38,252,247, + 80,154, 22, 41,116, 77, 71, 66,200,233, 37, 75,150,116, 44,237, 60,165,180, 35, 0,109,145,125, 24,243, 31, 0,150, 46, 93,186, +184,208,190,234, 99,222,167, 76,181,193, 83,107,151, 76,153, 54, 11,214,150, 82,203,122,181,188,156, 78,156,191,241,240,230,237, +135, 47, 43, 85,176,179,167,122,173,245, 79, 43,214,186,145, 28,149,177,131,188,253,236,236,236,160,211,233,240,230,205, 27,196, +198,198, 66,167,211,193,160, 84, 66,147,145, 1,117,122, 58, 88,101, 22,132, 44, 11, 85,114, 18,108,205, 36,192, 31, 51, 12,203, + 18, 66,197, 10,172,252, 95,137,165, 5, 36,230, 22,224, 9, 4,197,118, 31,150,192, 89,187, 94,189,122, 7,131,131,131,235,183, +105,211,102, 1, 33,196,146, 82, 26, 21, 23, 23,215,122,246,236,217, 26, 71, 71, 71,140, 28, 57,210, 7,192,224, 50,197,165, 72, +235, 87,209,201, 7,222, 30,131, 81,169, 66, 43,100, 40,245, 72, 86,232,145,148,161,195,166, 95, 26,226,200,214,122,248,253, 72, + 83, 4, 95,104,139, 12,189, 19,228, 46, 93, 64, 89,109, 64,105,156,183,111,223,198,198,141, 27,177,113,227, 70,108,216,176, 1, +107,215,174, 69,122,122, 58,170, 85,171,134,232,232,104,156, 59,119, 14, 9, 9, 9,176,179,179,195,147, 39, 79,176,105,211, 38, +220,191, 95,254,113,196,106,181, 26, 66,185,173, 46,223,178,197, 9,100,186, 66, 2,220,104, 30,131,193, 48, 36,161,107,215,234, +137, 54, 54,254,181,106,213,250,106,220,184,113, 30,141, 27, 55, 46, 56,239,225,225,225, 46,149, 74,223, 19, 66,182, 18, 66,106, +150,198,197, 1,181,236,237,171, 65,171,121,149,151, 86, 2, 16, 34, 65,171,182, 47,209,184,233, 67,232,244, 66, 48, 68, 12,134, +145,192, 96, 72,133,181,181, 11, 40, 37,213,202, 8,226,236,228,228,100,175,203,151, 47, 51,239,222,189,203, 23,150,145,115,231, +206, 93,251,243,207, 63,135,216,218,218,178,167, 79,159,198,241,227,199,209,177, 99, 71,222,215, 95,127,237, 85,161, 66,133,141, +101,189,247,156,213,241,119,246,174, 56,215, 87,160,183,174, 41,145, 86,170, 12,165,188,203,119, 45,236,101, 0,112, 46, 60, 60, +203,193, 93,177, 84,153,245, 44,218,202, 45,251,199,178, 6,184, 83, 58,135,123, 20,246,234,238,222, 99,231, 51,147, 18,211, 5, +181,170, 7,168,150,204,255, 94, 88,169,114,213,159,230, 76, 27,229, 20,167,144,100,180, 29,119,238,213,209,243,247,179, 7, 14, +253,198, 48,124,196, 24,245,185,243,151,142,113, 28, 87,189,164, 25,132, 28,199, 33, 33, 33, 1, 47, 94,188, 64, 68, 68, 4,146, +147,147,145,146,146,130,172,172,172,130,110, 69,179, 44,197,153,181,191,158,122, 42,147, 74,205,234, 87,247,114,191,247, 56, 36, + 73, 38,149,154,121, 85,118,247, 38,100, 94,177,229, 8,203,178,213, 37,102, 82, 0, 4, 89,193, 55,161, 78,203,134, 42, 35, 27, +234,244,108,104,116, 60,168, 53, 12, 84, 90, 6,118, 77,191, 64,182, 82, 13, 77,122, 38, 56,150, 13, 52, 85, 51, 38,152, 96, 66, + 41,245,242,233,160,160,160, 25, 70, 94,110,116, 55,102,190, 16,203,223, 15, 10, 10,154,145,103, 45, 11, 64, 9, 99,150,141,178, + 96,149, 54, 53, 50, 37, 37, 52,219,194,222,191,251,196,169, 63,156,219,183,237, 23, 7,141, 38, 39,218,214, 90,206,202,205, 68, +118,195, 71, 46, 66, 86,118,122,183,236, 52,227,103, 61,165,167,167,227,237,219,183,144, 74,165, 16, 10, 4, 96, 85, 42,176, 42, + 37, 84,233,169, 96,116, 26, 8, 89, 22, 54,102, 82, 84,116,113, 66, 37, 71,227,172, 35,175,175, 92, 44, 24,208,190, 44, 46,163, + 64,108, 45,168,235, 7,177, 76, 14,177, 92,142,137,103,174, 3, 0,132, 66, 33,240,195, 2, 99, 18,209,206,213,213,245,228,222, +189,123,133,201,201,201,120,242,228,201, 83, 74,105, 38, 33,196, 28, 0,247,242,229,203,203,193,193,193, 29,189,188,188, 0,192, +179, 44, 62, 69, 10,195,234, 13, 20, 49,239, 35,241, 46,246, 49,108, 44,171, 64, 96,230,141,164, 12, 29,196,210, 42,208,107,254, +152,132,169, 86, 68, 65,165, 51,110,162,163, 78,167,131, 78,167,131, 94,175,135, 70,163,193,192,129, 3,113,235,246,109,236, 63, +126, 5,111,195, 67,225, 83,217, 9,131, 6, 13, 68,205,154, 53,241,224,193,199,143, 31,110, 56,237,194, 11,169, 84,138, 13, 27, + 54,160,240,160,119, 99,215,216, 37,132,252,220,177, 99,199,170,161, 74, 37, 94,188,122,133, 54,115,231, 2, 0,206,158, 61, 91, +112,141, 86,171,197,164, 73,147, 68, 33, 33, 33,195, 31, 62,124, 56,156, 16,178,130, 82, 90,252, 32,114, 10,156, 57,115, 7,163, + 70,133, 32, 57, 57,119, 28,246,129,125,127,232,209,119,111,117,248,178,195,121, 0,128,149,149, 21, 86,172,168,102, 84, 56, 89, +150,197,230,205,155, 33,149, 74, 33,149, 74,115, 63, 18, 62,191,241,164, 73,147,186, 23,119,125,213,170, 85,133,101,113, 78,234, +229, 38,121, 18, 37,253,206,178,106,165, 0, 11,187, 26, 72,213, 63,174,246, 56, 46, 97,236,164, 94,110,171, 86, 28,138, 85, 75, +137,102, 7, 97, 99, 42,240, 37,234,157,198,132, 49,252,220, 26,173, 85,165,161, 59,223, 39, 43,102,142,249,166,191,173,133,149, +131,114,235,218, 37,214, 12,143,161, 39, 31,234, 50, 2, 60,108,173,186, 52, 88,157, 61,106,226,236,199, 90, 67,204, 24,196,156, + 12, 45,205, 85, 5,203,178,136,143,143, 71,114,114, 50,162,163,163,145,146,146,146,247,237,167,148, 75, 64, 23,215,232,209, 70, + 71, 35,241,248, 86, 56, 13, 24, 8,239,249,243,193,114,124,168,115, 88, 28,110,214, 26,138, 12, 21,180, 28,129, 85,237, 70,248, +226,244,111, 32, 28, 11,108, 88,103,170, 65, 76, 48,225,191, 43,158, 74,212, 34,198, 90,176, 62,209,130, 86, 32,178,150, 44, 89, +242, 98,201,146, 37,159,244,172, 50,221, 52, 0,128, 34, 57, 36,194,182, 98,141,120,165, 74,105,230,232, 96,175, 49,147,136,185, + 76, 69, 22,239,241,243,167,186,236,132, 55,175,203,241,188,151,193,193,193,213,226,227,227, 17, 29, 21, 5,131, 74, 9, 70,163, + 5, 85,231,160, 77,147, 70,144, 0,144, 48, 4, 66, 78, 7, 62, 79,132,172,108, 5, 0,188, 44,179, 82,212,235,255,100,201, 34, +132, 64, 34, 55,135, 80, 38,131,216,220,252, 3,139,150, 49,162, 64, 44, 22,239, 61,116,232,144,179,171,171, 43,230,207,159, 15, + 55, 55, 55,223,234,213,171,231, 52,109,218, 84,234,232,232, 8,127,127,127, 52,106,212, 8,231,206,157, 3,128,240,178,248,244, + 6,201,179,215,145,104,156,146,118, 27,191, 93,223, 0,173, 74,131, 90,205, 55, 64,199,175, 4,251,128,121,224,222,236, 70,206, +251, 19,185,214, 2,167, 78,136,141,142, 4,225,137, 94,148, 51,115,224,217,179,103,216,119,226, 6,156, 43,250, 33, 58,236, 21, + 94, 93,187,140, 91,246,182,168,228, 31, 0,189, 94,111,180, 32, 50,246,186,252, 46, 36, 35,208,127,202,148, 41,200, 16, 8,128, + 14, 29, 32,140,136,128, 78,167, 67,131, 6, 13, 80,183,110, 93, 0, 64,131, 6, 13,192,231,243, 81,163, 70, 13,184,184,184, 96, +221,186,117,253, 81,194, 44, 61,134,224,137,193,144,234,235,225,225, 81, 32,176,118,238, 74,198,227,135,109, 65, 32,194,154,181, +127,120,101,112,119,119,199,251,132, 8, 16, 66,131,203, 8,227, 2, 39, 39,167,217,206,206,206, 30, 63,255,252, 51, 79, 34,145, + 96,244,232,209, 85,178,179,179, 43,229,153,140, 49,125,250,244, 92,171,212,156, 57,152, 59,119, 46, 52, 26, 77, 78, 73,100,187, + 86,214,112, 73, 74,227,134, 59, 58,185,118,107,105, 87,169,122,171,118,109, 80,197,171, 21, 90,181,139, 6,128,197, 54,252,200, +222,203,102, 85, 59,102, 87,193,102,251,197,243,151,230, 52,105,222,106,102,208, 72,235,133, 75, 55,165,151, 57,166, 49, 51,106, + 71,214,107, 81,159,149,191,108,220,181,242,135,233,227, 37,209,201,218,244,184,116,154, 45, 23,243,229,158,142, 68, 62,118,234, +130,183,241,241, 17,147, 17,115,190,204,153,147, 28,199, 33, 34, 34, 2, 90,173, 22, 44,203, 66,173, 86, 67,169, 84, 34, 38, 38, +166, 32,125, 85, 50,139, 47,199, 12,237, 20,168, 84,169,114,238, 61, 15,139,158, 53,110, 64, 67,165, 74,149, 19,246, 46, 58,148, +210,213,197,170, 48,134, 97,158,231,100,231,180,209,100,170,145,249,244, 53,108, 91, 85,132,206, 64,160, 97, 89,164,167,100, 65, +107, 0,244, 60, 1,220,122, 14,130, 30,124,164, 39,196,129,225,241,158,154,170, 25, 19, 76,248,207,162, 76, 55, 13,132,144,211, + 13, 27, 54,220, 95,216,202,148,255, 31,128, 6,128,184, 20,254,228,194, 34,170,112,151, 96,113,207, 41,194,251,209, 2,171,212, +169,145,132, 16, 18, 88,189,162,203,178, 57, 3,220, 56,131,193, 39, 41, 37,209,192,231,139, 5, 21, 44, 85, 9,229,121,152, 70, +163, 57,125,249,242,229,174,109,219,182, 21,135, 61,127, 10,109,102, 38,180,153, 25, 16,112, 6,216, 72,235,128,209,105, 64,180, + 90,184,250,114, 80,103, 73,113,227, 86,176, 94,163,209,156, 46,179,146, 55,228, 10, 44,134,199,251,160,171, 80,100, 46,135,196, +220, 2, 18,185,188,104, 23, 34, 41, 67, 69,155,117,238,220,185,117,131, 6, 13, 64, 41,197,230,205,155,161,211,233, 68, 58,157, + 14, 90,173, 22, 58,157, 14, 10,133, 2,187,118,237,194,250,245,235,111, 1,248,181,204, 74,204,160,189,124,225,210,213,122,195, + 6,116, 20,156, 61,189, 2, 6, 45, 11, 21,113,131, 82,169, 71,182,214, 12,172,237, 64, 32,241, 12,120,124, 9, 26,214,168,130, + 19,135,143,234, 96,208, 92, 41,175, 16, 82,171,213,136,137,142, 68,108,120, 40,228,138,247,176,183, 48, 67, 78, 68, 40,106, 14, + 26, 12,173, 86, 91,102, 26, 13,169, 69,244,203,219,129,191,226, 43, 6, 66,185,173,174,225,180, 11, 37,138, 60,185, 92, 94, 46, + 11, 71,106,106, 42, 78,157, 58,133, 6, 13, 26,160,121,243,230,136,139,139, 67, 68, 68, 4,218,183,111, 95,112,205,211,167, 79, +241,248,241, 99,120,122,150,110, 20, 76, 73,211,159,141,141,121,210,171, 75,151, 46,194,187,119,239,130, 82, 10, 47, 47, 11, 88, +152,203, 64, 24, 49,252,252, 28, 0,228,106,255, 22, 45, 90, 64,161,136, 48,164,167,211,179,101,196,229, 94, 66,200,113,173, 86, +251,166, 89,179,102, 46,225,225,225,152, 56,113, 34,255,192,129, 3,249, 38, 99, 4, 5, 5,125,112,143, 74, 85,114,215,188, 79, +117,223,239,171, 24,172,155, 75,164,149, 42, 91,216,213, 64, 21,175, 86, 0,128,182, 29,135,161, 74, 85,119, 40, 82,158, 85, 86, +171, 34,187, 9,249,233,214,207,214,196,133, 72, 59, 84, 27,170, 78,186, 30, 6,192, 24,199,189, 84, 21,118, 32, 49, 90, 48,240, +224,241,147,231, 70,182,239,216, 89,160,103, 13,134,106, 21, 5, 86,135,142,157, 73,138,139,138, 94,141,232,243,193,127,216,251, + 74, 21,201,172, 66,161,128, 76, 38, 67,112,112,176,166, 67,135, 14, 98,134, 97,240,230,205,155, 2,129,229, 96,103,227,223,184, +110, 53,223,133, 43,119, 93,144,137,197,226,118, 45,234,248,133,132, 69,197, 82, 74, 34, 75,226,213,234,245,151, 94, 60,121,218, +178,130,115, 85, 94,252,141,187, 48,107,210, 30, 26, 13, 3,181,150,131,198, 0, 24,120, 66, 88, 6,214,135,212,195, 15, 20,192, +131,187,183,244, 26,189,254,130,169,142, 49,193,132,255,180, 21,139,150, 38,142,242,254,167, 1,136, 92,178,100, 73, 74, 33,235, + 82, 50,128,167, 0, 2,243,174, 75, 46,114, 95, 50,114,103, 3,214, 45,196,147, 92, 72,104, 21,254,175, 45,114,205, 71, 53,252, +202,116,211, 0, 0,118,118,118, 14,181,106,213,241,220,178,237, 32, 40,165,120,253,120, 57,210,147, 94, 97,246,226, 59,158,110, +110,110,205, 99, 99, 99,111, 24,105,237, 56,176,125,251,246,201,245,107,215,170, 85,217,205, 13, 79, 35,223, 65, 72, 89, 8, 89, + 22,140, 78, 3, 62,171,133, 91, 53, 22, 12,145, 35, 62, 62, 19, 75,247, 30, 12,102, 89,246, 64, 89,188, 1,237, 59, 99,121,124, + 38, 8, 33, 88,212,160, 26,196,114, 57, 68,114, 57, 38,156,186, 90, 32,170, 78,204,159, 14,177, 76,142,170, 13,202,118,224, 78, + 41,205, 49, 55, 55,127,248,252,249,243,186,213,170, 85,195,228,201,147, 17, 25, 25, 9,142,227,144,152,152,168, 78, 72, 72,136, + 75, 78, 78,142, 4,112, 12,192, 22, 99, 60,133, 11, 53,234, 85,167,143,236, 28,211,176, 73,115,187, 46,221,214,227,248,225, 73, +200,200, 84, 32,199, 32,133, 82,109,128, 82,195,131,141,109,117,212,175, 81, 3,241,113, 73,120,113,247, 66, 54, 95,147,179,188, + 60,214, 43,134, 97,240,244,233, 83,120,184,152, 35,244,183, 27,176, 51, 19, 32,208,197, 9, 46,141,155,228,207, 30, 44, 19,122, + 22,252,201,203, 11,252, 96, 9,173,172,172,144,153,153,249,129,144, 51, 51, 51,131,139,139, 11,210,210,210,176,105,211, 38, 0, +184,101, 12,181, 86,171,133,175,175, 47, 30, 60,120,128,203,151, 47,163, 85,171, 86,104,222,188, 57,158, 61,123,134,139, 23, 47, +226,241,227,199, 32,132,192,214,214, 22,250, 92,171,164,190, 36, 50,157, 14,135,126,252,105,251,140,149, 43,215, 7, 12, 24, 48, + 0, 71,142,236,199,176,161, 62,121, 3,219,197,232,220,201, 7,243, 23, 60, 64,253,250, 45, 96,103, 39,192,202, 21, 39,222,170, + 84,236, 46, 35,194,185,240,226,197,139, 46,106,181, 26, 25, 25, 25, 84, 46,151,147,212,212, 92,119, 84,197, 89,176,114,114,114, + 36, 37, 17, 61,127,244,114,121, 70, 22, 77,167,217,143,187,165, 25, 30, 87,111,213, 46, 6,109, 59, 14,197,165,211,191,226,234, +133,203,176,225, 71,190,131, 44,235, 92,202,187, 20, 69,130,210,107,163, 95,237,175,121,177,202, 11, 27,199,117,177,230, 57, 59, +115,135,130,214,103,102,148,146,222,148, 16, 66,210, 66,118,159, 60, 70,209,185, 81,195,250, 85,171,185, 59,139,210, 83,146,232, +225, 19,231,130,117,239,142,156,202, 23, 86,101,173,138, 64, 41,157, 31, 20, 20,244, 67,222,255, 29,179,102,205,250,122,233,210, +165,246,239,223,191, 47, 24,131,149,148,146,118,181, 81,135,177,108,106, 70,166,118,251,202,169, 61,165, 18,177,104,214,210,237, +215,245, 60,220, 45,137,215,192,113,235,186, 77,152, 61, 62,236,245, 99, 87, 59, 51, 17,110, 5,205, 65,248,229,107,208, 49, 66, +180,187,120, 15, 90, 29, 11, 69,114, 42,174, 13,255, 14,150, 78,214,216,112,237, 72, 34,199,113, 27, 76, 85,140, 9, 38,252,119, + 81,138, 22, 41,110,140, 75,162, 17,215, 61, 48,130,231, 47,129, 81, 83,234, 82, 82, 82,146,110,222,188,135,235,167, 23,226,198, +233,133,120,241,248, 41,226,227,180,136, 75, 84,195,194,194,226, 78, 41, 74,180, 77,209, 74, 33, 39, 39,167,251,172,217, 63,188, +151, 72,205,208,172,117,107, 56,217, 59,192, 76, 40, 0,207,192,129, 71, 4,200, 78,182, 66,232,179, 28, 76,219,190, 59, 41, 59, + 39,167,123,209,202,161, 40,103,161,227,185,221,130,230,230,121,155,197,135,221,133,230,185,131,220,249, 34, 81,113,131,225,255, +196,153,157,157,221,163,103,207,158,233,153,153,153,248,250,235,175,113,227,198,141,199, 23, 46, 92,176,120,250,244,169, 52, 41, + 41,169, 42,165,244, 11, 74,233,166,146,196, 85, 81,206,180,180,240, 44,106,208,244, 89,242,195, 4,149,218, 96,139, 94,131, 15, + 64,198,196,192,192,114,160, 0, 92,108, 68,104,220,102, 1,146,180,141,112, 96,227,162, 28, 78,167, 30, 80,216, 7, 86, 81, 78, + 74, 41,181,181,181,253,224, 93, 24,134,193,245,235,215,209,171,103, 15,180,235,214, 21,246,149, 61,224,208,166, 61,218,125, 61, + 10,155, 54,109, 2,195, 48,176,177,177,249,192,162, 81, 82,124,230, 35, 61, 61, 29,149, 42, 85,194,189,101,237, 3,206, 77,242, +173,229, 30,254, 75, 45,179, 39, 63, 7,156, 56,113, 2, 65, 65, 65,217, 79,158, 60, 89, 1, 96,138, 17,105, 52,115,252,248,241, +170,176,176, 48,200,100, 50, 24, 12, 6,220,186,117, 11,235,215,175,199,207, 63,255,140,199,143, 31,195,214,214, 22,158,158,158, +208,104, 52,120,240,224,129, 10,192,204, 82,242, 18,151,156,108,232,177,102,205,210,212,142, 29,155, 98,251,246,181,112,114,106, + 4, 1,223, 9,124,129, 61,100,114, 95,108,221,242, 35,190,250,170, 22, 78,158, 56,152,150,146,106,232, 81,212,235,122, 9,225, + 84,223,187,119, 15, 27, 55,110, 68,207,158, 61,227,122,245,234,197,102,102,102, 22, 88,176,242, 87, 73,159,155, 55,134, 76,163, +209,136, 75,226,252,122,234,243,184,239, 23, 6,207, 79,124, 31,215,224,198,181, 59,253,175, 94,184,140,183, 97, 87,113,245,194, +101,252,118,245,118, 80,226,251,184, 6,181,234,121, 11,187,127, 61,230,251,157, 71,143,240,228, 22,206,216,121,244, 8,175,223, +216, 9,139,234,180,107, 53,211,136, 52,162, 0,104,118, 82,226,244,197,203,127,201, 54,232,212,204,178,213,235,226, 85,201, 9, + 51,145, 63,181,178, 4,235, 85, 97,206,156,156,156, 77, 42,149,202, 69,165, 82,185,168,213,234,153,145,145,145,205, 38, 79,158, +156,204,178,108,129,176, 78,122,113,226,206,203,223,126, 93,236, 96,103, 45,109, 84, 55,192,103,197,166,195,215,163, 99, 18,247, +228,251,192, 42, 33,141,212,217, 42,117,143,174,221, 7, 42,211,211, 52,240, 25, 31, 4,131, 88, 14,141, 1,208,113, 60,232,192, +199,227,133, 43, 96,110,107,142, 93,111, 31,229,100,232,117, 61, 10,251,192, 50, 38,127,126,100, 11,217,196,105,226, 52,113,254, + 13, 57,255,109, 40,211, 77, 3, 0,184,186,186, 54,235,210,185, 13, 90,116,156, 5, 74, 41, 94, 61,250, 9,233,201,175,225,234, + 36, 70, 68,180,162, 33,128, 27,198, 62,144, 82, 26, 77, 8,105, 48,126,230,172,163,189,190,104,237, 87,173,114,101,113,165, 74, + 21, 33,115,112, 64, 74, 74, 50,126,191, 27,162, 95,180,239, 80,112,158,184, 50,102,169, 28,112, 28,151, 59,120, 29, 64,187,137, +211, 64,120,188, 2,119, 12,249, 21, 98,149,122,141,192,227,243,193, 82, 14, 26,141,134, 26, 17,206, 88, 66, 72,143, 1, 3, 6, + 92, 57,125,250, 52,211,174, 93,187,154,199,142, 29,227, 62, 37,178,179, 19, 67,175,201, 29,189, 59, 46,154, 62,242, 64,131, 86, + 93, 45,188, 2,234, 8,235, 84,226, 65,167, 39,136,143,139,194,233,163,247,117, 33,247, 46, 40,168, 65,221, 71,153, 92,250, 82, + 57, 58,157, 46,218,209,209,209,113,222,188,121, 48, 24, 12, 48, 24, 12, 96, 89, 22, 41, 41, 41,184,115,231, 14,170,215,173, 15, +191,161,195,145,156,156,140, 53,107,214,192,205,205, 13,139, 23, 47, 70, 90, 90, 26, 12, 6, 67,137,241, 42,224,193,208,191,127, +127, 62, 0,136,248, 48, 76,169, 83,231,122,173, 90,181,154,116,180, 72, 18,206, 89,147,107,217, 26,255, 77,127,225,169,187,167, + 14, 1,216, 84,214,218,118,158,158,158, 34,181, 90, 93,211,217,217,153, 71, 8, 89,165,213,106,135, 76,159, 62,221,121,241,226, +197,240,241,241, 65, 74, 74, 10,100, 50, 25,188,188,188,144,156,156,140,251,247,239,179, 57, 57, 57, 27, 1,204,167,148, 38,151, +145, 70,111, 8, 33, 13,198,141,251,246,232,143, 75, 71,122,169, 53, 45, 68, 54, 54, 77, 64,169, 1,201,201,145,200, 82,220,210, + 45,152,255,107,120, 98,146,190, 59,165, 52,204,200,100,154, 51,102,204, 24, 32,111,169,156,136,136,136, 39,126,126,126, 94, 37, + 89,176,140,193,138, 67,177,106, 0,251,150, 77,108, 52, 81,145,242,204,203,134, 31,249,174, 65, 53,110,205,138, 67,177,234,121, + 19,173, 22,166, 68,222, 8, 77, 80, 94,216,184,243,232, 17,222,224,110, 61, 88, 55,121, 88,144,196,129, 30,110,213,169,204, 60, + 74,107,214,172, 89,129,144,180, 42, 73,169,175, 31, 14,251,122,100,111, 75,161,234,108,160, 91,170, 39,227, 94, 75,242,248,241, +227,119,198,174,233, 89,132, 55,148, 16,210,108,250,244,233, 23,138,186, 31, 73, 74, 73,187,218,176,227, 24,154,145,145,249, 36, + 41,228,196,115, 35,184,238, 19, 66, 90, 87,171, 94,235,200,143,139,151, 58, 6,140,153,204,143,191,121, 29, 96,245, 72,184,113, + 29, 66,137,150, 91,122,235, 82, 98,154, 78,215,205,228,197,221, 4, 19, 76,214,171,210,180,200, 63, 82, 96,149,133,216,216,216, + 27,158, 30,110, 23, 67, 67,155,125,225,238,102, 15, 0,136,120, 23,143,184, 68,205, 69, 99,187, 7,139, 17, 89,117,118,159, 58, +219, 71, 44, 22,119, 36,121,174, 24,232, 71, 44,246,108, 48, 24, 98, 43, 87,174, 92,194,217,241,197, 30,101, 89, 54,209,200,112, + 94, 39,132, 12,244,244,244, 92, 26, 21, 21,117,148, 82,170,252,212, 8,207, 78, 12,189,102, 99,227,233,113,251,242,145, 9,119, +175,159,110, 67, 13,218,234, 0, 64,248,162,114, 45,246,156,157,157, 61,114,244,232,209,155, 4, 2,129, 59,242,198,148,229,143, +135, 98, 89,150,167,211,233, 36, 44,203,242, 0, 16,134, 97, 12, 2,129, 64,125,244,232, 81,131,193, 96,136,214,104, 52, 35, 75, +226,221,241,152, 10, 10,239,111,207,109,169,200,188,170, 35, 59,255, 88,170, 10,160, 37,120, 92, 47,138,179,103,207, 86,178,182, +182,254,130, 16,210,147, 82,234,155,149,149,165,153, 61,123,246,237, 67,135, 14, 41, 42, 87,174,252,101,135, 14, 29,136,141,141, + 13, 30, 60,120, 64, 83, 83, 83, 15, 3,152, 73, 41,141, 40, 71, 94,138, 32,132, 4,142, 28,181,161,175,141,205,166, 14,148, 34, + 16, 20,132, 48,120,158,153,201,157,205,201, 97,247, 80, 74,217,114,240, 25,138, 88,206, 22, 4, 7, 7,255, 10, 64, 80,220, 24, +172,114,193, 44,251,164, 90, 21,217,131,200,115,142,173, 88, 29,171, 6,128, 57, 43, 51, 50, 1,108, 29,215,205,134,123,249,104, +235, 79,174, 22, 97, 83, 87, 31, 75,219,110, 12, 93,173, 90,181, 60, 24,134,233, 3,160,154,131, 56,163,170,189, 40,147, 37,132, +182, 36,132,177, 3,240,204,223,223,255, 52,128,216,143, 44,232, 66, 1, 84, 44,122, 60,233,197,137, 59, 0,238,148,147,235, 62, + 33,164,234,196, 41,147,190, 19, 9, 4,109, 9,203,214, 48, 28, 57, 68, 77,139, 61,155, 96,130, 9,255,122, 11,150, 49, 8,143, +136,109, 7, 0, 94, 94, 94,244,205,155, 55,159,172, 48,243, 4,212,126,148,225, 68,180, 44,164,164,164,212,249,139, 21,245, 62, + 0,251, 62, 39,103,158,128,154,159,183,125,108,184,158, 3,168,255,255,212,170, 80, 14,169, 69, 10, 44, 91, 2, 30, 12,198,222, +251,197, 23, 95, 68,233,116,186,203, 0, 98, 8, 33, 86, 0,210,116, 58,221, 5,189, 94,159, 72, 8,169,179, 98,197,138,124, 71, +170, 11, 40,165, 15, 63, 50,124, 28,128,189,121,219,231,126,247,189, 46, 46, 46,147,108,109,109, 61,213,106,181, 72,173, 86, 11, + 11,107,127,169, 84,154,108, 44,151,149, 57,217, 33,228,167,219, 90,153,147, 63, 9, 40, 27, 87, 28, 81, 41,131,125,108, 92,113, +196, 88,190,199,143, 31, 71,212,172, 89,115, 55,195, 48,149, 41,165,142, 0,181,164, 20,201,148,210, 20, 62,159, 31, 23, 18, 18, + 18,247,119, 41,104,242, 4,212,242,188,205, 4, 19, 76, 48,193, 36,176,138, 34, 44, 44,140,152,162,237,191,135,162,150, 45, 99, + 17, 25, 25,169, 1,112, 59,111, 43, 90,233, 62, 4,208,233,239,254,238,241,241,241,181, 62, 7,207,215, 83,159,199, 1,152, 80, +167,152, 37,151,231,172, 73,203, 2,240,125,203,206,229,227,124,242,228, 73, 52,128,104, 83, 14, 53,193, 4, 19, 76,248,123,129, + 49, 69,129, 9, 38,152, 96,130, 9, 38,152, 96,194,231, 5, 1, 80,236, 76,128,242,172,148,253, 49,179, 9,202,226, 55,113,154, + 56, 77,156, 38, 78, 19,167,137,211,196,249,239,227,252,207, 32,127,150,221, 95,177, 1,104, 99,226, 52,113,154, 56, 77,156, 38, + 78, 19,167,137,211,196,249, 95,219,248, 38,137,105,130, 9, 38,252, 87,113,248,240, 97,163, 22,253,236, 59,117,107, 71,185,220, +122,118,182, 34,115,233,254,229,195,142,229, 31,239,217,179, 39,107,138, 69, 19, 76, 48,161, 56,148, 40,176, 60, 60, 42,248, 51, + 44,215,152, 82,134, 71, 25,170, 39, 10,213,129,240,180,180, 15,220, 7,184,187,187, 91, 9, 24,116, 34,148,202, 8,225, 88,142, +199,220,138,136,136, 9, 49,230,193,132, 16,145,181,181,245, 24,145, 72,212, 70,167,211,185,241,120,188, 88,181, 90,125, 57, 59, + 59,123,109, 81,103,131,255,107,248,248,248,244,187,126,253,186, 85,147, 38, 77, 52, 82,169,212,160, 82,169,248,231,207,159, 23, +127,245,213, 87, 25,111,222,188,249,168, 25,134,174,174,174,173,182,110,221, 90,165, 93,187,118,168, 90,181,170,178, 79,159, 62, +194,134, 13, 27, 10,191,254,250,235,183,113,113,113, 87,203,195, 69, 8,241, 39,132,236, 34,132,240, 56,142, 27,148, 55,195,240, +179,131, 16,194, 0, 24, 1,160, 43, 0, 15, 0, 17, 0,142, 3,216,108,140, 55,251, 98,248,122, 0,104, 15, 32, 48,239,208, 83, + 0,103, 41,165, 71, 62, 33,140, 61, 0,180, 39,132,212,204,179,208, 62,249, 92,156, 2,129,160, 38, 0,232,245,250, 39,127,151, +112, 18, 66,134, 74,165,210,111, 0, 64,165, 82,109,161,148,254, 90,238,192,108,242,163, 0,224,255,211, 43, 0, 64,200, 84, 95, + 24,187, 31,242,182,156,179,137, 75,120, 22, 70,190, 36,159, 16,151,237, 7, 12, 24,176,120,207,158, 61,115, 40,165, 39,254,138, +188,239,228, 84, 97,237,207,171, 55,187, 76, 24, 51,124, 41,114, 87,112, 40, 79,248,248,214,214,214, 93,164, 82,105, 93,173, 86, +235,192,227,241,146,212,106,245, 3,133, 66,113,130, 82,106, 32,132, 16, 63,224, 11, 17,195,248,104, 57,238, 86,200,199,204,166, +125, 69,172,117, 57,112, 34,220, 31,235,176, 81, 6, 26,161, 25,222,195,151,166,151,118, 43,143,199, 91,238,234,234, 58, 34, 35, + 35, 35,155, 97, 24, 74,114,145, 23,244, 2,103,205,132,227,184,184,180,180,180, 58,255,171,114,152,199,227, 77,112,113,113,233, +166, 80, 40,114,120, 60, 30, 45, 20, 62, 2, 0, 12,195, 16,142,227,146, 82, 83, 83, 7,153,170,118, 19,254, 54, 2,171,144, 91, +250, 22,148,210, 27, 30, 30, 21,252,123,118,237,190,120,212,200,209,132,199, 99, 16,252,226, 5,191,255,160,161, 95,216,216,216, +184,202, 53, 26, 63, 16,194,229, 72, 36,193,122,189, 46,238,208,190, 61,230,190, 62, 62, 44,203,114,216,184,105,195, 87, 30, 30, + 21,102,148, 37,178, 8, 33,222, 78, 78, 78,187,102,204,152,225,212,185,115,103,158,139,139, 11,162,162,162,172,246,237,219,231, +187,106,213,170,222,132,144, 65,121,126,120, 62,166,176,109,234,100,195,124, 97, 46, 37,173,145,197, 34, 75,143, 43,239, 85,184, + 72, 41,253,237, 99, 35, 41, 39, 39,103,108, 78, 78, 78,253,186,117,235,210,109,219,182,145, 33, 67,134, 80, 66, 8, 81,169, 84, + 59,240,145, 46, 28,100, 50,217,186,118,237,218,121,121,121,121, 69,132,135,135,183, 63,120,240,224,217,193,131, 7,123,200,100, +178, 48, 0,222,229,164,251, 53, 53, 53, 53, 80,165, 82,193,205,205,109, 27,128,218,127,129,184, 34, 0,142,216,216,216,168,231, +207,159,191,165, 69,139, 22,174,241,241,241,236,180,105,211, 26, 63,121,242,228, 75, 66, 72, 87, 99, 69, 22, 33,196, 26,192, 70, +185, 92,110, 54,109,218,180,155,109,219,182,125, 39,151,203, 37,207,158, 61, 19, 76,155, 54,109, 4, 33,164, 23,128, 81,148,150, + 94, 49, 20,199,105,111,111,111, 53,103,206,156,231,141, 26, 53,186, 33, 20, 10,133,175, 95,191, 22, 4, 5, 5,125,247, 41,156, + 94, 94, 94,230, 63,252,240,195,131,154, 53,107, 38, 74, 36, 18, 97,120,120,184, 96,198,140, 25,163,120, 60, 94, 47,142,227, 62, +138,211,198,198,198, 98,198,140, 25, 15,155, 55,111,158, 44, 22,139, 69, 33, 33, 33,252,233,211,167,143, 42, 79, 56,109,109,109, + 91,218,218,218,110,126,255,254, 61, 31, 0,156,157,157,235,121,122,122,254, 82,120,125,200,124,151, 18,122,189, 62, 75,173, 86, + 15, 72, 77, 77,253,147, 3, 91,255,159, 94,225,251, 31,118,244,251,254,135,220,253,157,121,199,203,218, 7,134, 24,157,247,253, +171,228,150, 49,223, 77, 89, 63, 48,247, 55,247,248,134,188,160,174,171, 66,104,121,196, 26, 33,164, 75,171, 86,173,230, 94,189, +122,117, 67,139, 22, 45,166,237,222,189,219, 33, 38, 38,230, 71, 66, 72,133,190,125,251, 14,185,114,229,202,146,228,228,228,195, +159, 43,255,139,132, 98, 49, 97, 8,164, 18, 51,139,114,126, 55,174, 78, 78, 78,115, 39, 78,156,104,215,189,123,119,198,221,221, + 29,225,225,225,214,123,246,236,169,186, 97,195,134,118,132,144,121,190, 64,205,169, 53,106, 12,237, 91,165, 74,187, 70, 39, 79, +206, 2, 80, 62,129,245,138, 88, 43, 51, 80, 93,163, 69, 45, 74, 97,245,199,179,145, 33,214,225,177,236, 21,121, 94,146,200, 34, +132,172,236,210,165,203,160,227,199,143,203,119,239,222, 45,111,212,168, 17, 28, 29, 29, 65, 8, 1,203,178,224, 56, 14, 28,199, +229,173,245,233, 85,110, 17, 92,155, 16, 11, 14,152, 34, 37,104,165, 1, 9, 0, 0, 49,232, 11, 21,197, 85, 6, 88,254,168, 12, + 71,197,133,194, 57,169, 91,183,110, 29,142, 30, 61, 42, 61,116,232,144,180,110,221,186,112,114,114, 2,128,130,240, 81, 74, 81, +165, 74, 21, 83,173,254, 15, 70, 81, 45,242,175,177, 96, 21, 94,193,154, 97,185,198,163, 70,142, 38,125,250,245,125,255, 38,226, + 45,199, 23,136,250,157,191,112,193,204,223,223,159,209,172, 93, 11, 67,114, 50,244, 19, 39, 54,186,124,249,178,190, 87,191,129, + 42, 1,143,252,234, 81,165,178,217,129,125,251,157,142, 30, 57,220, 24, 64, 72,105,150, 43, 39, 39,167, 93,215,175, 95,119,245, +242,242,130, 86,171, 69, 74, 74, 10, 40,165, 24, 56,112, 32,191,121,243,230,174,157, 59,119,222, 69, 8,105, 82, 30, 75, 22, 33, +196,177,170, 27,255,244,207, 63,244,246,254,234,139,198, 50,215, 10,158,160,239,213,136, 9,127, 85,247,244,245,187,227,188,172, +152,208, 55,153,180, 35,165, 52,177,188,145,148,146,146, 50,181, 91,183,110, 71, 90,182,108,105, 47, 22,139,225,226,226, 66, 58, +119,238,156, 20, 31, 31, 63,239, 19, 50, 18,242, 90, 93,108,225,223,162,203,248, 24, 9, 55,107,107,107, 88, 91, 91, 3,128,235, +167,100,136, 94,189,122,241,162,163,163,191,225, 56,206,175,240,113, 7, 7, 7, 31,150,101,211,163,162,162,125, 84, 90,157,223, +232, 49, 51,230,246,233,217,198,234,246,237,219, 92,187,118,237, 52, 55,111,222, 28, 1, 96,163,145,143,217, 88,163, 70,141,240, + 85,171, 86,105,194, 34,222, 85, 14,126, 25, 6,153, 68,200, 86,168, 80, 65, 28, 18, 18,162,153, 61,123,182,114,245,234,213, 27, + 1,244, 42, 71,208, 55,126,245,213, 87,233,179,102,205, 74, 10, 13,127,231,252, 52, 36,148,202,197, 66,189,163,163, 3,239,225, +195,135,234, 31,127,252,145, 91,178,100, 73,185, 57, 7, 14, 28, 24, 63,109,218,180,119,201,169, 25,174,233, 25, 89, 84,148,147, +163,115,115,115,227, 95,187,118, 45,123,253,250,245,154,105,211,166,149,155,179, 69,139, 22,239, 23, 44, 88, 16,253, 42, 44,194, +229,113,240,107,200,197, 2,189,147,147, 3,239,241,227,199, 57, 75,150, 44,209,253,244,211, 79, 70,113,202,100,178,157, 7, 15, + 30,228,159, 56,145,107,180,185,115,231, 14,227,225,225, 97, 86,248, 26,149, 90, 3,134, 0, 41, 41, 41,102, 13, 27, 54,220, 9, +192,173, 36,190,193,131, 7,191, 47, 79, 94, 25,172,249,201,184, 11, 55,249,209,124, 97, 53,122,244,232,146,124,115, 13,244, 47, +135,200,106,223,190,253,204, 51,103,206,120,238,222,189,123,197,222,189,123,181, 0, 32,145, 72,236,246,239,223,191,164,119,239, +222,232,221,187,247,108, 0,159, 77, 96,177,148,213, 1,128, 88, 34, 22,191,122,245,138,248,250,250, 82, 35,190,113,129,163,163, +227,188, 75,151, 46,217,251,251,251, 67,171,213, 34, 53, 53, 21,124, 62, 31, 35, 70,140,224,181,104,209,194, 97,104,231,206,219, +191,247,240, 80, 15,244,244,108,191, 59, 60,252,116,142,193,240,212, 24,107, 83,102,102,102,118,190, 21,199,175,178, 57,191, 89, + 77,131,184, 70, 85,189, 72,200, 51, 8, 59, 77,228,200,197,181, 68,233, 91, 5,191, 3,128, 48, 7,201, 66, 32,189,152,240,253, +212,165, 75,151,222,199,143, 31,183, 6,128,195,135, 15, 35, 39, 39, 7, 21, 43, 86,132, 80, 40,132, 64, 32,128, 64, 32, 40,248, + 95,222,178,201,159,144,118,102, 60,102,247,164,174,157,204,235,249,250, 8,157,204,229,224,178, 20,136, 12, 15,111,112,245, 85, + 88,173,125, 47, 94,141,246, 39,100, 64, 8,165, 23,202,136,199,113, 93,186,116,105,123,244,232, 81,243,252,112,234,245,122,120, +120,120, 64, 40, 20, 66, 36, 18, 21,132,211,132,127, 62, 10,107,145,127,141,192,202,123,161, 22,185, 47,200,240,120, 60, 6,111, + 35, 34,245, 45, 91,182, 30,182,123,207, 30,177, 88, 44,206, 45, 32,174, 94, 5, 85,171, 97, 37,151,163, 91,183,110,130, 90,181, +106, 89,116,239,220,249,235,119,111,223,109,226,241, 24, 39, 74,153, 82,199, 52, 88, 91, 91,143,153, 49, 99,134,147,151,151,215, + 7, 45,108,131,193,128,212,212, 84, 88, 89, 89, 97,248,240,225, 14,235,215,175, 31, 3,224,103, 35,197, 74, 37,111, 15,135, 91, + 87,143, 45,118,118,182, 21, 0,201,135,129,152,181,192,137, 44,248,217, 85,129, 95,215,118,178, 62, 45,106,214,106, 59,117,221, + 99, 66, 72, 99, 74,105,100,121, 34, 73,173, 86,255, 78, 8,249,154, 97,152, 19, 0,152,107,215,174,209,151, 47, 95,142,164,148, + 70,125,108,196,115, 28,135,140,140, 12,112, 28,199,203,219,207,255,253,159,101,134, 94,189,122,241, 98, 98, 98, 70,250,249,249, + 85,221,178,101, 11,146,146,146, 32,149, 74,193,178, 44,106,214,172,233,222,190,125,251,208,228,212,140,186,122,131, 94,155, 16, + 27, 94,111,255,230,200,156, 64, 47,175,219,123,246,236,169,227,230,230,214,213, 24,129, 69, 8,233, 33,151,203,165, 43, 86,172, + 80,154, 91, 57,117,169, 87,223, 69,240, 60,228,117,164, 80,204,231, 50, 51, 21,169, 79,159, 62,125,181,108,217,178,166,151, 46, + 93, 82, 17, 66,122, 24,211,101, 70, 8,233, 97,103,103,103, 57,115,230,204, 68,169,185, 93,211,186,245, 29,248,193, 33,111,226, + 4, 66, 70,223,184,113,227,150,119,238,220,249,117,206,156, 57, 53, 46, 94,188,200,150,135,179, 74,149, 42,230,211,166, 77,123, +107,105,101,215,214,222,201,133,103,111, 99,229, 9, 0, 17, 17, 17,187, 19, 19, 19,195, 38, 77,154, 84,247,252,249,243, 40, 15, +167,181,181,181,249,130, 5, 11,162, 42,123,248,244,244,240,242, 97, 46, 95,191,247, 92, 36, 98,244, 42,149, 42,237,229,203,151, +111,230,207,159, 95,231,242,229,203,212, 24,206,156,156, 28,129,157,157, 29,172,172,172,192,169, 84,200,204,204,196,209,163, 71, +145,149,149, 5,150,101, 33,149, 74,177,104,197, 38,132, 7,223,197,111,191,253, 6,133, 66, 81,172, 47,179,144,169,190,133,172, + 82,159, 25,155,252,232, 6,110,204,192, 82,132, 21, 10, 9,175,129,216,228, 71, 75,235, 46, 44,100,185,122,181,123,247,110, 95, +127,127,127,180,107,215, 78, 4, 0, 99,198,140, 17,181,111,223, 30, 7, 15, 30,196,225,195,135, 67,188,189,189,111,133,133,133, + 45, 55,166,219,112,208,160, 65, 77, 52, 26,205, 34, 0, 50,134, 97, 30, 89, 88, 88,204,219,180,105, 83,124,254,249,132,248,216, +135, 90,173,182, 83, 96,173,186,102, 11,182,109, 31,176,255,103,223,221,101,113, 90, 89, 89,117,159, 58,117,170,141,191,191, 63, + 10,127,219, 28,199, 33, 62, 62, 30,175,239,222,117,156, 94,187,182,203, 32, 59, 59,199,221,225,225,167,126,124,246,236,215, 87, +192,181, 82,222,125,101,183,110,221, 6, 29, 61,122, 84,126,232,208, 33,121,221,186,117,115,173, 77,234,167,208, 36,159,192,195, + 27,235, 17, 30,149,187, 62,250,187,120,200, 0, 52,169,233,131,167,133,187, 13, 63,104,149,185,185,141, 56,126,252,184, 69,161, +178,249, 3, 65, 85,244, 63, 24,202,216, 4,144,237,230, 85,208, 62, 51, 2, 75, 50, 66,232,170, 82,196, 85,139, 10,246,118,199, +182,125, 63, 81,226,148,158, 2,156, 59, 6,196,197, 2, 28,139, 0, 75, 43, 4, 56,185, 8, 91, 53, 8,180, 25,243, 40,228,136, + 63, 33,157, 66, 40, 45,241,189,221,220,220,186, 29, 63,126, 92,150,191,111,103,103, 7,137, 68,242, 39,113, 37, 20, 10,193, 48, + 38,207, 67,255, 18, 43, 86,139,127,195,187, 48,133, 85, 35,128,235, 0, 64, 9, 81, 62, 11, 14, 22,240, 68,162,129,123,246,238, + 21, 11,133, 66, 68, 69, 69, 33, 36, 36, 4, 57, 87,174, 64,117,251, 54, 18, 19, 19,145,157,157, 13, 71, 71, 71,108,218,182, 77, +166,101,233,176,215,161,161, 60,202, 80,125, 33,206, 63, 77,213, 20,139,197,109,186,119,239, 94,162, 8, 75, 76, 76, 68,231,206, +157, 5,124, 62,223, 40,247, 17,132, 16,226, 98, 79, 78, 93, 57,178,192,217, 89, 20, 2,188,153, 4,100, 61, 6,168, 6, 48,104, +129,184,231,192,153,121,168,152,253,138, 92, 88, 48,216,201,213,140,127,138, 20,105,138, 25, 49, 77,213,195,215,215,119,235,192, +129, 3, 25, 0,104,213,170, 21,241,245,245,221, 76, 8,241, 40, 69,133, 95, 46,163,114,188,155,158,158,142,222,189,123,219,122, +122,122, 94,238,221,187,183,109,254,241,143,229,204,131,109, 64, 64, 64,170, 84, 42,221, 71, 8, 17, 27,209, 90, 40,224,140,142, +142,254,198,215,215,183,234,150, 45, 91,120, 60, 30, 15, 91,182,108,193,129, 3, 7,240,251,239,191, 35, 53, 53, 85, 62,105,210, + 36,203,211,151,239,158,191,245,251,253,147,203,103, 77,177,237,214,186,133,135,117,102,178,194,213,213,181, 13,114,199,100, 25, + 19,206,246, 99,199,142,189,248,228,101,132, 3,195, 23, 8,197, 66,129,212,222,206,170,162,147,189,117, 85, 87, 91,235,170,230, + 34,129,149, 66,161,120,123,240,224,193,108,228,142,207, 50,138,243,135, 31,126,120,250, 42, 34,198,150,225,241, 5, 2,158, 64, +100,101, 41,183,237,220,241,139,150, 0, 32,229, 17,177, 66,161,136,217,185,115,167,178, 60,156,179,103,207,190,147,144,156,238, + 32, 16,138,248, 98,161, 64, 82, 80, 17, 89,200, 29,101, 98,177, 52, 39, 39, 39,106,235,214,173,153,229,225,156, 62,125,250,131, + 23, 97, 81,118,132, 1,143, 1, 17, 88, 91,155, 59,216, 91,153, 59, 57, 88,200,157, 36, 12, 36, 10,133, 34,114,231,206,157, 10, + 99, 56,117, 58,157, 32, 41, 41, 9,175, 94,189, 66,133,186,117,113,249,242,101,184,187,187,163,119,239,222,232,219,183, 47,164, + 82, 41, 90, 53,172,142, 25, 51,102, 32, 60, 60, 28, 6,131, 65, 84,206,188, 4, 23, 23,151,235, 37, 86,162,121,227,168, 74,226, +244,175, 66, 74, 21, 87, 69,185,139,187,174, 40,103,251,246,237,103, 94,185,114,197,115,215,174, 93,157, 7, 13, 26,244,251,174, + 93,187,208,160, 65, 3,188,124,249, 18,149, 43, 87,198,142, 29, 59,208,183,111,223,223,215,172, 89,211,249,209,163, 71,129, 85, +170, 84,153, 81, 22,103,159, 62,125,190,171, 89,179,230,213,247,239,223, 55, 76, 75, 75,171,118,244,232,209, 97,221,186,117,123, +219,175, 95,191,214, 5, 22, 44,189,126,239,153,147, 71,208,161,115,119,248, 4, 84,219, 56,100,198,238,234,101,125,155, 82,169, +180,110,239,222,189,121,197, 53,174,110,157, 57,227,104,247,244,169,235, 40,123,123,199,197, 47, 95,190,203, 19, 87,167, 10, 47, + 17, 86,152,147, 16,242, 83,215,174, 93,123, 31, 61,122,180,192,218,116,251,246,109, 60,127,254, 28,145,145,145,200,200,200, 64, +235,145,217, 24,189, 36,247,246,209, 75, 40,190, 24, 67,101,165,189,123,118,118,182,234,216,177, 99,232,213,171, 23, 70,140, 24, +129, 42, 85,170, 20,136,172,162,226,234,198,253, 75, 16, 85, 75,179,105,178, 25, 67,219,158,128,189,204, 13,211, 75, 76,119, 66, +100,102, 12, 57,176,113,242,120, 73,244,161,131,216,120,232, 36,174,188, 8, 3, 85,171, 0,173, 22,143,162, 19,113, 45, 49, 27, +210,168,104,252,236,229,110, 38, 97,152, 3,158,132,152,151, 20, 78,165, 82,169, 57,123,246, 44, 6, 13, 26,132,241,227,199,163, +106,213,170, 5,225,220,185,251,128, 93,223, 97,163,188,107, 55,105, 22,232, 95,187, 65,141, 44, 13,175,174,208,204,230, 27, 82, +140,185,237,175,112, 29, 96,226,252,107, 44, 88,249, 90,228,223,102,193,154, 7, 0,122, 14,167, 6, 14, 30,214,233,242,149, 43, +102, 34,145, 8,239,222,189, 67, 98, 98, 34, 14,236,219,199, 30,114,112,200, 17, 8, 4,116,192,175,191,154, 15,255,230, 27, 34, + 16, 8,224,235,235,139,158, 61,123, 74,123,244,238,151,100, 47, 16, 28, 40, 67,172, 56, 59, 57, 57, 97,250,244,233, 88,178,100, +201, 7,231,134, 12, 25,130, 85,171, 86,193,202,202, 10, 12,195, 56, 25,107,120, 25, 55,175,171,155,117, 21,171, 68,250,120,167, +128,240,204,108,192, 51, 3, 24, 33, 32,225,229,138, 44,134, 7,205,163,171,105, 76,131,131,138,238, 77,115, 92, 87,159,223,212, + 11,192, 65, 99, 35,201,197,197,101,246,213,171, 87,237, 39, 77,154, 68, 21, 10, 5, 73, 72, 72,160,139, 23, 47,182,255,238,187, +239,102, 3, 24,252, 49, 17, 31, 31, 31,191,160, 67,135, 14,237,206,156, 57,227, 56,120,240, 96, 75, 0,232,208,161, 67, 98,124, +124,252,130, 79, 73, 80,161, 80,200,123,241,226,133,205,138, 21, 43,250, 78,158, 60, 57,160, 90,181,106, 78, 25, 25, 25,145,113, +113,113, 61,203,178,184,113, 28,231,183,101,203, 22,240,120,185,117, 2,195, 48, 16,137, 68, 16,137, 68,176,176,176, 72,143,136, +136,224, 42, 57, 74, 69,202,196,132, 76,107,190,181,128, 56, 59,217, 90, 57, 57,183, 72, 77, 77,189, 7,192,210,200, 32, 6,126, +249,229,151,207,110, 63,121,195,142, 30,210,170,170,153,144, 17,152, 75, 37, 60,169, 72, 64, 8,165,172, 78,175,109,184,110,231, +181,237,222,222,222,254,198,154,136, 9, 33, 53, 27, 52,104,112,229,201,203, 40, 60,125, 17, 17,107,111, 99,102,251,101,171,198, + 62,249,231,107,212,107,208,183,208,229, 25, 70,125, 24,124,126, 96,221,186,117, 99, 19,211,148,112,176,179,252, 64, 72, 91,219, + 57,180, 1, 0,101,102,230,186, 10, 21, 42,248,242,249,252,202,198,134,179,105,211,166, 9,143, 66,162,225,100,111, 99,147,119, +248,131, 49, 61, 41, 9, 9, 27,189,188,188,124, 9, 33,149,202,226,211,106,181,226,227,199,143,227,209,163, 71, 88, 16, 16,128, +239, 43, 85,130,189,189, 61,174, 92,185, 2, 74, 41,228,114, 57, 50, 50, 50,112,240,224, 65,180,110,221, 26, 90,173, 86, 86,146, + 80,202, 31, 95, 85,146, 16,138,143,143,255, 75, 90,148, 69,185,253,127,122,133,144,145, 37, 95,127,246,236,217,221,187,119,239, + 94,226,239,239,143, 9, 19, 38, 52, 89,181,106,213,239,213,170, 85,107,210,170, 85, 43, 92,189,122, 21,195,134, 13,251,125,205, +154, 53, 77, 70,141, 26,133,141, 27, 55,226,237,219,183,219, 74,123,126,159, 62,125,230,126,253,245,215,179,214,174, 93,155,107, +165, 1,208,181,107,215,252,178,113,123,175, 94,189, 82,243,175, 61,180, 53,246,118, 21, 15,175, 70,223,141,155, 34, 26, 51,106, + 80, 16,128,190,101, 84, 20,246,206,206,206,152, 61,123, 54, 22, 44, 88, 80, 96,177,191,122,244,168,163,225,236, 89,215, 94, 85, +171, 58, 28,103,152,164, 77, 49, 49,113,113, 69,196, 85,113,214,166, 99,199,142, 21,228, 21, 91, 91, 91,136, 68,162, 92, 17,196, + 23,128,199,242,112,121,163, 12, 17,209, 57, 24,189,132, 98,195,116,130,202, 46, 80,214,244, 41, 53, 63,162,113,227,198, 80, 40, + 20,224,241,120, 48, 55, 55,135,141,141,205, 7,226, 74,145,157,129,101,219,230, 34,201,231, 58,218,158, 4, 67,120,192,211, 69, + 64,214,155,146,151,116,226, 1,227,134,183,107, 99, 89, 65,149,141, 75,201,233, 24, 21, 21,131,231, 27, 54,224,218,132,239, 32, + 5,133,229,188, 37,168, 29, 20,132, 7,222, 94,168, 43,230,161,181,157,149,249,197,148,140, 9, 40, 97,233, 48, 66, 8,234,212, +169, 3,181, 90, 13,129, 64, 0, 11, 11, 11,104,117, 6, 65,175,129, 35, 60, 42,122, 86, 19, 47, 94,190,152,113,180,225,131,207, +216, 32, 44, 74,101,185,122,229,194,213,119,127,187, 57,156,152,217,117,163, 57, 41, 9, 38,155,208, 63,210,130, 53,239,223,240, + 46,252, 66,138, 17,133, 44, 25, 25, 54, 54, 54,174, 62, 62, 62,140, 86,171,205,237,122, 56,124,152,221,186,125,251, 25,181, 90, + 61, 14,128,112,237,250,245, 27, 93,221,220, 90, 14, 28, 52,136,232,245,122,116,232,208, 65,116,250,244,105,219,240,196,196,172, + 50, 34,175,224, 89,223,126,251, 45, 86,172, 88,145,111,162, 47,184, 70,175,215,195,216,202, 85,110,137,246,237, 58,214,177,136, +145,253, 98,161,107,164,207,174, 20,110,126, 87,150, 45,173, 3, 70,196,135,132, 7, 78,167, 55,132, 37,117,123, 24, 30,230,231, + 47, 77, 75,173,220, 38,160, 57,182, 94,218,213,190, 60, 2,203,204,204,172,158, 92, 46,199,195,135, 15,211,234,212,169,147, 65, + 41,181, 92,176, 96,129,157,153,153, 89,189, 79, 80,233,239, 8, 33,205, 26, 55,110, 60,134, 97,152, 54, 28,199, 93, 78, 76, 76, + 92, 75, 41,125,103,100, 38, 28, 13, 96, 14, 10,141, 51,209,106,181, 96, 24, 6,148, 82,244,233,211, 7,211,167, 79,247,127,254, +252, 57,174, 94,189,106,211,166, 77,155,187,132,144, 12, 0,195, 41,165, 37, 90,201, 82, 83, 83,177,113,227, 70,240,249,124, 88, + 89, 89,193,220,220, 28, 18,137, 4, 77,154, 52,121,191,116,233, 82,191, 35, 71,142,228,100, 36, 37, 17,105, 86,166,134,216,218, + 74,224,226,254,229,144,110,221,131,145, 59,155,208, 40,200,100, 50, 51, 17, 52, 89, 12,171,102,150,205, 93,199, 55, 19, 10,137, + 68,200,135,152,203,225,205, 88,186,144, 74, 8, 21,228, 89, 87,169,177,156, 18,137, 68, 40, 19, 81,141, 64,204,232,205, 24,250, + 89,250, 89, 69, 34,145, 80, 44, 80,170, 74, 20,179, 12,225,241,120, 60,113,121, 56,165, 82,169, 80, 46, 98, 53, 37,190, 7, 3, + 30,195, 48, 37,114,246, 10, 32,244,208, 24,223,252,221,130,176, 25, 12, 6,212,171, 87, 15,251, 79, 92,195,217, 43,183,145, 18, +245, 12,227, 70, 15,131,151,151, 23, 46, 92,184,240, 73,241, 16, 31, 31, 95,172,200, 42,152, 1, 88, 28,242,198, 93,149,213, 53, + 88,192,253,131,101,153,179, 18, 9, 33, 93,154, 54,109,250,221,222,189,123,181, 95,126,249,165,168, 79,159, 62,168, 86,173, 90, +147,161, 67,135, 2, 0,218,180,105,131, 85,171, 86, 53, 25, 58,116, 40, 14, 28, 56,128,163, 71,143,106, 90,180,104, 49,141, 16, + 18, 71, 41, 61, 91, 66,163,162,211,166, 77,155,138, 90, 6, 97, 48, 24,160,215,235,157, 13, 6,131,179, 94,175, 7, 33, 4,171, + 87,175, 73,185,120,225, 52,166,205,152, 7, 7,123,167,154,101,118, 15,228,117, 87, 25, 12, 6,140, 31, 63, 30, 75,150, 44,193, +249,253,251, 29,115,142, 31,119,157,230,233,233,112,208, 96, 72, 74,172, 86, 45, 46,231,210,165, 56,170, 84,150,154,215,149, 74, +165,234,236,217,179, 22, 7, 15, 30,132,149,149, 21,170, 86,173, 90, 32,134, 24,158, 20, 60,161, 53,124, 2,234, 1,184, 15, 0, +168,236, 2,165,111, 21,252, 78, 8, 50, 40, 3, 77, 41,249, 17, 78, 78, 78,224,243,249,120,242,250, 62,204, 51, 44, 80, 59,160, + 62, 4, 2, 1,178,148,153,248,110,121, 79,120, 45, 76, 70,117, 95, 64,149, 8,220,155, 4,253,251,219, 88,145, 19,131,117, 37, +126,223, 4,173, 27, 85,245, 16,226,250,101, 84, 74,140,197,131,165, 75, 81, 55, 40, 8,161, 0,104, 86, 22,124,166, 77, 67,220, +134, 13,176, 87,164, 2, 14, 21,209,218,197, 65,116, 43, 51,171, 13, 74, 89,155, 85, 38,147,193,213,213,181, 64,248,245, 25, 60, +202, 99,228,164, 81,210,110, 95,180, 4,159,111,135, 12,165, 30,169, 89,122, 88,219,201, 49,109, 82, 47,201,229, 58,174,117, 55, +173,217,115,146, 16, 82,183, 52,225,106,194,223, 11,159,186,198,241,223,214,130, 85, 20, 98,189,222, 71,179,113, 35,148,151, 47, + 67,116,241, 34, 14,186,184,100,171,213,234,201,148,210,152,188,194,110,194,175, 59,118,220,234,124,231,142,133,246,213, 43,120, + 60,127, 14,129,149, 85, 77, 99, 31,156,111,189,210,104,114,191,253, 93,187,118, 33, 51, 51, 19,153,153,153, 48, 24, 12,198,191, +128, 16, 77,156, 28, 42,227, 61,194,192,241, 25,121,164, 79, 78, 3,185,218, 60,222, 53,218, 81,153,201,184,226, 85, 84,125,153, + 42, 85,219,128,240,180, 80,167,228,192,181,113, 85,240,193,111, 82,158, 72,202, 47, 40,249,124,126, 90,104,104,104, 39,111,111, +239, 83, 0,236, 62,181,191,159, 82,250, 6,192,184,143,185,151,199,227,205,121,251,246,173,195,182,109,219,198, 44, 88,176,128, + 22, 22, 88,249,255,249,124, 62, 40,165,176,180,180,132, 64, 32,112,188,125,251,182, 99,253,250,245,215, 1,168, 89,138,152,132, +131,131, 3, 68, 34, 17,204,205,205,161, 84,164,203, 54, 44,158,213,194,204,218,209,102,202,148, 41,204,144, 33, 67,194,215,173, + 91,231,238,228,227,227,251,236,217,179,168,206, 61,123, 61, 58,123,246, 44, 0,108, 54, 50,232, 79,159, 63,127, 46,242,242,172, +196,231,244, 42, 78, 38, 4, 36, 79, 87,115, 34,115, 39, 72,120, 60,240, 9,168,212, 76,230,240, 38, 50, 50, 30, 64,146,145,241, +248, 36, 44, 44, 76,224,230,226,200,207, 82,170, 51,100,124, 78,244,246,193,253,151, 85,234,214,243, 3, 0,245,131,219,199,196, + 62, 1,230,111,147,146, 45, 60, 60, 60,140, 26,127,103, 48, 24,158,190,123,247, 78,232,234,234, 42, 8, 11,123,179,199,214,194, +220,197,198,209,177, 5, 0,104,211,146,111, 18,149, 58, 94, 32, 16,184,198,191,127,159,108, 48, 24,226,141, 13,103,104,104,168, +208,205,197,145,127,234,204,217,253, 78, 50, 51,103, 43,169,216, 82,194,128, 72, 40,151, 41, 50, 24,222, 75,205,100, 46,111,163, +163, 83, 40,165,177, 37,241,108,224,198, 12,204,205, 3, 83,182, 22, 62,254,251,239,191,227,218,195,183,176,228,177, 16,232,149, +184,123,244, 32,186,143,157, 88,230,247, 20, 50,213, 23,208,252,180,207,191,202,144, 15,132, 83,110, 23,160,115,177, 66,168, 76, +129, 85, 22, 54,249, 93, 47, 34,178, 16, 31, 95,122,225, 58, 96,192,128,121,187,119,239, 46,152,196,241,242,229, 75,180,106,213, + 10, 0, 48,111,222, 60,180,107,215, 14,245,235,215,199,203,151, 47,225,229,229,133,171, 87,175,138,121, 60,158,120,224,192,129, +139, 1,156, 45, 43, 72,155, 55,111,198,176, 97,195,138, 27, 48, 29, 14, 64, 77,172,125,179,167, 47,221,105,151,150,154,130,164, +228,247, 79,140,125,213, 5, 11, 22,128,227, 56, 28,221,186,213,209,246,201, 19,215, 33,149, 43, 59, 28,230,184,164, 48,119,247, +184,175,218,183, 79,196,154, 53,198, 52,168,254,100,197,177,181,181,133, 80, 40, 4, 79,224, 2,190, 40, 16,140, 80,136, 90, 77, + 3,177,124,178, 44,103,240, 87, 88, 67, 8, 50,196, 34, 60, 22,154,225,125, 73,156, 6,131, 1, 2,129, 0, 7,207,239,192, 51, +171, 61, 64, 22,112,235,113, 23, 76, 28, 54, 19, 83, 87,141,128,247,226,100, 88,122, 3, 73,119,129,251,147, 24, 46,243, 29,247, +181, 38, 25,231, 40,165,169, 37,133, 85, 15, 84,119,181, 48, 7, 98,163,209, 74, 12,252, 54,103, 58, 94, 0, 8, 8, 10, 2, 0, +196,109,216, 0,245,236,233,240,240,169, 4, 72,165,240,150,202,160,126, 30, 86,189,180, 70, 57,199,113, 5,227,172,118,237, 61, +100, 87,179,153,135,164,109, 19,127,236, 60,181, 8,223,246, 90, 3, 1,143,128,101,117, 88,177,170, 35, 88, 77, 54,122,117, 30, + 65,154,183,241, 10,188,124, 74,251, 53,128, 45, 38,233, 98,194,255, 2, 76, 94, 6,110, 78, 8,161,132,144,230, 5, 45, 59, 74, + 57, 67, 90, 26,104,158, 0, 18, 8, 4, 20, 64,225, 25, 74,102, 86, 86, 86, 68,224,230, 6, 34,206,109,112, 83,224,147,157,238, +241,249,124,176,172,241, 52, 28, 11, 30,136, 14,180,144,177, 67, 41, 33, 88,100,215, 26,227, 68,179,241, 94,100, 85,184,134, 3, + 12, 20, 44, 56, 94, 57,131, 69,149, 74, 37, 12, 6,131,181,167,167,231, 25,131,193, 96,157, 87, 97,254,207, 90, 70, 44,203, 70, +240,120, 60,140, 25, 51,166,192,218,167,213,106,241,254,253,123,104, 52, 26,104,181, 90,188,125,251, 22,153,153,153,208,106,181, +120,241,226, 5,170, 84,169, 2, 30,143,231, 92,106,124,114, 28,236,237,237,225,232,232, 8,141, 82, 33, 59,178,121, 85,135,159, +230, 78,183,235,231, 73,153,109,107,126,230,220,220,220, 82, 3, 2, 2,156,196, 98,177,174,118,237,218,154, 83,167, 78, 93, 4, +208,189, 28,126,176,206,206,159, 63,191,126,253,250,245, 43, 89,201,101, 58,177,136, 7,177, 65, 73,197,154, 84,202, 87,165,208, +138,110,149,116,144,201,235,245,233,211, 71,100, 76,165,152,207, 57,117,234,212,170,126,126,126,118, 86, 22, 50, 5,159, 65,156, +144,101,227,210, 31,222,190, 4, 0, 66, 59, 7, 21,100,242,122,121, 99,232,140,230,156, 54,109, 90,128,171,171,171, 45,195,144, + 12,131, 78, 23, 85, 80,224,171, 85,137, 60,177, 68, 9,177,164,233,240,225,195, 5,229,228,244,171, 81,163,134,173,181,165, 69, +134,128, 33,209, 66,214, 16, 35,165,108,172, 72,175, 75, 22, 59, 56,102, 67, 38,111,220,175, 95, 63,126, 73,156,249,214,171,162, +150, 33, 62,159,143,184,184, 56,228,196, 63,131, 48,238, 21, 2,229, 2, 52,112,178,131, 76, 38, 43,187,193, 50,242, 37,193,200, +151, 36,228, 45, 37, 33,111, 41, 41,188,255, 39,107,211,252, 76,124,112, 93, 9, 40, 58, 62,235, 79,226,170,200,189,121, 34,171, +212,239,105,207,158, 61, 51, 90,182,108,153,212,174, 93, 59,237,153, 51,103, 64, 8,193,213,171, 87, 17, 23, 23,135,118,237,218, +129, 82,138,187,119,115,141,179, 79,158, 60, 65,155, 54,109,180,205,154, 53,139,219,179,103,207, 28, 99, 18,103,216,176, 97,208, +235,245,200,206,206, 70, 90, 90, 26, 78,159, 62,141,192,192, 64,106,102,102,214,157, 87,225,139, 69,189,190,158,209,168, 90,141, +154, 88,183,102,185, 86,196, 23, 44, 45, 71, 99, 8,167,119,239,118,180,124,248,208,181,131, 86,235,112,130,199, 75,138,246,242, +138,107,212,190,125, 98,121,138,144,124, 43,142,155,155, 91,129,184, 18, 10,133,224,139,236,193,147, 85,135,200,182, 29,204,156, +186,227,218, 99,177,198, 82,134, 99,230,114,156,151, 89,225,121, 41,126,176,136,193, 96,128, 80, 40,196,245, 71,231, 16, 56, 19, + 8,156, 9,196,215, 59,129,190, 19,191,132,221,184, 80, 88,122, 3,239,127, 3, 50,150, 7, 66,255,214, 82,161, 73,198,193,210, +196, 85, 65, 57,146,145, 14,228, 13,234, 23, 22,105,201,243, 1, 8,120, 60, 16,169, 20,144, 72, 1,177,164,204,254, 10,150,101, + 11,198,131, 93,191,123,211,182,111,143,142,228,246,211, 75,104, 28,216, 15,169,217, 58, 36,102,234,144,145, 3, 4,212,157,133, +106,109,142,225,217,219, 44,212,172, 81,141,199, 19,201, 6,195,132,127, 12,138,211, 34,255,120,129, 5,224,122,209,129,101, 6, +177,248,133,225,187,239, 96,117,242, 36, 4, 97, 97, 24, 58,120,176,133,153,153,217, 26, 66, 72,109, 66, 72, 99,185, 92,190,110, +238,220,185,230,118, 75,150,192,229,230, 77, 68,158, 62, 13,189, 64,240,160, 60, 15, 87,169, 84, 5, 22,162,124, 75,150,149,149, + 85,185, 44, 88,172, 1,119,226, 18, 95, 65,132, 74,224, 64,179,207, 43,154,221,235, 23, 49,203,225,180,162,138,215, 27,165,208, +107,190,125, 3,135, 53, 21,155,220, 83, 18,126,182,200, 74,130,232,232, 24,176,224,238,148, 39,156,106,181, 58, 83,169, 84,162, +102,205,154,182, 15, 31, 62,244, 12, 12, 12,180,201, 59,126,255, 19, 51, 83, 67, 87, 87,215, 67,110,110,110,239, 92, 93, 93, 15, + 17, 66, 26,150,227,246,109,191,253,246, 27,120, 60, 30,230,206,157,139,172,172, 44,232,116, 58,164,166,166, 34, 58, 58, 26, 90, +173, 22,177,177,177,120,253,250, 53,180, 90, 45, 34, 35, 35, 11,226,184, 52,232,245,122,152,155,155, 35, 35, 53, 73,118, 96,195, +207, 29, 22,206,157, 41,205, 12,127,132,216,248, 68,112,172, 42,126,217,178,101,175,189,188,188,174,232,116,186, 10, 28,199, 53, +167,148,110, 50, 86,104,230, 57, 42,253,221,215,215,183,254,178,101,203,154,207, 94,186, 85,108,206,203,162, 34,115, 49, 39, 50, + 23, 81,145,111, 3,124, 61,103,173,100,233,226, 5, 79,158, 62,125,154,102,228,204, 60, 6,192,239, 13, 26, 52, 8,120,255,254, +125,147,192,192,192,154, 78, 85,189, 37, 98, 87,151, 20,145, 75,197, 84,170,202,185,204,184, 87,238,180,102,205,154,135,119,239, +222, 77, 44, 15,167,171,171,107,245,245,235,215,215,117,119,119,175, 43,177,180,148,102,103,100,108,214,100,164,109, 21,216, 57, + 73, 25, 91,187, 94,187,118,237,186,115,241,226,197,148,242,112,250,251,251, 87, 91,188,120,113,237, 90,181,106,213,118,246,246, +145, 72, 93,221,146,133,174, 21,147,164, 53,234, 72,152,138, 30, 61, 87,173, 90,117,239,193,131, 7,201,198,112,242,249,124,150, + 97, 24, 8, 4, 2,200,100, 50,220,184,113, 3,253,186,127, 9, 39, 7, 11,120,251,248,160,197,200,177, 56,115,230, 12, 68, 34, + 17, 24,134, 1,195, 48,250, 79, 45, 48,140, 17, 66,101,161, 36,241, 85, 22, 55,165,244,236,245,235,215,127, 28, 50,100,136,168, +125,251,246,184,119,239, 30,134, 13, 27,246,251,209,163, 71, 1, 0,247,238,221,195,196,137, 19,127,191,114,229, 10, 70,141, 26, +133, 86,173, 90,137,126,251,237,183,117,198,204, 34, 52, 24, 12,216,190,125, 59, 12, 6, 3,228,114, 57,108,108,108,208,177, 99, + 71, 4, 7, 7,143,250,245,215, 95, 95,241, 4,130,254, 29, 58,247,192,153,147, 71,241,250, 69,240,168, 29,139, 7, 26,229,204, +151, 82,138, 99,219,183, 59, 74,126,255,221,181, 93, 78,142,195, 89,177, 56, 41,218,203, 43,174,113,135, 14,137, 86, 86, 86, 70, + 55, 38, 9, 33,132,101,217, 2, 81,149, 47, 54,242, 55,190,200, 30,124, 89, 53,240,205,235,226,217, 27,161, 94, 80,143, 62, 22, +214,161, 47, 75,115, 50, 74, 8, 1,199,113, 16, 8, 4,168, 85,181, 49,222,228,205,139,172, 58, 16,168,189, 51, 21, 14,141,114, +187, 5,163,150, 57,224,251,225,243, 32,224, 9,245,198,184,206, 17, 0,207,195, 35,222, 2,114,115, 60,215, 2,150,243,150,192, + 39, 40, 8,113, 27, 54, 32,254,199, 31,225, 56,122, 52, 44,231, 46, 68,122, 68, 44, 32,149, 34, 52, 71, 13,137, 64,240,188,172, +120,204,159, 53,152,166,136, 20, 87,118,169,142, 64,191,145,176,182,174,129,184, 52, 45,226,211,180,216,186,161, 43, 30,253,182, + 16, 15, 47, 14, 66,212,251,247,144, 58,117, 3,107,208, 84, 51,201,150,127, 20,174,255,155, 6,185, 51,133, 62,182,130,130,205, +211,198,198, 92,175,215,197, 94,186,116, 73,199, 48, 12,204,204,204, 48,100,216, 48,102,195,250,245, 77,251, 53,108,120,117, 68, +219,182,231,174, 94,185, 82,171,126,253,250,160,148,130, 97, 24, 28, 56,112, 64,165, 86,171, 82,221,221,221,173,140,125,120,114, +114,114, 65, 11, 47, 39, 39, 7, 28,199,193,194,194,162, 92,174, 10,148, 10, 92,190,114,254, 81, 58,101,191,141,110,255,102,165, +110,233,251,174,245, 51, 56,150,159,201,234,145,169,162,200, 82,131,127,143,177,169, 63,196,171,155,238,109,155,250,175,111,188, +186,157,170,102,213,229,154,253,144,148,148, 52,179, 87,175, 94,169,206,206,206,196,194,194, 2,174,174,174, 76,151, 46, 93, 82, + 98, 98, 98,230,127,108,196,219,217,217,245,109,217,178,229,169,184,184,184,158, 55,110,220,168,116,243,230,205,158, 45, 91,182, + 60,101,103,103,215,215, 72,138,131, 51,102,204, 80,138, 68, 34, 52,104,208, 0, 89, 89, 89,208,106,181,101,110,101,182, 60, 57, + 14, 18,137, 4,135,182,174,250, 98,225,220,153,210,180, 87,247,240,236,247, 75, 56,255, 78,147, 51,103,233,234,187, 18,137,228, +163,222,215,203, 65, 86,189,186,139,249,203,137,195,250,196, 79, 15, 10, 50,127,254,252,185,116,220,248, 9,136, 76,204,160,162, +246, 43,120,104, 62,155,121,170,180, 35, 29,190,106,133, 31, 23,255,208, 28,192,168, 50, 43,106, 7, 89,245,106, 46,230, 33, 83, + 70,244,139, 24, 63,126,188,116,233,210,165,234,122,245,234,233, 19, 18, 18, 44,229,118, 14,117, 4,182,118, 13,223,189, 79,180, +170, 83,183,238,155,241,227,199,171,203,203,249,195, 15, 63,152,221,186,117, 75,216,186,117,107,154,148,148,100, 45,148, 74, 27, + 9,204, 45,155,199,167,164,216,180,105,211,230,205,208,161, 67,217,143,225, 12, 13, 13, 21,214,169, 83,135, 38, 36, 36, 88,155, +217,218, 55, 16,218,218, 55,123,155,240,222,186,102,173, 90, 97, 19, 39, 78,212,151,198,217,107,237, 31,226, 68, 46,151, 39, 4, + 6, 6, 98,206,156, 57, 88,176, 96, 1,122,247,238,141,119,145,239,208,124,232, 8, 84, 25, 50, 10,167,239,222, 71,124,124, 60, +102,206,156, 9, 47, 47, 47, 8, 4,130,176,207, 81,104, 24, 35,178, 74,234, 62,244,175, 66,174,151, 54,206,170, 44,238,158, 61, +123,126,215,187,119,111, 28, 60,120, 16,195,135, 15,255,125,205,154, 53, 77,134, 15, 31, 14, 0,104,208,160, 1, 22, 46, 92,216, +100,214,172, 89,191, 47, 90,180, 8,173, 91,183,134,135,135, 71,153,254,196, 88,150,133,193, 96, 64,191,126,253, 96, 48, 24,144, +156,156,140,208,208, 80,108,222,188, 25,148, 82, 9, 0, 56,187,184,213, 17,137, 68,120,250,248, 65,206,236,225,245,247, 24, 27, + 87,199,182,111,119, 52,187,125,219,245, 75,149,202,225,130,153, 89, 82,122,173, 90,113,181, 91,183, 78, 36,132,192,220,220,188, + 60, 2,171, 64, 12, 21,118, 75, 80,116,203,159,160, 98,116, 15, 64, 30,231,168,126, 19, 33, 57,223,180, 64,100,201, 43, 2,156, + 1,120, 20, 36,192,152,110,115, 16, 88,189, 38, 24,134, 49, 74, 88, 43, 41,174, 92, 12, 13,215,194,206, 30,169,182,206,240,206, + 19, 87,154, 89,211,192,173, 90,134,244,165, 75, 97, 57,122, 52, 24, 11, 27, 64, 34,197,149,216,247,218, 28,189,161,196, 50, 57, +127, 92,105,254,187,103,167, 17,176,156, 8,183, 30,159,199,197,155,135,241, 46, 46, 25, 81, 73,106,128,111, 9,181, 50, 22, 58, + 85, 28,180, 25,143,161,208,152,153,228,202, 63,211,138,245,175, 25, 51, 87,156,163, 81, 80, 11,105,159,195,235, 54, 88,246,234, + 55, 80, 25, 24, 24,104,237,234,234, 10, 66, 8,186,118,235, 70, 90,222,184, 97, 46,112,113,129,109,237,218, 5,222,115, 47, 95, +186,132,243,231,207, 43,207, 28, 63,230, 58,236,235,175, 59, 1,165,186,213, 41,136,188,148,148, 20, 56, 58, 58,130, 97, 24,136, +197, 98,196,197,197,193,217,217, 57,215,236,205,231, 11, 8, 33,124, 74,105, 89,230,172, 93,211,131,238, 6, 37,213,159, 89,165, +190,185,128,156, 83,190, 7, 75, 41, 4,132, 5, 84, 20,122, 22,208,232, 41,234, 84,230,217, 92, 84, 25,172, 79,223, 59,250, 22, +192,174,114, 90,176,174, 17, 66, 70,114, 28,119, 24, 0,115,227,198, 13, 46, 36, 36,228, 59, 99, 7,164, 23, 7, 51, 51,179,169, + 87,175, 94,181,153, 58,117,106,250,233,211,167, 51, 59,118,236,104,185,121,243,102,155, 86,173, 90, 77, 5,176,223,136,150,177, +138, 16,178, 51, 38, 38,230,187,186,117,235, 34, 45, 45, 13, 58,157, 14,143, 30, 61,130,151,151, 23, 30, 62,124, 8,111,111,111, + 60,120,240, 0, 62, 62, 62, 96, 89, 22,106,181, 26, 28,199,149, 89,162,199,199, 68,201,205, 52,233, 22,241,247,206, 33,244,249, + 35,156,141,208,228, 44,219,126,224,108,245,154,117,148,229, 45,192, 1,192,199, 81, 22,224,234, 96,123,113,233,188, 31, 28, 34, +175, 29,192,209,237,107,185,235,231,206,249,139,204, 49,178, 69,223,241, 61,180,122,184, 3, 16, 55,170, 95,151,126,101, 21,202, + 73, 43,225,253,149, 23,165,123, 50,247,113,148, 5,184,216,219, 94, 88,182,100,190,121,248,249, 29, 56,184,105, 5, 61,178,123, + 95,160, 26,168, 95,189,122,245,246,132, 16,103, 0,134,188, 52, 50,106, 9,154,226, 56,175,156, 62, 93, 75, 13,212,247,244,244, +108, 47, 16, 8, 42,229, 89,249,226, 62, 7,103,141, 26, 53,218, 19, 66,220,115,147,147,198,162,156, 75,229, 12, 31, 62,124,249, +148, 41, 83, 38,234,245,122,219, 66, 22, 72,222,230,205,155,249, 44,203, 50,148, 82, 29,195, 48,186, 11, 23, 46,176, 6,131, 33, + 94,173, 86,143,254,212, 2,163, 71,143, 30,184,123,247,238, 60,228, 78,176, 40, 19,105,105,105,124, 27, 27, 27, 67, 89,194,203, + 88,238, 27, 55,110, 44,232,223,191,255,244,253,251,247,135,174, 89,179,166,243,168, 81,163,112,224,192, 1, 84,173, 90, 21, 79, +159, 62,197,204,153, 51, 1,160,201,172, 89,179, 78,110,219,182,205, 35, 50, 50,114,185, 49, 86, 91,131,193,128,125,251,246,161, +107,215,174,176,183,183,135,139,139, 11, 8, 33,215,190,254,250,235,245, 0,192, 35, 60, 33, 0,104,212, 26,141,175,111, 93, 99, +156,140,146, 74,150,150,174,102,183,111,187,126,161, 84, 58, 28, 5,146,244,117,234,196,117,236,219, 55, 49, 50, 50, 18, 9, 9, + 9,112,114,114,202, 47,235,120,132, 16,166,172,110,246,124, 43, 78, 89,226,170, 28, 22,101,228,143,109,114,116,116,196,172, 49, + 75,176,100,195, 44,188,193,117, 84, 29, 0,188, 88, 9,116,245, 24,139,186,129, 13,224,226,226, 98,124,175, 2,176,230,116,100, +204,248, 47,164, 2,123, 79, 78,141, 39, 85, 61, 97,153,158,140, 42, 94,238, 32,102, 50, 40,118,108, 70,230,238, 93, 48,147, 75, +112, 63, 93,129, 43,111,163,178,178, 13,134, 85,165,133, 19, 64,129,207, 43,247, 10,222,234,215,145,217,102, 73,113,183,240,251, +111,199, 81, 53,112, 2,164, 78,157, 96,227,187, 8,186, 87,171,161, 77,189, 8,155, 10, 29, 17, 27, 25, 14, 30, 95, 28,108,146, + 44,255, 44, 20,214, 34,255, 26, 11,214, 7, 25,154, 35, 2, 31,111,111, 86,200,224,215,174,157, 58,229, 60,121,242,164,160,149, +167,190,127, 31,202,243,231,193,178, 44, 40,165,184,121,227, 6, 6, 13, 28,152, 45,224,145,173,149, 43, 87,162,132,254,225,123, +133, 16,242, 39, 95, 86,154, 66,253, 84, 42,149, 10, 42,149,170, 96,208,102,114,114, 50, 68, 34, 17,164, 82, 41, 26, 54,108, 72, +120, 60, 94,175, 98, 62,182, 54, 69, 18, 67,207,166, 41,123,110,235, 48, 32,193, 37, 91, 71, 71, 90, 85, 70, 69,161,180,224,163, +116,178, 32,232, 28, 40,128, 29, 63,137, 94, 89,222, 54,158,211,164,246,164,148,234, 75,227, 44,230,153,222, 53,106,212, 88, 63, +104,208, 32, 6, 0,218,180,105,195,212,168, 81,227, 23, 66,136,119, 41,247,148,202, 41,145, 72,196, 0,112,234,212,169,180,208, +208,208, 47, 79,157, 58,149, 86,248,184,145,156,155,127,250,233, 39,152,153,153,193, 96, 48, 64,171,213, 22,140,191, 42,252,171, +211,233, 96,103,103,135, 51,103,206,128,101,217, 51,101,133,211,175, 90,141,236, 76,190, 85,226,206, 83, 87,113, 46, 82,151, 93, + 94,113, 85,152,179,170,179,220,199,201,206,246,210,178,197, 11,236,211,223, 60, 66,108,108, 44,189,112,254,204, 29, 21,165,113, + 25, 10, 58, 59, 61,155,250,228,104,168,180,158, 7,162, 47,109,154, 70,103, 53,131, 30,228,207,179, 7, 11,115, 6, 56,203,125, + 92,237,109, 47,252,188,108,177,121,198,155, 71, 72,120,255, 30,103,207,156,122,162,162, 52,142, 82,122,132, 82, 58,148,227,184, +234, 28,199, 85,167,148, 14, 45, 73,180,148,151, 83,167,211, 85,215,233,116,159,149,179,188,225, 44, 52,131, 16,243,230,205, 11, +139,141,141, 29,149,152,152,216, 35,127, 75, 75, 75,235,154,149,149,213, 49, 39, 39,167,189,106,101, 37, 75,165, 82,233,144,149, +149,229,172, 82,169,234, 80, 74, 31, 25,155, 63,139,162,112, 5, 27, 31, 31, 63, 55, 62, 62,158,148,154, 63, 71,190, 36,235,150, +127,187,251,208,161, 67,142,159,194, 93, 52,156,201,201,201,135,247,237,219, 87,179, 74,149, 42, 30, 67,135, 14,197,198,141, 27, +177,102,205, 26, 13, 0,108,219,182, 77, 83,200,114, 85,225,221,187,119,117,139,235, 30, 44,204,201, 48,204,174, 47,190,248,130, +222,188,121, 19, 93,187,118,133, 94,175, 71, 76, 76, 12,182,108,217, 2,131,193,160,104,221,186, 53, 7, 0, 42,117,142,130,114, + 20, 90, 93,241,253,236,133, 57, 9, 33,196, 23,232, 52,212,217,185,210, 23, 74,165,195, 69,153, 44,233, 77,197,138,113,109,123, +247, 78, 20, 10,133,144,203,229, 5,101,157, 88, 44, 70,189,122,245, 8,159,207,111, 81, 6,231, 7, 86,156,162,219,199,124,155, + 5, 93,122,121, 28,110,110,110, 88, 48,121, 5,220,238,247,192,181,166,182,168,153, 58, 20,237,154,118,134,143,143, 79,185, 56, + 67, 40, 85,170, 40,250, 76, 12,141, 86, 37, 73,197,168, 41, 97, 81,185,106, 5, 16,169, 25, 32,145,194, 34, 48, 0,150,245,107, +224,137,179, 35, 38,158,187,146,163,214,235,251,132, 83,154, 85, 26, 39, 33,164,192,114,215,165, 67,155,180, 13,191,172,224, 90, + 55,255, 14,102, 82, 11,232, 5, 21,144,150,173, 71,186,146, 66, 43,174, 15,145, 80,140,118, 13, 3,112,247,194,142, 28, 86,171, +220,249,177,121,254, 99,227,211,196,105,194, 7, 22,172,252,169,145,249,191,132,112, 44,203,114,168, 92,165,178,121,228,187,232, +181,189,123,247, 26,222,190,125, 7,179, 14, 29, 58, 72, 2, 94,229,118, 81,156, 58,117, 10, 71,143, 30,205,185,120,241,162, 66, + 44,224,109,171,224, 94,193,145,101, 57, 16, 82,186,133,132, 97,152,215, 47, 95,190,116,245,243,243,131, 90,173,198,210,165, 75, +245, 65, 65, 65, 2,185, 92, 14, 74, 41, 86,174, 92,201,246,235,215,143,215,181,107, 87,243,203,151, 47,143,131, 17,107,253, 81, + 74,159, 17, 66,218,173,111,217,253,104,221, 49,195,108,253, 91, 54,178,110, 81,193, 21,250,218, 20,241, 49,239, 16,122,229, 98, +250,139, 11,171, 82,161, 78,236, 78, 41, 13, 41,111, 36,185,184,184,204,185,120,241,162,195,216,177, 99,169, 90,173, 38,209,209, +209,116,241,226,197, 14,223,124,243,205, 28,148,225, 11,167,180,252,153,145,145, 1, 66, 8,151,151, 89,243, 91,175, 70, 79, 83, +165,148, 6, 19, 66, 78,116,235,214,173, 75,235,214,173,241,234,213,171,130,174,192,194, 2, 43,127, 54,225,146, 37, 75, 50,128, + 63, 28, 4,150, 4,177, 88,140, 45,135,207,159,139,143,141, 50,171, 92,217, 83,109,105,109,205,125,140,229, 10, 0, 68, 12, 51, +247,199, 5, 63, 56,164,188,188, 75,130,239, 92,229, 14, 61, 75, 76, 50,176,116, 76,177, 23,103,197,211, 60,213, 95,122,235,133, +225,205,253,113,241,124,203,252,238,203,253,143, 19, 20,132,165, 99, 63,173,169,241, 15,225,252, 31, 32,119,134, 95, 60,113,113, +113,161,249, 93,120,197, 9,172,178, 80, 92,247,224,199,114,191,125,251,118,113,237,218,181,167,132,133,133, 29,242,247,247, 31, + 5,192, 93,163,209,100,204,154, 53,107,217,182,109,219,134, 27, 99,185, 2,128, 3, 7, 14,172, 26, 54,108,216,249, 78,157, 58, + 77,227, 56,174, 70,161,202,227,173,131,131, 67,129, 71,174,228,196,247, 65, 35,135,247, 11,202,206, 78, 47,211, 79,157, 47,208, +114, 90,141, 26, 67, 7,120,120,184,157,224,241,146,184, 70,141,226, 2,157,157, 19, 87,175, 94,205, 78,154, 52,137,103,105,105, + 9, 0, 88,191,126, 61,237,221,187, 55,233,209,163,135,217,181,107,215,250, 0,184, 90,150, 21,167, 56,203, 21,159,207,255,216, + 10,242, 3,129,149, 47,178,230, 76, 92,138,184,184, 56, 8,133, 66,120,121,121, 65, 36, 18,149,155, 59,132,210,235,254,132,116, +252,246, 93,226,129,214, 54,230,230,173, 29, 5, 34,111,169, 57, 64, 9, 66, 83,210,113, 37,238,149,246,202,187,168, 44,181,222, +208,167, 52, 47,238, 0,192,178,108,146,183,183,119, 65,247, 17, 33, 36, 85,161, 33,150, 7,253,234,203,135,142, 60, 68,126,127, +112, 27,241, 58, 14, 26, 61,135,202, 85,106,161,197,151, 43,113,242,220,115, 54, 62, 50, 36, 68,175, 74,223,106,170,230,255, 89, +214,171,194,191,255, 10,129, 85, 20, 28,143,185,181,113,211,134,175, 14,236,219,239,196,227, 49, 78,225, 17, 17, 15, 58,119,239, + 25,119,233,210, 37, 27,161,165,101, 61, 0,156,118,212,168, 59, 58,141, 42,237,244,137, 19, 21, 43, 87,174, 20,152,183,216, 51, +229,120,204,173,210, 30,152,156,156,188,118,240,224,193, 77, 79,159, 62, 45, 10, 10, 10,202,138,136,136, 56,113,227,198,141, 30, +251,247,239,151, 46, 93,186, 52, 59, 53, 53,245,192,209,163, 71,251,117,238,220, 89,175,213,106,115,202,145, 48, 33,132, 16,191, +251, 63, 44,239,127,255,167, 13,109,193,231, 53,134, 70, 0,112,250, 91,208,101, 93, 2,176,215,136,238,198, 98, 33,147,201, 2, +205,204,204,240,228,201,147,244,250,245,235,107,213,106,181,112,209,162, 69,182, 50,153, 44,240, 19, 50, 18, 77, 79, 79, 7,199, +113,124, 0, 36,239, 23, 92,249,215,202,233,219,185,115,231, 19, 7, 15, 30,252,162, 67,135, 14,240,240,240,128, 94,175,135,183, +183, 55,180, 90, 45,188,188,188,160,209,104, 48,111,222, 60,100,102,102, 78, 50,102, 17, 97,137, 68, 2,145, 72, 4, 31,191,106, + 57, 18,137, 4, 31, 43,174, 0, 64, 38, 96, 60, 94,159,222,142,164,212, 20,238,224,211,196,196, 28, 29,219, 46, 44, 73,249,162, +232,117, 57, 44,148, 45,135,142,139, 3, 0, 13,135,236, 82, 57, 69,240, 8, 61,179, 5,137, 73, 41, 56,240, 56, 33, 67,169,227, +190,124, 93, 12,103,185,194,249, 15,225,236,181,246, 21, 90,124,107,252,181,135, 70,126, 90, 1,241, 49, 66,170,160,146,125, 75, + 9, 54,249, 81,108, 90, 91,172,143,171, 79,225,206,179, 76,157,200,171,116, 99,250,245,235, 23,244,238,221,187, 5,121,254,174, + 54,149,135,107,251,246,237, 97, 0,134,149,118,205,254,229,195,142, 1, 56,102, 12,159, 25,159, 31,216,183, 74,149,118, 27, 67, + 67,111,108,203,201,145,156, 91,181, 42,181,125,251,246,170,240,240,240,187, 87,175, 94,109,188,111,223, 62,209,143, 63,254,168, + 74, 76, 76,252,237,192,129, 3,205,123,244,232, 97,208, 24, 49, 3,133, 16,242,217,196, 85, 62, 95, 97,203, 80,190,200,114,113, +113, 65,197,138, 21, 63,233,187,207, 19, 89,215, 60, 9,241,184,152,150, 61,225, 86,166,170,141,250,213,219,234, 0, 32, 17, 8, +158,231, 24, 12,151,179, 13,134, 85, 69, 45, 87,197, 33, 53, 53,117,208,159,194, 46,181,117,217,177,110,238,169, 7,191,215,243, +110,218, 97,136,180,154, 11, 7,173,142, 34, 38, 42, 28,243,102,111,205, 73,136, 10, 11,209, 25,116,221, 76, 62,176, 76,248,219, + 9,172,136,136,152, 16, 15,143, 10, 51,142, 30, 57,220,152, 82,134, 71, 9, 81, 90, 89, 89,159,138,142,142,254,192, 11,182,167, +141,141,249,176,111,134,245, 33, 28, 17, 16,194,177, 28,143,185, 21, 17, 17, 19, 82, 70,193,248,176, 99,199,142,139, 3, 2, 2, + 38,176, 44, 59, 83,169, 84,158,176,178,178,186, 87,187,118,237, 5, 44,203,206,206,202,202, 58, 97,103,103,119,114,253,250,245, + 11, 89,150, 45,151,143,168, 60, 1,181, 19,248,188, 75,171, 17, 66,230, 83, 74, 45,249,124,126,230,243,231,207,247,249,248,248, +244,163,148, 90, 18, 66, 50, 63,150, 83,173, 86,143,205,200,200,176, 27, 49, 98,132,126,243,230,205, 62, 67,134, 12, 9,122,241, +226,133, 64,173, 86, 71,148,243,157, 53,132,144, 46,189,123,247,222, 42, 16, 8, 90, 51, 12, 67, 56,142, 43,188,220, 6, 40,165, + 96, 89,246,100, 89,241, 34, 16, 8,178,191,250,234, 43,121,153, 86, 41,145, 40,219,216,240,101,105,217, 9, 27,174,190, 88,162, +214, 83,106,224,232,200,215,137,202, 98,167,144,221,127, 77, 3,140,230, 84,115, 19,214, 92, 8, 89,162,209,115,156,129,163,163, + 74,226, 44, 15,254, 41,156, 0, 48,154, 89,187, 27,155,214, 22, 12,120,207,239, 54, 44,186,255,185,145,111,105, 66,121,188, 44, +231,185, 99, 8, 25,249, 23,112, 23, 35,182,202,139,158, 61,123,178,159, 59,158, 84, 6,195,205,250,199,143, 79,215,114,220,235, +138,237,219,203,125,125,125,187,179, 44,187, 85,161, 80, 92,177,180,180, 12,169, 94,189,250,112, 0,219, 20, 10,197, 21, 71, 71, +199,155,171, 86,173, 26,201,113,220,207,101, 88,113,226,242,173, 56, 0,104,190,245, 41, 95, 64, 20, 22, 18,122,189, 62,214,152, +112,178, 44, 27, 23, 24, 24, 72, 10, 91,179,138,254, 22,134,177,188,133,145, 39,160,230,163, 20, 39,162, 31, 37,176, 85,169,241, +132,144,218, 47, 31,255, 54, 42, 52,228,113,255,252,217,130, 60,158, 40,152,213,229,236,212,171,210,183,154,196,149, 9,127, 7, +147,220, 95,182, 1,104, 99,226, 52,113,154, 56, 77,156, 38, 78, 19,167,137,211,196,249, 95,219, 76, 75,143,155, 96,130, 9, 38, +152, 96,130, 9, 38,124,102, 16, 0,109, 74,176,108, 25,237, 43,234, 99,102, 19,148,197,111,226, 52,113,154, 56, 77,156, 38, 78, + 19,167,137,243,223,199,249,159,129,169,139,208,196,105,226, 52,113,154, 56, 77,156, 38, 78, 19,167,169,139,208,212, 69,104,130, + 9, 38,152, 96,130, 9, 38,152,240,183, 6,223, 20, 5,229, 67,222,154,114,223, 2,232, 9,192, 19, 64, 56,128,195, 0,214,151, + 99,193,227,194,124, 22, 0,130, 0, 52, 6, 80, 5,192, 91, 0,191, 1, 88, 74, 41,205, 54,197,120,241,176,183,183,159, 33, 16, + 8,172, 0, 20, 44,173, 84,244, 87,175,215,103,100,102,102, 46,254,139,242, 1,143, 82,202,150, 39,172,255,139,112,154,240,183, + 45, 71,188,109,108,108,246,164,165,165, 13,160,148,134,154, 98,196, 4, 19,254,197, 2,139, 16,114, 3, 0, 40,165,205, 1,192, +220,220,252, 54,195, 48, 85,242,206, 1,200, 93, 19,170,240,126,209, 95,142,227,222,166,166,166, 54, 42,233, 97,102,102,102,183, +121, 60, 94, 21, 66, 72,254,226,179, 96, 24, 6,122,189,222,156,199,227,101,149,192, 25,155,150,150, 86,231,111, 82, 40, 18, 0, +167,173,173,173,213, 11, 22, 44, 88,223,162, 69,139, 10,241,241,241,134,169, 83,167, 54,123,250,244,105, 7, 66,200, 87,229, 17, + 89,132,144,134,132,144, 29, 53,107,214, 60, 54,120,240,224,131,245,235,215, 23,165,166,166,154, 31, 62,124,216,117,231,206,157, +143, 8, 33, 3, 40,165, 15,255,101, 21, 75,137,203, 31, 25,185, 52, 18, 0, 64, 32, 16, 88,197,199,199,155,231, 11, 21, 74, 41, + 12, 6, 3, 40,165,208,235,245, 80, 42,149,240,247,247,255,236,225,119,118,118,174, 69, 8, 89,235,229,229, 85,199,197,197,229, + 1,128,239,226,227,227,159,150, 21,214,216,216, 88,243,188,239,235,255, 37,156,255,114,113,242,181, 72, 36,250,210,203,203,171, +158, 70,163, 73,127,251,246,237,125,150,101,127,160,148,190,255, 76,252,150, 0,126, 16,139,197,245, 61, 61, 61, 43,132,133,133, +197,232,116,186,123, 0,230, 83, 74, 51, 63,135,184,106,222,188,249,239,235,214,173,179, 29, 61,122,244,239,132,144, 38, 38,145, +101,194,255, 10,238,238,238, 86, 74,165,114, 43, 33,164,150, 80, 40,116, 50, 51, 51,131,153,153,217,123,145, 72,244,196,206,206, +110,248,153, 51,103, 50,254,159,191,239, 15,180,200, 63, 94, 96,229,173,251,243,193, 82, 13,124, 62,223, 45, 50, 50,210, 33,127, + 65, 82,142,227, 10, 42,178,252,223,124,228,249, 89,130,175,175,175,174,140,138,166, 66,108,108,172,131, 92,254,135,171, 37,157, + 78, 7, 39, 39, 39, 46, 46, 46,206,161,232, 66,194, 90,173, 22,110,110,110,127, 39, 95, 38,223,218,216,216,100, 70, 71,199, 4, +170, 53,186,249,223,140,157, 62, 99, 64,207,182,214,183,111,223,230,190,250,234, 43,205,141, 27, 55,190, 5,176,214,216, 66,156, + 16,178,115,234,212,169,243, 36,102, 22,182, 87,111,135,104,118, 30, 62, 19, 87,211,187, 50,153, 52,105, 18,111,220,184,113, 55, +107,213,170,181,135, 16, 82,187, 60,150, 44,115,115,243,243, 98,177,184, 18,143,199,131, 78,167,139, 78, 75, 75,251,226,111, 84, + 49,214, 4,240,152, 16, 82,139, 82,250,196,216,115,165, 65,161, 80, 20, 44,185, 84,120,243,245,245,253, 43,194,207,175, 80,161, +194,137, 37, 75,150,184,190, 79, 72,192,138,149, 43, 27, 0, 88, 15,160,129, 49,247, 39, 37, 37,253,191,132,243, 95, 46,174,130, +230,205,155,183,164,127,255,254, 96, 89, 22, 42,149,202,229,205,155, 55, 1,179,102,205,234, 70, 8,169, 71, 41,141,248, 68,126, +123, 47, 47,175, 87, 19, 38, 76,176,169, 87,175, 30, 24,134, 65,102,102,166,203,111,191,253,214, 96,219,182,109,131, 8, 33,190, +148,210,228, 79,121,134,141,141,205,158, 45, 91,182,216,154,153,153,225,228,201,147,182,173, 91,183,254,141, 16,210,244, 99, 69, + 22, 33,132,177,181,181, 29, 7,160, 21,199,113, 34, 0,247,210,211,211, 23, 82, 74,117,166, 28, 99, 66,105,176,179,179,251, 58, + 43, 43,107,157, 68, 34, 17,218,216,216,192,204,204, 12,124, 62, 31, 66,161,208, 93, 46,151,187,243,249,252,246,157, 58,117,250, +238,212,169, 83, 91,255,159,190,239, 63,105,145,127,133, 5,139, 82,122,163,200,139, 66, 42,149,226,224,193,131,224,241,120, 31, +172,226, 94,220,127,119,119,247, 50, 31,150,111, 1, 59,117,234, 20, 44, 44, 44, 96,105,105, 89, 80,193,136,197, 98, 92,185,114, + 5, 2,129, 0,124, 62, 31, 2,129, 0,117,234,212, 41,214,225,221, 95,137, 94, 1,185,139, 76, 22,231,188,177,169,167, 20, 61, +199,205,237,147,163,214,213, 5,160,204, 72, 79, 79,127,112,244,104,124, 77,111,111,225,158, 61,123,234,185,186,186,246, 52, 86, + 96, 1, 8,170, 93,187,246, 17,158,212,210,110,240,144,161,131,135,243, 25,221,160,145, 83, 22,197, 36,164, 40, 71,140, 24,113, +244,228,201,147,131,127,252,241,199,151,223,127,255,125, 16,128,153,198,134, 95, 36, 18, 85,122,243,230,141, 23,199,113,168, 94, +189,250,223,102,185,129,124, 1, 69, 41, 5, 33,228, 3, 33, 85,218,185,210,192,113, 92,193,210, 64, 69, 55,189, 94,143,207,237, +103,208,213,213,213,119,224,192,129,118,105, 41, 41, 88,177,114,101,254,225, 58,101,117, 23,230,119, 5,106,181, 90,244,232,209, + 99, 32,203,178,252,252,176,105, 52, 26,109,102,102,166,186,208, 76,157,100, 74,105, 91, 35,226,179,138, 76, 38, 91, 6,160,150, + 74,165,114, 5, 0,153, 76, 22,199,113,220, 49,165, 82, 57,147, 82,170,250,200,116,170, 0, 32, 0, 37, 47,217, 68,151, 44, 89, + 18, 22, 20, 20, 20,241,255,205, 73, 8,169,228,232,232,184,184, 87,175, 94, 56,115,230, 12,206,158, 61,171,151, 74,165,252, 33, + 67,134,144,239,190,251,206,122,194,132, 9,237, 1,172,254,196,100,110, 63,111,222, 60, 27, 63, 63, 63, 28, 62,124, 24,207,158, + 61, 83,121,121,121, 73, 91,180,104, 1, 62,159,111, 51, 99,198,140,175, 0,236,248,148, 7,164,165,165, 45,156, 50,101,202,206, +125,251,246,153,191,125,251, 22,107,215,174,181,235,211,167,207, 13, 66, 72,115, 99, 69, 22, 33, 68, 12, 96, 28,128,150, 60, 30, +175,233,144, 33, 67, 12, 99,199,142, 21, 48, 12,163, 95,185,114,165,253,182,109,219,250,216,217,217,213, 74, 73, 73, 49, 13, 51, + 40, 5, 60, 30, 79,199,113,156, 0,128,132, 82,170, 41,107,255,223,244,238,182,182,182,163,211,211,211,215, 59, 59, 59,195,193, +193,225,131,186,214, 96, 48, 32, 51, 51, 19, 98,177, 88, 88,161, 66,133, 45,253,251,247, 23,236,221,187,119,195,255, 71,184,138, +106,145,127,133,192, 42,169, 98,200, 95, 72, 52, 95, 72,229,139,159,162,255,243, 69, 89,145,136,186, 92,164, 80, 32,217,217,217, + 5,226,202,194,194, 2,121,149, 42,244,122,253,159,120, 89,150, 69,209, 85,181,141,153,254, 73, 8, 25, 13,224, 10,165, 52,220, +200, 4, 45,224, 60, 52,198, 23, 59,197, 83,251,229,187, 60,111, 63, 37,247,119, 39,128,219,239,134,175, 93,215,188,185,235,184, +217,107,230,170, 82,227, 83,102, 12,236, 84,201,203,201, 86, 42,203, 72,202,180,241,241,105, 7,192, 80,142,112, 54, 27, 60,120, +240,174,139,119, 35,137, 68, 34, 20,242,121, 60, 65,147,234,222,182, 21, 44,121,150,230,128,101, 76, 68,216,237,161, 67,135, 86, +255,254,251,239,155,150,231,221, 25,134,129,133,133, 5,118,237,218, 5, 38, 95,209, 26,249,238,159,241, 3, 41,154,238,252,124, + 1,149,150,150,134, 51,103,206,160, 67,135, 14,143, 9, 33,181,242, 46,121, 76, 41,133, 66,161, 64, 66, 66, 2,156,157,157, 31, + 19, 66, 4,133,187, 11, 75, 10,167, 94,175,135, 94,175, 71,255,254,253,255, 36, 92, 20, 10,133,186,200, 20,227, 15,196,139,177, +239,238,226,226,114, 17, 64, 91, 30,143, 7,173, 90,173, 93,246,243, 7, 78,183, 31, 22, 22, 87, 37,113,230,119, 9,178, 44,203, +127,248,240,161,160,208,250,110, 2, 0, 50, 0,118, 44,203,130,207,231, 63, 55, 34, 62,125,205,204,204,110,159, 58,117,202,162, + 78,157, 58, 68, 36, 18,193, 96, 48, 32, 56, 56,184,194,143, 63,254, 56,242,242,229,203, 95, 17, 66,252,139, 46,106,110,100,186, + 7,252,246,219,111, 74, 15, 15, 15,182, 4,139, 33,223,219,219,187, 57,128,136,255, 1,103,108, 98, 98, 98,215,182,109,219,142, +122,255,254,253, 43,131,193, 48, 13, 64, 53, 59, 59,187,199,221,187,119,135, 84, 42,109,105,140,192, 42, 45,221, 29, 28, 28,186, + 52,106,212, 8,107,215,174,197,143, 63,254,216,134, 82,122,133, 16,210, 90,161, 80, 92,238,220,185, 51,172,172,172,186, 22, 39, +176,140,205, 75,132, 16,239,102,205,154,109,153, 63,127,190,249,153, 51,103,224,229,229,133,172,172, 44, 76,158, 60,217, 97,206, +156, 57,215, 9, 33, 45,242, 69, 86, 73,156,132, 16,127,177, 88,188, 99,223,190,125,114, 15, 15, 15, 15,161, 80,200,120,120,120, + 32, 45, 45, 13,106,181, 90,188,104,209,162,234, 82,169,244,233,234,213,171,119, 0,232,254,255,253,189, 23, 9,107, 38, 0, 11, + 0, 86,229,233, 94, 45,229,221, 51, 1,136, 11, 62, 30,129, 0, 18,137, 4,146,255, 99,239,186,195,163, 42,214,247, 59,231,156, + 45,201,182,108,122, 33, 33, 9, 74, 72,104,129, 68, 18,185,161, 10, 10,151,114, 5, 46,197,138,136,138, 8, 10,138, 2,130, 72, + 40,130, 32, 74, 81,105, 42, 69,189, 34, 88,127, 72, 81, 4, 67,151, 18, 90, 66, 9, 16, 73, 32, 61,155, 77, 47,219,206,153,223, + 31,236,174, 75, 76,217, 13, 27, 8,186,239,243,204,147,221, 61,155,119,167,158,121,207, 55,223,124,227,230, 6,169, 84,138, 75, +151, 46,205,113,115,115, 91,110,123, 47,110,136,147,252, 57,105,117, 33,132, 28,103, 89,182,193,247,181, 93, 64,238,116,125,154, +243, 28, 76, 8, 89, 1,160,239,205, 91, 62,179,223,199,199,103, 74, 94, 94, 94,166,189,156, 65, 65, 65,222, 21, 21, 21, 43,131, +130,130,224,231,231,103,157, 59, 34, 35, 35,161,211,233,112,237,218, 53, 80, 74,145,151,151, 7,185, 92,142,240,240,240,149,175, +191,254,250, 55,203,150, 45, 43,106,206,178,255,221, 96, 17, 88,243,106,175,123, 18, 66, 32, 8, 2, 56,142,187, 69, 96,213, 78, + 22, 49,100,238,167,164, 49, 83,182, 94,175,183,138, 43, 15, 15, 15,171, 56, 51,153, 76,245, 9,172,166, 40,243,104, 65, 16,218, + 16, 66,214,217, 43,178,106, 99,236,216,177,127,241,231,120,237,181,215,178, 10, 10, 10,232,127, 7,116,145, 95,220,149,147,123, +191,167,194,221, 87,169, 12,119,243,244, 82, 23, 21, 21, 29, 5,160,118,224, 39,218,198,198,198,186,111,254,238, 96,214,243,175, + 46, 94,240,192,125,222,170,232, 96, 31,207, 0, 15,119,137,130, 33,149,110, 38, 99,150,151,151, 87, 68, 19,158,200, 0, 0,106, +181, 26, 28,199,181, 8, 11, 22,165,212, 68, 8,137, 33,132,156,218,177, 99, 7,226,227,227,173, 34,203, 34, 62, 74, 75, 75,145, +146,146,130, 94,189,122, 1, 64, 76, 99,190, 88,150,101,106,139,192,106, 72,184, 88,190,207,178,236,185, 38, 22, 97,129,167,167, +103,175,190,125,251, 74,182,108,221, 42,161,148, 86,226,230,129,212, 21,148,214,115,112,117, 45,152, 76, 38, 24,141, 70,139,149, + 17,169,169,169,183, 88,128, 69, 34, 17,252,253,253,237,202,140, 84, 42,125,253,235,175,191, 86,197,197,197,145,162,162, 34, 8, +130, 0,134, 97,208,170, 85, 43,172, 94,189,218,109,228,200,145,173,146,147,147,103,161, 9,199,206, 0, 32,245, 9, 33, 0, 80, +169, 84, 38,192,225,221,199,117,114,154, 76, 38,146,144,144,240,134, 70,163,233, 92, 93, 93,253,142, 61,253, 8,192,255,153,147, +229,158,114,230,226,197,139,213,163, 71,143,118, 15, 15, 15,143,191,221,190,218,174, 93,187,238, 34,145, 8,199,142, 29,211, 1, +176, 60, 73,239, 63,123,246,172,110,196,136, 17,210,144,144,144,238, 14, 88,238,218, 69, 69, 69,237,241,243,243,115,183, 8,255, + 81,163, 70,137,214,175, 95,175,204,206,206,134,193, 96,192,204,153, 51, 49,100,200, 16,248,248,248,224,181,215, 94,243, 95,186, +116,233,151, 0, 98, 27,224,116,147, 72, 36,159, 95,185,114, 37, 34, 48, 48,208,253,247,223,127, 71,116,116, 52, 52, 26, 13,242, +242,242, 80, 81, 81,129,188,188, 60,140, 31, 63,222,239,131, 15, 62, 8,106, 65,115, 77,137, 88, 44,134, 76, 38, 83,151,148,148, +148,222, 6,143, 20,128,196, 86, 92, 73,165, 82, 72,165, 82,184,185,185,193,142,103,202,123, 26,132,144, 86,132,144,243, 98,177, + 88, 42,147,201,196, 12,195, 64, 42,149, 14,240,242,242, 74,125,228,145, 71, 58,253,242,203, 47, 25,246,240,212,212,212,124,238, +230,230, 38,242,245,245, 5, 0,116,239,222, 29,143, 60,242, 8,180, 90,173, 80, 80, 80,128, 86,173, 90, 49,103,207,158, 69, 89, + 89, 25,254,248,227, 15, 68, 70, 70,138, 8, 33,159, 3,248,119, 51, 23,113,222,223,206, 7,139, 82,154, 72, 8,233, 93,215, 36, +198,113,156, 53,213,101,185,178, 36,123,132, 16, 33, 4, 60,207,195,223,223, 31,102, 71, 58,235,129,163, 60,207,255,133,159, 82, +218,164, 1, 35,151,203,241,196, 19, 79,208, 53,107,214,188,104, 22, 89, 87,236,253,223, 81, 31, 93,180, 90,173,106,163, 67,135, + 14, 71,102,205,154,245,232,111,191,253,150,253,192,125,225,156, 60, 39,179,194, 77,165, 86, 35,184,245,224,103,134,141, 56,139, +155,187, 9,237,197,149,242,242,114,247,251,131,101,122,134,169, 33,173,165,156, 50, 80, 46,150, 6,120,122,182, 18,235,117, 5, + 42, 79, 79,137, 78,167, 43, 1,208,224,225,204, 42,149,234,103,169, 84, 26,202,178, 44, 88,150,133,143,143,143, 7,165, 20,106, +181, 26,193,193,193,138,200,200,200, 52,142,227,192, 48, 12, 42, 42, 42, 50,175, 93,187, 54,160,177,140,121,122,122,254, 44,149, + 74, 67, 25,134, 1, 33, 4, 44,203, 90, 55, 36, 88, 94,179, 44, 11, 66, 8,170,170,170,236,226,164,148,158, 38,132,196, 12, 30, + 60,216, 42,178,118,237,218,133,129, 3, 7,162,164,164, 4,169,169,169,182,226,202, 46, 31, 44, 65, 16, 96, 48, 24, 96, 48, 24, + 26, 20, 46, 98,177, 24,106,181,186,201,131,196,203,203,235,208,168, 81,163,240,201, 39,159, 80,243, 41,239,114, 66, 72,180,135, +135,199,165,243,231,207,219,229,231, 66, 41,181,230, 19,192, 45,227,202,146,236, 93,210,100, 89,118, 64,108,108, 44, 41, 45, 45, +181, 8, 71,235,131, 16,203,178,248,248,227,143,221,227,226,226,222,114,115,115,123, 67, 44, 22,151, 25,141,198, 45, 53, 53, 53, +239, 80, 74, 75, 90,210,205,167,103,207,158,175,222,184,113, 99, 72,104,104,232,246,219, 16,239,180, 91,183,110,122, 0,238, 44, +203,138,156, 48,129,177, 0,192,243,124,141, 69,228, 83, 74, 77,177,177,177, 53,230,201,221,238, 19,144,125,124,124,190,220,185, +115,103,112,104,104, 40,140, 70, 35, 76, 38, 19, 42, 42, 42,176,127,255,126,232,116, 58,152, 76, 38, 68, 68, 68,224,237,183,223, +174,153, 50,101,138,219,186,117,235, 10, 42, 42, 42,158,108,132,118,202, 55,223,124, 35, 15, 12, 12,116,175,174,174, 70,122,122, + 58, 98, 99, 99, 81, 94, 94,142,202,202, 74, 84, 85, 85,193, 96, 48,160,172,172, 76,205,243,188,190,197, 76, 52, 28, 7,169, 84, + 10,177, 88, 92, 18, 26, 26, 10, 66,136, 91, 70, 70, 70, 83,150,220, 84, 0,202, 68, 34,145,196, 86, 88, 73,165, 82, 28, 59,118, +108,150, 68, 34,169,211,122,213, 80,255,113,228,125, 11, 16, 88, 43,196, 98,177,212,203,203, 75,108,115, 31, 20, 43, 20, 10,248, +249,249,125, 4, 96,144,157, 60, 93,189,189,189,173,135,125, 15, 25, 50, 4, 41, 41, 41,223,231,231,231, 63, 93, 80, 80, 0,131, +193,240,185, 84, 42, 29, 94, 86, 86, 6, 65, 16,144,159,159,143,182,109,219,118,189, 3, 15,227,117,106,145,123,221,130, 85,231, +186,167,101,137,176, 46, 65, 85, 91,112,217, 35,132,244,122,189, 34, 54, 54, 86,176, 76,220,150, 4,128,212, 39,176,204,150, 2, +135, 33, 18,137,148, 19, 39, 78, 44, 95,179,102,205, 4, 66,200,122, 74,233,229,166, 86,210,246,111,191,242, 95,242,246,204,183, +189,130,194,239,127,227,141, 57,220,208,161, 67,127,223,188,121, 51,239,213,126, 80,191,125, 63,127,225,191,114,218,244, 93, 59, +119,238, 4,110, 58, 60,219,139, 67, 63,253,244, 83,192,107,175, 76,194,219,175, 79,217,173,138,240,145, 40,136,151,220, 77, 87, + 89,168, 0,173,150,182,141, 26,242,221,246,237,185, 0,146, 27, 34,113,119,119, 15,189,124,249,114,132, 82,169,180,126,102, 48, + 24,160, 86,171,177,121,243,102, 95,165, 82,233,171, 80, 40,192,113, 28,162,163,163,237,181,144,132,166,165,165, 69, 40,149, 74, + 84, 85, 85, 65,167,211,193,104, 52, 66, 16, 4,235,128,148, 72, 36,144,203,229,232,210,165,139, 35,131,199, 42,178,118,237,218, +133,142, 29, 59,162,184,184, 24, 23, 47, 94,116, 88, 92,153, 39, 65,171, 5,203,114, 31,172, 75,184, 88,172,122, 77, 65,231,206, +157,233,225,195,135,177,123,247,110,252,231, 63,255, 33, 63,254,248,163,129,231,121,113,118,118,182,221,214, 48, 65, 16,172, 22, + 44,139,213,205,100, 50,221,242,185,237, 82,187, 29,214, 48,165, 68, 34, 65, 77, 77,141,117, 9,223, 54,181,105,211, 6, 90,173, +150, 43, 43, 43,227,114,114,114,100, 11, 23, 46,124, 57, 41, 41, 41, 16,192,227,119,243,102,179,102,205,154,208,231,159,127,254, + 58,199,113,116,224,192,129, 79,101,102,102, 14, 11, 12, 12,220,251,219,111,191,189, 15,160,157,163,124,190,190,190, 39, 57,142, + 11, 86, 40, 20,226,109,219,182, 25,203,203,203,197,126,126,126,249, 22, 65,107,233, 19, 70,163, 49,171,180,180,244, 1,123,248, +124,125,125,197, 31,126,248,161,177,168,168, 72, 28, 16, 16,144,111,225,145,203,229,226,109,219,182, 25,203,202,202,196,106,181, +250,100, 73, 73, 73,163,124, 26,141,230,201,177, 99,199, 30,220,187,119,175, 15,203,178,200,204,204, 68, 81, 81, 17,212,106, 53, + 62,255,252,115,132,134,134,226,155,111,190,209,106,181,218,231,222,123,239,189,183, 42, 42, 42,236, 9,217,208, 43, 62, 62, 62, +180,164,164, 4,106,181, 26,149,149,149, 56,121,242, 36, 58,116,232,128,156,156, 28, 48, 12, 3,181, 90,141,213,171, 87, 87, 17, + 66,180, 45, 97,146, 97, 89,214,106,101,178, 17, 69, 53,221,187,119, 71, 82, 82,210,116, 71, 68, 17,165, 84, 47, 18,137,110, 17, + 86, 54,175, 77,142,230,141,231,121,177,217, 7,148,216,243,190, 5,160,183,187,187,187,184,246,135, 85, 85, 85,226,192,192,192, +158, 14, 8, 94,111,119,119,119, 0, 64,215,174, 93,161,213,106,121,133, 66, 49,102,218,180,105, 70, 0,152, 48, 97,194,152,235, +215,175,215, 24, 12, 6, 86, 44, 22,163,180,180, 20, 65, 65, 65,222,119,104,197, 99,255,223, 74, 96,153, 21, 99, 18,128, 62,150, +194,217, 46, 17, 54,100,185,170,101,193, 34,141, 12,180,146,172,172, 44,185, 92, 46,183,126,102, 52, 26, 17, 20, 20, 36, 8,130, + 64,106,255,142, 37, 31, 77,133, 72, 36, 82,190,249,230,155, 37,171, 87,175,126, 26,118, 58,138,111,155, 28,133,205,181,196,213, +218, 37,243, 63,250,112,201, 66,175,171,187, 55,226,211, 85,203,120,158, 71,114,231,206,157,123, 86, 84, 84,112, 30,114, 35, 52, + 37,216,133,155,113,176,236, 18,131,230, 88, 90, 27,142, 31, 63,158, 60,104,208,160,195, 27,190,254,206, 43, 39, 61,253,168,180, + 76,147,171,106, 27,193,137, 91,133, 14, 47,175,169, 17,143, 25, 51,198, 23,192,127, 27,226, 98, 24, 6,233,233,233,200,200,200, +128, 66,161,128, 82,169,132, 66,161,128, 74,165,130, 82,169,132, 82,169,116,184, 14, 25,134, 1,207,243,248,246,219,111, 33,147, +201, 32,151,203,111, 73, 22,113,117, 59,109, 51,112,224, 64,104,181, 90, 40, 20,138, 38, 11, 32,139, 56,177, 44,189, 89, 4,214, +151,247,221,135,231,115,114,172, 2,107,133,135, 7,222, 22, 28, 14, 81,134,232,232,104,122,244,232, 81, 28, 62,124, 24,149,149, +149,248,240,195, 15, 17, 24, 24,248, 16,128, 57,142,114, 89,242,105, 52, 26,249,236,236,108,145, 70,163,129, 37, 92,137,165,223, + 87, 85, 85,217, 61, 41,112, 28,103,181, 46, 90,146,173, 21,139,101, 89,248,251,251, 35, 32, 32, 0,107,215,174, 21,135,135,135, + 15,185,155, 55,154,165, 75,151,182, 93,177, 98,197,103,155, 55,111,222,245,228,147, 79,110, 77, 73, 73, 25,231,225,225,113,110, +223,190,125, 11,165, 82,169,208,196,241, 29,156,147,147,227,103,251,145, 32, 8, 50,147,201,100,237, 27, 85, 85, 85,232,212,169, +147,221,124,231,207,159,151, 1,192,194,133, 11, 69, 0,100,130, 32,128,231,121, 88, 56,171,170,170, 68, 29, 58,116, 8,182,115, +162, 72, 35,132,244,236,223,191,255,145, 61,123,246,120,134,134,134, 34, 59, 59, 27,217,217,217,104,219,182, 45, 22, 45, 90, 84, + 89, 86, 86,150, 96, 22, 85, 63,218, 89,236, 32, 79, 79, 79,209,245,235,215, 97, 50,153,208,181,107, 87,172, 94,189, 26, 99,198, +140, 65,167, 78,157, 80, 86, 86,134,243,231,207, 99,211,166, 77,158, 98,177,248,191,119,123,130, 49, 47, 97,213,155,154, 56,238, + 85,110,110,110,101, 82,169, 84, 98,241,191,218,191,127,191,195,214, 43,219, 7, 63, 71,222,183, 4,177, 90, 27, 18,137, 4, 1, + 1, 1,142,172,242, 16, 91,247, 28,141, 70,195, 23, 23, 23, 91,151,241,215,175, 95,207,183,109,219,150, 23, 4,129, 21,139,197, + 32,132, 64,161, 80, 52,187,200,172, 75,139,252, 29, 44, 88, 73,148, 82, 98,118, 40, 39, 22, 97, 67, 41,253,139,168,170, 79,112, +153, 45, 88,164,177,193,198,178, 44,118,239,222,109, 21, 2,150, 93,132,148, 82, 56, 91, 96,121,123,123, 87,198,199,199,171,110, +220,184,241, 85, 83, 45, 87,107,151,204,255,104,241,130,185, 94,218, 11,191, 35, 43, 39, 23,218, 2, 99,242,161,115,215,190, 7, +240, 61, 0, 96, 93,251, 36, 76,184,240,177,189,156,237,125,101, 93, 58, 7, 41,191,127,120,208,144,144,209, 47,188,202,188,244, +210, 75, 61,198,142, 29, 91,250,228,147, 79,190,162, 80, 40,218, 25, 12,134,226,239,118,236,200, 24, 61,122,116, 56,207,243, 99, + 41,165,101,141, 76,220,153, 35, 70,140,176,214,109, 64, 64,128,106,203,150, 45,254, 74,165, 18, 79, 61,245, 84, 97, 70, 70,134, +117, 89,168,188,188, 60,211,158, 60, 26, 12,134,204, 46, 93,186,212,187, 44,104,177, 64, 58,194,105, 49, 75,195,236,208, 94, 84, + 84,132, 75,151, 46,129,227, 56, 60,248,224,131, 56,116,232, 16,122,244,232,225,208, 14, 66, 74,169,117,215,160,193, 96,224, 1, +136, 56,142,195,248,172, 44,171,224,224,184,166,197,210,237,210,165, 11, 61,118,236, 24,206,157, 59, 7,157, 78,135,231,158,123, + 14,230,229, 65, 0,120,196,129, 50,223, 23, 16, 16, 48,112,208,160, 65, 65, 0, 80, 89, 89, 73, 78,157, 58, 5,158,231, 65, 41, + 69, 65, 65, 1, 14, 28, 56, 0,141, 70, 3,134, 97,224,233,233, 25, 76, 8, 9,167,148, 94,107, 96, 66, 32,215,174, 93,195,187, +239,190, 11, 65, 16, 48,125,250,116, 68, 68, 68, 88,133, 85,102,102, 38, 22, 46, 92, 8,158,231, 49,119,238, 92,180,109,219, 22, + 70,163,209,205,145, 56, 99,206,198,107,175,189,118,245,251,239,191,223,117,227,198,141,127, 47, 89,178,164, 55, 33, 68,120,227, +141, 55,222, 85,169, 84,252,237,240, 22,151,150,227,210,149, 76,171, 0,170,157,124,125,188, 28,230,187,156,126,195,250,255, 60, +111,203,199,195,219,203,211,209, 44, 86, 25,141,198,202,225,195,135,171,191,253,246, 91,210,182,109, 91,252,241,199, 31,150,135, +210,170, 38,132,102,200,214,106,181, 17, 44,203,138,175, 92,185,130,176,176, 48,196,199,199,227,157,119,222,129, 70,163,129,201, +100,130,159,159,159, 96, 52, 26, 79,233,245,250, 3,119,123,130,177,181, 50,217,166,253,251,247, 79,151, 72, 36, 20,192, 49, 0, + 14, 9,108, 74,169,190,117,235,214,181,185, 77,104, 33,104,206,157,137,129,129,129,251,149, 74,229,144,226,226,226, 91,172, 88, + 9, 9, 9, 6,127,127,255,131,246,242, 40, 20,138, 98,142,227,188,121,158, 71,106,106, 42, 90,183,110, 45,190,126,253,250, 98, + 66,200, 76, 0,104,223,190,253,226,188,188, 60,177, 37, 58, 64,104,104, 40,106,106,106,138,239, 64,245,253, 69,139,252, 29, 4, +214, 95,118,235,217,138, 30,123, 68,150, 61, 86, 8, 66, 8,170,171,171,111,177,134, 88,118, 17,214, 37,176,204, 19,121,147,150, + 8,205,226,202,125,203,150, 45,255, 91,181,106,213, 97,123,255,207,214, 7,107,221,251, 11,150, 88,196,213,217,195,123,240,227, +197, 82,205,244,197,203, 87, 52,181,178, 59,248,202,163, 3,252,125,146,222, 91, 52, 95,117,117,247, 38,108, 93,247, 1, 61,123, +226, 68,220,137, 19, 39,158,158, 52,105, 82,107,115,135,210, 2, 56, 3, 96,180, 61,187,110, 10, 11, 11,111,241,127,138,136,136, + 72, 83,171,213,254,110,110,110, 72, 79, 79,175, 72, 77, 77,117,120,233,165, 54,167,147,158, 76,110, 17, 87,169,169,169,232,219, +183, 47, 0,224,208,161, 67, 72, 72, 72,112, 88,100,213,212,212, 88, 6, 62, 42, 43, 43,171, 0, 72, 63, 15, 15, 7, 0, 76, 46, + 42,194,201,247,222,195,239,139, 23, 59, 44,212,187,118,237, 74, 79,156, 56,129,140,140, 12,152, 76, 38, 60,250,232,163,182,226, +202,145, 50,119,138,138,138,250,117,223,190,125,190, 10,133, 2,149,149,149,168,168,168,192,216,177, 99, 49,112,224, 64, 84, 87, + 87, 99,207,158, 61,248,233,167,159,160, 84, 42, 81, 89, 89,137,202,202, 74,207,193,131, 7, 31, 33,132,244,170,207,119,144, 82, + 74, 7, 12, 24,128,131, 7, 15,130,101, 89,196,197,197,161,168,200,186,185, 7,254,254,254,117, 93, 99,205,227,253,174, 76, 68, + 28,199,209,253,251,247, 47,233,221,187, 55,110,220,184,241,239,216,216,216, 15,199,141, 27,151,125,187,188,158, 30, 74,116,233, +112, 31,116, 58, 29,116, 58, 29,130,130,130, 80, 94, 94,142,171, 87,175, 66,167,211,193,223, 79,237, 48, 95, 76,167,182, 86, 62, + 63, 63, 63, 84, 86, 86,226,218,181,107,208,235,245,240,241,241,116,164,253, 67, 6, 12, 24,240,219,255,254,247, 63,239, 77,155, + 54,233,251,244,233, 35,249,240,195, 15,137, 74,165, 66, 65, 65, 65, 83,139,188,255,208,161, 67,161,253,251,247,143,188,112,225, + 2,246,239,223, 15,189, 94,143,152,152, 24, 92,190,124, 25,221,187,119, 71, 69, 69,197,177, 19, 39, 78,252, 95, 75,152, 96, 44, +203,119, 54,150,166,217,106,181,218, 0, 96,197,237,244,197,235,215,175, 75,163,163,163,117,110,110,110, 18,179, 88, 91,126,183, +250,118, 29,237,126, 91, 59, 19, 27, 66, 64, 64,192, 84, 31, 31,159,254,109,218,180, 65,126,126,190, 88, 34,145, 32, 33, 33,193, +208,173, 91, 55, 67, 64, 64,192,100,123,121,220,220,220, 46,184,185,185,245,170,168,168,128,193, 96,192,201,147, 39, 33,151,203, +167,247,235,215,111, 74, 65, 65, 1, 10, 10, 10, 36, 50,153,204,250, 48,221,181,107, 87,212,212,212, 92,184, 67,245,215,162,252, +222,156, 34,176,108, 84, 99,109,179,121,163,203,131,246,250, 96, 17, 66,160,215,235, 33,151,203,173, 75, 79,182,145,219,235, 18, + 88, 77, 65, 72, 72, 8,226,227,227,221,183,110,221,250,229,178,101,203,142, 52,133,227,155,255,125, 17,232, 33, 84,133,228, 28, +219,137,180,115,201,248,254,124,137,102,250,226,229,175, 12,253,239,227,249,181, 5,217,182, 9,141,243,181,243,147,119,106,229, +239,157,244,254,210,197, 42,237,133,223,145,155,151,135,157,199, 78, 36,235, 41, 61, 15, 96,186,179, 26,212,178,179,166, 37,117, + 84,219, 48, 13, 26,141, 6,231,207,159,183,136,171, 24, 0,232,209,163,199, 41,139,200, 74, 78, 78, 70,108,108,236, 95,194, 52, +212, 97,185, 43,105,223,190,189,213,154, 85, 90, 90, 42, 0,192, 11,185,185, 88, 31, 24, 8,142,227,240,251,226,197,152,109, 52, +226, 29,145,200,161,193,205,243, 60,180, 90,173,229,201,176, 73,226,202,124, 51,124,125,223,190,125,190, 27, 54,108, 40,219,188, +121,115,145, 32, 8,162, 46, 93,186, 4,119,235,214,141,108,223,126,211,175,251,177,199, 30,195,244,233,211,113,254,252,121,200, +229,114, 36, 36, 36,240,137,137,137,126, 83,167, 78,157,140,155,113,142,254, 2,158,231,197,225,225,225,123, 1, 60,116,225,194, + 5, 0, 56, 66, 41, 77,176, 92,111,232,154, 29, 16,202,203,203, 69, 74,165,178,206, 16, 15, 98,177, 88,236,168,197,193,150,243, +240,225,195,239,190,255,254,251,223, 79,155, 54,237,202,109,114,214,105,193, 26, 50,100, 8,170,117, 6,100,229,151,130,231, 77, +168, 54, 20, 56,204,103,107,193, 26, 50,100, 8,170,106,244,184,158,171,133,201,196,163,188,218,100,111, 63,146, 61,252,240,195, + 63,111,217,178, 37,224,232,209,163,224,121, 94,184,124,249,242,181,225,195,135,171,222,120,227, 13,111, 27, 31, 83, 71,177,234, +241,199, 31, 31,121,248,240, 97,109,100,100,164,215,177, 99,199, 80, 80, 80, 0,147,201,132,135, 30,122, 8, 18,137,228,250,226, +197,139,197, 0, 86,181, 20,129, 37,149, 74,113,252,248,113,167, 8, 43, 91, 72, 36,146, 38, 47, 51,222,171, 56,118,236, 88,246, +164, 73,147, 58,168, 84,170, 21, 61,123,246,236,235,237,237,205,120,122,122,238,111,213,170,213,148,232,232,104,187, 87, 19,196, + 98,241, 56,165, 82,121, 85, 36, 18,177, 90,173, 22, 89, 89, 89, 96, 24, 6,130, 32, 72,140, 70, 35, 2, 3, 3,173, 70,147,254, +253,251,163,117,235,214,252,217,179,103,199,221,137, 50,214,167, 69,238,105,129, 85, 27, 12,195,128, 82, 10,183, 7, 30, 64,238, +158, 61,248,246,219,111, 27, 36, 90,183,110, 29,106,155,244, 8, 33,253,109, 99,101, 88,118, 11, 62,255,252,243,214,239, 36, 39, + 39, 91,157,221, 31,125,244,209, 91, 56,143, 31, 63,254, 23,145, 85,155,179, 46, 20, 20, 20, 92,216,182,109,219,137,165, 75,151, + 30,179,243,102,104,229,180,248, 96,141,124,226,169,220,143,222,125, 59,101,243,246,125,157,114,171,105,238,244,197,203,167,213, + 22, 87,246,114,182, 15, 80,180, 15,246,243,222,191,108,233, 98, 15,139, 53,108,203,169,188, 82,152,232, 4, 71, 26,203,158,178, +219, 90, 18, 9, 33,130, 51, 56,155, 32,168,110,225,180, 13,211,144,155,155,107, 21, 87, 54,129, 70, 99,122,244,232,113,202, 44, +174, 44,215, 76, 13,113, 22, 23, 23, 47,170,125, 29,128,143,165,252, 28,199, 33,225,173,183, 26, 20, 87,245,149,221, 28,143, 10, + 17, 17, 17, 14,139, 43, 91, 78, 66, 72, 66, 85, 85, 21, 54,109,218, 84,126,229,202,149,251,218,180,105, 51,117,227,198,141,203, +101, 50,217, 45,255, 83, 85, 85,133,127,255,251,223, 88,176, 96, 1,158,121,230, 25, 97,220,184,113, 44,195, 48,253, 27,202,103, + 70, 70,198,132,126,253,250,173,171,169,169,225,138,138,138, 38,216,123,173,177,178,111,219,182,237, 74, 68, 68, 68,111,212, 31, +138, 65, 0,112,244,118, 56, 87,172, 88, 1, 0,145,183,195, 89,159, 5,235,235,175,191,134, 32, 8, 8, 9, 80, 67,167,211,161, +118, 93, 55,198, 89,219,130,181,117,235, 86, 8,130,128,214,129, 94,208,235,245,176, 56, 6, 55,198,233,237,237,253,193,230,205, +155,131, 47, 94,188,136,172,172, 44, 44, 95,190, 60,179,164,164,100, 80, 73, 73,137, 52, 49, 49, 49,233,137, 39,158,240, 23, 4, + 65,231,232,216,164,148,234, 8, 33,227,254,245,175,127,125,190,112,225,194, 63,162,162,162, 90, 39, 36, 36,168,139,138,138, 10, + 79,159, 62,125,109,221,186,117, 10,147,201, 52,174,190,165,167, 59, 49,222,109,145,157,157, 61,207,108, 61,117, 72, 88,217,147, +207,227,199,143,191,105,230, 62, 97, 15,247,157, 42,251,237,238, 76,108, 44,159, 31,127,252,113, 22,106,197, 55,115, 52,159, 7, + 14, 28,200, 24, 50,100,200,130,176,176,176, 68,153, 76,134,172,172, 44,107, 64,100,203,152, 33,132,160,111,223,190,120,252,241, +199,113,250,244,233, 5,207, 61,247, 92, 70,115,215,231,223, 13,150, 48, 13,196,246,175,217, 66,112,227,234,213,171,129,109,139, +139,217, 32, 66, 16, 23, 23, 7,219, 51, 4, 45,126, 57, 22, 31,151, 3, 7, 14,152, 4, 65,104, 48,230, 20,207,243, 55, 14, 31, + 62,236,191,103,207, 30,145,197,100,108,118,214, 20,114,114,114,152,164,164, 36,171, 53,140,227, 56,236,223,191,223,100, 48, 24, +174, 59, 90,168,180,180, 52,167, 60,189, 29, 72,205,152,242,243,206, 31,124, 30,140,239, 89,162,242,242,170,115, 0, 91, 34,190, + 55,216,185, 57,230,157, 37,139,230,171, 45,226,234,235, 83,121, 37, 53, 58,190,239,133,194,170,179,206,110,208,242,242,242, 12, +203,110,193,138,138,138,235, 45,165,163, 89,118, 16, 6, 6, 6,158, 66,173,221,130,150,107,177,177,177,127,185,230,112,135,230, + 56, 76,171,168, 0,199,113,232, 51,111, 30, 30, 90,176,192, 33,235,149,101,201,186,246,120,104, 98,153, 15,167,164,164,132, 61, +243,204, 51,202,136,136,136,116, 66,136,232,217,103,159, 21, 2, 3, 3,153,131, 7, 15, 82, 0,232,211,167, 15,201,203,203, 67, +110,110,174,105,252,248,241,194, 51,207, 60,195,156, 57,115,134, 10,130,240,107, 35,220,127, 0,232,231,232,181,198, 48,114,228, +200,116,212, 17,240,243,118,208, 28,156, 22,104, 75,202,144,158,145,141,155,206,232, 2,248,204,124,171,223,148,209,104,130,182, +172,200, 97, 11,214,213,107,217,230,163,193,120,240,124,142,153,239,166,163, 59, 45,110,124, 35,130, 72, 36,234,177, 98,197,138, + 65, 12,195, 48,191,255,254,187,110,233,210,165, 55, 10, 11, 11, 31,165,148, 94, 55,247,179, 62,155, 54,109,250,210,142,144, 12, +245,181,253,121, 66, 72,247, 25, 51,102,188, 2,160, 7,128,214, 0,174, 3, 56, 4, 96, 85, 11,139, 56,190,252, 30,229,110, 50, +238,149,157,137, 63,253,244,211,188, 39,159,124,146,139,138,138,154, 21, 25, 25,201,228,229,229,161,164,164, 4, 44,203, 90, 86, +129, 16, 22, 22, 38,156, 60,121,114,209,184,113,227,230,221,137, 60,213,165, 69,254,150, 22,172,226,226,226, 1,131, 6, 13,218, +195,178,108,184, 69,205,218,250,177,212,113, 40,115, 70,126,126,126,131, 65,200,138,139,139, 7, 76,153, 50,101, 15,203,178,225, + 22,203,148,201,100,210,105,181,218,151,250,244,233,179, 90, 36, 18, 73,109,121, 5, 65,200,204,207,207,191,163,103,233,213,142, +131, 53, 96,208, 48,205,237,114, 42,196,204,253,105, 59, 62, 65,126,129, 6, 95,159,202, 43, 46,215,243,125,210, 10, 43, 83,154, + 35,255, 25, 25, 25, 3, 91,106,103, 51, 11,169, 58,151,254, 26,186,102, 47, 4, 65,128,135,135, 7,234,234,175,142,152,166,157, + 53,184,243,242,242,150,189,245,214, 91,143, 44, 90,180,200,119,215,174, 93, 42,243,111, 96,196,136, 17, 5, 41, 41, 41, 61, 1, + 72,117, 58,221,175,139, 22, 45,242,157, 63,127,190,117, 44, 14, 30, 60, 56, 63, 63, 63,255, 35,184,208, 32,140, 70, 99, 86,199, +246,145,150,182,187, 37, 52,131,237,107,147,201,148,229, 8, 95, 93, 60,182,239,121,158,207,106,196,138, 60, 45, 62, 62,158,157, + 54,109, 90,254,174, 93,187,246, 22, 23, 23,191, 70, 41,173,178,233,103,105,104, 32,152,168,157,125, 85, 7, 96,169, 57,185,208, + 2,239,117,142,188,191, 91,248,242,203, 47,231, 76,152, 48, 97,147,183,183,247, 23,157, 58,117,138, 12, 9, 9, 81,201,100, 50, + 84, 85, 85,149,215,212,212, 92, 58,118,236,216,147, 47,191,252,242, 31, 45,164, 90,187, 1,240, 5, 96, 57, 11,212, 23,128, 30, + 55, 3,207, 22,154, 45,153,247,134,192, 50, 71,171,238,238,228, 78,215, 16,103,104, 75,169,148,177,186,165, 95, 97,221,210, 91, +206, 33,180,136,175, 58,223, 55,178,208, 87, 90,109,154,180,234,231,212,101, 58, 19, 21, 12, 38,225,217,180,130,202,243,255,224, + 27,143,169, 41,215,236, 64,161, 29,145,218, 11,237,200, 31,113, 98, 89, 83, 8, 33,255,154, 52,105,210, 28,153, 76, 22, 7, 0, + 85, 85, 85,191,231,228,228, 44,176,236, 18,108,236,186, 11, 13, 52,102, 97,225, 3, 45,145, 79,175,215, 79,249,215,191,254,181, +146,231,249,247,141, 70,227, 33, 87, 75,185,208,146,177,110,221,186, 63, 44,243,242,168, 81,163, 88, 0,216,182,109, 27,223, 2, +179,234, 75, 8,249,137, 82, 58,196,124,239,252,137, 82, 58,196,246,179,123, 70, 96,253, 83,177, 45,245,207, 9,182,182,112,106, +236,125,125,184,148, 87,177,255,118,159, 88, 93,104, 84,204, 60,220, 66,243,149, 14, 96,108, 83,175,187,112, 79,246,197,235, 0, + 30,117,213,132, 11,247,220,252,215, 50,133,213, 61, 11,198, 85, 5, 46,184,224,130, 11, 46,184,224,130, 11,206, 5, 1,208,191, +158,167, 48,187,119, 7,152,119,112, 57,250,148,247,171,139,211,197,233,226,116,113,186, 56, 93,156, 46,206,127, 22,103, 19, 49, +184,145, 37,194, 29, 45, 78, 97,217, 58,113, 58, 59, 1,232,239,226,116,113,186, 56, 93,156, 46, 78, 23,167,139,211,197,121,155, +169,239,204,153, 51,223,196,205,243,137,233,204,153, 51,223,164,148, 14,190, 41, 99,232,224, 59,156, 23,187,146,203, 7,203, 5, + 23, 92,112,193, 5, 23, 92,104,233, 56,178,120,241,226,170,197,139, 23, 91, 28,218, 11, 1, 16,179,245,170,176, 37,102,216, 37, +176, 92,112,193, 5, 23, 92,112,225, 31, 4, 66,136,220,211,211,115, 47,195, 48,161, 54,159,161,174,215, 0,192,243,124,174, 86, +171,125,132, 82,170,185,147,156,181,160, 7,112,252, 94,170,103,206, 92,112, 75,100,217, 70, 79,176,238, 20,168,232,217, 62, 34, +244,127,185,121,154, 83,186,202,234,241,199,179,203,181, 77,108, 96,111,137, 68, 50, 70, 46,151,247,167,148,222,199,178,236,197, +210,210,210, 95,141, 70,227, 22, 74,105,133,107, 8,184,208, 2,110, 66, 35,165, 82,233, 82, 66, 72, 43,189, 94,207, 73,165, 82, + 19,165, 52,183,166,166,102, 54,165,244, 75, 87, 13,185,224, 66,163, 99,168,222, 3,198,239,230,225,227, 0,160, 84, 42, 79, 50, + 12, 19,108, 59,249, 91,226, 51,214,142,243,104, 19,239,241,143,162,162,162,127, 53, 80,222,251,188,188,188, 86, 3,232,214, 88, + 28, 62,243, 50,219, 9,173, 86,251,146,121, 55,113, 93,124, 74, 79, 79,207,121,132,144, 81, 12,195, 52,122,224,175, 32, 8, 60, +165,116, 91,113,113,241, 92, 74,105,121,125,223,243,244,244,252,245,226,197,139,221,252,252,252, 26, 13, 75, 99, 50,153,112,253, +250,117,223,184,184,184, 3, 0,162,154,147,211, 17, 45,114,207, 8, 44,115, 99,219,117,130, 53, 75,200, 83,107, 23,188,212, 42, + 47,243, 74,171,201, 75,182,182,139, 13,149,245, 73,206,172,202,115,228, 71,221,221,221,199, 68, 71, 71,175, 90,185,114,165,119, + 88, 88, 24,145,201,100,200,205,205,141, 58,125,250,244,240,196,196,196,185, 34,145,104,156,209,104,220,115,155, 3, 91,237, 37, +227,166, 23, 85, 26,223,116,221,230, 92,112,176,239,136, 69, 34,209,190,192,192,192,132,117,235,214, 33, 42, 42, 10, 42,149, 10, + 57, 57, 57,220,185,115,231, 66,166, 79,159,254,133,155,155,219,100,157, 78,215,151, 82, 90,237,170, 49, 23, 92,168,115, 28,117, + 5, 80,231,225,237, 13, 93,187, 83, 96, 24, 38, 56, 59, 59,219, 79, 38,147,129,231,121,115,244,126, 1,148, 82,235, 95, 91, 49, +196,243, 60,162,162,162, 12,141,136,182,143, 11, 10, 10,250,219, 30, 89,214,208,201, 56,217,217,217,253, 59,116,232,240, 49,128, + 71,234, 17, 45,243, 94,121,229,149,169,157, 58,117,178, 88,125,204,167, 22,220,252,171,209,104, 48,105,210, 36,235,111, 8,130, +128, 61,123,246,188, 50,110,220, 56, 0,120,181,129,178,135,250,249,249,145, 9, 19, 26,142, 53,148,152,152,136,196,196, 68,172, + 90,181,138,136, 68, 34,117, 35,245,233, 20, 78,123,181,200, 61, 37,176, 28,192,206, 37, 43, 63, 27,255,246,211, 9,100,221, 43, +125, 35, 94,254,112,223,209,216, 32,207, 94,201, 57,197, 55,236, 20, 87,175,188,248,226,139,239,206,159, 63,223,237,210,165, 75, + 56,127,254, 60, 76, 38, 19,148, 74, 37,162,163,163,153,157, 59,119, 6, 78,153, 50,229, 27,137, 68,242,172, 94,175,255,174,169, + 5, 11, 80,137,222,147, 75,153, 39, 36, 28,119, 76,111, 50,253, 95, 75,172,124,153, 76,182,177,186,186,122,137, 57,178,243,189, +114,211,108,167, 84, 42,103,151,149,149, 61,245,119,157, 24, 56,142, 75, 26, 58,116,104,247,141, 27, 55, 34, 35, 35, 3,233,233, +233,200,201,201, 65,120,120, 56, 58,119,238,140,125,251,246,225,213, 87, 95,141, 59,112,224,192, 33,152, 15,172,182,179,238, 24, +145, 72,244,140,151,151,215, 48,127,127,127,191,194,194,194,194,226,226,226,237, 58,157,110, 67, 83,159,228,205,156, 79,134,133, +133, 13, 11, 10, 10,242,207,206,206,214,100,101,101,253,159, 78,167,219, 72, 41, 21,110,163,157, 3, 1, 68, 3,240, 54,127,148, + 27, 22, 22,150,122,237,218,181, 2, 39,114,230,132,133,133,157,119,148,147, 16, 34, 7,176, 21, 64, 80, 35, 95,205, 1, 48,218, + 28,224,216,133,187, 32,174,204, 71, 79,221, 34,164, 26,186,118,167,225,238,238,142, 45, 91,182, 64, 36, 18, 65, 36, 18,161,184, +184, 24,193,193,193,214,247, 98,177,216,250,186,117,235,214,141,242,241, 60, 31,199,178, 44, 42, 42, 42,192,243,188, 53,149,148, +148,128, 82, 10,169, 84, 10,158,191,121,236,146,205,245,184, 6,234,113, 84, 80, 80, 16,190,250,234, 43,232,245,250,191, 92, 87, +169, 84, 72, 73,249,243, 80, 16,150,101, 17, 31, 31,207, 16, 66, 70, 53, 36,176, 44,150,162, 23, 94,120, 1, 44,203, 90,143,190, +179,188,182, 36,158,231,145,152,152, 8,219, 35,196,238, 36,231, 61, 63, 14,204,133,164,117, 29, 19,210, 37, 72,241,210,195,125, +186,191,231,238, 38,118,231, 77, 70, 8, 70, 3,120,147, 30, 28, 17,208,175,179, 63,226,195,101,208,104,203,240,242,250,147,101, + 89,133,213,241,201, 57,229,105,141, 52, 64, 88,124,124,252,169,125,251,246,169,247,238,221,139,180,180, 52,188,243,206, 59, 0, + 0,185, 92,142,221,187,119,131,101, 89, 8,130,128,129, 3, 7, 22,230,228,228, 68, 81, 74,181, 77, 24,220,161,189, 58, 5, 39, +127,247,102, 47,175,142, 19,191,201,204, 43,213,223, 71, 41,109,113, 1,212, 20, 10, 69, 33,203,178,124, 89, 89, 89,159,123, 65, +100,153,197, 85, 18, 33, 68, 92, 90, 90,234,213, 66,242, 20,211,181,107,215,165,105,105,105,223, 87, 85, 85,125, 92, 75,192, 78, +138,136,136, 24,114,230,204,153, 89,246,222,192, 9, 33, 35,253,252,252,182, 93,185,114, 5, 39, 78,156, 64,113,113, 49, 10, 10, + 10,240,202, 43,175, 96,205,154, 53,232,216,177, 35,228,114, 57, 68, 34, 17,122,246,236, 9,173, 86,251, 44,165,116,163, 29,188, +172,135,135,199,198,213,171, 87,183,125,244,209, 71, 57,157, 78, 7,158,231,177,109,219, 54,227,220,185,115, 51,138,138,138,158, +118, 84,100, 17, 66,152,192,192,192, 13,159,124,242, 73,187,135, 30,122,136,171,174,174,134, 32, 8,216,177, 99,135,113,214,172, + 89,127,228,230,230,142,109, 74,191, 39,132,116,149,201,100, 29, 94,122,233,165,194, 71, 31,125,212, 0, 0, 39, 78,156, 96,206, +158, 61,171,106,211,166, 77,230,156, 57,115, 78, 53,129, 51, 86,169, 84, 70, 78,152, 48, 65, 51,100,200, 16,163, 88, 44, 22, 14, + 31, 62,204,165,165,165,169,194,194,194,210,103,205,154,117,214, 1,174,157, 71,142, 28,233, 29, 28, 28, 44,152,111,234,212,114, +131,103, 24,134,154,255,226,210,165, 75, 92,239,222,189,147, 40,165,255,113, 73,158, 59, 58, 38, 57, 0, 70, 74, 41,180, 90, 45, +142, 29, 59,134,193,131, 7,195,230, 97,228, 20,165, 20,101,101,101,168,174,174, 70, 96, 96, 32, 0,136,238,244,114,161, 90,173, +206, 47, 44, 44,244,251,241,199, 31, 33, 18,137,176,103,207, 30,172, 89,179, 6, 91,182,108,169, 83,100, 5, 6, 6, 34, 34, 34, + 34, 43, 39, 39, 39,164,129,123,122,105, 69, 69,133,170,180,180, 20, 60,207,227,216,177, 99,248,244,211, 79,225,231,231, 7, 31, + 31, 31,248,250,250, 34, 46, 46, 14,114,185,220, 42,178,122,246,236, 89, 86, 81, 81,225, 81, 23,159,183,183,119,206,180,105,211, + 2,147,147,147, 97, 52, 26,235, 20, 88, 83,167, 78,181,181, 34, 65, 38,147,161,123,247,238,185, 69, 69, 69,245, 62,128,248,250, +250,230, 22, 22, 22, 6,156, 61,123,246, 22,241, 83,151, 32, 98, 89, 22, 74,165, 18,225,225,225,249,185,185,185, 1,205,201, 89, +159, 22,185,231, 45, 88,230, 27, 85, 31,219,139,237,194, 3,103,191, 51,101,164, 59,120, 3,168,177, 26, 48, 84, 1,134, 10, 8, +250, 42, 16,177, 59, 96,172,134,143, 84,139,207, 95,108,167,122,107, 91,250,133,174, 1,170,193,167,243,202,118, 55,208,161, 19, +215,174, 93,171, 78, 73, 73, 65, 90, 90, 26, 62,248,224, 3, 44, 88,176, 0, 98,177, 24, 90,173, 22, 67,135, 14,197,145, 35, 71, + 96, 48, 24,240,214, 91,111,121,205,152, 49, 99, 50, 0,135, 15,153, 12, 80,113,107,182,110, 88,229,229,197, 22,225,217,135, 78, +122,127,252,203,181,151, 0,124,216,210, 42, 95, 44, 22, 27, 62,253,244,211,160,231,158,123, 46,137, 16,210,162, 69, 22, 33,164, +157,151,151, 87,210,187,239,190,235, 63,103,206,156, 92, 39,113,250,203,229,242,109,149,149,149, 83,155,242, 4, 75, 8,137, 25, + 49, 98,196,182,141, 27, 55,134,246,234,213,203, 8,224, 22,129,213,174, 93,187,225, 73, 73, 73,189,199,141, 27,119, 31, 33,100, + 52,165,180, 81, 97, 32,149, 74, 23,174, 89,179, 6, 57, 57, 57, 40, 41, 41,129, 68, 34, 1,207,243,150,223,131, 84, 42, 5,195, + 48,112,115,115,195,172, 89,179, 48,119,238,220, 68, 0, 27,237,224,125,102,245,234,213,109, 7, 12, 24,192,101,100,100,128, 97, + 24, 72,165, 82, 60,241,196, 19,162,170,170,170,208,249,243,231,191, 0, 96,181, 35,229, 23,137, 68, 79,174, 95,191,190, 93, 66, + 66, 2,119,241,226, 69,116,239,222, 29,199,143, 31,199,127,255,251, 95, 81,121,121,121,248,244,233,211,199, 3, 88,239,168,149, + 73, 38,147,117,250,237,183,223,110,132,132,132, 88,215, 54,194,195,195,249,193,131, 7,107, 47, 94,188, 24,121,244,232,209,162, +238,221,187, 95,119,128,179,149, 76, 38,139,218,185,115,103,238,252,249,243,251,173, 91,183,238, 81, 0,136,139,139,251,191, 5, + 11, 22,236,211,106,181, 29, 15, 30, 60,168,237,217,179,103,150,157,148, 65,129,129,129,252,164, 73,147, 20, 13,125,233,179,207, + 62, 43, 1,208,154, 16,210,198,124, 0,182, 11,119, 0,148, 82, 19, 33, 36,134, 16,114,106,199,142, 29,136,143,143,199,142, 29, + 59, 48,120,240,224, 83,230,235, 40, 45, 45, 69, 74, 74, 10,122,245,234, 5,220, 60,224,253,174,248, 98,241, 60, 15,142,227,144, +149,149,133,207, 62,251, 12,139, 22, 45, 66, 68, 68, 4,140, 70,163, 85, 96,113, 28, 7,145, 72,100,177,182,216, 53,233,155, 76, + 38,156, 56,113, 2, 95,124,254, 57,222,154, 61, 27, 74,165, 18, 0, 96, 48, 24,160, 45, 46,134,155,155,155,213,130,213, 72, 93, +110,187,114,229,202,212,224,224,224, 91,150, 6, 45,127,205,162, 14,130, 32,192,100, 50,161,166,166, 6,203,151, 47, 55, 81, 74, +183, 53, 50, 38,173, 22,175,169, 83,167, 66,167,251,243,124,240,232,232,104, 0, 64, 88, 88, 24,186,116,233, 98,125,207, 48, 12, +181,151,243,147,127,117, 66,181,205,183, 35, 19,151, 1, 0,130,131,131, 17, 25, 25,105, 17,213,117,114,214,165, 69,238,105,129, + 85,159, 82,188,120, 45,127,201,196, 55, 63, 88, 38,151,178,162, 73,255,233,132, 16,181, 8,112,247,130,184,215, 12, 16,117,232, +205, 14,160,253, 3,248,101, 6,222, 29, 90,196, 76,170,212,253, 16,239,229,229,123, 76,171,173,207,185, 46, 46, 36, 36, 4, 7, + 15, 30, 68,155, 54,109, 48,103,206, 28, 68, 69, 69, 65, 46,151, 35, 63, 63, 31,149,149,149,144,203,229, 40, 43, 43, 67, 76, 76, + 12,171, 84, 42,251, 58, 42,176, 8, 33, 49,207, 13,141,143,227,252,219, 35,161,223,131,248,101,110, 31,249,166,253,217,111, 18, + 66, 54,216, 30,184,218, 66, 68, 11,134, 13, 27, 6,141, 70,227, 63,123,246,236, 38,139, 44,119,119,247, 47, 8, 33,131, 68, 34, +145,129, 16, 2,134, 97,172,135, 29, 91, 94, 27, 12, 6, 49,203,178, 59, 53, 26,205, 83, 77,200,103, 59, 79, 79,207,164, 35, 71, +142,248,203,229,114, 36, 38, 38, 58, 69, 92, 41,149,202,223,199,143, 31,223,250,139, 47,190,216, 77, 8, 25,232,136,200,178, 21, + 87,227,198,141,203, 60,115,230,204,172,218,223, 57,125,250,244,244,103,159,125,118,219,166, 77,155,194, 8, 33,219, 8, 33,163, + 26, 19, 89, 12,195,132, 70, 70, 70, 34, 55, 55, 23,249,249,249,168,169,169, 65,126,126, 62, 0, 32, 43, 43, 11,193,193,193, 80, +171,213, 8, 14, 14, 70, 76, 76, 12, 88,150, 13,180, 39,191, 74,165,114,208,240,225,195,185,195,135, 15, 35, 47, 47, 15, 30, 30, + 30,144,203,229,224,121, 30,207, 63,255,188,120,197,138, 21,255,118, 84, 96,133,132,132, 60,218,175, 95, 63, 46, 53, 53, 21,215, +174, 93,131, 78,167, 67, 90, 90, 26, 84, 42, 21,158,126,250,105,241,210,165, 75,135, 58, 42,176, 0,116,122,225,133, 23,242,109, +197,149, 5,114,185,156,180,107,215, 78,235,237,237, 29, 11,224,186, 35,156,147, 39, 79, 46, 88,188,120,113,175, 95,127,253,117, +134,229,195, 95,127,253,117, 58, 0,172, 92,185,242,160,175,175,111, 44, 0,123, 5, 22, 40,165,194, 99,143, 61,150, 41,145, 72, + 32, 18,137, 32,145, 72,110, 73, 98,177, 24, 12,195, 40,205, 95,103,241, 55, 5, 33,164, 27,128, 15,112,115,135,213,108, 74,233, +177, 22, 34,178, 78, 19, 66, 98, 6, 15, 30,108, 21, 89,187,118,237,194,192,129, 3, 81, 82, 82,130,212,212, 84, 91,113,117,183, +124,176, 32, 8, 2, 68, 34, 17,150, 45, 91, 6,131,193,128, 47,191,252, 18,223,124,243,205, 45,247, 80,149, 74,133, 85,171, 86, + 57,180,156,197,243, 60, 54,109,218,132, 25,211,167, 91,197,149,249,161, 26, 1,254,254,240,246,241, 65,122,122,122,163, 2,171, +184,184,120,238,246,237,219,209,144,147,251,246,237,219,173,175,109,157,220,237,201, 39,203,178,208,233,116,120,248,225, 63, 79, + 26,155, 60,121,178,245,181, 86,171, 5,203,178,150,186, 32,246,114, 86, 83, 96,152,219,159,159, 13,154, 54,205,250, 90,163,209, +212,203,249,119,176, 90,213,105,193,170, 11, 41,185,229, 31,113, 4, 93, 22, 76,124,228,153, 16, 63, 21,104, 69, 62,196, 15,205, +197, 57,173, 12, 43,214,254, 12, 0,152, 58, 50, 6,157,250, 47,132,126,227, 35,152,252, 32,145, 60,155,101,124, 3,192,156,186, +248,124,124,124,188, 77, 38, 19, 8, 33,144,203,229,104,223,190, 61,220,220,220, 80, 88, 88,136,151, 95,126, 25,187,119,239,134, +193, 96,128, 88, 44, 70,155, 54,109, 96, 48, 24,238,107,130,245,234,211,229,239, 45, 82, 23,157,250, 10,201,127,148, 64,230, 29, +130,217,143,199,121, 38,126,121,124, 46,128,233, 45,169,242, 45, 59, 86, 34, 35, 35,177,110,221, 58,255,137, 19, 39, 54, 73,100, +213,212,212,188,163, 82,169,250,109,216,176,193,127,248,240,225,127,185,126,245,234, 85,244,234,213, 43, 63, 47, 47,239,157,219, + 17, 87,106,181, 26, 55,110,220,184,237,117,115,139,184,218,179,103, 79,168, 89,168,248,190,254,250,235,118,139, 44, 66,200, 35, +195,135, 15, 95,191,113,227,198, 86, 99,199,142,205,249,225,135, 31,142, 3,120,174,174,124,125,247,221,119,199, 5, 65, 16,109, +222,188, 57, 20, 64,163, 34,203, 96, 48,136,149, 74, 37,206,158, 61,139, 41, 83,166,220,226,160,106, 89,206, 6,128,180,180, 52, +180,105,211, 6,149,149,149,118,249, 49,250,250,250,250,235,245,122, 60,251,236,179,184,113,227, 79,119,197, 86,173, 90, 89,234, +212,199,209,122,244,247,247,247,175,174,174, 70,207,158, 61, 81, 83, 83, 3, 0, 24, 61,122, 52, 68, 34, 17, 10, 10, 10, 32, 18, +137,124,154,208, 60, 62,131, 7, 15,206,169,239,162, 74,165, 50,120,122,122,182,119,144,211,123,232,208,161,217,235,215,175,255, +203, 82,221,241,227,199,255,227,229,229,245,171,151,151, 87, 59, 7, 57, 5, 91, 49, 37, 22,139,111, 17, 88, 34,145, 8, 12,195, + 8,248,251,227, 61, 0,150, 93,109,107, 0,116,105, 65,150, 44,171,200,218,181,107, 23, 58,118,236,136,226,226, 98, 92,188,120, +241,174,139, 43, 27, 65, 2,142,227,172,227,220,205,205, 13, 49, 49, 49, 86,113, 69, 8, 65, 85, 85, 21, 56,142,179,220,175,237, +186,249,149,148,148, 32, 48, 32, 0, 74,165, 18,109, 35, 34,112,229,242,101, 0,176,190,150, 74,165, 32,132,192,100, 50, 53, 86, +135,229,184,233, 75,245,170,179,155,199, 34,134, 26, 52, 21, 7, 5, 65, 16, 4,203, 61,159, 58,131,211,199,199, 7, 21, 21, 21, +246,114,222,251, 2,139, 16,210, 27, 64, 18,108,182, 70, 18, 66,152,174, 65,202,207, 22, 76,232,247, 76,191, 14,222,168, 46,188, + 6, 55,165, 15,136, 58, 12, 43,214,254,140, 11, 25, 55, 93,163, 86,124,115, 10,155,222, 28, 0,184,123,161,157, 74,131, 0,149, +100,120,125, 2, 75,171,213, 86, 26,141, 70, 47,119,119,119,112, 28, 7,137, 68,130,162,162, 34,204,153, 51, 7, 91,183,110, 69, + 88, 88, 24,120,158,135, 84, 42, 69, 65, 65, 1,196, 98,177, 67,187, 19, 57,142, 12, 78,124,254,223,225,242,128, 8, 20,237, 89, + 96,158,133,186,226,133,161,140,228,253,239,206,141, 37,132,188, 79, 41, 45,104, 41,149,111, 17, 4, 10,133, 2,254,254,254, 88, +180,104,145,255,204,153, 51,191,132,131, 7, 67, 83, 74,211, 8, 33,125,158,127,254,249,164,162,162, 34,255,200,200, 72, 40, 20, + 10, 40, 20, 10,228,231,231, 99,228,200,145,249,121,121,121, 77,181,142,125, 62,126,252,120,127,177, 88,140,171, 87,175,194,203, +203,203, 42, 12,155, 42,174, 84, 42,213,239,191,254,250,107,232,253,247,223,143, 75,151, 46,161,125,251,246,216,186,117,171,239, +227,143, 63,222,168,200, 34,132, 72, 1,188,187,117,235,214, 96,142,227,200,247,223,127, 31, 12,224, 49,123,126,251,235,175,191, + 14, 19,137, 68,171, 8, 33, 15, 81, 74,117,117,125, 71, 34,145, 24,115,115,115, 69, 33, 33, 33,248,236,179,207,192, 48, 12,114, +115,115, 49,107,214, 44, 44, 94,188, 24,241,241,241, 80, 42,149, 8, 9, 9, 65, 74, 74, 10, 20, 10,133, 93, 75, 27,133,133,133, +249, 60,207,135,236,222,189, 27,133,133,127,198,196, 11, 13, 13,133,217, 95, 67,227,104, 93,230,228,228,228, 19, 66, 66,206,156, + 57,131,140,140, 12, 12, 28, 56, 16, 63,252,240, 3, 30,120,224, 1, 0,128, 94,175,111, 74,240, 61,158,101, 89,218, 64,253, 19, + 0,158,206,228, 52, 79, 90, 14,113, 10,130, 32, 88,196,149,237, 95, 91,209,213,200,111,254, 93,224, 97,243,218,212, 82, 51, 57, +112,224, 64,104,181, 90, 40, 20,138, 70, 39,224, 59, 45,176, 68, 34, 17,230,205,155,135, 23, 95,124, 17,254,254,254,152, 49, 99, + 6, 56,142,179, 38,219,149, 0, 71,224,231,239,223,224,117,139, 15, 86, 35,247, 75,165,135,135,199, 60,134, 97, 70,177,118, 84, + 28,207,243,188, 32, 8,219, 74, 75, 75, 27, 12,211, 96,113, 72,183,167, 45,108,235,160,145,188,222, 54,103, 93, 90,228, 94,134, +165,116, 73,102,211, 92,210, 45,226,234,133,190,207,244,235,160,198,142,125,199, 33, 54,148, 0,250,242, 6, 90,214, 8, 34,150, +195, 95,197, 5, 55, 96, 58, 60,147,153,153, 9,181, 90,109,189, 17,118,236,216, 17, 71,143, 30, 69,187,118,237,192,243,188,245, +243,243,231,207,195, 96, 48, 28,112, 96,226,102,125,100,162, 85,211,223, 90,160, 68,202, 6,168,229, 18,244,141,189, 31,240,142, + 2, 43,146,226,131, 87,135,122,249,123,171, 86,180,164,202,183,116, 68,139, 16,154, 51,103, 78,126, 81, 81,209,147, 77,124, 90, + 76, 43, 46, 46,238, 51,123,246,236,124,141, 70, 3,115,232,139,219, 18, 87, 0, 80, 93, 93,253,244,250,245,235,243,147,146,146, +160, 80, 40,160, 84, 42,155, 44,176, 44,150,171,185,115,231,182, 14, 9, 9, 65,122,122, 58, 60, 60, 60,224,237,237,141,232,232, +104, 28, 62,124,216, 55, 36, 36,100,183,121,151, 81,125,229,212, 1,120, 99,212,168, 81,217, 21, 21, 21,194,240,225,195,179, 8, + 33, 91, 8, 33,107,234, 73, 91,134, 15, 31,158, 85, 81, 81, 33,140, 25, 51, 38, 3,192, 43,245,137, 43,243, 13,247,122, 74, 74, + 10, 60, 60, 60,208,174, 93, 59,116,236,216, 17,221,186,117, 3,112,211, 55,161,125,251,246, 8, 15, 15, 7, 0,156, 57,115, 6, +132,144,124,123,202, 94, 94, 94,190,107,227,198,141,198,144,144, 16,116,238,220, 25,177,177,177,232,222,189, 59, 66, 67, 67, 49, +111,222, 60,125,101,101,229,174, 38, 8,172, 29, 91,183,110, 53,134,132,132, 32, 54, 54, 22, 82,169, 20,209,209,209, 8, 10, 10, +194,162, 69,139,244,165,165,165,187,154,208, 76,215, 83, 82, 82,216, 6, 4,183, 10, 64,190,131,156, 55, 78,156, 56,193, 62,248, +224,131,127,217,205, 27, 23, 23,247,127, 10,133,194, 3,128,163,126,125,212, 86, 84, 73,165, 82,107,178,124,206,113,220, 63,193, +130, 53, 21,192, 57, 0,233, 0,102,180,164,140,217,238, 22, 44, 42, 42,194,197,139, 23,145,156,156,140, 7, 31,124, 16,135, 14, + 29, 2,110,134,105,232,122, 55, 31,112, 41,165, 16,137, 68,136,140,140,196,171,175,190,138,157, 59,119, 34, 45, 45, 13, 70,163, +209, 42,128, 24,134,177, 88, 68,237,182, 96,137,197, 98,248,251,251,195,104, 52, 90,173, 87, 0,112,229,242,101,112, 28, 7, 65, + 16,160,215,235, 27,181, 96,121,120,120,204,251,244,211, 79, 95,209,104, 52,129,133,133,133,126,182, 41, 63, 63,223, 47, 55, 55, +215, 47, 59, 59,219,239,198,141, 27,126,153,153,153,126,215,174, 93, 11, 92,178,100,201, 43, 30, 30, 30,118,185,214,176, 44,139, +232,232,104, 76,158, 60,217,154, 62,250,232, 35,107, 74, 74, 74,178, 58,165, 59, 50,175, 69, 38, 46,195,160, 66,106, 77, 59,125, +137, 53,165,190, 62,161, 33,206, 91,180,200,223, 69, 96,217, 6,248, 66,151, 96,197,194, 5,227,123, 61,211, 47, 74,133,159,246, + 37, 99,225,247, 87, 47,253,145,173,129,144,159, 2,161,240, 34,166,142,140, 65,251, 48, 47,180, 15,243,194,212,145, 49, 16, 10, + 82, 65,139,211, 65,165,106,100, 20, 11, 57, 13,152, 77,151, 44, 88,176,160,196,203,203, 11,238,238,238,144, 72, 36,200,202,202, + 66,135, 14, 29,172, 55, 71,137, 68, 2,134, 97,240,214, 91,111, 21, 22, 22, 22,174,181,183, 32,114, 9,243,194,146,105,163,253, +197,110, 10,224,198, 1,168,148, 10,124,246,241, 50,160, 34, 7, 96,197, 24,218,187, 11, 27,232,163,126,136, 16,210,174, 5,221, +128, 0, 0,249,249,249, 24, 61,122,244,109, 9, 33,139,200, 42, 42, 42,234, 51,113,226,196,252,131, 7, 15, 58,141,179,172,172, +172,207,140, 25, 51,242,243,242,242,110,241, 39,112, 20, 10,133, 98,186, 32, 8,234,165, 75,151,230,197,196,196,228, 14, 27, 54, + 44,119,192,128, 1,185, 9, 9, 9,185,157, 59,119,206,237,211,167, 79,174, 94,175,231,212,106,245,178, 70,242,180,247,135, 31, +126, 24, 54,110,220,184,204,205,155, 55, 7,141, 24, 49, 34, 14,192,103,148,210,151,108, 19,128, 79, 71,140, 24, 17,183,121,243, +230,160,113,227,198,101,126,247,221,119,141,250, 96,213,212,212,204,155, 49,227,230, 60,165, 84, 42, 33,145, 72,224,235,235,107, + 21,194, 98,177, 24, 82,169, 20,213,213,213,152, 61,123, 54, 74, 74, 74, 22,218, 83,118,157, 78,183,105,254,252,249, 25, 43, 86, +172, 48, 84, 87, 87,131,101, 89,228,231,231, 99,234,212,169,250, 77,155, 54,221,168,172,172,116,212, 87, 10, 70,163,113,211,219, +111,191,157,254,241,199, 31, 27, 56,142, 67,105,105, 41, 84, 42, 21,222,120,227, 13,253,134, 13, 27,178,170,171,171, 63,113,148, +179,123,247,238, 87, 51, 51, 51, 85, 85, 85,127,117, 87, 20,137, 68, 68, 46,151,119, 3,176,207, 17,206,152,152,152,244,235,215, +175, 43, 23, 46, 92,184,191,127,255,254, 75,148, 74,229,101,165, 82,121,185,127,255,254, 75, 63,252,240,195, 36, 55, 55,183, 56, + 0,191, 58, 56,118, 4, 91, 81,101,107,189,178,124,198,113,220,223,222,130, 69, 41, 77,162,148, 70, 83, 74,239,167,148,254,214, + 82,197, 85,106,106, 42,122,246,236,137,238,221,187,227,240,225,195, 72, 72, 72,104, 17, 34,203, 34,176, 56,142,195,227,143, 63, +142,189,123,247,162,109,219,182, 86,199,118, 91, 39,119, 71, 68,134,201,100, 66,167, 78,157,160,211,235,111,177,124,113, 28, 7, + 95, 63, 63, 92,189,122,213, 46, 11, 22,195, 48,163,134, 13, 27,198,156, 63,127, 30, 81, 81, 81, 56,117,234,148, 53,157, 57,115, + 6,231,206,157, 67,106,106, 42, 46, 92,184,128,216,216, 88,100,102,102, 98,216,176, 97, 12,195, 48,163, 26,225,181,219,218,100, +217, 9,216,152, 5,207, 89,156,182, 90,228, 94, 71, 93,129, 70,209,198, 71, 54,238,161,182, 44,126,250, 45, 25,139,182,223,216, + 36, 0,223,253,120,186,244,167,105,221, 5, 24,182, 61,129, 78, 35, 63,191,185, 44, 8, 64, 40, 72,133, 97,219, 83, 32, 50, 31, + 28,202, 22,163,172,202, 88,239,137,214, 6,131,225,152,167,167,231,150, 13, 27, 54,140,127,246,217,103, 37, 0, 32,147,201,240, +218,107,175,129, 82, 10,137, 68, 2,150,101, 49,113,226,196,138,130,130,130,229,148,210,171,118, 14,102,247, 86,158,146,183,158, +156, 52,199, 13,103,214, 3,140, 24, 26, 69, 12,162, 7,140, 71, 65,218, 81,160,232, 34,192,138,177, 54,241,121,159,255, 76, 94, +182, 30, 64,207,150, 34,176,174, 92,185,114,219, 86,166,218,130,136, 16,210,103,230,204,153, 95, 22, 21, 21, 61,233, 76,206,167, +159,126, 58,105,239,222,189,254, 77,229, 41, 47, 47,127, 13,192,107, 78,186, 49,158, 50,199,122,217,182,113,227,198,208,140,140, +140,165, 0, 30,178,253, 78,151, 46, 93, 22, 89,156,224,237, 17, 87,102,222, 47,221,220,220,166, 76,157, 58, 53,118,197,138, 21, +144,201,100, 80,169, 84, 72, 75, 75,179,198,193,169,174,174,198,152, 49, 99,160,211,233,206, 83, 74,215,217,153, 95, 19, 33,228, +169,119,222,121,103,252,202,149, 43,135,176, 44,235,203,243,124, 97,117,117,245,238,234,234,234,245, 77,217, 69, 69, 41, 21, 8, + 33, 99,231,204,153, 51,118,249,242,229,195, 24,134,241, 51,153, 76,154,242,242,242,237,213,213,213, 77,138,173,117,228,200,145, +194,213,171, 87,255, 81, 88, 88, 24, 21, 28, 28, 92,170, 80, 40,244,122,189,158,117,119,119, 87,201,229,242, 24, 0, 71, 1, 92, +112,132, 51, 57, 57, 57,111,237,218,181, 25, 58,157, 46,114,237,218,181, 7, 85, 42,213, 94, 66, 8, 17,139,197,158,238,238,238, +125, 1,236, 7,112,197,161, 39, 67,134, 17,108,173, 85,181,253,175,204, 15,106,255, 4, 11, 86,139,131, 57, 76,195, 41, 74, 41, + 52, 26, 13,206,159, 63,143,190,125,251, 2,230, 48, 13, 61,122,244, 56,117,232,208, 33, 36, 36, 36, 32, 57, 57, 25,177,177,177, +167, 8, 33,119, 60, 76,131,173, 5,203, 34,164, 90,183,110,109,125,111,155,108,124,176,236, 2,207,243, 16,139,197,224, 56, 14, +129, 65, 65,214,223,162,148,226,234,213,171,208,106,181,118, 9, 44,150,101, 89, 66, 8,198,140, 25, 99,215,239, 62,246,216, 99, +216,191,127, 63, 88, 59,213, 32,203,178, 8, 11, 11,107,244, 59,150, 91,142,189,156,193,193,193, 77,230,180,213, 34,127, 27,129, +101,139,244,252,202,133,227, 87, 30,121,243, 98, 94,205,119,103,114, 42, 95, 5, 64, 65,229,191,116,246, 97, 31,233, 23,145, 5, +221,250, 30, 32,170,155,147, 13,173,200, 5,145,251, 35,139,182,194, 59, 63, 93,206, 35, 2, 93,218,208, 15,150,148,148, 76,253, +232,163,143,216, 95,126,249,101,244,226,197,139, 61,162,162,162,240,212, 83, 79, 65,175,215,227,220,185,115,120,241,197, 23,181, +133,133,133,235, 74, 74, 74,150,216, 91, 8, 31, 5,247,246,138,151, 31,241,102,140, 21, 64,222, 41, 64,234, 1, 31, 79, 5,206, + 30, 63, 0,228, 37, 3,172, 24, 96, 37,120,160,115, 20,162,219,223, 31, 69, 8,233, 65, 41, 61,116,183, 43,223,104, 52,138,123, +247,238,237, 52,113,101, 43,136,224,160, 31,151,189, 34,171,127,255,254, 73,148, 82,105, 11,121,122, 63, 69, 8, 25,121,237,218, +181, 69,151, 47, 95,254,169,246,245,203,151, 47,255,212,187,119,111,209,233,211,167,167,219, 35,174,108,172, 77,189, 14, 31, 62, +124,160, 71,143, 30,177, 51,103,206, 68,108,108, 44,218,181,107,135, 51,103,206, 32, 57, 57, 25,137,137,137, 48, 24, 12,231,170, +171,171, 19, 28,204, 47,143,155,187,250,214, 59,177, 14, 4,220, 12, 19,177,209, 89,156, 47,189,244,210,217,244,244,244, 34, 95, + 95,223,120,177, 88,220, 25, 55,253,124,242, 0,108,112, 84, 8, 89,240,226,139, 47,158, 73, 79, 79,215,180,106,213,234, 65, 51, +167, 26, 64, 54,128, 79,155,192,153,115,242,228,201,224,110,221,186, 49, 34,145,136,178, 44, 11,145, 72, 68, 57,142,163,102,191, + 25, 10, 0,219,183,111,151, 2,208,194,133, 59, 61, 46,173, 97, 26,114,115,115,173,226,202, 38,208,104, 76,143, 30, 61, 78,153, +197,149,229,154,233, 46,229, 21,243,231,207,199,186,117,235,208, 88, 4,114,243,110, 61,210, 24,159,197,130,197,243, 60, 12, 6, + 3, 82, 83, 83, 65, 8, 1,207,243,214,101, 65, 75,136, 6,147,201,212, 96,164,119,158,231,121,189, 94,143,175,191,254,218, 46, +145,245,213, 87, 95,161,166,166, 6,124, 35,202,205, 54,164, 66,151, 46, 93,160,213,106, 17, 20, 20,100,177, 56,219, 26, 69, 28, + 18,172, 22,206,200,200, 72,104, 52, 26,248,248,220,220,103, 19,242,244, 11,127, 90,247, 42,255, 57,113,127, 73, 67,141,123,139, + 53, 32, 76,237, 65, 13,252,247,131, 58, 72,250,140,236,234,129, 48,127, 37, 68, 98, 41,114,203, 76,216,119,169, 28,155, 14,228, +221,168,228, 77, 67, 82,179, 42, 83,236,108,140, 7, 3, 3, 3,103,241, 60,223,145, 97, 24, 25,165,180,130,101,217,211, 57, 57, + 57,243, 40,165,169,142, 20, 66,237,206, 94,241,148,179, 30, 34,145,132,242,130, 0,128, 1,136, 37,177, 55,255, 50, 55,223, 87, +215, 24,196, 60, 37,223,229, 23,106,158,187,219,149,239,235,235,187, 81,163,209,220,115,145,220,189,189,189,103, 55, 37,220,195, + 61,248, 36, 62, 86,169, 84, 46,166,148,250, 86, 86, 86,178,114,185, 92, 96, 24,166,176,172,172,236,109, 74,233, 39,112,225,110, +181,139, 37,146,123,120, 35, 95, 45, 0, 48, 5, 64, 57,165, 52,195, 85,115,119,188,157,186, 2, 56,133, 58,118, 11, 54,116,237, + 78,193,219,219,251,216,207, 63,255,252, 64,155, 54,109, 24, 91, 71,118,134, 97,172,193, 49, 25,134, 1,199,221,180, 67, 28, 56, +112,192, 52,102,204,152,163,121,121,121,189,234,227, 84,169, 84,191,156, 59,119,238,225,210,210,210,191, 8, 41,219,200,238,150, +247,149,149,149,152, 56,113,226,158,178,178,178, 58,143,202, 81,171,213,203,223,127,255,253, 87, 70,140, 24,193, 88,194, 74,216, + 38,203,177, 62,150,100, 48, 24,240,249,231,159, 11, 43, 87,174, 92, 85, 82, 82, 82,239,206,195,160,160,160, 27, 57, 57, 57,193, +150,144, 9,245, 37, 91,132,133,133,229,102,100,100, 4,221, 73,206,127,140,192, 50, 15, 10,210, 41, 80, 62,154,128,140, 98,128, + 78, 12,129,196, 72, 73, 26, 64,127, 17, 65,177, 58, 57, 39,199,117, 46,155, 11,127,215,201,226,174, 30, 76,235, 66,157,109,210, + 6,141,199,184, 50, 2,200,114,181, 93,203, 27, 55,119,123, 76, 17, 66,228, 94, 94, 94,123, 89,150, 13,181, 88, 96,108,125,130, +234, 56,232, 57, 35, 63, 63,191, 95, 67,241, 20, 9, 33,247, 41,149,202,143,121,158,143,179,231,176,103,150,101,143,151,151,151, + 79,106,232,176,231,230,216, 69,232,227,227,115, 53, 51, 51,243, 62,153, 76,102, 93,186,180, 45,119,237,188, 95,185,114, 5,189, +123,247,206,204,205,205, 13,187,147,156,255, 40,129,229,130, 11, 46,184,224,130, 11, 46,220,243,194,183,157,151,151,215,207, 34, +145, 72,106, 43, 34,107,191,182,192,100, 50,213, 20, 22, 22, 14,108,104,181,165, 57, 56,239,121, 88,148,166,189,233,230,191,216, +253,221,254,246,114,154, 83,239,150,206,217,140,101,167, 78,228,236,109,230, 76,188, 71,242,217,187,165,114, 90,202,107, 47,175, + 35,156,246,246, 41, 7,243, 73,157,157,207,230,226,116,214, 56,170, 35,159,180, 25,218, 61,241, 30,201,103,239,150,198, 89,187, +255,216,195,235, 40,167, 61,125,170, 9,249,164,206,206,103,115,113,222,238, 56,106, 32,159,244,118,251, 82, 61,109,159,232,168, +246,184, 23, 19,231,160,234,165,205, 36,242,136, 13, 63,105,169,156,182,245,224,204,144,254,205,112, 60, 64,146,179, 57,107,213, +167,179,144,104,222, 49,178,223, 60,240,156, 86,118,103,180,123,173,178, 58,133,215,150,211, 89,117,105,203,227,172,126,223,220, +156,206, 26, 75,181, 57,157,209,239,235,106,247,102,108, 35,103,229,211, 41, 99,169, 57,250,124, 29,253,231,182,121,107,115, 58, + 99, 44,213,230,116, 70,191,191, 19,156,206, 24, 75,117,113, 58,163,223,215,215,246,255, 20, 75, 33,211,148,202,106, 38,147,165, +211, 15,120,108,142, 19,185,155, 67,100, 18, 66,168, 57,130,109,139,231,116,114, 27, 37,154, 57, 19,157,200,217,199, 89,109,212, + 28,253,221,150,211, 89,252,181,121,156,209, 78,117,113,222,110,126,235,201,167,211,203,126,187,253,254, 78,113, 58,185,141,156, + 50,150,106,113,246,113,242, 67, 64, 31,155,247,137,206,228,116,214, 88,170, 35,159,183,221, 78,117,113,222,110,126,235,201,167, +211,203,238,140, 57,164,185,120,239, 5,112, 45, 33, 19,205, 33,132, 44,131,206,153,220,205, 97,197,105, 46, 75,155,179,172, 56, +117,240,238,119, 34, 93,146,179,243,105,206, 31,249, 59, 5,171,115,141, 37,215, 88,186,151,199, 82, 93,253,134, 82,154, 72, 8, +153,219,146,250,121,109, 78,103, 9,161, 58,202,126, 91, 99,169,246,255, 58, 99, 44, 53,194, 73,154,163,252,206, 30, 79, 45, 17, + 76, 75,201,136, 89,213,210,102,224,235,211,146, 27,160,153,242,217,231, 94, 40,123,115,228,147, 16,146,216, 76,101,191, 87,234, +212, 53,150, 92, 99,169,197,141,165, 90,125,178,143,179, 44, 67,206,126,144,170,205,233,140,223,176,229,112, 86, 31,109,238,178, + 59,115, 44, 53, 71,219,223, 43,248,255, 1, 0,166,217,112,195,230,179,174,247, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, 0}; diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index f16fc9ebe05..c0aba90f90f 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -87,7 +87,7 @@ DEF_ICON(ICON_BLANK012b) /* various ui */ DEF_ICON(ICON_HELP) -DEF_ICON(ICON_GHOSTDRAW) +DEF_ICON(ICON_GHOST_ENABLED) DEF_ICON(ICON_COLOR) DEF_ICON(ICON_LINKED) DEF_ICON(ICON_UNLINKED) @@ -102,11 +102,11 @@ DEF_ICON(ICON_BORDER_RECT) DEF_ICON(ICON_BORDER_LASSO) DEF_ICON(ICON_FREEZE) DEF_ICON(ICON_STYLUS_PRESSURE) -DEF_ICON(ICON_BLANK032) -DEF_ICON(ICON_BLANK033) -DEF_ICON(ICON_BLANK034) -DEF_ICON(ICON_BLANK035) -DEF_ICON(ICON_BLANK036) +DEF_ICON(ICON_GHOST_DISABLED) +DEF_ICON(ICON_NEW) +DEF_ICON(ICON_FILE_TICK) +DEF_ICON(ICON_CANCEL) +DEF_ICON(ICON_URL) DEF_ICON(ICON_BLANK037) DEF_ICON(ICON_BLANK038) DEF_ICON(ICON_BLANK039) @@ -236,7 +236,7 @@ DEF_ICON(ICON_SURFACE_DATA) DEF_ICON(ICON_EMPTY_DATA) DEF_ICON(ICON_SETTINGS) DEF_ICON(ICON_RENDER_ANIMATION) -DEF_ICON(ICON_BLANK080E) +DEF_ICON(ICON_RENDER_STILL) DEF_ICON(ICON_BLANK080F) DEF_ICON(ICON_BOIDS) DEF_ICON(ICON_STRANDS) @@ -665,9 +665,9 @@ DEF_ICON(ICON_STICKY_UVS_VERT) DEF_ICON(ICON_CLIPUV_DEHLT) DEF_ICON(ICON_CLIPUV_HLT) DEF_ICON(ICON_SNAP_PEEL_OBJECT) -DEF_ICON(ICON_BLANK221) DEF_ICON(ICON_GRID) DEF_ICON(ICON_GEARS) +DEF_ICON(ICON_BLANK221) DEF_ICON(ICON_BLANK224) DEF_ICON(ICON_BLANK225) DEF_ICON(ICON_BLANK226) diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index 98d58c92da4..ac1378af859 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -325,9 +325,9 @@ void graph_header_buttons(const bContext *C, ARegion *ar) /* ghost curves */ // XXX these icons need to be changed if (sipo->ghostCurves.first) - uiDefIconButO(block, BUT, "GRAPH_OT_ghost_curves_clear", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_DATA_CURVE, xco,yco,XIC,YIC, "Clear F-Curve snapshots (Ghosts) for this Graph Editor instance"); + uiDefIconButO(block, BUT, "GRAPH_OT_ghost_curves_clear", WM_OP_INVOKE_REGION_WIN, ICON_GHOST_DISABLED, xco,yco,XIC,YIC, "Clear F-Curve snapshots (Ghosts) for this Graph Editor instance"); else - uiDefIconButO(block, BUT, "GRAPH_OT_ghost_curves_create", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_OB_CURVE, xco,yco,XIC,YIC, "Create snapshot (Ghosts) of selected F-Curves as background aid for this Graph Editor instance"); + uiDefIconButO(block, BUT, "GRAPH_OT_ghost_curves_create", WM_OP_INVOKE_REGION_WIN, ICON_GHOST_ENABLED, xco,yco,XIC,YIC, "Create snapshot (Ghosts) of selected F-Curves as background aid for this Graph Editor instance"); xco+= XIC; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index c771259d5a1..6f7a498fb2c 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1225,50 +1225,50 @@ static void rna_def_scene_render_data(BlenderRNA *brna) static EnumPropertyItem image_type_items[] = { {0, "", 0, "Image", NULL}, - {R_PNG, "PNG", 0, "PNG", ""}, - {R_JPEG90, "JPEG", 0, "JPEG", ""}, + {R_PNG, "PNG", ICON_FILE_IMAGE, "PNG", ""}, + {R_JPEG90, "JPEG", ICON_FILE_IMAGE, "JPEG", ""}, #ifdef WITH_OPENJPEG - {R_JP2, "JPEG2000", 0, "JPEG 2000", ""}, + {R_JP2, "JPEG2000", ICON_FILE_IMAGE, "JPEG 2000", ""}, #endif - {R_BMP, "BMP", 0, "BMP", ""}, - {R_TARGA, "TARGA", 0, "Targa", ""}, - {R_RAWTGA, "RAWTARGA", 0, "Targa Raw", ""}, - //{R_DDS, "DDS", 0, "DDS", ""}, // XXX not yet implemented - {R_HAMX, "HAMX", 0, "HamX", ""}, - {R_IRIS, "IRIS", 0, "Iris", ""}, + {R_BMP, "BMP", ICON_FILE_IMAGE, "BMP", ""}, + {R_TARGA, "TARGA", ICON_FILE_IMAGE, "Targa", ""}, + {R_RAWTGA, "RAWTARGA", ICON_FILE_IMAGE, "Targa Raw", ""}, + //{R_DDS, "DDS", ICON_FILE_IMAGE, "DDS", ""}, // XXX not yet implemented + {R_HAMX, "HAMX", ICON_FILE_IMAGE, "HamX", ""}, + {R_IRIS, "IRIS", ICON_FILE_IMAGE, "Iris", ""}, {0, "", 0, " ", NULL}, #ifdef WITH_OPENEXR - {R_OPENEXR, "OPENEXR", 0, "OpenEXR", ""}, - {R_MULTILAYER, "MULTILAYER", 0, "MultiLayer", ""}, + {R_OPENEXR, "OPENEXR", ICON_FILE_IMAGE, "OpenEXR", ""}, + {R_MULTILAYER, "MULTILAYER", ICON_FILE_IMAGE, "MultiLayer", ""}, #endif - {R_TIFF, "TIFF", 0, "TIFF", ""}, // XXX only with G.have_libtiff - {R_RADHDR, "RADHDR", 0, "Radiance HDR", ""}, - {R_CINEON, "CINEON", 0, "Cineon", ""}, - {R_DPX, "DPX", 0, "DPX", ""}, + {R_TIFF, "TIFF", ICON_FILE_IMAGE, "TIFF", ""}, // XXX only with G.have_libtiff + {R_RADHDR, "RADHDR", ICON_FILE_IMAGE, "Radiance HDR", ""}, + {R_CINEON, "CINEON", ICON_FILE_IMAGE, "Cineon", ""}, + {R_DPX, "DPX", ICON_FILE_IMAGE, "DPX", ""}, {0, "", 0, "Movie", NULL}, - {R_AVIRAW, "AVIRAW", 0, "AVI Raw", ""}, - {R_AVIJPEG, "AVIJPEG", 0, "AVI JPEG", ""}, + {R_AVIRAW, "AVIRAW", ICON_FILE_MOVIE, "AVI Raw", ""}, + {R_AVIJPEG, "AVIJPEG", ICON_FILE_MOVIE, "AVI JPEG", ""}, #ifdef _WIN32 - {R_AVICODEC, "AVICODEC", 0, "AVI Codec", ""}, + {R_AVICODEC, "AVICODEC", ICON_FILE_MOVIE, "AVI Codec", ""}, #endif #ifdef WITH_QUICKTIME - {R_QUICKTIME, "QUICKTIME", 0, "QuickTime", ""}, + {R_QUICKTIME, "QUICKTIME", ICON_FILE_MOVIE, "QuickTime", ""}, #endif #ifdef __sgi - {R_MOVIE, "MOVIE", 0, "Movie", ""}, + {R_MOVIE, "MOVIE", ICON_FILE_MOVIE, "Movie", ""}, #endif #ifdef WITH_FFMPEG - {R_H264, "H264", 0, "H.264", ""}, - {R_XVID, "XVID", 0, "Xvid", ""}, + {R_H264, "H264", ICON_FILE_MOVIE, "H.264", ""}, + {R_XVID, "XVID", ICON_FILE_MOVIE, "Xvid", ""}, // XXX broken #if 0 #ifdef WITH_OGG - {R_THEORA, "THEORA", 0, "Ogg Theora", ""}, + {R_THEORA, "THEORA", ICON_FILE_MOVIE, "Ogg Theora", ""}, #endif #endif - {R_FFMPEG, "FFMPEG", 0, "FFMpeg", ""}, + {R_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, "FFMpeg", ""}, #endif - {R_FRAMESERVER, "FRAMESERVER", 0, "Frame Server", ""}, + {R_FRAMESERVER, "FRAMESERVER", ICON_FILE_SCRIPT, "Frame Server", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef WITH_OPENEXR -- cgit v1.2.3 From 331a58d44c310c77f6bf8f9194948a73163922c2 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 10 Oct 2009 09:34:22 +0000 Subject: * Added the new Render Icons to the menu as well. * Added Tooltips for Help Scripts. * Minor tweak to Continuous Grab Tooltip, as it now works on Mac too. --- release/scripts/ui/space_info.py | 15 ++++++++------- source/blender/makesrna/intern/rna_userdef.c | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 3b4eed0c298..4ab9902d67d 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -85,7 +85,6 @@ class INFO_MT_file_import(bpy.types.Menu): layout.itemO("import.3ds", text="3DS") layout.itemO("import.obj", text="OBJ") - class INFO_MT_file_export(bpy.types.Menu): __label__ = "Export" @@ -99,7 +98,6 @@ class INFO_MT_file_export(bpy.types.Menu): layout.itemO("export.ply", text="PLY") layout.itemO("export.x3d", text="X3D") - class INFO_MT_file_external_data(bpy.types.Menu): __label__ = "External Data" @@ -170,8 +168,8 @@ class INFO_MT_render(bpy.types.Menu): rd = context.scene.render_data - layout.itemO("screen.render", text="Render Image") - layout.item_booleanO("screen.render", "animation", True, text="Render Animation") + layout.itemO("screen.render", text="Render Image", icon='ICON_RENDER_STILL') + layout.item_booleanO("screen.render", "animation", True, text="Render Animation", icon='ICON_RENDER_ANIMATION') layout.itemS() @@ -194,7 +192,6 @@ class INFO_MT_help(bpy.types.Menu): layout.itemO("help.user_community", icon='ICON_URL') layout.itemS() layout.itemO("help.operator_cheat_sheet") - bpy.types.register(INFO_HT_header) bpy.types.register(INFO_MT_file) @@ -221,31 +218,37 @@ class HelpOperator(bpy.types.Operator): return ('FINISHED',) class HELP_OT_manual(HelpOperator): + '''The Blender Wiki manual''' __idname__ = "help.manual" __label__ = "Manual" __URL__ = 'http://wiki.blender.org/index.php/Manual' class HELP_OT_release_logs(HelpOperator): + '''Information about the changes in this version of Blender''' __idname__ = "help.release_logs" __label__ = "Release Logs" __URL__ = 'http://www.blender.org/development/release-logs/' class HELP_OT_blender_website(HelpOperator): + '''The official Blender website''' __idname__ = "help.blender_website" __label__ = "Blender Website" __URL__ = 'http://www.blender.org/' class HELP_OT_blender_eshop(HelpOperator): + '''Buy official Blender resources and merchandise online''' __idname__ = "help.blender_eshop" __label__ = "Blender e-Shop" __URL__ = 'http://www.blender3d.org/e-shop' class HELP_OT_developer_community(HelpOperator): + '''Get involved with Blender development''' __idname__ = "help.developer_community" __label__ = "Developer Community" __URL__ = 'http://www.blender.org/community/get-involved/' class HELP_OT_user_community(HelpOperator): + '''Get involved with other Blender users''' __idname__ = "help.user_community" __label__ = "User Community" __URL__ = 'http://www.blender.org/community/user-community/' @@ -275,7 +278,6 @@ class HELP_OT_operator_cheat_sheet(bpy.types.Operator): print("See OperatorList.txt textblock") return ('FINISHED',) - bpy.ops.add(HELP_OT_manual) bpy.ops.add(HELP_OT_release_logs) bpy.ops.add(HELP_OT_blender_website) @@ -283,4 +285,3 @@ bpy.ops.add(HELP_OT_blender_eshop) bpy.ops.add(HELP_OT_developer_community) bpy.ops.add(HELP_OT_user_community) bpy.ops.add(HELP_OT_operator_cheat_sheet) - diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index f8135f32eda..c1fb3e88084 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1657,7 +1657,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop= RNA_def_property(srna, "continuous_mouse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_CONTINUOUS_MOUSE); - RNA_def_property_ui_text(prop, "Continuous Grab", "Experimental option to allow moving the mouse outside the view (Linux only at the moment)"); + RNA_def_property_ui_text(prop, "Continuous Grab", "Experimental option to allow moving the mouse outside the view"); prop= RNA_def_property(srna, "global_pivot", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCKAROUND); -- cgit v1.2.3 From 562184862920f872baa386f9461eb114109a8cdc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Oct 2009 10:49:17 +0000 Subject: - added redraw notifier. - removed custom invoke function, use generic names (was misleading since conversion is done on selection, not just active). - made convert mesh to curve use the 'keep_original' option. --- source/blender/blenkernel/intern/mesh.c | 93 ++++++++++++++++-------------- source/blender/editors/object/object_add.c | 72 +++++++---------------- 2 files changed, 71 insertions(+), 94 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index ce30075c424..0065c348ad0 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -983,23 +983,23 @@ void mesh_to_curve(Scene *scene, Object *ob) /* make new mesh data from the original copy */ DerivedMesh *dm= mesh_get_derived_final(scene, ob, CD_MASK_MESH); - MVert *mv, *mverts= dm->getVertArray(dm); + MVert *mverts= dm->getVertArray(dm); MEdge *med, *medge= dm->getEdgeArray(dm); MFace *mf, *mface= dm->getFaceArray(dm); - int totvert = dm->getNumVerts(dm); int totedge = dm->getNumEdges(dm); int totface = dm->getNumFaces(dm); int totedges = 0; int i; + /* only to detect edge polylines */ EdgeHash *eh = BLI_edgehash_new(); EdgeHash *eh_edge = BLI_edgehash_new(); - ListBase edges = {NULL, NULL}; - EdgeLink *edl; + ListBase edges = {NULL, NULL}; + /* create edges from all faces (so as to find edges not in any faces) */ mf= mface; for (i = 0; i < totface; i++, mf++) { if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) @@ -1021,9 +1021,9 @@ void mesh_to_curve(Scene *scene, Object *ob) med= medge; for(i=0; iv1, med->v2)) { - BLI_edgehash_insert(eh_edge, med->v1, med->v2, NULL); + EdgeLink *edl= MEM_callocN(sizeof(EdgeLink), "EdgeLink"); - edl= MEM_callocN(sizeof(EdgeLink), "EdgeLink"); + BLI_edgehash_insert(eh_edge, med->v1, med->v2, NULL); edl->edge= med; BLI_addtail(&edges, edl); totedges++; @@ -1037,7 +1037,9 @@ void mesh_to_curve(Scene *scene, Object *ob) cu->flag |= CU_3D; while(edges.first) { - ListBase polyline = {NULL, NULL}; + /* each iteration find a polyline and add this as a nurbs poly spline */ + + ListBase polyline = {NULL, NULL}; /* store a list of VertLink's */ int closed = FALSE; int totpoly= 0; MEdge *med_current= ((EdgeLink *)edges.last)->edge; @@ -1045,43 +1047,40 @@ void mesh_to_curve(Scene *scene, Object *ob) int endVert= med_current->v2; int ok= TRUE; - Nurb *nu; - BPoint *bp; - VertLink *vl; - appendPolyLineVert(&polyline, startVert); totpoly++; appendPolyLineVert(&polyline, endVert); totpoly++; BLI_freelinkN(&edges, edges.last); totedges--; - - while(ok) { + while(ok) { /* while connected edges are found... */ ok = FALSE; i= totedges; while(i) { - MEdge *ed= edl->edge; + EdgeLink *edl; + i-=1; edl= BLI_findlink(&edges, i); + med= edl->edge; - if(ed->v1==endVert) { - endVert = ed->v2; - appendPolyLineVert(&polyline, ed->v2); totpoly++; + if(med->v1==endVert) { + endVert = med->v2; + appendPolyLineVert(&polyline, med->v2); totpoly++; BLI_freelinkN(&edges, edl); totedges--; ok= TRUE; } - else if(ed->v2==endVert) { - endVert = ed->v1; + else if(med->v2==endVert) { + endVert = med->v1; appendPolyLineVert(&polyline, endVert); totpoly++; BLI_freelinkN(&edges, edl); totedges--; ok= TRUE; } - else if(ed->v1==startVert) { - startVert = ed->v2; + else if(med->v1==startVert) { + startVert = med->v2; prependPolyLineVert(&polyline, startVert); totpoly++; BLI_freelinkN(&edges, edl); totedges--; ok= TRUE; } - else if(ed->v2==startVert) { - startVert = ed->v1; + else if(med->v2==startVert) { + startVert = med->v1; prependPolyLineVert(&polyline, startVert); totpoly++; BLI_freelinkN(&edges, edl); totedges--; ok= TRUE; @@ -1097,32 +1096,38 @@ void mesh_to_curve(Scene *scene, Object *ob) } /* --- nurbs --- */ + { + Nurb *nu; + BPoint *bp; + VertLink *vl; + + /* create new 'nurb' within the curve */ + nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb"); + + nu->pntsu= totpoly; + nu->pntsv= 1; + nu->orderu= 4; + nu->flagu= 2 | (closed ? CU_CYCLIC:0); /* endpoint */ + nu->resolu= 12; + + nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*totpoly, "bpoints"); + + /* add points */ + vl= polyline.first; + for (i=0, bp=nu->bp; i < totpoly; i++, bp++, vl=(VertLink *)vl->next) { + VecCopyf(bp->vec, mverts[vl->index].co); + bp->f1= SELECT; + bp->radius = bp->weight = 1.0; + } + BLI_freelistN(&polyline); - /* create new 'nurb' within the curve */ - nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb"); - - nu->pntsu= totpoly; - nu->pntsv= 1; - nu->orderu= 4; - nu->flagu= 2 | (closed ? CU_CYCLIC:0); /* endpoint */ - nu->resolu= 12; - - nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*totpoly, "bpoints"); - - /* add points */ - vl= polyline.first; - for (i=0, bp=nu->bp; i < totpoly; i++, bp++, vl=vl->next) { - VecCopyf(bp->vec, mverts[vl->index].co); - bp->f1= SELECT; - bp->radius = bp->weight = 1.0; + /* add nurb to curve */ + BLI_addtail(&cu->nurb, nu); } - BLI_freelistN(&polyline); - - /* add nurb to curve */ - BLI_addtail(&cu->nurb, nu); /* --- done with nurbs --- */ } + ((Mesh *)ob->data)->id.us--; ob->data= cu; ob->type= OB_CURVE; } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 47053ea6d93..0b7dbf791e0 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1018,8 +1018,8 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) /**************************** Convert **************************/ static EnumPropertyItem convert_target_items[]= { - {OB_CURVE, "CURVE", 0, "Curve", ""}, - {OB_MESH, "MESH", 0, "Mesh", ""}, + {OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve from Mesh/Text", ""}, + {OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Mesh", ""}, {0, NULL, 0, NULL, NULL}}; static void curvetomesh(Scene *scene, Object *ob) @@ -1035,14 +1035,6 @@ static void curvetomesh(Scene *scene, Object *ob) object_free_modifiers(ob); } -static void meshtocurve(Scene *scene, Object *ob) -{ - mesh_to_curve(scene, ob); - - if(ob->type == OB_CURVE) - object_free_modifiers(ob); -} - static int convert_poll(bContext *C) { Object *obact= CTX_data_active_object(C); @@ -1081,8 +1073,22 @@ static int convert_exec(bContext *C, wmOperator *op) continue; else if (ob->type==OB_MESH && target == OB_CURVE) { ob->flag |= OB_DONE; - meshtocurve(scene, ob); - ob->recalc |= OB_RECALC; + + ob1= copy_object(ob); + ob1->recalc |= OB_RECALC; + + basen= MEM_mallocN(sizeof(Base), "duplibase"); + *basen= *base; + BLI_addhead(&scene->base, basen); /* addhead: otherwise eternal loop */ + basen->object= ob1; + basen->flag |= SELECT; + base->flag &= ~SELECT; + ob->flag &= ~SELECT; + + mesh_to_curve(scene, ob1); + + if(ob1->type==OB_CURVE) + object_free_modifiers(ob1); /* after derivedmesh calls! */ } else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */ ob->flag |= OB_DONE; @@ -1233,48 +1239,14 @@ static int convert_exec(bContext *C, wmOperator *op) BASACT= basact; DAG_scene_sort(scene); - WM_event_add_notifier(C, NC_SCENE, scene); + WM_event_add_notifier(C, NC_SCENE|ND_DRAW, scene); - return OPERATOR_FINISHED; -} - -static int convert_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - Object *obact= CTX_data_active_object(C); - uiPopupMenu *pup; - uiLayout *layout; - char *title; - - if(obact->type==OB_FONT) { - pup= uiPupMenuBegin(C, "Convert Font to", 0); - layout= uiPupMenuLayout(pup); - uiItemEnumO(layout, "Curve", 0, op->type->idname, "target", OB_CURVE); - } - else { - if(obact->type == OB_MBALL) - title= "Convert Metaball to"; - else if(obact->type == OB_CURVE) - title= "Convert Curve to"; - else if(obact->type == OB_SURF) - title= "Convert Nurbs Surface to"; - else if(obact->type == OB_MESH) - title= "Convert Modifiers to"; - else - return OPERATOR_CANCELLED; - pup= uiPupMenuBegin(C, title, 0); - layout= uiPupMenuLayout(pup); - } - - uiItemBooleanO(layout, "Mesh (keep original)", 0, op->type->idname, "keep_original", 1); - uiItemBooleanO(layout, "Mesh (delete original)", 0, op->type->idname, "keep_original", 0); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } + void OBJECT_OT_convert(wmOperatorType *ot) { /* identifiers */ @@ -1283,7 +1255,7 @@ void OBJECT_OT_convert(wmOperatorType *ot) ot->idname= "OBJECT_OT_convert"; /* api callbacks */ - ot->invoke= convert_invoke; + ot->invoke= WM_menu_invoke; ot->exec= convert_exec; ot->poll= convert_poll; -- cgit v1.2.3 From 85ebea5838f9bb4bb65354215a87cba8f812425c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Oct 2009 12:29:11 +0000 Subject: When in localview, MKey moves objects out of localview, added redraw notifiers --- source/blender/editors/object/object_add.c | 2 +- source/blender/editors/object/object_relations.c | 12 +++++++++--- source/blender/windowmanager/WM_api.h | 2 ++ source/blender/windowmanager/intern/wm_operators.c | 12 +++++++++--- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 0b7dbf791e0..d79ec460dec 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1239,7 +1239,7 @@ static int convert_exec(bContext *C, wmOperator *op) BASACT= basact; DAG_scene_sort(scene); - WM_event_add_notifier(C, NC_SCENE|ND_DRAW, scene); + WM_event_add_notifier(C, NC_SCENE|NC_OBJECT|ND_DRAW, scene); /* is NC_SCENE needed ? */ diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 4a0c812f7b1..d6a55077be9 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -978,8 +978,14 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op) static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event) { - move_to_layer_init(C, op); - return WM_operator_props_popup(C, op, event); + View3D *v3d= CTX_wm_view3d(C); + if(v3d && v3d->localvd) { + return WM_operator_confirm_message(C, op, "Move from localview"); + } + else { + move_to_layer_init(C, op); + return WM_operator_props_popup(C, op, event); + } } static int move_to_layer_exec(bContext *C, wmOperator *op) @@ -1023,7 +1029,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op) /* warning, active object may be hidden now */ - WM_event_add_notifier(C, NC_SCENE, scene); + WM_event_add_notifier(C, NC_SCENE|NC_OBJECT|ND_DRAW, scene); /* is NC_SCENE needed ? */ DAG_scene_sort(scene); return OPERATOR_FINISHED; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index eaf8b00163c..44e404524f5 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -158,6 +158,8 @@ int WM_operator_winactive (struct bContext *C); int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op); +int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, char *message); + /* operator api */ void WM_operator_free (struct wmOperator *op); void WM_operator_stack_clear(struct bContext *C); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 915f4c80663..7db6669ca74 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -488,20 +488,26 @@ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } -/* op->invoke */ -int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event) +/* Can't be used as an invoke directly, needs message arg (can be NULL) */ +int WM_operator_confirm_message(bContext *C, wmOperator *op, char *message) { uiPopupMenu *pup; uiLayout *layout; pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); layout= uiPupMenuLayout(pup); - uiItemO(layout, NULL, 0, op->type->idname); + uiItemO(layout, message, 0, op->type->idname); uiPupMenuEnd(C, pup); return OPERATOR_CANCELLED; } + +int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event) +{ + return WM_operator_confirm_message(C, op, NULL); +} + /* op->invoke, opens fileselect if path property not set, otherwise executes */ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) { -- cgit v1.2.3 From f716f22d1f984c7323ee71682a197d91cb0d06b0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Oct 2009 16:17:33 +0000 Subject: changed limits for some rna values, added object.scale_linked_x/y/z --- source/blender/makesrna/intern/rna_curve.c | 3 +- source/blender/makesrna/intern/rna_object.c | 56 +++++++++++++++++++++++++-- source/blender/makesrna/intern/rna_sequence.c | 2 +- source/blender/makesrna/intern/rna_ui.c | 2 - 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 3b6bd2255f2..1f1caeaa9b5 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -471,7 +471,8 @@ static void rna_def_font(BlenderRNA *brna, StructRNA *srna) /* number values */ prop= RNA_def_property(srna, "text_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "fsize"); - RNA_def_property_range(prop, 0.1f, 10.0f); + RNA_def_property_range(prop, 0.0001f, 10000.0f); + RNA_def_property_ui_range(prop, 0.01, 10, 1, 1); RNA_def_property_ui_text(prop, "Font size", ""); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 611585c8809..46885b89f2c 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -508,6 +508,32 @@ static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value) ob->rotmode= value; } +/* not called directly */ +static void rna_Object_scale_linked_set(Object *ob, float value, int axis) +{ + if(ob->size[axis]==0.0f || value==0.0f) { + ob->size[0]= ob->size[1]= ob->size[2]= value; + } + else { + VecMulf(ob->size, value / ob->size[axis]); + } +} + +static void rna_Object_scale_x_linked_set(PointerRNA *ptr, float value) +{ + rna_Object_scale_linked_set(ptr->data, value, 0); +} +static void rna_Object_scale_y_linked_set(PointerRNA *ptr, float value) +{ + rna_Object_scale_linked_set(ptr->data, value, 1); +} +static void rna_Object_scale_z_linked_set(PointerRNA *ptr, float value) +{ + rna_Object_scale_linked_set(ptr->data, value, 2); +} + + + static PointerRNA rna_MaterialSlot_material_get(PointerRNA *ptr) { Object *ob= (Object*)ptr->id.data; @@ -1276,6 +1302,26 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Scale", "Scaling of the object."); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + /* linked scale for the transform panel */ + prop= RNA_def_property(srna, "scale_linked_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "size[0]"); + RNA_def_property_float_funcs(prop, NULL, "rna_Object_scale_x_linked_set", NULL); + RNA_def_property_ui_text(prop, "Scale X", "Scaling of the objects X axis."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + + prop= RNA_def_property(srna, "scale_linked_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "size[1]"); + RNA_def_property_float_funcs(prop, NULL, "rna_Object_scale_y_linked_set", NULL); + RNA_def_property_ui_text(prop, "Scale Y", "Scaling of the objects X axis."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + + prop= RNA_def_property(srna, "scale_linked_z", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "size[2]"); + RNA_def_property_float_funcs(prop, NULL, "rna_Object_scale_z_linked_set", NULL); + RNA_def_property_ui_text(prop, "Scale Z", "Scaling of the objects Z axis."); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update"); + + /* delta transforms */ prop= RNA_def_property(srna, "delta_location", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "dloc"); @@ -1494,25 +1540,27 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "dupli_frames_start", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupsta"); - RNA_def_property_range(prop, 1, 32767); + RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Dupli Frames Start", "Start frame for DupliFrames."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); prop= RNA_def_property(srna, "dupli_frames_end", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupend"); - RNA_def_property_range(prop, 1, 32767); + RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Dupli Frames End", "End frame for DupliFrames."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); prop= RNA_def_property(srna, "dupli_frames_on", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupon"); - RNA_def_property_range(prop, 1, 1500); + RNA_def_property_range(prop, 1, MAXFRAME); + RNA_def_property_ui_range(prop, 1, 1500, 1, 0); RNA_def_property_ui_text(prop, "Dupli Frames On", "Number of frames to use between DupOff frames."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); prop= RNA_def_property(srna, "dupli_frames_off", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupoff"); - RNA_def_property_range(prop, 0, 1500); + RNA_def_property_range(prop, 0, MAXFRAME); + RNA_def_property_ui_range(prop, 0, 1500, 1, 0); RNA_def_property_ui_text(prop, "Dupli Frames Off", "Recurring frames to exclude from the Dupliframes."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c index 9404fb775c3..c48031d51b3 100644 --- a/source/blender/makesrna/intern/rna_sequence.c +++ b/source/blender/makesrna/intern/rna_sequence.c @@ -548,7 +548,7 @@ static void rna_def_sequence(BlenderRNA *brna) /* functions */ func= RNA_def_function(srna, "getStripElem", "give_stripelem"); RNA_def_function_ui_description(func, "Return the strip element from a given frame or None."); - prop= RNA_def_int(func, "frame", 0, INT_MIN, INT_MAX, "Frame", "The frame to get the strip element from", INT_MIN, INT_MAX); + prop= RNA_def_int(func, "frame", 0, -MAXFRAME, MAXFRAME, "Frame", "The frame to get the strip element from", -MAXFRAME, MAXFRAME); RNA_def_property_flag(prop, PROP_REQUIRED); RNA_def_function_return(func, RNA_def_pointer(func, "elem", "SequenceElement", "", "strip element of the current frame")); } diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index a1b412c70f4..303511a2dca 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -343,7 +343,6 @@ static void menu_draw(const bContext *C, Menu *hdr) static void rna_Menu_unregister(const bContext *C, StructRNA *type) { - ARegionType *art; MenuType *mt= RNA_struct_blender_type_get(type); if(!mt) @@ -362,7 +361,6 @@ static void rna_Menu_unregister(const bContext *C, StructRNA *type) static StructRNA *rna_Menu_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { - ARegionType *art; MenuType *mt, dummymt = {0}; Menu dummymenu= {0}; PointerRNA dummymtr; -- cgit v1.2.3 From 811a7678276e7f0aefaf4145276a71cdd2915a26 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 10 Oct 2009 17:19:49 +0000 Subject: Add operator and operator type flag for GRAB_POINTER, don't coopt the OPTYPE_BLOCKING flag for that. It will check if either the operator or operator type flags are set on top of the user preference before grabbing the pointer. I've set that flag for 3d view navigation operators, others should be set too (no transform, I'll deal with that one). --- source/blender/editors/space_view3d/view3d_edit.c | 6 +++--- source/blender/makesdna/DNA_windowmanager_types.h | 2 +- source/blender/windowmanager/WM_types.h | 1 + source/blender/windowmanager/intern/wm_event_system.c | 6 ++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 4c96e1fee39..3cd810d5c16 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -621,7 +621,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; } /* ************************ viewmove ******************************** */ @@ -743,7 +743,7 @@ void VIEW3D_OT_move(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; } /* ************************ viewzoom ******************************** */ @@ -976,7 +976,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) ot->poll= ED_operator_view3d_active; /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); } diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 2b986d6d802..0292f01fd6d 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -330,7 +330,7 @@ typedef struct wmOperator { #define OPERATOR_PASS_THROUGH 8 /* wmOperator flag */ - +#define OP_GRAB_POINTER 1 /* ************** wmEvent ************************ */ /* for read-only rna access, dont save this */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index d746df01421..31cb5ee0832 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -44,6 +44,7 @@ struct wmWindowManager; #define OPTYPE_UNDO 2 /* do undo push after after */ #define OPTYPE_BLOCKING 4 /* let blender grab all input from the WM (X11) */ #define OPTYPE_MACRO 8 +#define OPTYPE_GRAB_POINTER 16 /* */ /* context to call operator in for WM_operator_name_call */ /* rna_ui.c contains EnumPropertyItem's of these, keep in sync */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ea73ed38123..f1104feaf5b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -462,8 +462,10 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P } else if(retval & OPERATOR_RUNNING_MODAL) { /* grab cursor during blocking modal ops (X11) */ - if(ot->flag & OPTYPE_BLOCKING) - WM_cursor_grab(CTX_wm_window(C), (U.uiflag & USER_CONTINUOUS_MOUSE)); + if(ot->flag & OPTYPE_BLOCKING) { + int warp = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER)); + WM_cursor_grab(CTX_wm_window(C), warp); + } } else WM_operator_free(op); -- cgit v1.2.3 From 622ffe263a61c1312e14ce74de148e7106b4b183 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sat, 10 Oct 2009 17:40:56 +0000 Subject: Bringing back the transform orientations panel. Orientations enum in view3d. Full list of custom orientation (RNAified) in scene. --- release/scripts/ui/space_view3d.py | 9 +++- source/blender/editors/transform/transform_ops.c | 17 +++---- source/blender/makesrna/RNA_enum_types.h | 4 ++ source/blender/makesrna/intern/rna_scene.c | 25 +++++++++ source/blender/makesrna/intern/rna_space.c | 64 +++++++++++++++++++++++- 5 files changed, 107 insertions(+), 12 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 33ae3472053..3d91f73d209 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1256,8 +1256,15 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel): view = context.space_data col = layout.column() - col.itemO("TFM_OT_select_orientation", text="Select") + + col.itemR(view, "transform_orientation") col.itemO("TFM_OT_create_orientation", text="Create") + +# orientation_index = view.__rna__.properties["transform_orientation"].items[view.transform_orientation].value +# +# if orientation_index >= 4: +# orientation = context.scene.orientations[orientation_index - 4] +# col.itemR(orientation, "name") col.itemO("TFM_OT_delete_orientation", text="Delete") # Operators diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 0913f0ea273..b0e79b3b062 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -123,6 +123,8 @@ static int select_orientation_exec(bContext *C, wmOperator *op) int orientation = RNA_enum_get(op->ptr, "orientation"); BIF_selectTransformOrientationValue(C, orientation); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); return OPERATOR_FINISHED; } @@ -140,12 +142,6 @@ static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event return OPERATOR_CANCELLED; } -static EnumPropertyItem *select_orientation_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - *free= 1; - return BIF_enumTransformOrientation(C); -} - void TFM_OT_select_orientation(struct wmOperatorType *ot) { PropertyRNA *prop; @@ -162,7 +158,7 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) ot->poll = ED_operator_areaactive; prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); - RNA_def_enum_funcs(prop, select_orientation_itemf); + RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); } @@ -172,6 +168,8 @@ static int delete_orientation_exec(bContext *C, wmOperator *op) int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); BIF_removeTransformOrientationIndex(C, selected_index); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); return OPERATOR_FINISHED; } @@ -221,8 +219,7 @@ static int create_orientation_exec(bContext *C, wmOperator *op) BIF_createTransformOrientation(C, op->reports, name, use, overwrite); - /* Do we need more refined tags? */ - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); return OPERATOR_FINISHED; } @@ -393,7 +390,7 @@ void Properties_Constraints(struct wmOperatorType *ot) RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); - RNA_def_enum_funcs(prop, select_orientation_itemf); + RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); } void TFM_OT_translate(struct wmOperatorType *ot) diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index ccf4b7a2db3..ff4eee8d074 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -58,6 +58,10 @@ extern EnumPropertyItem unpack_method_items[]; extern EnumPropertyItem object_type_items[]; +struct bContext; +struct PointerRNA; +EnumPropertyItem *rna_TransformOrientation_itemf(struct bContext *C, struct PointerRNA *ptr, int *free); + #endif /* RNA_ENUM_TYPES */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 6f7a498fb2c..f987c99a090 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -428,6 +428,24 @@ static void rna_Physics_update(bContext *C, PointerRNA *ptr) } #else +static void rna_def_transform_orientation(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + int matrix_dimsize[]= {3, 3}; + + srna= RNA_def_struct(brna, "TransformOrientation", NULL); + + prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "mat"); + RNA_def_property_multi_array(prop, 2, matrix_dimsize); + + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "name"); + RNA_def_struct_name_property(srna, prop); +} + static void rna_def_tool_settings(BlenderRNA *brna) { StructRNA *srna; @@ -2247,12 +2265,19 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock"); + /* Transform Orientations */ + prop= RNA_def_property(srna, "orientations", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "transform_spaces", NULL); + RNA_def_property_struct_type(prop, "TransformOrientation"); + RNA_def_property_ui_text(prop, "Transform Orientations", ""); + /* Nestled Data */ rna_def_tool_settings(brna); rna_def_unit_settings(brna); rna_def_scene_render_data(brna); rna_def_scene_game_data(brna); rna_def_scene_render_layer(brna); + rna_def_transform_orientation(brna); /* Scene API */ RNA_api_scene(srna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index f2ab9360856..99ee3e653f0 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -77,6 +77,7 @@ EnumPropertyItem space_type_items[] = { static EnumPropertyItem dc_all_items[] = {DC_RGB, DC_RGBA, DC_ALPHA, DC_Z, DC_LCMS, DC_ZERO}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" @@ -142,6 +143,66 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr) } } +static int rna_TransformOrientation_getf(PointerRNA *ptr) +{ + View3D *v3d= (View3D*)ptr->data; + + return v3d->twmode; +} + +EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Scene *scene; + ListBase *transform_spaces; + TransformOrientation *ts= NULL; + + 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; + + RNA_enum_item_add(&item, &totitem, &global); + RNA_enum_item_add(&item, &totitem, &normal); + RNA_enum_item_add(&item, &totitem, &local); + RNA_enum_item_add(&item, &totitem, &view); + + if(C) { + scene= CTX_data_scene(C); + + if(scene) { + transform_spaces = &scene->transform_spaces; + ts = transform_spaces->first; + } + else + { + printf("no scene\n"); + } + } + else + { + printf("no context\n"); + } + + if(ts) + RNA_enum_item_add_separator(&item, &totitem); + + for(; ts; ts = ts->next) { + tmp.identifier = ts->name; + tmp.name= ts->name; + tmp.value = i++; + RNA_enum_item_add(&item, &totitem, &tmp); + } + + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; +} + /* Space Image Editor */ static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr) @@ -728,7 +789,8 @@ static void rna_def_space_3dview(BlenderRNA *brna) prop= RNA_def_property(srna, "transform_orientation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "twmode"); RNA_def_property_enum_items(prop, transform_orientation_items); - RNA_def_property_ui_text(prop, "Transform Orientation", "The alignment of manipulator handles."); + RNA_def_property_enum_funcs(prop, "rna_TransformOrientation_getf", NULL, "rna_TransformOrientation_itemf"); + RNA_def_property_ui_text(prop, "Transform Orientation", "Transformation orientation."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From deb30e8f9e7858a6e7800a31d0b2051471406162 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Sat, 10 Oct 2009 18:42:20 +0000 Subject: Fix #19571 (reported by Markus Ilmola): Added missing callbacks. Was leading to crashs when the raytree was empty. --- source/blender/render/intern/raytrace/rayobject.cpp | 6 +++++- source/blender/render/intern/source/rayobject_instance.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 621fd3f794e..d8880b51c6c 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -559,6 +559,9 @@ static float RE_rayobject_empty_cost(RayObject *o) return 0.0; } +static void RE_rayobject_empty_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +{} + static RayObjectAPI empty_api = { RE_rayobject_empty_intersect, @@ -566,7 +569,8 @@ static RayObjectAPI empty_api = NULL, //static void RE_rayobject_instance_done(RayObject *o); RE_rayobject_empty_free, RE_rayobject_empty_bb, - RE_rayobject_empty_cost + RE_rayobject_empty_cost, + RE_rayobject_empty_hint_bb }; static RayObject empty_raytree = { &empty_api, {0, 0} }; diff --git a/source/blender/render/intern/source/rayobject_instance.c b/source/blender/render/intern/source/rayobject_instance.c index 9329d110870..e2f4dc5a9dd 100644 --- a/source/blender/render/intern/source/rayobject_instance.c +++ b/source/blender/render/intern/source/rayobject_instance.c @@ -41,6 +41,9 @@ static void RE_rayobject_instance_free(RayObject *o); static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max); static float RE_rayobject_instance_cost(RayObject *o); +static void RE_rayobject_instance_hint_bb(RayObject *o, RayHint *hint, float *min, float *max) +{} + static RayObjectAPI instance_api = { RE_rayobject_instance_intersect, @@ -48,7 +51,8 @@ static RayObjectAPI instance_api = NULL, //static void RE_rayobject_instance_done(RayObject *o); RE_rayobject_instance_free, RE_rayobject_instance_bb, - RE_rayobject_instance_cost + RE_rayobject_instance_cost, + RE_rayobject_instance_hint_bb }; typedef struct InstanceRayObject -- cgit v1.2.3 From a3f6b0ed00e2f93c7e666763e94bdf29003110ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Oct 2009 21:23:20 +0000 Subject: - add torus back from 2.4x as an operator bpy.ops.mesh.primitive_torus_add(major_radius=1, minor_radius=0.25, major_segments=48, minor_segments=16) - experemental dynamic menus, used for INFO_MT_file, INFO_MT_file_import, INFO_MT_file_export and INFO_MT_mesh_add. these can have items added from python. eg. - removed OBJECT_OT_mesh_add, use the python add menu instead. - made mesh primitive ops - MESH_OT_primitive_plane_add, ...cube_add, etc. work in object mode. - RNA scene.active_object wrapped - bugfix [#19466] 2.5: Tweak menu only available for mesh objects added within Edit Mode ED_object_exit_editmode was always doing an undo push, made this optional using the existing flag - EM_DO_UNDO, called everywhere except when adding primitives. --- release/scripts/io/add_mesh_torus.py | 98 ++++++++++ release/scripts/io/export_3ds.py | 17 +- release/scripts/io/export_fbx.py | 18 +- release/scripts/io/export_mdd.py | 14 +- release/scripts/io/export_obj.py | 20 +- release/scripts/io/export_ply.py | 6 +- release/scripts/io/export_x3d.py | 19 +- release/scripts/io/import_3ds.py | 19 +- release/scripts/io/import_obj.py | 25 +-- release/scripts/modules/dynamic_menu.py | 95 ++++++++++ release/scripts/ui/space_info.py | 66 +++++-- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/include/ED_object.h | 1 + source/blender/editors/mesh/editmesh_add.c | 224 +++++++++-------------- source/blender/editors/mesh/mesh_ops.c | 5 +- source/blender/editors/mesh/meshtools.c | 2 +- source/blender/editors/object/object_add.c | 118 ++---------- source/blender/editors/object/object_edit.c | 11 +- source/blender/editors/object/object_intern.h | 1 - source/blender/editors/object/object_ops.c | 2 - source/blender/editors/screen/screen_ops.c | 2 +- source/blender/editors/space_outliner/outliner.c | 8 +- source/blender/makesrna/intern/rna_scene.c | 31 +++- source/blender/makesrna/intern/rna_texture.c | 3 +- source/blender/python/intern/bpy_operator_wrap.c | 3 + source/blender/windowmanager/intern/wm_files.c | 2 +- 26 files changed, 450 insertions(+), 362 deletions(-) create mode 100644 release/scripts/io/add_mesh_torus.py create mode 100644 release/scripts/modules/dynamic_menu.py diff --git a/release/scripts/io/add_mesh_torus.py b/release/scripts/io/add_mesh_torus.py new file mode 100644 index 00000000000..a0f41db15d6 --- /dev/null +++ b/release/scripts/io/add_mesh_torus.py @@ -0,0 +1,98 @@ + +import bpy, Mathutils +from math import cos, sin, pi, radians + + +def add_torus(PREF_MAJOR_RAD, PREF_MINOR_RAD, PREF_MAJOR_SEG, PREF_MINOR_SEG): + Vector = Mathutils.Vector + Quaternion = Mathutils.Quaternion + + PI_2= pi*2 + Z_AXIS = 0,0,1 + + verts = [] + faces = [] + i1 = 0 + tot_verts = PREF_MAJOR_SEG * PREF_MINOR_SEG + for major_index in range(PREF_MAJOR_SEG): + verts_tmp = [] + quat = Quaternion( Z_AXIS, (major_index/PREF_MAJOR_SEG)*PI_2) + + for minor_index in range(PREF_MINOR_SEG): + angle = 2*pi*minor_index/PREF_MINOR_SEG + + vec = Vector(PREF_MAJOR_RAD+(cos(angle)*PREF_MINOR_RAD), 0, (sin(angle)*PREF_MINOR_RAD)) * quat + verts.extend([vec.x, vec.y, vec.z]) + + if minor_index+1==PREF_MINOR_SEG: + i2 = (major_index)*PREF_MINOR_SEG + i3 = i1 + PREF_MINOR_SEG + i4 = i2 + PREF_MINOR_SEG + + else: + i2 = i1 + 1 + i3 = i1 + PREF_MINOR_SEG + i4 = i3 + 1 + + if i2>=tot_verts: i2 = i2-tot_verts + if i3>=tot_verts: i3 = i3-tot_verts + if i4>=tot_verts: i4 = i4-tot_verts + + # stupid eekadoodle + if i2: faces.extend( [i1,i3,i4,i2] ) + else: faces.extend( [i2,i1,i3,i4] ) + + i1+=1 + + return verts, faces + + +class MESH_OT_primitive_torus_add(bpy.types.Operator): + '''Add a torus mesh.''' + __idname__ = "mesh.primitive_torus_add" + __label__ = "Add Torus" + __register__ = True + __undo__ = True + __props__ = [ + bpy.props.FloatProperty(attr="major_radius", name="Major Radius", description="Number of segments for the main ring of the torus", default= 1.0, min= 0.01, max= 100.0), + bpy.props.FloatProperty(attr="minor_radius", name="Minor Radius", description="Number of segments for the minor ring of the torus", default= 0.25, min= 0.01, max= 100.0), + bpy.props.IntProperty(attr="major_segments", name="Major Segments", description="Number of segments for the main ring of the torus", default= 48, min= 3, max= 256), + bpy.props.IntProperty(attr="minor_segments", name="Minor Segments", description="Number of segments for the minor ring of the torus", default= 16, min= 3, max= 256), + ] + + def execute(self, context): + verts_loc, faces = add_torus(self.major_radius, self.minor_radius, self.major_segments, self.minor_segments) + + me= bpy.data.add_mesh("Torus") + + me.add_geometry(int(len(verts_loc)/3), 0, int(len(faces)/4)) + me.verts.foreach_set("co", verts_loc) + me.faces.foreach_set("verts_raw", faces) + + sce = context.scene + + # ugh + for ob in sce.objects: + ob.selected = False + + me.update() + ob= bpy.data.add_object('MESH', "Torus") + ob.data= me + context.scene.add_object(ob) + context.scene.active_object = ob + ob.selected = True + + ob.location = tuple(context.scene.cursor_location) + + return ('FINISHED',) + +# Register the operator +bpy.ops.add(MESH_OT_primitive_torus_add) + +# Add to a menu +import dynamic_menu +import space_info +menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, (lambda self, context: self.layout.itemO("mesh.primitive_torus_add", text="Add Torus")) ) + +if __name__ == "__main__": + bpy.ops.mesh.primitive_torus_add() \ No newline at end of file diff --git a/release/scripts/io/export_3ds.py b/release/scripts/io/export_3ds.py index 2c1999c3d45..5ca7d5629d5 100644 --- a/release/scripts/io/export_3ds.py +++ b/release/scripts/io/export_3ds.py @@ -1,12 +1,4 @@ -#!BPY # coding: utf-8 -""" -Name: '3D Studio (.3ds)...' -Blender: 243 -Group: 'Export' -Tooltip: 'Export to 3DS file format (.3ds).' -""" - __author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] __url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") __version__ = "0.90a" @@ -1100,9 +1092,7 @@ def save_3ds(filename, context): # # save_3ds('/test_b.3ds') class EXPORT_OT_3ds(bpy.types.Operator): - ''' - 3DS Exporter - ''' + '''Export to 3DS file format (.3ds).''' __idname__ = "export.3ds" __label__ = 'Export 3DS' @@ -1128,3 +1118,8 @@ class EXPORT_OT_3ds(bpy.types.Operator): return context.active_object != None bpy.ops.add(EXPORT_OT_3ds) + +# Add to a menu +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.3ds", text="Autodesk 3DS...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py index 21b1388ebfe..d159c6588e5 100644 --- a/release/scripts/io/export_fbx.py +++ b/release/scripts/io/export_fbx.py @@ -1,10 +1,3 @@ -#!BPY -""" -Name: 'Autodesk FBX (.fbx)...' -Blender: 249 -Group: 'Export' -Tooltip: 'Selection to an ASCII Autodesk FBX ' -""" __author__ = "Campbell Barton" __url__ = ['www.blender.org', 'blenderartists.org'] __version__ = "1.2" @@ -3341,9 +3334,7 @@ def write_ui(): # GLOBALS.clear() class EXPORT_OT_fbx(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Selection to an ASCII Autodesk FBX''' __idname__ = "export.fbx" __label__ = "Export FBX" @@ -3451,3 +3442,10 @@ bpy.ops.add(EXPORT_OT_fbx) # SMALL or COSMETICAL # - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version') + + +# Add to a menu +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.fbx", text="Autodesk FBX...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + diff --git a/release/scripts/io/export_mdd.py b/release/scripts/io/export_mdd.py index f0e366ea505..1336660aefc 100644 --- a/release/scripts/io/export_mdd.py +++ b/release/scripts/io/export_mdd.py @@ -1,11 +1,3 @@ -#!BPY - -""" - Name: 'Vertex Keyframe Animation (.mdd)...' - Blender: 242 - Group: 'Export' - Tooltip: 'Animated mesh to MDD vertex keyframe file.' -""" __author__ = "Bill L.Nieuwendorp" __bpydoc__ = """\ @@ -180,9 +172,13 @@ class EXPORT_OT_mdd(bpy.types.Operator): bpy.ops.add(EXPORT_OT_mdd) +# Add to a menu +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.mdd", text="Vertex Keyframe Animation (.mdd)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + if __name__=='__main__': #if not pack: # Draw.PupMenu('Error%t|This script requires a full python install') #Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd')) bpy.ops.EXPORT_OT_mdd(path="/tmp/test.mdd") - diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py index 83b400816e3..1e8a152e91f 100644 --- a/release/scripts/io/export_obj.py +++ b/release/scripts/io/export_obj.py @@ -906,14 +906,16 @@ def do_export(filename, context, # orig_scene.makeCurrent() # Window.WaitCursor(0) - + +''' +Currently the exporter lacks these features: +* nurbs +* multiple scene export (only active scene is written) +* particles +''' class EXPORT_OT_obj(bpy.types.Operator): - ''' - Currently the exporter lacks these features: - * nurbs - * multiple scene export (only active scene is written) - * particles - ''' + '''Save a Wavefront OBJ File''' + __idname__ = "export.obj" __label__ = 'Export OBJ' @@ -984,6 +986,10 @@ class EXPORT_OT_obj(bpy.types.Operator): bpy.ops.add(EXPORT_OT_obj) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.obj", text="Wavefront (.obj)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + if __name__ == "__main__": bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj") diff --git a/release/scripts/io/export_ply.py b/release/scripts/io/export_ply.py index 8e79c3741bb..d74cc0e9d7e 100644 --- a/release/scripts/io/export_ply.py +++ b/release/scripts/io/export_ply.py @@ -273,7 +273,9 @@ class EXPORT_OT_ply(bpy.types.Operator): bpy.ops.add(EXPORT_OT_ply) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.ply", text="Stanford (.ply)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + if __name__ == "__main__": bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply") - - diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py index db29afc7d6d..2c6ca749757 100644 --- a/release/scripts/io/export_x3d.py +++ b/release/scripts/io/export_x3d.py @@ -1,10 +1,3 @@ -#!BPY -""" Registration info for Blender menus: -Name: 'X3D Extensible 3D (.x3d)...' -Blender: 245 -Group: 'Export' -Tooltip: 'Export selection to Extensible 3D file (.x3d)' -""" __author__ = ("Bart", "Campbell Barton") __email__ = ["Bart, bart:neeneenee*de"] @@ -1204,9 +1197,7 @@ def x3d_export_ui(filename): # Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) class EXPORT_OT_x3d(bpy.types.Operator): - ''' - X3D Exporter - ''' + '''Export selection to Extensible 3D file (.x3d)''' __idname__ = "export.x3d" __label__ = 'Export X3D' @@ -1229,12 +1220,12 @@ class EXPORT_OT_x3d(bpy.types.Operator): wm = context.manager wm.add_fileselect(self.__operator__) return ('RUNNING_MODAL',) - - def poll(self, context): # Poll isnt working yet - print("Poll") - return context.active_object != None bpy.ops.add(EXPORT_OT_x3d) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.x3d", text="X3D Extensible 3D (.x3d)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + # NOTES # - blender version is hardcoded diff --git a/release/scripts/io/import_3ds.py b/release/scripts/io/import_3ds.py index 339fac839ea..cbd9d8948ab 100644 --- a/release/scripts/io/import_3ds.py +++ b/release/scripts/io/import_3ds.py @@ -1,10 +1,3 @@ -#!BPY -""" -Name: '3D Studio (.3ds)...' -Blender: 244 -Group: 'Import' -Tooltip: 'Import from 3DS file format (.3ds)' -""" __author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin'] __url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") @@ -1130,9 +1123,7 @@ else: ''' class IMPORT_OT_3ds(bpy.types.Operator): - ''' - 3DS Importer - ''' + '''Import from 3DS file format (.3ds)''' __idname__ = "import.3ds" __label__ = 'Import 3DS' @@ -1155,13 +1146,13 @@ class IMPORT_OT_3ds(bpy.types.Operator): wm = context.manager wm.add_fileselect(self.__operator__) return ('RUNNING_MODAL',) - ''' - def poll(self, context): - print("Poll") - return context.active_object != None''' bpy.ops.add(IMPORT_OT_3ds) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("import.3ds", text="3D Studio (.3ds)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func) + # NOTES: # why add 1 extra vertex? and remove it when done? # disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time) diff --git a/release/scripts/io/import_obj.py b/release/scripts/io/import_obj.py index a762005ae7d..a557e4427d8 100644 --- a/release/scripts/io/import_obj.py +++ b/release/scripts/io/import_obj.py @@ -1,11 +1,3 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 249 -Group: 'Import' -Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' -""" __author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" __url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] @@ -1560,15 +1552,9 @@ else: print 'TOTAL TIME: %.6f' % (sys.time() - TIME) ''' -#load_obj('/test.obj') -#load_obj('/fe/obj/mba1.obj') - - class IMPORT_OT_obj(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Load a Wavefront OBJ File.''' __idname__ = "import.obj" __label__ = "Import OBJ" @@ -1593,10 +1579,6 @@ class IMPORT_OT_obj(bpy.types.Operator): bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True), ] - ''' - def poll(self, context): - return True ''' - def execute(self, context): # print("Selected: " + context.active_object.name) @@ -1624,6 +1606,11 @@ class IMPORT_OT_obj(bpy.types.Operator): bpy.ops.add(IMPORT_OT_obj) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("import.obj", text="Wavefront (.obj)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func) + + # NOTES (all line numbers refer to 2.4x import_obj.py, not this file) # check later: line 489 # can convert now: edge flags, edges: lines 508-528 diff --git a/release/scripts/modules/dynamic_menu.py b/release/scripts/modules/dynamic_menu.py new file mode 100644 index 00000000000..ce51dc9937b --- /dev/null +++ b/release/scripts/modules/dynamic_menu.py @@ -0,0 +1,95 @@ +import bpy + +def collect_baseclasses(_class, bases): + + if _class is type or _class is object: + return bases + + bases.append(_class) + for _superclass in _class.__bases__: + collect_baseclasses(_superclass, bases) + + return bases + +def collect_subclasses(_class, subs): + + if _class is type or _class is object: + return subs + + subs.append(_class) + for _subclass in _class.__subclasses__(): + collect_subclasses(_subclass, subs) + + return subs + +class DynMenu(bpy.types.Menu): + + def draw(self, context): + ''' + This is a draw function that is used to call all subclasses draw functions + starting from the registered classes draw function and working down. + + DynMenu.setup() must be called first. + + Sort/group classes could be nice + ''' + + subclass_ls = [] + collect_subclasses(self.__class__, subclass_ls) + # print(subclass_ls) + + for subclass in subclass_ls: + # print("drawwing", subclass) # , dir(subclass)) + subclass.internal_draw(self, context) + # print("subclass.internal_draw", subclass.internal_draw) + +def setup(menu_class): + ''' + Setup subclasses (not needed when self.add() is used) + ''' + bases = collect_baseclasses(menu_class, []) + + # Incase 'DynMenu' isnt last + while bases[-1] is not DynMenu: + bases.pop() + bases.pop() # remove 'DynMenu' + + root_class = bases[-1] # this is the registered class + + for subclass in collect_subclasses(root_class, []): + #print(subclass) + + draw = getattr(subclass, 'draw', None) + if draw and not hasattr(subclass, 'internal_draw'): + # print("replace", subclass, draw) + try: + del subclass.draw + except: + pass + subclass.internal_draw = draw + + root_class.draw = DynMenu.draw + +def add(menu_class, func): + ''' + Add a single function directly without having to make a class + + important that the returned value should be stored in the module that called it. + ''' + + newclass = type('', (menu_class,), {}) + newclass.internal_draw = func + setup(menu_class) + return newclass + +''' +# so we dont need to import this module +DynMenu.setup = setup +DynMenu.add = add + +# Only so we can access as bpy.types. +# dont ever use this directly! +bpy.types.register(DynMenu) +''' + + diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 4ab9902d67d..5a7a3b61cc2 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -1,6 +1,9 @@ import bpy +import dynamic_menu +# reload(dynamic_menu) + class INFO_HT_header(bpy.types.Header): __space_type__ = 'INFO' @@ -36,8 +39,9 @@ class INFO_HT_header(bpy.types.Header): layout.template_running_jobs() layout.itemL(text=scene.statistics()) - -class INFO_MT_file(bpy.types.Menu): + + +class INFO_MT_file(dynamic_menu.DynMenu): __label__ = "File" def draw(self, context): @@ -76,27 +80,31 @@ class INFO_MT_file(bpy.types.Menu): layout.operator_context = "EXEC_AREA" layout.itemO("wm.exit_blender", text="Quit") -class INFO_MT_file_import(bpy.types.Menu): - __label__ = "Import" + +# test for expanding menus +''' +class INFO_MT_file_more(INFO_MT_file): + __label__ = "File" def draw(self, context): layout = self.layout - - layout.itemO("import.3ds", text="3DS") - layout.itemO("import.obj", text="OBJ") -class INFO_MT_file_export(bpy.types.Menu): - __label__ = "Export" + layout.itemO("wm.read_homefile", text="TESTING ") + +dynamic_menu.setup(INFO_MT_file_more) +''' + +class INFO_MT_file_import(dynamic_menu.DynMenu): + __label__ = "Import" def draw(self, context): - layout = self.layout + pass # dynamic menu + +class INFO_MT_file_export(dynamic_menu.DynMenu): + __label__ = "Export" - layout.itemO("export.3ds", text="3DS") - layout.itemO("export.fbx", text="FBX") - layout.itemO("export.obj", text="OBJ") - layout.itemO("export.mdd", text="MDD") - layout.itemO("export.ply", text="PLY") - layout.itemO("export.x3d", text="X3D") + def draw(self, context): + pass # dynamic menu class INFO_MT_file_external_data(bpy.types.Menu): __label__ = "External Data" @@ -114,6 +122,23 @@ class INFO_MT_file_external_data(bpy.types.Menu): layout.itemO("file.report_missing_files") layout.itemO("file.find_missing_files") + +class INFO_MT_mesh_add(dynamic_menu.DynMenu): + __label__ = "Add Mesh" + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.itemO("mesh.primitive_plane_add", icon='ICON_MESH_PLANE') + layout.itemO("mesh.primitive_cube_add", icon='ICON_MESH_CUBE') + layout.itemO("mesh.primitive_circle_add", icon='ICON_MESH_CIRCLE') + layout.itemO("mesh.primitive_uv_sphere_add", icon='ICON_MESH_UVSPHERE') + layout.itemO("mesh.primitive_ico_sphere_add", icon='ICON_MESH_ICOSPHERE') + layout.itemO("mesh.primitive_cylinder_add", icon='ICON_MESH_TUBE') + layout.itemO("mesh.primitive_cone_add", icon='ICON_MESH_CONE') + layout.itemS() + layout.itemO("mesh.primitive_grid_add", icon='ICON_MESH_GRID') + layout.itemO("mesh.primitive_monkey_add", icon='ICON_MESH_MONKEY') + class INFO_MT_add(bpy.types.Menu): __label__ = "Add" @@ -122,7 +147,9 @@ class INFO_MT_add(bpy.types.Menu): layout.operator_context = "EXEC_SCREEN" - layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH') + # layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH') + layout.itemM("INFO_MT_mesh_add", icon='ICON_OUTLINER_OB_MESH') + layout.item_menu_enumO("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE') layout.item_menu_enumO("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE') layout.item_menu_enumO("object.metaball_add", "type", 'META', text="Metaball", icon='ICON_OUTLINER_OB_META') @@ -143,6 +170,10 @@ class INFO_MT_add(bpy.types.Menu): layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY') + layout.itemS() + + layout.item_menu_enumO("object.group_instance_add", "type", text="Group Instance", icon='ICON_OUTLINER_OB_EMPTY') + class INFO_MT_game(bpy.types.Menu): __label__ = "Game" @@ -199,6 +230,7 @@ bpy.types.register(INFO_MT_file_import) bpy.types.register(INFO_MT_file_export) bpy.types.register(INFO_MT_file_external_data) bpy.types.register(INFO_MT_add) +bpy.types.register(INFO_MT_mesh_add) bpy.types.register(INFO_MT_game) bpy.types.register(INFO_MT_render) bpy.types.register(INFO_MT_help) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index a18815d04a6..061a8279530 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4681,7 +4681,7 @@ int join_curve_exec(bContext *C, wmOperator *op) DAG_scene_sort(scene); // because we removed object(s), call before editmode! ED_object_enter_editmode(C, EM_WAITCURSOR); - ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR|EM_DO_UNDO); WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index ec763fe3dfc..7ea882b765b 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -70,6 +70,7 @@ void ED_object_exit_editmode(struct bContext *C, int flag); void ED_object_enter_editmode(struct bContext *C, int flag); void ED_object_base_init_from_view(struct bContext *C, struct Base *base); +struct Object *ED_object_add_type(struct bContext *C, int type); void ED_object_single_users(struct Scene *scene, int full); diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 4af5ddf56fa..cb71765906c 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -70,6 +70,7 @@ #include "ED_transform.h" #include "ED_util.h" #include "ED_view3d.h" +#include "ED_object.h" #include "mesh_intern.h" @@ -1306,20 +1307,41 @@ static float new_primitive_matrix(bContext *C, float primmat[][4]) /* ********* add primitive operators ************* */ -static int add_primitive_plane_exec(bContext *C, wmOperator *op) +static void make_prim_ext(bContext *C, int type, int tot, int seg, + int subdiv, float dia, float depth, int ext, int fill) { Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - /* plane (diameter of 1.41 makes it unit size) */ - dia*= sqrt(2.0f); - - make_prim(obedit, PRIM_PLANE, mat, 4, 0, 0, dia, 0.0f, 0, 1); - + int newob; + float mat[4][4]; + + if(obedit==NULL || obedit->type!=OB_MESH) { + /* create editmode */ + ED_object_add_type(C, OB_MESH); + ED_object_enter_editmode(C, EM_DO_UNDO); + obedit= CTX_data_edit_object(C); + newob = 1; + } + else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); + + dia *= new_primitive_matrix(C, mat); + + make_prim(obedit, type, mat, tot, seg, subdiv, dia, depth, ext, fill); + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + + + /* userdef */ + if (newob && (U.flag & USER_ADD_EDITMODE)==0) { + ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */ + } + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); +} + +static int add_primitive_plane_exec(bContext *C, wmOperator *op) +{ + /* sqrt(2.0f) - plane (diameter of 1.41 makes it unit size) */ + make_prim_ext(C, PRIM_PLANE, 4, 0, 0, sqrt(2.0f), 0.0f, 0, 1); return OPERATOR_FINISHED; } @@ -1332,7 +1354,7 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_plane_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1340,19 +1362,9 @@ void MESH_OT_primitive_plane_add(wmOperatorType *ot) static int add_primitive_cube_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - /* plane (diameter of 1.41 makes it unit size) */ - dia*= sqrt(2.0f); - - make_prim(obedit, PRIM_CUBE, mat, 4, 0, 0, dia, 1.0f, 1, 1); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + /* sqrt(2.0f) - plane (diameter of 1.41 makes it unit size) */ + make_prim_ext(C, PRIM_CUBE, 4, 0, 0, sqrt(2.0f), 1.0f, 1, 1); + return OPERATOR_FINISHED; } void MESH_OT_primitive_cube_add(wmOperatorType *ot) @@ -1364,7 +1376,7 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_cube_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1372,18 +1384,10 @@ void MESH_OT_primitive_cube_add(wmOperatorType *ot) static int add_primitive_circle_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr,"radius"); - - make_prim(obedit, PRIM_CIRCLE, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, 0.0f, 0, - RNA_boolean_get(op->ptr, "fill")); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + make_prim_ext(C, PRIM_CIRCLE, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), 0.0f, 0, + RNA_boolean_get(op->ptr, "fill")); + return OPERATOR_FINISHED; } @@ -1396,32 +1400,24 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_circle_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 3, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "fill", 0, "Fill", ""); } static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr, "radius"); - - make_prim(obedit, PRIM_CYLINDER, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, - RNA_float_get(op->ptr, "depth"), 1, 1); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), + RNA_float_get(op->ptr, "depth"), 1, 1); + + return OPERATOR_FINISHED; } void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) @@ -1433,31 +1429,23 @@ void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_cylinder_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); - RNA_def_float(ot->srna, "depth", 1.0f, -FLT_MAX, FLT_MAX, "Depth", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); } static int add_primitive_tube_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr, "radius"); - - make_prim(obedit, PRIM_CYLINDER, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, - RNA_float_get(op->ptr, "depth"), 1, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + make_prim_ext(C, PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), + RNA_float_get(op->ptr, "depth"), 1, 0); + return OPERATOR_FINISHED; } @@ -1470,32 +1458,24 @@ void MESH_OT_primitive_tube_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_tube_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); - RNA_def_float(ot->srna, "depth", 1.0f, -FLT_MAX, FLT_MAX, "Depth", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); } static int add_primitive_cone_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia *= RNA_float_get(op->ptr, "radius"); - - make_prim(obedit, PRIM_CONE, mat, RNA_int_get(op->ptr, "vertices"), 0, 0, dia, - RNA_float_get(op->ptr, "depth"), 0, RNA_boolean_get(op->ptr, "cap_end")); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_CONE, RNA_int_get(op->ptr, "vertices"), 0, 0, + RNA_float_get(op->ptr,"radius"), RNA_float_get(op->ptr, "depth"), + 0, RNA_boolean_get(op->ptr, "cap_end")); + + return OPERATOR_FINISHED; } void MESH_OT_primitive_cone_add(wmOperatorType *ot) @@ -1507,34 +1487,26 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_cone_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); - RNA_def_float(ot->srna, "radius", 1.0f, -FLT_MAX, FLT_MAX, "Radius", "", 0.001, 100.00); - RNA_def_float(ot->srna, "depth", 1.0f, -FLT_MAX, FLT_MAX, "Depth", "", 0.001, 100.00); + RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); + RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); RNA_def_boolean(ot->srna, "cap_end", 0, "Cap End", ""); } static int add_primitive_grid_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia*= RNA_float_get(op->ptr, "size"); - - make_prim(obedit, PRIM_GRID, mat, RNA_int_get(op->ptr, "x_subdivisions"), - RNA_int_get(op->ptr, "y_subdivisions"), 0, dia, 0.0f, 0, 1); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_GRID, RNA_int_get(op->ptr, "x_subdivisions"), + RNA_int_get(op->ptr, "y_subdivisions"), 0, + RNA_float_get(op->ptr,"size"), 0.0f, 0, 1); + + return OPERATOR_FINISHED; } void MESH_OT_primitive_grid_add(wmOperatorType *ot) @@ -1546,7 +1518,7 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_grid_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1554,22 +1526,13 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) /* props */ RNA_def_int(ot->srna, "x_subdivisions", 10, INT_MIN, INT_MAX, "X Subdivisions", "", 3, 1000); RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisons", "", 3, 1000); - RNA_def_float(ot->srna, "size", 1.0f, -FLT_MAX, FLT_MAX, "Size", "", 0.001, FLT_MAX); + RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX); } static int add_primitive_monkey_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float mat[4][4]; - - new_primitive_matrix(C, mat); - - make_prim(obedit, PRIM_MONKEY, mat, 0, 0, 2, 0.0f, 0.0f, 0, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - return OPERATOR_FINISHED; + make_prim_ext(C, PRIM_MONKEY, 0, 0, 2, 0.0f, 0.0f, 0, 0); + return OPERATOR_FINISHED; } void MESH_OT_primitive_monkey_add(wmOperatorType *ot) @@ -1581,7 +1544,7 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_monkey_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1589,18 +1552,10 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia*= RNA_float_get(op->ptr, "size"); + make_prim_ext(C, PRIM_UVSPHERE, RNA_int_get(op->ptr, "rings"), + RNA_int_get(op->ptr, "segments"), 0, + RNA_float_get(op->ptr,"size"), 0.0f, 0, 0); - make_prim(obedit, PRIM_UVSPHERE, mat, RNA_int_get(op->ptr, "rings"), - RNA_int_get(op->ptr, "segments"), 0, dia, 0.0f, 0, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - return OPERATOR_FINISHED; } @@ -1613,7 +1568,7 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_uvsphere_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1621,23 +1576,14 @@ void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) /* props */ RNA_def_int(ot->srna, "segments", 32, INT_MIN, INT_MAX, "Segments", "", 3, 500); RNA_def_int(ot->srna, "rings", 24, INT_MIN, INT_MAX, "Rings", "", 3, 500); - RNA_def_float(ot->srna, "size", 1.0f, -FLT_MAX, FLT_MAX, "Size", "", 0.001, 100.00); + RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00); } static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) { - Object *obedit= CTX_data_edit_object(C); - float dia, mat[4][4]; - - dia= new_primitive_matrix(C, mat); - dia*= RNA_float_get(op->ptr, "size"); - - make_prim(obedit, PRIM_ICOSPHERE, mat, 0, 0, - RNA_int_get(op->ptr, "subdivisions"), dia, 0.0f, 0, 0); - - DAG_id_flush_update(obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - + make_prim_ext(C, PRIM_ICOSPHERE, 0, 0, RNA_int_get(op->ptr, "subdivisions"), + RNA_float_get(op->ptr,"size"), 0.0f, 0, 0); + return OPERATOR_FINISHED; } @@ -1650,7 +1596,7 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) /* api callbacks */ ot->exec= add_primitive_icosphere_exec; - ot->poll= ED_operator_editmesh; + ot->poll= ED_operator_scene_editable; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 6f94db38316..0865455b3b9 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -428,7 +428,10 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) /* add/remove */ WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "name", "INFO_MT_mesh_add"); + WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0); /* use KM_RELEASE because same key is used for tweaks */ WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 00893f10165..fad73e19e16 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -533,7 +533,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) DAG_scene_sort(scene); // removed objects, need to rebuild dag before editmode call ED_object_enter_editmode(C, EM_WAITCURSOR); - ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR|EM_DO_UNDO); WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index d79ec460dec..5f088f23939 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -144,14 +144,14 @@ void add_object_draw(Scene *scene, View3D *v3d, int type) /* for toolbox or menu } /* for object add primitive operators */ -static Object *object_add_type(bContext *C, int type) +Object *ED_object_add_type(bContext *C, int type) { Scene *scene= CTX_data_scene(C); Object *ob; /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */ /* deselects all, sets scene->basact */ ob= add_object(scene, type); @@ -169,7 +169,7 @@ static Object *object_add_type(bContext *C, int type) /* for object add operator */ static int object_add_exec(bContext *C, wmOperator *op) { - object_add_type(C, RNA_enum_get(op->ptr, "type")); + ED_object_add_type(C, RNA_enum_get(op->ptr, "type")); return OPERATOR_FINISHED; } @@ -224,7 +224,7 @@ static Object *effector_add_type(bContext *C, int type) /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */ /* deselects all, sets scene->basact */ if(type==PFIELD_GUIDE) { @@ -232,7 +232,7 @@ static Object *effector_add_type(bContext *C, int type) ((Curve*)ob->data)->flag |= CU_PATH|CU_3D; ED_object_enter_editmode(C, 0); BLI_addtail(curve_get_editcurve(ob), add_nurbs_primitive(C, CU_NURBS|CU_PRIM_PATH, 1)); - ED_object_exit_editmode(C, EM_FREEDATA); + ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); } else ob= add_object(scene, OB_EMPTY); @@ -278,92 +278,6 @@ void OBJECT_OT_effector_add(wmOperatorType *ot) } /* ***************** add primitives *************** */ -/* ****** work both in and outside editmode ****** */ - -static EnumPropertyItem prop_mesh_types[] = { - {0, "PLANE", ICON_MESH_PLANE, "Plane", ""}, - {1, "CUBE", ICON_MESH_CUBE, "Cube", ""}, - {2, "CIRCLE", ICON_MESH_CIRCLE, "Circle", ""}, - {3, "UVSPHERE", ICON_MESH_UVSPHERE, "UVsphere", ""}, - {4, "ICOSPHERE", ICON_MESH_ICOSPHERE, "Icosphere", ""}, - {5, "CYLINDER", ICON_MESH_TUBE, "Cylinder", ""}, - {6, "CONE", ICON_MESH_CONE, "Cone", ""}, - {0, "", 0, NULL, NULL}, - {7, "GRID", ICON_MESH_GRID, "Grid", ""}, - {8, "MONKEY", ICON_MESH_MONKEY, "Monkey", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int object_add_mesh_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - int newob= 0; - - if(obedit==NULL || obedit->type!=OB_MESH) { - object_add_type(C, OB_MESH); - ED_object_enter_editmode(C, EM_DO_UNDO); - newob = 1; - } - else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA); - - switch(RNA_enum_get(op->ptr, "type")) { - case 0: - WM_operator_name_call(C, "MESH_OT_primitive_plane_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 1: - WM_operator_name_call(C, "MESH_OT_primitive_cube_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 2: - WM_operator_name_call(C, "MESH_OT_primitive_circle_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 3: - WM_operator_name_call(C, "MESH_OT_primitive_uv_sphere_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 4: - WM_operator_name_call(C, "MESH_OT_primitive_ico_sphere_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 5: - WM_operator_name_call(C, "MESH_OT_primitive_cylinder_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 6: - WM_operator_name_call(C, "MESH_OT_primitive_cone_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 7: - WM_operator_name_call(C, "MESH_OT_primitive_grid_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - case 8: - WM_operator_name_call(C, "MESH_OT_primitive_monkey_add", WM_OP_INVOKE_REGION_WIN, NULL); - break; - } - /* userdef */ - if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); - } - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - return OPERATOR_FINISHED; -} - - -void OBJECT_OT_mesh_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Add Mesh"; - ot->description = "Add a mesh object to the scene."; - ot->idname= "OBJECT_OT_mesh_add"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= object_add_mesh_exec; - - ot->poll= ED_operator_scene_editable; - - /* flags: no register or undo, this operator calls operators */ - ot->flag= 0; //OPTYPE_REGISTER|OPTYPE_UNDO; - - RNA_def_enum(ot->srna, "type", prop_mesh_types, 0, "Primitive", ""); -} static EnumPropertyItem prop_curve_types[] = { {CU_BEZIER|CU_PRIM_CURVE, "BEZIER_CURVE", ICON_CURVE_BEZCURVE, "Bezier Curve", ""}, @@ -382,7 +296,7 @@ static int object_add_curve_exec(bContext *C, wmOperator *op) int newob= 0; if(obedit==NULL || obedit->type!=OB_CURVE) { - object_add_type(C, OB_CURVE); + ED_object_add_type(C, OB_CURVE); ED_object_enter_editmode(C, 0); newob = 1; } @@ -395,7 +309,7 @@ static int object_add_curve_exec(bContext *C, wmOperator *op) /* userdef */ if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); } WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); @@ -457,7 +371,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op) int newob= 0; if(obedit==NULL || obedit->type!=OB_SURF) { - object_add_type(C, OB_SURF); + ED_object_add_type(C, OB_SURF); ED_object_enter_editmode(C, 0); newob = 1; } @@ -470,7 +384,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op) /* userdef */ if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); } WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); @@ -514,7 +428,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) int newob= 0; if(obedit==NULL || obedit->type!=OB_MBALL) { - object_add_type(C, OB_MBALL); + ED_object_add_type(C, OB_MBALL); ED_object_enter_editmode(C, 0); newob = 1; } @@ -527,7 +441,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) /* userdef */ if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); } WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); @@ -576,7 +490,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op) if(obedit && obedit->type==OB_FONT) return OPERATOR_CANCELLED; - object_add_type(C, OB_FONT); + ED_object_add_type(C, OB_FONT); obedit= CTX_data_active_object(C); if(U.flag & USER_ADD_EDITMODE) @@ -610,7 +524,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) int newob= 0; if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) { - object_add_type(C, OB_ARMATURE); + ED_object_add_type(C, OB_ARMATURE); ED_object_enter_editmode(C, 0); newob = 1; } @@ -624,7 +538,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) /* userdef */ if (newob && (U.flag & USER_ADD_EDITMODE)==0) { - ED_object_exit_editmode(C, EM_FREEDATA); + ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); } WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); @@ -652,7 +566,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) Object *ob; int type= RNA_enum_get(op->ptr, "type"); - ob= object_add_type(C, OB_LAMP); + ob= ED_object_add_type(C, OB_LAMP); if(ob && ob->data) ((Lamp*)ob->data)->type= type; @@ -720,7 +634,7 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "type")); if(group) { - Object *ob= object_add_type(C, OB_EMPTY); + Object *ob= ED_object_add_type(C, OB_EMPTY); rename_id(&ob->id, group->id.name+2); ob->dup_group= group; ob->transflag |= OB_DUPLIGROUP; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index ac47556c7f7..9535a6ee829 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -280,6 +280,8 @@ void OBJECT_OT_restrictview_set(wmOperatorType *ot) void ED_object_exit_editmode(bContext *C, int flag) { + /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ + Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); int freedata = flag & EM_FREEDATA; @@ -353,7 +355,8 @@ void ED_object_exit_editmode(bContext *C, int flag) /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); - ED_undo_push(C, "Editmode"); + if(flag & EM_DO_UNDO) + ED_undo_push(C, "Editmode"); if(flag & EM_WAITCURSOR) waitcursor(0); @@ -481,7 +484,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op) if(!CTX_data_edit_object(C)) ED_object_enter_editmode(C, EM_WAITCURSOR); else - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); return OPERATOR_FINISHED; } @@ -521,7 +524,7 @@ static int posemode_exec(bContext *C, wmOperator *op) if(base->object->type==OB_ARMATURE) { if(base->object==CTX_data_edit_object(C)) { - ED_object_exit_editmode(C, EM_FREEDATA); + ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO); ED_armature_enter_posemode(C, base); } else if(base->object->mode & OB_MODE_POSE) @@ -558,7 +561,7 @@ void check_editmode(int type) if (obedit==NULL || obedit->type==type) return; -// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */ +// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); /* freedata, and undo */ } #if 0 diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 353622526d3..dc7ae1490fd 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -83,7 +83,6 @@ void OBJECT_OT_select_name(struct wmOperatorType *ot); /* object_add.c */ void OBJECT_OT_add(struct wmOperatorType *ot); -void OBJECT_OT_mesh_add(struct wmOperatorType *ot); void OBJECT_OT_curve_add(struct wmOperatorType *ot); void OBJECT_OT_surface_add(struct wmOperatorType *ot); void OBJECT_OT_metaball_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index d75cf63c1d4..2b010f5b6bc 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -110,7 +110,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(GROUP_OT_objects_remove_active); WM_operatortype_append(OBJECT_OT_delete); - WM_operatortype_append(OBJECT_OT_mesh_add); WM_operatortype_append(OBJECT_OT_curve_add); WM_operatortype_append(OBJECT_OT_text_add); WM_operatortype_append(OBJECT_OT_surface_add); @@ -119,7 +118,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_effector_add); WM_operatortype_append(OBJECT_OT_group_instance_add); - WM_operatortype_append(OBJECT_OT_mesh_add); WM_operatortype_append(OBJECT_OT_metaball_add); WM_operatortype_append(OBJECT_OT_duplicates_make_real); WM_operatortype_append(OBJECT_OT_duplicate); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 30fdb5b2c95..e160b85e233 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2934,7 +2934,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) multires_force_update(CTX_data_active_object(C)); /* get editmode results */ - ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */ + ED_object_exit_editmode(C, EM_DO_UNDO); /* 0 = does not exit editmode */ // store spare // get view3d layer, local layer, make this nice api call to render diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 28fdc4708df..2612f8a024c 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -1824,7 +1824,7 @@ static void tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops } if(ob!=scene->obedit) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); @@ -2173,7 +2173,7 @@ static int tree_element_active_pose(bContext *C, Scene *scene, TreeElement *te, if(set) { if(scene->obedit) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); if(ob->mode & OB_MODE_POSE) ED_armature_exit_posemode(C, base); @@ -2327,7 +2327,7 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { Object *obedit= CTX_data_edit_object(C); if(obedit) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); else { ED_object_enter_editmode(C, EM_WAITCURSOR); // XXX extern_set_butspace(F9KEY, 0); @@ -3057,7 +3057,7 @@ static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, TreeSto if(base) { // check also library later if(scene->obedit==base->object) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); ED_base_object_free_and_unlink(scene, base); te->directdata= NULL; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f987c99a090..2683e171681 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -58,9 +58,11 @@ EnumPropertyItem prop_mode_items[] ={ #include "DNA_anim_types.h" #include "DNA_node_types.h" +#include "DNA_object_types.h" #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_scene.h" #include "BKE_node.h" #include "BKE_pointcache.h" @@ -79,6 +81,22 @@ static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter) return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base*)internal->link)->object); } +static PointerRNA rna_Scene_active_object_get(PointerRNA *ptr) +{ + Scene *scene= (Scene*)ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_Object, scene->basact ? scene->basact->object : NULL); +} + +static void rna_Scene_active_object_set(PointerRNA *ptr, PointerRNA value) +{ + Scene *scene= (Scene*)ptr->data; + if(value.data) + scene->basact= object_in_scene((Object*)value.data, scene); + else + scene->basact= NULL; +} + + static int layer_set(int lay, const int *values) { int i, tot= 0; @@ -2051,6 +2069,13 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Camera", "Active camera used for rendering the scene."); + prop= RNA_def_property(srna, "active_object", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_pointer_funcs(prop, "rna_Scene_active_object_get", "rna_Scene_active_object_set", NULL); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Object", "Object to use as projector transform."); + + prop= RNA_def_property(srna, "world", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "World", "World used for rendering the scene."); @@ -2081,7 +2106,7 @@ void RNA_def_scene(BlenderRNA *brna) prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_TIME); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "r.cfra"); - RNA_def_property_range(prop, MINAFRAME, MAXFRAME); + RNA_def_property_range(prop, -MINAFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Current Frame", ""); RNA_def_property_update(prop, NC_SCENE|ND_FRAME, "rna_Scene_frame_update"); @@ -2089,6 +2114,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "r.sfra"); RNA_def_property_int_funcs(prop, NULL, "rna_Scene_start_frame_set", NULL); + RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Start Frame", ""); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); @@ -2096,12 +2122,15 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "r.efra"); RNA_def_property_int_funcs(prop, NULL, "rna_Scene_end_frame_set", NULL); + RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "End Frame", ""); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_TIME); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "frame_step"); + RNA_def_property_range(prop, 0, MAXFRAME); + RNA_def_property_ui_range(prop, 0, 100, 1, 0); RNA_def_property_ui_text(prop, "Frame Step", "Number of frames to skip forward while rendering/playing back each frame"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 428df15ef4e..c4fb9ea3d0d 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -37,6 +37,7 @@ #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "DNA_node_types.h" +#include "DNA_scene_types.h" /* MAXFRAME only */ #include "BKE_node.h" @@ -1579,7 +1580,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) prop= RNA_def_property(srna, "still_frame_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "still_frame"); - RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Still Frame Number", "The frame number to always use"); RNA_def_property_update(prop, 0, "rna_Texture_update"); diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index bb0cea9e761..769a8336d4a 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -270,6 +270,9 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) /* api callbacks, detailed checks dont on adding */ if (PyObject_HasAttrString(py_class, "invoke")) ot->invoke= PYTHON_OT_invoke; + //else + // ot->invoke= WM_operator_props_popup; /* could have an option for standard invokes */ + if (PyObject_HasAttrString(py_class, "execute")) ot->exec= PYTHON_OT_execute; if (PyObject_HasAttrString(py_class, "poll")) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1aca9a66e57..ff0e69b74d4 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -533,7 +533,7 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports) packAll(G.main, reports); } - ED_object_exit_editmode(C, 0); + ED_object_exit_editmode(C, EM_DO_UNDO); do_history(di, reports); -- cgit v1.2.3 From fc44a97b73ce802a09eafc1c607afc123f970fec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Oct 2009 23:15:52 +0000 Subject: adding a cone didnt work --- source/blender/editors/mesh/editmesh_add.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index cb71765906c..d703ba1fb35 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -1184,14 +1184,14 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se /* center vertices */ /* type PRIM_CONE can only have 1 one side filled * if the cone has no capping, dont add vtop */ - if((fill && type>1) || type == PRIM_CONE) { + if(type == PRIM_CONE || (fill && !ELEM(type, PRIM_PLANE, PRIM_CUBE))) { vec[0]= vec[1]= 0.0f; - vec[2]= -depth; + vec[2]= type==PRIM_CONE ? depth : -depth; Mat4MulVecfl(mat, vec); vdown= addvertlist(em, vec, NULL); if((ext || type==PRIM_CONE) && fill) { vec[0]= vec[1]= 0.0f; - vec[2]= depth; + vec[2]= type==PRIM_CONE ? -depth : depth; Mat4MulVecfl(mat,vec); vtop= addvertlist(em, vec, NULL); } @@ -1204,7 +1204,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se /* top and bottom face */ if(fill || type==PRIM_CONE) { - if(tot==4 && (type==0 || type==1)) { + if(tot==4 && ELEM(type, PRIM_PLANE, PRIM_CUBE)) { v3= v1->next->next; if(ext) v4= v2->next->next; @@ -1223,7 +1223,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se v4= v4->next; } } - if(type>1) { + if(!ELEM(type, PRIM_PLANE, PRIM_CUBE)) { addfacelist(em, vdown, v3, v1, 0, NULL, NULL); if(ext) addfacelist(em, vtop, v4, v2, 0, NULL, NULL); } @@ -1248,7 +1248,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se } addfacelist(em, v3, v1, v2, v4, NULL, NULL); } - else if(type==PRIM_CONE && fill) { + else if(fill && type==PRIM_CONE) { /* add the bottom flat area of the cone * if capping is disabled dont bother */ v3= v1; @@ -1264,7 +1264,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se /* simple selection flush OK, based on fact it's a single model */ EM_select_flush(em); /* flushes vertex -> edge -> face selection */ - if(type!=0 && type!=13) + if(type!=PRIM_PLANE && type!=PRIM_MONKEY) righthandfaces(em, 1); /* otherwise monkey has eyes in wrong direction */ BKE_mesh_end_editmesh(obedit->data, em); @@ -1525,7 +1525,7 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) /* props */ RNA_def_int(ot->srna, "x_subdivisions", 10, INT_MIN, INT_MAX, "X Subdivisions", "", 3, 1000); - RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisons", "", 3, 1000); + RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisions", "", 3, 1000); RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX); } -- cgit v1.2.3 From ac441cecd03b60c8e4b9d2b41b2f2096df1f2be1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 10 Oct 2009 23:50:15 +0000 Subject: bugfix - [#19563] Select camera+ctrl alt 0 crash --- source/blender/editors/space_view3d/view3d_view.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index d26141e3b54..fd850e90ff5 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -411,6 +411,7 @@ static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) RegionView3D *rv3d= CTX_wm_region_view3d(C); setcameratoview3d(v3d, rv3d, v3d->camera); + rv3d->persp = V3D_CAMOB; WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C)); @@ -418,6 +419,16 @@ static int view3d_setcameratoview_exec(bContext *C, wmOperator *op) } +int view3d_setcameratoview_poll(bContext *C) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + + if (v3d==NULL || v3d->camera==NULL) return 0; + if (rv3d && rv3d->viewlock != 0) return 0; + return 1; +} + void VIEW3D_OT_setcameratoview(wmOperatorType *ot) { @@ -428,7 +439,7 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot) /* api callbacks */ ot->exec= view3d_setcameratoview_exec; - ot->poll= ED_operator_view3d_active; + ot->poll= view3d_setcameratoview_poll; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -- cgit v1.2.3 From 77bfc417ffd0b74df78ffb8f73032ac5afff4b86 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 11 Oct 2009 07:29:53 +0000 Subject: Bugfix #19612: Incorrect ranges for frame range properties broke playback. I'm still not exactly sure which commit did this evil deed, but at least it's fixed now... --- source/blender/makesrna/intern/rna_nodetree.c | 6 +++--- source/blender/makesrna/intern/rna_object.c | 6 +++--- source/blender/makesrna/intern/rna_scene.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4547362e235..bd018973f5a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -790,7 +790,7 @@ static void def_cmp_image(StructRNA *srna) prop = RNA_def_property(srna, "offset", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "offset"); - RNA_def_property_range(prop, -MAXFRAMEF, MAXFRAMEF); + RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Offset", "Offsets the number of the frame to use in the animation"); RNA_def_property_update(prop, 0, "rna_Node_update"); @@ -903,13 +903,13 @@ static void def_cmp_output_file(StructRNA *srna) prop = RNA_def_property(srna, "start", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "sfra"); - RNA_def_property_range(prop, 1, MAXFRAMEF); + RNA_def_property_range(prop, MINFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "Start Frame", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); prop = RNA_def_property(srna, "end", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "efra"); - RNA_def_property_range(prop, 1, MAXFRAMEF); + RNA_def_property_range(prop, MINFRAMEF, MAXFRAMEF); RNA_def_property_ui_text(prop, "End Frame", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); } diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 46885b89f2c..99ce6f0bea8 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1540,19 +1540,19 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "dupli_frames_start", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupsta"); - RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); + RNA_def_property_range(prop, MINAFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Dupli Frames Start", "Start frame for DupliFrames."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); prop= RNA_def_property(srna, "dupli_frames_end", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupend"); - RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); + RNA_def_property_range(prop, MINAFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Dupli Frames End", "End frame for DupliFrames."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); prop= RNA_def_property(srna, "dupli_frames_on", PROP_INT, PROP_NONE|PROP_UNIT_TIME); RNA_def_property_int_sdna(prop, NULL, "dupon"); - RNA_def_property_range(prop, 1, MAXFRAME); + RNA_def_property_range(prop, MINFRAME, MAXFRAME); RNA_def_property_ui_range(prop, 1, 1500, 1, 0); RNA_def_property_ui_text(prop, "Dupli Frames On", "Number of frames to use between DupOff frames."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 2683e171681..4a42a63bf6b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2106,7 +2106,7 @@ void RNA_def_scene(BlenderRNA *brna) prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_TIME); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "r.cfra"); - RNA_def_property_range(prop, -MINAFRAME, MAXFRAME); + RNA_def_property_range(prop, MINAFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Current Frame", ""); RNA_def_property_update(prop, NC_SCENE|ND_FRAME, "rna_Scene_frame_update"); @@ -2114,7 +2114,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "r.sfra"); RNA_def_property_int_funcs(prop, NULL, "rna_Scene_start_frame_set", NULL); - RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); + RNA_def_property_range(prop, MINFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Start Frame", ""); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); @@ -2122,7 +2122,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_int_sdna(prop, NULL, "r.efra"); RNA_def_property_int_funcs(prop, NULL, "rna_Scene_end_frame_set", NULL); - RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); + RNA_def_property_range(prop, MINFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "End Frame", ""); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); -- cgit v1.2.3 From 4081f33687c88a9fcb0c09be86b79964b2c13f08 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Oct 2009 11:21:51 +0000 Subject: EditMesh was using VBO's even when off in the user preferences causing glMapBufferARB to return an invalid array, however setDrawOptions was (incorrectly) disabling VBO's in almost all cases so it didnt crash except for entering editmode on an object used as a custom bone shape. Changed to allow setDrawOptions (since it works fine), but only to use VBO's when its enabled in the userprefs. --- source/blender/blenkernel/intern/DerivedMesh.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 86c272e3799..a8ea83a45fc 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -492,11 +492,12 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us } glEnd(); } else { - GPUBuffer *buffer = 0; + GPUBuffer *buffer = NULL; float *varray; - if( setDrawOptions == 0 ) { + + if(GPU_buffer_legacy(dm)==FALSE) buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 ); - } + if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) { int prevdraw = 0; int numedges = 0; -- cgit v1.2.3 From 7ac1c7c89956d5df7f99509917fd933002d2861d Mon Sep 17 00:00:00 2001 From: Lukas Steiblys Date: Sun, 11 Oct 2009 12:09:14 +0000 Subject: fixed the code that updates normals of quads when sculpting --- source/blender/editors/sculpt_paint/sculpt.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c9353f697db..b88fe5a9d7a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1017,6 +1017,18 @@ static void update_damaged_vert(SculptSession *ss, ListBase *lb) VECCOPY(&buffer[(cur->element-cur->element%3)*3],norm); VECCOPY(&buffer[(cur->element-cur->element%3+1)*3],norm); VECCOPY(&buffer[(cur->element-cur->element%3+2)*3],norm); + + /* maybe this was a quad - need to update the other triangle of the quad */ + if( ss->drawobject->faceRemap[cur->element/3-1] == i ) { + VECCOPY(&buffer[(cur->element-cur->element%3-3)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3-2)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3-1)*3],norm); + } + if( ss->drawobject->faceRemap[cur->element/3+1] == i ) { + VECCOPY(&buffer[(cur->element-cur->element%3+3)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3+4)*3],norm); + VECCOPY(&buffer[(cur->element-cur->element%3+5)*3],norm); + } } //VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no); -- cgit v1.2.3 From efed73598f7d571aa57468b31748c5777dbfc41f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Oct 2009 19:06:38 +0000 Subject: Use OB_MODE_EDIT as a flag everywhere, also fixed a typo which made drawing the set-scene not work right. --- source/blender/blenkernel/intern/anim.c | 4 ++-- source/blender/blenkernel/intern/object.c | 2 +- source/blender/editors/mesh/editmesh_mods.c | 2 +- source/blender/editors/object/object_edit.c | 2 +- source/blender/editors/space_view3d/drawmesh.c | 6 +++--- source/blender/editors/space_view3d/drawobject.c | 10 +++++----- source/blender/makesrna/intern/rna_object.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index bb7a792943e..f119f52a47d 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -549,7 +549,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl /* mballs have a different dupli handling */ if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ - if(par->mode==OB_MODE_EDIT) { + if(par->mode & OB_MODE_EDIT) { dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd); } else { @@ -760,7 +760,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa else go= go->next; /* group loop */ } - if(par->mode==OB_MODE_EDIT) { + if(par->mode & OB_MODE_EDIT) { MEM_freeN(mface); MEM_freeN(mvert); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0b0a7a54c38..64e22c85251 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2370,7 +2370,7 @@ void object_handle_update(Scene *scene, Object *ob) EditMesh *em = BKE_mesh_get_editmesh(ob->data); // here was vieweditdatamask? XXX - if(ob->mode==OB_MODE_EDIT) { + if(ob->mode & OB_MODE_EDIT) { makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH); BKE_mesh_end_editmesh(ob->data, em); } else diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 3c3cdf25d7b..b790f1aceed 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -123,7 +123,7 @@ void EM_automerge(Scene *scene, Object *obedit, int update) int len; if ((scene->toolsettings->automerge) && - (obedit && obedit->type==OB_MESH && obedit->mode==OB_MODE_EDIT) && + (obedit && obedit->type==OB_MESH && (obedit->mode & OB_MODE_EDIT)) && (me->mr==NULL) ) { Mesh *me= (Mesh*)obedit->data; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 9535a6ee829..abd6847c6db 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2004,7 +2004,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) /* Irritating workaround! disallow paint modes from editmode since a number of shortcuts conflict * XXX - would be much better to handle this on a keymap level */ - if(ob->mode == OB_MODE_EDIT && ELEM6(mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT, OB_MODE_PARTICLE_EDIT, OB_MODE_POSE)) { + if((ob->mode & OB_MODE_EDIT) && ELEM6(mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT, OB_MODE_PARTICLE_EDIT, OB_MODE_POSE)) { return OPERATOR_PASS_THROUGH; } diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index dbe0844cbe5..365b9ff03f7 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -350,7 +350,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O int istex, solidtex= 0; // XXX scene->obedit warning - if(v3d->drawtype==OB_SOLID || (ob->mode==OB_MODE_EDIT && v3d->drawtype!=OB_TEXTURE)) { + if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) { /* draw with default lights in solid draw mode and edit mode */ solidtex= 1; Gtexdraw.islit= -1; @@ -561,7 +561,7 @@ void draw_mesh_text(Scene *scene, Object *ob, int glsl) return; /* don't draw when editing */ - if(ob->mode==OB_MODE_EDIT) + if(ob->mode & OB_MODE_EDIT) return; else if(ob==OBACT) if(paint_facesel_test(ob)) @@ -641,7 +641,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o /* draw the textured mesh */ draw_textured_begin(scene, v3d, rv3d, ob); - if(ob->mode==OB_MODE_EDIT) { + if(ob->mode & OB_MODE_EDIT) { glColor4f(1.0f,1.0f,1.0f,1.0f); dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh); } else if(faceselect) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 2d998c5ed5e..3d51449e28f 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5512,7 +5512,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(ob==OBACT && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) { if(ob->type==OB_MESH) { - if(ob->mode==OB_MODE_EDIT); + if(ob->mode & OB_MODE_EDIT); else { if(dt=OB_BOUNDBOX ) { dtx= ob->dtx; - if(ob->mode==OB_MODE_EDIT) { + if(ob->mode & OB_MODE_EDIT) { // the only 2 extra drawtypes alowed in editmode dtx= dtx & (OB_DRAWWIRE|OB_TEXSPACE); } @@ -5550,7 +5550,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw outline for selected solid objects, mesh does itself */ if((v3d->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) { - if(dt>OB_WIRE && dtmode!=OB_MODE_EDIT && (flag && DRAW_SCENESET)==0) { + if(dt>OB_WIRE && dtmode & OB_MODE_EDIT)==0 && (flag & DRAW_SCENESET)==0) { if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) { drawSolidSelect(scene, v3d, ar, base); @@ -6159,7 +6159,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec switch( ob->type) { case OB_MESH: { - if(ob->mode==OB_MODE_EDIT) { + if((ob->mode & OB_MODE_EDIT)==0) { Mesh *me= ob->data; EditMesh *em= me->edit_mesh; @@ -6215,7 +6215,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r DerivedMesh *dm=NULL, *edm=NULL; int glsl; - if(ob->mode == OB_MODE_EDIT) + if(ob->mode & OB_MODE_EDIT) edm= editmesh_get_derived_base(ob, me->edit_mesh); else dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 99ce6f0bea8..b91e5952c8f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -416,7 +416,7 @@ static void rna_Object_active_material_index_set(PointerRNA *ptr, int value) Object *ob= (Object*)ptr->id.data; ob->actcol= value+1; - if(ob->mode==OB_MODE_EDIT && ob->type==OB_MESH) { + if((ob->mode & OB_MODE_EDIT) && ob->type==OB_MESH) { Mesh *me= ob->data; if(me->edit_mesh) -- cgit v1.2.3 From dff1738765aba649b07f3174ed807e7df8e38eee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Oct 2009 19:57:56 +0000 Subject: bugfix for exitmode verts being unselectable. caused by view3d_project_short_clip/noclip being used by selecton code outside of object drawing (which isnt supposed to happen according to view3d_project_short_* comments). Deal with this by adding ED_view3d_init_mats_rv3d(ob, r3d) which initialized the region mat's and is used in mesh_foreachScreenVert, mesh_foreachScreenEdge etc. --- source/blender/editors/include/ED_view3d.h | 2 ++ source/blender/editors/mesh/editmesh.c | 8 ++++++++ source/blender/editors/space_view3d/drawobject.c | 19 +++++++++++++------ source/blender/editors/space_view3d/space_view3d.c | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index fd1b7e1351d..7b1022d1a3f 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -134,5 +134,7 @@ int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, in /* get 3d region from context, also if mouse is in header or toolbar */ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); +void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d); + #endif /* ED_VIEW3D_H */ diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 52744c81b7e..8234d0ab6dc 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1796,6 +1796,14 @@ void undo_push_mesh(bContext *C, char *name) /* *************** END UNDO *************/ +void EM_init_viewmats(Object *ob, RegionView3D *rv3d) +{ + wmMultMatrix(ob->obmat); + /* local viewmat and persmat, to calculate projections */ + wmGetMatrix(rv3d->viewmatob); + wmGetSingleMatrix(rv3d->persmatob); +} + static EditVert **g_em_vert_array = NULL; static EditEdge **g_em_edge_array = NULL; static EditFace **g_em_face_array = NULL; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3d51449e28f..3e9b2e5751b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -139,7 +139,9 @@ static void draw_empty_sphere(float size); static void draw_empty_cone(float size); -/* ************* only use while object drawing ************** */ +/* ************* only use while object drawing ************** + * or after running ED_view3d_init_mats_rv3d + * */ static void view3d_project_short_clip(ARegion *ar, float *vec, short *adr) { RegionView3D *rv3d= ar->regiondata; @@ -1205,6 +1207,8 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo int i, N = lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; short s[2] = {IS_CLIPPED, 0}; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ + for (i=0; ihide==0) { view3d_project_short_clip(vc->ar, dl?co:bp->vec, s); @@ -1328,6 +1332,7 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe data.userData = userData; data.clipVerts = clipVerts; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ EM_init_index_arrays(vc->em, 1, 0, 0); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); EM_free_index_arrays(); @@ -1370,6 +1375,7 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd data.userData = userData; data.clipVerts = clipVerts; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ EM_init_index_arrays(vc->em, 0, 1, 0); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); EM_free_index_arrays(); @@ -1399,6 +1405,7 @@ void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFa data.func = func; data.userData = userData; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ EM_init_index_arrays(vc->em, 0, 0, 1); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); EM_free_index_arrays(); @@ -1413,6 +1420,8 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb Nurb *nu; int i; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ + for (nu= cu->editnurb->first; nu; nu=nu->next) { if(nu->type == CU_BEZIER) { for (i=0; ipntsu; i++) { @@ -5451,11 +5460,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw paths... */ // TODO... - /* multiply view with object matrix */ - wmMultMatrix(ob->obmat); - /* local viewmat and persmat, to calculate projections */ - wmGetMatrix(rv3d->viewmatob); - wmGetSingleMatrix(rv3d->persmatob); + /* multiply view with object matrix. + * local viewmat and persmat, to calculate projections */ + ED_view3d_init_mats_rv3d(ob, rv3d); /* which wire color */ if((flag & DRAW_CONSTCOLOR) == 0) { diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index e1bd48e002f..d017e11e783 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -158,6 +158,24 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C) return rv3d; } +/* Most of the time this isn't needed since you could assume the view matrix was + * set while drawing, however when functions like mesh_foreachScreenVert are + * called by selection tools, we can't be sure this object was the last. + * + * for example, transparent objects are drawn after editmode and will cause + * the rv3d mat's to change and break selection. + * + * 'ED_view3d_init_mats_rv3d' should be called before + * view3d_project_short_clip and view3d_project_short_noclip in cases where + * these functions are not used during draw_object + */ +void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d) +{ + wmMultMatrix(ob->obmat); + /* local viewmat and persmat, to calculate projections */ + wmGetMatrix(rv3d->viewmatob); + wmGetSingleMatrix(rv3d->persmatob); +} /* ******************** default callbacks for view3d space ***************** */ -- cgit v1.2.3 From 84172b31b5eea67275e0d517b3cd7aebbb38b73d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Oct 2009 20:03:55 +0000 Subject: remove OB_RADIO, added function by mistake --- source/blender/blenloader/intern/readfile.c | 3 --- source/blender/editors/mesh/editmesh.c | 8 -------- source/blender/editors/space_view3d/drawobject.c | 8 +++----- source/blender/makesdna/DNA_object_types.h | 2 +- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 184b584d188..ad51892a94f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4168,9 +4168,6 @@ static void lib_link_scene(FileData *fd, Main *main) /* base->object= newlibadr_us(fd, sce->id.lib, base->object); */ base->object= newlibadr_us(fd, sce->id.lib, base->object); - /* when save during radiotool, needs cleared */ - base->flag &= ~OB_RADIO; - if(base->object==NULL) { printf("LIB ERROR: base removed\n"); BLI_remlink(&sce->base, base); diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 8234d0ab6dc..52744c81b7e 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1796,14 +1796,6 @@ void undo_push_mesh(bContext *C, char *name) /* *************** END UNDO *************/ -void EM_init_viewmats(Object *ob, RegionView3D *rv3d) -{ - wmMultMatrix(ob->obmat); - /* local viewmat and persmat, to calculate projections */ - wmGetMatrix(rv3d->viewmatob); - wmGetSingleMatrix(rv3d->persmatob); -} - static EditVert **g_em_vert_array = NULL; static EditEdge **g_em_edge_array = NULL; static EditFace **g_em_face_array = NULL; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3e9b2e5751b..5a7f82dda13 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5567,10 +5567,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) switch( ob->type) { case OB_MESH: - if (!(base->flag&OB_RADIO)) { - empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag); - if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself - } + empty_object= draw_mesh_object(scene, v3d, rv3d, base, dt, flag); + if(flag!=DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself break; case OB_FONT: @@ -5913,7 +5911,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(zbufoff) glDisable(GL_DEPTH_TEST); if(warning_recursive) return; - if(base->flag & (OB_FROMDUPLI|OB_RADIO)) return; + if(base->flag & OB_FROMDUPLI) return; if(G.f & G_RENDER_SHADOW) return; /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 0940a88267c..73bf698db16 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -421,7 +421,7 @@ extern Object workob; #define OB_FROMDUPLI 512 #define OB_DONE 1024 -#define OB_RADIO 2048 /* deprecated */ +// #define OB_RADIO 2048 /* deprecated */ #define OB_FROMGROUP 4096 /* ob->recalc (flag bits!) */ -- cgit v1.2.3 From 6b652ca543d70826cf61a17b8565eb6ecfd7cdcf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Oct 2009 20:32:25 +0000 Subject: realized some parts of the code might use screen/vert projection on instance objects which dont use the object matrix normally. moved functions outside *_foreachScreen' funcs into their callers (mainly selection tools) --- source/blender/editors/curve/editcurve.c | 1 + source/blender/editors/mesh/editmesh_mods.c | 7 +++++++ source/blender/editors/mesh/editmesh_tools.c | 2 ++ source/blender/editors/object/object_lattice.c | 1 + source/blender/editors/space_view3d/drawobject.c | 11 ++++------- source/blender/editors/space_view3d/view3d_select.c | 12 ++++++++++++ 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 061a8279530..45820869b48 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2242,6 +2242,7 @@ static short findnearestNurbvert(ViewContext *vc, short sel, int mval[2], Nurb * data.mval[0] = mval[0]; data.mval[1] = mval[1]; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data); *nurb = data.nurb; diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index b790f1aceed..c4f4cd48d53 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -422,6 +422,9 @@ EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short strict) data.closestIndex = 0; data.pass = 0; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1); if (data.dist>3) { @@ -511,6 +514,7 @@ EditEdge *findnearestedge(ViewContext *vc, int *dist) data.dist = *dist; data.closest = NULL; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 2); *dist = data.dist; @@ -566,6 +570,7 @@ static EditFace *findnearestface(ViewContext *vc, int *dist) data.dist = 0x7FFF; /* largest short */ data.toFace = efa; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenFace(vc, findnearestface__getDistance, &data); if(vc->em->selectmode == SCE_SELECT_FACE || data.dist<*dist) { /* only faces, no dist check */ @@ -594,6 +599,8 @@ static EditFace *findnearestface(ViewContext *vc, int *dist) data.closestIndex = 0; data.pass = 0; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); if (data.dist>3) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 88d08efe95e..971e0a147d3 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -543,7 +543,9 @@ void xsortvert_flag(bContext *C, int flag) if(eve->f & flag) sortblock[i].v1 = eve; + ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); mesh_foreachScreenVert(&vc, xsortvert_flag__doSetX, sortblock, 0); + qsort(sortblock, amount, sizeof(xvertsort), vergxco); /* make temporal listbase */ diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index bd8171e8593..b49c1eb5902 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -292,6 +292,7 @@ static BPoint *findnearestLattvert(ViewContext *vc, short mval[2], int sel) data.mval[0]= mval[0]; data.mval[1]= mval[1]; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); return data.bp; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5a7f82dda13..9e773298d4a 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1207,8 +1207,6 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo int i, N = lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; short s[2] = {IS_CLIPPED, 0}; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ - for (i=0; ihide==0) { view3d_project_short_clip(vc->ar, dl?co:bp->vec, s); @@ -1303,6 +1301,10 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) /* ***************** ******************** */ +/* Note! - foreach funcs should be called while drawing or directly after + * if not, ED_view3d_init_mats_rv3d() can be used for selection tools + * but would not give correct results with dupli's for eg. which dont + * use the object matrix in the useual way */ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData; @@ -1332,7 +1334,6 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe data.userData = userData; data.clipVerts = clipVerts; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ EM_init_index_arrays(vc->em, 1, 0, 0); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); EM_free_index_arrays(); @@ -1375,7 +1376,6 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd data.userData = userData; data.clipVerts = clipVerts; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ EM_init_index_arrays(vc->em, 0, 1, 0); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); EM_free_index_arrays(); @@ -1405,7 +1405,6 @@ void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFa data.func = func; data.userData = userData; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ EM_init_index_arrays(vc->em, 0, 0, 1); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); EM_free_index_arrays(); @@ -1420,8 +1419,6 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb Nurb *nu; int i; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* so view3d_project_short works */ - for (nu= cu->editnurb->first; nu; nu=nu->next) { if(nu->type == CU_BEZIER) { for (i=0; ipntsu; i++) { diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index a37e916064c..8dc7d6a0518 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -459,7 +459,10 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves data.pass = 0; bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ + if(ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { EM_backbuf_checkAndSelectVerts(vc->em, select); @@ -584,6 +587,7 @@ static void do_lasso_select_curve(ViewContext *vc, short mcords[][2], short move data.moves = moves; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); } @@ -604,6 +608,7 @@ static void do_lasso_select_lattice(ViewContext *vc, short mcords[][2], short mo data.moves = moves; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); } @@ -1256,6 +1261,7 @@ static void do_nurbs_box_select(ViewContext *vc, rcti *rect, int select) data.rect = rect; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data); } @@ -1275,6 +1281,7 @@ static void do_lattice_box_select(ViewContext *vc, rcti *rect, int select) data.rect = rect; data.select = select; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data); } @@ -1324,6 +1331,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select) data.done = 0; bbsel= EM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ if(ts->selectmode & SCE_SELECT_VERTEX) { if (bbsel) { @@ -1705,6 +1713,8 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa struct {ViewContext *vc; short select, mval[2]; float radius; } data; bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0)); + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ + vc->em= ((Mesh *)vc->obedit->data)->edit_mesh; data.select = selecting; @@ -1773,6 +1783,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int selecting, short *mval data.mval[1] = mval[1]; data.radius = rad; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); } @@ -1798,6 +1809,7 @@ static void lattice_circle_select(ViewContext *vc, int selecting, short *mval, f data.mval[1] = mval[1]; data.radius = rad; + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data); } -- cgit v1.2.3 From 94d81336f19f62e5361f756fce258247edb708fd Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 11 Oct 2009 21:13:32 +0000 Subject: Update MSVC project files --- projectfiles_vc9/blender/gpu/BL_gpu.vcproj | 4 ++++ projectfiles_vc9/blender/render/BRE_render.vcproj | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj index 0b2927e9ee2..af0b90796d1 100644 --- a/projectfiles_vc9/blender/gpu/BL_gpu.vcproj +++ b/projectfiles_vc9/blender/gpu/BL_gpu.vcproj @@ -507,6 +507,10 @@ Name="Header Files" Filter="h;hpp;hxx;hm;inl" > + + diff --git a/projectfiles_vc9/blender/render/BRE_render.vcproj b/projectfiles_vc9/blender/render/BRE_render.vcproj index 358549f19c1..5a40dd4e97e 100644 --- a/projectfiles_vc9/blender/render/BRE_render.vcproj +++ b/projectfiles_vc9/blender/render/BRE_render.vcproj @@ -331,6 +331,14 @@ RelativePath="..\..\..\source\blender\render\intern\include\pointdensity.h" > + + + + -- cgit v1.2.3 From 0c0aa79cb98a1fdfdade440b1a9e0ff911148b08 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sun, 11 Oct 2009 23:04:01 +0000 Subject: * crash fix in volume render, less reliance on global R --- source/blender/render/intern/include/volume_precache.h | 2 +- source/blender/render/intern/source/convertblender.c | 6 +++--- source/blender/render/intern/source/volume_precache.c | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index 368d60ee7f0..5c3a7bdfbf0 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -28,6 +28,6 @@ void volume_precache(Render *re); void free_volume_precache(Render *re); -int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co); +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co); #define VOL_MS_TIMESTEP 0.1f diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 655c453eee7..af7d7a02bba 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3026,7 +3026,7 @@ static void init_camera_inside_volumes(Render *re) for(vo= re->volumes.first; vo; vo= vo->next) { for(obi= re->instancetable.first; obi; obi= obi->next) { if (obi->obr == vo->obr) { - if (point_inside_volume_objectinstance(obi, co)) { + if (point_inside_volume_objectinstance(re, obi, co)) { MatInside *mi; mi = MEM_mallocN(sizeof(MatInside), "camera inside material"); @@ -4850,8 +4850,6 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) /* MAKE RENDER DATA */ database_init_objects(re, lay, 0, 0, 0, 0); - init_camera_inside_volumes(re); - if(!re->test_break(re->tbh)) { int tothalo; @@ -4876,6 +4874,8 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) RE_make_stars(re, NULL, NULL, NULL, NULL); sort_halos(re, tothalo); + init_camera_inside_volumes(re); + re->i.infostr= "Creating Shadowbuffers"; re->stats_draw(re->sdh, &re->i); diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 3361eea46e7..62d7343036a 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -72,7 +72,6 @@ int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int l if (limit == 0) return depth; if (RE_rayobject_raycast(tree, isect)) { - float hitco[3]; isect->start[0] = isect->start[0] + isect->labda*isect->vec[0]; isect->start[1] = isect->start[1] + isect->labda*isect->vec[1]; @@ -730,12 +729,12 @@ void free_volume_precache(Render *re) BLI_freelistN(&re->volumes); } -int point_inside_volume_objectinstance(ObjectInstanceRen *obi, float *co) +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co) { RayObject *tree; int inside=0; - tree = makeraytree_object(&R, obi); //create_raytree_obi(obi, obi->obr->boundbox[0], obi->obr->boundbox[1]); + tree = makeraytree_object(re, obi); //create_raytree_obi(obi, obi->obr->boundbox[0], obi->obr->boundbox[1]); if (!tree) return 0; inside = point_inside_obi(tree, obi, co); -- cgit v1.2.3 From eaadc0685b84a0b423a281b4c0af1b8906db3b9c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 06:45:55 +0000 Subject: fix for own typo r23771, reported as [19621] Weight Paint crashes in rev. 23775 --- source/blender/editors/space_view3d/drawobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 9e773298d4a..096129f6f9e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -6161,7 +6161,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec switch( ob->type) { case OB_MESH: { - if((ob->mode & OB_MODE_EDIT)==0) { + if(ob->mode & OB_MODE_EDIT) { Mesh *me= ob->data; EditMesh *em= me->edit_mesh; -- cgit v1.2.3 From 829bbda7f5322d53614bf6d691b70fb4f65c1ca1 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 12 Oct 2009 09:39:57 +0000 Subject: Bugfix #19616: vertex group select as IK target cause crash in Blender2.5 Thanks to Masahito Takahashi (mato) for the report and patch to fix this! --- source/blender/blenkernel/BKE_constraint.h | 2 +- source/blender/blenkernel/intern/constraint.c | 3 ++- source/blender/editors/object/object_relations.c | 2 +- source/blender/ikplugin/intern/iksolver_plugin.c | 8 ++++---- source/blender/ikplugin/intern/itasc_plugin.cpp | 10 ++++++++-- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 126816f5a95..6446b48d553 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -131,7 +131,7 @@ void constraints_clear_evalob(struct bConstraintOb *cob); void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to); -void get_constraint_target_matrix(struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime); +void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime); void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime); #ifdef __cplusplus diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 8846fe77809..cf919f024b8 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3553,7 +3553,7 @@ short proxylocked_constraints_owner (Object *ob, bPoseChannel *pchan) * None of the actual calculations of the matricies should be done here! Also, this function is * not to be used by any new constraints, particularly any that have multiple targets. */ -void get_constraint_target_matrix (bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime) +void get_constraint_target_matrix (struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime) { bConstraintTypeInfo *cti= constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; @@ -3564,6 +3564,7 @@ void get_constraint_target_matrix (bConstraint *con, int n, short ownertype, voi /* make 'constraint-ob' */ cob= MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb"); cob->type= ownertype; + cob->scene = scene; switch (ownertype) { case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */ { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index d6a55077be9..0c97b945037 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -618,7 +618,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) add_constraint_to_object(con, ob); - get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob)); + get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob)); VecSubf(vec, ob->obmat[3], cmat[3]); ob->loc[0] = vec[0]; diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 68afbcd0db2..b160e7346bd 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -210,7 +210,7 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = t /* called from within the core where_is_pose loop, all animsystems and constraints were executed & assigned. Now as last we do an IK pass */ -static void execute_posetree(Object *ob, PoseTree *tree) +static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) { float R_parmat[3][3], identity[3][3]; float iR_parmat[3][3]; @@ -347,7 +347,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though * strictly speaking, it is a posechannel) */ - get_constraint_target_matrix(target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); + get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); /* and set and transform goal */ Mat4MulMat4(goal, rootmat, goalinv); @@ -357,7 +357,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* same for pole vector target */ if(data->poletar) { - get_constraint_target_matrix(target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); + get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); if(data->flag & CONSTRAINT_IK_SETANGLE) { /* don't solve IK when we are setting the pole angle */ @@ -511,7 +511,7 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose tree->pchan[a]->flag |= POSE_CHAIN; } /* 5. execute the IK solver */ - execute_posetree(ob, tree); + execute_posetree(scene, ob, tree); /* 6. apply the differences to the channels, we need to calculate the original differences first */ diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index dc0c2c4c12f..7f4c1967207 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -89,6 +89,7 @@ void KDL::SetToZero(JntArray& array); // one structure for each target in the scene struct IK_Target { + struct Scene *blscene; iTaSC::MovingFrame* target; iTaSC::ConstraintSet* constraint; struct bConstraint* blenderConstraint; @@ -105,6 +106,7 @@ struct IK_Target float eeRest[4][4]; //end effector initial pose relative to armature IK_Target() { + blscene = NULL; target = NULL; constraint = NULL; blenderConstraint = NULL; @@ -155,6 +157,7 @@ struct IK_Channel { struct IK_Scene { + struct Scene *blscene; IK_Scene* next; int numchan; // number of channel in pchan int numjoint; // number of joint in jointArray @@ -172,6 +175,7 @@ struct IK_Scene std::vector targets; IK_Scene() { + blscene = NULL; next = NULL; channels = NULL; armature = NULL; @@ -533,7 +537,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram bConstraint* constraint = (bConstraint*)target->blenderConstraint; float tarmat[4][4]; - get_constraint_target_matrix(constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0); + get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0); // rootmat contains the target pose in world coordinate // if enforce is != 1.0, blend the target position with the end effector position @@ -601,7 +605,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& IK_Channel &rootchan = ikscene->channels[0]; // get polar target matrix in world space - get_constraint_target_matrix(ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0); + get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0); // convert to armature space Mat4MulMat4(polemat, mat, imat); // get the target in world space (was computed before as target object are defined before base object) @@ -1050,6 +1054,7 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) return NULL; ikscene = new IK_Scene; + ikscene->blscene = blscene; arm = new iTaSC::Armature(); scene = new iTaSC::Scene(); ikscene->channels = new IK_Channel[tree->totchannel]; @@ -1382,6 +1387,7 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) // finally add the constraint for (t=0; ttargets.size(); t++) { IK_Target* iktarget = ikscene->targets[t]; + iktarget->blscene = blscene; condata= (bKinematicConstraint*)iktarget->blenderConstraint->data; pchan = tree->pchan[iktarget->channel]; unsigned int controltype, bonecnt; -- cgit v1.2.3 From b4a113669d8fecad28369b3d777aa285addacf46 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Mon, 12 Oct 2009 09:53:28 +0000 Subject: Cocoa : Fullscreen mode improvement (Bugfix# 16682) Instead of capturing the display and all user input (video game mode), the mechanism is now to hide dock & menu bar, and enlarge the window made borderless to cover the whole screen surface. Thus all OS X window management features remains available (other windows,multi screens compatible, process switching, expose, spaces, ..) --- intern/ghost/intern/GHOST_SystemCocoa.mm | 14 --- intern/ghost/intern/GHOST_WindowCocoa.mm | 150 +++++++++++++++++++++++++------ 2 files changed, 124 insertions(+), 40 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 8bbe446616d..3e0d58b46a6 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -733,13 +733,6 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow( NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_IWindow* window = 0; - //First check if we are in fullscreen mode - //If so, exit it before creating a new window - window = m_windowManager->getActiveWindow(); - if (window && (window->getState() == GHOST_kWindowStateFullScreen)) - window->setState(GHOST_kWindowStateNormal); - window = NULL; - //Get the available rect for including window contents NSRect frame = [[NSScreen mainScreen] visibleFrame]; NSRect contentRect = [NSWindow contentRectForFrameRect:frame @@ -1008,13 +1001,6 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() //Check open windows if some changes are not saved if (m_windowManager->getAnyModifiedState()) { - //First check if we are in fullscreen mode - //If so, exit it before creating a new window - GHOST_IWindow *window = m_windowManager->getActiveWindow(); - if (window && (window->getState() == GHOST_kWindowStateFullScreen)) - window->setState(GHOST_kWindowStateNormal); - window = NULL; - int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?", @"Cancel", @"Quit anyway", nil); if (shouldQuit == NSAlertAlternateReturn) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 205c18e29ba..95c5207b986 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -29,6 +29,11 @@ #include +#ifndef MAC_OS_X_VERSION_10_6 +//Use of the SetSystemUIMode function (64bit compatible) +#include +#endif + #include "GHOST_WindowCocoa.h" #include "GHOST_SystemCocoa.h" #include "GHOST_Debug.h" @@ -44,7 +49,7 @@ static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = 0 }; -#pragma mark Cocoa delegate object +#pragma mark Cocoa window delegate object @interface CocoaWindowDelegate : NSObject { @@ -96,6 +101,26 @@ static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = } @end +#pragma mark NSWindow subclass +//We need to subclass it to tell that even borderless (fullscreen), it can become key (receive user events) +@interface CocoaWindow: NSWindow +{ + +} +-(BOOL)canBecomeKeyWindow; + +@end +@implementation CocoaWindow + +-(BOOL)canBecomeKeyWindow +{ + return YES; +} + +@end + + + #pragma mark NSOpenGLView subclass //We need to subclass it in order to give Cocoa the feeling key events are trapped @interface CocoaOpenGLView : NSOpenGLView @@ -152,7 +177,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( rect.size.width = width; rect.size.height = height; - m_window = [[NSWindow alloc] initWithContentRect:rect + m_window = [[CocoaWindow alloc] initWithContentRect:rect styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:NO]; if (m_window == nil) { @@ -212,9 +237,16 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() if (m_window) { [m_window close]; + [[m_window delegate] release]; [m_window release]; m_window = nil; } + + //Check for other blender opened windows and make the frontmost key + NSArray *windowsList = [NSApp orderedWindows]; + if ([windowsList count]) { + [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; + } [pool drain]; } @@ -295,8 +327,8 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const NSRect screenSize = [[m_window screen] visibleFrame]; //Max window contents as screen size (excluding title bar...) - NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize - styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)]; + NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)]; rect = [m_window contentRectForFrameRect:[m_window frame]]; @@ -418,7 +450,11 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST outY = screenCoord.y; } - +/** + * @note Fullscreen switch is not actual fullscreen with display capture. As this capture removes all OS X window manager features. + * Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged. + * Thus, process switch, exposé, spaces, ... still work in fullscreen mode + */ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) { GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid") @@ -439,9 +475,50 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) //to give window delegate hint not to forward its deactivation to ghost wm that doesn't know view/window difference m_fullScreen = true; - //Only 10.6 API will enable to manage several display in fullscreen mode, and topmenu autoshow - [m_openGLView enterFullScreenMode:[m_window screen] withOptions:nil]; +#ifdef MAC_OS_X_VERSION_10_6 + //10.6 provides Cocoa functions to autoshow menu bar, and to change a window style + //Hide menu & dock if needed + if ([[m_window screen] isEqual:[NSScreen mainScreen]]) + { + [NSApp setPresentationOptions:(NSApplicationPresentationHideDock | NSApplicationPresentationAutoHideMenuBar)]; + } + //Make window borderless and enlarge it + [m_window setStyleMask:NSBorderlessWindowMask]; + [m_window setFrame:[[m_window screen] frame] display:YES]; +#else + //With 10.5, we need to create a new window to change its style to borderless + //Hide menu & dock if needed + if ([[m_window screen] isEqual:[NSScreen mainScreen]]) + { + //Cocoa function in 10.5 does not allow to set the menu bar in auto-show mode [NSMenu setMenuBarVisible:NO]; + //One of the very few 64bit compatible Carbon function + SetSystemUIMode(kUIModeAllHidden,kUIOptionAutoShowMenuBar); + } + //Create a fullscreen borderless window + CocoaWindow *tmpWindow = [[CocoaWindow alloc] + initWithContentRect:[[m_window screen] frame] + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:YES]; + //Copy current window parameters + [tmpWindow setTitle:[m_window title]]; + [tmpWindow setRepresentedURL:[m_window representedURL]]; + [tmpWindow setReleasedWhenClosed:NO]; + [tmpWindow setAcceptsMouseMovedEvents:YES]; + [tmpWindow setDelegate:[m_window delegate]]; + //Assign the openGL view to the new window + [tmpWindow setContentView:m_openGLView]; + + //Show the new window + [tmpWindow makeKeyAndOrderFront:nil]; + //Close and release old window + [m_window setDelegate:nil]; // To avoid the notification of "window closed" event + [m_window close]; + [m_window release]; + m_window = tmpWindow; +#endif + //Tell WM of view new size m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this); @@ -456,11 +533,48 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) m_fullScreen = false; //Exit fullscreen - [m_openGLView exitFullScreenModeWithOptions:nil]; +#ifdef MAC_OS_X_VERSION_10_6 + //Show again menu & dock if needed + if ([[m_window screen] isEqual:[NSScreen mainScreen]]) + { + [NSApp setPresentationOptions:NSApplicationPresentationDefault]; + } + //Make window normal and resize it + [m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)]; + [m_window setFrame:[[m_window screen] visibleFrame] display:YES]; +#else + //With 10.5, we need to create a new window to change its style to borderless + //Show menu & dock if needed + if ([[m_window screen] isEqual:[NSScreen mainScreen]]) + { + //Cocoa function in 10.5 does not allow to set the menu bar in auto-show mode [NSMenu setMenuBarVisible:YES]; + SetSystemUIMode(kUIModeNormal, 0); //One of the very few 64bit compatible Carbon function + } + //Create a fullscreen borderless window + CocoaWindow *tmpWindow = [[CocoaWindow alloc] + initWithContentRect:[[m_window screen] frame] + styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) + backing:NSBackingStoreBuffered + defer:YES]; + //Copy current window parameters + [tmpWindow setTitle:[m_window title]]; + [tmpWindow setRepresentedURL:[m_window representedURL]]; + [tmpWindow setReleasedWhenClosed:NO]; + [tmpWindow setAcceptsMouseMovedEvents:YES]; + [tmpWindow setDelegate:[m_window delegate]]; - [m_window makeKeyAndOrderFront:nil]; - [m_window makeFirstResponder:m_openGLView]; + //Assign the openGL view to the new window + [tmpWindow setContentView:m_openGLView]; + //Show the new window + [tmpWindow makeKeyAndOrderFront:nil]; + //Close and release old window + [m_window setDelegate:nil]; // To avoid the notification of "window closed" event + [m_window close]; + [m_window release]; + m_window = tmpWindow; +#endif + //Tell WM of view new size m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this); @@ -534,22 +648,7 @@ GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext() if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) { if (m_openGLContext != nil) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [m_openGLContext makeCurrentContext]; -#ifdef GHOST_DRAW_CARBON_GUTTER - // Restrict drawing to non-gutter area - ::aglEnable(m_aglCtx, AGL_BUFFER_RECT); - GHOST_Rect bnds; - getClientBounds(bnds); - GLint b[4] = - { - bnds.m_l, - bnds.m_t+s_sizeRectSize, - bnds.m_r-bnds.m_l, - bnds.m_b-bnds.m_t - }; - GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b); -#endif //GHOST_DRAW_CARBON_GUTTER [pool drain]; return GHOST_kSuccess; } @@ -725,7 +824,6 @@ inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore) { - printf("\ncursor grab %i",grab); if (grab) { //No need to perform grab without warp as it is always on in OS X -- cgit v1.2.3 From 237cd688aaead5592393db58cf2e39e2ab3ce9b2 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 12 Oct 2009 11:27:34 +0000 Subject: Animation Editors: 'Only Selected' filtering option now works on Pose Channels too * Only F-Curves and Drivers that affect selected bones will be visible when this happens. * Moved the function to grab text within a pair of "" following some prefix to blenlib. --- source/blender/blenlib/BLI_string.h | 11 ++ source/blender/blenlib/intern/string.c | 24 +++++ source/blender/editors/animation/anim_deps.c | 14 +-- source/blender/editors/animation/anim_filter.c | 123 ++++++++++++++-------- source/blender/editors/animation/anim_ipo_utils.c | 28 +---- 5 files changed, 125 insertions(+), 75 deletions(-) diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 53563f85eb9..fb345de72e9 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -68,6 +68,17 @@ char *BLI_strdupn(const char *str, int len); */ char *BLI_strncpy(char *dst, const char *src, int maxncpy); + /* Makes a copy of the text within the "" that appear after some text 'blahblah' + * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples" + * + * - str: is the entire string to chop + * - prefix: is the part of the string to leave out + * + * Assume that the strings returned must be freed afterwards, and that the inputs will contain + * data we want... + */ +char *BLI_getQuotedStr(const char *str, const char *prefix); + /** * Returns a copy of the cstring @a str into a newly mallocN'd * string with all instances of oldText replaced with newText, diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index de4b53cbd93..405f8c6db97 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -100,6 +100,30 @@ char *BLI_sprintfN(const char *format, ...) return n; } +/* Makes a copy of the text within the "" that appear after some text 'blahblah' + * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples" + * + * - str: is the entire string to chop + * - prefix: is the part of the string to leave out + * + * Assume that the strings returned must be freed afterwards, and that the inputs will contain + * data we want... + */ +char *BLI_getQuotedStr (const char *str, const char *prefix) +{ + int prefixLen = strlen(prefix); + char *startMatch, *endMatch; + + /* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */ + startMatch= strstr(str, prefix) + prefixLen + 1; + + /* get the end point (i.e. where the next occurance of " is after the starting point) */ + endMatch= strchr(startMatch, '"'); // " NOTE: this comment here is just so that my text editor still shows the functions ok... + + /* return the slice indicated */ + return BLI_strdupn(startMatch, (int)(endMatch-startMatch)); +} + /* Replaces all occurances of oldText with newText in str, returning a new string that doesn't * contain the 'replaced' occurances. */ diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 62341a5d6ae..9d39911548b 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -78,10 +78,7 @@ void ED_anim_object_flush_update(const bContext *C, Object *ob) * 3) Grouping (only for pose to action for now) */ -/* XXX OBSOLETE CODE WARNING: - * With the Animato system, the code below is somewhat obsolete now... - */ - + /* Notifier from Action/Dopesheet (this may be extended to include other things such as Python...) * Channels in action changed, so update pose channels/groups to reflect changes. * @@ -90,12 +87,14 @@ void ED_anim_object_flush_update(const bContext *C, Object *ob) */ void ANIM_action_to_pose_sync (Object *ob) { - bAction *act= (bAction *)ob->action; - bActionChannel *achan; +#if 0 + AnimData *adt= ob->adt; + bAction *act= adt->act; + FCurve *fcu; bPoseChannel *pchan; /* error checking */ - if ((ob == NULL) || (ob->type != OB_ARMATURE) || ELEM(NULL, act, ob->pose)) + if (ELEM3(NULL, ob, ob->adt, ob->pose) || (ob->type != OB_ARMATURE)) return; /* 1b) loop through all Action-Channels (there should be fewer channels to search through here in general) */ @@ -120,6 +119,7 @@ void ANIM_action_to_pose_sync (Object *ob) } // TODO: add grouping changes too? For now, these tools aren't exposed to users in animation editors yet... +#endif } /* Notifier from 3D-View/Outliner (this is likely to include other sources too...) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 13b050e4497..6b953d2460d 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -77,6 +77,7 @@ #include "BLI_blenlib.h" #include "BKE_animsys.h" +#include "BKE_action.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_key.h" @@ -676,7 +677,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s /* ----------------------------------------- */ -static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionGroup *grp, void *owner, short ownertype, int filter_mode, ID *owner_id) +static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, void *owner, short ownertype, int filter_mode, ID *owner_id) { bAnimListElem *ale = NULL; FCurve *fcu; @@ -686,6 +687,35 @@ static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionG * NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too... */ for (fcu= first; ((fcu) && (fcu->grp==grp)); fcu= fcu->next) { + /* special exception for Pose-Channel Based F-Curves: + * - the 'Only Selected' data filter should be applied to Pose-Channel data too, but those are + * represented as F-Curves. The way the filter for objects worked was to be the first check + * after 'normal' visibility, so this is done first here too... + * - we currently use an 'approximate' method for getting these F-Curves that doesn't require + * carefully checking the entire path + * - this will also affect things like Drivers, and also works for Bone Constraints + */ + if ( ((ads) && (ads->filterflag & ADS_FILTER_ONLYSEL)) && + ((owner_id) && (GS(owner_id->name) == ID_OB)) ) + { + Object *ob= (Object *)owner_id; + + /* only consider if F-Curve involves pose_channels */ + if ((fcu->rna_path) && strstr(fcu->rna_path, "pose_channels")) { + bPoseChannel *pchan; + char *bone_name; + + /* get bone-name, and check if this bone is selected */ + bone_name= BLI_getQuotedStr(fcu->rna_path, "pose_channels["); + pchan= get_pose_channel(ob->pose, bone_name); + if (bone_name) MEM_freeN(bone_name); + + /* can only add this F-Curve if it is selected */ + if ((pchan) && (pchan->bone) && (pchan->bone->flag & BONE_SELECTED)==0) + continue; + } + } + /* only include if visible (Graph Editor check, not channels check) */ if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || (fcu->flag & FCURVE_VISIBLE)) { /* only work with this channel and its subchannels if it is editable */ @@ -710,7 +740,7 @@ static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionG return items; } -static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter_mode, void *owner, short ownertype, ID *owner_id) +static int animdata_filter_action (ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, void *owner, short ownertype, ID *owner_id) { bAnimListElem *ale=NULL; bActionGroup *agrp; @@ -718,16 +748,21 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter int items = 0; /* loop over groups */ - // XXX in future, we need to be prepared for nestled groups... + // TODO: in future, should we expect to need nested groups? for (agrp= act->groups.first; agrp; agrp= agrp->next) { + ListBase tmp_channels = {NULL, NULL}; + short grp_channel=0; + int tmp_items = 0; + + /* add this group as a channel first */ if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) { /* check if filtering by selection */ if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) { ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id); if (ale) { - BLI_addtail(anim_data, ale); - items++; + BLI_addtail(&tmp_channels, ale); + grp_channel=1; } } } @@ -758,28 +793,30 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter { if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) { // XXX the 'owner' info here needs review... - items += animdata_filter_fcurves(anim_data, agrp->channels.first, agrp, owner, ownertype, filter_mode, owner_id); - - /* remove group from filtered list if last element is group - * (i.e. only if group had channels, which were all hidden) - */ - // XXX this is really hacky... it should be fixed in a much more elegant way! - if ( (ale) && (anim_data->last == ale) && - (ale->data == agrp) && (agrp->channels.first) ) - { - BLI_freelinkN(anim_data, ale); - items--; - } + tmp_items += animdata_filter_fcurves(&tmp_channels, ads, agrp->channels.first, agrp, owner, ownertype, filter_mode, owner_id); } } } } + + /* check group had any F-Curves visible */ + // TODO: this needs more work to truly work so that closed group with no visible channels, and visible group with visible channels are differentiated between + if (/*tmp_items*/1) { + /* add the temp channels to the list of filtered channels */ + addlisttolist(anim_data, &tmp_channels); + + /* increase the counts as appropriate */ + items += tmp_items + grp_channel; + } + else { + BLI_freelistN(&tmp_channels); + } } /* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive group) */ if (!(filter_mode & ANIMFILTER_ACTGROUPED)) { // XXX the 'owner' info here needs review... - items += animdata_filter_fcurves(anim_data, (lastchan)?(lastchan->next):(act->curves.first), NULL, owner, ownertype, filter_mode, owner_id); + items += animdata_filter_fcurves(anim_data, ads, (lastchan)?(lastchan->next):(act->curves.first), NULL, owner, ownertype, filter_mode, owner_id); } /* return the number of items added to the list */ @@ -794,7 +831,7 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter * - for normal filtering (i.e. for editing), we only need the NLA-tracks but they can be in 'normal' evaluation * order, i.e. first to last. Otherwise, some tools may get screwed up. */ -static int animdata_filter_nla (ListBase *anim_data, AnimData *adt, int filter_mode, void *owner, short ownertype, ID *owner_id) +static int animdata_filter_nla (ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, void *owner, short ownertype, ID *owner_id) { bAnimListElem *ale; NlaTrack *nlt; @@ -996,9 +1033,9 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads, if (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) { ANIMDATA_FILTER_CASES(ma, { /* AnimData blocks - do nothing... */ }, - items += animdata_filter_nla(anim_data, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);, - items += animdata_filter_fcurves(anim_data, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);, - items += animdata_filter_action(anim_data, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);) + items += animdata_filter_nla(anim_data, ads, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);, + items += animdata_filter_fcurves(anim_data, ads, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);, + items += animdata_filter_action(anim_data, ads, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);) } } } @@ -1056,9 +1093,9 @@ static int animdata_filter_dopesheet_particles (ListBase *anim_data, bDopeSheet if (FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) { ANIMDATA_FILTER_CASES(psys->part, { /* AnimData blocks - do nothing... */ }, - items += animdata_filter_nla(anim_data, psys->part->adt, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);, - items += animdata_filter_fcurves(anim_data, psys->part->adt->drivers.first, NULL, psys->part, ANIMTYPE_DSPART, filter_mode, (ID *)psys->part);, - items += animdata_filter_action(anim_data, psys->part->adt->action, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);) + items += animdata_filter_nla(anim_data, ads, psys->part->adt, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);, + items += animdata_filter_fcurves(anim_data, ads, psys->part->adt->drivers.first, NULL, psys->part, ANIMTYPE_DSPART, filter_mode, (ID *)psys->part);, + items += animdata_filter_action(anim_data, ads, psys->part->adt->action, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);) } } } @@ -1138,9 +1175,9 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad /* filtering for channels - nla, drivers, keyframes */ ANIMDATA_FILTER_CASES(iat, { /* AnimData blocks - do nothing... */ }, - items+= animdata_filter_nla(anim_data, iat->adt, filter_mode, iat, type, (ID *)iat);, - items+= animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);, - items += animdata_filter_action(anim_data, iat->adt->action, filter_mode, iat, type, (ID *)iat);) + items+= animdata_filter_nla(anim_data, ads, iat->adt, filter_mode, iat, type, (ID *)iat);, + items+= animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);, + items += animdata_filter_action(anim_data, ads, iat->adt->action, filter_mode, iat, type, (ID *)iat);) } /* return the number of items added to the list */ @@ -1182,7 +1219,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B { /* AnimData blocks - do nothing... */ }, { /* nla */ /* add NLA tracks */ - items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); + items += animdata_filter_nla(anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); }, { /* drivers */ /* include drivers-expand widget? */ @@ -1197,7 +1234,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B /* add F-Curve channels (drivers are F-Curves) */ if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) { // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?) - items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob); + items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob); } }, { /* action (keyframes) */ @@ -1213,7 +1250,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B /* add F-Curve channels? */ if (EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) { // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?) - items += animdata_filter_action(anim_data, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); + items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); } } ); @@ -1240,7 +1277,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B /* add NLA tracks - only if expanded or so */ if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) - items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); + items += animdata_filter_nla(anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); }, { /* drivers */ /* include shapekey-expand widget? */ @@ -1254,7 +1291,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B /* add channels */ if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) { - items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, key, ANIMTYPE_DSSKEY, filter_mode, (ID *)key); + items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, key, ANIMTYPE_DSSKEY, filter_mode, (ID *)key); } }, { /* action (keyframes) */ @@ -1272,7 +1309,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B /* add channels */ if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) { - items += animdata_filter_action(anim_data, adt->action, filter_mode, key, ANIMTYPE_DSSKEY, (ID *)key); + items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, key, ANIMTYPE_DSSKEY, (ID *)key); } } ); @@ -1384,14 +1421,14 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads if ( (EXPANDED_SCEC(sce) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) ) return items; - /* Action, Drivers, or NLA for Scene */ + /* Action, Drivers, or NLA for Scene */ if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) { adt= sce->adt; ANIMDATA_FILTER_CASES(sce, { /* AnimData blocks - do nothing... */ }, { /* nla */ /* add NLA tracks */ - items += animdata_filter_nla(anim_data, adt, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce); + items += animdata_filter_nla(anim_data, ads, adt, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce); }, { /* drivers */ /* include drivers-expand widget? */ @@ -1405,7 +1442,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads /* add F-Curve channels (drivers are F-Curves) */ if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) { - items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, sce, ANIMTYPE_SCENE, filter_mode, (ID *)sce); + items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, sce, ANIMTYPE_SCENE, filter_mode, (ID *)sce); } }, { /* action */ @@ -1420,7 +1457,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads /* add F-Curve channels? */ if (EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) { - items += animdata_filter_action(anim_data, adt->action, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce); + items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce); } } ) @@ -1434,7 +1471,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads { /* AnimData blocks - do nothing... */ }, { /* nla */ /* add NLA tracks */ - items += animdata_filter_nla(anim_data, adt, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo); + items += animdata_filter_nla(anim_data, ads, adt, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo); }, { /* drivers */ /* include world-expand widget? */ @@ -1449,7 +1486,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads /* add F-Curve channels (drivers are F-Curves) */ if (FILTER_WOR_SCED(wo)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) { // XXX owner info is messed up now... - items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, wo, ANIMTYPE_DSWOR, filter_mode, (ID *)wo); + items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, wo, ANIMTYPE_DSWOR, filter_mode, (ID *)wo); } }, { /* action */ @@ -1464,12 +1501,14 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads /* add channels */ if (FILTER_WOR_SCED(wo) || (filter_mode & ANIMFILTER_CURVESONLY)) { - items += animdata_filter_action(anim_data, adt->action, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo); + items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo); } } ) } + // TODO: scene compositing nodes (these aren't standard node-trees) + /* return the number of items added to the list */ return items; } @@ -1861,7 +1900,7 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode /* firstly filter the data */ switch (datatype) { case ANIMCONT_ACTION: - items= animdata_filter_action(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact); + items= animdata_filter_action(anim_data, NULL, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact); break; case ANIMCONT_SHAPEKEY: diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index 1590aa57463..088fddd2e7e 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -93,30 +93,6 @@ int geticon_anim_blocktype(short blocktype) } } -/* helper function for getname_*() - grabs the text within the "" that starts with 'blahblah' - * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples" - * - * - str: is the entire string to chop - * - prefix: is the part of the string to leave out - * - * Assume that the strings returned must be freed afterwards, and that the inputs will contain - * data we want... - */ -static char *grab_quoted_text (const char *str, const char *prefix) -{ - int prefixLen = strlen(prefix); - char *startMatch, *endMatch; - - /* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */ - startMatch= strstr(str, prefix) + prefixLen + 1; - - /* get the end point (i.e. where the next occurance of " is after the starting point) */ - endMatch= strchr(startMatch, '"'); // " NOTE: this comment here is just so that my text editor still shows the functions ok... - - /* return the slice indicated */ - return BLI_strdupn(startMatch, (int)(endMatch-startMatch)); -} - /* Write into "name" buffer, the name of the property (retrieved using RNA from the curve's settings) * WARNING: name buffer we're writing to cannot exceed 256 chars (check anim_channels_defines.c for details) */ @@ -164,8 +140,8 @@ void getname_anim_fcurve(char *name, ID *id, FCurve *fcu) */ if (strstr(fcu->rna_path, "pose_channels") && strstr(fcu->rna_path, "constraints")) { /* perform string 'chopping' to get "Bone Name : Constraint Name" */ - char *pchanName= grab_quoted_text(fcu->rna_path, "pose_channels["); - char *constName= grab_quoted_text(fcu->rna_path, "constraints["); + char *pchanName= BLI_getQuotedStr(fcu->rna_path, "pose_channels["); + char *constName= BLI_getQuotedStr(fcu->rna_path, "constraints["); /* assemble the string to display in the UI... */ structname= BLI_sprintfN("%s : %s", pchanName, constName); -- cgit v1.2.3 From 600fcd98f3b3162db191f865e070c695af1f9713 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Mon, 12 Oct 2009 11:41:20 +0000 Subject: Fix some mem leaks --- source/blender/blenlib/intern/util.c | 2 ++ source/blender/editors/screen/area.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index f6fa4f1ebd2..387d1881d3c 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1527,6 +1527,8 @@ char* BLI_getbundle(void) { bundleURL = CFBundleCopyBundleURL(mainBundle); pathStr = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle); CFStringGetCString(pathStr, path, MAXPATHLEN, kCFStringEncodingASCII); + CFRelease(pathStr); + CFRelease(bundleURL); return path; } #endif diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f539020c93d..428f17886ec 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -193,7 +193,7 @@ static void area_draw_azone(short x1, short y1, short x2, short y2) static void region_draw_azone(ScrArea *sa, AZone *az) { - GLUquadricObj *qobj = gluNewQuadric(); + GLUquadricObj *qobj = NULL; short midx = az->x1 + (az->x2 - az->x1)/2; short midy = az->y1 + (az->y2 - az->y1)/2; @@ -202,6 +202,8 @@ static void region_draw_azone(ScrArea *sa, AZone *az) /* only display action zone icons when the region is hidden */ if (!(az->ar->flag & RGN_FLAG_HIDDEN)) return; + qobj = gluNewQuadric(); + glPushMatrix(); glTranslatef(midx, midy, 0.); -- cgit v1.2.3 From 715f682f224aae59e5565dfad5d4ef230d3a38df Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 12 Oct 2009 12:39:05 +0000 Subject: Fixed [#19624] Small typo in Network Render. --- release/scripts/io/netrender/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py index cc1cbf3ed4a..fba834ed9e0 100644 --- a/release/scripts/io/netrender/ui.py +++ b/release/scripts/io/netrender/ui.py @@ -80,7 +80,7 @@ class SCENE_PT_network_job(RenderButtonsPanel): col = split.column() - col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animation on network") col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job") col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor") col.itemR(scene.network_render, "job_name") -- cgit v1.2.3 From e36003e8e73e42e7b559d4cec19b9004d14fefa6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 12:54:08 +0000 Subject: macro's can set options for the operators they execute changed extrude, rip and duplicate to disable proportional editing however this gives a different problem now. Commented in transform.c // XXX If modal, save settings back in scene this changes disables the option whenever the macro used used. --- source/blender/editors/include/ED_mesh.h | 1 + source/blender/editors/include/ED_object.h | 1 + source/blender/editors/mesh/mesh_ops.c | 18 +++++++++++------- source/blender/editors/object/object_ops.c | 6 +++++- source/blender/editors/space_api/spacetypes.c | 6 ++++++ source/blender/makesdna/DNA_windowmanager_types.h | 5 +++-- source/blender/windowmanager/WM_api.h | 1 + source/blender/windowmanager/intern/wm_keymap.c | 12 +----------- source/blender/windowmanager/intern/wm_operators.c | 22 ++++++++++++++++++++-- 9 files changed, 49 insertions(+), 23 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index cf0e6eb01c3..3bceeb9340e 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -85,6 +85,7 @@ int join_mesh_exec(struct bContext *C, struct wmOperator *op); /* mesh_ops.c */ void ED_operatortypes_mesh(void); +void ED_operatormacros_mesh(void); void ED_keymap_mesh(struct wmKeyConfig *keyconf); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 7ea882b765b..e19fc806404 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -44,6 +44,7 @@ struct ModifierData; /* object_edit.c */ void ED_operatortypes_object(void); +void ED_operatormacros_object(void); void ED_keymap_object(struct wmKeyConfig *keyconf); /* send your own notifier for select! */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 0865455b3b9..9e74c5717c6 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -235,8 +235,6 @@ static void MESH_OT_specials(wmOperatorType *ot) void ED_operatortypes_mesh(void) { - wmOperatorType *ot; - WM_operatortype_append(MESH_OT_select_all_toggle); WM_operatortype_append(MESH_OT_select_more); WM_operatortype_append(MESH_OT_select_less); @@ -323,8 +321,12 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_edgering_select); WM_operatortype_append(MESH_OT_loopcut); +} - /* macros */ +void ED_operatormacros_mesh(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; /*combining operators with invoke and exec portions doesn't work yet. @@ -335,16 +337,18 @@ void ED_operatortypes_mesh(void) ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_duplicate"); - WM_operatortype_macro_define(ot, "TFM_OT_translate"); + otmacro= WM_operatortype_macro_define(ot, "TFM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); ot= WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_rip"); - WM_operatortype_macro_define(ot, "TFM_OT_translate"); + otmacro= WM_operatortype_macro_define(ot, "TFM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "MESH_OT_extrude"); - WM_operatortype_macro_define(ot, "TFM_OT_translate"); - + otmacro= WM_operatortype_macro_define(ot, "TFM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); } /* note mesh keymap also for other space? */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 2b010f5b6bc..9869d15a69c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -178,8 +178,12 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_remove); +} + +void ED_operatormacros_object(void) +{ + wmOperatorType *ot; - /* macros */ ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER); if(ot) { WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate"); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 397da005543..60b9c5a6da7 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -105,6 +105,12 @@ void ED_spacetypes_init(void) spacetypes = BKE_spacetypes_list(); for(type=spacetypes->first; type; type=type->next) type->operatortypes(); + + + /* Macros's must go last since they reference other operators + * maybe we'll need to have them go after python operators too? */ + ED_operatormacros_mesh(); + ED_operatormacros_object(); } /* called in wm.c */ diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 0292f01fd6d..7a024e35ff0 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -181,6 +181,7 @@ typedef struct wmOperatorTypeMacro { /* operator id */ char idname[MAX_ID_NAME]; /* rna pointer to access properties, like keymap */ + struct IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ struct PointerRNA *ptr; } wmOperatorTypeMacro; @@ -240,14 +241,14 @@ typedef struct wmKeyMapItem { /* operator */ char idname[64]; /* used to retrieve operator type pointer */ - IDProperty *properties; /* operator properties */ + IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ /* modal */ short propvalue; /* if used, the item is from modal map */ /* event */ short type; /* event code itself */ - short val; /* 0=any, 1=click, 2=release, or wheelvalue, or... */ + short val; /* KM_ANY, KM_PRESS, KM_NOTHING etc */ short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ short keymodifier; /* rawkey modifier */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 44e404524f5..958b388f574 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -181,6 +181,7 @@ int WM_operator_repeat (struct bContext *C, struct wmOperator *op); int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties); int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports); +void WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */ void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_free(struct PointerRNA *ptr); void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 3d3a6e46fb2..eedacb056b7 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -57,17 +57,7 @@ static void keymap_properties_set(wmKeyMapItem *kmi) { - if(!kmi->properties) { - IDPropertyTemplate val = {0}; - kmi->properties= IDP_New(IDP_GROUP, val, "wmKeyMapItemProperties"); - } - - if(!kmi->ptr) { - kmi->ptr= MEM_callocN(sizeof(PointerRNA), "wmKeyMapItemPtr"); - WM_operator_properties_create(kmi->ptr, kmi->idname); - } - - kmi->ptr->data= kmi->properties; + WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname); } wmKeyConfig *WM_keyconfig_add(wmWindowManager *wm, char *idname) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7db6669ca74..99872f92f0f 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -270,8 +270,7 @@ wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char BLI_strncpy(otmacro->idname, idname, OP_MAX_TYPENAME); /* do this on first use, since operatordefinitions might have been not done yet */ -// otmacro->ptr= MEM_callocN(sizeof(PointerRNA), "optype macro ItemPtr"); -// WM_operator_properties_create(otmacro->ptr, idname); + WM_operator_properties_alloc(&(otmacro->ptr), &(otmacro->properties), idname); BLI_addtail(&ot->macro, otmacro); @@ -441,6 +440,25 @@ void WM_operator_properties_create(PointerRNA *ptr, const char *opstring) RNA_pointer_create(NULL, &RNA_OperatorProperties, NULL, ptr); } +/* similar to the function above except its uses ID properties + * used for keymaps and macros */ +void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring) +{ + if(*properties==NULL) { + IDPropertyTemplate val = {0}; + *properties= IDP_New(IDP_GROUP, val, "wmOpItemProp"); + } + + if(*ptr==NULL) { + *ptr= MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr"); + WM_operator_properties_create(*ptr, opstring); + } + + (*ptr)->data= *properties; + +} + + void WM_operator_properties_free(PointerRNA *ptr) { IDProperty *properties= ptr->data; -- cgit v1.2.3 From f1a0df22df7b929601db58db5ecb77ed82bf8361 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Oct 2009 13:12:45 +0000 Subject: Bugfix: texture nodes header was still showing wrong texture when using node materials. --- source/blender/blenkernel/BKE_texture.h | 5 ++ source/blender/blenkernel/intern/texture.c | 105 ++++++++++++++++++++++++++ source/blender/makesrna/intern/rna_brush.c | 18 +---- source/blender/makesrna/intern/rna_lamp.c | 20 +---- source/blender/makesrna/intern/rna_material.c | 18 +---- source/blender/makesrna/intern/rna_world.c | 22 +----- 6 files changed, 119 insertions(+), 69 deletions(-) diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 407dc94adfa..c7a6e20cc8b 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -75,6 +75,11 @@ struct Tex *give_current_lamp_texture(struct Lamp *la); struct Tex *give_current_world_texture(struct World *world); struct Tex *give_current_brush_texture(struct Brush *br); +void set_current_brush_texture(struct Brush *br, struct Tex *tex); +void set_current_world_texture(struct World *wo, struct Tex *tex); +void set_current_material_texture(struct Material *ma, struct Tex *tex); +void set_current_lamp_texture(struct Lamp *la, struct Tex *tex); + struct TexMapping *add_mapping(void); void init_mapping(struct TexMapping *texmap); diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index f09abf93bb8..d1c26b5a1b4 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -840,6 +840,28 @@ Tex *give_current_lamp_texture(Lamp *la) return tex; } +void set_current_lamp_texture(Lamp *la, Tex *newtex) +{ + int act= la->texact; + + if(la->mtex[act] && la->mtex[act]->tex) + id_us_min(&la->mtex[act]->tex->id); + + if(newtex) { + if(!la->mtex[act]) { + la->mtex[act]= add_mtex(); + la->mtex[act]->texco= TEXCO_GLOB; + } + + la->mtex[act]->tex= newtex; + id_us_plus(&newtex->id); + } + else if(la->mtex[act]) { + MEM_freeN(la->mtex[act]); + la->mtex[act]= NULL; + } +} + Tex *give_current_material_texture(Material *ma) { MTex *mtex= NULL; @@ -867,6 +889,47 @@ Tex *give_current_material_texture(Material *ma) return tex; } +void set_current_material_texture(Material *ma, Tex *newtex) +{ + Tex *tex= NULL; + bNode *node; + + if(ma && ma->use_nodes && ma->nodetree) { + node= nodeGetActiveID(ma->nodetree, ID_TE); + + if(node) { + tex= (Tex *)node->id; + id_us_min(&tex->id); + node->id= &newtex->id; + id_us_plus(&newtex->id); + ma= NULL; + } + else { + node= nodeGetActiveID(ma->nodetree, ID_MA); + if(node) + ma= (Material*)node->id; + } + } + if(ma) { + int act= (int)ma->texact; + + tex= (ma->mtex[act])? ma->mtex[act]->tex: NULL; + id_us_min(&tex->id); + + if(newtex) { + if(!ma->mtex[act]) + ma->mtex[act]= add_mtex(); + + ma->mtex[act]->tex= newtex; + id_us_plus(&newtex->id); + } + else if(ma->mtex[act]) { + MEM_freeN(ma->mtex[act]); + ma->mtex[act]= NULL; + } + } +} + Tex *give_current_world_texture(World *world) { MTex *mtex= NULL; @@ -880,6 +943,28 @@ Tex *give_current_world_texture(World *world) return tex; } +void set_current_world_texture(World *wo, Tex *newtex) +{ + int act= wo->texact; + + if(wo->mtex[act] && wo->mtex[act]->tex) + id_us_min(&wo->mtex[act]->tex->id); + + if(newtex) { + if(!wo->mtex[act]) { + wo->mtex[act]= add_mtex(); + wo->mtex[act]->texco= TEXCO_VIEW; + } + + wo->mtex[act]->tex= newtex; + id_us_plus(&newtex->id); + } + else if(wo->mtex[act]) { + MEM_freeN(wo->mtex[act]); + wo->mtex[act]= NULL; + } +} + Tex *give_current_brush_texture(Brush *br) { MTex *mtex= NULL; @@ -893,6 +978,26 @@ Tex *give_current_brush_texture(Brush *br) return tex; } +void set_current_brush_texture(Brush *br, Tex *newtex) +{ + int act= br->texact; + + if(br->mtex[act] && br->mtex[act]->tex) + id_us_min(&br->mtex[act]->tex->id); + + if(newtex) { + if(!br->mtex[act]) + br->mtex[act]= add_mtex(); + + br->mtex[act]->tex= newtex; + id_us_plus(&newtex->id); + } + else if(br->mtex[act]) { + MEM_freeN(br->mtex[act]); + br->mtex[act]= NULL; + } +} + /* ------------------------------------------------------------------------- */ EnvMap *BKE_add_envmap(void) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index e87c8434a7d..e9744c7f5ed 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -65,29 +65,15 @@ static PointerRNA rna_Brush_active_texture_get(PointerRNA *ptr) Brush *br= (Brush*)ptr->data; Tex *tex; - tex= (br->mtex[(int)br->texact])? br->mtex[(int)br->texact]->tex: NULL; + tex= give_current_brush_texture(br); return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); } static void rna_Brush_active_texture_set(PointerRNA *ptr, PointerRNA value) { Brush *br= (Brush*)ptr->data; - int act= br->texact; - if(br->mtex[act] && br->mtex[act]->tex) - id_us_min(&br->mtex[act]->tex->id); - - if(value.data) { - if(!br->mtex[act]) - br->mtex[act]= add_mtex(); - - br->mtex[act]->tex= value.data; - id_us_plus(&br->mtex[act]->tex->id); - } - else if(br->mtex[act]) { - MEM_freeN(br->mtex[act]); - br->mtex[act]= NULL; - } + set_current_brush_texture(br, value.data); } static void rna_Brush_update(bContext *C, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 3d3333a7eed..88d9a496840 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -69,31 +69,15 @@ static PointerRNA rna_Lamp_active_texture_get(PointerRNA *ptr) Lamp *la= (Lamp*)ptr->data; Tex *tex; - tex= (la->mtex[(int)la->texact])? la->mtex[(int)la->texact]->tex: NULL; + tex= give_current_lamp_texture(la); return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); } static void rna_Lamp_active_texture_set(PointerRNA *ptr, PointerRNA value) { Lamp *la= (Lamp*)ptr->data; - int act= la->texact; - if(la->mtex[act] && la->mtex[act]->tex) - id_us_min(&la->mtex[act]->tex->id); - - if(value.data) { - if(!la->mtex[act]) { - la->mtex[act]= add_mtex(); - la->mtex[act]->texco= TEXCO_GLOB; - } - - la->mtex[act]->tex= value.data; - id_us_plus(&la->mtex[act]->tex->id); - } - else if(la->mtex[act]) { - MEM_freeN(la->mtex[act]); - la->mtex[act]= NULL; - } + set_current_lamp_texture(la, value.data); } static StructRNA* rna_Lamp_refine(struct PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 3366bc04c70..b05cf1afa84 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -130,29 +130,15 @@ static PointerRNA rna_Material_active_texture_get(PointerRNA *ptr) Material *ma= (Material*)ptr->data; Tex *tex; - tex= (ma->mtex[(int)ma->texact])? ma->mtex[(int)ma->texact]->tex: NULL; + tex= give_current_material_texture(ma); return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); } static void rna_Material_active_texture_set(PointerRNA *ptr, PointerRNA value) { Material *ma= (Material*)ptr->data; - int act= ma->texact; - if(ma->mtex[act] && ma->mtex[act]->tex) - id_us_min(&ma->mtex[act]->tex->id); - - if(value.data) { - if(!ma->mtex[act]) - ma->mtex[act]= add_mtex(); - - ma->mtex[act]->tex= value.data; - id_us_plus(&ma->mtex[act]->tex->id); - } - else if(ma->mtex[act]) { - MEM_freeN(ma->mtex[act]); - ma->mtex[act]= NULL; - } + set_current_material_texture(ma, value.data); } static PointerRNA rna_Material_active_node_material_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index b2ed90eef03..c0c9c1d6568 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -71,31 +71,15 @@ static PointerRNA rna_World_active_texture_get(PointerRNA *ptr) World *wo= (World*)ptr->data; Tex *tex; - tex= (wo->mtex[(int)wo->texact])? wo->mtex[(int)wo->texact]->tex: NULL; + tex= give_current_world_texture(wo); return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex); } static void rna_World_active_texture_set(PointerRNA *ptr, PointerRNA value) { World *wo= (World*)ptr->data; - int act= wo->texact; - - if(wo->mtex[act] && wo->mtex[act]->tex) - id_us_min(&wo->mtex[act]->tex->id); - - if(value.data) { - if(!wo->mtex[act]) { - wo->mtex[act]= add_mtex(); - wo->mtex[act]->texco= TEXCO_VIEW; - } - - wo->mtex[act]->tex= value.data; - id_us_plus(&wo->mtex[act]->tex->id); - } - else if(wo->mtex[act]) { - MEM_freeN(wo->mtex[act]); - wo->mtex[act]= NULL; - } + + set_current_world_texture(wo, value.data); } static void rna_World_update(bContext *C, PointerRNA *ptr) -- cgit v1.2.3 From 0eab183a66a8faaaed93c9ca35300288d0467493 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 12 Oct 2009 13:37:07 +0000 Subject: Following up on revision 23783 Transform saves back tool settings only when they weren't set as operator argument (and only when running modal). --- source/blender/editors/transform/transform.c | 50 +++++++++++++--------- .../blender/editors/transform/transform_generics.c | 2 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ad89d8a3a59..0b7a672a0b6 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1288,6 +1288,36 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) proportional = 0; } + // If modal, save settings back in scene if not set as operator argument + if (t->flag & T_MODAL) + { + /* save settings if not set in operator */ + if (RNA_struct_find_property(op->ptr, "proportional") && !RNA_property_is_set(op->ptr, "proportional")) + { + ts->proportional = proportional; + } + + if (RNA_struct_find_property(op->ptr, "proportional_size") && !RNA_property_is_set(op->ptr, "proportional_size")) + { + ts->proportional_size = t->prop_size; + } + + if (RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && !RNA_property_is_set(op->ptr, "proportional_editing_falloff")) + { + ts->prop_mode = t->prop_mode; + } + + if(t->spacetype == SPACE_VIEW3D) + { + if (RNA_struct_find_property(op->ptr, "constraint_orientation") && !RNA_property_is_set(op->ptr, "constraint_orientation")) + { + View3D *v3d = t->view; + + v3d->twmode = t->current_orientation; + } + } + } + if (RNA_struct_find_property(op->ptr, "proportional")) { RNA_enum_set(op->ptr, "proportional", proportional); @@ -1319,26 +1349,6 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); } - - // XXX If modal, save settings back in scene - if (t->flag & T_MODAL) - { - ts->prop_mode = t->prop_mode; - - /* only save back if it wasn't automatically disabled */ - if ((t->options & CTX_NO_PET) == 0) - { - ts->proportional = proportional; - ts->proportional_size = t->prop_size; - } - - if(t->spacetype == SPACE_VIEW3D) - { - View3D *v3d = t->view; - - v3d->twmode = t->current_orientation; - } - } } int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode) diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 6637122ffb8..c3ceea1a0c8 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -934,7 +934,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; t->around = v3d->around; - if (op && RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_orientation")) + if (op && RNA_struct_find_property(op->ptr, "constraint_orientation") && RNA_property_is_set(op->ptr, "constraint_orientation")) { t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation"); -- cgit v1.2.3 From 50fd4f967f7f83c8ff33b76274bc6f2e8845fb46 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 14:38:35 +0000 Subject: minor changes to texture ui, not user visible --- release/scripts/ui/buttons_texture.py | 78 ++++++++++++++++++----------------- release/scripts/ui/space_image.py | 2 +- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index 62281695177..b8b46b257df 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -10,6 +10,20 @@ def active_node_mat(mat): return mat return None + +def context_tex_datablock(context): + + idblock = active_node_mat(context.material) + if idblock: return idblock + + idblock = context.lamp + if idblock: return idblock + + idblock = context.world + if idblock: return idblock + + idblock = context.brush + return idblock class TextureButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' @@ -28,19 +42,11 @@ class TEXTURE_PT_preview(TextureButtonsPanel): tex = context.texture slot = context.texture_slot - ma = active_node_mat(context.material) - la = context.lamp - wo = context.world - br = context.brush - - if ma: - layout.template_preview(tex, parent=ma, slot=slot) - elif la: - layout.template_preview(tex, parent=la, slot=slot) - elif wo: - layout.template_preview(tex, parent=wo, slot=slot) - elif br: - layout.template_preview(tex, parent=br, slot=slot) + + idblock = context_tex_datablock(context) + + if idblock: + layout.template_preview(tex, parent=idblock, slot=slot) else: layout.template_preview(tex, slot=slot) @@ -54,22 +60,19 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): layout = self.layout tex = context.texture - - id = active_node_mat(context.material) - if not id: id = context.lamp - if not id: id = context.world - if not id: id = context.brush + + idblock = context_tex_datablock(context) space = context.space_data - if id: + if idblock: row = layout.row() - row.template_list(id, "textures", id, "active_texture_index", rows=2) + row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2) split = layout.split(percentage=0.65) - if id: - split.template_ID(id, "active_texture", new="texture.new") + if idblock: + split.template_ID(idblock, "active_texture", new="texture.new") elif tex: split.template_ID(space, "pin_id") @@ -139,14 +142,12 @@ class TEXTURE_PT_mapping(TextureSlotPanel): def draw(self, context): layout = self.layout - ma = active_node_mat(context.material) - la = context.lamp - wo = context.world - br = context.brush + idblock = context_tex_datablock(context) + tex = context.texture_slot textype = context.texture - if not br: + if type(idblock) != bpy.types.Brush: split = layout.split(percentage=0.3) col = split.column() col.itemL(text="Coordinates:") @@ -170,7 +171,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel): split.itemL(text="Object:") split.itemR(tex, "object", text="") - if ma: + if type(idblock) == bpy.types.Material: split = layout.split(percentage=0.3) split.itemL(text="Projection:") split.itemR(tex, "mapping", text="") @@ -191,7 +192,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel): row.itemR(tex, "y_mapping", text="") row.itemR(tex, "z_mapping", text="") - if br: + elif type(idblock) == bpy.types.Brush: layout.itemR(tex, "map_mode", expand=True) row = layout.row() @@ -212,10 +213,8 @@ class TEXTURE_PT_influence(TextureSlotPanel): def draw(self, context): layout = self.layout - ma = active_node_mat(context.material) - la = context.lamp - wo = context.world - br = context.brush + idblock = context_tex_datablock(context) + textype = context.texture tex = context.texture_slot @@ -226,8 +225,8 @@ class TEXTURE_PT_influence(TextureSlotPanel): sub.active = active sub.itemR(tex, factor, text=name, slider=True) - if ma: - if ma.type in ['SURFACE', 'HALO', 'WIRE']: + if type(idblock) == bpy.types.Material: + if idblock.type in ('SURFACE', 'HALO', 'WIRE'): split = layout.split() col = split.column() @@ -272,11 +271,12 @@ class TEXTURE_PT_influence(TextureSlotPanel): factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color") factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color") - elif la: + elif type(idblock) == bpy.types.Lamp: row = layout.row() factor_but(row, tex.map_color, "map_color", "color_factor", "Color") factor_but(row, tex.map_shadow, "map_shadow", "shadow_factor", "Shadow") - elif wo: + + elif type(idblock) == bpy.types.World: split = layout.split() col = split.column() @@ -301,7 +301,8 @@ class TEXTURE_PT_influence(TextureSlotPanel): col = split.column() col.itemR(tex, "negate", text="Negative") col.itemR(tex, "stencil") - if ma or wo: + + if type(idblock) in (bpy.types.Material, bpy.types.World): col.itemR(tex, "default_value", text="DVar", slider=True) # Texture Type Panels # @@ -775,3 +776,4 @@ bpy.types.register(TEXTURE_PT_pointdensity_turbulence) bpy.types.register(TEXTURE_PT_colors) bpy.types.register(TEXTURE_PT_mapping) bpy.types.register(TEXTURE_PT_influence) + diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py index c1a4fc723ca..93d8043b61f 100644 --- a/release/scripts/ui/space_image.py +++ b/release/scripts/ui/space_image.py @@ -32,7 +32,7 @@ class IMAGE_MT_view(bpy.types.Menu): for a, b in ratios: text = "Zoom %d:%d" % (a, b) - layout.item_floatO("image.view_zoom_ratio", "ratio", a/float(b), text=text) + layout.item_floatO("image.view_zoom_ratio", "ratio", a/b, text=text) layout.itemS() -- cgit v1.2.3 From fbde77ce809111318a8cfb6b25eeaf03511cb0dc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 16:00:39 +0000 Subject: texture slots up/down back --- release/scripts/ui/buttons_texture.py | 4 ++ source/blender/blenkernel/BKE_texture.h | 3 ++ source/blender/blenkernel/intern/texture.c | 49 +++++++++++++++++++++++ source/blender/editors/render/render_intern.h | 3 ++ source/blender/editors/render/render_ops.c | 2 + source/blender/editors/render/render_shading.c | 55 ++++++++++++++++++++++++++ 6 files changed, 116 insertions(+) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index b8b46b257df..a748a7ea155 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -75,6 +75,10 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): split.template_ID(idblock, "active_texture", new="texture.new") elif tex: split.template_ID(space, "pin_id") + + row = split.row(align=True) + row.item_enumO("texture.slot_move", "type", 'UP', text="", icon='ICON_TRIA_UP') + row.item_enumO("texture.slot_move", "type", 'DOWN', text="", icon='ICON_TRIA_DOWN') if (not space.pin_id) and ( context.sculpt_object or diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index c7a6e20cc8b..b9dc5916e69 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -75,6 +75,9 @@ struct Tex *give_current_lamp_texture(struct Lamp *la); struct Tex *give_current_world_texture(struct World *world); struct Tex *give_current_brush_texture(struct Brush *br); +int give_active_mtex(struct ID *id, struct MTex ***mtex_ar, short *act); +void set_active_mtex(struct ID *id, short act); + void set_current_brush_texture(struct Brush *br, struct Tex *tex); void set_current_world_texture(struct World *wo, struct Tex *tex); void set_current_material_texture(struct Material *ma, struct Tex *tex); diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index d1c26b5a1b4..33dfcfca76e 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -889,6 +889,55 @@ Tex *give_current_material_texture(Material *ma) return tex; } +int give_active_mtex(ID *id, MTex ***mtex_ar, short *act) +{ + switch(GS(id->name)) { + case ID_MA: + *mtex_ar= ((Material *)id)->mtex; + if(act) *act= (((Material *)id)->texact); + break; + case ID_WO: + *mtex_ar= ((World *)id)->mtex; + if(act) *act= (((World *)id)->texact); + break; + case ID_LA: + *mtex_ar= ((Lamp *)id)->mtex; + if(act) *act= (((Lamp *)id)->texact); + break; + case ID_BR: + *mtex_ar= ((Brush *)id)->mtex; + if(act) *act= (((Brush *)id)->texact); + break; + default: + *mtex_ar = NULL; + if(act) *act= 0; + return FALSE; + } + + return TRUE; +} + +void set_active_mtex(ID *id, short act) +{ + if(act<0) act= 0; + else if(act>=MAX_MTEX) act= MAX_MTEX-1; + + switch(GS(id->name)) { + case ID_MA: + ((Material *)id)->texact= act; + break; + case ID_WO: + ((World *)id)->texact= act; + break; + case ID_LA: + ((Lamp *)id)->texact= act; + break; + case ID_BR: + ((Brush *)id)->texact= act; + break; + } +} + void set_current_material_texture(Material *ma, Tex *newtex) { Tex *tex= NULL; diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index d3ecbbc56e8..7b4c0194c5d 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -46,5 +46,8 @@ void WORLD_OT_new(struct wmOperatorType *ot); void SCENE_OT_render_layer_add(struct wmOperatorType *ot); void SCENE_OT_render_layer_remove(struct wmOperatorType *ot); +void TEXTURE_OT_slot_move(struct wmOperatorType *ot); + + #endif /* RENDER_INTERN_H */ diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index 7d35dff7493..8c0c1b18fca 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -51,5 +51,7 @@ void ED_operatortypes_render(void) WM_operatortype_append(SCENE_OT_render_layer_add); WM_operatortype_append(SCENE_OT_render_layer_remove); + + WM_operatortype_append(TEXTURE_OT_slot_move); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 26df0df935b..4a2c88f54a7 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -681,3 +681,58 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int texture_slot_move(bContext *C, wmOperator *op) +{ + ID *id= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; + + if(id) { + MTex **mtex_ar, *mtexswap; + short act; + int type= RNA_enum_get(op->ptr, "type"); + + give_active_mtex(id, &mtex_ar, &act); + + if(type == -1) { /* Up */ + if(act > 0) { + mtexswap = mtex_ar[act]; + mtex_ar[act] = mtex_ar[act-1]; + mtex_ar[act-1] = mtexswap; + set_active_mtex(id, act-1); + } + } + else { /* Down */ + if(act < MAX_MTEX-1) { + mtexswap = mtex_ar[act]; + mtex_ar[act] = mtex_ar[act+1]; + mtex_ar[act+1] = mtexswap; + set_active_mtex(id, act+1); + } + } + + WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C)); + } + + return OPERATOR_FINISHED; +} + +void TEXTURE_OT_slot_move(wmOperatorType *ot) +{ + static EnumPropertyItem slot_move[] = { + {-1, "UP", 0, "Up", ""}, + {1, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Move Texture Slot"; + ot->idname= "TEXTURE_OT_slot_move"; + ot->description="Move texture slots up and down."; + + /* api callbacks */ + ot->exec= texture_slot_move; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", ""); +} -- cgit v1.2.3 From 9cefe50e1f11fc6cf5b9c71cc25c18cd5c3f735d Mon Sep 17 00:00:00 2001 From: William Reynish Date: Mon, 12 Oct 2009 16:34:55 +0000 Subject: *Added ability to enable GLSL display in the 3D Views View panel (n key). *Commented out the Quad View options since they don't work yet. --- release/scripts/ui/space_view3d.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 3d91f73d209..832ec0c5999 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1125,6 +1125,7 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel): def draw(self, context): layout = self.layout view = context.space_data + gs = context.scene.game_data col = layout.column() col.itemR(view, "display_floor", text="Grid Floor") @@ -1134,16 +1135,21 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel): col.itemR(view, "outline_selected") col.itemR(view, "all_object_centers") col.itemR(view, "relationship_lines") - col.itemR(view, "textured_solid") - - layout.itemS() - - layout.itemO("screen.region_foursplit", text="Toggle Quad View") col = layout.column() - col.itemR(view, "lock_rotation") - col.itemR(view, "box_preview") - col.itemR(view, "box_clip") + col.itemL(text="Shading:") + col.itemR(gs, "material_mode", text="") + col.itemR(view, "textured_solid") + + +# XXX - the Quad View options don't work yet +# layout.itemS() +# +# layout.itemO("screen.region_foursplit", text="Toggle Quad View") +# col = layout.column() +# col.itemR(view, "lock_rotation") +# col.itemR(view, "box_preview") +# col.itemR(view, "box_clip") class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel): __space_type__ = 'VIEW_3D' -- cgit v1.2.3 From 9c7fe13a575d73e21883164e06e8ff179aa2e907 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Mon, 12 Oct 2009 16:51:36 +0000 Subject: Cocoa : fix secondary window display bug issue --- intern/ghost/intern/GHOST_WindowCocoa.h | 3 +++ intern/ghost/intern/GHOST_WindowCocoa.mm | 30 ++++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index bc0dd9db13d..d6c154535a9 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -275,6 +275,9 @@ protected: /** The mother SystemCocoa class to send events */ GHOST_SystemCocoa *m_systemCocoa; + /** The first created OpenGL context (for sharing display lists) */ + static NSOpenGLContext *s_firstOpenGLcontext; + NSCursor* m_customCursor; GHOST_TabletData m_tablet; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 95c5207b986..fd68b6200ee 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -149,6 +149,8 @@ static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = #pragma mark initialization / finalization +NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil; + GHOST_WindowCocoa::GHOST_WindowCocoa( GHOST_SystemCocoa *systemCocoa, const STR_String& title, @@ -197,7 +199,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( [pixelFormat release]; - m_openGLContext = [m_openGLView openGLContext]; + m_openGLContext = [m_openGLView openGLContext]; //This context will be replaced by the proper one just after [m_window setContentView:m_openGLView]; [m_window setInitialFirstResponder:m_openGLView]; @@ -229,9 +231,6 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() { if (m_customCursor) delete m_customCursor; - /*if(ugly_hack==m_windowRef) ugly_hack= NULL; - - if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);*/ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [m_openGLView release]; @@ -670,12 +669,15 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp case GHOST_kDrawingContextTypeOpenGL: if (!getValid()) break; - pixelFormat = [m_openGLView pixelFormat]; - tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat - shareContext:m_openGLContext]; - if (tmpOpenGLContext == nil) - success = GHOST_kFailure; - break; + pixelFormat = [m_openGLView pixelFormat]; + tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat + shareContext:s_firstOpenGLcontext]; + if (tmpOpenGLContext == nil) { + success = GHOST_kFailure; + break; + } + + if (!s_firstOpenGLcontext) s_firstOpenGLcontext = tmpOpenGLContext; #ifdef WAIT_FOR_VSYNC /* wait for vsync, to avoid tearing artifacts */ [tmpOpenGLContext setValues:1 forParameter:NSOpenGLCPSwapInterval]; @@ -683,7 +685,6 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp [m_openGLView setOpenGLContext:tmpOpenGLContext]; [tmpOpenGLContext setView:m_openGLView]; - [m_openGLContext release]; m_openGLContext = tmpOpenGLContext; break; @@ -704,7 +705,12 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; switch (m_drawingContextType) { case GHOST_kDrawingContextTypeOpenGL: - [m_openGLView clearGLContext]; + if (m_openGLContext) + { + [m_openGLView clearGLContext]; + if (s_firstOpenGLcontext == m_openGLContext) s_firstOpenGLcontext = nil; + m_openGLContext = nil; + } [pool drain]; return GHOST_kSuccess; case GHOST_kDrawingContextTypeNone: -- cgit v1.2.3 From 6b03b4285c005287f694aee75f85e9175fe44157 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Mon, 12 Oct 2009 17:00:38 +0000 Subject: *Moved the texture reordering buttons to the side *Use same icons for reordering in constraints, modifiers. --- release/scripts/ui/buttons_texture.py | 10 ++++++---- source/blender/editors/interface/interface_templates.c | 12 ++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index a748a7ea155..5efdaf77839 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -67,18 +67,20 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): if idblock: row = layout.row() + row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2) + col = row.column(align=True) + col.item_enumO("texture.slot_move", "type", 'UP', text="", icon='ICON_TRIA_UP') + col.item_enumO("texture.slot_move", "type", 'DOWN', text="", icon='ICON_TRIA_DOWN') + + split = layout.split(percentage=0.65) if idblock: split.template_ID(idblock, "active_texture", new="texture.new") elif tex: split.template_ID(space, "pin_id") - - row = split.row(align=True) - row.item_enumO("texture.slot_move", "type", 'UP', text="", icon='ICON_TRIA_UP') - row.item_enumO("texture.slot_move", "type", 'DOWN', text="", icon='ICON_TRIA_DOWN') if (not space.pin_id) and ( context.sculpt_object or diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 7f768a42956..c092b1ca68b 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -560,14 +560,14 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i if(!isVirtual) { /* XXX uiBlockSetCol(block, TH_BUT_ACTION); */ uiBlockBeginAlign(block); - uiItemO(row, "", VICON_MOVE_UP, "OBJECT_OT_modifier_move_up"); - uiItemO(row, "", VICON_MOVE_DOWN, "OBJECT_OT_modifier_move_down"); + uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_modifier_move_up"); + uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_modifier_move_down"); uiBlockEndAlign(block); uiBlockSetEmboss(block, UI_EMBOSSN); if(modifier_can_delete(md)) - uiItemO(row, "", VICON_X, "OBJECT_OT_modifier_remove"); + uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove"); /* XXX uiBlockSetCol(block, TH_AUTO); */ } @@ -923,10 +923,10 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con) uiBlockSetEmboss(block, UI_EMBOSS); if (show_upbut) - uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_up", WM_OP_INVOKE_DEFAULT, VICON_MOVE_UP, xco+width-50, yco, 16, 18, "Move constraint up in constraint stack"); + uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_up", WM_OP_INVOKE_DEFAULT, ICON_TRIA_UP, xco+width-50, yco, 16, 18, "Move constraint up in constraint stack"); if (show_downbut) - uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_down", WM_OP_INVOKE_DEFAULT, VICON_MOVE_DOWN, xco+width-50+18, yco, 16, 18, "Move constraint down in constraint stack"); + uiDefIconButO(block, BUT, "CONSTRAINT_OT_move_down", WM_OP_INVOKE_DEFAULT, ICON_TRIA_DOWN, xco+width-50+18, yco, 16, 18, "Move constraint down in constraint stack"); uiBlockEndAlign(block); } @@ -1184,7 +1184,7 @@ uiLayout *uiTemplateGroup(uiLayout *layout, Object *ob, Group *group) xco = 290; if(group->id.lib==0) { /* cant remove objects from linked groups */ - but = uiDefIconBut(block, BUT, B_NOP, VICON_X, xco, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership"); + but = uiDefIconBut(block, BUT, B_NOP, ICON_X, xco, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership"); uiButSetFunc(but, group_ob_rem, group, ob); } } -- cgit v1.2.3 From d2551d1bb1475e17ae4322f2e1088903add856f0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Oct 2009 17:16:44 +0000 Subject: Bugfix: crash in assigning automatic vertex weights from armature. --- source/blender/editors/object/object_vgroup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 2b17a6cbe54..902a32bb7f3 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -405,20 +405,23 @@ static float get_vert_def_nr(Object *ob, int def_nr, int vertnum) eve= BLI_findlink(&me->edit_mesh->verts, vertnum); if(!eve) return 0.0f; dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); + vertnum= 0; } else - dvert = me->dvert + vertnum; + dvert = me->dvert; } else if(ob->type==OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); if(lt->dvert) - dvert = lt->dvert + vertnum; + dvert = lt->dvert; } if(dvert==NULL) return 0.0f; + dvert += vertnum; + for(i=dvert->totweight-1 ; i>=0 ; i--) if(dvert->dw[i].def_nr == def_nr) return dvert->dw[i].weight; -- cgit v1.2.3 From 0696cf23e5561a2ac65cf5af8881748cc45b8da4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Oct 2009 19:19:29 +0000 Subject: Fix #19631: soft size setting for lamps was not RNA wrapped correct. --- 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 88d9a496840..4ad1f942b33 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -480,7 +480,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) RNA_def_property_update(prop, 0, "rna_Lamp_update"); prop= RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "soft"); + RNA_def_property_float_sdna(prop, NULL, "area_size"); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows)."); RNA_def_property_update(prop, 0, "rna_Lamp_update"); -- cgit v1.2.3 From b5f820cd874a7b3ca1de81103b99969429adfd6c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 19:34:58 +0000 Subject: added rna api MVert,MFace & MEdge index properties eg. for v in me.verts: print(v.index) added calc_edges as an option eg. mesh.update(calc_edges=True) This is needed when adding faces to an existing mesh which create new edges. --- source/blender/editors/include/ED_mesh.h | 2 +- source/blender/editors/mesh/mesh_data.c | 4 +-- source/blender/makesrna/intern/rna_mesh.c | 36 +++++++++++++++++++++++++++ source/blender/makesrna/intern/rna_mesh_api.c | 1 + source/blender/python/intern/bpy_interface.c | 3 +++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 3bceeb9340e..144d29a4405 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -195,7 +195,7 @@ void ED_mesh_geometry_add(struct Mesh *mesh, struct ReportList *reports, int ver void ED_mesh_transform(struct Mesh *me, float *mat); void ED_mesh_calc_normals(struct Mesh *me); void ED_mesh_material_add(struct Mesh *me, struct Material *ma); -void ED_mesh_update(struct Mesh *mesh, struct bContext *C); +void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges); int ED_mesh_uv_texture_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me); int ED_mesh_uv_texture_remove(struct bContext *C, struct Object *ob, struct Mesh *me); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 43e1dd417a6..6ed2ca08c9c 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -504,9 +504,9 @@ static void mesh_calc_edges(Mesh *mesh) BLI_edgehash_free(eh, NULL); } -void ED_mesh_update(Mesh *mesh, bContext *C) +void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges) { - if(mesh->totface && mesh->totedge == 0) + if(calc_edges || (mesh->totface && mesh->totedge == 0)) mesh_calc_edges(mesh); mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 84a1940de9d..8b67ccecc3d 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -732,6 +732,27 @@ static void rna_MeshFace_verts_set(PointerRNA *ptr, const int *values) memcpy(&face->v1, values, (face->v4 ? 4 : 3) * sizeof(int)); } +static int rna_MeshVertex_index_get(PointerRNA *ptr) +{ + Mesh *me= (Mesh*)ptr->id.data; + MVert *vert= (MVert*)ptr->data; + return (int)(vert - me->mvert); +} + +static int rna_MeshEdge_index_get(PointerRNA *ptr) +{ + Mesh *me= (Mesh*)ptr->id.data; + MEdge *edge= (MEdge*)ptr->data; + return (int)(edge - me->medge); +} + +static int rna_MeshFace_index_get(PointerRNA *ptr) +{ + Mesh *me= (Mesh*)ptr->id.data; + MFace *face= (MFace*)ptr->data; + return (int)(face - me->mface); +} + /* path construction */ static char *rna_VertexGroupElement_path(PointerRNA *ptr) @@ -905,6 +926,11 @@ static void rna_def_mvert(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, "rna_MeshVertex_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0, 0, 0); RNA_def_property_struct_type(prop, "VertexGroupElement"); RNA_def_property_ui_text(prop, "Groups", "Weights for the vertex groups this vertex is member of."); + + prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_int_funcs(prop, "rna_MeshVertex_index_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Index", "Index number of the vertex."); } static void rna_def_medge(BlenderRNA *brna) @@ -963,6 +989,11 @@ static void rna_def_medge(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FGON); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Fgon", "Fgon edge"); + + prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_int_funcs(prop, "rna_MeshEdge_index_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Index", "Index number of the vertex."); } static void rna_def_mface(BlenderRNA *brna) @@ -1017,6 +1048,11 @@ static void rna_def_mface(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_funcs(prop, "rna_MeshFace_normal_get", NULL, NULL); RNA_def_property_ui_text(prop, "face normal", "local space unit length normal vector for this face"); + + prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_int_funcs(prop, "rna_MeshFace_index_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Index", "Index number of the vertex."); } static void rna_def_mtface(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 3da0e1e6fd4..52ff98f66f0 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -72,6 +72,7 @@ void RNA_api_mesh(StructRNA *srna) RNA_def_function_ui_description(func, "Calculate vertex normals."); func= RNA_def_function(srna, "update", "ED_mesh_update"); + RNA_def_boolean(func, "calc_edges", 0, "Calculate Edges", "Force recalculation of edges."); RNA_def_function_flag(func, FUNC_USE_CONTEXT); func= RNA_def_function(srna, "add_material", "ED_mesh_material_add"); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index d0829acd6cc..9e76c1d03aa 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -241,6 +241,9 @@ static PyObject *CreateGlobalDictionary( bContext *C ) {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""}, {NULL, NULL, 0, NULL} }; -- cgit v1.2.3 From 10198e99ff398380696e3408f752280e6bb5106d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Oct 2009 19:41:40 +0000 Subject: Deep Shadow Buffer Since the deep shadow buffer summer of code project is not actively under development anymore, I decided to build my own DSM implementation from scratch, based on reusing as much existing shadow buffer code as possible. It's not very advanced, but implements the basic algorithm. Just enough so we can do shading tests with it, optimizations and other improvements can be done later. Supported: * Classical shadow buffer options: filter, soft, bias, .. * Multiple sample buffers, merged into one. * Halfway trick to support lower bias. * Compression with user defined threshold. * Non-textured alpha transparency, using Casting Alpha value. * Strand render. Not Supported: * Tiling disk cache, so can use a lot of memory. * Per part rendering for lower memory usage during creation. * Colored shadow. * Textured color/alpha shadow. * Mipmaps for faster filtering. * Volume shadows. Usage Hints: * Use sample buffers + smaller size rather than large size. * For example 512 size x 9 sample buffers instead of 2048 x 1. * Compression threshold 0.05 works, but is on the conservative side. --- release/scripts/ui/buttons_data_lamp.py | 4 +- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/object.c | 1 + source/blender/blenloader/intern/readfile.c | 6 +- source/blender/makesdna/DNA_lamp_types.h | 3 +- source/blender/makesrna/intern/rna_lamp.c | 7 + source/blender/makesrna/intern/rna_material.c | 2 +- .../blender/render/intern/include/render_types.h | 11 +- source/blender/render/intern/include/zbuf.h | 7 +- .../blender/render/intern/source/convertblender.c | 4 +- source/blender/render/intern/source/rendercore.c | 2 +- source/blender/render/intern/source/shadbuf.c | 488 +++++++++++++++++++-- source/blender/render/intern/source/shadeinput.c | 13 +- source/blender/render/intern/source/strand.c | 71 +-- source/blender/render/intern/source/zbuf.c | 166 ++++--- 15 files changed, 650 insertions(+), 137 deletions(-) diff --git a/release/scripts/ui/buttons_data_lamp.py b/release/scripts/ui/buttons_data_lamp.py index 2879da8d8d5..4e495d158eb 100644 --- a/release/scripts/ui/buttons_data_lamp.py +++ b/release/scripts/ui/buttons_data_lamp.py @@ -202,7 +202,7 @@ class DATA_PT_shadow(DataButtonsPanel): col.itemL(text="Buffer Type:") col.row().itemR(lamp, "shadow_buffer_type", expand=True) - if lamp.shadow_buffer_type in ('REGULAR', 'HALFWAY'): + if lamp.shadow_buffer_type in ('REGULAR', 'HALFWAY', 'DEEP'): split = layout.split() col = split.column() @@ -218,6 +218,8 @@ class DATA_PT_shadow(DataButtonsPanel): sub = col.column(align=True) sub.itemR(lamp, "shadow_buffer_size", text="Size") sub.itemR(lamp, "shadow_buffer_samples", text="Samples") + if lamp.shadow_buffer_type == 'DEEP': + col.itemR(lamp, "compression_threshold") elif lamp.shadow_buffer_type == 'IRREGULAR': layout.itemR(lamp, "shadow_buffer_bias", text="Bias") diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index a79bf43c354..e91e434b97d 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 5 +#define BLENDER_SUBVERSION 6 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 64e22c85251..8494fdae954 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -772,6 +772,7 @@ void *add_lamp(char *name) la->samp= 3; la->bias= 1.0f; la->soft= 3.0f; + la->compressthresh= 0.05f; la->ray_samp= la->ray_sampy= la->ray_sampz= 1; la->area_size=la->area_sizey=la->area_sizez= 1.0f; la->buffers= 1; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ad51892a94f..0004187b1c6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9920,8 +9920,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } /* put 2.50 compatibility code here until next subversion bump */ - { + if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 6)) { Object *ob; + Lamp *la; /* New variables for axis-angle rotations and/or quaternion rotations were added, and need proper initialisation */ for (ob= main->object.first; ob; ob= ob->id.next) { @@ -9939,6 +9940,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + + for(la = main->lamp.first; la; la=la->id.next) + la->compressthresh= 0.05f; } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index 78c8d1a5607..0a0046f8470 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -63,7 +63,7 @@ typedef struct Lamp { short pad2; float clipsta, clipend, shadspotsize; - float bias, soft; + float bias, soft, compressthresh, pad5[3]; short bufsize, samp, buffers, filtertype; char bufflag, buftype; @@ -167,6 +167,7 @@ typedef struct Lamp { #define LA_SHADBUF_REGULAR 0 #define LA_SHADBUF_IRREGULAR 1 #define LA_SHADBUF_HALFWAY 2 +#define LA_SHADBUF_DEEP 3 /* bufflag, auto clipping */ #define LA_SHADBUF_AUTO_START 1 diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 4ad1f942b33..a518bd28d24 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -570,6 +570,7 @@ static void rna_def_spot_lamp(BlenderRNA *brna) {LA_SHADBUF_REGULAR , "REGULAR", 0, "Classical", "Classic shadow buffer."}, {LA_SHADBUF_HALFWAY, "HALFWAY", 0, "Classic-Halfway", "Regular buffer, averaging the closest and 2nd closest Z value to reducing bias artifaces."}, {LA_SHADBUF_IRREGULAR, "IRREGULAR", 0, "Irregular", "Irregular buffer produces sharp shadow always, but it doesn't show up for raytracing."}, + {LA_SHADBUF_DEEP, "DEEP", 0, "Deep", "Deep shadow buffer supports transparency and better filtering, at the cost of more memory usage and processing time."}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem prop_shadbuffiltertype_items[] = { @@ -690,6 +691,12 @@ static void rna_def_spot_lamp(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "bufflag", LA_SHADBUF_AUTO_END); RNA_def_property_ui_text(prop, "Autoclip End", "Automatic calculation of clipping-end, based on visible vertices."); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); + + prop= RNA_def_property(srna, "compression_threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "compressthresh"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Compress", "Deep shadow map compression threshold."); + RNA_def_property_update(prop, 0, "rna_Lamp_update"); } static void rna_def_sun_lamp(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index b05cf1afa84..e03e221f822 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1559,7 +1559,7 @@ void RNA_def_material(BlenderRNA *brna) prop= RNA_def_property(srna, "shadow_casting_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "shad_alpha"); RNA_def_property_range(prop, 0.001, 1); - RNA_def_property_ui_text(prop, "Shadow Casting Alpha", "Shadow casting alpha, only in use for Irregular Shadowbuffer."); + RNA_def_property_ui_text(prop, "Shadow Casting Alpha", "Shadow casting alpha, in use for Irregular and Deep shadow buffer."); RNA_def_property_update(prop, 0, "rna_Material_update"); prop= RNA_def_property(srna, "light_group", PROP_POINTER, PROP_NONE); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 8f16d636e79..48bf34d0696 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -245,10 +245,17 @@ struct Render struct ISBData; +typedef struct DeepSample { + int z; + float v; +} DeepSample; + typedef struct ShadSampleBuf { struct ShadSampleBuf *next, *prev; intptr_t *zbuf; char *cbuf; + DeepSample **deepbuf; + int *totbuf; } ShadSampleBuf; typedef struct ShadBuf { @@ -258,7 +265,7 @@ typedef struct ShadBuf { float viewmat[4][4]; float winmat[4][4]; float *jit, *weight; - float d, clipend, pixsize, soft; + float d, clipend, pixsize, soft, compressthresh; int co[3]; int size, bias; ListBase buffers; @@ -527,6 +534,8 @@ typedef struct LampRen { float clipend; /** A small depth offset to prevent self-shadowing. */ float bias; + /* Compression threshold for deep shadow maps */ + float compressthresh; short ray_samp, ray_sampy, ray_sampz, ray_samp_method, ray_samp_type, area_shape, ray_totsamp; short xold[BLENDER_MAX_THREADS], yold[BLENDER_MAX_THREADS]; /* last jitter table for area lights */ diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index b6d0c656f63..a0665daf916 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -37,6 +37,7 @@ struct VlakRen; struct ListBase; struct ZSpan; struct APixstrand; +struct APixstr; struct StrandShadeCache; void fillrect(int *rect, int x, int y, int val); @@ -50,11 +51,12 @@ void projectverto(float *v1, float winmat[][4], float *adr); int testclip(float *v); void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); +void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data); unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist); void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int)); -int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct RenderLayer *rl, struct APixstrand *apixbuf, struct ListBase *apsmbase, struct StrandShadeCache *cache); +int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); typedef struct APixstr { unsigned short mask[4]; /* jitter mask */ @@ -118,6 +120,7 @@ typedef struct ZSpan { /* exported to shadbuf.c */ void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4); void zbuf_free_span(struct ZSpan *zspan); +void freepsA(struct ListBase *lb); /* to rendercore.c */ void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) ); @@ -128,7 +131,7 @@ void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop); void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4); /* exported to shadeinput.c */ -void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4]); +void zbuf_make_winmat(Render *re, float winmat[][4]); void zbuf_render_project(float winmat[][4], float *co, float *ho); #endif diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index af7d7a02bba..072083e58a7 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3402,9 +3402,10 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) shb->bias= shb->bias*(100/re->r.size); /* halfway method (average of first and 2nd z) reduces bias issues */ - if(lar->buftype==LA_SHADBUF_HALFWAY) + if(ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) shb->bias= 0.1f*shb->bias; + shb->compressthresh= lar->compressthresh; } static void area_lamp_vectors(LampRen *lar) @@ -3486,6 +3487,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) lar->clipend = la->clipend; lar->bias = la->bias; + lar->compressthresh = la->compressthresh; lar->type= la->type; lar->mode= la->mode; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index f3db64295a3..6c18592b8d2 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -524,7 +524,7 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, case SCE_PASS_RAYHITS: /* */ - col= &shr->rayhits; + col= shr->rayhits; pixsize= 4; break; } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 48305d31e10..50e0321a6eb 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -49,8 +49,8 @@ #include "render_types.h" #include "renderdatabase.h" #include "rendercore.h" - #include "shadbuf.h" +#include "shading.h" #include "zbuf.h" /* XXX, could be better implemented... this is for endian issues @@ -166,6 +166,326 @@ static void make_jitter_weight_tab(Render *re, ShadBuf *shb, short filtertype) } } +static int verg_deepsample(const void *poin1, const void *poin2) +{ + const DeepSample *ds1= (const DeepSample*)poin1; + const DeepSample *ds2= (const DeepSample*)poin2; + + if(ds1->z < ds2->z) return -1; + else if(ds1->z == ds2->z) return 0; + else return 1; +} + +static int compress_deepsamples(DeepSample *dsample, int tot, float epsilon) +{ + /* uses doubles to avoid overflows and other numerical issues, + could be improved */ + DeepSample *ds, *newds; + float v; + double slope, slopemin, slopemax, min, max, div, newmin, newmax; + int a, first, z, newtot= 0; + + /*if(print) { + for(a=0, ds=dsample; az/(double)0x7FFFFFFF, ds->v); + printf("\n"); + }*/ + + /* read from and write into same array */ + ds= dsample; + newds= dsample; + a= 0; + + /* as long as we are not at the end of the array */ + for(a++, ds++; az - newds->z; + if(ds->z == newds->z) { + /* still in same z position, simply check + visibility difference against epsilon */ + if(!(fabs(newds->v - ds->v) <= epsilon)) { + break; + } + } + else { + /* compute slopes */ + div= (double)0x7FFFFFFF/((double)ds->z - (double)newds->z); + min= ((ds->v - epsilon) - newds->v)*div; + max= ((ds->v + epsilon) - newds->v)*div; + + /* adapt existing slopes */ + if(first) { + newmin= min; + newmax= max; + first= 0; + } + else { + newmin= MAX2(slopemin, min); + newmax= MIN2(slopemax, max); + + /* verify if there is still space between the slopes */ + if(newmin > newmax) { + ds--; + a--; + break; + } + } + + slopemin= newmin; + slopemax= newmax; + } + } + + if(a == tot) { + ds--; + a--; + } + + /* always previous z */ + z= ds->z; + + if(first || a==tot-1) { + /* if slopes were not initialized, use last visibility */ + v= ds->v; + } + else { + /* compute visibility at center between slopes at z */ + slope= (slopemin+slopemax)*0.5; + v= newds->v + slope*((z - newds->z)/(double)0x7FFFFFFF); + } + + newds++; + newtot++; + + newds->z= z; + newds->v= v; + } + + if(newtot == 0 || (newds->v != (newds-1)->v)) + newtot++; + + /*if(print) { + for(a=0, ds=dsample; az/(double)0x7FFFFFFF, ds->v); + printf("\n"); + }*/ + + return newtot; +} + +static float deep_alpha(Render *re, int obinr, int facenr, int strand) +{ + ObjectInstanceRen *obi= &re->objectinstance[obinr]; + Material *ma; + + if(strand) { + StrandRen *strand= RE_findOrAddStrand(obi->obr, facenr-1); + ma= strand->buffer->ma; + } + else { + VlakRen *vlr= RE_findOrAddVlak(obi->obr, (facenr-1) & RE_QUAD_MASK); + ma= vlr->mat; + } + + return ma->shad_alpha; +} + +static void compress_deepshadowbuf(Render *re, ShadBuf *shb, APixstr *apixbuf, APixstrand *apixbufstrand) +{ + ShadSampleBuf *shsample; + DeepSample *ds[RE_MAX_OSA], *sampleds[RE_MAX_OSA], *dsb, *newbuf; + APixstr *ap, *apn; + APixstrand *aps, *apns; + float visibility, totbuf= shb->totbuf; + int a, b, c, tot, minz, found, size= shb->size, prevtot, newtot; + int sampletot[RE_MAX_OSA], totsample = 0, totsamplec = 0; + + shsample= MEM_callocN( sizeof(ShadSampleBuf), "shad sample buf"); + BLI_addtail(&shb->buffers, shsample); + + shsample->totbuf= MEM_callocN(sizeof(int)*size*size, "deeptotbuf"); + shsample->deepbuf= MEM_callocN(sizeof(DeepSample*)*size*size, "deepbuf"); + + ap= apixbuf; + aps= apixbufstrand; + for(a=0; anext) + for(b=0; b<4; b++) + if(apn->p[b]) + for(c=0; cmask[b] & (1<next) + for(b=0; b<4; b++) + if(apns->p[b]) + for(c=0; cmask[b] & (1<deepbuf[a]= NULL; + shsample->totbuf[a]= 0; + continue; + } + + /* fill samples */ + ds[0]= sampleds[0]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample"); + for(c=1; cnext) { + for(b=0; b<4; b++) { + if(apn->p[b]) { + for(c=0; cmask[b] & (1<z= apn->z[b]; + ds[c]->v= 1.0f; /* not used */ + ds[c]++; + ds[c]->z= apn->z[b]; + ds[c]->v= deep_alpha(re, apn->obi[b], apn->p[b], 0); + ds[c]++; + } + } + } + } + } + + if(apixbufstrand) { + for(apns=aps; apns; apns=apns->next) { + for(b=0; b<4; b++) { + if(apns->p[b]) { + for(c=0; cmask[b] & (1<z= apns->z[b]; + ds[c]->v= 1.0f; /* not used */ + ds[c]++; + ds[c]->z= apns->z[b]; + ds[c]->v= deep_alpha(re, apns->obi[b], apns->p[b], 1); + ds[c]++; + } + } + } + } + } + } + + for(c=0; cv= visibility; + ds[c]++; + + visibility *= 1.0f-ds[c]->v; + ds[c]->v= visibility; + ds[c]++; + } + + /* halfway trick, probably won't work well for volumes? */ + ds[c]= sampleds[c]; + for(b=0; bz= (ds[c]->z>>1) + ((ds[c]+2)->z>>1); + ds[c]++; + ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1); + ds[c]++; + } + else { + ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1); + ds[c]++; + ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1); + ds[c]++; + } + } + + /* init for merge loop */ + ds[c]= sampleds[c]; + sampletot[c] *= 2; + } + + shsample->deepbuf[a]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample"); + shsample->totbuf[a]= 0; + + /* merge buffers */ + dsb= shsample->deepbuf[a]; + while(1) { + minz= 0; + found= 0; + + for(c=0; cz < minz)) { + minz= ds[c]->z; + found= 1; + } + } + + if(!found) + break; + + dsb->z= minz; + dsb->v= 0.0f; + + visibility= 0.0f; + for(c=0; cz == minz) { + ds[c]++; + sampletot[c]--; + } + + if(sampleds[c] == ds[c]) + visibility += 1.0f/totbuf; + else + visibility += (ds[c]-1)->v/totbuf; + } + + dsb->v= visibility; + dsb++; + shsample->totbuf[a]++; + } + + prevtot= shsample->totbuf[a]; + totsample += prevtot; + + newtot= compress_deepsamples(shsample->deepbuf[a], prevtot, shb->compressthresh); + shsample->totbuf[a]= newtot; + totsamplec += newtot; + + if(newtot < prevtot) { + newbuf= MEM_mallocN(sizeof(DeepSample)*newtot, "cdeepsample"); + memcpy(newbuf, shsample->deepbuf[a], sizeof(DeepSample)*newtot); + MEM_freeN(shsample->deepbuf[a]); + shsample->deepbuf[a]= newbuf; + } + + MEM_freeN(sampleds[0]); + } + + //printf("%d -> %d, ratio %f\n", totsample, totsamplec, (float)totsamplec/(float)totsample); +} + /* create Z tiles (for compression): this system is 24 bits!!! */ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square) { @@ -176,7 +496,7 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square) int a, x, y, minx, miny, byt1, byt2; char *rc, *rcline, *ctile, *zt; - shsample= MEM_mallocN( sizeof(ShadSampleBuf), "shad sample buf"); + shsample= MEM_callocN( sizeof(ShadSampleBuf), "shad sample buf"); BLI_addtail(&shb->buffers, shsample); shsample->zbuf= MEM_mallocN( sizeof(uintptr_t)*(size*size)/256, "initshadbuf2"); @@ -277,7 +597,6 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square) } MEM_freeN(rcline); - } /* sets start/end clipping. lar->shb should be initialized */ @@ -381,11 +700,54 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) } } +static void makeflatshadowbuf(Render *re, LampRen *lar, float *jitbuf) +{ + ShadBuf *shb= lar->shb; + int *rectz, samples; + + /* zbuffering */ + rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf"); + + for(samples=0; samplestotbuf; samples++) { + zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]); + /* create Z tiles (for compression): this system is 24 bits!!! */ + compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE); + + if(re->test_break(re->tbh)) + break; + } + + MEM_freeN(rectz); +} + +static void makedeepshadowbuf(Render *re, LampRen *lar, float *jitbuf) +{ + ShadBuf *shb= lar->shb; + APixstr *apixbuf; + APixstrand *apixbufstrand= NULL; + ListBase apsmbase= {NULL, NULL}; + + /* zbuffering */ + apixbuf= MEM_callocN(sizeof(APixstr)*shb->size*shb->size, "APixbuf"); + if(re->totstrand) + apixbufstrand= MEM_callocN(sizeof(APixstrand)*shb->size*shb->size, "APixbufstrand"); + + zbuffer_abuf_shadow(re, lar, shb->persmat, apixbuf, apixbufstrand, &apsmbase, shb->size, + shb->totbuf, (float(*)[2])jitbuf); + + /* create Z tiles (for compression): this system is 24 bits!!! */ + compress_deepshadowbuf(re, shb, apixbuf, apixbufstrand); + + MEM_freeN(apixbuf); + if(apixbufstrand) + MEM_freeN(apixbufstrand); + freepsA(&apsmbase); +} + void makeshadowbuf(Render *re, LampRen *lar) { ShadBuf *shb= lar->shb; float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp; - int *rectz, samples; if(lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END)) shadowbuf_autoclip(re, lar); @@ -405,31 +767,26 @@ void makeshadowbuf(Render *re, LampRen *lar) i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat); Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat); - if(ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) { + if(ELEM3(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) { + shb->totbuf= lar->buffers; + /* jitter, weights - not threadsafe! */ BLI_lock_thread(LOCK_CUSTOM1); shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp)); make_jitter_weight_tab(re, shb, lar->filtertype); BLI_unlock_thread(LOCK_CUSTOM1); - shb->totbuf= lar->buffers; if(shb->totbuf==4) jitbuf= give_jitter_tab(2); else if(shb->totbuf==9) jitbuf= give_jitter_tab(3); else jitbuf= twozero; /* zbuffering */ - rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf"); - - for(samples=0; samplestotbuf; samples++) { - zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]); - /* create Z tiles (for compression): this system is 24 bits!!! */ - compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE); - - if(re->test_break(re->tbh)) - break; + if(lar->buftype == LA_SHADBUF_DEEP) { + makedeepshadowbuf(re, lar, jitbuf); + shb->totbuf= 1; } - - MEM_freeN(rectz); + else + makeflatshadowbuf(re, lar, jitbuf); /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */ } @@ -539,17 +896,27 @@ void freeshadowbuf(LampRen *lar) ShadSampleBuf *shsample; int b, v; - v= (shb->size*shb->size)/256; - for(shsample= shb->buffers.first; shsample; shsample= shsample->next) { - intptr_t *ztile= shsample->zbuf; - char *ctile= shsample->cbuf; - - for(b=0; bzbuf); - MEM_freeN(shsample->cbuf); + if(shsample->deepbuf) { + v= shb->size*shb->size; + for(b=0; bdeepbuf[b]) + MEM_freeN(shsample->deepbuf[b]); + + MEM_freeN(shsample->deepbuf); + MEM_freeN(shsample->totbuf); + } + else { + intptr_t *ztile= shsample->zbuf; + char *ctile= shsample->cbuf; + + v= (shb->size*shb->size)/256; + for(b=0; bzbuf); + MEM_freeN(shsample->cbuf); + } } BLI_freelistN(&shb->buffers); @@ -567,6 +934,9 @@ static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int int ofs; char *ct; + if(shsample->deepbuf) + return 0; + /* always test borders of shadowbuffer */ if(xs<0) xs= 0; else if(xs>=shb->size) xs= shb->size-1; if(ys<0) ys= 0; else if(ys>=shb->size) ys= shb->size-1; @@ -587,6 +957,67 @@ static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int return 0; } +static float readdeepvisibility(DeepSample *dsample, int tot, int z, int bias, float *biast) +{ + DeepSample *ds, *prevds; + float t; + int a; + + /* tricky stuff here; we use ints which can overflow easily with bias values */ + + ds= dsample; + for(a=0; a ds->z); a++, ds++) + ; + + if(a == tot) { + if(biast) + *biast= 0.0f; + return (ds-1)->v; /* completely behind all samples */ + } + + /* check if this read needs bias blending */ + if(biast) { + if(z > ds->z) + *biast= (float)(z - ds->z)/(float)bias; + else + *biast= 0.0f; + } + + if(a == 0) + return 1.0f; /* completely in front of all samples */ + + prevds= ds-1; + t= (float)(z-bias - prevds->z)/(float)(ds->z - prevds->z); + return t*ds->v + (1.0f-t)*prevds->v; +} + +static float readdeepshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs) +{ + float v, biasv, biast; + int ofs, tot; + + if(zs < - 0x7FFFFE00 + bias) + return 1.0; /* extreme close to clipstart */ + + /* calc z */ + ofs= ys*shb->size + xs; + tot= shsample->totbuf[ofs]; + if(tot == 0) + return 1.0f; + + v= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, bias, &biast); + + if(biast != 0.0f) { + /* in soft bias area */ + biasv= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, 0); + + biast= biast*biast; + return (1.0f-biast)*v + biast*biasv; + } + + return v; +} + /* return 1.0 : fully in light */ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs) { @@ -603,6 +1034,9 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int if(xs<0) xs= 0; else if(xs>=shb->size) xs= shb->size-1; if(ys<0) ys= 0; else if(ys>=shb->size) ys= shb->size-1; + if(shsample->deepbuf) + return readdeepshadowbuf(shb, shsample, bias, xs, ys, zs); + /* calc z */ ofs= (ys>>4)*(shb->size>>4) + (xs>>4); ct= shsample->cbuf+ofs; diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 30ff213b95b..79ee6c89460 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -1232,7 +1232,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) s3= RE_vertren_get_sticky(obr, v3, 0); if(s1 && s2 && s3) { - float winmat[4][4], ho1[4], ho2[4], ho3[4]; + float obwinmat[4][4], winmat[4][4], ho1[4], ho2[4], ho3[4]; float Zmulx, Zmuly; float hox, hoy, l, dl, u, v; float s00, s01, s10, s11, detsh; @@ -1240,14 +1240,15 @@ void shade_input_set_shade_texco(ShadeInput *shi) /* old globals, localized now */ Zmulx= ((float)R.winx)/2.0f; Zmuly= ((float)R.winy)/2.0f; + zbuf_make_winmat(&R, winmat); if(shi->obi->flag & R_TRANSFORMED) - zbuf_make_winmat(&R, shi->obi->mat, winmat); + Mat4MulMat4(obwinmat, obi->mat, winmat); else - zbuf_make_winmat(&R, NULL, winmat); + Mat4CpyMat4(obwinmat, winmat); - zbuf_render_project(winmat, v1->co, ho1); - zbuf_render_project(winmat, v2->co, ho2); - zbuf_render_project(winmat, v3->co, ho3); + zbuf_render_project(obwinmat, v1->co, ho1); + zbuf_render_project(obwinmat, v2->co, ho2); + zbuf_render_project(obwinmat, v3->co, ho3); s00= ho3[0]/ho3[3] - ho1[0]/ho1[3]; s01= ho3[1]/ho3[3] - ho1[1]/ho1[3]; diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index d00076a80e8..61080c7d807 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -417,6 +417,8 @@ typedef struct StrandPart { intptr_t *rectdaps; int rectx, recty; int sample; + int shadow; + float (*jit)[2]; StrandSegment *segment; float t[3], s[3]; @@ -525,7 +527,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float } } else { - bufferz= spart->rectz[offset]; + bufferz= (spart->rectz)? spart->rectz[offset]: 0x7FFFFFFF; if(spart->rectmask) maskz= spart->rectmask[offset]; } @@ -560,8 +562,10 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float CHECK_ASSIGN(0); } - strand_shade_refcount(cache, sseg->v[1]); - strand_shade_refcount(cache, sseg->v[2]); + if(cache) { + strand_shade_refcount(cache, sseg->v[1]); + strand_shade_refcount(cache, sseg->v[2]); + } spart->totapixbuf[offset]++; } } @@ -596,23 +600,16 @@ static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, f VECCOPY(jco3, co3); VECCOPY(jco4, co4); - if(re->osa) { - jx= -re->jit[sample][0]; - jy= -re->jit[sample][1]; + if(spart->jit) { + jx= -spart->jit[sample][0]; + jy= -spart->jit[sample][1]; jco1[0] += jx; jco1[1] += jy; jco2[0] += jx; jco2[1] += jy; jco3[0] += jx; jco3[1] += jy; jco4[0] += jx; jco4[1] += jy; - } - else if(re->i.curblur) { - jx= -re->jit[re->i.curblur-1][0]; - jy= -re->jit[re->i.curblur-1][1]; - jco1[0] += jx; jco1[1] += jy; - jco2[0] += jx; jco2[1] += jy; - jco3[0] += jx; jco3[1] += jy; - jco4[0] += jx; jco4[1] += jy; + /* XXX mblur? */ } spart->sample= sample; @@ -756,7 +753,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp } /* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand *apixbuf, ListBase *apsmbase, StrandShadeCache *cache) +int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) { ObjectRen *obr; ObjectInstanceRen *obi; @@ -768,7 +765,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand StrandSegment sseg; StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg; MemArena *memarena; - float z[4], bounds[4], winmat[4][4]; + float z[4], bounds[4], obwinmat[4][4]; int a, b, c, i, totsegment, clip[4]; if(re->test_break(re->tbh)) @@ -788,27 +785,31 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand spart.rectz= pa->rectz; spart.rectmask= pa->rectmask; spart.cache= cache; + spart.shadow= shadow; + spart.jit= jit; - zbuf_alloc_span(&zspan, pa->rectx, pa->recty, re->clipcrop); + zbuf_alloc_span(&zspan, pa->rectx, pa->recty, clipcrop); /* needed for transform from hoco to zbuffer co */ - zspan.zmulx= ((float)re->winx)/2.0; - zspan.zmuly= ((float)re->winy)/2.0; + zspan.zmulx= ((float)winx)/2.0; + zspan.zmuly= ((float)winy)/2.0; zspan.zofsx= -pa->disprect.xmin; zspan.zofsy= -pa->disprect.ymin; /* to center the sample position */ - zspan.zofsx -= 0.5f; - zspan.zofsy -= 0.5f; + if(!shadow) { + zspan.zofsx -= 0.5f; + zspan.zofsy -= 0.5f; + } zspan.apsmbase= apsmbase; /* clipping setup */ - bounds[0]= (2*pa->disprect.xmin - re->winx-1)/(float)re->winx; - bounds[1]= (2*pa->disprect.xmax - re->winx+1)/(float)re->winx; - bounds[2]= (2*pa->disprect.ymin - re->winy-1)/(float)re->winy; - bounds[3]= (2*pa->disprect.ymax - re->winy+1)/(float)re->winy; + bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx; + bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx; + bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy; + bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); firstseg= NULL; @@ -819,14 +820,14 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand for(obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) { obr= obi->obr; - if(!obr->strandbuf || !(obr->strandbuf->lay & rl->lay)) + if(!obr->strandbuf || !(obr->strandbuf->lay & lay)) continue; /* compute matrix and try clipping whole object */ if(obi->flag & R_TRANSFORMED) - zbuf_make_winmat(re, obi->mat, winmat); + Mat4MulMat4(obwinmat, obi->mat, winmat); else - zbuf_make_winmat(re, NULL, winmat); + Mat4CpyMat4(obwinmat, winmat); if(clip_render_object(obi->obr->boundbox, bounds, winmat)) continue; @@ -843,14 +844,14 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand svert= strand->vert; /* keep clipping and z depth for 4 control points */ - clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]); - clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]); + clip[1]= strand_test_clip(obwinmat, &zspan, bounds, svert->co, &z[1]); + clip[2]= strand_test_clip(obwinmat, &zspan, bounds, (svert+1)->co, &z[2]); clip[0]= clip[1]; z[0]= z[1]; for(b=0; btotvert-1; b++, svert++) { /* compute 4th point clipping and z depth */ if(b < strand->totvert-2) { - clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]); + clip[3]= strand_test_clip(obwinmat, &zspan, bounds, (svert+2)->co, &z[3]); } else { clip[3]= clip[2]; z[3]= z[2]; @@ -900,7 +901,11 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand obi= &re->objectinstance[sortseg->obi]; obr= obi->obr; - zbuf_make_winmat(re, NULL, winmat); + + if(obi->flag & R_TRANSFORMED) + Mat4MulMat4(obwinmat, obi->mat, winmat); + else + Mat4CpyMat4(obwinmat, winmat); sseg.obi= obi; sseg.strand= RE_findOrAddStrand(obr, sortseg->strand); @@ -917,7 +922,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand spart.segment= &sseg; - render_strand_segment(re, winmat, &spart, &zspan, 1, &sseg); + render_strand_segment(re, obwinmat, &spart, &zspan, 1, &sseg); } } diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 3b3a8568933..a7b9867715f 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -271,7 +271,7 @@ static APixstr *addpsmainA(ListBase *lb) return psm->ps; } -static void freepsA(ListBase *lb) +void freepsA(ListBase *lb) { APixstrMain *psm, *psmnext; @@ -1760,12 +1760,12 @@ static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[ } } -static void zbuffer_part_bounds(Render *re, RenderPart *pa, float *bounds) +static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bounds) { - bounds[0]= (2*pa->disprect.xmin - re->winx-1)/(float)re->winx; - bounds[1]= (2*pa->disprect.xmax - re->winx+1)/(float)re->winx; - bounds[2]= (2*pa->disprect.ymin - re->winy-1)/(float)re->winy; - bounds[3]= (2*pa->disprect.ymax - re->winy+1)/(float)re->winy; + bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx; + bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx; + bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy; + bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; } static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho) @@ -1803,7 +1803,7 @@ void zbuf_render_project(float winmat[][4], float *co, float *ho) projectvert(vec, winmat, ho); } -void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4]) +void zbuf_make_winmat(Render *re, float winmat[][4]) { float panomat[4][4]; @@ -1814,13 +1814,8 @@ void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4]) panomat[2][0]= -re->panosi; panomat[2][2]= re->panoco; - if(duplimat) - Mat4MulSerie(winmat, re->winmat, panomat, duplimat, 0, 0, 0, 0, 0); - else - Mat4MulMat4(winmat, panomat, re->winmat); + Mat4MulMat4(winmat, panomat, re->winmat); } - else if(duplimat) - Mat4MulMat4(winmat, duplimat, re->winmat); else Mat4CpyMat4(winmat, re->winmat); } @@ -2047,12 +2042,15 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, Material *ma=0; ObjectInstanceRen *obi; ObjectRen *obr; - float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0}; + float obwinmat[4][4], winmat[4][4], bounds[4]; + float ho1[4], ho2[4], ho3[4], ho4[4]={0}; unsigned int lay= rl->lay, lay_zmask= rl->lay_zmask; int i, v, zvlnr, zsample, samples, c1, c2, c3, c4=0; short nofill=0, env=0, wire=0, zmaskpass=0; short all_z= (rl->layflag & SCE_LAY_ALL_Z) && !(rl->layflag & SCE_LAY_ZMASK); short neg_zmask= (rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK); + + zbuf_make_winmat(&R, winmat); samples= (R.osa? R.osa: 1); samples= MIN2(4, samples-pa->sample); @@ -2060,7 +2058,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, for(zsample=0; zsamplerectx, pa->recty, R.clipcrop); /* needed for transform from hoco to zbuffer co */ @@ -2135,9 +2133,9 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, continue; if(obi->flag & R_TRANSFORMED) - zbuf_make_winmat(&R, obi->mat, winmat); + Mat4MulMat4(obwinmat, obi->mat, winmat); else - zbuf_make_winmat(&R, NULL, winmat); + Mat4CpyMat4(obwinmat, winmat); if(clip_render_object(obi->obr->boundbox, bounds, winmat)) continue; @@ -2182,14 +2180,14 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, v3= vlr->v3; v4= vlr->v4; - c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1); - c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2); - c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3); + c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1); + c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2); + c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3); /* partclipping doesn't need viewplane clipping */ partclip= c1 & c2 & c3; if(v4) { - c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4); + c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4); partclip &= c4; } @@ -2511,11 +2509,13 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo VlakRen *vlr= NULL; VertRen *v1, *v2, *v3, *v4; Material *ma=0, *sss_ma= R.sss_mat; - float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0}; + float obwinmat[4][4], winmat[4][4], bounds[4]; + float ho1[4], ho2[4], ho3[4], ho4[4]={0}; int i, v, zvlnr, c1, c2, c3, c4=0; short nofill=0, env=0, wire=0; - zbuffer_part_bounds(&R, pa, bounds); + zbuf_make_winmat(&R, winmat); + zbuffer_part_bounds(R.winx, R.winy, pa, bounds); zbuf_alloc_span(&zspan, pa->rectx, pa->recty, R.clipcrop); zspan.sss_handle= handle; @@ -2551,9 +2551,9 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo continue; if(obi->flag & R_TRANSFORMED) - zbuf_make_winmat(&R, obi->mat, winmat); + Mat4MulMat4(obwinmat, obi->mat, winmat); else - zbuf_make_winmat(&R, NULL, winmat); + Mat4CpyMat4(obwinmat, winmat); if(clip_render_object(obi->obr->boundbox, bounds, winmat)) continue; @@ -3181,6 +3181,11 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) int x, y, *rza, *rma; intptr_t *rd; + if((R.osa==0 && !pa->rectz) || !pa->rectdaps) { + fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE); + return; + } + if(R.osa==0) { memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty); if(rectmask && pa->rectmask) @@ -3222,7 +3227,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) * Do accumulation z buffering. */ -static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, RenderLayer *rl, unsigned int lay) +static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspans[16], *zspan; /* MAX_OSA */ @@ -3232,28 +3237,27 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re VlakRen *vlr=NULL; VertRen *v1, *v2, *v3, *v4; float vec[3], hoco[4], mul, zval, fval; - float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0}; + float obwinmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0}; int i, v, zvlnr, c1, c2, c3, c4=0, dofill= 0; - int zsample, samples, polygon_offset; + int zsample, polygon_offset; - zbuffer_part_bounds(&R, pa, bounds); - samples= (R.osa? R.osa: 1); + zbuffer_part_bounds(winx, winy, pa, bounds); for(zsample=0; zsamplerectx, pa->recty, R.clipcrop); + zbuf_alloc_span(zspan, pa->rectx, pa->recty, re->clipcrop); /* needed for transform from hoco to zbuffer co */ - zspan->zmulx= ((float)R.winx)/2.0; - zspan->zmuly= ((float)R.winy)/2.0; + zspan->zmulx= ((float)winx)/2.0; + zspan->zmuly= ((float)winy)/2.0; /* the buffers */ zspan->arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz"); zspan->apixbuf= APixbuf; zspan->apsmbase= apsmbase; - if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) + if(negzmask) zspan->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectmask"); /* filling methods */ @@ -3263,36 +3267,35 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re copyto_abufz(pa, zspan->arectz, zspan->rectmask, zsample); /* init zbuffer */ zspan->mask= 1<zofsx= -pa->disprect.xmin - R.jit[zsample][0]; - zspan->zofsy= -pa->disprect.ymin - R.jit[zsample][1]; - } - else if(R.i.curblur) { - zspan->zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0]; - zspan->zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1]; + if(jit) { + zspan->zofsx= -pa->disprect.xmin + jit[zsample][0]; + zspan->zofsy= -pa->disprect.ymin + jit[zsample][1]; } else { zspan->zofsx= -pa->disprect.xmin; zspan->zofsy= -pa->disprect.ymin; } - /* to center the sample position */ - zspan->zofsx -= 0.5f; - zspan->zofsy -= 0.5f; + + if(!shadow) { + /* to center the sample position */ + zspan->zofsx -= 0.5f; + zspan->zofsy -= 0.5f; + } } /* we use this to test if nothing was filled in */ zvlnr= 0; - for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) { + for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) { obr= obi->obr; if(!(obi->lay & lay)) continue; if(obi->flag & R_TRANSFORMED) - zbuf_make_winmat(&R, obi->mat, winmat); + Mat4MulMat4(obwinmat, obi->mat, winmat); else - zbuf_make_winmat(&R, NULL, winmat); + Mat4CpyMat4(obwinmat, winmat); if(clip_render_object(obi->obr->boundbox, bounds, winmat)) continue; @@ -3306,7 +3309,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re if(vlr->mat!=ma) { ma= vlr->mat; - dofill= ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST); + dofill= shadow || (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST)); } if(dofill) { @@ -3318,27 +3321,27 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re v3= vlr->v3; v4= vlr->v4; - c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1); - c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2); - c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3); + c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1); + c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2); + c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3); /* partclipping doesn't need viewplane clipping */ partclip= c1 & c2 & c3; if(v4) { - c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4); + c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4); partclip &= c4; } if(partclip==0) { /* a little advantage for transp rendering (a z offset) */ - if( ma->zoffs != 0.0) { + if(!shadow && ma->zoffs != 0.0) { mul= 0x7FFFFFFF; zval= mul*(1.0+ho1[2]/ho1[3]); VECCOPY(vec, v1->co); /* z is negative, otherwise its being clipped */ vec[2]-= ma->zoffs; - projectverto(vec, R.winmat, hoco); + projectverto(vec, obwinmat, hoco); fval= mul*(1.0+hoco[2]/hoco[3]); polygon_offset= (int) fabs(zval - fval ); @@ -3376,13 +3379,13 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re } } if((v & 255)==255) - if(R.test_break(R.tbh)) + if(re->test_break(re->tbh)) break; } } } - if(R.test_break(R.tbh)) break; + if(re->test_break(re->tbh)) break; } for(zsample=0; zsamplelayflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)); + + if(R.osa) + jit= R.jit; + else if(R.i.curblur) + jit= &R.jit[R.i.curblur-1]; + else + jit= NULL; + + zbuf_make_winmat(&R, winmat); + + if(rl->layflag & SCE_LAY_ZTRA) + doztra+= zbuffer_abuf(&R, pa, APixbuf, apsmbase, rl->lay, negzmask, winmat, R.winx, R.winy, samples, jit, R.clipcrop, 0); + if((rl->layflag & SCE_LAY_STRAND) && APixbufstrand) + doztra+= zbuffer_strands_abuf(&R, pa, APixbufstrand, apsmbase, rl->lay, negzmask, winmat, R.winx, R.winy, samples, jit, R.clipcrop, 0, sscache); + + return doztra; +} + +void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) +{ + RenderPart pa; + int lay= -1; + + if(lar->mode & LA_LAYER) lay= lar->lay; + + memset(&pa, 0, sizeof(RenderPart)); + pa.rectx= size; + pa.recty= size; + pa.disprect.xmin= 0; + pa.disprect.ymin= 0; + pa.disprect.xmax= size; + pa.disprect.ymax= size; + + zbuffer_abuf(re, &pa, APixbuf, apsmbase, lay, 0, winmat, size, size, samples, jit, 1.0f, 1); + if(APixbufstrand) + zbuffer_strands_abuf(re, &pa, APixbufstrand, apsmbase, lay, 0, winmat, size, size, samples, jit, 1.0f, 1, NULL); +} + /* different rules for speed in transparent pass... */ /* speed pointer NULL = sky, we clear */ /* else if either alpha is full or no solid was filled in: copy speed */ @@ -3902,11 +3950,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas sampalpha= 1.0f; /* fill the Apixbuf */ - doztra= 0; - if(rl->layflag & SCE_LAY_ZTRA) - doztra+= zbuffer_abuf(pa, APixbuf, &apsmbase, rl, rl->lay); - if((rl->layflag & SCE_LAY_STRAND) && APixbufstrand) - doztra+= zbuffer_strands_abuf(&R, pa, rl, APixbufstrand, &apsmbase, sscache); + doztra= zbuffer_abuf_render(pa, APixbuf, APixbufstrand, &apsmbase, rl, sscache); if(doztra == 0) { /* nothing filled in */ -- cgit v1.2.3 From d2e1e0d2a93e55f6e7849299871b0afe85b90d96 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 21:06:03 +0000 Subject: remove C specials menus, reuse python ones from the header menu instead. --- release/scripts/ui/space_info.py | 2 +- release/scripts/ui/space_view3d.py | 77 ++++++++- source/blender/editors/mesh/mesh_ops.c | 188 ++-------------------- source/blenderplayer/bad_level_call_stubs/stubs.c | 2 +- 4 files changed, 85 insertions(+), 184 deletions(-) diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index 5a7a3b61cc2..aef90d818d1 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -41,7 +41,7 @@ class INFO_HT_header(bpy.types.Header): layout.itemL(text=scene.statistics()) -class INFO_MT_file(dynamic_menu.DynMenu): +class INFO_MT_file(bpy.types.Menu): __label__ = "File" def draw(self, context): diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 832ec0c5999..96f622af54b 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1,6 +1,8 @@ import bpy +import dynamic_menu + # ********** Header ********** class VIEW3D_HT_header(bpy.types.Header): @@ -742,11 +744,37 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu): layout.itemM("VIEW3D_MT_edit_mesh_showhide") +# Only used by the menu +class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu): + __label__ = "Specials" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.itemO("mesh.subdivide", text="Subdivide") + layout.item_floatO("mesh.subdivide", "smoothness", 1.0, text="Subdivide Smooth") + layout.itemO("mesh.merge", text="Merge...") + layout.itemO("mesh.remove_doubles", text="Remove Doubles") + layout.itemO("mesh.hide", text="Hide") + layout.itemO("mesh.reveal", text="Reveal") + layout.itemO("mesh.select_inverse", text="Select Inverse") + layout.itemO("mesh.flip_normals") + layout.itemO("mesh.vertices_smooth", text="Smooth") + # layout.itemO("mesh.bevel", text="Bevel") + layout.itemO("mesh.faces_shade_smooth") + layout.itemO("mesh.faces_shade_flat") + # layout.itemO("mesh.blend_from_shape", text="Blend From Shape") + # layout.itemO("mesh.shape_propagate_to_all", text="Propagate to All Shapes") + layout.itemO("mesh.select_vertex_path", text="Select Vertex Path") + class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): __label__ = "Vertices" def draw(self, context): layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' layout.itemO("mesh.merge") layout.itemO("mesh.rip") @@ -757,13 +785,19 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): layout.itemO("mesh.vertices_smooth") layout.itemO("mesh.remove_doubles") + + layout.itemO("mesh.select_vertex_path", text="Select Vertex Path") + + # uiItemO(layout, "Blend From Shape", 0, "mesh.blend_from_shape"); + # uiItemO(layout, "Propagate to All Shapes", 0, "mesh.shape_propagate_to_all"); class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): __label__ = "Edges" def draw(self, context): layout = self.layout - + layout.operator_context = 'INVOKE_REGION_WIN' + layout.itemO("mesh.edge_face_add") layout.itemO("mesh.subdivide") @@ -782,12 +816,30 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW") layout.item_enumO("mesh.edge_rotate", "direction", 'CCW', text="Rotate Edge CCW") -class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): + layout.itemS() + + layout.itemO("TFM_OT_edge_slide", text="Edge Slide") + layout.itemO("mesh.loop_multi_select", text="Edge Loop") + + # uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1); + # uiItemO(layout, "Edge Slide", 0, "mesh.edge_slide"); // EdgeSlide(em, 0,0.0); + + layout.item_booleanO("mesh.loop_multi_select", "ring", True, text="Edge Ring") + + layout.itemO("mesh.loop_to_region") + layout.itemO("mesh.region_to_loop") + + +class VIEW3D_MT_edit_mesh_faces(dynamic_menu.DynMenu): __label__ = "Faces" def draw(self, context): layout = self.layout - + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.itemO("mesh.flip_normals") + # layout.itemO("mesh.bevel") + # layout.itemO("mesh.bevel") layout.itemO("mesh.edge_face_add") layout.itemO("mesh.fill") layout.itemO("mesh.beauty_fill") @@ -802,6 +854,21 @@ class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): layout.itemO("mesh.faces_shade_smooth") layout.itemO("mesh.faces_shade_flat") + + layout.itemS() + + # uiItemO(layout, NULL, 0, "mesh.face_mode"); // mesh_set_face_flags(em, 1); + # uiItemBooleanO(layout, NULL, 0, "mesh.face_mode", "clear", 1); // mesh_set_face_flags(em, 0); + + layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW") + + layout.itemS() + + layout.item_menu_enumO("mesh.uvs_rotate", "direction") + layout.item_menu_enumO("mesh.uvs_mirror", "axis") + layout.item_menu_enumO("mesh.colors_rotate", "direction") + layout.item_menu_enumO("mesh.colors_mirror", "axis") + class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu): __label__ = "Normals" @@ -1264,14 +1331,14 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel): col = layout.column() col.itemR(view, "transform_orientation") - col.itemO("TFM_OT_create_orientation", text="Create") + col.itemO("tfm.create_orientation", text="Create") # orientation_index = view.__rna__.properties["transform_orientation"].items[view.transform_orientation].value # # if orientation_index >= 4: # orientation = context.scene.orientations[orientation_index - 4] # col.itemR(orientation, "name") - col.itemO("TFM_OT_delete_orientation", text="Delete") + col.itemO("tfm.delete_orientation", text="Delete") # Operators diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 9e74c5717c6..eaaf76d7bc7 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -63,174 +63,6 @@ #include "mesh_intern.h" -/******************************** menus *************************************/ - -static int vertex_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Vertex Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, "Remove Doubles", 0, "MESH_OT_remove_doubles"); - uiItemO(layout, "Merge...", 0, "MESH_OT_merge"); - uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth"); - uiItemO(layout, "Select Vertex Path", 0, "MESH_OT_select_vertex_path"); - //uiItemO(layout, "Blend From Shape", 0, "MESH_OT_blend_from_shape"); - //uiItemO(layout, "Propagate to All Shapes", 0, "MESH_OT_shape_propagate_to_all"); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_vertex_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Vertex Specials"; - //ot->description= "Perform special vertex operations."; - ot->idname= "MESH_OT_vertex_specials"; - - /* api callbacks */ - ot->invoke= vertex_specials_invoke; - ot->poll= ED_operator_editmesh; -} - -static int edge_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Edge Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, "Mark Seam", 0, "MESH_OT_mark_seam"); - uiItemBooleanO(layout, "Clear Seam", 0, "MESH_OT_mark_seam", "clear", 1); - uiItemEnumO(layout, "Rotate Edge CW", 0, "MESH_OT_edge_rotate", "direction", 1); - uiItemEnumO(layout, "Rotate Edge CCW", 0, "MESH_OT_edge_rotate", "direction", 2); - //uiItemO(layout, "Loopcut", 0, "MESH_OT_loop_cut"); // CutEdgeloop(em, 1); - //uiItemO(layout, "Edge Slide", 0, "MESH_OT_edge_slide"); // EdgeSlide(em, 0,0.0); - uiItemO(layout, "Edge Slide", 0, "TFM_OT_edge_slide"); - uiItemO(layout, "Edge Loop", 0, "MESH_OT_loop_multi_select"); - uiItemBooleanO(layout, "Edge Ring", 0, "MESH_OT_loop_multi_select", "ring", 1); - uiItemO(layout, NULL, 0, "MESH_OT_loop_to_region"); - uiItemO(layout, NULL, 0, "MESH_OT_region_to_loop"); - uiItemO(layout, "Mark Sharp", 0, "MESH_OT_mark_sharp"); - uiItemBooleanO(layout, "Clear Sharp", 0, "MESH_OT_mark_sharp", "clear", 1); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_edge_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Edge Specials"; - //ot->description= "Perform special edge operations."; - ot->idname= "MESH_OT_edge_specials"; - - /* api callbacks */ - ot->invoke= edge_specials_invoke; - ot->poll= ED_operator_editmesh; -} - -static int face_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Face Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, NULL, 0, "MESH_OT_flip_normals"); - // uiItemO(layout, "Bevel", 0, "MESH_OT_bevel"); // bevelmenu(em) - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_smooth"); - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_flat"); - uiItemO(layout, NULL, 0, "MESH_OT_quads_convert_to_tris"); - uiItemO(layout, NULL, 0, "MESH_OT_tris_convert_to_quads"); - uiItemO(layout, NULL, 0, "MESH_OT_edge_flip"); - - uiItemS(layout); - - uiItemO(layout, NULL, 0, "MESH_OT_fill"); - uiItemO(layout, NULL, 0, "MESH_OT_beauty_fill"); - - uiItemS(layout); - - // uiItemO(layout, NULL, 0, "MESH_OT_face_mode"); // mesh_set_face_flags(em, 1); - // uiItemBooleanO(layout, NULL, 0, "MESH_OT_face_mode", "clear", 1); // mesh_set_face_flags(em, 0); - // - // uiItemS(layout); - - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_rotate", "direction"); - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_mirror", "axis"); - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_colors_rotate", "direction"); - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_colors_mirror", "axis"); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_face_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Face Specials"; - //ot->description= "Perform special face operations."; - ot->idname= "MESH_OT_face_specials"; - - /* api callbacks */ - ot->invoke= face_specials_invoke; - ot->poll= ED_operator_editmesh; -} - -static int specials_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Specials", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - uiItemO(layout, "Subdivide", 0, "MESH_OT_subdivide"); - uiItemFloatO(layout, "Subdivide Smooth", 0, "MESH_OT_subdivide", "smoothness", 1.0f); - uiItemO(layout, "Merge...", 0, "MESH_OT_merge"); - uiItemO(layout, "Remove Doubles", 0, "MESH_OT_remove_doubles"); - uiItemO(layout, "Hide", 0, "MESH_OT_hide"); - uiItemO(layout, "Reveal", 0, "MESH_OT_reveal"); - uiItemO(layout, "Select Inverse", 0, "MESH_OT_select_inverse"); - uiItemO(layout, NULL, 0, "MESH_OT_flip_normals"); - uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth"); - // uiItemO(layout, "Bevel", 0, "MESH_OT_bevel"); // bevelmenu(em) - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_smooth"); - uiItemO(layout, NULL, 0, "MESH_OT_faces_shade_flat"); - //uiItemO(layout, "Blend From Shape", 0, "MESH_OT_blend_from_shape"); - //uiItemO(layout, "Propagate to All Shapes", 0, "MESH_OT_shape_propagate_to_all"); - uiItemO(layout, "Select Vertex Path", 0, "MESH_OT_select_vertex_path"); - - uiPupMenuEnd(C, pup); - - return OPERATOR_CANCELLED; -} - -static void MESH_OT_specials(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Specials"; - //ot->description= "Perform special vertice, edge or face operations."; - ot->idname= "MESH_OT_specials"; - - /* api callbacks */ - ot->invoke= specials_invoke; - ot->poll= ED_operator_editmesh; -} - /**************************** registration **********************************/ void ED_operatortypes_mesh(void) @@ -313,11 +145,6 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_vertex_color_remove); WM_operatortype_append(MESH_OT_sticky_add); WM_operatortype_append(MESH_OT_sticky_remove); - - WM_operatortype_append(MESH_OT_vertex_specials); - WM_operatortype_append(MESH_OT_edge_specials); - WM_operatortype_append(MESH_OT_face_specials); - WM_operatortype_append(MESH_OT_specials); WM_operatortype_append(MESH_OT_edgering_select); WM_operatortype_append(MESH_OT_loopcut); @@ -449,11 +276,18 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, 0, KKEY); /* menus */ - WM_keymap_add_item(keymap, "MESH_OT_vertex_specials", VKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_edge_specials", EKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_face_specials", FKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_specials", WKEY, KM_PRESS, 0, 0); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", WKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_specials"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", FKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_faces"); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", EKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_edges"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", VKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_edit_mesh_vertices"); + /* UV's */ WM_keymap_add_item(keymap, "UV_OT_mapping_menu", UKEY, KM_PRESS, 0, 0); } diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 8b6143467b9..ebd7b439624 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -215,4 +215,4 @@ void smoke_get_obstacle(void) {return;} void smoke_get_index(void) {return;} void smoke_step(void) {return;} -char blender_path(){return NULL;} \ No newline at end of file +char blender_path(){return NULL;} -- cgit v1.2.3 From 565622dac3868a25f39a3028268408f6d7cb038b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 21:11:31 +0000 Subject: skin tool from 2.4, am loathed to do this but durian artists want. --- release/scripts/io/mesh_skin.py | 639 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 639 insertions(+) create mode 100644 release/scripts/io/mesh_skin.py diff --git a/release/scripts/io/mesh_skin.py b/release/scripts/io/mesh_skin.py new file mode 100644 index 00000000000..4a330a516fb --- /dev/null +++ b/release/scripts/io/mesh_skin.py @@ -0,0 +1,639 @@ +#!BPY + +""" +Name: 'Skin Faces/Edge-Loops' +Blender: 243 +Group: 'MeshFaceKey' +Tooltip: 'Select 2 vert loops, then run this script.' +""" + +__author__ = "Campbell Barton AKA Ideasman" +__url__ = ["blenderartists.org", "www.blender.org"] +__version__ = "1.1 2006/12/26" + +__bpydoc__ = """\ +With this script vertex loops can be skinned: faces are created to connect the +selected loops of vertices. + +Usage: + +In mesh Edit mode select the vertices of the loops (closed paths / curves of +vertices: circles, for example) that should be skinned, then run this script. +A pop-up will provide further options, if the results of a method are not adequate try one of the others. +""" + + +# $Id$ +# +# -------------------------------------------------------------------------- +# Skin Selected edges 1.0 By Campbell Barton (AKA Ideasman) +# -------------------------------------------------------------------------- +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- + +# Made by Ideasman/Campbell 2005/06/15 - cbarton@metavr.com + +import Blender +import bpy +from Blender import Window +from Blender.Mathutils import MidpointVecs, Vector +from Blender.Mathutils import AngleBetweenVecs as _AngleBetweenVecs_ +import BPyMessages + +from Blender.Draw import PupMenu + +BIG_NUM = 1<<30 + +global CULL_METHOD +CULL_METHOD = 0 + +def AngleBetweenVecs(a1,a2): + try: + return _AngleBetweenVecs_(a1,a2) + except: + return 180.0 + +class edge(object): + __slots__ = 'v1', 'v2', 'co1', 'co2', 'length', 'removed', 'match', 'cent', 'angle', 'next', 'prev', 'normal', 'fake' + def __init__(self, v1,v2): + self.v1 = v1 + self.v2 = v2 + co1, co2= v1.co, v2.co + self.co1= co1 + self.co2= co2 + + # uv1 uv2 vcol1 vcol2 # Add later + self.length = (co1 - co2).length + self.removed = 0 # Have we been culled from the eloop + self.match = None # The other edge were making a face with + + self.cent= MidpointVecs(co1, co2) + self.angle= 0.0 + self.fake= False + +class edgeLoop(object): + __slots__ = 'centre', 'edges', 'normal', 'closed', 'backup_edges' + def __init__(self, loop, me, closed): # Vert loop + # Use next and prev, nextDist, prevDist + + # Get Loops centre. + fac= len(loop) + verts = me.verts + self.centre= reduce(lambda a,b: a+verts[b].co/fac, loop, Vector()) + + # Convert Vert loop to Edges. + self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in xrange(len(loop))] + + if not closed: + self.edges[0].fake = True # fake edge option + + self.closed = closed + + + # Assign linked list + for eIdx in xrange(len(self.edges)-1): + self.edges[eIdx].next = self.edges[eIdx+1] + self.edges[eIdx].prev = self.edges[eIdx-1] + # Now last + self.edges[-1].next = self.edges[0] + self.edges[-1].prev = self.edges[-2] + + + + # GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP. + self.normal = Vector() + for e in self.edges: + n = (self.centre-e.co1).cross(self.centre-e.co2) + # Do we realy need tot normalize? + n.normalize() + self.normal += n + + # Generate the angle + va= e.cent - e.prev.cent + vb= e.next.cent - e.cent + + e.angle= AngleBetweenVecs(va, vb) + + # Blur the angles + #for e in self.edges: + # e.angle= (e.angle+e.next.angle)/2 + + # Blur the angles + #for e in self.edges: + # e.angle= (e.angle+e.prev.angle)/2 + + self.normal.normalize() + + # Generate a normal for each edge. + for e in self.edges: + + n1 = e.co1 + n2 = e.co2 + n3 = e.prev.co1 + + a = n1-n2 + b = n1-n3 + normal1 = a.cross(b) + normal1.normalize() + + n1 = e.co2 + n3 = e.next.co2 + n2 = e.co1 + + a = n1-n2 + b = n1-n3 + + normal2 = a.cross(b) + normal2.normalize() + + # Reuse normal1 var + normal1 += normal1 + normal2 + normal1.normalize() + + e.normal = normal1 + #print e.normal + + + + def backup(self): + # Keep a backup of the edges + self.backup_edges = self.edges[:] + + def restore(self): + self.edges = self.backup_edges[:] + for e in self.edges: + e.removed = 0 + + def reverse(self): + self.edges.reverse() + self.normal.negate() + + for e in self.edges: + e.normal.negate() + e.v1, e.v2 = e.v2, e.v1 + e.co1, e.co2 = e.co2, e.co1 + e.next, e.prev = e.prev, e.next + + + def removeSmallest(self, cullNum, otherLoopLen): + ''' + Removes N Smallest edges and backs up the loop, + this is so we can loop between 2 loops as if they are the same length, + backing up and restoring incase the loop needs to be skinned with another loop of a different length. + ''' + global CULL_METHOD + if CULL_METHOD == 1: # Shortest edge + eloopCopy = self.edges[:] + + # Length sort, smallest first + try: eloopCopy.sort(key = lambda e1: e1.length) + except: eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length )) + + # Dont use atm + #eloopCopy.sort(lambda e1, e2: cmp(e1.angle*e1.length, e2.angle*e2.length)) # Length sort, smallest first + #eloopCopy.sort(lambda e1, e2: cmp(e1.angle, e2.angle)) # Length sort, smallest first + + remNum = 0 + for i, e in enumerate(eloopCopy): + if not e.fake: + e.removed = 1 + self.edges.remove( e ) # Remove from own list, still in linked list. + remNum += 1 + + if not remNum < cullNum: + break + + else: # CULL METHOD is even + + culled = 0 + + step = int(otherLoopLen / float(cullNum)) * 2 + + currentEdge = self.edges[0] + while culled < cullNum: + + # Get the shortest face in the next STEP + step_count= 0 + bestAng= 360.0 + smallestEdge= None + while step_count<=step or smallestEdge==None: + step_count+=1 + if not currentEdge.removed: # 0 or -1 will not be accepted + if currentEdge.angle 2: + return None + + vert_used[i] = True + + # do an edgeloop seek + if len(sbl) == 2: + contextVertLoop= [sbl[0], i, sbl[1]] # start the vert loop + vert_used[contextVertLoop[ 0]] = True + vert_used[contextVertLoop[-1]] = True + else: + contextVertLoop= [i, sbl[0]] + vert_used[contextVertLoop[ 1]] = True + + # Always seek up + ok = True + while ok: + ok = False + closed = False + sbl = vert_siblings[contextVertLoop[-1]] + if len(sbl) == 2: + next = sbl[not sbl.index( contextVertLoop[-2] )] + if vert_used[next]: + closed = True + # break + else: + contextVertLoop.append( next ) # get the vert that isnt the second last + vert_used[next] = True + ok = True + + # Seek down as long as the starting vert was not at the edge. + if not closed and len(vert_siblings[i]) == 2: + + ok = True + while ok: + ok = False + sbl = vert_siblings[contextVertLoop[0]] + if len(sbl) == 2: + next = sbl[not sbl.index( contextVertLoop[1] )] + if vert_used[next]: + closed = True + else: + contextVertLoop.insert(0, next) # get the vert that isnt the second last + vert_used[next] = True + ok = True + + mainVertLoops.append((contextVertLoop, closed)) + + + verts = me.verts + # convert from indicies to verts + # mainVertLoops = [([verts[i] for i in contextVertLoop], closed) for contextVertLoop, closed in mainVertLoops] + # print len(mainVertLoops) + return mainVertLoops + + + +def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE): + + new_faces= [] # + + # Make sure e1 loops is bigger then e2 + if len(eloop1.edges) != len(eloop2.edges): + if len(eloop1.edges) < len(eloop2.edges): + eloop1, eloop2 = eloop2, eloop1 + + eloop1.backup() # were about to cull faces + CULL_FACES = len(eloop1.edges) - len(eloop2.edges) + eloop1.removeSmallest(CULL_FACES, len(eloop1.edges)) + else: + CULL_FACES = 0 + # First make sure poly vert loops are in sync with eachother. + + # The vector allong which we are skinning. + skinVector = eloop1.centre - eloop2.centre + + loopDist = skinVector.length + + # IS THE LOOP FLIPPED, IF SO FLIP BACK. we keep it flipped, its ok, + if eloop1.closed or eloop2.closed: + angleBetweenLoopNormals = AngleBetweenVecs(eloop1.normal, eloop2.normal) + if angleBetweenLoopNormals > 90: + eloop2.reverse() + + + DIR= eloop1.centre - eloop2.centre + + # if eloop2.closed: + bestEloopDist = BIG_NUM + bestOffset = 0 + # Loop rotation offset to test.1 + eLoopIdxs = range(len(eloop1.edges)) + for offset in xrange(len(eloop1.edges)): + totEloopDist = 0 # Measure this total distance for thsi loop. + + offsetIndexLs = eLoopIdxs[offset:] + eLoopIdxs[:offset] # Make offset index list + + + # e1Idx is always from 0uu to N, e2Idx is offset. + for e1Idx, e2Idx in enumerate(offsetIndexLs): + e1= eloop1.edges[e1Idx] + e2= eloop2.edges[e2Idx] + + + # Include fan connections in the measurement. + OK= True + while OK or e1.removed: + OK= False + + # Measure the vloop distance =============== + diff= ((e1.cent - e2.cent).length) #/ nangle1 + + ed_dir= e1.cent-e2.cent + a_diff= AngleBetweenVecs(DIR, ed_dir)/18 # 0 t0 18 + + totEloopDist += (diff * (1+a_diff)) / (1+loopDist) + + # Premeture break if where no better off + if totEloopDist > bestEloopDist: + break + + e1=e1.next + + if totEloopDist < bestEloopDist: + bestOffset = offset + bestEloopDist = totEloopDist + + # Modify V2 LS for Best offset + eloop2.edges = eloop2.edges[bestOffset:] + eloop2.edges[:bestOffset] + + else: + # Both are open loops, easier to calculate. + + + # Make sure the fake edges are at the start. + for i, edloop in enumerate((eloop1, eloop2)): + # print "LOOPO" + if edloop.edges[0].fake: + # alredy at the start + #print "A" + pass + elif edloop.edges[-1].fake: + # put the end at the start + edloop.edges.insert(0, edloop.edges.pop()) + #print "B" + + else: + for j, ed in enumerate(edloop.edges): + if ed.fake: + #print "C" + edloop.edges = edloop.edges = edloop.edges[j:] + edloop.edges[:j] + break + # print "DONE" + ed1, ed2 = eloop1.edges[0], eloop2.edges[0] + + if not ed1.fake or not ed2.fake: + raise "Error" + + # Find the join that isnt flipped (juts like detecting a bow-tie face) + a1 = (ed1.co1 - ed2.co1).length + (ed1.co2 - ed2.co2).length + a2 = (ed1.co1 - ed2.co2).length + (ed1.co2 - ed2.co1).length + + if a1 > a2: + eloop2.reverse() + # make the first edge the start edge still + eloop2.edges.insert(0, eloop2.edges.pop()) + + + + + for loopIdx in xrange(len(eloop2.edges)): + e1 = eloop1.edges[loopIdx] + e2 = eloop2.edges[loopIdx] + + # Remember the pairs for fan filling culled edges. + e1.match = e2; e2.match = e1 + + if not (e1.fake or e2.fake): + new_faces.append([e1.v1, e1.v2, e2.v2, e2.v1]) + + # FAN FILL MISSING FACES. + if CULL_FACES: + # Culled edges will be in eloop1. + FAN_FILLED_FACES = 0 + + contextEdge = eloop1.edges[0] # The larger of teh 2 + while FAN_FILLED_FACES < CULL_FACES: + while contextEdge.next.removed == 0: + contextEdge = contextEdge.next + + vertFanPivot = contextEdge.match.v2 + + while contextEdge.next.removed == 1: + #if not contextEdge.next.fake: + new_faces.append([contextEdge.next.v1, contextEdge.next.v2, vertFanPivot]) + + # Should we use another var?, this will work for now. + contextEdge.next.removed = 1 + + contextEdge = contextEdge.next + FAN_FILLED_FACES += 1 + + # may need to fan fill backwards 1 for non closed loops. + + eloop1.restore() # Add culled back into the list. + + return new_faces + +def main(): + global CULL_METHOD + + is_editmode = Window.EditMode() + if is_editmode: Window.EditMode(0) + ob = bpy.data.scenes.active.objects.active + if ob == None or ob.type != 'Mesh': + BPyMessages.Error_NoMeshActive() + return + + me = ob.getData(mesh=1) + + if me.multires: + BPyMessages.Error_NoMeshMultiresEdit() + return + + time1 = Blender.sys.time() + selEdges = getSelectedEdges(me, ob) + vertLoops = getVertLoops(selEdges, me) # list of lists of edges. + if vertLoops == None: + PupMenu('Error%t|Selection includes verts that are a part of more then 1 loop') + if is_editmode: Window.EditMode(1) + return + # print len(vertLoops) + + + if len(vertLoops) > 2: + choice = PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment') + if choice == -1: + if is_editmode: Window.EditMode(1) + return + elif len(vertLoops) < 2: + PupMenu('Error%t|No Vertloops found!') + if is_editmode: Window.EditMode(1) + return + else: + choice = 2 + + + # The line below checks if any of the vert loops are differenyt in length. + if False in [len(v[0]) == len(vertLoops[0][0]) for v in vertLoops]: + CULL_METHOD = PupMenu('Small to large edge loop distrobution method%t|remove edges evenly|remove smallest edges') + if CULL_METHOD == -1: + if is_editmode: Window.EditMode(1) + return + + if CULL_METHOD ==1: # RESET CULL_METHOD + CULL_METHOD = 0 # shortest + else: + CULL_METHOD = 1 # even + + + time1 = Blender.sys.time() + # Convert to special edge data. + edgeLoops = [] + for vloop, closed in vertLoops: + edgeLoops.append(edgeLoop(vloop, me, closed)) + + + # VERT LOOP ORDERING CODE + # "Build a worm" list - grow from Both ends + edgeOrderedList = [edgeLoops.pop()] + + # Find the closest. + bestSoFar = BIG_NUM + bestIdxSoFar = None + for edLoopIdx, edLoop in enumerate(edgeLoops): + l =(edgeOrderedList[-1].centre - edLoop.centre).length + if l < bestSoFar: + bestIdxSoFar = edLoopIdx + bestSoFar = l + + edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) ) + + # Now we have the 2 closest, append to either end- + # Find the closest. + while edgeLoops: + bestSoFar = BIG_NUM + bestIdxSoFar = None + first_or_last = 0 # Zero is first + for edLoopIdx, edLoop in enumerate(edgeLoops): + l1 =(edgeOrderedList[-1].centre - edLoop.centre).length + + if l1 < bestSoFar: + bestIdxSoFar = edLoopIdx + bestSoFar = l1 + first_or_last = 1 # last + + l2 =(edgeOrderedList[0].centre - edLoop.centre).length + if l2 < bestSoFar: + bestIdxSoFar = edLoopIdx + bestSoFar = l2 + first_or_last = 0 # last + + if first_or_last: # add closest Last + edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) ) + else: # Add closest First + edgeOrderedList.insert(0, edgeLoops.pop(bestIdxSoFar) ) # First + + faces = [] + + for i in xrange(len(edgeOrderedList)-1): + faces.extend( skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0) ) + if choice == 1 and len(edgeOrderedList) > 2: # Loop + faces.extend( skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) ) + + # REMOVE SELECTED FACES. + MESH_MODE= Blender.Mesh.Mode() + if MESH_MODE & Blender.Mesh.SelectModes.EDGE or MESH_MODE & Blender.Mesh.SelectModes.VERTEX: pass + elif MESH_MODE & Blender.Mesh.SelectModes.FACE: + try: me.faces.delete(1, [ f for f in me.faces if f.sel ]) + except: pass + + me.faces.extend(faces, smooth = True) + + print '\nSkin done in %.4f sec.' % (Blender.sys.time()-time1) + + + if is_editmode: Window.EditMode(1) + +if __name__ == '__main__': + main() -- cgit v1.2.3 From 1fc616351ba8ead153c0c951a91cfadcd740cc17 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Oct 2009 21:12:30 +0000 Subject: updated to work with 2.5x, currently no UI options. --- release/scripts/io/mesh_skin.py | 234 ++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 114 deletions(-) diff --git a/release/scripts/io/mesh_skin.py b/release/scripts/io/mesh_skin.py index 4a330a516fb..5487b6ba10b 100644 --- a/release/scripts/io/mesh_skin.py +++ b/release/scripts/io/mesh_skin.py @@ -1,71 +1,22 @@ -#!BPY - -""" -Name: 'Skin Faces/Edge-Loops' -Blender: 243 -Group: 'MeshFaceKey' -Tooltip: 'Select 2 vert loops, then run this script.' -""" - -__author__ = "Campbell Barton AKA Ideasman" -__url__ = ["blenderartists.org", "www.blender.org"] -__version__ = "1.1 2006/12/26" - -__bpydoc__ = """\ -With this script vertex loops can be skinned: faces are created to connect the -selected loops of vertices. - -Usage: - -In mesh Edit mode select the vertices of the loops (closed paths / curves of -vertices: circles, for example) that should be skinned, then run this script. -A pop-up will provide further options, if the results of a method are not adequate try one of the others. -""" - - -# $Id$ -# -# -------------------------------------------------------------------------- -# Skin Selected edges 1.0 By Campbell Barton (AKA Ideasman) -# -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -------------------------------------------------------------------------- - -# Made by Ideasman/Campbell 2005/06/15 - cbarton@metavr.com - -import Blender +# import Blender +import time, functools import bpy -from Blender import Window -from Blender.Mathutils import MidpointVecs, Vector -from Blender.Mathutils import AngleBetweenVecs as _AngleBetweenVecs_ -import BPyMessages +# from Blender import Window +from Mathutils import MidpointVecs, Vector +from Mathutils import AngleBetweenVecs as _AngleBetweenVecs_ +# import BPyMessages -from Blender.Draw import PupMenu +# from Blender.Draw import PupMenu BIG_NUM = 1<<30 global CULL_METHOD -CULL_METHOD = 0 +CULL_METHOD = 0 def AngleBetweenVecs(a1,a2): + import math try: - return _AngleBetweenVecs_(a1,a2) + return math.degrees(_AngleBetweenVecs_(a1,a2)) except: return 180.0 @@ -95,10 +46,10 @@ class edgeLoop(object): # Get Loops centre. fac= len(loop) verts = me.verts - self.centre= reduce(lambda a,b: a+verts[b].co/fac, loop, Vector()) + self.centre= functools.reduce(lambda a,b: a+verts[b].co/fac, loop, Vector()) # Convert Vert loop to Edges. - self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in xrange(len(loop))] + self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in range(len(loop))] if not closed: self.edges[0].fake = True # fake edge option @@ -107,7 +58,7 @@ class edgeLoop(object): # Assign linked list - for eIdx in xrange(len(self.edges)-1): + for eIdx in range(len(self.edges)-1): self.edges[eIdx].next = self.edges[eIdx+1] self.edges[eIdx].prev = self.edges[eIdx-1] # Now last @@ -254,34 +205,61 @@ class edgeLoop(object): # Returns face edges. # face must have edge data. -def getSelectedEdges(me, ob): - MESH_MODE= Blender.Mesh.Mode() +# Utility funcs for 2.5, make into a module?? +def ord_ind(i1,i2): + if i1 2: choice = PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment') if choice == -1: - if is_editmode: Window.EditMode(1) + if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False) return + elif len(vertLoops) < 2: - PupMenu('Error%t|No Vertloops found!') - if is_editmode: Window.EditMode(1) + raise Exception('Error%t|No Vertloops found!') + if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False) return else: choice = 2 @@ -567,7 +543,7 @@ def main(): CULL_METHOD = 1 # even - time1 = Blender.sys.time() + time1 = time.time() # Convert to special edge data. edgeLoops = [] for vloop, closed in vertLoops: @@ -616,24 +592,54 @@ def main(): faces = [] - for i in xrange(len(edgeOrderedList)-1): + for i in range(len(edgeOrderedList)-1): faces.extend( skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0) ) if choice == 1 and len(edgeOrderedList) > 2: # Loop faces.extend( skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) ) # REMOVE SELECTED FACES. - MESH_MODE= Blender.Mesh.Mode() - if MESH_MODE & Blender.Mesh.SelectModes.EDGE or MESH_MODE & Blender.Mesh.SelectModes.VERTEX: pass - elif MESH_MODE & Blender.Mesh.SelectModes.FACE: + MESH_MODE= ob.mode + if MESH_MODE == 'EDGE' or MESH_MODE == 'VERTEX': pass + elif MESH_MODE == 'FACE': try: me.faces.delete(1, [ f for f in me.faces if f.sel ]) except: pass - me.faces.extend(faces, smooth = True) + if 1: # 2.5 + mesh_faces_extend(me, faces) + me.update(calc_edges=True) + else: + me.faces.extend(faces, smooth = True) - print '\nSkin done in %.4f sec.' % (Blender.sys.time()-time1) + print('\nSkin done in %.4f sec.' % (time.time()-time1)) + + if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False) + + +class MESH_OT_skin(bpy.types.Operator): + '''Bridge face loops.''' + + __idname__ = "mesh.skin" + __label__ = "Add Torus" + __register__ = True + __undo__ = True + ''' + __props__ = [ + bpy.props.EnumProperty(attr="loft_method", items=[(), ()], description="", default= True), + ] + ''' - if is_editmode: Window.EditMode(1) + def execute(self, context): + main(context) + return ('FINISHED',) + + +# Register the operator +bpy.ops.add(MESH_OT_skin) + +# Add to a menu +import dynamic_menu +menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_edit_mesh_faces, (lambda self, context: self.layout.itemO("mesh.skin", text="Bridge Faces")) ) -if __name__ == '__main__': - main() +if __name__ == "__main__": + bpy.ops.mesh.skin() -- cgit v1.2.3 From 3a1216a2f299025c992561f55c0bb29034c79bdf Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 12 Oct 2009 22:33:32 +0000 Subject: Project option for snap to faces. This is similar to the old retopo all option but uses the snapping code and not the openGL depth buffer (it's thus more precise). Not sure if making it available as a snap option is sensible, this is up for discussion. NOTE: it will get slow fast on large meshes, we need to plug in an acceleration structure into snapping. This will need an icon too. --- .../blender/editors/armature/editarmature_sketch.c | 6 +- source/blender/editors/include/ED_transform.h | 8 +- source/blender/editors/include/ED_view3d.h | 4 +- .../blender/editors/space_view3d/view3d_header.c | 4 + source/blender/editors/space_view3d/view3d_view.c | 4 +- source/blender/editors/transform/transform.c | 1 - source/blender/editors/transform/transform.h | 2 + .../editors/transform/transform_conversions.c | 7 - .../blender/editors/transform/transform_generics.c | 341 ++++++++++----------- source/blender/editors/transform/transform_ops.c | 34 +- source/blender/editors/transform/transform_snap.c | 115 +++++-- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/RNA_enum_types.h | 1 + source/blender/makesrna/intern/rna_scene.c | 22 +- 14 files changed, 306 insertions(+), 244 deletions(-) diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 74876691dac..989070c1147 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1174,6 +1174,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok SK_Stroke *snap_stk; float vec[3]; float no[3]; + float mval[2]; int found = 0; int dist = SNAP_MIN_DISTANCE; // Use a user defined value here @@ -1197,9 +1198,12 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok point_added = 1; } } + + mval[0] = dd->mval[0]; + mval[1] = dd->mval[1]; /* try to snap to closer object */ - found = snapObjectsContext(C, dd->mval, &dist, vec, no, SNAP_NOT_SELECTED); + found = snapObjectsContext(C, mval, &dist, vec, no, SNAP_NOT_SELECTED); if (found == 1) { pt->type = dd->type; diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index a7ffefba8df..e07cbff429a 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -166,10 +166,10 @@ typedef enum SnapMode #define SNAP_MIN_DISTANCE 30 -int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, short mval[2]); -int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, short mval[2]); -int snapObjectsTransform(struct TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode); -int snapObjectsContext(struct bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode); +int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, float mval[2]); +int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, float mval[2]); +int snapObjectsTransform(struct TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode); +int snapObjectsContext(struct bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode); #endif diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 7b1022d1a3f..2752402fb66 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -88,8 +88,8 @@ void project_int_noclip(struct ARegion *ar, float *vec, int *adr); void project_float(struct ARegion *ar, float *vec, float *adr); void project_float_noclip(struct ARegion *ar, float *vec, float *adr); -void viewline(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]); -void viewray(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]); +void viewline(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]); +void viewray(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3]); int get_view3d_viewplane(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize); int get_view3d_ortho(struct View3D *v3d, struct RegionView3D *rv3d); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a44e3743bb4..8dcc8791d88 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -2144,6 +2144,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center"); xco+= XIC; } + if (ts->snap_mode == SCE_SNAP_MODE_FACE) { + uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_ROTATECOLLECTION,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them"); + xco+= XIC; + } uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); xco+= XIC + 10; uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode"); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index fd850e90ff5..8b378f05eb2 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -482,7 +482,7 @@ void VIEW3D_OT_setobjectascamera(wmOperatorType *ot) /* ********************************** */ /* create intersection coordinates in view Z direction at mouse coordinates */ -void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]) +void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]) { RegionView3D *rv3d= ar->regiondata; float vec[4]; @@ -517,7 +517,7 @@ void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float } /* create intersection ray in view Z direction at mouse coordinates */ -void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]) +void viewray(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3]) { float ray_end[3]; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0b7a672a0b6..4c24d366162 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2605,7 +2605,6 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short center = td->center; } else { - /* !TODO! Make this if not rely on G */ if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { center = td->center; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 60786127e3a..5cee1f51b0a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -87,6 +87,7 @@ typedef struct TransSnap { short modeTarget; short mode; short align; + short project; short status; float snapPoint[3]; /* snapping from this point */ float snapTarget[3]; /* to this point */ @@ -578,6 +579,7 @@ void snapGrid(TransInfo *t, float *val); void snapGridAction(TransInfo *t, float *val, GearsType action); void initSnapping(struct TransInfo *t, struct wmOperator *op); +void applyProject(TransInfo *t); void applySnapping(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); int handleSnapping(TransInfo *t, struct wmEvent *event); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 51ce87803fd..826fcb0c2dd 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -125,7 +125,6 @@ #include "ED_object.h" #include "ED_markers.h" #include "ED_mesh.h" -#include "ED_retopo.h" #include "ED_types.h" #include "ED_uvedit.h" #include "ED_view3d.h" @@ -4478,12 +4477,6 @@ void special_aftertrans_update(TransInfo *t) if (t->obedit) { if (cancelled==0) { EM_automerge(t->scene, t->obedit, 1); -#if 0 // TRANSFORM_FIX_ME - /* when snapping, delay retopo until after automerge */ - if (G.qual & LR_CTRLKEY) { - retopo_do_all(); - } -#endif } } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index c3ceea1a0c8..20d136e4790 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -91,7 +91,6 @@ #include "ED_keyframing.h" #include "ED_markers.h" #include "ED_mesh.h" -#include "ED_retopo.h" #include "ED_particle.h" #include "ED_screen_types.h" #include "ED_space_api.h" @@ -617,201 +616,201 @@ void recalcData(TransInfo *t) } } } - else if (t->obedit) { - if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { - Curve *cu= t->obedit->data; - Nurb *nu= cu->editnurb->first; - - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - - if (t->state == TRANS_CANCEL) { - while(nu) { - calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ - nu= nu->next; - } - } else { - /* Normal updating */ - while(nu) { - test2DNurb(nu); - calchandlesNurb(nu); - nu= nu->next; - } - /* TRANSFORM_FIX_ME */ - // retopo_do_all(); - } - } - else if(t->obedit->type==OB_LATTICE) { - Lattice *la= t->obedit->data; - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - - if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); + else if (t->spacetype == SPACE_VIEW3D) { + + /* project */ + if(t->state != TRANS_CANCEL) { + applyProject(t); } - else if (t->obedit->type == OB_MESH) { - if(t->spacetype==SPACE_IMAGE) { - SpaceImage *sima= t->sa->spacedata.first; + + if (t->obedit) { + if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { + Curve *cu= t->obedit->data; + Nurb *nu= cu->editnurb->first; - flushTransUVs(t); - if(sima->flag & SI_LIVE_UNWRAP) - ED_uvedit_live_unwrap_re_solve(); + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); - } else { - EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; - /* mirror modifier clipping? */ - if(t->state != TRANS_CANCEL) { - /* TRANSFORM_FIX_ME */ -// if ((G.qual & LR_CTRLKEY)==0) { -// /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */ -// retopo_do_all(); -// } - clipMirrorModifier(t, t->obedit); + if (t->state == TRANS_CANCEL) { + while(nu) { + calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ + nu= nu->next; + } + } else { + /* Normal updating */ + while(nu) { + test2DNurb(nu); + calchandlesNurb(nu); + nu= nu->next; + } } - if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) - editmesh_apply_to_mirror(t); - + } + else if(t->obedit->type==OB_LATTICE) { + Lattice *la= t->obedit->data; DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - - recalc_editnormals(em); + + if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); } - } - 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; - int i; - - /* Ensure all bones are correctly adjusted */ - for (ebo = edbo->first; ebo; ebo = ebo->next){ - - if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ - /* If this bone has a parent tip that has been moved */ - if (ebo->parent->flag & BONE_TIPSEL){ - VECCOPY (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{ - VECCOPY (ebo->parent->tail, ebo->head); - if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; + else if (t->obedit->type == OB_MESH) { + if(t->spacetype==SPACE_IMAGE) { + SpaceImage *sima= t->sa->spacedata.first; + + flushTransUVs(t); + if(sima->flag & SI_LIVE_UNWRAP) + ED_uvedit_live_unwrap_re_solve(); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); + } else { + EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; + /* mirror modifier clipping? */ + if(t->state != TRANS_CANCEL) { + clipMirrorModifier(t, t->obedit); } + if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) + editmesh_apply_to_mirror(t); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ + + recalc_editnormals(em); } + } + 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; + int i; - /* on extrude bones, oldlength==0.0f, so we scale radius of points */ - ebo->length= VecLenf(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; + /* Ensure all bones are correctly adjusted */ + for (ebo = edbo->first; ebo; ebo = ebo->next){ + + if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ + /* If this bone has a parent tip that has been moved */ + if (ebo->parent->flag & BONE_TIPSEL){ + VECCOPY (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{ + VECCOPY (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= VecLenf(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; + } + } + 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; } } - 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; - } - } - - - if (t->mode != TFM_BONE_ROLL) - { - /* fix roll */ - for(i = 0; i < t->total; i++, td++) + + + if (t->mode != TFM_BONE_ROLL) { - if (td->extra) + /* fix roll */ + for(i = 0; i < t->total; i++, td++) { - float vec[3], up_axis[3]; - float qrot[4]; - - ebo = td->extra; - VECCOPY(up_axis, td->axismtx[2]); - - if (t->mode != TFM_ROTATION) + if (td->extra) { - VecSubf(vec, ebo->tail, ebo->head); - Normalize(vec); - RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec); - QuatMulVecf(qrot, up_axis); - } - else - { - Mat3MulVecfl(t->mat, up_axis); + float vec[3], up_axis[3]; + float qrot[4]; + + ebo = td->extra; + VECCOPY(up_axis, td->axismtx[2]); + + if (t->mode != TFM_ROTATION) + { + VecSubf(vec, ebo->tail, ebo->head); + Normalize(vec); + RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec); + QuatMulVecf(qrot, up_axis); + } + else + { + Mat3MulVecfl(t->mat, up_axis); + } + + ebo->roll = ED_rollBoneToVector(ebo, up_axis); } - - ebo->roll = ED_rollBoneToVector(ebo, up_axis); } } + + if(arm->flag & ARM_MIRROR_EDIT) + transform_armature_mirror_update(t->obedit); + } - - if(arm->flag & ARM_MIRROR_EDIT) - transform_armature_mirror_update(t->obedit); - - } - else - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - } - else if( (t->flag & T_POSE) && t->poseobj) { - 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' - * (i.e. uneditable animation values) - */ - // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? - if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { - 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->scene, (View3D *)t->view, ob, t->mode, targetless_ik); - } - - /* old optimize trick... this enforces to bypass the depgraph */ - if (!(arm->flag & ARM_DELAYDEFORM)) { - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ + else + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ } - else - where_is_pose(scene, ob); - } - else { - for(base= FIRSTBASE; base; base= base->next) { - Object *ob= base->object; + else if( (t->flag & T_POSE) && t->poseobj) { + Object *ob= t->poseobj; + bArmature *arm= ob->data; - /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */ - if(base->flag & BA_HAS_RECALC_OB) - ob->recalc |= OB_RECALC_OB; - if(base->flag & BA_HAS_RECALC_DATA) - ob->recalc |= OB_RECALC_DATA; + /* if animtimer is running, and the object already has animation data, + * check if the auto-record feature means that we should record 'samples' + * (i.e. uneditable animation values) + */ + // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? + if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { + 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->scene, (View3D *)t->view, ob, t->mode, targetless_ik); + } - /* if object/base is selected */ - if ((base->flag & SELECT) || (ob->flag & SELECT)) { - /* if animtimer is running, and the object already has animation data, - * check if the auto-record feature means that we should record 'samples' - * (i.e. uneditable animation values) - */ - // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? - if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { - animrecord_check_state(t->scene, &ob->id, t->animtimer); - autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); + /* old optimize trick... this enforces to bypass the depgraph */ + if (!(arm->flag & ARM_DELAYDEFORM)) { + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ + } + else + where_is_pose(scene, ob); + } + else { + for(base= FIRSTBASE; base; base= base->next) { + Object *ob= base->object; + + /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */ + if(base->flag & BA_HAS_RECALC_OB) + ob->recalc |= OB_RECALC_OB; + if(base->flag & BA_HAS_RECALC_DATA) + ob->recalc |= OB_RECALC_DATA; + + /* if object/base is selected */ + if ((base->flag & SELECT) || (ob->flag & SELECT)) { + /* if animtimer is running, and the object already has animation data, + * check if the auto-record feature means that we should record 'samples' + * (i.e. uneditable animation values) + */ + // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? + if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) { + animrecord_check_state(t->scene, &ob->id, t->animtimer); + autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); + } } + + /* proxy exception */ + if(ob->proxy) + ob->proxy->recalc |= ob->recalc; + if(ob->proxy_group) + group_tag_recalc(ob->proxy_group->dup_group); } - - /* proxy exception */ - if(ob->proxy) - ob->proxy->recalc |= ob->recalc; - if(ob->proxy_group) - group_tag_recalc(ob->proxy_group->dup_group); } + + if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) + reshadeall_displist(t->scene); } - - /* update shaded drawmode while transform */ - if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) - reshadeall_displist(t->scene); } void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index b0e79b3b062..3408f6cf3f7 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -63,32 +63,6 @@ EnumPropertyItem proportional_mode_types[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem snap_mode_types[] = { - {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", ""}, - {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", ""}, - {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", ""}, - {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", ""}, - {0, NULL, 0, NULL, NULL} -}; - -EnumPropertyItem proportional_falloff_types[] = { - {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""}, - {PROP_SPHERE, "SPHERE", 0, "Sphere", ""}, - {PROP_ROOT, "ROOT", 0, "Root", ""}, - {PROP_SHARP, "SHARP", 0, "Sharp", ""}, - {PROP_LIN, "LINEAR", 0, "Linear", ""}, - {PROP_CONST, "CONSTANT", 0, "Constant", ""}, - {PROP_RANDOM, "RANDOM", 0, "Random", ""}, - {0, NULL, 0, NULL, NULL} -}; - -EnumPropertyItem orientation_items[]= { - {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}, - {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}, - {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}, - {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}, - {0, NULL, 0, NULL, NULL}}; - char OP_TRANSLATION[] = "TFM_OT_translate"; char OP_ROTATION[] = "TFM_OT_rotate"; char OP_TOSPHERE[] = "TFM_OT_tosphere"; @@ -157,7 +131,8 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) ot->exec = select_orientation_exec; ot->poll = ED_operator_areaactive; - prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + 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); } @@ -374,7 +349,7 @@ void Properties_Proportional(struct wmOperatorType *ot) void Properties_Snapping(struct wmOperatorType *ot, short align) { RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", ""); - RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", ""); + RNA_def_enum(ot->srna, "snap_mode", snap_mode_items, 0, "Mode", ""); RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX); if (align) @@ -389,7 +364,8 @@ void Properties_Constraints(struct wmOperatorType *ot) PropertyRNA *prop; RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); - prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + 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); } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 84dc9e69e7a..0e3f999d47b 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -217,8 +217,69 @@ int handleSnapping(TransInfo *t, wmEvent *event) return status; } +void applyProject(TransInfo *t) +{ + /* XXX FLICKER IN OBJECT MODE */ + if ((t->tsnap.project) && (t->tsnap.status & SNAP_ON) && (t->modifiers & MOD_SNAP_GEARS)) + { + TransData *td = t->data; + float tvec[3]; + float imat[4][4]; + int i; + + if(t->flag & (T_EDIT|T_POSE)) { + Object *ob = t->obedit?t->obedit:t->poseobj; + Mat4Invert(imat, ob->obmat); + } + + for(i = 0 ; i < t->total; i++, td++) { + float iloc[3], loc[3], no[3]; + float mval[2]; + int dist = 1000; + + if (td->flag & TD_NOACTION) + break; + + if (td->flag & TD_SKIP) + continue; + + VECCOPY(iloc, td->loc); + if (t->flag & (T_EDIT|T_POSE)) + { + Object *ob = t->obedit?t->obedit:t->poseobj; + Mat4MulVecfl(ob->obmat, iloc); + } + else if (t->flag & T_OBJECT) + { + VECCOPY(iloc, td->ob->obmat[3]); + } + + project_float(t->ar, iloc, mval); + + if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode)) + { +// if(t->flag & (T_EDIT|T_POSE)) { +// Mat4MulVecfl(imat, loc); +// } +// + VecSubf(tvec, loc, iloc); + + Mat3MulVecfl(td->smtx, tvec); + + VecAddf(td->loc, td->loc, tvec); + } + + //XXX constraintTransLim(t, td); + } + } +} + void applySnapping(TransInfo *t, float *vec) { + /* project is not applied this way */ + if (t->tsnap.project) + return; + if (t->tsnap.status & SNAP_FORCED) { t->tsnap.targetSnap(t); @@ -305,12 +366,24 @@ void initSnapping(TransInfo *t, wmOperator *op) RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal); Normalize(t->tsnap.snapNormal); } + + if (RNA_struct_find_property(op->ptr, "snap_project")) + { + t->tsnap.project = RNA_boolean_get(op->ptr, "snap_project"); + } } } else { snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP); t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE); + t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT); + } + + /* force project off when not supported */ + if (ts->snap_mode != SCE_SNAP_MODE_FACE) + { + t->tsnap.project = 0; } if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV @@ -537,9 +610,13 @@ void CalcSnapGeometry(TransInfo *t, float *vec) { float loc[3]; float no[3]; + float mval[2]; int found = 0; int dist = SNAP_MIN_DISTANCE; // Use a user defined value here + mval[0] = t->mval[0]; + mval[1] = t->mval[1]; + if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME) { ListBase depth_peels; @@ -550,7 +627,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) depth_peels.first = depth_peels.last = NULL; - peelObjectsTransForm(t, &depth_peels, t->mval); + peelObjectsTransForm(t, &depth_peels, mval); // if (LAST_SNAP_POINT_VALID) // { @@ -633,7 +710,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) } else { - found = snapObjectsTransform(t, t->mval, &dist, loc, no, t->tsnap.mode); + found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode); } if (found == 1) @@ -854,7 +931,7 @@ void TargetSnapClosest(TransInfo *t) } /*================================================================*/ -int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) { float lambda; int result; @@ -885,7 +962,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4 new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); if (new_dist <= *dist && new_depth < *depth) { @@ -905,7 +982,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4 return retval; } -int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) { float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; int result; @@ -953,7 +1030,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); /* 10% threshold if edge is closer but a bit further * this takes care of series of connected edges a bit slanted w.r.t the viewport @@ -990,7 +1067,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n return retval; } -int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) { int retval = 0; float dvec[3]; @@ -1011,7 +1088,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); if (new_dist <= *dist && new_depth < *depth) { @@ -1034,7 +1111,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray return retval; } -int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { float imat[4][4]; float ray_start_local[3], ray_normal_local[3]; @@ -1099,7 +1176,7 @@ int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float return retval; } -int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { int retval = 0; int totvert = dm->getNumVerts(dm); @@ -1333,7 +1410,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E return retval; } -int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { ToolSettings *ts= scene->toolsettings; int retval = 0; @@ -1365,7 +1442,7 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma return retval; } -int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mval[2], int *dist, float *loc, float *no, SnapMode mode) { +int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { Base *base; float depth = FLT_MAX; int retval = 0; @@ -1382,7 +1459,7 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv base= FIRSTBASE; for ( base = FIRSTBASE; base != NULL; base = base->next ) { - if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (mode == SNAP_NOT_OBEDIT && base != BASACT)) ) { + if ( BASE_SELECTABLE(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)) ) { Object *ob = base->object; if (ob->transflag & OB_DUPLI) @@ -1407,12 +1484,12 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv return retval; } -int snapObjectsTransform(TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode) +int snapObjectsTransform(TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, dist, loc, no, mode); } -int snapObjectsContext(bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode) +int snapObjectsContext(bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; @@ -1477,7 +1554,7 @@ void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], O peel->flag = 0; } -int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels) +int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], ListBase *depth_peels) { int retval = 0; int totvert = dm->getNumVerts(dm); @@ -1585,7 +1662,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta return retval; } -int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, short mval[2]) +int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, float mval[2]) { Base *base; int retval = 0; @@ -1666,12 +1743,12 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase return retval; } -int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, short mval[2]) +int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, float mval[2]) { return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval); } -int peelObjectsContext(bContext *C, ListBase *depth_peels, short mval[2]) +int peelObjectsContext(bContext *C, ListBase *depth_peels, float mval[2]) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 437b45cfda1..e069136d46a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -982,6 +982,7 @@ typedef struct Scene { #define SCE_SNAP 1 #define SCE_SNAP_ROTATE 2 #define SCE_SNAP_PEEL_OBJECT 4 +#define SCE_SNAP_PROJECT 8 /* toolsettings->snap_target */ #define SCE_SNAP_TARGET_CLOSEST 0 #define SCE_SNAP_TARGET_CENTER 1 diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index ff4eee8d074..4db76c7f312 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -32,6 +32,7 @@ extern EnumPropertyItem object_mode_items[]; extern EnumPropertyItem prop_mode_items[]; +extern EnumPropertyItem snap_mode_items[]; extern EnumPropertyItem space_type_items[]; extern EnumPropertyItem region_type_items[]; extern EnumPropertyItem modifier_type_items[]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 4a42a63bf6b..29fb9e4deb2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -43,7 +43,14 @@ #include "WM_types.h" -/* prop_mode needs to be accessible from transform operator */ + +EnumPropertyItem snap_mode_items[] = { + {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."}, + {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."}, + {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."}, + {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."}, + {0, NULL, 0, NULL, NULL}}; + EnumPropertyItem prop_mode_items[] ={ {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""}, {PROP_SPHERE, "SPHERE", 0, "Sphere", ""}, @@ -54,6 +61,7 @@ EnumPropertyItem prop_mode_items[] ={ {PROP_RANDOM, "RANDOM", 0, "Random", ""}, {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" @@ -489,13 +497,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) {SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume."}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem snap_mode_items[] = { - {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."}, - {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."}, - {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."}, - {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem auto_key_items[] = { {AUTOKEY_MODE_NORMAL, "ADD_REPLACE_KEYS", 0, "Add & Replace", ""}, {AUTOKEY_MODE_EDITKEYS, "REPLACE_KEYS", 0, "Replace", ""}, @@ -570,6 +571,11 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Snap Peel Object", "Consider objects as whole when finding volume center."); RNA_def_property_ui_icon(prop, ICON_SNAP_PEEL_OBJECT, 0); + prop= RNA_def_property(srna, "snap_project", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT); + RNA_def_property_ui_text(prop, "Project Individual Elements", "DOC_BROKEN"); + RNA_def_property_ui_icon(prop, ICON_ROTATECOLLECTION, 0); + /* Auto Keying */ prop= RNA_def_property(srna, "enable_auto_key", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON); -- cgit v1.2.3 From 1aeb98a3c21f8362f2f5607ccc554a9eceb5b4af Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 13 Oct 2009 02:04:08 +0000 Subject: * ui fix for texture influences --- release/scripts/ui/buttons_texture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index 5efdaf77839..0313a986749 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -262,7 +262,7 @@ class TEXTURE_PT_influence(TextureSlotPanel): #sub = col.column() #sub.active = tex.map_translucency or tex.map_emit or tex.map_alpha or tex.map_raymir or tex.map_hardness or tex.map_ambient or tex.map_specularity or tex.map_reflection or tex.map_mirror #sub.itemR(tex, "default_value", text="Amount", slider=True) - elif ma.type == 'VOLUME': + elif idblock.type == 'VOLUME': split = layout.split() col = split.column() -- cgit v1.2.3 From 7171c5928e6bece26d3a3dde41c088e77dbba423 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 13 Oct 2009 02:21:18 +0000 Subject: Changing the animation editor filters should now result in the editors updating in realtime afterwards again. --- source/blender/editors/space_action/action_header.c | 9 +++------ source/blender/editors/space_graph/graph_header.c | 11 ++--------- source/blender/editors/space_nla/nla_header.c | 11 ++++------- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index 25a5123d1b5..e0d952c29c1 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -68,7 +68,7 @@ #include "action_intern.h" enum { - B_REDR= 0, + B_REDR= 1, } eActHeader_Events; /* ********************************************************* */ @@ -254,11 +254,8 @@ static void act_editmenu(bContext *C, uiLayout *layout, void *arg_unused) static void do_action_buttons(bContext *C, void *arg, int event) { - switch (event) { - case B_REDR: - ED_area_tag_redraw(CTX_wm_area(C)); - break; - } + ED_area_tag_refresh(CTX_wm_area(C)); + ED_area_tag_redraw(CTX_wm_area(C)); } void action_header_buttons(const bContext *C, ARegion *ar) diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index ac1378af859..8d8c8702987 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -244,15 +244,8 @@ enum { static void do_graph_buttons(bContext *C, void *arg, int event) { - switch (event) { - case B_MODECHANGE: /* change mode with mode selector */ - ED_area_tag_refresh(CTX_wm_area(C)); - /* no break, as we need redraw flush too... */ - - case B_REDR: - ED_area_tag_redraw(CTX_wm_area(C)); - break; - } + ED_area_tag_refresh(CTX_wm_area(C)); + ED_area_tag_redraw(CTX_wm_area(C)); } diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c index 4eb9fac5cb8..be0b4381f00 100644 --- a/source/blender/editors/space_nla/nla_header.c +++ b/source/blender/editors/space_nla/nla_header.c @@ -73,8 +73,8 @@ /* button events */ enum { - B_REDR = 0, -} eActHeader_ButEvents; + B_REDR = 1, +} eNLAHeader_ButEvents; /* ************************ header area region *********************** */ @@ -203,11 +203,8 @@ static void nla_addmenu(bContext *C, uiLayout *layout, void *arg_unused) static void do_nla_buttons(bContext *C, void *arg, int event) { - switch (event) { - case B_REDR: - ED_area_tag_redraw(CTX_wm_area(C)); - break; - } + ED_area_tag_refresh(CTX_wm_area(C)); + ED_area_tag_redraw(CTX_wm_area(C)); } -- cgit v1.2.3 From f8ab477f4569dec1853ec7c9114d21f9a84a062f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 13 Oct 2009 05:50:26 +0000 Subject: 2.5 Bugfixes: * Reverting some changes I made to try and get Action Groups with no viewable F-Curves, but were collapsed to get hidden. These were causing buggy behaviour * Move bones to armature layers, and change armature layer operators now use the new automatic properties drawing invoke callback. This allows changing the buttons there immediately affect the bones in the viewport * #19581: Text Editor: "Jump To" (go to line) not working Made this use the automatic operator props invoke callback, and fixed an RNA properties bug for this (the default value and range values were swapped). * PoseLib rename pose operator now works again. Once again, this uses the auto-props popup. Also, improved the code here while I was at it. * Disabled non-functional/old entry in Select Linked operator ("IPO's") --- source/blender/editors/animation/anim_filter.c | 25 +----- source/blender/editors/armature/poselib.c | 102 +++++++++++++++++-------- source/blender/editors/armature/poseobject.c | 47 ++---------- source/blender/editors/object/object_select.c | 2 +- source/blender/editors/space_text/text_ops.c | 7 +- source/blender/makesrna/intern/rna_object.c | 2 - 6 files changed, 86 insertions(+), 99 deletions(-) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 6b953d2460d..fef910a85a3 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -750,19 +750,14 @@ static int animdata_filter_action (ListBase *anim_data, bDopeSheet *ads, bAction /* loop over groups */ // TODO: in future, should we expect to need nested groups? for (agrp= act->groups.first; agrp; agrp= agrp->next) { - ListBase tmp_channels = {NULL, NULL}; - short grp_channel=0; - int tmp_items = 0; - - /* add this group as a channel first */ if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) { /* check if filtering by selection */ if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) { ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id); if (ale) { - BLI_addtail(&tmp_channels, ale); - grp_channel=1; + BLI_addtail(anim_data, ale); + items++; } } } @@ -792,25 +787,13 @@ static int animdata_filter_action (ListBase *anim_data, bDopeSheet *ads, bAction if ( !(filter_mode & ANIMFILTER_CURVEVISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) ) { if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) { - // XXX the 'owner' info here needs review... - tmp_items += animdata_filter_fcurves(&tmp_channels, ads, agrp->channels.first, agrp, owner, ownertype, filter_mode, owner_id); + items += animdata_filter_fcurves(anim_data, ads, agrp->channels.first, agrp, owner, ownertype, filter_mode, owner_id); } } } } - /* check group had any F-Curves visible */ - // TODO: this needs more work to truly work so that closed group with no visible channels, and visible group with visible channels are differentiated between - if (/*tmp_items*/1) { - /* add the temp channels to the list of filtered channels */ - addlisttolist(anim_data, &tmp_channels); - - /* increase the counts as appropriate */ - items += tmp_items + grp_channel; - } - else { - BLI_freelistN(&tmp_channels); - } + // TODO: but we still need to deal with the case when the group may be closed, but it has no visible curves too } /* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive group) */ diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index d34da201ef5..b06c7286859 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -285,6 +285,9 @@ static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout, bAction *act= ob->poselib; TimeMarker *marker; + /* set the operator execution context correctly */ + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + /* add each marker to this menu */ for (marker= act->markers.first; marker; marker= marker->next) uiItemIntO(layout, marker->name, ICON_ARMATURE_DATA, "POSELIB_OT_pose_add", "frame", marker->frame); @@ -398,7 +401,6 @@ static int poselib_add_exec (bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - void POSELIB_OT_pose_add (wmOperatorType *ot) { /* identifiers */ @@ -421,35 +423,35 @@ void POSELIB_OT_pose_add (wmOperatorType *ot) /* ----- */ -static int poselib_stored_pose_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) +static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, int *free) { Object *ob= CTX_data_active_object(C); bAction *act= (ob) ? ob->poselib : NULL; TimeMarker *marker; - uiPopupMenu *pup; - uiLayout *layout; - int i; - - /* sanity check */ - if (ELEM(NULL, ob, act)) - return OPERATOR_CANCELLED; - - /* start building */ - pup= uiPupMenuBegin(C, op->type->name, 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); - - /* add each marker to this menu */ - for (marker=act->markers.first, i=0; marker; marker= marker->next, i++) - uiItemIntO(layout, marker->name, ICON_ARMATURE_DATA, op->idname, "index", i); - - uiPupMenuEnd(C, pup); - - /* this operator is only for a menu, not used further */ - return OPERATOR_CANCELLED; -} + EnumPropertyItem *item= NULL, item_tmp; + int totitem= 0; + int i= 0; + + if (C == NULL) + return NULL; + + memset(&item_tmp, 0, sizeof(item_tmp)); + /* add each marker to the list */ + for (marker=act->markers.first, i=0; marker; marker= marker->next, i++) { + item_tmp.identifier= item_tmp.name= marker->name; + item_tmp.icon= ICON_ARMATURE_DATA; + item_tmp.value= i; + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + if (i > 0) { + *free= 1; + return item; + } + else + return NULL; +} static int poselib_remove_exec (bContext *C, wmOperator *op) { @@ -465,7 +467,7 @@ static int poselib_remove_exec (bContext *C, wmOperator *op) } /* get index (and pointer) of pose to remove */ - marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index")); + marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose")); if (marker == NULL) { BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); return OPERATOR_CANCELLED; @@ -499,13 +501,18 @@ static int poselib_remove_exec (bContext *C, wmOperator *op) void POSELIB_OT_pose_remove (wmOperatorType *ot) { + PropertyRNA *prop; + static EnumPropertyItem prop_poses_dummy_types[] = { + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ ot->name= "PoseLib Remove Pose"; ot->idname= "POSELIB_OT_pose_remove"; ot->description= "Remove nth pose from the active Pose Library"; /* api callbacks */ - ot->invoke= poselib_stored_pose_menu_invoke; + ot->invoke= WM_menu_invoke; ot->exec= poselib_remove_exec; ot->poll= ED_operator_posemode; @@ -513,10 +520,37 @@ void POSELIB_OT_pose_remove (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The index of the pose to remove", 0, INT_MAX); + prop= RNA_def_enum(ot->srna, "pose", prop_poses_dummy_types, 0, "Pose", "The pose to remove"); + RNA_def_enum_funcs(prop, poselib_stored_pose_itemf); } - +static int poselib_rename_invoke (bContext *C, wmOperator *op, wmEvent *evt) +{ + Object *ob= CTX_data_active_object(C); + bAction *act= (ob) ? ob->poselib : NULL; + TimeMarker *marker; + + /* check if valid poselib */ + if (act == NULL) { + BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + return OPERATOR_CANCELLED; + } + + /* get index (and pointer) of pose to remove */ + marker= BLI_findlink(&act->markers, act->active_marker-1); + if (marker == NULL) { + BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + return OPERATOR_CANCELLED; + } + else { + /* use the existing name of the marker as the name, and use the active marker as the one to rename */ + RNA_enum_set(op->ptr, "pose", act->active_marker-1); + RNA_string_set(op->ptr, "name", marker->name); + } + + /* part to sync with other similar operators... */ + return WM_operator_props_popup(C, op, evt); +} static int poselib_rename_exec (bContext *C, wmOperator *op) { @@ -532,7 +566,7 @@ static int poselib_rename_exec (bContext *C, wmOperator *op) } /* get index (and pointer) of pose to remove */ - marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index")); + marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose")); if (marker == NULL) { BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); return OPERATOR_CANCELLED; @@ -551,13 +585,18 @@ static int poselib_rename_exec (bContext *C, wmOperator *op) void POSELIB_OT_pose_rename (wmOperatorType *ot) { + PropertyRNA *prop; + static EnumPropertyItem prop_poses_dummy_types[] = { + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ ot->name= "PoseLib Rename Pose"; ot->idname= "POSELIB_OT_pose_rename"; ot->description= "Rename nth pose from the active Pose Library"; /* api callbacks */ - ot->invoke= poselib_stored_pose_menu_invoke; + ot->invoke= poselib_rename_invoke; ot->exec= poselib_rename_exec; ot->poll= ED_operator_posemode; @@ -565,7 +604,8 @@ void POSELIB_OT_pose_rename (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The index of the pose to remove", 0, INT_MAX); + prop= RNA_def_enum(ot->srna, "pose", prop_poses_dummy_types, 0, "Pose", "The pose to rename"); + RNA_def_enum_funcs(prop, poselib_stored_pose_itemf); RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose"); } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 1531d922e04..57fe083b319 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1727,31 +1727,6 @@ void pose_activate_flipped_bone(Scene *scene) /* ********************************************** */ -/* Present a popup to get the layers that should be used */ -// TODO: move to wm? -static uiBlock *wm_layers_select_create_menu(bContext *C, ARegion *ar, void *arg_op) -{ - wmOperator *op= arg_op; - uiBlock *block; - uiLayout *layout; - uiStyle *style= U.uistyles.first; - - block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockClearFlag(block, UI_BLOCK_LOOP); - uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN); - - layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 150, 20, style); - uiItemL(layout, op->type->name, 0); - uiTemplateLayers(layout, op->ptr, "layers"); /* must have a property named layers setup */ - - uiPopupBoundsBlock(block, 4.0f, 0, 0); - uiEndBlock(C, block); - - return block; -} - -/* ------------------- */ - /* Present a popup to get the layers that should be used */ static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) { @@ -1769,10 +1744,8 @@ static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *ev RNA_boolean_get_array(&ptr, "layer", layers); RNA_boolean_set_array(op->ptr, "layers", layers); - /* part to sync with other similar operators... */ - /* pass on operator, so return modal */ - uiPupBlockOperator(C, wm_layers_select_create_menu, op, WM_OP_EXEC_DEFAULT); - return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; + /* part to sync with other similar operators... */ + return WM_operator_props_popup(C, op, evt); } /* Set the visible layers for the active armature (edit and pose modes) */ @@ -1813,7 +1786,7 @@ void POSE_OT_armature_layers (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean_array(ot->srna, "layers", 16, NULL, "Layers", "Armature layers to make visible."); + RNA_def_boolean_layer_member(ot->srna, "layers", 16, NULL, "Layer", "Armature layers to make visible"); } void ARMATURE_OT_armature_layers (wmOperatorType *ot) @@ -1832,7 +1805,7 @@ void ARMATURE_OT_armature_layers (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean_array(ot->srna, "layers", 16, NULL, "Layers", "Armature layers to make visible."); + RNA_def_boolean_layer_member(ot->srna, "layers", 16, NULL, "Layer", "Armature layers to make visible"); } /* ------------------- */ @@ -1861,9 +1834,7 @@ static int pose_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) RNA_boolean_set_array(op->ptr, "layers", layers); /* part to sync with other similar operators... */ - /* pass on operator, so return modal */ - uiPupBlockOperator(C, wm_layers_select_create_menu, op, WM_OP_EXEC_DEFAULT); - return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; + return WM_operator_props_popup(C, op, evt); } /* Set the visible layers for the active armature (edit and pose modes) */ @@ -1908,7 +1879,7 @@ void POSE_OT_bone_layers (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean_array(ot->srna, "layers", 16, NULL, "Layers", "Armature layers that bone belongs to."); + RNA_def_boolean_layer_member(ot->srna, "layers", 16, NULL, "Layer", "Armature layers that bone belongs to"); } /* ------------------- */ @@ -1937,9 +1908,7 @@ static int armature_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *ev RNA_boolean_set_array(op->ptr, "layers", layers); /* part to sync with other similar operators... */ - /* pass on operator, so return modal */ - uiPupBlockOperator(C, wm_layers_select_create_menu, op, WM_OP_EXEC_DEFAULT); - return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; + return WM_operator_props_popup(C, op, evt); } /* Set the visible layers for the active armature (edit and pose modes) */ @@ -1984,7 +1953,7 @@ void ARMATURE_OT_bone_layers (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean_array(ot->srna, "layers", 16, NULL, "Layers", "Armature layers that bone belongs to."); + RNA_def_boolean_layer_member(ot->srna, "layers", 16, NULL, "Layer", "Armature layers that bone belongs to"); } /* ********************************************** */ diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 4fa0e04728f..27713cc2fa9 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -171,7 +171,7 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot) /*********************** Selection by Links *********************/ static EnumPropertyItem prop_select_linked_types[] = { - {1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... + //{1, "IPO", 0, "Object IPO", ""}, // XXX depreceated animation system stuff... {2, "OBDATA", 0, "Ob Data", ""}, {3, "MATERIAL", 0, "Material", ""}, {4, "TEXTURE", 0, "Texture", ""}, diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 44f7a097a18..a7b40deda22 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1628,10 +1628,6 @@ static int jump_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -// XXX invoke -// short tmp= txt_get_span(text->lines.first, text->curl)+1; -// button(&tmp, 1, nlines, "Jump to line:")) - void TEXT_OT_jump(wmOperatorType *ot) { /* identifiers */ @@ -1640,6 +1636,7 @@ void TEXT_OT_jump(wmOperatorType *ot) ot->description= "Jump cursor to line."; /* api callbacks */ + ot->invoke= WM_operator_props_popup; ot->exec= jump_exec; ot->poll= text_edit_poll; @@ -1647,7 +1644,7 @@ void TEXT_OT_jump(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER; /* properties */ - RNA_def_int(ot->srna, "line", 1, INT_MAX, 1, "Line", "Line number to jump to.", 1, 10000); + RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to.", 1, 10000); } /******************* delete operator **********************/ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index b91e5952c8f..6f2d455f660 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1192,7 +1192,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_select_update"); /* parent and track */ - prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_parent_set", NULL); RNA_def_property_flag(prop, PROP_EDITABLE); @@ -1238,7 +1237,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_update"); /* proxy */ - prop= RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE); RNA_def_property_ui_text(prop, "Proxy", "Library object this proxy object controls."); -- cgit v1.2.3 From 4b593ce328e4832cb69f56669239573eb72cf862 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 13 Oct 2009 06:15:41 +0000 Subject: * Fixing crash on mingw when entering world buttons * Changing hotkey in text editor for 'jumping' to a particular line to Ctrl-G, since this appears to be more standard (and is easier to hit). --- source/blender/editors/space_buttons/buttons_context.c | 14 +++++++++----- source/blender/editors/space_text/space_text.c | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index a5a7524e584..fe437dfd188 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -117,6 +117,7 @@ static int buttons_context_path_scene(ButsContextPath *path) static int buttons_context_path_world(ButsContextPath *path) { Scene *scene; + World *world; PointerRNA *ptr= &path->ptr[path->len-1]; /* if we already have a (pinned) world, we're done */ @@ -126,11 +127,14 @@ static int buttons_context_path_world(ButsContextPath *path) /* if we have a scene, use the scene's world */ else if(buttons_context_path_scene(path)) { scene= path->ptr[path->len-1].data; + world= scene->world; + + if(world) { + RNA_id_pointer_create(&scene->world->id, &path->ptr[path->len]); + path->len++; - RNA_id_pointer_create(&scene->world->id, &path->ptr[path->len]); - path->len++; - - return 1; + return 1; + } } /* no path to a world possible */ @@ -367,7 +371,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path wo= path->ptr[path->len-1].data; if(wo) { - give_current_world_texture(wo); + tex= give_current_world_texture(wo); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); path->len++; diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index e3816ed7495..09a5374a43b 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -241,7 +241,7 @@ static void text_keymap(struct wmKeyConfig *keyconf) if(U.uiflag & USER_MMB_PASTE) // XXX not dynamic RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0)->ptr, "selection", 1); - WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "TEXT_OT_jump", GKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0); -- cgit v1.2.3 From 4063c230af188167d0b8471d5700fe060c8420f6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Oct 2009 07:39:08 +0000 Subject: fix for warnings, wkey menu wasnt registered --- release/scripts/ui/space_view3d.py | 1 + source/blender/editors/armature/editarmature_sketch.c | 13 ++++++++----- source/blender/editors/include/ED_mesh.h | 2 ++ source/blender/editors/sculpt_paint/sculpt.c | 7 +++++-- source/blender/editors/transform/transform_generics.c | 1 + 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 96f622af54b..1fd589b4846 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1423,6 +1423,7 @@ bpy.types.register(VIEW3D_MT_pose_showhide) bpy.types.register(VIEW3D_MT_snap) # Edit Menus bpy.types.register(VIEW3D_MT_edit_mesh) +bpy.types.register(VIEW3D_MT_edit_mesh_specials) # Only as a menu for keybindings bpy.types.register(VIEW3D_MT_edit_mesh_vertices) bpy.types.register(VIEW3D_MT_edit_mesh_edges) bpy.types.register(VIEW3D_MT_edit_mesh_faces) diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 989070c1147..ce328ea8a82 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1006,9 +1006,9 @@ void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, float { float ray_start[3], ray_normal[3]; float delta = VecLenf(stk->points[i].p, stk->points[i + 1].p); - short pval[2]; + float pval[2]; - project_short_noclip(ar, stk->points[i].p, pval); + project_float(ar, stk->points[i].p, pval); viewray(ar, v3d, pval, ray_start, ray_normal); VecMulf(ray_normal, distance * progress / length); @@ -1076,10 +1076,13 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok float dist = FLT_MAX; float p[3]; float size = 0; + float mvalf[2]; BLI_freelistN(&sketch->depth_peels); sketch->depth_peels.first = sketch->depth_peels.last = NULL; + mvalf[0]= dd->mval[0]; + mvalf[1]= dd->mval[1]; peelObjectsContext(C, &sketch->depth_peels, dd->mval); if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) @@ -1712,7 +1715,7 @@ int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Strok { SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection"); float ray_start[3], ray_end[3]; - short mval[2]; + float mval[2]; isect->gesture_index = g_i; isect->before = s_i; @@ -1720,8 +1723,8 @@ int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Strok isect->stroke = stk; isect->lambda = lambda; - mval[0] = (short)(vi[0]); - mval[1] = (short)(vi[1]); + mval[0] = vi[0]; + mval[1] = vi[1]; viewline(ar, v3d, mval, ray_start, ray_end); LineIntersectLine( stk->points[s_i].p, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 144d29a4405..ed8d366ab8b 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -160,6 +160,8 @@ void EM_reveal_mesh(struct EditMesh *em); void EM_select_by_material(struct EditMesh *em, int index); void EM_deselect_by_material(struct EditMesh *em, int index); +void EM_automerge(struct Scene *scene, struct Object *obedit, int update); + /* editface.c */ struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index b88fe5a9d7a..fc0aa28a2c3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1469,12 +1469,15 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) { StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); - float *buffer; + float *buffer= NULL; int i; /* Restore the mesh before continuing with anchored stroke */ if((brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) { - buffer = buffer = ss->drawobject!=0?(float *)GPU_buffer_lock( ss->drawobject->normals ):0; + + if(ss->drawobject) + buffer= (float *)GPU_buffer_lock(ss->drawobject->normals); + for(i = 0; i < ss->totvert; ++i) { VecCopyf(ss->mvert[i].co, ss->mesh_co_orig[i]); ss->mvert[i].no[0] = cache->orig_norms[i][0]; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 20d136e4790..c8066f03abf 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -59,6 +59,7 @@ //#include "BIF_screen.h" //#include "BIF_mywindow.h" #include "BIF_gl.h" +#include "BIF_glutil.h" //#include "BIF_editmesh.h" //#include "BIF_editsima.h" //#include "BIF_editparticle.h" -- cgit v1.2.3 From 8f25c0a799ae19edab0eee928b9130b5017e1a74 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Oct 2009 08:55:11 +0000 Subject: moving textures up and down didnt move the material flag, made editmesh skin Ctrl+Alt+F --- source/blender/editors/mesh/mesh_ops.c | 1 + source/blender/editors/render/render_shading.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index eaaf76d7bc7..8c24dda4da7 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -258,6 +258,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) /* add/remove */ WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_skin", FKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); /* python */ WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 4a2c88f54a7..a9023194271 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -697,6 +697,16 @@ static int texture_slot_move(bContext *C, wmOperator *op) mtexswap = mtex_ar[act]; mtex_ar[act] = mtex_ar[act-1]; mtex_ar[act-1] = mtexswap; + + if(GS(id->name)==ID_MA) { + Material *ma= (Material *)id; + int mtexuse = ma->septex & (1<septex &= ~(1<septex |= (ma->septex & (1<<(act-1))) << 1; + ma->septex &= ~(1<<(act-1)); + ma->septex |= mtexuse >> 1; + } + set_active_mtex(id, act-1); } } @@ -705,6 +715,16 @@ static int texture_slot_move(bContext *C, wmOperator *op) mtexswap = mtex_ar[act]; mtex_ar[act] = mtex_ar[act+1]; mtex_ar[act+1] = mtexswap; + + if(GS(id->name)==ID_MA) { + Material *ma= (Material *)id; + int mtexuse = ma->septex & (1<septex &= ~(1<septex |= (ma->septex & (1<<(act+1))) >> 1; + ma->septex &= ~(1<<(act+1)); + ma->septex |= mtexuse << 1; + } + set_active_mtex(id, act+1); } } -- cgit v1.2.3 From f4d29269866a3bc4f9346bf24753d72da2456fc9 Mon Sep 17 00:00:00 2001 From: Andre Susano Pinto Date: Tue, 13 Oct 2009 10:52:18 +0000 Subject: Fix [#19602] Rayshadow that goes through transparent plane disappears (some bugs may show on other places if some of the code isnt prepared to handle non-normalized is->vec) --- source/blender/render/intern/raytrace/rayobject.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index d8880b51c6c..8aff7a38317 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -376,7 +376,6 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec) RE_RC_COUNT(isec->raycounter->raycast.test); /* Setup vars used on raycast */ - isec->labda *= Normalize(isec->vec); isec->dist = VecLength(isec->vec); for(i=0; i<3; i++) -- cgit v1.2.3 From de818dace53343a1fcbb03d8e535a77617c037fa Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 13 Oct 2009 11:21:02 +0000 Subject: DopeSheet: DopeSheet Summary Channel Added a summary channel that appears as the first channel in the DopeSheet. For now, this is disabled by default, but can be enabled using the 'Summary' toggle in the header between the mode selector and the standard filtering options. This has been done, since there is a possibility that it will make the DopeSheet run a bit slower. In this channel you can do everything that you can normally do with DopeSheet channels (i.e. select, transform, edit, etc). It might be worth noting though that care probably needs to be taken when trying to use Copy/Paste, since that is still a bit fidgety... In the process, I've fixed a few bugs, mostly with selection: - Selecting keyframes in scene summaries wouldn't work - Border select only worked in F-Curve and Group channels --- .../editors/animation/anim_channels_defines.c | 54 ++++++++++++++++++++++ source/blender/editors/animation/anim_filter.c | 29 +++++++++++- source/blender/editors/animation/keyframes_draw.c | 37 +++++++++++++++ source/blender/editors/animation/keyframes_edit.c | 44 ++++++++++++++++-- source/blender/editors/include/ED_anim_api.h | 6 +++ source/blender/editors/include/ED_keyframes_draw.h | 3 ++ source/blender/editors/space_action/action_draw.c | 10 ++++ .../blender/editors/space_action/action_header.c | 5 +- .../blender/editors/space_action/action_select.c | 36 +++++++++------ source/blender/makesdna/DNA_action_types.h | 1 + 10 files changed, 204 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 427fa47923f..a4423d43339 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -280,6 +280,12 @@ static void acf_generic_idblock_name(bAnimListElem *ale, char *name) /* Settings ------------------------------------------- */ +/* channel type has no settings */ +static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + return 0; +} + /* check if some setting exists for this object-based data-expander (category only) */ static short acf_generic_dsexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { @@ -335,6 +341,52 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle /* *********************************************** */ /* Type Specific Functions + Defines */ +/* Animation Summary ----------------------------------- */ + +/* backdrop for summary widget */ +static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + View2D *v2d= &ac->ar->v2d; + + // FIXME: hardcoded color - same as the 'action' line in NLA + glColor3f(0.8f, 0.2f, 0.0f); // reddish color + + /* rounded corners on LHS only + * - top and bottom + * - special hack: make the top a bit higher, since we are first... + */ + uiSetRoundBox((1|8)); + gl_round_box(GL_POLYGON, 0, yminc-2, v2d->cur.xmax+EXTRA_SCROLL_PAD, ymaxc, 8); +} + +/* name for summary entries */ +static void acf_summary_name(bAnimListElem *ale, char *name) +{ + if (name) + strcpy(name, "DopeSheet Summary"); +} + +// TODO: this is really a temp icon I think +static int acf_summary_icon(bAnimListElem *ale) +{ + return ICON_BORDERMOVE; +} + +/* all animation summary (DopeSheet only) type define */ +static bAnimChannelType ACF_SUMMARY = +{ + acf_summary_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + NULL, /* offset */ + + acf_summary_name, /* name */ + acf_summary_icon, /* icon */ + + acf_generic_none_setting_valid, /* has setting */ + NULL, /* flag for setting */ + NULL /* pointer for setting */ +}; + /* Scene ------------------------------------------- */ // TODO: just get this from RNA? @@ -1803,6 +1855,8 @@ void ANIM_init_channel_typeinfo_data (void) animchannelTypeInfo[type++]= NULL; /* AnimData */ animchannelTypeInfo[type++]= NULL; /* Special */ + animchannelTypeInfo[type++]= &ACF_SUMMARY; /* Motion Summary */ + animchannelTypeInfo[type++]= &ACF_SCENE; /* Scene */ animchannelTypeInfo[type++]= &ACF_OBJECT; /* Object */ animchannelTypeInfo[type++]= &ACF_GROUP; /* Group */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index fef910a85a3..7aba237ffb1 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -458,6 +458,16 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s /* do specifics */ switch (datatype) { + case ANIMTYPE_SUMMARY: + { + /* nothing to include for now... this is just a dummy wrappy around all the other channels + * in the DopeSheet, and gets included at the start of the list + */ + ale->key_data= NULL; + ale->datatype= ALE_ALL; + } + break; + case ANIMTYPE_SCENE: { Scene *sce= (Scene *)data; @@ -1497,7 +1507,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads } // TODO: implement pinning... (if and when pinning is done, what we need to do is to provide freeing mechanisms - to protect against data that was deleted) -static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int filter_mode) +static int animdata_filter_dopesheet (ListBase *anim_data, bAnimContext *ac, bDopeSheet *ads, int filter_mode) { Scene *sce= (Scene *)ads->source; Base *base; @@ -1510,6 +1520,21 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int return 0; } + /* dopesheet summary + * - only for drawing and/or selecting keyframes in channels, but not for real editing + * - only useful for DopeSheet Editor, where the summary is useful + */ + // TODO: we should really check if some other prohibited filters are also active, but that can be for later + if ((filter_mode & ANIMFILTER_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) { + ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, ANIMTYPE_NONE, NULL); + if (ale) { + BLI_addtail(anim_data, ale); + items++; + } + + // TODO: if the summary gets a collapse widget, then we could make the other stuff not get shown... + } + /* scene-linked animation */ // TODO: sequencer, composite nodes - are we to include those here too? { @@ -1898,7 +1923,7 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode case ANIMCONT_FCURVES: case ANIMCONT_DRIVERS: case ANIMCONT_NLA: - items= animdata_filter_dopesheet(anim_data, data, filter_mode); + items= animdata_filter_dopesheet(anim_data, ac, data, filter_mode); break; } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d0b5e12c9df..019ece64132 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -515,6 +515,24 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* *************************** Channel Drawing Funcs *************************** */ +void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos) +{ + DLRBT_Tree keys, blocks; + + BLI_dlrbTree_init(&keys); + BLI_dlrbTree_init(&blocks); + + summary_to_keylist(ac, &keys, &blocks); + + BLI_dlrbTree_linkedlist_sync(&keys); + BLI_dlrbTree_linkedlist_sync(&blocks); + + draw_keylist(v2d, &keys, &blocks, ypos); + + BLI_dlrbTree_free(&keys); + BLI_dlrbTree_free(&blocks); +} + void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos) { DLRBT_Tree keys, blocks; @@ -622,6 +640,25 @@ void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos) /* *************************** Keyframe List Conversions *************************** */ +void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks) +{ + if (ac) { + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* get F-Curves to take keyframes from */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* loop through each F-Curve, grabbing the keyframes */ + for (ale= anim_data.first; ale; ale= ale->next) + fcurve_to_keylist(ale->adt, ale->data, keys, blocks); + + BLI_freelistN(&anim_data); + } +} + void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree *blocks) { if (sce) { diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 7f0d3b4503d..3b2830e9045 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -310,16 +310,48 @@ static short scene_keys_bezier_loop(BeztEditData *bed, Scene *sce, BeztEditFunc return 0; /* Scene's own animation */ - if (sce->adt) - adt_keys_bezier_loop(bed, sce->adt, bezt_ok, bezt_cb, fcu_cb, filterflag); + if (sce->adt) { + if (adt_keys_bezier_loop(bed, sce->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } /* World */ - if (wo && wo->adt) - adt_keys_bezier_loop(bed, wo->adt, bezt_ok, bezt_cb, fcu_cb, filterflag); + if (wo && wo->adt) { + if (adt_keys_bezier_loop(bed, wo->adt, bezt_ok, bezt_cb, fcu_cb, filterflag)) + return 1; + } return 0; } +/* This function is used to loop over the keyframe data in a DopeSheet summary */ +static short summary_keys_bezier_loop(BeztEditData *bed, bAnimContext *ac, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, FcuEditFunc fcu_cb, int filterflag) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter, ret_code=0; + + /* sanity check */ + if (ac == NULL) + return 0; + + /* get F-Curves to take keyframes from */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* loop through each F-Curve, working on the keyframes until the first curve aborts */ + for (ale= anim_data.first; ale; ale= ale->next) { + ret_code= ANIM_fcurve_keys_bezier_loop(bed, ale->data, bezt_ok, bezt_cb, fcu_cb); + + if (ret_code) + break; + } + + BLI_freelistN(&anim_data); + + return ret_code; +} + /* --- */ /* This function is used to apply operation to all keyframes, regardless of the type */ @@ -347,6 +379,8 @@ short ANIM_animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, B return ob_keys_bezier_loop(bed, (Object *)ale->key_data, bezt_ok, bezt_cb, fcu_cb, filterflag); case ALE_SCE: /* scene */ return scene_keys_bezier_loop(bed, (Scene *)ale->data, bezt_ok, bezt_cb, fcu_cb, filterflag); + case ALE_ALL: /* 'all' (DopeSheet summary) */ + return summary_keys_bezier_loop(bed, (bAnimContext *)ale->data, bezt_ok, bezt_cb, fcu_cb, filterflag); } return 0; @@ -377,6 +411,8 @@ short ANIM_animchanneldata_keys_bezier_loop(BeztEditData *bed, void *data, int k return ob_keys_bezier_loop(bed, (Object *)data, bezt_ok, bezt_cb, fcu_cb, filterflag); case ALE_SCE: /* scene */ return scene_keys_bezier_loop(bed, (Scene *)data, bezt_ok, bezt_cb, fcu_cb, filterflag); + case ALE_ALL: /* 'all' (DopeSheet summary) */ + return summary_keys_bezier_loop(bed, (bAnimContext *)data, bezt_ok, bezt_cb, fcu_cb, filterflag); } return 0; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 97f4dd915e4..271827c2aba 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -122,6 +122,8 @@ typedef enum eAnim_ChannelType { ANIMTYPE_ANIMDATA, ANIMTYPE_SPECIALDATA, + ANIMTYPE_SUMMARY, + ANIMTYPE_SCENE, ANIMTYPE_OBJECT, ANIMTYPE_GROUP, @@ -161,6 +163,7 @@ typedef enum eAnim_KeyType { ALE_GPFRAME, /* Grease Pencil Frames */ ALE_NLASTRIP, /* NLA Strips */ + ALE_ALL, /* All channels summary */ ALE_SCE, /* Scene summary */ ALE_OB, /* Object summary */ ALE_ACT, /* Action summary */ @@ -184,6 +187,9 @@ typedef enum eAnimFilter_Flags { ANIMFILTER_ANIMDATA = (1<<9), /* only return the underlying AnimData blocks (not the tracks, etc.) data comes from */ ANIMFILTER_NLATRACKS = (1<<10), /* only include NLA-tracks */ ANIMFILTER_SELEDIT = (1<<11), /* link editability with selected status */ + + /* all filters - the power inside the bracket must be the last power for left-shifts + 1 */ + ANIMFILTER_ALLFILTERS = ((1<<12) - 1) } eAnimFilter_Flags; diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 51d7c664fba..699502eb9eb 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -30,6 +30,7 @@ #ifndef ED_KEYFRAMES_DRAW_H #define ED_KEYFRAMES_DRAW_H +struct bAnimContext; struct AnimData; struct BezTriple; struct FCurve; @@ -109,6 +110,7 @@ void draw_agroup_channel(struct View2D *v2d, struct AnimData *adt, struct bActio void draw_action_channel(struct View2D *v2d, struct AnimData *adt, struct bAction *act, float ypos); void draw_object_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Object *ob, float ypos); void draw_scene_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Scene *sce, float ypos); +void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypos); void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos); /* Keydata Generation */ @@ -117,6 +119,7 @@ void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct D void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); +void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); /* Keyframe Finding */ diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 4288cc10a26..7181a6b5aa1 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -260,6 +260,13 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET)) { switch (ale->type) { + case ANIMTYPE_SUMMARY: + { + // FIXME: hardcoded colours - reddish color from NLA + glColor4f(0.8f, 0.2f, 0.0f, 0.4f); + } + break; + case ANIMTYPE_SCENE: case ANIMTYPE_OBJECT: { @@ -351,6 +358,9 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) /* draw 'keyframes' for each specific datatype */ switch (ale->datatype) { + case ALE_ALL: + draw_summary_channel(v2d, ale->data, y); + break; case ALE_SCE: draw_scene_channel(v2d, ads, ale->key_data, y); break; diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index e0d952c29c1..2468bdf311c 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -331,8 +331,11 @@ void action_header_buttons(const bContext *C, ARegion *ar) /* MODE-DEPENDENT DRAWING */ if (saction->mode == SACTCONT_DOPESHEET) { /* FILTERING OPTIONS */ - xco -= 10; + /* DopeSheet summary... */ + uiDefIconTextButBitI(block, TOG, ADS_FILTER_SUMMARY, B_REDR, ICON_BORDERMOVE, "Summary", xco,yco,XIC*4,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Include DopeSheet summary row"); // TODO: needs a better icon + xco += (XIC*3.5); + /* Standard filtering... */ xco= ANIM_headerUI_standard_buttons(C, &saction->ads, block, xco, yco); } else if (saction->mode == SACTCONT_ACTION) { diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index e358f559b14..c945f41bc55 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -219,7 +219,7 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - int filter; + int filter, filterflag; BeztEditData bed; BeztEditFunc ok_cb, select_cb; @@ -235,6 +235,14 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + /* get filtering flag for dopesheet data (if applicable) */ + if (ac->datatype == ANIMCONT_DOPESHEET) { + bDopeSheet *ads= (bDopeSheet *)ac->data; + filterflag= ads->filterflag; + } + else + filterflag= 0; + /* get beztriple editing/validation funcs */ select_cb= ANIM_editkeyframes_select(selectmode); @@ -271,20 +279,10 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short !((ymax < rectf.ymin) || (ymin > rectf.ymax)) ) { /* loop over data selecting */ - if (ale->key_data) { - if (ale->datatype == ALE_FCURVE) - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - } - else if (ale->type == ANIMTYPE_GROUP) { - bActionGroup *agrp= ale->data; - FCurve *fcu; - - for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) - ANIM_fcurve_keys_bezier_loop(&bed, fcu, ok_cb, select_cb, NULL); - } - //else if (ale->type == ANIMTYPE_GPLAYER) { + //if (ale->type == ANIMTYPE_GPLAYER) // borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode); - //} + //else + ANIM_animchannel_keys_bezier_loop(&bed, ale, ok_cb, select_cb, NULL, filterflag); } /* set minimum extent to be the maximum of the next channel */ @@ -792,6 +790,12 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, if (ale->key_data) { switch (ale->datatype) { + case ALE_SCE: + { + Scene *scene= (Scene *)ale->key_data; + scene_to_keylist(ads, scene, &anim_keys, NULL); + } + break; case ALE_OB: { Object *ob= (Object *)ale->key_data; @@ -812,6 +816,10 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, break; } } + else if (ale->type == ANIMTYPE_SUMMARY) { + /* dopesheet summary covers everything */ + summary_to_keylist(ac, &anim_keys, NULL); + } else if (ale->type == ANIMTYPE_GROUP) { bActionGroup *agrp= (bActionGroup *)ale->data; agroup_to_keylist(adt, agrp, &anim_keys, NULL); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index e2eb13f0bdf..a011ba87948 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -422,6 +422,7 @@ typedef enum DOPESHEET_FILTERFLAG { ADS_FILTER_ONLYDRIVERS = (1<<1), /* for 'Drivers' editor - only include Driver data from AnimData */ ADS_FILTER_ONLYNLA = (1<<2), /* for 'NLA' editor - only include NLA data from AnimData */ ADS_FILTER_SELEDIT = (1<<3), /* for Graph Editor - used to indicate whether to include a filtering flag or not */ + ADS_FILTER_SUMMARY = (1<<4), /* for 'DopeSheet' Editor - include 'summary' line */ /* datatype-based filtering */ ADS_FILTER_NOSHAPEKEYS = (1<<6), -- cgit v1.2.3 From d3ebd621394d9bf79a21c1a9460905f606cff8eb Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 13 Oct 2009 11:32:03 +0000 Subject: Animation Editors: Filtering buttons Cleanup The filtering buttons for datatypes will now only be shown if there is data of that type present in the current file. They will still be shown in the same order, but by hiding the ones that won't be of any relevance, the presentation of the views should be cleaner (I hope ;) --- source/blender/editors/animation/anim_draw.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 507bf03e7ef..9863006308e 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -48,6 +48,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_fcurve.h" +#include "BKE_main.h" #include "BKE_nla.h" #include "BKE_object.h" #include "BKE_screen.h" @@ -325,6 +326,7 @@ void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, s /* standard header buttons for Animation Editors */ short ANIM_headerUI_standard_buttons (const bContext *C, bDopeSheet *ads, uiBlock *block, short xco, short yco) { + Main *mainptr= CTX_data_main(C); ScrArea *sa= CTX_wm_area(C); short nlaActive= ((sa) && (sa->spacetype==SPACE_NLA)); @@ -337,19 +339,27 @@ short ANIM_headerUI_standard_buttons (const bContext *C, bDopeSheet *ads, uiBloc if (nlaActive) uiBlockEndAlign(block); xco += 5; - /* datatype based */ + /* datatype based - only available datatypes are shown */ // TODO: only show the datablocks which exist uiBlockBeginAlign(block); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Scene Animation"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display World Animation"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Material Data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Lamp Data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Camera Data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Curve Data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display MetaBall Data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Armature Data"); - uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Particle Data"); + if (mainptr && mainptr->key.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSHAPEKEYS, B_REDR, ICON_SHAPEKEY_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display ShapeKeys"); + if (mainptr && mainptr->mat.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMAT, B_REDR, ICON_MATERIAL_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Material Data"); + if (mainptr && mainptr->lamp.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOLAM, B_REDR, ICON_LAMP_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Lamp Data"); + if (mainptr && mainptr->camera.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCAM, B_REDR, ICON_CAMERA_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Camera Data"); + if (mainptr && mainptr->curve.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOCUR, B_REDR, ICON_CURVE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Curve Data"); + if (mainptr && mainptr->mball.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOMBA, B_REDR, ICON_META_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display MetaBall Data"); + if (mainptr && mainptr->armature.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOARM, B_REDR, ICON_ARMATURE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Armature Data"); + if (mainptr && mainptr->particle.first) + uiDefIconButBitI(block, TOGN, ADS_FILTER_NOPART, B_REDR, ICON_PARTICLE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Particle Data"); uiBlockEndAlign(block); xco += 30; } -- cgit v1.2.3 From bdbae465190c99d5f9f4742f0c4cccc35fb8ea46 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 13 Oct 2009 12:09:11 +0000 Subject: Armature Ghosting Bugfix: I noticed that armature drawing seemed to be using the wrong colours for ghosting in some situations (in particular, Cessen's biped rig for 2.5). Commented out what appears to be the offending code for now. Not totally sure why this broke yet, but as possible bonus of this, we sometimes get coloured ghosted controls (if bone groups were in use). --- source/blender/editors/space_view3d/drawarmature.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 028d666dc71..26135cd8d31 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1654,6 +1654,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *bas /* prepare colors */ if (arm->flag & ARM_POSEMODE) set_pchan_colorset(ob, pchan); +#if 0 // XXX - 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) else { if ((scene->basact)==base) { if (base->flag & (SELECT+BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); @@ -1664,6 +1665,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *bas else UI_ThemeColor(TH_WIRE); } } +#endif /* catch exception for bone with hidden parent */ flag= bone->flag; @@ -1755,7 +1757,7 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *bas /* extra draw service for pose mode */ constflag= pchan->constflag; - if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) // XXX this is useless crap + if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) constflag |= PCHAN_HAS_ACTION; if (pchan->flag & POSE_STRIDE) constflag |= PCHAN_HAS_STRIDE; -- cgit v1.2.3 From edfe78aec90a679a5e95ca479192f6f9ecab7ff0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Oct 2009 15:30:19 +0000 Subject: Context operators for adjusting context values directly to avoid adding operators for adjusting single values which also need duplicate notifiers. wm.context_set(path="scene.tool_settings.someattr", somevalue) wm.context_toggle(path="scene.tool_settings.somebool") wm.context_toggle_values(path="scene.tool_settings.some_enum", value_1="somevalue", value_2="othervalue") # switch between 2 values wm.context_cycle_enum(path="scene.tool_settings.some_enum", reverse=False) the path value is taken from the context so the full path is context.scene.tool_settings... This means in keymaps you can cycle draw modes, change PET- anything with rna access. If its not so nice to map keys to operators like wm.context_set we could use macro's to wrap it and have its own name Use this for PET and setting pivot options - Made userpref key shortcut Ctrl+Alt+U since its not used in 2.4x - added pivot_point_align (Alt+Comma) - added PET wasnt rna wrapped correctly. --- release/scripts/modules/bpy_ops.py | 96 +++++++++++++++++++++- source/blender/editors/curve/curve_ops.c | 2 + source/blender/editors/include/ED_object.h | 3 + source/blender/editors/mesh/mesh_ops.c | 2 + source/blender/editors/object/object_ops.c | 23 ++++++ source/blender/editors/physics/particle_edit.c | 2 +- source/blender/editors/screen/screen_ops.c | 5 +- source/blender/editors/space_view3d/view3d_ops.c | 25 ++++++ .../blender/editors/transform/transform_generics.c | 4 +- source/blender/editors/uvedit/uvedit_ops.c | 2 + source/blender/makesdna/DNA_scene_types.h | 5 ++ source/blender/makesrna/intern/rna_scene.c | 13 ++- source/blender/makesrna/intern/rna_space.c | 5 ++ 13 files changed, 177 insertions(+), 10 deletions(-) diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py index 834a33d305d..b1d782917b6 100644 --- a/release/scripts/modules/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py @@ -145,7 +145,7 @@ bpy.ops = bpy_ops() class MESH_OT_delete_edgeloop(bpy.types.Operator): '''Export a single object as a stanford PLY with normals, colours and texture coordinates.''' __idname__ = "mesh.delete_edgeloop" - __label__ = "Export PLY" + __label__ = "Delete Edge Loop" def execute(self, context): bpy.ops.tfm.edge_slide(value=1.0) @@ -153,6 +153,100 @@ class MESH_OT_delete_edgeloop(bpy.types.Operator): bpy.ops.mesh.remove_doubles() return ('FINISHED',) +class WM_OT_context_set(bpy.types.Operator): + '''Set a context value.''' + __idname__ = "wm.context_set" + __label__ = "Context Set" + __register__ = True + __undo__ = True + + __props__ = [ + bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="value", name="Value", description="Assignment value (as a string)", maxlen= 1024, default= "") + ] + + def execute(self, context): + exec("context.%s=%s" % (self.path, self.value)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_toggle(bpy.types.Operator): + '''Toggle a context value.''' + __idname__ = "wm.context_toggle" + __label__ = "Context Toggle" + __register__ = True + __undo__ = True + + __props__ = [ + bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), + ] + + def execute(self, context): + exec("context.%s=not (context.%s)" % (self.path, self.path)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_toggle_values(bpy.types.Operator): + '''Toggle a context value.''' + __idname__ = "wm.context_toggle_values" + __label__ = "Context Toggle Values" + __register__ = True + __undo__ = True + + __props__ = [ + bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="value_1", name="Value", description="Toggle value (as a string)", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="value_2", name="Value", description="Toggle value (as a string)", maxlen= 1024, default= "") + ] + + def execute(self, context): + exec("context.%s = [%s, %s][context.%s!=%s]" % (self.path, self.value_1, self.value_2, self.path, self.value_2)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_cycle_enum(bpy.types.Operator): + '''Toggle a context value.''' + __idname__ = "wm.context_cycle_enum" + __label__ = "Context Toggle Values" + __register__ = True + __undo__ = True + + __props__ = [ + bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), + bpy.props.BoolProperty(attr="reverse", name="Reverse", description="Cycle backwards", default= False) + ] + + def execute(self, context): + orig_value = eval("context.%s" % self.path) # security nuts will complain. + + # Have to get rna enum values + rna_struct_str, rna_prop_str = self.path.rsplit('.', 1) + i = rna_prop_str.find('[') + if i != -1: rna_prop_str = rna_prop_str[0:i] # just incse we get "context.foo.bar[0]" + + rna_struct = eval("context.%s.rna_type" % rna_struct_str) + + rna_prop = rna_struct.properties[rna_prop_str] + + if type(rna_prop) != bpy.types.EnumProperty: + raise Exception("expected an enum property") + + enums = rna_struct.properties[rna_prop_str].items.keys() + orig_index = enums.index(orig_value) + + # Have the info we need, advance to the next item + if self.reverse: + if orig_index==0: advance_enum = enums[-1] + else: advance_enum = enums[orig_index-1] + else: + if orig_index==len(enums)-1: advance_enum = enums[0] + else: advance_enum = enums[orig_index+1] + + # set the new value + exec("context.%s=advance_enum" % self.path) + return ('FINISHED',) bpy.ops.add(MESH_OT_delete_edgeloop) +bpy.ops.add(WM_OT_context_set) +bpy.ops.add(WM_OT_context_toggle) +bpy.ops.add(WM_OT_context_toggle_values) +bpy.ops.add(WM_OT_context_cycle_enum) + diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index a71ff8347e8..929e3514990 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -248,5 +248,7 @@ void ED_keymap_curve(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "unselected", 1); WM_keymap_add_item(keymap, "CURVE_OT_specials_menu", WKEY, KM_PRESS, 0, 0); + + ED_object_generic_keymap(keyconf, keymap, TRUE); } diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index e19fc806404..3d0d776f549 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -47,6 +47,9 @@ void ED_operatortypes_object(void); void ED_operatormacros_object(void); void ED_keymap_object(struct wmKeyConfig *keyconf); +/* generic editmode keys like pet */ +void ED_object_generic_keymap(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int do_pet); + /* send your own notifier for select! */ void ED_base_object_select(struct Base *base, short mode); /* includes notifier */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 8c24dda4da7..3a3e4f54915 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -291,5 +291,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) /* UV's */ WM_keymap_add_item(keymap, "UV_OT_mapping_menu", UKEY, KM_PRESS, 0, 0); + + ED_object_generic_keymap(keyconf, keymap, TRUE); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9869d15a69c..4f9a3d22f3b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -273,3 +273,26 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "LATTICE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); } +void ED_object_generic_keymap(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int do_pet) +{ + wmKeyMapItem *km; + + /* used by mesh, curve & lattice only */ + if(do_pet) { + /* context ops */ + km = WM_keymap_add_item(keymap, "WM_OT_context_cycle_enum", OKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "scene.tool_settings.proportional_editing_falloff"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", OKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "scene.tool_settings.proportional_editing"); + RNA_string_set(km->ptr, "value_1", "'DISABLED'"); + RNA_string_set(km->ptr, "value_2", "'ENABLED'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", OKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(km->ptr, "path", "scene.tool_settings.proportional_editing"); + RNA_string_set(km->ptr, "value_1", "'DISABLED'"); + RNA_string_set(km->ptr, "value_2", "'CONNECTED'"); + } + +} + diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index e3f54158fbb..d4a180e2427 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2908,7 +2908,7 @@ static void brush_add(PEData *data, short number) ParticleSimulationData sim = {scene, ob, psys, psmd}; ParticleEditSettings *pset= PE_settings(scene); int i, k, n= 0, totpart= psys->totpart; - short mco[2]; + float mco[2]; short dmx= 0, dmy= 0; float co1[3], co2[3], min_d, imat[4][4]; float framestep, timestep= psys_get_timestep(&sim); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index e160b85e233..74303e8a6a3 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3410,10 +3410,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_render_view_show", F11KEY, KM_PRESS, 0, 0); /* user prefs */ - #ifdef __APPLE__ - WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_OSKEY, 0); - #endif - WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", UKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); /* Anim Playback ------------------------------------------------ */ diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 74074a04188..758bf803fb8 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -221,6 +221,31 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0); + /* context ops */ + km = WM_keymap_add_item(keymap, "WM_OT_context_set", COMMAKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "'BOUNDING_BOX_CENTER'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", COMMAKEY, KM_PRESS, KM_CTRL, 0); /* 2.4x allowed Comma+Shift too, rather not use both */ + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "'MEDIAN_POINT'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", COMMAKEY, KM_PRESS, KM_ALT, 0); /* new in 2.5 */ + RNA_string_set(km->ptr, "path", "space_data.pivot_point_align"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", PERIODKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "'CURSOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", PERIODKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "'INDIVIDUAL_CENTERS'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", PERIODKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(km->ptr, "path", "space_data.pivot_point"); + RNA_string_set(km->ptr, "value", "'ACTIVE_ELEMENT'"); + + transform_keymap_for_space(keyconf, keymap, SPACE_VIEW3D); fly_modal_keymap(keyconf); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index c8066f03abf..5fe9db3915f 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -995,10 +995,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } else { - if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) { + if ((t->options & CTX_NO_PET) == 0 && (ts->proportional != PROP_EDIT_OFF)) { t->flag |= T_PROP_EDIT; - if(ts->proportional == 2) + if(ts->proportional == PROP_EDIT_CONNECTED) t->flag |= T_PROP_CONNECTED; // yes i know, has to become define } } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 0f79420d3a7..9b3cb581c88 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -3129,6 +3129,8 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "UV_OT_tile_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0); + ED_object_generic_keymap(keyconf, keymap, TRUE); + transform_keymap_for_space(keyconf, keymap, SPACE_IMAGE); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index e069136d46a..d2e88408f6b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1016,6 +1016,11 @@ typedef struct Scene { #define PROP_CONST 5 #define PROP_RANDOM 6 +/* toolsettings->proportional */ +#define PROP_EDIT_OFF 0 +#define PROP_EDIT_ON 1 +#define PROP_EDIT_CONNECTED 2 + /* sce->flag */ #define SCE_DS_SELECTED (1<<0) #define SCE_DS_COLLAPSED (1<<1) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 29fb9e4deb2..7831f6acd11 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -502,6 +502,12 @@ static void rna_def_tool_settings(BlenderRNA *brna) {AUTOKEY_MODE_EDITKEYS, "REPLACE_KEYS", 0, "Replace", ""}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem proportional_editing_items[] = { + {PROP_EDIT_OFF, "DISABLED", 0, "Disable", ""}, + {PROP_EDIT_ON, "ENABLED", 0, "Enable", ""}, + {PROP_EDIT_CONNECTED, "CONNECTED", 0, "Connected", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "ToolSettings", NULL); RNA_def_struct_ui_text(srna, "Tool Settings", ""); @@ -526,14 +532,17 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Particle Edit", ""); /* Transform */ - prop= RNA_def_property(srna, "proportional_editing", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "proportional", 0); + prop= RNA_def_property(srna, "proportional_editing", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "proportional"); + RNA_def_property_enum_items(prop, proportional_editing_items); RNA_def_property_ui_text(prop, "Proportional Editing", "Proportional editing mode."); + RNA_def_property_update(prop, NC_SCENE|ND_MODE, NULL); /* header redraw */ prop= RNA_def_property(srna, "proportional_editing_falloff", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "prop_mode"); RNA_def_property_enum_items(prop, prop_mode_items); RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); + RNA_def_property_update(prop, NC_SCENE|ND_MODE, NULL); /* header redraw */ prop= RNA_def_property(srna, "normal_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "normalsize"); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 99ee3e653f0..7d77660db6d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -766,6 +766,11 @@ static void rna_def_space_3dview(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + prop= RNA_def_property(srna, "pivot_point_align", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ALIGN); + RNA_def_property_ui_text(prop, "Align", "Manipulate object centers only."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + prop= RNA_def_property(srna, "manipulator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "twflag", V3D_USE_MANIPULATOR); RNA_def_property_ui_text(prop, "Manipulator", "Use a 3D manipulator widget for controlling transforms."); -- cgit v1.2.3 From 46364383948e8e550238c93d3fc7629c5e66ad9b Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 13 Oct 2009 16:05:57 +0000 Subject: Enable snapping for curve edit mode. It's still not possible to snap TO a curve, but at least curves control points can be snapped (or projected) to mesh geometry. --- source/blender/editors/transform/transform_snap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 0e3f999d47b..6cfffd1ade7 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -115,7 +115,7 @@ int BIF_snappingSupported(Object *obedit) { int status = 0; - if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE)) /* only support object mesh or armature */ + if (obedit == NULL || ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) /* only support object mesh, armature, curves */ { status = 1; } @@ -393,7 +393,7 @@ void initSnapping(TransInfo *t, wmOperator *op) /* Edit mode */ if (t->tsnap.applySnap != NULL && // A snapping function actually exist (snapping) && // Only if the snap flag is on - (obedit != NULL && ELEM(obedit->type, OB_MESH, OB_ARMATURE)) ) // Temporary limited to edit mode meshes or armature + (obedit != NULL && ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) ) // Temporary limited to edit mode meshes, armature, curves { t->tsnap.status |= SNAP_ON; t->tsnap.modePoint = SNAP_GEO; -- cgit v1.2.3 From db763fc4459c327d84849cd34bde4a82d74a7123 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 13 Oct 2009 16:08:02 +0000 Subject: - Identify and use retopo icon from icons image. - Reuse proportional edit enums between rna scene and transform operator --- source/blender/editors/include/UI_icons.h | 2 +- source/blender/editors/space_view3d/view3d_header.c | 2 +- source/blender/editors/transform/transform_ops.c | 12 ++---------- source/blender/makesrna/RNA_enum_types.h | 3 ++- source/blender/makesrna/intern/rna_scene.c | 20 ++++++++++---------- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index c0aba90f90f..50f838b8745 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -685,7 +685,7 @@ DEF_ICON(ICON_BLANK230) DEF_ICON(ICON_BLANK231) DEF_ICON(ICON_BLANK232) DEF_ICON(ICON_BLANK233) -DEF_ICON(ICON_BLANK234) +DEF_ICON(ICON_RETOPO) DEF_ICON(ICON_UV_VERTEXSEL) DEF_ICON(ICON_UV_EDGESEL) DEF_ICON(ICON_UV_FACESEL) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 8dcc8791d88..c0a0241c74c 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -2145,7 +2145,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) xco+= XIC; } if (ts->snap_mode == SCE_SNAP_MODE_FACE) { - uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_ROTATECOLLECTION,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them"); + uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_RETOPO,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them"); xco+= XIC; } uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 3408f6cf3f7..5173245734b 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -55,14 +55,6 @@ typedef struct TransformModeItem static float VecOne[3] = {1, 1, 1}; -/* need constants for this */ -EnumPropertyItem proportional_mode_types[] = { - {0, "OFF", 0, "Off", ""}, - {1, "ON", 0, "On", ""}, - {2, "CONNECTED", 0, "Connected", ""}, - {0, NULL, 0, NULL, NULL} -}; - char OP_TRANSLATION[] = "TFM_OT_translate"; char OP_ROTATION[] = "TFM_OT_rotate"; char OP_TOSPHERE[] = "TFM_OT_tosphere"; @@ -341,8 +333,8 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event) void Properties_Proportional(struct wmOperatorType *ot) { - RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Editing", ""); - RNA_def_enum(ot->srna, "proportional_editing_falloff", prop_mode_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); + RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", ""); + RNA_def_enum(ot->srna, "proportional_editing_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100); } diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 4db76c7f312..f102143f0ed 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -31,7 +31,8 @@ extern EnumPropertyItem object_mode_items[]; -extern EnumPropertyItem prop_mode_items[]; +extern EnumPropertyItem proportional_falloff_items[]; +extern EnumPropertyItem proportional_editing_items[]; extern EnumPropertyItem snap_mode_items[]; extern EnumPropertyItem space_type_items[]; extern EnumPropertyItem region_type_items[]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7831f6acd11..d254c7c9eee 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -51,7 +51,7 @@ EnumPropertyItem snap_mode_items[] = { {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."}, {0, NULL, 0, NULL, NULL}}; -EnumPropertyItem prop_mode_items[] ={ +EnumPropertyItem proportional_falloff_items[] ={ {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""}, {PROP_SPHERE, "SPHERE", 0, "Sphere", ""}, {PROP_ROOT, "ROOT", 0, "Root", ""}, @@ -61,7 +61,13 @@ EnumPropertyItem prop_mode_items[] ={ {PROP_RANDOM, "RANDOM", 0, "Random", ""}, {0, NULL, 0, NULL, NULL}}; - + +EnumPropertyItem proportional_editing_items[] = { + {PROP_EDIT_OFF, "DISABLED", 0, "Disable", ""}, + {PROP_EDIT_ON, "ENABLED", 0, "Enable", ""}, + {PROP_EDIT_CONNECTED, "CONNECTED", 0, "Connected", ""}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" @@ -502,12 +508,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) {AUTOKEY_MODE_EDITKEYS, "REPLACE_KEYS", 0, "Replace", ""}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem proportional_editing_items[] = { - {PROP_EDIT_OFF, "DISABLED", 0, "Disable", ""}, - {PROP_EDIT_ON, "ENABLED", 0, "Enable", ""}, - {PROP_EDIT_CONNECTED, "CONNECTED", 0, "Connected", ""}, - {0, NULL, 0, NULL, NULL}}; - srna= RNA_def_struct(brna, "ToolSettings", NULL); RNA_def_struct_ui_text(srna, "Tool Settings", ""); @@ -540,7 +540,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "proportional_editing_falloff", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "prop_mode"); - RNA_def_property_enum_items(prop, prop_mode_items); + RNA_def_property_enum_items(prop, proportional_falloff_items); RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); RNA_def_property_update(prop, NC_SCENE|ND_MODE, NULL); /* header redraw */ @@ -583,7 +583,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "snap_project", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT); RNA_def_property_ui_text(prop, "Project Individual Elements", "DOC_BROKEN"); - RNA_def_property_ui_icon(prop, ICON_ROTATECOLLECTION, 0); + RNA_def_property_ui_icon(prop, ICON_RETOPO, 0); /* Auto Keying */ prop= RNA_def_property(srna, "enable_auto_key", PROP_BOOLEAN, PROP_NONE); -- cgit v1.2.3 From 52f1ed4db883f4160d7f67e038e28b48d17995d4 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 13 Oct 2009 16:08:34 +0000 Subject: Rename all enums called "prop_mode_items" into something more sensible. --- source/blender/makesrna/intern/rna_fcurve.c | 4 ++-- source/blender/makesrna/intern/rna_modifier.c | 12 ++++++------ source/blender/makesrna/intern/rna_sculpt_paint.c | 4 ++-- source/blender/windowmanager/intern/wm_operators.c | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 2802665c639..ba68f8e1624 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -157,7 +157,7 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_mode_items[] = { + static EnumPropertyItem generator_mode_items[] = { {FCM_GENERATOR_POLYNOMIAL, "POLYNOMIAL", 0, "Expanded Polynomial", ""}, {FCM_GENERATOR_POLYNOMIAL_FACTORISED, "POLYNOMIAL_FACTORISED", 0, "Factorised Polynomial", ""}, {0, NULL, 0, NULL, NULL}}; @@ -174,7 +174,7 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna) // XXX this has a special validation func prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_mode_items); + RNA_def_property_enum_items(prop, generator_mode_items); RNA_def_property_ui_text(prop, "Mode", "Type of generator to use."); RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index b04f0a865ef..09d80e75a49 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1694,7 +1694,7 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_mode_items[] = { + static EnumPropertyItem shrink_type_items[] = { {MOD_SHRINKWRAP_NEAREST_SURFACE, "NEAREST_SURFACEPOINT", 0, "Nearest Surface Point", ""}, {MOD_SHRINKWRAP_PROJECT, "PROJECT", 0, "Project", ""}, {MOD_SHRINKWRAP_NEAREST_VERTEX, "NEAREST_VERTEX", 0, "Nearest Vertex", ""}, @@ -1707,7 +1707,7 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "shrinkType"); - RNA_def_property_enum_items(prop, prop_mode_items); + RNA_def_property_enum_items(prop, shrink_type_items); RNA_def_property_ui_text(prop, "Mode", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -1806,7 +1806,7 @@ static void rna_def_modifier_mask(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_mode_items[] = { + static EnumPropertyItem modifier_mask_mode_items[] = { {MOD_MASK_MODE_VGROUP, "VERTEX_GROUP", 0, "Vertex Group", ""}, {MOD_MASK_MODE_ARM, "ARMATURE", 0, "Armature", ""}, {0, NULL, 0, NULL, NULL}}; @@ -1817,7 +1817,7 @@ static void rna_def_modifier_mask(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_mode_items); + RNA_def_property_enum_items(prop, modifier_mask_mode_items); RNA_def_property_ui_text(prop, "Mode", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -1845,7 +1845,7 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_mode_items[] = { + static EnumPropertyItem simple_deform_mode_items[] = { {MOD_SIMPLEDEFORM_MODE_TWIST, "TWIST", 0, "Twist", ""}, {MOD_SIMPLEDEFORM_MODE_BEND, "BEND", 0, "Bend", ""}, {MOD_SIMPLEDEFORM_MODE_TAPER, "TAPER", 0, "Taper", ""}, @@ -1858,7 +1858,7 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_MOD_SIMPLEDEFORM); prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_mode_items); + RNA_def_property_enum_items(prop, simple_deform_mode_items); RNA_def_property_ui_text(prop, "Mode", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index ab4b27cea7b..413f7c3dc7c 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -231,7 +231,7 @@ static void rna_def_vertex_paint(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_mode_items[] = { + static EnumPropertyItem brush_mode_items[] = { {0, "MIX", 0, "Mix", "Use mix blending mode while painting."}, {1, "ADD", 0, "Add", "Use add blending mode while painting."}, {2, "SUB", 0, "Subtract", "Use subtract blending mode while painting."}, @@ -246,7 +246,7 @@ static void rna_def_vertex_paint(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Vertex Paint", "Properties of vertex and weight paint mode."); prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_mode_items); + RNA_def_property_enum_items(prop, brush_mode_items); RNA_def_property_ui_text(prop, "Brush Mode", "Mode in which color is painted."); prop= RNA_def_property(srna, "all_faces", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 99872f92f0f..e3f23a488a2 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2013,7 +2013,7 @@ void WM_radial_control_string(wmOperator *op, char str[], int maxlen) just sets up the common parts of the radial control op. **/ void WM_OT_radial_control_partial(wmOperatorType *ot) { - static EnumPropertyItem prop_mode_items[] = { + static EnumPropertyItem radial_mode_items[] = { {WM_RADIALCONTROL_SIZE, "SIZE", 0, "Size", ""}, {WM_RADIALCONTROL_STRENGTH, "STRENGTH", 0, "Strength", ""}, {WM_RADIALCONTROL_ANGLE, "ANGLE", 0, "Angle", ""}, @@ -2026,7 +2026,7 @@ void WM_OT_radial_control_partial(wmOperatorType *ot) RNA_def_float(ot->srna, "new_value", 0, 0, FLT_MAX, "New Value", "", 0, FLT_MAX); /* Should be set before calling operator */ - RNA_def_enum(ot->srna, "mode", prop_mode_items, 0, "Mode", ""); + RNA_def_enum(ot->srna, "mode", radial_mode_items, 0, "Mode", ""); /* Internal */ RNA_def_int_vector(ot->srna, "initial_mouse", 2, NULL, INT_MIN, INT_MAX, "initial_mouse", "", INT_MIN, INT_MAX); -- cgit v1.2.3 From 12b3d458f28c2d9d7af25650f04d2a379bbbf604 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 13 Oct 2009 17:15:12 +0000 Subject: Bugfixes for particle mode: * Fix crash removing all particles. * Brush added particles did not get correct coordinates. --- source/blender/editors/physics/particle_edit.c | 3 +++ source/blender/editors/space_view3d/drawobject.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index d4a180e2427..74ed6451d29 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3003,6 +3003,9 @@ static void brush_add(PEData *data, short number) for(k=0, hkey=pa->hair; ktotkey; k++, hkey++, key++) { key->co= hkey->co; key->time= &hkey->time; + + if(!(psys->flag & PSYS_GLOBAL_HAIR)) + key->flag |= PEK_USE_WCO; } pa->size= 1.0f; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 096129f6f9e..78dd53e7271 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4237,7 +4237,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj if(!(point->flag & PEP_HIDE)) totkeys += point->totkey; - if(!(edit->points->keys->flag & PEK_USE_WCO)) + if(edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) pd=pdata=MEM_callocN(totkeys*3*sizeof(float), "particle edit point data"); cd=cdata=MEM_callocN(totkeys*(timed?4:3)*sizeof(float), "particle edit color data"); -- cgit v1.2.3 From ee29802378281f69e073275ccb4d93da475d8d8d Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 13 Oct 2009 17:49:05 +0000 Subject: [#19634] Missing - "All Edges" Button in edit mode Preferences --- release/scripts/ui/space_view3d.py | 6 +++--- source/blender/makesrna/intern/rna_mesh.c | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 1fd589b4846..cb3f91ad687 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1235,6 +1235,8 @@ class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel): col = layout.column() col.itemL(text="Overlays:") col.itemR(mesh, "draw_edges", text="Edges") + col.itemR(mesh, "all_edges") + col.itemS() col.itemR(mesh, "draw_faces", text="Faces") col.itemR(mesh, "draw_creases", text="Creases") col.itemR(mesh, "draw_bevel_weights", text="Bevel Weights") @@ -1253,7 +1255,6 @@ class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel): col.itemR(mesh, "draw_edge_angle") col.itemR(mesh, "draw_face_area") - class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel): __space_type__ = 'VIEW_3D' __region_type__ = 'UI' @@ -1273,8 +1274,7 @@ class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel): col.itemR(curve, "draw_handles", text="Handles") col.itemR(curve, "draw_normals", text="Normals") col.itemR(context.scene.tool_settings, "normal_size", text="Normal Size") - - + class VIEW3D_PT_background_image(bpy.types.Panel): __space_type__ = 'VIEW_3D' __region_type__ = 'UI' diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 8b67ccecc3d..03fead8c54f 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1546,6 +1546,10 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Draw Edges", "Displays selected edges using hilights in the 3d view and UV editor"); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + prop= RNA_def_property(srna, "all_edges", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_ALLEDGES); + RNA_def_property_ui_text(prop, "All Edges", "Displays all edges for wireframe in all view modes in the 3d view"); + prop= RNA_def_property(srna, "draw_faces", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWFACES); RNA_def_property_ui_text(prop, "Draw Faces", "Displays all faces as shades in the 3d view and UV editor"); @@ -1580,8 +1584,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWSHARP); RNA_def_property_ui_text(prop, "Draw Sharp", "Displays sharp edges, used with the EdgeSplit modifier"); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); - - + prop= RNA_def_property(srna, "draw_edge_lenght", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_EDGELEN); RNA_def_property_ui_text(prop, "Edge Length", "Displays selected edge lengths"); -- cgit v1.2.3 From e3d8c8eba855b0c97d71b83b33c93f99f99c7941 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Oct 2009 17:50:14 +0000 Subject: added back space switching keys Shift+F2 to F12 - Shift+F2 was Export DXF, made Logic Editor - Shift+F4 was data browser, made console - Shift+F11 was fullscreen in 2.5, changed fullscreen to Alt+F11 added Area.type so RNA can switch the type. --- release/scripts/modules/bpy_ops.py | 2 +- source/blender/makesrna/RNA_enum_types.h | 2 + source/blender/makesrna/intern/rna_screen.c | 25 ++++++++++ source/blender/windowmanager/intern/wm_operators.c | 53 +++++++++++++++++++++- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py index b1d782917b6..022c0581a81 100644 --- a/release/scripts/modules/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py @@ -204,7 +204,7 @@ class WM_OT_context_toggle_values(bpy.types.Operator): class WM_OT_context_cycle_enum(bpy.types.Operator): '''Toggle a context value.''' __idname__ = "wm.context_cycle_enum" - __label__ = "Context Toggle Values" + __label__ = "Context Enum Cycle" __register__ = True __undo__ = True diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index f102143f0ed..af950c1148a 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -60,6 +60,8 @@ extern EnumPropertyItem unpack_method_items[]; extern EnumPropertyItem object_type_items[]; +extern EnumPropertyItem space_type_items[]; + struct bContext; struct PointerRNA; EnumPropertyItem *rna_TransformOrientation_itemf(struct bContext *C, struct PointerRNA *ptr, int *free); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 2a72845dd42..004c57eedfc 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -26,6 +26,7 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -77,6 +78,22 @@ static int rna_Screen_animation_playing_get(PointerRNA *ptr) return (sc->animtimer != NULL); } +static void rna_Area_type_set(PointerRNA *ptr, int value) +{ + ScrArea *sa= (ScrArea*)ptr->data; + sa->butspacetype= value; +} + +static void rna_Area_type_update(bContext *C, PointerRNA *ptr) +{ + ScrArea *sa= (ScrArea*)ptr->data; + + if(sa) { + ED_area_newspace(C, sa, sa->butspacetype); /* XXX - this uses the window */ + ED_area_tag_redraw(sa); + } +} + #else static void rna_def_area(BlenderRNA *brna) @@ -107,6 +124,14 @@ static void rna_def_area(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", HEADER_NO_PULLDOWN); RNA_def_property_ui_text(prop, "Show Menus", "Show menus in the header."); + prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "spacetype"); + RNA_def_property_enum_items(prop, space_type_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_Area_type_set", NULL); + RNA_def_property_ui_text(prop, "Type", "Space type."); + RNA_def_property_update(prop, 0, "rna_Area_type_update"); + + RNA_def_function(srna, "tag_redraw", "ED_area_tag_redraw"); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index e3f23a488a2..2ed32808f48 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2186,6 +2186,7 @@ void wm_operatortype_init(void) void wm_window_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0); + wmKeyMapItem *km; /* items to make WM work */ WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0); @@ -2208,7 +2209,7 @@ void wm_window_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); - WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); /* debug/testing */ @@ -2216,5 +2217,55 @@ void wm_window_keymap(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0); + /* Space switching */ + + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */ + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'LOGIC_EDITOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F3KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'NODE_EDITOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F4KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was data browser */ + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'CONSOLE'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F5KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'VIEW_3D'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F6KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'GRAPH_EDITOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F7KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'PROPERTIES'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F8KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'SEQUENCE_EDITOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F9KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'OUTLINER'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F9KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'OUTLINER'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F10KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'IMAGE_EDITOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F11KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'TEXT_EDITOR'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_set", F12KEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "area.type"); + RNA_string_set(km->ptr, "value", "'DOPESHEET_EDITOR'"); } -- cgit v1.2.3 From 3b805af8af82d473bbcdd7809c43374995e005e6 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 13 Oct 2009 19:02:30 +0000 Subject: Various warning fixes --- source/blender/blenkernel/intern/cdderivedmesh.c | 1 - source/blender/blenkernel/intern/screen.c | 1 - source/blender/blenlib/BLI_arithb.h | 4 ++-- source/blender/blenlib/intern/arithb.c | 4 ++-- source/blender/editors/include/ED_object.h | 1 + source/blender/editors/mesh/editface.c | 3 --- source/blender/editors/mesh/editmesh_tools.c | 2 +- source/blender/editors/mesh/mesh_ops.c | 1 + source/blender/editors/object/object_ops.c | 2 -- source/blender/editors/sculpt_paint/sculpt.c | 1 - source/blender/editors/uvedit/uvedit_ops.c | 1 + source/blender/gpu/gpu_buffers.h | 4 ++-- source/blender/gpu/intern/gpu_buffers.c | 4 ++-- 13 files changed, 12 insertions(+), 17 deletions(-) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b9aa842b6dc..e38bb00fe8d 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -660,7 +660,6 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, for(i = 0; i < dm->drawObject->nelements/3; i++) { int actualFace = dm->drawObject->faceRemap[i]; int flag = 1; - unsigned char *cp = NULL; if(drawParams) { flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 918a67311a0..459db96dbfb 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -57,7 +57,6 @@ static void spacetype_free(SpaceType *st) ARegionType *art; PanelType *pt; HeaderType *ht; - MenuType *mt; for(art= st->regiontypes.first; art; art= art->next) { BLI_freelistN(&art->drawcalls); diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 1d275e70a17..e6aded12f3b 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -348,7 +348,7 @@ void VecUpMat3(float *vec, float mat[][3], short axis); void VecCopyf(float *v1, float *v2); int VecLen(int *v1, int *v2); -float VecLenf(float *v1, float *v2); +float VecLenf(float v1[3], float v2[3]); float VecLength(float *v); void VecMulf(float *v1, float f); void VecNegf(float *v1); @@ -412,7 +412,7 @@ void NormalFloatToShort(short *out, float *in); float DistVL2Dfl(float *v1, float *v2, float *v3); float PdistVL2Dfl(float *v1, float *v2, float *v3); float PdistVL3Dfl(float *v1, float *v2, float *v3); -void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3); +void PclosestVL3Dfl(float *closest, float v1[3], float v2[3], float v3[3]); float AreaF2Dfl(float *v1, float *v2, float *v3); float AreaQ3Dfl(float *v1, float *v2, float *v3, float *v4); float AreaT3Dfl(float *v1, float *v2, float *v3); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 26bbbf040f3..6c9ae78bac4 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2151,7 +2151,7 @@ int VecLen( int *v1, int *v2) return (int)floor(sqrt(x*x+y*y+z*z)); } -float VecLenf( float *v1, float *v2) +float VecLenf(float v1[3], float v2[3]) { float x,y,z; @@ -5131,7 +5131,7 @@ int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]) } /* point closest to v1 on line v2-v3 in 3D */ -void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3) +void PclosestVL3Dfl(float *closest, float v1[3], float v2[3], float v3[3]) { float lambda, cp[3]; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 3d0d776f549..8f74752ec8c 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -29,6 +29,7 @@ #define ED_OBJECT_H struct wmKeyConfig; +struct wmKeyMap; struct Scene; struct Object; struct bContext; diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index f65ab7ddd67..8f9dea00a1b 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -711,9 +711,6 @@ void face_borderselect(Scene *scene, ScrArea *sa, ARegion *ar) // XXX val= get_border(&rect, 3); if(val) { - View3D *v3d= sa->spacedata.first; - RegionView3D *rv3d= ar->regiondata; - /* without this border select often fails */ #if 0 /* XXX untested in 2.5 */ if (v3d->flag & V3D_NEEDBACKBUFDRAW) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 971e0a147d3..80ea5c51e1f 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -484,9 +484,9 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); /*char msg[100];*/ - int cnt = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); /*XXX this messes up last operator panel + int cnt = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit")); if(cnt) { sprintf(msg, "Removed %d vertices", cnt); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 3a3e4f54915..c8d85aace47 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -55,6 +55,7 @@ #include "WM_types.h" #include "ED_mesh.h" +#include "ED_object.h" #include "ED_screen.h" #include "ED_transform.h" #include "ED_view3d.h" diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 4f9a3d22f3b..eea36f630b7 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -63,8 +63,6 @@ void ED_operatortypes_object(void) { - wmOperatorType *ot; - WM_operatortype_append(OBJECT_OT_location_clear); WM_operatortype_append(OBJECT_OT_rotation_clear); WM_operatortype_append(OBJECT_OT_scale_clear); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index fc0aa28a2c3..4f667ab7976 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -305,7 +305,6 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float out[3], const static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_verts) { float area_normal[3]; - int j; ActiveData *node= active_verts->first; float* buffer; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 9b3cb581c88..1641d1c8fac 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -56,6 +56,7 @@ #include "ED_image.h" #include "ED_mesh.h" +#include "ED_object.h" #include "ED_screen.h" #include "ED_transform.h" diff --git a/source/blender/gpu/gpu_buffers.h b/source/blender/gpu/gpu_buffers.h index 20b502387da..662912f9c19 100644 --- a/source/blender/gpu/gpu_buffers.h +++ b/source/blender/gpu/gpu_buffers.h @@ -141,9 +141,9 @@ void *GPU_buffer_lock_stream( GPUBuffer *buffer ); void GPU_buffer_unlock( GPUBuffer *buffer ); /* upload three unsigned chars, representing RGB colors, for each vertex. Resets dm->drawObject->colType to -1 */ -void GPU_color3_upload( struct DerivedMesh *dm, char *data ); +void GPU_color3_upload( struct DerivedMesh *dm, unsigned char *data ); /* upload four unsigned chars, representing RGBA colors, for each vertex. Resets dm->drawObject->colType to -1 */ -void GPU_color4_upload( struct DerivedMesh *dm, char *data ); +void GPU_color4_upload( struct DerivedMesh *dm, unsigned char *data ); /* switch color rendering on=1/off=0 */ void GPU_color_switch( int mode ); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index e750a3d05fd..2563f7977cc 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1150,14 +1150,14 @@ void GPU_buffer_unbind() glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); } -void GPU_color3_upload( DerivedMesh *dm, char *data ) +void GPU_color3_upload( DerivedMesh *dm, unsigned char *data ) { if( dm->drawObject == 0 ) dm->drawObject = GPU_drawobject_new(dm); GPU_buffer_free(dm->drawObject->colors,globalPool); dm->drawObject->colors = GPU_buffer_setup( dm, dm->drawObject, sizeof(char)*3*dm->drawObject->nelements, GL_ARRAY_BUFFER_ARB, data, GPU_buffer_copy_color3 ); } -void GPU_color4_upload( DerivedMesh *dm, char *data ) +void GPU_color4_upload( DerivedMesh *dm, unsigned char *data ) { if( dm->drawObject == 0 ) dm->drawObject = GPU_drawobject_new(dm); -- cgit v1.2.3 From a9cf4bbf023fb58280d6f8b79b99d694af4d9ff6 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 13 Oct 2009 23:15:34 +0000 Subject: Use new operator to toggle view3d draw type. --- source/blender/editors/space_view3d/view3d_edit.c | 51 ----------------------- source/blender/editors/space_view3d/view3d_ops.c | 23 +++++----- 2 files changed, 13 insertions(+), 61 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 3cd810d5c16..8681a5bcd14 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1879,57 +1879,6 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); } -/* ********************* draw type operator ****************** */ - -static int view3d_drawtype_exec(bContext *C, wmOperator *op) -{ - View3D *v3d = CTX_wm_view3d(C); - int dt, dt_alt; - - dt = RNA_int_get(op->ptr, "draw_type"); - dt_alt = RNA_int_get(op->ptr, "draw_type_alternate"); - - if (dt_alt != -1) { - if (v3d->drawtype == dt) - v3d->drawtype = dt_alt; - else - v3d->drawtype = dt; - } - else - v3d->drawtype = dt; - - ED_area_tag_redraw(CTX_wm_area(C)); - - return OPERATOR_FINISHED; -} - -static int view3d_drawtype_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - return view3d_drawtype_exec(C, op); -} - -/* toggles */ -void VIEW3D_OT_drawtype(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Change draw type"; - ot->description = "Change the draw type of the view."; - ot->idname= "VIEW3D_OT_drawtype"; - - /* api callbacks */ - ot->invoke= view3d_drawtype_invoke; - ot->exec= view3d_drawtype_exec; - - ot->poll= ED_operator_view3d_active; - - /* flags */ - ot->flag= 0; - - /* rna XXX should become enum */ - RNA_def_int(ot->srna, "draw_type", 0, INT_MIN, INT_MAX, "Draw Type", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "draw_type_alternate", -1, INT_MIN, INT_MAX, "Draw Type Alternate", "", INT_MIN, INT_MAX); -} - /* ***************** 3d cursor cursor op ******************* */ /* mx my in region coords */ diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 758bf803fb8..0ac62652b52 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -83,7 +83,6 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_select_lasso); WM_operatortype_append(VIEW3D_OT_setcameratoview); WM_operatortype_append(VIEW3D_OT_setobjectascamera); - WM_operatortype_append(VIEW3D_OT_drawtype); WM_operatortype_append(VIEW3D_OT_localview); WM_operatortype_append(VIEW3D_OT_game_start); WM_operatortype_append(VIEW3D_OT_fly); @@ -174,17 +173,21 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ZEROKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 10); /* drawtype */ - km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, 0, 0); - RNA_int_set(km->ptr, "draw_type", OB_SOLID); - RNA_int_set(km->ptr, "draw_type_alternate", OB_WIRE); - km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, KM_ALT, 0); - RNA_int_set(km->ptr, "draw_type", OB_TEXTURE); - RNA_int_set(km->ptr, "draw_type_alternate", OB_SOLID); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", ZKEY, KM_PRESS, 0, 0); + RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); + RNA_string_set(km->ptr, "value_1", "'SOLID'"); + RNA_string_set(km->ptr, "value_2", "'WIREFRAME'"); - km = WM_keymap_add_item(keymap, "VIEW3D_OT_drawtype", ZKEY, KM_PRESS, KM_SHIFT, 0); - RNA_int_set(km->ptr, "draw_type", OB_SHADED); - RNA_int_set(km->ptr, "draw_type_alternate", OB_WIRE); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", ZKEY, KM_PRESS, KM_ALT, 0); + RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); + RNA_string_set(km->ptr, "value_1", "'TEXTURED'"); + RNA_string_set(km->ptr, "value_2", "'SOLID'"); + + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", ZKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); + RNA_string_set(km->ptr, "value_1", "'SHADED'"); + RNA_string_set(km->ptr, "value_2", "'WIREFRAME'"); /* selection*/ WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); -- cgit v1.2.3 From adddfffe231b066ed701852b6a378f2f7561d7a4 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 00:01:34 +0000 Subject: * Fixed crash with operator cheat-sheet * Removed obsolete comment --- source/blender/editors/animation/anim_draw.c | 1 - source/blender/editors/armature/poselib.c | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 9863006308e..2dc4aa09407 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -340,7 +340,6 @@ short ANIM_headerUI_standard_buttons (const bContext *C, bDopeSheet *ads, uiBloc xco += 5; /* datatype based - only available datatypes are shown */ - // TODO: only show the datablocks which exist uiBlockBeginAlign(block); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOSCE, B_REDR, ICON_SCENE_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display Scene Animation"); uiDefIconButBitI(block, TOGN, ADS_FILTER_NOWOR, B_REDR, ICON_WORLD_DATA, (short)(xco+=XIC),yco,XIC,YIC, &(ads->filterflag), 0, 0, 0, 0, "Display World Animation"); diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index b06c7286859..d6f93757505 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -436,13 +436,16 @@ static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, return NULL; memset(&item_tmp, 0, sizeof(item_tmp)); - - /* add each marker to the list */ - for (marker=act->markers.first, i=0; marker; marker= marker->next, i++) { - item_tmp.identifier= item_tmp.name= marker->name; - item_tmp.icon= ICON_ARMATURE_DATA; - item_tmp.value= i; - RNA_enum_item_add(&item, &totitem, &item_tmp); + + /* check that the action exists */ + if (act) { + /* add each marker to the list */ + for (marker=act->markers.first, i=0; marker; marker= marker->next, i++) { + item_tmp.identifier= item_tmp.name= marker->name; + item_tmp.icon= ICON_ARMATURE_DATA; + item_tmp.value= i; + RNA_enum_item_add(&item, &totitem, &item_tmp); + } } if (i > 0) { -- cgit v1.2.3 From e87839b6736535584dcffcbd1b9f144ad6e6ee01 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 02:18:59 +0000 Subject: Bugfix: Automerge keyframes was broken - the function call to perform the merging was commented out --- .../blender/editors/transform/transform_conversions.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 826fcb0c2dd..f5854a8d9db 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2890,7 +2890,7 @@ static void posttrans_fcurve_clean (FCurve *fcu) /* Loop 1: find selected keyframes */ for (i = 0; i < fcu->totvert; i++) { BezTriple *bezt= &fcu->bezt[i]; - + if (BEZSELECTED(bezt)) { selcache[index]= bezt->vec[1][0]; index++; @@ -2898,16 +2898,18 @@ static void posttrans_fcurve_clean (FCurve *fcu) } } - /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */ - if (len) { + /* Loop 2: delete unselected keyframes on the same frames + * (if any keyframes were found, or the whole curve wasn't affected) + */ + if ((len) && (len != fcu->totvert)) { for (i = 0; i < fcu->totvert; i++) { BezTriple *bezt= &fcu->bezt[i]; - + if (BEZSELECTED(bezt) == 0) { /* check beztriple should be removed according to cache */ for (index= 0; index < len; index++) { if (IS_EQ(bezt->vec[1][0], selcache[index])) { - //delete_icu_key(icu, i, 0); + delete_fcurve_key(fcu, i, 0); break; } else if (bezt->vec[1][0] > selcache[index]) @@ -2915,7 +2917,7 @@ static void posttrans_fcurve_clean (FCurve *fcu) } } } - + testhandles_fcurve(fcu); } @@ -4561,6 +4563,8 @@ void special_aftertrans_update(TransInfo *t) if (ANIM_animdata_context_getdata(&ac) == 0) return; + printf("automerge dopesheet keys \n"); + if (ac.datatype == ANIMCONT_DOPESHEET) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; @@ -4577,6 +4581,7 @@ void special_aftertrans_update(TransInfo *t) if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { + printf("\tdo fcurve clean \n"); if (adt) { ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); posttrans_fcurve_clean(fcu); -- cgit v1.2.3 From 828e3f30596d89fcad0e6481f88f006d51737c11 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 03:00:35 +0000 Subject: Left in debug prints --- source/blender/editors/transform/transform_conversions.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index f5854a8d9db..16d07894682 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4563,8 +4563,6 @@ void special_aftertrans_update(TransInfo *t) if (ANIM_animdata_context_getdata(&ac) == 0) return; - printf("automerge dopesheet keys \n"); - if (ac.datatype == ANIMCONT_DOPESHEET) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; @@ -4581,7 +4579,6 @@ void special_aftertrans_update(TransInfo *t) if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { - printf("\tdo fcurve clean \n"); if (adt) { ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); posttrans_fcurve_clean(fcu); -- cgit v1.2.3 From 6f2146e84821396cecbc2f27c20868596bb8f13f Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Wed, 14 Oct 2009 08:24:40 +0000 Subject: Cocoa : bugfix on continuous grab (cursor was returning to a wrong position upon button grab end) --- intern/ghost/intern/GHOST_WindowCocoa.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index fd68b6200ee..999ec0de9c1 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -873,7 +873,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool setCursorWarpAccum(-x_new, -y_new); } else { - m_systemCocoa->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + GHOST_TInt32 x_new, y_new; + //get/set cursor position works in screen coordinates + clientToScreen(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1], x_new, y_new); + m_systemCocoa->setCursorPosition(x_new, y_new); setCursorWarpAccum(0, 0); } -- cgit v1.2.3 From daebfaaa49186886af5bef2b579baed7c4c6e93f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 09:08:48 +0000 Subject: Bugfix: uv editor transform operators were not working anymore after the recent retopo/snap commit. --- .../blender/editors/transform/transform_generics.c | 43 +++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 5fe9db3915f..11789651d01 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -617,6 +617,17 @@ void recalcData(TransInfo *t) } } } + else if (t->spacetype == SPACE_IMAGE) { + if (t->obedit && t->obedit->type == OB_MESH) { + SpaceImage *sima= t->sa->spacedata.first; + + flushTransUVs(t); + if(sima->flag & SI_LIVE_UNWRAP) + ED_uvedit_live_unwrap_re_solve(); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); + } + } else if (t->spacetype == SPACE_VIEW3D) { /* project */ @@ -652,27 +663,17 @@ void recalcData(TransInfo *t) if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); } else if (t->obedit->type == OB_MESH) { - if(t->spacetype==SPACE_IMAGE) { - SpaceImage *sima= t->sa->spacedata.first; - - flushTransUVs(t); - if(sima->flag & SI_LIVE_UNWRAP) - ED_uvedit_live_unwrap_re_solve(); - - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); - } else { - EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; - /* mirror modifier clipping? */ - if(t->state != TRANS_CANCEL) { - clipMirrorModifier(t, t->obedit); - } - if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) - editmesh_apply_to_mirror(t); - - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ - - recalc_editnormals(em); + EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh; + /* mirror modifier clipping? */ + if(t->state != TRANS_CANCEL) { + clipMirrorModifier(t, t->obedit); } + if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) + editmesh_apply_to_mirror(t); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ + + recalc_editnormals(em); } else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ bArmature *arm= t->obedit->data; @@ -809,7 +810,7 @@ void recalcData(TransInfo *t) } } - if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) + if(((View3D*)t->view)->drawtype == OB_SHADED) reshadeall_displist(t->scene); } } -- cgit v1.2.3 From 1ef163f1e0dd1c535c3c9b81670333f02c45b236 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 09:08:53 +0000 Subject: UI Templates: ('Any ID' Selector) Added new template for choosing to use any type of ID-block. The first combo box allows you to choose the type of ID-block that gets used, and the second box allows you to choose the ID-block of the type specified by the first one. This is currently used for setting the ID-block used for Keying Sets, but the main user for this was intended to be the Drivers UI. However, I still need to clear up a few button-event issues there before I can port this over. Additional Bugfixes: * Adding new Keying Set path was setting the active path wrong, meaning that you had to click on the list to get some response after adding * Bone Groups list was being drawn too long by default (when empty) --- release/scripts/ui/buttons_data_armature.py | 2 +- release/scripts/ui/buttons_scene.py | 2 +- source/blender/editors/animation/keyingsets.c | 2 +- source/blender/editors/include/UI_interface.h | 2 + .../editors/interface/interface_templates.c | 47 +++++++++++++++++++++- source/blender/makesdna/DNA_anim_types.h | 2 + source/blender/makesrna/RNA_enum_types.h | 3 ++ source/blender/makesrna/intern/rna_ID.c | 32 +++++++++++++++ source/blender/makesrna/intern/rna_animation.c | 28 ++++++++++++- source/blender/makesrna/intern/rna_fcurve.c | 34 +++++++++++++--- source/blender/makesrna/intern/rna_ui_api.c | 12 +++++- 11 files changed, 154 insertions(+), 12 deletions(-) diff --git a/release/scripts/ui/buttons_data_armature.py b/release/scripts/ui/buttons_data_armature.py index 9344294ff9e..bbec295a165 100644 --- a/release/scripts/ui/buttons_data_armature.py +++ b/release/scripts/ui/buttons_data_armature.py @@ -88,7 +88,7 @@ class DATA_PT_bone_groups(DataButtonsPanel): pose = ob.pose row = layout.row() - row.template_list(pose, "bone_groups", pose, "active_bone_group_index") + row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2) col = row.column(align=True) col.active = (ob.proxy == None) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 49635071342..ce4adef354d 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -527,7 +527,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): if ksp: col = layout.column() col.itemL(text="Target:") - col.itemR(ksp, "id") + col.template_any_ID(ksp, "id", "id_type") col.itemR(ksp, "rna_path") diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index a044e867d56..30eaea8b82e 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -219,7 +219,7 @@ static int add_empty_ks_path_exec (bContext *C, wmOperator *op) /* don't use the API method for this, since that checks on values... */ ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty"); BLI_addtail(&ks->paths, ksp); - ks->active_path= BLI_countlist(&ks->paths) + 1; + ks->active_path= BLI_countlist(&ks->paths); ksp->groupmode= KSP_GROUP_KSNAME; // XXX? diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index adbfd731a09..2fd870cf696 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -620,6 +620,8 @@ uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout); void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus); void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop); +void uiTemplateAnyID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, + char *proptypename, char *text); uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr); uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr); void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index c092b1ca68b..a7c586be42a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -152,6 +152,7 @@ static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem) } /************************ ID Template ***************************/ +/* This is for browsing and editing the ID-blocks used */ /* for new/open operators */ void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop) @@ -390,7 +391,10 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname type= RNA_property_pointer_type(ptr, prop); template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type)); - + + /* create UI elements for this template + * - template_ID makes a copy of the template data and assigns it to the relevant buttons + */ if(template->idlb) { uiLayoutRow(layout, 1); block= uiLayoutGetBlock(layout); @@ -400,6 +404,47 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname MEM_freeN(template); } +/************************ ID Chooser Template ***************************/ +/* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use */ + +/* - propname: property identifier for property that ID-pointer gets stored to + * - proptypename: property identifier for property used to determine the type of ID-pointer that can be used + */ +void uiTemplateAnyID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *proptypename, char *text) +{ + PropertyRNA *propID, *propType; + uiLayout *row; + + /* get properties... */ + propID= RNA_struct_find_property(ptr, propname); + propType= RNA_struct_find_property(ptr, proptypename); + + if (!propID || RNA_property_type(propID) != PROP_POINTER) { + printf("uiTemplateAnyID: pointer property not found: %s\n", propname); + return; + } + if (!propType || RNA_property_type(propType) != PROP_ENUM) { + printf("uiTemplateAnyID: pointer-type property not found: %s\n", proptypename); + return; + } + + /* Start drawing UI Elements using standard defines */ + row= uiLayoutRow(layout, 1); + + /* Label - either use the provided text, or will become "ID-Block:" */ + if (text) + uiItemL(row, text, 0); + else + uiItemL(row, "ID-Block:", 0); + + /* ID-Type Selector - just have a menu of icons */ + // XXX should value really be 0? + uiItemFullR(row, "", 0, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY); + + /* ID-Block Selector - just use pointer widget... */ + uiItemFullR(row, "", 0, ptr, propID, 0, 0, 0); +} + /************************ Modifier Template *************************/ #define ERROR_LIBDATA_MESSAGE "Can't edit external libdata" diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index fedde34ae18..195d68d63ff 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -246,7 +246,9 @@ typedef struct DriverTarget { char *rna_path; /* target channel to use as driver value */ int array_index; /* if applicable, the index of the RNA-array item to use as driver */ + int idtype; /* type of ID-block that this target can use */ int flags; /* flags for the validity of the target */ + int pad; char name[64]; /* name of the variable */ } DriverTarget; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index af950c1148a..ca44e3405f6 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -29,6 +29,9 @@ /* Types */ +extern EnumPropertyItem id_type_items[]; + + extern EnumPropertyItem object_mode_items[]; extern EnumPropertyItem proportional_falloff_items[]; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 8ab5a1442c7..c52021b3a49 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -33,6 +33,38 @@ #include "rna_internal.h" +/* enum of ID-block types + * NOTE: need to keep this in line with the other defines for these + */ +EnumPropertyItem id_type_items[] = { + {ID_AC, "ACTION", ICON_ACTION, "Action", ""}, + {ID_AR, "ARMATURE", ICON_ARMATURE_DATA, "Armature", ""}, + {ID_BR, "BRUSH", ICON_BRUSH_DATA, "Brush", ""}, + {ID_CA, "CAMERA", ICON_CAMERA_DATA, "Camera", ""}, + {ID_CU, "CURVE", ICON_CURVE_DATA, "Curve", ""}, + {ID_VF, "FONT", ICON_FONT_DATA, "Font", ""}, + {ID_GD, "GREASEPENCIL", ICON_GREASEPENCIL, "Grease Pencil", ""}, + {ID_GR, "GROUP", ICON_GROUP, "Group", ""}, + {ID_IM, "IMAGE", ICON_IMAGE_DATA, "Image", ""}, + {ID_KE, "KEY", ICON_SHAPEKEY_DATA, "Key", ""}, + {ID_LA, "LAMP", ICON_LAMP_DATA, "Lamp", ""}, + {ID_LI, "LIBRARY", 0, "Library", ""}, + {ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""}, + {ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""}, + {ID_MB, "META", ICON_META_DATA, "MetaBall", ""}, + {ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""}, + {ID_NT, "NODETREE", 0, "NodeTree", ""}, + {ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""}, + {ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""}, + {ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""}, + {ID_SCR, "SCREEN", 0, "Screen", ""}, + {ID_SO, "SOUND", 0, "Sound", ""}, + {ID_TXT, "TEXT", ICON_TEXT, "Text", ""}, + {ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""}, + {ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""}, + {ID_WM, "WINDOWMANAGER", 0, "Window Manager", ""}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "BKE_idprop.h" diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index a62eef66cf0..23a9c48710e 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -24,6 +24,7 @@ #include +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" #include "RNA_enum_types.h" @@ -63,6 +64,20 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value) adt->action= value.data; } +/* ****************************** */ + +static StructRNA *rna_ksPath_id_typef(PointerRNA *ptr) +{ + KS_Path *ksp= (KS_Path*)ptr->data; + return ID_code_to_RNA_type(ksp->idtype); +} + +static int rna_ksPath_id_editable(PointerRNA *ptr) +{ + KS_Path *ksp= (KS_Path*)ptr->data; + return (ksp->idtype)? PROP_EDITABLE : 0; +} + static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value) { KS_Path *ksp= (KS_Path *)ptr->data; @@ -96,6 +111,7 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value) ksp->rna_path= NULL; } +/* ****************************** */ static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr) { @@ -153,8 +169,18 @@ static void rna_def_keyingset_path(BlenderRNA *brna) /* ID */ 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_ksPath_id_editable"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_ksPath_id_typef"); RNA_def_property_ui_text(prop, "ID-Block", "ID-Block that keyframes for Keying Set should be added to (for Absolute Keying Sets only)."); + prop= RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "idtype"); + RNA_def_property_enum_items(prop, id_type_items); + RNA_def_property_enum_default(prop, ID_OB); + RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used."); + /* Group */ prop= RNA_def_property(srna, "group", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Group Name", "Name of Action Group to assign setting(s) for this path to."); @@ -167,13 +193,11 @@ static void rna_def_keyingset_path(BlenderRNA *brna) /* Path + Array Index */ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE); - //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property setting."); RNA_def_struct_name_property(srna, prop); // XXX this is the best indicator for now... prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE); - //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific setting if applicable."); /* Flags */ diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index ba68f8e1624..12a81afa2b5 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -24,8 +24,10 @@ #include +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -80,6 +82,18 @@ static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) /* ****************************** */ +static StructRNA *rna_DriverTarget_id_typef(PointerRNA *ptr) +{ + DriverTarget *dtar= (DriverTarget*)ptr->data; + return ID_code_to_RNA_type(dtar->idtype); +} + +static int rna_DriverTarget_id_editable(PointerRNA *ptr) +{ + DriverTarget *dtar= (DriverTarget*)ptr->data; + return (dtar->idtype)? PROP_EDITABLE : 0; +} + static void rna_DriverTarget_RnaPath_get(PointerRNA *ptr, char *value) { DriverTarget *dtar= (DriverTarget *)ptr->data; @@ -523,11 +537,21 @@ static void rna_def_drivertarget(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions."); - /* Target Properties */ - prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "id"); - RNA_def_property_ui_text(prop, "Object", "Object the specific property used can be found from"); - + /* 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_DriverTarget_id_editable"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_DriverTarget_id_typef"); + RNA_def_property_ui_text(prop, "ID", "ID-block that the specific property used can be found from"); + + prop= RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "idtype"); + RNA_def_property_enum_items(prop, id_type_items); + RNA_def_property_enum_default(prop, ID_OB); + RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used."); + + /* Target Properties - Property to Drive */ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path (from Object) to property used"); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 436efbcb2cf..79465f64daf 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -255,7 +255,17 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block."); RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block."); RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block."); - + + func= RNA_def_function(srna, "template_any_ID", "uiTemplateAnyID"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "type_property", "", 0, "", "Identifier of property in data giving the type of the ID-blocks to use."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_string(func, "text", "", 0, "", "Custom label to display in UI."); + func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); parm= RNA_def_pointer(func, "data", "Modifier", "", "Modifier data."); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); -- cgit v1.2.3 From 8884f3fe5c5f53c8d21f881f5c4f5a2f6e3df7e2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 09:40:09 +0000 Subject: Bugfix: compositing nodes + border render + crop didn't work correct. --- source/blender/render/intern/source/pipeline.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 74a56528d8d..edf3cd83404 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2116,6 +2116,11 @@ static void do_render_fields_blur_3d(Render *re) re->display_init(re->dih, re->result); re->display_draw(re->ddh, re->result, NULL); } + else { + /* set offset (again) for use in compositor, disprect was manipulated. */ + re->result->xof= 0; + re->result->yof= 0; + } } } } -- cgit v1.2.3 From 107447b79e125e8755745a9730e510b66ab1e37b Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Wed, 14 Oct 2009 09:46:41 +0000 Subject: Cocoa : bugfix #19591 Add trackpad 2 fingers gesture handling, to have it mimicking correctly mouse wheel, and thus zoom in/out correctly in the 3D view --- intern/ghost/intern/GHOST_SystemCocoa.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 3e0d58b46a6..072b2dfee86 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1153,9 +1153,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSScrollWheel: { GHOST_TInt32 delta; - delta = [event deltaY] > 0 ? 1 : -1; - pushEvent(new GHOST_EventWheel(getMilliSeconds(), window, delta)); - + + double deltaF = [event deltaY]; + if (deltaF == 0.0) break; //discard trackpad delta=0 events + + delta = deltaF > 0.0 ? 1 : -1; + pushEvent(new GHOST_EventWheel([event timestamp], window, delta)); } break; -- cgit v1.2.3 From d38940676685912b426cb32ae40c25a9960af242 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 09:54:29 +0000 Subject: DopeSheet/Action Editors - Summary Channel Tweaks: * Summary channel now works in DopeSheet AND Action Editors * By clicking on the expand/collapse widget on the summary channel, you can now show/hide all the other channels in the editor. --- .../editors/animation/anim_channels_defines.c | 52 ++++++++++++- source/blender/editors/animation/anim_filter.c | 91 ++++++++++++++++------ .../blender/editors/space_action/action_header.c | 14 ++-- source/blender/makesdna/DNA_action_types.h | 6 +- 4 files changed, 128 insertions(+), 35 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index a4423d43339..c9052431d3c 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -280,11 +280,13 @@ static void acf_generic_idblock_name(bAnimListElem *ale, char *name) /* Settings ------------------------------------------- */ +#if 0 /* channel type has no settings */ static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { return 0; } +#endif /* check if some setting exists for this object-based data-expander (category only) */ static short acf_generic_dsexpand_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) @@ -372,6 +374,50 @@ static int acf_summary_icon(bAnimListElem *ale) return ICON_BORDERMOVE; } +/* check if some setting exists for this channel */ +static short acf_summary_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +{ + /* only expanded is supported, as it is used for hiding all stuff which the summary covers */ + return (setting == ACHANNEL_SETTING_EXPAND); +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_summary_setting_flag(int setting, short *neg) +{ + if (setting == ACHANNEL_SETTING_EXPAND) { + /* expanded */ + *neg= 1; + return ADS_FLAG_SUMMARY_COLLAPSED; + } + else { + /* unsupported */ + *neg= 0; + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_summary_setting_ptr(bAnimListElem *ale, int setting, short *type) +{ + bAnimContext *ac= (bAnimContext *)ale->data; + + /* if data is valid, return pointer to active dopesheet's relevant flag + * - this is restricted to DopeSheet/Action Editor only + */ + if ((ac->sa) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) { + SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first; + bDopeSheet *ads= &saction->ads; + + /* return pointer to DopeSheet's flag */ + GET_ACF_FLAG_PTR(ads->flag); + } + else { + /* can't return anything useful - unsupported */ + *type= 0; + return 0; + } +} + /* all animation summary (DopeSheet only) type define */ static bAnimChannelType ACF_SUMMARY = { @@ -382,9 +428,9 @@ static bAnimChannelType ACF_SUMMARY = acf_summary_name, /* name */ acf_summary_icon, /* icon */ - acf_generic_none_setting_valid, /* has setting */ - NULL, /* flag for setting */ - NULL /* pointer for setting */ + acf_summary_setting_valid, /* has setting */ + acf_summary_setting_flag, /* flag for setting */ + acf_summary_setting_ptr /* pointer for setting */ }; /* Scene ------------------------------------------- */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 7aba237ffb1..ea097420d1a 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1520,21 +1520,6 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bAnimContext *ac, bDo return 0; } - /* dopesheet summary - * - only for drawing and/or selecting keyframes in channels, but not for real editing - * - only useful for DopeSheet Editor, where the summary is useful - */ - // TODO: we should really check if some other prohibited filters are also active, but that can be for later - if ((filter_mode & ANIMFILTER_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) { - ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, ANIMTYPE_NONE, NULL); - if (ale) { - BLI_addtail(anim_data, ale); - items++; - } - - // TODO: if the summary gets a collapse widget, then we could make the other stuff not get shown... - } - /* scene-linked animation */ // TODO: sequencer, composite nodes - are we to include those here too? { @@ -1887,6 +1872,50 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bAnimContext *ac, bDo return items; } +/* Summary track for DopeSheet/Action Editor + * - return code is whether the summary lets the other channels get drawn + */ +static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim_data, int filter_mode, int *items) +{ + bDopeSheet *ads = NULL; + + /* get the DopeSheet information to use + * - we should only need to deal with the DopeSheet/Action Editor, + * since all the other Animation Editors won't have this concept + * being applicable. + */ + if ((ac && ac->sa) && (ac->sa->spacetype == SPACE_ACTION)) { + SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first; + ads= &saction->ads; + } + else { + /* invalid space type - skip this summary channels */ + return 1; + } + + /* dopesheet summary + * - only for drawing and/or selecting keyframes in channels, but not for real editing + * - only useful for DopeSheet Editor, where the summary is useful + */ + // TODO: we should really check if some other prohibited filters are also active, but that can be for later + if ((filter_mode & ANIMFILTER_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) { + bAnimListElem *ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, ANIMTYPE_NONE, NULL); + if (ale) { + BLI_addtail(anim_data, ale); + (*items)++; + } + + /* if summary is collapsed, don't show other channels beneath this + * - this check is put inside the summary check so that it doesn't interfere with normal operation + */ + if (ads->flag & ADS_FLAG_SUMMARY_COLLAPSED) + return 0; + } + + /* the other channels beneath this can be shown */ + return 1; +} + /* ----------- Public API --------------- */ /* This function filters the active data source to leave only animation channels suitable for @@ -1907,23 +1936,41 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode /* firstly filter the data */ switch (datatype) { - case ANIMCONT_ACTION: - items= animdata_filter_action(anim_data, NULL, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact); + case ANIMCONT_ACTION: /* 'Action Editor' */ + { + /* the check for the DopeSheet summary is included here since the summary works here too */ + if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) + items += animdata_filter_action(anim_data, NULL, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact); + } break; case ANIMCONT_SHAPEKEY: + { //items= animdata_filter_shapekey(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact); + } break; case ANIMCONT_GPENCIL: + { //items= animdata_filter_gpencil(anim_data, data, filter_mode); + } break; - case ANIMCONT_DOPESHEET: - case ANIMCONT_FCURVES: - case ANIMCONT_DRIVERS: - case ANIMCONT_NLA: - items= animdata_filter_dopesheet(anim_data, ac, data, filter_mode); + case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */ + { + /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ + if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) + items += animdata_filter_dopesheet(anim_data, ac, data, filter_mode); + } + break; + + case ANIMCONT_FCURVES: /* Graph Editor -> FCurves/Animation Editing */ + case ANIMCONT_DRIVERS: /* Graph Editor -> Drivers Editing */ + case ANIMCONT_NLA: /* NLA Editor */ + { + /* all of these editors use the basic DopeSheet data for filtering options, but don't have all the same features */ + items = animdata_filter_dopesheet(anim_data, ac, data, filter_mode); + } break; } diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index 2468bdf311c..ba5fc0893ec 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -326,23 +326,23 @@ void action_header_buttons(const bContext *C, ARegion *ar) xco += (90 + 8); + /* SUMMARY CHANNEL */ + uiDefIconTextButBitI(block, TOG, ADS_FILTER_SUMMARY, B_REDR, ICON_BORDERMOVE, "Summary", xco,yco,XIC*4,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Include DopeSheet summary row"); // TODO: needs a better icon + xco += (XIC*4.5); + /*if (ac.data)*/ { /* MODE-DEPENDENT DRAWING */ if (saction->mode == SACTCONT_DOPESHEET) { /* FILTERING OPTIONS */ - /* DopeSheet summary... */ - uiDefIconTextButBitI(block, TOG, ADS_FILTER_SUMMARY, B_REDR, ICON_BORDERMOVE, "Summary", xco,yco,XIC*4,YIC, &(saction->ads.filterflag), 0, 0, 0, 0, "Include DopeSheet summary row"); // TODO: needs a better icon - xco += (XIC*3.5); - - /* Standard filtering... */ + xco -= XIC; // XXX first button incurs this offset... xco= ANIM_headerUI_standard_buttons(C, &saction->ads, block, xco, yco); } else if (saction->mode == SACTCONT_ACTION) { uiLayout *layout; bScreen *sc= CTX_wm_screen(C); PointerRNA ptr; - + RNA_pointer_create(&sc->id, &RNA_SpaceDopeSheetEditor, saction, &ptr); layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, 20+3, 20, 1, U.uistyles.first); @@ -379,7 +379,7 @@ void action_header_buttons(const bContext *C, ARegion *ar) xco += (XIC + 8); } - /* always as last */ + /* always as last */ UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, (int)(ar->v2d.tot.ymax-ar->v2d.tot.ymin)); uiEndBlock(C, block); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index a011ba87948..8d590692794 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -444,9 +444,9 @@ typedef enum DOPESHEET_FILTERFLAG { } DOPESHEET_FILTERFLAG; /* DopeSheet general flags */ -//typedef enum DOPESHEET_FLAG { - -//} DOPESHEET_FLAG; +typedef enum DOPESHEET_FLAG { + ADS_FLAG_SUMMARY_COLLAPSED = (1<<0), /* when summary is shown, it is collapsed, so all other channels get hidden */ +} DOPESHEET_FLAG; -- cgit v1.2.3 From 0b1957793052e4b3b3d195a1562c8ff7706074e4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 10:33:27 +0000 Subject: skin/loft was broken, was passing short[2] as float[2] --- release/scripts/io/mesh_skin.py | 4 ++-- source/blender/editors/armature/editarmature_sketch.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/io/mesh_skin.py b/release/scripts/io/mesh_skin.py index 5487b6ba10b..79b78c15274 100644 --- a/release/scripts/io/mesh_skin.py +++ b/release/scripts/io/mesh_skin.py @@ -227,8 +227,8 @@ def mesh_faces_extend(me, faces): me.add_geometry(0, 0, new_facetot) tot = orig_facetot+new_facetot me_faces = me.faces - i= orig_facetot - while i < tot: + i= 0 + while i < new_facetot: f = [v.index for v in faces[i]] if len(f)==4 and f[3]==0: diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index ce328ea8a82..b3dd8f35137 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1083,7 +1083,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok mvalf[0]= dd->mval[0]; mvalf[1]= dd->mval[1]; - peelObjectsContext(C, &sketch->depth_peels, dd->mval); + peelObjectsContext(C, &sketch->depth_peels, mvalf); if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) { -- cgit v1.2.3 From 3d57e840882486fa8a86ec544eb80691a392aea4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 11:17:59 +0000 Subject: Bugfix: new bump mapping with UV coordinates wasn't working correct, my mistake in merging the patch. --- source/blender/render/intern/source/texture.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 64683e8e7da..9510dc15e5a 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1736,6 +1736,16 @@ void do_material_tex(ShadeInput *shi) vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3); + // compute ortho basis around normal + if(!nunvdone) { + // render normal is negated + nn[0] = -shi->vn[0]; + nn[1] = -shi->vn[1]; + nn[2] = -shi->vn[2]; + VecOrthoBasisf(nn, nu, nv); + nunvdone= 1; + } + if (tf) { float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3]; const float an[3] = {fabsf(nn[0]), fabsf(nn[1]), fabsf(nn[2])}; -- cgit v1.2.3 From cd202a1a24a7ef1ca396df4e679b240915fbc446 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 14 Oct 2009 11:57:26 +0000 Subject: Drivers UI - Converting to Layout Engine * Converted Drivers UI to mostly use the Layout Engine * All the buttons that perform actions are not operators yet (the code for that would be quite icky still) * I've added some (commented out) calls for the property definitions of Driver properties to perform Depsgraph updates. I've left these commented out until we have the option to turn off auto-updates, since with driver editing, that could be very dangerous. * Drivers can now (in theory) use any ID-block, using the Any-ID template added earlier. However, be warned that the stupid depsgraph won't be able to cope with most of these cases. TODO: - more fancy widgets for RNA-Path and Index will come later --- .../editors/animation/anim_channels_defines.c | 2 +- .../editors/interface/interface_templates.c | 1 - source/blender/editors/space_graph/graph_buttons.c | 150 ++++++++++----------- source/blender/makesrna/intern/rna_fcurve.c | 27 +++- 4 files changed, 96 insertions(+), 84 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index c9052431d3c..7c9814eda7b 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -2189,7 +2189,7 @@ void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float /* ------------------ */ -/* callback for widget settings - send notifiers */ +/* callback for (normal) widget settings - send notifiers */ static void achannel_setting_widget_cb(bContext *C, void *poin, void *poin2) { WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index a7c586be42a..de0d6191f16 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -438,7 +438,6 @@ void uiTemplateAnyID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn uiItemL(row, "ID-Block:", 0); /* ID-Type Selector - just have a menu of icons */ - // XXX should value really be 0? uiItemFullR(row, "", 0, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY); /* ID-Block Selector - just use pointer widget... */ diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index afc86309ffb..fa44b281f15 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -193,7 +193,7 @@ static void do_graph_region_driver_buttons(bContext *C, void *arg, int event) } /* default for now */ - WM_event_add_notifier(C, NC_SCENE, scene); + WM_event_add_notifier(C, NC_SCENE, scene); // XXX does this always work? } /* callback to remove the active driver */ @@ -251,21 +251,6 @@ static int graph_panel_drivers_poll(const bContext *C, PanelType *pt) return graph_panel_context(C, NULL, NULL); } -static void test_obpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - id= CTX_data_main(C)->object.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ - return; - } - id= id->next; - } - *idpp= NULL; -} /* driver settings for active F-Curve (only for 'Drivers' mode) */ static void graph_panel_drivers(const bContext *C, Panel *pa) @@ -275,91 +260,98 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) ChannelDriver *driver; DriverTarget *dtar; - PointerRNA rna_ptr; + PointerRNA driver_ptr; + uiLayout *col; uiBlock *block; uiBut *but; - int yco=85, i=0; - - if(!graph_panel_context(C, &ale, &fcu)) + + /* Get settings from context */ + if (!graph_panel_context(C, &ale, &fcu)) return; - driver= fcu->driver; - block= uiLayoutAbsoluteBlock(pa->layout); + /* set event handler for panel */ + block= uiLayoutGetBlock(pa->layout); // xxx? uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); - /* general actions */ - but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Update Dependencies", 10, 200, 180, 22, NULL, 0.0, 0.0, 0, 0, "Force updates of dependencies"); - uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); - - but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Remove Driver", 200, 200, 110, 18, NULL, 0.0, 0.0, 0, 0, "Remove this driver"); - uiButSetFunc(but, driver_remove_cb, ale, NULL); - - /* type */ - uiDefBut(block, LABEL, 1, "Type:", 10, 170, 60, 20, NULL, 0.0, 0.0, 0, 0, ""); - uiDefButI(block, MENU, B_IPO_DEPCHANGE, - "Driver Type%t|Normal%x0|Scripted Expression%x1|Rotational Difference%x2", - 70,170,240,20, &driver->type, 0, 0, 0, 0, "Driver type"); + /* general actions - management */ + col= uiLayoutColumn(pa->layout, 0); + block= uiLayoutGetBlock(col); + but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Update Dependencies", 0, 0, 10*UI_UNIT_X, 22, NULL, 0.0, 0.0, 0, 0, "Force updates of dependencies"); + uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); + + but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Remove Driver", 0, 0, 10*UI_UNIT_X, 18, NULL, 0.0, 0.0, 0, 0, "Remove this driver"); + uiButSetFunc(but, driver_remove_cb, ale, NULL); + + /* driver-level settings - type, expressions, and errors */ + RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr); - /* show expression box if doing scripted drivers */ - if (driver->type == DRIVER_TYPE_PYTHON) { - uiDefBut(block, TEX, B_REDR, "Expr: ", 10,150,300,20, driver->expression, 0, 255, 0, 0, "One-liner Python Expression to use as Scripted Expression"); + col= uiLayoutColumn(pa->layout, 1); + block= uiLayoutGetBlock(col); + uiItemR(col, NULL, 0, &driver_ptr, "type", 0); - /* errors */ - if (driver->flag & DRIVER_FLAG_INVALID) { - uiDefIconBut(block, LABEL, 1, ICON_ERROR, 10, 130, 48, 48, NULL, 0, 0, 0, 0, ""); // a bit larger - uiDefBut(block, LABEL, 0, "Error: invalid Python expression", - 50,110,230,19, NULL, 0, 0, 0, 0, ""); + /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */ + if (driver->type == DRIVER_TYPE_PYTHON) { + /* expression */ + uiItemR(col, "Expr:", 0, &driver_ptr, "expression", 0); + + /* errors? */ + if (driver->flag & DRIVER_FLAG_INVALID) + uiItemL(col, "ERROR: invalid Python expression", ICON_ERROR); } - } - else { - /* errors */ - if (driver->flag & DRIVER_FLAG_INVALID) { - uiDefIconBut(block, LABEL, 1, ICON_ERROR, 10, 130, 48, 48, NULL, 0, 0, 0, 0, ""); // a bit larger - uiDefBut(block, LABEL, 0, "Error: invalid target channel(s)", - 50,130,230,19, NULL, 0, 0, 0, 0, ""); + else { + /* errors? */ + if (driver->flag & DRIVER_FLAG_INVALID) + uiItemL(col, "ERROR: invalid target channel(s)", ICON_ERROR); } - } - but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Add Variable", 10, 110, 300, 20, NULL, 0.0, 0.0, 0, 0, "Add a new target variable for this Driver"); - uiButSetFunc(but, driver_add_var_cb, driver, NULL); + /* add driver target variables */ + col= uiLayoutColumn(pa->layout, 0); + block= uiLayoutGetBlock(col); + but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Add Variable", 0, 0, 10*UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "Add a new target variable for this Driver"); + uiButSetFunc(but, driver_add_var_cb, driver, NULL); /* loop over targets, drawing them */ for (dtar= driver->targets.first; dtar; dtar= dtar->next) { - short height = (dtar->id) ? 80 : 60; + PointerRNA dtar_ptr; + uiLayout *box, *row; - /* panel behind buttons */ - uiDefBut(block, ROUNDBOX, B_REDR, "", 5, yco-height+25, 310, height, NULL, 5.0, 0.0, 12.0, 0, ""); + /* panel holding the buttons */ + box= uiLayoutBox(pa->layout); - /* variable name */ - uiDefButC(block, TEX, B_REDR, "Name: ", 10,yco,280,20, dtar->name, 0, 63, 0, 0, "Name of target variable (No spaces or dots are allowed. Also, must not start with a symbol or digit)."); + /* first row context info for driver */ + RNA_pointer_create(ale->id, &RNA_DriverTarget, dtar, &dtar_ptr); - /* remove button */ - but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 290, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete target variable."); - uiButSetFunc(but, driver_delete_var_cb, driver, dtar); + row= uiLayoutRow(box, 0); + block= uiLayoutGetBlock(row); + /* variable name */ + uiItemR(row, "", 0, &dtar_ptr, "name", 0); + + /* remove button */ + but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete target variable."); + uiButSetFunc(but, driver_delete_var_cb, driver, dtar); - /* Target Object */ - uiDefBut(block, LABEL, 1, "Value:", 10, yco-30, 60, 20, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob: ", 70, yco-30, 240, 20, &dtar->id, "Object to use as Driver target"); + /* Target ID */ + row= uiLayoutRow(box, 0); + uiTemplateAnyID(row, (bContext *)C, &dtar_ptr, "id", "id_type", "Value: "); - // XXX should we hide these technical details? + /* Target Property */ + // TODO: make this less technical... if (dtar->id) { - uiBlockBeginAlign(block); - /* RNA Path */ - RNA_pointer_create(ale->id, &RNA_DriverTarget, dtar, &rna_ptr); - uiDefButR(block, TEX, 0, "Path: ", 10, yco-50, 250, 20, &rna_ptr, "rna_path", 0, 0, 0, -1, -1, "RNA Path (from Driver Object) to property used as Driver."); - - /* Array Index */ - uiDefButI(block, NUM, B_REDR, "", 260,yco-50,50,20, &dtar->array_index, 0, INT_MAX, 0, 0, "Index to the specific property used as Driver if applicable."); - uiBlockEndAlign(block); + col= uiLayoutColumn(box, 1); + block= uiLayoutGetBlock(col); + /* rna path */ + // TODO: this needs path constructor widget + uiItemR(col, "Path", 0, &dtar_ptr, "rna_path", 0); + + /* array index */ + // TODO: this needs selector which limits it to ok values + uiItemR(col, "Index", 0, &dtar_ptr, "array_index", 0); } - - /* adjust y-coordinate for next target */ - yco -= height; - i++; } - + + /* cleanup */ MEM_freeN(ale); } @@ -373,8 +365,8 @@ static void do_graph_region_modifier_buttons(bContext *C, void *arg, int event) switch (event) { case B_REDR: case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too - ED_area_tag_redraw(CTX_wm_area(C)); - return; /* no notifier! */ + WM_event_add_notifier(C, NC_ANIMATION, NULL); // XXX need a notifier specially for F-Modifiers + break; } } diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 12a81afa2b5..271964bb483 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -32,6 +32,7 @@ #include "rna_internal.h" #include "DNA_anim_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -52,8 +53,6 @@ EnumPropertyItem fmodifier_type_items[] = { #ifdef RNA_RUNTIME -/* --------- */ - static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) { FModifier *fcm= (FModifier *)ptr->data; @@ -82,6 +81,21 @@ static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) /* ****************************** */ +#include "BKE_depsgraph.h" + +static void rna_ChannelDriver_update_data(bContext *C, PointerRNA *ptr) +{ + ID *id= ptr->id.data; + + // TODO: this really needs an update guard... + DAG_scene_sort(CTX_data_scene(C)); + DAG_id_flush_update(id, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_SCENE, id); +} + +/* ----------- */ + static StructRNA *rna_DriverTarget_id_typef(PointerRNA *ptr) { DriverTarget *dtar= (DriverTarget*)ptr->data; @@ -535,7 +549,8 @@ static void rna_def_drivertarget(BlenderRNA *brna) /* Variable Name */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); - RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions."); + RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions. (No spaces or dots are allowed. Also, must not start with a symbol or digit)"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates /* Target Properties - ID-block to Drive */ prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); @@ -544,20 +559,24 @@ static void rna_def_drivertarget(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_DriverTarget_id_editable"); RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_DriverTarget_id_typef"); RNA_def_property_ui_text(prop, "ID", "ID-block that the specific property used can be found from"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates prop= RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "idtype"); RNA_def_property_enum_items(prop, id_type_items); RNA_def_property_enum_default(prop, ID_OB); RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used."); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates /* Target Properties - Property to Drive */ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path (from Object) to property used"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE); RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property used (if applicable)"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates } static void rna_def_channeldriver(BlenderRNA *brna) @@ -579,10 +598,12 @@ static void rna_def_channeldriver(BlenderRNA *brna) prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_type_items); RNA_def_property_ui_text(prop, "Type", "Driver types."); + RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); /* String values */ prop= RNA_def_property(srna, "expression", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Expression", "Expression to use for Scripted Expression."); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates /* Collections */ prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE); -- cgit v1.2.3 From c7c2e3de1ea805096d2047f4321d928ce427b00f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 13:20:20 +0000 Subject: set scene, currently UI is in the render buttons, should be moved to a scene buttons area. added a property flag PROP_ID_SELF_CHECK, so properties can be set to point to anything but themselves. --- release/scripts/ui/buttons_scene.py | 5 ++-- source/blender/makesrna/RNA_types.h | 46 ++++++++++++++++------------- source/blender/makesrna/intern/makesrna.c | 10 +++++++ source/blender/makesrna/intern/rna_mesh.c | 2 +- source/blender/makesrna/intern/rna_object.c | 11 +------ source/blender/makesrna/intern/rna_scene.c | 21 +++++++++++++ 6 files changed, 61 insertions(+), 34 deletions(-) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index ce4adef354d..c4679d40a10 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -25,14 +25,15 @@ class SCENE_PT_render(RenderButtonsPanel): def draw(self, context): layout = self.layout - - rd = context.scene.render_data + scene = context.scene + rd = scene.render_data row = layout.row() row.itemO("screen.render", text="Image", icon='ICON_RENDER_STILL') row.item_booleanO("screen.render", "animation", True, text="Animation", icon='ICON_RENDER_ANIMATION') layout.itemR(rd, "display_mode", text="Display") + layout.itemR(scene, "set", text="Set Scene") # XXX - this should get its own 'scene buttons' class SCENE_PT_layers(RenderButtonsPanel): __label__ = "Layers" diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 576f5cbb984..20160946ff3 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -126,47 +126,51 @@ typedef enum PropertyFlag { /* editable means the property is editable in the user * interface, properties are editable by default except * for pointers and collections. */ - PROP_EDITABLE = 1, + PROP_EDITABLE = 1<<0, /* this property is editable even if it is lib linked, * meaning it will get lost on reload, but it's useful * for editing. */ - PROP_LIB_EXCEPTION = 65536, + PROP_LIB_EXCEPTION = 1<<16, /* animateable means the property can be driven by some * other input, be it animation curves, expressions, .. * properties are animateable by default except for pointers * and collections */ - PROP_ANIMATEABLE = 2, + PROP_ANIMATEABLE = 1<<1, /* icon */ - PROP_ICONS_CONSECUTIVE = 4096, + PROP_ICONS_CONSECUTIVE = 1<12, /* hidden in the user interface */ - PROP_HIDDEN = 524288, + PROP_HIDDEN = 1<<19, /* function paramater flags */ - PROP_REQUIRED = 4, - PROP_RETURN = 8, - PROP_RNAPTR = 2048, - + PROP_REQUIRED = 1<<2, + PROP_RETURN = 1<<3, + PROP_RNAPTR = 1<<11, /* registering */ - PROP_REGISTER = 16, - PROP_REGISTER_OPTIONAL = 16|32, + PROP_REGISTER = 1<<4, + PROP_REGISTER_OPTIONAL = (1<<4)|(1<<5), /* pointers */ - PROP_ID_REFCOUNT = 64, - PROP_NEVER_NULL = 262144, + PROP_ID_REFCOUNT = 1<<6, + + /* disallow assigning a variable to its self, eg an object tracking its self + * only apply this to types that are derived from an ID ()*/ + PROP_ID_SELF_CHECK = 1<<20, + + PROP_NEVER_NULL = 1<<18, /* internal flags */ - PROP_BUILTIN = 128, - PROP_EXPORT = 256, - PROP_RUNTIME = 512, - PROP_IDPROPERTY = 1024, - PROP_RAW_ACCESS = 8192, - PROP_RAW_ARRAY = 16384, - PROP_FREE_POINTERS = 32768, - PROP_DYNAMIC = 131072 /* for dynamic arrays, and retvals of type string */ + PROP_BUILTIN = 1<<7, + PROP_EXPORT = 1<<8, + PROP_RUNTIME = 1<<9, + PROP_IDPROPERTY = 1<<10, + PROP_RAW_ACCESS = 1<<13, + PROP_RAW_ARRAY = 1<<14, + PROP_FREE_POINTERS = 1<<15, + PROP_DYNAMIC = 1<<17 /* for dynamic arrays, and retvals of type string */ } PropertyFlag; typedef struct CollectionPropertyIterator { diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 63b58f27c53..7e473fcb096 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -144,6 +144,11 @@ static void rna_print_data_get(FILE *f, PropertyDefRNA *dp) fprintf(f, " %s *data= (%s*)(ptr->data);\n", dp->dnastructname, dp->dnastructname); } +static void rna_print_id_get(FILE *f, PropertyDefRNA *dp) +{ + fprintf(f, " ID *id= ptr->id.data;\n"); +} + static char *rna_alloc_function_name(const char *structname, const char *propname, const char *type) { AllocDefRNA *alloc; @@ -530,6 +535,11 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr else { rna_print_data_get(f, dp); + if(prop->flag & PROP_ID_SELF_CHECK) { + rna_print_id_get(f, dp); + fprintf(f, " if(id==value.data) return;\n\n"); + } + if(prop->flag & PROP_ID_REFCOUNT) { fprintf(f, "\n if(data->%s)\n", dp->dnaname); fprintf(f, " id_us_min((ID*)data->%s);\n", dp->dnaname); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 03fead8c54f..046f1ea1030 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1452,7 +1452,7 @@ static void rna_def_mesh(BlenderRNA *brna) /* TODO, should this be allowed to be its self? */ prop= RNA_def_property(srna, "texture_mesh", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "texcomesh"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK); RNA_def_property_ui_text(prop, "Texture Mesh", "Use another mesh for texture indicies (vertex indicies must be aligned)."); /* UV textures */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 6f2d455f660..2f40cacbda6 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -223,14 +223,6 @@ static void rna_Object_parent_type_set(PointerRNA *ptr, int value) ED_object_parent(ob, ob->parent, value, ob->parsubstr); } -static void rna_Object_track_set(PointerRNA *ptr, PointerRNA value) -{ - Object *ob= (Object*)ptr->data; - - if(ob != value.data) - ob->track= value.data; -} - static EnumPropertyItem *rna_Object_parent_type_itemf(bContext *C, PointerRNA *ptr, int *free) { Object *ob= (Object*)ptr->data; @@ -1219,8 +1211,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_dependency_update"); prop= RNA_def_property(srna, "track", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_track_set", NULL); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK); RNA_def_property_ui_text(prop, "Track", "Object being tracked to define the rotation (Old Track)."); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_dependency_update"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index d254c7c9eee..03c7a06818d 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -110,6 +110,19 @@ static void rna_Scene_active_object_set(PointerRNA *ptr, PointerRNA value) scene->basact= NULL; } +static void rna_Scene_set_set(PointerRNA *ptr, PointerRNA value) +{ + Scene *scene= (Scene*)ptr->data; + Scene *set= (Scene*)value.data; + Scene *nested_set; + + for(nested_set= set; nested_set; nested_set= nested_set->set) { + if(nested_set==scene) + return; + } + + scene->set= set; +} static int layer_set(int lay, const int *values) { @@ -2084,6 +2097,14 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Camera", "Active camera used for rendering the scene."); + prop= RNA_def_property(srna, "set", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "set"); + RNA_def_property_struct_type(prop, "Scene"); + //RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Scene_set_set", NULL); + RNA_def_property_ui_text(prop, "Set Scene", "Background set scene."); + prop= RNA_def_property(srna, "active_object", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_pointer_funcs(prop, "rna_Scene_active_object_get", "rna_Scene_active_object_set", NULL); -- cgit v1.2.3 From 1ce959b16e936a4e35808c04a95e1b143f46947d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 13:21:54 +0000 Subject: Shape Keys: disable the temporary shape display system, where it would show you the last selected shape key until doing another operation. This is confusing, and the Pin button allows you to do the same kind of shape browsing. --- source/blender/blenkernel/intern/depsgraph.c | 5 +---- source/blender/blenkernel/intern/key.c | 2 +- source/blender/editors/object/object_select.c | 7 ------- source/blender/makesdna/DNA_object_types.h | 2 +- source/blender/makesrna/intern/rna_object.c | 3 --- 5 files changed, 3 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index ec054bc47cd..26ea17a296a 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2037,7 +2037,6 @@ static void dag_object_time_update_flags(Object *ob) if(me->key) { if(!(ob->shapeflag & OB_SHAPE_LOCK)) { ob->recalc |= OB_RECALC_DATA; - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; } } if(ob->particlesystem.first) @@ -2049,7 +2048,6 @@ static void dag_object_time_update_flags(Object *ob) if(cu->key) { if(!(ob->shapeflag & OB_SHAPE_LOCK)) { ob->recalc |= OB_RECALC_DATA; - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; } } break; @@ -2063,7 +2061,6 @@ static void dag_object_time_update_flags(Object *ob) if(lt->key) { if(!(ob->shapeflag & OB_SHAPE_LOCK)) { ob->recalc |= OB_RECALC_DATA; - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; } } break; @@ -2216,7 +2213,7 @@ void DAG_id_flush_update(ID *id, short flag) else if(ob->type==OB_CURVE || ob->type==OB_SURF) id= NULL; /* also for locked shape keys we make an exception */ - else if(ob_get_key(ob) && (ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK))) + else if(ob_get_key(ob) && (ob->shapeflag & OB_SHAPE_LOCK)) id= NULL; } } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 39f9ed808fd..b6e4ffd6cc3 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1368,7 +1368,7 @@ int do_ob_key(Scene *scene, Object *ob) if(key==NULL) return 0; - if(ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)) { + if(ob->shapeflag & OB_SHAPE_LOCK) { KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1); if (G.f & G_DEBUG) printf("ob %s, key %s locked \n", ob->id.name+2, key->id.name+2); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 27713cc2fa9..90d1a9df93e 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -105,13 +105,6 @@ void ED_base_object_activate(bContext *C, Base *base) /* XXX old signals, remember to handle notifiers now! */ // select_actionchannel_by_name(base->object->action, "Object", 1); - /* disable temporal locks */ - for(tbase=FIRSTBASE; tbase; tbase= tbase->next) { - if(base!=tbase && (tbase->object->shapeflag & OB_SHAPE_TEMPLOCK)) { - tbase->object->shapeflag &= ~OB_SHAPE_TEMPLOCK; - DAG_id_flush_update(&tbase->object->id, OB_RECALC_DATA); - } - } WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); } else diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 73bf698db16..4cf78c83cd0 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -499,7 +499,7 @@ extern Object workob; /* ob->shapeflag */ #define OB_SHAPE_LOCK 1 -#define OB_SHAPE_TEMPLOCK 2 +#define OB_SHAPE_TEMPLOCK 2 // deprecated /* ob->nlaflag */ // XXX depreceated - old animation system diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 2f40cacbda6..092f18ef0e2 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -747,7 +747,6 @@ static void rna_Object_active_shape_key_index_set(PointerRNA *ptr, int value) Object *ob= (Object*)ptr->id.data; ob->shapenr= value+1; - ob->shapeflag |= OB_SHAPE_TEMPLOCK; } static PointerRNA rna_Object_active_shape_key_get(PointerRNA *ptr) @@ -771,8 +770,6 @@ static void rna_Object_shape_key_lock_set(PointerRNA *ptr, int value) if(value) ob->shapeflag |= OB_SHAPE_LOCK; else ob->shapeflag &= ~OB_SHAPE_LOCK; - - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; } static PointerRNA rna_Object_field_get(PointerRNA *ptr) -- cgit v1.2.3 From 1847f6198e50118e8e6541dfcb351dda40802511 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 14 Oct 2009 14:07:32 +0000 Subject: After discussion with Campbell, split Scene tab in Scene and Render. This makes a clearer distinction between render and scene settings. --- release/scripts/ui/buttons_render.py | 460 +++++++++++++++++++++ release/scripts/ui/buttons_scene.py | 450 +------------------- source/blender/editors/screen/screen_ops.c | 3 + .../editors/space_buttons/buttons_context.c | 1 + .../blender/editors/space_buttons/buttons_header.c | 4 +- .../blender/editors/space_buttons/space_buttons.c | 2 + source/blender/makesdna/DNA_space_types.h | 17 +- source/blender/makesrna/intern/rna_space.c | 1 + 8 files changed, 486 insertions(+), 452 deletions(-) create mode 100644 release/scripts/ui/buttons_render.py diff --git a/release/scripts/ui/buttons_render.py b/release/scripts/ui/buttons_render.py new file mode 100644 index 00000000000..a8f1b730ff7 --- /dev/null +++ b/release/scripts/ui/buttons_render.py @@ -0,0 +1,460 @@ + +import bpy + +class SceneButtonsPanel(bpy.types.Panel): + __space_type__ = 'PROPERTIES' + __region_type__ = 'WINDOW' + __context__ = "render" + + def poll(self, context): + return (context.scene != None) + +class RenderButtonsPanel(bpy.types.Panel): + __space_type__ = 'PROPERTIES' + __region_type__ = 'WINDOW' + __context__ = "render" + # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here + + def poll(self, context): + rd = context.scene.render_data + return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) + +class RENDER_PT_render(RenderButtonsPanel): + __label__ = "Render" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + row = layout.row() + row.itemO("screen.render", text="Image", icon='ICON_RENDER_STILL') + row.item_booleanO("screen.render", "animation", True, text="Animation", icon='ICON_RENDER_ANIMATION') + + layout.itemR(rd, "display_mode", text="Display") + +class RENDER_PT_layers(RenderButtonsPanel): + __label__ = "Layers" + __default_closed__ = True + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render_data + + row = layout.row() + row.template_list(rd, "layers", rd, "active_layer_index", rows=2) + + col = row.column(align=True) + col.itemO("scene.render_layer_add", icon='ICON_ZOOMIN', text="") + col.itemO("scene.render_layer_remove", icon='ICON_ZOOMOUT', text="") + + rl = rd.layers[rd.active_layer_index] + + split = layout.split() + + col = split.column() + col.itemR(scene, "visible_layers", text="Scene") + col = split.column() + col.itemR(rl, "visible_layers", text="Layer") + + layout.itemR(rl, "light_override", text="Light") + layout.itemR(rl, "material_override", text="Material") + + layout.itemS() + layout.itemL(text="Include:") + + split = layout.split() + + col = split.column() + col.itemR(rl, "zmask") + row = col.row() + row.itemR(rl, "zmask_negate", text="Negate") + row.active = rl.zmask + col.itemR(rl, "all_z") + + col = split.column() + col.itemR(rl, "solid") + col.itemR(rl, "halo") + col.itemR(rl, "ztransp") + + col = split.column() + col.itemR(rl, "sky") + col.itemR(rl, "edge") + col.itemR(rl, "strand") + + if rl.zmask: + split = layout.split() + split.itemL(text="Zmask Layers:") + split.column().itemR(rl, "zmask_layers", text="") + + layout.itemS() + + split = layout.split() + + col = split.column() + col.itemL(text="Passes:") + col.itemR(rl, "pass_combined") + col.itemR(rl, "pass_z") + col.itemR(rl, "pass_vector") + col.itemR(rl, "pass_normal") + col.itemR(rl, "pass_uv") + col.itemR(rl, "pass_mist") + col.itemR(rl, "pass_object_index") + + col = split.column() + col.itemL() + col.itemR(rl, "pass_color") + col.itemR(rl, "pass_diffuse") + row = col.row() + row.itemR(rl, "pass_specular") + row.itemR(rl, "pass_specular_exclude", text="", icon='ICON_X') + row = col.row() + row.itemR(rl, "pass_shadow") + row.itemR(rl, "pass_shadow_exclude", text="", icon='ICON_X') + row = col.row() + row.itemR(rl, "pass_ao") + row.itemR(rl, "pass_ao_exclude", text="", icon='ICON_X') + row = col.row() + row.itemR(rl, "pass_reflection") + row.itemR(rl, "pass_reflection_exclude", text="", icon='ICON_X') + row = col.row() + row.itemR(rl, "pass_refraction") + row.itemR(rl, "pass_refraction_exclude", text="", icon='ICON_X') + +class RENDER_PT_shading(RenderButtonsPanel): + __label__ = "Shading" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + split = layout.split() + + col = split.column() + col.itemR(rd, "render_textures", text="Textures") + col.itemR(rd, "render_shadows", text="Shadows") + col.itemR(rd, "render_sss", text="Subsurface Scattering") + col.itemR(rd, "render_envmaps", text="Environment Map") + + col = split.column() + col.itemR(rd, "render_raytracing", text="Ray Tracing") + col.itemR(rd, "color_management") + col.itemR(rd, "alpha_mode", text="Alpha") + +class RENDER_PT_performance(RenderButtonsPanel): + __label__ = "Performance" + __default_closed__ = True + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + split = layout.split() + + col = split.column(align=True) + col.itemL(text="Threads:") + col.row().itemR(rd, "threads_mode", expand=True) + sub = col.column() + sub.enabled = rd.threads_mode == 'THREADS_FIXED' + sub.itemR(rd, "threads") + col.itemL(text="Tiles:") + col.itemR(rd, "parts_x", text="X") + col.itemR(rd, "parts_y", text="Y") + + col = split.column() + col.itemL(text="Memory:") + sub = col.column() + sub.itemR(rd, "save_buffers") + sub.enabled = not rd.full_sample + sub = col.column() + sub.active = rd.use_compositing + sub.itemR(rd, "free_image_textures") + sub = col.column() + sub.active = rd.render_raytracing + sub.itemL(text="Acceleration structure:") + sub.itemR(rd, "raytrace_structure", text="") + if rd.raytrace_structure == "OCTREE": + sub.itemR(rd, "octree_resolution", text="Resolution") + else: + sub.itemR(rd, "use_instances", text="Instances") + sub.itemR(rd, "use_local_coords", text="Local Coordinates") + +class RENDER_PT_post_processing(RenderButtonsPanel): + __label__ = "Post Processing" + __default_closed__ = True + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + split = layout.split() + + col = split.column() + col.itemR(rd, "use_compositing") + col.itemR(rd, "use_sequencer") + + col = split.column() + col.itemR(rd, "dither_intensity", text="Dither", slider=True) + + layout.itemS() + + split = layout.split() + + col = split.column() + col.itemR(rd, "fields", text="Fields") + sub = col.column() + sub.active = rd.fields + sub.row().itemR(rd, "field_order", expand=True) + sub.itemR(rd, "fields_still", text="Still") + + col = split.column() + col.itemR(rd, "edge") + sub = col.column() + sub.active = rd.edge + sub.itemR(rd, "edge_threshold", text="Threshold", slider=True) + sub.itemR(rd, "edge_color", text="") + +class RENDER_PT_output(RenderButtonsPanel): + __label__ = "Output" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + layout.itemR(rd, "output_path", text="") + + split = layout.split() + col = split.column() + col.itemR(rd, "file_format", text="") + col.row().itemR(rd, "color_mode", text="Color", expand=True) + + col = split.column() + col.itemR(rd, "file_extensions") + col.itemR(rd, "use_overwrite") + col.itemR(rd, "use_placeholder") + + if rd.file_format in ('AVIJPEG', 'JPEG'): + split = layout.split() + split.itemR(rd, "quality", slider=True) + + elif rd.file_format == 'OPENEXR': + split = layout.split() + + col = split.column() + col.itemL(text="Codec:") + col.itemR(rd, "exr_codec", text="") + + subsplit = split.split() + col = subsplit.column() + col.itemR(rd, "exr_half") + col.itemR(rd, "exr_zbuf") + col = subsplit.column() + col.itemR(rd, "exr_preview") + + elif rd.file_format == 'JPEG2000': + split = layout.split() + col = split.column() + col.itemL(text="Depth:") + col.row().itemR(rd, "jpeg2k_depth", expand=True) + + col = split.column() + col.itemR(rd, "jpeg2k_preset", text="") + col.itemR(rd, "jpeg2k_ycc") + + elif rd.file_format in ('CINEON', 'DPX'): + split = layout.split() + col = split.column() + col.itemR(rd, "cineon_log", text="Convert to Log") + + col = split.column(align=True) + col.active = rd.cineon_log + col.itemR(rd, "cineon_black", text="Black") + col.itemR(rd, "cineon_white", text="White") + col.itemR(rd, "cineon_gamma", text="Gamma") + + elif rd.file_format == 'TIFF': + split = layout.split() + split.itemR(rd, "tiff_bit") + +class RENDER_PT_encoding(RenderButtonsPanel): + __label__ = "Encoding" + __default_closed__ = True + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def poll(self, context): + rd = context.scene.render_data + return rd.file_format in ('FFMPEG', 'XVID', 'H264', 'THEORA') + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + split = layout.split() + + split.itemR(rd, "ffmpeg_format") + if rd.ffmpeg_format in ('AVI', 'QUICKTIME', 'MKV', 'OGG'): + split.itemR(rd, "ffmpeg_codec") + else: + split.itemL() + + split = layout.split() + + col = split.column() + col.itemR(rd, "ffmpeg_video_bitrate") + col.itemL(text="Rate:") + col.itemR(rd, "ffmpeg_minrate", text="Minimum") + col.itemR(rd, "ffmpeg_maxrate", text="Maximum") + col.itemR(rd, "ffmpeg_buffersize", text="Buffer") + + col = split.column() + col.itemR(rd, "ffmpeg_gopsize") + col.itemR(rd, "ffmpeg_autosplit") + col.itemL(text="Mux:") + col.itemR(rd, "ffmpeg_muxrate", text="Rate") + col.itemR(rd, "ffmpeg_packetsize", text="Packet Size") + + row = layout.row() + row.itemL(text="Audio:") + row = layout.row() + row.itemR(rd, "ffmpeg_audio_codec") + + split = layout.split() + + col = split.column() + col.itemR(rd, "ffmpeg_audio_bitrate") + col.itemR(rd, "ffmpeg_audio_mixrate") + col = split.column() + col.itemR(rd, "ffmpeg_multiplex_audio") + col.itemR(rd, "ffmpeg_audio_volume") + +class RENDER_PT_antialiasing(RenderButtonsPanel): + __label__ = "Anti-Aliasing" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw_header(self, context): + rd = context.scene.render_data + + self.layout.itemR(rd, "antialiasing", text="") + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + layout.active = rd.antialiasing + + split = layout.split() + + col = split.column() + col.row().itemR(rd, "antialiasing_samples", expand=True) + col.itemR(rd, "full_sample") + + col = split.column() + col.itemR(rd, "pixel_filter", text="") + col.itemR(rd, "filter_size", text="Size", slider=True) + +class RENDER_PT_dimensions(RenderButtonsPanel): + __label__ = "Dimensions" + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw(self, context): + layout = self.layout + + scene = context.scene + rd = scene.render_data + + split = layout.split() + + col = split.column() + sub = col.column(align=True) + sub.itemL(text="Resolution:") + sub.itemR(rd, "resolution_x", text="X") + sub.itemR(rd, "resolution_y", text="Y") + sub.itemR(rd, "resolution_percentage", text="") + + sub.itemL(text="Aspect Ratio:") + sub.itemR(rd, "pixel_aspect_x", text="X") + sub.itemR(rd, "pixel_aspect_y", text="Y") + + row = col.row() + row.itemR(rd, "use_border", text="Border") + rowsub = row.row() + rowsub.active = rd.use_border + rowsub.itemR(rd, "crop_to_border", text="Crop") + + col = split.column(align=True) + col.itemL(text="Frame Range:") + col.itemR(scene, "start_frame", text="Start") + col.itemR(scene, "end_frame", text="End") + col.itemR(scene, "frame_step", text="Step") + + col.itemL(text="Frame Rate:") + col.itemR(rd, "fps") + col.itemR(rd, "fps_base",text="/") + +class RENDER_PT_stamp(RenderButtonsPanel): + __label__ = "Stamp" + __default_closed__ = True + COMPAT_ENGINES = set(['BLENDER_RENDER']) + + def draw_header(self, context): + rd = context.scene.render_data + + self.layout.itemR(rd, "render_stamp", text="") + + def draw(self, context): + layout = self.layout + + rd = context.scene.render_data + + layout.active = rd.render_stamp + + split = layout.split() + + col = split.column() + col.itemR(rd, "stamp_time", text="Time") + col.itemR(rd, "stamp_date", text="Date") + col.itemR(rd, "stamp_frame", text="Frame") + col.itemR(rd, "stamp_scene", text="Scene") + col.itemR(rd, "stamp_camera", text="Camera") + col.itemR(rd, "stamp_filename", text="Filename") + col.itemR(rd, "stamp_marker", text="Marker") + col.itemR(rd, "stamp_sequence_strip", text="Seq. Strip") + + col = split.column() + col.active = rd.render_stamp + col.itemR(rd, "stamp_foreground", slider=True) + col.itemR(rd, "stamp_background", slider=True) + col.itemR(rd, "stamp_font_size", text="Font Size") + + row = layout.split(percentage=0.2) + row.itemR(rd, "stamp_note", text="Note") + sub = row.row() + sub.active = rd.stamp_note + sub.itemR(rd, "stamp_note_text", text="") + + +bpy.types.register(RENDER_PT_render) +bpy.types.register(RENDER_PT_layers) +bpy.types.register(RENDER_PT_dimensions) +bpy.types.register(RENDER_PT_antialiasing) +bpy.types.register(RENDER_PT_shading) +bpy.types.register(RENDER_PT_output) +bpy.types.register(RENDER_PT_encoding) +bpy.types.register(RENDER_PT_performance) +bpy.types.register(RENDER_PT_post_processing) +bpy.types.register(RENDER_PT_stamp) + diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index c4679d40a10..6c68e793852 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -9,445 +9,19 @@ class SceneButtonsPanel(bpy.types.Panel): def poll(self, context): return (context.scene != None) -class RenderButtonsPanel(bpy.types.Panel): - __space_type__ = 'PROPERTIES' - __region_type__ = 'WINDOW' - __context__ = "scene" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - - def poll(self, context): - rd = context.scene.render_data - return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) - -class SCENE_PT_render(RenderButtonsPanel): - __label__ = "Render" +class SCENE_PT_scene(SceneButtonsPanel): + __label__ = "Scene" COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - scene = context.scene - rd = scene.render_data - row = layout.row() - row.itemO("screen.render", text="Image", icon='ICON_RENDER_STILL') - row.item_booleanO("screen.render", "animation", True, text="Animation", icon='ICON_RENDER_ANIMATION') - - layout.itemR(rd, "display_mode", text="Display") - layout.itemR(scene, "set", text="Set Scene") # XXX - this should get its own 'scene buttons' - -class SCENE_PT_layers(RenderButtonsPanel): - __label__ = "Layers" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - def draw(self, context): layout = self.layout scene = context.scene - rd = scene.render_data - - row = layout.row() - row.template_list(rd, "layers", rd, "active_layer_index", rows=2) - - col = row.column(align=True) - col.itemO("scene.render_layer_add", icon='ICON_ZOOMIN', text="") - col.itemO("scene.render_layer_remove", icon='ICON_ZOOMOUT', text="") - - rl = rd.layers[rd.active_layer_index] - - split = layout.split() - - col = split.column() - col.itemR(scene, "visible_layers", text="Scene") - col = split.column() - col.itemR(rl, "visible_layers", text="Layer") - - layout.itemR(rl, "light_override", text="Light") - layout.itemR(rl, "material_override", text="Material") - - layout.itemS() - layout.itemL(text="Include:") - - split = layout.split() - - col = split.column() - col.itemR(rl, "zmask") - row = col.row() - row.itemR(rl, "zmask_negate", text="Negate") - row.active = rl.zmask - col.itemR(rl, "all_z") - - col = split.column() - col.itemR(rl, "solid") - col.itemR(rl, "halo") - col.itemR(rl, "ztransp") - - col = split.column() - col.itemR(rl, "sky") - col.itemR(rl, "edge") - col.itemR(rl, "strand") - - if rl.zmask: - split = layout.split() - split.itemL(text="Zmask Layers:") - split.column().itemR(rl, "zmask_layers", text="") - - layout.itemS() - - split = layout.split() - - col = split.column() - col.itemL(text="Passes:") - col.itemR(rl, "pass_combined") - col.itemR(rl, "pass_z") - col.itemR(rl, "pass_vector") - col.itemR(rl, "pass_normal") - col.itemR(rl, "pass_uv") - col.itemR(rl, "pass_mist") - col.itemR(rl, "pass_object_index") - - col = split.column() - col.itemL() - col.itemR(rl, "pass_color") - col.itemR(rl, "pass_diffuse") - row = col.row() - row.itemR(rl, "pass_specular") - row.itemR(rl, "pass_specular_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_shadow") - row.itemR(rl, "pass_shadow_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_ao") - row.itemR(rl, "pass_ao_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_reflection") - row.itemR(rl, "pass_reflection_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_refraction") - row.itemR(rl, "pass_refraction_exclude", text="", icon='ICON_X') - -class SCENE_PT_shading(RenderButtonsPanel): - __label__ = "Shading" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - split = layout.split() - - col = split.column() - col.itemR(rd, "render_textures", text="Textures") - col.itemR(rd, "render_shadows", text="Shadows") - col.itemR(rd, "render_sss", text="Subsurface Scattering") - col.itemR(rd, "render_envmaps", text="Environment Map") - - col = split.column() - col.itemR(rd, "render_raytracing", text="Ray Tracing") - col.itemR(rd, "color_management") - col.itemR(rd, "alpha_mode", text="Alpha") - -class SCENE_PT_performance(RenderButtonsPanel): - __label__ = "Performance" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - split = layout.split() - - col = split.column(align=True) - col.itemL(text="Threads:") - col.row().itemR(rd, "threads_mode", expand=True) - sub = col.column() - sub.enabled = rd.threads_mode == 'THREADS_FIXED' - sub.itemR(rd, "threads") - col.itemL(text="Tiles:") - col.itemR(rd, "parts_x", text="X") - col.itemR(rd, "parts_y", text="Y") - - col = split.column() - col.itemL(text="Memory:") - sub = col.column() - sub.itemR(rd, "save_buffers") - sub.enabled = not rd.full_sample - sub = col.column() - sub.active = rd.use_compositing - sub.itemR(rd, "free_image_textures") - sub = col.column() - sub.active = rd.render_raytracing - sub.itemL(text="Acceleration structure:") - sub.itemR(rd, "raytrace_structure", text="") - if rd.raytrace_structure == "OCTREE": - sub.itemR(rd, "octree_resolution", text="Resolution") - else: - sub.itemR(rd, "use_instances", text="Instances") - sub.itemR(rd, "use_local_coords", text="Local Coordinates") - -class SCENE_PT_post_processing(RenderButtonsPanel): - __label__ = "Post Processing" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - split = layout.split() - - col = split.column() - col.itemR(rd, "use_compositing") - col.itemR(rd, "use_sequencer") - - col = split.column() - col.itemR(rd, "dither_intensity", text="Dither", slider=True) - - layout.itemS() - - split = layout.split() - - col = split.column() - col.itemR(rd, "fields", text="Fields") - sub = col.column() - sub.active = rd.fields - sub.row().itemR(rd, "field_order", expand=True) - sub.itemR(rd, "fields_still", text="Still") - - col = split.column() - col.itemR(rd, "edge") - sub = col.column() - sub.active = rd.edge - sub.itemR(rd, "edge_threshold", text="Threshold", slider=True) - sub.itemR(rd, "edge_color", text="") - -class SCENE_PT_output(RenderButtonsPanel): - __label__ = "Output" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data + layout.itemR(scene, "camera") + layout.itemR(scene, "set", text="Background") - layout.itemR(rd, "output_path", text="") - split = layout.split() - col = split.column() - col.itemR(rd, "file_format", text="") - col.row().itemR(rd, "color_mode", text="Color", expand=True) - - col = split.column() - col.itemR(rd, "file_extensions") - col.itemR(rd, "use_overwrite") - col.itemR(rd, "use_placeholder") - - if rd.file_format in ('AVIJPEG', 'JPEG'): - split = layout.split() - split.itemR(rd, "quality", slider=True) - - elif rd.file_format == 'OPENEXR': - split = layout.split() - - col = split.column() - col.itemL(text="Codec:") - col.itemR(rd, "exr_codec", text="") - - subsplit = split.split() - col = subsplit.column() - col.itemR(rd, "exr_half") - col.itemR(rd, "exr_zbuf") - col = subsplit.column() - col.itemR(rd, "exr_preview") - - elif rd.file_format == 'JPEG2000': - split = layout.split() - col = split.column() - col.itemL(text="Depth:") - col.row().itemR(rd, "jpeg2k_depth", expand=True) - - col = split.column() - col.itemR(rd, "jpeg2k_preset", text="") - col.itemR(rd, "jpeg2k_ycc") - - elif rd.file_format in ('CINEON', 'DPX'): - split = layout.split() - col = split.column() - col.itemR(rd, "cineon_log", text="Convert to Log") - - col = split.column(align=True) - col.active = rd.cineon_log - col.itemR(rd, "cineon_black", text="Black") - col.itemR(rd, "cineon_white", text="White") - col.itemR(rd, "cineon_gamma", text="Gamma") - - elif rd.file_format == 'TIFF': - split = layout.split() - split.itemR(rd, "tiff_bit") - -class SCENE_PT_encoding(RenderButtonsPanel): - __label__ = "Encoding" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def poll(self, context): - rd = context.scene.render_data - return rd.file_format in ('FFMPEG', 'XVID', 'H264', 'THEORA') - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - split = layout.split() - - split.itemR(rd, "ffmpeg_format") - if rd.ffmpeg_format in ('AVI', 'QUICKTIME', 'MKV', 'OGG'): - split.itemR(rd, "ffmpeg_codec") - else: - split.itemL() - - split = layout.split() - - col = split.column() - col.itemR(rd, "ffmpeg_video_bitrate") - col.itemL(text="Rate:") - col.itemR(rd, "ffmpeg_minrate", text="Minimum") - col.itemR(rd, "ffmpeg_maxrate", text="Maximum") - col.itemR(rd, "ffmpeg_buffersize", text="Buffer") - - col = split.column() - col.itemR(rd, "ffmpeg_gopsize") - col.itemR(rd, "ffmpeg_autosplit") - col.itemL(text="Mux:") - col.itemR(rd, "ffmpeg_muxrate", text="Rate") - col.itemR(rd, "ffmpeg_packetsize", text="Packet Size") - - row = layout.row() - row.itemL(text="Audio:") - row = layout.row() - row.itemR(rd, "ffmpeg_audio_codec") - - split = layout.split() - - col = split.column() - col.itemR(rd, "ffmpeg_audio_bitrate") - col.itemR(rd, "ffmpeg_audio_mixrate") - col = split.column() - col.itemR(rd, "ffmpeg_multiplex_audio") - col.itemR(rd, "ffmpeg_audio_volume") - -class SCENE_PT_antialiasing(RenderButtonsPanel): - __label__ = "Anti-Aliasing" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw_header(self, context): - rd = context.scene.render_data - - self.layout.itemR(rd, "antialiasing", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - layout.active = rd.antialiasing - - split = layout.split() - - col = split.column() - col.row().itemR(rd, "antialiasing_samples", expand=True) - col.itemR(rd, "full_sample") - - col = split.column() - col.itemR(rd, "pixel_filter", text="") - col.itemR(rd, "filter_size", text="Size", slider=True) - -class SCENE_PT_dimensions(RenderButtonsPanel): - __label__ = "Dimensions" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - - scene = context.scene - rd = scene.render_data - - split = layout.split() - - col = split.column() - sub = col.column(align=True) - sub.itemL(text="Resolution:") - sub.itemR(rd, "resolution_x", text="X") - sub.itemR(rd, "resolution_y", text="Y") - sub.itemR(rd, "resolution_percentage", text="") - - sub.itemL(text="Aspect Ratio:") - sub.itemR(rd, "pixel_aspect_x", text="X") - sub.itemR(rd, "pixel_aspect_y", text="Y") - - row = col.row() - row.itemR(rd, "use_border", text="Border") - rowsub = row.row() - rowsub.active = rd.use_border - rowsub.itemR(rd, "crop_to_border", text="Crop") - - col = split.column(align=True) - col.itemL(text="Frame Range:") - col.itemR(scene, "start_frame", text="Start") - col.itemR(scene, "end_frame", text="End") - col.itemR(scene, "frame_step", text="Step") - - col.itemL(text="Frame Rate:") - col.itemR(rd, "fps") - col.itemR(rd, "fps_base",text="/") - -class SCENE_PT_stamp(RenderButtonsPanel): - __label__ = "Stamp" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw_header(self, context): - rd = context.scene.render_data - - self.layout.itemR(rd, "render_stamp", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - layout.active = rd.render_stamp - - split = layout.split() - - col = split.column() - col.itemR(rd, "stamp_time", text="Time") - col.itemR(rd, "stamp_date", text="Date") - col.itemR(rd, "stamp_frame", text="Frame") - col.itemR(rd, "stamp_scene", text="Scene") - col.itemR(rd, "stamp_camera", text="Camera") - col.itemR(rd, "stamp_filename", text="Filename") - col.itemR(rd, "stamp_marker", text="Marker") - col.itemR(rd, "stamp_sequence_strip", text="Seq. Strip") - - col = split.column() - col.active = rd.render_stamp - col.itemR(rd, "stamp_foreground", slider=True) - col.itemR(rd, "stamp_background", slider=True) - col.itemR(rd, "stamp_font_size", text="Font Size") - - row = layout.split(percentage=0.2) - row.itemR(rd, "stamp_note", text="Note") - sub = row.row() - sub.active = rd.stamp_note - sub.itemR(rd, "stamp_note_text", text="") - -class SCENE_PT_unit(RenderButtonsPanel): +class SCENE_PT_unit(SceneButtonsPanel): __label__ = "Units" __default_closed__ = True COMPAT_ENGINES = set(['BLENDER_RENDER']) @@ -549,7 +123,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): -class SCENE_PT_physics(RenderButtonsPanel): +class SCENE_PT_physics(SceneButtonsPanel): __label__ = "Gravity" COMPAT_ENGINES = set(['BLENDER_RENDER']) @@ -565,17 +139,7 @@ class SCENE_PT_physics(RenderButtonsPanel): layout.itemR(scene, "gravity", text="") - -bpy.types.register(SCENE_PT_render) -bpy.types.register(SCENE_PT_layers) -bpy.types.register(SCENE_PT_dimensions) -bpy.types.register(SCENE_PT_antialiasing) -bpy.types.register(SCENE_PT_shading) -bpy.types.register(SCENE_PT_output) -bpy.types.register(SCENE_PT_encoding) -bpy.types.register(SCENE_PT_performance) -bpy.types.register(SCENE_PT_post_processing) -bpy.types.register(SCENE_PT_stamp) +bpy.types.register(SCENE_PT_scene) bpy.types.register(SCENE_PT_unit) bpy.types.register(SCENE_PT_keying_sets) bpy.types.register(SCENE_PT_keying_set_paths) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 74303e8a6a3..eeddeee25bf 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3410,6 +3410,9 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_render_view_show", F11KEY, KM_PRESS, 0, 0); /* user prefs */ + #ifdef __APPLE__ + WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_OSKEY, 0); + #endif WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", UKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index fe437dfd188..c6cde9f1c6b 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -437,6 +437,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma * tracing back recursively */ switch(mainb) { case BCONTEXT_SCENE: + case BCONTEXT_RENDER: found= buttons_context_path_scene(path); break; case BCONTEXT_WORLD: diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index 83dd679c543..1bf2a058b5a 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -107,8 +107,10 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) // Default panels uiBlockBeginAlign(block); + if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_RENDER, 0, 0, "Render"); if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_SCENE, 0, 0, "Scene"); + uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_SCENE_DATA, xco+=BUTS_UI_UNIT, yco, BUTS_UI_UNIT, BUTS_UI_UNIT, &(sbuts->mainb), 0.0, (float)BCONTEXT_SCENE, 0, 0, "Scene"); if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_WORLD, 0, 0, "World"); if(sbuts->pathflag & (1<mainb == BCONTEXT_SCENE) ED_region_panels(C, ar, vertical, "scene", sbuts->mainb); + else if(sbuts->mainb == BCONTEXT_RENDER) + ED_region_panels(C, ar, vertical, "render", sbuts->mainb); else if(sbuts->mainb == BCONTEXT_WORLD) ED_region_panels(C, ar, vertical, "world", sbuts->mainb); else if(sbuts->mainb == BCONTEXT_OBJECT) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index ce4f0bc8737..0c2b89b7b29 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -569,14 +569,15 @@ typedef struct SpaceUserPref { /* buts->mainb new */ -#define BCONTEXT_SCENE 0 -#define BCONTEXT_WORLD 1 -#define BCONTEXT_OBJECT 2 -#define BCONTEXT_DATA 3 -#define BCONTEXT_MATERIAL 4 -#define BCONTEXT_TEXTURE 5 -#define BCONTEXT_PARTICLE 6 -#define BCONTEXT_PHYSICS 7 +#define BCONTEXT_SCENE 0 +#define BCONTEXT_RENDER 1 +#define BCONTEXT_WORLD 2 +#define BCONTEXT_OBJECT 3 +#define BCONTEXT_DATA 4 +#define BCONTEXT_MATERIAL 5 +#define BCONTEXT_TEXTURE 6 +#define BCONTEXT_PARTICLE 7 +#define BCONTEXT_PHYSICS 8 #define BCONTEXT_BONE 9 #define BCONTEXT_MODIFIER 10 #define BCONTEXT_CONSTRAINT 12 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7d77660db6d..5665d9d7adc 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -821,6 +821,7 @@ static void rna_def_space_buttons(BlenderRNA *brna) static EnumPropertyItem buttons_context_items[] = { {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"}, + {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"}, {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"}, {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"}, {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"}, -- cgit v1.2.3 From 4ef0ef19276209480ec9ad9acbafff1e45a21e82 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 14:28:05 +0000 Subject: added mesh mirror flag, now store this per mesh button in mesh interface also dont register operators that change context --- release/scripts/modules/bpy_ops.py | 12 ------------ release/scripts/ui/buttons_data_mesh.py | 3 +++ source/blender/editors/include/ED_mesh.h | 2 +- source/blender/editors/mesh/editmesh_mods.c | 2 +- source/blender/editors/transform/transform_generics.c | 2 +- source/blender/makesdna/DNA_mesh_types.h | 7 ++++++- source/blender/makesrna/intern/rna_mesh.c | 15 +++++++++++++++ 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py index 022c0581a81..0360964be3f 100644 --- a/release/scripts/modules/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py @@ -157,9 +157,6 @@ class WM_OT_context_set(bpy.types.Operator): '''Set a context value.''' __idname__ = "wm.context_set" __label__ = "Context Set" - __register__ = True - __undo__ = True - __props__ = [ bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), bpy.props.StringProperty(attr="value", name="Value", description="Assignment value (as a string)", maxlen= 1024, default= "") @@ -173,9 +170,6 @@ class WM_OT_context_toggle(bpy.types.Operator): '''Toggle a context value.''' __idname__ = "wm.context_toggle" __label__ = "Context Toggle" - __register__ = True - __undo__ = True - __props__ = [ bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), ] @@ -188,9 +182,6 @@ class WM_OT_context_toggle_values(bpy.types.Operator): '''Toggle a context value.''' __idname__ = "wm.context_toggle_values" __label__ = "Context Toggle Values" - __register__ = True - __undo__ = True - __props__ = [ bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), bpy.props.StringProperty(attr="value_1", name="Value", description="Toggle value (as a string)", maxlen= 1024, default= ""), @@ -205,9 +196,6 @@ class WM_OT_context_cycle_enum(bpy.types.Operator): '''Toggle a context value.''' __idname__ = "wm.context_cycle_enum" __label__ = "Context Enum Cycle" - __register__ = True - __undo__ = True - __props__ = [ bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), bpy.props.BoolProperty(attr="reverse", name="Reverse", description="Cycle backwards", default= False) diff --git a/release/scripts/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py index 055cbb02e3f..78c675e618f 100644 --- a/release/scripts/ui/buttons_data_mesh.py +++ b/release/scripts/ui/buttons_data_mesh.py @@ -60,6 +60,9 @@ class DATA_PT_settings(DataButtonsPanel): col = split.column() col.itemR(mesh, "texture_mesh") + + col = split.column() + col.itemR(mesh, "use_mirror_x") class DATA_PT_vertex_groups(DataButtonsPanel): __label__ = "Vertex Groups" diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index ed8d366ab8b..50411c9d998 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -66,7 +66,7 @@ struct Object; #define B_AUTOFGON 0x20 #define B_KNIFE 0x80 #define B_PERCENTSUBD 0x40 -#define B_MESH_X_MIRROR 0x100 +//#define B_MESH_X_MIRROR 0x100 // deprecated, use mesh #define B_JOINTRIA_UV 0x200 #define B_JOINTRIA_VCOL 0X400 #define B_JOINTRIA_SHARP 0X800 diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index c4f4cd48d53..288af7f7874 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -4291,7 +4291,7 @@ static int smooth_vertex(bContext *C, wmOperator *op) if(eve->f & SELECT) { if(eve->f1) { - if (ts->editbutflag & B_MESH_X_MIRROR) { + if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve->co); } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 11789651d01..47f76aab4ca 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -974,7 +974,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) // Need stuff to take it from edit mesh or whatnot here else { - if (t->obedit && t->obedit->type == OB_MESH && ts->editbutflag & B_MESH_X_MIRROR) + if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X)) { t->flag |= T_MIRROR; } diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index f7f1d3b53bd..0f4dbaa8218 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -82,7 +82,7 @@ typedef struct Mesh { * the face does not need to be selected, -1 is inactive */ int act_face; - int texflag; + short texflag, editflag; /* texture space, copied as one block in editobject.c */ float loc[3]; @@ -116,6 +116,11 @@ typedef struct TFace { /* texflag */ #define AUTOSPACE 1 +/* me->editflag */ +#define ME_EDIT_MIRROR_X (1 << 0) +#define ME_EDIT_MIRROR_Y (1 << 1) // unused so far +#define ME_EDIT_MIRROR_Z (1 << 2) // unused so far + /* me->flag */ #define ME_ISDONE 1 #define ME_NOPUNOFLIP 2 diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 046f1ea1030..039109f75a1 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1600,6 +1600,21 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Face Area", "Displays the area of selected faces"); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + /* editflag */ + prop= RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_X); + RNA_def_property_ui_text(prop, "X Mirror", "X Axis mirror editing"); + + /* + prop= RNA_def_property(srna, "use_mirror_y", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_Y); + RNA_def_property_ui_text(prop, "Y Mirror", "Y Axis mirror editing"); + + prop= RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_Z); + RNA_def_property_ui_text(prop, "Z Mirror", "Z Axis mirror editing"); + */ + rna_def_texmat_common(srna, "rna_Mesh_texspace_editable"); RNA_api_mesh(srna); -- cgit v1.2.3 From 73076a623b4a63c530a9bf34c2b416cd401b011d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 14:44:05 +0000 Subject: Bugfixes for python RNA/ * Adding properties to python defined subclasses could add them to the base type instead. * FloatProperty did not work correct with negative min/max. --- source/blender/python/intern/bpy_rna.c | 52 ++++++++++++++++------------------ 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index ee202d7fcff..fb83ae3f205 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2315,6 +2315,19 @@ PyTypeObject pyrna_prop_Type = { NULL }; +static struct PyMethodDef pyrna_struct_subtype_methods[] = { + {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""}, + {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""}, + +// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""}, + {NULL, NULL, 0, NULL} +}; + static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) { PointerRNA ptr; @@ -2340,6 +2353,17 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item); Py_DECREF(item); /* done with rna instance */ + + /* attach functions into the class + * so you can do... bpy.types.Scene.SomeFunction() + */ + { + PyMethodDef *ml; + + for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){ + PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass)); + } + } } /* @@ -2362,20 +2386,6 @@ PyObject *BPy_GetStructRNA(PyObject *self) } */ -static struct PyMethodDef pyrna_struct_subtype_methods[] = { - {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""}, - {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""}, - -// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""}, - {NULL, NULL, 0, NULL} -}; - - PyObject* pyrna_srna_Subtype(StructRNA *srna) { PyObject *newclass = NULL; @@ -2425,18 +2435,6 @@ PyObject* pyrna_srna_Subtype(StructRNA *srna) pyrna_subtype_set_rna(newclass, srna); Py_DECREF(newclass); /* let srna own */ - - - /* attach functions into the class - * so you can do... bpy.types.Scene.SomeFunction() - */ - { - PyMethodDef *ml; - for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){ - PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass)); - } - } - } else { /* this should not happen */ @@ -2818,7 +2816,7 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL}; char *id, *name="", *description=""; - float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f; + float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, def=0.0f; PropertyRNA *prop; StructRNA *srna; -- cgit v1.2.3 From 0f6190a19b8896d522f1512c0c2364e072354d5e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 14:44:21 +0000 Subject: fix for continuous grab where you couldnt properly click the button for incremental changes or editing --- source/blender/editors/interface/interface_handlers.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 195129eac8f..3690b3c3f43 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2138,15 +2138,15 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { - int mx, my, click= 0; + int mx, my; /* mouse location scaled to fit the UI */ + int screen_mx, screen_my; /* mouse location kept at screen pixel coords */ + int click= 0; int retval= WM_UI_HANDLER_CONTINUE; - mx= event->x; - my= event->y; + mx= screen_mx= event->x; + my= screen_my= event->y; - if(!ui_is_a_warp_but(but)) { - ui_window_to_block(data->region, block, &mx, &my); - } + ui_window_to_block(data->region, block, &mx, &my); if(data->state == BUTTON_STATE_HIGHLIGHT) { /* XXX hardcoded keymap check.... */ @@ -2164,8 +2164,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton retval= WM_UI_HANDLER_BREAK; } else if(event->type == LEFTMOUSE) { - data->dragstartx= mx; - data->draglastx= mx; + data->dragstartx= data->draglastx= ui_is_a_warp_but(but) ? screen_mx:mx; button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval= WM_UI_HANDLER_BREAK; } @@ -2204,7 +2203,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton snap= (event->ctrl)? (event->shift)? 2: 1: 0; - if(ui_numedit_but_NUM(but, data, fac, snap, mx)) + if(ui_numedit_but_NUM(but, data, fac, snap, (ui_is_a_warp_but(but) ? screen_mx:mx))) ui_numedit_apply(C, block, but, data); } retval= WM_UI_HANDLER_BREAK; -- cgit v1.2.3 From c27a94849cc9c880b78d4306a239ab8bcdc89d0d Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 14 Oct 2009 14:45:58 +0000 Subject: * Fixes for Render Tab separation. * All Edges is now in the object mode "Display" Tab, as the option doesn't affect Edit Mode. Missing Redraw here... --- release/scripts/io/engine_render_pov.py | 18 +++++++++--------- release/scripts/io/netrender/ui.py | 12 ++++++------ release/scripts/ui/buttons_render.py | 12 +----------- release/scripts/ui/buttons_scene.py | 7 ++----- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/release/scripts/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py index f0247ce532a..f69c8a267e0 100644 --- a/release/scripts/io/engine_render_pov.py +++ b/release/scripts/io/engine_render_pov.py @@ -826,12 +826,12 @@ class PovrayRender(bpy.types.RenderEngine): bpy.types.register(PovrayRender) # Use some of the existing buttons. -import buttons_scene -buttons_scene.SCENE_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') -del buttons_scene +import buttons_render +buttons_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') +del buttons_render # Use only a subset of the world panels import buttons_world @@ -852,14 +852,14 @@ del buttons_material class RenderButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' - __context__ = "scene" + __context__ = "render" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here def poll(self, context): rd = context.scene.render_data return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) -class SCENE_PT_povray_radiosity(RenderButtonsPanel): +class RENDER_PT_povray_radiosity(RenderButtonsPanel): __label__ = "Radiosity" COMPAT_ENGINES = set(['POVRAY_RENDER']) @@ -909,4 +909,4 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel): col = split.column() col.itemR(scene, "pov_radio_always_sample") -bpy.types.register(SCENE_PT_povray_radiosity) +bpy.types.register(RENDER_PT_povray_radiosity) diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py index fba834ed9e0..638f46318af 100644 --- a/release/scripts/io/netrender/ui.py +++ b/release/scripts/io/netrender/ui.py @@ -20,7 +20,7 @@ ERROR = 3 class RenderButtonsPanel(bpy.types.Panel): __space_type__ = "PROPERTIES" __region_type__ = "WINDOW" - __context__ = "scene" + __context__ = "render" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here def poll(self, context): @@ -29,7 +29,7 @@ class RenderButtonsPanel(bpy.types.Panel): # Setting panel, use in the scene for now. @rnaType -class SCENE_PT_network_settings(RenderButtonsPanel): +class RENDER_PT_network_settings(RenderButtonsPanel): __label__ = "Network Settings" COMPAT_ENGINES = set(['NET_RENDER']) @@ -60,7 +60,7 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="") @rnaType -class SCENE_PT_network_job(RenderButtonsPanel): +class RENDER_PT_network_job(RenderButtonsPanel): __label__ = "Job Settings" COMPAT_ENGINES = set(['NET_RENDER']) @@ -88,7 +88,7 @@ class SCENE_PT_network_job(RenderButtonsPanel): col.itemR(scene.network_render, "chunks") @rnaType -class SCENE_PT_network_slaves(RenderButtonsPanel): +class RENDER_PT_network_slaves(RenderButtonsPanel): __label__ = "Slaves Status" COMPAT_ENGINES = set(['NET_RENDER']) @@ -126,7 +126,7 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): layout.itemL(text="Stats: " + slave.stats) @rnaType -class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): +class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel): __label__ = "Slaves Blacklist" COMPAT_ENGINES = set(['NET_RENDER']) @@ -163,7 +163,7 @@ class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): layout.itemL(text="Stats: " + time.ctime(slave.stats)) @rnaType -class SCENE_PT_network_jobs(RenderButtonsPanel): +class RENDER_PT_network_jobs(RenderButtonsPanel): __label__ = "Jobs" COMPAT_ENGINES = set(['NET_RENDER']) diff --git a/release/scripts/ui/buttons_render.py b/release/scripts/ui/buttons_render.py index a8f1b730ff7..379326510bf 100644 --- a/release/scripts/ui/buttons_render.py +++ b/release/scripts/ui/buttons_render.py @@ -1,14 +1,6 @@ import bpy -class SceneButtonsPanel(bpy.types.Panel): - __space_type__ = 'PROPERTIES' - __region_type__ = 'WINDOW' - __context__ = "render" - - def poll(self, context): - return (context.scene != None) - class RenderButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -17,7 +9,7 @@ class RenderButtonsPanel(bpy.types.Panel): def poll(self, context): rd = context.scene.render_data - return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) + return (context.scene and rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) class RENDER_PT_render(RenderButtonsPanel): __label__ = "Render" @@ -446,7 +438,6 @@ class RENDER_PT_stamp(RenderButtonsPanel): sub.active = rd.stamp_note sub.itemR(rd, "stamp_note_text", text="") - bpy.types.register(RENDER_PT_render) bpy.types.register(RENDER_PT_layers) bpy.types.register(RENDER_PT_dimensions) @@ -457,4 +448,3 @@ bpy.types.register(RENDER_PT_encoding) bpy.types.register(RENDER_PT_performance) bpy.types.register(RENDER_PT_post_processing) bpy.types.register(RENDER_PT_stamp) - diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 6c68e793852..964e06d017d 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -7,7 +7,7 @@ class SceneButtonsPanel(bpy.types.Panel): __context__ = "scene" def poll(self, context): - return (context.scene != None) + return context.scene class SCENE_PT_scene(SceneButtonsPanel): __label__ = "Scene" @@ -17,9 +17,9 @@ class SCENE_PT_scene(SceneButtonsPanel): layout = self.layout scene = context.scene + layout.itemR(scene, "camera") layout.itemR(scene, "set", text="Background") - class SCENE_PT_unit(SceneButtonsPanel): __label__ = "Units" @@ -119,9 +119,6 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): col.itemR(ksp, "grouping") if ksp.grouping == 'NAMED': col.itemR(ksp, "group") - - - class SCENE_PT_physics(SceneButtonsPanel): __label__ = "Gravity" -- cgit v1.2.3 From 866e41520cbf0046dcfcb22d1d57bb980e7736ca Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 14:55:01 +0000 Subject: Bugfix: mesh menu was using two columns due to enum with label. --- release/scripts/ui/space_view3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index cb3f91ad687..ce4414dc2f6 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -737,7 +737,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu): layout.itemS() layout.itemR(settings, "automerge_editing") - layout.itemR(settings, "proportional_editing") + layout.item_menu_enumR(settings, "proportional_editing") layout.item_menu_enumR(settings, "proportional_editing_falloff") layout.itemS() -- cgit v1.2.3 From bc0916c630a17a691768b1b55f7925b8f004ad12 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 15:06:42 +0000 Subject: - added name field for renderlayer - skin/loft now adds faces with active material - defailt for scene panels isnt closed anymore since there is a lot of room there now. --- release/scripts/io/mesh_skin.py | 10 ++++++---- release/scripts/ui/buttons_render.py | 3 +++ release/scripts/ui/buttons_scene.py | 3 --- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/release/scripts/io/mesh_skin.py b/release/scripts/io/mesh_skin.py index 79b78c15274..f6fafc41111 100644 --- a/release/scripts/io/mesh_skin.py +++ b/release/scripts/io/mesh_skin.py @@ -221,7 +221,7 @@ def face_edge_keys(f): return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0]) -def mesh_faces_extend(me, faces): +def mesh_faces_extend(me, faces, mat_idx = 0): orig_facetot = len(me.faces) new_facetot = len(faces) me.add_geometry(0, 0, new_facetot) @@ -233,8 +233,10 @@ def mesh_faces_extend(me, faces): f = [v.index for v in faces[i]] if len(f)==4 and f[3]==0: f = f[1], f[2], f[3], f[0] - - me_faces[orig_facetot+i].verts_raw = f + + mf = me_faces[orig_facetot+i] + mf.verts_raw = f + mf.material_index = mat_idx i+=1 # end utils @@ -605,7 +607,7 @@ def main(context): except: pass if 1: # 2.5 - mesh_faces_extend(me, faces) + mesh_faces_extend(me, faces, ob.active_material_index) me.update(calc_edges=True) else: me.faces.extend(faces, smooth = True) diff --git a/release/scripts/ui/buttons_render.py b/release/scripts/ui/buttons_render.py index 379326510bf..699fd8d7391 100644 --- a/release/scripts/ui/buttons_render.py +++ b/release/scripts/ui/buttons_render.py @@ -45,6 +45,9 @@ class RENDER_PT_layers(RenderButtonsPanel): col.itemO("scene.render_layer_remove", icon='ICON_ZOOMOUT', text="") rl = rd.layers[rd.active_layer_index] + + if rl: + layout.itemR(rl, "name") split = layout.split() diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 964e06d017d..b3b3d8b6672 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -23,7 +23,6 @@ class SCENE_PT_scene(SceneButtonsPanel): class SCENE_PT_unit(SceneButtonsPanel): __label__ = "Units" - __default_closed__ = True COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw(self, context): @@ -41,7 +40,6 @@ class SCENE_PT_unit(SceneButtonsPanel): class SCENE_PT_keying_sets(SceneButtonsPanel): __label__ = "Keying Sets" - __default_closed__ = True def draw(self, context): layout = self.layout @@ -75,7 +73,6 @@ class SCENE_PT_keying_sets(SceneButtonsPanel): class SCENE_PT_keying_set_paths(SceneButtonsPanel): __label__ = "Active Keying Set" - __default_closed__ = True def poll(self, context): return (context.scene != None) and (context.scene.active_keying_set != None) -- cgit v1.2.3 From 922461830fa801179ca213ef4c208d1d14274c81 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 15:14:06 +0000 Subject: Scene/Render Buttons: * Keep Render as default tab instead of Scene. * Remove unnecessary Keying Sets label. * Fix missing scene name in render context path. --- release/scripts/ui/buttons_scene.py | 3 --- source/blender/editors/space_buttons/buttons_context.c | 2 +- source/blender/makesdna/DNA_space_types.h | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index b3b3d8b6672..deb20f2b432 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -46,9 +46,6 @@ class SCENE_PT_keying_sets(SceneButtonsPanel): scene = context.scene - row = layout.row() - row.itemL(text="Keying Sets:") - row = layout.row() col = row.column() diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index c6cde9f1c6b..8072853bcb8 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -777,7 +777,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout) name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf)); if(name) { - if(sbuts->mainb != BCONTEXT_SCENE && ptr->type == &RNA_Scene) + if(!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE) && ptr->type == &RNA_Scene) uiItemL(row, "", icon); /* save some space */ else uiItemL(row, name, icon); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 0c2b89b7b29..d7793b88bea 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -569,8 +569,8 @@ typedef struct SpaceUserPref { /* buts->mainb new */ -#define BCONTEXT_SCENE 0 -#define BCONTEXT_RENDER 1 +#define BCONTEXT_RENDER 0 +#define BCONTEXT_SCENE 1 #define BCONTEXT_WORLD 2 #define BCONTEXT_OBJECT 3 #define BCONTEXT_DATA 4 -- cgit v1.2.3 From e2ae8843d746b5d4cab0ecdc0ab8641114661f9e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 15:28:57 +0000 Subject: texture mapping buttons were not visible, (own fault) --- release/scripts/ui/buttons_texture.py | 46 ++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index 0313a986749..270ecaf19aa 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -177,28 +177,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel): split.itemL(text="Object:") split.itemR(tex, "object", text="") - if type(idblock) == bpy.types.Material: - split = layout.split(percentage=0.3) - split.itemL(text="Projection:") - split.itemR(tex, "mapping", text="") - - split = layout.split() - - col = split.column() - if tex.texture_coordinates in ('ORCO', 'UV'): - col.itemR(tex, "from_dupli") - elif tex.texture_coordinates == 'OBJECT': - col.itemR(tex, "from_original") - else: - col.itemL() - - col = split.column() - row = col.row() - row.itemR(tex, "x_mapping", text="") - row.itemR(tex, "y_mapping", text="") - row.itemR(tex, "z_mapping", text="") - - elif type(idblock) == bpy.types.Brush: + if type(idblock) == bpy.types.Brush: layout.itemR(tex, "map_mode", expand=True) row = layout.row() @@ -209,9 +188,32 @@ class TEXTURE_PT_mapping(TextureSlotPanel): row.active = tex.map_mode in ('TILED', '3D') row.column().itemR(tex, "size") else: + if type(idblock) == bpy.types.Material: + split = layout.split(percentage=0.3) + split.itemL(text="Projection:") + split.itemR(tex, "mapping", text="") + + split = layout.split() + + col = split.column() + if tex.texture_coordinates in ('ORCO', 'UV'): + col.itemR(tex, "from_dupli") + elif tex.texture_coordinates == 'OBJECT': + col.itemR(tex, "from_original") + else: + col.itemL() + + col = split.column() + row = col.row() + row.itemR(tex, "x_mapping", text="") + row.itemR(tex, "y_mapping", text="") + row.itemR(tex, "z_mapping", text="") + + # any non brush row = layout.row() row.column().itemR(tex, "offset") row.column().itemR(tex, "size") + class TEXTURE_PT_influence(TextureSlotPanel): __label__ = "Influence" -- cgit v1.2.3 From 59e3a08c8c9af8a7b8ca2a6a9c444369be80db36 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 14 Oct 2009 15:37:10 +0000 Subject: Fixed shape key mute icon. --- release/scripts/ui/buttons_data_mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py index 78c675e618f..108b4ef4371 100644 --- a/release/scripts/ui/buttons_data_mesh.py +++ b/release/scripts/ui/buttons_data_mesh.py @@ -131,7 +131,7 @@ class DATA_PT_shape_keys(DataButtonsPanel): subcol = col.column(align=True) subcol.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="") - subcol.itemR(kb, "mute", icon='ICON_MUTE_IPO_ON', text="") + subcol.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="") if key.relative: row = layout.row() -- cgit v1.2.3 From 58cabaa1e32ab52ff35cc996497e6f9a415b3078 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 16:23:23 +0000 Subject: weight-paint colorband wasnt working --- source/blender/makesrna/intern/rna_userdef.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index c1fb3e88084..aeb82e5640b 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -42,6 +42,11 @@ #ifdef RNA_RUNTIME +#include "BKE_main.h" +#include "BKE_DerivedMesh.h" +#include "BKE_depsgraph.h" +#include "DNA_object_types.h" + static void rna_userdef_update(bContext *C, PointerRNA *ptr) { WM_event_add_notifier(C, NC_WINDOW, NULL); @@ -124,6 +129,23 @@ static void rna_UserDef_audio_update(bContext *C, PointerRNA *ptr) sound_init(C); } +static void rna_UserDef_weight_color_update(bContext *C, PointerRNA *ptr) +{ + Main *bmain= CTX_data_main(C); + Object *ob; + + vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight):NULL); + + for(ob= bmain->object.first; ob; ob= ob->id.next) { + if(ob->mode & OB_MODE_WEIGHT_PAINT) + DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + } + + rna_userdef_update(C, ptr); +} + + + #else static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna) @@ -2134,12 +2156,14 @@ static void rna_def_userdef_system(BlenderRNA *brna) prop= RNA_def_property(srna, "use_weight_color_range", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_CUSTOM_RANGE); RNA_def_property_ui_text(prop, "Use Weight Color Range", "Enable color range used for weight visualization in weight painting mode."); + RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update"); prop= RNA_def_property(srna, "weight_color_range", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "coba_weight"); RNA_def_property_struct_type(prop, "ColorRamp"); RNA_def_property_ui_text(prop, "Weight Color Range", "Color range used for weight visualization in weight painting mode."); + RNA_def_property_update(prop, 0, "rna_UserDef_weight_color_update"); prop= RNA_def_property(srna, "enable_all_codecs", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ALLWINCODECS); -- cgit v1.2.3 From f579fe5681873749077b39a67f79ba6f7544d784 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 18:48:19 +0000 Subject: fixes for warnings and crashes during doc generation --- source/blender/blenkernel/intern/context.c | 2 +- source/blender/makesrna/intern/rna_fcurve.c | 2 ++ source/blender/makesrna/intern/rna_rna.c | 5 ++--- source/blender/makesrna/intern/rna_userdef.c | 2 ++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index bbfe077c15e..d5cc31d918a 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -441,7 +441,7 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member) { bContextDataResult result; - if(ctx_data_get((bContext*)C, member, &result)) + if(C && ctx_data_get((bContext*)C, member, &result)) return result.ptr.data; return NULL; diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 271964bb483..e69e2cd0e2c 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -53,6 +53,8 @@ EnumPropertyItem fmodifier_type_items[] = { #ifdef RNA_RUNTIME +#include "WM_api.h" + static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) { FModifier *fcm= (FModifier *)ptr->data; diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 8dd751cd26a..fbb24f9ada9 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -383,14 +383,13 @@ static void rna_Property_description_get(PointerRNA *ptr, char *value) { PropertyRNA *prop= (PropertyRNA*)ptr->data; rna_idproperty_check(&prop, ptr); - strcpy(value, prop->description); + strcpy(value, prop->description ? prop->description:""); } - static int rna_Property_description_length(PointerRNA *ptr) { PropertyRNA *prop= (PropertyRNA*)ptr->data; rna_idproperty_check(&prop, ptr); - return strlen(prop->description); + return prop->description ? strlen(prop->description) : 0; } static int rna_Property_type_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index aeb82e5640b..722b686218b 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -64,10 +64,12 @@ static void rna_userdef_lmb_select_set(PointerRNA *ptr,int value) userdef->flag &= ~USER_LMOUSESELECT; } +#if 0 static void rna_userdef_rmb_select_set(PointerRNA *ptr,int value) { rna_userdef_lmb_select_set(ptr, !value); } +#endif static void rna_userdef_emulate_set(PointerRNA *ptr,int value) { -- cgit v1.2.3 From 96d2dc7d090975687e5b99495fcc1e5725e75120 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 14 Oct 2009 18:51:00 +0000 Subject: iTaSC: Selection of constrained axis for CopyPose constraint This commit implements more of the CopyPose capabilities in Blender. It is now possible to select which axis will be constrained in position and orientation to obtain interesting effects. Another option selects if the axis are relative to the end effector or to the target. Unlocking a position axis means that the coordinate along this axis is not constrained and can take any value. Unlocking the Y axis of the End Effector produces an 'aiming' effect: the end effector is oriented towards the target but without stretching. Unlocking a rotation axis means that the end effector can freely rotation along that axis. Unlocking the Y axis produces a 'tangent' effect: the end effector aligns with the Y axis of the target but can rotate along that axis. A 'floor' effect is possible if the position Z axis of the target is unlocked. More effects are possible an can be combined. --- release/scripts/ui/buttons_object_constraint.py | 98 ++++++++++++++++++------- source/blender/ikplugin/intern/itasc_plugin.cpp | 25 +++++-- source/blender/makesdna/DNA_constraint_types.h | 10 +++ source/blender/makesrna/intern/rna_constraint.c | 47 ++++++++++++ 4 files changed, 148 insertions(+), 32 deletions(-) diff --git a/release/scripts/ui/buttons_object_constraint.py b/release/scripts/ui/buttons_object_constraint.py index 6be166e8af0..63fe27f2e4b 100644 --- a/release/scripts/ui/buttons_object_constraint.py +++ b/release/scripts/ui/buttons_object_constraint.py @@ -50,6 +50,7 @@ class ConstraintButtonsPanel(bpy.types.Panel): layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group") def ik_template(self, layout, con): + # only used for iTaSC layout.itemR(con, "pole_target") if con.pole_target and con.pole_target.type == 'ARMATURE': @@ -60,14 +61,14 @@ class ConstraintButtonsPanel(bpy.types.Panel): row.itemL() row.itemR(con, "pole_angle") - split = layout.split() + split = layout.split(percentage=0.33) col = split.column() col.itemR(con, "tail") col.itemR(con, "stretch") col = split.column() - col.itemR(con, "iterations") col.itemR(con, "chain_length") + col.itemR(con, "targetless") def CHILD_OF(self, context, layout, con): self.target_template(layout, con) @@ -115,24 +116,74 @@ class ConstraintButtonsPanel(bpy.types.Panel): layout.itemR(con, "ik_type") getattr(self, "IK_"+con.ik_type)(context, layout, con) else: - self.IK_COPY_POSE(context, layout, con) + # Legacy IK constraint + self.target_template(layout, con) + layout.itemR(con, "pole_target") + + if con.pole_target and con.pole_target.type == 'ARMATURE': + layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone") + + if con.pole_target: + row = layout.row() + row.itemL() + row.itemR(con, "pole_angle") + + split = layout.split() + col = split.column() + col.itemR(con, "tail") + col.itemR(con, "stretch") + + col = split.column() + col.itemR(con, "iterations") + col.itemR(con, "chain_length") + + split = layout.split() + col = split.column() + col.itemL() + col.itemR(con, "targetless") + col.itemR(con, "rotation") + + col = split.column() + col.itemL(text="Weight:") + col.itemR(con, "weight", text="Position", slider=True) + sub = col.column() + sub.active = con.rotation + sub.itemR(con, "orient_weight", text="Rotation", slider=True) def IK_COPY_POSE(self, context, layout, con): self.target_template(layout, con) self.ik_template(layout, con) - - split = layout.split() - col = split.column() - col.itemL() - col.itemR(con, "targetless") - col.itemR(con, "rotation") - - col = split.column() - col.itemL(text="Weight:") - col.itemR(con, "weight", text="Position", slider=True) - sub = col.column() - sub.active = con.rotation - sub.itemR(con, "orient_weight", text="Rotation", slider=True) + + row = layout.row() + row.itemL(text="Axis Ref:") + row.itemR(con, "axis_reference", expand=True) + split = layout.split(percentage=0.33) + split.row().itemR(con, "position") + row = split.row() + row.itemR(con, "weight", text="Weight", slider=True) + row.active = con.position + split = layout.split(percentage=0.33) + row = split.row() + row.itemL(text="Lock:") + row = split.row() + row.itemR(con, "pos_lock_x", text="X") + row.itemR(con, "pos_lock_y", text="Y") + row.itemR(con, "pos_lock_z", text="Z") + split.active = con.position + + split = layout.split(percentage=0.33) + split.row().itemR(con, "rotation") + row = split.row() + row.itemR(con, "orient_weight", text="Weight", slider=True) + row.active = con.rotation + split = layout.split(percentage=0.33) + row = split.row() + row.itemL(text="Lock:") + row = split.row() + row.itemR(con, "rot_lock_x", text="X") + row.itemR(con, "rot_lock_y", text="Y") + row.itemR(con, "rot_lock_z", text="Z") + split.active = con.rotation def IK_DISTANCE(self, context, layout, con): self.target_template(layout, con) @@ -610,20 +661,13 @@ class BONE_PT_inverse_kinematics(ConstraintButtonsPanel): split.itemL() if ob.pose.ik_solver == "ITASC": - layout.itemL(text="Joint constraint:") - split = layout.split(percentage=0.3) - row = split.row() - row.itemR(pchan, "ik_rot_control", text="Rotation") - row = split.row() + row = layout.row() + row.itemR(pchan, "ik_rot_control", text="Control Rotation") row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True) - row.active = pchan.ik_rot_control # not supported yet - #split = layout.split(percentage=0.3) - #row = split.row() - #row.itemR(pchan, "ik_lin_control", text="Size") - #row = split.row() + #row = layout.row() + #row.itemR(pchan, "ik_lin_control", text="Joint Size") #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True) - #row.active = pchan.ik_lin_control class BONE_PT_iksolver_itasc(ConstraintButtonsPanel): __label__ = "iTaSC parameters" diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 7f4c1967207..b6fceabdb46 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -1417,10 +1417,22 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) switch (condata->type) { case CONSTRAINT_IK_COPYPOSE: controltype = 0; - if ((condata->flag & CONSTRAINT_IK_ROT) && (condata->orientweight != 0.0)) - controltype |= iTaSC::CopyPose::CTL_ROTATION; - if ((condata->weight != 0.0)) - controltype |= iTaSC::CopyPose::CTL_POSITION; + if (condata->flag & CONSTRAINT_IK_ROT) { + if (!(condata->flag & CONSTRAINT_IK_NO_ROT_X)) + controltype |= iTaSC::CopyPose::CTL_ROTATIONX; + if (!(condata->flag & CONSTRAINT_IK_NO_ROT_Y)) + controltype |= iTaSC::CopyPose::CTL_ROTATIONY; + if (!(condata->flag & CONSTRAINT_IK_NO_ROT_Z)) + controltype |= iTaSC::CopyPose::CTL_ROTATIONZ; + } + if (condata->flag & CONSTRAINT_IK_POS) { + if (!(condata->flag & CONSTRAINT_IK_NO_POS_X)) + controltype |= iTaSC::CopyPose::CTL_POSITIONX; + if (!(condata->flag & CONSTRAINT_IK_NO_POS_Y)) + controltype |= iTaSC::CopyPose::CTL_POSITIONY; + if (!(condata->flag & CONSTRAINT_IK_NO_POS_Z)) + controltype |= iTaSC::CopyPose::CTL_POSITIONZ; + } if (controltype) { iktarget->constraint = new iTaSC::CopyPose(controltype, controltype, bonelen); // set the gain @@ -1432,7 +1444,10 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan) iktarget->errorCallback = copypose_error; iktarget->controlType = controltype; // add the constraint - ret = scene->addConstraintSet(iktarget->constraintName, iktarget->constraint, armname, iktarget->targetName, ikscene->channels[iktarget->channel].tail); + if (condata->flag & CONSTRAINT_IK_TARGETAXIS) + ret = scene->addConstraintSet(iktarget->constraintName, iktarget->constraint, iktarget->targetName, armname, "", ikscene->channels[iktarget->channel].tail); + else + ret = scene->addConstraintSet(iktarget->constraintName, iktarget->constraint, armname, iktarget->targetName, ikscene->channels[iktarget->channel].tail); } break; case CONSTRAINT_IK_DISTANCE: diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index fccec7a556f..7232042c876 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -502,6 +502,16 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG { #define CONSTRAINT_IK_POS 32 #define CONSTRAINT_IK_SETANGLE 64 #define CONSTRAINT_IK_GETANGLE 128 + /* limit axis */ +#define CONSTRAINT_IK_NO_POS_X 256 +#define CONSTRAINT_IK_NO_POS_Y 512 +#define CONSTRAINT_IK_NO_POS_Z 1024 +#define CONSTRAINT_IK_NO_ROT_X 2048 +#define CONSTRAINT_IK_NO_ROT_Y 4096 +#define CONSTRAINT_IK_NO_ROT_Z 8192 + /* axis relative to target */ +#define CONSTRAINT_IK_TARGETAXIS 16384 + /* MinMax (floor) flags */ #define MINMAX_STICKY 0x01 diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 325318ba34a..395633f5240 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -87,6 +87,12 @@ EnumPropertyItem constraint_ik_type_items[] ={ {0, NULL, 0, NULL, NULL}, }; +EnumPropertyItem constraint_ik_axisref_items[] ={ + {0, "BONE", 0, "Bone", ""}, + {CONSTRAINT_IK_TARGETAXIS, "TARGET", 0, "Target", ""}, + {0, NULL, 0, NULL, NULL}, +}; + #ifdef RNA_RUNTIME #include "BKE_action.h" @@ -497,11 +503,52 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Tail", "Include bone's tail as last element in chain."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + prop= RNA_def_property(srna, "axis_reference", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, constraint_ik_axisref_items); + RNA_def_property_ui_text(prop, "Axis Reference", "Constraint axis Lock options relative to Bone or Target reference"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + prop= RNA_def_property(srna, "position", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_POS); + RNA_def_property_ui_text(prop, "Position", "Chain follows position of target."); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + prop= RNA_def_property(srna, "pos_lock_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_IK_NO_POS_X); + RNA_def_property_ui_text(prop, "Lock X Pos", "Constraint position along X axis"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Constraint_dependency_update"); + + prop= RNA_def_property(srna, "pos_lock_y", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_IK_NO_POS_Y); + RNA_def_property_ui_text(prop, "Lock Y Pos", "Constraint position along Y axis"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Constraint_dependency_update"); + + prop= RNA_def_property(srna, "pos_lock_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_IK_NO_POS_Z); + RNA_def_property_ui_text(prop, "Lock Z Pos", "Constraint position along Z axis"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Constraint_dependency_update"); + prop= RNA_def_property(srna, "rotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_ROT); RNA_def_property_ui_text(prop, "Rotation", "Chain follows rotation of target."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + prop= RNA_def_property(srna, "rot_lock_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_IK_NO_ROT_X); + RNA_def_property_ui_text(prop, "Lock X Rot", "Constraint rotation along X axis"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Constraint_dependency_update"); + + prop= RNA_def_property(srna, "rot_lock_y", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_IK_NO_ROT_Y); + RNA_def_property_ui_text(prop, "Lock Y Rot", "Constraint rotation along Y axis"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Constraint_dependency_update"); + + prop= RNA_def_property(srna, "rot_lock_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_IK_NO_ROT_Z); + RNA_def_property_ui_text(prop, "Lock Z Rot", "Constraint rotation along Z axis"); + RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Constraint_dependency_update"); + prop= RNA_def_property(srna, "targetless", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_IK_AUTO); RNA_def_property_ui_text(prop, "Targetless", "Use targetless IK."); -- cgit v1.2.3 From 991e67ddc756cdbf6e85b9a0520792d1f48026e4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Oct 2009 19:19:43 +0000 Subject: RNA: * Enums with an _itemf callback now never get context NULL passed in, rather a fixed list of enum items are defined which should contain all items (if possible), from which the _itemf callback can then use a subset. --- source/blender/editors/armature/poselib.c | 13 +-- source/blender/editors/mesh/editmesh_mods.c | 114 +++++++++------------- source/blender/editors/mesh/editmesh_tools.c | 18 ++-- source/blender/editors/object/object_add.c | 14 +-- source/blender/editors/object/object_group.c | 9 +- source/blender/editors/object/object_modifier.c | 5 +- source/blender/editors/object/object_vgroup.c | 5 +- source/blender/makesrna/intern/rna_access.c | 2 +- source/blender/makesrna/intern/rna_constraint.c | 28 ------ source/blender/makesrna/intern/rna_define.c | 5 + source/blender/makesrna/intern/rna_image.c | 3 - source/blender/makesrna/intern/rna_material.c | 5 - source/blender/makesrna/intern/rna_object.c | 5 - source/blender/makesrna/intern/rna_object_force.c | 18 ---- source/blender/makesrna/intern/rna_particle.c | 58 ----------- source/blender/makesrna/intern/rna_rna.c | 2 +- source/blender/makesrna/intern/rna_sculpt_paint.c | 26 ++--- source/blender/makesrna/intern/rna_space.c | 109 ++++++++++----------- source/blender/makesrna/intern/rna_texture.c | 4 +- 19 files changed, 132 insertions(+), 311 deletions(-) diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index d6f93757505..f67c94eebc3 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -432,9 +432,6 @@ static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, int totitem= 0; int i= 0; - if (C == NULL) - return NULL; - memset(&item_tmp, 0, sizeof(item_tmp)); /* check that the action exists */ @@ -448,12 +445,10 @@ static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, } } - if (i > 0) { - *free= 1; - return item; - } - else - return NULL; + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; } static int poselib_remove_exec (bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 288af7f7874..74870778d02 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -658,7 +658,25 @@ static int unified_findnearest(ViewContext *vc, EditVert **eve, EditEdge **eed, /* selects new faces/edges/verts based on the existing selection */ -/* FACES GROUP */ +/* VERT GROUP */ + +#define SIMVERT_NORMAL 0 +#define SIMVERT_FACE 1 +#define SIMVERT_VGROUP 2 +#define SIMVERT_TOT 3 + +/* EDGE GROUP */ + +#define SIMEDGE_LENGTH 101 +#define SIMEDGE_DIR 102 +#define SIMEDGE_FACE 103 +#define SIMEDGE_FACE_ANGLE 104 +#define SIMEDGE_CREASE 105 +#define SIMEDGE_SEAM 106 +#define SIMEDGE_SHARP 107 +#define SIMEDGE_TOT 108 + +/* FACE GROUP */ #define SIMFACE_MATERIAL 201 #define SIMFACE_IMAGE 202 @@ -666,8 +684,19 @@ static int unified_findnearest(ViewContext *vc, EditVert **eve, EditEdge **eed, #define SIMFACE_PERIMETER 204 #define SIMFACE_NORMAL 205 #define SIMFACE_COPLANAR 206 +#define SIMFACE_TOT 207 -static EnumPropertyItem prop_simface_types[] = { +static EnumPropertyItem prop_similar_types[] = { + {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, + {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, + {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, + {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, + {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, + {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, + {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""}, + {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""}, + {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, + {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""}, {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""}, {SIMFACE_AREA, "AREA", 0, "Area", ""}, @@ -831,27 +860,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) /* ***************************************************** */ -/* EDGE GROUP */ - -#define SIMEDGE_LENGTH 101 -#define SIMEDGE_DIR 102 -#define SIMEDGE_FACE 103 -#define SIMEDGE_FACE_ANGLE 104 -#define SIMEDGE_CREASE 105 -#define SIMEDGE_SEAM 106 -#define SIMEDGE_SHARP 107 - -static EnumPropertyItem prop_simedge_types[] = { - {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, - {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, - {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, - {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""}, - {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""}, - {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, - {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, - {0, NULL, 0, NULL, NULL} -}; - static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mode) { EditEdge *eed, *base_eed=NULL; @@ -1073,25 +1081,6 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) /* ********************************* */ -/* -VERT GROUP - mode 1: same normal - mode 2: same number of face users - mode 3: same vertex groups -*/ - -#define SIMVERT_NORMAL 0 -#define SIMVERT_FACE 1 -#define SIMVERT_VGROUP 2 - -static EnumPropertyItem prop_simvertex_types[] = { - {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, - {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, - {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, - {0, NULL, 0, NULL, NULL} -}; - - static int similar_vert_select_exec(bContext *C, wmOperator *op) { ToolSettings *ts= CTX_data_tool_settings(C); @@ -1243,37 +1232,30 @@ static int select_similar_exec(bContext *C, wmOperator *op) static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *obedit; + Object *obedit= CTX_data_edit_object(C); EnumPropertyItem *item= NULL; - int totitem= 0; - - if(C) { - obedit= CTX_data_edit_object(C); + int a, totitem= 0; - if(obedit && obedit->type == OB_MESH) { - EditMesh *em= BKE_mesh_get_editmesh(obedit->data); - - if(em->selectmode & SCE_SELECT_VERTEX) - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - else if(em->selectmode & SCE_SELECT_EDGE) - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - else if(em->selectmode & SCE_SELECT_FACE) - RNA_enum_items_add(&item, &totitem, prop_simface_types); - RNA_enum_item_end(&item, &totitem); + if(obedit && obedit->type == OB_MESH) { + EditMesh *em= BKE_mesh_get_editmesh(obedit->data); - *free= 1; - - return item; + if(em->selectmode & SCE_SELECT_VERTEX) { + for(a=SIMVERT_NORMAL; a<=SIMVERT_TOT; a++) + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); + } + else if(em->selectmode & SCE_SELECT_EDGE) { + for(a=SIMEDGE_LENGTH; a<=SIMEDGE_TOT; a++) + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); + } + else if(em->selectmode & SCE_SELECT_FACE) { + for(a=SIMFACE_MATERIAL; a<=SIMFACE_TOT; a++) + RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); } } - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - RNA_enum_items_add(&item, &totitem, prop_simface_types); RNA_enum_item_end(&item, &totitem); *free= 1; - + return item; } @@ -1295,7 +1277,7 @@ void MESH_OT_select_similar(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, SIMVERT_NORMAL, "Type", ""); + prop= RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", ""); RNA_def_enum_funcs(prop, select_similar_type_itemf); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 80ea5c51e1f..d447040e8ea 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5856,14 +5856,10 @@ static EnumPropertyItem merge_type_items[]= { static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *obedit; + Object *obedit= CTX_data_edit_object(C); EnumPropertyItem *item= NULL; int totitem= 0; - - if(!C) /* needed for docs */ - return merge_type_items; - - obedit= CTX_data_edit_object(C); + if(obedit && obedit->type == OB_MESH) { EditMesh *em= BKE_mesh_get_editmesh(obedit->data); @@ -5882,14 +5878,12 @@ static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *fre RNA_enum_items_add_value(&item, &totitem, merge_type_items, 3); RNA_enum_items_add_value(&item, &totitem, merge_type_items, 4); RNA_enum_items_add_value(&item, &totitem, merge_type_items, 5); - RNA_enum_item_end(&item, &totitem); + } - *free= 1; + RNA_enum_item_end(&item, &totitem); + *free= 1; - return item; - } - - return NULL; + return item; } void MESH_OT_merge(wmOperatorType *ot) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 5f088f23939..25ecb41a523 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -608,9 +608,6 @@ static EnumPropertyItem *add_dupligroup_itemf(bContext *C, PointerRNA *ptr, int int i= 0; Group *group; - if(C==NULL) - return NULL; - memset(&item_tmp, 0, sizeof(item_tmp)); for(group= CTX_data_main(C)->group.first; group; group= group->id.next) { @@ -619,13 +616,10 @@ static EnumPropertyItem *add_dupligroup_itemf(bContext *C, PointerRNA *ptr, int RNA_enum_item_add(&item, &totitem, &item_tmp); } - if(i>0) { - *free= 1; - return item; - } - else { - return NULL; - } + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; } static int group_instance_add_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index c83f3022c7c..198838d6f05 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -275,18 +275,14 @@ static EnumPropertyItem group_items[]= { static EnumPropertyItem *group_itemf(bContext *C, PointerRNA *ptr, int *free) { + Main *bmain= CTX_data_main(C); + Group *group; EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; - Main *bmain; - Group *group; int a, totitem= 0; - if(!C) /* needed for docs */ - return group_items; - RNA_enum_items_add_value(&item, &totitem, group_items, -1); - bmain= CTX_data_main(C); if(bmain->group.first) RNA_enum_item_add_separator(&item, &totitem); @@ -298,7 +294,6 @@ static EnumPropertyItem *group_itemf(bContext *C, PointerRNA *ptr, int *free) } RNA_enum_item_end(&item, &totitem); - *free= 1; return item; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 252fdb5522a..f58e8cfeb9d 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -440,12 +440,12 @@ static int modifier_add_exec(bContext *C, wmOperator *op) static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *free) { + Object *ob= CTX_data_active_object(C); EnumPropertyItem *item= NULL, *md_item; ModifierTypeInfo *mti; - Object *ob; int totitem= 0, a; - if(!C || !(ob= CTX_data_active_object(C))) /* needed for docs */ + if(!ob) return modifier_type_items; for(a=0; modifier_type_items[a].identifier; a++) { @@ -466,7 +466,6 @@ static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *ptr, int *f } RNA_enum_item_end(&item, &totitem); - *free= 1; return item; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 902a32bb7f3..dd3e5969a75 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1233,13 +1233,13 @@ static int set_active_group_exec(bContext *C, wmOperator *op) static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free) { - Object *ob; + Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; bDeformGroup *def; int a, totitem= 0; - if(!C || !(ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data)) /* needed for docs */ + if(!ob) return vgroup_items; for(a=0, def=ob->defbase.first; def; def=def->next, a++) { @@ -1250,7 +1250,6 @@ static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free) } RNA_enum_item_end(&item, &totitem); - *free= 1; return item; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index bec2025907a..6cf2fd0c60f 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -727,7 +727,7 @@ void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, En *free= 0; - if(eprop->itemf) { + if(eprop->itemf && C) { int tot= 0; *item= eprop->itemf(C, ptr, free); diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 395633f5240..53c8db6ff0f 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -232,20 +232,6 @@ static EnumPropertyItem *rna_Constraint_owner_space_itemf(bContext *C, PointerRN Object *ob= (Object*)ptr->id.data; bConstraint *con= (bConstraint*)ptr->data; - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, space_object_items); - RNA_enum_items_add(&item, &totitem, space_pchan_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - if(BLI_findindex(&ob->constraints, con) == -1) return space_pchan_items; else /* object */ @@ -259,20 +245,6 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *C, PointerR ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, space_object_items); - RNA_enum_items_add(&item, &totitem, space_pchan_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - if(cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index f3fb1244565..48de7ace222 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2135,6 +2135,11 @@ PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, co { ContainerRNA *cont= cont_; PropertyRNA *prop; + + if(!items) { + printf("RNA_def_enum: items not allowed to be NULL.\n"); + return NULL; + } prop= RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE); if(items) RNA_def_property_enum_items(prop, items); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 521756b8539..44c55e821a9 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -128,9 +128,6 @@ static EnumPropertyItem *rna_Image_source_itemf(bContext *C, PointerRNA *ptr, in EnumPropertyItem *item= NULL; int totitem= 0; - if(C==NULL) /* needed for doc generation */ - return image_source_items; - if(ima->source == IMA_SRC_VIEWER) { RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_VIEWER); } diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index e03e221f822..74cb8675ad5 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -260,10 +260,6 @@ static EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *C, Poi EnumPropertyItem *item= NULL; int totitem= 0; - if(C==NULL) { - return prop_texture_coordinates_items; - } - RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_GLOB); RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_OBJECT); RNA_enum_items_add_value(&item, &totitem, prop_texture_coordinates_items, TEXCO_ORCO); @@ -283,7 +279,6 @@ static EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *C, Poi } RNA_enum_item_end(&item, &totitem); - *free= 1; return item; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 092f18ef0e2..09e0ac3feac 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -229,10 +229,6 @@ static EnumPropertyItem *rna_Object_parent_type_itemf(bContext *C, PointerRNA *p EnumPropertyItem *item= NULL; int totitem= 0; - if(C==NULL) { - return parent_type_items; - } - RNA_enum_items_add_value(&item, &totitem, parent_type_items, PAROBJECT); if(ob->parent) { @@ -253,7 +249,6 @@ static EnumPropertyItem *rna_Object_parent_type_itemf(bContext *C, PointerRNA *p } RNA_enum_item_end(&item, &totitem); - *free= 1; return item; diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 404223ab590..2247e5499fb 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -546,24 +546,6 @@ static EnumPropertyItem *rna_Effector_shape_itemf(bContext *C, PointerRNA *ptr, { Object *ob= NULL; - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, effector_shape_items); - RNA_enum_items_add(&item, &totitem, curve_shape_items); - RNA_enum_items_add(&item, &totitem, empty_shape_items); - RNA_enum_items_add(&item, &totitem, vortex_shape_items); - RNA_enum_items_add(&item, &totitem, curve_vortex_shape_items); - RNA_enum_items_add(&item, &totitem, empty_vortex_shape_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - if(particle_field_check(ptr)) return empty_shape_items; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 2c81bda121f..28d0d2deb34 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -499,39 +499,9 @@ static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str) else strcpy(str, "No object"); } -EnumPropertyItem from_items[] = { - {PART_FROM_VERT, "VERT", 0, "Vertexes", ""}, - {PART_FROM_FACE, "FACE", 0, "Faces", ""}, - {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, - {0, NULL, 0, NULL, NULL} -}; - -EnumPropertyItem reactor_from_items[] = { - {PART_FROM_VERT, "VERT", 0, "Vertexes", ""}, - {PART_FROM_FACE, "FACE", 0, "Faces", ""}, - {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, - {PART_FROM_PARTICLE, "PARTICLE", 0, "Particle", ""}, - {0, NULL, 0, NULL, NULL} -}; static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, int *free) { - /* ParticleSettings *part = ptr->id.data; */ - - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, part_reactor_from_items); - RNA_enum_items_add(&item, &totitem, part_from_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - //if(part->type==PART_REACTOR) // return part_reactor_from_items; //else @@ -542,20 +512,6 @@ static EnumPropertyItem *rna_Particle_draw_as_itemf(bContext *C, PointerRNA *ptr { ParticleSettings *part = ptr->id.data; - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, part_hair_draw_as_items); - RNA_enum_items_add(&item, &totitem, part_draw_as_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - if(part->type==PART_HAIR) return part_hair_draw_as_items; else @@ -566,20 +522,6 @@ static EnumPropertyItem *rna_Particle_ren_as_itemf(bContext *C, PointerRNA *ptr, { ParticleSettings *part = ptr->id.data; - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, part_hair_ren_as_items); - RNA_enum_items_add(&item, &totitem, part_ren_as_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - if(part->type==PART_HAIR) return part_hair_ren_as_items; else diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index fbb24f9ada9..31aecbb8a76 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -624,7 +624,7 @@ static EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA rna_idproperty_check(&prop, ptr); eprop= (EnumPropertyRNA*)prop; - if(eprop->itemf==NULL || eprop->itemf==rna_EnumProperty_default_itemf) + if(eprop->itemf==NULL || eprop->itemf==rna_EnumProperty_default_itemf || !C) return eprop->item; return eprop->itemf(C, ptr, free); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 413f7c3dc7c..7f8ded7d3ee 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -119,27 +119,13 @@ static void rna_ParticleEdit_update(bContext *C, PointerRNA *ptr) static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *ptr, int *free) { - if(C==NULL) { - EnumPropertyItem *item= NULL; - int totitem= 0; - - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, particle_edit_hair_brush_items); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - else { - Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C)); - - if(edit && edit->psys) - return particle_edit_hair_brush_items; + Scene *scene= CTX_data_scene(C); + PTCacheEdit *edit = PE_get_current(scene, CTX_data_active_object(C)); + + if(edit && edit->psys) + return particle_edit_hair_brush_items; - return particle_edit_cache_brush_items; - } + return particle_edit_cache_brush_items; } static int rna_ParticleEdit_editable_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 5665d9d7adc..015df0e73de 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -64,19 +64,23 @@ EnumPropertyItem space_type_items[] = { {SPACE_USERPREF, "USER_PREFERENCES", 0, "User Preferences", ""}, {0, NULL, 0, NULL, NULL}}; -#define DC_RGB {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors."} -#define DC_RGBA {SI_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha", "Draw image with RGB colors and alpha transparency."} -#define DC_ALPHA {SI_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Draw alpha transparency channel."} -#define DC_Z {SI_SHOW_ZBUF, "Z_BUFFER", ICON_IMAGE_ZDEPTH, "Z-Buffer", "Draw Z-buffer associated with image (mapped from camera clip start to end)."} +static EnumPropertyItem draw_channels_items[] = { + {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors."}, + {SI_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha", "Draw image with RGB colors and alpha transparency."}, + {SI_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Draw alpha transparency channel."}, + {SI_SHOW_ZBUF, "Z_BUFFER", ICON_IMAGE_ZDEPTH, "Z-Buffer", "Draw Z-buffer associated with image (mapped from camera clip start to end)."}, #ifdef WITH_LCMS -#define DC_LCMS {SI_COLOR_CORRECTION, "COLOR_CORRECTED", ICON_IMAGE_ALPHA, "Color Corrected", "Display color corrected image."} -#else -#define DC_LCMS {0, NULL, 0, NULL, NULL} + {SI_COLOR_CORRECTION, "COLOR_CORRECTED", ICON_IMAGE_ALPHA, "Color Corrected", "Display color corrected image."}, #endif -#define DC_ZERO {0, NULL, 0, NULL, NULL} - -static EnumPropertyItem dc_all_items[] = {DC_RGB, DC_RGBA, DC_ALPHA, DC_Z, DC_LCMS, DC_ZERO}; + {0, NULL, 0, NULL, NULL}}; +static EnumPropertyItem transform_orientation_items[] = { + {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", "Align the transformation axes to world space"}, + {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", "Align the transformation axes to the selected objects' local space"}, + {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", "Align the transformation axes to average normal of selected elements (bone Y axis for pose mode)"}, + {V3D_MANIP_VIEW, "VIEW", 0, "View", "Align the transformation axes to the window"}, + {V3D_MANIP_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"}, + {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME @@ -155,37 +159,26 @@ EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, i Scene *scene; ListBase *transform_spaces; TransformOrientation *ts= NULL; - - 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; - RNA_enum_item_add(&item, &totitem, &global); - RNA_enum_item_add(&item, &totitem, &normal); - RNA_enum_item_add(&item, &totitem, &local); - RNA_enum_item_add(&item, &totitem, &view); - - if(C) { - scene= CTX_data_scene(C); - - if(scene) { - transform_spaces = &scene->transform_spaces; - ts = transform_spaces->first; - } - else - { - printf("no scene\n"); - } + RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_GLOBAL); + RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_NORMAL); + RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_LOCAL); + RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_VIEW); + + scene= CTX_data_scene(C); + + if(scene) { + transform_spaces = &scene->transform_spaces; + ts = transform_spaces->first; } else { - printf("no context\n"); + printf("no scene\n"); } - + if(ts) RNA_enum_item_add_separator(&item, &totitem); @@ -197,7 +190,6 @@ EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, i } RNA_enum_item_end(&item, &totitem); - *free= 1; return item; @@ -245,22 +237,14 @@ static void rna_SpaceImageEditor_image_set(PointerRNA *ptr, PointerRNA value) ED_space_image_set(NULL, sima, sc->scene, sc->scene->obedit, (Image*)value.data); } -static EnumPropertyItem dc_rgb_items[] = {DC_RGB, DC_LCMS, DC_ZERO}; -static EnumPropertyItem dc_alpha_items[] = {DC_RGB, DC_RGBA, DC_ALPHA, DC_LCMS, DC_ZERO}; -static EnumPropertyItem dc_z_items[] = {DC_RGB, DC_Z, DC_LCMS, DC_ZERO}; - static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, PointerRNA *ptr, int *free) { SpaceImage *sima= (SpaceImage*)ptr->data; + EnumPropertyItem *item= NULL; ImBuf *ibuf; void *lock; - int zbuf, alpha; + int zbuf, alpha, totitem= 0; - if(C==NULL) { - /* needed for doc generation */ - return dc_all_items; - } - ibuf= ED_space_image_acquire_buffer(sima, &lock); alpha= ibuf && (ibuf->channels == 4); @@ -269,13 +253,26 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, P ED_space_image_release_buffer(sima, lock); if(alpha && zbuf) - return dc_all_items; - else if(alpha) - return dc_alpha_items; - else if(zbuf) - return dc_z_items; - else - return dc_rgb_items; + return draw_channels_items; + + RNA_enum_items_add_value(&item, &totitem, draw_channels_items, 0); + + if(alpha) { + RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_SHOW_ALPHA); + RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_USE_ALPHA); + } + else if(zbuf) { + RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_SHOW_ZBUF); + } + +#ifdef WITH_LCMS + RNA_enum_items_add_value(&item, &totitem, draw_channels_items, SI_COLOR_CORRECTION); +#endif + + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; } static void rna_SpaceImageEditor_curves_update(bContext *C, PointerRNA *ptr) @@ -641,14 +638,6 @@ static void rna_def_space_3dview(BlenderRNA *brna) {V3D_ACTIVE, "ACTIVE_ELEMENT", 0, "Active Element", ""}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem transform_orientation_items[] = { - {V3D_MANIP_GLOBAL, "ORIENT_GLOBAL", 0, "Global", "Align the transformation axes to world space"}, - {V3D_MANIP_LOCAL, "ORIENT_LOCAL", 0, "Local", "Align the transformation axes to the selected objects' local space"}, - {V3D_MANIP_NORMAL, "ORIENT_NORMAL", 0, "Normal", "Align the transformation axes to average normal of selected elements (bone Y axis for pose mode)"}, - {V3D_MANIP_VIEW, "ORIENT_VIEW", 0, "View", "Align the transformation axes to the window"}, - {V3D_MANIP_CUSTOM, "ORIENT_CUSTOM", 0, "Custom", "Use a custom transform orientation"}, - {0, NULL, 0, NULL, NULL}}; - srna= RNA_def_struct(brna, "Space3DView", "Space"); RNA_def_struct_sdna(srna, "View3D"); RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data"); @@ -911,7 +900,7 @@ static void rna_def_space_image(BlenderRNA *brna) prop= RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); - RNA_def_property_enum_items(prop, dc_all_items); + RNA_def_property_enum_items(prop, draw_channels_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_SpaceImageEditor_draw_channels_itemf"); RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the image to draw."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, NULL); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index c4fb9ea3d0d..6f7bc9a4feb 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -206,7 +206,7 @@ static EnumPropertyItem *rna_TextureSlot_output_node_itemf(bContext *C, PointerR EnumPropertyItem *item= NULL; int totitem= 0; - if(tex && C) { /* Note, tex/mtex/ntree can be invalid of C is NULL, TODO - can this give valid results when C is NULL? */ + if(tex) { bNodeTree *ntree= tex->nodetree; if(ntree) { EnumPropertyItem tmp= {0, "", 0, "", ""}; @@ -229,8 +229,8 @@ static EnumPropertyItem *rna_TextureSlot_output_node_itemf(bContext *C, PointerR } RNA_enum_item_end(&item, &totitem); - *free = 1; + return item; } -- cgit v1.2.3 From 7bed5e35b4145813601895d085831e29e08edcb1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Oct 2009 20:09:21 +0000 Subject: added operators for setting rna for each type, this avoids having double "'quoted'" strings from C which is ugly. --- release/scripts/modules/bpy_ops.py | 80 +++++++++++++++------- source/blender/editors/object/object_ops.c | 12 ++-- source/blender/editors/space_view3d/view3d_ops.c | 38 +++++----- source/blender/windowmanager/intern/wm_operators.c | 48 ++++++------- 4 files changed, 104 insertions(+), 74 deletions(-) diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py index 0360964be3f..6772a3771cb 100644 --- a/release/scripts/modules/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py @@ -153,54 +153,80 @@ class MESH_OT_delete_edgeloop(bpy.types.Operator): bpy.ops.mesh.remove_doubles() return ('FINISHED',) -class WM_OT_context_set(bpy.types.Operator): +rna_path_prop = bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= "") + +class WM_OT_context_set_boolean(bpy.types.Operator): '''Set a context value.''' - __idname__ = "wm.context_set" + __idname__ = "wm.context_set_boolean" __label__ = "Context Set" - __props__ = [ - bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), - bpy.props.StringProperty(attr="value", name="Value", description="Assignment value (as a string)", maxlen= 1024, default= "") - ] - + __props__ = [rna_path_prop, bpy.props.BoolProperty(attr="value", name="Value", description="Assignment value", default= True)] def execute(self, context): exec("context.%s=%s" % (self.path, self.value)) # security nuts will complain. return ('FINISHED',) +class WM_OT_context_set_int(bpy.types.Operator): # same as enum + '''Set a context value.''' + __idname__ = "wm.context_set_int" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.IntProperty(attr="value", name="Value", description="Assignment value", default= 0)] + def execute(self, context): + exec("context.%s=%d" % (self.path, self.value)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_set_float(bpy.types.Operator): # same as enum + '''Set a context value.''' + __idname__ = "wm.context_set_int" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.FloatProperty(attr="value", name="Value", description="Assignment value", default= 0.0)] + def execute(self, context): + exec("context.%s=%f" % (self.path, self.value)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_set_string(bpy.types.Operator): # same as enum + '''Set a context value.''' + __idname__ = "wm.context_set_string" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.StringProperty(attr="value", name="Value", description="Assignment value", maxlen= 1024, default= "")] + def execute(self, context): + exec("context.%s='%s'" % (self.path, self.value)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_set_enum(bpy.types.Operator): + '''Set a context value.''' + __idname__ = "wm.context_set_enum" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.StringProperty(attr="value", name="Value", description="Assignment value (as a string)", maxlen= 1024, default= "")] + def execute(self, context): + exec("context.%s='%s'" % (self.path, self.value)) # security nuts will complain. + return ('FINISHED',) + class WM_OT_context_toggle(bpy.types.Operator): '''Toggle a context value.''' __idname__ = "wm.context_toggle" __label__ = "Context Toggle" - __props__ = [ - bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), - ] - + __props__ = [rna_path_prop] def execute(self, context): exec("context.%s=not (context.%s)" % (self.path, self.path)) # security nuts will complain. return ('FINISHED',) -class WM_OT_context_toggle_values(bpy.types.Operator): +class WM_OT_context_toggle_enum(bpy.types.Operator): '''Toggle a context value.''' - __idname__ = "wm.context_toggle_values" + __idname__ = "wm.context_toggle_enum" __label__ = "Context Toggle Values" __props__ = [ - bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), - bpy.props.StringProperty(attr="value_1", name="Value", description="Toggle value (as a string)", maxlen= 1024, default= ""), - bpy.props.StringProperty(attr="value_2", name="Value", description="Toggle value (as a string)", maxlen= 1024, default= "") + rna_path_prop, + bpy.props.StringProperty(attr="value_1", name="Value", description="Toggle enum", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="value_2", name="Value", description="Toggle enum", maxlen= 1024, default= "") ] - def execute(self, context): - exec("context.%s = [%s, %s][context.%s!=%s]" % (self.path, self.value_1, self.value_2, self.path, self.value_2)) # security nuts will complain. + exec("context.%s = ['%s', '%s'][context.%s!='%s']" % (self.path, self.value_1, self.value_2, self.path, self.value_2)) # security nuts will complain. return ('FINISHED',) class WM_OT_context_cycle_enum(bpy.types.Operator): '''Toggle a context value.''' __idname__ = "wm.context_cycle_enum" __label__ = "Context Enum Cycle" - __props__ = [ - bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= ""), - bpy.props.BoolProperty(attr="reverse", name="Reverse", description="Cycle backwards", default= False) - ] - + __props__ = [rna_path_prop, bpy.props.BoolProperty(attr="reverse", name="Reverse", description="Cycle backwards", default= False)] def execute(self, context): orig_value = eval("context.%s" % self.path) # security nuts will complain. @@ -233,8 +259,12 @@ class WM_OT_context_cycle_enum(bpy.types.Operator): bpy.ops.add(MESH_OT_delete_edgeloop) -bpy.ops.add(WM_OT_context_set) +bpy.ops.add(WM_OT_context_set_boolean) +bpy.ops.add(WM_OT_context_set_int) +bpy.ops.add(WM_OT_context_set_float) +bpy.ops.add(WM_OT_context_set_string) +bpy.ops.add(WM_OT_context_set_enum) bpy.ops.add(WM_OT_context_toggle) -bpy.ops.add(WM_OT_context_toggle_values) +bpy.ops.add(WM_OT_context_toggle_enum) bpy.ops.add(WM_OT_context_cycle_enum) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index eea36f630b7..775f9937095 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -281,15 +281,15 @@ void ED_object_generic_keymap(struct wmKeyConfig *keyconf, struct wmKeyMap *keym km = WM_keymap_add_item(keymap, "WM_OT_context_cycle_enum", OKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "scene.tool_settings.proportional_editing_falloff"); - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", OKEY, KM_PRESS, 0, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", OKEY, KM_PRESS, 0, 0); RNA_string_set(km->ptr, "path", "scene.tool_settings.proportional_editing"); - RNA_string_set(km->ptr, "value_1", "'DISABLED'"); - RNA_string_set(km->ptr, "value_2", "'ENABLED'"); + RNA_string_set(km->ptr, "value_1", "DISABLED"); + RNA_string_set(km->ptr, "value_2", "ENABLED"); - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", OKEY, KM_PRESS, KM_ALT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", OKEY, KM_PRESS, KM_ALT, 0); RNA_string_set(km->ptr, "path", "scene.tool_settings.proportional_editing"); - RNA_string_set(km->ptr, "value_1", "'DISABLED'"); - RNA_string_set(km->ptr, "value_2", "'CONNECTED'"); + RNA_string_set(km->ptr, "value_1", "DISABLED"); + RNA_string_set(km->ptr, "value_2", "CONNECTED"); } } diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 0ac62652b52..4b692e572e2 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -174,20 +174,20 @@ void view3d_keymap(wmKeyConfig *keyconf) /* drawtype */ - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", ZKEY, KM_PRESS, 0, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, 0, 0); RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); - RNA_string_set(km->ptr, "value_1", "'SOLID'"); - RNA_string_set(km->ptr, "value_2", "'WIREFRAME'"); + RNA_string_set(km->ptr, "value_1", "SOLID"); + RNA_string_set(km->ptr, "value_2", "WIREFRAME"); - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", ZKEY, KM_PRESS, KM_ALT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, KM_ALT, 0); RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); - RNA_string_set(km->ptr, "value_1", "'TEXTURED'"); - RNA_string_set(km->ptr, "value_2", "'SOLID'"); + RNA_string_set(km->ptr, "value_1", "TEXTURED"); + RNA_string_set(km->ptr, "value_2", "SOLID"); - km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_values", ZKEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", ZKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "space_data.viewport_shading"); - RNA_string_set(km->ptr, "value_1", "'SHADED'"); - RNA_string_set(km->ptr, "value_2", "'WIREFRAME'"); + RNA_string_set(km->ptr, "value_1", "SHADED"); + RNA_string_set(km->ptr, "value_2", "WIREFRAME"); /* selection*/ WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); @@ -225,28 +225,28 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0); /* context ops */ - km = WM_keymap_add_item(keymap, "WM_OT_context_set", COMMAKEY, KM_PRESS, 0, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); RNA_string_set(km->ptr, "path", "space_data.pivot_point"); - RNA_string_set(km->ptr, "value", "'BOUNDING_BOX_CENTER'"); + RNA_string_set(km->ptr, "value", "BOUNDING_BOX_CENTER"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", COMMAKEY, KM_PRESS, KM_CTRL, 0); /* 2.4x allowed Comma+Shift too, rather not use both */ + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, KM_CTRL, 0); /* 2.4x allowed Comma+Shift too, rather not use both */ RNA_string_set(km->ptr, "path", "space_data.pivot_point"); - RNA_string_set(km->ptr, "value", "'MEDIAN_POINT'"); + RNA_string_set(km->ptr, "value", "MEDIAN_POINT"); km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", COMMAKEY, KM_PRESS, KM_ALT, 0); /* new in 2.5 */ RNA_string_set(km->ptr, "path", "space_data.pivot_point_align"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", PERIODKEY, KM_PRESS, 0, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0); RNA_string_set(km->ptr, "path", "space_data.pivot_point"); - RNA_string_set(km->ptr, "value", "'CURSOR'"); + RNA_string_set(km->ptr, "value", "CURSOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", PERIODKEY, KM_PRESS, KM_CTRL, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0); RNA_string_set(km->ptr, "path", "space_data.pivot_point"); - RNA_string_set(km->ptr, "value", "'INDIVIDUAL_CENTERS'"); + RNA_string_set(km->ptr, "value", "INDIVIDUAL_CENTERS"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", PERIODKEY, KM_PRESS, KM_ALT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_ALT, 0); RNA_string_set(km->ptr, "path", "space_data.pivot_point"); - RNA_string_set(km->ptr, "value", "'ACTIVE_ELEMENT'"); + RNA_string_set(km->ptr, "value", "ACTIVE_ELEMENT"); transform_keymap_for_space(keyconf, keymap, SPACE_VIEW3D); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 2ed32808f48..5ad138c3890 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2220,52 +2220,52 @@ void wm_window_keymap(wmKeyConfig *keyconf) /* Space switching */ - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */ + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */ RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'LOGIC_EDITOR'"); + RNA_string_set(km->ptr, "value", "LOGIC_EDITOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F3KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F3KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'NODE_EDITOR'"); + RNA_string_set(km->ptr, "value", "NODE_EDITOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F4KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was data browser */ + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F4KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was data browser */ RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'CONSOLE'"); + RNA_string_set(km->ptr, "value", "CONSOLE"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F5KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F5KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'VIEW_3D'"); + RNA_string_set(km->ptr, "value", "VIEW_3D"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F6KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F6KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'GRAPH_EDITOR'"); + RNA_string_set(km->ptr, "value", "GRAPH_EDITOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F7KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F7KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'PROPERTIES'"); + RNA_string_set(km->ptr, "value", "PROPERTIES"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F8KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F8KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'SEQUENCE_EDITOR'"); + RNA_string_set(km->ptr, "value", "SEQUENCE_EDITOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F9KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F9KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'OUTLINER'"); + RNA_string_set(km->ptr, "value", "OUTLINER"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F9KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F9KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'OUTLINER'"); + RNA_string_set(km->ptr, "value", "OUTLINER"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F10KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F10KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'IMAGE_EDITOR'"); + RNA_string_set(km->ptr, "value", "IMAGE_EDITOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F11KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F11KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'TEXT_EDITOR'"); + RNA_string_set(km->ptr, "value", "TEXT_EDITOR"); - km = WM_keymap_add_item(keymap, "WM_OT_context_set", F12KEY, KM_PRESS, KM_SHIFT, 0); + km = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F12KEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "path", "area.type"); - RNA_string_set(km->ptr, "value", "'DOPESHEET_EDITOR'"); + RNA_string_set(km->ptr, "value", "DOPESHEET_EDITOR"); } -- cgit v1.2.3 From 1da4a06fc7d19344b00717857b8eef6ed534a0ea Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Wed, 14 Oct 2009 21:05:35 +0000 Subject: Don't depend on context for transform_orientation enum New current_orientation property that returns the current transform orientation data (if any) New UI elements to rename and remove custom orientation (visible only when needed) --- release/scripts/ui/space_view3d.py | 11 +++++------ source/blender/makesrna/intern/rna_scene.c | 2 ++ source/blender/makesrna/intern/rna_space.c | 25 ++++++++++++++----------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index ce4414dc2f6..490c9065d94 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1333,12 +1333,11 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel): col.itemR(view, "transform_orientation") col.itemO("tfm.create_orientation", text="Create") -# orientation_index = view.__rna__.properties["transform_orientation"].items[view.transform_orientation].value -# -# if orientation_index >= 4: -# orientation = context.scene.orientations[orientation_index - 4] -# col.itemR(orientation, "name") - col.itemO("tfm.delete_orientation", text="Delete") + orientation = view.current_orientation + + if orientation: + col.itemR(orientation, "name") + col.itemO("tfm.delete_orientation", text="Delete") # Operators diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 03c7a06818d..59850216060 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -485,10 +485,12 @@ static void rna_def_transform_orientation(BlenderRNA *brna) prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "mat"); RNA_def_property_multi_array(prop, 2, matrix_dimsize); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); } static void rna_def_tool_settings(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 015df0e73de..bc789960c3d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -147,16 +147,20 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr) } } -static int rna_TransformOrientation_getf(PointerRNA *ptr) +static PointerRNA rna_CurrentOrientation_get(PointerRNA *ptr) { + Scene *scene = ((bScreen*)ptr->id.data)->scene; View3D *v3d= (View3D*)ptr->data; - - return v3d->twmode; + + if (v3d->twmode < 4) + return rna_pointer_inherit_refine(ptr, &RNA_TransformOrientation, NULL); + else + return rna_pointer_inherit_refine(ptr, &RNA_TransformOrientation, BLI_findlink(&scene->transform_spaces, v3d->twmode - 4)); } EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, int *free) { - Scene *scene; + Scene *scene = ((bScreen*)ptr->id.data)->scene; ListBase *transform_spaces; TransformOrientation *ts= NULL; EnumPropertyItem tmp = {0, "", 0, "", ""}; @@ -168,16 +172,10 @@ EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, i RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_LOCAL); RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_VIEW); - scene= CTX_data_scene(C); - if(scene) { transform_spaces = &scene->transform_spaces; ts = transform_spaces->first; } - else - { - printf("no scene\n"); - } if(ts) RNA_enum_item_add_separator(&item, &totitem); @@ -783,10 +781,15 @@ static void rna_def_space_3dview(BlenderRNA *brna) prop= RNA_def_property(srna, "transform_orientation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "twmode"); RNA_def_property_enum_items(prop, transform_orientation_items); - RNA_def_property_enum_funcs(prop, "rna_TransformOrientation_getf", NULL, "rna_TransformOrientation_itemf"); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_TransformOrientation_itemf"); RNA_def_property_ui_text(prop, "Transform Orientation", "Transformation orientation."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + prop= RNA_def_property(srna, "current_orientation", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "TransformOrientation"); + RNA_def_property_pointer_funcs(prop, "rna_CurrentOrientation_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Current Transform Orientation", "Current Transformation orientation."); + prop= RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, "RegionView3D", "viewlock", RV3D_LOCKED); RNA_def_property_ui_text(prop, "Lock", "Lock View Rotation"); -- cgit v1.2.3 From 316d604dafba8b60367f00d3ad19e3273056a690 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 15 Oct 2009 01:34:29 +0000 Subject: TransformOrientation enum is in the transform operators too, so we can't always cast to screen. --- source/blender/makesrna/intern/rna_space.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index bc789960c3d..72856e54bdf 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -160,7 +160,7 @@ static PointerRNA rna_CurrentOrientation_get(PointerRNA *ptr) EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, int *free) { - Scene *scene = ((bScreen*)ptr->id.data)->scene; + Scene *scene = NULL; ListBase *transform_spaces; TransformOrientation *ts= NULL; EnumPropertyItem tmp = {0, "", 0, "", ""}; @@ -172,19 +172,26 @@ EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, i RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_LOCAL); RNA_enum_items_add_value(&item, &totitem, transform_orientation_items, V3D_MANIP_VIEW); + if (ptr->type == &RNA_Space3DView) + scene = ((bScreen*)ptr->id.data)->scene; + else + scene = CTX_data_scene(C); /* can't use scene from ptr->id.data because that enum is also used by operators */ + if(scene) { transform_spaces = &scene->transform_spaces; ts = transform_spaces->first; } if(ts) + { RNA_enum_item_add_separator(&item, &totitem); - for(; ts; ts = ts->next) { - tmp.identifier = ts->name; - tmp.name= ts->name; - tmp.value = i++; - RNA_enum_item_add(&item, &totitem, &tmp); + for(; ts; ts = ts->next) { + tmp.identifier = ts->name; + tmp.name= ts->name; + tmp.value = i++; + RNA_enum_item_add(&item, &totitem, &tmp); + } } RNA_enum_item_end(&item, &totitem); -- cgit v1.2.3 From e6e8ba98dffc3cad88188b6d8b08e67e2008b9a8 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 15 Oct 2009 07:07:01 +0000 Subject: Fixed some icons in user preferences. These seem to be caused to an issue in the icon file itself though, where it assumes the wrong icon when pressed. (See checkboxes in menus that become locks when enabled) --- release/scripts/ui/space_userpref.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 7af8766e256..46a56f7d133 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -469,13 +469,13 @@ class USERPREF_PT_input(bpy.types.Panel): row = subcol.row() if kmi.expanded: - row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_DOWN") + row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_RIGHT") else: row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_RIGHT") itemrow = row.row() itemrow.enabled = km.user_defined - itemrow.itemR(kmi, "active", text="", icon="ICON_DOT") + itemrow.itemR(kmi, "active", text="", icon="ICON_CHECKBOX_DEHLT") itemcol = itemrow.column() itemcol.active = kmi.active @@ -519,7 +519,7 @@ class USERPREF_PT_input(bpy.types.Panel): subrow.itemR(kmi, "shift") subrow.itemR(kmi, "ctrl") subrow.itemR(kmi, "alt") - subrow.itemR(kmi, "oskey") + subrow.itemR(kmi, "oskey", text="Cmd") sub.itemR(kmi, "key_modifier", text="", event=True) flow = itemcol.column_flow(columns=2) -- cgit v1.2.3 From 3b2d75293333aef42afd2e7c77da855365f8b2cd Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Thu, 15 Oct 2009 08:27:31 +0000 Subject: Cocoa : - Small changes to make ghost_cocoa compatible with 10.4 + gcc4.0 (the initial goal was to be 10.5+ compatible, but 10.4 is finally also possible) - Main window title is now in Apple document window title style (proxy icon + filename) - fix for top menu "Blender" sub-menu not anchored correctly in 10.5 --- intern/ghost/intern/GHOST_SystemCocoa.mm | 5 ++-- intern/ghost/intern/GHOST_WindowCocoa.mm | 47 ++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 072b2dfee86..62f0c538e7e 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -635,6 +635,7 @@ GHOST_TSuccess GHOST_SystemCocoa::init() [mainMenubar addItem:menuItem]; [menuItem release]; + [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5 [appMenu release]; //Create the window menu @@ -815,7 +816,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const { - NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; + unsigned int modifiers = [[NSApp currentEvent] modifierFlags]; //Direct query to modifierFlags can be used in 10.6 keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false); @@ -1175,7 +1176,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); - NSUInteger modifiers; + unsigned int modifiers; NSString *characters; GHOST_TKey keyCode; unsigned char ascii; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 999ec0de9c1..f86fa49b31c 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -40,13 +40,13 @@ // Pixel Format Attributes for the windowed NSOpenGLContext -static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = +static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated, - NSOpenGLPFAAllowOfflineRenderers, // NOTE: Needed to connect to secondary GPUs - NSOpenGLPFADepthSize, 32, - 0 + //NSOpenGLPFAAllowOfflineRenderers, // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 32, + (NSOpenGLPixelFormatAttribute) 0 }; #pragma mark Cocoa window delegate object @@ -187,7 +187,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( return; } - [m_window setTitle:[NSString stringWithUTF8String:title]]; + setTitle(title); //Creates the OpenGL View inside the window @@ -271,7 +271,38 @@ void GHOST_WindowCocoa::setTitle(const STR_String& title) NSString *windowTitle = [[NSString alloc] initWithUTF8String:title]; - [m_window setTitle:windowTitle]; + //Set associated file if applicable + if ([windowTitle hasPrefix:@"Blender"]) + { + NSRange fileStrRange; + NSString *associatedFileName; + int len; + + fileStrRange.location = [windowTitle rangeOfString:@"["].location+1; + len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location; + + if (len >0) + { + fileStrRange.length = len; + associatedFileName = [windowTitle substringWithRange:fileStrRange]; + @try { + [m_window setRepresentedFilename:associatedFileName]; + } + @catch (NSException * e) { + printf("\nInvalid file path given in window title"); + } + [m_window setTitle:[associatedFileName lastPathComponent]]; + } + else { + [m_window setTitle:windowTitle]; + [m_window setRepresentedFilename:@""]; + } + + } else { + [m_window setTitle:windowTitle]; + [m_window setRepresentedFilename:@""]; + } + [windowTitle release]; [pool drain]; @@ -501,7 +532,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) defer:YES]; //Copy current window parameters [tmpWindow setTitle:[m_window title]]; - [tmpWindow setRepresentedURL:[m_window representedURL]]; + [tmpWindow setRepresentedFilename:[m_window representedFilename]]; [tmpWindow setReleasedWhenClosed:NO]; [tmpWindow setAcceptsMouseMovedEvents:YES]; [tmpWindow setDelegate:[m_window delegate]]; @@ -557,7 +588,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) defer:YES]; //Copy current window parameters [tmpWindow setTitle:[m_window title]]; - [tmpWindow setRepresentedURL:[m_window representedURL]]; + [tmpWindow setRepresentedFilename:[m_window representedFilename]]; [tmpWindow setReleasedWhenClosed:NO]; [tmpWindow setAcceptsMouseMovedEvents:YES]; [tmpWindow setDelegate:[m_window delegate]]; -- cgit v1.2.3 From a6645bfafb75f9688f8446904682143fbf7b63e3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 08:39:47 +0000 Subject: pack all was giving an error on the render result --- source/blender/blenkernel/intern/packedFile.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 0de97b9c703..036cadebbe8 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -176,6 +176,11 @@ PackedFile *newPackedFile(ReportList *reports, char *filename) char name[FILE_MAXDIR+FILE_MAXFILE]; void *data; + /* render result has no filename and can be ignored + * any other files with no name can be ignored too */ + if(filename[0]=='\0') + return NULL; + //XXX waitcursor(1); // convert relative filenames to absolute filenames @@ -188,7 +193,7 @@ PackedFile *newPackedFile(ReportList *reports, char *filename) file= open(name, O_BINARY|O_RDONLY); if (file <= 0) { - BKE_reportf(reports, RPT_ERROR, "Can't open file: %s", name); + BKE_reportf(reports, RPT_ERROR, "Can't open file: \"%s\"", name); } else { filelen = BLI_filesize(file); -- cgit v1.2.3 From a28b9512fe51a829cbab692f7505d9aa66a9ad5e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 09:00:40 +0000 Subject: made texflag a short everywhere (only stores one flag) fix for crash with separate (missing NULL check) --- source/blender/blenkernel/BKE_object.h | 2 +- source/blender/blenkernel/intern/object.c | 4 ++-- source/blender/editors/object/object_edit.c | 2 +- source/blender/editors/transform/transform_conversions.c | 2 +- source/blender/makesdna/DNA_curve_types.h | 2 +- source/blender/makesdna/DNA_meta_types.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 1cb6efeb838..aeb33cd3628 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -114,7 +114,7 @@ int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3 void object_handle_update(struct Scene *scene, struct Object *ob); float give_timeoffset(struct Object *ob); -int give_obdata_texspace(struct Object *ob, int **texflag, float **loc, float **size, float **rot); +int give_obdata_texspace(struct Object *ob, short **texflag, float **loc, float **size, float **rot); int object_insert_ptcache(struct Object *ob); // void object_delete_ptcache(struct Object *ob, int index); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8494fdae954..eb5beb734a1 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1102,7 +1102,7 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) pa->hair = MEM_dupallocN(pa->hair); } - if(psysn->particles->keys || psysn->particles->boid) { + if(psysn->particles && (psysn->particles->keys || psysn->particles->boid)) { ParticleKey *key = psysn->particles->keys; BoidParticle *boid = psysn->particles->boid; @@ -2475,7 +2475,7 @@ float give_timeoffset(Object *ob) { } } -int give_obdata_texspace(Object *ob, int **texflag, float **loc, float **size, float **rot) { +int give_obdata_texspace(Object *ob, short **texflag, float **loc, float **size, float **rot) { if (ob->data==NULL) return 0; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index abd6847c6db..d302e1eeec8 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1258,7 +1258,7 @@ static void copymenu_modifiers(Scene *scene, View3D *v3d, Object *ob) static void copy_texture_space(Object *to, Object *ob) { float *poin1= NULL, *poin2= NULL; - int texflag= 0; + short texflag= 0; if(ob->type==OB_MESH) { texflag= ((Mesh *)ob->data)->texflag; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 16d07894682..317457ee33f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -292,7 +292,7 @@ static void createTransTexspace(bContext *C, TransInfo *t) TransData *td; Object *ob; ID *id; - int *texflag; + short *texflag; ob = OBACT; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 6cfeb646cf2..f988511b146 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -174,7 +174,7 @@ typedef struct Curve { float size[3]; float rot[3]; - int texflag; /* keep an int because of give_obdata_texspace() */ + short texflag, pad1; /* keep a short because of give_obdata_texspace() */ short drawflag, twist_mode, pad[2]; float twist_smooth, pad2; diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h index 8b61405b851..0e746eb0f4d 100644 --- a/source/blender/makesdna/DNA_meta_types.h +++ b/source/blender/makesdna/DNA_meta_types.h @@ -77,7 +77,7 @@ typedef struct MetaBall { char flag, flag2; /* flag is enum for updates, flag2 is bitflags for settings */ short totcol; - int texflag; /* used to store MB_AUTOSPACE */ + short texflag, pad; /* used to store MB_AUTOSPACE */ /* texture space, copied as one block in editobject.c */ float loc[3]; -- cgit v1.2.3 From 29e738f60c1cafc33b8006425f1fad4c1721d971 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Oct 2009 09:56:10 +0000 Subject: Bugfix: deep shadow buffer commit made mixed solid/ztransp rendering not work correct without OSA. --- source/blender/render/intern/source/zbuf.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index a7b9867715f..6e305a2b82b 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -3181,15 +3181,19 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) int x, y, *rza, *rma; intptr_t *rd; - if((R.osa==0 && !pa->rectz) || !pa->rectdaps) { - fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE); - return; - } - if(R.osa==0) { - memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty); + if(!pa->rectz) + fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE); + else + memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty); + if(rectmask && pa->rectmask) memcpy(rectmask, pa->rectmask, sizeof(int)*pa->rectx*pa->recty); + + return; + } + else if(!pa->rectdaps) { + fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE); return; } -- cgit v1.2.3 From 384a1b5a5c15cfc5311f3865bde095d89130cfa5 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 15 Oct 2009 10:13:59 +0000 Subject: UI Templates: RNA-Path Builder (Skeleton Code) Added a base-template for editing/creating RNA-Paths. This is now used for KeyingSets and Driver UI's, so that when the actual magic gets put in, it will work. --- release/scripts/ui/buttons_scene.py | 2 +- source/blender/editors/include/UI_interface.h | 2 ++ .../editors/interface/interface_templates.c | 35 ++++++++++++++++++++-- source/blender/editors/space_graph/graph_buttons.c | 8 +++-- source/blender/makesrna/intern/rna_ui_api.c | 10 +++++++ 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index deb20f2b432..54f47791d59 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -97,7 +97,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel): col = layout.column() col.itemL(text="Target:") col.template_any_ID(ksp, "id", "id_type") - col.itemR(ksp, "rna_path") + col.template_path_builder(ksp, "rna_path", ksp.id) row = layout.row() diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 2fd870cf696..bd8214db29b 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -622,6 +622,8 @@ void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *newop, char *openop, char *unlinkop); void uiTemplateAnyID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *proptypename, char *text); +void uiTemplatePathBuilder(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, + struct PointerRNA *root_ptr, char *text); uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr); uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr); void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index de0d6191f16..dfe21171928 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -405,9 +405,10 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname } /************************ ID Chooser Template ***************************/ -/* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use */ -/* - propname: property identifier for property that ID-pointer gets stored to +/* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use + * + * - propname: property identifier for property that ID-pointer gets stored to * - proptypename: property identifier for property used to determine the type of ID-pointer that can be used */ void uiTemplateAnyID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *proptypename, char *text) @@ -438,12 +439,42 @@ void uiTemplateAnyID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn uiItemL(row, "ID-Block:", 0); /* ID-Type Selector - just have a menu of icons */ + // FIXME: the icon-only setting doesn't work when we supply a blank name uiItemFullR(row, "", 0, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY); /* ID-Block Selector - just use pointer widget... */ uiItemFullR(row, "", 0, ptr, propID, 0, 0, 0); } +/********************* RNA Path Builder Template ********************/ + +/* This is creating/editing RNA-Paths + * + * - ptr: struct which holds the path property + * - propname: property identifier for property that path gets stored to + * - root_ptr: struct that path gets built from + */ +void uiTemplatePathBuilder(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *root_ptr, char *text) +{ + PropertyRNA *propPath; + uiLayout *row; + + /* check that properties are valid */ + propPath= RNA_struct_find_property(ptr, propname); + if (!propPath || RNA_property_type(propPath) != PROP_STRING) { + printf("uiTemplatePathBuilder: path property not found: %s\n", propname); + return; + } + + /* Start drawing UI Elements using standard defines */ + row= uiLayoutRow(layout, 1); + + /* Path (existing string) Widget */ + uiItemR(row, text, ICON_RNA, ptr, propname, 0); + + // TODO: attach something to this to make allow searching of nested properties to 'build' the path +} + /************************ Modifier Template *************************/ #define ERROR_LIBDATA_MESSAGE "Can't edit external libdata" diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index fa44b281f15..87a11305bd9 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -339,11 +339,15 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* Target Property */ // TODO: make this less technical... if (dtar->id) { + PointerRNA root_ptr; + + /* get pointer for resolving the property selected */ + RNA_id_pointer_create(dtar->id, &root_ptr); + col= uiLayoutColumn(box, 1); block= uiLayoutGetBlock(col); /* rna path */ - // TODO: this needs path constructor widget - uiItemR(col, "Path", 0, &dtar_ptr, "rna_path", 0); + uiTemplatePathBuilder(col, (bContext *)C, &dtar_ptr, "rna_path", &root_ptr, "Path"); /* array index */ // TODO: this needs selector which limits it to ok values diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 79465f64daf..cce8fb0fef7 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -266,6 +266,16 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); parm= RNA_def_string(func, "text", "", 0, "", "Custom label to display in UI."); + func= RNA_def_function(srna, "template_path_builder", "uiTemplatePathBuilder"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); + parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "root", "ID", "", "ID-block from which path is evaluated from."); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + parm= RNA_def_string(func, "text", "", 0, "", "Custom label to display in UI."); + func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); parm= RNA_def_pointer(func, "data", "Modifier", "", "Modifier data."); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); -- cgit v1.2.3 From 734d50e8df0c06e6a4630078f4b7250fbe7d6dcc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 11:11:52 +0000 Subject: typing in non-existant dirs now goes back to the previous dir. (also for bookmarks and when changing dir's in other places) --- release/scripts/ui/space_view3d.py | 4 ++-- source/blender/blenkernel/intern/pointcache.c | 3 --- source/blender/editors/space_file/file_intern.h | 2 +- source/blender/editors/space_file/file_ops.c | 17 ++++++++++------- source/blender/editors/space_file/filesel.c | 10 ++++++++-- source/blender/editors/space_file/space_file.c | 4 ++-- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 490c9065d94..dfc491522f5 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -172,8 +172,8 @@ class VIEW3D_MT_select_object(bpy.types.Menu): layout.itemO("object.select_random", text="Random") layout.itemO("object.select_mirror", text="Mirror") layout.itemO("object.select_by_layer", text="Select All by Layer") - layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...") - layout.itemO("object.select_grouped", text="Select Grouped...") + layout.item_menu_enumO("object.select_by_type", "type", "", text="Select All by Type...") + layout.item_menu_enumO("object.select_grouped", "type", text="Select Grouped...") layout.itemO("object.select_pattern", text="Select Pattern...") class VIEW3D_MT_select_pose(bpy.types.Menu): diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index fa0d5cba604..68f0e33a98f 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -84,9 +84,6 @@ #include "BLI_winstuff.h" #endif -static void ptcache_data_to(void **data, int type, int index, void *to); -static void ptcache_data_from(void **data, int type, void *from); - #define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); } #define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); } diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index a99594e9575..d07ffd4b964 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -88,7 +88,7 @@ int file_hilight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my /* filesel.c */ float file_string_width(const char* str); float file_font_pointsize(); -void file_change_dir(struct SpaceFile *sfile); +void file_change_dir(struct SpaceFile *sfile, int checkdir); int file_select_match(struct SpaceFile *sfile, const char *pattern); void autocomplete_directory(struct bContext *C, char *str, void *arg_v); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index c0be1ffb637..a49b0a072af 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -177,7 +177,7 @@ static FileSelect file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, s BLI_add_slash(params->dir); } - file_change_dir(sfile); + file_change_dir(sfile, 0); retval = FILE_SELECT_DIR; } } @@ -343,7 +343,7 @@ static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event) RNA_string_get(op->ptr, "dir", entry); BLI_strncpy(params->dir, entry, sizeof(params->dir)); BLI_cleanup_dir(G.sce, params->dir); - file_change_dir(sfile); + file_change_dir(sfile, 1); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } @@ -645,7 +645,7 @@ int file_parent_exec(bContext *C, wmOperator *unused) if (BLI_has_parent(sfile->params->dir)) { BLI_parent_dir(sfile->params->dir); BLI_cleanup_dir(G.sce, sfile->params->dir); - file_change_dir(sfile); + file_change_dir(sfile, 0); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } } @@ -672,7 +672,7 @@ int file_refresh_exec(bContext *C, wmOperator *unused) { SpaceFile *sfile= CTX_wm_space_file(C); - file_change_dir(sfile); + file_change_dir(sfile, 1); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); @@ -704,7 +704,7 @@ int file_previous_exec(bContext *C, wmOperator *unused) folderlist_popdir(sfile->folders_prev, sfile->params->dir); folderlist_pushdir(sfile->folders_next, sfile->params->dir); - file_change_dir(sfile); + file_change_dir(sfile, 1); } WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); @@ -736,7 +736,7 @@ int file_next_exec(bContext *C, wmOperator *unused) // update folder_prev so we can check for it in folderlist_clear_next() folderlist_pushdir(sfile->folders_prev, sfile->params->dir); - file_change_dir(sfile); + file_change_dir(sfile, 1); } WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); @@ -795,6 +795,8 @@ int file_directory_exec(bContext *C, wmOperator *unused) SpaceFile *sfile= CTX_wm_space_file(C); if(sfile->params) { + char prev_dir[sizeof(sfile->params->dir)]; + BLI_strncpy(prev_dir, filelist_dir(sfile->files), sizeof(prev_dir)); if ( sfile->params->dir[0] == '~' ) { if (sfile->params->dir[1] == '\0') { @@ -817,7 +819,8 @@ int file_directory_exec(bContext *C, wmOperator *unused) #endif BLI_cleanup_dir(G.sce, sfile->params->dir); BLI_add_slash(sfile->params->dir); - file_change_dir(sfile); + file_change_dir(sfile, 1); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 9f5d889c7b9..89678bffd01 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -384,9 +384,15 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar return sfile->layout; } -void file_change_dir(struct SpaceFile *sfile) +void file_change_dir(struct SpaceFile *sfile, int checkdir) { - if (sfile->params) { + if (sfile->params) { + + if(checkdir && S_ISDIR(BLI_exists(sfile->params->dir)) == 0) { + BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir)); + /* could return but just refresh the current dir */ + } + filelist_setdir(sfile->files, sfile->params->dir); if(folderlist_clear_next(sfile)) diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 4d3376e0e1f..91d917acfe7 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -180,7 +180,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl) if(sfileo->params) { sfilen->params= MEM_dupallocN(sfileo->params); - file_change_dir(sfilen); + file_change_dir(sfilen, 0); } if (sfileo->layout) { sfilen->layout= MEM_dupallocN(sfileo->layout); @@ -197,7 +197,7 @@ static void file_refresh(const bContext *C, ScrArea *sa) sfile->folders_prev = folderlist_new(); if (!sfile->files) { sfile->files = filelist_new(params->type); - file_change_dir(sfile); + file_change_dir(sfile, 0); params->active_file = -1; // added this so it opens nicer (ton) } filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT); -- cgit v1.2.3 From fe649ec580cf9fa0da1ca81a97b17a92fe7f2c92 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 15 Oct 2009 11:52:23 +0000 Subject: Num Sliders Tweak: The dark bar for sliders will now be drawn in a way that takes into account the state of the slider (this includes info about keyframing and/or drivers). This means no more ambiguarity about whether these sliders are animated or not! I've had to make a little hack here to make sure that the sliders bar will still be visible after the state has been blended, but this should probably be solved nicer by adding a separate setting for blending-factor in this case. --- .../blender/editors/interface/interface_widgets.c | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 007a57fb67a..246da9ddf4c 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1262,6 +1262,35 @@ static void widget_state(uiWidgetType *wt, int state) } } +/* sliders use special hack which sets 'item' as inner when drawing filling */ +static void widget_state_numslider(uiWidgetType *wt, int state) +{ + uiWidgetStateColors *wcol_state= wt->wcol_state; + float blend= wcol_state->blend - 0.2f; // XXX special tweak to make sure that bar will still be visible + + /* call this for option button */ + widget_state(wt, state); + + /* now, set the inner-part so that it reflects state settings too */ + // TODO: maybe we should have separate settings for the blending colors used for this case? + if(state & UI_SELECT) { + if(state & UI_BUT_ANIMATED_KEY) + widget_state_blend(wt->wcol.item, wcol_state->inner_key_sel, blend); + else if(state & UI_BUT_ANIMATED) + widget_state_blend(wt->wcol.item, wcol_state->inner_anim_sel, blend); + else if(state & UI_BUT_DRIVEN) + widget_state_blend(wt->wcol.item, wcol_state->inner_driven_sel, blend); + } + else { + if(state & UI_BUT_ANIMATED_KEY) + widget_state_blend(wt->wcol.item, wcol_state->inner_key, blend); + else if(state & UI_BUT_ANIMATED) + widget_state_blend(wt->wcol.item, wcol_state->inner_anim, blend); + else if(state & UI_BUT_DRIVEN) + widget_state_blend(wt->wcol.item, wcol_state->inner_driven, blend); + } +} + /* labels use theme colors for text */ static void widget_state_label(uiWidgetType *wt, int state) { @@ -2192,6 +2221,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) case UI_WTYPE_SLIDER: wt.wcol_theme= &btheme->tui.wcol_numslider; wt.custom= widget_numslider; + wt.state= widget_state_numslider; break; case UI_WTYPE_EXEC: -- cgit v1.2.3 From 158534d40460bab6f5781384dfdc11d3b93f81bc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Oct 2009 13:33:56 +0000 Subject: Bugfix: editing shape keys in edit mode would not work correct when blending shape keys. --- source/blender/editors/mesh/editmesh.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 52744c81b7e..b0c51131041 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -787,7 +787,6 @@ void make_editMesh(Scene *scene, Object *ob) undo_editmode_clear(); } - /* make editverts */ CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); mvert= me->mvert; @@ -797,10 +796,14 @@ void make_editMesh(Scene *scene, Object *ob) co= mvert->co; + /* edit the shape key coordinate if available */ + if(actkey && a < actkey->totelem) + co= (float*)actkey->data + 3*a; + eve= addvertlist(em, co, NULL); evlist[a]= eve; - // face select sets selection in next loop + /* face select sets selection in next loop */ if(!paint_facesel_test(ob)) eve->f |= (mvert->flag & 1); -- cgit v1.2.3 From d80074f18cc4f11086c7e69c8591b2b43980d946 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 15 Oct 2009 13:47:18 +0000 Subject: Updated icons. Changed some icon names that weren't blank. --- release/datafiles/blenderbuttons | Bin 190499 -> 195438 bytes release/scripts/ui/buttons_data_mesh.py | 4 +- release/scripts/ui/buttons_material.py | 2 +- release/scripts/ui/space_filebrowser.py | 14 +- release/scripts/ui/space_info.py | 12 +- source/blender/editors/datafiles/blenderbuttons.c | 12066 ++++++++++--------- source/blender/editors/include/UI_icons.h | 22 +- .../editors/interface/interface_templates.c | 6 +- source/blender/makesrna/intern/rna_ID.c | 10 +- source/blender/makesrna/intern/rna_texture.c | 6 +- 10 files changed, 6151 insertions(+), 5991 deletions(-) diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons index aa7870f6712..f9a4b934969 100644 Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ diff --git a/release/scripts/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py index 108b4ef4371..8dc5af5cf4f 100644 --- a/release/scripts/ui/buttons_data_mesh.py +++ b/release/scripts/ui/buttons_data_mesh.py @@ -82,9 +82,9 @@ class DATA_PT_vertex_groups(DataButtonsPanel): col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="") col.itemO("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="") - col.itemO("object.vertex_group_copy", icon='ICON_COPYDOWN', text="") + col.itemO("object.vertex_group_copy", icon='ICON_COPY_ID', text="") if ob.data.users > 1: - col.itemO("object.vertex_group_copy_to_linked", icon='ICON_COPYDOWN', text="") + col.itemO("object.vertex_group_copy_to_linked", icon='ICON_LINK_AREA', text="") group = ob.active_vertex_group if group: diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index fbd2df381e0..e0e2fc736c0 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -59,7 +59,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel): col = row.column(align=True) col.itemO("object.material_slot_add", icon='ICON_ZOOMIN', text="") col.itemO("object.material_slot_remove", icon='ICON_ZOOMOUT', text="") - col.itemO("object.material_slot_copy", icon='ICON_COPYDOWN', text="") + col.itemO("object.material_slot_copy", icon='ICON_COPY_ID', text="") if ob.mode == 'EDIT': row = layout.row(align=True) diff --git a/release/scripts/ui/space_filebrowser.py b/release/scripts/ui/space_filebrowser.py index f1ea5555787..5b0c189464f 100644 --- a/release/scripts/ui/space_filebrowser.py +++ b/release/scripts/ui/space_filebrowser.py @@ -12,11 +12,17 @@ class FILEBROWSER_HT_header(bpy.types.Header): layout.template_header(menus=False) + row = layout.row() + row.itemS() + row = layout.row(align=True) + row.itemO("file.previous", text="", icon='ICON_BACK') + row.itemO("file.next", text="", icon='ICON_FORWARD') row.itemO("file.parent", text="", icon='ICON_FILE_PARENT') row.itemO("file.refresh", text="", icon='ICON_FILE_REFRESH') - row.itemO("file.previous", text="", icon='ICON_PREV_KEYFRAME') - row.itemO("file.next", text="", icon='ICON_NEXT_KEYFRAME') + + row = layout.row() + row.itemS() row = layout.row(align=True) row.itemO("file.directory_new", text="", icon='ICON_NEWFOLDER') @@ -24,8 +30,8 @@ class FILEBROWSER_HT_header(bpy.types.Header): layout.itemR(params, "display", expand=True, text="") layout.itemR(params, "sort", expand=True, text="") - layout.itemR(params, "hide_dot") - layout.itemR(params, "do_filter") + layout.itemR(params, "hide_dot", text="Hide Invisible") + layout.itemR(params, "do_filter", text="", icon='ICON_FILTER') row = layout.row(align=True) row.itemR(params, "filter_folder", text=""); diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index aef90d818d1..961329ea5d0 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -48,19 +48,19 @@ class INFO_MT_file(bpy.types.Menu): layout = self.layout layout.operator_context = "EXEC_AREA" - layout.itemO("wm.read_homefile", text="New") + layout.itemO("wm.read_homefile", text="New", icon='ICON_NEW') layout.operator_context = "INVOKE_AREA" - layout.itemO("wm.open_mainfile", text="Open...") + layout.itemO("wm.open_mainfile", text="Open...", icon='ICON_FILE_FOLDER') layout.item_menu_enumO("wm.open_recentfile", "file", text="Open Recent") layout.itemO("wm.recover_last_session") layout.itemS() layout.operator_context = "EXEC_AREA" - layout.itemO("wm.save_mainfile", text="Save") + layout.itemO("wm.save_mainfile", text="Save", icon='ICON_FILE_TICK') layout.operator_context = "INVOKE_AREA" layout.itemO("wm.save_as_mainfile", text="Save As...") - layout.itemO("screen.userpref_show", text="User Preferences...") + layout.itemO("screen.userpref_show", text="User Preferences...", icon='ICON_PREFERENCES') layout.itemS() layout.operator_context = "INVOKE_AREA" @@ -78,7 +78,7 @@ class INFO_MT_file(bpy.types.Menu): layout.itemS() layout.operator_context = "EXEC_AREA" - layout.itemO("wm.exit_blender", text="Quit") + layout.itemO("wm.exit_blender", text="Quit", icon='ICON_QUIT') # test for expanding menus @@ -212,7 +212,7 @@ class INFO_MT_help(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.itemO("help.manual", icon='ICON_URL') + layout.itemO("help.manual", icon='ICON_HELP') layout.itemO("help.release_logs", icon='ICON_URL') layout.itemS() diff --git a/source/blender/editors/datafiles/blenderbuttons.c b/source/blender/editors/datafiles/blenderbuttons.c index 8d8cb8af4d6..8b8c349e851 100644 --- a/source/blender/editors/datafiles/blenderbuttons.c +++ b/source/blender/editors/datafiles/blenderbuttons.c @@ -1,5960 +1,6114 @@ -/* DataToC output of file */ +/* DataToC output of file */ -int datatoc_blenderbuttons_size= 190499; +int datatoc_blenderbuttons_size= 195438; char datatoc_blenderbuttons[]= { -137, 80, 78, - 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 88, 0, 0, 2,128, 8, 6, 0, 0, 0, 64, 11, 6,158, 0, 0, - 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 10, 79,105, 67, 67, 80, 80,104,111,116,111, -115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,222,244, 66, - 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193, 17, 69, 69, - 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44, 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,123,163,107, -214,188,247,230,205,254,181,215, 62,231,172,243,157,179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30, 17,224,131, -199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16, 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192, 7,190, 0, - 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,128, 20, 0, - 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38, 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,127,230,211, - 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138, 69, 0, 88, - 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73, 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0, 48, 81,136, -133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,153,178, 60, -185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46, 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,153, 25, 50, -129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,191, 6,255, - 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,238, 4,104, - 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,228,228,216, - 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192, 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,129, 71, 4, -248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185, 88, 42, 20, -227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137, 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53, 0,176,106, - 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16, 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,104,131,225, -207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0, 68,160,129, - 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,128, 28,114, - 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14, 61,112, 15, -250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8, 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248, 33,193, 72, - 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53, 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92, 70,186,145, - 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178, 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,116, 49,154, -143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,108, 48, 46, -198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172, 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4, 18,129, 69, -192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76, 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132, 81,194, 39, - 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50, 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196, 55, 36, 18, -137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,218,100,107, -178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,226, 40, 82, -202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50, 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,182, 82,175, - 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,221,149, 30, - 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103, 25,119, 24, -175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202, 10,149, 74, -149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170, 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,227,169, 9, -212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169, 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,195, 76,195, - 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99, 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,217,124,118, - 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67, 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,116, 78, 9, -231, 40,167,151,243,126,138,222, 20,239, 41,226, 41, 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,171, 81,171, - 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231, 83,217, 83, -221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158, 76,111,167, -222,121,189,231,250, 28,125, 47,253, 84,253,109,250,167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197, 53,113,111, - 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165, 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,140,105,198, - 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33, 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59, 76,199,205, -204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,101, 73,178, -228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165, 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,167,185, 78, -147, 78,171,158,214,103,195,176,241,182,201,182,169,183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,103,183,197, -174,195,238,147,189,147,125,186,125,141,253, 61, 7, 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,222,154,206, -156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103, 23,103,185, -115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,157,155,179, -155,194,237,168,219,175,238, 54,238,105,238,135,220,159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,209, 63, 11, -159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,239, 23, 62, -246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89, 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,127, 35,255, -100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,246,178,217, -237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105, 14,133, 80, -126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,209,220, 67, -115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,198, 46,102, - 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123, 23,152, 47, -200, 93,112,121,161,206,194,244,133,167, 22,169, 46, 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,140, 37,242, - 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209, 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,145,188, 53, -121, 36,197, 51,165, 44,229,185,132, 39,169,144,188, 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189, 49,131,146, -145,144,113, 66,170, 33, 77,147,182,103,234,103,230,102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,201,107,179, -144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158, 43,205,237, -204,179,202,219,144, 55,156,239,159,255,237, 18,194, 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,178, 60,113, -121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,107,129, 94, -193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157, 27, 62, 21, -137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102, -233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,205, 40,219, -187,131,182, 67,185,163,191, 60,184,188,101,167,201,206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181, 97,215,248, -110,209,238, 27,123,188,246, 52,236,213,219, 91,188,247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,251,179,247, - 63,174,137,170,233,248,150,251,109, 93,173, 78,109,113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,210, 61, 84, - 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,247, 9,223, -247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91, 98, 91,186, - 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,242,207,140, -157,149,157,125,126, 46,249,220, 96,219,162,182,123,231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,231, 59,188, - 59,206, 92,242,184,116,242,178,219,229, 19, 87,184, 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,156,187,154, -174,185, 92,107,185,238,122,189,181,123,102,247,233, 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,221,189,243, -122,111,247,197,247,245,223, 22,221,126,114, 39,253,206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,217, 67,221, -135,213, 63, 91,254,220,216,239,220,127,106,192,119,160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67, 5,143,153, -143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,174, 23, 22, - 47,126,248,213,235,215,206,209,152,209,161,151,242,151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201, -120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251, -147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,131, 0, 0, -249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234, 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 2,221, 78, 73, 68, - 65, 84,120,218,236, 93,119,120, 83, 85, 31,126,207,189, 55, 59,105,186, 91,104,203,104,153,101, 79,217, 8,178, 28,108,113,128, - 11, 20, 5, 4, 62, 21,193,130,136,128, 76, 23, 67,100, 56, 89,178,101,136,202, 82,217, 75, 64,100,239, 89, 74,247,110,118,114, -207,247, 71,115, 99, 26,210, 38,133, 50,196,243, 62,207,125,146,187,222,123,246,121,207,239, 44, 66, 41, 5, 3, 3, 3, 3, 3, - 3, 3, 3, 67,217,129, 48,129,197,192,192,192,192,192,192,192, 80,182,224, 74,173,200, 8,161,165,120,182,163,191,156,206,227, -209, 7,157,243, 46,250,157,150, 33,231,163, 78,206,241,255, 18,119, 62,250,160,114, 74,254,245,151,183, 52,156,254,166,169, 82, -186,147,150,181, 59,239, 22,103, 89,229, 35, 47,238,164,119, 33,222,199,255, 75,220,249,232,131,198,233,153,126,252,225, 45, 45, -167, 63,105,234, 54,220, 73,203,218,157,119,139,243, 78,243, 81, 9,238,164,119,154,150,138,137,251,241,248, 15, 64,184, 91,226, -170, 52,160,148, 18, 55,126,242,160,114,186,135,131,196, 95,150,110, 45, 67,108, 47,107, 78,143,240, 44, 43,140,167,148, 18, 66, -200, 14, 0,143,150,165,223,203, 34,222, 61,252, 90, 38,188,165, 21, 87,165,229, 44,171,116,127,183, 57,203, 42, 47,121,114,150, - 69,186,247, 22,239,119, 49,142,202,202,157,101,146,151,238, 70,154,247,146,126,238,152,215,147,179, 44,242,146, 39,103, 89,164, -251,123,193, 89, 22,121,201, 27,103, 89,164,251,226,226,158, 89,176,238,141, 16,240,204,216,237, 30,100, 33,116,183, 68,166,191, - 22,151, 7,129,179,140,227,104,188,147,179, 44, 91, 51,237,202, 42,142,238, 70,122,119,231, 44, 43,126, 79,158,178,136, 39,111, -156,119,234,222, 98,220, 89,230,126,191,211,116,127,175, 56,203, 56,142,202, 36, 47,121,112,182, 43,227, 70, 64, 59,183,243,241, -101,201, 89, 86,121,201,139, 59,239, 56,158,188,113,222,169,123,139,113,103,153,251,189, 44,234,144,187,197,251,208, 89,176,238, -166,184,186, 91,149, 89, 89,114,223, 13, 43,206,221,178,180,149,149, 21,199, 11,239,142, 50,164,219, 94,214,238,116,186,143,220, - 45,107,235,131, 14,150,151, 88, 94,122,208,242,146,183,116, 67, 41, 29, 79, 8,249,240, 65,107, 60,187,115,150,149, 16,242,226, -247, 59,202, 75,158,239,150, 69, 94,242,193, 73,238,134,255,203, 58, 63, 61,136,224, 30, 20,135,248, 59,190,231, 54,248,218, 61, -200, 17,112,151,220,217,238,223,224,247,187,225, 78, 66,200,248,187,228,247,127, 75,152,178,188,196,242,210, 3,151,151, 60,210, -100,187,178,178, 12,149,117, 67,202,147,179, 44,190,225,206, 81, 86,105,244,110,251,189, 44,243,210,221,136,251,127, 11, 74,109, -193,186,219,221, 38, 15, 50,231,221,224,190, 75,126,223,113, 55, 90, 7,119, 97, 92, 87,153,187,147, 82, 58, 30,101,216,229, 40, -249,185, 44,221,122, 55,187, 9,239, 70,218,188,155,233,189, 44,199,121,220, 37,191,255, 91,226,189,204,221, 89, 86,121,201, 75, -156,223,177, 91,189,133, 95, 89,119, 97,151,101,218,188,155,156,101,193,125, 55,220,121,183,226,254,223, 4, 14, 12, 12, 12, 12, - 12, 12, 12, 12, 12,101, 10,182, 14, 22, 3, 3, 3, 3, 3, 3, 3,195,189, 18, 88,209,209,209, 27, 53, 26, 77,213,226, 94, 44, - 40, 40,184,153,148,148,212,158, 5, 33, 3, 3,131,207,130,134, 16, 14,255, 88,204, 69, 0,148,178,214, 29, 3, 3,195, 67,140, - 98,199, 96, 41,149,202,184,211,167, 79, 87, 23, 69, 17, 14,135, 3,118,187,221,245,107,177, 88,208,182,109,219, 82,143,223, 42, - 87,174,220, 78,158,231, 43,151,230, 29,135,195,113, 45, 57, 57,185,117, 9, 5,247, 94, 0,113,132, 16,247,107, 37,254, 2, 72, -178, 90,173,141, 74,226, 36,132,196,121,242, 21,195, 37,253, 47,145, 51, 40, 40,232,144, 32, 8, 49,222,184,138,251, 47,138,226, -165,212,212,212,150, 44,153,222, 27,148, 43, 87,110,167, 32, 8,165, 78,159, 55,111,222, 44, 54,125, 70, 68, 68,252,197,113, 92, -148,175, 52,201,113,133,218,131, 82,202,139,162,120, 54, 41, 41,169,117,113, 2,132,227, 56,159,105,222,243, 63,128, 68,171,213, -218,196, 87, 62,242, 55, 15, 57,127, 75,228,116, 23, 87,130, 32, 76,139,136,136, 24,108, 48, 24, 76, 0, 40,207,243, 52, 52, 52, - 20,132, 16, 23,167,221,110, 79,203,202,202,170,203, 82, 34, 3, 3,195, 67, 45,176, 68, 81,228,204,102, 51,206,157, 59,135, 98, -202,121,199,109,124,175,250,137,223,183, 70,168,195, 35,225,176, 89,161, 12, 13,119,113,103,159, 62, 1,209,106,133,195,106, 65, - 88,147,230, 82,229,133,218,181,107,243, 62, 56, 99,166, 79,159, 30, 17, 16, 16, 0,147,201, 4,147,201, 4,179,217, 12,147,201, - 4,139,197, 2,139,197, 2,171,213, 10,171,213, 10,187,221, 14,179,217,140,109,219,182,249,114,123,204,228,201,147, 35,244,122, -189,139, 79, 58, 36, 78,137,215,102,179,193,100, 50,225,247,223,127, 47,145, 83, 16,132,152,164,164,164, 8,185, 92, 14, 74, 41, - 68, 81, 4,165,180,200,225,137, 42, 85,170, 88, 89, 18,189,167,168,190,111,209,183, 17,202,144, 80,136, 54, 27, 66, 27, 52,150, - 68, 15,146,126,223, 12,135,213, 10,209,102, 67,165,110,189, 93,215,227,227,227, 75, 76,159,148,210, 74,187,191,156, 25, 36, 15, - 8,128,221,100, 66,108,215, 94,174,123, 39,231,207,132,104,179,130,218,172,168,247,206, 88, 0, 64,122,122,186,177,106,213,170, - 73, 40, 28, 8, 74,139, 17, 44, 49, 5, 5, 5, 17,146, 27, 60, 69, 17,199,113, 69,142, 61,123,246,160, 99, 71,159,139, 46,199, -204,158, 61, 59, 66,202, 35,158,233,220,110,183,187,126,237,118, 59, 76, 38, 19, 54,109,218,228,175,229,106,122,167, 78,157, 6, -252,252,243,207,218,117,235,214,105, 43, 87,174, 12,185, 92, 14,158,231,193,243, 60, 56,142,131, 32, 8,104,214,172, 25, 97, 73, -144,129,129,225,161, 23, 88,102,179,249,114,195,134, 13,169,243,127,180, 82,169,148,123, 20,156, 81,213,171, 87, 63,235,249,158, -175,174, 67,117,120, 36,190,139, 13, 1, 0, 60,115, 49,195, 85, 49,172,110,211,192,245, 76,223,171, 57,133,207,170,213, 32, 30, -205,112,111,208,106,181,232,212,169, 19, 20, 10, 5,154, 52,105, 2,153, 76,230,245,144,203,229,144,201,100,254, 84, 10,208,233, -116,152, 48, 97,130, 36,142,160, 85, 41, 49,172,101, 19,168, 64,241,213,137,243,176,136, 20,130, 32,184, 14,127, 56,229,114, 57, -142, 31, 63, 14, 65, 16,192,243,188,235, 87,250,191, 97,195, 6,244,233,211, 7,130, 32, 64,173, 86, 3,255,161,217, 22, 15, 10, - 84,161, 97, 88,221,182, 33, 0,224,133,235,121,174,184,251,245,185,174,174,103, 94,186, 81,224,138, 79,201,242, 84, 28, 56,142, -131, 60, 32, 0,191,244,121, 2, 0,208,251, 92, 42,100, 50, 25, 4, 65,192,177,207, 39, 65,166, 80, 64,144,203, 81,239,157,177, - 72, 79, 79, 55,246,234,213,107,119, 64, 64,192,230,220,220, 92,248, 16,110,184,126,253, 58, 4, 65, 40, 54,189,115, 28,135,133, - 11, 23,226,234,213,171,126,249,221,104, 52, 98,234,212,169, 32,132, 20,201, 47,197,253,247, 83, 92, 77,234,220,185,243,139, 63, -255,252,115, 48, 33, 4,115,230,204,129, 92, 46,199,147, 79, 62,137,208,208, 80,108,217,178, 5,114,185, 28,163, 70,141, 98,137, -143,129,129,161, 36,200, 0, 52, 0, 16,238, 52,240,228, 1, 8,114,187,159,230,252, 13,119, 59,255,211, 11, 79, 83,231, 51,210, -125,233,220, 2, 64,225,229,122, 6, 0,181,243, 48, 3,216, 11,160,142,219,119,164,247,224,249, 93,193, 89, 16, 62, 10, 96, 59, -128,118,210,226,119, 55,111,222,124,194,205,146,114,250,236,217,179, 53, 37,173,227,236, 42,148,219,237,246,234, 82,183,161,212, -242,237,216,177, 99,137, 45,122,135,205,122,139,240,240,166,161,188,117,121, 20, 39, 92,172, 86, 43,158,125,246,217,194, 24, 40, -166,178,113, 63,252,208,108,176, 88, 44, 16, 4, 1, 53, 42,132,227,131, 46, 13,241, 8,181,161, 32,159,192,158, 83,128, 30, 58, - 27, 78,215,106,132, 5,215,210,112, 53, 55, 31,130, 32,248,197, 41,138, 98,177,226,138,231,121,204,155, 55, 15,207, 63,255, 60, -120,158,247,139,143,161,236,225,176, 90,189,166,195,226,210,172, 63,241,100, 55,153, 10,197,150,192,187,196,149, 76, 38,131, 76, -169,132, 32,151, 67, 80,200,145,158,158,110,236,216,177,227,126,133, 66,177, 40, 50, 50, 50, 41, 49, 49,209,167,192, 42,194,229, -165, 49,241,253,247,223, 99,241,226,197,104,214,172,153, 95,249,200, 98,177, 64, 46,151, 99,210,164, 73,183,220,159, 63,127,254, - 45, 2,171, 36, 78,103,195,136,139,138,138, 26,178,105,211, 38,189,244,108, 88, 88, 24,100, 50, 25,234,214,173,139,128,128, 0, -236,222,189, 27, 14,135,195,239,124,201,192,192,240,240,194,155, 22,113, 67,219,209,163, 71, 55,153, 54,109,218,148, 22, 45, 90, - 44,223,187,119,239, 50, 66,200, 70,183, 50,177,171,147, 99,163,219,121, 83, 15,145, 37, 3, 16, 78, 8,217, 40, 61,239,126,238, -118,189, 35, 0,133,116, 62,122,244,232, 58,211,166, 77,155,146,144,144, 48,102,234,212,169,242,209,163, 71,215,155, 54,109,218, - 20,233, 59,222,220,225,110,193, 42,113, 21, 96,169,187,240,204,153, 51,240, 53, 46,213,215,250, 25,202,208,112,151,229,106, 85, -149, 80,215,245,231,175,100,187, 42,174, 95, 30,169, 10,133, 78,139, 38, 31,126,226,151,101,200, 98,177, 32, 53, 53,213,213,242, -246,117,248,203,169, 81,171,176,237,237,186,184,158,161,192,248,125,153,248,249,232, 5,200,100, 50, 60, 94,171, 46,158,144, 7, - 96,108, 37, 5,222, 62,127, 5, 54, 63,199,234, 82, 74,189, 10, 43,233,191,212, 85,194, 4,214,253, 67,104,131,198, 46,203,213, -210, 10, 1,183, 88,173, 0, 96, 67,163,202, 80, 6,232, 80,247,127, 9,126,165,165,216,174,189, 92,150,171,159, 27,199,130,151, -201, 32, 83, 40,240,204,241, 27, 0, 10,187, 5,219,215,141,223,145,205, 43, 22,190,248,226,139,151,255,248,227, 15,181, 47, 78, -169, 49,225, 41,176, 36,241,243,253,247,223, 99,201,146, 37, 16, 4, 1, 86,171,127, 61,205,102,179,185,216,252,225,205,130,229, - 79, 26, 45, 40, 40,176,172, 95,191, 30, 95,124,241, 5, 66, 67, 67,209,185,115,103,148, 47, 95, 30,171, 86,173, 2,165, 20, 67, -135, 14,133, 90,173,150,172,213, 44, 1, 50, 48,252,183, 81,146, 22, 81, 78,155, 54,109,138,187,128,241, 20, 52,238,194,201, 67, - 68,185,139,180, 58, 62,202,215,141,158,162, 73,250, 46, 33,100,227,212,169, 83,187,250,112, 71,154,167,192, 42,113,153,125,179, -217,124,185,126,253,250,126,169, 8,131,193,144,236, 75,100,120,107,249,187, 91, 5,148, 1, 58, 40,117, 58,112,126,174,210,101, -179,217, 92, 2,101,235,214,173, 80,171,213,120,242,201, 39,239,200,130,101,181, 90,161,144,203,192,133, 69,226,229, 25,127, 32, - 35,207,232,170,208,182, 95,186,140, 35, 41,169,120,187, 69, 7,104,213,169,200,183, 88,252,178, 16,136,162,120,139,184, 18, 4, - 1,207, 62,251, 44,204,102, 51, 8, 33, 69,198,165,128,117, 17,222,207,150,148,215,115, 66, 8, 84,250, 0, 40,180, 90,240, 60, -239, 23,151,187,181, 73, 80, 40, 32, 83, 42, 32, 56,133,140,100,185,202,230, 21, 11,111,220,184,177, 31,128,234,145, 71, 30, 81, -251,195,235, 46,176,220, 5,144,187,184,226,121, 30, 54,155,205, 47,255,154,205,102,200,229,255,140, 4,184,118,237, 90,137, 2, -203,135,159, 41, 33, 68, 4, 32,198,197,197,185,222, 45, 87,174, 28,130,130,130, 32,138, 34, 68, 81,132, 74,165,130, 90,173, 46, -242, 93, 6, 6,134,255,116,217, 91,156,214, 48, 38, 36, 36,140, 33,132,108,116, 90,146, 78,148, 32,164,188,161,169,135, 72, 75, - 43,166,236,234,234, 77,100,185,255,151, 48,122,244,232, 58, 94,220,241,231, 45, 2,203, 77, 53,222, 2,247,238,194,178,170,188, - 74,170,192,212,122, 61,228, 90, 45, 56,142,243,185,191,146,212, 69, 40,141, 57, 25, 60,120,112,137,227, 82,252, 29, 47,101,181, - 90,193, 9, 60,110,150,139,133,131,219,245, 79, 5,233, 60, 56, 65,134,171,229,106,130, 63,243, 23,100,162,120, 91, 22,172,161, - 67,135,226,235,175,191,150,252, 9, 66, 8, 4, 65, 64,181,106,213,112,249,242,101,150,211,238, 3, 40,165,197,138,101,233,186, - 42, 32, 0, 10,157, 14,188,159,105,201, 93, 12,201,149, 74, 8, 10, 57, 4,121, 97,183, 96,183,110,221,118,100,103,103, 47,172, - 93,187,246,121, 20, 46, 99,192,249,155,135, 4, 65, 40, 34,124,188,137, 43, 65, 16, 96,183,219,253,110, 84,120, 10,157,201,147, - 39,223,242,220,211, 79, 63,237,111, 67,133,114, 28, 71,229,114, 57, 58,117,234,132,122,245,234, 97,221,186,117, 16, 69, 17,111, -190,249, 38,212,106, 53,102,206,156, 9,187,221,142,233,211,167, 51, 11, 22, 3, 3, 67, 73, 90,196, 60,117,234,212, 19, 83,167, - 78,117, 89,146, 60, 45, 88,197,224, 41,167,152, 10,151,196, 25, 10,199, 82,253, 89,130, 27,186, 22, 39,188,220,175, 77,155, 54, -109,138, 23,119,184,186, 37,239,249,102,207,217,167,142,187, 6, 17,187,119, 11,110,106, 89, 19, 74,157, 22, 74,157, 14,173,214, -237,114,181,154, 1,223,221, 48, 54,155,205, 37,176, 50, 50, 50, 74, 20, 87,165,177, 96,113, 10, 1,171, 99,178, 64, 21, 50, 8, - 22, 91, 17,129,197, 11, 50, 92, 15,141, 5, 39,147, 67,112,248, 87,129, 81, 74,111,233, 18,124,229,149, 87, 64, 8,113,205,248, -170, 95,191,190, 59, 23,171,113,238, 49,146,126,223,236, 26,208,238,222, 45,184,241,145,170, 80, 5,232,160,208,106,209,246,167, -189, 46,107, 35,222,159,236,147,243,236,183, 95,226,248,204, 41,144, 41, 20,232,253,215, 85,151,229,170,101,141,170,251, 45, 90, -253,194,107,215,174,237, 7,192, 61,247,220,115, 65,245,235,215,247,153, 39, 37, 65, 94,146,184,114, 23, 88,254, 90,176,164,134, -138, 63,150, 51,127, 44, 78,148, 82, 26, 18, 18, 2,142,227,160,215,235,161,211,233, 92, 51,104, 85, 42, 21, 52, 26,141,107,252, -166, 63,223,101, 96, 96,248, 79, 35, 88, 18, 56, 78,145, 84,196,178, 68, 41,237,234, 46,130,138,235, 42,116, 90,156,118,250,248, -214,207, 78, 97,230, 21,146, 37,205,163, 12,221,232, 41,206, 4, 73, 49,186,255,150, 47, 95,254, 87,157, 78, 23,235,175,175, 75, -179,232,168,251, 32, 98, 73, 92, 17, 66,160,210,233,160,208,105,161, 12,208, 21,107,229, 42, 73, 96, 73, 21,138, 84,217, 44, 90, -180, 8, 58,157, 14,253,251,247, 47,245, 24, 44,151,192,146,115,216,162,252, 29,188, 66, 40, 34,174, 4, 65, 0, 47,147, 33, 89, - 87, 30,156, 76, 6,193,238,159, 37, 35, 39, 39, 7,130, 32,224,131, 15, 62,112,181,216,221,197, 85,105,252,204,112,119, 32,186, -137,145, 34, 86,213,128, 0, 87,250, 44,205, 0,119, 0,160,118, 27,100, 74, 37,100, 10,185, 75, 92,117,235,214,109,135, 69,171, - 95, 88,179,102, 77,151,229, 74,163,209, 72,179, 71,125,130,227,184, 34,105,122,225,194,133, 69,196,149,167, 5,203, 31, 62,201, -130,245,245,215, 95,151, 40,162,228,114, 57,228,114,185,223,254,231, 56, 14, 59,118,236,192,145, 35, 71, 48,120,240, 96,168,213, -106,204,158, 61, 27,118,187, 29, 31,125,244, 17,212,106, 53, 20, 10, 5, 75,124, 12, 12,204,122, 85,210,190,162,105, 30,227,156, -136,135,165, 41,205,155,176,114,239, 14,116,251,111,243,194,107,241,232, 58,244,188, 46,253,102, 76,157, 58,245, 15,201,114,229, -118,189,136, 59,138,181, 96, 41,149,202,216,115,231,206,185, 22, 25, 45,233,215, 98,177,160,125,251,246,126, 91,194, 68,231, 44, - 66,206, 57,144,219, 53,238, 74,175,131,210,217,245,226, 33, 52,136,175,194, 91,106, 1,187, 11,172, 15, 63,252, 16,130, 32,224, -235,175,191, 6, 0,188,251,238,187,126,143,193,146, 56,225, 32, 72,164, 23,209,112, 70, 31, 88,150,218,144,178,231,111, 8,130, -128,136,230, 79, 64,124,164, 15, 12,106, 29, 4,135,221,239, 89,132,153,153,153,184,124,249, 50,120,158,199, 59,239,188, 83,100, -173, 34,207,153,105, 91,183,110,101, 22,172,251, 40,176, 56,231,248, 42,111,233,211, 67, 92, 17, 95,194,154, 58,236,133,227,174, -228,255,204, 22,204,206,206, 94,120,237,218,181, 3, 0,184, 23, 95,124, 49, 72,163,209,224,219,111,191, 53, 0, 80,172, 90,181, -202,231, 32,119, 41,221, 20, 39,174,110,167,139, 80,178, 4,187,143,235, 42, 73, 96,249, 3,201,173,132, 16, 56, 28, 14,168,213, -234, 34,150, 43,149, 74, 5,165, 82,201, 18, 30, 3, 3,131, 47,252, 89,138,103,155,186,137,165, 63,111,147,247,207, 59,117,176, - 80,156,192, 48,155,205, 56,117,234,148,191, 60,126, 47, 58, 26,218,184, 25,250, 94,205, 1, 33, 4, 91,218,212,118,117,187,180, - 92,179,195, 85, 9, 92,157,250, 46,100, 90, 29, 66,219,116,246,171, 0,151, 42, 6,119,129,149,157,157, 13,153, 76,134, 73,147, - 38,129,227, 56, 76,159, 62, 29,209,209,209,184,121,243, 38, 86,173, 90,229,151, 5,139,119,240, 40,255, 82, 60, 52,175, 4, 66, -255, 82, 91, 4,119,250, 16, 55, 44, 2,246,154, 52,104,107, 58, 9,197,150, 89,176,136, 14,191,198,117, 1,128,221,110,199,142, - 29, 59, 60, 7,178,131, 82,234, 90, 37,223,102,179,193,106,181, 98,250,244,233, 96, 59,137,220,123, 84,120,170, 39, 94, 78, 50, - 0, 0,126,117,235,182,110,189,118,151, 43,125, 94,158,252, 14,100, 90, 29,130,155,182,241,139,179,214,155, 35, 81,235,205,145, - 72, 79, 79, 55,118,104, 80,123,103,190, 92,243,125,221,186,117,139, 88,174, 84, 42, 21,113,158,251, 37,170, 57,142, 3,207,243, - 46,113, 37,137, 41,111, 2,203,223,113,135, 54,155, 13,114,185,220,111,129, 85, 26, 11,214,171,175,190,138,242,229,203,187, 44, - 87, 19, 39, 78,132, 90,173,198,232,209,163, 97,179,217, 48,107,214, 44,150,248, 24, 24, 24,238,135, 24,187,107,240, 90,242,154, - 76,166, 43,245,234,213, 67, 49,247,162, 85, 42,149,204,163,112,142,170, 94,189,250, 89,207,174, 66, 66, 72, 71, 74,233, 54,111, -133,185,251,108, 44,165,135,213, 74, 30,160,135, 76,171, 3,231,165, 59,207, 27,167,180,142,142,187,192,146,142,156,156, 28,200, -100, 50,124,241,197, 23,208,235,245, 48,155,205, 62, 57, 9, 33,176,219,237,224,121, 30,134,235,121, 56, 61,101, 27, 20,170,189, -168,218,249,121,148,151,169, 33,223,253, 35,140, 14, 91,137, 11,141,122,227,172, 94,189, 58,198,141, 27,119,203,242, 12,197, 33, - 58, 58,218,167,223,239, 20,140,211, 59,167, 63,233,147, 87, 42,189, 77,214,184, 37,222,129,127,102, 11,230,203, 53,223, 95,190, -124, 89,178, 92, 5,106, 52, 26,204,159, 63,223, 0,128,251,232,163,143, 52,149, 42, 85,226,253, 73, 75, 60,207, 99,209,162, 69, -183, 12,104,247, 38,174,188, 45,251,225,205,239,118,187,253, 22,129,245,236,179,207,222, 50,123,176, 56, 11,150, 55, 78,201,173, -161,161,161, 46,203,149,195,225,112,205, 30,180,217,108,176,219,237,197, 54, 38, 88,250,100,156,140,243,191,195,249,176,193,107, -237,158,148,148,244,120,113, 47, 84,173, 90,245,220,185,115,231,170, 57, 28, 14,247, 61, 10,229, 38,147,169,122,203,150, 45,125, - 54,149, 69, 81,132, 82,169, 4,165, 20, 13,199, 78, 3, 33,183,142,183, 10,106,217, 1, 68, 16,224,112, 56, 96,177, 88,124,206, - 34, 52, 26,141,174,202,164,184, 1,238,249,249,249,174,117,126, 56, 63,214,127, 48,153, 76, 69, 42, 42, 66, 69, 92,253,109,229, - 45,179, 9,165,195,223,214,188, 74,165, 42,210,197, 83, 18,124,173, 41,198, 80,246,144,150, 84,160,148,162,246,176,247, 10,227, -201,217, 93, 40,137,128,192, 38,109, 64,100, 2, 68, 0,102,179,217,151,153,145, 72, 99,174, 40,165,223,245,232,209,227, 44, 10, -103,176, 80,157, 78,167,148,201,100, 34,128, 76, 0, 52, 43, 43, 43,240,198,141, 27,162,201,100,170,232,203,157, 59,118,236,192, -133, 11, 23,208,184,113, 99,215,150, 77, 82,183,155, 36, 98,220, 5,150,191, 22, 44,111,107,106, 21,183,154,187,191,105,158,231, -121, 4, 6, 6,186, 22, 49,149,203,229,208,104, 52, 0,128, 89,179,102,185,194,156,129,129,129,225,161, 23, 88,190,202,203, 18, -186, 15, 75,236, 42,180,219,237,137,149, 42, 85, 42,213,199, 28, 14, 71,138, 15,193,150,184,106,213, 42,185,187,181,192,215, 47, -165, 52,197, 71, 37,155,184, 97,195, 6,185,167, 21,162,184,255,132, 16,159,156, 14,135, 35,177,114,229,202, 94,121,138,131,205, -102,187,193,146,232,189,131,195,225, 72,172, 88,177, 56,109,243,214,109,165, 79,187,221,126, 62, 54, 54, 54, 41, 40, 40,232,231, -200,200,200,140, 61,123,246,132, 54,109,218, 52,212,253,153,166, 77,155,150,247,120,205,130, 98,246, 33,148,210,124,151, 46, 93, -188,166,121,111,105, 83, 74,211,190,210,252,111,191,253,230, 87, 62,146,254,139,162,152,232,135, 96,189,218,176, 97, 67,206,157, -163,184,180,111,179,217,210, 88, 42,100, 96, 96,248,207, 10, 44,163,209,120,189, 94,189,122,246, 98,238, 93, 43,233,221,244,244, -244, 38,101,237, 1,171,213,218,242,223,192,153,150,150,214,132, 37,183, 7, 27,119, 35,142, 82, 82, 82, 30,249, 55,164, 79,139, -197,210,242,110,132,105, 70, 70, 70, 11,150,178, 24, 24, 24,152,192,242, 3,254, 46,199,192,192,192,192,192,192,192,192,240, 95, - 5,199,130,128,129,129,129,129,129,129,129,161,108, 65, 80,184,107,244, 45, 40,205,236, 0, 66, 72,199,210,126,216, 23, 63,227, -100,156,140,147,113, 50, 78,198,201, 56, 31, 62, 78, 95,220, 15,205,236, 68, 74,233, 93, 59, 0,116,100,156,140,147,113, 50, 78, -198,201, 56, 25, 39,227,252,175, 29,172,139,144,129,129,129,129,129,129,129,161,140, 33,176, 32,184, 63, 32,132,240,148, 82, 71, - 25, 82, 6, 3, 40,110, 67, 55, 11,128,172,219,113, 38, 0,185,243,144, 22, 42,178, 1,176, 58, 15, 63,150,154,159,192, 37, 37, - 5,215,161, 14, 89, 83, 74,136, 76, 20,113,180, 98,197, 10,127, 1,143, 91, 0, 64, 87,174, 86, 45,157, 86,221,209,108,181,196, - 42,101,138, 83,217, 5,249, 91, 77, 41,103,175,176, 20,194,192,112, 95,202,165,110, 0, 38, 56,243,254, 84, 74,233, 74, 22, 42, - 12, 12,101, 44,176, 2, 2, 2, 14,113, 28, 23,227,190,102,141,180, 48,102,113,235,226, 56, 28,142,196,204,204,204, 38,126,102, -100, 1,192, 51, 58,157,174,189, 76, 38,107, 5, 0, 54,155,109, 79,126,126,254, 31, 0, 86, 81, 74,237,183, 89, 64,232, 1, 60, - 11,160,159,243,210, 15, 0, 86, 82, 74,115,111,147,175, 94, 96, 96,224, 26,153, 76, 70,211,211,211,155, 3, 64,104,104,232,126, -155,205, 70,114,115,115,159,166,148, 30, 43, 37, 31, 39,151,203,167,181,105,211,166, 53, 33,100, 49,165,116, 94, 25,197,165,146, -227, 56,175,194, 68, 20,197,202,183,193, 39, 7, 16,248,197, 23, 95,132, 46, 89,178,164, 97, 98, 98, 98, 93, 0,136,137,137, 57, -254,226,139, 47,254, 53,108,216,176, 12, 0, 57, 78,161, 85, 44,146,146,130,235,164, 38, 95, 26,156,146,122,234, 89, 0, 40, 87, -190,238, 74,158,231,228,209,209, 71,246,105,194,250,133,213,168, 89,101,208,242,111,191,144, 87,142,173,128,223,247, 30,105, 48, -236,127, 99,234,168, 34,107,124,198, 68,214,189,131, 94,175, 63,196,113, 92, 76, 73,121,220, 91,158,119, 56, 28,137, 25, 25, 25, - 77,138,227, 20, 4, 33,166,164,242,194,219, 53, 81, 20, 47,165,165,165,121, 93, 50, 34, 48, 48,112,159, 32, 8,177,254,114, 73, -191,118,187, 61,177,184, 37, 98, 2, 3, 3, 15,241, 60, 31,227,107,205, 47,207, 95, 81, 20, 47,165,166,166, 22,231,206, 91,252, - 94, 22,238,188, 29,206,146,220, 41,149, 71, 0,102,133,134,134, 54,203,200,200,120, 1,192,152,220,220,220,250, 60,207, 35, 36, - 36,100, 12, 33,228, 66, 96, 96,224, 55, 57, 57, 57,123, 1,252,143, 82, 42,178, 28,195,192,112,135, 2,139,227,184,152, 27, 55, -110, 68,104,181, 90, 0,255,236,151, 39,109,242, 44,138, 34, 40,165,174, 95,187,221,142,248,248,120,127, 69, 70, 93,189, 94,191, -122,244,232,209, 21,159,121,230, 25,133,180, 37, 76, 82, 82, 82,245, 53,107,214,188, 48,105,210,164, 15, 9, 33,125, 40,165,199, -253, 21, 45, 0, 58, 0,120,165, 97,195,134,189, 39, 78,156, 40,127,236,177,199,224,112, 56,240,203, 47,191,180,249,232,163,143, -190, 32,132,252, 8, 96, 33,128,223,252, 45, 36, 8, 33,173,203,149, 43,183,108,247,238,221,229, 47, 95,190,236,120,230,153,103, - 86, 0,192,161, 67,135,226, 28, 14, 7,105,222,188,249,207,132,144,190,148,210,221,165, 8,243, 30,195,134, 13,235, 51,116,232, -208,240,254,253,251,191, 4, 96,158,243, 91,210, 46,226,165,221,128,208,101,185,162,148,150,180, 3,111,185, 82, 88,178,180,151, - 47, 95, 14,110,217,178,229,144,212,212,212,183,221,121, 83, 82, 82,112,248,240, 97,235,148, 41, 83,102,236,221,187,119,110,108, -108,108, 22,128,130,226,136,168, 67,214, 52, 37,245,212,179,109, 91,124, 17, 8, 0,171, 54, 12,121,254,224, 95,105, 1, 27, 55, - 45,120, 65,161,146,155,151,124, 53, 67, 94,173,106,101,108, 63,116, 30, 7, 78,101,146,186,173,187, 10, 57, 27, 23,119, 2,176, -128,101,207,123, 3,158,231,163, 19, 19, 19, 35, 52, 26,141,215, 13,221, 61,198, 93, 72, 11,235,162,122,245,234,197, 23, 44,130, - 16,115,227,198,141, 8,149, 74,229, 42, 59, 60,203, 12,169, 92,113,165, 21, 74, 81,163, 70, 13,107, 9,101, 82,165,107,215,174, - 69,104, 52, 26, 23,143, 55,247,121, 10,141, 26, 53,106,148,228,247, 34,238,244,135,147, 82,138,106,213,170, 57,124,249, 93,218, -177,194,151,191, 37,206,216,216, 88, 90, 26, 78,127,220, 89,165, 74, 21,171,143,232,159,117,246,236,217,161, 21, 42, 84, 64,181, -106,213,246, 54,107,214, 76,175,213,106,177,105,211, 38,212,170, 85,171,142, 94,175, 63,176,106,213, 42,217,168, 81,163, 26,124, -255,253,247, 0, 48,140,229, 24, 6,134, 59, 20, 88,132, 16,104,181, 90,172, 88,177,194,181, 61,140,180, 77,134,183,255,197,175, -128,125, 11,111,147,216,216,216, 29,187,119,239, 86,151, 47,255,207, 2,214, 22,139, 5,193,193,193,120,243,205, 55, 21,221,186, -117,171,214,185,115,231,253,132,144, 71, 41,165,135,124,240,245, 14, 15, 15,159,243,193, 7, 31, 68, 62,247,220,115, 8, 13, 45, -178, 72, 54,158,121,230, 25, 60,253,244,211,242,179,103,207, 62,191,104,209,162,231,231,205,155,151, 76, 8, 25, 70, 41,253,177, - 36, 94,141, 70,211,163,106,213,170,243,119,239,222, 29, 17, 17, 17,129,184,184, 56,110,212,168, 81,213,170, 87,175,174,142,137, -137,225,110,222,188,137,117,235,214, 69,247,237,219,119,181, 66,161, 24,100,177, 88,214,251,225,119, 69, 72, 72,200,200, 55,222, -120, 35, 52, 55, 55,215,126,228,200,145,243,210,117,165, 82, 57,174,121,243,230,141, 8, 33, 43, 40,165, 11,111,199,114,229,180, -210,121,238, 57, 98,147,238,251,105,201, 82, 28, 61,122, 52,164, 69,139, 22, 63,154,205,230, 70,131, 7, 15,190, 54,101,202, 20, -181, 94,175,215, 3, 32,185,185,185, 89, 19, 38, 76,176,204,156, 57,243,189, 90,181,106,117,216,183,111, 95,239, 6, 13, 26,216, -156,226,237, 86,129, 69,136,203, 61,215,111,164, 97,199, 94, 81, 49,110,244,187, 49, 31, 79,142,189,250,231,201,235,162,160,214, -227,167,157, 39,144,146,145,143, 95,247,157, 68,185,208, 0, 34, 87,202,234, 4,197,212,121, 52,231,198,201,157,148,237,120,125, -215, 65, 8,129, 70,163,193, 79, 63,253,116,203, 22, 83,222,182,159, 18, 4, 1, 65, 65, 65, 62,119, 35, 80,169, 84,216,186,117, -107,145,237,165,188,253,151,126, 3, 3, 3,129, 18, 54,187, 38,132, 64,165, 82, 97,207,158, 61,224, 56,238,150,247, 61,221, 44, - 8, 2,180, 90, 45,184, 18,246,164,146, 56,119,238,220,233,147, 75,250,213,233,116, 0, 80,226,254, 67, 74,165, 18,187,119,239, - 46,214,207,158,255,117,206,253, 46,125,113,238,217,179,167,200, 22, 93,158, 91,119,185,159,107,181, 90, 87,195,173,216,214, 89, -112,112,243,152,152, 24, 28, 60,120, 16,171, 86,173, 10,169, 83,167, 14,206,159, 63, 15, 66, 8,166, 76,153, 66,106,215,174, 45, - 75, 78, 78, 70,155, 54,109,176,118,237,218,150, 44,183, 48,220, 71,200, 0, 52, 0, 16,142,194, 93, 99,242, 0, 4, 57,235, 30, - 5,128, 12, 0,106,231, 97, 6,144, 15, 32,204,249,110,186,179,108,113, 23, 8,105, 40,186, 41,116, 83, 39,183,180,163, 68,184, -219, 61,233, 27,158,231,158,191, 69,184, 5,103, 33, 35, 85, 98,237, 40,165, 59,138,248,200, 15,113, 37,237, 35,230,153,151,189, -108,252,170,212,106,181,107,246,239,223,175, 14, 15,255,199,237,102,179, 25,121,121,121,200,207,207, 71, 94, 94, 30, 2, 2, 2, -176,106,213, 42,117,135, 14, 29,214, 16, 66,170, 83, 74,205,197,113, 2,152,113,243,230,205, 72,187,221, 14,133, 66, 81, 92,203, - 23,241,241,241, 24, 51,102, 12,186,116,233, 82,174,125,251,246, 51, 0,252, 88, 2, 39, 52, 26,205,252,195,135, 15, 71,104, 52, - 26,156, 59,119, 14,137,137,137, 24, 49, 98, 68, 5, 81, 20,113,253,250,117,156, 63,127, 30, 55,110,220,192,162, 69,139, 34,122, -246,236, 57, 31,192,250,146,252,238,196,192,119,222,121,167,122, 72, 72, 8,247,201, 39,159,228,228,231,231,127,229,188, 62,122, -214,172, 89,125,219,182,109, 27,254,218,107,175,129, 16,178,156, 82,122,139, 96,241,224,244,102,185,114, 0, 56,237,241, 90,188, -135,101,171,156, 51,241,101,123,225, 36, 0, 2, 59,119,238,252,142,217,108,110,180,123,247,238, 11,173, 90,181,170, 4,224,166, -148,232, 2, 3, 3,181, 51,102,204,136,236,218,181,235,217,199, 30,123,172, 81,231,206,157,223, 73, 75, 75,155,226,188, 79, 61, - 57, 69, 17, 71,203,149,175,187,114,231,190, 97,207,110,223, 99,145,191,251,191, 15,175, 85,172, 80, 57,231,232,185, 76,199,201, - 75,105,200, 51,218,209,235,177,194,141,197,155,215,173,136, 57, 43,118,227,205,183,222,151,253,184,114,241,211, 23, 40,180, 0, -126, 46, 33, 60,239, 8,140,243, 31,145, 33,138, 34,100, 50, 25,158,120,226, 9, 16, 66,110,217,107, 83, 38,147, 97,223,190,125, -120,236,177,199, 32,147,201,240,234,171,175,250,197, 41, 8, 2, 58,119,238, 12,187,221,126, 11,159,167, 88,240,166, 5, 60,253, - 78, 41,133, 32, 8,224, 56,206,171,248,241,182, 71,168,175,114, 73,114,103, 73, 92,238,247,124,185, 83,178, 30,249, 43,174,252, -229,148,220, 41, 8, 2, 90,182,108,137,191,254,250,171, 68,177,229, 77, 87,122,250, 61, 43, 43,235,229,234,213,171,239,252,226, -139, 47, 66, 0, 32, 35, 35,195,181, 17, 61,207,243, 56,115,230, 12, 44, 22, 11,198,143, 31,111,205,205,205,125,141,229, 35,198, -121, 55, 57, 75,210, 34, 0,218,142, 30, 61,186,201,180,105,211,166,180,104,209, 98,249,222,189,123,151, 17, 66, 54, 82, 74,187, - 74,191,163, 71,143,174, 51,109,218,180, 41, 9, 9, 9, 99,166, 78,157,122,130, 16,178, 17, 0, 60,207,157,238,239,234, 33,222, -194, 37, 30,167, 91,138, 60,235,237,220,243,215,147, 91,112,187, 64,156,158, 35,238,133,153,191, 2,203,159,189,245, 4, 65, 24, - 58,101,202,148,200,146,196, 85,126,126, 62,146,146,146, 80,169, 82, 37,188,250,234,171,145, 95,124,241,197, 80, 0,159,150, 64, - 43,231,121, 30, 7, 15, 30, 68,106,106, 42,234,213,171,135,216,216,216, 34, 15, 92,188,120, 17,191,252,242, 11,178,179,179,209, -184,113, 99,160,112,124,145, 87, 52,104,208, 96,124,124,124,124,231,206,157, 59,219,213,106, 53,142, 30, 61,138, 70,141, 26, 97, -197,138, 21,168, 88,177, 34, 52, 26, 13,206,158, 61,139,122,245,234, 97,199,142, 29, 8, 15, 15, 71,195,134, 13,237,141, 27, 55, -222,149,153,153,249,199,149, 43, 87,198, 23,147,112,228,209,209,209, 99,222,120,227, 13, 69, 82, 82,146,184,104,209,162,189,148, -210,189,132,144, 65,239,191,255,254, 75, 93,186,116, 9, 63,114,228, 72,238,159,127,254,249,167, 55,113,229,167,229,202,238, 89, - 25, 57, 28, 14,179,209,104,180,152,205,102, 27,199,113, 87, 8, 33, 22,135,195, 81, 92,223,142,234,149, 87, 94,169,146,158,158, -254,230, 91,111,189,117,217, 41,174,206,160,112, 96, 59, 0,192,110,183,155,243,243,243,115, 91,180,104, 81,169,111,223,190, 23, -150, 45, 91,246,230, 43,175,188,178,106,225,194,133,249, 0,140,158,132, 21, 43, 86,248,139,231, 57,121, 65, 94,200,165,213,171, -190,121,251,151, 13, 67, 43, 92,191,126,163, 90,104, 88,120,129, 92, 23,158,180,234,135,239, 15, 1,176, 36,165,229,226,216,197, -100,200,100, 60, 78, 93,207, 65,219,199,159,145, 93, 56, 55,185,181, 36,176, 24,238, 42,168,180, 57,244,246,237,219, 75,180, 96, -237,219,183, 15, 50,153, 12,106,181, 26, 51,103,206, 44,145, 84, 18, 4,146,117,200,151,136,225, 56,174,196,114, 68, 18, 25,210, - 6,236,158,199,151, 95,126,137,183,222,122,171,200, 55,156, 34,131,248,226, 44,206,125,149, 42, 87, 70,106, 74, 74,145,107,254, -108, 22,239,112, 56, 32,147,201,240,245,215, 95,163,107,215,174,216,184,113, 99,137,191, 79, 60,241, 4, 56,142,163,254,132,103, -203,150, 45, 97,181, 90, 93,110, 62,115,230,140, 87,222,121,243,230,249,170,204,186, 1,152,208,168, 81, 35,125,251,246,237,177, -115,231, 78, 60,253,244,211,102,171,213,122, 14, 0,158,122,234,169, 26, 95,124,241,133,226,240,225,195, 8, 13, 13,149, 93,187, -118,237, 59, 66, 8, 27,248,206,112,119, 11, 35, 47, 90, 68,170,243,166, 77,155, 54,197, 67, 24, 21,129,116,159, 16,178,113,234, -212,169, 93,221,197,144,251,185,155,149,201, 93,188,213,113,183, 64,185,139,167, 98, 68,153,167,187,221,159, 79, 43, 34,176,156, - 30,106,231,110,245,145, 10, 93, 95,226,170,184,150,162, 39, 2, 3, 3,159,236,213,171,151, 75,220,152, 76, 38,151,176,146,196, -149,116,126,246,236, 89, 52,105,210, 68, 30, 24, 24,248,164, 15,129, 37,137, 55, 68, 69, 69, 33, 61, 61, 29,199,143, 31, 71,165, - 74,149, 96,179,217,176,121,243,102,228,228,228, 64, 38,147, 65, 46,151,195,106, 45,121, 72, 66,124,124,252, 19, 75,150, 44,105, -178,120,241,226, 44,169, 5,247,195, 15, 63,128, 82,138,240,240,112, 24, 12, 6,164,164,164,224,143, 63,254,128,221,110,135, 78, -167, 67, 92, 92,156,162, 71,143, 30,173, 39, 76,152, 32, 3, 48,190, 24,234,102, 79, 63,253,180, 94,175,215,227,127,255,251, 31, -181, 90,173,159, 18, 66,154,247,238,221,123,204,176, 97,195, 66,174, 92,185, 98, 25, 56,112,224, 33,171,213, 58,195, 25, 31, 50, - 74,169,205, 71, 66, 44,214,114,101,179,217,164, 48,189,156,159,159,143,176,176,176, 74, 62,198,104, 1,128,124,207,158, 61, 45, - 1,240, 31,125,244,145, 10, 64,138,187,184,178, 88, 44,200,207,207, 71, 65, 65,129, 45, 39, 39, 39,117,228,200,145,246,101,203, -150,241,206,119, 78,121, 19, 88,192,227,150,218,181,181, 10, 74,249,247, 23, 44, 88,160,235,210,165, 11,167,211,233,144,151,151, -167,255,117,211, 38, 93,135,246,173,227,166, 76,251,120,139, 62,166, 94,202,158,163,151,112, 35, 57, 7, 22,155, 13,113,229, 3, - 11,237, 95, 12,119, 29,206, 9, 42, 46, 11,150,187,152,216,185,115, 39, 30,127,252,113, 87, 94,151,203,229, 69, 44, 93,190, 56, - 5, 65,192,227,143, 63,126,139, 69,103,251,246,237, 94,173, 77,190,224, 46,134, 60, 69,145, 55,225,197,113, 28,124,245, 50, 75, -214, 59,111, 34,203,221,138,239, 33,218,124, 85, 18, 16, 4, 1,195,134, 13,131, 76, 38,195,168, 81,163, 32, 8, 2, 26, 54,108, - 8, 65, 16,208,162, 69, 11,200,100, 50, 60,246,216, 99,165,246,251,254,253,251,209,168, 81, 35,151,155, 26, 54,108,136,166, 77, -155, 66, 16, 4,180,105,211, 6, 50,153, 12,157, 59,119,246,135,115, 76, 94, 94, 94,125,157, 78,135,179,103,207,130,231,121, 16, - 66,206, 83, 74,235, 3,192, 27,111,188,113,193, 96, 48, 84, 49,153, 76,120,227,141, 55,136,197, 98,169, 55,106,212,168,247, 1, - 48,129,197,112, 55,203,163, 34, 90,196, 13,198,132,132,132, 49,132,144,141,146, 69,202,211,210,228,237,220, 11,191, 36,130,164, -238,193,166, 30,226, 77,234, 58,124,170,132,119, 45, 30,130,202,179,139,240, 79,159, 22, 44,169,208,245, 87, 96,249,130,201,100, -106, 16, 17, 17, 81,172,184,114,255,181, 88, 44,136,141,141,133,201,100,106, 80,218,202,162,124,249,242,176, 90,173,248,230,155, -111, 32,151,203, 33,151,255,163, 43, 44,150,146,141, 67, 39, 79,158,188,188,127,255,254, 70,141, 27, 55, 14, 94,187,118,109,218, -163,143, 62, 26,222,165, 75, 23,168,213,106, 24,141, 70,216,108, 54, 52,111,222, 28,241,241,241, 72, 76, 76,196,175,191,254,154, - 94,189,122,245,176, 3, 7, 14,136,201,201,201, 87, 75,160,238,208,161, 67, 7, 16, 66,240,235,175,191,102, 80, 74, 15,171,213, -234,181, 83,166, 76, 9,178, 88, 44,226, 75, 47,189,116, 61, 51, 51,115, 36, 0,155, 82,169,252,180, 75,151, 46,205,120,158, 95, -225,112, 56,230,148, 54,129,122,134,109, 65, 65, 1, 84, 42,149, 63, 75, 66,200, 50, 51, 51,235, 2,128, 86,171, 13, 1,112,193, -149,178,141,198, 34, 34,216, 98,177,152, 66, 66, 66,180, 0,224,124, 71, 86, 76,124,132,107, 52,154,213, 87,175, 94, 10,112, 31, - 31, 23, 20, 20,132,126,125,251,114,173, 90,182, 84,212,111,208,160,243,216,207, 22,175,136, 10,213, 91,226,162, 66, 97,115,216, -176,109,203,102,145,138,182, 45,172,184,185, 55, 2, 75, 18, 25,158, 22, 44,153, 76,134, 29, 59,118,220,114, 77, 46,151,227,171, -175,190,242, 75, 16, 72, 98,170,184, 46, 50,143, 46, 45,226, 75,184,200,100, 50,240, 60,143,175,191,254, 26,162, 40,226,237,183, -223, 46,210,109,232,206,239,103,139,217,245, 78,252,135, 34, 0, 11, 18, 63, 87,186,222,247,116,175, 84, 94,250, 99, 21,251,226, -139, 47,252,178, 96, 61,245,212, 83, 62, 5,171,123,143,130,187,187,254,250,235, 47,175,188, 11, 22, 44,240, 25,158, 14,135, 3, - 63,255,252,179, 75,156, 74,248,224,131, 15,222,136,137,137,137,220,181,107, 23,146,147,147, 81, 80, 80,128,252,252,124, 52,111, -222, 60,174, 99,199,142, 71,147,147,147,175,156, 60,121,178, 23,203, 61, 12,247,208,130,101,158, 58,117,234,137,169, 83,167,122, -181, 80,121, 90,146, 74,178, 52,185, 9,171, 63,225,236, 26, 76, 72, 72, 24,131,194,225, 51,127,250,241,174,194,179,139,208,171, -225,199, 67, 53, 78,240, 86,232,250,211, 77,232,167,217, 92, 32,132,192,100, 50,121, 21, 86,238,162,192,106,181, 34, 51, 51, 19, - 14,135, 67,184,131,136,186,229,154, 47,129,117,252,248,241,254, 3, 6, 12, 72, 10, 12, 12,172,159,150,150,150, 42,138,226, 99, -251,246,237, 11, 23, 4, 1,122,189, 30,122,189, 30,191,252,242, 11, 52, 26, 13,134, 13, 27,150,234,112, 56,118, 6, 4, 4,132, - 26,141,198,191,147,147,147,199, 22,171, 92,100,178, 14,109,219,182,197,225,195,135,145,157,157,253, 59, 33,164,254,107,175,189, -214,169, 66,133, 10,100,242,228,201,166, 11, 23, 46,124, 9, 32, 77,171,213,126,179,100,201,146, 71, 27, 55,110,172,123,241,197, - 23, 65, 8,249,150, 82,106,242,215,207, 5, 5, 5, 69,132, 85,110,110, 46,242,242,242,160,213,106,237,126,134,153, 12,133, 99, -169,164,241, 84,174,184,113, 90,175,164,248,161,130, 32,208,194, 71,168,172, 56, 62,173, 86,251,209,226,197,139,213,158,147, 15, - 28, 14, 7, 82, 82, 82,160,215,235,241,193,216,177,242,137, 35, 94,107,196,235, 34,247,113, 28,129,197, 74,179,169,104,217, 92, -144,242,220, 46, 86,220,220, 27, 72,130,160,123,247,238,183,116, 11,202,229,114,108,221,186, 21, 61,123,246,116, 53, 88, 26, 55, -110,236,179, 81, 37, 9,130,110,221,186,185, 44, 65,155, 55,111,246,218,189, 39, 89,160,252, 17,130,210,179,195,135, 15,135, 32, - 8,152, 51,103, 14,222,121,231, 29,112, 28,135,207, 63,255, 28, 28,199, 97,220,184,113,126,139, 75,119,225,114,229,227,194,223, -152,119,114,145, 49, 47, 18, 0, 16,160,215, 75, 30, 42, 85,217, 35, 8,130,203,114,213,160, 65, 3,200,100, 50,180,104,209, 2, -130, 32,184, 44, 87, 79, 62,249,164,123, 56, 82,127, 56, 5, 65,192,185,115,231, 92,110,110,209,162, 69, 17,203,149, 32, 8,120, -234,169,167,252,113,230,148,160,160,160, 9,241,241,241,181,102,204,152, 33,227,121, 30, 29, 58,116,168, 49,112,224,192,171,161, -161,161,161, 31,125,244,145,198,203, 59,106, 0,245,107,213,170,165,101,185,134,225, 46, 90,176, 38,120,185, 21,236, 62,166,170, - 20,124, 27,221,159,151, 56, 60, 69,145,211, 34,182,211, 23,151,183,119,139,131, 80, 82,107,172, 52, 2,203,105, 94, 46,241, 99, - 26,141,230, 88,106,106,106, 11,181, 90, 93, 68, 92,121, 19, 90, 60,207, 35, 57, 57, 25, 26,141,230, 88, 89, 70,158,175, 46, 66, -167,152, 25,225, 22,160, 29,159,124,242,201,133, 91,183,110, 45,191,109,219, 54, 28, 56,112, 0,225,225,225,248,226,139, 47,110, -166,164,164,244,167,148,110,245,231,187, 85,170, 84,169,173,213,106,177,119,239, 94, 0,216, 5,224,149, 55,223,124,147,216,237, -118,204,157, 59,215, 0, 96,107, 96, 96,224,143,107,214,172,105, 80,175, 94, 61,197,182,109,219,242, 14, 28, 56,176,221, 79,113, -229, 16, 69,241, 22, 97,229, 30,166, 1, 1, 1,254, 88,176,108,129,129,129,199,115,115,115,159, 49, 26,141,185, 74,165, 50, 32, - 55, 55,215,236, 46,172, 36,126, 65, 16,100,231,206,157, 75, 2, 16, 23, 24, 24,120, 28,110, 93,137, 69, 18,152, 32,116,232,208, -161,131,224, 25, 7, 41, 41, 41, 72, 78, 78,134,213,106, 69,227,198,141, 9, 79,108,124,230,181,191,223, 96,197,203,253, 41,208, -164,188, 46,205,250,243, 54,115,112,243,230,205,174,115,142,227,224,156,182,239, 83, 12,109,221,186,181,196,129,232, 30, 93,132, - 62, 77,225,210,243,115,231,206, 45,220,142,194,105,185,226, 56, 14, 9, 9, 9, 80, 42,149,152, 60,121, 50, 18, 18, 18, 32, 8, -130,207, 46, 66,119,225, 82,121,148,193,189, 81, 84,152, 41,156,227,157, 8, 33,238, 34,139,248, 43,218, 74,178,222,249, 99,249, -119,231,148,222, 83,169, 84,197, 14,112,247,224, 36, 37,248,251, 39, 66,200,165,242,229,203,239,105,209,162, 69,224,161, 67,135, -240,249,231,159,203,205,102,115,197,109,219,182,185,190,235, 45,188, 10, 10, 10,212, 44,231, 48,220, 13,235, 85, 9,183,211, 60, -198, 79, 17,247,238,186, 18,126, 61,159,135,219, 53,119,222, 52,143,122,204,253,186,167,168,242,252,134,251, 51,105,183, 88,176, -124, 21, 18,190,132,150, 63, 22, 44,131,193,240,219,166, 77,155,154,246,237,219, 87, 40,169,123,176,160,160, 0,145,145,145, 56, -113,226,132,221, 96, 48,252,230,135,101,172,204, 4,150,151, 8,223, 86,174, 92, 57,222,102,179,161, 90,181,106,136,142,142,134, -201,100, 66,118,118, 54,239,175,184, 34,132,200,155, 52,105,194, 3, 64, 86, 86, 22, 80, 56,157,180,122,245,234,213,113,248,240, - 97,100,101,101,173, 7,208,113,226,196,137, 13,155, 53,107, 38, 95,177, 98,133, 97,240,224,193,235,109, 54,219,100, 63,173, 15, - 22,187,221, 30,203,113,156, 53, 59, 59,251,134,123,120, 70, 70, 70,134,104,181, 90,146,146,146, 98,243, 71, 96,213,175, 95,255, -224,181,107,215,240,209, 71, 31,165, 77,153, 50,165,122, 94, 94, 94, 86, 78, 78,142,221, 93,100,153, 76, 38, 46, 44, 44, 76, 57, -111,222, 60, 53, 0,212,175, 95,255, 96,113, 2,171,160,160,160,130, 70,243, 79, 67,216,108, 54, 35, 57, 57, 25,201,201,201, 72, - 73, 73, 65, 94, 94, 30,226,226,226, 96, 48, 24, 42,177,226,229,190, 9,172, 34,221,100,238,249,219,189, 2, 47, 77, 94,119, 23, - 46,221,187,119,119,141,221,146, 44, 98,210,177,122,245,106,207,129,227,126, 9,172,185,115,231, 98,248,240,225, 80,169, 84,152, - 49, 99, 70,145, 46, 66, 79, 81, 32,138, 34,241,199,239,177,239, 25,145, 60, 59, 4, 50,153, 12,161,131, 83,138,116,197,121, 17, - 26,126,185,115,202,148, 41,101,210, 69,232,206, 89,169, 82, 97, 86,249,250,235,175,241,204, 51,207, 96,215,174, 93,183,221, 69, - 88,167, 78,157, 31, 54,110,220, 24,120,242,228, 73,228,230,230, 34, 45, 45, 13,102,179, 25,137,137,137,197,246, 2, 56,203,114, - 21,203, 57, 12,247, 24,127,222, 99,222, 59,254,158,224,163,226,246, 91, 96,249, 99,193, 50,155,205, 51,254,247,191,255,189,217, -177, 99,199,144,128,128, 0, 36, 37, 37,221, 34,174,242,243,243,161,211,233, 96, 52, 26,177, 97,195,134, 92,179,217, 60,195,151, - 40,176,217,108,136,136,136, 64,122,122, 58,196, 98,198, 69,115, 28, 7,181, 90,141,252,252,124, 20, 39, 6, 74,170, 40,172, 86, - 43,108, 54, 27,108, 54, 27,172, 86, 43, 74,185, 60,147, 90, 90,176,181,160,160, 0, 0, 10,162,162,162,170,168, 84, 42, 92,190, -124, 25, 0,206, 1,104,223,165, 75, 23, 89, 70, 70, 6, 29, 56,112,224, 62, 74,233, 48, 31,171,217, 91,118,238,220, 25, 11, 0, -106,181,250, 44, 0, 36, 38, 38,218,178,179,179,139, 88, 6, 53, 26, 13,237,217,179,103,121, 74, 41,118,238,220, 25, 43,151,203, - 41,138, 89,179, 10,128,105,253,250,245, 39, 3, 3, 3,151, 77,155, 54,173,111,215,174, 93, 79,212,173, 91, 55,182,160,160, 32, -213,104, 52, 26, 77, 38, 19,229,121, 94, 30, 28, 28,172,218,178,101,203,133,125,251,246,117,212,235,245,203,214,175, 95,127, 18, -128, 87, 75,155, 86,171, 77, 52, 24, 12,149,165, 56,117, 23, 87,201,201,201,160,148,226,210,165, 75,208,104, 52,215, 88,249,113, - 95, 91,142,183, 8, 43,111, 98,203, 95,113,229, 46, 8,182,108,217, 82,226, 26, 88,254,114,186,139,161,119,222,121, 7,179,103, -207,190,197,130, 53,121,114, 97,155,100,236,216,177,126,143,193,146,172, 85,201,179, 67, 80,110,120,102, 17,183, 3, 0,145,220, - 87,202, 37,217, 4, 65,192, 71, 31,125,116,203,224,115,247, 46, 60, 63,187,242,138,184, 51, 53, 53, 21,130, 32, 32, 36, 36, 4, -253,250,245, 67,231,206,157, 93, 93,141,165,229, 61,125,250,244,158,247,222,123,175, 94,157, 58,117, 48,105,210,164,204,160,160, -160,128,215, 95,127, 93,200,206,206, 38, 37, 89,176,152,192, 98, 96,184, 3,129, 37,101, 44,127,103, 17,122, 43, 36, 9, 33, 29, -221,215,202,160,148,230, 16, 66,250,117,234,212,105,237,202,149, 43,213, 85,170, 84,193,233,211,167,145,153,153, 9,139,197, 2, -185, 92,142,242,229,203, 35, 59, 59, 27,223,127,255,189,209, 96, 48,244,163,148,230,148,196, 9,224,253, 38, 77,154,204,255,244, -211, 79, 85, 13, 27, 54, 68,102,102, 38,242,243,243,139,172, 58,173,215,235,161, 86,171,113,240,224, 65,108,222,188,217, 8,224, -125, 31,156,222, 84, 28,172, 86,171, 75,104,249, 18, 88, 30,156, 90,201,138, 99, 48, 24, 0,192, 94,177, 98,197, 72, 0,184,116, -233, 18, 0, 92,141,139,139, 27, 91,181,106, 85,178,100,201, 18, 74, 41,221,230, 77, 92,121,112,102,182,105,211, 38, 11, 64, 57, -139,197, 34, 7,128,156,156, 28,107, 88, 88, 88,132, 82,169, 20,213,106,181,168, 82,169,196,164,164, 36,187,221,110,151, 3, 64, -155, 54,109, 44, 0,146,225, 54,214,195,131, 83, 4,144,187, 96,193,130, 9, 47,190,248, 98,139,150, 45, 91,214, 25, 50,100,200, -241,129, 3, 7,114,209,209,209,193,121,121,121,166,243,231,207,103,125,246,217,103,121,251,247,239,239, 40,147,201,174, 46, 88, -176, 96, 2,128, 92,231,187,183,112,218,237,246,223,182,109,219,214,191,107,215,174,194,141, 27, 55,144,146,146,226, 18, 87, 41, - 41, 41,136,143,143,199,190,125,251, 28, 86,171,117, 91, 41,194,179,172, 44, 55,140,179,176,241, 65,165,188, 94,156,176,146, 26, - 81,254,114,186,139,161,103,158,121,166,136,213, 74, 46,151, 99,205,154, 53, 94,203, 13, 47, 43,146,119,244, 92, 15, 74,114,211, -123,239,189, 87, 68,172,125,240,193, 7,197, 58,205, 87,120, 74, 60, 57, 95, 71, 23,157, 69, 88, 76, 62, 47,201,157, 82,217, 41, -147,201,240,193, 7, 31,248,109,193,130,199, 24, 44,111,156,146,223, 31,125,244, 81, 24, 12, 6,151,128, 45,206,130,229, 43, 60, - 29, 14,199,240,217,179,103, 83,189, 94,223, 44, 55, 55,247,133,107,215,174, 45, 50, 24, 12,143,228,228,228,148,104,193, 50,155, -205, 74,150,143, 24,231,221, 88, 11,235, 63, 33,176,156,149, 35, 42, 84,168, 80,100,111, 43,142,227,138, 28,165, 25, 71,224,204, -176, 91, 8, 33,189, 91,181,106,181,116,248,240,225, 1, 13, 27, 54,148, 85,174, 92, 25, 5, 5, 5,184,124,249, 50, 78,156, 56, - 97, 95,191,126,125,174,193, 96,120,129, 82,186,197, 15,190,197,132,144,205, 93,186,116, 25,215,188,121,243, 65, 31,126,248, 33, - 95,163, 70, 13,228,228,228, 32, 56, 56, 24, 17, 17, 17, 56,115,230, 12, 54,108,216,224, 72, 79, 79,159, 15, 96, 34,165, 52,173, -180, 13,124,171,213,138,231,159,127, 30,162, 40, 98,230,204,153,238, 11,162,249, 3,171,213,106,165, 0, 72,122,122, 58, 0, 24, - 36,193,117,254,252,121, 0,184, 86,185,114,101, 29, 0,108,219,182,141, 0,216,235,175,187,220, 45, 89,241,241,241,151, 61, 11, - 69,201,114, 37, 89,189,224,123,131,102,211,179,207, 62,155,106, 48, 24,186,188,243,206, 59,227,230,206,157,219,119,238,220,185, -183, 60,164,215,235,151,125,254,249,231, 19,159,125,246,217,212,226,172, 87, 78,139,221,216,151, 95,126,249,217, 99,199,142, 5, -168, 84, 42, 20, 20, 20, 32, 35, 35, 3, 86,171, 21,113,113,113, 72, 77, 77,197,226,197,139,243,140, 70,227,120,150, 29,239, 15, -220, 5, 65,113, 86, 44, 95,226,170, 36, 43,206, 79, 63,253,228,117,141,169,210,114,122,138, 12,127,215,166, 42,169, 49, 36, 45, - 47,227,109,233,135,210,148,107,222,120, 5, 65,192, 39,159,124,226, 90,108,213,155,229,170, 52, 22, 44,137, 51, 36, 36, 4, 0, - 32,109,109,244,212, 83, 79,221, 54,175,115,219,176, 97,110,223,152, 50,114,228,200, 9,241,241,241, 53, 0, 40,221,195,128,109, -170,192,192, 80, 70, 2,203,225,112, 36,214,172, 89,179, 72,193,230,107,147, 81,155,205,150,232,103,166,222, 76, 8,137,251,252, -243,207,255,167,213,106, 59, 26, 12,134,122,206, 2,227, 88, 65, 65,193, 54,179,217, 60,171, 52,155, 51, 59, 5,211, 80, 66,200, -204, 46, 93,186, 76,126,236,177,199,250,140, 24, 49,130, 80, 74, 49,111,222, 60,122,241,226,197,213, 0,222,167,148, 94,188,157, - 64, 10, 9, 9, 57,249,253,247,223, 71,174, 93,187, 22, 54,155, 13,179,102,205, 66, 64, 64,192,201,210,184, 79, 16,132,165, 45, - 91,182,236,187,111,223,190,101,148,210,227, 74,165,242,135, 54,109,218,244,219,187,119,239, 74, 74,233, 41, 65, 16,126,104,209, -162, 69,191,131, 7, 15,254, 72, 41,253,187, 20,206,115, 89,178,236,118,239, 61,138,222, 44, 87, 62,144, 59, 96,192, 0,235,128, - 1, 3, 70, 60,251,236,179,223,252,249,231,159,143,100,103,103,215, 3,128,160,160,160, 99, 77,155, 54, 61,184,114,229,202, 51, - 78,203,149,201,151,223, 9, 33, 61,235,213,171,247,227,164, 73,147,180,117,234,212, 17,170, 85,171,134, 43, 87,174,224,248,241, -227,246,239,190,251, 46,223,104, 52,118,167,148,102,177,236,120,255, 4, 22,165, 20, 65, 65, 65, 69, 26, 79,210,212,253,210,118, - 11,186, 87,200,210,150, 58,158,188,197,113,250, 24,228, 10, 0,208,233,116,174, 69, 73,253, 25,154, 32,138, 37,175,167, 70, 41, -117,113, 74,135, 31,226,202,231,140, 63,231, 86, 53,126,115,250,179, 76,131, 86,171,133,205,102,115,241,250, 49,147,147,148, 50, -206,126, 2,240, 83,181,106,213,206, 3,168,202, 68, 21, 3,195, 93, 16, 88,153,153,153, 77,238,230,135,157, 2,106,162,243, 40, - 43,206,139, 0,158, 37,132,124,250,251,239,191, 75,253, 5, 31,249,218,207,208, 23, 78,159, 62,221, 85, 38,147,125,181,108,217, -178,230,148, 82, 4, 6, 6,238,191,114,229,202,235,165,225,176,219,237,131, 8, 33,111, 75,179, 2,205,102,243, 32, 66,200,187, -148,210, 2,183,251,174,243,210,122, 29,128,153, 82, 26, 85,204,125,115, 41,196,149,203,146, 5,192,178,114,229,202,124, 0, 71, -241,207, 58, 87, 54,231, 97,130, 91,183,160,143,120,249,131, 16, 82,237,131, 15, 62,152,194,243,124,135,130,130,130,104,173, 86, -123,221,110,183,255,102, 48, 24,222,167,148,102,176,172,120,255, 96,177, 88,110,212,172, 89, 83,240,214,112, 42,169, 2, 47,169, - 65,229,112, 56, 18,171, 87,175,238,179, 81,230,133,243, 70, 9,233,232,106, 92, 92, 28,231, 47,151, 4,171,213,154, 90,146, 59, -227,226,226, 80, 90, 78, 95,126,143,141,141,245,234,119, 31, 66,240, 70, 9,229,199,109,113,150, 20,158, 37,193,104, 52,102,133, -135,135,231,155, 76, 38,153,217,108,150,217,237,246, 34,230, 70,181, 90,157,198,114, 14, 3,195,109, 10,172,127, 51,156,130,170, - 91, 25,242,153, 1,188, 84, 6, 60, 38,143,243,130,146,206, 75,137,187, 97, 1, 18, 1, 24,202, 40, 12,211, 1, 12,100, 89,238, -193, 67,122,122,122,179,178,230,204,200,200, 40,243, 6, 90, 90, 90, 90,139,187,224,247, 38,255, 85,206,146,112,227,198,141,102, - 44,103, 48, 48,220, 25, 56, 22, 4, 12, 12, 12, 12, 12, 12, 12, 12,101, 11, 2,160,163,183, 27,165,153, 29, 64, 8,233, 88,218, - 15,251,226,103,156,140,147,113, 50, 78,198,201, 56, 25,231,195,199,233,139,251,161,153,157, 72, 41,189,107, 7,128,142,140,147, -113, 50, 78,198,201, 56, 25, 39,227,100,156,255,181,131,117, 17, 50, 48, 48, 48, 48, 48, 48, 48,148, 49,152,192, 98, 96, 96, 96, - 96, 96, 96, 96, 96, 2,139,129,129,129,129,129,129,129,129, 9, 44, 6, 6, 6, 6, 6, 6,134,255, 24, 8, 33,117, 9, 33,245, -254,171,254, 23, 88, 18, 96, 96, 96, 96, 96, 96, 96, 40, 35, 81,165, 4,240, 12, 33,228,205,186,117,235, 54,117,110,200,190,159, - 82, 58, 19,192, 90,111,251,236, 62,180, 97,225,182, 41,242, 14, 0,160,148, 62,202,146, 8, 3, 3, 3, 3, 3, 3, 67, 41,132, - 85,101, 0,131,116, 58,221,107,237,218,181, 11,238,222,189, 59, 66, 67, 67, 97,183,219,113,253,250,117,108,220,184, 17,123,247, -238, 77,178, 88, 44,179, 1,124, 77, 41,205, 46,134,231,161,209, 34,132, 82, 42,109, 92,220,206,233,169, 29, 44,169, 48, 48, 48, - 48, 48, 48, 48,248, 41,174, 18,122,247,238, 61, 57, 50, 50,146,171, 91,183, 46,202,151, 47, 15,179,217, 12,163,209, 8, 74, 41, - 4, 65, 0,165, 20, 57, 57, 57,216,185,115, 39,254,248,227, 15,115, 86, 86,214,247, 0,102, 81, 74,207,185,241, 60, 84, 90,196, - 37,176, 74,187, 41, 40, 3, 3, 3, 3, 3, 3, 3, 3, 33,228,236,233,211,167,171, 59, 28, 14,164,167,167,195,108, 54,195, 96, - 48,184, 4, 22,207,243,160,148,194,110, 47,236, 29, 20, 69, 17,135, 15, 31,198,182,109,219,232,165, 75,151, 62,164,148,126, 36, - 9,172,135, 73,139,176, 65,238, 12, 12, 12, 12, 12, 12, 12,119, 4,139,197,130, 37, 75,150, 32, 61, 61, 29, 21, 42, 84, 64,116, -116, 52,130,130,130,160, 86,171, 1,192, 37,174, 0,128,227, 56, 52,109,218, 20, 67,135, 14, 37, 0,250, 61,172, 97, 34, 13,114, -159,192,198, 96, 49, 48, 48, 48, 48, 48, 48,220, 6,108, 22,139, 5, 77,154, 52,193,229,203,151,113,248,240, 97, 52,106,212, 8, -181,106,213, 66,122,122, 58,146,146,146,138, 60,124,240,224, 65, 28, 57,114, 4,109,219,182,245,228,153,240,208,141,193, 2, 0, - 66,200,163, 78, 79,237, 96,105,133,129,129,129,129,129,129,193, 47, 33, 65, 72,207,168,168,168,239,222,124,243,205,192,230,205, -155, 35, 49, 49, 17, 55,110,220, 64, 86, 86, 22, 26, 54,108,136, 58,117,234,224,226,197,139,216,188,121, 51,142, 28, 57, 2,165, - 82,137,152,152, 24,232,150, 45,199, 87, 4, 39, 41,165,117,220,184, 30, 26, 45,226, 18, 88, 12, 12, 12, 12, 12, 12, 12, 12,183, - 41,178, 2, 0,140,140,139,139,123,119,240,224,193,202,218,181,107, 35, 49, 49, 17,105,105,105,200,202,202,194,254,253,251, 1, - 0,209,209,209,136,142,142,198,153, 51,103,176,103,207,158,220,252,252,252, 1,148,210,181, 15,101,152, 48,129,197,192,192,192, -192,192,192, 80, 70, 66, 43, 2,192,216,218,181,107, 15,122,237,181,215,132, 74,149, 42,225,198,141, 27,248,253,247,223, 81,181, -106, 85, 92,191,126, 29,127,252,241,135, 37, 45, 45,109, 38,128,105,148,210,156,135, 53, 44,184,187, 28,208, 29, 25, 39,227,100, -156,140,147,113, 50, 78,198,249,223,224,164,148,166, 82, 74,135,157, 60,121,178,218, 91,111,189,181,116,210,164, 73,162, 40,138, -136,136,136,192,170, 85,171,196, 21, 43, 86,124,151,150,150, 86,133, 82,154,240, 48,139, 43,128,173,228,206,192,192,192,192,192, -192, 80,198,160,148, 94, 1,240, 34, 33,228,227,195,135, 15,191, 15,128, 2,152, 68, 41, 61,245, 95, 9, 3, 38,176, 24, 24, 24, - 24, 24, 24, 24,238,150,208, 58, 1,224,185,255,162,223,217, 58, 88, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, 48, 48, 48, - 48, 48, 48, 48,129,197,192,192,192,192,192,192,192,240,159, 2, 1, 80,220, 76,128,109,126,147,220,198, 12, 5, 95,252,140,147, -113, 50, 78,198,201, 56, 25, 39,227,124,248, 56,125,113,151, 70,127, 60,208,160,148,250, 60,224, 92, 47,171,180, 7,128,142,183, -243, 30,227,100,156,140,147,113, 50,206,127, 47,167,179,241, 78, 80,216, 75,194, 73,231, 15,178,223,111,167,158,187, 87,126,255, -175,112, 62,108,135,224, 67, 93,186, 2,137, 16, 34, 2, 16,105, 25,172, 76, 74, 8,145, 34,160, 76,248, 24,238,130,105,179, 48, -142,200, 63, 58,156,197, 19, 3, 3, 67,169,202, 14,222,173,146,117, 0,112, 16, 66,240,160,149, 37,101, 89,207,221, 13,191,255, -151, 57,255,237, 16, 74, 10, 40,158,231,183,132,133,133,181, 79, 79, 79, 23,157,215,161, 80, 40,192,113, 28,100, 50,153, 49, 47, - 47, 79,127, 27,145,240,109,100,100,228, 43, 25, 25, 25, 34,199,113, 80,169, 84, 32,132,184, 56,179,179,179,245,247, 59, 80, 42, - 87,174,156,101, 52, 26,117,158,215, 85, 42,149,233,234,213,171, 1,255,133, 2, 82, 46,151,247, 14, 9, 9, 9, 74, 75, 75,163, - 28,199, 65, 46,151,131,231,121, 56,255,219,179,179,179, 23,250,203, 23, 18, 18,114, 48, 36, 36, 36, 72,122,159, 16,130,140,140, -140,236,148,148,148, 71, 0, 64,173, 86,239,209,106,181,161,130, 32,128,231,121,240, 60, 15,131,193,144,145,158,158,222,138, 85, - 87,255, 78,172, 94,189,154,239, 18,253,106, 85,129, 26,235,115, 28, 13, 20, 69,146, 99, 39,234,191, 55,223,248,246,130, 63,239, -247,233,211,199,113,159,243, 64, 69, 0,118, 74,105, 82, 25,241, 61, 1,224,121,231,169, 9, 64, 58,128,243, 0, 86, 83, 74,141, -247, 59,190,148, 74,229,204,200,200,200,215,242,243,243, 13,132, 16, 74, 8, 65, 97, 53,128, 91,126, 29, 14, 71, 98,122,122,122, - 19, 31,149,172, 76,161, 80,124, 30, 25, 25,249,114, 65, 65,129,193,201, 71, 9, 33,136,140,140,188,133,211,110,183, 39,166,165, -165, 53,241,199,173, 17, 17, 17, 11, 52, 26,205, 11, 6,131,161,192, 41,136, 92,189, 49, 40, 92,107, 73,194,197,212,212,212, 54, -190, 4,129, 66,161,152, 21, 25, 25,217,223,233,119, 16, 66,104,120,120,248, 93,241,123, 68, 68,132, 87,206,226,252,238,141,211, -221,157,132, 16,132,135,135,223,177, 59, 31, 68,206,135, 86, 96, 1,224, 8, 33,235, 91,181,106,213,110,199,142, 29,220,233,211, -167,185,248,248,120, 56, 28, 14,136, 98, 97,122,142,137,137,209,220, 70, 33,179,168, 77,155, 54,207,239,220,185,147, 91,191,126, - 61,215,180,105, 83, 16, 66,224,112, 56,224,112, 56, 80,183,110, 93,245, 29, 22, 98, 58, 65, 16,222, 86, 40, 20,143,218,237,246, - 90, 0, 32,147,201, 78,153,205,230, 29,118,187,125, 6,165, 52,223, 31, 30,171,213,170, 73, 77, 77,189, 37,108,226,226,226, 20, -183,235, 54,189, 94,191,151,227,184, 56, 87, 0, 59,133,134,183, 76, 44,253, 82, 74, 47,165,165,165,181, 44,142, 51, 56, 56,216, -197, 89, 28,135,231, 53, 81, 20, 47,165,166,166,182,244, 33,174,158,110,211,166, 77,224,182,109,219,200,245,235,215,137, 90,173, -134, 40,138,112, 56, 28,176,217,108,168, 93,187,118,169,214, 79, 11, 10, 10,210, 39, 36, 36, 84,125,226,137, 39,176,102,205, 26, -188,244,210, 75,104,221,186,245, 57,233,190, 86,171, 13, 61,121,242,100,245,144,144, 16, 24, 12, 6,228,228,228,160, 83,167, 78, -255,250,204,213,188, 81,133, 73,132, 35, 33,174, 10,192,238,200,220,127,244,198,216, 59,229, 13, 10, 10, 58,162, 80, 40, 34,165, -120,229, 56,206,107, 92,187, 95, 51,153, 76, 41,233,233,233,141,124,228,159,202, 0,186,241, 60, 95, 77, 16,132,154, 0, 42,219, -237,246, 72, 0,144,203,229, 41, 60,207, 95,177,217,108,103, 44, 22,203,121, 0, 63, 57, 23, 18,244,138, 46,209,175, 86, 37,118, - 67,159, 60,179,248,164,166,202,180, 26,134,139, 9,103, 53, 74,195, 47, 93,162, 95, 93,237,175,200,186,143,226, 42, 54, 42, 42, -234, 19,231,255,145,148,210,203,101, 64,251, 60,165, 52, 16, 0,114,114,114, 2,175, 95,191, 94,238,167,159,126,170, 59,101,202, -148,199, 8, 33,211,125, 45,190,216,162, 73,197, 67, 28,199,197, 72,242, 65,164,142,196,125,135,174,151, 73,197,196,243,252,172, - 94,189,122,245, 95,189,122,181,230,240,225,195,154, 90,181,106,185,202, 39, 81, 20,225,105,120,136,141,141, 45, 49,248, 0, 8, - 28,199,205,236,213,171, 87,223,101,203,150,105,206,156, 57,163,137,141,141, 45, 82,230, 73,233, 82,186, 22, 21, 21,229,151, 91, -195,195,195,191,125,252,241,199, 95, 92,180,104,145,108,243,230,205,234,136,136, 8,132,132,132, 64,161,184,181,104,110,220,184, -177,232,131,142,227, 56,110, 86,143, 30, 61, 94, 92,177, 98,133,230,192,129, 3,154,186,117,235,130,231,249, 59,246,123,207,158, - 61,251, 46, 95,190, 92,115,236,216, 49, 77,181,106,213,192,113, 28, 56,142,187,133,143,227, 56, 84,168, 80,193, 47,206,238,221, -187,247, 93,185,114,165,230,200,145, 35,154,154, 53,107,186,194,206,173,123,174,212,238,124,192, 57, 31, 62,129,229, 52,151, 46, -105,213,170, 85,151, 29, 59,118,240, 0,112,228,200, 17,100,102,102, 34, 58, 58, 26, 58,157, 14, 74,165, 18, 38,147,137,150,178, -208,250,214, 41,174,100, 0,240,227, 11, 61,113, 73, 6, 12, 75,181, 64, 46,151,227,226,197,139,224,121,158,222, 65,161,216, 86, -175,215, 47, 94,187,118,109,112,163, 70,141,184,244,244,116,196,198,198, 34, 51, 51,243,145,157, 59,119, 54,126,245,213, 87, 95, - 37,132,188, 68, 41,221,233, 47,231, 47,191,252, 2,173, 86, 11,141, 70, 3,173, 86, 11,139,197, 66,110, 59,160, 5, 33,230,202, -149, 43, 17, 58,157, 14,162, 40,186, 14,143,254,107, 23, 68, 81, 68,245,234,213,173, 62, 10,198,152,171, 87,175, 70,168,213,106, - 80, 74,139,240, 57, 28, 14, 40,149, 74,247,150, 2, 28, 14, 7,226,226,226,172,190, 44, 87,146,184, 2,128,101,203,150,161, 92, -185,114,136,136,136,128, 86,171,133, 90,173, 46, 82,161,251, 89,128,163, 75,151, 46, 24, 63,126, 60,166, 77,155,134,145, 35, 71, - 22, 41,104,101, 50, 25, 66, 66, 66,176,105,211, 38,232,245,122, 84,170, 84, 9, 50,153,236,223,111, 9,228, 72,200,190, 67,215, - 92, 22,217,199, 31,139, 23,154, 55,174, 52,215, 25,195,224, 56, 64, 20, 11,171, 76, 66, 64,237, 54, 49,235,207,191,111,140,243, - 35, 60,163,174, 94,189, 26,161, 84, 42,253,114,135,195,225, 64,116,116, 52,239, 35,255, 60, 89,167, 78,157, 31,135, 12, 25, 34, -175, 86,173, 26,145,203,229, 16, 4, 1,130, 32, 72,233,177, 18,165,180,146, 40,138,237, 82, 82, 82,232, 23, 95,124,241, 49, 33, -164, 23,165,244, 23,175,233,157, 26,235,231,153,197, 39,119,253,133, 71,250,116,124, 15,155, 86, 37, 60,210,166,161,136, 0,141, -241, 2,128, 7, 86, 96, 17, 66,244,106,181,250,131, 85,171, 86,201, 1,160, 99,199,142, 31, 16, 66,222,162,148,230,150,213, 55, - 2, 3, 3, 17, 24, 24,136,186,117,235,162,119,239,222, 65, 13, 27, 54, 28, 73, 8,121,157, 82,106, 45, 94, 9,240, 49,123, 14, - 94,142,144,206,187,119,169, 39,111,217,180, 82, 74, 97, 67,204,243,105, 10,209, 33, 38, 30,248, 43,177,137, 31,254,253,184,119, -239,222,253, 86,175, 94,173, 3,128,121,243,230,161,119,239,222, 8, 9, 9,129, 70,163,129, 92, 46,135, 76, 38, 43,242,235,195, - 34,196, 3,248,248,233,167,159,238,179,108,217,178, 0, 0, 88,180,104, 17,186,118,237,138,208,208, 80,232,245,122, 40,149, 74, - 40, 20, 10,200,229,242, 34,229,128, 63,226,170,101,147, 38, 3, 22, 45, 90, 4, 0, 24, 61,108, 24, 58, 54,110, 12,157, 70, 13, -141, 90, 1, 41, 44, 20,188, 12,189,223, 75,240,229,111, 14,192,167,189,123,247,126,118,197,138, 21, 1, 0,112,248,240, 97,164, -166,166, 34, 50, 50, 18,106,181, 26, 10,133,194,229,103, 66, 8,212,106,181, 95,126,239,221,187,119,159,229,203,151,187,252,222, -165, 75, 23,132,134,134, 34, 32, 32, 0, 74,165, 18,114,185,188,200, 81, 92, 24,184,115,246,234,213,171,207,202,149, 43, 3, 0, - 96,225,194,133,232,216,177, 35,130,131,131, 17, 16, 16,224, 10,203,210,198,209,131,204,249, 80, 10, 44,105,108, 84,100,100,228, -179,187,118,237,226,220,196, 1,148, 74,165, 43, 99, 72,221,132,165, 40,180, 72,100,100,228, 43, 59,119,238,116,189,100,161,183, -152,168, 75, 93,113,187,241,119,108,223,190,253,242,141, 27, 55,170,228,114, 57,140, 70, 35, 78,156, 56,129,192,192, 64, 40, 20, - 10,244,232,209,131,111,213,170, 85,104,187,118,237,214, 16, 66,250,250, 51, 67,129, 82, 10,157, 78, 87, 68, 96,221,105, 23,178, - 90,173,198,134, 13, 27,192,243,188,215,130,203,253,127, 68, 68,132, 63,254,134, 82,169,196,222,189,123,193,243, 60,100, 50, 25, - 4, 65,128, 76, 38,195,207, 63,255,140, 17, 35, 70, 32, 61, 61, 29,132, 16,200,100, 50, 4, 4,248,236,221, 36, 33, 33, 33, 65, -146,184,146,196,143, 90,173,134, 76, 38, 35,130, 32, 16,169, 11,143, 16, 66,252,237, 83,231, 56, 14, 75,151, 46,197,244,233,211, - 49,106,212, 40, 44, 88,176, 0,245,235,215,119, 23,159,200,205,205, 69,112,112, 48,130,131,131,161, 82,169,110, 59, 45, 60, 72, -240, 12,157,207,103,204,214, 64,164, 40, 28,228, 33, 2, 34, 64, 65, 33, 82, 17, 41, 55, 46,224,195,241,159,240,165,232,210,193, -158, 61,123, 92, 34, 72, 16, 4, 16, 66,224, 46,140,164,163, 92,185,114, 62,249,228,114,249,132,117,235,214, 41,150, 46, 93,138, - 21, 43, 86,184,210,150, 86,171, 69, 80, 80, 16, 66, 67, 67, 93, 71, 76, 76, 12,249,238,187,239,228,245,235,215,159, 0,224, 23, -239,113, 78, 3, 53, 85,166,213,232,211,241, 61, 0, 64,159,247, 40,178,206, 77,110,192,101,143, 11,124,128,197,149, 0, 96,244, -156, 57,115, 66, 27, 55,110, 12, 0,152, 51,103, 78,232,128, 1, 3, 70, 19, 66,198, 82, 74,237,119, 64,191,156, 16,242,188,179, - 28, 80,117,234,212, 73,241,229,151, 95,162,102,205,154, 24, 62,124,120,200,199, 31,127,220, 29,192,234,146,202, 35,119,124, 49, -103,110, 16,165,133,233,135,138,180,200,111,102,234, 21,188,245,206,135,126, 57,170, 66,133, 10,131,214,172, 89,227, 26, 14, 17, - 21, 21, 85,164,242,119, 47,163,164,163, 4, 81, 68, 0,112, 21, 43, 86, 28,176,114,229, 74, 23,103, 88, 88, 24,228,114,121,145, - 10,246,196,209,195,248,230,179, 9,208,135,149,195,251, 83,103,249,116,103, 68, 68,196,130, 39,159,124,242,133,239,191,255,222, -117,237,145,154, 53,241, 84,171,102,136, 8,211, 35, 44,184,176,108,163, 34,193,223,103, 46,251,172,143, 0,112, 21, 42, 84,120, -117,213,170, 85, 58,247,134,160,228, 87, 0, 48, 24, 12, 46,171,189,197, 98, 65,147, 38, 77,252,242,187, 59,103,104,104,168,203, -239, 82,248,185,135,173,212,128, 41,137,179, 66,133, 10, 3, 36, 1, 12, 0, 33, 33, 33, 69, 56,100, 50, 25, 86,109, 90,124, 75, -221,112,167,156,165,141,119, 79,206, 43, 87,174, 96,202,148, 41,174, 50, 73,178,226, 17, 66, 16, 29, 29,141,217,179,103,151, 74, - 96, 3,104, 10, 32,220,237,220, 2, 64,225,246,155, 6,224, 79, 47,207, 73,215,101, 0, 26, 56,239, 57, 0,228, 1, 8,242,194, - 87, 28, 79, 58, 10,187,160,195, 61,158,247,252, 78, 81,129, 69, 8,145,114,111,123, 0,123,210,211,211,197,211,167, 79,115,135, - 15, 31,134, 76, 38, 67, 68, 68, 4,154, 54,109, 42,117,159, 65, 38,147, 65,171,213,146,160,160,160, 20,169,194,149, 2,207,102, -179,185,250,147,221,132, 12,151,153,153, 41,110,221,186,149, 91,210,171, 51, 44, 20,104,248,193, 84,116,233,218, 21,155,163, 21, -224, 1, 60,114, 58, 29, 26,141, 70,144,201,100, 54, 41, 18, 36, 78,247,177, 89,158,226,136, 16, 18,160,213,106,191,251,233,167, -159, 84, 28,199, 33, 47, 47, 15,162, 40,162, 85,171, 86,224, 56, 14,199,143, 31,199,251,239,191,143, 31,127,252, 17,235,214,173, - 83, 55,106,212,232, 59, 66, 72, 45, 74,105,158, 91,225,181,205, 91,226, 12, 8, 8,128, 70,163,113, 9, 44,201,207,146,251,220, -187, 99, 40,165, 55,210,211,211, 27,151,196,233,112, 56,208,179,103, 79, 16, 66,192,243,188, 75, 12,121,254,202,229,114, 28, 63, -126,252,150,196,231, 77, 24,138,162,136,214,173, 91, 3, 0, 52, 26, 13,116, 58, 29,182,111,223,238,186,223,176, 97, 67, 88, 44, - 22,132,133,133,225,212,169, 83,222, 10,238, 34,156,105,105,105, 52, 41, 41,137, 44, 89,178, 4, 50,153, 12,161,161,161,208,104, - 52,100,241,226,197,163,229,114,121,140,201,100, 18, 45, 22, 11, 20, 10,197,108,201,154, 37, 8, 66, 65, 78, 78, 78,104,113,156, - 60,207, 99,200,144, 33,120,247,221,119,177, 96,193, 2,188,241,198, 27,183, 88,184, 76, 38, 19,194,194,194, 92, 34,203, 31,191, -223,185, 0,186,203,156, 34,197,137, 35,155,113,242,216, 54,136, 14, 17, 14,145,130, 82, 7, 68, 59,112,120,235,254,234, 55, 47, - 37, 69, 83, 80,192,217,145,161,204,201,183,183, 11, 83,214, 4,176,126,123,186,121,166,175,244, 41, 8, 2,108, 54, 27,126,250, -233, 39, 92,184,112, 1, 91,182,108,129,209,104,116,133, 99,139, 22, 45, 48, 96,192, 0,175, 2,203,147,147, 82,186,232,250,245, -235, 13, 91,183,110, 77,178,179,179,145,157,157, 13,163,209, 8,135,195, 1,187,221, 14, 65, 16,160, 82,169,160, 86,171, 17, 25, - 25, 9,147,201, 68,205,102,243,162,226, 56, 69,145,228, 24, 46, 38,156,221,180, 42,225,145, 62,239, 81,172,158, 78, 80,181,162, -210,240,219,161,128, 1,235,119,143,236, 4,128,138,206, 82,135, 3,168,205, 33,166,191, 59,250,179,161,247, 60,142,138, 98,208, -219,111,191, 93,171, 95,191,126,174, 11,253,250,245,195,137, 19, 39,106,205,152, 49, 99, 16,128, 57,165,229, 36,132, 68, 59,239, -255, 10,224, 87,169,130, 95,191,126,125, 47, 0,175,172, 91,183, 14,125,251,246,197,199, 31,127, 92,215, 83, 96,185,115, 82, 74, -113,229,220, 46, 92, 57,191, 27,162, 72,221,172,224,222,255, 83, 63,221, 89, 80, 80, 96,250,235,175,191,116,223,124,243, 13, 34, - 34, 34, 16, 27, 27, 11,141, 70, 3,149, 74, 85,164,114,117,175,112,125,229,205,130,130, 2,211,233,211,167,117,203,151, 47, 71, - 72, 72, 8, 42, 85,170, 4,141, 70,227,178,222, 40, 20, 10,108,252,113, 37, 62,121,171, 55,110, 92, 56,142,161,253,186,250,116, -167, 70,163,121,225,251,239,191, 47, 98,242,136, 14, 15,131, 32,227,192,203, 8,130, 59,244, 2, 0,100,253,190,182,216,213, 29, - 61, 56, 73, 94, 94,158,233,192,129, 3,186, 67,135, 14, 65, 20, 69, 84,174, 92, 25, 6,131, 1,122,189,222,229,255,173, 91,183, -162, 71,143, 30, 88,186,116, 41, 90,180,104,225,211,239,249,249,249,166, 99,199,142,233,126,248,225, 7,132,132,132,160, 66,133, - 10,208,104, 52, 46,195,132, 36,180,120,158, 71, 92, 92, 28,114,114,114,160,211,233,124,134,231,225,195,135,117, 63,252,240, 3, -130,131,131, 17, 19, 19,227,178,176, 73,162,104,250,220,241, 69, 56, 84,164,252, 29,115,222, 78,188,187,115,246,236,217, 19, 85, -171, 86,133, 94,175,135, 86,171,117,113,151,196,233,166, 69,218, 81, 74,119,120, 26, 49, 9, 33, 27,221,190,223,149, 16,178,209, -253,183,184,231,156,127,219,142, 30, 61,186,201,180,105,211,166,180,104,209, 98,249,222,189,123,151, 21,199, 87, 28,207,232,209, -163,235, 76,155, 54,109,138,251,243, 94,190,115,171, 5,139, 82, 74,156,158, 19, 0, 32, 62, 62, 30,153,153,153, 80, 42,149,104, -218,180, 41,210,211,211,161,211,233, 32,151,203, 65, 41,197,208,161, 67,249,145, 35, 71, 70,112, 28, 7,187,221,238, 42,240,139, -233, 75, 23, 57,142, 67,203,150, 45,113,194,217,243,211,165,107, 87,196,196,196, 64, 26,196,161, 82,169, 48,116,232, 80, 50, 98, -196, 8, 65,178, 94, 80, 74, 97, 52, 26, 81,190,124,121,117, 9, 93,111,111,173, 89,179, 38, 80,161, 80, 32, 47, 47,207,213, 69, -198,243, 60, 78,159, 62,141, 79, 63,253, 20, 47,191,252, 50,174, 93,187,134,168,168, 40,188,251,238,187,186,105,211,166,189, 5, - 96,162,175,130, 88,167,211,185,196,149, 70,163,193, 91,111,189, 37,180,106,213, 42, 66,167,211, 33, 32, 32, 0, 82,119,159,195, -225, 64,149, 42, 85,124, 74,113, 81, 20,177,121,243,102, 8,130,224,211,130,229, 76,120,126,113, 30, 56,112,192, 37,206,220, 91, - 69,132, 16,156, 56,113,194, 37,230,252,224,164, 28,199, 65,171,213,162, 92,185,114, 80,171,213,208,104, 52,100,249,242,229, 99, - 99, 99, 99,203,143, 24, 49,130,203,205,205,229, 90,182,108,137,222,189,123, 11,162, 40,194,106,181,162, 78,157, 58, 62, 45,109, - 59,118,236,192,252,249,243,241,198, 27,111,120,181, 96, 73,131, 32,245,250,251, 62,199,161,204, 32, 2,176,218,109, 48,228, 27, - 93, 93,184, 14,135, 3,199,182, 31,173,126,233,232,185, 58, 27,151, 47,149, 1,128,105,251, 90,247,215,202,247,158,187,178, 70, -187, 16,249,129,237,153,214, 3,190, 44,131,195,135, 15,199,184,113,227,240,220,115,207, 97,235,214,173,120,255,253,247,241,234, -171,175, 22,177, 96,249, 3,155,205,246,213, 75, 47,189,244,198,234,213,171,107,190,247,222,123,156,100,193,210,104, 52,210, 24, - 46,152,205,102, 24,141, 70,156, 57,115, 70, 28, 56,112,224, 89,139,197,242, 85,113,124,118,162,254, 91,163, 52,252, 82, 37,134, -171, 90,112,249,147,128,214,205, 42, 27,137,186,113, 78,175, 26, 29,233,147,175, 84, 14, 6,165,160, 34, 32, 82,192,108, 46,192, -208,161,255,227,239,103, 92, 17, 66,158,236,212,169, 83,231,201,147, 39,223,114,111,242,228,201, 56,117,234, 84,103, 66,200,149, -226,186, 68,139,225,140, 41, 87,174,220, 76,231,255,183, 40,165,137, 82,111, 49,128, 30, 91,183,110, 5, 0, 84,172, 88, 17, 0, -234, 16, 66,150, 0, 88,238, 20, 99,183,152, 67,109, 54, 59,140, 70,115,137,194, 74, 58,167, 84,244,215,141,180,102,205,154,232, -214,173, 27,100, 50,153,171,145,230,222, 61,230, 41,180, 74, 42, 63, 0,136,132, 16,196,197,197,161,115,231,206,144,203,229,208, -106,181, 46,209,162, 80, 40,192,243, 60, 30,237,208, 25,147,103, 77,192,132,151, 91, 97,124,143,202,216,126,236,106,137,238, 52, - 26,141,249,251,247,239, 87,143, 24, 56, 16,205,227,227, 17, 30, 20,132,184,168,242, 80, 43, 21,144,187,187,137,248, 54,170,211, -194,202, 78,228,121, 30,117,235,214, 69, 74, 74, 10, 46, 95,190,140,203,151, 47,131,227, 56,180,110,221,218,101,117, 57,127,254, - 60, 38, 78,156, 8,179,217,236,183,223,171, 85,171,134,199, 30,123, 12, 10,133, 2, 26,141,166, 72,215,160, 20,166,121,121,121, -168, 90,181, 42,214,175, 95,143, 26, 53,106,248,228,140,143,143,199,163,143, 62, 10,185, 92,238,138, 35,181, 90,237,170, 55, 0, -224,250,129,124,215, 55,162,163,163, 75,197,185,229,224, 53,124,179,245, 15,152, 45, 34,114, 13,182, 34, 47,148, 15,211, 99,247, - 15,239,249,229,119,137,243,235,175,191, 70,118,118,182,171, 12,146,140, 37,146,113,162, 66,133, 10,152, 55,111, 94,113,241, 35, -105, 17, 82,204,253,174,126, 54,164,164,231, 82, 36,195,255,180,105,211,166,120,190,239,139,207,253,190,199,251, 22, 15, 81,150, - 82, 98, 23,161, 84, 47, 72,170, 50, 58, 58, 26,210, 56, 15, 41,211,185, 10, 80,187, 29, 63,254,248, 35, 34, 34, 34, 92, 71, 96, - 96, 96,177, 9, 90, 26, 39, 52, 60,173,112,152,193,166, 40, 57,174, 0,120, 42,173, 48, 67, 72, 99,132,214,172, 89, 3,119, 1, - 19, 16, 16, 80, 98,119,145, 66,161,104,215,180,105, 83,206,108, 54,223, 34,174,166, 77,155,134,190,125,251,162, 70,141, 26, 16, - 69, 17,249,249,249,104,223,190,189,108,246,236,217,237, 74, 35,176, 52,154,194,241,252, 22,139, 5,219,183,111, 71,112,112, 48, - 66, 67, 67, 17, 18, 18,130,128,128, 0,105, 38, 36,245, 37, 50, 40,165,232,217,179,167, 43,209,185, 91,173, 60,197,214,222,189, -123,253,234,122,163,148,162, 89,179,102,208,106,181,208,233,116,208,233,116,216,188,121,243, 63,102,244, 71, 30,129, 40,138,136, -136,136,192,190,125,251, 74,236,230,164,148, 82,185, 92,238,122, 94, 38,147,145,197,139, 23,143,142,139,139, 43,255,206, 59,239, -112, 60,207,227,200,145, 35, 56,121,242, 36, 42, 87,174,236,247,152,172,236,236,236,155,163, 71,143,118,140, 30, 61, 26, 0, 80, -167, 78, 29,100,103,103,167, 74,247,115,115,115, 51, 58,119,238, 12,158,255,167,142, 77, 79, 79,207,248,215, 11, 44, 81,132,221, -106,135,193,100, 66,126,158,193,101, 13, 74, 77, 74, 9,122,111,196,219,178, 79,135,246, 7, 0,140,152, 57, 7,121, 11,254, 41, -192,214,142,120, 62,162,215,103, 43, 18, 0,244, 40,137,223, 96, 48,192,108, 54,163, 82,165, 74, 56,120,240, 32,242,242,242,208, -177, 99,199, 34, 22, 82, 41, 76,125,153,226, 41,165, 22, 66, 72,171,174, 93,187,254, 57, 99,198,140, 42,181,106,213, 34, 5, 5, - 5, 48, 24, 12,112,255, 61,118,236, 24, 93,182,108,217, 37,131,193,208,146, 82,106, 41,142,111,243,141,111, 47,116,137,126,117, -245,111, 71,248,174, 17, 85,207,234,111,100, 85,177,103,220, 80, 22,228, 26,207,152, 28,244, 36,168, 3,112, 64, 4,181,139,112, - 56,187,183,238,163,184,138,169, 94,189,250,235, 75,151, 46, 45,146, 6,221, 45,172, 75,151, 46, 69,235,214,173, 95, 39,132,156, - 46,105,112,191, 27,167, 66, 38,147, 37,172, 92,185, 82, 14, 0,143, 61,246, 88, 2, 33,228, 29, 74,169,165, 94,189,122,125,246, -238,221, 27, 40,149, 43,129,129,129,160,148,242, 6,131, 33,176,101,203,150,125, 36, 75, 87,145,248, 17, 1,155,205, 6,163,209, -140,156,156, 60, 88,172, 54,103,153, 41,194,225,176, 59,127, 69,216,157,229,168, 66, 46, 4, 52,174, 87, 62,159, 82, 10,142,144, -236, 67,199,110, 86, 40,174, 92, 42,174, 43,203, 31,235,149, 23, 56,164,178, 48, 52, 52, 20, 10,133, 2, 91, 55,174,197,229,191, -182, 67,198, 3,162,221, 6,135,221, 10,135,205, 2,129,231,113,224,228, 53,180,136,211,248, 19, 71, 52, 52, 52, 20, 29, 26, 53, - 66,215, 22, 45, 10,167,171, 9, 2,116, 74, 37, 52,114, 85,161,229, 10, 0,117,112,128,127, 73, 73,116,159,213,120,232,208, 33, - 12, 31, 62, 28,211,167, 79,135, 90,173,118,205,102, 62,125,250, 52, 86,174, 92,137, 78,157, 58,249,237,119, 66,136,203,239,130, - 32, 32, 33, 33, 1, 73, 73, 73,152, 57,115, 38, 26, 55,110, 12,153, 76,134,236,236,108,180,108,217, 18, 41, 41, 41,126,135,167, -212,141,167, 80, 40,138, 88,155, 36,225,119, 59,113, 36,113,246,239, 89, 30, 27,246, 44, 3, 1,193,254, 31,222, 46, 82, 23,205, - 91,177,171,212,156,227,198,141, 43,226, 78,127,172, 87,165,200,175, 27,253, 17, 89,110,207, 29,150,116,122, 66, 66,194, 24, 66, -200,198,132,132,132, 49, 83,167, 78, 61,225, 15, 95, 49,247,127,118,254, 62,229,118,237,176, 79,129, 69, 41,165, 10,133, 2,162, - 40, 22, 17, 85,158, 3,106, 37,147,159,187, 73,209,151, 24, 16, 69,209,149, 24,120, 47,133,216,190,125,251,176,111,223,190, 34, -215,191,249,230,155, 18, 43,112,187,221, 94, 43, 32, 32,160,136,245, 74, 46,151, 35, 33, 33, 1, 47,190,248,162, 75, 92,201,229, -114, 44, 92,184, 16, 77,154, 52,129,197, 98,169,229, 99, 60,138,161, 92,185,114,156, 84, 0,105,181, 90, 50,124,248,112,222,110, -183,187,194, 68, 58,164,177,105,190, 18,139, 52, 43,101,203,150, 45,126, 89,176,252, 29,131, 68, 41,197,209,163, 71,139,136, 54, -105, 22, 12, 0, 28, 61,122,212, 53, 62,203, 31, 78,158,231,225,112, 56,160, 86,171,137, 92, 46, 39,114,185, 60, 70, 18, 87, 60, -207,187,226,219,125, 76,158, 47,191,223,184,113,163,125, 73,247, 83, 83, 83, 31,218,229, 24,172, 54, 27,140, 6, 11,242,242,141, -152, 48,213, 57,126,100, 2, 14, 0, 56,208,106,208,112, 12,233,210,233, 49,143,126,126,127, 10, 24, 87,165,184,102,205, 26,200, -100, 50,172, 95,191, 30,122,189, 30,221,187,119,135, 94,175,199,123,239,189,135,231,158,123,206,111, 11,150, 51, 45,229, 16, 66, - 90,189,245,214, 91,127,126,242,201, 39, 21, 43, 84,168, 0,139,197, 2,171,213, 10,139,197,130, 11, 23, 46, 96,217,178,101,215, - 13, 6, 67, 43, 74,105,142, 47,190,205, 55,190,189,240,227,206, 17, 73, 29,159,235,109, 60,157,178, 9,201,201, 25,176,219,111, - 64,116,216, 97,181, 23,206, 72,118,216,237,176,219, 29,144,203,121,253, 39,147,223,222, 42,130,130,227,136,165, 79,159, 62, 79, -220,195,104,162,231,206,157,203, 8, 15, 15,151, 10, 49,189, 52,161, 69,161, 80, 80, 0,210, 0,247, 2, 0, 86, 63, 57, 7, 77, -159, 62,189,130,212,125, 63,125,250,244, 10,239,188,243,206, 32, 0,179,142, 29, 59,182,184,127,255,254,239,172, 90,181,170,200, - 11,253,251,247,199,177, 99,199, 22,123, 55, 17, 56, 45, 88, 38, 19,210, 50,178,240,218,160,177, 46,211, 1, 64,139,136, 10, 10, -138,193,195,160, 2,128,244,148, 11,232,255,218,112,165,175,134,128,183, 10,176, 20, 99,112,220, 45, 67,174,231,244,122, 61,228, -114, 57, 14,109, 91,139,249,227,250, 3, 14, 43,168,205, 8, 88, 13,128, 53, 31,162,197, 0, 34, 87, 3, 54,223,171, 84,112, 28, - 71, 3, 2, 2,160, 83,171, 17, 17, 20, 84,184,136, 35,207, 67, 38, 19, 32,218, 0,226, 32, 46, 33, 42, 58,252, 74,235, 52, 44, - 44, 12,162, 40, 66,173, 86,227,202,149, 43, 24, 50,100, 8,172, 86, 43,122,246,236, 9,139,197, 2,147,201, 4,163,209,136,184, -184, 56, 24, 12, 6,191,253, 46,213,157,114,185, 28,111,191,253, 54,154, 52,105,130,137, 19, 39, 98,212,168, 81,136,139,139,195, -224,193,131,177,108,217, 50,212,169, 83,167, 68, 94,137, 83,138, 35,157, 78,231,138, 23,207,174, 60, 0,165,138, 35,111,156,133, -227,254,113, 75,188,255,239,165, 14,165,230,156, 54,109, 26,210,210,210,110,177, 92, 73,255,163,163,163, 49,119,238,220,219,237, -226,151,172, 69,145, 94,110, 63,229,197,242,212, 20,133, 99,163,204, 83,167, 78, 61, 49,117,234,212,174,132,144,141, 83,167, 78, -237, 90,130, 5,235, 41, 31, 22,174,167, 80, 56,230,170, 68, 8, 30,125,159,237,220, 45, 35, 82, 5, 42, 85,228,238,133,187, 70, -163,193,143, 63,254,136,197,139, 23, 23,169,236,125, 9,172, 95,194, 11,223,127,210,105,185,114, 63,239,214,173, 27, 98, 99, 99, -139, 88,175,212,106,117,137,137, 70, 20, 69, 92,189,122, 21, 39, 78,156, 64,243,230,205,145,147,147, 3, 25,199, 97,196,177, 99, -168,253,210, 75,176, 56, 45, 50, 10,133, 2,111,188,241,134, 95, 3,213, 47, 95,190, 28,236,126, 30, 22, 22,150,216,166, 77,155, -232,131, 7, 15,186, 6,190, 59,187,207, 92, 66,195, 31,241, 66, 41,197,211, 79, 63, 93,196,106,229, 46,174,220,143, 77,155, 54, -249,213, 69, 72, 41, 69,155, 54,109, 92,214,171,128,128, 0,172, 91,183,206, 21, 87,109,219,182, 5, 0, 68, 70, 70,250,197, 41, -249,195, 57,176, 29, 38,147, 73,204,203,203,227, 14, 31, 62, 12,133, 66,225,178,216,169,213,106,168, 84, 42, 40,149, 74,175,173, -126, 6,128, 82, 17, 22,155, 13, 70,163, 17,249,249,133, 43,132, 92, 56,190,166,168, 0, 51,223,254,228, 52,201, 74,149,151,151, -135,223,126,251, 13,107,215,174, 69,227,198,141,111, 25,228,238,143, 5,203, 45, 61,165, 17, 66, 90,143, 28, 57,114,255,164, 73, -147,162, 66, 66, 66, 96,181, 90,113,237,218, 53,124,247,221,119, 73, 6,131,161, 53,165, 52,205,255, 64, 0,108, 54, 59, 76, 6, - 51,114,114,243, 48,126,242,194, 98,147, 30, 0,100,166,158, 65,183,238,207, 40,238,109, 60,209, 27, 0, 94,117, 43, 11,151, 0, -144,204,241,185,148,210, 23, 75, 41,128,219,245,233,211,167,195,219,111,191,237,186,246,246,219,111, 99,255,254,253, 29, 8, 33, -199, 41,165,219, 9, 33,117,103,204,152,225,122,102,198,140, 25, 88,189,122,245,111,148,210,237,197,165, 37,169,139, 48, 63,223, - 8,125, 80,121,220,184,188,195,167, 91,228,188, 9, 84, 20,125, 54,252,188, 89,173,220,203,167, 82,164, 31, 26, 25, 25, 41,245, - 46, 64, 46,151,163,213, 83,207,227,141, 49, 51,161,146, 81,188,221,167, 41, 98,116, 20, 80,135, 64,222,246, 61,144,160, 74,133, - 47, 14,249,201, 47,254, 81,243,231,227,200,185,194, 21, 94, 98,194,195, 49,242,185,231, 64,109,192,222,147, 39,177,226,143, 63, -240, 92,251,246,208,168, 84,126, 55, 84,164,198,247,133, 11, 23,176,119,239, 94,196,199,199,227,252,249,243,174, 49,182, 82,207, -131, 63,254,167,148, 82,105,114,146, 82,169,132, 76, 38, 67,114,114, 50,186,118,237,234,106,224,239,216,177, 3, 35, 71,142,196, -128, 1, 3,208,174, 93, 59,175,227, 98, 61, 57,195,195,195, 93,134, 3,207, 9, 8,238,221,182,165,137, 35,111,156, 18,110, 55, -222,221, 57, 39, 77,154,228,117,162,132, 63,156,238, 90,164, 4, 28,246,176, 30, 65, 26, 15, 37, 9, 34,207,115, 0,193,210,181, -132,132,132, 49,254,190,231,126, 46, 89,192,252,237,170, 20,164, 62, 79,111,149,172,100, 46,246, 6,173, 86,139, 55,223,124, 19, -227,198,141, 67, 88, 88,152,207,177, 51,146,114, 45, 9, 63,253,116,107, 38, 91,191,126,189,175, 46,194,211,129,129,129, 77,218, -183,111,143,156,156, 28, 92,191,126, 29, 90,173, 22,181, 63,251, 12,199,134, 12, 65,131,249,243,193, 61,246,152,107,145,212, 99, -199,142, 65,173, 86,159, 46,173,197, 32, 32, 32, 0,193,193,193,174, 62,117, 73,104,185, 89,176,168, 31,137, 16,191,252,242,139, -215, 86,226,237,140,193,146, 50,255,254,253,251,139,140,191,114, 23, 60,251,247,239,119, 89,176,164,215,252,233,218, 82,171,213, - 84,226,211,104, 52, 8, 9, 9,129, 82,169,132, 90,173, 46, 34,174,252,177,222,249, 90, 72, 84,173, 86, 31,212,106,181, 65,210, -125,153, 76,134,188,188,188,236,140,140,140, 71,254,213, 93,132,160,176, 91,237, 48, 26, 77,200,207, 43,251,181, 36,165, 9, 39, - 63,254,248, 35,154, 53,107,118,139,184,146,194,250, 54, 4, 71, 34, 33,164,221,172, 89,179, 14,124,254,249,231,193,249,249,249, -248,254,251,239,115,242,243,243,219,185,141, 35,242,143, 75,164,176, 89,173, 48,152,204, 40,200, 47, 12,131,139, 39,214, 60,212, -194,186, 94,189,122, 47,185,207,118,147,240,253,247,223,227,252,249,243, 47, 1,216, 14, 96,254,123,239,189, 87,173,113,227,198, - 21, 0,224,189,247,222,187, 14, 96,126, 73,101,135,213,217, 69,152,159, 95,104,245, 48, 21,164,151, 77, 58,117,138,140,226,198, - 92,221, 78, 87,142, 84,222,202,229,114,188, 52,112, 8, 46,158, 57,133,102, 97, 89,136, 9,211,129,230,222,128,252,177, 15,113, - 44, 83,131,153,243, 55,151,154,123,165,219, 36,158, 79, 87,174,244,122,239,102,223,190,165,242,251,217,179,103,161, 86,171,225, -112, 56,110,169,111, 74,235,127,119,225, 50, 99,198, 12,140, 28, 57, 18, 11, 23, 46,196,177, 99,199,208,160, 65, 3,116,236,216, - 17,169,169,169,248,251,239,191, 97, 54,155,253,118,167,251,184,184,179,151, 78, 98,219,222, 95,113, 53,241, 50,146,146,175,223, -118,188,187,115,122, 10,172, 31,183,253,133,167, 59, 53,186, 45,206,241,227,199, 35, 53, 53,181,136,229,202,221,186, 89,156, 5, -203, 83,139,120, 32,221, 99,172,147,116,110,241, 16, 59,158,231,158,207, 3, 64, 42, 0,222,199,123,158,231,233, 83,167, 78,221, - 46, 89,190,156,188,124,113,227,175,188,118, 17, 74, 98, 72,154,218,239,105,153,146,254,107,181, 90, 4, 4, 4, 32, 32, 32, 0, -122,189,222,167,101, 72, 18, 88,109, 46,229, 21, 25,203, 37, 89,178, 0, 96,192,128, 1,183, 88,176, 60, 23,167,243,132,217,108, -222,177, 99,199,142,134,221,186,117,227, 79,159, 62, 13,158,231, 33,138, 34, 44, 45, 90,160,193,252,249, 56,254,246,219,120,244, -202, 21,152,172, 86,168, 84, 42,108,222,188,217,106, 48, 24,118,148,182,188,112, 23, 88, 90,173, 22,129,129,129, 46,129,225,143, - 42,151, 50,109, 73,227, 27,164,195,125,144,191, 63,153, 89,170, 72,221,199,221, 16, 66, 96, 52, 26, 93,131, 53,253,177, 50,186, -119, 17,186,103, 60,142,227, 16, 20, 20,228, 42, 52, 36, 11,150,191,214, 59, 95, 11,137,106, 52, 26,253,153, 51,103,170, 74,203, - 72,164,167,167,227,177,199, 30, 59,247,175,175,105, 69,192,106,119, 32,223,104, 66,190,209, 80,102,180, 82, 90, 91,186,116, 41, - 46, 92,184, 0,171,213,138,169, 83,167,222, 34,172, 74, 51,200,221, 75,186,186,208,168, 81, 35,241,241,199, 31,199,254,253,251, -161, 84, 42,109,148,210, 82,175, 95, 37, 82, 17, 86,187, 29, 38,163, 17,249, 5, 5,255, 9,203,229,177, 99,199, 86,107,181,218, -231, 1,232,178,179,179,249,192,192, 64,104, 52, 26, 24,141,198, 28, 56,103, 10, 58,199,188, 77,123,246,217,103,103, 2,128,205, -102,155, 86,210,152, 54, 74, 41,108,118,167, 88, 47,195,112,148,210, 82,113,101,210,237, 44,151, 34, 85,164,210,238, 15, 31,142, - 24,138,230, 97,153,232, 88, 59, 4,198,228,243, 80,233,195, 64,130, 42, 99,230,252,205, 56,117, 37,179, 20,182, 80,224,241, 71, -123,160,126,252,173,203,123,181,238, 80,216, 22,219,253,219, 65,164,164, 39,149,218,239, 5, 5, 5,197, 90,170,252,181, 96,121, -250, 93, 38,147,161, 97,195,134,168, 94,189, 58,182,111,223,142, 70,141, 26,225,252,249,243, 56,127,254, 60,174, 92,185,130, 99, -199,142, 33, 43, 43,171,212,113,180,110,203, 10,100,229,101, 66, 33, 87, 32, 51, 59, 29, 87,111, 92, 70,100,104,185, 59,142,119, - 9, 53,159, 26, 15, 0,136, 10, 15, 44,149,192,114,231,252,248,227,143,111, 17,237,101,176,244,206, 65, 31,231,165,125,255,174, - 67, 40,198, 42,100, 12, 9, 9, 81,187,247,159,114, 28,135,192,192, 64, 50,125,250,116,158,227, 56, 4, 4, 4, 32, 48, 48, 16, -146, 89,208, 23, 20, 10,133,177,114,229,202,106, 41, 1, 74,194, 73,175,215,243,211,167, 79, 39,223,124,243, 77,177, 86, 45, 31, - 99,176, 62,127,241,197, 23, 95, 77, 76, 76, 12,142,136,136,192,205,155, 55,161, 80, 40, 10, 51, 69,251,246,104,115,233, 18,172, -133, 99,138,112,246,236, 89,124,245,213, 87, 5,102,179,249,243,210, 6,148, 78,167, 67,104,104,168,171,107, 80,178,224,184,137, - 69,191,134, 86,150,100,138,151,198, 79,221, 78, 87,145,167,200, 26, 52,104, 80, 17,177,229, 47,228,114,185, 93, 90,169,157,227, - 56, 88,173, 86, 52,106,212, 8,169,169,169,174,204,226,110,185,243, 71, 96,249, 90, 72, 84, 16, 4, 88, 44, 22,180,109,219, 22, -132, 16,204,153, 51,231,225,232,118, 20, 69,162,211,133, 34, 42,170, 6,194, 35, 76, 16,197,178,219,253,197,110,183, 99,240,224, -193, 69, 44, 86,210, 76, 69,169,139,159, 82, 10,155,205,118,219,139,182, 74,249,250, 78,214,127,163,128,171,107,171,160,192,244, -175,139,194, 74,149, 42,233,157, 93,134,158,240, 62,219, 15,255, 44,201, 64, 8,153,116,237,218,181,122,129,129,129,232,220,185, - 51,214,173, 91,183, 30,192, 38, 15, 75,225,255,156,255,111,148, 28, 23,206,112, 52,153, 81, 80, 80,246,214,208,146, 26,122,183, - 3,142,227,192,243, 60,102, 77,155,128,230,161,233,232, 80, 83,135,245,191, 29,192, 83, 53,229,128,165,244, 61,192, 82, 25, 22, - 18, 21,139,202,117,154,223,114, 95,169, 47,236,154,171, 92,167, 57,184,235,231, 75,237,119,247,111,120, 89, 58,224,142,194,243, -181,215, 94,195,123,239,189,135,206,157, 59,227,252,249,243,216,185,115, 39,206,159, 63,143,225,195,135,163, 78,157, 58,104,208, -160, 65,169, 56, 55,108, 91,141,220,252, 28,112,132, 67,102, 78, 6, 76,102, 35, 70, 13, 30,119,199,241, 46,225,242,182,169, 0, -128, 53, 91,143,220, 54,231,251,239,191,143,228,228,228, 34,150,171, 59, 25,119,245,111,133, 87,129,149,145,145,225,181,191, 47, - 60, 60, 60,165, 83,167, 78, 17, 55,111,222,132, 78,167,243, 41,174, 8, 33, 29,165,181, 50,146,147,147,189,114, 6, 4, 4, 88, - 59,117,234, 36, 43, 95,190,124,145,217,131, 90,173,246, 22,235,143, 39,167,179, 96,202, 35,132,188,222,170, 85,171, 69,155, 54, -109,210, 84,175, 94, 29,185,185,185,160,148, 98,225,194,133, 24, 58,116, 40, 84, 42, 21,206,158, 61,139,238,221,187, 27, 12, 6, -195,235,238,107, 96,121,227,244,150,185, 57,142,115,173, 98,239, 69, 92,149,232,119,247, 76, 58,107,214, 44, 76,153, 50, 5, 99, -198,140, 41, 49, 98, 22, 44, 88, 0,120,116,231,121,227,164,148,226,211, 79, 63, 45, 51,206,140,140,140,133, 30,214,167, 57,189, -122,245, 18,174, 95,191, 94, 68, 84,185, 31, 94, 10,164, 34,156,190, 22, 18,229,121, 30,145,145,145,152, 52,105, 18, 66, 67, 67, - 81,174, 92,185, 91, 44, 47,190,226,232, 54, 91,239,119,149,211, 65,197,195,159, 76,251,160,245,247, 75, 54,200,148, 10, 96,223, -206, 53,200,205, 74, 46,106,129,181,254, 51, 37, 90,209,168, 3, 44, 71,126,243,203,157,102,179, 25, 31,127,252, 49,198,143, 31, -143,241,227,199,251, 19,239,119,228,119,127, 68,150, 87, 78,145, 18,141, 54, 24, 42,109, 20,106,215, 9,134, 88,202,181, 58,239, - 83,188, 27,174, 95,191, 30, 88,161, 66, 5,156, 59,119,142,224,159,241, 88,238, 13,198,231,225, 54,219,175, 24,206, 99,203,150, - 45,171, 87,175, 94, 61,204,153, 51, 7, 0, 94,217,178,101,203,243,132, 16,147, 47,145,230,201, 41, 82, 74,212,154, 32,168,180, -229, 81,187,110, 16, 68,209, 94, 38,126,151, 42, 63, 79,235, 85, 41, 23,146,190,133, 83,106, 32, 29,219,249, 19, 6,191, 82, 13, -235,126, 63,140, 31, 78,200, 80, 67,155,142,170,193,105, 16,211, 78,227,173, 62,141, 48,115,117, 97, 37,126,211,119, 28,149,152, - 0, 77, 70,235, 29,249,221,221, 82,229,158,214,125,141,193, 42,201,239,121,121,121,200,206,206,198,162, 69,139,208,191,127,127, -164,166,166,226,202,149, 43, 56,119,238, 28,150, 47, 95,238,154,157, 94,218, 56, 26, 49,240,125,140,253,244, 29, 80, 80,212,172, - 90, 27, 9, 67,198,163,105,253, 22,119, 28,239,158,240,101,189, 42,137,115,230,204,153,183,149,150,254, 19, 2,171,164, 86, 9, -199,113, 8, 11, 11,115, 37, 14,247,132,119, 59, 45, 93,158,231, 97,183,219, 93, 99,123,164, 3, 0,186,117,235,134,159,126,250, -201,159,153, 17,155, 8, 33, 47,212,170, 85,235,187, 9, 19, 38,232, 30,125,244, 81, 33, 42, 42, 10, 77,155, 54,197,217,179,103, -241,243,207, 63,219,230,206,157, 91, 96, 48, 24, 6, 80, 74,183,222, 78,185, 36,109, 61,227,126,148,166,149, 99,181, 90,175,159, - 63,127,190,252,167,159,126,202,115, 28,135,153, 51,103,186, 50,163,180, 80,171, 59,118,238,220,105, 23, 69,177,196, 46, 25,155, -205,118,253,252,249,243,229, 63,251,236, 51,158, 16,226,226,148, 90,143,158,221,171,254,112,122, 19,151,210,132, 7,111,135, 55, -183,123,139,227,146, 22, 18, 21, 4, 1,103,207,158,197,184,113,227, 64, 8,193,154, 53, 15,199, 24,157, 99,167,211,191,105, 80, - 59, 34,184,219, 19,173,235,129, 16, 88, 45,183,246, 0,233,178,242, 93,226,170,215,103, 43,176,118,196,115,254,136,157, 11,187, -119,239, 14,249,248,227,143, 5,158,231, 49, 99,198,140, 34,139,253,122,198,251,174, 93,187,236,183,211,189, 39,229,103,171,213, - 10,163,241,246,172, 38,148,210,189, 83, 39,143,237,180,120,233, 47, 50, 66, 44,216,183, 99, 13,114,178,189, 79, 77, 87,200, 4, -124,179,232, 71,187, 92,198, 95,191,207, 81,183,160, 99,199,142,227,182,109,219, 38,248,216, 39,206, 23, 54,204,158, 61,251,201, -151, 94,122, 41,164, 86,173, 90, 88,187,118, 45, 80,184,242,179,194,153,183,138,136, 52, 31,225,184,126,218,228,177, 47, 47,250, -225, 23, 5, 71,172,216,183,115, 13,114, 60,196,250,173,214,104, 25,190, 93,248,163, 85, 46,151,157,241, 85,174,187, 91,175,238, -180, 66,116, 79,123, 29,158,121, 3,195, 23,125,137,138,141, 58,227,157, 15,218,227,199, 79,158,199,123,173, 0,235,170,126,168, -219,103, 49, 22,142,238, 2, 0,136,154,227, 95,122,148, 9,114, 92,243, 98,161,202,206, 81, 57, 69, 77,233,172,164,146,223, 75, - 42,195, 75,107,193,226, 56, 14,177,177,177,168, 82,165, 10, 90,181,106,133, 70,141, 26,161,125,251,246,248,251,239,191,241,247, -223,127, 99,248,240,225,197,138, 43,127,226,168, 93,203, 78, 56,208,230,204, 29, 39,114,207,120, 47, 11,248,147,150,134, 12, 25, - 2, 0,255, 9,107,150,112, 59,129, 39, 37,200, 59,221, 58, 70,226,180, 88, 44,174,174, 55,247,117,149,164, 65,239,126,206,208, -219, 74, 8,169,243,193, 7, 31,188,173, 82,169,218, 27, 12,134, 26, 78, 11,204, 89,179,217,252,135,209,104,156, 65, 41,205,190, - 19,183,186, 47,203,224,205, 9, 37,189,155,149,149,213,165, 75,151, 46, 91, 5, 65,136,245,220,240,212, 91, 6, 22, 69,241, 74, - 74, 74, 74,137, 83,213, 51, 50, 50,186,116,238,220,217, 43,167,183,130,193, 31, 78,111,241, 35,138, 98,177,226,202,159, 2,200, -215, 66,162,130, 32, 64,171,213, 98,221,186,117, 8, 11, 11,123,168, 50,216,209,147,169, 31,151,116,191, 93,152,114, 7,128,240, - 94,159,173,184,182, 61,221, 82,169, 93,152,226,234,218, 17,207, 85, 44,233,157,244,244,244,206,253,251,247,255, 85, 16,132, 88, -207,240,247, 22, 23,118,187,253,114,114,114,114,169,151, 61,160,148,226,204,153, 51,226,107,175,189,150,158,150,150,246,204,237, -248, 63, 97,220,236,207,167, 76, 24, 26,250,120,167,230, 77,193, 1,150,226, 7,245, 82, 2, 80, 65,198, 95, 31, 57,102,230,192, -251, 25,103,148,210,163,132,144,137, 85,171, 86,125, 3, 64,113, 53,225,114, 63,120,172,132,144, 79,154, 52,105,242,222,152, 49, - 99,130,186,117,235,134, 10, 21, 42, 20,187, 94, 96,201,233, 40,229,141, 6,181,194, 99, 30,239,216,172, 11, 8,161, 22,139,217, -135,200, 1, 5,165, 84, 46,151,157, 57,120, 52,169,190, 47,235,188,115,199,140, 50,239,154,239,219,255,117,244,237,255,186, 43, - 61,253,240,221,163,216,114,126, 59, 58,215, 72,132,249,171,214, 32,250,138,165, 18,109,147,167, 14, 47, 75, 75,102,145,201, 87, -101, 53, 6,139,231,121,164,167,167,227,236,217,179, 72, 73, 73,129,193, 96,192,169, 83,167, 96,181, 90,145,149,149,133,186,117, -235,222,182, 59,203, 42,142,238, 39,231,127,169,155,176, 84, 2,203,110,183, 39,250,218,245,220,102,179,149,106,150,145, 76, 38, - 51, 85,175, 94,157,120,155,109, 32,253,215,106,181, 70, 63, 11,198,108, 0,227, 0,140,115,238, 55,133,204,204,204, 59, 86,129, - 14,135, 35,169, 82,165, 74,124,113,194,197, 25, 54, 41, 62,220, 86, 0,160, 69, 25, 87, 4,101,206,233, 37,126, 10,226,227,227, - 93, 99,185, 60,215, 52,113,110,130, 90,226,168, 91, 95, 11,137, 22, 20, 20,220,236,210,165,139,195,253,190,251, 66,164, 15, 53, - 8,189,250,228,243,175, 86,218,158,110,169, 4, 0,146,200, 2,165, 87, 75,136,119, 35,128, 71,239,182,211, 46, 93,186,100,105, -214,172,217,210,188,188,188, 33,148,210,219, 30,165, 63,230,195, 57, 99,254,109,209, 66, 41, 61, 10, 96, 80, 25,240,156, 34,132, - 12,250,224,131, 15,250,124,240,193, 7,213, 0,132, 1, 80,249, 43,210,138,136,172, 83,105,101,190, 54,152,221,110, 79,172, 82, -165, 74,169, 44, 53,190,202,120,155,205, 86, 98, 61,241, 43,180,133,243, 40,161, 0,144,225, 23,167,209,104,204,108,216,176, 97, -169,204, 44, 54,155, 45,213, 95,191,151, 47, 95, 30, 81, 81, 81,174, 95, 9,158,215,125,185,211,110,183, 39,198,196,196, 32, 44, - 44,172,216, 21,218, 61,199, 92,249,195, 89,214,113, 84, 18,103, 84,212,226, 50,231, 44, 43,189,240, 80, 11, 44,105,143,193,178, - 68, 74, 74,202, 93,217, 27,133,150,133,121,237, 31, 75, 81, 83,252, 71,145,145,145, 17,122,167, 28,190, 22, 18, 77, 73, 73,105, -255, 95, 13,223,237,105,150, 87,110,185,230, 20, 91,247, 27, 5, 5, 5, 21, 41,165,183, 53, 50,191, 79,159, 62, 14, 48,184, 11, -226, 69, 15,162,219,210,211,211,203,188, 76,191, 27,245, 68,102,102,102,189,255,170,223,239,134, 59,255, 45,156,255,118,112, 44, - 8, 24, 24, 24,138, 17, 6, 76, 36, 49, 48, 48, 48,220, 38, 8,128,142,197, 20,174,126,207,220, 33,132,116,188,141,194,123, 27, -227,100,156,140,147,113, 50, 78,198,201, 56,255, 91,156,190,184,203,122,230,240,253,108,165,222,181, 3, 64, 71,198,201, 56, 25, - 39,227,100,156,140,147,113, 50,206,255,218,193,186, 8, 25, 24, 24, 24, 24, 24, 24, 24,202, 24, 76, 96, 49, 48, 48, 48, 48, 48, - 48, 48, 48,129,197,192,192,192,192,192,192,192,192, 4, 22, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 12, 12, 12, 12, 12, 12, 12, - 12, 12,183, 15, 82,134,235,113, 50, 48, 48, 48, 48, 48, 48, 48, 48, 72, 2,139, 16,226, 82, 89,148, 82,194,130,133,129,129,129, -129,129,129,225,158, 10,146,135, 76,139,184, 4, 22, 19, 86, 12, 12, 12, 12, 12, 12, 12,247, 83, 96, 61, 76, 90,164,136, 5,139, -137, 44, 6, 6, 6, 6, 6, 6,134,251, 37,176, 30, 38, 45,194, 44, 88, 12, 12, 12, 12, 12, 12, 12, 15,132,192,122,104, 45, 88, - 15,147,114,100, 96, 96, 96, 96, 96, 96,248,119, 9,172,135, 73,139,176, 89,132, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, - 48, 48, 48, 48, 48, 48, 60,216,184,171, 11,141, 18, 66, 58, 50, 78,198,201, 56, 25, 39,227,100,156,140,147,113, 50,129,197,192, -192,192,192,192,192,192,192,192, 4, 22, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, - 48, 48, 48, 48, 48, 48, 48, 48,129,197,192,192,192,192,192,192,192,112,159, 64, 0,120,157, 9, 64, 41,221,230, 55,201,109,204, - 38,240,197,207, 56, 25, 39,227,100,156,140,147,113, 50,206,135,143,211, 23,119,105,244,199, 3, 13, 74,233, 93, 59, 0,116,100, -156,140,147,113, 50, 78,198,201, 56, 25, 39,227,252,175, 29,172,139,144,193, 87, 11, 67, 32,132, 8,183,123,255, 94,113, 50, 48, - 48, 48, 48, 48, 60, 72, 96,149, 24, 67, 73, 66,168, 5,128,174,206,255, 27, 41,165,251, 74,115,255, 94,113,222, 43, 68, 69, 69, -169,131,131,131, 59, 31, 57,114, 68,113,234,212, 41,236,218,181,139,126,243,205, 55,214,172,172,172, 45, 73, 73, 73, 70,150, 98, - 30,138, 52,223, 5, 64,130,243,116, 26,165,116,243, 29,242, 17,141, 70, 51, 92,171,213, 62,169, 84, 42,163,236,118, 59, 49, 24, - 12, 73, 5, 5, 5, 91,237,118,251,103,148, 82,241, 54, 56,155,134,133,133, 13,170, 83,167, 78,245, 75,151, 46, 93,191,118,237, -218, 18, 0,155, 1,116,169, 88,177,226,139,113,113,113, 21, 78,156, 56,113, 46, 61, 61,125, 62,165,244,207,251,229, 78, 6, 6, - 38,176,252,203,124, 92,112,112,112, 39,181, 90,253,191,252,252,252,134,122,189,254,164,221,110,159,125,243,230,205,141, 44,227, - 61,180, 21,141, 0,160, 43,165, 84, 6, 0, 60,207,247,104,209,162, 69, 37, 66,136, 40,237,120,206,113, 92, 67,135,195,193, 57, -159,239, 74, 8,249,147, 82,106, 47, 13,103,179,102,205, 42, 8,130, 64, 41,165,132, 82,202,113, 28, 87,191, 52,156,101,133,240, -240,240, 41,162, 40, 70,149,244, 76, 96, 96, 96,147, 35, 71,142,212, 92,185,114,165,227,171,175,190,202, 30, 48, 96,128,110,200, -144, 33,194,156, 57,115,190, 4,240, 63,207,231,195,194,194, 62,231, 56, 46,204,159,239,139,162,152,158,158,158,254, 14, 75,121, -247, 29, 9,115,183,229,181,165, 20,120,179, 83, 0,231, 20, 46,183,141,232,232,232, 69, 47,191,252,242,243,245,234,213, 19, 40, -165,176,217,108, 48,155,205, 53,247,237,219,215,110,205,154, 53, 77, 0, 60, 83,202,124,217, 53, 33, 33,225,235,137, 19, 39,134, -203,100, 50, 98,179,217,154,175, 92,185,242,241, 65,131, 6, 29,157, 63,127,126,131,103,159,125, 54, 64,186,254,225,135, 31, 62, - 65, 8,121,155, 82,186,252, 94,187,147,129,129,193,135,192, 10, 8, 8,168, 22, 30, 30, 62, 34, 52, 52,244,137, 38, 77,154,228, -188,254,250,235, 23, 47, 92,184,112, 60, 54, 54,214,240,253,247,223, 79,182,217,108,115,107,212,168,177, 37, 55, 55,247,179,228, -228,228, 83,165, 44, 40,170, 1,120, 29,192, 19, 0, 98, 0, 36, 1,248, 21,192,215,148,210, 51,183, 41, 10,234, 5, 4, 4,140, -226, 56,174,121,126,126,126,140, 78,167, 75,162,148, 30,200,205,205,253,132, 82,122,228, 54, 57,163, 5, 65,120, 93, 38,147, 61, - 42,138, 98, 21,142,227, 46, 59, 28,142, 29, 86,171,245,107, 74,233,181,219,228,172,166,215,235,223,146,203,229,173, 77, 38, 83, - 5,165, 82,153,232,112, 56,246,102,103,103,207,188, 93,191,223,109, 40, 20, 10,110,201,146, 37, 13, 20, 10, 5, 0,192, 98,177, -160, 78,157, 58,119,180,219,185, 76, 38,227, 62,251,236,179, 70,130, 32,192,106,181,138,121,121,121,180,119,239,222,247,165,219, -154, 16, 18,147,148,148, 20, 40,151,203,189,222,119, 56, 28,104,219,182,109,172, 92, 46,199,103,159,125,102, 75, 79, 79,111,248, -197, 23, 95, 28, 89,182,108, 89,216,151, 95,126,217,199,155,192,226, 56, 46, 44, 49, 49,209, 43,167,195,225,128,213,106,133,221, -110,135,197, 98, 65,173, 90,181, 88,105,244, 96,160, 18, 0,252,242,183, 9, 0, 66,238,148, 76,171,213,198,247,237,219, 87, 72, - 75, 75,131, 76, 38,131,213,106, 69,114,114, 50,234,212,169,195, 47, 93,186,180, 70,105,249,106,214,172, 57,104,234,212,169, 17, -191,252,242,139,117,233,210,165,230,142, 29, 59,202, 7, 12, 24,160,111,219,182,109,155,152,152, 24,238,187,239,190, 51,111,219, -182,205,250,194, 11, 47, 40,167, 76,153, 18,241,235,175,191, 62, 15, 96,249,189,118, 39, 3, 3, 67, 9, 2, 43, 32, 32, 96,135, - 78,167,171, 58,112,224,192, 51, 67,134, 12,217,162,211,233, 28, 0,240,195, 15, 63, 8, 61,122,244, 72,235,221,187,119,170,193, - 96,224,231,206,157, 91,241,139, 47,190,216, 26, 16, 16,112, 35, 47, 47,239, 17, 63, 42, 50, 2,224,127, 28,199, 13,235,220,185, -243, 14,155,205,150,182, 97,195,134, 85,189,122,245,106, 67, 41,213,254,254,251,239, 63, 19, 66, 22, 0,248,212, 95,235, 24, 33, -132, 87,171,213,227, 99, 99, 99,223, 93,190,124,185,178,122,245,234,208,106,181,200,201,201,169,120,242,228,201, 10,175,188,242, - 74,119,173, 86, 59,219, 96, 48,140,165,148,218,252, 14, 28, 65,120, 53, 60, 60,252,211,121,243,230,233,235,214,173, 75,180, 90, - 45, 46, 95,190, 92,110,207,158, 61, 45, 62,254,248,227,161, 60,207,143,113, 56, 28,115, 75, 81,137, 19,141, 70, 51,178, 90,181, -106, 99, 22, 47, 94, 28, 16,167,215, 17, 5,117,192, 66, 81,235,138,193, 28,255,242,203, 47, 63,167,211,233, 62, 41, 40, 40,152, -114,191, 44,131,132, 16, 37, 0, 80, 74,205,132,144,141, 60,207,247, 80, 40, 20, 92,143, 30, 61,176,109,219, 54, 98, 50,153, 4, - 0, 80,169, 84,246, 30, 61,122, 64,173, 86,195, 98,177,136, 0, 54, 22,103,105,242,198, 41,147,201,184,246,237,219, 27, 14, 30, - 60,152, 41,113,106, 52, 26, 91,251,246,237, 67, 21, 10,133,218,110,183,211,146, 56,239,146,136,196,133, 11, 23,138, 92,203,203, -203, 67, 90, 90, 26, 50, 50, 50, 96, 54,155,145,157,157, 13, 81, 20,137, 90,173, 78, 19, 69, 17, 28, 87,104,108, 43,142, 83, 46, -151,227,236,217,179, 69,174,217,237,118, 20, 20, 20,192,108, 54,195,106,181, 34, 47, 47, 79, 29, 16, 16, 80,173,118,237,218,137, - 0,214,103,102,102,126,150,156,156,124,149, 21, 79,247, 5,215, 54,254,101,170, 8,192, 2,224,114, 25,240,137, 0,176,107,215, - 46,164,164,164, 32, 61, 61, 29,105,105,105,136,137,137,193,237,228,241, 51,103,206,204,106,216,176, 33, 57,122,244,232, 79, 0, -190, 94,177, 98, 69,175,204,204,204,121, 35, 71,142, 12,249,228,147, 79, 50, 71,141, 26, 53, 24,192,218, 21, 43, 86,244,175, 87, -175, 94,183, 99,199,142,205,188, 31,238,100, 96,184, 11,104, 10, 32,220,249, 63,221, 89,238,134,186,157,255,237,204,183,210,115, - 22, 0, 10, 47,191, 18,164,243, 52, 0,127,186,189, 39,157,223, 49,164,174, 24, 42, 29,210, 13, 74,105, 84,181,106,213, 50,103, -204,152, 81, 51, 33, 33, 33, 52, 63, 63,159, 7,128,232,232,104, 19, 33,132, 26, 12, 6,254,189,247,222, 11,159, 54,109, 90, 77, -165, 82,153,101,183,219,195, 61,201,139,153,106, 57, 76,175,215,119,191,124,249,242,138,154, 53,107,134, 76,157, 58,245, 47,181, - 90, 77,103,205,154,117,184, 74,149, 42,229,175, 94,189,186, 88,175,215, 63, 6,224, 93,111, 14,246,198,169, 84, 42, 39,189,244, -210, 75,239,158, 63,127, 94,217,180,105, 83,232,245,122,240, 60,143,144,144, 16,180,109,219,150,156, 62,125, 90,217,187,119,239, -225, 42,149,234, 19,127, 57,121,158,127,163,119,239,222,179,175, 94,189, 26,216,185,115,103,162, 80, 40,144,149,149, 5,165, 82, -137, 86,173, 90,145,181,171, 87,233, 91, 52,107, 54, 93, 46,151,191,229, 47,167, 70,163,121,231,133, 23, 94,248,240,216,177, 99, -250, 58,117,234,144,171,159,127,132,253,221,218,224,242,228, 49,136,143,143, 39, 71,143, 30, 13,232,223,191,255, 24,173, 86, 59, -198, 95,206, 59,133, 59, 39, 33,100, 8,128, 76, 0,153,132,144, 33,148,210,125,117,234,212, 57,124,234,212, 41,180,105,211, 6, -171, 86,173,170, 63,114,228,200, 33, 35, 71,142, 28,178,106,213,170,250,109,218,180,193,169, 83,167, 80,167, 78,157,195,238, 99, -165,252,225,220,177, 99, 7, 30,123,236,177,172, 85,171, 86,197,141, 27, 55,110,202,184,113,227,166,172, 88,177,162,202, 99,143, - 61,150, 53,115,230, 76,115, 73,156,119,195,239,238,150, 37,247, 67, 20,255,169, 91,162,162,162, 82,127,252,241, 71, 60,251,236, -179,156, 66,161,184,249,220,115,207, 41,119,239,222, 77, 1,108, 44,141, 59, 77, 38, 19,140, 70, 35, 10, 10, 10,112,233,210, 37, -245,199, 31,127,220,122,252,248,241, 85,183,109,219, 22, 61,102,204,152,193,225,225,225, 71,202,149, 43, 87,233, 94,251,157,113, - 2, 0,146, 1, 88, 1, 20, 0,184,122, 39,156, 29, 58,116,168, 91,181,106,213,200,149, 39,130,145, 37,175, 9, 81, 30, 4, 81, - 30, 4, 71,104, 83, 92, 80, 60,129,138, 21, 43, 70, 6, 4, 4,180, 40, 13, 39,165,116,235, 95,127,253,245, 4,165,116, 62,165, -212, 65, 41, 93, 61,106,212,168,215, 8, 33,107, 70,141, 26,245, 6,165,116,181,243,250, 55,127,255,253,119, 55, 74,233, 31,247, -195,157, 44, 45, 49,206,219,108,224,223,162, 69,220, 16, 78, 8,217, 72, 8,217, 56,122,244,232,246, 0, 66, 61,206, 91,186, 63, - 7, 64,225,237, 87, 58,220,174,135, 3,120,202,237,189,240,178,242, 15,231, 22, 88,132, 82, 74,220, 60,106,251,248,227,143,247, -127,251,237,183,219,110,222,188, 89, 62, 46, 46,238,169, 94,189,122, 85,202,201,201, 33,189,122,245,138, 45, 95,190,124,215, 29, - 59,118,148,235,211,167,207,239,125,250,244,217, 71, 8,177,251, 17,120, 85,120,158,127,251,232,209,163,187, 43, 86,172,104, 77, - 74, 74, 10,104,216,176, 97, 30, 0, 84,175, 94,221,144,145,145,161, 14, 12, 12,196,166, 77,155, 14, 18, 66, 94, 39,132,212,244, -131,179, 81, 68, 68,196,255,230,204,153,163,228,121,222,235, 51, 42,149, 10, 95,124,241,133, 50, 56, 56,120, 32, 33,164,185, 31, -156, 49,161,161,161,211, 23, 45, 90,164, 54,155,205,176, 88, 44,136,140,140,132, 78,167,195,205,164, 36, 36, 93,185,140,228,203, -151, 48,246,157,183,180,122,157,110, 60, 33, 36,214, 31,191, 71, 68, 68,140,155, 57,115,166,250,232, 51,157,177,189,146, 6,149, - 38,124,134, 70, 7, 46, 34,110,246, 66,236,172, 22,140, 63, 31,111,134,169,147, 39,171, 34, 34, 34, 70,250,227,247,187, 96,185, -250,132, 82,170,166,148,170, 9, 33,179, 90,182,108,185, 84,173, 86, 15,153, 58,117,106,151, 45, 91,182, 60,190,115,231,206,118, -118,187, 93,102,183,219,101,187,118,237,106, 99, 50,153, 4,165, 82, 9, 65, 16,168,191,156, 45, 90,180, 88,164, 86,171, 7,207, -155, 55,175,203, 31,127,252,241,226,161, 67,135,222,116, 56, 28, 10,135,195,161, 56,116,232,208, 27, 70,163, 81, 70, 41,117, 20, -199,121,175, 33,147,201, 32,151,203,161, 86,171,209,186,117,235,139,223,124,243,141, 45, 38, 38, 70,182,102,205,154,224,168,168, - 40,237,156, 57,115,178,243,242,242,166,251,203,103,181, 90, 97, 54,155, 97, 52, 26, 97, 50,153,240,251,239,191,199, 14, 29, 58, - 84, 48,153, 76,142,110,221,186,101,218,108, 54,243,168, 81,163,244, 33, 33, 33, 35, 88,131,245,190,192, 14, 32,223, 41,176,204, -238,105,153, 16, 82, 79,178,198,250,131,236,236,236, 5,223,126,251,109, 12,167, 12,194,110,203,147, 88, 46, 78,192,150,192, 57, - 72,173,244, 46, 34, 98,170,226,249,231,159,143,160,148,206, 41,131,138,110, 61,165,180, 15,165,244,199,219,121,255,110,187,147, - 16, 82, 73,167,211,173,210,235,245,187,117, 58,221, 42, 66, 72,165, 59,245,115,231,106,164, 99,143, 90,124, 98,231,170,132,246, -168,197, 39,118,174, 86,250,181,154, 24, 30, 76,120,106, 17, 55,164, 81, 74,187, 82, 74,187, 78,155, 54,109,138,219,243,210,185, -218, 79,254,174,148,210,174, 30,105,116,227,221,240,139,224,174, 28,189,121, 42, 60, 60,220, 50,102,204,152,163, 38,147,233,248, -162, 69,139,170,190,240,194, 11, 13, 43, 85,170,116,182,119,239,222, 63,235,116, 58,187, 52, 38,199, 79,188,250,228,147, 79,254, - 18, 22, 22,134,156,156, 28,193,102,179,241, 5, 5, 5, 60, 0,136,162, 8,147,201,196, 95,186,116, 73, 48,155,205,180,121,243, -230, 27,246,237,219,247, 58,128,183, 75, 34,212,104, 52, 67,214,172, 89,163, 42, 78, 92, 57, 28, 14,228,229,229,193,110,183, 99, -214,172, 89,170, 87, 95,125,245,127, 0,246,251,168, 84,223, 93,180,104, 81,128,221,110, 7,199,113,160,148,226,200,145, 35,200, - 72, 77,133, 41, 47, 23,230,220, 28, 88,115,115,192, 23,228, 97, 88,191,231, 3,166,124,245,205, 24, 0,175,149,196, 25, 16, 16, -240,206,162, 69,139,116,162, 40, 34,251,200, 1,175,207,228,157,252, 27,162,195,142,185,115,231,234,158,125,246,217, 4, 0, 47, -223,175, 68,174, 84, 42,133, 37, 75,150,244, 85, 40, 20,160,148, 18,139,197,130, 45, 91,182,220, 49,231,226,197,139, 95,148, 56, -173, 86, 43,173, 91,183,238, 45,105,206,108, 54,211, 7, 37,179, 43, 20, 10,168, 84, 42, 88,173, 86, 84,174, 92,217,216,175, 95, -191,189,147, 39, 79,174,200,113,156, 86, 46,151,111,202,200,200,152,146,148,148,116,201, 95, 62,155,205, 6,139,197, 2,139,197, - 2,163,209,136,139, 23, 47,150,139,141,141, 37, 67,134, 12,113, 24, 12,134,184,217,179,103, 95,216,178,101,139,102,250,244,233, -189, 1, 12, 99,197,237, 61,109,100, 40, 0, 4, 86, 12, 21, 10,100, 60,242, 1, 4, 56,197, 64,111, 66, 72,243, 90,181,106, 5, -159, 58,117, 42,139, 16,178, 31,192,114, 74,233,205,146,248, 68, 81, 36,162, 40,226,141, 71,178, 49,164, 5, 15,155, 45, 7, 57, - 57, 57,184,122,245, 42, 78,158, 60,137, 3, 7, 78,222,150, 59, 85, 42,213,171, 58,157,174,179, 74,165,170,108,183,219,185,252, -252,252,171, 6,131, 97,155, 40,138, 11,168,115,129,162,210,224,110,185, 83,130, 86,171,253,120,204,152, 49,173, 2, 3, 3,241, -215, 95,127,197,173, 88,177,226, 99,220,225,160,121,149,140,251,238,243,153,115,162,163, 35,130,240,247,206,159,162,167,204, 95, -249, 29, 10,199,242, 50,252,251,243, 33, 45, 70, 96,253, 9,224, 41,231,236,242,174,119,192,127, 71,239,223,150,192, 42,198, 67, -238,153,218, 49,104,208,160,179, 27, 54,108,168,220,164, 73,147,211,197, 13, 6,246,129, 86,241,241,241, 87,247,238,221,139,144, -144, 16,171,205,102,227, 77, 38, 19, 39,151,203,105,102,102, 38, 49, 26,141,220,223,127,255,173, 74, 76, 76,148, 7, 7, 7,203, - 0, 52,242, 69, 40,151,203, 91, 84,173, 90,213,235, 61,139,197,130,252,252,124,228,229,229,193,108, 54, 35, 58, 58,154,112, 28, -215,204,103,160, 8, 66,155, 90,181,106,145,172,172, 44, 68, 69, 69, 97,207,158, 61,200,207,206,134, 41, 47, 23,150,220, 28, 88, -115,178, 97,203,201, 70,118,106, 18,170,150,139, 38,132,144,150,126,112,182,170, 22, 24, 64,206,188,253, 26,154, 30,185, 10, 34, -147,227, 96,221,242,160, 54, 43, 0,224,145, 99, 73, 32,114, 5, 78, 15,121, 1,149,159, 27, 64, 4,158,111,126, 47, 19,181,115, -124,212, 72,142,227,102, 41,149, 74, 97,240,224,193,184,121,243,102,145, 52, 49,120,240, 96,215,152,171,182,109,219,238, 82,169, - 84,246,180,180, 52,152,205,102,153, 63,156,149, 43, 87,190, 58,118,236,216,131, 22,139, 37, 38, 42, 42, 42,200,108, 54, 27,107, -212,168, 17,165, 86,171, 35, 45, 22,139,163, 73,147, 38, 11,212,106,181, 45, 63, 63,159,218,237,118,242,128,100,118, 16, 66, 96, -183,219, 97,183,219, 17, 22, 22, 86,144,158,158,126, 32, 43, 43,171,239,237,240,217,108, 54,105,134, 22,140, 70, 35, 40,165,248, -235,175,191,160, 82,169,100, 14,135,227,132,221,110,215,200,100, 50,112,206,193, 93, 12,247, 44,158,219,213, 12, 82,124, 62,181, -121, 68, 80,131,110,218, 2,141,130, 47, 16,175, 54,168,252,253, 39, 39, 87,188,244,226,171, 1, 19, 39, 78,172, 20, 22, 22,166, -186,112,225,130,233,163,143, 62,138, 93,178,100, 9, 1,240,105, 73,156,215,175, 95, 95, 51,102,204,152,144, 39,159,124, 50, 78, -169, 84,146,156,156, 28,164,165,165, 33, 37, 37, 5,151, 47, 95,166,127,255,253,247, 69,179,217,188,170, 52,238,140,138,138,250, -102,232,208,161, 47, 53,110,220, 88, 38, 89, 68, 11, 10, 10, 26,238,216,177,163,251,175,191,254,218, 6, 64,169,211,229,245,235, -215, 87,189,255,254,251,218, 39,158,120,162,166, 82,169,228,202,194,157,238,224, 56, 46, 82,167,211, 97,219,182,109, 8, 10, 10, - 2,199,113,145,119, 26, 95, 38,171, 24, 29, 85, 46, 20,166, 61,159,163,102,120, 37,152,172, 98, 52, 75,197, 15,143, 5,171,152, - 91, 77, 37, 11,148, 15,145,100, 76, 72, 72, 24, 67, 8,217,152,144,144, 48,198,155, 5, 75,178,191,184, 63,231,246,188,185,204, - 5,150, 47,164,165,165, 41, 10, 10, 10, 4, 81, 20,249,156,156, 28,141, 70,163,177, 43, 20, 10, 75, 41,191, 87,187,123,247,238, - 7,155, 53,107,150,239,180,104,216, 34, 34, 34,172, 57, 57, 57, 16, 69, 17,162, 40,218,245,122,125,190,205,102, 67, 92, 92, 28, - 7,192,103, 55,153,209,104,172,168,213,106,111,185,110, 48, 24, 92,226, 42, 63, 63, 31, 6,131, 1,122,189, 30,249,249,249, 81, -126, 84,130,177, 26,141, 6, 73, 73, 73,133,150,165,172, 76,152,115,115, 97,201,251, 71, 92, 57,178,179, 32, 26, 11, 16, 82,161, - 34,108, 54, 91, 69, 95,156,102,179,185,162, 66,180, 35,115,251, 22, 84, 28, 95,124,185,156,189,127, 55,116, 85,170,195,102, 52, - 68,223,135,132, 61,183, 97,195,134,141,214,174, 93, 59,224,198,141, 27,183,220,239,217,179, 39,134, 13, 27,134,161, 67,135,158, -126,234,169,167,254,254,233,167,159,240,230,155,111, 66, 20,197, 6,132,144, 28, 74,233,175, 37,113, 38, 36, 36, 28,186,126,253, -250,246,115,231,206, 13,142,136,136, 80,214,171, 87,239,124,189,122,245,248,181,107,215, 70, 14, 28, 56,240,240,227,143, 63,126, -229,183,223,126, 11,217,182,109,155, 74, 20,197,198,132,144, 27,247,123, 29, 44,169,139,216, 98,177,192,100, 50,193,106,181, 2, - 37, 12,106,247,226,127, 79,107,129, 75,172, 57,185,201,218,181, 63, 98,215,174, 93,220,201,147, 39, 98, 6, 15, 30, 34, 13,164, -103, 37,237,189, 17, 86, 79, 40, 56,242,213,200, 6,161,170, 17,245, 67, 11, 20, 2,201, 63,251,213,152,252,203, 21,245, 5,145, - 21, 52,150,152,216,160,168, 41, 83, 38,151, 63,125,250,140,121,236,216,177,167,158,123,238,185,136, 17, 35, 70,212, 90,179,102, - 77, 27, 66,200,183,148,210,236, 98,120,229, 3, 6, 12, 56, 16, 17, 17, 81,101,254,252,249,169,215,175, 95, 15,182,217,108, 26, -155,205,102, 45, 40, 40,184, 96, 48, 24,118, 91,173,214,109,148,210,195,165,113,111, 64, 64, 64,253, 87, 94,121, 69,150,157,157, - 13,231,236, 91,164,166,166,162, 85,171, 86,252,134, 13, 27,106,223, 78, 24,100,102,102,126, 78, 8,217,190,108,217,178,206,122, -189,190,177, 82,169, 44, 7,192,145,151,151,151, 82, 80, 80,112,244,118,220,233, 14,135,195,145,114,248,240,225, 42,122,189, 30, -215,174, 93,131,195,225, 72,185,211,120, 83,201,185,235,199,118,110,168, 16, 31, 22,139,221,123,247, 67, 37,231,174,179,212,252, -208, 67, 26, 35, 5,119,225,228, 69, 24,237,157, 58,117,170,122,218,180,105,152, 58,117,234, 9,111, 22, 44, 73,104, 77,157, 58, -245,132,244,156,219,243, 59,203, 84, 96, 21,167, 24,243,242,242,132, 35, 71,142, 4, 95,191,126, 93, 23, 22, 22,102,170, 85,171, - 86, 14, 33, 68,228, 56,142,222,188,121, 51,228,242,229,203,170,208,208,208,130, 42, 85,170,100,250,249,189,115,195,135, 15,111, - 51,110,220,184,195,157, 58,117, 74, 7,128,172,172, 44,100,100,100, 32, 45, 45, 13, 86,171, 21, 73, 73, 73,220,161, 67,135, 66, - 54,109,218,212, 16,128,207,174, 23,181, 90,125, 45, 39, 39,167, 70, 72, 72,136,171, 66,147, 68,149,187,192,178, 88, 44,200,201, -201,129, 78,167, 75,242,197,201,243,124,226,141, 27, 55,106,153,140, 70, 92, 59,127, 30,230,188,194, 46, 65,151,184,202,201, 4, -242,243,160, 85,169,144,147,158, 6,153, 76,150,236,139, 83,169, 84, 94,179,112, 66,157,144,118,157, 1, 82,124,253, 28,248, 72, - 43,208,186, 77, 32, 83, 47,190,113, 63, 82, 48,199,113,142,146,186,125, 21, 10, 5, 34, 35, 35,197,230,205,155,227,205, 55,223, -132,195,225,112,166, 89,210,142, 16,178,155, 82,154, 95, 28,167, 40,138,220,169, 83,167,122, 93,184,112,129,151,201,100, 92,179, -102,205,234,180,110,221,218,162, 80, 40, 32,151,203,133,252,252,252,128,109,219,182,169,108, 54, 27,113,114,222,179,117,176,128, -194,217,125, 94, 4, 60, 10, 10, 10, 96, 52, 26,145,159,159,143,172,172, 44, 65,173, 86,215,168, 91,183,238,126,139,197,178,202, -110,183,127,119,233,210,165,220,226, 56,157,130,204,149, 54, 69, 81, 4,165, 20, 14,135, 3, 54,155, 13,114,185, 92,220,177, 99, - 39, 62,157,241, 49, 22,125,183,132,118,239,222,157,108,216,176, 1,162, 40, 38,178,242,244,158,224,179,236,229,147, 85,176, 59, - 10,204, 59,150,229, 47, 61,151, 91, 48,113,233,204, 67, 22, 5,159,219,228,209,200,122,113,177, 53,248,160,160, 96,110,222,130, - 89, 25, 63, 44, 89,125,225,218,181,107,185, 95,126,249,101,139, 26, 53,106, 4, 30, 61,122, 52, 26,128, 87,129,165,211,233, 42, -247,239,223,191,127, 86, 86,150,124,201,146, 37, 11,111,220,184,177,131, 82,122,209,163,160,111, 68, 8,249, 4,128, 12, 64, 36, - 10,199,127,109,165,148, 46, 46,193,189, 34, 33, 4,127,252,241,199, 45,179,253,196, 59, 83,229, 89,245,234,213,171,127,238,220, -185,245,201,201,201, 75, 61,111,106, 52,154,238,117,234,212,121,254,224,193,131, 31, 80, 74, 47,148,134,216, 96, 48,140, 90,189, -122,245, 39, 60,207, 71, 57, 28,142, 36,163,209, 56,234,142, 45, 88, 54,241,181,169,243, 86,124,109,180, 56, 42,170, 21,252, 53, -147, 77, 28,200,146,242, 67,109,189, 2,156, 99,176,164,255, 0,136,199,249, 81,231,127,139,219,179,105,110, 86, 43,139,135,213, -203,219,189, 52, 0,182,178,242,143, 80, 66,101,163, 27, 59,118,108,139, 6, 13, 26,220,108,219,182,109,114,108,108,172,193,173, - 21,101, 12, 13, 13, 53,154, 76, 38,245,213,171, 87,203,175, 91,183,174,186,195,225,208,248,241,189,223,131,130,130, 66, 14, 29, - 58, 20,186,124,249,242,106, 71,142, 28,169,212,175, 95,191, 71, 45, 22, 11,204,102, 51, 46, 93,186, 84,233,171,175,190, 18,229, -114,121, 54, 33,228, 79, 0, 14, 95,132, 86,171,117,223,201,147, 39,171,183,109,219,150,216,108, 54,151,160,114, 23, 89,249,249, -249,144,203,229,184,114,229, 10, 21, 69,241,128, 47, 78, 81, 20,247,237,223,187,183, 86,195,122,117, 97,206,201,114,138,171, 28, -216,115,178, 32,230,100,130, 43,200, 71,104,136, 0,141, 74,135, 19,215, 19, 1,192, 39,167,221,110,223,115, 62, 39,175,118,195, - 25,223,144, 29, 85,131, 64,109, 86, 87,183, 32, 0, 87,119, 97,203,211,105,216,250,199,118,106,119, 56,246, 63,168,153,224,239, -191,255, 78,237,215,175,223, 97, 81, 20, 27,149,198,154,227, 86,249,228,229,231,231, 35, 61, 61,221,145,145,145, 97, 2,128,212, -212,212,172, 13, 27, 54,156, 18, 69,241,145,219,225, 44, 11,216,108,182, 91,172, 79, 14,135, 3,118,187, 93,178, 20, 40,126,254, -249,231,182,167, 78,157,146, 31, 63,126, 28,187,118,237,106,240,195, 15, 63,140,174, 84,169, 82,189,171, 87,175, 38,251, 18,109, -196,187,176,230, 1, 96,229,178, 85, 24, 52,104, 16, 73, 78, 78,198,242,229,203,225,107,209, 83,134, 50, 67, 1,236, 14,181,101, -199,178,252,167,126,185,150,183,239,166,241, 35, 0,155,169,209, 78, 43, 84,168,240,119,227,198,193, 97, 0, 96, 54, 57,202, 85, -171, 86,237, 81, 65, 16, 20,206, 52,220, 56, 52, 52,116, 46,128,214,222, 72,123,246,236,217, 50, 34, 34,162,225,175,191,254,122, -244,198,141, 27, 59, 61,197, 21, 0,212,168, 81, 99,194,241,227,199,159,144,201,100,238,147,139, 40, 0,175, 2,171, 93,187,118, - 53, 42, 85,170, 20,250,203,185, 64,228,202,171,130,242, 57,128,160,130, 35,168, 62,174,202,107, 33, 38,102,127,104, 80, 80, 80, -131,236,236,236,163,165,180,226, 85,124,246,217,103,127,254,230,155,111,226, 31,127,252,113, 5,128, 91, 4, 86,124,124,124,239, -223,126,251,173,207,224,193,131,235, 19, 66,186, 81, 74,207,151,162,210,188, 10,160, 79, 89, 70,218,150,243,116, 27,156,107,150, - 49,252,103,240,231, 93,122,246,174, 65, 40, 65,184,108, 61,127,254,124,211,167,159,126, 58,221, 93, 92,185, 43,204,192,192, 64, - 99, 88, 88, 88,230,209,163, 71,195, 69, 81,220,225,199,247,190,254,237,183,223,254,152, 61,123,246,178,144,144, 16,219,139, 47, -190,200,189,247,222,123,187, 50, 50, 50,104, 70, 70, 6,230,204,153,211,182, 77,155, 54,187,174, 94,189,234, 56,124,248,112,127, - 0,143,251,209, 58,154,219,183,111,223,231,207,157, 59,167,178, 90,173,200,206,206,190,197,122,101,179,217,192,243, 60,166, 76, -153, 98,206,205,205,157,229, 71, 69, 59,107,242,164, 73,207,174, 93,177, 60,128,183, 90, 97,203,206,132, 61, 39, 27,142,236, 76, -112,134, 2, 4,168, 8,170, 53, 10, 71,214, 13, 37,190, 92,246, 83,158,217,108,254,212, 23,103, 94, 94,222,231, 47,191,252,114, -191, 83,167, 78, 5,232,235, 53, 70,206,225, 91,123,190, 20,225,145,176, 88, 44,120,231,157,119,242,114,114,114,166,221,143, 4, - 33,138, 34,111,177, 20,223,243,107,177, 88, 32,138, 98,226,201,147, 39, 87, 16, 66,242, 8, 33,237,156,183,182,123,179, 94,185, -115,114, 28, 39,214,170, 85,107,109,100,100,100, 47, 0, 5,181,106,213, 90,171, 84, 42, 31,179, 88, 44,205, 68, 81, 76,252,235, -175,191,126, 36,132, 36, 19, 66,164, 86,198, 61, 93, 7,203,102,179, 97,220,184,113,152, 54,109, 26, 18, 18, 18, 92,254,149,186, - 9,179,179,179, 99,119,239,222, 45,223,177, 99, 7,157, 63,127,126,198,203, 47,191, 28,244,250,235,175, 7,125,245,213, 87,111, - 3, 24, 85, 28,231,168, 81,163, 48,127,254,124, 12, 26, 52,200,155,181, 84, 76, 76,188, 14,147,201, 68,103,207,158,157, 36,147, -201,130,191,253,246, 91,245,192,129, 3, 9, 43, 79,239, 9,222, 87,247,251,224, 45, 20, 46,205, 48,139, 82,186, 93,186,161,215, -235,213,107,215,174, 19, 0, 96,205,234, 31,101,148,210, 64,105, 97,216,165, 75,151,170, 90,181,106, 21, 81, 28,233,234,213,171, -179, 63,250,232,163,208,215, 94,123,237,241,237,219,183,107, 8, 33,191, 56, 11,253,116,103,195, 49, 12,192,158,240,240,240,242, - 43, 86,172,168,218,185,115,103,173, 31,101,200,183, 43, 86,172,168, 60, 99,119, 32,126, 41,232,133,235,226, 51,160, 65, 20, 33, - 17,121,168,165,187,134,190,125,251, 70,205,154, 53,235,107, 0,141, 75, 33,174,106, 63,253,244,211,235,190,249,230,155,216,215, - 95,127, 61,113,207,158, 61,215, 9, 33, 19,188, 60,154,241,202, 43,175, 92, 93,184,112, 97, 85, 81, 20, 55, 19, 66, 30,167,148, -158, 99,201,135,129,225,246, 44, 88,175, 18, 66,234, 36, 36, 36,124, 28, 21, 21, 85,113,252,248,241,151,107,213,170, 85,224,202, -109, 25, 25,186, 29, 59,118,196,229,230,230,230,217,237,246, 23, 41,165,127,123,201,188, 29,221,215,202,160,148, 94, 37,132,124, -220,160, 65,131,231, 87,174, 92,185, 35, 32, 32, 32,119,255,254,253,122,189, 94,159,115,234,212, 41, 45,207,243,134,203,151, 47, - 99,203,150, 45,109, 1,124,225,173,149,228,133,243,136, 74,165,154,245,234,171,175,254,239,243,207, 63, 87, 81, 74, 97, 48, 24, -144,155,155, 11,179,217, 12, 65, 40,244,226,220,185,115,205, 5, 5, 5, 95, 81, 74,247,251,193,121, 74,161, 80,124, 62,109,218, -212,247,134, 15, 24,160, 66, 78, 6,178,111,222, 0, 49,228, 67,167, 86,162, 78,135, 24, 24, 50,121,204,217,244,135, 57, 53,223, - 48,143, 82,122,212, 15,206,139, 90,173,118,226,208,161, 67, 39,206, 92,181, 69, 13, 0,167,222,120, 30,217,123,254,128,182,118, - 61,180, 60,157, 6,179,217,140, 65,131, 6, 25,114,115,115, 63,245,182,162,187, 39,103, 89,192,157,147, 16, 50,132, 16,242, 82, -124,124, 60, 6, 15, 30,140,158, 61,123, 22,121,118,221,186,117,152, 55,111, 30,204,102,243, 75,132,144, 35,148,210,185,132,144, -221, 78,255,229,251,226,172, 92,185,114,211, 58,117,234, 32, 42, 42,202,224, 20, 23,157, 78,158, 60,217, 56, 62, 62,222,147,243, - 79, 39,167,253, 94,249,221,225,112,100,157, 61,123, 86,255,201, 39,159, 16,171,213,138, 9, 19, 38, 64, 18,154, 82,207,203,155, -111,190, 25, 21, 16, 16,128,241,227,199, 91,210,211,211, 31,251,248,227,143,127, 95,178,100, 73,216,183,223,126,219, 87, 18, 88, -238,156,162, 40,166, 30, 59,118, 44, 96,254,252,249,156,221,110,199,231,159,127,126, 75, 55,228,128, 1, 3, 96,181,218,192,243, -130,197,100, 50,215, 86,171,213, 23, 66, 67, 67,213,238,179,193,238,182,223,255,203,156,148,210,173, 0,182,250,243,158,201,100, - 66, 90, 90, 26,210,211,211, 17, 20, 20, 4,158,231, 73,113,238, 52,153, 76,127,141, 26, 53,234,240,130, 5, 11, 30,223,179,103, - 79,159,157, 59,119, 62,190,109,219, 54,211,213,171, 87,237, 54,155,141,150, 47, 95, 94,104,221,186,181,234,201, 39,159,212, 42, -149, 74,238,253,247,223, 79,159, 60,121,114, 24,128,140, 18,252,206, 19, 66, 48,162,109, 30, 70,181,231, 97,177, 20, 54, 40,111, -220, 72,196,201,147, 39,177,111,223, 25, 80, 74,185, 82,134,231,172,165, 75,151,198, 41, 20, 10,178,108,217,178,138,203,150, 45, - 27,238, 43, 28, 22, 47, 94, 92,121,217,178,101,115,157, 92, 34, 75, 75,140,147,161,148, 2,203, 89,248,156, 0,240, 56, 33,164, -245,235,175,191, 62, 61, 62, 62,222,108,183,219,101,155, 55,111,174,153,158,158,174,176,219,237,163, 40,165,165, 26, 16, 70, 41, -157, 79, 8, 65,143, 30, 61, 70, 85,169, 82,229,183, 35, 71,142,212,239,222,189,251,230,181,107,215,182,182,219,237, 23,143, 31, - 63,254, 18,128, 89, 0,190,240,151,211,108, 54,143,253,249,231,159,237,187,119,239, 30, 49,121,242,100,101,116,116, 52, 9, 14, - 14,198,245,235,215,113,229,202, 21, 58,115,230, 76,179,209,104,252,194,100, 50,141,245,151,211,106,181,126,180,241,183, 63, 84, - 71,255, 62, 54,228,221, 23,158,215, 85,174, 81, 19, 90, 82, 3,249, 25, 25,216,254, 71, 18,102,110,221,145,151,152,155,255,157, -213,106,245,155,211, 96, 48,124,190, 98,197, 10,126,251,246,237, 99,190,252,242,203,128,184,126,175, 17, 93,108, 21,136,113, 53, -177,121,243,102, 58, 98,196,136,188,220,220,220, 79, 11, 10, 10,166,220,235,132, 32,173, 89, 37,138,162, 0, 0,106,181, 26,195, -134, 13,131,251,214, 56,243,230,205,131,209,104, 4, 0,129, 16,242, 9, 33,228,187,226,172, 86,197,112, 86,252,229,151, 95, 42, -186,115,198,199,199,123,227, 52,223,107,255,103,102,102,142,125,226,137, 39,166, 10,130, 16, 84,220, 51,193,193,193,210,146, 31, -142, 27, 55,110,156, 9, 14, 14,134, 76, 38, 3,165,212,107, 62,202,200,200, 24,251,244,211, 79, 79,226, 56,174, 88, 75,135, 94, -175,191,250,251,239,191, 87, 27, 56,112, 32,247,253,247,223, 95,122,237,181,215,148,191,255,254,187,227,118,215, 52, 98,184,123, -112,159,176, 80, 80, 80, 0,135,195, 65, 75,120,246, 26, 33,100,212,225,195,135, 85,131, 6, 13,106,252,194, 11, 47,232,219,183, -111,175,115,127,198,104, 52,138, 63,253,244, 83,193,252,249,243, 51,118,238,220,249,231,128, 1, 3,122,161,112,252,136, 87, 92, -187,118,237,231, 41, 83,166, 4, 62,249,228,147,213, 1,184,198, 95,165,165,165,225,234,213,171, 56,126,252,248, 85,171,213,186, -161,148,222,122,179, 95,191,126,191, 44, 92,184,176,210,235,175,191,158,184,124,249,242, 13, 0,114,188, 60,167,235,221,187,119, -247,133, 11, 23, 86,122,227,141, 55,174, 1, 24,206, 86,120,103, 96,184, 3,129,229, 86, 88,236, 6,208,130, 16,210,131,231,249, -145,249,249,249,159, 83, 74,215,223, 65, 65, 53,159, 16,178,249,252,249,243,175, 1,104,242,249,231,159,143, 6,112, 29,133, 38, -244,206,222,198, 43,248,224,115, 0,248,128, 16,178,230,173,183,222, 42,147,189, 8,157,133, 71, 2, 33,100,229,136, 47,230,141, -161,148, 54,229,169, 24,234, 32, 92, 38, 33,228,144,201,100,154, 70, 41, 61, 84, 74, 78, 10,224, 99, 66,200,250,231,158,123,238, -129,222,139,208,108, 54,219,123,245,234,245, 45,199,113,162,211,194, 35,152,205,230,254, 40,197,204, 83,111,156, 61,123,246,252, -158,231,121,187,211,194,195,153,205,230, 87,239,132,179, 12, 43,207,124, 0, 67, 75,122,166,110,221,186, 75, 54,108,216,208,175, -123,247,238, 14,171,213,154,218,173, 91, 55,225,192,129, 3,148,227,184,109,197,112,154, 81,204,142, 4, 18,202,149, 43, 87,105, -206,156, 57, 71,134, 15, 31,174, 95,182,108, 89,200,238,221,187, 29,179,103,207,206,205,204,204,252,140, 21, 79, 15, 22,100, 50, - 25, 52, 26, 13, 44, 22, 11,210,210,210,224,107,201, 41, 74,233, 5, 66,200, 83, 35, 71,142,108, 51,114,228,200,167, 98, 98, 98, -106, 87,172, 88,177, 34,199,113,220,205,155, 55,211,174, 95,191,126,197,106,181,254, 6,224,103, 0,242, 42, 85,170,252, 5, 96, - 73,113,124, 25, 25, 25,147, 8, 33,127, 44, 94,188,248, 41,173, 86, 91, 75,165, 82,133,216,108, 54, 46, 47, 47, 47,211,104, 52, -158, 50,153, 76, 27, 41,165,123, 75,153,238,207, 18, 66,218, 11,130,240,243, 55,223,124, 19,127,243,230,205,202, 59,118,236,232, -230,249, 92,227,198,141, 23, 46, 92,184,176,210,224,193,131, 47, 44, 91,182,172, 84, 99,176, 24, 24,152,192,242, 47, 51,174, 7, -176,190, 44, 62,236, 28,248, 56,214,121,148, 85, 37,121, 12, 64,191, 50,174,120,143,162,140, 7,104, 58, 11,167, 33, 15, 88,235, -220, 76, 8, 25,233,156,213, 4, 0, 35,255,250,235,175,185, 30, 22,169,191,221,239,251,178, 52,121,227, 60,122,244,168, 39,231, -241,210,112,222, 79,100,103,103,255,111,206,156, 57, 7, 19, 18, 18,148,175,188,242, 10,142, 31, 63,142,105,211,166,153,179,179, -179,151,221, 46,103,114,114,242,213,114,229,202, 53,154, 57,115,230,136, 25, 51,102,244, 32,132,176,189, 8, 31, 16, 24,141,198, -139,245,235,215,151,246, 79,165,118,187,221, 53,251,211,185, 34,255, 69, 63,242,149, 29,192, 31,206,195, 23, 62,241,131,111, 31, -128,125,101,156,247,175, 17, 66,158,186,114,229,202,148,179,103,207,110,242,246,204,137, 19, 39,214,117,238,220, 89,179,111,223, -190, 49,165,157, 69,200,192,192, 4, 22,195,127, 30,206,241, 79,223,185, 89, 95, 74,117,255, 94,113,222, 47, 36, 38, 38,102, 1, -112,109, 25, 18, 23, 23,119,203, 56,181,219, 21, 89, 40, 92,181,157,173,220,254, 0,225,210,165, 75, 79,252,135,242,254,181,146, - 26,167, 22,139,101, 3,128, 13, 44, 85, 48, 48, 48,129,197,112,251, 5,173,249, 78,238,223, 43, 78, 6, 6, 6, 6,134,135, 3, -132,144,215,125,212, 17, 95,253, 43,253, 5,160, 99, 49, 30,218, 86,138,192, 41,245, 70,155,190,248, 25, 39,227,100,156,140,147, -113, 50, 78,198,249,240,113,250,226,118,127,159, 16,242,250,191, 85, 96,129, 82,122,215, 14, 0, 29, 25, 39,227,100,156,140,147, -113, 50, 78,198,201, 56,111,243, 59,175,223,139,239,220,141,131,109, 40,203,192,192,128, 46, 49, 36,184, 75, 12, 9, 46,238, 94, -235,138, 36,136,133, 18, 3, 3, 3,131,255, 96, 99,176, 24,254,117,120,230,153,103,248,210, 60,127, 57, 40,136,203, 73,172,248, -153, 78,163,236,102, 48,153, 63, 59,255,243,152, 47, 30,134,112, 40, 95,190,124, 77,189, 94,255, 34,128,218, 6,131, 33, 66,163, -209,164, 2, 56,153,155,155,187,228,230,205,155,126, 47,247,209,190, 50, 25, 39,202,240,190,243,255,228, 63,174,208,137,158,247, - 4,128,182,171, 76, 62,220,126,133, 78,247, 91,180, 85, 37, 38, 10, 40, 9,129,117,243,121,234,218,224,242,241,106,196, 36,210, - 91,175,119,169, 70, 44,148, 66, 78, 0,243,230, 11, 84,197, 82, 58, 3, 3,195, 67, 47,176, 20, 10, 69, 29, 74,233, 0, 66, 72, - 57, 66, 72, 50,165,244, 59,139,197,114,226,191, 22, 88, 10,133,162, 14, 33,100, 0,165,180, 28,165, 52,153, 16,114,159,195,129, -144,213,207, 20, 90, 33,251,172,130, 8,248, 88,152,231, 63,136,203, 65, 65, 92,206,141,138, 95,245,239,209,244,149,247, 6,180, - 71,163,103, 63, 31,133, 82, 44, 98,251, 32,130, 16,194,199,197,197,189, 89,169, 82,165,231, 22, 44, 88, 32,143,139,139,131, 74, -165,130,209,104, 44,127,241,226,197,242,131, 7, 15,126,180, 74,149, 42, 43, 46, 93,186,244,165,115,141,184,226, 69, 80, 12, 9, - 22,101,120,127,199,220,193,114, 0,120,116,240,188,113, 26, 25,161, 70, 59,140,106, 1,234, 38,209, 24,183, 99,238, 96, 30, 0, - 30, 29, 50,239, 35,133,140,240, 86,123,145,197, 48, 19, 41,165,171,188,113, 83, 64,177,113,241,167,232,254,210,187, 2, 33,100, -132,116,253,201,234, 32,155,150,206,194,227,207,255,175,200,245, 46, 85, 32,252,180,248, 83,116,125,233,221, 98,119, 27,127,188, - 58,103, 19, 69, 90,108,185,197,113,196,190,249, 60, 77,240,114,203,171, 59,187,198, 11, 41, 86,155,195,235, 66,176,114, 25,159, -186,241,180, 61,146, 16,242, 12,128, 24,127, 57, 25, 24, 24, 24, 74, 20, 88, 42,149,234, 81,141,146,255, 18, 34, 13,210,105,213, - 1, 11,190,250, 90,217,245,169,174,252,198,159, 55, 58, 6,189,254,250,192, 96,157, 58, 15,160,217, 38,187,253, 77,147,201,182, -195,159,143,133,135,135, 31,226,121, 62,198, 75, 31, 43, 40,165,176,219,237,137, 57, 57, 57, 77,238,212, 83,209,141,159, 77,177, - 89,173,197,174,158, 45, 8,178,212,164,191, 86, 69,250,195,165, 82,201, 30, 85,242,194,151, 0,130, 2,180,154,128,249, 95,125, - 85, 24, 14, 27, 55, 58,222,120, 99,224,192, 80,189, 38, 15, 28,201, 54,152, 29,111,154, 76,166, 29,247, 46,234, 8, 89,189, 26, -156,180, 66,215,234,213,224,250,244, 33,255,105,145,149,158,158, 78, 0, 32, 44, 44,140, 22, 17, 87,221,155,190,242,254,235, 29, - 48,249,171,223, 96, 52, 91,150,254,219,253, 25, 23, 23,247,230, 51,207, 60,243,220,164, 73,147,228, 28, 87,216,203, 95, 80, 80, - 0,163,209,136,232,232,104,108,223,190, 93, 62,118,236,216,231,214,173, 91, 7, 0,179, 75,195,205,243, 60, 57,117,250,100, 92, - 72,100,148, 37, 51, 37, 73,241,234,227,181, 93,219,193,200,100, 50,114,249,242,249, 42, 1,129, 33,174, 93,177, 3, 2, 2,124, -231,251, 16,189, 57,239,175,196,106,210,249,208,142, 49,142, 98,174,155, 1,168, 75,226, 18, 69, 42,108,249, 98,112,177,247, 7, - 77, 93,225,200, 59,124,173,154,231,245,226,220,105,181, 57, 34,138,227,235, 60,108,158, 84,134,196,228,229,229,249,205,201,192, -192,192, 80,162,192,210,200,249,175,254, 88,183,184,106, 82, 74, 58,150,173,221,132,154, 53,227,113,242,212, 41,212,172, 25,207, -119,104,211, 76,211,165,101, 3,141, 90,198,149, 27,248,254,167, 95, 1,168,230,103,225, 29,147,152,152, 24, 65, 8,129,195,225, -112, 45,218,103,179,217,144,159,159,143, 6, 13, 26,148,137,167,108, 86,107,196,197, 63,127,132,140, 39,176, 59, 40,108, 14, 10, -171, 93,132,213, 78,145,107,176,227,177,167,250, 69,248,203, 37, 35,220, 87, 63,175, 92, 88, 53, 53, 51, 7,107,127,217,250, 79, - 56,196,199,243, 93,218,183,209, 60,251,212,163,154,176, 64,109,185,167, 94,122,219,239,112, 40, 11,172,126,230, 31,113,229,126, -173,207, 42, 56,254, 75, 9,248,244,233,211,188,217,108,126, 94,175,215, 55,151,201,100,145,154,160,242, 98,182,188, 74, 70, 1, - 41,119,201, 90,160,104, 59,160,103,213,199,199,188,214, 14,147,191,250, 13,223,111,248,115, 97, 96,244,245,113,255,102,255,150, - 47, 95,190,102,165, 74,149,138,136, 43,105, 83,243,220,220, 92,228,229,229,129,227, 56,140, 26, 53, 74,190, 99,199,142,231,202, -151, 47,191,173,164,238,194,205,137, 52,171,125,101, 50,249,209,193,243,198,241, 60, 79,228, 65, 49, 71,198, 79,158,150,171, 82, -169,168, 86,171, 53,134, 86,140, 63,242,216,208,175, 26,137,162, 72,131,162,107, 30,156, 49,107, 78,158, 86,171,165, 50,153, 76, - 57,124,248,112,191,198,112, 26, 77, 70, 12, 27, 54,204,236,228,164,102,139,217,117, 61, 33, 33,193,117,221, 98,181,248, 29, 14, -151,146,243, 32, 23, 56,200,101, 60,228, 2, 15,117,185, 26, 80,228, 95,134,213,106, 45,194,233,175, 59,127,255,251, 6,212, 10, - 25, 52, 74, 1,213, 98, 99,160,164,198, 91,158,121,237,181,215,196,192,192, 64,171, 78,167,147,127,248,225,135,108,252, 42, 3, - 3,131,111,129, 69, 8,121, 20,192,118,167, 37,137, 20, 94, 67, 64, 96,128, 14,115,231,127,141,145,163, 63, 66,205,154, 53, 65, - 41, 5, 33, 4, 9, 31, 76,192,140,137, 9,120,238,137, 71, 1,160,216,102,156,183,169,154,132, 16, 92,190,124, 25, 38,147, 9, - 70,163,209,117,212,169, 83,199, 47, 7,251, 59,253, 83,198, 19,252,124, 36,175, 80, 88,217, 68, 88,237, 34,108,118, 17,237,235, - 4,148,146,147, 4,104, 52, 90,172,249,114, 46, 70, 77,252,164, 72, 56,140, 26, 61, 22, 95, 78,255, 0,111, 15,122, 25,132, 20, - 13,135,187,177, 9, 38,227, 44,138,189,123,247,150,215,104, 52,159,247,235,215, 47,106,248,240,225, 10, 42,104,133,205, 7,174, - 6,126,250,221,111, 81, 38,139,149,127,170,117, 21,188,218,179, 9, 38,127,253,135, 83, 92, 93,123, 61, 54, 59, 91,252, 55,251, - 93,175,215,191,184, 96,193,130, 91,196, 85, 74, 74, 10,151,159,159, 15,171,213, 42,230,229,229,193,225,112, 32, 33, 33, 65, 54, -118,236,216, 23, 9, 33, 19,157, 60,102,111,156,127, 92,161, 19, 53, 50, 66, 79,157, 62, 25, 55,118,194,164,220,167,159,126,250, - 60,199,113,144,201,100, 56, 89,190, 60,237,249,212,227,167, 39, 78,154,100, 30, 56,232,205, 19, 28,199,129,231,121, 28, 59,118, - 44, 14,128,198, 31,191, 19,128,186,115,126,247,251, 28, 10, 0, 28, 33,244,133, 23, 94, 56, 47,113,158,223,248, 49,245, 55, 60, - 5,158, 32, 38, 76,251,207, 23,148,106,192,185, 43,166, 59,167,191,238, 20,120, 14,205,107, 58,219, 93,209,141,128,196,221,183, - 54, 58, 53, 26,235,243,207, 63,127,254,236,217,179,126,251,157,229,119,198,201, 56,253,135, 55, 45,242, 48, 88,176,182,123,243, -140,213,108, 68,157,138, 33,152,255,217, 36,136,148, 3, 5, 5, 21, 41, 40,117, 32, 54, 76, 11,179,161, 0,165,237,143, 18, 69, -209,181,213,196,130, 5, 11,144,159,159, 15, 81, 20, 81,171, 86, 45,136,162, 24, 66, 8,249,219,237,241, 52, 74,105, 39, 95,156, - 17,245,122, 94, 5, 69, 69,247,107, 31,126,242, 45,246,254,117, 17,162, 8, 40,213, 26,244,121,241, 13,216, 29, 20, 22, 91,233, -246, 39,165, 16, 97, 54, 26, 16,165,147, 97,230,148,113, 32,130, 12, 60, 33, 32,132,128, 35, 34,106, 70, 7,193, 98, 50,220,243, -136,235,179, 10,226,234,213, 69,103,129, 22,142,195,250,239, 88,174, 52, 26,205,231, 75,150, 44,169,212,180,105, 83, 14, 0, 14, -158,203, 82,126,250,221,111, 81,223,142,239, 69, 26,213, 44,135,140, 28, 35, 38,127,179, 3,191, 31, 73,218,228, 41,174,254,197, -168, 29, 23, 23, 87, 68, 92,125,250,233,167, 97,115,231,206,141, 6,128,167,159,126,250, 70,135, 14, 29,210,207,158, 61,139,242, -229,203,147,244,244,244,167, 0,252,207, 89,120,141,164,148,206,245,106,101,178,195, 24, 18, 25,101, 81, 40, 20,144,132, 16,199, -113,224, 56, 14, 33,145, 81, 22,173, 62,216,226,121,189, 52,112,127,215,159,235, 62, 11,174, 18,158,191, 29,119,242,156, 91,241, - 39,120, 31, 2, 38,133, 77,105,221,202,192,192,224, 55,182, 63, 12,194,202, 83, 96,185,212, 35,165,116, 71,161,122, 4, 44,102, - 35, 98,130, 20, 40,167, 19, 96,179,217,177, 35,137, 71, 78,190, 9, 54,155, 21,169,201, 54, 28,188,113, 12,117, 27, 52, 14,111, -209,162, 69,158,205,102, 3,199,113,233, 7, 15, 30,140, 43, 65,241, 66, 20, 69, 88,173, 86, 88,173, 86, 20, 20, 20, 96,233,210, -165, 16, 4, 1,162, 40,226,131, 15, 62, 16, 40,165,245,164,231,149, 74,229, 49, 63, 85, 80,197, 11, 7,215, 32, 64,197,195, 46, - 82,216,237, 20,118, 17,176, 59, 40,140, 86,138, 94, 3,222,135,195, 65,225, 16, 41, 44,118,223,146,208, 93,176,169,171, 60,137, -238, 9,203, 1,232, 92,247,245, 74,138, 81,173,120, 40, 20, 50, 40, 20, 2, 76, 6,163,207,141, 95,203, 30,148,246,233, 67,196, -255,234, 32,119,179,217,220,183, 95,191,126, 81,146,184, 2,128,172, 92,179, 96,178, 88,249, 70, 53,203,161,211,115,239, 98,235, -138, 79,241,235,158,115, 8,214, 9, 59, 99, 30, 14,113, 5,131,193, 16,161, 82,169, 80, 80, 80,224,178, 92,205,157, 59, 55,218, - 98,177,112, 0, 32, 8,178,152, 52, 49, 90,229, 16,129, 64,253, 77,100,101,229,132,254, 99,149, 38,159, 16, 66,190,243,182,114, -190, 90,128, 58, 35, 37, 73,161, 84, 42, 77, 60,207, 67,178, 0,241, 60,143,204,148, 36, 5, 47,218,168,251,117, 65,240,127, 2, - 50, 33, 4,238,239,250,186,238, 87,193,197,147, 34, 5, 64, 17,177,116, 27,238, 20,120, 55,209,196,123, 23, 88,114,185,156,202, -100,178, 82,187,149,129,129,161,244,150, 44, 73,139, 60, 52, 2,203,105,154, 35, 82,161,101, 53, 26, 97,179,217, 97,183, 59, 96, -179, 59,144, 83, 96,197,119, 11, 23, 65,161, 80,128, 16, 2, 81, 20, 97,183,219,137, 40,138, 58,187,221,142, 71, 30,121,132,148, - 44, 9,104,145,113, 87,148, 82,240, 60, 15,153, 76,118,203,179, 86,171,181, 84, 30, 9, 80,241,136,237, 56,250,150,235, 7,214, - 76, 2,165,128, 67,116, 10, 44,171, 31,245,172, 15,193,214,160,109, 31, 88, 44,214, 66,139, 30,165,133,150,188,251, 34,109, 40, -253,175,141,185,114,179, 38,116, 28, 62,124,120,145,154, 48, 88,175,180,171, 20,114,199,145,211, 55,201,214, 21,159,114,135, 78, - 37,137, 10,153, 64,181, 52, 57,238, 97,241,183, 70,163, 73, 53, 24, 12,229,141, 70, 35,114,115,115,145,155,155, 91, 52, 67,203, -100,228,245, 65, 67,195,100,114, 5,108, 86, 11,126, 93, 50,217, 39,103,251,202,100, 92,147,104,140, 27,248, 68, 29, 4, 70,215, - 60,124,186, 74, 21, 81, 18, 40,127,254,186,184,213,186,153,111, 53,162,148, 34,239,250,177,131,173,122, 14, 60, 32, 8, 2,204, -102,179,223,203, 40, 80,128,156, 62,125, 58, 78,226,164,206, 50,134, 2,228,232,209,163,113,130, 32, 64, 16, 4,215,117,191,226, - 95,165, 1,116,229, 0,165,180, 60, 23,113,137, 54,119, 78,127,221, 89,187, 74, 20, 80,174, 30,160, 8, 44,246, 25,153, 76,166, - 56,118,236, 88,156, 40,138,108, 9, 9, 6,134,187,108,201, 66, 41,202,131, 7, 93, 96,181, 35,132, 80,143, 66, 17,102,147, 1, - 54,187, 3,118,155, 3,118,187, 29, 86,139, 21, 42,149, 10,122,189,222, 37,152,164, 35, 45, 45,205, 47, 81,100,183,219, 93, 22, - 44, 81, 20, 65, 41,197,249,243,231, 33,147,201, 32,151,203, 33,147,201, 32,147,201, 80,184,129,189,255,176, 59, 40,198,188, 55, - 2, 50,129,131, 92,224, 32, 19, 8,228, 2, 7, 7,165,160,160,176, 59, 10, 15,139,221, 63, 67, 70, 73,130, 13, 0,204, 22, 91, - 97,187,153, 2, 6,131, 1, 34,216, 10, 9,247, 10,233,233,233,196,104, 52, 86, 14, 10, 10, 42, 34,222,195, 53, 14,115,255,110, - 13,146,250,127,248, 99,148,197,102,135, 92,224,105,223,206,241, 73,191,173,221, 30,154,110,206, 38,210,236,194,127, 57, 78, 94, -184,112,161,124,133, 10, 21,144,155,155, 11,187,221, 46, 62,253,244,211, 55, 4, 65, 22, 35,200,100,164,235,243, 67,197,228,228, - 36, 27,199,241,160,212,129, 39,158, 25, 76,148, 42,181,220,106,177,216, 1,140,244,180, 94,185, 45,211,192, 3, 64,199,255,125, -211,232,153,167,123,158, 14, 8, 12,177,101,166, 36, 41,214,205,124,171,209,239,115, 94,231, 0,224,177,161, 95, 61,242,193,103, -223,157, 15,137,140,178,148,198,193, 42,165, 10,175,189,246,154,107,204,210,161,165, 99, 1, 0, 74,133, 18,207, 61,247,156,235, -250,111, 95,250,191,215,117,160,146, 2,249,201, 64, 65,178,167, 8, 42,194,233, 47,180,130, 29, 72, 62, 82,226, 51,206,129,237, - 26,150, 3, 25, 24,238, 26,110,209, 34,255,122,129,229, 52,197, 17,207,102,167,217,104,132,221,102,119,137, 44,139,165, 80, 64, -109,219,182,237, 22, 65,228, 79, 23, 25,165, 20,102,179, 25,113,113,113,176, 88, 44,136,143,143, 7,165, 20,213,170, 85,243, 42, -196, 74, 3,155,131, 98,202,244,207,110,185,190,123,213, 36,212,143,143, 69,179,106, 26,152,108, 34,114, 10,252,227, 45, 73,176, - 1, 40, 12, 11,167,184, 52, 22, 20,128,233,171,251, 7,155,205,134,172,172, 44,152,243,179,236, 53,202,209,156,215,186, 86, 49, -167,101, 26, 4,142,154,236, 49, 1, 6,115,126,230, 13, 94,163,121, 56,234,197,220,220,220, 37,131, 7, 15,126,116,231,206,157, -114,142,227,144,155,155,139,246,237,219,167,167,137,209,170,215, 7, 13, 13, 75, 74,186, 97,215,171, 5,179, 92, 46, 67,106,106, -170,248,232,147,253,140,207, 15,120, 43,234,173,247,167, 46, 72,218, 51,247,150,241, 87, 6, 14, 84,112, 75,189,118,135, 3, 19, - 39, 78, 52,235,131, 66,173, 28,181, 57,168, 91,198,166,148,210, 5, 95,127,101, 10, 9, 47,111,150,203,229,202,254,253,251,251, - 61,139, 48, 33, 33,193,172,209,104,168, 90,173,118,205, 22, 52,153, 77,152, 56,113,162, 89,171,213, 82,141, 70,227,215, 44, 66, -142, 35,246, 65, 83, 87, 56,220, 27,115, 82, 99, 76, 38,147,193,234, 32, 5,238,156,254,186,211,159, 89,132,195,134, 13, 19,131, -131,131,173, 1, 1, 1,242, 17, 35, 70,176,129, 88, 12, 12,101, 12,175, 90,228, 33,176, 96,221, 2, 17,133, 93, 95, 54,155,195, -217, 69,104,135,197, 98,129, 40,138,104,221,186,245, 45,207,103,101,101,249,180, 58, 57, 28,142,196, 90,181,106,185,172, 94, 14, -135, 35,100,236,216,177,194,213,171, 87,161, 80, 40,138,136,182,219,177, 96,141, 31,251, 46, 20, 50,222, 41,136, 10,133,145, 72, - 41, 54,252,188, 5, 27,126,222,226,122,150,231,101,169,119, 34,216, 0,192,108,182,129,210,194,154,201,152, 95,112, 31,198, 96, -253,119, 17, 22, 22, 70,211,210,210,174,100,103,103,215,208,106,181,200,200,200, 64,102,102, 38,178,179,179, 97,204,205,178,107, -237,217, 5, 22,123, 38, 4, 65, 64,242,245, 20, 56, 28,142,228,135,196,122,133,155, 55,111,158,169, 82,165,202,138, 49, 99,198, - 60,159,144,144, 32, 19, 69, 17,103,207,158, 5, 8,161, 50,185, 52, 64, 93, 64, 78, 78,174,168,209, 5,221,180, 82, 94, 35,147, - 43,192,241,114,175, 93,201,187,175,209,236,118,149,201,135,143, 14,153,247,145, 76, 46, 39,250,168, 26,251, 95, 25, 48,240,148, - 52, 72, 60,235,210,145,253, 29,255,247, 77, 51,135,195,129, 6, 45, 59,254,242,234,235, 67, 78,202,100, 50, 28, 58,116, 40,206, -151, 53,135, 0,246,158,175,140,226,117, 58, 77,254, 11, 47,188,112, 94,226,188,188,245,203,252,151,135,142, 3, 47, 83,230, 15, - 28, 56,208, 53,187,240,212,250, 79,242,123,190, 50, 74, 73, 80,124,183,247,230,243, 52, 33,239,240,181,106,239,190,251,174,249, -149, 87, 94,113,113, 30, 59,118, 44,238,233,167,159,214,124,248,225,135,102,119, 78,127,220, 9,248, 55,139, 80,171,213, 90, 95, -125,245,213,243,222,102, 38, 50, 48, 48, 48,248, 45,176, 64, 81, 40,176,236,118,216,109,133, 99,176,108, 54, 27,236,118, 59,254, -252,243,207, 34, 98, 72, 46,151,251, 53,179, 38, 51, 51,179,200, 34,162,132,144,191, 41,165,245, 42, 87,174,236, 18, 40, 99,198, -140,193,132, 9, 19, 74, 61, 83,199,230, 0, 38, 76,254,204,197,243,100,167, 54,232,241,196,163,160, 98,161, 80, 75, 61,190,174, - 84,138,173, 36,193,230,178, 96,129, 2,148, 34, 63, 47,143, 25,176,238, 49, 44, 22,203,182,217,179,103, 87, 30, 59,118,172, 34, - 51, 51, 19,233,233,233,200,202,202,114, 29,249,249,249, 40, 87,174, 28, 54,109,218,100,205,205,205,221,255, 48,249,253,210,165, - 75, 95,110,216,176, 1, 59,118,236,120, 46, 33, 33, 65, 86,174, 92, 57, 18, 24,152, 66,108, 86, 11, 0, 74,211,210,210, 68,141, - 46,232,102, 88,100,204,181,164,228,212,120,155,213, 2,209, 97, 45,118,100,246,246, 43,116,186, 66, 70,248,203,151,207, 85,153, -254,201,231,249,146,104,145,201,100,104,217,253,213, 67, 31,206, 90,124, 97,198,140, 25,150, 65, 67,134,157,148,238,249, 51,208, -123,203, 69,140,206,203,203,169,246,254,251,239,155,221, 57, 31,123,227,211,101,189,122,245,210, 76,153, 50,197,236, 62,227,175, -219,136,249,203, 58,116,232,160, 9, 8, 8, 56,239,139, 91,106,144,121,206, 66,244,156, 5,233,239,128,116,127,103, 17, 2, 40, -213, 0,127, 6, 6,134,255, 46,184,226,245, 21,205, 79, 76, 78,129, 32, 87, 3,188, 12, 14,135, 8,139,197, 2,135,195,129,166, - 77,155,162, 65,131, 6,168, 85,171, 22, 22, 44, 88, 0,141, 70, 3,142,227,110,177, 58, 17, 66, 58,250,114,128, 40,138, 48, 26, -141, 48,155,205,176, 90,173,152, 56,113, 98,137,133, 98,113,156, 5,102, 7,246,172,156,136,221, 43, 63,194,206, 21, 31, 97,100, -255,142,168, 18, 33,247,107,214,160, 55, 78, 73,176,141,254,112, 58, 70,188, 63, 21, 91,126,223, 13,158, 39, 46,193,166, 10, 8, -134,160,208, 2,130, 2, 55, 82,210, 64, 69,154, 95, 90,191,151, 22,140,243, 31, 40,149,202,101,203,151, 47, 79,218,181,107,151, - 24, 21, 21, 5,142,227,144,159,159,143,252,252,124,201,202,133, 83,167, 78,137, 87,175, 94,189,161, 84, 42,151, 63, 76,126,167, -148, 58, 46, 94,188, 56, 59, 57, 57,249,213,113,227,198,109,123,225,133, 23,228, 63,206, 31, 27,250, 98,151,234,216,190,105, 53, - 33,170,144, 2, 11,149,171, 18,111,166,212,252,253,231,165, 33, 47,118,169,142,228,125, 11,222, 32,132, 12, 41,142,211,106,135, - 37, 32, 48,196,166, 86,171,169,231, 50, 7, 1,129, 33,182,128,192, 16,139, 55, 65,227,143,223,189,113, 2,128, 74,165,162, 15, - 10,167, 63,179, 8,149, 74, 37, 45,173, 59, 89,126,103,156,140,147, 89,176,110,129,217,108, 31,242,193,130,245,115, 1,162,147, -134,104, 84,140,171, 22,110,181, 90, 73, 74, 74,138,203, 82, 36, 8,194,109,173, 99,227, 68,154, 86,171, 45,105, 41,134, 52,255, - 98, 26,215,154,180,127,182, 98, 73,247, 75,235, 48, 73,176,137, 20, 16, 11, 13, 85,160, 32, 46,193,246,233,154,223, 82,157,137, - 12, 0,201,183,217,197, 33, 44, 57,221, 59,196,199,199, 59,246,238,221,251,206,224,193,131, 63,239,208,161, 67,116,143, 30, 61, -228, 21, 42, 84,128, 82,169,196,197,139, 23,177,107,215, 46,235,165, 75,151,110, 24, 12,134,119,234,215,175,255, 80,206,180,188, -121,243,230, 25,231, 34,162,255,147,150, 98, 80,170,212,242,190, 3,222,138,113,205, 34, 92,241, 37,204, 38, 35, 0, 8, 37, 45, -211,224, 42, 16, 4, 65, 33,205,194,227, 56, 14, 22,139, 69, 37, 93, 63,116,232, 80,156,180, 4,130,116,221,175, 66,230, 95,192, -233,207, 44, 66,185, 92,174, 56,124,248,112, 28,165,108, 35,106, 6, 6,134, 59, 17, 88, 54,219, 54, 0, 85,221,175,213,170, 85, - 43,169, 73,147, 38,129, 64,225, 98,126,162, 40, 22, 17, 86, 60,207,231,149,230,227,254, 44, 34,234, 15, 82,143,173,171, 84,182, -210,220,183, 96, 43, 48,219, 42,177,228,115,127,209,178,101,203,155,167, 79,159,238,183,117,235,214,190, 59,119,238,236,104, 48, - 24, 42, 19, 66,160, 86,171,175, 88, 44,150,109, 74,165,114,217,195, 42,174,138,131,213,106,181, 39, 76,248,116, 17, 47,200,237, -162,104, 37, 86,171,117, 0,252,220,212, 29, 0,222,123,239, 61,175, 51,229,134, 13, 27,118,219, 51,232,254, 13,156,254,204, 34, -124,231,157,119,216, 44, 66, 6, 6,134, 59, 23, 88,222,112,234,212,169,168,255, 66,160,148,185, 96, 99,184,107,136,143,143,119, - 0, 88, 2, 96,137,231,102,207,255, 5, 80, 74,205,132,144,145,132,144, 79,156,151, 70, 94,250, 99,150,107,182, 32, 33,179,143, -185,223, 43,193,122,149,120,155,155, 23, 39,150,116,239, 65,231,148,203,248, 84,183, 77,157,111,185,231,227,155,137, 44, 7, 50, - 48, 48,148,137,192, 98, 96,120, 16,176,106,213, 42, 7, 11,133, 34, 34,107, 46, 33,228, 59, 73,112,249,123,207,227,185, 85,119, -193, 93, 15, 60,231,198,211,246,200,251,225, 15, 6, 6, 6, 38,176, 24, 24, 24,254, 29, 34,203,124, 59,247, 24, 24, 24, 24, 24, -238, 14, 8,128,142,197, 20,202,126,239,148,125, 59,179, 9,124,241, 51, 78,198,201, 56, 25, 39,227,100,156,140,243,225,227,244, -197,237,254, 62, 33,228,117, 74,233, 87,255,214,150,239, 93, 59, 0,116,100,156,140,147,113, 50, 78,198,201, 56, 25, 39,227,188, -205,239,188,126, 47,190,115, 55, 14,182,221, 3, 3, 3, 3, 3, 3, 3, 3, 67, 25,131,141,193,242, 19,164, 82,207,177, 16, 49, -166,240, 4, 31,211,107,235,198,179, 80,185, 61, 52,212,145, 48, 27,145,117, 13, 80,201,186, 87, 14,144,181,184,152,109,222,107, -176,138, 63, 81, 98, 91,127, 50,151,102,177, 16, 98, 96,184,251, 8,142,107,213, 47, 52,172,220, 27, 34,165,106, 0,176, 88, 76, -182, 27,215,175,205,162, 89, 39, 87, 20, 41,251, 66,106,245, 41, 23, 21, 51, 76,173,210,170, 11,139, 63, 98,201,204, 72,158,155, -117,105,207, 15, 94,203,202,127, 86,156, 14,186,112,225, 66,165,170, 85,171, 94, 5,144,237,241,216, 45,247,104, 9,251,141, 17, - 66, 72, 88, 92,163,151, 52, 42,205, 16,139,197, 18,171, 11, 8, 72,205,204, 72,155,159,121,237,216,151,110,143,233, 15, 28, 56, - 80,190, 89,179,102, 73, 0,242,124,113, 50, 48, 60,240, 2,171,105,211,166,177,162, 40,190, 12,224, 5, 74,233,209, 35, 71,142, - 60,125, 59, 60,205,154, 53,139,118, 56, 28,143, 80, 74, 27, 1,104,164,214,232, 26,154,205,166, 84,209, 97,127,233,240,225,195, -127,149,150,175,113,227,198, 63, 3,120,178,152,204, 58,225,208,161, 67,165, 19, 72, 34,125,255,207,157, 63, 42,131, 52, 4, 85, - 27,247, 30, 5,224,129, 20, 88,132, 16, 53,128, 87, 8, 33, 29, 52, 26, 77,117,131,193,112,133, 82,122, 12,192, 92, 74,105,210, -109,114,114,117,116,178, 87, 53,106,205,227,229,181,138, 70, 55,179,115,111, 24,108,226, 46,145, 88, 63, 41,173, 32,170, 74,136, -162, 74,133,160, 29, 35,122,180,137,175, 31, 95, 5,142, 19, 59, 97,177, 90,187, 31,186,105,232,190,224,175,148,119,170, 18,210, -232, 2,165, 22, 63,221, 85, 30,128, 64, 41,189,238, 60, 15, 6,208, 6, 64, 3, 0, 71, 1,236,162,244,206, 4,219,191,133, 51, - 38, 38, 38, 74, 20,197,215, 34, 35, 35,159, 74, 73, 73,249,153,227,184,111, 18, 19, 19,147, 88, 17,199, 80, 28, 66, 66,203, 13, -153,243,221,106,215,178,245, 84, 20,101,207,247,104,247, 34,128, 34, 2, 43, 40, 40,244,149,239,151,253,170, 38,255,172,121,168, - 24, 58,160,207, 27, 0,126,240, 38,132, 40,165,152, 48, 97, 2,153, 56,113, 98,255, 42, 85,170, 84,227, 56,238,236,184,113,227, -102,185, 63,231,121,239,195, 15, 63,164,206,119,169, 55,206,152, 26, 45,215, 63,247,252, 51,237,222,124,253, 21, 93,116,184, 14, - 55,211, 11, 66,231,125,187,228,211, 37, 75,126,232,250,218,115,157, 30, 7,128,143, 62,250,168,103,133, 10, 21, 42,243, 60,127, -249,131, 15, 62, 88, 92, 18, 39, 3,195, 3, 43,176,106,215,174,173, 85, 40, 20,125, 56,142,123,165,126,227, 22,173,187, 63,243, - 10,177, 17, 13, 38,191,219,215, 94, 90,174,118,237,218, 41,243,243,243, 39,197,214,108,252,118,187,206, 61,184, 90,241, 53, 17, - 22, 26, 12,145, 83, 96,225,166,115,161,219, 23,244,159, 11,160,217,109, 56,243,201,149,191, 28,192,205,108, 7, 8, 1, 8, 1, - 56, 2,228,155, 68,140, 25,208,250,195,210, 11, 36,194, 5,105, 8,222, 94,102, 2, 0,254, 65,140, 76, 66, 72,163,240,240,240, - 47,135, 15, 31, 30, 92,175, 94,189,242, 42,149, 74, 99, 52, 26,171, 93,184,112, 33,118,236,216,177,157, 8, 33,211, 40,165, 63, -150,134, 51, 62, 72, 85,241,137,154,149, 86,190, 55,232,149, 71,106, 84,174, 0,193,156, 15,209, 92, 80,225,234,165, 11, 45,166, -124,255,227,192, 58,129,178,231, 79,228,216,252,158, 16,161, 10,144,191, 63,230,213,190,241, 85,181, 20,150,227,123, 32,227,121, -168,244,193,104,198,243,224, 8,173,245,225,174, 27, 99, 0,124,232,135, 95, 39, 2, 24,227, 44,127,127,228, 56,238,108,199,142, - 29,235, 15, 28, 56,144, 52,104,208, 0, 71,142, 28,105,184,124,249,242, 1, 60,207,255, 45,138,226, 31, 0,246, 83,255,133,155, - 2, 64,115,142,227,218, 63,200,156, 81, 81, 81,106,139,197,242,114, 76, 76,204,235,221,187,119,175,215,173, 91, 55, 82,163, 70, - 13,156, 57,115,166,241,175,191,254,250, 97,131, 6, 13,142, 37, 38, 38,126,165, 80, 40, 22, 37, 37, 37, 25,253,225,252, 63,123, - 87, 29, 30,197,241,191,223, 57,247,248,197,133, 64,136, 64,208,224,238,110,165,184,151, 22,105, 11, 45, 82,188,184, 21, 43, 94, -164, 20,247, 22,183,226, 82, 60, 72, 32,144, 64,136, 16,119,185, 92,206,111,231,247, 7, 9,223,144, 70, 46,129,254,218,210,125, -159,103,159,189,155,221,125,119,108,103,223,253,204,204,103,250,215, 32, 97, 7,158, 80,255,138, 30, 47,146,102, 27, 0, 18, 75, -132, 61, 33,196, 9,128,140, 82,250,234,255,155,243, 47,122, 22,159, 17, 66,236,242,127,163,180, 61,135,195,129,201,100, 82,155, - 76,166, 42,101,112,250, 1,229, 26,214, 65, 41,165, 97, 37, 30, 4, 21, 2,192,226, 57,147, 17, 31, 27, 3,141, 86,173,201,202, - 74,223, 81,244,188,172,204,140,221,159, 15,238,246,141, 80, 40,230,187,121,120, 97,198,188, 21, 40,176,122, 21,135,121,243,230, -145, 57,115,230, 96,238,220,185,221, 1, 52,103, 24,230,122, 64, 64,192,218,119,190, 87, 25,230,237,177, 57,115,230,172,153, 55, -111, 30, 1,138, 95,210,213,174, 82,237, 33,159,124,210,179,213,162,153,227,228,241,233, 6, 60,138,210,192, 78, 46,192,156,239, -198, 10,117, 58, 99,227,141,187,118,143, 90,191,116,234, 86,179,217,220, 6, 64, 61,179,217,124, 31,192,174,210, 56, 89,176,248, - 71, 9, 44, 66, 8, 9, 10, 10,106, 65, 41, 29, 94,169,178, 79,159,222,131, 70, 75, 42, 85,173,129, 92,198, 10, 81,105, 12, 30, - 92,222,135,162, 95, 62, 22, 88,191,234,113, 56,220,157, 99,167,173,242,175, 85,167, 62,158,196,155,240, 71,172, 25,121,175,204, -224,114, 52, 96, 24, 0,128,182,162,137,139,203, 52,225, 70,184, 30, 28, 2,112, 57, 0,135, 67,192,173,232,168, 51, 70,255, 98, -193,246, 7,129,105,201, 12,192,232, 95,252, 3,197, 85, 27, 95, 95,223,213,243,231,207,119, 78, 78, 78,182,187,127,255, 62, 68, - 34, 17,108,109,109,121,174,174,174,254,171, 87,175,206, 30, 55,110,220,119,132,144,135,148,210,104,139,132,180, 92, 24,208,178, -110,224,205,217,115,231, 88,235,239,156, 65,230,190, 67,224,114, 40, 4, 50, 57, 92, 37, 18,172,237, 80,201,110,234,165,216,223, -106, 74, 36, 1, 33, 26, 77,188, 37,156, 30,142,118, 29,170,250,249, 35,243,200,122,188,204,209,225, 86,170, 14, 61, 91, 54,128, -143,157, 4,181, 77,102,216,139,121,109,202, 18, 88,249, 22,160,169,122,189,158, 35, 16, 8,136, 88, 44,238,115,242,228,201, 75, - 1, 1, 1,111,235, 74,179,102,205,208,172, 89, 51,178,108,217,178,218,151, 46, 93,170,189,123,247,110, 3, 33,228, 6,165,116, -117, 73,188, 18,137,244,181, 86,171,241,144, 72,165,250, 77, 63,253,116,177,105,211,166,180, 96,129,223,138,114, 2,128,181,181, -245,111,129,129,129, 14, 83,166, 76, 81, 53,105,210,228,131,112,122,123,123,255,222,188,121,243,214, 29, 58,116,224, 53,109,218, - 20,174,174,255,243, 1,236,224,224,128,230,205,155,147,216,216,216, 90,215,175, 95,223,248,251,239,191,175,245,246,246,190, 28, - 21, 21,213,161,204, 55, 50,224,247, 62,199,139,128, 11, 96, 49, 33,100, 43,165,244,143,210, 62, 12, 0, 12, 2,240,195,223,196, - 89, 42, 36, 18, 73,178, 86,171,117, 4, 0,177, 88,156,162,209,104,156, 44,120, 30,229,155, 55,111,118, 20, 8, 4,224,112, 56, - 48, 26,141, 48,155,205,111,247, 5, 27,195, 48, 48,155,205, 88,180,104,145, 69,190,221, 40,165,106,188,153,253, 77, 11,109, 76, -113,123,161, 80,232, 96, 9,103,124,108, 12,180,241,183,211,229, 50,153,151,220, 30, 11,124,125,125, 23, 20, 62, 94,213, 1,128, -246, 21,212,105,234,152,120,192,190, 12, 58,155,249,243,231, 15,155, 59,119,110, 79, 0,234,252,176,154,125,251,246,189, 92,228, -188,154,249,123, 53, 33,228, 10,135,195, 57, 1, 96, 59,128, 63, 89,114,165, 82,249,232,241, 95,126, 46,143, 75, 51, 96,225,111, -105,216,126, 45, 7,195,154, 43, 48,161,179, 53, 6, 13,236, 47, 59,244,235,225,209, 0,182, 22,186, 36, 44, 32, 32,128, 60,127, -254,156, 21, 87, 31, 23,234, 3, 80, 22,250,175, 7, 80,208,152,166,229, 63, 23,246, 69,194, 11,159, 87,176, 47, 88,130, 79,153, -127, 29, 45,196,155, 10,224,222, 7, 21, 88,249, 86,212, 2,107, 42, 41,238,196, 58,117,234,156,238,252,201,208, 78,141, 90,116, -128, 73,224,136,176, 20,130,216,104, 10, 30,199, 4, 46, 24, 68,222, 59, 70, 57, 28,206,206, 34,141, 65,137,150,141,160,160,160, - 73,149,124,235,254, 48, 99,238, 18,238,147,100, 33,182, 95,215,128,209,101, 35, 47, 45, 2,234,148, 23, 80, 37, 61, 67, 86,252, -147, 16,134, 97,230, 88,202,249,231,198, 8, 48, 51,249,223,124, 76,254,235, 1,164,184, 70,171,108, 78,131,250,121,101,191,192, -192, 76,161, 25, 48,168,159, 91,208, 16, 94,248,208,181,171, 36, 78, 66, 72,123, 31, 31,159,229, 51,103,206,116,127,250,244,169, -149, 90,173, 86,159, 57,115,230,106, 76, 76,140,147,179,179,115,236,216,177, 99,155,184,185,185, 57,126,242,201, 39,210, 3, 7, - 14,204, 4,240,121, 89,156, 53,100,194,192,230,245,107,220, 90,184,108,165, 44,237,208, 58,232, 35, 30,227, 86,154, 6, 33,233, - 26,234,166,200, 34,253, 2,236, 32, 21,242, 48, 58,200, 73,254,205,185,168, 31,242, 95,102,101,166,221,219,197,169,138, 81,147, - 7,173,198,136,211,175,178, 53,183,114,178, 29, 57,143, 95,167, 78,233, 94, 95,204, 77, 77,128,179,156, 95,181,188,249, 73, 8, -129, 84, 90,252, 10, 38, 54, 54, 54,104,213,170, 21, 2, 2, 2, 4, 45, 91,182,108, 3, 96,117, 73,156, 6,131,222,133, 97, 40, -172,172,172, 4,157, 58,117, 34,132, 16,170,215,235,223,139, 19, 0,236,236,236, 58, 54,107,214,140,251,235,175,191,230,102,100, -100, 68,119,237,218, 53, 77, 44, 22, 51,133,207,145,201,100,240,245,245,197,247,223,127, 47,232,220,185,115,153,156, 78, 78, 78, -237,119,239,222, 13, 66,200,219,151,117, 81,120,121,121,193,217,217, 25, 93,186,116,225,125,250,233,167,237, 75,203,207,254, 53, - 72, 88,129,120,234, 87,131,148,250, 98,234, 87,131, 80, 2,132, 23,181,100, 21,229,164,148,166, 19, 66, 54, 1, 56, 66, 8,233, - 83,156, 32, 34,132, 52, 5,112, 24, 64,103, 74,105, 74, 89,229, 94,152, 83, 40, 20, 10, 12, 6,131,109, 81,225, 83, 94,206, 66, -113,161,193,193,193, 8, 10, 10, 66,225,189, 86,171,125,187,246, 42, 33,196,209,210,250,201,225,112, 48,107,214, 44, 16, 66,192, -231,243, 33, 16, 8,138,221,183,106,213,170,188,109, 72, 44, 33,132, 35, 16, 8,166,242,120,188,207,117, 58,157,187, 88, 44, 78, - 48,155,205, 59,116, 58,221, 34, 74,169, 17,128,141,193, 96, 40,149, 83,163, 85,107, 40,195, 72,244,122,173, 81, 38,147,121,189, -120,241,194,183,164, 50,215,233,116,168, 89,179, 38,114,181,234,212,130,107,138,227,140,136,136,240,170, 82,165,138, 31,222,116, -129, 3,192, 53, 74,105,139, 66,255, 11,227, 26,165,180,115,254,239,240, 87,175, 94,121, 21, 8,172,194,156, 70,131,193,219,221, -209, 10,143,162, 53,216,126, 45, 7, 23,103,186,162,237,162, 4,244,174,203, 67,128,167, 28, 38,131,209,175,111,223,190, 59,241, -166,254,222, 3,208,171,111,223,190,254, 92, 46,247, 18,128,163, 0,178,255,191,219,100,150,179,194,134,130,210,180,136,146, 16, -114,178,208,253,187, 21,252,159, 54,109,218,140, 37, 75,150, 60, 37,132,156, 44, 28, 94,248,188,194,251,252,123,157,164,148,118, -155, 62,125,122,224,210,165, 75, 23, 23,156,251,183, 88,176, 0, 88,197,105,108,144, 27,229, 0, 30,151, 1,143, 67,192,227, 2, -160, 4,201,113,207,160, 87,167,223,184,127,255,126,148, 37, 68, 65, 65, 65, 77, 43, 7, 54, 90, 54,119,225, 10,206, 47,215, 52, -200,206,211, 34, 45,244, 56, 18,239,108, 75, 98,204,134,163,148,210,251, 28, 14, 39,216,187, 82,165,176,247,241,218,253, 70, 96, -229,139,170,119, 68,214,199, 3, 66, 72,103,127,127,255, 37,179,102,205,242,122,248,240,161, 34, 39, 39, 39,117,207,158, 61, 97, - 58,157,238, 33,128, 53,175, 95,191,110,185,102,205, 26,233,138, 21, 43, 58,212,168, 81,195,239,224,193,131,121,101, 90,174,100, -130, 90, 67, 7,245,191,213,115,204,120,113,232,193, 13, 16, 61, 11,198,230, 23,153,230,251,169,154,153,218, 92,211,106,137,148, -215, 52, 83,103, 58, 63,185,161, 43,199, 69,198,135,135, 21,191,149,165,241, 21, 10,197, 60,202, 19, 67,175, 55, 65,109,100,244, -161,169, 84, 61,177,101, 77, 3,149, 57,188, 89,172,151,195,225, 89,240, 96,103, 18, 66,126, 16, 10,133,179, 8, 33,180,103,207, -158,209,117,235,214,213, 2,128, 70,163,129, 78,167, 3,159,207,135, 86,171, 69,100,100, 36,110,223,190, 13, 91, 91,219,114,229, -107,102,102, 38,188,188,188, 32,151,203,223,155,211,108, 54,147, 13, 27, 54, 8,159, 62,125, 42,252,245,215, 95,173, 38, 79,158, -172,110,216,176, 97, 76,215,174, 93, 83,172,172,172, 76,143, 30, 61,194,173, 91,183,144,149,149,133, 6, 13, 26, 88,196,169,215, -235,193,227,241,160,209,104, 32, 18,137,192,227,241, 96, 50,153,192, 48,204, 91,209,149,155,155,139,140,140, 12, 8, 4, 2, 20, - 39, 20, 11,163, 64, 44,245,171, 65,232,193,211, 55, 83, 0,134, 66,175, 50, 66,159,109,132,174, 96,203, 52,246,155,176,178,246, -193, 39,197,127,132,149, 80, 86,183, 9, 33,125, 0, 28, 46, 42,178, 10, 9,161, 62,148,210, 71,229,229, 52, 24, 12, 55, 10,132, -143, 88, 44,118, 36,228,141, 48, 20,137, 68, 70,157, 78,215,186, 60,156, 0, 16, 28, 28,140,186,117,235,114,243, 57, 11, 15,221, - 97, 42,240, 92,130,203,229, 66, 32, 16,128, 16,130, 22, 45, 90, 96,228,200,145,168, 91,183, 46, 34, 34, 34,176,127,255,126,220, -187,119, 15,124, 62,255,237,249,150,162, 85,171, 86, 92,177, 88,124,179, 71,143, 30,129, 51,103,206, 20, 87,170, 84, 9,207,158, - 61,243, 92,186,116,233,212, 11, 23, 46,244, 36,132,212,163,148,150, 25,231,164,132,184,117, 3,122,182, 26,158,149,153,177,187, -170, 3,230,234,116, 58, 60,123,246,204,226,107,138, 59,238,227,227, 19,195,225,112, 94, 50, 12,115, 29, 64, 77, 74,105, 11, 66, -200, 25, 0,178, 34,167,170, 41,165,157, 9, 33, 57, 0, 66, 56, 28, 78, 56,195, 48, 49,197, 13,151, 82, 40, 20,169,113, 41, 57, - 78,246,114, 49,134, 54,147,163,237,162, 4,244,169, 39,130, 72, 64, 16, 22,149, 4,159, 42,149,200,163, 27,199,234,229,139,171, -250,137,137,137, 0, 80, 15, 64, 84,108,108,172, 75,129,192, 98,241,113,160,168, 8, 42, 16, 78, 75,150, 44,233, 86,156,168, 42, -230,217,124, 39,124,233,210,165,139, 11,253,255,160,147,172,120,133,149, 99,169,118,121, 46,183,247,147,179,171,111, 87, 53, 80, - 47,167,192,174,133,172, 65, 20, 49,143,206,130, 97,152, 29, 22,138, 43, 9,225,240,119, 76,153, 49,159,179,249,178, 6,201, 73, - 9, 72,184,186, 12,186,180,176,237,148,210, 9,193,193,193, 57,239,155,168,160,160,160, 64, 27,123,103,104, 13, 20, 12, 5,240, - 39,145,245,209,136,171,238,126,126,126,243,111,221,186,229,165,213,106, 21,127,252,241, 71,214,238,221,187, 95,234,245,250,159, - 41,165,123,242,207, 57,158,150,150,182,128, 82, 10, 43, 43, 43, 30,159,207,151,148, 54,240,179,134,181,160,238,136,225,131,111, - 76, 92,179, 85,252,242,201, 35,172, 57,124, 26, 34,179,222, 28,154,169,239,245, 68,101, 44,248, 42,184,212,197, 85, 26, 79, 65, - 61,248, 28, 2, 59,137,192,185, 49, 33,226, 91,148,150,217,157,235,224,225,197, 49,122,122,227,186, 73, 11,185, 66, 32, 4, 0, - 55,223,106,220,135, 26, 35,254,120,252, 12, 98,177,173,192,194,135,108, 54, 33,164,209,179,103,207, 72,110,110,174, 54, 36, 36, - 4,118,118,118,112,114,114,130,181,181, 53,158, 61,123,134,139, 23, 47, 34, 60, 60, 28,148, 82,212,170, 85,171, 92,121,155,156, -156,140,156,156, 28,244,234,245, 73,155,132,132,120,177,163,147,179,254,210,197, 11, 23, 42,194,201, 48, 12, 1,128,192,192, 64, - 4, 6, 6,242,227,227,227,109, 78,158, 60, 41, 95,178,100,137,171, 82,169,188,167,209,104,222, 17, 78,150, 10, 44, 0,208,106, -181,208,233,116, 16, 8, 4, 16,139,197, 16, 8, 4,200,201,201, 65,114,114, 50, 84, 42,213, 91,139,155,165,188,249, 49,166,216, -213,236,254,159, 43,199,112,199, 10, 54,136,127,228,139,172, 75,132,144,130,242, 77,206,223,247, 41,173,171,175, 12,206,119, 44, - 44,133,172, 76,252,138,112, 6, 5, 5, 21,112,188,211, 74,136,197,226,148, 2,203,149, 88, 44, 78,177, 84, 96,153, 76, 38, 8, - 4, 2, 52,108,216, 16,235,214,173,195,189,123,247,112,244,232, 81,120,122,122, 98,248,240,225,224,112, 56,120,250,244,105,121, -163,201,220,186,117,107,106,175, 94,189, 2,119,238,220, 41,142,137,137, 65, 88, 88, 24,108,108,108,176,110,221, 58,209,168, 81, -163,124, 46, 95,190, 60, 27,192,242, 50,243, 48,227,217,225,124,129, 11, 87, 87,215,225, 53,107,214,252,211, 57,206,206,206,214, -231,206,157,115, 44, 16, 94,133,175, 41, 1, 89,179,103,207,254, 49, 32, 32, 96,117,126,183, 96,115,188, 25, 7,215,234,240,225, -195, 4, 0,250,244,233, 67, 9, 33, 87,242,207, 15, 57,116,232, 80,235,231,207,159,211,185,115,231, 22,219, 38,165,166, 36,110, -250,113,221,230, 31,127,152,247,157,112, 98, 23,107,244,169,199,135, 88, 64, 96, 37,229, 99,209,218,173,198, 7,119,174, 61,118, -113,113, 57, 9,160, 87, 98, 98, 34, 92, 92, 92,114, 1,132,115,185,220, 40,179,217,156,192,142,113,255,215,189,215,138,155,232, - 48,138, 82,154, 88,156, 64,170,136, 64, 43,108,225, 42,192,244,233,211, 3,151, 44, 89,114,247, 67,166,133, 83,232,166,164,140, -151,132,139,141,210,205,110,244,160,142, 96, 24,192,100, 6, 76,102, 10,109,158, 26, 73, 97,151,243,244,122,253, 97, 11, 51,111, -217,240,111,151, 84, 14,142,229, 33, 49, 83,143,184,139,243,169, 46, 45,236,211,251,247,239,127,246,161,196,149,173,131,235,149, -239,151,109,195,189, 72, 61,204,204, 27,125,197, 48,244,237,239,143,164, 18, 86,117,112,112, 88,113,251,246,237, 74, 34,145, 72, -241,226,197, 11,243,161, 67,135, 18,244,122,253,198, 2,113,149,143,193, 65, 65, 65, 70,153, 76, 6,181, 90,173, 53, 24, 12,185, - 37,137,171, 64,137,196, 61,168, 70,141,107, 19,215,108, 21,107,245,122,100,107,116, 80,186, 56,155, 67, 50,243,122,133,168,116, -111, 43,100,117, 5,191, 73,189, 42,110,110, 68,172, 0, 5, 16,175,210, 39, 88, 34,174, 0, 64,166,176,230,184,215,107,133,122, -223,172,131,134,107, 77, 1,192,214,209,149,211,250,203, 69,232,180,230, 42,116, 60, 69,121, 36,176,174,106,213,170,218,252,250, -139,244,244,116,132,134,134, 34, 35, 35, 3,235,214,173, 67, 88, 88,216,219,151,110,249, 4,198,219,103, 2,169,169, 41, 34, 74, - 41, 82,146,147,132, 21,229, 44, 16, 88, 5,112,115,115,195,216,177, 99,121,106,181, 90, 92, 88, 92,149, 87, 96, 21,196,131, 82, - 10,189, 94,143,236,236,108,232,245,122,188,124,249,242,173,184,202,183,160,149, 47,253,122,149,177,216,112,109,134,241, 61, 26, -181, 63, 0, 8, 10, 57, 15,116,170,168,184, 42, 34,124,202,101,253, 41,203,130, 85,156,137, 91,163,209, 56, 81, 74, 73,112,112, - 48, 44, 25,127, 85, 56,223, 5, 2, 1, 70,142, 28,137,187,119,239, 34, 34, 34, 2, 92, 46, 23,106,181, 26,121,121,121,104,223, -190, 61, 10,198,227,149, 35, 13, 84, 32, 16, 12,158, 49, 99,134, 56, 42, 42, 10,105,105,105, 5,131,228, 97, 54,155, 49, 97,194, - 4,137, 72, 36, 26, 92, 94, 83,125, 66, 66, 66,199, 23, 47, 94,248, 21,221,146,146,146,178, 69, 34,209,123,231,237,225,195,135, - 73,159, 62,125,104,159, 62,125,104,129,208,178, 20, 89,113,161,155,142, 30, 63,121,126,210,247,203,114,243,212, 42, 84,113,149, - 32, 87,149,141, 69, 75,126, 48,222,186,117,253,202,212, 9, 99, 26, 31, 58,116,104, 41,128,240,252, 75,194, 15, 29, 58, 52,236, -251,239,191,223,133,124,119, 13, 44,254, 85, 22, 42, 82, 76,216,150,146, 44, 88, 31,194, 10, 86, 96,201, 2, 32,249, 75, 44, 88, -101,136,150, 58, 54, 14,110,151,167, 47,222, 42, 63,250,152,139,140,196,112,104, 83,194,225, 81,183, 39,146,195,255, 0, 53, 27, -127, 11, 13, 13, 85,151,197, 83,175, 94, 61, 95, 87,159, 58, 95,214,169,215, 16,203, 78,230, 66, 21,186, 31,250,204,168,245,193, -193,193,191,125,136,196, 4, 5, 5, 5,218,218,187, 92,153,177,116,171,221,137,167,124,164, 39,132, 35,236,216, 84,152, 13,127, -234, 21, 59, 93, 94,110, 9,163, 23,230,102, 37, 67,175, 50, 67,204,201, 19,255, 3, 42,225, 75,165, 82,185,243,199, 31,127, 28, -211,184,113, 99,233,192,129, 3, 95,100,102,102, 46,164,148, 30, 44, 36,194,218,248,249,249, 77, 94,191,126,189, 79,108,108, 44, -206,159, 63,255, 18,165, 12,224,123,170,209,196,213,180, 22,109,188,177,247,231,239,184, 94,126, 56, 48,119,138,233,230,147,103, - 61, 66, 85,166, 51,111,197,149, 92, 24,208, 56,176,234,201,175,199,141,225,152, 31,156, 69, 88,108, 10, 18,213,198,139,150,198, - 59, 94,149,103,228,139, 36,144, 59, 87, 66,180,198, 44,224,241,120,119,191,255,114,148,128,195,229,129,195, 19, 32, 50, 75, 87, -158,151,184,232,217,179,103, 4, 69, 38, 66,104,181,218, 18, 45, 62, 31, 18,150,114, 22, 55, 62, 10, 0,140, 70, 99,133, 57, 11, - 91,108,202,186, 23,195, 48,208,233,202,177, 28,161, 46,171,248, 50,208,164, 25, 63, 68,182,229,239,133,239, 35,174, 10,132, 79, -193, 0,116,145, 72,244, 86,164, 88,106,101, 42,197,130, 85,161,227,239,124,185,114, 56, 96, 24, 6, 2,129, 0,181,107,215,198, -201,147, 39, 97,103,103, 7, 43, 43, 43, 88, 89, 89, 65, 34,145,192,222,222,254,173,192,226,112, 44,158,125, 67,117, 58,157,167, -167,167, 39, 94,190,124, 9,177, 88,252,118, 19,137, 68, 8, 12, 12,132, 90,173,118,195, 71,101,171, 7,190,232,223,174,231,134, -221, 71,134,158, 60,121,234, 75,131, 78, 91,195,223,223,143,222,191,117,249,241,212, 9, 99, 58,177,146,228, 63,103,225, 58, 89, - 88, 36, 17, 66, 78, 78,155, 54,109, 70, 69,249,166, 77,155, 54,163, 56,139,214, 7, 19, 88, 5,138,177, 56,229, 88, 32,174,166, - 46,218, 98,117,248, 1, 7,153,137, 97,136, 57, 59, 67,101, 54,228,101, 50,140,209, 43,243,213, 13, 0,216, 97,225,253, 26, 52, -109,219,139,156,127,170,135, 94,149,128,156,167, 7,162,141, 70,227,244, 15, 41,174,166, 45,217,106,119,228, 49, 15, 25, 9,225, -120,117,122,122,182,217,144,215,166, 34,126,180, 10, 99,136, 80,216,179,127, 53,155,110,159, 55, 79,128,153,152, 49,248,217,243, -206,174,205, 73,207,132,235,244,216,223, 89,209, 82, 83, 83, 23,201,229,114,206,242,229,203, 63,211,106,181,115, 41,165,135, 11, - 85,194,246, 85,170, 84, 89,182,105,211, 38,247,215,175, 95, 11,111,220,184,145,113,229,202, 21, 6,192,210,210, 56, 67,178,117, - 83,106, 40, 4,220,170, 30,174,227, 94,198,197,245,120,146, 99, 58, 91,112,172,134, 76, 24,216,188,118,192, 31, 11,230,206, 80, -232,111, 28,134, 58, 49, 22,235,130,147,114, 24,179,101,101, 72, 8,177,107,236,229, 76,166,127, 49,156, 81,169, 84,144,137,132, -140,209,104,228, 14,109,215,194,252,195,212, 73,156,164,164, 36,168,115,115,121,132, 16, 59, 74,105, 70, 25, 92,243, 1,180,169, - 85,171, 22, 58,116,232, 16, 61,111,222,188,231,133,197,199, 63, 73, 96, 21,181, 96, 21,192, 96, 48,144,138,114, 22,182, 96,149, - 37,176,202,109,193,210,229, 20, 47,164,242, 82,223, 87, 96,189, 38,132,120, 22,252,254, 16,101,160,213,106, 29, 11,117, 13,150, -105,137,183,192,130, 85,225,227, 69,234,231, 91, 11,214,163, 71,143,224,225,225, 1,131,193, 0,133, 66, 1,133, 66, 1,185, 92, - 14,149, 74, 5, 62,159, 95, 94, 11, 28, 35, 22,139, 95,135,134,134,250, 41,149, 74,152,205,230,119, 68,214,139, 23, 47, 32,147, -201,226,203,107,193,114,117,117, 61, 39,147,201,188,138,134, 59, 59, 59, 91,127,136,114, 42,108,185,234,211,167, 79,133,250, 17, - 54, 44,249,110, 55,128,221,125,251,246,221, 25,114,235, 84, 61, 23, 23,151, 83, 1, 1, 1, 4, 0,216, 25,131, 31,151,245,170, -132,231, 56,181,136,229, 73, 95,232,127, 42, 0,146,255, 63,181,144, 0, 43,252, 91, 95, 76, 88,250,146, 37, 75, 46, 23, 26,191, -149,250,255,102,193, 10, 10, 10,170, 99, 99,239,122,249,187, 5,155,173,246,222,231, 32, 59,241, 57, 18, 46,204,202,102, 12,121, -109, 56, 28, 78, 98,236,205, 45,135, 1,228, 61,120,240,224,170,133,153, 87,215,223,215, 23, 7, 66,140,208, 38, 61, 6,168,121, -123, 72, 72, 72,222,251, 38,162, 64, 92, 77, 89,188,197,238,208, 67, 94,129, 8,204,102,222, 83, 92,125, 78,136, 45, 87, 38,222, - 56,180, 67,253,126, 94, 85,220,193, 80, 35, 24, 1, 69,239, 41, 14,188,240, 7,121, 71, 61, 59,112, 15, 50,185,204,151,113,183, -254, 62,239,227,185,185,185, 11, 8, 33, 71, 40,165,207, 10, 53,238,157,125,124,124, 22,255,244,211, 79,149,226,227,227, 21, 15, - 30, 60,200,217,178,101, 75, 20,195, 48,243,139,155, 85, 85, 20, 79, 84,134, 73,129,114,225,207, 79,115, 77,111,125,232, 84,151, - 9,106, 13, 31, 58,240, 86,187,129,195,197,175, 46,236,134, 93,212, 51,172,121,144,108,142, 87,105, 7, 62,207,163, 73,150,136, - 43,145, 72,116,120,245,161,227, 47,235,214,173, 75,212,106, 53,140, 70, 35,210,210,210,176,124,207,161, 80, 74, 41,108,109,109, -113,250,244,105,102,208,160, 65, 5, 3,162, 51, 74,224, 42,112,211, 0,129, 64, 64, 36, 18,137,119,116,116,116,116,165, 74,149, -180,197,137, 20,145, 72, 84,110,129, 37,145, 72,192, 48, 37, 27, 1,202,195,105, 50,153,136, 37,225,229,225, 44,136, 91,193,224, -246,162,225, 5,224,114,185, 96, 24,166,212,180,252, 89,189,149, 96,193,202, 75, 49,190,103,227,233, 85,218, 76,229,191, 19,249, -150,176, 2, 1, 83,172, 43,134,242, 88,176, 10,202, 66, 32, 16,224,248,241,227, 24, 49, 98, 4,204,102, 51,164, 82, 41,228,114, - 57,100, 50, 25,126,251,237, 55, 20,184,113, 40, 79, 54, 26,141,198, 61, 75,150, 44,153,177,105,211, 38, 9,165, 20, 66,161,240, -173,192,154, 59,119,174,198, 96, 48,236,177, 68, 96, 17,219,234,253,109,108,237,134,100,101,165,239,168,106, 95,250, 44,194,226, -174,201, 31,143, 85, 20, 54,243,231,207, 31,198, 48, 76, 79, 20,113,197, 80,228,188,119, 92, 56,148,230,166, 1,128,237,252,249, -243,191, 96, 24,166,122,254,255,119,102, 11, 22,174,161, 5,199,251,246,237,187,179,232, 44, 66, 22,255,122,220,251,183, 69,184, - 68,129, 85,167, 78,157, 0, 59,165,251,229,137, 11, 54, 91,237,184,195, 69,118,226, 51,164, 93,254, 62,155,154, 52,133, 69, 75, -179,114,222,175,174, 82,105,143, 12,181, 22,198,204,151, 32,132, 60,120,223, 4, 52,104,208,160,170,141,157,243,149,201, 11,183, -216,237, 11,230, 35, 43,225,127, 34,240,125,196,213, 16,161,176,103,160,175,251,182, 1,157,155,218, 90, 19, 19, 76, 49,207,241, -243,240,126, 8,238,110, 64,211,254,214,104,208, 69, 1,159, 58,226,126,167,183,102,180,117,109, 78, 62,255, 59,173, 89, 69,196, - 85,247, 74,149, 42,205,187,115,231,142, 23,195, 48,138,171, 87,175,170, 54,109,218,244, 74,171,213,174,165,148,158,178,148,243, -105,174,254,173,184,170, 97, 45,168,251,249,103,195,110,124,179,122,147, 56, 52,248, 30,150,237, 57, 1, 43,174,209,124, 63, 73, -219,247,105,238,255,186, 15, 75,131, 80, 40, 92,112,233,210, 37, 89,205,154, 53, 73,122,122,250, 91, 75,139,193, 96, 64,118,118, - 54, 84, 42, 21,116, 58, 29,130,130,130, 56,107,215,174,149,141, 27, 55,110, 1,128, 47, 45,141,175, 82,169,132, 64, 32,128,193, - 96,120, 43, 82,132, 66, 33,108,108,108,144,158,158,142,253,251,247, 3, 64,169,206, 41, 5, 2, 97, 34,135, 67, 60,100,114,185, - 81, 42,149, 82,185, 92, 94, 92, 58,202,197, 89,240, 85,212,169, 83, 39,229,130, 5, 11,248, 65, 65, 65,111, 3, 11,186, 8, 43, -194, 73, 41,205,235,208,161,131,116,237,218,181,240,242,242,130, 94,175,127, 71, 72,113, 56, 28, 8, 4, 2,196,198,198, 98,225, -194,133,160,148, 90,254, 33,163,205, 52,162,198, 48, 71,104,210,141,208,164, 27,161, 77, 51, 64,157, 98,132, 49,207,252, 79,107, -192, 42, 50, 0,221, 2, 75,152,227,135,176, 96, 21, 8,172,103,207,158, 97,231,206,157,232,210,165, 11,108,109,109,145,153,153, -137,131, 7, 15,226,249,243,231, 16, 10,133, 40,231, 56, 50,166, 97,195,134, 63, 92,191,126,189,251,192,129, 3,171, 79,158, 60, - 89, 82,163, 70, 13,132,135,135, 99,254,252,249,218,224,224,224, 8,141, 70, 51, 31, 22, 56, 36,117,243,240,252,230,231, 61, 39, -249, 35, 6,118, 30, 7,125, 52, 44,153, 69,248,206, 53,197, 12,118, 47,193, 77, 67,231, 18,232, 10,187,112,120,199, 77, 67, 97, -220,188,121,211,187, 82,165, 74, 1,120, 51, 51,176,224, 69, 91,120,182,224, 59, 47,225,196,196,196,250, 96,103, 17,178,248, 39, - 11, 44, 14,135, 51,161,225,167, 51,173,118,220,230, 33, 51,254, 41,178,175,207, 41, 42,174, 44,105,100,218, 21,246,149,193, 23, - 43,106,152, 32, 0,160,133, 41,235, 21,184, 92,110,185, 5, 86, 81, 78,134, 97, 38, 53,250,116,166,221,174,123, 60,100, 39, 60, - 67,234,149,239,203, 45,174, 10,115, 14, 17, 10,191,231,115,201,172,174, 45,234, 10,154,213,241,133, 44, 37, 26, 73,113, 9, 56, -240, 44, 53, 35, 34, 83,247,249, 31,196,128,152, 87,186,159,187,124, 97,103,103,235,204, 71,183, 49,246,118,183, 79,228, 28,117, -107,195, 49, 80, 3, 93,146,112,131,206, 45, 46,158, 31, 2,101,113, 18, 66,170, 90, 89, 89, 45, 15, 14, 14, 86,138,197, 98,171, -251,247,239,155, 55,111,222, 28,171,213,106, 87, 82, 74,247, 87,132, 51, 80, 34,113,175,238,231,125,245,155, 85, 63,137,115,213, -121, 80,235, 13,112,245,112, 51, 95,125,240,252,211,167,185,250, 99,150,112, 18, 66, 90,127,246,217,103,181, 26, 54,108,200, 41, - 44,174,244,122, 61,114,114,114,160, 82,169,144,147,147,131,156,156, 28,196,199,199,163,101,203,150,156, 90,181,106,213, 32,132, -180,166,148, 94, 46,202, 89,200, 77,195, 12, 0, 28, 66, 72,248,249,243,231,181, 67,135, 14,133, 68, 34,129, 90,173,134,187,187, - 59, 76, 38, 19,206,156, 57,131,224,224,224, 44,134, 97,246, 1,184, 80, 90, 60, 53,154, 60, 79, 66, 8, 87,157,155,219,174,102, -205,154, 3, 39, 77,154,100, 83,248,252,138,112, 2, 64,102,102,102,165,115,231,206,125, 31, 18, 18, 50,174,115,231,206,210, 25, - 51,102,240,189,189,189, 97, 50,153,200,123,112, 90, 63,120,240, 96, 69,179,102,205,190,234,212,169, 19,111,241,226,197,176,182, -182,134,217,108,134, 68, 34, 65, 78, 78, 14,230,207,159,143, 27, 55,110,152, 40,165, 27,178,179,179, 39,151,198,249,142, 31,172, -137,171,106,151, 86, 15, 75,242,131,245,119,212,121,141, 70,227, 84, 94,171,152, 37,241,124,240,224, 1, 45,234, 15,171, 52, 11, - 86,113,156, 5, 2,139,203,229, 34, 58, 58, 26,155, 55,111,254,147, 31,172, 2, 55, 14,197, 9,172, 18,226, 73,175, 92,185, 98, - 38,132, 52,190,127,255,254,212,161, 67,135,126,174, 86,171,221,101, 50, 89,130,209,104,220,161,209,104, 10,252, 96, 9,202,138, -167, 80, 40,230, 19, 14, 7, 18,177, 76,162,206, 80,199, 20, 55,139,240, 29,147,147, 90, 29, 35,182, 22,219, 23, 92, 83, 28,103, - 17, 55, 13,239,184, 98, 40, 66,247,142, 11,135,162,110, 26, 10,115, 54,105,210, 36,138,195,225,132, 49, 12,195, 1, 16,134, 34, -179, 5, 11,113,250, 37, 38, 38,214,119,113,113,185, 10, 64, 90,116, 22,225,223, 81, 63, 89, 78, 86, 96,149,248,113,248, 71,240, - 11,112, 68, 41, 80,221, 89, 94,110,113, 85, 28, 76, 58,117,196,194, 3,145,117,204,122, 13, 76, 57, 49,225,193,247,239,165,188, -111, 2, 40,165,178, 27, 15, 34,192,147,164, 35,235,214, 15, 89,196,172,107, 19, 28, 28,252,168,194,149, 6,152,254,211,153,195, - 2, 98,109,135,199,223,142, 64, 66,150, 26,103, 34, 51, 15,210, 60,221,151,187,243,215,139,115,111, 76,174,111,155,153,180,177, -121,111,235,126, 14,110,124,172,250,110, 7,196,211,236, 5, 13,218,182,248, 91,215, 40, 44, 24,248,190,102,205,154,177,205,155, - 55,151,247,235,215,239, 69, 70, 70,198, 59, 3,223,203,139,167, 26, 77, 92,160, 66,248,211,229, 45,171,190,147, 4, 54,196,225, -133,211,205,215, 30,132,245,122,162,210, 91, 60, 40, 80, 32, 16,180,154, 54,109,154, 64,173, 86,255, 73, 92, 21, 21, 88, 57, 57, - 57,120,252,248, 49,134, 15, 31, 46,122,244,232, 81, 43, 0,151, 75, 72,235,236,124,135,147, 60, 74,105,234,210,165, 75,123,110, -216,176,161,247,183,223,126, 43,234,220,185, 51,238,222,189,139,243,231,207,235,244,122,253,111, 0,142, 81, 74,117, 22,230,161, - 25,192, 57, 66,200,213,165, 75,151,246,228,114,185,111,215,179,124, 15, 78, 35,128,217,132,144, 21,187,118,237, 90,118,225,194, -133,129,195,135, 15, 23, 27,141, 70,242, 30,156, 38, 0,223, 42,149,202, 89,167, 79,159,222,241,251,239,191,247, 26, 50,100, 8, -103,252,248,241, 88,183,110, 29,126,253,245, 87,198,108, 54, 31,227,243,249,195, 82, 83, 83,203,156,128,242,142, 31,172, 82,252, - 92,149,117,220, 2,220,255, 11,170,254,123,115, 22,181,132,213,173, 91,215,169,240, 44,205,194,123, 75, 45, 88, 0,208,170, 85, -171,183, 86,197, 66, 51, 40,223,158, 67, 8, 41,119, 23, 33, 0,155,124, 63, 87, 27, 0,172,195,187, 94,220,185,248,159,167,119, -139,224,230,225,133,120,192, 94,163,215,102,149,186,216,179,181,204,222,205,195,171, 44,186,172,217,179,103,255, 56,103,206,156, - 31,139,186, 98, 40,124, 82, 81, 23, 14,243,230,205, 67, 73,110, 26, 0,100,206,158, 61,251, 7, 0, 8, 8, 8, 32,249,221,130, -245,144, 63, 91,176, 16,231,206,252,112,233,220,185,115,135, 2, 40,141,147, 5,139,191, 85, 96,205,200, 13, 94, 99, 4, 96, 79, - 8,153, 30, 28, 28, 28,250, 1, 36,192,180,148, 19, 35,214, 81, 32, 19,140,121,234,135, 72,128,217,108,158,169,126,176,150,161, -148,218, 16, 66,166,221,191,127,255,189,227, 73,172,237,160,154, 63, 22,191, 62, 77,160, 73,106,227, 39,187,245,239, 90,106,242, -199, 92,245,119,109, 78, 14,216,186,242,143,124,219,198,158,156,202, 24,250,143, 40,208,212,212,212,197,114,185,156,187, 98,197, -138,207, 52, 26,205, 59, 3,223, 43, 44,178, 84,250, 41, 53, 20, 2,110,128,183,199,184,231,209, 49, 61,159,168, 44,235, 22, 44, -244, 34, 17,186,186,186, 62,209,106,181, 32,132, 64,167,211,189, 21, 86, 42,149, 10,217,217,217,111,255, 27, 12, 6,164,166,166, -194,211,211, 19,133,124, 38,149, 36, 50, 18, 11,107, 4, 66,200,217, 5, 11, 22, 12, 92,184,112, 97, 91, 74,233, 69, 0,251, 40, -165, 21,114,253,145, 47,116, 14, 72, 36,210,229,132, 16, 55,129, 80,164, 63,121,242,228,153,247,228, 84, 1, 24, 67, 8, 89,176, - 98,197,138,181, 82,169,180,254,195,135, 15,223,139, 51, 95, 60,125,106,111,111,239,186,115,231,206, 67,219,182,109,107,196,227, -241,110, 19, 66,250,102,101,101,149,123,177,103,242,174, 69,160,220,199, 45,192,175,127, 65,181,127,111,206,242,184, 95,176,176, - 93,202,157, 53,107, 86, 74, 81,193, 85,212, 90, 85,240,223, 96, 48,104, 45,124,150,202,227,139,172, 84,113,193, 33, 68, 3, 64, - 50, 99,222,138, 55, 39, 91,190,216, 51, 8, 72,137,131, 5,231,204,153, 67,231,205,155, 71, 56, 28,206, 49, 0,225, 28, 14,231, -101,209, 65,232,133,143,205,155, 55, 15,115,230,204,161,115,231,150,252,109, 90,192,249,252,249,115,202,229,114, 47, 2,136,226, -114,185,209,133,121, 11,135, 23, 92, 83, 26, 39, 11, 22,127, 53,200, 95,233,132,237,223,104,234, 28, 44, 20,206,227, 0,223, 1, - 32, 20, 88,181, 91,175,159, 89,218,181, 46, 77,201, 34, 74, 48, 33,255,229,179, 56,241, 6, 93,248, 79, 72, 59, 33,164, 90,225, -177, 89, 31,130, 51, 80, 46,244, 47, 60, 54,203, 82, 78, 62,159,223,198,104, 52,146,212,212, 84,168,213,234,119,172, 85, 57, 57, - 57,200,203,203, 67, 78, 78,206, 59, 99,167,154, 54,109,138, 86,173, 90, 81,163,209,120,169, 2,105,231,231, 91,141, 62,100,126, -254, 43, 56,125,124,124,132, 17, 17, 17,250,127,234,179, 73, 8, 81,228, 11,205, 15,201,233, 76,105,217, 19, 45,254,205,237,210, - 95,193,105, 91,185,233, 32, 59,123,231, 47, 11, 22,125,214,104,213,154,164,132,184,117, 69, 7,175, 19,219,234,253,221, 60, 60, -191, 17, 10,197,252, 2, 97,150,158,150,180, 57, 51,242,143,189,197,197,147,252, 79, 65,218, 68, 68, 68,120,249,248,248,196, 0, -200, 42, 18,149, 63, 29, 43,236,159,175, 20, 78, 0, 80,220,185,115,199,181, 97,195,134,137, 0,114, 74, 11, 47,141,243,191, 90, -238,255,100,206, 18,238, 51,170,176, 31,172,143,197,130,245,159,196, 30,189,126, 14,202, 88,108,184, 48, 18,255,160, 51, 1,204, -252,167,165,195, 18,113, 85,110, 75,150, 5,226,170, 56, 20,136, 36,165, 82, 9,165, 82, 89,158,235, 42,154,118,227, 95,144,159, -255, 10, 78, 75,196,213,223, 92, 47, 85,127, 1,103, 18, 88,148, 27,249, 2,105,111,153,249,251,166,203,240, 64, 57,202,163, 64, -212,100, 2,200, 44,225, 35,190,180, 99,165,113, 34, 95, 60,229, 20,115,109, 73,225, 44, 88,252, 45,224,176, 89,192,130, 5, 11, - 22, 44, 88,176, 96,241, 97, 65, 0,180, 43,225,139,193, 98,211, 31, 33,164, 93, 5,190, 58, 47,176,156, 44, 39,203,201,114,178, -156, 44, 39,203,249,223,226, 44,139,187, 72,247,240,191,182,139,240,237,204,150,191, 98, 3,208,142,229,100, 57, 89, 78,150,147, -229,100, 57, 89, 78,150,179,130,247, 25,245,255,113,159,191, 98, 99,187, 8, 89,176, 96,193,130, 5, 11, 22, 44, 62, 48,216, 65, -238, 44, 44, 2,151,203, 93,210,162, 69,139, 47,111,220,184,177,210,104, 52,206,175, 8, 7, 33,196,213,201,201,105, 17,165,180, - 9, 33, 68,196,227,241,158, 37, 39, 39, 47, 54, 26,141,215, 43, 26, 47, 66,136,135,179,179,243, 34,134, 97, 26, 1, 16,240,120, -188,167, 9, 9, 9, 11, 41,165,183,223,131,211,202,217,217,185, 53,195, 48,238,111,146,206, 77, 73, 76, 76,188, 78, 41,141,103, -107, 2, 11, 22, 44, 88,176,120,111,129, 53,192,143,184,152,121,224, 29, 10,165,177,249, 47, 30, 5,128,218, 0,170, 2,120, 9, -224,209,251,206, 10,250,183,112,254,211, 65, 8,225,216,216,216,116,144, 74,165,223,228,230,230,214,177,178,178,122,106, 50,153, -214, 38, 38, 38,158,204,119, 74,248, 62,220,142, 3, 7, 14,156,246,243,207, 63,163, 95,191,126,179, 8, 33, 63, 82, 74,115,203, -195, 97,111,111,223,195,219,219,123,243,218,181,235,148,205,154, 53, 35, 18,137, 4,207,159, 63,119,251,242,203,177,245, 92, 93, - 93, 15, 36, 36, 36,124, 85,222,120, 41,149,202,190, 85,170, 84, 89,187, 97,195, 6,101,147, 38, 77, 8,159,207, 71,112,112,176, -251, 55,223,124,211,208,197,197,101, 71, 98, 98,226,164,242,114,218,217,217, 85,171, 92,185,114,167,141, 27, 55, 74,155, 54,109, - 10,145, 72,132,199,143, 31, 43, 70,143, 30,237,230,234,234,250, 56, 33, 33,225,124,121,248,130, 70, 63,224, 11,164, 6, 30, 0, - 24,242, 4,166,224,205,117,141,150,134,177,205, 19, 11, 22, 44, 88,124,132, 2,171, 79,117, 50, 31, 60,204, 0, 64, 58, 87, 37, -251,207, 71,113,175,183,111,223,222,103,228,200,145,164,110,221,186, 8, 14, 14,246,221,191,127,127, 87, 30,143, 23, 97, 54,155, -131, 1, 60,181,116,218, 57, 33,132, 15, 32,144,203,229, 6,253,147, 57,255, 13, 80, 40, 20, 85,149, 74,229, 36,123,123,251,206, -245,234,213,203, 25, 51,102, 76,116,104,104,232, 11,127,127,127,237,182,109,219, 22, 27,141,198,141,190,190,190,231, 85, 42,213, -138,164,164,164,138,186,110,168,100, 52, 26, 17, 22, 22, 6, 14,135,195, 7,224,141, 63, 47,125, 81, 90,217,184, 84,170, 84,105, -211,229, 63, 30, 56,230,232,185,120,153, 74, 1,228,129, 17, 56,227,167, 95, 14,216,206,158, 58,110,160,149,149,213,141,156,156, -156, 3,229,224,244,168, 82,165,202,218, 39, 79,158, 56,138,197, 98, 48, 12, 3,149, 74, 5, 87, 87, 87,108,219,182,205,246,187, -239,190,251, 76, 42,149, 94,203,203,203, 59, 81, 14, 78,171,202,149, 43,119, 10, 13, 13,149,138, 68, 34, 98, 50,153,136, 78,167, -131,135,135, 7,221,187,119,175,120,252,248,241,181, 69, 34,209,107,157, 78,247,194, 34,113,181,229, 1, 63, 39,237,114, 99, 26, -171,153, 5, 0, 68, 44, 89,216,106,158,221,221,156,180,203, 13,202, 10, 11,218,130, 91,193,163, 88,145,197,226,255,253, 67, 45, -200,193,193,225,112, 90, 90,218, 85, 0,159,231,175,108,240,190,156,174, 60, 30,207,155, 82,106,147,255, 63,203,100, 50, 69, 81, - 74, 19, 42,202,233,224,211,186, 59, 68,210, 17,160, 76,109, 14, 0,194,225, 60, 50, 27,242,182,167,133, 95, 62,241, 94,156, 66, -201,103, 0,173,205, 1, 24,194,225, 60,102, 76,121, 91, 83,159, 95, 62,195,214, 12, 22, 31, 76, 96,245,173, 78,108, 1, 76,221, -255,195, 40, 14,143,203, 37, 3,167,111, 25,116,245,220, 49, 77,229,106,117,223, 90,129,154, 55,111,142,230,205,155,147,101,203, -150, 85,189,120,241, 98,213,189,123,247,154, 8, 33,143, 41,165, 37,190, 36, 59,249, 16, 13, 3,136, 59,251,113,243, 6,204,220, -190,165, 73,147,166,140, 72, 36,194,251,112, 2, 64,135,170,220,200, 46, 13,125, 30, 15, 28, 55, 59,166, 81,163, 38,244, 67,112, -254, 75,196,213, 85,133, 66,225, 51,122,244,232,151, 99,199,142,189, 38,147,201, 40, 0,228,229,229,137,186,119,239,158,217,171, - 87,175,244,188,188, 60,252,244,211, 79, 30,107,215,174, 61,111,101,101, 21,159,147,147,211,160, 60, 86, 49, 0,115,122,244,232, - 49,235,235,175,191,134,167,167, 39,198,143, 31, 15,163,209, 24, 76, 8,153, 13, 96, 41,181,192,233,140,163,163,227,156,213,171, - 87, 59,170,141,124,124,191, 43, 2, 25,185, 6, 0,128, 84,200,193, 87,237,196, 24, 55,110,188,245,221,187,119,151,161, 28,190, -118,156,157,157, 23,109,216,176, 65, 41, 22,139, 65, 41, 69,110,110, 46, 84, 42, 21,114,115,115,161, 86,171, 49,118,236, 88,235, -167, 79,159,174, 6,112,162, 28,156,173, 55,110,220, 40, 21,137, 68, 56,127,254,188,159, 78,167,227,234,245,122,152,205,102,115, -149, 42, 85,194,190,254,250,107,209,147, 39, 79, 58, 2,176, 72, 96,185, 36,129,159,173,209,108, 88,255,195,119, 74, 0,248,122, -234,242, 13,128,166, 33,181, 32,204, 37, 9,245, 1,176, 2,171,244,250,201, 5,240, 9,159,207,239,237,227,227, 83,239,229,203, -151, 15, 77, 38,211,111, 0,126,123,223,143, 40, 66, 72, 91, 87, 87,215, 69, 9, 9, 9,235, 41,165,187,255, 43,121,234,228,228, -244,219,205,155, 55, 61, 54,110,220, 56,124,229,202,149,167,241, 30, 94,242,243, 63,122, 27, 55,104,208,192,161,119,239,222,124, -103,103,103,228,229,229, 33, 34, 34, 66,122,225,194, 5,165, 88, 44, 78,215,233,116,183,202, 83, 86, 14,126, 77,229,224, 89,237, -111,220,186, 93,179,126,159,126,162,112,178,183,134, 70,111,198,203,152, 68,207,179,167,143,183,116,173,209,245,166,193,144, 61, - 32, 45,252,143,220,242,114,182,238,212,173, 89,187,182,109, 21,214, 54,214,200, 86, 27,240, 42, 58,222,235,242,249, 19,205, 93, -106,116,189,198, 16,227,144,228,144,223,243,216,167,142, 69,121,192,177,240, 65,129, 76, 38, 45,246,152,181,181, 53, 90,183,110, -141, 37, 75,150,240, 0, 4, 21, 62,246,167,197, 79, 1,209,209, 13, 83,205,110, 74, 91,115,231,142, 29,137,149,149,213,123,115, -190, 9,100,188,155,120,210,206,247,118,205, 24,126, 97,239,170, 64,181, 42,139, 95,244, 20,185, 92, 14, 63, 63, 63,204,154, 53, -203, 50,206,247,196,255, 7, 39,165,212,181, 90,181,106,170,213,171, 87,251,205,157, 59,215, 86,171,213,202, 0,120,248, 84,111, -224,206,225,112, 60,180, 90,173,213,156, 57,115,148,203,150, 45,243, 83, 42,149, 89,148, 82,101, 57,227,185, 96,195,134, 13,179, -143, 29, 59,198,105,222,188, 57,108,109,109,209,186,117,107,156, 62,125,154,183,114,229,202,197, 0,102, 89, 18, 79, 14,135,211, -188, 89,179,102,132, 97, 40, 50,115,141,184,188, 36, 8,127, 44,175,143, 60, 61,131,204,172, 28,104,181, 90, 72,165, 82, 9, 33, - 68,110,105,218, 25,134,105,212,164, 73, 19, 2, 0,185,185,185,249,155, 26, 42,213,155,189, 94,111, 0,159,207, 87, 16, 66, 68, -229,224,116,111,218,180, 41, 0, 64,163,209,240,218,182,109, 75,218,180,105, 67, 84, 42, 21,175, 96, 25, 31, 62,159, 47, 36,132, -240, 44,225,212, 75,249,132,161,140,147, 76, 42,113,144, 73, 37, 14, 12,101,156, 0,192,146, 48,189,148, 79,254,206,250, 73, 8, - 81,114,185,220, 95,124,124,124,158,113,185,220,157,132, 16,231,247,225, 36,132,212, 39,132, 44,150, 74,165, 23,170, 85,171, 22, - 43,147,201, 46, 17, 66,150, 18, 66, 26, 87,132,147, 16, 34,148, 74,165,151, 22, 47, 94,124,232,225,195,135,253, 46, 94,188,232, - 29, 18, 18,242,233,178,101,203,246,203,229,242,235,132, 16,233,251, 60,155,222,222,222,219,238,220,185, 83,191, 73,147, 38, 63, -151, 86,135,202,195, 73, 8,225, 18, 66,234,144,226, 86,118,254,155,218,144,162,150,166,186,117,235,122,136,197, 98,180,107,215, - 14, 0, 90,189, 39,103,227, 49, 99,198, 56, 79,156, 56,145,255,232,209, 35,252,252,243,207, 56,118,236, 24, 82, 82, 82,208,173, - 91, 55, 65,155, 54,109,156, 69, 34, 81,227,114,113,242,172,246,127,243,237,132, 78,223,141,255, 66,241,248,181, 1,219, 47,188, -198,209, 91,137, 72,201, 19,162,251,167,195,172, 59,246,236,223, 81, 40,178,222, 95, 94,206,105, 83,167,118, 26,245,217, 32, 69, -104, 34,131,227,183,147,112, 59, 44, 27, 38,190, 13,186,124,250,185,109,237,166,157,186,242,192,223,241, 79, 40,163,143,157,243, -163,181, 96, 21, 94,145,254, 80, 40,205,236, 83,157,252,208,127,202,150, 89,132, 67,104,245, 6,109, 31, 86,171,219, 84,149,111, - 29,129, 78,167,131, 64, 32,128, 86,171,197,235,215,175,113,251,246,109,216,218,218,150,235,198,217,217,217,112,247,244,130, 92, - 46,255, 32,156,211,135,183, 19,189,138, 77, 21,157,187,125,165,229,154, 47,127,109, 84,165, 78,171,144,182,253,199, 63,177, 82, -186,106, 67, 66, 66,112,243,230, 77,100,102,102,162, 97,195,134, 31,211, 23,188,113,197,138, 21, 15, 18, 18, 18,200,141, 27, 55, -106,207, 95,189,215, 59, 36,167, 50, 55, 53,151,242,149,242,215,222,213,164, 47,204,217,217,217, 81,147, 38, 77,186,236,236,236, -172, 27, 55,110, 92, 75, 11,121,197, 0,252,251,244,233, 51,237,203, 47,191, 68, 68, 68, 4,190,248,226, 11,205,221,187,119,211, -155, 52,105, 98,191,117,235, 86,201,196,137, 19,113,245,234,213, 57,132,144, 35, 0,162, 40,165, 37,174,165,198, 48,140, 80, 34, -145, 0, 57,111, 62, 84, 13,166,130,181,105, 1,181, 90, 13, 30,178, 32, 20, 10, 57, 0,148, 0, 44,253,242, 20,136, 68,162,183, -226, 42, 46, 69,133,152,148, 92,168,114,117,208,104,140,208,107, 1,145,149, 19, 23,136,181, 7, 96,233,224,116,174, 72, 36,130, -201,100,130,193, 96,128, 86,171,133, 86,171,133, 78,167, 67,118,118, 54, 84, 42, 21,120, 60,158, 20,128, 21,128,140, 50,201,132, - 18, 19,151, 35, 88, 60, 99,225,134,185, 0,192,229, 8, 22,203,161,101, 44, 9,227, 10, 37,166,191,177, 94,137,148, 74,229,229, - 67,135, 14, 85,171, 90,181, 42,162,162,162, 2,250,246,237,219,144, 16, 82,135, 82,154, 87, 78, 46, 41,135,195,249, 97,196,136, - 17, 95, 14, 28, 56,144,248,250,250,130,199,227,193,100, 50,185, 71, 68, 68,180, 62,120,240,224, 84, 30,143,183,213,108, 54, 79, -178,116, 92, 31, 33,132, 35, 20, 10, 15,108,222,188,185, 69,195,134, 13,177,115,231, 78,220,189,123,151,169, 95,191, 62,103,232, -208,161,240,242,242,106, 56,116,232,208,163,132,144, 46, 21,177,100, 17, 66,188, 6, 15, 30,236,193,229,114,209,164, 73, 19,193, -205,155, 55,235, 2,184,249,158,121, 42,119,119,119,191,218,170, 85,171, 58, 23, 46, 92,120, 64, 8,105, 85,158,113,140,132,144, -158,174,174,174,203,172,173,173, 45,110, 20,115,114,114,242,226,227,227, 39,151, 99, 61,210, 70, 65, 65, 65,136,137,137,129,191, -191, 63, 4, 2, 65, 99, 66,200,104, 0,157, 0,204, 44,207,234, 16,132, 16,215,198,141, 27, 59,180,106,213,138, 44, 93,186, 20, - 0,192,231,243, 97, 54,155,193,225,112,192,231,243, 17, 16, 16, 64, 34, 35, 35,237, 8, 33,174,150,116, 23, 58,248,180,238,222, -164,109,167,102, 45, 26,214,226,172, 60,252, 18,102,198, 12, 46, 49,129, 71, 24, 48, 70, 17, 68, 2, 46,124, 3,235,113,195,158, - 62,110,232,224,215,190,123, 90,248,249, 19,150,112,118,234,222,163,121, 53,127, 95,206,154,163,175,144, 21,255,204, 28,255,252, - 90, 26,135,203, 65,181,160, 54, 14,190,213,235,112,235, 52,108,197, 79,136,122,218,218,174,106,203,118, 25, 47,175,178,162,226, -175,111,127,222,106,145,143, 70, 96, 21,197,225, 80, 58,219, 90, 68,148,143, 30, 5,115, 82, 85, 70,213,227,199,143, 97,107,107, - 11, 23, 23, 23, 88, 91, 91, 35, 52, 52, 20,151, 46, 93, 66,120,120, 56, 24,134, 65,237,218,181,203,117,227,132,196, 4,100,100, -101,127, 80,206, 42, 30, 74,124,237,161, 20, 36,167,231, 8, 46,220, 13,111,184,101,250,167,213, 57, 1,159,110,211,106,255,247, -238, 47, 88,239,238, 99,130,147,147,147,233,171,175,190,206, 24,181, 49,170,202,128, 54,174,220,158,141,157,113,244,102, 34,119, -255, 21, 46,157, 61,178, 86,234,203,151, 47, 44,126,201, 8,133,194, 69,157, 59,119,254,142, 82,202,255,230,155,111, 0, 0,195, -134, 13,203,185,125,251,182, 47,165, 52,133, 16,226, 58,114,228,200, 23,151, 47, 95,150, 78,152, 48,129,107, 50,153, 66,121, 60, - 30, 37,132,204,167,148,206, 45,182,146,241,120, 15, 31, 61,122, 84, 9,114, 47, 56, 40,184,232, 56,235,193, 27,171,162, 8, 72, - 77,138,195,157,144, 43,176,183,183,183,110,222,188,249,243,170, 85,171,234, 18, 19, 19,191, 81,171,213, 59, 74,173,184, 60,222, -211,224,224, 96,119,119,119,247, 55, 2, 43, 77,131,237,183, 56,200,211, 73, 0, 72, 64, 24, 25,172, 28, 43, 41,124, 13, 57,143, -148, 74,165, 65,175,215, 79,203,201,201, 41,181,171,135,203,229,166, 60,121,242, 68,225,225,225, 1, 0,198,163, 71,143,242,244, -122, 61, 40,165,230, 83,167, 78,117,138,141,141,173,227,237,237,205,113,119,119,159, 86,181,106, 85, 77,124,124,252, 23, 26,141, -166,196, 46,148,179,227,125, 12, 45,231, 94,217,152, 21, 21,123, 16, 0,220, 26, 86,203, 56, 57,183,174,190,229,220,220, 50,195, -206,142,247, 49, 96,220,223,182,228,199,136, 25, 51,102, 84,179,179,179,195,152, 49, 99, 48,111,222, 60,204,158, 61,187,234,152, - 49, 99, 70, 1,248,177, 28, 13,165,196,217,217,249,222,154, 53,107, 2,154, 54,109,138,211,167, 79, 99,223,190,125,136,140,140, - 52,121,123,123,243, 26, 54,108,136, 57,115,230,160, 99,199,142, 95,140, 27, 55,174, 37, 33,164,174,133,162,227,179, 57,115,230, -244,108,214,172, 25,134, 15, 31,174,187,114,229, 74, 63, 0,191,159, 63,127,190,205,213,171, 87, 15,239,217,179, 71,178,120,241, -226,118, 19, 39, 78, 28, 3, 96, 93, 5,210,223,171, 69,139, 22, 0,128,102,205,154, 97,217,178,101, 29,223, 71, 96, 17, 66,132, -246,246,246,167,118,238,220, 89,199,207,207, 15, 67,134, 12,169,219,175, 95,191, 83,132,144,246,148, 82,139, 26, 36, 55, 55,183, - 31,142, 29, 59,230, 35,149, 74, 45,190,175, 78,167,179,251,228,147, 79,150, 2, 40,151,192,218,187,119, 47, 38, 79,158,140,218, -181,107,215,106,212,168,209,166,209,163, 71,163, 79,159, 62,109, 9, 33, 78,148, 82,181, 69, 47, 22, 30,207,187, 91,183,110,252, -223,126,251, 13, 0,208,162, 69, 11,180,107,215, 14, 79,158, 60,193,141, 27, 55,192,229,114, 33,147,201,208,180,105, 83, 97, 66, - 66,130, 55,128, 50, 5, 22, 71, 36, 29,209,179, 91, 23,197,241,219,137, 48, 51, 38,212,243,177, 66,195, 0, 71,132,197,229, 32, -248, 89, 28,204,122, 1,172,236,236,209,184,101, 7,187,164,248,200, 17,176,100,120,128, 72, 58,162,119,207,174,242,227,183, 18, -144,149,240,156,190,188,123,228,146, 81,171,254, 2, 0,238, 95,220,191,201,217, 94,210,222, 55,168, 30,183, 85,251, 30,182,191, -237, 75, 26, 1,128, 21, 88, 44,222, 95, 96, 1, 64,142, 30,106,119,159, 26, 72,125,240, 0, 12,195, 32, 61, 61, 29,233,233,233, -240,241,241,193,186,117,239,182, 91, 21, 17, 46,127, 5, 39, 0, 56,217, 91, 97, 72,151, 6,188, 63, 66, 14,136,160,213,126, 16, -206,127, 42, 40,165,148, 16,194,137, 73, 51,218,164,102, 27, 4,253, 91,123, 80, 62,151,131, 1,173, 61,201,250, 19, 49,130, 20, - 53,223,134,195,225,196, 48, 76,217, 19, 9, 9, 33,252,158, 61,123,126,119,224,192, 1,254,243,231,207, 81,165, 74, 21, 24, 12, - 6,220,190,125, 59,142, 82,154,146,127,191, 4, 46,151,155,192, 48, 76,213,218,181,107, 99,201,146, 37, 8, 8, 8, 32, 93,186, -116,153,154, 47,178,254,116,163,132,132,132,197, 95,127,253,117,139, 45,219,247,219, 15,105, 68,160, 82,233,144,151,151,135,176, - 39,247,160, 78, 86, 99,211,166,205,144, 74,165, 4,128, 32, 41, 41, 73, 48,113,226,132,159,221,221,221,187,197,197,197,245, 46, - 81,160, 39, 36, 44, 28, 55,110, 92,195, 93,187,118,217,190, 25,119,165,129, 74, 35,194,157, 85,111,134,152, 53,156,120, 23, 91, -183,252,204,169, 89, 73,102,175, 82,169,240,197, 23, 95,172,113,113,113,105,154,152,152, 56,186, 36,206,196,196,196,235, 95,124, -241,133,219,193,131, 7,197, 85,171, 86, 13,207,206,206, 70, 70, 70, 6,103,207,158, 61,227, 92, 92, 92,172,143, 30, 61, 70,100, - 50, 25, 0,112,163,163,163, 5, 95,127,253,213, 1,103,103,231, 61, 73, 73, 73,195, 75, 42, 27, 0, 58, 66,144, 8,136,124, 36, - 18,238, 92, 64,115,227,202, 28,186,235, 77, 24, 64, 41, 40,153, 75, 6,223, 89, 42,106,166,211, 49,171, 1,125, 56,165,160,152, -243,247,173,167,230,224,224, 48,174,103,207,158, 88,186,116, 41, 78,156, 56, 49,209,206,206,110,213,188,121,243,224,234,234,250, - 53, 33,100, 53,181,124,177,183,229, 63,254,248, 99, 64, 64, 64, 0,134, 13, 27,166,191,112,225,194, 12, 0, 71, 1,196, 92,191, -126,221,115,199,142, 29,221, 15, 28, 56,176,116,205,154, 53,226,117,235,214,249,124,250,233,167,171, 1,140,180,224,131, 98,194, -192,129, 3,177, 98,197, 10, 92,185,114,229, 83, 74,233,233,252, 67,103, 8, 33,221, 23, 47, 94,124,113,214,172, 89,248,241,199, - 31,191, 41,175,192, 34,132,200,171, 85,171,246,125,167, 78,157,112,253,250,117, 52,111,222, 28,141, 27, 55,158, 72, 8, 89, 75, - 41, 77,171,128,184,226,200,229,242, 3,219,183,111,111, 94,169, 82, 37, 44, 92,184, 16,223,125,247, 29,182,109,219,214,124,200, -144, 33, 7, 8, 33,189, 45,153,229,107,109,109, 45,151, 74,165,152, 58,117, 42,141,140,140,204, 44,235,124, 15, 15, 15,219, 85, -171, 86, 17, 91, 91, 91,107, 75,197,176, 88, 44,110, 82,163, 70, 13,204,153, 51, 7,231,207,159,199,172, 89,179, 80,163, 70, 13, -196,196,196, 96,192,128, 1,210,153, 51,103,246, 1,176,221,194,118,201,218,222,222, 30, 41, 41, 41,224,243,249,104,218,180, 41, -142, 30, 61, 10,157, 78, 7, 71, 71, 71,100,101,101,161, 65,131, 6, 5, 98,204,218,194,214,174,134,131,157, 53, 82,158,198,131, - 7, 19,130,124, 29,112,249, 73, 58, 12, 70, 6,142,246, 54, 72, 74, 73, 70,163, 26,238,208,235, 61, 65, 41, 83,195,162, 15, 74, - 46, 39, 72, 36,150, 32, 67,149,134,248,103, 87,210, 13,102,221,232,172,200, 27,177, 0, 96, 87,165,197,232,251, 55,206,223,239, -219,181,133, 99,174,218, 3,132, 50, 13,192,130, 69, 57,192,177,224, 65,249, 83, 88, 94,222,159,123, 9,222, 87,184,252, 21,156, -197,181, 91, 31,163, 5,139, 82,202,184,217,242,178,101, 98,142,233,124,112,138,217,104, 50,227,220,253, 36,179, 84, 68, 76,182, - 34,125, 14,195, 48,148, 16, 66, 45,224, 49,158, 59,119,110,231,248,241,227,177,106,213, 42,188,120,241, 2, 2,129, 0, 53,106, -212,112, 41, 24, 31, 69, 8,177, 14, 10, 10,114,228,112, 56, 8, 11, 11,195,202,149, 43,241,217,103,159,209,155, 55,111,110, 43, -233, 69, 65, 41,125,152,152,152,184,121,242, 55,163,179, 56,121,177,144,209, 52, 24, 50, 94,128,209,164, 98,198,156,197,136, 74, -103,240, 32, 82,133, 7,145, 42,164,233,101, 88,185,254, 23,110, 96, 96, 96,119, 62,159,223,177,148,184,222, 78, 76, 76,220, 57, - 97,194,132,172,148,148, 20, 20, 88, 41, 13, 38, 6, 6,211,187,209, 80, 40, 20,216,180,105,147,141,135,135, 71, 31, 62,159,223, -186, 20,206,248,132,132,132,144, 47,191,252, 82,151,152,152,136,236,236,108,252,254,251,239,237,221,221,221,173,231, 46,254,145, - 68,165,211,183,241,204, 37,246,248,101,207,111, 92, 95, 95,223, 65,124, 62,191,113, 25,175, 47,159,218,181, 3, 14, 69, 71, 71, - 15, 15, 8, 8,248,178, 64, 88, 81, 10, 10, 0, 85,170, 84, 25, 19, 23, 23,247, 89,253,250,181, 14, 1,196,255,111, 54,207,183, -238,223,191,191, 63,195, 48, 56,116,232, 80, 8,165,244,199, 35, 71,142,220,211,233,116, 24, 48, 96,128, 55,222,116, 23, 89,194, - 83,127,208,160, 65, 95, 54,111,222, 28,223,126,251,173,225,194,133, 11, 65,148,210, 85,148,210,104,250, 6, 49,148,210,181, 87, -175, 94,173, 61,110,220, 56, 93,131, 6, 13, 48,124,248,240,207, 8, 33,205,203,224,109, 50,112,224,192, 0,134, 97,176,127,255, -254,199,133,196, 85, 65, 25, 94, 58,124,248,240,109,189, 94,143,193,131, 7, 87, 38,132,180, 41, 71,218, 5, 34,145,232,208,130, - 5, 11,108,226,227,227, 49,116,232, 80, 93, 88, 88, 24,230,206,157, 43,177,182,182, 62, 93,218, 24,193, 18, 13, 36, 34,209,150, -159,126,250,169,103,205,154, 53, 49,118,236, 88,253,198,141, 27,199,127,249,229,151,250,160,160, 32,108,216,176,161,167, 80, 40, - 44,215, 18, 32, 9, 9, 9, 89,161,161,161,246,101,109,113,113,113,201, 22,166, 89,170, 80, 40,110, 5, 6, 6,230,212,168, 81, -163,158,201,100, 66,104,104,232,171,157, 59,119, 50, 53,106,212,192,250,245,235,177,108,217, 50,116,235,214, 13, 92, 46,183, 79, -121,226,170, 86,171, 33, 22,139, 33, 16, 8, 16, 28, 28, 12,157, 78, 7,169, 84, 10,177, 88, 12, 46,151, 11, 27, 27, 27, 40, 20, - 10, 0,160,150,197, 21, 52, 39,207, 8, 62,159, 3, 30,135,193,243,152,108, 24,140, 12,196, 2, 46,248, 60, 2, 80, 6, 54, 50, - 62,196, 66, 46, 56,132, 48, 22,114, 34, 91,109,128, 80,192, 1, 95, 32, 36, 28,147, 89,242,246,229,200, 51, 75, 36, 18, 33,113, -176, 18, 65, 44, 96,125,114,179,248,192, 22,172, 2, 43,147, 37, 34, 69,167,211,189, 87, 68,254, 10,206, 18,204,230, 31, 85, 1, -230,228,228,240,110,221,186,165, 16, 8, 4,162,158,117, 26,166, 45, 59,248, 66, 57,111, 79, 56, 68, 60,144,206,129, 52,249,204, -233, 19, 66,149, 74,229,224,239,239,159,110, 9,159, 86,171,253,130, 16,178, 16, 64,117, 30,143,119,114,251,246,237,100,247,238, -221,182, 3, 7, 14,140, 32,132,196, 7, 6, 6,122,109,223,190,221, 10, 0,214,174, 93, 75, 15, 28, 56,208, 17,111, 92, 95, 36, -149,198,155,152,152, 56, 75, 36, 18,221, 12, 11, 11, 91,203,231,243,109,172,172,172,108,175, 94,189, 74,146,179, 13,248,126, 87, -228,219,153,133, 50, 17, 23,211,123, 59, 98,196,136,207,120,161,161,161,203, 1,156, 43,137, 51, 62, 62,126,162, 84, 42,189, 26, - 18, 18,242,163,194,173,150,157, 67,227,137, 86,109,166,191,233,126,116,182, 21,130,147,223, 38,102,101,101, 33, 45, 45, 13, 19, - 39, 78,180,153, 52,105,210, 20, 0,151, 75,137,231,239, 34,145, 40,230,233,211,167, 29,120, 60,158, 72, 46,151,215,185,117,235, - 22,121,157,101,196,244, 29,175,160,210,190,233,109, 85,136,249,152, 55,208, 29,227,198,141,227, 69, 68, 68,252, 0,160, 89, 9, - 47,176,170,181,107,215, 62,116,238,220,185,106, 11, 22, 44,200,120,254,252,185,154, 16, 50,175,104,181,156, 62,125,122,250,233, -211,167,253,186,116,233,114,136, 16,210,175, 60,227, 93, 62, 36,172,172,172,150,142, 30, 61, 26, 7, 14, 28, 64,102,102,230,234, -252, 58,246,227,222,189,123,247,127,241,197, 23,216,181,107,215, 82, 66,200, 89, 11,172, 88,157, 7, 12, 24,128, 51,103,206,224, -226,197,139,223, 83, 74, 67, 75, 16,181, 47, 8, 33, 83,143, 29, 59,182,102,224,192,129,248,229,151, 95, 58, 1, 40,205,241,108, -251,142, 29, 59,226,244,233,211, 72, 79, 79,223, 80,220, 9, 89, 89, 89, 27,143, 31, 63,222,168, 99,199,142, 88,178,100, 73,123, - 0,151, 44, 16, 26, 1,214,214,214,219,215,172, 89, 83,191,102,205,154, 24, 52,104,144,214, 96, 48,116,250,238,187,239, 78,236, -219,183, 79,177,115,231,206,122,163, 70,141,186, 67, 8,249,220, 82, 39,182, 92, 46,119,241,186,117,235, 70,182,106,213, 10, 19, - 39, 78, 52,157, 59,119,174, 7,165,244,119, 66, 72,196,148, 41, 83, 78,173, 92,185,146,187, 98,197,138,145, 92, 46, 55,213,108, - 54,207,248,155,154,144, 5,107,215,174,109,212,161, 67, 7,188,122,245, 10,183,111,223,134,193, 96,216,117,235,214,173,107, 85, -171, 86, 93,160,215,235, 79,200,100,178, 97, 10,133, 34,176, 78,157, 58,109, 8, 33, 82, 75,198,225, 17, 66,178, 34, 34, 34,100, -142,142,142,224,243,249,120,252,248, 49, 28, 29, 29, 1, 0, 41, 41, 41,168, 81,163, 6,184, 92, 46,178,178,178, 0, 32,219, 50, - 49,196, 9,137,136, 78,168,108,167,144, 1,102, 49, 30,134,197, 65,233, 96, 11, 51,225, 32, 41, 41, 17,117,252,221, 65, 8, 65, - 86,122, 18, 8, 33, 79, 44,225, 52, 83, 38,248,117, 66,138,155,189, 66,132,154,141, 58,216,223, 58,155,186,219,186, 74,179, 81, - 60, 46,225,138,196, 86,155, 71, 14, 31,238,192, 48, 20, 89,233,201,224,113, 56,119, 89,201,192,162, 66, 2,171,164, 65,101, 12, -195, 64, 42,149,190, 99, 97, 42, 42, 82,196, 98, 49,140,198,242,141, 37,149, 74,164, 48,154,153, 15,202, 89, 22,254, 10,206,191, - 19, 38,147, 73, 49,105,210,164,134, 13, 27, 54,140,111,219,182,109,148,159,159, 93,108,183, 70, 18,135, 53,219,142,212,233,210, -178,230,131,172,140,148,180, 72, 43, 43, 93,116,116,180,227,214,173, 91, 27, 26,141, 70,139, 6,112, 80, 74, 95, 3,120, 77, 8, -217,216,169, 83,167,175,250,246,237,139,208,208, 80,199,188,188, 60,199,130, 49, 32,187,119,239,198,129, 3, 7, 86, 81, 74, 45, -118,188,169,211,233,206, 2,240, 33,132,216,120,122,122, 38,219,217,217, 9, 18,115,213,111,103, 22, 10,120, 28, 52,253,238, 30, - 50,179,114,224,224,224, 0,133, 66,225,109,129,229,243, 4,128, 19, 85,219, 79,169,165, 9,217,124,101,199,246,237,214, 0,192, -229, 16, 40,173, 5,200,202,202, 66,106,106, 42,210,210,210,192,225,112, 96, 50,153,170, 89, 16,207, 23, 0, 94, 16, 66, 92,219, -180,105,179, 64,161, 80,128,201, 80, 35, 51,215,240, 78, 23,100,110,110, 30, 42, 85,170, 4,133, 66, 81,163,132,151,140, 2,192, -142, 35, 71,142, 4, 88, 89, 89,113, 39, 76,152, 96, 51, 97,194,132,102, 37,137, 49,153, 76,198, 61,126,252,184,175,179,179,243, -246,252,241, 57,217,255, 95,117, 41,223,229,193,152,201,147, 39,215, 19,139,197, 88,191,126,125, 36,128, 61,249,135, 15,109,220, -184,113,246,192,129, 3,253,199,143, 31, 31, 56,107,214,172,137,249, 93,133, 37,250, 72, 18, 8, 4, 65,213,170, 85,195,145, 35, - 71, 0,224, 72, 25,183, 63,124,243,230,205, 53,221,186,117,131, 88, 44,174, 95,198,185,222, 30, 30, 30, 56,118,236, 24, 0, 60, - 44,225,156,135, 97, 97, 97,232,221,187, 55, 8, 33,222, 22,164,189,103,135, 14, 29, 14, 47, 89,178,132,167, 80, 40, 48,114,228, - 72,253,157, 59,119,186, 80, 74,175, 17, 66, 90, 15, 30, 60,248,234,158, 61,123,100, 87,175, 94, 13, 88,180,104,209, 77, 46,151, -187,216,108, 54,207, 42,131,243,179,133, 11, 23, 78,239,213,171, 23,230,205,155, 71, 15, 30, 60, 56,136, 82,250,123,254,243,117, -142, 16, 50,212,214,214,118,207,204,153, 51, 73,118,118,246,116, 66, 72, 28,165,244,167, 82,172, 65,217,102,179,217, 89,173, 86, - 91,100,130,183,244,124, 7, 7,135,206, 29, 58,116,192,172, 89,179, 48,107,214, 44,172, 95,191,158, 2, 56, 73, 41,125, 12,160, - 69, 65, 61,190,117,235, 86, 96,251,246,237, 5,247,239,223,239, 10,224,160, 5,109, 83,244,229,203,151, 29,187,116,233, 34,144, - 74,165, 48,155,205, 72, 79, 79,135, 86,171, 69,141, 26, 53,208,168, 81, 35,164,164,164,224,228,201,147,134,172,172,172,104,139, -218, 59,189,122,231,249, 83,191,181,238, 62, 96,180,181, 68,192,133,217, 40, 68,114,114, 42, 84,102, 19,130,170,121,161,121, 29, - 79,196, 36,107,112,238,228,111,153, 42, 85,222, 78, 75, 56,141,186,188,237, 23,206,158,104,217,188,243, 96,107,153,127, 32,188, - 93,198,215,185,127,243,194,121,177,144, 79, 6, 15,236,103,211,180,110, 85, 60,142,204,193,153,147, 71, 50,179,115,114,182,131, -197, 95,142,143,101,128,187, 37, 22,172,180,137, 19, 39, 58, 76,154, 52, 9, 86, 86, 86,200,204,204,132, 78,167,123, 43, 82,132, - 66, 33,236,236,236,144,150,150,134,253,251,247, 3, 64,169, 99, 20, 56,128,182,247, 87, 63,136, 20, 86, 50,173, 88, 42,161, 14, - 50,197,123,115, 2, 0,135,195,209,125, 58,229, 23,193,200, 30, 13, 56,157,154,252,249,253, 89, 17,206,127, 3, 12, 6,195,239, - 81, 81, 81,245, 7, 12, 24,144,234,225,225,161,209,106,181,208,104, 52,170,147,251,214, 84,113,179, 26, 27,201,225,112,168, 66, -161, 96, 28, 29, 29,179, 47, 94,188,232,104, 50,153,174,148,243, 22, 19,251,245,235,199,185,112,225,194,152, 47,191,252,146, 84, -173, 90, 21,193,193,193, 88,191,126, 61,221,185,115,231, 26, 0,211, 42, 24,245, 92,157, 78,247,142, 5,164,240,204,194,220,220, - 92,232, 53,201, 48,150, 67, 13, 71, 92, 88, 30, 86,185,114,101, 99,160,151,236,109, 88,102,102, 38, 82,211,210,222, 10,172,212, -212, 84, 0, 40, 79, 31,113,206,159,227,201, 20,126,137, 65,155,151, 4,179,217,172, 47,161,161, 80, 17, 66,214, 45, 94,188,120, -229,154, 53,107, 28,231,205,155,151, 17, 18, 18,146,195,229,114,223, 25, 24,104, 54,155,197, 1, 1, 1,138,159,127,254,217,105, -209,162, 69, 25, 0,214,253, 63,139,171, 94, 53,107,214,220,209,185,115,103,197,151, 95,126,137,181,107,215, 34, 49, 49,113, 26, -165,212,148,159, 14,134, 16, 50,101,195,134, 13, 39,167, 78,157, 10,131,193,176,226,244,233,211,243, 8, 33, 99, 40,165,123,138, -227, 84, 42,149,238, 60, 30, 15, 15, 30, 60,200,161,148,190, 42,163, 65, 77,242,243,243, 75, 38,132, 56,185,184,184, 84, 41,237, - 92, 59, 59, 59, 31,133, 66,129,248,248,120, 0,136, 42,225,180,232,132,132, 4, 42, 20, 10,137,171,171,107,213,178,210,111,107, -107, 59,229,231,159,127,230, 93,190,124, 25,115,230,204,137,139,137,137, 25, 76, 41,189,158, 31,183, 7,132,144,230,173, 91,183, -222, 55,117,234, 84,191, 31,126,248,129,132,133,133,141, 69, 9, 46, 74, 10,224,229,229, 53,230,179,207, 62,195,186,117,235,176, -121,243,230,177,148,210, 67, 69,210,188,143, 16, 98,107,111,111,191,110,244,232,209,216,190,125,251, 96, 0, 37, 10,172,152,152, -152,169,173, 90,181,154,157,150,150,182,216,146, 50,181,228,124, 66, 72,235,110,221,186,249,104, 52, 26,108,223,190,253,213,206, -157, 59, 51,205,102,243,254,124,113, 85, 24, 71,127,251,237,183,217,139, 22, 45,194,153, 51,103,182, 19, 66,184,148,210,125,101, -148,105,130, 88, 44, 78,123,252,248,177,115, 64, 64, 0,199,197,197, 5, 13, 26, 52,128,141,141, 13,184, 92, 46, 82, 82, 82,112, -237,218, 53, 38, 34, 34, 34,205, 82,135,163,105,225,151, 79, 56,215,236,242,199,131, 59,215, 58, 4,214,109,202,119,115,176, 67, -227, 64, 55,216,200, 5, 32, 0, 98, 82, 52,184,116,233,188, 49, 42,234,213, 45, 75,102, 16, 22,112,186,214,234,122,211,198,209, -179, 67,245, 58, 77,121, 85,252,125,209,161, 69,109, 91, 91,153, 0, 12,165,120, 28,153,141,243,191,159, 53, 38,196,197, 94,102, -103, 16,178,248,208, 2,107,249,166, 77,155, 26,252,252,243,207,237, 39, 78,156, 40, 31, 54,108, 24,196, 98, 49,242,242,242,224, -238,238, 14,179,217,140,179,103,207,226,254,253,251,185, 12,195,156, 7,112,183,200, 3,220,174,176,175,140,179, 17, 84,250,198, -121,165,186,193,145, 26,181, 62, 8, 39, 0,200, 95, 50, 86,233,149,244,187,215, 30,186,209,123,239,185, 7,228,219,129, 45, 57, - 65,254, 30, 0, 80, 97,206, 15,240,210,250,203, 57, 77, 38,211, 72, 66, 72,224,148, 41, 83,150,185,185,185,185,206,155, 55,239, -117,245,234,213, 53, 57, 57, 57, 84,175,215, 51,105,105,105,210, 67,135, 14,121,167,167,167,171,140, 70,227,208, 98, 26,206, 82, -227, 73, 41, 53, 0,248,146, 16,114, 60, 59, 59,251,220,119,223,125,135, 69,139, 22,225,196,137, 19,205, 41,165,127, 84, 52,237, -148, 82,147,183,183,119,214,195,135, 15,157,132,246,190,112,178, 17,160,211,247,111,140, 17, 10, 17,129, 70,173,194,243, 39,143, -145,147,147,115,191, 28,156,122, 55, 55,183,236,228,228,100, 7, 39, 39,167, 55,226, 42, 53,245,173,184,202,200,200, 64,122,122, - 58, 5,240, 71, 57, 56,213, 62, 62, 62,121,207,159, 63, 23,114,165, 30,112,182, 21,225, 77, 23, 36,133, 82,193,131, 90,173,194, -179,219,183,144,157,157,125,165, 36, 78, 74,233,254,124,183, 71, 43, 87,174, 92,233, 80,175, 94,189,151,209,209,209, 45, 11,223, -199,221,221,253,232,234,213,171,187, 78,157, 58, 53,109,253,250,245, 83,139, 58,182,252,171,235,146,189,189,253,164, 83,167, 78, - 41, 12, 6, 3,214,174, 93,139, 85,171, 86,109,163,148,254, 90, 36, 47, 78,113,185,220, 13, 28, 14,231,171,175,191,254, 26,163, - 71,143,150,214,171, 87,111, 98, 33, 43,215, 59,156,241,241,241,179,130,130,130,102,167,164,164, 88, 36, 8, 94,188,120, 49, 42, - 40, 40,104, 86, 74, 74,202,178,210,210, 46,147,201,100,102,179, 25, 81, 81, 81,153, 37,137, 80, 74,169,214,215,215, 55,222,108, - 54,187, 75,165, 82,187,178,234,103,102,102,230,226,122,245,234,205, 77, 78, 78,254, 29,192,194,162, 46, 71, 40,165,143, 8, 33, -129,223,124,243,205,184,165, 75,151,246, 78, 74, 74,218, 95, 22,103, 76, 76,204,226,214,173, 91,127, 31, 30, 30,190,131, 82,186, -185,132,120,174, 39,132, 24,118,239,222, 61, 54, 42, 42,106, 73,105,156,148,210,147, 0, 78,150,195, 10, 80,236,249,133, 57,185, - 92,238,148,165, 75,151,114, 54,109,218, 4, 74,233, 10,147,201, 84, 82, 60, 31,115,185,220,157, 77,155, 54, 29,118,232,208, 33, -113, 96, 96,224,104, 0,251,202,170,159, 58,157,238,246,205,155, 55, 27, 69, 71, 71, 59,180,110,221, 90, 0, 0, 57, 57, 57,200, -202,202,194,201,147, 39, 13, 17, 17, 17,105,106,181,250,118,121,218, 16,147, 62,103,224,205, 75,199,246, 69,191,120,210,184, 85, -167,158,182,122,131, 59, 68,233, 92,100,165, 39,225,236,201,223, 50,163,162, 94,221,202,203,203, 26, 88, 30, 78,131, 46,123,192, -173,203,199,247,199, 69, 61,111,212,162,117, 23, 91,173,222, 11, 34, 1, 7,233,201,241, 56,123,234, 88, 70, 84, 84,228,117,173, - 81, 55,252,239,106,231,255, 75,156, 31,163, 57,174,204, 13,128, 0, 64, 59,185, 92,190,104,246,236,217, 43,238,220,185,179,162, - 91,183,110, 43, 68, 34,209, 34, 0,237, 0, 8, 74,184,174,221,255, 39,103,125, 87,216,181,174, 66,174,117,240, 33,204,152,230, -182,230, 17,141,100,186,247,229,172,232,246,255,205, 9,160, 25,159,207,191, 85,179,102,205,203, 10,133, 34,181, 82,165, 74,215, -249,124,254, 93, 0, 45,222, 55,158, 0, 28,250,247,239,207,168, 84, 42,218,175, 95, 63, 10,192,250,125, 57, 69, 34, 81,155, 86, -173, 90, 25, 95, 39,102,210,235,143, 98,233,201,171,161,116,239,137, 91,116,243,190,115,244,199, 13,191,208, 90,181,106,233, 1, -120,149,135, 83, 40, 20,118,106,213,170, 85, 86, 90, 90, 26, 13, 11, 11,163,215,174, 93,163,135, 15, 31,166,155, 55,111,166, 27, - 55,110,164,174,174,174,233, 0, 92,203,195, 41,145, 72,122,118,234,212,201, 20,159,154, 75,111,135, 38,209, 11,119, 94,209,163, - 23, 31,211,253, 39,111,209,109,187,127,165, 1, 1, 1, 90, 0, 78,101,113, 2,232,223,182,109,219,151, 54, 54, 54,155,138, 30, -147,201,100, 27,218,180,105, 19, 3, 96,232,223, 81,151, 0,116,114,115,115, 11, 19, 8, 4,167, 74,138, 67,161,115, 7,240,120, -188, 19,206,206,206,247, 0,124,242,255, 93,231, 1,116,115,116,116,188, 13,160, 71, 25,215, 21,156,215,235, 99,124,222, 63, 80, -185,183,225,241,120,215,240,198,199,149, 37,239,128, 5, 92, 46,247, 52,128,182,229,137, 39, 0, 87,185, 92,222, 76, 46,151,119, -151,203,229,221,109,108,108,154, 21,126, 14, 43,146,118,123,223,118,221, 61,235,246, 56,234, 81,187,107,140,103,157,110, 49,222, - 65, 61,143,218,251,182,235,254,190,156, 94, 65, 61,143,121,214,233,246,218,179, 78,247,232,202,245,123, 30,117,240,111,215,249, - 99, 43,247,127, 50,103, 9,247, 25,245,255,113,159,191, 98, 35,150,207,184, 6, 8, 33, 50, 0,237, 1,212, 3,112, 31,192,249, -210,252,162, 88,162,112,255, 10,206,198,174,196, 79, 38, 37, 71, 4, 60,174,227,233, 48,211, 23, 31,130,243,223,242,197, 64, 8, -233,201,227,241,190, 51,153, 76,203, 41,165,199, 62, 84, 60,173,173,173,127,238,208,161,195,136,163, 71,143,110, 52, 24, 12,227, - 62, 4,167,131,131,195,202,170, 85,171,142,235,215,175, 31,223,221,221, 29,105,105,105, 8, 13, 13,197,181,107,215,244, 9, 9, - 9, 99,210,211,211,119,148,151,211,197,197,101,161, 82,169, 28, 59,121,242,100, 91, 30,143,135,244,244,116,100,100,100,208,237, -219,183,167,171,213,234, 47,210,211,211,143,151,151,211,201,201,105, 75,213,170, 85,135, 15, 25, 50,132,239,229,229,133,180,180, - 52, 60,124,248, 16,231,206,157,211,189,126,253,122, 72,110,110,238,175,150,112, 18, 66,132, 37,249, 61, 34,132,240, 75,114,138, -201,126, 37,179,156, 44, 39,203,249, 95,181, 96, 17, 66, 70, 81, 74,183,224, 95, 8, 94,121, 78,206, 23, 41, 71, 8, 33, 39, 10, -198,103,124, 0, 11,218, 7,231,188,149, 64,195, 1, 4, 16, 66,120, 31,138,243, 95,100,145, 60, 6,224,216,135,230,205,206,206, -254,156, 16, 50,158, 82,170,249, 80,156,105,105,105,147, 8, 33,187, 95,189,122,181, 66, 38,147,213, 49,155,205, 70,173, 86,123, - 35, 53, 53,117, 34,165, 52,182, 34,156,137,137,137,179, 8, 33, 71,166, 77,155, 54, 13, 64, 45, 66,136,222,104, 52,222, 76, 73, - 73,153, 79, 41, 77,172, 8,103,114,114,242, 40,129, 64,240, 75, 68, 68,196, 18,137, 68, 82,139, 97, 24,125, 94, 94,222,149,180, -180,180, 9,148,210,228,114,148,141,190,148, 99,236,186,131, 44, 88,176, 96,241, 17,129, 87,145,139,254, 10,209,242,111,225,252, - 47,227, 67,138,171, 66,156,143, 1,180,253,192,156, 15, 1,244,253,144,156, 6,131,225, 14, 44, 92,155,141, 5, 11, 22, 44, 88, -176,224,177, 89,192,130, 5, 11, 22, 44, 88,176,248,187, 64, 8, 25,245, 81,166, 11,111, 6,127, 23,103, 5,184, 80,142,204,105, - 87,222, 27, 91, 48,150,136,229,100, 57, 89, 78,150,147,229,100, 57, 89,206,143,140,179, 44,238,143,102,118,226, 95, 60,250,159, -157, 97,193,114,178,156, 44, 39,203,201,114,178,156, 44,231,127,110, 99, 23, 88, 98,193,130, 5, 11, 22, 44, 88,176,248,192, 96, - 5, 22, 11, 22, 44, 88,176, 96,193,130, 5, 43,176, 88,176, 96,193,130, 5, 11, 22, 44, 88,129,197,130, 5, 11, 22, 44, 88,176, - 96,193, 10, 44, 22, 44, 88,176, 96,193,130, 5, 11, 22, 21,199, 59, 75,229, 16, 66, 40,165,148,176,217,194,130, 5, 11, 22, 44, - 88,176,248, 91,132,201, 71,162, 69, 88,129,197,130, 5, 11, 22, 44, 88,176, 96, 5, 22, 43,176, 88,176, 96,193,130, 5, 11, 22, -172,192,250, 23, 8,172,130,196,176, 2,139, 5, 11, 22, 44, 88,176, 96,241,119, 10,171,143, 69,139, 20, 12,114,111, 69, 8,161, - 96, 23,179,101,193,130, 5, 11, 22, 44, 88,252, 61,248,168,180,200, 59, 93,132, 44, 88,176, 96,193,130, 5, 11, 22, 44, 88,129, -197,130, 5, 11, 22, 44, 88,176, 96,193, 10, 44, 22, 44, 88,176, 96,193,130, 5,139,143, 29,127,169,163, 81, 66, 72, 59,150,147, -229,100, 57, 89, 78,150,147,229,100, 57, 89, 78, 86, 96,177, 96,193,130, 5, 11, 22, 44, 88,176, 96, 5, 22, 11, 22, 44, 88,176, - 96,193,130, 5, 43,176, 88,176, 96,193,130, 5, 11, 22, 44, 88,129,197,130, 5, 11, 22, 44, 88,176, 96,193,130, 21, 88, 44, 88, -176, 96,193,130, 5, 11, 22,127, 19, 8,128, 98,103, 2, 80, 74, 47, 88, 76, 82,129,217, 4,101,241,179,156, 44, 39,203,201,114, -178,156, 44, 39,203,249,241,113,150,197, 93, 30,253,241,143, 6,165,244, 47,219, 0,180, 99, 57, 89, 78,150,147,229,100, 57, 89, - 78,150,147,229,252,175,109, 60,214,136,199,130,197,191, 28,135, 9, 23,153,254,222,160,212, 21, 92, 97, 34, 18, 67, 94, 97, 14, -101,222,155, 51,185,186, 23, 36, 70, 39,152,196,169, 72,126, 28,249,222,156, 44, 88,176, 96,241, 31, 2, 43,176, 88,176,248,183, - 35, 53,192, 15, 60, 44, 1, 7, 46,160,134, 8, 40,171, 47, 1,240,228,189, 57, 5,204, 66,152, 57,238,160,134,112, 56,250, 47, - 5, 16,202,102, 54, 11, 22, 44, 88, 88,134,191,101,144, 59,159,207, 15,230,243,249, 11, 8, 33, 34,182, 8, 88,252, 85, 32,132, -136,248,124,254, 2,177, 88, 28,252,209, 38,114,119, 77, 41, 56,230,206,122, 35,227,118, 54, 36,203, 49, 79,103,246, 3,199,212, - 5,191,248,201,223,139,147, 71, 58,104, 13,140,231,158,187,121, 78,106,189,169, 26, 40,222,143,243,127,101, 98, 35, 20, 10,207, - 18, 66, 28,216, 26,250,113,162, 58, 33,245,234,243,249,147,171, 17,210,134, 16, 66,216, 28, 97,193, 10,172,255, 71,152, 76,166, -186,190,190,190, 19,121, 60, 94, 12, 33,164,199,127, 41,195, 37, 18,201, 77,185, 92,158, 44,151,203,147,101, 50,217,131,194,225, - 50,153,236, 79,225, 31,169,240,241,115,116,116,140,177,183,183, 15, 47, 28,238, 88,187,119, 19,223,102,195,230, 56, 4,246,106, -249, 1,238,209,131,207,231,199, 4, 6, 6, 78,208,233,116,117, 63,218,204,212, 50, 78,224,112, 91, 63, 77,204,147, 38,230, 24, -157,130,163,243, 20, 0,183, 21,244,112,169, 48,103, 54,227, 4,208, 54,143,226, 52,178,155, 25, 74,167,235,175,116, 86,224,112, - 90, 67, 75,156,223,187,193,225,112,198, 50, 12,211, 94, 32, 16,124,203, 54,191, 31, 39,132, 28, 78,211,155, 61,122, 44,156, 90, -171,214,184, 0,160,123,113, 34,139,188,193,248,106,213,170,157, 33,132, 12,248,128,109,203, 15, 1, 1, 1,241,132,144,111,216, -146, 96,241,175, 17, 88,125, 43,147,166,131,170,144,171,253, 43, 19,213,128, 42, 36,119,104, 21,114,163, 79,101,210,166,162, 55, -126,240,224,129, 36, 36, 36,196,177, 73,147, 38,251,197, 98,241, 13, 66,136,111,133, 30,102,161,240, 44,143,199,235, 91, 76, 88, -255, 34, 97, 79,133, 66, 97,182, 80, 40,124,101, 9, 47,159,207,127,201,227,241,212, 2,129,224,101,225,112, 30,143,215, 95, 36, - 18,157, 45, 18,214,183,104, 88, 41,188,238,209,209,209,142,177,177,177,142, 66,161,208,169, 32,156,203,229,186,199,196,196,252, - 41,188,188,224,243,249,109, 68, 34,209,225,178,194, 74,131, 72, 36,250,149,207,231,183, 41, 43,172,162,226,170, 67,135, 14, 55, - 18, 19, 19, 61,109,108,108,108, 10, 31,179,179,182,233,184,107,219,134,137, 61,187,116, 24,235, 88,253,147,154, 21,228,247, 21, -139,197, 55,130,130,130,246,159, 60,121,210,113,215,174, 93,210,143,246,233, 61, 92, 93, 0,194,180, 96, 40, 85, 62,139,215, 42, -187,246,232,203,123, 24,171, 81, 26,205,102, 59,128,219, 10, 59, 42,137, 42,196,201, 51, 54,103, 40,117,186, 24,205, 87,182,238, - 55,142,123, 41,154,167, 52,154,205,246,224,160,101,133, 56,255, 87, 54,124, 46,151, 59,113,229,202,149, 28, 0, 95, 19, 66,132, -255,165,198,182,161, 27,113,107, 91,149,119, 55,200,149, 52,253,128,130, 34, 80, 38,147,221, 39,132,248,253, 83,210,169,103,152, -176,253,145,145,231,134,248,248,116,155, 90,171,214,136,162, 34, 43,255,247,212,165, 75,151, 14,125,250,244,169,178,114,229,202, -163, 9, 33,156, 15,144, 23,171,151, 46, 93, 58,229,233,211,167,174,222,222,222,243, 62, 4, 39,139,127,150,118, 7,208, 26, 64, - 87, 0,109, 1, 52,200,255, 93, 63,127,235,138, 55, 94, 17, 10,239,235,231, 95, 91,112,188, 97, 9, 28, 93,139,185,174,126,161, -240,194,255,139,254, 46, 25,249,179, 1,104,225,125,209,173,191, 55,230,142,107,226,150,247,236,196, 94,154, 27, 27, 73, 51,159, - 63,164, 15,183, 44,166,227,234, 43,243, 6, 85,198, 15, 21,152,125, 64, 41,165,244,244,233,211, 84,165, 82,209, 95,127,253,149, -113,116,116,212, 10,133,194,213, 0,100,229, 26,165,207,227,229, 90, 89, 89,169, 4, 2,193,118, 0, 66, 74, 41,248,124,126,174, -173,173,173, 74, 32, 16,236, 6, 32,162,148,162,125,251,246, 26, 74, 41, 21, 8, 4,106, 75,120, 59,116,232,160,166,148, 82, 30, -143,167,206,143,179, 72, 32, 16,236,170, 86,173, 90, 14,159,207,207,205, 15, 19,138, 68,162,237,129,129,129, 57, 2,129, 32,215, - 18, 94, 43, 43,171, 88,147,201, 68,215,173, 91, 71,237,237,237, 19, 10,194, 21, 10, 69,172,201,100,162,107,214,172,161,118,118, -118, 9, 21,200, 83,142, 88, 44, 94, 94,179,102,205, 44,177, 88,156, 94, 40,108, 69,237,218,181,179, 37, 18, 73,186,165, 92, 34, -145, 40,221,222,222, 62, 83, 40, 20,174, 0,192,161,148, 66, 44, 22,167, 59, 58, 58,102,136,197,226,229, 5, 97,150,108,174,174, -174,163, 29, 29, 29, 19, 28, 29, 29, 19,108,108,108, 22,185,184,184, 36,165,166,166, 82, 74, 41,173, 82,165, 74, 10,165, 20,202, - 90,159, 52,169,218,116,232, 28,199,192, 30, 19, 54, 29,186,117,231,218,147,244,212, 90,237,199, 46,183,174,213,211,186, 28,233, -151,241,249,252,213, 78, 78, 78,218,125,251,246,153, 35, 35, 35,233,185,115,231,232,139, 23, 47,104, 73,245,250, 95,191,109,168, -238, 78, 55,251,239, 15,157,237,249,252,218,210, 78, 70, 26,125,137,238, 29,161, 52, 94,157,224, 22, 65,127, 10,248,149,110,174, -230, 81, 33,206,159,170,237,125, 60,211, 51,108,221,188,241,198,152,152, 24, 58,121, 88, 39,211,239,227,220, 94,209, 77, 1,135, - 42,196,249,191, 50, 26,248,201, 39,159,228,190,126,253,154, 86,175, 94, 93,205,229,114, 71,254, 87,102, 19, 53,112,133, 91, 59, - 63, 97,252,227, 61,147,153,238,129,210,244,186, 46,104,250, 1,102,113, 5, 58, 58, 58,166,237,216,177,131, 42, 20,138, 20, 0, -126,255,132,180, 2, 32, 1, 64,143,157,181,106, 29, 99,250,244, 49,239,172, 85,235, 88, 0,208, 3,111,220, 2, 17, 0,211,150, - 45, 91, 22,108, 52, 26,131,183,111,223, 30,220,163, 71,143, 96, 0,147,223,243,158,107,126,248,225, 7,106, 52, 26,233,246,237, -219,105,143, 30, 61, 40,128,181,150, 94, 47,151,203,171,214,172, 89,115,119,245,234,213, 95,215,174, 93, 91, 95,173, 90, 53,173, -159,159, 95,116, 96, 96,224, 14,145, 72,228,205,206,136,251,127,171, 59,165,105,145, 6,211,166, 77,155, 14,128, 78,155, 54,109, - 58,165,180,107,254,121, 93, 11,255, 46,186,167,148,182, 43,252,191, 56,142,130,173, 56,206,226,238, 81,228,119,201,233, 41, 72, - 12,128,150, 0,174, 22, 61,161,111,101, 52, 25,215,196, 77,163, 73, 77,164, 79, 22,127, 75, 47,183,118,167,127,180,114,166,225, - 19, 63,161,137,123, 86,211, 47,235,216,230,245,169,140,214, 21, 17, 88, 43, 87,174,164, 91,182,108,161,193,193,193, 52, 38, 38, -134, 78,157, 58, 85, 47,149, 74, 51,185, 92,238, 96, 75,185,132, 66, 97,246,139, 23, 47,232,196,137, 19,117, 66,161,240, 37,128, -202, 98,177, 56, 59, 50, 50,146,206,156, 57, 83, 47, 18,137, 34, 1,248, 10, 4,130,220,187,119,239, 82,161, 80,104,145,192, 18, - 8, 4,217,167, 79,159,166,124, 62, 95, 13,192,215,214,214, 54,242,212,169, 83, 70,134, 97,168,179,179,115, 14,128,202,246,246, -246, 47,207,156, 57, 99,100, 24,134,186,184,184,228, 88,194,107,109,109, 29,155,155,155, 75,183,109,219, 70, 29, 28, 28, 18, 10, - 11, 47,149, 74, 69,183,108,217,242, 78,184,133,249,233,228,228,228,244,176, 32, 46,158,158,158,169, 0,156, 28, 29, 29, 31,157, - 63,127,222, 72, 41,165,149, 42, 85, 74,181,148,207,193,193, 33, 37, 42, 42,138, 46, 94,188, 88, 39,149, 74, 31, 0,112, 82, 42, -149, 41, 49, 49, 49,116,201,146, 37, 58,169, 84, 26, 12,192,201, 66,174, 4,189, 94, 79,179,178,178,104,195,134, 13,115,255,248, -227, 15,154,147,147, 67,243,227,148, 66, 41,133,127,203,145, 11,238,188,200,205,249,108,202,134,131,222, 13, 6, 45, 62,119, 55, - 62,238,231,163,247,131, 29, 2,123,118,178,228, 30, 92, 46,119,176, 68, 34,201, 92,178,100,137, 33, 57, 57,153,222,187,119,143, - 30, 60,120,144, 30, 58,116,136,190,122,245,234,227, 20, 88,135,192,165,155,253,123,210,205,254,193, 59,134, 56,164,169, 30,236, -163,244,252, 55,244,213,130,202,116,118, 39,133,138,217,236, 31, 76, 55, 7,244,161,115, 91,242,202,197,185,165, 90,119,186,217, - 63,248,135,190, 94,233, 15,131,239,209,171, 87,175,210,141,171,151,209,113,237,220,212,204,102,255, 96,250, 83,181,222,229,226, -124, 87,184,191,184,113,227, 6,189,118,237, 26,157, 55,111, 30,149, 74,165,175,223, 63, 31,170, 9,232, 79,126, 94,116,171, 95, - 75,186,205,215,133, 94,169, 88,220,254,106,113,213,222, 79, 24,151,246,240, 40,165, 25, 47,105,210,138,234,180,147, 63,255,189, - 68, 86,190,184, 74,141,142,142,166, 73, 73, 73,116,213,170, 85,212,202,202,234, 31, 45,178,252,129,158, 0,166, 47, 95,190,252, -173,184,218,176, 97, 67,112, 72, 72, 72,176,167,167,231,233,247,184,215,218,229,203,151,191, 21, 87, 27, 54,108,160, 33, 33, 33, -212,203,203, 43,182,172,107,135, 12, 25, 34,109,210,164, 73,240,224,193,131,243,118,236,216, 65,163,163,163,233,227,199,143,233, -242,229,203,233,156, 57,115,232, 47,191,252, 66,123,247,238,173,110,216,176,225,157, 62,125,250,136,203, 25, 55, 30,165, 84,152, -191,241, 41,165, 5, 2,147, 7,128, 15,128,203,138,170, 63,107,131,146,180, 72, 73, 34,170, 36, 97, 85,244, 88, 41, 2,172, 84, -161, 86,214,253, 74, 75, 79, 97, 19,234, 21, 74,233,159,198,190,240, 40,230,143,154,180, 64, 28,181, 99, 21,146, 15,172, 7, 55, - 43, 25,124, 85, 58,116, 55, 78,193,120,227, 56,134, 54,110, 44,145, 16,178,176, 34,246, 62,185, 92, 14,129, 64,128,151, 47, 95, -226,249,243,231, 24, 49, 98,132,224,226,197,139, 54, 77,154, 52,217, 34,147,201, 30, 17, 66,106, 89, 48,166, 3, 85,171, 86,197, -248,241,227,133, 27, 54,108,168, 34,147,201, 30,152,205,102,190,183,183, 55,190,254,250,107,193,246,237,219, 43, 89, 89, 89,221, - 99, 24, 70, 32,149, 74, 97,233,152, 75, 46,151, 11,137, 68, 2,134, 97,248, 65, 65, 65,247,159, 60,121,226,221,190,125,123,222, -249,243,231,145,145,145,193, 11, 10, 10,122, 20, 18, 18,226,211,174, 93, 59,222, 31,127,252,129,156,156, 28,106,161, 25, 27,121, -121,121, 16,139,197,239,196,165, 32, 92, 36, 18,161, 60,227, 66,249,124,126,155,198,141, 27, 63,125,248,240, 97,237,182,109,219, -242,174, 92,185,130,244,244,116,126,189,122,245,158, 62,122,244,168, 86,235,214,173,121,183,110,221, 66, 86, 86,150,197, 83,236, - 37, 18, 9, 42, 85,170,132,207, 62,251, 76,248,203, 47,191,212,182,179,179,123,204,231,243,133,158,158,158, 24, 49, 98,132,112, -219,182,109,117,236,237,237, 31, 89,216,101,200, 5, 0,163,209,136,209,163, 71,203,172,172,172, 16, 27, 27, 11,134, 97, 96, 54, -155, 1, 0,233,153,233, 33,143, 66,158, 60, 31, 58,176,111, 75,141, 65,167,187,117,247,254,179, 42,149,188,220, 9,161,149,202, -200,203, 90, 34,145,232,209,167,159,126,186, 53, 58, 58,218,102,192,128, 1,252,251,247,239,227,245,235,215, 16,137, 68,144,203, -229,224,241, 62,210,137,178, 57,213,237,193,160,125, 76,170, 94, 36,178,113, 87,200, 93,252,128,215,215, 80, 89, 41, 2,151,195, - 21,223,139,204,147, 1,180, 61, 60,211,236,203,199,201,180,143, 76,209,139,140,118, 53,228,174,238,158, 72, 79, 79,135, 71,149, - 0,104,133, 74,225,205,151,106, 57, 72, 57, 57,255, 87, 86,205,125,125,125,157,171, 86,173,138,180,180, 52,212,173, 91, 23,182, -182,182,182,132,144,246, 21,206,131, 29,149, 68,200, 65, 83,128,179, 2,102, 50, 15, 70,222, 18,188, 76,173,139, 45, 65,252,127, - 82,183,160,149, 92,120,123,223,254, 3,110,246,158,213,128, 83,159,193,201, 70,132,109, 99,235,218, 41,173, 69,199, 42,210, 93, - 72, 8, 9,116,114,114,186,116,231,206, 29, 7,177, 88,140, 7, 15, 30,160,122,245,234, 88,181,106,149,210,214,214,246,218, 63, -161,187,144, 82, 74,159, 3, 39,126,120,252,120,251,238,136,136,147, 67,124,124,186, 13,246,243, 91, 52,102,192,128,145,227,199, -143,199,178,101,203,112,236,216, 49, 52,109,218, 20,163, 70,141, 50,190,126,253,122,103, 5,187, 5,215,175, 88,177, 98,220, 55, -223,124, 83,148,211, 16, 19, 19,243, 67,105,215, 6, 6, 6,186,191,120,241, 34,126,226,196,137,117,119,239,222, 45,145, 74,165, -200,202,202,194,214,173, 91, 49,125,250,116, 16, 66, 64, 41,197, 47,191,252, 34, 29, 49, 98, 68,131,136,136,136,248, 74,149, 42, - 89, 50,124,131, 0, 16, 3,144,230,111, 50, 0,210,125,251,246, 89,247,236,217,211, 42, 63, 76, 2, 64,194, 78,244, 42, 22,197, -106,145, 66,101,126,178, 72, 93,235, 86, 52,172,232, 49, 74,105,183,210, 56,202, 89,183,187, 89,122,125, 97,129,213,138, 16,114, -245, 79,100, 64, 45,103,111,127,100,159, 63, 4, 9,143, 64,194,205,223,120, 4,156, 87, 33,240, 16,243, 97,164, 52,176,162, 2, -171, 96,227,112, 56, 72, 76, 76,132, 72, 36,194,174, 93,187,196, 43, 87,174,172, 41,149, 74,111, 89, 91, 91, 47, 41, 75, 96, 1, -192,189,123,247, 80,187,118,109,178,119,239, 94,171, 65,131, 6,241, 0, 32, 36, 36, 4, 53,106,212, 32,199,143, 31, 87,140, 29, - 59,150,200,100, 50,139,197, 11, 33, 4, 18,137, 4, 35, 70,140, 32,183,110,221,146, 75, 36, 18,156, 58,117, 10,169,169,169, 24, - 57,114, 36,239,214,173, 91,114,153, 76,134,107,215,174, 33, 59, 59,187, 92,188, 90,173, 22, 18,137,228, 79, 2, 75,163,209, 64, - 34,145, 88,156,127,118,118,118,115,106,214,172,121,248,234,213,171,246, 18,137, 4, 87,174, 92, 65, 86, 86, 22,102,206,156, 41, -189,121,243,166,189,149,149, 21,242,197, 21,184, 92,174,229, 3,243, 10,229,169,175,175, 47,217,183,111,159, 99,255,254,253,197, - 0,240,240,225, 67,248,249,249,145,189,123,247, 58, 85,169, 82,229,144,157,157,221,236,210,184, 24,134, 65, 98, 98, 34,158, 62, -125,138, 87,175, 94, 33, 53, 53, 21,105,105,105, 80,169, 84, 48,153, 76, 0, 0,169, 42,231,212,190,131, 39, 30, 73, 36, 18,105, -117, 63, 95,207,144, 39,161, 41, 18,137, 68,234,229,233,233, 71,200, 60, 78, 9, 34,112,137, 72, 36,186,117,232,208,161, 90, 91, -183,110, 21,189,120,241, 2, 15, 30, 60,248, 83,189,250, 40, 5, 22, 33, 4, 68,239, 11, 66,234,222,126,165,182,107,222,109,160, - 0,145,103, 1,198, 8,112,120,104, 85,203,157,119, 44, 68,237, 4,138, 90,208, 33, 0,176,160,114, 18, 66, 0, 67, 85,128,212, -251,253,133,201,190,233, 39, 99, 5,241,241,241, 16, 8, 4, 16,137, 68,168,219,230, 83,222,190, 71, 70,103, 16,212,134, 1,254, - 22,113,190, 91, 94,223,207,153, 51, 71, 86,152,115,228,200,145, 50,107,107,235, 57, 21, 22, 87,106,105, 99,152,232, 55, 79,227, -243, 42, 45, 58,149, 84, 45, 34, 69,227, 15, 74, 39, 2,198, 58,239, 43,178, 8, 33,173,196, 98,113, 36, 33,164,217,123,137, 43, -133,240,214,254,253, 7,220,236, 60,222,136, 43,152,180, 0, 95, 2,103,165, 13,182, 77,104,109,167,180,145,148, 75,100,229,139, -171,139,183,111,223,118, 16,139,197, 8, 14, 14,134, 64, 32,128, 88, 44, 70,205,154, 53,177,121,243,102,165,157,157,221, 63, 74, -100, 45,125,252,120,199,146,167, 79,195,167, 5, 6, 6,244,146,201,236,190, 26, 60,216,122,230,204,153, 39,143, 31, 63,190,189, -107,215,174,105,119,239,222,253,145, 82,122,168,156,229, 67, 8, 33, 27, 86,174, 92,249, 85,129, 96,155, 57,115,230, 47,199,143, - 31, 95,210,181,107,215,196,187,119,239, 78,164,148,110, 40,141, 35, 55, 55,247,248,172, 89,179,172, 63,249,228,147,130,255,184, -113,227, 6,118,238,220, 9,153, 76,246,206,185, 61,122,244,192, 23, 95,124, 97,171,215,235,127, 45,141,211,201,201,169,237,237, -219,183,171, 3, 16, 0, 16, 21, 8,172, 39, 79,158,216,228,228,228,216,200,229,114, 27, 23, 23, 23, 69,129,200,250,228,147, 79, -108,248,124,126, 51,176, 64, 89, 90,164,176,192,177, 36,172,162,231, 91, 42,178,202, 37,176, 40,165, 87, 1,180, 40,238, 36, 67, - 70, 50, 68, 48, 67,194, 37,144,114, 11,137, 44, 48,224,101,167,160,162, 19,113, 11,191, 8, 21, 10,197, 91,161,149,151,151,103, -177,104, 41, 56,199,214,214, 22, 42,149, 10, 70,163, 17,114,185,252,109,152, 78,167,131,217,108,134, 76, 38, 67,121, 44, 88, 5, - 2,139, 97, 24, 92,187,118, 13,127,252,241, 7,120, 60, 30,236,236,236,192, 48, 12,110,221,186,133,144,144, 16, 8, 4, 2,216, -217,217,149,139,215, 96, 48, 20,107,193, 50, 24, 12, 16,137, 68,111, 5,142, 37, 66, 72,171,213,210, 71,143, 30,225,201,147, 39, - 16,137, 68, 80, 42,149, 16,139,197,136,143,143,199,243,231,207, 33, 20, 10,161, 84, 42, 45,230, 44, 44,176,172,172,172,144,153, -153,249, 70, 4, 73,223,140, 21,183,182,182,134, 90,173, 6,143,199,123,187,149, 6,179,217,140,132,132, 4,164,166,166, 34, 54, - 54, 22,105,105,105,111, 69, 22,195, 84,220,111,101, 65, 28,111,220,184, 65, 47, 93,186, 4,149, 74,245,167,186, 84, 96, 33,253, -232,176, 49,208, 26, 70,126,135,180, 92,163, 40,213, 32,176,118, 10,108, 7, 68,158, 1, 56, 60, 64,108,139, 70, 53, 42, 35, 38, -211, 44, 11, 75,214,139, 65,208, 17, 27,252,108, 45,226, 52,243,219,167,170,140,162,104,131,210,170, 90,173, 32, 36, 39, 39, 67, - 36, 18, 65, 36, 18,161, 94,211,118,136, 76, 55, 75, 67,227, 53, 82, 80,116,176,136,243,127,117,187,138, 92, 46,111,220,172, 89, - 51, 82,152,179, 75,151, 46, 32,132,212, 36,132, 4,148, 43,253,235,124,132, 48, 72, 27,129, 71,191, 9, 77,204,115, 61,246, 68, -235,215,189,215,167,118,107, 46,164, 84,123,150,164,243, 6, 53, 78, 2, 53, 4, 85, 84,100, 17, 66, 90, 42, 20,138,147,235,214, -173,243, 22,139,197,103, 8, 33,205, 43,212,190, 73,184,155,190,255,106,160,155,109,129,184, 50,230, 1, 60, 9,192,151, 0, 60, - 9,156, 29, 29,176,240,139,246,118, 82, 49,255,183,114, 8,213,125, 27, 54,108, 80, 22, 21, 87, 5, 91,221,186,117, 49,123,246, -108,165,157,157,221,222,191,249, 27,160,131,141,141,205,238,118,237,218,221, 78, 80, 40,190, 72, 12, 10, 18, 94,180,182,206,110, -155,157,109,237,245,228,137,193, 31, 8, 1,176, 49, 54, 54,182,147,165,226,138, 16, 50,192,218,218, 58,184, 93,187,118, 6,133, - 66,241,122,213,170, 85, 95,126,253,245,215, 88,182,108, 25,102,205,154,181, 21,192,231,148,210, 25,177,177,177,174,101,137, 43, - 0, 72, 74, 74, 26, 52,117,234,212,180,180,180, 52, 0, 64,205,154, 53,145,149,149,133,201,147, 39,227,219,111,191, 5, 0,212, -169, 83, 7,148, 82, 36, 39, 39, 99,197,138, 21,201, 73, 73, 73,195,203,104,239, 98, 15, 29, 58,212,192, 96, 48,184,231,119, 3, -138,178,178,178,172, 50, 50, 50, 20, 6,131, 65,198, 48,140,204,198,198, 70, 14, 64, 58,116,232, 80, 94,104,104,104, 53,147,201, - 20,207,106,170,119,196, 75,137, 90,164,130, 56,245, 62,150,170,226, 44, 96, 22,191,167,242,137, 72,225,125, 97,112, 9, 30,191, -190,127, 13,118,129, 65,239, 88,175,164, 92, 2,137,149, 53, 34, 99, 99, 32, 0,121, 90,129,200,191, 35,176, 10, 94,140, 17, 17, - 17,232,209,163, 71,222,226,197,139, 67,212,106,117,227,236,236,236,233,150, 8, 44,165, 82,137, 71,143, 30,209, 17, 35, 70,228, -108,221,186,213, 4, 0,142,142,142,120,242,228, 9,237,221,187,183,106,197,138, 21, 84, 42,149, 90,108,201, 33,132, 64, 44, 22, - 99,247,238,221,180,119,239,222,217,207,159, 63,167,246,246,246,176,183,183,199,174, 93,187, 76,221,187,119,207,190,119,239,222, -219,176,242, 8, 44,179,217, 12,137, 68,242, 78, 92, 10, 11, 47, 75,197, 80, 90, 90,218,188,151, 47, 95,246,237,214,173, 91,114, - 68, 68, 4, 85, 42,149, 80, 42,149,152, 59,119,110, 94,195,134, 13, 83,194,194,194,222,134, 85, 68, 96,217,219,219, 35, 42, 42, -138, 14, 30, 60, 56,101,231,206,157, 90, 0,112,112,112, 64,100,100, 36, 29, 56,112, 96,114,120,120,120,223,148,148,148,249,101, - 89,176, 94,189,122,245,214, 98,165,213,106,145,150,150,134,216,216,216,183, 93,132, 26,153, 85,167,129,253,186,215,214,104, 52, -121,161,225, 47, 94,215,172, 81,221, 81,163,209,228,197,188,126, 29, 78,233,156, 98, 85,152, 90,173,158,174,211,233, 26,111,220, -184, 49,100,252,248,241,121,175, 95,191, 46, 86,176,127,148, 2,139,195, 56,131,208,102,215, 95,228,218,180,239,222, 95, 72,146, -238, 2,134, 92, 64,100, 11,136,108,193,147,217,163,115,243, 58,220, 29,183,115,156, 65,153, 38, 16,136,220,203,228,228, 83, 39, -128,105,126, 62, 92,107,219,172,207, 56, 97, 70, 70, 6,184, 92,238, 91, 49, 36,149,201,208,182,215, 80,206, 47,119,117,206, 0, -109, 10,194,117,183, 52,186, 66,161,112,202,247,223,127, 47,200,204,204, 4,135,195,249, 31,167, 84,138, 49, 99,198,136,172,172, -172,102, 89,156,246,195,213, 5,224,139, 26, 1,244,219,176, 36,173,235,241, 16,141,255,164,165,219, 36,129,117, 26, 96,116, 43, - 71,201,210, 83, 41,129,143, 98, 53,149, 1,243, 4,152,244,245,202, 43,178, 8, 33,205, 21, 10,197,169,251,247,239, 75,187,116, -233,130, 21, 43, 86,200, 36, 18,201, 25, 66, 72,185, 27,124,117,174,249,235,249,107,119, 37, 63,254,177, 35, 96, 80,191, 17, 86, -133,182,148, 92, 6,179,183, 93,202, 54, 26,233, 64, 75, 57, 53, 26,205,176,207, 63,255, 60,253,183,223,126,251,147,184, 18,139, -197,136,138,138,194,162, 69,139, 50, 50, 50, 50,134,255,157,226,234,235,175,191, 94, 20, 23, 23,231,127,254,252,121, 94,106,106, -170,227,202,159,127,206, 62,156,157,157,177,228,201,147,176, 25, 53,106,248, 78,171, 85,107,120, 73, 46, 28, 74, 18, 87, 95,125, -245,213,190,184,184,184,186, 23, 46, 92,224,167,166,166,186,127,245,213, 87, 88,190,124, 57,102,205,154,181, 25,192,232,130,209, -209,150, 66,175,215,135,101,102,102,118,235,216,177, 99, 86,102,102, 38,106,213,170,133,238,221,187,195,217,217, 25,174,174,174, -232,217,179, 39,252,252,252,144,158,158,142,129, 3, 7,102,164,166,166,118,164,148,150, 58, 11, 61, 61, 61, 61, 98,239,222,189, -225,227,198,141,171, 27, 23, 23, 87, 13,128,189, 74,165,146,169, 84, 42,145, 94,175,151,216,218,218,218,214,169, 83,199, 97,212, -168, 81,242,135, 15, 31, 86,139,139,139,203, 5, 16,195,202,170,183,186,160, 68, 45, 2, 32, 53, 95,232,232,139,236, 83,203, 56, -102,233,181,197,254,182,224,188,178, 45, 88, 37,193, 0,204,222,121,104,135, 86,232, 89, 21,214,254,181, 33, 21,139, 33, 17, 10, - 33,177,181,135,142, 97,240,115, 84, 82,158,154,210, 89, 21,200,200,119, 44, 13, 58,157, 14, 83,166, 76,209, 14, 29, 58, 52, 43, - 58, 58,122, 76, 78, 78, 78,109, 74,233, 99, 75,196, 64, 78, 78, 14,150, 47, 95,174,153, 59,119,238,171,220,220,220,186, 66,161, -208,168,211,233,176,116,233, 82,237,183,223,126, 27,157,157,157, 93, 95, 40, 20, 26,196, 98,113,185,122, 97, 36, 18, 9,120, 60, -158, 81,165, 82,213, 93,188,120,113,196,134, 13, 27, 52, 10,133, 2, 2,129,192,168, 82,169,106, 46, 92,184, 48,108,201,146, 37, -154, 2,203,155,165,188, 12,195, 20,219, 69,200, 48,204,159, 44, 91,101,193,104, 52, 94, 74, 77, 77,173, 61,109,218,180,135, 91, -182,108,201,179,183,183,135, 88, 44,214,167,166,166,214,154, 52,105,210,163,245,235,215,231,217,219,219,151, 75, 96, 25, 12, 6, -152,205,102,252,242,203, 47,121,211,166, 77,123,148,150,150, 86,139, 16,162,103, 24, 6, 91,183,110,205,155, 60,121,242,195,148, -148,148,218, 70,163,241, 82, 89, 92,102,179,217,156,147,147, 3, 30,143,135, 39, 79,158,232, 4, 2, 1, 56, 28, 14, 94,190,124, -249, 86, 96,217,217,217, 85,175, 93,179, 70,192,174,125,135,174, 74, 4, 34, 81,227, 6,245,170,189,138,142,137,163,148, 68,151, - 81,135, 30,231,229,229,213, 78, 76, 76, 28, 51,121,242,228,172,249,243,231,107,117, 58,221, 59, 34, 75, 40,252, 8, 61, 1,112, - 32, 5,129,228, 69,138, 78, 33,230,152, 8,194,143,190, 17, 87, 98, 27, 64,108, 11,136,109,225,230,230,142,187, 81,121, 10,112, - 32,132,217,232,104,193, 3, 41, 3,129,244, 73, 50, 20,124,161,132, 36, 37, 37,189, 21, 66, 5,155,119,213,106,120, 16,147, 43, - 7,161, 34,112, 81, 30, 87, 34,221,236,237,237,121, 5, 67, 0, 10,111,213,171, 87,231, 26,141,198,142, 22, 51, 37,152, 93, 0, -230,171,240, 36,173,203,145, 71,106,255, 9, 75,126,145, 72,204, 89,192,253,181, 8,172,226,138, 9,125,234, 8,103, 30, 79, 13, -188, 23,157, 87, 5, 92, 58, 26, 76,174,178, 28,207,124, 51,133, 66,113,230,222,189,123, 82,133, 66,129, 87,175, 94,161, 65,131, - 6,216,178,101,139, 84, 42,149,158, 38,132,180, 42, 79, 49,221, 78,162, 49,185, 42,115,227, 41,135, 94, 39, 61, 78, 52,189, 35, -174, 82,213, 20,159,255,112, 60, 43, 51, 71,251,233,173,215,101, 63, 71,133,234,252,195,172,172,172, 14,179,102,205, 74, 79, 77, - 77,125, 71, 92,197,196,196, 20, 8,129, 86,148,210,167,127, 87,245,180,182,182, 30,188,100,201, 18,220,187,119, 15, 93,186,116, -193,181,107,215,144,145,145,129,253,103,206,188,216,251,226,197,140,130, 49, 89,197,185,112, 40, 9, 86, 86, 86,147,150, 44, 89, -130,251,247,239,191,229, 76, 79, 79,199,146, 37, 75,226, 0,140, 45,175,184, 42, 64,114,114,242,221,176,176,176,142,181,106,213, -122,182,110,221,186, 56, 23, 23, 23,102,212,168, 81,248,252,243,207,161, 84, 42,205,171, 87,175,126,221,188,121,243, 39, 17, 17, - 17,237,212,106,117,136, 5,229, 67,211,210,210,110,110,217,178,229,118,155, 54,109,164,195,134, 13, 83, 30, 59,118,204, 62, 47, - 47,207, 85, 36, 18, 57,234,245,122,225,179,103,207,184,135, 15, 31,118, 14, 13, 13,141,210,104, 52,119, 43, 26,247,255, 32,238, -229, 91,163, 46, 20,217,223, 43,227,152,165,215,150,244,187,172,243, 74, 23, 58,101,109,131,171, 96,238,152, 26,138,188,155, 67, - 26,209,164, 81,205,104,114,255,106,244, 70, 75, 59, 58,210,135,168,135, 85,208, 77,131,201,100,162,175, 94,189,162, 81, 81, 81, -116,246,236,217, 38,137, 68,162,145, 74,165,171, 81, 78, 55, 13,114,185, 60,215,207,207, 79,101,109,109,253,214, 77,131, 66,161, -200,245,247,247, 87,217,216,216,188,117,211, 32,147,201,114, 41,165, 84, 46,151, 91, 52,139, 80,161, 80,100,167,167,167, 83,137, - 68, 82,224,166, 65, 96,109,109,189,213,215,215, 87, 37,151,203, 11,220, 52,240,109,109,109, 55,249,249,249,169, 20, 10,133, 69, -110, 26, 28, 29, 29, 99,159, 61,123, 70,195,194,194,168,187,187,123, 66,161,217,118,177,143, 30, 61,162,143, 30, 61,162,110,110, -110, 21,114,211,160, 84, 42,151,215,175, 95, 63, 67,169, 84,166, 23, 10, 91, 81,191,126,253,204,130, 48, 11,103,254,165,231, 95, -243,214, 77,131, 82,169, 76,207,231, 46,151,155, 6,137, 68, 50, 90, 44, 22, 39,136,197,226, 4,145, 72,180,168, 82,165, 74, 41, - 7, 15, 30,164,171, 87,175,166, 10,133,226,141,155,134,234, 61, 26, 87,109, 50,124,134,178,122,207, 73,239,227,166, 65, 42,149, -174,150, 72, 36,154,249,243,231,155,178,178,178,168, 94,175,167,249,141,215,199, 53,139,112,139, 95, 85,250, 83,192,241,136,249, -222,161,223,180,144,106, 67, 22,214,166,244,215, 79, 40, 61,253, 57,165,151,166,208,187,155, 71,209, 38,222, 34,243, 31,147, 61, -194,233, 38,255, 35, 22,185, 86,216, 82,179, 42,253, 41,224,244,139,121,222,161,195,154,187,106,127,222,184,154,222,185,115,135, - 62,121,242,132,190,122,245,138,158, 62,122,144, 54,169, 34,125,195,249, 83,192,241,242,184,107, 0,208, 84, 36, 18,229,174, 90, -181,138,222,190,125,251, 45,231,241,227,199,169, 84, 42,205, 3, 44,156,133, 12, 16,250, 83,245, 94,166,141,254,215,103,182,151, -171,210, 79, 78,161, 52,100, 7,165, 91, 2, 41,221,222,144,210,131, 93, 41, 61, 49,156,222, 94,221,135, 54,245, 22, 24,233, 38, -255,107,116,115,245,246,150,198,147,207,231,231,252,246,219,111, 52, 33, 33,129, 94,187,118,141,222,191,127,159, 62,127,254,156, -190,126,253,154,158, 58,117,138,242,249,124, 45,128,114,207, 82,108,232, 4,175,118,190,130,196, 71, 75,155, 82,122,108, 32, 77, -221, 59,152,118,171,161,200,104,228,193,107,243, 30,179,173,234,216,219,219,167,157, 58,117,138, 70, 69, 69,209,171, 87,175, 82, - 71, 71,199, 52, 0,129,127,119,253,108,215,174,221, 29, 74,105,112,151, 46, 93,130, 1,156,109,215,174, 93,112,100,100,100,112, -131, 6, 13,110,163, 20, 23, 14,165,113,182,109,219,214, 64, 41,165, 93,186,116,161, 0, 18,218,181,107, 71, 35, 35, 35,105,131, - 6, 13,244, 31,104,246, 26, 23,192,112, 62,159,255,179,157,157,221,101, 91, 91,219, 75, 92, 46,119, 11,128, 33,229,105,239,138, -225,116, 5, 80, 29, 64,189,252,173, 90,126, 24, 59,131,240,191, 48, 43,210,210, 19,251,120,163,233,136, 42,228,234,160,202, 80, - 13,172,140,220,207,124,200,141, 79,189,209,166, 34,171,109, 23, 8,172, 95,127,253,149,122,120,120,168, 21, 10,197, 13, 0,190, - 21, 89,193,219,214,214,246, 44,151,203,237, 91, 76, 88,255, 34,238, 17,158,218,216,216,100, 91, 89, 89,189,178, 36,158, 86, 86, - 86,207,165, 82,169,218,202,202,234,121, 17,151, 0, 61,237,237,237, 79, 21, 9,235, 81, 52,172,164,180, 59, 57, 57,197,134,135, -135,211,215,175, 95, 83, 15, 15,143,132,194,194, 43, 36, 36,132,190,120,241,226, 29,225, 85,222,213,203,121, 60, 94, 27,165, 82, -121,184,172,176,210, 56,157,156,156,126,229,241,222,109,252,139, 11,171,200, 42,235, 0,252,220,220,220, 82, 86,174, 92, 73,229, -114,121, 74,225, 99,254, 45, 62,251,254,206,139,220,156,207,167,254,116, 80, 89,173, 87,205,138,172,220, 14,192, 87,161, 80,220, -240,242,242, 82, 95,188,120,177, 84,129,133,127,235,170,245,135,170, 9,232,230,106, 77,233,166,106,167,158,207,241,122, 54,188, -161, 76, 23,188,178, 11,165,151,166,208,219, 63,125, 78, 27,123, 11,223, 8,161,205, 1,103,232, 47,126, 45,232,218, 42, 66,139, - 56,127,246,105, 78, 55, 7,156, 9,157,237,245,236,147, 32,165,126,223,142,205,244,229,203,151,244,248,225,189,180, 81,229,124, -113,181,169,218,239,244,167,106,173, 45,226, 44, 70,100,109,219,182,141,190,124,249,146, 30, 57,114,196, 34,113,245, 14,103, 33, -129, 53,189,157, 60,235,243,134, 98,221,192, 58, 66,125,207, 64,129,161, 67, 85,129,169,137, 23,207, 92,219,133,195, 84, 83,130, -118,240,151,232,232, 38,255,107,116, 83,181,142,150,198, 83, 40, 20,190, 70, 33,159, 56, 69, 55,145, 72,148, 90,146,192, 42,171, -220, 27, 58,193,171,157,159, 40,241,226,252, 54,180,123, 45, 69,186, 37,226,170, 44, 78, 0,117, 28, 28, 28,210,182,111,223, 78, -157,156,156, 82, 45, 17, 87,255, 31,245,211,218,218,122,119,110,110,110,240,185,115,231,130,219,181,107, 23,188,123,247,238,224, - 27, 55,110, 4, 75,165,210,221, 37,185,112,168, 6,116, 44,141,211,202,202, 42, 88,165, 82,209,115,231,206,209,118,237,218,209, -221,187,119,211, 27, 55,110, 80,169, 84, 26,252,143,122, 54, 89, 78,118,171,136,192,250,144, 5, 0,128, 14, 26, 52, 40, 79, 42, -149, 38, 3,232,241, 95,170,124,118,118,118, 55, 29, 29, 29,147,157,156,156,146, 29, 28, 28, 30, 20, 18,133, 55,149, 74,101,178, -163,163,227, 59,225, 31,227,131, 7,192, 79, 32, 16,196,240,249,252,240,194,225,202,234, 61, 26,251, 52, 29, 54,203, 41,176, 71, -231,247,141, 39,128, 30, 82,169, 52,185,119,239,222,234,143, 78, 96, 81, 10,186,182,138,176, 64,100,133,204,242,122,222,189,134, -212,176,101, 98, 7,218,184, 82, 17,113,181,221, 75, 84, 46,206,124,145,245,112,166,231,243,214,126,114,211,146, 89, 19,104,163, -202,146,119,197, 85,121, 56,139,136, 44,169, 84,170,154, 51,103,142,197,150,171, 63,113,254,236,239, 73, 55, 7,236,126, 35,158, -202,216,126,242,223, 74,215,251,123,254, 83,202,189,161, 19,188,218,250,137,158, 90,106,185,178,132, 19, 64, 29, 91, 91,219,103, -150, 90,174,254, 63,210, 14,160,195,152, 49, 99,130, 35, 35, 35,131, 95,189,122, 21,124,227,198,141,224, 94,189,122, 5, 3,232, - 80,156,159, 44, 67,239,222,186, 58, 28,206,132, 50, 56, 7,140, 25, 51,134, 70, 70, 70,210, 87,175, 94,209, 27, 55,110,208, 94, -189,122, 81, 0, 3, 88,225,194, 10,172,127,234,246,183,204, 97, 87, 40, 20, 15,142, 30, 61,122, 86,163,209, 44,162,148,234,254, - 75,157,200,233,233,233, 77,138, 11,207,200,200,104,242, 31, 26,200, 24, 14,192,171,104,120,202,211, 99,183, 0,220,250, 64,247, - 56, 78, 8,249,253,236,217,179, 51, 21, 10, 69,167,143, 46, 19,199, 69,232,177,206,231, 62,132,194,165, 53,220,164,211,190,239, - 66,201,146,115, 55,189,150,245,118,124,221,196, 71, 22, 5, 62,243, 3,136,238, 46,134, 71,235,202,201,121, 23, 18,227,210,218, - 30,210,105,139,123,130,252,112,102,135,215,242, 94,246,175,155, 84,145,191, 6,197, 15, 16,229,221, 42, 23,231,187,101,242, 7, - 33,164,243,202,149, 43,119,230,229,229,125, 65, 41,189, 92,254,198,131,147, 4,181,113, 14,140,220, 26,160, 16,150,114,179, 60, -112,184, 79,144,130,228,127, 74,145,221, 78,162, 49, 0, 2, 63,240,179,244, 48,191,219,233,159,244,124,255, 78, 8,193,222,189, -123, 7, 7, 4, 4, 84, 9, 13, 13,125,149,151,151,183,135, 82,250,123,225,177, 74,132,144, 19, 63, 60,126,172, 94, 31, 26,250, -135,158, 97,254, 40,131,115,127, 62,231,164,128,128,128,192,208,208,208,167,121,121,121, 43, 41,165,251,217,161, 73, 44,254,169, -248, 91, 4, 86, 78, 78, 78, 16,155,245, 44,254, 31, 26,122, 29,128,239,243,183,143, 15,133, 68, 86,144,167,100,220,111, 99, 36, -121,160, 36, 14,124,102,117,185,197, 85, 49, 34,171,129,151,228,219, 35,163, 37,121,160, 72, 2,197,143,239, 35,174, 10,139, 44, - 0,149, 43, 76,208, 39,212, 0, 32, 10,132, 68, 99, 46, 74, 30, 28, 61, 23,111, 63,179, 89,252, 61, 34, 11,192,239,101,156, 67, - 1, 92,202,223, 44,225,220, 15,128, 21, 84, 44, 88,129,197,130, 5,139,255, 39,145,117,184,250, 61,164,113, 39,131,131,202,128, - 41, 6,106, 83, 18,198, 69,235,223,147,243, 14,210,200, 55,224,194, 15, 66, 83, 4,114,245, 73, 24,243, 30,156,127,193, 27, 28, -111,198, 70, 21,143, 57,108,213, 96,193,130, 5, 43,176, 88,176, 96,241, 62,120, 99,213,137,203,223,254,185,156, 44, 88,176, 96, -241, 31, 2, 1,208,174,132, 15,196, 11, 22,147, 16,210,174, 2, 31,160, 23, 88, 78,150,147,229,100, 57, 89, 78,150,147,229,252, -111,113,150,197, 93, 30,253,241,143,198,223, 49,139,144,229,100, 57, 89, 78,150,147,229,100, 57, 89, 78,150,243, 99,222, 56, 96, -193,130, 5, 11, 22, 44, 88,176, 96,241, 65,241,183,142,193,146, 58,248,185,128,199,169, 69, 24, 26, 0, 0,148, 67,158,195,196, - 60,206, 75, 11, 79,124, 95,110,133,155,191, 29,133,240, 16,129,190,175, 42, 62, 44,227,125,249,106,250, 91,247,118,114, 80, 12, - 78, 74,207,222,249,228,185,234, 88,121,174,181,177,169,100, 45,182,179,237,163, 51, 24,107, 8, 5,130,215,134,172,156, 45, 25, - 25, 17, 42,182,250,177, 96,193,130, 5, 11, 22,255, 49,129, 85, 41,176,249, 61,177, 88,226, 13, 0, 12,165, 96, 40,160,206,201, - 10, 78,140,184,215, 17, 0,148,222, 65,231,248, 98,171, 32,134,190, 57,110,102, 0,147, 65, 27,149, 29,125,187,190, 37, 55,150, - 59,250,127,210,174, 67,187,222,221,186,117,245,175, 89,163,166, 15, 0,132, 60, 9,137, 56,121,242, 84,152,220,209,255,183,220, -148,176, 35,239,147, 48, 10,241,130,122,245,234, 52,187,127,255,193,124, 0, 95,189,111, 70,217,219,203,199,253,254,235,228, 22, -109,123,175,144, 1, 40,151,192, 18,219,217,246,233,217,189, 83,157,239,198,143,225,124, 62,121,177,247,189, 63,174, 44, 83,184, -214,200,162,140,241,119,117,114,255,235, 37, 45,104,204,130, 5, 11, 22, 44, 88,176,248,200, 4,150, 88, 44,241,190,125,229,164, -221,145, 27,177, 0,128,118,117,157, 49, 99,225,186, 14,132,144, 48, 0,232,241,249, 92,191,249,211,199,227,230,211, 20, 80, 74, - 81,167,170, 61, 58,247,236,107,209, 77, 37,206,213,235,247,239,215,111,208,228,201,147,122,188,124,249, 50,122,223,190,125,215, - 1,160,121,139, 22, 85, 23, 47, 94,220,111,133,173,157, 72,226, 92, 61, 94,147, 20,122,175, 34,137,146,184,249,184, 85,247,173, - 53,248,192, 47,235, 56,173, 58,126, 58, 80,226,230,179, 68, 19, 31, 17,111,201,181, 74,165,242, 27, 62,159,111, 13, 0, 12,243, - 63,221, 83,197,131,235, 12, 0, 38, 51,163,176,115, 11, 80,113, 5, 98,179, 72, 36, 8, 85,229,230,238,204,142, 11,253,185, 52, - 78,157,209, 24,248,237,216, 17,156,135,175,210,225, 29,216,156,187,122,201, 76, 48,102,163,237,132,233, 11,251,220,191,115, 0, -192,156,171,108, 85,100,193,130, 5, 11, 22, 44,254, 3, 2, 11, 0,228, 18, 30,194, 34,147, 0, 0, 54, 18, 96,220,232, 97, 72, - 79, 75,245,211,155, 24,124, 54,108, 8, 30, 60, 79, 68, 88, 84, 42, 40,165,240,115,151, 90,124, 83, 46,152,122,159,141,252,172, -229,185,223,127,191,251,253,172,239,119, 17,242,198,123,247,230, 45, 91, 27,207,158, 51,251,139, 33,195,134,180, 63,124,248,240, - 83,148,181, 82,117, 73,137, 34,138,117,203,151, 46, 18,198,165,105,181,223, 76,158,198, 76,154,248,205,106, 0,159, 90,114, 45, -159,207,183,142,139,139,147,115, 56,239, 14, 79,251, 97,209,180,107,237,123,175,120, 17,253, 58,235,225,185,227,199,235, 87,175, - 94, 29,113,241, 73, 77,151,173,217, 84,219,197,167,254, 8, 85,142,166,183, 58, 53,180, 88,175,209, 34, 62,255,233,188,101, 63, -213, 97,108,170,114,102,124,209, 5,129, 62,174,136, 79,201, 66,139,142, 61,120,193,247,238,117, 0,192, 10, 44, 22, 44, 88,176, - 96,193,226, 35, 2, 7, 0, 8, 33,197, 58,236, 51,155, 41,194,162, 18, 17, 22,149,136,187,207, 83, 97,160,124,172, 94, 54, 15, - 43,151,204, 65,134,134,131, 35, 55, 99, 17, 30,149,132,240,168, 36,164,101,230,254,233,250,162, 83, 45, 87, 46,149,214, 93,189, -218,122,121,135, 22,178, 86,118,182,182,182, 47,158,238, 82,207,158,152, 92,109,222,183,177, 2,190, 94, 20, 39,147,203,154, 28, - 58,116,176,186,147,210, 81, 38,151, 43,166,200,220,235,108,179,177,169,109, 93, 26,103, 81, 72,157,170,245,232,209,181, 83, 27, -103,103, 39,102,204,234,224,231, 53,170, 5, 24,125,171,250, 54,149, 58,249,245, 40,233,154,194,156, 12,195,128,195,225, 32, 57, - 57, 25, 9, 9, 9,136,140,140, 68,120,120, 56, 98, 99,163,147, 25, 74,249,102, 48, 28, 23, 23,119,240,120, 66,120, 87,242,194, - 79,171,151, 72, 23,206,157,209, 64, 44, 19, 30, 35,132,144,226, 56,181, 25,153,135, 79,159,253, 61,254,204,190,159,204, 0,144, -146,153,139, 75,247, 94,226, 65,104,108,185, 10,235,175,152,186,202,114,178,156, 44, 39,203,201,114,178,156,255, 4,206,146,180, -200,191, 90, 96,149,132,136,216, 12,132, 69, 38, 33, 40,192, 13, 62,149, 92,112, 55, 60, 19,123, 46,197, 98,219,185, 24, 92,122, -148, 10,134,167, 64, 82, 14,240, 34, 58, 25, 47, 98,210, 74,243,171, 12, 0,224,138,248,253,191,253, 54,123,114,205,234, 57,141, -174,156, 25, 7, 55,229,139,234, 83,167,102,141,227,138,248,253,109, 61, 20,251,166, 77,158, 48, 88, 33,149, 10,245, 58, 61,170, - 84,246, 18,143,255,122,220, 8, 98, 43,218,103,105, 98,172,220,171,219,138, 36,146,159, 23,206,157, 34,250,241,200,139,215,106, - 61,212,191,221, 74,126, 53,105,218,236, 12, 30, 95,252,147,149,123,117, 91, 75,185,140, 70, 35,116, 58, 29,244,122, 61, 12, 6, - 3,226, 99,159,245,184,120,228,187,142,149, 61,236, 58,138,196, 98, 80, 0, 57, 26, 19, 34, 19,243,208,186,109,123,110, 80,221, -186,129,114,151,106, 35,139,227,202,202,138,206,102, 40, 87,113,242,232, 94,238,193,243, 15,177,235,228, 61, 28,187,252, 16,119, -175,158, 49, 81,198,248,118, 57, 9,133,171,175,159,194,181, 86,140,194,173,118,242,219,205,189,230,125,246, 59,128, 5, 11, 22, - 44, 88,176,248,119,161,196, 46, 66,173, 86, 19,245,105,255, 33,112,113,116,150,247,108, 53, 92, 16, 28,145,133,212,196, 24,188, - 12,127,130, 60,173, 17, 2,219,202,128,216, 25,149,188,189,240, 56,236,152, 97,237,242, 83,185,140, 73, 23, 85, 18, 95,207,158, -174,238, 46, 74, 25,103,249, 50,207,219,225, 97,153, 65,123,103,109,199,160, 65,114,135,229,203, 60,111, 71,191,146,113,164, 98, -218,100,196,176,129,132, 67, 40,166, 78,157,140,158,221, 58,225,179, 17, 67,201,206,157, 59, 26, 89,154, 24, 6,252,245,211,103, -206, 19, 38,103,153,244,119,195,115,117, 82,153, 68,242,199,139, 92,117,160,183,167,164, 75,239,225, 9,167, 14,253,252, 35,128, - 97,150,112, 21, 8, 43,163,209, 8,131,193, 0, 0,102, 0,224,112,222,236,211, 85,122,164,100,233,144,156,165,131,201,204,160, -119,255, 97,146,123,247, 31, 13, 3, 80,194,120, 44,134, 49,154,140,248,237,252, 3,196,223, 59,204, 16, 14, 55,187, 96,144,123, -129,184,114,118,246,188,214,173,247, 80,165, 80,252,166,187, 85,165,214, 97,231,166,101,108, 45,101,193,130, 5, 11, 22, 44, 62, - 22,129, 21,253,244,122,125, 0,240,175,223, 49, 93, 46,230,217,241, 56, 4,201,113, 17,216,185,226, 27, 48, 12, 69,151, 47,150, - 67,225,237, 12,137,128, 11, 93,110,122,110,250,203, 43,246,165,221,136, 16, 99,251, 13,155,227,189,191, 28, 91,197,106,239,222, - 92, 62, 0,236,221,155,203, 31, 59,198,195,106,227,230, 40,239,134,205,130, 64,205,102,116,235,249, 41,250, 15,232,143,232,164, - 60,252,122,237, 53,212, 26,189, 69,235,159, 73,149,213,106, 59,186,186,117,250,118,120, 39, 25,143, 75,136,175,151, 53, 55, 54, -213,104,226,114,249,230, 19,247,178, 19,122,247, 30,224,112,233,244,193, 54, 82,101,181,218,121,169,207, 30,149,197,167,211,233, - 96, 54,155,161,211,233, 96, 52, 26, 97,231, 80,249,116,251, 79, 87,196, 37, 38,169, 78, 37,101,106, 27,170,141, 38, 36,103,233, -144,146,165, 67,150,218, 0,103,133, 45, 76, 70,125,205,146,248, 40,165,187,122,125, 58,100, 40, 0, 14,225,152,182,171, 18,158, -133, 23, 28, 43, 16, 87,157,122, 14, 82, 94, 11,142,192,203,251,103, 50, 41, 99, 50,190,201, 56,134, 93,170,132, 5, 11, 22, 44, - 88,176,248,151,129,243, 63, 1, 68,104, 73,253,159,241,201, 25,176,151,243,160,116,245,198,224,111, 86, 2, 0,204,102, 35, 40, - 5, 76,102,203, 60, 12, 80,202, 63,255,213, 88,239,168, 74,222, 36,123,240, 32,169, 6, 0, 6, 15,146,106, 42,121,147,236,175, -198,122, 71,169,180,114,131,201,108,198, 31, 79, 83,176,252,192, 51,204,222, 17,130,179,247, 45,119,135,197, 21, 10,198, 46, 91, -186, 68,192,227, 18,242, 52, 38, 55, 55, 46,221,148,203,229,243, 13, 82,169,144,234, 41, 79, 23,157, 70,211,219,246, 26,241,146, -195, 37, 35, 75,227, 41,152, 57, 88,208, 69, 88, 96,193,162,148, 82, 2, 48, 12, 49,155,227,210,180,136, 77,213, 32, 54,229,127, - 91,114,166,174,196, 30, 82,133,171,175,159,181,149,252,172,173,141,213, 8, 27,107,171, 97, 50,137,237, 57,133,171,175, 95, 81, -113,117,251,105, 2, 34, 30, 94, 72, 54, 27,242,250,169,226, 31, 57,169,226, 31, 57,169,226, 66,234,177,213,148, 5, 11, 22, 44, - 88,252, 23, 80,154, 22,249, 87, 10, 44, 74, 41, 41,216,254, 44,140,128, 23, 49,105, 16,242, 24,184, 87,242, 1, 45, 36, 35, 40, - 0,147,217,178,124, 56,118, 44, 33,174, 74, 85, 53, 51,101,202,235,198, 53,106,218, 63, 30, 59,198,227,121,141,154,246,143,167, - 76,121,221,184, 74, 85, 53, 99, 52,241,205, 52,223,223, 86,129,111,173,124,119,252,150, 38,165, 65,237,234,149,185,243,246,190, -120,253,229,198,240, 48,129, 64, 96,116,119,144, 18, 47, 39, 41,215, 83, 41, 17,234,140, 28,157, 95, 96, 93, 61, 56,164,174, 37, - 2, 75,175,215,191,179,165,167, 70,244,248,253,215,201, 61,221,156,108,135,199,167,106,240, 58, 37, 15,177,169,121,120,157,154, -135, 60,157, 9, 33,207, 94, 1, 92,193,147,226, 56,173, 20,118,231,246,237,217,229, 89,187, 90, 21,199,234,126,149, 28,127,222, -177,203, 83, 44,182, 57,167,112,245,245,243,244,246, 15,190,115,225,160,242,246,211, 4,196,132,221, 79, 50,233,114,246,169,147, -159, 95,100, 31, 51, 22, 44, 88,176, 96,241, 95, 66,105, 90,228,223, 8,139, 60,185,123,185, 59,225,206,147, 40,212, 12,168, 12, -107, 43, 5,158, 71,196,129,203,225,131, 67, 0,163,201,114, 17, 68, 13,198, 3,171, 86, 89, 35, 38, 74,198,217,248, 83,148,247, - 87, 99,189,163, 86,173,178,190, 69, 13,198, 3, 0,134, 80,250,102,109,196, 2,199,166,230,114,184,223,164,140,209,195,201, 78, -202,189,255, 74,157,206,225,112,117,246,214, 98,198,222, 90,196,177, 87, 8,249, 2, 62,151, 49, 81,142,193,221,209, 91, 75, 25, -166,182, 37,124,133,187, 8,205,102, 51, 8,225,152,243, 5,152, 44, 54, 93,131,108, 45, 23,201, 89, 58,100,170, 12,240,117,147, -225,194,165,195,121,102,163,102,111,113, 92, 92,190,192,218,199,219, 29, 51, 22,172,130, 70,103,198,139,248, 92, 8, 68, 34,103, - 39,231,192, 71, 67,190,156, 38, 26,191, 37, 2, 35,219,216, 99,226,245,136,248,188,100,241, 52,246, 49, 99,193,130, 5, 11, 22, - 44,254, 3, 2, 75, 46, 21,131,114,197,184, 30, 28, 1,255,234,181,176,227,248, 93, 84,173,217, 8,137, 42, 19, 40, 56,101,206, - 30, 44,192,164,105,121, 15, 0, 60,232,217,211,213,253,147, 79,220,218, 83,202, 63,191,113, 83,118, 28, 0,252,180,191, 37, 40, - 0,134,161,160, 20,160,204, 27,161,101, 49, 8, 47, 38, 42, 49,167,146,183,179, 12,161,113, 6,157, 76, 36,224,216,202,132, 92, -165,181, 80, 32,224,241, 96,166, 68,151,152, 24,161, 35, 64,180, 37,116, 5, 93,131, 5,123,169,220,229,116,219, 94,203, 83,163, - 95,103,223,247,205,200,171,157,109, 16,130, 82,192,215, 77,134, 39,183, 79,153,147,227, 95,190,208, 36,135,109, 42,142,139, 97, -192, 53,152, 24, 60,122,149,141, 44,181, 17, 89,185, 6, 52,109,221, 93,208,180, 93, 15, 92,127,146, 6,198,100,196,178,173,167, - 84,102,106,236, 79,105,168,145,173,150, 44, 88,176, 96,193,130,197,191, 27, 22, 45,246,108,102, 40, 28,236,237, 32,150, 89, 33, - 42,217, 0, 21,113, 68,102, 30,133,217,252,198,130, 85,146,161,137, 16,210,174,184,240, 99,199, 18,226,142, 30, 77,221,118,236, - 88, 66,161, 1,220,255,179, 92,189,221, 51,212, 98, 78, 66,205, 23,142,159,185,146,221,163,161,210,150,195,229,106, 4,124,142, -142, 39,224, 26, 4, 60,142, 81,192,227,232,157,172,248,220, 43, 39,246, 11, 41,193,149,178, 56,181, 90, 45,218,181,107,135, 46, - 93,186,160,103,207,158,232,219,183, 47,252,252,170, 57,114,184, 68, 79, 9,195, 40,133, 42,248, 40, 9,120,218, 88, 92,220,255, - 67,222,147, 63,142, 62, 50,235,180,221,105,161, 62,205,119, 56, 41,101, 50,178,117,208, 26,204,200,204, 53, 32, 83,109,128, 73, -217, 24, 71,111, 38, 64,163, 55, 35, 38,248,176, 38, 53, 41,238, 27,109,242,139,168, 82, 53,100, 9,105,127, 31,176,156, 44, 39, -203,201,114,178,156, 44,231, 63,129,243, 99,131, 5, 22, 44,138, 42, 46, 50, 84,117,147, 65,107,112,132, 86,111,134, 90,107, 70, - 78,158, 1, 57,121, 70, 68, 37,229,225,201,241,247,143,200, 27,171, 21, 64,242,127,131,188, 17,118,150,218,176,132, 6,253,130, -149,203, 22,247,219, 95,183,142,126,124, 87, 23,143,199, 81,250, 4, 66, 56, 26, 14,151,103,180, 83,240,248,207,159, 63, 78,189, -117,237,116, 11,177,201, 60,180, 52, 30,147,201,148,237,230,230, 6,224,221,165,114,170,249, 72,122,254,113,106,106,229,150, 61, -150, 41,127, 92, 52, 57,143,195, 21, 48,132, 39,120, 98, 54,106,246,105,146,195,126,162,165, 12, 24,227, 8,196,207,238, 60, 12, -109,100, 99,231,129,151,241,106,168,181, 38, 24, 76, 12,108,229, 2,196,133,156, 51, 68, 61,191,127, 80, 21,255,104, 7, 91, 29, - 89,176, 96,193,130, 5,139,255,136,192,210,106,181, 81,205,218,117, 7,195, 80,152, 41,192,152,243, 45, 77,204,255,172, 77,102, -163, 54,234,125, 35,194, 48,230,187,235,183,108,235, 82,183, 65, 75,110,117, 79, 57,114,210,147,112,251,143,203, 38, 48,244,150, - 37,215,167,165,133,231, 74,157,125, 63,237,215,231,147, 67,195, 62, 27,147,213,162,117,107,153,163,163,179, 46, 46, 62, 46,239, -151,221,123,140,231, 78, 31,107,193,192, 52, 32, 45,237, 69,110,105, 60, 89, 89, 89,107,138, 11,111,219,204,163, 41,128,202, 92, - 30,209,231,165,132,203,202,147,182,180,248,216,222,139, 23,204,141, 30,244,197, 4, 97, 21, 55, 31,164,100,115, 17, 21,151,132, -231,215,142,233,226,195,239, 29,201,137,123, 48,146,173,138, 44, 88,176, 96,193,130,197,127, 72, 96,189, 14,125,227, 15,235,175, -134, 42, 41,101,200,142, 29,187, 22,238,218,189,191,169, 86,175,119,163, 16,196,154, 77,250,171,185,102,204,182,148, 35, 47,233, -197,125, 7, 7,191, 26,191,108, 93, 63,243,151,109, 27, 91,130, 49, 7, 16, 32,154, 18, 92, 17, 27,205,195,202, 18, 87,165, 11, - 56,213,230,246,159,174,208,164,167,231,238, 42,239,181,121,105,207,147,228, 78, 85, 60, 54,175, 94,176,156,195,225,118, 48,155, - 25, 62, 99, 54,190, 52, 27,180, 63,104, 82,195,142,211,242, 77,151,100,193,130, 5, 11, 22, 44, 88,252,219, 5,214,255, 23, 50, - 50, 34, 84, 0,198,191, 47, 79, 90, 90,120, 46,128, 15, 62, 19, 47, 36, 60,251, 87, 0,191, 86,244,250,220,228, 87,169,176,208, -139, 60, 11, 22, 44, 88,176, 96,193,226,223, 13, 14,155, 5, 44, 88,176, 96,193,130, 5, 11, 22, 31, 22, 4, 64,177, 51, 1,202, -179, 82,118, 69,102, 19,148,197,207,114,178,156, 44, 39,203,201,114,178,156, 44,231,199,199, 89, 22,119,121,244,199, 63, 26, 52, -223, 99,250, 95,177, 1,104,199,114,178,156, 44, 39,203,201,114,178,156, 44, 39,203,249, 95,219,216, 46, 66, 22, 44, 88,176, 96, -241,159,131,131,131,159,220,193,193, 79,110,233,249, 50,101,117, 39,153,178,186, 19,155,115, 44, 44, 5, 43,176,222, 19,132, 16, -226,239, 45, 31,215,161,165,199,209,128, 42,210,158,127, 23,167,220,169,138, 82,225, 89,255, 15, 43,247, 26,157,255,130, 52,138, - 2, 3, 3, 27, 7, 6, 6, 54, 38,132,136, 62, 4,167,204,201,127,160,135,111,227,107, 78, 62,117, 47,203,157,253,250,124,232, - 56, 43, 92,125,237, 21,158,245,126, 85,184,213,206, 84,184,214,206, 81,120,212,187,106,165,172, 94,165,172,235, 60,123, 46, 9, -152,191,255,233, 62,207,158, 75, 2,138, 59,110,215,121,157, 98,238,129,151,139, 28,122, 44,147,179,181,191, 98,240,108, 54,200, -198,181,213,100,251,242, 94,231,238,223,248,169,119,141, 22, 41,110,126,141,158, 88,122,141, 71, 64,147, 7,149, 2,155, 37,123, -248, 55,185,207,230,188,101,144, 56, 86,105, 44,177,243, 58, 37,182,243, 58, 45,182,175,210,250,125,249, 92, 93, 93, 37,213,170, - 85,235,212,184,113,227,209,237,218,181,251,182,110,221,186,163, 42, 85,170,212,129, 16,242,183, 77,178,146, 57,249, 79,215,241, - 73,154,142, 79,210,100, 78,254,211,203,110, 95, 3, 22, 18,142, 57,129,112,204, 9,114,167,128,133,255,148,178, 18, 59,251,123, -201,156,252, 87, 89,185, 4,222,149, 58,249,117, 47,239,245,118,118,118, 29, 28, 29, 29,123, 21,108,118,118,118, 29,216, 39,224, -195,161,220, 21,156,144, 32,190,220,197,248,173, 80, 44, 25,206,225,192, 42,229,229,109,183,127,114, 2,149, 85, 26,222,231,114, -184,238,133,195,204,140, 57, 46,245,213,157,122, 31,130,223,191,146,100,228,204, 73, 93, 39, 14,252,180,161, 87,187, 79,150, 17, - 0,199,138,125,225,123,214,191, 73, 8,167, 50,135, 0, 28, 14, 1,135, 0, 0, 77, 72,123,117,167,110, 69, 57, 11, 96,237,232, - 83, 89, 40, 87, 94,107,214,243, 43,231,224, 11,123,118,200,148,213,219,171, 83, 67, 31,127, 0, 97,165,244,241,241,169,239,231, -231,103, 63,110,220, 56, 1, 0,252,248,227,143, 85,171, 86,173,154, 30, 17, 17,113,143, 82,154, 90,161,198,205, 49, 96,200,154, - 21,243,119,117,238,220, 5, 9,105,106, 44, 91,181,161,149,220,217,175,111,110, 82,248,225, 15, 81, 38,182,182,149,173,120, 86, -182, 33,223, 76,153,239,216,169, 85,125,110,174,214,132,179,215, 30, 54,223,179, 97,254, 93, 43,101,245, 6, 57,169,161,175, 74, -186,150,201,203,158,229, 36,167,157,152,188,108, 0, 24, 88,244,184,155,220,216, 78, 41, 49,119,114, 17,241, 30, 2,248,173,204, -184,120, 55, 59,199, 23,137,188, 56, 28, 14, 10,202,158, 75,222,148,191,209,160,137,137,123,118,173,227, 63,225, 57,177,242,106, -152, 4, 46,207,158, 67,254, 23, 63,146, 95, 79, 9,165, 57,137,225,215,237, 63, 64,125,178,174, 81,213, 38,176,107,211,102,191, - 92,141,204,144,121,182,156,112,138, 80,206,198,152,107, 43, 31, 89,244, 50, 17,139,109, 79,156, 56,161,236,212,169,147,181, 83, -141, 94, 87, 45,250,240, 16,138,171,159, 60,121, 92,208,169, 83,199,114,212, 79,255,246,224,112,118, 19,128,207, 48,244, 71, 46, - 67, 15,230,166,135, 71,148,215,157,138,212, 41, 96, 36, 7,212,226,118,134, 1,185,159,151,252,124, 91, 5,243,150, 43,113,244, - 31, 46, 17,139, 39,251,250, 87,243,139,138,140, 8,207,201,201, 94,165, 73, 9,223, 70, 41,101,202, 69,102, 52,125,119,225,122, -112,103, 30,159, 79, 58,181,109,200, 5,112,249,125,202,221,201,201,169,215,186,117,235,170, 52,110,220, 24, 0, 96, 50,153,172, - 14, 29, 58,228,188, 96,193, 2,153, 37,207, 80, 9,233,117, 83, 42,149,158, 66,161,208, 13, 0,244,122,125,124,106,106,234,107, - 74,105,124,153,117,194,217,199,129,128, 55,255,250,181,107, 60, 0,104,222,188,197, 66,175,230,227,108,185, 2,185,166,216,236, -208,171,100, 0, 38,220,190,115,139, 0, 64,163,134,141,167,201,148,213,215,171, 83, 67,147,255, 54, 17,236, 20,208,144, 3, 76, -108,218,162,125,239,254, 3,134,112, 2,125, 61,209,161,125,155,169, 0, 78,148, 75, 0,240,120,146,187,119,239,250,112, 56, 28, -174,201,100,210, 54,106,212,232,245,251,196,203,205,191,201, 77, 2,142,135,193,164,223,154,250,234,254,194,162,117,143, 16,194, -181,246,168, 59, 19, 92,222, 23, 12,195,196,230,196,220,107,194, 10,172, 66,153, 99,229, 94,231, 70,191,254,131,107, 44,152, 50, - 74,188,118,247,121,216, 85,110, 16,154, 17,121,183,250, 63, 53,129, 92, 14,215,253,220,239,231, 28,165, 66, 46, 0, 32, 87,107, - 66,231, 78,157,202,188,206,198,187,225, 21, 14, 33,254, 5, 75,122,155, 77, 6, 49,143, 47,212, 18, 0, 32,111,102, 7, 56,184, - 86,186,228,226,108, 45, 29,248,105, 67,175,221,135,110,199,189,142,207, 42,177,209,231,112,184,238,199,142,159,112,116,179, 23, -131,199, 37,200,213,152,208,169, 75,119,115,113,231,186, 56, 91,119, 29,248,105, 67,175,189,135,239,188, 78, 76,202, 62, 85,106, - 35,238,226, 23, 36,179,118, 58,219,123,244, 2,123, 45,199, 14,179, 23,173,113,184,118,102,239,213,150, 93,135, 48, 49, 49,177, - 90, 74, 72,104,102, 70,226,183,185,137, 47,195, 44, 45, 99,185, 92, 94, 69, 46,151,215,238,220,185,179,120,242,228,201,252, 86, -173, 90,189, 61, 62,106,212, 40,193,149, 43, 87, 92, 86,172, 88,209,197,213,213, 85,155,155,155,251, 40, 55, 55,247, 21,165,212, -108,105,153, 56, 59, 43,191,254,244,147,238,104,211,251, 43,152, 25,130, 81, 95, 78,192,185, 51,191,141, 1,240, 65, 4,150, 81, -106,181,224,139,209,147,149,141,234,215,225,206,223, 27, 6,137,144,135,142,245,252,201,136,113,179,108,182,173,157,255, 51,128, -150,197, 89,174,152,188,236, 89, 53, 28,244, 3,122, 52,174,140,227,251,244, 3,220,219, 77, 5, 71,106,189,240,245,177,233,207, - 1,192,167,243,120,133,173, 68,178,206,213,134,235, 40, 50,167,174,243,233, 60,254, 66,196,153,181,170,210,226,194, 23,137,188, -246,237,221,235,107,171, 16,128,199, 33,224,114, 9,120, 92, 14,180,122, 51,250,246, 27,240,161, 44,140, 92,137,163,111, 23, 14, - 48,226,205,139, 26,219, 53, 41, 47, 78,151,167, 76, 8, 87, 96,127,242,248, 17,158,163,181, 8, 92, 46, 1,151, 3,112, 57, 4, -209,201, 26,140, 28, 57,194,250,125,133,122,231,166,142,245,175,172,111,217,177, 81, 13,187, 90, 7,110, 17,235, 70,157,251,219, -167,105,165,195,247, 31,187, 60,192,179,197,196, 59,148, 50,203, 99,175,175,254,189, 52, 30,157, 78,151,220,177, 83,103, 43,194, -147, 73, 47, 28,221,209,130,199, 33, 48,154, 41, 76,102, 10,115,254,218,165,111,158, 87, 2, 14,135,128, 50, 20, 95,124, 49, 18, - 29, 59,117,206, 99, 76, 76,156,197, 17,230,112,118,159,189,240,135, 82,103,100,176, 98,221,182,249,234,236,212,249,145,207,237, -163,165, 78,126, 19,242,146,195, 45, 94,183,130, 3, 90, 47,246,213,147,209,123, 79,222, 70,141,234,213, 96,102,222,196,211,223, - 93,134,189,167,110, 35,192, 63,224, 77,188, 25, 10, 63, 15, 57,234,215,171, 15, 0,219,202,159,191,173,120, 50,167,128,125, 61, -250, 12,235,211,187,207, 64,216,217, 90, 65,111,208,249, 93, 60,119,122,203, 79,235,150, 53, 37,132, 12, 47,151, 56,164,230,183, -239, 5,202, 48,239,109,101,114,117,117, 85,214,175,255, 63,119,138, 38,147, 9,222,222,222,136,143,143,247,175, 64, 93,146,186, -184,184,116,221,188,121,179, 99,151, 46, 93,248,206,206,206, 0,128,164,164, 36,183,179,103,207,214,117,117,117, 77, 73, 76, 76, - 60, 69, 41,205, 43,137,195,108,228, 8, 56, 60,112,197, 98,233,155, 52,130,112, 38,127, 61,180,150,147,139,171,174,184,243, 83, - 83,147,132, 83,190,186, 76,120, 60, 65,254,249,224, 80,202,144, 82,172, 66,237,248,124,190,164,184, 99, 6,174, 85, 35,202,183, -254,156,195,229,188,169,172, 38, 99,106, 70, 76,112,181,114, 88,222, 2,249, 66,193, 79,131,134,141,110,210,167,119, 79,184, 40, -173,113,225,198, 99,140,249,122,162,209,100, 48,174,170,208, 59,146,203,229,165,164,164, 68,219,218,218, 58,191,255,251,150, 84, - 62,127,238,140,227,133,139,151,166,173, 92,189,118,172,171, 95,115, 35, 67,233,219,117,134, 61,107,180,225,183,239,214,207,202, -209,167,145,120,237,156,207,249,172, 5,171,176,242,119,173,254,109,223,126,253,106,124, 53,102,148,248,219,117, 55,112,113,223, -143,105, 31, 74, 92, 41, 28,253, 27, 19, 46,111, 52,225,114,101,132, 67,132,140,153,137, 53,233,245, 11,243,210,194, 19,223,151, -155, 97, 40,126,189,153, 82,190, 7,153,162,234,238, 3, 71, 28,157,108, 68,208, 26,204,232, 63,112, 8,118,237,218,165, 80, 90, - 11,161,213,155,176,124,229, 74, 85,110,244, 49,199,232,216,156,248,118,159,174,248,253, 85, 84,198,147,215,137,218,131, 37, 55, - 12, 28, 56, 90,139,176,104,127, 56,172, 36,124,216, 42, 4,224,112, 72,225,134,131,248, 85,146,125,237,225, 97,211, 58, 33, 41, - 39,187, 16,231,158, 18, 31, 54,151,154, 29,173,109, 93,247,125, 50,122,145,205,139, 20, 30, 40, 12,136,176, 18,163,223,240,241, - 86, 85,156, 37,144,137,185, 54,145, 49,241, 46,147,191,251,238,134,181,163, 79,131,236,148,136,200,178,210, 93,169, 82,165,222, -221,186,117,147, 78,154, 52,137,239,225,225,129,237,123, 15,121, 53,239,216,183,123, 66, 98,178, 7,165, 20, 78,142,142,177, 95, -140,232,123,226,244,233,211, 49,177,177,177,252,101,203,150, 53, 60,114,228, 72,245,242,124,137,154, 41,133, 86,103,134, 57,255, -197,152,154,173, 43,111, 35, 75,220,220,220, 68,241,241,241,186,130, 23, 7, 33,228,109,102,202,221,234,116,108,219,178, 33,111, -243,153, 40,228,106,205,144,137,249,136, 74,206, 67,189, 58, 53,201, 86,179,169,118,113,156, 35,251,117,157,229, 36,167,157,122, - 52,174, 12, 71, 91, 41,126, 89,191, 8,199,111, 69,118, 74,206, 37,112,232,177,108,180,139,136,215, 94, 41, 21,172,107, 85,207, -199,185, 77,144, 23,238,213,243,113,190, 22, 28, 22, 94,179,223,170,113,241,185,252, 11, 25,103,198,169,138,111,112, 56,176, 83, - 8,176,237, 92, 12,164, 98, 30,100, 98, 30,100,162, 55,251,194,229, 95,161,175, 88,215,234, 30, 92,198, 60,210,202,181,250,200, - 1,253,250,186, 14, 26,208,151,130,203,193,161, 95, 79,244,220,179,103,119,162,220,217,255,103, 51,135,187, 77,147, 16, 26, 91, -102,158,114, 0, 71,107, 33,190,251,249, 9,172, 36,124, 40,164,124, 88, 73,249,104, 83, 75, 9,110, 5, 7, 18, 16, 66,108,199, -244,172,210,229,241,174,118,173,253, 61,229,190,143, 34,178, 67, 71, 46,188,191,250, 74, 86,235,111,215,255, 88,221, 62, 55, 75, -207,155, 61,249, 11, 94, 92, 66, 66,235, 67, 39,174,182,113,109, 48, 50,204,100, 80,207, 72,121,116,176, 88,139,109,236,243,155, -117,221, 27,247, 21, 27,114,141, 33,143,194,226,124, 50,117, 34, 60,141,206,129, 76,204,131,188, 32,111,197, 60,200,196,124,200, -197, 60, 36,196, 69, 33, 67,205,189, 17,111,207,105, 77,175,220, 52,149, 39,238, 90,131, 25, 15, 35,115, 81,201,191, 14, 92, 92, - 92,161,239, 50,184,210,157, 75,191, 30,147,185, 84, 91,162, 78,124, 54,195, 82,158,189, 39,111, 99,218,132,209,193, 4,120,144, -255,114,174, 59,123,233,134,160,249,211,190,122, 39,108,242,188,181, 65, 21, 21,215, 82, 39,255, 61, 45,187, 14,233, 83,179, 81, - 7,188,138,138,194,153, 19,247,209,182,125,103,116,233,222, 27,122,189,110,232,182,205,107,239, 1,216,240,167, 54,215,165, 90, -179,154, 53,170,237,113,115,117,245, 96,152, 55,171,114, 80, 10, 52,107,217, 6, 83,190,253, 2, 12,165,168, 93,183, 65,155, 46, - 3,198, 81,154,191,122, 71, 90,122,154, 58,236,121,104, 59, 77,242,243, 59, 22,231,165, 86,107, 76, 77, 77,197,195,135, 15, 17, - 30, 30,142,167, 79,159, 34, 61, 61, 29,214,214,214,185,229, 76,171, 85,173, 90,181, 6, 93,186,116, 73,108,107,107,251, 54, 92, -175,215, 67,161, 80, 96,208,160, 65,252, 14, 29, 58,184,117,237,218,117, 24, 33,100, 47,165, 52,167, 56, 30, 77,250,139, 4, 43, -231,128, 77, 45, 91,181, 28, 11, 0, 18, 43,151,200,117,219, 79, 60, 45,245, 89,179,118,245,106,210,164,169, 15, 40, 5, 1, 93, -163, 78, 11, 75, 42,197, 42, 36,187,125,251,118, 21, 46,151,203,251,223, 59,136,193,198, 95, 14, 4,156,191, 30,210,123,233,242, - 21, 98, 43,153, 8,169,217,122,124, 62,248, 19,139,223,193, 82,231,128, 46, 77,155,182, 60, 54,127,222,247, 60,185, 76,134,223, -239,188,194,184,111,191,211, 38, 70, 63, 89, 65, 25,254, 6,117, 74, 88,202,123,190, 42, 63,136,195,107, 95,119, 57, 20, 61, 58, -138,199, 12,237, 33,214, 27,205,200, 82, 27,161, 51,152, 97,102, 40,178,213, 70,132,190, 86,193,193, 74, 88, 17,234,250, 0,148, - 0, 82, 1,220, 43,242, 31,249,191, 81,204,255,180, 55,102, 17,216, 3,208, 3, 40,124,243,130,255, 37,133, 23, 92, 31, 10,160, - 90, 62,167, 25,192, 93, 0,153,101, 10, 44, 66, 8,165,148,146, 66,149,248,157,255,133, 33, 16,202,251, 77, 27, 55, 68,188, 96, -111, 48, 46,238, 91,156,150, 26,113,171, 32, 1,112,244,105,248, 32, 37,226,221,238, 46, 75,166, 90, 74, 92,171,123,240, 8,119, - 85,203, 86, 45, 58,140,253,242, 75,248, 87,113, 23,152,205,102,250, 36, 60,210,184, 99,219, 47,195,173, 61,106,174,206,137,123, - 50,171,192,212, 88,222,233,155,102,198, 28, 87,212, 98,101,102,204,113,101,197,147, 16,192, 70, 46,196,166, 51, 81,160, 20, 32, -160,176,150,241,177,255, 74, 28, 34,131,127,203,233, 86,227,181,122,208,252, 81,109, 90,247, 92,118, 41, 52,194,120, 48, 37, 69, -123,142, 82,154, 84, 18, 39,135, 0, 60, 46,129,149,148, 15,107,169, 0, 54, 50, 1, 72,161, 23, 87,225,110,193, 86, 61,126, 56, -127,233,143,248, 25, 0, 82, 41,165,186,226, 56, 37,206,190,245,173,108,220, 15,246, 30,187, 76, 17, 18,103, 2,143, 11, 84,118, -150,192, 78, 33,128,222, 68, 16,157,106,200,127, 98,108, 48,110,242, 60,187,105, 19,199,158, 38,164,122, 13, 74, 67, 13,165,165, - 61, 47, 47, 79, 56,100,200, 16,190,209,104, 52, 12,250,252,155, 14, 73, 73,169, 61, 55,174,249, 65,228,232,232,132, 60,173, 9, -193, 79, 95, 86,155, 63,127, 94,229, 19,103,175, 28,157,251,221,152, 99,157, 58,117,178, 62,112,224, 0, 83,158,114, 79, 77, 78, - 91,255,203,158,195,187,126, 92,177, 24, 97, 49,153,216,182,121, 3,168,217,180,169,212, 39,191, 16, 39,165,148,206,152, 49, 67, -114,244,232, 81,119,153, 76,150,147,151,151,151,250,142,253,129, 67,120,201, 25,121,112, 80, 8, 33,224,113,224,100, 43,134,163, -181, 8,124, 46,192, 33,196, 92, 28,231,182,131,167, 22, 50,121,217, 56,190, 79, 63,224,151,245,139,240,217,215, 51,241, 36, 77, -120,150, 35,181, 94,248,213,128,222,211,148, 18,115, 39, 87, 27,142, 99,155,160, 74,144,137, 5,152, 62,126, 8, 26, 4, 71, 59, -198,103, 49, 51, 83, 53,220, 58, 0,102, 22, 91,238,156, 55, 22, 43,133,148,143,179,123,150,167,168,179, 83,179, 11,186,222,244, - 58,109,140, 69,173, 94, 49,249, 41,115,242,159, 22, 84,167,214,162,177,163, 70,114,154, 54,110, 64, 57, 28, 62,210, 84,122, 66, - 41,240,237,184, 49,248,106,204, 23,206,177, 9, 41,179, 55,108,216, 52, 75,238, 88,109, 65,110,202,179,185,165,113,114,200, 27, -171,143, 92,204,131, 92,242, 70,176,200,197, 60,104,245,102, 16, 2,174,173, 87, 80, 54,121, 99,185, 77, 72,143, 46,254,139,187, - 40,167,157,103,224,197,243,145,138,128,204,131,153,183,162, 18,158, 46, 12,126,156,124,151, 82,154,225,217,114,226, 48,131,137, - 34, 87,107, 66, 84,114, 30, 76, 6, 74, 62,235,236, 5,239, 62,196,127,241, 47, 15,118, 17, 66,172, 10,132,115, 81,206,184, 91, -135,180, 14, 53,123,247,255,113,237,230,123, 43, 22,205,228,166,101,235,193, 80, 10,177,144, 11,137,144,151,191,113,161, 81,103, - 99,195, 79, 91,147, 76, 32,189,233,149, 43,166,114,181, 75, 12, 29,252, 73,151, 22,251, 9, 32, 36, 28, 65,156,171, 87, 37,175, -182,221,135,139,219,246, 24, 2,179, 73, 63, 77,230, 20,112, 89,157,252,252,162, 37,156, 53,170, 87, 3, 1, 30,228, 38,135,141, - 1, 0,185,147,255,166, 0,255,128,160,162, 97, 85,171,250, 7, 89, 82,238,249,109, 52, 71,162,244, 29, 85, 53,160,230,148,177, -223,111,174, 20,149,152, 7, 59, 15, 95, 60, 13,121,136, 51, 7,214, 63,208,168, 50, 87,156, 57,254,219,148, 5, 63,172,169,221, -189, 87, 63, 28, 59,114, 96, 18, 33,100, 35,125,131, 11,133,172, 83,131,119,252,188,197,131, 47, 20,193,104, 98, 96, 52,211, 55, -123,147, 25, 25, 25,153, 48,154, 24,136,165, 10,152, 24, 2,163,153,129,209,196, 64,167, 55,201,198, 12,233,250, 37,128, 59,197, -197,211,189, 90,171,115, 2,145,200,139,226,205,218,178,148, 82,112, 77,122,142,139,139,203, 94, 0, 16,137, 68, 16,137, 68, 96, - 24, 6,193, 97,169, 95, 43, 3,218,141, 69,190,176, 51, 27,244, 49,153, 81, 55, 58,150,148,118,103,103,231,238, 69,197,149, 86, -171, 69,110,110, 46,174,223,186,103,253,243,174,195,157,162, 98,226,170, 48,212, 90,167,112,172,210, 17, 64,247,146,242, 51, 39, -233,249,151, 30,141, 71,113, 38,125, 53,172,234,218, 29, 39,239,190, 56,187,160,212,113, 88,149,219, 77,211, 79, 26,253,105,189, -165,107,182,189,200,184,241,211,132,178,202,136,199,227,241, 83, 83, 83,223, 62,223,235,182,238,171,247, 32, 44,190,215,234, 31, - 87,139,131, 95,169, 16, 18,149,128, 97,237, 60,241,206, 75,160, 20, 78,185,179,143,131,143, 79,192,222, 13,107,150,242, 94, 36, -104,177,254,183,187,184,116,108,211,245,164,148, 59,157,104, 82,130,166, 34,109,200,251, 10,172,210, 56, 47, 63, 78, 67,174,214, - 4,157,222, 4, 35, 67,145,147,103, 68, 74,150, 30, 57,121, 6,228,106, 76, 24,214,222,179, 36, 17, 93,154, 30, 81, 18, 66, 78, - 82, 74,187,225,141,123, 41, 97,161,255, 32,132,156,204,143,215, 59,255,167, 77,155, 54, 99,201,146, 37, 79, 11,206, 45, 8, 47, - 56,183,180,240, 66,215,219, 79,159, 62,189,198,210,165, 75, 23, 55,110,220,120,255,205,155, 55, 35, 45, 18, 88,133, 19, 65, 8, - 41, 53,131, 69, 2,158,171, 84, 97,251, 70,112,252,207, 96,128, 74, 53, 90,165,175, 94, 54,223,206,197,183, 81, 76,226,139,219, - 94,150, 91,173,252,154, 72, 36,210, 83, 43, 87,174,196,128,238,205, 37,175,211,140,185,143, 95,107,146,213,122,152, 28,149,126, -194,133,139,151,202,151, 46, 91,254,213,201,227, 76, 22,128,229,197,119,229,213,191,207, 37,133,198, 88, 17, 2,202,152,227, 50, -162,238,214, 3,128,247, 25,107,149,171, 53,130,155, 63,118,134, 16, 32, 79,107, 2,151, 75, 82,178,158,239, 11, 29,244,253,216, - 54,187, 15,222, 78,160, 92, 59,149, 90, 29, 37,165,148,198,149,110, 33, 32,200,201, 51,194, 90,202,135,141,156, 15,107,153, 0, -220, 66, 15, 87, 65,183,224,238,131,183,226, 99, 98,179,238,229,139,171, 18, 57,121, 92, 78, 36, 53, 27,181,148,154, 21,221,234, - 43,225,104, 35,132,139,173, 8, 34, 33, 15, 70, 19,160,209, 51,208,234,205,136, 78,209, 64,165,145,160,102,203,190,149,237, 93, -238,235,236,189,234, 31, 77,143,185,215,187, 84, 81,106, 54, 99,199,222,195, 85, 19, 18,146,123,158, 62,186, 71,148,154, 99,196, -227,104, 53, 82,178,116, 0, 87,137, 57,139,215,139,166, 78, 24,213,107,199,190, 95, 99,218, 54,111, 24, 83,222,124, 85,167, 60, -223, 93,179, 73,215, 77,221,186,245,146, 60,189,115, 26, 47, 30, 94, 92,148,155,108,249,248, 43, 66, 8,231,208,161, 67,166, 81, -163, 70,169, 22, 47, 94,236,113,252,248,113,239,212,212,212,135, 0,140, 54, 54, 54, 1,126, 85,189, 30,253,126,246,140, 91,215, - 94,125,249,113,105, 26, 88, 75, 5,240,114,148,226,214,245,115, 70,161,144, 95,236,120,146,252,110,192,129,238,237,166,226,248, -173,200, 78, 79,211,197, 87,190, 24, 57, 44,230,247,107, 97,233,235,118,253,254,131,155,220,248, 80,204,164,174,187, 95,207,199, -121,218,184, 33, 88,178,118, 55,174, 6,135,165,168, 57, 46,139, 18,117,166,243,115,251, 79, 41,193,100,254, 70, 88, 43, 36,124, -168,115, 82,179, 95, 6,159,241,251, 64,214,231, 97,191, 31,221,205,201, 80, 25, 17,155,166, 37, 9, 25, 42,152, 25, 10, 27,169, - 0, 38,134, 34, 43, 35,141,236,217,189, 11,247,238,221,226,128,203,249, 28,192,220, 82,187,179,200,155, 46, 65,185,152,255,198, - 2, 36,121,179, 55,154, 25,248, 87,245,193,150,117,171,172, 28, 28,157,208,172,133,229, 99,158, 21,246, 94,181,247,111, 95,135, - 43, 55, 31,180,186,186,122,125,125,185,171,114,173,149,123,245, 21,214,222,237,181, 58,131, 25,217, 89,153, 16,234, 99,209,192, - 45, 21,118, 82, 51,162,115, 92,240, 36,233,133,188,172,238,172,180,144,223, 30, 42,107,124, 50,235,240,137, 75, 75, 58,182,111, -133, 39,209, 57,144, 8,121, 16, 11,185, 16, 11,185,224, 19, 51, 86,253,180,201,152,153,173,234,150,246,228,104, 90, 5,234,231, -133,252,175,221, 55, 47, 55,167, 42,202,221,107,103,237,252, 98,202,178,142,157, 62, 25, 78,158,220,187, 60, 3,192, 69,203, 62, -240,168, 69, 97, 12, 67, 45,174,251,142, 62,245,246,110,223,177,175,127,117, 95, 15, 36,103, 25,145,144,105,192,245, 7, 17,216, -249,243,172,172,204,228, 87,131, 97,200,205,101,136, 41,251,220,217, 19,103,191,254,102, 10, 2,107,212,174,148, 19,151, 99, 5, - 32,251,157,123,114,201,230,161, 35, 71,247,119,114,114, 82,252,207,130, 69,225,231, 95, 29, 93,122,124,138,115,199,142, 32,244, -233, 99, 48,244,141, 80, 98, 24,138,172,204,244, 36,147, 81,191,163,164,248, 9,197, 98,175, 95,182,239,242,229,112, 8, 12, 70, - 6,122, 19,131, 9, 95,142,208,143,249,118, 70,179, 46, 29, 90, 62, 21,114,145, 19,253, 58,209,230,214,131,103, 53, 25,190,220, - 99,228,228, 85, 2,173,206,140,236, 60, 35, 78,111, 43, 89,227, 72,236,188, 26,215,110,210,107,228,152,239,183,136, 68, 92,142, - 33,208,207, 35,178,101,163,192, 88, 79, 87, 7,213,252,165,235, 27,220,184,243,160, 75,191, 65, 35,197,195, 2,130,136,171,189, - 68, 49, 98,208, 39,181,100,246,158, 67,213,233,175, 75, 92,218,140, 47,181,205,242,244,174,154,247, 63, 11,145,255,111,132,162, -242, 59, 34,130, 32, 50, 47, 41,172, 55, 0,184,184,122,106,249, 34, 43, 85, 57, 4, 8, 5,128,181, 91,247,213,123, 20,158,240, -197,143, 63,174,150, 6,191, 82,225,225,171,108,136, 4, 28, 24,140, 12,136,133, 70,108,134,114, 71,207,156, 62,205, 42, 83,109, -198,149,199,169,120,122,255, 50,213,231,106, 7, 73, 77, 86,189,101, 78,254, 67, 1,248, 0,136, 32,132,110, 86, 39, 59, 31,163, -244,138,169,188,245,158, 97,222,124, 39, 91, 59,250, 84, 54,243, 68, 93,248, 66, 89, 99, 66,104, 32,161,176, 5,104,124,122,254, - 59,213, 82,133,166, 78, 14,199,178,197,179,177,230,231, 35, 72, 72,215,194,218, 28,139, 99,219, 22, 98,210,146,189,208,232,204, -165,213,241, 82,245, 72,113,130,168,168,208, 42,248, 93,112,222,146, 37, 75,186, 21, 41,155,110, 37,148,217,159,206, 43,184,126, -233,210,165,139, 11, 29,207,179,184,139,176, 32, 49,165, 37,202, 74, 89,189,138,192, 74, 46,178,146,240,225,237,233,130, 1, 99, -231, 58, 56,251, 54, 77, 17, 9,121,220,163,251,182,216,165,105, 68, 32, 28,142,218,226,238, 13,167,128,134, 10,133,226,244,111, -191, 30, 65, 21, 79, 71,193,158,235, 25, 81, 15, 34, 53,111, 77,186, 57,169, 49, 66,111,171, 60, 94,239, 79, 62,145, 94,188,116, -249,219,146, 4, 22,151,112,221,183,238,250,213, 81, 33,225,131, 16, 64,165, 49,225,139,161,159,190,255,235,139, 50,220,145,195, -135,129,228,139,171,156,244, 36,204,152,250,165, 86,102,124, 22,250, 58, 38, 62,190,221,167, 43, 47,230,228,242,181,253,135,124, -121, 47, 52,124, 73,102,217,181,215, 24,215,165,107, 23,193, 27, 75, 1,192, 37, 4, 12,101,146,253,189,229,227,254,212, 45,152, -164,219, 90,150, 96, 83,197,135,101, 40, 92,106,246,217,189,242,235,173,174, 78,142,246,114,153,132,202,165, 34, 18, 24,224, 43, -104,212,168,137,208,219,191,150,224,250, 51, 13, 94,167,106, 16,153,144, 13,145, 83, 29,222,128, 54,157,177,123,245,228, 86,132, - 16, 78, 89, 3, 95,207, 95,185,221,253,231,159,126, 20, 37,103, 25,240,252,117, 46,146, 50,181, 72,204,212, 33, 41, 67, 11,185, -132,143, 22, 61, 70,137, 78, 29,219,220,189,109,243,134,107, 43,146,189,145,145, 81,167,162,227, 19,251,214,170,219, 0,187,119, -110,111,110,107, 91,217, 42, 51, 51, 50,199,210,210, 89,184,112,161,112,233,210,165,188,117,235,214,229, 52,106,212,200,121,250, -244,233, 29, 83, 82, 82,238, 86,170, 84,201,255,220,111, 59, 46,213,105,209,179, 62, 24,131,178,121,203,214, 2, 17,195,195,239, - 39, 79, 26, 14, 30,216,147,174,209,168,198,148, 42, 52,164,214, 11,147,115, 9,148,110,110, 79,229, 66,115,123, 30, 39, 43, 60, -227,204,184, 93, 0,126,243,233, 60,254,194,229,251, 97,225,245,130,163, 29, 47, 5,191, 76,201,200, 51,248, 69,156,153, 88,106, -131,203, 37, 4,124, 46, 7, 10, 9, 15,156,252,214, 84,225, 86,251, 37, 8, 81, 22, 88, 74, 9, 72,254, 30, 32, 4, 9, 25, 49, - 15, 44, 24,147, 65, 40, 67,129,176, 56, 53,114,181,111, 76,240,238, 14, 82,164, 38,199, 97,227,218, 29,120,112,255, 30, 58,116, -238,129, 13, 91,247,224,139,161,125,181,101,177,113, 56,249, 22,172, 66,214, 43,185,132, 7,128, 32, 75,109,196,175, 55, 98,225, - 83,153, 99,241, 11, 1, 0, 20,114, 41,178, 85, 26,112, 4, 10, 68, 4,159,150,158,185,124,103,250,172, 5, 63,126,151,153,248, -248,245,203,144,235,240,119,200, 70,101, 55, 3,158, 38, 89,225,126,186, 55,252,171, 86, 1, 71,112,207, 34,238,180,167, 53,151, - 29,227,252,218,173, 94,157,234,141,189, 28,109,160,209,155,243,173, 88, 92,108,255,101, 23,162,163,226, 70,166, 61, 61,250,224, - 67, 40,217,220,228, 87,169, 98, 39,223,175, 66,238, 92,140,252,100,208, 87,112,113,243,172, 93,158,225, 9,150,132,153, 45, 16, - 88,132, 16,142, 93,165, 58, 59,119,238, 62,212,191,178,167, 51,206,223,137,194,221,240,116, 56, 56,216,131, 43,117,134,111,203, - 17, 54, 33,103,215,124,170, 73,203,221,201, 23, 72, 63,111,216,168, 41, 40,165, 8,123,246, 52, 35, 59,219,250, 79,109,115, 94, -194,243,135, 0,172,222,233,134, 82, 86,171, 45,183,182,123,168, 51,152, 17, 31, 31,135, 63,110, 94,169,155,127,158,197, 16, 9, -184,248,253, 65, 10, 12, 70, 6, 6, 19,131, 22, 45,219,235, 5, 28, 93,243, 69, 63,254,210, 40, 49, 33,145, 35,179,114, 96,236, -220,170, 9, 92, 68, 6,221,163, 87,217, 2,131,145, 65, 21, 87, 89,169,156, 74,215,170,139, 39, 79,158, 80,141, 43,144, 64,165, -214,233, 19, 19,226,157,183,236,187,156,251,236,121,136,155,187,163,181,213, 15,171, 55, 11,114,180, 4, 41,217, 58,100,168,114, -200,160,209, 83, 92,127, 94,191,100, 48, 0,139,215,142, 37, 20,149, 79,253,126, 61,192, 86, 33, 32,185, 90, 19,147,158, 99, 48, - 15,234,245,126,147, 40,243,197,213,168, 31, 87,173,150, 62,120,165,194,163, 87,217, 16, 11,184, 16, 10, 56,208, 27, 25, 88,242, - 56, 17, 66, 56,149,107,180, 28,211,164, 94, 77,156,123,152, 6, 46,151, 3,141, 42, 51,143,135,244,240,122,173, 58, 72,131, 26, - 52, 66,235, 86, 45,241, 50, 60,204,243,228,241, 95,219,222,250,227,106,146,220,209,255,235,220,148,176, 35,229,170,231,121,121, - 92,163,208,121,132,139, 91,165,166,189, 7,140,176,246,242,116, 35,142, 14,246, 48, 81, 30, 70, 13,253,212,226, 39,255,141, 32, - 7,150, 46,152, 14,157, 78, 15,165,141, 16,148, 2,191,172,157, 11,189, 94, 15, 87,123, 17,178,213,198,210,132,105,169,122,164, - 36,171, 83, 57,187,155, 79, 22, 39,178,138,134, 19, 66, 78, 78,155, 54,109, 6, 0, 58,109,218,180, 25, 5,255,151, 44, 89,162, - 1,144, 96,145,192, 42, 72, 84,137, 13,165,171,175,159,173,163,235,141,131, 59,215,219,102,230, 26, 32, 22,112,225,238,225,133, -169,243,215, 40, 59,215,115, 64,170, 86,138, 67,135,183,103,232,181,121, 7, 44,235, 75,246,173,167,144, 89,157,219,185,251, 0, -227, 96,111,207,217,248,123,234,171,116,149,233,109,215, 85,248,157,227,204,253,115, 91, 92, 40,200, 89,177, 88, 92, 85,175,215, -219,150, 85,160,191,252, 30,147, 63, 56,151,124,136, 54, 21,132,203, 53,239,222,179, 27, 14, 86, 66,232,140, 12,166,125,247,141, -102, 88, 91,115,214,160, 79,223,116, 11,242,101,213, 46, 54,169,235, 75,235,212,169,147,197,229,114,203,228, 75,143,188,251,167, -217, 18, 1,222,210,207,103, 78,234, 62,179,152,110, 65,139, 6,228,170, 18, 67,110, 0,120,199, 34, 66,124,124,132,123, 15, 29, -251,166, 79,191,254,179,220,106,247,146, 71, 37,102, 67, 64, 12,168, 95,205, 5,151,207, 30,161,113,209,225, 19, 44,153, 85,148, -146,154,225,161, 84, 58,225, 65,100, 46,226,211, 53, 72,202, 23, 87,137,153, 58,168, 52, 42,212,242,114, 69, 86,118,182, 71,133, -243, 23, 56,114,238,220,185,190, 93,122,246,199,248,239,230, 53,219,246,211,138,199,114,103,191,207,114,147,194,175, 88,242,101, - 72, 8,201,152, 58,117,170,207,214,173, 91, 57,131, 7, 15,214,212,172, 89, 83, 60,100,200,144,102,187,118,237, 18, 75,165, 98, -205,163,235,199,103,125, 62,110, 90,207, 45,107, 22,214,206,204,204, 36, 38,163,241,140, 33, 51,115,154,170, 12, 17,247,250,216, -244,231,164,250,188,225,237,155, 43,143,219, 73, 57,129, 34,170, 31, 64,170,207, 59, 64, 67,231, 24, 34,206,172, 85,213,236,183, -106, 92, 66, 22, 51, 83,203,113, 92, 84,150,184, 2, 0, 14,151,252, 31,123,103, 29, 94,197,209,182,241,123,142,231, 72,220, 29, - 8,132,132, 16, 92,139,187,107,209, 82,161, 45, 82, 42, 20,105, 75, 75,139,150, 66, 41, 20,105,105,177,226,180,184,187,187,107, - 2, 17, 8, 81,226,114, 36,199,101,231,251, 35,242, 6, 26, 57,161,244,123,251,210,249, 93,215, 94, 73, 78,118,239, 51,179, 59, -187,123,207, 51, 6,147,213, 6, 71,169, 16, 60, 30,175,196,188,251,174,223,118, 68,230,233, 44,134,144,207,131,128, 95, 20,221, -204, 85,155,241,225,232, 1,118,215, 0,172, 54, 10,189,201, 10, 93,113,109, 80,163,206,197,151,159, 77, 70,175,126,131,240,254, -248,201, 40,208, 3, 55,159,104, 96,182, 88,170,188, 41,120,132, 7,157,209,138,119,187, 7, 35,191,208, 12,173,222, 10,147,149, -131, 76, 44,128, 80,192,131,220, 65, 0, 39,153, 16,160, 84, 68, 8, 25, 11, 0, 66,161,208, 96, 54,155, 55, 87,114,157, 80, 51, -208, 27,122, 11, 15, 45,134, 47, 66,215,214,117, 17,125,113,151,224,220,213,251,181, 62,253,108, 58, 38,142,233,135,157, 49,181, -225,230, 21, 12,133, 92, 10, 11,229, 1,160,118,117,200,163,116, 38,231, 27, 62,120,228,202, 53,235, 98,231,204,152,230,160,212, - 18, 72, 68,124,156, 62,117, 18, 87,174,221, 92,150, 19,189,119, 51, 94, 34, 66,202,243,118,114,114,130,131,152, 15,147,217,104, -178,191,139, 2, 5, 5,154, 40,188,195, 86, 22,215,240,155,216, 56,148,243, 25,173,234,133, 64,156,253, 34,215,175, 92,187,101, -148,159,143, 23,246,156,186,135,245,107,126, 66,173,198,125,113,241,208,122, 56,215,108, 5,121, 80, 91,136, 29,119,140,229,241, - 5, 13, 62,250,244,171,193, 77,155,183,198,165, 11,167,145,157,153,177,146,210, 24,187, 34, 26,124, 33,249,164,115,183,126, 48, -152,108,104,215,165, 47,142, 30,216,243, 49,138, 7, 79,216,255,242,122,238,249, 12,158,117,242,164, 79,132,217, 74,147, 48, 71, -109, 66, 90,142, 14,137, 89, 58,236,251,227, 55,106,255,243,194,212,188,125,195, 0,225,216,133,167, 83, 3, 3,124,141, 66,163, - 94, 26,247, 56, 33,252,253,209,111, 11,107,213, 9,231,101,171,140,200, 81, 25,145,171, 50,162,208, 96, 69,157,128, 80,158,197, - 74, 90, 87,247, 58,123, 56,139,133, 43, 14, 60,129,147, 92,136,215,194, 95,124,224, 44,199,113,255, 49, 87, 75,138,204,213,189, - 39, 42, 72, 68,124, 72, 68, 60, 72, 68,124, 88,109,212,174, 10,139,212,171,110,239, 15, 63,154,224,103,178, 2,121, 42, 19, 4, -124, 2, 47, 15, 87,121,243, 70, 35,177,110,209,199, 0,128, 49, 95,252,130,247,223,125, 19,245,234, 55,128,178,160,192,103,228, -144,222, 75, 0,236,177, 55,173,135,143,159, 13, 58,126,254,246, 23, 31, 78,157,169, 24,214,175, 19,255, 78,130, 10, 25,249, 70, - 60,142,211, 84, 43,210, 6, 0, 86, 27, 7, 10,138, 13,219, 14, 66, 42, 22, 32, 71,101, 6,165, 20,223,254,180, 29,142, 82, 33, - 50, 10,138,154,245,171,120,198,147, 42,254,223,247, 47,197, 79,138,142,207,193,127,250,105, 85, 25,193,154, 63,127,126,244,252, -249,243,203,141,136, 85,105,176, 42, 51, 87, 46,174,190,151,246,111, 91,227,182,231,182, 9, 87,119,220, 68,159,150,190, 16, 9, -120,144, 57,123,226,238, 19, 45,142, 29,253, 93,121,120,255,206,167,249, 66,221, 15, 85,154, 43,223,176, 38,114,169,211,201, 21, -171, 55, 90, 61,188,188,176,249, 66,126, 90,129,214,106,249, 79,243,148,133,220, 60,182,186,150,149,179,244,212,103,198, 87, 89, -157,229, 40, 68,243,127,221, 7,128,130,227, 56, 80,142,131,208, 65, 33,247,172,221, 58,171,248, 1,231, 32,224, 17, 67,217, 59, -159,114,214,180,156,132,202,195,157, 4,128,179, 76,136,109,231,158, 2, 64, 22, 95,125,253,225, 27,175, 23, 53, 11, 26,204, 50, -117,253,218,181,105,243,230,205,149, 82,169,244,133, 47,114,117,155, 5,237, 42, 56,143, 31,155, 0, 44,244, 11,107, 55,168,135, -162, 97, 11, 49, 79,132,166, 97,190, 56,115,108, 47,189,122,116,221, 24, 93, 86,236, 70, 59, 11, 32, 10, 13, 22,164,231, 25,240, - 52,207,128,204, 2, 3, 50,243,141,200, 44, 48,128, 16, 2,131,201,250,151, 94, 88,218,236,216, 29,155, 55,174,237,111, 52, 99, - 68,251,238,131, 48,121,230,138,224,205, 43, 23,156,148,122,135,183,177,167, 3, 45,165,212, 70, 8, 73, 26, 61,122,116,163,223, -127,255,157, 31, 25, 25,169,127,248,240,161, 12, 0, 7,192,172, 80,200,164,191,253, 60,255, 88,139, 22, 45,254,120, 26, 23,115, - 26, 64,129, 61, 35,169,106,116, 28, 45, 9,119,202, 31, 27, 36,127,173, 71,136,143, 12, 65,114, 77,143,112,197,221, 31,188,186, -124,250, 93,246,169,165,217, 25, 70,235,137, 28, 61,191,241,211, 66,161, 93,125, 1, 45, 70, 67,242,224, 33, 35,192, 39, 60,152, - 13,186,228,146,194,229,229, 44,198,172, 45, 49, 80, 56, 8,225, 40, 21, 64, 33, 21,162,109,132, 27,170,241, 28,163, 22, 27, 7, -157,209, 6,189,209, 10,131,201, 10,143, 64, 87,172,217,188, 3, 41,217,122,236,187,145,139,216,100, 13, 66, 3,228,160,180,234, -199, 35,103,179,104,251,189, 62,202,145,207, 35,224,243, 8, 47, 34,188, 46,242, 11,205, 16, 9,120, 16, 57, 72, 33,151, 8,224, - 36, 21, 66, 36, 18, 34, 59, 59, 27, 70,163, 17, 65, 65, 65, 14,149, 91, 64, 10, 71,133, 20,161,181,252, 96,182, 88,113,248,252, - 3,204,155, 52, 24,221,218, 55, 3, 17, 42, 16, 99,108, 2, 71, 55, 71,112, 60, 30,204, 86, 14, 38,179, 13, 0,175,194,104, 91, - 80, 80, 80,103,185, 92, 46,215,233,116,154,228,228,228,179, 25, 49,187, 83,188,234, 15, 28,123,244,248,233,205,125,123,117,195, -237,123,209,216,185,103,255,133, 92,119,213,212,146, 99, 34, 35, 35, 91,121,120,120, 40,242,242,242,212,247,239,223,191,254,130, -181, 93, 34,247, 14,255,180,117,219,142, 40, 84,102, 35, 43, 53,209,238, 90,115,189, 96, 71,124, 51,127, 69,211,176,186, 97, 77, -109,180,200,112, 69, 4, 57, 98,202,204,229, 77,107,135,214,109, 90, 50,208,163, 94, 80,229,211,170,201,189,195, 38,204,251,241, -215,183,130, 2, 3,113,228, 82, 12,230, 79, 31,127, 91, 46,115,172, 25,224,237,234, 34,170,223, 12,119,238, 92,134, 23,196,112, -242, 14, 13, 24,209,127, 92, 64,143, 94,253,113,255,238, 77, 44, 93, 56,247,138,150, 47,253,206,158,180, 42,188, 67, 60, 27, 55, -111,255,134,163,155, 55,148, 42, 13, 28, 93,189, 80,175, 97,243, 55, 20,222, 33, 95, 20, 47, 86,255, 98,102,131, 82, 24,205, 20, - 5,133,102,164,230,232,145,148, 89,100,176, 56,174, 26,125,126,108, 28, 81, 56, 8, 4,110,150, 71, 65,247, 79,158,166,193,129, -222,100,225,220,207,248,102, 56, 32, 71, 89,100,174,114,212, 38,228,168, 76, 40, 52, 88,224, 38, 23,128,179,113,213,174,109, 23, - 20,154,225, 88,220, 79,214,198,189,120,159,239, 95,215,111, 11,187, 27,151, 62,240,199, 31,151,202,238, 60, 41, 99,174,132, 69, -209, 43,137,136, 15, 27,199, 21,191,105,170, 48,247, 2,225, 39, 3,122,119, 69,106,174,190,104, 20, 50,143, 32,180, 65, 11,120, - 72, 57,116, 25, 62, 13, 0,208,175,119,209, 52, 36, 79, 50,180, 56,112, 53, 7,120,182,195,118,229,207, 98,189,158,191,122,203, -161, 79,119,108,255,195,217, 96, 19, 96,213,145, 36,232,140, 86, 56,136,248,144,136,248,144,138,248,207,116, 9,170,218, 96, 21, -245,169, 75,201,181, 64,103, 48, 64,173,183,128, 2,184,254,168, 16,122,147, 21, 42,173, 5,173,194, 93,255,106,157,231, 16,128, - 62,207, 27,161,231, 77, 82,153, 8, 84,121,220, 40,171, 81,178,127, 69, 6,174,108,159, 44, 0,118, 85, 4, 5,207, 59,197,178, -127, 59,250,133,214,117,113,241,189,180,255,143, 53,110,187,111, 27,113,230,110, 30,134,180, 11,128, 78,149,137, 5,243, 63,207, - 39,160, 38, 30,159,167, 52, 26,244,187,243,100,230,121,244,193, 99,115,165, 15, 9,207,136,134, 82,153,236,244,247, 75, 87,153, -189,188,253,185,221, 87,149,217, 42,157,237,153, 88,161,205,104,228, 81,142,138,236, 49, 87,197, 77, 27,230,153, 31, 15, 2, 71, - 41,102, 45,221,129,239,166, 14,135, 66, 58, 74, 70, 8,145,105, 13, 86, 76,154,189, 22,139,191,121,207, 81, 38, 17,128, 16,192, - 96,178,225,173, 17,131,236, 43,120, 6, 43, 30, 95,251,189, 80,243,100,239,195,178,205,130, 45,219,246,186,217,178,101, 75,165, -171,171, 43,164, 82,233,127, 34, 19,118, 62,172,203, 27, 45,152,173, 68,154,163,163, 99, 7, 39, 39,167,178,122, 90,165, 82,185, -247, 69, 74,159, 70,153,123, 58, 51,233,126,139, 54,157,250,225,236,177,189,244,234,145,223,198, 84,103,142, 29, 87, 55,215,212, - 91,247, 31,215, 35,196,173, 40,130, 85,108,174, 76, 22, 14,193,222, 50,164, 38, 61,134,139,179,115,170,189,122, 50,175,240, 1, -132, 71,199, 19,208,117,133,153,113, 59,138,205,206, 72,185, 79,248,189,232,168, 59,243,250,190,241,137,160,251,144, 9,252,149, -243, 63,250, 10,207,117, 78,173, 4,115,108,108,236,131,247,222,123,239,181, 43, 87,174,216, 0,232, 8, 33, 22, 62,159, 47, 51, -153, 76,162, 78,157, 58,169, 98, 98, 98,206,193,142,206,136,237,222,221,233, 65, 36,154, 94,181, 67,155,143, 12,118,212,116,235, -212,174, 53, 90,215, 15, 68,106,187,214, 0,240, 73,114,161, 34,172,237, 7,191,109,171,229, 25,112,120,229,250, 3,223,141, 25, -222,117,146, 95,191,217, 63,166, 31,152, 89,105, 7,211,148, 7,103,123,148,103,223, 5,124, 30, 28,165, 66, 40,164, 2, 56, 74, -133,112,116, 16,194, 98,165,213,169, 41, 82,139,149, 43,138, 96,153,172, 40,212, 91,113,250, 78, 22, 50, 85, 38, 40, 53,102,232, -205, 54, 80,208,162,218,167, 29, 79,241,236,248,139, 46,165,215, 62,184,169,106,245, 79,139,156,118, 93, 76, 43, 29,161,231, 44, - 19,195, 81, 86, 52,170,250,252,249,243,112,119,175,186,118,207,113, 28,118, 30,189,142, 31, 55,156,198,209,117,159,195, 65,196, - 71,195, 1,179,241,206,192,150,224, 40,135,199,177,209, 89,161, 17,141,188,121, 60, 41,120,132,192,104,225, 0,208, 10,207,167, -201,100,114, 79, 73, 73, 81,215,169, 83,199,199,223,223,127, 8,159,207,167, 18,192,184,247,143,124,221,169,131, 91,101, 90,189, -209, 38,179,170,214,213,201,208,247, 9, 13, 13, 5, 33,132,122,120,120,136, 78,159, 62, 93,216,160, 65, 3,207, 23, 52, 87, 60, -169, 87,221,101,239,127,240,233,144,218, 33, 33,216,177,117, 29, 40, 37,187,236, 61,126,203,129, 43,152,251,229,179, 35, 6,167, -204, 92,222,116,241,236, 79,158,249,236,131, 47,127,108, 90,217, 51, 35, 32,178,243,231,225,225, 17,184, 18,157,134,133, 95,127, -112,219,144,253,100,164, 73,225, 62,206, 92,152, 49,185,113,147,102,240,113,119, 66,122,190, 17,253, 71, 13, 68,155,182,237,112, -255,238, 77,204,253,230,179, 43,208,153,186,211,156, 7,122,123,210,202, 81,225,248, 78, 61, 6, 10,245, 70, 51,150, 47,156,129, -113, 83,231,161, 85,231,126,194,168, 59, 87,199, 3,152, 99,111,158,141,102, 27, 58, 53,240, 40, 50,205, 22, 14,251,159,240, 5, -229,149, 64, 1,159,240, 26,135,184, 64,111,178, 66,173,179, 84,254,162, 18, 9, 51,149, 42,117,141,159,191,251,148,175, 53, 88, -145,163, 50, 33, 91,101, 68,174,242, 63,198, 42, 87,101, 68,142,202, 4,161,128, 32, 46, 33, 25, 60,161,160,218,253,239, 10, 10, - 45,104, 81,215,181,232, 30,125,193,214, 16,139,192,169,229,209,115,119, 7,255,248,227, 18,135,187,137, 26,220,123,162, 46,142, - 92,241, 33, 17,242, 32, 46,254,221,198, 1, 85,125,133,179, 87,237, 90,111,191, 55,166,139,147, 66,138,244,248,108, 8,248, 69, - 83,189, 56,123, 5,194, 89, 98,192, 71, 31,140,133,135,187, 11, 82,114,141, 88,182, 39, 14,247, 30, 60, 2,167,175, 94,182,151, -175,250,163,231,251, 31, 78,113,225, 9,197,216,116, 44,177, 40,157,124, 27, 98,174, 30, 48,164, 63,190,175, 45, 84,231, 81, 80, -155,157, 21,127, 66,173,182, 34, 99,250,221,172,105,248, 99,195, 47, 56,118, 43,187,180,115,214,197, 93,139,241,233,151,223, 34, - 87,109, 42, 46,250,149, 71,174,158,251, 59,167, 76,228,233, 79,127,151, 49, 69,229,253, 77,138,255, 54, 85,160, 97,122,206, 84, -153,158,251,220,244,156,158, 93,115,247, 9, 42,139, 92, 57,187,250, 92,218,183,109,181,219,238, 91, 38,156,189, 87,100,174,172, - 70, 37,126, 93,248,101,134, 78,169,110, 95,217,132,141,127, 50, 87, 94,117, 35, 37,114,249,185,175,191, 93,102,244,246,175, 97, - 61,124, 71,157,167, 49,216,254, 20, 6, 17,201,228, 54,185,179,167,193, 37,184,201,143, 66,189,105, 70, 78,206, 3,109, 85,145, - 38,142, 82, 28,188,150, 9, 74,139,170, 68,219,207, 63, 69,113, 77, 28, 54,174,168,249,228,196,157,108, 8,138,251,153,216, 27, -230,254,117,213, 47,234, 62, 17,201,218, 55,102,253,167, 89,176, 85,163,162,200,149,147,147, 19, 92, 92, 92,160, 80, 40, 96, 79, - 19, 97, 9, 21,141, 22,116,116,116,236,112,231,206, 29, 7, 39, 39, 39,240,249,124, 24,141, 70,212,175, 95,255,133,110,112,133, - 79,248,135, 45, 58, 15,250,170,109,231,126, 56,125,116, 55,189,122,116,253,216,234, 78, 96,216,167,235,107, 7,230,206,157, 85, -235,235,121, 63, 75, 28, 29, 4,120, 88,104, 2,143, 16, 4,123,203,224, 46,231,225,236,222, 77,134,225,253, 94,179,123, 82,187, -192, 64,255,205,139,127, 90, 45, 95,188, 96,118, 39, 71,255,176,211,154,167,177,249, 0,160,205,140, 89, 40,243, 9,127, 16,112, -249,248,225, 70, 29, 6,193,219, 47,164, 91, 53,194,188,148, 16,162, 75, 72, 72,120,242,245,215, 95,135, 45, 88,176,128,242,249, -124, 14,128,100,233,210,165,186,248,248,248, 59, 40, 26, 98,139,170,162, 87, 93,186,213,159,164, 16,219, 90,185,201,120,245, 67, -124,100,104, 93,191,168,245,115,120,159,182, 8, 12, 10, 66, 66,166,174,113,190,142, 19, 22,154,248, 33, 43, 86,221,187, 81,211, -131, 63,198,170, 55, 61, 64, 21,147,192, 86, 84,102, 75, 58,190,151, 68,175, 28,165, 66,112, 64,117,106,138,212, 98,229, 96, 52, -219,160, 55,218,160, 55, 89,161, 53,217,160, 51,217,192,209,162,123,130, 16, 2,179,149,131, 93,213,228,231,202,190,147,155, 7, - 66,106, 22,141,122,117,148, 22, 77,217,224, 36, 19, 22,141,117,118,119,135,151,151,151, 93, 81, 80,147,185,232, 22, 55, 89,184, -210,230,123,147,217, 10, 74, 41,226,226, 98, 63, 79,122,242,100, 64,157,208, 58,237, 35, 26, 54,114,147, 73,120, 0, 80,161, 25, -208,233,116, 54, 71, 71, 71, 47, 55, 55, 55,222,211,167, 79, 75, 77,115,157,198,157,172,123,118,239,194,224,193,131, 10, 31, 94, -191, 91, 58, 84, 93,175,215,147, 54,109,218, 56, 5, 6, 6,242,140, 70,163,186,122,231,128, 16,185,103,221,129,129,225,175,205, -123,107,244,184,186,157,186,246,196,153, 83,199,177,111,247,239, 27,181,217,177,199,237,190,223,195,194,255, 52,138,176,118,104, -221, 63,141, 34,172, 81, 43,180, 66,131,229,236,220,208,169, 97,243,142,129, 73,185,102, 28, 57,114, 24, 90, 85,230, 55, 38, 83, -161, 14, 66,186,246,224,239, 43,222,123,255,211,217, 78, 29, 59,180,131,171,147, 12, 2, 1, 31,183,110, 92,193,130, 57, 95, 93, -129,206,212,189,170,231,103,105,126, 35, 34, 68,117,130,106, 76, 12,170, 29,137, 91, 87, 47,224,113, 92, 84,244,221, 27, 87,234, -215,105,208, 10,158,126,193, 19, 73, 68,196, 2,250,224,129,185, 42, 29,147,193,144,252,206,219,111,162,236, 40,194,214, 77,194, -220,201,243, 55, 0, 0,157, 38,219,252,219,162, 73,241, 37,163, 8, 57,179, 41,185, 34, 93, 85, 65,206,206,179,151,174, 77, 29, -208,167, 39, 47, 87,109, 42,138, 88,169, 76,197,155, 17,185, 37,191,171,141, 8,245, 83, 32, 54,250, 22,103, 80,229,238,170,230, -125,105,120,103,104,143, 7, 37,101,151,227, 40, 8, 96,168,238,253, 77,133, 78, 99, 23,254,240,163,195,221, 39,133,184,151,168, - 46,106, 18, 20,242,139,140,149,144, 87,106,182,138, 70,167, 87, 17, 13, 34,252,239,222,125,123, 4,114,213,102,112, 28, 32,224, -243,138, 55, 17, 82, 52, 4,169, 26, 29,114, 11,114,240, 36, 41, 25,202,204,199,224,241,120,240,240,171, 11,123,195,141, 54, 42, -246,213,153,104,131, 33,125,218, 11,118, 95,206,128, 76, 34,128, 81,147,133, 35,219, 22,229, 24, 11,213,243,244,186,194,221,250, -188,248,116,123,243,206, 35, 36, 71, 93,104,240,150, 8,249,216,177,225,103, 12,125,231,131,226,147, 82,244,227,243,233,115, 1, - 30, 65,126,129, 6,132,144,234, 70, 69,111, 84,241,247,139,240, 50, 52,170,111,176,100, 50,247,147,251,254, 88,237,118,249, 9, - 15,215, 99, 11, 48,164, 93, 0, 44,134, 2, 44,251,118,114,166, 90,157,221, 89,147, 19,159, 80,173,111,226,241,122, 12,127,119, -106,116, 72,221, 8,227,153,168,194, 68,165,214, 82, 97, 63,134,214, 67,190,142,190,121,232,167,222, 42, 75,194, 4,133, 95,125, - 27,103,181, 46,212,101,199,206,174,160,137, 80, 60,123,217,142,210,230,193, 47, 22,108, 42,250,221,102,131,141,114,160, 28,240, -209, 55,191,194,202,217,192,217,108,224,108, 20, 22, 27,149, 85,149, 92, 47,191, 26,187, 11, 30,254, 30,254,198,215,127,110, 22, -116,113,113,129,187,187, 59,220,221,221, 81, 98,136,254,106,179,160,147,147, 19, 20, 10, 5, 46, 92,184, 0,169, 84, 10,185, 92, - 94, 45,221, 50,230,106, 66,243,142, 3,126,238,220,255, 61,156,216,189,138,222, 56,127, 96,156, 46, 43,118,173,221,145,120,155, -141, 88, 44, 22,244,233,222, 49,249,118,244,163,163,211,167,142,239,249, 90,223,113,146,214, 97,254, 48,152,108, 72, 75,122,140, -179,123,215, 27,234,214,242, 61,214,165, 93,203,100,139,197, 2,155,205, 86,229, 11,220, 96, 50,231,242,133, 82,249,136, 17,111, - 8,111, 92,191,190, 75,225, 85,119,135,141,240,238, 18,202, 53, 36,132, 12,110,216,176, 30,204, 22, 14, 58,157,186,160,186,121, -214,104, 52, 79,214,173, 91, 87,235,237,183,223,150, 69, 68, 68, 8, 31, 63,126,140,197,139, 23,231,105, 52,154, 39,246,106, 28, - 63, 31,187, 84, 64, 10,226,197,156,121,100,176,163,166, 91, 74,219,214, 24,209,183, 45,254, 56,116, 17,103, 47, 92, 65,114,161, -226, 78,161, 85,176, 55, 53, 57,221, 88,223, 77,189,171,127,235, 26,252, 29, 27, 10,118,121,117,250,114, 24,165,146,227, 57,103, -103,106,237,127,121, 3, 26,189, 5, 78,178,162,249,154, 74, 34, 89,124, 66,236,118, 66, 4,120,114,225,202,173,200,102,161, 17, -184,253, 68,133,108,165, 17,122,163, 21, 28, 71,193,129,194,221, 81, 12, 7, 17, 15, 41, 73, 79,192, 81,115, 98, 53, 95, 17, 57, - 29,218,119, 16, 0, 4,132, 80,129, 80, 32, 0, 69,209,188,136, 82,169,180,208,203,203,203,174, 8,150,217,106,197,224,158, 45, -209,170,121, 67, 12, 24,183, 8, 0,112,106,227, 52,184, 42,132,248, 99,243, 90,164,156, 91,178, 57,228,181, 15,142, 71,221,143, -126, 61,250,246,229, 55,122, 53,149, 54,246, 17,164,139, 42,210, 43, 44, 44,220, 69, 8, 17,139, 68,162,158,237,219,183,119,219, -181,107,151,210,195,195,131, 19,139, 68, 57,253,251,245,229,132, 34, 81,126,201,190,151, 46, 93, 18,142, 27, 55,206,177,160,160, - 32, 37, 43, 43,235, 10,165,212, 82,121, 5, 48,188, 43,120,248, 29,132, 56, 40,164,178,228,214, 93, 71,248, 53,111,213,210,121, -224,224,161,144,136, 37, 56,113,252, 40,150, 47, 89,176,189, 48,227,225,187,213, 57,147, 47, 99, 20,161, 74,229,172,141,127,112, -183, 32, 49,219,228, 42,116, 9,133, 80,226, 56,142, 56,251, 45,227, 75, 20, 51, 61, 27, 13,116,218,185,255, 48,238, 71, 69,193, - 77,106, 65,194,227,120, 93,212,157,219,191,232,136,112, 54,205,121,160,179, 55,157,178, 60,219,235,173,223,236,233,106, 52,219, -112,254,244, 33, 3,103,229,122, 94, 57,119,248,113, 64,221,230, 14,145,205,187,184,230,238, 91, 59, 24,192, 31, 85,233,164, 61, -252,115,196, 54, 40,172, 69,226,169,211, 39,157,189,131,235,243, 9, 8,204, 70, 3,114, 18,110, 88,117, 89, 49,106, 85,218,125, -187, 70,213,230,165,226,155, 47,103,126, 63,161,121,179,102,114, 10,135,103, 34, 86, 37,198, 42, 87,109,130,135,163, 24,122,117, - 14,226,111, 28, 53,232,114,248,149,206, 87,102, 53,105,101,185,217, 89,165, 77,105,133, 89,177,173, 42,219, 63, 55, 59, 75,108, - 53,105,101, 85,191,234,248,112,146,139,113, 63,241,105,105,135,118,137,176,168,239,149, 88,200, 47,237,135, 85,242, 44,168,130, -142, 34, 7, 23, 60,205, 51,128,128,130,179, 89, 97,181,152,160, 81,171,241, 52, 61, 19, 89,153, 89,208,104,148,144, 41, 92, 17, -217,184, 5, 28,229, 14,184,123,118, 59, 40,165,118,205, 75,104, 33,194,176,230,173,218, 73,162,146,138,250, 90, 57, 8, 41, 14, -252,190, 32,175, 80,157,221, 78,147, 30, 23, 95,221,103,177,213,102, 59,121,239, 65,124,253, 0,223,154,228,206, 99, 21, 54,175, -249, 9,166,226, 72,166,197, 98, 67, 84,138, 22, 25,249, 58,164, 36, 60,164,156,205,118, 18,175, 56, 21, 26, 44,145, 88, 40,117, -114,243,195,220,145,163,240,203, 47,191, 34, 49,245, 41,150,207,157,148,169,214,228,116,210,164,199,199,217, 89, 11,236, 90, 50, - 87,134, 54, 51,102,225,187,191, 36,166,237,191,157,207,211,155,104,165, 29,120, 28, 60,131,209,238,221,197,199,244,154,124,177, -205,168, 19, 28,216,252,238,239,229,105, 22, 57,102,152,230, 77, 25, 14,133, 84, 0, 66, 8, 74,154, 5, 87,204, 29, 11,153,164, -168,237, 88,111,180, 98,212,164, 31,177,249,199,201,160, 0, 70, 14,189,168,171, 40,157,101,154,240, 2,146,147, 11,158,118,125, -125,241, 41,131, 89,110,236, 59,232,237,155,205,154, 53, 83, 74,165, 82, 72,165, 82, 56, 57, 57,193,213,213, 21, 46, 46, 46, 85, -230,189,194, 73, 68,203,140, 22,228,241,120,224,241,120,144,203,229, 80, 40, 20,144,203,229,149,106, 86,104,174, 58,244, 95,209, -101,192,251, 56,177,123, 53,189,113,254,192,120, 93, 86,236, 26,123,175, 81,113,179,206,221,193,131, 7, 55, 24, 55,110,156,104, -230,212,113,199, 14, 29, 63, 27,183,227,224,234,126, 5, 5,202, 64, 74, 41, 92,156,157, 83,135,247,123,237, 64,167, 54,205,147, - 79,157, 58,197,253,254,251,239, 70, 66,200,253,170,210,153,155,157,189,241,212,201,211,179,218,117,232,136,181, 27,126,239, 16, -253,224, 97,135,199,143,227, 17, 24, 28,130,154,181, 66,161, 35,174, 56,125,238, 2, 10,149,217, 27,237, 73,231,115, 81, 44, 82, - 80, 80,112,121,248,240,225,221, 47, 94,188,200, 27, 62,124,184, 46, 55, 55,247, 82, 73,189,169,162,232, 85, 89,205,203,191, 14, -204, 1,176,177, 70,199,209,219,159,154,149, 19, 1, 44, 8, 10, 14,194,217, 11, 87,112,229,226,181, 95,115,101, 65,179,223, 29, - 53,122,108,141,254,252,247,251,183,174,193,247,114,149, 97,235,234,197,252,253, 87,146,126, 76,202,179,173, 5, 48,215,158,107, - 84,250,194,208,152,209,166,158, 27, 44, 54, 10,142, 22, 61,104, 29, 29,132,229, 62,112,203,211, 20,152, 36,239,142, 31, 55,238, -113,100,195,198,159,142, 26, 61, 94,212, 56, 36, 16,215, 31, 41, 1, 66,224,230, 35, 71, 70, 70, 6,206,239, 92,109, 45,120, 26, -243, 43,159,207,205,169, 78, 89,202, 79,186, 93,167,204,126, 99,115,115,115,113,246,236, 89,148, 24, 43, 79, 79,207,114, 13,214, -243,154,121, 89,233,151,230,254,176,170,205,152,183, 6,161,111,199,250, 56,119,227, 49, 76,197,243, 45,149, 12, 9,127,114,101, -165,120,226,240, 16,211,132,193,117,213,122,139, 56,233,155, 68,213,249,178,163, 92,159,215,164,148,154, 8, 33,251, 99, 99, 99, -219, 54,106,212,168,198,225,195,135,243,163,175, 29,251,164,108, 58,166, 76,153,162,248,229,151, 95,100,148,210, 75, 70,163, 49, -193,174,188,243,176,245,214,205,155,238,102, 11,135, 11,215,238,214,235,210,166, 49, 56, 10,220,184,113, 3,107,127, 91,107,184, -127,239,206, 34,109,150,207,156,138, 6,136, 84,116, 62,109,127, 97, 20, 97,137, 38,165,103,173, 10,239,240, 95, 47, 93, 56, 55, - 93,226,215, 12,225,189,191,234,255,244,238,254,254, 62, 17, 61,224, 17,242, 26,210,239,237,199,165, 99, 91, 14,115, 86,235, 52, - 7,142,151,172,205,137,209,218,123,191,151, 32,145,202, 62,142,104,218, 1, 41,201, 73, 72,140,143,218,168,207,139, 79, 87,248, -132,111, 76, 79, 75, 30, 95,171,126, 27, 92, 60,246,199, 39, 21, 25,172,170,202,124,160,167,116,245,225,131,251, 71,164,165,173, -244,209,234, 13, 18, 74,169, 65, 34, 22,100, 42,120,154,109,246,166,147,210, 7,102,185, 91,205,193, 67, 71,141, 63,180,124,249, - 18,161,183,139, 12,153, 5, 6,168,245,102,104,116,102,240, 8, 65, 29, 63, 57,116,154,124,156,219,249,131,197, 84, 88, 48,156, -210, 71,230,138, 52,139,214, 19,164, 31, 77,249,224, 12,196,206,129,126,181,186,124, 85,105,116, 78,147,126,175,223,148, 15, 14, -132, 81, 74,187, 40,188,195, 53,133, 89, 49, 95, 87,148,119, 66,138,238,239, 55, 58, 5,194,108, 45,154, 63,204,202, 1, 54,142, - 43,142,234, 1,180,180,221,158, 84,145,119,194,109, 59,116, 9,233, 89, 74,232, 77, 22, 24, 77, 86,152, 45, 54,240,248,124,184, -184,186, 32,180,102, 19, 56,187, 56, 33, 43, 51, 29, 87, 78,237, 71,220,189,115,151, 8,197,108, 93,118,220, 41,123,174,145, 72, -234, 18,230,235,231,195,203, 80,155, 32, 21,243,113,231,220, 97,179,197,100, 92,100,143,185, 42, 79, 83,153,151,255,227,167, 83, - 63, 27,185,126,221, 6,159, 6,181,156,144,150,171, 71, 90,142, 1, 26,131,165,216,128,113, 48, 22,230,226,222,233, 13,153, 54, -131,230,199,127,173,193,226,172, 54, 83,236,163, 4, 76,155,253, 3, 18,146,146,177,124,254,103, 89,133,213, 48, 87,229,177,110, - 66,205, 63,170,119, 68,241,148, 36,115,146, 42,175,111, 63,223, 44, 72, 57,112,148,226,192,181,204,210,102, 65,174,184, 71,229, -237,199,202,106, 53,225,221,139,213,111,209,235,243,156, 99, 30, 45, 42, 0, 0, 62,159, 95,186,149,244,149, 50, 24, 12,166, 23, -105, 22,124,190, 67, 59,199,113,112,114,114,130, 84, 42,173,118,211,163,220, 59,108, 68,243,142, 3,126,238, 50,112, 12, 78,238, - 89, 67,111,156,219,255,129, 46, 59,118,117,181,251, 32, 20, 20, 68, 19, 66,226, 23, 45, 90,212,120,237,218,181,181,166, 78,157, -154,176,233,231, 89,203, 1, 32, 47, 47, 15, 0,112,251,246,109,250,193, 7, 31, 24, 13, 6,195,147,130,130,130, 91,148,210, 42, -155, 14,244, 57,178,239,214,174, 88, 16,153,250, 52, 99, 80, 72,100, 11,120,214,106, 1,159, 58, 45, 81,160, 49,227,250,163,116, - 36, 60, 60,133,135, 23,118, 30,214, 41,172,179,170,155,230, 70,141, 26, 5,242,120,188,154,133,133,133, 62, 17, 17, 17,141,228, -114,249,237, 70,141, 26, 53, 17, 8, 4,105, 55,111,222, 76,170,142, 86,210,217,245,198, 26, 29, 71, 47, 75,214, 56,118, 74,200, -212, 53, 73,214, 56,222,214, 73,156, 39,103,159, 90,106,244,238,190,232, 71,106,206,141,222,177, 65,189,107,235,234,197,252, 81, - 99,167,216,162, 84,174, 19, 5, 82,241,137,249,239, 52,168, 70,243, 19, 47, 99,194,219, 3,254, 51, 77, 67,113,228,170,248,119, -187,194,241, 74,229, 93, 21,128, 47,164,126,245,127,142,154, 56,110,110,195,230,109,222,108,223,107, 56,207, 42, 82,224,216,158, -149,244,201,189,211, 59, 4,212, 54, 93,103,199,236,253, 85, 54,251,152, 76, 85,154,171,114, 35, 47,169,242,142, 59,126,255,237, -157, 93,123,118,207, 31,216,127,128,251,138,111,134,225,135, 85,123, 33,151, 74, 64, 57, 14,195, 59, 7, 13,121,248,123,143,126, -129,222, 14,254,187,206,164,157,255,104, 73,212, 23, 58,157, 57,174,170, 81,174,197,134,249,130,163,163, 99, 78,219,182,109, 91, - 73, 36, 18,146,155,155, 43,240,242,242,178, 58, 59, 59,155,210,210,210,116, 70,163,113, 23,165, 84, 91,157,124,154, 45, 28, 18, -179, 12,216,183,123, 23,238, 94, 59,133,135, 15, 99, 53, 15, 31, 60,252,137, 8,232,146,194,204,184,252, 23, 57,119, 92,185,163, - 8,105,181, 71, 17,106,249,210,239,110, 31,252,161, 99,104,231, 79, 90,187,215,110, 3,215,224,162, 49, 58,170,180, 40,164,222, -216,177, 79,147, 46, 26, 74,105,148,229, 69,175,177, 95, 64,173, 80,202, 23,227,242,217, 67,160, 28,247, 43, 0, 80,142,251,245, -246,197,195,227, 91,246,126, 31,110, 94, 53, 26,149,140,157,175,174,182, 72,192,211, 30,217,181,126, 79, 98, 98, 34, 98, 98, 98, -240,232,209, 35,228,231,231, 99,235,214,196,106, 93, 31,109,126,226, 9,133,123, 72,143,215,135,189,113, 96,200,136,183, 28,106, -133, 54,224,133, 5,184,194, 93, 33, 64,236,163, 36,196,221,188,199,197, 94, 63,108, 48,171,179, 7,234,242, 19, 43, 52,124,114, -207, 8,111,194,163,211, 74,214, 22,108,221,186, 77,216,103,243,230,183,114,247,244, 42,247, 57,158,151,147, 45,254,252,163,253, - 97, 87,174, 94,182,107, 45, 66,206,102,203, 27,251,206,112,142, 95,180,144, 39, 74,227,210,164,232, 98, 23, 85,162,138, 62,167, -156,181,202,136,253,232, 65,237, 96,229, 56,104,245,102,168,181, 70,168, 52, 6,100,100,231,225,238,189,123, 56,119, 96, 63, 30, -199,222,125, 98, 49,153,142,243,120,100,167, 46, 51,246, 92,245, 90,150, 4,181,220,221,220,240, 36,191, 16, 14, 98, 1,146,226, -110, 26,181,106,213,150, 23, 45, 71,186,220,184, 12,185,119, 88,247,225,195, 71, 28,237,220,163,191,115,243,215,186,202, 60,156, - 92, 32, 18, 80,196, 39,166,227,214,165,163,218,132,187,231,213, 22, 83, 97,207,151,177, 74,203,255,172,193, 82,107,114, 58,189, -247,238,184, 99, 60, 1, 95, 2,202, 25,116,186,130,158,127,197, 92,253, 93, 80,106, 75,123,103,228,160,103,234, 2, 86,142, 74, - 71, 14, 61,166, 47, 91, 55,176,216,168,108,228,208, 75,186,162, 7, 71,197, 29,246, 74,155,240,118, 92, 77, 75, 78, 85,222,200, -207, 55,158,249,171, 35,251,202,174, 45, 88,201,104, 65,109,120,120,120,169,169,226,243,249,176,217,108,118, 63,128, 68, 18,233, -152,206,253,223, 35, 39,247,174,161,215,207,238,157,160,203,142, 91,245,226,231,148,154, 1, 92, 35,132, 68, 77,159, 62,189,185, -183,183,183,247,140, 25, 51, 28,212,106,181,112,197,138, 21,134,220,220,220, 76,181, 90,125,133, 82,170,183, 95,243,150, 5,192, - 96,133,119,221, 78,116,215,154,110, 46, 30,254,221,157, 61, 3,106, 43,115,158, 62, 81,229,164, 31, 7,112,178,120,130,199,106, -209,164, 73,147, 16, 30,143, 55, 28, 64,164, 92, 46,175,163, 80, 40, 36,148,210,112, 66, 72, 52,199,113,247, 34, 34, 34, 14, 2, -168,214,245, 75, 58,187,222,216,126,194,111,191,231,235, 56,145,137, 39,250, 61,233,236,122, 35, 0,100, 29,159,170, 3,176,207, -187,211,180,193,251,175, 36, 45,143, 46,112,254, 36,251,204,119,251,171,155,102,101,234,157, 58, 47,171,252,235,211,163,211, 0, -188, 35,247, 14, 91,124,255,246,149,153,132, 66,104,131,245, 91, 93, 86,252,205,151,161, 47, 20, 10, 13,254,254,254,229,142, 22, -148, 72, 36,134,202,175,249, 89, 43,128,181,132,116,220,176,123,251,134,119,246,238,223, 55,191,125,151,129,238, 14, 1, 1,168, -233, 69,176, 97, 90,211, 79, 78,221,206,185,222,255,179,243,191, 36,164, 27,238, 81, 74,171,213,223, 69,163,209,196, 17, 66, 10, - 10, 11, 11, 7, 80, 74, 83, 9, 33,129, 5, 5, 5,119, 44, 22,203,253,106, 27, 1, 14,111,180,110,221, 98, 43, 33, 68, 64,173, -220,194, 43, 66,254,239,134,140,135,105, 47, 98, 40,202,210,160,166, 19, 38,205, 88,214,180,118,157,186, 77, 75,214, 34,172, 95, -195, 17,227,190, 88,220,180, 70,173,208,166,255, 89,159,176,242, 81,132, 52,253,150,158,120, 55,232, 22,123,124,209, 55,238,143, - 47, 77,144,186, 5, 40,180,185, 73,249, 5, 73, 55, 23,233,178,189, 23,189,200,196,146,101, 73,124, 20,189,100,237,162, 47,166, -102, 60,125,178, 86,155, 29, 23, 5, 0,218,236,184, 40,153,119,221,111,114, 51,211,166,230,101, 39, 44,122,209,115,161,213,106, -211,183,108,217,226,210,166, 77, 27,158,183,183, 55,114,114,114,112,230,204, 25,142,227,184,167,213,213, 42,204, 75, 56, 67, 72, -109,183,141,171,126, 94, 40,146, 59,246,182, 90,173,126,148, 2, 2,129, 32,195,164, 83, 31,213,240,228,159,209,252,196, 42,202, - 37, 71, 0,240, 74,214, 22,228, 56,142, 44, 92,190, 33, 73,232,224, 88,110,147,170,197,160,145,113, 28,103,247, 90,132, 5,201, - 55,107,191,172,251,155, 80, 58,187, 81,179, 86, 95, 89, 44,102, 3,138,250,131, 25, 0, 24, 40, 69, 30,143, 71,206,241, 57,203, - 49,213, 95,168, 68, 17, 2, 39, 74, 4,112,148, 10, 64, 64, 80,168,202,167,213,233,115, 85,238,245,206,138,141, 38,164, 99,240, - 17,211,246,183, 79,159, 56, 60,212,102,179,213, 44, 46, 57,137, 70,189,118, 71, 97,134,235, 70, 74,111, 88,241, 47, 64, 80,113, - 72, 52, 62, 14, 64,240, 63, 61, 3,121, 79,174, 55,123,153,122, 25,217,170, 13, 61,134, 45,166,137, 73, 5,215, 83, 50,141, 27, -203, 46,127,243, 87, 53, 83, 83,149,103,138,155, 5,141,127,142, 72,188,216,104,193,210,218,183, 65,255,253,210,233, 35, 96,208, -107, 55,233,178,227, 54,188, 28,243, 74,245, 0,206, 17, 66,156, 39, 76,152,208, 68,161, 80, 8,115,115,115,175, 81, 74, 85, 47, -170, 89,152, 21,119, 6,192, 25, 0,211, 94, 70, 26,111,223,190,157,208,184,113,227,205, 60, 30,175, 38,165,212,155, 82,234, 92, -108, 96,115, 5, 2,193,211, 7, 15, 30, 60,125,161,188, 27, 29,143, 20,154,248,161, 86,234,122,244, 79,166,195,221,235, 68,114, -190,109, 13, 95,238,240,143,233, 67,160,205,138,141, 6,240,250,203,214,173,108,158, 43,251,203,209,127,140,214,217, 67,235,223, -225,137,157,191,237, 18,102,208,117,255,244,233,220, 11,247,115,174, 81, 74, 53,127,161,140,230,136,197, 98, 61, 33, 36, 80, 36, - 18,233, 77, 38,211,189, 23, 58,127, 69,230,222,243,101,158, 59, 14,228,102,211,166,205,170,181,127,165,121,205,186,175, 3, 48, -141, 68, 68,204,144, 61,190,225,170,203,245,200,163, 52,246,165,188,168, 10, 51, 99,230,162,184,153,251,153,136, 68, 86,220,183, - 0,190,253, 43,218, 55,110,220, 56,176,104,209, 34,213,242,229,203,131,108, 54,155,204,100, 50,233,244,122,125, 98, 90, 90,218, -229, 23,187,230,143, 77, 0, 38, 22,111, 47, 16,101,137,201, 84,120,215, 93,246, 90,235,215, 38, 22, 85,204,233,178,196,115,203, - 38, 85,118,140,194,187,174,190,236,254,149,173, 69,248, 50, 41,204,142,251, 21,192,175,127, 95,132,130,203,121, 99,200, 0,160, -120, 66,109,206,106,205,121, 41,178, 69,247,252,111,120,129,197,203, 95, 41,104,241,242, 8,127,199, 6,160, 43,211,100,154, 76, -147,105,150,179, 47,143,157, 79,166,249,223,212,116,240,173, 23,232,224, 91, 47,208,222,227,203,219,159,157, 79, 10,182, 85,188, - 9,192, 96, 48, 24,255,255, 21, 59,142,157, 5,198,127, 19,125,250,131,212,191,115,127, 6,131,160,104, 85,234,242, 30,128,118, - 55,127, 16, 66,186,190,192, 3,246, 36,211,100,154, 76,147,105, 50, 77,166,201, 52,255, 93,154, 85,105, 87,199,127,252,211,107, -146,172,137,144,105, 50, 77,166,201, 52,153, 38,211,100,154,172,137,240, 37,110, 60, 48, 24, 12, 6,131,193, 96, 48, 94, 42,204, - 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131, -193, 96, 48, 24,140, 23,135, 80, 74, 81,188,196, 20, 1,240,204,239, 12, 6,131,193, 96, 48, 24,255, 47,134,228, 21,243, 34,165, - 6, 11, 0, 40,165,132, 25, 44, 6,131,193, 96, 48, 24,255, 13,131,245, 42,121,145,103, 34, 88,101, 51,199, 46, 53,131,193, 96, - 48, 24,140,255, 79,131,245, 42,121, 17,214, 68,200, 96, 48, 24, 12, 6,227, 31, 99,176, 94, 21, 47,194, 58,185, 51, 24, 12, 6, -131,193, 96,188,108,195, 88, 60,229, 61,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6, -131,193, 96, 48,254, 21,252,173,125,176, 8, 33, 93,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 52,153,193, 98, 48, 24, 12, - 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24, - 12,102,176, 24, 12, 6,131,193, 96, 48,254, 75, 16, 0,229,142, 4,160,148,158,180, 91,228, 5, 70, 19, 84,165,207, 52,153, 38, -211,100,154, 76,147,105, 50,205, 87, 79,179, 42,237,234,248,143,127, 52,148,210,191,109, 3,208,149,105, 50, 77,166,201, 52,153, - 38,211,100,154, 76,243,223,182,177, 38, 66, 6,131,193, 96, 48, 24,140,151, 12, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, - 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,227,197, 33,197,163, 1, 64, - 8,161,148, 82,194, 78, 9,131,193, 96, 48, 24,140,255,138, 41,121,133,188, 8,161,148,150,102,136,153, 44, 6,131,193, 96, 48, - 24,255, 77,115,245,170,120, 17,214, 68,200, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12,198, 63, 27,214, 7,139, -193, 96, 48, 24, 12,198, 63,195,148,188,106,125,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131, -197, 96, 48, 24, 12, 6,131,241,111,225,111,237,228, 78, 8,233,202, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 12, 22, -131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, - 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,241, 95,130, 0, 40,119, 36, 0,165,244,164,221, 34, 47, 48,154,160, 42,125, -166,201, 52,153, 38,211,100,154, 76,147,105,190,122,154, 85,105, 87,199,127,252,163,161,148,254,109, 27,128,174, 76,147,105, 50, - 77,166,201, 52,153, 38,211,100,154,255,182,141, 53, 17, 50, 24, 12, 6,131,193, 96,188,100,152,193, 98, 48, 24, 12, 6,131,193, - 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48, 24, 47, 14,161, -148,130, 16, 66,139,255,238, 72, 41, 61,199, 78, 11,131,193, 96, 48, 24,140,255, 87, 67,242,138,121,145, 82,131, 69, 41, 37, 37, - 63,217,101,102, 48, 24, 12, 6,131,241,255,109,176, 94, 37, 47,194,123,206, 57,118,100,151,152,193, 96, 48, 24, 12,198,127,203, -100,189, 42, 94,228,153, 8, 22,187,180, 12, 6,131,193, 96, 48,254, 91,230,234, 85,242, 34,204, 96, 49, 24, 12, 6,131,193, 96, - 6,235,239, 48, 88, 12, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193,248, -183,240,183, 78, 52, 74, 8,233,202, 52,153, 38,211,100,154, 76,147,105, 50, 77,166,201, 12, 22,131,193, 96, 48, 24, 12, 6,131, - 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 48,131,197, 96, - 48, 24, 12, 6,131,241, 95,130, 0, 40,119, 36, 0,165,244,164,221, 34, 47, 48,154,160, 42,125,166,201, 52,153, 38,211,100,154, - 76,147,105,190,122,154, 85,105, 87,199,127,252,163,161,148,254,109, 27,128,174, 76,147,105, 50, 77,166,201, 52,153, 38,211,100, -154,255,182,141, 53, 17, 50, 24, 12, 6,131,193, 96,188,100,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, - 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48, 24, 47, 14, 41, 30, 13, 0, 66, 8,165,148, 18, -118, 74, 24, 12, 6,131,193, 96,252, 87, 76,201, 43,228, 69, 8,165,180, 52, 67,204,100, 49, 24, 12, 6,131,193,248,111,154,171, - 87,197,139,176, 38, 66, 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,254,217,176, 62, 88, 12, 6,131,193, 96, - 48,254, 25,166,228, 85,235,131,245, 42,102,140,193, 96, 48, 24, 12, 6, 51, 89,255, 8,131,197, 96, 48, 24, 12, 6,131,193, 96, - 6,139,193, 96, 48, 24, 12, 6,227, 31,199,223,218,201,157, 16,210,149,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,147, 25, - 44, 6,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, - 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227,191, 4, 1, 80,238, 72, 0, 74,233, 73,187, 69, 94, 96, 52, 65, 85, -250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,245, 52,171,210,174,142,255,248, 71, 67, 41,253,219, 54, 0, 93,153, 38,211, -100,154, 76,147,105, 50, 77,166,201, 52,255,109, 27,107, 34,100, 48, 24, 12, 6,131,193,120,201, 8,202,251, 80,216,114, 94,150, -213,106,245, 2, 0,129, 64,144,109,185,254,181,111,101, 34, 66,160,139, 21, 88, 83, 44, 56,198, 66,233,137,114, 52, 79, 88,173, - 86,215, 98,205, 2,203,245,175,123, 84,170,217,226,219, 99,207,236,127,109,122,183,114,226,139,124, 97,139,111,211,159, 75,171, - 95, 53,194,119,182,255,143,116,254,175,104,254,155, 17,181,154,151,101,177, 20,149, 35,161, 80,144,109,190, 86,121, 57, 18,181, -252, 54,253,153,253,175, 78,247,174, 76, 83, 38,149,228,213,246,247,252,177, 50,205,132,244,220,201, 90,157,193,189, 50,205,234, -222,155,129,190,190, 93,108,197,247, 38, 31, 24,147,154,158,126,226,159, 84,150, 8, 33,205, 0,124, 13,192,169,204,199,247, 40, -165,159,178, 82,201, 96, 48, 94, 57,131,101,181, 90,189,110,237,153, 9,173, 17,232,242,214,183, 94, 33, 3, 87,109,253,211, 62, -134, 2,177, 50,122, 91, 3,190, 69,237,234, 41, 48, 59,165,167,167,147,226, 7,230, 26, 0, 65,229,104,186,222,218, 51, 19, 58, - 19,208,126,196,108,215, 32,192, 41, 71, 36,154, 34,149,203, 59,233,245,250,250, 0, 32,149, 74,163,245, 90,237, 25, 79,179,121, -241,243,251, 87,148,129,178,105,237,252,230,183, 94,225, 3, 87,125, 98,227, 56,241,211, 27, 43,219, 27,114,227, 5, 66,171,113, -197, 87,192,145,153,128,205,158, 19,242,204,247, 14,253,210, 93, 8,116, 22, 59, 56, 52,114,113,117,109,199, 81, 90,143,227, 56, - 98,179, 90, 31,168, 85,170, 11,156,213,122,215,106,210,186,223,218, 63,159,171, 44,157,207,231,101, 40, 32,216, 3, 12,145, 43, - 20,157,248, 66,225,107, 0, 96,179, 88, 46,107, 11, 11,207, 12, 2,118,218,147,119,123,207,207,139,238,255,111,195, 98,177,122, - 61, 57, 54, 19, 70, 11,208,228,245,249, 94, 13,223,216,184, 21, 0, 76,217,119,189, 11,227,247,183, 4, 0,121,237,190,215, 36, - 62, 77,178, 0, 64,144,156,225, 21,119,112, 58,140, 22,160, 94,223,217, 94, 85,105,142,158,177,221,253,243,177,131, 37, 0,112, -124,215,207,117, 79,239,254,181, 23, 0,116, 30,252,193,145,238,175,127, 20, 7, 0, 11, 87,239,118,255, 99,254,176, 74, 53,237, -187, 55, 85, 34, 85,252,193, 58, 38,117,134, 75,160, 92,224, 19, 31, 31,207, 3, 0, 63, 63, 63,187,238,205, 0,192, 57, 3,248, -144,199,231,183,171, 93,167, 78, 19, 0, 52,225,241,227,219, 54,171,245,162, 47,176,226, 37,151,165, 79, 40,165,253,158, 51, 93, -172, 64, 50, 24,140, 87,211, 96, 1,128,214, 8,156,123, 4,116,104,213, 16, 99,223,232,173, 40,251,191,157,171,102, 7,197,223, -216, 23,254,219,198,197,188,134, 13, 27,226,201,147, 39,118,125,153,206, 4,156,141, 7,160,124,232, 88, 32,151, 63, 94,242,195, - 15, 78,221,186,117, 19,248,249,249,129, 16,130,204,204,204, 86, 39, 79,158,108, 54,105,210,164,241, 80, 62, 44,208,153,160, 57, - 27, 95,181,110, 73, 90,235,215,173,129,175, 63, 26,230, 12, 0, 95,189,181,162,217,141,216, 44,183,199,143, 31,119,249,226,139, - 47,242,248,103,206,252,234, 1,172,207, 2, 82,237, 73,231,166, 3,215, 28,156, 51,126, 15, 25,245,209, 71,187,234,212,169,163, - 8, 14, 14, 38,142,142,142,224,243,249, 40, 40, 40, 8,138,138,138,234,117,253,250,117,237,201,115,107,196, 55,175,247, 79,200, -118,104,105,176, 43,239,250,116,135,227,142,142,209,111, 14, 26, 20, 48,108,216, 48,135,218,181,107, 3, 0, 30, 63,126, 28,186, -115,231,206, 17,187,118,237,154, 1,125,186, 85,103,130,161,170,188,151,106, 2,112, 0, 94,115,241,242, 26,197, 23, 10,235, 91, -173, 86,255,226,232,194, 83,155,197, 18,173,204,206,222,242,252,254,140, 63, 99,180, 0, 15, 51,128,174,237,154,224,205,193, 93, -229, 0,240,197,240,121,173,146, 19, 31,137, 76, 38, 19,234,134,213,107, 51,119,254,143,199,192,227, 97,243,238,147,165,251,219, -163,121,239,225, 19,204,156,187, 4,233,247,119,182,178,169, 30,117,210,168, 85,124, 0,112,114,118, 30,188,115,219,239,103,252, - 26, 12,185,250, 40,215,108,151,102,101,247,230,209,109, 63,249,166, 69,157,137,248,229,248, 58, 97, 80, 80, 16,238,223,191, 95, -189,123, 83, 21,235,200,249,250, 62, 88,252,217,103, 62,237,219,183,135, 66,161,128, 64, 32,128,213,106,237,122,241,226,197,174, - 51,103,206,252, 0,170, 88,173,189,247,166, 29, 44, 38,132,116, 26, 61,246, 19,223,222, 3,134, 96,112,207, 54,172, 32, 50, 24, -140, 87,215, 96, 9, 4,130,236,110,111,127,231,213,174,101, 36,110,220,141, 83, 37,165,100, 20,150,252, 47, 63,122,103,221, 1, -109,252, 35,206,159, 63, 7,163,209,136,203,151, 47,227,238,221,187, 72, 76, 76,196,184,113,227,140, 2, 96, 76, 5,154, 5,237, - 71,204,118,133, 42, 94, 17, 42,142,173,121, 50, 38,134,111, 48, 24,112,254,252,121, 20, 20, 20, 64, 44, 22, 35, 32, 32, 0,221, -187,119, 23,196,196,196,184,117,233,214,211,185,125,207,145, 79,224, 28, 90, 40, 16, 8, 10, 42,204,128, 64,144,221,229,173,111, -189, 34, 66,107,224,113, 82,186,234,235,249,191, 21,114, 28, 21, 36, 36, 38,155,207,157, 59,135, 38, 77,154,224,196,137, 19,238, -249,249,249,223,172, 88,177,226,107,225,247,191, 44,179,152,242,166, 86,162, 87,208,126,196,108, 87,247,236, 29,193,167,143,238, - 21, 69, 71, 71,139, 86,174, 92,137,188,188, 60,136,197, 98,184,184,184,192,199,199, 7,117,235,214, 37, 95,125,245,149,162,111, -223,104,124, 60,102, 72,176, 57,228,253,216,138,210, 89,154,247,194,100,153,135,250,120,237,221,135, 14,241,218,182,109,251, 76, - 53,189, 86,173, 90,232,209,163,135,195,168, 81,163,106, 15, 27,241, 6,215,190,207,232,199, 80, 4,235,170,212,212,166, 74,221, -117, 87,252,186,142, 24,177,127,246,236,217, 46, 62, 62, 62,144,203,229, 0, 0,149, 74, 21,144,148,148,212,106,198,140, 25,175, - 95,187,183, 77,208,190,111,106, 58,228,129,250,202,206,231,191, 21,161, 80,144, 93, 18, 53,114,148, 75, 11, 82,211,178,180, 0, - 96, 50,153, 96, 50,153, 96, 52, 26, 49,225,131,113,252, 49,175,183,168, 19,220,238,147, 59,137, 79,179,242,235,157,188,234, 86, -114,108, 85,154, 2, 93,162, 82,153,114,106,204,204,207, 62,243,241,246,254, 79,203,223,230, 77,155,248,249,249,249, 93,103,206, -156, 25, 65,101, 29,149,245,250,206,118,169, 76,179,178,123, 83, 25,119,168,230,220,143,122, 52, 90, 53,255, 32,108, 54, 27,174, - 92,185,130,243,231,207,227,199, 31,127,164, 71,142, 28, 81, 57,201,229, 85,220,155,177,142,109,125, 51, 67,190,255,126, 23,145, - 72, 36,216,183,111, 31, 98, 98, 98,192,227,241,208,176, 97, 67,188,249,230,155,232,218,181,171,207,216,177,227,104,251,158,195, - 19,224, 28,166,249, 43,101,137, 16,194, 3,240,201,151, 51,191,247,125,235,253, 15,177,112,238, 87,204, 96, 49, 24,140, 87,135, -226,209, 0,180,120,235, 64, 41, 5, 5,120,181, 6,174,250, 99,199, 77,238, 80,173,129,171,254,160, 0,143, 2, 60, 39,160, 70, -227,198,141, 45, 74,165,146, 94,191,126,157, 78,152, 48, 65,187,108,217,178, 51,135, 14, 29,218,105, 53,155,215,250,249,250, 46, -162, 0,175,220, 30,245, 0, 47, 24,112,150,201,100, 57, 41, 41, 41,244,240,225,195,116,214,172, 89,116,203,150, 45,244,200,145, - 35,244,228,201,147,244,200,145, 35,244,143, 63,254,160,247,238,221,163,113,113,113, 84, 46,151,231, 4, 3,206,149,104,242, 41, -192,175, 59,112,229,212, 93, 55, 44,179,195, 6,174,154, 68, 1,190, 43, 16,222,184,113, 99,219,206,157, 59,233,230,205,155,233, -198,141, 27,233,189,123,247,104,110,110, 46, 21, 72,228, 57, 37,199, 85,148, 78, 10,240,252,253,253,115,148, 74, 37, 13, 12, 12, -164, 98,177,152,122,123,123,211,186,117,235,210, 86,173, 90,209, 94,189,122,209, 55,222,120,131,126,243,205, 55, 84,169, 84, 82, - 7, 7,135,172,146,227, 42,210,108, 2, 72,229,114,121,202,173, 91,183,104, 69,232,245,122,154,155,155, 75,143, 29, 59, 70,229, -114,121, 74, 19, 64, 90,153,166, 20,104,218,160, 65,131,156,220,220, 92,106, 54,155,105, 74, 74, 10,141,138,138,162, 49, 49, 49, - 52, 37, 37,133,234,245,250, 82,237,184,184, 56, 26, 18, 18,146, 35, 5,154, 86,168,249,111,222, 74,202,196,115, 91,144,183,119, - 47, 31, 31, 31,253,174, 93,187,232,211,167, 79,233,134, 13, 27, 40, 15,152,247,167,125, 43,209, 20, 3,221,219,182,109,107,187, -114,229, 10,189,115,231, 14,157, 54,109, 26,237,209,163, 7,237,217,179, 39,157, 57,115, 38, 77, 75, 75,163,105,105,105,180, 87, -175, 94, 54, 49,208,189,170,242, 89,222,189,233, 12, 4,245,237,219, 87,111, 54,155,105, 66, 66, 2,173, 95,191,126, 26, 31, 24, - 37, 7, 34, 58, 0,146,170,202,167, 63,224,234,235,235,155,113,229,202, 21,186,123,247,110, 26, 28, 28,156,195, 7, 70, 59, 1, -181,156,128, 90,124, 96,116,173, 90,181,114,174, 92,185, 66,243,242,242,104, 80, 80, 80,134, 63,224,250,162,101, 9, 69,115,240, -173,251,114,230,247, 52, 54, 77, 75,191,156,249, 61, 5,144, 66,139,254,121,130,149, 73,182,177,237,223,183,253,201,139,252,143, -111,130, 50, 70,139, 16, 66, 40,138,230,198, 42, 23, 61,159,255,221,194,133, 11, 5, 6,131, 1,191,253,246,155,102,228,240,225, -187, 93, 92, 92,172, 66,161, 16,132, 87,245,128,196, 28,137,100,226, 15, 11, 23,186,152, 76, 38,220,188,121, 19,205,154, 53,131, - 68, 34,129, 72, 36,130, 80, 40,132, 80, 40,132,175,175, 47,178,179,179, 81,191,126,125,124,254,249,231,206, 11,190,251,110, 34, -140,198,185,149,233,114, 28, 21, 0,128,141,227,196, 34, 96,108,163,230,205, 23,125,245,213, 87, 60, 39, 39, 39, 24, 12, 6, 24, -141, 70,196,196,196,192,221,221, 29, 50,169, 76, 0,163,182,202,180,242,120, 60,158, 66,161,192,233,211,167,177,122,245,106, 36, - 38, 38, 34, 35, 35, 3,142,142,142,168, 95,191, 62,234,213,171,135, 14, 29, 58, 32, 33, 33, 1,196,142, 78, 35, 15, 4,130, 15, - 39,140, 25,227,213,164, 73,147,114,255,111, 48, 24,160, 84, 42,161, 82,169, 16, 16, 16,128, 33, 67,134,120,253,190,121,243,135, -176, 90, 23,151,183,191, 59,224, 19, 16, 26,186,255,250,245,235, 30,148, 82,108,222,188, 25,133,133,133, 48,153, 76,224,241,120, -112,112,112,128,171,171, 43, 58,119,238, 12, 79, 79, 79,132,134,134, 98,251,246,237, 30,189,122,245, 58,232,158,157,221, 52, 15, - 72,103,213,139,170, 73,206,202, 58,222, 29,240, 24,245,198, 27, 71,238,222,187,215,110,212,168, 81,200,202,202,250, 74, 56,109, -154,210, 2, 44,169,234,248, 48,192,217,205,215,119,253,247,223,127,207,203,204,204,196,148, 41, 83,114,211,147,147,167, 57, 3, - 23, 0,224,212,209,163,237,182,108,217,178, 96,243,230,205, 30,155, 54,109,226, 53,105,210,100,125, 88, 74, 74,253, 88, 64, 85, -157,116,106,128, 79,150, 46, 93,234, 96, 48, 24,208,173, 91,183, 4,135,196,196, 70, 86, 64,111,239,241, 25,192,135, 63,126,254, -185,143, 68, 34,193,148, 41, 83,114,117,201,201,145, 86, 32,167,204, 46, 73,158, 79,158, 28,125,235,173,183,162,238,221,187,231, -177,100,201, 18,159,215, 7, 13,250, 16,192,188,106, 68,172,202,118,104, 15, 29, 61,246, 19,239, 38, 45, 90, 99,211,218, 21,152, - 63,251,139,245, 0, 86, 17, 66, 62, 2,240, 3, 43,121, 12,198,191, 54,232, 83,165, 23,249,159,107, 34, 44,206, 80,199,202,118, -118,117,119,111, 22, 25, 25,137,243,231,207,163, 65,131, 6,215, 93, 92, 92,172, 34,137, 4, 66,161, 16,148,227,170,252, 50,169, - 92,222,165,107,215,174,130,171, 87,175, 34, 36, 36, 4, 82,169,180,212, 88,149,108, 34,145, 8,190,190,190, 80,171,213,232,210, -165,139,112,249,242,229, 93,170, 50, 88, 0,144, 28, 31,165,200,185,250,253, 27,107, 54,172,175,213,190,125,123,168, 84,106,112, - 28, 7,153, 76, 6,147,201, 4,129, 64, 80,212,212, 99,161,106,123, 78,140,205,102,179,241,249,124,132,132,132,224,187,239,190, -131,193, 96,128, 72, 36, 2, 0,168,213,106, 40,149, 74, 68, 69, 69, 33, 41, 41, 9,197,181,238, 74,113,116,118,238, 61,108,216, - 48,113,121,255, 51, 26,141, 80,169, 84, 80,169, 84, 80, 42,149, 48, 24, 12,104,221,186,181,248,208,193,131,189,145,151, 87,174, -193, 50, 58, 56,188,190,105,211, 38, 47,177, 88, 12,189, 94, 15,141, 70,131,212,212, 84, 36, 39, 39, 27,178,179,179,173,142,142, -142,188,224,224, 96,158, 68, 34,145, 12, 28, 56,144,168,213,106, 16, 66,208,183,111, 95,247,173,155, 55, 15, 3,240, 35,187,149, -237,227, 56, 96,108,106, 50,245,107,217,162,197,233,235, 55,110, 52,153, 56,113, 34,238,221,187,247,189,108,219,182,115, 58,224, -110,101,199, 38, 0, 31, 46, 42, 99, 92,104,114,114, 3,243,115,198, 37,184,200,184,220, 47, 49, 46, 67,171,105, 92,138,203, 87, -115, 95, 95, 95, 28, 57,114, 4, 41,137,137, 95, 84,199, 92, 1, 0,143,207,111,219,190,125,123,236,219,183, 15,105,201,201, 95, - 60,103,174,138, 42, 72, 64,142, 32, 33,225,139,245,235,215,175,123,247,221,119,193, 23, 8,218,194,106,173,206,215,252,169, 67, -251,187,227, 38, 98,253,234,229,235, 1,188, 79, 41,229, 0, 92,103, 37,142,193,248,247, 98,143, 23,249, 95,129, 87,214, 53, 2, - 56, 91,217,206, 94, 94, 94,254, 10,133, 2,233,233,233,168, 23, 30,158, 45,145, 72, 32, 22, 10,225, 32, 22,219,245,101, 58,157, -174,129,159,159, 31, 84, 42, 21, 60, 60, 60, 32, 18,137, 74, 55,177, 88, 92,250,187,163,163, 35,120, 60, 30,130,130,130,160,211, -233, 26, 84,169,155, 21,229,181,109,249, 7, 19,174,156, 59, 82,107,208,160,193,112,117,117, 67, 96, 96, 0,188,188,188, 32,149, - 74, 17, 24, 24,136,218,181,107,211,197,139, 23, 67,230,213,208,174, 7,120, 89,211, 36, 16, 8, 96,179,217,144,149,149,133,216, -216, 88,220,187,119, 15, 87,174, 92,193,157, 59,119,160,209,104, 96,135,191,130, 78,175,111, 36, 16, 8,202, 53, 87, 74,165,178, - 52,122,165, 84, 42,145,147,147,131,164,164, 36, 20,106,181,141, 43, 49,187,131, 35, 35, 35,249, 0, 32,149, 74,209,184,113, 99, -172, 90,181,202,122, 96,239,222,225, 17, 87,174,184, 5, 30, 59,230,178,102,229,202,225, 67,134, 12,177, 93,189,122, 21,106,181, - 26, 15, 31, 62,132,167,167,167, 64,236,224, 48,140,221,198,213,227, 22,160,245,208,104,122,190,246,218,107, 79, 84, 42, 21,126, -248,225, 7,158,208,209,113,245,108,128, 95,233,129,124,126,155,246,237,219, 99,255,254,253, 72, 79, 78,158,150, 92,142,113, 73, - 6,114, 82, 18, 18,166,173, 95,191, 30,221,187,119, 7, 17, 8,170,221, 17,169, 85,171, 86,145, 28,199,225,254,253,251,112, 1, -174, 85,247,248,218,117,234, 52, 81, 40, 20,136,137,137,129,188, 56,186, 86, 30,114,224,194,237,219,183, 33,149, 74, 81, 47, 34, -162,105, 53,191,102, 49, 33, 36,227,221,113, 19,177,251,232, 37, 0,192,250,213,203,179,202,152, 43, 6,131,193, 34, 88, 85,122, -145,255, 57,131,101,103,198, 1, 0, 66,161, 16, 98,137, 4, 98,177,184,200, 24, 73, 36,213,113,167,112,112,112, 40, 53, 84,101, -141, 85,217,223,101, 50,153, 93,198, 5, 0, 10, 30, 29,109,247,254,123,239,138, 37, 18, 9, 76, 38, 35, 40,165,144, 72, 28,224, -226,226,130,144,144, 16,168,213,106,188,214,166,131, 49, 85, 41, 58,232, 94,111,224,189, 23, 57, 81, 86,171, 21, 90,173, 22, 5, - 5, 5,200,207,207,135, 90,173,134, 94,175,183,123, 72, 57,199,113,252,212,212, 84,252,254,251,239,200,203,203, 3, 80,212,129, -186,196, 84,149,252,124,242,228, 9, 54,111,222,140,196,196,196,106, 93,159,118,237,218,225,224,193,131,252,142, 93,186,172, 61, - 17, 28,156,126, 34, 56, 56,189, 99,151, 46,107,247,239,223,207,247,247,247, 71, 82, 82, 18,110,222,188,137,130,130,130,146, 2, -204,168, 38,143,129, 2, 93,126,254,187, 95,125,245, 21, 85, 40, 20,248, 97,209,162, 70,243,128,145,246, 26, 23,231, 74,140,139, -243, 95, 51, 46,160,148,130,227, 56,216,108,182, 23,202, 27, 33,132, 8,133,194,234, 78,145, 64,170,161, 95,218,161,253,243,111, -190,195,225,125, 59, 75,254, 21,207,204, 21,131,193,120, 21, 17,148,113,140, 85,190,120,179,178,178,158,106,181,218, 90,193,193, -193, 72, 75, 75,243, 10, 10, 10, 74, 22, 11,133, 16,137,197,118,245,193,146,201,100,247,211,211,211,219,248,251,251,195,106,181, -150,154,169,231,155, 8, 75,162, 50,119,238,220,129, 76, 38,187, 15, 67,165, 51, 32,192,102, 42,168,209,180,105,211,210, 72,144, -139,139, 11, 92, 92,156, 33,145, 56, 96,250,244,233,220,146,197,139, 87, 4,117,158,173,122,103,210, 87,244,171,121,107, 95,234, - 9,180,247,133, 36,147,201,238, 7, 6, 6,182,118,118,118,198,238,221,187,145,148,148,132,130,130, 2,232,116, 58, 24,141, 70, -232,116, 58,152, 76, 38, 56, 56, 56, 32, 34, 34, 2, 78, 78, 78, 56,121,242,228,125, 24,141,229,155,202,188,188,221,247,239,223, -111,221,162, 69,139,210, 8, 74,167, 78,157, 72,167, 78,157, 60, 74,163,102, 58, 29,114,115,115,113,253,250,117,156, 60,121, 18, -132, 16,196,199,199,219,140,122,253, 31,172,232,191, 24, 6,224, 50,127,253,250,117,227,199,143,127,175, 77,155, 54,176, 1,189, - 0,108,254,111, 25,151, 18,174, 92,185, 18,101,179,217,218,212,173, 91, 23, 74,160, 37,128,125,213, 50,143,143, 30,221,182, 90, -173, 93, 26, 53,106,132,221, 59,118,180, 3,144, 84,222,126, 90,160, 93,147, 38, 77,160,215,235,241,240,193,131, 91,213, 48, 87, -107,191,156,249,253,232,183,222,255, 16,155,214,174,192,250,213,203, 83,215,173, 90, 22, 8,192,204, 74, 21,131,193,168,142, 23, -121, 37, 35, 88,170,130,130, 91,183,111,223, 70,211,166, 77,241,248,241,227, 22,148,227, 4, 34,177, 24, 98,145, 8, 60, 59, 94, - 32,122,173,246,212,169, 83,167,172,141, 27, 55, 70, 97, 97, 33, 4, 2,193, 51,209, 43,177, 88, 12,161, 80, 8,129, 64, 0,153, - 76,134, 61,123,246,152,245, 90,237,169, 42,163, 67, 54,206,198,227,241, 74, 95, 98, 74,165, 18, 58,157, 30,223,125,247, 29,126, - 90,188,248, 13, 27, 48, 73, 40,247,212,255, 55, 79,180, 65,167, 59,125,248,240, 97, 75,173, 90,181, 48,122,244,104, 76,154, 52, - 9,147, 38, 77,194,248,241,227, 49,122,244,104,188,249,230,155, 24, 52,104, 16, 90,182,108, 9, 79, 79, 79,196,198,198, 90, 12, - 58,221,233,138,244, 36, 6,195,174,183,223,126, 59,187,196,152,105,181, 90,104, 52, 26,168, 84, 42,228,228,228,224,210,165, 75, -216,180,105, 19, 22, 47, 94,140, 61,123,246,192,104, 52,194,108, 54,227,206,157, 59, 5,114,139,101, 7,187,149, 95, 28, 33,176, -251,226,197,139,112,115,115,131, 95, 64, 64, 7, 59,140, 11, 26, 53,106, 4, 21,208,174,194,123,235, 5,140,203, 51,198, 71,163, -185,241,228,201, 19,116,236,216, 17,190, 1, 1,223, 71, 0,210,234, 28,111,179, 90, 47, 92,188,120, 17,111,189,245, 22,130,107, -213,250,222, 19,240,124,126, 31, 79,192,179,102,237,218,223,143, 30, 61, 26,199,143, 31,135,205,106,189, 80,137,169,106, 70, 8, -217, 79, 8, 57, 7, 32,105,244,216, 79, 70, 63,215,161,125, 40, 33,100, 11,128,169,172, 68, 49, 24,140, 87,145,106, 25, 44,169, -205,246,229,212,169, 83, 45, 60, 30, 15,131, 7, 15,118,220,183,127,255,144, 59,119,239,134,100,103,103,187,216,108,182, 42,181, - 60,141,198,101, 83,167, 78, 85,154, 76, 38,132,133,133, 33, 63, 63, 31, 54,155, 13, 2,129, 0, 2,129, 0,132, 16,240,120, 60, - 40, 20, 10,220,190,125, 27,235,214,173, 83,123, 26,141,203,170,124, 57,216,108,247, 55,111,222, 12, 62,159, 79, 29, 28, 28, 64, - 8,129, 64, 32,192,146, 37, 75,178,127, 2,118, 3, 0,159,199, 51, 1, 0,143, 71,236,237,149, 91,101,251,164, 88, 44, 6, 87, -212,185,191,202,125, 93,141,198,165, 11, 23, 46,212, 60,124,248, 16, 90,173,182, 52,218, 86, 88, 88, 88,218,105, 94,169, 84,130, - 16, 2,173, 86,139,253,251,247,107, 92,141,198,165, 21,233,229, 1,153,105,241,241,253, 91,180,104,145,247,228,201, 19,168, 84, - 42,220,191,127, 31, 39, 79,158,196,246,237,219,113,252,248,113, 60,122,244, 8, 86,171, 21,254,254,254,160,148, 98,239,222,189, - 42,171, 70,211, 43, 15,200,100, 69,191, 98,106,248,248,116,241,246,242, 74,241,244,240, 72,171,225,227,211,229,249,255, 59, 3, -113,113,113,113,176, 90,173, 8, 9, 9,113,171,172, 31, 22,181, 90, 47,150, 24,151,192, 90,181, 22, 4,151, 99, 92,130, 1,207, -224,218,181, 23,148, 24, 23,106,181, 94,172,110,154, 29,129,229,159,125,246,153, 94, 36, 18, 97,219,182,109, 33,150, 58,117, 98, - 4,192, 72, 5, 16,222, 17, 16, 85,117,188, 47,176,226,155,111,190,201, 36,132, 96,203,150, 45, 30,206,181,107, 71, 9,128,183, -157,129, 26,206, 64, 13, 1,240,182,115,237,218, 81,219,182,109,243,176, 90,173,152, 52,105, 82,166, 47,176,162, 18,201, 79, 40, -165,253, 40,165,237, 41,165,129,235, 86, 45,195,225,125, 59, 75,204,213,251,148,210,235,148,210, 55, 41,165, 81,172,196, 49, 24, -140, 87, 17, 82, 94, 63, 39, 97,203,121, 89, 0,245,234,208,170, 33,110,220,141, 85,121,184, 58, 29, 43,249, 95,126,244,206,186, -157, 27, 56, 53,252,229,151, 95, 32, 20, 10,145,154,154,138, 7, 15, 30,192,201,201, 9,111,188,241,134, 81,175,209,244, 47, 89, -139,144, 16,210,149, 82,122,178, 88,179,104,189, 51, 85,188,162,182,224, 94,173,163,135, 15,242,157,157,157, 81, 88, 88, 88, 58, -173,128, 76, 38,131, 84, 42,197,205,155, 55,209,167,223, 0, 91,142,172,125,233, 68,163, 37,235,157,149,213, 4, 33,124, 0,104, - 9,200,110, 3, 83,188,252,252,166,126,253,245,215,210, 30, 61,122, 64, 36, 18, 33,160, 70,104,102, 72,207, 31,150,243,120,196, -154,150,167,158, 94,187,134,159,243,131,248, 36, 0,164,104,205,194,226,181, 8,203, 75,103,144,233, 92,200,158,141,139,157, 26, - 55,110, 92, 26, 21,203,202,202, 66,118,118, 54,148, 74, 37,180,218,162,169, 30, 14, 30, 60,136,195,231, 99,212,250,128, 33, 9, - 21,165,243, 63,121,143,117,244, 51, 95,171,185,117,243, 70,190,167,167, 39,178,178,178,144,147,147, 3,165, 82, 9,189, 94, 15, -155,205,134,252,252,124,252,182,126,163, 45, 79,209, 62,177,100, 34,199, 74, 53,181,169, 82,183,194, 75,254, 77, 34,130,233,123, -239,189,231,232,228,228, 4,142,227, 80, 80, 80,128,148,148, 20, 60,121,242, 4,231,207,159,215,102, 43, 77,208,122,116, 75, 43, -153,104,180,220,243,249,178, 10,213,255,162,102,113, 89, 2, 0, 63, 95,223,244,228,228,100, 47,155,205, 6,127,127,127,171, 50, - 63,127,129, 24, 56,238, 8,100, 0,160,185,192,215, 75,151, 47,127,119,192,128, 1,104,222,188,121,106,102, 86, 86,205,242,202, - 18, 8,225,135, 1,206,186,128,128,232,235,215,175,251,164,164,164,224,173,183,222,202, 77,126,252,184,116,154, 6, 21,208, 46, -184,118,237, 5,219,182,109,243,168, 85,171, 22, 26, 52,104,144,233, 80, 50, 77, 67,249,229,179,194,123, 83, 25,119,168,230, 7, -131, 34,155, 79,152, 48, 1, 86,171, 21,231,207,159,199,181,107,215,144,156,156,140, 75,151, 46, 41,157,228,242,225, 37,107, 17, - 86, 84, 62,123,133,106, 67,182,108,217, 76, 68, 34, 17,214,175, 95,143,219,183,111, 3, 0,154, 52,105,130,209,163, 71,195,106, -181, 98,212,168, 55,233,161, 88,105, 66,101,229,147, 16, 18, 9, 96, 17,138,204, 93,115, 74,169, 3, 33, 36, 29, 64, 96,117,250, - 92,177,242,201, 52,153,230,191, 71,243, 85,163,202,181, 8,191,253, 21,206,207, 46,199, 49, 38,125,231,170,217,130,182,237,218, -135,207,158, 53,147,215,162, 69, 11, 4, 6, 6,162, 73,147, 38, 72, 73, 73,145,184,184,184, 84,181,222, 89, 97,251,158, 35,159, - 52,108,216,208,101,218,180,105,206,221,187,119, 23, 6, 6, 6,130, 82,138,219,183,111, 99,247,238,221,230,181,107,215,170,117, -222,253,148,183,206,252, 94,104,207,122,103,215, 0, 29,128, 57, 1,233,233,171, 63,252,224,131,153,141,155, 54,125,111,214,172, - 89, 60,133, 76, 42,252,110,250,251, 14, 0,240,237,207,219,157, 7, 12,121, 3, 75,235, 0, 29, 70,150,191,206, 91,217,116,166, -164,141, 73,238, 61,168, 75,157, 41, 31,189,107, 27, 54,108,152,220,201,201, 9,129,129,129,112,117,117, 69, 66, 66, 2,210,210, -210,232,129, 3, 7, 10,175,220,137, 19,238, 61,126, 35,217,193,217,215,158,117, 3, 53,237,123, 12, 77,236,221,187,183,235,219, -111,191,237,216,172, 89, 51,161, 68, 34,129, 68, 34, 65, 86, 86, 22, 30, 61,122,100, 62,112,224, 64,161,206,171, 87,193,173, 51, -219, 52,118,174, 69,168,111, 63, 98,246,163, 11, 39,102, 77,138,190,127,255, 77, 14,104,100, 54,155,253,109, 54, 27,225,241,120, - 25, 28,199,221, 55,107, 52,235,140, 77,102, 45, 97,107, 17,218,135,205,102, 19,217,108, 54, 40,149, 74,156, 56,113, 66,240,248, -241,227,175,239,222,189,251,117,122,122, 58, 44, 22, 11, 94,127,253,117, 52,105,210, 4,103,206,156, 65, 78, 86,214,129,202,180, - 98, 1,149, 36, 45,109,244,152, 49, 99,142,108,222,188,153,119,247,238, 93,143,245,235,215,255, 86,158,113,121,243,205, 55,185, -172,148,148,209,198, 74,230,192,170,226,222,204, 61,186,237,167,187, 3, 7, 15,137,152, 53,227,107,225,107,175,189, 6, 15, 15, - 15,180,107,215, 14,102,179,217,165, 94,189,122, 85,221,155,154,246, 61,135, 39, 52,106,212, 72,190,100,201, 18,159,119,223,125, - 23, 31,125,244, 17, 0, 64,175,215,227,248,241,227,152, 52,105, 82,102,138,160,165,182,170,242, 89, 28,153, 42, 49, 94,231, 0, -180, 7,144,192, 58,180, 51, 24,140,127,181,193, 2,254,179,222,217,133,107, 81, 40,187, 28, 71, 17,190, 15,172, 65,111, 63, 30, - 55,117, 65, 3,190, 69,237, 42, 36, 6,167,248,184, 56, 82,213,154,132,165,235,157, 57,135, 22,186, 63,249,163,197,119,223,126, - 59,113,233,210,165, 93, 74,166, 98,144,201,100,247,245, 90,237, 41, 79,163,113,153,206, 57,244, 84,117,215,206, 75, 3,178, 0, -124,224,122,235,214,242,190, 3, 94, 95,232,224, 22, 34,252,106,222, 90, 3,159,199, 51, 61, 74,207,193,210, 58,128,220,142, 1, -143, 58, 19, 16,173,244,181,102,185, 15,137,253,230,179,207,166,124, 59,103, 78, 11,133, 66,209,193,108,181,134,114, 28, 7,112, - 92,188, 78,171, 61, 71,205,230,235,198, 38, 51, 22, 59, 56,251, 82,187,215, 13,116,169,167,113, 75,220,217, 98,195,186,117,159, -236,216,177,227, 79,121,119, 55, 26,151,235, 92,234,157,180, 39,239,101,247, 49, 0,151,145,157,125,185,194,218, 6,216, 90,132, -118,223, 20, 28, 55,214,213,213,117, 83,151, 46, 93, 28,186,118,237,138, 62,125,250,224,181,215, 94, 3,199,113,160,148, 66,163, -209, 96,251,246,237, 88,184,112, 97,124, 77, 96, 78, 85,122, 70,224,148,228,240,225, 94,141, 26, 53, 90, 95,153,113, 41, 54, 87, - 85,246, 57,172,252,222,148,196, 91,157,251, 39,141,248,240,187, 58, 38,117,134,139,187,204,234, 19, 29,117,159,103,255,189, 25, -166,177,221,222,222,242,245, 65,131, 62,228, 11, 4,237,138, 71, 52,210,135, 15, 30,220, 42, 89,236, 25, 77, 70,159,168,102, 89, - 42,153,123,142,117,104,103, 48, 24,255,110,131, 37, 16, 8,178, 75,162, 60, 2,129, 32, 59, 97,239,184, 55, 42, 19, 17, 2, 93, -138, 35, 87,168,114, 45,194,226,223,147, 0, 13,140,198,185,207, 76, 34, 90,102,180,160,240,185,253,171,147,169, 2, 32, 22, 86, - 99, 95,100, 63, 0,246,127, 80,164,215,226,219, 47,202,230,169,194, 19,242,204,247,138,242, 13,192, 5, 20, 22, 94, 64, 97, 97, -185,179, 75, 11, 5,162,252,170,210,249,124,222, 83, 0,245, 95,205,187,160,154,231, 71,240, 23,206,231,191,141,167,185,185,123, - 1, 40, 2, 14, 30,244, 62,122,240,224,176, 41,147, 39,191,238,235,231, 87,219,195,195,195,213,209,209,145,119,245,234,213, 39, - 86,131, 97,121, 99, 96, 67,113,244,180, 74,140,192,169,176,148,148,250, 67, 7, 13,250,144, 8, 4,109,203, 26, 23,106,181, 94, - 10, 1, 86, 24,237,152,189,189,186,247,102,160,196,183, 75,113,228, 10,124, 59,239,205,180,162,116,204,131,213, 58, 15,247,238, -149, 83,230,171, 93,150,190, 37,132,104,192,102,104,103, 48, 24,255, 38,254,230,117,133,186, 50, 77,166,249,170,104, 22,121, 20, - 56,177,243,201, 52,153, 38,211,100,154, 47, 95,243, 85,219, 4,204, 98, 50, 24,118, 87, 70,108,248, 79,115, 23,131,193, 96, 48, - 24, 21, 66, 0,116,173,224,101, 98,247,232, 0, 66, 72,215, 23,120, 89,157,100,154, 76,147,105, 50, 77,166,201, 52,153,230,191, - 75,179, 42,237, 87,102,116, 34,107, 34,100,154, 76,147,105, 50, 77,166,201, 52,153, 38,107, 34,124,185, 27, 15, 12, 6,131,193, -192,236,217,132, 7, 16, 2,204,230, 1, 59,249,192, 80,126,209,223, 47,206,208,161,164,220, 73,104, 63,249,132, 56,178, 51,206, - 96,188,218,176, 62, 88,255, 69, 8, 33, 65, 62, 62, 62,171, 0,144,204,204,204,177,148,210, 20,118, 86,254,121,184,187,187,119, -177, 90,173, 80,169, 84,167, 94,197,252,213,175, 67, 6, 81, 30,234,253, 39,172,141,148, 7,241,116, 83,121,251, 70,132,146,183, - 64,254, 51,151, 22,225,240, 48,250, 17,221, 83,141, 50,207, 27,216,203,115, 17, 0,236, 61,146, 51,245,239,152, 23,139, 16, 82, -215,211,211,243,152, 64, 32, 16,216,108,182, 15,178,178,178, 14, 86,108,128,134,242, 1,192, 83,186,251, 75, 23, 55,143,105,223, - 76, 33, 66,147,241, 7,165,209, 96, 80,241, 4,130, 68,177, 72,118,209,202,147, 31, 73,203,234,245,160,188,227,119,236,216, 81, -225,234,218,145,161,164, 87,120, 68, 68,191,166, 13,164, 9,139,150,181, 88,218, 33,196, 67,248, 36,245,142,226,215, 77, 41,171, - 60, 93,253,251, 77,124, 95,112, 80, 66,109,111,126,255, 27, 45,100,119,153,253,204, 39,196,205, 12, 52, 16, 74, 36,129, 54,171, -213,155, 0,148, 47, 16,100, 89,140,198, 84, 17,112,111, 26,165,202, 87, 93, 83, 36,145, 4,216,172, 86,111, 0,248, 39,166,147, - 81,133,193,114,116,116,188,201,227,241, 2,202, 46, 82,203, 43, 94,208,185,228,179,178,255, 35,132,192,102,179,165,229,231,231, - 55,171,198,131,208, 9,192, 48, 0, 37, 67,205,183, 2,216, 78, 41, 85,191,224,131,213, 73, 36, 18, 77,149,203,229,157,245,122, -125,125, 0,144, 74,165,209, 90,173,246,180,217,108, 94,244, 34,186,132, 16, 1,128,161, 10,133,162, 19,143,199,235, 68, 41, 37, -148,210, 51,133,133,133,167, 1,236,160,148, 90, 95, 64, 83,234,229,229, 53, 47, 60, 60,124,228,151, 95,126,153,231,238,238, 30, - 54,105,210,164, 27,158,158,158,191,231,230,230, 78,167,148,234,255, 9,133,131, 16, 82,219,199,199,103,171, 80, 40,228,167,166, -166,118, 2,128,192,192,192, 51, 38,147,201,150,157,157,253, 6,165,244,113, 53,245,228, 0, 90, 41, 20,138,102, 10,133,162,189, -205,102,171,199,113, 28, 56,142,123, 88, 88, 88,120,222,108, 54,223, 4,112,149, 82,170,253, 7,153, 96, 71, 47, 47,175,205,132, - 16, 16, 66, 66, 41,165,154, 87,237, 33, 64,121,168,247, 32, 58, 38,172,212, 68,213, 15,175,228,132, 32,168,156,125,237, 54, 88, -189,187,184,244,236,215,175, 17, 15, 0,204,230, 27, 61, 1, 28,126,217,230,106,240,224,193,151, 55,111,222,236,106, 52, 26, 49, -118,236,216,173,206,206,206, 43, 84, 42,213,151,149, 29,231,232,232, 56,105,206,220,159,101,197,207, 52, 47,142,227,188, 50, 50, - 82, 67, 99, 99,238,247,140,141,141,250,206,172,221,115,213, 76,249,227,148,186,254, 49,246,164, 35,162, 54,233, 59, 96,232,160, - 62,115,230,204,194,200,225, 35,107, 68, 71, 27,164,254, 78, 9, 98,181, 89, 94,199,195, 35,160,255, 23, 95,125, 79,174, 94, 57, -219,127,199,246,181,167,191,120,143,116,102, 38,203,174,107, 75,190, 21, 8, 90,185,134,135,183, 31,190,119, 47, 20,129,129, 2, -129, 68,194, 3, 0,171,209, 24, 88,152,154,234,187,173,127,255,150,179, 9, 57, 59,147,210,107, 76,243,255, 95,147, 97,167,193, -226,241,120, 1, 79,159, 62,245,146,203,229, 69, 15, 97, 74, 97,179,217, 96,179,217, 80,252, 82, 4,165,180,244,167,213,106, 69, -120,120,184, 93, 53, 88, 0,157, 1,188,211,184,113,227,215,231,204,153, 35,234,220,185, 51,108, 54, 27, 14, 31, 62,220,110,238, -220,185, 63, 17, 66,118, 3,216, 0,224,148,189, 53, 92, 66, 72, 15,185, 92,190,229,135, 31,126,112,234,214,173,155,192,207,207, - 15,132, 16,100,102,102,182, 58,121,242,100,179, 73,147, 38,125, 64, 8, 25, 69, 41, 61, 86,141, 27, 58,210,209,209,113,231,160, - 65,131, 2, 58,116,232,224, 16, 17, 17, 1,155,205,134, 59,119,238,188,123,243,230,205, 17,187,118,237,154, 73, 8, 25, 98,239, -122,106,132, 16,162, 80, 40,222,246,247,247,159, 55, 99,198, 12,183, 81,163, 70,137,163,162,162, 10, 66, 66, 66,200,197,139, 23, - 61,183,111,223,254,193,130, 5, 11,134, 58, 58, 58, 78, 47, 44, 44,220, 72,203, 91,199,232, 57,156,156,156,110,242,120,188, 0, -123, 12, 48, 0,187, 77, 48, 33,164,113,205,154, 53,183, 95,184,112,161,102, 82, 82,146,109,224,192,129,155, 0,224,244,233,211, - 13, 44, 22, 11,233,222,189,251, 17, 66,200, 48, 74,233, 29, 59,243,222,208,205,205,109,223,200,145, 35,221,106,215,174, 45,171, - 89,179, 38,145,203,229,224,243,249, 80,169, 84,126, 81, 81, 81, 93,175, 93,187,166, 63,121,242,100, 62, 33,164, 63,165,244, 94, - 53,174,211,107, 94, 94, 94,111, 10,133,194, 72,171,213,234, 15, 0, 2,129,224,169,197, 98,137,202,206,206,222, 76, 41,189,252, -162, 55,136,183,183,247, 79,243,230,205,243,200,206,206,166, 11, 22, 44,248, 9,192,219,175,234,195, 96,235,239, 59,112,243,198, - 53, 0, 16, 17, 66,200,243,229,143, 16, 66,234,133, 66,244,233,167,147,209,172,121, 75,188, 49,114,104,149,154, 3,251,120,204, - 17,243, 5,238, 58,147,241, 90,174,138,183, 47,200, 75, 60,104,212,208,102, 9, 0,112,244,200,253, 65, 45, 91,186, 93,244,112, -230, 6,200,196,146,150, 38,155, 53,111,239,161,220, 25,213, 49, 83,254,254,254,199, 92, 93, 93,101,249,249,249,153, 57, 57, 57, -191, 14, 30, 60,248,219, 13, 27, 54,184, 62,121,242, 4,169,169,169,152, 56,113,162, 34, 45, 45,237, 67,137, 68,114,197,104, 52, - 86, 24,201,210,104, 52,203,230,205,157, 60,195,209,201,149, 47,147,202,161,112,116, 66,205,154,161,104,222,162, 29,186,118,235, -143,132,132,216, 86,219,255, 88,123,155,159,177,115,190, 77,220,228, 91,165,178,102,133,207,165,250, 97,164, 67,137,185,154, 49, - 99, 22,226, 98, 98, 52, 73,137,188,143, 15,237, 21,200,122,117, 9,151,152,204,133, 73, 87,175,156,173,217,170,117, 71, 0,104, -182, 99,251,218,211,179, 71,145, 46, 51,183,188,122,230,253,101,154,171, 57, 66,225,219, 61,150, 44,241,106,242,193, 7,162,194, -196, 68,115,194,202,149,186,172,243,231,109, 2,137,132, 6,246,236, 73, 60, 59,117,114,248,224,225, 67,209,165, 5, 11,218,127, - 39, 22,135,124,101, 50,109, 97,154,255,127,154,140,106, 24, 44, 66, 8,228,114, 57,182,109,219, 6,161, 80, 8,129, 64, 0,161, - 80, 88,225,239, 65, 65, 65,246,220, 36,131, 61, 61, 61,127,158, 49, 99,134,247,176, 97,195,224,238,238,254,124,184, 30,175,191, -254,186, 40, 46, 46,110,196,198,141, 27, 71,252,250,235,175,153,132,144,143, 41,165,187,171,208,237, 20, 22, 22,182,251,248,241, -227, 82,131,193,128,243,231,207,163,160,160, 0, 98,177, 24, 1, 1, 1,232,222,189,187, 32, 38, 38,198,173, 91,183,110,187, 9, - 33,125, 41,165,103,236, 72,107, 51, 47, 47,175,115, 59,118,236,112,104,212,168, 17,121,244,232, 17,154, 52,105, 2, 0, 80,169, - 84, 24, 56,112,160,195,168, 81,163,106,143, 24, 49,226, 42, 33,164, 3,165,244,102, 21,122, 77,125,124,124, 54, 14, 26, 52,200, -239,187,239,190,115,114,116,116, 68, 82, 82, 82,134,143,143, 79,104,201,249, 30, 49, 98,132,184, 95,191,126,190, 11, 23, 46, 92, -182,115,231,206,207, 8, 33,111, 83, 74,111, 85,166, 91, 98,132,101, 50, 25,178,178,178,176,117,235, 86,124,248,225,135,224,243, -249,200,206,206,198,246,237,219,241,241,199, 31,151, 24, 25,187, 76,176, 92, 46,239,218,168, 81,163,223, 78,159, 62, 29,224,226, -226, 2, 63, 63, 63,222, 55,223,124, 19, 25, 18, 18, 34,173, 81,163, 6, 63, 35, 35, 3,187,119,239, 14,121,243,205, 55,247, 57, - 56, 56,188,107, 48, 24,170,108, 58,243,246,246, 94,119,232,208,161,160,232,232,104,172, 92,185, 18,249,249,249, 16,139,197,112, -113,113,129,143,143, 15, 66, 67, 67,201,180,105,211,100,253,250,245,147,125,244,209, 71,235, 0, 52,182,227, 26, 53,242,242,242, - 90, 53, 98,196,136,144,217,179,103,187,248,248,248,160,164, 66,160, 82,169, 2,146,146,146, 90,205,152, 49, 99,136,183,183,247, -147,236,236,236,113,148,210,187,213,124,168, 55,238,210,165, 75,223,129, 3, 7,242, 51, 50, 50,176,121,243,230,190,132,144,198, -246,154,202,255, 53,110,222,184,134,177, 19, 38, 22,250, 5, 6,138, 14,236,255, 99, 64, 97,225,234,139, 10,158,139, 0, 0, 10, - 57,165,181, 77, 43, 69,219,126,253, 71,136,122,247, 25, 88,184,250,151,101, 10,123, 12,150,152, 47,112,223,182,101,124,234,249, - 75,241,245,142,157, 76,234, 58,176,127, 87,158, 64, 20, 86, 27, 0,166, 76, 30, 35,222,187,255,228,138, 30, 93,107,100,180,111, - 19,154, 58,124,212,202,192,234,152,171,186,117,235,158,189,125,251,182,183, 68, 34, 65,126,126,190,251,234,213,171,127,108,219, -182, 45, 47, 33, 33, 1, 49, 49, 49, 72, 76, 76,132, 74,165, 66,183,110,221, 20,183,110,221,250, 21, 64,133, 6, 43, 71, 63,120, - 94,136, 87,238,114,127,119,215,154, 6,179,202,203,102,205,139, 56,125,242,110,195, 93, 59,116, 77,188,124, 2, 66, 71,140, 24, -139, 47,190,252, 94,184,103,215,198, 25,231,206, 31, 7, 80,179,226, 25,252, 41, 94,251,106,250,151, 80,107,140, 24, 53,114, 12, -222, 28, 57,198,157,194,228, 75,109, 6,185, 73, 95,224,226, 44,138, 62,184,241,143, 29,131, 0, 4,148, 49, 89,167,152,201,170, -152, 57, 2, 65,203,190, 63,255,236, 25,249,254,251,146,187,179,103,107,115,207,159,215,215,233,221,187,160,201,248,241, 70, 0, -208, 36, 38,138,226,102,206,148,121,182,111, 47,109, 61,117,170,171,205,100,242,153, 75, 72,139,111, 40,189, 94, 93,205,160, 97, -195,108, 51,214,175,111,126,126,242,228,142,196, 98,225,247,108,221,250,206,130,205,155,159,254, 21,205,151,153,206,244,115,231, -140,249, 33, 33,104, 50,112, 96, 94,144,151,151,241,101,230,253,175,164,147, 81,206,115,138, 82, 10, 66, 72, 7, 0,103, 1,204, -166,148,206, 2, 0, 23, 23,151, 44,165, 82,233,181,123,247,238, 42,205,149, 80, 40,132,175,175, 47, 66, 67, 67,179,179,178,178, -188, 43,121, 40,166, 90,173,214, 0,171,213, 10,177, 88, 92,105,194,212,106, 53,238,220,185,131, 78,157, 58,165, 81, 74, 3, 43, -107,194,145,201,100, 9, 49, 49, 49, 30, 15, 30, 60,192,205,155, 55, 17, 18, 18, 2, 87, 87, 87, 8,133, 66, 88, 44, 22,168,213, -106,132,133,133, 65, 34,145,160,105,211,166,185, 90,173, 54,164,178,166, 30, 66,136, 68, 46,151,199,159, 59,119, 46,176, 73,147, - 38,184,126,253, 58, 2, 3, 3,225,227,227, 3, 0, 72, 76, 76,196,197,139, 23,209,187,119,111,220,190,125, 27,175,191,254,122, -170, 86,171, 13,165,148, 26, 43,210,116,119,119,207, 56,125,250,116, 90,131, 6, 13, 12, 90,173,150,151,149,149, 37, 60,127,254, -188, 85,163,209, 40, 84, 42,149, 80,169, 84, 10,213,106,181, 64,171,213, 10,121, 60,158, 72,175,215, 11, 79,157, 58,197, 55,153, - 76, 78,149,157,167,146,235,180,127,255,126, 52,104,208, 0,187,119,239,198,148, 41, 83,112,233,210, 37, 4, 6, 6, 98,199,142, - 29,152, 58,117, 42, 98, 99, 99,225,225,225,129,136,136,136, 74,175, 17, 0,212,169, 83,231,209,253,251,247,107,139, 68,162,146, -117, 23, 75,214,179, 67, 78, 78, 14, 30, 63,126,140,167, 79,159,162, 78,157, 58, 24, 57,114,228,227,180,180,180, 58, 85, 21,180, -128,128,128,156,232,232,104,143,134, 13, 27, 34, 43, 43, 11, 46, 46, 46,112,118,118,134,139,139, 75,233,239, 33, 33, 33,152, 60, -121, 50,124,124,124,178,245,122,189,119, 85,230,167, 65,131, 6,199, 78,157, 58,229,225,228,228,132,204,204, 76,168,213,106, 8, - 4, 2,200,100, 50,120,120,120,192,193,193, 1, 0, 16, 31, 31,143, 62,125,250,228, 38, 36, 36,244,168, 70,196,141,231,237,237, - 29,115,239,222,189, 80, 74, 41, 82, 82, 82, 16, 27, 27,139, 9, 19, 38,196, 27, 12,134,240, 87,105, 77,189, 50,253,170, 68,111, -143, 30, 43, 26,216,127,128,238,206,205,163,156, 20,231,208,162,177, 84, 9, 0,215,239,232, 93,244,232,128,198,205,122,242,246, -238,223, 39,219,184, 97,181, 16, 28,188, 65, 16,251, 32,142,206,173, 72,187,111, 15,151,183,166, 78,236, 89,175,125,155,246, 2, -181,154,250,252,182,105, 77,139,228, 39, 9,222, 0, 16, 92, 43, 36,235,189,183,198, 92,119,114, 34,153,231, 47,157,183, 46, 90, -118,244,225,193, 99,202, 77,118, 92,155,144,208,208,208, 43,251,247,239,247,240,242,242,130,179,179, 51,180, 90, 45,204,102, 51, - 30, 60,120, 96,216,182,109,155,197,201,201,201, 49, 51, 51, 19, 74,165, 18,132, 16,236,223,191, 63,133, 82, 26,252,188, 86, 73, - 31, 44, 0,152,208,171,158, 48,162,115,168,171, 72, 98,149, 74,133,113,190, 32, 54, 9,161, 10,239,211,167,175, 52, 60,115,238, -194, 27,189,251, 14,247,108,221,186, 19,190,255,238, 11, 75, 74,102, 86, 19,165,174,127, 76,121,125,176,234,133,146,206, 3, 95, - 31, 52,116,206,156, 89,152, 53, 99, 54, 14,238,223,171, 82,200,121, 70, 39, 23,161,115,251, 86,109, 12,147, 63, 28,144,170, 43, - 76, 11,252,113,197,154,145,221,122, 12, 13,104,213,186, 35,174, 94, 57,139, 29,219,215,222, 20,217, 44,172,185,240, 57,102, 19, -226,234, 18, 18, 50,238,147,248,120,209,221, 89,179, 10,173,233,233, 5,205, 38, 77,202, 45,111,223,180, 19, 39,228, 98, 63, 63, - 39,215,254,253,221,150, 5, 7, 83, 75,118,246,170,242,250, 16,149,167,121, 82,161,112,249,227,200,145, 46, 84, 40,236,240,249, - 23, 95, 72,251,246,237, 11,181, 90,141, 93,187,118, 97,213,202,149, 70, 95, 95,223,251,126, 81, 81,183, 35,213,234,175,237,213, -108, 54,105, 82,174,205,102, 35, 67,167, 78,237, 22,157,152,216, 57, 51, 59,187, 6, 0,248,186,185,165, 54, 11, 9,185,185,238, -224,193,216,159,106,214,228,236, 77,231,154,163, 71,189,119, 38, 37,189,239,230,230, 38,205,202,206, 22, 72,196,226,188, 86, 17, - 17, 59,126,153, 62,253,172,245,222, 61,145, 67, 64,128,147,115,223,190,213,206,123,179, 73,147,114,243, 53, 26,193, 39,223,126, -219, 38, 57, 43,171, 70,161,209, 88, 71,169,209,248,216, 44, 22,158,147, 76,150, 87, 43, 44, 44, 91,127,254,124, 70, 45,157,110, -226, 26, 74,179,255,198, 72,229,159,188,200,171, 16,193, 58, 75, 41,253,211,104, 25, 74,169, 93,209, 43,161, 80,248, 76,115, 84, - 37,136,248,124, 62,174, 95,191,142,236,236,108, 52,104,208, 0, 53,107,214,124,102,135,132,132, 4, 28, 62,124, 24, 74,165, 18, - 77,155, 54, 5, 0, 81,101,130, 18,137,228,211,133, 11, 23,186,152, 76, 38,220,188,121, 19,205,154, 53,131, 68, 34,129, 72, 36, -122,198,252,101,103,103,163,126,253,250,248,252,243,207,157,191,251,238,187, 79, 81,201, 26,114, 2,129,224,163, 49, 99,198,120, -149, 68,172, 82, 83, 83, 75,210, 2, 0,240,244,244,196,157, 59,119,208,172, 89, 51, 4, 4, 4, 96,200,144, 33, 94,155, 55,111, -254, 8,192,162, 10,107,242, 98, 49,175, 65,131, 6,205,139, 35, 68,224,241,120,113, 78, 78, 78,158,222,222,222,114, 39, 39,167, - 63,229,113,253,250,245, 74, 30,143,103,169,234,132,242,120, 60,100,102,102, 34, 50, 50, 18, 42,149, 10, 0,160,213,106, 81,167, - 78, 29,168,213, 69, 93,206,140, 70, 35,252,252,252,160,215, 87,222,181,171, 81,163, 70,179,194,195,195,187,119,236,216, 81, 34, - 20, 10,113,247,238, 93, 52,105,210, 4,219,182,109, 67, 80, 80, 16,100, 50, 25,226,227,227,209,160, 65, 3,156, 59,119, 14,158, -158,158,168, 95,191,190,164,105,211,166, 23,242,243,243,207, 36, 37, 37,205,170, 36,157, 60,133, 66,129,115,231,206, 97,221,186, -117, 72, 76, 76, 68,122,122, 58, 28, 29, 29,209,184,113, 99, 68, 68, 68,224,181,215, 94, 67,124,124, 60, 72, 21,133,137, 16,226, - 19, 26, 26,122,240,250,245,235, 30,148, 82,108,222,188, 25,133,133,133, 48,153, 76,224,241,120,112,112,112,128,171,171, 43, 58, -119,238, 12, 79, 79, 79,132,134,134, 98,251,246,237, 30,189,122,245, 58, 92, 28,129,202,172,234,188,186,186,186, 78,156, 57,115, -102,160,151,151, 23,146,146,146,160, 82,169,224,237,237,141,142, 29, 59,250,159, 60,121,114, 34,128, 37,175,202, 11,172,164, 67, - 59, 33,132, 28,216,255,199,128, 32, 95,113,189, 22, 77, 52,193,247,111, 9,106, 31, 62,249,168, 97,209,249, 8,190,215,162,169, -230,241,245,155, 71,147, 15,236,255,227,218,195, 56,236,179,167, 9, 59, 87,197,219,119,236,100, 82,215,134,245,219,241,151,175, -152, 57, 96,236,123, 61, 36,110,174,237,136, 58,123, 59, 46, 93,187, 31,252,205,172,105, 94,115,103, 45, 56,112,236,100,146, 45, - 87,197,155,103, 79,122,235,215,243,253,233,236, 94, 47,143, 66,243, 47,184,115,205, 25, 16,182, 70,173,144,186, 80,171,213,112, -112,112,112, 24, 57,114,164,237,203, 47,191,212, 57, 57, 57,201, 8, 33, 56,115,230, 76, 54,128, 30, 85,233, 26,188, 92,169,205, -108,177, 82, 49,159,163,196, 81, 79,108,249,226,168, 7, 79,208,161, 67,175,172,230,205,154,124,183,224,135, 37, 95,133,132,132, -121,142, 28, 53, 78,184,104,209,215, 43, 1,180, 43, 79,231, 97, 60, 61, 29, 81,155, 72, 1,244,153, 51,119, 22, 18, 18,226, 93, -199,190,163,156, 45,144, 72,253,194,131,219, 56,174, 92,119,166,103,157, 58, 53,107,140, 29,253,238,161,213,235,215,245, 41, 27, -201,250,227,247,213,251, 8, 33, 93,236, 57,183,255, 34, 26,190,121,240, 32, 10, 83, 82, 44,249, 23, 46, 24,186,252,252,115,110, - 96,143, 30, 75, 76,102,179, 71,201,163,130, 71, 8, 72, 73, 23, 9,142, 35,130,207, 63,231, 81,129, 0, 22, 87,215,119,166, 1, -117,171,210,156,146,145, 49,248,141,247,223,239,179,239,232, 81,212,172, 89,179,244,125,230,226,226,130,169, 83,167, 98,210,164, - 73,146, 59,119,238,180,216,185,115,103,139, 69, 63,252,224, 61, 13, 24,108, 79, 58,143, 95,189,234, 58,126,206,156,233,141,154, - 53, 11,218,180,117,171,164,118,237,218, 0,128,199,143, 31,135,126,191, 96, 65,112,100,131, 6, 89,223,125,250,233,134,232, 47, -191,172, 15,224, 66,101,154,153,231,207,155,118, 38, 37,189,127,250,204, 25,151,200,200, 72, 0, 64,108,108,172,215,178,101,203, -198,212, 31, 50,100,212,156, 15, 62,248,186,175,193,160,116,202,201,145,244,253,233, 39,193, 31, 67,135, 86,169, 89,146, 78, 0, -232,248,238,187,159,182,235,212, 41, 98,240,251,239,187, 5, 5, 5, 17,133, 66, 1,179,217,140,244,244,116,215,232,232,232,218, - 7, 53, 26,245,158,171, 87, 55,175, 41, 94,196,253,111,162, 92, 47,242,191,110,176, 58, 18, 66, 40,128,142,148,210,115, 37, 47, -110,155,205,102,151,185, 18, 8, 4, 40,238, 4,108,223,151, 10, 4,240,243,243, 67,110,110, 46,162,162,162, 16, 28, 28, 12,139, -197,130, 99,199,142, 65,165, 82, 65, 40, 20, 66, 36, 18,193,108,174,122,109, 88,185, 92,222,181,107,215,174,130,171, 87,175, 34, - 36, 36, 4, 82,169,180, 52, 93, 37,155, 72, 36,130,175,175, 47,212,106, 53,186,116,233, 34, 92,190,124,121,215,202, 12,150,179, -179,115,239, 97,195,134,149,134,216, 10, 11, 11,193,231,243, 75,205, 74, 97, 97, 33,242,243,243,161, 84, 42, 97, 48, 24,208,186, -117,107,241,193,131, 7,123, 87,102,176,202,162,211,233, 10,179,179,179, 93,218,181,107,231,186, 97,195,134,216,214,173, 91,135, - 61, 83,194,206,158, 53, 24, 12, 6, 33,143,199,179,107,157,187, 45, 91,182,148,158,251,167, 79,159, 98,229,202,149,165,255,139, -143,143,199,242,229,203, 75,231,229,168,236, 26,133,135,135,247,218,188,121,115,179, 77,155, 54, 21,240,249,124,196,198,198, 98, -235,214,173,160,148,194,211,211, 19, 58,157, 14, 89, 89, 89, 56,115,230, 12,172, 86, 43, 20, 10, 5,252,253,253, 29, 62,250,232, -163,182,179,103,207, 22, 2,168,208, 96,217,108, 54, 27,159,207, 71,112,112, 48,102,204,152, 1,131,193, 0,145, 72, 84, 26,173, - 84, 42,149,184,125,251, 54,146,146,146, 80,213,203,197,193,193, 97,200,166, 77,155,188,196, 98, 49,244,122, 61, 52, 26, 13, 82, - 83, 83,145,156,156,108,200,206,206,182, 58, 58, 58,242,130,131,131,121, 18,137, 68, 50,112,224, 64, 82, 98, 52,251,246,237,235, -190,121,243,230,225, 85,153, 35, 66,136,103,189,122,245,190, 26, 51,102,140, 67,217,202, 70,102,102, 38, 6, 15, 30, 44,187,124, -249,242,151,132,144,173,148,210,156, 87,233, 45, 70, 41,165,133,133,171, 47,158,223,247,115,189,251,183, 4,181, 77,166,130,214, -221,122, 79, 20, 0,192,229,115,235, 91,223,191, 21, 5, 41,177, 38, 31, 57,190,232,162, 66, 49,150, 86, 21, 1,236,221,197,165, -103,144,151,120,208,192,254, 93,121,191,109, 90,211, 98,236,123, 61, 36, 94,181,214, 16, 0,112, 21, 5,224, 53,219, 20,158,193, -168,117,248,109,211,154, 22, 3,251,247,190,150,248, 36,121, 73,159,174,174,123, 14,159, 82, 30,173, 44, 66,232,235, 35,244,119, -115,202,131,155, 99, 19, 4,135, 56,226,246,157,123,216,183,251, 2, 66,195,219,194,104, 52,194,106,181,202,251,245,235,167,219, -182,109,155, 33, 46, 46, 78,163,215,235, 59, 80, 74,227,170,202,127, 90,218, 3, 46,204,167,149, 89, 36,149, 88, 53, 42,145,110, -218,215, 59,135, 54,109,217,189,153,171,175,191,208, 83,206, 29,232,212,161,221,214,223,183,172,154, 52,229,179,185,104,220,184, -117,235,135,143,142, 68, 0,184, 95,174,105,125, 76, 15, 70,134, 18,107,194,163, 71,125,146,147,146,210,234,122,251,152, 30, 43, -169,101,226,180, 53,221,218,117, 24,210,176,118,189,246,226,232, 7,231,200,228, 15,199,252,254,227,138, 53, 35, 75, 76,214,249, -243,199, 58,204,154,149, 36, 6, 96,100,190,170,184, 86, 46,145, 4, 40,130,131, 5,137, 27, 54,232, 67,250,245, 43, 0, 0,147, -217,236,145,152,148,228, 44,147,201, 64, 41,133,197, 98,121,166,143,112, 73,191,224,200,176, 48,111,123, 52, 19,191,249,166,225, -231,159,127,142,204,204, 76, 88,173, 86, 8,133,194,231,159,217,208,106,181,120,231,157,119,240,211, 15, 63,180,178, 71,211,102, -179,145,241,115,230, 76,255, 98,250,244,218,227,198,141,227,149,125,246,186,185,185, 97,231,174, 93,226, 21, 43, 86, 4,124,245, -211, 79,239,188, 33,145, 36, 84,165,153, 91,167, 14,220,178,178,164, 37,230, 10, 0,194,194,194,176,114,229, 74,201,123,239,189, - 39,238,215,175,223,226, 59,141, 26, 45, 91,210,182,237, 35,247,186,117,157,196, 18, 73,128,189,231, 19, 0, 52, 6, 67,228,146, -101,203, 92,175, 93,187,134,172,172, 44,100,102,102,150,220,203,104,222,188, 57,121,243,205, 55,157,107, 5, 6,182,248,155, 47, -247,159,188,200,255,188,193, 42,206, 8, 41,206, 24, 41,243, 82,124,198,168, 84,101,176, 94, 32, 28, 8, 95, 95, 95,152,205,102, -172, 93,187, 22, 34,145,168,244,165, 11, 0, 38,147,201, 30,179,210,192,207,207, 15, 42,149, 10,117,235,214,125, 38,114, 37, 18, -137, 32, 16, 8, 32, 18,137, 32,145, 72, 96, 52, 26, 17, 20, 20, 4,157, 78,215,160, 50, 77,189, 94,223,216,205,205,173,244,197, -106, 52, 26, 75,205,149, 82,169,132, 82,169,132,201,100, 66, 65, 65, 1, 10, 11, 11,161,209,104,160,213,106,155,216,147,103,142, -227, 16, 21, 21,245, 56, 44, 44,172, 49,159,207,135, 66,161,144,107,181,218,210,190, 67,249,249,249,216,184,113,163,246,173,183, -222,242,216,191,127,191,206,158,115,248,241,199, 31, 67, 34,145, 64,167,211,225,215, 95,127,197, 39,159,124, 2,145, 72, 4,141, - 70,131,149, 43, 87, 98,242,228,201, 16, 8, 4, 48,153, 76, 88,182,108, 89,197,145,140, 7, 15, 18,175, 94,189,218,164,105,211, -166,174,123,246,236,201,233,214,173,155,103,143, 30, 61, 32,149, 74,161,215,235, 97,177, 88,208,170, 85, 43,132,135,135, 35, 59, - 59, 27, 71,142, 28,201, 13, 13, 13,245,184,118,237, 26,151,153,153,153, 92,213,203,187,172,193,182,217,108,200,202,202,130, 82, -169, 68, 78, 78, 14,210,211,211,145,150,150, 6,129, 64,128,170, 42,239,238,238,238,175, 71, 70, 70,242, 1, 64, 42,149,162,113, -227,198,152, 62,125,186, 85,175,215, 15, 3,112,164,120,183, 94,107,214,172,217,115,241,226, 69,129,159,159, 31, 98, 98, 98,224, -233,233, 41,112,112,112,168,210, 96,249,248,248,172, 63,112,224,128, 91,137,169, 46, 57,207, 58, 93,209,229, 24, 60,120,176,219, -166, 77,155,214, 3,232,253,170,189,204, 20, 60, 23, 65,139,198, 82,229,225,147,143, 26,118,235, 61, 81,224, 91,123, 38, 0,224, - 53, 64,112,226,240,178,134,189,187,214,217, 81,210, 47,171, 50, 6,246,242, 92,212,175, 95, 35,222,168,161,205, 18, 4,162,176, -218, 91, 54, 45,243,118,115,109,247,159,135, 4,223, 13,114, 41, 16, 94,219,198,187,242, 71,130,247,228,137, 97,166,173, 27,222, - 79,216,178,227,102, 87,145,232,110,103, 0,147, 43,210,190, 23,109,220, 95,160,241,175,231, 42, 58, 75,224,208, 31, 77, 26,135, -194,211, 83,137, 95, 87,111,130,127, 80, 27, 24,141, 70, 56, 57, 57,201,108, 54,155,153,207,231,111,177,199, 92, 1,192,169, 83, - 74,174,126,125,165,137,175,225,172, 31,126,178,104, 80,183, 94,253, 35, 58,119,238,202, 29, 63,113,220,220,166,137, 57,163,115, -231,214, 89,103,206,158,143,207,204,124, 26, 26, 30,222, 16,113,177,119,122, 2, 36, 10, 40,191,192, 70,197,211,163,181,107,147, - 51,219,182,141,229,244,220,109,233,183,243,238,247,234,211,231,237,200,246,237,218,115, 39, 78,158, 54,137,145,251, 80,209,246, -181,167,111,143, 24,182,103,219,238, 61,221,207,156, 62, 88, 71,165,206, 58,248,195, 10,202,204, 85,217,202,153,213,234, 45,144, - 72,120, 57,103,206, 88, 27,188,247,158,177,228,126,148,201,100,216,183,111, 31,196, 98,113,233, 38, 18,137, 74,127,247,246,246, - 46, 25, 84,101,151, 38, 0,100,100,100, 32, 51, 51, 19,206,206,206,240,244,244, 68,102,102, 38, 46, 95,190,140,184,184, 56, 8, -133, 66,244,236,217, 19,188, 10,250, 46, 63,175, 57,116,234,212,110,245, 26, 52, 8,122,222, 92, 1,128,217,108, 70,126,126, 62, - 6, 12, 24,192, 59,114,228,136,207,209,148,148,254,223, 0, 91, 42,211,108,210,167, 79, 94,214,206,157,229,126,119,211,166, 77, -201,165, 75,151, 36, 61,123,244,152, 52,101,222,188, 21, 63,109,218,148,106,179, 90,125,170,147,119, 30,143,199, 35,132, 32, 48, - 48, 16,249,249,249, 40, 44, 44,106,169, 86, 40, 20,112,117,117,133,197, 98, 1, 71,169,240,111,174,228,149,235, 69,254,167, 13, - 86,113,102, 0,160, 99,217, 23, 10,199,113,118,153, 43,161, 80, 88, 58,130,237, 47,156,216, 63,125,102,143,193, 42, 73,171,131, -131, 67,233, 13, 86,214, 88,149,164,147,199,227,129,207,231,195,158,200, 59,199,113,124,141, 70,131, 93,187,118,161, 67,135, 14, -165,205, 79, 42,149, 10, 74,165, 18, 42,149, 10, 6,131, 1,137,137,137, 56,117,234, 20,234,212,169, 3,192,190, 73, 91, 19, 18, - 18,110,214,172, 89,179, 89,201,203,187, 83,167, 78, 1, 27, 54,108, 72,239,221,187,183, 31,165, 20, 95,127,253,117,110,171, 86, -173, 60,202,190,220,171,130,207,231,227,242,229,203,168, 83,167, 14, 40,165, 16,137, 68,136,141,141,133,151,151, 23, 56,142,131, - 64, 32, 64, 78, 78, 14, 28, 29, 43,159,219, 48, 42, 42,106,244,187,239,190,155,238,236,236,220, 48, 47, 47, 47, 67, 34,145,180, - 59,127,254,124,160,217,108,134,147,147, 19,156,156,156,112,248,240, 97,184,184,184,224,211, 79, 63, 77,209,235,245,151,229,114, -185,183, 94,175,191,151,153,153,249,117,117,174,183,213,106,133, 86,171, 69, 65, 65, 1,242,243,243,161, 86,171, 97, 48, 24,170, - 76, 99,121,180,107,215, 14, 7, 15, 30,228,207,159, 63,255,183,132,132,162,138, 96, 72, 72, 8, 62,253,244, 83,190,191,191, 63, - 18, 19, 19,113,243,230, 77,152,205,102, 84, 21,126, 22, 10,133,157,166, 76,153,210, 54, 40, 40,136,152,205,102,112, 28, 7,163, -209,136,146,223, 83, 82, 82, 80,175, 94, 61, 94,112,112,112,107, 66, 72, 39,123, 6, 76, 48,138, 80,103,111,135,171, 40, 0,224, -187,129, 83,175,128,246, 5, 39, 35,201,206,206,158, 55,114, 28,255,189,195, 91, 11,189, 99, 31, 57, 34, 48,228, 77, 4,212, 26, -128, 49,239,218, 48,235,219,131,240, 15,140, 64,114,114, 50, 58,117,234, 36, 74, 79, 79,127, 23,192, 84,123,181, 79,156,184,106, - 59,126,248,200,144,161,195,223,110,214,181,107,111,235,177, 99,135, 17,117,239, 88,244,187,195, 95,207,166, 92, 33,113,113,145, -221,126,244,232, 97,104,100,100, 83,152, 45,150,118,192,172,133, 0, 42,124,168, 60,126, 76, 77,179,103,207,230, 29,218,187,254, -205,145,163,222,105,212,165, 75,119,203,177, 19, 7,112,243,202,137,187,139, 23,142, 57, 55,127,217,246, 78,221,122,190, 94,223, -193,233,234,225,200,250,250,247, 3,157,130, 30,179,146, 82,193,203,202,193,129, 67,241,115,145, 71, 8, 40,165,207,152,171,231, - 13, 22,143,199,171,178,226, 95, 86,179,236,187,168,164, 34,189,106,213, 42, 72, 36, 18,136,197, 98, 8,133,194, 42,187, 89,148, -213,140, 78, 76,236,188,113,203, 22, 73,121,230, 42, 47, 47, 15,121,121,121, 40, 44, 44,196,136, 17, 35, 68,179,111,220,104, 90, -149,102,144,175,175, 81, 46,149,102, 61,120,240,192, 47, 34, 34,226,153,244,170,213,106, 72,165, 82,108,217,186, 85,212,183, 79, -159, 9, 93, 14, 31, 94, 12, 64, 89,221,188, 19, 66,224,229,229, 5, 87, 87, 87, 16, 66, 96,181, 90,145,153,153,137,232,232,104, -220,184,113, 3,124, 66,172,127,231, 53, 46,207,139,188, 10, 17, 44, 82, 81,180,197, 94,131,197,231,243, 95, 40,138, 85, 25,246, - 52, 17,202,100,178,251,233,233,233,109,252,253,253, 97,181, 90, 75, 13,214,243, 77,132, 37,209,142, 59,119,238, 64, 38,147,221, -175, 74,147, 82,218,186, 69,139, 22,216,189,123, 55,206,156, 57,131, 39, 79,158, 64,167,211,193,104, 52, 66,175,215, 35, 58, 58, - 26, 28,199, 33, 50, 50, 18,114,185,188, 74, 77, 0,208,106,181, 25, 66,161, 48, 76, 42,149,254,167,185,195,215, 23,121,121,121, -156,197, 98,193,198,141, 27,213, 62, 62, 62,114,169, 84,106,183, 97, 37,132, 32, 59, 59, 27, 1, 1, 1,165,125,176, 52, 26, 13, -188,188,188, 74, 12, 5,140, 70, 35, 28, 29, 29,171,108, 34,164,148, 26, 0, 76, 41,163,221,124,232,208,161,191,111,219,182,173, -214,201,147, 39,113,237,218, 53,120,122,122,226,187,239,190,123,146,148,148, 52,146, 82,122,227,111,184,193,170,220, 39, 47, 47, -111,215,253,251,247, 91,183,104,209,162,244,233,208,169, 83, 39,210,169, 83, 39,143,178, 33,253,156,156, 28, 92,191,126, 29, 39, - 79,158, 4, 33, 4,241,241,241, 54,189, 94,255,123, 37,223, 45, 10, 14, 14,222, 48,125,250,116,133,213,106, 45, 45,219, 82,169, - 20, 14, 14, 14, 16,137, 68,224,243,249, 72, 74, 74,194,128, 1, 3,156,127,254,249,231,245,132,144,218,148, 82, 51, 94, 17, 10, - 57,165,245,250, 29,189,139,171,107,240,189,203,231,214,183,126,173,248, 25,113,249,220,122,171,171,107,240,189,235,119,244, 46, -237, 3,149, 86, 69, 21, 58,123,143,228, 76, 53,155,111,244, 60,122,228,254,160, 41,147,199,136,131,107,133,100, 93,186,118, 63, -248, 53,219, 20,158, 92, 10,104,245, 64,190, 18,136,121,204,231,130,107,133,100,221,184, 21, 43, 94,252,227,218, 16,157,222,180, -231,240, 41,229,209, 42, 42, 99, 6, 66,200,192,143,191, 18,158,123,123,180,151, 88,228, 16, 8, 77,193, 45,212, 8,118,199,176, -215,195,176, 98,245, 45, 56, 57,185,193,219,219, 27, 60, 30, 79,110,111,222,115,115,115,201,174, 63, 46,188,247,214, 59, 99, 90, -245,232,222,199,122,244,216, 33,193,153,227,251, 47,175, 95,253,213, 30,202,215,202, 8,213, 72, 3,131, 2,238, 37, 62,137, 27, -217,190,125,119, 72,197,178, 58, 64,120,185, 5,182,116,224, 0, 69, 10,143, 7,135,183,222, 25,251, 90,143, 30,253,173,199,142, -237,197,177,195,155,174,206,156, 89,227,240,147,167, 91, 69, 87,110,164, 57, 12, 28,242, 65,193,193, 35, 15, 77,175,247,171, 25, -231, 39,111,172, 7,227,217, 10,164, 64,144,101, 53, 26, 3, 3,122,244,224,235,146,147,133, 10,111,111, 43, 0, 88, 44,150, 42, - 13, 22, 0,206, 30, 77,123,211,162,211,233,192, 1, 86,123, 52, 51,179,179,107, 20, 87,190, 75,177, 88, 44,165,230, 42, 47, 47, - 15, 74,165, 18,114,185, 28, 57, 70,163,183, 61,154,221, 91,182,220, 56,123,214,172,169, 59,119,237, 18,149, 53, 87, 37,155, 80, - 40,196,247, 11, 23,138, 62,249,236,179, 15, 38, 8, 4, 19,171,115, 62, 75, 42,235,124, 62, 31, 2,129, 0,201,201,201, 72, 73, - 73, 65,114,114, 50,146,147,147, 33,149, 74, 65, 43, 56,159, 47, 49,130, 69, 94,165,178, 91,233, 52, 13,213,233,228,110,175, 33, -176,217,108, 47,213, 96,105,181,218,147,167, 78,157,106, 57,112,224, 64,193,213,171, 87,225,227,227, 83,106,176, 74,126,150, 52, - 59,201,100, 50,236,217,179,199,172,213,106, 79, 86,113, 19,157, 58,124,248,112,179, 25, 51,102, 8, 71,143, 30,141, 7, 15, 30, - 96,220,184,113, 80, 42,149, 80,171,213,200,203,203,131, 78,167, 67,203,150, 45,225,224,224,128,123,247,238, 89,116, 58,221,169, - 42, 10, 14,205,206,206, 46,244,244,244,244,125,254,127, 67,134, 12,241,254,229,151, 95,116, 49, 49, 49,150, 54,109,218, 56,217, -107, 52, 74,248,227,143, 63, 74, 35,115,113,113,113,248,229,151, 95, 74,251, 92,221,186,117, 11,139, 22, 45, 42,157,187,172,154, -133,253, 70,253,250,245,173, 22,139, 5,117,234,212,129,191,191, 63, 12, 6, 3,150, 46, 93,106,253, 59,204,149,189, 24, 12,134, -157,111,191,253,246, 23,183,111,223,246, 21, 8, 4, 69,161,235,226,252,153,205,102, 60,122,244, 8,209,209,209,136,137,137, 65, -126,126,126,105, 5,224,206,157, 59, 5, 22,139,101,123, 69,186,158,158,158, 95,175, 91,183,206, 71, 38,147, 61, 83,158, 75,162, -159, 37, 81,209,156,156, 28,184,184,184,160, 75,151, 46, 94,167, 78,157,250, 26,192,140, 87,225, 97, 64, 8, 33,109, 90, 41,218, -126,252,193, 59,104,209, 84,243,248,254,173, 40,156, 56,188,172, 33, 80,212,201,189, 65,211,200,199,215,111, 59,162, 87,247,169, -109, 47, 93, 29, 87,105, 39,247,226, 62, 84,135, 91,182,116,187,184,119,255,201, 21,211, 38,143,185,254,205,172,105, 94, 6,163, -214, 33,188,182,141, 7, 20,153,171, 43,183,229,134,185,179,198, 92, 95,240,227, 70, 46, 37,219, 60,233,218,181,130, 10, 71,247, -150, 53, 45,245,235,194,193, 39,184, 79,122,112,173, 78, 53,239,223, 90, 11, 15,231, 2, 56,214,105,131, 94, 61, 90,226,228,169, -251, 72,126,106, 64, 70, 70, 6,140, 70, 99,165,211, 30,196,220,219,243, 38, 37, 52,136, 80,146, 66,120,212,225,205,183,223,111, -215,167, 79,127,122,240,224,126,235,222, 61, 91, 46,110,223,188,124, 39, 79, 36, 20,232, 77,206, 38, 66, 12, 42,142,231,248, 64, -171,205, 43,122,120,138, 68, 21,135, 91,139, 39,100,141,168, 31,238,243,230,219,227,156,123,247, 26, 64, 15, 31,222,203,109,223, -182,241,204,246,181, 13,182,112, 60,181, 40, 35, 85, 39, 81,169, 45, 42, 74,196, 46,133,106, 78,151,149, 80,219,224,215,103,136, - 25,140,103,223, 3, 70, 99, 90, 97,106,170,175, 91,135, 14,146, 71,179,102,201,188, 91,182, 52,144,226, 62,194,149, 25, 44, 62, -159, 15,240,120,156, 61,154,246,166, 69,175,215,131, 3, 44, 47,162,105,181, 90,159, 49, 87, 37, 6,171, 36,158, 97,143,230,234, -153, 51,175, 6,245,232,145,127,246,236, 89,239,142, 29, 59, 18,141, 70, 3,141, 70,243,140,201,242,243,243, 35, 17,145,145,178, - 63,206,156, 9,153, 97,231,249,180, 39,239, 60, 30,239,111, 55, 88,175, 92,212,181,178,127,150, 68,176,236, 49, 88,118, 70,176, - 44, 22,139, 5, 94, 94, 94,200,205,205,173,240,133,207,227,241, 32,149, 74, 75,218,128, 43, 29, 73,103, 52, 26,151, 78,157, 58, -245,163, 94,189,122,121,132,133,133, 33, 39, 39, 7,222,222,222,112,112,112, 40,237, 27, 86,162,119,235,214, 45,172, 91,183, 78, -109, 52, 26,151, 86,161,185,100,225,194,133, 31, 14, 30, 60,216,205,199,199, 7,174,174,174,184,119,239, 30, 92, 93, 93,161, 86, -171, 17, 27, 27, 11, 71, 71,199,210,126, 57,251,247,239,215, 24,141,198, 37, 85,152, 54,122,254,252,121,179,163,163,227,189,156, -156, 28,126,126,126,190,160,160,160, 64,160, 86,171,133, 42,149, 74,120,244,232, 81, 15,103,103,103,221,233,211,167,115,130,130, -130,248, 79,158, 60,225, 91, 44, 22,158, 29, 47, 69, 76,156, 56, 17, 34,145, 8, 70,163, 17, 75,151, 46,197,212,169, 83, 75,251, - 92, 45, 92,184, 16,211,167, 79, 47, 53,204,107,214,172,169,174,201,130,217,108,134,197, 98,129,197, 98,177,203,244,254, 21,236, - 49,234,148,210, 76, 66, 72,223, 22, 45, 90, 28,223,177, 99,135,123,241,156, 98,200,202,202, 66, 86, 86, 22,114,114,114, 80, 88, - 88, 8,171,213, 10,127,127,127,100,101,101, 97,239,222,189, 42,141, 70,211,163,178, 17,132,124, 62,255,237,118,237,218, 9,158, - 79, 67, 73,173,174,196,180, 75, 36, 18,164,167,167,163, 83,167, 78,226,179,103,207,190,253,191,110,176, 74,140, 75,189, 80,136, -250,245, 31, 33,106,220,172,167,238,250,205,163,201, 82, 98, 77,238,221,181,206, 14,160,104,154,134,235,183, 29,209,184, 89, 79, - 94,191, 12, 83, 75,101,193,234,198, 17,117,137,185,178,101,117, 0,192,195,153, 27,208,163,107,141, 12, 39, 39, 34,152, 59,107, -193,129,223, 54,173,105,113,229,143,255, 76,211, 48,119, 86,209, 52, 13, 61,186,214,176, 62,136,137, 27, 0, 96,147,189,166,165, -111,223,126,183, 87,175,221,140,180,132,253,126, 43, 22,184,136, 97, 40, 0,132, 97,104,215,202, 9,215,126, 74,193,221,187,119, - 51, 77, 38, 83,167, 74,203, 18,161, 65,209, 15,162,234, 54,168, 31,225,243,230,219, 99,157,250,246, 29,128,131, 7,247, 97,243, -198,181,231, 95, 31, 49,248,183,167, 5,106,190,151, 80, 38,146, 81, 78,204, 23, 57, 11, 28,100,178,108,115,122,122,209,195, 83, - 32,116, 2,134,114,149,180, 16, 98,252,216, 81,206,157,187, 14,192,161,195,251,176,121,227,234,115,223,212, 31,178,182,102,147, -122,164,101,211, 31, 62,168, 89,171,102,176,182, 48, 75,205, 35, 98,179,193,192, 57,254,176, 49,233,199,132,233,111, 39,220,142, - 26,186,152,141, 34,124,134,123,155,123,247,110,241,201,227,199, 34,207,182,109,165,233,103,206,200,138, 87, 14,169,212, 96, 9, - 4, 2,208,138,155,180,158,209, 36,155, 54,241, 0, 84, 58,184, 74, 36, 18, 65,167,211,193, 2,152,237,209,244, 61,118, 44,245, -241,227,199,161,110,110,110,207,152,171,252,252,252,210,223, 13, 6, 3,116, 58, 29,164, 82,105,180, 61,154, 89,231,207, 27, 22, - 76,156, 56, 99,228,136, 17,203, 79,158, 58,229,224,238,238, 14,149, 74,245,140,193, 50,153, 76,232,220,165,139,104,225,237,219, -111, 2,152,105,207,249,244,238,212,169,202,254,190,124, 62, 31,220,223,220, 68,248,170,193,171,170,169,198,222, 81,132,229,189, - 24, 9, 33, 93,159,251,104,122,179,102,205, 12,113,113,113, 8, 10, 10, 42, 53, 41,101,191,211,201,201, 9, 46, 46, 46,184,117, -235, 22,230,205,155,167, 7, 48,189, 50, 77, 74,169, 70,167,211, 13,239,214,173,155, 94, 32, 16, 32, 60, 60,188,116,254, 43,142, -227, 32, 22,139, 33,151,203,113,251,246,109,244,235,215, 79,167,211,233,134, 63, 63, 7, 86, 57,154, 42,157, 78,247, 70,247,238, -221,117, 15, 30, 60, 64,187,118,237,112,247,238, 93, 20, 22, 22,162,176,176, 16,137,137,137,136,136,136,128, 78,167,195, 47,191, -252,162,215,233,116,111, 80, 74, 85,149,105,106, 52,154,126, 83,167, 78,229,255,254,251,239, 53,253,253,253,235, 55,111,222, 60, -172, 75,151, 46,181, 7, 13, 26, 20,220,187,119,111,223,208,208, 80, 67,143, 30, 61, 60,123,245,234,229,169,211,233,132,151, 46, - 93,202,176, 88, 44,189,170, 56,159,165,166, 36, 46, 46,174,180, 73, 80, 32, 16, 32, 55, 55,183,116,166,253,146,135, 81,121, 6, -184, 34,205,178, 38,187,196, 88,149, 24,173,170,158,253, 21,104, 86,249,194, 16,139,197, 37, 17, 78, 90,149, 38,165,244,206,195, -135, 15,187,117,232,208,225,206,123,239,189,167,201,204,204,132,163,163, 35, 66, 66, 66, 80,183,110, 93,120,120,120,192,108, 54, - 99,207,158, 61,218,189,123,247,222, 87,169, 84,157,158,159, 3,235,121, 77, 30,143,151, 88,222,195,181, 36,122, 85, 98,176, 28, - 28, 28,224,239,239, 95,114,110, 19,171,115, 62, 95, 48,178,244,247,106, 22, 27,151, 46,157,123,212,234,221,103,160,243,222,253, -251,100, 63,253,186,225, 97,251, 1, 31,173,244, 8,158,178,219, 35,120,202,238,246, 3, 62, 90,249,211,175, 27, 30,238,221,191, - 79,214,187,207, 64,231, 46,157,123,212,122, 16, 29, 19,246,204,186,132,229,164, 83, 38,150,180,108,223, 38, 84,121,254,210,121, -235,130, 31, 55,218,218,188,214,251,218,242,229, 43,183, 47, 95,190,114,123,155,215,122, 95, 91,240,227, 70,219,249, 75,231,173, -237,219,132, 42,101, 98, 73, 75,123,242, 62,126,236, 40,231, 62,189, 7,224,224,193, 61,214,157,127,252,178,112,205,230,244, 14, -157, 6,165,101, 37, 38,220,160,208,109,128,135,227, 61, 60,124,248, 80,101, 50,153, 58,149,215,193,189, 60,205,113, 99, 70,149, - 53, 87, 23,220,125,218,173,121,248, 16,182, 19, 39, 14, 88, 78,157,186,173,191,112, 39, 91,117,243, 65,110,126,158,218,240, 68, -171, 81,155, 56,142, 3,229,108,252,217,179,139, 58,226, 86,116,141,218,180,233,136,211, 39,183, 98,227,134, 85, 42,142,131, 97, -200,142, 29,182,161, 67,103,209,224, 26, 53,130,183,252,177,149,244,237, 63,208,153, 2, 92,191,193, 3, 92,126,223,246, 59,169, - 85,167, 86,141,144,144,162,169,105,254, 39,203,210,223,160, 57,147,210, 2,117,114,242,185, 91, 63,255,108,244, 30, 62,220, 77, -236,237,237, 4,155,141,148, 60,223, 43,218, 4, 2,193, 51, 17,151,202, 52,253, 61, 60,158,238,223,191, 31,117,235,214,133,191, -191, 63,202,246,129, 45,153, 72,219,221,221, 29,187,118,237, 2, 5,110,218,163,217,164,102,205, 91,223, 47, 88, 96,226, 56, 14, - 5, 5, 5,127,138, 94, 21, 20, 20,128,227, 56, 28, 62,116,200,164, 46, 44,220,104,111,222, 59,241,249,133, 35,219,183,159,223, -167, 79, 31,243,227,199,143,193,113, 28,202, 70,178,178,179,179,161, 80, 40, 96, 48, 26, 3, 9, 33, 50,123, 52,179,143, 30,149, -163,138,231,250,243, 17,172,191,227,186,255,171, 34, 88, 86,171, 21,129,129,129,207, 44,189,194,227,241,158,217,170, 51,130,144, - 82,186,137, 16,114,172, 71,143, 30, 51, 90,181,106, 53,126,198,140, 25,252,176,176, 48,168, 84, 42,184,186,186,194,203,203, 11, -177,177,177,216,191,127,191, 45, 55, 55,119, 37,128, 57,246, 12,133,167,148,158, 33,132,244,109,216,176,225,182,105,211,166, 57, -119,239,222, 93, 24, 24, 24, 8, 74, 41,110,223,190,141,221,187,119,155,215,174, 93,171, 46, 54, 87,103,236, 76,235,113, 66,200, -235,189,122,245,218,242,246,219,111, 59,218,108, 54, 97, 98, 98, 34,140, 70, 35, 44, 22, 11, 82, 82, 82,204, 7, 15, 30, 44,212, -233,116,163, 40,165,199,237,208,187, 69, 8,137, 56,113,226,196,219,151, 46, 93,154,247,222,123,239,185,119,233,210, 69,100,181, - 90,113,241,226,197,156, 38, 77,154,120,101,103,103,155,119,237,218,149,103, 48, 24,166,219,108, 54,187,150,202, 33,132, 64,173, - 86,195,195,195, 3, 70,163, 17, 28,199,193,100, 50, 65,161, 80,148, 46,111, 68, 41, 69,117, 58,205, 63, 87, 6,248,102,179, 25, - 35, 70,140, 0,199,113, 88,186,116, 41,172, 86,107,181,197,156,157,157,111,222,185,115,167,111,227,198,141, 75, 77, 75, 73, 25, -146, 72, 36,240,240,240,128,187,187, 59, 14, 30, 60, 8,161, 80,120,211,206,107,116, 23, 64, 19, 66,200,107,247,239,223,127, 11, - 64, 99,179,217,236,111,179,217, 8,143,199,203,160,148,222, 83,171,213,191,217,187, 84, 78,118,118,246,188,119,222,121,167,201, -214,173, 91, 21, 2,193,127,110, 13,129, 64, 0,137, 68,130,146, 73, 45, 41,165, 48,153, 76,248,250,235,175,213, 90,173,118,222, -171,242, 48,104,214,188, 37, 86,255,178, 76,113,234,244,177,156,135,241,216, 87,118, 42, 6, 5,128, 75, 87,199,237, 83, 22,172, -110,156,158,154,170,104,214,188,165, 93,154, 38,155, 53,111,248,168,149,129,197, 75,229,204, 75,124,146,188,100,235,134,247, 19, - 0, 96,241,143,107, 67, 82,178,205,147, 30,196,196, 13,248,117,229,217,150, 38,155, 53,207, 30,205,255,152,150, 45, 42, 80, 24, - 40,165,215, 8, 33, 53,195, 94, 51, 76,143, 12, 23,245, 79,207,178, 60, 45, 44, 52,125, 76, 41, 77,176, 55,239,109,219,116,192, -233,227,191, 99,243,198, 45,106,202,241, 13, 30, 30, 30, 20, 0, 30, 62,244,160, 15, 31, 42,233,127,250, 11,187,104, 61,101, 57, -115,166,127, 57,126,178, 70,163, 89,178,226,135,202, 39,156,109,216,168, 21, 26, 54,106,133,143, 62,254,202, 57,162,126,120, 16, - 0,236,216, 65,109,145,161,228,192,140,111,102,245,159, 51,103, 22,212, 26, 35,230,204, 41, 90, 86, 39, 54,234,193,161,199,143, -169,137,189,154,158,101,134,213,122, 13,147, 39,135,234,242,243, 61,219,126,241,133,135,224,179,207,120,149,117,114, 47,123,255, -218,163,121,227,222,189, 67,227,222,127,255,233,204, 25, 51,122,172, 92,181, 74,218,160, 65, 3,100,102,102, 34, 60, 60, 28,254, -254,254, 56,113,226, 4,118,109,223,174, 85,106, 52,211, 1,252,106,143,230,166,195,135, 99,195,234,215,207, 93,181,106,149, 95, -159, 62,125,136, 86,171,133, 74,165,130, 74,165,130,209,104, 68,241, 68,206, 52, 46, 62,254,161,197, 98, 89,105,111,222,109, 57, - 57, 14,115, 90,182, 76, 19,113,220,247,175, 15, 30, 60,117,206,220,185,146, 90,181,106, 17,163,209, 88, 26,197, 50,155,205, 80, - 40, 20,102,147,201,228, 14, 64,103,143,166,100,237, 90,107, 78, 78, 14, 60, 61, 61, 75,167, 93, 42, 59,175,160, 70,163, 1,165, -108, 18,220,106, 85, 20, 42,122,135,187,185,185,221, 20, 8, 4, 1,101,163, 89,229,173,109, 87,246, 51,139,197,146,150,147,147, -211,172,172,195,165,148,158,172,192, 24,132, 0,248,174,115,231,206,175, 79,153, 50,133,156, 61,123, 22,123,247,238,165, 9, 9, - 9, 59, 1, 76,175,232,225, 88,133,166,163, 68, 34,249, 84, 46,151,119, 45,153,138, 65, 38,147,221,215,106,181, 39,141, 70,227, -210,138,102,111,175, 66,211, 73, 34,145, 76,148,203,229,221, 52, 26, 77, 99, 0,112,116,116,188,163,213,106, 79, 24,141,198,101, - 21, 45, 32, 93,133,166,212,217,217,121,158,135,135,199, 27,159,125,246,153,251,249,243,231, 51, 78,159, 62, 45, 82, 42,149, 91, - 77, 38, 83,133,139, 61,151,167,233,238,238,126,147,207,231, 7,252, 29,215, 8, 0, 26, 53,106,116,176, 95,191,126,125, 70,141, - 26, 5,139,197,130, 95,127,253, 21, 39, 78,156, 56, 20, 31, 31,223,183,178,218,231,243,154,132, 16,143,128,128,128,179,227,199, -143, 15, 30, 49, 98,132,204,213,213, 21, 2,129, 0, 90,173, 22,143, 30, 61,194,237,219,183,233,190,125,251, 10,111,221,186,149, -166,211,233, 58, 82, 74,115,237, 61,159,127,165,150,252,188,166, 80, 40,236, 16, 24, 24,248,199,204,153, 51, 29,187,117,235, 38, -117,119,119, 7,159,207,135,197, 98, 65, 70, 70, 6,162,162,162,112,236,216, 49,237,206,157, 59,181,121,121,121, 35,158,159,171, -229,255, 43,157, 47, 83, 51,162, 46,249,230,185, 5,156, 43,156,157,189,178,125,237, 73,103,159,174,174,189, 95,127,189,121, 87, - 0,216,181,235,198,201, 67, 39, 11, 14,191,104, 58,171, 74,171, 61,154,245, 66,249, 51,163, 31, 68, 61, 51, 17,101,253,136,200, -184,122, 13, 6,127,107,143, 86,201, 76,238,207,231,189,204,236,248,101, 99,184,207, 52,167,150, 44, 8,253,213,244, 47,241,221, -188,249,216,183, 99,207,161, 7,143,233,193,255,229,178,244,119,106,150, 44, 78, 44,243,245,109,191,148,227,190,188, 27, 21,165, - 40, 91, 81, 43,137, 52,151,173, 76,250,249,249,101,167,167,167,123,219,163,217,247,167,159,204, 58,185, 92,242,229,247,223,119, - 40, 52, 24, 58,204,153, 51, 71,112,227,198, 13,252,242,243,207, 86, 67, 90,218,150, 28, 96, 98,121,173, 31,149,105, 6, 79,156, -232,240,249, 47,191,140, 14,169, 83,199,235,173,183,222, 18, 10,133, 66,104,181, 90,164,166,166,226,248,177, 99,166, 7, 15, 31, - 62, 80,171,213,253, 41,165,233,246,106,246,253,233, 39,179, 75, 72, 8,100,158,158,244,212,153, 51,206,227, 62,253,116,124,141, -154, 53,157,123,244,236, 41,116,114,114, 66, 65, 65, 1, 18, 19, 19,177,103,207,158,236,194,194, 66, 63, 74,169,205, 30,205, 45, -151, 46, 53, 60,124,238,220,144,111,191,253, 86, 28, 25, 25, 9,103,103,103,104, 52, 26, 68, 69, 69,225,220,185,115,198,149, 43, - 87,170, 84, 42,213,120,171,213,186,255,239,186,238,255, 26,131,245,255,117,227, 17, 66,154, 1,248,166,248,207,185,118,172,233, -247,202, 60,116, 8, 33, 65,110,110,110,171, 13, 6, 3,213,235,245,227, 40,165, 41,255,180,116, 18, 66, 4,205,154, 53,251, 37, - 59, 59,251, 53, 74, 41,156,157,157, 47, 71, 71, 71, 79,160,148, 90,171,171, 73, 8,225, 3,120, 77,161, 80,180,116,116,116,236, - 96, 52, 26,235, 21, 55,179, 61,212,106,181,231,204,102,243, 53, 0,151, 41,165,182,255,102,222,139,211,217,205,207,207,239,125, -142,227,234, 16, 66, 92,108, 54, 27, 44, 22,139,146,227,184, 71, 42,149,106, 45,128, 19,255,237,116,190, 44,205,250,117,200, 32, -202, 67,189,138,140,192, 51,134,230, 57,227, 64, 56, 60,140,126, 68,247, 84,163,204,243, 6,246,242, 92, 4, 20,141, 52,172,106, -201,161,103, 12,150, 29,166,165,218,230,178,142,224, 29, 74,104,208,179, 15, 69,146, 18,222,112,208,230,191, 98,176,236,165,126, - 24,233, 0,138,215, 56,138,107, 15,227,233,233, 87,245, 89,247, 50, 53,231, 19,226,246,179,171,235,101,158, 64,224, 3,128, 87, - 28,109,225, 56, 66,108,148, 16,107,217,102,172,178, 21,202,170, 52,205, 64, 3,161, 68, 18,104,179, 90,189, 51, 1,197, 97,155, -173,169,129,210,194, 0,224,155,219,148,198,190, 72, 58,205, 64, 3,190, 68, 18,116,152,210, 1, 57,114,121,195,108,189,222, 19, - 0, 85,200,229, 15,213, 90,237, 70,131,193,176,162,156, 69,213,171,212, 20, 73, 36, 1, 54,171,213, 27, 0,120, 2, 65,246, 54, -163, 49, 48,205,201,233, 45,131,209, 24,172, 80, 40, 44, 38,147, 73,109, 48, 24, 70, 89, 44,150, 83,213,201,251, 35,171, 53,226, - 18,143,215,206, 44,151,187,155, 9,145,155,172, 86,179,201,108, 78, 53, 24, 12,247, 1,252, 72, 41,125,252,119, 94,247, 87,142, -146,209,102,127,199, 6,160, 43,211,100,154, 76,147,105, 50, 77,166,201, 52,255,126, 77, 0, 50, 0, 65, 0,248,255,139,121,127, -213, 54, 1,179,152, 12, 6,131,193, 96,188, 18, 1, 19, 29,202,233,115,197,248, 47, 53, 17, 2,232, 90,193,133,178, 59,244,247, - 34,163, 9,236,104, 74, 96,154, 76,147,105, 50, 77,166,201, 52,153,230, 43,166, 89,149,246, 43,211,244,200,154, 8,153, 38,211, -100,154, 76,147,105, 50, 77,166,201,154, 8, 95,238,198, 3,163, 34,103,237, 77, 8,241,126,217,251, 50, 94,237,178, 80,206,177, -254,132, 16,255,106,238,239,203,206, 58,131,193, 96,252,111,243,255,110,176,236,125, 89,253,197,151,218, 95, 50, 60,132,144,249, -132, 32,189,104, 35,243, 95,214,190,118,124,175,159,167,167,231, 39,245,235,215,223,226,227,227,243, 17, 33,196,171,154,199,135, -202,229,242,101, 10,133,226,172, 66,161, 56, 43,151,203,151, 17, 66, 66, 95,210,117, 35,132,144,113, 14, 14, 14,103,252,252,252, -158, 74, 36,146, 51,132,144,241,228, 5, 23,160, 36,132,212, 38,132, 76, 38,132, 76, 33,132,132, 85,231, 88,239,200,129,219,189, - 34, 7,222,243,138, 28, 24,229,209,160,127,168, 87,228,192, 40,175,200,129,247,188, 35, 7,110,255, 27,202,235, 11, 95,223,226, - 99, 83,138,182,170,143, 37,132,252, 72,128, 84, 66,144,246, 87,203, 18,131,193, 96, 48,254,187, 84,171,147,123, 64, 64, 64, 47, -142,227, 70, 2, 0,143,199,251, 61, 45, 45,237,200, 11,188,112, 62, 47,254,125, 33,165,244,203,191,178,159, 29,199, 46,161,148, - 78,173,190, 57,195,231, 28, 71,121, 69,249, 36, 95,120,123,123,203,248,124,254,159, 58, 14,218,108, 54, 25, 33,248,136,227,138, - 22,168,228,241,200,231,132,144,101,148,210,172, 23, 49,133,111,190,249,230,146,101,203,150, 57,200,100, 50, 36, 39, 39,119, 31, - 63,126,124, 27, 66,200,100, 74,105, 70, 85,199, 75,165,210,145, 45, 90,190, 54,249,251, 31, 22, 43,188,189,188,228, 86, 27,103, - 78, 76, 78,146,125, 61,109,106, 75,169, 84,186,172,178, 69,142,159, 55, 82, 0,198, 10, 4,130, 97, 14, 14, 14,181, 13, 6,195, - 99,171,213,186,147,207,231,247,152, 55,111, 94,100,239,222,189, 29,212,106,181,216,106,181,214,217,188,121,243,228,117,235,214, -245, 34,132, 12,168,108,184,125, 73, 4,135, 82,250,180,204,199,189, 82, 82, 82, 26, 8,133, 66,212,174, 93,155, 0,136,173, 98, -255, 82, 40, 16, 26,125,113, 71, 3, 0,168,223,118,104, 92,244,197, 29, 40,254,253,111,168, 12, 60, 91, 22,164, 82,233,175,122, -189, 62,181,228,255,197,233,204,178,231, 88, 66,200,242,226,101,126, 34, 1, 12, 46,222,117, 55,165, 52,138, 16,226,227, 32,145, -124,170, 55, 24, 8, 0,242, 87,202, 18,131,193, 96, 48,254,199, 12, 22,165,244,173, 71,143, 30,201, 56,142, 67, 88, 88,216,155, - 0,236, 54, 88,229,189,112,186,116,233,210, 68, 42,149, 62, 51,107,177, 94,175, 23, 19,130, 46, 47, 98, 90, 74,190,195,100, 50, -242,132, 66, 49,120, 60, 50,185, 97,195,134, 53,114,115,115,207,243,120,188, 45,105,105,105, 5, 47,240,146,197,154, 53,107,234, -250,250,250,254,105,118,229,140,140, 12,241,128, 1,253,171,165, 55,154, 16,137, 81, 34,105, 41, 34,196,215,102,181,186, 0,128, - 64, 32, 40, 8,115,118,110,246,221,183,223,202, 8, 33, 92, 94, 94, 30,244,122, 61, 38, 77,154, 36,125,240,224,193, 64, 0, 43, -170, 72, 99,221, 86,173,219, 76, 58,118,236,104, 61,117,126,129, 97,205,146, 85,183,244, 2,145,174,102, 68,184,232,151,213, 27, - 93,199,142, 30,245, 49, 33,228, 78,121,203,134, 60,167,195, 3,176,231,211, 79, 63,173,223,183,111, 95,177, 70,163,113,208,235, -245, 53,182,108,217,242,117,179,102,205, 20,141, 27, 55, 22,255,241,199, 31, 68,165, 82,129, 82, 42, 11, 15, 15,167,195,134, 13, - 51,108,219,182,237, 35, 0,203,237, 49,188,190,190,190, 51,138, 13,122,217,178, 39,244,243,243,147, 22,159,211, 57,132, 96, 82, -101,230,154, 0,241,245,219, 14, 5, 8,234, 68, 95,220,225, 80,191,221, 80, 3, 40, 30, 17, 32, 30, 0,252,253,253,231, 0,101, -230,117,122,150,135, 79,159, 62,125,161,181, 3,251,244,233, 11, 0,191,250,251,251, 31,204,202,202,138, 36, 4,227,236,173, 4, - 16, 66,224,238,238,254, 58,128,159, 0, 12,143,137,137,169, 15, 0,225,225,225, 66, 0, 81, 46, 46, 46, 77,141, 69,230,138,193, - 96, 48, 24,255, 66,131, 37, 2,128,243,231,207,131, 82, 42,126,145,160, 64,217, 23,206,196,137, 19,225,235,235,251,188,105,193, -217,179,103,254, 74,158,158,249,142,185,115,231, 42,148, 74,101,215,223,126,251,173,189,191,191,255,162,167, 79,159, 94,173, 34, -143, 89,132,144,133,197, 17, 7, 72, 36, 14,113,227,199,143,191, 93,252,239, 26, 7, 14, 28,144,245,235,215, 79, 7, 32, 9, 0, - 36, 18, 7,127, 62,159, 87,183,168, 83, 27, 22, 86,102, 4,135, 18, 18, 34, 22,139, 59,143,251,233, 39,107,211,126,253, 4,114, - 79, 79, 2, 0, 73, 49, 49,238, 11,127,248,161, 77, 65, 66,130, 88,239,238,158,151,167,213,234,227,226,226, 32,145, 72, 8,159, -207,111, 90, 85,134,229,114,249, 39,223,126,247,189, 92,157,175,212, 27,212, 26, 19,223,106, 49, 58, 74,101,182,172,204,236, 60, -133, 84,174,251,226,155, 89,226, 15,199,188,253, 9,128, 9, 85, 72,125, 52,121,242,228,122, 45, 90,180,240,223,190,125, 59, 81, -169, 84, 16, 8, 4,138,198,141, 27,163, 89,179,102,182,211,167, 79,147,154, 53,107, 34, 50, 50, 18, 23, 47, 94,196,229,203,151, - 73,147, 38, 77,100,187,119,239,126,179, 60,131, 85,142,169,158,220,186,117,235, 64,133, 66, 97, 80,171,213,120,239,189,247, 0, - 0,221,186,117,171, 43,151,203,127, 45, 44, 44,116,216,191,127,223,235, 85,153,235,172,168,189,195, 0,192, 43,114,224, 61, 0, - 13, 64,241, 40, 59,106,111,195, 50,187,212,139,141,141,109, 85, 80, 80, 80,218,217,176,100, 97,241,246,237,219, 87,167,188,103, - 17, 66, 22,246,235,215,247, 11,128,160, 83,167, 78, 89, 19, 39, 78,164, 81, 81, 81,131,134, 14, 29,210, 37, 62,254, 81,133,233, -124,190, 28,141, 28,249,198, 19, 55, 55,183,110,126,126,126,241, 0, 4, 66,161,176,100, 87,190,191,191,191, 91,100,100,228, 8, -133, 66,145,200,231,241,106, 82, 80, 90, 85, 89, 98, 48, 24, 12,198,255,128,193, 34,132,208, 50, 47, 6, 82, 73, 45, 60,247,206, -157, 59,190, 6,131, 1,132,144, 92, 59, 94, 80, 39,203,190,112,248,124,254, 47, 60, 30,153, 64, 8, 65,100,100,131, 39, 75,151, - 46, 45,111,205, 45, 83,100,100,131, 39,124, 62,175, 22,165, 20,132,240,126,229, 56, 91, 86,121,154, 21,189, 16,197, 98,201,231, - 0,224,227,227,155,112,228,200, 17,211,144, 33, 67,240,195, 15, 63,136,166, 77,155, 54, 53, 56, 56,248,163,228,228,228,204,138, -210, 89,252,247,151,222,222,222,178, 53,107,214,212, 29, 63,126,252,237,244,244,244, 47, 1,192,207,207,111, 62,128, 8, 0, 73, -101, 62,195,202,149,219,158,142, 25, 51, 38, 46, 43, 43,235,203,138, 52, 95, 39,164,118,112,120,120,231, 57,231,207, 83,158,209, - 72,114, 47, 92, 80,231,100,101, 89, 30,231,228,200, 54,220,188,217,247,235,249,243,133,129, 65, 65, 56,187,127,191, 71,174, 78, -151,163, 50, 26, 13, 89, 89, 89,212,106,181, 94,182, 35,239,245,189, 60,189,100,171,126,252,245,134,163,144,207,121, 5,248, 19, -161,155,155,128, 39,115, 18,243, 5, 60, 99,173, 26,161, 98, 0,245,171,186, 70, 34,145,232,205,238,221,187,203,182,109,219, 70, - 34, 35, 35,225,226,226,130, 11, 23, 46,224,206,157, 59, 40, 40, 40,224, 89, 44, 22, 52,111,222, 28,223,127,255, 61,130,130,130, -160, 84, 42,145,146,146,226, 33, 22,139, 61, 43, 57,159,207, 24,222,169, 83,167, 34, 48, 48, 16, 86,171, 21,249,249,249,176, 90, -173,144,203,229, 0,128,164,164, 36, 28, 56,176,191,202,178,100,167, 57, 66,235,214,173, 53,132,144,135,207, 71,176,170,163,233, -235,235,187, 49, 39, 39,183, 73,167, 78,157,160, 82,169, 76, 51,103,206, 68,195,134, 13, 17, 26, 90,215,158, 50,255,165, 68, 34, - 89, 27, 20, 20,244,205,103,159,125,230,230,230,230, 6,163,209,248,113, 70, 70, 6,198,143, 31, 95, 28, 21,235, 19, 46, 16, 8, - 54,188,247,222,123,168, 81,163, 70,140, 70,163,137,189,115,231,206,180,194,194,194, 7, 47,154,119, 59,207, 15,211,100,154, 76, -147,105,254,163, 52,237,245, 34,255, 83, 6,139, 82, 74, 8, 33,180,170, 12, 81, 74, 11,252,253,253,125,165, 82, 41, 40,165,213, -110,110,179,217,108, 31,121,120,120,100,127,249,229,151,109,235,214,173,107,250,232,163,143,162, 18, 19, 19,167,151,221,167,102, -205,154,243,126,254,249,103,196,197,197, 37,205,159, 63,255, 98,110,110,238,220,106, 94,244,105,132,144,165,197,209,176,220,253, -251,247, 55, 60,127,254,252,132, 37, 75,150,120,126,248,225,135,162, 79, 62,249,100, 20,128, 31,170,210,225,243,249,186,242,154, - 5, 43,120, 9,155,202,235,163, 85, 66, 63, 66,164, 78, 98,113,167, 57,231,207, 83, 83, 82,146,110,221,226,197,142,171,174, 95, -159,105,161,212,219,203,203, 11,237,218,180, 41,116,224,243,115,179, 51, 51, 57,175,218,181,249,137, 71,142,120,232,197,226,244, -109,219,182,169,242,242,242,246,218, 81, 40,213, 28,165, 38, 69, 64,144,101,200,192,110,145, 55,174,221,137,113,244,242,224, 53, -105, 28,217, 48, 38, 46,233, 22, 56,206, 76, 8, 81, 87,165,227,236,236, 92, 55, 47, 47, 15,106,181, 26,158,158,158, 88,186,116, - 41,124,124,124,160,211,233, 16, 29, 29, 77, 3, 2, 2,200,249,243,231, 17, 16, 16,128,156,156, 28,152, 76, 38,104, 52,154,108, -163,209,168,175,200,240, 10, 4,130,181, 60, 30,121, 31, 0,106,212,168,249,240,215, 95,127, 53, 0, 64,189,122,245, 48,104,208, - 32,236,218,181, 11, 15, 30, 60, 0,199,113,160,148, 26, 2, 2, 2, 31,242,120,164, 94,177, 71,122,225, 40, 78,201, 18, 60, 79, -159, 62, 29,252,130, 55, 58,241,241,241, 25, 20, 30, 30, 62,106,228,200,145, 38,161, 80, 8,157, 78, 7,157, 78,135,135, 15, 31, -154,122,244,232,145,213,175, 95, 95,239, 67,135, 14, 85,154, 78,163,209,248,196,207,207,111,234,228,201,147,151,174, 92,185,210, -233,235,175,191,134,205,102, 3,199,113,165, 63, 75,126,223,187,119, 47, 18, 18, 18,150,149, 53, 87, 12, 6,131,241,111,193, 94, - 47,242, 63,101,176,254, 63,225,243,249,171,142, 31, 63,222,184,125,251,246,130, 46, 93,186, 68, 6, 4, 4, 68,166,165,165, 69, - 1, 64, 64, 64, 64,100,207,158, 61, 35,189,188,188,176,108,217, 50, 29,159,207, 95,245,130, 23,169,236,203,238,182,175,175,239, -162,221,187,119, 47, 28, 55,110, 28,124,124,124, 34,254,191,243,236, 36,145, 52,121,111,233, 82,171,208, 98,225,253,180,104,145, -211,226, 51,103, 22,110,223,177, 67,208,186,117,107, 66, 41,197,253,123,247,164,223, 47, 95, 46, 27, 49,112, 96, 82,108, 66,130, -117,223,177, 99,150,172,167, 79,243,159,230,228,204,160,148,230, 87,165,111,177, 88,174,196,199,199,251,181,235,208,218,255,220, -245,168, 59, 67, 6,246,238, 44, 20,240,200,163,164,180,155,190, 62, 30,206,103,207,156,212, 91, 44,150, 43, 85,233,104,181,218, - 68,171,213,234, 70, 41,245, 60,123,246, 44, 60, 61, 61, 81, 80, 80, 0,139,197, 2,147,201,100,210,233,116, 14,121,121,121, 48, - 24, 12, 48, 26,141,112,114,114,194,253,251,247,179,172, 86,235,233,138, 52,173, 86,235, 88, 7, 7,135,239, 40,165, 66,163,209, -152,126,242,228, 73,136, 68,162, 64,103,103,231, 47, 45, 22, 11,210,211,211,113,233,210,165,249,102,179, 57,181,228, 24,177, 88, -226,105, 52, 26,173, 21,117,114,183, 55,130,245,162, 4, 4, 4,248,213,172, 89,115,242,180,105,159,215,105,216,176, 49,114,115, -115,193,113, 28, 20, 10, 5,116, 58, 29,156,156,156,240,218,107,175,221,158, 55,111, 94, 62,165,152, 86,149, 9, 76, 79, 79,207, - 11, 10, 10,154, 49,126,252,248,201,117,234,212, 9, 2,128,208,208, 80,116,239,222, 29, 71,142, 28, 65, 92, 92, 28, 10, 11, 11, -109, 55,110,220, 56,144,158,158,206,214,246, 98, 48, 24, 12,102,176,170, 79, 86, 86, 86, 78, 64, 64,192,209, 91,183,110,245, 29, - 54,108, 24,206,158, 61,251, 14,128,201, 0, 32,145, 72,222, 25, 54,108, 24,110,221,186,133,152,152,152,163, 89, 89, 89, 57, 47, -227, 59,197, 98,177,193,100, 42, 10, 70, 57, 56, 56, 56, 84,243,240, 26,197, 77,131, 0, 80,163,146,207, 42,132, 39, 16,248, 54, -232,217, 83, 80,112,231,142,122,205,181,107,115,183,108,217, 34,104,219,182, 45,177,152,205,176,113, 28, 66, 66, 66, 72,151,174, - 93,229,235,183,108,113,179,105,181,231,191,253,226,139, 11,171,223,123,175, 48,142,210, 36,123, 18,104, 52, 26,151, 79,248,224, -253,174,103,206, 94,240,143, 8,175,237,118,244,248,153,219,238,238,206,178,186,117,234,200,243, 10,242,109,211,167,125, 38, 48, - 26,141, 63, 85,165,163,215,235,247,156, 60,121,114, 96, 96, 96,160,103, 84, 84, 20, 76, 38, 19,108, 54, 27,186,116,233, 2, 74, -169, 4, 0, 39, 16, 8, 16, 19, 19, 3,179,217,156, 29, 31, 31,159,254,232,209, 35, 9,128, 5,149,233, 26, 12,134,228,178,127, - 7, 5, 5,181,237,211,167, 15,172, 86, 43,122,246,236,137,253,251,247,183, 77, 79, 79, 95, 83,102,151,228,151, 80, 19, 2,165, -180,158,191,191,255,238,226,143,236,234,220,238,235,235, 27, 22, 26, 26, 58,111,254,252,249,194,192,192, 64,112, 28, 7, 55, 55, - 23,104,181,122,228,229,229, 33, 34, 34, 2,129,129,129,248,254,251,239,129,162, 17,128,118, 69,216, 82, 82, 82, 18, 1,124, 20, - 17, 17, 33,210,104, 52,145,122,189,126,102,151, 46, 93,112,251,246,109, 92,185,114,229, 99,173, 86,155, 47,151,203, 45,126,126, -126, 35,121, 60,158,220,108, 54,239,207,206,206,206,102,143, 40, 6,131,193,120,197, 13,150,183,183,183,204,193,193,225,141,247, -223,127,223,133,227, 56,136, 68,162, 6, 30, 30, 30,223,229,230,230, 22, 86,247, 75,117, 58,221,246, 45, 91,182,116,255,241,199, - 31, 69,189,123,247,174, 29, 16, 16,208, 2, 0, 6, 15, 30, 92,219,209,209, 17, 91,182,108, 49,235,116,186,151, 54,167,145,197, - 98,105,223,188,121,115,228,231,231, 35, 41, 41, 41,170, 58,199, 30, 56,112, 64,134,162,126, 87,149,126, 86, 25, 86,147,201,213, -197,223,159,247,244,204, 25,115,190, 90,237,219,190, 67, 7, 98, 49,155,193,227,241,144,151,151,135,148,148, 20, 56,187,184,144, -152,248,120,197,218,207, 63, 63, 80,163, 81, 35,177,205,100,114,175,134,153,208, 18, 66, 70,127,252,209,135,123,182,110,253,221, - 83,169, 86, 63,150, 74,101, 70,137, 68,228, 51,241,227,143,109,249,249,249,111, 83, 74,237,185, 78, 11,182,110,221,218,179,103, -207,158,247,130,130,130,188,114,114,114,124,148, 74,165, 45, 63, 63,159,143,162,190, 84, 4, 0,206,156, 57, 3,181, 90,109,181, -217,108,231, 1,204,161,148,154,236, 77,171,155,155,155, 99,167, 78,157, 90,121,123,123, 67,173, 86,195,195,195, 3, 77,154, 52, -105,229,230,230,182, 61, 63, 63, 95,243, 50, 11,247,137, 19, 39, 28, 41,165,173, 40,165,232,217,179,167, 93,199, 16, 66,134,244, -233,211, 71,200,227,241,160,215,235, 32,145, 56, 64,161,112,130,163,163, 51,234,214,173,139,244,244,116,244,232,209,195, 28, 31, - 31,191, 57, 35, 35,227, 80,117,211,164, 82,169,186,181,110,221,250,253, 9, 19, 38,192,102,179, 97,192,128, 1, 72, 77, 77,253, - 38, 49, 49,241,128,135,135,199,192,119,223,125,215,205,221,221, 29, 83,166, 76,145, 2, 88,202, 30, 81, 12, 6,131,241, 63,110, -176, 42,107,243, 12, 8, 8,104,238,225,225,241,177,163,163,163,203,233,211,167,229, 0,208,182,109, 91,112, 28,183,202,207,207, -239,151,244,244,244, 75,213,249,210,130,130, 2,181,175,175,239,190, 43, 87,174, 12, 29, 60,120, 48, 78,156, 56,241,118,177,193, -194,149, 43, 87,240,228,201,147,125, 5, 5, 5,234,151,145,193,128,128,128, 94, 29, 59,118, 28,220,188,121,115, 28, 60,120, 16, - 54,155,237,114,117,142, 47, 59, 98, 16,229,140, 34, 44,249,204, 46, 49, 62, 31,132, 16, 88,173, 86, 0, 64,110, 78, 14,226, 98, - 99,145, 95, 80, 0,163,193, 0,173, 78,103,171, 91,179,166, 94,101, 50, 9, 9, 80,173, 54, 46, 74,105,178, 66,161, 72,209,105, -181, 94,238,174,110,122,153, 76, 2,165, 90, 37,186,121,227,106, 33,165,244,177,157, 26, 38, 66, 72,135, 35, 71,142,204,224,243, -249,195, 20, 10, 5, 38, 76,152,192,239,216,177, 35, 68, 34, 17,140, 70, 35,148, 74, 37,182,108,217,146, 99,181, 90,107, 21, 27, - 18,133, 92, 46,223,200,231,243,211,212,106,245,215, 85,125,135, 68, 34,233,216,191,127,127,190,209,104,196,156, 57,115, 48, 99, -198, 12,244,236,217,147,127,253,250,245,142, 0,246,191,172,130,205,113, 28,186,117,235, 86,182,147,251, 67,123,142, 19, 10,133, -117,235,212,169,131,156,156, 28,228,228,228,192,211,211, 19,126,126,126,240,246,246,198,146, 37, 75,232,210,165, 75,207,217,108, -182,205,153,153,153,185, 47, 80, 22, 71,190,243,206, 59, 35,134, 14, 29, 10,173, 86,139,211,167, 79,163, 77,155, 54,248,254,251, -239, 61, 47, 92,184,240,126,243,230,205, 33, 20, 10,113,238,220, 57,152,205,230,116,246,120, 98, 48, 24,255, 54, 94,149,254, 87, - 85, 70,176, 92, 93, 93,157, 28, 28, 28,198,245,237,219,183,237,192,129, 3,241,221,119,243, 74,255,199,227,241,176,105,211, 38, -197,158, 61,123,190, 8, 12, 12,236,192,113,220,175, 79,159, 62,205,183,247,139, 57,142,219,179,117,235,214,222,173, 91,183,150, -117,234,212, 41,164,248,229,107,218,186,117,171,142,227,184, 61,213,205,200,243,147, 62,250,251,251, 55, 20, 8, 4,131,251,246, -237,219,112,244,232,209,136,142,142,198,150, 45, 91, 30,213,173, 91,247, 98, 53,165,147,170, 24, 69, 56,191,170,104, 22, 95, 44, -206, 83,102,102,186, 40,130,130,132,174,142,142, 25, 7, 15, 30, 12,236,218,181, 43, 73, 77, 77, 69, 65, 65, 1, 12, 6, 3,110, -220,184,193, 9,128,100,129,171, 43, 73,190,114,133,240,197,226,188,234,158,131, 64, 95,215,208,111,166,141,175, 97, 48, 26,234, -171, 84, 42,171, 64, 40, 20, 6,248,184,164, 86,179,112, 27,229,114,121, 51, 0, 2,142,227,116,110,110,110,178,227,199,143, 67, - 44, 22,131, 16,130, 6, 13, 26,192,193,193, 65, 36,151,203, 83, 0,192,199,199, 71,188,106,213, 42,231, 81,163, 70, 93,168, 74, -187, 99,199,142,130,224,224,224,238,117,235,214,197,229,203,151,241,240,225,195,167, 87,175, 94,245,111,214,172, 25,252,253,253, -187,119,236,216,241,240,217,179,103,173, 47,233, 38,125,161, 78,238, 54,155,141, 18, 66,192,227,241,192,113, 28,114,114,114, 80, -171, 86, 45,172, 88,177, 2, 75,150, 44,249,233, 69,251, 72, 69, 68, 68,136, 26, 55,110, 60,120,232,208,161,120,252,248, 49,230, -207,159, 95,144,157,157,125,249,248,241,227,189, 38, 76,152,192,111,211,166, 13,242,242,242,176,110,221, 58,235,237,219,183,119, -102,101,101,237, 97,143, 90, 6,131,193,120, 5, 13,150,191,191,127, 31, 55, 55,183,247,135, 15, 31,206, 15, 11, 11, 67, 86, 86, - 22, 52,154, 66, 67,195,134,145, 28,192,163, 98,177,200, 44,151,203, 49,118,236, 88, 52,104,208,160,197, 23, 95,124,209,220,199, -199,103, 83,102,102,230, 46,123,190, 56, 43, 43, 75,231,235,235,187,115,194,132, 9, 11,238,220,185, 93, 11, 0,174, 95,191,254, - 36, 61, 61,125, 90, 86, 86,150,174,154,230,170,100, 50, 75, 34,149, 74,175,133,134,134, 38,246,234,213,203,105,224,192,129,240, -244,244,196,173, 91,183,240,253,247,223,199,155, 76,166, 25, 47,235, 5, 94, 29,172, 70, 99,230,205,189,123, 29, 59,190,241,134, -211,196, 62,125, 22,125, 56, 97,194,143,223,124,243,141, 32, 44, 44,140,232,116, 58, 92,187,118,141,238,218,181,203,178,126,238, -220,165,144,203,133, 87,118,237, 18,155, 76,166,228,106, 70, 71, 58,244,238,217, 33,108,209,143,203, 97,208, 23,226,218,229, 67, - 40, 40,200,193,170,213,187,195, 2, 2, 2, 58,164,165,165,157,171,198,249,172,123,226,196, 9, 47, 74, 41,196, 98, 49,230,204, -153, 3, 63, 63, 63, 56, 57, 57, 65,163,209, 96,242,228,201,206,159,126,250,169, 51, 0, 68, 71, 71, 67,161, 80,216,165, 27, 27, - 27,219,116,252,248,241, 50,155,205,134,163, 71,143,154,249,124,254,162, 19, 39, 78, 44,108,212,168,145,168, 99,199,142,178,245, -235,215, 55, 3,112,245,101, 25,172, 23,193,102,179, 37, 29, 63,126,188,193,176, 97,195,168, 64, 32, 32, 74,165, 18,206,206,206, - 88,177, 98,133, 46, 35, 35,227,133, 39,104,203,203,203, 19,214,175, 95, 95,196,113, 28,118,238,220,137,167, 79,159,126,150,149, -149,149,227,231,231,119,116,234,212,169,227,194,194,194, 2, 98, 98, 98,158,234,245,250,149,233,233,233,105,236,209,196, 96, 48, - 24,175,110, 4,235,141,163, 71,143,242, 57,142,195,234,213,171,113,235,214, 45,154,155,155, 59,131, 16,178,209,201,201,201,150, -155,155,251,198,152, 49, 99, 6,206,152, 49,131,180,107,215, 14, 87,174, 92, 33,181,106,213, 26, 12, 96, 87,153, 23,117,215,202, -230,202, 80,169, 84, 55,178,178, 50,107,149,153, 88,178,150, 68,226,112,163,138,151,255, 51,154,207, 79,102,201,231,243, 90,206, -153, 51, 71,235,235,235,107,138,138,138,194,202,149, 43,185,155, 55,111,158, 17,139,197,171,210,211,211,141,246,104,190, 12,202, -106,138,173,214, 91,155,167, 78,173,215,116,192, 0,238,253, 41, 83, 10, 69, 82,233, 39,139,150, 47,255, 92,169,209,248,129, 16, -234,238,236,156,188,122,206,156,249, 61,251,247, 47,140, 62,119,206,225,206,137, 19, 66, 79,139,229,110,117,210,153,150,150,118, - 46,180,118, 16, 54,172,249, 17,102,179, 17, 25, 79,139,252, 89,110,158, 10,149,153,171,242, 52,173, 86,171,234,245,215, 95, 23, - 1,144,190,249,230,155,226,236,236,108,212,174, 93, 27, 0,160, 86,171,113,232,208, 33,132,135,135, 3, 0,238,223,191, 95,250, -123, 85,233,116,116,116,236,218,190,125,123, 36, 39, 39,227,193,131, 7,151,159, 62,125,170,244,247,247,191,156,146,146,210,177, -121,243,230,216,181,107, 87,151,138, 12, 86,117,175,145, 61, 6,171,130,188, 47,216,179,103,207,208, 43, 87,174,244,157, 50,101, -138,160,115,231,206, 0, 0,173, 86,107,160,148,218, 94, 68,179, 44, 22,139,165,100,210, 83, 29, 0, 20,155,169,175,255,138,230, - 95, 45,159, 76,147,105, 50, 77,166,249, 79,208,252, 55, 25, 44, 43,199,113, 56,123,246, 44,118,239,222,109, 51,153, 76, 95,102, -100,100,196,150,249,255,250,192,192,192, 11,131, 7, 15, 94, 28, 23, 23,199,127,240,224, 1,236,121, 1,149,197, 96, 48, 88,158, - 95, 42,216, 96, 48, 88,254,106,166, 54,108,216,128,204,204, 76,115,106,106,234, 73,171,213,186,231, 47,142, 70,252,203,163, 8, -215, 83,106,124,131,144,147, 51,219,182,237, 54,227,196, 9,201,251, 95,125,101,124,103,244,232,207,108, 38,147,133, 47, 18,113, - 98,185,156,103,147, 72,132,209,231,206, 57, 44,251,224, 3, 55,189,209,120,116,115, 53, 58,142,151,137, 96,225,157,247, 39, 65, - 95, 38,130,117,229, 70, 28,170, 27,193, 50, 24, 12,245, 1, 64, 42,149,166, 0,240,121,235,173,183,192,113, 28,244,122, 61, 52, - 26, 13,210,211,211, 85,163, 71,143,182, 1,128, 92, 46, 23, 12, 30, 60,216,201,174, 19, 89,163,134, 15,159,207,199,225,195,135, - 33,145, 72, 78, 3,128, 68, 34, 57,125,226,196,137,142, 35, 71,142, 68, 96, 96, 96, 80,201, 36, 40,149,233,120, 71, 14,220, 78, -129, 80, 16,212, 41,186,211, 81,199, 43,114,224, 61, 2,196, 23,207,242,254,176, 73,147, 38,128,157,253,174,202,146,147,147,163, - 5,176,206,219,219,251,208,103,159,125,246, 86,171, 86,173,218,205,152, 49,131, 80, 74,255,242,194,232,148, 82,216,108, 54,246, -212, 97, 48, 24,140,127,179,193, 34,132,252,209,169, 83,167, 17,148, 82, 62,143,199,219,242,156,185, 2, 0,164,166,166, 62, 9, - 8, 8, 88, 93,179,102,205,210, 5,160,171,249,194,201, 34,132,124,207,227,145,207,139,254,174,254,196,146,101,150, 36,249, 28, - 0,225,241,248, 27,111,223,190,253, 85, 74, 74, 74, 78,117, 13, 95,121,188,140, 81,132, 0,176,149,210,196, 17,132, 28,155, 18, - 25,217,181,231, 7, 31,160, 97,207,158, 78,126,193,193, 54,189,217,204,221,191,120,145, 92,222,185, 83,116,231,196, 9,161,222, -104, 60,186,155,210,148,234,166, 51, 45, 45,237, 92,237,144,128,227, 67, 6,247,238, 30, 82,211, 15, 0,144,144,152,142,220,124, -213,241,234,152,171,231,140,214,128, 21, 43, 86,236, 23,137, 68,130,178, 75,206,152,205,230,252, 18, 19, 70, 8,241, 91,189,122, -245, 31, 60, 30, 47,185, 42,189,216,216,216,227, 51,103,206,236,249,228,201,147,243,169,169,169,105, 0,144,144,144,144,230,231, -231,183, 59, 61, 61,189, 87, 74, 74,202, 17,106, 71,232,233,185,197,158, 17,125,113,135, 3,128, 6, 37,139, 61,191,232, 90,131, -101, 41, 54,229,139, 2, 2, 2,246,245,234,213,107, 4, 33, 36,243,175,232, 41, 20, 10,171, 94,175,183,114, 28, 39, 48,155,205, - 84,161, 80, 88,217,227,135,193, 96, 48,170, 69,115, 0, 37, 43,135,148, 4, 78, 60,159,251,221, 4,160,236, 82,126, 37,127,231, - 0,184, 81, 70,163,236,231, 85, 29, 11, 0,185, 0,238, 21,127,246,215, 12, 86, 90, 90,218, 17,216,177,152,179,189,251, 85, 98, -144,190, 36,132, 44, 43, 49, 75,127, 85,195,106,181,190,148,245,219,120, 60, 94, 98,191,126,253,170,181,127, 85,251,252, 65,105, -242, 39,132,108, 58,248,211, 79,141,143,174, 92,233,111,179, 90,221, 9, 64,249, 98,113,158,201,100, 74,242,180, 88,238, 86, 55, -114, 85,150,199, 9,105, 61, 0, 32, 52, 52,148, 62,122,244,232, 47,143,198,160,148,222, 5, 16, 88,197, 62,233, 0,218,217,163, -151,154,154,186, 31,229,140, 20, 76, 79, 79, 63, 0,224,128,189,233, 42, 93,236, 25,224,113,132, 27, 82,191,237,208,157, 0,184, -146,197,158, 95, 38,105,105,105, 9, 0,230,254, 85,157,199,143, 31,155,106,214,172,185,119,193,130, 5, 3,239,221,187,119, 48, - 53, 53,213, 4, 6,131,193, 96, 84,203, 92, 17, 66, 14, 22,191,123,250, 22, 87,242, 15, 62,255,123,201, 62, 37,251,149,221,167, - 68,227,249,207, 43, 59, 22, 0,166, 77,155,246,213,252,249,243,101, 0,236,238,139, 43,248, 39,156,181,151,177,168,237,203, 94, - 24, 55, 45, 45,109,205,223,145,215,229, 69, 6,234,234,223,121, 62,227,227,227,201,171,124,151,149, 44,246, 92,134,200,255,133, -116, 39, 38, 38,110,234,216,177,227,239,169,169,169, 44,122,197, 96, 48, 24,213,195,179, 60, 67, 84,129, 31,232, 91,217,255,159, -169,176,151,179, 95,121,127, 19, 66, 14,206,159, 63,191,111,117, 18,204, 99,215,140,193,248,255,227,191, 49,138,149,193, 96, 48, - 24,229,243,124,212,170,196,116, 61,255,247,180,105,211,190, 66, 53,154, 7,129,162,153,185,187, 86,240,165,118,143, 14, 32,132, -116,125,129, 76,157,100,154, 76,147,105, 50, 77,166,201, 52,153,230,191, 75,179, 42,237, 10,142,239, 83, 81,147, 94,101,205,133, -207,255, 94,213,177,118,236,123,168, 58, 39,226,111,219, 0,116,101,154, 76,147,105, 50, 77,166,201, 52,153, 38,211,252,139, 91, -115, 74,105, 31, 20,173,114, 66, 41,165,125, 40,165, 61,167, 77,155,246,101,201,103,211,166, 77,251,146, 82,218,165,100,191,226, -125, 74,143, 41,249,236,249,159,207,127, 86,197,190,118,167,249, 31,209, 7,139,193, 96, 48, 24, 12, 6,163, 18,110, 0,104, 94, - 38,186,148, 3,224,254,252,249,243, 11,202,244,141,202, 1,112, 23, 64,163,226,253,114,138, 3, 73,101,251, 78,153,138,255, 54, -149,179,143,201,158,125,237,133, 25,172, 10,104,236,203,159, 27, 20,224,213,172, 52,202, 87, 52, 57, 36,184,226, 89, 4, 74,167, - 19,224, 56, 80, 74,145,158,173,188,117, 47,139,126,243,162,223, 23,230, 79,220,188, 28, 28,150,114,148,182, 45,254,232,156, 42, -207, 56, 41, 74, 69,149,246,106,212,243, 33,245, 28,120,248,140,163,104, 8, 0, 60,130,123, 6, 14, 63, 60,204,164, 15,255,234, -249, 32,132,144,250,158, 24, 43,150,202,134, 59,187,184,214, 41, 40,200,141, 55, 27,140, 59, 30,228, 96, 21,125,129,105,211,107, -187,145, 86, 28,197, 87, 0,120, 66, 30, 22,199,229,209, 51,172,212, 49, 24,140,255, 39,248,127,241,248,242,166, 0,250,171,131, -139, 40,187, 44,118,153,172,231,185,110,231,126,255,239, 84,203, 96,213,247, 34, 31,128, 96, 22, 0, 10,138,217,209,217,244,215, -106, 29,239, 71,186, 58,240,249,107, 1,240, 13,102,219, 20,202,225,124,185, 47,115, 30,218, 59,136,248,139, 1,112, 6,155,237, -189,232,116,251,251,131, 69, 6,144,158, 2,142,183,153,163, 84,104,227,232, 70, 80, 28, 84,136,112,233, 74, 26, 53, 84, 39,173, - 65, 1, 94,205,246, 94,207,232,126,230,215,137,104,217,176, 54,168,205, 10,112, 22,200,218,125,134, 83, 75,222, 66,203,122, 65, -160,156, 5,224,172, 80,244, 90,132, 94,145,206, 47,124,115,132,249, 19,183, 96, 15,175,168, 53,107,214,250,248,133, 68, 16,206, -106, 70,236,245,227,163, 62,253,124, 70,231, 72,103, 18,105,143,201,106,228, 71,222,175, 93, 43,236,179, 73,179,126,228,251,250, - 5,202, 57,139,209,154,153,248,176,201,242,133, 51,118, 53,242, 35,139,239,166,211,181,246, 26,169, 8, 79,140, 19, 72,196, 67, -165, 14,242, 58, 58,157,230,145,205,108,217, 17,233, 39,232,249,195,162,165,141, 59,118,235,173,176,105, 50,121, 22, 14, 17,219, -183,253, 17,252,211,138, 95,122, 19, 66,250, 83, 74,185,234,228,153,163,248, 60,110,211,216,222, 66, 1,159,212,123,119, 13, 31, -213, 24,250, 90,150, 8,111, 50,146,208,170,167,137,160, 4, 23, 30,100,209,223, 95,228, 59,234,121,147,223, 8, 69, 93, 16,236, - 36, 20,127, 68,103,211,108,246,156, 99, 48, 94, 45,120, 60,222, 25,142,227, 58,189, 76, 77, 66, 72, 43, 74,233, 85,118,118,255, -157, 84, 47,130, 69,240,109,244,227, 84, 87,216,204,168, 95, 55,100, 46,128,106, 25, 44, 7, 62,127,227,141,248, 44, 31, 88,205, - 88, 51,111,194, 54,147, 5,176, 90,204,176, 89, 45,176, 89, 45,176, 90,205,176, 89, 44,160, 22, 35,102,172, 59, 3,152, 52,104, - 22, 25,186, 17,128,175,189,223, 33,164,188,205,183, 46, 30,119, 35, 38, 21,126,255,117,254,199,169, 57,133, 31,159,188,151,158, - 91,223,155,124,249, 32, 27,235,171, 99, 4,206,172,156,136, 45,123, 14,165, 45,251, 77, 27,195, 81, 10, 55, 39,105,216,168,190, -209,129,155,246,157, 73, 93,186,209, 16, 3, 0,206,114,113,216,219,247,226,131,254,202, 69,240,114,112, 88,186,234,151,159,124, -124,221,165,196,122,121, 1,172, 54, 27, 2,131,251,240,191,252,104,148,239,183, 75,214, 46, 1,240, 78,101,199,135,123,147,136, -186,181,235, 77,217,120,232,114,144, 86,157,109, 58,190,245,171,199, 48,194,226,227, 95, 79, 56,119,254,143,252,233, 95, 76,156, - 28,238, 77,174,197,100,209, 7, 85, 60, 12,120,245,188,176,111,254,130, 69, 13, 59,247,234,171,224, 10,115,248, 6,109, 97,221, - 53,235,214,206, 10,111,216, 66,214, 46, 50, 64,148,189, 99, 60,209,107,242, 97,230, 57, 72, 58,215,239,234,164,127,115,132,101, -205,134, 45, 31, 1, 88, 94,173,234, 95,153,230,105,142,123,241,218, 36,161,104,119,231,234,153,113,182,244, 27,160, 54, 11, 96, - 51,151,254,132,205, 2,202, 21,253,108, 57,126, 29, 0,188,144,193,226, 81,116, 63,121,241,134,111, 86,102, 70,243, 37,139,190, -251, 50,194,139, 28,129, 13,155, 31,230,227, 92,117,141, 37,131,193,248,231, 66, 8,177, 82, 74, 5, 47, 89,179, 55,165,244,240, - 95,212,248, 12,192,251,197,127,174,165,148,254,240, 18,210, 21, 0,192,167,248,207, 76, 74, 41, 91, 3,245,191,106,176, 0, 7, - 80, 14,216, 57, 16, 0,164,213,253, 50, 10, 56,128,240, 1,139, 22, 3,122,117,131,135,151, 15, 96,209, 1,102, 29, 96,209, 3, - 22, 45, 96,209, 35, 55, 35, 25, 48,107,129,132, 35,176, 82, 42,169,118,174,140, 42, 32,110, 7,186, 52, 9,130,167,179, 3, 38, - 14,136,240, 88,125, 52,110,237,218,227,177, 93, 1, 12,183, 43,173,148,162,101,131, 58, 88,182, 86, 27,179,255, 86,118, 15, 0, -232,211,216,227,104,203,136,224,192,165, 27, 13, 49,135,238,229,247, 4,128, 94,145,206, 71, 90,132,249, 6,113,127, 33,186,203, - 81,218,206,175, 70, 29, 98,187,179, 10,156, 58, 13,106,181, 30,105,137,155,224,234,223,148,103,227,208,161,170,227,165,124, 76, -251,100,250,247, 66,157, 58,203,196,153,115,108,158,252, 2,190, 64,204, 17, 60, 61,103, 44,228,148,182, 73, 99,223,178, 78,249, -102,222, 52, 0,163, 42,141, 6,121,225,163,197,139,151, 54,104,211, 44,220, 43,115,215, 68, 82, 88,144, 5, 43, 95, 38, 25,208, -186, 13, 92, 66, 35,184,172,179,139,137, 56,164, 43, 92,220, 67,240,244,242, 86, 36, 93,221, 77,218, 54, 25, 44, 89,255,187,232, -205,138, 12, 86,168, 39,105,219,163,125,139,109, 33, 65,126,190,148,114,224, 56, 10,202,217,240,238,144,238,248,114,123, 2,108, - 54, 27, 94,239,209,182,203,247,227, 58, 83,142,227, 64, 41,135,212,204, 60,221,233,107, 49, 93, 30,231,211,107,246, 68,166, 26, -181,234,212,246,222,173,171,225,150,184, 3,104, 54,234,255,216,187,234,240, 42,142,183,123,230,238,213,220,184,123, 66, 2, 36, - 65,130, 59,193, 37,104,113,111,129, 10, 80,160, 88,139,182, 64, 75,139,180, 80,172, 56,180,197,181,184,107,130, 91,176, 16, 32, - 36, 1,226,238,114,117,119,231,251, 35,210, 0,145,123, 3,109,127,237,183,231,121,246,185,119,237,236,216,206,156,125,103,230, -157,197, 79, 9,112,181, 84,153, 11,184,119,230,247, 90,192,111, 85,173,132, 72,109, 7,112,175, 78, 47,129, 71,219, 49,204,198, -221,167,237,179, 83,227, 71,254,177,125,221,192,245, 27, 55,238, 4, 48, 78,168, 70, 4, 8,248,111,128, 82,250,222, 69, 86,116, -116,116,194,187,136, 44, 55, 55,183,182, 0,126, 42, 30,137, 65, 8,249,201,203,203,107,222,159, 31,168,175,125,227,101,115, 28, - 55, 34, 46, 46,238,114, 69,156,189,122,245,114, 1,224, 85,138,211,139, 16,226, 85,214,181, 86, 86, 86, 92,171, 86,173, 94, 29, - 63,126, 60, 65, 40, 33,127,173,192,122, 26,179,127,114, 35, 77, 98, 30, 0, 60, 53,160,176,190,214,181,167,214,115, 75,182,126, -251,209,146,186,213,108,144,155,175,197,217,187,175,192,113,122,112, 44, 91,100,201, 98,193,177,122, 4, 54,176, 67, 43,245, 56, -172, 62,254, 12, 44,199, 47,174,136,243, 77,232, 40, 63,172, 97,231,193,251,120,158,202,228, 18, 81,182,175,187,173,195,151, 3, - 26,136, 38,247,169, 11,149,142, 29, 92,199,145, 92, 12, 75,166,155, 13,226,228,223,118, 89, 68,203, 58,198,177,149,198,189, 2, -235, 83,243,161,189,186, 88, 80, 77, 54,244,105, 81,200, 45,208, 35, 42, 93,143, 36,117, 22,228, 36,209, 32, 78,158,162,190,155, -171,179,242,218,222,153, 47,109,153, 28,177, 3,195, 74,101, 34, 22, 28, 79, 25,154, 21,166,177,169,213, 69, 82, 60, 46,171,162, -112,154, 40,205, 63,106,219,181,167,101,204,174, 49,196,196, 55, 16, 14,141,220,241,242,242, 86,164,220, 61,142,244,132, 87,196, - 66,157, 5, 71,219, 26,232, 62, 98, 8,150, 14,105,138,220,156, 92, 48,137,145,150, 50,137,220,170, 60, 78,202, 97,196,207, 63, - 46,116, 22, 51,162,194,244, 44,222, 56, 61, 84, 26, 13,192,177, 80,136,121, 16, 90,124, 78, 15, 78,175, 83,214,239, 63,115, 60, -128, 91,149,197, 61, 44,153,238,174,235, 64,218,128,215,215,162,122, 21, 8,112,245,113, 10, 45, 17, 61,117, 28,201,176,198,129, -163,219, 80,130, 43, 85,201, 35,127, 91,244,106,226,101,102,106,154,243, 20,113, 7,190, 64, 36, 20,212,177,245,167, 24,246,241, - 68,229,166, 77,155,122, 19, 66, 62, 47, 61, 6,237,175, 88,252, 84,224, 20, 56,255,173,156,150,150,150,222,213,170, 85,155,167, -215,235,219, 74,165, 82, 71,157, 78, 7,158,231,147,100, 50,217,149, 87,175, 94, 45,200,206,206,126,241,191, 22,247,135, 15, 31, - 26, 44,178, 12,225,148, 72, 36,120,246,236, 89,132,161, 34,235, 77, 78,137, 68,178,227,234,213,171,216,183,111, 31, 0, 32, 60, - 60, 28, 62, 62, 62,166,101,221,251,242,229, 75,211,246,237,219,239,192, 27, 43,112,188,201,249,232,209, 35,239, 99,199,142,225, -192,129, 3, 0,128,103,207,158,193,215,215,183,204,240, 92,189,122,149, 25, 62,124,184, 55,128,132,191, 58,143,254,147, 2,171, -104,125, 93,242,230,255, 50, 16,229, 97, 45,107, 4, 53, 7, 0, 81,198, 62, 44, 44,137,254,216,192, 89,210,237,194,129,181,109, - 21, 82, 17,230,111,254, 50, 54, 53, 35,183,133,152,128, 7, 0,150, 66,100,109, 38,187,177,120,100, 3,143,204, 60, 53,142,222, -142,191,252, 56,217, 56, 83,232,227, 4,122, 14,128,213,159, 13, 36,241, 29,185,244,220,158, 61,179,186,213,159,218,167, 62,142, - 92,127, 53, 21, 64,165, 94,218, 41,207,131,242,108,201,160,246,162, 79, 5,128,103, 81,122, 76, 55, 15, 90,120,140, 55,206,130, -213,158, 16,113,166, 3,186,219, 40,101,107,198,142,253,204, 66,159,250, 28, 25, 90, 41, 98, 51,213, 72, 82, 73,144, 39,118, 64, -252,211, 71,156,136,224, 92,229, 86, 22,228, 80, 86,109,101, 45, 51, 19,249,119, 25,239,154,115,122, 78,166,140,176,140, 69,191, - 31,172,210, 46, 44,127,197,230,167,230, 19,130, 74, 23,209,182,180,180,242, 81,167,191, 98,178, 51,211, 96,229, 84, 23,221, 6, -247,194,119, 61,235, 32, 55, 39, 31,169, 25, 55,104, 77,103, 11, 18,125,101, 39,190,238, 94, 27,233,201,137,208,232, 1,146,175, -201, 80,107,213,121,229,166,163, 8, 27,167,124, 53, 99,152,167,179,189,105,241,100, 1,202,115,104, 80,187, 58,186,180,109,142, -115, 87,175,225,206,163,112,240, 69,147, 5, 40,207, 35, 46, 37, 51, 89,173,227,182, 26,149,160, 28, 11,170, 87,151, 41,192, 80, -133,174,193,122,142, 68,201, 1,115, 91,212, 52,255,100, 86, 47, 79,115, 83, 57,129, 90,207, 65,173,213, 35,247,218, 26,216, 86, -171, 7,165, 66, 65, 26, 65, 37, 6,160, 23,170, 18, 1, 2,254,196,160, 65,131, 20,201,201,201, 65, 61,123,246,172,211,165, 75, - 23,101,155, 54,109,144,159,159,143,179,103,207, 34, 63, 63,223,211,221,221,221,243,236,217,179,253, 91,180,104, 17,230,230,230, -214,126,255,254,253,198,140,145, 21,227,207, 65,234, 60, 0,150, 16,130,162, 99, 4, 0,255, 46,235,208,202,100, 50, 68, 71, 71, -191,119, 75, 86,124,124,124, 68, 85, 44, 89,121,121,121, 82, 87, 87, 87,216,219,219,131,227, 56,228,231,231,227,240,225,195,200, -206,206, 6,207,243, 48, 49, 49,193, 15, 63,111,198,211,123, 65,184,117,235, 22,178,179,179,165,149,113,198,197,197,145, 6, 13, - 26, 64,163,209,128,101, 89,168,213,106,156, 63,127,190,100, 95, 44, 22, 99,198,247, 43, 16,126, 55, 8,247,239,223, 71, 92, 92, -220,223,178, 58,136, 17, 90,228, 63,105,193,122,103,112, 28, 59,123,211,182, 61, 55,102,143, 27,130,137, 67, 59,187, 47, 88,123, -176,115, 88, 42,221, 6, 0,117,236,201,200, 15, 59,212,244,176, 82, 74,240,221,174,187, 0,165,179,223,245,121,161,233, 52,188, -174, 19,153,122,232, 86,116,208,156, 33,141, 80,221,217,194,167, 70, 13, 34,139,140, 52, 96,205, 63,158,133,181,153,220,175,103, - 67,187,211,224,121, 88,153,203,107,129, 99, 97,101, 38,247,235,238,111,121, 10, 0,172,148,210, 90,101, 89,186,202, 67, 83, 15, -233, 24,165, 92, 60,198,180,177,179,199,168,222, 93, 76,122,244,238,111, 98, 38, 97,145,126,235, 44,114, 36,110,208,219,120, 66, -163,207, 64,220,139, 72,238,194,205, 39,241,105,185,154, 47, 43, 13, 38,197,229,248, 23,207,236,189,235,119,177, 78, 59,254,117, -138,247,232, 93, 94, 34,240,162,220,157,253,146, 77, 29,154,153,220,142,122,145,199,211,183, 45, 56,111, 34, 39, 59,251,149,158, -131,179,138, 19,155, 71, 94,250, 29,179,186,215, 67,102, 70, 10,212, 58, 22,217, 42, 86,231,100,165,144,107, 94,132, 66,163, 99, -161,213,243,144, 88,185,226,236,141, 71,105,188, 94, 95,238, 90,148,145,105,244, 62, 0,179,210,199,106,216,147, 6, 51, 45, 76, -238, 67,175, 66,116, 92, 2,182,157,184,209,168,232,186,170,127,157,242,108, 97, 55,115, 41,203, 21,161,104, 83,149,193,237,181, - 29, 73, 51, 19,133,244,151,159,166, 14,175,211,210,215, 70,206,199,221, 0,225,117, 48,229,196, 80,201, 56, 88,186, 87, 7,175, -205,165, 5,106,117,214, 99, 64,240,204, 46, 64, 64, 41,212,170, 85,203,201,210,210,242,241, 87, 95,125,101,211,175, 95, 63, 28, - 58,116, 8, 57, 57, 57,216,186,117, 43, 86,174, 92,137,111,191,253, 22,122,189, 30,155, 54,109, 82,254,241,199, 31,205,214,173, - 91, 23,231,233,233, 89, 55, 58, 58,186,178, 5,213, 9, 0, 57, 0, 73, 81,219, 69, 0,240, 39, 79,158, 68,143, 30, 61,112,242, -228, 73,190,232, 24, 71, 8,209, 83, 74, 53, 85, 21, 88, 50,153, 12,217,217,217,239, 69,100, 73, 36, 18,152,153,153, 65, 38,147, - 33, 55, 55,215,104,145,197,178, 44, 19, 23, 23,135,236,236,108,116,233,221, 27, 43, 22, 47, 70,135, 14, 29,208,165, 75, 23, 80, - 74,113,254,252,121,116,110,237,143, 33, 31,180,199,147, 39, 79,192,178,172, 65,225, 77, 74, 74, 66,114,114, 50,186,245,238,141, -205,235,214,161,121,243,230,240,243,243, 3,203,178, 8, 10, 10,194,192,192,214, 80,244,237,140,240,240,112,161, 80,255, 91, 4, - 86,104, 10,189, 89,199,158, 28, 31, 26,216,172, 87,239,128, 58,216,188,247,194,194, 58,117,200, 30, 0,176, 53,151,255,240, 81, -135,234, 8,139,201,196,133,251, 9,199,195, 82,223,207,236, 11,158,131,157,173,133, 18, 96,100, 80,233,120,214, 34, 10,149, 14, - 76,230, 41,133,178,237, 76,124,216, 59,204,189,121, 29,119,247,226, 89,132,102, 61,150, 99,228,163, 8,143,166,126, 78, 30,224, -244, 0,167,135,197,144, 93,192,247,166,149,134, 35,192, 91,126,110,230,151, 83, 91,117,239, 59,216, 68,166,180, 4,151, 19, 11, -125,210, 35,164, 63,191,140,124,165, 15,146,162,163,176,239,204,173,236,231,113,233, 57, 34, 17,206, 38,103,107,166, 71,102,208, -188,202,120,213,122, 44,158,247,245,151, 61,247,237,217,107, 46,175, 30, 64, 34,215,244,200,150,137, 89,185,189, 87, 99, 81,129, -194,142, 46,218,186,215, 34, 95,139, 37,149,241, 20,228,231, 28, 60,127,246,244,144,154,222, 1,230, 47,239,156,128, 74,173,129, - 70, 15,212,109,214, 30, 28, 71,101, 68, 68,120, 11,134, 33, 41,233,153, 32,122, 46,249,202,131,151,137, 87, 31, 68, 49, 26,243, -202,185, 95, 43,116,132,153,212,187,125, 67, 64,175,194, 7,109,235, 97,197,206, 11, 95, 0, 24,253,110,153, 92,104,193,162, 64, - 64, 93, 7,178, 1, 64,192,221,195, 43,107, 53,233, 59, 5,198, 88,176,252,237, 73,119,255, 26, 46,191,175,248, 97,166,141,173, -155, 15, 67,120, 61,168, 83,125, 32, 39,142,146,184, 27,176,116,109, 14,206,165, 53, 54,173, 94,150,199,243,116, 79, 85, 92, 84, - 8, 16,240, 95,134, 90,173, 62,248,227,143, 63,218,244,234,213,171,216, 2,131, 27, 55,110, 96,203,150, 45, 48, 53,125,189,158, -236,209,163, 7, 40,165, 54,243,231,207, 63, 8,160,101,121,156,173, 91,183,238,189,122,245,234,132,134, 13, 27, 70, 21,137, 44, - 41, 0, 81,104,104,168, 40, 54, 54,150, 88, 91, 91, 83, 23, 23, 23,125, 66, 66, 2, 15,128,251,248,227,143, 25, 51, 51,179,154, -121,121,121,193, 85, 21, 88, 50,153,236,189,140,201,146, 72, 36, 32,132, 64, 38,147, 65, 42,149,130, 82,106,148,200,226, 56, 78, -124,242,228, 73,220,189,123, 23,223, 54,108,136,169,174,174,176,177,177, 65, 80, 80, 16, 40,165, 48, 53, 53, 69, 70, 70, 6,246, -236,217,131,142, 29, 59,130,101, 89,169, 33,188, 7, 14, 28, 64, 72, 72, 8,190,111,210, 4, 83, 45, 45, 97,102,102,134,243,231, - 11,123,253,228,114, 57,162,163,163,113,254,252,121,180,111,223, 94, 40,212,127,181,192,106, 79,136,152, 56,194, 73,167, 85,129, -178, 20, 32,112,169, 83,135, 72,195,194,168,206,216,135,138, 68,248,122,245,182,227, 61,151, 79,233, 77,198,244,105,228,178,224, -247, 75,159, 3,192, 39, 3,124, 93,149,114, 49, 86, 29, 9,163, 34, 17,190,126, 31, 17,172, 83,135, 72, 69, 34,124,222,165,185, - 31, 18,178,180,136, 76,200,186, 24, 70,169, 65, 93, 58, 23,150,127,136,237, 71,131, 98, 87,110, 87, 63,165,148,194,202, 76,238, - 55,242, 97,164,199,239, 39, 67, 98,126,222,167,126, 74,121, 10, 43,165,164,214,232, 39,173, 43,157, 69,216,212, 67, 58,102,246, -204,233,173,251,140,254, 74,193, 62,221, 15,109,228, 25,240, 58, 21,114,116, 82,100, 49, 78,136,139,137,193,162, 77,199, 99,115, -242,181, 67, 66, 83,140, 19,150,225,105, 52,175,142, 61,233,183,232,187, 57,231, 22,255, 48,223, 76, 21, 21,148,199, 16, 86,197, - 84,107, 39,254,225,219,229, 36, 87,163, 29, 28,153, 65,115, 43,227,209,152, 99,201,143, 63,175,238,249,217,136,254, 79,125,125, -218,217,114, 9, 47,108,213, 57, 57, 41,187, 78,135, 56, 21,125, 25, 18, 0,136,140, 75, 71,106,118, 62,203,177,250, 96,115, 9, - 22, 60, 54,196, 26, 88,132,234,142,196,190, 95,155,250,195,237,205,165, 80,229,101,193,193, 92,130,192,230, 53,134, 87,119, 36, - 51,163,146,105,106,149, 51,154,215,131,234, 85,184,185,164, 99, 45,202,233,107,129,211, 67,247,112,135,241,150, 48,130,169, 19, -219,154, 89, 88,107, 95,138,144,111, 10,152,216,129, 88,120, 2,150, 94, 68, 82,123, 48, 18,162, 30,179, 95, 12, 31,145,254,226, - 85,220,175,118, 38, 88, 42, 84, 33, 2, 4,188,142,232,232,232,143,102,207,158,125,181,121,243,230,142,118,118,118,168, 87,175, - 30,142, 30, 61,138,175,190,250,170,228,154,134, 13, 27,130, 82,138,140,140, 12,252,248,227,143, 73, 9, 9, 9, 31, 85,196,249, -248,241,227,167,219,183,111,111, 91,167, 78, 29,157, 84, 42,205, 2, 32,207,202,202, 82,100,100,100, 16,181, 90, 13,158,231,121, - 75, 75, 75, 46, 33, 33, 65, 63,100,200, 16,205,245,235,215,107,228,231,231, 71,191,139, 5,203,221,221, 61, 52, 61, 61, 61,155, - 16,242,206, 46, 28,138,197,149,157,157,157,125, 94, 94, 30, 15, 32,179, 42, 46, 28, 88,150, 69,147, 38, 77,112,230,242, 61,156, -188,112, 29, 57, 9,207,240,249,103, 31,161, 94,189,122, 56,115,230, 76,149,243,172, 65,131, 6, 56,125,254, 42,174,222,125,128, -232,240,135,248,226,243,207, 80,183,110, 93,156, 62,125, 90, 40,208,239, 65, 96,181, 39,132, 20,127,137,191, 37, 87,107,219,147, - 6, 46, 53,101, 59,230,119,175, 81, 91,210,101, 62,136,196, 4,251,125, 78,183,254,122,209,154,167,245, 28,201,136, 71,201,149, -207,246,122,205,138,149, 76, 31,215,117, 32,187, 31, 60,169, 53,252,131,230,238,216,124, 84, 57, 23, 0, 6,183,241,198,237,231, -169,184, 21,158,178,251,113, 10,125,252,174,145,171,231, 72,148,160,216,253,227,164, 62,237, 61,221,156,176,229,208, 85, 16,130, -131, 6, 53,180,148,210,230,117, 60,177,114,251,155, 51, 6,157, 60,126,222,167,126,122, 38, 52,167, 59, 0,116,173,109,122,170, -105, 13,107,143,202, 44, 25, 38, 50,241,216,238,253, 63, 84,176,225, 71,129, 87,231, 65, 88, 13, 84, 58, 30,137,105,185, 40,176, -116, 71,208,141, 7,170,108,181,118,202,227,148,170, 89,237,194, 82,105, 84, 67,103, 18,147,151,175,114, 86,218,215, 80, 51, 34, -158,207,211, 80,220, 14,123,149,243, 56,145, 62, 51,132, 35, 50,146,106, 91,186,145, 54, 27,182,237,155, 39,145,202, 6, 51, 4, -196,193,202,212,126,195,242,239, 97,110,110, 6, 94,155, 7,228,167,162,223,132, 69,169,143,226,117,222, 0,224,107, 71,204,218, - 86,151,110, 19,139, 72,220,197, 8,237, 55,149, 61,131,232, 49,110, 68, 96, 67, 9,175,205,199,164, 31,247, 98,227,204, 62,248, -176, 83,109,201,137,107,225,227, 0, 44,168,106, 94, 83,142, 5,213,171,208,114,206,229,167, 4,184, 74,129,128,187,251,126,168, - 5,220, 51,152,163, 49, 33, 18,177, 51,169, 93,223,195, 84,202,199, 93, 3, 31,119,141, 50,238,173, 65, 60,218, 18,226,212,132, -254,242,211,183,249,155, 55,111, 57,203,139,240, 93,101, 46, 47, 4, 8,248,255, 10, 74,105,148,149,149, 85,183, 30, 61,122, 92, - 56,115,230,140,141,191,191, 63, 0,224,238,221,187, 0,128, 38, 77,154,192,215,215, 23,201,201,201, 24, 58,116,104, 90, 98, 98, - 98, 55, 74,105,133, 99,122,115,115,115, 95, 28, 56,112,192, 49, 63, 63,191,225, 55,223,124,147,226,233,233,153,163, 86,171, 73, - 86, 86, 22,207,178, 44,172,173,173,101, 13, 27, 54, 68,171, 86,173,242,110,220,184, 81, 45, 54, 54, 54, 23,192,171,170,132,191, - 79,159, 62,184,124,185,112, 18,222,251,240,139, 37,149, 74,225,239,239,239, 26, 21, 21, 21, 95,148, 62, 55,171,144,166, 37,255, - 31, 60,120,128,224,123,113, 16,107, 85,144,165, 38,224,230,161, 3,232, 61,118, 60, 88,182,234,163, 21, 30, 60,120,128,195,231, -111,194, 84, 46,198,179,103,143,113,224,192, 1,124,254,249,231,239,196, 89, 69, 84,168, 69,254,149, 2,139, 82, 26,140, 50,188, -208,214,168, 65,100,242, 60,204, 15,108,226, 58, 99,112, 64, 13, 70,159,147, 0,158,227,193, 72, 0, 7, 59, 11,236,216,177,219, -123,247,222,189, 55, 26,184, 74, 86,243, 44,251,245,163,100, 90, 96,196,179,231, 47,223,123,117,240,142, 47,219,139, 63,239, 94, -203, 6, 0,164, 98, 17, 86, 29,125,204, 2,152,255, 46,145,106,233, 70, 20,121,122,140,113,178,181,156, 59,251,211,158, 54,237, -155,248, 34,248, 86, 40, 86, 31,184,113, 89,150,130,237, 6, 23,106, 94,143, 55,117, 83, 89,179, 8,193, 87, 62,158,146,227,168, -147,212,212, 26,186, 87,151, 0,157, 26,106,141, 14,177,233, 28, 98, 51,212, 16, 43,165,184, 27, 30,167,178, 77,194,241,170,198, -153, 16, 66, 2,170, 43, 92,230, 45,252,217, 77,173,202, 99,115, 50,211, 88,169,236,166, 68,105, 34, 79, 52,134,231, 70, 28, 85, -183,243,150, 54, 6,120, 70,166,160, 5,115,166,141, 50,141, 15, 59,131,154,162, 4, 16, 74, 97, 82,187, 39,204, 77, 24,105, 27, - 47,105, 12, 0,120, 57, 89,202,126,252,238, 43,203, 41, 51,191,171,116,140, 87, 29, 66,164,245,154, 58, 77,241,247,180,198,229, -144,167,184,252, 40,250,241,229,187,207,234,118,168,231, 2, 95, 55,171,201,117, 8, 89, 18, 70,141,183,136, 22,102, 12, 11,232, -213, 37,179, 8,235, 56,146, 97, 77, 7,127, 83,230,236,193,242,224, 5,240,225, 28, 5, 97, 24,128,136, 10,103, 52,198, 94,131, -216,170, 58,221,189,239,112,193,150, 45,219,191, 15, 75,165,130,213, 74,128,128, 74,144,149,149,245, 80,169, 84, 6,214,175, 95, -127,235,164, 73,147,204, 71,140, 24,225,242,217,103,159,137, 0, 32, 57, 57,153, 95,185,114,101,194, 47,191,252,146,157,150,150, - 54, 90,167,211, 61, 50,228,131,151, 16,114,253,215, 95,127, 77,189,114,229, 74,221,102,205,154,201, 27, 55,110,204, 91, 91, 91, -139,229,114, 57,167,213,106,213,225,225,225, 92, 84, 84,148,115, 86, 86, 86, 4,128,200,170,116,223, 23, 89,171, 22, 48, 12, 51, -143, 82,234,255, 62,198, 96, 41,149, 74, 23, 0, 17,132,144,154,198,118, 15,190,213, 96,139,197,200,204,204, 68, 65,210, 99, 40, -226,158,163,190,169, 8,117,172,205, 96, 97, 97,241, 78, 98, 40, 59, 59, 27,200,143,199,213,171, 15, 0,150,133,165,165, 37, 44, - 45, 45,255,118,129, 85,158, 22,249,183, 91,176,222, 66, 93, 7,242,185,181, 12, 43,199,246,172, 33,245,242,112,131, 38,238, 46, - 30,196,230,225,235, 22,205,194, 24,185,185,122,236, 71,125,154,244, 31, 88, 13,237, 91, 53, 37, 94,206,150,147,151, 44, 95, 63, -161,174, 35,249,234,113, 50, 93,101,200,131, 31,167,208, 23,181, 29,200,150, 75, 15,227,198,185, 41, 85,224,121,138, 75,143, 18, -241,232, 85,230,150, 39, 41,244,133, 49,145,168,235, 66, 58,139, 33,218, 75, 41, 85, 88,154,154,230, 54,108, 80,203,174,115,203, - 6,162,110,237,154, 64,202, 0, 87,111, 63,192,212,229, 7,111,242, 60,237, 25, 98, 96,247, 96,225,140,193,215,133, 83,225,140, - 65,253,107, 51, 6, 41,165,180,112, 22, 97,197,195,186, 24,134, 36, 21, 68,223,113,146,216,250, 64, 21,121, 9,175, 50,121, 68, -167,228, 34, 71,236, 4, 77,124, 60, 64,249,152, 32, 74,171, 92,154,237,236,236, 28,188,235,248,214, 88,179,237, 0,116, 5,217, -120, 17,180, 21,121,153,137,248, 97,195,209, 26,110,110,110,237,226,226,226,130,141,168,100,124, 47, 28,223,237, 0, 10, 48, 18, - 57, 78,172,219,135, 52, 91, 19,216, 41,165,224, 85,169, 24, 59,101,132,101,247, 46, 35, 44, 1, 32,250,217,125,120, 42, 85, 6, -241,234,108,209,127,112, 7, 63, 43,232, 85,216,118,250,190, 90, 4,116,219,126,246,113,100,135, 90, 86,138,193, 1,158,214, 11, - 18,178, 6,160,138,206, 64,139, 45, 88, 37, 22,189, 42,204, 30,220, 79, 41, 87,219,158, 68,238,189,158, 98, 58,176, 75, 99,165, - 84, 76, 8,205,139, 7, 53,177,195,250,109,251,243,100,122,108, 18,154, 78, 1, 2, 12, 67, 65, 65, 65, 8, 33,164,222,244,233, -211,135,205,153, 51,167,173,169,169,169, 55, 0,228,231,231,191,208,235,245,151, 1,236, 54,102,182, 95,145, 96,138, 32,132,188, -136,140,140,116,220,185,115,167, 21, 0, 69,209,105, 53,128, 44, 0,201,239, 50,131,176, 88, 76, 17, 66,230,189, 71,209,112,178, -136,179,102, 85,238, 23,137, 68, 28, 33, 4,132, 16,200,229,114, 92,185,114, 5,131,122,118,193,147, 19, 89,240,183, 50, 67,179, -209, 99,177,247,220, 57, 48, 12, 3, 66, 8, 24,134, 49,170, 29, 17,139,197,184,122,245, 42, 62, 28, 58, 16,114, 49, 96,105,105, -137,233,211,167,227,200,145, 35, 16,139,133,213,244,254, 18,129, 5,130, 5,231,182, 46,146,130,211,227,216,214,101, 56, 30,154, -167,125,150,138,175,253, 82,177,242, 0,114,249,212,229,219,199,157,187, 26,186,244,227, 33,189,148, 29, 59,116, 65,199,246, 29, -196,117,155,182,155, 11, 96, 85,169,134,186,115, 69,190, 50, 56, 30,223,111, 58,253,116,236,222,160,112, 2, 93, 46,134,116,109, - 74, 57, 30,223, 87,210,248,191,197,105,105, 98,182,247,234,141, 27,214,208,229,225,213,253,139,138,106,222, 53, 0, 78,135,136, -136,231,248,101,219, 33, 62,232,246,179, 29, 90, 22,147, 34, 51,104,190,161,156,133,138,138,133,165,169,204,175,187,191,229, 41, - 30, 20, 86, 74,105, 45,202,115,176, 82, 74,106,117,173,109,122,138, 82, 74,205, 77, 36,181, 40,167,175,148, 83,165,101, 55,110, -251,109,203,207,159,124,242,137,105, 90, 92, 18, 18,114, 66,145, 39,115,133, 94,233,142,200,251,151, 85, 5, 26,182,210,198,187, -162,244, 76, 75, 75, 75, 9,185,149,129,189, 27, 22, 67,175,213, 32, 37,174, 80,163, 38,164,229,192,194,206,245,134, 49,156, 58, -150,207,238, 63, 98,140,212,196, 28, 38, 31,246,239, 37,139, 76,215,160,145,139,121, 97,101,145,151,138, 39,231,175,162,125,126, -161, 94,139,138, 21,193,179,129,139, 65,225, 52, 87, 72, 39,117,111,236,138, 23, 49,137,184,242, 56,126, 91, 84, 58, 77,168,110, - 75,182, 69, 38,100,141,235,211,194, 3, 43,142,132,125, 81,158, 40, 42,143,179,142, 35, 25, 6, 32,160,112,144,187, 10, 20, 8, -168,227, 72,134, 25, 50,115,176, 44, 78,177, 20,195,127, 62, 21,253,205,254, 59,105,125,102, 12,111, 99,209,170, 85, 15, 25, 88, - 45,114, 85, 26,125, 88, 38,205,121,151, 60,122, 7,235,164,192, 41,112,254, 43, 57,139,196,206,142,162,237,125,114, 38,224, 13, -191, 76,239, 26,247,210,221,129,148, 82,113,145,245,170,194, 65,238,149,113,150,238, 14,164,148,158, 44,178, 94, 85,104,197,122, -147,147,231,249,132, 38, 77,154,216,244,238,221, 27, 28,199,225,249,243,231,136,142,141, 69,231,113, 95,192,202,202, 10,151, 31, - 62,196,179,103,207, 48,111,222, 60,232,245,122, 28, 62,124, 56,174, 50, 78,177, 88,172,171, 81,163,134,180,111,223,190, 96, 89, - 22, 81, 81, 81,136,143,143,199,212,169, 83, 97,105,105,137,144,144,144, 18,206,180,180, 52,136,197, 98,221,223, 81,150,254,255, - 8, 44,128, 3,167, 71,246,185,249, 88,117, 5, 58,157, 30,181, 30,167,208,151,165,206,175,175,111, 75,142, 61, 12,125,250, 34, -228, 90, 71, 25, 82, 30, 21,222, 99, 4,194,211,104, 98, 83,119,113, 46,116,185, 22,136, 58,133,151,201,185,121,225,105, 52,209, -216, 72, 80,158, 35,208, 21, 0,137,119,113,253,114, 48,130,110, 62,192,157, 71, 79,185,235, 33,225,123, 69, 60,190, 15, 75,163, -207,171,240,213, 1,179,158, 43, 48,234, 81,132, 71, 83, 95, 71, 15,112, 44, 40,175,135,229,144,221, 24, 29,214,202,163,105,117, - 43,143, 66,203,149, 30,214,159, 94, 4,126, 86, 84,200,119, 39, 70,183, 41,192, 91, 62, 32, 55, 43,189, 69,167,118, 45, 77, 45, -107,119, 71, 90, 68, 56,158, 63,184,170, 10, 9,141,188,126, 39, 70,247, 78,214, 17, 87, 87,215,182,157,218,249, 97,200,216,217, -208, 21,100, 35, 42,232, 55,228,101, 36,225,202, 13, 51, 60,205,201,105, 9,192, 96, 11,214,245,104,125, 93, 0, 8,240,146,198, -152, 67,227,244, 81,175,222,144, 19, 53,120, 77, 14, 72, 65, 26, 34,227,181,217, 3, 54,196,114, 0,160,148, 19,177, 41,205,182, - 48,132,183,142,167,173,143,146,209, 99,251,185,199,224,249,194,101,150,120, 30,235,183, 95,140, 28,247,253,135,141, 80,199,195, -186, 1, 41,114,126, 98,112,165, 73,209,230,206,222,239,106,169, 47,204, 5,120, 29,174, 78,182,169,213,102, 85, 70,155,170, 90, -194, 30,197,211,120, 0,227,106,187,144,141,147, 87,157,158,219,228, 92, 88,192,151,159,246,177, 0, 21, 22, 70, 23, 32, 64,192, -223,143,188,188,188,177,163, 71,143,222, 40,145, 72,236, 1, 16,158,231,193,243,188,120,233,210,165, 18,142,227, 68, 34,145,136, - 99, 24,134, 61,121,242,164,158,227,184, 84,181, 90, 61,182, 50, 78,150,101, 35,199,143, 31, 95,163,178, 25,135,123,246,236,129, - 88, 44,214,177, 44, 27, 41,228,196,251, 20, 88, 20,223,181,254,112,254,124, 0, 4, 20,223,190, 33,174, 0, 0, 15,211,105, 66, - 93, 7, 50,181,110,211,118,243,139,239, 49, 54, 0,106,142, 27,216,180,158,239, 30, 0,208, 80,238,195,170, 68, 34, 71,163, 26, -220,176,105,203,189, 60,165, 98,150,210, 45, 34, 30,127,168, 89, 60, 49,100,230, 92,121, 72, 72,201, 10, 41, 94,192,153, 7,253, -179, 91,176,200, 29, 3,165,148,150,116, 11, 46, 83, 32, 45, 91, 83,169, 31,167,171, 47, 52, 93,154,122, 72,199,156,189,118,127, - 44,199, 81, 39,134, 33, 73, 42, 45,187,241, 93,197, 21, 0,196,197,197, 5,215,113, 32,103, 31, 54,112,236,106,167, 44,178,106, - 21, 0,105, 5, 56, 27,151,146, 27, 92, 21,206,204,124,125,159, 57, 43,143, 28,149, 73, 24, 49, 40, 45,116, 4, 74, 41,212, 58, - 46,163, 88,132,213,183, 37, 46,211, 15,179,123, 24,134, 68, 87,198,119,235, 89,226,138, 33, 75,206,127,245,248, 85,230,150,151, -153, 52, 20, 0, 94,102,210,208,154,182,100,110,100, 82,238, 87,161,209,153,203,140, 29, 55, 65, 9,174, 52, 29, 50,255,173, 99, -239,154,158, 79, 18,232, 3, 0,253,234, 58,144, 46, 67,190,252,229, 75, 66, 32, 44, 19, 33, 64,192,255, 35, 20, 91,177, 68, 34, -209,130,247,200,121,146, 16,210, 3, 64,132, 17,247,220, 2, 80,239, 61,199, 45, 29, 64,186,144,203,255,144,192,122,156, 66,215, -195,128,197,156, 13,189,174,220,251, 19,232,121, 0,182,239, 18,137, 34, 14,155,247,153, 48, 15,147,233,220,191, 34,193,139,196, -212, 95, 50,150, 39, 44,133, 6, 2,128,143,143, 15,141,136,136,192,187,122,193,125,146, 74, 31,224,141, 37, 23,202, 18,217, 0, -218, 24,194, 23,158, 70,191, 7,222,238, 2,142, 72,167, 63, 0,248,161, 74,113,174,162,167,118,131,203, 86, 10, 61, 7, 84,238, - 77, 95,128, 0, 1,255, 77,145,245, 23,112,158, 20, 82,246,255,185,192, 18,240,239,197,243,231,207,137,144, 10, 2, 4, 8, 16, - 80, 46,184,191,128, 83,112, 58, 44,224, 53,136,132, 36, 16, 32, 64,128, 0, 1, 2, 4, 8,120,191, 32, 0, 58,151, 41,197,141, -152, 29, 64, 8,233,108,180,212,175,132, 95,224, 20, 56, 5, 78,129, 83,224, 20, 56, 5,206,255, 30,103,101,220,255,153,217,137, -180,212,224,229,247,189, 1,232, 44,112, 10,156, 2,167,192, 41,112, 10,156, 2,167,192,249,255,109, 19,186, 8, 5, 8, 16, 32, - 64,128, 0, 1, 2,222, 51, 4,129, 37, 64,128, 0, 1, 2, 4, 8, 16, 32, 8, 44, 1, 2, 4, 8, 16, 32, 64,128, 0, 65, 96, - 9, 16, 32, 64,128, 0, 1, 2, 4, 8, 2, 75,128, 0, 1, 2, 4, 8, 16, 32, 64, 64,213, 65,140, 92,153, 68,128, 0, 1, 2, - 4, 8, 16, 32, 64,128, 33, 2,171,104,125,221,226,117,118, 5, 47,224, 2, 4, 8, 16, 32, 64,128,128,191, 87,144,252,199,180, -136,208, 69, 40, 64,128, 0, 1, 2, 4, 8, 16, 32, 8, 44, 1, 2, 4, 8, 16, 32, 64,128,128,127,135,192,106, 79, 8,161, 0, -218, 11, 73, 34, 64,128, 0, 1, 2, 4, 8,248, 7,240,159,210, 34, 37,131,220,133,241, 87, 2, 4, 8, 16, 32, 64,128,128,127, - 84,148,252,135,180,136, 48,139, 80,128, 0, 1, 2, 4, 8, 16, 32, 64, 16, 88, 2, 4, 8, 16, 32, 64,128, 0, 1,255,219,248, - 75, 7,185, 19, 66, 58, 11,156, 2,167,192, 41,112, 10,156, 2,167,192, 41,112, 10, 2, 75,128, 0, 1, 2, 4, 8, 16, 32, 64, -128, 32,176, 4, 8, 16, 32, 64,128, 0, 1, 2, 4,129, 37, 64,128, 0, 1, 2, 4, 8, 16, 32, 8, 44, 1, 2, 4, 8, 16, 32, - 64,128, 0, 1,130,192, 18, 32, 64,128, 0, 1, 2, 4, 8,248,135, 64, 0,148, 57, 19,128, 82,122,222, 96,146, 42,204, 38,168, -140, 95,224, 20, 56, 5, 78,129, 83,224, 20, 56, 5,206,255, 30,103,101,220,198,232,143,255,105, 80, 74,255,178, 13, 64,103,129, - 83,224, 20, 56, 5, 78,129, 83,224, 20, 56, 5,206,255,111,155,208, 69, 40,192, 80, 43,165, 35, 33,196, 81, 72, 9, 1, 2, 4, - 8, 16, 32,160,114,136,223, 39, 89,109, 66, 58,142,175,239,184,127,194,131, 36,155,202,174,117,112,112,216,168, 84, 42, 71, 20, - 20, 20,228, 19, 66,248,210, 22, 53, 0,165,221,203, 71,165,164,164,180,169,140, 79, 46,151,175,116,116,116,252, 52, 47, 47,175, -128, 16, 66, 9, 33, 32,132, 20,139,131,215,126, 57,142,139, 75, 75, 75,107,242,175, 22, 60, 0, 99,231,232,120, 91,194, 48,174, -198,222,203,241,252,203,228,164,164,150, 70,136,171,197,132, 96, 70,209,255,159, 40,165,179,255,131, 10,146, 49,228, 50,127,192, - 60, 28, 24,194,137, 68, 95, 72,128,181, 26,158,223, 80, 84,112,185,170, 62, 90,123,155,212, 32, 20, 13, 8,129, 37,165,200,166, - 4, 15,100,205,104,228, 63, 36,164, 91, 72, 36,146,193,214,214,214,230, 41, 41, 41, 23, 0, 28, 5,240,129,131,131, 67,167,204, -204,204, 92,189, 94,191,143, 82,122,179, 42,220,109, 27,146,153, 50,169,228, 99,181, 78,255,227,213,251,244,183,246,141,137, 45, -203, 99,137, 66, 42,110,163,209,178, 63, 93,121, 64,183, 24, 25, 86,242,134, 53,222,232,101, 41, 14, 24,152,239, 0,112,216,218, -218, 87,110,111,113, 65, 34, 99, 94,102, 37,231,141, 24,152,146, 18, 59,240, 29,242,253,127, 17,246,246,246,163, 68, 34,209, 66, - 74, 41, 56,142,251, 58, 61, 61,125,235,123, 42, 87,195, 0,152, 22,237,230, 83, 74,119, 27,113,111, 52, 0,143,162,221, 24, 74, -169,103, 69,199,255,163, 31,184,235, 15, 29, 58, 52,174, 67,135, 14, 88,177, 98, 5,214,175, 95,255, 42, 53, 53,117, 9,128,109, -148, 82,237,255, 42,183, 32,176,222, 19,234, 16, 82,239,147,110, 45, 79,140, 29,212, 77,102,192, 75,252,107,183,110,221, 62,220, -182,109,155, 36, 60, 60,220,196,203,203, 11, 34,145,168, 68, 0,149,174, 39,171, 85,171,198, 87,198,199, 48,204,170,126,253,250, -141, 62,112,224,128, 50, 36, 36, 68, 89,187,118,237, 18, 62,158,231,241,102,189,235,229,229, 85, 33,159,165,165,229, 93,134, 97, -220,202, 18,103,229,253,231, 56, 46, 46, 61, 61,189,137, 1,133, 57, 16,192, 44, 3,146,116, 9,165,244, 76, 69, 23, 72, 24,198, - 53, 33, 33,193,193,216,188,114,119,119,215, 25,241,242, 57, 18,130, 25, 60, 79, 69, 0, 32, 18,145,153, 38, 38, 38,235, 85, 42, - 85,108,241,249,162, 60, 75, 54, 38, 12,110,110,110,221,121,158, 31, 86,200, 41,218, 29, 23, 23,119,202,152,251, 45, 44, 44,238, -202,100, 50, 55,177, 88, 76,202,202,151, 55,247, 57,142,163, 58,157, 46, 46, 35, 35,195,104, 97, 29, 12,144,110, 64, 91,150, 97, -166,216,218,217,181, 9, 57,123,214,212,223,223, 95,196, 48,204,108, 0, 27,222,229,189,209,222, 38, 53, 56, 61, 6,169,244,242, - 94,114,207,111,125, 53,209,223,134,155, 72, 52,199,181,183,201,254,191, 91,100, 17, 66,186,141, 28, 57,114,209,143, 63,254,104, - 39,147,201, 68,251,246,237,107, 57,117,234,212,143, 87,172, 88,225, 58,120,240, 96,115,173, 86,203,207,156, 57,179, 45, 33,228, - 59, 74,233, 17, 99,184, 91, 53, 36, 45,252,188,156,231, 77, 28,209, 17, 95, 45,222, 51, 49,160, 30, 73, 51, 49,149,174, 31,208, -166,134, 85, 93,111,107,124,183,241,250, 36, 0, 91,140, 8, 43,145, 72, 36, 13,157,156,156,188, 52, 26, 13, 87,244,209, 70, 75, -213, 9, 0, 0,141, 70,163,203,204,204, 60,249,174,105,243,149, 66,209,188,185,149,217,185,249,195, 70,154,228,100,102, 56,174, - 58,113,244,225, 1, 56,212, 31, 8,188,250, 47, 53, 8, 34,145,104, 97,124,124,188, 51,165, 20,206,206,206, 11, 1,108,125, 79, -212,166,197,245, 48, 33,196,212,200,123, 61, 74,221,235, 97,192,241,170,148,125,133, 88, 36, 26, 47,147, 72,186,114, 28, 87,175, -168, 12, 61,210,234,245,231, 88,158, 95, 75, 41, 85,255,195, 89, 51, 99,220,184,113, 93,230,204,153,227, 53, 99,198, 12,204,152, - 49,163,218,230,205,155, 55, 46, 90,180,104, 38, 33,164, 62,165, 52,239,127,148, 91, 16, 88,239, 65, 92,185, 7, 54,244, 13,250, - 98,228, 32, 41,127, 96, 37,193,168,111, 42, 20, 87, 45,155, 52,249,120,219,182,109, 0,128, 17,125,250,160,107,179,102, 48, 55, - 51,133, 76, 86, 24, 28, 66, 9,164, 18, 41,250, 78,157,102,200,139,241, 83,255,254,253,135, 31, 56,112,192, 12, 0,214,175, 95, -143,254,253,251,195,198,198, 6, 74,165, 18, 82,169, 20, 18,137,228,181, 95, 3, 4,155, 91,124,124,188,131, 66,161, 40, 17,124, - 60,207,191,182,149,234,135, 6,203,178,240,241,241, 49, 52,185,102,101,103,103,183,205,207,207,175,176,239,214,219,219, 27, 0, -206, 24, 66, 56,103,198, 88,112,108, 62,196, 12,192,178,128, 70, 75,193,151,241, 45,239,226,226,134, 25,115, 22,227, 93,214,159, -236,217,179, 23, 0,172,119,117,117, 61,158,156,156,236, 79, 8,198, 86,197,178, 69, 41,253, 40, 34, 34, 66,201,243, 60,252,252, -252, 62, 4, 96,148,192, 18,139,197,110, 15, 31, 62,116,144,203,229,229, 90, 42, 75,137, 95,232,116, 58, 52,106,212,136, 53,230, - 25,142,128, 71,134, 72,244, 89,195,198,141,199,204,239,219, 87,113,251,246,109,133, 72, 36, 2,203,178, 88,186,116, 41, 75, 41, -181,170, 3, 88,132, 1, 57, 21,148,207, 57, 0, 70, 21, 89,101,183, 80, 74,151,190,118,158,162,129, 74, 47,239, 21,149,215,183, - 89,243,106, 51, 17,246,248, 81,179,234,102,135, 97, 46,214, 68, 2,248, 91, 5,150,165,165,229,192, 21, 43, 86,216,111,217,178, - 37,231,217,179,103,186, 13, 27, 54,216,143, 29, 59,182,150, 78,167,195,184,113,227, 82,253,252,252,164, 43, 86,172,176, 63,116, -232, 80, 32, 0,163, 4,150,152,224,251,161,125,186, 66,173, 23, 65,175,103,237,157,237,205,119, 76, 30,217, 94, 66,169, 22,219, -143,132, 64,207,242,191, 25,105,185,106, 56, 96,192, 0,207,221,187,119,139,159, 60,121, 34,174, 93,187, 54, 56,142, 43,217,120, -158, 7,199,113,240,245,245,125,231,116,249, 24,240,181,115,180, 57,215,178, 71,119, 19,103,133, 28, 54,153,169,248, 68, 42, 54, -223,170,212,236, 4,208,234,191,212, 32, 80, 74, 33, 22,139, 17, 27, 27, 11, 7, 7, 7, 19, 27, 27,155, 68, 0,223,102,100,100, -108,250,139, 68,125,149, 45, 91,239, 49, 12,205,100, 98,241, 31,219,127, 91,229,212,188, 85, 43,198,209,217, 1,225,207, 99, 32, - 38, 92,231,135,119, 66,218,127,252,249,151,147, 9, 33, 3, 40,165,183,255,137, 60,113,110, 49,161,159, 83,171,137,235, 65, 41, -230,255,114, 52,119,209, 79, 43,149,159,127, 54,146,153, 58,117, 42,220,221,221,189,250,245,235,247, 19,128,207,171,196,221,122, - 66, 63,231,128, 47,214, 19,202,227,187, 53, 71,115, 23,255,180, 82, 57,238, 61,113, 11,120, 15, 2,203,159, 16,171,250,158,142, -193, 63,204, 24,107, 70, 79,253, 46, 42, 72, 79, 65,121, 18,198,193,193, 97, 99,247,238,221, 71,108,221,250,231, 71, 81, 75,127, -127,244,235, 24, 0, 7, 91, 75, 40, 77,101,133,205, 16, 79,240,224,217, 75,131,132,128,187,187,251,184, 63,254,248,195,236, 79, - 17,225, 2,169, 84, 90,178,149, 22, 87,197,219,155,150,142,178,160, 80, 40,112,254,252,121,136,197, 98, 48, 12, 3,177, 88, 92, -178,149,222,103, 24, 6,142,142, 70, 13, 77, 90, 98,105,105, 89, 63, 55, 55,215, 34, 43, 43, 11, 30, 30, 30, 57, 0, 30,150, 58, - 95, 63, 53, 53,213,194, 24, 66, 78,159,135,121,211,186, 64,162,189, 5,157,180, 41,212,146, 86,184,118,251, 41,142,157,190,140, -248,196, 36,180,105,217, 0,163,134,245,199,158,157,155,192,113,156,177, 21,110, 50, 33,228,167,222,189,123,205, 4, 8, 58,116, -232,144, 60,121,242,100, 26, 26, 26,218,111,208,160,129,157,158, 63,143, 32, 69,150,173, 25,132,144, 85,134, 90,178, 40,165, 82, - 0,184,124,249, 50, 40,165,178,170,148, 61,185, 92,142, 27, 55,110,160,184, 59, 88, 36, 18, 65, 36, 18,129, 97, 24, 28,139,176, - 67,190, 86,132,130,228, 80,124,209,203, 3,222,222,222, 16,137, 42, 31,114,216, 30, 80, 92, 7,250, 17,137,100,170,179,139,139, - 87,187,234,213,149,231,207,159,103, 0,192,211,211,147, 38, 38, 38,102, 29, 57,114, 36, 87, 12,172,247,164,116, 91, 69,226,202, -195,195,163,181, 72, 36, 90, 88,156,230,132,144,159,188,188,188,230, 21,159,231,121, 30,195,186,216, 72, 38, 79,158, 34,109,222, -190,240,163,164,121,239,221,200,137, 90, 92,155,100,204,177,252,187, 43,131,236,236,236, 29,190,190,190, 76,106,106,234, 69, 0, - 47,244,122,253,154, 29, 59,118, 56,124,242,201, 39, 41, 59,119,238,156, 8,192,125,233,210,165,129,121,121,121,123,141,225,109, -211,128,244,104,210,208,191,133,135,187, 59,130,175,223,134, 84, 38,177, 26, 63,170, 23,204,204,196, 88,182,229, 4, 31, 29,151, - 49,241,202, 3,186,205, 8,113, 85,127,224,192,129,238,187,119,239,150, 2, 64,104,104, 40, 82, 82, 82, 96,107,107, 11,133, 66, - 81,242,206, 23, 91,177,222, 85, 92, 89,186,219,222, 58,124,248,136,137,141,141, 21,214, 76,155,140,143, 18,226, 96,193,136,160, -215,195,235,191,212, 24, 16, 66,124, 7, 12, 24,160,224, 56, 14,249,249,249, 8, 10, 10,178, 52, 49, 49,177,116,115,115,155, 15, -192, 96,129,101, 98, 98,146,172, 86,171, 29,138,234,209, 20,149, 74,229, 8,160, 64,161, 80,152, 20, 93,162, 50,210,178, 21, 83, -202, 66, 21, 99,192,113, 99,226,220,180, 89,211,250,231, 15, 30,216,101,150,157,155, 4, 43,235, 20,136,144,141, 77,155,214,194, -196,196, 2,243,231,207, 17,191,236,220,209, 53,176,199,128,243,132,144,206,255,132,200,162, 4,155,234,181, 29,108, 35, 83, 20, - 54,115, 60,167,199,134, 61, 95, 65, 36, 18, 97,222,236,177, 24,218,219,123,204,131,157,228,116,221,234,200, 45,172, 91,161,146, -136, 16,131,102, 52,197, 0,242, 77,157,123,143,176, 49, 81,154, 23,114,179,122,108,221, 60,185,144,123,222, 60,212,173, 91,119, - 12, 33,228, 27, 74,105,198,223, 80,254,218, 81, 74,131,203,219,255, 87, 10, 44, 66, 8,165,148,150,238,102,121,109,191, 34, 84, - 35, 68,238, 99,109,118,102,221,183,147, 93,152, 27, 39,196,170,152, 8, 36,168, 57, 88,253,217,136,190, 54,213, 82,169, 84,142, -216,186,117,235,107,250,203,195,209, 1, 82,169, 4, 18, 41,129, 85,155, 94, 0,128,172, 43,199, 65, 8, 45,175, 97,126,141, 51, - 63, 63, 95,125,255,254,125,179, 45, 91,182,192,193,193, 1, 94, 94, 94, 80, 42,149, 37, 21,109,233,173, 88,104,189, 41,176,222, -228, 44, 62, 47, 22,139, 33, 18,137,112,238,220, 57,176, 44,139,129, 3, 7,190, 37,174,196, 98,113,153,130,173,188,105,166,148, -210, 51,132,144,135,148,210,182, 69, 13,239, 67, 74,105,187, 82,207, 14,180,183,183,159, 5, 96,137,161,156, 98, 49,192,168,175, -131,119, 91, 5, 38,118, 18,116,124,125, 92,188,122, 15,191,111, 92, 9, 0,240,174,213, 4, 67,251,119, 7, 79, 11,173,111,134, -112,190,246,149,227,236,188, 45, 53, 53,173, 81,135, 14, 29,144,157,157,173,157, 63,127, 62,234,215,175, 15, 31, 31, 95,131,242, -168,156,151, 41,237,193,131, 7,206,106,181, 26,132,144, 52, 3, 4,217,249, 50, 56,176, 99,199, 14,168,213,111, 91,239,173,219, - 45,194, 87,253, 61, 49,250,139,109,248,233,217, 62,172, 91,183,174,194,184, 43,129,250,106,203,154,171,100, 12, 91,127,201,156, - 9,242,143, 62,250,136, 25, 61,122, 52, 98, 98, 98,240,201, 39,159,168,207,157, 59,167, 77, 74, 76, 60, 34,227,249, 53,186,215, - 5,113,185,156,114,185,124,251,153, 51,103,176,111,223, 62, 0, 64,120,120, 56,124,124,124, 94,107, 68,248,140,253,200,141, 94, -131, 91,199,158,162,121,239,221,184,117,108, 24,184,172, 19,146, 38, 62,200, 54, 38, 61,171, 96,169, 56, 95,198,177, 32, 0, 65, -165,210,247,155,157, 59,119, 14, 2,112,144, 82,122, 29,192,117, 0,123,140,225, 44, 36,194,232,193,253,251, 66, 44, 53,199,211, -136, 56,180,107,217, 8,142, 14, 14,120,248, 36, 18,209,241, 25,201,132, 96, 84,183,214,242, 37, 42,149,246,155,203,247,233,175, -149,113,186,187,187,123,239,223,191, 95, 82,202,226, 12,134, 97, 94,251,160, 42, 62, 86,213,242, 89, 44,174,204,221,204,110,125, -191,182,181,233,173, 71, 59,225,227,217, 3, 22,129, 61,176,124,207,110,196,165,101,171,217, 2,182,211,223,157, 71,127, 21, 39, - 33,196,183,127,255,254,215,119,237,218,101, 21, 27, 27,139,203,151, 47,195,203,203, 11, 5, 5, 5,149,126,232,190,201,169, 86, -171, 29, 74,137,166,226, 33, 12,123, 52, 26, 77,113, 69, 73,141, 9,103,121, 99,171,140, 29,115, 85, 70, 61, 47, 83, 72,165,251, - 15, 31,220, 99, 22,246,244, 50, 26, 54,104, 1, 51,203, 58,224,185, 36,164,103,228, 33, 51, 34, 1, 63,252,240, 19,230,127,251, - 53,142, 30, 58, 96,230, 87,187,193, 31,132,144,154,165,187, 11,255,142, 60, 34, 20, 99, 66, 47,239, 91, 15, 74,161, 74,121, 42, -151,170, 94, 40, 71, 14, 31,196,124, 52,180, 43,110, 94, 92,133,174, 13, 95,132,186, 56,160, 95,102, 81, 71,158,152, 65,186, 92, -129,107, 38,183,201,205, 98,145, 85,254,187, 73,199,156, 63,182,115, 61,161, 60, 84,201, 79,229,146,252, 23,202, 17,195, 6, 48, - 67,134, 12,193,209,163, 71,241,248,241,227,245,229,137,171,191, 32,238, 65, 69,223, 80,197,194, 42, 8,133,174,164,254,253, 22, - 44, 99,132, 85,209,245, 76, 99,153,248,224,111,243, 39,248, 43, 94,133, 74, 53,161, 55,144,160,225,233,150, 24, 54,115,101, 57, -247, 20, 20, 20,228, 71, 70, 70,154,140,234,215, 15,173,252,253,225,108,107,139,154,110,110, 48,145,203, 32,147, 74, 74,213,199, - 70,169, 94,234,231,231,135,222,189,123, 67, 34,145, 64,169, 84,194,204,204, 12, 50,153,172, 76,235,149, 68, 34, 49,216, 84,206, - 48, 12, 66, 67, 67, 17, 29, 29, 13, 43, 43, 43, 92,187,118, 13,157, 58,117,122,203,138, 85, 90,148, 25, 99,138,127,179,193, 47, - 22, 96, 48,176,107,176, 24,122, 61,144,143,250, 80, 68, 79,132,138, 52,128, 86,171,131, 86,163,193,175, 87,117,184, 29,153, 15, -157, 78, 11,173, 70, 93,238, 51, 43,178, 22, 56, 57, 57,245,171, 85,171,214,136, 97,195,134,105, 37, 18, 9, 10, 10, 10, 80, 80, - 80,128, 39, 79,158,104, 3, 3, 3,147,123,247,238,229,120,226,196, 9, 74, 41,126, 50,102, 28, 22,165, 52,211,197,197,197, 89, -161, 80,128, 82,154, 89,197, 47,158, 18,241,242, 38, 70, 45, 15,131,152, 41,204,147,245,235,215,131,227, 56, 84, 84,190,213,132, - 92,248,118,209,207,150, 63,174,252, 13,150, 54,142, 8, 14, 14,230, 78,159, 62,157, 75,128,240,231,143, 31, 47,255, 0, 56,185, - 31,208, 25, 19,190,204,204, 76, 19, 47, 47, 47,184,185,185,129,231,121,232,245,122, 60,124,248, 16, 73, 73, 73, 72, 79, 79,135, - 74,165,130,141,105, 22,106,216,186,129,205, 13, 66, 98,232,119,112, 54,123,138,109,103,180,250,198,190,120,240, 79, 87, 14,148, -210,147, 0, 78,190, 59, 17, 92, 29,156,220, 33,162,122, 36,164,164,163,111,207,174, 96,164,102,120, 25,155,134, 6,117,170, 59, - 15,255,160,181, 51, 67, 88,204, 88,178,123, 60,128, 95, 43,163, 43, 40, 40,224,158, 60,121, 34,121,240,224, 1, 24,134,129,133, -133, 69,201,112,128,210,226,202,144,225, 0,149,137,171, 69,235, 59,153,138, 36,249,200,225,206, 99,195,239, 55,225,227,209, 9, - 91,159, 62, 87,139,179,242, 58, 47, 83,171,195,255,205,149,191,179,179,243, 88,158,231,231, 83, 74,179,250,247,239,239,184,123, -247,110,235,248,248,120,132,132,132, 96,222,188,121,169, 28,199,177,148, 82, 66, 41,253,238, 61,148, 37,190,180,101,203,196,196, -164,216,178,149, 95,202,114,149, 95,133, 58, 64,162, 84,224, 11, 59, 11,210, 71, 44,178,240, 98,115,242, 94,166,105,233,145, 2, -150,255,133, 82,170,175,232, 94,145, 72,244,233,129,189,235, 93,236,236,121,180,183,239,136,196,100, 29, 22, 77, 27,137,244,244, - 92,252,186,121, 49, 0, 25,116, 44,131,182,237, 7,192,193,193, 21, 99, 62, 27,227,180,126,227,134, 9, 0,150,253,157,249,148, -120,115,237, 33, 66,200,121,123,123,251,199,147,199,141,179,175, 93,123, 28,228,114, 57, 46,158,254, 29,234,164, 29,185, 61, 91, - 65, 87,160, 70,207,106,189,169,205,171, 99, 36, 67, 34, 65, 4, 0, 72, 20, 72,148, 0, 21, 90,177, 18,175,253,201, 61, 97,204, - 24,123, 47,175, 15,161, 80, 40,176,103,207, 30,236, 94,179,134, 91, 9, 12,218, 72,200,165,177,148, 30,250, 27,163,252,175, 23, - 86,111, 9, 44, 99, 81, 93,170,188,190,121,218,224, 70,246,188, 74,172,189,122, 12,241, 26,158, 93, 26,161,211,221,205,162, 35, - 42, 40,208,188,135,135, 7, 58, 54,105,130,126,109,218, 64, 44, 22, 67, 33,147,194, 92, 97, 2,202, 21, 90,174,138,187, 8, 13, -213,122,197,194,198,214,214, 22, 82,169,180, 68, 88, 25,106,189, 42,143,147,231,121,136,197, 98, 60,124,248, 16, 1, 1, 1,112, -119,119,199,190,125,251, 16, 24, 24,248, 86,151,161,177,226,170, 88, 96,149,238,174, 43, 53,248,189,210,193,237,111, 66,163,165, -200,210,215, 71, 38,106,131,231, 69,224,120, 10,141, 90, 13, 74, 1, 74, 1,189, 78, 11, 77,145,192, 42, 18, 26,149,114,186,185, -185,185,120,121,121, 77,155, 53,107, 70,205,250,245, 27, 34, 45, 45, 13, 60,207,195,204,204, 12, 5, 5, 5,176,176,176, 64,171, - 86,173,238, 45, 92,184, 48,131, 82,204, 50,118,144,251,123, 48, 39, 3, 0,206,158, 61,251, 90,247, 96,241,150,159, 24,135,209, -147,118, 66, 38, 6, 30, 62,124,136, 90,181,106, 85, 38, 46, 69, 29,218,182,198,245,123,225,236,167, 51, 86,105, 36,233, 33, 75, -156,120,126,107, 28,144,252, 14,141, 10,210,210,210,144,156,156,140, 62,125,251, 98,247,174, 93,120,245,234, 21,234,212,169,131, - 14, 29, 58,192,193,193, 1,175, 94,189,194,237, 43, 26,104, 50, 51,144,161, 13,129,210,188, 57, 14, 7, 71,106,230,174,211, 70, -254, 83,149, 2, 33,164, 41,128, 79, 44, 45, 45,171, 21, 20, 20, 36,233,245,250,125, 69,162, 63, 80, 34,145, 12, 86, 42,149, 78, -217,217,217,175, 0,252, 74, 41,189, 83,105,151,145, 66, 97, 43, 87, 88,128,103, 53, 16,139,197,112,119,247, 2,229,180,200,204, - 81, 97,212,144,222,184,247,240, 9, 78, 95,186,201,234,245,252,106, 67,195,232,235,235,139,244,244,116, 48, 12, 3,165, 82, 9, - 83, 83, 83,248,249,249, 33, 54, 54,182, 68, 92, 85,181,139,240, 99,192,215,194,195,236,230,194,181,133,226, 42, 41, 33, 17,241, -175, 40,228, 50, 25, 54,110, 90,159, 95,144,148,217,252, 55, 32,252,223, 94,249,243, 60,255, 93,124,124,188,131, 88, 44,118, 98, - 89, 22,177,177,177,184,123,247, 46, 38, 78,156,152,156,158,158,222,158, 82, 90,165, 56, 42, 20,138,148, 98,203,149, 66,161, 72, -169,200,178,245, 46, 99,174, 8, 33,213,189,220,204,207,109, 94, 49,213,163,105,243, 86, 34,165,216, 34, 51, 47, 34, 41,224,234, -229,224, 86, 19, 87,252, 58,129, 16,210,149, 82, 26, 85,222,253,114,137,164,123,139,214,173,197,160,201, 16,203, 2,240,211,143, - 67,144,154,150,131,204,140, 92, 72,165,166,208,234, 25,112, 60, 65,171,128, 54,248,125,219, 94,212,253,236, 19, 70, 38,145,116, -249,187, 5, 86, 17, 22,255,242,203, 47, 30,117,235,214,197,111,191,253,134, 29, 59,118,196,140,232,148,242,199,212, 17,112,208, -233,208, 45,228, 25,108,170,245, 6, 66,158,193,166,177, 31,106,178, 98, 68, 16, 2, 19, 99,184,253,252,252,176,117,235, 86, 92, -218,190, 29, 31,101,103, 35, 88, 36, 98,244, 18,137,221, 73,189,126, 19,128, 67,127, 83,221,211,174,244,239,127, 65, 96,181, 39, -133,253,113, 37,191,149,221,100,234,232, 55,108,215,135, 93,154,212,241,118, 19,233,247,173, 66,124, 1,171,158,247, 76,199, 63, -203,165, 3,194, 42, 16, 7, 34,145,136, 50, 12, 3,115, 19, 19,216, 91, 89, 21,126,105,138, 68, 0, 15,240,122,128,112,133, 47, - 31,229, 9,140,153,252,204,243, 60,100, 50, 89,153, 3,218,141, 29,123, 85,154, 51, 55, 55, 23, 47, 95,190,196,152, 49, 99,160, - 84, 42, 1, 0, 73, 73, 73,240,244,244,132, 88, 44, 70,124,124, 60, 46, 94,188, 8,111,111,111,200,229,114,163, 84, 86, 41,107, - 82,125, 66, 72, 48,128,250,137,137,137, 22,206,206,206, 48,214,130,197, 81, 64,165,165,208,104, 89, 60, 15,143, 66,108,124, 2, - 94,188,136, 68,227,252, 28, 80, 48,160, 0,180, 90, 53, 96,160, 5,203,217,217,217,207,199,199,103,225,226,197,139, 37,238,238, -238,224,121, 30, 54, 54, 86,200,207, 87, 33, 61, 61, 29,117,234,212,129,187,187, 59,126,250,233, 39,160,176,251, 40,249,159, 42, -192,197,179, 69, 75,255,138, 68, 34, 76,250,192, 3, 25, 25,102, 96,152, 63,103,147, 86, 50, 6, 75, 10, 0,237,187,246, 23,159, - 59,125,210,148, 5, 22, 36, 49,204, 2,113,229,249,168,231,120, 94, 89,222,249,216,216, 88, 72, 36, 18, 28,216,191, 31, 25,201, -201,104,208,160, 1,154, 53,107,134,136,136, 8,220,187,119, 15,182,182,182,176,119,107,137,224, 23, 58,132, 37,168, 96,105,105, -137,200, 56,209, 63, 54,245,159, 16,210,171,115,231,206,107,150, 47, 95,238,228,228,228, 36, 73, 77, 77,101,215,174, 93, 27,184, -118,237,218,176, 9, 19, 38,212,153, 48, 97,130,181,189,189,189, 56, 41, 41, 73, 63,109,218,180, 64, 66,200, 44, 74,233,158, 10, -235, 11, 83,115, 27, 70,106, 10, 66,196,176,178,180,134, 88,102, 10,158, 21,131,227, 1, 11, 75,123, 92,191,119, 0,215, 30,229, -142, 77, 73,199,126, 3,222, 27,106,107,107, 75, 25,134,129,173,173,237,107, 93,131, 0,224,232,232,136,156,156, 28, 48, 12, 3, -137, 68, 98,180,200, 42, 22, 87,139,214,118, 50, 35,165,196, 85, 94,154, 45, 46,157,121,146, 85,144,148, 25,240, 95, 16, 87,197, -117, 28,165, 20, 47, 94,188, 64, 65, 65, 1,174, 92,185,130,239,190,251, 46,245, 77,113,229,232,232,248,153,133,133,197,183,121, -121,121, 63, 37, 38, 38,174,170,140,183,200, 50,245, 62,203,100, 52,222,112,199, 64, 8,145,184, 59, 43,206,220,187,178,211,211, -146, 62, 32,136, 30, 3, 60,207,121,108,126,203,161,109,143,166, 61, 69,141,214,125, 95,173,217,216,217,103, 8, 33,126,229, 89, -178,120,142,107,100,106,102, 14, 32, 5, 33,119,131, 74,196, 85,122, 70, 54, 52, 58, 6, 26, 45,129, 90, 39, 66,199,206,221,176, -102,195, 14,196,167,100,160,120,134,225,223,252, 78,218,248,251,251,143, 27, 52,104, 16, 22, 44, 88,128,101,203,150, 29, 6, 48, -100,201, 68,180,204,204,195, 40,151,222,212,166, 90,239,194,107, 7,206,164, 0, 96,147,122,158, 84,137,251,252,242,229,218,207, - 9,201, 17, 3,244, 4,199,129,167,148,136,254,166, 65,238,148, 82, 82,220,147,102,108,143,218,255,172,192,162,148, 6, 19, 66, - 80,250,183,162, 27,172,156,252,218,125, 51,115,242,202,214,125, 58,139,146, 62, 15, 64, 86,142, 70, 59,243,137, 94, 20, 87, 64, -251,133, 25,104,121,153,190,118, 45,238,133, 23,190,191,110, 14, 14,152, 49,124, 56, 40, 11, 92,123, 28,134,189,231,207, 99, 72, -231,206, 48, 45,154,193,103,168,181,169, 44,171, 85,105,235,149,177, 86,166,172,172, 44,236,223,191, 31,205,154, 53,131, 82,169, -132, 88, 44, 70,253,250,245,241,228,201, 19, 84,175, 94, 29,132, 16, 28, 62,124, 24,253,250,245, 67, 84, 84, 20, 90,182,108,105, - 86, 21,129, 21, 22, 22,102, 65, 41,109, 91,108,237,168, 98,201,132, 86,163,198,147, 39,207,208,173,103,127, 88, 89,217,192,201, -121, 55,206,159,217, 9,165,255, 71, 32, 40, 60, 95,214, 24,172,114,210,116, 96,207,158, 61, 37, 34,145, 8, 42, 85, 1,228,114, - 5,204,204, 44, 96,110,110, 9, 95, 95, 95, 36, 36, 36, 32, 48, 48, 80,247,252,249,243, 29,137,137,137, 39,140, 13,174,163,163, -163, 50, 55, 55,119,178,151,151,151,162,232, 43,183,163,157,157,221,162,180,180,180, 60, 35, 43,158, 18, 97, 69, 8, 1,195, 48, - 37, 2, 75, 44, 18,193,217,201,161,100,191,104,246, 39,169,128, 43, 39, 62, 93, 35, 7, 0, 15, 15, 15,172,217,120, 84,212,179, -103, 79, 76,158, 60, 25,122,189, 30,235,214,173, 3, 0, 12, 27, 54, 12, 58,157, 14,127,252,241, 71,225, 11, 36, 22, 87,216,231, -124,247,238, 93,132,132,132, 64,175,215, 35, 59, 59, 27,167, 78,157, 66,240,229,203,216,115,248, 2, 94,189,136, 64,125, 63, 79, -124,242,201,199,144, 72, 36,216,182,109, 27, 2, 2, 2,254,209, 10, 65, 42,149,142,220,188,121,179,235,214,173, 91,179,142, 28, - 57,146,221,188,121,115,211,149, 43, 87, 58,172, 89,179,166,131, 86,171,197,148, 41, 83, 82,110,221,186,149,223,167, 79, 31,203, - 77,155, 54,185,214,172, 89,243, 3,148, 49, 46,171,168,219,103, 8,128, 15,219, 55,179, 20,103,229,170,192,179, 90,188,120,245, - 18,217,121, 90,240,156, 14, 49,113, 9,200, 83,115, 72,207,200, 69,253, 70, 93,127, 9, 10, 10,250,154, 16, 50,135, 82,122,188, -210,143, 10,142,195,205,155, 55,113,237,218, 53, 92,190,124, 25,209,209,209, 37,231, 44, 44, 44,112,238,220, 57,116,232,208,225, -189,136,171,220,212, 66,113,149, 21,147,241,159, 17, 87, 69,117,208,124,103,103,231,249,206,206,206,138,179,103,207, 90, 86,171, - 86, 13, 44,203,106,223,180, 92,181,111,223,254,155,205,155, 55, 59, 87,175, 94,125, 34,128, 85, 85,125, 94,121,150, 45, 3,240, -150, 59, 6,145, 8,159,253,180,126,156,157,185, 44, 38, 1,207,127, 46,242, 5,200, 0, 5, 57, 64,208, 46,136, 91,207,125, 57, -177,239, 76,235, 89, 91, 23,124, 6, 96, 93,121,196,145, 81,177, 88,191,126, 13,166, 78, 25,133,223,127,253, 9, 60, 47,134, 70, -207,192,195,171, 5, 52, 58, 30, 68, 36, 70,131, 70, 77,112, 41,232, 10, 36, 34, 96,255,214,245,255, 68, 62,101, 16, 66,214, 29, - 62,124,248,139,201,147, 39,131,231,249,190,235,215,175,127, 62,107, 77,234,193,169, 35,192,188, 58, 70, 50, 66,158,193,102,224, - 76,138, 3, 63, 18, 52,246, 67,134, 82, 81,101,110,217,183,235,215,171, 82, 83, 83, 23,227,159,241,131,117,249,141,223,127,189, - 5,171,100,108, 74, 69,138,177,177,111,245,239, 45,109,172, 63,110,213,180,182,237,180,137,159, 73,162,146,212, 56,211,100, 90, -246,209, 21,115,205, 98,120,211, 41,209, 52,199, 40,171,203,222,139, 23, 75,254, 47,221,189,187,204,115,137, 3, 7, 26,252, 37, - 86,158,213,202, 88,203, 21, 0, 40,149, 74,171, 46, 93,186,160, 83,167, 78, 24, 48, 96, 64,201,152,171,134, 13, 27, 98,207,158, - 61,232,223,191, 63,238,223,191, 15,103,103,103,212,170, 85, 11,181,106,213,194,201,147, 39,141,125,105,192,113, 28,252,253,253, -139,103, 17,214,143,139,139,179,168,210, 11, 8, 10,141, 86,141,180,244, 12, 88, 91,219, 66, 38,147,161,121,243,102,248, 98, 82, -115,216,187,252,138,250,117,125,144,151,151, 7,158,167, 6,205, 34,148, 72, 36,190, 53,107,214, 68,106,106, 42, 82, 83, 83, 97, -111,111, 15, 23, 23, 23, 56, 58, 58, 98,197,138, 21,116,229,202,149,193, 28,199,237, 72, 74, 74, 50, 90, 17,186,185,185, 53,181, -179,179,251, 34, 37, 37, 69, 81,170,210, 84, 52,104,208, 96,163,139,139,203,186,132,132,132,107,198, 8, 44,157, 78, 7, 66, 8, - 78,188,112, 65,190,150, 32, 39, 46, 4,147, 63,240,124, 77,112, 73, 36, 18, 67, 6,234,230, 15, 29, 58,212,193,221,221, 13,177, -145,143,113,224, 0,197,242,229,203,113,249,114,225,123, 30, 94,244, 65, 80,188,223,161, 67, 7,120,121,121, 25,229,220,146,231, -121, 60,124,248, 16,187,143, 4,195,217,179, 54, 98,158, 63,197,189,147,199, 80,205,222, 6,117, 27, 53,129, 94,175,127, 39, 23, - 26,239, 3, 58,157,110,147,143,143, 15,180, 90,237, 5, 0,155, 31, 62,124,216, 47, 49, 49,113,197,209,163, 71, 93, 6, 13, 26, -148,112,236,216,177,169, 0, 14, 61,124,248,112,244,194,133, 11, 59,233, 11,187, 15,222, 2,195, 48,191, 79,155, 54,173,253,160, - 65,131,136, 84,164,215,158, 61,179, 77,204,178,122, 50,125,206, 22, 46,232,106,176,136,101,245,100,192,208,105,252,201,139,143, - 68, 99, 39, 45,229, 26,182,232,137,208,208, 80,167, 94,189,122,253, 0,160, 66,129,197, 48, 12, 56,142,131, 68, 34, 41, 17,208, -101, 93, 99,140,245,234, 19,160,186,133,167,217,205, 69,107, 59,155, 17,113,222,127, 94, 92, 1, 64, 90, 90,218, 70, 0, 27,109, -108,108,146, 77, 77, 77,145,155,155,251, 86,249, 35,132, 40,252,252,252, 20, 50,153, 12, 93,187,118,181,113,118,118, 14, 23,137, - 68,171,226,227,227,141, 86, 26,101, 89,182,170,234,166,193,218, 30,189,154,183,105,100,254,204,114,129,185, 66,172,190, 95, 45, - 92, 97, 65, 0,100,107, 28, 95, 92,143, 30,146, 67, 82,228, 13,155,116,104, 12, 11,177,105,175,242, 4,150,136, 97,238,101,103, -102,117,207,201,213,226,234,181, 80, 12, 29, 82, 19, 26, 29, 1,207,139,144,151,175, 1, 24, 9, 68, 0,134, 13, 31, 9, 74,196, -200, 72, 78, 0,195, 48,143,254,161,236,154, 61,110,220,184,238,115,230,204,241, 46,242, 85,229,121,108,207,220, 47,143, 92,217, -144,221,179,149,234,121, 99, 63, 0,128, 77, 99, 63,100, 72, 36,136, 16, 51, 72,167,244,181,217,154, 70,113, 23,249,193,154, 65, - 8,169, 71, 41, 45,248, 27,197,100,187,210,191,255, 9,129, 85, 25,124,170,187,117,107,215,180,201,164,175,231,124,109,254,252, -246,101,124,253,195, 47,124,205, 38,129,217, 63, 31, 58,157,155,109, 81,173, 99, 65,194,211,251, 6,107, 1, 0,221, 58,246, 71, -253, 58,205,222, 58, 25,208,161,208, 7,228,213, 75,119,145,156, 26,111,112, 35, 91, 36, 10,202, 28,115,101,200,212,252, 50, 42, -130,172,208,208, 80,135,184,184,184,215, 6,180,123,121,121,129, 16,130, 91,183,110,225,230,205,155, 24, 58,116, 40,196, 98, 49, - 36, 18, 9,130,131,131,115,171, 98,193, 66,209, 44, 66, 66, 72,160,155,155, 91,153,179, 7, 13, 73, 85,181,170, 0, 57,217, 89, - 56,123,246, 52,106,212,240,193,226,197, 11,225,234, 98,143,239,231, 79, 4,199,113,200,201,205, 45,241, 15,100,128,117,128, 22, - 91,135,120,158, 71,106,106, 42,188,189,189,177,118,237, 90,172, 88,177,226,151,132,132, 4,163,103,143, 88, 91, 91, 91, 40, 20, -138,177,189,122,245, 10,232,219,183, 47, 2, 3, 3, 95, 59,191,115,231, 78,179, 67,135, 14,205,116,119,119,111,199,243,252,250, -248,248,120,131,166, 5,255,246, 91,161,251, 36,101,139,249,152, 53,168, 26, 62, 28,191, 13, 63,255,124, 16,114,185,252,181,198, -118,193,130, 5, 21,138, 23,158, 82, 31,105,218,245,132, 47,103, 46,115, 88,188,248, 60,206,159, 79,129, 72, 36,130,179,179, 51, - 68, 34, 17, 94,190,124, 9,145, 72, 4, 79, 79, 79,136, 68, 34,196,199,199, 23,143,249,203,132,218, 48, 31,132, 34,145, 8,106, -181, 26,177, 49,175, 16, 23, 25, 14,179,156, 36,216, 91, 40,145,249,248, 33,234,127,242, 25,244,122,253,255,130, 85,227, 28,128, -115,165, 14, 29, 32,132,232, 9, 33,195, 1,236,165,148, 30, 44, 58,190, 5, 21, 56, 6,109,209,162, 69,195, 57,115,230, 72,138, -221,102,184,120, 44,100,117, 58, 29, 15, 0,126,245,219,190,166,242, 35, 34, 34,240,243,207, 63, 35, 63, 63, 31, 82, 35, 70,166, -119,238,220,185,100, 76,164, 84, 42,133,157,157, 29,116, 58, 29, 88,150, 53,186,107,208,214,211,237,151, 91, 33,193,220,131,200, - 13,170, 71,207, 78,153,196,189,228,145,151,102,247,159, 21, 87,111, 90,178,220,220,220,230,243, 60, 79, 41,165,115, 75,213,173, -114, 15, 15,143, 43,103,207,158,181,101, 89, 22,171, 87,175,182, 74, 74, 74,178,106,219,182,237, 44, 0,229, 10,172,114,220, 52, -148,135, 42,185,105,224, 56,248, 90,152, 91, 33, 19,113,208,216,233, 27,102,217,178, 25,231, 18, 63,187,239, 18,221,168,142, 41, -167,247, 22,229,104,225,170,180, 2, 79,105,185,142,208, 52,122,253,169,251, 33,247,186,122,184,215,100,142, 30,191,140, 62,253, - 6, 65,163, 17, 65,173, 39, 32,140, 4,132,145,162, 94,253, 70,168, 85,183, 62, 40,128,187,183,175,179, 90,189,254,220,223,157, - 63,142, 45, 39, 13,117,106,245,197, 42, 80,158,150,246,131, 53,237,139,113,120,124, 91, 98,121, 57,228, 71,105, 96, 11,156, 72, - 61, 79,160, 84,252, 57,139, 80, 34,170,220,117,133, 75,192,164,161, 46, 1,133,220,101,248,193,242,238,215,175,223, 98, 0,147, - 32,224,175, 17, 88, 30, 30, 30, 86, 14,102,202,223, 38,124,242,177,121,244,131, 27,136,123,120, 3,215,174,134,103,238,250,227, - 72,124, 78,118,234, 39, 70,136,171,146,238, 60, 91,167,106,240,170,253,182,192, 82,152,217, 3, 0,188,106, 55, 3, 99,106,105, - 84, 68,202,178, 94, 85, 69, 92,149,110,148,203,242,129, 53,118,236, 88,108,222,188, 25,173, 91,183,134,143,143, 79,201,151,178, -177, 86,178, 98, 71,136,165, 42, 57,163,103, 15,150, 22,107, 57,185,185,240,170,230,142, 95, 55,175,199,253,135, 97,176, 48, 55, -197,200,225,253,255, 20, 86, 28, 95,242,204,202,172, 36, 28,199,189, 58,123,246,108,189,193,131, 7, 83,177, 88, 76,178,178,178, - 96,105,105,137,181,107,215, 22, 36, 38, 38, 94, 50, 54,124,174,174,174, 61,109,108,108, 62, 29, 50,100, 8,227,231,231,135,228, -228,100, 88, 88,152,107, 9, 33, 50, 0,176,180,180,212,154,154,154, 98,204,152, 49,168, 87,175, 94,179,153, 51,103, 54,117,114, -114,218,158,148,148,244, 71, 69,101,137, 16,130, 61,123, 10,123,167, 62, 89,245, 20, 90,109,161, 64, 89,183,110, 29,138,198,178, -253,217, 21, 16, 25, 9, 24, 48, 51,197,204,204, 12, 62, 62, 62,101,230,125,155, 54,109,112,247,238,221,194, 46, 72,177, 24, 14, - 14, 14,184,118,237, 26,111,104, 30,137,197, 98,132,134,134,162,182,151, 29, 30,157, 63, 11, 59,165, 4, 13, 92,156,224,214,166, - 29,194,195,195,255, 81,235, 21, 33,164, 15,128, 94, 0, 78, 82, 74, 15, 17, 66, 6, 2, 8, 44,222,135,145,142, 69, 89,150,165, - 34,145,136,196,198,198,234,148, 74, 37,177,177,177, 17,203,229,114,104, 52,154, 18,161, 21, 17, 17,129,227,199,143, 35, 46, 46, - 14, 54, 54, 54, 34, 75, 75, 75,232,116, 58,131,102,148,114, 28,247,150,123,134,162,231, 26, 45,174, 70, 1,254,155, 23, 46,169, - 38, 23, 49,150,181,237,186, 33,234,113,132, 42, 47, 45,203,228,255,131,184, 2,128,204,204,204,141, 0, 54, 22,239,219,219,219, -143,102, 24,230,107, 75, 75, 75,203,224,224, 96, 43,123,123,123,178,109,219, 54,253,220,185,115,179, 24,134,201, 36,132,172,168, -136,175, 28, 55, 13,239, 34, 0, 61,223, 62,134,176,180,236, 72, 79,137,181, 11,255, 64, 77,175, 79,137,157, 85, 43, 83, 82,211, -158,212,245, 71,191,148, 39, 87, 71,179,145,173,146, 19,147, 68, 20,124, 88, 5,117,240,150, 89,115, 22, 76, 15,127,122,207, 67, - 97,161,192,216,113,115,112,226,244, 37, 16,145, 4, 87,174,223,130, 86,199, 33, 45, 35, 27, 67,134,141,128,155,179, 29,194,110, -158, 73,101,121,126,237,223,255,110,242,107,234,181, 27,102, 45,149, 23, 14,245,164, 60,135, 77,251,103, 21,249,193,154,138,181, - 27,255,168, 87,215,235,197,183, 85,241,131, 69, 41,191,166,107,159,209,214,114, 19,101, 81,154,112,216,241,235,151, 16,137, 86, - 97,222,188,121,240,247,247, 31, 95,180,114, 67, 6, 4,188, 63,129, 85,173, 90, 53,185,169, 4, 99,108, 76,164, 51, 38, 12,239, -107,159, 18,249, 24,113, 79,238, 21, 42,127,141, 74,159, 24, 30,220,192,128, 74,187,243, 27,190, 50,104, 69, 93, 84,106,181, 30, -198,114, 22, 55,180,111, 90,175,140, 17, 87,101,113,150, 22, 89,165,253, 94,185,187,187, 99,241,226,197,149,250,193, 42, 35,238, -197,199, 3, 1,212, 47, 22, 89, 40, 28,228, 30,104,200,204,193,242, 56, 29, 28, 29, 16,246,184,112, 86,191,127,109, 79,248,215, -246, 4, 5,133, 90,157,141,216,152,108, 80,158,130, 2,176,178,178,121,203,130, 85, 22, 39,203,178, 75, 14, 29, 58, 52,232,198, -141, 27,189,190,252,242, 75,113,199,142, 29, 11,237,247,249,249,106,106,192,218,107,101,112, 14, 63,125,250, 52,195,243, 60, 54, -109,218,132,144,144, 16,106,106,106, 54,197,204,204,124,155,133,133, 5,151,149,149, 53,252,179,207, 62,235,251,237,183,223,146, - 54,109,218,224,198,141, 27,196,219,219,187, 63,128, 63, 42,139,251,173, 91,183, 32, 18,137,192,102,196, 96,252,172,189, 48, 53, - 17,227,233,211,167,200,200,200,120,203,249,168, 33,233,201,243,124, 73,195, 93,188,181,105,211,166,164,187,177,121,243,230, 96, - 24, 6,247,239,223, 47,179,187,245, 13, 78,106,107,107, 91, 82, 62,164, 82, 41, 46, 93,186,132,239,191,255, 30, 30, 54, 86,200, -124,242, 8, 78,237, 59,162,203,199,159, 97,232,208,161, 96, 24, 6, 54, 54, 54, 37,150,222,202,226,254,142,130,170,132,147, 16, -210,187,118,237,218,179,195,194,194,220,234,213,171, 87,135, 16,210,222,223,223,191,233,163, 71,143,138,247, 37,148,210,125,198, -112,222,185,115,231,192,154, 53,107,198,141, 26, 53, 74,202,243, 60, 23, 29, 29,173, 7, 64,156,156,156,152, 59,119,238,240, 71, -143, 30,133, 74,165,130,155,155,155,200,213,213,149,156, 59,119,142,127,242,228,201, 45, 74,233, 28, 67,227, 94, 60, 83,176,120, - 48,187, 74,165, 50, 72, 92,189,201, 89,173,150,239,162, 78,109,253,220,211, 18,238, 35, 49, 62, 18,234, 12,107,253,165, 51,215, -140, 18, 87,127,117, 30,253,205,156, 11,158, 63,127,238,170,209,104, 32,147,201,176,110,221, 58,221,226,197,139,195,210,210,210, - 2, 40,165,170,170,134,211, 24, 7,164,149,113,102,167,227,196,225, 35,119,154,154,245,219,130,241, 9,169, 37, 3, 23, 41, 33, - 54, 7, 29,235, 4, 40,155,213,139, 23,157,156, 47,202,229, 10, 78,148,199, 73, 41,213, 18, 66, 6,245,235, 63,236,194,158, 61, -187,205,230,206,159,143,107,183, 30, 33, 61, 43, 15, 60,101,192, 19,130,175,191,158, 11, 39, 59, 27,228, 36, 60, 47,208,232,116, -253,222, 92, 50,231,239,200, 35, 74, 69, 19, 31, 5,239, 93, 69, 0, 94,149,250, 76, 46,206,123,161, 28, 57,188,159,120,232,208, -161, 56,116,252, 58,246, 28,123,177,126,247, 81,122,172, 42,249, 78,136,104,226,185,163,219, 86,137, 8,248,252,228,103,114, 38, - 55, 82,249,225,208,126,226, 65,131, 6,225,224,193,131, 8, 13, 13,221, 80,158,184,250, 43,226,254,255, 70, 96,153,139, 17, 26, - 80,167,186,107,155, 70,117, 21, 98, 78,133,184, 39,145,200,200, 87,227,220,227,232, 44, 17, 21,253, 94,213, 7, 22,142,157,144, - 34, 38,230,249, 91,231,178,178, 10, 71,230,229,230, 26,183,236,147, 72, 36,122,205,122,245, 46,150,171,210,225,116,116,116,124, -109,217,149,210, 13,118,241, 24,159, 42,184,104,152, 21, 19, 19, 99, 17, 19, 19, 3, 74, 41,110,221,186,101,209,188,121,243, 89, - 85,181, 94, 1,192,252, 5,171, 95, 91, 30,164,244,111, 89,199, 42, 67,106,106,106, 62,128,223, 28, 29, 29, 79, 76,159, 62,253, -163, 22, 45, 90,180,153, 55,111, 30,161,148, 86, 53, 97, 89,158,231, 17, 20, 20,132,131, 7, 15,114, 90,173,118,118, 98, 98,226, -179, 82,231,127,119,119,119,191,210,183,111,223,159,195,195,195,153,176,176, 48, 24, 34,228, 84, 42, 21,124,124,124,192,178, 44, -126, 28,239,142,220,220,122, 96, 89, 22, 28,199,193,212,212,244,181,117, 40, 13,201, 39,145, 72,244,154,101,164,120,187,117,235, - 22, 24,134, 65, 64, 64, 0,238,221,187, 87, 98,193,170,204,226,164,211,233, 98, 28, 29, 29, 29, 23, 44, 88, 80, 18,174,212,212, - 84,156, 61,123, 22, 45, 90,182, 66,157, 49, 99,145,144,144,128, 21, 43, 86,192,197,197, 5,139, 22, 45, 66, 70, 70, 6, 88,150, -141,249,155,235,129,110, 97, 97, 97,110,195,135, 15, 79,121,244,232,145,219,241,227,199,173,122,245,234,101, 58,108,216,176,148, - 71,143, 30,185, 17, 66,218, 2,216,103,228,251, 51,155, 16,114,122,209,162, 69,179, 38, 77,154,212,124,212,168, 81, 18,137, 68, -194,199,199,199,179,187,119,239, 38, 62, 62, 62, 34,169, 84, 74,206,156, 57,195,223,190,125,251, 38,203,178, 63, 82, 74,175, 24, -107,101, 46, 22, 87,198,142,185, 42,198, 20, 7,249, 72,115, 81,106,192,154,117,139, 69,126, 94,110,186,237,187,207,198, 94,185, -241, 60,138,209,176, 83,126, 3,162,254, 63, 54, 10, 12,195,236,171, 93,187,246,232,137, 19, 39,154, 4, 6, 6,202,191,253,246, -219,236,220,220,220, 50,197, 85, 89, 48,198, 77, 3,140,116, 64, 90, 10,191,206,254,234,248,148,105,245, 70, 87,255,212,169, 26, -206,231,167, 32, 83,204,136, 44,172, 68,104,228,201, 32, 55, 45,194,254,216,133,173, 47, 81,137, 95, 53, 74,233, 29, 66, 72,231, -186,245, 26,254,241,227,162, 31, 29,190,153, 57, 67,242,199,241, 83,160,172, 14,183,130,131, 97, 38,229,232,147,144,243,201, 26, -157,182,239, 63,181, 84, 78,242,141,213,123, 8, 33, 71,108,108,108,238,127,246,241,199,190,141, 26,125, 10,165, 82,137,253,251, -247, 99,219,202,149,220, 74, 96,240, 70, 66,238,141,165,212,232,118, 57,225,106, 9,247,131,143, 71,141,242,169, 93,123, 24,148, - 74, 37, 14, 28, 56,128, 29,171, 87,191, 19,183,128,138,186, 8, 69, 36,247,230,243,232,188, 91,207,163,243,192, 83,202, 83,170, - 17,137, 16,155,175,211, 45, 10,143,138,171,146, 24, 40,238, 34,252, 97,225,196,247,169,246, 75, 68, 79, 85,166,101,151,211, 56, -196,213,172, 89, 19,111, 90,180, 42,250,175,215,235,227, 12,164, 95,226,225,241,214,186,164, 75,170, 26,214,226,193,242,134,138, - 43, 67,253, 96, 1, 64,114,114,114, 42,128,101,110,110,110, 71,186,119,239, 62,148, 16,146, 84,197, 60,218,211,161, 67,135,161, -148, 82, 70, 36, 18,237,124, 67, 92, 1, 0, 98, 99, 99, 95,184,185,185,109,242,242,242, 42, 89, 0,186, 34, 78,158,231, 95,212, -171, 87, 79, 87, 86, 94,148,183,207,243,124,165,121,148,149,149,133,102,205,154,189,181,230, 36,165, 20,209,209,209,197, 22,166, -146,180,175, 72,184,229,229,229,141,253,226,139, 47, 54, 74, 36, 18, 15, 0,164, 88,220,114, 28,199,252,242,203, 47, 10,142,227, - 24, 0, 68, 36, 18,177, 18,137, 68,125,240,224, 65,150,101,217, 24,141, 70, 51,246,111,174, 7,246, 18, 66, 36, 0, 50,195,194, -194,218, 22, 89,174,226, 66, 67, 67,207,239,217,179,199, 17,168,220,125, 66, 57,101,243, 10,128, 43,132,144, 54,235,214,173,155, - 61,118,236,216,102, 67,135, 14, 21,183,111,223, 30, 39, 78,156,224,130,130,130,110,169, 84,170, 37,198, 10, 43, 66, 72,158,167, -167,103, 97, 5, 38,174,120,148, 3,203,178, 21,126,173,217,122,202,215,140,248,220, 69,177,105,201,217,188,180, 4,237,117,125, -158,118,206, 86, 32,244,255,115,163,144,148,148,244, 21, 33,100,238,138, 21, 43, 18, 26, 52,104, 32,151, 74,165, 90, 67,197, 85, -209,135,143,163, 17,101,132,175, 98,217, 98, 9, 33, 61,150,119, 25,120,164,221,215, 95,120,117,233, 16,160,116,175,230,224,250, - 36, 50, 25, 17, 55, 78,228, 63, 56,182,240, 21,213,100,246,161,148,178, 6,112,221, 38,132,212,252,114,198,151,197,139, 61,215, -239,116,238, 48,253, 31, 91,236,249,135,159,127,254,217,215,223,223, 31,251,246,237,195,153,109,219, 48, 56, 45, 13,151, 24,134, - 17, 73,165,182,199,116,186,101, 0,170, 42,130,126, 88,186,116,169, 79,237,218,181,113,224,192, 1,156,219,185, 19, 67,222, 31, -247,251, 68, 83, 0,246, 69,255,211, 0, 60, 3,208, 24,128, 9, 0, 13,128, 60, 0,118,165,174, 79, 47, 58, 87,124,254, 50,128, -191,117,160,107,185,181,211,163,231, 47, 27,191,239,135,169, 84,170, 12, 31, 31, 31,137, 49,247,232,245,250,148, 74, 42,208,184, -234,213,171, 27,108,165, 48, 68, 12,165,167,167, 55,249,171, 18,252, 93,198, 90,189, 37, 4,121,254,149,179,179, 51, 95,220,216, -151, 37,190,202, 58, 70,129,151,198, 60, 39, 46, 46, 46, 10,192,247, 85, 13,103, 92, 92,220, 41, 24,176,152,179,161,215, 1, 64, - 70, 70,198,123, 95,100,151, 80, 26,255,237,183,223, 26, 37,172, 65,105,124, 5,121,253, 8, 64,243,255,245, 6,149, 82,122,185, -168,242, 1, 33,164, 31, 33,164, 7,128, 51,148,210, 3,239,137,191, 68,104,109,218,180,105, 10,165, 20, 57, 57, 57, 43,141, 21, - 86,165,132,255,197,247, 21,247,140,100,237,197,221, 27,226, 58,170,178,116, 83, 54,231,105,183, 65, 64,113,158,169, 29, 28, 28, -126,255,240,195, 15, 91, 0,216,250, 62, 56,223,193, 77, 67,121, 97,124, 73, 8,105,112,233,203,239, 63,190,100,101,222, 19,156, -216, 15, 90,209, 49,104,211, 79, 0,248,205, 16, 43,120,233,248, 2,248,185,104,251,159, 66,145,175,170, 41, 35, 71,142,196,220, -185,115,113,242,199, 31,117,159, 19,146, 45, 1,232,233,194,143, 64, 17, 1,102,190, 11,247,232,209,163, 49,119,238, 92,156, 89, -182,236,189,113,255, 5,176, 39,132, 28, 7,128, 89,179,102,205, 89,188,120,177,245,236,217,179,235, 47, 89,178,100, 81,209,254, -227,226,243, 69,121,218,107,246,236,217,117, 75,157,207, 5,112,231,239,126,145,254,178, 13, 64,103,129, 83,224, 20, 56, 5, 78, -129, 83,224, 20, 56, 5,206,119,220,122, 22, 74,150,242,127,203,251, 95,234,216,223, 25, 94,136,132,111, 53, 1, 2, 4, 8, 16, - 32, 64,192,191, 17,165,173, 86, 85, 57,255,151,134, 13, 64,231,114, 44, 91,231,141,136, 96,231, 42, 88,206,206, 11,156, 2,167, -192, 41,112, 10,156, 2,167,192,249,255,139,179, 50,238,114,238,239, 73, 8, 57, 78, 41,237, 85,222,111,177,160,122,243,127,169, - 99, 70,175, 60,242, 78, 16,186, 8, 5, 78,129, 83,224, 20, 56, 5, 78,129, 83,224,252, 55,116, 17, 2,160,179,102,205,154,253, -111,232, 34,172, 96, 10,206, 1, 38, 62, 30, 22, 50,153, 82, 10, 0, 90,109,129,206,213, 21, 57,192,192,127,108, 33, 90, 1,255, - 90, 19,174, 99,145,152, 79,126,159,215, 10, 16, 32, 64,128,128,255, 55, 72, 45,182, 76, 1, 72, 5, 64,138,246,181, 69,191,169, - 69,109,199,155,255, 95, 59,255,119, 66, 92,158,184, 74, 75, 83,218,137,197,153,190, 28,167,174, 5, 0, 98,177,232,105, 90,154, -117,184,157,221,129,180,170,136, 44,123, 71,199, 16, 9,195,184, 26,114,173,158,227,226,211,146,147, 95,115,245, 78,129,127,189, -176, 51, 84, 60,188,139,200,248, 59, 4,138,189,189,189,163,163,163,227, 7, 22, 22, 22, 45,179,178,178,110,167,166,166, 30, 74, - 77, 77, 77, 46, 39, 60,139, 9,193,140,162,255, 63, 81, 74,103, 87, 16,118,131,175, 45,227, 94, 31,165, 82, 57,158, 16,226, 95, - 20,255,208,130,130,130,117,148,210,231,255, 15, 5,173, 9,128,190, 98,177,120,164,157,157, 93,179,164,164,164,111, 41,165, 43, -170,200, 37, 6,240,165,149,149,213, 80, 43, 43, 43,239,140,140,140,168,156,156,156,125, 0,126,166,148, 86, 58,229,249,187,201, - 46, 45,219, 7,182,255, 38,232, 76,208, 15,243, 87, 37,220,120,235,252, 87, 46,182, 93,187,180,158, 27,116,236,250,130,217,107, -226, 51,140, 12,155, 8, 40, 25, 71,202, 23,125,165,210,255,225,124,105, 1, 96, 78, 81,152,127,166,148, 94,250, 31, 47, 71,166, -142,142,142, 63, 2,232, 45, 22,139,195,226,227,227,199, 80, 74,227,222, 19,183, 4,128, 13,128, 12, 67,202,145,128,215, 33,151, -203, 87, 58, 57, 57,125,170, 82,169, 10, 8, 33,180,180,191, 70,150,101,227, 82, 83, 83,155,252, 7,163,125,231,223, 22,224, 50, - 5, 86,124, 60, 44,196,226, 76,223,148,164, 71, 67, 18, 18, 31, 14, 6, 0, 23,231,250,251, 28,156,234,237,141,143,151,233,154, -118,233,111, 38, 81,138,215, 49,140,164,161, 90,171,177,147,136, 37,105, 58, 86,127, 95,164,165,227, 19,159, 30, 44,211, 73,162, -132, 97, 92, 95,133, 95,114, 96,117, 25,144, 40, 92, 32, 49,241, 40, 55, 80, 46, 46, 46, 85,138,140,141, 77, 13,115,157, 92, 49, - 69, 34, 97,186,240,148,245,167, 60, 32, 34,146, 80,150,211, 95,144,106, 52,203, 51, 50, 34,115,171,154, 80, 45,125,108,125, 9, -213, 77,151, 16,218, 70, 79,201, 21, 74,164, 75,111, 60, 79, 15, 55,162, 66, 49, 72, 60,188,163,200, 40,125,239, 10, 74,233, 87, -239,187,192,184,185,185, 89, 15, 24, 48, 96,229,247,223,127,111, 98,102,102, 70, 98, 98, 98, 2,103,206,156,217,214,205,205,109, - 90, 92, 92, 92,194,155, 98,143, 16,204,224,249, 66, 7,165, 34, 17,153,233,232,232,168,100, 24,230,173,197, 67, 57,142, 83, 18, -130,137, 60, 95,184,224,184, 72, 68,102, 16, 66, 86, 25, 34, 20, 77, 76, 76,134, 53,107,222,106,218,143, 75,127, 54,115,116,112, - 48,101, 57, 94,247, 50,250,149,242,155, 89, 95, 53, 55, 49, 49, 89,165, 82,169,118, 27, 27, 79, 66, 8, 97, 24,102,136, 92, 46, -239, 5,160,118,209,225, 39, 26,141,230, 56,199,113,123, 13,109,200,157,156,156, 46, 51, 12, 83,205,152,103,115, 28, 23,147,148, -148, 20, 80,197,134,107,144,135,135,199,111,237,218,181, 83, 54,107,214, 12, 50,153, 12,115,231,206,253, 18,192, 10, 67,132,148, - 82,169, 28, 98,106,106, 90, 61, 47, 47, 47, 82,165, 82,253, 33,147,201, 58,175, 90,181,202,189,117,235,214,230,201,201,201,132, - 97, 24,199,227,199,143,127,180,122,245,234, 64, 66, 72,167,202,252, 12,101, 71,210,111,228,189,107,183,201,142,188,244, 13,128, -238,111,158,103,213,138,145,148,113,239,165,162,247, 98, 97,196, 20,121, 66,136, 72, 34,145,172,114,114,114, 26,173, 86,171,213, - 0, 40, 33,132, 58, 58, 58,150, 52, 52, 0,160,213,106, 51, 51, 51, 51,253, 42,226,170, 85,171,214, 93,134, 97,220, 42,200,143, -184,167, 79,159,190,143, 6,107, 70, 82, 82, 82, 15,137, 68, 66,220,221,221, 25, 0,151,140,136,175, 47,128,175,139, 26,153,117, -148, 82,142, 16,210, 1, 40,124,223, 1,252, 84, 44,216, 24,134, 89,231,231,231,247,193,147, 39, 79,214, 83, 74,127,168,106, 96, -157,156,156, 54,174, 93,187,118,112,159, 62,125,152,212,212, 84,215, 6, 13, 26,236, 2,208,230, 29,133,149, 12,192,108, 39, 39, -167, 9, 1, 1, 1,182,247,238,221,203, 32,132,172, 5,176,196, 16, 95, 83,132, 16, 37,128, 65, 0, 70, 2, 96, 0,236, 6,176, -135, 82,154,253,255, 69, 92, 49, 12,179,106,200,144, 33,163,119,237,218,165,124,245,234,149,210,213,213,181,196,233, 53, 33,164, -202,237,167,128,191, 73, 96,201,100, 74, 41,199,169,107, 37, 36, 62, 28,220,182,221, 47,150, 0,112, 57,248,139,193, 14, 78,117, - 67,101, 50,101,184,220, 66,113,176,127,239,206, 13, 7,246,106, 71,220,156, 29, 16,151,152,226,248,235,158, 51,221,142,159,185, -116, 16,133,142,191,202, 4,171,203,128,137,238, 60,158, 94, 93, 5, 81,195, 23,216,126, 41, 5,119, 30, 71,163, 32, 59, 13,110, -118, 50,204,250,164, 29, 26,214,176,175, 82, 68,204, 28,125, 59,136, 20,202,189,195,135,125,104,249, 65,223,218, 18, 79, 39, 39, - 80, 42, 71,120,100, 94,171, 83,103, 47, 53,253, 99,255,238,241,102,142,190, 67,242,146,195, 13,174,212,252,253, 45,173, 76, 84, -116,154,137,148, 14,237,214,188,142, 87,239, 46,173,136,183,183, 55,194,159,133, 87,191,116,237,206,232, 14,181,204, 95,170,116, -100,143,202,132, 44, 15, 13,205,206,170,200,170,244,166,208,232,212,169, 83, 35, 19, 19, 19,109,233,235, 84, 42,149,140, 16,116, -170,138,200, 40,126,134, 86,171, 17, 73, 36, 50,136, 68,100, 90,253,250,245,171,165,165,165, 93, 22,137, 68, 59,227,226,226, 50, -141, 73,207, 73,132,200, 50,197,226,198, 34,185,220,153,211,106,109, 1,128,200,100,153,110,214,214,245,190,158, 51,199,140, 97, - 24, 62, 61, 61, 29, 5, 5, 5,228,179,207, 62, 83, 68, 70, 70,246, 7,176,186,146, 48, 98,243,230,205,190,206,206,206,218, 55, -207, 37, 38, 38,202,250,244,249,160, 42, 21,182,111,139,150,173,167,158, 57,115,186,118, 78, 70,166,122,243,138,141, 33,122,133, - 82,227, 93,219, 79,178,110,211, 54,203, 49,163, 71,124, 65, 8,185, 79, 41, 53, 70, 12,123,152,152,152, 28, 92,182,108,153,127, -135, 14, 29, 36, 14, 14, 14, 72, 78, 78,198,147, 39, 79,252, 47, 94,188,216,119,219,182,109, 95, 18, 66,250, 83, 74, 13,241,184, -238,115,118,219,111, 14,102, 54,182,224,244,122,184, 53,104, 84,226,159,236,217,133,179, 96,245, 58,112,122, 61,234,245,234, 91, -104,134,225,121,212,169, 83,167, 74,222,114, 9, 33, 46,117,235,214,221,177,104,209, 34,169, 70,163,193,173, 91,183,112,233,210, - 37, 62, 49, 49,113, 73,101,226,138, 16,114,118,254,252,249,110, 1, 1, 1,230,105,105,105,224, 56,206,238,240,225,195,227, 27, - 53,106,100,225,238,238, 46,219,190,125, 59,242,242,242,192,178,172, 77,245,234,213,109,134, 13, 27,166,221,190,125,251,151, 0, -126, 44,207,114,149, 19, 73,191, 73, 34,213,187,249, 53, 30,137, 36,114,186,219,180,238,206,167, 44,106,144, 18, 75, 86,247, 26, - 53,204,171,215, 50,157,105,102, 81,207, 38, 39,254,252,204,238, 53,106,108, 62, 21, 89,249, 71, 16, 33, 68, 36, 18,137, 86,245, -239,223,127,248,158, 61,123,148, 79,158, 60, 81,214,174, 93, 27, 60,207,151,120,204, 47,118, 20,235,227,227, 99, 72,131,229,118, -225,194, 5, 7, 19, 19,147,183,156,242,230,231,231,163, 79,159, 62,127, 69,125,107,108, 30,127,247,226,197,139, 65, 7, 15, 30, - 28, 49, 99,198, 12, 31, 0, 19, 1,204, 77, 79, 79,111, 7, 0,182,182,182, 50, 0,151, 8, 33, 31, 79,159, 62,253,243, 89,179, -102,161, 71,143, 30,115, 9, 33, 11,171, 98,213, 35,132, 48,118,118,118, 61,250,244,233,195,232,245,122,152,154,154, 66,175,215, -215,120, 71,113, 37,151, 74,165, 71,151, 45, 91,214,101,216,176, 97, 16,139,197,224,121,222,230,236,217,179,243, 70,143, 30,221, -134, 16,210,189, 60,145, 69, 8,241, 2, 48,179,110,221,186, 35,102,205,154,101,210,173, 91, 55,228,229,229,225,192,129, 3,173, -215,172, 89,179,138, 16,114, 24,192, 66, 74,233,127,218, 73, 44, 33,228,167, 33, 67,134, 12,223,181,107,151, 25, 0, 44, 93,186, - 20, 83,167, 78,133,163,163, 35,204,204,204, 4, 69,243,111, 16, 88,149,161,160,160,160,209,236, 73, 31, 65, 36, 42,252, 74,172, -233,237,129,197,115,198,144, 35,199,207, 52,170,232, 62,137,194, 5, 79,175,172, 2,107, 55, 1,170, 2, 45, 66, 30,191,194,133, -159,187, 21,114, 4,206, 65,118,126, 11, 0, 0,165,212, 70,102, 98,242,147,150,227,174,193,201,233, 22,162,163, 83, 43, 19, 87, -246, 78,142,199, 55,108,248,209,196,191,134, 31,116,172, 30,241, 41,241, 32, 68, 14, 55, 87,115,124, 60,178,187,164, 93, 59, 23, -187,239,190,219,120,194,212,222,183, 95,126,106,120,165,142, 62,219,212, 52,189,221,175,113,141,198,189, 59,183, 18,249,248,213, -129, 84,161, 44, 57, 87,175, 97, 35,212,107,216,136,140, 25,157,235,253,224,193,131,111, 78, 7,223,154,211,166,166,105,200,149, -136,252,102, 21,189, 27,165,133,198,228,201,147,223, 90,144, 56, 49, 49, 17, 65, 65,239,212,107,240,218, 51,190,255,254,123,179, -172,172,172,206,191,254,250,107, 91, 87, 87,215,101,241,241,241, 55, 13, 33,249,136,144,106,144,203, 59,141,254,249,103,190,225, - 7, 31, 48, 86, 78, 78, 34,158,227, 72, 66, 84,148,237,138,213,171,219,103, 68, 68,152,228,219,216,100,100,170, 84, 5,225,225, -225, 80, 40, 20, 68, 44, 22, 55,125,147,135, 82,154, 76, 8,249, 73, 36, 34, 51, 9, 33,144,203, 21,225,227,198,141,187, 87,116, -186,218,177, 99,199,148,189,123,247, 46, 0,240,170,208,236,173,112,101, 24,145,111,225, 0, 65,252,100,136,176, 52, 53, 53,157, -244,195,162, 31, 77,115, 50,178, 84,186,252,124,189,189,133, 25, 33,102,230, 76, 78,118,110,110,124, 98,170,230,235,111, 23, 48, - 99, 63,254,112, 18,128,241,134,138,171, 6, 13, 26,220, 62,120,240,160,131,173,173, 45,178,178,178,144,158,158,142,219,183,111, -131,231,121,244,239,223, 95,222,170,121,179, 70,115,190,254,230, 6, 33,164,165, 33, 34,203,204,214, 14,223,183,106, 8, 0, 88, - 18,147, 94,146, 63,191, 12,236, 85,114,205,178,132,194, 15,112,133, 66,241, 46, 75, 61,181,236,212,169,147, 20, 0, 62,249,228, -147,156,220,220,220,197, 0,118,209, 10,156,161, 22,225,203,111,190,249,198,213,219,219,219,115,215,174, 93,200,203,203, 3, 0, - 7,111,111,111,248,249,249,113, 65, 65, 65,240,245,245,133,185,185, 57, 46, 95,190,140,155, 55,111,162,113,227,198,230, 82,169, -116,112,121, 2,171,125, 96,251,111,228,189,107,183,241,107, 60, 18,102, 22,206,216,188,123, 47,158,133,108,107,163,209, 61,249, -102,241, 68,215, 15, 85, 84, 62,202,205,199,124, 86,181, 38,237,108,107,214,253, 0,158,141,239,217,169,185, 43, 47,230, 78,168, -190, 68,172, 80,111,155,191, 44, 33,189, 60,113, 5, 96,105,255,254,253, 7,237,217,179,199, 10, 0, 30, 61,122,132,228,228,100, -216,219,219, 67,161, 80, 64, 34,145,148,172, 31,106, 40, 76, 76, 76,144,152,152, 8,157, 78, 87,108,181, 66,110,110, 46,156,156, -156, 10,213,205,119, 68, 52,127,190, 97, 94,199, 9, 33, 1,205,155, 55,223,233,233,233,233, 94,250,120,207,158, 61, 49,116,232, - 80, 0, 64,187,118,237, 58, 13, 28, 56,144, 22, 11,193,196,196,196,188, 59,119,238,116,161,148,222, 42,139, 83, 36, 18,169,226, -227,227, 49,125,250,116,188,124,249,114, 2, 33, 36, 26,128, 66, 38,147,149,124, 23, 19, 66,124,235,214,173,187,106,234,212,169, -136,140,140, 68, 88, 88,216,237,170,118,153, 82, 74, 57, 47, 47,175, 8,189, 94,223,132,101, 89,168, 84, 42,244,235,215, 79, 97, - 99, 99,147,204, 48,204,211,180,180,180, 17,148,210, 68, 35,172, 86,158, 98,177,120,205,244,233,211, 59,117,238,220, 25, 15, 31, - 62,196,193,131, 7, 49,108,216, 48,116,235,214, 13,203,150, 45,107, 55,113,226,196, 89, 0,230,151, 67,179, 35, 34, 34,162,165, -151,151, 87,201,106, 29, 86, 86, 86,248,242,203, 47, 49,105,210, 36,201,161, 67,135, 6,141, 24, 49,162, 54,128, 58,255,229, 6, -219,211,211,115,220,158, 61,123,204, 74,247,246,200,229,114,148, 42, 7, 2,254,215, 5,150, 86, 91,160, 19,139, 69, 79, 93,156, -235,239,187, 28,252, 69, 73, 23, 33, 32,122,170,213, 22,232, 0,128,227, 41,114, 10, 88,152,200, 69,120,149,148,139,199, 81,105, -101,189,164,175, 77,181,148,152,120, 32,201,227, 17,120,158,130,207,215, 66,149,157,132,197, 39, 10,240, 36, 78, 13,109,126, 38, -114,242, 11, 43, 55, 59, 59, 59,241,153, 51,167,166,158, 63,127,241,243,223,127,255,157,137,179,180, 12, 67,118,118,163,178, 56, -109,108,106,152,139, 77, 77,246,173,223, 48,215,132, 50, 81, 8,143,201, 71, 77,183,102,176,179,114, 71, 82, 90, 62,174,133,157, -196,211,231,199,225,237,236,137, 41,147,186, 41,126, 88,180,107,175,181,181,183, 71,102,230,139,156,242,194, 9, 0, 10,134,107, -250,237,238, 7,224, 50, 34, 65,179, 99, 64,243,223, 94, 37, 70,105,231,142, 90, 45, 29,161,180,178, 23, 61,122,186,162,105,121, -113,167,148, 38, 51, 12,179, 78, 36, 34,227, 9, 33,240,247,175,247, 98,229,202,149,218,178,146,222,223,191,222, 11,134, 17,121, - 23, 46,195, 34, 90,207,243, 92,114, 69,225,124, 83,204,200,100,242, 25,133,230,125,231,168, 83,167, 78,105, 7, 14, 28,136,165, - 75,151, 74,103,205,154,245,149,167,167,231,196,232,232,232,164,138,242,168, 63, 33, 30,174, 53,106,116, 93,120,237, 26,149,232, -245, 36,227,246,237,156,172,196, 68, 54, 41, 55, 87,182,255,233,211, 30,159,126,245,149,204,221,221, 29, 87,143, 31,183, 77,205, -207,167, 89, 26,141, 42, 43, 43,139,178, 44,123,187,156,184,207,118,116,116, 84,110,222,188,217,119,220,184,113,247, 18, 18, 18, -102, 23, 85, 12,139,139, 42,195, 87,165,142, 97,195,134,189,241,159,125,246, 89,120,114,114,242,236,138,194, 89, 10,117, 29,236, - 29,148,187, 55,110,127,104, 99,110, 34,178,119,115, 17, 73,172,172,196,172,204, 68,202, 3, 42,111,247, 26,166, 0,234,150,147, -102,231,223,104, 8,136,137,137,201,193,163, 71,143, 58, 72, 36, 18,112, 28, 7,123,123,123,188,124,249, 18, 89, 89, 89,200,205, -205,197,139,167, 79,224,229,238,142,239,102,205,116,158, 56,115,214, 65, 66, 72,147,210,141, 88, 89,225,228,116,186,183, 44,121, -229, 44, 16,254,218,175, 33,249,254, 6, 94,198,196,196,192,204,204, 12,254,254,254,102,215,174, 93,187, 82,158,184, 42,205,169, - 80, 40, 6,183,110,221,218,124,247,238,221,104,220,184, 49, 44, 45, 45, 17, 20, 20,132, 71,143, 30, 65,167,211,137,242,242,242, - 96,110,110,142, 37, 75,150,192,211,211, 19, 57, 57, 57,136,137,137,177,149, 72, 36,118,229,113, 6,157, 9,250, 33, 59,242,210, - 55, 73,228,116,183,205,187,247,226,179, 97, 67,224, 68,163,174, 88,214, 32, 63,116,237,221,122, 30,101,220,123,153,154,215,183, -246,241,239, 13,169,204, 12, 19,103, 44, 64,120,232, 49,235,130,220,135, 19, 8, 23,235, 14, 96,242,155,156,164, 48, 97, 68,238, -238,238,159,238,223,191,223,188,148, 5,170,100, 29,210,210,139,179,151,183, 16,123,153,121,196,113,208,233,116,208,233,116,224, - 56, 14,105,105,105,200,205,205,133,149,149, 85,225, 5,243, 1, 2, 66, 40,202, 22, 44,111,112,142, 56,127,254,188,187,169,169, -233,155,215, 32, 45, 45, 13, 44,203, 66,169, 84,150, 60, 83,175,215, 67,173, 86,155,213,169, 83,103, 60,128, 91,101,113,242, 60, - 63,109,240,224,193,173,111,221,186, 85,125,245,234,213,208,106,181, 75,147,146,146, 48, 96,192, 0,240, 60,143, 78,157, 58,181, -160,148, 62,251,250,235,175, 1, 0, 83,167, 78,213,231,231,231,143, 51, 36,238,229,136,162, 58, 3, 7, 14,172,126,225,194, 5, -180,105,211, 6, 26,141, 6,203,150, 45,179,216,176, 97,131,197,246,237,219,237,103,204,152,241, 27,128,192,138, 56,139,132,213, -156,110,221,186, 77,235,211,167,143,105,124,124, 60,172,172,172,176,119,239, 94, 44, 89,178,228,178, 86,171,157,179,125,251,246, -197, 7, 15, 30,108, 51,108,216, 48, 44, 91,182,108, 2, 33,228, 7, 74,169,190, 12, 78, 23,111,111,111, 60,124,248, 16,214,214, -214,176,179,179, 67,118,118, 54,110,222,188,137,219,183,111,163, 86,173, 90, 32,132,216, 87, 34, 26,223,251,194,196,127, 55,167, - 74,165, 82,199,196,196,152,253,248,227,143,112,118,118,134,167,167, 39, 20, 10, 5, 8, 33,208,235,245,229, 46,131,102, 72, 56, -219,183, 39,226,180,120,235, 62,150, 86,214, 19, 40,165,226,236,236,204,141, 58,100, 29,136,140,164,218,191, 43,238,255, 73,129, - 69, 8,161,148, 82, 82,252,235,234,138,156,180, 52,235,112, 7,167,122,123, 29,156,234, 22,153, 92, 69, 79, 25,198, 58,220,209, -177, 32, 7, 0,116, 44,197,245,167, 89,120, 24,145,132, 71, 17, 73, 48,149, 27,182, 76, 77,118,190, 22, 60,165,224,121, 10,117, -222,159,162, 76, 91,144,133,236,130,194,124,212,106, 10,144,157, 26, 70, 6,245,235,162,248,252,243,177,112,118,118, 45,247,197, -209,201, 21, 83, 38, 78,237, 97,101, 99, 37,193,241,107,167,209,162, 86, 63, 40,228, 18,164,103,171, 1, 2, 60,143, 58, 7,240, -230, 8, 13,143, 65,243,186, 74, 4,118,173,109,118,232,192,179,175, 0,204, 53, 36,188,186, 23, 65,144,213,233, 15,240,117, 65, - 51, 35,193,231,196,131, 42, 29,144,207,155, 32, 45, 33, 26, 79,175,236, 7,213, 85,190, 76, 23,199,113, 19,237,236,236, 82,102, -207,158, 29,224,235,235,171,157, 56,113, 98,232,203,151, 47,191, 46,125,141,151,151,215,194, 53,107,214, 32, 60, 60,252,213,226, -197,139,175,166,165,165,125,111,228,139, 57,139, 16,178,178,200, 26,150,118,244,232,209,250,151, 47, 95, 30,191, 98,197, 10,251, - 9, 19, 38, 72, 39, 77,154, 52, 2,192,210,138,186, 5, 77,229,242,206, 11, 47, 95,166,108, 92,156,102,199, 47,191,200,214, 94, -191,254,181,142,231, 93,236, 28, 28, 72,171,230,205,243,149, 34, 81, 90,122,114, 50,107, 95,189, 58,243,242,220, 57, 91,106, 98, -146,112,234,212,169,156,188,188,188, 63, 42,232,130, 41, 40,171, 91,176, 44, 56, 59, 59,107,203, 26,163, 85, 65, 67,144,195, 83, -170,179,242,246,166, 93, 59,181,172, 25,241, 44, 42, 74, 97,101,197,248,212,244,242,123,252,244,229,109,202,113,106, 66, 72,142, - 33, 92, 12,195, 12, 89,185,114,101, 61, 11, 11, 11,240, 60, 15, 75, 75, 75,164,166,166, 66,171,213, 34, 39, 39, 7,218,220,108, -104,179,179,241, 40,250, 37, 90,183,111,143, 65,221,186,214,222,126,248,232, 16, 0,123, 42,226,117,107,208,168,196,114, 53,203, -195,182,228,248,210,248,172, 18,177,245, 93, 67, 31,200, 77,205,208,237,203, 89,239, 82, 49,223,147,201,100, 39,251,247,239,223, -227,171,175,190, 18, 37, 38, 38,158, 38,132,180,166,148,134, 85,104, 97, 51, 51,171, 81, 44, 40, 44, 45, 45,177,114,229, 74, 56, - 58, 58,162,160,160, 0,119,238,220,161,110,110,110,228,210,165, 75,112,115,115, 67, 90, 90, 26,116, 58, 29,242,243,243,147,180, - 90,109,185, 5,191,168, 27,176,251,180,238,206,167,158,133,108,107,227, 74, 94,220, 25,252,101,187,136,103,143,158,198,156, 61, -119,237,123, 86,173,136,205,138, 59, 63,211,187,233, 61,187, 9,211,191,195,154,165,243,241,236,214,229, 12, 71,143,156,181, 38, - 68,179,181,121,151,242,195,155,159,159,175,126,250,244,169,249,131, 7, 15, 64, 8,129,165,165, 37,148, 74,101,153, 34,203, 80, -112, 28, 87,242,155,150,150,134,212,212, 84,132,135,135, 99,219,182,109, 72, 72, 72,176, 91, 97,105,145,100, 39,147, 62,148,102, -145, 57, 58, 29,189, 87, 9,221,198, 46, 93,186, 12,241,240,240, 48, 47,125,176,105,211,166, 24, 59,118, 44,214,175, 95,143,235, -215,175,191,182,222,101, 82, 82, 82,162, 94,175,223, 90, 65,222,102, 17, 66,186,245,235,215, 47,228,202,149, 43, 22, 91,182,108, - 1,203,178,101,110,155, 55,111,198,205,155, 55,231, 82, 74,159, 86,177, 27,170,214,128, 1, 3, 46,239,220,185,211, 42, 53, 53, - 21,105,105,105,200,203,203, 67,126,126, 62, 56,142,131,159,159, 31, 97, 89,214,175,178,238, 64,123,123,251,147,193,193,193, 29, -252,252, 10, 47,213,235,245,184,118,237, 26, 62,248,224,131, 28,173, 86, 59,128, 82,154, 78, 8,153,125,224,192,129,235,205,155, - 55, 71,211,166, 77,109,162,163,163,109, 0,148,105,185, 46,238,182, 77, 77, 77, 69,106,106, 42,126,253,245,207,117,156, 53, 26, - 77,105, 17, 94,141, 82,250,242,191,216, 96, 19, 66,136, 68, 34,193, 39,159,124, 2,177, 88, 12, 19, 19, 19,168,213,106,232,245, -250, 18, 17, 15, 35,187,159,125,124,204,109,197,144,126,230,235,219,118,202,160,201,189,236,157, 93, 92, 97,101, 33,199,147, 39, - 97,173, 47, 94, 56,247, 75, 29, 63,251, 13,188, 86,191,225,233,203,172,152,191, 33,126,175,105,145,255,104, 23,225, 64,206,206, -238, 64, 90,124,188, 76, 39,147, 41,195,139,173, 90,133,226,106, 32, 7,236, 6,171,211, 23, 85, 16,180,104, 51, 44, 45,114, 10, -180, 72,138,126,142,152,208, 75,112, 84, 39, 32,237, 69, 99, 64, 90, 15, 58, 85, 22,178,114,242,138, 94, 36, 14, 15, 66, 46, 32, - 39, 59, 3,254, 77,122, 1, 34, 81,185, 93, 91,150,182,164, 87,171,198,245,153,136,152, 80, 52,245, 29,136,234,110,109, 16,157, -152,131,172, 60, 13, 50,115,212,104,232, 63, 11,169,153, 42,228, 20,168, 17, 22,177, 29,174, 46,213, 69, 68, 28,213,201, 80,129, -165,126,176, 19,154, 71,123, 33,173,222, 1,178,186, 67, 32,113,107,137,216, 71, 65,184,127,242,103,196, 61,190, 10,202,115,112, -172, 86,219,160,184, 51, 12,179,241,236,217,179, 13,219,182,109, 43,238,212,169,147,191,155,155,155,127, 92, 92, 92, 40, 0,184, -185,185,249,119,235,214,205,223,193,193, 1,171, 86,173, 42, 96, 24,102, 99, 21, 27,217,210,149,211, 61,103,103,231,101, 7, 15, - 30,252,105,236,216,177,112,114,114,170,208,124,158, 42,145, 52, 24,181,104, 17,149, 48, 12,221,179,102,141,244,187,211,167,127, -254,125,235, 86,105,199, 14, 29, 8,165, 20,247,239,223, 87,254,184,102,141,114,120,159, 62,175,162, 83, 82,216,224,235,215,117, -137,113,113,185, 41,249,249,223, 37, 36, 36, 36,253, 19, 5, 88,175,215,223,120,241,242,133,107,147,230, 13,237,239, 61,121,241, - 56,176, 99,171, 86, 34,145, 72,244, 44, 42,250,186,189,189,133,242,220,217,115, 58,189, 94,127,195, 16, 46,185, 92,222,171, 99, -199,142,226,204,204, 76,184,184,184, 32, 53, 53, 21,241,241,241,133, 22,134,236, 76,232,178,179,161,207,201, 2,151,159,135, 23, -119,110,163, 97,117,111,249,254,194, 65,240,123, 42,201,147, 50, 45, 83,165, 45, 89,114, 51,115,200,205,205, 64,140,236, 30, 36, -132,244,177,178,178,154,153,149,149,117,146, 82,250,131, 78,167,155, 56,115,230,204,166,171, 87,175,182, 91,184,112,161,197,152, - 49, 99,246, 19, 66, 26, 82, 74, 53,229,113,228,229,229, 69,178, 44,107, 7,192,225,194,133, 11,112,112,112, 64,118,118,118,177, -101, 69, 91, 80, 80,160, 72, 79, 79,135, 70,163,129, 86,171,133,133,133, 5,238,222,189,155,201,178,236,209,202,194,103, 81,131, -252,160,209, 61,249,198,182,182,105,130,142,181,110,151,146,193,103,206, 95,150,176, 0,192,207,221,107,212,216,172,227, 47,191, -120, 30,122,204,250,229,157,160,140,132,231,249,213, 55,159,136,202,173, 32, 29, 41, 33,132, 39,132, 80, 95, 95, 95,164,166,166, -130, 97, 24, 40,149, 74,152,153,153,161, 86,173, 90,136,141,141,173,178,192, 98, 89,182, 68, 92, 29, 63,126, 28,137,137,137,216, -189,123, 55,220,221,221, 69, 0,236, 99, 99, 99,187, 12, 26, 52,168,185,173,173,245,226,244,244,204, 37, 21,132,243, 62, 0,139, - 55,242,169,131,157,157,221, 69,141, 70,131,168,168, 40, 28, 62,124,184, 61,165, 52,216,200,119, 59,138, 16,210, 45, 32, 32, 96, - 91,227,198,141,107, 80, 74, 81,175, 94, 61, 12, 29, 58, 20,219,183,111,199,131, 7, 15,144,157,157,205,159, 59,119,238,119, 0, -203,140,109,184,139,210,215,111,192,128, 1, 87,119,237,218,101,157,158,158, 14,149, 74,133,252,252,124,236,223,191, 31,173, 91, -183,134,157,157, 29,118,238,220,201, 82, 74,143, 85,192,165,176,178,178, 58,121,245,234,213,246, 53,107,214, 68, 88, 88, 24, 46, - 92,184,128,106,213,170, 65, 38,147, 97,196,136, 17, 22,235,215,175,255,130, 16,178, 68, 34,145,252, 48, 96,192, 0,112, 28,135, -107,215,174,165, 3,200,168, 76, 4,151, 99,217, 41,126,207,214,138,197,226, 97,132,144,174,148,210,219,255, 21, 97,229,231,103, - 93, 87,198,200, 39, 75,165, 18,219,204,204,204,146,186, 67,171,213, 66,163,209,188,102,185,146, 74, 37,182,205, 26,121,158, 80, - 21,228,206,121, 28,158, 89,238,152,180, 58, 53,173,234, 43, 77, 45,167,244,236, 54,104, 68,215,110,125, 25, 86,175,199,153, 51, -199,240,235,175,235,208, 33,192, 23,213,107,214,195, 23,147, 38, 91,106,180,236,172,115,231, 78,207,108,213,204,251,116,110, 78, -214,236,138, 56, 5,148, 33,176,202, 86,140, 3, 57, 87, 87,100, 22,189, 48,118,214,214,214,107, 56,142,235, 0,124, 6,137,153, - 19,194,238,222, 66, 70,166, 4, 26, 21, 87, 98,145, 50, 4, 89,217,185,136,126,120, 1,107,127, 89,137,244,244,116, 4,180,109, -143, 44,226, 6,107, 59, 7,100,166,167, 22, 85, 36,128, 78,171,135,189,163, 39,238,221,123,160,207,201,207, 47,183, 34,146, 42, -116,181, 61, 28,125,161,209,181,132, 66, 38, 67,118,174, 22,153, 69,226,106,231,129,193,208, 20,168,192,106,117, 96,181,122,216, -123, 12, 64, 45,199,142,224,185, 99,117, 13,172,208, 10,127,121, 22,218,136,115,208, 70,156,131,105,135,111,112,100,209,136, 55, - 94,124,195,102, 25, 39, 39, 39,167,186,185,185,157, 14, 9, 9,233, 53,120,240, 96, 4, 5, 5,141, 2, 48,173,168,113, 31, 53, -120,240, 96,132,132,132,224,233,211,167,167,147,147,147,223,139,207, 14,153, 76,166,214,106,181,197, 93, 65,138, 74,174,117,109, -218,191,191, 40,251,222,189,156, 21,215,174,205,223,188,101,139,180,115,167, 78, 68,207,178,224, 57, 14, 53,125,124, 72,215,174, - 93, 77,183,239,219,103,203,232,245, 55,167, 79,156,120, 97,253,135, 31,230,222,202,203, 51,116, 0,121,181,162,174, 65, 0,168, - 86,193, 49,131,161,209,104, 86,143,251,108,116,231,224,203, 87,221, 61,220, 93, 45,206,156, 11,126, 32, 55,145,137,170,123,213, - 96, 50,179, 51,196, 11,230,207, 49,209,104, 52,191, 24, 72, 87,219,206,206, 14, 73, 73, 73,136,136,136,128, 70,163,129, 94,175, - 7, 95,144, 15,109,102, 22,180,217, 25, 32,106, 21,228, 28, 7,117, 90, 50,170, 85,247, 6,254,156, 97, 88, 89, 3, 86,166,192, - 42,254, 85, 88, 90, 64,110,106, 6, 70, 34, 49,120,209,114, 66, 72,227,102,205,154,237,251,227,143, 63,164, 31,127,252,113,115, - 66,200, 26, 74,105, 52, 33,164,211,220,185,115,111,175, 89,179, 70, 62,118,236, 88,191,101,203,150,141, 4, 80,174, 96, 87,171, -213,251, 78,156, 56, 49,220,211,211,211,225,209,163, 71, 80,171,213,224,121, 30,221,187,119, 7,128,146, 50,243,236,217, 51,149, - 90,173, 78, 9, 13, 13,205,137,142,142,214,194,128, 89,127,243, 87, 37,220,152, 54,200,173,191,163,147,235, 77,133, 73, 53, 47, -154,119,175,223,180, 65,110, 75,151,239,143, 83,159,138,140,204,157, 59,161,250,146,252,220,135, 19,172,220,242,214,158, 58, 22, -101,200, 44, 95, 90, 60, 45,221,214,214, 22, 98,177, 24, 18,137, 4, 82,169, 20, 0,224,232,232,136,236,236,236, 10,187, 8,203, -107,188,115,114,114,144,157,157,141,167, 79,159, 34, 49, 49, 17, 55,110,220, 0,199,113, 40,156,164, 8,184,185,185,225,246,237, -219,230, 77,155, 54,157, 67,164,228, 18,213, 81,131,167,141, 51, 12, 51,229,195, 15, 63,132, 86,171,197,208,161, 67,177,121,243, -230, 41, 0,130,141, 45,239,148,210,155,132, 16,159, 7, 15, 30, 88, 0,248, 96,200,144, 33, 91, 7, 12, 24,128,224,224, 96, 28, - 59,118,172, 61,128,112, 0, 42, 0,139,139, 22, 86, 94, 92,209, 4,143, 34, 87, 12,235,236,237,237, 63,168, 91,183,238,131, 1, - 3, 6,248,239,218,181,203, 42, 37, 37,165,120, 82, 3, 94,190,124,137,223,126,251, 45,113,203,150, 45, 57, 28,199,217,138, 68, -162, 19, 89, 89, 89,229,205,130, 86,152,154,154,158,186,122,245,106,187,154, 53,107,226,252,249,243,152, 51,103, 14,218,181,107, -135,221,187,119,163, 86,173, 90,168, 87,175, 30, 28, 28, 28, 38,100,100,100,180,218,180,105, 83,251, 22, 45, 90, 96,231,206,157, - 72, 76, 76, 92, 87,145,203, 6,150,101, 43, 20, 88, 60,207,155, 14, 26, 52,232,243,149, 43, 87,194,195,195,227, 44, 33,164,217, -127,193, 77, 75, 45, 31,219, 37,205,154,182,155,233,236, 90, 19, 59,119,237, 70, 70, 70, 70, 73,251, 84,210, 70, 81,138,220,220, - 92, 36, 37, 37,193,210,194, 28, 75,151,253,208, 99,252,152,209,238, 0,252,203,172,232,106,216, 44, 27, 56,244,211, 47,135, 14, - 31,141, 71, 15, 66,176,125,235, 70,132, 62,186, 95,194,199,234,117, 8,127,114, 23,225, 79,238,194,209,201, 19, 93, 59,183, 39, -195,134, 13,235,254,225,240, 33,246, 0,254, 50, 23, 16,255, 37,235, 85,185, 93,132,111,188, 48,118,214,214,214,143,247,238,221, -107, 27, 16, 16,192,176, 44,139,211,103,206, 96,194,231, 31, 97,228,135,179,160,131, 53, 88,173, 20,188, 84, 97,208, 3, 51,210, - 83, 65,121, 30,249,249,249,184,126,253, 58, 56,189, 14, 31,142, 25, 9,158,231, 74, 4, 22, 64,161,213,233,224,234,225,135,117, -155, 23,178,144, 72,202,173,200,114,210, 25, 78,207, 82,196,167,196, 32, 38, 49, 20,150,230, 30, 16, 75, 60,144,158, 85, 0,177, -200, 9,122,245, 51,112, 69,230,211,130,252, 56,168,116,239,150,111, 92, 70,212,219,199, 88,214,224,251, 11, 10, 10,246,237,220, -185,179,235,242,229,203,165, 61,122,244,168,225,230,230,214, 12, 0,250,247,239, 95,195,220,220, 28, 59,119,238,212, 21, 20, 20, -236,123,143, 22,158,182, 77,155, 54, 69, 70, 70, 6, 94,189,122, 85,225,151, 7,167,213,218,154, 57, 56, 48, 41,151, 46,233, 83, - 51, 51,221, 59,118,236, 72,244, 44, 11, 17, 33,200,200,206, 70,244,171, 87,176,178,178, 34,143,159, 61, 51,251,229,139, 47, 14, -249,250,251,139,139,103, 24, 26,130, 99,199,142, 41,241,198, 32,212,178,142, 25,249, 66,230, 19, 66, 70, 79,156, 56,241,208,142, - 29, 59, 45,147, 83,146,195,229, 50, 25,107,102,166,112,249,112,196,120,113, 86, 86,214,112, 74,105,158,161,124,153,153,153,120, -241,226, 5, 76, 76, 76, 32,149, 72,192,171, 10,192,229,231, 65,157,145, 10, 70,167,133,140,227, 96,163,148,195,221,209, 17, 30, -246,118, 6,113, 62,187,112,182,100, 64,123,233,110,193,239,155,214,134,220,212, 12,114, 51, 51, 76, 61, 17, 84,244,245, 41, 5, -230, 85,222, 51, 76, 8,177,115,117,117, 61,186,107,215, 46,105,106,106, 42,238,223,191,255,128, 82,154, 77, 8, 49, 7,192, 63, -121,242,228,124,104,104,104,175,162, 89,116,149,205,254,250,249,224,193,131, 93, 2, 2, 2, 88, 47, 47, 47,211,228,228,100,143, -244,244,116,146,152,248,250, 24,230,147, 39, 79, 42, 84, 42, 85, 62,207,243,135, 80,232,199,169,210,130, 63,109,144,155,226,250, - 61, 76,106, 23, 88,173,158,133, 93,125,100,176,247,234,221,124,144, 56,105,218, 32,183,213,203,247,199,169, 77,136,102, 43,225, - 98,221,197, 10,245, 54, 3,243,155,218,217,217,129, 82,138,219,183,111,227,234,213,171,184,124,249, 50,162,163,163,255,180,106, - 91, 90,226,220,185,115,232,208,161,131, 49,239, 37,156,157,157, 97,109,109,141,237,219,183, 99,247,238,221, 37, 3,221,139,145, -150,150, 6,165, 82,137,229,203,151,155, 13, 28, 56,240,123, 0, 93, 13, 20,194,222, 93,186,116,233,233,236,236,140,244,244,116, - 56, 57, 57, 33, 32, 32,160, 55, 33,196,235, 29,186,178,198, 7, 6, 6,254,240,221,119,223, 65,175,215,227,147, 79, 62,193,243, -231,207,247, 61,127,254,124,165,135,135,199,164, 25, 51,102, 56, 58, 58, 58, 98,240,224,193,166, 0,250,151, 71, 98, 99, 99,179, -120,227,198,141,195,123,246,236, 41,210,233,116,109, 47, 94,188,136, 87,175, 94, 65,171,213,130,101, 89, 68, 70, 70, 98,226,196, -137,137,233,233,233,237, 40,165,145, 6,132,107,214,217,179,103,219,213,174, 93, 27,199,143, 31, 71,255,254,253, 47, 89, 89, 89, -249,214,175, 95,223,217,197,197, 5,251,247,239,135,133,133, 5, 60, 60, 60,108, 22, 46, 92,216,177,111,223,190, 56,126,252, 56, -166, 78,157, 26, 4,160,194,217,174, 44,203, 66, 44, 22,151,116,135,149, 18,175, 56,114,228, 8, 6, 12, 24,160, 88,191,126, 61, - 8, 33,200,200,200,176,176,183,183, 15, 37,132, 88, 84,100,189,253, 55,128, 17,145, 81,139, 22, 76,199,157,123,207,112,240,160, - 20,119,238,220,129,163,163, 35,228,114, 57, 40,165,208,104, 52, 72, 77, 77,133, 94,167, 65,189,186,222,216,182,101, 9, 82, 82, - 82, 1, 81,249, 99,210,136,136,140, 24,253, 81, 63, 92,185,122, 6,235,215,111, 68, 94, 94,126, 57, 31,221, 10,212,244,173, 13, - 87, 23, 7,196,198,197,130,136, 96,247, 87,198,245,255, 73, 23,225,159,176,178,178, 90,185,103,207, 30,219, 14, 29, 58, 48,249, -249,249,224,121, 30,109, 2, 2, 48,105,202, 20, 28,219,181, 11, 62,205,135,130,104,205,192, 42, 13,155,197,144,153,158, 10,189, -210, 25,125,251, 13, 68, 92, 92, 12,170,213,105,129,204,140,212,162,169,209, 92,137, 5, 75,171,213,193,206,193, 29,103,207,158, -101,240,201, 39,143,203, 21, 5, 58,217,195,240, 72,117,235, 44,213, 61, 92,191,179, 29, 58,141, 14,245,234,205,133,142,183,133, -131,219, 24,232,245,135,145,147,122,177,176,187,194,182, 3,226, 98, 98, 32, 98,164,143,141,177, 96,189,246,188,220,183,123,194, -120,206,112, 31,168,153,153,153, 57,206,206,206, 71,110,220,184, 49,168,127,255,254, 56,119,238,220,200, 34,129,133, 27, 55,110, -224,197,139, 23, 71, 50, 51, 51,115,222, 71,230,186,185,185,117,111,223,190,125,255,166, 77,155,226,248,241,227,224, 56,238,186, - 65, 47,180, 68, 66, 69, 34, 17,120,158, 7, 1,144,158,149,133,231,207,159, 35, 61, 45, 13,122,189, 30,249,121,121,124,109, 95, -223, 60,202,243,230,198,132,167,244,140, 65,148, 49,139,176,248, 88, 21, 68, 86,180,153,153, 89, 76,110, 94,158,189,181,149,117, -174, 76, 38,227, 50,179,178,178,195, 30, 63,210, 26,216, 40, 20,227, 73,104,104,168,127, 66, 66, 2, 98, 98, 98,192,230,231,130, -209,104, 33,210, 20,160, 83,171,150, 48, 1,133, 2, 60, 36,188, 30, 18, 70,130,220,194,217,118, 79, 42, 21,229,165, 26,132, 98, -113, 69, 8,129,194,204, 28, 82, 83, 83,200,205,205, 95,179,104, 25, 50,241, 75, 46,151,239,218,191,127,191,179,171,171, 43, 22, - 44, 88, 0, 55, 55,183, 90,245,234,213, 43,104,211,166,141,137,163,163, 35,234,212,169,131, 86,173, 90,225,212,169, 83, 0, 16, - 89, 73,250,177,132,144,174, 87,174, 92,249,242,218,181,107,131, 8, 33,100,214,172, 89,232,214,173, 27, 20, 10, 5, 10, 10, 10, -144,153,153,137, 77,155, 54, 17, 74,105,163,162,176,122, 42, 20,138,221,132,144, 56,149, 74, 53,248, 77,206,237, 43,234,187,164, -100,240,159, 56, 58,185,246,107, 23, 88,173, 94,199,192,206,240,246,233,136,142,129, 49, 0,176,196, 70,252,106,232,210,111,252, - 15,217,185,219,252,118,246,244,185,249, 1,237, 58,126, 61,107,172,245, 15, 75, 54, 86, 94,246, 9, 33,224, 56, 14, 98,177, 24, - 34,145,168, 76, 43,149, 88, 44, 46,153,109,102,128,245, 42,174,111,223,190, 37,251, 9, 9, 9,118,238,238,238,162, 98,203, 21, - 0,100,103,103, 35, 54, 54, 22,122,189, 30,182,182,182,208,233,116,245,141, 40, 87,147, 62,254,248, 99,162, 82,169,240,233,167, -159, 98,243,230,205, 24, 58,116, 40, 9, 14, 14,158, 4, 96,138,177,229, 93, 36, 18, 45,157, 49, 99,198,151, 19, 39, 78, 68, 70, - 70, 6, 78,158, 60,137,238,221,187, 99,239,222,189,246, 39, 79,158, 92,212,161, 67, 7, 48, 12,131,227,199,143,131,101,217,103, - 21,113, 73,165,210, 15,122,246,236, 41,138,141,141,133, 84, 42, 69,147, 38, 77, 16, 23, 23,135,130,130, 2,196,199,199, 99,242, -228,201, 73,233,233,233,237, 13,121,143, 8, 33,146,154, 53,107, 78,172, 85,171, 22,206,157, 59,135,129, 3, 7, 6,235,245,250, -158,169,169,169, 19, 51, 51, 51,127, 26, 49, 98, 4,252,253,253, 17, 30, 30,142, 46, 93,186,160,117,235,214, 56,121,242, 36, 62, -253,244,211, 32,189, 94,223,179, 18, 63, 88,207,142, 30, 61,234,209,169, 83, 39, 20, 20, 20, 32, 39, 39, 7, 18,137, 4, 86, 86, - 86, 56,117,234, 20,170, 87,175,142,245,235,215, 99,202,148, 41, 88,185,114, 37,111,111,111,207,106, 52, 26,233,127,193, 10,194, -115, 60, 0, 30, 94,238,102, 56,115,108, 11, 66, 30, 68, 33,228, 65, 40,100,242,194,193,237, 42, 85, 1, 26,213,171,137,230, 77, -154, 33, 33, 49, 30, 59,182,111,129,141,157,107,133,245, 8,165, 20, 82, 49,135,218,190, 78,216,181,125, 35,142,159,188,128,237, - 59,118,163,184,183, 67, 44,150,160, 97,163,230,104,210, 36, 0, 81, 47, 34,177,101,203,122,216, 59,184, 11,125,126, 85,237, 34, - 44,253,251, 90,230,242,124,199,128,128, 0, 38, 47, 47, 15,106,181, 26, 73, 73, 73,120,245,234, 21,172,172,173, 16,149,240, 18, -237,149, 58, 36,241, 57,120,242,224, 49, 71, 24,201,253,202, 30,184,225,187,207, 42,111, 48, 65, 97,106, 97, 7,141, 70, 3,157, - 94, 31,129,213,171,203,253, 82,102, 57,253,249, 51,231, 46, 54,251,120,228, 7,146,179, 23, 55, 67,175,229,161,210, 91, 34, 95, -173, 69,190, 78, 2,145,101,119, 32, 45, 24,140, 88,142, 22, 13,106,226,208,193, 83, 58,202,234, 47, 24, 88,178, 33,118,174, 15, - 54,241,225,159,135,222,152, 77, 40, 85,154,129,231, 88,227, 94, 24,158, 63,180,107,215,174, 30, 45, 91,182, 84,118,232,208,161, -122, 81,131,169,221,181,107, 87, 65,145,117,192, 88,213,255,154,247,118, 87, 87,215,250, 98,177,184,127,175, 94,189,234,143, 30, - 61, 26,143, 31, 63,198,206,157, 59, 35,124,125,125,175, 86, 40,172,100,178,244,188,148, 20, 43, 51, 47, 47,177,181,185,121,194, -169,147, 39, 61, 59,119,233, 66, 98, 98, 98,144,158,158, 14,181, 90,141,251, 15, 30, 80, 9,195,196, 17, 11, 11,209,179,123,247, - 68,140, 76,150,110, 68, 80, 95, 85, 50,139,112,113, 85,173, 89,238,206,214, 53,230,207, 26,231,173,214,168,253,115,114,114, 88, -177, 68, 34,113,115,178,138, 54,178,187,241,248,249,243,231,251,118,238,220, 89, 30,254,240, 62,216,236,108,104,179, 51, 33,229, - 57,216, 52,106, 0, 70,167, 1,180,122,184,214,166, 80,103, 41, 17,124,235,153, 94,163,209, 84,186, 82, 59,199, 22, 10, 44, 81, - 41,103,128, 0, 32, 51, 55,131,194,220, 2, 10, 51,179, 55,187, 16, 73, 37,249,173,252,224,131, 15, 58,181,104,209, 2,148, 82, -108,218,180, 9, 58,157, 78,166,211,233,160,213,106,161,211,233,144,147,147,131,237,219,183, 99,221,186,117,215, 0,252,110,128, - 72,101, 37, 18,201, 68,150,101, 29,228,114,185,206,222,222, 94,186,111,223,190, 18,183, 17, 13, 27, 54,132,169,169,169,134, 16, -162, 3, 0, 39, 39, 39,253,214,173, 91,197,125,250,244, 41,179, 17,243,171, 87,107,186, 55,107,221, 78, 97, 82,205,203,194,174, - 62,188,125, 58, 2, 0,186,244,250, 24,222, 53, 61,144,147,246,208, 75,173,122,213, 79, 42,206,180,126,188, 58, 62,204,164,167, -255,232,252,148,160,231, 0,182, 24,248, 14,161,115,231,206, 8, 12, 12, 44,233, 14,116,112,112,128, 86,171, 5,199,113, 70,185, -186, 40,118, 34,250,221,119, 68,132,249,192, 10, 75,139, 36, 0,246,165,197, 85, 76, 76, 12, 98, 98, 98,138,173,194,149,230, 81, -169,188, 50,241,241,241, 25,213,168, 81, 35,156, 60,121, 18,119,238,220,137, 63,115,230,140,107, 64, 64, 0,188,188,188, 70, 19, - 66,230, 80, 74, 85, 70,188,235,166,109,219,182,253, 98,226,196,137, 8, 13, 13,197,184,113,227,210, 99, 99, 99, 15,237,219,183, -239,211,249,243,231,139, 2, 3, 3,145,152,152,136,165, 75,151,114, 87,175, 94, 93, 6, 96, 65, 37,249,254, 52, 54, 54,214, 77, -173, 86, 35, 35, 35, 3, 44,203,162,160,160, 0,167, 78,157,194,246,237,219,147,139,196, 85,132,129,193,179, 9, 8, 8,176,126, -254,252, 57,182,108,217, 2,173, 86,251, 53,165, 84, 77, 8,249,125,230,204,153,115, 28, 29, 29, 45,187,116,233,130, 70,141, 10, -125,193,237,221,187, 23,147, 39, 79, 14,210,106,181, 61, 13, 72,131,225, 35, 71,142,252,202,197,197,101,242,140, 25, 51, 76, 58, -119,238,140,141, 27, 55,130,101, 89, 12, 26, 52,168, 68, 92,237,216,177, 99,215,142, 29, 59, 6, 2,144, 2, 80,252,219,173, 87, -127,230, 19,135,130,204, 80,112, 26,107, 52,172,231,135,134,254,213,112,230, 98, 8, 0,160,211,128, 0, 20,228,231, 98,235,214, - 77,136,136,120, 14,177, 68, 2, 43, 27, 39,131,222, 33,109,206, 83,100,233, 18,209,185, 67, 19,116, 15,108,143,223,183,237, 5, -171,215,225,211,143,135, 35, 51, 43, 11,219,182,109, 65,212,139, 72,136, 37, 18,216,218,185,252, 13,241, 44, 95,139,252, 39, 45, - 88,197, 21, 10,207,243,136,143,143,199,221,187,119,241,242,229, 75, 40,149, 74,168, 88,142, 95,127,254, 42, 79,136, 52,142,167, -244, 26,101, 75,188, 10,191,205,193,113,241,165, 60,204, 90, 90, 91, 91,203, 52, 26, 21, 88, 86, 95,170,166, 34, 0, 1,164, 98, -192,217,197, 27,177, 49,177, 84,165, 86, 7, 85,248, 5,166, 81,175, 60,114,104,255,196, 86,173, 3,236,186,119,250, 14,135, 14, -207, 69,102, 78, 14,212, 58, 9,242,213, 58, 20,168, 1, 43, 27, 95, 52,173, 87, 31, 9, 9,233,120,120, 39, 56, 79,172, 41,168, -116, 0,168,158,138,178,119, 45, 25,103,249,193,136,207, 97, 82,173, 45, 52,143,247,131,207, 77, 2,159, 91,216,109, 34, 51,181, -128,185,157, 59,242, 10,212,184, 26, 26, 5, 61, 21,101, 27,154,232,201,201,201, 5,206,206,206, 7,198,143, 31,191,228,254,253, -123,222, 0,112,251,246,237, 23, 9, 9, 9,179,146,147,147, 11,140,201,192, 82,222,219,137,137,137,201, 45, 31, 31,159,151,221, -187,119,183,232,219,183, 47,236,237,237, 17, 18, 18,130, 31,127,252,241,185, 86,171,157, 23, 20, 20, 84,161, 18,212,106,181,241, - 33,135, 15, 91,180,255,232, 35,171,233,189,123, 47,157, 56,113,226,202, 5, 11, 22, 72,124,124,124,136, 94,167,195,163, 71,143, -232,174,157, 59,245,235,102,207, 94, 33, 51, 53, 21,223, 62,114, 68,194,106, 52,241,255,116, 33,118,115,115,107,215,163, 91,187, -218,203,150,175,134, 90,149,135, 91,215, 79, 32, 51, 51, 21, 27, 55, 29,172,237,230,230,214, 46, 46, 46, 46,216, 64, 75,198,222, -223,126,251,237,203,230,141, 26, 53,170,238,238,142, 71,209, 47, 33,227, 57, 72, 89, 22,140, 78, 3, 17,171,134,187, 63, 5, 17, -153, 35, 49, 41, 7, 11,247, 28, 8,229, 56,110,111,101,188,117,123,124,128,101, 9,217, 32,132, 96, 97, 11,127,200,205,204, 32, - 51, 51,195,148, 99, 23, 75, 68,213,145, 5,179, 33, 55, 53, 67,205, 22, 1,134, 84, 66, 5,230,230,230,119, 31, 61,122,212,212, -223,223, 31, 95,126,249, 37, 94,189,122, 5,158,231,145,156,156,172, 78, 76, 76,140, 79, 77, 77,125, 5,224, 16,128,205,148, 26, -230,191,137,101, 89,135,144,144, 16, 20, 53, 78,184,112,225, 2, 92, 92, 92, 96,105,105,137,156,156, 28, 76,159, 62, 93, 62,111, -222, 60, 0,192,221,187,119, 37, 38, 38, 38,229,114, 61, 10,121,178, 44, 43,151,102,210,188,123,253, 50,216,123,245, 58, 6,198, -162, 75,175,209, 56,119,252,119, 92, 60,115, 30, 54,226, 87, 47, 97,154,123, 42,237,101, 90, 78, 92,190,207,134,218,141, 63,101, - 18,243,207,108,152,212,199,154,113,118,230,247,207, 90, 87,190,227,222,226, 47,112,134, 97, 74,198, 96, 21, 15,104, 55, 86, 92, -149,198,252,249,148, 39, 32,196, 78, 38,125, 24, 27, 27,219,197,205,205, 13,201,201,201,136,141,141, 69, 76, 76, 12, 98, 99, 99, - 81,179,102, 77, 68, 69, 69, 65, 42,149,222, 55,144,118,248,224,193,131,205,181, 90, 45,118,239,222,205, 2,232,181,127,255,254, -187, 77,155, 54, 21,119,235,214,205,124,237,218,181,195, 1,108, 54, 34,152,166, 22, 22, 22, 82,157, 78,135,181,107,215, 34, 54, - 54,182, 29,165,244, 9, 33,100,195,224,193,131,215,249,251,251,215, 12, 13, 13,125,158,151,151, 55,158, 82,250,208,128,186,232, -227, 38, 77,154,236,231,121,222,179,115,231,206,166,203,151, 47,183,120,246,236, 25,220,220,220,192,243,252, 35, 35,199, 48,101, -156, 63,127, 62,179, 85,171, 86,214, 69, 3,218, 23, 18, 66,190,103, 24,102, 73,255,254,253, 45,119,237,218,133,147, 39, 79, 66, -171,213,226,233,211,167,169,161,161,161,191, 0, 88,102,136, 8,162,148,102, 2,152, 67, 8, 89, 58,121,242,228,169,132,144,185, -169,169,169, 37,254,159,138,197, 21,128,145,148,210, 17,255, 49, 67,136, 94,167,211,194,194,198, 27,121, 89, 49, 72,141,189, 14, -165,185, 19, 2, 59, 54, 64,129, 74,139, 99, 71,254,192,195, 71, 15, 32, 18,137,224,232,228, 14, 43,107, 59,132,135, 63, 7,128, -176,138, 57,117, 48,183,174,134,188,236, 88,104, 83, 66, 96, 98,230,128,209, 31,245, 67,129, 74,135,131,135,254, 64,104,232, 67, - 48, 12, 3, 39,103,119, 88, 90, 21,114, 18, 90, 33,167, 0, 99, 5, 22,195, 48,151, 78,159, 62, 61,176,121,243,230,226,136,136, - 8, 68, 68, 68, 20,119,117,177, 4,220,129,228,135,135,135, 85,208,248,119, 46,246,149, 81,122,109, 65, 51,115,243,248,103, 79, -159, 56,102,102, 36,227,193,189,171,136, 8,127,132,151, 81, 79,160,211,169,193,136, 68, 16, 49, 34, 84,243,174,139,171,215,174, -107,181, 28,119,163, 60, 78, 0,200,200,136,204, 53,115,244, 29,242,195,130, 57,199,167, 78,255,214,100,208,192,245,120,248, 44, - 12,121,172, 19, 40, 5,156,108, 77,209,176,250, 12,196, 39,164, 98,207,239,107, 11,120,157,110, 68,105, 31, 88,101,113, 2, 64, -170, 88,229,176, 97,251, 31, 75,247,236, 63,248,217,152,209,195, 21,237, 59,127, 4,105,218, 35,176, 9, 33,112,173, 19, 0, 42, - 54,193,237,144,123,120, 24, 17,171, 46,208, 49,155,115,164,170,233,149,113,150, 70,118,118,246,157,228,228, 36,239, 82, 94,219, -189,229,114,197,157, 74,196, 84,231, 55,252, 2,189,230, 33,158, 97, 68,205, 23, 44, 88,144,239,236,236,172, 13, 13, 13,197,134, - 13, 27,248,187,119,239, 94,146,201,100, 27, 19, 18, 18, 52,149,113,218,235,245, 15,118,205,154, 85,167, 89,255,254,116,216, 23, - 95, 20, 64, 46,159,180,244,231,159,103,165,102,102,186, 80,158,135,189,141, 77,220,210,217,179, 23, 15, 28, 60, 56,243,241,213, -171, 38,215, 15, 31, 54,145,177,108, 72,101,225,124, 31,168,136, 51, 46, 46, 46,216,167,134, 7,182,110, 94, 14,157, 78,131,196, -248, 66,195, 85, 90,122, 54, 42, 18, 87,111,114, 22,117,254,247,255,102,222,188,155,223, 76,157,226,212,182, 83,103,196, 60,184, - 15, 93, 70, 42,136,158,133,132,136,145,159,162, 68, 74,114, 30,102,238,216,151,146, 87, 80,208,255, 77, 71,142,229,133,179,164, - 91,208,220,188, 72, 96,153,191,102,181, 82,152, 23, 14,114, 23,203,100,101, 13,134,127,139, 51, 47, 47,111,192,192,129, 3, 31, -222,190,125,219,250,211, 79, 63, 69,171, 86,173,238,169, 84,170, 14,148,210,220,170,166,167, 88, 44, 78,105,220,184,177,131, 68, - 34, 97, 63,249,228, 19,113, 90, 90, 90,137, 39,244,188,188, 60,156, 58,117, 10,197, 83,238, 31, 63,126,140,186,117,235,150,203, -249,233,140, 71,241, 0, 22, 76, 27,228,182,244,230,131,196, 73, 0,150,120,215,116,199,197, 51,231,113,229,226,245, 89, 45,252, -249,213, 61, 70, 52,253, 94,217, 97,240,244,218,141, 63,101,204, 44,156,177,237,224, 31,204,147,144, 45, 11, 11, 10, 30,213, 0, -240, 85,121,225, 36,132,128, 82,250,150, 75, 6,149, 74,101,144,184,170,168, 44, 81, 80, 42,205, 34,115, 6, 13, 26,212,252,214, -173, 91,230,102,102,102,208,233,116,160,148,162, 70,141, 26, 16,139,197,248,229,151, 95,242,211,210,210,230, 26,194,105,106,106, - 58, 49, 48, 48, 16, 79,159, 62,197,157, 59,119,254,160,148, 62, 36,132,252, 17, 17, 17, 49,164, 77,155, 54,248,253,247,223, 39, -150, 39,176,202,227,228,121,190,180,207,163,140,162,178,251, 0, 64, 11, 99,227, 94,228, 44,180, 53, 0,216,218,218,198, 58, 58, - 58, 90, 60,120,240, 0, 30, 30, 30,208,233,116,205,141, 41, 75,148, 82, 61, 33,100, 77, 80, 80,208,188,214,173, 91, 99,226,196, -137,237,130,130,130,218,181,110,221, 26,181,107,215,198,197,139, 23,177,115,231,206, 3, 28,199,141, 7,144, 69, 41,229,140,205, - 35, 74,105, 22,128,121,132,144, 25, 50,153, 12,230,230,230,226,248,248,120,102,247,238,221, 0, 48,166, 42,156,127, 85,189,244, -190, 56, 41, 33, 95,127,250,217,164, 13,159,125, 58, 92,209,164,113, 67, 20,228,196, 65,149,151,140,130,220, 36,252,178,249, 44, - 8, 17,193,222,222, 25, 14, 78,110,136,142,142,193,181, 19, 39,181,249, 5,170,149, 50, 61,191,164, 98,206, 47, 10, 57, 27, 21, -114, 22,228,167, 64,149,151, 82,194,233,224,224, 82,196, 25,141,171,215, 79,170, 85,249,249,203,181,148,252,244, 87,198,253,255, -157,192,202,204,204,156, 60,118,236,216, 14, 51,103,206,180,101, 89,150,177,177,177, 65,116,116, 52,123,224,192,129,140,188,188, -188,201, 85,122,168, 68,242,208,199,215,175, 67,159, 62,125,216, 15, 62,232, 45,253,240,227,110, 98,123, 7, 7,100,103,165, 35, -252,233,125, 60, 11, 11,129,143, 95, 3,204, 95,176, 2,176,178,170,116,166, 78, 94,114,248, 37, 51, 71,223, 94,223,125,243,213, -222,214,237,186, 90,248,213,109, 32,109, 88,195, 18, 58, 61,139,184,184, 56, 28, 57,252, 64, 23,122,247, 74, 14,207,106,135,228, -167, 26,182, 84, 78, 88, 24,213, 1,152, 92,167,142,197,119, 63,109,216,185,126,251,238, 3,253,198,140,232, 47,110,212,160, 19, - 94, 92, 63,132,203, 55, 47,178,153,106,122, 40, 87,194,124, 30, 22,145,147,105,108, 26,168,213,106,253,155, 67, 71,212,106,245, - 59, 47,122,186,117,235, 86, 36, 37, 37,233, 98, 99, 99,207,179, 44,123,200,152,217,136,171, 41,213,246, 39,228,252, 55, 1, 1, -221,190, 57,115, 70, 49,106,198, 12,237,136, 15, 63,252, 10, 26,141, 14, 50, 25, 21,155,154,138, 32,151, 75, 30, 95,189,106,178, -234,243,207,109,136, 86,123,238,119,227, 76,240,239,125, 22, 97, 41, 11, 22, 70,125, 58, 21,170, 82, 22,172, 27,119,194, 97,140, - 5,171,168, 2,143, 33,132,180,152,244,245, 55, 7,135, 4,118,170,237,239, 89, 77,110,239, 85, 13,102, 78, 78, 72, 79, 77,197, -213, 59,207,244, 11,246, 30, 12, 45, 18, 87, 6,249,133,225,121,190,100,150, 91,224,212,153, 32, 12, 83,226,142,161,120, 38,144, -119,179, 86, 96,196, 98,112,148,135, 70,163,161, 6,132, 51,142, 16, 50, 96,196,136, 17, 23,142, 31, 63, 46, 10, 12, 12,108,120, -232,208, 33,254, 93,202,142, 94,175,119, 43, 18, 90, 57, 74,165, 82, 60,122,244,104,232,245,122, 20, 20, 20, 32, 59, 59, 27, 79, -158, 60,209, 12, 26, 52, 72, 94, 36, 28,244, 67,134, 12,169,180,254, 88,190, 63, 78, 61,109,144,219,106, 27,241,171,161, 57,105, - 15,189,108,196,175, 94,182,240,231, 87, 47,223, 31,167,254,110,170,213, 15,105,175,130,195, 19,243,207,108,216,118,240, 15,102, -100,191, 1,156,155,217,243, 89, 10, 7,122,160, 99,239, 74, 27,161,183,156,138,190,131, 7,252,215,160,211,209,123,182,182,214, -139,155, 53,107, 54,103,249,242,229,102,246,246,246, 96, 89, 22, 47, 94,188,192,154, 53,107,242, 51, 51, 51, 23, 82, 74,239, 26, -194,229,235,235,235, 37, 22,139,177,103,207, 30, 0, 88, 83,116,120,205,161, 67,135,134,124,250,233,167,168, 86,173, 90, 29, 66, -136,220,152,174, 44, 74,105, 73,175,194,123,110,216,163, 86,173, 90,229,234,228,228, 68, 78,157, 58,197, 50, 12,115,172, 10, 52, -139,119,238,220,217,146,231,249, 78,109,218,180, 65,205,154, 53,139, 45,158, 56,124,248,240, 94,142,227, 70, 84, 36,130,140, 69, -110,110,110,241, 64, 59, 29, 10, 23,252,254,207,225,233,243,244,237,245,170, 59,158, 89,240,195,242,121, 53,170,123,141,251,100, -244, 96,198,215,167, 46,242,179,227, 96,107,231, 8, 55,119,111,164,166,164,225,244,233, 83, 92, 90, 90,214,111,156,136,124,247, -252,121,122,194,187,112,186,186,121, 35, 37, 37, 5, 39, 79,158,228,178, 50,115, 54, 65, 47, 90, 16,246, 42, 51, 25, 2,140,123, -167, 12, 25, 80, 91, 52,147,112, 85,161,155,134, 66,171, 86,102,102,230,100, 74,105,154,161, 74,156,188,233,252,108,208, 32, 41, - 78,156,168, 15,189,190,133,149,185,121, 39,202,243, 77, 27, 52,104, 96, 54,120,240, 96, 62, 32,160,149,204,194,194,130,212,169, -227,159,155,157,149,101, 93,248,101, 9,174, 50,213, 92,188,216,179,152,145,116,230, 56, 93,189,194,176, 86,190,216,179, 33, 74, -188,145,155, 69,117, 19, 57,191,217, 68,204, 7,168, 88,209, 85,149, 70,244,217,189,184,156,168,119,249,178, 41,189, 56,115,209, -210, 48,179,141,253, 90, 42,221, 69, 40, 18, 49,219, 92, 93, 93,231,196,196,196,164, 26, 90,137,149,197, 89,188, 84, 78,175, 41, - 83,244,141,187,118,101,109,220,221,121, 74, 41,247, 50, 36,132,220, 56,114, 68,114,227,200, 17,133, 94,163,185,180,159,210, 40, - 67, 56, 93, 92, 92, 22, 31, 59,118,204,224,177, 85,189,123,247, 14, 43, 30,151,101,104,122,214,168,238,118,166,186,151,107,215, -234, 94,133,221,208, 81, 47, 19, 16,245, 50,254,108,100, 84, 92, 96, 85,242,168,244, 98,207,164,200, 21, 3, 53, 96,177,231, 55, - 57,237,236,236,238,138,197, 98, 55, 99, 94, 74,142,227, 18, 82, 83, 83, 27, 25, 24,206, 97, 94, 94, 94, 75,162,163,163, 15,114, - 28, 55,245,125,124,121, 19, 66, 90, 49, 12,115,146,227, 56,147, 55, 45, 92,197, 34,140, 16,226, 41,151,203, 95, 27,228, 94, 17, -231,210,111,252,231,181,108,211,166,223,141, 43, 87, 14, 77,255, 33,244,181,113, 65,147,250,217,124, 60,108,194,228,159,118,175, - 93, 53, 99,245,161,140,223, 42, 11,167,163,163, 99, 16, 0,159, 98,161,101, 64, 90, 54,169,138,213,129, 72, 73, 83, 59, 75,187, -239,117, 58, 93, 3, 0, 84, 42,149, 62, 72, 75, 75,155, 91,150,184, 42,143,147, 97,152, 37,181,106,213,154,252,236,217,179,221, - 44,203,126, 82,234,250,101, 53,106,212,152,240,234,213,171, 53,122,189,126,186, 17,239,187, 69,155, 54,109, 50, 87,173, 90, 37, -154, 58,117, 42,130,131,131,109,138,186,207,222, 71,190, 59, 89, 91, 91,255,202,113, 92,109, 74,233,177,220,220,220,217,148,210, -124, 99, 57, 9, 33, 82, 0,211,170, 87,175, 62,217,205,205,205, 49, 46, 46, 46, 54, 42, 42,234, 39, 0,235, 13,237,174, 54,176, -254,212, 0, 40,158, 93, 85,233,120,171,127,171, 5,171, 52,234, 84,183,175, 78, 25,110, 97, 3,255,218, 3, 63, 26,209,143,220, -184,243, 28, 55,111, 92, 71, 92, 66,194, 33, 94, 36,154, 19, 30,158,246,252, 93, 57,175,223, 9,199,205,235,215,105, 98, 66,226, -126, 80,230,155,176,168,212,168,191, 43,238,255, 47, 5,214,251, 40, 40,196, 16,239,178, 46, 46, 46, 72, 79,111,174, 16,139, 3, -228,114,121, 7,145, 72,116, 57, 35, 45,237, 11, 67, 5,214,223,241,146,180,175, 99,111, 26, 20,150,154,255,190, 56,223, 28,160, - 94, 21, 78, 99, 56, 12,229, 44,111,177,103, 94,163, 73,176,101,217,187,171, 41,213, 26,202,233,230,230,246, 25,207,243, 94,134, -134, 73, 36, 18,189,140,139,139,219, 92,149,244,244,241,241,161, 17, 17, 17, 6, 13,146,252, 47, 84,184,255, 22,206,237, 43,234, -187,248,213,171, 53,253, 81,200,147,101, 69,221,135, 37,248,110,146,141,121, 64,199,246,115,175, 94, 12,250,126,254,234,140,220, -255, 90,220, 9, 33,162,178,132, 69,241, 92,116, 99, 57,165, 82,233,134,102,205,154,125,118,243,230,205, 95, 89,150, 29,243,191, - 26,247, 34,175,234,178,170, 12, 52, 23,222,163,138, 57,235,248,216, 54,161,180,196, 89,246,194, 39, 17,233,183,223, 27, 39,229, - 57,158, 50, 63, 60,139, 74,187,247,119,199,253,191, 6,241,223,245,160, 98,129, 84, 33, 18, 18, 98, 1,196, 2,216,255,191,154, - 96,134,136, 43,163,210,165, 10,162,232,175,224,120, 19, 69, 2,234,250,251,224,122, 83, 44,253,149,120,254,252, 57, 17, 94,235, -255, 61,124, 52,245, 97, 2,128, 41, 77,202,112, 77, 85, 36,170,166,119,248,224,191, 25,247,242,172, 54, 85, 93,136, 89,167,211, -141, 35,132, 76, 51,102,246,225, 63, 20,111, 10, 64, 35,148,254,247,143,176,231,233,119, 1,244,254, 95,231,252,255, 14,145,144, - 4, 2, 4, 8, 16,240,175, 19,109, 42, 33, 21, 4, 8,248,223, 6, 1,208,185,156, 23,216, 96,211, 31, 33,164,115, 21, 42,136, -243, 2,167,192, 41,112, 10,156, 2,167,192, 41,112,254,255,226,252,255,244, 37,244,151,109, 0, 58, 11,156, 2,167,192, 41,112, - 10,156, 2,167,192, 41,112,254,127,219,132, 46, 66, 1,127, 57,126,233, 79, 92,127,233, 79, 92,255,170,235, 5, 8, 16, 32, 64, -128,128,255, 53,136,255,107, 17, 34,132,216, 1, 24, 76, 8, 25, 84,100,161,219, 15, 96, 95,101, 46, 37,138, 97, 98, 98,146,172, - 86,171, 29, 0, 64,161, 80,164,168,213,234,210,107, 14, 16,188,189, 68, 6, 45,124, 76,249, 3, 86,189,189,189,147, 53, 26,141, -131, 1,214,196, 96, 66,200,101,145, 72, 20,108,140,239,166, 98,116,236,216,113, 20,195, 48, 11, 1,128,227,184,175, 47, 94,188, -184,245, 47, 76,231,230,238, 46, 78,191,235,244, 58, 54, 57, 53, 99, 46,165,244, 72, 89,215,173,235, 77, 22,139, 9,166, 23,253, - 95, 58,254, 88,197,174, 40,140,189,190,130,240, 53,145, 72, 36, 19, 29, 29, 29,187,199,197,197,221, 5, 48,131, 82, 90,169, 23, - 98, 15, 15,143,143,196, 98,241, 8,142,227,170, 51, 12, 19,197,178,236,206,152,152,152,237, 66, 85, 33, 64,128, 0, 1, 2,254, - 50,129,213,210,199,214,151, 80,221,116, 9,161,109,244,148, 92,161, 68,186,244,198,243,244,240,119,108,168,221, 1,180, 71,161, -175,161, 71, 0,206, 82, 74,211,141,228, 48, 5,208, 7,192,240,192,192,192,206,223,127,255, 61, 83,175, 94, 61,104, 52, 26, 4, - 5, 5, 5, 44, 93,186,116, 37, 33,228, 60,128, 93, 0,142, 84,228,219, 69,173, 86, 59, 20,107, 37, 66,136,195,192,129, 3,111, -151, 22, 85, 69,139,203, 18, 74,233, 13, 66,200,117,142,227,110,238,223,191, 63,182, 22, 33,205,199,122, 73, 15, 76,126,161,125, -203,231,145, 70,163,113, 56, 62,109, 2, 40,229,161, 78, 79, 67,235, 37,171, 74,206,157,234,214, 2, 34, 78, 15,153, 92, 26,220, -254,216,141,203, 0,130,139, 54,163,193, 48,204,194,211,167, 79, 59, 83, 74, 17, 24, 24,184, 16,192, 95, 34,176, 8, 33,242, 22, - 77, 26, 92, 58,246,199,110, 69, 94, 70, 50,186,245, 25,178,147, 16, 50,138, 82,250,199,107, 98,169, 7,113, 36, 98, 76,255,124, -209, 46, 6, 0,214,205, 25, 62, 99,101, 32, 89, 61,229, 12, 77, 34,132,116, 0, 74,150, 86,250,137, 82,122,105, 93, 15,226, 8, - 6, 51, 63, 95,180,139, 0,192,250, 57,195,167,175,235, 65, 86,141, 63,105,220, 44, 73, 66,200,248, 81,163, 70,173, 94,184,112, - 33,227,236,236,140,248,248,248,110,117,234,212,241, 37,132,212,169,104,112,176,151,151,215,222,246, 93,250,122,247, 31, 52, 84, -105,111,103,141,132,196, 52,139,189,187,127, 29,235,229,229,213,253,229,203,151, 67,132,234, 66,128, 0, 1, 2, 4,188, 55,129, -229,239,111,105,101,162,162,211, 76,164,116,104,183,230,117,188,122,119,105, 69,188,189,189, 17,254, 44,188,250,165,107,119, 70, -119,168,101,254, 82,165, 35,123, 84, 38,100,121,104,104,197,235,135,141,106, 68,244,122,174,240,153, 82, 49,184, 29, 15,153, 67, - 61,123,246,244,250,226,139, 47,208,178,101, 75,220,190,125,187,195,111,191,253, 54, 89, 44, 22,223,225, 56,238, 36,128, 32, 3, -156,199, 77,172, 81,163,198,210, 21, 43, 86,200, 59,116,232, 0,133, 66, 81,114, 78, 34,145,160,119,239,222,232,221,187, 55,147, -144,144, 16,120,236,216,177,192,159,126,250, 73, 75, 8,249,138, 82,186,198,144, 4,154, 59,119,110,147, 50, 14,159, 38,132, 68, -178, 44,123,191,126,253,250,177,126,132,212, 28,215,163,213,185,241,173,125, 76, 43,176, 78,225,206,194, 66,183, 37,165, 5, 22, - 45,200,133,196,194, 60, 88, 98,102,246,150,184,170, 77, 72,131, 22,214,162,223,183,100,112,245,141, 16, 89,136,141,141,133,165, -165,165, 73,251,246,237, 19, 9, 33,223, 94,186,116,105,211,123, 46, 55,205,191,157, 62, 94,154,249,234, 33,146,158,222,192,180, - 65, 1,202, 41,191, 28,253, 30,192, 31, 21,231,149, 72,244,211,117,126,214, 20, 96, 50,128,185,233,233,233,237, 0,192,214,214, - 86, 6,224,210,138, 91,232, 49,181, 53,169,178,155, 5, 66,136,148, 97,152,181,219,182,109,251,244,163,143, 62, 42, 92,226,225, -234, 85,152,153,153, 97,193,130, 5,213,190,252,242,203,197, 40,124,118,153,150,171,246, 93,250,122,175, 90,246,125,157,220,140, -108,205,198,181,251,238,184,248,251,137, 62,159,248,165,249, 42,157,198,201,195,195,227, 35,193,146, 37, 64,128, 0, 1, 2,222, -139,192,106, 83,211,244,118,191,198, 53, 26,247,238,220, 74,228,227, 87, 7, 82,133,178,228, 92,189,134,141, 80,175, 97, 35, 50, -102,116,174,247,131, 7, 15,190, 57, 29,124,107, 78,155,154,166, 33, 87, 34,242,155,149,199,167,231, 32,222,181,107, 23, 0,224, -231,175,134, 51, 57, 57, 57, 94, 74,229,159,156, 29, 59,118, 68,199,142, 29, 69,235,214,173,107,126,230,204,153,230, 91,182,108, -209, 17, 66, 86, 22,117,243,149,135, 57, 97, 97, 97,114,134, 97,192, 48,229,251, 50,117,113,113,193,192,129, 3,225,231,231, 39, -107,223,190,253, 28,252,185,108,197,107, 80, 40, 20, 41,132, 16, 7, 0,176,177,177,225,190,253,246,219,251,148,150,244, 0, 82, - 74,233, 13,145, 72,116,147,231,249, 91, 71,142, 28,137,171, 75,136, 67,175,198,126, 87,198,127, 56, 80, 73, 15,172, 44, 87, 28, -104,178, 50,202, 60, 46, 51, 85, 6,203, 76, 77, 47,203, 77, 76, 94, 19, 87,117, 9,113,107,225,231,117,118,221,212,225,230,134, -100,100,227,198,141,125, 59,116,232,160,224, 56, 14,249,249,249, 88,191,126,189,165,137,137,137,101,247,238,221,231, 3, 40, 17, - 88,117, 8,169, 55,192,133, 25,243,109, 60, 59,161, 10, 2,198,170, 77,203, 38,175,126, 89, 50,223,162, 73,139, 54,120,126,105, - 7, 50, 50,114,145,157,149, 7,158,231,223, 90,249,119,252, 73,154,188,174, 55, 89,186,110,246,240,153, 68, 36, 34, 13,250,205, -192, 7, 78,217,147, 8, 33,143, 1, 72,138, 23,106, 5, 32, 38,132,184,248,251,251, 47,173,217,181, 13,214,127,253, 33, 40,207, - 83, 0, 75, 13,181, 94, 17, 66, 28,204,205,205,143,156, 61,123,182,121,211,166, 77,113,243,230, 77,188,120,241, 2,227,199,143, -215, 78,152, 48, 65, 58,114,228, 72, 50,109,218,180, 47, 8, 33, 7, 40,165,215,222,122, 17,196,226, 17,125,250, 15,145,229,101, -229,168,181, 26,157,214,198,206,138,215,228,171, 11,210, 50,115,212, 67,134,127,166,125,124,239,214, 8, 0,111, 9,172,119, 73, - 79, 1, 2, 4, 8, 16, 96, 48,154, 2,176, 7,144, 10,224,206, 27,251, 40,250,143, 50,246,211, 80,216, 11,101, 91,138, 43, 13, -133,195,123,236, 81,232,163,243, 54,128,204,247, 30,226, 82,194,161,228,183,120,235,226, 43,167,148, 82,202,166, 71, 80,125,212, -121,170,123,184,253,237, 45,252, 24, 77, 14,249,131,222,222, 49,155, 22, 93, 95,238,136,250, 97,245, 64,105,216, 46, 74,195,118, -209,101,129,160,148,210, 16, 74,105,200,134, 97,206,218,101,129,160,203, 2, 65, 55, 12,115,214,242, 60, 31, 18, 31, 31, 31,114, -237,218,181, 16, 0,183, 42,153,201,144,156,123,231, 58,189,229, 0,154,145,145, 65, 53, 26, 13,125, 19,207,158, 61,163, 27, 54, -108,160,179,103,207,166,191,254,250, 43, 5,144, 92, 17,103, 96, 96, 96, 80,104,104, 40, 29, 57,114,228,125, 0, 38,229, 93, 87, - 27, 48, 29, 81,205,233,169,102,239, 74,157,246,163,122, 52,179,173,162,204,248, 59, 59, 59,191, 22,158,189,181,157,232,209,150, - 62,244, 92,215,198, 65,148,210,111, 41,165,237, 74, 95,223, 8,176,232,227,108, 27,161,222,183, 74,165, 29,211,130, 86, 54, 83, -161, 81,163, 70,190, 95,125,245, 85,134, 86,171,165, 47, 95,190,164, 27, 55,110,164,231,206,157,163,135, 15, 31,166, 1, 1, 1, - 9,165,194,235,248,177,159,103,178,118,203,119,154,170,204,136,144, 48,204,154, 59,231, 14,208,136, 43,251,233,237, 61,139,233, -206,111,134,209, 47,250, 52,215, 89,152,200,213, 0, 58,150,119,223,132,214,168,233, 87,205, 62, 60, 58, 58,154,234,116, 58, 58, -122,244,104, 26, 24, 24, 72,187,118,237, 74, 59,119,238, 76, 59,117,234, 68, 59,118,236, 72, 47, 94,188, 72, 19, 18, 18,104,231, - 54,141,243,123,213, 70, 19, 35,102,179,248,123,122,122, 38,189,124,249,146,234,116, 58,122,225,194, 5,186, 99,199, 14,122,225, -194, 5, 58,107,214, 44, 10, 96,235,231,159,127,174,202,204,204,164,129,129,129,113, 40, 90,193,160,244,230,233,233,249, 36, 52, - 60, 54,118,197,162,205, 23,183,173,217,125,241,224,129,115, 23,143,156,185,125,226,240,153, 59,251,110, 61,136, 58,236,233,233, -249,164,140,252,127,167,244, 20, 54, 97, 19, 54, 97, 19,182,215,234,242, 50,181, 72,209,214,179,232,120, 79, 74,105,231, 55,246, -123,226,207,241,208,175,237,207,154, 53,107,118,233,253,226,107,102,205,154, 53, 27, 0,109,217,178,229,110, 74,105,205,191, 34, - 62, 6,141,193,210,189, 8,130,172, 78,127,128,175, 11,154, 25, 9, 62, 39, 30, 84,233,128,124,222, 4,105, 9,209,120,122,101, - 63,168,174,114,191,119, 18, 6,236, 55, 19,134,139,173, 20,128,204,220, 94,151,155,155, 11, 83, 83, 83,228,103, 38, 74,191, 92, - 86, 98,217,146, 94,186,116, 9, 33, 33, 33,112,113,113, 49,168, 27,147,106, 11,123, 17,181, 90, 45,180, 90, 45,146,122, 52,131, -105,139,182,200,252,112, 2, 46, 92,184,128,148,148, 20, 72,165, 82,200,100, 50,176, 44, 91,105, 56, 69, 69,171,198, 22,103,116, - 89,215,180, 39, 68,236,102, 99,118,108,221,252,201, 94,162, 27,199, 37,170,152, 8, 36,168, 57, 88, 25,144,158,114, 51, 83,200, -148, 38,193, 50, 51,211,183,186, 5, 27, 19, 34, 49, 53, 83, 28,251,253,135,105, 78,204,189, 11, 10, 85,196, 67, 72,203,224,232, -210,165,203, 88, 0,243, 41,165, 89,237,219,183,119, 92,184,112,161,117,124,124, 60,194,194,194,176,111,223,190, 84,182, 48,162, -132, 82,250, 29, 0,180, 36, 68,225, 97,111,117,102,205,188,201,230,184,180, 87,134, 79,230, 25, 45,198, 45,107,247, 62, 49, 96, -228,231, 19, 86, 79,238,141,252, 92, 21,118,157,187,135,211, 33,145, 31, 0,184, 90,209,184,182, 53, 87,105, 4, 33,164, 83,255, -254,253,239, 95,190,124,217,110,203,150, 45, 96, 89,182,204,109,203,150, 45, 56,127, 37,100,146,161,139,233, 18, 66, 92,188,188, -188,206,223,186,117,203, 94,169, 84,226,220,185,115,200,202,202, 42,177, 92,141, 26, 53,138,100,101,101, 13, 93,191,126,253,128, - 87,175, 94, 45,187,114,229, 74, 58, 10,151,109, 98,223,232, 90,141,100, 89, 93, 45,231,218, 53,197,131,122,183,105,147,151,254, - 16,102,182,245,113,227, 65,228,177,172,204,116, 21,195, 48,145,165,175,127, 31,233, 41, 64,128, 0, 1, 2,140,238, 73, 57, 78, - 41,237, 69, 8, 57,254,230,177, 55,255, 23, 95,183,120,241,226,146,253,226,123,150, 44, 89,178,168,212,126,193, 95,217, 69,216, -158, 16, 66, 81, 56,216,252, 45,168, 31,236,132,230,209, 94, 72,171,119,128,172,238, 16, 72,220, 90, 34,246, 81, 16,238,159,252, - 25,113,143,175,130,242, 28, 28,171,213,174,244, 97, 91,239, 81, 9, 33, 36,132, 82,138,123,247,238, 33, 50, 50,242,181, 49, 83, -197,184,112,225, 2, 0,192,201,201,201,160, 72,200,154,180,130,251,131, 68,196, 54,112, 6, 0,184, 63, 72, 4, 0, 44,158, 51, - 7, 82,169, 20, 82,169,180,100, 81, 88, 67, 4, 86,209, 26, 90,224, 11,187,169,104, 89,231,155,200, 37,187,246,204,159,216, 76, -254,234,145, 76, 19,122, 3, 9, 26,158, 30, 75,230, 78, 24,178,162,177, 92,169, 12,150,153,153, 93,150,154,154,190, 38,174, 0, -128, 74, 36,219,119,124, 55,177,190,105,114,148,169,250,206, 5, 36,170,121,157, 69,217, 52,223,157, 58,117,202, 65, 44, 22, 59, -113, 28,135,152,152, 24, 60,126,252, 24,171, 86,173, 74,206,205,205,109, 31, 18, 18, 18, 94, 42,188,162,166, 38,178,125,219, 23, - 76,246, 22, 63, 12, 86,104, 34, 67,203, 20,109, 21,193,190, 94,191,192, 15,218, 55, 56, 49,246,195,175,209,183, 71, 87,140,108, - 95,135,190, 76,200, 80, 3, 56,103,200,194,210,148,210,120, 66, 72,151,182,109,219,238,108,216,176, 97,109, 74, 41,234,213,171, -135,161, 67,135, 98,251,246,237,120,240,224, 1,114,114,114,116,103,207,158, 93, 73, 41,253,205,192, 23, 77,105,109,109,125,250, -226,197,139,246, 74,165, 18,103,207,158,133, 74,165,130,179,179, 51, 38, 76,152, 32, 91,178,100,201,182,156,156,156, 65,139, 23, - 47, 86,188,124,249,114,205,153, 51,103,170, 1, 16, 81, 74,223, 42, 4, 90,173,118,211,174,237, 91, 87, 79,152,248,133,235,197, -155, 97, 23, 52,121,185,150,158,158,177, 57,246,214,102,230, 43,127,252,206, 67,171,213,142, 45, 59, 61,131,170,148,158, 2, 4, - 8, 16, 32,160, 44,219, 69,249, 90,164,180,104,122, 83,100, 25, 35,206, 0,168,102,205,154, 53,135, 16,114,124,214,172, 89,115, - 22, 47, 94,172, 2,144,240,151, 8,172, 34,247, 0,160,148, 6,151,211,133, 8,202,179,208, 70,156,131, 54,226, 28, 76, 59,124, -131, 35,139, 70,188,118, 29,199,233,171, 20, 0,181, 90, 13,169,153,173,238,231,175,134, 75, 1,128,151,152,234,138,207,241,188, - 65, 11,175,195,152, 37,189,140, 17, 88, 69,188,111,137, 7, 47,185, 89,240,166,169,131, 90,216,114, 5, 18,237,213, 99,136,215, -240,236,178, 8, 93,193,157, 44,250,211,156,114, 56,143,119,105, 6,125,102, 26, 20,230,166,193,221, 46,133,150, 57, 91,208, 75, - 97,113, 97,223,180, 97, 1, 78, 82, 72,181, 39,246, 35, 65,195,107, 54,188,210,255,182,170,156, 56, 83, 74,241,226,197, 11, 20, - 20, 20,224,250,245,235,248,227,143, 63, 82,223, 20, 87, 69,225, 13,250,117,198,136,230, 22,185, 73, 82,237,157,243, 72,208,240, - 26, 95, 67, 68, 85,253,126,173,165, 34,114,150,136, 24,147, 30,109,234, 96,202,103,253,176,226,215,163,172,214,161, 77,175,213, - 71, 78, 14,206,211,232,230, 24, 34,174, 74,133,249, 33,128, 58,132, 16, 57,128, 14, 67,135, 14, 61, 57, 96,192, 0, 4, 7, 7, -227,216,177, 99, 62, 0, 18,139,210,127, 1, 0, 71, 20,206, 46, 44,111, 37,119,145, 84, 42,221,115,254,252,249,186, 46, 46, 46, - 56,127,254, 60, 84, 42, 21, 62,255,252,115,237,196,137, 19,165,163, 70,141, 34,217,217,217, 37,150,171,235,215,175,167,151, 39, -174, 0, 32, 46, 46,238,148,167,167,103,171,182,109,219,246,243,246,241,179,136,202,205, 73, 81, 42, 21, 38, 87,130, 47, 73,239, -220,186,182, 38, 46, 46,238,118,217,233,121,193,224,244, 20, 32, 64,128, 0, 1, 21,182, 17,229,106,145, 55, 69, 86, 21,249,139, -239,147, 44, 94,188,248,241,226,197,139, 95,179,112,253, 85, 22, 44,163,192,101,188,221,230,113, 6, 8,151,242,208,114,230,153, -199, 38, 38, 38, 88,191,126, 61, 74, 15,122, 55, 84, 56, 21,156, 58,132,216,241,195, 75, 44, 87,197,150, 44,116, 27,245, 78, 2, -139,231,249,235, 0, 94, 83,121,166,142,126,195,246,124,216,165,117, 29,111, 87,145,126,223, 42,196, 21,176,234,249,207,116,234, -167,185,244,131,176, 50, 6, 79,151, 64,175,133,194,180,208,114, 85,150,184, 50,115,242, 29,176,109, 88,135,246, 13,252,106,136, -216,189,203, 17, 95,160,207,155,245, 68,167,139,202,167, 7,203, 41, 40,243,187,118,237, 58,223,214,214, 86,177,122,245,106, 75, - 79, 79, 79,176, 44,171,125, 83, 92,153, 58,250, 13,219, 59,170, 91,107, 95, 39,107,145,254,192, 47,136, 85,113, 5,171,162,244, -219, 54, 24, 32,174,236, 44,205,206,108, 88, 52,222, 68, 41,151, 64,173, 86, 99,201,186, 3, 56,123, 45,180, 87,234,163, 67,103, - 0,156,121,135,114,247,105,175, 94,189, 86, 44, 88,176, 0,122,189, 30,159,124,242, 9, 34, 35, 35,207, 62,123,246,108,149,135, -135,199, 87, 51,102,204,112,113,114,114,194,224,193,131,165, 0, 70,149,195,241,227,174, 93,187,122, 53,104,208, 0,193,193,193, -200,202,202,130,179,179, 51, 38, 78,156, 40, 91,188,120,241,182,156,156,156, 65,139, 22, 45, 82,188,120,241,162, 66,203,213,235, - 31, 9,220, 15, 27, 87,140,255,170,105,139, 0, 81, 68, 68, 56, 27,211,172,157,232,210,249, 99,151,109,109,109,183,189,150,158, -163,187, 27,157,158, 2, 4, 8, 16, 32,224,189,225, 4,128,158,111, 90,181,222, 20, 95,197, 22,170,210,251,111, 94, 95,116,254, - 47, 89,148, 92, 92, 42,128,196, 80,235, 16,151,155,244,214, 49,158, 51,216,144, 97,176,112,226, 12,228,228, 53,234,202, 4,147, - 81, 2,171,104, 12,214,105, 74,233,107, 2,203,202,201,175,221, 55, 51, 39,175, 12, 24,208, 77,148,252, 89, 75,100,229,105, 52, - 51,194, 88, 62,174,160, 18,113, 5, 64,196,233,130, 37, 22, 22,151,165,111,204, 22, 4, 0, 19,199,154,205,102, 77,253, 98, 93, -199, 97,189, 73,234,231, 1,200,204, 82,105,190,122,204,146,120, 21, 29, 20, 70,233,165,178,248, 46, 92,184,176, 17,192,198,246, -237,219, 39,155,154,154, 34, 47, 47,239,173,116, 45, 14,111,235, 1,221, 68,201,159, 54, 71, 70,190, 78, 51,227, 49,139, 4, 21, -191,167, 50,113,101,111,101,126,102,195,194,241,202,132,184, 87,144, 74,165, 48, 51, 51,195,185,171,143,144, 26,122,248, 93,132, - 21, 24,134,249,118,206,156, 57,243, 39, 76,152,128,244,244,116, 28, 59,118, 12, 61,122,244,192,238,221,187, 61, 79,158, 60,185, -162, 67,135, 14, 96, 24, 6,199,143, 31,135, 94,175,127, 94, 78,126,246, 27, 51,102,204, 87, 3, 6, 12,192,237,219,183,145,152, -152,248,154,229, 42, 43, 43,107,232,186,117,235, 6,188,124,249,178, 82,203,213, 27,104,230, 85,163,145,116,246,220,159,161, 41, - 72, 17,167,198,223, 12,190,112, 78,116, 35, 35, 35, 67, 9, 32,187,170,233, 41, 64,128, 0, 1, 2, 12,214, 7,229,205,198, 79, - 45, 18, 79,169,101,237,151, 18, 86,101,237,147, 55,172, 94,218, 55,206, 63,248,103, 44, 88, 60, 7,177,115,125,176,137, 15,255, - 60,148,255,186,192,146, 42,205,192,115,149,183, 95,163, 26, 17,253,215,109, 33, 94,222, 93, 4,169,153,173,174,229,204, 51,143, -203,187,214,204,204,204,208, 46, 66, 86,220,173, 31,106, 4,246, 69, 84, 61, 39, 80,189,174,196,146,133, 57,115, 94, 19, 89, 82, -169, 20,106,181, 26,120, 99,128,115, 25,184, 69, 8,121, 5,224, 6,165,148, 54,246,173,254,189,194,212,116,116,147,250, 53,236, -166,140,255, 84,242, 50, 69,131,139, 1,179,179, 14,252, 56,211, 44,150,154, 77,136,166, 89,215, 42, 41, 48,193, 61,174, 60,125, -203,114,213,200,183,250,215, 10,165,226,179, 22,254,190, 78,179,166,141,151,188, 76,214,144,139,205,102,228,252,241,211, 12,229, - 11,152,127, 21, 75, 51, 47, 25, 16,255,249, 61,122,244,152, 79, 41,165, 60,207,207, 5,128,210,225,157, 54,241, 51, 73, 84,146, - 26, 23, 2,190,206,252,227,199,153,230,177,168, 56,188,246,245,251,181,118,180,182, 56,179, 97,209, 4,101, 98,124, 52,228,114, - 57,204,205,205, 17,155,156, 13,137,152, 81,189, 75, 97, 35,132,200,219,181,107, 55,115,252,248,241,120,244,232, 17, 62,255,252, -243,196,152,152,152,131,123,247,238,253,124,222,188,121,226,192,192, 64, 36, 38, 38, 98,233,210,165,250,171, 87,175, 46, 2,176, -180,204, 66, 43, 22,127,250,253,247,223,211,132,132, 4,242,226,197, 11, 56, 59, 59,227,139, 47,190,144, 45, 90,180,168,100,204, -149, 49,150,171, 98,196,197,197, 5,251,212,240,192, 7,167, 86,130,213,107,130,179,210, 99, 46, 63,141,202, 12,182,145,201,190, - 12,104, 92,191, 74,233, 41, 64,128, 0, 1, 2,222, 11,238, 84,178,255, 63,135, 10, 5,150,158,138,178,119, 45, 25,103,249,193, -136,207, 97, 82,173, 45, 52,143,247,131,207, 77, 2,159, 91, 40, 96,100,166, 22, 48,183,115, 71, 94,129, 26, 87, 67,163,160,167, -162,236, 10,249, 56,136,127, 88,251,231,108, 65, 43, 43, 43,100,103,103,191,102,121, 81, 42,149,112,113,113, 65, 70, 70, 6, 54, -110,220, 8, 0,149, 53, 94,223, 54,109,218,116,205,162, 69,139,100,141,135,125,140,188,155, 87,222,180, 70,193,196,196, 4,114, -185, 28, 15, 31, 62,196,197,139, 23,181, 0,190,173, 68, 8,220, 98, 89,246,193,158, 61,123,226,124,170,187,117,107,223,180,217, -164, 57,179,103,153,135, 93, 57,139,185,139,214,240, 53,155, 4,102, 47,217,125, 56, 55,219,204,163, 83, 65,194,211,251, 6, 8, -139,183,157,136,122,123,116,108,217,168,225,244,185,115,191,182,120,124,229, 28,230,253,180,129,250, 52,232,156,253,211, 31, 71, -114,210,148,213,186,170,146,159,220, 54, 36, 3,131,130,130, 54, 2,216, 88,188,255,102,120,103, 45, 88,197,251, 54,237,150,185, -100,247, 31,249, 57,230, 30,157, 43, 10,175, 67,157,254,173,220,157,109,206,252,242,195, 56,101, 82,124, 12,228,114, 57,204,204, -204, 16,147,152,133,249, 43,247,229,235,120,190,219, 59,150, 55,185,185,185,185, 92,167,211, 97,237,218,181,136,137,137,105, 73, - 41,141, 33,132,108, 24, 50,100,200,234,122,245,234,213,122,252,248,241,243,188,188,188, 9,148,210,167,229,145, 88, 89, 89,181, -180,183,183, 39, 55,110,220,248, 63,246,174, 58, 60,170,227,237,158,185,235,155,221,184, 11, 65, 18,226, 64,112,119, 40, 45,238, -238, 45,210,226, 80, 8, 86, 92, 90, 40, 86,220,138,187,187, 75,139, 59, 33, 64, 66, 2,241, 16, 79, 54,217,172,223, 59,223, 31, -145,134, 52,178, 1,250,253, 42,123,158,231, 62,187,215,206,157, 59, 51,119,230,204, 59, 51,239, 96,212,168, 81,218,177, 99,199, - 10, 7, 15, 30, 76,210,211,211, 63,214,114, 5, 0,112,115,115,107,222,165, 67, 35, 52,110, 59,250,134, 86,157,113,243,221,171, -157, 55, 24,122, 75, 82,187,102,141,143,138, 79, 19, 76, 48,193, 4, 19,254,187, 40, 85, 96, 37,243, 85, 14, 27,119, 29, 89,182, -255,208,209,111, 70, 12,237, 47,105,209,102, 16,132, 41,207, 97,136,127, 4, 87,255, 38,160,124, 41,238, 63,124,140,103,225, 49, -234, 28, 29,111,139, 66,168,250,190,136,176,104, 67, 41,189, 92, 18,127,122,122, 58,170, 84,169,130,125,163,125, 2, 52,138, 36, -161, 59, 0, 38,206, 82,119,226, 97,211, 23,103,207,158,205,102, 89,118, 11,128, 67,165,113, 82, 74,183, 18, 66,206,245,234,213, -107,110,205,154, 53,135,205,157,187,148, 39,156, 48, 24,170,144,103, 48,107,209, 11, 54, 54, 54,120,251,246, 45, 46, 95,190,204, - 38, 39, 39,111, 7, 48,151, 82,154, 80, 6,231,221, 26, 53,106,196,186,187,187, 91, 57,200,165,219, 71, 15, 31,108, 30,245,236, - 46, 18, 67,159,226,214,239,161,233,123,143,156,136, 83,100, 38, 15, 47,173,114, 45,204,201, 48,204, 7,226,202,219,219, 78, 46, - 19, 91,239,250,110,196, 48,139,232,231,247,145, 20,250, 4,191,221, 10, 75,223,183,255, 88,114,106,106,226,208,146,196, 85, 89, -241, 89, 92,120,239,254,246, 58,125,255,161, 99,177, 89,202,244,175,139, 11,111, 97, 78,185, 76,240,253,137, 29, 11,205,226, 99, -163, 10,196, 85, 84, 66, 58,126, 88,181, 95,169,210,234,191, 76,126,118,204, 40, 75, 77,105,225,228, 56, 14,122,189, 62, 95, 84, - 43,242,226,251, 21,128,214,198,114,166,164,164, 92,143,140,140,236, 34,151,203, 11, 44, 87,153,153,153,189,150, 46, 93, 90, 46, -203, 85,209,112,198,198,198,222,240,172,226,246, 99, 66,159, 94, 26,103,103,251, 27,167,206, 61,120,238, 32,151,190,250,216,248, -252, 92, 48,113,154, 56, 77,156, 38,206,255, 2,231,127, 74, 96,133,132, 80, 29,128,241,254,254, 22,243,126,218,184,103,195,174, -125,135,187,141, 24,208,157, 95, 43,176, 53,222,222, 62,134,155,119,175, 26,210,213,244, 88,150,128, 55, 58,228,141,162, 76, 47, -168, 2, 30, 12,253,251,247,231, 3,128,136, 15,195,148, 58,117,174,215,170, 85,171, 73, 71,139, 36,225,156, 53,185,150,173,121, -227,250, 11, 79, 93, 59,117, 8,192, 38, 74,169,194,152,151,200, 19, 76, 35, 8, 33, 63,119,234,212,105,209,208, 6,181,186,143, -169,223, 28,122,189, 30,187,118,237, 66, 84, 84,212, 81, 0, 51, 41,165, 97,198,240, 61,127,254, 60, 37,160,106,165,241, 54, 82, -225,247,223,245,239,102,159, 28, 30,130,216,151,143, 1, 0, 26,141, 74,159, 16,122, 35,176, 60,145,156,191,112,179,191,191,191, -144,213,100, 15,145,240, 45,102,143,238,219,197, 33,245,221, 43,196,188,200,117,247,164, 81,231,232, 98, 66,175,250,126, 76, 34, - 86,170, 84, 73, 44, 19, 96,100,177,225,213,170,245,239,195, 94,214, 52,134, 39, 71,163, 93, 60,111,229,174, 47, 22,126, 63, 84, -108, 97, 97,129, 71,193,111, 48,123,197,190,114,137, 43, 35,210, 10,122,189,222,232, 25,162, 37, 96, 90, 96, 96,160,207,162, 69, -139,188,134, 12, 25,130, 79,181, 92, 21, 70,248,219,216,160, 22, 45, 90,248,191,121,253,168,165,141, 84,184,231, 83,226,211, 4, - 19, 76, 48,193, 4,147,192, 66,233, 66, 75,145, 14,160,119, 45, 55, 11,143, 69,107,247,108,145,242,185, 38, 42, 3,243,187, 74, -195,124,243, 56, 86, 17, 97,236,195,118, 60,166,130,194,251,219,115, 85,176,204,171, 58,178,243,143,189, 73, 3, 40,165, 63,125, -100,229, 29, 6,160, 7, 33,164,238,175,119, 31,207,202, 59,188,144, 82, 90,174,190, 90,115, 62,130,155,248,123,184, 54,173, 21, - 32,225,177, 42,196,190, 12, 71,154, 82,141, 75, 47,162, 50, 24,202,252,250,177,145,205,232,114,158, 54,245,247,116,111, 86, 59, -192, 76, 64,180,136, 13,121,132, 76,149, 22, 23, 95, 68,101,130,144,143, 30, 40,253,185,194,251,254,217,241, 7,246, 53,186,181, - 33,132, 92,158, 49,166,159,120,206,138,253,159, 85, 92, 1,200,137,139,139, 75,205,201,201,177,141,143,143,215,226, 35,157,187, - 81, 74,223, 16, 66,170, 79,152, 48, 97,254,148, 41, 83,190,255,241,199, 31,133, 31, 51,230,170, 36,164,199, 69, 29,107, 22,240, -249,211,223, 4, 19, 76, 48,193, 4,147,192, 42, 22,121, 98,170, 69, 11,127,123,217,239,175,147,149,159,201,162,161, 28, 82,139, - 20, 88,182, 4, 60, 24, 62, 3,231, 3, 0,157, 62,154,128, 33, 89,119,195,162,178,239,133, 69,101,131,163,148,163, 84,195, 48, -136, 81,234,116,139, 67, 35, 98, 63,126, 22, 29, 33,236,131, 55,209,170,135,225, 49,106,202,113,148,163, 84, 75, 8,222,235,245, -220,226,224,136,200, 19,127,135,240, 38, 63, 59,118,203,201,191,123,211, 91,247,130, 39, 41,149,186,181,201, 33,199,110,127,174, -204, 70, 41,213, 19, 66, 6, 52,108,216,112, 24,203,178, 27, 41,165,250, 79,224,210, 2,152, 70, 8, 57,250,252,249,243,131,183, -111,223, 78,248, 28,226,234, 47, 77,127, 19, 76, 48,193, 4, 19, 76, 2,171, 52, 92, 15,249, 60,226, 42, 31, 69, 45, 91,255,107, - 60, 15,123, 87,251,175,224, 13, 14,123, 87,237,159, 16,222,247, 33, 71, 31, 2,232,251, 87,132,149, 82,122, 17,192,197,207,200, -247,128, 16, 82, 25, 0,239,179,136,171,191, 48,253, 77, 48,193, 4, 19, 76, 48, 9, 44, 19, 76,248,199, 32,111,117, 80,131, 41, - 38, 76, 48,193, 4, 19, 76,248,187,128, 0,104, 83, 66,165,101,244,236, 0, 66, 72,155,143,168, 20, 47,155, 56, 77,156, 38, 78, - 19,167,137,211,196,105,226,252,111,113,254,151, 90,255,127,217, 6,160,141,137,211,196,105,226, 52,113,154, 56, 77,156, 38, 78, - 19,231,127,109, 99, 76, 18,211, 4, 19, 76, 48,193,132,191,172,155,132, 16,113,222, 2,239, 31,117,222, 4, 19,254,169,224,127, -196,199, 82, 53,207,242,245,230, 47,252, 32,199, 56, 59, 59,143,168, 81,163,134,159, 80, 40,100,178,178,178,230, 93,189,122,117, -110,209,235,154, 5, 8, 30,242, 24,184, 21,186, 19, 32, 60,128, 97,192, 82,196,222,124,154, 83,199,148,196,127,235,130,183,162, -212,194,254, 36, 97,120, 34,214,160, 3,171,215, 1,248,195,171, 63,199, 25,162, 12, 90,117,187,146,238,119,174,217,221,221,192, -210,165, 0,183,158,128, 25, 77,193,109, 32,148, 25, 77, 25,172, 39, 28, 70,129,175, 95, 6,131, 96, 10, 95,200,159, 25,255,232, - 80,204,191, 33,206, 14, 31, 62,204,251,148,251,123,246,236, 89,236, 2,159,174,174,174,167,205,204,204, 60, 75,186, 79,169, 84, - 38,196,199,199,183,252,151,231,199,102, 0,126, 1, 16, 80,228,212, 43, 0,227, 41,165, 87, 62,245, 25, 45, 8,225, 59, 2, 35, -133,192, 84, 0,208, 1, 63, 37, 2,155,174,127,166, 9, 26,159, 3, 14, 14, 14, 55,249,124,190,151, 82,169, 84, 42, 20, 10, 15, - 11, 11,139, 8,153, 76, 38, 51, 24, 12, 97, 73, 73, 73,205,202, 25,167,223, 34,111,201, 43, 66,200,247,148,210,245,229, 57,111, -130, 9,255,106,129, 69, 8,241, 6,208, 60,111,107, 86,183,110, 93, 71,165, 82, 9, 66, 72, 34,128,130, 37, 96, 40,165,161,159, - 35, 64, 60, 30,111,249,234,213,171, 39,143, 29, 59,182, 96,145,230,103,207,158, 21,127, 45, 3,183,107,167, 46, 59, 60,120, 30, -138,186,109,122,230, 9, 44, 6, 80, 38,160,101,219,122, 31, 91,200,154, 91, 91, 91,207, 35,132,244, 98, 24,166,204,202,140,227, - 56,150, 82,122, 40, 61, 61,125, 14,165, 52,171, 60,207,146,203, 36,122, 3,203, 22,251, 12, 62,143,199,102, 43,213, 37,206,174, -180,181,181,189,205, 48, 76,149,194, 11, 89,231,133,191,216,255,133,247, 13, 6, 67,108,114,114,114, 29, 99,226,130,225, 11,191, -103, 24,126, 27,202, 25,124, 1,128, 48,252, 87, 28,103,184,204, 25,116,203,202,251,190, 69,197,149,115, 5,143,223, 38,206, 92, -234, 22,252,242, 21,102,140,233,143, 31,127,217,129,233,227,135, 97,245,230,125, 24, 63,162, 31,252,253, 3, 74,229, 96, 41,153, - 55,123,252,128,150,139, 86,239,173, 59,115,124,127,217,162,213,123,235,206,156,208, 95,190,104,205,222, 58, 51, 39, 12,144, 47, - 92,179,167,206,172, 9, 3, 44, 22,173,217,171, 3, 48,252, 99,194,217,223,219, 85, 73, 12,134, 98, 91,215,148,207,215,236, 13, -141,147,253, 47, 62,220, 33, 67,134,212, 80,169, 84,143,250,183,173,181,180,166,183,107, 92,113,215,164,190,143,115,141,120,253, - 56, 72, 32,148,214,238, 18,180,227, 89,105,124, 98,177,184,202,171, 87,175,188, 56,142, 3,203,178, 48, 24, 12, 5,191, 90,173, - 22,205,154, 53,251, 44, 19, 98, 8, 33,157, 0,204,203,253, 88,177,132, 82,122,240, 19,184,228,124, 62,127,162, 72, 36,106,110, - 48, 24,252, 0, 64, 32, 16,188,212,104, 52, 55, 12, 6,195, 74, 74,105,118, 57, 41, 87,197,197,197,249,203,229,114,232,116,186, -130,133,225,121, 60,158,175,187,187,251, 58, 0, 94,159,250,254,142,192,200, 70, 77,154,172, 30, 60,121, 50, 79,117,243, 38, 86, -111,223,190, 10, 10, 5, 0,172, 43,235, 94,177, 88,124,129, 97,152,138,229,121, 30,199,113, 81, 26,141,166, 93,185, 42, 5, 62, -223, 43, 62, 62,222,193,197,197, 5, 0, 32,147,201,100,133,247,203, 99,185, 2,176,140, 82, 42, 5, 0,134, 97, 86, 55,106,212, -168, 33, 33,196, 0,128,114, 28,199, 16, 66,250,113, 28,199,207,187,126, 25, 33,100, 59,165, 84, 99,170,154, 77,248, 87, 11, 44, - 66,200, 89, 0,205,235,214,173, 43,237,219,183, 47,154, 55,111, 14, 47, 47, 47, 72, 36,146,220,194, 59, 53,213,241,201,147, 39, -189,111,222,188,217,251,212,169, 83, 32,132,168, 0,252, 78, 41, 45,246, 99,110,211,169,233, 88,137, 92,188, 6, 0,146, 99, 83, - 19, 98,223, 38,173, 73, 72, 72, 88, 70, 41,229, 10, 61,211, 99,240,224,193,147,198,141, 27,135,211,167, 79, 99,223,190,125,208, -104, 52,200,202,202,194,213,171, 87,139, 15,104, 78, 18,210,175, 46, 5,100,239,128,232, 27,128,153, 3, 32,115,252,232, 8,177, -182,182,158, 55,126,252,248, 9,254,254,254, 5, 94,199,245,122, 61, 12, 6, 3,244,122, 61,210,211,211, 49,105,210, 36,228, 89, -241,192,113, 28,206,157, 59, 55,118,196,136, 17, 0, 48,177, 56,206,134,117,220, 31, 50,132,113,203,183,205, 80,150,141,189,243, - 56,166,142,129,101,121,106,181,174,216,149,195, 37, 18, 97,169,226, 78, 32, 16,184,133,156, 60,233,192,136, 68,160, 44, 11,112, - 28, 40,199, 1, 40,180,209,220, 99,148,229, 64,245, 44, 56, 3, 7,131, 74,131,122,223,126,107, 76,225,216, 82, 32,146,236, 27, - 62,122,146,117,131,134, 13, 5,110,174, 46,208, 27, 88,132, 71,188,171,119,255,238,157,154,135,118,111,250,134, 16,210,143, 82, -122,237, 99,226, 89,100,102,113,113,237,134, 45,110, 15,158, 4,227,202,181,155,184,124,245, 6, 0,224,194,181, 92,183, 91, 12, -195,148, 21, 62,107, 91,175,150, 53,198, 14,235, 42, 91,248,243, 86,241,216, 97, 93,249,127,252,110, 17,143, 29,214,133,191,104, -229, 22,241,216, 97, 93, 4, 11,126, 90, 91,147, 16, 98, 77, 41, 45,113,181,129,146,210,136, 24, 12,226, 61, 17,137, 60, 0, 72, -222,184, 17,250,164, 36,184,204,153, 3, 0, 24,224,225,104,116,183,134,189,189,253, 67,129, 64,224, 86,214,117,122,189,190, 76, -241, 59,100,200,144, 64,149, 74,245,208, 96, 48, 80, 62,159, 31,212,191,219, 23,199,191,108, 26,152, 90,248,154,103,207,158,218, - 46, 94,124,178,235,193, 71, 89,180,119,109,243, 71,167,151, 15,169,211,113,202,142,167,165, 84,196,140, 70,163, 65, 88, 88,216, - 7,107,131, 22,214,179, 31, 41,130, 24, 0,171,109,109,109,235,167,166,166, 14, 0, 48, 67,161, 80,212,224,241,120,176,177,177, -153, 65, 8, 9,183,180,180,220,154,153,153,121, 59,207, 74,196, 25,201,219,204,194,194, 98,215,177, 99,199,172,107,213,170,197, -164,164,164,160,114,229,202, 72, 75, 75,171,119,243,230,205,218,195,135, 15, 31, 78, 8, 25, 68, 41,189, 89,142,224,250,152,153, -153,209,193,131, 7, 19,150,253,227,117,183,109,219,134,118,213, 12,158,163,190,148,229,168,181, 52,243, 74,152,229, 40,161, 80, -248,123,100,100,100,102,121,227, 67, 8, 76, 29, 60,121, 50, 79, 30, 25, 9,249,211,167, 24,160, 80,240,127,204,181,102,149, 41, -176, 24,134,169,184,107,223,175, 94, 34,145, 8, 6,131,161, 64, 4,230,151, 81,122,189, 30, 58,157, 14,122,189, 30, 44,203, 66, -175,211, 99,201,194,159, 62,186, 44, 52, 51, 51, 51,115,113,113, 73, 52, 51, 51, 51,251, 28,149,141, 88, 44,230,239,220,185,179, -159, 72, 36, 2, 0,104,181, 90, 84,171, 86,141,152,170, 97, 19,254,139, 22,172,175, 20, 10, 5, 88,150,133,185,185, 57,120, 60, - 94, 81, 11, 10,218,182,109,139,102,205,154,161,111,223,190, 8, 9, 9,145,246,237,219,183,109,137,150,128,201, 29, 81,193,203, - 49,175, 18,225,156,111,157,121,178,116,219,130,195,246, 0, 38, 23,186,108,248,200,145, 35, 73,106,106, 42,122,245,234,117, 83, -163,209,116, 46,109,185, 28,150, 67,108,203,190, 3,192, 81, 34, 93,121,111, 11,209,170, 85,148, 97, 24, 85,126, 23,225, 71, 86, - 8,189, 92, 92, 92,176,127,255,126,104,181,218, 63,157,183,176,176,192,139, 23, 47, 10, 91,220,208,160, 65, 3, 30, 33,164, 87, - 73, 2,139, 16,198,237,214,131, 72,135,252,253,142,109, 3,132, 13,235, 84, 76,180,183, 53,167, 0,200,204,153, 51, 11, 4, 27, - 0,204,155, 55,207,152,112,130, 17, 8,144,124,227,198, 31, 5, 48,159, 1, 35, 36, 32, 2,128,225,231,246,150,130, 2,148, 5, - 56, 3,192,233, 1,137,115, 5, 99,184, 91, 84,168,232,113,124,249, 47,155,205,181, 6,224,204,213,251,136,142,191, 2, 74, 41, -156, 29,108,208,168,110, 99, 65,173,186,245, 29,126,154, 55,237, 56, 33,164, 11,165,244,122,185, 35,154,163, 18, 79,119, 59,108, -221,246, 8,246,214,114,244,234,218, 30, 82,137, 24, 63,254,242, 43, 22, 78, 31, 3, 47,143,138,216,180,106, 81,137,183, 91, 90, - 90,206,175, 85,221,215,227,215,131,231,209,188, 89, 35,254,142,131, 23,208,162, 89, 99,254,175, 7,207,163, 69,243,166,252, 29, - 7,207,163, 69,179, 38,130, 29, 7,207,163, 65,157,234,158,183, 83,159,205, 7, 48,166,228,119, 46,146, 70, 95,228,166,145, 23, - 95, 88, 80, 1, 68,142, 30, 13, 0, 5, 2,171, 60, 16, 8, 4,110,241,241,241, 14,101, 93, 87,150,149, 32,207,114,245,208, 96, - 48, 32, 41, 41,137,100,100,100, 80, 43, 43,171,174,231, 55,205, 56,214,174, 73, 96, 26, 0, 60,125,250,212,102,201,146,197, 93, - 15, 60, 84, 64,117,119, 45,217,115,242, 6, 55,160,115,243,135, 39,150, 14,169,221,179,103,207,199,197,241,106, 52,154,119, 53, -107,214,164,121,255, 93,197, 98,177,176, 72,158,112,241,242,242,250,147,149,218,136,174,195,213,119,238,220, 25,227,239,239, 15, - 95, 95,223,219,245,235,215,183,144,201,100, 56,127,254, 60,252,252,252, 2, 44, 44, 44,238, 29, 58,116, 72, 48,109,218,180,192, -237,219,183, 3,192, 88, 35,242,103,155,150, 45, 91,238, 63,125,250,180, 68, 40, 20, 66,165, 82,225,197,139, 23,176,180,180,132, - 72, 36, 66,151, 46, 93,120,141, 27, 55,182,109,209,162,197,145,188, 70,128,209, 51,154,212,106, 53,157, 49, 99, 6,204,204,204, - 96,102,102, 6,153, 76, 6,153, 76, 6,185, 4,100,227,120,119,233,184,205, 25,210,137,115, 54, 46,221,181,126,238, 53,119,119, -247, 31,162,163,163, 51,202,155, 23, 84, 55,111, 66,254,244, 41, 80,232,219, 53, 22,150, 50, 27, 4, 5, 5,149,101,129,130, 80, - 40, 68,163, 70,141,202,228,179,181,181, 61,202,231,243, 63,104,145, 82, 74, 37, 65, 65, 65,108,104,104,168,140, 97, 24, 25,199, -113, 8, 10, 10, 98, 13, 6,131,196,209,209,241, 54,199,113,137,201,201,201,221,203,226,166,148,106, 8, 33,223, 51, 12,179, 90, - 44, 22,243, 43, 85,170, 20, 53,123,246,236, 59,121,214, 75, 80, 74,153, 74,149, 42,213,147, 74,165, 21, 53, 26,141, 1,192,247, - 38,235,149, 9,165,160,118,174, 17,184, 0, 90, 0,162,124,131,125,110,109, 7,187, 34,199, 1, 32, 37,175,129,232, 88,194,126, - 42,128, 16, 0, 62, 0, 28,242,206, 61, 0,144,246, 89, 4, 22, 33,132, 22,250, 40, 10, 42, 20,115,115,115, 60,120,240, 0,132, - 16,152,155,155,195,194,194, 2,150,150,150, 80, 40, 20, 8, 9, 9,193,171, 87,175, 16, 25, 25, 9, 66, 8, 60, 60, 60,144,255, -225, 20,226, 42, 40,216,246,254,124, 26, 18,185, 24,132, 0,181, 90,213, 64,141,102,213, 80,247,126,196,120, 23, 23,151,205,241, -241,241, 97,132, 16,126,181,106,213,134, 55,104,208, 0, 43, 86,172,128, 70,163, 89, 81,156,184, 42,204,121,243,133,190, 78, 94, -165, 52,101,247,249,112,179,129, 95,122,230,196,199,199, 47, 47,111, 36, 20, 45,128, 83, 82, 82,140, 94, 43,143,227, 56,164,167, -167,151,202, 89,212, 34,176,114,245, 90,171,172,204, 68, 44,248,113, 55,244,122, 61, 38, 79,158, 12,142,227, 10,182,140,140, 12, -163,194, 73,217, 34, 70, 5, 38,119, 35, 12, 64,248,128,123,159, 92, 61, 17,189,127, 45, 8, 5, 8, 11,160,200,123, 21,229, 36, -132,200,248, 66,241,190, 37, 43,214,155, 7,135,197,225,244,213,251,160,148,226,196,230, 31, 0, 0, 93, 70,204, 71,220,251, 20, - 52,174,237,139,201,179, 22,154,207,152,240,205, 62, 66,136, 39,165, 84, 89, 18,103,241,239,194, 98,193,252,249,216,188,102, 5, -126, 90,177, 6,138,204, 12, 8, 4,118, 0, 0,131,129, 5, 91,228,221,254,244,238,148,126, 57,107,202, 72,178,122,203, 17, 84, -171,234,132, 83,151,110,163, 78, 64, 69,156,187,122, 31, 13,170, 87,198,133, 27,143,208,160, 70, 21,220,184,251, 2,147,191, 27, - 76,110,157,219,241,101,121,210,104,213,170,181, 86, 89,138, 68,156, 94,180, 19, 73,235,214, 33,106,204, 24,212,203,187,230, 62, - 33, 16,186,185, 1,194,178,211,168, 40, 94,190,124, 9,141, 70, 83, 92,235, 30,126,126,126,101,166,187, 74,165,122,100, 48, 24, -104, 98, 98, 34, 73, 76, 76,132, 76, 38, 35, 47, 94, 4,179, 1, 1,213,186,209, 87,135,183, 0,192,146, 37,139,187, 29,124,164, - 64,206,237, 53, 80,221,249, 5,194,202,207,152,205,243, 70,234, 70,204,217,244,168, 80,229,246, 65, 56, 19, 18, 18,190,202,255, -239,225,225,241, 42, 52, 52,212, 39,191, 75, 57,175,171, 80,104, 48, 24,188,242,187, 13, 13, 6, 3, 52, 26, 13,218,180,105,195, - 43,237,221,173,173,173, 27,248,249,249,225,241,227,199, 88,179,102,141, 77,203,150, 45,241,230,205, 27, 16, 66,176,120,241, 98, -226,239,239, 47, 72, 73, 73, 65,187,118,237,112,244,232,209, 70,101,197, 39, 33,196, 92, 38,147,109, 63,117,234,148,132, 97, 24, -100,101,101,129,227, 56, 52,110,220, 24, 12,195, 32, 56, 56, 24, 51,103,206,196,209,163, 71,113,252,248,113,105,237,218,181,183, - 19, 66,252, 10,119,103,151,146, 70, 84,173, 86, 83,177, 88, 12,177, 88, 12,137, 68, 2,137, 68, 2,145, 72,132,108, 53, 48, 98, -101,148,134, 39,177,227, 2,106, 54,241, 28, 58,110, 49,179,124,246,176,171, 0, 78, 24,155,231,129,220, 49, 87,171,127,253,117, -205,128,204, 76, 6, 0,182, 18,194,233, 74, 88, 26,172, 56,206,108,117, 38, 42,122,184,225,200,129,227,232,209,167,107,177,226, - 74, 32, 16, 66, 40, 16,192,194, 70, 86, 38,167, 80, 40,116,124,245,234,149,173, 64, 32, 40,176,200,235,245,250,196,217,179,103, -219,119,232,208,193,252,220,185,115, 76,135, 14, 29, 56, 59, 59, 59,229,227,199,143,147,116, 58,157,109,227,198,141,141,206,243, -148,210,245, 53,107,214,172,117,236,216,177, 97, 65, 65, 65, 15,167, 76,153,178,160,240,249,101,203,150,205, 63,123,246,108,197, -110,221,186,237,122,242,228,201,250,242,148, 33,159, 90,206,155, 56,255,126,156, 37,105,145, 60, 56, 18, 66, 78, 23, 58,223, 49, -127, 63, 40, 40,104,198,146, 37, 75, 94, 16, 66, 78, 23, 62,158,127, 93, 30,247,233,226,246,243,238,181,153, 62,125,122,181,165, - 75,151, 46,110,216,176,225,254,219,183,111,191,253,108, 2, 43,255, 69, 10,191, 92,145,136,132, 66,161,128, 66,161, 64, 76, 76, - 12, 54,110,220,152,247, 33, 11,192,231,243,193,231,243, 11,198, 43,148,132,203,167,126,251, 5,192, 47,181,107,215, 22, 60,191, -115,232,220,212,205,227, 90,215,105, 83,139,247,232,202,243,158, 0, 22, 2,248,106,240,224,193,118, 0,176,115,231,206, 20, 0, -231,254, 23, 18,153, 82,122, 40, 44, 44,108,130,179,179,115,193, 24,148,194,221,132, 6,131, 1, 18,137, 4,249, 99, 85,212,106, - 53, 54,110,220,104,160,148, 30, 42,133, 19,161, 47,174, 34,236,197,181,220,251, 56, 14, 28,251,199,253,115,231,206, 45, 60,245, - 21,163,243, 44, 37,101,138,187,226,226,156, 22,249, 45,114,252, 79,162,172,104, 55, 4, 95, 56,185,255,176,111,109, 56,194, 47, - 16, 87,185,239,144, 43,204, 68, 66, 62,164, 98, 33, 66, 35,162, 81,201,181, 54,186,246, 30,100,125,108,255,175,147,145, 59,174, -166, 92,240,173,209, 16,227, 39, 76,192,150,205,155, 49,115,206,252, 2,117,110, 96, 89, 24,202, 10, 39,195, 48,141,235,248, 35, - 59, 53, 22, 60, 30, 15,141,106,122,130,199,227,161,105, 29,111,240,120, 60, 52,169,235, 3, 62,159,143, 22, 13,252, 81,181,106, - 85,240,249,124,166,140,116, 71,232,139, 43, 8,123,113,189,144,216,165,160, 0,116, 9, 9,127,186, 94,159,144, 0,234,110, 91, -222,188,133,225,195,135,103,196,196,196,232,138,158,171, 80,161,130,240,230,205,155, 86, 37,116,207, 21, 64, 42,149,214,230,243, -249,143,210,210,210, 56, 51, 51, 51,134,227, 88, 46, 32,160, 26,239,252,166, 25,199,242,175,153, 62,125,198,177,222,181, 45,186, -237, 62,116,154, 10, 43, 53, 33, 68, 32, 54,124, 51,103,147, 80, 32,148, 26,229,161, 62,191,187,240,245,235,215, 40, 43, 60,197, - 20,130, 31, 32, 61, 61,125,176,159,159,223,205, 95,126,249,197,134, 16,130,223,126,251, 13, 60, 30,175, 96,139,136,136, 0,195, - 48,152, 58,117,170, 78,161, 80,124, 93,102,129,197,231, 79, 56,114,228,136,165, 72, 36, 66, 86, 86, 86,193,119,195,227,241,240, -234,213, 43, 44, 95,190, 28,131, 7, 15, 70,116,116, 52, 92, 92, 92, 48,121,242,100,249,210,165, 75, 39, 0,152,111,196,171, 63, -211,106,181,117,204,204,204, 32,145, 72,144, 47,180, 0,224,226, 11, 65,112, 78, 78, 78,117, 59, 59, 59, 39,251, 27,167, 79, 54, -106,217, 57,208,214,222,185, 97,190,192, 50, 22,225,192,230,119, 44, 59,235,171, 99,199, 28,110, 29, 59,198,221, 61,117, 42, 86, -156,149,181,201,232, 60,164,103, 16, 21, 17,139,218,181,107,227,209,163, 71,168, 93,187,118, 97,177, 4,145, 72, 4,161, 80, 8, -161, 80, 8, 59,107,163,134, 74, 80,134, 97,112,235,214,135,203,141, 54,109,218, 52,237,218,181,107,114, 0,136,138,138,162, 29, - 59,118,204, 8, 9, 9,129,151, 87,233,195,208,156,156,156,110,242,120,188, 74, 69,190, 85,235,238,221,187, 35, 61, 61,189,125, -247,238,221,155,228, 29,139, 59,124,248,240, 64, 0, 16,137, 68, 96, 24,134,133, 9,255,121,148,165, 69, 10, 11,164,162, 66,107, -201,146, 37, 29,139, 30, 43, 44,166,138,251, 95,248,222,165, 75,151, 46, 46,196,173,250, 28,239,195, 47,172, 28,203, 42, 44, 75, - 67, 89, 2, 43, 31,143, 30, 61,210,187,186,186,110, 9,123, 18,217,218,179,134, 7,164, 50,241, 23,132,144, 95,196, 98,241,164, - 65,131, 6,225,238,221,187, 8, 14, 14,222,246,169,203,158, 84,175, 94,253,130, 88, 44,174, 88, 66,119, 72,212,243,231,207,219, -149, 80, 33,204,201, 27, 83, 86,226, 32,247,194,227,193, 10, 15,114, 47, 49, 67,112, 20,122,157, 30,202, 28,213, 31,149,119,158, -192, 82, 42,149,232,211,167,207, 7, 22,172,164,164, 36, 99,148, 62,246, 63,124,136,187, 23, 47,162,129,187, 59,110, 68, 68, 96, - 84,211, 70,168,228, 96, 3,202, 18, 80, 2, 68,239, 91, 11,133, 74,131,139,207, 66,161, 80,105,241,133,143, 15,220, 45,236,202, - 16, 46,252,118,245,234, 53, 18, 92,189,253,236,131,202,181,235,200,133, 16, 11,249, 48, 19, 11, 33, 17, 11, 32, 21, 11, 17, 19, -151,136,154,181,234, 10, 79, 29,221,215,238, 99, 4, 86,133,138,149,193,178, 44, 6, 15, 30,140,253,251,247,195,214,169, 34, 44, - 43, 84,195,194, 21,155,209,190, 77,211, 50,223, 63,191,197,206,231,243,193,227,241,254,244,155,255,223, 24,107, 36,229, 40,116, - 69,211,136,163, 0,165,112, 91,180, 8,110,139, 22,225,126,222, 51,253,149, 74,168, 84, 42,160,126, 64,185,196,149, 86,171, 69, - 76, 76,140, 46, 33, 33,193,177,152,138, 41, 81,171,213,150, 41,104,118,236,216,241,108,200,144, 33,117,108,108,108, 30, 62,123, -250, 84, 95, 35, 48, 80,112,110,227,140,227,249,221,131, 0, 16, 24, 24,152, 54, 99,198,140,227, 3,123,117,236,186, 62,168, 47, -251,237,252, 93,124,177, 84, 90,167,227,148,210, 7,186, 23,250, 62,222,213,168, 81,131, 26,115,109, 78, 78,206,251, 82,210,168, - 19,128,121,181,106,213,178,104,217,178, 37,110,222,188,137, 30, 61,122,104,116, 58, 93, 24, 0,116,232,208,193,123,239,222,189, -162,144,144, 16,216,219,219, 11,162,162,162,182, 19, 66, 74, 29,248, 46, 18,137, 90,212,173, 91,151,209,104, 52,127, 18, 87, 75, -151, 46, 69,191,126,253,224,237,237, 13,142,227,144,157,157,141,150, 45, 91, 10,214,172, 89,211,194, 72,129, 53,222,215,215,119, - 57,114,103, 17, 22, 46, 11, 95, 2,248, 62,207,186,253,190, 99,143,193, 47,154,182,233, 94,167, 82,213,106,206,101, 17, 58, 58, - 58, 78,103, 24,166, 55,199,113, 60,133, 66, 17,163, 37,164,170,127,197,138,142,141,187,118, 69,166, 64,192, 91,125,229, 10,147, -152,149, 37, 7, 96, 84, 87,163, 90,175, 68, 69,143,220,161,124, 61,250,116,197,163, 71,143,208,179,111, 55, 8,133, 66,240,249, - 2, 8, 5, 2, 8,132,185, 22, 44, 43, 59, 11,163,242,166, 94,175,255, 83, 94,165,148,194,194,194,162,160, 39, 35,255,152, 94, -175, 47,181,242, 3,224,117,105,193,108, 7,161,133, 37, 56,131, 30,238,157,123, 22,228,233,176,237,235,165,224, 56,105,118,244, - 59,244,217,127,234,111,181, 60,154, 9,127, 31,148,165, 69, 10, 11,164,207,240,172,211, 65, 65, 65, 51, 0,208,160,160,160, 25, -249,251, 75,150, 44, 81, 1,136,251, 44, 2,235, 83,197, 85,126, 55, 66,105,104,213,170,213, 88,115,115,243, 53, 0, 80,167, 78, - 29,196,220,141, 67,204,221, 56,248,249, 4, 52,174, 21, 88, 39,179, 95,191,126,176,181,181,197,148, 41, 83, 40,128,109,229,125, -126, 68,232, 11, 57, 0,234,226,226, 50, 5, 0, 92, 92, 92, 2,239,223,191,111,255,224,193, 3,212,173, 91,247, 15, 19,189, 78, -135, 38, 77,154,148, 86, 17,102, 33,119, 44,213,196,207,167,202, 57,232,116, 58,228,228,168,160,213,234, 96,208,115, 48, 24, 12, -168, 29, 96,142, 93,155,131,114,143, 25,242,173,101,185, 86, 50, 55, 39,115,212,174,238,164,103, 24,162,122,240, 52,193,162,164, -130, 49, 60, 37, 5,111,146,147,115, 45, 23, 39,207,148, 26,142, 11,193,175, 81,165, 74,149,210,173, 23,172,222,199,197,197, 9, -209,151, 30, 0, 0,228,102, 18, 92,216,185, 0, 50,179,220,201, 13,237, 7,207,128, 84, 44,132, 84, 44,128, 78,167,131,179,115, - 37, 24,116, 58,159,146,248,100, 54,206, 23,248, 66, 73, 69,202,114,160,148, 3,229, 88, 80,202, 65,108,110,107, 54,118,244, 48, -112, 28,139,122,245,234,129,240,120, 96,245, 26,244,234,212, 22,233,153, 89,176,181, 50,174,114, 16, 10,133,104,222,188,185,180, -164,243,111,222,188, 81, 21, 22,100,165,167,145, 30, 74,165, 10, 26,141, 6, 58,173, 1, 58,189, 1,108, 21, 33, 22,204,234, 15, -131,206,128,156,190, 13,161,211, 27,192, 77,232, 6,157, 86,143,104, 51,134, 9,244,183,215, 51, 32,170,199, 33, 73, 22,101, 9, -172,124, 81, 80, 18,138, 27,243, 87,130,200,122, 58,100,200,144,218, 53, 2, 3, 31,245,110, 19,248,243,243,224, 23,241,207,131, - 95,252,233,186,138,222,129,239,190, 93,186,127,178, 64, 40,173,109,172,184, 2, 62,236, 46,252, 68,204,200,202,202,170, 33,151, -203, 17, 26, 26, 10, 30,143, 7, 66,200, 27, 74,105, 13, 0, 24, 57,114,100, 56,159,207,247,224,241,120, 88,183,110, 29,225,243, -249,213, 27, 54,108, 56, 3,192,193, 82, 26,114,126,230,230,230, 31, 88,175,132, 66, 33,130,130,130, 48,112,224,192, 2,113, 37, - 20, 10,177, 99,199, 14,212,169, 83, 7, 90,173,214,207, 72, 17,252, 0, 64, 83, 35, 44,124, 36, 79,148,151, 41, 66, 13, 6,195, -144,212,222,189,171,226,198, 13, 52,246,240,240,175, 93,187, 54,116,186, 63, 12,152, 30, 30, 30, 21,178,178,178,222, 19, 66,246, - 0, 88, 79, 41,125, 82,170, 24, 82,115,136,138,136,205,111,172,162, 94,189,122, 5, 22,171,194,214, 43,161, 80, 8,169, 72, 94, -110,129, 69, 41,133, 82,169,100,206,159, 63,111,231,231,231, 71, 0,192,223,223,159,220,189,123,215, 70, 42,149,166,184,184,184, -148,217,240, 21, 90, 88,226,242,240, 62, 0,128, 94,173,190, 44,104, 16, 61, 92, 48, 3,124,129, 0,129,147,102,252, 41,223,115, - 28,199,131, 9, 38,113,101,132, 22,249, 92,226,170,168, 5,107,201,146, 37, 47,150, 44, 89,242, 39,107,216,103,179, 96, 25, 99, -242, 55,182, 21, 84, 20, 43, 86,172, 64,245,234,213, 75,173,128,214,172, 89,131,221,187,119,175,160,148, 70,148,247,249, 29, 91, -215, 10,192,202, 99, 47, 60,188, 3, 8, 0,204,159,208,137, 81, 42,149,184,117,235, 22, 44, 45, 45,241,230,205, 27, 99, 19,216, -220,210,210,114, 30,195, 48,189,120, 69, 71,246, 23, 47, 44, 89,142,227, 14,101,102,102,150,232,166,129, 82, 64,167, 55, 64,153, -163,134, 86,171,197,132,169,107,203, 12,199, 18,128,232,180, 89,252,230,205, 26, 74, 75,178,224,248, 85,240, 65,207,102, 93,255, - 84,105, 51, 12,114,199,186, 53,201,157,140,246,248,247,135,160, 52,119,248,149,149,173, 21,238,222,190, 93,234,179,181, 58, 3, -242, 41,179,115,212,104,213,127, 58,238,159, 88, 5, 0,185,226, 74, 34,128, 84, 36,132, 84,196, 7, 67,242, 92, 99,148, 84,216, -138,164, 21,211, 19, 34,188, 54,159,126,142, 17, 29,171,227,240,229,103,232,217,166, 6,174,221, 11, 65,203,250,254,120, 17, 22, -137, 0,175, 74, 88,183,253, 16, 40, 69,214,134,149, 11,223,255, 81,145, 25,162,140,177, 96,221,189,123, 87, 85,212,106, 85,248, -151,150, 93, 15,130,210, 63, 44, 88, 42,181, 6, 83,166, 27,229,142, 39, 55,141,154, 54,144, 26,115,113,105, 22, 42, 99, 4, 88, - 81, 75, 22,202,112,179, 82, 5, 64, 29, 96,218,255,178,192,100, 89, 22,103,206,156, 41, 72,143,226,210,177,112,218, 25, 33,110, - 16, 21, 21,133, 23, 47, 94,160, 65,131, 6,200,204,204,132,128, 97, 48,249,249,115,248, 15, 26, 4,173, 80, 8,142,227, 32, 18, -137, 48,114,228, 72,163,227,179,156,165,114,222, 56, 54,150,150, 81,150,252,220,177, 99,199,170,161, 74, 37, 94,188,122,133, 54, -115,231, 2, 0,206,158, 61,251, 65,158,152, 52,105,146, 40, 36, 36,100,248,195,135, 15,135, 19, 66, 86, 80, 74, 39,151, 88,206, - 82, 77,193, 24,172,222,253,123,160,170,111, 21,236,254,117, 95,193,249, 73,223,143,135, 64, 32,132, 64, 40,128,149,165,149, 81, -111, 83,184,236,206,201,201, 97, 14, 31, 62,236,214,162, 69, 11,225,136, 17, 35, 8, 0,108,222,188,153,217,186,117,171,236,226, -197,139, 66, 75, 75,203,132, 50,211, 72,175,251, 83, 26, 19, 66,192, 23, 8,192, 23, 9, 1,142, 3, 33, 68,182,108,217,178,249, - 47, 94,188,168,235,235,235, 11,141, 70, 51,136, 16,242,216,228, 7,203,132,178,180, 72,113, 99,169,242,172, 80, 37, 33,185,240, -184,172,146, 4, 90,225, 49, 89, 0, 62,203,100, 11,126, 89,162,138,199,227,149,105,157, 98, 24,166,204, 46,194, 73,147, 38,193, -220,220,188,164,138,135, 62,127,254, 60, 36, 33, 33, 97, 51,165,116,237,199,188,200,233, 43,143, 95,204,155,216, 45, 11,121,125, -167, 86, 86, 86, 41,173, 90,181,202, 6,160, 59,120,240,195, 6,177, 70,163, 41,177,226,182,180,180,156,183,117,235,214,113, 93, -187,118,101,138,186, 10, 40,220,141,151,191,233,245,122, 28, 60,120,112,220,180,105,211, 80,146,213, 43,191,242,206, 81,170,160, -202, 27,224, 28, 30,124,216,216,194,188,196, 83,246, 14,174,240,241, 47, 89, 64, 72, 37,185, 99,132,170,250,252, 49, 78, 67, 98, - 38, 6, 91, 10, 39,195, 19,132, 70,188,139,172,231,100,103,133,244,204,108,136, 69, 2, 72,197,130, 66,156,185,214, 43,169, 88, - 0,107, 43,115, 36, 39,198, 67, 36, 18,150,234, 3,109,225,222,199,184, 23, 28,137, 35,151,159, 64,167, 86, 98,229,206,243,208, -105,178,161, 83, 43,161, 83,231,254, 46,158,246, 13, 8,193,123,157, 58,219,187, 92, 25,152,207, 71,253,250,245, 75, 20, 56,113, -113,113, 70, 90,176,104,129, 5, 75,165, 46,103, 26, 25,215, 82, 42,213, 66,149,127,254, 99, 5, 65,190,235, 6,169, 84, 90,103, -199,142,146,221, 49, 20, 7,103,103,231,115,114,185,188,178,177,215,151,195,233,232, 98, 43, 43,171,121,190,190,190,126, 43, 87, -174, 20,240,120, 60,180,110,221,218,251,155,111,190,137, 2,128,234,213,171,187,228,151, 49,223,126,251, 45,189,123,247,110,112, -110,219,162,100,136, 68,162, 87,150,150,150,117, 90,182,108,137,204,204, 76,196,196,196, 64, 38,147,193,255,231,159,241,252,219, -111, 17,184,113, 35,152, 86,173, 64, 8,129, 72, 36,194,243,231,207, 33,149, 74, 95,149, 82,152,215, 7,240, 19,128,198,248,163, - 91,144, 2,184, 5, 96, 42,165,244, 94, 49,229, 29, 3, 0, 44,199,149,149, 88,253,167, 76,153,130, 12,129, 0,232,208, 1,194, -136, 8,232,116, 58, 52,104,208,160,192,170,222,160, 65, 3,240,249,124,212,168, 81, 3, 46, 46, 46, 88,183,110, 93,127,124, 56, -179,250, 3,168,179,117,136,138,136, 69,195,134, 13, 11, 44, 85, 29, 58,116, 40,176, 96, 9, 4,130, 2, 75, 22, 97,121, 70, 85, -102,133, 5,150, 94,175, 39, 66,161,144, 63,106,212, 40,242,245,215, 95, 83,189, 94,207, 9,133, 66,102,203,150, 45,228,238,221, -187,124,149, 74, 85,102, 3,220,189, 75, 47,244,106,157,107, 4, 61, 82,213, 30,188, 60, 97,213, 37, 56,182, 32, 93, 44,182,239, - 23, 45, 93,186,180,167,175,175,111,110,119, 59,192, 55,249,193, 50,161, 12, 3, 79,114, 17,113,164, 45,180,159, 12,128,228,237, - 39, 23, 18, 82,201,200,157, 17, 88,183,200,181,249,231,181, 69,126,243,207, 63,253, 28,239, 83, 90, 11, 56,236,206,157, 59, 94, -181,107,215, 70,116,116,244,159,102,182,229, 87, 88, 50,153, 12, 82,169, 20,183,115,173, 34, 97, 37,145, 93,189,122,245, 23,228, -122, 73, 6, 0,184,184,184, 52,108,217,187,197,237,122, 95,214,197,222, 37,251, 50, 19, 18, 18,106,228,251,192, 33,132, 16, 23, - 23,151,129, 2, 17,191,143, 71, 53,247,230,224,184,159, 46,159,252,125,110,105, 47,226,225, 29,144, 13, 64, 85,104, 22,225,242, -143,137, 16,134, 97,122,117,237,218,149, 9, 9, 9, 65,159, 62,125,176,123,247,238, 18,175, 29, 56,112, 32,246,239,223,143,174, - 93,187, 50,211,167, 79,239, 85,150,192,202,181,142,104, 63, 91,102,124,242,226, 49,182,108,219, 82,226, 24, 35, 23,215,220, 41, -255,241,113,241, 5,199,154, 55,106, 81,134,133,192,112,249,193,189,219, 53, 27, 52,109, 35,136,140, 77,132, 68,196,135,164,208, -140,125,105,222,248, 43,169, 88, 0, 39,123,107, 92,189,120, 90,167,215,105, 75,157, 77, 50,174,107, 0,190,237,228, 7, 80, 14, -221, 38,111,195,233,181, 99, 11,186,119,154,244, 24,143, 43, 7, 87, 27, 61,134,175, 40, 4, 2, 1,158, 63,127,174, 42,201,122, -197,227,241,202,244,169,245,135,149, 81,143,156, 28, 21,114, 84,234,207,217, 26,179,119,116,116,220, 96, 99, 99, 35, 41, 78, 64, - 17, 66,236,237,237,237, 55,216,218,218, 74,140,237, 34, 44, 73, 92,229,249,197,122, 56,100,200,144,114,137, 44,177, 88, 92, 57, - 44, 44,172,192,201,104,105,191, 90,173, 22, 45, 91,182,228, 27, 89, 88,158, 34,132,188,117,118,118,190,229,239,239,111, 25, 30, - 30,142,125,251,246, 9, 5, 2,129,123,126,249,145,149,149, 5, 30,143,135,164,164, 36, 61,128, 97,101,117,145,105, 52,154, 27, - 55,110,220,168,217,169, 83, 39,222,171, 87,175,192,227,241,114,195,213,176, 33, 2, 55,110, 68,240,196,137,104, 30, 25, 9,181, - 78, 7,137, 68,130, 11, 23, 46,232,114,114,114,110,148,196, 39,149, 74, 55,191,123,247, 46, 64, 34,145, 64,167,211,129,227, 56, - 48, 12, 67,248,124,126, 19, 43, 43,171, 53, 0,234, 22,190,222,193,193,193, 97,228,164, 31,125, 88,131,129, 77,136, 14, 79, 46, - 43, 14, 82, 83, 83,113,234,212, 41, 52,104,208, 0,205,155, 55, 71, 92, 92, 28, 34, 34, 34,208,190,125,251,130,107,158, 62,125, -138,199,143, 31,195,211,211,179,108, 11, 30,163,135,167, 79,101, 8,133, 66, 8, 4, 2, 8, 5,185,191,185, 91,174,229, 74, 40, - 16, 66,192, 23, 64, 34,149,148,219,130, 5, 0,114,185, 60, 63, 95,112,149, 43, 87, 78, 72, 72, 72,112, 6,192,203,119,192,106, - 76, 99, 37,191,142,200, 23, 87, 2,145,176,192,146, 5, 0, 25, 25, 25,234,174, 93,187,238,209,104, 52, 67,241, 17, 43,138,152, -240,159,196,131,255,209,189,127,137,192,106,223,168, 81,163,141,253,250,245,107,189,106,213, 42,200,229,114, 36, 36, 36, 20, 84, -132, 34,145, 8, 21, 42, 84, 64, 90, 90, 26, 54,109,218,132,216,216,216,171, 0, 70, 26,251,224,132,132,132,187,111,158,132,165, -182,236,217,200, 54,160,145,143, 85, 76, 88,108, 3, 0,183,243,196,213,182,126,147,218, 15,109,217,189, 30,132, 34, 1, 98,222, -188,255,127,139, 16, 30,143,199, 35,132,160, 79,159, 62, 70, 93,223,183,111, 95,220,184,113, 3,165,117, 39,114,249, 22,172, 28, - 53,148,170,207,215, 56,235, 63,172, 15,250, 15,235, 83, 32, 34,140,233, 98, 1,128,189,199,119,150, 92,128, 27,116,203,206, 28, -222, 53,162,102,237,250,246, 13,106,122,225,205,219, 88,252, 52,227,155,130,243, 83, 70,245,195,142, 3, 39,225,234,100, 7,101, - 86, 6, 14, 31,216,151,169,209,104,150,125,164, 17, 46, 87,212, 18, 2, 35,253, 75,126, 96, 53,205, 23, 88,213,170, 85, 43,209, -130,149,150,150,166, 42,171, 66, 40, 72, 35,173, 30,217, 74, 21, 84, 57,159, 71, 96, 17, 66, 2,155, 52,105,114,233,208,161, 67, -182, 14, 14, 14,136,143,143,255, 64, 96, 17, 66, 2, 27, 55,110,124,233,208,161, 67,182,142,142,142,136,137,137, 49,218, 61, 72, - 49,226, 10,201,201,201, 36, 61, 61,157,179,182,182, 46,151,200, 98, 24, 6, 26,141, 6, 47, 95,190, 52,246,177, 70,207,248,178, -180,180,220,177,127,255,126,203,148,148, 20,240,120, 60,188,124,249,242,131, 89,132,249,219,182,109,219,132,221,186,117,219, 10, -160,102,105,124, 6,131, 97,197,192,129, 3,135,199,197,197, 89, 59, 56, 56, 32, 33, 33, 1, 34,145, 8,148, 82,144,150, 45,209, -244,237, 91,232, 88, 22, 82,169, 20,161,161,161,216,188,121,179, 82,163,209,172, 40, 33,125, 68,102,102,102, 94, 66,161, 16, 3, - 6, 12,248,224,220,206,157, 59,209,185, 14,175,206,136,182,226,108, 3, 36,154, 68,233, 87,231,120, 60, 30, 25, 57,229, 39,239, -250,205, 58, 84,123, 29,124, 47, 60, 57, 49,246, 86, 25,175,175,215,106,181,240,245,245,197,131, 7, 15,112,249,242,101,180,106, -213, 10,205,155, 55,199,179,103,207,112,241,226, 69, 60,126,252, 24,132, 16,216,218,218,230, 15,179, 40,117,172,133, 54,199,128, -164,248,212, 63, 89,171,138,238, 11,133, 66,104, 84, 58,163,210,232,213,171, 87,120,240, 32,183,254,201,201,201, 1,159,207, 55, - 76,153, 50, 5, 12,195,208,224,224, 96, 56, 56, 56,208,169, 83,167,178,124, 62,223, 16, 29, 29,109,108,222,207,237, 22,204, 19, - 87, 60,129,224, 3, 97,198,113, 92,214,211,167, 79, 71, 16, 66,158, 17, 66,242,203, 15,147, 31, 44, 19,254, 85,224,151,210, 10, -121, 11,160, 13, 33,164,255,241,227,199, 87,172, 89,179,198,190, 99,199,142, 72, 79, 79, 71,197,138, 21,225,236,236,140,211,167, - 79,227,236,217,179, 41, 44,203, 78,166,148,238, 46,230, 35,107, 83,146,175, 12, 74, 41,117,113,113, 57,164,201,206,254,182,118, -115, 63, 92, 61,248,219, 18,103,103,231,145,174,174,174, 19,134,204,232, 50,180, 69,215,186, 8,125,252, 14,119, 47, 62, 71, 98, -116, 10,134, 52,157, 90, 42,103,209, 65,238, 86, 86, 86,195,205,204,204, 68, 0,116,197,180,130, 63,152, 69, 88,152,147,101, 89, - 86,171,213,226,192,129, 3, 70,137,172,125,251,246, 65,173, 86,131, 45,210,143, 90,152,147,114,148,240, 5, 98,184, 84,240,133, - 78,167, 4,199,125,156,181,166, 48, 39, 33, 4, 12,195, 32, 92, 36,130,205,251,247,184,118,205, 56,135,234,253,250,245, 43, 53, -141, 40,165, 89,132,144,129,107,127,154,115,120,220,180,121,230,173, 26,213,192,175, 7,207, 65,175,211, 65, 44, 22,192,218, 66, -134,170,149,221,160, 82, 42,176,104,222, 44, 69, 78,142,114, 96,209,177,103,127,226, 44,173, 39,133, 2, 44,199,225,242,205,251, - 70,191,123, 65, 45,207,178,224,243,249,120,243,230,141,170,184,217,131, 60, 30, 15, 2,129, 0, 12,195, 20,219,234,254, 48,141, - 56, 34, 16, 74, 80,161,162, 63,180,154,236,207,146, 70, 14, 14, 14,223, 31, 59,118,204, 54,223,229,193,179,103,207, 64, 8,121, - 89,200, 26,242,253,177, 99,199,108, 85, 42, 21,130,131,131,243,151,132,122, 89,158,239, 40,223,114,149,156,156, 76, 18, 18, 18, - 96,102,102,198, 60,123,246, 76, 83,163, 70,141,135, 40,125,165,134, 2, 78,181, 90, 29, 89,210,248, 72,181, 90,237, 42,145, 72, - 4, 69,238,117,241,242,242, 10, 45,218, 85, 88, 92, 56, 51, 51, 51,239, 77,155, 54,173,246,151, 95,126,137,239,191,255, 62,205, -218,218,218,124,195,134, 13,124, 30,143, 71,198,140, 25,195, 38, 37, 37,101,111,217,178,197,242,248,241,227,200,200,200,184, 93, -214,187,231,229,207, 17,141, 26, 53,218,121,254,252,121, 51, 47, 47, 47, 40, 20, 10, 80, 74,177, 99,199, 14,140, 25, 51, 6, 18, -137, 4,161,161,161,232,220,185,115, 78, 78, 78,206,136, 82,242, 39, 33,132, 80,142,227, 48,123,246,236, 2,167,162,249, 78, 70, -205,165, 4,155, 39, 85,145,141,223,146, 41,235,255,195,150, 65, 0,192, 26, 12,236,235,224,123,225, 59,214,254,112, 77, 40, 20, -222, 44, 35,141,102,142, 31, 63,126, 67,135, 14, 29,164,114,185, 28,105,105,105,184,117,235, 22,238,220,185,131,187,119,239, 66, -171,213,194,214,214, 22,214,214,214, 72, 72, 72,192,171, 87,175, 84, 0,102,150,198, 41, 50, 19,192,195,187,114,238,108,193, 60, -139,149,160,208,236,193,194,214, 44,161, 64, 96,212,119,212,172, 89, 51,212,175, 95, 63, 95,248,176, 81, 81, 81, 9, 26,141,134, - 20, 18,251,113,249, 66,220,221,221,221,176,109,219, 54, 90, 26,103,216,214,117,120,184,112,102,110,183,224,243,152, 2,177,117, -173,109, 45,240,133, 66, 84,232,216,163,112, 61,176,158, 16,178, 61,239,191,198,152, 60,255, 9, 13, 30, 19,231,223,156,243, 63, - 35,176, 10,125, 0,123, 9, 33,231,190,249,230,155,165,129,129,129,223,172, 92,185,146, 8,133, 66,204,157, 59,151,198,199,199, -255,154,215,234, 72,255,152,135, 83, 74,127,189,126,244,246,232,193, 65, 93,201,164, 85, 67,154, 60,188, 18,252,170,122, 35, 47, - 84,111,228,133,135, 87, 67,176,118,198,190,221,172,158,157,157,144,144, 80, 86,179, 73,211,166,177, 79,209, 65,238,182, 55,174, - 93,177, 45,239, 44, 66,142,227, 14,237,219,183,111, 92,247,238,221,153,251,247,239,255,105,204, 85,190, 51, 62,142,227,112,233, -210, 37,232,116, 58,252,250,235,175, 28,199,113, 37,251,193, 2, 61,177,122,213,210,193,191,238, 58, 33, 18, 9, 9,238,220, 60, -130,204,244,210,173,114, 66,161, 0,219,118, 28,213, 9,133,130,215,197,157,215,233,116, 49, 87,174, 92,113,108,199,178, 2,134, - 97,254, 36,156, 74,194,161, 67,135,244, 28,199, 69,149,145, 46,151, 8, 33,125,231, 5,125,183,163,107,207, 65, 86, 53,106,213, -226,187, 56, 87, 0,159, 97,144,146,244, 30, 55,174, 94, 48, 28,220,187, 43, 67,163, 81, 15,161,148, 94, 42,235,153,195,150, 95, - 47, 24,115, 5, 0, 29,199,172, 41, 24,127, 5, 0,157,134, 76, 67,203, 6, 1, 32,198,152,154,254, 16, 87,156,193, 96,128, 76, - 38,131,193, 96, 40,214, 85,131,165,165,165, 84,173, 86,171, 40,165, 96, 89,182, 84,211, 16, 5, 62,123, 26,177, 44,235,151,158, -158, 14,165, 82,137, 59,119,238,208, 69,139, 22, 37, 39, 39, 39, 23, 12,198,212,235,245,126,105,105,105,200,206,206,198,237,219, -183,233,210,165, 75,147, 83, 83, 83,103,148,231, 27,146, 74,165,117,248,124,254,195,244,244,116,206,204,204,140,209,235,245,250, - 26, 53,106,136,165, 82,169,209, 11,157,199,199,199,127, 89,210, 57, 79, 79,207,176,176,176,176,170, 44,203, 22, 94,163, 80,168, - 86,171,189, 26, 53,106,100, 76,215,206,248,237,219,183,227,232,209,163,245, 20, 10,197,192,168,168,168,157, 0,234,241,249,124, - 60,121,242,228,165, 90,173,238,215,189,123,247, 29,233,233,233,247, 0,140, 55,178,220, 56, 79, 8, 25,224,231,231,183,125,222, -188,121,242,230,205,155,243, 93, 92, 92, 80,183,110, 93,132,134,134,226,204,153, 51,250,245,235,215, 43,115,114,114,134,149,145, - 63, 41, 0, 98, 48, 24, 32, 18,137, 10, 54,177, 88, 12,161, 80,136, 44, 21,197,215, 63, 71,168, 12,144,170, 86,204, 29,113,134, - 2,228,125, 76, 68, 74,210,251,152,123,132,144,155,241,241,241,153, 37,196,153, 72,173, 86,215,116,118,118,230, 17, 66, 86,233, -116,186, 33, 99,199,142,117, 94,188,120, 49,124,124,124,144,146,146, 2,153, 76, 6, 47, 47, 47, 36, 39, 39,227,254,253,251,108, - 78, 78,206, 70, 0,243, 41,165,165,118, 59,102,164, 40,224,230,228,254,129,165,147, 82, 10,202, 2,122, 13, 11, 86, 71,161, 37, -122, 8, 4,122, 8,133, 66, 99, 42, 73,202,113, 28,210,157,157, 17,119,225, 2,242, 86,149, 40,209,138,118,250,244,233,178, 19, -136,227, 32, 16,139,192, 23,254,209, 45,152,107,205,202, 61,198,144, 63,165,167,201,106,101,194,127, 83, 96,229,125, 0, 25, 0, - 70, 18, 66,118,182,104,209,226, 52,165, 84, 0,160, 3,165,244,183, 79,121,120, 66, 66,194, 35, 23, 23,151,233,142,110,214, 75, -191, 26,216, 4, 62, 53, 43,130, 53,176,184,117,246, 9,126, 93,124,124,127, 92, 76,220, 16, 99,214, 38,227, 56,238, 90,227, 58, - 62, 12, 10,249,214,118,113,113,225, 62,102, 22, 97,102,102,230,156,201,147, 39,227,251,239,191, 47,247, 44,194,146,174,121,246, - 50,105,100,160,159,189, 91,167,175,154,182, 3, 97,168, 86,171, 41,165,192, 67,129,199, 81,161, 80,240,250,254,211,248, 26,197, - 93,151,156,156,220,110,232,208,161,151,248,124,126,229,242,196, 57,199,113, 81,137,137,137,173,141, 72,243,115,132, 16,239, 19, -135,119, 76, 63,123,114,127, 11,189, 86,235, 9, 2,136, 69,226,112,189, 94,119, 93,173, 86, 47, 49, 86, 88, 47, 27,217, 16,227, - 87, 95,196,186,239, 59, 97,236,210,131,216, 58,251,107, 76,255,121, 31,126,250,126, 60, 22,173,217,131, 31,198, 15, 64,207,254, - 67, 57, 74,152,223,141,125, 15, 30,143,119,126,211,166, 77,131,191,254,250,235,130,201, 8,148,210, 15, 10,116,189, 94,175,226, - 56, 14, 27, 55,110,228, 0,156, 47,141,239,195, 52, 34,180,180,241, 80,198,166,145, 66,161, 24,214,176, 97,195, 29, 0,196,148, -210, 55,233,233,233,163, 40,165, 5, 75, 56,101,103,103, 15,107,212,168,209, 14, 74,169,152, 16,242,167,243,198, 32,207,101, 67, - 29,107,107,235,135,121,150, 43,241,199, 12,116, 47, 45,170, 75,233, 62,100,141,200, 71, 28, 10, 45,127, 67, 8, 89, 92,175, 94, -189,194,139, 61,191, 4, 80,167,188,129,202,107, 4, 4,204,158, 61,123,162, 68, 34,105,153,147,147,227, 13, 0, 50,153, 44, 84, -163,209, 92, 83,169, 84, 43,243,202,173,210, 56,180,102,102,102,161, 6,131,161,154,189,189, 61,248,124,126,129,200, 2,128,147, - 15,217,135,148, 26,234,150, 55,108,103,207,158,173,100,109,109,253, 5, 33,164, 39,165,212, 55, 43, 43, 75, 51,123,246,236,219, -135, 14, 29,202,172, 92,185,242, 87, 29, 58,116, 32, 54, 54, 54,120,240,224, 1, 77, 77, 77, 61, 2, 96,134, 49, 51,167, 57,142, -139, 90,182,108, 25,202,251,189,151,118, 94,167,211,189, 63,123,246,172,221,151, 73, 73,124, 27,142,195,153, 51,103, 62, 16,110, - 69,241,250,245,107,104, 52,154, 82,157, 48,234, 50,211, 81, 99,252, 52,208,188,217,156,249,112,239,208, 3, 4, 20, 84,107,210, - 83, 38,252, 55, 64,254,146,105,204,229, 52, 33,186,184,184,244,145,200,196,223, 85,244,118,174, 17, 31,145, 20,146,149,153,179, - 59, 33, 33, 97, 19,165,148,253, 88,206,242, 56, 26, 53,153,121,255, 58,206, 63,252, 96,177,160,148, 5,229, 40, 40,229,192,113, -108,238, 66,212,148, 3,101, 89, 66, 8,126,215,228,100,126,109,108, 56, 9, 33,214,118,118,118,243, 41,165, 95,242,120, 60,166, -176,241,171,240,255, 60,203,213,249,228,228,228, 31,138, 10,194,127, 98,124, 30, 62,124,184, 88,209,111,236, 44,194,158, 61,123, -178,229,252, 54,175,201,100,178, 98, 29,106, 42,149,202,232,248,248,248, 47,254, 14,241,153,111,253,164, 70, 20,104, 69,186,218, -203, 61,139,176, 44,206, 74,149, 42,137,117, 58, 93, 45, 0, 94,132, 16, 43, 0,105, 58,157,238, 66,114,114,114, 34, 33,164, 14, -128,217,121,183, 45,160,148, 62,252, 95,126,239,132, 16,169,157,157,221,118,134, 97,220,140,185,223, 96, 48,104,211,210,210, 6, - 23,110, 8, 20,230,180,179,179,123,200,231,243,221,140,224,137, 77, 73, 73,169, 99, 42, 63, 77,156,255,121, 11,214, 95,141,248, -248,248, 3, 0, 14,124, 78,206,146, 60,181,155,240,255, 11,101, 90,194, 95,146, 14,121, 98,105,204,127, 45, 62,243, 5, 82, 49, -199, 31,161,200, 90,160,159,233,219,108,249, 79,136, 23,250,145, 45,197, 60, 1,213,244,115,134, 37, 50, 50, 82, 3,224,118,222, - 86,244,121, 15, 1,116,250, 27,197,155, 10, 64,159,207,197, 87,154,104, 50,193,132,255, 26, 24, 83, 20,152, 96,130, 9, 38,152, - 96,130, 9, 38,124, 94, 16, 0,109, 74,104,217, 24,109,250, 35,132,180,249,136,150,211,101, 19,167,137,211,196,105,226, 52,113, -154, 56, 77,156,255, 45,206,255, 12,242, 29, 62,254, 21, 27,128, 54, 38, 78, 19,167,137,211,196,105,226, 52,113,154, 56, 77,156, -255,181,205,212, 69,104,130, 9, 38,152, 96,130, 9, 38,152,240,153, 97,180,192,146, 59,249,249,217, 87, 10,220, 97, 83,161,198, - 51,155, 10, 53,158,217, 87, 10,220, 33,119,242,243,251, 47, 70, 26, 33, 68, 74, 8,233, 47, 16, 8, 46, 57, 59, 59, 43, 8, 33, - 19, 77, 89,169,252,104, 65, 8,191, 47, 33,223, 13, 38, 36,122, 48, 33,209,125, 9,249,174, 5, 33,255,186,101, 51,230,141,119, -105,248,219,249, 1,231,230,141,119,105, 88,236,249, 41, 46,182,247, 46,245, 94,189,100,140,171,205,103,202,159,230,142,142,142, -155,157,156,156, 34, 29, 29, 29,163, 28, 29, 29,183, 19, 66, 44, 77, 57,206, 4, 19, 76, 48,225,255, 15,252,188, 2,185, 57,128, -235, 0, 90, 80, 74,111, 20,189,200,166, 98,245,175,253,124,125,190, 95, 56,119, 6,113,114,176, 51, 51,176,156,238, 93,100,140, -255,156,133, 75, 15,219, 84,172,190, 34, 45,234,249,214,143,168, 4, 8,143,199,235, 35, 22,139, 59, 2,200, 23,106, 47, 53, 26, -205,105,150,101, 15, 24, 59, 43,200,201,201,233, 38,143,199,171, 84,158,103,179, 44, 27,253,254,253,251, 38, 31, 89,121,245,114, -119,119,223,222,188,121,115,179,122,245,234, 65, 36, 18, 97,246,236,217,147, 1,172, 52,150,195,198,198,211, 92, 39,150, 76,224, -139, 68,109,169, 94, 91,141,130, 2,140, 56,152, 51,104,174, 8, 53,154, 21,105,105,225, 89, 70,134,101, 6,128, 33,200,157, 86, -190,149, 82,186,236,175,200, 36,132,144, 10, 0, 90, 2,240, 5,240, 28,192, 69, 74,105,234,167,242, 58, 2, 35, 27, 53,105,178, -122,240,228,201, 60,213,205,155, 88,189,125,251, 42, 40, 20, 0,176,174,188,121, 73, 40, 68, 79, 59, 59, 65, 71, 74, 81,139, 0, -132, 0, 79,146, 83,185,179, 58, 29,123,128,150,119, 29,158, 15,185,251,227,195,105,245,123,203,203,145, 25, 78,103,137, 59,249, - 53,205, 12,191, 54, 11,192, 87, 69,207, 27,212,146,193,148, 87,161,163,138, 62,142, 1,240,243, 39,166,149,153,189,189,253,179, - 19, 39, 78,184,213,171, 87,143, 15, 0, 15, 31, 62, 28,212,177, 99,199, 86,132,144,106,148, 82,197,255,168, 81, 34,225, 51,204, -119, 34,129,160, 45,203,178,213, 1,128,199,227, 61,215,234,245,151, 12, 28,183,142, 82,170, 54, 21,199, 38,152,240,223, 70, 89, - 90,228, 31, 41,176, 0, 92,167,148, 18, 66, 8, 69,145,169,222,114, 71, 95,255,128, 0,191,201,231,143,237,172,144,145,150,161, -254,101,249,206, 71, 74,190, 40,199,203,223, 75,248,203,202,101,214,223,141,159, 52, 65,238,232,123, 47, 59,241, 85, 72, 57, 34, -209, 93, 42,149, 30, 93,190,124,121,181,150, 45, 91, 10, 28, 28, 28,144,152,152,136,151, 47, 95, 86,187,122,245,106,215,157, 59, -119, 78, 38,132,116,167,148, 26,179,240,149,215,197,157,219, 29,228, 54,182, 96,245,122,184, 5,214, 42,112,144,247,250,202, 69, - 24,244, 58,176,122, 61,170,119,236, 10, 0,224, 56, 14,254,254,254,188,143, 76,124,151,128,128,128,221,139, 23, 47, 22,106, 52, - 26,220,187,119, 15,215,174, 93,227, 18, 18, 18,150, 26,203, 33,119,244,110,201, 72,101, 7,250, 12,248,198,178, 75,199, 42, 2, -119, 71,123, 0,102,120,253,206,208,232,220,197,171,117,143, 29,248,245, 91,185,163,119,159,236,196,208,107,165,139, 52,155, 6, -132,144, 69,249, 30,157, 9, 33, 63, 85,174, 92,249,135,194,215, 20, 93,215,142, 82, 10, 62,159,159,152,149,149,213, 39, 37, 37, -229,113,113,188, 67,106, 17,189,158,205,205, 23, 66, 62,216,221,207,120,199, 58,116,232, 80,121,236,216,177,104,216,176, 33,238, -223,191,223,114,251,246,237,227,249,124,254, 3,150,101,207,230,229,157,143,242, 28, 40, 4,166, 14,158, 60,153, 39,143,140,132, -252,233, 83, 12, 80, 40,248, 63, 2, 83,203, 35,176, 8, 33, 85,156,156, 4,135, 39, 79, 26,234,231,225,217, 64, 40, 20,218,229, - 46,174,173, 77,241,142,142,126,220,115,233,143,155,131, 8, 33, 61, 40,165,111,140,228,227, 3,152, 7, 64, 2, 96, 22,128,217, -201,201,201, 94, 44,203,194,201,201,105, 54, 33,228, 56,128,133,246,246,246, 52, 57, 57,121, 26,165,212, 80,154,229, 74, 17, 78, -103,189, 39, 30, 95,250,212, 30,140,247,228,252,151,147,190,114, 62,103,225, 73, 22,206, 89, 29,127, 7, 0,190,242,244, 52,247, -240,149, 77,147, 91, 84,183, 81,196, 93,158,246,149,167,231,150,115,225,198, 9,236,162, 34, 19, 0, 92, 92, 92,150,237,218,181, -171, 66,253,250,245, 11,242,120,205,154, 53,121,203,150, 45,115,157, 56,113,226, 42, 0, 67,141,228,243,182,183,183,191,192,178, -172, 38, 53, 53,213, 59,255,184, 67, 96,247, 70,182,230,178,214,201,233, 89, 55, 83, 94, 28,191, 97, 36, 87, 61,137, 80,120,228, -212,238,213,206, 53,235, 55,100,100,118, 14,208,197,197, 35, 75,175,107,115,229,214,221, 22, 35,190,155, 58, 62, 47,141,238,155, -170, 24, 19, 76,248, 79,163, 68, 45,242, 79, 22, 88,200,123,161, 63, 65, 44, 22, 5,205,153, 57,141,100,164,102,168,212,138, 44, -173, 94,173, 86, 51, 66,170,126, 30,242, 54,137,225,243, 50, 38,142, 31,103, 30, 52,125,102, 16,128, 1,198,138,171,192,192,192, -251, 71,143, 30,117,176,177,177, 65,102,102, 38, 82, 83, 83,113,255,254,125, 80, 74,209,189,123,119,113,253,186,117,107,205,154, - 61,251, 14, 33,164,161, 49, 34, 75,110,107,135, 5,141,114,215,136, 93, 26,157,154,255, 28,252,210,179, 99,193, 53,203,243, 86, -181,144, 72, 36, 5, 11, 5,127, 4, 26,182,110,221, 90, 8, 0,195,135, 15, 87,100,101,101, 45, 1,176,151, 82, 26,103,172,184, -178,115,118, 57,189, 97,227, 50,105,117, 79, 47,232,244, 6, 68,189,143, 7, 95, 96, 5, 55, 55, 33,134, 14,104, 43,104,214,200, -198,110,209,130,205,103,100,246,222,221,148,201,161, 23, 74,226,178,178,178,218,121,224,192, 1, 28, 60,120, 16, 0, 16, 26, 26, - 10, 47, 47, 47, 89, 89, 97, 8, 14, 14,246,232,220,185,243,126, 0, 85,139, 59,175,103,193,223,187, 55,215, 72,243,243,148,254, - 60,133, 66, 81,217,204,204,172,224,124,171, 86,173,208,170, 85, 43,102,253,250,245,245, 47, 92,184, 80,127,235,214,173, 58, 66, -200, 42, 74,233,161,143,137, 80,213,205,155,144, 63,125, 10,220, 40,127, 99,133, 16, 82,165,118,237,138,119,207,158,217,109,119, -230,236, 75,252,252,243,118,132,135,135, 3, 0, 60, 60, 60,208,191, 95, 47,193,243,231,183, 3,122,246,236,127,155, 16,210,132, - 82, 26,106, 4,237,188, 45, 91,182,204,168, 92,185, 50,122,246,236,217, 43, 32, 32,192,201,194,194, 2,155, 54,109,130,179,179, -179,135, 86,171,125,115,226,196, 9,151,247,239,223, 99,220,184,113, 0, 48,185, 36,162, 22,237, 90,204, 18,119,242,107,234, 83, -123, 48,228, 22,206,216,178,239, 0, 94, 63,218,217, 84,163,123, 57,107,201, 24,215,129, 42, 42, 30,226,230,101, 30, 84,169, 78, -115,219,170, 1,157, 81,177,246, 99, 59, 53,251,219,219,217,223,121, 44,229, 75,212, 59,231, 44,143,255,147,149,144,244, 58,204, -171,166,120,101, 19,124, 9,169,148,206,225,242,132, 85, 65, 65,196, 82,116,110,214,172, 89,129,184,138,140,140,132, 70,163,129, -159,159, 31,163,213,106, 91, 26, 25,175,222, 95,124,241,197,239,103,207,158,181,245,246,246,254, 96,233, 22, 39, 91,171,118, 55, -142,174, 26,183,104,245, 30, 95, 7,255,110, 25, 73, 33,199,158,151, 37,174, 26, 55,168,125,249,252,209,221,114, 94,118, 12,248, - 86, 41, 0,151,138,132, 3,219, 64,204,108,208,119,212, 36,126,203,214,173, 92,219,126,213,227, 50, 33,164, 53,165,244,129,169, -142, 49,193,132,255,180, 21,139,254, 91,222,133, 95,200,186, 65,138,123, 49,142,114, 53, 28, 29,108,165,171,150,239,120,192,211, -105,181, 50, 43, 75,173,192,210,130, 35,230,150, 60,157, 86,159, 93,209,163,162,136,163, 92,141,226,200,139, 78,213, 36,132, 16, -169, 84,122,244,228,201,147, 14, 2,129, 0, 28,199,193,222,222, 30,239,222,189, 67, 70, 70, 6,178,178,178, 16,254,242, 37, 42, -187, 87,192,220,160,105,206,227,166, 5, 29, 37,132,212, 41,220, 93, 88,220,244, 79, 86,167, 43,154, 64, 37, 45,238,251,193,111, -105,156, 37,224, 93,116,116, 52,228,114, 57,170, 85,171, 38,191,117,235,214,111, 37,137,171,162,156, 54, 54,158,230,124,185,244, -224,250, 13,179,165, 58,125, 48, 66, 34,210,224, 83,185, 41, 28,109,221, 17,159,166,197,221,251, 39, 17,252,108, 47, 60, 93,221, - 49,102,116, 43,201,210,101,135, 15, 88, 91, 87,113, 79, 79,127,171, 40,142, 83,161, 80,200,171, 84,169, 2,119,247,220,117,201, - 88,150, 69, 72, 72, 8, 88,150, 45,216, 47,252,187,227,200, 85, 24, 20, 81, 24, 60,104, 16, 82, 83, 83,229,198,190,123,190,184, -218,212,223, 37, 64,153,158, 32, 4, 0,153,181,179,110,196,158,184, 23,141, 27, 55,134,171,171,171,240,202,149, 43,147, 0, 28, - 42,111,124,234,128,159, 86,255,250,235,154, 1,153,153, 12, 0,108, 37,132,211, 81,250,147,177,121,201,193, 65,112,228,252,185, - 93,118, 60,230, 21,108, 44,127,196,253,251, 81,208,233,114,179, 74,106,106, 18,198,126,167,128, 80, 96,142, 19, 39,246,216,250, -249, 53, 57,146,215, 69,198,149, 17, 78,201,185,115,231, 48,118,236, 88,132,132,132,184,240,120, 60,220,187,119, 15, 82,169, 20, -203,151, 47,231,249,249,249,185,200,100, 50,156, 63,127, 30,137,137,137,164,180,112, 94,191,112,125, 97,102,248,181, 89,239,201, -249, 47,183,236, 59,128,111,250,245,129, 19,141,248,205,210,147, 44,252,162, 83,227, 31, 40,175, 66, 71,153,121, 13,107,175,106, -157, 32, 20,201, 49,102,234,124,132, 6,159,178,206,201,122,246, 29, 97, 99, 42, 32,111,109,190, 15, 22, 59, 62,212,147, 93,179, -239,118,237, 75,238, 15, 42,186,212, 30,121, 15,192,179, 63, 4,150, 7,159, 48,172,101,190,181,242,205,155, 55, 8, 15, 15, 7, -159,207,135, 74,165,130,193, 96, 40, 54,156,174,174,174, 35, 13, 6,195, 15, 0,160,211,233,118, 56, 59, 59, 15,219,189,123,183, -109,225,149,162,242, 45, 87,105, 25,138,244,219, 15, 94,188,158, 52,178,103,139,155,119,131, 99,172, 2,187, 70,103, 60, 61,158, - 89, 66, 26, 73,164, 34,209,145,243,199,246,200,185,183, 87, 33,246,107, 1,190,220, 11,172, 62, 14,234,116, 37,212,111, 19,160, -221,180, 22, 30,163, 39,226,212,241,195,242,128,234,117, 14, 17, 66,188, 40,165,218,143,248, 54,141,134,137,211,196,105,226,252, -123,114,150,166, 69, 0,212, 6,224,152,247, 63, 21,185, 67, 99,236, 0,164, 32,119,217, 46, 71, 0, 90, 0,162, 66,247, 20,221, - 47,124,109,209,253,194,255, 83,243,254, 59,228,253, 62, 0,144, 86,222,119, 41,211,148, 67, 8,163, 96, 89, 78, 39,180,119, 80, -143,152, 60, 44,192,209,189, 2, 83,193,163, 2,255,155,222, 45,154,123, 84,114,148, 18,134,232, 9, 97,140, 26,215,193,227,241, -250,172, 90,181,170,186,133,133, 5,196, 98, 49, 44, 45, 45,145,149,149, 5,173, 86,139,204,204, 76,168, 50, 51,160,206, 72,195, -211,223,111, 66,202, 16,244,248,242, 11, 63, 30,143, 87,166,151, 97,183,192, 90, 88, 26,157,138,165,209,169, 8,114,183,197,180, - 10, 54,152,234,102,141,101,113, 25, 88, 30,159,137,159, 19, 20,152, 95,203, 27, 63, 54,173,141, 7, 7,247,124, 74,194, 63, 62, -115,230,204,185,248,248,120, 76,153, 50,133,169, 92,185,242,121, 66,136,191, 81, 98, 66, 44,153, 48, 98, 66, 71,107,107, 57,197, -205,135, 39,161,214,100,194, 76,196,131, 90,203,129, 16,224,229,139,163, 32,196, 6,207, 66, 19,160,211,102,225,139,118,126,114, - 86,108, 54,165,180,164, 73, 79, 79, 71,120,120, 56, 66, 67, 67,241,242,229, 75,248, 7, 4,224,249,243,231,184,123,247, 46,110, -220,184,129,203,151, 47,227,242,229,203,184,126,253, 58, 46,157, 62,132, 29,191,254,138,136,136, 8,148,102,122, 21,240, 96,248, -121, 74,127,252, 60,165, 63, 68,230,246,186,172,172, 44,112, 28, 7,101,122,130,112,242,242,189,152,188,124, 47,148,233, 9,194, -107,215,174, 97,207,158, 61,136,140,140,252, 64,168,151, 7,225,192,230,171, 44,155,156,126,236, 24, 61, 53, 96, 0,123, 87, 46, -143, 73, 4, 54, 25,115,175, 80,136,158,203,126, 26,237, 35,147,201,144,154,178, 10,190,190, 66, 76,158,104, 91,112,126,220, 88, - 55,212,173, 99, 7, 69,198, 97,136,132, 6,172, 89, 51,222,211,204,140, 55,200, 8,234, 89, 39, 79,158,140,189,116,233, 18,221, -187,119, 47, 14, 30, 60,136,240,240,112, 72,165, 82, 72, 36, 18, 36, 37, 37, 33, 56, 56,152, 46, 91,182, 44, 22,185, 93,136, 37, - 98,206,234,248, 59, 43,207, 37,124,229, 76, 35,206,191,126,180, 51,199,149,247,246, 86,239, 9, 77, 34, 29,172, 37, 89, 23, 47, -221, 90,112,238,216,241,117,155, 22, 44, 75, 91,183,108, 14,116,218,108,172, 93, 54, 7,191,204, 91,145,118,238,216,241,117,215, - 79,221,158, 95,172, 85,172,197, 60,190,179,163,141, 97,228,144, 30, 86, 95,125,213, 98,164, 83,189,145,243, 80,185,150, 12, 0, - 35,174, 90,107,160,119,181,250,218,171, 87,175, 66,167,211, 65,173, 86,231,127,119,216,189,123, 55,103, 48, 24,138,237,118,214, -233,116, 63,196,196,196, 56,135,134,134, 58,123,121,121,141, 59,116,232,144, 99,254, 26,114, 44,203, 22, 88,174,110,159, 94, 55, -105, 64,247,182,245, 39,252,176,238,154, 74,173,209, 46, 12, 26,214, 66,192,162, 65,137,173, 55,134,249,238,212,177,237, 78, 18, -107, 61,100,117,191,128, 33,219,128,136,101,223, 32,116, 94, 16,188, 23,204, 67,224,218,245,168, 48,228, 27,156,233,210, 19,193, - 11, 23,226,199,111,134,185, 48, 12, 51,218,212,134, 55,193, 4, 19,138,129, 35, 33,228, 52, 33,228,244,244,233,211, 91, 0,176, - 35,132,156,206, 19, 89,142,121,255, 69,249,215,148,176,111, 87,152,167,200,189,133,255,219, 78,159, 62,189, 53, 33,228,116,163, - 70,141, 6, 2,248,168, 9, 72,252,124,197, 88,248,247, 3, 11, 22,199,221,124,243, 54,178,253, 23,109,234,187,157,190,241,252, -193,200,161, 29,218, 49, 12, 67,158,132, 68,221,240,172,232,100,119,237,250, 77,202,113,220, 77, 99, 30, 38, 22,139, 59,182,106, -213,138,159,158,158, 14, 23, 23, 23, 36, 39, 39, 35, 46, 46, 14,122,189, 30,234,204, 12,104,179, 20,208, 42, 50,193, 42,179, 16, -254,240, 62,106,120,122,136,143,228, 14,130,223, 95,134,240, 41,214, 50, 85,216,146, 37,150,155, 67,108, 46, 7, 41,103,247, 32, - 33,164,139,149,149,213,180,140,140,140,179,148,210,133, 58,157,238,187,105,211,166, 61, 88,179,102,141,221,162, 69,139, 44, 70, -140, 24,113,136, 16, 82,179,172,113, 72,230,246,188,142, 13,107, 86, 99, 94,189,123,134, 38,129,131,225, 93,165, 45,222, 37,170, -144,174,212, 35, 45, 75,143,186,205,126, 65, 82,166, 22, 10,165, 6, 47,163, 86,194,197,213,139, 1,255,109,107,252, 49,192,250, - 79, 72, 76, 76,252,224,157,247,239,219,135,156,204, 76,120,122,122,194,207,207, 15,246,246,246,136,138,138,194,239,191,255,142, - 1,189, 59, 67, 32,232,129,164,164,164, 82,223,119,199, 99, 42, 32,132, 60,162,148,226,241,227,199, 8, 15, 15,135, 68, 34,249, -211,117, 87,174, 92,201,173,120,157,156,140,255, 58, 28, 29,167, 51, 12,211,155,227, 56,158, 66,161,136,209, 18, 82,213,191, 98, - 69,199,198, 93,187, 34, 83, 32,224,173,190,114,133, 36,102,101,201, 1,100,148,197,101,103, 35,232,208,178,213, 87,162,140,244, -237, 0,114,141, 82,195,134,218,227,171, 47, 29, 65, 24, 49, 92,156,205, 65, 24, 49, 8, 17, 33, 71,121, 21,245,235, 53, 20, 90, - 89,173,236, 8, 96, 71, 41,105,221, 31,192,236,198,141, 27,187,140, 25, 51,134, 28, 63,126, 28, 99,199,142,213, 1,136, 4,128, -239,190,251,206, 99,252,248,241,188,236,236,108, 82,161, 66, 5,231,183,111,223, 62, 33,132,148, 57,240,221,194,147, 44,212,232, - 94,206,178,242,146, 37,179,176,107,148,173, 23,167,206, 89, 30, 49, 7,192,207, 95,121,122,110,209,113, 55,223,134, 5,159,178, -126,247,224,122, 90,124,152,210, 99,203,153,136, 18,199, 96,221,184, 1,206,177,198, 13, 93,231, 47,155,243,187,118,106,153,227, -234,230,232,253,203, 58,237,238, 52, 87,219,133,149,220,221, 6,204, 89, 60, 77, 55,176, 91, 83,221,180,201, 99, 5, 1,254,126, - 68,161, 80,224,192,129, 3,134,115,231,206, 37,112, 28, 55,161,164,182, 15, 0,232,245,122,140, 28, 57, 82,102, 97, 97,129,152, -152, 24,248,250,250, 22, 8,172,132,228,212,231,183, 30, 4,191,154, 52,170, 87,243,189, 39,175,189,188,112,253,225,203,174, 95, - 54, 14, 36,132,150, 56,193, 68, 36, 16,180,173, 83,191, 62,143,210,120,240, 4,222,136,221, 61, 12,234,212, 44,104,148,106, 48, - 2, 25,180,122, 30,116, 28,129,184, 70, 61,188, 57,126, 18,158,125, 7,241,197, 2, 65, 59, 0,171, 76,117,137, 9, 38,252,247, - 80,154, 22, 41,116, 77, 71, 66,200,233, 37, 75,150,116, 44,237, 60,165,180, 35, 0,109,145,125, 24,243, 31, 0,150, 46, 93,186, -184,208,190,234, 99,222,167, 76,181,193, 83,107,151, 76,153, 54, 11,214,150, 82,203,122,181,188,156, 78,156,191,241,240,230,237, -135, 47, 43, 85,176,179,167,122,173,245, 79, 43,214,186,145, 28,149,177,131,188,253,236,236,236,160,211,233,240,230,205, 27,196, -198,198, 66,167,211,193,160, 84, 66,147,145, 1,117,122, 58, 88,101, 22,132, 44, 11, 85,114, 18,108,205, 36,192, 31, 51, 12,203, - 18, 66,197, 10,172,252, 95,137,165, 5, 36,230, 22,224, 9, 4,197,118, 31,150,192, 89,187, 94,189,122, 7,131,131,131,235,183, -105,211,102, 1, 33,196,146, 82, 26, 21, 23, 23,215,122,246,236,217, 26, 71, 71, 71,140, 28, 57,210, 7,192,224, 50,197,165, 72, -235, 87,209,201, 7,222, 30,131, 81,169, 66, 43,100, 40,245, 72, 86,232,145,148,161,195,166, 95, 26,226,200,214,122,248,253, 72, - 83, 4, 95,104,139, 12,189, 19,228, 46, 93, 64, 89,109, 64,105,156,183,111,223,198,198,141, 27,177,113,227, 70,108,216,176, 1, -107,215,174, 69,122,122, 58,170, 85,171,134,232,232,104,156, 59,119, 14, 9, 9, 9,176,179,179,195,147, 39, 79,176,105,211, 38, -220,191, 95,254,113,196,106,181, 26, 66,185,173, 46,223,178,197, 9,100,186, 66, 2,220,104, 30,131,193, 48, 36,161,107,215,234, -137, 54, 54,254,181,106,213,250,106,220,184,113, 30,141, 27, 55, 46, 56,239,225,225,225, 46,149, 74,223, 19, 66,182, 18, 66,106, -150,198,197, 1,181,236,237,171, 65,171,121,149,151, 86, 2, 16, 34, 65,171,182, 47,209,184,233, 67,232,244, 66, 48, 68, 12,134, -145,192, 96, 72,133,181,181, 11, 40, 37,213,202, 8,226,236,228,228,100,175,203,151, 47, 51,239,222,189,203, 23,150,145,115,231, -206, 93,251,243,207, 63,135,216,218,218,178,167, 79,159,198,241,227,199,209,177, 99, 71,222,215, 95,127,237, 85,161, 66,133,141, -101,189,247,156,213,241,119,246,174, 56,215, 87,160,183,174, 41,145, 86,170, 12,165,188,203,119, 45,236,101, 0,112, 46, 60, 60, -203,193, 93,177, 84,153,245, 44,218,202, 45,251,199,178, 6,184, 83, 58,135,123, 20,246,234,238,222, 99,231, 51,147, 18,211, 5, -181,170, 7,168,150,204,255, 94, 88,169,114,213,159,230, 76, 27,229, 20,167,144,100,180, 29,119,238,213,209,243,247,179, 7, 14, -253,198, 48,124,196, 24,245,185,243,151,142,113, 28, 87,189,164, 25,132, 28,199, 33, 33, 33, 1, 47, 94,188, 64, 68, 68, 4,146, -147,147,145,146,146,130,172,172,172,130,110, 69,179, 44,197,153,181,191,158,122, 42,147, 74,205,234, 87,247,114,191,247, 56, 36, - 73, 38,149,154,121, 85,118,247, 38,100, 94,177,229, 8,203,178,213, 37,102, 82, 0, 4, 89,193, 55,161, 78,203,134, 42, 35, 27, -234,244,108,104,116, 60,168, 53, 12, 84, 90, 6,118, 77,191, 64,182, 82, 13, 77,122, 38, 56,150, 13, 52, 85, 51, 38,152, 96, 66, - 41,245,242,233,160,160,160, 25, 70, 94,110,116, 55,102,190, 16,203,223, 15, 10, 10,154,145,103, 45, 11, 64, 9, 99,150,141,178, - 96,149, 54, 53, 50, 37, 37, 52,219,194,222,191,251,196,169, 63,156,219,183,237, 23, 7,141, 38, 39,218,214, 90,206,202,205, 68, -118,195, 71, 46, 66, 86,118,122,183,236, 52,227,103, 61,165,167,167,227,237,219,183,144, 74,165, 16, 10, 4, 96, 85, 42,176, 42, - 37, 84,233,169, 96,116, 26, 8, 89, 22, 54,102, 82, 84,116,113, 66, 37, 71,227,172, 35,175,175, 92, 44, 24,208,190, 44, 46,163, - 64,108, 45,168,235, 7,177, 76, 14,177, 92,142,137,103,174, 3, 0,132, 66, 33,240,195, 2, 99, 18,209,206,213,213,245,228,222, -189,123,133,201,201,201,120,242,228,201, 83, 74,105, 38, 33,196, 28, 0,247,242,229,203,203,193,193,193, 29,189,188,188, 0,192, -179, 44, 62, 69, 10,195,234, 13, 20, 49,239, 35,241, 46,246, 49,108, 44,171, 64, 96,230,141,164, 12, 29,196,210, 42,208,107,254, -152,132,169, 86, 68, 65,165, 51,110,162,163, 78,167,131, 78,167,131, 94,175,135, 70,163,193,192,129, 3,113,235,246,109,236, 63, -126, 5,111,195, 67,225, 83,217, 9,131, 6, 13, 68,205,154, 53,241,224,193,199,143, 31,110, 56,237,194, 11,169, 84,138, 13, 27, - 54,160,240,160,119, 99,215,216, 37,132,252,220,177, 99,199,170,161, 74, 37, 94,188,122,133, 54,115,231, 2, 0,206,158, 61, 91, -112,141, 86,171,197,164, 73,147, 68, 33, 33, 33,195, 31, 62,124, 56,156, 16,178,130, 82, 90,252, 32,114, 10,156, 57,115, 7,163, - 70,133, 32, 57, 57,119, 28,246,129,125,127,232,209,119,111,117,248,178,195,121, 0,128,149,149, 21, 86,172,168,102, 84, 56, 89, -150,197,230,205,155, 33,149, 74, 33,149, 74,115, 63, 18, 62,191,241,164, 73,147,186, 23,119,125,213,170, 85,133,101,113, 78,234, -229, 38,121, 18, 37,253,206,178,106,165, 0, 11,187, 26, 72,213, 63,174,246, 56, 46, 97,236,164, 94,110,171, 86, 28,138, 85, 75, -137,102, 7, 97, 99, 42,240, 37,234,157,198,132, 49,252,220, 26,173, 85,165,161, 59,223, 39, 43,102,142,249,166,191,173,133,149, -131,114,235,218, 37,214, 12,143,161, 39, 31,234, 50, 2, 60,108,173,186, 52, 88,157, 61,106,226,236,199, 90, 67,204, 24,196,156, - 12, 45,205, 85, 5,203,178,136,143,143, 71,114,114, 50,162,163,163,145,146,146,146,247,237,167,148, 75, 64, 23,215,232,209, 70, - 71, 35,241,248, 86, 56, 13, 24, 8,239,249,243,193,114,124,168,115, 88, 28,110,214, 26,138, 12, 21,180, 28,129, 85,237, 70,248, -226,244,111, 32, 28, 11,108, 88,103,170, 65, 76, 48,225,191, 43,158, 74,212, 34,198, 90,176, 62,209,130, 86, 32,178,150, 44, 89, -242, 98,201,146, 37,159,244,172, 50,221, 52, 0,128, 34, 57, 36,194,182, 98,141,120,165, 74,105,230,232, 96,175, 49,147,136,185, - 76, 69, 22,239,241,243,167,186,236,132, 55,175,203,241,188,151,193,193,193,213,226,227,227, 17, 29, 21, 5,131, 74, 9, 70,163, - 5, 85,231,160, 77,147, 70,144, 0,144, 48, 4, 66, 78, 7, 62, 79,132,172,108, 5, 0,188, 44,179, 82,212,235,255,100,201, 34, -132, 64, 34, 55,135, 80, 38,131,216,220,252, 3,139,150, 49,162, 64, 44, 22,239, 61,116,232,144,179,171,171, 43,230,207,159, 15, - 55, 55, 55,223,234,213,171,231, 52,109,218, 84,234,232,232, 8,127,127,127, 52,106,212, 8,231,206,157, 3,128,240,178,248,244, - 6,201,179,215,145,104,156,146,118, 27,191, 93,223, 0,173, 74,131, 90,205, 55, 64,199,175, 4,251,128,121,224,222,236, 70,206, -251, 19,185,214, 2,167, 78,136,141,142, 4,225,137, 94,148, 51,115,224,217,179,103,216,119,226, 6,156, 43,250, 33, 58,236, 21, - 94, 93,187,140, 91,246,182,168,228, 31, 0,189, 94,111,180, 32, 50,246,186,252, 46, 36, 35,208,127,202,148, 41,200, 16, 8,128, - 14, 29, 32,140,136,128, 78,167, 67,131, 6, 13, 80,183,110, 93, 0, 64,131, 6, 13,192,231,243, 81,163, 70, 13,184,184,184, 96, -221,186,117,253, 81,194, 44, 61,134,224,137,193,144,234,235,225,225, 81, 32,176,118,238, 74,198,227,135,109, 65, 32,194,154,181, -127,120,101,112,119,119,199,251,132, 8, 16, 66,131,203, 8,227, 2, 39, 39,167,217,206,206,206, 30, 63,255,252, 51, 79, 34,145, - 96,244,232,209, 85,178,179,179, 43,229,153,140, 49,125,250,244, 92,171,212,156, 57,152, 59,119, 46, 52, 26, 77, 78, 73,100,187, - 86,214,112, 73, 74,227,134, 59, 58,185,118,107,105, 87,169,122,171,118,109, 80,197,171, 21, 90,181,139, 6,128,197, 54,252,200, -222,203,102, 85, 59,102, 87,193,102,251,197,243,151,230, 52,105,222,106,102,208, 72,235,133, 75, 55,165,151, 57,166, 49, 51,106, - 71,214,107, 81,159,149,191,108,220,181,242,135,233,227, 37,209,201,218,244,184,116,154, 45, 23,243,229,158,142, 68, 62,118,234, -130,183,241,241, 17,147, 17,115,190,204,153,147, 28,199, 33, 34, 34, 2, 90,173, 22, 44,203, 66,173, 86, 67,169, 84, 34, 38, 38, -166, 32,125, 85, 50,139, 47,199, 12,237, 20,168, 84,169,114,238, 61, 15,139,158, 53,110, 64, 67,165, 74,149, 19,246, 46, 58,148, -210,213,197,170, 48,134, 97,158,231,100,231,180,209,100,170,145,249,244, 53,108, 91, 85,132,206, 64,160, 97, 89,164,167,100, 65, -107, 0,244, 60, 1,220,122, 14,130, 30,124,164, 39,196,129,225,241,158,154,170, 25, 19, 76,248,207,162, 76, 55, 13,132,144,211, - 13, 27, 54,220, 95,216,202,148,255, 31,128, 6,128,184, 20,254,228,194, 34,170,112,151, 96,113,207, 41,194,251,209, 2,171,212, -169,145,132, 16, 18, 88,189,162,203,178, 57, 3,220, 56,131,193, 39, 41, 37,209,192,231,139, 5, 21, 44, 85, 9,229,121,152, 70, -163, 57,125,249,242,229,174,109,219,182, 21,135, 61,127, 10,109,102, 38,180,153, 25, 16,112, 6,216, 72,235,128,209,105, 64,180, - 90,184,250,114, 80,103, 73,113,227, 86,176, 94,163,209,156, 46,179,146, 55,228, 10, 44,134,199,251,160,171, 80,100, 46,135,196, -220, 2, 18,185,188,104, 23, 34, 41, 67, 69,155,117,238,220,185,117,131, 6, 13, 64, 41,197,230,205,155,161,211,233, 68, 58,157, - 14, 90,173, 22, 58,157, 14, 10,133, 2,187,118,237,194,250,245,235,111, 1,248,181,204, 74,204,160,189,124,225,210,213,122,195, - 6,116, 20,156, 61,189, 2, 6, 45, 11, 21,113,131, 82,169, 71,182,214, 12,172,237, 64, 32,241, 12,120,124, 9, 26,214,168,130, - 19,135,143,234, 96,208, 92, 41,175, 16, 82,171,213,136,137,142, 68,108,120, 40,228,138,247,176,183, 48, 67, 78, 68, 40,106, 14, - 26, 12,173, 86, 91,102, 26, 13,169, 69,244,203,219,129,191,226, 43, 6, 66,185,173,174,225,180, 11, 37,138, 60,185, 92, 94, 46, - 11, 71,106,106, 42, 78,157, 58,133, 6, 13, 26,160,121,243,230,136,139,139, 67, 68, 68, 4,218,183,111, 95,112,205,211,167, 79, -241,248,241, 99,120,122,150,110, 20, 76, 73,211,159,141,141,121,210,171, 75,151, 46,194,187,119,239,130, 82, 10, 47, 47, 11, 88, -152,203, 64, 24, 49,252,252, 28, 0,228,106,255, 22, 45, 90, 64,161,136, 48,164,167,211,179,101,196,229, 94, 66,200,113,173, 86, -251,166, 89,179,102, 46,225,225,225,152, 56,113, 34,255,192,129, 3,249, 38, 99, 4, 5, 5,125,112,143, 74, 85,114,215,188, 79, -117,223,239,171, 24,172,155, 75,164,149, 42, 91,216,213, 64, 21,175, 86, 0,128,182, 29,135,161, 74, 85,119, 40, 82,158, 85, 86, -171, 34,187, 9,249,233,214,207,214,196,133, 72, 59, 84, 27,170, 78,186, 30, 6,192, 24,199,189, 84, 21,118, 32, 49, 90, 48,240, -224,241,147,231, 70,182,239,216, 89,160,103, 13,134,106, 21, 5, 86,135,142,157, 73,138,139,138, 94,141,232,243,193,127,216,251, - 74, 21,201,172, 66,161,128, 76, 38, 67,112,112,176,166, 67,135, 14, 98,134, 97,240,230,205,155, 2,129,229, 96,103,227,223,184, -110, 53,223,133, 43,119, 93,144,137,197,226,118, 45,234,248,133,132, 69,197, 82, 74, 34, 75,226,213,234,245,151, 94, 60,121,218, -178,130,115, 85, 94,252,141,187, 48,107,210, 30, 26, 13, 3,181,150,131,198, 0, 24,120, 66, 88, 6,214,135,212,195, 15, 20,192, -131,187,183,244, 26,189,254,130,169,142, 49,193,132,255,180, 21,139,150, 38,142,242,254,167, 1,136, 92,178,100, 73, 74, 33,235, - 82, 50,128,167, 0, 2,243,174, 75, 46,114, 95, 50,114,103, 3,214, 45,196,147, 92, 72,104, 21,254,175, 45,114,205, 71, 53,252, -202,116,211, 0, 0,118,118,118, 14,181,106,213,241,220,178,237, 32, 40,165,120,253,120, 57,210,147, 94, 97,246,226, 59,158,110, -110,110,205, 99, 99, 99,111, 24,105,237, 56,176,125,251,246,201,245,107,215,170, 85,217,205, 13, 79, 35,223, 65, 72, 89, 8, 89, - 22,140, 78, 3, 62,171,133, 91, 53, 22, 12,145, 35, 62, 62, 19, 75,247, 30, 12,102, 89,246, 64, 89,188, 1,237, 59, 99,121,124, - 38, 8, 33, 88,212,160, 26,196,114, 57, 68,114, 57, 38,156,186, 90, 32,170, 78,204,159, 14,177, 76,142,170, 13,202,118,224, 78, - 41,205, 49, 55, 55,127,248,252,249,243,186,213,170, 85,195,228,201,147, 17, 25, 25, 9,142,227,144,152,152,168, 78, 72, 72,136, - 75, 78, 78,142, 4,112, 12,192, 22, 99, 60,133, 11, 53,234, 85,167,143,236, 28,211,176, 73,115,187, 46,221,214,227,248,225, 73, -200,200, 84, 32,199, 32,133, 82,109,128, 82,195,131,141,109,117,212,175, 81, 3,241,113, 73,120,113,247, 66, 54, 95,147,179,188, - 60,214, 43,134, 97,240,244,233, 83,120,184,152, 35,244,183, 27,176, 51, 19, 32,208,197, 9, 46,141,155,228,207, 30, 44, 19,122, - 22,252,201,203, 11,252, 96, 9,173,172,172,144,153,153,249,129,144, 51, 51, 51,131,139,139, 11,210,210,210,176,105,211, 38, 0, -184,101, 12,181, 86,171,133,175,175, 47, 30, 60,120,128,203,151, 47,163, 85,171, 86,104,222,188, 57,158, 61,123,134,139, 23, 47, -226,241,227,199, 32,132,192,214,214, 22,250, 92,171,164,190, 36, 50,157, 14,135,126,252,105,251,140,149, 43,215, 7, 12, 24, 48, - 0, 71,142,236,199,176,161, 62,121, 3,219,197,232,220,201, 7,243, 23, 60, 64,253,250, 45, 96,103, 39,192,202, 21, 39,222,170, - 84,236, 46, 35,194,185,240,226,197,139, 46,106,181, 26, 25, 25, 25, 84, 46,151,147,212,212, 92,119, 84,197, 89,176,114,114,114, - 36, 37, 17, 61,127,244,114,121, 70, 22, 77,167,217,143,187,165, 25, 30, 87,111,213, 46, 6,109, 59, 14,197,165,211,191,226,234, -133,203,176,225, 71,190,131, 44,235, 92,202,187, 20, 69,130,210,107,163, 95,237,175,121,177,202, 11, 27,199,117,177,230, 57, 59, -115,135,130,214,103,102,148,146,222,148, 16, 66,210, 66,118,159, 60, 70,209,185, 81,195,250, 85,171,185, 59,139,210, 83,146,232, -225, 19,231,130,117,239,142,156,202, 23, 86,101,173,138, 64, 41,157, 31, 20, 20,244, 67,222,255, 29,179,102,205,250,122,233,210, -165,246,239,223,191, 47, 24,131,149,148,146,118,181, 81,135,177,108,106, 70,166,118,251,202,169, 61,165, 18,177,104,214,210,237, -215,245, 60,220, 45,137,215,192,113,235,186, 77,152, 61, 62,236,245, 99, 87, 59, 51, 17,110, 5,205, 65,248,229,107,208, 49, 66, -180,187,120, 15, 90, 29, 11, 69,114, 42,174, 13,255, 14,150, 78,214,216,112,237, 72, 34,199,113, 27, 76, 85,140, 9, 38,252,119, - 81,138, 22, 41,110,140, 75,162, 17,215, 61, 48,130,231, 47,129, 81, 83,234, 82, 82, 82,146,110,222,188,135,235,167, 23,226,198, -233,133,120,241,248, 41,226,227,180,136, 75, 84,195,194,194,226, 78, 41, 74,180, 77,209, 74, 33, 39, 39,167,251,172,217, 63,188, -151, 72,205,208,172,117,107, 56,217, 59,192, 76, 40, 0,207,192,129, 71, 4,200, 78,182, 66,232,179, 28, 76,219,190, 59, 41, 59, - 39,167,123,209,202,161, 40,103,161,227,185,221,130,230,230,121,155,197,135,221,133,230,185,131,220,249, 34, 81,113,131,225,255, -196,153,157,157,221,163,103,207,158,233,153,153,153,248,250,235,175,113,227,198,141,199, 23, 46, 92,176,120,250,244,169, 52, 41, - 41,169, 42,165,244, 11, 74,233,166,146,196, 85, 81,206,180,180,240, 44,106,208,244, 89,242,195, 4,149,218, 96,139, 94,131, 15, - 64,198,196,192,192,114,160, 0, 92,108, 68,104,220,102, 1,146,180,141,112, 96,227,162, 28, 78,167, 30, 80,216, 7, 86, 81, 78, - 74, 41,181,181,181,253,224, 93, 24,134,193,245,235,215,209,171,103, 15,180,235,214, 21,246,149, 61,224,208,166, 61,218,125, 61, - 10,155, 54,109, 2,195, 48,176,177,177,249,192,162, 81, 82,124,230, 35, 61, 61, 29,149, 42, 85,194,189,101,237, 3,206, 77,242, -173,229, 30,254, 75, 45,179, 39, 63, 7,156, 56,113, 2, 65, 65, 65,217, 79,158, 60, 89, 1, 96,138, 17,105, 52,115,252,248,241, -170,176,176, 48,200,100, 50, 24, 12, 6,220,186,117, 11,235,215,175,199,207, 63,255,140,199,143, 31,195,214,214, 22,158,158,158, -208,104, 52,120,240,224,129, 10,192,204, 82,242, 18,151,156,108,232,177,102,205,210,212,142, 29,155, 98,251,246,181,112,114,106, - 4, 1,223, 9,124,129, 61,100,114, 95,108,221,242, 35,190,250,170, 22, 78,158, 56,152,150,146,106,232, 81,212,235,122, 9,225, - 84,223,187,119, 15, 27, 55,110, 68,207,158, 61,227,122,245,234,197,102,102,102, 22, 88,176,242, 87, 73,159,155, 55,134, 76,163, -209,136, 75,226,252,122,234,243,184,239, 23, 6,207, 79,124, 31,215,224,198,181, 59,253,175, 94,184,140,183, 97, 87,113,245,194, -101,252,118,245,118, 80,226,251,184, 6,181,234,121, 11,187,127, 61,230,251,157, 71,143,240,228, 22,206,216,121,244, 8,175,223, -216, 9,139,234,180,107, 53,211,136, 52,162, 0,104,118, 82,226,244,197,203,127,201, 54,232,212,204,178,213,235,226, 85,201, 9, - 51,145, 63,181,178, 4,235, 85, 97,206,156,156,156, 77, 42,149,202, 69,165, 82,185,168,213,234,153,145,145,145,205, 38, 79,158, -156,204,178,108,129,176, 78,122,113,226,206,203,223,126, 93,236, 96,103, 45,109, 84, 55,192,103,197,166,195,215,163, 99, 18,247, -228,251,192, 42, 33,141,212,217, 42,117,143,174,221, 7, 42,211,211, 52,240, 25, 31, 4,131, 88, 14,141, 1,208,113, 60,232,192, -199,227,133, 43, 96,110,107,142, 93,111, 31,229,100,232,117, 61, 10,251,192, 50, 38,127,126,100, 11,217,196,105,226, 52,113,254, - 13, 57,255,109, 40,211, 77, 3, 0,184,186,186, 54,235,210,185, 13, 90,116,156, 5, 74, 41, 94, 61,250, 9,233,201,175,225,234, - 36, 70, 68,180,162, 33,128, 27,198, 62,144, 82, 26, 77, 8,105, 48,126,230,172,163,189,190,104,237, 87,173,114,101,113,165, 74, - 21, 33,115,112, 64, 74, 74, 50,126,191, 27,162, 95,180,239, 80,112,158,184, 50,102,169, 28,112, 28,151, 59,120, 29, 64,187,137, -211, 64,120,188, 2,119, 12,249, 21, 98,149,122,141,192,227,243,193, 82, 14, 26,141,134, 26, 17,206, 88, 66, 72,143, 1, 3, 6, - 92, 57,125,250, 52,211,174, 93,187,154,199,142, 29,227, 62, 37,178,179, 19, 67,175,201, 29,189, 59, 46,154, 62,242, 64,131, 86, - 93, 45,188, 2,234, 8,235, 84,226, 65,167, 39,136,143,139,194,233,163,247,117, 33,247, 46, 40,168, 65,221, 71,153, 92,250, 82, - 57, 58,157, 46,218,209,209,209,113,222,188,121, 48, 24, 12, 48, 24, 12, 96, 89, 22, 41, 41, 41,184,115,231, 14,170,215,173, 15, -191,161,195,145,156,156,140, 53,107,214,192,205,205, 13,139, 23, 47, 70, 90, 90, 26, 12, 6, 67,137,241, 42,224,193,208,191,127, -127, 62, 0,136,248, 48, 76,169, 83,231,122,173, 90,181,154,116,180, 72, 18,206, 89,147,107,217, 26,255, 77,127,225,169,187,167, - 14, 1,216, 84,214,218,118,158,158,158, 34,181, 90, 93,211,217,217,153, 71, 8, 89,165,213,106,135, 76,159, 62,221,121,241,226, -197,240,241,241, 65, 74, 74, 10,100, 50, 25,188,188,188,144,156,156,140,251,247,239,179, 57, 57, 57, 27, 1,204,167,148, 38,151, -145, 70,111, 8, 33, 13,198,141,251,246,232,143, 75, 71,122,169, 53, 45, 68, 54, 54, 77, 64,169, 1,201,201,145,200, 82,220,210, - 45,152,255,107,120, 98,146,190, 59,165, 52,204,200,100,154, 51,102,204, 24, 32,111,169,156,136,136,136, 39,126,126,126, 94, 37, - 89,176,140,193,138, 67,177,106, 0,251,150, 77,108, 52, 81,145,242,204,203,134, 31,249,174, 65, 53,110,205,138, 67,177,234,121, - 19,173, 22,166, 68,222, 8, 77, 80, 94,216,184,243,232, 17,222,224,110, 61, 88, 55,121, 88,144,196,129, 30,110,213,169,204, 60, - 74,107,214,172, 89,129,144,180, 42, 73,169,175, 31, 14,251,122,100,111, 75,161,234,108,160, 91,170, 39,227, 94, 75,242,248,241, -227,119,198,174,233, 89,132, 55,148, 16,210,108,250,244,233, 23,138,186, 31, 73, 74, 73,187,218,176,227, 24,154,145,145,249, 36, - 41,228,196,115, 35,184,238, 19, 66, 90, 87,171, 94,235,200,143,139,151, 58, 6,140,153,204,143,191,121, 29, 96,245, 72,184,113, - 29, 66,137,150, 91,122,235, 82, 98,154, 78,215,205,228,197,221, 4, 19, 76,214,171,210,180,200, 63, 82, 96,149,133,216,216,216, - 27,158, 30,110, 23, 67, 67,155,125,225,238,102, 15, 0,136,120, 23,143,184, 68,205, 69, 99,187, 7,139, 17, 89,117,118,159, 58, -219, 71, 44, 22,119, 36,121,174, 24,232, 71, 44,246,108, 48, 24, 98, 43, 87,174, 92,194,217,241,197, 30,101, 89, 54,209,200,112, - 94, 39,132, 12,244,244,244, 92, 26, 21, 21,117,148, 82,170,252,212, 8,207, 78, 12,189,102, 99,227,233,113,251,242,145, 9,119, -175,159,110, 67, 13,218,234, 0, 64,248,162,114, 45,246,156,157,157, 61,114,244,232,209,155, 4, 2,129, 59,242,198,148,229,143, -135, 98, 89,150,167,211,233, 36, 44,203,242, 0, 16,134, 97, 12, 2,129, 64,125,244,232, 81,131,193, 96,136,214,104, 52, 35, 75, -226,221,241,152, 10, 10,239,111,207,109,169,200,188,170, 35, 59,255, 88,170, 10,160, 37,120, 92, 47,138,179,103,207, 86,178,182, -182,254,130, 16,210,147, 82,234,155,149,149,165,153, 61,123,246,237, 67,135, 14, 41, 42, 87,174,252,101,135, 14, 29,136,141,141, - 13, 30, 60,120, 64, 83, 83, 83, 15, 3,152, 73, 41,141, 40, 71, 94,138, 32,132, 4,142, 28,181,161,175,141,205,166, 14,148, 34, - 16, 20,132, 48,120,158,153,201,157,205,201, 97,247, 80, 74,217,114,240, 25,138, 88,206, 22, 4, 7, 7,255, 10, 64, 80,220, 24, -172,114,193, 44,251,164, 90, 21,217,131,200,115,142,173, 88, 29,171, 6,128, 57, 43, 51, 50, 1,108, 29,215,205,134,123,249,104, -235, 79,174, 22, 97, 83, 87, 31, 75,219,110, 12, 93,173, 90,181, 60, 24,134,233, 3,160,154,131, 56,163,170,189, 40,147, 37,132, -182, 36,132,177, 3,240,204,223,223,255, 52,128,216,143, 44,232, 66, 1, 84, 44,122, 60,233,197,137, 59, 0,238,148,147,235, 62, - 33,164,234,196, 41,147,190, 19, 9, 4,109, 9,203,214, 48, 28, 57, 68, 77,139, 61,155, 96,130, 9,255,122, 11,150, 49, 8,143, -136,109, 7, 0, 94, 94, 94,244,205,155, 55,159,172, 48,243, 4,212,126,148,225, 68,180, 44,164,164,164,212,249,139, 21,245, 62, - 0,251, 62, 39,103,158,128,154,159,183,125,108,184,158, 3,168,255,255,212,170, 80, 14,169, 69, 10, 44, 91, 2, 30, 12,198,222, -251,197, 23, 95, 68,233,116,186,203, 0, 98, 8, 33, 86, 0,210,116, 58,221, 5,189, 94,159, 72, 8,169,179, 98,197,138,124, 71, -170, 11, 40,165, 15, 63, 50,124, 28,128,189,121,219,231,126,247,189, 46, 46, 46,147,108,109,109, 61,213,106,181, 72,173, 86, 11, - 11,107,127,169, 84,154,108, 44,151,149, 57,217, 33,228,167,219, 90,153,147, 63, 9, 40, 27, 87, 28, 81, 41,131,125,108, 92,113, -196, 88,190,199,143, 31, 71,212,172, 89,115, 55,195, 48,149, 41,165,142, 0,181,164, 20,201,148,210, 20, 62,159, 31, 23, 18, 18, - 18,247,119, 41,104,242, 4,212,242,188,205, 4, 19, 76, 48,193, 36,176,138, 34, 44, 44,140,152,162,237,191,135,162,150, 45, 99, - 17, 25, 25,169, 1,112, 59,111, 43, 90,233, 62, 4,208,233,239,254,238,241,241,241,181, 62, 7,207,215, 83,159,199, 1,152, 80, -167,152, 37,151,231,172, 73,203, 2,240,125,203,206,229,227,124,242,228, 73, 52,128,104, 83, 14, 53,193, 4, 19, 76,248,123,129, - 49, 69,129, 9, 38,152, 96,130, 9, 38,152, 96,194,231, 5, 1, 80,236, 76,128,242,172,148,253, 49,179, 9,202,226, 55,113,154, - 56, 77,156, 38, 78, 19,167,137,211,196,249,239,227,252,207, 32,127,150,221, 95,177, 1,104, 99,226, 52,113,154, 56, 77,156, 38, - 78, 19,167,137,211,196,249, 95,219,248, 38,137,105,130, 9, 38,252, 87,113,248,240, 97,163, 22,253,236, 59,117,107, 71,185,220, -122,118,182, 34,115,233,254,229,195,142,229, 31,239,217,179, 39,107,138, 69, 19, 76, 48,161, 56,148, 40,176, 60, 60, 42,248, 51, - 44,215,152, 82,134, 71, 25,170, 39, 10,213,129,240,180,180, 15,220, 7,184,187,187, 91, 9, 24,116, 34,148,202, 8,225, 88,142, -199,220,138,136,136, 9, 49,230,193,132, 16,145,181,181,245, 24,145, 72,212, 70,167,211,185,241,120,188, 88,181, 90,125, 57, 59, - 59,123,109, 81,103,131,255,107,248,248,248,244,187,126,253,186, 85,147, 38, 77, 52, 82,169,212,160, 82,169,248,231,207,159, 23, -127,245,213, 87, 25,111,222,188,249,168, 25,134,174,174,174,173,182,110,221, 90,165, 93,187,118,168, 90,181,170,178, 79,159, 62, -194,134, 13, 27, 10,191,254,250,235,183,113,113,113, 87,203,195, 69, 8,241, 39,132,236, 34,132,240, 56,142, 27,148, 55,195,240, -179,131, 16,194, 0, 24, 1,160, 43, 0, 15, 0, 17, 0,142, 3,216,108,140, 55,251, 98,248,122, 0,104, 15, 32, 48,239,208, 83, - 0,103, 41,165, 71, 62, 33,140, 61, 0,180, 39,132,212,204,179,208, 62,249, 92,156, 2,129,160, 38, 0,232,245,250, 39,127,151, -112, 18, 66,134, 74,165,210,111, 0, 64,165, 82,109,161,148,254, 90,238,192,108,242,163, 0,224,255,211, 43, 0, 64,200, 84, 95, - 24,187, 31,242,182,156,179,137, 75,120, 22, 70,190, 36,159, 16,151,237, 7, 12, 24,176,120,207,158, 61,115, 40,165, 39,254,138, -188,239,228, 84, 97,237,207,171, 55,187, 76, 24, 51,124, 41,114, 87,112, 40, 79,248,248,214,214,214, 93,164, 82,105, 93,173, 86, -235,192,227,241,146,212,106,245, 3,133, 66,113,130, 82,106, 32,132, 16, 63,224, 11, 17,195,248,104, 57,238, 86,200,199,204,166, -125, 69,172,117, 57,112, 34,220, 31,235,176, 81, 6, 26,161, 25,222,195,151,166,151,118, 43,143,199, 91,238,234,234, 58, 34, 35, - 35, 35,155, 97, 24, 74,114,145, 23,244, 2,103,205,132,227,184,184,180,180,180, 58,255,171,114,152,199,227, 77,112,113,113,233, -166, 80, 40,114,120, 60, 30, 45, 20, 62, 2, 0, 12,195, 16,142,227,146, 82, 83, 83, 7,153,170,118, 19,254, 54, 2,171,144, 91, -250, 22,148,210, 27, 30, 30, 21,252,123,118,237,190,120,212,200,209,132,199, 99, 16,252,226, 5,191,255,160,161, 95,216,216,216, -184,202, 53, 26, 63, 16,194,229, 72, 36,193,122,189, 46,238,208,190, 61,230,190, 62, 62, 44,203,114,216,184,105,195, 87, 30, 30, - 21,102,148, 37,178, 8, 33,222, 78, 78, 78,187,102,204,152,225,212,185,115,103,158,139,139, 11,162,162,162,172,246,237,219,231, -187,106,213,170,222,132,144, 65,121,126,120, 62,166,176,109,234,100,195,124, 97, 46, 37,173,145,197, 34, 75,143, 43,239, 85,184, - 72, 41,253,237, 99, 35, 41, 39, 39,103,108, 78, 78, 78,253,186,117,235,210,109,219,182,145, 33, 67,134, 80, 66, 8, 81,169, 84, - 59,240,145, 46, 28,100, 50,217,186,118,237,218,121,121,121,121, 69,132,135,135,183, 63,120,240,224,217,193,131, 7,123,200,100, -178, 48, 0,222,229,164,251, 53, 53, 53, 53, 80,165, 82,193,205,205,109, 27,128,218,127,129,184, 34, 0,142,216,216,216,168,231, -207,159,191,165, 69,139, 22,174,241,241,241,236,180,105,211, 26, 63,121,242,228, 75, 66, 72, 87, 99, 69, 22, 33,196, 26,192, 70, -185, 92,110, 54,109,218,180,155,109,219,182,125, 39,151,203, 37,207,158, 61, 19, 76,155, 54,109, 4, 33,164, 23,128, 81,148,150, - 94, 49, 20,199,105,111,111,111, 53,103,206,156,231,141, 26, 53,186, 33, 20, 10,133,175, 95,191, 22, 4, 5, 5,125,247, 41,156, - 94, 94, 94,230, 63,252,240,195,131,154, 53,107, 38, 74, 36, 18, 97,120,120,184, 96,198,140, 25,163,120, 60, 94, 47,142,227, 62, -138,211,198,198,198, 98,198,140, 25, 15,155, 55,111,158, 44, 22,139, 69, 33, 33, 33,252,233,211,167,143, 42, 79, 56,109,109,109, - 91,218,218,218,110,126,255,254, 61, 31, 0,156,157,157,235,121,122,122,254, 82,120,125,200,124,151, 18,122,189, 62, 75,173, 86, - 15, 72, 77, 77,253,147, 3, 91,255,159, 94,225,251, 31,118,244,251,254,135,220,253,157,121,199,203,218, 7,134, 24,157,247,253, -171,228,150, 49,223, 77, 89, 63, 48,247, 55,247,248,134,188,160,174,171, 66,104,121,196, 26, 33,164, 75,171, 86,173,230, 94,189, -122,117, 67,139, 22, 45,166,237,222,189,219, 33, 38, 38,230, 71, 66, 72,133,190,125,251, 14,185,114,229,202,146,228,228,228,195, -159, 43,255,139,132, 98, 49, 97, 8,164, 18, 51,139,114,126, 55,174, 78, 78, 78,115, 39, 78,156,104,215,189,123,119,198,221,221, - 29,225,225,225,214,123,246,236,169,186, 97,195,134,118,132,144,121,190, 64,205,169, 53,106, 12,237, 91,165, 74,187, 70, 39, 79, -206, 2, 80, 62,129,245,138, 88, 43, 51, 80, 93,163, 69, 45, 74, 97,245,199,179,145, 33,214,225,177,236, 21,121, 94,146,200, 34, -132,172,236,210,165,203,160,227,199,143,203,119,239,222, 45,111,212,168, 17, 28, 29, 29, 65, 8, 1,203,178,224, 56, 14, 28,199, -229,173,245,233, 85,110, 17, 92,155, 16, 11, 14,152, 34, 37,104,165, 1, 9, 0, 0, 49,232, 11, 21,197, 85, 6, 88,254,168, 12, - 71,197,133,194, 57,169, 91,183,110, 29,142, 30, 61, 42, 61,116,232,144,180,110,221,186,112,114,114, 2,128,130,240, 81, 74, 81, -165, 74, 21, 83,173,254, 15, 70, 81, 45,242,175,177, 96, 21, 94,193,154, 97,185,198,163, 70,142, 38,125,250,245,125,255, 38,226, - 45,199, 23,136,250,157,191,112,193,204,223,223,159,209,172, 93, 11, 67,114, 50,244, 19, 39, 54,186,124,249,178,190, 87,191,129, - 42, 1,143,252,234, 81,165,178,217,129,125,251,157,142, 30, 57,220, 24, 64, 72,105,150, 43, 39, 39,167, 93,215,175, 95,119,245, -242,242,130, 86,171, 69, 74, 74, 10, 40,165, 24, 56,112, 32,191,121,243,230,174,157, 59,119,222, 69, 8,105, 82, 30, 75, 22, 33, -196,177,170, 27,255,244,207, 63,244,246,254,234,139,198, 50,215, 10,158,160,239,213,136, 9,127, 85,247,244,245,187,227,188,172, -152,208, 55,153,180, 35,165, 52,177,188,145,148,146,146, 50,181, 91,183,110, 71, 90,182,108,105, 47, 22,139,225,226,226, 66, 58, -119,238,156, 20, 31, 31, 63,239, 19, 50, 18,242, 90, 93,108,225,223,162,203,248, 24, 9, 55,107,107,107, 88, 91, 91, 3,128,235, -167,100,136, 94,189,122,241,162,163,163,191,225, 56,206,175,240,113, 7, 7, 7, 31,150,101,211,163,162,162,125, 84, 90,157,223, -232, 49, 51,230,246,233,217,198,234,246,237,219, 92,187,118,237, 52, 55,111,222, 28, 1, 96,163,145,143,217, 88,163, 70,141,240, - 85,171, 86,105,194, 34,222, 85, 14,126, 25, 6,153, 68,200, 86,168, 80, 65, 28, 18, 18,162,153, 61,123,182,114,245,234,213, 27, - 1,244, 42, 71,208, 55,126,245,213, 87,233,179,102,205, 74, 10, 13,127,231,252, 52, 36,148,202,197, 66,189,163,163, 3,239,225, -195,135,234, 31,127,252,145, 91,178,100, 73,185, 57, 7, 14, 28, 24, 63,109,218,180,119,201,169, 25,174,233, 25, 89, 84,148,147, -163,115,115,115,227, 95,187,118, 45,123,253,250,245,154,105,211,166,149,155,179, 69,139, 22,239, 23, 44, 88, 16,253, 42, 44,194, -229,113,240,107,200,197, 2,189,147,147, 3,239,241,227,199, 57, 75,150, 44,209,253,244,211, 79, 70,113,202,100,178,157, 7, 15, - 30,228,159, 56,145,107,180,185,115,231, 14,227,225,225, 97, 86,248, 26,149, 90, 3,134, 0, 41, 41, 41,102, 13, 27, 54,220, 9, -192,173, 36,190,193,131, 7,191, 47, 79, 94, 25,172,249,201,184, 11, 55,249,209,124, 97, 53,122,244,232,146,124,115, 13,244, 47, -135,200,106,223,190,253,204, 51,103,206,120,238,222,189,123,197,222,189,123,181, 0, 32,145, 72,236,246,239,223,191,164,119,239, -222,232,221,187,247,108, 0,159, 77, 96,177,148,213, 1,128, 88, 34, 22,191,122,245,138,248,250,250, 82, 35,190,113,129,163,163, -227,188, 75,151, 46,217,251,251,251, 67,171,213, 34, 53, 53, 21,124, 62, 31, 35, 70,140,224,181,104,209,194, 97,104,231,206,219, -191,247,240, 80, 15,244,244,108,191, 59, 60,252,116,142,193,240,212, 24,107, 83,102,102,102,118,190, 21,199,175,178, 57,191, 89, - 77,131,184, 70, 85,189, 72,200, 51, 8, 59, 77,228,200,197,181, 68,233, 91, 5,191, 3,128, 48, 7,201, 66, 32,189,152,240,253, -212,165, 75,151,222,199,143, 31,183, 6,128,195,135, 15, 35, 39, 39, 7, 21, 43, 86,132, 80, 40,132, 64, 32,128, 64, 32, 40,248, - 95,222,178,201,159,144,118,102, 60,102,247,164,174,157,204,235,249,250, 8,157,204,229,224,178, 20,136, 12, 15,111,112,245, 85, - 88,173,125, 47, 94,141,246, 39,100, 64, 8,165, 23,202,136,199,113, 93,186,116,105,123,244,232, 81,243,252,112,234,245,122,120, -120,120, 64, 40, 20, 66, 36, 18, 21,132,211,132,127, 62, 10,107,145,127,141,192,202,123,161, 22,185, 47,200,240,120, 60, 6,111, - 35, 34,245, 45, 91,182, 30,182,123,207, 30,177, 88, 44,206, 45, 32,174, 94, 5, 85,171, 97, 37,151,163, 91,183,110,130, 90,181, -106, 89,116,239,220,249,235,119,111,223,109,226,241, 24, 39, 74,153, 82,199, 52, 88, 91, 91,143,153, 49, 99,134,147,151,151,215, - 7, 45,108,131,193,128,212,212, 84, 88, 89, 89, 97,248,240,225, 14,235,215,175, 31, 3,224,103, 35,197, 74, 37,111, 15,135, 91, - 87,143, 45,118,118,182, 21, 0,201,135,129,152,181,192,137, 44,248,217, 85,129, 95,215,118,178, 62, 45,106,214,106, 59,117,221, - 99, 66, 72, 99, 74,105,100,121, 34, 73,173, 86,255, 78, 8,249,154, 97,152, 19, 0,152,107,215,174,209,151, 47, 95,142,164,148, - 70,125,108,196,115, 28,135,140,140, 12,112, 28,199,203,219,207,255,253,159,101,134, 94,189,122,241, 98, 98, 98, 70,250,249,249, - 85,221,178,101, 11,146,146,146, 32,149, 74,193,178, 44,106,214,172,233,222,190,125,251,208,228,212,140,186,122,131, 94,155, 16, - 27, 94,111,255,230,200,156, 64, 47,175,219,123,246,236,169,227,230,230,214,213, 24,129, 69, 8,233, 33,151,203,165, 43, 86,172, - 80,154, 91, 57,117,169, 87,223, 69,240, 60,228,117,164, 80,204,231, 50, 51, 21,169, 79,159, 62,125,181,108,217,178,166,151, 46, - 93, 82, 17, 66,122, 24,211,101, 70, 8,233, 97,103,103,103, 57,115,230,204, 68,169,185, 93,211,186,245, 29,248,193, 33,111,226, - 4, 66, 70,223,184,113,227,150,119,238,220,249,117,206,156, 57, 53, 46, 94,188,200,150,135,179, 74,149, 42,230,211,166, 77,123, -107,105,101,215,214,222,201,133,103,111, 99,229, 9, 0, 17, 17, 17,187, 19, 19, 19,195, 38, 77,154, 84,247,252,249,243, 40, 15, -167,181,181,181,249,130, 5, 11,162, 42,123,248,244,244,240,242, 97, 46, 95,191,247, 92, 36, 98,244, 42,149, 42,237,229,203,151, -111,230,207,159, 95,231,242,229,203,212, 24,206,156,156, 28,129,157,157, 29,172,172,172,192,169, 84,200,204,204,196,209,163, 71, -145,149,149, 5,150,101, 33,149, 74,177,104,197, 38,132, 7,223,197,111,191,253, 6,133, 66, 81,172, 47,179,144,169,190,133,172, - 82,159, 25,155,252,232, 6,110,204,192, 82,132, 21, 10, 9,175,129,216,228, 71, 75,235, 46, 44,100,185,122,181,123,247,110, 95, -127,127,127,180,107,215, 78, 4, 0, 99,198,140, 17,181,111,223, 30, 7, 15, 30,196,225,195,135, 67,188,189,189,111,133,133,133, - 45, 55,166,219,112,208,160, 65, 77, 52, 26,205, 34, 0, 50,134, 97, 30, 89, 88, 88,204,219,180,105, 83,124,254,249,132,248,216, -135, 90,173,182, 83, 96,173,186,102, 11,182,109, 31,176,255,103,223,221,101,113, 90, 89, 89,117,159, 58,117,170,141,191,191, 63, - 10,127,219, 28,199, 33, 62, 62, 30,175,239,222,117,156, 94,187,182,203, 32, 59, 59,199,221,225,225,167,126,124,246,236,215, 87, -192,181, 82,222,125,101,183,110,221, 6, 29, 61,122, 84,126,232,208, 33,121,221,186,117,115,173, 77,234,167,208, 36,159,192,195, - 27,235, 17, 30,149,187, 62,250,187,120,200, 0, 52,169,233,131,167,133,187, 13, 63,104,149,185,185,141, 56,126,252,184, 69,161, -178,249, 3, 65, 85,244, 63, 24,202,216, 4,144,237,230, 85,208, 62, 51, 2, 75, 50, 66,232,170, 82,196, 85,139, 10,246,118,199, -182,125, 63, 81,226,148,158, 2,156, 59, 6,196,197, 2, 28,139, 0, 75, 43, 4, 56,185, 8, 91, 53, 8,180, 25,243, 40,228,136, - 63, 33,157, 66, 40, 45,241,189,221,220,220,186, 29, 63,126, 92,150,191,111,103,103, 7,137, 68,242, 39,113, 37, 20, 10,193, 48, - 38,207, 67,255, 18, 43, 86,139,127,195,187, 48,133, 85, 35,128,235, 0, 64, 9, 81, 62, 11, 14, 22,240, 68,162,129,123,246,238, - 21, 11,133, 66, 68, 69, 69, 33, 36, 36, 4, 57, 87,174, 64,117,251, 54, 18, 19, 19,145,157,157, 13, 71, 71, 71,108,218,182, 77, -166,101,233,176,215,161,161, 60,202, 80,125, 33,206, 63, 77,213, 20,139,197,109,186,119,239, 94,162, 8, 75, 76, 76, 68,231,206, -157, 5,124, 62,223, 40,247, 17,132, 16,226, 98, 79, 78, 93, 57,178,192,217, 89, 20, 2,188,153, 4,100, 61, 6,168, 6, 48,104, -129,184,231,192,153,121,168,152,253,138, 92, 88, 48,216,201,213,140,127,138, 20,105,138, 25, 49, 77,213,195,215,215,119,235,192, -129, 3, 25, 0,104,213,170, 21,241,245,245,221, 76, 8,241, 40, 69,133, 95, 46,163,114,188,155,158,158,142,222,189,123,219,122, -122,122, 94,238,221,187,183,109,254,241,143,229,204,131,109, 64, 64, 64,170, 84, 42,221, 71, 8, 17, 27,209, 90, 40,224,140,142, -142,254,198,215,215,183,234,150, 45, 91,120, 60, 30, 15, 91,182,108,193,129, 3, 7,240,251,239,191, 35, 53, 53, 85, 62,105,210, - 36,203,211,151,239,158,191,245,251,253,147,203,103, 77,177,237,214,186,133,135,117,102,178,194,213,213,181, 13,114,199,100, 25, - 19,206,246, 99,199,142,189,248,228,101,132, 3,195, 23, 8,197, 66,129,212,222,206,170,162,147,189,117, 85, 87, 91,235,170,230, - 34,129,149, 66,161,120,123,240,224,193,108,228,142,207, 50,138,243,135, 31,126,120,250, 42, 34,198,150,225,241, 5, 2,158, 64, -100,101, 41,183,237,220,241,139,150, 0, 32,229, 17,177, 66,161,136,217,185,115,167,178, 60,156,179,103,207,190,147,144,156,238, - 32, 16,138,248, 98,161, 64, 82, 80, 17, 89,200, 29,101, 98,177, 52, 39, 39, 39,106,235,214,173,153,229,225,156, 62,125,250,131, - 23, 97, 81,118,132, 1,143, 1, 17, 88, 91,155, 59,216, 91,153, 59, 57, 88,200,157, 36, 12, 36, 10,133, 34,114,231,206,157, 10, - 99, 56,117, 58,157, 32, 41, 41, 9,175, 94,189, 66,133,186,117,113,249,242,101,184,187,187,163,119,239,222,232,219,183, 47,164, - 82, 41, 90, 53,172,142, 25, 51,102, 32, 60, 60, 28, 6,131, 65, 84,206,188, 4, 23, 23,151,235, 37, 86,162,121,227,168, 74,226, -244,175, 66, 74, 21, 87, 69,185,139,187,174, 40,103,251,246,237,103, 94,185,114,197,115,215,174, 93,157, 7, 13, 26,244,251,174, - 93,187,208,160, 65, 3,188,124,249, 18,149, 43, 87,198,142, 29, 59,208,183,111,223,223,215,172, 89,211,249,209,163, 71,129, 85, -170, 84,153, 81, 22,103,159, 62,125,190,171, 89,179,230,213,247,239,223, 55, 76, 75, 75,171,118,244,232,209, 97,221,186,117,123, -219,175, 95,191,214, 5, 22, 44,189,126,239,153,147, 71,208,161,115,119,248, 4, 84,219, 56,100,198,238,234,101,125,155, 82,169, -180,110,239,222,189,121,197, 53,174,110,157, 57,227,104,247,244,169,235, 40,123,123,199,197, 47, 95,190,203, 19, 87,167, 10, 47, - 17, 86,152,147, 16,242, 83,215,174, 93,123, 31, 61,122,180,192,218,116,251,246,109, 60,127,254, 28,145,145,145,200,200,200, 64, -235,145,217, 24,189, 36,247,246,209, 75, 40,190, 24, 67,101,165,189,123,118,118,182,234,216,177, 99,232,213,171, 23, 70,140, 24, -129, 42, 85,170, 20,136,172,162,226,234,198,253, 75, 16, 85, 75,179,105,178, 25, 67,219,158,128,189,204, 13,211, 75, 76,119, 66, -100,102, 12, 57,176,113,242,120, 73,244,161,131,216,120,232, 36,174,188, 8, 3, 85,171, 0,173, 22,143,162, 19,113, 45, 49, 27, -210,168,104,252,236,229,110, 38, 97,152, 3,158,132,152,151, 20, 78,165, 82,169, 57,123,246, 44, 6, 13, 26,132,241,227,199,163, -106,213,170, 5,225,220,185,251,128, 93,223, 97,163,188,107, 55,105, 22,232, 95,187, 65,141, 44, 13,175,174,208,204,230, 27, 82, -140,185,237,175,112, 29, 96,226,252,107, 44, 88,249, 90,228,223,102,193,154, 7, 0,122, 14,167, 6, 14, 30,214,233,242,149, 43, -102, 34,145, 8,239,222,189, 67, 98, 98, 34, 14,236,219,199, 30,114,112,200, 17, 8, 4,116,192,175,191,154, 15,255,230, 27, 34, - 16, 8,224,235,235,139,158, 61,123, 74,123,244,238,151,100, 47, 16, 28, 40, 67,172, 56, 59, 57, 57, 97,250,244,233, 88,178,100, -201, 7,231,134, 12, 25,130, 85,171, 86,193,202,202, 10, 12,195, 56, 25,107,120, 25, 55,175,171,155,117, 21,171, 68,250,120,167, -128,240,204,108,192, 51, 3, 24, 33, 32,225,229,138, 44,134, 7,205,163,171,105, 76,131,131,138,238, 77,115, 92, 87,159,223,212, - 11,192, 65, 99, 35,201,197,197,101,246,213,171, 87,237, 39, 77,154, 68, 21, 10, 5, 73, 72, 72,160,139, 23, 47,182,255,238,187, -239,102, 3, 24,252, 49, 17, 31, 31, 31,191,160, 67,135, 14,237,206,156, 57,227, 56,120,240, 96, 75, 0,232,208,161, 67, 98,124, -124,252,130, 79, 73, 80,161, 80,200,123,241,226,133,205,138, 21, 43,250, 78,158, 60, 57,160, 90,181,106, 78, 25, 25, 25,145,113, -113,113, 61,203,178,184,113, 28,231,183,101,203, 22,240,120,185,117, 2,195, 48, 16,137, 68, 16,137, 68,176,176,176, 72,143,136, -136,224, 42, 57, 74, 69,202,196,132, 76,107,190,181,128, 56, 59,217, 90, 57, 57,183, 72, 77, 77,189, 7,192,210,200, 32, 6,126, -249,229,151,207,110, 63,121,195,142, 30,210,170,170,153,144, 17,152, 75, 37, 60,169, 72, 64, 8,165,172, 78,175,109,184,110,231, -181,237,222,222,222,254,198,154,136, 9, 33, 53, 27, 52,104,112,229,201,203, 40, 60,125, 17, 17,107,111, 99,102,251,101,171,198, - 62,249,231,107,212,107,208,183,208,229, 25, 70,125, 24,124,126, 96,221,186,117, 99, 19,211,148,112,176,179,252, 64, 72, 91,219, - 57,180, 1, 0,101,102,230,186, 10, 21, 42,248,242,249,252,202,198,134,179,105,211,166, 9,143, 66,162,225,100,111, 99,147,119, -248,131, 49, 61, 41, 9, 9, 27,189,188,188,124, 9, 33,149,202,226,211,106,181,226,227,199,143,227,209,163, 71, 88, 16, 16,128, -239, 43, 85,130,189,189, 61,174, 92,185, 2, 74, 41,228,114, 57, 50, 50, 50,112,240,224, 65,180,110,221, 26, 90,173, 86, 86,146, - 80,202, 31, 95, 85,146, 16,138,143,143,255, 75, 90,148, 69,185,253,127,122,133,144,145, 37, 95,127,246,236,217,221,187,119,239, - 94,226,239,239,143, 9, 19, 38, 52, 89,181,106,213,239,213,170, 85,107,210,170, 85, 43, 92,189,122, 21,195,134, 13,251,125,205, -154, 53, 77, 70,141, 26,133,141, 27, 55,226,237,219,183,219, 74,123,126,159, 62,125,230,126,253,245,215,179,214,174, 93,155,107, -165, 1,208,181,107,215,252,178,113,123,175, 94,189, 82,243,175, 61,180, 53,246,118, 21, 15,175, 70,223,141,155, 34, 26, 51,106, - 80, 16,128,190,101, 84, 20,246,206,206,206,152, 61,123, 54, 22, 44, 88, 80, 96,177,191,122,244,168,163,225,236, 89,215, 94, 85, -171, 58, 28,103,152,164, 77, 49, 49,113,113, 69,196, 85,113,214,166, 99,199,142, 21,228, 21, 91, 91, 91,136, 68,162, 92, 17,196, - 23,128,199,242,112,121,163, 12, 17,209, 57, 24,189,132, 98,195,116,130,202, 46, 80,214,244, 41, 53, 63,162,113,227,198, 80, 40, - 20,224,241,120, 48, 55, 55,135,141,141,205, 7,226, 74,145,157,129,101,219,230, 34,201,231, 58,218,158, 4, 67,120,192,211, 69, - 64,214,155,146,151,116,226, 1,227,134,183,107, 99, 89, 65,149,141, 75,201,233, 24, 21, 21,131,231, 27, 54,224,218,132,239, 32, - 5,133,229,188, 37,168, 29, 20,132, 7,222, 94,168, 43,230,161,181,157,149,249,197,148,140, 9, 40, 97,233, 48, 66, 8,234,212, -169, 3,181, 90, 13,129, 64, 0, 11, 11, 11,104,117, 6, 65,175,129, 35, 60, 42,122, 86, 19, 47, 94,190,152,113,180,225,131,207, -216, 32, 44, 74,101,185,122,229,194,213,119,127,187, 57,156,152,217,117,163, 57, 41, 9, 38,155,208, 63,210,130, 53,239,223,240, - 46,252, 66,138, 17,133, 44, 25, 25, 54, 54, 54,174, 62, 62, 62,140, 86,171,205,237,122, 56,124,152,221,186,125,251, 25,181, 90, - 61, 14,128,112,237,250,245, 27, 93,221,220, 90, 14, 28, 52,136,232,245,122,116,232,208, 65,116,250,244,105,219,240,196,196,172, - 50, 34,175,224, 89,223,126,251, 45, 86,172, 88,145,111,162, 47,184, 70,175,215,195,216,202, 85,110,137,246,237, 58,214,177,136, -145,253, 98,161,107,164,207,174, 20,110,126, 87,150, 45,173, 3, 70,196,135,132, 7, 78,167, 55,132, 37,117,123, 24, 30,230,231, - 47, 77, 75,173,220, 38,160, 57,182, 94,218,213,190, 60, 2,203,204,204,172,158, 92, 46,199,195,135, 15,211,234,212,169,147, 65, - 41,181, 92,176, 96,129,157,153,153, 89,189, 79, 80,233,239, 8, 33,205, 26, 55,110, 60,134, 97,152, 54, 28,199, 93, 78, 76, 76, - 92, 75, 41,125,103,100, 38, 28, 13, 96, 14, 10,141, 51,209,106,181, 96, 24, 6,148, 82,244,233,211, 7,211,167, 79,247,127,254, -252, 57,174, 94,189,106,211,166, 77,155,187,132,144, 12, 0,195, 41,165, 37, 90,201, 82, 83, 83,177,113,227, 70,240,249,124, 88, - 89, 89,193,220,220, 28, 18,137, 4, 77,154, 52,121,191,116,233, 82,191, 35, 71,142,228,100, 36, 37, 17,105, 86,166,134,216,218, - 74,224,226,254,229,144,110,221,131,145, 59,155,208, 40,200,100, 50, 51, 17, 52, 89, 12,171,102,150,205, 93,199, 55, 19, 10,137, - 68,200,135,152,203,225,205, 88,186,144, 74, 8, 21,228, 89, 87,169,177,156, 18,137, 68, 40, 19, 81,141, 64,204,232,205, 24,250, - 89,250, 89, 69, 34,145, 80, 44, 80,170, 74, 20,179, 12,225,241,120, 60,113,121, 56,165, 82,169, 80, 46, 98, 53, 37,190, 7, 3, - 30,195, 48, 37,114,246, 10, 32,244,208, 24,223,252,221,130,176, 25, 12, 6,212,171, 87, 15,251, 79, 92,195,217, 43,183,145, 18, -245, 12,227, 70, 15,131,151,151, 23, 46, 92,184,240, 73,241, 16, 31, 31, 95,172,200, 42,152, 1, 88, 28,242,198, 93,149,213, 53, - 88,192,253,131,101,153,179, 18, 9, 33, 93,154, 54,109,250,221,222,189,123,181, 95,126,249,165,168, 79,159, 62,168, 86,173, 90, -147,161, 67,135, 2, 0,218,180,105,131, 85,171, 86, 53, 25, 58,116, 40, 14, 28, 56,128,163, 71,143,106, 90,180,104, 49,141, 16, - 18, 71, 41, 61, 91, 66,163,162,211,166, 77,155,138, 90, 6, 97, 48, 24,160,215,235,157, 13, 6,131,179, 94,175, 7, 33, 4,171, - 87,175, 73,185,120,225, 52,166,205,152, 7, 7,123,167,154,101,118, 15,228,117, 87, 25, 12, 6,140, 31, 63, 30, 75,150, 44,193, -249,253,251, 29,115,142, 31,119,157,230,233,233,112,208, 96, 72, 74,172, 86, 45, 46,231,210,165, 56,170, 84,150,154,215,149, 74, -165,234,236,217,179, 22, 7, 15, 30,132,149,149, 21,170, 86,173, 90, 32,134, 24,158, 20, 60,161, 53,124, 2,234, 1,184, 15, 0, -168,236, 2,165,111, 21,252, 78, 8, 50, 40, 3, 77, 41,249, 17, 78, 78, 78,224,243,249,120,242,250, 62,204, 51, 44, 80, 59,160, - 62, 4, 2, 1,178,148,153,248,110,121, 79,120, 45, 76, 70,117, 95, 64,149, 8,220,155, 4,253,251,219, 88,145, 19,131,117, 37, -126,223, 4,173, 27, 85,245, 16,226,250,101, 84, 74,140,197,131,165, 75, 81, 55, 40, 8,161, 0,104, 86, 22,124,166, 77, 67,220, -134, 13,176, 87,164, 2, 14, 21,209,218,197, 65,116, 43, 51,171, 13, 74, 89,155, 85, 38,147,193,213,213,181, 64,248,245, 25, 60, -202, 99,228,164, 81,210,110, 95,180, 4,159,111,135, 12,165, 30,169, 89,122, 88,219,201, 49,109, 82, 47,201,229, 58,174,117, 55, -173,217,115,146, 16, 82,183, 52,225,106,194,223, 11,159,186,198,241,223,214,130, 85, 20, 98,189,222, 71,179,113, 35,148,151, 47, - 67,116,241, 34, 14,186,184,100,171,213,234,201,148,210,152,188,194,110,194,175, 59,118,220,234,124,231,142,133,246,213, 43,120, - 60,127, 14,129,149, 85, 77, 99, 31,156,111,189,210,104,114,191,253, 93,187,118, 33, 51, 51, 19,153,153,153, 48, 24, 12,198,191, -128, 16, 77,156, 28, 42,227, 61,194,192,241, 25,121,164, 79, 78, 3,185,218, 60,222, 53,218, 81,153,201,184,226, 85, 84,125,153, - 42, 85,219,128,240,180, 80,167,228,192,181,113, 85,240,193,111, 82,158, 72,202, 47, 40,249,124,126, 90,104,104,104, 39,111,111, -239, 83, 0,236, 62,181,191,159, 82,250, 6,192,184,143,185,151,199,227,205,121,251,246,173,195,182,109,219,198, 44, 88,176,128, - 22, 22, 88,249,255,249,124, 62, 40,165,176,180,180,132, 64, 32,112,188,125,251,182, 99,253,250,245,215, 1,168, 89,138,152,132, -131,131, 3, 68, 34, 17,204,205,205,161, 84,164,203, 54, 44,158,213,194,204,218,209,102,202,148, 41,204,144, 33, 67,194,215,173, - 91,231,238,228,227,227,251,236,217,179,168,206, 61,123, 61, 58,123,246, 44, 0,108, 54, 50,232, 79,159, 63,127, 46,242,242,172, -196,231,244, 42, 78, 38, 4, 36, 79, 87,115, 34,115, 39, 72,120, 60,240, 9,168,212, 76,230,240, 38, 50, 50, 30, 64,146,145,241, -248, 36, 44, 44, 76,224,230,226,200,207, 82,170, 51,100,124, 78,244,246,193,253,151, 85,234,214,243, 3, 0,245,131,219,199,196, - 62, 1,230,111,147,146, 45, 60, 60, 60,140, 26,127,103, 48, 24,158,190,123,247, 78,232,234,234, 42, 8, 11,123,179,199,214,194, -220,197,198,209,177, 5, 0,104,211,146,111, 18,149, 58, 94, 32, 16,184,198,191,127,159,108, 48, 24,226,141, 13,103,104,104,168, -208,205,197,145,127,234,204,217,253, 78, 50, 51,103, 43,169,216, 82,194,128, 72, 40,151, 41, 50, 24,222, 75,205,100, 46,111,163, -163, 83, 40,165,177, 37,241,108,224,198, 12,204,205, 3, 83,182, 22, 62,254,251,239,191,227,218,195,183,176,228,177, 16,232,149, -184,123,244, 32,186,143,157, 88,230,247, 20, 50,213, 23,208,252,180,207,191,202,144, 15,132, 83,110, 23,160,115,177, 66,168, 76, -129, 85, 22, 54,249, 93, 47, 34,178, 16, 31, 95,122,225, 58, 96,192,128,121,187,119,239, 46,152,196,241,242,229, 75,180,106,213, - 10, 0, 48,111,222, 60,180,107,215, 14,245,235,215,199,203,151, 47,225,229,229,133,171, 87,175,138,121, 60,158,120,224,192,129, -139, 1,156, 45, 43, 72,155, 55,111,198,176, 97,195,138, 27, 48, 29, 14, 64, 77,172,125,179,167, 47,221,105,151,150,154,130,164, -228,247, 79,140,125,213, 5, 11, 22,128,227, 56, 28,221,186,213,209,246,201, 19,215, 33,149, 43, 59, 28,230,184,164, 48,119,247, -184,175,218,183, 79,196,154, 53,198, 52,168,254,100,197,177,181,181,133, 80, 40, 4, 79,224, 2,190, 40, 16,140, 80,136, 90, 77, - 3,177,124,178, 44,103,240, 87, 88, 67, 8, 50,196, 34, 60, 22,154,225,125, 73,156, 6,131, 1, 2,129, 0, 7,207,239,192, 51, -171, 61, 64, 22,112,235,113, 23, 76, 28, 54, 19, 83, 87,141,128,247,226,100, 88,122, 3, 73,119,129,251,147, 24, 46,243, 29,247, -181, 38, 25,231, 40,165,169, 37,133, 85, 15, 84,119,181, 48, 7, 98,163,209, 74, 12,252, 54,103, 58, 94, 0, 8, 8, 10, 2, 0, -196,109,216, 0,245,236,233,240,240,169, 4, 72,165,240,150,202,160,126, 30, 86,189,180, 70, 57,199,113, 5,227,172,118,237, 61, -100, 87,179,153,135,164,109, 19,127,236, 60,181, 8,223,246, 90, 3, 1,143,128,101,117, 88,177,170, 35, 88, 77, 54,122,117, 30, - 65,154,183,241, 10,188,124, 74,251, 53,128, 45, 38,233, 98,194,255, 2, 76, 94, 6,110, 78, 8,161,132,144,230, 5, 45, 59, 74, - 57, 67, 90, 26,104,158, 0, 18, 8, 4, 20, 64,225, 25, 74,102, 86, 86, 86, 68,224,230, 6, 34,206,109,112, 83,224,147,157,238, -241,249,124,176,172,241, 52, 28, 11, 30,136, 14,180,144,177, 67, 41, 33, 88,100,215, 26,227, 68,179,241, 94,100, 85,184,134, 3, - 12, 20, 44, 56, 94, 57,131, 69,149, 74, 37, 12, 6,131,181,167,167,231, 25,131,193, 96,157, 87, 97,254,207, 90, 70, 44,203, 70, -240,120, 60,140, 25, 51,166,192,218,167,213,106,241,254,253,123,104, 52, 26,104,181, 90,188,125,251, 22,153,153,153,208,106,181, -120,241,226, 5,170, 84,169, 2, 30,143,231, 92,106,124,114, 28,236,237,237,225,232,232, 8,141, 82, 33, 59,178,121, 85,135,159, -230, 78,183,235,231, 73,153,109,107,126,230,220,220,220, 82, 3, 2, 2,156,196, 98,177,174,118,237,218,154, 83,167, 78, 93, 4, -208,189, 28,126,176,206,206,159, 63,191,126,253,250,245, 43, 89,201,101, 58,177,136, 7,177, 65, 73,197,154, 84,202, 87,165,208, -138,110,149,116,144,201,235,245,233,211, 71,100, 76,165,152,207, 57,117,234,212,170,126,126,126,118, 86, 22, 50, 5,159, 65,156, -144,101,227,210, 31,222,190, 4, 0, 66, 59, 7, 21,100,242,122,121, 99,232,140,230,156, 54,109, 90,128,171,171,171, 45,195,144, - 12,131, 78, 23, 85, 80,224,171, 85,137, 60,177, 68, 9,177,164,233,240,225,195, 5,229,228,244,171, 81,163,134,173,181,165, 69, -134,128, 33,209, 66,214, 16, 35,165,108,172, 72,175, 75, 22, 59, 56,102, 67, 38,111,220,175, 95, 63,126, 73,156,249,214,171,162, -150, 33, 62,159,143,184,184, 56,228,196, 63,131, 48,238, 21, 2,229, 2, 52,112,178,131, 76, 38, 43,187,193, 50,242, 37,193,200, -151, 36,228, 45, 37, 33,111, 41, 41,188,255, 39,107,211,252, 76,124,112, 93, 9, 40, 58, 62,235, 79,226,170,200,189,121, 34,171, -212,239,105,207,158, 61, 51, 90,182,108,153,212,174, 93, 59,237,153, 51,103, 64, 8,193,213,171, 87, 17, 23, 23,135,118,237,218, -129, 82,138,187,119,115,141,179, 79,158, 60, 65,155, 54,109,180,205,154, 53,139,219,179,103,207, 28, 99, 18,103,216,176, 97,208, -235,245,200,206,206, 70, 90, 90, 26, 78,159, 62,141,192,192, 64,106,102,102,214,157, 87,225,139, 69,189,190,158,209,168, 90,141, -154, 88,183,102,185, 86,196, 23, 44, 45, 71, 99, 8,167,119,239,118,180,124,248,208,181,131, 86,235,112,130,199, 75,138,246,242, -138,107,212,190,125, 98,121,138,144,124, 43,142,155,155, 91,129,184, 18, 10,133,224,139,236,193,147, 85,135,200,182, 29,204,156, -186,227,218, 99,177,198, 82,134, 99,230,114,156,151, 89,225,121, 41,126,176,136,193, 96,128, 80, 40,196,245, 71,231, 16, 56, 19, - 8,156, 9,196,215, 59,129,190, 19,191,132,221,184, 80, 88,122, 3,239,127, 3, 50,150, 7, 66,255,214, 82,161, 73,198,193,210, -196, 85, 65, 57,146,145, 14,228, 13,234, 23, 22,105,201,243, 1, 8,120, 60, 16,169, 20,144, 72, 1,177,164,204,254, 10,150,101, - 11,198,131, 93,191,123,211,182,111,143,142,228,246,211, 75,104, 28,216, 15,169,217, 58, 36,102,234,144,145, 3, 4,212,157,133, -106,109,142,225,217,219, 44,212,172, 81,141,199, 19,201, 6,195,132,127, 12,138,211, 34,255,120,129, 5,224,122,209,129,101, 6, -177,248,133,225,187,239, 96,117,242, 36, 4, 97, 97, 24, 58,120,176,133,153,153,217, 26, 66, 72,109, 66, 72, 99,185, 92,190,110, -238,220,185,230,118, 75,150,192,229,230, 77, 68,158, 62, 13,189, 64,240,160, 60, 15, 87,169, 84, 5, 22,162,124, 75,150,149,149, - 85,185, 44, 88,172, 1,119,226, 18, 95, 65,132, 74,224, 64,179,207, 43,154,221,235, 23, 49,203,225,180,162,138,215, 27,165,208, -107,190,125, 3,135, 53, 21,155,220, 83, 18,126,182,200, 74,130,232,232, 24,176,224,238,148, 39,156,106,181, 58, 83,169, 84,162, -102,205,154,182, 15, 31, 62,244, 12, 12, 12,180,201, 59,126,255, 19, 51, 83, 67, 87, 87,215, 67,110,110,110,239, 92, 93, 93, 15, - 17, 66, 26,150,227,246,109,191,253,246, 27,120, 60, 30,230,206,157,139,172,172, 44,232,116, 58,164,166,166, 34, 58, 58, 26, 90, -173, 22,177,177,177,120,253,250, 53,180, 90, 45, 34, 35, 35, 11,226,184, 52,232,245,122,152,155,155, 35, 35, 53, 73,118, 96,195, -207, 29, 22,206,157, 41,205, 12,127,132,216,248, 68,112,172, 42,126,217,178,101,175,189,188,188,174,232,116,186, 10, 28,199, 53, -167,148,110, 50, 86,104,230, 57, 42,253,221,215,215,183,254,178,101,203,154,207, 94,186, 85,108,206,203,162, 34,115, 49, 39, 50, - 23, 81,145,111, 3,124, 61,103,173,100,233,226, 5, 79,158, 62,125,154,102,228,204, 60, 6,192,239, 13, 26, 52, 8,120,255,254, -125,147,192,192,192,154, 78, 85,189, 37, 98, 87,151, 20,145, 75,197, 84,170,202,185,204,184, 87,238,180,102,205,154,135,119,239, -222, 77, 44, 15,167,171,171,107,245,245,235,215,215,117,119,119,175, 43,177,180,148,102,103,100,108,214,100,164,109, 21,216, 57, - 73, 25, 91,187, 94,187,118,237,186,115,241,226,197,148,242,112,250,251,251, 87, 91,188,120,113,237, 90,181,106,213,118,246,246, -145, 72, 93,221,146,133,174, 21,147,164, 53,234, 72,152,138, 30, 61, 87,173, 90,117,239,193,131, 7,201,198,112,242,249,124,150, - 97, 24, 8, 4, 2,200,100, 50,220,184,113, 3,253,186,127, 9, 39, 7, 11,120,251,248,160,197,200,177, 56,115,230, 12, 68, 34, - 17, 24,134, 1,195, 48,250, 79, 45, 48,140, 17, 66,101,161, 36,241, 85, 22, 55,165,244,236,245,235,215,127, 28, 50,100,136,168, -125,251,246,184,119,239, 30,134, 13, 27,246,251,209,163, 71, 1, 0,247,238,221,195,196,137, 19,127,191,114,229, 10, 70,141, 26, -133, 86,173, 90,137,126,251,237,183,117,198,204, 34, 52, 24, 12,216,190,125, 59, 12, 6, 3,228,114, 57,108,108,108,208,177, 99, - 71, 4, 7, 7,143,250,245,215, 95, 95,241, 4,130,254, 29, 58,247,192,153,147, 71,241,250, 69,240,168, 29,139, 7, 26,229,204, -151, 82,138, 99,219,183, 59, 74,126,255,221,181, 93, 78,142,195, 89,177, 56, 41,218,203, 43,174,113,135, 14,137, 86, 86, 86, 70, - 55, 38, 9, 33,132,101,217, 2, 81,149, 47, 54,242, 55,190,200, 30,124, 89, 53,240,205,235,226,217, 27,161, 94, 80,143, 62, 22, -214,161, 47, 75,115, 50, 74, 8, 1,199,113, 16, 8, 4,168, 85,181, 49,222,228,205,139,172, 58, 16,168,189, 51, 21, 14,141,114, -187, 5,163,150, 57,224,251,225,243, 32,224, 9,245,198,184,206, 17, 0,207,195, 35,222, 2,114,115, 60,215, 2,150,243,150,192, - 39, 40, 8,113, 27, 54, 32,254,199, 31,225, 56,122, 52, 44,231, 46, 68,122, 68, 44, 32,149, 34, 52, 71, 13,137, 64,240,188,172, -120,204,159, 53,152,166,136, 20, 87,118,169,142, 64,191,145,176,182,174,129,184, 52, 45,226,211,180,216,186,161, 43, 30,253,182, - 16, 15, 47, 14, 66,212,251,247,144, 58,117, 3,107,208, 84, 51,201,150,127, 20,174,255,155, 6,185, 51,133, 62,182,130,130,205, -211,198,198, 92,175,215,197, 94,186,116, 73,199, 48, 12,204,204,204, 48,100,216, 48,102,195,250,245, 77,251, 53,108,120,117, 68, -219,182,231,174, 94,185, 82,171,126,253,250,160,148,130, 97, 24, 28, 56,112, 64,165, 86,171, 82,221,221,221,173,140,125,120,114, -114,114, 65, 11, 47, 39, 39, 7, 28,199,193,194,194,162, 92,174, 10,148, 10, 92,190,114,254, 81, 58,101,191,141,110,255,102,165, -110,233,251,174,245, 51, 56,150,159,201,234,145,169,162,200, 82,131,127,143,177,169, 63,196,171,155,238,109,155,250,175,111,188, -186,157,170,102,213,229,154,253,144,148,148, 52,179, 87,175, 94,169,206,206,206,196,194,194, 2,174,174,174, 76,151, 46, 93, 82, - 98, 98, 98,230,127,108,196,219,217,217,245,109,217,178,229,169,184,184,184,158, 55,110,220,168,116,243,230,205,158, 45, 91,182, - 60,101,103,103,215,215, 72,138,131, 51,102,204, 80,138, 68, 34, 52,104,208, 0, 89, 89, 89,208,106,181,101,110,101,182, 60, 57, - 14, 18,137, 4,135,182,174,250, 98,225,220,153,210,180, 87,247,240,236,247, 75, 56,255, 78,147, 51,103,233,234,187, 18,137,228, -163,222,215,203, 65, 86,189,186,139,249,203,137,195,250,196, 79, 15, 10, 50,127,254,252,185,116,220,248, 9,136, 76,204,160,162, -246, 43,120,104, 62,155,121,170,180, 35, 29,190,106,133, 31, 23,255,208, 28,192,168, 50, 43,106, 7, 89,245,106, 46,230, 33, 83, - 70,244,139, 24, 63,126,188,116,233,210,165,234,122,245,234,233, 19, 18, 18, 44,229,118, 14,117, 4,182,118, 13,223,189, 79,180, -170, 83,183,238,155,241,227,199,171,203,203,249,195, 15, 63,152,221,186,117, 75,216,186,117,107,154,148,148,100, 45,148, 74, 27, - 9,204, 45,155,199,167,164,216,180,105,211,230,205,208,161, 67,217,143,225, 12, 13, 13, 21,214,169, 83,135, 38, 36, 36, 88,155, -217,218, 55, 16,218,218, 55,123,155,240,222,186,102,173, 90, 97, 19, 39, 78,212,151,198,217,107,237, 31,226, 68, 46,151, 39, 4, - 6, 6, 98,206,156, 57, 88,176, 96, 1,122,247,238,141,119,145,239,208,124,232, 8, 84, 25, 50, 10,167,239,222, 71,124,124, 60, -102,206,156, 9, 47, 47, 47, 8, 4,130,176,207, 81,104, 24, 35,178, 74,234, 62,244,175, 66,174,151, 54,206,170, 44,238,158, 61, -123,126,215,187,119,111, 28, 60,120, 16,195,135, 15,255,125,205,154, 53, 77,134, 15, 31, 14, 0,104,208,160, 1, 22, 46, 92,216, -100,214,172, 89,191, 47, 90,180, 8,173, 91,183,134,135,135, 71,153,254,196, 88,150,133,193, 96, 64,191,126,253, 96, 48, 24,144, -156,156,140,208,208, 80,108,222,188, 25,148, 82, 9, 0, 56,187,184,213, 17,137, 68,120,250,248, 65,206,236,225,245,247, 24, 27, - 87,199,182,111,119, 52,187,125,219,245, 75,149,202,225,130,153, 89, 82,122,173, 90,113,181, 91,183, 78, 36,132,192,220,220,188, - 60, 2,171, 64, 12, 21,118, 75, 80,116,203,159,160, 98,116, 15, 64, 30,231,168,126, 19, 33, 57,223,180, 64,100,201, 43, 2,156, - 1,120, 20, 36,192,152,110,115, 16, 88,189, 38, 24,134, 49, 74, 88, 43, 41,174, 92, 12, 13,215,194,206, 30,169,182,206,240,206, - 19, 87,154, 89,211,192,173, 90,134,244,165, 75, 97, 57,122, 52, 24, 11, 27, 64, 34,197,149,216,247,218, 28,189,161,196, 50, 57, -127, 92,105,254,187,103,167, 17,176,156, 8,183, 30,159,199,197,155,135,241, 46, 46, 25, 81, 73,106,128,111, 9,181, 50, 22, 58, - 85, 28,180, 25,143,161,208,152,153,228,202, 63,211,138,245,175, 25, 51, 87,156,163, 81, 80, 11,105,159,195,235, 54, 88,246,234, - 55, 80, 25, 24, 24,104,237,234,234, 10, 66, 8,186,118,235, 70, 90,222,184, 97, 46,112,113,129,109,237,218, 5,222,115, 47, 95, -186,132,243,231,207, 43,207, 28, 63,230, 58,236,235,175, 59, 1,165,186,213, 41,136,188,148,148, 20, 56, 58, 58,130, 97, 24,136, -197, 98,196,197,197,193,217,217, 57,215,236,205,231, 11, 8, 33,124, 74,105, 89,230,172, 93,211,131,238, 6, 37,213,159, 89,165, -190,185,128,156, 83,190, 7, 75, 41, 4,132, 5, 84, 20,122, 22,208,232, 41,234, 84,230,217, 92, 84, 25,172, 79,223, 59,250, 22, -192,174,114, 90,176,174, 17, 66, 70,114, 28,119, 24, 0,115,227,198, 13, 46, 36, 36,228, 59, 99, 7,164, 23, 7, 51, 51,179,169, - 87,175, 94,181,153, 58,117,106,250,233,211,167, 51, 59,118,236,104,185,121,243,102,155, 86,173, 90, 77, 5,176,223,136,150,177, -138, 16,178, 51, 38, 38,230,187,186,117,235, 34, 45, 45, 13, 58,157, 14,143, 30, 61,130,151,151, 23, 30, 62,124, 8,111,111,111, - 60,120,240, 0, 62, 62, 62, 96, 89, 22,106,181, 26, 28,199,149, 89,162,199,199, 68,201,205, 52,233, 22,241,247,206, 33,244,249, - 35,156,141,208,228, 44,219,126,224,108,245,154,117,148,229, 45,192, 1,192,199, 81, 22,224,234, 96,123,113,233,188, 31, 28, 34, -175, 29,192,209,237,107,185,235,231,206,249,139,204, 49,178, 69,223,241, 61,180,122,184, 3, 16, 55,170, 95,151,126,101, 21,202, - 73, 43,225,253,149, 23,165,123, 50,247,113,148, 5,184,216,219, 94, 88,182,100,190,121,248,249, 29, 56,184,105, 5, 61,178,123, - 95,160, 26,168, 95,189,122,245,246,132, 16,103, 0,134,188, 52, 50,106, 9,154,226, 56,175,156, 62, 93, 75, 13,212,247,244,244, -108, 47, 16, 8, 42,229, 89,249,226, 62, 7,103,141, 26, 53,218, 19, 66,220,115,147,147,198,162,156, 75,229, 12, 31, 62,124,249, -148, 41, 83, 38,234,245,122,219, 66, 22, 72,222,230,205,155,249, 44,203, 50,148, 82, 29,195, 48,186, 11, 23, 46,176, 6,131, 33, - 94,173, 86,143,254,212, 2,163, 71,143, 30,184,123,247,238, 60,228, 78,176, 40, 19,105,105,105,124, 27, 27, 27, 67, 89,194,203, - 88,238, 27, 55,110, 44,232,223,191,255,244,253,251,247,135,174, 89,179,166,243,168, 81,163,112,224,192, 1, 84,173, 90, 21, 79, -159, 62,197,204,153, 51, 1,160,201,172, 89,179, 78,110,219,182,205, 35, 50, 50,114,185, 49, 86, 91,131,193,128,125,251,246,161, -107,215,174,176,183,183,135,139,139, 11, 8, 33,215,190,254,250,235,245, 0,192, 35, 60, 33, 0,104,212, 26,141,175,111, 93, 99, -156,140,146, 74,150,150,174,102,183,111,187,126,161, 84, 58, 28, 5,146,244,117,234,196,117,236,219, 55, 49, 50, 50, 18, 9, 9, - 9,112,114,114,202, 47,235,120,132, 16,166,172,110,246,124, 43, 78, 89,226,170, 28, 22,101,228,143,109,114,116,116,196,172, 49, - 75,176,100,195, 44,188,193,117, 84, 29, 0,188, 88, 9,116,245, 24,139,186,129, 13,224,226,226, 98,124,175, 2,176,230,116,100, -204,248, 47,164, 2,123, 79, 78,141, 39, 85, 61, 97,153,158,140, 42, 94,238, 32,102, 50, 40,118,108, 70,230,238, 93, 48,147, 75, -112, 63, 93,129, 43,111,163,178,178, 13,134, 85,165,133, 19, 64,129,207, 43,247, 10,222,234,215,145,217,102, 73,113,183,240,251, -111,199, 81, 53,112, 2,164, 78,157, 96,227,187, 8,186, 87,171,161, 77,189, 8,155, 10, 29, 17, 27, 25, 14, 30, 95, 28,108,146, - 44,255, 44, 20,214, 34,255, 26, 11,214, 7, 25,154, 35, 2, 31,111,111, 86,200,224,215,174,157, 58,229, 60,121,242,164,160,149, -167,190,127, 31,202,243,231,193,178, 44, 40,165,184,121,227, 6, 6, 13, 28,152, 45,224,145,173,149, 43, 87,162,132,254,225,123, -133, 16,242, 39, 95, 86,154, 66,253, 84, 42,149, 10, 42,149,170, 96,208,102,114,114, 50, 68, 34, 17,164, 82, 41, 26, 54,108, 72, -120, 60, 94,175, 98, 62,182, 54, 69, 18, 67,207,166, 41,123,110,235, 48, 32,193, 37, 91, 71, 71, 90, 85, 70, 69,161,180,224,163, -116,178, 32,232, 28, 40,128, 29, 63,137, 94, 89,222, 54,158,211,164,246,164,148,234, 75,227, 44,230,153,222, 53,106,212, 88, 63, -104,208, 32, 6, 0,218,180,105,195,212,168, 81,227, 23, 66,136,119, 41,247,148,202, 41,145, 72,196, 0,112,234,212,169,180,208, -208,208, 47, 79,157, 58,149, 86,248,184,145,156,155,127,250,233, 39,152,153,153,193, 96, 48, 64,171,213, 22,140,191, 42,252,171, -211,233, 96,103,103,135, 51,103,206,128,101,217, 51,101,133,211,175, 90,141,236, 76,190, 85,226,206, 83, 87,113, 46, 82,151, 93, - 94,113, 85,152,179,170,179,220,199,201,206,246,210,178,197, 11,236,211,223, 60, 66,108,108, 44,189,112,254,204, 29, 21,165,113, - 25, 10, 58, 59, 61,155,250,228,104,168,180,158, 7,162, 47,109,154, 70,103, 53,131, 30,228,207,179, 7, 11,115, 6, 56,203,125, - 92,237,109, 47,252,188,108,177,121,198,155, 71, 72,120,255, 30,103,207,156,122,162,162, 52,142, 82,122,132, 82, 58,148,227,184, -234, 28,199, 85,167,148, 14, 45, 73,180,148,151, 83,167,211, 85,215,233,116,159,149,179,188,225, 44, 52,131, 16,243,230,205, 11, -139,141,141, 29,149,152,152,216, 35,127, 75, 75, 75,235,154,149,149,213, 49, 39, 39,167,189,106,101, 37, 75,165, 82,233,144,149, -149,229,172, 82,169,234, 80, 74, 31, 25,155, 63,139,162,112, 5, 27, 31, 31, 63, 55, 62, 62,158,148,154, 63, 71,190, 36,235,150, -127,187,251,208,161, 67,142,159,194, 93, 52,156,201,201,201,135,247,237,219, 87,179, 74,149, 42, 30, 67,135, 14,197,198,141, 27, -177,102,205, 26, 13, 0,108,219,182, 77, 83,200,114, 85,225,221,187,119,117,139,235, 30, 44,204,201, 48,204,174, 47,190,248,130, -222,188,121, 19, 93,187,118,133, 94,175, 71, 76, 76, 12,182,108,217, 2,131,193,160,104,221,186, 53, 7, 0, 42,117,142,130,114, - 20, 90, 93,241,253,236,133, 57, 9, 33,196, 23,232, 52,212,217,185,210, 23, 74,165,195, 69,153, 44,233, 77,197,138,113,109,123, -247, 78, 20, 10,133,144,203,229, 5,101,157, 88, 44, 70,189,122,245, 8,159,207,111, 81, 6,231, 7, 86,156,162,219,199,124,155, - 5, 93,122,121, 28,110,110,110, 88, 48,121, 5,220,238,247,192,181,166,182,168,153, 58, 20,237,154,118,134,143,143, 79,185, 56, - 67, 40, 85,170, 40,250, 76, 12,141, 86, 37, 73,197,168, 41, 97, 81,185,106, 5, 16,169, 25, 32,145,194, 34, 48, 0,150,245,107, -224,137,179, 35, 38,158,187,146,163,214,235,251,132, 83,154, 85, 26, 39, 33,164,192,114,215,165, 67,155,180, 13,191,172,224, 90, - 55,255, 14,102, 82, 11,232, 5, 21,144,150,173, 71,186,146, 66, 43,174, 15,145, 80,140,118, 13, 3,112,247,194,142, 28, 86,171, -220,249,177,121,254, 99,227,211,196,105,194, 7, 22,172,252,169,145,249,191,132,112, 44,203,114,168, 92,165,178,121,228,187,232, -181,189,123,247, 26,222,190,125, 7,179, 14, 29, 58, 72, 2, 94,229,118, 81,156, 58,117, 10, 71,143, 30,205,185,120,241,162, 66, - 44,224,109,171,224, 94,193,145,101, 57, 16, 82,186,133,132, 97,152,215, 47, 95,190,116,245,243,243,131, 90,173,198,210,165, 75, -245, 65, 65, 65, 2,185, 92, 14, 74, 41, 86,174, 92,201,246,235,215,143,215,181,107, 87,243,203,151, 47,143,131, 17,107,253, 81, - 74,159, 17, 66,218,173,111,217,253,104,221, 49,195,108,253, 91, 54,178,110, 81,193, 21,250,218, 20,241, 49,239, 16,122,229, 98, -250,139, 11,171, 82,161, 78,236, 78, 41, 13, 41,111, 36,185,184,184,204,185,120,241,162,195,216,177, 99,169, 90,173, 38,209,209, -209,116,241,226,197, 14,223,124,243,205, 28,148,225, 11,167,180,252,153,145,145, 1, 66, 8,151,151, 89,243, 91,175, 70, 79, 83, -165,148, 6, 19, 66, 78,116,235,214,173, 75,235,214,173,241,234,213,171,130,174,192,194, 2, 43,127, 54,225,146, 37, 75, 50,128, - 63, 28, 4,150, 4,177, 88,140, 45,135,207,159,139,143,141, 50,171, 92,217, 83,109,105,109,205,125,140,229, 10, 0, 68, 12, 51, -247,199, 5, 63, 56,164,188,188, 75,130,239, 92,229, 14, 61, 75, 76, 50,176,116, 76,177, 23,103,197,211, 60,213, 95,122,235,133, -225,205,253,113,241,124,203,252,238,203,253,143, 19, 20,132,165, 99, 63,173,169,241, 15,225,252, 31, 32,119,134, 95, 60,113,113, -113,161,249, 93,120,197, 9,172,178, 80, 92,247,224,199,114,191,125,251,118,113,237,218,181,167,132,133,133, 29,242,247,247, 31, - 5,192, 93,163,209,100,204,154, 53,107,217,182,109,219,134, 27, 99,185, 2,128, 3, 7, 14,172, 26, 54,108,216,249, 78,157, 58, - 77,227, 56,174, 70,161,202,227,173,131,131, 67,129, 71,174,228,196,247, 65, 35,135,247, 11,202,206, 78, 47,211, 79,157, 47,208, -114, 90,141, 26, 67, 7,120,120,184,157,224,241,146,184, 70,141,226, 2,157,157, 19, 87,175, 94,205, 78,154, 52,137,103,105,105, - 9, 0, 88,191,126, 61,237,221,187, 55,233,209,163,135,217,181,107,215,250, 0,184, 90,150, 21,167, 56,203, 21,159,207,255,216, - 10,242, 3,129,149, 47,178,230, 76, 92,138,184,184, 56, 8,133, 66,120,121,121, 65, 36, 18,149,155, 59,132,210,235,254,132,116, -252,246, 93,226,129,214, 54,230,230,173, 29, 5, 34,111,169, 57, 64, 9, 66, 83,210,113, 37,238,149,246,202,187,168, 44,181,222, -208,167, 52, 47,238, 0,192,178,108,146,183,183,119, 65,247, 17, 33, 36, 85,161, 33,150, 7,253,234,203,135,142, 60, 68,126,127, -112, 27,241, 58, 14, 26, 61,135,202, 85,106,161,197,151, 43,113,242,220,115, 54, 62, 50, 36, 68,175, 74,223,106,170,230,255, 89, -214,171,194,191,255, 10,129, 85, 20, 28,143,185,181,113,211,134,175, 14,236,219,239,196,227, 49, 78,225, 17, 17, 15, 58,119,239, - 25,119,233,210, 37, 27,161,165,101, 61, 0,156,118,212,168, 59, 58,141, 42,237,244,137, 19, 21, 43, 87,174, 20,152,183,216, 51, -229,120,204,173,210, 30,152,156,156,188,118,240,224,193, 77, 79,159, 62, 45, 10, 10, 10,202,138,136,136, 56,113,227,198,141, 30, -251,247,239,151, 46, 93,186, 52, 59, 53, 53,245,192,209,163, 71,251,117,238,220, 89,175,213,106,115,202,145, 48, 33,132, 16,191, -251, 63, 44,239,127,255,167, 13,109,193,231, 53,134, 70, 0,112,250, 91,208,101, 93, 2,176,215,136,238,198, 98, 33,147,201, 2, -205,204,204,240,228,201,147,244,250,245,235,107,213,106,181,112,209,162, 69,182, 50,153, 44,240, 19, 50, 18, 77, 79, 79, 7,199, -113,124, 0, 36,239, 23, 92,249,215,202,233,219,185,115,231, 19, 7, 15, 30,252,162, 67,135, 14,240,240,240,128, 94,175,135,183, -183, 55,180, 90, 45,188,188,188,160,209,104, 48,111,222, 60,100,102,102, 78, 50,102, 17, 97,137, 68, 2,145, 72, 4, 31,191,106, - 57, 18,137, 4, 31, 43,174, 0, 64, 38, 96, 60, 94,159,222,142,164,212, 20,238,224,211,196,196, 28, 29,219, 46, 44, 73,249,162, -232,117, 57, 44,148, 45,135,142,139, 3, 0, 13,135,236, 82, 57, 69,240, 8, 61,179, 5,137, 73, 41, 56,240, 56, 33, 67,169,227, -190,124, 93, 12,103,185,194,249, 15,225,236,181,246, 21, 90,124,107,252,181,135, 70,126, 90, 1,241, 49, 66,170,160,146,125, 75, - 9, 54,249, 81,108, 90, 91,172,143,171, 79,225,206,179, 76,157,200,171,116, 99,250,245,235, 23,244,238,221,187, 5,121,254,174, - 54,149,135,107,251,246,237, 97, 0,134,149,118,205,254,229,195,142, 1, 56,102, 12,159, 25,159, 31,216,183, 74,149,118, 27, 67, - 67,111,108,203,201,145,156, 91,181, 42,181,125,251,246,170,240,240,240,187, 87,175, 94,109,188,111,223, 62,209,143, 63,254,168, - 74, 76, 76,252,237,192,129, 3,205,123,244,232, 97,208, 24, 49, 3,133, 16,242,217,196, 85, 62, 95, 97,203, 80,190,200,114,113, -113, 65,197,138, 21, 63,233,187,207, 19, 89,215, 60, 9,241,184,152,150, 61,225, 86,166,170,141,250,213,219,234, 0, 32, 17, 8, -158,231, 24, 12,151,179, 13,134, 85, 69, 45, 87,197, 33, 53, 53,117,208,159,194, 46,181,117,217,177,110,238,169, 7,191,215,243, -110,218, 97,136,180,154, 11, 7,173,142, 34, 38, 42, 28,243,102,111,205, 73,136, 10, 11,209, 25,116,221, 76, 62,176, 76,248,219, - 9,172,136,136,152, 16, 15,143, 10, 51,142, 30, 57,220,152, 82,134, 71, 9, 81, 90, 89, 89,159,138,142,142,254,192, 11,182,167, -141,141,249,176,111,134,245, 33, 28, 17, 16,194,177, 28,143,185, 21, 17, 17, 19, 82, 70,193,248,176, 99,199,142,139, 3, 2, 2, - 38,176, 44, 59, 83,169, 84,158,176,178,178,186, 87,187,118,237, 5, 44,203,206,206,202,202, 58, 97,103,103,119,114,253,250,245, - 11, 89,150, 45,151,143,168, 60, 1,181, 19,248,188, 75,171, 17, 66,230, 83, 74, 45,249,124,126,230,243,231,207,247,249,248,248, -244,163,148, 90, 18, 66, 50, 63,150, 83,173, 86,143,205,200,200,176, 27, 49, 98,132,126,243,230,205, 62, 67,134, 12, 9,122,241, -226,133, 64,173, 86, 71,148,243,157, 53,132,144, 46,189,123,247,222, 42, 16, 8, 90, 51, 12, 67, 56,142, 43,188,220, 6, 40,165, - 96, 89,246,100, 89,241, 34, 16, 8,178,191,250,234, 43,121,153, 86, 41,145, 40,219,216,240,101,105,217, 9, 27,174,190, 88,162, -214, 83,106,224,232,200,215,137,202, 98,167,144,221,127, 77, 3,140,230, 84,115, 19,214, 92, 8, 89,162,209,115,156,129,163,163, - 74,226, 44, 15,254, 41,156, 0, 48,154, 89,187, 27,155,214, 22, 12,120,207,239, 54, 44,186,255,185,145,111,105, 66,121,188, 44, -231,185, 99, 8, 25,249, 23,112, 23, 35,182,202,139,158, 61,123,178,159, 59,158, 84, 6,195,205,250,199,143, 79,215,114,220,235, -138,237,219,203,125,125,125,187,179, 44,187, 85,161, 80, 92,177,180,180, 12,169, 94,189,250,112, 0,219, 20, 10,197, 21, 71, 71, -199,155,171, 86,173, 26,201,113,220,207,101, 88,113,226,242,173, 56, 0,104,190,245, 41, 95, 64, 20, 22, 18,122,189, 62,214,152, -112,178, 44, 27, 23, 24, 24, 72, 10, 91,179,138,254, 22,134,177,188,133,145, 39,160,230,163, 20, 39,162, 31, 37,176, 85,169,241, -132,144,218, 47, 31,255, 54, 42, 52,228,113,255,252,217,130, 60,158, 40,152,213,229,236,212,171,210,183,154,196,149, 9,127, 7, -147,220, 95,182, 1,104, 99,226, 52,113,154, 56, 77,156, 38, 78, 19,167,137,211,196,249, 95,219, 76, 75,143,155, 96,130, 9, 38, -152, 96,130, 9, 38,124,102, 16, 0,109, 74,176,108, 25,237, 43,234, 99,102, 19,148,197,111,226, 52,113,154, 56, 77,156, 38, 78, - 19,167,137,243,223,199,249,159,129,169,139,208,196,105,226, 52,113,154, 56, 77,156, 38, 78, 19,167,169,139,208,212, 69,104,130, - 9, 38,152, 96,130, 9, 38,152,240,183, 6,223, 20, 5,229, 67,222,154,114,223, 2,232, 9,192, 19, 64, 56,128,195, 0,214,151, - 99,193,227,194,124, 22, 0,130, 0, 52, 6, 80, 5,192, 91, 0,191, 1, 88, 74, 41,205, 54,197,120,241,176,183,183,159, 33, 16, - 8,172, 0, 20, 44,173, 84,244, 87,175,215,103,100,102,102, 46,254,139,242, 1,143, 82,202,150, 39,172,255,139,112,154,240,183, - 45, 71,188,109,108,108,246,164,165,165, 13,160,148,134,154, 98,196, 4, 19,254,197, 2,139, 16,114, 3, 0, 40,165,205, 1,192, -220,220,252, 54,195, 48, 85,242,206, 1,200, 93, 19,170,240,126,209, 95,142,227,222,166,166,166, 54, 42,233, 97,102,102,102,183, -121, 60, 94, 21, 66, 72,254,226,179, 96, 24, 6,122,189,222,156,199,227,101,149,192, 25,155,150,150, 86,231,111, 82, 40, 18, 0, -167,173,173,173,213, 11, 22, 44, 88,223,162, 69,139, 10,241,241,241,134,169, 83,167, 54,123,250,244,105, 7, 66,200, 87,229, 17, - 89,132,144,134,132,144, 29, 53,107,214, 60, 54,120,240,224,131,245,235,215, 23,165,166,166,154, 31, 62,124,216,117,231,206,157, -143, 8, 33, 3, 40,165, 15,255,101, 21, 75,137,203, 31, 25,185, 52, 18, 0, 64, 32, 16, 88,197,199,199,155,231, 11, 21, 74, 41, - 12, 6, 3, 40,165,208,235,245, 80, 42,149,240,247,247,255,236,225,119,118,118,174, 69, 8, 89,235,229,229, 85,199,197,197,229, - 1,128,239,226,227,227,159,150, 21,214,216,216, 88,243,188,239,235,255, 37,156,255,114,113,242,181, 72, 36,250,210,203,203,171, -158, 70,163, 73,127,251,246,237,125,150,101,127,160,148,190,255, 76,252,150, 0,126, 16,139,197,245, 61, 61, 61, 43,132,133,133, -197,232,116,186,123, 0,230, 83, 74, 51, 63,135,184,106,222,188,249,239,235,214,173,179, 29, 61,122,244,239,132,144, 38, 38,145, -101,194,255, 10,238,238,238, 86, 74,165,114, 43, 33,164,150, 80, 40,116, 50, 51, 51,131,153,153,217,123,145, 72,244,196,206,206, -110,248,153, 51,103, 50,254,159,191,239, 15,180,200, 63, 94, 96,229,173,251,243,193, 82, 13,124, 62,223, 45, 50, 50,210, 33,127, - 65, 82,142,227, 10, 42,178,252,223,124,228,249, 89,130,175,175,175,174,140,138,166, 66,108,108,172,131, 92,254,135,171, 37,157, - 78, 7, 39, 39, 39, 46, 46, 46,206,161,232, 66,194, 90,173, 22,110,110,110,127, 39, 95, 38,223,218,216,216,100, 70, 71,199, 4, -170, 53,186,249,223,140,157, 62, 99, 64,207,182,214,183,111,223,230,190,250,234, 43,205,141, 27, 55,190, 5,176,214,216, 66,156, - 16,178,115,234,212,169,243, 36,102, 22,182, 87,111,135,104,118, 30, 62, 19, 87,211,187, 50,153, 52,105, 18,111,220,184,113, 55, -107,213,170,181,135, 16, 82,187, 60,150, 44,115,115,243,243, 98,177,184, 18,143,199,131, 78,167,139, 78, 75, 75,251,226,111, 84, - 49,214, 4,240,152, 16, 82,139, 82,250,196,216,115,165, 65,161, 80, 20, 44,185, 84,120,243,245,245,253, 43,194,207,175, 80,161, -194,137, 37, 75,150,184,190, 79, 72,192,138,149, 43, 27, 0, 88, 15,160,129, 49,247, 39, 37, 37,253,191,132,243, 95, 46,174,130, -230,205,155,183,164,127,255,254, 96, 89, 22, 42,149,202,229,205,155, 55, 1,179,102,205,234, 70, 8,169, 71, 41,141,248, 68,126, -123, 47, 47,175, 87, 19, 38, 76,176,169, 87,175, 30, 24,134, 65,102,102,166,203,111,191,253,214, 96,219,182,109,131, 8, 33,190, -148,210,228, 79,121,134,141,141,205,158, 45, 91,182,216,154,153,153,225,228,201,147,182,173, 91,183,254,141, 16,210,244, 99, 69, - 22, 33,132,177,181,181, 29, 7,160, 21,199,113, 34, 0,247,210,211,211, 23, 82, 74,117,166, 28, 99, 66,105,176,179,179,251, 58, - 43, 43,107,157, 68, 34, 17,218,216,216,192,204,204, 12,124, 62, 31, 66,161,208, 93, 46,151,187,243,249,252,246,157, 58,117,250, -238,212,169, 83, 91,255,159,190,239, 63,105,145,127,133, 5,139, 82,122,163,200,139, 66, 42,149,226,224,193,131,224,241,120, 31, -172,226, 94,220,127,119,119,247, 50, 31,150,111, 1, 59,117,234, 20, 44, 44, 44, 96,105,105, 89, 80,193,136,197, 98, 92,185,114, - 5, 2,129, 0,124, 62, 31, 2,129, 0,117,234,212, 41,214,225,221, 95,137, 94, 1,185,139, 76, 22,231,188,177,169,167, 20, 61, -199,205,237,147,163,214,213, 5,160,204, 72, 79, 79,127,112,244,104,124, 77,111,111,225,158, 61,123,234,185,186,186,246, 52, 86, - 96, 1, 8,170, 93,187,246, 17,158,212,210,110,240,144,161,131,135,243, 25,221,160,145, 83, 22,197, 36,164, 40, 71,140, 24,113, -244,228,201,147,131,127,252,241,199,151,223,127,255,125, 16,128,153,198,134, 95, 36, 18, 85,122,243,230,141, 23,199,113,168, 94, -189,250,223,102,185,129,124, 1, 69, 41, 5, 33,228, 3, 33, 85,218,185,210,192,113, 92,193,210, 64, 69, 55,189, 94,143,207,237, -103,208,213,213,213,119,224,192,129,118,105, 41, 41, 88,177,114,101,254,225, 58,101,117, 23,230,119, 5,106,181, 90,244,232,209, - 99, 32,203,178,252,252,176,105, 52, 26,109,102,102,166,186,208, 76,157,100, 74,105, 91, 35,226,179,138, 76, 38, 91, 6,160,150, - 74,165,114, 5, 0,153, 76, 22,199,113,220, 49,165, 82, 57,147, 82,170,250,200,116,170, 0, 32, 0, 37, 47,217, 68,151, 44, 89, - 18, 22, 20, 20, 20,241,255,205, 73, 8,169,228,232,232,184,184, 87,175, 94, 56,115,230, 12,206,158, 61,171,151, 74,165,252, 33, - 67,134,144,239,190,251,206,122,194,132, 9,237, 1,172,254,196,100,110, 63,111,222, 60, 27, 63, 63, 63, 28, 62,124, 24,207,158, - 61, 83,121,121,121, 73, 91,180,104, 1, 62,159,111, 51, 99,198,140,175, 0,236,248,148, 7,164,165,165, 45,156, 50,101,202,206, -125,251,246,153,191,125,251, 22,107,215,174,181,235,211,167,207, 13, 66, 72,115, 99, 69, 22, 33, 68, 12, 96, 28,128,150, 60, 30, -175,233,144, 33, 67, 12, 99,199,142, 21, 48, 12,163, 95,185,114,165,253,182,109,219,250,216,217,217,213, 74, 73, 73, 49, 13, 51, - 40, 5, 60, 30, 79,199,113,156, 0,128,132, 82,170, 41,107,255,223,244,238,182,182,182,163,211,211,211,215, 59, 59, 59,195,193, -193,225,131,186,214, 96, 48, 32, 51, 51, 19, 98,177, 88, 88,161, 66,133, 45,253,251,247, 23,236,221,187,119,195,255, 71,184,138, -106,145,127,133,192, 42,169, 98,200, 95, 72, 52, 95, 72,229,139,159,162,255,243, 69, 89,145,136,186, 92,164, 80, 32,217,217,217, - 5,226,202,194,194, 2,121,149, 42,244,122,253,159,120, 89,150, 69,209, 85,181,141,153,254, 73, 8, 25, 13,224, 10,165, 52,220, -200, 4, 45,224, 60, 52,198, 23, 59,197, 83,251,229,187, 60,111, 63, 37,247,119, 39,128,219,239,134,175, 93,215,188,185,235,184, -217,107,230,170, 82,227, 83,102, 12,236, 84,201,203,201, 86, 42,203, 72,202,180,241,241,105, 7,192, 80,142,112, 54, 27, 60,120, -240,174,139,119, 35,137, 68, 34, 20,242,121, 60, 65,147,234,222,182, 21, 44,121,150,230,128,101, 76, 68,216,237,161, 67,135, 86, -255,254,251,239,155,150,231,221, 25,134,129,133,133, 5,118,237,218, 5, 38, 95,209, 26,249,238,159,241, 3, 41,154,238,252,124, - 1,149,150,150,134, 51,103,206,160, 67,135, 14,143, 9, 33,181,242, 46,121, 76, 41,133, 66,161, 64, 66, 66, 2,156,157,157, 31, - 19, 66, 4,133,187, 11, 75, 10,167, 94,175,135, 94,175, 71,255,254,253,255, 36, 92, 20, 10,133,186,200, 20,227, 15,196,139,177, -239,238,226,226,114, 17, 64, 91, 30,143, 7,173, 90,173, 93,246,243, 7, 78,183, 31, 22, 22, 87, 37,113,230,119, 9,178, 44,203, -127,248,240,161,160,208,250,110, 2, 0, 50, 0,118, 44,203,130,207,231, 63, 55, 34, 62,125,205,204,204,110,159, 58,117,202,162, - 78,157, 58, 68, 36, 18,193, 96, 48, 32, 56, 56,184,194,143, 63,254, 56,242,242,229,203, 95, 17, 66,252,139, 46,106,110,100,186, - 7,252,246,219,111, 74, 15, 15, 15,182, 4,139, 33,223,219,219,187, 57,128,136,255, 1,103,108, 98, 98, 98,215,182,109,219,142, -122,255,254,253, 43,131,193, 48, 13, 64, 53, 59, 59,187,199,221,187,119,135, 84, 42,109,105,140,192, 42, 45,221, 29, 28, 28,186, - 52,106,212, 8,107,215,174,197,143, 63,254,216,134, 82,122,133, 16,210, 90,161, 80, 92,238,220,185, 51,172,172,172,186, 22, 39, -176,140,205, 75,132, 16,239,102,205,154,109,153, 63,127,190,249,153, 51,103,224,229,229,133,172,172, 44, 76,158, 60,217, 97,206, -156, 57,215, 9, 33, 45,242, 69, 86, 73,156,132, 16,127,177, 88,188, 99,223,190,125,114, 15, 15, 15, 15,161, 80,200,120,120,120, - 32, 45, 45, 13,106,181, 90,188,104,209,162,234, 82,169,244,233,234,213,171,119, 0,232,254,255,253,189, 23, 9,107, 38, 0, 11, - 0, 86,229,233, 94, 45,229,221, 51, 1,136, 11, 62, 30,129, 0, 18,137, 4,146,255, 99,239,186,195,163, 42,214,247, 59,231,156, - 45,201,182,108,122, 33, 33, 9, 74, 72,104,129, 68, 18,185,161, 10, 10,151,114, 5, 46,197,138,136,138, 8, 10,138, 2,130, 72, - 40,130, 32, 74, 81,105, 42, 69,189, 34, 88,127, 72, 81, 4, 67,151, 18, 90, 66, 9, 16, 73, 32, 61,155, 77, 47,219,206,153,223, - 31,236,174, 75, 76,217, 13, 27, 8,186,239,243,204,147,221, 61,155,119,167,158,121,207, 55,223,124,227,230, 6,169, 84,138, 75, -151, 46,205,113,115,115, 91,110,123, 47,110,136,147,252, 57,105,117, 33,132, 28,103, 89,182,193,247,181, 93, 64,238,116,125,154, -243, 28, 76, 8, 89, 1,160,239,205, 91, 62,179,223,199,199,103, 74, 94, 94, 94,166,189,156, 65, 65, 65,222, 21, 21, 21, 43,131, -130,130,224,231,231,103,157, 59, 34, 35, 35,161,211,233,112,237,218, 53, 80, 74,145,151,151, 7,185, 92,142,240,240,240,149,175, -191,254,250, 55,203,150, 45, 43,106,206,178,255,221, 96, 17, 88,243,106,175,123, 18, 66, 32, 8, 2, 56,142,187, 69, 96,213, 78, - 22, 49,100,238,167,164, 49, 83,182, 94,175,183,138, 43, 15, 15, 15,171, 56, 51,153, 76,245, 9,172,166, 40,243,104, 65, 16,218, - 16, 66,214,217, 43,178,106, 99,236,216,177,127,241,231,120,237,181,215,178, 10, 10, 10,232,127, 7,116,145, 95,220,149,147,123, -191,167,194,221, 87,169, 12,119,243,244, 82, 23, 21, 21, 29, 5,160,118,224, 39,218,198,198,198,186,111,254,238, 96,214,243,175, - 46, 94,240,192,125,222,170,232, 96, 31,207, 0, 15,119,137,130, 33,149,110, 38, 99,150,151,151, 87, 68, 19,158,200, 0, 0,106, -181, 26, 28,199,181, 8, 11, 22,165,212, 68, 8,137, 33,132,156,218,177, 99, 7,226,227,227,173, 34,203, 34, 62, 74, 75, 75,145, -146,146,130, 94,189,122, 1, 64, 76, 99,190, 88,150,101,106,139,192,106, 72,184, 88,190,207,178,236,185, 38, 22, 97,129,167,167, -103,175,190,125,251, 74,182,108,221, 42,161,148, 86,226,230,129,212, 21,148,214,115,112,117, 45,152, 76, 38, 24,141, 70,139,149, - 17,169,169,169,183, 88,128, 69, 34, 17,252,253,253,237,202,140, 84, 42,125,253,235,175,191, 86,197,197,197,145,162,162, 34, 8, -130, 0,134, 97,208,170, 85, 43,172, 94,189,218,109,228,200,145,173,146,147,147,103,161, 9,199,206, 0, 32,245, 9, 33, 0, 80, -169, 84, 38,192,225,221,199,117,114,154, 76, 38,146,144,144,240,134, 70,163,233, 92, 93, 93,253,142, 61,253, 8,192,255,153,147, -229,158,114,230,226,197,139,213,163, 71,143,118, 15, 15, 15,143,191,221,190,218,174, 93,187,238, 34,145, 8,199,142, 29,211, 1, -176, 60, 73,239, 63,123,246,172,110,196,136, 17,210,144,144,144,238, 14, 88,238,218, 69, 69, 69,237,241,243,243,115,183, 8,255, - 81,163, 70,137,214,175, 95,175,204,206,206,134,193, 96,192,204,153, 51, 49,100,200, 16,248,248,248,224,181,215, 94,243, 95,186, -116,233,151, 0, 98, 27,224,116,147, 72, 36,159, 95,185,114, 37, 34, 48, 48,208,253,247,223,127, 71,116,116, 52, 52, 26, 13,242, -242,242, 80, 81, 81,129,188,188, 60,140, 31, 63,222,239,131, 15, 62, 8,106, 65,115, 77,137, 88, 44,134, 76, 38, 83,151,148,148, -148,222, 6,143, 20,128,196, 86, 92, 73,165, 82, 72,165, 82,184,185,185,193,142,103,202,123, 26,132,144, 86,132,144,243, 98,177, - 88, 42,147,201,196, 12,195, 64, 42,149, 14,240,242,242, 74,125,228,145, 71, 58,253,242,203, 47, 25,246,240,212,212,212,124,238, -230,230, 38,242,245,245, 5, 0,116,239,222, 29,143, 60,242, 8,180, 90,173, 80, 80, 80,128, 86,173, 90, 49,103,207,158, 69, 89, - 89, 25,254,248,227, 15, 68, 70, 70,138, 8, 33,159, 3,248,119, 51, 23,113,222,223,206, 7,139, 82,154, 72, 8,233, 93,215, 36, -198,113,156, 53,213,101,185,178, 36,123,132, 16, 33, 4, 60,207,195,223,223, 31,102, 71, 58,235,129,163, 60,207,255,133,159, 82, -218,164, 1, 35,151,203,241,196, 19, 79,208, 53,107,214,188,104, 22, 89, 87,236,253,223, 81, 31, 93,180, 90,173,106,163, 67,135, - 14, 71,102,205,154,245,232,111,191,253,150,253,192,125,225,156, 60, 39,179,194, 77,165, 86, 35,184,245,224,103,134,141, 56,139, -155,187, 9,237,197,149,242,242,114,247,251,131,101,122,134,169, 33,173,165,156, 50, 80, 46,150, 6,120,122,182, 18,235,117, 5, - 42, 79, 79,137, 78,167, 43, 1,208,224,225,204, 42,149,234,103,169, 84, 26,202,178, 44, 88,150,133,143,143,143, 7,165, 20,106, -181, 26,193,193,193,138,200,200,200, 52,142,227,192, 48, 12, 42, 42, 42, 50,175, 93,187, 54,160,177,140,121,122,122,254, 44,149, - 74, 67, 25,134, 1, 33, 4, 44,203, 90, 55, 36, 88, 94,179, 44, 11, 66, 8,170,170,170,236,226,164,148,158, 38,132,196, 12, 30, - 60,216, 42,178,118,237,218,133,129, 3, 7,162,164,164, 4,169,169,169,182,226,202, 46, 31, 44, 65, 16, 96, 48, 24, 96, 48, 24, - 26, 20, 46, 98,177, 24,106,181,186,201,131,196,203,203,235,208,168, 81,163,240,201, 39,159, 80,243, 41,239,114, 66, 72,180,135, -135,199,165,243,231,207,219,229,231, 66, 41,181,230, 19,192, 45,227,202,146,236, 93,210,100, 89,118, 64,108,108, 44, 41, 45, 45, -181, 8, 71,235,131, 16,203,178,248,248,227,143,221,227,226,226,222,114,115,115,123, 67, 44, 22,151, 25,141,198, 45, 53, 53, 53, -239, 80, 74, 75, 90,210,205,167,103,207,158,175,222,184,113, 99, 72,104,104,232,246,219, 16,239,180, 91,183,110,122, 0,238, 44, -203,138,156, 48,129,177, 0,192,243,124,141, 69,228, 83, 74, 77,177,177,177, 53,230,201,221,238, 19,144,125,124,124,190,220,185, -115,103,112,104,104, 40,140, 70, 35, 76, 38, 19, 42, 42, 42,176,127,255,126,232,116, 58,152, 76, 38, 68, 68, 68,224,237,183,223, -174,153, 50,101,138,219,186,117,235, 10, 42, 42, 42,158,108,132,118,202, 55,223,124, 35, 15, 12, 12,116,175,174,174, 70,122,122, - 58, 98, 99, 99, 81, 94, 94,142,202,202, 74, 84, 85, 85,193, 96, 48,160,172,172, 76,205,243,188,190,197, 76, 52, 28, 7,169, 84, - 10,177, 88, 92, 18, 26, 26, 10, 66,136, 91, 70, 70, 70, 83,150,220, 84, 0,202, 68, 34,145,196, 86, 88, 73,165, 82, 28, 59,118, -108,150, 68, 34,169,211,122,213, 80,255,113,228,125, 11, 16, 88, 43,196, 98,177,212,203,203, 75,108,115, 31, 20, 43, 20, 10,248, -249,249,125, 4, 96,144,157, 60, 93,189,189,189,173,135,125, 15, 25, 50, 4, 41, 41, 41,223,231,231,231, 63, 93, 80, 80, 0,131, -193,240,185, 84, 42, 29, 94, 86, 86, 6, 65, 16,144,159,159,143,182,109,219,118,189, 3, 15,227,117,106,145,123,221,130, 85,231, -186,167,101,137,176, 46, 65, 85, 91,112,217, 35,132,244,122,189, 34, 54, 54, 86,176, 76,220,150, 4,128,212, 39,176,204,150, 2, -135, 33, 18,137,148, 19, 39, 78, 44, 95,179,102,205, 4, 66,200,122, 74,233,229,166, 86,210,246,111,191,242, 95,242,246,204,183, -189,130,194,239,127,227,141, 57,220,208,161, 67,127,223,188,121, 51,239,213,126, 80,191,125, 63,127,225,191,114,218,244, 93, 59, -119,238, 4,110, 58, 60,219,139, 67, 63,253,244, 83,192,107,175, 76,194,219,175, 79,217,173,138,240,145, 40,136,151,220, 77, 87, - 89,168, 0,173,150,182,141, 26,242,221,246,237,185, 0,146, 27, 34,113,119,119, 15,189,124,249,114,132, 82,169,180,126,102, 48, - 24,160, 86,171,177,121,243,102, 95,165, 82,233,171, 80, 40,192,113, 28,162,163,163,237,181,144,132,166,165,165, 69, 40,149, 74, - 84, 85, 85, 65,167,211,193,104, 52, 66, 16, 4,235,128,148, 72, 36,144,203,229,232,210,165,139, 35,131,199, 42,178,118,237,218, -133,142, 29, 59,162,184,184, 24, 23, 47, 94,116, 88, 92,153, 39, 65,171, 5,203,114, 31,172, 75,184, 88,172,122, 77, 65,231,206, -157,233,225,195,135,177,123,247,110,252,231, 63,255, 33, 63,254,248,163,129,231,121,113,118,118,182,221,214, 48, 65, 16,172, 22, - 44,139,213,205,100, 50,221,242,185,237, 82,187, 29,214, 48,165, 68, 34, 65, 77, 77,141,117, 9,223, 54,181,105,211, 6, 90,173, -150, 43, 43, 43,227,114,114,114,100, 11, 23, 46,124, 57, 41, 41, 41, 16,192,227,119,243,102,179,102,205,154,208,231,159,127,254, - 58,199,113,116,224,192,129, 79,101,102,102, 14, 11, 12, 12,220,251,219,111,191,189, 15,160,157,163,124,190,190,190, 39, 57,142, - 11, 86, 40, 20,226,109,219,182, 25,203,203,203,197,126,126,126,249, 22, 65,107,233, 19, 70,163, 49,171,180,180,244, 1,123,248, -124,125,125,197, 31,126,248,161,177,168,168, 72, 28, 16, 16,144,111,225,145,203,229,226,109,219,182, 25,203,202,202,196,106,181, -250,100, 73, 73, 73,163,124, 26,141,230,201,177, 99,199, 30,220,187,119,175, 15,203,178,200,204,204, 68, 81, 81, 17,212,106, 53, - 62,255,252,115,132,134,134,226,155,111,190,209,106,181,218,231,222,123,239,189,183, 42, 42, 42,236, 9,217,208, 43, 62, 62, 62, -180,164,164, 4,106,181, 26,149,149,149, 56,121,242, 36, 58,116,232,128,156,156, 28, 48, 12, 3,181, 90,141,213,171, 87, 87, 17, - 66,180, 45, 97,146, 97, 89,214,106,101,178, 17, 69, 53,221,187,119, 71, 82, 82,210,116, 71, 68, 17,165, 84, 47, 18,137,110, 17, - 86, 54,175, 77,142,230,141,231,121,177,217, 7,148,216,243,190, 5,160,183,187,187,187,184,246,135, 85, 85, 85,226,192,192,192, -158, 14, 8, 94,111,119,119,119, 0, 64,215,174, 93,161,213,106,121,133, 66, 49,102,218,180,105, 70, 0,152, 48, 97,194,152,235, -215,175,215, 24, 12, 6, 86, 44, 22,163,180,180, 20, 65, 65, 65,222,119,104,197, 99,255,223, 74, 96,153, 21, 99, 18,128, 62,150, -194,217, 46, 17, 54,100,185,170,101,193, 34,141, 12,180,146,172,172, 44,185, 92, 46,183,126,102, 52, 26, 17, 20, 20, 36, 8,130, - 64,106,255,142, 37, 31, 77,133, 72, 36, 82,190,249,230,155, 37,171, 87,175,126, 26,118, 58,138,111,155, 28,133,205,181,196,213, -218, 37,243, 63,250,112,201, 66,175,171,187, 55,226,211, 85,203,120,158, 71,114,231,206,157,123, 86, 84, 84,112, 30,114, 35, 52, - 37,216,133,155,113,176,236, 18,131,230, 88, 90, 27,142, 31, 63,158, 60,104,208,160,195, 27,190,254,206, 43, 39, 61,253,168,180, - 76,147,171,106, 27,193,137, 91,133, 14, 47,175,169, 17,143, 25, 51,198, 23,192,127, 27,226, 98, 24, 6,233,233,233,200,200,200, -128, 66,161,128, 82,169,132, 66,161,128, 74,165,130, 82,169,132, 82,169,116,184, 14, 25,134, 1,207,243,248,246,219,111, 33,147, -201, 32,151,203,111, 73, 22,113,117, 59,109, 51,112,224, 64,104,181, 90, 40, 20,138, 38, 11, 32,139, 56,177, 44,189, 89, 4,214, -151,247,221,135,231,115,114,172, 2,107,133,135, 7,222, 22, 28, 14, 81,134,232,232,104,122,244,232, 81, 28, 62,124, 24,149,149, -149,248,240,195, 15, 17, 24, 24,248, 16,128, 57,142,114, 89,242,105, 52, 26,249,236,236,108,145, 70,163,129, 37, 92,137,165,223, - 87, 85, 85,217, 61, 41,112, 28,103,181, 46, 90,146,173, 21,139,101, 89,248,251,251, 35, 32, 32, 0,107,215,174, 21,135,135,135, - 15,185,155, 55,154,165, 75,151,182, 93,177, 98,197,103,155, 55,111,222,245,228,147, 79,110, 77, 73, 73, 25,231,225,225,113,110, -223,190,125, 11,165, 82,169,208,196,241, 29,156,147,147,227,103,251,145, 32, 8, 50,147,201,100,237, 27, 85, 85, 85,232,212,169, -147,221,124,231,207,159,151, 1,192,194,133, 11, 69, 0,100,130, 32,128,231,121, 88, 56,171,170,170, 68, 29, 58,116, 8,182,115, -162, 72, 35,132,244,236,223,191,255,145, 61,123,246,120,134,134,134, 34, 59, 59, 27,217,217,217,104,219,182, 45, 22, 45, 90, 84, - 89, 86, 86,150, 96, 22, 85, 63,218, 89,236, 32, 79, 79, 79,209,245,235,215, 97, 50,153,208,181,107, 87,172, 94,189, 26, 99,198, -140, 65,167, 78,157, 80, 86, 86,134,243,231,207, 99,211,166, 77,158, 98,177,248,191,119,123,130, 49, 47, 97,213,155,154, 56,238, - 85,110,110,110,101, 82,169, 84, 98,241,191,218,191,127,191,195,214, 43,219, 7, 63, 71,222,183, 4,177, 90, 27, 18,137, 4, 1, - 1, 1,142,172,242, 16, 91,247, 28,141, 70,195, 23, 23, 23, 91,151,241,215,175, 95,207,183,109,219,150, 23, 4,129, 21,139,197, - 32,132, 64,161, 80, 52,187,200,172, 75,139,252, 29, 44, 88, 73,148, 82, 98,118, 40, 39, 22, 97, 67, 41,253,139,168,170, 79,112, -153, 45, 88,164,177,193,198,178, 44,118,239,222,109, 21, 2,150, 93,132,148, 82, 56, 91, 96,121,123,123, 87,198,199,199,171,110, -220,184,241, 85, 83, 45, 87,107,151,204,255,104,241,130,185, 94,218, 11,191, 35, 43, 39, 23,218, 2, 99,242,161,115,215,190, 7, -240, 61, 0, 96, 93,251, 36, 76,184,240,177,189,156,237,125,101, 93, 58, 7, 41,191,127,120,208,144,144,209, 47,188,202,188,244, -210, 75, 61,198,142, 29, 91,250,228,147, 79,190,162, 80, 40,218, 25, 12,134,226,239,118,236,200, 24, 61,122,116, 56,207,243, 99, - 41,165,101,141, 76,220,153, 35, 70,140,176,214,109, 64, 64,128,106,203,150, 45,254, 74,165, 18, 79, 61,245, 84, 97, 70, 70,134, -117, 89,168,188,188, 60,211,158, 60, 26, 12,134,204, 46, 93,186,212,187, 44,104,177, 64, 58,194,105, 49, 75,195,236,208, 94, 84, - 84,132, 75,151, 46,129,227, 56, 60,248,224,131, 56,116,232, 16,122,244,232,225,208, 14, 66, 74,169,117,215,160,193, 96,224, 1, -136, 56,142,195,248,172, 44,171,224,224,184,166,197,210,237,210,165, 11, 61,118,236, 24,206,157, 59, 7,157, 78,135,231,158,123, - 14,230,229, 65, 0,120,196,129, 50,223, 23, 16, 16, 48,112,208,160, 65, 65, 0, 80, 89, 89, 73, 78,157, 58, 5,158,231, 65, 41, - 69, 65, 65, 1, 14, 28, 56, 0,141, 70, 3,134, 97,224,233,233, 25, 76, 8, 9,167,148, 94,107, 96, 66, 32,215,174, 93,195,187, -239,190, 11, 65, 16, 48,125,250,116, 68, 68, 68, 88,133, 85,102,102, 38, 22, 46, 92, 8,158,231, 49,119,238, 92,180,109,219, 22, - 70,163,209,205,145, 56, 99,206,198,107,175,189,118,245,251,239,191,223,117,227,198,141,127, 47, 89,178,164, 55, 33, 68,120,227, -141, 55,222, 85,169, 84,252,237,240, 22,151,150,227,210,149, 76,171, 0,170,157,124,125,188, 28,230,187,156,126,195,250,255, 60, -111,203,199,195,219,203,211,209, 44, 86, 25,141,198,202,225,195,135,171,191,253,246, 91,210,182,109, 91,252,241,199, 31,150,135, -210,170, 38,132,102,200,214,106,181, 17, 44,203,138,175, 92,185,130,176,176, 48,196,199,199,227,157,119,222,129, 70,163,129,201, -100,130,159,159,159, 96, 52, 26, 79,233,245,250, 3,119,123,130,177,181, 50,217,166,253,251,247, 79,151, 72, 36, 20,192, 49, 0, - 14, 9,108, 74,169,190,117,235,214,181,185, 77,104, 33,104,206,157,137,129,129,129,251,149, 74,229,144,226,226,226, 91,172, 88, - 9, 9, 9, 6,127,127,255,131,246,242, 40, 20,138, 98,142,227,188,121,158, 71,106,106, 42, 90,183,110, 45,190,126,253,250, 98, - 66,200, 76, 0,104,223,190,253,226,188,188, 60,177, 37, 58, 64,104,104, 40,106,106,106,138,239, 64,245,253, 69,139,252, 29, 4, -214, 95,118,235,217,138, 30,123, 68,150, 61, 86, 8, 66, 8,170,171,171,111,177,134, 88,118, 17,214, 37,176,204, 19,121,147,150, - 8,205,226,202,125,203,150, 45,255, 91,181,106,213, 97,123,255,207,214, 7,107,221,251, 11,150, 88,196,213,217,195,123,240,227, -197, 82,205,244,197,203, 87, 52,181,178, 59,248,202,163, 3,252,125,146,222, 91, 52, 95,117,117,247, 38,108, 93,247, 1, 61,123, -226, 68,220,137, 19, 39,158,158, 52,105, 82,107,115,135,210, 2, 56, 3, 96,180, 61,187,110, 10, 11, 11,111,241,127,138,136,136, - 72, 83,171,213,254,110,110,110, 72, 79, 79,175, 72, 77, 77,117,120,233,165, 54,167,147,158, 76,110, 17, 87,169,169,169,232,219, -183, 47, 0,224,208,161, 67, 72, 72, 72,112, 88,100,213,212,212, 88, 6, 62, 42, 43, 43,171, 0, 72, 63, 15, 15, 7, 0, 76, 46, - 42,194,201,247,222,195,239,139, 23, 59, 44,212,187,118,237, 74, 79,156, 56,129,140,140, 12,152, 76, 38, 60,250,232,163,182,226, -202,145, 50,119,138,138,138,250,117,223,190,125,190, 10,133, 2,149,149,149,168,168,168,192,216,177, 99, 49,112,224, 64, 84, 87, - 87, 99,207,158, 61,248,233,167,159,160, 84, 42, 81, 89, 89,137,202,202, 74,207,193,131, 7, 31, 33,132,244,170,207,119,144, 82, - 74, 7, 12, 24,128,131, 7, 15,130,101, 89,196,197,197,161,168,200,186,185, 7,254,254,254,117, 93, 99,205,227,253,174, 76, 68, - 28,199,209,253,251,247, 47,233,221,187, 55,110,220,184,241,239,216,216,216, 15,199,141, 27,151,125,187,188,158, 30, 74,116,233, -112, 31,116, 58, 29,116, 58, 29,130,130,130, 80, 94, 94,142,171, 87,175, 66,167,211,193,223, 79,237, 48, 95, 76,167,182, 86, 62, - 63, 63, 63, 84, 86, 86,226,218,181,107,208,235,245,240,241,241,116,164,253, 67, 6, 12, 24,240,219,255,254,247, 63,239, 77,155, - 54,233,251,244,233, 35,249,240,195, 15,137, 74,165, 66, 65, 65, 65, 83,139,188,255,208,161, 67,161,253,251,247,143,188,112,225, - 2,246,239,223, 15,189, 94,143,152,152, 24, 92,190,124, 25,221,187,119, 71, 69, 69,197,177, 19, 39, 78,252, 95, 75,152, 96, 44, -203,119, 54,150,166,217,106,181,218, 0, 96,197,237,244,197,235,215,175, 75,163,163,163,117,110,110,110, 18,179, 88, 91,126,183, -250,118, 29,237,126, 91, 59, 19, 27, 66, 64, 64,192, 84, 31, 31,159,254,109,218,180, 65,126,126,190, 88, 34,145, 32, 33, 33,193, -208,173, 91, 55, 67, 64, 64,192,100,123,121,220,220,220, 46,184,185,185,245,170,168,168,128,193, 96,192,201,147, 39, 33,151,203, -167,247,235,215,111, 74, 65, 65, 1, 10, 10, 10, 36, 50,153,204,250, 48,221,181,107, 87,212,212,212, 92,184, 67,245,215,162,252, -222,156, 34,176,108, 84, 99,109,179,121,163,203,131,246,250, 96, 17, 66,160,215,235, 33,151,203,173, 75, 79,182,145,219,235, 18, - 88, 77, 65, 72, 72, 8,226,227,227,221,183,110,221,250,229,178,101,203,142, 52,133,227,155,255,125, 17,232, 33, 84,133,228, 28, -219,137,180,115,201,248,254,124,137,102,250,226,229,175, 12,253,239,227,249,181, 5,217,182, 9,141,243,181,243,147,119,106,229, -239,157,244,254,210,197, 42,237,133,223,145,155,151,135,157,199, 78, 36,235, 41, 61, 15, 96,186,179, 26,212,178,179,166, 37,117, - 84,219, 48, 13, 26,141, 6,231,207,159,183,136,171, 24, 0,232,209,163,199, 41,139,200, 74, 78, 78, 70,108,108,236, 95,194, 52, -212, 97,185, 43,105,223,190,189,213,154, 85, 90, 90, 42, 0,192, 11,185,185, 88, 31, 24, 8,142,227,240,251,226,197,152,109, 52, -226, 29,145,200,161,193,205,243, 60,180, 90,173,229,201,176, 73,226,202,124, 51,124,125,223,190,125,190, 27, 54,108, 40,219,188, -121,115,145, 32, 8,162, 46, 93,186, 4,119,235,214,141,108,223,126,211,175,251,177,199, 30,195,244,233,211,113,254,252,121,200, -229,114, 36, 36, 36,240,137,137,137,126, 83,167, 78,157,140,155,113,142,254, 2,158,231,197,225,225,225,123, 1, 60,116,225,194, - 5, 0, 56, 66, 41, 77,176, 92,111,232,154, 29, 16,202,203,203, 69, 74,165,178,206, 16, 15, 98,177, 88,236,168,197,193,150,243, -240,225,195,239,190,255,254,251,223, 79,155, 54,237,202,109,114,214,105,193, 26, 50,100, 8,170,117, 6,100,229,151,130,231, 77, -168, 54, 20, 56,204,103,107,193, 26, 50,100, 8,170,106,244,184,158,171,133,201,196,163,188,218,100,111, 63,146, 61,252,240,195, - 63,111,217,178, 37,224,232,209,163,224,121, 94,184,124,249,242,181,225,195,135,171,222,120,227, 13,111, 27, 31, 83, 71,177,234, -241,199, 31, 31,121,248,240, 97,109,100,100,164,215,177, 99,199, 80, 80, 80, 0,147,201,132,135, 30,122, 8, 18,137,228,250,226, -197,139,197, 0, 86,181, 20,129, 37,149, 74,113,252,248,113,167, 8, 43, 91, 72, 36,146, 38, 47, 51,222,171, 56,118,236, 88,246, -164, 73,147, 58,168, 84,170, 21, 61,123,246,236,235,237,237,205,120,122,122,238,111,213,170,213,148,232,232,104,187, 87, 19,196, - 98,241, 56,165, 82,121, 85, 36, 18,177, 90,173, 22, 89, 89, 89, 96, 24, 6,130, 32, 72,140, 70, 35, 2, 3, 3,173, 70,147,254, -253,251,163,117,235,214,252,217,179,103,199,221,137, 50,214,167, 69,238,105,129, 85, 27, 12,195,128, 82, 10,183, 7, 30, 64,238, -158, 61,248,246,219,111, 27, 36, 90,183,110, 29,106,155,244, 8, 33,253,109, 99,101, 88,118, 11, 62,255,252,243,214,239, 36, 39, - 39, 91,157,221, 31,125,244,209, 91, 56,143, 31, 63,254, 23,145, 85,155,179, 46, 20, 20, 20, 92,216,182,109,219,137,165, 75,151, - 30,179,243,102,104,229,180,248, 96,141,124,226,169,220,143,222,125, 59,101,243,246,125,157,114,171,105,238,244,197,203,167,213, - 22, 87,246,114,182, 15, 80,180, 15,246,243,222,191,108,233, 98, 15,139, 53,108,203,169,188, 82,152,232, 4, 71, 26,203,158,178, -219, 90, 18, 9, 33,130, 51, 56,155, 32,168,110,225,180, 13,211,144,155,155,107, 21, 87, 54,129, 70, 99,122,244,232,113,202, 44, -174, 44,215, 76, 13,113, 22, 23, 23, 47,170,125, 29,128,143,165,252, 28,199, 33,225,173,183, 26, 20, 87,245,149,221, 28,143, 10, - 17, 17, 17, 14,139, 43, 91, 78, 66, 72, 66, 85, 85, 21, 54,109,218, 84,126,229,202,149,251,218,180,105, 51,117,227,198,141,203, -101, 50,217, 45,255, 83, 85, 85,133,127,255,251,223, 88,176, 96, 1,158,121,230, 25, 97,220,184,113, 44,195, 48,253, 27,202,103, - 70, 70,198,132,126,253,250,173,171,169,169,225,138,138,138, 38,216,123,173,177,178,111,219,182,237, 74, 68, 68, 68,111,212, 31, -138, 65, 0,112,244,118, 56, 87,172, 88, 1, 0,145,183,195, 89,159, 5,235,235,175,191,134, 32, 8, 8, 9, 80, 67,167,211,161, -118, 93, 55,198, 89,219,130,181,117,235, 86, 8,130,128,214,129, 94,208,235,245,176, 56, 6, 55,198,233,237,237,253,193,230,205, -155,131, 47, 94,188,136,172,172, 44, 44, 95,190, 60,179,164,164,100, 80, 73, 73,137, 52, 49, 49, 49,233,137, 39,158,240, 23, 4, - 65,231,232,216,164,148,234, 8, 33,227,254,245,175,127,125,190,112,225,194, 63,162,162,162, 90, 39, 36, 36,168,139,138,138, 10, - 79,159, 62,125,109,221,186,117, 10,147,201, 52,174,190,165,167, 59, 49,222,109,145,157,157, 61,207,108, 61,117, 72, 88,217,147, -207,227,199,143,191,105,230, 62, 97, 15,247,157, 42,251,237,238, 76,108, 44,159, 31,127,252,113, 22,106,197, 55,115, 52,159, 7, - 14, 28,200, 24, 50,100,200,130,176,176,176, 68,153, 76,134,172,172, 44,107, 64,100,203,152, 33,132,160,111,223,190,120,252,241, -199,113,250,244,233, 5,207, 61,247, 92, 70,115,215,231,223, 13,150, 48, 13,196,246,175,217, 66,112,227,234,213,171,129,109,139, -139,217, 32, 66, 16, 23, 23, 7,219, 51, 4, 45,126, 57, 22, 31,151, 3, 7, 14,152, 4, 65,104, 48,230, 20,207,243, 55, 14, 31, - 62,236,191,103,207, 30,145,197,100,108,118,214, 20,114,114,114,152,164,164, 36,171, 53,140,227, 56,236,223,191,223,100, 48, 24, -174, 59, 90,168,180,180, 52,167, 60,189, 29, 72,205,152,242,243,206, 31,124, 30,140,239, 89,162,242,242,170,115, 0, 91, 34,190, - 55,216,185, 57,230,157, 37,139,230,171, 45,226,234,235, 83,121, 37, 53, 58,190,239,133,194,170,179,206,110,208,242,242,242, 12, -203,110,193,138,138,138,235, 45,165,163, 89,118, 16, 6, 6, 6,158, 66,173,221,130,150,107,177,177,177,127,185,230,112,135,230, - 56, 76,171,168, 0,199,113,232, 51,111, 30, 30, 90,176,192, 33,235,149,101,201,186,246,120,104, 98,153, 15,167,164,164,132, 61, -243,204, 51,202,136,136,136,116, 66,136,232,217,103,159, 21, 2, 3, 3,153,131, 7, 15, 82, 0,232,211,167, 15,201,203,203, 67, -110,110,174,105,252,248,241,194, 51,207, 60,195,156, 57,115,134, 10,130,240,107, 35,220,127, 0,232,231,232,181,198, 48,114,228, -200,116,212, 17,240,243,118,208, 28,156, 22,104, 75,202,144,158,145,141,155,206,232, 2,248,204,124,171,223,148,209,104,130,182, -172,200, 97, 11,214,213,107,217,230,163,193,120,240,124,142,153,239,166,163, 59, 45,110,124, 35,130, 72, 36,234,177, 98,197,138, - 65, 12,195, 48,191,255,254,187,110,233,210,165, 55, 10, 11, 11, 31,165,148, 94, 55,247,179, 62,155, 54,109,250,210,142,144, 12, -245,181,253,121, 66, 72,247, 25, 51,102,188, 2,160, 7,128,214, 0,174, 3, 56, 4, 96, 85, 11,139, 56,190,252, 30,229,110, 50, -238,149,157,137, 63,253,244,211,188, 39,159,124,146,139,138,138,154, 21, 25, 25,201,228,229,229,161,164,164, 4, 44,203, 90, 86, -129, 16, 22, 22, 38,156, 60,121,114,209,184,113,227,230,221,137, 60,213,165, 69,254,150, 22,172,226,226,226, 1,131, 6, 13,218, -195,178,108,184, 69,205,218,250,177,212,113, 40,115, 70,126,126,126,131, 65,200,138,139,139, 7, 76,153, 50,101, 15,203,178,225, - 22,203,148,201,100,210,105,181,218,151,250,244,233,179, 90, 36, 18, 73,109,121, 5, 65,200,204,207,207,191,163,103,233,213,142, -131, 53, 96,208, 48,205,237,114, 42,196,204,253,105, 59, 62, 65,126,129, 6, 95,159,202, 43, 46,215,243,125,210, 10, 43, 83,154, - 35,255, 25, 25, 25, 3, 91,106,103, 51, 11,169, 58,151,254, 26,186,102, 47, 4, 65,128,135,135, 7,234,234,175,142,152,166,157, - 53,184,243,242,242,150,189,245,214, 91,143, 44, 90,180,200,119,215,174, 93, 42,243,111, 96,196,136, 17, 5, 41, 41, 41, 61, 1, - 72,117, 58,221,175,139, 22, 45,242,157, 63,127,190,117, 44, 14, 30, 60, 56, 63, 63, 63,255, 35,184,208, 32,140, 70, 99, 86,199, -246,145,150,182,187, 37, 52,131,237,107,147,201,148,229, 8, 95, 93, 60,182,239,121,158,207,106,196,138, 60, 45, 62, 62,158,157, - 54,109, 90,254,174, 93,187,246, 22, 23, 23,191, 70, 41,173,178,233,103,105,104, 32,152,168,157,125, 85, 7, 96,169, 57,185,208, - 2,239,117,142,188,191, 91,248,242,203, 47,231, 76,152, 48, 97,147,183,183,247, 23,157, 58,117,138, 12, 9, 9, 81,201,100, 50, - 84, 85, 85,149,215,212,212, 92, 58,118,236,216,147, 47,191,252,242, 31, 45,164, 90,187, 1,240, 5, 96, 57, 11,212, 23,128, 30, - 55, 3,207, 22,154, 45,153,247,134,192, 50, 71,171,238,238,228, 78,215, 16,103,104, 75,169,148,177,186,165, 95, 97,221,210, 91, -206, 33,180,136,175, 58,223, 55,178,208, 87, 90,109,154,180,234,231,212,101, 58, 19, 21, 12, 38,225,217,180,130,202,243,255,224, - 27,143,169, 41,215,236, 64,161, 29,145,218, 11,237,200, 31,113, 98, 89, 83, 8, 33,255,154, 52,105,210, 28,153, 76, 22, 7, 0, - 85, 85, 85,191,231,228,228, 44,176,236, 18,108,236,186, 11, 13, 52,102, 97,225, 3, 45,145, 79,175,215, 79,249,215,191,254,181, -146,231,249,247,141, 70,227, 33, 87, 75,185,208,146,177,110,221,186, 63, 44,243,242,168, 81,163, 88, 0,216,182,109, 27,223, 2, -179,234, 75, 8,249,137, 82, 58,196,124,239,252,137, 82, 58,196,246,179,123, 70, 96,253, 83,177, 45,245,207, 9,182,182,112,106, -236,125,125,184,148, 87,177,255,118,159, 88, 93,104, 84,204, 60,220, 66,243,149, 14, 96,108, 83,175,187,112, 79,246,197,235, 0, - 30,117,213,132, 11,247,220,252,215, 50,133,213, 61, 11,198, 85, 5, 46,184,224,130, 11, 46,184,224,130, 11,206, 5, 1,208,191, -158,167, 48,187,119, 7,152,119,112, 57,250,148,247,171,139,211,197,233,226,116,113,186, 56, 93,156, 46,206,127, 22,103, 19, 49, -184,145, 37,194, 29, 45, 78, 97,217, 58,113, 58, 59, 1,232,239,226,116,113,186, 56, 93,156, 46, 78, 23,167,139,211,197,121,155, -169,239,204,153, 51,223,196,205,243,137,233,204,153, 51,223,164,148, 14,190, 41, 99,232,224, 59,156, 23,187,146,203, 7,203, 5, - 23, 92,112,193, 5, 23, 92,104,233, 56,178,120,241,226,170,197,139, 23, 91, 28,218, 11, 1, 16,179,245,170,176, 37,102,216, 37, -176, 92,112,193, 5, 23, 92,112,225, 31, 4, 66,136,220,211,211,115, 47,195, 48,161, 54,159,161,174,215, 0,192,243,124,174, 86, -171,125,132, 82,170,185,147,156,181,160, 7,112,252, 94,170,103,206, 92,112, 75,100,217, 70, 79,176,238, 20,168,232,217, 62, 34, -244,127,185,121,154, 83,186,202,234,241,199,179,203,181, 77,108, 96,111,137, 68, 50, 70, 46,151,247,167,148,222,199,178,236,197, -210,210,210, 95,141, 70,227, 22, 74,105,133,107, 8,184,208, 2,110, 66, 35,165, 82,233, 82, 66, 72, 43,189, 94,207, 73,165, 82, - 19,165, 52,183,166,166,102, 54,165,244, 75, 87, 13,185,224, 66,163, 99,168,222, 3,198,239,230,225,227, 0,160, 84, 42, 79, 50, - 12, 19,108, 59,249, 91,226, 51,214,142,243,104, 19,239,241,143,162,162,162,127, 53, 80,222,251,188,188,188, 86, 3,232,214, 88, - 28, 62,243, 50,219, 9,173, 86,251,146,121, 55,113, 93,124, 74, 79, 79,207,121,132,144, 81, 12,195, 52,122,224,175, 32, 8, 60, -165,116, 91,113,113,241, 92, 74,105,121,125,223,243,244,244,252,245,226,197,139,221,252,252,252, 26, 13, 75, 99, 50,153,112,253, -250,117,223,184,184,184, 3, 0,162,154,147,211, 17, 45,114,207, 8, 44,115, 99,219,117,130, 53, 75,200, 83,107, 23,188,212, 42, - 47,243, 74,171,201, 75,182,182,139, 13,149,245, 73,206,172,202,115,228, 71,221,221,221,199, 68, 71, 71,175, 90,185,114,165,119, - 88, 88, 24,145,201,100,200,205,205,141, 58,125,250,244,240,196,196,196,185, 34,145,104,156,209,104,220,115,155, 3, 91,237, 37, -227,166, 23, 85, 26,223,116,221,230, 92,112,176,239,136, 69, 34,209,190,192,192,192,132,117,235,214, 33, 42, 42, 10, 42,149, 10, - 57, 57, 57,220,185,115,231, 66,166, 79,159,254,133,155,155,219,100,157, 78,215,151, 82, 90,237,170, 49, 23, 92,168,115, 28,117, - 5, 80,231,225,237, 13, 93,187, 83, 96, 24, 38, 56, 59, 59,219, 79, 38,147,129,231,121,115,244,126, 1,148, 82,235, 95, 91, 49, -196,243, 60,162,162,162, 12,141,136,182,143, 11, 10, 10,250,219, 30, 89,214,208,201, 56,217,217,217,253, 59,116,232,240, 49,128, - 71,234, 17, 45,243, 94,121,229,149,169,157, 58,117,178, 88,125,204,167, 22,220,252,171,209,104, 48,105,210, 36,235,111, 8,130, -128, 61,123,246,188, 50,110,220, 56, 0,120,181,129,178,135,250,249,249,145, 9, 19, 26,142, 53,148,152,152,136,196,196, 68,172, - 90,181,138,136, 68, 34,117, 35,245,233, 20, 78,123,181,200, 61, 37,176, 28,192,206, 37, 43, 63, 27,255,246,211, 9,100,221, 43, -125, 35, 94,254,112,223,209,216, 32,207, 94,201, 57,197, 55,236, 20, 87,175,188,248,226,139,239,206,159, 63,223,237,210,165, 75, - 56,127,254, 60, 76, 38, 19,148, 74, 37,162,163,163,153,157, 59,119, 6, 78,153, 50,229, 27,137, 68,242,172, 94,175,255,174,169, - 5, 11, 80,137,222,147, 75,153, 39, 36, 28,119, 76,111, 50,253, 95, 75,172,124,153, 76,182,177,186,186,122,137, 57,178,243,189, -114,211,108,167, 84, 42,103,151,149,149, 61,245,119,157, 24, 56,142, 75, 26, 58,116,104,247,141, 27, 55, 34, 35, 35, 3,233,233, -233,200,201,201, 65,120,120, 56, 58,119,238,140,125,251,246,225,213, 87, 95,141, 59,112,224,192, 33,152, 15,172,182,179,238, 24, -145, 72,244,140,151,151,215, 48,127,127,127,191,194,194,194,194,226,226,226,237, 58,157,110, 67, 83,159,228,205,156, 79,134,133, -133, 13, 11, 10, 10,242,207,206,206,214,100,101,101,253,159, 78,167,219, 72, 41, 21,110,163,157, 3, 1, 68, 3,240, 54,127,148, - 27, 22, 22,150,122,237,218,181, 2, 39,114,230,132,133,133,157,119,148,147, 16, 34, 7,176, 21, 64, 80, 35, 95,205, 1, 48,218, - 28,224,216,133,187, 32,174,204, 71, 79,221, 34,164, 26,186,118,167,225,238,238,142, 45, 91,182, 64, 36, 18, 65, 36, 18,161,184, -184, 24,193,193,193,214,247, 98,177,216,250,186,117,235,214,141,242,241, 60, 31,199,178, 44, 42, 42, 42,192,243,188, 53,149,148, -148,128, 82, 10,169, 84, 10,158,191,121,236,146,205,245,184, 6,234,113, 84, 80, 80, 16,190,250,234, 43,232,245,250,191, 92, 87, -169, 84, 72, 73,249,243, 80, 16,150,101, 17, 31, 31,207, 16, 66, 70, 53, 36,176, 44,150,162, 23, 94,120, 1, 44,203, 90,143,190, -179,188,182, 36,158,231,145,152,152, 8,219, 35,196,238, 36,231, 61, 63, 14,204,133,164,117, 29, 19,210, 37, 72,241,210,195,125, -186,191,231,238, 38,118,231, 77, 70, 8, 70, 3,120,147, 30, 28, 17,208,175,179, 63,226,195,101,208,104,203,240,242,250,147,101, - 89,133,213,241,201, 57,229,105,141, 52, 64, 88,124,124,252,169,125,251,246,169,247,238,221,139,180,180, 52,188,243,206, 59, 0, - 0,185, 92,142,221,187,119,131,101, 89, 8,130,128,129, 3, 7, 22,230,228,228, 68, 81, 74,181, 77, 24,220,161,189, 58, 5, 39, -127,247,102, 47,175,142, 19,191,201,204, 43,213,223, 71, 41,109,113, 1,212, 20, 10, 69, 33,203,178,124, 89, 89, 89,159,123, 65, -100,153,197, 85, 18, 33, 68, 92, 90, 90,234,213, 66,242, 20,211,181,107,215,165,105,105,105,223, 87, 85, 85,125, 92, 75,192, 78, -138,136,136, 24,114,230,204,153, 89,246,222,192, 9, 33, 35,253,252,252,182, 93,185,114, 5, 39, 78,156, 64,113,113, 49, 10, 10, - 10,240,202, 43,175, 96,205,154, 53,232,216,177, 35,228,114, 57, 68, 34, 17,122,246,236, 9,173, 86,251, 44,165,116,163, 29,188, -172,135,135,199,198,213,171, 87,183,125,244,209, 71, 57,157, 78, 7,158,231,177,109,219, 54,227,220,185,115, 51,138,138,138,158, -118, 84,100, 17, 66,152,192,192,192, 13,159,124,242, 73,187,135, 30,122,136,171,174,174,134, 32, 8,216,177, 99,135,113,214,172, - 89,127,228,230,230,142,109, 74,191, 39,132,116,149,201,100, 29, 94,122,233,165,194, 71, 31,125,212, 0, 0, 39, 78,156, 96,206, -158, 61,171,106,211,166, 77,230,156, 57,115, 78, 53,129, 51, 86,169, 84, 70, 78,152, 48, 65, 51,100,200, 16,163, 88, 44, 22, 14, - 31, 62,204,165,165,165,169,194,194,194,210,103,205,154,117,214, 1,174,157, 71,142, 28,233, 29, 28, 28, 44,152,111,234,212,114, -131,103, 24,134,154,255,226,210,165, 75, 92,239,222,189,147, 40,165,255,113, 73,158, 59, 58, 38, 57, 0, 70, 74, 41,180, 90, 45, -142, 29, 59,134,193,131, 7,195,230, 97,228, 20,165, 20,101,101,101,168,174,174, 70, 96, 96, 32, 0,136,238,244,114,161, 90,173, -206, 47, 44, 44,244,251,241,199, 31, 33, 18,137,176,103,207, 30,172, 89,179, 6, 91,182,108,169, 83,100, 5, 6, 6, 34, 34, 34, - 34, 43, 39, 39, 39,164,129,123,122,105, 69, 69,133,170,180,180, 20, 60,207,227,216,177, 99,248,244,211, 79,225,231,231, 7, 31, - 31, 31,248,250,250, 34, 46, 46, 14,114,185,220, 42,178,122,246,236, 89, 86, 81, 81,225, 81, 23,159,183,183,119,206,180,105,211, - 2,147,147,147, 97, 52, 26,235, 20, 88, 83,167, 78,181,181, 34, 65, 38,147,161,123,247,238,185, 69, 69, 69,245, 62,128,248,250, -250,230, 22, 22, 22, 6,156, 61,123,246, 22,241, 83,151, 32, 98, 89, 22, 74,165, 18,225,225,225,249,185,185,185, 1,205,201, 89, -159, 22,185,231, 45, 88,230, 27, 85, 31,219,139,237,194, 3,103,191, 51,101,164, 59,120, 3,168,177, 26, 48, 84, 1,134, 10, 8, -250, 42, 16,177, 59, 96,172,134,143, 84,139,207, 95,108,167,122,107, 91,250,133,174, 1,170,193,167,243,202,118, 55,208,161, 19, -215,174, 93,171, 78, 73, 73, 65, 90, 90, 26, 62,248,224, 3, 44, 88,176, 0, 98,177, 24, 90,173, 22, 67,135, 14,197,145, 35, 71, - 96, 48, 24,240,214, 91,111,121,205,152, 49, 99, 50, 0,135, 15,153, 12, 80,113,107,182,110, 88,229,229,197, 22,225,217,135, 78, -122,127,252,203,181,151, 0,124,216,210, 42, 95, 44, 22, 27, 62,253,244,211,160,231,158,123, 46,137, 16,210,162, 69, 22, 33,164, -157,151,151, 87,210,187,239,190,235, 63,103,206,156, 92, 39,113,250,203,229,242,109,149,149,149, 83,155,242, 4, 75, 8,137, 25, - 49, 98,196,182,141, 27, 55,134,246,234,213,203, 8,224, 22,129,213,174, 93,187,225, 73, 73, 73,189,199,141, 27,119, 31, 33,100, - 52,165,180, 81, 97, 32,149, 74, 23,174, 89,179, 6, 57, 57, 57, 40, 41, 41,129, 68, 34, 1,207,243,150,223,131, 84, 42, 5,195, - 48,112,115,115,195,172, 89,179, 48,119,238,220, 68, 0, 27,237,224,125,102,245,234,213,109, 7, 12, 24,192,101,100,100,128, 97, - 24, 72,165, 82, 60,241,196, 19,162,170,170,170,208,249,243,231,191, 0, 96,181, 35,229, 23,137, 68, 79,174, 95,191,190, 93, 66, - 66, 2,119,241,226, 69,116,239,222, 29,199,143, 31,199,127,255,251, 95, 81,121,121,121,248,244,233,211,199, 3, 88,239,168,149, - 73, 38,147,117,250,237,183,223,110,132,132,132, 88,215, 54,194,195,195,249,193,131, 7,107, 47, 94,188, 24,121,244,232,209,162, -238,221,187, 95,119,128,179,149, 76, 38,139,218,185,115,103,238,252,249,243,251,173, 91,183,238, 81, 0,136,139,139,251,191, 5, - 11, 22,236,211,106,181, 29, 15, 30, 60,168,237,217,179,103,150,157,148, 65,129,129,129,252,164, 73,147, 20, 13,125,233,179,207, - 62, 43, 1,208,154, 16,210,198,124, 0,182, 11,119, 0,148, 82, 19, 33, 36,134, 16,114,106,199,142, 29,136,143,143,199,142, 29, - 59, 48,120,240,224, 83,230,235, 40, 45, 45, 69, 74, 74, 10,122,245,234, 5,220, 60,224,253,174,248, 98,241, 60, 15,142,227,144, -149,149,133,207, 62,251, 12,139, 22, 45, 66, 68, 68, 4,140, 70,163, 85, 96,113, 28, 7,145, 72,100,177,182,216, 53,233,155, 76, - 38,156, 56,113, 2, 95,124,254, 57,222,154, 61, 27, 74,165, 18, 0, 96, 48, 24,160, 45, 46,134,155,155,155,213,130,213, 72, 93, -110,187,114,229,202,212,224,224,224, 91,150, 6, 45,127,205,162, 14,130, 32,192,100, 50,161,166,166, 6,203,151, 47, 55, 81, 74, -183, 53, 50, 38,173, 22,175,169, 83,167, 66,167,251,243,124,240,232,232,104, 0, 64, 88, 88, 24,186,116,233, 98,125,207, 48, 12, -181,151,243,147,127,117, 66,181,205,183, 35, 19,151, 1, 0,130,131,131, 17, 25, 25,105, 17,213,117,114,214,165, 69,238,105,129, - 85,159, 82,188,120, 45,127,201,196, 55, 63, 88, 38,151,178,162, 73,255,233,132, 16,181, 8,112,247,130,184,215, 12, 16,117,232, -205, 14,160,253, 3,248,101, 6,222, 29, 90,196, 76,170,212,253, 16,239,229,229,123, 76,171,173,207,185, 46, 46, 36, 36, 4, 7, - 15, 30, 68,155, 54,109, 48,103,206, 28, 68, 69, 69, 65, 46,151, 35, 63, 63, 31,149,149,149,144,203,229, 40, 43, 43, 67, 76, 76, - 12,171, 84, 42,251, 58, 42,176, 8, 33, 49,207, 13,141,143,227,252,219, 35,161,223,131,248,101,110, 31,249,166,253,217,111, 18, - 66, 54,216, 30,184,218, 66, 68, 11,134, 13, 27, 6,141, 70,227, 63,123,246,236, 38,139, 44,119,119,247, 47, 8, 33,131, 68, 34, -145,129, 16, 2,134, 97,172,135, 29, 91, 94, 27, 12, 6, 49,203,178, 59, 53, 26,205, 83, 77,200,103, 59, 79, 79,207,164, 35, 71, -142,248,203,229,114, 36, 38, 38, 58, 69, 92, 41,149,202,223,199,143, 31,223,250,139, 47,190,216, 77, 8, 25,232,136,200,178, 21, - 87,227,198,141,203, 60,115,230,204,172,218,223, 57,125,250,244,244,103,159,125,118,219,166, 77,155,194, 8, 33,219, 8, 33,163, - 26, 19, 89, 12,195,132, 70, 70, 70, 34, 55, 55, 23,249,249,249,168,169,169, 65,126,126, 62, 0, 32, 43, 43, 11,193,193,193, 80, -171,213, 8, 14, 14, 70, 76, 76, 12, 88,150, 13,180, 39,191, 74,165,114,208,240,225,195,185,195,135, 15, 35, 47, 47, 15, 30, 30, - 30,144,203,229,224,121, 30,207, 63,255,188,120,197,138, 21,255,118, 84, 96,133,132,132, 60,218,175, 95, 63, 46, 53, 53, 21,215, -174, 93,131, 78,167, 67, 90, 90, 26, 84, 42, 21,158,126,250,105,241,210,165, 75,135, 58, 42,176, 0,116,122,225,133, 23,242,109, -197,149, 5,114,185,156,180,107,215, 78,235,237,237, 29, 11,224,186, 35,156,147, 39, 79, 46, 88,188,120,113,175, 95,127,253,117, -134,229,195, 95,127,253,117, 58, 0,172, 92,185,242,160,175,175,111, 44, 0,123, 5, 22, 40,165,194, 99,143, 61,150, 41,145, 72, - 32, 18,137, 32,145, 72,110, 73, 98,177, 24, 12,195, 40,205, 95,103,241, 55, 5, 33,164, 27,128, 15,112,115,135,213,108, 74,233, -177, 22, 34,178, 78, 19, 66, 98, 6, 15, 30,108, 21, 89,187,118,237,194,192,129, 3, 81, 82, 82,130,212,212, 84, 91,113,117,183, -124,176, 32, 8, 2, 68, 34, 17,150, 45, 91, 6,131,193,128, 47,191,252, 18,223,124,243,205, 45,247, 80,149, 74,133, 85,171, 86, - 57,180,156,197,243, 60, 54,109,218,132, 25,211,167, 91,197,149,249,161, 26, 1,254,254,240,246,241, 65,122,122,122,163, 2,171, -184,184,120,238,246,237,219,209,144,147,251,246,237,219,173,175,109,157,220,237,201, 39,203,178,208,233,116,120,248,225, 63, 79, - 26,155, 60,121,178,245,181, 86,171, 5,203,178,150,186, 32,246,114, 86, 83, 96,152,219,159,159, 13,154, 54,205,250, 90,163,209, -212,203,249,119,176, 90,213,105,193,170, 11, 41,185,229, 31,113, 4, 93, 22, 76,124,228,153, 16, 63, 21,104, 69, 62,196, 15,205, -197, 57,173, 12, 43,214,254, 12, 0,152, 58, 50, 6,157,250, 47,132,126,227, 35,152,252, 32,145, 60,155,101,124, 3,192,156,186, -248,124,124,124,188, 77, 38, 19, 8, 33,144,203,229,104,223,190, 61,220,220,220, 80, 88, 88,136,151, 95,126, 25,187,119,239,134, -193, 96,128, 88, 44, 70,155, 54,109, 96, 48, 24,238,107,130,245,234,211,229,239, 45, 82, 23,157,250, 10,201,127,148, 64,230, 29, -130,217,143,199,121, 38,126,121,124, 46,128,233, 45,169,242, 45, 59, 86, 34, 35, 35,177,110,221, 58,255,137, 19, 39, 54, 73,100, -213,212,212,188,163, 82,169,250,109,216,176,193,127,248,240,225,127,185,126,245,234, 85,244,234,213, 43, 63, 47, 47,239,157,219, - 17, 87,106,181, 26, 55,110,220,184,237,117,115,139,184,218,179,103, 79,168, 89,168,248,190,254,250,235,118,139, 44, 66,200, 35, -195,135, 15, 95,191,113,227,198, 86, 99,199,142,205,249,225,135, 31,142, 3,120,174,174,124,125,247,221,119,199, 5, 65, 16,109, -222,188, 57, 20, 64,163, 34,203, 96, 48,136,149, 74, 37,206,158, 61,139, 41, 83,166,220,226,160,106, 89,206, 6,128,180,180, 52, -180,105,211, 6,149,149,149,118,249, 49,250,250,250,250,235,245,122, 60,251,236,179,184,113,227, 79,119,197, 86,173, 90, 89,234, -212,199,209,122,244,247,247,247,175,174,174, 70,207,158, 61, 81, 83, 83, 3, 0, 24, 61,122, 52, 68, 34, 17, 10, 10, 10, 32, 18, -137,124,154,208, 60, 62,131, 7, 15,206,169,239,162, 74,165, 50,120,122,122,182,119,144,211,123,232,208,161,217,235,215,175,255, -203, 82,221,241,227,199,255,227,229,229,245,171,151,151, 87, 59, 7, 57, 5, 91, 49, 37, 22,139,111, 17, 88, 34,145, 8, 12,195, - 8,248,251,227, 61, 0,150, 93,109,107, 0,116,105, 65,150, 44,171,200,218,181,107, 23, 58,118,236,136,226,226, 98, 92,188,120, -241,174,139, 43, 27, 65, 2,142,227,172,227,220,205,205, 13, 49, 49, 49, 86,113, 69, 8, 65, 85, 85, 21, 56,142,179,220,175,237, -186,249,149,148,148, 32, 48, 32, 0, 74,165, 18,109, 35, 34,112,229,242,101, 0,176,190,150, 74,165, 32,132,192,100, 50, 53, 86, -135,229,184,233, 75,245,170,179,155,199, 34,134, 26, 52, 21, 7, 5, 65, 16, 4,203, 61,159, 58,131,211,199,199, 7, 21, 21, 21, -246,114,222,251, 2,139, 16,210, 27, 64, 18,108,182, 70, 18, 66,152,174, 65,202,207, 22, 76,232,247, 76,191, 14,222,168, 46,188, - 6, 55,165, 15,136, 58, 12, 43,214,254,140, 11, 25, 55, 93,163, 86,124,115, 10,155,222, 28, 0,184,123,161,157, 74,131, 0,149, -100,120,125, 2, 75,171,213, 86, 26,141, 70, 47,119,119,119,112, 28, 7,137, 68,130,162,162, 34,204,153, 51, 7, 91,183,110, 69, - 88, 88, 24,120,158,135, 84, 42, 69, 65, 65, 1,196, 98,177, 67,187, 19, 57,142, 12, 78,124,254,223,225,242,128, 8, 20,237, 89, - 96,158,133,186,226,133,161,140,228,253,239,206,141, 37,132,188, 79, 41, 45,104, 41,149,111, 17, 4, 10,133, 2,254,254,254, 88, -180,104,145,255,204,153, 51,191,132,131, 7, 67, 83, 74,211, 8, 33,125,158,127,254,249,164,162,162, 34,255,200,200, 72, 40, 20, - 10, 40, 20, 10,228,231,231, 99,228,200,145,249,121,121,121, 77,181,142,125, 62,126,252,120,127,177, 88,140,171, 87,175,194,203, -203,203, 42, 12,155, 42,174, 84, 42,213,239,191,254,250,107,232,253,247,223,143, 75,151, 46,161,125,251,246,216,186,117,171,239, -227,143, 63,222,168,200, 34,132, 72, 1,188,187,117,235,214, 96,142,227,200,247,223,127, 31, 12,224, 49,123,126,251,235,175,191, - 14, 19,137, 68,171, 8, 33, 15, 81, 74,117,117,125, 71, 34,145, 24,115,115,115, 69, 33, 33, 33,248,236,179,207,192, 48, 12,114, -115,115, 49,107,214, 44, 44, 94,188, 24,241,241,241, 80, 42,149, 8, 9, 9, 65, 74, 74, 10, 20, 10,133, 93, 75, 27,133,133,133, -249, 60,207,135,236,222,189, 27,133,133,127,198,196, 11, 13, 13,133,217, 95, 67,227,104, 93,230,228,228,228, 19, 66, 66,206,156, - 57,131,140,140, 12, 12, 28, 56, 16, 63,252,240, 3, 30,120,224, 1, 0,128, 94,175,111, 74,240, 61,158,101, 89,218, 64,253, 19, - 0,158,206,228, 52, 79, 90, 14,113, 10,130, 32, 88,196,149,237, 95, 91,209,213,200,111,254, 93,224, 97,243,218,212, 82, 51, 57, -112,224, 64,104,181, 90, 40, 20,138, 70, 39,224, 59, 45,176, 68, 34, 17,230,205,155,135, 23, 95,124, 17,254,254,254,152, 49, 99, - 6, 56,142,179, 38,219,149, 0, 71,224,231,239,223,224,117,139, 15, 86, 35,247, 75,165,135,135,199, 60,134, 97, 70,177,118, 84, - 28,207,243,188, 32, 8,219, 74, 75, 75, 27, 12,211, 96,113, 72,183,167, 45,108,235,160,145,188,222, 54,103, 93, 90,228, 94,134, -165,116, 73,102,211, 92,210, 45,226,234,133,190,207,244,235,160,198,142,125,199, 33, 54,148, 0,250,242, 6, 90,214, 8, 34,150, -195, 95,197, 5, 55, 96, 58, 60,147,153,153, 9,181, 90,109,189, 17,118,236,216, 17, 71,143, 30, 69,187,118,237,192,243,188,245, -243,243,231,207,195, 96, 48, 28,112, 96,226,102,125,100,162, 85,211,223, 90,160, 68,202, 6,168,229, 18,244,141,189, 31,240,142, - 2, 43,146,226,131, 87,135,122,249,123,171, 86,180,164,202,183,116, 68,139, 16,154, 51,103, 78,126, 81, 81,209,147, 77,124, 90, - 76, 43, 46, 46,238, 51,123,246,236,124,141, 70, 3,115,232,139,219, 18, 87, 0, 80, 93, 93,253,244,250,245,235,243,147,146,146, -160, 80, 40,160, 84, 42,155, 44,176, 44,150,171,185,115,231,182, 14, 9, 9, 65,122,122, 58, 60, 60, 60,224,237,237,141,232,232, -104, 28, 62,124,216, 55, 36, 36,100,183,121,151, 81,125,229,212, 1,120, 99,212,168, 81,217, 21, 21, 21,194,240,225,195,179, 8, - 33, 91, 8, 33,107,234, 73, 91,134, 15, 31,158, 85, 81, 81, 33,140, 25, 51, 38, 3,192, 43,245,137, 43,243, 13,247,122, 74, 74, - 10, 60, 60, 60,208,174, 93, 59,116,236,216, 17,221,186,117, 3,112,211, 55,161,125,251,246, 8, 15, 15, 7, 0,156, 57,115, 6, -132,144,124,123,202, 94, 94, 94,190,107,227,198,141,198,144,144, 16,116,238,220, 25,177,177,177,232,222,189, 59, 66, 67, 67, 49, -111,222, 60,125,101,101,229,174, 38, 8,172, 29, 91,183,110, 53,134,132,132, 32, 54, 54, 22, 82,169, 20,209,209,209, 8, 10, 10, -194,162, 69,139,244,165,165,165,187,154,208, 76,215, 83, 82, 82,216, 6, 4,183, 10, 64,190,131,156, 55, 78,156, 56,193, 62,248, -224,131,127,217,205, 27, 23, 23,247,127, 10,133,194, 3,128,163,126,125,212, 86, 84, 73,165, 82,107,178,124,206,113,220, 63,193, -130, 53, 21,192, 57, 0,233, 0,102,180,164,140,217,238, 22, 44, 42, 42,194,197,139, 23,145,156,156,140, 7, 31,124, 16,135, 14, - 29, 2,110,134,105,232,122, 55, 31,112, 41,165, 16,137, 68,136,140,140,196,171,175,190,138,157, 59,119, 34, 45, 45, 13, 70,163, -209, 42,128, 24,134,177, 88, 68,237,182, 96,137,197, 98,248,251,251,195,104, 52, 90,173, 87, 0,112,229,242,101,112, 28, 7, 65, - 16,160,215,235, 27,181, 96,121,120,120,204,251,244,211, 79, 95,209,104, 52,129,133,133,133,126,182, 41, 63, 63,223, 47, 55, 55, -215, 47, 59, 59,219,239,198,141, 27,126,153,153,153,126,215,174, 93, 11, 92,178,100,201, 43, 30, 30, 30,118,185,214,176, 44,139, -232,232,104, 76,158, 60,217,154, 62,250,232, 35,107, 74, 74, 74,178, 58,165, 59, 50,175, 69, 38, 46,195,160, 66,106, 77, 59,125, -137, 53,165,190, 62,161, 33,206, 91,180,200,223, 69, 96,217, 6,248, 66,151, 96,197,194, 5,227,123, 61,211, 47, 74,133,159,246, - 37, 99,225,247, 87, 47,253,145,173,129,144,159, 2,161,240, 34,166,142,140, 65,251, 48, 47,180, 15,243,194,212,145, 49, 16, 10, - 82, 65,139,211, 65,165,106,100, 20, 11, 57, 13,152, 77,151, 44, 88,176,160,196,203,203, 11,238,238,238,144, 72, 36,200,202,202, - 66,135, 14, 29,172, 55, 71,137, 68, 2,134, 97,240,214, 91,111, 21, 22, 22, 22,174,181,183, 32,114, 9,243,194,146,105,163,253, -197,110, 10,224,198, 1,168,148, 10,124,246,241, 50,160, 34, 7, 96,197, 24,218,187, 11, 27,232,163,126,136, 16,210,174, 5,221, -128, 0, 0,249,249,249, 24, 61,122,244,109, 9, 33,139,200, 42, 42, 42,234, 51,113,226,196,252,131, 7, 15, 58,141,179,172,172, -172,207,140, 25, 51,242,243,242,242,110,241, 39,112, 20, 10,133, 98,186, 32, 8,234,165, 75,151,230,197,196,196,228, 14, 27, 54, - 44,119,192,128, 1,185, 9, 9, 9,185,157, 59,119,206,237,211,167, 79,174, 94,175,231,212,106,245,178, 70,242,180,247,135, 31, -126, 24, 54,110,220,184,204,205,155, 55, 7,141, 24, 49, 34, 14,192,103,148,210,151,108, 19,128, 79, 71,140, 24, 17,183,121,243, -230,160,113,227,198,101,126,247,221,119,141,250, 96,213,212,212,204,155, 49,227,230, 60,165, 84, 42, 33,145, 72,224,235,235,107, - 21,194, 98,177, 24, 82,169, 20,213,213,213,152, 61,123, 54, 74, 74, 74, 22,218, 83,118,157, 78,183,105,254,252,249, 25, 43, 86, -172, 48, 84, 87, 87,131,101, 89,228,231,231, 99,234,212,169,250, 77,155, 54,221,168,172,172,116,212, 87, 10, 70,163,113,211,219, -111,191,157,254,241,199, 31, 27, 56,142, 67,105,105, 41, 84, 42, 21,222,120,227, 13,253,134, 13, 27,178,170,171,171, 63,113,148, -179,123,247,238, 87, 51, 51, 51, 85, 85, 85,127,117, 87, 20,137, 68, 68, 46,151,119, 3,176,207, 17,206,152,152,152,244,235,215, -175, 43, 23, 46, 92,184,191,127,255,254, 75,148, 74,229,101,165, 82,121,185,127,255,254, 75, 63,252,240,195, 36, 55, 55,183, 56, - 0,191, 58, 56,118, 4, 91, 81,101,107,189,178,124,198,113,220,223,222,130, 69, 41, 77,162,148, 70, 83, 74,239,167,148,254,214, - 82,197, 85,106,106, 42,122,246,236,137,238,221,187,227,240,225,195, 72, 72, 72,104, 17, 34,203, 34,176, 56,142,195,227,143, 63, -142,189,123,247,162,109,219,182, 86,199,118, 91, 39,119, 71, 68,134,201,100, 66,167, 78,157,160,211,235,111,177,124,113, 28, 7, - 95, 63, 63, 92,189,122,213, 46, 11, 22,195, 48,163,134, 13, 27,198,156, 63,127, 30, 81, 81, 81, 56,117,234,148, 53,157, 57,115, - 6,231,206,157, 67,106,106, 42, 46, 92,184,128,216,216, 88,100,102,102, 98,216,176, 97, 12,195, 48,163, 26,225,181,219,218,100, -217, 9,216,152, 5,207, 89,156,182, 90,228, 94, 71, 93,129, 70,209,198, 71, 54,238,161,182, 44,126,250, 45, 25,139,182,223,216, - 36, 0,223,253,120,186,244,167,105,221, 5, 24,182, 61,129, 78, 35, 63,191,185, 44, 8, 64, 40, 72,133, 97,219, 83, 32, 50, 31, - 28,202, 22,163,172,202, 88,239,137,214, 6,131,225,152,167,167,231,150, 13, 27, 54,140,127,246,217,103, 37, 0, 32,147,201,240, -218,107,175,129, 82, 10,137, 68, 2,150,101, 49,113,226,196,138,130,130,130,229,148,210,171,118, 14,102,247, 86,158,146,183,158, -156, 52,199, 13,103,214, 3,140, 24, 26, 69, 12,162, 7,140, 71, 65,218, 81,160,232, 34,192,138,177, 54,241,121,159,255, 76, 94, -182, 30, 64,207,150, 34,176,174, 92,185,114,219, 86,166,218,130,136, 16,210,103,230,204,153, 95, 22, 21, 21, 61,233, 76,206,167, -159,126, 58,105,239,222,189,254, 77,229, 41, 47, 47,127, 13,192,107, 78,186, 49,158, 50,199,122,217,182,113,227,198,208,140,140, -140,165, 0, 30,178,253, 78,151, 46, 93, 22, 89,156,224,237, 17, 87,102,222, 47,221,220,220,166, 76,157, 58, 53,118,197,138, 21, -144,201,100, 80,169, 84, 72, 75, 75,179,198,193,169,174,174,198,152, 49, 99,160,211,233,206, 83, 74,215,217,153, 95, 19, 33,228, -169,119,222,121,103,252,202,149, 43,135,176, 44,235,203,243,124, 97,117,117,245,238,234,234,234,245, 77,217, 69, 69, 41, 21, 8, - 33, 99,231,204,153, 51,118,249,242,229,195, 24,134,241, 51,153, 76,154,242,242,242,237,213,213,213, 77,138,173,117,228,200,145, -194,213,171, 87,255, 81, 88, 88, 24, 21, 28, 28, 92,170, 80, 40,244,122,189,158,117,119,119, 87,201,229,242, 24, 0, 71, 1, 92, -112,132, 51, 57, 57, 57,111,237,218,181, 25, 58,157, 46,114,237,218,181, 7, 85, 42,213, 94, 66, 8, 17,139,197,158,238,238,238, -125, 1,236, 7,112,197,161, 39, 67,134, 17,108,173, 85,181,253,175,204, 15,106,255, 4, 11, 86,139,131, 57, 76,195, 41, 74, 41, - 52, 26, 13,206,159, 63,143,190,125,251, 2,230, 48, 13, 61,122,244, 56,117,232,208, 33, 36, 36, 36, 32, 57, 57, 25,177,177,177, -167, 8, 33,119, 60, 76,131,173, 5,203, 34,164, 90,183,110,109,125,111,155,108,124,176,236, 2,207,243, 16,139,197,224, 56, 14, -129, 65, 65,214,223,162,148,226,234,213,171,208,106,181,118, 9, 44,150,101, 89, 66, 8,198,140, 25, 99,215,239, 62,246,216, 99, -216,191,127, 63, 88, 59,213, 32,203,178, 8, 11, 11,107,244, 59,150, 91,142,189,156,193,193,193, 77,230,180,213, 34,127, 27,129, -101,139,244,252,202,133,227, 87, 30,121,243, 98, 94,205,119,103,114, 42, 95, 5, 64, 65,229,191,116,246, 97, 31,233, 23,145, 5, -221,250, 30, 32,170,155,147, 13,173,200, 5,145,251, 35,139,182,194, 59, 63, 93,206, 35, 2, 93,218,208, 15,150,148,148, 76,253, -232,163,143,216, 95,126,249,101,244,226,197,139, 61,162,162,162,240,212, 83, 79, 65,175,215,227,220,185,115,120,241,197, 23,181, -133,133,133,235, 74, 74, 74,150,216, 91, 8, 31, 5,247,246,138,151, 31,241,102,140, 21, 64,222, 41, 64,234, 1, 31, 79, 5,206, - 30, 63, 0,228, 37, 3,172, 24, 96, 37,120,160,115, 20,162,219,223, 31, 69, 8,233, 65, 41, 61,116,183, 43,223,104, 52,138,123, -247,238,237, 52,113,101, 43,136,224,160, 31,151,189, 34,171,127,255,254, 73,148, 82,105, 11,121,122, 63, 69, 8, 25,121,237,218, -181, 69,151, 47, 95,254,169,246,245,203,151, 47,255,212,187,119,111,209,233,211,167,167,219, 35,174,108,172, 77,189, 14, 31, 62, -124,160, 71,143, 30,177, 51,103,206, 68,108,108, 44,218,181,107,135, 51,103,206, 32, 57, 57, 25,137,137,137, 48, 24, 12,231,170, -171,171, 19, 28,204, 47,143,155,187,250,214, 59,177, 14, 4,220, 12, 19,177,209, 89,156, 47,189,244,210,217,244,244,244, 34, 95, - 95,223,120,177, 88,220, 25, 55,253,124,242, 0,108,112, 84, 8, 89,240,226,139, 47,158, 73, 79, 79,215,180,106,213,234, 65, 51, -167, 26, 64, 54,128, 79,155,192,153,115,242,228,201,224,110,221,186, 49, 34,145,136,178, 44, 11,145, 72, 68, 57,142,163,102,191, - 25, 10, 0,219,183,111,151, 2,208,194,133, 59, 61, 46,173, 97, 26,114,115,115,173,226,202, 38,208,104, 76,143, 30, 61, 78,153, -197,149,229,154,233, 46,229, 21,243,231,207,199,186,117,235,208, 88, 4,114,243,110, 61,210, 24,159,197,130,197,243, 60, 12, 6, - 3, 82, 83, 83, 65, 8, 1,207,243,214,101, 65, 75,136, 6,147,201,212, 96,164,119,158,231,121,189, 94,143,175,191,254,218, 46, -145,245,213, 87, 95,161,166,166, 6,124, 35,202,205, 54,164, 66,151, 46, 93,160,213,106, 17, 20, 20,100,177, 56,219, 26, 69, 28, - 18,172, 22,206,200,200, 72,104, 52, 26,248,248,220,220,103, 19,242,244, 11,127, 90,247, 42,255, 57,113,127, 73, 67,141,123,139, - 53, 32, 76,237, 65, 13,252,247,131, 58, 72,250,140,236,234,129, 48,127, 37, 68, 98, 41,114,203, 76,216,119,169, 28,155, 14,228, -221,168,228, 77, 67, 82,179, 42, 83,236,108,140, 7, 3, 3, 3,103,241, 60,223,145, 97, 24, 25,165,180,130,101,217,211, 57, 57, - 57,243, 40,165,169,142, 20, 66,237,206, 94,241,148,179, 30, 34,145,132,242,130, 0,128, 1,136, 37,177, 55,255, 50, 55,223, 87, -215, 24,196, 60, 37,223,229, 23,106,158,187,219,149,239,235,235,187, 81,163,209,220,115,145,220,189,189,189,103, 55, 37,220,195, - 61,248, 36, 62, 86,169, 84, 46,166,148,250, 86, 86, 86,178,114,185, 92, 96, 24,166,176,172,172,236,109, 74,233, 39,112,225,110, -181,139, 37,146,123,120, 35, 95, 45, 0, 48, 5, 64, 57,165, 52,195, 85,115,119,188,157,186, 2, 56,133, 58,118, 11, 54,116,237, - 78,193,219,219,251,216,207, 63,255,252, 64,155, 54,109, 24, 91, 71,118,134, 97,172,193, 49, 25,134, 1,199,221,180, 67, 28, 56, -112,192, 52,102,204,152,163,121,121,121,189,234,227, 84,169, 84,191,156, 59,119,238,225,210,210,210,191, 8, 41,219,200,238,150, -247,149,149,149,152, 56,113,226,158,178,178,178, 58,143,202, 81,171,213,203,223,127,255,253, 87, 70,140, 24,193, 88,194, 74,216, - 38,203,177, 62,150,100, 48, 24,240,249,231,159, 11, 43, 87,174, 92, 85, 82, 82, 82,239,206,195,160,160,160, 27, 57, 57, 57,193, -150,144, 9,245, 37, 91,132,133,133,229,102,100,100, 4,221, 73,206,127,140,192, 50, 15, 10,210, 41, 80, 62,154,128,140, 98,128, - 78, 12,129,196, 72, 73, 26, 64,127, 17, 65,177, 58, 57, 39,199,117, 46,155, 11,127,215,201,226,174, 30, 76,235, 66,157,109,210, - 6,141,199,184, 50, 2,200,114,181, 93,203, 27, 55,119,123, 76, 17, 66,228, 94, 94, 94,123, 89,150, 13,181, 88, 96,108,125,130, -234, 56,232, 57, 35, 63, 63,191, 95, 67,241, 20, 9, 33,247, 41,149,202,143,121,158,143,179,231,176,103,150,101,143,151,151,151, - 79,106,232,176,231,230,216, 69,232,227,227,115, 53, 51, 51,243, 62,153, 76,102, 93,186,180, 45,119,237,188, 95,185,114, 5,189, -123,247,206,204,205,205, 13,187,147,156,255, 40,129,229,130, 11, 46,184,224,130, 11, 46,220,243,194,183,157,151,151,215,207, 34, -145, 72,106, 43, 34,107,191,182,192,100, 50,213, 20, 22, 22, 14,108,104,181,165, 57, 56,239,121, 88,148,166,189,233,230,191,216, -253,221,254,246,114,154, 83,239,150,206,217,140,101,167, 78,228,236,109,230, 76,188, 71,242,217,187,165,114, 90,202,107, 47,175, - 35,156,246,246, 41, 7,243, 73,157,157,207,230,226,116,214, 56,170, 35,159,180, 25,218, 61,241, 30,201,103,239,150,198, 89,187, -255,216,195,235, 40,167, 61,125,170, 9,249,164,206,206,103,115,113,222,238, 56,106, 32,159,244,118,251, 82, 61,109,159,232,168, -246,184, 23, 19,231,160,234,165,205, 36,242,136, 13, 63,105,169,156,182,245,224,204,144,254,205,112, 60, 64,146,179, 57,107,213, -167,179,144,104,222, 49,178,223, 60,240,156, 86,118,103,180,123,173,178, 58,133,215,150,211, 89,117,105,203,227,172,126,223,220, -156,206, 26, 75,181, 57,157,209,239,235,106,247,102,108, 35,103,229,211, 41, 99,169, 57,250,124, 29,253,231,182,121,107,115, 58, - 99, 44,213,230,116, 70,191,191, 19,156,206, 24, 75,117,113, 58,163,223,215,215,246,255, 20, 75, 33,211,148,202,106, 38,147,165, -211, 15,120,108,142, 19,185,155, 67,100, 18, 66,168, 57,130,109,139,231,116,114, 27, 37,154, 57, 19,157,200,217,199, 89,109,212, - 28,253,221,150,211, 89,252,181,121,156,209, 78,117,113,222,110,126,235,201,167,211,203,126,187,253,254, 78,113, 58,185,141,156, - 50,150,106,113,246,113,242, 67, 64, 31,155,247,137,206,228,116,214, 88,170, 35,159,183,221, 78,117,113,222,110,126,235,201,167, -211,203,238,140, 57,164,185,120,239, 5,112, 45, 33, 19,205, 33,132, 44,131,206,153,220,205, 97,197,105, 46, 75,155,179,172, 56, -117,240,238,119, 34, 93,146,179,243,105,206, 31,249, 59, 5,171,115,141, 37,215, 88,186,151,199, 82, 93,253,134, 82,154, 72, 8, -153,219,146,250,121,109, 78,103, 9,161, 58,202,126, 91, 99,169,246,255, 58, 99, 44, 53,194, 73,154,163,252,206, 30, 79, 45, 17, - 76, 75,201,136, 89,213,210,102,224,235,211,146, 27,160,153,242,217,231, 94, 40,123,115,228,147, 16,146,216, 76,101,191, 87,234, -212, 53,150, 92, 99,169,197,141,165, 90,125,178,143,179, 44, 67,206,126,144,170,205,233,140,223,176,229,112, 86, 31,109,238,178, - 59,115, 44, 53, 71,219,223, 43,248,255, 1, 0,166,217,112,195,230,179,174,247, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, + 68, 82, 0, 0, 2, 88, 0, 0, 2,128, 8, 6, 0, 0, 0, 64, 11, 6,158, 0, 0, 0, 4,115, 66, 73, 84, 8, 8, 8, 8,124, + 8,100,136, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 0, 25,116, 69, 88,116, + 83,111,102,116,119, 97,114,101, 0,119,119,119, 46,105,110,107,115, 99, 97,112,101, 46,111,114,103,155,238, 60, 26, 0, 0, 32, + 0, 73, 68, 65, 84,120,156,236,157,119,120, 84,197,254,198,223, 57,101,119,179, 37,155, 70, 18, 82, 40, 9, 16, 90, 0,105,210, + 69,138,160,136,130, 8, 40, 94,189, 42,122, 17, 5, 11, 54, 34,162, 72,141,247,122, 69,192,159,136,122, 85, 64,233, 42,136, 94, + 17,174, 20,233, 2, 22, 64,122, 79, 66,122,207,246,221, 51,191, 63,178,103,221,221,108, 11,108, 20,113, 62,207,115,158,221,211, +222, 51,115,234,123,190, 51,103,134, 80, 74,193, 96, 48, 24, 12, 6,131,193, 8, 31,220, 31,157, 0, 6,131,193, 96, 48, 24,140, +235,141,122, 27, 44, 66, 72,200, 33, 47, 66,200,224, 80, 53,157, 67,255,107, 93, 51,148,229,234,171, 41, 15, 97,212,236,239,212, +156, 17, 70,205,134, 76,103,255,107, 85, 83,206,111,168,186,245,209,244,254, 31,166,116,134,116,222, 95, 11,154,193,150,189,138, +116, 6,212,190,194,227, 62,227, 79,146,206,254,215,154,166,247,249, 19,138,110,125, 53,221,211, 29,198,116, 6, 61,239,175, 21, +205, 64,203, 95,101, 58,253,106,135,122, 46,249, 57,246, 51,130,173,123, 61, 32,212,103,225,250, 24,140,250, 64, 41, 37,110,250, +228, 90,213,148, 33,132, 80, 89, 63, 28,132, 83,203,201,182,112,107,122,237,207,112, 49,131, 82, 74, 8, 33,219, 1,244, 15,147, +230, 54,167,230, 85, 31,119,175,188,134, 69,183,190,230,170,190,154,225, 58,239, 27, 90,211,125,218,213,156,171,222,154,225, 56, +239,125, 29,247,112,106,134,235, 90,242, 90, 63, 44,215, 82, 67,156,243, 62,206,159,171,214,245,214, 12,199,181,228,173, 25,142, +243,254,247,208,148,167, 95,205,181,228, 75, 51, 28,231,189,191, 99,127,181,186,127, 22,234, 21,193,106,200, 29,227, 60, 0, 55, +135, 91, 51,220,105,110, 8,147, 25,202, 91,226,181,162,137,240, 30,163, 25, 78,205, 25, 97,212,188, 57, 92,199,168, 33,206,119, +119,205,112,233,123,235,132,227, 56,249,210,188,218,244,250, 73,231, 85,225, 75,243,106,207,251,223, 75, 19,225, 61, 70, 97,185, +150,188, 52,195,118, 45,121,231, 55, 28, 17, 12,119,205,112, 93, 75, 62,210,121,213,199,201,151,230,213,166,215, 79, 58,175, 10, + 95,154,225,120,134, 52,148,238,159,129,122, 69,176, 26,138,134, 48, 66, 64,237, 69, 23, 78,237,134,136,226, 52, 84,164, 45, 92, + 81, 28, 31,186,219,195, 40, 23,182,104,147,140, 51,125, 97,121,163,253, 51,194,174, 37,118, 45,225, 26,187,150,124,157, 55,148, +210, 25,132,144, 87,195,169,121,181,120,107,134,203, 8,249,200,251, 85, 93, 75,222,235,134,227, 90, 10,162,121, 85, 17,102,127, +249,191, 26,221, 63, 11,215, 76, 37,247, 96,229,189, 87,161, 23,214,168, 88,184,105,160,116,222,252,103,200, 59, 26, 32,157,132, +144, 25, 13,148,247, 63,203, 62,101,215, 18,187,150,194, 66, 56,175, 37,175,115, 50, 44,105, 13,247,121,238, 75, 51, 28,219,112, +215, 8,215, 57,218,208,121, 15,231,181,212, 16,199,254,207, 66,189, 35, 88, 13, 93,108,114, 45,107, 54,132,118, 3,229,125, 59, + 26,224,237,160, 1,234,117,109, 71,248,163, 2, 51, 16,198, 34, 71, 57,207,225, 76,107, 67, 22, 19, 54,196,185,217,144,231,123, + 56,235,121, 52, 80,222,183,227,207,113,220,183, 35,204,233, 12,215,181,228,227,152,111,199, 85,166,213,215,254, 11,119, 17,118, + 56,207,205,134,212, 12,135,118, 67,164,211,143,238,118,252, 5, 34, 87, 50,215, 76, 4,139,193, 96, 48, 24, 12, 6,227,122,129, + 80,214,208, 40,131,193, 96, 48, 24, 12, 70, 88,241, 91, 68,152,146,146,178, 81,163,209,180,244, 55,191,166,166,230,114, 94, 94, +222,128,134, 73, 22,131,193,184,158, 32,132,112,248, 45, 98, 46, 1,160,148,189,221, 49, 24,140,235, 24,191, 6, 75,165, 82,165, + 31, 59,118, 44, 67,146, 36, 56, 28, 14,216,237,118,215,175,197, 98,193, 77, 55,221, 84,239,250, 91,141, 27, 55,222,193,243,124, +243,250,172,227,112, 56, 46,230,231,231,247,245, 55,159, 16,178, 27, 64, 58, 33,196,125, 90,192, 95, 0,121, 86,171,181, 75, 32, + 77, 66, 72,186,183,158, 31, 45,249,127, 64,205,232,232,232, 3,130, 32,164,250,210,242,247, 95,146,164,179,133,133,133,189,253, +105, 50,194, 75,227,198,141,119, 8,130, 80,239,243,243,242,229,203,126,207,207,228,228,228, 31, 57,142, 75,174,135, 36, 47, 73, +210,137,203,151, 47,247,245,103, 64,228,115, 62,144,136,247,249, 68, 8,201,177,219,237,221, 2, 44,239, 87, 51,192, 57, 31, 80, +211,109, 89, 78, 16,132,236,132,132,132,137, 6,131,193, 4,128,242, 60, 79,227,226,226,228,180, 1, 0,236,118,123, 81, 89, 89, + 89,135, 96,122, 12, 6,131,241,103,192,175, 73,146, 36,137, 51,155,205, 56,121,242, 36,252,220,231, 29, 87,176,189,140,131,255, +219,156, 16,153,144, 8,187,213, 10,109,163,120,151,118,193,175, 71, 96,183, 89, 97,183, 88,208,180,123,207,218, 13, 56, 28,104, +223,190, 61, 31, 68, 51,245,245,215, 95, 79,136,140,140,132,201,100,130,201,100,130,217,108,134,201,100,130,197, 98,129,197, 98, +129,213,106,133,213,106,133,221,110,135,217,108,198,150, 45, 91,130,165, 61,117,206,156, 57, 9,122,189,222,165, 39, 15,178,166, +172,107,179,217, 96, 50,153,240,221,119,223, 5,212, 20, 4, 33, 53, 47, 47, 47, 65,161, 80,128, 82, 10, 73,146, 64, 41,245, 24, +188,105,209,162,133, 53, 72, 58, 25,225, 37, 99,206,138,175, 18,162,212, 42,216, 37, 9,195, 59,181,112,205, 56,251,193, 26, 80, +187, 3,146,221,142, 86,147,238, 7, 0, 80, 74,209,174, 93,187,128,231, 39,165,180,217,156, 21, 95, 69,135,170, 89, 92, 92,108, +108,219,182,109, 30,106, 43,130,250,139,240,164, 26,141,198, 4, 57, 13, 50,178, 81,225, 56,206, 99,216,180,105, 19,134, 15, 31, + 30, 44,239,169,207, 60,243, 76,130,205,102,131,197, 98,129,217,108,134,205,102,131,221,110,119, 13, 14,135,195, 53, 88, 44, 22, +236,219,183, 47,152,166, 28,185,122,253,150, 91,110,121,248,171,175,190,210,126,241,197, 23,218,230,205,155, 67,161, 80,128,231, +121,240, 60, 15,142,227, 32, 8, 2,122,244,232,241,151,169,252,202, 96, 48,174,127,252, 26, 44,179,217,124,174,115,231,206,212, +249, 63, 69,165, 82, 41,220,231, 19, 66,146, 51, 50, 50, 78,120,175, 23,172,232, 48, 50, 33, 17, 89, 77, 98, 1, 0,175, 92, 40, +145,181,240,207,222, 55,184,150,153,153, 91, 1, 0, 80,171,213, 32,238,175,205,126,208,106,181,184,229,150, 91,160, 84, 42,209, +173, 91, 55,136,162,232,115, 80, 40, 20, 16, 69, 49,152, 28, 8, 33,208,233,116,120,237,181,215, 0, 0,130, 32, 64, 27,161,194, +228,222,221, 16, 1,138,247,142,156,130, 69,162, 16, 4,193, 53,132,162,169, 80, 40,112,248,240, 97, 8,130, 0,158,231, 93,191, +242,255, 13, 27, 54, 96,244,232,209, 16, 4, 1,106,181, 26,248, 11,125,109,113,173, 16,165, 86,225,239,139, 63, 7, 0, 92,154, + 63, 9, 64,237,177,219,247,248, 43,174,101,154,253, 99, 44, 8, 33, 16, 69, 17, 28, 23,252, 59,145, 80, 53, 75, 75, 75,141,247, +222,123,239,206,200,200,200, 77,149,149,149, 1, 53, 41,165,184,116,233, 18, 4, 65,240,123,190,115, 28,135, 55,223,124, 19,167, + 79,159, 14, 41,239, 38,147, 9,239,191,255, 62, 28, 14,135,135,174,252,223,123, 90, 48,156,230,106,246,144, 33, 67,238,255,234, +171,175, 98, 8, 33,120,251,237,183, 33,138, 34,110,191,253,118,196,197,197,225,219,111,191,133, 66,161,192, 11, 47,188, 16, 82, + 26, 25, 12,198, 95, 22, 17,192, 13, 0,226, 81, 27,224,169, 2, 16,237, 54,191,200,249, 27,239, 54,254,131, 15,157,238,206,101, +228,249,242,184, 5,128,210,199,244, 18, 0,106,231, 96, 6,176, 27, 64,166,219,118,228,245,220,211,241, 3,224, 52, 88,164,182, + 85,213,109, 0,110,150, 27,191,187,124,249,242,109,242,210, 45, 90,180, 56,118,226,196,137, 54,178,215,113, 22, 21, 42,236,118, +123,134, 92,108, 40, 71,135, 6, 15, 30, 28,240,141,222,110,245, 12,202,184, 23, 17,120, 79,119,255,245, 7, 33, 4, 86,171, 21, + 99,199,142, 5, 0,191, 15, 27,247, 33, 4,207, 6,139,197, 2, 65, 16,208,186, 73, 60,166, 15,237,140, 27,169, 13, 53,213, 4, +246,138, 26,140,208,217,112,172, 93, 23, 44,185, 88,132, 11,149,213, 16, 4, 33, 36, 77, 73,146,252,154, 43,158,231,177,120,241, + 98,220,123,239,189,224,121, 62, 36, 61, 70,248,177, 75,146,199,184,191,115, 51,212,243, 51, 84,205,210,210, 82,227,240,225,195, +247,170, 84,170,165,137,137,137,121, 57, 57, 57, 1, 53, 41,165,117, 76,143,247,203,196,191,255,253,111, 44, 92,184, 16, 3, 6, + 12, 8, 41,157,102,179, 25,132, 16, 44, 89,178,164,206,188, 89,179,102,213,217, 94, 32, 77,231,139, 17,151,156,156,252,248, 55, +223,124,163,151,151,109,212,168, 17, 68, 81, 68,135, 14, 29, 16, 25, 25,137,157, 59,119,194,225,112,132,124, 93, 50, 24,140,235, + 23, 95, 94,196,141,155,178,178,178,186,101,103,103,207,237,213,171,215,202,221,187,119,175, 32,132,108,148,103, 82, 74,135, 59, + 53, 54,186,141,119,135,167,201, 18, 1,196, 19, 66, 54,202,203,187,143,187, 77, 31, 12, 64, 41,143,103,101,101,101,102,103,103, +207,157, 58,117,234, 75,243,230,205, 83,100,101,101,117,204,206,206,158, 43,111,199, 87, 58,128,223, 34, 88, 1, 91, 1,150,139, + 11,143, 31, 63,238,175,184,208, 69,176,246, 51,180,141,226, 93,145,171,153,205,226, 92,211, 95,203, 41,119, 61,184, 22,117,109, + 9,173, 86,139,161, 51,255, 21,112, 91, 64,237,195,202, 98,177,160,176,176,208, 21, 85, 8, 54,132,170,169, 81, 71, 96,203, 51, + 29,112,169, 68,137, 25,123, 74,241,213, 79,167, 33,138, 34,110,109,215, 1,183, 41, 34,241,114, 51, 37,158, 57,117, 30,182, 16, +235,234, 82, 74,125, 26, 43,249,191, 92, 84,194, 12,214, 31,199,240, 78, 45, 92, 81,166,125,145,131, 92,211, 71,215, 28,118, 29, +147,103, 23,255, 19, 0, 48,160, 75,143,160,215, 67, 40,154, 37, 37, 37,198,190,131,110,222,238, 48, 90, 62,190,255,254,251,207, +109,221,186, 85, 29, 74, 90,125, 25, 44, 57, 74, 43,155, 43, 65, 16, 96,177, 88, 66,202,187,197, 98,241,123,125, 40, 20,138,122, + 71,176, 0,160,166,166,198,178,126,253,122, 44, 90,180, 8,113,113,113, 24, 50,100, 8,146,146,146,176,102,205, 26, 80, 74, 49, +105,210, 36,168,213,106, 57, 90, 29,146, 38,131,193,184,110, 9,228, 69, 84,217,217,217,115,221, 13, 12,224,105,104,220,141,147, +151,137,146,185, 41, 43, 43, 43, 51, 80, 2,220,205,150, 60, 77,222, 46, 33,100,227,188,121,243,134, 7, 73,135, 28, 73,251,173, +136, 48, 80,171,176,102,179,249, 92,167, 78,157, 66,114, 17, 6,131, 33, 63,208,124,249,129,228,125, 51,117,143, 10,232,116, 58, +104,245, 58,112, 33,222,111,109, 54,155,203,160,108,222,188, 25,106,181, 26,195,134, 13,187,170, 8,150,213,106,133, 82, 33,130, +107,148,136,191,207,223,138,146, 42,163,235,193,178,237,236, 57, 28, 42, 40,196, 51,189, 6, 65,171, 46, 68,181,197, 18, 82,164, + 77,146,164, 58,230, 74, 16, 4,140, 29, 59,214, 21, 61,112,175,151, 2, 86, 68,248,135,225,235,252,244,158, 46,121, 69,166,174, + 68,179,164,164,196, 56,124,248,240,189, 14,163,229,227,220,220,220,189, 0, 34,110,188,241,198,122, 27, 44,217, 88,137,162,136, + 55,223,124, 19, 11, 23, 46,116,205, 15,213, 96,217,237,118, 15,227,116,234,212, 41,143,109,121, 27,186, 64,197,163,180,246, 46, + 41, 1,144,210,211,211, 93,235, 52,110,220, 24,209,209,209,144, 36, 9,146, 36, 33, 34, 34, 2,106,181, 26, 10,133,194,175, 22, +131,193,248,235, 16,192,139, 24,167, 78,157,250, 18, 33,100,163, 51,146,116,196,185,188, 47, 35,229,139,238,240, 52,105, 69,190, + 22,114,143,100,185,155, 44,247,255, 50, 89, 89, 89,153, 62,210,225,138,152,185,238,166,110,174,177, 14,238,197,133,225,192, 87, +177,160,251, 3, 76, 23,173,135, 90,171, 5,207,115, 65,251, 87,146,139, 8,229, 27,254,196,137, 19, 3,214, 75, 9,181,190,148, +213,106, 5, 39,240,184,220, 56, 13, 14,238,123,215,186,242,192, 9, 34, 46, 52,110, 3,254,248,143, 16, 67,124,208,122, 71,176, + 38, 77,154,132,247,223,127, 31, 28,199,185,246,137, 32, 8,104,213,170, 21,206,157, 59, 23,146, 38, 35,252,248, 51,203,222,211, + 29, 14, 41,228,168,139,175,229, 74, 74, 74,140, 99,198,140,217, 94, 81, 81,241,113,251,246,237, 79,161,182, 25,131,144, 26,255, +149,207, 21,119, 99, 37,155,171, 5, 11, 22,120,152, 33,155,205, 22,210, 11,128,205,102,171, 99,116,222,120,227, 13,143, 95, 0, +232,221,187,119, 72,145, 96, 0,148,227, 56,170, 80, 40,112,203, 45,183,160, 99,199,142,248,226,139, 47, 32, 73, 18,158,120,226, + 9,168,213,106,188,245,214, 91,176,219,237,120,253,245,215, 89, 4,139,193, 96, 4,242, 34,230,121,243,230, 29,153, 55,111,158, + 43,146,228, 92, 62,152,185,186, 29,181,102, 42, 94, 54,103,168,173, 75,229,171,126,150,156,134, 58,154,222,134, 11,168,141,108, +249, 72,135,171, 88,242,119,239,236, 57,255,232, 97,252,171, 79,103, 0,158,197,130,139,123,180,129, 86,167,133, 54, 82,135, 49, + 27,190, 7, 0,231,205,126,106, 80, 77,155,205,230, 50, 88, 37, 37, 37, 1,205, 85,125, 34, 88,156, 82,192,218,212, 50, 80,165, + 8,193, 98,243, 48, 88,188, 32,226, 82, 92, 26, 56, 81, 1,193, 97, 15, 73,147, 82, 90,167, 72,240,193, 7, 31, 4, 33,196,245, +197, 87,167, 78,157,220,181,216, 19,231,119, 38,255,192, 7, 56,182,238,113, 0, 64,223,154, 26,215,177,152,211,233,183,239, 54, +230, 31,222,238,138, 54,206,196,115, 87,164, 89, 82, 82, 98,188,177,109,230, 94, 69,108,212,199, 23, 47, 94,220, 11,128,187,231, +158,123,162, 59,117,234, 20,210, 53, 41,127, 52,225,109,174,220, 35, 87,242,175,205,102, 11, 41,239,114, 93,168, 96,200,197,133, +193,206,121, 74, 41,141,141,141, 5,199,113,208,235,245,208,233,116,174, 47,104, 35, 34, 34,160,209,104, 92,245, 55, 67, 52,108, + 12, 6,227,175, 75,140,108,112,156, 38, 9,128,103,157, 43,119, 19,228,175,168,208, 25,113,218, 17,100, 91, 95,161,214,152,249, + 68,142,164,185, 79,243,222, 46,224, 52, 88,222,125,121, 37, 37, 37,253, 87,167,211,165, 5,205,174,147,250, 52, 58,234,176,253, + 86,201, 93, 54, 87,132, 16,232, 34,117, 80,235,180, 80, 71,234, 60,230,133,130, 92, 68,200,243,188,235, 97,179,116,233, 82,232, +116, 58, 60,244,208, 67,245,174,131, 5, 56, 13,150,130,195,183,170,239,192, 43, 5, 15,115, 37, 8, 2,120, 81, 68,190, 46, 9, +156, 40, 66,176,135, 22, 21,171,168,168,128, 32, 8,152, 62,125,186,235,141,221,221, 92,213, 39,207,140,134,129, 58,126, 51, 35, +254, 42,178,215,247, 24,121,107,202,145, 43, 69,108,212,199,109,218,180,113, 69,174, 52, 26,141,252,245,104, 80, 56,142,243,105, +174,188,191,248, 19, 4,161,246, 92, 14,242,181,163,123, 4,107,222,188,121, 46, 93,247,200,149, 76,125,174, 35, 57,173,219,183, +111,199,161, 67,135, 48,113,226, 68,168,213,106, 44, 92,184, 16,118,187, 29,179,102,205,130, 90,173,134, 82,169, 12, 46,196, 96, + 48,174,107,130,244, 43, 90,228, 85,207,137,120, 69,154,138,156,235,122, 24, 43,247,226, 64,183,255,238,111,157,178,174,197,171, +232,208,123,186,252, 91, 50,111,222,188,173,114,228,202,109,186, 71, 58, 0, 63, 17, 44,149, 74,149,118,242,228, 73, 87, 35,163, +129,126, 45, 22, 11, 6, 12, 24, 16,114, 36, 76,254,138, 80, 16,120, 15, 67,161,137,212, 65,163,143,132, 90,167,243, 54, 26, 1, +159,102, 28,199,185,222,128,221, 13,214,171,175,190, 10, 65, 16,240,254,251,239, 3, 0,158,123,238,185,144,235, 96,201,154,112, + 16,228,208, 51,232, 60,127, 52, 44,159,216, 80,176,235,103, 8,130,128,132,158,183, 65,186,113, 52, 12,106, 29, 4,135, 61,228, +175, 8, 75, 75, 75,113,238,220, 57,240, 60,143, 41, 83,166,120,180, 85,228,253,101,218,230,205,155,131,230,157, 17,126,168,100, +247, 24, 15,161,184, 48,232, 49,114,215,148,235, 92, 85, 84, 84,124,124,241,226,197,125, 0,184,251,239,191, 63, 90,163,209,224, + 63,255,249,143, 1,128,114,205,154, 53, 1, 93,150,187, 41, 15,102,174, 68, 81,172, 61,151, 67, 64, 46,194,150,135, 96, 21,222, + 67, 57,231,229,180, 18, 66,224,112, 56,160, 86,171, 61, 34, 87, 17, 17, 17, 80,169, 84, 33,165,143,193, 96,252,165,241, 91,164, +231,131,238,110,102, 41,216,122,254,230,215,103,123, 62,241,105,140, 56,142,131,217,108,198,175,191,254, 26,170, 78,200,141,142, + 54,233,214, 3, 51,115, 43, 64, 8,193,123,189,219, 67,171,215, 65,163,213,226,238, 47,182,187,110,216,135,231, 62, 7,149, 86, +135,228,126, 67,130,234,201,111,222,222, 6,171,188,188, 28,162, 40, 98,246,236,217,224, 56, 14,175,191,254, 58, 82, 82, 82,112, +249,242,101,172, 89,179, 38,168,174,213,106, 5,239,224,145,244, 64, 91,104, 30,140,130,254,129,155, 16,115,203,171,200,181, 8, +216,109,210,224, 38,211, 81, 40,191, 93, 0,139,228, 8,249,139, 42,187,221,142,237,219,183,123, 87,100, 7,165,212,213, 74,190, +205,102,131,213,106,197,235,175,191, 30,210, 23,106,140,240,146,212,115, 18,226,187, 61, 6, 0,216, 48,111,188,107,250,244,195, +191,157,159,111,126, 82,219, 96,127,155,230,193,207, 79,119,205,146,146, 18,227,173, 3,122,239, 48, 73,226, 71, 29, 58,116,240, +136, 92, 69, 68, 68, 16,231,120, 72,166,154,227, 56,240, 60, 95,167, 88,208,159,201, 10,165, 14,150,221,110,119, 53, 0, 26,168, +190,226,149, 68,176,198,143, 31,143,164,164, 36, 87,228,106,230,204,153, 80,171,213,200,202,202,130,205,102,195,130, 5, 11, 66, +214, 99, 48, 24,140, 32, 92,181, 57, 10, 7, 62,239,160, 38,147,233,124,199,142, 29,125,174, 96, 50,153, 82, 34, 34, 34, 60,238, +174,196,217,232,168,119, 81, 33, 33,100, 48,165,116,139,183,134, 28,173,137,212, 71, 34, 66,167,133,198, 43,106, 21, 17,169,135, + 74,167, 3,167,168,123, 19,247,165, 41,215, 29,113, 55, 88,242, 80, 81, 81, 1, 81, 20,177,104,209, 34,232,245,122,152,205,230, +160,154,242,195,134,231,121, 24, 46, 85,225,216,220, 45, 80, 70,236, 70,203, 33,247, 34, 73, 84, 67,177,243, 51, 24, 29,158,117, +178, 66,209,204,200,200,192, 43,175,188, 82,167,121, 6,127,164,164,164, 4,205,251,213,194, 52,125,107, 6,250,202, 85, 70,162, + 14, 95,203,249,212,148, 35, 87, 38, 73,252,232,220,185,115,114,228, 42, 74,163,209,224,221,119,223, 53, 0,224,102,205,154,165, +105,214,172, 89,157,118,228,124,157, 75, 60,207, 99,254,252,249, 62,235, 92,249, 50, 91,161,228, 93,190,142,220,215,237,223,191, +191,207,134, 70,125,153, 54, 95,154,114, 90,227,226,226, 92,145, 43,135,195,225,250,122, 80,110, 45,222,223,203,196,245,112, 46, + 49, 77,166,201, 52,255,154,248,124,186,231,229,229,221,234,111,133,150, 45, 91,158, 60,121,242,100, 43,185,203, 12,231, 13, 83, + 97, 50,153, 50,122,247,238, 29, 52,148, 35, 73, 18, 84, 42, 21, 40,165, 24,248, 74, 54, 8, 7,112,240,124,120, 37,244, 25, 4, +158, 23, 32,213,118,201, 17,244, 43, 66,163,209,232,241, 80,240, 53, 84, 87, 87,195,108, 54, 7,253,188, 92,198,100, 50,121, 52, +165, 64,168,132, 11,255, 91, 93,231,107, 66,121, 8,181, 94, 78, 68, 68,132, 71, 17, 79, 32,130,181, 41,198, 8, 63,242,135, 8, + 0,208,186,247, 48, 72,146, 3,212,225,240,232,206,168,109,218,173,144,168, 3, 86,155, 1,102,179, 57, 88,152,145, 20, 23, 23, + 27,199,140, 25,179, 29,192,135, 35, 70,140, 56,129,218, 47, 88,168, 78,167, 83,137,162, 40, 1, 40, 5, 64,203,202,202,162,114, +115,115, 37,147,201,212, 52, 88, 58,191,250,234, 43,252,250,235,175,232,215,175,159, 71,183, 77,114, 20,212,189, 53,246, 80,206, + 79,185, 88,220, 87, 11,238,254, 12, 92,168,240, 60,143,168,168, 40, 40, 20, 10,204,158, 61, 27, 10,133, 2, 26,141, 6, 0,176, + 96,193, 2, 87,163,169, 12, 6,131,113, 61,113, 37, 95, 17,242, 1,138, 15, 3, 22, 21,218,237,246,156,102,205,154,213,107, 99, + 14,135,163, 32,208,124, 73,146,114,214,172, 89,163, 0,234, 86, 74,246,247, 75, 41, 13,168, 73, 41,205,217,176, 97,131,235,123, +117,247,135,147,175,255,132,144,160,154, 14,135, 35,167,121,243,223,250, 17, 14,197,144,217,108,182,220,160, 11, 49,194,134,195, +225, 8,112,126, 78,243,183, 78,176,243,243, 84,235,214,173,115,163,163,163,191, 78, 76, 76, 44,217,181,107, 87, 92,247,238,221, +227,220,151,233,222,189,123,146,215,106, 22,248,239,135, 16,132,144,156, 17, 35, 70,248, 60,231, 1,184,140,187,215,249, 25,176, +105,120, 74,105,206,254,253,251, 21,238,235,251,211,119,187,142, 2, 55, 55, 95,187,204,133,206,157, 59,115,238, 58,254,206,125, +155,205,230,179, 93, 26, 6,131,193,248, 51, 82,111,131,101, 52, 26, 47,117,236,216,209,103,173, 89,163,209,120, 49,208,186,197, +197,197,221,234,187,189, 96, 88,173,214,222,127, 6,205,162,162,162,176,231,157, 17, 94, 26,226, 24, 21, 20, 20,220, 24,110, 77, +187,221, 30,246,243,211,102,179,133, 93, 19, 0, 74, 74, 74,122, 53,132, 46,131,193, 96, 92,235,212,219, 96,133,218, 28, 3,131, +193, 96, 48, 24, 12,198, 95,149,144, 90,141,102, 48, 24, 12, 6,131,193, 96,132, 14, 65,109,175,209,117,168,207,215, 1,132, 16, +159, 26,129, 8,166,207, 52,153, 38,211,100,154, 76,147,105, 50,205,235, 79, 51,152,246,117,243,117,162,252,117, 84, 67, 12, 0, + 6, 51, 77,166,201, 52,153, 38,211,100,154, 76,147,105,254,213, 6, 86, 68,200, 96, 48, 24, 12, 6,131, 17,102,126,247,206,158, + 25,181, 16, 66,120, 74,105,200, 45,224,135, 64, 12, 0,127, 29,186, 89, 0,148, 93,129, 38, 1,160,112, 14,114, 67, 69, 54, 0, + 86,231, 16, 66, 83,243,175,113,121,121, 49,153,212, 33,118,167,132,136,146,132,159,154, 54,109,242, 35,112,171, 5, 0,116,141, +219,181,211,105,213,131,205, 86, 75,154, 74, 84,254, 90, 94, 83,189,217, 84,112,226,252, 21,164,149,193, 96, 92, 37,132,144, 59, + 0,188,134,218,107,127, 30,165,116,245, 31,156, 36, 6,227, 79,139, 95,131, 21, 25, 25,121,128,227,184,212, 96,237,235,200, 56, +251, 26,203, 41, 45, 45, 13,233, 83,119, 66,136, 0, 96,140, 78,167, 27, 32,138, 98, 31, 0,176,217,108,187,170,171,171,183, 2, + 88, 67, 41, 13,173, 3,181,186,186,122, 0, 99, 1,220,231,156,244, 41,128,213,148,210,202, 43,212,235, 24, 21, 21,181, 78, 20, + 69, 90, 92, 92,220, 19, 0,226,226,226,246,218,108, 54, 82, 89, 89,121, 55,165,244,151,122,234,113, 10,133, 34,187, 95,191,126, +125, 9, 33,203, 40,165,139,175, 36, 93, 62, 80,113, 28,231,211,152, 72,146,212,220,215,244, 32, 40, 0, 68, 45, 90,180, 40,110, +249,242,229,157,115,114,114, 58, 0, 64,106,106,234,225,251,239,191,255,199,201,147, 39,151, 0,168, 64,173,209,242, 75, 94, 94, + 76,102, 97,254,217,137, 5,133,191,142, 5,128,198, 73, 29, 86,243, 60,167, 72, 73, 57,180, 71,211,232,190, 70,173,219,180,120, +108,229,127, 22, 41,154,167, 53,193,119,187, 15,221, 48,249,169,151, 50, 35, 18, 91,255,155,153,172,223, 15,189, 94,127,128,227, +184, 84,192,255, 53,238,235,154,119, 56, 28, 57, 37, 37, 37, 62,175,119,189, 94,127, 64, 16,132, 84,127,235,250,155, 38, 73,210, +217,162,162, 34,159, 77, 70, 68, 69, 69,237, 17, 4, 33, 45, 84, 45,249,215,110,183,231,248,107, 34, 38, 42, 42,234, 0,207,243, +169,129,242,233,107,158, 36, 73,103, 11, 11, 11,253,165,179, 78,222,195,145,206, 43,209, 12,148, 78,231, 50, 28,128, 5,113,113, +113, 61, 74, 74, 74,254, 6,224,165,202,202,202, 78, 60,207, 35, 54, 54,246, 37, 66,200,233,168,168,168, 15, 42, 42, 42,118, 3, +120,138, 82, 42,249,211, 98, 48, 24,158,248, 53, 88, 28,199,165,230,230,230, 38,104,181, 90, 0,191,245,151, 39,119,242, 44, 73, + 18, 40,165,174, 95,187,221,142,182,109,219,134,180, 81, 66, 72, 7,189, 94,191, 54, 43, 43,171,233,152, 49, 99,148,114,151, 48, +121,121,121, 25,235,214,173,251,219,236,217,179, 95, 37,132,140,166,148, 30, 14, 81,143, 3, 48, 8,192,131,157, 59,119, 30, 53, +115,230, 76,197,192,129, 3,225,112, 56,240,245,215, 95,247,155, 53,107,214, 34, 66,200,103, 0, 62, 6,240,191, 80,111, 18,132, +144,190,141, 27, 55, 94,177,115,231,206,164,115,231,206, 57,198,140, 25,179, 10, 0, 14, 28, 56,144,238,112, 56, 72,207,158, 61, +191, 34,132,140,163,148,238, 12, 41,227,181,140,152, 60,121,242,232, 73,147, 38,197, 63,244,208, 67, 15, 0, 88,236,220,150,220, +139,120,125, 59, 32,116, 69,174, 40,165,138, 0,203, 53, 70,232,145, 44,237,185,115,231, 98,122,247,238,253,120, 97, 97,225, 51, +238,186, 5, 5, 5, 56,120,240,160,117,238,220,185,243,119,239,222,253, 78, 90, 90, 90, 25,128, 26,127, 66,212, 33,118, 47, 40, +252,117,236, 77,189, 22, 69, 1,192,154, 13,143,223,187,255,199,162,200,141,223, 44,249,155, 50, 66, 97, 94,254,222,124, 69,171, +150,205,177,237,192, 41,236,251,181,148,116,232, 59, 92,168,216,184,236, 22, 0, 75, 66, 72, 39, 35, 12,240, 60,159,146,147,147, +147,160,209,104,124,118,232,238, 85,239, 66,110,184, 20, 25, 25, 25,126, 53, 5, 65, 72,205,205,205, 77,136,136,136,112,221, 59, +188,239, 25, 0,224,126,186, 83, 74,209,186,117,107,191,134,157,227,184,102, 23, 47, 94, 76,208,104, 52, 46, 29, 95,233,147,145, +141, 70,235,214,173, 3,229,221, 35,157,161,104, 82, 74,209,170, 85, 43,191,209,103, 57,239,114,143, 21,193,242, 45,107,166,165, +165,249,189,246,125,105,134,146,206, 22, 45, 90, 4,124, 1, 2,176,224,196,137, 19,147,154, 52,105,130, 86,173, 90,237,238,209, +163,135, 94,171,213,226,155,111,190, 65,187,118,237, 50,245,122,253,190, 53,107,214,136, 47,188,240,194, 13, 31,125,244, 17, 0, + 76, 14,162,199, 96, 48,156,248, 53, 88,132, 16,104,181, 90,172, 90,181,202,111,183, 25,238,255,155, 54, 13,218,187,135,172,219, + 45, 45, 45,109,251,206,157, 59,213, 73, 73,191, 53, 96,109,177, 88, 16, 19, 19,131, 39,158,120, 66,121,199, 29,119,180, 26, 50, +100,200, 94, 66, 72,127, 74,233,129, 32,122,163,226,227,227,223,158, 62,125,122,226, 61,247,220,131,184, 56,143, 70,178, 49,102, +204, 24,220,125,247,221,138, 19, 39, 78,220,187,116,233,210,123, 23, 47, 94,156, 79, 8,153, 76, 41,253, 44,144,174, 70,163, 25, +209,178,101,203,119,119,238,220,153,144,144,144,128,244,244,116,238,133, 23, 94,104,149,145,145,161, 78, 77, 77,229, 46, 95,190, +140, 47,190,248, 34,101,220,184,113,107,149, 74,229, 99, 22,139,101,125, 8,121, 87,198,198,198, 62, 63, 97,194,132,184,202,202, + 74,251,161, 67,135, 78,201,211, 85, 42,213, 43, 61,123,246,236, 66, 8, 89, 69, 41,253, 56,152,150, 27,174,200,149, 51, 74,231, +221,231,136, 77,158, 31, 98, 36, 75,249,211, 79, 63,197,246,234,213,235, 51,179,217,220,101,226,196,137, 23,231,206,157,171,214, +235,245,122, 0,164,178,178,178,236,181,215, 94,179,188,245,214, 91, 47,182,107,215,110,208,158, 61,123, 70,221,112,195, 13, 54, +212,154,183, 58, 80, 66, 92,233,185,148, 91,132,237,187, 37,229, 43, 89,207,165,254,115, 78,218,133, 31,142, 94,146, 4,181, 30, + 95,238, 56,130,130,146,106,252,119,207, 81, 52,142,139, 36, 10,149,152, 25,157,154,217,191, 34,247,232,142, 43, 48,156,140,122, + 66, 8,129, 70,163,193,151, 95,126, 89,167,139, 41, 95,221, 79, 9,130,128,232,232,232,160,189, 17, 68, 68, 68, 96,243,230,205, + 62,251, 70,244,213,245, 78, 84, 84, 20, 0,255,157, 93, 19, 66, 16, 17, 17,129, 93,187,118,129,227, 56,159, 93,248,120, 79,211, +106,181,224, 2,244, 73, 37,107,238,216,177, 35,168,150,252,171,211,233, 0,160, 78,159,145,238,168, 84, 42,236,220,185,211,111, +158,189,255,235,156,253,177, 6,211,220,181,107,151, 71, 23, 93,222, 93,119,185,143,107,181, 90,215,139,155, 63, 98, 98, 98,122, +166,166,166, 98,255,254,253, 88,179,102, 77,108,102,102, 38, 78,157, 58, 5, 66, 8,230,206,157, 75,218,183,111, 47,230,231,231, +163, 95,191,126,248,252,243,207, 27,164, 49, 90, 6, 35, 68, 68, 0, 55, 0,136, 71,109,175, 49, 85, 0,162, 81,251,236, 81, 2, + 40, 1,160,118, 14,102, 0,213, 0, 26, 57,215, 45, 70,237,189,197,221, 32, 20,193,179, 83,232,238, 78,109,185, 71,137,120,183, +121,242, 54,188,199,189,127, 61,180, 5, 0, 32,132,200, 15,177,155, 41,165,219, 61,114, 20,130,185,146,251, 17,243,190,150,105, +221,142, 95, 85, 90,173,118,221,222,189,123,213,241,241,191,165,221,108, 54,163,170,170, 10,213,213,213,168,170,170, 66,100,100, + 36,214,172, 89,163, 30, 52,104,208, 58, 66, 72, 6,165,212,236, 79, 19,192,252,203,151, 47, 39,218,237,118, 40,149,190,171, 32, +113, 28,135,182,109,219,226,165,151, 94,194,208,161, 67, 27, 15, 24, 48, 96, 62, 0,151,193,242,161, 9,141, 70,243,238,193,131, + 7, 19, 52, 26, 13, 78,158, 60,137,156,156, 28, 60,251,236,179, 77, 36, 73,194,165, 75,151,112,234,212, 41,228,230,230, 98,233, +210,165, 9, 35, 71,142,124, 23,128,135,193,242,165, 9,224,209, 41, 83,166,100,196,198,198,114,255,250,215,191, 42,170,171,171, +223,115, 78,207, 90,176, 96,193,184,155,110,186, 41,254,145, 71, 30, 1, 33,100, 37,165,180,142, 97,241,210,244, 21,185,114, 0, + 56,230,181, 90, 91,175,200, 86, 99,212,158,124,229, 62, 52, 9,128,168, 33, 67,134, 76, 49,155,205, 93,118,238,220,121,186, 79, +159, 62,205, 0, 92,134,243,164,139,138,138,210,206,159, 63, 63,113,248,240,225, 39, 6, 14, 28,216,101,200,144, 33, 83,138,138, +138,230, 58,231, 83,111, 77, 73,194, 79,141,147, 58,172,222,177,103,242,216,109,187, 44,138,231,158,122,245, 98,211, 38,205, 43, +126, 58, 89,234, 56,122,182, 8, 85, 70, 59,238, 26, 88,219,177,120,207, 14, 77,241,246,170,157,120,226,233,105,226,103,171,151, +221,125,154, 66, 11,224,171, 0,251,243,170, 96,154,181, 56,139,146, 32,138, 34,110,187,237, 54, 16, 66,234,244,181, 41,138, 34, +246,236,217,131,129, 3, 7, 66, 20, 69,140, 31, 63, 62, 36, 77, 65, 16, 48,100,200, 16, 87, 63,135,238,122,222,102,193,151, 23, +240,206, 59,165, 20,130, 32,128,227, 56,191, 29, 92,123,107, 6,187, 47,201,233, 12,164,229, 62, 47, 88, 58,229,232, 81,168,230, + 42, 84, 77, 57,157,130, 32,160,119,239,222,248,241,199, 31, 3,154, 45, 95,190,210, 59,239,101,101,101,127,207,200,200,216,177, +104,209,162, 88, 0, 40, 41, 41,113,117, 68,207,243, 60,142, 31, 63, 14,139,197,130, 25, 51,102, 88, 43, 43, 43, 31,169, 35,232, + 67, 51, 28, 48,205,191,166,102, 32, 47, 2,224,166,172,172,172,110,217,217,217,115,123,245,234,181,114,247,238,221, 43, 8, 33, + 27, 41,165,195,229,223,172,172,172,204,236,236,236,185, 83,167, 78,125,105,222,188,121, 71, 8, 33, 27, 1,192,123,220,153,254, +225,110,218, 34,128,120, 89,199,153, 22,143,101,125,141,123,255,122,107, 11,110, 19,136, 51,115,196,109, 90,200, 6, 43,216,219, + 23, 0, 8,130, 48,105,238,220,185,137,129,204, 85,117,117, 53,242,242,242,208,172, 89, 51,140, 31, 63, 62,113,209,162, 69,147, + 0,188, 17, 64, 86,193,243, 60,246,239,223,143,194,194, 66,116,236,216, 17,105,105,105, 30, 11,156, 57,115, 6, 95,127,253, 53, +202,203,203,209,181,107, 87,160,182,126,145, 79,110,184,225,134, 25,109,219,182, 29, 50,100,200, 16,187, 90,173,198, 79, 63,253, +132, 46, 93,186, 96,213,170, 85,104,218,180, 41, 52, 26, 13, 78,156, 56,129,142, 29, 59, 98,251,246,237,136,143,143, 71,231,206, +157,237, 93,187,118,253,190,180,180,116,235,249,243,231,103,248,210, 37,132, 40, 82, 82, 82, 94,154, 48, 97,130, 50, 47, 47, 79, + 90,186,116,233,110, 74,233,110, 66,200, 99,211,166, 77,123, 96,232,208,161,241,135, 14, 29,170,252,225,135, 31,126,240,101,174, +124,224, 43,114,229, 81,111,205, 89, 52, 99, 54, 26,141, 22,179,217,108,227, 56,238, 60, 33,196,226,112, 56,252,149,237, 68, 60, +248,224,131, 45,138,139,139,159,120,250,233,167,207, 57,205,213,113,212, 86,108, 7, 0,216,237,118,115,117,117,117,101,175, 94, +189,154,141, 27, 55,238,244,138, 21, 43,158,120,240,193, 7,215,124,252,241,199,213, 0,140,222,130, 77,155, 54,249,145,231, 57, + 69, 77, 85,236,217,181,107, 62,120,230,235, 13,147,154, 92,186,148,219, 42,174, 81,124,141, 66, 23,159,183,230,211,143, 14, 0, +176,228, 21, 85,226,151, 51,249, 16, 69, 30,191, 94,170,192, 77,183,142, 17, 79,159,156,211, 23, 78,131,197,104, 80,168,220, 57, +244,182,109,219, 2, 70,176,246,236,217, 3, 81, 20,161, 86,171,241,214, 91,111, 5, 20,149, 13,129, 28, 29, 10,102, 98, 56,142, + 11,120, 31,145, 77,134,220, 1,187,247,240,127,255,247,127,120,250,233,167, 61,182,225, 52, 25, 1,163, 98,238,198,197, 59,125, +205,154, 55, 71, 97, 65,129,199,180, 80, 58,139,119, 56, 28, 16, 69, 17,239,191,255, 62,134, 15, 31,142,141, 27, 55, 6,252,189, +237,182,219,192,113, 92,192,104,173,156,206,222,189,123,195,106,181,186,210,124,252,248,113,159,186,139, 23, 7,174,222, 41, 87, +104,239,210,165,139,126,192,128, 1,216,177, 99, 7,238,190,251,110,179,213,106, 61, 9, 0,183,223,126,123,235, 69,139, 22, 41, + 15, 30, 60,136,184,184, 56,241,226,197,139, 31, 18, 66, 88,197,119, 70,131,226,203,139, 56, 81,101,103,103,207,245, 50, 70, 30, +200,243, 9, 33, 27,231,205,155, 55,220,169, 87,103,220,185,184,123,223,167, 55,101,101,101,101,186,141, 23,185,155, 39,183,180, +249,221,182,215,242, 69,128,155,193,114,102,232,102,121,156,227, 56,200, 55,221, 96,230,202,223,155,162, 55, 81, 81, 81,195,238, +186,235, 46,151,185, 49,153, 76, 46, 99, 37,155, 43,121,252,196,137, 19,232,214,173,155, 34, 42, 42,106, 24, 2, 27, 44, 0,128, + 32, 8, 72, 78, 78, 70,113,113, 49, 14, 31, 62,140,102,205,154,193,102,179, 97,211,166, 77,168,168,168,128, 40,138, 80, 40, 20, +176, 90, 3, 87, 73,104,219,182,237,109,203,151, 47,239,182,108,217,178, 50,249, 13,238,211, 79, 63, 5,165, 20,241,241,241, 48, + 24, 12, 40, 40, 40,192,214,173, 91, 97,183,219,161,211,233,144,158,158,174, 28, 49, 98, 68,223,215, 94,123, 77, 4, 48,195,143, +116,143,187,239,190, 91,175,215,235,241,212, 83, 79, 81,171,213,250, 6, 33,164,231,168, 81,163, 94,154, 60,121,114,236,249,243, +231, 45,143, 62,250,232, 1,171,213, 58,223,121, 60, 68, 74,169,205,143, 22,128,192,145, 43,155,205, 38,239,211,115,213,213,213, +104,212,168, 81,179, 32,117,180, 0, 64,177,107,215,174,222, 0,248, 89,179,102, 69, 0, 40,128,155,185,178, 88, 44,168,174,174, + 70, 77, 77,141,173,162,162,162,240,249,231,159,183,175, 88,177,130,119,174,243, 43,124, 24, 44,224, 86, 75,251,246, 90, 37,165, +252,180, 37, 75,150,232,134, 14, 29,202,233,116, 58, 84, 85, 85,233,255,251,205, 55,186, 65, 3,250,166,207,205,254,231,183,250, +212,142, 5,187,126, 58,139,220,252, 10, 88,108, 54,164, 39, 69, 1,144, 88,133,218,223, 1,231, 7, 42,174, 8,150,187,153,216, +177, 99, 7,110,189,245, 86,215,181,174, 80, 40, 60, 34, 93,193, 52, 5, 65,192,173,183,222, 90, 39,162,179,109,219, 54,159,209, +166, 96,184,155, 33,111, 83,228,203,120,113, 28, 87,167,126,146, 47, 77,127, 69,151, 0,234,204, 11,197, 96,201,249,157, 60,121, + 50, 68, 81,196, 11, 47,188, 0, 65, 16,208,185,115,103, 8,130,128, 94,189,122, 65, 20, 69, 12, 28, 56,176,222,121,223,187,119, + 47,186,116,233,226, 74, 83,231,206,157,209,189,123,119, 8,130,128,126,253,250, 65, 20, 69, 12, 25, 50, 36, 20,205,151,170,170, +170, 58,233,116, 58,156, 56,113, 2, 60,207,131, 16,114,138, 82,218, 9, 0, 38, 76,152,112,218, 96, 48,180, 48,153, 76,152, 48, + 97, 2,177, 88, 44, 29, 95,120,225,133,105, 0,152,193, 98, 52, 24,222, 94,196, 13,227,212,169, 83, 95, 34,132,108,148, 35, 82, +206,229, 55,122,173,191,209,199,186, 30,243,157, 38, 72, 46, 30,236, 14, 79,243, 38, 23, 29,222, 30, 96, 93,139,151,161,242, 46, + 34,252, 1, 8, 18,193,146,111,186,161, 26,172, 96,152, 76,166, 27, 18, 18, 18,228,255,117,204,149,251,175,197, 98, 65, 90, 90, + 26, 76, 38,211, 13,250, 58,137,232, 0, 0, 32, 0, 73, 68, 65, 84, 65,133, 61,119, 0,146,146,146, 96,181, 90,241,193, 7, 31, + 64,161, 80, 64,161,248,205, 87, 88, 44,129,131, 67, 71,143, 30, 61,183,119,239,222, 46, 93,187,118,141,249,252,243,207,139,250, +247,239, 31, 63,116,232, 80,168,213,106, 24,141, 70,216,108, 54,244,236,217, 19,109,219,182, 69, 78, 78, 14,254,251,223,255, 22, +103,100,100, 52,218,183,111,159,148,159,159,127, 33,128,244,160, 65,131, 6,129, 16,130,255,254,247,191, 37,148,210,131,106,181, +250,243,185,115,231, 70, 91, 44, 22,233,129, 7, 30,184, 84, 90, 90,250, 60, 0,155, 74,165,122, 99,232,208,161, 61,120,158, 95, +229,112, 56,222,174, 79,254,129,186,251,182,166,166, 6, 17, 17, 17,161, 52, 9, 33,150,150,150,118, 0, 0,173, 86, 27, 11,224, +180, 60,195,104, 52,122,152, 96,139,197, 98,138,141,141,213, 2,128,115, 29,239,186, 95, 0, 0, 66, 72,188, 70,163, 89,123,225, +194,217, 72,247,250,113,209,209,209,184,111,220, 56,174, 79,239,222,202, 78, 55,220, 48,228,229,127, 47, 91,149, 28,167,183,164, + 39,199,193,230,176, 97,203,183,155, 36, 42,217,190,173,111,222, 25,245,199,189,136,208, 59,130, 37,138, 34,182,111,223, 94,103, +154, 66,161,192,123,239,189, 23, 80, 87, 54, 4,178,153,242, 87, 68,230, 85,164, 21,240, 70, 34, 71,213,121,158,199,251,239,191, + 15, 73,146,240,204, 51,207,120, 20, 27,186,235,135,130,187,249,107,251,170, 4,192,130,156, 55, 85,174,245,189,211,235, 92, 39, +164,168,216,162, 69,139, 66,138, 96,221,126,251,237, 65, 13,171,123,137,130,123,186,126,252,241, 71,159,186, 75,150, 44, 9,186, + 63, 29, 14, 7,190,250,234, 43,151, 57,149,153, 62,125,250,132,212,212,212,196,239,191,255, 30,249,249,249,168,169,169, 65,117, +117, 53,122,246,236,153, 62,120,240,224,159,242,243,243,207, 31, 61,122,244,174,144,118, 48,131, 81, 15, 2, 68,176,204,243,230, +205, 59, 50,111,222, 60,159, 17, 42,183,245,135, 7, 50, 89,110, 81,168,238,168, 53, 66,241,178,105, 67,109,245,153, 31, 66, 88, + 87,233, 93, 68,232,107,121,239, 8,214,107,110,227,174,155,110, 40,197,132, 33,134,205, 5, 66, 8, 76, 38,147, 79, 99,229,110, + 10,172, 86, 43, 74, 75, 75,225,112, 56,174,184,173, 46, 95,111,174,193, 12,214,225,195,135, 31,122,248,225,135,243,162,162,162, + 58, 21, 21, 21, 21, 74,146, 52,112,207,158, 61,241,130, 32, 64,175,215, 67,175,215,227,235,175,191,134, 70,163,193,228,201,147, + 11, 29, 14,199,142,200,200,200, 56,163,209,248,115,126,126,254,203,254,116, 69, 81, 28,116,211, 77, 55,225,224,193,131, 40, 47, + 47,255,142, 16,210,233,145, 71, 30,185,165, 73,147, 38,100,206,156, 57,166,211,167, 79,255, 31,128, 34,173, 86,251,193,242,229, +203,251,119,237,218, 85,119,255,253,247,131, 16,242, 31, 74,169, 41,212, 60,215,212,212,120, 24,171,202,202, 74, 84, 85, 85, 65, +171,213,134,212,236, 5,165, 84, 68,109, 93, 42,185, 62,149,235,216, 56,163, 87,242,241,161,130, 32,208,218, 69,168, 79,115, 5, + 0, 90,173,118,214,178,101,203,212,222, 31, 31, 56, 28, 14, 20, 20, 20, 64,175,215, 99,250,203, 47, 43,102, 62,251, 72, 23, 94, +151,184,135,227, 8, 44, 86, 90, 78, 37,203,166,154,130,123,190, 15, 53,223,140,171, 67, 54, 4,119,222,121,103,157, 98, 65,133, + 66,129,205,155, 55, 99,228,200,145,174, 23,150,174, 93,187, 6,125,169,146, 13,193, 29,119,220, 1,160, 54, 18,180,105,211, 38, +159,197,123,114, 4, 42, 16,238,198,133,231,121, 60,249,228,147, 16, 4, 1,111,191,253, 54,166, 76,153, 2,142,227,240,230,155, +111,130,227, 56,188,242,202, 43, 33,229,219,219,184,156,255,103,237,111,234,148, 74,148, 44, 78, 4, 0, 68,234,245,114,134, 66, +210,148,243, 46, 8,130, 43,114,117,195, 13, 55, 64, 20, 69,244,234,213, 11,130, 32,184, 34, 87,195,134, 13,115,223,143, 1, 55, + 32,107, 10,130,128,147, 39, 79,186,210,220,171, 87, 47,143,200,149, 32, 8,184,253,246, 58, 47,223,190,152, 27, 29, 29,253, 90, +219,182,109,219,205,159, 63, 95,228,121, 30,131, 6, 13,106,253,232,163,143, 94,136,139,139,139,155, 53,107,150,198,199, 58,106, + 0,157,218,181,107,167, 13,121,103, 48, 24,245,192,219,139,184, 17,227, 94,167,170, 30,122, 27,221,151,151, 53,188, 77,145, 51, + 34,182, 35,152,150,175,117,253, 33, 56, 23,246,121,167,172,143,193,114,134,151, 3,110, 76,163,209,252, 82, 88, 88,216, 75,173, + 86,123,152, 43, 95, 70,139,231,121,228,231,231, 67,163,209,212,171,157,169, 96, 4, 43, 34,116,154,153,103,229,113, 66,200,224, + 97,195,134,125,188,121,243,230,164, 45, 91,182, 96,223,190,125,136,143,143,199,162, 69,139, 46, 23, 20, 20, 60, 68, 41,221, 28, +202,118, 91,180,104,209, 94,171,213, 98,247,238,221, 0,240, 61,128, 7,159,120,226, 9, 98,183,219,241,206, 59,239, 24, 0,108, +142,138,138,250,108,221,186,117, 55,116,236,216, 81,185,101,203,150,170,125,251,246,109, 11,209, 92, 57, 36, 73,170, 99,172,220, +247,105,100,100,100, 40, 17, 44, 91, 84, 84,212,225,202,202,202, 49, 70,163,177, 82,165, 82, 69, 86, 86, 86,154,221,141,149,172, + 47, 8,130,120,242,228,201, 60, 0,233, 81, 81, 81,135,225, 86,148,232,142, 32, 8,131, 6, 13, 26,228, 97,146,173, 86, 43, 10, + 10, 10,144,159,159, 15,171,213,138,174, 93,187, 18,158,216,248,210,139, 63, 79, 8, 33,141,140, 48, 67, 8,161,242,181, 46,127, +245,231, 61, 8,130,128, 77,155, 54,185,198, 57,142,131,243,179,125,127,154, 46, 51,180,121,243,102,191, 81, 43, 31, 69,132, 65, + 67,225,242,242,239,188,243, 78,109,119, 20,206,200, 21,199,113,152, 58,117, 42, 84, 42, 21,230,204,153,131,169, 83,167, 66, 16, +132,160, 69,132,238,198,165,249, 11, 6,215,116,185,136,208,230,172,239, 68, 8,113, 55, 89, 1, 35, 88,238,166, 45, 80,244, 46, +148,200,191,187,166,188, 94, 68, 68,132,207, 98, 82, 31,154,126, 55, 64, 41,253,146, 16,114, 54, 41, 41,105, 87,175, 94,189,162, + 14, 28, 56,128, 55,223,124, 83, 97, 54,155,155,110,217,178,197,181, 93, 95,251,171,166,166, 70, 29, 82,194, 25,140,122, 16, 40, + 50, 12,103,189, 40,249, 63, 0,226, 94, 92, 23,224,215,123,121,184, 77,115,215, 45,130,231,115,204,125,186,183,169,242,222,134, +251, 50,174,186, 93, 1,155,105,168, 79, 37,247, 80, 34, 88, 6,131,225,127,223,124,243, 77,247,113,227,198, 9,129,138, 7,107, +106,106,144,152,152,136, 35, 71,142,216, 13, 6,195,255,130,233, 58, 28,161, 55,136, 30,204, 96,121, 67, 41,221,210,184,113, 99, +222,102,179,161, 85,171, 86, 72, 73, 73,129,201,100, 66,121,121, 57, 31,170,185, 34,132, 40,186,117,235,198, 3, 64, 89, 89, 25, + 80,251, 57,105, 70, 70, 70, 6, 14, 30, 60,136,178,178,178,245, 0, 6,207,156, 57,179,115,143, 30, 61, 20,171, 86,173, 50, 76, +156, 56,113,189,205,102,155, 19,138,190, 36, 73, 22,187,221,158,198,113,156,181,188,188, 60,215,125,127, 38, 38, 38,198,106,181, + 90, 82, 80, 80, 16,176, 62,151, 19, 91,167, 78,157,246, 95,188,120, 17,179,102,205, 42,154, 59,119,110, 70, 85, 85, 85, 89, 69, + 69,133,221,221,100,153, 76, 38,174, 81,163, 70,170,197,139, 23,171, 1,160, 83,167, 78,251,225,199, 96,213,212,212, 52,209,104, +126,123, 17, 54,155,205,200,207,207, 71,126,126, 62, 10, 10, 10, 80, 85, 85,133,244,244,116, 24, 12,134,102,161,228,149, 17,126, +188,191,122,115,191,190,221, 31,224,245,185,214,129,223,140,203,157,119,222,233,170,187, 37, 71,196,228, 97,237,218,181,238,197, +131, 64,136, 6,235,157,119,222,193,147, 79, 62,137,136,136, 8,204,159, 63,223,163,136,208,219, 20, 72,146, 20,212, 12, 9,130, +128,180, 23,141,200, 95, 24, 11, 81, 20, 17, 55,177,192,163, 40,206,135,209, 8, 41,157,115,231,206, 13, 75, 17,161,187,102,179, +102,205, 0, 0,239,191,255, 62,198,140, 25,131,239,191,255,254,138,139, 8, 51, 51, 51, 63,221,184,113, 99,212,209,163, 71, 81, + 89, 89,137,162,162, 34,152,205,102,228,228,228, 0,240, 93, 10, 0, 0, 6,131, 33, 34,104, 98, 25,140,240,226,183,232,174,129, +116,175,122,123, 1,139,223,220, 43,127, 6, 51, 88,161, 68,176,204,102,243,252,167,158,122,234,137,193,131, 7,199, 70, 70, 70, + 34, 47, 47,175,142,185,170,174,174,134, 78,167,131,209,104,196,134, 13, 27, 42,205,102,243,252, 32,121,176,217,108, 54, 36, 36, + 36,160,184,184, 24,146,159,122,209, 28,199, 65,173, 86,163,186,186, 26,240, 99, 6,252, 65, 41,133,213,106,133,205,102,131,205, +102,131,213,106, 13,250, 86,236,133, 90,110,176,181,166,166, 6, 0,106,146,147,147, 91, 68, 68, 68,224,220,185,115, 0,112, 18, +192,128,161, 67,135,138, 37, 37, 37,244,209, 71, 31,221, 67, 41,157, 76, 3,183,102,111,217,177, 99, 71, 26, 0,168,213,234, 19, + 0,144,147,147, 99, 43, 47, 47,247,136, 12,106, 52, 26, 58,114,228,200, 36, 74, 41,118,236,216,145,166, 80, 40, 40,252,180, 89, + 5,192,180,126,253,250,163, 81, 81, 81, 43,178,179,179,199, 13, 31, 62,252, 72,135, 14, 29,210,106,106,106, 10,141, 70,163,209, +100, 50, 81,158,231, 21, 49, 49, 49, 17,223,126,251,237,233, 61,123,246, 12,214,235,245, 43,214,175, 95,127, 20,128,207, 72,155, + 86,171,205, 49, 24, 12,205,229, 99,234,110,174,242,243,243, 65, 41,197,217,179,103,161,209,104, 46,214,103,135, 50,194,139,252, + 50,229, 29,105,241,158, 22,170,185,146, 17, 4, 1,223,126,251,173,223, 40, 78,125, 12,155,187, 25,154, 50,101, 10, 22, 46, 92, + 88, 39,130, 53,103, 78,237, 59,201,203, 47,191, 28,114, 29, 44,160, 54, 90,149,191, 48, 22,141,159, 44,245, 72, 59, 0, 16, 57, +125,245,108,146, 77, 16, 4,204,154, 53,171, 78,229,115,247, 34,188, 16,139,242, 60,210, 89, 88, 88, 8, 65, 16, 16, 27, 27,139, +251,238,187, 15, 67,134, 12,113, 21, 53,214, 87,247,216,177, 99,187, 94,124,241,197,142,153,153,153,152, 61,123,118,105,116,116, +116,228, 63,254,241, 15,161,188,188,188, 54,156,232, 39,130,197, 12, 22,131, 17,156,128, 17, 44, 0, 33,153, 43,127, 55, 94, 66, +200, 96,247,182, 50, 40,165, 21,132,144,251,110,185,229,150,207, 87,175, 94,173,110,209,162, 5,142, 29, 59,134,210,210, 82, 88, + 44, 22, 40, 20, 10, 36, 37, 37,161,188,188, 28, 31,125,244,145,209, 96, 48,220, 71, 41,173, 8,164, 9, 96, 90,183,110,221,222, +125,227,141, 55, 34, 58,119,238,140,210,210, 82, 84, 87, 87,123,180, 58,173,215,235,161, 86,171,177,127,255,126,108,218,180,201, + 8, 96, 90, 16,205, 58,200,198, 74, 54, 90,193, 12,150,151,166, 86,142,226, 24, 12, 6, 0,176, 55,109,218, 52, 17, 0,206,158, + 61, 11, 0, 23,210,211,211, 95,110,217,178, 37, 89,190,124, 57,165,148,110,241,101,174,188, 52, 75,251,245,235, 87, 6,160,177, +197, 98, 81, 0, 64, 69, 69,133,181, 81,163, 70, 9, 42,149, 74, 82,171,213, 82, 68, 68,132,148,151,151,103,183,219,237, 10, 0, +232,215,175,159, 5, 64, 62,220,234,122,120,105, 74, 0, 42,151, 44, 89,242,218,253,247,223,223,171,119,239,222,153,143, 63,254, +248,225, 71, 31,125,148, 75, 73, 73,137,169,170,170, 50,157, 58,117,170,236,223,255,254,119,213,222,189,123, 7,139,162,120, 97, +201,146, 37,175, 1,168,116,174, 91, 71,211,110,183,255,111,203,150, 45, 15, 13, 31, 62, 92,200,205,205, 69, 65, 65,129,203, 92, + 21, 20, 20,160,109,219,182,216,179,103,143,195,106,181, 6,220,255,161, 28,163,250,194, 52,107, 53,229,230, 1, 2, 25, 43,249, + 37, 42, 84, 77,119, 51, 52,102,204, 24,143,168,149, 66,161,192,186,117,235,124,222, 55,188,175, 43,239,188, 19,183, 54,186, 94, +124,241, 69, 15,179, 54,125,250,116,191, 73, 11,164, 41,231, 93, 20, 69, 84,188,159,226,249, 21,161,159,235, 60, 80, 58,229,123, +167, 40,138,152, 62,125,122,200, 17, 44,120,213,193,242,165, 41,231,189,127,255,254, 48, 24, 12, 46, 3,235, 47,130, 21,108,127, + 58, 28,142, 39, 23, 46, 92, 72,245,122,125,143,202,202,202,191, 93,188,120,113,169,193, 96,184,177,162,162,194,103, 62,101,204, +102,179, 42,208,254,188, 90,152,230, 95, 83,243,122, 35,224, 43,158,221,110, 71,147, 38, 77, 92, 23, 55, 33, 4, 28,199,121, 12, +245,169, 71, 0, 0,148,210,111, 9, 33,163,250,244,233,243,201,147, 79, 62, 25,217,185,115,103,177,121,243,230,168,169,169,193, +185,115,231,112,228,200, 17,251,250,245,235, 43, 13, 6,195,223, 40,165, 65,191, 34,163,148, 46, 35,132,108, 26, 58,116,232, 43, + 61,123,246,124,236,213, 87, 95,229, 91,183,110,141,138,138, 10,196,196,196, 32, 33, 33, 1,199,143, 31,199,134, 13, 27, 28,197, +197,197,239, 2,152, 73, 41, 45, 10,166,235,189, 25,171,213,138,123,239,189, 23,146, 36,225,173,183,222,114,111, 16, 45, 20,172, + 86,171,149, 2, 32,197,197,197, 0, 96,144, 13,215,169, 83,167, 0,224, 98,243,230,205,117, 0,176,101,203, 22, 2, 96,119,168, +233,130, 91, 36,171,109,219,182,231,128,186,221,143,200,243, 81, 27,185, 10,150,110,211,216,177, 99, 11, 13, 6,195,208, 41, 83, +166,188,242,206, 59,239,140,123,231,157,119,234, 44,164,215,235, 87,188,249,230,155, 51,199,142, 29, 91, 8, 63,209, 43, 0,168, +169,169,121,249,239,127,255,251,216, 95,126,249, 37, 50, 34, 34, 2, 53, 53, 53, 40, 41, 41,129,213,106, 69,122,122, 58, 10, 11, + 11,177,108,217,178, 42,163,209, 56, 35,196, 60, 51,194,140,187, 33,240, 23,197, 10,102,174,252, 33, 8, 2,190,252,242,203, 58, + 81,171, 80, 42,181,251, 75,167,175,186, 71,129,162, 96,129, 94,134,228,230,101,188,235,131,137, 98,104,109,251, 5,210, 21, 4, + 1,255,250,215,191, 32, 8,130,223,200, 85,125, 34, 88,178,102,108,108, 44, 0, 64,238,218,232,246,219,111,191, 98, 93, 90,219, +109,152,171,251, 27, 66,200,220,231,159,127,254,181,182,109,219,182, 6,160,114,223, 7,245,140,218, 51, 24,127,121,252, 26, 44, +135,195,145,211,166, 77, 27, 0,240, 48, 88, 50,190,166,217,108,182,156, 80, 54, 74, 41,221, 68, 8, 73,127,243,205, 55,159,210, +106,181,131, 13, 6, 67, 71,160,182, 18,124, 77, 77,205, 22,179,217,188,128,214,163,115,102,167, 97,154, 68, 8,121,107,232,208, +161,115, 6, 14, 28, 56,250,217,103,159, 37,148, 82, 44, 94,188,152,158, 57,115,102, 45,128,105,148,210, 51,161,106,186, 19, 27, + 27,123,244,163,143, 62, 74,252,252,243,207, 97,179,217,176, 96,193, 2, 68, 70, 70, 30,173, 79,250, 4, 65,248,164,119,239,222, +227,246,236,217,179,130, 82,122, 88,165, 82,125,218,175, 95,191,251,118,239,222,189,154, 82,250,171, 32, 8,159,246,234,213,235, +190,253,251,247,127, 70, 41,253,185, 30,201,115, 69,178,236,118,223, 37,138,190, 34, 87, 65,168,124,248,225,135,173, 15, 63,252, +240,179, 99,199,142,253,224,135, 31,126,184,177,188,188,188, 35, 0, 68, 71, 71,255,210,189,123,247,253,171, 87,175, 62,142,218, +200, 85,192, 74,248,148,210, 34, 66,200,200,142, 29, 59,126, 54,123,246,108,109,102,102,166,208,170, 85, 43,156, 63,127, 30,135, + 15, 31,182,127,248,225,135,213, 70,163,241, 78, 74,105, 40,125, 36, 50, 26, 0, 57,218, 20, 29, 29,237,241,242, 36,127,186, 95, +223, 98, 65, 25, 89,211,251,197,140,231,121,191,154, 65, 42,185, 2, 0,116, 58,157,171, 81,210, 80,170, 38, 72,254,234, 13,184, +165, 83,214,148,135, 16,204, 85,208, 47,254,156, 93,213,132,172, 25, 74, 51, 13, 90,173, 22, 54,155,205,165, 27,194,151,156,245, +114,137,148,210, 47, 1,124,217,170, 85,171, 83, 0, 90, 50, 83,197, 96, 92, 57,126, 13, 86,105,105,169,207, 94,221,195,133,211, + 64,205,116, 14,225,210, 60, 3, 96, 44, 33,228,141,239,190,251, 78, 46, 47,152, 69,131,244,103, 24,140, 99,199,142, 13, 23, 69, +241,189, 21, 43, 86,244,164,148, 34, 42, 42,106,239,249,243,231,255, 81, 31, 13,187,221,254, 24, 33,228, 25,249,171, 64,179,217, +252, 24, 33,228, 57, 74,105,141,219,124,215,120, 61,161, 0,204,148,210,100, 63,243,205, 8,221, 92,201,152, 0, 88, 86,175, 94, + 93, 13,224, 39,252,214,206,149,205, 57,152,224, 86, 44, 24, 48,113,148,110, 37,132,180,154, 62,125,250, 92,158,231, 7,213,212, +212,164,104,181,218, 75,118,187,253,127, 6,131, 97, 26,165,180,164,158,105, 99,132, 17,139,197,146,219,166, 77, 27,185,219, 44, +248,250,245, 69,160, 23, 42,135,195,145,147,145,145, 17,244,165,204,135,102,174,191,121,148,210, 11,233,233,233, 92,168, 90, 50, + 86,171,181, 48, 80, 58,211,211,211, 67, 78,159, 91, 58, 3,230, 61, 45, 45,205,103,222, 3, 33, 73,146,223,188,219,237,246, 43, +210, 12,180, 63, 3, 97, 52, 26,203,226,227,227,171, 77, 38,147,104, 54,155, 69,187,221,238, 17,110, 84,171,213,245, 45, 5, 96, + 48,254,114, 92,113, 27, 83,215, 50, 78, 67,117, 71, 24,245,204, 0, 30, 8,131,142,201,107,188, 38,208,120, 61,105,136, 8,144, + 4,192, 16,116,169, 16,160,148, 22, 3,120, 52, 28, 90,140,240, 82, 92, 92,220, 35,220,154, 37, 37, 37, 97,127, 65, 43, 42, 42, +234, 21,110,205,226,226,226,176,167,243,207,162, 25,136,220,220,220,176,159, 19, 12,198, 95,141, 43,139,253, 51, 24, 12, 6,131, +193, 96, 48,252, 66, 0, 12,246, 53,163, 62, 95, 7, 16, 66,124,106, 4, 34,152, 62,211,100,154, 76,147,105, 50, 77,166,201, 52, +175, 63,205, 96,218,215,205,215,137,148,210, 6, 27, 0, 12,102,154, 76,147,105, 50, 77,166,201, 52,153, 38,211,252,171, 13,172, +136,144,193, 96, 48, 24, 12, 6, 35,204, 48,131,197, 96, 48, 24, 12, 6,131, 17,102,152,193, 98, 48, 24, 12, 63, 16, 66, 98,174, +101, 61, 6,131,113,237,194, 12, 22,131,193, 96,248,128, 16,210, 1,192,236, 48,203,206,118,234, 50, 24,215, 61,132,144, 14,132, +144,142,127,116, 58,254, 40,152,193, 98, 48, 24, 12, 47, 8, 33,195, 90,180,104, 49, 11,128, 46,204,210,186, 22, 45, 90,204, 34, +132, 12, 11,179, 46,131,113, 77, 64, 8, 81, 17, 66, 30,224, 56,110,127,135, 14, 29,126,201,204,204,252,153,227,184, 61,132,144, + 49,132,144,235,178,237, 77,127, 16,231,215, 0, 32,132,108, 7, 0, 74,105,255, 63, 48, 61, 12, 6,131,241,135,225,124, 0, 60, + 54,110,220,184, 59,178,179,179,149, 77,154, 52,185, 68, 41,189, 63,140,250,203, 47, 93,186,148,250,224,131, 15, 86,111,221,186, +245, 91, 0,239, 82, 31, 29,187, 51, 24,127, 54, 8, 33,205, 1, 60,166,211,233, 30,185,249,230,155, 99,238,188,243, 78,196,197, +197,193,110,183,227,210,165, 75,216,184,113, 35,118,239,222,157,103,177, 88, 22, 2,120,159, 82, 90,238, 71,103, 59,112,125,120, + 17, 66, 41,149, 59, 46,190, 25, 0, 40,165,219,255,216, 36, 49, 24, 12,198,239, 15, 33, 68, 15, 32,107,254,252,249, 61, 31,123, +236,177, 52,147,201,148, 19, 19, 19,115, 54,220, 6,203,106,181, 14, 46, 42, 42, 58, 48,103,206, 28, 44, 94,188,248, 87, 0,243, +104, 61,250, 94,101, 48,174, 53, 8, 33, 83, 71,141, 26, 53, 39, 49, 49,145,235,208,161, 3,146,146,146, 96, 54,155, 97, 52, 26, + 65, 41,133, 32, 8,160,148,162,162,162, 2, 59,118,236,192,214,173, 91,205,101,101,101, 31, 1, 88, 64, 41, 61,233,166,115, 93, +121, 17,151,193,162,245,236, 20,148,193, 96, 48,174, 23, 8, 33,105,106,181,122,250,134, 13, 27,218,247,237,219, 55,161,170,170, +234,172,205,102,171, 73, 78, 78,166,168,237,212,220, 23, 21,148,210,201, 62,180, 22, 1,136,242,179,142,222,106,181,118, 47, 46, + 46, 62, 0, 0,235,214,173, 67, 86, 86, 86,137,209,104,156, 69, 41, 61, 23,158,220, 48, 24,191, 47,132,144, 19,199,142, 29,203, +112, 56, 28, 40, 46, 46,134,217,108,134,193, 96,112, 25, 44,158,231, 65, 41,133,221, 94, 27,172,149, 36, 9, 7, 15, 30,196,150, + 45, 91,232,217,179,103, 95,165,148,206,114,234, 92, 87, 94,132, 25, 44, 6,131,241,151,134, 16,210,167,113,227,198,207,124,247, +221,119,205,155, 53,107,166,175,174,174, 62,109,183,219,109, 0, 16, 19, 19,147,201,243,188,202,123, 29,135,195, 97,142,136,136, +216,233, 43,186, 69, 8, 89,110, 50,153,250,250, 90,207,185,174,189,172,172,236, 39,121,252,231,159,127,198, 35,143, 60, 98,205, +207,207,159, 79, 41,221, 21,206,188, 49, 24,191, 7,132,144, 19, 63,253,244, 83,198,202,149, 43,209,165, 75, 23,180,107,215, 14, +213,213,213, 46,179,101,177, 88, 96,179,217,234,172, 87, 89, 89,137,103,158,121,230, 36,165,180,181, 83,231,186,242, 34,114,133, +179,215,174,167,114, 79, 6,131,193,168, 47,249,249,249,197,209,209,209,151, 37, 73,162,242,180,178,178,178, 35, 87,162,117,165, +235, 49, 24,127, 82,108, 22,139, 5,221,186,117,195,185,115,231,112,240,224, 65,151,209, 42, 46, 46, 70, 94, 94,158,199,194,251, +247,239,199,161, 67,135,112,211, 77, 55,121,235, 92, 87, 94,196,189,146,123,127,224,250, 40,247,100, 48, 24,140,250, 32, 23, 17, +206,155, 55, 47,238,238,187,239,118, 77,111,136, 34,194,188,188, 60,215, 27, 58, 43, 34,100, 92, 15, 16, 66, 70, 38, 39, 39,127, +248,196, 19, 79, 68,245,236,217, 19, 57, 57, 57,200,205,205, 69, 89, 89, 25, 58,119,238,140,204,204, 76,156, 57,115, 6,155, 54, +109,194,161, 67,135,160, 82,169,144,154,154, 10,221,138,149,120,143,224, 40,165, 52,211, 77,171, 63,112,125,120, 17,151,193, 98, + 48, 24,140,191, 50,114, 37,247,137, 19, 39,182,155, 54,109, 26, 8, 33, 72, 78, 78,174, 8,119, 37,247,188,188,188, 40, 74, 41, + 88, 37,119,198,245, 4, 33, 36, 18,192,243,233,233,233,207, 77,156, 56, 81,213,190,125,123,228,228,228,160,168,168, 8,101,101, +101,216,187,119, 47, 0, 32, 37, 37, 5, 41, 41, 41, 56,126,252, 56,118,237,218, 85, 89, 93, 93,253, 48,165,244,243, 63, 54,245, + 13, 3, 51, 88, 12, 6,131,225, 68,110,166, 97,192,128, 1, 67, 22, 47, 94,140,140,140,140,176, 27,172,147, 39, 79, 70, 77,156, + 56, 17,172,153, 6,198,245, 8, 33, 36, 1,192,203,237,219,183,127,236,145, 71, 30, 17,154, 53,107,134,220,220, 92,124,247,221, +119,104,217,178, 37, 46, 93,186,132,173, 91,183, 90,138,138,138,222, 2,144, 77, 41,173,248,163,211,220, 80, 52,104, 67,163,132, +144,193, 76,147,105, 50, 77,166,249,103,209,164,148,218, 41,165,111,111,221,186,245,221, 97,195,134, 73,225,208,244,102,216,176, + 97,210,214,173, 91,223,165,148,190, 29,200, 92, 93, 15,251,147,105,254,245, 52, 41,165,133,148,210,201, 71,143, 30,109,245,244, +211, 79,127, 50,123,246,108, 73,146, 36, 36, 36, 36, 96,205,154, 53,210,170, 85,171, 62, 44, 42, 42,106, 65, 41,157,122, 61,155, + 43,224,183, 74,238, 12, 6,131,193,112, 66, 41,253,154, 16,146, 3,224,177, 48, 75, 87,159, 57,115,230, 95,148,210,195, 97,214, +101, 48,174, 41, 40,165,231, 1,220, 79, 8,249,231,193,131, 7,167, 1,160, 0,102, 83, 74,127,253,131,147,246,187,193, 12, 22, +131,193, 96,248,128, 82,122,152, 16,242,114,152,101, 95,166,148,150,133, 89,147,193,184,102,161,148, 30, 1,112,207, 31,157,142, + 63, 2,214, 23, 33,131,193, 96,248, 33,220,102,136,153, 43, 6,227,175, 3, 51, 88, 12, 6,131,193, 96, 48, 24, 97,134, 25, 44, + 6,131,193, 96, 48, 24,140, 48, 67, 0,248,251, 18, 96, 75,200, 34, 87,240,133, 66, 48,125,166,201, 52,153, 38,211,100,154, 76, +147,105, 94,127,154,193,180,235,227, 63,174,105, 40,165, 65, 7, 56,219,203,170,239, 0, 96,240,149,172,199, 52,153, 38,211,100, +154, 76,243,207,171,137,218,151,119,130,218, 82, 18, 78, 30,191,214,210,233,157,230,107, 53,239,127, 21,205,235,109, 8,248, 21, + 33, 33,196,181,147, 8, 33, 18, 0,137, 58,247,226,213, 64, 8,145, 15, 64, 88,244, 24,225,199,121,140,228, 46, 61, 40, 59, 78, + 12, 6, 35, 20,220,238, 29, 60,126,123,200, 58, 0, 56, 8, 33,184,214,238, 37,225,124,206, 53, 68,222,255,202,154,127,118,124, + 26, 44,121, 71,241, 60,255,109,163, 70,141, 6, 20, 23, 23, 75,206,233, 80, 42,149,224, 56, 14,162, 40, 26,171,170,170,244,245, +221, 32, 33,228, 63,137,137,137, 15,150,148,148, 72, 28,199, 33, 34, 34, 2,132, 16,151,102,121,121,121,189, 53,195, 77,243,230, +205,203,140, 70,163,206,123,122, 68, 68,132,233,194,133, 11,145,127, 68,154,126, 79, 8, 33, 68,161, 80,140,138,141,141,141, 46, + 42, 42,162, 28,199, 65,161, 80,128,231,121, 56,255,219,203,203,203, 63, 14, 85, 47, 54, 54,118,127,108,108,108,180,188, 62, 33, + 4, 37, 37, 37,229, 5, 5, 5, 55, 2,128, 90,173,222,165,213,106,227, 4, 65, 0,207,243,224,121, 30, 6,131,161,164,184,184, +184, 79,131,101,146,209,160,172, 93,187,150, 31,154, 50,190,165, 64,141,157, 56,142, 70, 73, 18,169,176, 19,245,207,155,114,255, +115, 58,148,245, 71,143, 30,237,104,232, 52, 6,130, 16,210, 7, 0, 40,165,187,194,164,231,222, 63,161, 9, 64, 49,128,211, 0, +214, 80, 74,141,225,216,198,213,160, 82,169,222, 74, 76, 76,124,164,186,186,218, 64, 8,161,132, 16,212, 62, 6, 80,231,215,225, +112,228, 20, 23, 23,119,243,165,227,246,144, 21,149, 74,229,155,141, 27, 55,254,187,193, 96, 48, 56,245, 40, 33, 4, 73, 73, 73, + 30,122, 0, 96,179,217,114,138,138,138,124,106,122,147,144,144,176, 68,173, 86,255,205, 96, 48,212, 56, 13,145, 11,175,135,248, +153,162,162,162,126,254,116,228,180, 42,149,202, 5,137,137,137, 15, 57,243, 14, 66, 8,141,143,143,191,234,188, 39, 38, 38,254, +189,166,166,198, 35,239, 9, 9, 9, 62, 53,253,229,221,151,166,123, 58, 9, 33,136,143,143,191,234,116, 94,139,154,215, 3,254, + 34, 88, 28, 33,100,125,159, 62,125,110,222,190,125, 59,119,236,216, 49,174,109,219,182,112, 56, 28,144,164,218,243, 57, 53, 53, + 85, 83,223,141, 17, 66,150,246,235,215,239,222, 29, 59,118,112,235,215,175,231,186,119,239, 14, 66, 8, 28, 14, 7, 28, 14, 7, + 58,116,232,160,190,154,204, 16, 66,116,130, 32, 60,163, 84, 42,251,219,237,246,118, 0, 32,138,226,175,102,179,121,187,221,110, +159, 79, 41,173, 14, 69,199,106,181,106, 10, 11, 11,235,236,155,244,244,116,229,149,166, 77,175,215,239,230, 56, 46, 93, 30,151, +141,134, 51,221, 62,127, 41,165,103,139,138,138,122,251,211,140,137,137,113,105,250,211,240,158, 38, 73,210,217,194,194, 66,191, +154, 78,115,117,119,191,126,253,162,182,108,217, 66, 46, 93,186, 68,212,106, 53, 36, 73,130,195,225,128,205,102, 67,251,246,237, +235,213,126, 90,116,116,180,126,234,212,169, 45,111,187,237, 54,172, 91,183, 14, 15, 60,240, 0,250,246,237,123, 82,158,175,213, +106,227,142, 30, 61,154, 17, 27, 27, 11,131,193,128,138,138, 10,220,114,203, 45,245,217,196, 53, 73,207, 46, 77,102, 19,142,196, +202,227,212,238, 40,221,251, 83,238, 85,183,171, 20, 29, 29,125, 72,169, 84, 38,202,199,149,227,126,251, 86,197,223,241, 55,153, + 76, 5,197,197,197, 93, 2,233, 18, 66,154, 3,184,131,231,249, 86,130, 32,180, 1,208,220,110,183, 39, 2,128, 66,161, 40,224, +121,254,188,205,102, 59,110,177, 88, 78, 1,248,146,214, 54, 36,232,147,161, 41,227, 91, 18,187, 97,116,149, 89, 26,166,105,145, +221,218,112,102,234, 9,141,202,240,245,208,148,241,107, 67, 53, 89,127, 20,132,144,180,198,141, 27, 63,227,252,127,153,134,167, + 19,230, 40,147,201,212,151,231,121,149,221,110, 71, 65, 65, 65,241,187,239,190,123, 97,209,162, 69, 3, 8, 33,111,208, 32, 13, +143,246,234,214,244, 0,199,113,169,112,218, 7,137, 58,114,246, 28,184, 20,150, 7, 19,207,243, 11,238,186,235,174,135,214,174, + 93,171, 57,120,240,160,166, 93,187,118,174,251,147, 36, 73,240, 14, 60,164,165,165, 5,146, 35, 0, 4,142,227,222, 26, 61,122, +244,184,229,203,151,107, 46, 92,184,160, 73, 78, 78,118,105,186,155, 55,153,228,228,228,144,210, 26, 23, 23,247,159,219,110,187, +237,254,101,203,150,137, 27, 54,108, 80, 55,106,212, 8,113,113,113, 80, 40, 20,117,150,237,211,167, 79,176,150,248, 57,142,227, + 22,140, 24, 49,226,254, 85,171, 86,105,246,237,219,167,233,208,161, 3,120,158,191,234,188,143, 28, 57,114,220,202,149, 43, 53, +191,252,242,139,166, 85,171, 86,224, 56, 14, 28,199,213,209,227, 56, 14, 77,154, 52, 9, 73,243,206, 59,239, 28,183,122,245,106, +205,161, 67,135, 52,109,218,180,113,237, 79,183,226,185,122,167,243, 26,215,252,211, 83,231, 65,233, 12,151, 46,239,211,167,207, +208,237,219,183,243, 0,112,232,208, 33,148,150,150, 34, 37, 37, 5, 58,157, 14, 42,149, 10, 38,147,169, 94,225, 62, 66,200,127, +156,230, 74, 4,128,207,254, 54, 18,103, 69, 96,114,161, 5, 10,133, 2,103,206,156, 1,207,243, 87, 28, 66, 36,132,220,164,215, +235,151,125,254,249,231, 49, 93,186,116,225,138,138,138,144,158,158,142,210,210,210, 27,119,236,216,209,117,252,248,241,227, 9, + 33, 15, 80, 74,119,132,170,249,245,215, 95, 67,171,213, 66,163,209, 64,171,213,194, 98,177,144,224,107,249, 70, 16,132,212,243, +231,207, 39,232,116, 58, 72,146,228, 26,188,202,175, 93, 72,146,132,140,140, 12,107, 32, 77,158,231, 83, 47, 92,184,144,160, 86, +171, 65, 41,245,208,115, 56, 28, 80,169, 84,238,111, 10,112, 56, 28, 72, 79, 79,247,171, 41, 71,174,100,115, 5, 0, 43, 86,172, + 64,227,198,141,145,144,144, 0,173, 86, 11,181, 90,237,241, 64, 15, 5,158,231, 49,116,232, 80,204,152, 49, 3,217,217,217,120, +254,249,231, 61,110,176,162, 40, 34, 54, 54, 22,223,124,243, 13,244,122, 61,154, 53,107, 6, 81, 20,235,181,141,107, 17,194,145, +216, 61, 7, 46,186, 34,178,183, 14,108, 43,244,236,218,236,157,218, 49, 9, 28, 7, 72, 82,237, 35,147, 16, 80,187, 77, 42,251, +225,231,220, 87,130,233,242, 60,159,124,225,194,133, 4,149, 74, 21, 82, 58, 28, 14, 7, 82, 82, 82,248,128,105, 37,100, 88,102, +102,230,103,143, 63,254,184,162, 85,171, 86, 68,161, 80, 64, 16, 4, 8, 66,237, 45, 66,146,164,102,148,210,102,146, 36,221, 92, + 80, 80, 64, 23, 45, 90,244, 79, 66,200, 93,148,210,175,125,233, 9,212,216,169,202, 44, 13,251,254, 71,220, 56,122,240,139,248, +102,205,212, 27,251,117,150, 16,169, 49,158, 70,109,228,230,154,132, 16,162, 87,171,213,211,191,255,254,251,140,170,170,170,202, +190,125,251, 78, 39,132, 60, 77,195,208, 25,115, 89, 89,217, 17,249,191, 82,169,196, 83, 79, 61,133,219,110,187, 45,250,150, 91, +110,153, 66, 8,249, 7,165,212,239,181,201,113,124,234,174,253,231, 18,228,241, 59,135,118, 84,244,238,222,172, 0, 0,234, 22, +188, 80, 72, 14, 41,103,223,143, 57, 65, 13, 24, 33,228,159,163, 70,141,186,111,237,218,181, 58, 0, 88,188,120, 49, 70,141, 26, +133,216,216, 88,104, 52, 26, 40, 20, 10,136,162,232,241, 27, 64, 75, 46, 30,250,231, 61,247,220, 51,122,249,242,229,145, 0,176, +124,249,114,140, 28, 57, 18,113,113,113,136,140,140,132, 82,169, 4,207, 7, 60, 29,125, 18, 23, 23,247,159,190, 55,222,248,240, +178,101,203, 0, 0,211,158,126, 26,183,245,232, 1,157, 70, 13,141,186,246,221,151, 82, 64,201,139,184,117,242,147,193,242,205, + 1,120, 99,212,168, 81, 99, 87,173, 90, 21, 9, 0, 7, 15, 30, 68, 97, 97, 33, 18, 19, 19,161, 86,171,161, 84, 42, 93,121, 38, +132, 64,173,246,255,254,239,158,247, 81,163, 70,141, 94,185,114,101, 36, 0, 44, 93,186, 20, 67,135, 14,117,229, 93,165, 82, 65, +161, 80,120, 12,222,102,211,151,230, 93,119,221, 53,122,245,234,213,145, 0,240,241,199, 31, 99,240,224,193,136,137,137,113,237, + 79, 89,171, 62,199,232, 90,214,188, 94,240, 48, 88,206, 29,197, 37, 38, 38,142,253,254,251,239, 93, 79, 81, 65, 16,160, 82,169, +160, 82,169,160, 84, 42, 93,197,132,161, 66, 8, 33,137,137,137, 15,238,216,177,195,181,146,197,235,166,160, 82,169,234,253,224, +118,211, 31, 60, 96,192,128,149, 27, 55,110,140, 80, 40, 20, 48, 26,141, 56,114,228, 8,162,163,163,161, 84, 42, 49, 98,196, 8, +190, 79,159, 62,113, 55,223,124,243, 58, 66,200, 56, 26,194, 23, 10,148, 82,232,116, 58, 15,131,117,181, 69,200,106,181, 26, 27, + 54,108, 0,207,243, 62,111, 92,238,255, 19, 18, 18,130,234, 17, 66,160, 82,169,176,123,247,110,240, 60, 15, 81, 20, 33, 8, 2, + 68, 81,196, 87, 95,125,133,103,159,125, 22,197,197,197, 32,132, 64, 20, 69, 68, 70, 6, 45,221, 36,177,177,177,209,178,185, 2, +106,205,143, 90,173,134, 40,138, 68, 16, 4, 34, 23,225, 17, 66, 72,168,101,234, 28,199,225,147, 79, 62,193,235,175,191,142, 23, + 94,120, 1, 75,150, 44, 65,167, 78,157, 92,243, 5, 65, 64,101,101, 37, 98, 98, 98, 16, 19, 19,131,136,136,136, 43, 62, 23,174, + 37,188,247,206,155,243, 23,106, 32, 81,212, 86,242,144, 0, 9,160,160,144,168,132,130,220,211,120,117,198,191, 66,126,234,168, + 84, 42,236,218,181,203,101,130, 4, 65, 0, 33, 4,238,198, 72, 30, 26, 55,110, 28, 84, 79,161, 80,188,246,197, 23, 95, 40, 63, +249,228, 19,172, 90,181,202,117,110,105,181, 90, 68, 71, 71, 35, 46, 46,206, 53,164,166,166,146, 15, 63,252, 80,209,169, 83,167, +215, 0,248, 52, 88, 28, 71,163, 52, 45,178, 91,143, 30,252, 34, 0, 96,244,139, 20,101, 39,231,220,192,149,191, 18,229,107,249, +107, 1, 82,219,209,115,214,134, 13, 27,218, 39, 39, 39, 71,104,181,218, 11,243,230,205,139,123,234,169,167,178, 8, 33, 47,211, +171,235,148,185, 66,142,210, 68, 68, 68, 68,244,239,223, 95, 57,119,238, 92,180,108,217, 18,227,199,143,143, 93,188,120,241, 8, + 0,107,252,173,236,125,169, 45,122,251,157,104, 74,107,207, 31, 42, 81,143,223,210,194,243,120,122,202,171, 33, 37,170, 73,147, + 38,143,173, 91,183,206, 85, 29, 34, 57, 57,217,227,225,239,126,143,146, 7,127,134, 0,206,202,205, 77,155, 54,125,248,211, 79, + 63,117,105, 54,106,212,200,117, 95, 18, 4, 1, 28,199,225,251,239,191,199,188,215,178, 16, 19,159,140,133,111, 47, 14,154,206, +132,132,132, 37,195,134, 13,251,219,210,165, 75, 93,211, 58,182,104,129,219,251,244, 64, 66, 35, 61, 26,197,212,222,219,168, 68, +240,243,241,192, 1, 71,249, 57,215,164, 73,147,241,107,214,172,113,165,211,253,190, 12, 0, 6,131,193, 21,181,183, 88, 44,232, +214,173, 91, 72,121,119,215,148,163,107,178, 89,243,190,215,203, 47, 48,129, 52,155, 52,105,242,176,108,128, 1, 32, 54, 54,214, + 67, 67, 20, 69,172,249,102,153,119, 30,175, 90,179,190,199,221, 91,243,220,185,115,152, 59,119,174,199,113,151,163, 89, 41, 41, + 41, 88,180,104, 81, 32, 77, 95,116, 7, 16,239, 54,110, 1,160,116,251, 45, 2,240,131,143,229,228,233, 34,128, 27,156,243, 28, + 0,170, 0, 68,251,208,243,167, 83,140,218,238,126,226,189,150,247,222,142, 11, 1, 0, 8, 33,242,213, 59, 0,192,174,226,226, + 98,233,216,177, 99,220,193,131, 7, 33,138, 34, 18, 18, 18,208,189,123,119, 0,128,213,106,133, 40,138,208,106,181, 36, 58, 58, +186, 64,126,224,202, 59,207,189, 44,221,205,200,112,165,165,165,210,230,205,155,185,229,119, 13,129,133, 2,157,167,207,195,208, +225,195,177, 41, 69, 9, 30,192,141,199,138,161,209,104, 4, 81, 20,109,242, 65,144, 53,221,235,102,121,155, 35, 66, 72,164, 86, +171,253,240,203, 47,191,140,224, 56, 14, 85, 85, 85,144, 36, 9,125,251,246, 5,199,113, 56,124,248, 48,166, 77,155,134,207, 62, +251, 12, 95,124,241,133,186, 75,151, 46, 31, 18, 66,218, 81, 74,171,100, 13, 31,154, 0,128,200,200, 72,104, 52, 26,151,193,146, +243,236, 30,234,150,151,167,148,230, 22, 23, 23,119, 13,164,233,112, 56, 48,114,228, 72, 16, 66,192,243,188,199, 77,199,253, 87, +161, 80,224,240,225,195,117, 78, 62, 95,198, 80,206, 43, 0,104, 52, 26,232,116, 58,108,219,182,205, 53,191,115,231,206,176, 88, + 44,104,212,168, 17,126,253,181,110, 23, 80,222,154, 69, 69, 69, 52, 47, 47,143, 44, 95,190, 28,162, 40, 34, 46, 46, 14, 26,141, +134, 44, 91,182, 44, 75,161, 80,164,154, 76, 38,201, 98,177, 64,169, 84, 46,148,163, 89,130, 32,212, 84, 84, 84,196,249,211,228, +121, 30,143, 63,254, 56,158,123,238, 57, 44, 89,178, 4, 19, 38, 76,128,247,124,147,201,132, 70,141, 26,185, 76, 86, 40,121,191, + 90, 26, 92, 83,162, 56,114,104, 19,142,254,178, 5,146, 67,130, 67, 51,137,208,191, 0, 0, 32, 0, 73, 68, 65, 84,162,160,212, + 1,201, 14, 28,220,188, 55,227,242,217,188, 20, 10, 10, 56, 11, 50, 84, 21,213,246,155, 27,169,218, 0, 88,191,173,216,252,150, +191,116,202,251, 70, 16, 4,216,108, 54,124,249,229,151, 56,125,250, 52,190,253,246, 91, 24,141, 70,215,126,236,213,171, 23, 30, +126,248, 97,159, 6,203, 91,147, 82,186,244,210,165, 75,157,251,246,237, 75,202,203,203, 81, 94, 94, 14,163,209, 8,135,195, 1, +187,221, 14, 65, 16, 16, 17, 17, 1,181, 90,141,196,196, 68,152, 76, 38,106, 54,155,151,250,211,148, 36, 82, 97, 56, 51,245,196, + 55,107,166,222, 56,250, 69,138,181,175, 19,180,108,170, 50,252,239, 64,228,195,235,119, 62,127, 11, 0, 42, 57,239, 58, 28, 64, +109, 14,169,248,185,172,127, 79, 10,150,206,112, 16, 64,243,177,249,243,231,247,236,219,183,111, 66,101,101,229, 49, 73,146,232, +221,119,223,141, 19, 39, 78,180, 91,188,120,241, 99, 0,222,174,175, 38, 33,100,128,115,254,100,183,105,228,155,111,190,185, 11, +192,131, 31,124,240, 1, 70,141, 26,133,197,139, 23,103,194,203, 96,185,107, 82, 74,113,254,228,247, 56,127,106, 39, 36,137,186, + 69,193,125,255,247,247,230,227,157,206,154,154, 26,211,143, 63,254,168,251,224,131, 15,144,144,144,128,180,180, 52,104, 52, 26, + 68, 68, 68,120, 60, 92,221, 31,184,193,174, 77,163,209,104, 58,127,254,188,110,229,202,149,136,139,139, 67,243,230,205,161,209, +104,160, 84, 42, 93, 47, 2,203,151, 47,199,138, 25,247,225,252,241, 95, 48,242,246,186,213, 1,188, 53, 53, 26,205,223,150, 46, + 93,234, 17,242, 72,140,137,129, 32,114,224, 69,130,152, 65,119, 1, 0,202,190,251,220,111,235,142, 94,154,164,170,170,202,180, +111,223, 62,221,129, 3, 7, 32, 73, 18,154, 55,111, 14,131,193, 0,189, 94,239,202,255,230,205,155, 49, 98,196, 8,124,242,201, + 39,232,213,171, 87,208,188, 87, 87, 87,155,126,249,229, 23,221,167,159,126,138,216,216, 88, 52,105,210,196,149,119,121, 16, 69, + 17, 60,207, 35, 61, 61, 29, 21, 21, 21,208,233,116, 1, 53,107,106,106, 76, 7, 15, 30,212,125,250,233,167,136,137,137, 65,106, +106,170, 43,194, 38,155,162,215,223,153,225,161, 17, 65,146,174, 90,179,190,199,221, 91,243,174,187,238, 66,203,150, 45,161,215, +235,161,213,106, 93,218,129, 52,221,188,200,205,148,210,237,240, 36,158, 16,178,209,109,251,195, 9, 33, 27,221,127,253, 45,231, +252,123, 83, 86, 86, 86,183,236,236,236,185,189,122,245, 90,185,123,247,238, 21,254,244,252,233,100,101,101,101,102,103,103,207, +117, 95,222,199,118, 92, 8,110, 51,137, 51,115, 2, 0,180,109,219, 22,165,165,165, 80,169, 84,232,222,189, 59,138,139,139,161, +211,233,160, 80, 40, 64, 41,197,164, 73,147,248,231,159,127, 62,129,227, 56,216,237,181, 47,118,130, 32,248, 43, 75,151, 56,142, + 67,239,222,189,113,196, 89,242, 51,116,248,112,164,166,166, 66,174,196, 17, 17, 17,129, 73,147, 38,145,103,159,125, 86,144,163, + 23,148, 82, 24,141, 70, 36, 37, 37,249,141,205, 10,130,240,244,186,117,235,162,148, 74, 37,170,170,170, 92, 69,100, 60,207,227, +216,177, 99,120,227,141, 55,240,247,191,255, 29, 23, 47, 94, 68,114,114, 50,158,123,238, 57, 93,118,118,246,211, 0,102,250,211, +148,209,233,116, 46,115,165,209,104,240,244,211, 79, 11,125,250,244, 73,208,233,116,136,140,140,132, 92,220,231,112, 56,208,162, + 69,139,160, 86, 92,146, 36,108,218,180, 9,130, 32, 4,141, 96, 57, 79,188,144, 52,247,237,219,231, 50,103,238,111, 69,132, 16, + 28, 57,114,196,101,230, 66,208,164, 28,199, 65,171,213,162,113,227,198, 80,171,213,208,104, 52,100,229,202,149, 47,167,165,165, + 37, 61,251,236,179, 92,101,101, 37,215,187,119,111,140, 26, 53, 74,144, 36, 9, 86,171, 21,153,153,153, 1,211, 72, 8,193,246, +237,219,241,238,187,239, 98,194,132, 9, 62, 35, 88,114, 37, 72,189,254, 15,255,198, 33,108, 72, 0,172,118, 27, 12,213, 70, 87, + 17,174,195,225,192, 47,219,126,202, 56,251,211,201,204,141, 43, 63, 17, 1,192,180,237,115,247,213,146, 70,189,179,186,245,205, +177,138,125,219, 74,173,251, 2,233,115, 28,135, 39,159,124, 18,175,188,242, 10,238,185,231, 30,108,222,188, 25,211,166, 77,195, +248,241,227, 61, 34, 88,161, 96,179,217,222,123,224,129, 7, 38,172, 93,187,182,205,139, 47,190,200,201, 17, 44,141, 70, 35,215, +225,130,217,108,134,209,104,196,241,227,199,165, 71, 31,125,244,132,197, 98,121,207,159,158,157,168,127,214,168, 12, 95,183, 72, +229, 90,214,156,251, 87,100,223, 30,205,141, 68,221,181,226,174,214,131,233,176, 7,155,199,128, 82, 80, 9,144, 40, 96, 54,215, + 96,210,164,167,234, 95,102, 20, 70, 8, 33,195,198,141, 27,119,199, 99,143, 61,150, 86, 85, 85,117,198,110,183,219,228,121,211, +166, 77,195,201,147, 39,135, 16, 66,206,251, 43, 18,245,163,153,218,162, 69,139,167, 28, 14, 7, 37,132,156,166,148,230, 56,103, + 45, 4, 16,181,125,251,118, 0, 64,106,106, 42, 0,100, 18, 66,150, 3,168,112, 55, 99, 46, 40,133,205,102,135,209,104, 14,104, +172,228,113, 74,131, 85, 63,114,165,145,182,105,211, 6,119,220,113, 7, 68, 81,116,189,164,185, 23,143,121, 27,173, 0, 80, 0, + 18, 33, 4,201,201,201, 24, 54,108, 24, 20, 10,133,135,166,252, 64, 29, 54,108, 24,158,156, 57, 29,239, 61, 57, 16,239, 62,144, +129,193,179, 11, 2,166,211, 96, 48, 84,111,221,186, 85,253,220,132, 9,184,161, 85, 43, 52,210,235,209, 52, 49, 30,106,149, 18, + 10,247, 52,145,224, 65,117, 90,251,176,147,120,158, 71,135, 14, 29, 80, 80, 80,128,115,231,206,225,220,185,115,224, 56, 14,125, +251,246,117, 69,130, 79,157, 58,133,153, 51,103,194,108, 54,135,156,247, 86,173, 90, 97,224,192,129, 80, 42,149,208,104, 52, 30, + 69,131,242, 62,173,170,170, 66,203,150, 45,177,126,253,122,180,110,221, 58,168,102,219,182,109,209,191,127,127,143,253,169, 86, +171, 93,207, 13, 0,184,180,175,218,181,141,148,148,148,122,105,126,187,255, 34, 62,216,188, 21,102,139,132, 74,131,205, 99,133, +164, 70,122,236,252,244,197,144,242, 46,107,190,247,222,123,168,168,168,112, 61,123,228, 96,137, 28,156,104,210,164, 9,222,125, +247, 93,223, 98,191,121, 17,159,207, 42, 95, 70, 38,200,114,242,201,165,202,206,206,158,235,189,126, 48, 61,247,249, 94,235, 91, +188, 76, 89,157,147,216,215,221, 87,146, 47,130,148,148, 20,200,245, 60,228, 11, 68,198,110,183,227,179,207, 62, 67, 66, 66,130, +107,136,138,242, 29,253,167,148, 82,185,158,208,147, 69,181,213, 12,190, 73, 86,224, 60,128,219,139,106, 47, 8,185,142,208,186, +117,235,224,110, 96, 34, 35, 35, 3, 22, 23, 41,149,202,155,187,119,239,206,153,205,230, 58,230, 42, 59, 59, 27,227,198,141, 67, +235,214,173, 33, 73, 18,170,171,171, 49, 96,192, 0,113,225,194,133, 55,163, 30, 6, 75,163,169,173,207,111,177, 88,176,109,219, + 54,196,196,196, 32, 46, 46, 14,177,177,177,136,140,140,148,191,132, 12,120,101,203,149,252, 70,142, 28,233,122,240,185, 71,173, +188,205,214,238,221,187,131, 37,207, 85,105,178, 71,143, 30,208,106,181,208,233,116,208,233,116,216,180,105,147,107,153, 27,111, +188, 17,146, 36, 33, 33, 33, 1,123,246,236, 9, 88,204, 73, 41,165, 10,133,194,181,188, 40,138,100,217,178,101, 89,233,233,233, + 73, 83,166, 76,225,120,158,199,161, 67,135,112,244,232, 81, 52,111,222, 60,228, 58, 89,229,229,229,151,179,178,178, 28, 89, 89, + 89, 0,128,204,204, 76,148,151,151, 23,202,243, 43, 43, 43, 75,134, 12, 25,226, 81, 47,163,184,184,184, 36,232, 14,184,198,145, + 36, 9,118,171, 29, 6,147, 9,213, 85, 6, 87, 52,168, 48,175, 32,250,197,103,159, 17,223,152,244, 16, 0,224,217,183,222, 70, +213,146,223,110, 96,159, 63, 55, 46,225,174, 55, 86, 78, 5, 48, 34,144,190,193, 96,128,217,108, 70,179,102,205,176,127,255,126, + 84, 85, 85, 97,240,224,193, 30, 17, 82,121,159, 6, 11,197, 83, 74, 45,132,144, 62,195,135, 15,255, 97,254,252,249, 45,218,181, +107, 71,106,106,106, 96, 48, 24,224,254,251,203, 47,191,208, 21, 43, 86,156, 53, 24, 12,189, 41,165, 22,127,122,155,114,255,115, +122,104,202,248,181,255, 59,196, 15, 79,104,121, 66,159, 91,214,194, 94,146,171,170,169, 52, 30, 55, 57,232, 81, 80, 7,224,128, + 4,106,151,224,112, 22,111,253, 81, 16, 66, 58,180,104,209,226, 31, 11, 23, 46, 76, 52,153, 76,185, 54,155,173,198,107, 62, 22, + 47, 94,140, 97,195,134,253,131, 16,146, 19,172, 66,186,115, 29,101,116,116,244,180,109,219,182,101, 94,190,124, 57,191, 79,159, + 62, 83, 9, 33, 83, 40,165,150, 54,109,218, 68, 29, 56,112,160,175, 40,138,202,242,242,242,195,122,189, 30, 22,139,165,131,205, +102,179,116,235,214,109,167, 47, 61, 42, 1, 54,155, 13, 70,163, 25, 21, 21, 85,176, 88,109,206,123,166, 4,135,195,238,252,149, + 96,119,222, 71,149, 10, 33,178,107,199,164,106, 74, 41, 56, 66,202, 15,252,114,217,103, 77,106,249,188,240, 85,148, 21, 74,244, +202, 7, 14,226,252,106, 44, 46, 46, 14,162, 40,226,147, 79, 62,193,207,187, 54,253, 63,123,231, 29, 30, 69,213,182,241,251,204, +246,221,100,147, 13,105,164, 64,168, 74, 19, 41,130, 32, 69, 90,104, 2,138,210, 69,129, 15,145,142,162,148, 23, 17, 21,129,208, +139, 82, 21, 17, 65,145, 94,149, 34,210, 5, 68,233,189, 8, 4, 66,122,223,108,182,206,204,249,254,200, 78,220,108,182, 37, 4, + 17,156,223,117, 13,100,103,206,220,115,102,203,236,189,207,121,206, 51, 80, 72, 40, 56,214, 6,214,102, 5,103,179, 64, 38,145, +224,215, 51,119, 16, 91,211,251,196,108, 66, 8, 13, 9, 9,193, 43, 77,155,162, 75,211,166, 5,211,213,164, 82,248, 43,149,208, +200, 85, 5,145, 43, 0,148, 99,224, 54,124, 87, 20, 94,232,103,120,120, 56,254,252,243, 79,140, 30, 61, 26,179,102,205,130, 90, +173, 46,156,205,124,245,234, 85,108,216,176, 1,177,177,177, 37, 62,119, 33, 98, 55,113,226, 68, 36, 38, 38, 98,225,194,133,104, +216,176, 33,100, 50, 25,178,179,179,241,210, 75, 47, 33, 37,197,179,177, 20, 52,129,191,135,241, 20, 10, 69,145,104,147, 96,252, + 74,250, 26, 57,106, 14,124, 45, 2, 59,126, 91, 7, 2,130,147, 63,188, 95,228,187,104,217,250,163, 37,214,252,228,147, 79,138, +244,211,151,232,149,175, 56, 69,153,124,105,119,218,190,202, 56,113,226,196, 73,132,144, 93, 19, 39, 78,156, 20, 23, 23,119,201, + 23, 61, 55,219,127,178,255,255,138,195,186,211, 78,109,138, 27, 44, 74, 41, 85, 40, 20,224,121,190,136,169,114, 78,168, 21, 66, +126,142, 33, 69, 79, 48, 12, 3,158,231, 11,223, 12,206, 63, 87, 37, 18, 9, 78,156, 56,129, 19, 39, 78, 20, 89,191,114,229, 74, +143, 95,224, 44,203,214,210,106,181, 69,162, 87,114,185, 28, 19, 39, 78, 68,255,254,253, 11,205,149, 92, 46,199,234,213,171,241, +194, 11, 47,192, 98,177,212,242,212, 87,185, 92,158, 95,190,124,121, 6, 40,184, 0,249,249,249,145,209,163, 71, 75, 88,150, 45, +124, 78,132, 69,200, 77,243,246,102, 33,246, 89, 41,251,246,237,243, 41,130,229,107, 14, 18,165, 20,231,206,157, 43, 98,218,132, + 89, 48, 0,112,238,220,185,194,252, 44, 95, 52, 37, 18, 9, 56,142,131, 90,173, 38,114,185,156,200,229,242,104,193, 92, 73, 36, +146,194,215,219, 49, 39,207,219,185, 63,120,240,160,181,167,237,169,169,169, 79,109, 57, 6,171,205, 6, 99,190, 5,250, 60, 35, + 62,139,251,182, 96,229,103,248, 29,192,239,205,134,142,198,240, 14,177,109, 80,116,156,223, 43,142, 95,138,155, 55,111,134, 76, + 38,195,246,237,219, 17, 16, 16,128,110,221,186, 33, 32, 32, 0, 19, 38, 76, 64,239,222,189,125,142, 96, 1, 0,165, 52,135, 16, +210,236,189,247,222,251, 99,206,156, 57, 21, 43, 84,168, 0,139,197, 2,171,213, 10,139,197,130, 91,183,110, 97,221,186,117,247, +243,243,243,155, 81, 74,115,188,233,237,125,240,205,173, 45, 71, 62, 72,108,215,251,117,227,213,148, 61, 72, 78,206, 0,203, 62, + 0,207,177,176,178, 5, 51,146, 57,150, 5,203,114,144,203, 37, 1,115,166,191,255, 11, 15, 10,134, 33,150, 30, 61,122,116, 42, +201,115, 82, 90, 8, 33, 65, 0,134,254,245,215, 95,250,224,224,224, 11,246,213, 1,137,137,137, 4, 0, 34, 35, 35, 41, 0,199, + 4,247,161,246,124, 44,111, 55,109, 30,186,115,231,206,151,116, 58,157,133, 97,152,172,143, 62,250,168,194,167,159,126, 58, 20, +192,162,107,215,174,125,219,167, 79,159, 64,199, 95,240, 25, 25, 25,167,135, 14, 29,138,107,215,174,125,235, 74,140,194, 30,193, + 50,153,144,150,145,133,193, 67, 39,219,215,219,255,165, 69,219, 14, 27, 5, 21, 0,164,167,220,194,192,193,163, 61,206,134,224, +121,222,229, 23, 96, 9,114,112, 10,142, 91, 16,122, 0, 80,240, 30,245,247,247, 47, 24,102,219,190, 14, 63,205, 27, 10,112, 86, + 80,155, 17,176,230, 3,214, 60,240,150,124, 16,185, 26,176,121,175, 82, 65, 8,161,254,254,254,240, 87,171, 17,166,211, 21, 20, +113,148, 72, 32,147, 73,193,219, 0,194,217,103, 94,243, 0,239, 67,129, 15, 74, 41, 13, 9, 9, 1,207,243, 80,171,213,184,123, +247, 46,134, 15, 31, 14,171,213,138,215, 94,123, 13, 22,139, 5, 38,147, 9, 70,163, 17, 85,170, 84, 65,126,126,190, 79,231, 46, + 92,231,133,209,158,247,223,127, 31, 47,188,240, 2,166, 78,157,138,241,227,199,163, 74,149, 42, 24, 54,108, 24,214,173, 91,135, + 58,117,234,120,212,117,124, 62, 5, 77,225,117,113, 30,202, 3, 80,226,215,200, 89,179, 32,239, 31,197, 94,247, 49,111,181, 45, +177,102, 92, 92, 28,210,210,210,138, 69,174,132,191,163,162,162,176,108,153,247,220, 59, 55,199, 19,162, 69,225, 46, 54,191,226, +212, 14, 40,200,165,250, 3,128, 57, 46, 46,238, 82, 92, 92, 92, 23, 66,200,174,184,184,184, 46, 78,237,188,233, 56,111, 79,243, +214,215,194,171,175,221,125,182, 2,254,142,140, 8, 95,160,246,131, 8,237, 0, 20,228,251,108,217,178, 5,194,140, 14,199, 54, +174, 16, 12,214,207,161,246, 16,177, 61,114,229,248,184,107,215,174,168, 92,185,114,145,232,149, 90,173,246,248,166,225,121, 30, +241,241,241,184,120,241, 34,154, 54,109,138,156,156, 28,200, 24, 6, 31, 92,184,128,218,111,189, 5,139, 61, 34,163, 80, 40,240, +238,187,239,250,148,168,126,231,206,157, 32,199,199, 33, 33, 33, 9, 45, 90,180,136, 58,117,234, 84, 97,226,187,125,248,172,208, +104,248, 98, 94, 40,165,120,227,141, 55,138, 68,173, 28,205,149,227,178,103,207, 30,192,135, 33, 66, 74, 41, 90,180,104, 81, 24, +189,210,106,181,216,182,109, 27,128,130,215,170,101,203,150, 0,128,240,240,112,159, 52,133,243,176, 39,182,195,100, 50,241,122, +189,158, 57,125,250, 52, 20, 10, 69, 97,196, 78,173, 86, 67,165, 82, 65,169, 84,150,106, 70,208,127, 1, 74,121, 88,108, 54, 24, +141, 70,228,229, 21, 84, 8,185,117,113,115,145, 54, 86,115,233, 39,167, 9, 81, 42,189, 94,143, 95,127,253, 21, 91,183,110, 69, +195,134, 13,139, 37,185, 3,222, 35, 88,127,247,153,166, 17, 66,154,143, 27, 55,238,228,180,105,211, 34,203,149, 43, 7,171,213, +138,123,247,238, 97,213,170, 85,137,249,249,249,205, 41,165, 94, 47, 44,127, 11, 2, 54, 27, 11, 83,190, 25, 57,185,122,124, 58, +125,181,187,150, 12, 0,100,166, 94, 67,215,110, 61, 75, 93, 14,165,164,216,141,210,112,199,117,246,161, 58, 33, 28,159, 75, 41, +237, 95, 18, 77, 66, 72,235, 89,179,102,245,110,216,176,161, 54, 39, 39,231, 10, 0,188,243,206, 59, 56,115,230, 76, 91, 66,200, + 37, 74,233, 65, 66, 72,157, 6, 13, 26,180,125,231,157,119, 0, 0, 95,127,253, 53,118,237,218,245, 43,165,244,160,235,126,242, +133, 67,132,121,121, 70, 4,232, 34,240,224,206, 97,175,125,145, 75, 76,160,188,251,225, 66,193, 16,184,138, 90, 57, 94,159, 74, +240,254,161, 66,206,159,240, 69,221,233,141,183,208,105,248, 76,104,100,192,140,129,205, 80, 69, 7, 64, 93, 14,242,150, 19, 64, +116, 49, 5, 59, 14,223,233,147,254,248,229,203,113,230, 70, 65,133,151,232,208, 80,140,235,221, 27,212, 6, 28,191,124, 25,235, + 15, 30, 68,239,214,173,161, 81,169,124,210, 18,206, 93, 46,151,227,214,173, 91, 56,126,252, 56,106,214,172,137,155, 55,111, 22, + 41, 39, 65, 41,245,233,252, 41,165, 84,152,156,164, 84, 42, 33,147,201,144,156,156,140, 46, 93,186, 20,254,192, 63,124,248, 48, +198,141, 27,135, 65,131, 6,161, 85,171, 86, 46,243, 98,157, 53, 67, 67, 67, 11, 3, 7,206, 19, 16, 28,135,109, 75,242, 26,185, +210, 20, 40,237,235,238,168, 57,125,250,116,151, 19, 37,124,209,116,244, 34, 30, 56,141,162,209, 35, 8,249, 80,130, 33,114,126, + 12, 32, 72, 88, 55,113,226,196, 73,190,238,231,248, 88,136,128, 57,233,186, 69,106,111, 88,228,140,133, 47, 89, 33, 92,236, 10, + 63, 63, 63,140, 24, 49, 2, 83,166, 76, 65, 72, 72,136,215,220, 25,193,185,122, 98,231,206,226, 31,178,237,219,183,123, 27, 34, +188, 26, 24, 24,248, 66,155, 54,109,144,147,147,131,251,247,239,195,207,207, 15,181,231,205,195,133,225,195, 81,111,249,114, 48, +109,218,128,144,130, 34,169, 23, 46, 92,128, 90,173,190,234,177, 35, 78, 16, 66,160,213,106, 17, 20, 20, 84, 56,166, 46, 24, 45, +135, 8,150, 87,231, 70, 41,197,207, 63,255,236,242, 87, 98,105,114,176,132, 15,255,201,147, 39,139,228, 95, 57, 26,158,147, 39, + 79, 22, 70,176,132,221,188,245,211,254,171,142, 10,122, 26,141, 6,229,202,149,131, 82,169,132, 90,173, 46, 98,174,124,137,222, +121, 43, 36,170, 86,171, 79,249,249,249,233,132,237, 50,153, 12,122,189, 62, 59, 35, 35,163,177,183,190,254,155,225, 65,193, 90, + 89, 24,141, 38,228,233,203,190,150,164, 48,225,100,203,150, 45,120,241,197, 23,139,153, 43,225,185, 46, 41,148,210, 4, 66, 72, +171, 69,139, 22,253, 62,127,254,252,160,188,188, 60,124,251,237,183, 57,121,121,121,173, 28,242,136,124,211,226, 41,108, 86, 43, +242, 77,102, 24,242, 10,158,131,191, 46,109,246,178,215,147, 77,141, 26, 53, 6, 14, 27, 54, 44, 84,175,215,255,197,243,127,199, + 83,230,207,159,143,191,254,250,107, 32,128,131, 0,150, 79,159, 62,189,122,221,186,117, 43, 0,192,244,233,211,239, 3,112,157, +148,130,130,107,135,213, 62, 68,152,151, 87, 16,245, 48, 25,210,203,164,191,130,201,112,151,115, 85,154,161, 28, 98,159,185, 44, +145, 72, 48,114,228, 72, 92, 56,127, 30,109, 35,115, 81,165,188, 22, 52,247, 1,228,109, 62,193,185, 52, 53,230, 46,240, 57,165, +173,144, 13, 14,147,120,230,110,216,224,114,219, 95,175,122, 28, 93, 47, 68, 56,247,235,215,175, 67,173, 86,131,227,184, 98,223, + 55, 37, 61,127, 71,227,178, 96,193, 2,140, 27, 55, 14,171, 87,175,198,133, 11, 23, 80,175, 94, 61,180,107,215, 14,169,169,169, + 56,127,254, 60,204,102,179,207,253,116,204,139,187,126,251, 50,246, 31,223,141,248,132, 59, 72, 76,190, 95,162,254,185,211, 20, + 16, 94,247, 45,251,207,226,141, 88,143,165,243,220,106,126,242,201, 39, 72, 77, 77, 45, 18,185, 18, 12, 43, 0,183, 17, 44,103, + 47,226, 68,186, 83,174,147,240,216,226,100,118,156, 31, 59,183, 7,128, 84, 0, 18, 47,251, 57, 63, 78,143,139,139, 59, 36, 68, +190,236,186, 18,234, 38,255, 10,112, 83,104, 84,120, 50,132, 47,101,199,168,143,240,183,159,159, 31,180, 90, 45,180, 90, 45, 2, + 2, 2,188, 70,134, 4,131,213,226,182,190, 72, 46,151, 16,201, 2,128, 65,131, 6, 21,139, 96, 57, 22,228,116,133,217,108, 62, +124,248,240,225,250, 93,187,118,149, 92,189,122, 21, 18,137, 4, 60,207,195,210,180, 41,234, 45, 95,142,139,239,191,143,151,239, +222,133,201,106,133, 74,165,194,222,189,123,173,249,249,249,135, 61,118,182, 56,196,209, 96,249,249,249, 33, 48, 48,176,208, 96, +248,226,202,133, 15,173,167,252, 6, 97,113, 76,242,247,134,144,115, 38, 44,194, 23, 43, 33, 4, 70,163,177, 48, 89,211,177,189, + 39,132, 33, 66,199, 15, 30,195, 48,208,233,116,133, 23, 13, 33,130,229,107,244,206, 91, 33, 81,141, 70, 19,112,237,218,181,106, + 66, 25,137,244,244,116,180,105,211,230,134, 59,189, 39, 6, 30,176,178, 28,242,140, 38,228, 25, 61, 15, 49,148, 4,225,189,246, +253,247,223,227,214,173, 91,176, 90,173,136,139,139, 43,102,172, 74,146,228,238, 12,165,244, 86,131, 6, 13,248,142, 29, 59,226, +228,201,147, 80, 42,149, 54, 74,105,137,235, 87,241,148,135,149,101, 97, 50, 26,145,103, 48,120,223,225, 41,224,218,181,107, 57, + 90,173,246, 4, 0,255, 27, 55,110, 72,252,252,252, 80,181,106, 85,152, 76,166, 28, 0, 57, 64, 97,206,219,204,119,223,125,119, + 33, 0,216,108,182,153,158,114,218, 40,165,176,177,118,179, 94,134,207,163,240, 94,114,119, 77, 42, 77,185, 20,199, 47, 84,158, +231, 49,228,157,119,208, 46, 50, 23,221, 27,134,194,144,116, 3,154,192, 80, 16, 93, 37,204, 93,240, 51, 46,221,246, 57,213,146, + 2, 64,135,150,175,226,249,154,197,203,123, 53,111, 91,240, 91,236,216,175,167,144,146,158,232,115, 63,129,130,115, 55, 24, 12, +110, 35, 85,190, 70,176, 4, 77, 98, 47,151, 34,147,201, 80,191,126,125, 60,243,204, 51, 56,116,232, 16, 26, 52,104,128,155, 55, +111,226,230,205,155,184,123,247, 46, 46, 92,184,128,172, 44,111, 35,205,197, 95,163,109,251,214, 35, 75,159, 9,133, 92,129,204, +236,116,196, 63,184,131,240, 96,239,165, 88, 60,105, 58, 6, 82,106,188,242, 41, 0, 32, 50, 52,176, 68, 6,203, 81,115,206,156, + 57,197, 76,123, 25,148,222, 57,229,229,113, 73,247,127,228,184,188,250, 42, 20, 10, 99,185,114,229,212,142,227,167, 12,195, 32, + 48, 48,144,204,154, 53, 75,194, 48, 12,180, 90, 45, 2, 3, 3, 33,132, 5,189,161, 80, 40,140,149, 42, 85, 82, 11,111, 64,225, + 3, 24, 16, 16, 32,153, 53,107, 22, 89,185,114,165,203,253,118,238,220,233, 45, 7,107,126,255,254,253,255, 47, 33, 33, 33, 40, + 44, 44, 12, 73, 73, 73, 80, 40, 20, 5, 31,138,214,173,209,226,246,109, 88, 11,114,138,112,253,250,117,124,245,213, 87, 6,179, +217, 60,223,199,231,167, 16,127,127,127, 4, 7, 7, 23, 14, 13, 10, 17, 28, 7,179,232, 83,106,165,167, 80,188,240,139,175,164, + 56, 26, 44,225,139,117,232,208,161, 69,204,150,175,200,229,114, 86,168,212,206, 48, 12,172, 86, 43, 26, 52,104,128,212,212,212, +194, 15,139, 99,228,206, 23,131, 37,147,121, 46, 36, 42,149, 74, 97,177, 88,208,178,101, 75, 16, 66,176,120,241,226,167, 99,216, +145,231,137,191,127, 48, 34, 35,159, 69,104,152, 9,188, 47,201, 33, 62,194,178, 44,134, 13, 27, 86, 36, 98, 37,204, 84, 20,134, +248, 41,165,176,217,108,222,102, 63,185, 69,248, 92,251,242,249,118,171, 1, 20, 14,109, 25, 12,166, 82,235, 60, 46,162,163,163, + 3,236, 67,134,206,184,158,237,135,191, 75, 50, 16, 66,166, 37, 36, 36,212,173, 81,163, 6, 94,126,249,101,236,217,179,103, 59, +128,173, 14,237, 18, 8, 33, 75,132,191, 61,245,131,218,135, 90,141, 38, 51, 12,134,178,143,134,122,250,161, 87, 26,132,107,206, +148, 41, 31,163, 93, 68, 54, 94,171, 23,136,239,118,253,134,126,245,213,128,197,183, 2,185,142, 8,125, 9,142,170,140,202,207, + 53, 41,182, 93, 21, 88, 48, 52, 87,249,185, 38,144,220,191, 89, 34,109,231, 33, 54,231,235,101,105, 34,120,142,207,231,224,193, +131, 49, 97,194, 4,180,111,223, 30, 55,111,222,196,145, 35, 71,112,243,230, 77,140, 30, 61, 26,117,234,212, 65,189,122,245, 74, +164,185, 99,255, 38,228,230,229,128, 33, 12, 50,115, 50, 96, 50, 27, 49,126,152,215,250,196, 94,251, 41,112,103,127, 28, 0, 96, +243, 47,103, 74,173, 57,105,210, 36, 36, 39, 39, 23,137, 92, 61, 76,222,213,147,138, 75,131,149,145,145,225,114,188, 47, 52, 52, + 52, 37, 54, 54, 54, 44, 41, 41, 9,254,254,254, 94,205, 21, 33,164, 29,181,215,202, 72, 78, 78,118,169,169,213,106,173,177,177, +177,178,136,136,136, 34,179, 7,253,252,252, 10,219, 56,221, 10,164, 80, 19, 0, 40,165,122, 66,200,144,102,205,154,125,183,103, +207, 30,205, 51,207, 60,131,220,220, 92, 80, 74,177,122,245,106,140, 28, 57, 18, 42,149, 10,215,175, 95, 71,183,110,221,242,243, +243,243,135, 80,135, 26, 88,174, 52, 93,156, 7, 24,134, 41,172, 98,239,194, 92,121, 60,119, 65, 3, 0, 22, 45, 90,132, 25, 51, +102, 96,210,164, 73,110,247, 5,128, 21, 43, 86, 0, 78,195,121,174, 52, 41,165,152, 59,119,110,153,105,102,100,100,172,118,220, +238,231,231,183,184,123,247,238,210,251,247,239, 23, 49, 85,142,139,139, 11, 82, 17, 77,111,133, 68, 37, 18, 9,194,195,195, 49, +109,218, 52, 4, 7, 7,163,124,249,242,197, 34, 47,222, 94,163,210,240,168, 53, 57,202,159,158, 51,243,227,230,223,174,221, 33, + 83, 42,128, 19, 71, 54, 35, 55, 43,185, 72,123,179,245,239, 41,209,138, 6,109, 97, 57,243,171, 79,253, 52,155,205,152, 61,123, + 54, 62,253,244, 83,124,250,233,167, 30,251,100,127,221,189,106,122,194, 23,147,229, 82,147,167, 68,227, 23, 4,149, 95, 36,106, +215, 9, 2, 95,194, 90,157,143,233,117,231, 19, 19, 19, 17, 25, 25,137,155, 55,111, 62, 39,145, 72,138, 56, 2,142,227,204, 42, +149,170,200,108, 63, 55,154, 23,183,108,217, 82,119,242,228,201,152, 49, 99, 6, 0, 12, 56,124,248,112, 31, 66,136,224, 52,221, +154, 52,103, 77,158, 82,162,214,232,160,242,139, 64,237,231,116,224,249,210,213, 60,117,117, 13, 17, 70, 43, 28,163, 87, 37, 44, + 36,237,242, 90, 7, 0,127,252,186, 29, 83,222,127, 14,171,127,250, 29, 95,156, 2,158,215,165,162,118,104, 26,248,180,171,248, +176,223, 11,152,251,195,159, 0,128, 35,135, 61,107,162, 32,205,199,109, 31, 76, 70,143, 55,189,112,219, 79,231,145, 26,225,154, +234,216,198, 83, 4,203,149,166,240,227, 80,175,215, 35, 59, 59, 27,223,125,247, 29, 6, 14, 28,136,212,212, 84,220,189,123, 23, + 55,110,220,192,143, 63,254, 88, 56, 59,189, 36,253,148,201,100,248,224,157,143, 48,121,238, 88, 80, 80,212,168, 86, 27, 19,135, +127,138, 70,207, 55, 45,245,185, 59, 71,176, 4,188, 69,175, 60,105, 46, 90,180,168, 84,239,165,167,141, 18,141, 31, 8,145,172, +144,144,144,194, 55,135,227, 27,175, 52,191,116, 37, 18, 9, 88,150, 45,204,237, 17, 22, 0,232,218,181, 43,118,238,220,233,203, +204,136, 61,132,144, 55,107,213,170,181,234,179,207, 62,243,127,249,229,151,165,145,145,145,104,212,168, 17,174, 95,191,142,159, +126,250,201,182,116,233, 82, 67,126,126,254, 32, 74,233, 47, 37,238, 36, 64,132, 91,207, 56, 46, 69, 26,120,233,163,213,106,189, +127,243,230,205,136,185,115,231, 74, 24,134,193,194,133, 11, 11, 63,140, 66,161, 86, 71,142, 28, 57,194,242, 60,239,113, 72,198, +102,179,221,191,121,243,102,196,188,121,243, 36,132,144, 66, 77,134, 97, 10, 53, 29,251,229,139,102,177, 19,183, 95, 96,220,153, + 43, 87,125,119,198, 91, 33, 81,169, 84,138,235,215,175, 99,202,148, 41, 32,132, 96,243,230,167, 35, 71,231,194,213,244,149,245, +106,135, 5,117,237,212,188, 46, 8,129,213, 82,124, 4,200, 63,171, 32,249, 93,209,160, 45,186,207, 91,143,173, 31,244,246,170, + 75, 41,189,117,236,216,177,114,179,103,207,150, 74, 36, 18, 44, 88,176,160, 72,177, 95,231,215,253,232,209,163,108,105,134,247, +132,207,179,213,106,133,209, 88,186,168, 9,165,244,120,220,244,201,177,107,190,255, 89, 70,136, 5, 39, 14,111, 70, 78,182,235, +169,233, 10,153, 20, 43,191,219,194,202,101,146,210, 37,149,148, 29, 95,244,232,209, 99,242,166, 77,155,164, 0, 46,121,109,237, +158,237,223,124,243, 77,167,158, 61,123,150,171, 94,189, 58,190,253,246, 91,185, 78,167,107, 72, 8, 33,174, 76,154, 39, 40,165, +219,103, 78,159,252,246,119, 63,252,172, 96,136, 21, 39,142,108, 70,142,147, 89,119, 70, 46,151,225,155,213, 91,172,114,185,236, +154,167,118,194,205,220,203, 34,114,229, 76,183,254,195,209,125,209, 23,168,218,168, 3,102,206,106,135,111,166,247,196,252,142, +114, 88, 55,246,195,243, 61,214, 96,221,212,206, 0,128,200,111,124,211,147, 73,229,184,231, 34, 66,149,157, 83,144,216,174,215, +151, 44, 74, 42,156, 59,224,254, 26, 94,210, 8, 22,195, 48,168, 92,185, 50,170, 86,173,138,102,205,154,161, 65,131, 6,104,221, +186, 53,206,159, 63,143,243,231,207, 99,244,232,209,110,205,149,183,126,202,100, 50,180,122, 41, 22,191,183,240,248,146,150, 88, +179,180, 81,110,111,154,174,222, 75,195,134, 13, 3,128,255, 68, 52,171,196, 6,203,113,198,193,195, 12, 29, 56,106, 90, 44,150, +194,161, 55,199,186, 74, 66,210,187,143, 51,244,126, 33,132,212,249,248,227,143,223, 87,169, 84,173,243,243,243,159, 5, 0, 63, + 63,191,235,102,179,249,160,209,104, 92, 64, 41,205,126,152,190, 58,150,101,112,213, 5, 79,251,102,101,101,117,232,208,161,195, + 47, 82,169,180,178,227, 7,214, 49,241,207, 17,158,231,239,166,164,164,120,156,170,158,145,145,209,161,125,251,246, 46, 53, 29, +255, 47,137,166, 51,194,236, 79,119,230,202,213,113,156,241, 86, 72, 84, 42,149,194,207,207, 15,219,182,109, 67, 72, 72, 72, 73, +186,247,175,231,220,229,212,217,158,182,183, 10, 81, 30, 6, 16,218,125,222,250,123,135,210, 45, 49,173, 66, 20,241, 91, 63,236, + 83,209,211, 62,233,233,233,237, 7, 14, 28,184, 91, 42,149, 86, 6,138, 62,255,174, 94, 11,150,101,239, 36, 39, 39,151,184,236, + 1,165, 20,215,174, 93,227, 7, 15, 30,156,158,150,150,214,179,164,251, 3,192,196, 41, 95,204,159,241,217,200,224,142,177, 77, + 26,129, 1, 44,238,147,122, 41, 1,168, 84, 38,185, 63,110,210,194,119, 74,115,172,178,130, 82,122,134, 16, 50,173, 81,163, 70, +163,225,182, 46, 56,188,150,169,160,148, 90, 9, 33,243, 59,117,234,244,225,168, 81,163,116,237,219,183,183, 70, 69, 69,157,118, +140,206,251,202,185,203, 41,239,214,171, 21, 26,221,177,221,139, 29, 64, 8,181, 88, 60, 39, 71, 19, 2, 10, 74,169, 92, 46,187, +118,234, 92,226,243,238,219, 21,185, 99, 70,153, 15,205,143, 24, 49, 2, 35, 70,140, 0, 80,240,126, 90,188,184, 5, 54, 93, 60, +134, 30,207, 39,192,252, 85,115,144, 0,143,111,245, 34,253, 4,128,143, 62, 30, 92,102,125,115, 60,119,161,127,101,145,131, 37, +145, 72,144,158,158,142,235,215,175, 35, 37, 37, 5,249,249,249,184,114,229, 10,172, 86, 43,178,178,178,240,220,115,207,149,186, +159,101,245, 26, 61, 78,205,255,130,177, 18, 40,145,193, 98, 89, 54,193,219, 93,207,109, 54, 91,137,102, 25,201,100, 50,211, 51, +207, 60, 67, 92,205, 54, 16,254,246,243,243,243,233,231,179,221, 64, 77, 1, 48,133,216, 63, 17,153,153,153, 15,237, 2, 57,142, + 75,140,137,137,145,184, 51, 46, 0,192,178,172,199,138,113,148, 82, 3, 0,207,113,220, 18,242, 40, 52,157,145,201,100,134,154, + 53,107, 22,230,114, 57,215, 52, 33,132, 64,173, 86,123,204,186,245, 86, 72,212, 96, 48, 36,117,232,208,129,115,220,238, 88,136, +244,169,134,208,248,206,125,254, 47,230, 80,186, 37, 6, 0, 4,147, 5, 74,227,221,237, 66, 41, 53, 2,120,249, 81,119,237,246, +237,219,150, 23, 95,124,241,123,189, 94, 63,156, 82, 90,234, 44,253, 73,159, 44,246, 60,118,253, 47,132, 82,122, 6,192,219,101, +160,115,145, 16, 50,116,246,236,217, 61,103,207,158, 93, 13, 64, 8, 0,161,142,128, 87,147,230,200,185, 43,105,101, 94, 27,140, +101,217,132,170, 85,171, 2,240, 61, 82,227,237, 26,111,179,217, 60,126, 79, 92, 66, 32, 38,157, 4, 10,110,227,150,225,147,166, +201,100,202,108,218,180,105,137,194, 44, 44,203,122,188,134, 56,158,123, 68, 68, 4, 34, 35, 35, 11,255, 23,112, 94,239,173,159, + 44,203, 38, 68, 71, 71, 35, 36, 36,196,109,133,118,231,156, 43, 95, 52,203,250, 53,242,164, 25, 25,185,198,213, 46,143,165,159, + 79, 58, 37, 50, 88,194, 61, 6,203,146,148,148,148, 71,114,111, 20,143, 3,246, 37, 36, 35, 35,163, 81, 89,105, 61,105,100,100, +100, 4,123,111,229, 25,111,133, 68, 83, 82, 82, 60, 22, 34,125,154, 57,148,102, 25, 80,108,157,221,108, 61,110, 12, 6, 67, 69, + 74,105,169, 50,243,123,244,232, 81,118, 25,253, 79, 56,118, 67,188,250,113,247,195, 21,233,233,233,101,126, 77,127, 20,223, 19, +153,153,153,117,203, 90,243, 73, 57,247, 71,209,207, 39, 69,243, 73,231,191,155,125, 38, 34, 34,226,145,210,154, 43, 17, 17, 17, + 17,145,130, 25,101,237, 92,109, 40,201,204, 29, 66,136, 75, 13, 79,120,211, 23, 53, 69, 77, 81, 83,212, 20, 53, 69, 77, 81,243, +233,211,244,166, 93,214, 51,135, 31, 27, 66,189,156, 71,177, 0,104, 39,106,138,154,162,166,168, 41,106,138,154,162,166,168,249, + 95, 91,196, 33, 66, 17, 17, 17, 17, 17, 17, 17,145, 50, 70, 52, 88, 34, 34, 34, 34, 34, 34, 34, 34,101,140,104,176, 68, 68, 68, + 68, 68, 68, 68, 68,202, 24,209, 96,137,136,136,136,136,136,136,136,148, 49,162,193, 18, 17, 17, 17, 17, 17, 17, 17, 41, 99,136, +125, 54,128,136,136,136,136,136,136,136,136, 72, 25, 33, 5, 0, 66, 72,161,203,162,148,150,236,206,150, 34, 34, 34, 34, 34, 34, + 34, 34, 15,201,211,230, 69, 10,111,149,243, 52,156,140,136,136,136,136,136,136,200,147,203,211,228, 69, 10,115,176, 28,157,163, +136,136,136,136,136,136,136,200, 63,205,211,228, 69, 10, 13,214,211,228, 26, 69, 68, 68, 68, 68, 68, 68,158, 60,158, 38, 47, 82, + 36,130,245, 52, 57, 71, 17, 17, 17, 17, 17, 17,145, 39,139,167,201,139,136,179, 8, 69, 68, 68, 68, 68, 68, 68, 68,202, 24,177, + 14,150,136,136,136,136,136,136,136, 72, 25,243, 72, 13, 22, 33,164,157,168, 41,106,138,154,162,166,168, 41,106,138,154,162,230, +127, 13, 49,130, 37, 34, 34, 34, 34, 34, 34, 34, 82,198,136, 6, 75, 68, 68, 68, 68, 68, 68, 68,164,140, 17, 13,150,136,136,136, +136,136,136,136, 72, 25, 35, 26, 44, 17, 17, 17, 17, 17, 17, 17,145, 50, 70, 52, 88, 34, 34, 34, 34, 34, 34, 34, 34,101, 12, 1, +224,114, 38, 0,165,116,191,207, 34,165,152, 77,224, 77, 95,212, 20, 53, 69, 77, 81, 83,212, 20, 53, 69,205,167, 79,211,155,118, + 73,252,199,191, 26, 74,233, 35, 91, 0,180, 19, 53, 69, 77, 81, 83,212, 20, 53, 69, 77, 81, 83,212,252,175, 45,226, 16,161,136, + 71, 8, 33, 82, 66,136,180,180,219,255, 41, 77, 17, 17, 17, 17, 17,145,127, 19, 46,191,196, 8, 33,213, 1, 76, 2, 16,232,176, +250, 20,165, 52,206,169,221, 15, 0, 52, 14,171, 12, 0,166, 82, 74,111,250,112,108,185, 93, 95,105, 95,120, 0, 38, 0,102, 0, +122, 0, 54, 31,207, 65,228, 17, 65, 8,105, 10,160,139,253,239, 93,148,210, 19, 37,217,254, 79,105,254, 83, 68, 70, 70,170,131, +130,130,218,159, 57,115, 70,113,229,202, 21, 28, 61,122,148,174, 92,185,210,154,149,149,181, 47, 49, 49,209,248,184,251, 39,242, +240, 16, 66, 58, 0,152,104,127, 56,147, 82,186,247, 33,245,136, 70,163, 25,237,231,231,215, 89,169, 84, 70,178, 44, 75,242,243, +243, 19, 13, 6,195, 47, 44,203,206,163,148,242,165,208,108, 20, 18, 18, 50,180, 78,157, 58,207,220,190,125,251,254,189,123,247, +214, 2,216, 11,160, 67,197,138, 21,251, 87,169, 82,165,194,165, 75,151,110,164,167,167, 47,167,148,254,241,184,250, 41, 34,242, + 95,199, 93,148, 96, 10,165,180,159,227, 10, 66,138,223,224,186, 77,155, 54,221,246,237,219,167,225,121, 30,194,162, 86,171, 89, + 0, 3,188, 28, 55,248,248,241,227, 49,195,135, 15,239,158,152,152,248,130, 94,175,111, 12, 0, 26,141,230,247,176,176,176, 63, + 22, 45, 90,244, 99,251,246,237, 19, 80, 96,180,124,134, 16, 34,149,201,100, 3,131,130,130, 58,179, 44,219,128, 82, 10,153, 76, +118, 38, 43, 43,107,175,205,102,251,134, 82, 90, 98,211, 70, 8, 81, 72,165,210, 17, 74,165,178, 3,203,178,117, 1, 64, 42,149, + 94, 48,155,205,123, 89,150, 93, 66, 41,181,148, 66, 83,165, 80, 40, 70, 4, 4, 4,196, 90, 44,150,186, 0,160, 80, 40, 46,228, +230,230,254, 98,177, 88,150, 80, 74, 77, 37,213, 44,107,236, 17,164, 46,148, 82, 25, 0, 72, 36,146, 87,155, 54,109, 26, 67, 8, +225, 9, 33,148, 82, 74, 24,134,169,207,113, 28, 99,111,223,133, 16,242, 7,165,148, 45,137,230,139, 47,190, 88, 65,179,144, 17, + 60, 0, 0, 32, 0, 73, 68, 65, 84, 42,149, 82, 74, 41,161,148, 50, 12,195, 60, 95, 18,205,178, 34, 52, 52,116, 6,207,243,145, +158,218, 4, 6, 6,190,112,230,204,153, 26, 27, 54,108,224,190,250,234,171,236, 65,131, 6,249, 15, 31, 62, 92,186,120,241,226, + 37, 0,198, 56,183, 15, 9, 9,153,207, 48, 76,136, 47,199,231,121, 62, 61, 61, 61,125,108, 41,187, 47, 82,118, 76, 92,186, 95, +223,146, 82, 96, 68,172,150, 65,129,113, 41, 53, 81, 81, 81,223,189,253,246,219,125,234,214,173, 43,165,148,194,102,179,193,108, + 54,215, 56,113,226, 68,171,205,155, 55,191, 0,160,103, 73,244, 8, 33, 93, 38, 78,156,248,245,212,169, 83, 67,101, 50, 25,177, +217,108, 77, 54,108,216,208,113,232,208,161,231,150, 47, 95, 94,175, 87,175, 94, 90, 97,253, 39,159,124,210,137, 16,242, 62,165, +244,199,127,186,159, 34, 34, 34,238, 13,150, 31, 0, 16, 66, 82, 0,156,178,175, 59,229,220,232,192,129, 3, 59,164, 82,169, 16, +193,106,108, 48, 24,194, 81, 52,234,229,138, 74,253,251,247,111,186,105,211,166, 25,189,122,245, 74,214,104, 52,207,188,254,250, +235,122, 66,136,100,195,134, 13,245,171, 86,173,170,238,218,181,107,255, 54,109,218,124,176,123,247,238,163, 0,210,124, 57, 17, + 66, 72,237,114,229,202,109,153, 61,123,118, 76,135, 14, 29,228, 33, 33, 33,160,148, 34, 49, 49, 49,234,167,159,126,234,248,217, +103,159,125, 64, 8,121,141, 82,122,217, 23, 61,187,102, 35,181, 90,189,233,179,207, 62,139,232,216,177,163,180,124,249,242, 48, +153, 76,184,114,229, 74,187,189,123,247,182, 92,177, 98,197, 24, 66, 72, 15, 95,127, 37,218, 53, 27, 7, 6, 6,110,254,118,194, +132,240, 38, 3, 7, 74,203,149, 43, 7, 74, 41,210,210,210,218, 29, 91,179,166,213,176,217,179,199, 16, 66,222,160,148, 22,123, +190, 31, 39, 10,133,130, 89,187,118,109, 61,133, 66, 1, 0,176, 88, 44,168, 83,167, 78,113,215, 93, 2,100, 50, 25, 51,111,222, +188, 6, 82,169, 20, 86,171,149,215,235,245,244,245,215, 95,127, 44,195,214,132,144,232,196,196,196, 64,185, 92,238,114, 59,199, +113,104,217,178,101,101,185, 92,142,121,243,230,217,210,211,211,235,127,249,229,151,103,214,173, 91, 23,178,100,201,146, 30,112, + 97,176, 24,134, 9, 73, 72, 72,112,169,201,113, 28,172, 86, 43, 88,150,133,197, 98, 65,173, 90,181,202,252,156, 68, 74, 69, 12, + 0,252,124,222, 4, 0,229, 30, 86,204,207,207,175,102,223,190,125,165,105,105,105,144,201,100,176, 90,173, 72, 78, 78, 70,157, + 58,117, 36,223,127,255,253,179, 37,213,171, 81,163,198,208,184,184,184,176,159,127,254,217,250,253,247,223,155,219,181,107, 39, + 31, 52,104, 80, 64,203,150, 45, 91, 68, 71, 71, 51,171, 86,173, 50,239,223,191,223,250,230,155,111, 42,103,204,152, 17,182,123, +247,238, 62, 0,188, 26,172,178,238,167,136,136,136,123,131, 37,112,138, 82,250, 42, 0,200,229,242,250, 21, 42, 84,248,142,101, +217,242, 0, 32,149, 74,147,101, 50,217, 60,171,213,122, 22, 0, 8, 33,219,121,158,239,230, 69, 47,184,127,255,254, 77,119,239, +222, 61,247,196,137, 19, 57, 25, 25, 25,229,119,236,216, 97,250,224,131, 15,238, 2,192,237,219,183,171,116,237,218, 53,106,228, +200,145, 9,237,219,183, 95,212,186,117,235, 81, 7, 15, 30,252, 5, 5, 67,143,110, 33,132,212,174, 83,167,206,241, 35, 71,142, +104,117, 58, 93,145,109,149, 42, 85,194,168, 81,163,228,221,186,117,171,218,182,109,219,223, 8, 33, 45, 40,165, 23,189,244, 19, +132,144,198,213,171, 87,223,127,224,192, 1,255,160,160, 32,100,103,103, 35, 57, 57, 25,249,249,249, 8, 8, 8, 64,175, 94,189, +228, 47, 55,111, 86, 97,228,232, 49,251, 9, 33,237,124, 49, 89,132,144,198,205,106,215,222,191, 46, 46,206,223,118,239, 30,212, +106, 53,242,242,242, 0, 0, 90,173, 22, 47, 84,174, 44,253,115,205,154,168,126,227,199, 11,154,255,184,201, 34,132, 40, 1,128, + 82,106, 38,132,236,146, 72, 36,175, 42, 20, 10,230,213, 87, 95,197,254,253,251,137,201,100,146, 2,128, 74,165, 98, 95,125,245, + 85,168,213,106, 88, 44, 22, 30,192, 46,119,145, 38, 87,154, 50,153,140,105,221,186,117,254,169, 83,167, 50, 5, 77,141, 70, 99, +107,221,186,117,176, 66,161, 80,179, 44, 75, 61,105, 62, 10, 20, 10, 5,110,221,186, 85,100,157, 94,175, 71, 90, 90, 26, 50, 50, + 50, 96, 54,155,145,157,157, 13,158,231,137, 90,173, 78,227,121, 30, 12, 83, 16,108,115,167, 41,151,203,113,253,250,245, 34,235, + 88,150,133,193, 96,128,217,108,134,213,106,133, 94,175, 87,107,181,218,234,181,107,215, 78, 0,176, 61, 51, 51,115, 94,114,114, +114,124, 89,159,159,136, 79,220,219,117,214, 84, 17,128, 5,192,157, 50,208,227, 1,224,232,209,163, 72, 73, 73, 65,122,122, 58, +210,210,210, 16, 29, 29,141,210, 12,187, 93,187,118,109, 81,253,250,245,201,185,115,231,118, 2,248,122,253,250,245,221, 51, 51, + 51,151,141, 27, 55,174,220,156, 57,115, 50,199,143, 31, 63, 12,192,214,245,235,215, 15,172, 91,183,110,215, 11, 23, 46, 44,124, + 28,253, 20, 17,121, 4, 52, 2, 16,106,255, 59, 29, 5,215,221, 96,135,199,231, 81,240,185, 21,218, 89, 0, 40, 92,252, 47, 32, + 60, 78, 3,240,135,195,126,194,227,135, 70, 24,138,161,194,226,170, 81,120,120,248,232, 54,109,218,204, 61,125,250,116,173,164, +164,164,160,164,164,164,160,211,167, 79,215,106,211,166,205,220,240,240,240,209, 66, 59,251,204, 2, 56, 60,118,156,106, 41, 63, +126,252,120,204,150, 45, 91,102,238,223,191, 63,167,126,253,250,150, 3, 7, 14,176,237,219,183, 79, 5,192, 2, 96,219,183,111, +159,122,240,224, 65,174, 73,147, 38,234,221,187,119,223,255,237,183,223,230,111,218,180, 41, 28,128,196,141, 38, 8, 33, 50,157, + 78,183,237,240,225,195,197,204,149, 35, 21, 42, 84,192,174, 93,187, 2,116, 58,221,118, 66, 72,145,144,130, 11, 77,149, 74,165, +218,124,240,224, 65,127,173, 86,139,212,212, 84,200,100, 50,132,133,133, 33, 39, 39, 7,201, 73, 73,136,191,113, 3,140,197,130, + 5,211, 63,215,170,213,234, 77,132, 16,133, 55,205,192,192,192,205,235,102,204,240,207,216,191, 31,231,166, 77,131,213,106, 45, + 28, 90,181, 90,173,248,109,248,112,164,253,250, 43, 86, 77,153,226, 31, 24, 24,184,153, 16,162,242,164, 89, 22, 56,106, 18, 66, +134, 3,200, 4,144, 73, 8, 25, 78, 41, 61, 81,167, 78,157,211, 87,174, 92, 65,139, 22, 45,176,113,227,198,231,199,141, 27, 55, +124,220,184,113,195, 55,110,220,248,124,139, 22, 45,112,229,202, 21,212,169, 83,231,180, 99,174,148, 47,154,135, 15, 31, 70,155, + 54,109,178, 54,110,220, 88,101,202,148, 41, 51,166, 76,153, 50, 99,253,250,245, 85,219,180,105,147,181,112,225, 66,179, 39,205, + 71,113,238, 2, 28,199, 21, 89,120,254,239,239,150,200,200,200,212, 45, 91,182,160, 87,175, 94,140, 66,161, 72,234,221,187,183, +242,216,177, 99, 20,192,174,146,244,211,100, 50,193,104, 52,194, 96, 48,224,246,237,219,234,217,179,103, 55,255,244,211, 79,171, +237,223,191, 63,106,210,164, 73,195, 66, 67, 67,207,148, 47, 95, 62,166, 36,154, 37, 69,212,116, 75, 50, 0, 43, 10,126,212,197, + 63,140,102,219,182,109,159,171, 86,173, 90,248,134, 75, 65,200,146,215, 0, 47,215,129,151,235,192, 5, 55,194, 45, 69, 39, 84, +172, 88, 49, 92,171,213, 54, 45,137, 38,165,244,151,179,103,207,118,162,148, 46,167,148,114,148,210, 77,227,199,143, 31, 76, 8, +217, 60,126,252,248,119, 41,165,155,236,235, 87,158, 63,127,190, 43,165,244,224,227,232,231,195, 34,106,254, 55, 53,189,120,145, + 80, 66,200, 46, 66,200,174,255,253,239,127,173, 1, 4, 59, 61,126,201,177, 29, 0,133,171,255,133,197, 97,125, 40,128, 87, 28, +246, 11,117,113,236, 82, 81, 56, 28, 99,207,129, 17,126,137,159, 34,132,236, 0,112, 74, 46,151,215,175, 87,175,222,171,123,246, +236,209,134,134,254,125,220,208,208, 80,108,218,180, 73, 91,187,118,237, 87,229,114,121,125, 0,167, 2, 2, 2,118,192,197, 80, +162, 29,221,240,225,195,187,191,245,214, 91,185,245,235,215, 7,128,236,203,151, 47,107,154, 52,105, 98, 96, 89,150,176, 44, 75, +154, 52,105, 98,184,124,249,178,198,102,179,233, 27, 53,106,228,215,182,109,219,187, 99,199,142,237, 15, 64,229, 70, 19, 0,250, +206,154, 53, 43, 58, 40, 40,200,109, 3, 74, 41,244,122, 61,194,195,195, 49,124,248,240,242, 50,153,236,255, 60, 61, 41, 82,169, +116,196,172, 89,179,194,116, 58, 29,178,178,178, 16, 29, 29, 13,139,197,130,235,215,175,195,100,200,131, 77,159, 11, 91,110, 54, +210,254,186, 9,157, 76,138,254,221,186,132, 75,165,210, 17,158, 52, 21, 10,197,136,111,198,143, 15,183,220,189,139,219, 27, 55, +130, 99,139, 7,102, 88,171, 21, 23,190,254, 26,166,132, 4,204, 28, 60, 56, 92,161, 80,120,212, 44, 75,236, 81,166, 57,148, 82, + 53,165, 84, 77, 8, 89,244,210, 75, 47,125,175, 86,171,135,199,197,197,117,216,183,111, 95,199, 35, 71,142,180, 98, 89, 86,198, +178,172,236,232,209,163, 45, 76, 38,147, 84,169, 84, 66, 42,149,186, 52,230,174, 52,155, 54,109,250,157, 90,173, 30,182,108,217, +178, 14, 7, 15, 30,236,255,231,159,127,142,224, 56, 78,193,113,156,226,207, 63,255,124,215,104, 52,202, 40,165,156, 59,205,127, + 26,153, 76, 6,185, 92, 14,181, 90,141,230,205,155,255,181,114,229, 74, 91,116,116,180,108,243,230,205, 65,145,145,145,126,139, + 23, 47,206,214,235,245,179,124,213,179, 90,173, 48,155,205, 48, 26,141, 48,153, 76, 56,112,224, 64,229,145, 35, 71, 74, 77, 38, + 19,215,181,107,215, 76,155,205,102, 30, 63,126,124, 64,185,114,229, 62,120,148,231, 37,226, 22, 22, 64, 30, 10, 12,150, 89, 88, + 73, 8, 81, 18, 66,234, 10,209, 88, 95,200,206,206, 94,241,205, 55,223, 68, 51, 74, 29,142, 89, 58,227, 71,254, 51,236, 11, 92, +140,212,152, 15, 17, 22, 93, 13,125,250,244, 9,163,148, 46,126,216, 14, 83, 74,183, 83, 74,123, 80, 74,183,148,102,255, 71,221, + 79, 66, 72,140,191,191,255,198,128,128,128, 99,254,254,254, 27, 9, 33, 49,165,213, 18,104, 95,157,180,123,181,150, 36,161,125, + 53, 66, 95,173, 37, 73,104, 95,189,228,181,154, 68,254,157, 56,121, 17, 71,210, 40,165, 93, 40,165, 93,102,206,156, 57,195,161, +189,240, 88,237,163,126, 23, 74,105, 23,199,117,118, 99, 85,230, 20, 14, 17, 10,137,203,246, 14, 20,206, 22,172, 80,161,194,119, +223,125,247,157,214,121,199,164,164, 36,228,230,230, 98,242,228,201,218,183,222,122,107,204,253,251,247,223,246,114, 44, 69,114, +114,114,131,126,253,250,169,172, 86,107, 22,207,243, 76,110,110,174, 52, 48, 48,144, 19, 26, 4, 6, 6,114, 57, 57, 57, 50,131, +193, 32,225, 56,206,252,214, 91,111, 41, 6, 15, 30,252, 2, 28, 34, 88,206,132,134,134,198,118,238,220, 89,225,110,187,205,102, +131,193, 96,128,193, 96,128,213,106, 69,243,230,205,149, 43, 87,174,108, 15, 96,153,187,125,148, 74,101,108,108,108,172, 44, 51, + 51, 19,129,129,129,136,143,143,199,157, 59,119, 96,206,203,131, 53, 47, 23,214, 60, 61, 88,125, 46,104,110, 14, 50,110, 94, 67, +147,154, 53,228, 63, 40,149, 29, 0,204,119,167, 25, 16, 16, 16,219,100,192, 0,169,159,159, 31, 90,245, 43,152, 63,176,187,102, + 77, 80,142, 3,207,113,224, 88, 22, 29,174, 95,135,205,102, 3,195, 48,104,148,153, 41, 13, 88,179, 38, 22,192, 92,143,207,234, + 35, 66,169, 84, 74,215,174, 93,219, 87,161, 80,128, 82, 74, 44, 22, 11,246,237,219,247,208,154,107,214,172,233, 47,104, 90,173, + 86,250,220,115,207, 21,251, 32,153,205,230,127,133,185, 2, 10,134, 13, 85, 42, 21,172, 86, 43, 42, 85,170,100,236,215,175,223, +241,233,211,167, 87,100, 24,198, 79, 46,151,239,201,200,200,152,145,152,152,120,219, 87, 61,155,205, 6,139,197, 2,139,197, 2, +163,209,136,191,254,250,171,124,229,202,149,201,240,225,195,185,252,252,252, 42, 95,124,241,197,173,125,251,246,105,102,205,154, +245, 58,128, 81,143,240,212, 68,156,176, 71,161, 3, 43, 6, 75, 13, 50, 9,242, 0,104,237,102,224,117, 66, 72,147, 90,181,106, + 5, 93,185,114, 37,139, 16,114, 18,192,143,148,210, 36, 79,122, 60,207, 19,158,231,241,110,227,108, 12,111, 42,129,205,150,131, +156,156, 28,196,199,199,227,242,229,203,248,253,119,159,211, 65,139,160, 82,169,254,207,223,223,191,189, 74,165,170,196,178, 44, +147,151,151, 23,159,159,159,191,159,231,249, 21,212,121, 24,193, 7, 30, 85, 63, 5,252,252,252,102, 79,154, 52,169, 89, 96, 96, + 32,206,158, 61, 91,101,253,250,245,179,241,144, 73,243, 42, 25,179,106,254,194,197, 81, 81, 97, 58,156, 63,178, 51,106,198,242, + 13,171, 0, 68, 63, 84, 71, 69,254, 21, 56,122, 17, 39,254, 0,240,138,125,118,121, 23, 23,219,125,213,127,168,253, 75, 66,161, +193,114,115, 66, 96, 89,182,188, 99,228,138, 82,138,164,164, 36, 60,120,240, 0,105,105,105, 8, 10, 10,130,213,106, 45,239,195, +177,148,122,189,190,113,112,112,112,190, 76, 38, 51, 27,141, 70,104, 52, 26, 94, 38,147, 81,251,113,136,125, 22, 34,103, 54,155, +137, 84, 42,181,105,181, 90,127,179,217, 92, 3, 30,114,197, 40,165,141,131,131,131, 93,110, 51,155,205,200,203,203,131,193, 96, + 64, 94, 94, 30,204,102, 51,194,195,195,193,178,108, 3, 79, 29,101, 89,182,110,104,104, 40, 18, 19, 19,161, 86,171,145,144,144, + 0, 75,158, 30, 86,189, 30,172, 33, 23, 92, 78, 14,248,220, 92,240,134, 92,216, 44,249,136,122,166, 38,132, 25,134,238,176, 88, + 44,117,131,131,131, 97, 48,252,157, 78, 70,237,198,138,101, 89,176,246,164,103, 97,216, 48, 36, 36, 4,194, 12,195,127, 2,123, +126,212, 56,134, 97, 22, 41,149, 74,233,176, 97,195,144,148,148, 84,228, 61, 49,108,216,176,194,156,171,150, 45, 91, 30, 85,169, + 84,108, 90, 90, 26,204,102,179,204, 23,205, 74,149, 42,197, 79,158, 60,249,148,197, 98,137,142,140,140,212,153,205,102,227,179, +207, 62, 27,169, 86,171,195, 45, 22, 11,247,194, 11, 47,172, 80,171,213,182,188,188, 60,202,178,236, 67, 37,208,151, 21,132, 16, + 16, 66, 10, 94, 35,150, 69, 72, 72,136, 33, 61, 61,253,247,172,172,172,190,165,209,179,217,108,194, 12, 45, 24,141, 70, 80, 74, +113,246,236, 89,168, 84, 42, 25,199,113,151, 88,150,213,200,100, 50, 48,246,228, 46,145,127, 6, 66, 72,171, 26, 58,197,252,184, + 38, 97,186,122, 93,253, 12, 26,133,196,192,199,215,171,244,237,156,203,235,223,234,255,127,218,169, 83,167,198,132,132,132,168, +110,221,186,101,250,252,243,207, 43,175, 93,187,150,192,203,143,159,251,247,239,111,158, 52,105, 82,185,206,157, 59, 87, 81, 42, +149, 36, 39, 39, 7,105,105,105, 72, 73, 73,193,157, 59,119,232,249,243,231,255, 50,155,205, 27, 75,210,207,200,200,200,149, 35, + 71,142,124,171, 97,195,134, 50,160, 32, 34,106, 48, 24,234, 31, 62,124,184,219,238,221,187, 91, 0, 40,241,251,242,254,253,251, + 27, 63,250,232, 35,191, 78,157, 58,213, 80, 42,149, 76, 89,244,211, 17,134, 97,194,253,253,253,177,127,255,126,232,116, 58, 48, + 12, 19, 94, 90, 45, 1,147,149,143,138, 44, 31, 12,211,111,243, 81, 35, 52, 6, 38, 43, 31,245,176,154, 34,255, 14,220,121, 17, + 20,228, 72,129, 82,218,197,139, 73, 50, 78,156, 56,113, 18, 33,100,215,196,137, 19, 39,185,208, 23,246,227, 28,219, 57,180, 55, + 59,239, 83, 90, 74, 84,204,145,231,121, 60,120,240, 0,137,137,137,120,240,224, 1, 50, 50, 50,192, 48,140,167, 39,196, 17, 74, + 8,225,127,249,229,151,160,227,199,143, 27, 26, 53,106,148, 45,228,183,176, 44, 75,108, 54, 27,177,231,189,144,248,248,120,249, +177, 99,199,116, 87,175, 94, 13, 71, 65, 34,154,199, 36, 75, 87, 63,218, 4, 99,229,184,152, 76, 38,168, 84,158, 70, 27,255, 70, +248, 2, 60,123,250,116,129,185,202,211,219,135, 6,115,192,229,230,128, 26,244, 80,112, 54, 40, 64, 65, 76,249, 62,105, 58,230, +243, 0, 40, 52, 87, 86,187,193,178, 88, 44,176,217,108,224,121, 30,172,139, 33,196, 71, 13,165,116,105,253,250,245, 27,108,221, +186,117,208,131, 7, 15,138,109,127,237,181,215, 48,106,212, 40,140, 28, 57,242,234, 43,175,188,114,126,231,206,157, 24, 49, 98, + 4,120,158,175, 71, 8,201,161,148,238,246,164, 57,113,226,196, 63,239,223,191,127,232,198,141, 27,195,194,194,194,148,117,235, +214,189, 89,183,110, 93,201,214,173, 91,195,223,121,231,157,211, 29, 59,118,188,251,235,175,191,150,219,191,127,191,138,231,249, +134,132,144, 7,143,187, 14,150,217,108, 46,140, 56,153, 76, 38, 88,173, 86,192, 67, 82,187, 51,206,239, 77,225,181,101, 89, 86, +208, 38, 91,183,110,193,209,163, 71,153,203,151, 47, 69, 15, 27, 54, 92, 72,164, 47,227, 51, 17,113, 5, 33,164,147,130, 33, 95, +141,171, 23,172,250,224,249, 96,131, 66, 74,242,174,127, 53, 41,239, 78,197, 0, 67,120, 5,141, 37,186,178, 46,114,198,140,233, + 17, 87,175, 94, 51, 79,158, 60,249, 74,239,222,189,195, 62,248,224,131, 90,155, 55,111,110, 65, 8,249,134, 82,154,237, 70, 87, + 62,104,208,160,223,195,194,194,170, 46, 95,190, 60,245,254,253,251, 65, 54,155, 77, 99,179,217,172, 6,131,225, 86,126,126,254, + 49,171,213,186,159, 82,122,186, 36,253,213,106,181,207, 15, 24, 48, 64,150,157,157, 13,251,236, 91,164,166,166,162, 89,179,102, +146, 29, 59,118,212, 46,205,115,144,153,153, 57,159, 16,114,104,221,186,117,237, 3, 2, 2, 26, 42,149,202,242, 0, 56,189, 94, +159, 98, 48, 24,206,149,166,159,142,112, 28,151,114,250,244,233,170, 1, 1, 1,184,119,239, 30, 56,142, 75, 41,173,150,128, 74, +206,220,191,112,100, 71,133,154, 33,149,113,236,248, 73,168,228,204,253,135,213, 20,249,215, 35,228, 72,193,209, 56,185, 48, 70, +199,227,226,226,212, 51,103,206, 68, 92, 92,220, 37,103, 17, 65,131, 82,218, 37, 46, 46,238,146,208,206,161,253,145,178,234,176, +212,126, 32,183, 95, 24, 82,169, 52, 57, 45, 45, 45, 72,167,211, 21, 26,171,196,196, 68, 36, 38, 38, 66,161, 80, 32, 62, 62, 30, + 10,133,194, 99,168,220,142, 73,173, 86,255, 89,191,126,253,103,111,223,190, 45,255,252,243,207, 43,156, 62,125, 58,160, 89,179, +102,207,169,213,106,142, 82, 10,147,201,196, 92,185,114,197,127,238,220,185, 81,141, 27, 55,182, 52,110,220,248,204,134, 13, 27, +140,240, 80,116,148, 16,114, 42, 41, 41,169, 74,165, 74,149, 0,252, 61, 67, 75, 88, 28,141, 22, 80, 48,180, 41,149, 74,207,120, +124, 82,164,210, 11,215,175, 95,111,167, 81, 41, 97,209,231,194,154,151, 11, 86,175, 7,167,207, 1,151,147, 3, 24,114,161, 96, + 89,200, 56, 27,212, 42, 21, 30, 36, 36, 64, 42,149, 94,240,164,169, 80, 40, 46,164,164,164,180,211,233,116,133, 95,158, 54,150, + 45, 88, 56, 14, 22,150, 45,140, 96,201,100, 50,220,191,127, 31, 10,133,194,163,230,163,128, 97, 24, 78, 40,197,224, 10,133, 66, +129,240,240,112,190, 73,147, 38, 24, 49, 98, 4, 56,142, 3, 10,234, 20,182, 34,132, 28,163,148,230,185,211,228,121,158,185,114, +229, 74,247, 91,183,110, 73,100, 50, 25,243,226,139, 47,214,105,222,188,185, 69,161, 80, 64, 46,151, 75,243,242,242,180,251,247, +239, 87,217,108, 54, 98,215,252,199,234, 96, 1,112,105,106,133,100,116,163,209,136,188,188, 60,100,101,101, 73,213,106,245,179, +207, 61,247,220, 73,139,197,178,145,101,217, 85,183,111,223,206,117,167,105, 55,100, 0, 10,204, 22,207,243,160,148,130,227, 56, +216,108, 54,200,229,114,254,240,225, 35,152,187, 96, 54,190, 91,181,150,118,235,214,141,236,216,177, 3, 60,207, 39, 60,154,179, + 20,113, 98, 94,246,143,211, 85, 96, 57,131,249,240,186,188,239,111,228, 26,166,126,191,240, 79,139, 66,146,251,194,203,225,117, +171, 84,126, 86,162,211, 5, 49,203, 86, 44,202,248, 97,237,166, 91,247,238,221,203, 93,178,100, 73,211,103,159,125, 54,240,220, +185,115, 81, 0, 92, 26, 44,127,127,255, 74, 3, 7, 14, 28,152,149,149, 37, 95,187,118,237,234, 7, 15, 30, 28,166,148,254,229, +216,134, 16,210,128, 16, 50, 7,128, 12, 64, 56, 10,242,191,126,161,148,174,241,208, 95,158, 16,130,131, 7, 15, 22,155,237,199, + 63,156, 43,207,170, 91,183,238,243, 55,110,220,216,158,156,156,252,189,243, 70,141, 70,211,173, 78,157, 58,125, 78,157, 58,245, + 49,165,244,150, 43, 1,119,228,231,231,143,223,180,105,211, 28,137, 68, 18,201,113, 92,162,209,104, 28,255, 16,253, 4, 0,152, +108,252,224,184,101,235,191, 54, 90,184,138,106,133,228,158,201,198,191,243,176,154, 34,143, 31, 47,193,154, 52,135,232, 83, 26, + 0,226,244,248,156,253,111,139, 67,219, 52,187,110, 23, 0, 22,167,168,151,171,109,105, 40,195, 34,231,238, 42,185,255, 15, 64, + 99, 0,167,100, 50,217,162,183,222,122,107,238, 15, 63,252,160,205,205,205, 69, 74, 74, 10, 82, 83, 83, 33,149, 74, 17, 16, 16, +128,165, 75,151, 26, 83, 82, 82, 22, 57,238, 67,157, 42,190,219, 49,133,132,132,252,185,118,237,218,242, 95,125,245,149,244,237, +183,223,142,127,229,149, 87,106, 44, 93,186,244,182, 92, 46,167, 28,199, 17,179,217, 76,222,125,247,221,170, 11, 22, 44,184, 43, +145, 72, 52,189,122,245, 34,126,126,126,167, 80,112,225,113, 73, 90, 90,218, 47,219,182,109,235, 62,118,236, 88,165,197, 98,113, + 25,185, 18,214,233,116, 58,252,246,219,111,150,172,172, 44,143,201, 68,102,179,249,151, 61, 63,255,212,242,205,222,189,229, 54, +125, 46,108,250, 92,176,185,185,224,244,217, 32,121,185,144,113, 44,212,114, 30,229,163, 85, 96,141,254,248,233,143,115, 54,179, +217,236,177, 32, 97,110,110,238, 47,199,190,251,174, 85,227,152, 24,233,111,163, 71,195,106,179,161,211,245,235,133,166,202,106, +181, 98,123,221,186,224, 8, 65,189, 33, 67,112,147,101,217,220,220,220, 95, 60,105, 62, 46,206,159, 63,159,218,175, 95,191,211, + 60,207, 55, 64, 9,162, 57, 2,254,254,254,250,188,188, 60,164,167,167,115, 25, 25, 25, 38, 0, 72, 77, 77,205,218,177, 99,199, + 21,158,231, 27,151, 70,179, 44,176,217,138,126,174, 4, 35,196,218,205,111,106,106,170,226,167,159,126,106,121,229,202, 21,249, +197,139, 23,113,244,232,209,122, 63,252,240,195,255, 98, 98, 98,234,198,199,199, 39,187,210,116, 52,109,174,138,245,194,158, 95, +184, 97,221, 70, 12, 29, 58,148, 36, 39, 39,227,199, 31,127,132,183,162,167, 34,101,134, 1, 44,167,182, 28, 94,151,247,202,207, +247,244, 39,146,140,159, 3,216, 75,141, 44,173, 80,161,194,249,134, 13,131, 66, 0,192,108,226,202, 87,175, 94,253,101,169, 84, +170, 0, 0,127,127,255,134,193,193,193, 75, 1, 52,119, 37,250,218,107,175,189, 20, 22, 22, 86,127,247,238,221,231, 30, 60,120, +112,196,217, 92, 1,192,179,207, 62,251,217,197,139, 23, 59,201,100,178,194, 55,134,125,246,148, 75,131,213,170, 85,171,103, 99, + 98, 98,130,127,190, 17,136, 92,121, 53, 80, 73, 14, 32, 85,129,211, 61,143,120,121, 45, 68, 71,159, 12,214,233,116,245,178,179, +179,207,185,218,223, 29,132,144,138,189,122,245,250,105,229,202,149, 53, 59,118,236,168, 0, 80,204, 96,213,172, 89,243,245, 95, +127,253,181,199,176, 97,195,158, 39,132,116,165,190,221,173, 3, 0, 64, 41,141, 7,208,163, 36,125,242,198,190,155,116, 63,236, + 53,203, 68,254, 51,148,164,116, 66,153,148, 89,120, 88,220, 13, 17, 54,230,121,190, 27,195, 48,176, 90,173,113,225,225,225,219, +123,245,234,245,218,255,254,247, 63,255,224,224,224,194,200,213,210,165, 75,141,119,238,220,217,108,181, 90,207, 18, 66,166, 36, + 38, 38,118,139,140,116,251,189,160,255,226,139, 47,214,119,237,218,245,237, 33, 67,134, 24,235,214,173, 27, 80,163, 70,141,252, +227,199,143,251,199,198,198,230, 74, 36, 18,250,219,111,191,105,171, 86,173,106, 34,132, 40,127,253,245,215,140,147, 39, 79, 86, +141,139,139,251, 6, 5,211,166,221,177,110,218,180,105,147,187,117,235, 86, 53, 56, 56, 24,185,185,185, 69, 76,150,240,183, 74, +165, 66,114,114, 50,182,108,217,146,100,179,217,190,241,244,164,176, 44,187,100,241,210,101, 99, 90, 55,121, 49, 42, 64,163, 70, +114, 66, 60,184,156, 44,192,144, 7, 5,107,131, 90, 65, 17, 85, 77, 3,169,196, 15,183,146,243,240,221,241, 63,146, 89,150, 93, +226, 73,211, 98,177, 44, 25,181, 96,193,152, 19,203,150, 69,197,244,236,137,203,107,214, 20, 14, 9, 10, 6,139, 35, 4, 21,219, +182, 5, 19, 24,136, 25,203,151,167, 88, 44, 22,143,154,143, 2,158,231, 37, 22,139,251,226,244, 22,139, 5, 60,207, 39, 92,190, +124,121, 61, 33, 68, 79, 8,105,101,223,116,200, 85,244,202, 81,147, 97, 24,190, 86,173, 90, 91,195,195,195,187, 3, 48,212,170, + 85,107,171, 82,169,108, 99,177, 88, 94,228,121, 62,225,236,217,179, 91, 8, 33,201,132, 16,225, 87,198, 63, 90, 7,203,102,179, + 97,202,148, 41,152, 57,115, 38, 38, 78, 44,184, 91,138,197, 98, 41, 28, 38,204,206,206,174,124,236,216, 49,249,225,195,135,233, +242,229,203, 51,222,126,251,109,221,144, 33, 67,116, 95,125,245,213,251, 0, 92,254, 42,183,217,108, 24, 63,126, 60,150, 47, 95, +142,161, 67,135, 22,219, 46,145, 72,248,132,132,251, 48,153, 76,244,139, 47,190, 72,148,201,100, 65,223,124,243,141,250,157,119, +222,249, 87,228,160,253, 7,248, 72,221,239,227,247, 80,112,141, 89, 68, 41, 61, 36,108, 8, 8, 8, 80,111,221,186, 77, 10, 0, +155, 55,109,145, 81, 74, 3,133,194,176,223,127,255,189,170, 89,179,102, 97,238, 68, 55,109,218,148,253,249,231,159, 7, 15, 30, + 60,184,227,161, 67,135, 52,132,144,159, 81,112,209, 79, 7,192, 1, 8, 1,240, 91,104,104,104,196,250,245,235,171,181,111,223, +222,207, 91, 71,245,122,253, 55,235,215,175,175,180,224, 88, 32,126, 54,116,199,125,190, 39,168,142,162, 92,152, 30,181,252,239, +161,111,223,190,145,139, 22, 45,250, 26, 64, 67, 95, 79,158, 16, 82,251,141, 55,222,216,182,114,229,202,202, 67,134, 12, 73,248, +237,183,223,238, 19, 66, 62,115,209, 52, 99,192,128, 1,241,171, 87,175,174,198,243,252, 94, 66, 72, 71, 74,233, 13, 95,143, 35, + 34,242, 95,132,184,202, 95, 34,132,108,103, 89,182,155, 84, 42,221, 65, 29, 10,141,134,135,135,143,177, 88, 44, 17,132, 16, 42, +151,203,147, 83, 82, 82, 22, 57, 22, 26, 77, 72, 72,232, 22, 29, 29, 93,184,143,189, 88,166, 99,173,140,128, 78,157, 58,181, 59, +113,226,196,151,187,118,237, 74,213,235,245,254,155, 54,109, 82,207,156, 57, 51,158,231,121, 58, 97,194,132,152, 14, 29, 58,228, +115, 28,151, 52,100,200,144,170,149, 43, 87, 30,114,245,234,213,253,112, 48, 88, 46, 52, 65, 8,169, 93,173, 90,181,223, 54,111, +222, 28,160,211,233,144,154,154,138,204,204, 76, 24, 12, 6,112, 28, 7,153, 76,134,180,180, 52,124,254,249,231,185,137,137,137, +197, 10,141,186,209,108, 92, 41, 42,234,151, 69,159, 77,209,234,164, 12, 50,174, 93, 1,155,149, 1, 25,107, 67,133,218,129,144, + 43,212,184,121, 93,143,247,215,109,209,223,203,204, 46, 86,104,212,157,230, 11,213,171,239, 95, 62,110,156,191,233,254,125, 68, + 12, 28,136,252,252,124, 88,173, 86, 48, 12,131,191, 22, 45,130, 60, 52, 20,147, 55,108, 48, 92,186,119,175, 45,117, 42, 52,234, + 74,243, 97,113,212, 36,132, 12, 39,132, 20, 38,185,191,246,218,107, 69,218,110,219,182, 13,203,150, 45,131,217,108,102, 41,165, + 99, 40,165, 75, 9, 33,254, 0,224,104,174,220,105, 86,170, 84,233, 94,157, 58,117,254,224, 56, 78, 10, 0, 18,137,132, 94,190, +124,185,225,157, 59,119, 42, 56,105, 10, 67,215,172, 43,205, 71,113,238,193,193,193,139,118,239,222, 93, 41, 44, 44,140, 56, 86, + 88, 7,254,206,157, 27, 49, 98, 68,219,147, 39, 79, 42,235,215,175,111, 78, 79, 79,111, 20, 26, 26,122, 96,237,218,181, 33,189, +122,245, 74,188,116,233, 82,148,179,102, 72, 72,200,220,205,155, 55, 87,171, 86,173, 26, 35, 68,193,156,135, 33, 7, 13, 26,212, +110,237,218,181,138,238,221,187,155, 13, 6, 67,184, 86,171,189,181,121,243,230,144, 87, 95,125, 53,249,210,165, 75, 17,255,196, +185,139,154,174,169, 83,167,206,205, 75,151, 46, 85, 19, 30, 27,141, 70,164,165,165, 33, 61, 61, 29, 58,157, 14,177,177,177,127, +221,185,115,167,154, 43, 77,123, 84,104,225,138, 21, 43, 58,250,249,249,201,143, 28, 57, 98,216,191,127,191, 41, 62, 62,158,181, +217,108, 52, 34, 34, 66,218,188,121,115, 85,231,206,157,253,148, 74, 37,243,241,199, 31,167, 79,159, 62, 61,132, 16,178,144, 82, +250,190, 43,205, 6, 13, 26,252,190,103,207,158,198,132, 16, 72, 36, 18, 88, 44, 86,100,103,103,227,193,131, 4, 92,190,124, 25, + 39, 78,156,192,190,125,251,206,229,229,229,213,247,245,220, 9, 33, 7,204,102,115, 43,133, 66,225,179,161,231, 56, 14, 82,169, +244, 32,128,118,148, 82,254,105,123,221, 69,205,199,167,249,180,225,105,118, 30, 0, 52, 38,132,108,183,175, 58,229, 92,138,129, + 16,242, 63, 66,200, 20,251,195,198, 62,164, 0,228,238,222,189,251,104,187,118,237, 70,180,109,219,118, 65,251,246,237,147,146, +146,146,170,204,159, 63, 63,154,101, 89,235,229,203,151,153, 91,183,110,197,255,249,231,159,213,158,121,230,153, 33, 87,175, 94, + 61, 12,207,209, 43,161,175,151, 9, 33,205, 90,183,110,189,101,200,144, 33, 21,155, 52,105,162,208,233,116,144, 74,165,184,125, +251, 54,206,157, 59,103,217,176, 97, 67, 66,118,118,182,207,183,202,161,148,158, 34,132,196,246, 26, 57,102,243,144,215,186,134, +188, 88,227, 89, 69, 68, 68, 4, 96, 52,226,218,189,100,156,188,118,206,186,242,232,201, 52,179,217,252,134,179,185,242,162,217, +174,205,184,113,155,167,190,249,102, 56,146,146,164, 17, 17, 17, 80, 40, 20,184,115,231, 14,110,241, 60, 59,107,197,138,148,220, +220,220,127,252, 86, 57, 66,205, 42,158,231,165, 0,160, 86,171, 49,106,212, 40, 56,222, 26,103,217,178,101, 48, 26,141, 0, 32, + 37,132,204, 33,132,172,114, 23,181,114,163, 89,241,231,159,127,174,232,168, 89,179,102, 77, 87,154,101, 54,139,195, 87, 50, 51, + 51, 39,119,234,212, 41, 78, 42,149,186,173, 86, 27, 20, 20, 4,189, 94, 15,150,101,185, 7, 15, 30, 92, 11, 10, 10,130, 76, 38, + 3,165,212,229,231, 40, 35, 35, 99,242, 27,111,188, 49,141, 97, 24,183,145,142,128,128,128,248, 3, 7, 14, 84,127,231,157,119, +152,111,191,253,246,246,224,193,131,149, 7, 14, 28,224, 74, 91,211, 72,228,209,225,248, 99,212,254,227,205,109, 73, 4, 74,233, + 61, 66,200,248,211,167, 79,171,134, 14, 29,218,240,205, 55,223, 12,104,221,186,181,191, 99, 27,163,209,200,239,220,185,211,176, +124,249,242,140, 35, 71,142,252, 49,104,208,160,238, 40,200, 31,113,201,189,123,247,126,154, 49, 99, 70, 96,231,206,157,159, 1, + 80,152,127,149,150,150,134,248,248,120, 92,188,120, 49,222,106,181,238, 40,225,105,141,232,215,175,223,207,171, 87,175,142, 25, + 50,100, 72,194,143, 63,254,184, 3, 64,142,139,118,254,175,191,254,122,183,213,171, 87,199,188,251,238,187,247, 0,140,166, 98, +133,119, 17, 17,143,184, 51, 88, 57, 60,207,195,100, 50,133,243, 60,223,141,231,121,248,251,251,187,106,215, 56, 49, 49,177,155, +227,205,158,225,229,182, 54, 0,210,246,239,223,255,203,186,117,235,218, 78,152, 48,225,205,236,236,236,198,231,207,159,111, 2, + 0, 50,153,236,132,159,159,223,239,113,113,113, 3,199,143, 31,159, 6, 31,204,149,128,221,100,213,154, 59,119,110,153,221,236, +217,110,136,170, 47,217,184,101,196, 55, 74,101,172,211,205,158,127,177,223,236,185, 68, 55,102, 22, 52,199,125,253,245,136,128, +141, 27,255,181, 55,123, 54,155,205,108,247,238,221,191, 97, 24,134, 7, 0,142,227,164,102,179,121, 32, 74, 56,243,212, 89,243, +181,215, 94,251, 86, 34,145,176, 0,192,243, 60, 99, 54,155,255,239, 97, 52,203, 10,187, 81, 28,233,169,205,115,207, 61,183,118, +199,142, 29,253,186,117,235,198, 89,173,214,212,174, 93,187, 74,127,255,253,119,202, 48,140,203, 95,113,118,163,248,161, 39,205, +242,229,203,199, 44, 94,188,248,204,232,209,163, 3,214,173, 91, 87,238,216,177, 99,220, 23, 95,124,145,155,153,153, 57,175,244, +103, 35,242, 40,144,201,100,208,104, 52,176, 88, 44, 72, 75, 75,115, 57,123,217, 17, 74,233, 45, 66,200, 43,227,198,141,107, 49, +110,220,184, 87,162,163,163,107, 87,172, 88,177, 34,195, 48, 76, 82, 82, 82,218,253,251,247,239, 90,173,214, 95, 1,252, 4, 64, + 94,181,106,213,179, 0,214,186,211,203,200,200,152, 70, 8, 57,184,102,205,154, 87,252,252,252,106,169, 84,170,114, 54,155,141, +209,235,245,153, 70,163,241,138,201,100,218, 69, 41, 61, 94,146,115,162,148, 94, 39,132,180,150, 74,165, 63,173, 92,185,178,102, + 82, 82, 82,165,195,135, 15,119,117,110,215,176, 97,195,213,171, 87,175,142, 25, 54,108,216,173,117,235,214,149, 40, 7, 75, 68, +228,191,138,187, 47,182, 25, 10,133, 66, 10,251, 77,159,237,184,138,168,156,114,202,185,202, 1, 48,195, 69, 59,103, 12,125,251, +246,189,211,183,111,223, 57,246, 62, 72, 80, 80,138,129, 69, 65, 6,191, 21, 94, 74, 51,184,194, 62,164,244,181,125, 41, 19,236, +102,103, 46,202,176,224,231,163,208,124, 88,132,154, 85,246, 89, 77, 0, 48,238,236,217,179, 75, 29,219, 16, 66,206, 59,110,247, + 22,105,114,165,121,238,220, 57,103,205,139, 37,209,124,156,100,103,103,143, 89,188,120,241,169,137, 19, 39, 42, 7, 12, 24,128, +139, 23, 47, 98,230,204,153,230,236,236,236,117,165,213, 76, 78, 78,142, 47, 95,190,124,131,133, 11, 23,126,176, 96,193,130, 87, + 9, 33,226,189, 8,255, 37, 24,141,198,191,158,127,254,121,144,130,217, 9,148,101,217,194,217,159,246,138,252,197, 18,215,157, +177, 95,147, 14,218, 23,111,204,241,214,192, 94,182,164, 76, 75,151,216,163,109,175,220,189,123,119,198,245,235,215,247,184,106, +115,233,210,165,109,237,219,183,215,156, 56,113, 98, 82, 73,103, 17,138,136,252, 87,113,105,176,236,191, 78,222,244,182,179,155, +217,130,190,194,193,123,180, 75,228, 31,196,158,255,180,202,254,119, 49,163,227,109,251, 63,165,249,184, 72, 72, 72,200, 2, 80, +120,203,144, 42, 85,170, 20,203, 83, 43, 13,118, 51, 53, 10, 98,229,246,127, 21,183,111,223,238,244,184,251,240, 79, 65, 41,189, + 7,160,159,187,237, 22,139,101, 7,128,146, 14, 63,138,136,252,167,121,236, 67, 51, 34,255, 46,124,137, 74,253, 27, 52, 69, 68, + 68, 68, 68, 68,254,205, 16, 0, 46,111,146, 89,146,217, 1,132,148,252, 70,155,222,244, 69, 77, 81, 83,212, 20, 53, 69, 77, 81, + 83,212,124,250, 52, 29,180, 23,184,217,116,205, 73,239,171,146,246,225, 95, 1,165,244,145, 45, 40,152,198, 43,106,138,154,162, +166,168, 41,106,138,154,162,166,168, 89,154,227, 12,249, 39,142,243, 40, 22,241,134,178, 34, 34, 34, 34, 34, 34, 34, 34,101,140, +203, 28,172, 77,155, 54, 73,132,191,251,244,233, 51,136,227,184,194,233,235, 18,137,100,241,143, 63,254,184,202,147,104,143, 30, + 61, 56, 79,154,174,240,118, 28, 87,154,117,158, 13, 28, 22, 28,168, 25,147,157,147,191,240,118, 34,119,212,100, 50,213, 18,182, +169, 84,170, 43,171, 86,173,242, 88,105,184, 52,253, 28, 52,104,208, 51,206,199,169, 20, 45,107, 85, 78,171, 26,149,153,157, 55, +255,226, 13,253,147, 25,202,124,130,232,217,179,167,199,215,200,153, 59,119,116,204, 25, 68,204, 11,240,147,119,205, 51,216,230, +113,167,167,124,249,168,250,246, 79, 18, 17, 17, 81, 35, 32, 32,160, 63,128,218,249,249,249, 97, 26,141, 38, 21,192,229,220,220, +220,181, 73, 73, 73,215,188,237, 47,208,170, 50,137, 7, 80,209,254,240,222,161, 59, 52,198,151,109,222,232, 80,141,152, 40,160, + 36, 4,214,189, 55,105,225, 13, 46, 59, 86, 39, 38,158, 22, 95,223,161, 58,177, 80, 10, 57, 1,204,123,111, 81,223,238,202,254, + 4, 64, 8, 9, 0, 16, 11,160, 14,128,243, 0,246, 81, 74,125,187, 67,188,136,136,200, 19,139, 75,131, 53,104,208,160,150, 10, + 41,253, 18, 60,213,129,210, 96,179,217, 44, 83, 40, 20,176, 88, 44,208,168,213, 75,134,254,223,128,207, 64,144,109,229,153, 81, +171, 86,173, 42,245,157,167, 75,114, 39,169, 54,227, 0, 0, 32, 0, 73, 68, 65, 84,156, 30, 61,122, 20,155,230, 28, 20,160,158, +118,104,231,132,160,150,175,196,205,180,220,201, 28,175,215,235, 25,165, 82, 9,179,217,140,192,192,192,102, 35,135, 12,110, 72, + 25, 98,145,171,252,142, 47, 88,176,192,229,189,226,124,225,253,247,223, 47,207, 90, 13, 47, 81, 27, 85, 88, 44, 22,165,243,113, +116, 26,191, 89,135,118, 78,208,188,220,101,230,103, 0, 68,131,245, 47,162,192, 92,149,255,234,189,190, 47, 14,152, 61,186, 29, +116,173,102,141, 7,240, 68, 27, 44, 66,136,164, 74,149, 42, 35, 98, 98, 98,122,175, 88,177, 66, 94,165, 74, 21,168, 84, 42, 24, +141,198,136,191,254,250, 43, 98,216,176, 97, 47, 87,173, 90,117,253,237,219,183,151, 80, 74,139,253,136,112, 65,197, 67,171, 63, + 6, 0, 52,235,255,121, 69, 66,200,135, 0,242, 1,224,229, 74,127,111,107, 53,224,243,138,132,144,113, 40, 58,251, 55,137, 82, +234,114,118, 25, 5, 20,187,214,204, 69,183,183, 62,148, 18, 66,134, 9,235, 59, 63, 3,236,249,126, 17, 58,246, 25, 83,100,125, +135,170,144,238, 92, 51, 23, 93,222,250,208,237,221,198, 59, 62,195,216,120,222,117, 97, 87, 0, 96, 24,194,238,189, 73, 93,221, +248, 55,133, 82, 90,236,126,161,132,144, 14, 40,184,209,178,203,246, 93,106, 74, 83,172, 54,206,101,161, 88,185, 76,146,186,235, + 42, 91,108,223, 1, 13,136,205,198, 21, 92, 91,229, 82,112,129,129,129,135, 62,250,232, 35,105,151, 46, 93,176,114,229,202,230, + 95,125,245,213, 16, 66,200,175, 0,118, 80,177,228,129,136,200, 83,139,203, 11,149,130,161,203,247,174, 91, 86, 45, 57, 45, 19, +189,135,253, 15,235,214,173, 67, 86, 86, 22,130,130,130,160, 80,200,101, 75,103,140, 47,175,211,106,202,247, 26, 57,101, 57,128, + 26,165, 61,120, 9,143, 83,221,121,127, 98, 47, 68, 42,149, 72,101, 10,133,140, 89,191,126, 61,178,179,179,161,211,233,160, 80, +200,152, 69,159,143, 85,235, 2,252,212,111,142,153,218, 28,192,198,210,246,147, 53,230, 53,223,249,253,226,128,148,180, 12,244, + 27, 53, 25,206,199,145,201,229, 28, 80,240,133, 82,218, 99,136, 60, 60,233,233,233, 4, 0, 66, 66, 66, 40,224,104,174,154, 12, + 88, 48,182, 61,222,159,191, 15,249, 38, 75,177, 27,217, 62,105, 84,169, 82,101, 68,207,158, 61,123, 79,155, 54, 77,206, 48, 5, +163,252, 6,131, 1, 70,163, 17, 81, 81, 81, 56,116,232,144,124,242,228,201,189,183,109,219, 6, 0, 95,148, 84,255,210,165, 75, +149, 42, 86,172,104, 2,128,174,117,181,206,219, 98,132,109, 0,160,213,106,225,141, 96,157,159,249,210,165,147,181,133,253, 70, +180,141,226,220,172, 55, 1,208,120,210,226,121, 42,221,247,229, 48,183,219,223,153,246, 3,123,126,227,209, 26, 85,170, 84, 49, + 58,174,119, 83, 40, 25, 0,194,243,242,242, 42, 58,175, 20,218, 91,109, 92,152,187,227,181, 31,181,204,165,241,178,113,144,254, +240,195, 15, 0,128,121, 31,246,147,124,253,123,186, 84, 42, 45,184,212,206,153, 51, 7, 83,167, 78, 85,236,221,187,183,243,154, + 53,107, 58,219,111,141, 35,150, 63, 16, 17,121, 10,113,105,176, 8,129, 54, 64,235,135,110,111,143,194,238, 61,123,209,178,101, +203,194,109,149, 43, 87, 70,159,215,187, 98,219,138, 56, 48, 32,222,175,174, 30,120,216,227,100,229, 24, 62,233,212,251,139,207, +239, 37,231,157,216,181,235,103,180,104,209,162,200,254,111,246,234,142,205, 75,167,131, 80, 42,127,152,126,242, 12,149, 7, 4, +248,225,141,193, 99,224,234, 56, 67, 7,116,219,213,177,199,162,118, 41, 25, 6,119, 51, 34, 68, 30, 17, 87,175, 94,149,152,205, +230, 62, 1, 1, 1, 77,100, 50, 89,184, 82, 87,145, 79,148, 54,206, 72, 35, 85,110,167,134,229,183, 28,219, 46,188,227,188,247, + 90,227,253,249,251,176,112,221,201,213, 13,144, 60,197,187,234,191,151,136,136,136, 26, 49, 49, 49, 69,204,149, 94,175, 71, 94, + 94, 30,114,115,115,161,215,235,193, 48, 12,198,143, 31, 47, 63,124,248,112,239,136,136,136,253, 62, 12, 23,222,107,214,255,243, + 2,147, 33,145,229, 77,153, 50,197, 28, 22, 22,102,214,104, 52, 84, 42, 87,234, 91, 13,248, 92, 11, 0,140, 84,174, 95,184,112, +161, 37, 42, 42,202, 36,149, 74, 21, 99,198,140,241, 41,135,211,108, 54, 83, 71, 77,139,197, 92,184,126,214,172, 89,150,240,240, +112,179, 70,163,161, 86,171,251,155,140, 59,115,225, 78, 38,148,114, 9,148,114, 9, 84, 10, 25,180,149, 26, 65,153,117, 17, 44, +203, 98,246,236,217,214,242,229,203, 91, 52, 26, 13, 85, 40, 20,242,209,163, 71,123,237,231,160, 65,131,168, 78,167,179,106, 52, + 26,249,212,169, 83,139,221,151,239,192,249, 7, 80, 43,100,208, 40,165,168, 94, 57, 26, 74,106,116, 37,227, 18,137,164,232,136, +182, 82,169, 68,243,230,205, 81,187,118,109,108,223,190,189, 21,196,250, 82, 34, 34, 79, 37, 82, 0, 32,132,188, 12,224, 16, 0, + 80, 74, 9, 0, 48,160,248,116,112, 71, 12,121,171, 39, 56,142, 47,200,138, 7, 32, 33, 4, 31,246,110, 9,158, 99,193,195,235, +173, 34,188, 78,213, 44,233,113, 28, 53, 41, 97, 36, 0, 80,163, 98, 48, 29, 58,176, 47,120,174, 96, 52,132, 3, 32, 3,240, 65, +207,230,224, 56, 27,120, 47, 69,225,125,235, 39,143,143, 7,181,135,171,227,212,168, 26,206,152, 57, 22,196,225,102,140,190,104, +150, 20, 81,179, 40,199,143, 31,143,208,104, 52,243,251,245,235, 23, 57,122,244,104, 5, 39,213, 73, 55,157,200, 8,156,176,244, + 68,100,190,217, 42,233,219,186, 18,198,190, 89, 23, 99, 23, 30, 16,204,213,144,202,149,179,159,232,215, 40, 32, 32,160,255,138, + 21, 43,138,153,171,148,148, 20, 38, 47, 47, 15, 86,171,149,215,235,245,224, 56, 14, 19, 39, 78,148, 77,158, 60,185, 63, 33,100, +170, 93,199,236, 74,243,208, 29, 26, 67, 8, 25,119,233,210,165,152,143, 62,250,200,218,166, 77,155,123,149, 43, 87, 54, 72, 36, + 18, 68, 68, 68, 44,138,141,141, 45, 55,109,218, 52,107,231,206,157,239, 74, 36, 18, 84,175, 94,221,112,241,226,197, 24, 0,106, + 95,207,221, 81,115,213,129,197, 20, 0, 8, 33,136,141,141,141,175, 94,189,186, 65, 34,145,224,198,206, 89,197, 46, 40,238, 52, +101, 82, 6,207, 68, 5, 22, 60, 32, 4, 80,251, 3, 89, 5, 15, 99, 99, 99, 19,106,212,168,145,199, 48, 12, 46, 92,184, 16, 13, +160, 72, 62,151, 43, 77,181, 90,109,235,219,183,239,189,107,215,174, 21,107, 15, 0, 82, 9,131, 38, 53,236, 1,171,168, 6, 64, +194, 49,183,253,148, 73,192, 78, 30,209, 79,170, 83, 1, 74,109,136, 57, 55, 55, 23, 1, 1, 1, 0, 0,171,213,138,179,103,207, +162,105,211,166, 47,111,220,184,241,176,155,167,203,227,185, 63, 12,162,166,168,249,111,214,116,229, 69,158,100,132, 8,214, 33, +231,147,225, 57, 22,213,162,130,177,244,195, 55,192,178, 28, 56,142,183, 47, 28, 88,150,135,205,106,129, 23,127,229, 19, 15,115, +156,160, 0,245,180,221,235, 71, 7,181,125,117, 78,219, 47, 63,120,253, 23,222,102, 3,199, 3, 44,199,131,179,113,224,121, 30, + 54, 75,217,212,176,228,109, 28,170, 69, 6,227,203, 15, 94,135,243,113, 22,255,180,175,235,129, 29,227, 53, 45,187,204,252, 0, +192,236, 50, 57,160,136, 71,174, 94,189, 42,209,104, 52,243,215,174, 93, 27,211,168, 81, 35, 6, 0,142, 94,103,149, 19,150,158, +136,220, 27,215,140, 52,171, 29,140,212,108, 51,198, 44, 57,135,221, 39, 82,247, 56,155,171, 39,152,218, 85,170, 84, 1,240,183, +185,154, 59,119,110,200,210,165, 75,163, 0,224,141, 55,222,120,208,182,109,219,244,235,215,175, 35, 34, 34,130,164,167,167,191, + 2, 96, 12, 0, 16, 66,198, 81, 74,151,186,209, 53, 84,172, 88,209, 20, 26, 26,106, 22,140, 16,195, 48,144, 74,165,168, 88,177, +162, 41, 44, 44,204, 92,189,122,117,131, 92, 46, 7,195, 48, 16, 12,158, 47, 16, 66, 32,145, 72, 32,104, 58, 34,145, 72, 32,104, +150, 4,153,212,161,189,211,245, 65, 56,142,171,227,185, 67,165, 82, 81, 0,110,219, 75, 24,135,203,163,212,115, 38,192,234, 51, + 84, 70, 8, 57, 68, 41,197,153, 51,103,112,251,246,109,200,229,114,148, 47, 95, 30, 83,167, 78,133,217, 92,112, 77,234,217,179, +231,203, 0, 46,248,212, 65, 17,145,255, 6,197,188,200,147, 76,145, 33, 66, 66,200,203,148,210,195, 0,192,177, 54,112, 28,239, +210,244, 88,109, 44,108, 86,159,239,195,236, 17, 79,199,225, 56,206,227,113,132, 28, 44,158, 82,169, 75,115,197, 23,220, 55,172, + 76,250,201,219, 96,227, 80,204, 92,241, 60, 15, 66,152,130,144, 22,197, 67, 13, 69,138,248,142,217,108,238,219,175, 95,191, 72, +193, 92, 1, 64,186,222, 38,205, 55,219, 36,205,106, 7,163, 97,235,158, 56,125,112, 35, 54, 28,121,128,170,161,154, 35,149,253, +158, 10,115,133,252,252,252, 48,149, 74, 5,131,193, 80, 24,185, 90,186,116,105,148,197, 98, 97, 0, 64, 42,149, 69,167,241, 81, + 42,142, 7, 2, 3,146,144,149,149, 19, 44, 92,176, 8, 33,115, 8, 33,171,168,135,202,249,114,185,188,208,152, 56, 26, 31,165, + 82, 89, 42,227, 34, 32,152, 50,185, 92,238,114,189,243, 48,154, 55,228,142, 6, 11,180, 32,138,229,128, 96,232,132,220, 39,111, + 40, 20,138,194,115,119,133, 84,226,112, 60, 73,201, 83, 45,173, 86, 43,242,242,242,144,157,157, 13,149,170, 32, 64, 70, 41, 5, + 33,100, 12,128,247, 74, 44, 40, 34,242, 20,227,232, 69,158,100,156,175, 62,135, 80, 80,221, 29,172,205,234,210,244,172,217,119, + 26,183, 50,108,136, 10,186, 12,161,173,175,244,238,221,123,117, 68, 68, 68, 19,225,177, 92,163, 13,238,255,225, 44,112, 86, 11, +116, 74,138,247,122,180, 40, 98,174, 56,142,135,213,234, 62, 2,149,149, 99,248,164, 99,207, 69,159, 7,251,105, 79, 56,155,158, +201,155,174,245,200,200,177, 68, 19,233, 85,100,147, 40,174,231,187,159, 14, 18,246, 99, 24,230,252,250,101, 83,198,250,218,111, + 74, 24, 89,215,209, 95, 13,225,228,218, 90, 1, 52,235,200,212, 62,181,182, 58,154,184, 48,127,255, 93, 29,222, 88,208, 46, 37, + 83,204,193,250,167, 80, 40, 20,237, 70,143, 30, 93,228,155, 46, 68, 43, 99, 53, 74, 25,247,219,229,116,114,250,224, 70,230,232, +165,116, 94, 37,151,208, 80,122,187,202,227,234,103, 89,163,209,104, 82,243,243,243, 35,140, 70, 35,114,115,115,145,155,155, 91, +100,187, 84, 38, 35, 67,134,142, 12,145,201, 21,176, 89, 45,216,189,118,186, 87,205, 86,149, 73,252,203,149, 80,177,107, 93, 45, + 36, 50,133,254,114,149, 42,139,164, 82, 41, 24,134,193,206, 37, 19,198,108,153, 63, 74, 11, 0,231,119, 45,201,237, 51,126,241, + 23, 12,195,192,108, 54, 43, 75,210,239,251,247,239, 71,155,205,102,147,221,152, 9,134, 15,119,238,220,169, 96, 54,155,141,142, +235,125, 65,173,209, 2,186,202,128,166,104,158, 57, 33, 4,119,239,222,141,180,217,108,249, 82,169, 20, 22,139,197, 39, 55,196, + 48,140,252,194,133, 11,209, 60,207,187,108, 95,187,106, 36, 80,190, 46,160, 8,244,181,139, 66,145, 68,175,109, 8, 33,244,105, +250,213, 46, 34, 82, 6, 20,122,145, 39, 25,193, 96,181, 34,132, 20, 94, 13, 40, 5, 88,171,181,208, 88, 21, 68,152, 10,254,190, +147,195,227,218,141,155, 88,184,112, 33, 14,255,249, 65,224,180,105,211,148,147, 39, 79, 54,247,238,221,123, 62,207,243,207, 51, + 12,115,190, 71,143, 30, 99, 92, 29,140,231,249, 10,167, 79,159, 46,252,178,179,217,108,208,106,181,208,106,181,168, 83,165,124, + 49,115,197,218, 35, 88,238, 46, 83,148, 48, 18, 80, 0, 20,148,229,108,224,108, 40, 52, 61, 25, 57,150,232,109, 7,207, 85,115, +104,254,172,240, 71,243, 70,181,138,139,217,233, 61,108,106,225,121,172, 95, 54,101,236,180,149, 43,149, 89, 92,248,232, 62,189, + 6,215,233,217,167, 63,250,189,222,241,101,147,201,182, 93,202,128,183,241, 28, 56, 27, 15,158, 82,134, 2, 69,114,176, 68, 30, + 29,233,233,233,196,104, 52, 86,210,233,116,133,235, 40,165,136,240, 51,152,199,247,122, 38, 49,118,194,177, 72,147,149,131, 82, +198,208, 49,175,198, 36,254,190,109, 67,112,186, 57,157, 8,179, 11,159,112, 46,223,186,117, 43,162, 66,133, 10,200,205,205, 5, +203,178,252, 27,111,188,241, 64, 42,149, 69, 75,101, 50,210,165,207, 72, 62, 57, 57,209,198, 48, 18, 80,202,161, 83,207,225, 68, +169, 82,203,173, 22, 11, 11, 96,156,155,232,149, 99, 41, 6,109,108,108,108, 57, 97,102,223,150,249,163,180, 14,219, 2, 26, 54, +108, 88,206,113, 22,161, 47, 40, 20, 10,210,187,119,111,117,197,138, 21, 9, 0,252,177,246, 35, 0,128, 92, 46, 39, 93,187,118, + 85, 85,172, 88,144, 95,255,235, 18,223,239,117, 29,162,161, 64,206, 29, 32,231,110,145,245, 18,137, 4, 93,187,118, 85, 86,169, + 82,165, 68,159, 69,123, 98,187,219,218, 91,126, 82, 22, 72, 62,227,147,214,128, 6,196,246, 81, 75, 72,231,119, 98,160,240, 15, + 54, 55,153,176,247,119, 79,237, 69,147, 37, 34, 82, 72, 17, 47,242,164, 35, 5, 0,123, 40,174,200,135,155,181, 89,139,153, 43, +142,227,161,226, 12, 88,184,112, 33,222,123,239, 61, 0,144,143, 29, 59,118,235,180,105,211,186,243, 60,255, 60,165,180, 5, 33, +238,175, 17, 12,195, 28,138,136,136, 72,161,148,202, 24,134,105,177,100,201,146,114,157, 58,117,130, 86,171, 5,229,105, 49,115, +197,113, 60,108,102, 75,129,227,115, 65, 80,128,122,218,158, 77, 99,130,218,188, 58,187, 45,103,195, 47,130,185,226,108,127,167, +197,103,164, 36, 96,223,158,237, 88,190,108, 69, 22, 8,189, 10, 10,158, 97,152,243,238,250,200,243,252,243,199,254,184,210,162, +121,163, 90,152,182,114,165,242,210,233,164,173, 35,223,255,168, 78,207, 62,253,177,241,199,181,144, 88,179,206, 72,153,240,191, +205, 21,199, 33, 77,159,219,245,192,206, 9, 98, 14,214, 99,194,102,179, 33, 43, 43, 11,182,188, 44,246,133, 8, 67,206,167, 61, +195,204, 41, 89, 38,169,140,207,103,107, 6,164,154, 15,102,222,149,104, 52, 30,103,255, 63, 49,228,230,230,174, 29, 54,108,216, +203, 71,142, 28,145, 51, 12,131,220,220, 92,180,110,221, 58, 61,141,143, 82, 13, 25, 58, 50, 36, 49,241, 1, 27,160,150,154,229, +114, 25, 82, 83, 83,249,151, 59,247, 53,246, 25, 52, 38,242,189, 73, 51,190, 74, 60,190,204, 93,254, 85, 17, 28,103,246, 57,111, +251,250,235,175, 45, 81, 81, 81, 38,165, 82,169, 24, 48, 96,128, 79,227,132, 22,139,133,206,154, 53,203,236, 60, 91,208, 98,177, +208,133, 11, 23, 90,162,163,163,205,106,181,154,218,108,222,211, 14, 24,134,176,239, 76,251,129,101, 89,182,112,157,112,205,145, + 72, 36,176,241, 36,239,203, 47,191,180, 70, 71, 71, 91, 52, 26, 13, 85, 42,149,114, 95,250, 57,114,228, 72, 26, 20, 20,100,245, +243,243,147,143, 31, 63,254,161,102, 17,218, 56, 72,167, 45, 41, 44,211,160,212,106,181,208,235,245,133,125,141,136,136, 40,182, +143,104,178, 68, 68, 92,123,145, 39, 25,151, 9, 10, 60,229,243, 82, 82,211,195,116,145,213, 96,179,177,224, 88, 27, 88, 27, 11, + 27,107,195,184,129,175, 33,110, 89,193, 72,152,221,100,197,142, 29, 59,118, 43,224,253,182, 59,235,215,175,255,124,236,216,177, + 1, 41, 41, 41,123, 87,175, 94, 93,174, 95,191,126, 24, 55,110, 28,230,204,153, 3,169, 66,133,192,242, 49,133,199, 97,109, 44, + 56, 27,139,212,140, 44, 80, 74,243, 92,233, 9, 57, 88,148, 66, 26, 80,190, 50, 56, 78,216,215, 6, 70, 82, 48, 51,125,223,158, +237,232, 55,112, 20,100,202,192,160,197, 11,103, 27,235,188, 16,209,125,242,224,193,222, 51,223, 9,152, 75,167,147,182,142,124, +111,124,172, 96,174,182,172, 89,114,117,201,152,216,117, 26,133,180,240, 56,156,205, 6,134,145,136, 57, 88,255, 32, 33, 33, 33, + 52, 45, 45,237,110,118,118,246,179,126,126,126,200,200,200, 64,102,102, 38,178,179,179, 97,206,205, 98,131,185,108, 3, 97, 51, +241,255,236,157,119, 92, 83,215,251,199, 63,207,205, 14,123, 41, 67, 4, 7, 14, 20,172,171,110, 28,173, 90,107, 29,109,197,189, +103,181,213, 86, 91,235,172, 3,247,104,221, 86,171,214, 90, 90, 7,126, 29,173,213,186,234,172,171,162, 56,192,133, 3,217,130, +140, 64, 8,153,247,252,254,128,208,128, 1, 18,196,174, 95,222,175, 87, 94, 33,247,158,251, 57,231, 50,146, 15,207, 57,207,115, +132, 66, 33,158,197,235, 97, 48, 24, 82,254, 35,209, 43, 36, 39, 39,223,173, 93,187,246,238,153, 51,103, 14,152, 62,125,186,136, +231,121,220,187,119, 15, 12, 96, 34,177, 4, 28,199, 65, 36, 18, 34, 59, 91,193,219, 57,184, 36,107,153,192, 78, 36,150,128, 19, +136,203, 42, 56,250,180,227,240,130, 50, 13,156, 80,156, 99,204,236, 19,139,197,184, 20,177, 82,209,113,248, 2, 39, 0, 16, 75, +229,153, 93,187,118,141,107,208,160,129,242,234,213,171,254, 40,145, 69, 88, 18, 2,244,239, 14,255, 92, 96, 39,151, 41,187,116, +233,242,212,168,249,228,248,122,197,144, 9,179,136, 4, 18,101,143, 30, 61,226,130,130,130,148, 2,129, 0, 49, 7,151, 43,222, + 29,254,185,140, 10, 18,116,205,114,244, 1, 27,115, 35,226, 92,253, 69,139, 22,233,186,119,239, 30,111, 92, 15,246,228,201, 19, +159,119,222,121, 71,186,106,213, 42,221, 59,239,188,147, 16, 28, 28,156,203,113, 28, 34, 35, 35,205,102, 5,150, 68, 46,151,235, + 70,141, 26,245,244,214,173, 91, 21,202, 34, 44,143,234,213,171,131,231,121,116,234,212, 9,249,249,230, 3,128, 54,147,101,195, +198,127, 11,179, 6, 75,203,243, 31, 13,157,182,114, 61,129, 28,120,176, 98, 89, 58, 12, 0, 24,163,207, 62,251,212, 30,128,220, +104,178, 38, 79,158,156, 89, 94,103, 38,230,170,249,160, 65,131, 48, 99,198, 12,124,249,229,151,134, 21, 43, 86, 8, 98, 30,198, +107, 67,167,172,200, 42,209, 15, 24, 99,185, 6, 3, 62, 50,167,151,153,173,156, 27,242,206,210,249,137,169,121,231,251,126,186, +164,216,187, 86, 22, 21, 20, 51,220,244,245, 38,165, 72,234,108,223,119,192, 16, 0,232,178,126,245,242,253, 11,177,181,124,147, +197, 40,240,163,201,159,187, 26,205,213,134, 85,139,110,185, 82,234,186,209, 95, 68,191,176,106,222,217, 1,251, 67,222, 89,250, +214,179, 12,229,154,242,190, 7, 54, 42, 7,141, 70,115, 98,237,218,181, 53,102,207,158, 45,201,200,200, 64,122,122, 58, 50, 51, + 51,139, 30,185,185,185,240,242,242,194,175,191,254,170, 85, 40, 20,151,254,238,241, 86, 38,143, 30, 61,218,240,211, 79, 63,225, +204,153, 51,253,167, 79,159, 46,242,242,242, 34,103,231, 20,210,105, 53, 0, 24, 75, 75, 75,227,237, 28, 92,146, 61, 60,125,159, + 38,165, 60, 11,212,105, 53,224, 13,218, 82, 87,145, 23,150,105,248,236,246,237,219, 53, 86,174, 92,169, 49,205,236, 27,240,249, +250,181,205,154, 53,115, 91,183,110,157,166, 71,143, 30,113,198, 69,233,150, 44,114, 63,246, 16, 31,223,190,125,179, 97, 73,205, +142, 99, 87,110, 51,106,154,102, 23,246,252,116,243,182, 58,117,234,184, 5, 5, 5,197,149,165, 91,171, 86, 45,149,183,183,183, +166,126,253,250,185, 34,145,168, 32,114,165,211,229,213,170, 85,139,247,244,244,212, 52,104,208, 32,215,218,197,248,114,185,156, + 1, 47,214,172, 50, 98, 77, 22,161, 72, 0,253,160, 65,131,138, 42,185,127, 86,167, 78,242,144, 33, 67,188,167, 76,153,130,109, +219,182,225,247,223,127,207, 40,121, 77,135, 14, 29,112,246,236,217,249, 0,230, 90, 52, 96, 27, 54,108,252,227, 49,107,176,182, +111, 15, 63, 9,147, 53, 75,230, 88,184,112,161,180, 48,114,213,229,147, 79, 62,129, 74,165,114, 45,217,134,136, 58, 27,107,101, +152, 51, 87,203,151, 47,223,201, 24,243, 5,208, 78,111,224, 47,127,243,237,142, 78,229, 13,216, 84,147, 17, 39,224, 56,202,149, +136,216,245,175,191,217, 94,172, 66,119,225,162,246,122, 32,220, 88,191,122,185, 10, 64,151,146, 38, 43, 52, 52, 52,175,164,166, +145, 15,198,143, 43, 50, 87,235, 87, 47, 63, 30,212,220,239,189,217,163, 23,152, 53,101, 11,230,142,179,231, 56,106, 99,186, 6, +203,156,230,203, 98,211,252, 83, 83, 42,149,238,220,181,107, 87,247,144,144, 16,255,215, 94,123,141,203,200,200, 64,110,110, 46, +114,115, 11,130,157, 30, 30, 30,136,137,137,225,227,226,226, 18,165, 82,233,174,191,107,156,175, 66,179,112,251,155,181,222,222, +222, 39,230,204,153, 51, 36, 61, 61,253,157,204,204, 44,247, 95,190, 91,136,110,125,199, 83,135,238, 3,149, 26, 38,148, 37, 36, +167,214, 63,125,248, 71,183, 35,187, 55, 64,171,209,140, 37,218, 20, 99, 44,211, 96,102,156,121,198,114, 12,245,235,215, 87,154, + 26, 20, 63, 63,191,124, 31, 31, 31,117, 80, 80, 80,209,113,115,217,121,230,238,221, 90,205,194,245, 93,202,178, 52, 1, 20,153, +181,146,229, 31,236,236,236, 96, 52, 93,214,140,211, 52,123,210, 28,229,101, 17,154,106,126,119,141,137, 76,207,125, 71, 36, 8, + 15, 15,239, 28, 30, 30,222, 28,192,117, 0,199, 0,232, 10,175, 43, 90, 12,207, 24,155, 7, 96, 94,121,247,254, 50,216, 52,109, +154,255,100,205,255, 26,150,229, 48,151,192,184,160, 29, 0, 55,121,242,228, 76,149, 74,229, 58,100,200,144, 50,175, 73, 73, 73, +217,182, 99,199,142, 98,230,234,253,247,223, 31,177,119,239,222, 19,207,158, 61,171,200, 48,224,234, 36, 95,120,230,231,105,174, + 29,122, 44,253, 4,192, 10,179,141, 24,248,160,230,222,239,173, 95,189,124, 63,138,155,172,239, 1,188,111,230, 10, 2,128,174, +221,122,227,199,237,235,140,107,183,228,183,174, 38, 30,233,127, 45,204,108,246,161,139,131, 52,172,112, 28, 83, 96, 91,131,245, +151, 16, 24, 24,104,184,112,225,194,148,241,227,199,127,245,230,155,111, 86,235,221,187,183,184,122,245,234,144, 74,165,120,248, +240, 33,206,157, 59,167,125,244,232, 81, 98, 94, 94,222,148,215, 94,123,205,146,253,248,254,117, 36, 39, 39,223, 45, 44, 34,250, +177,113, 90, 73, 42,147,139, 7,142,252,196,183, 40,139,112,247, 6,168,243, 85, 0, 32,180,164, 76,131, 80, 40, 20, 71, 69, 69, +249, 27,163, 84, 90,173, 86,106, 60,126,245,234, 85,127, 99,109,172,252,252,124,139,179, 8, 95,149,230,205,155, 55,125,141,217, +142,198,108, 65,161, 80, 40,142,140,140,244, 53,106,170,213,106,139,178, 8, 37, 18,137, 56, 42, 42,202,215, 96, 48, 84, 90, 22, +161,145, 66, 67,124,180,240, 1,160,192, 88, 21,154, 43, 42,156, 22,180, 77, 15,218,176,241, 31,163, 66, 6,203,184,160,221,210, +246, 68, 36,172, 81,163, 70,215, 1, 3, 6, 20, 51, 87,161,161,161,134,125,251,246,157,246,246,246, 78,229, 56,174,188,237, 60, + 94,212, 53,174,193, 42, 40,168, 94, 12,142,227,110,180,123,189, 1, 56,142,187, 49,123,244,104,245, 66,108, 45,102,178, 14,238, +223,243, 86, 41,178, 12, 0,220, 61,125, 49,104,196, 68, 12, 26, 49,209, 21, 64, 91,160,244,236,195,178,198, 97,227,213,209,166, + 77,155,228, 59,119,238, 12, 58,126,252,248,192,179,103,207,118,206,203,203,171, 65, 68,144,203,229, 79, 52, 26,205, 9,169, 84, +186,243,191,106,174, 74, 67,171,213,234,167,207, 95,185, 67, 32, 16, 25,120, 94, 75, 90,173,118, 4,172,248, 59,159, 62,125, 58, + 7, 51,107,171, 38, 78,156,104,246,248,223,165, 57,115,230, 76,179, 89,127, 19, 39, 78, 44, 51, 27,176, 52, 62,253,244,211, 74, +203, 34,180, 4,155,145,178, 97,227,191, 79,133, 12, 22,199,113, 55,204,100, 11, 18, 0,102, 46, 67,143, 49,166, 23, 8, 4,243, + 93, 92, 92,198, 41,149,202, 95,223,127,255,253,201,161,161,161, 6,160, 96,225,123, 69,198, 0, 20,172,193,234,216,115,217,148, +172, 92,245,186,146,231, 74, 70,154,140, 38,107,195,154,229, 27,247,239,221, 21,154,146,148, 96, 54,163,202,104,204, 74, 59,103, +238,120,182, 66, 53,191, 99,207,101,159,100, 42, 84,182, 53, 88,127, 49,129,129,129, 6, 0,225, 0,194, 75,110,246,252,255, 1, +198,152,154,136,166, 18,145, 49,130, 59,245,209,169, 53, 69,191,219, 68,235,110,152,158, 43, 35,122,149,108,201,198,205,230,174, + 43,235,220, 43,208, 76, 45, 99,227,230,178, 72,181, 82, 47, 21, 0,196, 34,193,179,210, 54,117, 22,139, 4, 21, 11,189,151,192, + 24,197, 2, 48,191, 50,244,108,216,176,241,207,192,172,193, 50,154,159,210, 40,173,206, 85, 89, 24, 12,134,101, 0,150, 89,123, + 93, 89,220,186,159,243, 13,128,111, 44,109, 95,184,230,106, 88,225,195, 44,134,231,183,173,190,183,208,208,208, 77, 0, 54, 89, +123,157,141,138, 17, 17, 17,241,255, 42, 42, 85, 30,140,177,141, 68,244,109,225,215,106, 75,207,149,104, 87,233, 27, 14,191, 34, +205,163,229,183,170, 60,189, 67,119,244,158,149,217, 95, 25,227,176, 69,180,108,216,248,143, 81,161, 8,150, 13, 27, 54,254, 89, +148, 99,158, 42,103, 67, 78, 27, 54,108,216,176, 97, 49, 4,160,179,185, 19,214,100, 7, 16,145, 89,141,178, 40, 79,223,166,105, +211,180,105,218, 52,109,154, 54, 77,155,230,127, 79,179, 60,109,211,235,137,104, 44, 99,204,226,153,170,127, 20,172,160,214,212, + 43,121, 0,232,108,211,180,105,218, 52,109,154, 54, 77,155,166, 77,211,166, 89,193,126,198,254, 21,253,188,138,135,101, 85,248, +108,216,176, 97,195,134, 13, 27, 54,108, 88,140,109, 13,150,133, 80,245,119,191, 0,216,140,130, 23,180,156, 61, 61, 48,239,239, + 29,209,191, 23, 34,242, 0,208,195, 81, 38,238,213,208, 69,220,250,214,243,252, 11, 74,173,225,103, 0, 7, 25, 99,229,238, 8, + 96,195,134,141,151,135, 92, 27, 86, 7,209, 72,128,253,153, 70,201,179,104,150, 21,179,189, 88, 59,151, 6, 35,192, 81, 67,147, + 67, 42, 48,108, 97,153,209,241,102,117,255, 76, 49,119,137,141,141,245, 15, 8, 8,136, 3,144, 85,162,217, 11,231, 88, 97,184, +162, 52, 77,143, 90, 77,135,218,201,236, 38,104, 52,154,154, 14,142,142,207, 50,158,167,109,202,120,122,115,131, 73, 51,167,203, +151, 47,123,183,108,217, 50, 9, 64, 78,121,154, 54,108,188,106, 94,218, 96, 81,221, 62, 53,161,231,134,129, 97, 48, 8, 81,236, + 81, 68,159, 10,233, 4,188, 95, 13,188,176, 5,128,166, 0,107,106, 47,151, 53, 81,105,180,207,120,198,134,178,216,221,215,173, +214,171,213,247, 23, 0,221, 75, 57, 59,159, 61,218, 51,207, 58, 69, 54,243,143,179,251,164, 46,118,132,128,102,239,125, 14,147, +138,203,255, 36,136, 72, 14, 96, 56, 17,189,105,103,103, 87, 55, 47, 47,239, 9, 99,236, 38,128,141,140,177,164, 10,106,114, 0, + 70, 57,216,219,119,243,119,148, 52,125,154,158,157,152,163, 51,156, 3,176,194, 90, 67, 68, 68, 18,127, 87,251, 51,171, 7,116, + 12,108,221,176, 14,248,232,179,200,215,104,123,157, 78,200,237, 53,247, 98,210, 20, 34,106,202, 24,211, 88,168,229, 13, 64,200, + 24,139, 47,124,109, 15, 32, 8, 64, 45, 0,143, 0,220,102,140, 41,203,144,176,164,143,127,133,166,175,175,175, 15,207,243,163, + 61, 61, 61,223, 73, 77, 77,253,133,227,184,173, 9, 9, 9, 21,250,121, 87, 34,155,141,235, 39, 44,125, 6, 48,206,154, 14,228, +114,121,106,126,126,126, 85, 0,144,201,100,207, 84, 42,213, 43,203,250,251, 43,251,250, 75, 32,140, 57,118,254,118, 55,211, 67, + 93,219, 53,124,177, 29, 71, 13,143,157,143,110, 95,188, 93,144, 1,102,222, 3, 11,171,166, 98,254,252,249, 20, 22, 22, 54,162, +118,237,218,117, 56,142,187, 55,103,206,156, 98, 37,108, 74,158,155, 59,119,238,159, 21, 87,205,104,250,214,107,115,176,255,128, +190, 29, 63, 28, 59,220,161, 90, 21, 7, 36,167, 43,221,191,222, 22,190, 50, 60,252,199, 30,163,251,119,233, 6, 0, 11, 22, 44, +120,183,122,245,234, 53, 4, 2,193,227, 47,190,248,226,251,178, 52,109,216,248, 43,168,144,193,162,134,125,237,145,207, 66, 1, + 26,222,161,117,179,118,227,134,246, 36, 38,144, 97,224,152,105,250,242,175, 46,161, 85, 99,132, 20, 2,213,194, 70, 65, 13, 39, +247,237,217,153,107, 30, 84, 3,222, 85,156, 1, 78,132,205,135,159,184,175, 91,254,197, 70, 0, 45, 43, 48,204,238, 15, 47,238, + 68,114,150, 1, 68, 0, 17,192, 17,144,155,207,163,235,187,195,230,194,106,131, 68,156,139, 29, 97,242,206,124, 0, 84,234,190, +110,127, 39, 68,212,180, 74,149, 42, 27, 38, 77,154,228,218,168, 81, 35,111,153, 76,102,167, 82,169,234,196,198,198,214,156, 61, +123,118, 23, 34, 90,202, 24,219,103,165,166, 95,128,175,207,158,117,147, 71,181,120,173,150, 63, 68,154, 92,240,106,101,245,251, +177, 15, 90,127,176, 49, 98, 12, 17, 13, 96,214,109,151, 48,107,243,196,161,129,193,142,128,246,246,239, 16, 9, 4,176,115,118, + 69, 23,161, 0, 2, 66,131, 97, 71,159,204,132, 5,251,177, 21, 86, 48,159, 89,240, 37,253, 40, 16, 8,142,119,238,220,185,230, +232,209,163,169, 89,179,102,136,140,140,172,181,115,231,206,206, 66,161,240,177,193, 96,184, 9,224, 30, 99,236,133,125, 36, 75, +209, 22, 1,168, 39, 16, 8, 26,253,147, 53,125,124,124,228, 26,141,102,152,175,175,239,216, 94,189,122, 53,234,217,179, 39,213, +171, 87, 15,119,239,222,109,118,228,200,145,185,141, 27, 55,190,153,144,144,240,141, 68, 34,217,145,148,148,164,178, 68,179,127, + 48,221,221,125,139,213,175,232,249, 18,247, 60, 22,128, 79, 97, 64, 99,190, 5,207, 73, 0,230, 51,198,202,170,131, 85,140,252, +252,252,170,198,207, 79, 34, 50, 91,175,170,178,176,166, 47, 34,138, 33, 34,183,194,175, 81,214, 51,199,113,208,235,245, 74,189, + 94, 95,187, 28,205,122,128, 85,203, 58, 24, 99,172,172, 2,206,114, 0,232,218,182, 97, 6, 8,209, 0, 0,158, 69,191,208,138, +103,209, 69,198,139,161,225,177,223,163,221,138, 69,189, 74, 48,127,254,124,154, 59,119, 46,230,205,155,215, 19, 64, 8,207,243, +231, 2, 3, 3,215, 22,147,228,249,162,115,115,231,206, 93, 51,127,254,124, 66,177, 93,111,255,196,173, 70,227, 33,239,189,215, +187,227,162, 89, 19, 29, 18,159,107, 17,245, 88, 5, 55, 7, 49,230, 78, 29, 47, 81,171,117,173, 55,126, 31, 62,118,253,210,105, + 91, 12, 6,195, 27, 0,154, 27, 12,134,171, 0,190, 47, 75,211,134,141,191, 2,139, 13, 22, 17, 17,106,247,105, 15, 3,134,251, + 87,247, 12,157, 52,186,159, 60, 40, 48, 0,249,112,192,147,116, 3, 14, 31, 58, 2, 0,187,173,233,156,106,245,111, 46, 20, 99, +199,242,121, 83,235,135,180, 8,194,173, 68, 29,174, 38, 26,144,247, 88, 7, 1,167,131,129,103, 0,131,249,173,231, 45, 32, 33, + 83,143,243,247, 52,224, 8, 16,112, 0,199, 17, 4, 21, 93,117,102,208,220, 95,176, 61, 50, 40, 61,149, 7, 12,154,251, 21, 29, +211,171,130,136,222,168, 91,183,238,234,176,176, 48,175,212,212, 84,183,171, 87,175, 66, 42,149,194,213,213, 85,232,227,227, 83, +127,245,234,213,217, 19, 39, 78,156, 74, 68,215, 25, 99, 79, 44,212, 12,236,222,188,209,133,111,150, 47,112,214, 93, 62,130,172, + 93,255,131,128, 99, 16,219, 59,160,166, 92,142, 35,239, 5,184,133, 30,122,188,143,136, 2, 25, 99,137,150,104, 6,120,185,119, +109, 20, 24,136,204,253,235, 17,149,153,143, 35, 73, 42,140,236,210, 10,193,110,114,132,232, 13,240,178, 23,189,129,114, 12, 22, + 17,185, 2,152,166,209,104, 56,177, 88, 76, 50,153,108,200,162, 69,139,180, 3, 7, 14, 76, 48,182, 9, 9, 9, 65, 72, 72, 8, +229,228,228,212, 58,117,234, 84,173,240,240,112, 61, 17,197, 48,198, 14,150,166, 43,151,219, 61,205,207, 87, 85,151,201,229,121, + 95,111,220,248,101,251,246,237,121,169,244,207,221, 91, 42,162, 9, 0, 46, 46, 46, 91,234,214,173, 75, 51,102,204, 72,170, 44, +205,154, 53,107, 30, 11, 9, 9,233,212,181,107, 87, 97,219,182,109,225,227,227, 83,116,206,195,195, 3, 33, 33, 33, 20, 31, 31, +255,218,185,115,231, 54, 30, 59,118,108,109,205,154, 53, 79, 61,126,252,184,107, 89,154, 0,192,202,217,131,180,188,243,197,218, + 22, 68,166, 96,133, 97,250,198, 76, 1,227,127, 37, 68,228,176,121,243,230,170,198, 61, 19,117, 58, 29, 12, 6, 67,209,179,241, +193,243, 60, 12, 6, 3, 22, 45, 90,100, 81,109,183,194, 72,167,209, 56, 24, 31,188,185,103,137, 68,226, 97,217, 96, 17,237, 45, +205,106, 96,111,111,239, 15,160,123,221,186,117,167,153,158,174, 83,165,224, 89,169, 84,198, 37,171, 93,162, 1,180,127, 65,227, + 79, 92,194,194,194,134,205,155, 55,175, 55,254,220, 83,178, 81,223,190,125, 79,149,104,215,168,240, 89, 73, 68,167, 57,142,251, + 25,192,118, 0, 47, 68,196,237,236, 28,198, 77,154, 48,218, 33, 33, 93,139,133,251,210,177,253,172, 2,195, 66, 28, 49,249,109, +103, 12, 26,216,223, 62,226,127,123,199, 1,216, 98,114,201,221,192,192, 64,186,115,231,142,205, 92,253,183,120, 29, 64, 21,147, +215, 26, 0,198,173,173,210, 81,240,119,225, 94,226,184,105, 59,227,115, 90,225,241, 42,133,215, 49, 19,221, 52, 0,127, 84,214, +128,133, 0,138,246,192, 42,115, 47,172,154,161,135, 71, 13,236,213,237,157, 55,219,128,147,185,226,254, 51,224,226, 83, 6, 33, +167, 3, 7,134,203,191,159, 98, 16,242, 59, 76, 47, 41, 43,178, 65, 53, 67, 63,109, 20, 28,180,108,235,242,143, 5, 49,207,132, +216,126, 46, 15,218,252, 92,164,165, 60,197,179,164, 56, 36, 39, 60, 66,226,211, 71, 55, 1,154,107,169,102, 73, 24, 3, 12, 60, + 10,254,231,227,129,130,239,227,139,183,103,145,166, 78,121,167,118,253,224,160, 76,137, 1,208, 41,239,148,223,119,229,111,130, + 89,154, 38, 17,117, 9, 8, 8, 88, 49,107,214, 44,223,219,183,111, 59, 41,149, 74,229,145, 35, 71,206,196,197,197,121,122,121, +121,197,143, 31, 63,190, 77,181,106,213,170,190,251,238,187,118,123,246,236,153, 5, 96,180, 5,154, 65,189, 90, 53,185,184,109, +237, 42,251,231, 17,235,160,137,189,129,195,201, 74,252,158,154,199,106, 57, 75,233,163,215,170,192, 65, 42,196,130,182, 62, 14, +221,247,199, 46, 3, 48,200,146,123,111, 88,221,187,182, 78,149,135,124,149, 14, 59,238,102,168,142, 39, 42,171,146,203,147,180, +181,161,173,100,130,180, 36,248, 59, 74,234, 88,115,239, 70,100, 50,243,187,156,184,186,186,162, 67,135, 14, 8, 12, 12, 20,182, +111,223,190, 17,128, 34,227, 82, 82, 83,171,213,120,243, 60,131,163,163,163,220,221,221,221,213,209,209,241,185, 86,171,125, 41, + 77, 0,112,115,115,235,211,161, 67, 7,225,206,157, 59,211, 31, 63,126,124,121,224,192,129,143,156,156,156,138, 69,123,237,237, +237, 81,167, 78, 29,124,241,197, 23,194,110,221,186,149,171,233,233,233,217, 37, 60, 60, 28, 68, 84,244, 97, 93, 18,127,127,127, +120,121,121,161,123,247,238,194, 62,125,250,116, 49, 61, 87, 82,179,127, 48,221, 53,154,167,126,193, 84,230, 7, 83,191, 96, 98, + 4,220, 43, 25,201, 42,169, 89, 24,193, 42, 86,157,188,172,105, 54,115,237, 45,248,185, 63, 51, 70,147,100, 50,153, 69,149,213, +203,209, 44,117, 90, 83, 42,149, 22, 69,157, 74,246,101, 78,147,227, 56,204,158, 61, 27, 68, 4,145, 72, 4,177, 88,108,246,185, + 99,199,142,214,142, 51,158,136, 56,177, 88, 60, 77, 40, 20,142, 86,171,213,190, 50,153, 44,201, 96, 48,124,167, 86,171, 23, 21, + 70, 64, 93,204,253,238,150,166,105,111,111,239,127,255,254,253,186,165,125, 83,212,106, 53, 26, 53,106, 4,168, 17, 83,150,102, +108,108,172,127,237,218,181,235, 1, 48,110,165,118,150, 49,214,222,228,181, 41,103, 25, 99,111, 23,126,125,239,225,195,135,254, + 40, 52, 88,166,154, 58,173,182,166,111, 85, 39, 68, 61, 81, 97,251, 89, 5, 78,206,242,193,155,139,146,240,126, 83, 33, 2,253, + 28,160,215,234,234,245,237,219,119, 7, 10,126,127,255, 0,240,110,223,190,125,235, 11, 4,130,223, 0, 28, 0,144, 93,214,189, +191, 12, 54,205,202,165, 28, 47, 82,133,136, 14,153,244,223,195,248,122,250,244,233, 51,151, 44, 89,114,155,136, 14,153, 30, 55, +109,103,250, 92,216,215, 33,198, 88,143, 25, 51,102, 4, 45, 93,186,116,177,177,109,101,222,143, 53, 83,132, 78,105,249,246, 56, +247,212, 9, 66,129, 1, 66,142, 32, 20, 0, 96,132,184, 39,177,200, 81,100,157,103,143,254,247,216, 18, 33,170,213,183,109,227, + 38,141,150,255,184,250,115,238,219,115,121,200, 82,230,227,206,245,211,248,227,244,129, 20,131,222,112, 0,196,174, 2, 92, 36, + 30,241,119, 25,171,120,213,238, 2,131, 85,104,170,138,153,172,255, 14, 68,244,118,253,250,245,151,204,158, 61,219,255,250,245, +235,142, 10,133, 34,237,135, 31,126,184,171, 86,171,175, 3, 88,243,244,233,211, 14,247,162,136,169, 0, 0, 32, 0, 73, 68, 65, + 84,107,214,172,177, 91,185,114,101,215, 70,141, 26,213,139,136,136,200,179, 64,243,181,169,195, 7, 93, 28, 61,233, 19, 89,204, +158, 13,144,196, 68, 98,246,141,116,195,201,228,188, 89, 0, 86, 35, 62,183,109, 90,190,254,248,170, 14,213,185, 26,142, 98, 4, +184, 72,204,127, 66,152, 65, 38,145, 10,153, 80, 6,141, 70,143, 28, 13,175, 97,140, 41, 67, 91, 4,106,153,189,135, 12, 0,132, + 28,149,251, 59,201, 24,203, 36,162,101, 18,137,100, 54, 17,177,215, 95,127, 61, 42, 56, 56, 56,215,213,213, 21, 42,149, 10,106, +181, 26, 98,177, 24, 42,149, 10,113,113,113,184,124,249, 50, 92, 93, 93, 45, 29, 34, 0, 32, 55, 55, 23,142,142,142,224,121,254, +165, 53, 13, 6, 3,109,218,180,201,254,246,237,219,246,123,247,238,245,156, 60,121,242,243, 6, 13, 26, 92,237,223,191,255,131, +170, 85,171,170,111,220,184,129, 11, 23, 46, 32, 51, 51, 19,173, 90,181,178, 72, 83,163,209, 64, 40, 20, 66,165, 82, 65, 42,149, + 66, 40, 20, 66,175,215,131,231,249, 34,211,149,155,155,139,140,140, 12,136,197, 98,104, 52,101, 47,107, 51,154,165,126,193,196, +246,252,122,225, 25, 12, 60,160, 85,232,160,206, 46,120,104,178,117,200,207,210,245,155,242,229,107,123,110, 89, 86,117,220, 24, +193, 50,165,172,105, 54,115,237,203,163,178,215, 65,149, 53,173,153,149,149, 37,119,113,113,153,102, 73, 68,142,136, 32, 16, 8, + 32, 22,139, 65, 68,104,223,190, 61, 70,141, 26,133,166, 77,155, 34, 54, 54, 22,187,118,237,194, 31,127,252, 1,145, 72, 84,212, +222, 82, 58,118,236, 40,144,201,100, 23,122,245,234, 21, 52,107,214, 44, 89,141, 26, 53, 16, 19, 19,227,183,116,233,210,105, 39, + 78,156,232, 77, 68,205, 25, 99,124,185, 66,198,169,191,130,105,193,238,106,181, 26, 49, 49, 47,248,167,178,174,121,129,128,128, +128, 56,142,227, 30,240, 60,127, 14, 64, 35,198, 88,123, 34, 58, 2,192,190, 68, 83, 37, 99,236,109, 34, 82, 0,184,201,113,220, + 61,158,231,227,204, 45,151,114,116,116, 76, 75,120,166,240,116,119,144, 97,104, 59, 7,188,185, 40, 9,161,205,165,144,138, 9, +119, 31,167, 32,160,118, 13,138, 58,127,176, 57, 10,204,213,235,201,201,201, 0,208, 28,192,227,248,248,120,111, 20, 26, 44, 27, +255, 13, 74,154, 32,163,113, 90,178,100, 73,143,146,199,204, 25,166,146,199,151, 46, 93,186,216,228,117,165, 38, 89, 21,125,152, + 17,149,253, 95, 43,120,188,127,104,223,206, 75,111,106,201, 63,168, 89, 59,252, 25, 13, 98,136,188,124, 1, 0,251,206,146, 14, +201,167,167,156,179,179,255,110,211,226,137,220,230,211,121,136, 79,122,134, 11,135,191, 67, 90,242,147,237, 0,155,204, 30, 69, + 40, 42,126, 59,133,125,212,234, 27, 84,213,195, 29,249, 90, 6,158, 1,120,193,100,253, 55, 32,162,158,245,234,213, 11,187,120, +241,162,127,126,126,190,227,239,191,255,158, 21, 30, 30,254, 64,163,209,108,101,140,253, 80,216,230,167,244,244,244, 5,140, 49, + 56, 58, 58, 10, 69, 34,145,188,172,133,159, 68,212,116,234,232, 97,231,151,109,218, 38,123,112, 43, 10,107,246, 30, 70, 86, 94, +158,225,244, 51,213,187,140, 49,227,127, 5,191, 5,184, 72, 19, 25, 88,117, 17, 71,240,182, 23,121, 17,145,140, 49, 86,238,116, +174,119,117,127, 78,231, 87, 19,231,244,249,168,230, 46,149, 0, 64,173,122, 13, 5,215, 85, 58,252,126, 35, 6, 30, 14, 78, 98, + 75,238,157, 49, 54,135,136, 60,119,236,216,193,233,116,186,220,216,216, 88,120,121,121,193,211,211, 19,206,206,206,184,115,231, + 14, 78,158, 60,137,187,119,239,130,231,121, 52,110,220,216,194,239,106, 1,207,159, 63,199,141, 27, 55,208,189,251, 59,147,211, +210,158, 57,185,186,185, 43,207,159, 59,187,178, 34,154, 60,207, 19, 0, 4, 5, 5, 33, 40, 40, 72,150,152,152,232,123,232,208, +161,170, 11, 23, 46,124,234,239,239,255,163, 74,245,231,242, 40,181,218,178,162,235, 70,195,148,159,159, 95,100,254,100, 50, 25, +196, 98, 49, 20, 10, 5, 82, 83, 83,145,147,147, 3, 0,112,113,113, 41,215, 96, 21,195,192, 3,225,237,174,190,112, 60,120,184, + 85,107,156,204, 69,164, 42,179,253,171,160,172,105, 77, 34, 26, 12, 96,154,153,203, 94,128,136,160,215,235, 33, 22,139,209,178, +101, 75,172, 91,183, 14,127,252,241, 7, 14, 28, 56, 0, 63, 63, 63, 12, 31, 62, 28, 28,199,225,246,237,219,214, 14,145,191,120, +241,226,180,119,223,125, 55,104,199,142, 29,178,184,184, 56,220,189,123, 23, 46, 46, 46, 88,183,110,157,116,236,216,177, 1,167, + 78,157,154, 3, 96, 69,121, 66,166,217,130, 62, 62, 62,253, 26, 53,106,244, 66, 27, 47, 47, 47,231,163, 71,143, 86, 53, 26,175, +146, 25,134,102,200,154, 51,103,206,170,192,192,192,213,133,211,130, 33, 0,236, 25, 99, 29,247,238,221, 75, 0, 16, 26, 26,202, +136,232,116, 97,251,155, 17, 17, 17,157,238,220,185,195,230,205,155,103,246, 61, 41,237, 89,242,166, 85,235, 54,175, 90, 54,127, +170,100, 74,119,103,132, 54, 23, 65, 38, 38, 56,217,137,176,104,237, 22,221,181,203,103,111,120,123,123, 31, 2,240,110,114,114, + 50,188,189,189,115, 1,220, 19, 8, 4,143, 13, 6, 67,146,109,141,251,191, 11,115, 94,164, 48,138,156, 92,248,181, 89,227,100, + 41, 37, 35, 92, 70,102,204,152, 17,180,100,201,146, 43, 21,213, 53, 71,209,138,164, 82,167, 6,141, 8, 57,111, 47, 79, 15,183, +233,195,219,130,231, 1,189, 1,208, 27, 24,148,121, 42,196,220,250, 35, 15, 50,218,107, 81,143, 82,201,242,133,179, 62,169, 21, +149,192, 33, 41, 83,139, 51, 7, 55,179,180,228, 39,125,216,163, 61, 35, 43,203, 92,121, 85,245, 56,189,115,243, 2,252,241, 72, + 3, 3, 95,224,175,120,158, 21,125,253, 95,128,136,234,120,120,120,172,188,116,233, 82, 13,169, 84,234,120,255,254,125, 67, 68, + 68, 68,146, 70,163,217,104, 52, 87,133, 12,110,214,172,153,206,222,222, 30,185,185,185,106,173, 86,155, 91,134,185,242,237,216, +244,181,179,203, 54,109,147,229,107, 52,200, 86,169, 33,112,175, 90,210, 92,129,136,218,116,170, 91,173, 26,201, 28,193, 0, 60, + 81,104,147, 44, 49, 87, 0,224,224,236,194,249, 54,239,136,230, 31,175,131,130, 28, 25, 0,184,123, 87,227, 58, 77, 88,132,110, +107,206, 64,201, 57, 90, 99,129,147, 6, 13, 26,148,208,176, 97,195,236,192,192,192,236,231,207,159, 35, 58, 58, 26,153,153,153, + 88,179,102, 13, 98, 98, 98,192,243, 5,114,230,166, 75,202,131,231,121,100,102,102, 56, 48,198,144,153,241,220,126,214,172, 89, +206, 21,209, 52, 24, 12,197,254,182,170, 85,171,134,241,227,199,139,243,242,242, 92,158, 62,125,234,100,122,206, 82, 77,141, 70, + 99, 44,194, 7,198, 24, 52, 26, 13,178,179,179,161,209,104,240,224,193,131, 34,115, 85,216,191,117, 6, 75,171, 48,191,200, 94, +245,220,162,197,247, 70,152, 73,245,101,185, 92,158,106,124,227,148,201,100, 32, 34,115,211,108,149, 82,173,217,216, 23, 17, 49, +185, 92, 94,218, 38,207,102, 41, 52,121,102,177,118,124, 6,131, 1, 98,177, 24,163, 70,141,194,149, 43, 87, 16, 27, 27, 11,129, + 64, 0,165, 82,137,188,188, 60,116,233,210, 5, 18,137,196,216,175,165,178, 76, 44, 22, 15,158, 57,115,166,236,241,227,199, 72, + 79, 79, 55, 46,146,135,193, 96,192,228,201,147,229, 82,169,116, 48,172, 12,213, 39, 37, 37,189,117,255,254,253,122, 37, 31, 41, + 41, 41,217,166,107, 6, 43,202,222,189,123, 41, 52, 52,148,133,134,134, 50,163,209,178,148,172,132,232, 77, 7,126, 58,116,252, +211, 47,150,231,230, 41,115, 80,219, 71,142,220,156,108, 44, 90,178, 76,119,241,226,185,211,211, 38,127,208, 58, 34, 34, 98, 41, +128,123,133,151,220,139,136,136, 24,246,197, 23, 95,124,143,194,114, 13, 54,254, 61,152,243, 34,166,127,123,149, 49,141,103, 78, +163,112,154, 80,254,178,218,166, 88, 52, 69, 72, 1,253,155,120,122,184,159,218,177,126,190,195,161, 91, 64, 66,252, 19,164, 37, +199,161,121,235,142,136,185, 21, 5, 94,103,216,199,238, 71,148,155,102, 78, 53,251,214, 13,108,208,112, 66,135,214,193, 88,126, + 40, 23,247, 35,143, 34, 43, 45,121, 61,123,188,199,170,204,182, 82,245,107,245, 13,242,172,226,113,250,251, 13, 97,110, 71,162, + 57,196,199, 63,193,193,239, 87, 67,167,125,225,179,255,176,181,218,114, 94, 35,201,205, 74,133, 38,199, 0, 25,151,103,126,193, +207, 95, 8, 99,236, 65,149, 42, 85,118,172, 90,181,234,131,214,173, 91,219, 13, 28, 56,240,126,102,102,230, 66,198,216, 30, 99, + 27, 34,122,163, 94,189,122,159,173, 95,191, 62, 32, 62, 62, 30, 39, 79,158,188, 15,224,197,200,196,159,154, 9, 2,129, 96,227, +201,239,183, 76,149,215,170,143, 53, 51, 63,213,239,253, 35,186, 23, 99,236,136,137,102, 96,231, 70,117, 15, 45,252,236, 67,142, +191,246, 43,110,196,165,226, 81,182,250,164,165,227,142,205, 82,234, 68, 82, 57, 28,188,106,224,126,174, 65, 44, 20, 10,175,140, + 30, 61, 74,204, 9,132,224,132, 98, 68,103,230, 91,243, 33,238,112,229,202, 21, 78, 32, 16, 20, 51,230,166, 17, 33, 35,150, 70, +134,172,193, 82,205,146, 6,203,136, 94,175,127,225,184,165,154,106,181, 26,230,124,178,185,181, 88, 60,207, 91,119,255,154,108, +243, 46, 47,223, 58,131,101, 26,145, 50,157, 26, 52,174,151,203,207,207,175, 42,151,203, 83,141,211,124,149, 21,193,122,153,204, +194,178,166, 41,173, 25, 31,199,113,224,121, 30, 98,177, 24,141, 27, 55,198,161, 67,135,224,230,230, 6, 39, 39, 39, 56, 57, 57, + 65, 46,151,195,221,221,189,200, 96,113,156,197,217, 55, 76,173, 86,251,249,249,249,225,193,131, 7,144,201,100, 69, 15,169, 84, +138,160,160, 32, 40,149,202,106,248, 79,197,234,129, 49,253, 59,247,222, 16,190,127,232,161, 67,191, 76,208,170,243,131,235,215, +175,199,174, 94, 60,117, 99,218,228, 15,186,149,127,181,141,255, 18,198,232,147,233, 90,170,233,211,167,207,172,168,222,244,233, +211,103,154,139,104, 85, 6, 66,224, 79,199,104,206, 57, 26,205,213,246,117,243,156,246, 95, 7, 18, 18, 30,227,248,158,181, 57, + 58,173, 38,147,231,117,254,143,238, 70, 1, 28,190,179,168, 55,142,181,232,221,189, 19, 29,191,173,129, 34, 43, 13,247,174, 30, +125, 2,149,100, 70,101,220,136,209, 92,237,216, 48,223,237,231, 91,132,248,248, 39, 56,178,107,117,182, 78,175,125,131, 61,138, +176,186,142,150, 41, 67, 36,146,222,253, 27,184,244, 24,213, 46, 9,134, 16, 3, 6,199,220,121,219, 39,132,122, 39,157, 43, 59, +211,235, 85,147,150,150,182,200,193,193,129, 91,177, 98,197,200,252,252,252,121,140,177,162, 40, 34, 17,117,169, 93,187,246,242, + 77,155, 54,249, 62,125,250, 84,114,254,252,249,140,211,167, 79, 51, 0, 75,202,210, 52, 24, 12,159, 19,145,160,105,141,106, 19, +175, 61, 73,236,197, 24,251,213, 68, 51,168, 71,179,134,191,111, 91, 50,199, 81,247,251, 94,228, 38,199, 99,198,239, 9, 10, 0, + 22,253, 12,137,200,205,195,195,131,134, 12, 25,194,231,228,228, 64, 44,145,240, 58,157, 78,208,166, 77, 27,195, 39,159,124,194, +165,164,164, 64,145,147, 43, 36, 34, 55,198, 88, 70, 57, 90, 97, 0, 38,183,105,211,134, 90,182,108,121,121,245,234,213,199,140, +231,204,153,137,138, 68,176,202,195, 82, 77,158,231,205,126,122,234,116,186, 23,254,222, 42, 18,193, 50,197,156,193,178, 58,130, +165, 46, 45,130,149,102,117, 4,203,156, 89, 49, 53,135,166, 6,168, 34,107,176, 42,155,178, 76,148, 53,227, 51,174,131, 19,139, +197,136,138,138, 66,245,234,213,161,213,106,225,232,232, 8, 71, 71, 71, 56, 56, 56, 32, 39, 39, 7, 34,145,200,170,245, 87, 0, +120,153, 76,246, 52, 58, 58,186, 94,149, 42, 85, 96, 48, 24,138,153,172,251,247,239,195,222,222, 62, 17, 86, 70,176,124,124,124, +142, 22,102, 17, 22,195,203,203,203,217, 26,157,210, 48,141, 92,133,134,134, 86,104, 30, 97,195,146,169,225, 0,194,251,246,237, +187,227,230,197, 95,154,123,123,123,255, 18, 24, 24, 72, 0, 96,203, 24,252,111, 80,150, 23, 1,144, 86, 34,242,164, 49,121,157, + 6,128, 10, 95,167, 21,106,148,252, 90, 99,230,216,243, 37, 75,150,156, 50, 89,191,149,134, 74,164,204, 8, 22, 5,244,111, 82, +213,221,237,212,214, 53,243,156,246, 68, 2,137,241,143,113,102,223,186,108,189, 65,251, 6,120,150,124,241,196,190,189, 32,228, +225,209,222, 51,192,158,178,164, 10,224,209,180,105, 3,127, 28,184,173, 67, 90,194,125, 48,198,111,103,169,223,151,187,232,186, + 60,140,230,106,251,186,121,110,251,163, 8, 9,241,143,113,124,207,218,108,189, 65,251, 70, 69,138,148, 26, 25, 77,228,202, 57, +218,125, 61,244,173, 22,125,253,107, 85, 3,207,116,224,197, 12,239,127,238, 33,188,119, 45,239,128, 95, 87,193, 30, 62,151,159, +144,112,241,239,171, 62,158,155,155,187,128,136,246, 51,198,138, 86,167, 18,209,219, 1, 1, 1,139,191,254,250,235, 26,137,137, +137,142,215,174, 93, 83,124,243,205, 55,143,121,158, 15, 99,140,149,155,105,197, 24,251,148,136,182, 50,147, 26, 58, 68,244,218, +212,145,131, 46, 14, 26, 49, 90,246,248, 68, 56, 92, 31,199,224,179,223,147, 12,247, 50, 53, 3, 25, 99, 41,229,105, 18,145,155, + 84, 42,221,123,248,240,225, 7, 77,155, 54, 37,165, 82, 9,157, 78,135,244,244,116,236,223,191, 63,154, 49, 6, 87, 87, 87, 28, + 62,124,152, 31, 52,104,208, 94, 34, 10, 45,205,100,153,148,105,160,194, 50, 13,173,126,253,245,215, 59,221,186,117, 75, 0, 94, + 52, 41, 82,169, 20,249,249,214, 85,251, 40, 45, 43,177, 34,154,165, 69,176, 74, 30,183, 70,211, 56, 77,105, 92,220, 94,242,184, + 17,129, 64, 0,158,231, 95, 56, 94, 38,234, 44,243, 70, 74,249,172,194, 17, 44,211,108, 63, 75,218,151, 69,121, 5, 63, 43,146, + 89,104,164,178, 34, 88, 0,138, 34, 88, 63,253,244, 19, 70,140, 24, 1,131,193, 0, 59, 59, 59, 56, 56, 56,192,222,222, 30,251, +246,237,131,177,140,131, 53, 67,212,233,116, 63, 44, 89,178,100,230,166, 77,155,228,140, 49, 72, 36,146, 34,131, 53,111,222, 60, +149, 86,171,253, 1, 22, 24,172,162, 10,237, 60,139,174, 83,165,236, 44, 66,115,215,148,178, 30,203, 37, 44, 44,108, 24,207,243, +189, 81,162, 20, 67,137,118,197, 74, 56,148, 85,166, 1,128,107, 88, 88,216, 24,158,231,141, 85, 80,139,101, 11,154,180, 51,126, +150,212,235,219,183,239,142,146, 89,132, 54,254,245, 84, 90,249,132,191,138, 82, 13, 22, 5,244, 13,172,234,238,113,106,203,234, +121, 78, 63, 94, 1,146,226, 31,225,194, 79,235,179, 13,188,206,212,180,180,179,170, 55,162,166, 62, 85, 93,144,113, 73, 5, 69, +250, 83,128,225,218,203, 12, 30, 0,168, 86,255, 58, 85, 61,220, 79,111, 91, 59,207, 45,226, 58,135,196,167,143,113,186,208, 4, +190,140,185, 26, 34,145,244, 14,170,235,187,109,192,219,237, 92,157, 73, 7,125,220, 29,108, 29,222, 15,145, 61,181,104,219,223, + 25, 45,186, 59, 34,160,137,172,223,225, 45, 25,111,250,132,208,232,191, 51,154, 85,194, 92,245,172, 81,163,198,252,203,151, 47, +251,243, 60,239,120,230,204,153,156, 77,155, 54, 61,202,207,207, 95,203, 24,251,197, 10, 77, 83,115,213,116,250,216,225,231, 23, +127,189, 85, 22, 29,249, 7,150,255,240, 51, 84, 58,141,225,104, 66,110, 95,211,233,195,178,144, 72, 36, 11,126,251,237, 55,251, + 70,141, 26,209,243,231,207,139, 34, 45, 90,173, 22,217,217,217,200,201,201,129, 90,173, 70,179,102,205,184,181,107,215,218, 79, +156, 56,113, 1,128, 9,150,142,215,209,209, 17, 98,177, 24, 90,173,182, 40,130, 37,149, 74,225,236,236,140,231,207,159, 99,247, +238,221, 0, 80,102, 84, 76, 44,150, 36,115, 28, 85,151,219,217,169,101, 50, 25,239,237,237,253, 66, 27,107, 53, 11, 73,120,251, +237,183,125,195,194,194,100,205,154, 53, 43, 58,104,140, 96, 85, 68,147, 49,150,215,181,107, 87,187,181,107,215,194,223,223, 31, + 26,141,166,152,145,226, 56, 14, 98,177, 24,241,241,241, 88,184,112, 33, 24, 99,150,255, 35,147,159,169, 67,163, 97, 85,160,122, +174, 43,120,164,235,144,247, 76, 7,109,158, 85, 25,189,166,102,197,212, 4, 21,174,145,122,193, 0, 89, 26, 33, 42,111, 10,208, +218,204, 66, 83,195, 38,149, 74,145,149,149, 37, 39,162,193,230, 74, 53, 88, 19,193, 50, 26,172,152,152, 24,236,216,177, 3,221, +187,119,135,171,171, 43, 50, 51, 51,177,103,207, 30,220,185,115, 7, 18,137, 4, 68,100, 77, 20,139,111,217,178,229,178,115,231, +206,245, 28, 56,112, 96,195,207, 62,251, 76, 30, 28, 28,140,123,247,238, 33, 44, 44, 44, 63, 50, 50, 50, 86,165, 82,133,193,146, +130,164,133, 21,218,141, 69, 68, 45,202, 34, 44,113, 77, 73, 74, 41,211,240,182,217,198,197, 75, 56, 20, 43,211, 96,202,133, 11, + 23,106,214,168, 81, 35, 16, 5,153,129,192,139,217,130,166,252,145,156,156,252, 58,108, 89,132, 54,254, 1,148, 30,193, 98, 52, +121,224,240,177, 78, 63, 92, 33,196,199,197,226,234,225,141, 37,205, 85,185, 16, 81,103,211, 90, 25, 50,185,125, 48, 79, 5,105, +201,138,244,120,128, 9,172, 54, 88, 37, 53,193,248, 79, 7, 14, 27,235,182,243, 42, 33, 41,254, 33,126, 63,184,193,106,115,101, +170, 57, 84, 34,153, 35, 18,114,179,222,105,223, 84, 28,210,164, 30,236,158, 61, 70, 74, 66, 18,118,199,164,101,196,102,170, 71, +255, 78, 90,196, 61, 84,111,237, 62,198,205,205,213, 75,132, 30, 31,184,187, 93,250, 89,113,160,218, 27,156,150,105,217,146,164, +243,108,158,217,113, 86, 2,229,105, 18, 81, 29, 39, 39,167, 21,145,145,145, 85,100, 50,153,211,213,171, 87, 13,155, 55,111,142, +207,207,207, 95,201, 24,219, 85, 65, 77,223,215,235,214, 62,179,120,195, 22, 89,174, 50, 15, 74,141, 22, 82, 79,111,195,254,139, +183,250,176, 82,138, 97,150,212, 36,162, 78, 35, 71,142,124,173,101,203,150,156,169,185,210,104, 52, 80, 40, 20,200,201,201,129, + 66,161,128, 66,161, 64, 98, 98, 34, 58,116,232,192,189,246,218,107,193, 68,212,137, 49,118,170,164,166, 73,153,134,153, 0, 56, + 34,250, 35, 42, 42, 42,183, 91,183,110,144,203,229, 80, 42,149,240,243,243,131, 94,175,199,225,195,135, 17, 25, 25,169,228,121, +254, 12,128,168,178,198,169, 82,229,249, 17, 17,167,202,203,107, 60,108,216,176, 14, 83,166, 76, 41,150, 90, 94,181,106, 85,184, +185,185, 89,165, 9, 0, 25, 25, 25, 13,126,253,245,215, 79,162,162,162, 62,237,222,189,187,243,204,153, 51,165, 53,107,214,132, +193, 96,224, 42,170,153,153,153,233,124,237,218,181,149,237,218,181,251,176, 91,183,110,194,197,139, 23,195,217,217, 25, 6,131, + 1,114,185, 28, 10,133, 2, 97, 97, 97, 56,127,254,188,158, 49,182, 33, 59, 59,251,179,178, 52,139,213,193,154,242, 85,153,233, +145,165,213,193, 50,243,115, 55, 27,241, 41,205, 0,153,107,255, 87,252, 29,149, 48,108,112,113,113,153, 6, 96,154,185, 82, 13, +150,106, 2,127, 70,176, 4, 2, 1,158, 60,121,130,205,155, 55,191, 80, 7,203, 88,198,193,156,118, 41,247,206, 78,159, 62,109, + 32,162,214, 87,175, 94,157, 54,116,232,208,209, 74,165,210,215,222,222, 62, 73,167,211,125,167, 82,169,140,117,176,204,102,227, +150,246,253, 84, 42,149,113,230,178, 8, 75,182, 1, 92,202,212, 44, 81,166,161, 88, 41,134, 18,151, 21, 43,225, 80,178, 76,131, +169,102,155, 54,109, 30,115, 28,119,183,112,170,253, 46, 74,100, 11,154,104,214, 75, 78, 78,126,221,219,219,251, 12, 0,187,146, + 89,132,127,199,123,178, 77,243,255, 55,101, 24, 44,200, 78, 92,126, 2,137, 60, 3, 55, 78,110,183,218, 92,153, 67,157,159, 23, + 59,103,231,211, 38, 26,117, 62,148,217,169,247,216,227, 93, 86,133,239,205, 66,176, 63,241, 71, 28,100,246, 89,184,126,226,219, + 44,131, 33,255, 13, 22,251,191,168,242, 47, 44, 77, 14,211, 55, 30,142, 16,147,179, 27,110,124, 50, 2, 73, 89, 74, 28,121,148, +185,135,229,169, 39,132, 23,238,187,231,219,154,206,109,155,149,178, 49,228,125,231,126, 30,213, 68,248,106,234,119,144, 77,119, + 23,183,120,179,253,223,186, 71,161,113,225,251,154, 53,107,198,135,132,132, 56,244,235,215,239,126, 70, 70, 70,177,133,239, 21, +208, 76, 32,162,175,127,217,244,229, 84,247, 70,173,176,254,139,207, 13, 59, 47,222, 42,150, 85, 88, 30, 98,177,184,227,244,233, +211,197, 74,165,242, 5,115, 85,210, 96, 41, 20, 10,220,184,113, 3,195,135, 15,151, 70, 69, 69,117, 4, 80,178, 2,180,113, 92, +115,136,104, 19, 10,246, 34, 76, 9, 15, 15,111,125,240,224,193,214,147, 39, 79, 22,119,239,222, 29,151, 46, 93,194,241,227,199, +181, 90,173,246, 34,128,139,204,194,237,103, 88, 65,253,160,107, 68,116,107,249,242,229,173, 5, 2,193, 28,227,185,232,232,104, +108,223,190,189, 34,154,122, 0, 43,137,232,235,240,240,240, 57, 39, 78,156, 24, 57,108,216, 48, 39,157, 78,135,152,152, 24,124, +251,237,183, 21,213,252,164, 74,149, 42,179, 15, 31, 62,252,221,177, 99,199,222, 29, 50,100, 8, 55,105,210, 36,172, 91,183, 14, +255,251,223,255,120,131,193,112, 80, 36, 18, 13, 75, 75, 75, 43, 55, 1,165, 88, 29,172, 50,234, 92,149,119,190,196, 24,191,161, +130,237,111, 44,222,139,208,146, 72,206,203, 76, 1, 90, 56,110,139,183,234, 41, 13,227,125,116,236,216,177, 40,170,200, 24, 43, +182,110,206,104,172,172,157, 34, 4,224, 82,248,123,186, 1,192, 58, 20,175,226, 46,192,159,149,222, 45, 85,108,152,172,118,137, +134, 26, 49,101,111,246,236, 2, 48,152, 15, 93,253, 73,214,156, 57,115, 86,205,157, 59,119, 85,201, 82, 12,166,141, 74,150,112, +152, 63,127, 62, 74, 43,211, 0, 32,115,206,156, 57,203, 0, 32, 48, 48,144, 10,167, 5,155,163, 48, 91,208, 68,115, 71,225,113, +187,121,243,230, 13, 5, 80,150,166, 13, 27,175,156, 50,214, 96,177,153,209,231,118,234, 0,184,131,184, 25,236,225,110,179,133, +229,172,129,241,108,250,111, 63,206, 91, 7,134, 76,102,208, 91, 84, 79,166, 92,120,193,172,232,115, 63,242, 0,185,128,184,233, +236,225,255, 94,122,156,228,236,134,156,176,241,248,223,237, 36,150,162,212,189, 23,174,209, 20,139,212, 20,174,185,234,239, 19, + 66,187, 93,125, 68,251, 63,121,195,157,126,201, 24,250,178,221, 86, 10,105,105,105,139, 29, 28, 28, 4, 43, 87,174, 28,169, 82, +169,138, 45,124,175, 40,140,177,207,137, 72,208,162,142,255,196, 43, 15,226,122, 91, 58, 45,104,132,136, 36, 62, 62, 62,183,242, +243,243, 65, 68, 80,171,213, 69,198, 42, 39, 39, 7,217,217,217, 69,175,181, 90, 45,210,210,210,224,231,231, 7, 34, 42,179, 38, + 86,137, 15,194,179, 68, 20, 25, 22, 22,214, 62, 44, 44,172, 49, 10,162, 64,103,173,154, 26, 43,174,173, 3,112, 86, 46,183, 75, + 34, 34, 95,177, 68,170,188,112,225,194,137,151,212,204, 67, 65,100,228,171,175,190,250,106,145,189,189,253,235,209,209,209, 39, + 95, 70,179,208, 60,245,113,119,119,247,217,177, 99, 71,196,182,109,219, 90, 9,133,194, 75, 68,212, 55, 43, 43,203,234,205,158, +169,120, 68,192,234,243, 37, 24, 7,203,246, 32, 52,125, 46,151,202, 46, 46,250, 42, 12,155,193, 96,200,157, 61,123,118,145,150, +241,222, 74, 70,171,140,175,181,218, 23, 83,157,205, 81,222, 58,182, 18,148, 99, 46, 40, 23, 0, 10,246, 22, 44,216,254,198,210, +205,158, 1,148,186,183,229,220,185,115,217,252,249,243,137,227,184,131, 0,238,113, 28,247,160,228, 34,116,211,115,243,231,207, +199,220,185,115,217,188,121,243, 74, 29,169, 81,243,206,157, 59, 76, 32, 16,156, 4,240, 88, 32, 16, 60, 49,213, 53, 61,110,188, +166, 44, 77, 27, 54, 94, 53,165, 26, 44,246, 40, 34, 30,192,136,202,236,140, 61,142, 56, 1, 43,246, 50,179, 72,243,201,174, 56, + 0, 67, 42, 77, 15, 88, 49,166, 69,199,169, 40,248, 47,240,171,146,230,202,148,164,115,236,160,119, 91, 90,210,226,205,246,147, + 81,112,193,226,202, 26,199,203, 96,110,225,251,203, 98,110,225,187,165, 24, 12,134, 99,114,185,156,148, 74, 37, 84, 42, 85,177, +104,149, 66,161, 64, 94, 94, 30,114,115,115,139, 22,167,231,230,230, 26,167,187,172,250,239,179,208,164, 28, 33,162, 99,140,177, + 10,239, 0, 96,138, 74,149, 87, 29, 0,136, 72, 80, 89,154,133,137, 6,163, 43, 83,243,249,243,231, 73, 0,218, 4, 4, 4, 72, + 98, 99, 99,173, 72, 25, 44, 78,121, 27, 57, 91,186,209,179,145,202,136, 6,189,106, 42,219,176, 1,128, 86,171,109, 80,217,154, +140, 49,107,204,173, 37,130,223,118,109,215, 80, 0,211,218, 63,229,109,246, 12, 0,160, 92, 48,124, 91,202, 24, 25, 21, 56, 72, + 6, 96,199,195,135, 15,253,121,158,143, 51, 19, 73, 42,118,110,222,188,121, 96,230,210, 98, 95,212, 4,128, 3,241,241,241, 62, + 6,131, 33,185,132,110,177,227,101,105,218,176,241, 87, 96,205, 86, 57,255, 47,248, 94,163,153,139,114, 54, 27, 54, 37,249,119, + 54, 11,192,172, 87, 55,162,138, 81,153,230,202, 68,211,106,115, 5, 0, 58,157,238, 55, 0,168, 82,165, 10,170, 84,169, 82, 94, +115,211,235, 42,210, 29, 42,203,180,252, 27, 53, 95,198, 92,217,248,255, 5,203,140,142, 7,240, 69,185,237,202,175,222, 94,188, +253,159,166, 38, 19, 64,102, 41, 30,167,172,115,101,105, 2,128, 2,128,194,204,181,165, 29,183, 97,227,111,193,170,201,127, 27, + 54,108,216,176, 97,195,134, 13, 27,229, 67, 0, 58,155, 59, 97, 77,118, 0, 17,153,213, 40,139,242,244,109,154, 54, 77,155,166, + 77,211,166,105,211,180,105,254,247, 52,203,211, 46,153,141,204, 42,105, 27,173,191, 28, 99,102,203,171,120, 0,232,108,211,180, +105,218, 52,109,154, 54, 77,155,166, 77,211,166, 89,193,126,198,254, 21,253,188,138,135,109,138,208,134, 13, 27, 54,108,216,176, + 97,163,146,177, 45,114,255,151, 66, 68,117, 0,204, 4, 96,186, 87,216, 21,198,216,146, 18,237,126, 4, 96,103,114, 72, 9, 32, +140, 49,246,192,154,254, 4, 2,193,146,246,237,219, 79, 56,127,254,252,151, 58,157, 46,172, 2,227,245,247,246,246, 94, 70, 68, +205, 0,136,136,232, 97,106,106,234, 18,157, 78, 87,225, 66,117, 68, 84,203,203,203,107, 41,128, 38, 28,199,137,136, 40, 54, 53, + 53,117,161, 78,167, 43,185, 45,135, 53,154,142,158,158,158,109, 25, 99, 94, 0, 4, 34,145,232,121, 98, 98,226,101, 86,193,108, +184,190,243,239,136, 21, 74,189, 8, 0,156,236,133,186,136,185,129, 90, 75,143, 85,244, 30,108,216,176, 97,195,198,223, 79,153, + 6,107, 64, 61,242, 54, 8, 33,140,136,102,241, 64,193,135, 15,128,198, 0,234, 0,120, 0, 32,138, 49,150,243, 50, 3,248,183, +104,254, 3,153,195, 24, 27,100,122,192, 92, 29,161, 55,222,120,163,215,177, 99,199,236,140,219,168,240, 60, 15,185, 92,174, 7, + 48,220,210,142,136,168,234,192,129, 3,167,111,221,186, 21,253,250,245,155, 77, 68,171, 24, 99,185,150, 94,239,230,230, 22, 90, +171, 86,173,117, 91,182,108,169,210,170, 85,107,146, 72, 36,120,248, 48,214,119,220,184,113,193,158,158,158, 7, 83, 83, 83, 71, + 91,170,101,196,221,221,125,112,237,218,181,191,218,188,121,179, 71,187,118,237, 64, 68,136,140,140,244,253,228,147, 79, 26,123, +121,121,237, 74, 73, 73,249,208, 90, 77, 15, 15,143,186,181,107,215,238,180,126,253,122,121,219,182,109, 33,147,201, 16, 21, 21, +229,240,193, 7, 31,120,121,121,121,197,164,164,164,156,177, 70,175,239,252, 59,226,155,145, 63,191,171,215,170,151, 3,128, 80, + 44,253,188,245, 42,197,207, 25,145,103,123,150,119,172,239,124, 28,176,153, 44, 27, 54,108,216,248,247, 82,170,193, 10,109, 72, + 97, 16, 98, 38, 0,122,187, 14,237, 58,254, 88,112,174, 75,151, 46, 1,163, 70,141,162,166, 77,155, 34, 50, 50,178,238,174, 93, +187,222, 17, 10,133,177, 6,131, 33, 18,192,109,102, 97, 21,106, 34, 18, 1, 8, 18, 8, 4,205,254,201,154,255,112,236, 1,128, +136, 82, 1, 92, 41, 60,118,165,100,163,223,126,251,237, 39,161, 80,104,140, 96,181, 80, 42,149,158, 40, 30,245,178,132, 26, 58, +157, 14,119,239,222, 5,199,113, 34, 0, 53,241,226,214, 23,102, 33, 34, 95, 95, 95,223,141, 23,175, 68,186,147, 80,142,204,124, + 0,249, 90, 72, 28, 60,177,117,123,184,219,148,143, 63,236,227,228,228,116, 78,161, 80,124,111,233, 96,136,168,166,159,159,223, +170, 27, 55,110,184,219,217,217,129,231,121,228,228,228,192,203,203, 11, 91,182,108,113,153, 50,101,202, 32,185, 92,126, 90,165, + 82,253,207, 10, 77,199,218,181,107,119,186,117,235,150,220,184,209,179, 70,163,129,175,175, 47,126,252,241, 71,233,164, 73,147, + 26, 72,165,210, 4,181, 90,253,200, 82, 77,133, 82, 47,210,107,213,203,119,108,152, 87, 29, 0,134,125, 56,111,185, 36,199,233, +176, 37,199, 20, 74,253, 47, 0,108, 6,203,198, 95, 10, 17, 53,243,240,240,216,155,158,158,126, 6,192,104, 86, 9,165, 68,136, +200, 71, 40, 20,214,100,140,185, 20,190,206,210,235,245,143, 25, 99, 86, 23,194, 53,226, 17,208,169, 39,164,118, 35,192,248,198, + 28, 0,226,184, 40,131, 54,111,123,250,189, 83, 63,191,148,166, 68, 62, 18, 96,141, 57,128, 39,142,187,193,235,243,182,164,221, + 57,101, 85, 97,101, 27, 54,140,152, 53, 88,125, 27,146, 43,128,105,187,214,205,228,132, 2, 1, 13,252,120,201,160,109, 27, 86, +114, 93,122,246, 45,154, 38, 9, 9, 9, 65, 72, 72, 8, 45, 95,190,188,206,201,147, 39,235,252,248,227,143,122, 34,186,193, 24, +219, 93, 90,103,221, 2, 72,197, 3,178,119,234, 11,149, 3,191,248,126,115,203,150, 45, 33,149, 74,241, 50,154, 0,208,181,142, +224, 81,247,150, 1, 55, 6, 78,156, 19,215,170, 85, 27, 86, 25,154,255, 34,174, 48,198,122, 3, 0, 17,185,250,249,249,181,213, +235,245, 50, 0, 16, 10,133,249, 0, 38,178,194, 45,126,136,232, 32,207,243,189, 44, 21, 38, 34, 14,192,220, 94,189,122,205,254, +232,163,143,224,231,231,135, 73,147, 38, 65,167,211, 69, 18,209, 28, 0, 75, 89,225, 42,196,210,168, 90,181,234,156,141, 27, 55, +186, 9, 37,246,104, 58,237, 49,146,179,244, 0, 0, 7, 41,240,211,120,134, 73,147, 38, 57, 93,189,122,117, 33, 0,139, 13, 86, +213,170, 85,195,182,108,217,226,102,103,103, 7,198, 24,114,115,115,145,147,147,131,220,220, 92,228,230,230,226,195, 15, 63,116, +138,137,137, 89, 6,192, 98,131,229,233,233,217,118,253,250,245,114,153, 76,134,220,220, 92,177, 86,171,165,156,156, 28,228,229, +229, 49,141, 70,163,157, 56,113,162,244,246,237,219, 29, 1, 88,108,176,108,188, 90,136, 72, 0,224, 61,145, 72,244,126, 64, 64, + 64,243, 7, 15, 30, 92,215,235,245,251, 0,236,123,217,127,162,136,232, 77, 31, 31,159, 69, 73, 73, 73,235, 25, 99,225,149, 51, +226,127, 62,158,158,158,251, 46, 92,184, 80,125,227,198,141,195,191,252,242,203,195,176,226,111,168, 36,133,255,244,182,110,209, +162,133,199,251,239,191, 47,242,242,242, 66, 94, 94, 30, 98, 99, 99,237, 78,156, 56, 81, 69, 38,147, 61, 87,171,213, 22,111, 15, + 5, 0, 30,245,218, 58, 64,232,180,171,117,167,206,237,250,245,121,207,209,211,221, 25, 42,141, 1, 15,226,146,253,126, 61,252, + 83, 7,159,224,119, 46,104,181,217, 3,210,239,253,110,113,132,221,168,217,169, 91,143,118,157,223,124,211,209,217,197, 25,217, + 74, 45, 30, 62, 73,244, 63,117,252,231, 16,239,224,119,206,242,164, 27,146,122,243, 88,133,118, 91,176,241,255, 23,139, 23,185, +219,217,217,153, 61,238,236,236,140, 78,157, 58, 97,201,146, 37, 66, 0,205, 76,207,177,146,155,159, 2,210, 67,155,102,192,217, + 94,202,249,249,249, 57, 58, 57, 57,189,180,102,193, 65,190,102, 27, 63,246,246, 31,223,207, 28,126,226,199,175,130,148, 57, 89, +162,146, 77, 28, 28, 28, 80,175, 94, 61,204,158, 61,219, 50,205,151,228,175,214,244,246,246,174, 31, 18, 18,210,236,183, 51,103, + 92,146,146,146,164, 73, 73, 73,210, 99,191,253,230,210,186,117,235,102,222,222,222,245, 77, 52,172, 25,231,130, 13, 27, 54,204, + 57,120,240, 32, 23, 18, 18, 2, 87, 87, 87,116,234,212, 9,135, 15, 31, 22,126,249,229,151,139, 1,204, 46,111,156, 28,199,181, + 11, 9, 9, 33, 48,134,148,108, 61, 46, 47,169,143,168,149,129,200,201,103,200,200, 86, 64,165,202,135,157,157,157,172,112, 90, +215,210,123,111,211,186,117,107, 2, 80,100,170,114,114, 10, 30,185,185, 74,104, 52, 90, 72,165, 82, 71, 34,146, 89,170,201, 24, +243,106,219,182, 45, 0, 64,171,213, 22,205,181,102,101,101, 81,118,118, 54, 52, 26, 13, 68, 34,145,152,136,202,156, 86, 55,213, +116,178, 23,234,132, 98,233,231,195, 62,156, 23, 63,236,195,121,241, 66,177,244,115,141,163,194, 96,201, 49, 39,123,161,206,156, +102,101, 81,158, 38, 17, 85, 17, 8, 4,223, 6, 4, 4,196, 8, 4,130, 29, 68,228,245, 50,154, 68,244, 58, 17, 45,182,179,179, + 59,209,160, 65,131,120,123,123,251,223,136,104, 41, 17,181,174,136, 38, 17, 73,236,236,236,126, 91,188,120,113,196,245,235,215, +251,157, 60,121,178,230,205,155, 55,251, 44, 95,190,124,151,131,131,195, 57, 34, 50,255,134, 85,206, 56,141,212,172, 89,115,219, +229,203,151, 95,111,211,166,205, 86, 34,146,150,215,222, 18, 77, 34, 18, 16, 81, 19,178,112, 79,160,191,250,231, 78, 68, 62, 77, +155, 54,173, 46,147,201,208,185,115,103, 0,232,248,146,154,173, 63,248,224, 3,175, 41, 83,166,136,162,162,162,176,117,235, 86, + 28, 60,120, 16,207,158, 61, 67,143, 30, 61,196,111,188,241,134,151, 84, 42, 53,251,243, 47, 85, 83,232,180,235,227, 79, 38,119, +155, 58,105,140,227,141,167, 90,108, 63,241, 20, 7, 46, 38,227, 89,158, 4, 61,251, 12,115,126,171,119,255,183, 36, 82,103,179, + 27,219,151,165, 57,125,218,180,110, 99, 71, 14,114,140, 78,230,241,211,165, 20, 92,186,155, 13,189,200, 5,221,251,140,118,109, +220,182,219, 59, 66,136,190,179,242,222, 43,204,255,103,205,255, 26, 69, 31, 22, 68,196, 24, 43,216,196, 53, 34,154,101,134, 54, +164,101,253, 63, 90, 60,155, 56, 98, 53,130,218, 68, 87,171,221, 80,233,238,238,142,188,188, 60,168,213,106,136,197, 98,228,231, +231,227,233,211,167,184,116,233, 18, 92, 93, 93,173,234, 88,161, 80,192,193,193, 1, 14, 14, 14,149,162, 57, 99,120,103,233,195, +248, 52,233,209, 75,167, 59,172,153,240,191, 86,181,155,116,188,249,102,255, 73,183,156,170,248,228,223,188,121, 19, 23, 46, 92, + 64,102,102, 38, 90,182,108,105,213, 56,255,193, 92, 41,124,159,190, 66, 68,174, 33, 33, 33,190, 71, 79,156,117,205,205,231,157, +158,164,234, 68, 60,207,195,206,206, 91,191,123,239, 79,217,253,250,244, 36, 34,122, 6,224, 74,161,169,125, 97, 42,209,148, 66, + 99, 82, 63, 52, 52,116,250,132, 9, 19, 16, 27, 27,139, 49, 99,198,168,174, 92,185,242,188, 77,155, 54,238, 91,182,108,145, 79, +153, 50, 5,103,206,156,153, 75, 68,251, 1, 60,102,140,153,221, 75,141, 49, 38, 22,139,197,208, 23,218, 5,173,129,135,209,215, + 43, 20, 10, 48, 85, 38,196, 98,177, 0, 64, 21, 0, 22,173,147,227,121, 94, 44, 18,137,138,204,213,211, 84, 5,158, 62,203,131, + 34, 87, 3,149, 74, 15,141,138, 65, 96,231, 46, 4,158,120, 2,120, 98,137, 38, 0,129, 76, 38,131, 94,175, 71, 78, 78,193, 48, +140,145, 49,141, 70,131,236,236,108, 8, 4, 2, 7, 0, 78, 0, 50, 44, 17, 44, 88,188,142, 3,133,211,125,248,227,135, 94, 30, + 15,126,153,161, 13,157, 23, 83,116,204,201, 94,168,219, 59,165,129,192,221,183,241,249, 38,253,190, 11, 52, 30,251, 59,215, 95, + 17,145,180, 74,149, 42,167, 34, 34, 34, 26,212,169, 83, 7,143, 31, 63, 14,236,219,183,111, 75, 34,106,194,172,220, 51,145,136, +236, 56,142, 91, 54, 98,196,136, 9, 3, 7, 14,164,186,117,235, 66, 40, 20, 66,175,215,251,198,198,198,118,218,179,103,207, 52, +161, 80,184,197, 96, 48,124,106,233,186, 62, 34,226, 36, 18,201,238,205,155, 55,183,111,217,178, 37,118,236,216,129, 43, 87,174, +240,175,191,254, 58, 55,116,232, 80,248,251,251,183, 28, 58,116,232, 1, 34,234, 94,145, 72, 22, 17,249, 15, 30, 60,184,186, 64, + 32, 64,155, 54,109,196, 23, 46, 92,104, 10,224,130,181, 58, 37, 52, 29,124,125,125,207,116,236,216,177,201,137, 19, 39,174, 17, + 81, 71,107,214, 49, 18, 81,111, 31, 31,159,229,206,206,206, 22,191, 41, 42, 20,138,188,196,196,196,207,152,229,251,145,182,106, +214,200, 78, 9,201, 0, 0, 32, 0, 73, 68, 65, 84,172, 25,226,226,226, 80,191,126,125,136,197,226,214, 68, 52, 14, 64, 55, 0, +179,152, 21,187, 67, 16,145, 79,235,214,173, 61, 58,118,236, 72, 75,151, 46, 5, 0,136, 68, 34, 24, 12, 6,112, 28, 7,145, 72, +132,192,192, 64,122,244,232,145, 27, 17,249, 88, 50, 93,232, 17,208,169,103,155, 55,187,181,107,223,242, 53,238,203,189, 15, 96, +224, 13, 16,144, 30, 66,226,193,235,164,144,138, 5,168, 27,212, 92,112,247,246,141,150, 30,245,186,244, 76,191,119,188,220,233, + 66,143,128, 78, 61,187,245,236, 21,210,160,126, 93,110,205,129,135,200, 74,140, 49, 36,222, 57,155,206, 9, 56, 52,104,246,134, + 71,221,134, 77, 4, 77, 90,118, 20, 37, 61,190,221,201,173, 78,135,206, 25, 15,206,216, 76,197, 43,198,212,139,252,219, 41,245, +191,241,189,209,108,142,147,132,106,238,217,179,147, 75,203,209, 42, 99, 99, 99,225,225,225, 1,111,111,111, 56, 59, 59, 35, 58, + 58, 26,191,253,246, 27,238,221,187, 7,158,231,209,184,113, 99,171, 58, 78, 79, 79,199,141, 27, 55,224,234,234, 90,105,154,181, +171, 87,193, 71,213,171,136, 83,159, 43,196, 39,174,220,107,249,205,140, 62, 13,185,192, 62,219,242,243,255,252,236,215,104,254, + 27, 59,137,152,102, 11,250,249,249,181,221,190,125,187, 88,173,135, 99,221,113, 23, 87, 40,243, 13,246, 0, 96, 47, 19, 40, 35, +151,215,251,116,193,130, 5,202,145, 35, 71, 6, 62,125,250,116, 73,233,138, 5, 72, 36,146, 69,111,191,253,246, 84,198,152,232, +227,143, 63, 6, 0, 12, 27, 54, 76,113,233,210,165,186,140,177,103, 68,228, 51,106,212,168,251,167, 78,157,178,155, 60,121,178, + 64,175,215, 71, 11,133, 66, 70, 68, 97,140,177,121, 37,245, 56,142,187,122,237,218,181, 26, 62,254,245,224,239,206, 33,100,118, +193,118,106,238,118, 60, 18,158, 60,196,157,155, 87,224,229,229,229,236,237,237, 29, 83,191,126,125,109, 98, 98,226,180,220,220, +220,141,101,141, 81, 44, 22, 71, 69, 70, 70,122,251,251,251, 35, 55, 55, 23, 9,105,121,152,180,207, 14, 10, 85, 65,208, 66, 4, + 21,154, 84,175,231, 40,231, 52, 87, 60, 61, 61,181, 26,141,230,139,172,172,172, 50,183,251, 16,137, 68,207,111,222,188,233,224, +231,231,135,252,252,124,150,145,145, 65, 74,165, 18, 57, 57, 57,244,203, 47,191,188,155,156,156,252,122,205,154, 53,201,215,215, + 55,172, 78,157, 58,170,196,196,196, 49,150,172,241,138,152, 27,168, 37, 34,131, 80, 40,252,114,236,216,177,253,246,239,223,127, +117,239,188, 6,189, 25, 99, 90, 0, 32, 34,231,160,160,160,163,175,189,214,208, 39,124,101,163,181,140,177, 21,229,105,254, 5, +140,152, 57,115,102, 3, 55, 55, 55,124,240,193, 7,152, 63,127, 62,230,204,153, 83,231,131, 15, 62, 24, 11, 96,149,165, 34, 68, + 36,247,242,242,250, 99,205,154, 53,129,109,219,182,197,225,195,135,177,115,231, 78, 60,122,244, 72, 95,179,102, 77, 97,203,150, + 45, 49,119,238, 92,188,245,214, 91, 99, 38, 78,156,216,129,136,154, 90,104, 58, 70,206,157, 59,183,119,187,118,237, 48,124,248, +112,245,233,211,167,251, 1, 56,118,252,248,241, 55,206,156, 57,179,247,135, 31,126,144, 47, 94,188,184,243,148, 41, 83, 62, 0, +176,174, 2,247,255,110,251,246, 5,123, 27,183,107,215, 14,203,151, 47,127, 11, 47, 97,176,136, 72,226,238,238,254,203,142, 29, + 59,154,212,171, 87, 15, 67,134, 12,105,218,175, 95,191, 95,136,168, 11, 99,204,162, 55,164,106,213,170, 45, 59,120,240, 96, 64, +105, 51, 9,230, 80,171,213,110,239,189,247,222, 82, 0, 86, 25,172, 31,127,252, 17,159,125,246, 25, 26, 55,110,252, 90,171, 86, +173, 54,141, 27, 55, 14,161,161,161,111, 18,145, 39, 99, 76,105,137,144, 80, 40,172,217,163, 71, 15,209,190,125,251, 0, 0,237, +219,183, 71,231,206,157,113,235,214, 45,156, 63,127, 30, 2,129, 0,246,246,246,104,219,182,173, 36, 41, 41,169, 38,128,114, 13, + 22, 39,181, 27,209,187, 71,119,199,159, 46, 37,195,192,235,209, 60,192, 9, 45, 3,171,226,110,130, 2,145, 49, 9, 48,104,196, +112,114,115, 71,235, 14, 93,221, 82, 18, 31,141, 0, 80,254,122, 44,169,221,136,247,123,191,227,240,211,197, 36,100, 37,221, 97, + 15,174,236,255, 77,151,175, 28, 3, 0, 87, 79,238,218,228,229, 46,239, 82,183, 89,115, 65,199, 46,189, 92,247,237, 76, 25, 1, +192,102,176,108, 88, 76,153,211, 29, 57, 90,164,190,249, 78, 31, 92,187,118, 13, 0,240,252,249,115, 60,127,254, 28, 1, 1, 1, + 88,183,174,248,251, 86, 69,140, 11,207,243,149,174, 9, 0,158,238, 78, 24,210,189,133,240,252,141,157, 50,101, 90,154,204,193, +193,161,200, 97,253, 87, 12,150, 41,122,189, 94, 86,179,102, 77, 40, 84,160,236, 60,157, 67,250,174,130,200,190,199,128,211, 14, + 26,141,134,115,112,112,128, 90,173, 46,115,186, 12, 40, 88, 51,209,187,119,239,169,187,119,239, 22,221,185,115, 7,181,107,215, +134, 86,171,197,165, 75,151, 18, 88,193, 6,197, 96,140, 37, 9, 4,130, 36,158,231,235, 52,110,220, 24, 75,150, 44, 65, 96, 96, + 32,117,239,222,125, 90,161,201,226, 77, 53,147,147,147,151,141, 27, 55,238,141, 61,123,247,187,109,238,175,130, 34, 91,129,220, +220, 92, 68, 93,191,138,140,212,124,124,243,205, 55,144,201,228, 4, 64,252,236, 89,170,120,242,228,201,107,125,125,125,187, 37, + 36, 36,244, 40,109,156, 73, 73, 73,139, 62,252,240,195,214,187,118,237,114,201,201,201,129, 74,149,143, 12,165, 29, 98, 86, 23, +236,175,219,224,147, 24,108, 88,191,145,107, 84,195,222, 35, 47, 47, 15, 19, 38, 76,248,202,199,199,167,109, 82, 82,210,168,210, + 52, 19, 19, 19, 47,127,244,209, 71,158, 63,252,240,131, 76,163,209,104, 13, 6, 3, 84, 42, 21,183,107,215,174,105, 53,106,212, +112,221,178,101, 11,201,100,242,194,182, 9,226,241,227,199,239,246,242,242,250, 33, 37, 37,101,120, 57,223, 83,129, 64, 32, 88, + 29, 30, 30, 62,180,127,255,254,142,201,201,201, 13, 15, 30, 60, 40, 5,160, 42,108,226,221,165, 75,151, 26, 43, 87,174,172, 18, + 20, 20, 52,141,136, 68,140,177,191,117,211,112, 15, 15,143,137,189,123,247,198,210,165, 75,241,243,207, 63, 79,113,115,115,251, +106,254,252,249,240,241,241,249,136,136, 86,151,183,238,206,132, 21,171, 86,173, 10, 12, 12, 12,196,176, 97,195, 52, 39, 78,156, +152, 9,224, 0,128,184,115,231,206,249,125,247,221,119, 61,119,239,222,189,116,205,154, 53,178,117,235,214, 5,244,233,211,103, + 53,128, 82,127, 70, 70, 60, 61, 61, 39, 15, 28, 56, 16, 43, 87,174,196,233,211,167,251, 48,198, 14, 23,158, 58, 66, 68, 61, 23, + 47, 94,124,114,246,236,217, 88,181,106,213,199,176,210, 96, 17,145, 67,131, 6, 13,190,232,214,173, 27,206,157, 59,135,144,144, + 16,180,110,221,122, 10, 17,173,101,140,165, 91,163, 85,168,199, 57, 56, 56,236,222,190,125,123, 72,141, 26, 53,176,112,225, 66, + 76,157, 58, 21,219,182,109, 11, 25, 50,100,200,110, 34,122,191,228,223,140, 57,156,157,157, 29,236,236,236, 48,109,218, 52,246, +232,209,163,204,242,218, 87,175, 94,221,245,171,175,190, 34, 87, 87, 87,139, 18, 90,136, 72, 46,147,201,218, 4, 7, 7, 99,238, +220,185, 56,126,252, 56,102,207,158,141,224,224, 96,196,197,197, 97,192,128, 1,118,179,102,205, 10, 5, 96,209,190,132,140, 49, +103,119,119,119, 60,123,246, 12, 34,145, 8,109,219,182,197,129, 3, 7,160, 86,171, 81,181,106, 85,100,101,101,161, 69,139, 22, + 0, 0,161, 80,104, 97,210, 13, 11,246,112,115,198,179,219,137, 16, 66,143,102,117, 61,112,234,214,115,104,117, 60,170,186,187, + 32,229, 89, 42, 90, 5,251, 66,163,241, 3, 99,124,176, 37,138, 18, 1,215, 76, 42,147, 35, 35, 39, 29,137, 49,167,159,107, 13, +234,113, 89,143,206,199, 3,128, 91,237,246,227,174,158, 63,126,181,239, 59,237,171,230, 42,171,131, 24,223,194,178,113,218,176, + 81, 64,185,107,176,204,189,151,230,229,189, 56, 75,240,178,198,229, 85,104,154,227,191,104,176,140, 24, 55, 71,214,232,120,104, +116, 5,239,217,106,181, 26, 42,149,170,172,203,138, 96,140,233,142, 30, 61,186, 99,210,164, 73,248,234,171,175,112,255,254,125, +136,197, 98, 4, 7, 7,123, 19,145, 3, 80, 16,113,105,214,172, 89, 85,142,227,112,247,238, 93,124,249,229,151, 24, 57,114, 36, +187,112,225,194, 54,115, 31, 20,140,177,235, 25, 25, 25,235,199,141, 25,153,149,153,250, 20, 58, 85, 38,158, 37, 62,132, 90,153, +133,133, 75,150, 33, 79, 39, 68, 74,182, 22, 41,217, 90,112, 82, 55,108,218,178, 93,208,160, 65,131,110, 66,161,176, 84,131,197, + 24,187,148,154,154,186,101,252,248,241, 89, 41, 41, 41, 69,247,167,209, 49,104,116,197,127, 95,237,236,236,176,122,245,106,231, +186,117,235,246, 22,137, 68,157,202,208, 76,142,143,143,191, 51,126,252,120, 77,106,106, 42,178,179,179,241,211, 79, 63,245,172, + 81,163,134,235,210, 21, 95,145, 82, 43, 68, 74,150, 22, 41, 89, 90, 72, 28,170, 98,247,222,253,130,122,245,234, 13, 18,137, 68, +165,174, 33, 50,154,171, 31,126,248, 97,104,255,254,253, 29, 87,172, 88,145,113,240,224,193, 13,140, 49,211, 31,200,221,213,171, + 87,239,217,189,123,119,206,212,169, 83,221,150, 47, 95, 62,133,136,102,150,250, 67,122,197, 16, 81,167,254,253,251,215,231,121, + 30, 17, 17, 17, 55, 25, 99,171,246,239,223,255,135, 90,173,198,128, 1, 3,106,162, 96,186,200, 18,157,215, 7, 13, 26, 52, 33, + 36, 36, 4,159,124,242,137,246,196,137, 19,205, 24, 99, 95, 49,198,158,176, 2,226, 24, 99,107,207,156, 57,211,120,226,196,137, +234, 22, 45, 90, 96,248,240,225, 35,137, 40,164, 28,221, 54, 3, 7, 14, 12,228,121, 30,187,118,237,186, 97, 98,174, 0, 0,140, +177,223,246,238,221,123, 73,163,209, 96,240,224,193,181,136,232, 13, 43,238, 93, 44,149, 74, 35, 22, 44, 88,224,146,152,152,136, +161, 67,135,170,239,222,189,139,121,243,230,201,157,157,157, 15, 27,255, 6,172, 65, 42,149,126,243,245,215, 95,247,110,212,168, + 17,198,143, 31,175,217,184,113,227,164, 9, 19, 38,104,154, 53,107,134, 13, 27, 54,244,150, 72, 36, 86,109, 1,146,148,148,148, + 21, 29, 29,237, 94,222, 35, 33, 33, 33,213,194,123,182,115,116,116,188, 24, 20, 20,164, 8, 14, 14,110,174,215,235, 17, 29, 29, +253,112,199,142, 29,124,112,112, 48,214,175, 95,143,229,203,151,163, 71,143, 30, 16, 8, 4,161,214,140, 85,169, 84, 66, 38,147, + 65, 44, 22, 35, 50, 50, 18,106,181, 26,118,118,118,144,201,100, 16, 8, 4,112,113,113,129,163,163, 35, 0, 88,100,216,137,192, + 20,121, 58,136, 68, 28,132, 28,143, 59,113,217,208,234,120,200,196, 2,136,132, 4, 48, 30, 46,246, 34,200, 36, 2,112, 68,229, +154,214, 66, 77,100, 43,181,144,136, 57,136,196, 18,226,244, 6,185,241, 28, 39, 52,200,229,114, 9,121, 56, 73, 33, 19,219,106, +114,219,176,158,114, 11,141,242,252,139,191,167,230, 76,138, 90,173,126,169,129,188, 10, 77,115,230,240,101, 53,255,137, 8,133, +194,252,123,247,238, 73,156,220,125,120,119, 71, 81,102,141,145,231,157, 1,192,205, 65,152,173, 53,232,248,164,164, 36, 72,165, + 82,179,107,164, 74,146,159,159, 63,134,136, 22, 2,104, 40, 20, 10, 15,109,223,190,157,194,195,195, 93, 7, 14, 28, 24, 75, 68, +137, 65, 65, 65,254,219,183,111,119, 2,128,181,107,215,178,221,187,119,191,133,130,210, 23, 41,165,105,166,164,164,204, 19,137, + 68, 23, 62,252,240,195,117, 18,137,196,213,222,222,222,253,220,185,115,148,175,101,120,125,102, 92, 81,102,161,147,156,195,217, + 25, 78, 24, 59,118,172, 32, 38, 38,102, 9,128, 67,101,104, 78,147, 74,165,231,238,223,191,255,149,179,111,147, 42,246,254, 51, +157, 91,206,184, 11, 0,240,247, 16,129, 43,124, 63,204,202,202, 66, 90, 90, 26, 38, 76,152,224, 26, 27, 27, 59, 13,192,169,210, + 52, 19, 18, 18,206, 72,165,210,132,219,183,111,119, 20,137, 68, 18,123,123,251,215, 47, 94,188, 72,249, 26, 30,175, 77,139, 67, + 70,110,193, 56,221, 28,132,184,186,192, 19, 31,125,244,145,240,193,131, 7,203, 0,180, 51,167,199,113,220,114, 83,115,245,249, +231,159, 71, 1,168, 69, 68,197,166, 64, 13, 6, 3, 13, 30, 60,248, 22,128,224,169, 83,167,186, 49,198,166, 16, 81, 6, 99,108, +115,105, 99,125, 85, 56, 57, 57, 45, 29, 55,110, 28,118,239,222,141,204,204,204,213, 0,160, 80, 40, 86,253,248,227,143,187,198, +140, 25,131,239,191,255,126, 41, 17,253,106, 65, 20,235,237, 1, 3, 6,224,200,145, 35, 56,121,242,228, 23,140,177,104,115,141, + 24, 99,247,137,104,218,193,131, 7,215, 12, 28, 56, 16,223,126,251,109, 55, 0,231,202,208,237,242,214, 91,111,225,240,225,195, +120,254,252,249, 6,115, 13,178,178,178, 54,254,244,211, 79,173,222,122,235, 45, 44, 89,178,164, 11,128,223,202,187,111, 34, 10, +116,118,118,222,190,102,205,154,215, 27, 53,106,132, 65,131, 6,229,107,181,218,110, 83,167, 78,253,121,231,206,157,142, 59,118, +236,104, 62,118,236,216,203, 68, 52,154, 49,118,169, 60, 61, 0, 16, 8, 4,139,215,173, 91, 55,170, 99,199,142,152, 50,101,138, +254,232,209,163,189, 24, 99,199,136, 40,246,243,207, 63,255,229,203, 47,191, 20,172, 92,185,114,148, 64, 32, 72, 51, 24, 12,127, +151,169, 94,176,118,237,218, 86, 93,187,118,197,195,135, 15,113,233,210, 37,104,181,218,239, 47, 94,188,120,182, 78,157, 58, 11, + 52, 26,205,207,246,246,246,195, 28, 29, 29,131,154, 52,105,242, 6, 17,217, 89,178, 14,143,136,178, 98, 99, 99,237,171, 86,173, + 10,145, 72,132, 27, 55,110,160,106,213,170, 0,128,103,207,158, 33, 56, 56, 24, 2,129, 0, 89, 89, 89, 0,144,109,201, 64,137, +184,155,177, 79,146,106,185, 57,218, 3, 6, 25,174,223, 77, 64, 21, 15, 87, 24,136, 67, 74, 74, 50,154,212,247, 5, 17, 33,235, +121, 10,136,232,150, 37,154, 6,198, 71, 62, 77,122, 86,205,221, 81,138, 70,173,186,186, 95,252, 53, 45,220,185,118,187,177, 66, + 1, 9,164, 50,167,205,163,134, 15,247,224,121,134,172,231,169, 16,114, 92,153,107, 87,109,216, 40, 73,145, 45, 47,109, 81, 89, +193, 98,233,226,243,254, 37, 77,138, 76, 38, 43,138,158, 88,138,105, 41,133,202,210, 44,143, 87,161,249,119, 65, 68, 51,136,232, + 32, 17,205,136,143,143,191, 51,106,212, 40,173, 94,171,206,185,176,176,214,244,107, 75,106,140,191, 56,207,123,252,129, 73,206, +211,243,178, 51,114,214,174, 93,171,139,143,143,191, 99,122, 77, 89,218,140,177,167,140,177,195,223,125,247,221,198,136,136, 8, + 4, 7, 7, 35, 58, 58,186,170, 82,169,108,122,235,214, 45,183,192,192, 64,132,135,135, 99,247,238,221, 95, 49,198,142,151,101, +174,140,232,116,186, 19,201,201,201,245,226,226,226, 2, 92, 92, 92,116, 46, 46, 46, 40,153, 89,168, 80,241,120,158,149, 13, 55, + 55,119, 56, 57, 57,213, 44, 79, 83,173, 86, 31, 78, 78, 78,174,203,187,214,111, 95, 55,125,117,118,228,226,234,136, 92, 92, 29, +135,167,249,192,219, 69,130,204,204, 76,164,165,165, 33, 45, 45, 13, 68, 4,157, 78,215,192, 2,205, 71, 73, 73, 73, 91,159, 62, +125,122,208,211,211, 19,142,142,142, 96, 0, 82,178,116,136, 90, 25,136,168,149,129, 72,201,210, 65,145,147,131, 26, 53,106,192, +209,209,209,236, 84, 4, 17,113,213,170, 85,235,222,191,127,127, 71, 0, 40, 52, 78,111, 50,198,198,155,121,124,160,215,235,219, + 26,219,126,246,217,103,110, 0,222, 42,111,172,149, 73, 97,134,219,135, 99,198,140,105, 46,147,201,176,126,253,250, 71, 0,126, + 40, 60, 29,177,113,227,198,187, 0, 48,105,210,164, 32, 0, 83, 10, 75, 36,148,138, 88, 44,110,214,160, 65, 3, 92,188,120, 17, + 0,246,151,211,253,222, 11, 23, 46,160, 78,157, 58,144,201,100,175,151,211,182,102,245,234,213,113,247,238, 93, 0,184, 94, 74, +155,235,119,239,222, 69,245,234,213, 65, 68,229,254, 30, 17, 81,239,174, 93,187,222, 60,117,234,212,235,109,218,180,193,168, 81, +163, 52,151, 47, 95,238,206, 24, 59,123,253,250,245, 78,131, 7, 15, 86,214,173, 91, 23,103,206,156, 9, 28, 60,120,240, 5,129, + 64,176,208, 2,205,145, 97, 97, 97, 51,222,125,247, 93,132,133,133,177, 61,123,246, 12, 98,140, 29, 3, 0,198,216,209, 93,187, +118, 13, 93,180,104, 17,123,255,253,247, 49,127,254,252, 25, 68, 52,190, 44, 61,165, 82,153,109, 48, 24,160, 84, 42, 45, 10,193, + 91,218,222,195,195,227,237,174, 93,187, 98,246,236,217,168, 86,173, 26,126,254,249,103, 6,224, 16, 99,236,156, 90,173,110,207, + 24,251, 82,169, 84, 30,184,120,241, 34,186,116,233, 34, 6,240,142, 37,253,235,245,250, 39,167, 78,157,210,186,187,187,195,215, +215, 23,126,126,126, 80, 42,149,200,202,202, 66,112,112, 48, 90,181,106, 5,165, 82,137, 67,135, 14,105,179,178,178, 44, 74, 68, +209,107,148, 59,142,255,178, 47,219,221, 81, 10,223,170,206,168, 81,205, 13,185, 89,233, 72, 75, 73, 66,179, 6,126,232,208,172, + 6,210,179, 53, 56,122,104, 95,102, 78, 78,222, 14, 75, 52,117,234,188,237, 39,126,253, 57,219,213, 81,140,122,245,131, 48,120, +212,164, 38, 77,154,182, 60,222,162, 69,219,163, 43,150, 46,126,237,205,214, 13, 40, 33, 61, 31, 71, 14,237,207,204, 86, 40, 44, +154, 30,181,241,114,252, 87, 22,184, 3,229, 79, 17,166, 79,153, 50, 5, 82,169, 20,222,222,222, 69,166,200,104, 82, 36, 18, 9, +188,189,189,161,215,235,177,107,215, 46, 0, 40,115,141, 2, 7,168,123,141, 95,194,171,117, 44, 79, 36, 18, 85,138, 38, 0,112, + 28,167,238,243,249,183,252,175, 23,204, 39,185, 84, 68,243, 95, 64,139,194,154, 86, 45, 24, 99,153, 79,158, 60, 73,232,215,167, + 87,118, 92,236,237, 20,101, 86, 82,178,226,121,124,114,252,163, 91, 41, 51,167, 77,201, 78, 72, 72,136, 47,172,133,213, 34, 41, + 41,169, 23, 0, 75,215, 18, 76,233,215,175,223,215, 99,198,140, 97, 81, 81, 81, 0,128,200,200, 72, 12, 31, 62,156, 13, 29, 58, +116, 53,128,233, 21, 24,183, 82,165, 82, 21,139,126,104, 13,124,209,212,158, 66,161, 64, 82, 82, 18, 52, 26,141,197, 78,248,254, +209,149,247, 50,158, 92,213, 5,249,219, 35,200,223, 30,129,213,237, 64,250,220, 34,115,149,150,150,134,212,212, 84, 0,176, 40, +138, 87,136, 66,173, 86, 23, 27,167,233, 20,164, 66,161, 64, 74, 74, 10, 12, 6,131,217, 15, 48,198, 24,159,152,152,120,116,247, +238,221, 57, 0,176, 98,197,138, 12, 34, 58, 73, 68, 95,155,121,108, 18, 10,133,191, 27,219,174, 92,185, 50, 3,192, 97,115,186, +175, 2, 34,122,183, 81,163, 70,153, 51,102,204, 88,255,241,199, 31, 99,211,166, 77, 72, 78, 78,158,206, 24,211, 27,239, 37, 61, + 61,253,243, 13, 27, 54, 96,196,136, 17,152, 51,103,206,202,166, 77,155, 42,136,104,112,105,154, 85,170, 84,241, 21, 10,133,184, +118,237,154,130, 49,246,176,172,254, 25, 99, 41,215,174, 93, 75, 37, 34,120,123,123,215, 46,171,173,155,155, 91,128,163,163, 35, + 18, 19, 19, 1,224,113, 41,205,158, 36, 37, 37, 49,137, 68, 2, 31, 31,159, 58,229,220, 62, 92, 93, 93, 63,223,186,117,171,240, +246,237,219,120,243,205, 55, 19,206,156, 57,211,133, 49,118,186,112,108,215, 34, 35, 35, 67, 58,117,234,116,239,248,241,227, 88, +182,108, 25, 53,110,220,184, 76, 51, 4, 0,254,254,254, 31,140, 28, 57, 18,235,214,173,195,230,205,155,199, 51,198, 34, 74,220, +243,206, 13, 27, 54, 76,218,188,121, 51, 70,141, 26,133,154, 53,107,150,250,189, 4,128,184,184,184,105, 29, 59,118,140,188,127, +255,190, 69, 59, 20, 88,210,158,136, 58,181,108,217, 50, 64,165, 82, 97,251,246,237, 15, 3, 2, 2,254,136,136,136,152,194, 24, +187, 81,162,233,129,125,251,246, 97,200,144, 33,104,220,184,241,118, 34, 26, 88, 94,255,140,177,164,184,184,184,244, 27, 55,110, +240, 2,129, 0,190,190,190,232,222,189, 59, 6, 12, 24,128,198,141, 27,227,217,179,103, 56,123,246, 44, 31, 27, 27,155,110, 73, + 6, 33, 0,164,223, 59,245,243,227,199,247,126,191,118,249,172, 78, 40,224,224,231,237,134,247, 58, 55,193,232,208,182,104, 22, + 88, 13,113,207, 84,248,237,183,227,186,199,143, 31, 94,180, 36,131,208,168,121, 39,250,198,133,219,215,206,235, 69, 66, 66, 96, +253,186,152, 61,243,115,215, 69,115,167,185,212,173,237,135, 27,143,178,113,252,216, 17, 93, 82, 66,252, 41, 91, 6,161, 13,107, + 41,111,138,112,197,166, 77,155, 90,108,221,186,181,203,148, 41, 83, 28,134, 13, 27, 6,153, 76,134,188,188, 60,248,250,250,194, + 96,248, 63,246,206, 59, 60,138,226,225,227,223,185,222, 47,245,238,210, 8,132,146, 78,239,189, 24,122, 19, 4, 4,193,242,162, + 20, 5, 81, 65, 4, 69, 84, 4, 65,154, 20, 17, 65, 81,148,166, 96, 9, 29, 84, 4, 4,169,161, 37, 49, 4,210,123,114,233,229, +146, 92,219,121,255, 72,194, 47,196,148, 75, 65, 16,231,243, 60,243,220,221,236,238,103,103,246, 46,119,223,108,153,181,226,248, +241,227,184,122,245,106, 33,199,113,191,160,202,229,255,132,144,160,202, 99,101, 28,143,162,178,178,193, 43, 13,221,130, 39, 78, +108, 18, 39, 0, 40,239,114,234,172, 22,198, 93,155,246,159, 27,191,231,196, 53,242,218,148,254,188,206,190,205, 0, 0, 58,157, + 14,106,181,186,222,206,198,242, 79, 56, 43, 31,190, 77, 77, 77,189, 77, 8,201,120,233,165,151,252, 42, 78,104,151, 72, 36, 37, +137,137,137, 17,229,225,234,111,203,212,213,206,242, 43,221, 94, 38,132, 28,204,203,203, 59,241,230,155,111, 98,197,138, 21, 56, +116,232, 80, 95, 74,233,121, 91,219, 89,197,105,245,242,242,202,189,124,249,178,174,141,127, 39,180,212, 10,209,239,221, 59,160, +148,194, 73, 78, 81,144,155,141,235,215,175,161,160,160,224, 82,125,218,233,230,230,150,155,145,145,225,172,213,106,145,157,157, +141,204,204,204,123,225, 42, 39, 39, 7,217,217,217,148, 16,242, 71, 61,156, 69,173, 91,183, 54, 68, 68, 68,136,117,205,218,160, +149, 86,132,238,111,223, 6, 40,133,167, 35, 15, 5,249,185,184,112,225, 2,242,242,242, 78,215,228,228, 56,110,254,212,169, 83, +249, 0,158,125,243,205, 55, 29, 1,116, 88,184,112,225, 47, 85,175, 20, 20, 10,133,159,236,218,181,171,109,197,161,196,183,222, +122,107, 61,165,244, 75, 91,218,217, 80, 42, 59,157,156,156,230, 31, 57,114, 68,101, 50,153,176,105,211, 38,172, 95,191,126, 7, +165,244,190, 43, 36, 41,165, 71,248,124,254, 22, 30,143,247,202,156, 57,115, 48,115,230, 76,121,151, 46, 93,222,192,255,246,114, +221,231, 76, 78, 78, 94,210,185,115,231,165, 25, 25, 25, 54,157,176,127,231,206,157, 25,157, 59,119, 94,146,145,145,177,186,166, +118, 2,128, 66,161, 80, 88,173, 86,196,198,198,230, 80, 74,171, 61,180, 68, 41, 45,241,246,246, 78,182, 90,173, 30,114,185,220, +177,182,190, 3, 64, 78, 78,206, 71, 93,186,116,121, 63, 61, 61,253, 36,128,229, 85,135, 28,161,148,222, 32,132, 4,206,155, 55, +111,238,170, 85,171,198,167,165,165,253,109,156,165,170,206,248,248,248,143, 6, 14, 28,248,110,100,100,228,206,154, 14,245, 82, + 74, 63, 37,132,152,118,237,218, 53, 59, 54, 54,246,111, 87,248, 86,118, 82, 74, 15,163,150, 67,230,213,184,171,157,191,178,147, +207,231, 47, 92,181,106, 21,239,243,207, 63, 7,165,116,173,197, 98,169,169,157, 55,249,124,254, 55,189,123,247,126,110,255,254, +253,210,192,192,192,153, 0,246,214,212,247, 10, 74, 75, 75, 47,254,249,231,159, 61,226,226,226,156, 7, 14, 28, 40, 2,202,254, + 49,201,205,205,197,225,195,135, 77, 81, 81, 81,153, 69, 69, 69,213, 30,110,173,201,105, 49,230, 79,249,243, 84,240,222,184, 59, +161, 61, 7, 12, 27,235, 96, 52,121, 64,146,197, 71,110, 86, 26,142, 31,254, 49, 39, 54, 54,250,130,193,144, 91,109, 0,172,201, +105, 42,205,155,124,225,247,131,251,146, 98, 35,122,244, 27, 56,194,161,196,216, 28, 18, 17, 15, 89,233,201, 56,126, 36, 56, 59, + 54, 54,230,143, 18,115,233,243,245,113, 54,134,255,178,243,177,131, 82, 90,103, 1, 32, 2, 16,164, 84, 42, 87, 44, 93,186,116, +237,165, 75,151,214,142, 26, 53,106,173, 68, 34, 89, 1, 32, 8,128,168,134,229,130,254, 73,103, 87, 55, 56, 14,108, 69,206, 14, +105, 77,184, 89,125, 29,172,207,119, 87, 24, 7, 13, 26,180,165, 49,206,134,150, 7,237, 4, 16,108, 54,155, 41,128, 52, 0,193, +229,101,113, 53,203, 44,174, 52, 61, 45, 33, 33,129, 2, 8,174, 79, 59, 1, 56, 63,253,244,211, 92, 65, 65, 1,157, 52,105, 18, + 5, 96,215,152,190, 75, 36,146,129,253,250,245, 51,167,235,179,233,237,152,100,122, 49, 36,156,158, 56,245, 39,221,247,227, 17, +186,121,203, 54,218,190,125,123, 35,128,230,245,113, 10, 4,130, 65, 3, 7, 14,204, 74, 79, 79,167, 17, 17, 17,244,236,217,179, +244,192,129, 3,116,219,182,109,116,235,214,173,180, 89,179,102,233, 0,116,245,113,202,100,178,177,195,135, 15, 55,231,230, 27, +104,108,114, 22,189, 21, 17, 75,207, 95,190, 69,143,159, 58, 79,119,239,221, 79, 3, 2, 2, 74,234,114, 2,224,243,249,252,205, +251,246,237,203,167,148,210,177, 99,199, 38, 1,144, 86,154,222,114,254,252,249, 25,148, 82,186,122,245,234, 44, 0,111, 63,132, +207,210, 48,119,119,247,219, 34,145,232, 8,128,103,235, 88,110,178, 64, 32, 56,228,226,226,114, 5,192,184,127,178,157,229,175, + 71,105,181,218,139, 0,198,212,177, 92,197,124, 79,254,211,219,243,223,226, 4, 48, 72, 32, 16,156, 69,217, 24, 87,117, 45, 39, + 2,240, 33,159,207, 63, 10,224,137,250,180, 19,128,155, 82,169,236,163, 84, 42, 71, 43,149,202,209,246,246,246,125, 0,184, 53, +166,239, 78,222, 65,163, 61, 59,141,249,185, 89,135,145,241,158, 29, 71,197,123,117, 30,251,179,147,119,208,232,198, 58,155,119, + 30, 27,236,217,113, 84,130,103,199,209,113, 45,187,142,253,217,217, 55,104,248,227,246,190, 63,202,206, 26,214, 51,227,159, 88, +207, 3,105,123, 61, 59,170, 0, 48, 14,192,202,242, 71, 69, 99,223,128, 7,225,236,225, 10,159,160,214, 36, 98,132,175, 32, 27, +192,132,166,112, 54,224, 67,241,160,191, 28,119, 26,141, 70, 90, 82, 82, 66, 13, 6, 3, 45, 44, 44,188, 47, 56, 85,154, 47, 56, + 37, 37,133, 38, 37, 37,209,132,132, 4, 26, 23, 23, 71, 1,236,174,111, 59,213,106,245,151, 19, 39, 78,180, 10,133,194,205, 77, +209,119, 71, 71,199,149,221,187,119, 55,109,220,184,145,254,252,243,207,244,139, 47,190,160,115,230,204,161,109,219,182, 45,181, +183,183,159,210, 16,167,139,139,203, 18, 95, 95,223,172, 29, 59,118,208,221,187,119,211, 13, 27, 54,208,119,222,121,199,234,225, +225,145,166, 82,169,134, 54,196,169,213,106,183,247,233,211,199,180,125,251,118,250,203, 47,191,208, 61,123,246,208,249,243,231, + 83, 63, 63,191, 82,133, 66,241,148, 45, 78, 0,124,129, 64,176,110,214,172, 89,105,110,110,110, 71,170, 76,147, 7, 4, 4, 92, +153, 58,117,106, 10,128,183, 30,151,207, 39,115, 50, 39,115, 50,103, 19,173,231, 95, 27,176,234,188,138,176, 50,180,108,144,185, +159, 8, 33,135,104,249,249, 25,141,229, 65, 56, 47,164,208, 72, 0,126,132, 16, 65, 83, 57, 31, 65, 62, 18,139,197, 2,148,223, +244,185,156,234,174,114,185,236,230,230, 86,249,117, 30,128,122,143,179,148,151,151,247, 34, 33,228, 85,122,255, 16, 3, 13, 38, + 43, 43,107, 49, 33,228,187,152,152,152,149,246,246,246,157,205,102,179, 57, 63, 63,255,108, 78, 78,206, 91,148,210,164,134, 56, + 83, 83, 83,151, 19, 66, 14, 46, 89,178,228, 77, 74,105, 55, 30,143, 87, 98, 54,155, 79,103,102,102,174,164,148,234, 27,226, 76, + 79, 79,159, 33, 18,137,190,138,138,138, 90, 41,147,201,218,115, 28,103, 52, 24, 12,167, 51, 51, 51, 95,167,148,218,116, 41, 60, + 45,187, 97,238,124, 66,200, 58, 0, 25, 85,166, 25, 8, 33,189,195,195,195,157, 40,165,169,213, 27, 24, 12, 6,131,241,111,163, + 94, 1,171,130, 7, 17, 90,254, 45,206, 71, 5, 74,233, 93, 0,181,158, 24, 91, 62, 95,157,163,183,215, 99,157, 77, 18,174, 42, +249,110, 1, 24,222,196,206, 48, 0,207, 54,165,211,100, 50, 93,130,141,247,101,171,141,154, 2, 20, 45, 59,215,141,133, 43, 6, +131,193,120,140, 96,163,167, 49, 24, 12, 6,131,193, 96, 52, 49, 4,101, 39,127,255, 13, 90,143,171, 3, 8, 33,213, 58,106,163, + 46, 63,115, 50, 39,115, 50, 39,115, 50, 39,115, 62,126,206, 74,238,154,238,109,122,187,138,175, 94,119, 60,120,100,120,192, 39, +167,253, 43, 78,172, 99, 78,230,100, 78,230,100, 78,230,100,206,135,235,124,220, 10, 59, 68,200, 96, 48, 24, 12, 6,131,209,196, +176,128,197, 96, 48, 24, 12, 6,131,209,196,176,128,197, 96, 48, 24, 12, 6,131,209,196,176,128,197, 96, 48, 24, 12, 6,131,209, +196,176,128,197, 96, 48, 24, 12, 6,131,209,196,144,242,171, 1,202, 94, 16, 66, 41,165,228, 33,182,135,193, 96, 48, 24, 12,198, +127,152,199, 37,139,176, 61, 88, 12, 6,131,193, 96, 48, 24, 77, 12, 11, 88, 12, 6,131,193, 96, 48, 24, 77, 12, 15, 40,219, 29, +247,176, 27,194, 96, 48, 24, 12, 6,227,191,203,227,150, 69, 42,246, 96, 13, 40,239, 88,163,111,104,203, 96, 48, 24, 12, 6,131, +209, 0, 30,171, 44,114,223, 73,238, 12, 6,131,193, 96, 48, 24,140,198,195,206,193, 98, 48, 24, 12, 6,131,193,104, 98, 88,192, + 98, 48, 24, 12, 6,131,193,104, 98, 30,104,192, 34,132, 4, 49, 39,115, 50, 39,115, 50, 39,115, 50, 39,115,254,215, 96,123,176, + 24, 12, 6,131,193, 96, 48,154, 24, 22,176, 24, 12, 6,131,193, 96, 48,154, 24, 22,176, 24, 12, 6,131,193, 96, 48,154, 24, 22, +176, 24, 12, 6,131,193, 96, 48,154, 24, 22,176, 24, 12, 6,131,193, 96, 48,154, 24, 2,160,218, 43, 1, 40,165,191,218, 44,105, +192,213, 4,117,249,153,147, 57,153,147, 57,153,147, 57,153,243,241,115,214,229,174, 79,254,120,164,161,148, 62,176, 2, 32,136, + 57,153,147, 57,153,147, 57,153,147, 57,153,243,191, 86, 4, 77, 29,216, 24, 12,198, 63,204, 1,194, 71,142,175, 23, 40,117, 3, + 95,156,138,212, 91,209,120,143,114,141,118,166, 7, 52,135,204,172,131, 69,170, 71,250,205,152, 70, 59, 25, 12, 6,227, 63, 4, + 11, 88, 12,198,191, 29,189,159, 15, 4, 88, 9, 30, 92, 65, 77, 81,208, 4,172, 4, 16,218,104,167,136, 91, 14, 43,207, 3,212, + 20, 9,173,239, 42, 0,225, 77,210, 94, 6,131,193,248, 15,240, 80, 78,114,151, 74,165, 33, 98,177,248, 67, 66,136,228, 97,172, +159,241,223,128, 16, 34, 17,139,197, 31,202,100,178,144,135,221,150, 7,198,174,118,114,240,172,195,141,102,206,253,248,173, 92, +173,161,212,234, 3,158,101, 4,190,242, 81, 54,202, 41, 32, 67, 74, 76,156,231,238,203, 6, 93,145,209,226, 15,138,198, 57,203, + 33,132,216,139,197,226,227,132, 16,231,198,186, 24,143, 38, 1,132,116,233, 42, 20, 46,240, 39,100, 16, 33,132, 60,236,246, 48, + 24, 15,139,135, 18,176, 74, 75, 75, 59,117,234,212,233, 13,177, 88, 28, 79, 8, 25,243, 48,218,240,176, 80,169, 84,127,218,217, +217,165,219,219,219,167,219,217,217, 93,171,171,254,113,132, 16,226,163,213,106,227,157,156,156, 34, 43,215,107, 59,140,239,229, +221,231,185,247,156, 3,159,236,223, 4,235, 24, 35,145, 72,226,187,119,239,254,122, 73, 73, 73,167,198,250, 30, 89, 74, 56, 29, +120,252,129, 97,169, 6,121,106,190, 89, 23, 18,103, 80, 1,252, 1, 48,194,181,193,206, 60, 78, 7,208, 65, 55,146,138, 21,127, +102,107,116,127, 68,151,170,193,227, 13, 68, 9,113,105,108,115,121, 60,222,108,142,227, 6,139, 68,162,215, 26,235, 98, 60,154, +136,121,188,222,127,142, 25,179,252,173,246,237,231,250, 1,163,171, 11, 89,164,140, 87,253,253,253,143, 17, 66, 38, 55,213,186, + 9, 33, 31,251,249,249, 37, 19, 66,230, 53,149,147,193,104, 40, 54, 7,172,137, 45, 73,239,103, 90,145, 51, 79,183, 36, 5,147, + 91,145,194,103, 91,145,115, 19, 90,146, 65, 13, 93,241,217,179,103,101, 17, 17, 17,218,254,253,251,239,147,201,100,231, 8, 33, +222, 13,241, 72,165,210,227, 2,129, 96, 98,229, 58,185, 92,126, 92, 32, 16, 60, 93,165, 46, 76, 46,151,231,201,100,178,104, 27, +189,119,197, 98,113,145, 84, 42,189, 91,185, 94, 32, 16, 60,173, 80, 40,142, 87,169,155, 88,181,174, 38,132, 66,161, 71, 98, 98, +162, 54, 41, 41, 73, 43, 22,139,117,149,235, 19, 18, 18,180,137,137,137,247,213,215, 23,161, 80, 56, 72,169, 84, 30,168, 90,167, + 82,169, 14,212,180, 76, 85,148, 74,229, 15, 66,161,240,190,247, 86,165, 82,253,173,174, 33, 16, 66,124,134, 12, 25,114, 46, 53, + 53,213,211,222,222,222,190,242, 52, 71, 59,251,161,223,238,216,242,198,216, 17, 67,102,107, 3,198,181,107,160,223, 91, 46,151, +159,235,214,173,219,190, 83,167, 78,105,119,239,222, 45,111,108,155, 31, 89, 14, 4,136, 64,184,126, 28,165,154,191,146, 75, 52, + 35,199, 76, 20, 92, 79, 44,214,152,173, 86, 71,128, 63, 0, 59, 91,212,127, 15,241,129, 0, 17, 4,230,190, 28,165,186,223,226, +132,154,129,147,230,242, 79,197, 9, 52,102,171,213, 9, 60,244,111,144,179, 28, 66,136,144,207,231,191,177,110,221, 58, 30,128, + 57,132, 16,113, 67, 93,255, 70,186,187, 19,247, 39,218, 8, 46,119,118, 35,189,155,202, 73, 8, 9, 84, 40, 20, 87, 9, 33, 62, + 77,229,108, 44, 70,142,187,189, 47, 38,230,196,180,214,173, 71,189,213,190,253, 11, 85, 67, 86,249,243,183, 86,173, 90,245,108, + 88, 88,152,166,101,203,150, 51, 9, 33,141,254,103,159, 16,178, 97,213,170, 85, 11,195,194,194,220,188,188,188, 62,104, 10, 39, +227,145, 66, 12, 96, 32,128,145, 0,158, 0,208,173,252,121,215,242, 50, 18,101,163, 34, 84,126,236, 90,190,108,197,244,238, 53, + 56, 70, 86,179, 92,215, 74,245,149, 95, 87,125, 94, 51,229, 87, 3,208,202,143, 85,203,211, 94,120,127,110, 47,119,195, 95,135, +246,208,194,196, 24,154, 19,113,157, 94,223,254, 17,157,219, 85, 99,120,166, 37, 62,110,192,213, 7,148, 82, 74, 67, 66, 66,104, +113,113, 49, 61,122,244, 40,167,211,233, 74,196, 98,241, 6, 0,138,250,184,196, 98,113,161, 70,163, 41,144,201,100, 95, 3, 16, + 83, 74, 33,145, 72, 10, 93, 92, 92, 10,164, 82,233, 46, 0, 18, 74, 41,134, 14, 29, 90, 76, 41,165, 18,137,164,200, 22,239,240, +225,195,139, 40,165, 84, 44, 22, 23,149,183, 89, 34,149, 74,191,237,210,165, 75,190, 68, 34, 41, 44,175, 19,203,229,242,175,187, +118,237,154, 47,149, 74, 11,109,241, 58, 58, 58, 38, 90,173, 86,122,232,208, 33,170,213,106, 83, 42,234, 29, 28, 28, 18,173, 86, + 43, 13, 14, 14,166, 26,141, 38,197, 22, 87,149,109,202, 83, 42,149,107,186,117,235,150,171, 84, 42,179, 42,213,173,237,209,163, + 71, 94, 69,157, 45, 69,161, 80,100,121,122,122,230, 40,149,202,181, 0,120,148, 82, 40,149,202,172, 22, 45, 90,100,171,213,234, + 53, 21,117,182, 20, 55, 55,183,153, 90,173, 54, 69,171,213,166,216,219,219,175,112,117,117, 77,211,235,245,148, 82, 74, 91,181, +106,149, 65, 41,133,166,253,184, 94,109,122, 63,251,158, 54,112,204,235,159,239,191,112,233,108,104,150,190,253,224,217,107,236, +218,143,181,171, 71,255, 21, 98,177,120,131,139,139, 75, 73,112,112,176, 53, 61, 61,157,222,188,121,147,166,166,166,210,154, 62, +215,255,250,178, 37,192,131,110,243,221, 23,190,212, 51,226,236,170, 97,102, 26,119,138,238,121, 65, 99, 62,243,186,123, 20,221, +234,247, 3,221,230,223,172, 65,206,173,254,123,110,190,227,121,123,243, 7,175,154,227,227,227,233,130,231,134, 89, 78,206,117, +143,166,159,251,237,111,144,243,127,239,209,148,113,227,198, 21, 38, 36, 36,208,128,128,128, 34, 62,159, 63,253,161,111,195,127, +168,116,115,131,123,144,143, 56,249,230,238, 5,220,232, 64,121, 86, 39, 87,244,110,172, 19, 64,160, 86,171,205,220,185,115, 39, + 85,169, 84, 25, 0,124, 30,118, 63,203,219, 69,252,128, 49,223,180,111, 31,204, 77,152, 96,253,166,125,251, 96, 63, 96, 12,202, +134, 5, 34, 0, 22,173, 94,189, 58,196,108, 54,135,124,253,245,215, 33, 99,198,140, 9, 1,176,160,145,235,220,248,241,199, 31, + 83,179,217, 76,191,254,250,107, 58,102,204, 24, 10, 96,147,173,203, 43,149,202, 54,237,218,181,219, 21, 16, 16,144,208,161, 67, + 7,163,191,191,127,137,143,143, 79, 92, 96, 96,224,209,123,187,187, 0, 0, 32, 0, 73, 68, 65, 84, 78,137, 68,226,245,176,183, +233,127,165,212,145, 69,186, 45, 90,180,104, 49, 0,186,104,209,162,197,148,210,145,229,243,141,172,252,188,234, 35,165, 52,168, +242,235,234, 28, 21,165, 58,103,117,235,168,242,188,230,254, 84,116, 6, 64,127, 0,103,170,206, 48,177, 37,122,205,237,229, 94, + 92,172, 79,165,161, 31,189, 70,127, 31,232, 65,207, 15,112,161,145,111,140,163,169,187, 55,208,151, 59, 58, 24, 38,180,196,192, + 6,108, 68, 26, 28, 28, 76, 79,158, 60, 73,163,163,163,105,122,122, 58,125,247,221,119,141, 10,133, 34,135,207,231, 79,181,213, + 37,147,201,242,146,147,147,233,187,239,190, 91, 90,190,183,169,165, 92, 46,207, 75, 75, 75,163, 31,125,244,145, 81, 38,147,197, + 0,240,150, 72, 36,133,209,209,209, 84, 42,149,218, 20,176,228,114,121, 94,104,104, 40,149, 72, 36, 69, 0,188, 53, 26, 77,204, +111,191,253,102,230, 56,142,122,120,120,228, 3,104,169,209,104,238,158, 58,117,234, 94,157, 45, 94, 71, 71,199,196,226,226, 98, +122,242,228, 73,170,211,233, 82,170,214, 31, 59,118,236,190,224,101,227,246,212,185,186,186, 94,175,104,159,151,151,151, 30,128, +206,205,205,237,198,153, 51,103,204,148, 82,218,170, 85, 43,189,173, 62, 23, 23,151,140,140,140, 12,186,105,211,166, 82,149, 74, +117, 13,128,206,197,197, 37, 67,175,215,211, 79, 63,253,180, 84,173, 86,135, 0,208,217,226,114,118,118, 78, 49, 26,141, 52, 55, + 55,151,118,239,222,189,240,252,249,243, 52, 63, 63,159, 82, 74,105,139, 22, 45, 50, 40,165,240,237, 63,253,195, 75,119, 10,243, +255,111,225,150,239,189,186, 61,243,209,137,203,201, 73, 95,254,124, 53,196, 57,112,236, 48, 91,214,193,231,243,167, 42, 20,138, +156, 79, 62,249,196,148,147,147, 67, 99, 98, 98,232,197,139, 23,233,197,139, 23,105,122,122,250,227, 25,176,246,131, 79,183,249, +142,165,219,124, 67,118, 78,115,206, 44,184,182,151,210, 95,230,209,232, 15, 91,210,165,195, 84, 5,220, 54,223, 16,186,205,111, + 2,125,191,191,160, 94,206,237,254,163,233, 54,223,144,143, 39, 54,207,186, 30,114,133,158, 57,115,134,126,182, 97, 53,157, 27, +228, 94,196,109,243, 13,161, 91,253,199,215,203, 89,169, 72, 36,146, 59,231,206,157,163,103,207,158,165, 31,124,240, 1,149,203, +229, 9,141,223, 14,254, 34,186,213,167, 57,221,226, 61,128,238,240,118,165,167, 27,214,182, 7, 89,186,185,193,125,176,143, 56, + 41,243,250,207,148,102,223,165,105,107, 3,232, 48, 95, 97,163, 66, 86,121,184,210,199,197,197,209,180,180, 52,186,126,253,122, +170, 86,171, 31,233,144,229, 11,140, 5,176,120,205,154, 53,247,194,213,150, 45, 91, 66,110,221,186, 21,226,233,233,121,180, 17, +235,218,180,102,205,154,123,225,106,203,150, 45,244,214,173, 91,180,121,243,230,137,117, 45, 59,109,218, 52,121,175, 94,189, 66, +166, 78,157,106,216,185,115, 39,141,139,139,163,183,110,221,162,107,214,172,161,239,189,247, 30,253,234,171,175,232,248,241,227, +139,186,119,239,126,105,194,132, 9,210,122,182, 77, 64, 41, 21,151, 23, 33,165,180, 34, 96, 10, 0, 8, 1,240, 31,246,251,244, +168,149,218,178, 8,173, 33, 68,213, 20,172,170, 78,171, 37,128,213, 26,212,234, 90, 95,109,253,169,188, 11,245, 52,165,180, 63, +170, 32,160, 88, 54, 99,254,135,210,216,157,235,145,254,221,167,224,231,166, 67, 88,144,133,210,115, 71, 96, 62,119, 16,207,246, +236, 41,147, 17,178,188,234,114,182, 32,147,201, 32, 16, 8,144,146,146,130,148,148, 20,204,156, 57, 83,116,238,220, 57,251,190, +125,251,110, 87, 42,149, 55, 8, 33,237,235,114, 16, 66,224,230,230,134,185,115,231,138,191,249,230,155, 86, 42,149,234,154,213, +106, 21,234,116, 58,204,158, 61, 91,180,127,255,254, 22,246,246,246, 87,172, 86,171, 72, 44, 22,195,214,115, 46, 9, 33, 16,137, + 68,176, 88, 44,194,110,221,186, 93, 13, 15, 15,247,234,223,191,191, 32, 34, 34, 2,153,153,153,130,174, 93,187,222, 8, 15, 15, +111,221,175, 95, 63, 65, 76, 76, 12,242,242,242,168,173, 94,163,209, 8,137, 68, 2, 30,143,119, 95,125,105,105, 41,234,211, 70, +160,236,240, 95,239,222,189,195,110,222,188,217,161,127,255,254,130,208,208, 80,100,102,102, 10,187,119,239, 30,118,227,198,141, +246,125,250,244, 17, 68, 70, 70, 34, 47, 47,207,230, 75,236,165, 82, 41, 52, 26, 13,158,125,246, 89,241,254,253,251, 59,104, 52, +154,155, 2,129, 64,236,236,236,140,169, 83,167,138,247,239,223,223, 81,167,211,221,176,241,144, 33, 31, 0,204,102, 51,102,206, +156,169, 80,171,213, 72, 76, 76, 4,199,113,176, 90,173, 0,128,172,156,172, 91, 55,110,133, 70, 60, 59,101, 98,255, 98, 83,105, +233,133,203, 87,255,106,213,162,185, 7, 33,180, 69,109, 98, 66, 72,123,185, 92,126, 99,242,228,201, 95, 36, 36, 36,216, 79,157, + 58, 85, 24, 23, 23,135,172,172, 44, 8,133, 66, 72,165,210,251,182,241, 99, 69,126,128, 19, 56, 12,142,215, 27, 37, 18,123, 15, +149,210,213, 7, 72, 56,139,150, 26, 9,248, 60,190,244, 74,140, 65, 1,208,193,240,204,116,170,159,147, 27, 28,147, 97,148,152, + 29,219, 42,221, 60, 60,145,149,149,133,102,173,252, 80, 34,214,136,255,188, 91,164, 4,169,167,179, 28, 66, 72, 95,111,111,111, +151, 54,109,218, 32, 51, 51, 19,157, 58,117,130,131,131,131, 3, 33,100,112,125, 93,247,216,217, 66,130,124,244, 6, 33,235,192, +231,125, 0,179, 96, 37,238,234, 59, 97,123,103, 97,131,157, 77, 76,119,119,226,174, 86,138, 47,238,221,247,157,187,147,167, 63, +112,228,255,160,179,151, 96,199,236, 78,142, 26, 59, 73,112, 67, 14, 23, 18, 66, 2,117, 58,221,169, 75,151, 46, 57, 75,165, 82, + 92,187,118, 13, 1, 1, 1, 88,191,126,189,198,193,193,225,236,163,112,184,144, 82, 74, 35,128, 67, 31,223,188,249,245,174,168, +168,195,211, 90,183, 30, 53,213,199,103,197,172,201,147,167,191,250,234,171, 88,189,122, 53,130,131,131,209,187,119,111,204,152, + 49,195,156,144,144,240, 77, 67,214, 67, 8,249,116,237,218,181,115,231,205,155, 87,213,105,138,143,143,255,184,182,101, 3, 3, + 3, 61,238,220,185,147,252,198, 27,111,116,218,181,107,151, 76, 46,151, 35, 55, 55, 23,219,183,111,199,226,197,139, 65, 8, 1, +165, 20, 95,125,245,149,252,133, 23, 94,232, 22, 21, 21,149,220,162, 69, 11, 91, 78,223, 32, 0,164, 0,228,229, 69, 1, 64,190, +119,239, 94,187,177, 99,199,170,203,235,100, 0,100,236, 66,175,106,169, 54,139, 84, 64, 8, 57, 92,249, 53,165,116, 84,213,186, +170,211, 40,165,163,106,115,212,135,218,214, 87,149,202,191, 62, 3, 8, 33,103,254, 38, 3,218,187,120,249, 34,239,151,253,144, + 9, 8,100,252,242, 34, 32,224, 69,223, 66, 51,169, 16,102, 74, 3, 27,210, 80,169, 84, 10,153, 76, 6,153, 76, 6, 66, 8,114, +114,114,160, 86,171,241,221,119,223, 73, 55,109,218,212, 78, 46,151, 95,176,179,179, 91, 89,155,163, 34,140, 68, 70, 70,162, 99, +199,142,228,240,225,195,234, 89,179,102, 9, 0, 32, 62, 62, 30,237,218,181, 35,191,255,254,187,234,205, 55,223, 36, 18, 73,253, + 62,203, 34,145, 8, 11, 23, 46, 36,231,207,159, 87,202,229,114,132,134,134,162,176,176, 16,111,190,249,166,224,207, 63,255, 84, + 42, 20, 10, 68, 69, 69,161,164,164,164, 94,193,205,104, 52, 66, 36, 18,221,183, 12, 33, 4, 38,147, 9, 98,177,216,230, 80,224, +236,236,252, 94,151, 46, 93, 14,156, 62,125,218, 73, 38,147,225,214,173, 91, 48, 24, 12, 88,190,124,185,252,220,185,115, 78, 42, +149, 10,183,111,223,134,193, 96,168, 87,104,171, 88,255,221,187,119,225,237,237, 77,142, 28, 57,162,157, 49, 99,134, 20, 40,219, +166, 62, 62, 62,228,232,209,163, 58, 63, 63,191,253, 90,173,118,105,109, 46,142,227,144,154,154,138,176,176, 48, 68, 71, 71, 67, +175,215, 35, 51, 51, 19, 5, 5, 5,176, 88, 44, 0, 0,121, 65,254,145,189,223, 31,186, 33,147,201,228, 1, 62,222,158,183, 66, +195, 51,100, 50,153,188,185,167,167, 15, 33, 31, 84,187, 49, 84, 42,213, 74,153, 76,118,225,224,193,131,237,191,248,226, 11, 73, +102,102, 38,226,227,227, 65, 8,129, 84, 42,189, 87,248,124,190,205,253,254,215, 64, 8, 1, 49,122,131,144, 78, 23,163,139, 28, +251,142,154, 34, 66,204,113,128, 51, 3, 60, 1, 6,180,247, 16, 4,223, 42,210,129,162, 61, 74,225, 7,216,240,230, 19, 66, 0, + 83, 27,128,116, 57,121,199,226,212,123,220,108, 81,114,114, 50, 68, 34, 17, 36, 18, 9, 58, 13,122, 74,176,247,134,217, 5, 4, + 29, 96,130,175, 77,206, 74,200,100,178,119,223,123,239, 61, 69,101,231,244,233,211, 21,118,118,118,239, 53,104, 27,236,108, 33, + 65,145,188, 39,172,244,181,176,228,226,230, 43,142,164,249, 69,103, 20,251,129, 98, 62, 96,238,216,216,144, 69, 8, 25, 32,149, + 74, 99, 8, 33,125, 26,234,232,238, 78,220,213, 42,241,133,125,251,190,115,119,108, 86, 22,174, 96, 41, 1,132, 50,184,104,236, +177,227,245,129,142, 26,123, 89,189, 66, 86,121,184,250,237,226,197,139,206, 82,169, 20, 33, 33, 33, 16,137, 68,144, 74,165,104, +215,174, 29,182,109,219,166,113,116,116,124,164, 66,214,170,155, 55,119,174, 12, 11,139, 92, 20, 24,232,247,164, 66,225,248,202, +212,169,118,239,188,243,206,225,131, 7, 15,126, 61,114,228,200,204,203,151, 47,127, 66, 41,221, 95, 31,119,249, 73,242, 91,214, +173, 91,247, 74, 69, 96,123,231,157,119,190, 58,120,240,224,202,145, 35, 71,166, 94,190,124,249, 13, 74,233,150,218, 28,133,133, +133, 7,151, 44, 89, 98, 55,110,220,184,138,215, 56,119,238, 28,190,249,230, 27, 40, 20,138,251,230, 29, 51,102, 12, 94,122,233, + 37, 7,163,209,248, 67,109, 78,173, 86, 27,116,241,226,197, 0, 0, 34, 0, 18,148, 7,172,208,208, 80,251,252,252,124,123,165, + 82,105,239,234,234,170, 42,175,151,141, 27, 55,206, 94, 40, 20,246,173, 79,223,255, 3, 84,155, 69, 42,168, 26,150,106,170,107, +232,252,182, 96,235,242,247,126,188, 40,165,103, 0,244,171,110, 38, 83,118, 58, 36,176, 66,198, 39,144,243, 43,133, 44,112, 16, +228,101,212,243,171,246,127, 84,254, 33,148,201,100,144, 74,165,247,246,228,228,229,229,129, 16, 82,103,216,168, 8, 14, 74,165, + 18,197,197,197, 48,153, 76,144, 74,165,247,234, 44, 22, 11, 44, 22, 11,100, 50, 25, 36, 18, 73,189,247, 96,153,205,102,132,133, +133, 33, 42, 42, 10, 60, 30, 15, 10,133, 2,102,179, 25,127,253,245, 23,146,147,147, 33, 16, 8, 32,151,203,235, 21, 96,172, 86, + 43,196,226,191,159,223,107, 54,155,235,181, 7,139,199,227,193, 96, 48,208, 59,119,238, 32, 46, 46, 14, 34,145, 8,106,181, 26, + 98,177, 24,122,189, 30, 73, 73, 73,247,234,234,211,190,138,121,101, 50, 25,138,138,138, 64, 41,189,215, 94,153, 76,134,210,210, + 82, 16, 66,192,231,243,235,124,127,172, 86, 43, 82, 82, 82,160,215,235,145,152,152,136,204,204,204,123, 33,139,227, 26, 63,110, +229,213,171, 87,105,120,120, 56, 74, 75, 75, 33,145, 72, 32,149, 74,239,123, 20, 8, 30,195,161,222, 62, 11,180,131, 89, 56, 36, +179,208, 44,209,155, 68,118,186,192, 32, 32,230, 24,192, 19, 0, 82, 7,244,104,219, 18,241, 57, 86,197,237,116,163, 20, 4, 67, +177,197,199,193, 38,167, 85, 56, 88, 95, 96,150,196,153, 52,106,255,246,157,145,158,158, 14,137, 68, 2,137, 68,130, 46,189,131, + 16,147,101,149,135, 39, 23,203, 65, 49,196, 38,103, 57,132,144, 86, 74,165,178,103,159, 62,125, 72,101,231,136, 17, 35, 64, 8, +105, 71, 8,241,171, 87,255, 55,183, 22,195, 36,239, 1, 33,125, 45, 60,213,224, 22, 28, 90,226, 51,250,201,167, 28, 55,252,154, +225, 23,145, 90,226, 5,206,178, 0,212,212,185,161, 33,139, 16,210, 95,165, 82, 29,222,188,121,179,151, 84, 42, 61, 70, 8,105, +208, 15,160, 82,198,255,252,221, 87,166,184, 59, 84,132, 43,179, 1, 16,200, 0,161, 12, 16,200,224,162,117,198,242,151, 6, 59, +202,165,194, 31,109,117,202,100,178,189, 91,182,108,209, 84, 13, 87, 21,165, 83,167, 78, 88,186,116,169,198,209,209,113, 79, 67, +218,220, 84, 16, 66,134,216,219,219,239, 10, 10, 10,186,152,162, 82,189,148,218,185,179,248, 55, 59,187,188, 39,242,242,236,154, +135,134,154,124,129, 91, 0, 62, 75, 76, 76, 28,102,107,184, 34,132, 76,182,179,179, 11, 9, 10, 10, 50,169, 84,170,132,245,235, +215,191, 60,103,206, 28,172, 94,189, 26, 75,150, 44,249, 2,192,139,148,210,183, 19, 19, 19,221,234, 10, 87, 0,144,150,150,246, +204, 91,111,189,149,153,153,153, 9, 0,104,215,174, 29,114,115,115,177, 96,193, 2,188,246, 90,217, 69,174, 29, 59,118, 4,165, + 20,233,233,233, 88,187,118,109,122, 90, 90,218,243,181, 57, 57,142, 75,220,191,127,127, 55,147,201,228,129,178,195,128,146,220, +220, 92,117,118,118,182,202,100, 50, 41, 56,142, 83,216,219,219, 43, 1,200,159,125,246, 89, 65, 88, 88, 88,128,197, 98, 73,182, +165,255,255, 21,106,203, 34, 13,228, 72, 3,219, 49,138, 16,114,184,186, 61, 96,182,194, 43, 23,145,202,143,149,225, 19,220, 76, +184,122, 22,142,129,157,239,219,123, 37,231, 19,200,212,118,136, 73,140,135, 8, 36,172, 33, 43,175,252,197, 80, 17,178,194,195, +195,241,196, 19, 79, 24,222,127,255,253, 91, 69, 69, 69, 61,115,114,114, 22,215,230,168, 8, 3,118,118,118, 56,127,254, 60, 29, + 63,126,124,254,198,141, 27, 45, 21,117, 23, 47, 94,164,131, 7, 15, 46, 88,182,108, 25,173,122, 88,174, 46,175, 72, 36,194,198, +141, 27,233,192,129, 3,243, 46, 93,186, 68, 21, 10, 5,228,114, 57, 54,110,220,104,233,215,175, 95,222,239,191,255, 78, 21, 10, +197,223,254,219,169, 13, 30,143,119, 47, 96, 85, 14, 61, 60, 30, 15, 28,199,213, 43, 96,101,100,100,124, 16, 17, 17, 49,113,208, +160, 65,233, 97, 97, 97, 84,173, 86,195,206,206, 14,139, 22, 45, 50,116,236,216, 49,227,230,205,155,247,234,234,115,168,172, 98, +253, 42,149, 10, 97, 97, 97,116,212,168, 81, 25,159,125,246, 89, 73, 69, 93,104,104, 40, 29, 62,124,120,122, 88, 88,216,196,180, +180,180,101,181,185, 56,142, 67,116,116,244,189, 61, 86, 37, 37, 37,200,204,204, 68, 98, 98,226,189, 67,132,197, 10,245,176, 41, +147, 70,119, 40, 46, 46, 54,132, 71,222, 73,104,215, 54, 64, 91, 92, 92,108,136, 79, 72,136,164,244,189,106, 83, 88, 65, 65,193, +226,226,226,226,158, 43, 86,172,184, 53,113,226, 68,195,237,219,183,255, 22,174,164, 82,233,227, 25,176,120,156, 11, 8,237,243, +199,157, 66,251,193,163,159, 22,147,180,203,128,169, 16,144, 56, 0, 18, 7, 8, 20, 78, 24,222,183, 35,127,231,197,124, 23, 80, +174, 23, 68, 18,143, 58,157, 66,170, 3,184,190,191, 68,150, 56,244,153, 48, 87,156,157,157, 13, 62,159,127, 47, 12,201, 21, 10, + 60,241,228,179,188,175, 46,151,186, 0,180, 55, 8,191,110,103, 57, 98,177,120,225,187,239,190, 43,202,201,201, 1,143,199,251, +159, 83, 46,199,172, 89,179, 36,106,181,122,137,205,125, 63, 16, 32,130, 80,210, 3, 28,125,237,118, 90,177,219,193,155,197, 62, +243, 87,238,144, 5,118,236,134,153, 3,180,178,149, 71, 51, 2,110, 36, 27,188, 0,235, 27,176, 24,187,212, 55,100, 17, 66,250, +170, 84,170, 35, 87,175, 94,149,143, 24, 49, 2,107,215,174, 85,200,100,178, 99,132,144,122,127,225, 23, 21, 90,231, 44,219,244, +109,250,205, 79,134, 2,166,162,178, 96, 85,169,100, 20,114, 88,186,227, 84,158,217, 76,167,216,234, 44, 46, 46,126,238,197, 23, + 95,204,250,241,199, 31,255, 22,174,164, 82, 41, 98, 99, 99,177, 98,197,138,236,236,236,236,231,235,219,222,166,130, 16, 50,100, +206,156, 57, 43,146,146,146,124,127,249,229, 23,129, 94,175,215,174,251,242,203,188, 3,121,121,217, 43, 67, 67,111,191,221,182, +173,247,162,246,237,159,175,105, 8,135, 26,156,147, 95,121,229,149,189, 73, 73, 73,157,126,253,245, 87,161, 94,175,247,120,229, +149, 87,176,102,205, 26, 44, 89,178,100, 27,128,153,180,252, 36, 30, 91, 49, 26,141,183,115,114,114, 70, 13, 29, 58, 52, 55, 39, + 39, 7,237,219,183,199,232,209,163,225,226,226, 2, 55, 55, 55,140, 29, 59, 22, 62, 62, 62,200,202,202,194,148, 41, 83,178,245, +122,253, 80, 74,105,173, 87,161,103,101,101,221,221,179,103,207,157, 57,115,230,116, 78, 74, 74,242, 7,224, 84, 80, 80,160, 40, + 40, 40,144, 24,141, 70,153,131,131,131, 67,199,142, 29,157,103,204,152,161,188,118,237, 90, 64,114,114,114, 1,128,184,250,180, +251,113,166,182, 44, 2, 64, 95, 30,116,140, 85, 30,245,117, 76,179,117,217,106,159,219, 48, 95,141,212,249,171,107, 2,150,126, +179,127,103,137,216,179, 13,236,124, 59, 64, 46,149, 66, 38, 22, 67,230,224,132, 82,142,195,151,177,105,134, 34, 74,109,255,130, + 44,135, 82,122,239,240,160, 84, 42, 69, 97, 97, 33,230,206,157, 91, 50,105,210,164,220,216,216,216, 89,249,249,249, 29, 40,165, + 55,235,242, 16, 66, 80, 84, 84,132,247,223,127,191,120,209,162, 69,209, 5, 5, 5,157, 68, 34,145,217,100, 50,225,221,119,223, + 45,153, 61,123,118, 92,110,110,110, 87,145, 72,100,170,239,143,173, 80, 40,132, 64, 32, 48,231,229,229,117,122,235,173,183,162, + 86,172, 88, 81, 44, 18,137, 32, 18,137,204,249,249,249,237, 22, 47, 94,124,123,241,226,197,197, 66,161,176, 94,123,198, 42,246, + 8, 85, 61, 68, 88,121, 79,145,173,152,205,230, 83, 25, 25, 25, 29,230,205,155,119,125,227,198,141, 6,165, 82, 9,137, 68, 98, +204,200,200,104,255,242,203, 47,223, 88,187,118,173, 65,169, 84,214,107, 15,150,201,100, 2,199,113,216,188,121,179, 97,222,188, +121, 55,244,122,125,123,148,125, 32,177,113,227, 70,195,203, 47,191,124, 61, 61, 61,189,131,217,108, 62, 85,151,203,106,181, 90, +243,243,243, 33, 16, 8, 16, 26, 26, 90, 42, 18,137,192,227,241,112,247,238,221,123, 1,203,209,209, 49,160, 67,187,182,126,223, +238,221,127, 70, 38,146, 72,122,118,235,226, 31, 29, 23,159, 68, 41,169,245,139,135, 82,122,179,168,168,168, 67, 98, 98,226,172, +233,211,167,231,206,159, 63,191,164,176,176,240,190, 31, 28,161,240,145, 57, 29,167,233,224, 65, 14, 2,217,157,140, 82,149,148, +103, 33,136,252,185, 44, 92, 73,237, 1,169, 3, 32,117,128,187,187, 7, 46,199, 26, 84,224, 65, 12,171, 89, 91,167,147, 82, 5, + 8,228,161,233, 80, 9,197, 50,146,150,150,118, 47, 8, 85, 20,175, 54,254,184, 22, 95,168, 4,161, 18,240, 81,159,161, 68, 70, + 57, 57, 57, 9, 82, 83, 83,255,230, 12, 8, 8,224,155,205,230,161, 54,155, 82,172,174, 0, 55, 39, 50,163,196,237,167, 27, 6, +159,215, 87,126, 37,147, 89,115,129,171,155, 16,216,202, 13,175, 79,232, 40,126, 39, 88, 31,120, 37,206,208, 10, 2, 58, 11, 92, +161,198, 86, 53, 33,164,143, 74,165, 58,118,229,202, 21,185, 74,165, 66,116,116, 52,186,117,235,134,237,219,183,203,229,114,249, + 81, 66,200,128,122,244, 25, 23,211,104,124, 97,129,181,231,194,253, 9,105, 55, 83, 45,247,133, 43,125, 17,197,139, 31, 31,204, +205,201, 47,121,234, 66, 66,221,127, 71, 21, 80, 74,175,231,230,230, 14, 89,178,100, 73,150, 94,175,191,239,179, 30, 31, 31, 95, + 17, 4, 6, 80, 74, 27,244, 79,111, 83, 96,103,103, 55,117,229,202,149,184,114,229, 10, 70,140, 24,129,179,103,207, 34, 59, 59, + 27,251,142, 29,187,179,231,206,157,183, 43,206,201,170,110, 8,135,154, 80,171,213,243, 87,174, 92,137,171, 87,175,222,115,102, +101,101, 97,229,202,149, 73, 0,102,215, 55, 92, 85,144,158,158,126,249,246,237,219, 67,219,183,111,255,215,230,205,155,147, 92, + 93, 93,185, 25, 51,102,224,197, 23, 95,132, 70,163,177,110,216,176, 33,161,111,223,190,161, 81, 81, 81, 65, 69, 69, 69,183,234, +242, 81, 74,105,102,102,230,249, 47,190,248,226,194,160, 65,131, 20,211,166, 77,211, 6, 7, 7, 59, 25, 12, 6, 55,145, 72,164, + 51, 26,141,226,240,240,112,193,129, 3, 7, 92,255,250,235,175,216,226,226,226,203, 13,109,251,127,144, 43, 40,219, 27,245,107, +149,199, 43,117, 76,179,117,217,154,158,215, 53, 95,205,216,114,102,255,212, 86,120,127, 86, 91,149,225,207,105, 61,104,218,140, + 62, 52,253,105,127,122,174,191, 35,157,222,154, 20, 61,215,192, 97, 26,172, 86, 43, 77, 79, 79,167,233,233,233,116,249,242,229, + 22,153, 76, 86, 44,151,203,235, 61, 76,131, 82,169, 44,244,246,246, 46,176,179,179,187, 55, 76,131, 74,165, 42,244,245,245, 45, +176,183,183,191, 55, 76,131, 66,161, 40,164,148, 82,165, 82,105,211, 85,132,106,181, 58,175,176,176,144,202,229,242,138, 97, 26, + 68,118,118,118, 95,120,123,123, 23, 40,149,202,138, 97, 26,132, 14, 14, 14,159,251,248,248, 20,168, 84, 42,155,134,105,112,113, +113, 73, 76, 74, 74,162, 73, 73, 73,180, 89,179,102, 41,149,235,227,227,227,105,124,124, 60,245,240,240,104,208, 48, 13, 26,141, +102, 77,215,174, 93,179, 53, 26, 77, 86,165,186,181, 93,187,118,205,169,168,179,165, 56, 59, 59,103,117,233,210, 37, 71,163,209, +220, 27,166, 65,163,209,100,149,187,235, 53, 76,131, 76, 38,155, 41,149, 74, 83,164, 82,105,138, 68, 34, 89,209,162, 69,139,140, +239,191,255,158,110,216,176,129,170, 84,170,178, 97, 26, 2,198,244,108,211,235,249,183, 53, 1, 99,231, 55,102,152, 6,185, 92, +190, 65, 38,147, 21,127,244,209, 71,150,162,162, 34,106, 54,155,105,249,151, 23,173,239,246,124,164,203,118,159, 54,116,171,223, +193,168,101, 94,225,243,250,201, 75,110, 45,239, 64,233, 15,227, 40, 61,250, 34,165,167, 22,210,203,219,102,208, 94, 94, 18,235, +249, 5,205, 34,233,231,190, 63,217, 52,180,194,246,118,109,232, 86,191,163,119, 62,240, 10,127,174,175, 91,201,151,159,109,160, +151, 46, 93,162,161,161,161, 52, 58, 58,154, 30,253,249,123,218,171,149,188,204,185,213,239, 96,125,134,107, 0,208, 91, 34,145, + 20,174, 95,191,158, 94,188,120,241,158,243,224,193,131, 84, 46,151, 27, 0, 27,175, 66, 6, 8,221, 18, 48,206,242,153,239,185, + 37,131,149,133, 89,135, 23, 82,122,107, 39,165,219, 3, 41,253,186, 59,165,223,143,164,244,208,243,244,226,134, 9,180,183,151, +200, 76, 63,247,253,131,238, 8, 24,108,107, 59,133, 66, 97,254,143, 63,254, 72, 83, 82, 82,232,217,179,103,233,213,171, 87,105, + 68, 68, 4, 77, 72, 72,160, 71,142, 28,161, 66,161,176, 4, 64,189,175, 82,236,174, 67,243, 32,111, 81,234,141, 85,189, 41, 13, +158, 66,245,123,166,210, 81,109, 85,217, 61,154, 9, 6, 53,244, 51, 0,160,163,147,147, 83,230,145, 35, 71,104,108,108, 44, 61, +115,230, 12,213,106,181,153, 0, 2, 31,246,231, 51, 40, 40,232, 18,165, 52,100,196,136, 17, 33, 0,142, 7, 5, 5,133,196,196, +196,132,116,235,214,237, 34,106, 25,194,161, 54,231, 19, 79, 60, 97,162,148,210, 17, 35, 70, 80, 0, 41, 65, 65, 65, 52, 38, 38, +134,118,235,214,205,216, 20,109, 70,217,197, 56,207, 11,133,194, 47, 29, 29, 29,127,119,112,112, 56,197,231,243,183, 3,152, 86, +159,239,187,106,156,238, 0, 2, 80, 54, 94, 82,151,242,231,110, 96, 87, 16,254, 39,138,205, 51, 78,240, 66,239, 23, 90,145, 51, +207,180, 68,193,148,150, 40,252,191,214,228,220, 83, 94,168,245, 11, 2, 53,220,109,187, 34, 96, 29, 58,116,136, 54,107,214,172, + 72,165, 82,157, 3,224,109, 83,131,171, 56, 29, 28, 28,142,243,249,252,137,213,212, 61, 93,185,206,206,206, 46,204,222,222, 62, + 79,173, 86, 71,219,210, 78,181, 90, 29, 33,151,203,139,212,106,117, 68,229,122, 62,159, 63,214,201,201,233, 72,149,186, 49, 85, +235,106,234,187,139,139, 75, 98, 74, 74, 10,213,235,245,212,211,211,243,190,128,149,148,148, 68,211,210,210,238, 11, 94,182, 56, + 43, 23,129, 64, 48, 72,163,209, 28,168,171,174, 54,167, 78,167,251, 65, 32,184,255,203,191,186,186,250,190,239,229,211,124,220, +221,221, 51,214,173, 91, 71,149, 74,101, 70,229,105,190,253,254,239,221, 75,119, 10,243, 95,124,107,235,247, 26,255, 39,219,213, +183,239,229,243,121,171, 84,170,115,205,155, 55, 47,250,237,183,223, 40, 45,171,164, 13,221,158,245, 45,255,136,115,191,191,136, +110,243,239, 77, 63,247, 63, 18,241, 94,243,191,158,239,174, 40, 13, 89, 55,130,210, 83, 11,233,197,173, 47,210,158, 94,226,178, + 32,180,205,239, 24,253,202,167, 31,221,212, 74,108,147,243,203,214,125,233, 54,191, 99,225, 75,155,255, 53,174,179,198,184,119, +231, 54,122,247,238, 93,122,240,192, 30,218,163,101,121,184,250,220,255, 36,221,234, 63,208, 38,231,253,211,122, 75, 36,146,194, + 29, 59,118,208,187,119,239,210,159,126,250,201,166,112,117,159, 19, 32,116,107,192,147,150,207,124,207, 45, 14, 82,230,190,216, + 93, 90, 58,165,163,216, 56, 54, 80,100, 26,210, 70,100,233,213, 92, 96,237,224,202,227,252, 53,160, 67,124,101,165,244,115,223, + 63,232,231,254, 67,109,109,167, 88, 44, 78, 64,165, 49,113,170, 22,137, 68,162,175, 41, 96,213,245,190,119,215,161,121,144,143, + 36,245,183,101,131,232,232,246,170, 44, 91,194, 85, 93, 78, 0, 29,157,157,157, 51,191,254,250,107,170,211,233,244,182,132,171, +127,226,243,105,103,103,183,171,176,176, 48,228,196,137, 19, 33, 65, 65, 65, 33,187,118,237, 10, 57,119,238, 92,136, 92, 46,223, + 85, 62,255,223, 66,150, 63, 48,180, 54,167, 90,173, 14, 41, 40, 40,160, 39, 78,156,160, 65, 65, 65,116,215,174, 93,244,220,185, +115, 84, 46,151,135, 52,248,239,232, 1,244,157, 57, 89,185,111, 27, 61, 80,121, 45, 1,107,218,180,105, 6,185, 92,158, 14, 96, +204,195,126, 83,255, 73,167,179,179,243,159, 58,157, 46, 93,167,211,165,107, 52,154,107,213,213, 59, 59, 59, 95,123,216,237,124, +144, 78, 0, 62, 34,145, 40, 94, 40, 20, 70, 86,174,215, 4,140,233,217,186,247,115, 75,116,129, 99,134, 55,182,157, 0,198,200, +229,242,244,241,227,199, 23, 61,118, 1,139, 82,208, 77,173,196, 21, 33,235,214,146,230, 17,163,219,202, 77,219,223, 24, 66,123, +182,168, 18,174,190,110, 46,169,151,179, 60,100, 93,127,199, 51, 98,160,143,210,178,114,201,235,180, 71, 75,217,253,225,170, 62, +206,251,167,247,150,203,229, 5,239,189,247,158,205,123,174,254,230,252,210,215,147,110,245,219, 93, 22,158,234, 42,254, 95,210, + 79,125, 61, 31,149,247,189,187, 14,205,159,240,145,132,217,186,231,202, 22, 39,128,142, 14, 14, 14,127,217, 18,174,254,169,190, + 3, 24, 50,107,214,172,144,152,152,152,144,232,232,232,144,115,231,206,133, 60,249,228,147, 33, 0,134, 84,154,231, 94,200, 50, +141, 31, 95,218,145,199,123,189, 14,231,228, 89,179,102,209,152,152, 24, 26, 29, 29, 77,207,157, 59, 71,159,124,242, 73, 10, 96, +114, 83,190, 71, 15,226,125,103,206,255,110,121, 40,103, 0,171, 84,170,107, 63,254,248,227,241,226,226,226, 21,148,210,210,135, +209,134,135,133, 94,175,239, 85,159,250,199, 17, 74,105, 36,128,230, 85,235, 51,194,130, 47, 0,184,208, 68,235, 56, 72, 8, 57, +121,252,248,241,119, 84, 42,213,176,166,112, 62, 82,204,141, 50, 98,115,235,171, 16,139, 87,181,117,151, 47,122,119, 4, 37, 43, + 79,252,217,124,245,120,109, 66,175,214,138, 88, 8,185,143, 65, 74, 47,227,249, 56,219,255,190,202,156,151, 33, 51,175,234,208, + 76,190,232,163,177, 32, 31, 31,219,217,124,205,147, 78, 9,189, 90, 41, 19, 64,241, 49, 36,134, 11,245,114, 86,130, 82,122,158, + 16, 50,124,221,186,117,223, 24, 12,134,151, 40,165,191,215, 91,162,226,165,161,200,188, 20,102,126, 91, 80,212,124,194, 34,165, + 6,240, 16,138, 44, 94,122, 67,218,250, 32,184,152, 70,227, 1, 52,104, 72,155,154,160,148, 94, 7,224,223,148,206,198, 66, 41, + 61, 73, 8,193,158, 61,123,166,250,249,249,181, 10, 15, 15,143, 54, 24, 12,187, 41,165, 39, 43,205, 67, 9, 33,135, 62,190,121, +179,232,211,240,240,243, 70,142, 59, 95,135,115, 95,185,115,190,159,159, 95, 96,120,120,120,152,193, 96, 88, 71, 41,221,247,224, +123,196, 96, 52,140,135, 18,176,242,243,243, 59, 63,140,245, 50,254, 91,148,135,247,119,203,203,227, 71,165,144,213,217, 83, 54, +247,199, 89, 50, 3, 40, 73,130,144,219, 80,239,112,117,191,243, 50,100,230, 85,221,154,203, 94,251,105,166,204, 0,138, 52, 80, +124,210,152,112, 85, 1,165,244, 60,128,150, 13, 22, 76, 8, 55, 1,136, 5, 33,113,120, 31, 53,159, 28,253, 62,238,253,155,205, +248,231, 41, 15, 83, 39,235,152,135, 2, 56, 85, 94,108,113,238, 3,192, 2, 21,227, 95,195, 99,120, 13, 59,131,241, 31, 98,110, +148, 17, 7, 2,174, 32,147,191, 0, 60,180, 4, 44,241, 40,178,164, 97,110,156,177,145,206, 75,200, 36,243,192,135, 15,196,150, + 40, 20, 26,211, 48,171, 17,206,166,166,236,199,185,230, 0,213,176,225, 75, 25, 12, 6,163,201, 96, 1,139,193,248,183, 83,182, + 87, 39,169,188, 60,186, 78, 6,131,193,248, 15, 65, 0, 4, 85, 55,129, 82,250,171,205, 18, 66,170,117,212, 70, 93,126,230,100, + 78,230,100, 78,230,100, 78,230,124,252,156,117,185,235,147, 63, 30,105, 30,228, 25,244,248,151, 92,185,192,156,204,201,156,204, +201,156,204,201,156, 15,215,249,184, 21,219,239,159,194, 96, 48, 24, 12, 6,131,193,176,137,135,122, 14,150,220,217,199, 21, 2, + 94,123,194, 81, 63, 0,160, 60, 18, 1, 11,119,211,144, 25,153,218, 88,183,202,221,215,145, 66,188,159,192, 56,177, 32,249,118, +118, 99,125,237,124,237,198,235,156, 85, 83,211,178,242,190, 9,141, 40, 8,174,207,178,246,246, 45,236,164,142, 14, 19, 74, 77, +230,182, 98,145, 40,193,148,155,191, 61, 59, 59,170,160,177,109, 98, 48, 24, 12, 6,131,241,104, 82, 99,192,106, 17,216,247,138, + 84, 42,243, 2, 0,142, 82,112, 20, 40,202,207, 13, 73,141,186, 50, 20, 0, 52, 94,157, 79, 8,165,234,206, 28, 45,155,110,229, + 0,139,169, 36, 54, 47,238, 98, 87, 91, 86,172,212,250,142, 11, 26, 18, 52,126,212,168,145,190,237,218,182,107, 13, 0,183, 66, +111, 69, 29, 62,124,228,182, 82,235,251, 99, 97,198,237,159, 26,211, 49, 10,233,135, 93,186,116,236,115,245,234,181,101, 0, 94, +105,140, 11, 0,156,156,148,115, 79,254,176,160,223, 19,227,215, 42, 0,212, 43, 96, 73, 29, 29, 38,140, 29, 61,172,227,155,175, +206,226,189,184,224, 35,175, 43,231, 79,175, 86,185,181,205,165,156,249,100, 81,250,211,127,212,116, 67, 99, 6,131,193, 96, 48, + 24,255, 78,106, 12, 88, 82,169,204,235,226,233,195,142, 63,157, 75, 4, 0, 4,117,114,193,219,203, 55, 15, 33,132,220, 6,128, + 49, 47,190,239,179,108,241,171,248, 51, 44, 3,148, 82,116,108,227,132,225, 99, 39,218,180, 82,153, 75, 64,215,167, 39, 77,122, +102,193,130,249, 99,238,222,189, 27,183,119,239,222, 63, 0,160,111,191,126,109, 62,250,232,163, 73,107, 29, 28, 37, 50,151,128, +228,226,180,240,218,111,164, 88,147,223,189,181,123,128,119,251,169,223,125,181,153, 55, 96,232, 83, 83,100,238,173, 87, 22, 39, + 71, 37,219,178,172, 70,163,153, 39, 20, 10,237, 0,128,227,254,151,123, 90, 53,227,187, 0,128,197,202,169, 28,221,253, 10,248, + 34,169, 85, 34, 17,133, 23, 20, 22,126,147,151, 20,254,101,109,206, 82,179, 57,240,181,217, 47,240,174, 71,103,193, 43,176, 47, +127,195,202,119,192, 89,205, 14,175, 47, 94, 62,225,234,165,239, 0,188,119,166, 33,253,100, 48, 24, 12, 6,131,241,104, 82,235, + 33, 66,165, 76,128,219, 49,105, 0, 0,123, 25, 48,119,230,115,200,202,212,251, 24, 45, 28,254,239,185,105,184, 22,145,138,219, +177,122, 80, 74,225,227, 33,183,121,165,124,112, 93,254,111,250,255,245, 63,113,242,228,229,119,151,188,251, 45, 33,101,163,119, +111,219,254, 69,207,165,239, 45,125,105,218,115,211, 6, 31, 56,112, 32, 12,117,221,169,186,166, 78, 17,213,230, 53,171, 86,136, +147, 50, 75, 74,230, 45, 88,196,205,127, 99,222, 6, 0, 79,217,178,172, 80, 40,180, 75, 74, 74, 82,242,120,247,159,158,246,241, +138, 69,103, 7,143, 95,123, 39, 46, 33,247,250,137,131, 7,187, 6, 4, 4, 32, 41, 57,173,247,234,141,159,119,112,109,221,245, +133,130,252,226,241, 69,250,240,106, 71,141,150, 8,133, 97, 31,172,222,218,145,179,111,195,123,251,165, 17, 8,108,237,134,228, +140, 92,244, 27, 58, 70, 16,114,229,202, 16, 0,103, 26,210, 79, 6,131,193, 96, 48, 24,143, 38, 60, 0, 32,132, 84, 59, 96,159, +213, 74,113, 59, 54, 21,183, 99, 83,113, 57, 66, 15, 19, 21, 98,195,234, 15,176,110,229,123,200, 46,230,225,167, 63, 19, 17, 25, +155,134,200,216, 52,100,230, 20,254,109,121, 90,229, 82,203,117,171,228,157, 54,108,176, 91, 51,164,159, 98,128,163,131,131,195, +157,176,111,139,150,190,145,238,255,193,107,137, 34,161, 81,146,164, 80, 42,122,237,223,255,125,128, 78,163, 85, 40,149,170,133, + 10,143,142, 59,236,237, 59,216,213,230,172,138, 92,231, 63,102,204,200, 97,131, 92, 92,116,220,172, 13, 33, 17,109,253,253,204, +222,109,188,123,203,117, 62, 99,106, 90,166,178,147,227, 56,240,120, 60,164,167,167, 35, 37, 37, 5, 49, 49, 49,136,140,140, 68, + 98, 98, 92, 58, 71,169,208, 10,142,231,234,234, 1,129, 64, 12,175, 22,205,177,117,195, 74,249,242,247,223,238, 38, 85,136,131, + 9, 33,164, 58,103, 73,118,206,129,163,199, 79, 38, 31,219,187,213, 10, 0, 25, 57,133, 56,117,229, 46,174,133, 39,214,214,149, + 90,219,217, 84, 48, 39,115, 50, 39,115, 50, 39,115, 62, 10,206,154,178,200,191,149, 90,175, 34,140, 74,204,198,237,152, 52,116, +246,115, 71,235, 22,174,184, 28,153,131,221,167, 18,177,227, 68, 60, 78,221,208,131, 19,168,144,150, 15,220,137, 75,199,157,248, +204,218,198, 85, 6, 0,240, 37,194,167, 95,123, 45,111, 65,187,128,252, 30,167,143,205,133,187,230, 78,192, 91,111,229,206,229, + 75,132, 79, 59, 52, 83,237, 93,180,224,245,169, 42,185, 92,108, 44, 53,162, 85,203,230,210, 87,231,204,125,129, 56, 72,246,218, +218, 25,181, 71,128,131, 68, 38,251,114,249,251, 11, 37,159,252,116, 39,161,200,136,162, 31, 47,164, 71,207, 95,180, 52, 91, 32, +148,110, 85,123, 4, 56,216,234, 50,155,205, 40, 45, 45,133,209,104,132,201,100, 66,114,226, 95, 99,126,251,233,205,161, 45,155, + 57, 14,149, 72,165,160, 0,242,139, 45,136, 73, 53, 96,224, 19,131,249,157, 59,117, 10, 84,186,250, 79,175,206,149,155, 27,151, +199, 81,190,234,240,207,123,248,223,255,114, 29,223, 30,190,130,224,223,175,227,242,153, 99, 22,202,153,239,221, 78, 66,229,230, +237,163,114,107, 31,175,114,239,144,126,175,120,180,187,106,107,155, 25, 12, 6,131,193, 96, 60, 26,212,120,136,176,164,164, 56, +246,169,167,167,193, 85,235,162, 28, 59,224,121, 81, 72, 84, 46,244,169,241,184, 27, 25, 10, 67,137, 25, 34,135,150,128,212, 5, + 45,188,154,227,230,237, 96,211,166, 53, 71, 10, 57, 75,105,108, 77,190,177, 99,221, 60, 92, 53, 10,222,154,213,158, 23, 35,111, +231,116,222,179,228,107, 60,243,140,210,121,205,106,207,139,113,209, 10,158, 92, 74,123,189,240,220, 20,194, 35, 20,111,189,181, + 0, 99, 71, 13,195,255,189,240, 44,249,230,155,157, 61,108,237, 12, 7,225,167,139,223,249, 64,156,158,107, 49, 94,142, 44, 44, +149, 43,100,178,243,119, 10,139, 2,189, 60,101, 35,198, 63,159,114,100,255,151,159, 0,120,206, 22, 87, 69,176, 50,155,205, 48, +153, 76, 0, 96, 5, 0, 30,175,236, 49,171,192,136,140,220, 82,164,231,150,194, 98,229, 48,254,233,231,100, 87,174,222,120, 14, + 64, 13,231, 99,113,156,217, 98,198,143,191, 92, 67,242,149, 3, 28,225,241,243, 42, 78,114, 7,202,194,149,139,139,231,217, 81, +227,159,213,136,165,101,135, 91, 11,138, 74,241,205,231,171,109,237, 62,131,193, 96, 48, 24,140, 71,132, 26, 3, 86, 92,216, 31, + 93, 1,192,183,235,208, 44,165, 84,224, 40,224, 17,164, 39, 69,225,155,181,243,192,113, 20, 35, 94, 90, 3,149,151, 11,100, 34, + 62, 74, 11,179, 10,179,238,158,118,170,109, 69,132,152, 7,111,217,150,236,245,242,236, 86,234, 61,123, 10,133, 0,176,103, 79, +161,112,246,172,102,234,207,182,197,122,117,239,211, 25,212,106,197,168,177, 79,225,233,201, 79, 35, 46,205,128, 31,206, 38,160, +168,216,104,211,253,207,228, 26,255, 14, 90, 55,247, 97,175, 61, 63, 76, 33,224, 19,226,221,220,142, 41,233,120, 44, 0, 0, 32, + 0, 73, 68, 65, 84,159,168, 55, 91,248,124,161,245,208,149,188,148,241,227, 39, 59,159, 58,250,253, 32,185,198,191,131, 65,255, +215,141,186,124,165,165,165,176, 90,173, 40, 45, 45,133,217,108,134,163,115,203,163,131,159, 90,155,148,154, 86,112, 36, 45,167, +164,123,145,217,130,244,220, 82,100,228,150, 34,183,200, 4, 23,149, 3, 44,102, 99,187,154,124,148,210,111,159,124,106,218,179, + 0,120,132,103,249,186, 32,229,175,200,138,105, 21,225,106,216,216,103, 52,103, 67,162,112,247,234,177, 28,202, 89,204,101, 27, +142, 99,183, 42, 97, 48, 24, 12, 6,227, 95,198,189, 67,132,132, 16, 90,211,241,207,228,244,108, 56, 41, 5,208,184,121, 97,234, +188,117, 0, 0,171,213, 12, 74, 1,139,213,182, 17, 6, 40, 21,254,242,202,108,175,216, 22, 94, 36,111,234, 51,242, 98, 0,152, +250,140,188,184,133, 23,201,123,101,182, 87,108, 65,137,210,100,177, 90,113, 62, 44, 3,107,190,251, 11, 75,119,222,194,241,171, +182, 15,135,197, 23,139,102,175, 94,181, 82, 36,224, 19, 18, 22, 95, 88,152,148,101, 41,228, 11,133, 38,185, 92, 76,141, 84, 80, + 26,151, 73,179,158,120,242,133,187, 60, 62,169,246, 48, 94, 5, 21, 87, 14, 86, 28, 34,172,216,131, 69, 41,165, 4,224, 56, 98, +181, 38,101,150, 32, 81, 95,140,196,140,255,149,244,156,210, 26,143,144,170,220,188,125,236,212,202,227, 14,246,234, 23,236,237, +212,207, 41,100, 14, 39, 84,110,222, 62, 21,211, 42,194,213,197,176, 20, 68, 93,255, 53,221,106, 50, 76, 42, 72,190,161, 43, 72, +190,161, 43, 72,186,213,197,230,141,192, 96, 48, 24, 12,198,191,152,218,178,200,191, 13, 30, 0, 80, 74, 73, 69,169, 58, 3,165, +192,157,248, 76,136, 5, 28, 60, 90,180, 6,173, 20, 35, 40, 0,139,213,182,237, 16, 28,156,146,212,170, 77, 17,183,112, 97, 66, +207,182,237,156,110,206,158,213, 44,162,109, 59,167,155, 11, 23, 38,244,108,213,166,136, 51, 91,132, 86, 90, 62,222, 86,197,216, + 90,229,195,241,219,218,149,110, 29, 2, 90,242, 63,216,115, 39,225,229,207, 34,111,139, 68, 34,179,135,179,156, 52,215,201,249, +158, 26,153,184,212,204, 43,245, 9,236,100, 4,143,116,170,205, 82, 17,176,140, 70,227,125, 37, 75, 31, 53,230,228, 15, 11,198, +186,235, 28,158, 79,214, 23, 35, 33,195,128, 68,189, 1, 9,122, 3, 12,165, 22,220,250, 43, 26,224,139, 66,171,115,170, 85,142, + 39,246,238,254,214,179,131,127, 43,109,128, 79, 11,237,151, 59,191,245,148, 74,237, 79,168,220,188,125, 60,189,124, 67, 46,253, +250,189,230, 98, 88, 10,226,111, 95, 77,179,148,230,239, 45, 74,143,248,173, 30, 29,103, 48, 24, 12, 6,227, 95, 79,109, 89,228, +223,136, 77, 35,185, 55,247,208,225, 82,104, 44,218,249,181,132,157, 90,133,136,168, 36,240,121, 66,240, 8, 96,182,216, 30,130, +168,201,252,221,250,245,118,136,143, 85,240, 62,219, 26,235,245,202,108,175,216,245,235,237, 46, 80,147,249, 59, 0,211, 40, 45, +187, 55, 98,197,192,166, 54,238, 28, 43,115,115,230,102, 58, 71, 57,255,106,116, 81, 22,143,199, 47,117,178,147,114, 78,118, 18, +158,147, 74, 44, 20, 9,249,156,133,242, 76, 30, 90,175, 18,202,113, 29,108,241, 85, 62, 68,104,181, 90, 65, 8,207, 10, 0, 28, +199, 41, 18,179,138,145, 87,194, 71,122,110, 41,114, 10, 76,240,118, 87,224,215, 83, 7, 12, 86,115,241,158,234, 92,124,161,200, +174,181,151, 7,222,254,112, 61,138, 75,173,184,147, 92, 8,145, 68,226,162,115, 9,188, 49,237,229, 69,146, 87,183, 71, 97,250, + 32, 39,188,241, 71, 84,178, 33, 93,186,200,246, 94, 51, 24, 12, 6,131,193,120, 20,177, 41, 96, 41,229, 82, 80,190, 20,127,132, + 68,193, 55,160, 61,118, 30,188,140, 54,237,122, 32,181,192, 2, 10, 94,157, 87, 15, 86, 48,127,145,225, 26,128,107, 99,199,186, +121,140, 27,231, 62,152, 82,225, 47,159,125,158,151, 4, 0, 91,247,245, 7, 5,192,113, 20,148, 2,148, 43, 11, 90, 54, 67, 4, +241,177,169,249, 45,188, 92, 20, 8, 79, 50,149, 42, 36, 34,158,131, 66,204,215,216,137, 69, 34,129, 0, 86, 74, 74, 83, 83,163, + 74, 9, 16,103,139,174,226,208, 96,197,163, 92,233,122,244,137, 39,215,232,227, 18,242,174,122,103, 27, 58,228,153,196,160, 20, +240,118, 87, 32,244,226, 17,107,122,242,221, 59,197,233,183, 63,175,206,197,113,224,155, 44, 28,110, 68,231, 33,183,200,140,220, + 66, 19,122, 15, 28, 45,234, 29, 52, 6,127,132,102,130,179,152,177,250,139, 35, 5, 86,106,126,154,210,112,179,237,157,102, 48, + 24, 12, 6,131,241, 40, 98,211,205,158,173, 28,133,179,147, 35,164, 10, 53, 98,211, 77, 40, 32, 90,228, 24, 40,172,214,178, 61, + 88, 53,237,104, 34,132, 4, 85, 87, 31, 28,156,146,244,243,207,250, 29,193,193, 41,149, 78,224,254,223,158,171,123,143,220,223, + 3, 86, 77, 78, 66,173,191, 30, 60,118, 58,111, 76,119,141, 3,143,207, 47, 22, 9,121,165, 2, 17,223, 36, 18,240,204, 34, 1, +207,168, 83, 11,249,167, 15,237, 19, 83,130,211,117, 57, 75, 74, 74, 16, 20, 20,132, 17, 35, 70, 96,236,216,177,152, 56,113, 34, +124,124,252,181, 60, 62, 49, 82,194,113, 26,113, 1, 90,107, 8, 4, 37,137,248,109,223,199,134,208,243, 63,223,176,150,150,140, +166,149,142,105,222,231,164,148,203,206, 43, 69,137,201,138,156, 66, 19,114,138, 76,176,104,122,226,231, 63, 83, 80,108,180, 34, + 62,228, 64,177, 62, 45,105, 94, 73,250,157, 26,175,194,172,173,239,141,129, 57,153,147, 57,153,147, 57,153,243, 81,112, 62,110, +216,176, 7,139,162,149,171, 2,109,220, 21, 40, 49,105, 81, 98,180,162,168,196,138,124,131, 9,249, 6, 51, 98,211, 12, 8, 61, +216,248,134,148,237,181, 2, 72,249,115,144,178, 96,103,235, 62, 44,177,201,248,225,186,213, 31, 77,218,215,169,163,241,213,145, +174,205,110,198, 26, 83, 8,225, 21,243,248, 2,179,163, 74, 32,140,136,184,169,191,112,246,104, 63,169,197,250,108,109, 30,139, +197,146,231,238,238, 14,224,254, 91,229,248,183,150,141, 61,127,228,173,150,253,199,172,214,124,178, 98,129,129,199, 23,113, 68, + 32, 10,181,154,139,247, 22,167,223,222, 74,107, 57, 97,140, 39,146,254,117,233,122,120, 15,123,199,102,184,155, 92,132,162, 18, + 11, 76, 22, 14, 14, 74, 17,146,110,157, 48,197, 70, 92,253,190, 32,249,198, 78, 27,187,202, 96, 48, 24, 12, 6,227, 17,167,206, +128, 85, 82, 82, 18,219, 39,104, 52, 56,142,194, 74, 1,206, 90,190,167,137,251,223,222, 38,171,185,164,214, 61, 47,182,192,113, +214,203,159,110,223, 49,162, 83,183,254,252, 0, 79, 37,242,179,210,112,241,252,239, 22,112,244,130, 45,203,103,102, 70, 22,202, + 93,188,159,154, 52, 97,220,254,231,254,111, 86,110,191,129, 3, 21, 90,173, 75,105, 82,114,146,225,171, 93,187,205, 39,142, 6, +247,227, 96,153,156,153,121,231,239, 67,206, 87, 34, 55, 55,119, 99,117,245, 79,244,105,214, 27, 64, 75,190,128, 24, 13, 25,145, +138,250,244, 45, 51, 57,113,252, 71, 31,190, 31,247,204, 75,175,139, 91,185,183, 70, 70, 30, 31,177, 73,105,136, 56, 27, 92,154, + 28,121,229,167,252,164,107,181, 94,217,200, 96, 48, 24, 12, 6,227,223, 69,157, 1, 43, 33,188,108, 60,172, 7, 77, 65, 90,198, +180,157, 59,191, 93,254,237,174,125,189, 75,140, 70,119, 10, 81,162,213, 98, 60, 83,104,197, 82, 91, 29,134,180, 59, 87,157,157, +125,218,126,245,197,167,239,124,181,227,179,254,224,172,126, 4,136,163, 4,167,165,102,235,115,117,133,171,218,200,204, 44,216, + 54,248,169,181,197, 89, 89,133,223,214,119, 89, 67,102, 68,154, 82,215,170,217,182, 13, 31,174,225,241,248, 67,172, 86, 78,200, + 89,205,119,173,166,146,143,139,245,183, 15,214,182,247,139,193, 96, 48, 24, 12,198,191, 15,155, 78,114,255, 39,200,206,142, 42, + 0,240,106, 99, 61,153,153,145,133, 0,154,252, 74,188, 91,145,121, 63, 0,248,161,161,203, 23,166, 71,235, 97,227, 40,242, 12, + 6,131,193, 96, 48,254,221,216,116,146, 59,131,193, 96, 48, 24, 12, 6,195,118, 8,128,106,175, 4,168,207,157,178, 27,114, 53, + 65, 93,126,230,100, 78,230,100, 78,230,100, 78,230,124,252,156,117,185,235,147, 63, 30,105,104,249,136,233, 15,162, 0, 8, 98, + 78,230,100, 78,230,100, 78,230,100, 78,230,252,175, 21,118,136,144,193, 96, 48, 24,255, 57,156,157,125,148,206,206, 62, 74, 91, +231, 87,104, 2,116, 10, 77,128,238, 65,182,137,241,120,193, 2, 86, 35, 33,132, 16, 95, 47,229,220, 33,253, 91,254,236,215, 74, + 62,246, 97, 57,149,186, 86, 26,149,103,215,243,106,143,182,195,155,162, 13, 85,218, 35, 9, 12, 12,236, 25, 24, 24,216,147, 16, + 34,105, 10,167, 66,231, 59,165,153,119,207,179,186,214,157,126, 87,186,248, 76,104, 10,103,101, 84,110,222, 78, 42,207, 46, 63, +168,220, 59,228,168,220, 58,228,171,154,117, 57,163,214, 4,180,170,107, 57,207,177, 43,253,150,237, 11,219,235, 57,118,165, 95, +117,211, 29,135,111, 86,189,255,221,221, 21,206, 99, 86,219,252,197,204,184, 31,207, 62,207,216,187, 13, 88,224, 84,223,229, 60, +124,123,134,121,181,237,151,225,238,211,163,218,123,126, 86, 71, 51,191, 94,215, 90, 4,246, 73,111,230,219,235,106,125,215,247, + 95, 69,166,109,213, 83,230,216,252,136,212,177,249, 81,169, 83,171,129,141,245,185,185,185,201,252,253,253,135,245,236,217,115, +102, 80, 80,208,107,157, 58,117,154,209,162, 69,139, 33,132,144,135,118,145,149, 66,231,187,184, 84, 72, 50, 75,133, 36, 83,161, +243, 93, 92,215,252, 74,157,223,114,194,179,166, 16,158, 53, 69,169,243, 91,254, 79,180,209, 22,164, 46,190,205, 21, 58,223,245, +106,215,192,203,114,157,207,232,250, 46,239,232,232, 56, 68,171,213, 62, 89, 81, 28, 29, 29,135, 60,136,118,254, 87,169,247, 7, +156,144,206, 66,165,171,249, 53,177, 84,246, 60,143, 7,117,198,221,139,238, 15,162, 97, 77,133,166, 85,247,171,124, 30,223,163, +114,157,149,179, 38,233,163, 47,117,105, 10,191,111, 11,217,244,119, 22, 78,123, 99,202,164,160,230, 65,163,230, 17, 0,193,213, +205,167,242,236,250, 39, 33,188,150, 60, 2,240,120, 4, 60, 2, 0, 52, 37, 51,250,210,223,110, 62,109,171,179, 2, 59,109,235, +150, 98,165,230,108,159,177,175,184,132,252,186,123,167, 66, 19, 48,184, 72, 31,126,179,177,125, 35,132,104, 90,183,110,221,213, +199,199,199,105,238,220,185, 34, 0,248,228,147, 79,218,180,105,211, 38, 43, 42, 42,234, 10,165, 84,223, 16,175, 66,235, 55,109, +227,218,101,223, 14, 31, 62, 2, 41,153, 69, 88,189,126,203, 0,165,139,207,196,194,180,200, 3,141,109, 51, 0, 56, 56,180, 84, + 11,212, 14,183,230, 45, 92,166, 29, 54,160, 43,191,176,196,130,227,103,175,247,221,189,101,217,101,181, 38,160, 91,190, 62, 60, +186,166,101, 57, 67,222, 18,157,146, 14,227, 12,121, 0, 48,165,234,116,119,165, 57, 72, 35,179, 14,115,149, 8,174, 3,248,177, +206,182,120,245, 57, 33,148, 72,154,243,120, 60, 84,188,247,124, 82,246,254,155, 77,197,241, 73,127,157, 29,218,168,206, 54, 17, +234,230,221,211,192, 23, 56,241,200,255,218, 71,202, 63,167,132,210,252,212,200, 63,234, 29,136,170, 66, 8,177,107,219,198, 62, +112,100,239, 62, 95,157,137,201, 86,120,246,127,253, 8,161,188,207,226,207,174,187, 97,203,242, 82,169,212,225,208,161, 67,154, + 97,195,134,217,233,218, 62,121,198,150,101,148, 98,105,192,225,195, 7, 69,195,134,217,190,153, 21, 90,223,193,224,241,118, 17, + 64,200,113,244, 19, 62, 71,191, 47,204,138,140,162,229,199, 69,108, 69,174,243,155,206, 3,181,249,123,134, 3,185,106, 72,143, +216, 81,159,117, 84, 64, 8,225,203,180,190,207,203,164,210, 5,222,190,254, 62,177, 49, 81,145,249,249,121,235,139, 51, 34,119, + 80, 74,235,113, 87, 87, 0,102,203,155,191,254, 17, 50, 92, 32, 20,146, 97, 79,116,231, 3,248,189, 33,109,170, 64,167,211, 61, +185,121,243,230, 86, 61,123,246, 4, 0, 88, 44, 22,245,254,253,251, 93, 62,252,240, 67, 5,108,248, 27,170, 14, 66,136,187, 70, +163,241, 20,139,197,238, 0, 96, 52, 26,147,245,122,125, 2,165, 52,185,174,101,149, 46,173,157, 9, 4,203,254, 56,123, 86, 0, + 0,125,251,246, 91,222,188,239, 92, 7,190, 72, 89, 92,221,252,102, 99,129, 2,192,235, 23, 47, 93, 32, 0,208,163,123,207, 69, + 10, 77,192,167, 69,250,240,244,134,180,189, 41,144,233,252,186,243,128, 55,122,247, 27, 60,254,233,201,211,120,129,222,158, 24, + 50,120,208, 91, 0, 14,213,199, 35, 16, 8,100,151, 47, 95,110,205,227,241,248, 22,139,165,164, 71,143, 30, 9,141,105,151,187, +111,175, 63, 9,120,205, 76, 22,227, 23,250,232,171,203,171,126,246, 8, 33,124,187,102,157,222, 1, 95,240, 18,199,113,137,249, +241, 87,122, 53,102,125,143, 58,245, 10, 88,132, 16,190,218,163,227,185, 73, 79, 79,109,251,225,194, 25,210, 77,187,126,129, 99, +203,110,225,217, 49,151, 3, 30, 84, 3, 27, 11,159,199,247, 56,121,242,132, 86, 38,225, 3, 0, 10,139,173, 24,110,195,151,173, +189, 87,247,211, 60, 66,124, 43,110,233,109,181,152,164, 2,161,184,132, 0, 0, 41,187, 58,192,217,173,197, 41, 87, 87, 71,249, +148, 73, 65,205,119,237,251, 37, 41, 33, 41,235, 76, 77, 62, 30,143,239, 17,124,240,144,214,221, 73, 10, 1,159,160,176,216,130, + 97, 35, 70, 91,171,155,215,213,213,113,228,148, 73, 65,205,247,124,247,107, 66,106,106,246,145,218,218, 41,119,245,233,172,176, +211, 29, 31, 63,243, 67,167, 18,158, 35,150,174,216,232,124,246,216,158, 51,253, 71, 78,227,226,227, 19, 75, 40, 33,225, 57,217, +169,175, 21,166,222,189, 93,103,167, 81,246, 30, 43,149,202, 86, 74,165,178,195,240,225,195,165, 11, 22, 44, 16, 14, 24, 48,224, +222,244, 25, 51,102,136, 78,159, 62,237,186,118,237,218, 17,110,110,110, 37,133,133,133, 55, 10, 11, 11,163, 41,165,213,246,165, + 58, 92, 92, 52,115,158, 26, 55, 26,131,198,191, 2, 43, 71, 48,227,229,215,113,226,216,143,179, 0, 52, 73,192, 50,203,213, 31, +190, 52,115,129,166, 71,215,142,252,101,123,110, 67, 38, 22, 96,104, 23, 95,242,194,220, 37,246, 59, 54, 45,251, 18, 64,255,170, +203,120,142, 93,233,199, 25,242,150,180,117, 54, 78, 30,211,179, 37, 14,238, 53, 78,246, 8,122, 11, 60,185,221,242,132,224,197, + 17, 0,208,122,248,171, 42, 7,153,108,179,155, 61, 95, 43,177,234, 55,183, 30,254,234,175, 81,199, 54, 21,212,214, 22,161, 68, +210,124,223,222, 61,222, 14, 74, 17,248,124, 2, 1,143, 7, 62,159,160,212,100,197,132,137,147,155,162,187,229, 63,174,222, 35, +120,192, 11, 0,192, 1, 95, 23,103,220, 57, 90,159,247,132,240, 69, 78,135, 15,254, 36,208,218, 73,192,231, 19,240,121, 0,159, + 71, 16,151, 94,140,233,211, 95,176,107,100,251, 52,195,123,107,187,158,254,180,255,208, 30,109, 29,219,127,119,129,216,245, 24, +254,180, 83,102,137,252,249,125,193,191, 79,246,236,247,198, 37, 74,185, 53,137,127,108, 56, 89,155,167,180,180, 52,125,232,176, +225,106, 34, 80,200,127,253,121,103, 63, 1,143,192,108,165,176, 88, 41,172,229,247, 46, 45,251,123, 37,224,241, 8, 40, 71,241, +210, 75,211, 49,116,216,112, 3,103,225,146,106,115,223, 7,143,183,235,248,175,231, 53,165,102, 14,107, 55,239, 88, 86,148,167, + 95, 22, 19,225, 20, 39,215,249,188,110, 72,143,180,249,190, 21, 60,208, 46,137,209,161, 51,247, 28,190,136,182, 1,254,176,114, +101,237,244,245, 80, 96,207,145,139,240,243,245, 43,107, 55, 71,225,211, 76,137,174, 93,186, 2, 64,189, 3, 22, 33, 3, 4, 10, +157,223,222, 49, 19,158,155, 48,126,194, 20, 56, 58,168, 97, 52,149,250,252,118,226,232,246,173,155, 87,247, 38,132, 60, 95,175, +112, 72,173,247,126, 23, 40,199, 53,122, 47,147,155,155,155,166,107,215,255, 13,167,104,177, 88,224,229,229,133,228,228,100,223, +250,186, 8, 33,114, 87, 87,215,145,219,182,109,211,142, 24, 49, 66,232,226,226, 2, 0, 72, 75, 75,115, 63,126,252,120, 39, 55, + 55,183,140,212,212,212, 35,148, 82, 67, 77, 14,171,153, 39,226, 9,192,151, 74,229, 0, 0, 10,194, 91, 48,231,217,246, 58, 87, +183,210,234,230,215,235,211,196, 11, 95,249,157, 8, 4,162,242,249,193,163,148, 35,213,205, 11, 0,142,142,142, 65, 66,161, 80, + 86,221, 52, 19, 95,221,131, 10,237, 94,228,241,121,101, 31, 86,139, 89,159, 29, 31,226,111,107,255, 21, 58,223, 64,161, 88,180, +245,153,231,102,246,154, 48,126, 44, 92, 53,118,248,245,220, 77,204,154,243,134,217, 98, 50,175,183,213, 83, 25, 62,159, 47,200, +200,200,136,115,112,112,112,105,200,242,247,185,120,164,229, 47, 39,142,105,127,253,237,212,162,117, 27, 54,205,118,243,233,107, +230, 40,189,119,159, 97,207,182,131,132,131, 71, 77, 82,107, 91,247,144,110,122,239, 69, 97, 99,215,247,168, 83,175, 63, 30,165, + 91,192,107, 19, 39, 77,106,251,202,172, 25,210,215, 54,159,195,111,123, 63,201,108,170,112,165,210,250,246, 36,124,193, 76,194, +231, 43, 8,143,136, 57, 43,151,104, 49, 26,151, 27, 50, 35, 83, 27,235,182,114,192, 15,231, 51,234,181, 12,161,104,179,235,251, +159,181, 58,123, 9, 74,140, 22, 60, 61,101, 26,118,237,250, 86,229,172, 22,163,196,104,193,154,117,235, 10, 10,227,142,104,227, + 18,115,146,131, 70,191,113, 50, 58, 54, 35, 52, 33,181,228,251, 26,125,132, 7,173,157, 4, 43,246, 69, 66, 45, 19,194, 65, 37, + 2,143, 71, 42, 77, 39,196,167,133, 98, 78,179,102,154,129, 41,169, 57,121,149,156,187,107,114, 42, 92,219, 13,181,115,112,219, + 59,110,230, 10,251, 59, 25, 2, 80,152, 16,165,150, 98,210,243,175,170, 91,185,200,160,144,242,237, 99,226,147, 93, 23,188,249, +230, 57, 59,109,235,110,121, 25, 81, 49,117,245,187, 69,139, 22,227, 71,141, 26, 37,159, 63,127,190,176, 89,179,102,248,122,207, +254,230,125,135, 78, 28,157,146,154,222,140, 82, 10,157, 86,155,248,210, 11, 19, 15, 29, 61,122, 52, 62, 49, 49, 81,184,122,245, +234,238, 63,253,244, 83, 0,234,241,159,168,149, 82,148,148, 90, 97, 45,255, 97,212,231, 85,251,189, 86, 35,132, 16,226,238,238, + 46, 73, 78, 78, 46,173,248,225, 32,132,220,219,152, 74,247,142, 67,159,232,223, 93,176,237, 88, 44, 10, 75,172, 80, 72,133,136, + 77, 55,160, 75,199,118,228, 11,171,165, 67,117,206,233,147, 70, 46,209, 41,233,176, 49, 61, 91, 66,235, 32,199, 87,159,174,192, +193, 11, 49,195,210, 11, 9,156,199,172,158,233, 42, 17, 12,214,200, 69,155, 7,116,105,237, 50,168,115,115, 92,233,210,218,229, +108,200,237,200,118,147,214,207, 77, 46, 20,254,154,125,108,110,181, 65,139,207,227,193, 81, 37,198,151,199,227, 32,151, 10,160, +144, 10,160,144,148, 61, 86,126,255, 27,130,204, 45,160, 25,159,179, 78, 87,187, 5, 76,159, 60,105,162,219, 51,147, 39, 82,240, +121,216,255,195,161,177,187,119,239, 74, 85,186,248,126,105,229,241,119, 20,167,132, 39,214,229, 34, 60, 64,107, 39,198,155, 95, +134, 66, 45, 19, 66, 37, 23, 66, 45, 23, 98, 80,123, 13,248, 13, 60,145,128, 16,226, 48,107,108,171, 17, 55,191, 13, 26,232,235, +169,244,190, 17,149, 23, 62,125,249,213, 13,167,115, 7,190,246,233, 39, 1, 78,133,185, 70,193,210, 5, 47, 9,146, 82, 82, 6, +238, 63,116,102,144, 91,183,233,183, 45,166,162,183, 51,110,124, 95,237, 30,219,196,136, 63, 59,121,244,156, 40, 53, 21,154,111, +221,184,157,212, 58,167, 84,130,176,184,124, 40,164, 2, 40, 43,182,173, 84, 0,133, 84, 8,165, 84,128,148,164, 88,100, 23,241, +207, 37, 59,241, 6,210,211,127, 90,234,211,246, 18,147, 21,215, 99, 10,209,194,183, 35, 92, 93,221, 96, 28, 49,181,197,165, 83, + 63, 4, 43, 92,253, 87, 22,165,254,245,182,173,158, 61,135, 47, 98,209,235, 51, 67, 8,112, 13, 0, 40,208,105,233,170, 45,157, +151, 45,122,229,190,186, 5, 31,108,234, 92,159,246, 85, 64, 8,225,203,117,190,187,251,143,156, 54,161, 93,143, 33,136,142,141, +197,177, 67, 87,241,196,224,225, 24, 49,122, 60,140,198,210,103,119,108,219,116, 5,192,150,170,203,170, 92,253,251,180,107,235, +191,219,221,205,173, 25,199,149,221,149,131, 82,160, 79,255, 65, 88,248,218, 75,224, 40, 69,135, 78,221, 6,141,152, 60,151, 82, + 90, 22, 4, 51,179, 50,139,110, 71,132, 7, 21,167, 71, 92,178,181,141, 37, 37, 37,102,189, 94,143,235,215,175, 35, 50, 50, 18, + 97, 97, 97,200,202,202,130,157,157, 93,189, 6,126, 38,132,168,219,183,111,255,204,169, 83,167,164, 14, 14, 14,247,234,141, 70, + 35, 84, 42, 21,158,121,230, 25,225,144, 33, 67,220, 71,142, 28,249, 28, 33,100, 15,165, 52,191, 58, 79,113,214,157, 20,181,139, +223,231,253, 7,244,159, 13, 0, 50,181,107,204,230,175, 15,133,213,182,110,153,157, 91,243, 94,189,122,183, 6,165, 32,160, 27, +139, 50,111,167,213, 52,175, 64, 32, 80, 92,188,120,177, 21,159,207,191,247,251,202,113, 28, 62,251,234, 59,191, 95,254,184, 53, +126,213,154,181, 82,181, 66, 2,125,158, 17, 47, 78, 29,103,243,111,176,220,197,111, 68,239,222,253,131,151,125,240,174, 64,169, + 80,224,228,165,104,204,125,237,205,146,212,184,208,181,148, 19,110, 41,202,184, 93,191, 31,185,191,211, 36, 3, 94,123,123, 40, +161, 26, 51, 84, 58,235,217, 49, 82,163,217,138,220, 34, 51, 74, 77, 86, 88, 57,138,188, 34, 51,194, 19, 10,224,172, 22, 55, 68, +221, 21,128, 6,128, 30,192,149, 42,175, 81,254, 28,213,188,206, 68,217, 62, 17, 39, 0, 70, 0,149, 87, 94,241,186,166,250,138, +229,195, 1,248,151, 59,173, 0, 46, 3,200,169,171,193, 2, 66, 8,165,148,222,251,166,175,250,186, 50, 34,177,114,210,162,185, +211,164, 31,238, 9,193,111,123, 63,202,212, 71, 93,168,232, 0,180,173,187, 95,203,136,186,255,112, 23,181,225, 82, 75,153, 91, + 64, 51, 1,225,175,239, 63,160,223,144,217, 47,191, 12,223, 86, 30, 34,171,213, 74, 67, 35, 99,204, 59,119,124,245,188, 93,179, +118, 27,242,147, 66,151, 84,236,106,180,197, 89, 25, 43,103, 77,170,186,199,202,202, 89,239,251,111,182, 58, 39, 33,128,189, 66, +132,207,143,198,128, 82,128,128, 66, 45, 23, 98,223,233, 36,196,132,252,152, 63,170, 67,126,209, 51,171,222, 31, 52,112,196,171, +167,194,163, 74,190,207,200, 40, 57, 65, 41, 77,171,201,201, 35,128,128, 79,160,150, 11, 97, 39, 23,193, 94, 33, 2,169,244,195, + 85,249,176,224,128, 17,175,254,114,234,124,252,219, 0,244,148,210,210,234,156, 50, 23,239,174,106,123,143,239,199,207, 94,173, +186,149,100,129,128, 15,180,116,145,193, 81, 37,130,209, 66, 16,167, 55,149, 45, 3,123,204, 93,240,129,227,162, 55,102, 31, 37, + 36,160, 45,165,225,166,218,250,110, 48, 24,196,211,166, 77, 19,154,205,102,211, 51, 47,206, 27,146,150,166, 31,251,217,198,143, + 37, 90,173, 14,134, 18, 11, 66,194,238,250, 47, 91,246, 65,203, 67,199, 79,255,252,254,155,179,130,135, 13, 27,102,247,221,119, +223,113,181, 57,171,162, 79,207,252,244,171,221, 7,190,253,100,237, 71,184, 29,159,131, 29,219,182,128, 90, 45,159,215,182, 76, +101, 39,165,148,190,253,246,219,178,159,127,254,217, 67,161, 80,228, 27, 12,134,202,135, 42,121, 60, 30, 17,164,103, 27,224,172, + 18, 67, 36,224, 65,231, 32,133,214, 78, 2, 33, 31,224, 17, 98,173,206,185,227,251, 35,203, 57, 67, 30, 14,238, 53, 78,254,234, +211, 21,248,191, 57,239, 32, 52, 83,124,156, 39,183, 91,254,202,228,241,139, 52, 50,235, 48, 55,123,158,118, 80,231, 22, 80, 72, + 69, 88,252,234, 52,116, 11,137,211, 38,231,114,239,232,139,249, 29, 1,188, 83, 93,223,121, 60, 2, 1,159, 64, 37, 23,226,248, +238, 53, 25, 69,121,250,188,138, 67,111,198,210,146,248,218,250, 92,219,246, 84,232,124, 23,117,238,216,126,197,236, 25,211,121, +189,123,118,163, 60,158, 16,153, 5, 70, 66, 41,240,218,220, 89,120,101,214, 75, 46,137, 41, 25, 75,183,108,249,124,137, 82,235, +255, 97, 97,198, 95,239,215,230,228,145,178,189, 62, 74,169, 0, 74, 89, 89, 96, 81, 74, 5, 40, 49, 90, 65,254,159,189,251,142, +111,170,220,255, 0,254,121, 78,102, 51,186,119,161, 45,179,236,189, 55,200, 18, 5, 5, 68, 65,112,224, 0, 68,175,202, 21, 21, +113, 32, 23, 5, 68,134,160,168, 12,153,138,202, 18, 68,150,236, 97,101, 21,202,106, 11,165, 3, 74,119,155,166,217,243, 60,191, + 63,218, 98,129,142, 20,235,239, 94,241,251,126,189,242,162, 73, 79, 62,121, 78, 72,210,111,158,113, 14,131,196, 63,186,131,158, +149,244,220,102, 22,164, 85,252,141,251,206,204,128,168,150,251,127, 77,241,110,166,251, 81, 23,155,154,121,241,163, 51,241, 57, + 39, 57,231,133, 81,125,254,253,140,195,197, 97,180,186,144,154, 99,134,203,193,217,115, 67,162, 81,127, 20,107, 58,123, 85,220, + 58,198,152, 79, 89,225,124,103,102, 70,236, 70,107, 80,235,145,163, 23, 45, 89,118,106,254,199,239, 74,242,245,118,136,156,195, + 75, 33,129, 74, 33, 45,189, 72, 96, 49,233,177,244,171, 21,217, 46,176,145,252,208, 33, 87, 85,237,188,139,200,199,141,120,168, +247,247, 12, 80, 48, 65,158, 17, 17, 93, 47,186,255,176,103,189,250, 63,242, 20,220, 46,251, 52, 77,104,179,131,166,156,132,253, +158,100,182,106,209, 28, 12,136, 51,230, 36, 78, 2, 0,109,104,211,175,155, 53,109,214,225,206,219, 26, 55,110,122, 87,129, 85, + 89, 38, 99, 76, 80, 5,199, 76,104,220,172,245, 91, 47,189,191,172, 94,106,150, 25, 1,145, 49,184,120,254, 44,118,253,240, 69, +156,197,160,155,191,107,251,150,183,102,125,178,184,237,176,225, 79, 96,219,214, 31,222, 96,140,125,201, 75,252,241, 62, 18,197, +113,107, 86, 46,143,148, 41,148,112,186, 68, 56,221,188,228, 95,151, 27,133,133, 58, 56, 93, 34,188,212,222,112,137, 12, 78,183, + 8,167, 75,132,205,238,210, 76,122,234,225,201, 0, 78, 84,212,206,186,205,251,238,145, 43,149,209, 28, 37,231,150,229,156, 67, +226,178, 11,225,225,225,223, 1,128, 82,169,132, 82,169,132, 40,138, 56,147,152,247, 74,112,179, 1, 47,161,180,176,115, 59,236, +233,186,212, 99,131, 43,219,247,176,176,176, 97,119, 22, 87, 86,171, 21, 70,163, 17, 71, 99, 79,249,174, 92,183,233,193,212,244, +140,134, 34,247,181,121,135, 52, 28, 12,224,182, 57, 73,229, 51,139,179, 19, 38, 71,118,155, 32,188,241,242, 51,141,151,172,217, +113,242,202,238, 89, 85,206,195,106, 48, 96,154,253,141,137,143,117,156,187,248,155, 43,133,199,190,154, 82,221,255,145, 84, 42, +149,229,229,229,165,151, 93,255,124,197,134,142,113,137, 55,135,127,182,232, 51,175, 51,215, 12, 56,159,154,137,103, 6, 68,225, +182, 63, 2, 85,100,106,195, 26, 5, 53,106,212,236,187,165,139,231, 74,175,100, 90,241,197,150,147, 56,176,237,235,163,217,185, + 39, 30,228,217,153, 21, 14,109, 86,151, 89,209,102, 30,108,227, 81,230,193,248,124, 24,173, 46,216,236, 46, 56, 69,142, 98,179, + 19,185, 69,118, 20,155, 29, 48, 90, 92,120,102, 96, 84,133,247,171,166, 30, 9,102,140,237,224,156, 15, 69,201,225,165, 20,229, +174,131, 49,182,163,180, 93,183, 93,159, 54,109,218,244, 57,115,230, 92, 44,219,182,236,246,178,109,171,186,189,220,253, 3,223, +121,231,157, 86,115,231,206,157,221,173, 91,183,239,127,251,237,183, 20,120, 82, 96,149,223, 9,198, 88,149, 79,176, 82, 46,141, + 80,123,251,151, 20, 28,127,116, 24,160, 94,171,190, 5,159,205,251, 79, 64,120, 76,215,244,172, 43,191, 71, 87,247,160,101,188, + 67,154,116, 87,169,212,191, 44, 88,176, 0, 99,134,245, 82, 93,207,119, 26,227,175, 91,114, 76,118,184, 66,130,155, 40, 62,154, + 61, 87, 59,119,222,167, 47,239,216, 46, 22, 1,248,180,162, 12,191,250,157, 78, 75, 88,185, 57, 86,140,129,139,238,140,194,212, +147, 29, 1,224,207,204,181, 50, 89, 93,144,148,206,157, 97, 12, 48,219,220,144, 72, 88,110, 81,226,143,151,198,206,250,232,129, +245,223,255,154,201, 5, 63,131,201,148,170,230,156, 87, 57, 4,193, 4,134, 98,179, 19,190,106, 25,252,180, 50,248,106,228,144, +148,123,115,149, 13, 11,174,223,176,247,102,122,122,193, 41,148, 20, 87,149,102, 74, 37, 66, 10,119, 59,173,156,187,189,135,118, + 10, 70,136,159, 2,225,254, 74, 40, 21, 82, 56, 93,128,197, 46,194,106,119, 35, 45,215, 2,131, 69,133,214,125, 30,111, 16, 24, +126,218, 22, 24,221,233,167,130,244, 83, 35,171,106,171,219,237,198,154,239, 54, 53,206,204,204,121,116,231, 79,223, 42,243,138, +157,136, 79, 51, 33,183,200, 6, 72,130, 49, 99,246, 23,202,183,167, 76, 24,190,102,195,230,244,254,189,186,164,215,240,105,133, + 41, 55, 97,125,235,238, 15,127, 61,116,232,112,213,197, 19, 59,113,229,236,254,143,141, 57,158,207,191, 98,140, 9, 27, 55,110, +116, 77,152, 48,193, 48,123,246,236,200,237,219,183,215,207,203,203, 59, 11,192,233,231,231,215,172, 73,227,232,115,123,119,239, +170,243,240,240,199,101, 25,249, 22,248,170,229,136, 14, 81, 35,246,232, 30,167, 66, 33,171,112, 62, 73,233, 48,224,147,117, 7, +188,141,237,177, 41, 15, 94, 44,240, 58,244,226,243,207,164,239, 61,146, 88,240,249,186,189,159,212,209, 58,207,122,137,121,159, +159,238,216, 40,108,218,191,158,194,156, 37,235,113,248, 76, 98,174, 73, 8,255, 56,203,230,250,245,195,209,111, 85,216, 86,137, + 80, 82, 88,123,171,100, 48, 21,231,233,175,158,217,213,164,166,207, 87, 37,158,217,251,211,122,161,208,224,196,141,124, 43,203, + 44, 52,192, 45,114,248,169,229,112,137, 28, 69,133,249,236,219,245,235,112,234, 84,172, 0,137,240, 2,128, 15,171, 10, 19, 88, +201,144,160,214, 75, 86,210, 3,164, 42,249,215,233, 22,209,180,113, 35, 44,255,124,161, 79, 80, 72, 40,122,246,246,124,206,179, +119, 96,116,219,239, 87,127,142, 67,191,197,245, 61,252,217, 23,157,180, 17,193, 75,124,234,182,152,239, 91,127,160,213,230,112, + 67, 95,164,131,194,126, 3,157,235,228, 33, 64,237, 70, 90,113, 56, 46,100, 95,209, 86, 55,156,149,127,126,203,217,224, 86, 35, +222,219,244,243,129, 57,131, 7,246,197,133,180, 98,168, 20, 82,120, 41, 36,240, 82, 72, 32, 99,110, 44,252,234,107,167, 78,111, + 24,154,127,225,167,124,143, 27, 92,202,148,155,176, 15, 37,223,118, 1,148, 44, 32, 89,191,228,189,181, 47,190, 53,111,240,131, + 35,158,101, 23, 78, 29,156, 14, 96,127,229, 9,127,112,139,119,239, 74, 69,183,137, 21,220, 86, 17,198,152, 16,210,168,227,119, +171,215,108, 24,221, 34, 38, 18, 57, 69, 78,100,234, 28, 56, 26,151,140,181, 43,223, 43,210,229, 92, 27, 7,135,209, 40, 50,151, +126,207,238,159,119,191,242,218, 91,104,217,170,109,189,226,140, 98, 31, 0,250,219, 30, 83,194,150, 61,253,252,196,209,161,161, +161,222,127,244, 96,113, 52,105,218, 2, 15, 61,242, 24,246,108,219,138, 75, 23,227, 33,242,146, 66, 73, 20, 57,138,116, 5,217, + 46,167,125, 77,101,237, 83,120,121, 69,175, 90,189, 46, 70, 16, 24, 28, 78, 17,118,151,136, 41,147,199,219, 39,189, 62,189,231, + 67,131,250, 92, 84, 72, 80,156,118, 61,203, 47, 54,238,114,107, 81,166,141,124,126,234, 66,185,213,230,134,222,236,196,206,111, + 42,175,113, 84, 1,209,221,218,118, 31,254,252,164,247,151, 43,149, 18,193,209,178, 73,100, 74,159,174, 45,111, 68, 69, 4, 25, +254, 51,247,139,206,199, 78,196, 61,244,196,216,231,189,158,105,214,129, 69, 4,170,188,199,143, 29,209, 70, 19, 24,245,180,169, +224,122,165,167, 54,147,169,253,139,162,234, 55,190, 53,148,168, 14,107,186,133,113, 52, 40,191, 13,103, 72, 49,103, 39,142, 4, +128,240,136, 40,171, 76,233, 83,229,148,128,219,238, 91,250, 58, 94,178, 98, 67,199,115, 73,153, 47, 46, 90,244,153,250,204, 53, + 3,206, 94,211, 67, 41, 23,224,112,138, 96, 30,118, 98,139, 92, 50,241,221,119,166,249,232, 76,110, 28,138,207,195,197,211, 7, +185,221,104, 29,171,118,249,140,212,132, 54,125, 26, 64, 35, 0,201,140,241,101,166,156,176,109,156, 31,170, 81,143, 45, 80,210, +203, 6,148,204,233,117, 75,149, 15,201, 20,154,110,140,241,150,140,195, 31,224, 55, 11, 74,255,166, 86,185,207,229,126, 54,229, + 36, 97,222,236, 15,176,120,229, 86,100, 22, 88,225,235,190,129,109,223,124,132, 55,230,124, 7,139,173,242,217, 11,213,213, 35, + 21, 21, 68,119, 22, 90,101, 63,151,109, 55,103,206,156,161,183,181,179,244,247,119,181,255,142,219,203,223,127,238,220,185,179, +203,253,190,210, 33,232,242,164,165, 33,172,186,157,242, 9,110,209, 80,238,163, 85,250,168,100,168, 31, 21,142, 49, 47,125, 24, + 20, 22,211, 35, 87,169,144, 74,126,218,176, 60, 32,223,162, 4, 19, 4,147, 39, 15, 10,148, 76,210,243,246,246,222,185,101,243, + 86, 52,140, 10,145,127,123,180, 48, 53, 46,197,114,171, 75,183, 56, 47, 93, 81,223,199, 44, 29, 57, 98,132,122,255,129,131,175, +163,146, 2, 75,194, 36,117, 87,172,219, 28,226,173,146,129, 49,192, 96,113,225,197,167, 31,243,180, 25,149,227,162,228,185,103, +159, 6, 43, 45,174,138, 11,178, 49,253,173,151,172, 26,231,149, 75,215,211,174,223, 28, 48,236,141,253,197, 70,102, 29,253,212, +228, 83,151,146,230, 84, 91,201, 66,116,102, 60,244,240, 67,242,146,158, 2, 64,194, 24, 68, 46,230, 52,173,175,253,215, 93,195, +130,217,182, 21,213, 21,108,134,155,137,133,222,225,173, 71,173, 95,240,202,138,136,208,144, 64,173, 70,197,181,106, 37,107,217, + 44, 70,222,181,107,119, 69,253,166,109,228, 71, 47, 91,112, 61,207,130,148, 76, 61,148,161,237,164, 99, 30, 24,130,245,159, 77, +237,203, 24, 19,170,155,248,250,235,161,223,135,173,252,106,145, 50,167,200,129,132,235, 70,100,235,172,200,210,217,144, 93,104, +133, 86, 37, 67,239, 71, 38, 40,127,217,182,108, 88,255, 94, 93,150,212,240,153, 5, 0,164,164,164,254,146,118, 51,235,241, 54, +237, 59, 99,253,218,213,189,252,253, 27,248,232,116, 41, 21,118,233, 87,128,127,244,209, 71,138,185,115,231, 74, 63,255,252,243, +226,174, 93,187,134,189,243,206, 59,131,115,115,115, 79,214,171, 87,175,233,158, 45,107, 14,180,235,253,104, 39,136,142,224, 94, +125,250,201,149,162, 20,123,119,236,112,252,248,195,183, 5, 22,139, 97, 82, 85,193,130,218,247,163, 28, 35, 67,112,157, 58, 23, +181, 10,247, 64,169, 80,148, 84,184,235, 95,235, 0,108,105, 52,228,213,125, 7, 79, 39, 38,117, 60,147, 22,114,224,204,213,220, + 66,179,163, 73,242,174,127, 87,249,129, 43, 97, 12, 82,137, 0,111,149, 20, 66,233,167,169,119,157,182, 87,193, 88, 48, 80,242, +218, 98, 96,165,255, 2,140, 33,179, 48, 61,206,131, 57, 25,140,139, 28, 72,204, 48,193,104, 45,233,130,175, 27,164, 70, 94, 78, + 6,190, 92,178, 6,113,167, 79, 97,208,144, 71,176,116,197,183,120,241,233,199,173,213,165, 9, 66,105, 15, 86,185,222, 43,173, + 74, 10,128,161,200,228,196,230, 99, 55,208,168,129,224,241, 31, 4, 0,240,214,170,161, 55, 88, 32,200,189,145,124,102,167,122, +215,193, 19,239,188, 55,107,209,155,186,172,248,235, 87,207, 31, 69,211, 32, 61, 26,212,113,224, 98,182, 15, 78, 23,212, 71,211, +198, 13, 33,200, 79,121,148,157,127,177,245,188,109,194,230,161, 29,219,181,232, 22, 29,226, 7,139,221, 93,218,139, 37,193,234, + 85,235,144,150,154,241,124,254,197,159,226, 60,111,109,229,140, 57,215,242,188, 66, 99, 94, 62,127, 98,127,202,136,177, 47, 35, +188, 78, 84,133,195,204, 21,169,168,112,170,232,182,138,138,174, 59, 49,198,132,128,122,237,214,174, 93,191,113,116,131,168, 48, +252,122, 34, 21, 39,147, 10, 16, 20, 20, 8,137, 58, 12, 49,125,198,251,157,223,189,248, 49, 75,190,113,173, 76,174,126,161, 75, +215, 30,224,156, 35,241,242,197, 66,189,222,247,174,207,102,115,102,194, 89, 0, 62,229,111, 83, 7, 55,111,171,245, 13, 56,107, +115,184,113,243,102, 6,142,255,118,168,125,233,118, 30, 83,202, 37,216, 27,151, 11,135, 83,132,195, 37,162,119,159,129,118,185, + 96,235,245,241,162, 85, 93,179, 50,179, 4,141, 79,144, 24, 80,167,185, 60, 92,233,176,157,187,166,151, 59,156, 34, 26, 70,104, +170,204, 12,142,104, 60,123,234,212, 41,205, 37,114, 21, 12, 38,155, 61, 43,243,102,216,242, 13, 7,141,151, 19,206,215,169, 27, +226,235,243,201,103,160,118,160, 3, 0, 0, 32, 0, 73, 68, 65, 84,203,228,197, 86,134, 92,189, 13,133,134, 98, 54,118,226, 91, + 17, 43,191,152, 51, 14,128,199,231,142,101, 28, 13,126,217,123,180,153,191,183,156, 25,173, 46,177,160,216,225, 30, 59,252,207, + 45,162, 44, 45,174, 38, 44, 90,248,153, 58,238,154, 1,231,174,233,225, 37,151, 64, 33, 23, 96,119,138,240,228,237,196, 24, 19, + 26,180,234, 51,169,123,199,214,216,115, 54, 31, 18,137, 0,139, 65,103,150,162, 32,169, 99,223, 65,234, 14,157,187,162, 95,223, + 62,184,154,148, 24,181, 99,251,230,254,177,199, 15,103,107, 67,154,190, 98,204, 77,220, 90,147,182, 26,205,102,137, 83, 17, 54, + 62,188, 78,189, 30, 35,199,140,247,141,142,170,195, 66,130, 2,225,226, 82, 76,120,250, 49,143,223,249, 37, 5, 57, 48,119,214, + 59,176,217,236, 8,246, 83,128,115, 96,213,146, 15, 97,183,219, 17, 17,168,132,222,228,172,244,254,213,213, 35,149,245, 58,213, + 68,249, 34,172,170,219, 25, 99, 59,166, 77,155, 54, 29, 0,159, 54,109,218,244,178,235,115,230,204,177, 0,200,172,238,113,254, +152,204, 88,201,176, 32, 0,120, 71,196, 52,241, 15,137, 56,246,227,218, 47,252,117, 70, 7,188,228, 18,212,141,140,198,219,255, + 89, 28, 60,164, 99, 16,242,172,106,108,220,180,186,208,110, 53,255,224,201,206,169,195, 98, 58,122,107,124,246,172, 93,255,131, + 24, 20, 24, 40,124,185, 55,239, 90,129,193,117,107,232, 42,233,196,118,241,244,158,229,225, 28,108,183,151,151, 87, 99,187,221, +238, 95, 85,158,200,129, 85,123,211, 75, 39,231,254,185,121, 45,101,152, 68,226,254,246,219,245, 8,244, 81,192,230, 20, 49,237, +205,215, 44,207, 12,210, 22,141,125, 98,204, 3,253, 30,122,245,128, 76, 19,179,191,123,251, 24,222,174, 93,187, 34,137, 68, 82, +109, 94, 65,202,201,187, 86, 75, 52,171,175,126,225,221,183,158,121,183,130, 97, 65,143, 38,228, 26,178,206, 31, 3,112, 91,143, + 8,107,212, 72,241,221,198,109,175,141,122, 98,244,123,117,218, 14,215,166,102,233, 33,103, 14,116,106, 30,142,131,187,183,242, +140,180,164, 41,158,172, 42,202,205, 43,140, 12, 14, 14, 69, 92,138, 17, 55, 11, 44,200, 46, 45,174,178,116, 54, 24, 44, 6,180, +137,142, 64,145, 94, 31,233, 73, 59, 43,194,128,173,123,246,236,121,252,161, 71, 71,227,213, 55,103,246,252,230,171,249,241,218, +176, 38,207, 25,179,147, 14, 85,119,223,210,119, 94,225,219,111,191,221,104,197,138, 21,194,184,113,227, 44,173, 91,183,246,122, +234,169,167,122,174, 91,183,206, 75,173,246,178,156, 59,186,253,189, 23,254, 53,237,209,229,139, 63,106,171,211,233,152,203,233, +220,229,208,233,166, 25,170, 41,226,174,111,123, 39,129,181,152,249,236,192, 94,193,219, 3,212, 66, 75, 37,183,143, 97, 45,102, +254,192, 47,205,112, 36,239, 90, 98,104,253,196,194,127,101, 22,137,239, 90,133,144,143,171, 43,174, 0, 64,144, 48,216,157, 34, +188, 85, 50, 8, 66,105,143, 37, 23,195, 87,255,176, 75, 29,236,171,128, 76, 34, 64, 42, 41,233,221,204, 47,118,224,229,241,158, + 30,233,131,139, 46, 55,135,197,238,130,185,244,219,160,161, 56, 31,239,188,249,111, 12, 25, 54, 2, 47, 76,250, 55,116, 22,224, +116,138, 1, 14,167,179,218, 55,133,192, 4,152,109, 46, 60, 55, 40, 26,133, 70, 7, 76, 22, 23,236, 46, 17,106,133, 20, 50,169, + 0,141,151, 20, 62,106, 25,192,185,156, 49, 54, 1, 0,100, 50,153,213,225,112,172,175,180,133,156,163,126,100, 40, 44, 78, 1, +157, 71,207,199,128,110, 77,112,241,216,102,233,225,223,207, 55,120,253,205,119,241,218,139,195,176, 41,161, 17, 2, 66,162,161, +213,168,224,228, 2, 0,238,209,132, 60,206,103,136,225,205, 70, 62,249,245,138, 85,137,255,249, 96,154, 87,145,137, 65, 41,151, +224,192,254,125,136, 61,113,122,113,222,197,159, 42,109,215,189,144,113, 33,212,199,199, 7, 94, 10, 9,236, 14,155,221,211,251, +185, 69, 14, 14,180,215,134, 54,253, 26, 40,153,111,229, 22, 81,193,109, 85, 23, 88,140, 49,230, 27,209,106,245,215, 43,191, 29, + 23, 17, 22,130,173,251,227,177,122,197,231,104,208,110, 40,142,253,178, 26,190,245,187, 66, 19,213, 19, 10,239,141, 19, 4,137, +180,245, 43,175, 79, 31,217,161, 83, 55, 28, 63,122, 0,185,217, 89, 95,115,158,224, 81,143,134, 68,198, 94,125, 96,224, 48, 88, +237,110,244,234, 63, 20,187,127,222,250, 47,148, 46,158,240,212,157, 69,184, 8,193,245,239, 41,175,202,114,245,118, 89,190,222, +142, 27,249, 22,164,101,155,240,211,247,223,120, 60, 36,197, 96,239,212,187, 77, 93,217,132,121, 7,110, 68,214, 13,183,201,108, + 22, 85, 82,242,181,102, 47,140,127, 70,214,160,113, 51, 33, 87,111, 67,158,222,134,124,189, 13, 70,171, 11,141,235,198, 8, 78, + 23,235, 86,147,118, 3, 64,144,175, 66,182,244,231, 20,248,104,100,232,222,236,222, 23,206,138,162,248, 71,113,181,168,164,184, +138, 79,209, 67, 41,151, 64, 41, 23,160,148, 75,224,114,115,143,190,176,168, 66,154, 60,244,242, 43,147, 35,236, 46,160, 64,111, +135, 84,194, 16, 18,228,175,233,212,246, 73,172,154,255, 47, 0,192,139,111,127,137, 23,158,123, 10,205, 91,182, 70,145, 78, 23, +246,228,168,135, 22, 1,240,168,192, 18, 69, 17, 59,247, 30,138,218,123, 36,238,237,151,167,206,208, 62, 49,172,159,228,236, 53, + 61,178, 10,109, 72, 78, 50,212,168,167, 13, 0, 92,110, 17, 28, 28,107,126,216, 1,149, 66,138, 60,189, 3,156,115,124,244,249, +143,240, 86,201,144,165, 43, 25,214,175, 74, 85,245, 72,233,239, 43,236,129,242, 84,233,253,243,240,199, 60,173, 10,115,203,247, + 96,205,153, 51,231,226,156, 57,115, 42,236, 17,171, 76,181, 19,236,188, 35, 98,154,248,249,135, 31,223,254,195,138,128,173,113, +118,252,190,241, 52, 30,238, 18, 14,185, 84,128,218, 55, 24,231, 82, 76,216,179,123, 67,209,206,237,155,110, 22,202,204, 21,246, + 50,149,167, 14,111,218, 94,163,242,217,183,116,249, 90, 87, 80, 72, 8,214, 31, 45,204,208,153, 92,183,202, 89,183,219,201, 78, +239, 89,222,192, 37, 58, 31,180,100, 95,169,246,235,172,200, 33,159,243,213, 54, 0, 28,162, 40,130,139, 34,100, 94, 90, 77,112, +163,110, 57, 0,224, 22,185,151, 84, 96, 37,223,224, 75, 95, 37, 92,116,101,228, 93,171,186,187,147, 1,240, 81,203,240,195,225, +155, 0,144, 35, 49,156,185, 60,246,137,146, 97, 65,171,221,171,184,101,163, 70,188, 83,167, 78, 69, 42, 85,133,139, 69, 60, 82, +211, 97, 65, 79,240,228,100, 59,128,121, 17, 77,123,141, 24,172,109,211, 89, 33,200,209,161,105, 56, 14,238,249,137,255,190,123, +213,139,230,156,196,181, 30,229,112, 14,163,213,137,204, 2, 43,110, 22, 88,145,173,179, 34,187,208,134,108,157, 21,140, 49, 88, +237, 53,238,129,190,141, 41, 55,113,227,250,181, 43, 31,177, 57, 48,166,247,160, 17,248,247,140,165,209,235,191,158,187, 79, 21, +218,172,135, 39, 19,104, 57,231,110,198, 88,218,248,241,227,219,110,216,176, 65,210,170, 85, 43,203,229,203,151,213, 0, 68, 0, + 14,173, 86,173,250,230,139, 57,123, 58,119,238,252,253,205,164,132, 3, 0,116,158,172,164,170,215,119,188,178,153, 79,225,132, + 40, 77,247,193, 13,195,212,136,210, 24, 6, 55,211,158,251, 52,164,255,235,179,115,247,127,150,155,101,115,253,154,103,145,180, +187,105,148,121, 52, 23,208,105,179,166,143, 28, 53, 26, 18, 38,192, 97, 53,167, 3, 0, 88,201,132,242, 15,191, 77,128,214, 75, + 6,111,149, 20, 90,149, 12, 61, 91, 4,120,244,141,182,236, 41,112,186, 69,152,109,110, 88,108, 46, 88,237, 46, 4, 69,250, 99, +197,250,141,184,158,107,193,182, 83,249, 72, 76, 55, 32,166,174, 6,156, 87,255,241, 40,186,157,166, 97,143,141,243,150, 8, 12, + 18,129, 9, 45,154, 53, 65,161,209, 1,185, 84,128,220, 75, 5,141, 82, 10, 31,149, 12,114,185, 12,185,185,185,176,217,108,136, +138,138,242,170,178,129, 34,135,183, 86,133,152, 6, 17,112, 56, 93,216,121,228, 18, 62,158, 50, 18, 3,123,119, 4,147,105,145, + 96,107, 15,239, 0,111,136,130, 0,135, 75,132,221,225, 6, 32, 84,218,219, 22, 21, 21,245,128, 70,163,209,152,205,102, 67,122, +122,250,161,172,132, 45,215, 67, 90, 14,159,176,123,239,129,245, 67,135, 12, 68, 92,252, 69,108,218,186,253,104,126,160,126,106, +217,125, 90,181,106,213, 53, 40, 40, 72, 91, 80, 80, 80,124,254,252,249,147,158, 63,189,127, 96,140, 49, 77,104,179,215,187,245, +236, 11, 99, 81, 46,114,110,164,122,252,173,185,121,180, 55,222,159,179,180, 67,211, 38, 77, 59,184,121, 73,193,213, 34,202, 27, +111,204, 88,210,161, 81, 76,147, 14,101, 11, 61,154, 71, 85,125, 88, 53, 77,104,211,201, 31, 47,252,234,233,168,200, 72,236, 58, +158,128, 57,239, 78,138,211,168,189,235,215, 13,245,247,147,183,236,136,179,103,127, 67, 8, 20,240, 9,141,169, 59,230,145,137, +117, 7, 15,121, 4,231,207,157,198,103,243,102,197,154, 36,170,217,158,180, 85, 27,218, 48,184, 93,167,222, 99,189, 3, 66, 81, +164, 55,192,219, 63, 4,205,219,116, 26,171, 13,109,248,118,233,201,234,239,137,200, 57,108, 14, 14,157,193,129,235,121, 37,197, + 85,106,142, 25,162, 88,131, 57, 63,110,145,105,189,164,210, 0,231,213,168,243,251, 14,240,232,200, 80, 54,111,214,155, 18, 7, +188,144, 87, 84, 82, 92,229, 21,219,145,167,183,195,104,117, 34, 64, 35,133,232,174,124,165, 95,101,116, 70, 7,188, 75,231,201, +122,210,171, 88,153,175, 86,255,208,244, 92, 82,230,240,133, 11, 63, 83,159, 77, 41, 87, 92,201, 74,122,175,148,114, 9,220,162, + 8,120,240,142,151, 73,101,175, 62,250,208, 0,220,200,183,148,174, 68,102,136,105,221, 25, 65, 42, 17,253, 71, 79, 3, 0, 12, +123,168,100,158,113, 74,150, 9, 63,255,158, 7,220, 62, 97,187, 74, 38,139, 69,178,252,219, 95, 94,223,248,227,247,190, 86,183, + 20,203,118,165,193,108,115,193, 75, 46,129, 82, 46,129, 74, 46,185,109, 74, 80,117, 92,238,146, 57,117,215,243,157, 48, 91,173, + 40,182, 56,193, 1,156,188,106,132,197,238,130,222,228, 68,215,102, 85,246,153,120,226, 23, 0, 15,151, 93, 41,223,155, 85, 73, + 15, 84, 69, 78,149,207, 40,219,254,206,140, 59,127, 87,154,231,209, 23, 65,233,157,149, 98,249,235,222, 17, 49, 77,252,252,194, +143,111,255,126, 69,192,150, 56, 27, 14,158, 43,192,168, 94,117, 97,214,103, 99,238,156,183, 10, 25,184, 93,144, 8, 69, 54,171, +101, 75,129,218,241, 49,191,148,236,184,251, 33,254,160, 9,110,209, 70,165, 86, 31,248,228,179,101,142,144,208, 58,226,150,223, +139,114,245,102,247,109,125,133,110,155, 77,224, 34,151,123, 82, 92, 1,128, 32, 48,199,140,127,141,128,200, 57, 62,252,108, 35, +102, 79, 29, 13,173,106,156,154, 49,166, 54, 89, 93,152, 50,115, 37, 22,188,255,188,183, 90, 41, 5, 99,128,213,238,198,211, 99, + 70,120, 18, 13,147,213,133,228, 19, 27,140,134,148, 29,151,203, 15, 11,118,233, 57,228,116,151, 46, 93,138,252,253,253,161, 82, +169,254,232,153,240, 64,101,171, 5,115,139,144,225,237,237,221,199,199,199,167,124,158,169,168,168,232, 39,143,195,203, 49, 20, +229, 31,200, 78, 59,223,185, 71,191, 97, 56,180,231, 39,254,251,174,111, 94,172,201, 49,118,252, 3,252,111,156, 57,159,220,156, +177,128,146, 30,172,210,226,202,238, 20, 17, 29,170,198,141,180,100,248,249,250, 86,187, 58,173,140, 58,164,217,163, 76,224,147, + 24,248, 42, 99,118,210,198,210, 98,231, 73, 77, 88,179,248,139, 23,206,126, 60,116,236,171,210, 65,163, 38, 75,190,158,243,202, +116,220, 49, 57,181, 10,142,196,196,196, 75,207, 63,255,124,247,216,216, 88, 55, 0, 51, 99,204, 41,145, 72,212,118,187, 93,222, +175, 95, 63,125, 66, 66,194, 97,120, 48, 25,177,215,115,155,130,152,210, 48,164, 81, 76,167, 39,163,189, 13, 3,251,245,234,134, +110, 45, 35,113,163, 87, 55, 0,120, 53,221,168,109,218,243,165,111,126,104, 16, 92,119,231,215,171,127,158,253,226,232, 1, 83, + 34,134,205, 92,152,249,243,140, 42, 39,152, 94,191,116,168,130, 99,130,148, 13, 27,202,160, 85, 73,225,173,146,193,219, 75, 6, +167,203,179,111,180,165,184,211, 37,150,244, 96,217, 93, 48, 90, 92, 56,112, 54, 7,217,122, 59,138, 12, 14, 88, 28,110,112,240, +146,111,159, 30,124,138,231, 94, 57,230, 87,246,179,127,116, 7,253,242,207,231,251,108, 62,150,113,107,133,158,175, 90, 1,111, +117,201,170,234, 35, 71,142, 32, 48,176,250,111,247,162, 40, 98,211,238,147, 88,184,230, 0,118,175,122, 11, 94,114, 9,218, 60, + 58, 19,207, 14,239, 2,145,139, 72, 78,188,152, 19,211,162,109,168, 32,168, 32, 48, 6,155, 83, 4,192, 43,125, 62,237,118,123, +224,245,235,215,139, 27, 55,110, 28, 86,167, 78,157, 81, 18,137,132, 43, 1,219, 79,223, 23,154,247,239,248, 78,109,178,216,220, +106,151,126, 85,227, 44,203,195, 49, 49, 49, 96,140,241,160,160, 32,249,129, 3, 7,140,173, 91,183, 14,174, 44,183, 42,140, 49, + 65, 21,210,100,241, 11, 47,189, 62,170, 81,195,134,216,248,221, 42,112,206, 54,123,122,255,111,127,142,197,172,119,110, 95, 49, +248,198,140, 37, 29, 22,204,124,245,182,219, 94,122,103, 97,165,171, 8, 25, 99,172,110,171, 7,222,106,214,172, 5, 98, 47,102, + 96,222,123, 47,197, 89,115, 83,158,180,107, 3, 39, 58,140, 89,255,110,215,190, 35,194, 2,125,144, 89,104,195, 35,227,134,163, + 71,207, 94, 56,127,238, 52,102,189,255,102, 44,204,246, 65, 60,239, 82,181,147,160, 1, 64,228,178, 73,253, 6, 15,151, 89,108, + 14, 44,153,247, 1, 38, 78,253, 24, 93, 31, 24, 38,187,112,246,247, 73, 0,254,227,233, 62,219, 28,110,244,107, 29, 84, 82, 52, + 59, 69,108, 79,145, 72, 43,122, 5, 74, 37, 76,104,215,208, 15, 22,187, 11,197,230,202,135,140, 0, 64, 42,151,101, 23,233,139, +235,125, 49,251,117,137,201,234, 66,158,222,142, 92,189, 13,249, 69,127, 20, 86,249,122, 27,242,244,118,200,164, 12, 73,215,210, + 33,200,164, 53,158,127,167, 51, 58,209,185,137, 63,128,146, 66,230, 94, 56,165, 62, 93,118, 31, 62, 55,114,225,194, 69, 94,231, + 82, 13,136, 79, 41, 46,237,185,146, 64, 41, 19,160, 40,253,217, 45, 2,213, 61,132,111, 72,163, 6,207, 60,255, 98,127, 31,173, + 10,153, 87,114, 33,149, 48, 72, 36, 12,190, 33,145,240, 85, 90,241,202, 75, 19, 16, 20,232,135,235,249, 54, 44,222,154,132,248, + 75, 87, 33, 90,106,182,219, 75,150,125,255,224, 11, 47,191,225, 39,200, 20, 88,183, 39,181,164,157, 18, 55, 18,126,255,217,154, +153,124,222,100, 44, 46,224,224,110, 15,191,248, 51,238,114,151, 20,166,179, 63,156,134,239,215,124,137, 61,103,114,111, 77,206, + 58,182,121, 1, 94,127,231, 35,228, 23,219,129, 10, 38,213, 87, 85,143,160,164, 3,162,172,231,233,174,235,229,138,162,138,174, +179,210,235,246, 74, 50,236,119, 20, 85,246, 59,110,183,223,145,231,209,177,251, 42,237,193,242,142,136,105,226,235, 31,118,124, +219, 15,203, 3,182,156,177,227, 80,124, 73,113,229,178, 21,225,171,121,239,100,153,139,138,123, 87,117,192,198, 59,105, 66,154, +180, 82,106, 52,135,223,251,104,177, 45,180, 78, 61,215,206,179,197, 5, 6,171,251,174,110, 16,185, 90,227,214,248, 6, 91,253, +162,219, 47,148, 89,236, 31,228,229, 93,170,114, 94, 23, 67,201, 55,164, 29, 39,178,193,121,201, 87,162, 31,143,220, 68,233, 55, +113,184,197,146,225,147, 95,207,230, 66, 90, 58,207,196, 19,140, 1, 95, 45,251,178,248,225,214,122,211,216,217, 31,222, 26, 22, +236,218,182,164,231,202,199,199, 7,126,126,126,208,106,181,240,100,136,176, 76,101,171, 5,189,189,189,251,156, 61,123,214,203, +199,199, 7, 18,137, 4, 54,155, 13, 45, 91,182,244, 56,183, 60,109, 88,179,151, 59, 63, 48, 98,122,207, 7,134,225,192,238, 45, +252,247,221,171, 39,212,244, 0,134, 15, 15,232,254,243,172, 89, 31, 54,120,239,227, 47,148,222, 94, 82, 92, 54,218, 33, 48,134, +232, 80, 53, 2, 53, 2, 14,253,180,206, 58,122, 88,119,143, 15,106, 23, 25, 89,103,253,130,207,151,107, 22,204,157,217,207,187, + 78,211, 3,134,155,137,133, 0, 96,202, 78,152,167, 14,107,118,169,238,111,123,119,182,237, 51, 2,161, 17, 13, 7,122,154, 89, + 58, 84,104,190,118,237, 90,202,123,239,189,215,116,238,220,185, 92, 34,145,136, 0,148,159,125,246,153,249,202,149, 43,103, 81, +178,196, 22,213,245, 94,245, 31,216,114,138, 86,225,238, 26,160, 22, 90, 54, 12, 83,163, 91,203,146,209,207,209, 15,247, 68,100, + 84, 20,174,101,155,219, 21,154, 69,153,209, 46,105,184,116, 89,252,169,250, 65,146, 23, 93, 22,251, 37, 84,115, 16,216,138, 48, +252, 49,241,189,172,247,202, 91, 37,131, 8,212,228,155, 34,119,186, 68,216, 28,110, 88,108,110, 88,236, 46,152,236,110,152,237, +110,136,188,228, 61,193, 24,131,195, 37,150, 61,164,231,237, 99,128, 79, 64, 16, 26,214, 47, 89,245,234,173, 42, 57,100,131,143, + 90, 86,178,214, 57, 48, 16, 33, 33, 33,213, 55,144,115,216, 29, 37,111,113,187, 83,188, 53,124,111,119,184,192, 57, 71, 82, 82, +226, 91,105, 41, 41,143, 54,142,105,220,187, 69,155,182, 1,106,165, 0, 0,149, 22, 3,102,179,217,237,237,237, 29, 18, 16, 16, + 32,220,188,121,243, 86,209,220,184, 93, 63,215,214, 45,155, 49,114,228, 8,227,229,147,231,110, 45, 85,183, 88, 44,172, 71,143, + 30, 62,145,145,145,130,205,102,243,116,126, 95,233,115,192,152, 38,184,201,240,200,102,221, 63,126,122,252,196, 38,253, 6, 60, +136,131,251,247, 98,219,150, 13,107, 77,185,137, 85, 30,175,171,188,166, 77,155,221,181,138,176, 81, 76,147,187, 86, 17,214,107, + 16, 83,105,129,229,235,219,198,167, 77,167,190,145,105,249, 14,236,218,181, 19, 38,125,246,251,118,187,209, 12, 25, 95,185, 99, +195,210,231, 95,120,125,166, 79,223, 62,189,224,239,163,134, 84, 42,193,153, 83,177,152,251,159,233,177, 48,219, 7, 85,247,249, +121,107,127, 91,180,144, 55,142,170,247, 90, 84,163, 86, 56,243,251, 81, 36, 39, 93,184,120,238, 84,108,203,198,173,187, 34, 56, + 34,250, 53,214,162,197, 92,126,233, 82,149, 95,160, 1,192,110,181,166, 63,251,204, 83, 40,191,138,176, 91,251,166,129,183,189, + 0, 75,175,152, 13,185,142,111,230, 79,185, 82,182,138, 80,116,216,211, 43,203,213,235,242, 54, 29, 58,126, 98,234,163, 15, 63, + 40,228, 23,219, 75,122,172,244,246,210,139, 13,249,101, 63, 23,219, 16, 19,161, 69,226,197, 51,162, 85,159,239,113, 33, 92,218, + 44,235,179,143, 15,190, 4,252, 49,169,159, 1,213,206, 95,188, 19,151,249, 76,152,247,233, 66,175,115, 41, 70,196,167, 22,151, + 12, 9,202, 36, 37,133,149, 76,184, 85,108,149,172, 78,175,154,139, 73,102, 63,247,204, 24,228, 23, 59, 32,138,128, 84, 34,148, + 94,228,184,110, 96,184, 97, 48, 35, 95,151,135,148,180,116, 20,101, 39, 67, 16, 4, 4, 69, 52,129,167,221,141,110,174, 8, 55, +219,121,235, 81, 15,247,150,110,249, 45, 11,106,165, 20, 54, 67, 14,118,253, 48, 63,207,102, 44,254,216, 98, 54,110,177, 20, 92, +169,118,174, 81, 25,129,177,188, 98,163, 53, 84, 41,147, 96,227,154, 47,240,248,179, 47,149, 62, 41, 37,255,188,245,238, 44, 64, + 96, 40,212, 25,192, 24,171,105,175,232,157,157, 46,158, 77,216,172, 89,102,173,170,180,192, 82,171, 3,247,109,251,126,121,192, +111, 41, 2, 78, 38,234, 48,170, 87, 93, 56,173, 58, 44,254,232,223,217,197,197,185, 15, 24,242,174,120, 92, 92, 1, 0, 4, 97, +240,232,231,166, 94,108,216,164,133,237,224, 5, 99,106,145,201, 89,233, 60,134,110,163,222,187,120,250,151,207, 31,210, 59,175, + 77,214, 70,180,116,139, 46,215, 60,115,110,226,204,138,182, 21, 57, 20, 51, 23,111,188, 53, 60,248,246,220,117, 37, 63,187,221, +112,115, 17, 92, 4, 94,121,255, 43,184, 68, 55, 68,183, 27,162,155,195,233,230,234,234,154, 27, 18, 81,111,139, 46,225,199,102, + 99,255,115,247,176,160,159,159, 31, 2, 3, 3, 17, 24, 24,136,178,130,200, 83,149, 13, 11,250,248,248, 64,171,213,226,232,209, +163, 80,169, 84,208,104, 52, 53,202, 45,163, 13,107, 54,185, 83,223, 71,191,120,224,145,231,241,235,150,101,252,212,145,159, 39, +154,115, 18, 87,122,122,127,183,219,205,156, 78, 39, 30, 30,212, 55, 61,238,226,213,221,239, 78,157,244, 96,247,161, 19,149,221, +154,214,129,213,238, 70, 70, 90, 50, 14,253,180,218,218,164, 65,248,158,254,189,186,164, 59,157, 78,184,221,238,106,255,128, 91, +237,142,124,137, 76,165, 25, 51,102,172,236,212,201,147,155,181, 33, 77, 54,186,153,112,142,113,177, 13, 99,108,100,155, 54,205, +225,112,138, 48,155,139,171, 95, 48,112, 7,131,193,144,178,106,213,170, 6,207, 60,243,140,186, 69,139, 22,178,228,228,100, 44, + 88,176,160,192, 96, 48, 84,123,220,175, 50,123,143, 36,126, 38,101,186, 43, 10,209,241,100,180,183, 97,224,245,158,221, 48,102, +104, 79,124,255,203, 49, 28, 58, 26,139,116,163,246,172,209, 37,253,233, 70,122,166,173,101, 64,241,230, 71,186,213,147,108, 92, +163,219, 28,210,239,157, 39, 56, 87,238,205, 59, 52,195,227, 5, 30, 37,139, 49,156,240, 81,151, 28,175,169,172, 39, 75,194,152, +199,149, 16, 3, 82,142,198,158,105,213, 49,166, 5,226, 82,244,200, 45,178,193, 98,115, 65, 20, 57, 68,112, 4,122, 43,224, 37, + 23,112, 61, 45, 5, 34,119,164,122,218,182, 18, 60,175, 79,239, 62, 82,128,129, 49, 46,149, 73,165,224, 40, 57, 46,162, 74,165, + 50,134,132,132,120,212,131,229,112,185, 48,242,193, 46,232,218,169, 13, 30,157, 56, 31, 0,176,127,237, 52,248,107,101,248,126, +253, 74, 92, 63,188,104,125,195,238, 47,237,189,112,254,226, 99, 23,227,126, 27, 59,164,131,170, 93,152, 52, 83, 94, 89,158,209, +104,220,204, 24, 83,200,229,242, 7,123,247,238, 29,176,121,243,230,162,160,160, 32, 81, 33,151,231, 61, 50,108,168, 40,147,203, + 11,203,182, 61,126,252,184,108,226,196,137,222, 58,157,238,122, 78, 78, 78, 44,231,188,202, 46, 18, 77, 72,179, 1, 16,176, 1, +140,121,105, 85,234,244,110, 3,198, 68,116,234,218,197,119,248,200,199,161, 84, 40,241,235,222,221, 88,178,104,238,143,198,172, +203,207,121,252, 52,162,118, 86, 17,234,245,190,166, 43,151,206,233, 82,115,237,254, 50,191, 24,200,148,222, 19,153,111,196, 98, +137, 82, 59, 35,184,237,112,159, 77,219,119,226,252,133, 11, 8, 80, 57,113, 45,249,138,249,194,217,184, 47,205, 76, 54,147,231, + 93,242,104,165, 19, 0,168, 11,220,143,117,123,234, 65,127,155,195,141, 35, 7,126,177,138, 46,241,193,216,195, 59,147,235, 54, +233,228,213,170, 83,127,255,252,109, 43, 71, 2,248,190,186,156,140,203,119,247,216, 70, 53,237,156,186,255,192, 62,223,208,232, +150, 18, 6, 6,135,205,138,188,107,167, 92,230,156,132, 98,125,198,121,143, 86,213, 22,220,192,251,239,204,248,100,114,167,142, + 29, 53, 28, 94,183,245, 88,149, 21, 86,249,197,118, 4,121, 43, 96, 41,206,195,149, 83,187,173,230, 60, 73,149,199, 43,115,217, + 77,234,252,220,156, 91, 67,105,198,156,196,174, 85,109,159,159,155,163,112,217, 77,213,254,237, 16, 4, 9,124, 52, 10,156, 79, +189,121,107, 66,187, 82, 86, 50,247, 74, 33,147,220,154,135, 5,220, 61, 95,173, 2,125,229, 94,126,184, 89, 96, 5, 3,135,232, +118,193,229,180,195, 80, 92,140,155,153,217,200,201,206,129,193, 80, 4,181,214, 31,173,218,117,134,183,198, 11,231, 14,253, 8, +206,185, 71,199, 37,116, 50, 89,211, 78, 93,123, 41, 47,164,149,204,181,242,146,113,252,188, 97,110,129,177, 56,183,151, 33, 51, +233,138, 39, 25,229,185,220,238,125,241,151,174,180,172, 27, 94,159,157, 77,214, 99,253,138,207, 97, 47,237,201,116, 58,221,184, +112,221,132,172, 66, 51,174, 95,187,204, 69,183,187, 70,135, 92,250, 59,170,180,192,146, 43,100, 42,159,128, 8,204,122,114, 28, +190,252,242, 43,164,222,184,137, 37,179,166,100, 23, 27,242,250, 25, 50,175, 36,121, 18,206, 24, 27, 80,118,172, 12, 83,118,194, +188,231,190, 76,205,216, 30, 87, 40, 88,236,188,202, 9, 60, 94,193,209,232,245,220,130, 61, 22, 67,161,194,109, 51, 75,127, 94, +255,220,134,138, 50, 1, 64, 96,176,127,252,198,104,104, 85, 82, 48,198, 80, 54, 44,184,116,214, 4,168,149, 37, 99,199, 22,155, + 11,227,166, 44,196,250,133,255, 6, 7,240,228,227,199,110,251,224, 41,159, 89,110, 8,175,110,122, 90,238,205, 1,195,222,216, +111,117, 40,109, 67, 71, 60,115,186, 99,199,142, 69, 42,149, 10, 42,149, 10, 62, 62, 62,240,247,247,135,159,159, 31, 42, 82, 73, +102,165,171, 5, 5, 65,128, 32, 8,208,104, 52,208,106,181,208,104,238, 94, 85,115,231,190,223, 73, 27,214,108,114,167, 62,143, + 44,237,255,232, 11,248,117,203,114,126,234,200,207,147,204, 57,137, 43,170,122,174,239,204, 20, 69,241,220,200,145, 35, 91, 79, +156, 56, 81, 62, 99,234,196, 61,191,236, 61,148,180,113,199,242, 97, 58, 93, 81, 36,231, 28,126,190,190, 55, 70, 15,235,254,115, +191, 30,157,210,247,239,223, 47,110,216,176,193,198, 24, 59, 95, 93, 59,243,115,115,215,238,223,119,224,195, 94,125,250, 98,229, +154, 13,125, 46, 94,186,220, 39, 57,249, 10, 34,163, 27,162,126,131, 24,152,153, 63, 14, 28, 62, 10, 99, 81,110,133,115,196, 42, +219,247,178,165, 38, 58,157,238,183,209,163, 71, 15, 58,118,236,152, 48,122,244,104,115,126,126,254,113,148,126,111,170,172,247, +170,124,230,111, 95, 13,207, 3,176,182, 94,223,241, 63,222,116, 20,189, 6, 96,110, 84,116, 20, 14, 29,141, 69,236,177, 19, 95, +229,171,163,102, 62, 55,110,252,132,122,143, 72, 94,120,164, 91, 61, 73,136,191, 26,223, 45, 95, 32,217, 30,155,182, 48,173,192, +189, 18,192,172,170,218,121,167, 2,131, 3, 61,154, 7,192,233,230, 16,121,201, 7,173,183,151,172,194, 15,220,138, 50,165,118, +229,115,147, 38, 78, 76,110,213,166,221,235,227,198, 79,146,183,107, 24,137,147, 87,139, 0,198, 16, 16,166, 65, 86, 86, 22,142, +108, 90,238,210,221, 76,248, 74, 34, 17,239, 26,222,169,170,157,133,105,113,141,203,109, 55, 33, 63, 63, 31,135, 14, 29, 66, 89, + 97, 21, 28, 28, 92, 97,129,117,103,102, 65, 78,230,241, 89,159, 46,235,241,226,211, 35, 48,180,111, 75, 28, 62,149, 12,123,233, +241,150,202,150,132,167,196,126,173,120,109,116, 67,251,228,145, 77,138, 45, 78, 69,218,251,169,250, 35,229, 87,185,222,153,201, + 57,183, 51,198,182, 39, 38, 38,246,108,219,182,109,189,157, 59,119, 22, 94, 60,177,231,213,242,237,120,227,141, 55,180, 95,126, +249,165,154,115,126,220,102,179,221,245, 69,176,194,125, 23,240,221,153,211,167, 3, 29, 78, 17, 71, 79,156,107,222,191, 71, 59, +136, 28, 56,117,234, 20, 86,126,179,210,122, 62,254,236,124, 83, 78,216,127, 42, 91, 32, 82,217,243,233,105, 49, 85,209,118,101, +153,156, 31,114,105, 67,155,125,117,252,232,225,119,149, 17, 29,209,236,161,233,143,220, 60,183,253,145,176, 22,131, 17,212,176, + 59, 50,227,183,227,248,158,111,119,138, 46,215, 52, 47, 81, 72, 55,229, 37, 84, 90,236, 87,214, 78,165, 74,253,175, 22, 29,250, +224,122,122, 26, 82,175, 92, 88,107, 41,184,146,169, 13,107,182, 54, 51, 35,125, 82,131,150, 61,112,108,207,247,175,162,146, 2, +171,186,215,124,100,176,106,249,206, 29,219,199,100,100,124, 29,102,178, 88,149,156,115,171, 82, 33,205,214, 10,134, 74, 23, 69, +221,253,255,126,201,161, 9,168, 63,242,241,113,147,126, 89,178,100,145, 44,212, 79,141,108,157, 21,197, 22, 7, 12,102, 7, 4, +198,208, 56, 66, 3,179,161, 16,135, 55,125,234,180, 27,117,163, 57,191,234,168, 44,179,228,124,130,252,149, 55, 94, 58, 8,133, +111,100, 68,131,254,211,171,236,157, 51,100,198, 15,123,227,165,159,155,114,206,251,107, 67,155, 25,140, 57, 9,239, 85,182,239, +140,149,188,191,199,246,139,132,195, 85,114,252, 48,151, 8,184, 69,177,180, 87, 15,224,183,198,237,239,126,195,223,158,201,196, + 31,126, 57,142,204,156, 34, 88,236, 78,216,236, 46, 56,156,110, 8, 18, 9,252,252,253, 16, 83,191, 61,124,253,124,144,147,157, +137,216,253,219,145, 20,127,248, 56,227,152,105,206, 77,218, 95,121,230, 31,228, 42,191,166,225, 17, 97, 66, 86,177, 29, 42,133, + 4,103, 15,239,116, 56,237,182,249,158, 20, 87, 21,101, 22, 21, 20, 46,124,125,234,155, 79,174, 94,181, 38,172,117, 3, 31,100, +228, 91,144,145,103,133,193, 90,242,253,198,229, 22, 97, 51,230, 35,254,192,154,108,183,213,112, 79, 71,158,255, 59,169,180,192, + 18, 93,110,123,226,213,107,152, 54,243, 83, 92, 75, 75,199,146, 57,111,230, 24,107, 80, 92, 85,100,213,228,250,213,126, 3,186, + 93,233, 33, 73,254,147, 86,229, 86,119, 13, 11,114, 17, 34,231,248,249, 68,246,173, 97, 65,177,116, 70,101, 92,114, 81,149, 89, +119, 14,225,197, 39, 26,190,181, 88,114,124, 19,174,206,215, 1,128, 68, 34,185,117, 41,155, 43,101,181, 90,171, 92, 85, 84,197, + 65, 68,111, 27,215, 22, 69, 17, 62, 62, 62, 80,169, 84, 53, 30,122,212,132, 54, 29,211,169,239,163, 95,244, 31,254, 34,246,109, + 93,193, 79, 29,222,254,146, 57, 55,113,185,199, 1,165,116, 58,221, 69,198,216,149,249,243,231,183, 91,185,114,101,131,169, 83, +167, 94, 91,247,197,135, 75, 0,160,160,160, 0, 0, 16, 23, 23,199, 95,122,233, 37,155,213,106, 77,209,233,116,103, 56,231,213, + 14, 29, 88,242,212,179, 87, 46,157,219,234,198,205,172, 17, 13, 91,117, 70,112,131,206, 8,107,220, 5, 58,131, 3, 39,175,102, +226,218,229,253,184,124,116,211, 78,179,214,245, 97, 77,219,220,182,109,219, 72, 65, 16,234, 27,141,198,176, 22, 45, 90,180,213, +104, 52,113,109,219,182,109, 47,149, 74, 51, 78,159, 62, 93,245,139,231, 14,105,135, 86,219,234,245, 29,191, 56,221,224,221,239, + 90,182,185,125,186,193, 59,206,172,244,253,119,238,254,207,108,161,131,230, 47,228,142,252,139, 27,215, 20,111,254,110,249, 2, +201,184, 9,111,184, 47,232,253, 95,147,170, 20,191,206,121,182,181,199,143,193,152,144, 53,249,153, 71,255, 56, 76, 67,105,207, + 85,233,207, 30,117,199, 23, 21,157,211, 3,120, 91, 21,209,242,139, 11,175, 77,156,213,166, 83,143,167,122, 15, 25, 45,184,228, + 90,236,217,250, 53, 79,137, 63,176, 81,202,221,239,154, 61, 56,122,127,117,236,118,123,181,197, 85, 69,244, 55, 52,125, 55,110, +248,230,217,205, 91,183,204, 25,254,200,163,129, 75,223,127, 2,159, 46,251, 9, 26,149, 18, 92, 20, 49,250,129,168, 81,151, 55, + 12, 30, 22, 25,234, 85,103,243,193,140, 35,175, 44,186,240,182,217,236, 72,170,110,149,107,105,193,124,212,219,219, 59,175,103, +207,158, 93,149, 74, 37,203,207,207,151,134,132,132,184,124,125,125,237, 25, 25, 25,102,155,205,182,153,115,238,113,175, 34, 0, + 56,156, 34, 82,115,172,216,182,101, 51,206,157,216,143,203,151, 19, 13,151, 47, 93,254,156, 73,249, 34, 99,118, 82, 97,245, 9, +119, 19, 43, 92, 69, 88,241,109, 85, 49, 73, 84,179,227,118,124,218, 55,230,129, 87,187, 5, 54,234, 1,255,232,146, 53, 58,250, +140, 11,184,113,106,227, 54, 67,166,252,113,206, 47, 84, 61,145,169, 10, 17,117, 27,196,112,137, 2,191, 29,250, 5, 92, 20,191, + 2, 0, 46,138, 95,197, 29,219, 57,169,203, 67, 47, 32, 32,164, 94,219,178,181,243, 53,205,150, 75, 5,211,174,205,171,183,166, +166,166, 34, 33, 33, 1, 87,175, 94, 69, 97, 97, 33,190,251, 46,181, 70,255, 63,166,194,212, 95,181,129, 13, 7, 63,246,196,216, +159, 71,141,121,218,171, 65, 76,107,161,105, 93,127, 4,106,165, 72,188,154,134,164,211,241, 98,226,201,157, 86, 71,113,238,112, +115, 97,106,165, 5,159, 38,184, 69, 40, 19,248,180,178,115, 11,118,235,214,163,233,155, 31,207,233, 26, 24, 28, 82,225,231,120, + 65, 94,174,226,173, 87,182, 55,141,253,253, 55,143,206, 69, 40,186,221, 5, 19,158, 29, 45, 74, 74, 78,228,137, 91,253,210, 12, + 0, 47,235,181, 42,185,157,139,174,106,123,236,199,143,232, 5,151, 40,194,100,113,160,216,100,131,222, 96, 69, 86,110, 1,206, +197,199,227,240,207,219,145,156,120, 46,197,105,183,239, 21, 4,182,201,156,157,120,184,186,188,219, 8,210, 6,129, 1, 1, 72, + 41, 52,194, 75, 33, 69, 90,210,105,155,169, 88, 95,233,217, 67,170, 99,206, 79,202,210,132, 54, 29, 52,122,244,152,221, 15, 12, +126,196,183, 83,247, 1,234, 32, 31, 63,200,165, 28, 87, 82, 51,113,230,248,110,211,181,115, 71,138,157,118,227,131,181,113,150, +150,255,117,149, 22, 88,197,134,188,126,207, 63, 55,113,143, 32,149, 40,193, 69,171,217,172,123,240,207, 20, 87,127, 21,206,221, + 25,207, 62, 89, 50,105,189,236,187,128, 75,228,170, 39, 31,223, 99, 41,255,221,192,233,230,234, 39, 31, 63,110, 6, 0, 46, 86, + 62, 97,239,214, 16,222,247,191,102,164,167, 23,156, 42, 44,180, 29,252,179, 43,251,202,159, 91,176,138,213,130,166,102,205,154, +221, 42,170, 36, 18, 9,220,110,183,199, 31, 64,114,165,234,197, 7, 30,121,158,237,251,105, 5, 63,121,232,167,201,230,220,164, +101,247,218,222,210,130,233, 4, 99,236,194,187,239,190,219, 41, 52, 52, 52,244,131, 15, 62,240, 42, 46, 46,150, 45, 93,186,212, +154,159,159,159, 93, 92, 92, 28,203,121,229, 19,146,239,206, 60,227, 4, 48, 82, 27,218,164, 31,223,188, 98,160, 95, 80,157, 65, +190,193,117, 27, 21,229,221, 76,209,231,101,238, 5,176,175,244, 0,143, 53,210,190,125,251,134,130, 32,140, 6,208, 74,163,209, + 52,214,106,181, 74,206,121, 51,198,216, 69, 81, 20,227, 91,180,104,177, 3, 64,141,254,255,210, 14,173,182,245,158,252,205,134, + 66,179, 40,183, 11,242, 13,105,135, 86,219, 0, 32,103,239, 84, 51,128,109,161,253,166,141,220, 30,155,182,228,162,206,247,213, +220,131,179, 61, 62, 55, 93,153,162, 27,103, 27, 87,191,149,103, 44,153, 23, 51, 0, 60,171, 9,109,186,224,124, 92,236, 12,198, + 33,115,195,245,145, 57,231,202,233,218,200,151,201,100,214, 58,117,234, 84,184, 90, 80,169, 84, 86, 57, 63,165,244, 96,135, 43, + 25,235,187,102,203,143,107,158,253,105,251,182, 57,189,251, 15, 15,244,170, 91, 23,245, 67, 24,214, 76,235,240,234,254,184,188, +147,143,188,121,228,203,107,153,214,120,206,121,141,230,187, 24, 12,134, 36,198,152,206,104, 52, 62,202, 57,191,193, 24,139,212, +233,116,103,157, 78,231,249, 26, 23, 2, 34,198,118,235,214,249, 59,198,152,148,187,196,121,177, 50,201, 6,107,214,229,140,123, + 41, 40,202,107, 93,223, 7, 83, 62, 88,220,161, 81,227, 38, 29,202,206, 69,216,178,158, 55, 38,190,189,160, 67,189, 6, 49, 29, +254, 56, 63, 97,213,171, 8,121,230, 25, 11, 11,109, 61, 48,113,239,252,247, 3,147,143, 79, 86, 5,212,213,154,242,211, 10,117, +105,167,231,155,115, 67,231,223,203,129, 37,203, 75,189,122,113,209,202,249,111, 79,205,186,153,178,210,148,155,116, 1, 0, 76, +185, 73, 23,212,161, 77,222,207,207,206,152, 90,144,123,109,254,189, 62, 23, 38,147, 41,243,219,111,191,245,235,209,163,135, 16, + 26, 26,138,188,188, 60, 28, 60,120, 80, 20, 69,177,218, 19, 51,223,201, 88,112,237, 32, 99,141, 2,214, 46,251, 98,158, 92,227, +253,144,203,229,138,224, 28,144, 74,165, 89,118,115,241,110,131,160,121,147, 23,166, 86,243,186, 20, 25, 0,161,236,220,130,162, + 40,178,121, 75,214,164,201,188,188, 43, 28, 82,117, 90, 13,106, 81, 20, 61, 62, 23,161, 46,253,116,163,154,238, 87,101, 24,231, + 51,219,118,236, 58,221,233,116, 88, 81, 50, 31,204, 10,192,202, 57, 10, 4,129, 29,150,136,206, 61,158,156, 2,173,210,124, 6, + 31,206,164,240, 86, 73,193,192, 96,212, 23,242,154,204,185,170,136, 41, 39,241, 34, 99,125,163,119,217,127,124,230,192,175, 59, + 31,119,187,221,245, 75, 95, 57,169, 54,139,105,163, 49,203,127, 45,231,167,254,220, 50,244,191,137, 74, 11,172,210, 98, 42,250, +255,175, 41,247,166, 32,165,250,163,203,214, 68, 86, 78,225,154,193,195,167,242,212,180,220,147,215,179,109,107,121,185,211,223, +252,217,204, 27, 55,242, 14,150, 14, 11,222,181,196,243, 94, 87, 11,150,113, 88, 45,159,124,246,238, 24, 88, 45,166,117,230,220, +164, 53,127, 38,171, 76,105, 1,117,152, 49,230, 59,121,242,228,246, 74, 16,255,138, 0, 0, 32, 0, 73, 68, 65, 84, 90,173, 86, +150,159,159,127,130,115,174,175,246,206,149, 48,230, 36, 29, 4,112, 16,192,180,218,104, 99, 92, 92,220,181,118,237,218,173, 23, + 4,161, 62,231, 60,148,115,238,139,146, 2, 54, 95, 42,149,222,188,116,233, 82,141, 63,196, 1,128,219,188,119, 25,237,146, 24, + 23,247,223,125,231,239,100,129, 33,191,166, 23,186, 87, 72, 52, 94,255, 51,115, 8, 76, 57,137, 23, 1,212,194, 17,118,111, 87, +213,113,174, 60, 85,190,208, 58,244,203,234,103, 5,133,239, 71,253,155, 90,205,131, 94,191, 57,235,232,249,188, 19,156,115,143, +143,142,125,119, 54,207, 83, 40, 20, 22,198, 88,164, 92, 46,183,216,237,246,248,123,201, 41, 45,238,239,105,165, 97,101, 68,176, +211, 29, 58,120,254,241, 36,130, 85, 89, 20,243,156,243,102, 0,211, 88,139, 22, 31,168,147, 79,249,155,243,131, 10, 56, 79,172, +149, 63, 84,198,236,132, 89, 40, 29,230, 46,207,156,147,244, 17,128,143,254, 76,246,169, 83,167,126,158, 63,127,190,126,201,146, + 37, 81,110,183, 91,109,183,219,205, 22,139, 37, 53, 35, 35,227,183,123,201,227, 60,217, 14,224,181,210, 75,141,153,243, 19,178, +181,161, 77, 22,119,239,214,253, 53, 0, 96,224,139, 83, 15, 47,158, 82,213,125,180,161, 77, 44,229,183,175,234, 92,132,181,201, +152,155,244, 21,128,175,254,178, 7,224, 98,222,216, 81,143, 2,165, 7,212, 22, 93,174,123, 62, 28,199,109,177, 37,239,249,111, +112, 15, 39, 47,191,175,240,210,211, 35,252, 21, 23, 0, 3, 40,147, 50, 41,147, 50, 43,216, 86,248, 59,180,147, 50,239,223, 76, +175,240,230,145, 94,225,205, 35, 61,189,127, 69,219,255, 93,247,253,127, 53,243,126,187,120,124, 38,111, 66, 8,169, 45,220,131, +179, 9, 16,242, 87,178,100, 94,242,248, 56,126,247,178, 61, 33, 12, 37,103,165,190, 11,247,236,236,219, 37, 33,140, 85,152, 81, +149,234,242, 41,147, 50, 41,147, 50, 41,147, 50, 41,243,254,203,172, 46,187, 38,245,199,255,180,191,178,123, 12,127,147,110, 73, +202,164, 76,202,164, 76,202,164, 76,202,252,239,102,222,111, 23,207,207,241, 66, 8, 33,132, 16, 66, 60, 66, 5, 22, 33,132, 16, + 66, 72, 45,163, 2,139, 16, 66, 8, 33,164,150, 81,129, 69, 8, 33,132, 16, 82,203,168,192, 34,132, 16, 66, 8,169,101,140,115, +142,210, 83, 76, 49, 0,183,253, 76, 8, 33,132, 16,242,255,225,126,171, 69,110,245, 96, 49,198,254,212, 57,183, 8, 33,132, 16, + 66,254,140,251,169, 22,185, 85, 96,113,206,217,253,180, 99,132, 16, 66, 8,249,123,185,159,106,145,219,230, 96,253,221,187,227, + 8, 33,132, 16,242,247,118,191,212, 34, 52,201,157, 16, 66, 8, 33,164,150,177,210, 67,222, 19, 66, 8, 33,132,144, 90, 66, 61, + 88,132, 16, 66, 8, 33,181,140, 10, 44, 66, 8, 33,132,144, 90,246,151, 22, 88,140,177, 1,148, 73,153,148, 73,153,148, 73,153, +148, 73,153,255, 52,212,131, 69, 8, 33,132, 16, 82,203,168,192, 34,132, 16, 66, 8,169,101, 84, 96, 17, 66, 8, 33,132,212, 50, + 42,176, 8, 33,132, 16, 66,106, 25, 21, 88,132, 16, 66, 8, 33,181,140, 1,168,112, 37, 0,231,124,159,199, 33,247,176,154,160, +186,124,202,164, 76,202,164, 76,202,164, 76,202,188,255, 50,171,203,174, 73,253,241, 63,141,115,254,151, 93, 0, 12,160, 76,202, +164, 76,202,164, 76,202,164, 76,202,252,167, 93,104,136,144, 16, 66, 8, 33,164,150, 81,129, 69, 8, 33,132, 16, 82,203,168,192, + 34,132, 16, 66, 8,169,101, 84, 96, 17, 66, 8, 33,132,212, 50, 42,176, 8, 33,132, 16, 66,106, 25, 43, 93, 13, 0,198, 24,231, +156,179,255,114,123, 8, 33,132, 16,242, 15,117, 63,213, 34, 2,240,199, 14, 49,198,248,127,187, 65,132, 16, 66, 8,249,231,185, +223,106, 17, 26, 34, 36,132, 16, 66, 8,169,101, 84, 96, 17, 66, 8, 33,132,212, 50,154,131, 69, 8, 33,132,144,255, 9,247, 83, + 45,114,171,192, 34,132, 16, 66, 8, 33,181,131,134, 8, 9, 33,132, 16, 66,106, 25, 21, 88,132, 16, 66, 8, 33,181,236, 47, 45, +176, 24, 99, 3, 40,147, 50, 41,147, 50, 41,147, 50, 41,147, 50,255,105,168, 7,139, 16, 66, 8, 33,164,150, 81,129, 69, 8, 33, +132, 16, 82,203,168,192, 34,132, 16, 66, 8,169,101, 84, 96, 17, 66, 8, 33,132,212, 50, 42,176, 8, 33,132, 16, 66,106, 25, 3, + 80,225, 74, 0,206,249, 62,143, 67,238, 97, 53, 65,117,249,148, 73,153,148, 73,153,148, 73,153,148,121,255,101, 86,151, 93,147, +250,227,127, 26,231,252, 47,187, 0, 24, 64,153,148, 73,153,148, 73,153,148, 73,153,148,249, 79,187,208, 16, 33, 33,132, 16, 66, + 72, 45,163, 2,139, 16, 66, 8, 33,164,150, 81,129, 69, 8, 33,132, 16, 82,203,168,192, 34,132, 16, 66, 8,169,101, 84, 96, 17, + 66, 8, 33,132,212, 50,198, 57, 7, 99,140,151, 94,239,203, 57, 63,252,223,108, 16, 33,132, 16, 66,254,121,238,183, 90, 68, 90, +246, 3,231,156,149,238, 28,251, 47,182,135, 16, 66, 8, 33,255, 80,247, 83, 45,114,107,136,176,116,135,250,254, 23,219, 66, 8, + 33,132,144,127,176,251,169, 22,185,173, 7,235,191,217, 16, 66, 8, 33,132,252,179,221, 79,181, 8, 77,114, 39,132, 16, 66, 8, +169,101,172,244,144,247,132, 16, 66, 8, 33,164,150, 80, 15, 22, 33,132, 16, 66, 72, 45,163, 2,139, 16, 66, 8, 33,164,150,253, +165, 5, 22, 99,108, 0,101, 82, 38,101, 82, 38,101, 82, 38,101, 82,230, 63, 13,245, 96, 17, 66, 8, 33,132,212, 50, 42,176, 8, + 33,132, 16, 66,106, 25, 21, 88,132, 16, 66, 8, 33,181,140, 10, 44, 66, 8, 33,132,144, 90, 70, 5, 22, 33,132, 16, 66, 72, 45, + 99, 0, 42, 92, 9,192, 57,223,231,113,200, 61,172, 38,168, 46,159, 50, 41,147, 50, 41,147, 50, 41,147, 50,239,191,204,234,178, +107, 82,127,252, 79,227,156,255,101, 23, 0, 3, 40,147, 50, 41,147, 50, 41,147, 50, 41,147, 50,255,105, 23, 26, 34, 36,132, 16, + 66, 8,169,101, 84, 96, 17, 66, 8, 33,132,212, 50, 42,176, 8, 33,132, 16, 66,106, 25, 21, 88,132, 16, 66, 8, 33,181,140, 10, + 44, 66, 8, 33,132,144, 90,198, 74, 87, 3,128, 49,198, 57,231,236,191,220, 30, 66, 8, 33,132,252, 67,221, 79,181,136, 0,252, +177, 67,140, 49,254,223,110, 16, 33,132, 16, 66,254,121,238,183, 90,132,134, 8, 9, 33,132, 16, 66,106, 25, 21, 88,132, 16, 66, + 8, 33,181,140,230, 96, 17, 66, 8, 33,228,127,194,253, 84,139,220,234,193,186,159,198, 61, 9, 33,132, 16,242,247,115, 63,213, + 34,183,122,176, 8, 33,132, 16, 66, 72,237,160, 57, 88,132, 16, 66, 8, 33,181,236, 47, 45,176, 24, 99, 3, 40,147, 50, 41,147, + 50, 41,147, 50, 41,147, 50,255,105,168, 7,139, 16, 66, 8, 33,164,150, 81,129, 69, 8, 33,132, 16, 82,203,168,192, 34,132, 16, + 66, 8,169,101, 84, 96, 17, 66, 8, 33,132,212, 50, 42,176, 8, 33,132, 16, 66,106, 25, 3, 80,225, 74, 0,206,249, 62,143, 67, +238, 97, 53, 65,117,249,148, 73,153,148, 73,153,148, 73,153,148,121,255,101, 86,151, 93,147,250,227,127, 26,231,252, 47,187, 0, + 24, 64,153,148, 73,153,148, 73,153,148, 73,153,148,249, 79,187,208, 16, 33, 33,132, 16, 66, 72, 45,147, 86,116,163,172,203,199, + 57, 46,151, 43, 4, 0,164, 82,105,174,243,228,123,225, 85,133,200,128,254, 46, 96, 69,105,224,139, 78,206,127,173, 32,243, 87, +151,203,229, 95,154,169,115,158,124,111,112,149,153,157, 63,218,115,219,246, 39,222, 29,120,215, 70,140, 73,100,157, 63,202,188, +163,173, 17, 85,229,222,134,115,247,255, 71, 59,255, 46,153,255,100,242,174, 31,231, 56,157, 37,175, 35,153, 76,154,235, 56, 81, +245,235, 72,222,229,163,204,219,182,255,253,221,208,170, 50,213, 42,101, 65,163, 58,193, 11,171,202,188,150,153,255,111,147,217, + 26, 88, 85,102, 77,223,155,145,225,225,253,221,165,239, 77, 9,240,226,141,204,204,255,159,247,166,135, 24, 99, 29, 1,188, 7, +192,167,220,205,241,156,243,215,239, 53,147, 16, 66,254, 23, 84, 88, 96,185, 92,174,144, 51, 91,103,192,100, 3,250, 63,253, 81, + 72,195,225,203,190,187,107, 27,171, 78, 81,116,241,135,214, 18,103,177,127,176,212,225,147,153,153,201, 0,128, 49,182, 2, 64, + 84, 5,153,254,103,182,206,128,217, 14,244, 30, 51,211, 63, 10,240,201,147,203,223, 80,105, 52,253, 44, 22, 75, 75, 0, 80,169, + 84, 23, 45, 38,211,193, 96,135, 99,193,157,219, 87,182, 3,229,219,250,192, 83, 31,133, 52, 27,190,236, 85,183, 40, 42,110,158, +250,186,183, 53,255,138, 84,230,178, 45,157, 14,236,154, 1,220, 85, 76, 85,146,247,199,227, 62,254, 78,160, 12,120, 64,225,229, +213,214,207,223,191,151,200,121,115, 81, 20,153,219,229,186, 84,172,215, 31, 21, 93,174,115, 46,187, 41,240,204,246, 57, 98, 85, +237,188,115, 95, 30, 7,164, 91,129, 81, 26,173,182,159, 68, 38,235, 14, 0,110,167,243, 55,147,209,120,112, 4,176,201,147,125, +247,244,249,185,215,237,255,105,156, 78, 87, 72,202,158, 25,176, 57,129,246,143,205, 9,105, 51,118,237,119, 0, 96,207, 61, 23, +106,188,178,189, 11, 0,104, 26, 13, 61,161, 12,107,159, 3, 0,210,244,172,144,164, 29,239,194,230, 4,154, 15,157, 25, 82, 93, +230,248, 15,126, 12,124,107,194, 72, 37, 0,236,221,252, 69,147, 3, 91,190, 26, 2, 0, 15,140,124,105,215,160,199, 94, 73, 2, +128,121,203,183, 4,126, 63,231,137, 42, 51, 61,123,111,234,229,250, 43, 59, 26,219,139,179,252, 34, 53,210,176, 43, 87,174, 8, + 0, 16, 17, 17,225,209,123,179, 46,224,155, 5,188, 44, 72, 36,189, 26, 53,110,220, 30, 0,191,150,156, 28,231,118,185,142,133, + 3, 75,107,249,181,244, 42,231,124, 88,249, 27, 24, 99,127, 50,146, 16, 66,254,251, 42, 44,176, 0,192,100, 3, 14, 95, 5,250, +116,109,131, 9, 99, 31,210,150,255,221,166,101, 51,163,174,156,218,214,236,155,181, 11,132, 54,109,218, 32, 37, 37,197,163, 7, + 51,219,129, 67, 87, 0, 20, 93,246,214,105, 52,201,139, 62,253,212,103,224,192,129,210,136,136, 8, 48,198,144,157,157,221,117, +223,190,125, 29,167, 76,153, 50, 9, 69,151,117,102, 59, 12,135,174, 84,159, 91,214,214,150, 77,234,225,189, 87,158,240, 5,128, +233, 79, 47,237,120, 42, 49, 39, 32, 57, 57,185,255,219,111,191, 93, 32, 57,120,240,171, 32, 96,117, 14,112,195,147,118,174,251, +249,132,151,111,214,134,134,227, 94,121,101,115,227,198,141,181,209,209,209,204,219,219, 27, 18,137, 4, 58,157, 46,234,194,133, + 11, 67, 78,158, 60,105,218,119,120,133,226,244,201, 71,174,229,122,117,177,122,180,239,150, 76,175,189,222,222, 23,159, 26, 49, +162,238, 19, 79, 60,225,213,168, 81, 35, 0, 64,114,114,114,204,166, 77,155,198,108,222,188,249, 3, 88, 50, 93,102, 59,172,213, +237,251,173, 76, 0, 94, 64,119,191,144,144,113, 18,153,172,165,203,229,170, 3, 0, 82,169,244,166,219,233,188, 88,148,155,251, +237,157,219,147,187,217,156,192,229, 44, 96, 64,175,246,120,106,228, 0, 13, 0,188, 61,250,227,174,233,169, 87,229,118,187, 29, + 77,154, 54,239, 49,107,206,194, 61, 16, 4,172,223,178,239,214,246,158,100,198, 95, 78,193,140, 89,139,144,121,126, 83, 87,183, +254,106, 63, 67,177, 94, 2, 0, 62,190,190, 35, 55,253,176,225, 96, 68,235, 81,191, 95,205,119,120,148, 89,213,123,115,247, 15, +159,135,103, 92, 56,216,226,203,189,171,100, 81, 81, 81, 56,127,254,188, 71,251,126,235,181,161, 79,244, 22,195,195, 47, 45,120, +243,205,176,222,189,123, 67,171,213, 66, 42,149,194,229,114, 13, 56,118,236,216,128, 25, 51,102,188, 4,125,162,201,211,247,166, + 7, 22, 48,198,250,141,159,240,106,248, 67,143,142,194,200, 7,123,212, 74, 40, 33,132,252,183, 85, 88, 96, 73,165,210,220,129, +207,204, 14,233,213,165, 21, 78,157, 75,210,167, 93,207, 50,150,253,174,240,226,166, 38,143,246,168,211,226,200,145,195,176,217, +108,248,237,183,223,112,238,220, 57,164,166,166, 98,226,196,137, 54, 41,240, 98, 37,153,186,222, 99,102,250, 67,127, 69, 27,163, + 72,172,191, 47, 33, 65, 98,181, 90,113,228,200, 17,232,116, 58, 40, 20, 10,212,173, 91, 23,131, 6, 13,146, 38, 36, 36, 4,244, + 31,248,160,111,239, 7,159, 76,129,111,140, 81, 42,149,234, 42,221, 1,169, 52,183,255,211, 31,133,180,136,169,135,228,180, 76, +253,123,115,190, 49,138, 34,151, 94, 75, 77,119, 28, 62,124, 24,237,219,183,199,175,191,254, 26, 88, 88, 88,248,254,210,165, 75, +223,147,125,242,229, 98,167,189, 96,106, 21,121,186,222, 99,102,250, 7,230,110,140, 62,176,251, 39,249,197,139, 23,229, 95,127, +253, 53, 10, 10, 10,160, 80, 40,224,231,231,135,176,176, 48, 52,105,210,132, 77,159, 62, 93, 59,116,232, 69,252,235,197, 81,209, +142,134, 47, 36, 86,214,206, 91,251,110, 76, 87, 7, 21,239,109,180,229,151, 95,132,158, 61,123,222,246, 53,189, 65,131, 6, 24, + 60,120,176,215,184,113,227, 26, 61, 49,102,172,216,251,225,241,201,208, 70,155,171,205, 52,221, 80, 5,154, 99, 35, 6,140, 25, +179,125,230,204,153,126, 97, 97, 97,208,104, 52, 0, 0,189, 94, 95, 55, 45, 45,173,235, 7, 31,124,240,216,137,248, 31,164,189, +135,222,200,132, 38,210, 82,213,243,249, 79, 37,147, 73,115,203,122,141,188, 53, 42,221,141,140, 28, 19, 0,216,237,118,216,237, +118,216,108, 54, 76,126,105,162,228,197,199, 58, 55,142,238,245,234,217,212,155, 57,133,205,247,253, 30, 80,118,223,234, 50,165, +230,212,162,162,235,251, 95,156,241,230,155, 97,161,161,127,140,252,173, 95,183, 78, 82, 88, 88, 56, 96,198,140, 25, 45,184,186, +111, 81,243,161, 51,253,170,202,172,234,189, 89,148,244, 75,253, 89,175, 12,110,187,108,206, 14,184,221,110,196,198,198,226,200, +145, 35, 88,184,112, 33,223,181,107,151,222, 71,163,169,230,189,153,232,221, 51, 60,187,225, 39,159,108,102, 74,165, 18,219,182, +109, 67, 66, 66, 2, 4, 65, 64,155, 54,109,240,212, 83, 79, 97,192,128, 1, 97, 19, 38, 76,228,189, 31, 28,125, 13,190, 77, 13, +127,230,181,196, 24, 19, 0,188,250,206,140, 79,194,159,126,225,101,204,155, 53,157, 10, 44, 66,200,253,163,116, 53, 0, 47,189, +244,225,156,131, 3, 66,131,225,203,190,223,120, 90,252,165,193,240,101,223,115, 64,224,128,224, 3,212,107,215,174,157,179,168, +168,136,159, 60,121,146, 79,158, 60,217,180,120,241,226,131,191,252,242,203, 38,151,195,177, 50, 34, 60,124, 62, 7,132, 10,103, +212, 3, 66, 52,224,171, 86,171,243,174, 95,191,206,119,238,220,201, 63,252,240, 67,254,237,183,223,242, 93,187,118,241,125,251, +246,241, 93,187,118,241,239,191,255,158,199,199,199,243,164,164, 36,174,209,104,242,162, 1,223, 42, 50, 37, 28,144, 52, 25,254, +245,212,205,167,156, 51,155, 14, 95, 54,133, 3, 18,127,160, 89,187,118,237,220,155, 54,109,226,235,215,175,231,107,215,174,229, +241,241,241, 60, 63, 63,159, 75,149,154,188,178,251, 85,214, 78, 14, 8,117,234,212,201, 43, 42, 42,226,145,145,145, 92,161, 80, +240,208,208, 80,222,164, 73, 19,222,181,107, 87, 62,100,200, 16, 62,118,236, 88,254,254,251,239,243,162,162, 34,238,229,229,149, + 83,118,191,202, 50,219, 3, 42,141, 70,115,253,204,153, 51,188, 50, 22,139,133,231,231,231,243, 61,123,246,112,141, 70,115,189, + 61,160,170, 42, 83, 5,116,104,221,186,117, 94,126,126, 62,119, 56, 28,252,250,245,235,252,194,133, 11, 60, 33, 33,129, 95,191, +126,157, 91, 44,150, 91,217, 73, 73, 73,188, 97,195,134,121, 42,160, 67,165,153,255,228, 75,217,107,226,142, 75, 84,104,232,144, +176,176, 48,203,230,205,155,249,205,155, 55,249,154, 53,107,184, 0,124,124,215,182, 85,100, 42,128, 65, 61,123,246,116,199,198, +198,242,179,103,207,242,105,211,166,241,193,131, 7,243, 7, 31,124,144,207,152, 49,131,103,100,100,240,140,140, 12, 62,100,200, + 16,183, 2, 24, 84,221,235,179,162,247,166, 47, 16, 53,116,232, 80,139,195,225,224,215,174, 93,227, 45, 91,182,204,144, 0,227, + 52, 64,139, 62,128,178,186,215,103, 29,192, 63, 60, 60, 60, 43, 54, 54,150,111,217,178,133, 71, 71, 71,231, 73,128,241, 62, 64, + 3, 31,160,129, 4, 24,223,160, 65,131,188,216,216, 88, 94, 80, 80,192,163,162,162,178,234, 0,254,247,250, 90, 66,201, 49,248, + 86,189, 51,227, 19,158,152, 97,226,239,204,248,132, 3,184,206, 75,126,249,235,127,253,245, 64, 23,186,208,229,255,253,114, 87, + 45,242, 55,191, 72,203, 21, 90,140, 49,198, 81,114,108,172, 10, 89, 36,146,217,243,230,205,147, 90,173, 86,124,243,205, 55,134, + 39, 71,143,222,226,231,231,231,146,201,100, 96, 66,245, 11, 18,243,148,202,215, 62,157, 55,207,207,110,183,227,244,233,211,232, +216,177, 35,148, 74, 37,228,114, 57,100, 50, 25,100, 50, 25,194,195,195,145,155,155,139,150, 45, 91,226,173,183,222,242,157, 59, +123,246,107,176,217,102, 85,149, 43,138, 92, 10, 0,110, 81, 84,200,129, 9,109, 59,117,154, 63,125,250,116,193,199,199, 7, 86, +171, 21, 54,155, 13, 9, 9, 9, 8, 12, 12,132, 90,165,150,194,102,170,182,173,130, 32, 8, 90,173, 22, 7, 14, 28,192,242,229, +203,145,154,154,138,172,172, 44,120,123,123,163,101,203,150,104,222,188, 57,250,244,233,131,107,215,174,129,121, 48,105,228,146, + 84,250,242,228, 23, 95, 12,105,223,190,125,133,191,183, 90,173, 40, 42, 42,130, 94,175, 71,221,186,117, 49,106,212,168,144, 13, +235,215,191, 12,151,107, 65, 69,219, 7, 2, 97,117, 99, 98,182,159, 60,121, 50,136,115,142,245,235,215,195,104, 52,194,110,183, + 67, 16, 4,120,121,121,193,223,223, 31, 15, 60,240, 0,130,131,131, 17, 19, 19,131, 31,127,252, 49,104,200,144, 33, 59, 2,115, +115, 59, 20, 0,153,213, 62, 9, 4,233, 57, 57,123, 7, 1, 65,227,198,142,221,117, 46, 62,190,215,184,113,227,144,147,147, 51, + 93, 54,109, 90,145, 19, 88, 84,221,253,155, 2,190, 1,225,225,171, 63,249,228, 19, 33, 59, 59, 27,111,188,241, 70,126,102,122, +250, 52, 95,224, 40, 0,236,223,189,187,215,183,223,126, 59,119,253,250,245, 65,235,214,173, 19,218,183,111,191,186,233,245,235, + 45, 19, 1,125, 77,218,105, 0, 94,253,236,179,207,188,172, 86, 43, 6, 14, 28,120,205, 43, 53,181,173, 11,176,120,122,255, 44, +224,229,133,111,189, 21,166, 84, 42,241,198, 27,111,228,155,211,211, 91,185,128,188,114,155,164, 5,167,164,236,126,250,233,167, + 47,196,199,199, 7, 45, 90,180, 40,236,177, 17, 35, 94, 6,240,177,167,143,113,199,132,246,152,241, 19, 94, 13,109,223,185, 27, +214,173, 92,138, 57, 51,223, 94, 13, 96, 25, 99,236, 21, 0,159,122,154, 73, 8,185,191,120, 82,139,252, 93,220, 42,176, 74,119, +168,111, 85, 27,251, 7, 6,118,108,213,170, 21,142, 28, 57,130,214,173, 91,159,244,243,243,115,201,149, 74,200,100, 50,112, 81, +172,246,193, 84, 26, 77,255, 1, 3, 6, 72,127,255,253,119, 52,108,216, 16, 42,149,234, 86, 97, 85,118,145,203,229, 8, 15, 15, + 71,113,113, 49,250,247,239, 47, 91,178,100, 73,255,234, 10, 44, 0, 72,191,114, 65,155,247,251, 39, 99, 87,172, 89,221,160,119, +239,222,208,235,139, 33,138, 34,212,106, 53,236,118, 59,164, 82,105,201, 80,143,147, 23,123,242,196,184,221,110,183, 68, 34, 65, +195,134, 13, 49,123,246,108, 88,173, 86,200,229,114, 0, 64,113,113, 49,138,138,138,112,225,194, 5,164,165,165,129,151,150,222, + 85,241,246,245,125,232,137, 39,158, 80, 84,244, 59,155,205, 6,189, 94, 15,189, 94,143,162,162, 34, 88,173, 86,116,235,214, 77, +241,203,142, 29, 15,161,160,160,194, 2,203,230,229,245,216,186,117,235, 66, 20, 10, 5, 44, 22, 11, 12, 6, 3,110,220,184,129, +244,244,116,107,110,110,174,203,219,219, 91,136,142,142, 22,148, 74,165,114,248,240,225,172,184,184, 24,140, 49, 12, 29, 58, 52, +240,187,245,235,159, 0, 80,229,138, 54,242,135,189,128,173,131,221, 62,172, 75,231,206, 7, 78,158, 58,213,254,181,215, 94, 67, +124,124,252, 39,234, 31,126, 56,108, 6,206, 85,117,223,107,192,203,243,203, 21, 46, 60, 61,189,181,227,142,194, 37,186,164,112, + 57, 95, 86,184, 60, 94,195,194, 5, 0,188,125,125, 59,133,135,135, 99,215,174, 93,184,158,154,250,118, 77,138, 43, 0, 16, 36, +146,158,189,123,247,198,182,109,219,144,145,158,254,246, 29,197, 21, 0, 32, 15,200,147, 94,187,246,246,234,213,171, 87, 61,247, +220,115,144, 72,165, 61,225,114,213,228, 97,238,154,208,254,220,196,215,176,122,249,146,213, 0, 94,224,156,139, 0, 78,214, 36, +144, 16,114,127,241,164, 22,249,187,184,213,237,196, 57,103, 0, 14, 85,181,113, 72, 72, 72, 29,173, 86,139,204,204, 76, 52,111, +214, 44, 87,169, 84, 66, 33,147,193, 75, 81, 97,221,112, 23,179,217,220, 58, 34, 34, 2,122,189, 30, 65, 65, 65,144,203,229,183, + 46, 10,133,226,214,207,222,222,222, 16, 4, 1, 81, 81, 81, 48,155,205,173,171,205,205,185, 16,242,195,146,151, 38,199, 30,222, +213, 96,196,136,145,240,247, 15, 64,100,100, 93,132,132,132, 64,165, 82, 33, 50, 50, 18,141, 26, 53,226, 11, 22, 44,128, 58,164, +141, 71, 31,224,229,139, 38,169, 84, 10,183,219,141,156,156, 28, 36, 38, 38, 34, 62, 62, 30,177,177,177, 56,123,246, 44, 12, 6, + 3, 60,168,175, 96,182, 88,218, 74,165,119, 79,121,179,217,108, 40, 42, 42,186,213,123, 85, 84, 84,132,188,188, 60,164,165,165, +193,104, 50,181,171, 44,207, 63, 48,112,100,171, 86,173, 36, 0,160, 82,169,208,174, 93, 59, 44, 91,182,204,245,243, 79, 63,141, +110, 17, 27, 27, 16,185,103,143,223,138,175,191, 30, 61,106,212, 40,247,239,191,255,142,226,226, 98, 92,190,124, 25,193,193,193, + 82,133,151,215, 19,158, 60, 7,228, 15,103, 0, 83,144,193,240, 96,247,238,221, 83,244,122, 61, 62,253,244, 83, 65,230,237,189, +124, 38, 32,169,242,142, 18, 73,143,222,189,123, 99,251,246,237,200, 76, 79,159,150, 94, 65,225,146, 14,228, 93,191,118,109,218, +234,213,171, 49,104,208, 32, 48,169,180,198, 19,145,186,118,237,218, 74, 20, 69,156, 63,127, 30,126,192,137,154,222,191, 81,227, +198,237,181, 90, 45, 18, 18, 18,160, 41,237, 93,171,136, 6, 56, 26, 23, 23, 7,149, 74,133,230, 45, 90,116,168,225,195, 44, 96, +140,101, 61, 55,241, 53,108,217,125, 28, 0,176,122,249,146, 28,252, 81, 92, 17, 66,254,225, 60,169, 69,254, 46,106,116,160,209, +178, 66, 66, 38,147, 65,161, 84, 66,161, 80,148, 20, 70, 74,165,199, 25,140, 49,120,121,121,221, 42,168,202, 23, 86,229,127, 86, +171,213, 30, 21, 46, 0,160,187,186,187,215, 11,207, 63,167, 80, 42,149,176,219,109,224,156, 67,169,244,130,159,159, 31, 26, 54, +108,136,226,226, 98,116,239,209,199,118,163, 72,190, 35,176,249,240,248,154,236,115, 25,151,203, 5,147,201, 4,157, 78,135,194, +194, 66, 20, 23, 23,195, 98,177,120,188,164, 92, 20, 69,201,141, 27, 55,176, 97,195, 6, 20, 20, 20, 0, 40,153, 64, 93, 86, 84, +149,253,155,146,146,130,245,235,215, 35, 53, 53, 21,168,193,255, 79,175, 94,189,176, 99,199, 14, 73,223,254,253, 87,254, 26, 29, +157,249,107,116,116,102,223,254,253, 87,110,223,190, 93, 82,167, 78, 29,164,165,165,225,244,233,211,208,233,116,101, 47, 96, 82, + 67,201,128,206, 92, 88,248,220,244,233,211,185, 86,171,197,167,243,231,183,253, 24,120,178,170,251,148, 47, 92,124,171, 40, 92, +124,255, 92,225, 2,206, 57, 68, 81,132,219,237,209,209, 72,238,194, 24, 99, 50,153,172,166,135, 72,240,120,227,242, 19,218,223, +122,127, 54,118,110,219, 84,246,171, 43, 84, 92, 17, 66,238, 71, 82,224, 86,197, 88,237, 31,222,156,156,156,155, 38,147,169, 65, +116,116, 52, 50, 50, 50, 66,162,162,162,210, 21, 50, 25,228, 10,133, 71,115,176,212,106,245,249,204,204,204, 30,117,234,212,129, +203,229,186, 85, 76,221, 57, 68, 8,148,244,202,156, 61,123, 22,106,181,250, 60,172, 85, 30, 1, 1,110,187,174, 94,135, 14, 29, +110,245, 4,249,249,249,193,207,207, 23, 74,165, 23,222,125,247, 93,113,209,130, 5, 75,163, 30,152,169,127,118,202,116, 62,253, +227,149, 30, 62, 53,158,241,244, 15,146, 90,173, 62, 31, 25, 25,217,205,215,215, 23, 91,182,108, 65, 90, 90, 26,116, 58, 29,204, +102, 51,108, 54, 27,204,102, 51,236,118, 59,188,188,188,208,162, 69, 11,248,248,248, 96,223,190,125,231, 97,179, 85,152,167, 43, + 40,216,114,254,252,249,110,157, 59,119,190,213,131,210,175, 95, 63,214,175, 95,191,160,178,235,102,179, 25,249,249,249, 56,121, +242, 36,246,237,219, 7,198, 24,174, 92,185,226,182, 89, 44,223,255,217,253,254,167,178, 2,191, 73, 86,175, 94, 53,105,210,164, +231,123,244,232, 1, 55, 48, 4,192,250,202,182,255,171, 11,151, 50,177,177,177, 23,220,110,119,143, 38, 77,154,160, 8,232, 2, + 96, 91, 77,238,159,124,245,106,156,203,229,234,223,182,109, 91,108,217,184,177, 23,128,180,138,182, 51, 1,189,218,183,111, 15, +139,197,130,203,151, 46,157,241, 36,187,180,184, 90,249,206,140, 79,198, 63,253,194,203, 88,183,114, 41, 86, 47, 95,114, 99,213, +178,197,145, 0, 28, 53,105, 39, 33,228,254,229,105, 45,242,119, 81,163, 30, 44,189, 78,119, 38, 46, 46, 14, 29, 58,116, 64,114, +114,114,103, 46,138, 82,185, 66, 1,133, 92, 14,193,131, 63, 32, 22,147,105,255,254,253,251, 93,237,218,181,131,209,104,132, 84, + 42,189,173,247, 74,161, 80, 64, 38,147, 65, 42,149, 66,173, 86, 99,235,214,173, 14,139,201,180,191,186, 92,209, 45,186, 5, 65, +184,245, 71,172,168,168, 8,102,179, 5,179,103,207,198,231, 11, 22,140,117, 3, 83,100,154,224, 26,205, 73,169,109, 86,179,249, +192,206,157, 59,157, 13, 26, 52,192,248,241,227, 49,101,202, 20, 76,153, 50, 5,147, 38, 77,194,248,241,227,241,212, 83, 79, 97, +196,136, 17,232,210,165, 11,130,131,131,145,152,152,232,180,154,205, 7, 42,203, 83, 90,173,155,159,121,230,153,220,178,194,204, +100, 50,193, 96, 48, 64,175,215, 35, 47, 47, 15,199,143, 31,199,186,117,235,176, 96,193, 2,108,221,186, 21, 54,155, 13, 14,135, + 3,103,207,158,213,105,156,206,141,255,159,251,126,191,145, 1, 91,142, 29, 59,134,128,128, 0, 68,212,173,219,167,170,109, 75, + 11, 23,180,109,219, 22,122,160, 87,101,219,233,239,161,112, 41,207,100, 48,156, 74, 73, 73, 65,223,190,125, 17, 94,183,238, 39, + 45, 0, 85, 77,238,239,118,185,142, 30, 59,118, 12, 79, 63,253, 52,162, 27, 52,248, 36, 24, 8,190,115,155, 96, 32,184,126,163, + 70,159,140, 31, 63, 30,123,247,238,133,219,229,170,180, 71,142, 49,214,145, 49,182,157, 49,118, 24, 64,218,248, 9,175,142,191, + 99, 66,251,227,140,177,111, 1, 84,122,200, 20, 66, 8,249, 59,171, 81,129,165,114,187,223,153, 58,117,170, 83, 16, 4,140, 28, + 57,210,123,219,246,237,163,206,158, 59,215, 48, 55, 55,215,207,237,118, 87,155, 21,108,179, 45,158, 58,117,106,145,221,110, 71, +211,166, 77, 81, 88, 88, 8,183,219, 13,169, 84, 10,169, 84, 10,198, 24, 4, 65,128, 86,171, 69, 92, 92, 28, 86,173, 90, 85, 28, +108,179, 45,174, 46,215,237,118,159, 95,191,126, 61, 36, 18, 9,247,242,242, 2, 99, 12, 82,169, 20,139, 22, 45,202,253, 28,216, + 2, 0, 18, 65,176, 3,128, 32, 48, 79,103,229, 86, 59, 62,169, 80, 40, 32,150, 76,238,175,118, 91,127,155,237,179,121,243,230, + 25, 46, 95,190, 12,147,201,116,171,183,205,104, 52,222,154, 52, 95, 84, 84, 4,198, 24, 76, 38, 19,182,111,223,110,240,183,217, + 62,171, 44,175, 0,200,206,184,114,229,145,206,157, 59, 23,164,164,164, 64,175,215,227,252,249,243,216,183,111, 31,126,252,241, + 71,236,221,251,127,236, 93,119, 84, 84,215,215,221,119, 58, 83,232,189,139, 20, 65, 4, 21,177,119, 81,177,119,141, 70, 99, 18, + 99, 52,137,137,177, 36,209,104,108,137,198,152,166,166,153,104, 18,107,130, 93, 36,118, 69,137, 26, 43,168,128, 10,138, 32, 34, + 48, 67,155,222,203,253,254,128,225,135, 74, 25, 82,190,196,100,246, 90,179, 24,102,238,219,239,220,247,238,188,183,223,185,231, +158,115, 12,119,238,220,129,201,100,130,191,191, 63, 40,165,216,191,127,191,204,164, 80, 12,174, 0, 74,109, 60, 6,255, 73,180, +240,241, 73,240,246,242, 42,244,244,240, 40,106,225,227,147,240,248,247,206, 64, 78, 78, 78, 14, 76, 38, 19, 66, 67, 67,221, 26, +139,195,162, 38,211, 89,171,112, 9,108,217,114,117,112, 61,194, 37, 24,240, 12, 14, 11, 91,109, 21, 46,212,100, 58,219, 92,155, + 29,129,245,111,189,245,150,134,195,225, 32, 41, 41, 41,212, 24, 30,126,139, 5, 76, 18, 1, 81,125, 0, 78, 83,219,251, 2, 95, +189,247,222,123,165,132, 16,108,223,190,221,195, 57, 44, 44,147, 5, 76,117, 6, 90, 56, 3, 45, 88,192, 84,231,176,176,204,164, +164, 36, 15,147,201,132, 57,115,230,148,250, 2, 95, 53, 66,249, 6,165,116, 56,165,180, 23,165, 52,240,135,111,215,225,208,129, +221, 86,113,245, 18,165,244, 18,165,116, 10,165, 52,179,185,125,181,195, 14, 59,236,120, 26, 64,234,139,115, 98,119, 94, 41, 6, +168, 87,239, 46,109,113,249,218,109,153,135,171,211, 81,235,119,149, 89,187, 91,245,139,117,106,251,245,215, 95,131,205,102,227, +193,131, 7,200,206,206,134,147,147, 19,158,125,246, 89,157, 70,161, 24, 97,173, 69, 72, 8,233, 79, 41, 61, 81,195, 89, 93,239, + 76,150, 43, 10, 99, 93,111,121,228, 80, 10,211,217,217, 25, 74,165,178, 54,173,128, 64, 32, 0,159,207,199,149, 43, 87, 48,116, +248, 72,115,153,160, 87,109,162, 81,107,189,179,186,156, 32,132, 9, 0,157, 1, 65, 58, 48,207,203,207,111,254,226,197,139,249, +137,137,137,224,112, 56, 8,104, 17, 81, 26, 58,232,227,245, 12, 6, 49, 21, 85,200, 23,133,181,240,115,206,206, 45, 0, 64,170, +107, 22,214,212, 34,172,207,206, 32,253,153,208,125, 91, 62,117,106,223,190, 58,206, 92, 42,149, 66, 44, 22, 67, 34,145, 64, 42, +149, 66,165,170, 78,245,144,146,146,130, 67,105,183,228,154,128,113,121, 13,217,249,191,190,223,118,244, 51, 92, 12,217,177,109, + 11,211,211,211, 19, 98,177, 24,101,101,101,144, 74,165,208,104, 52, 48,155,205,168,172,172,196,247, 63,110, 49, 87,136,122,229, + 91, 19, 57, 54,202,169,122,192,119, 83,158,243,143,139, 14,166,211,166, 77,115,116,114,114,130,197, 98, 65, 85, 85, 21, 10, 11, + 11,113,239,222, 61,164,165,165,169, 36, 82, 61, 84, 30, 3,138,172,137, 70,235, 61,158,127,214,160,122, 26, 57,107,198, 18, 0, +248,249,250, 22,223,191,127,223,203,108, 54,195,223,223,223, 36,173,172, 92,205, 5,142, 57, 2, 37, 0,104, 57,176,120,237,250, +245, 47,142, 28, 57, 18, 29, 59,118,124, 80, 42, 22,135,212, 55,150, 64, 8, 51, 18,112, 86, 7, 4,100, 93,186,116,201,167,176, +176, 16,207, 61,247, 92,249,253,187,119,107,211, 52,200,128,158,193, 97, 97,171,147,146,146, 60, 90,182,108,137,216,216,216, 82, + 7,107,154,134,250,199,103,131,191, 77,105,206, 47, 33,175,140,142,233,248,234,171,175,194,100, 50, 33, 45, 45, 13, 23, 47, 94, +196,253,251,247,113,238,220, 57,169,147, 80,248,140,181, 22, 97, 67,227,115,112,132, 42,116,251,246,109,132,195,225,224,199, 31, +127, 68,122,122, 58, 0, 32, 46, 46, 14, 47,188,240, 2, 76, 38, 19, 38, 79,158, 66,127,185,205,207,107,108,124, 18, 66, 98, 0, +124,130,106,113,215,145, 82,234, 64, 8, 41, 6, 16,216,156,152,171,167,114, 44,217, 57,237,156,118, 78, 59, 96, 67, 45,194, 15, +190,129,243,163,229, 56,166, 23,239,254,118, 57,171, 71,207, 94, 81,203,151, 45,101,116,234,212, 9,129,129,129,136,139,139, 67, + 97, 97, 33,207,197,197,165,169,122,103,202, 94,131, 38,221,107,219,182,173,203,130, 5, 11,156, 7, 14, 28,200, 14, 12, 12, 4, +165, 20,233,233,233,216,187,119,175, 97,211,166, 77,114,181,247,112,233,213,212,159,148,182,212, 59,187, 8,168, 1,172, 8, 40, + 46,254,238,181, 87, 94, 89,218,190, 67,135,105,203,150, 45, 99,136, 4,124,246,170, 69, 47, 57, 0,192, 7, 95,238,116, 30, 57, +238, 89,172, 13, 7,122, 79,170,191,206, 91, 93, 59, 11,139,166,223, 31, 50, 58, 33,124,222,172, 23,205, 19, 38, 76, 16, 58, 57, + 57, 33, 48, 48, 16,174,174,174,200,203,203, 67, 81, 81, 17, 61,120,240,160,242,183,140, 28,246,254, 99,151,239, 59, 56,251,218, + 82, 55, 80,209, 43,113,124,254,144, 33, 67, 92,167, 78,157,234, 24, 31, 31,207,230,241,120,224,241,120, 16,139,197,184,115,231, +142,225,224,193,131, 74,181,215,224,170,171,169, 73, 10, 27,107, 17,106,122, 77, 92,126,231,215,227,203,230,100,221,184, 49,197, + 2,180, 51, 24, 12,254,102,179,153, 48, 24,140, 18,139,197,114,195,160, 80,252,160,139, 91,246,185,189, 22,161,109, 48,155,205, + 28,179,217, 12,169, 84,138,227,199,143,179,238,222,189,187,248,218,181,107,139,139,139,139, 97, 52, 26, 49,118,236, 88,196,197, +197, 33, 53, 53, 21,101, 98,241,193,198,184,110, 3, 50, 94, 81,209, 11,211,167, 79, 63,188,109,219, 54,198,181,107,215, 60,126, +252,241,199,239,235, 19, 46, 83,166, 76,177,136, 11, 11, 95,208, 53,146, 3,171,137,223,102,249,145,164, 47,174,141, 26, 51, 46, +122,217,146,197,236,110,221,186,193,195,195, 3, 61,123,246,132,193, 96,112,105,221,186,117, 83,191, 77, 69,175, 65,207,228,181, +107,215, 78,248,249,231,159,251,188,248,226,139,152, 53,107, 22, 0, 64,163,209,224,216,177, 99,152, 51,103, 78,105, 33,171,179, +170,169,241, 89,227,153,178, 10,175, 51, 0,122, 1,200,179, 7,180,219, 97,135, 29,255, 21, 52, 89,139,240,215,139,153,168, 91, +142,163, 26,190,217,166,160,169,119,103,204, 95, 29,203, 52,202, 93,217, 68,235,148,155,147, 67,154,170, 73, 88, 91,239,204, 57, + 66,233,126,239,231, 78,171, 62,248, 96,246,218,181,107, 19,172,169, 24, 4, 2,193, 13,141, 74,117,210, 83,167, 91,167,118,142, + 56,217,220,218,121, 69,128, 24,192, 43,174, 87,175,174, 31, 54,114,236, 26, 7,183, 80,246,187, 43, 55,105,153, 12,134,254, 78, +113, 25,214,134, 3, 66, 27, 22, 60,170,245, 64,150,212,215, 36,118, 31,119,251,189,183,222,154,247,193,138, 21,157, 68, 34, 81, +111,131,201, 20, 97,177, 88, 0,139, 37, 87,173, 82,157,161, 6,195, 37, 93,220,146, 79, 29,156,125,169,205,117, 3, 93, 90, 43, +220,242,119,119,218,252,195, 15,111,236,218,181,235,137,190,187,235,116,235,213, 46,173, 79,216,210,247,186,109,180,192,121, 72, + 36,231, 27,106, 75, 96,175, 69,104, 43, 88, 22,203,203,174,174,174, 91, 19, 18, 18, 28,250,247,239,143,161, 67,135,162, 91,183, +110,176, 88, 44,160,148, 66,161, 80, 96,231,206,157, 88,179,102, 77,110, 8,176,162, 41, 62, 29,112,146,119,232,208,224,118,237, +218,253,216,152,112,169, 17, 87, 77,198, 28, 54,254,219,228,229,154,156, 71, 20, 76,124,109, 85,184, 94, 94,226,226, 46, 48,249, +100,101,222, 96,216,254,219,140, 84,152,211,119,118, 30, 59,122,244,107, 76, 22,171,103,205,138, 70,122, 51, 59,251,170,181,216, + 51,226, 94, 56,222,204,177,100,205, 61,103, 15,104,183,195, 14, 59,254, 51,104,176, 22,161,213,203,195, 98,177, 36,121,251,103, + 60,219, 24, 9, 27, 72,168,241, 92,161,201, 90,132, 53,239, 11, 0, 5,116,186,247, 31, 73, 34, 90,103,181, 32,251,177,246,205, +233, 84, 21,112, 27, 38,221, 48, 72,178,129,228, 87,170,249, 58,125,240, 78,221, 62, 53,180,237,163,118,114, 42,181,192,175, 80, + 42,127,133, 82, 89,111,118,105, 54,139, 83,217,148,157,143,247,189, 16,144,255,209,190, 63,206,217,224,193,248,157,237,255,203, +120, 88, 94,190, 31,128, 40, 32, 37,197,251, 72, 74,202,132,121,115,231,142,245,245,243, 11,243,240,240,112,117,116,116,100, 92, +184,112,225,158, 73,171, 93,223, 30,216, 92,227, 61,109, 18, 58,224,100,100, 97, 97,155,241,163, 71,191, 70, 88,172, 30,117,133, + 11, 53,153,206,133, 2, 95, 53,230,185,178,162,185,191,205, 64,158,111, 66,141,231, 10, 76, 27,127,155, 69,213,118,172,132,201, +180, 18,215,159,204,106,242, 59,126,155, 31, 16, 66, 20,176,103,104,183,195, 14, 59,254, 75,248, 43,235,240, 0,232,111,231,180, +115,254, 91, 56, 81, 29,204,238,244, 79,183,211,206,105,231,180,115,218, 57,159, 70,206,127,219,171,193, 41, 66, 59,236,176,227, + 81,208,234,160,115,155, 74, 45,217, 97,135, 29,118,216,241,223, 6, 1,208,191,190, 47,104, 51, 86, 7, 16, 66,234,179,190,216, +255, 0, 0, 32, 0, 73, 68, 65, 84,229,104, 12, 77,241,219, 57,237,156,118, 78, 59,167,157,211,206,105,231,252,247,113, 54,197, +221, 28,253,241,143,198, 95,233, 30,195, 83,226,150,180,115,218, 57,237,156,118, 78, 59,167,157,211,206,249,247,114,254,219, 94, +205, 74, 52,106,135, 29,118,216,241,111,197,242,229,132, 1, 16, 2, 44,103, 0,187,153,192,120,102,245,255,191, 31,227,199,147, +122,147,208,190,241, 6,113,252, 35,188,118,216, 97,199, 63, 31,246, 24,172,191, 17,132,144, 32, 31, 31,159,111, 1,144,210,210, +210,151, 41,165,133,127,183, 77,118, 60, 9,119,119,247, 4,147,201, 4,153, 76,214,100, 10,133,167, 17,109,194,201,104,202, 64, +235,218, 15, 40, 10,179,115,233,214,250,218, 70, 71,144,231, 64,254,151, 75,139, 88,112, 51,235, 14,221,103,235,190, 8, 33,140, + 81,131, 61, 63, 1,128,253,135,203,230,211,191, 32, 47, 22, 33,164,149,167,167,231, 81, 22,139,197, 50,155,205,175,136,197,226, +148,134,218,142, 31, 63,158, 9, 0,158,252,189, 11, 93,220, 60, 22,188, 55,143,176,245,186,143,165, 58,173, 86,198, 96,177,242, +185, 28,193, 89, 19, 67,120,184, 72, 60, 56,187,190,237,119,237,218,213, 96,117,237,152, 8, 50, 56, 42, 58,122,120,135, 88,126, +222, 39,235, 58,173,237, 29,234,193,190,247, 32, 67,244,205,214,194,111, 61, 93,253,135,207,126,137,149,194,163,230, 41, 31,125, + 79,149, 13,113,216,241, 36, 62, 36,196,205, 0,196,178,121,188, 64,179,201,228, 77, 0,202,100,177,196, 70,157,238, 1, 7,184, +190,128, 82,233,191,157,147,195,227, 5,152, 77, 38,111, 0,248, 39,218,105, 71, 53, 26, 20, 88,142,142,142, 87, 24, 12, 70, 64, +221, 34,181,140,154,130,206,214,207,234,126, 71, 8,129,217,108, 46,170,172,172,140,183,117,231,132, 16, 39, 0, 19, 0, 88,151, +154,239, 0,176,147, 82,250,187, 2,137, 9, 33, 78, 28, 14,103,190, 80, 40,236,167,209,104,218, 0, 0,159,207,207, 82,169, 84, +167, 12, 6,195, 39,191,135,151, 16,194, 2, 48, 94, 36, 18,245,101, 48, 24,125, 41,165,132, 82,154,170, 84, 42, 79, 1,216, 69, + 41,181,181,244, 78, 93, 78,190,151,151,215,202,168,168,168, 73, 11, 23, 46,172,112,119,119,143,156, 51,103,206,101, 79, 79,207, +159,202,203,203, 23, 81, 74,255,214,186,137, 86, 16, 66,194,124,124,124,118,176,217,108,230,131, 7, 15,250, 2, 64, 96, 96, 96, +170, 94,175, 55, 75, 36,146,103, 41,165,119,155,201, 39, 4,208, 69, 36, 18,197,139, 68,162, 94,102,179,185,181,197, 98,129,197, + 98,185,169, 84, 42,211, 12, 6,195, 21, 0, 23, 40,165,170,191,162, 63,191, 7,132, 16, 71, 47, 47,175,109,132, 16, 16, 66, 34, + 40,165,138,191,219,166, 63, 27,148,129,214,217, 89,183, 34,173,255, 71,183,137,106,184, 49, 65, 80, 61,109,109, 22, 88, 67, 18, + 92, 6, 13, 31,222,142, 1, 0, 6,195,229, 65, 0, 14,253, 14,147, 27, 54,143,144, 86, 99,198,140, 57,191,109,219, 54, 87,157, + 78,135,151, 95,126,121,135,179,179,243, 87, 50,153,108, 97, 99,219, 57, 58, 58,206, 89,241,254,151,130,154,107,154,151,197, 98, +241, 42, 41,121, 16,113,251,214,141, 65,183,111,103,174, 50,168,246, 93, 48, 80,230, 12,169,122,196, 45, 91,236,136, 14, 35,195, + 70,142, 31, 61,116,197,138,101,152,244,204,164, 22, 89, 89, 90,190,191, 83, 30, 87,110, 16,134,123,120, 4,140,120,231,221,143, +200,133,223, 78,143,216,181,115,211,169,119,166,145,126,118,145,213, 52, 8, 33,228, 3, 22,171,139,107, 84, 84,175,103,246,239, +135, 40, 48,144,197,226,241, 24, 0, 96,210,233, 2,149, 15, 30,248, 38,141, 24,209,121, 57, 33,167,151, 82,122,209,206,249,255, +207,105,199,163,104, 80, 96, 49, 24,140,128,135, 15, 31,122, 9,133, 66, 0,213,177, 90,102,179, 25,102,179, 25, 53, 55, 69, 80, + 74,107,255,154, 76, 38, 68, 69, 53,114, 97,174, 1, 33,132, 1,160, 31,128,231,251,244,233, 51,238,147, 79, 62, 97,199,198,198, + 90, 75,123,244,124,247,221,119,191, 36,132,236, 1,176, 25,192, 73, 91,159,112, 9, 33,137, 66,161,112,251,199, 31,127,236, 52, + 96,192, 0,150,159,159, 31, 8, 33, 40, 45, 45,237,114,226,196,137,248, 57,115,230,188, 66, 8,153, 76, 41, 61,218, 52, 91, 45, +103,140,163,163,227,238,209,163, 71, 7,244,238,221,219, 33, 58, 58, 26,102,179, 25, 25, 25, 25, 47, 94,185,114,101,226,158, 61, +123,150, 18, 66,198, 81, 27,235,169, 17, 66,136, 72, 36,154,234,239,239,191,114,201,146, 37,110,147, 39, 79,230,102,102,102, 86, +133,134,134,146,179,103,207,122,238,220,185,243,149,213,171, 87,143,119,116,116, 92,164, 84, 42,183,208,154,137,238,198,224,228, +228,116,133,193, 96, 4, 0, 77, 11, 96, 0, 54,139, 96, 66, 72,251,144,144,144,157,191,254,250,107, 72, 65, 65,129,121,212,168, + 81, 91, 1,224,212,169, 83,177, 70,163,145, 12, 28, 56,240, 48, 33,100, 2,165, 52,195,198,190,183,117,115,115, 59, 48,105,210, + 36,183,176,176, 48, 65, 72, 72, 8, 17, 10,133, 96, 50,153,144,201,100,126,153,153,153,253, 47, 94,188,168, 57,113,226, 68, 37, + 33,100, 4,165,244,201, 4, 76, 13,115,119,243,242,242,154,194,102,179, 99, 76, 38,147, 63, 0,176, 88,172,135, 70,163, 49, 83, + 34,145,108,163,148, 54,152,128,181, 41,120,123,123,127,177,114,229, 74, 15,137, 68, 66, 87,175, 94,253, 5,128,169,191,151,235, +159,142, 29, 63,237,194,149,203, 23, 1,128, 67, 8, 33,143,143, 63, 66, 8,105, 29, 1,206,155,111,206, 69,124,199,206,120,118, +210,248, 38, 57, 71, 13,245, 88,193,101,178,220,213,122,221,197,114, 25,227, 64,144, 23,119,244,228,241,241,121, 0,112,228,240, +141,209,157, 59,187,157,245,112,182,140, 20,112,121,157,245,102, 83,197,254, 95,202,151,216,106, 47, 33,164,149,191,191,255, 81, + 87, 87, 87, 65,101,101,101,105, 89, 89,217, 55, 99,198,140,249, 96,243,230,205,174,247,238,221,195,131, 7, 15, 48,123,246,108, + 81, 81, 81,209,107, 60, 30,239, 55,157, 78,215,160, 39, 75,161, 80,172, 91,249,254,220, 37,142, 78,174, 76, 1, 95, 8,145,163, + 19, 66, 66, 34,208,177, 83, 79,244, 31, 48, 2,121,121,183,187,236,252,121, 83, 58,179,100,247,135,102,110,220, 7, 82,105, 72, +131,215,165, 54,145,164,183, 85, 92, 45, 89,178, 12, 57,183,110, 41, 10,242, 25,175,255,178,159, 37, 24,156, 16,197,211, 27,148, + 5, 23,126, 59, 29,210,165,107, 31, 0,136,223,181,115,211,169,229,147, 73,194,210,237,255, 62,241,254,103,129, 16, 66, 86,176, +217, 83, 19, 63,255,220, 43,238,149, 87, 56,202,252,124, 67,222,134, 13,106,113, 90,154,153,197,227,209,192, 65,131,136,103,223, +190, 14,175,220,188,201, 57,183,122,117,175, 85, 92,110,232,187,122,253,118, 59,231,255, 31,167, 29, 79,162, 65,129, 69, 8,129, + 80, 40, 68, 82, 82, 18,216,108, 54, 88, 44, 22,216,108,118,131,239,131,130,158,168,192, 81, 31,231, 24, 31, 31,159, 47,191,250, +234, 43,239,196,196, 68, 56, 56, 56,212,126,199,100, 50, 49, 96,192, 0,244,239,223,159, 93, 92, 92, 60, 49, 41, 41,105,226,170, + 85,171,196,132,144, 89,148,210,189, 77,240,246,141,140,140,220,123,236,216, 49,190, 86,171, 69, 90, 90, 26,170,170,170,192,229, +114, 17, 16, 16,128,129, 3, 7,178,110,221,186,229, 54, 96,192,128,189,132,144, 97,148,210, 84, 27,108,141,247,242,242, 58,179, +107,215, 46,135,118,237,218,145, 59,119,238, 32, 46, 46, 14, 0, 32,147,201, 48,106,212, 40,135,201,147, 39,135, 77,156, 56,241, + 2, 33,164, 55,165,244, 74, 19,124, 29,124,124,124,182,140, 30, 61,218,111,213,170, 85, 78,142,142,142, 40, 40, 40, 40,241,241, +241,137,176, 30,239,137, 19, 39,114,135, 15, 31,238,187,102,205,154,117,187,119,239,126,139, 16, 50,149, 82,122,181, 49, 94,171, + 16, 22, 8, 4, 16,139,197,216,177, 99, 7, 94,123,237, 53, 48,153, 76, 72, 36, 18,236,220,185, 19,175,191,254,186, 85,200,216, + 36,130,133, 66, 97,255,118,237,218,125,127,234,212,169, 0, 23, 23, 23,248,249,249, 49,222,123,239,189,152,208,208, 80,126,139, + 22, 45,152, 37, 37, 37,216,187,119,111,232,148, 41, 83, 14, 56, 56, 56,188,168,213,106,155,156, 58,243,246,246,254,225,151, 95, +126, 9,202,202,202,194,134, 13, 27, 80, 89, 89, 9, 46,151, 11, 23, 23, 23,248,248,248, 32, 34, 34,130, 44, 88,176, 64, 48,124, +248,112,193,172, 89,179,126, 0,208,190, 41, 78, 66, 72, 59, 47, 47,175,111, 39, 78,156, 24,186,124,249,114, 23, 31, 31, 31, 88, + 31, 8,100, 50, 89, 64, 65, 65, 65,151, 37, 75,150,140,243,246,246,190, 39,145, 72,102, 80, 74,175, 53,217,249, 71,249,219, 39, + 36, 36, 12, 27, 53,106, 20,179,164,164, 4,219,182,109, 27, 70, 8,105,111,171,168,124,218,112,229,242, 69,188,252,234,108,165, + 95, 96, 32,231, 96,242,207, 35,149,202,239,206,138, 24, 46, 44, 0, 80, 90,164,166,238, 93, 68, 61,134,143,152,200, 25, 50,116, +148,242,187,175,215,137,108, 17, 88, 92, 38,203, 61,105,251,204, 7,105,231,114, 91, 31, 61, 81,208,127,212,136,254, 12, 22, 39, + 50, 12, 0,230,205,157,206,221,159,124,226,171,196,254, 45, 74,122,117,143,120,240,204,228, 13,129,182,218, 74, 8,105,213,170, + 85,171,211,233,233,233,222, 60, 30, 15,149,149,149,238,223,125,247,221,103, 61,122,244, 96,228,229,229,225,214,173, 91,200,207, +207,135, 76, 38,195,128, 1, 3, 68, 87,175, 94,253, 6, 64,131, 2,171, 76, 51,102,101,168, 87,249,122,127,119,215, 16,173, 65, +230,101, 54, 85, 68,159, 58,113,173,237,158, 93,234, 56, 47,159,128,136,137, 19, 95,198, 59, 11, 63, 98,239,219,179,101,201,153, +180, 99, 0, 66, 26,206,224, 79,209,237,221, 69, 11, 33, 87,232, 48,121,210,116, 76,153, 52,221,157, 66,239, 75,205, 90,161, 94, + 83,229,226,204,201, 74,217,242,243,174,209, 0, 2,234,136,172,147,118,145,213, 48, 86,176, 88,157,135,125,249,165,103,204, 75, + 47,241,174, 45, 95,174, 42, 79, 75,211,132, 15, 25, 82, 21, 55,115,166, 14, 0, 20,249,249,156,156,165, 75, 5,158,189,122,241, +187,206,159,239,106,214,235,125,222, 39,164,211,123,148, 94,106, 46,103,208,132, 9,230, 37, 63,254,216, 49,109,238,220, 62,196, +104,100, 14,234,218, 53, 99,245,182,109, 15,255, 8,231,159,105,103,241,153, 51,186,202,208, 80,196,141, 26, 85, 17,228,229,165, +251, 51,251,254, 71,236,180,227, 73, 16, 74, 41, 8, 33,189, 1,156, 6,176,156, 82,186, 12, 0, 92, 92, 92,196, 82,169,212,107, +239,222,189, 77,138, 43, 54,155, 13, 95, 95, 95, 68, 68, 68, 72,196, 98,177,119,131, 59, 35,228,129,197, 98, 9,160,148,214,122, + 91, 26,130, 78,167, 67,110,110, 46,218,182,109, 91, 68, 41,109,240,194, 75, 8,113, 20, 8, 4,121,183,110,221,242,200,206,206, +198,149, 43, 87, 16, 26, 26, 10, 87, 87, 87,176,217,108, 24,141, 70,200,229,114, 68, 70, 70,130,199,227,161, 67,135, 14,229, 42, +149, 42,180,177,169, 30, 66, 8, 79, 40, 20,230,158, 57,115, 38, 48, 46, 46, 14,151, 46, 93, 66, 96, 96, 32,124,124,124, 0, 0, +249,249,249, 56,123,246, 44,134, 12, 25,130,244,244,116,140, 29, 59,246,129, 74,165,138,160,148,234, 26,226,116,119,119, 47, 57, +117,234, 84, 81,108,108,172, 86,165, 82, 49,196, 98, 49, 59, 45, 45,205,164, 80, 40, 68, 50,153,140, 45,149, 74,217,114,185,156, +165, 82,169,216, 12, 6,131,163,209,104,216, 39, 79,158,100,234,245,122,167,198,142,147,245, 60, 37, 39, 39, 35, 54, 54, 22,123, +247,238,197,188,121,243,112,238,220, 57, 4, 6, 6, 98,215,174, 93,152, 63,127, 62,110,223,190, 13, 15, 15, 15, 68, 71, 71, 55, +122,142, 0, 32, 60, 60,252,206,141, 27, 55,194, 56, 28,142,181,238,162,181,158, 29,202,202,202,112,247,238, 93, 60,124,248, 16, +225,225,225,152, 52,105,210,221,162,162,162,240,198,248, 0, 32, 32, 32,160, 44, 43, 43,203,163,109,219,182, 16,139,197,112,113, +113,129,179,179, 51, 92, 92, 92,106,223,135,134,134, 98,238,220,185,240,241,241,145,104, 52,154, 70,109, 36,132,180,143,141,141, + 61,122,242,228, 73, 15, 39, 39, 39,148,150,150, 66, 46,151,131,197, 98, 65, 32, 16,192,195,195,163, 86,192,231,230,230, 98,232, +208,161,229,121,121,121,137,205,240,184, 49,188,189,189,111, 93,191,126, 61,130, 82,138,194,194, 66,220,190,125, 27,175,190,250, +106,174, 86,171,141,250, 43, 98,135,254, 46,212,137,171,226, 76,125,225,101,206,168, 17, 35,213, 25, 87,142, 88,248, 56,131, 78, +237,249, 82, 0,184,148,161,113,209,160, 55,218,199, 15, 98,236, 79, 62, 32,216,178,249, 59, 54, 44,240, 6,193,237,236, 28,250, +126, 67,220,195, 18, 93,158,155, 63,123, 80,235, 94,221,123,177,228,114,234,243,253,214,141,157,238,223,203,243, 6,128,224,150, +161,226,105,207, 77,191,228,228, 68, 74,211,206,165,153, 62, 89,119,228,102,202, 81,105,189,177, 95,117, 65, 8, 9,141,136,136, +248, 45, 57, 57,217,195,203,203, 11,206,206,206, 80,169, 84, 48, 24, 12,200,206,206,214, 38, 37, 37, 25,157,156,156, 28, 75, 75, + 75, 33,149, 74, 65, 8, 65,114,114,114, 33,165, 52,248,113, 46,107, 12, 22, 0,188, 58,184, 53, 59,186, 95,132, 43,135,103,226, +243,217, 57,190, 32,102, 30,161, 34,239, 83,167,126,107,155,122,230,215,103,135, 12,123,198,179,107,215,190,248,104,213, 59,198, +194, 82,113,156, 84, 61,226, 86,125, 49, 88,173, 35, 72,191, 81, 99, 71,143, 95,177, 98, 25,150, 45, 89,142,148,228,253, 50,145, +144,161,115,114, 97, 59,247,234,210, 93, 59,247,181,145, 15,212,202,162,192,207,190,218, 56,105, 64,226,248,128, 46, 93,251,224, +194,111,167,177,107,231,166, 43, 28,179,209, 62, 93,248, 24,150, 19,226,234, 18, 26, 58,227,141,220, 92,206,181,101,203,148,166, +226,226,170,248, 57,115,202,235,107, 91,116,252,184,144,235,231,231,228, 58, 98,132,219,186,224, 96,106,148, 72,190,173, 47,134, +168, 62,206, 19, 34,145,203,207,135, 15, 39, 80, 54,187,247,219,239,188,195, 31, 54,108, 24,228,114, 57,246,236,217,131,111, 55, +108,208,249,250,250,222,240,203,204, 76,143,145,203, 23,219,202, 25, 63,103, 78,185,217,108, 38,227,231,207, 31,144,149,159,223, +175, 84, 34,105, 1, 0,190,110,110, 15,226, 67, 67,175,252,144,146,114,251,139,144, 16,139,173,118,110, 60,114,196,123,119, 65, +193, 75,110,110,110,124,177, 68,194,226,113,185, 21, 93,162,163,119,125,189,104,209,105,211,245,235, 28,135,128, 0, 39,231, 97, +195,154,221,247,248, 57,115,202, 43, 21, 10,214, 27, 31,124,208,253,190, 88,220, 66,169,211,133, 75, 21, 10, 31,179,209,200,112, + 18, 8, 42, 90, 70, 70, 74, 52,105,105, 37, 45,213,234,217, 27, 41,109,176, 18,202, 31, 69,125, 90,228,105,134,213,131,117,154, + 82,250,196,106, 25, 74,169, 77,222, 43, 54,155,253,200,116, 84, 35,224, 16, 66,112,245,234, 85,184,187,187,195,199,199, 7, 60, +222,163,197, 1,203,202,202,112,238,220, 57,220,188,121, 19,237,218,181, 3, 0, 78, 99,132, 60, 30,239,205, 53,107,214,184,232, +245,122, 92,185,114, 5,241,241,241,224,241,120,224,112, 56,143,136, 63,137, 68,130, 54,109,218,224,237,183,223,118, 94,181,106, +213,155,104,164,134, 28,139,197,154, 53,125,250,116, 47,171,199,234,193,131, 7,232,208,161, 67,237,247,158,158,158,200,200,200, + 64,124,124, 60, 2, 2, 2, 48,110,220, 56,175,109,219,182,205, 2,240, 73, 67,156, 92, 46,151, 17, 27, 27,219, 17, 0,132, 66, + 33, 24, 12, 70,142,147,147,147,167,183,183,183,208,201,201,233,137, 62,254,248,227,143, 82, 6,131, 97,108,172,239, 64,245,180, + 96,105,105, 41, 98, 98, 98, 32,147, 85, 87, 90, 81,169, 84, 8, 15, 15,135, 92, 94, 29,114,166,211,233,224,231,231, 7,141,166, +241,208,174,118,237,218, 45,139,138,138, 26,216,167, 79, 31, 30,155,205,198,181,107,215, 16, 23, 23,135,164,164, 36, 4, 5, 5, + 65, 32, 16, 32, 55, 55, 23,177,177,177, 56,115,230, 12, 60, 61, 61,209,166, 77, 27, 94,135, 14, 29,126,173,172,172, 76, 45, 40, + 40, 88,214,136,157, 12,145, 72,132, 51,103,206,224,135, 31,126, 64,126,126, 62,138,139,139,225,232,232,136,246,237,219, 35, 58, + 58, 26,221,186,117, 67,110,110, 46, 72, 19,131,137, 16,226, 19, 17, 17,145,114,233,210, 37, 15, 74, 41,182,109,219, 6,165, 82, + 9,189, 94, 15, 6,131, 1, 7, 7, 7,184,186,186,162, 95,191,126,240,244,244, 68, 68, 68, 4,118,238,220,233, 49,120,240,224, + 67, 53, 30,168,210,166,142,171,171,171,235,236,165, 75,151, 6,122,121,121,161,160,160, 0, 50,153, 12,222,222,222,232,211,167, +143,255,137, 19, 39,102, 3,248,188, 41,142,167, 5,214,128,118, 66, 8, 57,152,252,243,200, 32, 95,110,235, 78,113,138,224, 27, + 87, 89, 97,135, 78,220,105, 11, 0,174,174,193,215, 59,117, 80,220,189,116,229,200,253,131,201, 63, 95,188,153,131, 3,182, 76, + 97,151,203, 24, 7,142,158, 40,232,223,182, 77, 79,230,250,175,150,142,124,121, 90, 34,207,205,181, 39,145, 75,118,226,220,197, + 27,193,239, 45, 91,224,245,254,178,213, 7,143,158, 40, 48,151,203, 24, 43,109,177,183, 77,107,223, 47, 78,239,247,242, 80, 26, +190, 70,198, 69,103,128,221, 21, 45, 67, 91, 65, 46,151,195,193,193,193, 97,210,164, 73,230,133, 11, 23,170,157,156,156, 4,132, + 16,164,166,166, 74, 0, 36, 54,197,171,245,114,165,102,131,209, 68,185, 76, 11, 37,142, 26, 98,174,228,102,102,223, 67,239,222, +131,197, 29,227,227, 86,173,254,248,243,119, 67, 67, 35, 61, 39, 77,158,193,254,228,147,197, 27, 0,244,172,143,231,102, 46, 61, + 21, 29, 70,248, 0,134,174,120,127, 25,242,242,114, 93, 95,126, 94,186,156,197,227,251, 69, 5,119,119,220,240, 67,234,160,240, +240,144, 22, 47,191,240,226, 47,223,253,248,195, 80,212,241,100,253,252,211,119, 7, 8, 33, 9,182, 28,219,255, 16,218, 78, 73, + 73,129,178,176,208, 88,249,235,175,218,132, 47,191, 44, 15, 76, 76,252, 92,111, 48,120, 88, 47, 21, 12, 66, 64,172, 33, 18, 22, + 11, 97,189,253, 54,131,178, 88, 48,186,186, 62,191, 0,104,213, 20,231,188,146,146, 49,207,190,244,210,208, 3, 71,142, 32, 36, + 36,164,246,126,230,226,226,130,249,243,231, 99,206,156, 57,188,140,140,140, 78,187,119,239,238,244,201,199, 31,123, 47, 0,198, +216, 98,231,177, 11, 23, 92,103,174, 88,177,168, 93,124,124,208,214, 29, 59,120, 97, 97, 97, 0,128,187,119,239, 70,124,180,122, +117,112, 76,108,172,120,213,155,111,110,206, 90,184,176, 13,128, 95, 27,227, 44, 77, 75,211,239, 46, 40,120,233, 84,106,170, 75, + 76, 76, 12, 0,224,246,237,219, 94,235,214,173,155,222,102,220,184,201, 43, 94,121,101,241, 48,173, 86,234, 84, 86,198, 27,246, +197, 23,172,159,199,143,111,146,211,106, 39, 0,244,121,241,197, 55,123,246,237, 27, 61,230,165,151,220,130,130,130,136, 72, 36, +130,193, 96, 64,113,113,177,107, 86, 86, 86, 88,138, 66, 33,223,119,225,194,182,141, 53, 69,220,255, 34,212,171, 69,158, 86, 88, + 5, 86, 31, 66, 8, 5,208,135, 82,122, 6,168,190,113,155,205,102,155,196, 21,139,197, 66, 77, 16,176, 77, 59,165,148,162,188, +188, 28,229,229,229,181, 83, 68, 18,137, 4,167, 78,157, 66,110,110, 46,216,108, 54, 56, 28, 14, 12,134,166,107,195, 10,133,194, +254,253,251,247,103, 93,184,112, 1,161,161,161,224,243,249,181,118, 89, 95, 28, 14, 7,190,190,190,144,203,229, 72, 72, 72, 96, +175, 95,191,190, 63, 26, 17, 88,206,206,206, 67, 38, 76,152,192,181,254,175, 84, 42,193,100, 86, 63,232,234,116, 58, 40,149, 74, + 84, 86, 86, 66, 42,149, 66,171,213,162,107,215,174,220,148,148,148, 33,104, 68, 96,213,133, 90,173, 86, 74, 36, 18,151,158, 61, +123,186,110,222,188,249,118,215,174, 93, 35,235,126,127,250,244,105,173, 86,171,101, 51, 24, 12,155,234,220,109,223,190,189,246, +216, 63,124,248, 16, 27, 54,108,168,253, 46, 55, 55, 23,235,215,175,175,205,203,209,216, 57,138,138,138, 26,188,109,219,182,248, +173, 91,183, 86, 49,153, 76,220,190,125, 27, 59,118,236, 0,165, 20,158,158,158, 80,171,213, 16,139,197, 72, 77, 77,133,201,100, +130, 72, 36,130,191,191,191,195,172, 89,179,122, 44, 95,190,156, 13, 96, 89, 67,220,102,179,217,204,100, 50, 17, 28, 28,140, 37, + 75,150, 64,171,213,130,195,169,214,149,114,185, 28, 82,169, 20,233,233,233, 40, 40, 40, 64, 83, 55, 23, 7, 7,135,113, 91,183, +110,245,226,114,185,208,104, 52, 80, 40, 20,120,240,224, 1,238,223,191,175,149, 72, 36, 38, 71, 71, 71, 70,112,112, 48,131,199, +227,241, 70,141, 26, 69,172, 66,115,216,176, 97,238,219,182,109,123, 6, 77,136, 35, 66,136,103,235,214,173,223,157, 62,125,122, +237, 28, 54,165, 20,165,165,165, 24, 51,102,140,224,252,249,243, 11, 9, 33, 59, 40,165,101,141,241, 60,109,160,148, 82,165,242, +187,179,105, 7,190,108,125,227, 42, 43, 76,175,175,234, 58, 96,200,108, 22, 0,156, 63,243, 99,215, 27, 87, 51,193, 39,166,251, +135,143,125,114, 86, 36,122,185,209,115, 68, 8, 97, 12, 73,112, 25, 20,228,197, 29, 61,106, 68,127,198,247, 91, 55,118,122,121, + 90, 34,207,171,229, 70, 2, 0,174,156, 0,116, 51,207, 99,104,117, 42,135,239,183,110,236, 52,106,196,144,139,249,247,238,127, + 62,180,191,235,190, 67, 39,165, 71, 26,243, 16,250,250,176,253,221,156, 42,224,230, 24,135,224, 80, 71,164,103, 92,199,129,189, +191, 34, 34,170, 7,116, 58, 29, 76, 38,147,112,248,240,225,234,164,164, 36,109, 78, 78,142, 66,163,209,244,166,148,230, 52,213, +255,162,162,108, 75,164, 79, 23, 3,135,207, 51, 41,100, 28,245,130,197,187,199,119,232, 60, 48,222,213,215,159,237, 41,180, 28, +236,219,187,231,142,159,182,127, 59,103,222, 91,239,163,125,251,174, 93,111,222, 57, 28, 13,224, 70,125, 92,217,119,105, 74, 76, + 4, 49,229,221,185, 51,244,126, 65, 65, 81, 43,111, 31,253, 93, 41, 53,206, 94,176,113, 64,207,222,227,218,134,181,238,197,205, +202, 62, 67,230,190, 54,253,167,207,190,218, 56, 9, 53, 34, 43, 45,237,104,239,101,203, 10,184, 0, 26,244,134,255,215,192,225, +241, 2, 68,193,193,172,252,205,155, 53,161,195,135, 87, 1,128,222, 96,240,200, 47, 40,112, 22, 8, 4,160,148,194,104, 52, 62, + 18, 35,108,141, 11,142,137,140,172,215, 19,254, 56,103,254,123,239,181,125,251,237,183, 81, 90, 90, 10,147,201, 4, 54,155,253, + 72,123,181, 90, 13,149, 74,133,231,159,127, 30, 95,124,252,113, 23, 91, 56,205,102, 51,153,185, 98,197,162,119, 22, 45, 10,155, + 49, 99, 6,163,238,181,215,205,205, 13,187,247,236,225,126,245,213, 87, 1,239,126,241,197,243,207,242,120,121, 77,113,150,135, +135,195, 77, 44,230, 91,197, 21, 0, 68, 70, 70, 98,195,134, 13,188,105,211,166,113,135, 15, 31,254,105, 70,187,118,235, 62,239, +209,227,142,123,171, 86, 78, 92, 30, 47,192,214,227, 9, 0, 10,173, 54,230,243,117,235, 92, 47, 94,188, 8,177, 88,140,210,210, +234,231, 80, 66, 8, 58,118,236, 72,166, 76,153,226,220, 50, 48,176, 83,253,103,233, 79,195, 19, 90,228,105, 6, 11, 0,106, 58, + 66,106, 58, 86, 59, 10,204,102,243, 35, 66,165, 41,129,245,123, 32,149, 74, 33,149, 74,177,105,211, 38,112, 56,156,218,155, 46, + 0,232,245,250, 38,183, 87,171,213,177,126,126,126,144,201,100,104,213,170,213, 35,158, 43, 14,135, 3, 22,139, 5, 14,135, 3, + 30,143, 7,157, 78,135,160,160, 32,168,213,234,216,198, 56, 53, 26, 77,123, 55, 55, 55,212, 28, 27,232,116,213,215, 58,157, 78, + 87,107,175, 94,175, 71, 85, 85, 21,148, 74, 37, 20, 10, 5, 84, 42, 85,156, 45,253,181, 88, 44,200,204,204,188, 27, 25, 25,217, +158,201,100, 66, 36, 18, 9, 85, 42, 85,109,236, 80,101,101, 37,182,108,217,162,122,238,185,231, 60,146,147,147,155, 20, 88,132, + 16,188,254,250,235,224,241,120, 80,171,213,248,230,155,111,240,198, 27,111,128,195,225, 64,161, 80, 96,195,134, 13,152, 59,119, + 46, 88, 44, 22,244,122, 61,214,173, 91,215, 32, 87,118,118,118,254,133, 11, 23,226, 58,116,232,224,186,111,223,190,178, 1, 3, + 6,120, 38, 38, 38,130,207,231, 67,163,209,192,104, 52,162, 75,151, 46,136,138,138,130, 68, 34,193,225,195,135,203, 35, 34, 34, + 60, 46, 94,188,104, 41, 45, 45,189,223,152,157,117, 69, 19,139,197,130,217,108,134, 88, 44,134, 84, 42, 69, 89, 89, 25,138,139, +139, 81, 84, 84, 4, 22,139,133,166, 30,222,221,221,221,199,198,196,196, 48, 1,128,207,231,163,125,251,246, 88,180,104,145, 73, +163,209, 76, 0,112,184,166,217,224,141, 27, 55,238, 59,123,246, 44,203,207,207, 15,183,110,221,130,167,167, 39,203,193,193,161, + 73,129,229,227,227,243,227,193,131, 7,221,172,162,218,122,156,213,234,234,211, 49,102,204, 24,183,173, 91,183,254, 8, 96, 72, +163,134, 62,133, 16, 49, 92, 88,157,218,243,165,135, 78,220,105, 59, 96,200,108,150,111,216, 82, 0, 64, 55,128,117,252,208,186, +182, 67,250,135,239,178,198,101, 53,134, 81,131, 61, 63, 25, 62,188, 29, 99,242,248,248, 60, 22, 39, 50,108,251,214,117,222,110, +174, 61,255,119,145, 96,186, 65,200, 7,162,194,204,140,223,126,206,243,158, 59, 59, 82,191, 99,243, 75,121,219,119, 93,233,207, +225, 92,235, 7, 96,110, 67,220,215,179,116,201, 85, 10,255,214,174,156,211, 4, 14, 35, 16,215, 62, 2,158,158, 82,124,243,221, + 86,248, 7,117,135, 78,167,131,147,147,147,192,108, 54, 27,152, 76,230,118, 91,196, 21, 0,156, 60, 41,181,180,105, 35,213, 51, + 21, 22,211,107,111,124, 50,122,192,224, 17,209,253,250,245,183, 28, 59,126,204,208, 61,206, 80,210,175, 95, 87,113,234,233,180, +220,210,210,135, 17, 81, 81,109,145,115, 59, 99, 16, 64, 50,129,250, 7,108,102, 46, 61, 18, 22, 70, 82,147,146, 94,182,104, 44, +233,252, 15, 86,222, 24, 60,116,232,212,152, 94, 61,123, 89,142,159, 56,165,231,162,252,166,168, 71,183,135, 83, 39, 78,216,151, +180,119,223,192,212, 83, 41,225, 50,185, 56,229,227,175, 26, 14, 53,248, 47,194,108, 50,121,179,120, 60, 70, 89,106,170, 41,118, +218, 52, 29, 80,253,123, 20, 8, 4, 56,112,224, 0,184, 92,110,237,139,195,225,212,190,247,246,246,182, 46,170,178,137, 19, 0, + 74, 74, 74, 80, 90, 90, 10,103,103,103,120,122,122,162,180,180, 20,231,207,159, 71, 78, 78, 14,216,108, 54, 6, 13, 26, 4, 70, + 3,177,203,143,115,142,159, 63,127, 64,235,216,216,160,199,197, 21, 0, 24, 12, 6, 84, 86, 86, 98,228,200,145,140,195,135, 15, +251, 28, 41, 44, 28,241, 30,240, 68, 16,121, 93,206,184,161, 67, 43,196,187,119,215,187,239, 14, 29, 58,144,115,231,206,241, 6, + 37, 38,206,153,183,114,229, 87, 95,108,221,250,192,108, 50,249, 52,167,239, 12, 6,131, 65, 8, 65, 96, 96, 32, 42, 43, 43,161, + 84, 86,207, 84,139, 68, 34,184,186,186,194,104, 52,194, 66, 41,187, 62,206, 63, 11, 13,105,145,167, 21, 44, 0,168,233, 12, 0, +244,177,126, 65, 8,129,197, 98,177, 73, 92,177,217,236, 38, 99,170,154, 66,125, 55, 85, 91, 4,150,213, 86, 7, 7,135,218, 31, + 88, 93, 97,101,181,147,193, 96,128,201,100, 54,121,243, 6, 0,139,197,194, 84, 40, 20,216,179,103, 15,122,247,238, 93, 59,253, + 36,147,201, 32,149, 74, 33,147,201,160,213,106,145,159,159,143,147, 39, 79, 34, 60, 60, 28,128,109, 73, 91,243,242,242,174,132, +132,132,196, 91,111,222,125,251,246, 13,216,188,121,115,241,144, 33, 67,252, 40,165, 88,188,120,113,121,151, 46, 93, 60,234,222, +220,155, 2,147,201,196,249,243,231, 17, 30, 30, 14, 74, 41, 56, 28, 14,110,223,190, 13, 47, 47, 47, 88, 44, 22,176, 88, 44,148, +149,149,193,209,177,241,220,134,153,153,153, 47,188,248,226,139,197,206,206,206,109, 43, 42, 42, 74,120, 60, 94,207,180,180,180, + 64,131,193, 0, 39, 39, 39, 56, 57, 57,225,208,161, 67,112,113,113,193,155,111,190, 89,168,209,104,206, 11,133, 66,111,141, 70, +115,189,180,180,116,177,205, 6, 3, 48,153, 76, 80,169, 84,168,170,170, 66,101,101, 37,228,114, 57,180, 90,109,147, 54,214,135, +158, 61,123, 34, 37, 37,133,249,225,135, 31,126,159,151, 87,253, 32, 24, 26, 26,138, 55,223,124,147,233,239,239,143,252,252,124, + 92,185,114, 5, 6,131, 1, 77,185,159,217,108,118,223,121,243,230,245, 8, 10, 10, 34, 6,131, 1, 22,139, 5, 58,157, 14,214, +247,133,133,133,104,221,186, 53, 35, 56, 56,184, 43, 33,164,175, 45, 11, 38,236,168,134, 92,178, 19,174,156, 0,128,233, 6,139, +252, 43,168,126,103, 50, 18,137, 68,178,114,210, 12,230,180, 67, 59,148,222,183,239, 56, 34, 48,116, 10, 2, 90,142,196,244, 23, +205, 88,246, 65, 10,252, 3,163,113,255,254,125,244,237,219,151, 83, 92, 92,252, 34,128,249,182,114, 31, 63,126,193,124,236,208, +225,113,227,159,153, 26,223,191,255, 16,211,209,163,135,144,121,253,104,214,139,207,140,149, 80,139,146,184,184, 8,210,239,220, +185, 25, 17, 19,211, 1, 6,163,177, 39,176,108, 13,128, 6, 47, 42,119,239, 82,253,242,229,203, 25,191,236,255,113,202,164,201, +207,183, 75, 72, 24,104, 60,122,252, 32,174,252,118,252,218,167,107,166,159,249,112,221,206,190, 3, 6,141,109,227,224,116,225, + 80, 76, 27,205, 75,129, 78, 65,205, 74,125,242, 95, 2,203,193,193,130,154,235, 34,131, 16, 80, 74, 31, 17, 87,143, 11, 44, 6, +131,209,228,131,127, 93, 78, 43, 40,165,181, 15,210,223,126,251, 45,120, 60, 30,184, 92, 46,216,108,118,147, 97, 22,117, 57,179, +242,243,251,109,217,190,157, 87,159,184,170,168,168, 64, 69, 69, 5,148, 74, 37, 38, 78,156,200, 89,126,249,114,135, 6,232,106, + 57,131,124,125,117, 66, 62, 95,156,157,157,237, 23, 29, 29,253,136,189,114,185, 28,124, 62, 31,219,119,236,224, 12, 27, 58,244, +213,132, 67,135, 62, 5,208,104,254,170,250,250, 78, 8,129,151,151, 23, 92, 93, 93, 65, 8,129,201,100, 66,105,105, 41,178,178, +178,112,249,242,101, 48, 9,105,118, 90,162,230,160, 62, 45,242, 52,195,234,193,170,119, 20, 54, 71, 96, 49,153,204,223,237,197, +106, 8,182, 76, 17, 10, 4,130, 27,197,197,197,221,253,253,253, 97, 50,153,106, 5,214,227, 83,132, 64,181,183, 35, 35, 35, 3, + 2,129,160, 94,183,126, 93, 78, 74,105,215, 78,157, 58, 97,239,222,189, 72, 77, 77,197,189,123,247,160, 86,171,161,211,233,160, +209,104,144,149,149, 5,139,197,130,152,152, 24, 8,133,194, 38, 57, 1, 64,165, 82,149,176,217,236, 72, 62,159, 95,251,153,175, +175, 47, 42, 42, 42, 44, 70,163, 17, 91,182,108,145,251,248,248, 8,249,124,190,205,130,149, 16, 2,137, 68,130,128,128,128,218, + 24, 44,133, 66, 1, 47, 47, 47,171,160,128, 78,167,131,163,163, 99,147, 83,132,148, 82, 45,128,121,117,184, 59,142, 31, 63,254, +167,164,164,164,150, 39, 78,156,192,197,139, 23,225,233,233,137, 85,171, 86,221, 43, 40, 40,152, 68, 41,189,108,147,145,205,128, + 45, 99,168,162,162, 98,207,141, 27, 55,186,118,234,212,169,246,234,208,183,111, 95,210,183,111, 95, 15,235,255,106,181, 26,101, +101,101,184,116,233, 18, 78,156, 56, 1, 66, 8,114,115,115,205, 26,141,230,167, 70,246,205, 9, 14, 14,222,188,104,209, 34,145, +201,100,170, 29,219,124, 62, 31, 14, 14, 14,224,112, 56, 96, 50,153, 40, 40, 40,192,200,145, 35,157,191,252,242,203, 31, 9, 33, + 97,148,210,166, 7,234, 83, 2,165, 69,106,186,148,161,113,113,117, 13,190,126,254,204,143, 93,187,213, 92, 35,206,159,249,209, +228,234, 26,124,253, 82,134,198,165, 87,160,212, 36,106,130,103,255,225,178,249, 6,195,229, 65, 71, 14,223, 24, 61,111,238,116, +110,112,203, 80,241,185,139, 55,130,187,153,231, 49,132,124, 64,165, 1, 42,165,192,173,187, 76, 75,112,203, 80,241,229,171,183, +185,159,126,182, 41, 84,173,209,239, 59,116, 82,122,164, 49,110, 74,169,150, 16, 50,234,245,119,217,103,166,190,224,197,229, 58, + 4, 66, 81,117, 21, 45,130,221, 49, 97,108, 36,190,250,238, 42,156,156,220,224,237,237, 13, 6,131, 33,180,181,239,229,229,229, +100,207,207,191, 78,123,238,249,233, 93, 18, 7, 14, 53, 29, 57,250, 11, 43,245, 88,242,249, 31,191,123,119, 31,101,170, 4,132, + 42,248,129, 65, 1,215,243,239,229, 76,234,213,107, 32,248, 92, 65, 56, 16, 85,239,128,173, 93, 56, 64, 81,200, 96,192,225,185, +231, 95,238,150,152, 56,194,116,244,232,126, 28, 61,180,245,194,210,165, 45, 14,221,123,184,131,243,219,229, 34,135, 81,227, 94, +169, 74, 57,124, 83, 63,118,120, 72,142,159,176,253, 63, 34, 7,222, 63, 9, 76, 22, 75,108,210,233, 2, 3, 18, 19,153,234,251, +247,217, 34,111,111, 19, 0, 24,141,198, 38, 5, 22,128,122,167,154, 31,231,180,213, 22,181, 90, 13, 11, 80,175,200,120,156,179, + 84, 34,105, 81,243,240, 93, 11,163,209, 88, 43,174, 42, 42, 42, 32,149, 74, 33, 20, 10, 81,166,211,213, 59,149,249, 56,231,192, +206,157,183, 44, 95,182,108,254,238, 61,123, 56,192,255,196,149,245,197,102,179,241,209,154, 53,156, 55,222,122,235,149, 87, 89, +172,217,205, 57,158, 64,245,195, 58,147,201, 4,139,197,194,253,251,247, 81, 88, 88,136,251,247,239,227,254,253,251,224,243,249, +160, 13, 28,207, 63, 11,255,166,248, 43,160,137, 52, 13,205, 9,114,183, 85, 16,152,205, 13, 38, 62,126, 2,182, 8, 44,149, 74, +117,226,228,201,147,157, 71,141, 26,197,186,112,225, 2,124,124,124,106, 5,150,245,175,117,218, 73, 32, 16, 96,223,190,125, 6, +149, 74,213,104, 33, 73,181, 90,125,242,208,161, 67,241, 75,150, 44, 97,191,240,194, 11,200,206,206,198,140, 25, 51, 32,149, 74, + 33,151,203, 81, 81, 81, 1,181, 90,141,206,157, 59,195,193,193, 1,215,175, 95, 55,170,213,234, 70, 83, 21, 80, 74,169, 68, 34, + 81,122,122,122,250, 62,254,221,184,113,227,188,191,254,250,107,245,173, 91,183,140,221,187,119,119, 2,108, 19, 26, 86,252,252, +243,207,181,158,185,156,156, 28,124,253,245,215,181, 49, 87, 87,175, 94,197, 39,159,124, 82,155,187,172, 57,160,148, 94,110,211, +166,141,201,104, 52, 34, 60, 60, 28,254,254,254,208,106,181, 88,187,118,173,233,175, 16, 87,182, 66,171,213,238,158, 58,117,234, + 59,233,233,233,190, 44, 22,171,218,117, 93,211, 63,131,193,128, 59,119,238, 32, 43, 43, 11,183,110,221, 66,101,101,101,237, 3, + 64, 70, 70, 70,149,209,104,220,217, 16,175,167,167,231,226, 31,126,248,193, 71, 32, 16, 60, 50,158,173,222, 79,171, 87,180,172, +172, 12, 46, 46, 46, 72, 72, 72,240, 58,121,242,228, 98, 0, 54,231,110,250, 39,131, 16, 66,186,119, 17,245,120,253,149,231,209, +169,131,226,238,141,171,153, 56,126,104, 93,109,144,123,108,135,152,187,151,210, 29, 49,120,224,252, 30,231, 46,204,104, 52,200, +189, 38,134,234, 80,231,206,110,103,247, 39,159,248,106,193,220,233,151,222, 91,182,192, 75,171, 83, 57, 68,133,153, 25, 64,181, +184,250, 45, 93,168,125,127,217,244, 75,171, 63,219, 98, 41,148, 24,230, 92,188, 88,213,224,234,222,186,162,165, 77, 43, 56,248, + 4, 15, 45, 14,110,217, 55,228,250,213, 77,240,112,174,130, 99,120,119, 12, 78,236,140, 19, 39,111,224,254, 67, 45, 74, 74, 74, +160,211,233, 26, 77,123,112,235,250,190, 41,148,208, 32, 66, 73, 33, 97, 80,135, 41, 83, 95,234, 57,116,232, 8,154,146,146,108, +218,191,111,251,217,157,219,214,239,102,112,216, 44,141,222, 89, 79,136, 86,102, 97, 56,102,171, 84, 21, 0, 0, 22,135,211,176, +187,181, 38, 33,107,116,155, 40,159, 41, 83,103, 56, 15, 25, 60,146, 30, 58,180,223,178, 51,105, 75,234,206, 77,177,219, 45, 12, + 57,167,228,129,154, 39,147, 27,101,148,112, 93,148,114,139, 90,156, 23,166,245, 27, 58,238, 95, 35,214,255, 44, 24,116,186, 34, +229,131, 7,190,110,189,123,243,238, 44, 91, 38,240,238,220, 89, 75,106, 98,132, 27, 19, 88, 76, 38, 19, 96, 48,234,189,232, 61, +206,105,171, 45, 26,141, 6, 22,160,222,197, 71, 77,113,154, 76,166, 71,196,149, 85, 96,213,192, 38, 59,191, 91,186,244, 66, 80, + 98, 98,229,233,211,167,189,251,244,233, 67, 20, 10, 5, 20, 10,197, 35, 34,203,207,207,143, 68,199,196, 8,126, 78, 77, 13,173, +239,194, 84,223,241,180,165,239, 12, 6,227, 47, 23, 88,255, 54, 52, 26, 75, 97,245, 96,217, 34,176,108,244, 96, 25,141, 70, 35, +188,188,188, 80, 94, 94,222,224, 13,185,212,196,113, 0, 0, 32, 0, 73, 68, 65, 84,159,193, 96,128,207,231, 91,231,128, 27, 93, + 73,167,211,233,214,206,159, 63,127,214,224,193,131, 61, 34, 35, 35, 81, 86, 86, 6,111,111,111, 56, 56, 56,212,198,134, 89,249, +174, 94,189,138, 31,126,248, 65,174,211,233,214, 54,193,249,249,154, 53,107, 94, 27, 51,102,140,155,143,143, 15, 92, 93, 93,113, +253,250,117,184,186,186, 66, 46,151,227,246,237,219,112,116,116,172,141,203, 73, 78, 78, 86,232,116,186, 70,227,122,212,106, 53, + 77, 75, 75, 51, 56, 58, 58, 94, 47, 43, 43, 99, 86, 86, 86,178,170,170,170, 88,114,185,156, 45,147,201,216, 71,142, 28,241,112, +118,118, 86,159, 58,117,170, 44, 40, 40,136,121,239,222, 61,166,209,104,108, 82,181, 18, 66, 48,123,246,108,112, 56, 28,232,116, + 58,172, 93,187, 22,243,231,207,175,141,185, 90,179,102, 13, 22, 45, 90, 84, 43,152, 55,110,220,216, 20,229, 35,160,148,194, 96, + 48,192,104, 52,194,104, 52,218, 36,122,255, 8,108, 17,234,148,210, 82, 66,200,176, 78,157, 58, 29,219,181,107,151,123, 77, 78, + 49,136,197, 98,136,197, 98,148,149,149, 65,169, 84,194,100, 50,193,223,223, 31, 98,177, 24,251,247,239,151, 41, 20,138,196,198, + 86, 16, 50,153,204,169, 61,123,246,100, 61,110,131,245,169,206, 42,218,121, 60, 30,138,139,139,209,183,111, 95,238,233,211,167, +167,226, 41, 23, 88, 86,225,210, 58, 2,156,225, 35, 38,114,218,199, 15, 82, 95,186,114,228, 62,159,152,238, 15,233, 31,190, 11, +168, 78,211,112, 41,221, 17,237,227, 7, 49,134,151,232, 59, 75,171,190,107, 31,221,138, 24, 26, 43,171, 3, 0, 30,206,150,145, +137,253, 91,148, 56, 57, 17,214,251,203, 86, 31,252,126,235,198, 78,191,253,252,191, 52, 13,239, 47,171, 78,211,144,216,191,133, + 41,251, 86,206, 72, 0, 13,167,105,120, 76,180, 12, 27, 54, 60,253,187, 77,219, 80,148,151,236,247,213,106, 23, 46,180, 85, 0, + 59, 18, 61,187, 56,225,226, 23,133,184,118,237, 90,169, 94,175,239,219, 88,223, 41,161, 65, 89,217,153,173, 98,219, 68,251, 76, +153,250,178,211,176, 97, 35,145,146,114, 0,219,182,108, 74, 27, 59,113,204,247, 15,171,228, 76, 47,182,128, 35,160, 22, 46,147, +227,204,114, 16, 8, 36,134,226, 98, 0, 0,139,197,118, 2,198, 91, 26,153, 33,196,204,151, 39, 59,247,235, 63, 18,191, 28, 58, +128,109, 91,190, 59,243, 94,155,113,155, 66,226, 90,147,206, 29, 62,126, 37,164,101, 72,176, 74, 41,150, 51, 8,215,160,213, 90, + 28, 63,222, 82,240, 89,222,162,169,121,233,153,227, 63,181,175, 34,124, 4,215,183, 13, 25,210,233,141,187,119, 57,158, 61,122, +240,139, 83, 83, 5,164,186,114, 72,163, 2,139,197, 98,129, 54, 60,165,245, 8, 39,217,186,149, 1,160,209,197, 85, 28, 14, 7, +106,181, 26, 70,160,161,139,224, 35,156,190, 71,143, 62,184,123,247,110,132,155,155,219, 35,226,170,178,178,178,246,189, 86,171, +133, 90,173, 6,159,207,207,178,133, 83,156,150,166, 93, 61,123,246,146, 73, 19, 39,174, 63,113,242,164,131,187,187, 59,100, 50, +217, 35, 2, 75,175,215,163, 95, 66, 2,103, 77,122,250, 20, 0, 75,109, 57,158,222,125,251, 54, 25,239,203,100, 50, 97,249,139, +167, 8,255,109,104,240,110,102, 21, 75,182,174, 34,172,239,198, 72, 8,233,255,216, 71,139,226,227,227,181, 57, 57, 57, 8, 10, + 10,170, 21, 41,117,247,233,228,228, 4, 23, 23, 23, 92,189,122, 21, 43, 87,174,212, 0, 88,212, 24, 39,165, 84,161, 86,171,159, + 25, 48, 96,128,134,197, 98, 33, 42, 42,170, 54,255,149,197, 98, 1,151,203,133, 80, 40, 68,122,122, 58,134, 15, 31,174, 86,171, +213,207, 60,158, 3,171, 30, 78,153, 90,173,126,118,224,192,129,234,236,236,108,244,236,217, 19,215,174, 93,131, 82,169,132, 82, +169, 68,126,126, 62,162,163,163,161, 86,171,241,245,215, 95,107,212,106,245,179,148, 82, 89, 99,156, 10,133, 98,248,252,249,243, +153, 63,253,244, 83,136,191,191,127,155,142, 29, 59, 70, 38, 36, 36,132,141, 30, 61, 58,120,200,144, 33,190, 17, 17, 17,218,196, +196, 68,207,193,131, 7,123,170,213,106,246,185,115,231, 74,140, 70,227,224, 38,142, 39,128,106, 81,146,147,147, 83, 59, 37,200, + 98,177, 80, 94, 94, 94,155,105,223,122, 49,170, 79, 0, 55,196,105,133,197, 98,169, 21, 86, 86,161,213,212,181,191, 1,206, 38, +111, 24, 92, 46,215,234,225,124,162,109, 61,231, 40,227,230,205,155, 3,122,247,238,157, 49,109,218, 52, 69,105,105, 41, 28, 29, + 29, 17, 26, 26,138, 86,173, 90,193,195,195, 3, 6,131, 1,251,246,237, 83,237,223,191,255,134, 76, 38,235,251,120, 14,172,199, + 57, 25, 12, 70,126,125, 23, 87,171,247,202, 42,176, 28, 28, 28,224,239,239,111, 61,182,249, 54,244,253, 15,225, 47,231,172, 17, + 46, 9,253, 18, 91, 14, 25, 58,202,121,127,242, 1,193, 23,223,108,190,217,107,228,172, 13, 30,193,243,246,122, 4,207,219,219, +107,228,172, 13, 95,124,179,249,230,254,228, 3,130, 33, 67, 71, 57, 39,244, 75,108,153,157,117, 43,242,145,186,132,245,216, 41, +224,242, 58,247,234, 30, 33, 77, 59,151,102, 90,253,217, 22,115,247,110, 67, 46,174, 95,191, 97,231,250,245, 27,118,118,239, 54, +228,226,234,207,182,152,211,206,165,153,122,117,143,144, 10,184,188,206,182,244,125,230,203,147,157,135, 14, 25,137,148,148,125, +166,221, 63,127,189,102,227,182,226,222,125, 71, 23,137,243,243, 46, 83,168, 55,195,195,241, 58,110,222,188, 41,211,235,245,125, +235, 11,112,175,143,115,198,244,201,117,197,213,175,238, 62, 61, 55,222,188, 9,243,241,227, 7,141, 39, 79,166,107,126,205,144, +200,174,100,151, 87, 86,200,181,247, 84, 10,185,222, 98,177,128, 90,204,204,229,203,171, 3,113, 27, 58, 71,221,187,247,193,169, + 19, 59,176,101,243,183, 50,139, 5,218,113,187,118,153,199,143, 95, 70,131, 91,180, 8,222,254,243, 14, 50,108,196, 40,103, 10, + 88,134,143, 25,233,242, 83,210, 79,164,101,120,203, 22,161,161,213,169,105,158,202,177,244, 23,112, 46,165,180, 74,126,255,254, +153,171, 95,126,169,243,126,230, 25, 55,174,183,183, 19,204,102, 98,189,190, 55,244, 98,177, 88,143,120, 92, 26,227,244,247,240, +120,152,156,156,140, 86,173, 90,193,223,223, 31,117, 99, 96,173,137,180,221,221,221,177,103,207, 30, 80,224,138, 45,156,113, 33, + 33, 87, 63, 90,189, 90,111,177, 88, 80, 85, 85,245,132,247,170,170,170, 10, 22,139, 5,135,126,249, 69, 47, 87, 42,183,216,218, +247,190, 76,166,114, 82,175, 94, 31, 14, 29, 58,212,112,247,238, 93, 88, 44, 22,212,245,100, 73, 36, 18,136, 68, 34,104,117,186, + 64, 66,136,192, 22, 78,201,145, 35,194, 6,214,106,212,226,113, 15,214, 95,113,222,255,109,104,212,131,101, 50,153, 16, 24, 24, +248, 72,233, 21, 6,131,241,200,171, 57, 43, 8, 41,165, 91, 9, 33, 71, 19, 19, 19,151,116,233,210,101,230,146, 37, 75,152,145, +145,145,144,201,100,112,117,117,133,151,151, 23,110,223,190,141,228,228,100,115,121,121,249, 6, 0, 43,108, 89, 10, 79, 41, 77, + 37,132, 12,107,219,182,109,210,130, 5, 11,156, 7, 14, 28,200, 14, 12, 12, 4,165, 20,233,233,233,216,187,119,175, 97,211,166, + 77,242, 26,113,101, 83, 80, 50,165,244, 24, 33,100,236,224,193,131,183, 79,157, 58,213,209,108, 54,179,243,243,243,161,211,233, + 96, 52, 26, 81, 88, 88,104, 72, 73, 73, 81,170,213,234,201,148,210, 99, 54,240, 93, 37,132, 68, 31, 63,126,124,234,185,115,231, + 86, 78,155, 54,205, 61, 33, 33,129, 99, 50,153,112,246,236,217,178,184,184, 56, 47,137, 68, 98,216,179,103, 79,133, 86,171, 93, +100, 54,155,109, 42,149, 67, 8,129, 92, 46,135,135,135, 7,116, 58, 29, 44, 22, 11,244,122, 61, 68, 34, 81,109,121, 35, 74, 41, +154, 19, 52, 95, 23, 38,147,137,105, 48, 24, 48,113,226, 68, 88, 44, 22,172, 93,187, 22, 38,147,169,217,100,206,206,206, 87, 50, + 50, 50,134,181,111, 95,157,160,157,201,100,214,142, 33, 30,143, 7, 15, 15, 15,184,187,187, 35, 37, 37, 5,108, 54,187,209,172, +248, 86,212,100,102,143, 35,132,116,187,113,227,198,115, 0,218, 27, 12, 6,127,179,217, 76, 24, 12, 70, 9,165,244,186, 92, 46, +255,222,214, 82, 57, 18,137,100,229,243,207, 63, 31,183, 99,199, 14, 17,139,245,191,159, 6,139,197, 2,143,199,131, 53,169, 37, +165, 20,122,189, 30,139, 23, 47,150,171, 84, 42,155,114, 55, 61, 13,136,239,216, 25,223,125,189, 78,116,242,212,209,178,155,185, + 56, 80, 55, 21,131, 8,192,185, 11, 51, 14, 72,171,190,107, 95,252,224,129, 40,190,227, 19, 90,168, 94,232,205,166,138,103, 38, +111, 8,172, 41,149,179, 50,255,222,253,207,119,108,126, 41, 15, 0, 62,253,108, 83,104,161,196, 48, 39,251, 86,206,200,111, 54, +156,238,172, 55,155, 42,108,225,252,159,104,217, 46, 3,133,150, 82,122,145, 16, 18, 18,217, 77,187, 40, 38,138, 51,162, 88,108, +124,168, 84,234, 95,167,148,214,187,244,189, 62,244,232,222, 27,167,142,253,132,109, 91,182,203,169,133,169,245,240,240,160, 0, +112,243,166, 7,189,121, 83, 74,255, 23, 47,236,162,242, 20,148,173, 88,180,112,230, 92,133, 66,241,249, 87, 31, 55,158,112,182, +109,187, 46,104,219,174, 11,102,189,254,174,115,116,155,168, 32, 0,216,181,139,154, 99, 34,200,193, 37,239, 45, 27,177, 98,197, + 50,200, 21, 58, 88,203,234,220,206,204,254,229,238, 93,106,219,234,158,255, 16,150,152, 76, 23, 49,119,110,132,186,178,210,179, +199, 59,239,120,176,222,122,139,209, 88,144,123,221,223,175, 45,156,151,175, 95,255,101,198, 75, 47, 61, 92,186,100, 73,226,134, +111,191,229,199,198,198,162,180,180, 20, 81, 81, 81,240,247,247,199,241,227,199,177,103,231, 78,149, 84,161, 88, 4,224, 27, 91, + 56,183, 30, 58,116, 59,178, 77,155,242,111,191,253,214,111,232,208,161, 68,165, 82, 65, 38,147, 65, 38,147, 65,167,211,161, 38, +145, 51,205,201,205,189,105, 52, 26, 55,216,194,217,227,157,119, 60,204,101,101, 14, 43, 58,119, 46,226, 88, 44, 31,141, 29, 51, +102,254,138,247,223,231,181,108,217,146,232,116,186, 90, 47,150,193, 96,128, 72, 36, 50,232,245,122,119, 0, 79,120,167,234,227, +228,109,218,100, 42, 43, 43,131,167,167,103,109,218,165,186,121, 5, 21, 10, 5, 40,181, 39,193,109, 14, 72, 67,247,112, 55, 55, +183, 43, 44, 22, 43, 0,104,188,182, 93,221,207,140, 70, 99, 81, 89, 89, 89,124,157, 54,253, 41,165,245,198, 59, 17, 66, 66, 1, +172,234,215,175,223,216,121,243,230,145,211,167, 79, 99,255,254,253, 52, 47, 47,111, 55,128, 69, 13, 93, 28,155,224,116,228,241, +120,111, 10,133,194,254,214, 84, 12, 2,129,224,134, 74,165, 58,161,211,233,214, 54,148,189,189, 9, 78, 39, 30,143, 55, 91, 40, + 20, 14, 80, 40, 20,237, 1,192,209,209, 49, 67,165, 82, 29,215,233,116,235,104, 3, 5,164,155,224,228, 59, 59, 59,175,244,240, +240,120,246,173,183,222,114, 79, 75, 75, 43, 57,117,234, 20, 71, 42,149,238,208,235,245, 13, 22,123,174,143,211,221,221,253, 10, +147,201, 12,248, 43,206, 17, 0,180,107,215, 46,101,248,240,225, 67, 39, 79,158, 12,163,209,136,111,190,249, 6,199,143, 31,255, + 37, 55, 55,119, 88, 67,219,212,199, 73, 8,241, 8, 8, 8, 56, 61,115,230,204,224,137, 19, 39, 10, 92, 93, 93,193, 98,177,160, + 82,169,112,231,206, 29,164,167,167,211, 3, 7, 14, 40,175, 94,189, 90,164, 86,171,251, 80, 74,203,155,226,252,163,168,143,147, +205,102,247, 14, 12, 12,252,121,233,210,165,142, 3, 6, 12,224,187,187,187,131,201,100,194,104, 52,162,164,164, 4,153,153,153, + 56,122,244,168,106,247,238,221,170,138,138,138,137,143,231,106,249,255,178,243,207,228,140,110, 69,222,123,172,128,115,131,217, +217, 27,107,107,139,157, 67,251,187, 14, 25, 59,182, 99,127, 0,216,179,231,242,137, 95, 78, 84, 53, 90,236,185, 49, 59,155,178, +213, 22,206,214, 17,204,165, 89,217,153,143, 36,162,108, 19, 29,147,211, 58,118,204, 7,182,112, 89, 51,185, 63,222,247, 58,217, +241,255,135,199,166, 83,173, 5,161,223, 93,180, 16,171, 86,126,136, 3,187,246,253,146,125,151,214,150,243,121, 26,199,210, 95, +201, 73, 72,117,113, 98,129,175,111,175,181, 22,203,194,107,153,153,162,186, 15,106, 86, 79,115,221,135, 73, 63, 63, 63, 73,113, +113,177,183, 45,156,195,190,248,194,160, 22, 10,121, 11, 63,250,168,183, 82,171,237,189, 98,197, 10,214,229,203,151,241,245,151, + 95,154,180, 69, 69,219,203,128,217,245,205,126, 52,198, 25, 60,123,182,195,219, 95,127,253, 66,104,120,184,215,115,207, 61,199, +102,179,217, 80,169, 84,120,240,224, 1,142, 29, 61,170,207,190,121, 51, 91, 46,151,143,160,148, 22,219,202, 57,236,139, 47, 12, + 46,161,161, 16,120,122,210,147,169,169,206, 51,222,124,115,102,139,144, 16,231,196, 65,131,216, 78, 78, 78,168,170,170, 66,126, +126, 62,246,237,219, 39, 81, 42,149,126,148, 82,179, 45,156,219,207,157,107,123,232,204,153,113, 31,124,240, 1, 55, 38, 38, 6, +206,206,206, 80, 40, 20,200,204,204,196,153, 51,103,116, 27, 54,108,144,201,100,178,153, 38,147, 41,185, 33, 59,237,120, 20, 13, + 10,172, 63,133,220,134, 19, 64, 8,137, 7,240, 94,205,191,239,211,166,107,250, 61,181, 23,136,122,218, 4,185,185,185,125,167, +213,106,169, 70,163,153, 65, 41, 45,252,167,217, 73, 8, 97,197,199,199,127, 45,145, 72,186, 81, 74,225,236,236,124, 62, 43, 43, +235, 85, 74,105,131,115,241, 13,113, 18, 66,152, 0,186,137, 68,162,206,142,142,142,189,117, 58, 93,235,154,105,182,155, 42,149, +234,140,193, 96,184, 8,224, 60,165,244,137,149, 16,255,159,125,175,177,115,128,159,159,223, 75, 22,139, 37,156, 16,226, 98, 54, +155, 97, 52, 26,165, 22,139,229,142, 76, 38,219, 4,224,248,223,109,231,159,197,217, 38,156,140,166, 12,180,174,253,178,145,184, +170,199,133, 3,177,224,102,214, 29,186,207, 86, 59, 9, 33,140, 81,131, 61, 63, 1,170, 87, 26,210, 38, 74, 14, 61, 34,176,108, + 16, 45,182,224, 17,206,112,214,243,148,208, 71, 56, 9, 37,133, 81,109, 71,111,179,133,171, 33,129,101, 43,218, 68,146,222,160, +232,102,161,184,120, 51,151,158,106,200,206, 63, 11,255, 6,206, 15, 9,113,251,210,213,245, 60,131,197,242, 1,192,168,241,182, + 88, 44,132,152, 41, 33,166,186,211, 88,117, 31, 40,155,226, 52, 0,177,108, 30, 47,208,108, 50,121,151, 2,162, 67,102,115, 7, + 45,165,202, 0,224,189,116, 74,111,255, 30, 59, 13, 64, 44,147,199, 11, 58, 68,233,200, 50,161,176,173, 68,163,241, 4, 64, 69, + 66,225, 77,185, 74,181, 69,171,213,126,245,248, 76,133, 45,156, 28, 30, 47,192,108, 50,121, 3, 0,131,197,146, 36,233,116,129, + 69, 78, 78,207,105,117,186, 96,145, 72,100,212,235,245,114,173, 86, 59,217,104, 52,158,108, 78,223,239,152, 76,209,231, 24,140, +158, 6,161,208,221, 64,136, 80,111, 50, 25,244, 6,195, 3,173, 86,123, 3,192,103,148,210,218, 52, 34,118,129,101, 3,172,171, +205,254,138, 23,128,254,118, 78, 59,167,157,211,206,105,231,180,115,218, 57,255,122, 78, 0, 2, 0, 65, 0,152,255,100, 59,255, + 43,175,166, 39,170,237,176,195, 14, 59,236,176,195,142,127, 60, 40,165,106,212, 19,115,101,199,223, 3, 2,160,222,149, 0,180, + 25,174,191,223,179,154,160, 41,126, 59,167,157,211,206,105,231,180,115,218, 57,237,156,255, 62,206,166,184,155,163, 63,254,209, +248, 43,221, 99,120, 74,220,146,118, 78, 59,167,157,211,206,105,231,180,115,218, 57,255, 94,206,127,219,235,143, 21, 16,252, 23, +131, 16,226, 77, 8,169,183,124,193, 31,105,107,199,211,135, 63,114,126, 9, 33,254,132, 16,255,102,182,127, 34,219,191, 29,118, +216, 97,135, 29, 79, 23,254,223, 5,150,173, 55,171, 63,120, 83,251, 67,130,135, 16,242, 33, 33, 40,174,126,145, 15,255,172,182, + 54,236,215,207,211,211,243,141, 54,109,218,108,247,241,241,153, 69, 8,241,106,230,246, 17, 66,161,112,157, 72, 36, 58, 45, 18, +137, 78, 11,133,194,117,132,144,136, 63, 98, 83, 29,110, 66, 8,153,225,224,224,144,234,231,231,247,144,199,227,165, 18, 66,102, + 18,210,140,154, 62,143,242,133, 17, 66,230, 18, 66,230, 17, 66, 34,155,222,226,127,240,142, 25,181,211, 43,102,212,117,175,152, + 81,153, 30,177, 35, 34,188, 98, 70,101,122,197,140,186,238, 29, 51,170,193, 50, 56,191, 23,127,228,252,214,108, 91, 88,253,106, +122, 91, 66,200,103, 4,120, 64, 8,138,254,232, 88,178,195, 14, 59,236,176,227,239, 69,179,130,220, 3, 2, 2, 6, 91, 44,150, + 73, 0,192, 96, 48,126, 42, 42, 42, 58,220,156,237,107,110, 56,111,215,188, 95, 67, 41, 93,248, 71,218,217,176,237,231,148,210, +249,205,180,209,155, 16,188,109,177, 80, 6, 0, 48, 24,228, 29,111,111,111, 1,147,201,124, 34,112,208,108, 54, 11, 8,193, 44, +139,165,186, 64, 37,131, 65,222, 38,132,172,163,148,138,155,179, 79,235,126,167, 76,153,242,249,186,117,235, 28, 4, 2, 1,238, +223,191, 63,112,230,204,153,221, 9, 33,115, 41,165, 37, 77,109,207,231,243, 39,117,234,220,109,238, 71, 31,127, 42,242,246,242, + 18,154,204, 22, 67,126, 65,129,112,241,194,249,157,249,124,254,186,198,138, 28, 63,102, 7, 1,240, 50,139,197,154,224,224,224, + 16,166,213,106,239,154, 76,166,221, 76, 38, 51,113,229,202,149, 49, 67,134, 12,113,144,203,229, 92,147,201, 20,190,109,219,182, +185, 63,252,240,195, 96, 66,200, 72,218,200,114,123,171, 7,135, 82,250,176,206,199,131, 11, 11, 11, 99,217,108, 54,194,194,194, + 8,128,219, 77,180,175, 5, 5, 34,178,206,238,138, 5,128, 54, 61,198,231,100,157,221,133,154,247,182,116,209,102,212, 55, 22, +248,124,254, 55, 26,141,230,129,245,251, 26, 59,159, 56,223,245,109, 75, 8, 89, 79,171,203,252,196, 0, 24, 83,211,116, 47,165, + 52,147, 16,226,227,192,227,189,169,209,106, 9, 0,242, 71,198,146, 29,118,216, 97,135, 29,127, 63,154, 37,176, 40,165,207,221, +185,115, 71, 96,177, 88, 16, 25, 25, 57, 5,128,205, 2,171,190, 27, 78, 66, 66, 66, 28,159,207,127, 36,107,177, 70,163,225, 18, +130,132,223, 35, 90,172,251,208,235,117, 12, 54,155, 11, 6,131,204,109,219,182,109,139,242,242,242, 52, 6,131,177,189,168,168, +168,170, 57,253,173,225,196,198,141, 27, 91,249,250,250, 62,145, 93,185,164,164,132, 59,114,228,136,102,241,189, 64, 8, 79,199, +227,117,230, 16,226,107, 54,153, 92, 0,128,197, 98, 85, 69, 58, 59,199,175,250,224, 3, 1, 33,196, 82, 81, 81, 1,141, 70,131, + 57,115,230,240,179,179,179, 71, 1,248,170, 9, 27, 91,117,233,218,125,206,209,163, 71, 90,203, 43,171,180, 27, 63,255, 46, 93, +195, 98,171, 90, 70,183,230,126,253,221, 22,151,151, 95,152,252, 58, 33, 36,131,214, 83, 54,228, 49, 30, 6,128,125,111,190,249, +102,155, 97,195,134,113, 21, 10,133,131, 70,163,105,177,125,251,246,197,241,241,241,162,246,237,219,115,127,254,249,103, 34,147, +201, 64, 41, 21, 68, 69, 69,209, 9, 19, 38,104,147,146,146,102, 1, 88,223, 0,231, 35,130,215,215,215,119, 9, 0, 48, 24,140, +186, 99,143,237,231,231,199, 7,128,146,146,146, 21,132, 96, 78, 77,251,122,197, 53, 1,114,219,244, 24, 15, 16,132,103,157,221, +229,208,166,231,120, 45, 40,238, 16, 32, 23, 0,252,253,253, 87, 0,117,242, 58, 61,138,155, 15, 31, 62,252, 93,181, 3,135, 13, + 27, 14, 74,233, 55,254,254,254, 41, 98,177, 56,134, 16,204,104,204,206, 71,108, 38, 4,238,238,238, 99, 1,124, 1,224,153, 91, +183,110,181, 1,128,168,168, 40, 54,128, 76, 23, 23,151, 14,186,106,113,101,135, 29,118,216, 97,199,191, 0,205, 21, 88, 28, 0, + 72, 75, 75, 3,165,148,251, 59,246, 87,123, 3, 33, 53, 69,138,125,125, 31, 13, 55, 41, 41, 41,193,233,211, 54, 85,179,177,105, + 31,239,191,255,190, 72, 42,149,246,255,254,251,239,123,249,251,251,127,242,240,225,195, 11,141,109, 76, 41, 21, 19, 66,214,212, +120, 28,192,227, 57,228,204,156, 57, 51,189,230,235, 22, 7, 15, 30, 20, 12, 31, 62, 92, 13,160, 0, 0,120, 60, 7,127, 38,147, +209,170, 58,168, 13,107, 26, 19,130,227, 9, 9,229,114,185,253,102,124,241,133,169,195,240,225, 44,161,167, 39, 1,128,130, 91, +183,220,215,124,252,113,247,170,188, 60,174,198,221,189,162, 66,165,210,228,228,228,128,199,227, 17, 38,147,217,161,169, 14, 11, +133,194, 55, 62, 88,181, 70, 40,175,148,106,116,114,165,158,105, 54,234, 28,249,124,115,105,169,184, 92, 36, 16,168, 23,190,183, +156,243,202,244,231,222, 0,240,106, 19, 84,179,230,206,157,219,186, 83,167, 78,254, 59,119,238, 36, 50,153, 12, 44, 22, 75,212, +190,125,123,196,199,199,155, 79,157, 58, 69, 66, 66, 66, 16, 19, 19,131,179,103,207,226,252,249,243, 36, 46, 46, 78,176,119,239, +222, 41,168, 71, 96,213, 35,170,231,118,237,218, 53, 80, 36, 18,105,229,114, 57,166, 77,155, 6, 0, 24, 48, 96, 64, 43,161, 80, +248,141, 82,169,116, 72, 78, 62, 48,182, 41,113, 45,206,220, 63, 1, 0,188, 98, 70, 93, 7, 16, 11,138, 59,146,204,253,109,235, + 52,105,125,251,246,237, 46, 85, 85, 85,181,193,134,214,194,226,189,122,245,106,234,112,214,194, 58, 22, 70,140, 24,254, 14, 64, +208,167, 79, 31,241,236,217,179,105,102,102,230,232,241,227,199, 37,228,230,222,105,208,206,199,199,209,164, 73,207,222,115,115, +115, 27,224,231,231,151, 11,128,197,102,179,173, 77,153,254,254,254,110, 49, 49, 49, 19, 69, 34, 81, 62,147,193, 8,161,160,180, +169,177,100,135, 29,118,216, 97,199, 63, 27, 44, 0, 32,132,212,102,146,165,148, 54,248, 20, 77, 8, 41,207,200,200,240,213,106, +181, 32,132,148, 55,212,174, 14,215,137, 58,239,197, 76, 38,243,107, 6,131,188, 74, 8, 65, 76, 76,236,189,181,107,215,214, 87, +115, 75, 31, 19, 19,123,143,201,100,180,164,148,130, 16,198, 55, 22,139, 89, 92, 31,103, 61,251, 19, 19, 66,214,112,185,188,183, + 1,192,199,199, 55,239,240,225,195,250,113,227,198,225,227,143, 63,230, 44, 88,176, 96,126,112,112,240,172,251,247,239,151, 54, +100,103,205,255, 11,189,189,189, 5, 27, 55,110,108, 53,115,230,204,244,226,226,226,133, 0,224,231,231,247, 33,128,104, 0, 5, +117, 62,195,134, 13, 73, 15,167, 79,159,158, 35, 22,139, 23, 54,196, 57,150,144,176,224,168,168,126, 43,210,210, 40, 67,167, 35, +229,191,254, 42, 47, 19,139,141,119,203,202, 4,155,175, 92, 25,182,248,195, 15,217,129, 65, 65, 56,157,156,236, 81,174, 86,151, +201,116, 58,173, 88, 44,166, 38,147,233,124, 67,156,117,208,198,203,211, 83,240,237,103,223, 92,118,100, 51, 45,222,254,254,132, +229,230,194,102, 8,156,185, 12, 22, 75,219, 50, 56,156, 3,160, 77, 3,199,172,150,147,195,225, 76, 25, 56,112,160, 32, 41, 41, +137,196,196,196,192,197,197, 5,191,254,250, 43, 50, 50, 50, 96, 52, 26, 25, 85, 85, 85,232,216,177, 35, 62,250,232, 35, 4, 5, + 5, 65, 42,149,162,176,176,208,131,203,229,122, 54,114, 60, 31, 17,188,243,231,207, 71, 96, 96, 32, 76, 38, 19, 42, 43, 43, 97, + 50,153, 32, 20, 10, 1, 0, 5, 5, 5, 56,120, 48,185,222, 14, 54,118,222, 27,104,143,174, 93,187, 42, 8, 33, 55, 31,251,234, +102,157, 54, 77,114,250,250,250,110,145, 72,202,226,250,246,237, 11,153, 76,166, 95,186,116, 41,218,182,109,139, 86,173,234, 15, + 27,123,108,204, 47,228,241,120,155,130,130,130,222,123,235,173,183,220,220,220,220,160,211,233, 94, 47, 41, 41,193,204,153, 51, + 1, 0, 67,135, 14,141, 98,177, 88,155,167, 77,155,134, 22, 45, 90,220, 82, 40, 20,183, 51, 50, 50, 22, 40,149,202,236,223,219, +119, 91, 96,231,180,115,218, 57,237,156,255, 52, 78, 91,181,200,211, 2, 22, 80,221, 17, 66, 8,109,170, 67,148,210, 42,127,127, +127, 95, 62,159, 15, 74,105,179,167,219,204,102,243, 44, 15, 15, 15,201,194,133, 11,123,180,106,213, 74, 63,107,214,172,204,252, +252,252, 69,117,219,132,132,132,172,252,242,203, 47,145,147,147, 83,240,225,135, 31,158, 45, 47, 47,111, 86,157, 49, 74,233, 2, + 66,200, 90, 0, 40, 41, 41, 41, 79, 78, 78,110,155,150,150,246,234,231,159,127,238,249,218,107,175,113,222,120,227,141,201, 0, + 62,110,138,135,201,100,170,235,155, 22,172, 15,190,190,190,250,250, 98,180,172, 24, 78, 8,223,137,203,237,187, 34, 45,141,234, + 11, 10,212, 63,124,250,169,227,183,151, 46, 45, 53, 82,234,237,229,229,133,158,221,187, 43, 29,152,204,114, 73,105,169,197, 43, + 44,140,153,127,248,176,135,134,203, 45, 78, 74, 74,146, 85, 84, 84,236,111,106,255,132, 16,185,217, 98, 49, 56,250, 7,154,198, +141, 30,216,230,242,197,140, 91,142,158, 30,140,248,184,152,216,236,156,130,171,212,108, 54, 18, 66,234,173,153, 88, 23,206,206, +206,173, 42, 42, 42, 32,151,203,225,233,233,137,181,107,215,194,199,199, 7,106,181, 26,191,253,246, 27, 13, 8, 8, 32,105,105, +105, 8, 8, 8, 64, 89, 89, 25,244,122, 61, 20, 10,133, 68,167,211,213, 91, 59,145, 82, 42,102,177, 88,155, 24, 12,242, 18, 0, +180,104, 17,114,243,155,111,190,209, 2, 64,235,214,173, 49,122,244,104,236,217,179, 7,217,217,217,176, 88, 44,160,148,106, 3, + 2, 2,111, 50, 24,164,117,245,230,191,223,139, 99, 45,193,243,240,225,195, 49, 77,183,126, 18,132, 16,226,227,227, 51, 58, 42, + 42,106,242,164, 73,147,244,108, 54, 27,106,181, 26,106,181, 26, 55,111,222,212, 15, 28, 56, 80, 60, 98,196,112,239,148,148,148, + 70,237,212,233,116,247,252,252,252,230,207,157, 59,119,237,134, 13, 27,156, 22, 47, 94, 12,179,217, 12,139,197, 82,251,215,250, +126,255,254,253,200,203,203, 91, 87, 87, 92,217, 97,135, 29,118,252, 87, 96,171, 22,121, 90,240,255,158,201,157,201,100,126,123, +236,216,177,246,189,122,245, 98, 37, 36, 36,196, 4, 4, 4,196, 20, 21, 21,101, 2, 64, 64, 64, 64,204,160, 65,131, 98,188,188, +188,176,110,221, 58, 53,147,201,252,246,247,236,227,177,155, 93,186,175,175,239, 39,123,247,238, 93, 51, 99,198, 12,248,248,248, + 68,255, 41, 29,105, 6,156,120,188,184,105,107,215,154,216, 70, 35,227,139, 79, 62,113,250, 52, 53,117,205,206, 93,187, 88, 93, +187,118, 37,148, 82,220,184,126,157,255,209,250,245,130,137,163, 70, 21,220,206,203, 51, 29, 56,122,212, 40,126,248,176,242, 97, + 89,217, 18, 74,105,101, 83,252, 70,163,241,183,220, 59,185,254, 61,250,118,243,251,245, 82, 86,198,152, 81, 67,250,177, 89, 12, +114,167,224,225, 21, 95, 31, 15,231,211,169,199,181, 70,163,241,183,166,120, 84, 42, 85,190,201,100,114,163,148,122,158, 62,125, + 26,158,158,158,168,170,170,130,209,104,132, 94,175,215,171,213,106,135,138,138, 10,104,181, 90,232,116, 58, 56, 57, 57,225,198, +141, 27, 98,147,201,116,170, 33, 78,147,201,244,178,131,131,195, 42, 74, 41, 91,167,211, 21,159, 56,113, 2, 28, 14, 39,208,217, +217,121,161,209,104, 68,113,113, 49,206,157, 59,247,161,193, 96,120, 96,221,134,203,229,121,234,116, 58, 83, 67, 65,238,182,128, +210,223, 95, 99, 51, 32, 32,192, 47, 36, 36,100,238,130, 5,111,135,183,109,219, 30,229,229,229,176, 88, 44, 16,137, 68, 80,171, +213,112,114,114, 66,183,110,221,210, 87,174, 92, 89, 73, 41, 22, 52, 37, 2,139,139,139, 43,130,130,130,150,204,156, 57,115,110, +120,120,120, 16, 0, 68, 68, 68, 96,224,192,129, 56,124,248, 48,114,114,114,160, 84, 42,205,151, 47, 95, 62, 88, 92, 92,252,239, + 72,176,103,135, 29,118,216,241, 31,199,255,187,192, 18,139,197,101, 1, 1, 1, 71,174, 94,189, 58,108,194,132, 9, 56,125,250, +244,243, 0,230, 2, 0,143,199,123,126,194,132, 9,184,122,245, 42,110,221,186,117, 68, 44, 22,151,253, 25,251,228,114,185, 90, +189,190,218, 25,229,224,224,224,208,204,205, 91,212, 76, 13, 2, 64,139, 70, 62,107, 16, 12, 22,203, 55,118,208, 32, 86, 85, 70, +134,124,227,197,139,239,111,223,190,157,213,163, 71, 15, 98, 52, 24, 96,182, 88, 16, 26, 26, 74, 18,250,247, 23,254,184,125,187, +155, 89,165, 74,251,224,157,119,126,253,110,218, 52,101, 14,165, 5,182, 24,168,211,233,214,191,254,234,203, 3, 78,166,166,249, + 69, 69,133,186, 31, 57,158,154,238,238,230, 44,104, 21, 17, 33,172,172,170, 50, 47, 90,240, 54, 75,167,211,125,209, 20,143, 70, +163,217,119,226,196,137, 81,129,129,129,158,153,153,153,208,235,245, 48,155,205, 72, 72, 72, 0,165,148, 7,192,194, 98,177,112, +235,214, 45, 24, 12, 6, 73,110,110,110,241,157, 59,119,120, 0, 86, 55,198,171,213,106,239,215,253, 63, 40, 40,168,199,208,161, + 67, 97, 50,153, 48,104,208, 32, 36, 39, 39,247, 40, 46, 46,222, 88,167,201, 35,237,127, 15,106, 98,175, 90,251,251,251,239,173, +249,200,166,224,118, 95, 95,223,200,136,136,136,149, 31,126,248, 33, 59, 48, 48, 16, 22,139, 5,110,110, 46, 80,169, 52,168,168, +168, 64,116,116, 52, 2, 3, 3,241,209, 71, 31, 1,213, 43, 0,109,242,176, 21, 22, 22,230, 3,152, 21, 29, 29,205, 81, 40, 20, + 49, 26,141,102,105, 66, 66, 2,210,211,211,241,219,111,191,189,174, 82,169, 42,133, 66,161,209,207,207,111, 18,131,193, 16, 26, + 12,134,100,137, 68, 34,249,253, 71,192, 14, 59,236,176,195,142,191, 19, 54, 11, 44,111,111,111,129,131,131,195,179, 47,189,244, +146,139,197, 98, 1,135,195,137,245,240,240, 88, 85, 94, 94,174,108,238, 78,213,106,245,206,237,219,183, 15,252,236,179,207, 56, + 67,134, 12, 9, 11, 8, 8,232, 4, 0, 99,198,140, 9,115,116,116,196,246,237,219, 13,106,181,250, 79,203,105,100, 52, 26,123, +117,236,216, 17,149,149,149, 40, 40, 40,200,108,206,182, 7, 15, 30, 20,160, 58,238,170,209,207, 26,131, 73,175,119,117,241,247, +103, 60, 76, 77, 53, 84,202,229,190,189,122,247, 38, 70,131, 1, 12, 6, 3, 21, 21, 21, 40, 44, 44,132,179,139, 11,185,149,155, + 43,218,244,246,219, 7, 91,180,107,199, 53,235,245,238,182,242, 83, 74, 85,132,144,231, 95,159,245,218,190, 29, 59,126,242,144, + 74,229,121, 14,124,190,158,199,101,123,191, 49,235, 53,115,101,101,229, 84, 74,169, 45,231,105,245,142, 29, 59, 6, 13, 26, 52, +232,122, 80, 80,144, 87, 89, 89,153,143, 84, 42, 53, 87, 86, 86, 50, 81, 29, 75, 69, 0, 32, 53, 53, 21,114,185,220,100, 54,155, +211, 0,172,160,148,218, 52,149, 10, 0,110,110,110,142,125,251,246,237,226,237,237, 13,185, 92, 14, 15, 15, 15,196,197,197,117, +113,115,115,219, 89, 89, 89,169,176,149,199, 22, 28, 63,126,220,145, 82,218,133, 82,138, 65,131, 6,217,180, 13, 33,100,220,208, +161, 67,217, 12, 6, 3, 26,141, 26, 60,158, 3, 68, 34, 39, 56, 58, 58,163, 85,171, 86, 40, 46, 46, 70, 98, 98,162, 33, 55, 55, +119, 91, 73, 73,201, 47,205,181, 73, 38,147, 13,232,218,181,235, 75,175,190,250, 42,204,102, 51, 70,142, 28,137, 7, 15, 30,188, +151,159,159,127,208,195,195, 99,212,139, 47,190,232,230,238,238,142,121,243,230,241, 1,172,109, 46,191, 29,118,216, 97,135, 29, +255, 12,212, 10,172,198,230, 60, 3,254,143,189,243, 14,143,162,248,255,248,123,118,175,230, 82, 46,189, 23, 66, 75, 66, 8, 1, +164,215,128,244, 34, 16,154, 8, 42, 22, 64, 44,136, 34, 32,126, 5,197, 66, 81, 1, 11, 29,145,222,130, 32, 2, 2, 65, 36,244, + 22, 33,144, 0,129, 4, 8,185,244,222,175,237,238,252,254, 72, 49,196, 36,119, 23,162, 63,197,125, 61,207, 61,119,187, 55,243, +222,217,107,251,190,207,124,102,198,219,187,163,179,179,243,155,182,182,182,246, 39, 78,156,176, 6,128, 30, 61,122, 64, 16,132, +181,158,158,158,171, 82, 83, 83,207, 90,114,208,188,188,188, 66, 15, 15,143,159,206,159, 63, 63, 54, 60, 60, 28,145,145,145, 47, + 0, 64,120,120, 56,206,159, 63,143,123,247,238,253,148,151,151,103, 50,103,200, 28,188,189,189, 7,135,133,133,133,119,236,216, + 17, 7, 15, 30, 4,207,243,231, 76,215,250,131,234, 35, 6, 81,203, 40,194,202,125,102,137,177, 44, 8, 33,224, 56, 14, 0,144, +157,149,133,248,219,183,145,155,151, 7,157, 86,139,146,210, 82, 62,192,223,191,172, 64,175,151, 18,192,162, 62, 46, 74,105,146, +141,141,205,195,210,210, 18, 87, 71,103,135, 50,107,165, 18,249,133, 5,178, 43,151, 47, 20, 81, 74, 19,204,212,208, 19, 66,122, +255,242,203, 47,243, 89,150, 29,103, 99, 99,131,233,211,167,179, 97, 97, 97,144,201,100,208,233,116,200,207,207,199,182,109,219, +178, 56,142,107, 10, 0,132, 16, 27,107,107,235,205, 44,203,106, 10, 11, 11,255,103,234, 24, 10,133, 34,236,153,103,158, 97,117, + 58, 29, 22, 46, 92,136,249,243,231, 99,208,160, 65,236,165, 75,151,194, 0,212,158,225,222, 0, 4, 65, 64,255,254,253,171, 39, +185,215, 76,118,175, 21,169, 84, 26,208,162, 69, 11,100,101,101, 33, 43, 43, 11, 46, 46, 46,240,244,244,132,155,155, 27,150, 47, + 95, 78, 87,172, 88, 17,197,243,252,214,244,244,116,147,131, 60,106,226,237,237, 61,225,197, 23, 95,124,118,236,216,177, 40, 41, + 41,193,137, 19, 39,208,189,123,119, 44, 89,178,196,229,244,233,211,175,116,236,216, 17, 82,169, 20, 81, 81, 81, 48, 24, 12,169, +150,234,139,136,136,136,252,219,121, 82,242,175, 0, 19, 17, 44, 7, 7, 7, 59,165, 82, 57,117,216,176, 97, 61, 70,142, 28,137, +207, 63,255,172,234, 57,134, 97,176,101,203, 22,155,125,251,246,205,241,241,241,233, 45, 8,194,234,148,148, 20,147,249, 66,149, + 8,130,176,111,251,246,237, 67,186,118,237,170,234,211,167, 79, 51, 0, 80, 40, 20,250,237,219,183,151, 10,130,176,207,210, 19, +169, 57,233,163,151,151, 87,168, 68, 34, 9, 31, 54,108, 88,232,228,201,147, 17, 27, 27,139,109,219,182,221, 13, 8, 8, 56, 99, +161,244, 3, 19,163, 8, 43,247,213, 9, 43,151,231,228,167,167,219,219,248,250, 74, 29,108,109,211, 14, 30, 60,232,211,175, 95, + 63,146,156,156,140,188,188, 60,104,181, 90, 92,190,124, 89,144, 0, 73, 18, 7, 7,146,116,254, 60, 97,229,242, 28, 75, 95, 3, + 31, 15,135,150, 31,206,157,214, 68,171,213,182, 46, 40, 40,224,164, 82,169,212,219,221, 62,217,116,205, 63,160,148,234,172,173, +173, 59, 0,144, 8,130, 80,234,232,232,168, 58,118,236, 24,228,114, 57, 8, 33,104,211,166, 13,148, 74,165,204,218,218,250, 33, + 0,184,187,187,203,215,174, 93,171,158, 56,113,226,105, 83,218, 97, 97, 97, 18, 63, 63,191, 1, 1, 1, 1, 56,119,238, 28,110, +222,188,153,114,225,194, 5,175, 14, 29, 58,192,203,203,107, 64, 88, 88,216,225,147, 39, 79,114,150,158,119, 29,231,209,160, 36, +119,158,231, 41, 33, 4, 12,195, 64, 16, 4,100,101,101,161,105,211,166, 88,185,114, 37,150, 47, 95,254,109, 67,115,164,130,131, +131,101,237,218,181, 11, 31, 59,118, 44, 18, 18, 18,176,104,209,162,188,204,204,204,115,199,142, 29, 27, 60,125,250,116,182,123, +247,238,200,201,201,193,198,141, 27,185,223,127,255, 61, 34, 35, 35,195,226,239,128,136,136,136,136,200, 63,135, 58, 13,150,151, +151,215, 80, 71, 71,199, 87,198,143, 31,207, 6, 6, 6, 34, 35, 35, 3, 69, 69,197,218,208,208, 16, 1, 96,168, 92, 46, 51, 88, + 91, 91, 99,202,148, 41,104,211,166, 77,167, 57,115,230,116,116,119,119,223,146,158,158,190,215,156, 3,103,100,100,148,122,120, +120, 68, 76,159, 62,125,241,213,171,191, 55, 5,128, 75,151, 46,221, 75, 77, 77,157,155,145,145, 81,231,136,188,218,168, 54,153, + 37,177,178,178,186,216,178,101,203,251,131, 7, 15,182, 27, 57,114, 36, 92, 92, 92, 16, 29, 29,141, 37, 75,150,220,209,235,245, +243, 27,235, 2,110, 9,156, 78,151,126,101,255,126,219,176,231,158,179,155, 49,116,232,151,175, 79,159,190,236,195, 15, 63,148, + 4, 6, 6,146,210,210, 82, 92,188,120,145,238,221,187,215,248,195, 39,159,172,128,181,181,244,252,222,189,114,189, 94,159,100, +201, 49,188,189,189,123, 15, 25,212, 59,240,203,101,223, 64, 91, 86,140,139,231, 14, 33, 47, 47, 11,107,215,253, 24,232,237,237, +221, 91,163,209, 68,153,171, 69, 8, 9,136,140,140,116,165,148, 66, 46,151, 99,225,194,133,240,244,244,132,157,157, 29,138,138, +138,240,206, 59,239,168,223,126,251,109, 53, 0,196,198,198,194,198,198,198, 44,221,219,183,111, 63, 53,109,218, 52, 21,207,243, + 56,114,228,136,129,101,217, 47, 35, 35, 35,151,182,109,219, 86, 22, 22, 22,166,250,232,240, 3, 78, 0, 0, 32, 0, 73, 68, 65, + 84,225,135, 31, 58, 0,168,119,158, 50,115,105,104,146, 59,207,243, 15,142, 29, 59,214,102,220,184,113, 84, 34,145,144,252,252, +124,168,213,106,172, 92,185,178, 52, 45, 45,173,193, 19,180,229,228,228, 72, 91,183,110, 45, 19, 4, 1, 17, 17, 17, 72, 73, 73, +121, 47, 35, 35, 35,203,211,211,243,200,172, 89,179,166, 6, 6, 6,122,223,186,117, 43,165,172,172,108, 77,106,106,170,166,161, +199, 17, 17, 17, 17, 17,249,103, 80, 95, 4,235,185, 35, 71,142,176,130, 32, 96,221,186,117,136,142,142,166,217,217,217,243, 9, + 33,155,237,236,236,248,236,236,236,231, 94,125,245,213,145,243,231,207, 39, 61,123,246,196,249,243,231, 73,211,166, 77,195, 1, + 84, 25, 44, 66, 72,191,250,230,202, 40, 40, 40,184,156,145,145,222,180,218,196,146, 77, 21, 10,229,229,250, 26, 92, 83,179,230, +100,150, 44,203,116, 94,184,112, 97,137,135,135,135,254,198,141, 27, 88,179,102,141,112,229,202,149,223,228,114,249,218,212,212, + 84,157, 57,154,141, 65,117, 77, 57,199, 69,111,157, 53,171,213, 83, 35, 70, 8,175,188,251,110,177,204,202,234,173, 47,191,249, +102,118,126, 81,145, 39, 8,161, 78,106,117,210,186,133, 11, 23, 13,122,230,153,226,216,168, 40,229,213,200, 72,169,139,209,120, +205,146,118,106, 52,154,168,150,205,125,177,105,253, 50, 24, 12, 58,164,165, 36, 1, 0,178,115, 10, 80,159,185,170, 77,147,227, +184,130,209,163, 71,203, 0, 88, 77,154, 52, 73,158,153,153,137,230,205,155, 3, 0, 10, 11, 11,113,232,208, 33, 4, 5, 5, 1, + 0,174, 95,191, 94,245,216, 84, 59,109,109,109,251,245,234,213, 11, 73, 73, 73,136,139,139, 59,151,146,146,146,239,229,229,117, +238,225,195,135, 97, 29, 59,118,196,222,189,123,159, 70, 29, 6,203,210,247,200, 28,131, 85,199,185, 47,222,183,111,223,216,243, +231,207, 15,123,247,221,119, 37,125,251,246, 5, 0,148,148,148,104, 41,165,124, 67, 52,171, 99, 52, 26, 43, 39, 61, 45, 5,128, + 10, 51, 85,111,215,234, 95,253,249, 20, 53, 69, 77, 81, 83,212,252, 39,104, 62,105,212,103,176, 56, 65, 16,112,242,228, 73,252, +248,227,143,188, 94,175,127, 63, 45, 45,237,118,181,231,127,240,241,241, 57, 29, 30, 30,254, 85,124,124, 60, 27, 23, 23, 7,115, + 46, 64,213,209,106,181,198,154, 75, 5,107,181, 90,163, 37, 26,181,177,105,211, 38,164,167,167, 27,146,147,147,143,115, 28,183, +239, 49, 71, 35, 62,246, 40,194, 31, 40,213, 61, 71,200,241, 5, 61,122,244,159, 31, 25,169,120,101,222, 60,221,139,147, 39,191, +199,235,245, 70, 86, 38, 19,228,214,214, 12,175, 80, 72, 99,163,162,148, 95,191,246,154, 99,153, 78,119,100,171, 5,137,227, 64, + 85, 4, 11, 47,190, 50, 19,101,213, 34, 88,231, 47,199,195,210, 8,150, 86,171,109, 13, 0, 86, 86, 86, 15, 1,184, 63,255,252, +243, 16, 4, 1,101,101,101, 40, 42, 42, 66,106,106,106,193,228,201,147,121, 0,176,182,182,150,132,135,135,219,153,163,219,164, + 73, 19,119,150,101,113,248,240, 97, 40, 20,138, 19, 0,160, 80, 40, 78, 68, 70, 70,134, 77,152, 48, 1, 62, 62, 62,190,149,147, +160,212,167,227, 22, 50,114, 55, 5, 90,130,160, 5, 0,128,160,133,107,200,200, 24, 2,220,169,152,229,253,102,251,246,237, 1, + 51,243,174,170,147,149,149, 85, 2, 96,163,155,155,219,161,247,222,123,239,249, 46, 93,186,244,156, 63,127, 62,161,148, 62,246, +194,232,148, 82,240,188, 69, 95, 17, 17, 17, 17, 17,145,127, 41,117, 26, 44, 66,200,206, 62,125,250, 60, 75, 41,101, 25,134,217, + 86,195, 92, 1, 0,146,147,147,239,121,123,123,175,243,247,247,175, 90, 0,218,146,131, 87,204,188,190,132, 97,200,236,242,109, +203, 39,150,172,182, 36,201,108, 0,132, 97,216,205,191,255,254,251,188,135, 15, 31,102, 89,106,248,106,163, 49, 70, 17, 2,192, +118, 74,239, 63, 75,200,209,119, 67, 66,250, 13,122,237, 53,132, 14, 26,100,231,233,231,199,151, 25, 12,194,245, 51,103,200,185, +136, 8,217,213,200, 72,105,153, 78,119,228, 71, 74, 31, 90,218, 78,141, 70, 19,213,188,153,247,177, 49,225, 67, 6, 52,243,247, + 4, 0, 36,222, 79, 69,118,110,193, 49, 75,204, 85,117,180, 90,237,136,149, 43, 87, 30,144,201,100,146,234, 75,206, 24, 12,134, +220, 74, 19, 70, 8,241, 92,183,110,221, 78,134, 97,146, 76,233,221,190,125,251,216,130, 5, 11, 6,221,187,119,239, 84,114,114, +178, 6, 0, 18, 19, 19, 53,158,158,158, 63,166,166,166, 14,126,248,240,225, 47,166,204, 21,240,167,197,158, 17,123,102,143, 18, + 64,155,202,197,158, 27,186,214, 96,117, 42, 76,249,151,222,222,222, 63, 13, 30, 60,248, 89, 66, 72,186,201, 74,245, 96, 99, 99, +195,149,149,149,113,130, 32, 72, 12, 6, 3,181,177,177,249,219,187,170, 69, 68, 68, 68,254,229,116, 4, 80,185,114, 72,101,224, +196,165,198, 99, 61,128,234, 75,249, 85,110,103, 1,184, 92, 77,163,250,126, 83,117, 1, 32, 27, 64, 76,197, 62,179,168,211, 96, +105, 52,154, 95, 96,198, 98,206,230,150,171, 11, 74,233,251,132,144,175, 43, 30, 55,104,214,238,234, 26, 28,199, 53,202,250,109, + 12,195,220, 31, 62,124,184, 69,229, 77,149,217, 73,105,210, 91,132,108, 57,248,237,183,237,142,172, 89,227,197,115,156, 19, 1, + 40, 43,151,231,232,245,250, 7, 46, 70,227, 53, 75, 35, 87,213, 73, 72,212, 12, 4,128,128,128, 0,122,231,206,157,199, 30,141, + 65, 41,189, 6,192,199, 68,153, 84, 0, 61,205,209, 75, 78, 78, 62,128, 90, 70, 10,166,166,166,254, 12,224,103,115,219, 85,181, +216, 51,192, 8, 68, 24,211,186,199,216, 8, 0, 66,229, 98,207,141,137, 70,163, 73, 4, 96,209,106, 2,181,145,144,144,160,247, +247,247,223,191,120,241,226,145, 49, 49, 49, 7,147,147,147, 27,252, 62,139,136,136,136,252, 7,233, 8,192,133, 16,114, 16, 0, + 40,165,195, 0,128, 16,114,176,230,227,202, 50,149,229,170,151,169,212,168,185,191,190,186, 0, 48,119,238,220,121,139, 22, 45, + 82, 1, 48, 59, 23,247,111,159,104,180, 54, 26,106,172, 26, 91,163, 58, 26,141,102,189,233, 82,150,243, 77,185,129,106,148, 68, +238,186,136,143,143,127, 98,134,185,214, 70,229, 98,207,213, 8,249,127,105,136,133,220,191,127,127, 75, 88, 88,216,142,228,228, +100, 49,122, 37, 34, 34, 34, 98, 25, 46,181, 25,162,218, 10,214, 98,170,234,164,182,114,181,109, 19, 66, 14, 46, 90,180,200,164, + 94,117, 30, 59,175, 68, 68, 68,196,124,254, 63, 70,177,138,136,136,136,136,212, 78,205,168, 21, 80,110,186,106,110,207,157, 59, +119, 30, 44,232, 30, 4,202,103,230,238, 87,199, 65,205, 30, 29, 64, 8,169, 85,163, 62, 76,233,139,154,162,166,168, 41,106,138, +154,162,166,168,249,228,105,154,210,174,163,254,208,186,186,244,234,235, 46,172,249,216, 84, 93, 51,202,154,191,130, 71,101,242, +242, 95,113, 3,208, 79,212, 20, 53, 69, 77, 81, 83,212, 20, 53, 69, 77, 81,243, 49,111, 29, 41,165, 67, 81,190,202, 9,165,148, + 14,165,148, 14,154, 59,119,238,251,149,251,230,206,157,251, 62,165,244,233,202,114, 21,101,170,234, 84,238,171,121, 95,115,159, +137,178,102,183,249, 31,145,131, 37, 34, 34, 34, 34, 34, 34, 34, 82, 15,151, 1,116,164,127, 68,151,178, 0, 92, 95,180,104, 81, + 94,181,220,168, 44, 0,215, 0,180,173, 40,151, 5,252, 41,167, 74, 95,177,173,175,165,140,222,156,178,230, 34, 26,172, 58,104, +231,193,126,226,235,237,218, 1,168,136,242,149, 79, 14, 9,161,220,185,131, 86, 88,120, 8, 2, 40,165, 72,205,204,143,142,201, +160, 31, 54,244,120,129, 94,196,209, 85,169, 92, 33, 80,218,163, 98, 87, 84, 65,142,110,230,141, 2,154,111,174, 70, 43,119,210, + 74,201,224, 61,129, 34, 20, 0, 24,130, 24,173,128, 47,110,166, 83,139,231,131,170, 9, 33,132,180,118,193, 20,185,149,106,188, +218,222,161, 69, 94, 94,246, 29,131, 86,183, 39, 46, 11,107,171, 94, 11, 11,104,238, 72,186, 8, 20,243, 0, 48, 82, 6, 95,197, +231,208, 6,207,146, 46, 34, 34, 34, 98, 33,236, 99,214,175,109, 10,160,199, 29, 92,212,176,229, 39,254, 91,212, 54, 17,249, 37, + 51,203,253,237, 88,100,176, 90,187,146,215, 64,240, 17, 0, 10,138,143, 99, 51,233,106,139,234,123,146,126, 74,150,221, 0,128, +213, 26,248,119,169,128, 83,181,149, 35, 12,122, 41,101,236, 87, 0, 4, 45,207,191, 28,155,106,126, 62, 88,136, 55, 25, 36, 17, +152,173, 2,165, 82, 94,160,155, 65,113,208, 70,134,179,231, 53, 84,107, 73, 91,125,189, 93, 59,236,191,148, 54,224,183,213, 51, +208, 57,180, 57, 40,207, 1,130, 17,170,158,239,225,215,229,207,163,115, 43, 95, 80,193, 8, 8, 28,108, 6,127,137,193, 33,234, + 6,127, 57, 2,189,136,163,159,179,235,141,245,235, 55,184,123, 54, 11, 38, 2,103,192,237, 75,199, 38,190, 61,123,126,223, 16, + 53, 9, 49,199,100,181,245, 36,175, 52,111, 26,248,222,204,143,150,177,158,158, 62,214, 60,167,227,210,239,221,108,255,205,210, +249,123,219,122,146,175,174,165,210, 13,230,180,133, 16, 66,130, 93, 48, 85,162,144,143,181, 82, 90,183, 40, 45, 45,186,203, 27, +140,123, 66, 60, 37,131,190,248,114, 69,187,176,254, 67,108,248,162,116,198, 40, 32,120,247,174,157,126,223,174, 92, 53,132, 16, +242, 12,165, 84,176,228,156, 5,138,217,241, 91,166, 12,145, 74, 88,210,234,165,245, 44, 44, 24,250, 90,157, 96, 55, 50,129, 80, +211,211, 68, 80,130,211,113, 25,212,162,121,218, 42,105,229, 70,190, 39, 20, 1, 32,136, 32, 20, 59, 99, 51,105,102, 67,116, 68, + 68, 68,254,185, 48, 12,243,155, 32, 8,125, 26, 83,147, 16,210,133, 82,250,151,142, 26, 23,249,231, 98, 89, 4,139,224,211,216, +132,100, 7,240, 6,180, 14,104,246, 9, 0,139, 12,150,146,101, 55, 95,190,147,225, 14,206,128,245,159, 77,223,165, 55, 2,156, +209, 0,158, 51,130,231,140,224, 56, 3,120,163, 17,212,168,195,252,141,191, 1,250, 34,116, 8,105,185, 25,128,135,185,199,144, + 82,102,107,244,153, 99,142, 68, 95,128, 29,171, 23,189,153,156, 85,252,230,241,152,212,236,214,110,228,253,184, 76,252, 96,137, + 17,248,109,205, 12,108,219,119, 72,243,245,247, 37,183, 4, 74,225,104,103, 21, 56,113, 88,172,207,150,159,126, 75, 94,177, 89, +123, 11, 0,212,214,242,192, 23, 98,238,248, 90,242, 58,212,196, 85,169, 92,177,118,213,183,238, 30, 78, 86,132, 59,183, 24, 28, +207,195,199,111, 40,251,254, 27, 19, 61, 62, 93,190, 97, 57,128, 23,235,171, 31,228, 70,130, 3,154,183,122,119,243,161,115,190, +165, 69,153,250, 99,219,230, 37, 80, 29,140,238, 94,173,164,159, 44, 90,198,126, 48,103,198, 59, 65,110,228,226,173, 12, 26, 87, +159, 14, 33,132,105,229,138,159, 22, 45,254, 50,180,239,224, 97, 54, 66,113, 22,171, 45, 41, 14, 88,191,113,195, 71, 65,161,157, + 84, 61, 67,188,101,153,123,166,145,178,162, 92, 24, 24,165,162,111,235,126,118,101,147,158, 53,174,223,180,237, 13, 0,223, 88, +114,206,124,181,238,105, 65,104,248,191, 73, 66,209,243,234,133,223,166,242,169,151, 65,121, 35,192, 27,170,238,193, 27, 65,133, +242,251,206,211, 54, 2, 64,131, 12, 22, 67, 49,224,248,153,203, 30, 25,233,105, 29,151,127,249,249,251,193,174,228, 23,240,216, +122, 51, 23, 81,150, 26, 75, 17, 17,145,127, 46,132, 16,142, 82,218,168, 61, 59,132,144, 33,148,210,195,143,169,241, 30,128, 87, + 42, 54, 55, 80, 74,191,104,132,118,121, 3,112,175,216, 76,167,148,138,107,160, 54, 50,150,126,144,148,160, 2, 16, 49, 18, 0, +172, 44, 61, 24, 5,148, 32, 44, 96, 44,193,136,193,253,225,236,234, 14, 24, 75, 1, 67, 41, 96, 44, 3,140, 37,128,177, 12,217, +105, 73,128,161, 4, 72,252, 5, 28,165, 10, 75,143, 3, 93, 1, 16,191, 7, 79,183,247,133,139, 90,137, 25, 35,130,157,215, 29, +137,223,176,225,216,237,126, 0,198,155,213, 86, 74,209,185, 77, 11,124,189,161,228,214,129,232,204,129, 0, 48,180,157,243,145, +206,193,126, 62, 43, 54,107,111, 29,138,201, 29, 4, 0,131, 67,212,191,116, 10,244,240, 21, 30, 35,186, 43, 80,218,211,179, 73, + 11,194, 95, 93, 11,161, 80,131,194,194, 50,104,238,111,129,131,215, 83, 12, 47,160,183,169,250, 86, 44,230,190,245,191, 37,210, +210,194, 12, 61,111,200,226,157,153, 60,137, 68, 33, 16,164, 70,233, 74,132,124,254,237, 87, 39,241,179,230,127, 62, 23,192,196, +250,116,130, 93,241,198, 87, 95,173,104,211,189, 67,144,107,250,222, 25,164, 56, 47, 3, 28,171, 82,140,232,218, 29,246, 45,131, +133,140,147, 95, 17,121,179,126,176,119,106,134,148,115,219,241,224,194,143,164, 71,251,112,197, 15, 59,100,147, 80,135,193,106, +233, 66,122, 12,236,213,105, 87, 51, 95, 79, 15, 74, 5, 8, 2, 5, 21,120,188, 52,102, 0,222,223,157, 8,158,231, 49,122, 96, +143,167,151, 76,237, 75, 5, 65, 0,165, 2,146,211,115, 74, 79, 92,188,245,116, 66, 46,189,104,234,220, 41,193,233,182, 93,250, +244,136,137,190, 16,100,140,255, 25, 29, 38, 46,186, 69,128, 51, 85,207, 3, 61,126, 63,250, 67, 16,176,209,148, 84,173, 16, 66, + 72, 43, 87,240, 15,142, 44,134,111,175, 41,236,218, 29, 71, 92, 10,178, 82, 94,216,187,101,213,152,213,107,215,110, 3, 48,173, + 65,194, 34, 34, 34,255, 56, 40,165,141,110,178, 18, 18, 18,210, 30,199,100,121,123,123,247, 2,176,180, 50, 19,131, 16,178,212, +223,223,191,106,181,138,138,181, 77, 43, 41,224,121,126,162, 70,163,169,181,119,168,146, 97,195,134,121, 2,240,175,166,233, 79, + 8,241,175,173,172,189,189, 61,223,173, 91,183, 7, 7, 15, 30, 76,109, 72,251,255,203, 88,250, 33,186,245,112,207,140,246,186, +180, 98, 0,184,101,170, 48,173, 49,212, 82,107,228, 23,111,250,232,249,197,173,155, 56,162,168, 68,143, 99, 87, 30,128,231,141, +224, 57,174, 34,146,197,129,231,140, 24,216,214, 25,221,180,211,240,205,193,219,224,120, 97, 81,125,154, 53, 49, 80, 97, 66,187, +126,227,118, 11, 2,149, 43,164, 76, 65,128,143,147,235,187,163,219, 50, 51, 70,180, 70,153,129, 27, 23,236, 70, 78,196,101,208, + 71, 38, 17,173, 83, 83,248,243,148, 69,180,182,125,124, 45,251,204, 28,166, 26,228, 70, 58, 63, 59,172,191, 29,213, 21,192,152, +157,136,162, 82, 35, 18,115,140, 72,215,230, 67, 65,210,204,210, 20, 40, 66,189, 60, 60,172,207,238,154,115,223, 73, 82, 40,113, +149,112, 82, 57,229,164,188, 64, 89,228,199,233,156,130,250, 75, 42,243,178,234,107,167,149,202,246,249, 94, 3,134,170, 31,110, +159, 66,172, 2, 6,194,181,189, 15,238,159,218,132,204, 43, 7, 81, 92, 92, 72, 20, 5,249,112,115,106,142,193, 19,199,227,139, +241, 29, 81, 84, 88, 4, 54, 45, 65, 45,151, 42,236,235,210,164, 60, 38,126,181,228, 51, 15, 9,203,148,191,158,149, 55,222,136, + 50,157, 14,224, 57, 40, 37, 2, 8,173,124,206, 8,222,104, 80,133,134,207,153, 14,224, 98,109,154,213,137,203,160, 59, 90,187, +146,158, 16,140, 65,212, 88, 6, 2,156,137,205,164, 85,166, 39,216,141, 76,120,106,224,228,158,148,224,116,125,231, 94, 23, 33, + 78, 24,214,193,223,198,218,186,240, 22, 52, 17,111, 34, 1, 74,234,214,253, 21, 76,120,233, 13,213,186,117,235,134, 19, 66, 94, +171,158,131,102,238,251,110, 9,162,166,168,249,111,213, 84,171,213, 77,155, 52,105, 50,223,104, 52,246,146,201,100,110, 6,131, + 1,130, 32,164,203,229,242,211, 15, 30, 60, 88, 88, 80, 80,112,239,159,208,206,234,196,196,196,152,109,178,204,209,148, 74,165, +184,125,251,246, 93,115, 77, 86, 77, 77,169, 84,186,245,204,153, 51,216,189,123, 55, 0, 32, 62, 62, 30, 45, 91,182,180,174,173, +238,253,251,247,173,195,194,194,182,162,198, 10, 28, 53, 53,175, 95,191,222,244,231,159,127, 70, 68, 68, 4, 0,224,246,237,219, + 8, 8, 8,168,181, 61,103,206,156, 97,159,123,238,185,166, 0, 30, 49, 88,127,197,123,244,164, 33, 1,128,138,245,117, 73,205, +199,181,144,232,235, 32,111, 15, 45, 15, 0,137,150, 30, 44, 46,157, 46,105,235, 33, 29,244,107,196,202, 94, 74, 25,131, 5,235, +223, 77,206,202, 45,234, 34, 33, 16, 0,128,163, 96, 28,108,228,231, 23,189,208,214, 55,175, 88,139, 3,151, 82, 78,197,102, 88, + 22, 10,141, 77,165,145, 0,170, 46,248, 33, 78, 36,224,133, 47, 34,119,238,156, 59, 40,116,230,136, 80,252,116,238,193, 76, 0, + 38,103,105,167,130, 0, 42,112, 85, 73,237, 0, 0, 65, 0, 4, 14,213,174,167, 16, 64,203,247, 9,150, 69,176,194, 8,145,228, +185, 98,176,163, 74,254,221,212,169,175,218, 25,179,238, 32, 87, 47, 67,114,158, 22,233,101, 82, 20, 75, 92,145,114,235, 58,207, + 16, 68,154,210, 34, 4,133,224,181,246,142,114, 27, 38,164,255,116,175,194,163,243,242,228,148, 99,237, 70,126,106,159,253,235, +178, 7, 92, 89, 86, 9, 33, 48,185,136,182, 90,109,223, 82,155,243,128, 45,200,203,134,189,123,107, 12, 26, 55, 12, 31, 15, 13, + 70, 81, 97, 9,178,206, 29,162, 45, 60,236, 72,210,233,109,248, 96,112, 43,228,100,164, 65,103, 4, 72,137, 46, 87,171,215, 22, +215,165, 73, 25,172,125,123,214,236, 9,126, 30, 46,214,149,131, 5,168,192,163,109,171,102,232,223,171, 51, 34,207,156,197,229, +235,241, 16, 42, 6, 11, 80, 65,128, 38, 51, 47, 67,107,224, 55, 89,244,130,242, 28,168,241,207,105,118, 21,121, 87, 22,119, 13, +182,113, 35, 42, 30,248,176, 75, 11,219,151,231, 14,243,179,181, 86, 16,104,141, 60,180,122, 35,138,206,126, 7,167, 38,109,160, + 82, 42, 73,123,148, 73, 0,211,175,173,136,200,127,137,177, 99,199, 42, 51, 50, 50, 78, 14, 29, 58, 52,184,127,255,254,170,158, + 61,123,162,164,164, 4,199,142, 29, 67, 73, 73,137,159,143,143,143,223,177, 99,199,194,187,116,233, 18,231,237,237, 29,182,103, +207, 30, 75,114,100, 37,248, 35, 73, 93, 0,192, 17, 66, 80,177,143, 0, 16,232, 99,172, 67, 43,151,203,145,148,148,212,104,145, + 44,153, 76, 6,173, 86,139,148,148, 20,179, 77, 86,117,138,139,139,101, 94, 94, 94,112,113,113, 1,207,243, 40, 41, 41,193,254, +253,251, 81, 80, 80, 0, 65, 16, 96,101,101,133, 79,191, 90,143, 91,191,159,196,197,139, 23, 81, 80, 80, 32, 51,165,169,209,104, + 72,219,182,109,161,211,233,192,113, 28,180, 90, 45,142, 31, 63, 94,181, 45,145, 72, 48,251,147,229,136,191,114, 18, 87,175, 94, +133, 70,163,249, 91, 86, 7,177,192,139,252, 43,248,219, 71, 17,242, 60,247,254,186,205, 59,207,191, 63,109, 60,222,120,182,159, +207,194,149, 63,246,139,203,162,155, 1, 32,216,133,188, 48,169, 79, 11, 95,123,149, 20, 31,111,191, 2, 80,250,254,227, 30,239, + 70, 14,141,111,237, 78,102,238,187,152,116,114,222,248,246,104,230, 97,215,178,121,115, 34, 79, 72, 48, 99,205, 63,129,131,131, +141, 34,112,104, 59,231, 35, 16, 4,216,219, 42,130,192,115,176,183, 81, 4, 14, 14, 81,255, 2, 0,246, 42, 89, 80,109,145,174, +186,232,232, 43,155,162, 82, 72,166, 88, 63,229,225,251,226,240,254, 86, 67,134,135, 91,217, 72, 57,228, 92, 60,134, 66,169, 55, +140,142,126,208, 25,115,161,185,151,192,255,122,225,102, 74,118,145,238, 93,147,205,164, 56,149,114,239,182, 75,211,208,254, 14, +217, 7, 63,200,108, 58,121,187, 63, 3,129, 41,218, 54, 42,195,218,181,147,213,165,187,247,138, 5,250,231, 8, 78, 77, 10, 11, + 10, 30, 24,121,120,148,241, 18,219,132,223,126,192,220,193,109,144,151,155, 9,173,129, 67, 65, 25,103,112,183, 87, 42,116,247, +110, 64,103,224,160, 55, 10,144,218,123,225,216,249,235,217,130,209, 88,231, 90,148, 9,217,244, 42, 0,155,234,251,154,187,144, +182,115,236,172,174,194, 88,134, 36, 77, 42, 54, 31, 58,223,190,162, 92,131,161, 2, 87,222,205, 92, 65,101,242,123, 67,146,219, + 91,185,145, 78, 86, 74,217,183, 75,103, 62, 23,220, 53,192, 81, 33,104,206,131, 8, 6, 88,243, 18,148,201,121,168,125,154, 65, +208, 23,209, 82,173, 54, 63, 22, 16,103,102, 23, 17,169, 70, 80, 80,144,187, 90,173,142,157, 53,107,150,227,168, 81,163,176,111, +223, 62, 20, 22, 22, 98,211,166, 77, 88,177, 98, 5, 62,250,232, 35, 24,141, 70,172, 91,183, 78,181,119,239,222, 78,171, 86,173, +210,248,249,249,181, 78, 74, 74, 50,181,160, 58, 1,160, 0, 32, 69,249,181,139, 0, 16, 14, 31, 62,140, 33, 67,134,224,240,225, +195, 66,197, 62,158, 16, 98,164,148,234, 26,210,126,185, 92, 14,185, 92,142,130,130,130, 70, 51, 89, 54, 54, 54,144,203,229, 40, + 42, 42,178,216,100,113, 28,199,106, 52, 26, 20, 20, 20,160,255,240,225, 88,190,104, 17,250,244,233,131,254,253,251,131, 82,138, +227,199,143,163, 95,247, 16,140,127, 38, 12, 55,111,222, 4,199,113,102,181, 55, 61, 61, 29, 25, 25, 25, 24, 52,124, 56,214,175, + 90,133,206,157, 59, 35, 48, 48, 16, 28,199,225,228,201,147, 24, 51,176, 59,148, 35,251, 33, 62, 62,190,225, 39,254, 31,231,111, + 55, 88, 55, 50,233,133, 96, 23,114,240,217,129,157,134, 13,239, 17,140,245,187,126,253, 44, 56,152,236, 4, 0, 39, 91,197,167, +207,247,105,134,184,135,121,248,245,106,234,193,184,172,198, 25,125, 33,240,112,118,178, 83, 1,172, 28,101, 6,129,179, 75,132, +201,196,100,129, 82,168,122,205,193,164,225,113, 62,157,131,125,124, 42, 71, 17,218, 12, 89,134, 23,174,223,245,237, 24,232,238, + 11,222, 8,240, 70,216,141,223, 14,124, 82,107,196,246, 17,122, 52, 85, 68,206,121,119,102,183,193, 35,199, 89,201, 85,106,240, +133,201, 48,166, 95, 71,206,157, 83, 40, 81,181, 68,122, 82, 34,118, 31,189, 88,112, 71,147, 83,200, 48, 56,150, 81,160,123, 47, + 33,151,214, 25, 29,170, 68,107,196,162,249, 31,188, 59,116,247,206, 93,182,138,102, 61, 72,194,119, 67, 10,228, 18, 78,225,210, +244, 41,166, 84,233, 76, 63,223,180,203,174, 68,143,197,166,116, 74, 75, 10,127, 60,126,236,200,248, 22, 77,123,216,222,191,124, + 8,101, 90, 29,116, 70,160,117,167, 48,240, 60,149, 19,134, 8,118, 44, 75, 50,115,242, 64,140,124,198,233,107,247,211,206, 92, + 75,100,117,182,166,181,171, 35, 33,236, 91,195,195,218, 1,198, 50, 60,211,171, 13,150,111,251,245, 77, 0,147, 45,209,248, 19, + 66,121, 4,139, 2, 61, 90,187,146, 53, 0,122, 92,217,191, 34,168,195,200,183, 1, 11, 34, 88, 33, 46,100,112, 72,115,207, 31, +150,127, 58,199,209,201,187, 37, 75, 4, 35,168,123, 40, 80,168,161, 68,115, 30,106,175,206,224, 61,187, 99,221, 55, 95, 22, 11, + 2,221,217,144, 41, 42, 68, 68,158,100,180, 90,237,143, 75,150, 44,113, 28, 54,172,124, 58,161,226,226, 98,156, 63,127, 30, 27, + 54,108,128,181,245,163,191,147, 67,134, 12, 1,165,212,113,193,130, 5, 63, 2,232, 90,151,102,151, 46, 93,134,175, 92,185, 50, +181, 93,187,118,137, 40, 55, 89, 50, 0,204,141, 27, 55,152,228,228,100,226,224,224, 64, 61, 61, 61,141,169,169,169, 2, 0,254, +165,151, 94, 98,109,108,108, 90, 20, 23, 23, 71, 89,218,254, 74,131, 37,151,203, 27, 37, 39, 75, 42,149, 86,233,202,100, 50, 80, + 74, 45, 50, 89, 60,207, 75, 14, 31, 62,140, 43, 87,174,224,163,118,237, 48,211,203, 11,142,142,142, 56,121,242, 36, 40,165,176, +182,182, 70,110,110, 46,118,238,220,137,190,125,251,130,227, 56,147, 17, 44, 0,136,136,136, 64,116,116, 52, 62,233,208, 1, 51, +213,106,216,216,216,224,248,241,242, 94, 63,133, 66,129,164,164, 36, 28, 63,126, 28, 97, 97, 97, 13, 61,245,255, 60,102,127,104, +194, 8,145, 16, 55,184, 27,244,101,160, 28, 5, 8, 60,131,131,137, 44, 46,142, 26, 44, 61, 40,195,224,131,111, 54, 31, 28,186, +236,237,225,100,202,136,246,158, 11,127,248,237, 53, 0,120,121,116,128,151, 74, 33,193,215, 63,197, 81,134,193, 7,150,234,214, + 70,112, 48,145, 49, 12, 94,235,223, 57, 16,169,249,122, 36,164,230,159,136,163,212,172, 46,157, 95,151, 77,194,150, 3, 39,147, + 87,108,209,222,162,148,194,222, 70, 17,248, 66, 76,130,239, 15,135,163, 31,126,181, 91,123,139, 10, 20,246, 42,105,208,228,155, +221, 77,142, 34,236,232, 43,155,242,254,156,247,186,143,152, 60, 75,201,221,218, 3,125,194, 81, 8,134, 50, 20, 26,100,200,103, +221,161,121,248, 16,159,175, 59,152, 92, 88,162, 31,127, 35,211, 50, 99, 25,159, 77,139,131, 93,200,168,207, 63,158, 23,185,232, +211, 5, 54,165,137, 39,139, 89,194,149,177,126,189, 37,159,126,180,140, 20,233,244,227, 18,114,105,145, 41, 29,157, 45, 22, 47, +249,234,155,161,175, 78, 12,191, 21,208,178,183, 19,159,122,207, 73, 91, 88,152,185,253, 72,180, 59,202,255, 25, 18, 0, 72,208, +228, 32,171,160,132,227, 57, 99,148,173, 20, 11, 99,205,137, 6, 86,208,204,141,184,140,234, 25,250,156,139,173, 12,101,197,249, +112,181,149, 98, 96,231,230,207, 53,115, 35,115, 18, 51,168, 69,147,184, 61,130, 96, 4, 53,150,225,194,226,190, 65,148, 55, 6, +129, 55,194, 16,179,213, 98, 25, 74, 48,243,141, 94, 54,118, 14,250,251, 12, 74,172, 1, 43,103, 16, 59, 63, 64,237, 79,164,173, +198, 33, 53, 49,150,123,243,185,137, 57,247, 30,104,190,119,182,194, 99,143,228, 17, 17,121,210, 72, 74, 74,122,254,253,247,223, + 63,211,185,115,103, 55,103,103,103,180,105,211, 6, 7, 14, 28,192,172, 89,179,170,202,180,107,215, 14,148, 82,228,230,230, 98, +201,146, 37,233,169,169,169,207,215,167,121,235,214,173,219, 91,182,108,233, 25, 28, 28,108,144,201,100,249, 0, 20,249,249,249, +202,220,220, 92,162,213,106, 33, 8,130,160, 86,171,249,212,212, 84,227,248,241,227,117,231,206,157,107, 94, 82, 82,242,176, 33, +237,175, 52, 87, 62, 62, 62, 55,114,114,114, 10, 8, 33,143, 53,133,131, 84, 42, 5,195, 48,144,201,100,112,118,118,118, 41, 46, + 46, 22, 0,228, 53,100, 10, 7,142,227,208,161, 67, 7, 28, 61,245, 59, 14,255,122, 14,133,169,183,241,218,171,207,163, 77,155, + 54, 56,122,244,104, 67,154, 7, 0,104,219,182, 45,142, 28, 63,131, 51, 87,174, 33, 41, 62, 6,111,190,246, 42, 90,183,110,141, + 35, 71,142, 52, 88, 83,228, 15,131, 21, 70, 8,169,252, 39,254, 39,187,218,202,133,180,245,108, 33,223,186, 96,112,243, 86,210, +254, 11, 64,164, 86,216,211,242, 72,247, 15, 62,255,238, 86, 27, 55, 50,241,122,134,233,209, 94,213,185,145, 65, 99, 91,187,146, + 29,215,110, 6, 61,247, 76,103, 31,172, 63,160,250, 16, 0,198,245,108,138, 75,119,178,112, 49, 62,115, 71,108, 38,141,125,188, + 83, 43,207,163, 1,197,142, 37,111,141, 8,243,243,118,199,134,125,103, 64, 8,126, 52,167, 46,165,148,118, 14,246,195,138, 45, + 53, 71, 12,186,251,126,181, 91,123,235,232,141,194,193, 0, 48,160,149,245, 47, 29,155, 59,248,154,138,100, 88,201, 37, 83, 7, +135, 79, 82,114,241, 7,128, 7,199, 65, 56, 29,202, 12, 2,210,178,139, 80,170,246,193,201,243,215,202, 10,180,250,183, 99, 45, + 52, 87,149,196,101,209,196,118, 30,228, 97, 73, 73,153,135,202,165,185, 86, 66, 4, 90,172, 21,112, 41,238, 65, 65,108, 26,189, +109,142, 70, 66, 2,213,119,245, 38, 61,215,108,222, 61, 95, 42,147,143, 99, 9,136,171,189,181,203,154,101,159,192,214,214, 6, +130,190, 24, 40,201,194,168,215, 63,207,186,158, 98,104, 10, 0, 1,206,196,166, 87, 51,217,102, 9, 67, 52, 39,238,234,255,103, +234, 24,196,136,105, 19, 7,182,147, 10,250, 18,188,181,100, 23,214,206, 25,129, 73, 79,183,146, 30, 58, 27, 63, 13,192,194,134, +156, 59, 80, 62,208,128, 26,203,208,117,222,169, 91, 4, 56, 67,129, 30, 87,118,127, 26, 4,252,110,182,198, 83,132, 72, 37, 30, +164, 85,168,175,181, 76,208,156,133,160, 57, 75, 89,159,238, 32,190,189, 8,113,239, 64,191, 93,250, 81,201,250,245, 27,142, 9, + 12, 62, 54, 53,229,133,136,200,127, 21, 74,105,162,189,189,253,160, 33, 67,134,252,122,244,232, 81,199,144,144, 16, 0,192,149, + 43, 87, 0, 0, 29, 58,116, 64, 64, 64, 0, 50, 50, 50,240,236,179,207,102,167,165,165, 13,162,148,214,155,211, 91, 84, 84,148, + 24, 17, 17,225, 90, 92, 92,220,254,195, 15, 63,204,240,243,243, 43,212,106,181, 36, 63, 63, 95,224, 56, 14, 14, 14, 14,242,118, +237,218,161, 91,183,110,197,231,206,157,243, 79, 78, 78, 46, 4,112,191, 33,237, 31, 49, 98, 4, 78,157, 42, 31,132,215, 24,243, + 98, 73,165, 82,132,132,132,120, 37, 38, 38,166, 0, 64, 67,230,197,170,126,121,185,118,237, 26,162,126,215, 64,162, 47,131, 60, + 43, 21, 23,246, 69, 96,248,212,233,224,184,134,103, 43, 92,187,118, 13,251,143, 95,128,181, 66,130,219,183, 99, 17, 17, 17,129, +215, 94,123,237,177, 52, 27, 72,189, 94,228,223,134, 4, 0, 40,165, 81,168,101, 22,218,230,205,137, 92, 81,140, 5, 3, 59,120, +205, 30,215,163, 57,107, 44, 76,133,192, 11, 96,165,128,171,179, 29,182,110,221,209,116,199,174, 93,231,219,122, 73,191, 17, 56, +238,131,235, 25,180,212,130, 99, 47, 88,182,235,204,184,173,239,134, 73, 94, 27, 28,228, 8, 0, 50, 9,131,175, 15,196,114, 0, + 22, 60,206, 73,117,245, 38,202, 98, 35,166,184, 59,169, 63,124,255,149,161,142, 97, 29, 2, 16,117,241, 6,190,137, 56,127, 74, +158,137, 45,230,234, 80,193,136,154,190,169,182, 81,132, 16, 76,231, 83,242, 60,117,151, 89, 59,192,240,224, 55,192,160,133, 86, +103, 64,114, 14,143,228, 92, 45, 36, 42, 25,174,196,107,202,156,210,113,208,164, 80, 29, 16, 66, 72,143,102, 74,207, 15, 63,251, +202, 91, 91, 86,204, 21,230,101,115, 50,249, 5,169,202, 74,145,102,186,246, 31,156,215, 80,109,239,166,178,167, 0,129,149, 43, +105,233,188,119, 94,180, 78,137, 59,138, 22, 76, 42, 8,165,176,106, 53, 20,182, 86,172,172,167,191,236, 33, 0,248,187,171,229, + 75, 62,158,165,126,123,206,199, 38,115,188,130, 9,145,181,233,232,254,118,136,159, 3, 78, 69,223,194,169,235, 73,177,167,174, +220,110,221,167,141, 39, 2,188,237,103, 4, 19,178, 56,142, 90, 30, 17, 5, 0, 80, 14, 48,106,171, 70, 17, 6,187,145, 9, 29, +199,253,175,214,209,131,117,225, 15, 8,241, 60, 5, 97, 89,128, 48,229, 35, 26,147,207, 66, 98,223,140,238,216,189,191,116,195, +134, 45,159,196,101, 61,254,252, 51, 34, 34, 79, 58,249,249,249, 49, 42,149,106, 96,104,104,232,166,183,222,122,203,118,226,196, +137,158,175,190,250, 42, 3, 0, 25, 25, 25,194,138, 21, 43, 82,191,253,246,219,130,236,236,236,201, 6,131,225,186, 41, 61, 74, + 41, 37,132,156,219,184,113, 99, 86, 84, 84, 84,235, 46, 93,186, 40, 59,116,232,192, 59, 56, 56, 72, 20, 10, 5,175,215,235,181, +241,241,241, 66, 98, 98,162,103,126,126,254, 29, 0, 9, 13,233,190,175,136, 86, 45,100, 89,118, 62,165, 52,164, 49,114,176, 84, + 42,149, 7,128,187,132,144, 22,150,118, 15,214, 68, 34,145, 32, 47, 47, 15,165,233,177, 80,106,238, 32,212,154, 65,176,131, 13, +236,236,236, 30,203, 12, 21, 20, 20, 0, 37, 41, 56,115,230, 26,192,113, 80,171,213, 80,171,213,127,187,193,170,203,139,252, 91, +169,243,131,211,218,149,188,230, 32,199,138,169, 67,155,203,252,125,189,161,211, 92,193,181,228, 98,124,208,165, 83, 28,171,176, +213, 78,125,126, 68,135,240, 49, 77, 16,214,173, 35,241,247, 80,207, 88,188,108,245,235,173,221,200,172,216, 12,250,181, 57, 7, +142,205,164,247, 90,185,146, 13,191,197,104,166,121,171,202, 32, 8, 20,191, 93, 79,195,245, 7,121, 27,110,102,210, 90,135,238, +214,217, 86, 79,210, 79, 2,102, 23,165, 84,169,182,182, 46,106,215, 54,200,185, 95,215,182,204,160,222, 29, 32, 99,129, 51,151, +174, 97,230,178, 31, 47, 8, 2, 29, 26,109,102,247, 96,249,136,193, 71,141, 83,249,136, 65,227, 35, 35, 6, 41,165,180,124, 20, + 97,253,105, 93, 44, 75,210, 75,147, 46,187, 75,157, 90,162, 44,225, 55, 60,200, 19,144,148, 89,132, 66,137, 59,116, 41, 41, 0, + 21, 30,158,164,180,193,159,102,103,103,103,215,166,193, 1,205,191,219, 28, 1, 67,105, 1,238,157,220,132,226,188, 52,124,186, +230, 64,115,111,111,239,222, 26,141, 38,202, 92, 45, 66, 72,192,175, 7,119,184,130, 2,172, 84,129, 67,171,118, 35,219,201, 10, +206, 42, 25,132,178, 44, 76,125,123,162,122,112,255,137,106, 0, 72,186,125, 21,126,170, 50, 83,146, 0, 0,131, 19,194,199,245, + 9,180,135,177, 12,155,143, 92,213, 50,192,160, 45,199, 98, 19,250, 4,217, 43,199,245,240,115, 88,152,154, 63, 26, 13,156, 12, +180, 50,130, 85, 73, 67, 70, 15,238,161,148,111,229, 66, 18,118,157,203,180, 30,211,255, 41,149, 76, 66, 8, 45, 78, 1,181,114, +198,234,205,123,138,229, 70,172,107, 72,219, 68, 68,254,139,148,150,150, 70, 19, 66,218,188,247,222,123, 19,230,205,155,215,203, +218,218,186, 41, 0,148,148,148,220, 51, 26,141,167, 0,236,176,100,180, 95,133, 97,186, 75, 8,185,119,255,254,125,247,237,219, +183,171,241,199,124,140,101, 0, 10, 80, 62, 97,102,131, 71, 16, 86,154, 41, 66,200,124, 83,101, 45,208, 60, 92,161,217,162, 33, +245, 25,134,225, 9, 33, 32,132, 64,161, 80,224,244,233,211, 24, 59,180, 63,110, 30,202, 71,136,189, 13, 58, 77,158,138, 93,145, +145, 96, 89, 22,132, 16,176, 44,107,209,117, 68, 34,145,224,204,153, 51,152,244,236, 24, 40, 36,128, 90,173,198,123,239,189,135, +159,126,250, 9, 18,137,184,154,222,227, 80,247,171, 71,176, 48,114,211,231, 50,240, 70,252,188,233, 75, 28,188, 81,172,191,157, +133, 15, 2,179,176, 34, 2, 69, 66,214,178, 45,211, 34,207,220,248,226,165,241,195, 84,125,251,244, 71,223,176, 62,146,214, 29, +123,127, 8,160,202, 96, 17, 66,250,213, 55, 87, 6, 47,224,147,117, 71,110, 77,221,117, 50,158,192, 80,132,241, 3, 58, 82, 94, +192, 39,245, 53,184, 54, 77,181,149,205,174, 51,231,207, 59,192, 80,140, 7, 87, 79, 40,155, 52,109, 14,240, 6,220,189,123, 7, +223,110,222, 39,156,188,116,123,171,158,195, 91, 9,185,180,196, 92, 77, 0,128,192, 65,109, 45, 15, 28, 28,162,254, 69, 0,133, +189, 74, 22, 68, 5, 30,246, 42,105,208,128, 86,214,191, 80, 74,169,173,149, 52,136,242,127,246,108, 53, 53,203,244,220,218,205, + 27, 55,124,245,242,203, 47, 91,103,107,210,145, 90,120, 3,197,114, 47, 24, 85, 62, 72,184,122,170,172, 84,199,153,188,120,215, +247,122,102,103,103,103, 70, 95,204,197,174, 53,139, 96,212,235,144,169, 41,247,168,169,217,133,176,115,246, 58,111,137,166,129, + 19, 10,194, 39, 78,145, 89,217,194,106, 82,248, 48,121, 66,142, 14,237, 61,109, 1, 0,180, 56, 11, 55,143,159, 65, 88, 73, 20, + 0, 32, 49,153,129, 95, 91, 79,179,218,105,171,148,189, 53,248, 41, 47,220,123,152,134,211,177, 41,155, 19,115,104,106, 51, 39, +178, 57, 33, 53,127,218,136, 46,190, 88,254, 83,220,155,168,195, 20,213,165, 25,236, 70, 38, 0,232, 81,158,228, 94, 6, 10,244, + 8,118, 35, 19,204, 25, 57, 88,155,166, 68,134,231,190,250, 37,233,127,123, 46,103,143,152,253, 92, 79,187,110,221,134,200,193, +233, 81, 84,166, 51,198,229,209,194,134,104, 62, 46,162,166,168,249,111,213,172, 48, 59, 91, 43,110,141,169,153, 82,113,107, 20, + 77,224,209,238, 64, 74,169,164, 34,122, 85,111,146,187, 41,205,234,221,129,148,210,195, 21,209,171,122,163, 88, 53, 53, 5, 65, + 72,237,208,161,131,227,240,225,195,193,243, 60,238,220,185,131,164,228,100,244,155,246, 38,236,237,237,113, 42, 38, 6,183,111, +223,198,252,249,243, 97, 52, 26,177,127,255,254, 63,205,200, 94, 83, 83, 34,145, 24,154, 55,111, 46, 27, 57,114, 36, 56,142, 67, + 98, 98, 34, 82, 82, 82, 48,115,230, 76,168,213,106, 68, 71, 71, 87,105,102,103,103, 67, 34,145,252,169,103,225,175,248, 44, 61, +105,212,103, 79,121,240, 70, 20, 68, 46,192,215,167, 97, 48, 24, 17, 20,155, 73,171,247,105,175, 14,117, 34, 63,199,220,184,117, + 47,250,108, 95, 57, 50,175,151,215,177,128,248,108,154,214,209, 71, 82, 4, 67,145, 29, 18,127,193,253,140,162,226,248,108,106, + 81,151, 22, 0, 80,129, 39, 48,148, 2,105, 87,112,238, 84, 20, 78, 94,184,134,203,215,111,241,231,162,227,119, 49, 2, 62,137, +203,166,119, 44,214,164, 20, 54, 67,151,227,197,235,119,125, 59, 6,184,249,130,231, 64, 5, 35,212,227,119, 96,114, 92, 55,223, +142,205,236,125,203, 35, 87, 70, 56,188,114, 2,248, 74, 89,175,222,229,135,134,117, 61,154, 42, 70, 23,229,231,116,121,186,119, + 87, 72, 90,177,166, 0, 0, 32, 0, 73, 68, 65, 84,107,117,171,193,200,190, 27,143, 59,215,206,148, 69,223, 72, 56,119,249,161, +225,177,162, 35, 94, 94, 94,189,158,238, 29,136,241, 83,223,135,161,180, 0,137, 39, 55,162, 56, 55, 29,167,207,219,224, 86, 97, + 97, 87, 0, 81,230,106,157, 75, 50,182, 6,128, 30,254,178,135,182,208,185, 63, 63,108, 56, 20, 68, 11, 65, 87, 8, 82,154,141, +132, 20,125,193,232, 53,201, 60, 0,168, 20, 68, 98, 77, 11,236,204,209, 13,246,115,106,169, 98,141,216, 18, 25, 11, 65, 40, 95, +102, 73, 16,176,122,203,137,132,105,159, 76,106,143, 96, 95,135,182,164, 98,242, 19,115,219, 74, 40,122, 94,222,245,113,144,246, +215, 15, 1,193,128, 51, 51, 28,131,122,126,157,219, 19, 13,140,132, 93, 79,161, 41, 0,166,181,242, 36,107,103,124,125,228,195, + 14,145,113, 61,222,125,101,132, 29,168,184, 48,186,136,136,200,223, 79,113,113,241,212,201,147, 39,175,149, 74,165, 46, 0,136, + 32, 8, 16, 4, 65,242,197, 23, 95, 72,121,158,103, 24,134,225, 89,150,229, 14, 31, 62,108,228,121, 62, 75,171,213, 78, 53,165, +201,113, 92,194,244,233,211,155,155, 26,113,184,115,231, 78, 72, 36, 18, 3,199,113, 9,141,118, 66,255, 33,234,190,104, 80,124, +220,125,210,130, 5, 0, 8, 40, 62,170, 97,174, 0, 0, 49, 57, 52,181,181, 43,153,217,186, 99,239, 5,149,117, 44,109,128,150, +231,199,116,108, 19,176, 19, 0,116,148,159,100,105,125, 0, 40,212,149,141,107,215,177,235, 46,129, 82, 9, 71,233, 6, 70,192, + 94, 45,135,155,230,140,156,171,139,212,204,252,232,202, 5,156, 5,208, 63,186, 5, 43,166, 99,160,148,210,170,110,193, 47,149, +200, 46,208,153,156,199,233,204, 61, 93,255,142,190,178, 41,199,206, 94,157,202,243,212,157,101, 73,122,153,158, 91,251,184,230, + 10, 0, 52, 26, 77, 84,176, 43, 57, 22,211,214,109,128,179,170,124, 95,118, 41,144, 93,138, 99,154,204,162,168,134,104,230,149, + 24, 71,204, 91,241,211, 1,185,148,149,128,210,242,137, 64, 41,133,214,192,231, 86,154,176, 80, 39,226,249,222,126,110, 39,203, +146, 36, 83,122, 23,111,167, 45, 31,191,248,248,172,216, 7,121, 27,238,231,209, 27, 0,112, 63,143,222,104,225, 68, 62, 76, 72, + 47,154,117, 35, 41,239, 75, 75,243, 38, 40,193,233,142,227, 23,252,105,159, 37, 26,181,113, 51,149, 94, 3, 48,170,181, 43,233, + 63,254,221,111,223, 37, 4,226, 50, 17, 34, 34,255, 33, 42,163, 88, 12,195, 52,120,240, 77, 45,154,135, 9, 33, 67, 0,220,181, +160,206, 69, 0,109, 26,171, 13, 21,154, 57, 0,114, 26, 83, 83,228,207,212,105,176, 98, 51,233,106,152,177,152,179,185,229,234, +172,159, 74,143, 3,112,106,104,253,106, 26,142,143,163, 81,147,152, 12,250, 97, 99,234, 85, 82, 97,166,254,146, 92,158,184, 76, + 58, 16, 0, 2, 2, 2,232,157, 59,119,240,184,179,224,222,204,162,215, 80, 99,201,133,154,196,228,208, 84, 0, 61,205,209,139, +207,166,159, 0,127,238, 2,190,155, 67, 63, 5,240,105, 67,218,216,208,153,218,205, 37, 54,147, 70, 2,166,103,211, 23, 17, 17, +121,242,104,140, 73, 70,107,209,124,172,133,159, 69,254, 61,136,221, 30, 79, 32,241,241,241, 79,204, 40, 12, 17, 17, 17,145,191, +128, 6, 39,194,215,131, 56,233,176,200, 35, 48,255,223, 13, 16, 17, 17, 17, 17, 17, 17, 17,121,210, 32, 0,250,213,246,132, 37, +163, 3, 8, 33,181,106,212,135, 41,125, 81, 83,212, 20, 53, 69, 77, 81, 83,212, 20, 53,159, 60, 77, 83,218, 79,204,232, 68, 90, + 45,121,185,177,111, 0,250,137,154,162,166,168, 41,106,138,154,162,166,168, 41,106,254,215,110, 98, 23,161,136,136,136,136,136, +136,136, 72, 35, 35, 26, 44, 17, 17, 17, 17, 17, 17, 17,145, 70, 70, 52, 88, 34, 34, 34, 34, 34, 34, 34, 34,141,140,104,176, 68, + 68, 68, 68, 68, 68, 68, 68, 26, 25,209, 96,137,136,136,136,136,136,136,136, 52, 50,164, 98, 52,128,136,136,136,136,136,136,136, +136, 72, 35,193, 0, 0, 33,132, 86,191, 23, 17, 17, 17, 17, 17, 17, 17,249, 59,121,210,188,136,216, 69, 40, 34, 34, 34, 34, 34, + 34, 34,210,200,136, 6, 75, 68, 68, 68, 68, 68, 68, 68,164,145,169, 52, 88, 97, 21, 33,185,176,255,207,198,136,136,136,136,136, +136,136,252,103,121,162,188, 72, 85,146, 59, 33,132, 82, 74,201,255,115,123, 68, 68, 68, 68, 68, 68, 68,254,163, 60, 73, 94, 68, + 28, 69, 40, 34, 34, 34, 34, 34, 34, 34,210,200,136, 57, 88, 34, 34, 34, 34, 34, 34, 34, 34,141,204, 95,106,176, 8, 33,253, 68, + 77, 81, 83,212, 20, 53, 69, 77, 81, 83,212, 20, 53,255,107,136, 17, 44, 17, 17, 17, 17, 17, 17, 17,145, 70, 70, 52, 88, 34, 34, + 34, 34, 34, 34, 34, 34,141,140,104,176, 68, 68, 68, 68, 68, 68, 68, 68, 26, 25,209, 96,137,136,136,136,136,136,136,136, 52, 50, +162,193, 18, 17, 17, 17, 17, 17, 17, 17,105,100, 8,128, 90, 71, 2, 80, 74,143,155, 45,210,128,209, 4,166,244, 69, 77, 81, 83, +212, 20, 53, 69, 77, 81, 83,212,124,242, 52, 77,105, 91,226, 63,254,209, 80, 74,255,178, 27,128,126,162,166,168, 41,106,138,154, +162,166,168, 41,106,138,154,255,181,155,216, 69, 40, 98, 22,132, 16, 55, 66,136,219,255,119, 59, 68, 68, 68, 68, 68, 68,254, 13, + 72, 26, 83,172, 21, 33,125,167,135,186,237,121,253, 90,186,163,169,178,174,174,174,107, 85, 42,213,196,210,210,210, 18, 66,136, + 80,185,191,194, 25, 87, 95,191, 39, 49, 51, 51,179,167, 41, 61,133, 66,177,194,205,205,237,149,226,226,226, 82, 66, 8, 37,132, +128,144,242,229,140,106,222,243, 60,175,201,206,206,238, 96,201,185,253,211, 32, 0,235,236,230,118, 73,202,178, 94,150,214,229, + 5,225,126, 70,122,122, 87,179,143, 69,200, 34, 66, 48,187,226,241, 82, 74,233,251,150, 30,243, 31, 15, 33,172, 57,197, 66, 0, +219,120, 96, 60,207, 48,111, 74,129,149, 58, 65, 88, 3, 0,160,148,111,232,161,245,151, 72,115, 66,209,150, 16,168, 41, 69, 1, + 37,184, 38,239, 68, 19, 26,170,247, 56, 16, 66,186, 72,165,210,113, 14, 14, 14,182,153,153,153,191, 2, 56, 0,224, 25, 87, 87, +215,167,243,242,242,138,140, 70,227,110, 74,233,133,134,104,247,106, 71,230,200,101,210,151,180, 6,227,146, 51, 87,233,198,176, +167,136, 19, 39, 96,177, 82, 38,233,169,211,115, 75, 79, 95,163, 27, 44,108,235, 35,235,149,209,138, 31, 15, 75,136, 48,243,125, + 7,128,253, 14, 14, 1, 10, 23,187, 95,165,114,246,126,126, 70,241,196, 49,153,153,201, 99, 30,227,125,255, 39,226,226,226,242, + 34,195, 48,159, 81, 74,193,243,252, 7, 57, 57, 57,155, 26, 67,151, 16, 50, 1,128,117,197,102, 9,165,116,135, 5,117,147, 0, +248, 86,108, 62,164,148,250,213,183, 95,196, 50, 8, 33,171,247,237,219, 55,173, 79,159, 62, 88,190,124, 57, 86,175, 94,253, 32, + 43, 43,107, 49,128,205,148, 82,253,223,173,243, 36,209,104, 6, 43,152,144, 54, 47, 15,234,122,104,234,216, 65,114, 83,101, 93, + 92, 92,190, 31, 52,104,208,164,205,155, 55, 75,227,227,227,173,252,253,253,193, 48, 76,149, 1,170,254, 59,217,164, 73, 19,161, + 46,157, 74, 88,150,253,122,212,168, 81,147, 35, 34, 34, 84,209,209,209,170, 86,173, 90, 85,233, 9,130,128,154,191,187,254,254, +254,245,234,169,213,234, 43, 44,203,122, 3,127, 54,103,117, 61,230,121, 94,147,147,147, 99,210,180, 17, 66, 6, 2,152,107,170, + 28,128,197,148,210,163,245, 21,144,178,172, 87,106,106,170,171, 25, 90,143,224,227,227, 99, 48,183,108,121,228, 10,179, 5,129, + 50, 0,192, 48,100,142,149,149,213,234,178,178,178,228,202,231, 1,128, 82,154, 97, 73, 27,188,189,189, 7, 11,130, 48,161, 92, +147,217,161,209,104,126,177,164,190,157,157,221, 21,185, 92,238, 45,145, 72,170,222,140, 26,215,219, 71,182,121,158,167, 6,131, + 65,147,155,155,107,177,177,142, 2,200, 32,160, 23,199,178,111, 59, 57, 59,247,140, 62,118,204, 58, 36, 36,132, 97, 89,246,125, + 0,107, 44,213,171,142,254, 18,105,206, 27, 49,182,204,168, 24,166,240,251, 40, 64,151,244, 81,188,149, 84,119, 80,127,137,236, +249,187, 77, 22, 33,100,208, 11, 47,188,240,249,146, 37, 75,156,229,114, 57,179,123,247,238,174, 51,103,206,124,105,249,242,229, + 94,227,198,141,179,213,235,245,194,156, 57,115,122, 17, 66, 62,166,148,254,100,137,118,183,118,164, 75,160,191,199,252, 55, 38, +246,197,172, 69, 59,223,232,209,134,100, 91, 89,203, 86,143,238,217,220,190,117, 83, 7,124,188,246,220, 91, 0,204, 54, 88,132, + 16, 34,149, 74,219,185,187,187,251,235,116, 58, 30, 0, 92, 93, 93,171,190,232, 44, 91,238,155,116, 58,157, 33, 47, 47,239,176, + 37,109,173,141, 89, 74,101,231,206,246, 54,145, 11, 38,188, 96, 85,152,151,235,246,245,161, 3, 49, 17,112, 13, 29, 3, 60,120, + 92,237,127, 18, 12,195,124,150,146,146,226, 65, 41,133,135,135,199,103, 0, 54, 53,146,180,117,229,239, 48, 33,196,218, 68,217, +154,248, 86,171,235,107,198,126,139, 33,132, 40, 37, 12, 51, 93, 46,149, 14,224,121,190, 13, 0,176, 44,123, 93,111, 52, 70,114, +130,176,146, 82,170,125, 28,253,127, 56,179,167, 77,155,214,127,222,188,121,254,179,103,207,198,236,217,179,155,172, 95,191,126, +237,231,159,127, 62,135, 16, 18, 74, 41, 45,254,155,117,158, 24, 26,197, 96, 5, 19,226, 51,176, 93,192,201, 55, 95, 24, 43, 19, + 34, 86, 16,188,248,191, 58,203,186,184,184,124,223,181, 67,135,151, 54,111,222, 12, 0,152, 56, 98, 4, 6,116,234, 4, 91, 27, +107,200,229,229,205, 33,148, 64, 38,149, 97,228,204,119, 76, 30,155, 16,178, 52, 60, 60,252,185,136,136, 8, 27, 0, 88,189,122, + 53,194,195,195,225,232,232, 8,149, 74, 5,153, 76, 6,169, 84,250,200,189, 41, 88,150,245, 78, 73, 73,113, 85, 42,149, 0,202, + 13,159, 32, 8,143,220,170,245, 67,131,227, 56,180,108,217,210,164,110, 5,115, 11, 10, 10,122,149,148,148,212,219,119,219,180, +105, 83, 0,168,215, 96, 85,242,217,167,159, 64,224, 74, 32,145, 0, 28, 7,232, 12, 12,132, 90,254,203,123,122,122, 98,250,244, +233,127, 50,156,150, 48,108,216,112, 80, 74, 87,123,121,121, 29,204,200,200, 8, 33, 4, 83, 1,203, 35, 91,148,210,231,239,222, +189,171, 18, 4, 1,129,129,129,147, 0, 88,100,176, 36, 18,137,119, 76, 76,140,171, 66,161,168, 51, 82, 89,205,252,194, 96, 48, +160,125,251,246,156, 37,199,112, 3,124,115, 25,230,213,118, 79, 61, 53,101,254,136, 17, 86, 87,174, 92, 81, 48, 12, 3,142,227, +240,197, 23, 95,112,148, 82,251, 96,192, 46, 14, 40,172, 75,131, 16, 50, 15,192,139, 40,143,202,110,160,148,126,241,200,243, 20, +109,203,140,138, 97,137,197, 35, 59,117,110, 50, 7,113,177,215, 59, 53,179,217, 15, 91,137, 46, 1,192,223,106,176,212,106,245, +152,229,203,151,187,108,216,176,161,240,246,237,219,134, 53,107,214,184, 76,157, 58, 53,200, 96, 48, 96,218,180,105, 89,129,129, +129,178,229,203,151,187,236,219,183,111, 32, 0,139, 12,150,132,224,147,103, 71, 12,128,214,200,192,104,228, 92, 60, 92,108,183, +206,120, 33, 76, 74,169, 30, 91,126,138,134,145, 19, 54,154,171, 85, 17,185,106, 55,122,244,104,191, 29, 59,118, 72,110,222,188, + 41,105,213,170, 21,120,158,175,186, 9,130, 0,158,231, 17, 16, 16, 96,233,203,240, 39, 94, 2, 2,156,221, 28, 35,187, 14, 25, +108,229,161, 84,192, 49, 47, 11, 47,203, 36,182,155, 84,186,109, 0,186, 61,246, 1,254, 65, 80, 74, 33,145, 72,144,156,156, 12, + 87, 87, 87, 43, 71, 71,199, 52, 0, 31,229,230,230,174,251, 43,142,247, 56,145,173, 70,108, 67, 39,185, 68,178,119,203,198,175, +221, 59,119,235,198,186,121,184, 34,254,206, 67, 72, 8,223, 47,230,114,116,216, 75,175,189, 59,131, 16, 50,154, 82,122,233,239, +110,219, 95,141, 71,247,215, 71,121,244,120,115, 53,161, 2, 62,254,238, 64,209,162,165, 43, 84,211, 94,125,129,157, 57,115, 38, +124,124,124,252, 71,141, 26,181, 20,192,107, 38,117,186,188, 62,202,189,219, 27,171, 65, 41, 22,124,123,160,232,243,165, 43, 84, +175, 53, 64,231, 73,227,177, 13, 86, 8, 33,246,161,126,110, 81,159,206,158,106, 67,127,249,129, 41,205,201, 68, 93, 22,198,213, +213,117,237,224,193,131, 39,110,218,180,169,106, 95,215,144, 16,140,234,219, 3,174, 78,106,168,172,229,229,151, 33,129,224,218, +237,251,102, 25, 1, 31, 31,159,105,123,247,238,181,169,220,246,244,244,132, 76, 38,171,186, 85, 55, 87,149,183,154,145,142,218, + 80, 42,149, 56,126,252, 56, 36, 18, 9, 88,150,133, 68, 34,169,186, 85,223,102, 89, 22,110,110, 22,165, 38, 45, 86,171,213,161, + 69, 69, 69,118,249,249,249,240,245,245, 45, 4, 16, 83,237,249,208,172,172, 44, 59, 75, 4, 5,174, 4, 51, 95,110, 5,169,254, + 2,244,210, 78, 40,147,116,199,185,203, 55,113,240,104, 20, 82, 82,211,209,163, 75, 59, 60, 63, 97, 12, 34, 35, 35,193,243,150, +245,104, 80, 74, 51, 8, 33, 75,159,121,102,248, 28,128, 32, 44, 44, 44, 99,198,140, 25,244,198,141, 27,163,198,142, 29,243,244, +157, 59,119, 9, 0, 48, 12,153, 77, 8,249,218,220, 72, 22,165, 84, 6, 0,167, 78,157, 2,165,212,100,212,179, 54, 20, 10, 5, +206,159, 63,143,202,238, 96,134, 97,192, 48, 12, 88,150,197,207,119,157, 81,162,103, 80,154,113, 3,111, 14,243, 69,211,166, 77, +193, 48,166, 83, 14,195, 0,229, 57, 96, 20,145, 74,103,122,120,122,250,247,110,214, 76,117,252,248,113, 22, 0,252,252,252,104, + 90, 90, 90,254,254,253,251,139, 36,192,106, 63, 74, 55,215,103,174,124,125,125,187, 51, 12,243, 89,229,107, 78, 8, 89,234,239, +239, 63,191,242,121, 65, 16, 48,161,191,163,116,198,140,183,101,157,195,202,255,148,116, 30,190, 3,133,137,139, 90,145,220,121, +234,134,188, 38,143, 67, 65, 65,193,214,128,128, 0, 54, 43, 43,235, 4,128,123, 70,163,241,187,173, 91,183,186,190,252,242,203, +153,219,182,109,123, 3,128,207, 23, 95,124, 49,176,184,184,120,151, 37,186, 61,219,146, 33, 29,218,133,116,241,245,241, 65,212, +185, 75,144,201,165,246,211, 95, 28, 6, 27, 27, 9,190,220,112, 72, 72,210,228,190,113,250, 26,221,108,142, 86,133,185, 10, 29, + 51,102,140,207,142, 29, 59,100, 0,112,227,198, 13,100,102,102,194,201,201, 9, 74,165,178,234, 59, 95, 25,197,122, 28, 94, 2, + 2,212, 62, 78, 23,247,239,255,201,202,209,209, 30,223,189, 51, 3,207,167,106, 96,199, 50, 48, 26, 81,127, 40,252, 95, 6, 33, + 36, 96,244,232,209, 74,158,231, 81, 82, 82,130,147, 39, 79,170,173,172,172,212,222,222,222, 11, 0,152,109,176,172,172,172, 50, +180, 90,173, 43, 0, 40,149,202,204,178,178, 50, 55, 0,165, 74,165,210,170,162, 72, 89,181,226,230, 68,182, 30, 86,139, 80, 61, + 52, 99,191,217, 16, 66, 58,118,234, 24,122,252,199,136,237, 54, 5, 69,233,176,119,200, 4,131, 2,172, 91,183, 18, 86, 86,118, + 88,176, 96,158,228,126,191,190, 94, 3,135,140, 62, 78, 8,233,247,196,153, 44, 74,214,245, 27, 62,209,209, 74,101, 11, 0, 16, + 56, 35, 54,173,159, 1,134, 97, 48,127,254,124,180,110,221,122, 10, 33,228,127,148,210,220,250,101,176,174, 77,175,113,142,114, +101,249,165, 88,224,141, 88,179,115, 86,185,206,251, 83,241,236,240,166, 83,174,109, 35, 71, 90, 55, 67, 17, 0, 80,138, 50, 41, +131,135,232, 68, 51, 43, 53, 8, 33,189, 41,165, 81,117,109,255, 27,145, 16, 66, 40,165,180,122, 55,203, 35,219,245,209,132, 16, + 69, 75, 7,155,163,171, 62,154,225,201,158, 63, 36, 41,123,120, 23,169, 90, 30,246, 21,207,211, 26, 67, 45, 85, 42,213,196, 77, +155, 54, 61,226,191,124,221, 92, 33,147, 73, 33,149, 17,216,247, 28, 6, 0,200, 63,125, 16,132,212,110,174,106,106,150,148,148, +104,175, 94,189,106,179, 97,195, 6,184,186,186,194,223,223, 31, 42,149,170,234,135,182,250,173,210,104,213, 52, 88, 53, 53, 43, +159,151, 72, 36, 96, 24, 6,145,145,145,224, 56, 14, 99,198,140,249,147,185,146, 72, 36,181, 26,182,154,154,213,246, 31, 37,132, +196, 80, 74,123, 85, 92,120, 99, 40,165,189,171, 29,123,160,139,139,203, 92, 0,139,205,213,100, 89, 10, 86,123, 14,130,247, 10, + 72,146,103, 64, 47,109,139,223,206, 68, 99,211,218,229, 0, 0,255,160,142, 24, 59,106, 88, 85,244,205, 28,205,234,120,120,120, +108,206,204,204,106,223,167, 79, 31, 20, 20, 20,232, 23, 44, 88,128,208,208, 80, 4, 4, 4,214, 90,222, 28, 77, 66, 72,246,181, +107,215, 60,180, 90, 45, 8, 33,217,166,202,215,166, 73, 8,193,214,173, 91,161,213,254, 57,122,239,208,251,115,204, 10,247,195, +228, 55, 55, 99,233,237,221, 88,181,106, 85,189,231,174, 2, 66,181,234, 22, 95,203, 89, 46,116,201, 7,111, 40, 38, 77,154,196, + 78,158, 60, 25, 15, 31, 62,196,203, 47,191,172,141,140,140,212,167,167,165,253, 36, 23,132,239, 12,143, 26,226, 58, 53, 21, 10, +197,150,163, 71,143, 98,247,238,221, 0,128,248,248,120,180,108,217,242,145,139,136,144,187, 7, 69, 73,223,225,226,207,183,208, +121,248, 14, 92,252,121, 2,248,252, 67,210, 14, 45, 81, 80,223,185, 63, 46,181,105, 82, 74, 79, 2, 56, 89,185, 77, 8,249,223, +182,109,219,198, 2,248,145, 82,122, 14,192, 57, 0, 59, 45,209, 44, 23,194,228,113,225, 35, 33,145,217,226,214, 93, 13,122,119, +109, 15, 55, 87, 87,196,220, 76, 64, 82, 74,110, 6, 33,120,113, 80,119,197,226,178, 50,253,255, 78, 93,165,223,155,210,244,241, +241,105,186,103,207, 30,105,229, 54,203,178, 96, 89,246,145, 63, 84,149,251, 44,106,103, 13, 94, 2, 2,108,189,109, 46,126,178, +178,187,245,197,235,219,208,210,111, 8,236, 6, 14,193,178,157, 59,160,201, 46,208,114,165,220,211,150,106, 90,194,223,169, 73, + 8, 9, 8, 15, 15, 63,183,125,251,118,251,228,228,100,156, 58,117, 10,254,254,254, 40, 45, 45, 53,249, 71,183,166,166, 86,171, +117,173,102,154, 42, 83, 24,118,234,116,186,202, 31, 74,147,255,156,171,107,214,149, 91,101,105,206, 85, 45,191,243,114,165, 76, +182,103,255,143, 59,109,226,110,157, 66,187,182, 93, 96,163, 14,134,192,167, 35, 39,183, 24,121,119, 83,241,233,167, 75,177,224, +163, 15,112, 96, 95,132, 77, 96,171,182,123, 9, 33, 45,170,119, 23,254,219,223,119, 16, 58,229,248,207,219, 86, 19, 42,160, 44, +227,150, 66, 90,114, 79, 53,113,194,104,118,252,248,241, 56,112,224, 0, 98, 99, 99, 87,215,101,174,170,107, 18,138, 41, 55, 78, +237, 94, 13, 74, 81,150,121, 75, 33, 43,187,167,122,225,185,177,236,243,207, 14,192,133, 19, 95, 99, 64,187,123, 55, 60, 93, 49, + 42,175,162,147, 80,194, 34, 71,161,196, 89,171, 75,228, 66, 53,147,117, 18,229,255,161, 42,141,213, 73,148, 79, 37,245,175,165, + 42,130,101,137,177,170, 40,207, 62, 37,151,252,184,113,193,235, 33,202, 7, 55,100,186, 27,231,145,170, 19,232,134,135, 92,222, +138, 58,234,148,150,150,150, 36, 36, 36, 88,189, 56,106, 20,186,133,132,192,195,201, 9, 45,188,189, 97,165,144, 67, 46,147,254, +161,109,193, 9, 16, 66,104, 96, 96, 32,134, 15, 31, 14,169, 84, 10,149, 74, 5, 27, 27, 27,200,229,242, 90,163, 87, 82,169,212, +180, 40,202, 67,229, 44,203,226,198,141, 27, 72, 74, 74,130,189,189, 61,206,158, 61,139,167,159,126,250, 79, 81,172,138,118, 88, +208,234, 63,186, 29,107,217,127, 20,102,118, 13, 86,194,243, 4,197,180, 45,148, 15,222, 64, 41,105, 15,157,142,131, 78,167,195, +247,103, 12,184,148, 80, 2,131, 65, 15,157, 78, 87,231, 49,235,130, 16, 66,220,221,221, 71, 5, 5, 5, 77,156, 48, 97,130, 94, + 42,149,162,180,180, 20,165,165,165,184,121,243,166,126,192,128, 1, 25,207, 60, 51,220,237,224,193,131,148, 82, 44,181, 36, 15, +139, 82,154,231,233,233,233,161, 84, 42, 65, 41,205,179,228,124,171,181,175,202,188,212,228,197,101,113,144,176,229,239,201,234, +213,171,193,243, 60,234,251,124,107, 9,249,245,163,207,191, 82, 47, 89,177, 17,106, 71, 55, 68, 69, 69,241, 71,142, 28, 41, 34, + 64,252,157,216,216,101,207, 0,135,247, 0,102,231,174, 1, 64, 94, 94,158,149,191,191, 63,188,189,189, 33, 8, 2,140, 70, 35, + 98, 98, 98,144,158,158,142,156,156, 28,148,149,149,193,209, 58, 31,205,157,188,193, 21,157, 68,218,141,143,225, 97,115, 11,155, +143,234,141, 79, 5,224,154, 37,199,250, 43,160,148, 30, 6,240,216,249, 75,160,240,114,117,247, 1, 67,141, 72,205,204,193,200, +161, 3,192,202,108,112, 63, 57, 27,109,131,155,121, 60,247, 76,119, 15,150,112,152,189,120,199,116, 0,223,155,146, 43, 45, 45, +229,111,222,188, 41,189,118,237, 26, 88,150,133,157,157, 93, 85, 58, 64,117,115,101, 78, 58, 64, 93, 84,154,171,207, 87, 63,109, +205, 72, 75, 80,200, 31,199,154, 31, 46,160,165,239,211,216,116,235,142, 86,146, 95,220,239, 75,173, 54,190,193, 7,248, 7,224, +225,225, 49, 85, 16,132, 5,148,210,252,240,240,112,183, 29, 59,118, 56,164,164,164, 32, 58, 58, 26,243,231,207,207,226,121,158, +163,148, 18, 74,233,199,143,123, 44, 74,169, 80, 61,178,101,101,101, 85, 25,217, 42,169, 22,185, 42,177, 84,151, 16, 34, 85, 41, +241,166,179, 29, 25, 33, 97,236,252,185,194,226,251,217,122,250, 83, 41, 39,124, 75, 41, 53,214, 87,151, 97,152, 87, 34,118,173, +246,116,118, 17, 16,230,210, 23,105, 25, 6,124,254,206, 11,200,201, 41,194,247,235, 23, 1,144,195,192,177,232, 21, 54, 26,174, +174, 94,152,242,234, 20,247,213,107,215,188, 14,224, 75, 75,219,249, 79, 37,237,236,202,125,132,144,227, 46, 46, 46,177,175, 79, +153,226,226,239, 63, 9, 74,165, 18, 59,119,238,196,142,239,190,227, 87, 0, 99,215, 18,242,219, 84, 74,247,213,171,115,225, 15, +157, 25,211,166,185,180,106, 53, 13, 10,133, 2, 39,142,252, 0,109,250,214,162,161,221, 96, 40,213, 98,104,147,225,212,241,193, +207, 36, 87, 42,197, 93, 0,144, 42,145, 38, 5, 50,107,200,253,235,141, 85, 37, 13,238, 34,108, 38, 83,157, 91,255,206,184,246, + 46, 66,153, 68,127,230,103,164,232, 4,238,139,187, 6,195,149,124, 58,177,174, 58, 12,195, 8,190,190,190,232,219,161, 3, 70, +245,236, 9,137, 68, 2,165, 92, 6, 91,165, 21, 40, 95, 30,185,170,236, 34, 52,215,235, 85, 26, 27, 39, 39, 39,200,100,178, 42, + 99,101,110,244,170, 46, 77, 65, 16, 32,145, 72, 16, 19, 19,131, 30, 61,122,192,199,199, 7,187,119,239,198,192,129, 3,255,212, +101,104,169,185, 2,202, 13, 86,245,238,186,106,201,239, 38,147,219,107,162,213, 19,100,235,219,130,144, 16,112, 28,192, 83, 64, +167,213,130, 82,128, 82,192,104,208, 67,171,213, 86, 29,211,156,174, 87,111,111,111, 79,127,127,255,119,230,206,157,221, 34, 52, +180, 29,178,179,179, 33, 8, 2,108,108,108, 80, 90, 90, 10, 59, 59, 59,116,235,214,237,247,207, 62,251, 44,151, 82,204,181, 52, +201,253,113,169,124,205,143, 29, 59,246, 72,247, 96,229,173, 36, 77,131,201,111,109,131, 92, 2,196,196,196, 32, 40, 40,200,148, +185,100,250,244,234,142,115,191,199,115, 47,191,183, 66, 39,205,137, 94,236, 46, 8,155, 52, 64,131,207,139, 82,138,236,236,108, +100,100,100, 96,196,200,145,216,177,125, 59, 30, 60,120,128,224,224, 96,244,233,211, 7,174,174,174,120,240,224, 1, 46,157,214, + 65,151,151,139, 92,125, 52, 84,182,157,177, 63, 42, 65,247,225, 42,253,255,203, 40, 66,160,188,219, 4,192,203,106,181,186, 73, +105,105,105,186,209,104,220,141,114,211, 63, 80, 42,149,142, 83,169, 84,238, 5, 5, 5, 15, 0,124, 79, 41,189,108, 74,207, 74, +169,116, 82, 40,237, 32,112, 58, 72, 36, 18,248,248,248,131,242,122,228, 21,150,225,197,241,195,241,123,204, 77, 28,249,237, 2, +103, 52, 10,223,152,219,198,128,128, 0,228,228,228,128,101, 89,168, 84, 42, 88, 91, 91, 35, 48, 48, 16,201,201,201, 85,230,170, +161, 93,132, 47, 1, 1,118,190, 54, 23, 62, 91, 89,110,174,210, 83,211,144,242,128, 66, 33,151, 99,237,186,213, 37,165,233,121, +157, 55, 2,255,106,115, 5, 0,130, 32,124,156,146,146,226, 42,145, 72,220, 57,142, 67,114,114, 50,174, 92,185,130, 55,222,120, + 35, 35, 39, 39, 39,140, 82,218,160,115, 84, 42,149,153,149,145, 43,165, 82, 89,117,241,172, 45,178,245, 56, 57, 87,132,144,102, +254,222,182,145,235,151,207,244,237,216,185, 27,163,146,216,229, 21,223, 77,239,113,230, 84, 84,183, 55,150,127,255, 58, 33,100, + 0,165, 52,177,174,250, 10,169,116,112,151,238,221, 37,160, 25,144,200,123, 96,233,146,241,200,202, 46, 68, 94,110, 17,100, 50, +107,232,141, 44,120,129,160, 91,143,158,248, 97,243, 46,180,126,245,101, 86, 46,149,246,199, 19,100,176, 42, 88,244,237,183,223, +250, 6, 6, 6, 98,211,166, 77,248,109,203, 22, 60, 95, 80,128, 40,134, 97,141, 82,169,243, 97,163,113, 29,128,122, 13, 86,117, +157,214,173, 91, 99,227,198,141,216,186,117,235,195,137, 79,103,238,157, 57, 17,174, 6, 3, 6, 69,223,134, 99,147,225, 64,244, +109, 56, 62, 21,136, 22,156, 4,119, 9,129, 85,117, 1, 66, 72,239,234,247,255,118, 36, 0,194, 72,121,127, 92,213,189,169, 74, +214,110,129, 19,182, 79,234,223, 33,184,169, 55, 99,220,253, 53, 82, 74, 57,237,252,219, 6,225,118, 17, 29, 29, 87,143, 57, 96, + 24,134,178, 44, 11, 91, 43, 43,184,216,219,151,255,211,100, 24, 64, 0, 4, 35, 64,248,242, 47, 31, 21, 8, 44, 25,252, 44, 8, + 2,228,114,121,173, 9,237,150,230, 94, 85,215, 44, 42, 42,194,253,251,247, 49,101,202, 20,168, 84, 42, 0, 64,122,122, 58,252, +252,252, 32,145, 72,144,146,146,130, 19, 39, 78,160,105,211,166, 80, 40, 20, 22,185,172,106,209,164, 80, 66, 72, 20,128,208,180, +180, 52, 59, 15, 15, 15,192,210, 8,150, 64, 81,170, 35,208,235,121,220,185,115, 7,169,169,169,184,127,239, 46, 58,150, 20,130, +130, 5,165,212,162, 8,150,135,135, 71, 96,203,150, 45, 63, 91,180,104,145,212,199,199, 7,130, 32,192,209,209, 30, 37, 37,101, +200,201,201, 65,112,112, 48,124,124,124,176,116,233, 82,160,188,251,232,111, 53, 87,213,169, 28, 45, 90,253,158, 97, 24,188,245, +140, 47,114,115,109,192,178,127,140, 38, 53,145,131, 37, 3,128,176, 1,225,146,200, 35,135,173, 57, 96, 97, 58,203, 46, 52,245, + 15,132, 82,106,228, 5, 65, 85,215,243,201,201,201,144, 74,165,136,216,179, 7,185, 25, 25,104,219,182, 45, 58,117,234,132,187, +119,239,226,247,223,127,135,147,147, 19, 92,188,187, 34,234,158, 1,113,169,101, 80,171,213, 72,208, 48,255,111, 67,255, 9, 33, +195,250,245,235,247,221,178,101,203,220,221,221,221,165, 89, 89, 89,220,202,149, 43, 7,174, 92,185, 50,238,245,215, 95, 15,126, +253,245,215, 29, 92, 92, 92, 36,233,233,233,198,119,222,121,103, 32, 33,100, 46,165,180,206,110, 67, 0,176,182,182,117,100,101, +214, 32, 68, 2,123,181, 3, 36,114,107, 8,156, 4,188, 0,216,169, 93,112,238,247, 8,156,189, 94, 52, 53, 51, 7,123, 76,181, +143, 82, 74,157,156,156, 40,203,178,112,114,114,122,164,107, 16, 0,220,220,220, 80, 88, 88, 8,150,101, 33,149, 74, 45, 54, 89, +149,230,234,243,149, 79,219,144,106,230,170, 56,219, 9,191, 29,189,153, 95,154,158,215,227, 73, 48, 87, 0,170, 6,235,220,187, +119, 15,165,165,165, 56,125,250, 52, 62,254,248,227,172,154,230,202,205,205,237, 85, 59, 59,187,143,138,139,139,151,166,165,165, +125,109, 74,183, 34, 50,213,104,212, 54, 29, 3, 33, 68,234,227,161, 60,250,251,233,109,126,106,122,141, 32,105, 10,112,167, 48, +214,246,162,107,175, 33, 29,135, 50,237, 87,125,210,164,211,212,247,143, 18, 66, 2,235,138,100, 9, 60,223,222,218,198, 22, 64, + 38,162,175,156,172, 50, 87, 57,185, 5,208, 25, 88,232,244, 4, 90, 3,131,190,253, 6,225,187, 53, 91,145,146,153,139,202, 17, +134, 79, 10,132, 16,199,144,144,144,105, 99,199,142,197,194,133, 11,113,124,217, 50,253,107,132, 20, 74, 0,122,136,231, 33, 80, + 74, 24, 51,146,211,107,234,124,249,229,151,251, 0, 60,187,248, 13,116,205, 43,198,139,158,195,169, 99,147,225,229,101,199,204, +161, 0,224,152,117,252, 79,169, 58,164,178, 39,205,210, 30,181,127, 42, 18, 74,105, 20, 33, 4,213,239,235,171, 96,239, 30,216, +251,127,115,102,172,232, 62,162, 31,147,254, 90, 15,228, 23,234,244,115,110, 26, 25, 77, 41, 29, 85,159,185,170,206,123, 43, 87, +226,247,248,242,239,175,183,171, 43,102, 63,247, 28, 40, 7,156,141,141,195,174,227,199, 49,190, 95, 63, 88, 87,140,224, 51, 69, +229,197,179,182,168, 85,245,232,149,165, 81,166,252,252,124,236,217,179, 7,157, 58,117,130, 74,165,130, 68, 34, 65,104,104, 40, +110,222,188,137,102,205,154,129, 16,130,253,251,247, 99,212,168, 81, 72, 76, 76, 68,215,174, 93,109, 76,171,254, 65,165,217,137, +139,139,179,163,148,246,170,140,118, 52, 20,157, 78,135, 91,183,110, 97,248,240,225,112,112,112,128,151,215, 14, 28, 63,186, 13, +170,144,231, 65, 8, 44, 50, 88,132,144, 49, 67,135, 14,149, 50, 12,131,178,178, 82, 40, 20, 74,216,216,216,193,214, 86,141,128, +128, 0,164,166,166, 98,224,192,129,134, 59,119,238,108, 77, 75, 75, 59,100,105, 91,221,220,220, 84, 69, 69, 69, 51,252,253,253, +149, 0,160, 84, 42,251, 58, 59, 59,127,158,157,157,109,209, 48,222,234,198,138, 16, 2,150,101,171, 12,150,132, 97,224,225,238, + 90,181, 93,145,127, 86,231,135,128, 16, 82,152,146,163, 83, 0,128,175,175, 47,190, 91,123,128, 25, 58,116, 40,102,204,152, 1, +163,209,136, 85,171, 86, 1, 0, 38, 76,152, 0,131,193,128,189,123,247, 2, 0, 36, 18, 73,189,125,206, 87,174, 92, 65,116,116, + 52,140, 70, 35, 10, 10, 10,240,203, 47,191, 32,234,212, 41,236,220,255, 43, 30,220,187,139,208, 64, 63,188,252,242, 75,144, 74, +165,216,188,121, 51,122,244,232, 97,201, 75,208,232,200,100,178, 23,214,175, 95,239,181,105,211,166,252,159,126,250,169,160,115, +231,206,214, 43, 86,172,112,253,238,187,239,250,232,245,122,188,253,246,219,153, 23, 47, 94, 44, 25, 49, 98,132,122,221,186,117, + 94, 45, 90,180,120, 6,181,228,101, 85,116,251,140, 7, 48, 41,172,147, 90,146, 95, 84, 6,129,211,227,222,131,251, 40, 40,214, + 67,224, 13,120,168, 73, 69,177,150, 71, 78,110, 17, 66,219, 15,248,246,228,201,147, 31, 16, 66,230, 81, 74, 15,154,106, 39,207, +243,184,112,225, 2,206,158, 61,139, 83,167, 78, 33, 41, 41,169,234, 57, 59, 59, 59, 68, 70, 70,162, 79,159, 62, 22,157,123, 93, +230,170, 40,171,220, 92,229, 63,204,125, 98,204, 21, 0, 80, 74, 23,120,120,120, 44,240,240,240, 80, 30, 59,118, 76,221,164, 73, + 19,112, 28,167,175, 25,185, 10, 11, 11,251,223,250,245,235, 61,154, 53,107,246, 6, 0,147, 6,171, 46,234,138,108,153,129,111, +181,200,151, 47, 0, 48, 12, 94, 93,186,122,154,179,173,252, 97, 42,238,124, 85, 49, 23, 32, 11,148, 22, 2, 39,183, 67,210,253, +195,251,111,140,156,227, 48,119,211,194, 87, 1,172,170, 75, 56, 33, 49, 25,171, 87,127,135,153,111,191,136, 31,190, 95, 10, 65, +144, 64,103,100,225,235,223, 5, 58,131, 0,194, 72,208,182,125, 7,252,118,242, 52,164, 12,176,103,211,234, 6,158,253, 63, 19, + 74,105, 46, 33,100,213,254,253,251,223,156, 49, 99, 6, 4, 65,144,127,180,122,117, 89, 86, 86,214, 34, 88, 48,127, 85, 45, 58, +163, 86,175, 94, 29, 63,247,187,172,125, 51, 39,130,125,240, 51,201,141,190, 13,199, 49,115, 40, 34,150, 16, 60, 21,136, 92, 85, +237,151,248, 83, 53,238,255,213, 72, 0, 84,229,166,212,231, 24,159, 10,104,246,137,218,209,225,165,110, 29, 91, 57,189,243,198, +171,210,196,116, 45,142,118,120,167,224,192,242, 15,109, 30, 10,214,111, 39,209, 66,139,162, 46,187, 78,156,168,122,252,197,142, + 29,181, 62,151, 54,102,140, 89, 90,130, 32,212, 25,181,178, 52,114, 5, 0, 42,149,202,190,127,255,254,120,250,233,167, 49,122, +244,232,170,156,171,118,237,218, 97,231,206,157, 8, 15, 15,199,213,171, 87,225,225,225,129,160,160, 32, 4, 5, 5,225,240, 97, +203, 82, 85, 42,187,235, 66, 66, 66, 42, 71, 17,134,106, 52, 26,139, 70, 15, 86, 71,167,211, 33, 39, 39, 7,142,142,142,144,203, +229,232,220,185, 19,222,124,171, 51,156, 61, 54, 34,164, 85, 32, 74, 74, 74,170,134,174,155, 66, 42,149, 6,180,104,209, 2, 89, + 89, 89,200,202,202,130,139,139, 11, 60, 61, 61,225,230,230,134,229,203,151,211, 21, 43, 86, 68,241, 60,191, 53, 61, 61,221, 98, + 71,232,237,237,221,209,217,217,249,205,204,204, 76,101,181, 31, 77,101,219,182,109,215,122,122,122,174, 74, 77, 77, 61,107,174, + 22, 33, 4, 6,131, 1,132, 16, 28,186,231,137, 18, 61, 65,161,230,255,216,187,238,176, 40,206,245,123,190,153,109,148,165,151, +165, 44, 32,168,160, 40, 24,187, 81,136, 93, 52,154,168,216, 80,115, 19, 75,162, 73,140, 53,118,141,137, 49,106, 98, 55,106,108, + 55,137, 92,187, 98,140,196, 94,176,199, 46, 32, 32,138,133, 14,178,244,133,173, 51,243,253,254,160, 4,145,178,152,114,111,242, +243, 60,207, 62,176, 51,179,103,190, 25,150,153, 51,239,247,190,231,189,133, 41,111,123, 61, 39,184,196, 98,177, 41,137,186, 37, + 97, 97, 97,206, 30, 30, 74,164, 38,221,195,129, 3, 20,171, 87,175,198,133, 11,101,255,231,137,229, 15, 4, 21,239,187,119,239, + 14,111,111,239, 6,153, 91, 10,130,128,232,232,104,236, 62,124, 30,174, 94,254, 72,121,144,128,219, 71,143,160,145,147, 61, 90, +182,105, 7,163,209,248,187, 44, 52,254, 8, 24, 12,134,173,190,190,190,208,235,245,103, 0,108,139,142,142, 30,156,153,153,185, +230,231,159,127,118, 27, 54,108, 88,198,145, 35, 71,166, 1, 56, 20, 29, 29, 61,230,171,175,190,234,105, 44,155, 62,120, 1, 44, +203,254, 48,125,250,244,110,195,134, 13, 35, 18,198,168, 63,121, 98,135,136,227,140,100,230,188,237,124,212,165,243, 12,199, 25, +201,144,176,233,194,209,179, 49,204,132,201, 43,248,214,157,250, 35, 54, 54,214,101,192,128, 1, 75, 0,212, 41,176, 88,150, 5, +207,243, 16,139,197,149, 2,186,166,109, 26, 18,189, 26, 7, 52,182,246,146,255,186,116, 99, 47, 57, 17,169,255,241,226, 10, 0, + 84, 42,213, 22, 0, 91,236,237,237,179, 45, 45, 45, 81, 92, 92,252,194,247,143, 16, 98,214,172, 89, 51, 51,169, 84,138, 62,125, +250,216,187,186,186, 38, 50, 12,179, 46, 61, 61,189,193, 74,163,166,200,214,203,218, 52,216, 57, 97, 64,199,224, 54, 86,247,109, + 22, 91,153,137,180,119, 26, 37,154, 89, 19, 0,133, 58,197,227, 43,201, 35,138,200, 51, 89,235,118,221,219,194, 90,100, 57, 0, +181, 8, 44,134,101,111, 23,230, 23,244, 43, 42,214,227,210,229, 88,132,141,104, 10,157,129, 64, 16, 24,168, 75,116, 0, 43, 6, + 3, 96,228,168,119, 65,137, 8,121,217, 25, 96, 89, 54,166,161,199,253, 55,192,220,137, 19, 39,246,155, 55,111,158, 79,185,127, +149, 87,185,127,213, 44, 66, 72, 32,165,180,244, 37,121, 26, 29,217,179,112,198,225,139,155, 11,251,119,214, 60,104, 91, 86, 19, +101,223,182, 25,242,196, 98, 60, 20,177,200,165,244,185,138, 82, 84, 20,124, 85, 45,252,250, 59,195,164, 28, 44,223,198,202,190, + 93,219,183,155, 60,127,222,124,171, 7,215, 47, 96,254,146,111,133,166,237, 66, 10, 87, 29, 58, 94, 92,104,221,168, 71,105, 70, +194, 29, 19,247, 71, 1, 32,164,123, 40, 90,181,232,240,194,202,160,238,101, 30,144,151,206,221, 68,118, 78,186, 73,132, 21,226, +169,182,156, 43, 83, 74,243,171, 67,163,209, 20,196,198,198, 58,167,165,165, 61,151,208,238,237,237, 13, 66, 8,174, 93,187,134, + 95,127,253, 21, 97, 97, 97, 16,137, 68, 16,139,197, 56,127,254,124,113, 67,246, 81, 37,154, 20, 77, 41,237, 74, 8, 9, 81, 42, +149, 53, 86, 15,154,194,165,209,104, 80, 88, 88,136, 19, 39, 78,160,105,211,166, 88,186,116, 41,220, 92, 21,152, 63,127, 6, 4, + 65, 64, 81, 81, 81,165, 63, 80,125,224,121,158, 86, 68,135, 4, 65, 64, 78, 78, 14,124,124,124,176,113,227, 70,172, 89,179,230, +219,140,140,140, 6, 87,185,216,217,217, 89,155,153,153, 77, 24, 48, 96, 64,208,160, 65,131, 16, 18, 18,242,220,250,157, 59,119, +202, 15, 29, 58, 52,219,195,195,163,171, 32, 8,223,165,167,167,215, 89, 22, 92,129,239,191, 47,179, 79,178,232,180, 8,115,134, + 53,194, 59, 31,237,192,170, 85, 17,144,201,100,149,122,237,222, 71, 0, 0, 32, 0, 73, 68, 65, 84,219,176, 44,139,197,139, 23, +215, 41, 94, 4, 74,125, 37,170, 43, 25, 51,102,175,116, 94,182,236, 52, 78,159,126, 6,134, 97,224,234,234, 10,134, 97,240,228, +201, 19, 48, 12, 3, 47, 47, 47, 48, 12,131,244,244,244,138,156,191,124,212, 80,197, 88, 19, 24,134,129, 86,171, 69,106,202, 83, +164, 37, 37, 66, 94,148, 5, 39,107, 11,228,223,139, 70,171,113,239,195,104,172, 51, 39,247, 47, 1,165,244, 20,128, 83, 85, 22, + 29, 32,132, 24, 9, 33,163, 0,236,165,148, 70,148, 47,223,142, 58,140, 65, 59,117,234,212,122,222,188,121,226, 10,219, 12, 55, +207,175, 56,131,193, 32, 0, 64,179, 86,111, 60,167,242, 31, 62,124,136, 85,171, 86,161,164,164, 4,146, 6,100,166,247,234,213, +171, 50, 39, 82, 34,145,192,209,209, 17, 6,131, 1, 28,199, 53,120,106,208,193, 75,249,237,181, 91,231,249,187, 73,155, 53, 49, +247,143,153,167, 61, 17,160, 86, 57,254, 99,197, 85, 85, 80, 74, 23, 41,149,202, 69,130, 32, 80, 74,233,194,138,229,132, 16,153, +167,167,231,197,147, 39, 79, 58,112, 28,135,245,235,215,219,102,101,101,217,190,241,198, 27,115, 0,212, 42,176,106,177,105,168, + 13, 47,101,211,192,243,240,179,182,178, 69, 62,210,160,115, 52,182, 46,112,224,242, 78,101,190,127,199, 45,185, 77, 11, 75,222, +232,195, 20,233,225,110, 97, 11,129,210, 90,141,208,116, 70,227,177, 59,183,110,247,241,244,104,202,254, 28,121, 1, 3, 7, 15, +131, 78,199, 64,107, 36, 32,172, 24,132,149, 32,176, 85, 27, 52,111,217, 10, 20,192,205,235, 87, 56,189,209,120,170, 54,190,191, + 35,220,130, 38,135,185, 5,125,178, 14, 84,160, 53,248, 96,249, 12, 30, 60,120, 25,128,201,245,241, 40, 94,159, 28,230,210,185, +140,167,170, 15,214,244, 79, 38,226,222,117,177,205,133, 91, 95, 75, 66, 58,225,151,156,211, 4, 22,102,191, 85, 17,138,153,151, +179,215,248,187,160, 94,129,229,233,233,105,235, 44,183,248,254,227,113, 99,173,146,239, 94, 69, 90,244, 85, 92,190,148,152,191, +235,224,225,244,162,194,156,113, 13, 16, 87,149,211,121,142,174,141,224, 83,131,192, 50,183,114, 2, 0,248,180,232, 0, 81, 74, +195,108,128,106,138, 94,189,140,184,170, 64,133,168,170,158,208, 62, 97,194, 4,108,219,182, 13, 93,186,116,129,175,175,111,229, +147,114, 67,163,100,213,163, 73, 47, 83, 61, 88, 21,197,197,197,240,242,242,194,214,173, 91, 17, 19, 19, 3, 43, 43, 43,132,133, +133,161,184,184,184, 82, 88,153,154,228,206,243,252,211,147, 39, 79, 6, 14, 31, 62,156,138, 68, 34, 82, 80, 80, 0, 27, 27, 27, +108,220,184,177, 52, 51, 51,243, 92, 67,199,230,238,238,222,223,222,222,126,252,136, 17, 35,216,102,205,154, 33, 59, 59, 27,214, +214, 86,122, 66,136, 20, 0,108,108,108,244,150,150,150,248,224,131, 15, 16, 24, 24,216, 97,246,236,217,237, 93, 92, 92,194,179, +178,178, 14,214,198, 89, 49, 45,184,103, 79,217,236,212,184,117, 9,208,235,203, 4,202,166, 77,155, 80,158,203, 86,137,164,164, + 36,192,132,202, 20,185, 92, 14, 95, 95,223, 26,255,246,193,193,193,184,121,243,102,217, 20,164, 72, 4,103,103,103, 92,190,124, +217,164,178, 76, 90,110,224, 24, 27, 27, 11,127,111, 71,196,156, 62, 9, 71, 11, 49, 94,115,115,129, 50,184, 43, 18, 19, 19,255, +171,209, 43, 66,200, 64, 0, 3, 0, 28,165,148, 30, 34,132, 12, 5, 16, 82,241, 30, 13, 52, 22,229, 56,142, 50, 12, 67, 82, 83, + 83, 13, 22, 22, 22,196,222,222, 94, 36,147,201,160,211,233, 42,133,214,195,135, 15, 17, 25, 25,137,180,180, 52,216,219,219, 51, + 54, 54, 54, 48, 24, 12, 38, 85,148,242, 60,255,130, 61, 67,249,126, 27, 44,174,222, 3, 2,182,125,181,188,145,140, 97,109,252, + 29,251,226,209,189,135, 26,181,170,192,252,255,131,184, 2,128,252,252,252, 45, 0,182, 84,188,119,114,114, 26,195,178,236,124, + 27, 27, 27,155,243,231,207,219, 58, 57, 57,145, 29, 59,118, 24, 23, 46, 92, 88,192,178,108, 62, 33,100, 77, 93,124,181,216, 52, +188, 52,106,178, 99,160, 20,113,170,194, 36, 47,177,157,155,112, 87, 75,175, 76, 77,157,211, 60, 95,220,212,137,180, 12,192,224, +103,241,151,198,112, 73,157,179, 51,179, 24, 10, 33,174, 54, 94, 65, 16,182,207,153,183,120,102, 98,194,109, 79, 51,107, 51, 76, +152, 56, 15,191, 28, 63, 7,194,136,113,241,202, 53,232, 13, 60, 84,121,133, 24, 49,114, 52,148,174,142,136,251,245, 68, 14, 39, + 8, 27,127,239,241,252, 47,129, 82, 97, 67,159,129, 99,236,100,230,101,105,164,130,192,227, 63,255,158, 1,134, 89,135,207, 62, +251, 12, 1, 1, 1, 31,145,178,206, 13,117, 62,240, 18, 34,108, 8,236, 58,210, 78, 34, 43,227,161, 2,143,173,251,231,148,251, + 96, 77,195,198, 45, 7, 3, 91,122, 63,254,188, 46, 31,172,127, 34,106, 21, 88,141, 26, 53,146, 89,138,241,129,189,185,100,214, +199,163, 6, 57, 61, 75,186,135,180,248,219, 0, 0,157, 78, 99,204, 76, 60,255, 90,125,228,229,198,108, 85,163, 29,180,174, 41, + 42,173,182,254, 39,248,234,156, 21, 55,218,234,209,171,134,136,171,154, 56, 1,188,112,131,101, 89, 22, 30, 30, 30, 88,182,108, + 89,189, 62, 88, 53, 28,123,197,242, 16, 0,173, 0, 84, 77,114, 15, 49,165,114,176, 54, 78, 39, 39, 39,228,230,230, 2, 0,186, +117,235,134,110,221,126,171, 83, 48, 24, 12,149, 81, 43, 43, 43,171, 23, 34, 88, 53,113,114, 28,183,252,208,161, 67,195,174, 94, +189, 58, 96,198,140, 25,162, 30, 61,122, 0, 40,243, 28,163, 38,244, 94,171,129,115,212,241,227,199, 89, 65, 16,176,117,235, 86, +220,186,117,139, 90, 90,202,167,202,229, 86, 59,172,173,173,249,130,130,130, 81,239,191,255,254,160,207, 63,255,156, 4, 7, 7, +227,234,213,171,196,199,199, 39, 20,192,193, 58, 56, 1, 0,215,174, 93, 3,195, 48,224,242, 82,240,209,156,189,176, 52, 23, 33, + 33, 33, 1,121,121,121, 47,152,143,154,114, 62, 5, 65,168,188,113, 87,188,130,131,131, 43,167, 27, 59,118,236, 8,150,101,113, +231,206,157, 26,167, 91,171,113, 82, 7, 7,135,202,239,135, 68, 34,193,185,115,231,240,229,151, 95,194,211,222, 22,249,241, 49, +112,233,214, 3,189,199,190,143,176,176, 48,176, 44, 11,123,123,123,160,154, 79, 80,109,199,254,123, 80,149,147, 16,242,150,191, +191,255,220,184,184, 56,101, 96, 96, 96, 11, 66, 72,183,128,128,128,246, 49, 49, 49, 21,239,197,148,210,154,253, 48,106,225,188, +113,227,198,129, 13, 27, 54, 76,124,239,189,247, 36,130, 32,240,201,201,201, 70, 0,196,197,197,133,189,113,227,134,240,243,207, + 63, 67,163,209, 64,169, 84, 50,238,238,238,228,212,169, 83, 66,124,124,252, 53, 74,233, 60, 83,143,189,162, 82,176, 34,153, 93, +163,209,152, 36,174,170,115, 54,106,238,183,180,231, 27,205, 60, 84, 25,119,144,153,158, 4,109,158,157,241,220,137,203, 13, 18, + 87,127,246,223,232, 47,230, 92,252,224,193, 3,119,157, 78, 7,169, 84,138, 77,155, 54, 25,150, 45, 91, 22,167, 82,169,130, 40, +165,154,234, 27,155, 58,206,134, 24,144,214,199, 89,152,139, 95,126, 58,124,163,189,124,240,118,124,148,145, 83,153,184, 72, 9, +177,143, 80,180, 8,178,232, 16,152,206, 28, 93,196, 20,243,165,149, 57,162,213, 57, 41,165,122, 66,200,176,193,161, 35,207,236, +217,179, 91,190,112,209, 34, 92,190, 22,131,220, 2, 53, 4,202, 66, 32, 4,243,231, 47,132,139,163, 61,138, 50, 30,148,234, 12, +134,193,180, 90,203,156,191,251,223,157, 16,102,210,169,159,119,172, 99, 8,132,146,236,251, 50,182, 56,201,226,157,176,193,162, + 97,195,134, 33, 34, 34, 2,177,177,177,155,107, 19, 87, 85, 57, 41,101, 38,197,156,223,187,142, 0,130, 38,231,190, 76,164,126, +108,241,238,168,193,162,176,176, 48, 28,138,188,130, 61, 71, 30,127,183,251,103,122,228,143, 60,166,191, 3,106, 21, 88, 86, 34, +196, 6,181,104,236, 30,220,166,165,153,136,215, 32, 45, 62, 9,121, 37, 90,156,186,151, 92,192, 80,230,135,151,221, 97, 89,238, +132, 4, 41, 41, 15, 94, 88, 87, 80, 80,150,245, 86, 92,220,176,182, 79, 12,195, 60, 23,189,250, 61,145,171,170,227, 84, 40, 20, +149, 55,199, 10, 33, 87,113,195,174,200,241,121, 9,139,134, 57, 41, 41, 41,214, 41, 41, 41,160,148,226,218,181,107,214, 29, 59, +118,156,131,223, 17,189,154, 49, 99,198,115,237, 65,170,254,172,105, 89,125,200,201,201, 41, 1,240,189, 66,161,248,101,230,204, +153,255,234,212,169, 83,240,103,159,125, 70, 40,165, 47,123, 98, 57, 65, 16, 16, 21, 21,133,136,136, 8, 94,175,215,207,205,204, +204,188, 95,101,253, 15, 30, 30, 30, 23, 7, 13, 26,180, 42, 49, 49,145,141,139,139,131, 41, 66, 78,163,209,192,215,215, 23, 28, +199,225,235,143, 60, 80, 92, 28, 8,142,227,192,243, 60, 44, 45, 45,159,235, 67,105,202,223,137, 97,152,231, 34, 35, 21,175,107, +215,174,129,101, 89, 4, 5, 5,225,246,237,219,149, 17,172,250, 34, 78, 6,131, 33, 69,161, 80, 40, 22, 47, 94, 92, 57,174,156, +156, 28,156, 60,121, 18,157, 94,239,140, 22, 31, 76, 64, 70, 70, 6,214,172, 89, 3, 55, 55, 55, 44, 93,186, 20,121,121,121,224, + 56,238,175, 14,155,247,141,139,139, 83,142, 26, 53,234, 89, 76, 76,140, 50, 50, 50,210,118,192,128, 1,150, 35, 71,142,124, 22, + 19, 19,163, 36,132,188, 1,160, 94,129, 85, 21, 60,207,207, 37,132, 28, 95,186,116,233,156,201,147, 39,119,124,239,189,247,196, + 98,177, 88, 72, 79, 79,231,118,239,222, 77,124,125,125, 25,137, 68, 66, 78,156, 56, 33, 92,191,126,253, 87,142,227,190,166,148, + 94,108,200, 62,170,138,171,134,230, 92, 85, 96,170,179,236, 93, 43, 38, 39,104,195,166,101, 76, 51,111,165, 33,124,247,201,212, +139, 87, 31, 60, 98,117,220,212,239,129, 90, 75,252,255,201, 96, 89,118,159,191,191,255,152, 73,147, 38,153,135,132,132,200, 62, +255,252,243,194,226,226,226, 26,197, 85, 77,104,136, 77, 3, 26,104, 64, 90, 5,255,158,251,105,228,212,233,129, 99, 26,143,119, +105,132,211, 37,207,144, 47, 98, 25,107, 91, 6,109,188, 88, 20,171, 30, 58, 29, 57,243,227, 19,212,227,171, 70, 41,189, 65, 8, +233,213, 50,176,245,193,175,151,126,237,188, 96,246, 44,241,193,200, 99,160,156, 1,215,206,159,135, 92,194,211,248, 91,167,179, +117, 6,253, 32,250, 79,115,113, 7,144,113,105,253, 30, 66,200, 97,123,123,251,187, 99,223,123,207,215,223,127, 36, 44, 44, 44, +112,224,192, 1,252,103,253,122,126, 45, 48,124, 11, 33,183, 39, 80, 90,231, 61, 63,251,106, 37,207,157,247,199,142,245,107,211, +102, 60, 44, 44, 44,176,127,255,126,236, 88,187,214,100,158,127, 26,106,159, 34,100, 72,241,175, 15,146,213,215, 30, 36,171, 33, + 80, 42, 80,170, 99, 24,164,150, 24, 12, 75, 19, 31,165,189,148, 24,168,152, 34, 92,242,213,164,151, 30,112, 77,156, 21,162,231, +101,202,178,107, 2,207,243,105, 77,155, 54,125,110, 31,245,253,110, 52, 26,211, 76,164, 95,238,233,249, 66, 95,210, 6,231, 93, + 85,160, 98,218,207, 84,113,101,170, 15, 22, 0,100,103,103,231, 0, 88,169, 84, 42, 15,247,235,215, 47,140, 16,146,245, 50, 99, + 36,132,236,233,222,189,123, 24,165,148,101, 24,102,103, 53,113, 5, 0, 72, 77, 77,125,172, 84, 42,183,122,123,123, 87, 54,128, +174,139, 83, 16,132,199,129,129,129,149,198,159,213, 5, 84, 77,239, 5, 65,168,247,111, 84, 80, 80,128, 14, 29, 58,188,208,115, +146, 82,138,228,228,228,138, 8, 19,128,178,115, 95,151,112, 83,171,213, 19, 62,249,228,147, 45, 98,177,216, 19, 0,169, 16,183, + 60,207,179,223,126,251,173, 25,207,243, 44, 0,194, 48, 12, 39, 22,139,181, 17, 17, 17, 28,199,113, 41, 58,157,110, 66,125,227, +252,131,177,151, 16, 34, 6,144, 31, 23, 23,247, 70,121,228, 42, 45, 54, 54,246,244,158, 61,123, 20, 64,253,246, 9, 53,161, 92, + 48, 93, 36,132, 4,111,218,180,105,238,132, 9, 19, 58,132,133,133,137,186,117,235,134, 95,126,249,133,143,138,138,186,166,209, +104,150, 55, 84, 88, 17, 66,212, 94, 94, 94, 0, 80,105,244, 91, 27, 56,142,171,243,105,205,193, 75,182, 97,244,135,110,102, 91, +151,159, 84,171, 50,244, 87,140,106,253,188, 31,129,216,134,140,231,159,134,172,172,172, 79, 9, 33, 11,215,172, 89,147,241,218, +107,175,201, 36, 18,137,222, 84,113, 5, 52,204,166,129, 82,106,186,243,241,243,159,227, 8, 33,111,174,238, 61,244,112,215,249, +159,120,247,238, 30,100,225,209,200,217, 61, 62, 41, 27, 15,175,254, 82,114,247,200, 87, 79,169, 46,127, 32,165,180,222,254,163, +148,210,235,132,144,166, 51,102,205,168,104,246,220,170,231,169,159,232,255,163,102,207, 75, 86,172, 88,225,235,239,239,143, 3, + 7, 14,224,212,206,157, 24,161, 82,225, 28,203,178,140, 68,226,112,196, 96, 88, 9,192, 20, 97,180,100,213,170, 85,126, 1, 1, + 1,216,183,111, 31, 78,236,216,129,225, 47,199, 83, 27,218, 3,112, 42,255, 93, 5,224, 62,128,182, 0,204, 1,232, 0,168, 1, + 56, 86,217, 62,183,124, 93,197,250, 11, 0,254,210, 68,215, 90,175, 78, 49, 15,158,180,253,163,119,166,209,104,242,124,125,125, + 77,179, 82, 47,135,209,104,172,115,142,150,227,184,180,198,141, 27, 3, 48,221, 77,189, 62, 49,148,155,155,219,206,212,241, 53, + 20,191, 55,215,170, 42,120, 65,120,234,234,234, 42,148,243,214,180,175, 26,151, 81,224, 73, 67,246,147,150,150,246, 8,192,151, + 47, 57, 76,164,165,165, 29,131, 9,205,156, 77,221, 14, 0,242,242,242,254,240, 38,187,132,210,244,207, 63,255,252,183,247, 38, + 8,107, 80, 90,107, 53, 6,165, 52, 6, 64,199, 63,116,144,127, 2, 40,165, 23, 80, 94, 22, 77, 8, 25, 76, 8,121, 19,192, 9, + 74,233,129, 63,136,191, 82,104,109,221,186,117, 42,165, 20, 69, 69, 69,107, 27, 42,172, 42,144,157,157,125,182,254,173, 76, 67, + 94,182,254,236,238,205,105, 61, 52, 5,134,169,219,212,122,147,250, 33,254,127, 0,165, 84,235,236,236,252,195, 59,239,188,211, + 9,192,143,127, 4,231,239,176,105,168, 17,148,210, 39,132,144,215,206,205,248,114,236, 57, 91,171,254,224, 69,205,160,103,142, + 64,159,251, 11,128,239, 77,137,130, 87,225,210, 2, 88, 85,254,250,127,131,114,255,170,169, 99,198,140,193,194,133, 11,113, 98, +229, 74,195,135,132, 20,138, 1,122,188,236, 1,147, 33,192,108, 83,121,222,125,247, 93, 44, 92,184, 16, 71,191,254,250,165,120, +234,129, 19, 33, 36, 18, 0,230,204,153, 51,111,217,178,101,118,115,231,206,109,181,124,249,242,165,229,239,239, 85,172, 7, 0, + 74,233,128,185,115,231,182,172,178,190, 24, 64,189,198,200,127, 40,170, 62,161,255,209, 47, 0,189, 94,113,190,226,124,197,249, +138,243, 21,231, 43,206, 87,156,175, 56,127,231,171,127,153,100,169,253,103,109,191, 87, 89,246, 87,142, 23,191, 63, 89,233, 21, + 94,225, 21, 94,225, 21, 94,225, 21, 94,225,191,128,170, 81,171,151, 89,255,103,130, 0,232, 85,211, 10,218,128, 42, 6, 66, 72, +141, 28,117,161, 62,254, 87,156,175, 56, 95,113,190,226,124,197,249,138,243, 21,231, 63,143,179, 62,238, 90, 62,223,159, 16, 18, + 73, 41, 29, 80,219,207,114,206, 23,126,175,178,172,193,157, 71,126, 23,254,204,240, 24,254, 38, 97,201, 87,156,175, 56, 95,113, +190,226,124,197,249,138,243, 21,231,127,151,179,158, 87,127,148, 85,154,210, 57,115,230,204,165,127,131, 41,194, 58, 74,112, 14, +176,233,233,176,150, 74, 45, 36, 0,160,215,151, 26,220,221, 81, 4, 12,253,175, 53,162,125,133,191, 39, 8, 33, 10, 0,160, 38, + 52,133,110,200,182,175,240, 10,175,240, 10,175,240,255, 6, 57,180, 60, 50, 5, 32, 7, 0, 41,127,175, 47,255,153, 3,148, 37, +183, 87,251,253,185,245,127, 37,106, 17, 88, 7, 88,149,202,194, 81, 36,202,247,227,121,109,115, 0, 16,137,152, 4,149,202, 46, +209,209,241,128,234,101, 68,150,147, 66,113, 75,204,178,238,166,108,107,228,249,116, 85,118,246,115, 86,239, 20,248,219, 11, 59, + 83,197,195,239, 17, 25,127,133, 64,113,114,114, 82, 40, 20,138,183,173,173,173, 95, 47, 40, 40,184,158,147,147,115, 40, 39, 39, +167,198,253, 17, 66,150, 17,130, 89,229,191,127, 67, 41,157, 91, 27,111, 67,182,173,225,179,190, 22, 22, 22, 31, 17, 66, 2, 0, +128, 82, 26, 91, 90, 90,186,137, 82,250,162,225,218, 63, 28,132, 16,115, 0,131, 68, 34,209,187,142,142,142, 29,178,178,178, 62, +167,148,214,233,190, 93, 7,151, 8,192, 12, 91, 91,219, 48, 91, 91, 91,159,188,188,188, 71, 69, 69, 69,251, 0,172,162,148,214, + 91,242,252,197, 20,183,215,187,133,116, 91, 16,117, 34,106,201,162,117, 25, 87, 95, 88,255,169,155, 67,159,222, 93, 22, 70, 29, +185,178,120,238, 6,211,218, 35, 85, 25, 27, 3, 84,230,145, 10, 40,123, 74,253,239, 54,115,172, 3,132,144, 78, 0,230,161,108, +204,171, 40,165, 13,238,138,240, 87,130, 16, 98,169, 80, 40,190, 6,240,150, 72, 36,138, 75, 79, 79,255,128, 82,106,170, 29, 77, +125,220, 98, 0,246, 0,242, 76,249, 30, 85,249,156, 8,101,229,250, 1, 40,179,211,184, 65, 77,176, 98,248,167, 65, 38,147,173, +117,113,113, 25,175,209,104, 74, 9, 33,180,170, 95, 35,199,113,105, 57, 57, 57,127, 90, 37,252,127, 17,127,109, 5,224, 31,128, + 26, 5, 86,122, 58,172, 69,162,124,191,103, 89, 49, 35, 50, 50,163,135, 3,128,155,107,171,125,206, 46,129,123,211,211,165,134, +246,189, 67,229, 98, 11,209, 38,150, 21,183,214,234,117,142, 98,145, 88,101,224,140,119, 24, 61,253, 40, 51, 33,162, 70,147, 68, + 49,203,186, 63, 77, 60,231,204, 25,242, 32, 54,115,131,216,252, 5, 47,168, 74,184,185,185,189,212,193,216,219, 55,177, 50,200, +204,166,138,197,108,111,129,114, 1, 84, 0, 24, 34,142,229,120,227, 25,137, 78,183, 58, 47, 47,169, 65,253, 2,171,162,185, 35, +113,161, 64, 24, 8,122,131,226, 20, 1,246, 36,168,168,201,190, 80,166,138,135,223, 41, 50,170,126,118, 13,165,244, 83, 83, 63, +107, 42,148, 74,165,221,144, 33, 67,214,126,249,229,151,230,114,185,156,164,164,164,132,204,158, 61,251, 13,165, 82, 57, 61, 45, + 45, 45,163,218,120, 20,132, 96,150, 32,148, 25,148, 50, 12,153,173, 80, 40, 44, 88,150,125,161,121, 40,207,243, 22,132, 96,146, + 32,148, 53, 28,103, 24, 50,139, 16,178,206, 20,161,104,110,110, 62,178, 67,199,206,211,191, 94,177, 74,174,112,118,182,228,120, +193,240,228,233, 83,203, 5,115, 63,237,104,110,110,190, 78,163,209,152,212, 64,182,218,216, 9,203,178, 35,100, 50,217, 0, 0, +254,229,139,227,117, 58, 93, 36,207,243,123, 77,189,145,187,184,184, 92, 96, 89,182, 81, 67,246,205,243,124, 74, 86, 86, 86, 80, +253, 91,190, 8, 66,200, 48, 79, 79,207,239,187,118,237,106,209,161, 67, 7, 72,165, 82, 44, 92,184,112, 6,128, 58, 5, 86,133, +144,178,176,176, 24, 97,105,105,217, 88,173, 86, 39,105, 52,154,131, 82,169,180,215,186,117,235, 60,186,116,233, 98,149,157,157, + 77, 88,150, 85, 68, 70, 70,254,107,253,250,245, 33,132,144,158,245,221,220, 10,147,232, 2,217, 91,254,193,133, 73,231, 22, 0, +232, 87,125, 61,167, 53,123,151,178, 30, 3, 52,244,118, 42, 26, 80, 34, 79, 8, 97,196, 98,241, 58, 23, 23,151, 49, 90,173, 86, + 11,128, 18, 66,168, 66,161,168, 88, 15, 0,208,235,245,249,249,249,249,205,234,226,106,222,188,249, 77,150,101,149,181,173,231, +121, 62, 45, 33, 33,225,143,184, 97,205,202,202,202,122, 83, 44, 22, 19, 15, 15, 15, 22,128,201, 2,139, 16,226, 7, 96, 62,202, +110, 50,155, 40,165, 60, 33,164, 59, 80,246,255, 14,224,155, 10,193,198,178,236,166,102,205,154,189, 29, 31, 31,255, 29,165,116, +201,203, 14,214,197,197,101,203,198,141, 27,135, 15, 28, 56,144,205,201,201,113,127,237,181,215,118, 1, 8,126, 89,190,242,227, +144, 2,152,235,226,226,242,113, 80, 80,144,195,237,219,183,243, 8, 33, 27, 1, 44,167,117,120, 77, 17, 66,148, 0,122,217,218, +218,246,156, 63,127,190,124,192,128, 1,216,186,117,235,155,219,182,109, 83, 19, 66,206, 0, 56,253, 71,137,191,255,117,176, 44, +187,110,196,136, 17, 99,118,237,218,101,241,244,233, 83, 11,119,119,247, 74,211,107, 66,200, 75,223, 63, 95,225,143, 71,141, 2, + 75, 42,181,144,240,188,182,121, 70,102,244,240, 55,186,126,107, 3, 0, 23,206,127, 50,220,217,165,101,172, 84,106,145, 40,179, + 54,139, 8,125,171, 87,235,161, 3,186, 18,165,171, 51,210, 50,159, 41,254,189,231, 68,223,200, 19,231, 34, 80,102,252, 85, 35, + 56, 67, 30,204, 13,167,113,255,210,122, 56,118,203,192,134,163,105,184,122,247, 9, 74, 11, 85,104,228, 98,142, 21, 83,251,192, +197,206,226,165, 14, 68,174,240,235,206,152, 89,236, 29, 53,242, 29,155,183, 7,249,139,189, 92, 92, 64,169, 12,137, 73,234,206, +199, 78,158,107,127,112,255,238,143,228, 10,191, 17,234,236, 68,147, 47,106,109,221,136,121,137, 1,131, 68, 44,249, 87,112,199, +150, 61, 71,190, 25,204,180,240,111,138,184,123,241,125, 14,159,189,182,162,133,130, 57,195,241, 52,220, 82,130,159,110,101,212, +110,196, 87,147,208,232,217,179,103, 27,115,115,115,125,213,237, 52, 26,141,148, 16,244,124, 25,145, 81,177, 15,189, 94,199,136, +197, 82, 48, 12,153,222,170, 85,171, 70, 42,149,234, 2,195, 48, 59,211,210,210, 76,234,241, 86,129,201,132, 72,243, 69,162,182, +140, 76,230,202,235,245, 14, 0, 64,164,210,124,165,157, 93,224,252,121,243,228, 44,203, 10,185,185,185, 40, 45, 45, 37,239,191, +255,190, 89, 82, 82, 82, 40,128,245,245,140, 17,219,182,109,243,115,117,117,213, 87, 95,151,153,153, 41, 29, 56,240,237,134, 12, +177,130,211,175,211,235, 93,166,157, 56,113,220,191, 40, 47, 95,187,109,205,214,219, 70, 51,115,173,119,115, 63,201,166,173, 59, +172, 63, 24, 51,250, 19, 66,200, 29, 74,169,201,253,228, 8, 33,158,230,230,230, 17, 43, 87,174, 12,232,222,189,187,216,217,217, + 25,217,217,217,136,143,143, 15, 56,123,246,236,160, 29, 59,118,204, 32,132,132, 82, 74, 77,113, 92,247, 61, 19,254,189,179,165, +189, 3,120,163, 17,110,173,218, 84,228, 47,224,225,217,147,224, 12, 6, 8, 70, 35,252, 7, 12, 2, 80,214,170,167, 69,139, 22, + 47,229,150, 75, 8,113,107,217,178,229,127,150, 46, 93, 42,209,233,116,184,118,237, 26,206,157, 59, 39,100,102,102,214,105,100, + 75, 8, 17, 17, 66, 78, 46, 90,180, 72, 25, 20, 20,100,165, 82,169,192,243,188,227, 79, 63,253,244, 81,155, 54,109,172, 61, 60, + 60,164,225,225,225, 80,171,213,224, 56,206,190,113,227,198,246, 35, 71,142,212,135,135,135,207, 0,240,117, 77,156, 95, 76,113, +123,189, 40,137, 46,200, 34,141,251, 54,107,251, 46,178,200,241,190,211,251,185, 30,179,110, 66, 42, 35, 89,253,154, 52,177,106, +220,220,114,182,220, 58,208,190, 40,253,244,236,126, 77,154,108, 59,150, 84,255, 67, 16, 33,132, 97, 24,102, 93,104,104,232,168, + 61,123,246, 88,196,199,199, 91,248,251,251, 67, 16,132, 74,199,252, 10,163, 88, 95, 95,223,122,207, 27,203,178,202, 51,103,206, + 56,155,155,155,191, 96,202, 91, 82, 82,130,129, 3, 7,214,203, 97, 34,170, 94,111, 27,250, 55,254,226,241,227,199,195, 34, 34, + 34, 70,207,154, 53,203, 23,192, 36, 0, 11,115,115,115,187, 2,128,131,131,131, 20,192, 57, 66,200,216,153, 51,103,126, 56,103, +206, 28,188,249,230,155, 11, 9, 33, 95,189, 76, 84,143, 16,194, 58, 58, 58,190, 57,112,224, 64,214,104, 52,194,210,210, 18, 70, +163,177, 73, 67,121,170,113,202, 36, 18,201,207, 43, 87,174,236, 61,114,228, 72,136, 68, 34, 8,130, 96,127,242,228,201,207,198, +140, 25, 19, 76, 8,233, 87,147,200, 34,132,188,251,225,135, 31, 14,121,231,157,119,208,174, 93,187, 74,115,217,149, 43, 87, 98, +241,226,197,242,147, 39, 79, 14, 10, 15, 15, 31, 68, 8, 57, 72, 41,253, 71,123,153, 17, 66,190, 25, 49, 98,196,168, 93,187,118, +201, 1, 96,197,138, 21,152, 54,109, 26, 20, 10, 5,228,114,249,127,123,120,175, 80, 13,245, 54,123,174, 9,165,165,165,109,230, + 78,254, 23, 24,166,236, 41,177,169,143, 39,150,205,251,128, 28,142, 60,209,166,174,207,137,205,220,112,255,210,122,200, 60,166, + 66,103,228,240,235,221,199, 56,181, 34, 4, 0,224,215,111, 62,116,134,158, 0, 0, 74,169,189,212,220,252, 27, 61,207, 95,134, +139,203, 53, 36, 39,215, 57,119, 42, 87,248,117,119,114, 81, 68,110,222,252,181,121, 64,147,102, 48,112, 70,164, 63, 75, 7, 33, + 50, 40,221,173, 48,246,221,126,226,174, 93,221, 28,191,248, 98,203, 47,150, 78,126,131, 75,114, 18,235, 53,250,108,230, 68,126, + 12,110,227, 59,124,100,255, 32, 89, 96, 64, 75, 72,100,230,149,235,218,182,107,135,182,237,218, 49,115,212,197,189,175,223,184, +213,251,192,201, 95,117,205,156,200,190,251, 57,244,189, 58, 40, 43,221, 41, 9, 33,152, 50,101,202, 11, 13,137, 51, 51, 51, 17, + 21,245,187,102, 13,158,219,199,151, 95,126, 41, 47, 40, 40,232,245,239,127,255,251, 13,119,119,247,149,233,233,233,191,154, 66, +242, 47, 66, 26, 65, 38,235, 57,102,213, 42,161,245,219,111,179,182, 46, 46,140,192,243, 36,227,209, 35,135, 53,235,215,119,203, +123,248,208,188,196,222, 62, 47, 95,163, 41, 77, 76, 76,132,153,153, 25, 17,137, 68,237,171,243, 80, 74,179, 9, 33,223, 48, 12, +153, 77, 8,129, 76,102,150, 56,113,226,196,219,229,171, 27, 29, 57,114,196,226,173,183,222, 42, 5,240, 20, 0,100, 50, 51,119, +150,101,252,202, 18, 4,241,141, 41,194,210,210,210,114,242,146,165,223, 88, 22,229, 21,104, 12, 37, 37, 70,103,107, 57,129, 92, +206, 22, 23,169,139, 50,178,114,180,243, 63, 95, 44,154, 48,246,157,201, 0, 62, 50,233, 4, 18,226,249,218,107,175, 93,143,136, +136,112,118,112,112, 64, 65, 65, 1,114,115,115,113,253,250,117, 8,130,128,208,208, 80, 89,231,142, 29,218,204,155,191,224, 42, + 33,228,117, 83, 68,150,165,189, 35, 86, 4,181, 6, 0,124,246, 52,183, 98, 63,216, 58,108, 64,229, 54,139,211, 10, 1, 0,102, +102,102,191,167,213,211,235, 61,123,246,148, 0,192,184,113,227,138,138,139,139,151, 1,216, 69,235, 48, 67, 45,199,140, 5, 11, + 22,184,251,248,248,120,237,218,181, 11,106,181, 26, 0,156,125,124,124,208,172, 89, 51, 62, 42, 42, 10,126,126,126,176,178,178, +194,133, 11, 23,240,235,175,191,162,109,219,182, 86, 18,137,100, 56,106, 17, 88,221, 66,186, 45,144,189,229, 31,220,172,237,187, +144, 91,187, 98,219,238,189,184,127,107, 71,176,206, 16,191, 96,217, 36,247,119, 52, 84,246,158,210,215,106, 78,163,118, 93, 29, +154,182,124, 27, 94,109,111, 59,106,249,139,143, 23,126,220,120,185,200, 76,187, 99,209,202,140,220,154,120,203,167, 5, 87,132, +134,134, 14,219,179,103,143, 45, 0,196,196,196, 32, 59, 59, 27, 78, 78, 78, 48, 51, 51,131, 88, 44,174,236, 31,106, 42,204,205, +205,145,153,153, 9,131,161,172, 57, 0,207,243, 40, 46, 46,134,139,139, 11, 0,224,139, 47, 8,179,104,145,105,174,227,132,144, +160,142, 29, 59,238,244,242,242,242,168,186,188,127,255,254, 8, 11, 11, 3, 0,116,237,218,181,231,208,161, 67,105,133, 16,204, +204,204, 84,223,184,113,163, 55,165,244, 90, 77,156, 12,195,104,210,211,211, 49,115,230, 76, 60,121,242,228, 99, 66, 72, 50, 0, + 51,169, 84, 90,177,137,148, 16,226,215,178,101,203,117,211,166, 77, 67, 82, 82, 18,226,226,226,174,191,236,148, 41,165,148,247, +246,246,126,104, 52, 26,219,113, 28, 7,141, 70,131,193,131, 7,155,217,219,219,103,179, 44,155,160, 82,169, 70, 83, 74, 51, 77, + 60, 31, 82, 0, 94, 34,145,104,195,204,153, 51,123,246,234,213, 11,209,209,209,136,136,136,192,200,145, 35,209,183,111, 95,172, + 92,185,178,235,164, 73,147,230, 0, 88, 84, 3, 69,207, 77,155, 54,129,231,249, 23,254, 55,204,204,204, 16, 20, 20,132, 22, 45, + 90,224,240,225,195, 61, 1,252,163, 5,150,151,151,215,196, 61,123,246, 84, 42, 41, 55, 55, 55,200,100, 50, 84,249, 30,188,194, +255, 16,106,188, 2,233,245,165, 6,145,136, 73,112,115,109,181,239,194,249, 79, 42,167, 8, 1, 38, 65,175, 47, 53, 0, 0, 47, + 80, 20,149,114, 48,151, 49,120,154, 85,140,123,143, 84, 47,240,208,106,165,150, 98,115, 79,200, 58, 60, 5,165, 20,122, 3, 15, + 93, 97, 22,150,253, 82,138,248, 52, 45,244, 37,249,208, 27,202,210,172, 28, 29, 29, 69, 39, 78, 28,155,118,250,244,217, 15,127, +248,225, 7, 54,205,198, 38, 14,133,133,109,106,226,180,183,111, 98, 37,178, 52,223,247,221,230,133,230,148,125,132,196,148, 18, + 52, 85,118,128,163,173, 7,178, 84, 37,184, 28,119, 20, 9, 15, 34,225,227,234,133,169,147,251,154, 45, 89,186,107,175,157,157, +143,103,126,254,227,162,218,198, 89,142,119,183, 28, 79, 4,151,247, 8,124,110, 18,248,226,140, 23, 54,144, 59,121,162,109,119, +119, 56,121, 52,145,189, 55,117,241,187, 0,222,171,137,147, 82,154,205,178,236, 38,134, 33, 31, 17, 66, 16, 16, 16,248,120,237, +218,181, 47, 68,113, 0,232, 3, 2, 2, 31,179, 44,227, 67, 41, 5, 33,204,119,130,192,103,215,196, 89,195,185,206, 38,132,124, + 35,149,202,102, 1,128,139,139,235,163, 99,199,142,233,135, 14, 29,138, 21, 43, 86, 72,230,204,153,243,169,151,151,215,164,228, +228,228,172,106,159,123,142, 51,148, 16, 79,247, 38, 77,250,124,117,249, 50, 21, 27,141, 36,239,250,245,162,130,204, 76, 46,171, +184, 88,186, 63, 33,225,205,241,159,126, 42,245,240,240,192,165,200, 72,135,156,146, 18, 90,160,211,105, 10, 10, 10, 40,199,113, +215,107,226,164,148,206, 85, 40, 20, 22,219,182,109,243,155, 56,113,226,237,140,140,140,185, 0,224,230,230,182, 12, 64, 11, 0, + 79,171, 44,195,230,205,123,211,223,127,255,253,196,236,236,236,231,166, 70,235, 56,246,150,206, 78, 78, 22,187,183,132, 71,219, + 91,153, 51,142, 74, 87, 70,108, 99, 35,230,100, 22, 18, 74,161,245,241,105, 98, 1,160,101, 45,231,236, 57, 78, 66, 8, 49, 55, + 55,143,248,249,231,159,157,197, 98, 49,120,158,135,147,147, 19,158, 60,121,130,130,130, 2, 20, 23, 23,227,113, 66, 60,188, 61, + 60,240,197,156,217,174,147,102,207,137, 32,132,180,171,122, 19,171,105,156,188,209,128,106,251,169,177,235, 64,213, 60, 10, 19, +143,189, 58,158,164,164,164, 64, 46,151, 35, 32, 32, 64,126,249,242,229,139,181,137,171,170,156,102,102,102,195,187,116,233, 98, +181,123,247,110,180,109,219, 22, 54, 54, 54,136,138,138, 66, 76, 76, 12, 12, 6, 3,163, 86,171, 97,101,101,133,229,203,151,195, +203,203, 11, 69, 69, 69, 72, 73, 73,113, 16,139,197,142,181,113, 70,157,136, 90, 82,152,116,110, 65, 22, 57,222,119,219,238,189, +120,127,228, 8,184,208, 71, 23,109,154,144, 37,125,222,234,242, 25,101, 61, 6, 88, 90,181,178,243, 13,120, 11, 18,169, 28,147, +102, 45, 70, 98,236, 17,187,210,226,232,143, 9,159,234, 1, 96, 74,117, 78, 82,118, 98, 24, 15, 15,143,241,251,247,239,183,170, + 88, 94,209,147,176,170,176,170,120,213,116,158,107,252, 27,241, 60, 12, 6, 3, 12, 6, 3,120,158,135, 74,165, 66,113,113, 49, +108,109,109,203, 54, 88, 4, 16, 16, 66, 81,179, 96,169,198, 57,250,244,233,211, 30,150,150,150,213,183,129, 74,165, 2,199,113, +176,176,176,168,220,167,209,104,132, 86,171,149,183,104,209,226, 35, 0,215,106,226, 20, 4, 97,250,240,225,195,187, 92,187,118, +173,241,250,245,235,161,215,235, 87,100,101,101, 97,200,144, 33, 16, 4, 1, 61,123,246,236, 68, 41,189, 63,127,254,124, 0,192, +180,105,211,140, 37, 37, 37, 19, 77, 57,246,154, 64, 8,105, 49,116,232,208,198,103,206,156, 65,112,112, 48,116, 58, 29, 86,174, + 92,105,189,121,243,102,235,240,240,112,167, 89,179,102,125, 15, 32,164, 46,206,114, 97, 53,175,111,223,190,211, 7, 14, 28,104, +153,158,158, 14, 91, 91, 91,236,221,187, 23,203,151, 47,191,160,215,235,231,133,135,135, 47,139,136,136, 8, 30, 57,114, 36, 86, +174, 92,249, 49, 33,100, 9,165,212, 88, 19,231,227,199,143,225,228,228, 4,107,107,107, 0,101,141,236,239,220,185,131, 83,167, + 78,161,121,243,230,245, 30, 83, 3,254,143, 76,198, 95,205,169,209,104,180, 41, 41, 41,242,175,191,254, 26,174,174,174,240,242, +242,130,153,153, 25, 8, 33, 48, 26,141,160,181,232,105, 83,198,217,173, 27, 17,169,210,237, 6,218,216,218,125, 76, 41, 21, 21, + 22,230,111, 49,160,224, 64, 82, 18,173,233, 94,245,167, 28,251, 63, 13, 34, 0, 32,132, 80, 74, 41,169,248,233,238,142, 34,149, +202, 46,209,217, 37,112,175,179, 75,203,242,190, 92, 76, 2,203,218, 37, 42, 20,165, 69, 0, 96,224, 40,174, 36, 20, 32,250, 97, + 22, 98, 30,102,193, 82,102, 90,155, 26,157,129, 43,171,179,164, 20, 90,245,111, 15,169,134,210,124,232, 12,101,233, 28,122, 93, + 41, 10,115,226,200,176,193,189,205, 62,252,112, 2, 92, 93,221,157,106,161,131, 65,102, 54,117,210,180, 55,109,237,109,197,136, +188,124, 28,157,154, 15,134,153, 76,140,220, 66, 45, 64,128, 7,143, 78, 1,130, 21, 98, 19, 83,208,177,165, 5, 66,250,248,203, + 15, 29,184,255, 41,128,133,166,140,151, 75,187, 14,137,111, 63,136,121, 35,140,170,251, 16, 10,146, 1, 75, 23,104,136, 28,185, +153,201, 72,184,120,208,164, 22,165, 60,207, 79,114,116,116,124, 54,119,238,220, 32, 63, 63, 63,253,164, 73,147, 98,159, 60,121, + 50,191,234, 54,222,222,222, 95,109,216,176, 1,137,137,137, 79,151, 45, 91,118, 73,165, 82, 53,168, 61, 13,165,116, 14, 33,100, + 45, 0,100,102,102,170,126,254,249,231, 86, 23, 46, 92,248,104,205,154, 53, 78, 31,127,252,177,100,242,228,201,163, 1,172,168, +237,243,147, 9,145, 90,202,100,189,190,186,112,129,114,105,105,186,255,124,251,173,116,227,149, 43,243, 13,130,224,230,232,236, + 76, 58,119,236, 88, 98,193, 48,170,220,236,108,206,169,113, 99,246,201,169, 83, 14,212,220, 60,227,216,177, 99, 69,106,181,250, + 96,109,188, 44,203,150,214, 52, 45, 88, 19, 92, 93, 93,245, 53,229,104,213, 6, 66, 72,145, 64,169,193,206,199, 27,125,122,118, +110,250,240,254,163, 71, 50, 27, 91,214,215,183, 81,179,184,132,167,215, 4,142,211, 17, 66,138,234,103, 2, 88,150, 29,177,118, +237,218, 64,107,107,107, 8,130, 0, 27, 27, 27,228,228,228, 64,175,215,163,168,168, 8,250,226, 66,232, 11, 11, 17,147,252, 4, + 93,186,117,195,176,190,125,252,195,127,250,121, 4,128, 61,117,241,186,181,106, 83, 25,185, 90,220,200,161,114,249, 23,169, 5, +149, 98,235,235, 54,190,144,200,229,232, 61,125,142,169,135,254, 2, 40,165,183,165, 82,233,209,208,208,208, 55, 63,253,244, 83, + 38, 51, 51,243, 56, 33,164, 11,165, 52,174,174,207,201,229,242, 38, 21,130,194,198,198, 6,107,215,174,133, 66,161, 64,105,105, + 41,110,220,184, 65,149, 74, 37, 57,119,238, 28,148, 74, 37, 84, 42, 21, 12, 6, 3, 74, 74, 74,178,244,122,125,173,211,226,229, +211,128,253,166,247,115, 61,118,255,214,142, 96,119,242,248,198,240, 25, 93, 31,222,143, 73, 72, 57,121,234,242,151,156,214, 44, +181, 32,237,244,108,159,246,183, 29, 63,158,249, 5, 54,172, 88,132,251,215, 46,228, 41, 60,139, 54,154, 19,221,143, 29,123,215, + 62,222,146,146, 18,109,124,124,188, 85,116,116, 52, 8, 33,176,177,177,129,133,133, 69,141, 34,203, 84,240, 60, 95,249, 83,165, + 82, 33, 39, 39, 7,137,137,137,216,177, 99, 7, 50, 50, 50, 28,215,216, 88,103, 57, 74, 37,209,146, 2, 50,207, 96,160,183,235, +161,219,210,187,119,239, 17,158,158,158, 86, 85, 23,182,111,223, 30, 19, 38, 76,192,119,223,125,135, 43, 87,174, 60,215,239, 50, + 43, 43, 43,211,104, 52,254, 88, 27, 33,165,180,128, 16,210,119,240,224,193,183, 46, 94,188,104,189,125,251,118,112, 28, 87,227, +107,219,182,109,248,245,215, 95, 23, 82, 74, 19, 76, 62, 1, 85, 64, 8,105, 62,100,200,144, 11, 59,119,238,180,205,201,201,129, + 74,165,130, 90,173, 70, 73, 73, 9,120,158, 71,179,102,205, 8,199,113,117,230,181, 17, 66,100, 78, 78, 78, 71,207,159, 63,223, +189, 89,179,178, 77,141, 70, 35, 46, 95,190,140,183,223,126,187, 72,175,215, 15,161,148,230, 18, 66,230, 30, 56,112,224, 74,199, +142, 29,209,190,125,123,251,228,228,100,123, 0, 53, 70,174,213,106, 53,212,106, 53,196, 98, 49, 92, 83, 65, 51,158, 0, 0, 32, + 0, 73, 68, 65, 84, 92, 92,176,100,201, 18,232,245,101,151, 21, 63, 63,191,138,253, 50, 0,214, 52,111,222,124,112, 66, 66,194, +114, 74,233,198,151, 57, 7,255,171, 32,132, 16,177, 88,140,113,227,198, 65, 36, 18,193,220,220, 28, 90,173, 22, 70, 99, 89,157, + 64,185,192,106,208,244,179,175,175,149,131, 8,146,247,253,252,222,152, 58,108,202, 0, 39, 87, 55,119,216, 90,203, 16, 31, 31, +215,229,236,153, 83,223,182,104,230,180, 89,208, 27, 55, 39, 60, 41,248,211,155,208, 87,215, 34,127,246,254,254,108,212,114, 5, + 26,202, 59, 58, 30, 80,165,167, 75, 13, 82,169, 69, 34, 80, 22,213, 42, 19, 87, 67,121, 96, 55, 56,131,177,252, 2, 65,203, 95, + 38, 10, 44, 35,143,135,247, 99,113,241,228,207,112, 44, 77,135,234,113,107, 64, 18, 8,189,166, 16, 90,125,217,147,190, 32,240, +184,123,235, 12,138, 10,243, 16,208,110, 0,192, 48,181, 78,109,217, 56,144, 1,157,219,182, 98, 31,166,196,162,189,223, 80, 52, + 86, 6, 35, 57,179, 8, 5,106, 29,242,139,180,104, 29, 48, 7, 57,249, 26, 20,149,106, 17,247, 48, 28,238,110,141, 25, 34,122, +212, 19, 38, 10, 44, 93, 92, 4,116, 9,135, 33,241,234, 2,105,179,183,193,122, 5, 33, 37,250, 28,238, 30, 91,131,180,123,151, + 64, 5, 30,174,126, 29,234, 39, 2,192,178,236,150,147, 39, 79,182,126,227,141, 55, 68, 61,123,246, 12, 80, 42,149, 1,105,105, +105,177, 0,160, 84, 42, 3,250,246,237, 27,224,236,236,140,117,235,214,149,178, 44,187,197, 36,210,106,168, 54,173,118,219,213, +213,117,101, 68, 68,196, 55, 19, 38, 76,128,139,139, 75,139,186, 62,155, 35, 22,191,246,222,210,165, 84,204,178,116,207,134, 13, +146, 47,142, 31, 95,245,195,143, 63, 74,122,116,239, 78, 40,165,184,115,231,142,197,215, 27, 54, 88,140, 26, 56,240,105,242,179, +103,220,249, 43, 87, 12,153,105,105,197,207, 74, 74,190,200,200,200,120,169, 70,208,191, 23, 70,163,241,234,147,199,143,148,109, + 58,180,118,186, 29,247, 56, 46,164,103,231,215, 25,134, 97, 18, 30, 37, 95,117,114,178,182, 56,115,242,180,193,104, 52,190, 80, +189, 86, 19,100, 50,217,128, 30, 61,122,136,242,243,243,225,230,230,134,156,156, 28,164,167,167,151, 69, 24, 10,243, 97, 40, 44, +132,177,168, 0,124,137, 26,143,111, 92, 71,235,198, 62,178,253,101, 73,240,117, 10,172,138,167,202,234,209,148,170,145, 44,169, +149, 21,164,114, 57, 72, 3,167, 7, 9, 33, 3,109,109,109,103, 23, 20, 20, 28,165,148, 46, 49, 24, 12,147,102,207,158,221,126, +253,250,245,142, 95,125,245,149,245, 7, 31,124,176,159, 16,210,154, 82,170,171,141, 67,173, 86, 39,113, 28,231, 8,192,249,204, +153, 51,112,118,118, 70, 97, 97, 97, 69,100, 69, 95, 90, 90,106,150,155,155, 11,157, 78, 7,189, 94, 15,107,107,107,220,188,121, + 51,159,227,184,159,235, 27,159,117, 19,178, 68,103,136, 95,224,224,111,153, 97,224,236,186, 62,203, 19,242, 23,173,204, 88, 12, + 96, 85,191, 38, 77,182, 25,132, 11,143, 31,196, 30,177,123,114, 35, 42, 47,227, 65, 73,227,109,191, 60,170, 53, 7,171,252,202, + 43, 16, 66,104,179,102,205,160, 82,169,192,178, 44, 44, 44, 44, 32,151,203,209,188,121,115,164,166,166,190,180,192,226, 56,174, + 82, 92, 69, 70, 70, 34, 51, 51, 19,187,119,239,134,135,135, 7, 3,192, 41, 53, 53,181,247,176, 97,195, 58, 58, 56,216, 45,203, +205,205,175, 53,175,141, 82,122, 7,128,117,213,101,132,144,238,142,142,142,103,117, 58, 29, 30, 61,122,132,159,126,250,169, 27, +165,244,188,201, 3, 44,227,125, 68, 8,233, 27, 20, 20,180,163,109,219,182, 77, 40,165, 8, 12, 12, 68, 88, 88, 24,194,195,195, +113,247,238, 93, 20, 22, 22, 10,167, 78,157,250, 1,192,202,134,112,147,223,238,108,205,134, 12, 25,114,105,215,174, 93,118,185, +185,185,208,104, 52, 40, 41, 41,193,254,253,251,209,165, 75, 23, 56, 58, 58, 98,231,206,157, 28,165,244, 72, 29, 92,102,182,182, +182, 71, 47, 93,186,212,173,105,211,166,136,139,139,195,153, 51,103,208,168, 81, 35, 72,165, 82,140, 30, 61,218,250,187,239,190, +251,132, 16,178, 92, 44, 22, 47, 25, 50,100, 8,120,158,199,229,203,151,115, 1,212, 91, 73,106, 52, 26, 81, 80, 80,128,130,130, + 2,152,155,155, 87,156, 27,160, 44, 69, 98,251,154, 53,107,198, 76,157, 58, 21, 77,154, 52, 89, 66, 8,249,142,190,100, 67,233, +255, 37, 52,107,102,215, 82,202,202,166, 72, 36, 98,135,252,252,252,202,107,135, 94,175,135, 78,167,123, 46,114, 37,145,136, 29, + 58,180,241,250, 69, 83, 90, 60,239, 94, 98,126,173,141,203, 91, 52,181,109,101, 97,105, 51,181,127,223, 97,163,251,244, 29,196, +114, 70, 35, 78,156, 56,130,127,255,123, 19,186, 7,249,161,113,211, 64,124, 50,121,138,141, 78,207,205, 57,117,234,248,236,206, + 29,124,142, 23, 23, 21,204,173,139,243, 21,158,135, 8, 0,106, 86,140, 67,121,119,119,228, 3, 0, 33,196,209,206,206,110, 3, +207,243,221,129,247, 33,150,187, 32,238,230, 53,228,229,139,161,211,240, 16,104,153,200, 50, 5, 58,157, 30, 23, 78, 28,198,218, + 53,171,144,155,155,139,160, 55,186, 65, 45,242,128,167,135, 39,180,154,178,192, 5,165,128, 65,111,132,147,194, 11,183,111,223, + 53, 22,149,148,156,175,141, 79, 98,102,240,247, 84,248, 65,103,120, 29,102, 82, 41, 10,139,245,200, 47, 23, 87, 59, 15, 12,135, +174, 84, 3, 78,111, 0,167, 55,194,201,115, 8,154, 43,122, 64,224,143,212, 56,101, 84, 43, 4, 30,134, 39, 23, 96,120,114, 1, +230,175, 79,198,207,203, 70, 62,183,218,212,255,223,236,236,236, 28,165, 82,121,252,214,173, 91, 3,134, 15, 31,142,168,168,168, +247, 0, 76, 7, 0,153, 76,246,222,240,225,195,113,235,214, 45, 36, 36, 36, 28,207,206,206,254, 67, 60, 59,164, 82,169,182,226, + 41,207,204,204,204,172,158,109,221,219,135,134, 50,133,183,111, 23,173,185,124,121,209,182,237,219, 37,189,122,246, 36, 70,142, +131,192,243,104,234,235, 75,250,244,233, 99, 25,190,111,159, 3,107, 52,254, 58,115,210,164, 51,223,189,243, 78,241, 53,181,218, +212, 4,242, 70,229, 83,131, 0,208,168,142,101, 38, 67,167,211,173,159, 56, 97,124,239,115, 81,231, 61, 26,121,185, 91,157, 60, +115,225,174, 84, 38, 97, 26,123, 55,102, 11, 10, 10, 68,159, 47,154,107,174,211,233,190, 53,145,206,223,209,209, 17, 89, 89, 89, +120,248,240, 33,116, 58, 29,140, 70, 35,132,210, 18,232,243, 11,160, 47,204, 3,209,106, 32,227,121,104, 85,217,104,212,216, 7, +248,173,194,176, 78,212, 52, 45, 88,117, 74,208,204,218, 26, 18, 75, 57, 24,177,184,198,105,173, 90, 56,219,118,232,208, 97,223, +193,131, 7, 37, 99,199,142,237, 72, 8,217, 64, 41, 77, 38,132,244, 92,184,112,225,245, 13, 27, 54,200, 38, 76,152,208,108,229, +202,149,239, 2,168, 85,176,107,181,218,125,191,252,242,203, 40, 47, 47, 47,231,152,152, 24,104,181, 90, 8,130,128,126,253,250, + 1, 64,229,119,230,254,253,251, 26,173, 86,251, 44, 54, 54,182, 40, 57, 57, 89, 15, 19,170,254, 22,173,203,184, 58,125,152, 50, + 84,225,226,254,171,153,121, 35,111,170,190, 61,120,250, 48,229,138,213,251,211,180,199,146,146,138, 23,126,220,120,121, 73,113, +244,199,182, 74,245,198, 99, 71,106, 23, 87, 85, 64, 43,202,210, 29, 28, 28, 32, 18,137, 32, 22,139, 33,145, 72, 0, 0, 10,133, + 2,133,133,133,117, 78, 17,214, 4,158,231, 81, 84, 84,132,194,194, 66, 36, 36, 36, 32, 51, 51, 19, 87,175, 94, 5,207,243, 40, + 43, 82, 4,148, 74, 37,174, 95,191,110,213,190,125,251,121, 68, 66,206, 81, 3, 53,185,108,156,101,217,169,239,188,243, 14,244, +122, 61,194,194,194,176,109,219,182,169, 0,206,155,250,249,202,131,167,244, 87, 66,136,239,221,187,119,173, 1,188, 61, 98,196, +136, 31,135, 12, 25,130,243,231,207,227,200,145, 35,221, 0, 36, 2,208, 0, 88, 70,202, 26, 43, 47,171,171,192,131,148, 89, 49, +108,114,114,114,122,187,101,203,150,119,135, 12, 25, 18,176,107,215, 46,219,103,207,158, 85, 20, 53,224,201,147, 39,248,254,251, +239, 51,183,111,223, 94,196,243,188, 3,195, 48,191, 20, 20, 20,212, 86, 5,109,102,105,105,121,236,210,165, 75, 93,155, 54,109, +138,211,167, 79, 99,222,188,121,232,218,181, 43,118,239,222,141,230,205,155, 35, 48, 48, 16,206,206,206, 31,231,229,229,117,222, +186,117,107,183, 78,157, 58, 97,231,206,157,200,204,204,220, 84,155,101, 67,125,169,100, 70,163,145, 0,232,184,102,205, 26,159, +169, 83,167,226,224,193,131,104,211,166,141,205,163, 71,143, 86,162,252, 26,251,119, 69,115, 95,135,229, 29,218,119,157,237,234, +222, 20, 59,119,237, 70, 94, 94,153, 6,165,191, 25,126,130, 82,138,226,226, 98,100,101,101,193,198,218, 10, 43, 86, 46,121,243, +163, 15,198,120,160,204,206,226, 5,248, 55,177, 95, 57, 52,108,252,140,176, 81, 99, 16,115,247, 22,194,127,220,130,216,152, 59, +149,124,156,209,128,196,248,155, 72,140,191, 9,133,139, 23,250,244,234, 70, 70,142, 28,217,239,157, 81, 35,156, 0,252,105, 22, + 16,255,164,232, 21, 80,203, 20, 97,213, 13,202,197,213,189,189,123,247, 58, 4, 5, 5,177, 28,199,225,248,137, 19,248,248,195, +127,225,221,119,230,192, 0, 59,112,122, 9, 4, 73,157,247,238, 74,104, 52,165,160,160, 40, 41, 41,193,149, 43, 87, 64, 5, 14, +225, 91, 87,129, 82,161, 82, 96, 1, 20,122,131, 1,238,158,205,176,105,219, 87, 28,196,226, 90, 47,100, 69,185, 44,111,228, 40, +210,159,165, 32, 37, 51, 22, 54, 86,158, 16,137, 61,145, 91, 80, 10, 17,227, 2,163,246, 62,248,242,240,105,105, 73, 26, 52,134, +223,247,119,227, 11, 95,140,146, 82,193,244, 7,164,210,210,210,125, 59,119,238,236,179,122,245,106,201,155,111,190,217, 68,169, + 84,118, 0,128,208,208,208, 38, 86, 86, 86,216,185,115,167,161,180,180,116,223,239, 26,100, 21, 24,141,198, 55,218,183,111,143, +188,188, 60, 60,125,250,180,206, 39, 15, 94,175,119,144, 59, 59,179,207,206,157, 51,230,228,231,123,244,232,209,131, 24, 57, 14, + 12, 33,200, 43, 44, 68,242,211,167,176,181,181, 37,247,238,223,151,127,251,201, 39,135,252, 2, 2, 68, 21, 21,134,166,224,200, +145, 35, 22, 40,203,187,170,115, 89, 67, 64, 41, 45, 33,132,188,247,201, 39,159, 28,250,207,127,118,218,100,101,103, 63,144, 73, +101,156, 92,110,238,250,206,232, 17,162,130,130,130, 81,148, 82,181,169,124,249,249,249,120,252,248, 49,204,205,205, 33, 17,139, + 33,104, 74,193,151,168,161,205,203, 1,107,208, 67,202,243,176,183,144,193, 67,161,128,167,147, 99,253,132, 40,171, 22,172, 72, +104,175, 58, 45,184,162,131, 63,164,150,114, 72,173,228,248, 40, 50, 10, 0,202,132,194,194,250,103,134, 9, 33,142,238,238,238, + 63,239,218,181, 75,146,147,147,131, 59,119,238,220,165,148, 22, 18, 66,172, 0, 8,241,241,241,167, 99, 99, 99, 7,148, 87,209, +213, 87,253,181, 42, 34, 34,162,119, 80, 80, 16,231,237,237,109,153,157,157,237,153,155,155, 75, 50, 51,159,207, 97, 62,122,244, +168,153, 70,163, 41, 17, 4,225, 16,202,124,156,234,245, 31,154, 62, 76,105,118,229, 54, 38,119, 13,105, 20,104,237,216, 10,121, +220,237,192, 95,239,102, 78,158, 62, 76,185,126,245,254, 52,173, 57,209,253, 72,248, 84, 15,145,153,214,164,228,100, 74, 41,117, +116,116, 4,165, 20,215,175, 95,199,165, 75,151,112,225,194, 5, 36, 39, 39, 87,110, 99, 99, 99,131, 83,167, 78,161,123,247,238, +166, 80, 2, 0, 74, 75, 75,225,234,234, 10, 59, 59, 59,132,135,135, 99,247,238,221,149,137,238, 21, 80,169, 84,176,176,176,192, +234,213,171,229, 67,135, 14,253, 18, 64, 31, 83,184, 9, 33, 62,189,123,247,238,239,234,234,138,220,220, 92,184,184,184, 32, 40, + 40,232, 45, 66,136, 55,165,244,137,201,131,124, 30, 31,133,132,132, 44,249,226,139, 47, 96, 52, 26, 49,110,220, 56, 60,120,240, + 96,223,131, 7, 15,214,122,122,122, 78,158, 53,107,150, 66,161, 80, 96,248,240,225,150, 0, 66,107, 35,177,183,183, 95,182,101, +203,150, 81,253,251,247,103, 12, 6,195, 27,103,207,158,197,211,167, 79,161,215,235,193,113, 28,146,146,146, 48,105,210,164,204, +220,220,220,174,148,210, 36, 19,198, 53,231,228,201,147, 93,253,253,253, 17, 25, 25,137,208,208,208,115,182,182,182,126,173, 90, +181,114,117,115,115,195,254,253,251, 97,109,109, 13, 79, 79, 79,251,175,190,250,170,199,160, 65,131, 16, 25, 25,137,105,211,166, + 69, 1,168,179,218,181, 54, 8,130, 64,214,172, 89, 19,176,102,205, 26,101,133,184, 98, 24, 6,123,247,238,197,221,187,119, 7, +226,111, 46,176, 88,134,188,183,116,241, 76,220,184,125, 31, 17, 17, 18,220,184,113, 3, 10,133, 2, 50,153, 12,148, 82,232,116, + 58,228,228,228,192,104,208, 33,176,165, 15,118,108, 95,142,103,207,114, 0,134,212,154, 90, 67, 24, 50,122,204,191, 6,227,226, +165, 19,248,238,187, 45, 80,171, 75,106,220, 78, 42, 53, 67, 83, 63,127,184,187, 57, 35, 53, 45, 21,132,129,105, 23,189,151,196, +255,147, 41,194,223, 96,107,107,187,118,207,158, 61, 14,221,187,119,103, 75, 74, 74, 32, 8, 2,130,131,130, 48,121,234, 84, 28, +217,181, 11,190, 29,195, 64,244,114,112, 22,166, 85, 49,104, 53,165,104,209,166, 51,134, 13, 31,129,148,228,100,132, 12, 24, 2, +173,182,180, 50, 23, 1, 40,139, 96,233,245, 6, 56, 58,123,224,228,201,147, 44,198,141,187, 87, 27, 31,111,144, 70, 39, 38,105, +187, 20,104,110,227,202,141,112, 24,116, 6, 4, 6, 46,132, 65,112,128,179,242, 3, 24,141, 63,161, 40,231, 44, 0,192,218,161, + 59,210, 82, 82,192,176,146, 90,249,234,131, 80,242, 98, 96,169, 33,133, 58,249,249,249, 69,174,174,174,135,175, 94,189, 58, 44, + 52, 52, 20,167, 78,157,122, 23, 0, 66, 67, 67,113,245,234, 85, 60,126,252,248,112,126,126,190, 73, 57, 67,245, 65,169, 84,246, +235,214,173, 91,104,251,246,237, 17, 25, 25, 9,158,231,175,152,242, 57, 86, 44,166, 12,195, 64, 16, 4, 16, 0,185, 5, 5,120, +240,224, 1,114, 85, 42, 24,141, 70,148,168,213,130,191,159,159,154, 10,130, 85,189,100, 85, 80,181, 98, 16, 53, 84, 17, 86, 44, +107, 8, 39, 0, 80, 74,147,229,114,121, 74,177, 90,237,100,109,103, 95,108, 38,149,242,133, 5,133,133,113,247, 98,244, 38,222, + 20, 42, 16, 31, 27, 27, 27,144,145,145,129,148,148, 20,112, 37,197, 96,117,122, 48,186, 82,244,236,252, 58,204, 65, 97, 6, 1, + 98,193, 8, 49, 43, 70,113, 89,181, 93,124,125,164, 21, 2, 31,248, 45,146, 69, 8, 41,155, 22,180,180,132, 84,110, 85,185,174, +252,120,234, 29,168, 76, 38,219,181,127,255,126, 87,119,119,119, 44, 94,188, 24, 74,165,178,121, 96, 96, 96,105,112,112,176,185, + 66,161, 64,139, 22, 45,208,185,115,103, 28, 59,118, 12, 0,234, 60, 7,148, 82,142, 16,210,231,226,197,139, 51, 46, 95,190, 60, +140, 16, 66,230,204,153,131,190,125,251,194,204,204, 12,165,165,165,200,207,207,199,214,173, 91, 9,165,180, 77,249, 88,189,204, +204,204,118, 19, 66,210, 52, 26,205,240,234,156,225,107, 90,185, 61,203, 19,198, 41, 92,220, 7,119, 13,105, 20,216, 35,164, 23, +124,124,123,160, 71, 72, 10, 0, 44,183, 23, 61, 13, 91,177, 32,224,144,163,135,253,247, 39,143,159, 90, 20,212,181,199,252, 57, + 19,236,150, 44,223, 82,255,119,159, 16, 2,158,231, 33, 18,137,192, 48, 76,141, 81, 42,145, 72, 4,150, 53, 45, 21,133,231,249, +180, 65,131, 6, 85,190,207,200,200,112,244,240,240, 96, 42, 34, 87, 0, 80, 88, 88,136,212,212, 84, 24,141, 70, 56, 56, 56,192, + 96, 48,180, 50,137,188, 12,147,199,142, 29, 75, 52, 26, 13,198,143, 31,143,109,219,182, 33, 44, 44,140,156, 63,127,126, 50,128, +169, 13,224, 1, 0, 48, 12,179, 98,214,172, 89, 51, 38, 77,154,132,188,188, 60, 28, 61,122, 20,253,250,245,195,222,189,123,157, +142, 30, 61,186,180,123,247,238, 96, 89, 22,145,145,145,224, 56,238,126, 93, 92, 18,137,228,237,254,253,251, 51,169,169,169,144, + 72, 36,104,215,174, 29,210,210,210, 80, 90, 90,138,244,244,116, 76,153, 50, 37, 43, 55, 55,183,155, 41,255, 71,132, 16,113,211, +166, 77, 39, 53,111,222, 28,167, 78,157,194,208,161, 67,207, 27,141,198,254, 57, 57, 57,147,242,243,243,191, 25, 61,122, 52, 2, + 2, 2,144,152,152,136,222,189,123,163, 75,151, 46, 56,122,244, 40,198,143, 31, 31,101, 52, 26,251,215,100,209, 80,142,226,103, +207,158,217, 52,105,210, 4,217,217,217, 80,171,213,184,122,245,170,117, 84, 84,148,183,155,155,155,237,163, 71,143,232,130, 5, + 11, 44,166, 78,157,138,181,107,215,226,206,157, 59, 8, 15, 15, 71,143, 30, 61,140, 15, 31, 62, 52,217, 91,237,127, 21, 2, 47, + 0, 16,224,237, 33,199,137, 35,219,113,235,238, 35,220,186, 27, 11,169,172, 44,185, 93,163, 41, 69,155,192,166,232,216,174, 3, + 50, 50,211,241,159,240,237,176,119,116,175,243, 58, 66, 41,133, 68,196,195,223,207, 5,187,194,183, 32,242,232, 25,132,255,103, +119,101, 78,155, 72, 36, 70,235, 54, 29,209,174, 93, 16, 30, 61, 78,194,246,237,223,193,201,217,163, 86,190, 87,168, 25,149, 83, +132, 85,127, 86,133, 32, 8, 61,130,130,130, 88,181, 90, 13,173, 86,139,172,172, 44, 60,125,250, 20,182,118,182,120,148,241, 4, +221, 44, 12,200, 18,138, 16,127,247, 30, 79, 88,241,157,250,118,216,191,107,107,160,107,107,124, 60, 54,172,214,109, 40, 40, 44, +173, 29,161,211,233, 96, 48, 26, 31, 98,253,250, 90,159,148, 57,222,120,250,196,169,179, 29,198,190,251,182,248,228,217,109, 48, +234, 5,104,140, 54, 40,209,234, 81, 98, 16,131,177,233, 7,168,206,131, 21,201,208,233,181,166, 56, 20,113,204, 64, 57,227, 25, +147,206, 14, 0,145, 34, 0, 92,246,111,129, 31,161,228,217,115,235,205,172,236, 77,158, 34,172,228, 16,132, 67,187,118,237,122, +243,245,215, 95,183,232,222,189,123, 99, 0,144,201,100,250, 93,187,118,149,150, 71, 7, 26, 4, 82,205,189,221,221,221,189,149, + 72, 36, 10, 29, 48, 96, 64,171, 49, 99,198,224,222,189,123,216,185,115,231, 67, 63, 63,191, 75,117,241,176, 82,105,174,250,217, + 51, 91,185,183,183,200,206,202, 42,227,216,209,163, 94,189,122,247, 38, 41, 41, 41,200,205,205,133, 86,171,197,157,187,119,169, +152,101,211,136,181, 53,115,255,246,109,134,149, 74,107, 44,167,175, 5, 79,235,169, 34,172, 88,214, 96,120,184,218, 53, 89, 52, +119,162,143, 86,171, 13, 40, 42, 42,226, 68, 98,177, 88,233, 98,155,220, 16, 14,157, 78, 23,121,250,244,233, 65,189,122,245,146, + 37, 70,223, 1, 87, 88, 8,125, 97, 62, 36, 2, 15,251, 54,175,129, 53,232, 0,189, 17,238,254, 20,218, 2, 11,156,191,118,223, +168,211,233,234,237,212, 94, 33,176,152, 42,102,128, 0, 32,149,203, 33,179,178,134, 76, 46,175, 62,133, 88,231,147, 27, 33,196, +226,237,183,223,238,217,169, 83, 39, 80, 74,177,117,235, 86, 24, 12, 6,169,193, 96,128, 94,175,135,193, 96, 64, 81, 81, 17,194, +195,195,177,105,211,166,203, 0,126,168,111,140,148, 82, 78, 44, 22, 79,226, 56,206, 89, 38,147, 25,156,156,156, 36,251,246,237, +171,180,141,104,221,186, 53, 44, 45, 45,117,132, 16, 3, 0,184,184,184, 24,127,252,241, 71,209,192,129, 3, 37, 53,241, 53, 11, +108, 62,211,135,179,235,106,102,222,200,219,218,177, 21,124,124,123, 0, 0,122, 15, 24, 11,159,166,158, 40, 82, 69,123,107, 53, + 79, 7, 75, 68,249,118,247,214,167,199,153,247, 15, 24, 83,242, 44,234, 1,128,237,245,141, 21, 40,243, 11,235,213,171, 23, 66, + 66, 66, 42,167, 3,157,157,157,161,215,235,107, 44,231,175, 11, 21, 38,162, 95,124, 65, 24, 44, 2,214,216, 88,103, 1,168,124, +250, 47, 44, 44, 68, 74, 74, 10, 82, 82,202,162,215,229, 9,197, 38, 61, 93, 19, 66,204,125,125,125,223,107,211,166, 13,142, 30, + 61,138, 27, 55,110,164,159, 56,113,194, 61, 40, 40, 8,222,222,222, 99, 8, 33,243, 40,173,221, 67,175, 6, 62,203, 55,222,120, +227,147, 73,147, 38, 33, 54, 54, 22, 19, 39, 78,204, 77, 77, 77, 61,180,111,223,190,241,139, 22, 45, 98, 66, 66, 66,144,153,153, +137, 21, 43, 86,240,151, 46, 93, 90, 9, 96,113, 93,124,148,210,132,212,212, 84,165, 86,171, 69, 94, 94, 30, 56,142, 67,105,105, + 41,142, 29, 59,134,240,240,240,236,114,113,245,208,196,225,217, 7, 5, 5,217, 61,120,240, 0,219,183,111,135, 94,175,159, 79, + 41,213, 18, 66,126,152, 61,123,246, 60,133, 66, 97,211,187,119,111,180,105, 83,230, 5,183,119,239, 94, 76,153, 50, 37, 74,175, +215,247,175,231, 28,172,118,113,113,249, 96,226,196,137,205,167, 79,159,142,228,228,100,235,163, 71,143,118,185,114,229, 10,241, +240,240, 64,110,110, 46, 28, 28, 28,176,118,237, 90, 76,155, 54,237, 7, 0,217,215,174, 93,123, 47, 41, 41,233, 75, 74,233,119, +166,158,219,255,101, 80,202,163, 52, 63, 22,188,206, 14,173, 3,155,161,117, 64, 35,156, 56,123, 11, 0,208,115, 72, 16, 74, 75, +138,241,227,143, 91,241,240,225, 3,136,196, 98,216,218,187,212,203, 41, 8, 2,244, 69, 9, 40, 48,100,162, 87,247,118,232, 23, +210, 13, 63,236,216, 11,206,104,192,248,177,163,144, 95, 80,128, 29, 59,182,227,209,227, 36,136,196, 98, 56, 56,254,249, 6,166, +117,105,145,191, 35, 76,202, 2, 53, 26,203, 18,218,211,211,211,113,243,230, 77, 60,121,242, 4, 22, 22, 22,208,112,188,240,221, +233, 75, 2, 33,146, 52,129,210,203,148,171,116, 21,126,145,131,231,211,171, 56,204,218,216,217,217, 73,117, 58, 13, 56,206, 88, +229, 74, 69, 0, 2, 72, 68,128,171,155, 15, 82, 83, 82,169, 70,171,141,170,107,108, 18,157,118,237,225, 67,251, 39,117,238, 18, +228,216,175,231, 23, 56,244,211, 66,228, 23, 21, 65,107, 16,163, 68,107, 64,169, 22,176,181,247, 67,251,192, 86,200,200,200, 69, +244,141,243,106,145,174,212,148, 4,208, 7,223,206, 31,235, 59,246,227,153, 48,247,234, 2, 93,252, 33, 8,234,236,202, 8,150, +153,220, 14,246,158,254, 40, 40,209, 97,255,153, 91, 0, 96,114, 75,150,236,236,236, 82, 87, 87,215, 3, 31,125,244,209,242, 59, +119,110,251, 0,192,245,235,215, 31,103,100,100,204,201,206,206, 54,185,130, 14,120,206,189,157,152,155,155, 95,243,245,245,125, +210,175, 95, 63,235, 65,131, 6,193,201,201, 9,183,110,221,194,215, 95,127,253, 64,175,215,127, 22, 21, 21, 85,231,148,142, 94, +175, 79,191,245,211, 79,214,221,254,245, 47,219,153,111,189,181, 98,210,164, 73,107, 23, 47, 94, 44,246,245,245, 37, 70,131, 1, + 49, 49, 49,116,215,206,157,198, 77,115,231,174,145, 90, 90,138,174, 31, 62, 44,230,116,186,250, 60,150,254,116, 40,149,202,174, +111,246,237,234,191,114,245,122,104, 53,106, 92,187,242, 11,242,243,115,176,101,107,132,191, 82,169,236,154,150,150,118,222, 20, + 30,158,231,247,126,255,253,247, 51, 58,182,105,211,166,177,135, 7, 98,146,159, 64, 42,240,144,112, 28, 88,131, 14, 12,167,133, + 71, 0, 5, 97,172,144,153, 85,132,175,246, 28,136,229,121,126,111,125,188,205,223,124, 27,139,211, 10, 65, 8,193,170,215, 3, + 32,181,146, 67, 98, 41,199, 71, 63,159,173, 20, 85,145,139,231, 66, 42,151,163, 73,199,250, 13,220, 41,165,165, 86, 86, 86, 55, + 99, 98, 98,218, 7, 4, 4, 96,198,140, 25,120,250,244, 41, 4, 65, 64,118,118,182, 54, 51, 51, 51, 61, 39, 39,231, 41,128, 67, + 0,182,153,154,228,203,113,156,243,173, 91,183, 0, 64, 2, 0,103,206,156,129,155,155, 27,108,108,108, 80, 84, 84,132,153, 51, +103,202, 62,251,236, 51, 0,192,205,155, 55,197, 21, 9,198, 53, 33,230, 86,252,202,130, 98,154, 79,213,183, 7,231,113,183, 3, +123,132,164,162,247,128, 49, 56, 21,249, 3,206,158, 56, 13,123,209,211, 39,176, 44, 62,166,122,162, 42, 74, 43,241,221,236,223, +118, 60,155, 89,114, 98,243,228,129,118,172,171,171,176,127,206,166,194,130,122,206, 1, 88,150,173,204,193,170, 72,104,111,168, +184,170,138, 69,139,168, 64, 64,136,163, 84, 18,157,154,154,218, 91,169, 84, 34, 59, 59, 27,169,169,169, 72, 73, 73, 65,106,106, + 42,154, 54,109,138, 71,143, 30, 65, 34,145,212,251, 48, 89,142, 81,195,135, 15,183,210,235,245,216,189,123, 55, 7, 96,192,254, +253,251,111,182,111,223, 94,212,183,111, 95,171,141, 27, 55,142, 2,176,173, 1,195,180,180,182,182,150, 24, 12, 6,108,220,184, + 17,169,169,169, 93, 41,165,241,132,144,205,195,135, 15,223, 20, 16, 16,208, 52, 54, 54,246,129, 90,173,254,136, 82, 26, 93, 31, + 89,118,118,246,216,118,237,218,237, 23, 4,193,171, 87,175, 94,150,171, 87,175,182,190,127,255, 62,148, 74, 37, 4, 65,136,161, + 13,107, 53,149,119,250,244,233,252,206,157, 59,219,149, 39,180,127, 69, 8,249,146,101,217,229,161,161,161, 54,187,118,237,194, +209,163, 71,161,215,235,145,144,144,144, 19, 27, 27,251, 45,128,149,117, 21, 96, 0, 0,165,244, 49,128,217,132,144, 86,155, 55, +111, 14,115,119,119, 31,117,229,202, 21,114,241,226, 69,172, 90,181,138, 91,184,112,161, 40, 56, 56, 24, 51,102,204,120, 12, 96, +124,249,247,125, 94, 3,198,253,191, 14,163,193,160,135,181,189, 15,212, 5, 41,200, 73,189, 2, 11, 43, 23,132,244,120, 13,165, + 26, 61,142, 28, 62,136,232,152,187, 96, 24, 6, 10, 23, 15,216,218, 57, 34, 49,241, 1, 0,212, 85, 61,108, 52, 24, 12,176,178, +107, 4,117, 97, 42,244,207,110,193, 92,238,140, 49,255, 26,140, 82,141, 1, 17,135, 14, 34, 54, 54, 26, 44,203,194,197,213, 3, + 54,182,101,156,132,214,201,249, 10,213, 80,175,192, 98, 89,246,220,241,227,199,135,118,236,216, 81,244,240,225, 67, 60,124, 88, +246, 48,147,159,159,207, 17,240, 7,178,163,127, 26, 89,219,103, 9, 33,189, 42,188, 50,170,246, 22,148, 91, 89,165,223, 79,136, + 87,228,231,101,227,238,237, 75,120,152, 24,131, 39,143,226, 97, 48,104,193, 50, 12, 24,150, 65, 35,159,150,184,116,249,138, 94, +207,243, 87,107,227, 4,128,188,188,164, 98,185,194,111,196,146,197,243, 34,167,205,252,220,124,216,208,239, 16,125, 63, 14,106, +206, 5,148, 2, 46, 14,150,104,221,120, 22,210, 51,114,176,231,135,141,165,130,193, 48,186,170, 7, 86, 77,156, 0,160, 80,161, +197,166,173, 63,140,219, 22,190,235,243,153,159, 76, 80, 12, 12, 29, 13,105, 94, 28,140, 25,183,224,211,190, 31,136,204, 22, 71, + 79,158,197,249,155,113,217, 2, 79, 63, 87,228,226,223,245,113, 86, 69, 97, 97,225,141,236,236, 44,159, 42,174,237, 62, 50,153, + 89,157, 73,179,213, 57, 73, 53,135,120,150,101, 58, 46, 94,188,184,196,213,213, 85, 31, 27, 27,139,205,155, 55, 11, 55,111,222, + 60, 39,149, 74,183,100,100,100,212,120, 17,171,202,233,100, 52,222,221, 53,103, 78,139, 14,161,161,116,228, 39,159,148, 66, 38, +155,188, 98,213,170, 57, 57,249,249,110, 84, 16,224,100,111,159,182, 98,238,220,101, 67,135, 15,207,191,119,233,146,249,149,159, +126, 50,151,114,220,173,250,198,249, 71,160, 46,206,180,180,180,243,190, 77, 60,241,227,182,213, 48, 24,116,200, 76, 79, 6, 0, +168,114, 11, 81,151,184,170,206, 89, 62,249, 31,186,224,179,207,126, 93, 48,109,170,203, 27, 61,123, 33,229,238, 29, 24,242,114, + 64,140, 28,196, 68,132,146,103, 22,120,150,173,198,236,255,236,123,166, 46, 45, 13,165,213,226,240,181,141,179, 34, 66, 37,179, +182,130,196, 82, 14,169,220,234,185,168,149,153,181, 53,164,150,114,136,164,210,154,146,225, 95,224, 84,171,213, 67,134, 14, 29, + 26,125,253,250,117,187,241,227,199,163,115,231,206,183, 53, 26, 77,119, 74,169, 73,237,160,106,226, 20,137, 68,207,218,182,109, +235, 44, 22,139,185,113,227,198,137, 84, 42, 85,165, 19,186, 90,173,198,177, 99,199, 80, 81,114,127,239,222, 61,180,108,217,178, + 86,206,241,179, 98,210, 1, 44,158, 62, 76,185,226,215,187,153,147, 1, 44,247,105,234,129,179, 39, 78,227,226,217, 43,115, 58, + 5, 8,235,223, 28,221,254, 75,139,238,195,103,250,183, 29,207,202,173, 93,177, 35,226, 32, 27,127,107,251, 87,165,165, 49, 77, + 0,124, 90,219, 56, 9, 33,160,148,190, 96,201,160,209,104, 76, 18, 87,117,125,151, 40, 40,149, 20,144,121,195,134, 13,235,120, +237,218, 53, 43,185, 92, 14,131,193, 0, 74, 41,154, 52,105, 2,145, 72,132,111,191,253,182, 68,165, 82, 45, 52,133,211,210,210, +114, 82, 72, 72, 8, 18, 18, 18,112,227,198,141,131,148,210,104, 66,200,193,135, 15, 31,142, 8, 14, 14,198, 15, 63,252, 48, 9, +181, 8,172,218, 56, 5, 65,168,234,121,148, 7, 0,148,210,187, 0, 58, 53,244,216,105,153, 89,104, 23, 0,112,112,112, 72, 85, + 40, 20,214,119,239,222,133,167,167, 39, 12, 6, 67,199,250,248,170,114, 82, 74,141,132,144, 13, 81, 81, 81,159,117,233,210, 5, +147, 38, 77,234, 26, 21, 21,213,181, 75,151, 46,240,247,247,199,217,179,103,177,115,231,206, 3, 60,207,127, 4,160,128, 82, 90, +107,127,217,154,142,189, 92, 48, 70, 7, 6, 6,142,242,240,240,192,170, 85,171, 12,209,209,209, 83,150, 44, 89,178,230,206,157, + 59,178,150, 45, 91, 50,209,209,209,181, 62, 76,252,213,215,165, 63,138,147, 18, 50,127,252,251,147, 55,191, 63,126,148, 89,187, +182,173, 81, 90,148, 6,141, 58, 27,165,197, 89,248,118,219, 73, 16,194,192,201,201, 21,206, 46, 74, 36, 39,167,224,242, 47, 71, +245, 37,165,154,181, 82,163,176,188,110,206, 79,202, 56,219,148,113,150,150, 60,131, 70,253,172,146,211,217,217,173,156, 51, 25, +151,174, 28,213,106, 74, 74, 86,235, 41,249,230,207, 60,246,127, 26,234, 21, 88,249,249,249, 83, 38, 76,152,208,125,246,236,217, + 14, 28,199,177,246,246,246, 72, 78, 78,230, 14, 28, 56,144,167, 86,171,167,188,212, 78,197,226,104, 95,191,102,221, 7, 14, 28, +200,189,253,246, 91,146,119,198,246, 21, 57, 57, 59,163,176, 32, 23,137, 9,119,112, 63,238, 22,124,155,189,134, 69,139,215, 0, +182,182,245, 86,234,168,179, 19,207,201, 21,126, 3,190, 88,240,233,222, 46, 93,251, 88, 55,107,249,154,164,117, 19, 27, 24,140, + 28,210,210,210,112,248,167,187,134,216,155, 23,139, 4, 78, 63,162, 36,199,180, 86, 57, 81,101, 9,188, 91, 2, 21,100,231,210, + 21,223,206,216,184,229,199,153,179, 39,143,183, 12, 14,234,141,152,211, 63,224, 96,228,222, 18,173, 78,191, 66,194, 98, 85,140, +138, 54, 40,234, 4, 0, 90,173,214, 88, 61,117, 68,171,213,154,220,244,180, 54,252,248,227,143,200,202,202, 50,164,166,166,158, +230, 56,238, 80, 67,170, 17,215, 83,170, 15, 37,228,244,130,160,160,190, 11, 78,156, 48,123,111,214, 44,253,232,119,222,249, 20, + 58,157, 1, 82, 41, 21, 89, 90, 50,144,201,196,247, 46, 93, 50, 95,247,225,135,246, 68,175, 63,245, 67, 61, 79,159,213,240,135, + 87, 17, 2,149, 17, 44,188, 55,126, 26, 52, 85, 34, 88, 87,111, 36,162, 33, 17, 44, 0,160,148,166, 16, 66, 58, 77,158,191, 32, + 98, 68, 72, 79,255, 0,175, 70, 50, 39,239, 70,144,187,184, 32, 55, 39, 7,151,110,220, 55, 46,222, 27, 17, 91, 46,174, 76,242, +133, 17, 4,161,178,202,173,231,148,217, 32, 44, 11,148, 11,129,138, 74, 32,239,246,157, 65, 68, 34,240, 84,128, 78,167,171, 55, + 9,139, 82,154, 70, 8, 25, 50,122,244,232, 51,145,145,145, 76, 72, 72, 72,235, 67,135, 14,253,174,114,116,163,209,168, 4, 0, +145, 72, 84,100, 97, 97, 33, 26, 51,102, 12,140, 70, 35, 74, 75, 75, 81, 88, 88,136,248,248,120,221,176, 97,195,100, 0, 96,105, +105,105, 28, 49, 98, 68,189,215,143,213,251,211,180,211,135, 41,215,219,139,158,134, 21,169,162,189,237, 69, 79,159,116, 10, 16, +214,175,222,159,166,253, 98,154,237, 18,213,211,243,137,153, 37, 39, 54,239,136, 56,200,190, 59,120, 8,175,148, 63,152, 99,230, + 76, 15,244,120,171,110, 94, 66,200, 11,166,162,191,195, 1,255, 57, 24, 12,244,182,131,131,221,178, 14, 29, 58,204, 91,189,122, +181,220,201,201, 9, 28,199,225,241,227,199,216,176, 97, 67, 73,126,126,254, 87,148,210,155,166,112,249,249,249,121,139, 68, 34, +236,217,179, 7, 0, 54,148, 47,222,112,232,208,161, 17,227,199,143, 71,163, 70,141, 90, 16, 66,100,245, 69,113,170,130, 82, 90, + 57,171,240, 71,130, 16,242,104,221,186,117,238, 46, 46, 46,228,216,177, 99, 28,203,178,181, 90, 49,212,129,101, 59,119,238,124, + 93, 16,132,158,193,193,193,104,218,180, 41, 0,224,230,205,155,248,233,167,159,246,242, 60, 63,186, 46, 97,101, 10,226,227,227, + 47,166,166,166,134,205,152, 49, 67,178,122,245,234, 53,211,167, 79,151,165,166,166, 34, 46, 46,174, 70, 23,252,191, 59, 18, 30, +228,134, 7, 54, 86,156, 88,188,100,245,103, 77, 26,123, 79, 28, 55,102, 56,235,231,219, 18, 37,133,105,112,112, 84, 64,233,225, +131,156,103, 42, 28, 63,126,140, 87,169, 10,190,231, 25,242,197,131, 7,185, 47, 58, 99, 55,128,211, 93,233,131,103,207,158,225, +232,209,163,124, 65,126,209, 86, 24,153,197,113, 79,243,235,237,172,241, 10,207,131,152,146, 80, 91, 94, 73,184,174,204,166,161, + 44,170,149,159,159, 63,133, 82,250,162,125,251,243,159,171, 84,184,164,186,249,217,176, 97, 18,252,242, 75, 43, 24,141,157,108, +173,172,122, 82, 65,104,255,218,107,175,201,135, 15, 31, 46, 4, 5,117,150, 90, 91, 91,147, 22, 45, 2,138, 11, 11, 10,236, 0, +128, 2,124,117,206,234,168,104,246, 44, 98,197,189,120,222, 16, 88, 54,214,250,155, 61,155,162,196, 27, 43,136,147, 72,192, 34, +134,144, 49, 2,165, 63,112, 12,190,120,148, 77,107, 21, 47,166,112, 86,153,222,171,104, 13, 83,103, 99,231, 90,158,230, 43,167, + 8, 25,134,221,225,238,238, 62, 47, 37, 37, 37,199,212,139, 88, 77,156, 21,173,114, 6, 76,157,106,108,219,167, 15,103,239,225, + 33, 80, 74,249, 39,183,110,145,171,135, 15,139,175, 30, 62,108,102,212,233,206,237,167,244,145, 41,156,110,110,110,203,142, 28, + 57, 98,114,110,213, 91,111,189, 21, 87,145,151, 85,215, 56,171,162, 73, 99,229,137,198,222,238,125, 26,123,151, 77, 67, 63,122, +146,129, 71, 79,210, 79, 38, 61, 74, 11,169,237, 51,117,113, 18,242, 91,179,103, 82,110,197, 64, 77,104,246, 92,157,211,209,209, +241,166, 72, 36,170,181,145,112, 77,224,121, 62, 35, 39, 39,167,178,237, 84, 61,227, 28,233,237,237,189, 60, 57, 57, 57,130,231, +249,105,166,238,163, 30,206,206, 44,203, 30,229,121,254,185, 57, 64,145, 72,244,172, 66,132, 17, 66,188,100, 50,217,115, 73,238, +117,113,174, 88, 16,240,217,235,193,193,131,175, 94,188,120,104,230,146,216,231,242,130, 38, 15,182, 31, 59,242,227, 41,223,236, +222,184,110,214,250, 67,121,223,215, 55, 78,133, 66, 17, 5,192,183,124,125,157,199, 89,126, 46,159, 43, 43, 55,245,201,155, 72, + 72,123, 71, 27,199, 47, 13, 6,195,107, 0,168, 68, 34,185,171, 82,169, 22,214, 36,174,106,227,100, 89,118,121,243,230,205,167, +220,191,127,127, 55,199,113,227,170,108,191,178, 73,147, 38, 31, 63,125,250,116,131,209,104,156, 89,227,254,107,254,127,183, 14, + 14, 14,254, 63,246,206, 59, 60,138,170,109,227,247,153,221,157, 45,217, 84, 66,218,210, 91,128, 4, 72, 32,161,132,150, 4, 65, + 81, 64,169, 74,143,162, 32, 77,144, 38,132, 23, 41, 10,137,160, 52, 17, 1, 1, 1, 5, 4, 4, 20,164, 23, 3,210,139, 36, 16, + 66, 11,144, 66, 66, 8,233,101,251,206,249,254, 72,118,217, 36,187,155, 77,136,239,231,171,243,187,174,185,118,103,230,204, 61, +103,102,118,103,158,121,206,115,158,147,179,106,213, 42,230,227,143, 63, 70, 76, 76, 76, 45, 74,169,221,227,140, 86,114,221,189, +221,220,220, 54, 25, 12, 6, 63, 74,233,129,130,130,130, 57,148, 82,203,221,203,108,104, 18, 66, 88, 0,211,154, 52,105, 50,165, +110,221,186, 94,169,169,169, 41,137,137,137, 75, 1,216,157,147,170,146,122, 6, 13, 28, 56,240,194,242,229,203, 69,245,234,213, + 67, 74, 74, 10,166, 77,155,166,219,187,119,111, 8,165,180,130, 71,221, 30,205,234,242,223,214,244,111,226,209,132, 10, 12,139, + 3, 91,251, 13, 30, 53, 98, 0,185,112,229, 30, 46, 94, 56,143,212,180,180,125, 28,195, 68,222,189,251,220, 98,147,110, 85, 52, +207, 95,185,139,139,231,207,211,244,180,244,221,160,130,255,196, 39,102,218,117,159,231,169,136, 93, 6, 86,181,197,109, 25, 88, +150, 80, 40, 20,200,180,134, 88,153, 0, 0, 32, 0, 73, 68, 65, 84,202,234, 40, 21, 10,187, 74, 36,146,112,134, 97,206,100, 63, +127, 62, 25,176,207,192,170,137,122, 86, 70,211,166, 68,108,109,232,128,234,104,150, 15, 80,175,142,102, 85, 52,236,213,180, 54, +216, 51,167, 86,167,185,235,245, 87, 87, 83,235,231,160,188,102,221,186,117, 63,224, 56,174,145,189,117, 98, 24,230, 81,106,106, +106,153,102, 19,123,207,103,243,230,205,233,189,123,247,236, 10,146,252,255,254, 45,253,155, 52,183,173, 8, 80,180,104,211,114, +102,220,181,219, 95,150, 54, 31,154, 88,248, 81, 45,167,174, 61,194,230,253,113,234,247,207,230,175,206, 46,243, 18,244, 79, 56, +118, 66, 8, 99,201,176, 32,164,164, 47,122, 85, 53, 89,150, 93,215,161, 67,135, 15, 46, 94,188,184, 73,175,215,143,173,169,122, + 86, 23, 27,247, 37, 2, 64, 92, 21,239, 92,101,154,102,235,131, 4, 2,193, 52,127,127,255,142,241,241,241,151, 12, 6,195,114, + 91,198,149, 61,154,213,225,255, 75,211,223,215, 61,152, 82, 83,178,236,197,183,239,103, 93,182, 85,190, 74,154,148, 51,112, 84, +240,249,157,196,231, 54, 71, 44,224, 13,172,202,169,214, 96,207,213,193,104, 32,217, 36, 45, 45, 5, 64, 10,128,221,127,121,133, +170,137, 61,198, 85, 85,168,142, 81,244, 87,104,148,167,212,128,178, 43,173, 67,101,148, 55,150,254, 74,238,222,189,251,143,232, +125,242, 79, 99,212,199,177,105, 0,166, 6, 91, 72, 77, 85,106, 84,205, 12,127,243,191, 93,171,255, 14,214,188, 54,182,140, 43, + 91,104,181,218, 15, 9, 33,211,104, 21,122, 31,254,127, 80,122,124, 85, 54,174,236,212,190, 6,192,106,252,239, 63,157,248,123, + 89, 87, 1, 84,210,144,254,255,175,249,111,167,102,130, 22,120,120,120,120,120,254,107,252,221,141, 43, 30, 30,158,146, 92, 46, + 61, 45,173,168,138,235,143, 16, 98, 81,195, 22,118,196, 39,241,154,188, 38,175,201,107,242,154,188, 38,175,249, 15,211,252,215, + 96,236,197,244, 87, 76, 0,122,242,154,188, 38,175,201,107,242,154,188, 38,175,201,107,254,219, 38,190,137,144,231, 47,231,235, +129,164,206,215, 3, 73,157,191,170, 60, 15, 15, 15, 15, 15,207,223,141,255, 90,144,187, 53, 8, 33, 10,148, 36,200,107, 10,224, + 14,128,179,180, 10,221,142, 45,232,213, 6,240, 54, 33,100, 8, 0, 80, 74,119, 3,216, 69, 43, 73, 41, 97, 68, 38,147,101,168, + 84, 42, 79, 0,144, 74,165,207, 84, 42,149,249,152, 3,196,108, 2, 0,106,156,104,169, 73,111,137,198,141, 27,103,168,213,106, + 79, 59,118,159, 71, 41,141,101, 24, 38,206,209,209,241,212,157, 59,119, 42, 29,134,197,156, 30, 61,122, 68, 8, 4,130,197, 0, + 96, 48, 24,230,158, 58,117,106, 75, 85,182,175, 10,132,144,142,245, 20,222,223,107,117, 90,125, 70,102,246, 60, 74,233, 47,150, +202,173,237, 71,162,132, 4, 51, 75,191, 47,155,112,192,118, 42,138,170,150,183, 81,191, 96,145, 72, 52,201,203,203,235,245,212, +212,212,171, 0,102, 81, 74, 43,205, 66, 92,191,126,253, 81, 66,161,112,132,193, 96,104, 34, 16, 8, 18,245,122,253,143,201,201, +201,219,170, 83, 7, 30, 30, 30, 30,158,127, 47, 85, 50,176, 90,214, 38,222, 20, 24, 10,130, 94,160, 56, 78,128,157, 9,207,233, + 83,123,183,239,211,146,232,116,250,146,125,178, 12, 12,135, 31, 48, 27,250,244,233, 83,119,242,228,201,232,220,185, 51, 46, 94, +188, 24,178,121,243,230,247, 4, 2, 65, 44,199,113,167, 1, 92,164, 54,210, 1, 24, 33,132,200, 1,188, 5, 96,248,235,175,191, +222,115,241,226,197,130, 86,173, 90, 65,169, 84,226,247,223,127,239,186,108,217,178,149,132,144, 19, 0,182, 3,248,133,218,200, +237,162, 82,169, 60,141,182, 18, 33,196,115,208,160, 65, 87,204,114,237, 16, 66, 8, 24,134, 1,165,244, 2,128, 11, 28,199, 93, +216,189,123,119, 74, 75, 66, 58,142,107,196,238,153,242, 80, 83, 33,231,145, 90,173,246,220,191,116, 9,132, 18, 9,212, 5,249, + 8,121,247, 69,207,234,227,159,206, 4,225,244, 16,128,230,132,127,190, 50, 22, 64, 92, 90, 90, 90,108,104,104,232, 35, 59, 79, +171, 9,129, 64,176,248,200,145, 35, 62,148, 82,188,246,218,107,139, 1,108,169,170,134, 61, 16, 66, 36,157,130, 3, 79, 31,248, +121,135,180, 48, 59, 3,189,223,122,231, 71, 66, 72, 4,165,244,103,243,114,107,223, 32, 94, 68,136,153,227,151,108, 23, 0,192, +218,200,225,179, 86,190, 70, 86, 79, 61, 74,159, 18, 66,194, 1,211,208, 74, 75, 41,165,167,215,190, 65,188, 32,192, 39,227,151, +108, 39, 0,240,109,228,240,153,107,223, 32,171, 38, 28,170, 90, 47, 73, 66,200,132,136,136,136,213,139, 23, 47, 22,248,248,248, +224,201,147, 39,189,253,253,253,155, 19, 66,252,169,141,224,224, 70,141, 26,253, 20,254,106,255, 38, 3,135, 12,149,213,118,119, +195,147,244, 76,151, 93, 59, 54,143,107,212,168,209,235,143, 30, 61,122,167,106,103,137,135,135,135,135,231,223, 76,165, 6, 86, +144,130,200,138,180,232, 47, 20,144, 81,221, 58,182,122,101,216, 27,221, 24,127,191,102,136,191,117,251,213, 95, 78, 93, 90,230, +239,197,156,212, 27,232, 54, 57,139,253,215,210,108,247,108,209,233, 33, 60,182,127, 59, 0, 96,194,123,195, 5,151, 47, 95,110, + 22, 20, 20,100, 26, 65,253,149, 87, 94,193, 43,175,188, 66,214,174, 93, 27,120,236,216,177,192,141, 27, 55,106, 9, 33,223, 83, + 74,127,179,166, 73, 8,153,212,180,105,211,101,171, 87,175,150,132,134,134, 66, 34,145,152,214, 57, 58, 58,162, 95,191,126,232, +215,175,159, 32, 45, 45,237,181, 3, 7, 14,188,182,116,233, 82, 13, 33,100, 6,165,116,141, 53, 77,115, 62,253,244,211, 32, 11, +139,143, 16, 66, 30,232,245,250,235, 1, 1, 1, 41, 45, 8,105,246,225, 27,157,143, 79,232,226, 43,183,166, 35, 20,139,177, 53, +162,228, 25,109,110, 96, 61, 58,117, 24,142,206, 78, 89, 14, 78, 78,177, 0,226, 0,196, 82, 74,227, 30, 60,120,112,219,143,144, +192, 78,110,204,247, 27,179, 13, 1,246,212, 21, 0, 4, 2, 1, 82, 82, 82,224,226,226, 34, 11, 11, 11, 75, 39,132, 44, 56,125, +250,244, 6,123,183,183,147,142, 11,102, 78, 96,115, 30,199,226,105,194, 5, 76, 27,210,213, 97,234,215,191,126, 6,224,103, 91, + 27, 17,194, 48, 75,207,115,179,167, 2, 83, 0,204,203,202,202, 10, 5, 0,119,119,119, 49,128,211, 43, 46,225,141,143,187, 84, +146, 57,210,166, 62, 97, 5, 2,193, 55, 91,183,110,125,127,212,168, 81, 37, 67, 60,252,241, 7, 28, 29, 29,177,104,209,162,134, +211,167, 79,143, 66,201,190, 43, 80,191,126,253, 81, 97,189,250, 55, 94,185,236, 51,191,130,236, 60,245,250,111,118, 93,169,211, +186,133,224,195, 73,211,157,214,232, 52,222,245,235,215, 31,197,123,178,120,120,120,120,120,236,197,166,129,213,194,131,108,233, +214,206,247,237, 97,125,186, 74,218,180,110, 5, 86,242, 34,177,115, 80,112, 48,130,130,131,153,217,133, 5,189, 46, 95,185,214, +107,207,177,139,234, 22, 30,100,215,157, 76, 26, 97,239,206,141,131,197, 46,126,203,171, 71, 81,238, 51, 41, 0,200, 93, 61, 85, +145,251,159,158,234,210,165, 11,234,214,173,203,158, 60,121,114, 12, 0,171, 6, 22,128,200, 59,119,238, 72, 4, 2,219,121, 76, + 21, 10, 5, 6, 15, 30,140, 22, 45, 90,136,195,194,194, 34,241, 98,216,138, 50, 72,165,210,103,132, 16, 79, 0,168, 85,171,150, + 97,193,130, 5, 55,104, 41, 0,192,113,220, 5,129, 64,112,129,227,184, 75,191,252,242, 75,106, 43, 66, 60,251, 6,181, 56, 59, + 97,228, 96, 7,186,103,165, 85,227, 64,149,159,111,113,185,131,163, 60, 83, 38,151,199, 74, 28,164,113, 0, 98, 1,196,213,169, + 83,231,118, 43, 66,234,118,106,209,232,216,218,143,135, 59,217, 60,176, 82,130,130,130,154,135,135,135, 75, 13, 6, 3,138,138, +138,240,237,183,223,186,200,100, 50,151,215, 95,127,125, 62, 0,147,129,229, 79, 72,155, 65, 10,193,216, 5, 79,244, 19,237,209, + 53,135, 16,226,218, 45, 36,248,241,215,209,243,157,131, 59,117,195,189,211, 63, 32, 59,187, 0,121,185,133,224, 56,174,194,200, +191, 19, 14,209,140,181,253,200,178,181,115,134,127, 66, 24,134, 4, 14,152,133, 55,189,243, 62, 34,132,220, 2, 32, 18,139,197, +198,162, 66, 66,136,162,117,235,214,203,154,189,218, 13,223,206, 29, 9,202,113, 20,192, 50,123,189, 87,132, 16, 79, 39, 39,167, + 95,142, 29, 59,214,177,125,251,246,184,120,241, 34, 30, 62,124,136, 9, 19, 38,104, 38, 78,156,200,142, 30, 61,154, 76,155, 54, +109, 50, 33,100, 15,165,244, 92,249,237,133, 66,225,136,183, 6,190, 35, 46,204,205, 87,105, 53, 90,141,187,187, 11, 85, 21,169, + 10,178,114,242,149,111, 15,125, 95, 27,119,237,226, 8, 0, 21, 12,172,151, 57,159, 60, 60, 60, 60, 60,118,211, 30,128, 7,128, + 76, 0, 87,202,205,163,244, 59, 44,204, 63, 71, 73, 88,143,187,153,214,115,148,132,247,120,160, 36, 71,231,101, 0,213, 14, 77, +178, 6,161,148,162, 52,161,176, 49,177,176,201, 72,104,225, 65,232,157, 76, 10,125,118, 34, 12, 89, 15, 96, 40,168, 56,188, 17, +145,186, 34, 79,105, 64, 74,226,109, 68, 76, 93,132, 59,153,214, 51,104,247,105, 73,116, 46, 98, 8,157, 88,128,117,112, 85, 15, +139, 62,122, 62, 56, 56, 88, 21, 25,202,244,137, 90, 91,226,217,154, 54,118, 56, 66, 62,222,115, 52, 49, 49, 81,175, 80, 40, 48, +106,212, 40, 80, 74,251, 90, 61, 0, 66, 50, 10,174,156,247, 76,232,219, 25, 29, 50, 44,135, 65,221,189,123, 23,103,206,156, 65, +114,114, 50,154, 52,105,130, 49, 99,198, 60,163,148,122, 89,211,236,221,187,119,204,210,165, 75,187,127,245,213, 87,177, 91,183, +110,237, 66,169,229,177, 6,253, 9,145, 7, 54,244,190,178, 49,234,147, 38,228,240,247,162,226,228,251,112,141, 81, 86, 56,126, +133, 66, 65,211,210, 94,156,187, 47,154,251, 64,238,226, 4,185,179, 99,198,232, 99, 87, 77,158,171,210,207, 59, 65,132, 56,215, +245,113,191,186,115,197,188, 58,204,169,159,164,236,250, 11, 54,189, 58, 65, 65, 65,205,195,194,194,206, 47, 94,188,216, 45, 45, + 45, 13, 39, 78,156, 64,195,134, 13, 81, 92, 92,140,229,203,151,167,159, 61,123, 86, 81, 90, 95,175, 14, 45, 26,196,126, 59,253, + 93, 23,118,204,167, 18, 91,154,150, 96,133,194, 53,231,143,252, 52,209, 69, 66,145,155,246, 16, 15,110,223,194,229,248, 71,186, +109,199, 99, 13,249, 74,117, 31, 74,233, 41, 75,219, 77,234, 74,154,157, 78,243, 56,112,228,247, 43,190, 62, 62, 62, 24, 55,110, + 28,158, 62,125, 10, 74, 41, 56,142, 51,245,184,136,140,140, 68,243,230,205, 17, 49,244,205, 98, 73,246,181,176, 3,241,246,141, +247, 70, 8,105,221,160, 65,131, 99,167, 79,159,246,170, 83,167, 14,206,158, 61,139,167, 79,159,194,219,219, 27, 39, 79,158, 68, +116,116,244,214,241,227,199, 15, 89,188,120,177,116,216,176, 97, 79,142, 30, 61, 90,175,124,204, 92,195,134, 13,111, 31, 56,122, +214,241,228,190,163,137,110, 78,114, 56,122,213,130,192,201, 77, 9, 10,165,151,135, 11,251, 78,255,158, 77, 31, 63,126,236,103, +190,205,203,158, 79, 30, 30, 30, 30,158, 23, 88,179, 69, 74,233, 67, 8, 57, 88,106, 15,104, 0,136,205,230, 65, 8, 57, 8, 0, +229,231,103,207,158, 29, 25, 21, 21,117,203, 56,111, 44, 51,103,206,156, 86,209,209,209, 75, 66, 66, 66,118,158, 63,127,126, 1, +128,251, 53,125, 60,118,197, 96,233, 83, 47,131,245,125, 29, 34,131, 14,186,231,119,192,229, 38, 1,114,111, 40,137, 35,178,210, +147,144,112,246,231, 18, 91,176, 18,126, 75,160, 34, 66,200,201,219,183,111, 35, 33, 33, 1, 41, 41, 41,112,112,112,168, 80,238, +143, 63,254,128, 76, 38,131,143,143,143, 93, 7, 65, 53,101,147, 5,199, 6, 53,128, 99, 72, 40,158, 15,251, 16, 39, 79,158,196, +179,103,207,192,178, 44,196, 98, 49,244,122,125,165,122, 12,195, 16,192,148,137,216, 98, 22,230, 48, 66,132,117,107, 57, 30, 88, + 59,127, 74, 35,230,194, 65,145, 50,249, 62,210, 84, 6,184,218, 81, 95,153,163, 28, 14,114,135,116,153,204,161,188,113,117, 47, +136, 16,145,220, 81,122,224,251,207,167,121, 11,174,159,148, 42,239,199,130,181,160,209,171, 87,175,113, 0,230, 83, 74,115,195, +194,194,188, 22, 47, 94,236,246,228,201, 19,196,199,199, 99,215,174, 93,153,250,146, 3, 37,148,210,133, 0, 16, 66,136,180,190, +135,235,209, 53,159, 78,113,194,233,159,196, 24,243,169, 29, 53, 45,139,139, 95,191,223, 6,141, 30, 63,113,245,148,126, 40, 42, + 80, 98,251,241,235, 56,114,237,193,155, 0,254,176, 21,215,182,230, 15,122,159, 16,242,202,192,129, 3,255, 60,115,230, 76,237, +141, 27, 55, 66,175,215, 91,156, 54,110,220,136, 19,103,175,125, 68,237, 28, 76,151, 16,162,104,212,168,209,137, 75,151, 46,121, + 56, 56, 56,224,248,241,227,200,205,205, 53,121,174, 34, 34, 34, 72,110,110,238,208,111,191,253,118,208,227,199,143,191, 60,123, +246,108, 22, 74,134,109, 42,243, 67, 16, 8, 4, 15,244,122,109, 75,133,159,175, 96, 72,191,110,221, 10,179, 98,225,232, 30,128, +139,127, 62, 56,152,151,155,173, 20, 8, 4, 15,204,203,215,196,249,228,225,225,225,225,169, 26, 70,163,202,220, 96, 42,111,104, + 25,191, 27,203, 69, 69, 69,153,230,141,219, 68, 71, 71, 47, 49,155,183,232, 68,121, 89,140, 6, 86, 24, 33,132, 2, 8,179, 84, + 72, 29,191, 23,234,132, 95,192, 54,232, 2,113,139, 55, 33,104,208, 21,201,177,167,113,227,240, 10,164,222,250, 3,148, 51,192, +167,121, 7,123,247,169,106,217,178, 37, 84,170,146,208, 43,181, 90, 13, 86,238,166,154, 54,118,184, 20, 0, 56,161,212,100, 45, +217,232,152, 87, 6,167, 46,225,232,144, 65,113,217,171,196,224, 53,122,178, 62,127,247, 93,176, 44, 11,150,101, 77,131,194,218, + 99, 96,149,142,161,101, 28,173,190, 66, 37, 8, 33, 36, 88, 34,218,190,115,254,164, 14,146,199,113, 98,245,205, 11, 72, 83,115, +244, 64,134,225, 55,123, 70, 52,118,144, 59, 60,145, 57, 56,196,201, 28,229,230, 6,214, 3, 0,160, 34,209,182, 31, 22, 78, 10, +144,103, 36,202, 85, 87, 78, 34, 93,197,105,157, 45,203, 44, 60,124,248,176,167, 80, 40,244, 54, 24, 12, 72, 78, 78,198,173, 91, +183,176,106,213,170,140,130,130,130,176,107,215,174,221, 53,171, 47,211, 94, 38,222,181,109,209,148,198,194,216, 24,169,250,193, + 77,139, 70,155, 45, 60,218, 12,120,237,205,176,192,223,198,141,156,139,254,111,188,138,209, 97,254,244, 81, 90,182, 10,192,113, +106,199,192,210,148,210, 39,132,144, 94,221,187,119,255,177,109,219,182,126,148, 82,180,105,211, 6, 67,135, 14,197,182,109,219, +112,227,198, 13,228,231,231,107,143, 29, 59,182,146, 82,186,185, 50,189,210,227,114,112,115,115, 59,114,234,212, 41, 15, 7, 7, + 7, 28, 59,118, 12, 74,165, 18, 62, 62, 62,152, 56,113,162, 56, 58, 58,122,107,126,126,254,144,168,168, 40,233,163, 71,143,214, + 28, 61,122,180, 33, 0,134, 82, 90,225, 71,160,209,104, 54,108,223,182,101,245,196, 73,147,235,156,186, 24,127, 82, 93, 84,224, + 82,175,126, 74, 65,237, 90,142,142, 43,150, 46,172,167,209,104,198,153,237,215,236,124,254, 94,173,243,201,195,195,195,195, 83, + 1,155,182, 8,240,194,104, 42,111,100,217,131,153,241,165,156, 61,123,118, 36, 33,228, 96,169,135, 75, 9,160, 98, 19,221, 75, + 34, 44,173,112, 12, 33, 4,148,210, 24,171, 37, 57, 3,180,143,206, 64,251,232, 12,100, 33, 31,225,215,168,178,195, 64,217, 57, + 72,186, 69,250, 45, 58,126, 74,173, 86, 11,183,108,217, 98,138,203, 2, 0,131,161,242,225, 11,171,138, 61, 6, 22, 74,135, 16, + 42, 53,176, 42, 84,162,145,196, 49,102,195,199, 67, 58,185, 27,138, 69,154, 63, 14,224,137,154,211,127,121, 95, 91,124, 37,151, + 46,141,180, 34,184,127,234, 56,164,156, 61, 1, 7, 71,199,148,247,207,196,153,123,173, 98, 1, 60, 4,128, 70, 82,231,147,187, +166, 13,235,234,205,130,213,252,182, 27,105,106, 78,189,238,177,110,243, 42, 11,122,198,102,181,135, 15, 31,162,184,184, 24,231, +207,159,199,207, 63,255,156, 89,222,184, 42,173,239,239,155,102,141,232,232, 92,240,148,213, 92, 57,129, 52, 53,167,110,110,199, + 73,240, 8, 24,208,133,101,200, 49,194, 8,100,111,116,243,199,212, 15, 6, 96,197,166, 95,245, 26,207,110,125, 87,255,114,232, +237, 66,181, 54,210, 30,227,202,172,206,177, 0,252, 9, 33, 18, 0,225, 67,135, 14, 61, 52,104,208, 32,196,196,196,224,192,129, + 3,190, 0,210, 1,128, 16,178, 8,128, 23, 74,122, 23, 90, 27,201,157, 97, 89,118,231,137, 19, 39, 90, 41, 20, 10,156, 56,113, + 2, 74,165, 18,227,199,143,215, 76,154, 52,137,141,136,136, 32,121,121,121, 38,207,213,249,243,231,179, 96,197,184, 2,128,212, +212,212,195, 13, 27, 54,236,210,189,123,247,254,141,125, 91, 56, 39, 22,228, 63,115,116,144,202,206,198,156,102,175, 93,185,176, + 38, 53, 53,213, 52,152,106,217,243,121,210,238,243,201,195,195,195,195, 99, 29,187,108, 17,192,102,216,144,157,219,137,162,162, +162,110, 69, 69, 69,149,241,112,213, 52,213,202,131,101,200, 75,174,176,140,114,246, 27, 88,150, 60, 83,110,110,110,122,153, 76, + 86,198,192,226,236,212,204,222,183, 3,137, 19,134,155, 60, 87, 70, 79, 22,122, 71, 84, 40, 91, 21, 15, 86,105, 48,116,153, 74, +200,189, 90, 12,219, 57,178, 87, 23,255,198,117, 24,221,174, 85, 72, 45,214,171,230,223,209,170, 18, 10,232,155,241, 22,130,167, + 77,154,122, 29,164,114, 89,146,204, 81, 94,222,184,122, 12, 0,142,222,205, 7,109, 29, 22, 30, 22,216,162, 41,163,255,105, 57, +158, 20,235, 10,103,223,214,106, 19,139,232, 94, 75,122,148,210,249,175,190,250,234,124,119,119,119,233,234,213,171, 93, 26, 52, +104, 0,189, 94,175, 41,111, 92,201,189, 90, 12,251, 41,162,119,151,230,222,110,140,110,207,215, 72, 81, 26,138, 87, 37,234,182, +174,171,228, 28,120, 4, 12,232, 82,219,197,241,232,186, 37, 19,100, 14, 18, 17, 84, 42, 21,162,215,238,193,177,115, 55,251,102, +198,237, 59, 10,224,104, 37, 18,182,120,191,111,223,190, 43, 22, 45, 90, 4,157, 78,135, 49, 99,198,224,193,131, 7,199,238,220, +185,179,170,126,253,250, 51,102,205,154,165,240,246,246,198,219,111,191,205, 2,136,176,162,241,197,246,237,219,251, 6, 6, 6, + 34, 38, 38, 6,185,185,185,240,241,241,193,164, 73,147,196, 81, 81, 81, 91,243,243,243,135, 44, 89,178, 68,250,240,225, 67,155, +158, 43,115,244,122,253,103,235, 87, 76,152,222,190, 83, 87,230,254,253,187,250,228, 14,161,204,233, 19, 7,206,184,185,185,109, + 53,150,145,123,181, 24,246,211,187,175, 87,249,124,242,240,240,240,240,212, 24,191, 1,232, 99,156, 49,247,102,153, 27, 95, 70, + 15,149,249,124,249,242,165,235,255,146, 65,201, 77, 6,150,133,128, 50,171,112, 69,153, 21,150,217,211,156,215,167, 37,209,141, +107, 15, 97,100, 40, 3, 86,238,166,234,183,232,184,197,160,104, 0,144,203,229,118,123,176, 56,181,202,230,122,179, 60, 86,118, + 25, 88, 2,129,128, 0, 56,194,113,220, 5,152, 25, 88,174,222, 45, 66,255,243,201,148,149, 93, 7,245,102, 50, 62, 8, 65,110, +161, 90, 61, 43, 94,207,165, 22,219, 54,174, 0, 0, 6,221, 35, 7,185, 99,156, 84, 94, 38,238, 42, 25, 0,100, 94,205, 58,204, +254,120,242,218, 30,195,250,145,204,241, 93,145,147,171, 84,207,184,165, 39, 79,148,116, 72, 60,165,167, 45,201,157, 60,121,114, + 61,128,245, 97, 97, 97, 25,114,185, 28,133,133,133, 21,174,129,177,190, 93, 6,245,102, 50,222,239,136,236, 34,173,122,214, 45, + 61,210,148,220, 78, 91, 85,245, 8, 24,208,197,195,213,233,232,186,197, 19, 28,210, 82, 31,131,101, 89, 56, 58, 58,226,248, 31, +113,200,188,185,255,101, 12, 43, 8, 4,130, 5,145,145,145,243, 39, 78,156,136,172,172, 44, 28, 56,112, 0,111,188,241, 6,118, +236,216,209,224,208,161, 67, 43,194,195,195, 33, 16, 8,112,240,224, 65,232,116,186,123,150, 52, 8, 33, 3,198,142, 29, 59, 99, +208,160, 65,184,124,249, 50,210,211,211,203,120,174,114,115,115,135,174, 93,187,118,208,163, 71,143, 42,245, 92,149,163, 67,163, +166,237,216, 57,243,190,130,186,248,153, 48,243,201,197,152,147,199,153, 11,217,217,217, 14, 0,242,170,123, 62,121,120,120,120, +120,236,195,134, 45,146, 89,106, 60,101, 90,154, 55, 51,172, 44,205,147,114, 94, 47, 77,185,245, 55,106,170,254,230,216,229,193, + 18,122,181,134, 62,227,166,105,158, 43,122, 86,102,189,212,169,150, 93, 77,132, 58, 61,132,235, 54,155,242, 96, 73,179,178,178, +164,181,107,215, 86,153, 27, 6, 14, 14, 14, 80, 40, 20,200,201,201,193,134, 13, 27, 0,160,178, 96,103,189,243,160,145,232, 48, +108, 12,174,212, 21,131,234,180, 38, 79,214,186,119,223, 53, 21, 34,132,128,101, 89, 99,236, 87,101, 15,219, 75,132,144,199, 28, +199, 93,160,148,210,160,230, 77, 62,147,202,229,239, 6, 7, 52,173, 61,117,194,251,162, 71,207,212, 56,213,117, 78,238,158, 47, + 62,113, 76,161,142, 19,147,104,174,109,227, 10, 72,124,235,219, 31,202,123,174, 82,219, 53,111, 50, 87,234, 32,253,160, 83,235, +230,222,179,167, 77, 16, 61,202, 80,147, 83, 29,102,229,255,188,116,150,195, 67, 56,205, 72,161, 57, 22,141,171,114,204,127,227, +141, 55,230, 83, 74, 41,199,113,243, 0,192,188,190,211, 38,125, 32, 74,124,170,194,201,174,115,115,126,254,226, 19,167, 20,216, +174,175, 71,192,128, 46, 94,110,206, 71,215, 45,153,232,144,254, 36, 9, 18,137, 4, 78, 78, 78, 72,201,200,131, 72, 40,176,153, +231,172, 50, 8, 33,146,208,208,208, 79, 38, 76,152,128,184,184, 56,140, 31, 63, 62, 61, 57, 57,121,239, 79, 63,253, 52,254,211, + 79, 63, 21,190,246,218,107, 72, 79, 79,199,178,101,203,116,127,252,241,199, 18, 0,203, 44,233, 8,133,194,247, 63,251,236, 51, +154,150,150, 70, 30, 62,124, 8, 31, 31, 31, 76,158, 60, 89,188,100,201, 18, 83,204, 85, 85, 60, 87, 70, 82, 83, 83, 99,124,155, +214,199,155,135, 87, 66,175, 83,199,228,102, 37,159, 73, 72,204,137,169, 37, 22, 79,239, 26, 20, 80,173,243,201,195,195,195,195, + 83, 35, 92,169,100,254,111, 71,101, 6,214,189,175,231,190,231,251,222,196,153,144, 53,232, 2,245,237,125,224, 10, 51, 76, 30, + 44,169,163, 27,106,213,247, 67,110,145, 26,187, 79, 94, 3, 0,139, 30, 7,107, 20, 20, 20, 32, 40, 40, 8,223, 68, 52,239,161, + 42,200,146,202, 0,168, 37,206,170,253,226,110,167, 14, 29, 58, 84,204,113,220, 78, 0,135, 42,145, 89,208,170, 85,171, 53, 95, +125,245,149,216,111,216,123, 40,188,120,182,204, 74,134, 97, 32,147,201, 32,145, 72, 16, 27, 27,139, 83,167, 78,105, 0, 44,176, + 37, 72, 8,185,164,215,235,111,236,222,189, 59,197,183, 73,221,222, 97,237, 59,124, 20, 57,103,182, 83,252,217, 99,152,183,100, + 13,215, 44,248,181,188,232, 29,251, 11,242, 28,235,191, 82,156,150,240,167, 29,135,122, 3,101,141,171, 52,191,198,245,123,132, +180,107, 59,115,222,188,185,206,183,206, 30,199,167, 75,215, 81,223,192,158,121, 75,127,254, 37,255,185, 67,195, 87,149, 25,183, + 47,219,150, 44,225,247,223,127, 95, 15, 96,189,113,190,124,125,103, 47, 90,197, 53,111,223, 59, 39,122,199,207, 69,249, 78,245, +123,218,170,175,167,255,192,206,245,124,106, 29,253,250,243, 15, 29,158, 62, 73,134, 68, 34,129,163,163, 35,146,211,115, 49,127, +229,174, 34, 45,199,245,182,167, 78, 54,144, 56, 57, 57, 73,180, 90, 45,190,249,230, 27, 36, 39, 39,135, 80, 74,147, 9, 33,235, +222,121,231,157,213,109,218,180,105,121,235,214,173,123,133,133,133, 19, 41,165, 9,214, 68, 92, 93, 93, 67, 60, 60, 60,200,133, + 11, 23,240,225,135, 31,106, 38, 79,158,204,142, 30, 61,154,228,228,228, 84,215,115, 5, 0,168, 91,183,110,232, 91,125, 58,163, + 75,175,241, 49, 26, 85,238,153, 71, 9, 91, 99, 24,122, 78, 26,212, 54,160, 90,231,147,135,135,135,135,231, 95,140,173,145,160, + 67, 1, 97,115,119,140,107, 85,135,125,186,237,139,201,180, 32,241, 60, 85, 94, 94, 79,243,247,125, 64,127, 91, 54,154, 30,250, +122, 42, 29,223,167, 21,109,233, 73,158, 54,119,199,184, 80, 64,104,190, 61,202,141,182,253, 70, 11,232,122, 53, 5,237,213, 20, +180, 79,115,232, 0, 68,182,107,215,110,255,164, 14,160, 52,126, 59,165,241,219,233,164, 14,160, 0, 62, 4,224,104,169, 78,229, + 53, 75,151,249, 0,216, 16, 20, 20,164, 63,125,250, 52,189, 51,164, 39,189,222,178, 54,157, 56,113, 34,253,244,211, 79,233,240, +225,195,169,135,135,135, 30, 37, 9, 55,125, 42,211,124,243,205, 55,235, 82, 74, 81,175, 94, 61,215, 96,191,102, 79, 99, 79, 30, +160,103,182,173,166,155, 38, 13,164, 29,219,248, 61,247,110,217,253,134,204,167, 69, 91, 91,231,206, 92,211,219,219,123, 14,165, +180, 55,165,212,135, 82, 10, 95, 95,119,199,118, 45,155,165,221, 56,113,128,158,253, 97, 13,221, 52,105, 32,237, 20,224,159, 85, +215, 47, 60, 65,234,217,178,131, 61,154,150, 38,139,245,109,221,242,185, 87,179,206,127, 90,171,175,185,102,227, 14,111,255,146, +154,150, 65, 47, 93,186, 68, 15, 29, 58, 68,207,158, 61, 75,183,253,244, 11,173,223,126, 72, 97,237, 54,253,187,216,218,183, 61, +245, 4,224,210,167, 79, 31,122,239,222, 61,250,250,235,175, 83, 0, 46,213,209, 4,176,255,209,163, 71,244,230,205,155, 52, 50, + 50,146, 2,216, 50, 97,194, 4,101, 94, 94, 30,237,217,179,103, 50, 74, 58, 41, 8,171, 83,207, 38,141,234, 68, 15,232,215,109, +193,164, 15, 7,133,190,236,249,172,169,137,215,228, 53,121, 77, 94,243,223,160,249, 79,155,108,122,176,126, 47,121,251, 95,223, +198,139,252,184,100,217,215,211,191, 89,191,101,230, 39, 31,189, 47,239,214,181, 23,226, 78,124,143,159, 15,254, 84,164, 82,107, +150,177, 2,124, 21,247,220,114, 50, 78,115,126, 75,160,162,242,203, 8, 33, 14,181,154,194,148, 67,233,126, 14, 64, 41,173, 82, +204, 48,165, 52, 29,192, 88, 66,200, 87,225,225,225,139, 63,232,210, 97,224,164,206, 61,160,211,233,176,109,219, 54, 36, 37, 37, +237, 5, 48,151, 82,106,151,135, 45, 46, 46,238,121,171,102, 13,167,212,146,177, 51, 39, 14, 31,224,145,249, 32, 30,169,183,175, + 3, 0,212,106,165, 46,253,110, 76, 96, 85,234, 39,147,201, 46,121,120,120,220,241,240,240,200, 49,168, 11,199, 74,133,206,243, +198, 15,125,203, 51,235, 81, 2, 82,110,149,180,128,170, 85,197,218,148,187,167, 90, 86, 69,215, 72,195,134, 13, 37,114, 17,198, + 89,172,175, 70,165,123,122,239,118, 91,123,116,138,213,154, 37, 11, 87,108,123,245,243,153,239, 74,156,157,157,113,237,230,125, +204, 91,190,163, 72,169,209,245,206,140,221, 87, 35,205, 96,148, 82,232,116, 58,187, 59, 48, 88,225,147,192,192,192, 22,139, 23, + 47,246,141,136,136,192,203,122,174,204,121,240, 48,117,118, 88, 88,152,255,253, 59,215,194,107,201,216, 31, 95,230,124,242,240, +240,240,240,252,123,177, 43, 6, 43, 46,131, 22, 3, 88,212,196,139,172,155,179,120,197,124,134,172,124,151,163,244,123, 61,131, +133,137,207,105,197,136,247, 42, 64, 41, 45,238,211,146,232, 95,237, 63, 92, 8, 0, 34, 97,165,241, 81,182,180,238, 1, 24, 68, + 8,105,255,221,185,203,255, 41, 93,252, 57,165,180, 74,109,181, 78, 66,220,236,234,223,164, 78,183,118,173,164, 2,131, 18,169, +183, 31, 32,187, 72,133,227,183,146,114, 25,202,124, 95,213,122, 37, 38, 38,254, 14, 0,173,155, 53,188,221,205,191,105,253,238, + 65,173, 28, 68, 68,131,212,248,107,200, 83,106,112,236, 86, 82, 30, 8,169,118,160,116, 77,213,247,105,236,254, 43, 30, 1, 3, +122, 18, 66, 78, 68, 78, 26, 38,153,191,124,103,141, 26, 87, 0,138,159, 60,121,146, 85, 92, 92,236,158,150,150,166, 65, 53,147, +187, 81, 74,239, 19, 66,218, 76,157, 58,117,209,140, 25, 51,102,126,241,197, 23,108,117, 98,174,172,145,243, 36,105, 95,247, 86, + 53,119,253,121,120,120,120,120,254,125, 84, 41, 77, 67, 98, 6,205, 4, 48,177,105, 83, 50,237,193, 3,170,169,169, 74, 88,242, +108,189, 12,165, 6, 85,191,106, 11, 48,164,224,226,189,164,194, 75,247,146, 10,193, 81,202, 81,170,102, 24,164, 20,105,181, 75, +238, 38,166, 86,191, 23, 29, 33,134, 43,247,147,149, 87, 31,164,168, 40,199, 81,142, 82, 13, 33,120,170,211,113, 75,110, 38, 62, +254,229,239, 80,223,204,216,125,231,188,253, 7,118, 59,119,233,230,180,162, 34,237,154,204,248,125,231,171, 93,175,114, 80, 74, +117,132,144, 17, 33, 33, 33,239, 25, 12,134,117,148, 82,221, 75,104,105, 0,124, 66, 8,217, 27, 23, 23,183,235,252,249,243,233, +168, 1,227, 10,192, 95,119,253,121,120,120,120,120,254, 53, 84, 43, 15, 86, 77, 26, 87,127, 71,226,238, 61, 10,250, 43,116,111, +222,123,212,250,175,208,173,233,250, 62,141,223,123, 21,192,208,154,212, 52, 66, 41, 61, 6,224, 88, 13,234, 93, 33,132, 52, 2, + 32,168, 17,227, 10,127,221,245,231,225,225,225,225,249,247, 80, 45, 3,139,135,231,239, 4, 45,137,184,172, 17,227,138,135,135, +135,135,135,167, 38, 32, 0,122, 90, 90, 65, 41, 61, 97,183, 8, 33, 22, 53,108, 81,153, 62,175,201,107,242,154,188, 38,175,201, +107,242,154,255, 60,205,127, 13,127,101, 23, 69,252,143,116, 13,229, 53,121, 77, 94,147,215,228, 53,121, 77, 94,243,255, 87,243, +159, 54, 49, 53,109,176,241,240,240,240,240,240, 24, 33,132, 72, 74, 7,120,175,214,122, 30,158,255, 85,170, 28,131, 69, 8,105, + 6,148,116,149,175,249,234,152,246, 49,201,199,199,103,108, 64, 64,128, 31,203,178, 76, 65, 65,193,194, 83,167, 78, 45, 40, 95, +174,123, 43,209, 85, 1,131,186,102, 91, 2, 68, 0, 48, 12, 12, 20,169,103,110, 20, 7,255, 85,117,228,121,121, 8, 33, 13,100, +206, 30,191, 18, 70, 32, 54,232,181, 48,232,180, 0, 94, 12,155,196,113,250, 36,189, 70,245,154,181,237,125,218, 14,172,175, 55, +208,104,128, 91, 75,192,140,167,224,190, 37,148, 25, 79, 25,172, 37, 28, 62,132, 80,183, 12,122,209, 12, 33, 43,156,155,118,109, +119,202,127,227,152,254,106,246,236,217, 35,120,153,237, 7, 15, 30,108,113,128,207, 58,117,234, 28,116,112,112,104,106,109,187, +162,162,162,244,180,180,180,240,151,217,247,223, 29, 66, 72,119, 0, 95, 3,104, 85,110, 85, 2,128, 41,148,210,147, 47,187,143, + 48, 66,132, 94,192, 56, 22,152, 5, 0, 90, 96,105, 6,176,254,247, 26,234,160, 81, 19,120,122,122,158, 17, 10,133,190, 69, 69, + 69, 69,249,249,249, 77,156,157,157, 19,229,114,185, 92,175,215,223,123,246,236, 89,247,170,104, 17, 66, 38,160,116,200, 43, 66, +200, 76, 74,233,218,170,172,231,225,249, 95,166, 82, 3,139, 16,210, 28, 64,104,233,212,189,125,251,246, 94, 69, 69, 69, 32,132, +100, 0, 56, 3, 32, 6, 64, 12,165,244,110, 77, 84, 72, 32, 16,124,185,106,213,170,233,147, 39, 79, 54, 13,210, 28, 27, 27,107, +185, 44,131,186,167, 15,158,244,188, 18,123, 7,237,123, 14, 70,137,129,197, 0,197, 79, 17,222,179,125,181,246, 79, 8,113,114, +115,115, 91, 72, 8, 25,194, 48, 76,165, 15, 51,142,227, 12,148,210,221, 57, 57, 57,243, 41,165, 5, 85,217,151,163, 92,170,211, + 27, 12, 22,247, 33, 20, 8, 12,133, 69, 42,171,233, 43,220,221,221,207, 51, 12,211,216,124, 32,235,210,250, 91,252,110, 62,175, +215,235, 83, 51, 51, 51, 43, 53, 62, 9, 33, 82, 70,200, 78, 33,132,237, 5,134,107, 14, 16, 16, 48,119, 57,131,230, 56,167,215, +174,162,148,218, 30,101,219,182,118, 3,159,122, 77,206,126, 60, 55,186,238,205,219, 9,136,156, 52, 28, 95,124,189, 5,115,166, +188,135, 85, 27,118, 96,202,216, 97,240,247, 47,255,156, 43,139,129,146,133,243,166,140, 8, 95,188,106,123,251,185, 83,134,203, + 23,175,218,222,126,238,212,225,142,139, 87,111, 15,158, 59,117,132,227,231,171,127, 12,254,207,212, 17,206,139, 87,111,215, 2, + 24, 83,157,122,142,104, 94,167, 8,122,189,229,183,107,161, 80,253,227,221, 39,242,234,232,190, 44, 17, 17, 17, 1, 74,165,242, +218,240, 94,237,162,219, 54,175,243,196, 82,153,172,167, 79,234, 36,222,185, 62, 91,196,202,130,222,154,189,197,242,159,168, 20, +137, 68,210, 56, 33, 33,193,151,227, 56, 24, 12, 6,232,245,122,211,167, 70,163, 65,247,238,221,107,164, 67, 12, 33,164, 31,128, +133, 40,137,255,140,162,148,238,122, 9, 45, 71,161, 80,248,177, 88, 44, 14,213,235,245,126, 0, 32, 18,137,110,171,213,234, 24, +189, 94,191,130, 82, 90, 88, 69,201,149, 79,158, 60,241,119,116,116,132, 86,171, 53, 13, 12, 47, 16, 8, 90,214,175, 95,255, 27, + 0,190,213,173,171, 17, 47, 96, 92,231,174, 93, 87,141,158, 62, 93,160, 60,115, 6,171, 54,111, 94,137,252,124, 0,248,166,178, +109, 37, 18,201, 81,134, 97, 26, 84,101,127, 28,199, 37,169,213,106,171, 47, 41,150, 16, 10,133,190,105,105,105,158, 10,133, 2, + 0, 32,151,203,229,230,243,246, 82,234,149, 90, 70, 41,149, 1, 0,195, 48,171, 58,119,238, 28, 66, 8,209, 3,160, 28,199, 49, +132,144, 97, 28,199, 9, 75,203, 47, 35,132,108,166,148,170,171,180, 35, 30,158,191, 41, 86,111,154,132,144, 67, 0, 66,219,183, +111, 47, 27, 58,116, 40, 66, 67, 67,225,235,235, 11,169, 84, 10, 0,200,202,202,242,250,243,207, 63,223, 62,115,230,204,219, 7, + 14, 28, 0, 33, 68, 9,224, 15, 74,169,197, 63,115,207,126,221, 38, 75, 29, 37,171, 1, 32, 51, 53, 43, 61,245,225,179,213,233, +233,233,203,168,217, 40,209,132,144, 38,163, 71,143,158,246,209, 71, 31,225,224,193,131,216,177, 99, 7,212,106, 53, 10, 10, 10, +112,234,212, 41,203, 21, 45,122,134,156, 83,209,128,252, 49,144,252, 59,224,224, 9,200,189,170,125, 66,220,220,220, 22, 78,153, + 50,101,170,191,191, 63, 40, 45,201, 58,174,211,233,160,215,235,161,211,233,144,147,147,131,105,211,166, 1, 40,137, 95,227, 56, + 14,135, 15, 31,158, 60,118,236, 88, 0,248,216,146,102, 72,112,253,171, 12, 97,234, 26,125, 51,212, 96, 72,189,112, 61, 37, 88, +111, 48, 8, 84, 42,173,197,145,195,165, 82,214,166,113, 39, 18,137,234,198,255,250,171, 39, 35, 22,131, 26, 12, 0,199,129,114, + 28, 0,179,137,150, 44,163, 6, 14, 84,103, 0,167,231,160, 87,170,209, 97,194,132, 74,207, 3, 33,164,179, 72, 44,219, 49,226, +131,233,222, 29, 59,117, 18, 53,172,167,128,222,192,225,193,163, 84,239,107, 87, 47,118,217,189,245,155,241,132,144, 97,148,210, +106,229,201, 18, 59, 56, 31, 91,243,237,119,117,175,252,121, 19, 39, 79,159,193,137, 83, 49, 0,128,163,167, 75,228, 24,198,118, +235, 53, 33,196,205,221, 55, 60, 96,242,123,253,229,159,127,181, 81, 50,249,189,254,194, 23,159,223, 73, 38,191,247,150,112,241, +138,239, 36,147,223,123, 75,244,217,210, 53,109, 9, 33,110,148,210, 28,107,122,214,174, 17,244,122,201,143,137, 25, 2, 0,200, + 92,183, 14,186,103,207,160,152, 63, 31, 0, 48,162,137,151,221,205, 26, 30, 30, 30, 87, 69, 34, 81,221,202,202,233,116,186, 74, +141,223,136,136,136, 64,165, 82,121, 85,175,215, 83,161, 80, 56,123,248,128, 87,247,247,238, 22,152,101, 94, 38, 54,246,134,251, +146, 37,191,246,223,117,173,128,190, 29,228,116,237,224,151, 17,193,125,103,108,177, 58, 98, 60,199,113,140, 90,173,198,189,123, +247,140,241, 21,229,177,232,249,170, 12, 66, 8, 3, 96,149,187,187,123,199,172,172,172, 17, 0, 34,243,243,243, 3, 4, 2, 1, +106,213,170, 21, 73, 8,121,224,226,226,178, 49, 47, 47,239, 60, 74,188, 68,118,165,248, 39,132,116,119,118,118,222,182,111,223, + 62,183,118,237,218, 49,153,153,153,104,220,184, 49,178,179,179, 59,156, 57,115, 38,104,204,152, 49, 99, 8, 33,163, 40,165,103, +170, 80,221, 22, 14, 14, 14,116,244,232,209,196, 96,120,113,184,155, 54,109,194,107,173,245, 77, 63,236, 45, 47, 86,105,104,222, +201,123, 46, 31,178, 44,251,199,227,199,143,243,170,116, 50, 0,176,192,172,209,211,167, 11, 28, 31, 63,134,227,141, 27, 24,145, +159, 47,252,162,196,155, 85,169,129,197, 48, 76,131,109, 59,191,247, 21,139,197,166,251,146,181,201, 96, 48, 64,171,209, 34,250, +115,139,227,165,219,133,131,131,131,131, 66,161,200,112,112,112,112,168,182,136, 25, 18,137, 68,184,117,235,214, 97, 98,177, 24, + 0,160,209,104,208,186,117,107,139,247, 63, 30,158,127, 2,182,222,221, 69, 37,160, 0, 0, 32, 0, 73, 68, 65, 84, 74, 95,207, +207,207,135,193, 96,128,147,147, 19, 4,130,178,207,123,119,119,119,244,234,213, 11,221,187,119,199,208,161, 67, 17, 31, 31, 47, + 27, 58,116,104, 47,107, 98,195,167,247, 69, 61,223, 18,195, 71,167,227,124,206,253,246,103,244,166,207,246,120, 0,152,110, 86, +108,204,184,113,227, 72, 86, 86, 22,134, 12, 25,114, 70,173, 86,191, 73, 41,205,183,166,105,224,144, 26, 62,116, 56, 56, 74,100, + 43, 46,109, 32, 26,149,146, 50, 12,163, 52, 54, 17,218,117, 6,202, 65, 8, 25,162, 80, 40,176,115,231, 78,104, 52, 21,211,125, + 57, 59, 59,227,214,173, 91,166,121,129, 64,128, 78,157, 58, 9, 8, 33, 67, 96,197,192, 34,132,169,123,238,202, 99, 79,227,124, +223, 94,173,216,144,224, 6, 25, 30,238, 78, 20, 0,153, 59,119, 46, 0,152, 30,108, 11, 23, 46,180,167,158, 96, 68, 34,100,198, +196,152,150, 49, 66, 6, 12, 75, 64, 68, 0, 35, 44,105, 45, 5, 5,168, 1,224,244, 0,167, 3,164, 62,245,236,209,238, 80,167, +190,239,193, 37,203,215,186,170,117, 20, 59,127, 57,137, 71,143, 30, 66,192, 48,104,210,212, 23,175,134,117, 19, 5,181, 15,169, +183,116,193,244, 3,132,144,215, 41,165,118, 13, 76, 93, 6,142, 74,155,214,175,141,141,155,174,193,195,205, 17, 67,250,191, 1, +153, 84,130, 47,190,254, 30,159,207,153, 4,223, 38, 13,176,126,229, 98,171,155,187,184,184, 44,106,215,166,101,147,239,119, 29, + 65,104,247,206,194, 45,187,142, 34,172,123, 23,225,247,187,142, 32, 44,180,155,112,203,174, 35, 8,235,222, 85,180,101,215, 17, +116, 10,110,211,244,124, 86,236, 34, 0,147,172, 31,115,185,107,244,106,201, 53,242, 21,178,166, 7,192,227,241,227, 1,192,100, + 96, 85, 5,145, 72, 84, 55, 45, 45,205,179,178,114,149,121, 9, 74, 61, 87, 87,245,122, 61,158, 61,123, 70,114,115,115,169,171, +171,107,255, 35,235, 35,247,189,214, 53, 48, 27, 0,110,220,184, 81, 43, 42,106, 73,255,159,174,230, 67,121,113, 13,249,241,215, + 24,110,196,155,161, 87,127,137,142, 8, 26, 60,120,240,117, 75,186,106,181,250, 81,219,182,109,105,233,247, 58, 18,137,132, 53, + 95, 79, 8, 81,248,250,250, 86,240, 82,219,209,116,184,234,194,133, 11,147,252,253,253,209,178,101,203,243, 29, 59,118,116,150, +203,229, 56,114,228, 8,252,252,252, 90, 57, 59, 59, 95,218,189,123,183,232,147, 79, 62, 9,220,188,121, 51, 0, 76,182,125,134, + 74,122, 53,133,135,135,239, 60,120,240,160,148,101, 89, 40,149, 74,220,186,117, 11,174,174,174, 16,139,197,120,235,173,183, 4, + 93,186,116,113, 15, 11, 11,251,185,244, 37,192,238, 30, 77, 42,149,138, 70, 70, 70,194,193,193, 1, 14, 14, 14,144,203,229,144, +203,229,112,148,130,172,155, 82, 95,246,209,134, 92,217,199,243,215, 69,111, 91,187,224,116,253,250,245, 63, 77, 78, 78,206,181, + 87,219,136,242,204, 25, 56,222,184, 1,152,253,119,237,197,197,161, 22,102,207,158,109,179,140, 80, 40, 4,203,178,232,220,185, +115,165,122,238,238,238,123,133, 66, 97,153, 55, 82, 74,169,116,246,236,217,134,187,119,239,202, 25,134,145,115, 28,135,217,179, +103, 27,244,122,189,212,203,203,235, 60,199,113, 25,153,153,153, 3, 43,211,166,148,170, 9, 33, 51, 25,134, 89, 37,145, 72,132, + 13, 27, 54, 76,154, 55,111,222, 5,148,120, 47, 65, 41,101, 26, 54,108,216, 65, 38,147, 53, 80,171,213,122, 0, 51,121,239, 21, +143, 13,130, 0,152,255, 86, 53, 0,196,165,223,179, 80, 18, 95, 82,187,220,114, 0,120,142,146, 23, 68, 47, 43,243, 89, 0,226, + 1,180, 0,224, 89,186,238, 10,128,236,151,173,176,209, 53,107,122,101,165,148,154, 30, 40, 78, 78, 78,184,114,229, 10, 8, 33, +112,114,114,130,179,179, 51, 92, 92, 92,144,159,159,143,248,248,120, 36, 36, 36,224,241,227,199, 32,132,160, 73,147, 38, 64,233, + 31,199, 76,203,116, 99,219,254,213, 65, 72, 29, 37, 32, 4,104,215, 35, 0, 1,221, 91,163,253,229,196, 41, 10,133, 98, 67, 90, + 90,218, 61, 66,136,176,117,235,214, 99, 58,117,234,132,229,203,151, 67,173, 86, 47,183,100, 92,153,107,158,185,165, 11, 6, 0, +133, 66, 49,227,135, 35, 15, 28, 70,246,110, 90,156,150,150,246,101, 85, 79, 66,249, 27,240,243,231,207,237, 30, 43,143,227, 56, +228,228, 84,116,140,152,107,150,247, 8,172, 88,181,198,181, 32, 47, 3,159,125,241, 3,116, 58, 29,166, 79,159, 14,142,227, 76, + 83,110,174,229,123,118,249,122, 82, 67, 57,167, 2, 83, 50, 17, 6, 32, 66,160,254, 59, 37,246, 68,242,206, 53, 32, 20, 32, 6, + 0,229,142,171,188, 38, 33, 68, 42, 96,101, 63, 45,248, 98,181,235,245,132, 84,252,114,242, 58,180,249, 79,144,126, 99, 31, 0, +160, 73,231, 97,216,165, 22,160, 99, 64, 83, 76,157,187,212,237, 63, 83, 71,253, 68, 8,105,105,222, 92,104,207, 3,141, 82, 3, + 62, 91,180, 8, 27, 86, 47,199,210,229,171,145,159,151, 11,145,168, 54, 0, 64,175, 55,192, 80,238,216, 42, 28, 59,165,189,255, + 51, 99, 28, 89,245,221,207,104,221,204, 27, 7,142,159, 71,112,171, 6, 56,124,234, 50, 58,181,105,132,163, 49,215,208, 41,160, + 49, 98, 46,222,194,244,137,163,201,185,195, 91,122,219, 58,159,229,175,209,202,149,107, 92, 11,242, 51,112,112,241, 86, 60,251, +230, 27, 36, 77,154,132, 14,165,101, 46, 19, 2,182,110, 93,128, 69, 5, 42, 59,246,219,183,111, 67,173,174,248, 12,145, 72, 36, +240,243,243,179,184,141,185,166, 82,169,188,166,215,235,105, 70, 70, 6,201,200,200,128, 92, 46, 39,183,110,221, 52,180,106,213, +122, 0, 77,216,243, 29, 0, 68, 69, 45, 25,176,235, 90, 62,138,207,175,134,242,194,215, 96, 27,197, 50, 27, 22,142,211,142,157, +191,254, 26, 94, 60,220,202,212, 51, 61, 61,253,117,227,247, 38, 77,154, 36,220,189,123,183,133,177, 73,185,180,169,144,213,235, +245,190,198,102, 67,189, 94, 15,181, 90,141,158, 61,123,154,222,188, 44, 29,187,155,155, 91, 39, 63, 63, 63, 92,191,126, 29,171, + 87,175,174, 21, 30, 30,142,251,247,239,131, 16,130, 37, 75,150, 16,127,127,127,209,243,231,207,241,218,107,175, 97,239,222,189, + 21, 44, 2, 11,191, 79, 39,185, 92,190,249,192,129, 3, 82,134, 97, 80, 80, 80, 0,142,227,208,181,107, 87, 48, 12,131,155, 55, +111, 98,238,220,185,216,187,119, 47,246,239,223, 47, 11, 10, 10,218, 76, 8,241, 51,111,190,183,113,141,168, 74,165,162, 18,137, + 4, 18,137, 4, 82,169, 20, 82,169, 20, 98,177, 24,133, 42, 96,236,138, 36,181, 64, 90,155,107,213,182,107,211,119, 63, 90,194, +124, 57,239,189, 83, 0,126,169, 68,179, 12, 90, 96,233,170,239,191, 95, 61, 34, 47,143, 1,128,141,132,112, 90, 74,151, 90,172, +140, 5,205, 2, 85, 46, 26, 52,173,139,159,119,238,199,160,161,253, 43,108, 35, 20, 10, 33, 18,177, 96, 69, 34, 56,213,170,232, +120, 42,175,201,178,172, 87, 66, 66,130,187, 72, 36, 50,121,228,117, 58, 93,198,188,121,243, 60,250,244,233,227,116,248,240, 97, +166, 79,159, 62, 92,237,218,181,139,174, 95,191,254, 76,171,213,186,119,233,210,165,210,122,154,173, 91,219,182,109,219,118,251, +246,237,123,111,246,236,217, 87,103,204,152,241,153,249,250,101,203,150, 45, 58,116,232, 80,131, 1, 3, 6,108,251,243,207, 63, +215,154,109, 87,227,221,252,121,205,191,191,166, 53, 91,164, 20, 47, 66,200, 65,179,245,125,141,243,179,103,207,142,140,138,138, +186, 69, 8, 57,104,190,220, 88,174, 84,251,160,165,249,210,109,107,205,153, 51,167,117,116,116,244,146,144,144,144,157,231,207, +159,127,136,154, 50,176,140, 7, 98,126,112,230, 80, 74,145,159,159,143,252,252,124,164,164,164, 96,221,186,117,165,127,100, 17, +132, 66, 33,132, 66,161, 41, 94,193, 26, 39, 14,156,253, 26,192,215, 65, 65, 65,162,184, 11,187, 15,207,218,240,209, 43,193, 61, +219, 9,174,157,140, 27, 12,224,115, 0,175,143, 30, 61,186, 54, 0,108,221,186,245, 57,128,195, 47,123,112,213,129, 82,186,251, +222,189,123, 83,125,124,124, 76, 49, 40,230,205,132,122,189, 30, 82,169, 20,198, 88, 21,149, 74,133,117,235,214,233, 41,165,187, +109,104,226,238,173, 83,184,119,235,116,201,118, 28, 7,206,240, 98,251, 5, 11, 22,152,119,125,197,248, 82, 79, 73,101,112,150, +206, 57, 45,247, 89,110,121, 5,163,172, 28, 12,195,126, 52,120,212, 36, 31,142, 8,241,235,169, 63, 33, 18,137,192,153,121, 47, + 69,130,146,183,227, 91,247,211,160,240,106,133, 55,135,141,243,222,183,109,205, 71, 0,190,176,171,210,102,180, 12, 12,193,148, +169, 83,241,221,134, 13,152, 59,127,145,201, 58,215, 27, 12,208, 87, 90, 79,134,233, 18,236,143,194,172, 84, 8, 4, 2,116,110, +219, 20, 2,129, 0,221,130,155, 67, 32, 16,160,107,251, 22, 16, 10,133, 8,235,228,143,102,205,154, 65, 40, 20,218,108,115, 44, +185, 70, 39,113,239,214,239,102,198,110,201, 53,209,166,167, 87, 40,175, 75, 79, 7,173,239, 94,165,227,165,148, 98,204,152, 49, +185, 41, 41, 41,218,242,235,234,213,171,199,158, 57,115,198,213, 74,243,156, 9,153, 76, 22, 36, 20, 10,175,101,103,103,115, 14, + 14, 14, 12,199, 25,184, 86,173, 90, 11,142,172,143,220,103, 44, 51,103, 78,228,190,183,131,156, 7,252,176,251, 32,101, 27,118, + 37, 68, 36,209,127, 48,127, 61, 43, 98,101,118,101,168, 55, 54, 23,222,185,115,199, 90,115,161,249, 49,217,108,226,201,201,201, + 25,237,231,231,119,230,235,175,191,174, 69, 8,193,217,179,103, 33, 16, 8, 76, 83, 98, 98, 34, 24,134,193,172, 89,179,180,249, +249,249,239, 87, 86, 55,161, 80, 56,245,231,159,127,118, 17,139,197, 40, 40, 40, 48,253,111, 4, 2, 1, 18, 18, 18,240,229,151, + 95, 98,244,232,209, 72, 78, 78,134, 66,161,192,244,233,211, 29,163,163,163,167, 2, 88,100,199,161,199,106, 52,154, 96, 7, 7, + 7, 72,165, 82, 24, 13, 45, 0, 56,118, 75,116,179,184,184,184, 77,237,218,181,189, 61, 98, 14,254,218, 57,252,205, 64,119, 15, +159, 16,148, 26, 88,246,242, 0,216,240, 80,175,255,207,235,251,246,121,158,219,183,143,187,240,235,175,169,210,194,194,245,118, + 11,232, 4, 72,122,144,138,160,160, 32, 92,187,118, 13, 65, 65, 47, 46, 41,203,178, 16,139,197, 96, 89, 22, 44,203,162,182,171, + 93,161, 18,148, 97, 24,156, 59, 87,118,184,209,110,221,186,101,159, 62,125,218, 17, 0,146,146,146,104,223,190,125,115,227,227, +227,225,235,107, 59, 12,205,219,219,251,140, 64, 32,104,104,190,140, 97, 24,183,129, 3, 7, 34, 39, 39,231,141,129, 3, 7,118, + 45, 93,246,100,207,158, 61, 35, 1, 64, 44, 22,131, 97,152,106, 53, 65,243,252,179,168,204, 22, 41, 45,211,183,252, 60, 33,228, + 96, 84, 84, 84,223,242,203,204,141, 41, 75,223,205,183,141,142,142, 94, 98,166,173,172,137,227, 49, 53, 17, 18, 66,104,101, 55, + 75, 91, 84,102, 96, 25,185,118,237,154,174, 78,157, 58,223,221,251,243,241, 43, 77, 3,154, 64, 38,151,188, 74, 8,249, 90, 34, +145, 76, 27, 53,106, 20, 46, 94,188,136,155, 55,111,110,162, 47,217,171,166, 77,155, 54, 71, 37, 18, 73, 3, 75,235,212,106,117, + 82, 92, 92,156,197, 88,177,156,156,156,249,165, 49,101, 86,131,220,205,227,193,204,131,220,173,213,133,114, 20, 58,173, 14, 69, +197,202, 23, 15,239, 82, 3,171,168,168, 8,239,188,243, 78, 25, 15,214,179,103,207, 42, 61, 62, 66, 8,190,252,229, 23, 28,223, +189, 27,111, 4, 6, 98,239,229,203,136, 30, 53, 28, 45, 27,212, 1, 53, 16, 80, 2, 36,239, 88,131,172,252, 66,108, 63,121, 14, +217, 5,197, 24,209,173, 27,124,157,107,219,214, 21,177,189, 58,116, 10, 97, 79,156,143,135, 72, 36, 4, 3, 14, 84, 87, 12,133, + 95, 24, 4, 12, 3, 23,175, 70, 96, 69, 34,136, 68, 66, 36,166, 60,135, 95,235,246,226,131, 98,105, 47, 84,195,192,170,223,160, + 49, 56,131, 1,163, 71,143,198,206,157, 59,225,238,221, 0, 46,245, 90,227,243,229, 27,240, 70,207,110,149, 30, 63, 0,147,129, + 47, 16, 8, 42,124, 26,191,219,227,141,164, 28,133,182,252, 53,226, 40, 40,128,186,139, 23,163,238,226,197,184, 92,186, 79,255, +162, 34, 40,149, 74,160,163,237, 32,252, 50,250,148, 66,163,209, 32, 37, 37, 69,155,158,158, 94,225,201,231,237,237,157,161,209, +104, 42, 53,104,182,108,217, 18, 27, 17, 17, 17, 92,171, 86,173,171,177, 55,110,232, 2, 2, 3, 69,135,215, 69,238, 55, 54, 15, + 2, 64, 96, 96, 96,118,100,100,228,254,145, 67,250,246, 95, 59,123,168, 97,194,162,109, 66,137, 76, 22,220,119,134,237, 64,119, + 35,106,181,250, 81, 64, 64,128,237,138,148, 82, 92, 92,252,212,218, 58, 99, 64,123,187,118,237,156,195,195,195,113,230,204, 25, + 12, 26, 52, 72,173,213,106,239, 1, 64,159, 62,125,154,111,223,190, 93, 28, 31, 31, 15, 15, 15, 15, 81, 82, 82,210,102, 66,136, +205,192,119,177, 88, 28,214,190,125,123, 70,173, 86, 87, 48,174,162,163,163, 49,108,216, 48, 52,111,222, 28, 28,199,161,176,176, + 16,225,225,225,162,213,171, 87,135,193, 62, 3,107, 74,203,150, 45,191, 68, 73, 47, 66,243,123,225,109, 0, 51, 1,224,249,243, +231, 79,251, 14, 26,125,171, 91,207,129,193, 13,155,181,246,169, 76,208,203,203,107, 14,195, 48,111,115, 28, 39,200,207,207, 79, +209, 16,210,204,191, 97, 67,175, 46,253,251, 35, 79, 36, 18,172, 58,121,146,201, 40, 44,116, 4, 96, 87, 83,163, 82, 87,136, 6, + 77, 75, 66,249, 6, 13,237,143,107,215,174, 97,240,176, 1, 96, 89, 22, 66,161,168,228,191,201,150,120,176, 92,107, 59,217, 35, + 9,157,174,236,144,160,198,243,234,236,236, 12,160,164, 37,195,184, 76,167,211,217,124,248, 1,240,221,181,104,158,167,204,217, + 5, 6,157, 14,173,250, 15, 54,253,166, 47,109, 92, 43, 3,199,201,114,147, 30, 97,242,238, 3, 53, 58,254, 44,207, 63,135,202, +108, 17,115, 3,169, 6,246,117,112,246,236,217,145, 0,232,236,217,179, 35,141,243, 81, 81, 81, 74, 0, 22, 59, 15, 85, 5, 83, + 19,225,203, 24, 87, 0, 42, 52,233,148,167, 71,143, 30,147,157,156,156, 86, 3, 64,112,112, 48, 82, 46, 62, 65,202,197, 39,240, +107,209,170, 75,187,192,224,188, 97,195,134,193,221,221, 29, 51,102,204,160, 0, 54, 85,117,255,137,119,111, 57, 2,160, 10,133, + 98, 6, 0, 40, 20,138,192,203,151, 47,123, 92,185,114, 5,237,219,191,232, 81,168,213,106,209,181,107, 87,171, 58,165, 77, 9, + 31,195, 74, 60, 85,117,160,148,131, 86,171, 69,113,177, 18, 26,141, 22,122, 29, 7,189, 94,143,160, 86, 78,216,182, 97,118,201, + 50,189,209, 91, 86,226, 37,171,235,237,132,160, 54,222, 58,134, 33,202, 43, 55,210,157, 45,233,106, 52, 26,196, 38, 37,225,198, +227,199, 0,128, 55,163, 44,182, 52,152,216,118,242, 12,252,253,253, 43,171,109,211,186, 10,111,164, 29,143, 45,185,105, 43, 83, +112,229,143, 93,112,114,114, 4, 0,180, 10, 29, 1,150, 45, 49,176,138,148, 90,212,110, 81, 15,132, 82,171,221,251,229,181,124, +142, 10, 89,105, 3,106,224, 64, 41, 7,202, 25, 64, 41, 7,137,147,187,195,164, 15,223, 5,199, 25,208,161, 67, 7, 16,129, 0, + 6,157, 26, 67,250,245, 66, 78, 94, 1,220, 93, 45, 30,114, 5, 88,150, 69,104,104,168,204,218,250,251,247,239, 43,129,138, 61, + 42, 43, 28, 53,229, 74, 12,172, 34, 37,212,106, 53,180, 26, 61,180, 58, 61,184,198, 44, 62,251,207,112,232,181,122, 20, 15, 13, + 41, 89, 54,117, 0,180, 26, 29,146, 29, 24, 38,208,223, 67,199,128, 40,175,199, 63,179, 89, 97, 74, 41,140, 70,129, 53, 44,197, +252, 89, 98,203,150, 45, 55, 34, 34, 34,130, 2, 2, 3,175,189,221, 51,240,171,184,155,183,210,226,110,222,170, 80,174, 65,243, +192, 71, 19,162,119, 78, 23,177,178, 32,123,141, 43,160,108,115,225, 75, 18, 89, 80, 80, 16,224,232,232,136,187,119,239, 66, 32, + 16,128, 16,114,159, 82, 26, 0, 0,227,198,141,123, 32, 20, 10,155, 8, 4, 2,124,243,205, 55, 68, 40, 20,182, 9, 9, 9,137, + 4, 96,213,192,210,235,245,126, 78, 78, 78,101,188, 87, 44,203, 98,246,236,217, 24, 57,114,164,201,184, 98, 89, 22, 91,182,108, + 65,112,112, 48, 52, 26,141,229,182,215,114,208,146, 65,226,109, 91,246, 0, 56,142, 43,105,102,229, 42,177,134, 75,234, 27,145, +245,246,219,205, 16, 19,131, 46, 77,154,248, 7, 5, 5, 65,171,125,225,192,108,220,184,113,189,130,130,130,167,132,144, 31, 1, +172,165,148,254,105, 83, 79, 69,145,244,160, 36,188,244,218,181,107,232,208,161,131,201, 99,101,238,189, 98, 89, 22, 50,214,177, +178,234, 1, 40,107, 96, 81, 74, 81, 84, 84,196, 28, 57,114,164,182,159,159, 31, 1, 0,127,127,127,114,241,226,197, 90, 50,153, +236,185, 66,161,168,244,197, 87,230,236,130, 45, 17,239, 0, 0, 62,237, 89,210, 50, 79, 8,193,145,133,145, 16,137, 68,120,101, + 70,100,153,242, 26,141, 6, 28,199,189, 84,250, 17,158,127, 6,246,216, 34, 53,101, 92, 25,181,140, 30,172,168,168,168, 91, 81, + 81, 81, 21,188, 97, 47, 67, 25, 15, 86,233, 14,171,101,104,149,127, 11, 42,207,242,229,203,209,166, 77, 27,171,235, 41,165, 88, +189,122, 53,126,248,225,135,229,148,210,196,170,238,191,239, 43,237, 90, 97,197,190, 91, 77,154,183, 34, 0,176,104,106, 63,166, +168,168, 8,231,206,157,131,139,139, 11,238,223,183, 47,109, 23, 33,196,201,197,197,101, 33,195, 48, 67, 4,229, 35,251, 45, 96, + 48, 24, 12, 28,199,237,206,203,203,179,154,166,129, 82, 64,171,211,163,168, 88, 5,141, 70,131,169,179,214, 84, 90,143, 40,128, +104, 53, 5,194,208,238, 33, 22,141, 7, 66, 8, 58,180, 14,197,196,145,242, 10, 15,109, 65, 73, 42, 48,180,237, 80, 50,182,244, +245, 75, 55, 65, 41, 96, 48, 0,181, 61,107, 97,211,206,175,108,237,154,232, 13, 92,233,219,176, 1,133,106, 3,252, 58,245, 69, +234,237, 24, 0, 37, 30, 35, 49, 91,210, 52,204,138, 68,224, 40, 41,201,222, 96, 5, 86, 44,107,144,147,158,232,187,225, 96, 28, +198,246,109,131, 61, 39, 98, 49,184,103, 0, 78, 95,138, 71,120, 71,127,220,186,247, 24,173,124, 27,226,155,205,187, 65, 41, 10, +190, 93,241,185,201, 35,194,113,250, 36,171,149, 52,243, 96, 93,188,120, 81, 89,222,107,101,254, 89,153, 87, 8, 40,249,253, 25, + 61, 88, 74,149, 26, 51,230,216,149,142,167,228, 26,117,235,100,213,192, 51,199,150,135,202, 30, 3,204,156, 45, 91,182,196,162, +146, 52, 43,141, 1, 4, 3,159,216, 37,248, 23, 97, 48, 24,240,219,111,191,153,174, 71,121, 8, 33,101, 60,142,149,193,113, 28, +146,146,146,112,243,230, 77,132,132,132, 32, 47, 47, 15, 34,134,193,244,184, 56,248,143, 26, 5, 13,203,130,227, 56,136,197, 98, +140, 27, 55,206,238,243, 89, 37, 74,239,145,148, 26,108,138, 19, 66,190,234,219,183,111,179,187, 69, 69,184,149,144,128,158, 11, + 22, 0, 0,126,251,237, 55, 83, 25,141, 70,131,105,211,166,137,227,227,227,199, 92,189,122,117, 12, 33,100, 57,165,116,186, 21, + 73,104,169,202, 20,131,245,246,136, 65,104,230,215, 24, 63,108,222, 97, 90, 63,109,214, 20,136, 68, 44, 68, 34, 17, 92, 93, 93, +237, 58, 26,243,123,119,113,113, 49,179,103,207,158,186, 97, 97, 97,236,216,177, 99, 9, 0,108,216,176,129,217,184,113,163,252, +216,177, 99,172,139,139, 75,197,246,242,114,232,181,101, 91,192, 9, 33, 32,132, 64, 36, 18,129, 21,179, 0,199,129, 16, 34, 95, +182,108,217,162, 91,183,110,181,111,217,178, 37,212,106,245, 40, 66,200,117,202,231,193,250,215, 83,153, 45, 98, 41,150,170,212, + 11,101,141, 76,243,184, 44,107, 6,154,121, 76, 22,128, 26,233,108, 81, 38, 6,203, 18, 2,129,160, 82,239, 20,195, 48,149, 54, + 17, 78,155, 54, 13, 78, 78,150, 93,214, 26,141,134,198,197,197,197,167,167,167,111,160,148, 86,110,125, 88,224,224,201,235,183, + 22,126, 60,160, 0,165,109,167,174,174,174,207,123,244,232, 81, 8, 64,187,107, 87,217, 23, 98,181, 90,157,100, 77,199,197,197, +101,225,198,141, 27, 63,234,223,191, 63, 83, 62, 85,128,121, 51,158,113,210,233,116,216,181,107,215, 71,159,124,242, 9, 96,197, +235,101,124,120, 23, 23, 41,161, 44, 13,112,126,112,115,143,125, 7,102,227, 1,225,232,166, 64,221, 38, 6,171, 15, 17,134, 45, +137, 17,242,110, 16,104, 90,230,228, 36,133,193,134, 38, 33, 76,226,227,228,180, 58,245,188,107,225, 65, 74, 38,188, 26,182, 65, +206,147, 23,231, 65, 40, 20, 64, 84,218, 68,232,234, 44, 71,230,179,103, 96, 24,129, 77,131,248,243,237,215,113,233,230, 99,252, +124,226, 79,104, 85, 69, 88,177,245, 8,180,234, 66,104, 85, 69,208,170, 74, 62,151,124,242, 1, 8,193, 83,173,170,176,185, 45, +173,242, 8,133, 66,116,236,216,209,170,129,243,228,201, 19, 59, 61, 88,212,228,193, 82,170,170,120,141,236,192,216, 68, 88,217, +250,234, 26, 4,198,212, 13, 50,153, 44,120,203, 22,235,233, 24, 44,225,227,227,115,216,209,209,177,145,189,229,171,144,116,116, +137,171,171,235,194,150, 45, 91,250,173, 88,177, 66, 36, 16, 8,240,202, 43,175, 52,255,224,131, 15,146, 0,160, 77,155, 54, 10, +160,228, 30, 51, 97,194, 4,122,241,226,197,155, 0,162,108, 9,138,197,226, 4, 23, 23,151,224, 30, 61,122, 32, 47, 47, 15, 41, + 41, 41,144,203,229,240,255,234, 43,196, 77,152,128,192,117,235,192,244,232, 1, 66, 8,196, 98, 49,226,226,226, 32,147,201, 18, +172,233, 17, 66, 58, 2, 88, 10,160, 11, 94, 52, 11, 82, 0,231, 0,204,162,148, 94, 42,191,141,241,198, 96,224,184,202, 46,214, +240, 25, 51,102, 32, 87, 36, 2,250,244, 1,155,152, 8,173, 86,139,144,144, 16, 4, 7,151,100,226, 8, 9, 9,129, 80, 40, 68, + 64, 64, 0, 20, 10, 5,190,249,230,155,225, 40,219,179,186, 12,234, 66, 29,146, 30,164, 34, 36, 36,196,228,169,234,211,167,143, +201,131, 37, 18,137, 76,158, 44, 98, 57,197, 94,249,227, 47, 99, 96,233,116, 58,194,178,172,240,195, 15, 63, 36,239,191,255, 62, +213,233,116, 28,203,178,204,119,223,125, 71, 46, 94,188, 40, 84, 42,149,149,190,128,183, 30, 48, 4,159,246, 42,113,130,126,222, +200, 3, 34, 86, 4, 49,203, 98, 70, 66,170,233,186, 56,111,217, 41,142,142,142, 30,220,178,101,203,146,230,118, 64,200,231,193, +226,169,196,193,147, 89,206, 56,210,152,205,103, 2, 32,165,243,153,165, 90,198,239, 87, 0,180, 47, 87,214,184, 94, 83,238,211, +184,190, 74,247, 80,107,216,122, 3,190,119,225,194, 5,223,160,160, 32, 36, 39, 39, 87,232,217,102,124, 96,201,229,114,200,100, + 50,156, 63,127, 30, 0,238, 89, 19, 59,117,234,212,215, 40,201,146, 12, 0, 80, 40, 20, 33,225,111,135,157,239,208,187, 61,182, + 71,237,200, 75, 79, 79, 15,160,165, 57,112, 8, 33, 68,161, 80,140, 20,137,133,239, 52,105, 93, 63, 20, 28,183,244,196,175,127, + 44,176,117, 32, 77,154,183, 42, 4,160, 52,235, 69, 88,229,222,132, 0,192, 48,204,144,254,253,251, 51,241,241,241,120,231,157, +119,240,195, 15, 63, 88, 45, 59,114,228, 72,236,220,185, 19,253,251,247,103,230,204,153, 99, 53, 77, 67, 89,239,136,125,205, 64, +246,112,247,222, 13,108,219,241,157,213, 24, 35, 79, 79, 15, 0,192,179,103,153,166,101,193,193,182, 19, 49,115,122,205,241,235, + 87, 47,135,116,238,254, 10,155,146,145, 11, 78,175,134,170,224,185,105,125,113,110, 6,168, 94, 5,214,161, 22,188,107,187,224, +218,133, 99, 26,173, 70,117,220,150,230, 71,253, 91, 97, 66, 63, 63,128,114, 24, 48,125, 19, 14,174,153,108,106,222,233, 58,104, + 10, 78,238, 90,101,119, 12, 95,121, 68, 34, 17,226,226,226,148,214,188, 87, 2,129,160,210,156, 90,128,209,203,168, 67,113,177, + 18,197,202,106,231, 79,173, 0, 33,196,195,203,203,235,219, 90,181,106, 73, 45, 25, 80,132, 16, 15, 15, 15,143,111,221,221,221, +165,246, 54, 17,150,167, 92, 94,172,171, 17, 17, 17, 85, 50,178, 36, 18, 73,163,123,247,238,153,146,140,218,250,212,104, 52, 8, + 15, 15,183, 43,233, 40,165,244, 0, 33,228,161,143,143,207, 57,127,127,127,151, 7, 15, 30, 96,199,142, 29,172, 72, 36,170,111, +188,127, 20, 20, 20, 64, 32, 16,224,217,179,103, 58, 0,239, 85,214, 68,166, 86,171, 99, 98, 98, 98,218,246,235,215, 79,144,144, +144, 0,129, 64, 80, 82,175,144, 16, 4,174, 91,135,155, 31,127,140,208,199,143,161,210,106, 33,149, 74,113,244,232, 81,109,113, +113,113,140, 53, 61,153, 76,182,225,209,163, 71,173,164, 82, 41,180, 90, 45, 56,142, 3,195, 48, 68, 40, 20,118,117,117,117, 93, + 13,160, 76,198, 98, 79, 79, 79,207,113,211,190,104, 97,208,235, 13,233,201, 15, 50,173,200,154,200,202,202,194,129, 3, 7,208, +169, 83, 39,132,134,134,226,201,147, 39, 72, 76, 76, 68,159, 62,125, 76,101,110,220,184,129,235,215,175,163,105, 83,171, 45,237, + 38, 56,129, 14, 77, 91, 54, 2, 43, 98, 33, 98, 69, 37,159, 34, 81,233, 84,242,221,184,204,152,179,176, 18,104,249,214, 7, 71, +199,146,166, 69,137, 68,194, 53,106,212, 40, 61, 61, 61,221, 7,128,192,152,128,213,158,151, 21,160,228, 25, 97, 52,174, 88, 49, +107,242,100, 1, 64,110,110,174,170,127,255,254, 63,170,213,234,119, 81,141, 17, 69,120,254,149, 92,249,127,218,182,218,216,250, + 97,191,209,185,115,231,117,195,134, 13,123,101,229,202,149,112,116,116, 68,122,122,186,233, 65, 40, 22,139, 81,175, 94, 61,100, +103,103, 99,253,250,245, 72, 77, 77, 61, 5, 96,156,189, 59, 78, 79, 79,191,120,255,207,123, 89,225,131, 59,187,183,234,220,194, + 53,229, 94,106, 39, 0,231, 75,141,171, 77,195,166,189,241,110,248,192, 14, 96,197, 34,164,220,183, 26, 71, 91,227, 8, 4, 2, + 1, 33, 4,239,188,243,142, 93,229,135, 14, 29,138,152,152, 24,216,106, 78,228,140, 30,172, 98, 21,138,148, 53,247,114, 54,241, +163,145,152,248,209, 72,147, 17, 97, 79, 19, 11, 0, 40, 20, 63, 89, 93,199,233,181, 43, 15,254,180,126,108,187, 14, 33, 13,130, + 91, 53,194,165,171,127, 98,251,186, 23, 78,133,205, 95, 47,194, 23,155, 79,161,158,151, 27,180,234, 34, 28,222,243,221, 83,173, +186,120,165,173,253, 85,230,148, 97, 8,129,157,249, 37, 95,108, 83,106, 52,137, 68, 34,180,110,221,218,170, 7, 43, 59, 59, 91, + 89,217, 3, 1, 40,189, 70, 26, 29, 10,139,148, 80, 22,215,140,129, 69, 8, 9,236,218,181,235,241,221,187,119,187,123,122,122, + 34, 45, 45,173,140,129, 69, 8, 9,236,210,165,203,241,221,187,119,187,123,121,121, 33, 37, 37,197,238,244, 32, 70,204,140, 43, +100,102,102,146,156,156, 28,206,205,205,173, 74, 70, 22,195, 48, 80,171,213,184,125,251,182,189,187,181,187,199,151,139,139,203, +150,157, 59,119,186, 60,127,254, 28, 2,129, 0,183,111,223, 46,211,139,208, 56,109,218,180,137, 29, 48, 96,192, 70, 0,109,109, +233,233,245,250,229, 35, 71,142, 28,243,228,201, 19, 55, 79, 79, 79,164,167,167, 67, 44, 22,131, 82, 10, 18, 30,142,110, 15, 31, + 66,107, 48, 64, 38,147,225,238,221,187,216,176, 97, 67,145, 90,173, 94,110, 73,139, 16, 34,118,112,112,240,101, 89, 22, 35, 70, +140, 40,179,110,235,214,173,120, 51, 88, 16, 60,182,151,164, 80, 15,169, 58, 67,246,250, 97,129, 64, 64,198,205, 88,218,188, 99, +247, 62,173,239,220,188,244, 32, 51, 35,245,156, 37, 93, 51,116, 26,141, 6, 45, 91,182,196,149, 43, 87,112,226,196, 9,244,232, +209, 3,161,161,161,136,141,141,197,177, 99,199,112,253,250,117, 16, 66,224,238,238,110, 12,179,176, 25,107,161, 41,210,227,217, +147,172, 10,222,170,242,243, 44,203, 66, 45,174,208, 89,213, 34, 9, 9, 9,184,114,165,228,249, 83, 92, 92, 12,161, 80,168,159, + 49, 99, 6, 24,134,161, 55,111,222,132,167,167, 39,157, 53,107,150, 65, 40, 20,234,147,147,147,237,210, 52, 26, 83, 70,227, 74, +200,138,202, 24,102, 28,199, 21,220,184,113, 99, 44, 33, 36,150, 16, 98,204,134,202,231,193,226,249, 71, 97,213,192,162,148, 62, + 4,208,147, 16, 50,124,255,254,253,203, 87,175, 94,237,209,183,111, 95,228,228,228,160, 65,131, 6,240,241,241,193,193,131, 7, +113,232,208,161,231, 6,131, 97, 58,165,180,130,171,135, 16,210,211, 90,174, 12, 74, 41, 85, 40, 20,187,213,133,133, 19,130, 66, +253,112,106,215,217, 40, 31, 31,159,113,117,234,212,153, 26, 17,249,214,187, 97,253,219,227,238,245, 71,184,120, 44, 14, 25,201, +207, 17,209,109,150, 77,205,242, 65,238,174,174,174, 99, 28, 28, 28,196, 0, 42,220,101,202,247, 34, 52,215, 52, 24, 12, 6,141, + 70,131,159,126,250,201, 46, 35,107,199,142, 29, 80,169, 84, 48,148,107, 71, 53,215,164, 28, 37, 66,145, 4,138,122, 45,161,213, + 22,129,227,170,231,173, 49,215, 36,132,128, 97, 24, 60, 16,139,225,249,252, 57, 46, 93,170,208,146, 97, 17,243, 55,231,242,154, + 0, 64, 41, 85, 17, 66, 70,172, 90, 60,227,224,164,217, 75, 93,123,116,110,139, 79,191,218, 10,173,118, 51, 24, 1, 3,153,132, + 69, 80,135, 46, 16, 64,141,111,163,103,230, 22,231,231,140,160,229,134,204,169,160,105,171, 37,133, 2, 6,142,195,137, 51,182, +115,149, 90,186,238, 6,131, 1, 66,161, 16,247,239,223, 87, 90,234, 61, 40, 16,148, 52,103, 50, 12, 99,241,173,187,236, 53,226, +136,136,149,162, 94, 3,127,104,212,133, 53,114,141, 60, 61, 61,103,238,219,183,207,221,152,242, 32, 54, 54, 22,132, 16,147, 21, + 99, 92,175, 84, 42,113,243,230, 77,227,144, 80, 21,172, 28, 91,255, 35,163,231, 42, 51, 51,147,164,167,167,195,193,193,129,137, +141,141, 85, 7, 4, 4, 92,133,237,145, 26, 76,154, 42,149,234,177,181,248, 72,149, 74, 85, 71, 42,149,138,202,109,171,240,245, +245,189, 91,190,169,208, 82, 61,243,242,242, 46,125,242,201, 39, 65,189,123,247,198,204,153, 51,179,221,220,220,156,190,253,246, + 91,161, 64, 32, 32,147, 38, 77, 50, 60,123,246,172,240,187,239,190,115,217,191,127, 63,114,115,115, 43,140, 10, 96,225,247, 89, + 64, 8, 25,219,185,115,231,173, 71,142, 28,113,240,245,245, 69,126,126, 62, 40,165,216,178,101, 11, 38, 77,154, 4,169, 84,138, +187,119,239,226,205, 55,223, 44, 46, 46, 46, 30, 91, 62, 54,210, 76,147, 16, 66, 40,199,113,152, 55,111,158, 41,169,168, 49,201, +168,147,140, 96,195,180,198,242, 41,223,229,201,135,127,250,221, 40, 0, 48,232,245,134, 59, 55, 47, 61,216,178,230,211,211, 44, +203,158,177, 86,207, 82,230, 78,153, 50,229,219, 62,125,250,200, 28, 29, 29,145,157,157,141,115,231,206,225,194,133, 11,184,120, +241, 34, 52, 26, 13,220,221,221,225,230,230,134,244,244,116, 36, 36, 36, 40, 1,204,181,165, 41,150,139,208,164,133,177, 39,239, + 11,239,149,105,158, 21, 65, 36,124,209,147,176,178,243, 9, 0,221,187,119, 71,199,142, 29, 1,148,244,138, 78, 74, 74, 74, 87, +171,213,196,204,216,127, 2,148, 24,226,245,235,215,215,111,218,180,137,218,210,188,184,225, 27, 28,249,108, 46,196, 44,139,233, +183, 83, 76,198,214,214, 30,237, 32, 18,179,240,235, 55,200,180, 45,165,116, 45, 33,100,115,233,119,181, 53,205,154,128,215,252, +251,107,254,211,168,212, 53, 75, 41,221, 78, 8, 57,252,193, 7, 31, 68, 7, 6, 6,126,176, 98,197, 10,194,178, 44, 22, 44, 88, + 64,211,210,210,190, 71,201, 91,135,213, 33, 72, 42,209,254,254,247,189,231,199,143,158,221,159, 76, 91, 25,209,245,234,201,155, + 9,109, 58,251,162, 77,103, 95, 92, 61, 21,143, 53,145, 59,126, 48,232, 12,243,210,211,211, 43,123,109, 82,247,236,210,162,124, +144,187,123,204,233,147,238, 85,237, 69,200,113,220,238, 29, 59,118,124, 52,112,224, 64,230,242,229,203, 21, 98,174,104,105, 50, + 62,142,227,112,252,248,113,104,181, 90,124,255,253,247, 28,199,113,214,243, 96,129,254,178,106,101,244,232,239,183,253, 34, 22, +179, 4, 23,206,252,140,188, 28,219, 94, 57,150, 21, 97,211,150,189, 90,150, 21,221,177,180, 94,171,213,166,156, 60,121,210,235, + 53,131, 65,196, 48, 76, 5,195,201, 26,187,119,239,214,113, 28,151,100,171, 12,165,244, 60, 33,162,126,159,207,124,111, 71,159, +183, 63,240,234,220,185,171,168,182,167, 23, 8, 33,120,150,241, 12,119,111, 94,214, 29,254,121, 99, 70, 81,113,129, 93, 67,229, +188,247,229,239,166,152, 43, 0,232, 59,105,181, 41,254, 10, 0,250, 69,124,130,240, 78,173, 64,236,113, 53,149, 98, 48, 24, 56, +189, 94, 15,185, 92, 14,189, 94,111, 49, 85,131,139,139,139, 76,165, 82, 41, 41,165, 48, 24, 12, 54, 93, 67, 20,168,241,107,100, + 48, 24,252,114,114,114, 80, 84, 84,132, 11, 23, 46,208,197,139, 23,103,102,102,102,154,130, 49,117, 58,157, 95,118,118, 54, 10, + 11, 11,113,254,252,121, 26, 29, 29,157,153,149,149,101, 43, 88,179, 2, 50,153, 44, 88, 40, 20, 94,205,201,201,225, 28, 28, 28, + 24,157, 78,167, 11, 8, 8,144,200,100, 50,187, 7, 58, 79, 75, 75,171,144,132,213, 72,211,166, 77,239,221,187,119,175,153,193, + 96, 48, 31,163,144, 85,169, 84,190,157, 59,119,182,167,105,103,202,230,205,155,177,119,239,222, 14,249,249,249, 35,147,146,146, +182, 2,232, 32, 20, 10,241,231,159,127,222, 86,169, 84,195, 6, 14, 28,184, 37, 39, 39,231, 18,128, 41,246,212,151, 82,122,132, + 16, 50,194,207,207,111,243,194,133, 11, 29, 67, 67, 67,133, 10,133, 2,237,219,183,199,221,187,119,241,219,111,191,233,214,174, + 93, 91, 84, 92, 92,252, 30,165,212, 86,243, 53, 5, 64,244,122, 61,196, 98,177,105,146, 72, 36, 96, 89, 22, 5, 74,138,247,191, + 74, 84,234, 33, 83, 46, 95, 48,246, 55, 10,144,167, 41,137,207,159, 61, 77,185, 68, 8, 57,147,150,150,102,113,168,156,166, 77, +155,138, 85, 42, 85, 91, 31, 31, 31, 33, 33,100,165, 86,171,125,119,242,228,201,222, 75,150, 44, 65,139, 22, 45,240,252,249,115, +200,229,114,248,250,250, 34, 51, 51, 19,151, 47, 95, 54, 20, 23, 23,175, 3,176,136, 82,106,179,217, 49, 55, 51, 31,117,189,234, +151,241,116, 82, 74, 65,245,128,206, 96,128, 65, 75,161, 33, 58,136, 68, 58,176,172,133, 76,184,229, 48, 26,152, 57, 62, 62,120, +114,244, 40, 74, 71,149,176,234, 69, 59,120,240,160,181, 85, 47,160, 28,196, 18,113,153,102, 65, 66, 8, 88,177, 24, 34, 49, 91, +161, 71, 12,239,181,226,249,167, 98,111, 44, 69, 46,128,113,132,144,173, 97, 97, 97, 7, 41,165, 34, 0,125, 40,165,103, 95,102, +231,233,233,233,215, 20, 10,197, 28,175,186,110,209,175,143,236,138, 22,109, 27,192,160, 55,224,220,161, 63,241,253,146,253, 59, +159,164, 60,137,160,118,180, 29,113, 28,119,186, 75,112, 11, 6,102,185,181, 21, 10, 5, 87,157, 94,132,121,121,121,243,167, 79, +159,142,153, 51,103, 86,185, 23,161,181, 50,177,183,159,141, 11,244,243,168,219,239,245,110,175,129, 48, 84,163,177,126, 63, 33, + 4,166,140,163, 44, 43,186,115,249, 70, 90,128,165,114,153,153,153,175,189,251,238,187,199,133, 66,161,221,193,201, 64,201,224, +175, 25, 25, 25,175, 84, 86,142, 82,221, 57, 66,136,239,129,157,235, 63, 62,178,119,243,107, 28,103,104, 74, 0, 8,132,236, 3, +157, 86,123, 84,173,204, 95, 81,222,115,101,141,101,227, 66, 48,101,213, 49,124, 51,179, 31, 38, 71,239,194,198,121,239, 99,206, + 87, 59,176,116,230, 20, 44, 94,253, 35, 62,157, 50, 2,131,135,191,203, 81,194,252, 97,239,113, 8, 4,130, 35,235,215,175, 31, +253,254,251,239,155, 58, 35, 80, 74,203,220,208,117, 58,157,146,227, 56,172, 91,183,142, 3,112,196,150, 94,217,107, 68,168,173, +120, 40,123,175, 81,126,126,254,123, 33, 33, 33, 91, 0, 72, 40,165,247,115,114,114, 62,164,148,154,134,112, 42, 44, 44,124,175, +115,231,206, 91, 40,165, 18, 66, 72,133,245,246, 80,154,178, 33,216,205,205,237,106,169,231, 74, 82,157, 64,119, 27, 8,108, 52, + 31, 86,218, 84, 88,250,255, 53, 13,127, 67, 8, 89,210,161, 67, 7,243,193,158,111, 3,176,219, 24, 52,211, 61, 78, 8,105, 53, +111,222,188,143,165, 82,105,120,113,113,113,115, 0,144,203,229,119,213,106,245,105,165, 82,185,162,244,190,101, 75, 67,227,224, +224,112, 87,175,215,183,246,240,240, 40,233, 33, 91,106,100, 1,192,175, 87, 13, 87, 41,213, 87,121,212,248, 67,135, 14, 53,116, +115,115,123,149, 16, 50,152, 82,218,178,160,160, 64,253,159,255,252,231,194,222,189,123,115, 27, 52,104,240,122,159, 62,125, 72, +173, 90,181,112,229,202, 21,154,149,149,245, 51,128, 72,123,122, 78,115, 28,151,180,108, 89,213,198, 22,172,236,101, 57, 55, 16, +215, 0, 0, 32, 0, 73, 68, 65, 84, 74,171,213, 62, 61,116,232, 80,237,222,207,158, 9,107,113, 92,153, 30,142,150, 58, 92,220, +185,115, 7,106,181,218,102, 18, 70,117, 94, 14,122,124,252, 9, 80,218,155,211, 72,137,231,138,130,218,184,255,241,240,252,147, + 32,127, 73, 55,102,163,184,157, 46, 68,133, 66,241,142, 84, 46,153,216,160,185, 79, 64, 90,226,179,248,130,188,226, 31,210,211, +211,215, 83, 74, 43,220,192,237,213,172, 74,162,209,255, 21,247,233,255,162,230,139, 60, 88, 6, 80,106, 0,229, 40, 40,229,192, +113,134,146,129,168, 41, 7,106, 48, 16, 66,240,135,186, 56,207,106, 38,239,242,245, 36,132,184,213,174, 93,123, 17,165,180,183, + 64, 32, 96,204,157, 95,230,223, 75, 61, 87, 71, 50, 51, 51, 63, 45,239,105,253, 95, 60,159,123,246,236,177,104,244,219,219,139, +112,240,224,193,134,170,212, 83,161, 80,156,150,203,229, 22, 19,106, 22, 21, 21, 37,167,165,165,189,106,169,158, 53,133,189,154, + 70,239, 39,181,227,134, 86,174,169,189,202,189, 8, 43,211,108,216,176,161, 68,171,213,182, 3,208, 28,128, 43,128,108,157, 78, +119, 36, 51, 51, 51,131, 16, 18, 12, 96, 94,233,102,159, 81, 74,175,218,163, 89, 83, 88,248, 31,201,106,215,174,189,153, 97,152, + 74, 7, 34, 7, 0,189, 94,175,201,206,206, 30,109,254, 34, 96,174, 89,187,118,237,171, 66,161,176, 82, 45,189, 94,159,250,252, +249,115,171,134,245,255,226,127,147,215,228, 41,207,223,162,247, 70, 90, 90,218, 79, 0,172, 71, 94, 87, 3,107,153,218,121,254, +187, 20,101,167,255, 37,215,161,212, 88,178, 58,120,243, 63, 21,163,129,100, 97,185,105,156,193,154,196,206,116, 12,255,239,216, + 99, 88, 89,217,238, 18,236, 72, 46, 90, 21, 30, 63,126,172, 6,112,190,116, 42,191,191,171, 0,250,213,228,254, 94, 6, 74,169, + 18,128,125, 61,122,236,192,150,209,196,195,243,111,163,242,254,235, 60, 60, 60, 60, 60, 60, 60, 60, 60, 85,130, 0,232,105,105, + 69, 85, 92,127,132, 16,139, 26,182,168, 76,159,215,228, 53,121, 77, 94,147,215,228, 53,121,205,127,158,230,191, 6, 90,154,240, +241,175,152, 0,244,228, 53,121, 77, 94,147,215,228, 53,121, 77, 94,147,215,252,183, 77,124, 19, 33, 15, 15, 15, 15, 15, 15, 15, + 79, 13, 99,183,129,229,232,237,231,231,209, 48,112, 75,173,122, 1,177,181,234, 5,196,122, 52, 12,220,226,232,237,103,215, 40, +245,255, 52, 8, 33, 50, 66,200,112,145, 72,116,220,199,199, 39,159, 16, 98,113,136,156,255,117, 8, 33,206,132,144,193,132,144, + 69,132,144, 1,132, 16,135,154,212, 15, 35, 68, 56,148,144,137,163, 9, 73, 30, 77, 72,242, 80, 66, 38,134, 17,242,183,232,120, + 81,147, 44,156,162, 8, 57,123,100,196,225,133, 83, 20, 33, 22,215,207, 80,184, 95, 58,254,246,170,168, 73,117,106,213,196,254, + 8, 33, 78, 94, 94, 94, 27,188,189,189, 31,123,121,121, 37,121,121,121,109, 38,132,184,212,132, 54, 15, 15, 15, 15,143,125, 8, + 1,128, 16, 18, 10,224,119, 0, 97,148,210,152,242,133,106, 53,104,243,190, 95,203, 22, 51, 63, 95, 48,151,120,212,118,147,233, +116, 6,109, 74,106,186,255,252,207,163,246,212,106,208,102,121,118, 82,220,198,170,238,152, 16, 66, 4, 2,193, 59, 18,137,164, + 47, 0,163,161,118, 91,173, 86, 31, 52, 24, 12, 63,209, 82, 31,100,101,120,123,123,159, 17, 8, 4, 13,171,178,111,131,193,144, +252,244,233, 83,235,217, 70,109, 64, 8, 25, 82,191,126,253,205,161,161,161, 14, 29, 58,116,128, 88, 44,198,188,121,243,166, 3, + 88, 97,175, 70,173, 90, 77,157,180, 18,233, 84,161, 88,220,139,254, 31,123,223, 29, 22,213,181,189,253,238, 51,125,152,161, 13, +189,216, 0, 65,154,130,189,247, 18,149,216, 34, 26, 99,143,137,122, 53, 38,150,196,222,141, 26, 91,212,104,172,177,107,108,216, +107, 20,123, 55, 88, 16,176,128, 32, 8, 2, 67, 25, 6,152, 62,103,246,247, 7, 37, 72, 40,131,201,253,238,239,230,206,251, 60, +243,204, 41,251,188,103,157, 51,195,225,157,181,214, 94,203,160, 11,166,160, 0, 35,140, 54, 25,181,151,249, 90,237,154,156,156, +248,252,234, 89, 0, 66,200, 44, 0, 35, 81, 52,173,124, 59,165,180,102, 69,114,202, 97,100, 99, 98, 48,176, 69,223, 9, 62, 23, +172,173,173,237,213,217,179,103,115,195,194,194,176,125,251,246,182, 91,183,110,253,146, 16,114, 25,192, 73, 74,105,252, 95, 57, + 23, 0,184, 0, 99, 91,183,109,187,110,196,212,169, 28,245,245,235, 88,183, 99,199, 90, 40,149, 0,176,177, 38, 60,132, 16,194, +231, 99,160,163, 35, 47,140, 82, 52, 38, 0, 33,192, 35,121,182,233,172, 94,207, 30,164, 53,237,195,243, 62,247,103,120,127, 90, +253,254,154,114,228,197,211, 57,194,143, 3,218,229,197, 95,153, 3,160,103,249,253, 70,141,104, 4,229,212, 10, 83,211,168, 20, + 0,171, 63,212,214, 98,123,173,156,156,156,158,156, 56,113,194,179,121,243,230, 92, 0,120,248,240,225,240,176,176,176,206,132, +144, 96, 74,169,242,175,240,255, 5,187, 68, 92,134,153, 32,224,241,186,177, 44,219, 16, 0, 56, 28,206, 83,157,193,240,155,209, +100,218, 72,205,172,169,102,129, 5, 22,252,115, 81,157, 22,249,111, 67,137,183,224, 42,165,148, 16, 66, 40,202, 77,245,150,186, +248, 7, 6, 5, 5, 76, 61,127,108,119,173,188, 28,133,230,167,213,123,162, 10, 56,252, 66,191, 0, 95,193, 79, 63,174,180,155, +240,245,148,111,164, 46,254,247, 10, 50,226, 98,204, 61, 41, 33,164,182, 88, 44,142, 88,181,106, 85,112,167, 78,157,120,206,206, +206,200,200,200, 64,108,108,108,112,100,100,100,191,221,187,119, 79, 37,132, 12,160,148,154,211,248,202,247,242,158, 29,206, 18, +153, 3, 88,131, 1,238,141, 26,151,196,135,241, 42,242, 34,140,122, 61, 76, 6, 3, 2,194,250, 1, 0, 76, 38, 19, 2, 3, 3, +205,107,218,247,103,187,221,131,130,130,246, 46, 93,186,148,175,213,106,113,239,222, 61, 92,185,114,197,244,238,221,187,229,230, +114, 72, 93,252, 58, 49, 98,201,193,193, 67,191,176,237, 27,230,197,171,237,226, 4,192, 10,207, 19,141,173,207, 93,140,108,118, +236,224,206,127, 73, 93,252, 6, 23,100,188,184, 82, 21,143, 76, 38,107, 73, 8,249,190,164,162, 51, 33,100, 69,189,122,245,230, +149, 29, 83,190,175, 29,165, 20, 92, 46, 55, 35, 63, 63,127,112, 86, 86, 86, 84,121, 78, 3, 11,238,254,253, 69,250, 97,206,132, +207, 56, 55,111,222,148, 4, 6, 6,106, 1, 96,229,202,149, 88,180,104,145,224,194,133, 11,189,246,236,217,211,139, 16,178,150, + 82,122,210,220,235,174, 8,124,224,187, 17, 83,167,114,164, 73, 73,144, 62,126,140,161, 74, 37,247, 7,224, 59,212, 64, 96, 17, + 66,188, 92, 93,121, 71,166, 78, 25, 21,224,237,211,146,207,231, 59,130, 82, 10,189, 46,203, 47, 57, 57,106,224,242, 31,182,206, + 32,132,124, 66, 41, 53,171,210, 44, 41,242,160, 45, 4, 32, 2, 48, 7,192, 92,185, 92,238,203,178, 44, 92, 93, 93,231, 18, 66, +142, 3, 88,226,228,228, 68,229,114,249,116, 74,105,165, 61,117, 22,126,237,222, 74, 25, 79,231,164, 19,239,143, 26, 52, 25,129, +116,114,254,163, 41, 61,221,206,217,248,144, 37,243,215,165,221, 1,128,158, 62, 62,214,222,254,146,233, 82,155,134, 50,101,234, +165,233, 61,125,124,182,157,139, 55, 79, 96,151,179,155, 0,128,187,187,251,202, 61,123,246,212,106,209,162, 69,233,119, 60, 52, + 52,148,179,114,229, 74,143,201,147, 39,175, 5, 48,202, 76, 62, 63, 39, 39,167, 11, 44,203,106,179,179,179,253, 74,182, 59,135, + 12,104,237, 96, 45,233, 34,207,205,191,158,245,236,248, 53, 51,185,154,139,248,252,163, 39,247,174,115, 11,109,209,138,145, 58, + 58, 67,147,154,134, 2,131,190,235,149, 91,119, 59,126, 57,225,187,175,139, 63,163,170,251, 37, 89, 96,129, 5,255,116, 84,170, + 69,254, 27, 81, 26,142, 41,190,160, 63, 65, 40, 20,204,152, 63,123, 58, 81,100, 43,212,218,252, 2,157, 81,163, 81, 51, 60,147, +230, 73,236,235, 76,134,203, 81, 76,153, 52,201,122,250,172,217, 51, 0, 12,173,232,248,242, 32,132,212, 14, 9, 9,185, 31, 17, + 17,225, 44,147,201,144,151,151,135,236,236,108,220,191,127, 31,148, 82, 12, 24, 48, 64,216,162, 89,179,198,115,230,206,189, 67, + 8,105,101,142,200,146,200, 28,177,178,109, 81,143,216,121, 73,217, 37,231,193,214,240,176,210, 49,139,222, 22,117,181, 16,137, + 68,165,141,130, 63, 0,173,186,116,233,194, 7,128,207, 63,255, 92,153,159,159,191, 12,192,126, 74,105,170, 57, 7, 75, 93,252, + 58, 57,186,185,159,222,180,121,165,184,161,143, 47,244, 6, 35,222,164,167,129,203,179,131,167, 39, 31,163,134,118,227,181,111, + 45,115,252,126,241,214, 51, 18, 39,191,254,133,242, 23, 23, 42,227,178,179,179,219,125,240,224, 65, 28, 58,116, 8, 0,240,226, +197, 11,248,250,250, 74,170,179, 33, 58, 58,218,187, 79,159, 62,191, 2,168, 95,221,216,242,133,236,133, 66, 33,218,182,109,139, +192,192, 64,156, 56,113,162, 35,128,191, 36,176, 0, 64,125,253, 58,164,143, 31, 3,215,174,213,248, 88, 66,136, 87,147, 38,117, +238,158, 61,179,215,241,204,217, 88,172, 94,189, 3,241,241, 69,142, 53,111,111,111,124, 54, 36,156,247,244,233,237,160,129, 3, + 63,187, 77, 8,105, 75, 41,125, 97, 6,237,194,109,219,182,205,170, 87,175, 30, 6, 14, 28, 24, 30, 20, 20,228,106, 99, 99,131, + 45, 91,182,192,205,205,205, 91,167,211,189, 58,113,226,132,123,122,122, 58, 38, 77,154, 4, 0, 83, 43, 35,234,216,163,227, 28, +225,199, 1,237, 26, 52, 25, 1,169,141, 27,182, 29, 56,136,231,191,239,110,167,213,199,206, 89, 54,209, 99,152,154, 10, 71,122, +250, 90,207,168,219,180,131, 67,253,160, 62,168,211, 36,202, 81,195,222,120, 61,119,130,247,114,174, 72,179,123,254,170,180,236, + 63, 93,115,248, 17, 78,176, 50, 78, 22,253, 27,178, 41,157,111, 42, 22, 86,165, 15, 34,150,162, 79,251,246,237, 75, 63,184,164, +164, 36,104,181, 90, 4, 4, 4, 48, 58,157,206,172,154, 86,132, 16,191,238,221,187,223, 60,123,246,172,131,159,159,223,123,173, + 91, 92, 29,236,122, 92,139, 88, 59,233,251,117,251,252,157, 3,251, 43, 50, 99,142, 61,173,134,171,121,155,150, 77, 46,157,139, +216, 43, 37, 5, 41, 16,216,101, 1,166,108, 36,252,250, 11,136,149, 12,131,199, 79,225,118,234,210,217,163, 91,207, 79, 46, 17, + 66,186, 80, 74,255, 35, 93,239, 45,176,192,130,255, 27,168, 76,139,252, 55,162, 84, 96,149, 81,141,239,193, 68, 77,141, 92,157, + 29,196,107, 87,237,122,192,209,235,116, 86,118, 54,122, 91, 27, 91, 10,107, 27,142,222,160, 47,168,237, 91,143,111,162,166, 10, + 91,133,208,114, 83, 53, 9, 33, 68, 44, 22, 71,156, 60,121,210,153,199,227,193,100, 50,193,201,201, 9,137,137,137, 80, 40, 20, +200,207,207, 71,124,108, 44,234,213,174,133, 5, 51,166,187, 77,154, 62, 35,130, 16,210,180,108,184,176, 60, 39, 0,176,134,247, +251, 57,151,180, 74, 41,143,146,109,229,247, 85,196, 89, 9, 18,147,147,147, 33,149, 74, 17, 28, 28, 44,189,117,235,214,141,202, +196, 85,121, 78,153,204,199,154, 43, 21, 31,250,121,211, 92,177,222, 16,141,152,132, 28, 52,168,215, 14, 46, 14,181,145,150,163, +195,221,251, 39, 17,253,100, 63,124, 60,106, 99,226,248,206,162,229, 43,143, 28,180,183,247,170,157,155,251, 90, 89, 17,167, 82, +169,148,122,121,121,161,118,237,162,190,100, 44,203, 34, 38, 38, 6, 44,203,150,174,151,125,223,117, 52, 18, 70,229, 27,140, 24, + 62, 28,217,217,217,210,138, 56,121, 28, 24,167,124,249, 25, 87,204, 3, 4, 18,153,174,160,160,160,212, 27,168,215,235,241,232, +209, 35,180,106,213,170,195,225,195,135,175, 85,117,147,204,189,159,122, 96,197,186,157, 59,215, 15,205,203, 99, 0, 96, 59, 33, + 38, 61,165, 43,204,225, 36,132, 16,103,103,222,209,243,231,246, 56,114,152, 56,200,108,127,192,253,251,111,160,215, 23,217,155, +157,157,137,175, 38, 40,193,231, 89,227,196,137,125, 14, 1, 1,109,143, 22,135,200, 76,149,113, 22, 67,116,238,220, 57,124,245, +213, 87,136,137,137,113,231,112, 56,184,119,239, 30,196, 98, 49, 86,173, 90,197, 9, 8, 8,112,151, 72, 36, 56,127,254, 60, 50, + 50, 50,254,244, 37, 43,203,121,245,194,213, 37,121,241, 87,230,164,147,243, 31,109, 59,112, 16, 95, 12, 25, 12, 87,154,112,195, +214,135, 44,233,254,113,155,121,148, 83, 43, 76, 98,221,200,222, 55,248, 99,240, 5, 82, 76,252,110, 17, 94, 68,159,178, 87,229, + 63,153, 64,216,148, 90, 40,238,205, 87,150,147, 30, 30,200,174, 63,112,187,201,111,181, 31,212,113,111, 50,246, 30,128, 39, 40, + 21, 88,222, 92,194,176,182,197,199,224,213,171, 87,136,143,143, 7,151,203,133, 90,173,134,209,104,172,208, 78, 15, 15,143,177, + 70,163,113, 30, 0,232,245,250, 93,110,110,110,163,247,238,221,235, 80, 86, 96,151,120,174,114, 20,202,220,219, 15,158, 61,159, + 50,118, 96,199,235,119,163, 83,236, 66,250, 37, 43, 30, 31,207,171,228, 51, 18,137, 5,130,163,231,143,237,147, 26, 94, 71, 66, + 18,208, 17, 60,169, 47, 88, 67, 42, 84,185,133,200,143,127, 7,237,166, 13, 8,157, 48, 25,167,142, 31,145, 6, 53,108,122,152, + 16,226, 75, 41, 45,237, 83, 84,131,191, 77,179, 97,225,180,112, 90, 56,255,111,114, 22,243, 86,168, 69, 0, 52, 1,224, 82,188, +156,141,162,212, 24, 71, 0, 89, 40,106,219,229, 2, 64, 7, 64, 80,230,152,242,235,101,199,150, 95, 47,187,156, 93,188,236, 92, +252,254, 0, 64, 78, 77,175,165,218,132, 98, 66, 24,165,209,100, 18, 10,156,156,180,163, 7,117, 13,190,120,233,225, 35,137,131, + 45,183,123,167, 38, 29,238, 63,141,191,195,128, 49, 16,194,152,149,215,193,225,112, 6,175, 93,187,182,161,141,141, 13, 76, 38, + 19,108,109,109, 33,151,203,161,211,233,144,151,151, 7,109,190, 18,250,124, 37, 30,167, 36,161, 77,135,142,248,228,163,238, 1, +251,142,159, 28, 12,224,215,170,120,221, 27, 53, 46,245, 92, 45,170,235, 80,186,125, 97,138,162, 84,108,253,208,216, 23,124,169, + 20,221,166,204, 48,199,212, 10, 65, 41,141, 18, 8, 4,231, 6, 12, 24,208,115,218,180,105,204,187,119,239,206, 19, 66,218, 80, + 74,171, 13,143,234,133,162,111,254,245, 77,152,189,189,148,226,240,111, 39,209,190,241, 16, 88, 9, 56,200, 86,234, 65, 8, 16, +251, 44, 2,132,200,240,228,197, 59,180, 11,181, 65,247, 30, 1,210,227, 71, 98,167,225,143,252,159,242, 32,185,185,185,200,204, +204,132,193, 96,128,193, 96,192,192,240,112,236,217,189, 27,133,133,133, 80,171,213,208,233,116, 96, 89, 22, 12,195,224,183,211, +135,145,242, 58, 22,173, 91,181, 2, 42,113,189,238,138,162, 60, 66,200,221,231,207,159, 35, 54, 54, 22,111,223,190,133, 72, 36, +130,171,171, 43, 22, 45, 90, 4,173,182,168,135, 88,120,120,120, 7, 0, 85,122, 46,204, 65, 60,176,245,181,209, 56,167,231,177, + 99,206,183,142, 29, 51,221, 57,121,242,173,168,160, 96,139, 57,199,242,249, 24,184,114,197,248, 6, 18,137, 4,111,147,215,194, +223,159,143,169,147, 29,176,236,135, 44, 0,192,164,175, 60,209,172,169, 35,148,138, 35,112,116,158,133,245,235,191,246, 25, 57, +114,205,112, 0,187,170,161,158,115,242,228,201, 79,124,125,125, 61,162,162,162,136, 64, 32,128, 88, 44,134, 88, 44,134, 72, 36, + 66,102,102, 38, 18, 19, 19,233,202,149, 43, 83, 81, 20, 66,172, 20,197, 97,192,158, 83,122,186,157,123,254,251,238,118, 30,156, +215,143, 63,153,216, 54,233,201,221,168,252,139,191,221, 90,108,212,136, 82, 20,111, 47, 77,247,106, 22,229, 56,225,219,133,216, +176,114, 62,158,223,187,158,227, 82, 91,185, 81, 76,180,187, 90,116,251, 51,103,199,142, 11,185, 19,230, 14, 50,142, 29,249,137, +221, 41,151,219, 99,207,114,137, 60, 61,235,247, 85, 72,140, 82, 11,235, 55, 30,230,231,205,232, 34, 35, 35,197,237,219,183,135, + 70, 83,148,214,196,225,112,176,119,239, 94,147,209,104,172, 48,236,172,215,235,231,165,166,166,186,169,213,106,124,244,209, 71, +147, 86,173, 90, 37, 41,233, 33,199,178, 69,133,227, 75, 60, 87, 75,126,220,115,225,155,121, 27,175, 92,248,245, 7,247, 37, 51, + 70,119, 28, 58,241,251, 43,168,164,207, 35,151, 97, 38,156, 58,182,195, 85,100,111,128, 88,214, 29,154, 12, 53,158,111,253, 2, + 42,165, 6,205,150, 44, 4, 32,128,206,192, 96,203,199, 3,193,115,112,199,252, 49,163,221,103,111,217, 54, 30,192,218,106, 62, + 35, 11, 44,176,224,127, 15, 46,132,144,211, 0, 48, 99,198,140, 89,203,150, 45,123, 70, 8, 57, 77, 41, 13, 3,128,146,229,146, + 49, 0, 80,209,122,201,216,242,235,229,151,103,206,156, 25,180,124,249,242,165,173, 90,181,250,245,246,237,219,175,241, 1, 2, +139, 41, 62, 9, 41,251, 94, 22, 38,147,233,250,171,132, 36, 85,143,110, 45, 61, 78, 93,125,250,112,212,168,222, 93, 6,245,105, +215,253,117, 74,102,156, 79, 29, 87,199,232,103,143,109, 76, 38,211,117,115, 78, 38, 20, 10,195, 58,119,238,204,205,205,205,133, +149,149, 21,228,114, 57, 82, 83, 83,161,215,235,161,201, 83, 64,155,167,128, 70,145, 11,125, 94, 46,226, 31,222, 71, 35, 31,111, + 97,113, 18,124,149, 40,241,178,148,247, 76,149,245,100, 9,172,173, 33,180,182, 6,169, 97,120,144, 16,210,215,222,222,254, 46, + 33,100, 14, 0,232,245,250, 9,211,167, 79,207, 50,153, 76,248,254,251,239,109,164, 82,233, 97, 66,136,176, 58, 30,107, 39, 78, + 88,171,208, 96, 38, 46,241, 9,218,134,140,128,159, 87, 47, 36,102,168,145,149,175, 71,166, 66,143,102,237,127, 66,221,144,133, +168, 21,186, 12,177,111,114,224,238,225,203,128, 43,172,178, 41,115, 70, 70,198,123,235,191, 30, 56, 0,149, 74, 5, 31, 31, 31, + 12, 25, 50, 4,211,167, 79,199,144, 33, 67,224,238,238,142,161,131,250, 96,254,252,249,200,204,204,172,206, 84,173,159,159,159, +182, 78,157, 58,218, 58,117,234,104,245,122, 61, 10, 10, 10,160, 80,252,209, 55,183,248,126,127, 93, 29, 81,121,184,184,184,204, +116,115,115,123,226,226,226,242, 76, 36, 18,157,125, 68, 72,156,182,110, 93,151, 54,253,250,145,192, 65,131, 56,201, 86, 86,228, + 26, 32,173,150, 8,128,163,140,215,187, 83,231,158, 2, 69,238, 14, 0, 69, 78,169,209,163,156,112,243, 90, 16,110,221,104,138, +175, 38,248,128, 48, 34, 16, 70, 0, 85, 97, 36, 90, 52,111,197,183,179, 35, 85,126,151,138, 19,218, 31,181,105,211,198,125,226, +196,137, 68, 40, 20, 98,210,164, 73,250, 49, 99,198,188, 28, 50,100,200,203,203,151, 47,179,117,234,212, 65,173, 90,181, 72,173, + 90,181,220, 0, 60, 42, 62,166, 74,216,248,144, 37, 90,125,236, 13, 59, 95,201,107, 22,142,173, 11, 12,194,129,243, 87,165,101, + 47,222,152,176, 58,241,185,202,251,249,189,235,217, 47,163, 79,153, 18, 31, 92,205, 74,123,153,239,189,120, 99,194,234,153, 27, + 82, 43,252, 99,190,118, 13,166,136,211,215,244,170, 66, 21,183,223,199,157, 84, 99, 63, 31,236, 39,147, 6,237,133, 71,247,144, +186,181, 61,135,206, 95,186, 94, 63,102,252, 55,250,237,191,236,160,249,249,249, 80, 42,149, 88,191,126,189,241,212,169, 83,169, + 44,203,126, 83,137,137, 28, 0, 48, 24, 12, 24, 59,118,172,196,198,198, 6, 41, 41, 41,165, 30, 80, 0,120, 39,207,126,122,235, + 65,116,220,148,113,225, 29, 10,181, 90,237,133,171, 15, 99, 3,125,235,120, 18, 66, 43,157, 96, 34,224,241,186, 53,109,209,130, + 67,169, 2,132, 91, 27,241,187, 87, 66,153,158, 3,101,102, 14, 56, 60, 9,140, 16,194, 96, 18,192,174, 81,115,188,120, 16, 5, + 15, 39, 23,174,144,199,179,180,184,178,192,130,255, 81, 84,165, 69,202,140, 9, 91,190,124,249,210,170,246,151,121,215,149, 91, + 47, 21, 80,229,197, 87,217,101, 0, 88,190,124,249, 82, 74,105,216,237,219,183, 15, 0,168,178,193,121,101,168, 86,109,112, 52, +186,101,211,166,207,129,173,141,216,182, 69, 99, 95,215,227,231,175,254,126,253,246,195,216,186,158,142, 78,212,160,179, 95,177, +102,131, 39, 81,169,205, 77,242, 14,112,116,116,132, 94,175,199,171, 87,175,240,246,237, 91,232,245,122, 24, 11, 11,161, 85, 40, +160,201,205, 5, 91,152, 15, 62,203, 66, 45,207,132,131,149, 8,248, 99,134, 97,149,168, 40, 44, 88, 54, 36, 40,178,177,129,208, +218, 6, 12,143, 87, 97,248,176, 18,206, 38,205,155, 55, 63, 20, 29, 29,221,162,107,215,174,139, 9, 33,182,148,210, 55,169,169, +169, 93,230,206,157,171,117,113,113,193,216,177, 99, 27, 0, 24, 81, 29,151, 80,160, 11,168,227,218, 0,126,222, 35, 80,183, 86, +103, 40, 10, 13,144, 43, 13,200, 84,232,177,229,167, 86, 56,186,189, 57,110, 30,109,135,232, 11,221,160, 48,184, 66,234,222, 23, +148,213, 5, 85,197,121,251,246,109,108,222,188, 25,155, 55,111,198,166, 77,155,176, 97,195, 6,228,230,230, 34, 56, 56, 24,201, +201,201, 56,119,238, 28,222,189,123, 7, 71, 71, 71, 60,122,244, 8, 91,182,108,193,253,251,213,231, 17,155, 51,129,147, 82, 90, +227, 88,185,209,104, 28,249,174, 95,191,134, 25, 50, 89, 96,227,198,141,123, 78,154, 52,201,187, 77,155, 54,165,251,189,188,188, +106,139,197,226,116, 66,200,118, 66, 72,104, 85, 92, 38,160,177,147, 83, 48,116,218, 56, 0, 0, 33, 60, 16, 34, 66,231,110,177, +104,211,238, 33,244, 6, 62, 24, 34, 4,195,136, 96, 52,102,195,222,222, 29,148,146,224,106, 76,156, 43,151,203,125, 47, 93,186, +196, 36, 38, 38, 66, 36, 18, 1, 64,210,130, 5, 11, 54,172, 94,189, 58,198,193,193,129, 61,125,250, 52,142, 31, 63,142,176,176, + 48,206,152, 49, 99,124,107,213,170,181,185,186,235,158,191, 46,237,206,254, 53,231, 62,229, 25,236, 67, 69,226,186,245, 80, 40, +237, 59,161,163,147, 4, 0,206,197,199,231, 59,215, 86, 46, 47,204,127,146,108,231, 89,240, 67,117, 9,238,148,206, 55,253,254, + 50,238,238,254, 99,231,243, 50, 51,114,121,141, 27, 6,169,151, 45,250,150, 95,183, 94,253, 21,243,167,143,115, 77, 85,138, 20, +221, 38,157,139,139, 56,127,191, 96,216,168, 47,140,159,127, 57, 81,115,238,252,111,199, 76, 38, 83,195,202,102, 16,154, 76, 38, +188,123,247, 14,207,158, 61, 67, 66, 66, 2,228,114, 57,178,178,178,144,159,159, 95, 26, 86,180,202, 87,158,217,176,243,212, 99, +137, 88,108,213,162,161,111,237,123, 81, 49,153, 18,177,216,202,183, 94,109, 63, 66, 22, 86,248, 28, 97, 89,182,161,200, 74, 12, +128, 64, 17,125, 29, 5,185, 5, 40, 80, 20, 32, 63,167, 0, 90, 61, 7, 26, 45, 3,181,142, 65,157, 14,221, 81, 80,168, 65, 65, +118, 30, 76, 44, 27, 82,221,253,180,192, 2, 11,254,119, 65, 8, 57, 61, 99,198,140, 89,102, 14, 55, 59,140, 89, 94,112,205,152, + 49, 99, 22, 33,228,244,204,153, 51,131, 96, 70,206,114, 69,168,182, 76, 67, 86,214,139, 2, 27,167,192, 1,147,191,155,119,238, +192, 47, 27,157,116, 58,117,178,163,189,148,181,182, 18,218,143, 25,251, 61,242, 11,114,251, 23,152, 89, 86, 0, 0,114,115,115, +241,250,245,107,136,197, 98,240,121, 60,176,106, 53, 88,117, 33,212,185,217, 96,244, 90,240, 89, 22, 50, 43, 49,234,184,187,162, +174,139,171, 89,156,175, 34, 47,150, 38,180,151, 13, 11,174,108, 30, 0,129, 68, 10,129,181, 20,255, 58,125, 21, 0,192,231,243, +129,185,139,171,229, 36,132, 56,122,120,120,156,220,191,127, 63, 95, 46,151,227,209,163, 71,143, 41,165,121,132, 16,107, 0,166, +216,216,216, 75,209,209,209, 97,190,190,190, 0,224, 83, 29,159, 50,139, 97, 13, 70,138,148,244, 36, 36,190,141,130,204,214, 11, + 60, 43, 63,100, 42,244, 16,138,189, 96,208,254, 17,101,212, 40,223, 64,173, 55,111,162,163, 94,175,135, 94,175,135,193, 96,128, + 86,171,197,176, 97,195,112,235,246,109,252,122,252, 50, 94,199,191, 64,131,122,174, 24, 62,124, 24, 66, 67, 67,241,224, 65,213, +249,195, 35, 27, 19,195,236,246,224,174,233,201, 64, 32,117,208,182,156,126,225, 94, 85,227, 75, 68, 86, 85,191, 54, 74, 64, 8, + 89, 29, 22, 22, 86,255, 69, 97, 33,158,197,197,161,235,130, 5, 0,128, 51,103,206,148,142,209,233,116,152, 50,101,138, 32, 38, + 38,230,243,135, 15, 31,126, 78, 8, 89, 67, 41,173, 56,137,156, 2,103,206,220,193,184,113, 49,144,203,139,242,176, 15, 30,248, + 67,143, 38,190,214,227,163,222, 69,145, 43, 59, 59, 59,172, 89, 83,157,182, 42, 2,203,178,216,186,117,107,105, 88, 16, 0,184, + 92,110,155, 41, 83,166, 12,168,104,124,253,250,245,249,213,113, 78, 9,247, 20, 61,122, 35,158, 96, 91,191,110,144,141, 99, 35, +100, 27,162,130,163, 82,223,125, 53, 37,220,115,237,154,195,111, 53, 98,162,221, 69,216,148, 90, 92,145,102,183, 57, 54,198,159, + 91,175,179,171, 59,106,119,186, 92, 57,123,226, 23,159, 57,216,216, 57, 23,110,223,176,204,158,225, 48,244,228, 67,189, 34,200, +219,193,174,111,203,117, 5,227, 38,207,141,210, 25, 83, 38, 34,229,228,139,170, 74, 85,176, 44,139,180,180, 52,200,229,114, 36, + 39, 39, 35, 43,171, 40,204,154,149,149,245,167,153,168, 53, 1, 33, 4,234,228,100,188, 57,182, 29,117,135, 13, 67,179,197,139, +192,154,184, 80,171, 88,172,105,221, 5,185,121,106,104, 77, 4,238, 77, 90,227,139,179, 55,192, 80, 22,216, 82,163, 10, 29, 22, + 88, 96,193, 63, 8,230,148,105, 40, 17, 66,203,150, 45,171, 54,186, 85, 83,148, 21, 89,203,150, 45,123,182,108,217,178,191,116, +174,106,203, 52, 0,128, 82, 30,147,224, 80,167, 81, 90,161,186,192,202,217,197, 81, 39, 21, 9, 77,121,202, 66, 78,212,211,199, +250,130,119,175,158,215,224,124,177,209,209,209,193,105,105,105, 72,126,243, 6, 70,117, 33, 24,173, 14, 84,163, 66,215,182,173, + 33, 2, 32, 98, 8,248, 38, 61,184, 28, 1,242, 11,148, 0, 16, 91, 29, 41,107, 48,148, 46,151,136, 43, 66, 8, 4,214,214, 16, + 72, 36, 16, 72,173, 75,247, 1,230,121,104,132, 66,225,254,195,135, 15,187,121,120,120, 96,209,162, 69,240,244,244,244,111,216, +176,161,170, 93,187,118, 98, 23, 23, 23, 4, 6, 6,162,117,235,214, 56,119,238, 28, 0, 84, 91, 19,202, 96, 20, 61,121,158,132, + 54, 89, 57,183,113,227,234, 38,232,212, 90, 52,238,176, 9,122,110, 93, 56, 5, 45,132,233,213, 94,168,210, 79, 0, 0,172, 92, + 63,198,219,228, 36, 16,142,224, 89,181,134,150, 1,165, 20, 79,158, 60,193,129, 19,215,224, 86, 39, 0,201, 47,227, 16,119,229, + 18,110, 57, 57,160,110, 96, 16, 12, 6, 67,149,215,110, 96,193, 93,178,177,180, 76,131, 48, 39, 39, 71, 40,147,201,180, 64,209, +189,115,115,115,171,240,156,102,138,172,207,166, 77,155, 6, 5,143, 7,244,238, 13,126, 66, 2,244,122, 61, 90,181,106,133,166, + 77,155, 2, 0, 90,181,106, 5, 46,151,139, 70,141, 26,193,221,221, 29, 27, 55,110,252, 12,149,204,210, 99, 8, 30, 25,141,217, +254,222,222,222,165, 2,107,247, 30, 57,162, 30,118, 3,129, 0,235, 55,252, 81,149,161,118,237,218, 72,127,151, 0, 66,104,116, + 53, 54, 46,118,117,117,157,235,230,230,230,189,122,245,106,142, 72, 36,194,248,241,227,189, 10, 10, 10,234, 2,192,242,229,203, + 49,115,230, 76, 0,192,252,249,243,177, 96,193, 2,104,181, 90, 85,101,100,123,126,108,228,158,153, 99,250,220,197,213,163,127, + 39,199,186, 13, 59,247,232, 10, 47,223,206,232,220, 35, 25, 0,150,202,184, 73,131, 86,206, 9, 62,230, 88, 75,182,227,226,249, +223,230,183,237,208,121,246,140,177,246, 75,150,111,201,173, 54,167, 49,239,205,174,252,231,130,193, 63,254,180,121,207,143,243, +102,126, 45, 74,150,235,114, 83,115,105,129, 84,200,149,250,184, 16,233, 87,223, 45,126,157,150,150, 48, 21, 41,231,171,157, 57, +105, 50,153,144,144,144, 80,154,179,167,209,104, 80, 88, 88,136,148,148,148,210, 16,161, 90, 98,243,209,196, 81, 31,135, 20,170, +213,170,123, 79, 95, 38,207,153, 52,180, 85,161, 90,173,122,153,152,252,130,210,117, 21,170, 48,134, 97,158,170,242, 85, 93, 85, + 10, 13,228,143,158,195,179, 75, 29, 24,140, 4, 58, 35, 11,121,118, 62,180, 70,128,101,120, 8, 26, 52, 28, 44,225, 34, 43, 45, + 21, 12,135,243,184, 58,123, 45,176,192,130,127, 44,170, 45,211, 64, 8, 57,221,170, 85,171, 95,129, 63,188, 76, 37,203, 0,180, + 0,170, 74,217,145,151, 21, 81, 37, 97,195,202,206, 83,142,183,198,168,182, 76, 67,241, 62, 18,210,176,142,251,202,249,159,121, +154,140,198, 6,153, 89, 25, 70, 46, 87,200,171,101,171,126, 87,147,147,105,181,218,211,151, 46, 93,234,215,173, 91, 55,225,203, +167,143,161,203,203,131, 46, 79, 1,158,201, 8,153,184, 41, 24,189, 22, 68,167,131,135,191, 9,154,124, 49,174,221,138, 54,104, +181,218,211,213,241,150, 8, 44,134,195,121, 63,239, 74, 42,133,208,218, 6, 66,169,180,124, 8,177, 74, 49, 64, 8,177,234,211, +167, 79,151,150, 45, 91,130, 82,138,173, 91,183, 66,175,215, 11,244,122, 61,116, 58, 29,244,122, 61,148, 74, 37,246,236,217,131, +159,127,254,249, 22,128,157,213,217,104, 50,234, 46, 93,248, 45,178,249,232,161, 97,188,179,167,215,192,168, 99,161, 38,158, 40, + 44, 52,160, 64,103, 5,214, 97, 24,144,113, 6, 28,174, 8,173, 26,121,225,196,145, 8, 61,140,218,203,213,241,150, 23, 76, 26, +141, 6, 41,201, 73,120, 27,255, 2, 82,101, 58,156,108,172,160, 74,120,129,208,225, 35,160,211,233, 42, 97,169, 28,181,106,213, +130,201,100, 66,167, 78,157, 74,147,166, 43,178,193, 28,145,149,157,157,141, 83,167, 78,161,101,203,150,232,208,161, 3, 82, 83, + 83,145,144,144,128,222,189,123,151,142,121,252,248, 49,162,162,162,224,227, 83,181, 83, 48, 43,199,112,246,109,202,163,240,190, +125,251,242,239,222,189, 11, 74, 41,124,125,109, 96, 99, 45, 1, 97,132, 8, 8,112, 6, 80,164,253, 59,118,236, 8,165, 50,193, +152,155, 75,207, 86,197, 73, 41,221, 79, 8, 57,174,211,233, 94,181,111,223,222, 61, 62, 62, 30,147, 39, 79,230, 30, 60,120, 16, + 0, 48, 99,198, 12,204,152,241,254, 36, 9,181,186,242,208,124,131,134,254,223,122, 25,237, 59,136,196,117,235,217, 56, 54,130, +151,111,103, 0, 64,183,176,209,240,170, 95, 27,202,172, 39,245, 52,234,164,254,124,110,174,253,147,245,169, 49,226,222,193,163, + 52,153, 87, 95, 2, 48,167,112, 47, 85,191, 60,152,145,204, 27,118,232,248,201,115, 99,123,133,245,225, 25, 88,163, 49,184, 14, +207,238,240,177, 51,153,169,111,146,215, 33,249,124,137,160,172,242, 23, 5,203,178,172, 82,169,132, 68, 34, 65,116,116,180,182, +119,239,222, 66,134, 97,240,234,213,171, 82,129,229,236, 40, 11,108,211, 44,216,127,201,143,123, 46, 72,132, 66, 97,143,142, 77, + 3, 98, 94,190,121, 75, 41, 73,170,140, 87,103, 48,252,246,244,209,227, 78, 78,238,245, 57, 9, 87,239,194,161, 93, 47,104,181, + 12,212, 58, 19,180, 70,192,200,225,195, 45,180, 5,236,124, 2, 64, 1, 60,184,123,203,160, 53, 24, 42, 45, 77, 98,129, 5, 22, +252,243, 81,133, 22,145,151, 17, 68, 57, 0,146,150, 45, 91,150, 85,198,187, 36, 7,240, 24, 64, 72,241, 56,121,185,227,228, 40, +154, 13,216,172, 12,143, 28, 40, 21, 90,101,151,117,229,198,124,208, 15,191,106,203, 52, 0,128,163,163,163,115,227,198, 77,125, +182,253,114, 8,148, 82, 60,143, 90,133,220,204, 56,204, 93,122,199,199,211,211,179,195,219,183,111,175,153,115, 50,150,101, 15, +238,216,177, 99,106,139, 38,141, 27,215,243,244,196,227,164, 68,240, 41, 11, 62,203,130,209,107,193,101,117,240, 12,102,193, 16, + 41,210,210,242,176,124,255,161,104,150,101, 15, 86,199,235,223,171, 15, 22,189,205, 3, 33, 4,171, 91, 5, 67, 96, 45, 5, 95, + 34,197,191, 78, 70,150,138,170,211,139,102, 66, 32,149,194,167, 69,245, 5,220, 41,165, 42,107,107,235,135, 79,159, 62,109, 22, + 28, 28,140,169, 83,167, 34, 41, 41, 9, 38,147, 9, 25, 25, 25,154,119,239,222,165,202,229,242, 36, 0,199, 0,108, 51,167, 82, + 56, 95,171, 89,123,250,232,238,137,173,218,118,112,236,219,255,103, 28, 63, 50, 5,138, 60, 37, 84, 70, 49, 10, 53, 70, 20,106, + 57,144, 57, 52, 68,139, 70,141,144,150,154,137,103,119, 47, 20,112,181,170, 85,213,223,213, 82,155,193, 48, 12, 30, 63,126, 12, +111,119,107,188,184,113, 13,142, 86, 60,132,184,187,194,189, 77, 91, 36, 36, 36, 84,203,193,227,192,248,217,103,159,149, 86,114, +239,222,189,123,226,176, 97,195,220,166, 76,153,130, 95,126,249, 5,183,110,221,250, 83,226,117,135, 14, 29,112,253,250,245,133, + 0,230, 87, 67,111,208,233,116,240,247,247,199,131, 7, 15,112,233,210, 37,116,238,220, 25, 29, 58,116,192,147, 39, 79,112,241, +226, 69, 68, 69, 69,129, 16, 2, 7, 7, 7, 24,138, 68,179,161, 50, 50,189, 30,135,127, 88,177, 99,214,143, 63,254, 28, 52,116, +232, 80, 28, 61,250, 43, 70,143,106, 0,194, 8, 65,136, 16,125, 62,110,128, 69,139, 31,160, 69,139,142,112,116,228,225,199, 53, + 39, 94,171,213,236,158,106,111, 2,176,228,226,197,139,238, 26,141, 6, 10,133,130, 74,165, 82,146,157, 93, 52, 67,181, 34, 15, +150, 74,165, 18, 85, 70,244,244,247,216, 85,138,124,154, 75, 11,162,250,231, 24,163, 26,118,238,145,130,110, 97,163,240,219,233, +157,136,188,112, 9, 50,110, 82, 34, 36,249,231,178, 18,179,148,239, 10,125, 55, 7, 52, 25,195,121, 91,120, 97,243,164,190,246, + 28, 55, 55,211,225, 25, 63,231, 41, 42,227,166,197,127,176, 57, 49,123, 79, 30,163,232,211,186, 85,139,250,193,181,221, 4,185, + 89,153,244,200,137,115,209,250,196,163,167, 80, 44,172,104, 53, 46, 91, 74,233,162, 25, 51,102,204, 43, 94,222, 53,103,206,156, + 49,203,151, 47,119, 74, 79, 79, 47,205,193,202,204,202,137,108,221,251, 43, 54, 91,145,167,219,241,227,119, 3,197, 34,161, 96, +206,242, 29, 87, 13, 28,220,173,140,215,104, 50,109, 28, 52,121,238,215, 47,159, 71,121,212, 21, 11,112,226,187,249,120,124,241, + 10, 12, 12, 31,227, 46,221,131, 86,207, 66,145,149,141,203,159, 79,128,212,197, 30, 63, 95, 61,154, 97, 50,153, 54, 85,101,171, + 5, 22, 88,240,207, 70, 21, 90,164,162, 28,151,140, 10,182,149, 31, 87,221,250,191, 13,102, 77,169,203,202,202,202,188,126,253, + 30,174,158, 94,130,107,167,151,224, 89,212, 99,164,165,234,144,154,161,129,141,141,205,157,202,142, 35,132,116, 45,187, 78, 41, +165, 42,149,106,192,156,185,243,210, 69, 98, 43,180,239,210, 5,174, 78,206,176,226,243,192, 49,154,192, 33, 60, 20,200,237,240, +226,137, 10,211,119,236,205, 44, 80,169, 6,148,255,231, 80,158,179,204,118, 16, 66, 32,180,177,134, 64,106, 13,161,181,205,123, +225, 66,145,141, 13, 68,214, 54,224, 10, 4, 21, 37,195,255,137,179,160,160,224,147,129, 3, 7,230,230,229,229, 97,204,152, 49, +184,118,237, 90,212,133, 11, 23,108, 30, 63,126, 44,206,204,204,172, 79, 41,237, 78, 41,221, 82,153,184, 42,207,153,147, 19,159, + 79,141,218,193,203,230,125,163,214, 24, 29, 16, 62,226, 32, 36, 76, 10,140,172, 9, 20,128,187, 76,128, 54, 93, 23, 35, 83,215, + 26, 7, 55,127,175, 50,233, 53, 67,203,214,192, 42,207, 73, 41,165, 14, 14, 14,239, 93, 11,195, 48,184,122,245, 42,194, 7,126, +130, 30,253,251,193,169,158, 55,156,187,246, 66,143, 49,227,176,101,203, 22, 48, 12, 3,153, 76, 6,148,241,104,148,229,220, 21, + 69,121,251,159, 80,178,255, 9, 37, 59,127,167, 92, 0,195,247,238,221,251, 67, 72, 72,200,149, 91,183,110,173, 2, 48,184,236, +253, 46, 99,203,130,178,222,171, 74, 62,163,217, 95,127,253,181,250,229,203,151,144, 72, 36, 48, 26,141,184,117,235, 22,126,254, +249,103,172, 94,189, 26, 81, 81, 81,112,112,112,128,143,143, 15,180, 90, 45, 30, 60,120,160, 6, 48,187, 50, 78, 74,169, 73, 46, + 55,126,178,126,253,242,236,176,176,118,216,177, 99, 3, 92, 93, 91,131,199,117, 5,151,231, 4,137,212, 31,219,183,253,128,158, + 61, 27,227,228,137, 67, 57, 89,217,198, 79,104,185,170,235,149,216,169,185,119,239, 30, 54,111,222,140,129, 3, 7,166,134,135, +135,179,121,121, 69, 69,106,103,204,152, 81,218, 37,125, 65,113, 14,153, 86,171,125,207, 29, 93,150,115,204,119, 79, 83,191, 93, + 18,189, 40, 35, 61,181,229,181, 43,119, 62,139,188,112, 9,175, 95, 70, 34,242,194, 37,220,136,188, 61, 35, 35, 61,181,101,227, +230,126,252, 1, 99, 38,126,187, 59,219,243,196,221, 0, 0, 32, 0, 73, 68, 65, 84,226, 40, 71,106,227,134,221, 17, 71, 57, 67, +190,250,230,251,166, 61, 58, 87,122,237,101,111, 3, 0, 90,144,153, 49,115,233,170,159, 10,140,122, 13,179,114,221,198, 52,181, +252,221,108,148, 76,173,172,196,123, 85,150, 83,165, 82,109, 81,171,213,238,106,181,218, 93,163,209,204, 78, 74, 74,106, 63,117, +234, 84, 57,203,178,165, 30,210,204,103, 39,238,196,222,216,185,212,217,209, 94,220,186, 89, 80,131, 53, 91,142, 92, 77, 78,201, +216, 87, 82, 3,171,146,207, 72, 83,160,214,124,210,111,192,176, 66, 69,174, 22,173,190,153, 1,147, 72, 10, 45, 11, 24, 40, 7, + 70,194,197,211, 37,107, 32,150, 89, 99,127,226,239,170, 60,131,254,147,178, 53,176,170,185,246, 15,134,133,211,194,105,225,252, +191,201,249, 79, 3, 23,168,126,106,164,135,135, 71,251,190,125,186,162, 99,216, 28, 80, 74, 17,247,251, 10,228,202,159,195,195, + 85,136,132,100,101, 43, 0,215,204, 61, 33,165, 52,153, 16,210,242,235,217,115, 34,194,187,119, 9, 8,174, 87, 79, 88,183,110, + 29, 72,156,157,145,149, 37,199,205,187, 49,134,239, 15, 28,142, 46, 22, 87,230,180,202,129,201,100, 42, 74, 94, 7,208,229,235, +233, 32, 28, 14, 80, 92,142,161,228, 31, 98,189,102,173, 65,184, 92,176,212, 4,173, 86, 91,109, 18, 22,165,244, 45, 33,228,147, +161, 67,135, 94, 62,125,250, 52,211,163, 71,143,208, 99,199,142,125,120,198, 47,128,130,140, 23, 87,164, 46,126, 97,223,207, 28, +123,176,101,231,126, 54,190, 65, 77,249, 77,235,114,160, 55, 16,164,165,190,193,233,136,251,250,152,123, 23,148,212,168, 25, 92, + 40,175,186, 85,142, 94,175, 79,118,113,113,113, 89,184,112, 33,140, 70, 35,140, 70, 35, 88,150, 69, 86, 86, 22,238,220,185,131, +134,205, 90, 32, 96,212,231,144,203,229, 88,191,126, 61, 60, 61, 61,177,116,233, 82,228,228,228,192,104, 52,154,117, 95, 41,165, + 44,128, 11,197, 47, 0,127, 8,217,146, 95, 25,213,133, 7,125,124,124, 4, 26,141, 38,212,205,205,141, 75, 8, 89,171,211,233, + 70,205,156, 57,211,117,233,210,165,104,208,160, 1,178,178,178, 32,145, 72,224,235,235, 11,185, 92,142,251,247,239,179, 42,149, +106, 51,128, 69,148, 82,121, 69,156,101,236,123, 69, 8,105, 57,105,210,191, 34,126, 88, 62,214, 87,163,237, 40,144,201,218,130, + 82, 35,228,242, 36,228, 43,111,233, 23, 47,218, 25,159,145,105, 24, 64, 41,125,105,206, 53, 3,152, 63,113,226, 68,160,184, 85, + 78, 66, 66,194,163,128,128, 0, 95,160, 98, 15,150, 57, 88,115,248,173, 6,192,129,149,147, 91, 79, 86,102, 61,241,149,113,147, + 18, 91, 6,155,214,175, 57,252, 86,179,112,178,221,146,172,164,107, 47,222, 21, 94,216,188, 59,226, 40,103, 68,255, 79, 88, 79, +233,203, 25, 34,103,122,164,243,199, 85,243, 82, 74,105,104,104,104, 45, 66,114,188, 50,179,159, 63, 28, 61,102,236, 32, 91,190, +250,108,136,103,182, 15, 83,187,177, 40, 42, 42, 42,177, 58,239, 85, 37,188, 47, 8, 33,237,103,206,156,121,129, 82,250, 94,238, + 65,102, 86, 78,100,171,176,137, 84,161,200,123,148, 25,115,162,218, 90,104,148,210,251,132,144, 46,193, 13, 27, 31,253, 97,233, +114,151,142, 95, 79,229,190,184,114, 21, 96, 13,120,115,237, 42, 88,161,206,180,230,246,111, 25,121,122,125,127,106,169,226,110, +129, 5,255,211, 48,167, 76,195,127, 19,170, 45, 52, 10, 0,111,223,190,189,230,227,237,121,241,197,139,246,221,107,123, 58, 1, + 0, 18, 18,211,144,154,161,189,104,110,120,176, 44,138, 69, 86,211,189,167,206, 14, 22, 10,133, 97,164,184, 20, 3,253,128,102, +207, 70,163,241,109,189,122,245, 42,217, 91,113,169, 38,150,101, 43,114, 43, 86,100,231, 85, 66,200, 48, 31, 31,159,229,111,222, +188,137,160,148, 22,154,115, 92, 85, 40,200,120,113, 69, 38,243,241,190,125,233,232, 55,119,175,158,238, 74,141,186,134, 0, 64, +184,130, 26, 53,123, 46, 40, 40, 24, 59,126,252,248, 45, 60, 30,175, 54,138,115,202, 74,102,124,177, 44,203,209,235,245, 34,150, +101, 57, 0, 8,195, 48, 70, 30,143,167,137,136,136, 48, 26,141,198,100,173, 86, 59,246, 67,237,175,233, 23,255,236,217,179,117, +237,237,237,187, 19, 66, 6, 82, 74,253,243,243,243,181,115,230,204,185, 19, 17, 17,145, 87,167, 78,157,143,122,247,238, 77,100, + 50, 25, 30, 60,120, 64,179,179,179,143, 0,152, 77, 41,173, 62,158,249,135, 61, 9,132,144,144,177,227, 54,125, 42,147,109,233, + 77, 41, 66, 64, 65, 8,131,167,121,121,166,179, 42, 21,187,175, 88, 40,154,203,103,196,251,158,179,197,209,209,209, 59, 1,240, + 42,202,193,170, 17,172, 10, 78,106,212, 73,159, 16,169,234,216,154,117,111, 53, 0, 48,255, 71, 69, 30,128,237,147,250,203, 76, +177,191,111, 95,225, 97,243,242,187,117,199,114,118,152, 67,215,184,113, 99,111,134, 97, 6, 3, 8,118, 22, 42,234, 59, 9,242, + 88, 66,104, 39, 66, 24, 71, 0, 79, 2, 3, 3, 79, 3,120,251, 33,166,210,162,182, 66,117,202,111,207,124,118,226, 14,128, 74, +189,214,149,112,221, 39,132,212,159, 60,109,202, 4, 1,143,215, 13, 44,219,104,241,241,195,212,210,236,217, 2, 11, 44,248, 39, +195, 44,129, 5, 0,241, 9,111,123, 0,128,159,159, 31,125,249,242,229, 95, 86,152,197, 2,234, 87, 84, 83,165,189, 58,100,101, +101, 53,253, 43,199, 87, 7, 74,233, 1, 0, 7,254, 78,206, 98, 1,181,168,248,245, 65,160,148, 62, 5,208,226,111, 51,234,195, +108, 40,137,149, 47,172,108, 76,247,238,221,223,232,245,250, 75, 40,250, 71,111, 7, 32,199, 96, 48,156,215,233,116, 25,132,144, +166,107,214,172, 41,169, 84,191,152, 82,250,240, 3,237, 48, 1,216, 95,252,250, 91, 65, 41,221,239,238,238, 62,197,193,193,193, + 71,163,209, 8, 52, 26, 13,191,172,246, 23,139,197, 85,122,217,202,194,206,154,236,226,115,115, 29,236,172,201,159, 4,148,204, + 3, 71,213,133,209, 13,100, 30, 56,106, 46, 95, 84, 84, 84, 66,104,104,232, 94,134, 97,234, 81, 74, 93, 0,106, 75, 41,228,148, +210, 44, 46,151,155, 26, 19, 19, 99, 86,143,204,255, 31, 40, 22, 80,171,138, 95, 22, 88, 96,129, 5,255,120,152, 45,176, 74,240, +226,197,139,127,132,235,206,130,191, 7,213, 9,237,164,164, 36, 45,128,219,197,175,242,199, 62, 4, 80, 77, 32,236, 63,143,180, +180,180,198,127, 7,207,152,239,158,166, 2,248,166,105, 5, 45,151,231,175,207,201, 7,240,109,167, 62, 53,227,124,244,232, 81, + 50, 0,179, 66,190, 22, 88, 96,129, 5, 22,252,255, 67,205,250,198, 88, 96,129, 5, 22, 88, 96,129, 5, 22, 88, 80, 45, 8,128, + 10,103, 2,208, 26,116,202,254,144,217, 4,213,241, 91, 56, 45,156, 22, 78, 11,167,133,211,194,105,225,252,231,113,254,207,160, +100,150,221,191,227, 5,160,171,133,211,194,105,225,180,112, 90, 56, 45,156, 22, 78, 11,231,255,218,171,198, 57, 88, 22, 88, 96, +129, 5,255, 20, 28, 57,114,196,172,166,159,159,126,183, 61, 76, 42,181,159, 91,160,204, 91,254,235,170,209,199, 74,182, 15, 28, + 56,208,236, 25,170, 22, 88, 96,193,255, 22, 42, 21, 88,222,222,181, 2, 25,214,212,134, 82,134, 67, 25,106, 32, 74,245,193,248, +156,156,247,202, 7,212,174, 93,219,142,199,224, 99, 66,169,132, 16, 19,107,226, 48,183, 18, 18, 82, 98, 42,227, 44, 15, 66,136, +192,222,222,126, 34,159,207,239,170,211,233, 60, 25,134,121,171,213,106, 47,169, 84,170, 13,180, 92,193,193,255, 36, 26, 52,104, + 48,228,234,213,171,118,109,219,182,213,138,197, 98,163, 90,173,230,158, 63,127, 94,216,179,103, 79,197,171, 87,175, 62,104,134, +161,135,135, 71,231,237,219,183,123,245,232,209, 3,245,235,215, 47, 28, 60,120, 48,191, 85,171, 86,252, 49, 99,198,188, 78, 77, + 77,141,172, 9, 23, 33, 36,144, 16,178,135, 16,194, 49,153, 76,195,105,209, 12,195,191, 29,132, 16, 6,192,151, 0,250, 1,240, + 6,144, 0,224, 56,128,173,212,140,106,246, 21,240,125, 2,160, 23,128,144,226, 77,143, 1,156,165,148,154, 61,147,174, 50, 78, + 66, 72, 40, 0, 80, 74, 31,253, 93,156, 60, 30, 47, 20, 0, 12, 6,195,223,198,249, 87,237, 36,132,140, 18,139,197, 95, 0,128, + 90,173,222, 70, 41,173,182,109,211,159,176, 37,128, 2, 64,224,138, 56, 0, 64,204,119,254, 48,119, 61,230,117, 13,103, 19, 87, +114, 46,140,141,253,224,201, 51,132,144, 94, 67,135, 14, 93,186,111,223,190,249,148,210, 19, 31,202, 83, 21, 92, 93,107,109, 88, +189,110,171,251, 55, 19, 63, 95,142,162, 14, 14, 85, 34,136,144,110, 2, 14,167,143,142,101,111,196, 0,135, 1,112,101, 50,217, + 16,129, 64,208, 94,167,211,185,113,185,220,119, 58,157,238,122, 94, 94,222, 1, 74,105,165, 29, 11,204, 70, 28,177,215,171,224, + 74, 76,127,244, 97,163, 12,180,124, 43,164,195,159,230, 86,117, 40,135,195, 89,229,225,225,241,165, 66,161, 40, 96, 24,134,146, + 34, 0, 69, 93,210, 74,106,223, 17,147,201,148,154,147,147,243, 65,179,182, 9, 33, 34, 0, 11, 80,212,211,109, 29,165, 85,219, + 84,137,157,223,184,187,187,247, 87, 42,149, 42, 14,135, 67,203,216, 71, 0,128, 97, 24, 98, 50,153, 50,179,179,179,135,127,136, +141, 22, 88,240,119,131, 11,188,215,251,167, 35,165,244,154,183,119,173,192,129,253, 6, 44, 29, 55,118, 60,225,112, 24, 68, 63, +123,198,253,108,248,168,238, 50,153,204, 67,170,213, 6,128, 16,147, 74, 36,138, 54, 24,244,169,135, 15,236,179,246,111,208,128, +101, 89, 19, 54,111,217,212,211,219,187,214, 44,115, 68, 22, 33,196,207,213,213,117,207,140, 25, 51, 92,251,244,233,195,113,117, +117, 69, 82, 82,146,221,175,191,254,218,224,167,159,126, 26, 68, 8, 25, 78,139,106,241,212, 8,132,144,118,174, 50,166,187,181, +152,116, 65, 62,139,124, 3, 46,167,171,113,145, 82,122,163,166, 92, 37, 80,169, 84, 95,169, 84,170, 22,205,154, 53,163,191,252, +242, 11, 25, 57,114, 36, 37,132, 16,181, 90,189, 11, 31, 88,194, 65, 34,145,108,236,209,163,135,175,175,175,111, 66,124,124,124, +175, 67,135, 14,157, 29, 49, 98,132,183, 68, 34,121, 9,192,175,134,116, 59,179,179,179, 67,212,106, 53, 60, 61, 61,127, 1,208, +228, 67,108,170, 10,197, 15,177,163, 50,153, 76,179,104,209,162,109, 29, 59,118,244, 72, 75, 75, 99,167, 79,159,222,230,209,163, + 71, 31, 17, 66,250,153, 43,178, 8, 33,246, 0, 54, 75,165, 82,171,233,211,167, 95,239,214,173, 91,162, 84, 42, 21, 61,121,242, +132, 55,125,250,244, 47, 9, 33,225, 0,198,213,228, 33, 92,194,233,228,228,100, 55,127,254,252,167,173, 91,183,190,198,231,243, +249,207,159, 63,231,205,152, 49, 99,194, 95,225,244,245,245,181,158, 55,111,222,131,208,208,208, 12,145, 72,196,143,143,143,231, +205,154, 53,107, 28,135,195, 9, 55,153, 76, 31,196, 41,147,201,108,102,205,154,245,176, 67,135, 14,114,161, 80, 40,136,137,137, +225,206,156, 57,115, 92, 77,236,116,112,112,232,228,224,224,176, 53, 61, 61,157, 11, 0,110,110,110,205,125,124,124,126, 42,169, +135, 6,252,209,171,210, 96, 48,228,107, 52,154,161,217,217,217,127, 42, 96, 27,184, 34, 14,223,206,219, 53,228,219,121, 69,235, +187,139,183, 87,183, 14,140, 52,251,187, 31,232, 85,244,140,153, 48,237,231, 97, 69,239, 69,219, 55, 21,155,186,209,139,208,154, +136, 53, 66, 72,223,206,157, 59, 47,136,140,140,220,212,177, 99,199,233,123,247,238,117, 78, 73, 73,249,129, 16, 82,235,211, 79, + 63, 29,121,249,242,229,101,114,185,252,136,185,124,213, 65,192, 23, 10, 9, 67, 32, 22, 89,217,152, 51,158,199, 48, 97,183,251, +246,253, 98,219,243,231,141,127,138,139,243, 42,116,115,107, 49,105,210, 36,151, 1, 3, 6, 48,181,106,213,194,171, 87,175, 28, +246,238,221, 27,176,109,219,182,254,132,144,175, 41,165,111, 62,216,184, 56, 98, 95,168, 64, 67,173, 14,141, 41,133, 93,201,102, + 66,160, 16,234, 17, 37,137, 35, 79, 43, 19, 89,132,144, 31,251,246,237, 59,252,248,241,227,210,189,123,247, 74, 91,183,110, 13, + 23, 23, 23, 16, 66,192,178, 44, 76, 38, 19, 76, 38, 19, 40,165,240,245,245,253, 43, 51,200,215,222,184,113,227,203, 87,175, 94, + 97,204,152, 49, 28, 0,115,106,114, 48, 33,100, 74,255,254,253,123, 71, 68, 68,136, 15, 31, 62, 44,110,214,172, 25, 92, 93, 93, + 1,160,212, 62, 74, 41,188,188,188,254,130,137, 22,252,167, 81, 94,139,252, 39,109,249, 59, 80, 81, 47, 66,194,176,166, 54,227, +198,142, 39,131,135,124,154,254, 42,225,181,137,203, 19, 12, 57,127,225,130, 85, 96, 96, 32,163,221,176, 1, 70,185, 28,134,201, +147, 91, 95,186,116,201, 16, 62,100,152,154,199, 33, 59,189,189,234, 89, 29, 60,240,171,107,196,209, 35,109, 0, 84, 41,176, 8, + 33, 2, 87, 87,215, 61, 87,175, 94,245,240,242,242,130, 66,161, 64, 82, 82, 18, 10, 11, 11, 49,104,208, 32, 94,155, 54,109, 60, + 6, 14, 28,184,135, 16,210,214, 92, 79, 22, 33,196,165,190, 39,247,244,234,121,131,252,122,118,111, 35,241,168,229, 3,154,174, + 65, 74,124, 92,179,211, 87,239, 78,242,181, 99, 94,188,202,163, 97,148, 82,179,138,140,150, 69, 86, 86,214,119,253,251,247, 63, +218,169, 83, 39, 39,161, 80, 8,119,119,119,210,167, 79,159,204,180,180,180, 74,235, 63,153, 97, 47, 0,128, 97, 24,182,236, 59, + 33, 31,244, 12,243,180,183,183,135,189,189, 61, 0,120,124,168, 77, 0, 16, 30, 30,206, 73, 78, 78,254,194,100, 50, 5,148,221, +238,236,236,220,128,101,217,220, 55,111,146, 27,168,117,250,128,241, 19,103, 45, 24, 60,176,171,221,237,219,183, 77, 61,122,244, +208, 94,191,126,253, 75, 0,155,205, 60,205,230, 70,141, 26,197,175, 93,187, 86,251, 50, 33,177, 94,116,236, 75, 72, 68,124,182, + 86,173, 90,194,152,152, 24,237,220,185,115, 11,215,173, 91,183, 25, 64,120, 13, 76,223,220,179,103,207,220, 57,115,230,100,190, +136, 79,116,123, 28,243,130, 74,133,124,131,139,139, 51,231,225,195,135,154, 31,126,248,193,180,108,217,178, 26,115, 14, 27, 54, + 44,109,250,244,233,137,242,108,133, 71,174, 34,159, 10, 84, 42,189,167,167, 39,247,202,149, 43, 5, 63,255,252,179,118,250,244, +233, 53,230,236,216,177, 99,250,226,197,139,147,227, 94, 38,184, 71, 69, 63,135, 84,200, 51,184,186, 58,115,162,162,162, 84,203, +150, 45,211,175, 88,177,194, 44, 78,137, 68,178,251,208,161, 67,220, 19, 39,138,156, 54,119,238,220, 97,188,189,189,173,202,142, + 81,107,180, 96, 8,144,149,149,101,213,170, 85,171,221, 0, 60, 43,227, 27, 49, 98, 68,122, 13,174, 3, 35,180, 43,204, 27,184, + 37,128,150, 8,171,241,227,199, 87, 86,155,107, 88, 96, 13, 68, 86,175, 94,189,102,159, 57,115,198,103,239,222,189,107,246,239, +223,175, 3, 0,145, 72,228,248,235,175,191, 46, 27, 52,104, 16, 6, 13, 26, 52, 23,192,223, 38,176, 88,202,234, 1, 64, 40, 18, + 10,227,226,226,136,191,191,127,149,133,144,245, 38,211,195,109,207,159, 55,253,151,191,127,179, 28,147,169, 62,191,103,207,130, + 41, 83,166,100, 41,149, 74, 36, 37, 37, 65,175,215, 99,228,200,145,156,142, 29, 59,186, 15, 26, 52,104, 61, 33,228, 19, 74,169, +190, 58, 59, 74,188, 77,121,121,121, 5, 37, 94,156,128,122,214,220,246,161, 70, 97,163,250, 6, 1,159, 99,228,127, 60,217, 68, + 46,110, 32,133,254, 94,184, 9, 0,124, 21,228,124,224, 79, 2,139, 16,178,162,111,223,190,131,142, 31, 63,110, 15, 0, 71,142, + 28,129, 74,165, 66,157, 58,117,192,231,243,193,227,241,192,227,241, 74,151,107,242,108, 34,132, 76,147, 74,165,189, 10, 10, 10, +142, 83, 74,215, 3,240,109,219,182, 45,188,189,189, 1,160, 77,241,152,225, 28, 14,231, 83,150,101,183, 82, 74,143, 87,193, 53, +169,111,223,190,221, 34, 34, 34,172, 75,236, 52, 24, 12,240,246,246, 6,159,207,135, 64, 32, 40,181,211,130,255,126,148,213, 34, +255,105, 91,254, 42, 74,203, 52, 20, 95, 80, 71, 0,160,148,225,112, 56, 12, 94, 39, 36, 25, 58,117,234, 50, 34, 57, 57, 89,218, +162, 69, 11,134,199,227,161, 48, 50, 18,154, 7, 15, 32,149, 74,209,191,127,127,222,245,235,215,109,108,164, 54, 99, 18, 95, 39, +230,115, 56, 12, 40,101,170,205,105,176,183,183,159, 56,107,214, 44, 87, 95, 95, 95, 24,141,198,210, 10,228, 70,163, 17, 41, 41, + 41,144, 74,165, 24, 62,124,184,179,149,149,213, 68,115, 46,130, 16, 82,215,207,219, 57,234,234,217, 45, 77,166,140,235, 37,241, +179,250, 13,146,148,175, 33, 61,242, 47, 4,164,157,199,140,126, 45, 36, 23, 55,206,109,236,227, 46,139, 34,132,212,173,233, 77, +210,104, 52, 55,163,163,163,199, 92,187,118,205, 4, 0, 87,174, 92,161,177,177,177, 99,255,202,175, 78,147,201, 4,133, 66, 1, +147,201,196, 41, 94, 47,121,255, 80,202,191,140,240,240,112, 78, 74, 74,202,216,128,128, 0,191,123,247,238,225,228,201,147,184, +116,233, 18, 46, 92,184, 0,129, 64, 80,123,224,192,129,114,121,182,194, 94,161,200, 19,189,123, 27,223,252,215,173, 91,221,211, + 18, 19,111,239,219,183,175, 0, 69, 97,195,106, 65, 8,249, 68, 42,149,138,215,172, 89, 83,104,109,231,218,187, 69,203,118,205, +120, 34, 27, 71,190, 80,234,148,151,167,212, 63,126,252, 56,110,229,202,149,126, 13, 26, 52,176, 47, 14,163,153,197,233,232,232, +104, 59,123,246,108,189,149,181, 83,187,102, 45, 90, 6, 11, 68, 54, 50,158,192, 74,214,166, 77,155,254,113,113,113,137,243,231, +207,247, 8, 13, 13,117,174, 9,167,151,151,151,245,244,233,211,181, 54,182,178,110,129, 1,129,141, 91,183,106, 62,184, 73,147, + 38,195,185, 92, 46,155,145,145,241,114,202,148, 41, 30, 29, 58,116,112,168, 9,167,189,189,189,245,226,197,139,117,245,188, 27, +124,242,241,199, 97,157, 68, 86,118, 50,129,216, 90,166, 86,171,217,216,216,216, 87,139, 22, 45,242, 8, 9, 9,113, 52,135, 83, +165, 82,241, 28, 29, 29, 17, 28, 28,140, 64,111,111,228,229,229, 33, 34, 34, 2, 59,119,238,196,246,237,219,113,224,192, 1, 52, +109,219, 29,214,214,214, 72, 75, 75,131, 82,169,228, 85,196, 83, 26,166,251,119, 96, 75, 0,221,100,154, 56,108,252,248,241,169, + 85,136, 43,140, 31, 63, 62,117,194,180,159,135,149,132, 16, 43, 3, 33,164,111,151, 46, 93,158,156, 61,123, 54,126,239,222,189, + 8, 12, 12, 68,143, 30, 61, 4, 0, 48,113,226, 68,193,160, 65,131,112,232,208, 33, 28, 57,114, 36,198,207,207,239, 22, 33,164, +175, 57,102, 14, 31, 62,188,109,120,120,248,141,240,240,240, 71,131, 7, 15,222, 58,118,236, 88,247,178,251,223,165,189,125,168, +211,233, 16,210,184,153,213,226, 95,238, 13,173,142, 47, 22,216,187, 53, 46,110,231,242,103,207,222,204, 13, 12,180,171,147,152, + 40,219,181,106,149, 99, 73,243,108,131,193,128,148,148, 20,216,219,219, 99,232,208,161,142, 66,161,176,218,176, 86,177,183,105, + 84,114,114,178,116,219,182,109,110,143, 30, 61,114,127,247,238,157,219,229, 75, 23,156,190,157, 58,209,218, 86, 42, 16,164,201, +139, 4,106, 98, 26, 36,113,175,209,150, 82,216,149, 13, 27,150,133,167,167,231,151,199,143, 31,119, 45, 89,183,183,183,127, 79, + 80,149, 95, 6, 67, 25, 89, 16,217, 81,183, 47,201,180, 11, 36,223, 84, 97,103,239,195,135, 15,175, 76, 76, 76,236, 16, 22, 22, +182,142, 16, 82,167,130, 49, 78,157, 58,117,218,246,252,249,243, 30,125,251,246, 61, 70, 8,233, 94, 25,159,167,167,103,255,227, +199,143, 59,148,172, 59, 58, 58, 66, 36, 18,253, 73, 92,241,249,124, 48,140,165,242,208,127, 59,202,106,145,255,118,148,126, 27, +105, 81,193,200,171, 0, 64, 9, 41,124, 18, 29,205,227, 8, 4,195,246,237,223, 47,228,243,249,120,243,230, 13, 98, 98, 98,160, +186,124, 25,234,219,183,145,145,145,129,130,130, 2,184,184,184, 96,203, 47,191, 72,116, 44, 29,253,252,197, 11, 14,101,254,200, + 39,160,149, 76,213, 20, 10,133, 93, 7, 12, 24, 80,169, 16, 75, 75, 75, 67,175, 94,189,120, 28, 14,231, 79,211, 67,203,115, 18, + 66,136,187, 19, 57,117,249,232, 98, 55, 55, 65, 12,240,106, 10,144, 31, 5, 80, 45, 96,212, 1,169, 79,129, 51, 11, 81,167, 32, +142, 92, 88, 60,194,213,195,138,123,138,148,251, 41, 86,153,157,101,206,225,237,239,239,191,125,216,176, 97, 12, 0,116,238,220, +153,248,251,251,111, 37,132,120, 87,118, 76,117,156, 42,149,234,110,110,110, 46, 6, 13, 26,228,224,227,227,115,105,208,160, 65, + 14, 37,219, 63,148,179, 24, 14, 65, 65, 65,217, 98,177,248, 0, 33,164,194, 7,107,101,156,201,201,201, 95,248,251,251,215,223, +182,109, 27,135,195,225, 96,219,182,109, 56,120,240, 32,110,222,188,137,236,236,108,233,148, 41, 83,108, 79, 95,186,123,254,214, +205,251, 39, 87,205,153,230,208,191, 75, 71,111,251, 60,185,210,195,195,163, 43,138,114,178,204,177,179,215, 87, 95,125,117,241, + 81,108,130, 51,135,199,231, 11,120, 92,177,147,163, 93, 29, 87, 39,251,250, 30, 14,246,245,173, 5, 60, 59,165, 82,249,250,208, +161, 67, 5, 40,202,207, 50,139,115,222,188,121,143,227, 18, 82, 28, 24, 30,151,203,231,242, 5,118,182, 82,135, 62, 97,221, 59, + 1,128,152, 67,132, 74,165, 50,101,247,238,221,133, 53,225,156, 59,119,238,157,119,242, 92,103,190, 72,196, 17, 10,121,165,247, +210,222, 70,234, 34, 17, 10,197, 42,149,234,205,246,237,219,243,106,194, 57,115,230,204, 7,207, 94,190,113, 36, 12, 56, 12, 8, +207,222,222,218,217,201,206,218,213,217, 70,234, 42, 98, 32, 82, 42,149, 73,187,119,239, 86,154,195,169,215,235,121,153,153,153, +136,139,139, 67,173,102,205,112,233,210, 37,212,174, 93, 27,131, 6, 13,194,167,159,126, 10,177, 88,140,206,173, 26, 98,214,172, + 89,136,143,143,135,209,104, 20,152,105,103, 41,220,221,221,175, 86,182,175, 36,143,170, 50,206, 64, 47, 82, 42,174,204,225,174, +104, 92,121,206, 94,189,122,205,190,124,249,178,207,158, 61,123,250, 12, 31, 62,252,230,158, 61,123,208,178,101, 75,196,198,198, +162, 94,189,122,216,181,107, 23, 62,253,244,211,155,235,215,175,239,243,251,239,191,135,120,121,121,205,170,142,115,240,224,193, + 19, 66, 67, 67, 35,211,211,211, 91,229,228,228, 4, 71, 68, 68,140,238,223,191,255,235, 33, 67,134,116, 41, 25,195, 26, 12,251, +207,156, 60,138,222,125, 6,160, 65, 80,240,230,145,179,246, 54,172,138,147, 82, 74,159, 1, 91,119,190,123, 39,223,175,209,168, + 6,241,120, 86, 86,247,238,201,142,108,218,228, 88, 18,182, 5,128,212,212, 84,124,252,241,199, 60, 62,159,223,174, 42, 59, 9, + 33, 43,250,245,235, 55, 40, 34, 34,162,212,219,116,251,246,109, 60,125,250, 20, 73, 73, 73, 80, 40, 20,232, 50,182, 0,227,151, + 21,113,143, 95, 70,209,125, 34,149, 84,197, 89, 80, 80,160, 62,118,236, 24,194,195,195,241,229,151, 95,194,203,203,171, 84,100, +149, 23, 87,215,238,255, 6, 65,112,142,172,237, 86,140,234,118, 2, 78, 18, 79,204,172,196, 78,126,215,174, 93,183,244,233,211, + 7, 44,203, 66,163,209,152, 0,228,148,183, 3, 0,167, 94,189,122,188, 90,181,106, 97,201,146, 37,176,179,179, 91, 75, 8,225, + 84,196, 89, 88, 88,168, 61,123,246, 44,134, 15, 31,142,175,191,254, 26,245,235,215, 47,181,115,247,222,131,142,159,142, 30,231, +215,164,109,251,144,192, 38, 45, 27,229,107, 57,205,248, 86,178, 47,202, 63,227, 43,250,140,254, 14, 88, 56,255,126,148,213, 34, +255,237, 40, 13, 17,150,109,121, 98, 48,225,212,176, 17,163, 63,190,116,249,178,149, 64, 32, 64, 98, 98, 34, 50, 50, 50,112,240, +192, 1,246,176,179,179,138,199,227,209,161, 59,119, 90,127,254,197, 23,132,199,227,193,223,223, 31, 3, 7, 14, 20,127, 50,104, + 72,166, 19,143,119,176,186,147, 18, 66,220, 74,226,231,163, 71,143,198,143, 63,254,248,222,254,111,191,253, 22, 7, 14, 28, 0, + 33,196,181,162,227,203, 33,124,210,194,126,158,246, 94,118, 25, 52,106, 55,143,112,172,100,224, 88, 1, 12, 31, 16,113,138, 68, + 22,195,129,246,247,200, 28,166,229, 33,229,128,118, 42,143,117,231,183,132, 3, 56,100,238, 77,114,119,119,159, 27, 25, 25,233, + 52,101,202, 20,170, 84, 42,201,187,119,239,232,210,165, 75,157, 38, 76,152, 48, 23,192, 8,115,121,202, 34, 45, 45,109,113,239, +222,189,123,156, 57,115,198,101,196,136, 17,182, 0,208,187,119,239,140,180,180,180,197, 31,194, 87, 2, 62,159,207,121,246,236, +153,108,205,154, 53,159, 78,157, 58, 53, 40, 56, 56,216, 85,161, 80, 36,165,166,166, 14,172,206,227,102, 50,153, 2,182,109,219, + 6, 14,167,232, 57,199, 48, 12, 4, 2, 1, 4, 2, 1,108,108,108,114, 19, 18, 18, 76,117, 93,196,130,194,140,119,121,246, 92, +123, 30,113,115,117,176,115,117,235,152,157,157,125, 15,128,173,153, 38,134,124,244,209, 71, 79,110, 63,122,197,142, 27,209,169, +190, 21,159,225, 89,139, 69, 28,177,128, 71, 8,165,172,222,160,107,181,113,247,149, 29,126,126,126,129, 48,211, 69, 76, 8, 9, +109,217,178,229,229, 71,177,111,240,232,105,252, 91, 39,153,149,195, 71,157,219, 52, 40,217,223,168,121,203, 79,203, 12, 87,152, +195,201,229,114, 67,154, 53,107,246, 54, 35,167, 16,206, 50,219,247,132,180,189,163,115, 87, 0, 40,204,203,219, 88,171, 86, 45, +127, 46,151, 91, 89, 51,204, 63,217,217,174, 93,187,119,191,199, 36,195,213, 73, 38, 43,222,252, 94, 78, 79,214,187,119,155,125, +125,125,253,205,241,180,234,116, 58,225,241,227,199,241,251,239,191, 99,113, 80, 16,190,173, 91, 23, 78, 78, 78,184,124,249, 50, + 40,165,144, 74,165, 80, 40, 20, 56,116,232, 16,186,116,233, 2,157, 78,247,167,127,184, 64, 73, 14, 86,229,231,113,119,119,191, +154,150,150,246,111,249, 69, 89,158, 59,112, 69, 28, 98,170,232,148,121,246,236,217,189,123,247,238, 93, 22, 24, 24,136,111,190, +249,166,237,218,181,107,111, 6, 7, 7,183,237,220,185, 51, 34, 35, 35, 49,122,244,232,155,235,215,175,111, 59,110,220, 56,108, +222,188, 25,175, 95,191,254,165,170,243, 15, 30, 60,120,193,152, 49, 99,230,108,216,176,161,200, 75, 3,160, 95,191,126, 64,209, +179,113, 71,120,120,120,118,201,216,195,219,223,222,246,242,246,109, 61, 97,210, 52,193,196,113,195,103, 0,248,180, 66,210, 98, + 80, 74,169,187,187,123,190,177,125,251,156, 67,119,238, 96, 48,159,111,181,255,209, 35,156,210,104,208,174,127,255, 44, 0,152, + 57,115, 38,246,236,217, 3, 0, 46, 85,113,121,122,122,126,121,236,216,177,210,239,138,131,131, 3, 4, 2, 65,145, 8,226,242, +192, 97, 57,184,180, 89,130,132,100, 21,198, 47,163,216, 52,147,160,158, 59, 10, 67, 27, 84,206, 73, 8, 65,155, 54,109,160, 84, + 42,193,225,112, 96,109,109, 13,153, 76,246,158,184, 82, 22, 40,176,242,151, 5,200,108,112, 21,221, 78,130, 33, 28,224,241,247, + 64,254,171, 74, 91, 58,125,188,102,205, 26, 55,141, 70,131, 43, 87,174,224,242,229,203, 63, 81, 74, 11,202,235, 29, 74,105, 58, +135,195,217,185, 98,197,138,209,238,238,238, 24, 63,126,188,223,210,165, 75,251, 1,127,230, 37,132,160,105,211,166,208,104, 52, +224,241,120,176,177,177,129, 78,111,228,133, 15,251,210,187,142, 79,176,112,233,170,165,140,139,140, 11, 46, 35,195,203, 55,106, +219,117, 63, 46, 89,119,247,198,245,207,137,149, 99,127,170,202,122, 87,213,125,181,224,255, 30, 72, 53,237,215,254,155,192, 5, +254,220,238, 36, 57, 57, 89, 33,147,201, 60, 26, 52,104,192,232,116,186,162,208,195,145, 35,236,246, 29, 59,206,104, 52,154, 73, + 0,248, 27,126,254,121,179,135,167,103,167, 97,195,135, 19,131,193,128,222,189,123, 11, 78,159, 62,237, 16,159,145, 81,109,163, +226,242,191, 46, 70,142, 28,137,181,107,215, 2, 0,190,250,234, 43, 0, 69, 46,244,138,126,133,148,135,212, 22,189,122,132, 53, +181, 73,145,252,100,163,111,109, 40,168, 27,111,125, 87, 82, 32,110, 10, 70,192,133,136, 3,147,222, 96,124,153,217,255, 97,252, +203,128, 64,113, 78,118,189,174, 65, 29,176,253,183, 61,189, 80, 3,129,101,101,101,213,220,218,218, 26, 15, 31, 62,204,105,218, +180,169,130, 82,106,187,120,241, 98, 71, 43, 43,171,230,230,114,148, 7,165, 52,145, 16,210,190, 77,155, 54, 19, 25,134,233,106, + 50,153, 46,101,100,100,108,160,148, 38,154,115, 60, 33,100, 60,128,249, 40,147,103,162,211,233,192, 48, 12, 40,165, 24, 60,120, + 48,102,206,156, 25,248,244,233, 83, 68, 70, 70,202,186,118,237,122,151, 16,162, 0,240, 57,165,180, 82, 47, 89,118,118, 54, 54, +109,218, 4, 14,135, 3, 59, 59, 59, 88, 91, 91, 67, 36, 18,161,109,219,182,233,203,151, 47, 15, 56,122,244,168, 74,145,153, 73, +196,249,121, 90,226,224, 32,130,123,237,143, 70,246, 31, 16,141,162,217,132,102, 65, 34,145, 88, 9,160,205,103, 88, 13,179,114, +193, 70,174, 21,159, 79, 68,124, 46,132, 38, 21,103,214,242, 37, 84, 68, 40, 15, 69,222, 85,179, 26,126, 3,128, 72, 36,226, 75, + 4, 84,203, 19, 50, 6, 43,166,230, 51, 26, 43,130, 64, 32,224, 11,121,133,234,202,246,243, 25,194,225,112, 56,213,122, 9,203, + 66, 44, 22,243,165, 2, 86, 91,217,126, 17, 3, 14,195, 48,149,114,134, 7, 17,122,120, 98,105, 72,175,212, 54,163,209,136,230, +205,155,227,215, 19, 87,112,246,242,109,100,189,121,130, 73,227, 71,195,215,215, 23, 23, 46, 92,168,137,137,127, 66, 90, 90, 90, +133, 34,171,202,208, 98,113,222, 85, 85, 97,193,247,184,231,217, 86, 59, 43,145, 16,210,183, 93,187,118, 19,246,239,223,175,251, +232,163,143, 4,131, 7, 15, 70,112,112,112,219, 81,163, 70, 1, 0,186,118,237,138,181,107,215,182, 29, 53,106, 20, 14, 30, 60, +136,136,136, 8,109,199,142, 29,167, 19, 66, 82, 41,165,103, 43,226, 52,153, 76, 31,111,217,178,229,189,109,122,189, 30, 70,163, + 17, 6,131,193,205,104, 52,186, 21, 63,139,176,110,221,250,172,139, 23, 78, 99,250,172,133,112,118,114, 13,173,234,186, 74,192, +225,112,200,200,105,211,178,118,173, 90,133, 85, 7, 15, 98, 90,189,122, 86,123, 98, 98,112, 81,163,193,161,200,200,172,226,243, + 84,155,223, 84, 88, 88,168, 62,123,246,172,205,161, 67,135, 96,103,103,135,250,245,235,151,138, 33,134, 35, 6,135,111,143, 6, + 65,205, 1,220, 7, 0,212,115, 71,161,191, 23,110, 18, 2, 5,101, 80,233,247, 77, 44, 22,195,213,213, 21, 92, 46, 23,143,158, +223,135,181,194, 6, 77,130, 90,128,199,227, 33,191, 48, 15, 19, 86, 13,132,239, 18, 57, 26,250, 3,234, 12,224,222, 20, 24,210, +111, 99,141, 42, 5, 27, 43,161,108, 92,187,118,109,104,181, 90,108,219,182,141,162,232, 25, 85, 33, 76, 38,211,236,213,171, 87, +143,152, 55,111, 30,167, 89,179,102, 0, 16,138, 10, 4, 22, 0, 72, 36, 18,120,120,120,148, 10,191,193, 35,198,121,143,157, 50, + 78,220,191,123, 39,112,185,142, 80, 20, 26,144,157,111,128,189,163, 20,211,167,132,139, 46, 53,245,104,182,101,253,190,147,132, +144,102,180,172,203,208,130,255,211, 40,175, 69,254,219, 81,105,153, 6,161,193,208, 64,187,121, 51, 10, 47, 93,130,224,226, 69, + 28,114,119, 47,208,104, 52, 83, 41,165, 41, 0, 64, 8,249,102,231,174, 93,183,250,220,185, 99,163,139,139,131,247,211,167,224, +217,217,153,245,208, 41,139, 29, 59,118, 64,169, 84, 34, 47, 47, 15, 0,240,211, 79, 63, 65,169, 84,162, 36, 87,161,218, 11,224, +163,173,171,115, 61,164,227, 37, 76, 92, 70,154,212, 64,213, 82,170,177, 78,243, 72,118, 41,204, 99, 60, 16,247,166,133, 68,157, +173,107, 73, 56, 58,104,178, 84,240,104, 83, 31, 92,112,219,214,196,198,146,184, 62,151,203,205,121,241,226,197,199,126,126,126, +167, 0, 56,254,213,120, 63,165,244, 21,128, 73, 31,114, 44,135,195,153,255,250,245,107,231, 95,126,249,101,226,226,197,139, 41, +240,135,192, 42, 89,230,114,185,160,148,194,214,214, 22, 60, 30,207,229,246,237,219, 46, 45, 90,180,216,136,162, 7, 89,133,176, +178,178,130,139,139, 11,120, 60, 30,108,109,109, 81,168,204,149,108, 90, 58,167,163,149,189,139,108,218,180,105,204,200,145, 35, +227, 55,110,220, 88,219,181, 65, 3,255, 39, 79,158,188,233, 51, 48,252,247,179,103,207, 2,192, 86, 51, 77,127,252,244,233, 83, +129,175, 79, 93,174,201,160, 54, 73,248,128,232,241, 58,147,192,218, 21, 34, 14, 7, 92, 2, 42,182,146, 56,191, 74, 74, 74, 3, +144,105, 14, 33,165,244,209,203,151, 47,121,158,238, 46,220,252, 66,141, 66,194, 53, 9, 94, 63,184, 31,235,213,172,121, 0, 0, +104, 30,220, 62, 38,108, 16,100,253, 58, 83,110,227,237,237,157,100, 14,167,209,104,124,156,152,152,200,247,240,240,224,189,124, +249,106,159,131,141,181,187,204,197,165, 35, 0,232,114,228,215,137, 90,147,198,227,241, 60,210,210,211,229, 70,163, 49,205, 92, + 59, 95,188,120,193,247,116,119,225,158, 58,115,246, 87, 87,137,149,155,157, 88,104, 43, 98, 64, 68,212,148, 39, 48, 26,211,197, + 86, 18,247,215,201,201, 89,148,210,183,149,241,108, 50, 77, 28, 6, 0, 28,206,180,237,101,183,223,188,121, 19, 87, 30,190,134, + 45,135, 5,207, 80,136,187, 17,135, 48,224,171,201,213,254, 45,197,124,231, 15,104, 87, 28, 8,244, 26,249,199, 58, 74, 66,128, +110, 0,254, 44,132,202,142,251, 32,108, 9, 40, 13, 1, 20,115, 35, 45,173,234,135,235,208,161, 67, 23,238,221,187,183,116, 18, + 71,108,108, 44, 58,119,238, 12, 0, 88,184,112, 33,122,244,232,129, 22, 45, 90, 32, 54, 54, 22,190,190,190,136,140,140, 20,114, + 56, 28,225,176, 97,195,150, 2,168, 80, 96,149,197,214,173, 91, 49,122,244,232,138, 18,166,227, 1,104,136,189,127,193,204,229, +187, 29,115,178,179,144, 41, 79,127,100,238,165, 18, 66, 48,114,218,180,172, 45, 58, 29,246,223,187,135,225, 18,137,213,174, 87, +175,208,187, 69, 11, 52,236,220, 57,203,156,103, 93, 69, 94, 28, 7, 7, 7,240,249,124,112,120,238,224, 10, 66,192,240,249,104, +220, 46, 4,171,166, 74, 84, 35,122, 98, 61, 33, 80, 8, 5,136,226, 91,161,194,201, 11,132, 16, 24,141, 70,240,120, 60, 28, 58, +191, 11, 79,236,246, 1,249,192,173,168,190,152, 60,122, 54,190, 91,251, 37,252,150,202, 97,235, 7,100,222, 5,238, 79, 97, 76, +121,137,166, 49, 90, 57,206, 81, 74,179, 43,226, 20,139,197, 1, 98,177, 24,133,133,133,120,249,242,229, 27, 74,169,178,178,107, +162,148,102,116,237,218, 53,147,195,225,184,121,120,120, 0, 64,237, 74,236, 36, 38,147,169, 52,207,106,207,254,195,142,161,237, +189, 69,221,218, 6, 98,247,169,239,241,175,240,245,224,113, 8, 88, 86,143, 53,107,195,192,106, 11, 16,222,231, 75,210,161,171, +111,200,165, 83,186, 49, 0,182, 85,123,131, 45,176,224,223, 0, 6, 0, 8, 33, 29, 8, 33,148, 16,210,161,100,135,137, 82,147, + 49, 39, 7, 84, 91,244,227,135,199,227, 81, 0,101,103, 40, 89,217,217,217, 17,158,167, 39,136,176,232, 7, 55, 5,254,182,162, +123, 6,131,121,165, 97, 76, 44, 56, 32,122,208, 50,206,142, 66, 17,193,247,142, 93, 48, 73, 48, 23,233, 2,187, 63, 6, 83, 10, + 24, 41, 88,152,204, 42, 46, 88, 6,180,160,160, 0, 70,163,209,222,199,199,231,140,209,104,180, 47,162,251,207,253, 50, 98, 89, + 54,129,195,225, 96,226,196,137, 64,113, 40, 77,167,211, 33, 61, 61, 29, 90,173, 22, 58,157, 14,175, 95,191, 70, 94, 94, 30,116, + 58, 29,158, 61,123, 6, 47, 47, 47,112, 56, 28,183,170,120, 77, 38, 19,156,156,156,224,230,230, 6,109,161, 82,114,116,235,218, +222, 43, 22,206,116, 28,226, 67,153, 95,214,175, 54,121,122,122,102, 7, 5, 5,185, 10,133, 66,125,147, 38, 77,180,167, 78,157, +186, 8, 96, 64, 13,234, 96,157, 93,180,104, 81,139, 22, 45, 90,212,181,147, 74,244, 66, 1, 7, 66, 99, 33, 21,106,179, 41, 87, +157, 69,235,120,214,213, 67, 34,109, 62,120,240, 96, 1,204,248,167, 88,194,249,221,119,223,213, 15, 8, 8,112,180,179,145, 40, +185, 12, 82,249, 44,155,154,251,240,246,111, 0,192,119,116, 86, 67, 34,109, 94,156, 67,103, 54,231,244,233,211,131, 60, 60, 60, + 28, 24,134, 40,140,122,253,155,146, 29, 68,163,206,224, 8, 69,133, 16,138,218,125,254,249,231,188, 26,114, 6, 52,106,212,200, +193,222,214, 70,193, 99, 72, 50,159, 53,166,136, 41,251, 86, 96,208,203,133,206, 46, 5,144, 72,219, 12, 25, 50,132, 91, 25,103, +137,247,170,188,103,136,203,229, 34, 53, 53, 21,170,180, 39,224,167,198, 33, 68,202, 79, 61,231, 46, 0, 0, 32, 0, 73, 68, 65, + 84, 67, 75, 87, 71, 72, 36,146,234,127,172,140,141, 37, 24, 27, 75, 98, 94, 83, 18,243,154,146,178,235,101,135,165,165,165,193, +125, 81, 30,222, 27, 87, 9,202,231,103,189,135, 45, 1, 87,203, 31, 91, 44,178,170,252,123,218,183,111,223,172, 78,157, 58,101, +246,232,209, 67,119,230,204, 25, 16, 66, 16, 25, 25,137,212,212, 84,244,232,209, 3,148, 82,220,189, 91,228,156,125,244,232, 17, +186,118,237,170,107,223,190,125,234,190,125,251, 42,245,162,148,197,232,209,163, 97, 48, 24, 80, 80, 80,128,156,156, 28,156, 62, +125, 26, 33, 33, 33,212,202,202,106, 0,167, 86,247,239,195,199,204,106, 29,220, 40, 20, 27,215,175,210, 9,184,188,229,230,112, +150,128, 16,130, 17, 83,167,102,229, 53,110,156,179,167,176, 80, 53,210,198,198,202, 39, 37, 69,246,240,194, 5, 71,189,190,218, +201,131, 0,254,240,226,120,122,122,150,138, 43, 62,159, 15,174,192, 9, 28, 73, 67, 8, 28,122,192,202,117, 0,174, 68, 9,181, +182, 18, 28,179,150,226,188,196, 14,149,150,104, 0, 64,140, 70, 35,248,124, 62,174,254,126, 14, 33,179,129,144,217, 64, 90,243, + 19,248,116,242, 71,112,156,244, 2,182,126, 64,250, 13, 64,177, 42, 4,134,215,182, 74,173, 28,135, 42, 19, 87, 0,160,213,106, + 53, 44,203,130, 16, 2, 62,159, 47, 40,179,235,214,213,171, 87,113,249,242,101, 0,120, 89,178, 49, 55, 55,151, 50, 12, 3,137, + 68, 2, 0, 21,134,176, 1,128,101,217,210,124,176,171,119,175, 59,124,250, 73, 24,185,253,248, 55,180, 9, 25,130,236, 2, 61, + 50,242,244, 80,168,128,160,102,115, 16,220,245, 24,158,188,206, 71,104,163, 96, 14, 71, 32,249,160, 20, 14, 11,254, 51,168, 72, +139,252, 55,163,196, 5,115,181,124, 98,153, 81, 40,124,102,156, 48, 1,118, 39, 79,130,247,242, 37, 70,141, 24, 97, 99,101,101, +181,158, 16,210,132, 16,210, 70, 42,149,110, 92,176, 96,129,181,227,178,101,112,191,126, 29, 73,167, 79,195,192,227, 61,248, 16, + 35,212,106, 53,184,220, 34,103,154, 78,167,131, 68, 34, 1,203,178,128, 25, 33, 34,214,136, 59,169, 25,113, 16,160, 46, 76,160, + 5,231,149,237,239, 13, 73,152,227,124, 90,233,229,251,170,144,239,187,200,169,165,243,250, 58,109,239, 21, 18,110,129,192, 78, +132,228,228, 20,176, 48,221,169,137,125, 26,141, 38,175,176,176, 16,161,161,161, 14, 15, 31, 62,244, 9, 9, 9,145, 21,111,191, +255, 1,151, 91, 10, 66, 72, 43, 15, 15,143,195,158,158,158,137, 30, 30, 30,135, 9, 33,173,106,112,248, 47, 55,110,220, 0,135, +195,193,130, 5, 11,144,159,159, 15,189, 94,143,236,236,108, 36, 39, 39, 67,167,211,225,237,219,183,120,254,252, 57,116, 58, 29, +146,146,146,160,213, 86, 26, 41, 40,133,193, 96,128,181,181, 53, 20,217,153,146,131,155, 86,247,254,126,225, 92,113,222,171,223, +241, 54, 45, 3, 38, 86,157,182,114,229,202,231,190,190,190,151,245,122,125, 45,147,201,212,129, 82,186,197, 92,161, 73,138, 10, +149,222,244,247,247,111,177,114,229,202, 14,115,151,111, 23, 90,115,242,169,192, 90,104, 18, 88, 11,168,192,191, 37,198,204,223, + 32, 90,190,116,241,163,199,143, 31,231,152, 83,116,179,132,179,101,203,150, 65,233,233,233,109, 67, 66, 66, 66, 93,235,251,137, +132, 30,238, 89, 2,247, 58,217, 84,173,186,196,212,174,247,241,250,245,235, 31,222,189,123, 55,163, 38,156, 30, 30, 30, 13,127, +254,249,231,102,181,107,215,110, 38,178,181, 21, 23, 40, 20, 91,181,138,156,237, 60, 71, 87, 49,227,224, 24,190,103,207,158, 59, + 23, 47, 94,204,170, 9,103, 96, 96, 96,240,210,165, 75,155, 52,110,220,184,137,155, 95, 3,145,216,195, 83,206,247,168,147, 41, +110,212, 84,196,212,241, 30,184,118,237,218,123, 15, 30, 60,144,155,195,201,229,114, 89,134, 97,192,227,241, 32,145, 72,112,237, +218, 53, 12, 25,240, 17, 92,157,109,224,215,160, 1, 58,142,253, 10,103,206,156,129, 64, 32, 0,195, 48, 96, 24,230, 47, 23,180, + 52, 71, 8, 85,135,202,196, 87,117,220,148,210,179, 87,175, 94,253, 97,228,200,145,130, 94,189,122,225,222,189,123, 24, 61,122, +244,205,136,136, 8, 0,192,189,123,247, 48,121,242,228,155,151, 47, 95,198,184,113,227,208,185,115,103,193,141, 27, 55, 54,154, + 83,124,212,104, 52, 98,199,142, 29, 48, 26,141,144, 74,165,144,201,100, 8, 11, 11, 67,116,116,244,184,157, 59,119,198,113,120, +188,207,122,247,249, 4,103, 78, 70,224,249,179,232,113,187,150, 14,171,113, 49, 95,134, 97,208,107,196,136,172,172,160,160,156, + 93, 74,165,234,115,123,123, 43,255,244,116,217,149,195,135, 29,171, 59,150, 16, 66, 88,150, 45, 21, 85, 37, 98,163,228,197, 21, + 56,129, 43, 9, 6,215,186, 25,158,188,226, 27,120,205,105, 20,191, 41,141,173,170,200, 40, 33, 4, 38,147, 9, 60, 30, 15,141, +235,183,249,127,236,157,119,120, 20, 85,219,198,239, 51,179,125, 55,187, 73, 54,189, 64, 18, 2, 73,232,129, 64, 66, 47,130,130, + 4,165, 72,121,177,208,148, 34, 42,168,136, 8, 72,111, 2,175, 32, 82, 4, 1, 1,145,106, 69,122,145, 72, 7, 65,145, 94, 19, + 72,111,155,182, 73,182,206,156,239,143,100,215, 37,108,146,221, 0, 2,239,183,191,235,154,107,203, 76,238, 61, 51,217,157,185, +231, 57,231, 60, 15,110,126, 91,246,126,189,215,129,152, 13,185,240,109, 83,214, 45,120,119,161, 47, 62, 26, 62, 3, 66, 86,100, +170, 46,109, 14,207,243,151,114,115,115, 33, 16, 8, 16, 25, 25,233, 79, 8,177, 68,165, 62,239,220,185,243,204, 55,222,120, 99, + 1,128,113,229,159, 31,210,191,127,255, 64,163,209,136, 63,255,252, 19, 0,206, 85,166, 75, 41,181,206, 26,212, 20, 38, 73,194, + 2,155, 32,186,193, 72,120,122, 54, 69,170,198,128, 52,141, 1,107, 86,246,198,185,163,179,241,199,254, 55,112, 55, 35, 3, 50, +255, 62,224,204,250,198,213, 29, 91, 23, 79, 21, 15,120,145,103,153,138,105, 26, 0, 0,117,213,106,165,201,100, 76, 57,112,224, +128,145, 97, 24,200,229,114, 12, 25, 54,140, 89,185, 98, 69,251, 65,173, 91, 31, 30,241,252,243,123, 14, 31, 58,212, 60, 46, 46, + 14,148, 82, 48, 12,131,173, 91,183,150,234,116,165,185,181,107,215,246,176,255, 81,255, 96, 59,182,138, 82,138,194,194, 66,171, +193, 42, 40, 40,128,159,159,159,195, 93,132,197,133, 56,120,104,239,185, 60,202,189,125,175,199,205,197,198,249, 25,189,227,242, +121, 78, 80,192,153, 80, 80, 74, 81,164,131,224, 52,163,142, 27, 18,209,199,120,167,107,220,181,132,171, 39,114,117,156,206,169, +217, 15, 89, 89, 89,147,251,247,239,159, 27, 16, 16, 64, 84, 42, 21,130,130,130,152, 94,189,122,229, 36, 39, 39,207,116, 70,199, + 22,111,111,239,255,116,238,220,121,103,106,106,106,191,132,132,132,208,223,127,255,189, 95,231,206,157,119,122,123,123, 87, 57, +112,214,134,109,147, 38, 77, 42, 22,139,197,104,213,170, 21,138,138,138, 96, 48, 24,170, 93,170,131,231,121, 72,165, 82,108, 95, +179,228,133, 57, 51, 62,149,229, 94, 57,137, 11,199, 14, 96,111,162,190,100,218,252, 47, 78, 73,165,210, 26,237,111,132,175,162, + 73,147, 64,229,149,247,135, 13, 76,251,100,226, 68,229,223,127,255, 45,123,111,236, 56, 36,101,230, 83,113,143,207, 89,116,252, +148,249,171,216,155,196,191,248, 28, 62,155, 59,181, 35,128, 81,213,105, 54,244, 85, 52,105, 28,168,188, 60,126,196,160,219, 99, +199,142,149,205,159, 63, 95, 23, 27, 27,107, 74, 79, 79,119,119,243,246,109, 33,244,242,110,157,152,145,233,209,162,101,203,155, + 99,199,142,213, 57,171, 57,117,234, 84,249,241,227,199, 69, 93,186,116,161, 89, 89, 89,158, 34,153,172,141, 80,233,222, 49, 45, + 39, 71,221,181,107,215,155, 67,135, 14,229,106,162,121,253,250,117, 81,139, 22, 45,104,122,122,186,167,220,203,167,149,200,203, +167,195,157,244, 12,207,102,205,155,223,120,255,253,247, 77, 85,105,246, 95,246,143, 57,113,115,115, 75,143,142,142,198,180,105, +211, 48,107,214, 44, 12, 24, 48, 0,137, 73,137,232, 56,116, 4,234, 12, 25,133, 95, 79,157, 65, 90, 90, 26, 38, 79,158,140,136, +136, 8, 8,133,194, 27,149,233, 58,131, 35, 38,171,178,238,195,134,117,200,145,170,198, 89, 85,167,221,175, 95,191, 49,150, 84, + 12,195,135, 15, 63,182,116,233,210,118,195,135, 15, 7, 0,180,106,213, 10,179,103,207,110, 55,101,202,148, 99,115,230,204, 65, +151, 46, 93, 16, 30, 30, 94,109, 62, 49,142,227, 96, 54,155, 49,104,208, 32,152,205,102,100,103,103,227,250,245,235, 88,189,122, + 53, 40,165, 82, 0, 8, 8, 12,110, 33, 22,139,241,215,249,179, 37,159, 14,143,219, 84,157,166, 5,219,115, 29,207,243,208,106, +181,232, 55,122,116, 78, 74,189,122,154,175,114,114, 74,222,244,244,148,135,221,189,171, 86, 26, 12, 65, 85,141, 57,181, 53, 67, +182,105, 9, 42, 46,150, 9, 42,142, 98,209, 28, 53,232,125, 72,247,182,183,154, 44,183, 16,128, 55, 3,231, 38, 10,241, 78,159, +105,136,110,210, 12, 12,195, 56, 98,172, 79,157, 62,125, 26, 98,177, 24,239,191,255, 62, 97, 89,118, 9, 33,132, 80, 74,243, 40, +165,211, 40,165, 31, 83, 74,117,132, 16, 34,145, 72, 86, 13, 27, 54, 12,122,189, 30,199,142, 29, 3,128, 67,246, 4, 45,227, 74, + 45,251,174,213, 16,112,188, 24,199,207,239,197,254,223,119, 32, 49, 53, 27,119,179,116,128,192, 29,186,226, 20, 24, 75, 83, 97, +200, 63,143, 66,189,220,158,156,139,167, 28, 91, 47,242,172, 99, 47,209, 40,168, 74, 54,112,199,242,149,238,253, 7,189, 94, 28, + 29, 29,237, 25, 20, 20, 4, 66, 8,122,247,233, 67, 58, 39, 36, 40,133,129,129,240,138,137,177,102,207, 61,120,224, 0,246,238, +221, 91,188,235,167, 31,131,134,189,249,230, 75,176, 77,246, 92, 1, 66,136,160,110,221,186,214,207, 77, 79, 79,135, 68, 34,177, +142,121, 40, 44, 44,132,143,143, 15,210,211,211,225, 96, 96,100,227, 39, 19, 79, 77,204,138,155, 92, 39, 78, 41, 36,123,138, 51, +192, 81, 10, 33,225,128, 82, 10, 19, 7,232, 77, 20, 45,194, 88,245,254, 82,179,231,175,167,127,184, 3, 96,163, 51, 7, 73,167, +211,253, 70, 8, 25,201,243,252, 14, 0, 76, 66, 66, 2,127,249,242,229, 49,142, 14, 72,183,135, 92, 46,159,112,248,240, 97,245, +132, 9, 19,242,126,253,245,215,130,158, 61,123,186,175, 94,189, 90,253,220,115,207, 77, 0,176,165,186,191,167,148,150, 18, 66, + 54, 36, 39, 39,143,105,217,178, 37, 52, 26, 13,140, 70, 35,206,157, 59,135,136,136, 8,252,241,199, 31,136,140,140,196,217,179, +103, 17, 21, 21,101,153, 50, 13,158,231,171,237,198, 77, 75,190,235, 38,215,231,169,210, 78,239,198,181, 11,127, 96,247,109,125, +201,194,117, 91,119, 55,105,214,162,216,217, 19, 56, 0, 68,249, 41, 26, 5,249,122,237,159, 63, 99,170,111,210,111, 91,241,195, +186,101,252,145, 61,123, 26,138,149, 24,217,233, 63, 99, 95, 49,152, 80, 27,128,164, 77, 92, 75,250,162,199,117, 94, 22,138,140, + 67,151,170,206,100, 30,229,167,104, 20,232,227,181,111,225,252, 89,202, 91,123,190,193,182, 85,159,211,239,191,221, 28,173, 3, +226,154, 52,105,210,131, 16, 18, 0,192, 92,254, 63,114,168, 4,141, 61,205, 67,191,254,218, 92, 7,196,213,173, 91,183,135, 80, + 40, 12, 5, 0,147,201,148,250, 40, 52,155, 54,109,218,163,252, 14,159,150,143,185,114,170, 84,206,240,225,195, 23,141, 31, 63, +254,125,147,201,100,205, 17,100, 50,153,216,213,171, 87, 11, 56,142, 99, 40,165, 70,134, 97,140,251,246,237,227,204,102,115,154, + 78,167, 27,237,168,118,101,188,242,202, 43, 56,117,234,212, 12, 84, 49,120,217, 22,141, 70, 35, 80,171,213,214,187,165,170,198, +109, 57,162,157,144,144, 48,235,213, 87, 95,253,100,203,150, 45,215,151, 46, 93,250,242,168, 81,163,176,117,235, 86,212,171, 87, + 15,127,253,245, 23, 38, 79,158, 12, 0,237,166, 76,153,242,203,218,181,107,195,147,146,146, 22, 85,215, 70,147,201, 4,179,217, +140,205,155, 55,163,119,239,222,240,241,241, 65, 96, 96, 32, 8, 33,191,189,249,230,155, 43, 0,128, 37,172, 8, 0,244, 58,189, +190,126,253,150, 14, 71,108,195,195,195,173,231,186,140,140, 12,235,204,191, 23, 94,125, 53,103,205,252,249,216, 84, 90,138, 55, + 61, 61,229, 41,193,193, 1,191,220,186, 53,130, 16,178,186,178,136,176, 37,138, 83,157,185,114, 34,162, 12,203,216, 38, 63, 63, + 63, 76,121,103, 30,230,173,156,130,155, 56,130,122,175, 1,151, 22, 3,189,195,223, 69,203,232, 86, 8, 12, 12,172, 94,176,140, +223,222,126,251,237,179,151, 47, 95,110,217,180,105, 83,204,156, 57,179,215,244,233,211,247, 19, 66, 70, 88,102, 49, 19, 66,194, + 88,150, 93,114,224,192,129,231, 85, 42, 21,174, 92,185,130,237,219,183,223,132,101,132,190,157,118, 2,176,230,188,170, 93, 43, + 82,119, 45, 73, 43,207, 74, 61,142, 99, 71,127, 66,189,232,113,144,249,191, 4,117,253, 57, 48, 94,253, 2,134,220,253, 80,215, +234,137,148,164, 91, 96, 5,146,139,142, 54,220,197,211,129,173, 23,121,214,177, 59, 74,155,240, 68, 24, 21, 25,201,137, 24,124, +211,251,165,151, 74,254,252,243, 79,235, 93,158,238,204, 25, 20,239,221, 11,142,227, 64, 41,197,239, 9, 9,120,227,245,215,181, + 66,150,172, 9, 11, 11,165,132,254,147,123,133, 16,242, 64, 30, 43,145, 72,212,191,127,255,254,214,147, 78,114,114, 50, 20, 10, + 5,196, 98, 49,120,158,135,217,108, 6,203,178,112,119,119,135,217,108,126, 32,228, 82, 81,147, 82,106,226, 52,197,253,214,198, +191,150, 30,168, 53,210,145, 30, 97, 8, 17,201,172, 63, 74,127, 21,193,203,209, 66,120, 11,178,232,161, 69,207,167,241,250,220, +126,180, 66,237, 47,123,237,172,176, 62,178,105,211,166, 43,222,120,227, 13, 6, 0,186,118,237,202, 52,109,218,244, 75, 66, 72, +165, 37,109,170,211,148, 74,165, 18, 0,216,185,115,167,230,250,245,235,221,119,238,220,169,177,125,223, 65,205,213, 11, 22, 44, +128, 92, 46,135,217,108,134,193, 96,176,142,191,178,125, 52, 26,141,240,246,246,198,174, 93,187,192,113,220,174,234,218,217,160, +113, 83,109,129,192, 35,115,253, 47,135,176, 39,201,168,117,214, 92,217,106,214, 11,112,139,242,247,246, 58,176,112,238, 44,159, +188,155,231,144,146,146, 66,247,237,221,117,178,148,210,212,252, 66,250,105,158,150, 70,149,232,169, 44, 54, 28,247, 14,172,250, +152, 78,233, 0, 19,200,131, 93,195,182,154,141, 2,220,162,130,124,188,246,125,190,104,190, 50,255,198, 31, 72,207,200,192,238, + 93, 59,255, 44,165, 52,149, 82,250, 61,165,116, 40,207,243, 77,120,158,111, 66, 41, 29, 90,153,105,113, 86,211,104, 52, 54, 49, + 26,141,143, 84,211,217,118,218,204, 32,196,140, 25, 51,110,164,164,164,140,202,204,204,124,197,178,104, 52,154,222, 69, 69, 69, + 61, 75, 74, 74,122,148, 46, 14,117, 47, 46, 46,246, 45, 42, 42, 10, 40, 45, 45,109, 65, 41, 61,103, 79,211, 17,108, 47,176,105, +105,105,211,211,210,210, 30,136,182,220,167, 57,242, 10, 89,190,232,237,111,183,111,223, 94,101,250,129,234,180, 43,182, 51, 59, + 59,123,199,230,205,155,155,213,169, 83, 39,124,232,208,161,248,234,171,175,176,116,233, 82, 61, 0,172, 93,187, 86,111, 19,185, +170,149,152,152,216,210, 94,247,160,173, 38,195, 48, 27, 95,120,225, 5,250,251,239,191,163,119,239,222,214, 4,160, 95,127,253, + 53,204,102,115, 97,151, 46, 93,120, 0, 40,213,149, 20, 82,158,194, 96,180,223,207,110,239,120,138,197,226, 23,109,243,253, 89, +146, 40,139,197, 98, 80, 74, 17,213,174, 93, 78,126,116,180,102, 93, 65, 65,201,244, 38, 77, 84, 35,234,215, 31,218, 0,120,221, +158, 38, 33,228,190, 40, 78,197,165, 38,191, 77, 11, 22,141,224,224, 96,204,250,240,115, 4,159,121, 5,191,181,247, 66,179,220, +161,232,214,254,101, 68, 69, 85,145,235,161,130, 38,165,148,102,101,101,141,154, 58,117, 42, 47, 22,139,241,214, 91,111,225,135, + 31,126,232,218,179,103,207,164,160,160,160,164, 70,141, 26,101,140, 25, 51,230,118, 78, 78, 78,207, 86,173, 90, 65,163,209, 96, +244,232,209, 70,141, 70,211,223,118, 28,103,197,118, 18, 66,172,145,187, 94,241, 93, 53, 43,191,252,156,239,210,113, 12,228, 50, + 21, 76,194, 90,208,104, 77,200, 43,166, 48, 72,226, 32, 22, 73,208,173,117, 35,156,218,183,190,132, 51, 20,111,168, 76,243, 81, +224,210,116, 81, 21,247,165,105,176, 60, 18,194,115, 28,199, 35,172, 78,152, 50, 41,241,222,178, 1, 3,250, 15,239,209, 35, 94, + 30, 31, 31, 47,109,116,181,172,139, 98,231,206,157,248,225,135, 31, 74,246,239,223, 95, 40, 17,178,107,107,213,174,229,199,113, + 60, 8,169, 58, 66,162, 84, 42,199, 78,154, 52, 73, 86, 80, 80,128,165, 75,151,242,205,154, 53, 99, 20, 10, 5,140, 70, 35,214, +174, 93,107,106,212,168,145,144, 97, 24, 20, 20, 20,128, 97,152,107,142,236, 4,165,244, 2, 33,164,219,138,206,125,127,104,249, +206, 48,175,134,157,219,120,118,170, 21, 4, 83, 12, 69, 90,114, 34,174, 31,218,159,119,105,223,146, 92,232, 50,251, 82, 74, 29, + 46, 70,109, 33, 48, 48,112,218,254,253,251,125,223,125,247, 93,170,211,233,200,189,123,247,232,220,185,115,125,223,122,235,173, +105,168, 38, 23, 78, 21,144,252,252,124, 16, 66,120, 0,214, 71, 56, 81, 30,128, 82,122,145, 16,242,115,159, 62,125,122,117,233, +210, 5, 87,175, 94,181,118, 5,218, 26, 44,203,108,194,121,243,230,229, 3,255, 36, 8,172, 12,137, 68,130,175,119,236,221,147, +150,114, 87, 30, 22, 86, 87,231,238,233,201,215, 36,114, 5, 0, 98,134,153,254,217,172,169,190, 57, 87, 78,145,139, 39, 15,243, +219, 47,100,102,153, 57,106, 63, 67,127, 81, 26, 5, 0,166,186,177,119, 12, 59,125,193,188, 89,238,150,238,203, 45,231,211, 11, + 9, 71,223,173, 81, 3,159, 53,205, 39, 64,217, 12,191, 52, 18, 24, 24, 72, 45, 93,120,246, 12, 86,117,216,235, 30,172,169,246, +157, 59,119,230,198,196,196,140,191,113,227,198,246,134, 13, 27,142, 2, 80, 91,175,215,231, 79,153, 50,101,225,218,181,107,135, + 59, 18,185, 2,128,173, 91,183, 46, 25, 54,108,216,222,151, 94,122,233, 99,158,231,155, 90,222, 39,132,220,241,245,245,181,102, +228,202,206,204,152, 56,114,248,160,137, 90,109,158,195,121,234,220,220,220, 70, 76,153, 50, 69, 90, 92, 92,140,229,203,151,243, +141, 26, 53, 98, 44, 55, 67,223,126,251,173, 57, 50, 50, 82,208,127,204,152,156,197, 25, 25,152,125,244,104,241,196,198,141,155, +173,187,126,189, 5,236, 68,216, 45, 55,140,246, 34, 87,150,225, 21,206, 98,209,180, 53,106,193,193,193,152,246,254,124,164,166, +166, 66, 36, 18, 33, 34, 34, 2, 98,177,184, 26,165,251,161,148,254, 69, 8, 25,116,239,222,189, 13,203,151, 47, 23,183,106,213, + 10,177,177,177, 16, 10,133, 33,150,246, 26, 12, 6, 92,184,112, 1,147, 38, 77,162,103,206,156,121,139, 86, 81,160,158,227,184, +172,200,200, 72, 75,155, 41, 33, 36,183, 80, 79,220,183, 53,136,115, 27, 58,114, 59, 57,118,246, 4,210,140, 60,244, 38, 30, 97, +117,154,163, 83,247,197,248,101,207,223, 92, 90,210,229,203,166,210,188, 53,149,233,186,120,250,168,232, 69,158,117,236,254, 50, +121,150, 57,254,213,170,149, 47,110,221,188,197,159,101, 25,255, 91,183,111,159,125,185,111,191,212, 3, 7, 14,168, 69,238,238, +177, 0,120,195,168, 81, 39,141,250, 82,205,175, 63,255, 28, 18, 22, 22, 26, 93, 94,236,153,242, 44,115,188,170, 15,212,106,181, +197, 71,143, 30, 45,249,228,147, 79, 72,114,114,242,119,126,126,126, 3,247,236,217,227,214,183,111,223,210,171, 87,175,126,239, +239,239,223,171,115,231,206,202,241,227,199,235,181, 90,237, 50, 71,119,132, 82,122,153, 16,210,224,204,212, 69,175,158, 89,176, +242,121, 8,216,182,208, 11, 1,222,116, 28,198,162, 3, 0,190,163,148, 58, 54,176,171, 2, 10,133, 34, 90,161, 80,224,207, 63, +255,204,139,139,139, 51,232,116, 58,209,156, 57,115,188, 20, 10, 69,116, 77,244,202,219, 75,243,242,242,192,243,188, 0, 0, 41, +127, 4,239,124,173,156,255,188,252,242,203, 63,111,219,182,237,133,248,248,120,132,135,135,195,100, 50, 33, 50, 50, 18, 6,131, + 1, 17, 17, 17,208,235,245,152, 49, 99, 6, 10, 10, 10, 62,160, 14, 20, 17,150, 74,165, 16,139,197,136,106,208,184, 68, 42,149, + 58, 61,174,195, 22,133,144, 9,191,246,235, 58,100,229,230,240,219,254,202,204, 44, 49,114,221,110,100, 21, 95,170,184, 93, 9, +135,226,206, 67,223, 75, 5, 0, 61, 15,109,149,154, 98,132, 95,251,117, 53, 50,179,114,176,245,124,122,126,177,145,239,126,205, +142,166, 83,237,124, 70, 52,251, 47,187,138, 78,111, 59,190,237,246, 42,146,118, 58, 66, 77,140,148,133,203,119, 40,193,170, 6, + 20,171,150,217,205,113,245, 48,218,229,145,169,159, 1,128, 16,146, 60,104,208,160,137,137,137,137,179,202,243, 93,173,170,250, +175,239,103,221,186,117, 55, 0, 12,171,106,155, 45,139,134,253, 8,224, 71,103,116,139,138,138,116,231,206,157,211,141, 31, 63, +158, 36, 39, 39,239,241,247,247,127, 97,239,222,189,242,190,125,251,234, 47, 94,188,120, 40, 48, 48,176, 67,215,174, 93,221,118, +159, 62,157, 90,114,235,214,175,191, 38, 38, 6,155,120,254,215,202,244,202,103,230, 61, 18,115,101,209,179,141, 12, 89, 76, 86, + 96, 96, 32, 66, 66, 66, 30,234,119, 79, 41,221, 70, 8,185,210,174, 93,187, 31,134, 14, 29, 90, 47, 46, 46, 14,145,145,145,208, +104, 52, 72, 73, 73,193,177, 99,199,176,122,245,234,211,165,165,165,239,218, 70, 86,237,145,155,155,251, 64, 25, 33, 34,243, 10, + 92,191,124,250,206,179,199, 98, 35,219,199, 15,145, 53, 14,228, 97, 48, 82, 36,223,189,133, 25,159,174, 41, 73,191,123,227,178, +209,108,236,227,202,129,229,226, 73, 98,247,215,121,251,118,242,229,240,240, 90,147,126,248,126, 71, 91, 74, 25,150, 18, 82,236, +225,225,185,243,222,189,123,247,101,193,174,171, 86, 43,135,189, 53,108, 32,225,137,144, 16,158,227, 89,230,248,237,219,201, 85, + 70,136, 12, 6,195,200,129, 3, 7, 46,149,203,229, 83, 52, 26,205,159, 30, 30, 30,127, 69, 71, 71,207,162,148,126, 90, 90, 90, +250,179, 82,169, 60,221,166, 77,155, 57, 33, 33, 33, 75, 40,165,127, 56,179, 51,229, 6,106, 3,170, 24, 3, 86, 19, 8, 33, 51, + 1,184, 11, 4,130,130,191,255,254,123,115, 84, 84,212, 32, 74,169, 59, 33,164,160,166,154, 58,157,238,221,252,252,124,239, 17, + 35, 70,152, 86,175, 94, 29, 53,100,200,144,137,151, 46, 93, 18,234,116,186,219,206,232, 80, 74,245,132,144, 94, 3, 6, 12, 88, + 35, 20, 10,187, 48, 12, 67,120,158,167, 54,235, 65, 41, 5,199,113,191,160,154,227, 34, 20, 10,181, 47,190,248,162, 91,117,159, + 41, 22,139,171, 52, 64,182, 20, 25,184,113, 43, 15, 95,154,167, 51, 81,106,230,233,200,107,153,197,118,167,144,157,185, 70, 27, + 57,172,169,227,199, 45,221,119,121,158,222,196,243,102,158,142,170, 76,211, 25,158, 21, 77, 0, 24,205, 44,251, 22,171,150, 89, + 7,188, 91,186, 13, 43,190,126,212, 88, 34, 77,112, 38,203,114,121, 58,134,170,178,179,215, 88,187, 28, 91,179,229, 44,253,250, +245,123,100,169,101, 42, 98, 52, 26, 39,191,252,242,203,179, 60, 60, 60, 22,102,103,103,255,233,225,225,113,185,126,253,250,227, +120,158, 95, 82, 82, 82,178, 83,169, 84,190,212,178,101,203, 15, 66, 67, 67,215, 39, 81,186,190, 42, 45,142,227, 82, 45, 81, 28, + 0,212, 18,125,178, 24, 8, 91, 35, 97, 50,153, 42,205,161, 86, 81, 51, 58, 58,186,188,215,162, 76,175,226,163, 45,142,234, 90, + 27, 89,118,211, 91,127,214,172, 89,109, 0, 60, 7, 32, 26, 64, 33,128,187, 0, 78, 82, 74,247, 58,163,119,159,118,105,110, 26, + 33, 36,230,202,249,163,163,174, 95, 62,255,170,101,182, 32,203,138, 47,114,198,146, 13,166,210,188, 53, 46,115,229,226,137, 99, +185, 0, 63,142, 5, 64, 87,151,166, 75,211,165,233,210,116,105,186, 52, 93,154, 46,205,255,111,139,171,244,184, 11, 23, 46, 92, +184,112,225,194,197, 35,134, 0,176, 59, 19,128, 58, 81, 41,187, 38,179, 9,170,211,119,105,186, 52, 93,154, 46, 77,151,166, 75, +211,165,249,191,167,249,255,134,199, 25, 30,195, 51, 18,150,116,105,186, 52, 93,154, 46, 77,151,166, 75,211,165,249,100, 53,255, +215, 22, 87, 23,161, 11, 23, 46, 92,184,112,225,194,197, 35,166,230,115,124,255,159, 82, 94, 83,238,109, 0,253, 0,212, 5,112, + 11,192, 14, 0, 43,168,227, 5,143,109,245, 84, 0, 38, 2,104, 11,160, 14,128, 59, 0,142, 2,152, 79, 41,117,120,182,222,255, + 55,124,124,124, 38, 9,133, 66, 15,160,172,220,135,229,209,246, 57,199,113,249, 5, 5, 5,115, 31,199,231, 19, 66, 88, 74,169, + 67, 51,208, 44,109,181,109,155,237,163,201,100,122,108,237,116,241,116, 66, 8,137, 84,171,213,155, 52, 26,205,107,148,210,235, + 79,186, 61, 46, 92, 60, 74,124,125,125, 71, 25,141,198, 41, 34,145,104, 78, 86, 86,214,202, 39,221,158, 39,133,213, 96, 17, 66, + 18, 0,128, 82,218, 17, 0,148, 74,229, 9,134, 97,234,148,175, 3, 80, 86, 19,202,246,117,197, 71,158,231,239,228,230,230,182, +169,236,195,228,114,249, 9,150,101,235, 16, 66, 44,197,103,193, 48, 12, 76, 38,147,146,101,217,162, 74, 52, 83, 52, 26, 77,139, + 71,180,191, 15, 69,121,173,176, 95, 61, 61, 61,117,179,102,205, 90,209,169, 83,167, 90,105,105,105,230, 9, 19, 38,116,248,235, +175,191,226, 9, 33, 47, 58, 99,178, 8, 33,173, 9, 33,235,155, 53,107,246,227,224,193,131,183,197,197,197,137,115,115,115,149, + 59,118,236, 8,218,176, 97,195, 57, 66,200,107,212,201, 84, 21, 79, 59,132, 16, 1,173, 36, 31, 89, 85,235, 42, 34, 20, 10, 61, + 82, 82, 82,148, 64, 89, 55,119,185,161,130,201,100,130,201,100, 66,113,113, 49,162,163,107,156,166,172, 82, 2, 2, 2,154, 19, + 66,150, 69, 68, 68,180, 8, 12, 12, 60, 11, 96, 76, 90, 90,218, 95,206,180,213,108, 54,131, 82,106,109,103,195,134, 13, 31,121, + 59,255,151, 33,132,188, 41, 22,139,187, 71, 68, 68,196,234,245,250,188, 59,119,238,156,225, 56,110, 42,165, 52,227, 17,233,187, + 3,152, 42,145, 72,226,234,214,173, 91,235,198,141, 27,201, 70,163,241, 52,128,153,148,210, 26,167,102,177,209,143,236,216,177, +227,177,229,203,151,123,141, 30, 61,250, 24, 33,164,157,203,100,185,120, 82,212,174, 93,219,163,184,184,120, 13,128,230, 66,161, +208, 95, 42,149, 66, 38,147,101, 72, 36,146, 63,101, 50,217,240, 99,199,142,229, 87, 43, 82, 1,142,227,166, 38, 37, 37,249,183, +106,213,106, 65,227,198,141,103,228,228,228,232,140, 70,227,161,188,188,188, 15, 40,165,133, 85,253,109, 69, 47,242, 44, 35, 0, +172,197, 21, 59,221,183, 66, 32, 8, 78, 74, 74,242, 85, 42,149,224, 56,206, 26, 29,176, 92,204,202,251, 96, 1,148, 93, 52, 56, +142, 67,253,250,245,141, 85,125,152, 80, 40,172,149,146,146,226,235,230,246, 79,170, 37,163,209, 8,127,127,127, 62, 53, 53,213, +183, 98, 33, 97,131,193,128,224,224,224,167, 41,151,201,219,106,181,186,224,222,189,228,104,157,222, 56,243,173,119, 63,153,244, + 90,191,231, 61, 79,156, 56,193,191,248,226,139,250,132,132,132,183, 1, 56,148, 28,149, 16,226, 78, 8,217, 48, 97,194,132, 25, + 82,185,202,235,240,137,203,250, 13, 59,118,165, 54,139, 12, 35, 31,124,240, 1,251,222,123,239,253,222,188,121,243, 77,132,144, + 24,103, 34, 89, 74,165,114,175, 68, 34, 9,101, 89, 22, 70,163,241,158, 70,163,121,161,198,123,251,136, 33,132, 52, 3,112,158, + 16,210,156, 82,250,167,163,235,170, 34, 55, 55, 23,165,165,165, 15, 44, 13, 27, 54,188,239, 59,250,136,218, 47,168, 85,171,214, +207,243,230,205, 11,202, 72, 79,199,231,139, 23,183, 2,176, 2, 64, 43, 71,254, 62, 43, 43,235,129,118,214,175,255,120,114, 86, +253,175, 66, 8,153, 56, 99,198,140,121,175,190,250, 42, 56,142, 67,105,105,105,224,205,155, 55, 27, 77,153, 50,165, 15, 33, 36, +150, 82,234, 84, 30, 57, 59,250, 62, 17, 17, 17, 87,199,141, 27,167,142,141,141, 69,121, 85,137,192,163, 71,143,182, 90,187,118, +237, 27,132,144,250,148,210,236,135,249, 12,181, 90,189,233,235,175,191,246,146,203,229,248,229,151, 95,188,186,116,233,114,148, + 16,210,190,166, 38,139, 16,194,120,121,121,189, 7,224, 57,158,231,197, 0, 78,231,229,229,205,166,148, 86,121, 62,118,225,194, +219,219,251,205,162,162,162,229, 18,137, 68,228,233,233, 9,185, 92, 14,129, 64, 0,129, 64, 80, 91, 34,145,212,150, 72, 36, 61, +158,123,238,185, 49,135, 15, 31,174, 50, 35,126,155,230,254, 67,193,144,153, 44, 97, 88, 0,104, 24,225,165,114,119,119,199,204, +153, 51, 21,189,122,245, 82, 0,192,177, 99,199, 6, 15, 25, 50,164, 11, 33,164,113,101, 38,203,158, 23,121,150,177, 45,246,156, + 96,187,130, 16, 2,153, 76,134,109,219,182,129,101,217,251,170,184,219,123, 94,187,118,237,106, 63,204, 18, 1,219,185,115, 39, + 84, 42, 21,220,221,221,173, 23, 24,137, 68,130, 67,135, 14, 65, 40, 20, 66, 32, 16, 64, 40, 20,162, 69,139, 22,118, 19,222, 61, + 78,250, 55, 42, 43, 50,105, 47,121, 99,251,186, 50,244,123,111,250,192, 18,157,177, 37,128,226,252,188,188,188,179, 63,252,144, +214, 44, 50, 82,180,105,211,166,216,160,160,160,126,112,208, 96, 1,152, 24, 19, 19,243, 61, 43,115,247, 30, 60,100,232,224,225, + 2,198,248,198,200,241,115,146,211,115,138, 71,140, 24,241,195, 47,191,252, 50,248,179,207, 62,187,242,209, 71, 31, 77, 4, 48, +217,209,246,139,197,226,208,155, 55,111, 70,240, 60,143, 38, 77,154, 60, 53,229, 6, 44, 6,138, 82, 10, 66,200,125, 70,170,170, +117,213, 97,137, 88,217, 91, 30, 53, 65, 65, 65,245, 95,127,253,117,111, 77, 78, 14, 62, 95,188,216,242,118,139,234,186, 11, 45, + 93,129, 6,131, 1,175,188,242,202,235, 28,199, 9, 44,230, 79,175,215, 27, 10, 10, 10,116, 54, 51,117,178, 41,165,207, 87,215, + 22, 66, 72, 29,133, 66,177, 16, 64,243,210,210,210, 32, 0, 80, 40, 20,169, 60,207,255, 88, 92, 92, 60,153, 82, 90, 90,147,125, + 36,132,212, 2,208, 8,149,151,108,162,243,230,205,187, 49,113,226, 68,135,141,204,163,210, 36,132,132,250,249,249,205,237,223, +191, 63,118,237,218,133,221,187,119,155,100, 50,153, 96,200,144, 33,100,204,152, 49,158,227,198,141,235, 1,224, 11, 71,219, 85, + 9, 61,102,204,152,161,110,208,160, 1,118,236,216,129, 11, 23, 46,148, 70, 68, 68,200, 58,117,234, 4,129, 64,160,158, 52,105, +210,139, 0,214, 63,204, 7,104, 52,154,217,227,199,143,223,176,121,243,102,229,157, 59,119,176,108,217, 50,239,129, 3, 7, 38, + 16, 66, 58, 58,106,178, 8, 33, 18, 0,239, 1,232,204,178,108,251, 33, 67,134,152,223,125,247, 93, 33,195, 48,166,197,139, 23, +251,172, 93,187,118,160,183,183,119,243,156,156, 28,215, 48,131, 42, 96, 89,214,200,243,188, 16,128,148, 82,170,175,238,245, 19, +110,238, 35,197,203,203,107,116, 94, 94,222, 10,127,127,127,248,249,249, 61,112,173,213,235,245,144, 74,165, 34,127,127,255,175, +123,247,238, 45,252,233,167,159, 42,237,234, 35, 44,153,250,203,150, 89, 65,106, 79, 37, 0, 96,201, 87,251, 74, 0,224,167,159, +126, 66, 90, 90, 26, 60, 61, 61,209,184,113, 99,118,214,172, 89, 1, 31,124,240,193,231, 0,134, 87,166, 85,209,139, 60,203, 84, + 57, 6,139,231,121,107, 33, 81,139,145,178,152,159,138,207,129, 7,179,255,210, 10, 83, 53, 9, 33, 68,171,213, 90,205,149, 74, +165, 66,249, 69, 21, 38,147,233, 1, 93,142,227, 44,142,182, 82, 77,123, 16, 66, 70, 3, 56, 68, 41,189,229,200, 65,176,213,220, +254, 78,125,108,144, 76, 24,100, 73,121,222, 99,124,217,227, 6, 0, 39, 18,135, 47, 91,222,177, 99,208,123,159, 46,157, 94,154, +155,150, 51,233,245,151, 66, 35,252,189,100,138,252,172, 2,117, 84, 84, 55, 0,102,123,154,149,208, 97,240,224,193, 27,247,159, + 74, 34, 82,169, 72, 36, 96, 89, 97,187, 38,145, 94,181,220, 89,119, 37,224,158,124,251,198,137,161, 67,135, 54,249,232,163,143, +218, 59,179,239, 12,195, 64,165, 82, 97,227,198,141, 96, 44,142,214,193,125,127, 84,216,249,191, 11, 80,110,160, 52, 26, 13,118, +237,218,133,248,248,248,243,132,144,230,229,155,156,167,148,162,176,176, 16,233,233,233, 8, 8, 8, 56, 79, 8, 17,218,118, 23, + 86,212,180, 68, 81, 45,102,106,200,144, 33,175,155,205,102,235,247,217,142,113, 1, 42,152, 23, 71,247, 61, 48, 48,112, 63,128, +231, 89,150,133, 65,167, 51, 44,252,239,127,109, 87,255, 97,107,174, 42,211,180,180,149,227, 56,193,249,243,231,133,150,223, 12, + 0, 33, 0, 5, 0,111, 74, 41, 24,134,121,160, 38,155,157,227, 89, 95, 46,151,159,216,185,115,167,170, 69,139, 22, 68, 44, 22, +195,108, 54,227,226,197,139,181, 62,251,236,179,145, 7, 15, 30,124,145, 16,210,144, 86, 40,106, 94,149,166, 13,141,142, 30, 61, + 90, 28, 30, 30,110,215, 48, 22, 22, 22, 10, 34, 35, 35, 59, 2,120,192, 12,253, 11,154, 41,153,153,153,189,159,127,254,249, 81, + 25, 25, 25, 87,205,102,243,199, 0, 26,123,123,123,159,239,219,183, 47,100, 50, 89,103, 56, 96,176,170,250,191,251,250,250,246, +106,211,166, 13,150, 45, 91,134,207, 62,251,172, 43,165,244, 16, 33,164, 75, 97, 97,225,193,151, 95,126, 25, 30, 30, 30,189, 97, +199, 96, 57,250, 93, 34,132, 68,118,232,208,225,235,153, 51,103, 42,119,237,218,133,136,136, 8, 20, 21, 21,225,195, 15, 63,244, +157, 54,109,218, 17, 66, 72, 39,139,201,170, 76,147, 16,210, 80, 34,145,172,223,188,121,179, 91,120,120,120,184, 72, 36, 98,194, +195,195,161,209,104,160,211,233, 36,115,230,204,105, 34,147,201,254,250,226,139, 47,214, 3,232, 91,147,118, 58, 67, 85,154,229, +213, 46, 84, 0, 60,156,233, 94,173, 98,223, 11, 0, 72, 44,175,133, 66, 33,164, 82, 41,164, 82, 41, 36, 18, 9,110,220,184,241, +169, 88, 44, 94, 12,155,115,113, 85,154,228,159,139, 86, 52, 33,228, 12,203,178, 85,190,174, 56, 4,228,223, 62,158, 0, 64, 8, + 9, 38,132, 44, 1,208, 25, 0,195, 48, 76,130,183,183,247,216,140,140,140,187,142,106, 6, 6, 6,122,105,181,218, 47, 2, 2, + 2,224,231, 87, 86,143,157, 97, 24, 4, 5, 5,193,100, 50, 33, 51, 51, 19,148, 82,228,231,231, 67, 46,151, 35, 48, 48,240,139, +145, 35, 71,238, 88,181,106, 85,174, 93, 77, 30,159,189, 60,112,202, 84,150,101, 25, 0, 96, 5,110,110,227, 62, 1, 66, 67, 67, +209,174, 93, 59,232,116, 58, 20, 20, 20,160, 81,163, 70, 2, 66,200, 96,134, 97, 84,148,210,149,148,210,195, 78, 31,160,103, 8, +203, 5,105, 70,197,126, 79, 66, 8,120,158,135, 64, 32,184,207, 96, 85, 92, 44,102,168,252,123, 90,101,196,132, 16,194, 24, 12, + 6,171,185,114,119,119,183,154, 51,179,217, 92,153,193,114,122,167,188,188,188,154,242, 60, 95,135, 16,178,202, 81,147, 85,145, +193,131, 7, 63, 48,158,227,131, 15, 62, 72,201,202,202,162,175,116,139, 86, 92,221,147,150, 94,215,211, 77,230,163, 84,134, 73, + 61,213, 30,185,185,185, 39, 1,120, 56,241, 17,245, 98, 98, 98,100, 27,126, 56,154,242,214,251,243,102,181, 8,247, 82, 53, 13, +246,246,244,119,151,137,221, 24, 82, 44, 53,155, 82,212,106,117,132,179,237,182,212, 15,243,240,240,128, 64, 32,120, 42, 34, 88, +148, 82, 51, 33,164, 57, 33,228,252,174, 93,187, 16, 23, 23,103, 53, 89,229,235, 81, 80, 80,128,139, 23, 47,162, 67,135, 14, 0, +208,220,145,177, 88, 60,207,195,104, 52,194,104, 52, 90,141,139, 72, 36,178,172,182, 26, 23,203,182, 44,203, 86, 90, 80,182, 26, +102,121,122,122,118,232,220,185,179,120,203,182,109, 98, 74,105, 49,202, 10, 82,107, 41,173,164,112,117, 5,204,102,179, 53,170, + 38, 20, 10,113,239,222, 61,107, 20,216, 18, 9,174,216, 69, 94, 25, 18,137,100,252,214,173, 91, 85,177,177,177, 36, 55, 55, 23, + 60,207, 91, 79,142, 43, 86,172,144,246,235,215, 47,232,220,185,115,147, 80,131,178, 51, 0, 72,101, 70, 8, 0, 84, 42,149, 25, +112,122,246,177, 93, 77,179,217, 76,218,182,109,251, 81, 78, 78, 78,147,210,210,210, 57,213,137,148,127, 39,126, 41, 95,202,132, + 9,249,235,234,213,171,165, 3, 6, 12,144,133,133,133,197, 57,217,174, 7,136,140,140,108, 45, 20, 10,113,250,244,105, 61,128, +132, 13, 52, 89,147, 0, 0, 32, 0, 73, 68, 65, 84,242,183, 19, 46, 92,184,160,239,219,183,175,164, 86,173, 90,173, 29,213, 34, +132, 68,214,175, 95,255,128,175,175,175,204, 18,177,236,223,191,191,112,245,234,213,202,212,212, 84, 24,141, 70, 76,156, 56, 17, + 61,123,246,132,183,183, 55, 62,248,224, 3,191, 5, 11, 22,108, 2, 16, 83,133,166, 84, 44, 22,111,188,121,243,102, 68, 64, 64, +128,236,212,169, 83,104,218,180, 41,114,114,114,144,145,145, 1,173, 86,139,140,140, 12, 12, 31, 62,220,247,243,207, 63, 15,124, +136, 67,241,168,201, 23,137, 68,144,203,229, 30,249,249,249, 15, 51,142, 77, 2, 64, 12,252, 99,174, 36, 18, 9, 36, 18, 9,164, + 82, 41,120,158,127, 42,206,121,143, 11, 66, 72, 16, 33,228,178, 72, 36,146,200,229,114, 17,195, 48,144, 72, 36,221,212,106,245, +165, 23, 94,120,161,241,254,253,251,147, 28,209,209,233,116, 27, 37, 18,137,208,215,215, 23, 0, 16, 17, 17,129,166, 77,155,162, +184,184,152, 47, 40, 40,128,135,135, 7,115,247,238, 93,148,150,150, 34, 61, 61, 29, 33, 33, 33, 66,134, 97, 54, 2,120,209,158, +222,241,115,233, 95, 1,248,202,242,218,199,199, 39, 19,128,204,242, 90, 42,149, 34, 40, 40, 8,169,169,169, 80, 42,149,236,180, +105,211,250,110,219,182,173, 15, 33,100, 48,165,244, 91, 27,169, 7,188,200,179,140, 0, 0, 40,165,211, 9, 33, 29, 43,174,180, + 24, 44,203, 98, 47,114,101, 89, 28, 49, 66,132, 16,112, 28, 7, 63, 63, 63,200,229,114,200,229,114,107,193, 81,142,227, 30,208, + 47,191,163,119,122,167, 20, 10, 5, 94,125,245, 85,186,114,229,202, 81,229, 38,235,166,163,127,219,127,217, 85,107,212,170, 34, + 13, 27, 54, 60, 49,105,210,164, 94,191,253,246, 91,106,139,240, 48,129, 34,237,174, 86,170,242,240, 64,112,237,248, 33,189,251, + 94, 64,217,108, 66, 71,185, 89, 84, 84, 36,171, 27, 44, 55, 48,140,142,212,150, 8,148, 1, 10,145,196,223,211, 51, 72,100,208, +103,169, 60, 61,197,122,189, 62, 31, 64,149,197,153, 85, 42,213, 62,137, 68, 18,194,178, 44, 88,150,133,183,183,183, 59,165, 20, + 30, 30, 30, 8, 14, 14,118,139,138,138,186, 46, 16, 8,192, 48, 12,180, 90,237,221,196,196,196,110,213, 53,204,211,211,115,159, + 68, 34, 9, 97, 24, 6,132, 16,176, 44,107,157,144, 96,121,206,178, 44, 8, 33, 40, 41, 41,113, 72,147, 82,250, 39, 33,164,121, +124,124,188,213,100,237,217,179, 7,221,187,119, 71,126,126, 62, 46, 93,186,100,107,174, 28,234, 30,180, 29,212, 78, 41,133, 72, + 36,194,181,107,215,238,235,186,182, 44, 74,165,210, 17, 73,187,168,213,234, 99,253,251,247,199,215, 95,127, 77,105, 89,149,119, + 5, 33,164,169,187,187,251,181,203,151, 47, 59, 52,206,133, 82, 10,163,241,159, 77, 45,223,113,219,223,151,163,176, 44,219, 45, + 38, 38,134, 20, 20, 20, 88,140,163,245, 70,136,101, 89, 44, 95,190, 92, 22, 27, 27, 59, 69, 42,149,126, 36, 18,137, 10, 77, 38, +211, 22,157, 78, 55,135, 82,234,244, 96,213,199, 73,251,246,237,223, 79, 78, 78,238, 25, 18, 18,178,179,166, 26,148, 82,218,178, +101, 75, 3, 0, 25,203,178,194,106,255,160, 26, 8, 33, 44, 0,112, 28,167,179,152,124, 74,169, 57, 38, 38, 70,135,178,139,187, +195, 21,144,189,189,189, 55,237,222,189, 59, 56, 36, 36, 4, 38,147, 9,102,179, 25, 90,173, 22, 9, 9, 9,208,235,245, 48,155, +205,136,136,136,192,212,169, 83,117, 99,199,142,149,174, 90,181, 42, 75,171,213,190, 86,141,236,216, 29, 59,118, 40, 2, 2, 2, +100,165,165,165,184,125,251, 54, 98, 98, 98, 80, 84, 84,132,226,226, 98,148,148,148,192,104, 52,162,176,176,208,131,227, 56, 67, +141, 15,196, 35, 70, 32, 16, 64, 34,145, 64, 36, 18,229,135,132,132,128, 16, 34, 77, 74, 74,170, 73,151,155, 10, 64,161, 80, 40, + 20,219, 26, 43,137, 68,130,211,167, 79, 79,150, 74,165,159,195, 78,244,170, 50,104,133,129,154,213,189,126,210, 16, 66,150,136, + 68, 34,137, 90,173,182,222, 73,242, 60, 47,114,115,115,131,175,175,239, 50, 0, 61, 28,209,161,148, 54, 83,171,213,214,243,123, +116,116, 52,146,147,147,127, 44, 40, 40,120, 35, 43, 43, 11, 12,195,108,100, 24,166, 79,185, 62,242,242,242, 80,171, 86,173,102, +149,233,181,141, 9, 24, 5, 66,173, 17,172,134,245,212,247,213,180, 85,169, 84, 80,169, 84, 72, 76, 76, 68,113,113, 49,189,113, +227, 6, 25, 61,122, 52, 49, 24, 12,223, 16, 66, 78, 82, 74,239,148,183,203,174, 23,121, 86,169,116, 12, 22,240, 79, 23,161, 61, + 67, 85,209,112, 57, 98,132, 12, 6,131, 91, 76, 76, 12,111,185,112, 91, 22, 0,164, 50,131,133,178, 72,129,211, 8,133, 66,229, +232,209,163,139, 86,174, 92, 57,146, 16,178,154, 82,122,163, 38, 58, 0,176,243,251,205,126,159, 77,157, 56, 85, 29, 24, 86,247, +163,143, 62, 21,188,244,210, 75,167, 54,108,216,192,169, 27,244,232,114,120,223,183,126, 95,124, 56, 97,207,238,221,187,129,178, + 1,207,142,114,236,215, 95,127,245,255,224,189, 49,152, 58,126,236, 94, 85,132,183,216,141,168, 21, 82,125,113,182, 27,104,169, +164, 94,253,158, 63,236,220,153, 14,160,202, 74,243, 50,153, 44,228,198,141, 27, 17,182, 6,194,104, 52,194,195,195, 3, 27, 54, +108,240, 81, 42,149, 62,110,110,110, 16, 8, 4,104,218,180,169, 67, 13,147, 72, 36, 33,215,175, 95,143, 80, 42,149, 40, 41, 41, +129, 94,175,135,201,100, 2,207,243, 32,132, 64, 40, 20, 66, 44, 22, 67,161, 80, 56, 53, 83,207,214,100,237,217,179, 7,141, 26, + 53, 66, 94, 94, 30,174, 94,189,234,180,185, 2,254,137, 10,217,142,183, 18, 8, 4,216, 20, 30,142,183,210,210,172,198,101,137, +187, 59,166,242, 78,103,208, 0, 0, 52,105,210,132, 30, 63,126, 28,123,247,238,197,203, 47,191, 76,126,254,249,103, 35,199,113, +162,212,212, 84,135,163, 97, 60,207, 91,219,106, 57, 95,219, 26, 43,103, 13,150,217,108, 86,138,197, 98,232,116, 58,107, 23,190, +237, 82,167, 78, 29,104, 52, 26, 65, 97, 97,161, 32, 45, 45, 77, 62,123,246,236,119,143, 28, 57, 18, 0, 96,144,211, 7,224, 17, +178,114,229,202,144,183,222,122,235,158, 64, 32,160,221,187,119,127,253,238,221,187,189, 3, 2, 2, 14,253,246,219,111,255, 5, + 16, 89,173, 64, 5,124,124,124,254, 16, 8, 4,193,110,110,110,162,237,219,183,155,138,138,138, 68,190,190,190,153,192, 63, 9, +148,129,178, 34,197, 5, 5, 5,213,206, 68,246,241,241,249,195,199,199, 71,244,229,151, 95,154,114,115,115, 69,254,254,254,153, + 22, 29,133, 66, 33,218,190,125,187,169,176,176, 80,228,225,225,241, 71,126,126,126,181,122, 57, 57, 57,175, 13, 30, 60,248,232, +161, 67,135,188, 89,150,197,221,187,119,145,155,155, 11, 15, 15, 15,108,220,184, 17, 33, 33, 33,216,177, 99,135, 70,163,209,188, +185,112,225,194, 41, 90,173,214,145,148, 13, 29,226,226,226, 66,242,243,243,225,225,225,129,226,226, 98,252,241,199, 31,104,216, +176, 33,210,210,210,192, 48, 12, 60, 60, 60,176, 98,197,138, 18, 66,136,198,145,227,248,184, 97, 89,214, 26,101,178, 49, 69,186, +214,173, 91,227,240,225,195, 31, 59, 99,138, 40,165, 6,161, 80,120,159,177,178, 60, 23,137, 68, 14, 27, 43, 11, 28,199,137,202, +199,128, 18, 71, 94, 63, 5,116,148,201,100,162,138,111,150,148,148,136, 2, 2, 2,218,219,251, 3,123, 8, 4, 2, 47,153,172, + 44,192, 20, 18, 18,130,130,130, 2,206, 96, 48, 12,220,184,113,163, 9, 0, 98, 98, 98, 6,114, 28,167, 51,155,205,172, 88, 44, + 70,113,113, 49,124,125,125,189, 42, 21,100,240,241, 47, 91,102,251, 87, 28,131, 21, 16, 16,128,230,205,155, 67,175,215, 35, 61, + 61, 29, 9, 9, 9, 38,142,227,190, 91,185,114, 37,239,227,227, 51,236,149, 87, 94, 97,207,157, 59,247, 14,128,247, 45, 82,255, +115, 99,176,202, 29,227, 17, 0,157, 44, 59,103,219, 69, 88, 85,228,170, 66, 4,171,202, 47, 33,203,178,249, 41, 41, 41, 10,133, + 66, 97,125,207,100, 50, 33, 48, 48,144,231,121,158, 84,252, 28, 75, 59,106,138, 80, 40, 84,126,242,201, 39,249, 43, 86,172,120, + 3, 14, 14, 20,223,254, 78,125,108,176,121,189,243,251,205,126, 95,125, 54,115,217,151, 11,102,171,111,237,249, 6,107,150, 46, +226, 56, 14,231,154, 52,105,210, 94,171,213, 10,220, 21, 38,228,228, 99, 15,202,242, 96, 57,100, 6, 73, 89, 46,173,117,103,206, +156, 57,215,163, 71,143,227,235,182,254,160, 78,187,125,251,164,164, 48, 39, 93, 85, 47, 66, 32, 10, 10,233, 83,164,211,137, 6, + 14, 28,232, 3,224,149,170,180, 24,134,193,237,219,183,145,148,148, 4, 55, 55, 55, 40,149, 74,184,185,185, 65,165, 82, 65,169, + 84, 66,169, 84, 58,125, 12, 25,134, 1,199,113,248,254,251,239, 33,151,203,161, 80, 40,238, 91, 44,230,234, 97,254, 55,221,187, +119,135, 70,163,129,155,155,155,181, 91,211, 25, 44, 99,176, 12, 6, 3, 12, 6, 3,140, 70, 35, 7, 64, 40, 16, 8, 48, 60, 37, +197, 26,213,113,198,184, 84,164,105,211,166,244,228,201,147, 56,126,252, 56,138,139,139,241,229,151, 95, 34, 32, 32,224, 57, 0, +159, 58,170, 65, 8, 9,247,247,247,239,254,194, 11, 47, 4,154, 76, 38,104,181, 90,230,239,191,255,134, 84, 42, 5,203,178, 72, + 73, 73,193,230,205,155,145,152,152, 8, 0,240,244,244, 12, 38,132,132, 81, 74, 19, 43,211,228, 56, 78, 36, 16, 8,172,119,159, +150,197, 54,138,197,178, 44,252,252,252,224,239,239,143,175,190,250, 74, 20, 22, 22,214,179,198, 7,226, 17,176, 96,193,130,122, + 75,150, 44, 89,187, 97,195,134, 61,175,189,246,218,182,139, 23, 47, 14,117,119,119,255,251,240,225,195,179, 37, 18, 73,141,220, +175, 80, 40, 12, 78, 75, 75,243,181,125,139,231,121,185,217,108,182, 26,218,146,146, 18, 52,110,220,216, 97,189,203,151, 47,203, + 1, 96,246,236,217, 66, 0,114, 75,250, 15,139,102, 73, 73,137,176, 97,195,134,193,142,232, 81, 74,175, 19, 66,218,119,237,218, +245,196,129, 3, 7, 60, 67, 66, 66,144,154,154,138,212,212, 84,212,171, 87, 15,115,231,206, 45, 46, 44, 44,108, 91,110,170,126, +118,112,183, 3, 61, 61, 61,133,247,238,221,131,217,108, 70,179,102,205,176, 98,197, 10, 12, 28, 56, 16,141, 27, 55, 70, 97, 97, + 33, 46, 95,190,140,245,235,215,123,138, 68,162, 42,207, 29,255, 6,229, 93, 88,149, 46, 53,193,108, 54,171,164, 82,105,161, 68, + 34, 17, 91,198, 95, 37, 36, 36, 56, 29,189,178, 80,241,166,174,186,215, 79, 18,139, 89,173,136, 88, 44,134,191,191,191,195, 58, + 18,137,132, 88,206,141,102,179, 25, 5, 5, 5, 92, 64, 64,128,181, 27,255,252,249,243, 92,104,104, 40,199,178, 44, 43, 22,139, + 65, 8,129, 92, 46,175,244,132, 79, 57, 58,243,165,129,159, 90,103, 17, 50, 66,133,106,220, 39,101, 55,251,231,207,159,135,209, +104, 68, 66, 66,130,105,225,194,133,105,249,249,249,227, 0, 8,246,237,219, 55,120,194,132, 9,172,175,175,175,117,156,172, 61, + 47,242, 44, 99,185,250, 28,161,148,146,242, 1,229,101, 78,137, 16, 80, 74, 31, 48, 85,149, 25,174,242, 8, 86,149, 87, 92, 75, +215,210,222,189,123,173, 70,192, 50,139,144, 82,250,128,174,165, 29, 53,197,203,203,171, 56, 46, 46, 78,149,156,156,188,185, 38, +127,111, 49, 87,243,103, 79, 87,231, 94, 57,137,148,180,116,104,178, 76,231,142,253,157,248, 35,128, 31, 1, 0,171, 26, 28,193, +200, 43,203, 29,213,108,224, 35,143,110, 18,168,252,241,249, 30, 61,107, 13, 24,241, 62,243,246,219,111,183, 27, 60,120,112,193, +107,175,189,246,158,155,155, 91,164,209,104,204,251, 97,215,174,164, 1, 3, 6,132,113, 28, 55,184,178,233,172, 22, 76, 38,211, +221,190,125,251, 90,143,173,191,191,191,106,203,150, 45,126, 74,165, 18,175,191,254,122,118, 82, 82,146,181, 91,168,168,168,232, +174, 35,109, 52, 26,141,119,163,163,163, 43,237, 22,180, 68, 32,157,209, 4,238,159, 45,152,155,155,139,107,215,174, 65, 32, 16, +160, 85,171, 86, 56,118,236, 24,218,181,107,231,212, 12, 66,157, 78,135,144,144, 16,232,116, 58, 20, 23, 23,151, 0,144,108, 12, + 11, 3, 0,188,147,155,139, 63, 22, 46,196,169,121,243, 44,159,237,104, 51, 1, 0,209,209,209,244,244,233,211,248,251,239,191, +161,215,235,241,230,155,111,162,188,123, 16, 0, 28, 74,125, 65, 8,105, 92,191,126,253,131,135, 15, 31,246, 81, 42,149,208,106, +181,208,106,181, 24, 54,108, 24, 70,141, 26, 5,147,201,132,149, 43, 87,226,167,159,126,130, 74,165,130, 86,171, 69,113,113,177, +103,124,124,252, 9, 66, 72,135,202,186,182, 41,165, 36, 49, 49, 17,243,231,207, 7,207,243,152, 48, 97, 2, 34, 34, 34,172,198, +234,238,221,187,152, 61,123, 54, 56,142,195,180,105,211, 80,175, 94, 61,152, 76, 38, 41,113, 34,207,216,163,230,131, 15, 62,184, +245,227,143, 63,238, 73, 78, 78,126,241,179,207, 62,235, 72, 8,225, 63,250,232,163,249, 42,149,202,161,100,173,149,145, 87, 80, +132,107, 55,239, 90, 13, 80,197,197,199, 91,237,180,222,141,219,201,214,191,231, 56, 91, 61, 14, 94,106, 79,103,155, 88, 98, 50, +153,138,251,244,233,227,241,253,247,223,147,122,245,234,225,206,157, 59,150,155,210, 18, 71,103, 13,218,144,170,209,104, 34, 88, +150, 21,221,188,121, 19,161,161,161,136,139,139,195,156, 57,115,144,147,147, 3,179,217, 12, 95, 95, 95,222,100, 50,157, 55, 24, + 12,191, 59,219,216, 71,141,109,148,201,118,249,237,183,223, 62,150, 74,165, 20,192,105, 0, 78, 25,108, 74,169,161,118,237,218, +247,105,215, 36,122,245,184,120,156, 51, 19, 3, 2, 2, 18,148, 74,101,207,188,188,188,251,162, 88,109,219,182, 53,250,249,249, + 29,117, 84,199,205,205, 45,143,101, 89, 47, 0, 72, 77, 77,133, 66,161, 16,221,190,125,123, 30, 33,100, 34, 0,132,133,133,205, +211,104, 52,162,176,242,243,169,191,191, 63, 12, 6, 67,165,195, 85, 78,156,207,248, 6,192, 55,150,215, 94, 94, 94,233, 5, 5, + 5,178, 69,139, 22,105,231,205,155, 87,202,113,156, 30,192,225,252,252,124,107, 30,172,208,208,208, 2,161, 80,168,246,240,240, + 8,178,145,122,192,139, 60,203,216, 38, 26,125, 32,250, 98, 49, 61,142,152, 44, 71,162, 16,132, 16,148,150,150,222, 23, 13,177, +204, 34,180,103,176,202, 47,228, 53,234, 34, 44, 55, 87,178, 45, 91,182,124,183,116,233,210,227,142,254,157,237, 24,172, 85,255, +157,245,153,197, 92, 93, 56,118, 0, 63, 95, 45,200,153, 48,111,241,146,154,180, 7, 0, 26,250, 40,154,250,251,121, 31, 89, 56, +111,150,234,214,158,111,176,109,213,231,244,194,217,179,177,103,207,158,125, 99,204,152, 49,181, 81,246,133,210, 0,248, 11,192, + 0, 71,102,221,100,103,103,223, 55,254, 41, 34, 34,226,186,135,135,135,159, 84, 42,197,237,219,183,181,151, 46, 93,114,186,235, +165,162,230,163,160,162,185,186,116,233, 18, 58,119,238, 12, 0, 56,118,236, 24,218,182,109,235,148,201, 50,153, 76,249, 13, 26, + 52, 0, 80, 22,205, 42, 40, 40,224, 1, 96, 68,122, 58, 86, 7, 4, 64, 32, 16,224,212,188,121,152,108, 50, 97,142,208,185,161, + 57,205,154, 53,163,103,207,158, 69, 82, 82, 18,204,102, 51,122,245,234,101,107,174, 28,198,223,223,127,252,225,195,135,125, 86, +175, 94,173,223,180,105,147,158,231,121,166, 89,179,102,202,230,205,155, 99,201,146,178,175,209,128, 1, 3, 48, 97,194, 4, 92, +186,116, 9,114,185, 28,237,219,183,231,166, 79,159,238, 59,110,220,184,119, 80, 54, 13,255, 1, 40,165,180, 91,183,110, 56,122, +244, 40, 88,150, 69,108,108, 44,114,115,173,147,123,224,231,231,103,111, 29,139,178,223,251, 19,185, 16, 9, 4, 2,154,144,144, +240, 89,199,142, 29,145,156,156,252, 98, 76, 76,204,151, 67,135, 14, 77,125, 88, 93, 79,119, 37,162, 27,134, 67,175,215, 67,175, +215, 35, 48, 48, 16, 69, 69, 69,184,117,235, 22,244,122, 61,252,124,157,153,119, 82,166,215,188,113, 61,171,158,175,175, 47,138, +139,139,145,152,152, 8,131,193, 0,111,111,199, 13, 22, 33,164, 86,183,110,221,126,251,238,187,239,188,214,175, 95,111,232,212, +169,147,248,203, 47,191, 36, 42,149, 10, 89, 89, 89,206,238,170,133,132, 99,199,142,133,116,237,218, 53,234,202,149, 43, 72, 72, + 72,128,193, 96, 64,243,230,205,113,227,198, 13,180,110,221, 26, 90,173,246,244,217,179,103,127,169, 94,234,241, 99,233,190,179, + 44, 71,143, 30,157,172, 82,169, 76, 0,236,206,244,115,148,123,247,238, 73,154, 54,109,170,151, 74,165,226,114,179, 86,163,232, +213,227,224, 97,103, 38, 86,133,191,191,255, 56,111,111,239,174,117,234,212, 65,102,102,166, 72, 44, 22,163,109,219,182,198,150, + 45, 91, 26,253,253,253, 29,154,112, 3, 0, 18,137,228,138, 72, 36,234, 80,118, 19,193,225,222,189,123,160,148, 78,104,220,184, +241,216,162,162, 34,228,230,230,138, 85, 42,149,245,102, 58, 42, 42, 10,122,189,254,138,163,250, 44,203,206, 12, 13, 13,157, 34, + 18,137,230,100,103,103, 63,144,222,129, 16, 34,142,142,142, 86,137, 68, 34, 24,141, 70,125,133,117, 79,213,184,183,135,193,118, + 12, 22,177,183, 99,142,116, 15, 58, 58, 6,139, 16, 2,131,193, 0,133, 66, 97,237,122,178,124, 23, 45, 99,123, 42, 26,172,154, + 80,171, 86, 45,196,197,197,201,182,109,219,182,105,209,162, 69, 39,106,162,177,227,187,111, 3,220,249,146, 90,105,167,119,227, +218,133, 63,240,227,229,252,156, 9,243, 22,191,247,210, 43,131, 50,109,183,235,191,236, 42,182,143,172, 94, 47,210, 87,209, 56, +200,207,235,200,231, 11,231,171,114,175,156, 68,122, 70, 6,118,159, 62,123,206, 64,233,101, 0, 19,106,210, 70,123,216,206, 70, +123, 90,190,168,182,105, 26,114,114,114,112,249,242,101,139,185,106, 14, 0,237,218,181, 59,111, 49, 89,231,206,157, 67, 76, 76, +204, 3,105, 26, 42,146,151,151,119, 95,105,153,242,116, 12,222, 22,163, 47, 16, 8,208,118,202, 20,167,205, 21, 33,132,114, 28, + 7,141,166,108,248, 74,219,182,109,107,100,174,202,181,218,150,148,148, 96,211,166, 77, 57, 55,111,222,172, 85,167, 78,157,113, +223,124,243,205, 98,185, 92,126,223,118, 37, 37, 37,232,218,181, 43, 70,143, 30,141,169, 83,167,242, 67,135, 14,101, 25,134,169, +180,130, 61,199,113,162,176,176,176, 67, 0,158,187,114,229, 10, 0,156,160,148,182,181,172,175,106,157, 3,240, 69, 69, 69, 66, +165, 82,105, 55,197,131,168,108,154,166,179, 93,122, 86,205,227,199,143,207,255,239,127,255,251,227,135, 31,126,104,141,206,213, + 80, 19,192,131, 17,172,158, 61,123, 66,167, 55, 33, 37,179, 0, 28,103, 70,169,209, 57, 35, 83, 49,130,213,179,103, 79,148,234, + 12,184,151,174,129,217,204,161,168,212,177,107, 56, 33, 68,254,252,243,207,239,219,178,101,139,255,201,147, 39,193,113, 28,127, +227,198,141,196, 62,125,250,168, 62,250,232, 35, 47,155, 49,166,206,178,116,208,160, 65,253,142, 31, 63,174,137,138,138, 82,159, + 62,125, 26, 89, 89, 89, 48,155,205,120,238,185,231, 32, 22,139,239,205,155, 55, 79, 4, 96,105, 77,196, 31, 53,150, 8,211, 31, +127,252,241, 72,140,149, 45, 98,177,184,198,221,140,207, 42,167, 79,159, 78, 29, 51,102, 76, 67,149, 74,181,164,125,251,246,157, +189,188,188, 24, 79, 79,207,132,160,160,160,177, 77,155, 54,189,235,168,142, 80, 40, 28,170, 80, 40,110,153,205,102,182, 60,114, + 14, 0, 48,155,205, 98,134, 97, 16, 22, 22,102, 13,154,196,198,198,194,223,223,159,187,122,245,234, 80, 71,245,179,178,178,238, +155, 85,104,135,145,109,219,182, 21,232,245,122, 36, 37, 37, 29,179, 93, 81,153, 23,121, 22,169,116,128, 10,195, 48,160,148, 66, +218,162, 5,210, 15, 28,192,247,223,127, 95,165,208,170, 85,171,128, 10, 33, 61, 66, 72, 87,219, 92, 25,150,217,130,111,189,245, +150,117,155,115,231,206, 89, 7,187,247,234,213,235, 62,205, 51,103,206, 60, 96,178, 42,106,218, 35, 43, 43,235,202,246,237,219, +207, 46, 88,176,224,116,149,141,182,163,105, 25,131,213,239,213,215,211,151,205,159,122,113,253, 47,135, 26,167,151,210,244, 9, +243, 22,127, 88,209, 92, 57,170,217,192,223,173, 65,176,175, 87,194,127, 23,206,119,183, 68,195,182,156,207, 40,128,153, 58, 96, +205,236,107, 86,134,109, 36,145, 16, 82,237, 69,203, 17, 77,103,169,168,105,155,166, 33, 61, 61,221,106,174,232, 63,137, 70,155, +183,107,215,238,124,185,185,178,172, 51, 87,165, 89, 25, 2,129, 0, 31,106,181, 16, 8, 4,232, 52, 99, 6,158,155, 53,203,225, +118, 90,224, 56, 14, 2,129, 0, 17, 17, 17, 78,155, 43, 91, 77, 74,233,241,139, 23, 47,134, 14, 25, 50, 68, 25, 17, 17,113,155, + 16, 34, 28, 54,108, 24, 31, 16, 16,192,156, 58,117, 10,148, 82,180,107,215, 14,153,153,153,224,121, 30, 27, 55,110,196,144, 33, + 67,200, 95,127,253, 69,121,158, 63,104, 79,211, 66, 82, 82,210,200, 46, 93,186,172,210,233,116,130,220,220,220,145,142,174,171, +110,223,183,111,223,126, 51, 34, 34,162, 35, 42, 79,197,192, 3, 56,249, 48,154,229,209,187,168,135,209,180, 80, 49,130,181,117, +235, 86,240, 60,143, 90,254, 30,208,235,245,168,104,102,171,211,172, 24,193,218,182,109, 27,120,158, 71,237, 0, 53, 12, 6, 3, + 44, 3,131,171,211,244,242,242,250,124,195,134, 13,193, 87,175, 94, 69, 74, 74, 10, 22, 47, 94,124, 55, 63, 63,191, 71,126,126, +190,100,250,244,233, 71, 94,125,245, 85, 63,158,231,171,236, 30,178,215, 78, 74,169,158, 16, 50,180, 77,155, 54, 27,103,207,158, +125,167,126,253,250,181,219,182,109,235,145,155,155,155,253,231,159,127, 38,174, 90,181,202,205,108, 54, 15,173,172,235,233,223, +248,189,219,146,154,154, 58, 3,101,215, 25,167,140,149, 35,237, 60,115,230,204, 39,229,218,103, 28,209,254,183,246,253, 97,103, + 38, 86,215,206,229,203,151,167,160, 66,126, 51,103,219,121,230,204,153,164,174, 93,187,206,242,243,243,155, 46,149, 74,145,157, + 93, 86,156,192, 18,105, 44,255, 27,180,104,209, 2,221,186,117,195,245,235,215,103, 77,153, 50, 37,169, 42, 77, 7,218, 32, 0, + 16, 14,224,141, 46, 93,186,124,212,175, 95, 63, 44, 95,190, 28,148,210,181,206,236,203,179,132, 37, 77, 3,177,125, 4, 0,147, +201,148,124,235,214,173,128,122,121,121,108, 32, 33,136,141,141,181,142,191,177, 29,151, 99, 25, 40,247,251,239,191,155,121,158, +175, 50,231, 20,199,113,201,199,143, 31,247, 59,112,224,128,208,242,143, 44, 31,172,201,167,165,165, 49, 71,142, 28,177, 70,195, + 4, 2, 1, 18, 18, 18,204, 70,163,241,158,179, 59,117,253,250,245, 71,114,247,246,251,165,164,177,251,118,255,228,221, 42,174, +125,190, 74,173,182,251, 3,182,100,124,175, 10, 34, 96,230, 44,152, 55,203,195, 98,174,182,158,207,200,215,233,185,206, 87,178, + 75, 46, 60,138,118,218, 82, 84, 84,148,100,153, 45,168,213,106,157, 62,118,143, 11,203, 12,194,128,128,128,243,168, 48, 91,208, +178, 46, 38, 38,230,129,117,206,192,243, 60,220,221,221, 1,192,118,134,170,195, 16, 66,168,165,203,186,188, 93, 15, 53, 6, 32, + 35, 35, 99,209,148, 41, 83, 94,152, 59,119,174,207,158, 61,123, 84,229,154,232,219,183,111,214,197,139, 23,219, 3,144, 20, 23, + 23, 31,156, 59,119,174,143, 77, 61, 66, 65,124,124,124,102,102,102,102,149, 21, 1,202,167, 53,119,113,118, 93,117,244,235,215, +239, 54,236, 36,252,124, 24, 30,135,166, 5, 77,126, 33,110, 39,165,150,215,162,228,193,221,205,180,142,155, 50,153,204,208, 20, +230, 86, 47, 98, 67, 94, 65, 17,110, 37,166,150,151, 6,227,192,113,105,229,122,101, 3,221,105, 94, 73,181, 26, 66,161,176,221, +146, 37, 75,122, 48, 12,195,156, 58,117, 74,191, 96,193,130,228,236,236,236, 94,148,210,123, 0, 64, 8,233,180,126,253,250, 77, + 14,164,100,176, 11,165,244, 50, 33,164,245,199, 31,127,252, 30,128,118, 0,106, 3,184, 7,224, 24,128,165,206,142,235,121,204, + 44,174,126,147,167, 82,187,198, 60, 43, 51, 19, 15, 30, 60, 56,163,119,239,222,130,144,144,144, 73, 33, 33, 33, 76, 94, 94, 30, +180, 90, 45, 24,134,129,191,191, 63, 26, 53,106, 4,127,127,127,254,202,149, 43,115, 63,254,248,227,106,115,234, 53,108,216, 48, +220,100, 50,213,101, 24, 38, 28, 64, 56,165, 52,156, 16, 18, 14, 64, 13, 0,177,177,177,170,208,208, 80, 65,171, 86,173, 16, 23, + 23,135, 35, 71,142, 96,199,142, 29,223, 80, 74,247, 89, 52,236,121,145,103,153, 74, 35, 88,121,121,121,221,122,244,232,113,128, +101,217, 48,224,193, 11,150,109,215, 30, 0,240, 60,159,148,153,153,105, 55, 9,153,173,230,216,177, 99, 15,176, 44, 27,102,137, + 76,153,205,102,189, 70,163,121,187, 83,167, 78, 43,132, 66,161,196, 86,151,231,249,187,153,153,153,255,106, 45,189,138,121,176, +186,245,232,157,243,176,154,110, 34,166,238,181, 95, 87, 35, 51, 43, 7, 91,207,103,228, 21, 25,184, 78,215,179,139, 47, 62,172, +174, 61,146,146,146,186, 63, 14,221, 71, 65,185,145,178,219,245, 87,213, 58, 7,201,118, 32,145,104,149, 53,228, 44,161,233, 71, +245,227,166,148, 94, 36,132,180, 25, 51,102,204,167,114,185, 60, 22, 0, 74, 74, 74, 78,165,165,165,205,178,204, 18,172,110,189, +139,202, 49,153, 76, 41,141, 26,148, 5,194, 44,233, 20, 44,193, 1,219,231,102,179, 57,197, 25, 61,123, 58,182,175, 57,142,171, + 82,143,101,217, 15,227,226,226,216, 15, 63,252, 48,115,207,158, 61,150, 2,183, 86,103, 86, 62,176,189,210,100,162,142, 80,110, +162, 22,148, 47, 46,158, 50,170,155,137, 88,211,155,200, 71,205, 79, 63,253,244,233,192,129, 3,215,171,213,234,111,195,195,195, +163,252,252,252, 84, 50,153, 12,122,189,190,200, 96, 48, 92,187,126,253,250,107, 83,166, 76,185,227,136,214,250,245,235, 89, 0, + 34,158,231,165, 12,195, 40, 0,168, 8, 33,158, 40, 55, 88,132, 16, 24,141, 70, 36, 37, 37, 97,242,228,201,220,161, 67,135, 22, + 2,152,230, 68,115, 91, 2,240,193, 63,231,113, 31, 0, 6,148, 37,158,205, 6,112,214, 9,173,127,133, 74, 13, 22, 45,203, 86, +237,112,214, 98, 71,168, 70, 51,228, 81,126,214,195, 48, 88,191, 96, 51, 86, 45,184,175, 14, 33,128,202, 95, 87,211,209, 87, 80, +106, 30,179,116,223,165, 69,122, 51,229,141,102,126,216,245,172,226,203,143,169,233, 79, 61, 85, 25,168,135,153,225, 70, 29,168, +223,231,160,206, 35,189,115,162,101,197,135, 7,215,116,189,139,202,201,206,206,174, 54, 23,213,147,208, 51, 24, 12, 99,219,180, +105,243, 5,199,113,255, 53,153, 76,199,170,255, 11, 23, 46,158, 28, 91,183,110,189,131,242,235,114,255,254,253, 89, 0,216,190, +125,187,211,179,123,135, 12, 25,194,209,178, 2,227, 58, 0,197, 0, 10, 81,150, 40,155, 0, 64,113,113,113, 94, 90, 90,218, 21, +142,227,174, 0,216, 84,131, 25,180, 62,132,144, 95, 41,165, 61, 1,192,242,220,246,189,167,141,154, 39, 9,250, 31,101,251,165, +127, 46,176, 21,141, 83,117,175, 43,227, 90,134, 54, 1, 15,121,199,234,194,133,139,103,131,242,174,192, 94,213,110,232,194,197, + 83, 70, 77,140,149,133,203,151, 47, 63,182,161, 0,207, 42, 53,155,166,231,194,133, 11, 23, 46, 92,184,112,225,162, 82, 8, 0, +187,211,193,157,156, 29, 80,233,148,242,202,168, 78,223,165,233,210,116,105,186, 52, 93,154, 46, 77,151,230,255,158,102, 13,137, +175,166,139,112,215, 99,248,204,135,195,118, 16,231,163, 94, 0,116,117,105,186, 52, 93,154, 46, 77,151,166, 75,211,165,233,210, +124,200,165,243,196,137, 19, 63, 65, 89,125, 98, 58,113,226,196, 79, 40,165,241,101, 54,134,198,255,203,109,113,104,113,141,193, +114,225,194,133, 11, 23, 46, 92, 60,237,156,152, 55,111, 94,201,188,121,243, 44, 3,218,179, 1, 16, 90, 22,189,170,114,134,248, +147,226,137, 25, 44, 66, 72, 32, 35, 16,189, 46, 20, 73, 58,131,242,141, 0, 0, 12,123,137, 51,232,126, 51,155,141,223, 82, 74, +211, 28,208,176, 59,227, 43, 10,104, 16,225, 33,251, 89,207,113,162,123, 69,134,254,215,202, 18,209, 61, 0, 45,183,225,149,209, +159,144,182, 82,177,120,191,216,195,195,110,118, 65, 67,126,126,169,206, 96,120, 97, 59,165, 14,151,226,113,225,194,133, 11, 23, + 46,158, 36,132, 16,133,167,167,231, 33,134, 97, 66,108,222,131,189,231, 0,192,113, 92,186, 70,163,121,129, 82, 90,105,218,162, +199,161, 89, 1, 3, 42,185,150, 63,173, 8,128,251, 74,170, 84, 91,193,186,126,128, 91,251,168,240,144,239,210, 50, 50,207, 23, +234, 12,195,175,165, 22,105,156,254, 80,145,244, 45, 15,111,255, 57,255, 25, 58,214, 43, 34, 50,138,212,170, 21, 4, 80,224, 94, +114,138,223,173,155, 55,186,108,219,176,244, 3,145, 84, 58,217,168,211,125,237,172,118, 4,160, 8,117,147, 28,253,122,226,171, + 30, 2,152, 49,104,246,119,123,120,173,177,246,141,178,105,163, 14,211,159,144,182,158,106,245,190, 5, 7, 14,200,148,205,154, +221,183,142, 82, 10,158,231,161, 61,127, 94, 54,177,123,247,125,253, 9,233,230, 50, 89,255,123, 16, 66,252, 85, 42,213, 56,161, + 80,216,201,104, 52,134,136,197,226,100,142,227, 18,242,242,242,150, 80, 74, 31,186,142,158, 11, 23,255,235,144, 42, 10,140, 87, +181,238,223, 64,169, 84,254,193, 48, 76,112,121, 91, 0,192, 90, 57,164, 98,158, 71,155,124,143,119,114,115,115,219, 84,166, 73, + 8, 9, 87,171,213, 43, 0,180,172, 46,209,113,249,253,253, 89,141, 70,243, 54, 45, 75,215, 98, 79, 79,233,233,233, 57,131, 16, +210,159, 97,152,106, 11,254,242, 60,207, 81, 74,183,231,229,229, 77,163,148, 22, 85,182,157,167,167,231,193,171, 87,175,182,244, +245,245,173, 54, 45,141,217,108,198,189,123,247,124, 98, 99, 99,127, 7, 80,105,102,237, 71,161,233,140, 23,121, 22,176, 87,139, +176,202,131,195,243,120,125,221,156,183,131,210,239,222, 12, 26, 57,119,115,100,125,111,121,167,171, 57, 37, 25,142,126,160, 88, +166,252,165,221,115, 61, 59,143,126,239, 67,197,159, 23,175, 97,255,145,147, 40, 44,214,131,101, 24,120, 40,229,136,140,172, 75, + 22,175,254,222,251,155,175, 22,255, 87,230,230, 17, 95,170,205,127,217,153, 29,114,151, 11, 38, 77,232, 19,171,240, 82,115, 0, +207, 97,124,143,104,197,164, 95,207, 79, 66,137,121,146,163, 26, 86,115,117,240,160, 60, 43, 51, 19, 11,189,188, 32, 48,153, 32, + 37, 4, 50, 66, 32, 5,224, 38,145,160,253,119,223, 97,206,174, 93,242,201,241,241, 46,147,245, 63,134, 82,169, 28, 26, 25, 25, +185, 96,205,154, 53, 94,117,234,212,129, 66,161,128, 70,163,241,190,126,253,122,179,247,223,127,127,176,187,187,251,148,130,130, +130, 85, 79,186,157, 46, 92, 60,173,148,103, 43,183, 91,188,189,170,117,255, 22, 12,195, 4,167,166,166,250,202,229,114,112, 28, + 87,158,189,159,183,222, 64,219,118,112, 80, 74,193,113, 28,234,215,175,111,172, 74, 83,169, 84, 46,207,202,202,234,106, 91,178, +172,170,142,146,212,212,212,174, 13, 27, 54, 92, 14,192,110, 66,109, 79, 79,207, 25,239,189,247,222,184,198,141, 27, 3,128,181, +157,150,199,156,156, 28,140, 25, 51,198,250, 25, 60,207,227,192,129, 3,239, 13, 29, 58, 20, 0,222,175, 98,223, 67,124,125,125, +201,200,145, 85,231, 26,154, 62,125, 58,166, 79,159,142,165, 75,151, 18,161, 80, 88,101,229,244, 71,165,233,168, 23,121, 22,112, +186,139,144,161,252,238,217, 75,214, 12,159, 57,164, 29, 89,247,126,215,136, 81, 75, 15,158,108, 24, 40,235,112, 57,173, 52,185, +218, 15, 19, 73,135,181,234,240, 98,167, 49,227, 38, 40, 54,255,116, 24,215,175, 92,192,213, 99, 91,238,219,166,197, 11, 67,145, +145, 83,132,161,163,199,187, 17, 86,208, 73, 36,149, 15, 51,234, 74,214, 57,210,182, 40,192, 47, 68, 34,126,183,117, 92, 35, 33, +106,167, 0, 20,104, 23, 83, 79, 88,107,223,223,239, 22,193,188,244, 26, 80,109, 45,193,138,230,106,243, 43,175,160,123,105, 41, +252, 80,150,211,194,178,148, 0,184,214,187, 55,234,255,248, 35,102,252,252,179,124, 90,175, 94, 78,155, 44,185, 92,254, 77,105, +105,233,103,212,249,132,107, 79, 12, 66, 72,164, 82,169,156, 92, 88, 88,248,250,147,110,139, 5, 66, 72, 0,128,236,138,119,195, +132, 16, 17, 0, 15, 74,169, 83, 21,127,165, 82,233, 91,131, 6, 13, 90,188,108,217, 50,121,102,102, 38,210,210,210,192,113, 28, +164, 82, 41, 34, 34, 34,200,193,131, 7,189, 38, 76,152,176, 72,165, 82, 73, 10, 11, 11,191,112,162,157,140, 80, 40, 28,162, 86, +171,123,251,249,249,249,102,103,103,103,231,229,229,237,212,235,245,235,106,122, 39, 95,174,249, 90,104,104,104,239,192,192, 64, +191,212,212,212,156,148,148,148, 95,244,122,253, 55,148,210, 26, 21, 80, 46,215, 13, 0,208, 20,128, 87,249, 91,233,161,161,161, +151, 18, 19, 19,157,171,158, 92,181,102, 90,104,104,232,101,103, 53, 9, 33, 10, 0,219, 0, 4, 86,179,105, 26,128, 1,180, 44, +193,177,139,127, 17,139,129,162,148,130, 16,114,159,145,170,106,221,191,141, 76, 38,195,150, 45, 91, 32, 20, 10, 33, 20, 10,145, +151,151,135,224,224, 96,235,107,145, 72,100,125, 94,187,118,237,106,245, 56,142,139,101, 89, 22, 90,173, 22, 28,199, 89,151,252, +252,124, 80, 74, 33,145, 72,192,113,101,101,151,108,214,199, 86,166, 71, 8,233, 31, 24, 24,136,205,155, 55,195, 96, 48, 60,176, + 94,165, 82,225,226,197,127,138,130,176, 44,139,184,184, 56,134, 16,210, 31, 85, 24, 44, 75,164,104,196,136, 17, 96, 89,214, 90, +250,206,242,220,178,112, 28,135,233,211,167,163,252,127, 85,229,190, 63, 14,205,103, 29, 82,190,147,148,218, 41, 19, 82,223,223, +237,237,110,157, 91, 45,148, 73, 68, 50,222,108, 2,103, 54,130, 51, 25, 32, 32, 28, 94,104, 26,128,214,117,228,200,214, 20, 98, +228,170, 51,133,169,169,250,184,139,185, 69,149, 26, 5, 66, 72,160,210,195,247,175,175, 54,254,228,189,255,228, 85, 92,186,112, + 30,231,247,172,176,187,109,215, 65, 19,209,176,105, 75, 52,169,231,143,143, 70,245,203,201,205, 74,139,182, 55, 38,171,226, 24, +172, 54, 74,209,198,101,175,117, 30,212,180,153, 7,131,142,229,215,171,131,102,156, 59,153,193,141,253,229,207,205, 39,139,140, +247,101,204,182, 55, 6,107,176, 68, 82,242,229,201,147,178,172,172, 44,108,126,229, 21,196,148,150, 34, 71, 40, 68, 3,147,201, +106,178,242, 1,228, 10, 4,240, 55,155,161, 83,169,224,255,253,247,224, 24, 6, 19,187,119, 47,221,104, 48, 60, 88, 93,182, 18, +220,220,220,178, 89,150,229, 10, 11, 11, 59, 61, 11, 38,171,220, 92, 29, 33,132,136, 10, 10, 10,212, 79, 65,123, 24, 0, 51,135, + 15, 31, 62,236,232,209,163,183,110,221,186,213,149,150,101, 18, 6, 33, 68, 80,183,110,221,195,237,219,183, 15, 95,187,118,237, +215, 0,102, 58, 98, 56, 8, 33, 65,117,234,212,249,243,210,165, 75,222, 55,110,220,128, 86,171,133, 80, 40,196,107,175,189,134, +239,191,255, 30, 34,145, 8, 18,137, 4, 34,145, 8, 29, 58,116,200, 73, 76, 76,108, 73, 41,189,235,128, 46,235,238,238,254,205, +138, 21, 43,234,245,234,213, 75,160,215,235,193,113, 28,182,111,223,110,154, 54,109, 90, 82,110,110,238, 27,206,154, 44, 66, 8, + 19, 16, 16,176,238,235,175,191,142,124,238,185,231, 4,165,165,165,224,121, 30,187,118,237, 50, 77,154, 52,233, 78,122,122,250, + 96, 74,169,211,137, 3, 9, 33,205,228,114,121,195,183,223,126, 59,187, 87,175, 94, 70, 0, 56,123,246, 44,115,225,194, 5, 85, +157, 58,117,238,126,250,233,167,231,107,160, 25,163, 84, 42,163, 70,142, 28,153,211,179,103, 79,147, 72, 36,226,143, 31, 63, 46, +184,126,253,186, 42, 52, 52,244,246,164, 73,147, 28,174,203, 73, 8,217,125,226,196,137,142,193,193,193,124,249, 73,157,150,191, + 79, 25,134,161,229,143,184,118,237,154,160, 99,199,142, 71, 40,165, 78, 69,193, 93, 60, 28,164,172,168,175,137, 82, 10,141, 70, +131,211,167, 79, 35, 62, 62, 30, 0,154,151,111,114,158, 82,138,194,194, 66,148,150,150, 34, 32, 32, 0, 0, 30,166, 76, 86,141, +240,240,240,200,204,206,206,246,253,249,231,159, 33, 20, 10,113,224,192, 1,172, 92,185, 18, 91,182,108,177,107,178, 2, 2, 2, + 16, 17, 17,145,146,150,150, 86,171, 50, 77, 55, 55,183, 2,173, 86,171, 42, 40, 40, 0,199,113, 56,125,250, 52,214,172, 89, 3, + 95, 95, 95,120,123,123,195,199,199, 7,177,177,177, 80, 40, 20, 86,147,213,190,125,251, 66,173, 86,235,110, 79,207,203,203, 43, +237,195, 15, 63, 12, 56,119,238, 28, 76, 38,211, 3, 8, 4,196,136, 0, 0, 25,215, 73, 68, 65, 84,235, 85, 42, 21,198,141, 27, +103,125,205, 48, 12,228,114, 57, 90,183,110,157,158,155,155, 91,233, 13,136,143,143, 79,122,118,118,182,255,133, 11, 23,238, 51, + 63,246, 12, 17,203,178, 80, 42,149, 8, 11, 11,203, 76, 79, 79,247,127,156,154,149,121,145,103, 21,107, 4,171,252, 68,213,201, +118,101, 84,168,255,228, 5,227,250,203,192, 25, 65, 77,165,128,177, 4, 48,106,193, 27, 74, 64, 68, 50,192, 84, 10, 31,137, 6, +219, 70, 71,169, 62,222,124,251, 74, 3, 31, 85,252,149,236,194,189,246, 62,136, 17,136, 94,235, 63,228, 61,175,148,172, 66,164, +102, 22,128,101,254,201,113,218,188,235, 16, 8, 88, 6,103,246,149, 5,170, 24,150, 69, 65,177, 30,249, 90, 35,250, 13, 25,167, +254,122,241,212,215, 0,124, 86,213,142, 52, 2, 34, 26,185,185,245,105,220, 40,132, 65,189,116,144,240,157, 0, 0,122,244, 37, + 52,203,243,101,235,239, 23,247,209, 22, 25,231, 94, 2,110, 84,165, 35,246,240,144, 41,155, 53,195, 2, 47, 47,244, 40, 45,197, + 45,129, 0,131, 52, 26,252, 62,110, 28, 4,235,214, 65, 0, 64, 63,108, 24,218, 46, 89,130,139,106, 53, 2, 11, 11, 97, 28, 54, + 12,226,115,231, 32,114,119,183, 59, 24,190, 50, 68, 34,145,113,205,154, 53,129,111,190,249,230, 17, 66,200, 83,109,178, 8, 33, +145,106,181,250,200,252,249,243,253, 62,253,244,211,244, 71,164,233,167, 80, 40,182, 23, 23, 23,143,115,246, 14,182,220, 92,205, + 94,181,106,213,168, 17, 35, 70,120,188,249,230,155,244,214,173, 91, 30, 0, 44,209, 16,159,246,237,219,215, 93,179,102,141,127, +203,150, 45,223, 27, 57,114,164,136, 16, 50,165, 58,147,229,230,230, 54,122,205,154, 53,222, 57, 57, 57, 86,115, 37, 20, 10,145, +146,146, 2,153, 76,102, 45,118, 46, 20, 10, 49,127,254,124,175,209,163, 71,143, 3, 48,174, 42, 77, 0,144, 72, 36, 67, 86,172, + 88, 81,175, 91,183,110,130,164,164, 36, 48, 12, 3,137, 68,130, 87, 95,125, 85, 88, 82, 82, 18, 50,115,230,204, 17, 0,236,223, +113, 84,130, 80, 40,124,109,245,234,213,145,109,219,182, 21, 92,189,122, 21,173, 91,183,198,153, 51,103,240,202, 43,175, 8,139, +138,138,194, 38, 76,152, 48, 28,192,106,103, 52, 9, 33, 1,114,185,188,241,111,191,253,150, 92,171, 86, 45,235, 13, 72, 88, 88, + 24, 23, 31, 31,175,185,122,245,106,212,201,147, 39,115, 91,183,110,237,112, 33,113, 66, 72,144, 92, 46,175,191,123,247,238,244, +153, 51,103,118, 89,181,106, 85, 47, 0,136,141,141,253,101,214,172, 89,135, 53, 26, 77,163,163, 71,143,106,218,183,111,239, 80, +205, 64, 0,129, 1, 1, 1,220,152, 49, 99,220,170,218,104,237,218,181,249, 0,106, 19, 66,234,208,178, 2,216, 46,254, 5, 40, +165,102, 66, 72,115, 66,200,249, 93,187,118, 33, 46, 46, 14,187,118,237, 66,124,124,252,249,242,245, 40, 40, 40,192,197,139, 23, +209,161, 67, 7,160,172,192,251, 19, 25,139,197,113, 28, 4, 2, 1, 82, 82, 82,176,118,237, 90,204,157, 59, 23, 17, 17, 17, 48, +153, 76,214,223,190, 64, 32,128, 80, 40,180, 68, 91, 28,186,232,155,205,102,156, 61,123, 22,223,110,220,136, 41,147, 39, 67,169, + 84, 2, 0,140, 70, 35, 52,121,121,144, 74,165,214, 8, 86, 85, 80, 74,183,223,188,121,115, 92,112,112,240,125, 93,131,150, 71, + 0,112,115,115, 3,207,243, 48,155,205,208,233,116, 88,188,120,177,153, 82,186,189, 42, 93, 75,108,130,101, 89,140, 27, 55, 14, +122,253, 63,245,193,155, 54,109, 10, 0, 8, 13, 13, 69,116,116,180,245, 53,195, 48, 85, 78, 10,179,213,252,186, 77, 99,148,218, +108, 29, 53,125, 17, 0, 32, 56, 56, 24, 81, 81, 81, 22, 83,109, 87,211,158, 23,121, 86, 17, 0,149,215, 95,187,146,152,241,217, +155, 19, 22, 45, 82, 72, 89,225,216,222, 77, 80,219, 67, 4,200,212, 16,117,248, 24,196, 35, 4, 0, 64, 53,119,128,253, 31,227, +191,125, 52,204,136, 77,186,159,234,170,213, 62,183, 52,154, 7, 6,215, 9, 69,210,206,225,245, 34,201,189,116, 13, 4, 2, 1, + 20,238,222,104,211,251,125,176, 44, 3, 55, 15,111, 16,174,212,186, 45,203,176, 16,176, 2,104,138, 74, 17, 90,167, 30, 35,145, +202, 58,163, 26,131,229,238, 46, 92,254,209,192, 54, 82, 70,154, 3, 4,138,255, 89, 17, 40, 6,227, 85,132, 15,187, 71,200, 70, +252,242,247,114, 20,152,186, 56,116, 96, 44, 17, 43,179, 25,191,143, 27,135, 46,171, 87,227, 20, 0, 33,128,152,213,171,113,109, +196, 8,248,154, 76,144, 0, 96,245,122,152, 43,244,217, 59, 2, 33, 4,189,123,247, 70, 78, 78,142,223,228,201,147,107,108,178, +100, 50,217,183,132,144, 30, 66,161,208, 72, 8, 1,195, 48,214,226,220,150,231, 70,163, 81,196,178,236,238,156,156, 28,167,187, +246, 8, 33,145,158,158,158, 71, 78,156, 56,225,167, 80, 40, 48,125,250,116,103, 37,236,105,250, 41,149,202, 83,195,135, 15,175, +253,237,183,223,238, 37,132,116,119,212,100, 85, 52, 87,171, 87,175,206, 95,187,118,237,215,182, 93,129,148,210,116, 66,200,186, +150, 45, 91,190, 61, 98,196, 8, 15, 0,163, 70,142, 28,137,234, 76,150, 68, 34,233, 20, 30, 30, 14,141, 70, 99, 61,193, 74, 36, + 18, 0,128, 66,161,128,187,187, 59, 68, 34, 17,244,122, 61,154, 55,111, 78,196, 98,113, 59, 71,218,172, 84, 42,123,244,233,211, + 71,112,252,248,113,100,100,100,192,221,221, 29, 10,133, 2, 28,199,225,173,183,222, 18, 45, 89,178,228, 69, 56,105,176,106,213, +170,213,171, 75,151, 46,130, 75,151, 46, 33, 49, 49, 17,122,189, 30,215,175, 95,135, 74,165,194, 27,111,188, 33, 90,176, 96,193, + 75,112,210, 96, 1,104, 60, 98,196,136, 76, 91,115,101, 65,161, 80,144,200,200, 72,141,151,151, 87, 12, 0,135, 13, 22,128,198, +239,188,243, 78,214,188,121,243, 58, 28, 60,120,240, 99,203,155, 7, 15, 30,156, 0, 0, 95,124,241,197, 81, 31, 31,159, 24, 0, +142, 26, 44, 80, 74,249,255,252,231, 63,119,197, 98, 49,132, 66, 33,196, 98,241,125,139, 72, 36, 2,195, 48,202,242,205,171, 29, + 28,252,172, 66, 8,105, 9,224,115,148,205,176,154, 76, 41, 61,253,132,155, 4,192, 90,188,189,121,124,124,188,213,100,237,217, +179, 7,221,187,119, 71,126,126, 62, 46, 93,186,100,107,174,158,212, 24, 44,240, 60, 15,161, 80,136, 69,139, 22,193,104, 52, 98, +211,166, 77,216,177, 99,199,125,231, 80,149, 74,133,165, 75,151, 58,213,157,197,113, 28,214,175, 95,143,143, 39, 76,176,154, 43, + 0, 16,137, 68,240,247,243,131,151,183, 55,110,223,190, 93,173,193,202,203,203,155,182,115,231, 78, 84, 53,200,125,231,206,157, +214,231,182,131,220, 29,105, 39,203,178,208,235,245,120,254,249,127, 74,185,190,243,206, 59,214,231, 26,141, 6, 44,203, 90,142, +133, 67, 7,128,101, 89,148, 82,160,183,244,159,247,122,124,248,161,245,121, 78, 78, 78,165,154,255, 11, 81, 43, 91,170, 28,131, +117, 35,171,120,153,128,164, 71,207, 27,243,194,144,218,190,238,160,218, 76,136,158,155,134,191,178,101, 88,180,120, 55, 0, 96, +252,171, 45,208,180,235,108, 24,190,121, 1,227, 90,179,226,215, 83,244, 31, 1,248,180,162, 22,165,124,253,224,160, 64,252,117, +235, 34, 4, 44, 11,177,187, 55,220,213,126,224,205, 6, 20,100, 37,226,200, 15,203, 1, 0,171,214,111, 7,195, 48, 16, 8, 88, +232, 13, 28, 34,106, 7,130,231,249, 74,103, 46, 0, 64, 3,160, 77, 39, 63,239,184,208, 80, 53, 65,195,124, 60, 80, 1,168,153, + 4, 17,105,110,164,181,155, 44, 54,175,160,176,205, 21,224, 68,117, 7, 70, 90,174, 18, 0, 64,180,110, 29, 78, 1,104,181,186, +236, 90,117,125,196, 8,184,173, 91, 7, 69,249, 54, 18, 66, 80, 88,205, 15,197, 30,150, 25, 43, 81, 81, 81, 88,181,106,149,223, +232,209,163,107,100,178,116, 58,221, 28,149, 74,213,101,221,186,117,126,125,250,244,121, 96,253,173, 91,183,208,161, 67,135,204, +140,140,140, 57,206,182,209,214, 92,121,120,120, 32, 57, 57,249,161,251,205, 45,230,234,192,129, 3, 33,193,193,193,104,222,188, +185,207,248,241,227,157, 49, 89,159,218,154,171,145, 35, 71,254, 13,192,151, 16, 82,209,160,144,242,117, 77,108, 76, 86, 1,128, + 5,149, 9,155,205,230, 16,133, 66,129,172,172, 44, 12, 25, 50, 4, 55,110,252, 19,240, 12, 12, 44,139,184,135,134,134,226,246, +237,219,240,241,241, 1, 33,196,215,145,125,246,241,241,241, 51, 24, 12, 24, 54,108, 24,146,147,255, 25,174, 24, 20, 20,100, 57, +166,222,142,232,216,226,231,231,231, 87, 90, 90,138,246,237,219, 67,167,211, 1, 0, 6, 12, 24, 0,161, 80,136,172,172, 44, 8, +133, 66,167, 53, 1,120,199,199,199, 87,154, 34, 69,165, 82, 25, 61, 61, 61, 27, 56,169,233,245,210, 75, 47,165,174, 94,189,250, +129,174,186, 51,103,206,188,172, 86,171, 15,170,213,234, 72, 39, 53,121, 91, 51, 37, 18,137,238, 51, 88, 66,161, 16, 12,195,212, +120, 12,218, 51,196, 66, 0,150, 89,109, 43, 1, 68, 63,193,182,220,135,173,201,218,179,103, 15, 26, 53,106,132,188,188, 60, 92, +189,122,245,137,155, 43, 11, 60,207, 67, 32, 16, 88,111,142,165, 82, 41,154, 55,111,110, 53, 87,132, 16,148,148,148, 64, 32, 16, + 88,206,215, 14,157,252,242,243,243, 17,224,239, 15,165, 82,137,122, 17, 17,184, 89,126, 30,177, 60,151, 72, 36, 32,132,192,108, +174, 58,112, 87, 62, 19,240,125, 84, 49,158,170,134, 80,160,204, 12, 85, 69, 96, 96, 32,120,158,183,156,243,171,139, 32, 56,164, +233,237,237, 13,173, 86,235,168,230, 51,141, 37, 77, 67, 71, 0, 71, 96, 51, 53,146, 16,194, 52,240,115, 91, 59,111,116,151, 33, + 47, 52,242, 70,105,118, 34,164, 74,111, 16,143, 80, 44, 90,188, 27,151,238,228, 2, 0, 22,125,247, 7, 54,207,236, 1,200,212, +136,114,207,129,191, 82,208, 7,118, 12, 22, 1, 37, 60,165, 16,176,101,253,177, 2, 1, 11,150,101,160,201, 78,199,146,105,163, + 0, 0,171,214,239,192,174,163, 87, 17, 28,222,200,218, 79, 11, 66, 0, 90,245,151,218,199, 93,180,106,116,223, 86, 50,226,145, + 15,120, 8, 31,220,192, 83, 4, 18,202,252, 95,123, 87, 30, 29, 85,149,167,191,251,222,171, 74, 45,169,164, 18, 66,165, 32, 36, + 4, 1,219,168, 96,156, 0, 14, 52, 25,150,145, 70,156,227,204,208,200, 34, 10, 2,129, 34,168,199, 33,216, 14,112, 20, 8,105, +192,214, 99, 88, 6,161, 33,131,136, 44, 42, 58,200, 98,219,224, 8, 39,172,118, 11, 97, 80,130, 1, 73, 32, 97, 73, 82, 73,165, +178, 84,146, 74,106,189,243, 71,213,171, 84,202, 90, 83,175,144,104,190,115,238,169,229,189,250,222, 93,235,125,239,119,127,247, +119,241,242,184,100,249,249, 35,109,219,127,104, 52, 63, 26,168, 98,100,132,184, 28,218, 57, 0, 98,183, 99, 98, 56, 44, 89, 12, +156,143,198,206, 85, 39,161,130, 23, 42, 10,133, 2,106,181, 26,235,214,173, 83, 47, 91,182,108, 47, 66,220, 24,154, 82,122,141, + 16, 50,110,193,130, 5,133,117,117,117,234,180,180, 52, 40, 20, 10, 40, 20, 10,104,181, 90, 76,157, 58, 85, 91, 93, 93,221, 85, +235,216,238,172,172, 44,181, 88, 44, 70,105,105, 41,122,245,234,229, 18,134, 93, 1, 33, 68, 29, 27, 27,251,183,175,191,254, 58, +117,240,224,193,184,122,245, 42, 30,121,228, 17,236,223,191, 95, 53,115,230,204,160, 68,150, 76, 38,155,236, 20, 76,208,104, 52, +113, 26,141,102, 44,128,177,129,174,173,209,104,226,114,114,114,254, 21,126, 4,150, 72, 36,186,173,215,235,251,200,100, 50, 28, + 56,112, 0, 10,133, 2,114,185, 28, 73, 73, 73,208,235,245,144,203,229,160,148,194, 98,177,240,127, 18,117,193,148,187,182,182, + 86,107,179,217, 82,142, 30, 61,138,218,218,142,152,120,169,169,169,112,250,107, 4, 27, 11,198,133,202,202, 74, 45, 33, 36,229, +210,165, 75, 40, 47, 47,199,164, 73,147,112,240,224, 65, 12, 31, 62, 28, 0, 96, 50,153,186, 18,124,207,198,178,172,207, 63, 61, +231, 19,103,188,144,156,112,220,180, 66,226,180,219,237,118, 94, 92,185,191,186,139,174, 0,215,252,165,192,221,119,231,103, 11, +121, 16, 8,147, 38, 77,130, 94,175,135, 66,161, 8,120, 3,190,151,224, 45, 88,171, 87,175, 70,118,118, 54,212,106, 53,150, 46, + 93, 10,142,227, 92,201,125, 38, 32, 20, 36,170,213,126,143,243, 62, 88,254, 64, 8,137, 81, 42,149,171, 25,134,153,198, 6, 81, +113, 54,155,205,102,183,219, 63,109,108,108,244, 27,166,129,119, 72, 15,166, 45,220,235, 32, 64, 94,195,230,244,166, 69,186, 51, +248,210, 21, 58, 77,115,133, 64,135,184,250, 83,246,248, 57, 19,135,196,227,240,241,191, 67,108,110, 0, 76, 62,219, 11,176, 89, + 64,196,209, 80, 43, 69,201,222, 14, 19,134,189,122,231,110, 37, 18,226, 21, 78,113,229, 76, 12,131,244, 33,142,135,215,191,156, + 46, 65,242,192, 33,224, 88, 22, 28,203, 66, 33,147, 64, 91, 93, 5,142, 99,174,250,186,236, 80, 22, 83,166, 60,148, 50, 64,157, + 24, 5, 12,245, 51, 0,134,197, 32,185,111, 20,158, 74,144,166, 14,101, 49,197, 95,165, 80, 74, 33,113, 10, 44, 3, 0,211,188, +121,200, 40, 40,192, 53,141, 6, 55, 53, 26, 60, 80, 80, 0,204,155, 7, 59, 58, 86, 21, 6, 26, 40,222,192,119, 68, 94, 8,173, + 88,177, 66, 91, 87, 87,247, 66,200, 68,142, 60, 95,171,175,175, 31,247,198, 27,111,104,117, 58, 29,228,114, 57,170,170,170,194, + 18, 87, 0, 96, 52, 26,103, 23, 20, 20,104, 11, 11, 11,161, 80, 40, 16, 19, 19,211,101,129,197, 91,174, 86,173, 90,213, 63, 37, + 37, 5,101,101,101, 80, 42,149, 72, 72, 72, 64,122,122, 58,206,158, 61,171, 74, 73, 73, 57,234, 92,101,228, 47, 79,135, 10, 10, + 10, 26, 0,160,160,160,160,129, 16,114,146, 16,178,141, 16,242,103,143,180,141, 16,114,210,253, 92,163,209,248,185, 63,110,147, +201,116,178,164,164,132,202,229,114,176, 44, 11,179,217, 12,169,212, 97,235,102, 89,214,229,152, 11, 0, 78,199,211, 51,193,148, +221, 96, 48,252,245,131, 15, 62,176,164,164,164,224,177,199, 30,195,176, 97,195, 48,106,212, 40,164,166,166, 98,245,234,213,166, +150,150,150,191, 6,195,227,142,202,202,202,191,236,223,191,223,146,146,146,130, 97,195,134, 65, 34,145, 32, 61, 61, 29, 73, 73, + 73, 88,183,110,157,169,177,177, 49,100, 78, 0,183, 46, 95,190,236,243, 31, 82, 38,147,197, 34,136,213,184, 30,184,125,254,252, +121,118,228,200,145,135, 61, 15, 60,241,196, 19,135, 21, 10,133, 18, 64,168,126,125,212, 93, 84, 73, 36, 18, 87,226,191,231, 56, +238,215, 96,193, 90, 12,224,123, 0,101, 0,150, 6, 56,247,158,194,125,181, 96, 93, 93, 29, 74, 74, 74, 80, 84, 84,132,145, 35, + 71,226,204,153, 51,128, 35, 76,131,223,177, 30,225,252,129, 82, 10,145, 72,132,180,180, 52,228,228,228,224,203, 47,191,196,181, +107,215, 96,177, 88, 92, 2,136,247,185, 12,197,130, 37, 22,139,161, 86,171, 97,177, 88, 92,214, 43, 0,184,254,227,143,224, 56, + 14,118,187, 29, 38,147, 41,160, 5, 75,169, 84,174,222,177, 99,199,171, 58,157,174,111,109,109,109,162,123,210,106,181,137, 85, + 85, 85,137,119,239,222, 77,188,125,251,118, 98, 69, 69, 69,226,205,155, 55,251,190,253,246,219,175, 42,149,202,213,193,228,147, +101, 89,164,167,167,227,149, 87, 94,113,165,247,222,123,207,149, 10, 11, 11, 59,140, 29, 65,130,101, 89,164,229,190,139,127,169, +165,174,244,165,138,184, 82,241, 31, 22,250,227,236,164, 69,186, 59, 60,157,220, 1, 0, 15,247,145,175,249,211,130, 49,115,126, +247,136, 18,135,142, 95, 64,222,231, 55,174,254,102,142, 42,109,112,124, 45,236,181, 37,248,195,243,195,241,238,190, 11, 0, 28, + 83,132,246,154, 98,208,250, 50,208,152, 20,220,212,235,188, 78, 47, 88, 77,109, 39,110,148,254, 56, 62,109,232, 8,166, 90,215, +220,105,133, 65,198,184,169, 32,132,160,223,192, 33, 96, 57, 14, 44,203,128, 99, 89,196,197, 74, 81,114,233,146,189,221,104, 60, +225,141, 51, 3,224, 18,100, 81,155,159,127, 42, 93,138,190,205,128, 76,226, 58, 70,111, 76,237,124,178,140, 3,134,198, 96,238, +221, 4,217, 9,109,219,102, 81,139,249, 48,128,159, 46,203,128,227,169, 38, 70, 34, 65, 43, 0,157, 72,132, 81, 27, 55,226, 71, +141, 6, 49, 59,119,130,133,195,139, 90,181,113, 35, 12,187,119,131,177, 90, 65,165,210,176, 44, 88, 90,173, 22,211,167, 79, 15, + 75, 8, 1, 29,150,172, 69,139, 22, 21,174, 91,183, 78,189, 98,197, 10,193, 56,151, 46, 93, 90,184,111,223, 62,245, 3, 15, 60, +208, 85, 42, 40, 20,138,255,180,219,237,113,239,188,243, 78,117,126,126,126,167, 39, 67,190, 46, 76, 38,147, 36, 46, 46,238, 93, + 0,227,253, 80,229, 45, 92,184, 80, 12, 32,219,105,201,122,108,225,194,133,231, 40,165,111,186,159, 68, 8,201,221,190,125,251, +116,183,169,196,109, 0, 54,250,203, 99, 83, 83,211,159,115,114,114,230,157, 58,117,170,183, 84, 42, 5, 33, 4, 98,177, 24, 15, + 62,248,160,211,242,234,112,120,165,148,226,181,215, 94,211,213,212,212, 4, 21,166,161,189,189,125, 87, 94, 94,222,120,163,209, +152, 58,119,238, 92,113,124,124, 60,180, 90, 45,214,175, 95,111,218,181,107,215,237,150,150,150, 80,125,165, 96,177, 88,118,173, + 92,185,114, 92,115,115,243,192,249,243,231,139, 27, 27, 27, 97, 52, 26,241,250,235,175,155,118,238,220,121,199,104, 52,134, 28, +168,119,212,168, 81,165, 21, 21, 21,153,173,173,173,245,114,121,231, 5,177, 34,145,136, 68, 71, 71,143, 0,176, 59, 20,206,140, +140,140,178, 91,183,110,141, 92,179,102,205, 73,139,197, 34,250,246,219,111, 93, 78,238,155, 55,111, 46,148, 74,165, 79, 34,116, +103,124,187, 68, 34,233,100,177,242,124,207,113,220, 47,222,130, 69, 41, 45,132, 35,244,197,125, 5, 79,113, 85, 92, 92,140,241, +227, 29, 67,250,204,153, 51, 24, 61,122, 52,206,156, 57,131,204,204,204,159, 53, 76, 3, 47,176, 56,142,195,204,153, 51, 49, 97, +194, 4,244,239,223,223, 53,206,221,157,220, 67, 17, 25, 86,171, 21, 67,135, 14, 69,187,201, 4,177, 88,236,154,130,228, 56, 14, +170,196, 68,148,150,150, 6,101,193, 98, 24,102,218,228,201,147,153, 43, 87,174, 96,198,140, 25,216,179,103,143,207,115,103,205, +154,133,143, 63,254, 24,147, 39, 79,102,150, 47, 95,238, 55, 76, 3,239, 92, 30, 76,153,248,251,116, 32, 11,158, 80,156,238, 90, +164,187,195, 91,160, 81, 12, 84,201,231, 78,120,144,195,161, 19, 23,144,119,232,214, 46, 27,165, 7, 14, 92,172,255, 98,233,104, +192,252,233,243, 72,159,186,219, 49, 45, 8,192, 94, 83, 12,243,167,179, 64,228,189,113,250,174, 8,141, 70,179,215, 29,173,173, + 86,243,158,131,123,183,228,140,220,154,169,234,155,168,132,190,209,232, 18, 89, 23, 11, 63, 3, 0, 76, 89,184, 22, 28,235,152, + 58,140, 85, 72, 33, 19,179,248,159, 15, 55,233,204,230, 54,175,189,202, 46, 98,178,231,255,246, 65,165, 82, 73,129, 71,197,157, +142,145,129, 14,206, 78, 66,235, 31,226,209,187,184, 30,207, 15, 86,196,110,188,210,144, 13, 96,179, 39,167,169,161,193,104, 40, + 42,146,253,211,222,189, 40,249,253,239,209,207, 96, 64,113,124, 60, 84, 86, 43, 20,112, 90,171,118,238,132, 97,207, 30, 72,173, + 86, 64,169, 68,221,150, 45,176, 94,190, 12,107, 83,147,209,147,207, 31, 8, 33,184,126,253,122,216, 86, 38,119,240,130,104,217, +178,101,123,235,234,234, 94, 16,146,115,246,236,217,133,199,143, 31,247,111,247,246, 3,131,193,176, 4,192, 18, 1,242, 99, 39, +132,188,233, 12,104,151,173,209,104,226,206,159, 63, 63,143, 16,178,149, 82, 90, 5, 0,132,144,196,172,172,172, 5, 30,226, 42, +224, 42, 66, 74,233, 45,133, 66,241,199, 37, 75,150,172,205,207,207, 87,240, 14,237,223,125,247, 29,172, 86, 43, 68, 34, 17,108, + 54, 27,178,178,178,154,235,234,234,222,245, 21,129,217, 11,175,149, 16, 50,107,237,218,181, 89,155, 54,109,122,134,101, 89,149, +205,102,171, 53, 26,141, 71,141, 70, 99, 65, 87, 86, 81, 57,235,225,197, 21, 43, 86,188,184, 97,195,134,201, 12,195, 36, 90,173, + 86,157,193, 96, 56, 98, 52, 26,187, 20, 91,235,220,185,115,181, 91,183,110,189, 81, 91, 91,251,112,114,114,114,163, 66,161, 48, +153, 76, 38, 86, 38,147,197, 70, 71, 71,103, 0,248, 6,192, 15,161,112, 22, 21, 21, 85,111,219,182,173,188,189,189, 61,109,219, +182,109,167, 99, 99, 99,143, 19, 66,136, 88, 44,142,151,201,100,227, 1,156, 4,112, 61, 20, 78,134, 97,236,238,214, 42, 79,255, +171,168,168,168, 95,139, 15,214,125, 7,103,152,134,139,148, 82,232,116, 58, 92,185,114,133, 23, 87, 25, 0,144,153,153,121,145, + 23, 89, 69, 69, 69, 24, 54,108,216, 69, 66,200, 61, 15,211,224,110,193,226,133, 84,255,254,253, 93,159,221,147,155, 15, 86, 80, +176,217,108, 16,139,197,224, 56, 14,125,147,146, 92,215,162,148,162,180,180, 20,122,189, 62, 40,129,197,178, 44, 75, 8,193,140, + 25, 51,130,186,238,115,207, 61,135,147, 39, 79, 34,152,233, 68, 39, 63, 6, 12, 24, 16,240, 28, 39,130, 18, 62, 44,203, 34, 57, +217,235, 68, 86, 80,156,238, 90,164,187,195,171,147,123, 89,141,113,205,172,245,103,151,255, 80,221,118,160, 68,219,154, 3,128, +126, 90, 44,255, 42, 93,197, 78,156,248,208, 29,180, 23,100,130,196, 58,130,174,209,230, 42,144,104, 53,238,216,251, 33,247,240, +213,106, 43,136, 87,255, 22, 74,105,165, 88, 42,127,243,195, 29,155,243,179, 22,189,166, 40, 46,211,162,177,185, 29, 44,219,209, +105,121,231,246,216,104, 41, 82,250, 40,177,239,191,215, 27, 12, 77, 13, 43,188,197,192, 2,128,212, 24,177,230,201, 17,131, 37, +232,211, 2,180, 73,129,182,142,206, 74, 47,253,187,227,141,193,195, 72, 53, 36, 14, 79,223,106,145, 30,188,213,162,129, 23,129, +213,102, 50, 77, 92,254,244,211,199,214,124,241,133,252,225, 3, 7,160,125,246, 89, 36, 53, 53, 65, 2,116,242,201, 98, 44, 22, + 64,169,132,110,207, 30,180,218,108,200,159, 59,183,181,205,108,126,202, 71, 61,123,133,197, 98, 17,143, 29, 59, 86, 48,113,197, +195,201, 21,146, 31, 87, 48,156,132,144,113, 19, 38, 76, 40,164,148, 74, 2,255, 34,178,112, 19, 89,230,243,231,207, 47, 56,125, +250,116, 25, 58,111,248,217,112,250,244,233,178,249,243,231,147,247,223,127,127, 39,128,149,193, 6,222,108,110,110,222, 28, 23, + 23,135, 49, 99,198,172,124,235,173,183, 18,134, 15, 31,142,196,196, 68, 24, 12, 6, 20, 21, 21, 97,241,226,197,250,166,166,166, +183,234,235,235,243, 67,204,179, 13, 14, 75, 77,200,214, 42, 63,156,118, 0, 31, 56,147, 32,120,233,165,151,190, 43, 43, 43,171, + 83,169, 84,255, 40, 22,139, 31,131,195,207,167, 26,192, 78,132, 40,132,120,100,103,103, 95, 42, 43, 43,211,245,235,215,111,164, +147, 51, 14,192, 93, 0, 59,186,192, 89,121,225,194,133,228, 17, 35, 70, 48, 34,145,136,178, 44, 11,145, 72, 68, 57,142,163, 78, +191, 25, 10, 0, 71,142, 28,145, 0, 8,121, 43,175, 30,132, 7,247, 48, 13, 85, 85, 85, 46,113,229, 22,104, 52, 35, 51, 51,243, +162, 83, 92,241,199,126, 22,255, 49, 74, 41,242,242,242,176,125,251,118, 4,138, 64,238, 92,173,231,215,140,195, 91,170,120,241, +100, 54,155, 81, 92, 92, 12, 66, 8,108, 54,155,107, 90,144, 15,209, 96,181, 90,253,174, 62,183,217,108, 54,147,201,132, 79, 62, +249, 36, 40,145,245,209, 71, 31,161,173,173, 13,182, 0,202,205, 61,164,194,227,143, 63, 14,189, 94,239, 90,196,147,145,145,225, + 58,207,108,246, 27,184,222, 39,103, 90, 90, 26,116, 58, 29,122,247,118,172,179, 73,153,173,113,157,103,109,249,245,196,253, 37, +193,134, 22,120, 60, 46, 78,217, 30,101,249,252,223,134, 72,198, 77,203, 80, 98, 96,159, 24,136,196, 82, 84, 54, 89,241,245, 15, + 77,216, 81, 88,125,219,104,177, 61,115,173,166,229,178, 63, 30,105,180,242,232,240,223, 78, 24, 61,123,193,226,232,230,118, 27, +202,203, 43, 80, 91, 83, 5,134, 48,232,219, 47, 25,169,169, 3, 32,139, 98,176,167, 32,191,229,226,185,227,103, 13, 77,250, 73, +190,184,158,137,139, 58,183,225,217,209, 35, 7, 13,138, 33,176, 90, 0,155, 5,176, 90, 0,187,243,149,255,206,222,185,175, 93, +185,210, 64,151,255,159,254,111, 95, 52,152,188,238, 41, 53,141,144,209,241,241,241,199,242, 14, 29,146,219, 77, 38,152,230,205, +131,172,189, 29, 50, 66, 64, 40, 5, 3,128, 72,165,168,219,178,197, 33,174,230,204,105,109,104,108, 12,121,171, 28,149, 74,245, +129, 78,167,235,118,145,220, 19, 18, 18,222,232, 74,184,135, 72,193,185,146,175,129, 15, 50,234,246, 61, 7, 64,197, 91,181,186, +192, 59, 64,165, 82, 45,103, 24,102, 20,165, 52,129, 97,152,122,187,221,254, 77, 77, 77,205,219,148,210, 82, 33,242,222,131,208, + 65, 58, 34,185, 7,154,175,174, 1,240, 31, 0, 12,148,210,242,136,103,172, 7,157,192, 79, 19,194,203,106, 65,127,199,238, 21, + 18, 18, 18,254,126,236,216,177,225, 3, 7, 14,100,220,221, 21,248, 88,119,252, 52, 22,199, 57,236, 16,167, 78,157,178,206,152, + 49,227,155,234,234,234, 49,190, 56, 99, 99, 99,191,250,254,251,239,127,215,216,216,248, 19, 33,229, 30,217,157,255,220,210,210, +130, 69,139, 22,253,111, 83, 83,147,215,173,114,226,226,226, 54,228,231,231,191, 58,101,202, 20,134, 15, 43,225,158,168,115,129, + 21,159,204,102, 51,118,239,222,109,223,180,105,211,127, 53, 52, 52,248,156, 34, 76, 74, 74,186, 93, 89, 89,153,204,135, 76,240, +149,220, 49, 96,192,128,170,242,242,114,159,193, 75, 35,193,217,221, 17,180,192, 2, 28, 43,136,210, 18,163,167, 83, 96, 26, 3, +251, 80,134,144, 40, 43,197, 53, 80,124, 37,231, 90,183, 22, 85,210,160,166,200,196,114,249,203, 49,138,248, 85, 83, 94,120, 37, + 97,192,160,223, 16,117,223,126, 32, 96,160,173,190,139,138, 27, 63,210,207,247,110,169,107,105,210,175,110,109,109,222,226,143, +231, 97, 66, 6, 15,138, 21,239,143,178,225, 33,240,229,240,216, 63,202, 19, 20,128, 89,196, 92,189, 97,176,204, 40,241,115,147, +228, 69,214,202,207, 62,147,115,143, 62,250,147, 0,111,118,187, 29,214,203,151,145, 63,119,110,151,196, 85, 15,122,208,131,240, + 64, 8, 25,136,192, 49,174, 44, 0,238,252, 92, 22,146, 95, 59,200,125,188,217, 51, 33, 36,186, 87,175, 94,199, 89,150, 77,117, +126,238,228, 19,196,191,231, 95,237,118,123,185, 86,171,125,146, 82,218,234,135,115, 80, 76, 76,204, 22,155,205,246, 68, 32,159, + 37, 74, 41, 88,150,253,214, 96, 48,188,236,203,213, 32, 82,171, 8,123,247,238, 93, 90, 81, 81, 49,136, 95, 21,237,126,175,244, +172, 7, 0,184,126,253, 58,198,142, 29, 91, 81, 85, 85,229,115, 62, 49, 18,156,221, 29, 33, 9, 44, 65, 47, 76, 72,146, 88,162, +120, 49, 74, 38,253,103,187,197,154, 6, 2,112, 34,209, 85, 83,155,241, 68,187,177,249, 67, 95,211,130, 30, 28, 97, 5,100,162, + 1, 10, 63,141,144,209, 18,177,248, 43,177, 82, 41,243,118,170,181,169,201,216,102, 54, 79,236, 17, 87, 61,232, 65, 15,122,208, +131,238, 2,226,216,153,227,152, 72, 36,146, 56, 63,187, 31,251,201,249, 86,171,181,173,182,182,118,146,191,217,150, 72,112,118, +123,240, 74, 51,216, 4,167, 46, 9,242,220, 9,193,114, 58,211,216,251,157, 51,130,101, 15,200, 29, 2,231, 88, 39,103,110, 55, +201,167,144,109, 36, 40, 39, 58,116,120, 80,188,161,112, 6,219,167, 66,204,103, 80,253,254,126,224, 12,178, 61,187,146, 79,191, +220, 93,108,247,220,110,146, 79, 33,219, 72, 16, 78,207,254, 19, 12,111,168,156,193,244,169, 46,228, 51, 96,191,191, 95, 56,131, +104,211,174,230,211, 39,119,176,125,201, 71,219,231, 6,250,237, 47, 33,249,141,228,238,137, 72,121,246, 83,103,120,124, 39,191, + 32,161,242, 35,193,201,131, 8,188, 17,165,144, 92, 78, 20, 10,205,233, 81,159, 66, 33,151, 58, 86,140,156, 68, 16,129, 66,131, + 68, 33,237, 88,133, 18, 86, 29,120,148, 85, 16, 94,119, 78,161,234,210,157, 71,168,126, 31,105, 78,247,239,194,233,171,158,156, + 66,244,123,111,237, 46, 36,167, 80, 99,201,227,247,130,140,165, 72,244,121, 47,253, 39,108, 94, 79, 78, 33,198,146, 39,167, 16, +253,254, 94,112,242,223,135, 51,150,188,113, 10,209,239,125,181,125,184,188,221, 5, 33, 69,140,140,100,197,144, 8,108,240, 40, +180, 16,226, 57,133,228,227, 57,137, 35,130,237,125,207, 9, 97,219, 40,215,201,153, 43, 32,231, 56,161,218, 40, 18,253,221,157, + 83, 40,126, 79, 30, 33,218,201, 27,103,184,249,245,145,207,176,224,141, 51,220,126,127,175, 56, 33,108, 27, 9, 50,150, 60, 56, + 5, 27, 75,158,229, 37,132,228, 10,201, 41,212, 88,242,146,207,176,219,201, 27,103,184,249,245,145,207,176,224,141, 83,136,123, + 72,164,120,187, 3, 66,178, 96, 69, 10,145, 16, 66, 64, 71, 60, 13,161,111,100, 66,138,172, 72, 89,218,132,178,226,120,225, 61, + 41, 32,157, 96,214, 38, 30,206,252, 9,242, 68,219, 29,209, 51,150,122,198, 18,238,179,177,228,173,223, 80, 74,115, 9, 33,171, +132,228, 12, 23,158,156, 66, 9, 33, 47,101, 15,107, 44,121,254, 86,136,177, 20,128, 51, 44, 11,179,175,242,135,195,219, 93,208, +245, 77,229, 4,134, 83,213, 10,246,103,235,198, 39,168, 85, 76,104, 68, 40,159,227,186, 67,217, 17,129,124, 18, 66,114, 35, 84, +246,238, 82,167, 61, 99,169,103, 44, 9, 2, 33,199,146, 71,159, 20, 36,175, 66,247,115,111,156, 66, 92,195,157, 67,168, 62, 26, +233,178, 11, 57,150, 34,209,246,221, 5,255, 15,195, 78,238,106,137,168,169,119, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, 0}; diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 50f838b8745..e8c99a51bf8 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -33,7 +33,7 @@ DEF_ICON(ICON_BLENDER) DEF_ICON(ICON_QUESTION) DEF_ICON(ICON_ERROR) -DEF_ICON(ICON_BLANK1) // XXX this is used lots, it's not actually 'blank' +DEF_ICON(ICON_CANCEL) DEF_ICON(ICON_TRIA_RIGHT) DEF_ICON(ICON_TRIA_DOWN) DEF_ICON(ICON_TRIA_LEFT) @@ -66,9 +66,9 @@ DEF_ICON(ICON_VIEWZOOM) DEF_ICON(ICON_ZOOMIN) DEF_ICON(ICON_ZOOMOUT) DEF_ICON(ICON_PANEL_CLOSE) -DEF_ICON(ICON_BLANK009) +DEF_ICON(ICON_COPY_ID) //ICON_BLANK009 DEF_ICON(ICON_EYEDROPPER) -DEF_ICON(ICON_BLANK010) +DEF_ICON(ICON_LINK_AREA) //ICON_BLANK010 DEF_ICON(ICON_AUTO) DEF_ICON(ICON_CHECKBOX_DEHLT) DEF_ICON(ICON_CHECKBOX_HLT) @@ -83,7 +83,7 @@ DEF_ICON(ICON_DOTSUP) DEF_ICON(ICON_DOTSDOWN) DEF_ICON(ICON_LINK) DEF_ICON(ICON_INLINK) -DEF_ICON(ICON_BLANK012b) +DEF_ICON(ICON_PLUGIN) /* various ui */ DEF_ICON(ICON_HELP) @@ -105,13 +105,13 @@ DEF_ICON(ICON_STYLUS_PRESSURE) DEF_ICON(ICON_GHOST_DISABLED) DEF_ICON(ICON_NEW) DEF_ICON(ICON_FILE_TICK) -DEF_ICON(ICON_CANCEL) +DEF_ICON(ICON_QUIT) DEF_ICON(ICON_URL) DEF_ICON(ICON_BLANK037) DEF_ICON(ICON_BLANK038) DEF_ICON(ICON_BLANK039) DEF_ICON(ICON_BLANK040) -DEF_ICON(ICON_BLANK040b) +DEF_ICON(ICON_BLANK1) // Not actually blank - this is used all over the place /* BUTTONS */ DEF_ICON(ICON_LAMP) @@ -127,7 +127,7 @@ DEF_ICON(ICON_SCRIPT) DEF_ICON(ICON_PARTICLES) DEF_ICON(ICON_PHYSICS) DEF_ICON(ICON_SPEAKER) -DEF_ICON(ICON_BLANK041) +DEF_ICON(ICON_TEXTURE_SHADED) //ICON_BLANK041 DEF_ICON(ICON_BLANK042) DEF_ICON(ICON_BLANK043) DEF_ICON(ICON_BLANK044) @@ -251,7 +251,7 @@ DEF_ICON(ICON_GROUP_UVS) DEF_ICON(ICON_BLANK089) DEF_ICON(ICON_BLANK090) DEF_ICON(ICON_RNA) -DEF_ICON(ICON_BLANK090b) +DEF_ICON(ICON_RNA_ADD) /* available */ DEF_ICON(ICON_BLANK092) @@ -690,7 +690,7 @@ DEF_ICON(ICON_UV_VERTEXSEL) DEF_ICON(ICON_UV_EDGESEL) DEF_ICON(ICON_UV_FACESEL) DEF_ICON(ICON_UV_ISLANDSEL) -DEF_ICON(ICON_BLANK239) +DEF_ICON(ICON_UV_SYNC_SELECT) DEF_ICON(ICON_BLANK240) DEF_ICON(ICON_BLANK241) DEF_ICON(ICON_BLANK242) @@ -801,8 +801,8 @@ DEF_ICON(ICON_BLANK303) DEF_ICON(ICON_BLANK304) DEF_ICON(ICON_BLANK305) DEF_ICON(ICON_BLANK306) -DEF_ICON(ICON_BLANK307) -DEF_ICON(ICON_BLANK308) +DEF_ICON(ICON_BACK) +DEF_ICON(ICON_FORWARD) DEF_ICON(ICON_BLANK309) DEF_ICON(ICON_BLANK310) DEF_ICON(ICON_BLANK311) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index dfe21171928..a9f8fe2bd6d 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2266,11 +2266,11 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) uiBlockSetHandleFunc(block, do_running_jobs, NULL); if(WM_jobs_test(wm, scene)) - uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", 0,0,75,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering"); + uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_CANCEL, "Render", 0,0,75,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering"); if(WM_jobs_test(wm, screen)) - uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast"); + uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast"); if(screen->animtimer) - uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); + uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); } diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index c52021b3a49..2fc1fcfc681 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -48,21 +48,21 @@ EnumPropertyItem id_type_items[] = { {ID_IM, "IMAGE", ICON_IMAGE_DATA, "Image", ""}, {ID_KE, "KEY", ICON_SHAPEKEY_DATA, "Key", ""}, {ID_LA, "LAMP", ICON_LAMP_DATA, "Lamp", ""}, - {ID_LI, "LIBRARY", 0, "Library", ""}, + {ID_LI, "LIBRARY", ICON_LIBRARY_DATA_DIRECT, "Library", ""}, {ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""}, {ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""}, {ID_MB, "META", ICON_META_DATA, "MetaBall", ""}, {ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""}, - {ID_NT, "NODETREE", 0, "NodeTree", ""}, + {ID_NT, "NODETREE", ICON_NODE, "NodeTree", ""}, {ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""}, {ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""}, {ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""}, - {ID_SCR, "SCREEN", 0, "Screen", ""}, - {ID_SO, "SOUND", 0, "Sound", ""}, + {ID_SCR, "SCREEN", ICON_SPLITSCREEN, "Screen", ""}, + {ID_SO, "SOUND", ICON_PLAY_AUDIO, "Sound", ""}, {ID_TXT, "TEXT", ICON_TEXT, "Text", ""}, {ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""}, {ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""}, - {ID_WM, "WINDOWMANAGER", 0, "Window Manager", ""}, + {ID_WM, "WINDOWMANAGER", ICON_FULLSCREEN, "Window Manager", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 6f7bc9a4feb..f49eb4122c5 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1609,9 +1609,9 @@ static void rna_def_texture(BlenderRNA *brna) static EnumPropertyItem prop_type_items[] = { {0, "NONE", 0, "None", ""}, - {TEX_PLUGIN, "PLUGIN", ICON_CONSTRAINT, "Plugin", ""}, - {TEX_IMAGE, "IMAGE", ICON_RENDER_RESULT, "Image or Movie", ""}, - {TEX_ENVMAP, "ENVIRONMENT_MAP", ICON_RENDER_RESULT, "Environment Map", ""}, + {TEX_PLUGIN, "PLUGIN", ICON_PLUGIN, "Plugin", ""}, + {TEX_IMAGE, "IMAGE", ICON_IMAGE_DATA, "Image or Movie", ""}, + {TEX_ENVMAP, "ENVIRONMENT_MAP", ICON_IMAGE_DATA, "Environment Map", ""}, {TEX_CLOUDS, "CLOUDS", ICON_TEXTURE, "Clouds", ""}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", ""}, {TEX_MARBLE, "MARBLE", ICON_TEXTURE, "Marble", ""}, -- cgit v1.2.3 From 33cd5fb85a7c50f8bf58c5e1422c90a4d0181aea Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 15 Oct 2009 13:52:27 +0000 Subject: Tiny tweak to make Anim Player button wide enough for icon+text. --- source/blender/editors/interface/interface_templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index a9f8fe2bd6d..7965a4c3b53 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2270,7 +2270,7 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) if(WM_jobs_test(wm, screen)) uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast"); if(screen->animtimer) - uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); + uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,100,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback"); } -- cgit v1.2.3 From 81beef19a34f01c9777f9a5f9aa94fe21e07b0a9 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Thu, 15 Oct 2009 14:41:21 +0000 Subject: Add side clicking in sliders. Hold Alt and click where arrows are in num buttons. --- source/blender/editors/interface/interface_handlers.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 3690b3c3f43..479c72304b2 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2378,6 +2378,15 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); retval= WM_UI_HANDLER_BREAK; } + /* alt-click on sides to get "arrows" like in NUM buttons, and match wheel usage above */ + else if(event->type == LEFTMOUSE && event->alt) { + int halfpos = (but->x1 + but->x2) / 2; + click = 2; + if (mx < halfpos) + mx = but->x1; + else + mx = but->x2; + } else if(event->type == LEFTMOUSE) { data->dragstartx= mx; data->draglastx= mx; @@ -2430,6 +2439,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton tempf= data->value; temp= (int)data->value; + /* XXX useles "if", same result for f, uh??? */ if(but->type==SLI) f= (float)(mx-but->x1)/(but->x2-but->x1); else f= (float)(mx- but->x1)/(but->x2-but->x1); -- cgit v1.2.3 From c102cedbf523e063a4849c011ddf8b6479dd95d9 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 15 Oct 2009 15:58:12 +0000 Subject: [#19644] Rotate around selection doesn't work offset structures weren't initialized properly. --- source/blender/editors/space_view3d/view3d_edit.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 8681a5bcd14..cee5c82ef38 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -277,6 +277,7 @@ static void calctrackballvec(rcti *rect, int mx, int my, float *vec) static void viewops_data(bContext *C, wmOperator *op, wmEvent *event) { + static float lastofs[3] = {0,0,0}; View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d; ViewOpsData *vod= MEM_callocN(sizeof(ViewOpsData), "viewops data"); @@ -291,6 +292,15 @@ static void viewops_data(bContext *C, wmOperator *op, wmEvent *event) vod->origx= vod->oldx= event->x; vod->origy= vod->oldy= event->y; vod->origkey= event->type; /* the key that triggered the operator. */ + + if (U.uiflag & USER_ORBIT_SELECTION) + { + VECCOPY(vod->ofs, rv3d->ofs); + /* If there's no selection, lastofs is unmodified and last value since static */ + calculateTransformCenter(C, event, V3D_CENTROID, lastofs); + VECCOPY(vod->obofs, lastofs); + VecMulf(vod->obofs, -1.0f); + } /* lookup, we dont pass on v3d to prevent confusement */ vod->grid= v3d->grid; -- cgit v1.2.3 From bd0fee9a4c9212c74619cdfbf4e524f0a57297fd Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 15 Oct 2009 17:18:47 +0000 Subject: Network Render: * Some code cleanups to match layout file code guidelines. * Ported Operator Labels to op file itself. * Added some Tooltips, theeth: Feel free to change/improve them as you like. :) --- release/scripts/io/netrender/operators.py | 42 +++++++++++++-------------- release/scripts/io/netrender/ui.py | 47 ++++++++++++------------------- 2 files changed, 37 insertions(+), 52 deletions(-) diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py index 42d1f6a0b86..e46b0c7b888 100644 --- a/release/scripts/io/netrender/operators.py +++ b/release/scripts/io/netrender/operators.py @@ -9,11 +9,9 @@ import netrender.model @rnaOperator class RENDER_OT_netclientanim(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Start rendering an animation on network''' __idname__ = "render.netclientanim" - __label__ = "Net Render Client Anim" + __label__ = "Animation on network" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -42,11 +40,9 @@ class RENDER_OT_netclientanim(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientsend(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Send Render Job to the Network''' __idname__ = "render.netclientsend" - __label__ = "Net Render Client Send" + __label__ = "Send job" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -73,9 +69,9 @@ class RENDER_OT_netclientsend(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientstatus(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Refresh the status of the current jobs''' __idname__ = "render.netclientstatus" - __label__ = "Net Render Client Status" + __label__ = "Client Status" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -120,7 +116,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): class RENDER_OT_netclientblacklistslave(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientblacklistslave" - __label__ = "Net Render Client Blacklist Slave" + __label__ = "Client Blacklist Slave" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -155,7 +151,7 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator): class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientwhitelistslave" - __label__ = "Net Render Client Whitelist Slave" + __label__ = "Client Whitelist Slave" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -189,9 +185,9 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientslaves(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Refresh status about available Render slaves''' __idname__ = "render.netclientslaves" - __label__ = "Net Render Client Slaves" + __label__ = "Client Slaves" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -239,9 +235,9 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientcancel(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Cancel the selected network rendering job.''' __idname__ = "render.netclientcancel" - __label__ = "Net Render Client Cancel" + __label__ = "Client Cancel" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -273,9 +269,9 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientcancelall(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Cancel all running network rendering jobs.''' __idname__ = "render.netclientcancelall" - __label__ = "Net Render Client Cancel All" + __label__ = "Client Cancel All" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -305,9 +301,9 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator): @rnaOperator class netclientdownload(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Download render results from the network''' __idname__ = "render.netclientdownload" - __label__ = "Net Render Client Download" + __label__ = "Client Download" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -357,7 +353,7 @@ class netclientdownload(bpy.types.Operator): class netclientscan(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientscan" - __label__ = "Net Render Client Scan" + __label__ = "Client Scan" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -393,9 +389,9 @@ class netclientscan(bpy.types.Operator): @rnaOperator class netclientweb(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Open new window with information about running rendering jobs''' __idname__ = "render.netclientweb" - __label__ = "Net Render Client Web" + __label__ = "Open Master Monitor" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py index 638f46318af..7d7f3c29630 100644 --- a/release/scripts/io/netrender/ui.py +++ b/release/scripts/io/netrender/ui.py @@ -33,10 +33,6 @@ class RENDER_PT_network_settings(RenderButtonsPanel): __label__ = "Network Settings" COMPAT_ENGINES = set(['NET_RENDER']) - def draw_header(self, context): - layout = self.layout - scene = context.scene - def draw(self, context): layout = self.layout @@ -48,7 +44,6 @@ class RENDER_PT_network_settings(RenderButtonsPanel): split = layout.split() col = split.column() - col.itemR(scene.network_render, "mode") col.itemR(scene.network_render, "path") col.itemR(scene.network_render, "server_address") @@ -79,13 +74,13 @@ class RENDER_PT_network_job(RenderButtonsPanel): split = layout.split() col = split.column() - - col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animation on network") - col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job") - col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor") + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION') + col.itemO("render.netclientsend", icon="ICON_FILE_BLEND") + col.itemO("render.netclientweb", icon="ICON_QUESTION") col.itemR(scene.network_render, "job_name") - col.itemR(scene.network_render, "priority") - col.itemR(scene.network_render, "chunks") + row = col.row() + row.itemR(scene.network_render, "priority") + row.itemR(scene.network_render, "chunks") @rnaType class RENDER_PT_network_slaves(RenderButtonsPanel): @@ -105,11 +100,9 @@ class RENDER_PT_network_slaves(RenderButtonsPanel): row = layout.row() row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2) - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") + sub = row.column(align=True) + sub.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") + sub.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0: while(len(netsettings.slaves) > 0): @@ -143,10 +136,8 @@ class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel): row = layout.row() row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2) - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") + sub = row.column(align=True) + sub.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0: while(len(netsettings.slaves_blacklist) > 0): @@ -180,13 +171,11 @@ class RENDER_PT_network_jobs(RenderButtonsPanel): row = layout.row() row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2) - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") - subcol.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") - subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") + sub = row.column(align=True) + sub.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") + sub.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + sub.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") + sub.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: while(len(netsettings.jobs) > 0): @@ -303,8 +292,8 @@ NetRenderSettings.EnumProperty(attr="mode", ("RENDER_MASTER", "Master", "Act as render master"), ("RENDER_SLAVE", "Slave", "Act as render slave"), ), - name="network mode", - description="mode of operation of this instance", + name="Network mode", + description="Mode of operation of this instance", default="RENDER_CLIENT") NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="") -- cgit v1.2.3 From d464e2454eb4816f58786fd4bbd419c759e764dc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 17:59:42 +0000 Subject: move view3d keymaps so edit&paint mode keymaps override removed workaround that prevented switching directly from editmode to paint modes + other minor changes --- source/blender/blenkernel/BKE_particle.h | 1 + source/blender/blenkernel/intern/particle.c | 8 ++++++++ source/blender/editors/object/object_edit.c | 6 ------ source/blender/editors/space_file/file_ops.c | 3 --- source/blender/editors/space_view3d/space_view3d.c | 5 +++-- source/blender/makesrna/intern/rna_particle.c | 5 +---- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index e9285782a1e..2291601bd47 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -200,6 +200,7 @@ struct Object *psys_get_lattice(struct ParticleSimulationData *sim); int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys); int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys); +int psys_check_edited(struct ParticleSystem *psys); void psys_check_group_weights(struct ParticleSettings *part); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 011d5c3f134..ea8562c0ca8 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -298,6 +298,14 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys) return 1; } +int psys_check_edited(ParticleSystem *psys) +{ + if(psys->part && psys->part->type==PART_HAIR) + return (psys->flag & PSYS_EDITED || (psys->edit && psys->edit->edited)); + else + return (psys->pointcache->edit && psys->pointcache->edit->edited); +} + void psys_check_group_weights(ParticleSettings *part) { ParticleDupliWeight *dw, *tdw; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d302e1eeec8..bd8b865a6c9 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2002,12 +2002,6 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) if(!ob || !object_mode_set_compat(C, op, ob)) return OPERATOR_PASS_THROUGH; - /* Irritating workaround! disallow paint modes from editmode since a number of shortcuts conflict - * XXX - would be much better to handle this on a keymap level */ - if((ob->mode & OB_MODE_EDIT) && ELEM6(mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT, OB_MODE_PARTICLE_EDIT, OB_MODE_POSE)) { - return OPERATOR_PASS_THROUGH; - } - /* Exit current mode if it's not the mode we're setting */ if(ob->mode != OB_MODE_OBJECT && ob->mode != mode) WM_operator_name_call(C, object_mode_op_string(ob->mode), WM_OP_EXEC_REGION_WIN, NULL); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index a49b0a072af..c35ff6ed7b6 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -795,9 +795,6 @@ int file_directory_exec(bContext *C, wmOperator *unused) SpaceFile *sfile= CTX_wm_space_file(C); if(sfile->params) { - char prev_dir[sizeof(sfile->params->dir)]; - BLI_strncpy(prev_dir, filelist_dir(sfile->files), sizeof(prev_dir)); - if ( sfile->params->dir[0] == '~' ) { if (sfile->params->dir[1] == '\0') { BLI_strncpy(sfile->params->dir, BLI_gethome(), sizeof(sfile->params->dir) ); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index d017e11e783..2cade9bb685 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -298,8 +298,6 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) wmKeyMap *keymap; /* object ops. */ - keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); /* pose is not modal, operator poll checks for this */ keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); @@ -349,6 +347,9 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm->defaultconf, "Font", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + keymap= WM_keymap_find(wm->defaultconf, "Object Non-modal", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + /* own keymap, last so modes can override it */ keymap= WM_keymap_find(wm->defaultconf, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 28d0d2deb34..d261bda739e 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -420,10 +420,7 @@ static int rna_ParticleSystem_editable_get(PointerRNA *ptr) { ParticleSystem *psys= (ParticleSystem*)ptr->data; - if(psys->part && psys->part->type==PART_HAIR) - return (psys->flag & PSYS_HAIR_DONE); - else - return (psys->pointcache->flag & PTCACHE_BAKED); + return psys_check_edited(psys); } static int rna_ParticleSystem_edited_get(PointerRNA *ptr) { -- cgit v1.2.3 From 66725a189e277744f134e4c098c6dbecd979689f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 18:27:41 +0000 Subject: disallow editing particle settings when first entering particle editmode, would crash instantly when changing the amount for eg. --- release/scripts/ui/buttons_particle.py | 22 +++++++++++----------- .../editors/space_buttons/buttons_context.c | 9 ++++++++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/release/scripts/ui/buttons_particle.py b/release/scripts/ui/buttons_particle.py index 81ddab40ec9..b0be974727a 100644 --- a/release/scripts/ui/buttons_particle.py +++ b/release/scripts/ui/buttons_particle.py @@ -6,8 +6,8 @@ from buttons_physics_common import effector_weights_ui from buttons_physics_common import basic_force_field_settings_ui from buttons_physics_common import basic_force_field_falloff_ui -def particle_panel_enabled(psys): - return psys.point_cache.baked==False and psys.edited==False +def particle_panel_enabled(context, psys): + return psys.point_cache.baked==False and psys.edited==False and (not context.particle_system_editable) def particle_panel_poll(context): psys = context.particle_system @@ -78,7 +78,7 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): return row=col.row() - row.enabled = particle_panel_enabled(psys) + row.enabled = particle_panel_enabled(context, psys) row.itemR(part, "type", text="") row.itemR(psys, "seed") @@ -89,7 +89,7 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): else: split.itemL(text="") row = split.row() - row.enabled = particle_panel_enabled(psys) + row.enabled = particle_panel_enabled(context, psys) row.itemR(part, "hair_step") if psys.edited==True: if psys.global_hair: @@ -99,7 +99,7 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): layout.itemO("particle.disconnect_hair") layout.itemL(text="") elif part.type=='REACTOR': - split.enabled = particle_panel_enabled(psys) + split.enabled = particle_panel_enabled(context, psys) split.itemR(psys, "reactor_target_object") split.itemR(psys, "reactor_target_particle_system", text="Particle System") @@ -118,7 +118,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches + layout.enabled = particle_panel_enabled(context, psys) and not psys.multiple_caches row = layout.row() row.active = part.distribution != 'GRID' @@ -221,7 +221,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel): psys = context.particle_system - point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0) + point_cache_ui(self, psys.point_cache, particle_panel_enabled(context, psys), not psys.hair_dynamics, 0) class PARTICLE_PT_velocity(ParticleButtonsPanel): __label__ = "Velocity" @@ -239,7 +239,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) + layout.enabled = particle_panel_enabled(context, psys) split = layout.split() @@ -284,7 +284,7 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) + layout.enabled = particle_panel_enabled(context, psys) split = layout.split() split.itemL(text="Initial Rotation:") @@ -322,7 +322,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) + layout.enabled = particle_panel_enabled(context, psys) row = layout.row() row.itemR(part, "physics_type", expand=True) @@ -461,7 +461,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel): boids = context.particle_system.settings.boids layout = self.layout - layout.enabled = particle_panel_enabled(context.particle_system) + layout.enabled = particle_panel_enabled(context, context.particle_system) # Currently boids can only use the first state so these are commented out for now. #row = layout.row() diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 8072853bcb8..eb88ea8519e 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -554,7 +554,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r static const char *dir[] = { "world", "object", "mesh", "armature", "lattice", "curve", "meta_ball", "lamp", "camera", "material", "material_slot", - "texture", "texture_slot", "bone", "edit_bone", "particle_system", + "texture", "texture_slot", "bone", "edit_bone", "particle_system", "particle_system_editable", "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL}; CTX_data_dir_set(result, dir); @@ -658,6 +658,13 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_ParticleSystem); return 1; } + else if(CTX_data_equals(member, "particle_system_editable")) { + if(PE_poll(C)) + set_pointer_type(path, result, &RNA_ParticleSystem); + else + CTX_data_pointer_set(result, NULL, &RNA_ParticleSystem, NULL); + return 1; + } else if(CTX_data_equals(member, "cloth")) { PointerRNA *ptr= get_pointer_type(path, &RNA_Object); -- cgit v1.2.3 From 5fff9cf6603d4d3d78c0edccc4d6661795c1a1e4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 19:18:40 +0000 Subject: stamp font size and added rendertime stamp option --- release/scripts/ui/buttons_render.py | 1 + source/blender/blenkernel/intern/image.c | 37 +++++++++++++++++++++++++++++- source/blender/makesdna/DNA_scene_types.h | 3 ++- source/blender/makesrna/intern/rna_scene.c | 25 +++++++++----------- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/release/scripts/ui/buttons_render.py b/release/scripts/ui/buttons_render.py index 699fd8d7391..0826c766ce3 100644 --- a/release/scripts/ui/buttons_render.py +++ b/release/scripts/ui/buttons_render.py @@ -422,6 +422,7 @@ class RENDER_PT_stamp(RenderButtonsPanel): col = split.column() col.itemR(rd, "stamp_time", text="Time") col.itemR(rd, "stamp_date", text="Date") + col.itemR(rd, "stamp_render_time", text="RenderTime") col.itemR(rd, "stamp_frame", text="Frame") col.itemR(rd, "stamp_scene", text="Scene") col.itemR(rd, "stamp_camera", text="Camera") diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 09d150341b2..efe53f6f8ef 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -964,6 +964,7 @@ typedef struct StampData { char camera[64]; char scene[64]; char strip[64]; + char rendertime[64]; } StampData; static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) @@ -1087,6 +1088,20 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) } else { stamp_data->strip[0] = '\0'; } + + { + Render *re= RE_GetRender(scene->id.name); + RenderStats *stats= re ? RE_GetStats(re):NULL; + + if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) { + BLI_timestr(stats->lastframetime, text); + + if (do_prefix) sprintf(stamp_data->rendertime, "RenderTime %s", text); + else sprintf(stamp_data->rendertime, "%s", text); + } else { + stamp_data->rendertime[0] = '\0'; + } + } } // XXX - Bad level call. @@ -1116,7 +1131,12 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i return; stampdata(scene, &stamp_data, 1); - stamp_font_begin(12); + + /* TODO, do_versions */ + if(scene->r.stamp_font_id < 8) + scene->r.stamp_font_id= 12; + + stamp_font_begin(scene->r.stamp_font_id); BLF_buffer(rectf, rect, width, height, channels); BLF_buffer_col(scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0); @@ -1166,6 +1186,21 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_position(x, y, 0.0); BLF_draw_buffer(stamp_data.date); + + /* the extra pixel for background. */ + y -= 4; + } + + /* Top left corner, below File, Date or Note */ + if (stamp_data.rendertime[0]) { + BLF_width_and_height(stamp_data.rendertime, &w, &h); + y -= h; + + /* and space for background. */ + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+3); + + BLF_position(x, y, 0.0); + BLF_draw_buffer(stamp_data.rendertime); } x= 0; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d2e88408f6b..91f8e8d5c41 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -866,7 +866,8 @@ typedef struct Scene { #define R_STAMP_MARKER 0x0080 #define R_STAMP_FILENAME 0x0100 #define R_STAMP_SEQSTRIP 0x0200 -#define R_STAMP_ALL (R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_CAMERA|R_STAMP_SCENE|R_STAMP_NOTE|R_STAMP_MARKER|R_STAMP_FILENAME|R_STAMP_SEQSTRIP) +#define R_STAMP_RENDERTIME 0x0400 +#define R_STAMP_ALL (R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_CAMERA|R_STAMP_SCENE|R_STAMP_NOTE|R_STAMP_MARKER|R_STAMP_FILENAME|R_STAMP_SEQSTRIP|R_STAMP_RENDERTIME) /* alphamode */ #define R_ADDSKY 0 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 59850216060..b9fd2926ca3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1280,14 +1280,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, "THREADS_AUTO", 0, "Auto-detect", "Automatically determine the number of threads, based on CPUs"}, {R_FIXED_THREADS, "THREADS_FIXED", 0, "Fixed", "Manually determine the number of threads"}, {0, NULL, 0, NULL, NULL}}; - - static EnumPropertyItem stamp_font_size_items[] = { - {1, "STAMP_FONT_TINY", 0, "Tiny", ""}, - {2, "STAMP_FONT_SMALL", 0, "Small", ""}, - {3, "STAMP_FONT_MEDIUM", 0, "Medium", ""}, - {0, "STAMP_FONT_LARGE", 0, "Large", ""}, - {4, "STAMP_FONT_EXTRALARGE", 0, "Extra Large", ""}, - {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem image_type_items[] = { {0, "", 0, "Image", NULL}, @@ -2005,23 +1997,28 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_SEQSTRIP); RNA_def_property_ui_text(prop, "Stamp Sequence Strip", "Include the name of the foreground sequence strip in image metadata"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + + prop= RNA_def_property(srna, "stamp_render_time", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_RENDERTIME); + RNA_def_property_ui_text(prop, "Stamp Render Time", "Include the render time in the stamp image"); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "stamp_note_text", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "stamp_udata"); RNA_def_property_ui_text(prop, "Stamp Note Text", "Custom text to appear in the stamp note"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - + prop= RNA_def_property(srna, "render_stamp", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_DRAW); RNA_def_property_ui_text(prop, "Render Stamp", "Render the stamp info text in the rendered image"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - prop= RNA_def_property(srna, "stamp_font_size", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "stamp_font_id"); - RNA_def_property_enum_items(prop, stamp_font_size_items); - RNA_def_property_ui_text(prop, "Stamp Font Size", "Size of the font used when rendering stamp text"); + prop= RNA_def_property(srna, "stamp_font_size", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "stamp_font_id"); + RNA_def_property_range(prop, 8, 64); + RNA_def_property_ui_text(prop, "Font Size", "Size of the font used when rendering stamp text"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); - + prop= RNA_def_property(srna, "stamp_foreground", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "fg_stamp"); RNA_def_property_array(prop, 4); -- cgit v1.2.3 From ee6dd8ec38e85cdd64f1f369322cc3c1477dc5c0 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Thu, 15 Oct 2009 20:09:50 +0000 Subject: Cocoa : - implemented custom cursor handling --- intern/ghost/intern/GHOST_WindowCocoa.mm | 87 ++++++++++++++------------------ 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index f86fa49b31c..e41c773a4c3 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -932,8 +932,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor sha return GHOST_kSuccess; } -#if 0 -/** Reverse the bits in a GHOST_TUns8 */ +/** Reverse the bits in a GHOST_TUns8 static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) { ch= ((ch>>1)&0x55) | ((ch<<1)&0xAA); @@ -941,7 +940,7 @@ static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) ch= ((ch>>4)&0x0F) | ((ch<<4)&0xF0); return ch; } -#endif +*/ /** Reverse the bits in a GHOST_TUns16 */ @@ -957,43 +956,68 @@ static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt) GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color) { - int y; + int y,nbUns16; NSPoint hotSpotPoint; + NSBitmapImageRep *cursorImageRep; NSImage *cursorImage; + NSSize imSize; + GHOST_TUns16 *cursorBitmap; + + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (m_customCursor) { [m_customCursor release]; m_customCursor = nil; } - /*TODO: implement this (but unused inproject at present) - cursorImage = [[NSImage alloc] initWithData:bitmap]; - for (y=0; y<16; y++) { + + cursorImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil + pixelsWide:sizex + pixelsHigh:sizey + bitsPerSample:1 + samplesPerPixel:2 + hasAlpha:YES + isPlanar:YES + colorSpaceName:NSDeviceBlackColorSpace + bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0)) + bitsPerPixel:1]; + + + cursorBitmap = (GHOST_TUns16*)[cursorImageRep bitmapData]; + nbUns16 = [cursorImageRep bytesPerPlane]/2; + + for (y=0; ydata[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8)); - m_customCursor->mask[y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8)); + cursorBitmap[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8)); + cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8)); #else - m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8)); - m_customCursor->mask[y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8)); + cursorBitmap[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8)); + cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8)); #endif - + } + imSize.width = sizex; + imSize.height= sizey; + cursorImage = [[NSImage alloc] initWithSize:imSize]; + [cursorImage addRepresentation:cursorImageRep]; + hotSpotPoint.x = hotX; hotSpotPoint.y = hotY; + //foreground and background color parameter is not handled for now (10.6) m_customCursor = [[NSCursor alloc] initWithImage:cursorImage - foregroundColorHint:<#(NSColor *)fg#> - backgroundColorHint:<#(NSColor *)bg#> hotSpot:hotSpotPoint]; + [cursorImageRep release]; [cursorImage release]; if ([m_window isVisible]) { loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom); } - */ + [pool drain]; return GHOST_kSuccess; } @@ -1002,36 +1026,3 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[ { return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1); } - -#pragma mark Old carbon stuff to remove - -#if 0 -void GHOST_WindowCocoa::setMac_windowState(short value) -{ - mac_windowState = value; -} - -short GHOST_WindowCocoa::getMac_windowState() -{ - return mac_windowState; -} - -void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const -{ - STR_String tempStr = in; - int num = tempStr.Length(); - if (num > 255) num = 255; - ::memcpy(out+1, tempStr.Ptr(), num); - out[0] = num; -} - - -void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const -{ - char tmp[256]; - ::memcpy(tmp, in+1, in[0]); - tmp[in[0]] = '\0'; - out = tmp; -} - -#endif \ No newline at end of file -- cgit v1.2.3 From 17c7b46334a1ee5cda28a75177269bdc17e68c06 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Oct 2009 20:15:21 +0000 Subject: object apply menu and keybinding (Ctrl+A) --- release/scripts/ui/space_view3d.py | 14 ++++++++++++++ source/blender/editors/object/object_ops.c | 3 +++ 2 files changed, 17 insertions(+) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index dfc491522f5..cac2b88f39e 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -395,6 +395,7 @@ class VIEW3D_MT_object(bpy.types.Menu): layout = self.layout layout.itemM("VIEW3D_MT_object_clear") + layout.itemM("VIEW3D_MT_object_apply") layout.itemM("VIEW3D_MT_snap") layout.itemS() @@ -437,6 +438,18 @@ class VIEW3D_MT_object_clear(bpy.types.Menu): layout.itemO("object.scale_clear", text="Scale") layout.itemO("object.origin_clear", text="Origin") +class VIEW3D_MT_object_apply(bpy.types.Menu): + __label__ = "Apply" + + def draw(self, context): + layout = self.layout + + layout.itemO("object.location_apply", text="Location") + layout.itemO("object.rotation_apply", text="Rotation") + layout.itemO("object.scale_apply", text="Scale") + layout.itemS() + layout.itemO("object.visual_transform_apply", text="Visual Transform") + class VIEW3D_MT_object_parent(bpy.types.Menu): __label__ = "Parent" @@ -1396,6 +1409,7 @@ bpy.types.register(VIEW3D_MT_select_edit_armature) bpy.types.register(VIEW3D_MT_select_face) # XXX todo bpy.types.register(VIEW3D_MT_object) # Object Menu +bpy.types.register(VIEW3D_MT_object_apply) bpy.types.register(VIEW3D_MT_object_clear) bpy.types.register(VIEW3D_MT_object_parent) bpy.types.register(VIEW3D_MT_object_track) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 775f9937095..5c53e041f6e 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -249,6 +249,9 @@ void ED_keymap_object(wmKeyConfig *keyconf) kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(kmi->ptr, "name", "INFO_MT_add"); + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_object_apply"); + WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1); WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0); -- cgit v1.2.3 From dcecd8e043962c9f38b15d569849d0303773af32 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 15 Oct 2009 20:38:35 +0000 Subject: Force cursor grab OFF when running with -d. It helps running a debugger when you can click on stuff when on a breakpoint... --- source/blender/windowmanager/intern/wm_cursors.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index e33132d18b9..c1dfd9ee9fb 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -165,14 +165,19 @@ void WM_cursor_wait(int val) void WM_cursor_grab(wmWindow *win, int warp) { - if(win) - GHOST_SetCursorGrab(win->ghostwin, 1, warp, -1); + /* Only grab cursor when not running debug. + * It helps not to get a stuck WM when hitting a breakpoint + * */ + if ((G.f & G_DEBUG) == 0) + if(win) + GHOST_SetCursorGrab(win->ghostwin, 1, warp, -1); } void WM_cursor_ungrab(wmWindow *win, int restore) { - if(win) - GHOST_SetCursorGrab(win->ghostwin, 0, -1, restore); + if ((G.f & G_DEBUG) == 0) + if(win) + GHOST_SetCursorGrab(win->ghostwin, 0, -1, restore); } /* afer this you can call restore too */ -- cgit v1.2.3 From 6ffb79107c9509f01019c8bf9af2caf0348ca330 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 15 Oct 2009 21:54:22 +0000 Subject: X Mirror editmesh with PET Lock vertice near the middle (|x| < 0.0001) on the mirror's plane. Don't propagate transformation across mirror plane (this could probably be smarter) --- source/blender/editors/transform/transform.h | 5 ++++- source/blender/editors/transform/transform_conversions.c | 16 ++++++++++++++++ source/blender/editors/transform/transform_generics.c | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 5cee1f51b0a..fc31fad622a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -215,7 +215,7 @@ typedef struct TransData { TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */ TransDataCurveHandleFlags *hdata; /* for curves, stores handle flags for modification/cancel */ void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */ - short flag; /* Various flags */ + int flag; /* Various flags */ short protectflag; /* If set, copy of Object or PoseChannel protection */ int rotOrder; /* rotation mode, as defined in eRotationModes (DNA_action_types.h) */ } TransData; @@ -289,6 +289,8 @@ typedef struct TransInfo { short current_orientation; short prop_mode; + + short mirror; float values[4]; float auto_values[4]; @@ -398,6 +400,7 @@ typedef struct TransInfo { #define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */ #define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */ #define TD_INTVALUES (1 << 15) /* for Graph Editor - curves that can only have int-values need their keyframes tagged with this */ +#define TD_MIRROR_EDGE (1 << 16) /* For editmode mirror, clamp to x = 0 */ /* transsnap->status */ #define SNAP_ON 1 diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 317457ee33f..496a9665371 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2214,7 +2214,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) for (eve=em->verts.first; eve; eve=eve->next) { if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) { if(eve->co[0]<0.0f) + { + t->mirror = -1; mirror = -1; + } break; } } @@ -2280,6 +2283,19 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } } } + + if (mirror != 0) + { + tob = t->data; + for( a = 0; a < t->total; a++, tob++ ) + { + if (ABS(tob->loc[0]) <= 0.00001f) + { + tob->flag |= TD_MIRROR_EDGE; + } + } + } + if (propmode) { MEM_freeN(vectors); MEM_freeN(nears); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 47f76aab4ca..8dc71710d82 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -259,11 +259,16 @@ static void editmesh_apply_to_mirror(TransInfo *t) continue; eve = td->extra; - if(eve) { + if (eve) { eve->co[0]= -td->loc[0]; eve->co[1]= td->loc[1]; eve->co[2]= td->loc[2]; } + + if (td->flag & TD_MIRROR_EDGE) + { + td->loc[0] = 0; + } } } @@ -969,6 +974,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) if (RNA_boolean_get(op->ptr, "mirror")) { t->flag |= T_MIRROR; + t->mirror = 1; } } // Need stuff to take it from edit mesh or whatnot here @@ -977,6 +983,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X)) { t->flag |= T_MIRROR; + t->mirror = 1; } } @@ -1373,6 +1380,12 @@ void calculatePropRatio(TransInfo *t) if (td->flag & TD_SELECTED) { td->factor = 1.0f; } + else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) + { + td->flag |= TD_SKIP; + td->factor = 0.0f; + restoreElement(td); + } else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) || -- cgit v1.2.3